All of lore.kernel.org
 help / color / mirror / Atom feed
* Quota fixes and improvements
       [not found] <yes>
@ 2009-01-16 18:08 ` Jan Kara
  2009-01-16 18:08   ` [PATCH 01/11] quota: Improve locking Jan Kara
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                   ` (90 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel

I'm sending for review patches fixing some bugs and implementing new quota
features. First four patches fix possible deadlocks in OCFS2 quotas. I plan
to send them to Linus next week if nobody objects. The remaining patches
are going to linux-next and I plan to merge them in the next merge window.

								Honza

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 01/11] quota: Improve locking
  2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
@ 2009-01-16 18:08   ` Jan Kara
  2009-01-16 18:08     ` [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop() Jan Kara
  2009-01-24  7:49     ` [PATCH 01/11] quota: Improve locking Andrew Morton
  0 siblings, 2 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

We implement dqget() and dqput() that need neither dqonoff_mutex nor dqptr_sem.
Then move dqget() and dqput() calls so that they are not called from under
dqptr_sem. This is important because filesystem callbacks aren't called from
under dqptr_sem which used to cause *lots* of problems with lock ranking
(and with OCFS2 they became close to unsolvable).

The patch also removes two functions which were introduced solely because OCFS2
needed them to cope with the old locking scheme. As time showed, they were not
enough for OCFS2 anyway and it would be unnecessary work to adapt them to the
new locking scheme in which they aren't needed.  As a result OCFS2 needs the
following patch to compile properly with quotas.  Sorry to any bisecters which
hit this in advance.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dquot.c               |  218 ++++++++++++++++++++++++++--------------------
 include/linux/quotaops.h |    2 -
 2 files changed, 122 insertions(+), 98 deletions(-)

diff --git a/fs/dquot.c b/fs/dquot.c
index 48c0571..bca3cac 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -87,14 +87,17 @@
 #define __DQUOT_PARANOIA
 
 /*
- * There are two quota SMP locks. dq_list_lock protects all lists with quotas
- * and quota formats and also dqstats structure containing statistics about the
- * lists. dq_data_lock protects data from dq_dqb and also mem_dqinfo structures
- * and also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes.
+ * There are three quota SMP locks. dq_list_lock protects all lists with quotas
+ * and quota formats, dqstats structure containing statistics about the lists
+ * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and
+ * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes.
  * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly
- * in inode_add_bytes() and inode_sub_bytes().
+ * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects
+ * modifications of quota state (on quotaon and quotaoff) and readers who care
+ * about latest values take it as well.
  *
- * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock
+ * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock,
+ *   dq_list_lock > dq_state_lock
  *
  * Note that some things (eg. sb pointer, type, id) doesn't change during
  * the life of the dquot structure and so needn't to be protected by a lock
@@ -103,12 +106,7 @@
  * operation is just reading pointers from inode (or not using them at all) the
  * read lock is enough. If pointers are altered function must hold write lock
  * (these locking rules also apply for S_NOQUOTA flag in the inode - note that
- * for altering the flag i_mutex is also needed).  If operation is holding
- * reference to dquot in other way (e.g. quotactl ops) it must be guarded by
- * dqonoff_mutex.
- * This locking assures that:
- *   a) update/access to dquot pointers in inode is serialized
- *   b) everyone is guarded against invalidate_dquots()
+ * for altering the flag i_mutex is also needed).
  *
  * Each dquot has its dq_lock mutex. Locked dquots might not be referenced
  * from inodes (dquot_alloc_space() and such don't check the dq_lock).
@@ -122,10 +120,17 @@
  * Lock ordering (including related VFS locks) is the following:
  *   i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock >
  *   dqio_mutex
+ * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem >
+ * dqptr_sem. But filesystem has to count with the fact that functions such as
+ * dquot_alloc_space() acquire dqptr_sem and they usually have to be called
+ * from inside a transaction to keep filesystem consistency after a crash. Also
+ * filesystems usually want to do some IO on dquot from ->mark_dirty which is
+ * called with dqptr_sem held.
  * i_mutex on quota files is special (it's below dqio_mutex)
  */
 
 static DEFINE_SPINLOCK(dq_list_lock);
+static DEFINE_SPINLOCK(dq_state_lock);
 DEFINE_SPINLOCK(dq_data_lock);
 
 static char *quotatypes[] = INITQFNAMES;
@@ -428,7 +433,7 @@ static inline void do_destroy_dquot(struct dquot *dquot)
  * quota is disabled and pointers from inodes removed so there cannot be new
  * quota users. There can still be some users of quotas due to inodes being
  * just deleted or pruned by prune_icache() (those are not attached to any
- * list). We have to wait for such users.
+ * list) or parallel quotactl call. We have to wait for such users.
  */
 static void invalidate_dquots(struct super_block *sb, int type)
 {
@@ -600,7 +605,6 @@ static struct shrinker dqcache_shrinker = {
 /*
  * Put reference to dquot
  * NOTE: If you change this function please check whether dqput_blocks() works right...
- * MUST be called with either dqptr_sem or dqonoff_mutex held
  */
 void dqput(struct dquot *dquot)
 {
@@ -697,36 +701,30 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
 }
 
 /*
- * Check whether dquot is in memory.
- * MUST be called with either dqptr_sem or dqonoff_mutex held
- */
-int dquot_is_cached(struct super_block *sb, unsigned int id, int type)
-{
-	unsigned int hashent = hashfn(sb, id, type);
-	int ret = 0;
-
-        if (!sb_has_quota_active(sb, type))
-		return 0;
-	spin_lock(&dq_list_lock);
-	if (find_dquot(hashent, sb, id, type) != NODQUOT)
-		ret = 1;
-	spin_unlock(&dq_list_lock);
-	return ret;
-}
-
-/*
  * Get reference to dquot
- * MUST be called with either dqptr_sem or dqonoff_mutex held
+ *
+ * Locking is slightly tricky here. We are guarded from parallel quotaoff()
+ * destroying our dquot by:
+ *   a) checking for quota flags under dq_list_lock and
+ *   b) getting a reference to dquot before we release dq_list_lock
  */
 struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
 {
 	unsigned int hashent = hashfn(sb, id, type);
-	struct dquot *dquot, *empty = NODQUOT;
+	struct dquot *dquot = NODQUOT, *empty = NODQUOT;
 
         if (!sb_has_quota_active(sb, type))
 		return NODQUOT;
 we_slept:
 	spin_lock(&dq_list_lock);
+	spin_lock(&dq_state_lock);
+	if (!sb_has_quota_active(sb, type)) {
+		spin_unlock(&dq_state_lock);
+		spin_unlock(&dq_list_lock);
+		goto out;
+	}
+	spin_unlock(&dq_state_lock);
+
 	if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
 		if (empty == NODQUOT) {
 			spin_unlock(&dq_list_lock);
@@ -735,6 +733,7 @@ we_slept:
 			goto we_slept;
 		}
 		dquot = empty;
+		empty = NODQUOT;
 		dquot->dq_id = id;
 		/* all dquots go on the inuse_list */
 		put_inuse(dquot);
@@ -749,8 +748,6 @@ we_slept:
 		dqstats.cache_hits++;
 		dqstats.lookups++;
 		spin_unlock(&dq_list_lock);
-		if (empty)
-			do_destroy_dquot(empty);
 	}
 	/* Wait for dq_lock - after this we know that either dquot_release() is already
 	 * finished or it will be canceled due to dq_count > 1 test */
@@ -758,11 +755,15 @@ we_slept:
 	/* Read the dquot and instantiate it (everything done only if needed) */
 	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
 		dqput(dquot);
-		return NODQUOT;
+		dquot = NODQUOT;
+		goto out;
 	}
 #ifdef __DQUOT_PARANOIA
 	BUG_ON(!dquot->dq_sb);	/* Has somebody invalidated entry under us? */
 #endif
+out:
+	if (empty)
+		do_destroy_dquot(empty);
 
 	return dquot;
 }
@@ -1198,63 +1199,76 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space)
 }
 /*
  *	Initialize quota pointers in inode
- *	Transaction must be started at entry
+ *	We do things in a bit complicated way but by that we avoid calling
+ *	dqget() and thus filesystem callbacks under dqptr_sem.
  */
 int dquot_initialize(struct inode *inode, int type)
 {
 	unsigned int id = 0;
 	int cnt, ret = 0;
+	struct dquot *got[MAXQUOTAS] = { NODQUOT, NODQUOT };
+	struct super_block *sb = inode->i_sb;
 
 	/* First test before acquiring mutex - solves deadlocks when we
          * re-enter the quota code and are already holding the mutex */
 	if (IS_NOQUOTA(inode))
 		return 0;
-	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+
+	/* First get references to structures we might need. */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (type != -1 && cnt != type)
+			continue;
+		switch (cnt) {
+		case USRQUOTA:
+			id = inode->i_uid;
+			break;
+		case GRPQUOTA:
+			id = inode->i_gid;
+			break;
+		}
+		got[cnt] = dqget(sb, id, cnt);
+	}
+
+	down_write(&sb_dqopt(sb)->dqptr_sem);
 	/* Having dqptr_sem we know NOQUOTA flags can't be altered... */
 	if (IS_NOQUOTA(inode))
 		goto out_err;
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (type != -1 && cnt != type)
 			continue;
+		/* Avoid races with quotaoff() */
+		if (!sb_has_quota_active(sb, cnt))
+			continue;
 		if (inode->i_dquot[cnt] == NODQUOT) {
-			switch (cnt) {
-				case USRQUOTA:
-					id = inode->i_uid;
-					break;
-				case GRPQUOTA:
-					id = inode->i_gid;
-					break;
-			}
-			inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
+			inode->i_dquot[cnt] = got[cnt];
+			got[cnt] = NODQUOT;
 		}
 	}
 out_err:
-	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	up_write(&sb_dqopt(sb)->dqptr_sem);
+	/* Drop unused references */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		dqput(got[cnt]);
 	return ret;
 }
 
 /*
  * 	Release all quotas referenced by inode
- *	Transaction must be started at an entry
  */
-int dquot_drop_locked(struct inode *inode)
+int dquot_drop(struct inode *inode)
 {
 	int cnt;
+	struct dquot *put[MAXQUOTAS];
 
+	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (inode->i_dquot[cnt] != NODQUOT) {
-			dqput(inode->i_dquot[cnt]);
-			inode->i_dquot[cnt] = NODQUOT;
-		}
+		put[cnt] = inode->i_dquot[cnt];
+		inode->i_dquot[cnt] = NODQUOT;
 	}
-	return 0;
-}
-
-int dquot_drop(struct inode *inode)
-{
-	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
-	dquot_drop_locked(inode);
 	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		dqput(put[cnt]);
 	return 0;
 }
 
@@ -1470,8 +1484,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 	qsize_t space;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
-	int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
-	    chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
+	int cnt, ret = QUOTA_OK;
+	int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid,
+	    chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid;
 	char warntype_to[MAXQUOTAS];
 	char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
 
@@ -1479,21 +1494,11 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
          * re-enter the quota code and are already holding the mutex */
 	if (IS_NOQUOTA(inode))
 		return QUOTA_OK;
-	/* Clear the arrays */
+	/* Initialize the arrays */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
+		transfer_from[cnt] = NODQUOT;
+		transfer_to[cnt] = NODQUOT;
 		warntype_to[cnt] = QUOTA_NL_NOWARN;
-	}
-	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
-	/* Now recheck reliably when holding dqptr_sem */
-	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
-		up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
-		return QUOTA_OK;
-	}
-	/* First build the transfer_to list - here we can block on
-	 * reading/instantiating of dquots.  We know that the transaction for
-	 * us was already started so we don't violate lock ranking here */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		switch (cnt) {
 			case USRQUOTA:
 				if (!chuid)
@@ -1507,6 +1512,13 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 				break;
 		}
 	}
+
+	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	/* Now recheck reliably when holding dqptr_sem */
+	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
+		up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+		goto put_all;
+	}
 	spin_lock(&dq_data_lock);
 	space = inode_get_bytes(inode);
 	/* Build the transfer_from list and check the limits */
@@ -1517,7 +1529,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 		if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) ==
 		    NO_QUOTA || check_bdq(transfer_to[cnt], space, 0,
 		    warntype_to + cnt) == NO_QUOTA)
-			goto warn_put_all;
+			goto over_quota;
 	}
 
 	/*
@@ -1545,28 +1557,37 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 
 		inode->i_dquot[cnt] = transfer_to[cnt];
 	}
-	ret = QUOTA_OK;
-warn_put_all:
 	spin_unlock(&dq_data_lock);
+	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+
 	/* Dirtify all the dquots - this can block when journalling */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (transfer_from[cnt])
 			mark_dquot_dirty(transfer_from[cnt]);
-		if (transfer_to[cnt])
+		if (transfer_to[cnt]) {
 			mark_dquot_dirty(transfer_to[cnt]);
+			/* The reference we got is transferred to the inode */
+			transfer_to[cnt] = NODQUOT;
+		}
 	}
+warn_put_all:
 	flush_warnings(transfer_to, warntype_to);
 	flush_warnings(transfer_from, warntype_from_inodes);
 	flush_warnings(transfer_from, warntype_from_space);
-	
+put_all:
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT)
-			dqput(transfer_from[cnt]);
-		if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT)
-			dqput(transfer_to[cnt]);
+		dqput(transfer_from[cnt]);
+		dqput(transfer_to[cnt]);
 	}
-	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return ret;
+over_quota:
+	spin_unlock(&dq_data_lock);
+	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	/* Clear dquot pointers we don't want to dqput() */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		transfer_from[cnt] = NODQUOT;
+	ret = NO_QUOTA;
+	goto warn_put_all;
 }
 
 /* Wrapper for transferring ownership of an inode */
@@ -1651,19 +1672,24 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
 			continue;
 
 		if (flags & DQUOT_SUSPENDED) {
+			spin_lock(&dq_state_lock);
 			dqopt->flags |=
 				dquot_state_flag(DQUOT_SUSPENDED, cnt);
+			spin_unlock(&dq_state_lock);
 		} else {
+			spin_lock(&dq_state_lock);
 			dqopt->flags &= ~dquot_state_flag(flags, cnt);
 			/* Turning off suspended quotas? */
 			if (!sb_has_quota_loaded(sb, cnt) &&
 			    sb_has_quota_suspended(sb, cnt)) {
 				dqopt->flags &=	~dquot_state_flag(
 							DQUOT_SUSPENDED, cnt);
+				spin_unlock(&dq_state_lock);
 				iput(dqopt->files[cnt]);
 				dqopt->files[cnt] = NULL;
 				continue;
 			}
+			spin_unlock(&dq_state_lock);
 		}
 
 		/* We still have to keep quota loaded? */
@@ -1830,7 +1856,9 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
 	}
 	mutex_unlock(&dqopt->dqio_mutex);
 	mutex_unlock(&inode->i_mutex);
+	spin_lock(&dq_state_lock);
 	dqopt->flags |= dquot_state_flag(flags, type);
+	spin_unlock(&dq_state_lock);
 
 	add_dquot_ref(sb, type);
 	mutex_unlock(&dqopt->dqonoff_mutex);
@@ -1872,9 +1900,11 @@ static int vfs_quota_on_remount(struct super_block *sb, int type)
 	}
 	inode = dqopt->files[type];
 	dqopt->files[type] = NULL;
+	spin_lock(&dq_state_lock);
 	flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
 						DQUOT_LIMITS_ENABLED, type);
 	dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type);
+	spin_unlock(&dq_state_lock);
 	mutex_unlock(&dqopt->dqonoff_mutex);
 
 	flags = dquot_generic_flag(flags, type);
@@ -1952,7 +1982,9 @@ int vfs_quota_enable(struct inode *inode, int type, int format_id,
 			ret = -EBUSY;
 			goto out_lock;
 		}
+		spin_lock(&dq_state_lock);
 		sb_dqopt(sb)->flags |= dquot_state_flag(flags, type);
+		spin_unlock(&dq_state_lock);
 out_lock:
 		mutex_unlock(&dqopt->dqonoff_mutex);
 		return ret;
@@ -2039,14 +2071,12 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 {
 	struct dquot *dquot;
 
-	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
-	if (!(dquot = dqget(sb, id, type))) {
-		mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
+	dquot = dqget(sb, id, type);
+	if (dquot == NODQUOT)
 		return -ESRCH;
-	}
 	do_get_dqblk(dquot, di);
 	dqput(dquot);
-	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
+
 	return 0;
 }
 
@@ -2130,7 +2160,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 	struct dquot *dquot;
 	int rc;
 
-	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
 	dquot = dqget(sb, id, type);
 	if (!dquot) {
 		rc = -ESRCH;
@@ -2139,7 +2168,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 	rc = do_set_dqblk(dquot, di);
 	dqput(dquot);
 out:
-	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
 	return rc;
 }
 
@@ -2370,11 +2398,9 @@ EXPORT_SYMBOL(dquot_release);
 EXPORT_SYMBOL(dquot_mark_dquot_dirty);
 EXPORT_SYMBOL(dquot_initialize);
 EXPORT_SYMBOL(dquot_drop);
-EXPORT_SYMBOL(dquot_drop_locked);
 EXPORT_SYMBOL(vfs_dq_drop);
 EXPORT_SYMBOL(dqget);
 EXPORT_SYMBOL(dqput);
-EXPORT_SYMBOL(dquot_is_cached);
 EXPORT_SYMBOL(dquot_alloc_space);
 EXPORT_SYMBOL(dquot_alloc_inode);
 EXPORT_SYMBOL(dquot_free_space);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 21b781a..0b35b3a 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -24,10 +24,8 @@ void sync_dquots(struct super_block *sb, int type);
 
 int dquot_initialize(struct inode *inode, int type);
 int dquot_drop(struct inode *inode);
-int dquot_drop_locked(struct inode *inode);
 struct dquot *dqget(struct super_block *sb, unsigned int id, int type);
 void dqput(struct dquot *dquot);
-int dquot_is_cached(struct super_block *sb, unsigned int id, int type);
 int dquot_scan_active(struct super_block *sb,
 		      int (*fn)(struct dquot *dquot, unsigned long priv),
 		      unsigned long priv);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop()
  2009-01-16 18:08   ` [PATCH 01/11] quota: Improve locking Jan Kara
@ 2009-01-16 18:08     ` Jan Kara
  2009-01-16 18:08       ` [PATCH 03/11] ocfs2: Push out dropping of dentry lock to ocfs2_wq Jan Kara
  2009-01-24  7:49     ` [PATCH 01/11] quota: Improve locking Andrew Morton
  1 sibling, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

Since ->acquire_dquot and ->release_dquot callbacks aren't called under
dqptr_sem anymore, we don't have to start a transaction and obtain locks
so early. So we can just remove all this complicated stuff.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ocfs2/quota_global.c |  169 +----------------------------------------------
 1 files changed, 2 insertions(+), 167 deletions(-)

diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index 6aff8f2..f4efa89 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -810,171 +810,6 @@ out:
 	return status;
 }
 
-/* This is difficult. We have to lock quota inode and start transaction
- * in this function but we don't want to take the penalty of exlusive
- * quota file lock when we are just going to use cached structures. So
- * we just take read lock check whether we have dquot cached and if so,
- * we don't have to take the write lock... */
-static int ocfs2_dquot_initialize(struct inode *inode, int type)
-{
-	handle_t *handle = NULL;
-	int status = 0;
-	struct super_block *sb = inode->i_sb;
-	struct ocfs2_mem_dqinfo *oinfo;
-	int exclusive = 0;
-	int cnt;
-	qid_t id;
-
-	mlog_entry_void();
-
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (type != -1 && cnt != type)
-			continue;
-		if (!sb_has_quota_active(sb, cnt))
-			continue;
-		oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
-		status = ocfs2_lock_global_qf(oinfo, 0);
-		if (status < 0)
-			goto out;
-		/* This is just a performance optimization not a reliable test.
-		 * Since we hold an inode lock, noone can actually release
-		 * the structure until we are finished with initialization. */
-		if (inode->i_dquot[cnt] != NODQUOT) {
-			ocfs2_unlock_global_qf(oinfo, 0);
-			continue;
-		}
-		/* When we have inode lock, we know that no dquot_release() can
-		 * run and thus we can safely check whether we need to
-		 * read+modify global file to get quota information or whether
-		 * our node already has it. */
-		if (cnt == USRQUOTA)
-			id = inode->i_uid;
-		else if (cnt == GRPQUOTA)
-			id = inode->i_gid;
-		else
-			BUG();
-		/* Obtain exclusion from quota off... */
-		down_write(&sb_dqopt(sb)->dqptr_sem);
-		exclusive = !dquot_is_cached(sb, id, cnt);
-		up_write(&sb_dqopt(sb)->dqptr_sem);
-		if (exclusive) {
-			status = ocfs2_lock_global_qf(oinfo, 1);
-			if (status < 0) {
-				exclusive = 0;
-				mlog_errno(status);
-				goto out_ilock;
-			}
-			handle = ocfs2_start_trans(OCFS2_SB(sb),
-					ocfs2_calc_qinit_credits(sb, cnt));
-			if (IS_ERR(handle)) {
-				status = PTR_ERR(handle);
-				mlog_errno(status);
-				goto out_ilock;
-			}
-		}
-		dquot_initialize(inode, cnt);
-		if (exclusive) {
-			ocfs2_commit_trans(OCFS2_SB(sb), handle);
-			ocfs2_unlock_global_qf(oinfo, 1);
-		}
-		ocfs2_unlock_global_qf(oinfo, 0);
-	}
-	mlog_exit(0);
-	return 0;
-out_ilock:
-	if (exclusive)
-		ocfs2_unlock_global_qf(oinfo, 1);
-	ocfs2_unlock_global_qf(oinfo, 0);
-out:
-	mlog_exit(status);
-	return status;
-}
-
-static int ocfs2_dquot_drop_slow(struct inode *inode)
-{
-	int status = 0;
-	int cnt;
-	int got_lock[MAXQUOTAS] = {0, 0};
-	handle_t *handle;
-	struct super_block *sb = inode->i_sb;
-	struct ocfs2_mem_dqinfo *oinfo;
-
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (!sb_has_quota_active(sb, cnt))
-			continue;
-		oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
-		status = ocfs2_lock_global_qf(oinfo, 1);
-		if (status < 0)
-			goto out;
-		got_lock[cnt] = 1;
-	}
-	handle = ocfs2_start_trans(OCFS2_SB(sb),
-			ocfs2_calc_qinit_credits(sb, USRQUOTA) +
-			ocfs2_calc_qinit_credits(sb, GRPQUOTA));
-	if (IS_ERR(handle)) {
-		status = PTR_ERR(handle);
-		mlog_errno(status);
-		goto out;
-	}
-	dquot_drop(inode);
-	ocfs2_commit_trans(OCFS2_SB(sb), handle);
-out:
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		if (got_lock[cnt]) {
-			oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
-			ocfs2_unlock_global_qf(oinfo, 1);
-		}
-	return status;
-}
-
-/* See the comment before ocfs2_dquot_initialize. */
-static int ocfs2_dquot_drop(struct inode *inode)
-{
-	int status = 0;
-	struct super_block *sb = inode->i_sb;
-	struct ocfs2_mem_dqinfo *oinfo;
-	int exclusive = 0;
-	int cnt;
-	int got_lock[MAXQUOTAS] = {0, 0};
-
-	mlog_entry_void();
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (!sb_has_quota_active(sb, cnt))
-			continue;
-		oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
-		status = ocfs2_lock_global_qf(oinfo, 0);
-		if (status < 0)
-			goto out;
-		got_lock[cnt] = 1;
-	}
-	/* Lock against anyone releasing references so that when when we check
-	 * we know we are not going to be last ones to release dquot */
-	down_write(&sb_dqopt(sb)->dqptr_sem);
-	/* Urgh, this is a terrible hack :( */
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
-		if (inode->i_dquot[cnt] != NODQUOT &&
-		    atomic_read(&inode->i_dquot[cnt]->dq_count) > 1) {
-			exclusive = 1;
-			break;
-		}
-	}
-	if (!exclusive)
-		dquot_drop_locked(inode);
-	up_write(&sb_dqopt(sb)->dqptr_sem);
-out:
-	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-		if (got_lock[cnt]) {
-			oinfo = sb_dqinfo(sb, cnt)->dqi_priv;
-			ocfs2_unlock_global_qf(oinfo, 0);
-		}
-	/* In case we bailed out because we had to do expensive locking
-	 * do it now... */
-	if (exclusive)
-		status = ocfs2_dquot_drop_slow(inode);
-	mlog_exit(status);
-	return status;
-}
-
 static struct dquot *ocfs2_alloc_dquot(struct super_block *sb, int type)
 {
 	struct ocfs2_dquot *dquot =
@@ -991,8 +826,8 @@ static void ocfs2_destroy_dquot(struct dquot *dquot)
 }
 
 struct dquot_operations ocfs2_quota_operations = {
-	.initialize	= ocfs2_dquot_initialize,
-	.drop		= ocfs2_dquot_drop,
+	.initialize	= dquot_initialize,
+	.drop		= dquot_drop,
 	.alloc_space	= dquot_alloc_space,
 	.alloc_inode	= dquot_alloc_inode,
 	.free_space	= dquot_free_space,
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 03/11] ocfs2: Push out dropping of dentry lock to ocfs2_wq
  2009-01-16 18:08     ` [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop() Jan Kara
@ 2009-01-16 18:08       ` Jan Kara
  2009-01-16 18:08         ` [PATCH 04/11] ocfs2: Fix possible deadlock in ocfs2_write_dquot() Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

Dropping of last reference to dentry lock is a complicated operation involving
dropping of reference to inode. This can get complicated and quota code in
particular needs to obtain some quota locks which leads to potential deadlock.
Thus we defer dropping of inode reference to ocfs2_wq.

Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Mark Fasheh <mfasheh@suse.de>
---
 fs/ocfs2/dcache.c |   42 +++++++++++++++++++++++++++++++++++++++---
 fs/ocfs2/dcache.h |    9 ++++++++-
 fs/ocfs2/ocfs2.h  |    6 ++++++
 fs/ocfs2/super.c  |    3 +++
 4 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index b1cc7c3..e9d7c20 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -38,6 +38,7 @@
 #include "dlmglue.h"
 #include "file.h"
 #include "inode.h"
+#include "super.h"
 
 
 static int ocfs2_dentry_revalidate(struct dentry *dentry,
@@ -294,6 +295,34 @@ out_attach:
 	return ret;
 }
 
+static DEFINE_SPINLOCK(dentry_list_lock);
+
+/* We limit the number of dentry locks to drop in one go. We have
+ * this limit so that we don't starve other users of ocfs2_wq. */
+#define DL_INODE_DROP_COUNT 64
+
+/* Drop inode references from dentry locks */
+void ocfs2_drop_dl_inodes(struct work_struct *work)
+{
+	struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
+					       dentry_lock_work);
+	struct ocfs2_dentry_lock *dl;
+	int drop_count = DL_INODE_DROP_COUNT;
+
+	spin_lock(&dentry_list_lock);
+	while (osb->dentry_lock_list && drop_count--) {
+		dl = osb->dentry_lock_list;
+		osb->dentry_lock_list = dl->dl_next;
+		spin_unlock(&dentry_list_lock);
+		iput(dl->dl_inode);
+		kfree(dl);
+		spin_lock(&dentry_list_lock);
+	}
+	if (osb->dentry_lock_list)
+		queue_work(ocfs2_wq, &osb->dentry_lock_work);
+	spin_unlock(&dentry_list_lock);
+}
+
 /*
  * ocfs2_dentry_iput() and friends.
  *
@@ -318,16 +347,23 @@ out_attach:
 static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
 				   struct ocfs2_dentry_lock *dl)
 {
-	iput(dl->dl_inode);
 	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
 	ocfs2_lock_res_free(&dl->dl_lockres);
-	kfree(dl);
+
+	/* We leave dropping of inode reference to ocfs2_wq as that can
+	 * possibly lead to inode deletion which gets tricky */
+	spin_lock(&dentry_list_lock);
+	if (!osb->dentry_lock_list)
+		queue_work(ocfs2_wq, &osb->dentry_lock_work);
+	dl->dl_next = osb->dentry_lock_list;
+	osb->dentry_lock_list = dl;
+	spin_unlock(&dentry_list_lock);
 }
 
 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
 			   struct ocfs2_dentry_lock *dl)
 {
-	int unlock = 0;
+	int unlock;
 
 	BUG_ON(dl->dl_count == 0);
 
diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h
index c091c34..d06e16c 100644
--- a/fs/ocfs2/dcache.h
+++ b/fs/ocfs2/dcache.h
@@ -29,8 +29,13 @@
 extern struct dentry_operations ocfs2_dentry_ops;
 
 struct ocfs2_dentry_lock {
+	/* Use count of dentry lock */
 	unsigned int		dl_count;
-	u64			dl_parent_blkno;
+	union {
+		/* Linked list of dentry locks to release */
+		struct ocfs2_dentry_lock *dl_next;
+		u64			dl_parent_blkno;
+	};
 
 	/*
 	 * The ocfs2_dentry_lock keeps an inode reference until
@@ -47,6 +52,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, struct inode *inode,
 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
 			   struct ocfs2_dentry_lock *dl);
 
+void ocfs2_drop_dl_inodes(struct work_struct *work);
+
 struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno,
 				      int skip_unhashed);
 
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index ad5c24a..0773841 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -210,6 +210,7 @@ struct ocfs2_journal;
 struct ocfs2_slot_info;
 struct ocfs2_recovery_map;
 struct ocfs2_quota_recovery;
+struct ocfs2_dentry_lock;
 struct ocfs2_super
 {
 	struct task_struct *commit_task;
@@ -325,6 +326,11 @@ struct ocfs2_super
 	struct list_head blocked_lock_list;
 	unsigned long blocked_lock_count;
 
+	/* List of dentry locks to release. Anyone can add locks to
+	 * the list, ocfs2_wq processes the list  */
+	struct ocfs2_dentry_lock *dentry_lock_list;
+	struct work_struct dentry_lock_work;
+
 	wait_queue_head_t		osb_mount_event;
 
 	/* Truncate log info */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 43ed113..b1cb38f 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1887,6 +1887,9 @@ static int ocfs2_initialize_super(struct super_block *sb,
 	INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery);
 	journal->j_state = OCFS2_JOURNAL_FREE;
 
+	INIT_WORK(&osb->dentry_lock_work, ocfs2_drop_dl_inodes);
+	osb->dentry_lock_list = NULL;
+
 	/* get some pseudo constants for clustersize bits */
 	osb->s_clustersize_bits =
 		le32_to_cpu(di->id2.i_super.s_clustersize_bits);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 04/11] ocfs2: Fix possible deadlock in ocfs2_write_dquot()
  2009-01-16 18:08       ` [PATCH 03/11] ocfs2: Push out dropping of dentry lock to ocfs2_wq Jan Kara
@ 2009-01-16 18:08         ` Jan Kara
  2009-01-16 18:08           ` [PATCH 05/11] quota: Add quota reservation support Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

It could happen that some limit has been set via quotactl() and in parallel
->mark_dirty() is called from another thread doing e.g. dquot_alloc_space(). In
such case ocfs2_write_dquot() must not try to sync the dquot because that needs
global quota lock but that ranks above transaction start.

Signed-off-by: Jan Kara <jack@suse.cz>
Acked-by: Mark Fasheh <mfasheh@suse.de>
---
 fs/ocfs2/quota_global.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index f4efa89..1ed0f7c 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -754,7 +754,9 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
 	if (dquot->dq_flags & mask)
 		sync = 1;
 	spin_unlock(&dq_data_lock);
-	if (!sync) {
+	/* This is a slight hack but we can't afford getting global quota
+	 * lock if we already have a transaction started. */
+	if (!sync || journal_current_handle()) {
 		status = ocfs2_write_dquot(dquot);
 		goto out;
 	}
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 05/11] quota: Add quota reservation support
  2009-01-16 18:08         ` [PATCH 04/11] ocfs2: Fix possible deadlock in ocfs2_write_dquot() Jan Kara
@ 2009-01-16 18:08           ` Jan Kara
  2009-01-16 18:08             ` [PATCH 06/11] quota: Add quota reservation claim and released operations Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Mingming Cao, Jan Kara

From: Mingming Cao <cmm@us.ibm.com>

Delayed allocation defers the block allocation at the dirty pages
flush-out time, doing quota charge/check at that time is too late.
But we can't charge the quota blocks until blocks are really allocated,
otherwise users could get overcharged after reboot from system crash.

This patch adds quota reservation for delayed allocation. Quota blocks
are reserved in memory, inode and quota won't gets dirtied until later
block allocation time.

Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dquot.c               |  117 +++++++++++++++++++++++++++++++++------------
 include/linux/quota.h    |    3 +
 include/linux/quotaops.h |   21 ++++++++
 3 files changed, 110 insertions(+), 31 deletions(-)

diff --git a/fs/dquot.c b/fs/dquot.c
index bca3cac..9b1c4d3 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -899,6 +899,11 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
 	dquot->dq_dqb.dqb_curspace += number;
 }
 
+static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
+{
+	dquot->dq_dqb.dqb_rsvspace += number;
+}
+
 static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
 {
 	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
@@ -1068,7 +1073,11 @@ err_out:
 	kfree_skb(skb);
 }
 #endif
-
+/*
+ * Write warnings to the console and send warning messages over netlink.
+ *
+ * Note that this function can sleep.
+ */
 static inline void flush_warnings(struct dquot * const *dquots, char *warntype)
 {
 	int i;
@@ -1129,13 +1138,18 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
 /* needs dq_data_lock */
 static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
 {
+	qsize_t tspace;
+
 	*warntype = QUOTA_NL_NOWARN;
 	if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
 	    test_bit(DQ_FAKE_B, &dquot->dq_flags))
 		return QUOTA_OK;
 
+	tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
+		+ space;
+
 	if (dquot->dq_dqb.dqb_bhardlimit &&
-	    dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit &&
+	    tspace > dquot->dq_dqb.dqb_bhardlimit &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
 			*warntype = QUOTA_NL_BHARDWARN;
@@ -1143,7 +1157,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
 	}
 
 	if (dquot->dq_dqb.dqb_bsoftlimit &&
-	    dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
+	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
 	    dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
@@ -1152,7 +1166,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
 	}
 
 	if (dquot->dq_dqb.dqb_bsoftlimit &&
-	    dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit &&
+	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
 	    dquot->dq_dqb.dqb_btime == 0) {
 		if (!prealloc) {
 			*warntype = QUOTA_NL_BSOFTWARN;
@@ -1306,51 +1320,92 @@ void vfs_dq_drop(struct inode *inode)
 /*
  * This operation can block, but only after everything is updated
  */
-int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
+int __dquot_alloc_space(struct inode *inode, qsize_t number,
+			int warn, int reserve)
 {
-	int cnt, ret = NO_QUOTA;
+	int cnt, ret = QUOTA_OK;
 	char warntype[MAXQUOTAS];
 
-	/* First test before acquiring mutex - solves deadlocks when we
-         * re-enter the quota code and are already holding the mutex */
-	if (IS_NOQUOTA(inode)) {
-out_add:
-		inode_add_bytes(inode, number);
-		return QUOTA_OK;
-	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		warntype[cnt] = QUOTA_NL_NOWARN;
 
-	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
-	if (IS_NOQUOTA(inode)) {	/* Now we can do reliable test... */
-		up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
-		goto out_add;
-	}
 	spin_lock(&dq_data_lock);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
 			continue;
-		if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
-			goto warn_put_all;
+		if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
+		    == NO_QUOTA) {
+			ret = NO_QUOTA;
+			goto out_unlock;
+		}
 	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
 			continue;
-		dquot_incr_space(inode->i_dquot[cnt], number);
+		if (reserve)
+			dquot_resv_space(inode->i_dquot[cnt], number);
+		else
+			dquot_incr_space(inode->i_dquot[cnt], number);
 	}
-	inode_add_bytes(inode, number);
-	ret = QUOTA_OK;
-warn_put_all:
+	if (!reserve)
+		inode_add_bytes(inode, number);
+out_unlock:
 	spin_unlock(&dq_data_lock);
-	if (ret == QUOTA_OK)
-		/* Dirtify all the dquots - this can block when journalling */
-		for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-			if (inode->i_dquot[cnt])
-				mark_dquot_dirty(inode->i_dquot[cnt]);
 	flush_warnings(inode->i_dquot, warntype);
+	return ret;
+}
+
+int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
+{
+	int cnt, ret = QUOTA_OK;
+
+	/*
+	 * First test before acquiring mutex - solves deadlocks when we
+	 * re-enter the quota code and are already holding the mutex
+	 */
+	if (IS_NOQUOTA(inode)) {
+		inode_add_bytes(inode, number);
+		goto out;
+	}
+
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	if (IS_NOQUOTA(inode)) {
+		inode_add_bytes(inode, number);
+		goto out_unlock;
+	}
+
+	ret = __dquot_alloc_space(inode, number, warn, 0);
+	if (ret == NO_QUOTA)
+		goto out_unlock;
+
+	/* Dirtify all the dquots - this can block when journalling */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (inode->i_dquot[cnt])
+			mark_dquot_dirty(inode->i_dquot[cnt]);
+out_unlock:
 	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+out:
+	return ret;
+}
+
+int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
+{
+	int ret = QUOTA_OK;
+
+	if (IS_NOQUOTA(inode))
+		goto out;
+
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	if (IS_NOQUOTA(inode))
+		goto out_unlock;
+
+	ret = __dquot_alloc_space(inode, number, warn, 1);
+out_unlock:
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+out:
 	return ret;
 }
+EXPORT_SYMBOL(dquot_reserve_space);
 
 /*
  * This operation can block, but only after everything is updated
@@ -2057,7 +2112,7 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
 	spin_lock(&dq_data_lock);
 	di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
 	di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
-	di->dqb_curspace = dm->dqb_curspace;
+	di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
 	di->dqb_ihardlimit = dm->dqb_ihardlimit;
 	di->dqb_isoftlimit = dm->dqb_isoftlimit;
 	di->dqb_curinodes = dm->dqb_curinodes;
@@ -2097,7 +2152,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
 
 	spin_lock(&dq_data_lock);
 	if (di->dqb_valid & QIF_SPACE) {
-		dm->dqb_curspace = di->dqb_curspace;
+		dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
 		check_blim = 1;
 		__set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
 	}
diff --git a/include/linux/quota.h b/include/linux/quota.h
index d72d5d8..54b837f 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -198,6 +198,7 @@ struct mem_dqblk {
 	qsize_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
 	qsize_t dqb_bsoftlimit;	/* preferred limit on disk blks */
 	qsize_t dqb_curspace;	/* current used space */
+	qsize_t dqb_rsvspace;   /* current reserved space for delalloc*/
 	qsize_t dqb_ihardlimit;	/* absolute limit on allocated inodes */
 	qsize_t dqb_isoftlimit;	/* preferred inode limit */
 	qsize_t dqb_curinodes;	/* current # allocated inodes */
@@ -308,6 +309,8 @@ struct dquot_operations {
 	int (*release_dquot) (struct dquot *);		/* Quota is going to be deleted from disk */
 	int (*mark_dirty) (struct dquot *);		/* Dquot is marked dirty */
 	int (*write_info) (struct super_block *, int);	/* Write of quota "superblock" */
+	/* reserve quota for delayed block allocation */
+	int (*reserve_space) (struct inode *, qsize_t, int);
 };
 
 /* Operations handling requests from userspace */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 0b35b3a..3e3a0d2 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -183,6 +183,16 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
 	return ret;
 }
 
+static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
+{
+	if (sb_any_quota_active(inode->i_sb)) {
+		/* Used space is updated in alloc_space() */
+		if (inode->i_sb->dq_op->reserve_space(inode, nr, 0) == NO_QUOTA)
+			return 1;
+	}
+	return 0;
+}
+
 static inline int vfs_dq_alloc_inode(struct inode *inode)
 {
 	if (sb_any_quota_active(inode->i_sb)) {
@@ -339,6 +349,11 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
 	return 0;
 }
 
+static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
+{
+	return 0;
+}
+
 static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
 {
 	inode_sub_bytes(inode, nr);
@@ -376,6 +391,12 @@ static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
 			nr << inode->i_sb->s_blocksize_bits);
 }
 
+static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
+{
+	return vfs_dq_reserve_space(inode,
+			nr << inode->i_blkbits);
+}
+
 static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
 {
 	vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 06/11] quota: Add quota reservation claim and released operations
  2009-01-16 18:08           ` [PATCH 05/11] quota: Add quota reservation support Jan Kara
@ 2009-01-16 18:08             ` Jan Kara
  2009-01-16 18:08               ` [PATCH 07/11] quota: Use inode->i_blkbits to get block bits Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Mingming Cao, Jan Kara

From: Mingming Cao <cmm@us.ibm.com>

Reserved quota will be claimed at the block allocation time. Over-booked
quota could be returned back with the release callback function.

Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dquot.c               |  110 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/quota.h    |    6 +++
 include/linux/quotaops.h |   53 ++++++++++++++++++++++
 3 files changed, 165 insertions(+), 4 deletions(-)

diff --git a/fs/dquot.c b/fs/dquot.c
index 9b1c4d3..2916f91 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -904,6 +904,23 @@ static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
 	dquot->dq_dqb.dqb_rsvspace += number;
 }
 
+/*
+ * Claim reserved quota space
+ */
+static void dquot_claim_reserved_space(struct dquot *dquot,
+						qsize_t number)
+{
+	WARN_ON(dquot->dq_dqb.dqb_rsvspace < number);
+	dquot->dq_dqb.dqb_curspace += number;
+	dquot->dq_dqb.dqb_rsvspace -= number;
+}
+
+static inline
+void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
+{
+	dquot->dq_dqb.dqb_rsvspace -= number;
+}
+
 static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
 {
 	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
@@ -1452,6 +1469,72 @@ warn_put_all:
 	return ret;
 }
 
+int dquot_claim_space(struct inode *inode, qsize_t number)
+{
+	int cnt;
+	int ret = QUOTA_OK;
+
+	if (IS_NOQUOTA(inode)) {
+		inode_add_bytes(inode, number);
+		goto out;
+	}
+
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	if (IS_NOQUOTA(inode))	{
+		up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+		inode_add_bytes(inode, number);
+		goto out;
+	}
+
+	spin_lock(&dq_data_lock);
+	/* Claim reserved quotas to allocated quotas */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (inode->i_dquot[cnt] != NODQUOT)
+			dquot_claim_reserved_space(inode->i_dquot[cnt],
+							number);
+	}
+	/* Update inode bytes */
+	inode_add_bytes(inode, number);
+	spin_unlock(&dq_data_lock);
+	/* Dirtify all the dquots - this can block when journalling */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+		if (inode->i_dquot[cnt])
+			mark_dquot_dirty(inode->i_dquot[cnt]);
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+out:
+	return ret;
+}
+EXPORT_SYMBOL(dquot_claim_space);
+
+/*
+ * Release reserved quota space
+ */
+void dquot_release_reserved_space(struct inode *inode, qsize_t number)
+{
+	int cnt;
+
+	if (IS_NOQUOTA(inode))
+		goto out;
+
+	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+	if (IS_NOQUOTA(inode))
+		goto out_unlock;
+
+	spin_lock(&dq_data_lock);
+	/* Release reserved dquots */
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		if (inode->i_dquot[cnt] != NODQUOT)
+			dquot_free_reserved_space(inode->i_dquot[cnt], number);
+	}
+	spin_unlock(&dq_data_lock);
+
+out_unlock:
+	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
+out:
+	return;
+}
+EXPORT_SYMBOL(dquot_release_reserved_space);
+
 /*
  * This operation can block, but only after everything is updated
  */
@@ -1529,6 +1612,19 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
 }
 
 /*
+ * call back function, get reserved quota space from underlying fs
+ */
+qsize_t dquot_get_reserved_space(struct inode *inode)
+{
+	qsize_t reserved_space = 0;
+
+	if (sb_any_quota_active(inode->i_sb) &&
+	    inode->i_sb->dq_op->get_reserved_space)
+		reserved_space = inode->i_sb->dq_op->get_reserved_space(inode);
+	return reserved_space;
+}
+
+/*
  * Transfer the number of inode and blocks from one diskquota to an other.
  *
  * This operation can block, but only after everything is updated
@@ -1536,7 +1632,8 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
  */
 int dquot_transfer(struct inode *inode, struct iattr *iattr)
 {
-	qsize_t space;
+	qsize_t space, cur_space;
+	qsize_t rsv_space = 0;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
 	int cnt, ret = QUOTA_OK;
@@ -1575,7 +1672,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 		goto put_all;
 	}
 	spin_lock(&dq_data_lock);
-	space = inode_get_bytes(inode);
+	cur_space = inode_get_bytes(inode);
+	rsv_space = dquot_get_reserved_space(inode);
+	space = cur_space + rsv_space;
 	/* Build the transfer_from list and check the limits */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (transfer_to[cnt] == NODQUOT)
@@ -1604,11 +1703,14 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
 			warntype_from_space[cnt] =
 				info_bdq_free(transfer_from[cnt], space);
 			dquot_decr_inodes(transfer_from[cnt], 1);
-			dquot_decr_space(transfer_from[cnt], space);
+			dquot_decr_space(transfer_from[cnt], cur_space);
+			dquot_free_reserved_space(transfer_from[cnt],
+						  rsv_space);
 		}
 
 		dquot_incr_inodes(transfer_to[cnt], 1);
-		dquot_incr_space(transfer_to[cnt], space);
+		dquot_incr_space(transfer_to[cnt], cur_space);
+		dquot_resv_space(transfer_to[cnt], rsv_space);
 
 		inode->i_dquot[cnt] = transfer_to[cnt];
 	}
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 54b837f..a510d91 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -311,6 +311,12 @@ struct dquot_operations {
 	int (*write_info) (struct super_block *, int);	/* Write of quota "superblock" */
 	/* reserve quota for delayed block allocation */
 	int (*reserve_space) (struct inode *, qsize_t, int);
+	/* claim reserved quota for delayed alloc */
+	int (*claim_space) (struct inode *, qsize_t);
+	/* release rsved quota for delayed alloc */
+	void (*release_rsv) (struct inode *, qsize_t);
+	/* get reserved quota for delayed alloc */
+	qsize_t (*get_reserved_space) (struct inode *);
 };
 
 /* Operations handling requests from userspace */
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 3e3a0d2..7369d04 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -35,6 +35,11 @@ void dquot_destroy(struct dquot *dquot);
 int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc);
 int dquot_alloc_inode(const struct inode *inode, qsize_t number);
 
+int dquot_reserve_space(struct inode *inode, qsize_t number, int prealloc);
+int dquot_claim_space(struct inode *inode, qsize_t number);
+void dquot_release_reserved_space(struct inode *inode, qsize_t number);
+qsize_t dquot_get_reserved_space(struct inode *inode);
+
 int dquot_free_space(struct inode *inode, qsize_t number);
 int dquot_free_inode(const struct inode *inode, qsize_t number);
 
@@ -203,6 +208,31 @@ static inline int vfs_dq_alloc_inode(struct inode *inode)
 	return 0;
 }
 
+/*
+ * Convert in-memory reserved quotas to real consumed quotas
+ */
+static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
+{
+	if (sb_any_quota_active(inode->i_sb)) {
+		if (inode->i_sb->dq_op->claim_space(inode, nr) == NO_QUOTA)
+			return 1;
+	} else
+		inode_add_bytes(inode, nr);
+
+	mark_inode_dirty(inode);
+	return 0;
+}
+
+/*
+ * Release reserved (in-memory) quotas
+ */
+static inline
+void vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
+{
+	if (sb_any_quota_active(inode->i_sb))
+		inode->i_sb->dq_op->release_rsv(inode, nr);
+}
+
 static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
 {
 	if (sb_any_quota_active(inode->i_sb))
@@ -354,6 +384,17 @@ static inline int vfs_dq_reserve_space(struct inode *inode, qsize_t nr)
 	return 0;
 }
 
+static inline int vfs_dq_claim_space(struct inode *inode, qsize_t nr)
+{
+	return vfs_dq_alloc_space(inode, nr);
+}
+
+static inline
+int vfs_dq_release_reservation_space(struct inode *inode, qsize_t nr)
+{
+	return 0;
+}
+
 static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
 {
 	inode_sub_bytes(inode, nr);
@@ -397,6 +438,18 @@ static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
 			nr << inode->i_blkbits);
 }
 
+static inline int vfs_dq_claim_block(struct inode *inode, qsize_t nr)
+{
+	return vfs_dq_claim_space(inode,
+			nr << inode->i_blkbits);
+}
+
+static inline
+void vfs_dq_release_reservation_block(struct inode *inode, qsize_t nr)
+{
+	vfs_dq_release_reservation_space(inode, nr << inode->i_blkbits);
+}
+
 static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
 {
 	vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 07/11] quota: Use inode->i_blkbits to get block bits
  2009-01-16 18:08             ` [PATCH 06/11] quota: Add quota reservation claim and released operations Jan Kara
@ 2009-01-16 18:08               ` Jan Kara
  2009-01-16 18:08                 ` [PATCH 08/11] quota: Move EXPORT_SYMBOL immediately next to the functions/varibles Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Mingming Cao, Jan Kara

From: Mingming Cao <cmm@us.ibm.com>

Andrew has suggested to use inode->i_blkbits to get the block bits info,
rather than use super block's blockbits. That should be faster and emit
less code.

Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/quotaops.h |   22 ++++++++--------------
 1 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 7369d04..69b502e 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -410,38 +410,32 @@ static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr)
 
 static inline int vfs_dq_prealloc_block_nodirty(struct inode *inode, qsize_t nr)
 {
-	return vfs_dq_prealloc_space_nodirty(inode,
-			nr << inode->i_sb->s_blocksize_bits);
+	return vfs_dq_prealloc_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_prealloc_block(struct inode *inode, qsize_t nr)
 {
-	return vfs_dq_prealloc_space(inode,
-			nr << inode->i_sb->s_blocksize_bits);
+	return vfs_dq_prealloc_space(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_alloc_block_nodirty(struct inode *inode, qsize_t nr)
 {
- 	return vfs_dq_alloc_space_nodirty(inode,
-			nr << inode->i_sb->s_blocksize_bits);
+	return vfs_dq_alloc_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_alloc_block(struct inode *inode, qsize_t nr)
 {
-	return vfs_dq_alloc_space(inode,
-			nr << inode->i_sb->s_blocksize_bits);
+	return vfs_dq_alloc_space(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_reserve_block(struct inode *inode, qsize_t nr)
 {
-	return vfs_dq_reserve_space(inode,
-			nr << inode->i_blkbits);
+	return vfs_dq_reserve_space(inode, nr << inode->i_blkbits);
 }
 
 static inline int vfs_dq_claim_block(struct inode *inode, qsize_t nr)
 {
-	return vfs_dq_claim_space(inode,
-			nr << inode->i_blkbits);
+	return vfs_dq_claim_space(inode, nr << inode->i_blkbits);
 }
 
 static inline
@@ -452,12 +446,12 @@ void vfs_dq_release_reservation_block(struct inode *inode, qsize_t nr)
 
 static inline void vfs_dq_free_block_nodirty(struct inode *inode, qsize_t nr)
 {
-	vfs_dq_free_space_nodirty(inode, nr << inode->i_sb->s_blocksize_bits);
+	vfs_dq_free_space_nodirty(inode, nr << inode->i_blkbits);
 }
 
 static inline void vfs_dq_free_block(struct inode *inode, qsize_t nr)
 {
-	vfs_dq_free_space(inode, nr << inode->i_sb->s_blocksize_bits);
+	vfs_dq_free_space(inode, nr << inode->i_blkbits);
 }
 
 /*
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 08/11] quota: Move EXPORT_SYMBOL immediately next to the functions/varibles
  2009-01-16 18:08               ` [PATCH 07/11] quota: Use inode->i_blkbits to get block bits Jan Kara
@ 2009-01-16 18:08                 ` Jan Kara
  2009-01-16 18:08                   ` [PATCH 09/11] ext3: Remove unnecessary quota functions Jan Kara
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Mingming Cao, Jan Kara

From: Mingming Cao <cmm@us.ibm.com>

According to checkpatch: EXPORT_SYMBOL(foo); should immediately follow its
 function/variable

Signed-off-by: Mingming Cao <cmm@us.ibm.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dquot.c |   69 ++++++++++++++++++++++++++++-------------------------------
 1 files changed, 33 insertions(+), 36 deletions(-)

diff --git a/fs/dquot.c b/fs/dquot.c
index 2916f91..28aa146 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -132,6 +132,7 @@
 static DEFINE_SPINLOCK(dq_list_lock);
 static DEFINE_SPINLOCK(dq_state_lock);
 DEFINE_SPINLOCK(dq_data_lock);
+EXPORT_SYMBOL(dq_data_lock);
 
 static char *quotatypes[] = INITQFNAMES;
 static struct quota_format_type *quota_formats;	/* List of registered formats */
@@ -148,6 +149,7 @@ int register_quota_format(struct quota_format_type *fmt)
 	spin_unlock(&dq_list_lock);
 	return 0;
 }
+EXPORT_SYMBOL(register_quota_format);
 
 void unregister_quota_format(struct quota_format_type *fmt)
 {
@@ -159,6 +161,7 @@ void unregister_quota_format(struct quota_format_type *fmt)
 		*actqf = (*actqf)->qf_next;
 	spin_unlock(&dq_list_lock);
 }
+EXPORT_SYMBOL(unregister_quota_format);
 
 static struct quota_format_type *find_quota_format(int id)
 {
@@ -215,6 +218,7 @@ static unsigned int dq_hash_bits, dq_hash_mask;
 static struct hlist_head *dquot_hash;
 
 struct dqstats dqstats;
+EXPORT_SYMBOL(dqstats);
 
 static inline unsigned int
 hashfn(const struct super_block *sb, unsigned int id, int type)
@@ -309,6 +313,7 @@ int dquot_mark_dquot_dirty(struct dquot *dquot)
 	spin_unlock(&dq_list_lock);
 	return 0;
 }
+EXPORT_SYMBOL(dquot_mark_dquot_dirty);
 
 /* This function needs dq_list_lock */
 static inline int clear_dquot_dirty(struct dquot *dquot)
@@ -360,6 +365,7 @@ out_iolock:
 	mutex_unlock(&dquot->dq_lock);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_acquire);
 
 /*
  *	Write dquot to disk
@@ -389,6 +395,7 @@ out_sem:
 	mutex_unlock(&dqopt->dqio_mutex);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_commit);
 
 /*
  *	Release dquot
@@ -417,6 +424,7 @@ out_dqlock:
 	mutex_unlock(&dquot->dq_lock);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_release);
 
 void dquot_destroy(struct dquot *dquot)
 {
@@ -516,6 +524,7 @@ out:
 	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_scan_active);
 
 int vfs_quota_sync(struct super_block *sb, int type)
 {
@@ -563,6 +572,7 @@ int vfs_quota_sync(struct super_block *sb, int type)
 
 	return 0;
 }
+EXPORT_SYMBOL(vfs_quota_sync);
 
 /* Free unused dquots from cache */
 static void prune_dqcache(int count)
@@ -672,6 +682,7 @@ we_slept:
 	put_dquot_last(dquot);
 	spin_unlock(&dq_list_lock);
 }
+EXPORT_SYMBOL(dqput);
 
 struct dquot *dquot_alloc(struct super_block *sb, int type)
 {
@@ -767,6 +778,7 @@ out:
 
 	return dquot;
 }
+EXPORT_SYMBOL(dqget);
 
 static int dqinit_needed(struct inode *inode, int type)
 {
@@ -1282,6 +1294,7 @@ out_err:
 		dqput(got[cnt]);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_initialize);
 
 /*
  * 	Release all quotas referenced by inode
@@ -1302,6 +1315,7 @@ int dquot_drop(struct inode *inode)
 		dqput(put[cnt]);
 	return 0;
 }
+EXPORT_SYMBOL(dquot_drop);
 
 /* Wrapper to remove references to quota structures from inode */
 void vfs_dq_drop(struct inode *inode)
@@ -1324,6 +1338,7 @@ void vfs_dq_drop(struct inode *inode)
 			inode->i_sb->dq_op->drop(inode);
 	}
 }
+EXPORT_SYMBOL(vfs_dq_drop);
 
 /*
  * Following four functions update i_blocks+i_bytes fields and
@@ -1404,6 +1419,7 @@ out_unlock:
 out:
 	return ret;
 }
+EXPORT_SYMBOL(dquot_alloc_space);
 
 int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
 {
@@ -1468,6 +1484,7 @@ warn_put_all:
 	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_alloc_inode);
 
 int dquot_claim_space(struct inode *inode, qsize_t number)
 {
@@ -1574,6 +1591,7 @@ out_sub:
 	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return QUOTA_OK;
 }
+EXPORT_SYMBOL(dquot_free_space);
 
 /*
  * This operation can block, but only after everything is updated
@@ -1610,6 +1628,7 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
 	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
 	return QUOTA_OK;
 }
+EXPORT_SYMBOL(dquot_free_inode);
 
 /*
  * call back function, get reserved quota space from underlying fs
@@ -1746,6 +1765,7 @@ over_quota:
 	ret = NO_QUOTA;
 	goto warn_put_all;
 }
+EXPORT_SYMBOL(dquot_transfer);
 
 /* Wrapper for transferring ownership of an inode */
 int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
@@ -1757,7 +1777,7 @@ int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
 	}
 	return 0;
 }
-
+EXPORT_SYMBOL(vfs_dq_transfer);
 
 /*
  * Write info of quota file to disk
@@ -1772,6 +1792,7 @@ int dquot_commit_info(struct super_block *sb, int type)
 	mutex_unlock(&dqopt->dqio_mutex);
 	return ret;
 }
+EXPORT_SYMBOL(dquot_commit_info);
 
 /*
  * Definitions of diskquota operations.
@@ -1924,13 +1945,14 @@ put_inodes:
 		}
 	return ret;
 }
+EXPORT_SYMBOL(vfs_quota_disable);
 
 int vfs_quota_off(struct super_block *sb, int type, int remount)
 {
 	return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED :
 				 (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED));
 }
-
+EXPORT_SYMBOL(vfs_quota_off);
 /*
  *	Turn quotas on on a device
  */
@@ -2087,6 +2109,7 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
 					     DQUOT_LIMITS_ENABLED);
 	return error;
 }
+EXPORT_SYMBOL(vfs_quota_on_path);
 
 int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name,
 		 int remount)
@@ -2104,6 +2127,7 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name,
 	}
 	return error;
 }
+EXPORT_SYMBOL(vfs_quota_on);
 
 /*
  * More powerful function for turning on quotas allowing setting
@@ -2150,6 +2174,7 @@ out_lock:
 load_quota:
 	return vfs_load_quota_inode(inode, type, format_id, flags);
 }
+EXPORT_SYMBOL(vfs_quota_enable);
 
 /*
  * This function is used when filesystem needs to initialize quotas
@@ -2179,6 +2204,7 @@ out:
 	dput(dentry);
 	return error;
 }
+EXPORT_SYMBOL(vfs_quota_on_mount);
 
 /* Wrapper to turn on quotas when remounting rw */
 int vfs_dq_quota_on_remount(struct super_block *sb)
@@ -2195,6 +2221,7 @@ int vfs_dq_quota_on_remount(struct super_block *sb)
 	}
 	return ret;
 }
+EXPORT_SYMBOL(vfs_dq_quota_on_remount);
 
 static inline qsize_t qbtos(qsize_t blocks)
 {
@@ -2236,6 +2263,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 
 	return 0;
 }
+EXPORT_SYMBOL(vfs_get_dqblk);
 
 /* Generic routine for setting common part of quota structure */
 static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
@@ -2327,6 +2355,7 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
 out:
 	return rc;
 }
+EXPORT_SYMBOL(vfs_set_dqblk);
 
 /* Generic routine for getting common part of quota file information */
 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
@@ -2348,6 +2377,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
 	return 0;
 }
+EXPORT_SYMBOL(vfs_get_dqinfo);
 
 /* Generic routine for setting common part of quota file information */
 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
@@ -2376,6 +2406,7 @@ out:
 	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
 	return err;
 }
+EXPORT_SYMBOL(vfs_set_dqinfo);
 
 struct quotactl_ops vfs_quotactl_ops = {
 	.quota_on	= vfs_quota_on,
@@ -2531,37 +2562,3 @@ static int __init dquot_init(void)
 	return 0;
 }
 module_init(dquot_init);
-
-EXPORT_SYMBOL(register_quota_format);
-EXPORT_SYMBOL(unregister_quota_format);
-EXPORT_SYMBOL(dqstats);
-EXPORT_SYMBOL(dq_data_lock);
-EXPORT_SYMBOL(vfs_quota_enable);
-EXPORT_SYMBOL(vfs_quota_on);
-EXPORT_SYMBOL(vfs_quota_on_path);
-EXPORT_SYMBOL(vfs_quota_on_mount);
-EXPORT_SYMBOL(vfs_quota_disable);
-EXPORT_SYMBOL(vfs_quota_off);
-EXPORT_SYMBOL(dquot_scan_active);
-EXPORT_SYMBOL(vfs_quota_sync);
-EXPORT_SYMBOL(vfs_get_dqinfo);
-EXPORT_SYMBOL(vfs_set_dqinfo);
-EXPORT_SYMBOL(vfs_get_dqblk);
-EXPORT_SYMBOL(vfs_set_dqblk);
-EXPORT_SYMBOL(dquot_commit);
-EXPORT_SYMBOL(dquot_commit_info);
-EXPORT_SYMBOL(dquot_acquire);
-EXPORT_SYMBOL(dquot_release);
-EXPORT_SYMBOL(dquot_mark_dquot_dirty);
-EXPORT_SYMBOL(dquot_initialize);
-EXPORT_SYMBOL(dquot_drop);
-EXPORT_SYMBOL(vfs_dq_drop);
-EXPORT_SYMBOL(dqget);
-EXPORT_SYMBOL(dqput);
-EXPORT_SYMBOL(dquot_alloc_space);
-EXPORT_SYMBOL(dquot_alloc_inode);
-EXPORT_SYMBOL(dquot_free_space);
-EXPORT_SYMBOL(dquot_free_inode);
-EXPORT_SYMBOL(dquot_transfer);
-EXPORT_SYMBOL(vfs_dq_transfer);
-EXPORT_SYMBOL(vfs_dq_quota_on_remount);
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 09/11] ext3: Remove unnecessary quota functions
  2009-01-16 18:08                 ` [PATCH 08/11] quota: Move EXPORT_SYMBOL immediately next to the functions/varibles Jan Kara
@ 2009-01-16 18:08                   ` Jan Kara
  2009-01-16 18:08                     ` [PATCH 10/11] ext4: " Jan Kara
  2009-01-20 21:41                       ` Mingming Cao
  0 siblings, 2 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

ext3_dquot_initialize() and ext3_dquot_drop() is no longer
needed because of modified quota locking.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext3/super.c |   44 ++------------------------------------------
 1 files changed, 2 insertions(+), 42 deletions(-)

diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index b70d90e..ec410a9 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -707,8 +707,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
 #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
 #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
 
-static int ext3_dquot_initialize(struct inode *inode, int type);
-static int ext3_dquot_drop(struct inode *inode);
 static int ext3_write_dquot(struct dquot *dquot);
 static int ext3_acquire_dquot(struct dquot *dquot);
 static int ext3_release_dquot(struct dquot *dquot);
@@ -723,8 +721,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
 				const char *data, size_t len, loff_t off);
 
 static struct dquot_operations ext3_quota_operations = {
-	.initialize	= ext3_dquot_initialize,
-	.drop		= ext3_dquot_drop,
+	.initialize	= dquot_initialize,
+	.drop		= dquot_drop,
 	.alloc_space	= dquot_alloc_space,
 	.alloc_inode	= dquot_alloc_inode,
 	.free_space	= dquot_free_space,
@@ -2713,44 +2711,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
 	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
 }
 
-static int ext3_dquot_initialize(struct inode *inode, int type)
-{
-	handle_t *handle;
-	int ret, err;
-
-	/* We may create quota structure so we need to reserve enough blocks */
-	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-	ret = dquot_initialize(inode, type);
-	err = ext3_journal_stop(handle);
-	if (!ret)
-		ret = err;
-	return ret;
-}
-
-static int ext3_dquot_drop(struct inode *inode)
-{
-	handle_t *handle;
-	int ret, err;
-
-	/* We may delete quota structure so we need to reserve enough blocks */
-	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (IS_ERR(handle)) {
-		/*
-		 * We call dquot_drop() anyway to at least release references
-		 * to quota structures so that umount does not hang.
-		 */
-		dquot_drop(inode);
-		return PTR_ERR(handle);
-	}
-	ret = dquot_drop(inode);
-	err = ext3_journal_stop(handle);
-	if (!ret)
-		ret = err;
-	return ret;
-}
-
 static int ext3_write_dquot(struct dquot *dquot)
 {
 	int ret, err;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 10/11] ext4: Remove unnecessary quota functions
  2009-01-16 18:08                   ` [PATCH 09/11] ext3: Remove unnecessary quota functions Jan Kara
@ 2009-01-16 18:08                     ` Jan Kara
  2009-01-16 18:08                         ` Jan Kara
  2009-01-20 21:41                         ` Mingming Cao
  2009-01-20 21:41                       ` Mingming Cao
  1 sibling, 2 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

ext4_dquot_initialize() and ext4_dquot_drop() is no longer
needed because of modified quota locking.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/super.c |   44 ++------------------------------------------
 1 files changed, 2 insertions(+), 42 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e5f06a5..f0785fd 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -926,8 +926,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, gfp_
 #define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
 #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
 
-static int ext4_dquot_initialize(struct inode *inode, int type);
-static int ext4_dquot_drop(struct inode *inode);
 static int ext4_write_dquot(struct dquot *dquot);
 static int ext4_acquire_dquot(struct dquot *dquot);
 static int ext4_release_dquot(struct dquot *dquot);
@@ -942,8 +940,8 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
 				const char *data, size_t len, loff_t off);
 
 static struct dquot_operations ext4_quota_operations = {
-	.initialize	= ext4_dquot_initialize,
-	.drop		= ext4_dquot_drop,
+	.initialize	= dquot_initialize,
+	.drop		= dquot_drop,
 	.alloc_space	= dquot_alloc_space,
 	.alloc_inode	= dquot_alloc_inode,
 	.free_space	= dquot_free_space,
@@ -3378,44 +3376,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
 	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
 }
 
-static int ext4_dquot_initialize(struct inode *inode, int type)
-{
-	handle_t *handle;
-	int ret, err;
-
-	/* We may create quota structure so we need to reserve enough blocks */
-	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-	ret = dquot_initialize(inode, type);
-	err = ext4_journal_stop(handle);
-	if (!ret)
-		ret = err;
-	return ret;
-}
-
-static int ext4_dquot_drop(struct inode *inode)
-{
-	handle_t *handle;
-	int ret, err;
-
-	/* We may delete quota structure so we need to reserve enough blocks */
-	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (IS_ERR(handle)) {
-		/*
-		 * We call dquot_drop() anyway to at least release references
-		 * to quota structures so that umount does not hang.
-		 */
-		dquot_drop(inode);
-		return PTR_ERR(handle);
-	}
-	ret = dquot_drop(inode);
-	err = ext4_journal_stop(handle);
-	if (!ret)
-		ret = err;
-	return ret;
-}
-
 static int ext4_write_dquot(struct dquot *dquot)
 {
 	int ret, err;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 11/11] reiserfs: Remove unnecessary quota functions
  2009-01-16 18:08                     ` [PATCH 10/11] ext4: " Jan Kara
@ 2009-01-16 18:08                         ` Jan Kara
  2009-01-20 21:41                         ` Mingming Cao
  1 sibling, 0 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

reiserfs_dquot_initialize() and reiserfs_dquot_drop() is no longer
needed because of modified quota locking.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/reiserfs/super.c |   58 +-------------------------------------------------
 1 files changed, 2 insertions(+), 56 deletions(-)

diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index f3c820b..317c035 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -629,8 +629,6 @@ static const struct super_operations reiserfs_sops = {
 #ifdef CONFIG_QUOTA
 #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
 
-static int reiserfs_dquot_initialize(struct inode *, int);
-static int reiserfs_dquot_drop(struct inode *);
 static int reiserfs_write_dquot(struct dquot *);
 static int reiserfs_acquire_dquot(struct dquot *);
 static int reiserfs_release_dquot(struct dquot *);
@@ -639,8 +637,8 @@ static int reiserfs_write_info(struct super_block *, int);
 static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
 
 static struct dquot_operations reiserfs_quota_operations = {
-	.initialize = reiserfs_dquot_initialize,
-	.drop = reiserfs_dquot_drop,
+	.initialize = dquot_initialize,
+	.drop = dquot_drop,
 	.alloc_space = dquot_alloc_space,
 	.alloc_inode = dquot_alloc_inode,
 	.free_space = dquot_free_space,
@@ -1896,58 +1894,6 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 }
 
 #ifdef CONFIG_QUOTA
-static int reiserfs_dquot_initialize(struct inode *inode, int type)
-{
-	struct reiserfs_transaction_handle th;
-	int ret, err;
-
-	/* We may create quota structure so we need to reserve enough blocks */
-	reiserfs_write_lock(inode->i_sb);
-	ret =
-	    journal_begin(&th, inode->i_sb,
-			  2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (ret)
-		goto out;
-	ret = dquot_initialize(inode, type);
-	err =
-	    journal_end(&th, inode->i_sb,
-			2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (!ret && err)
-		ret = err;
-      out:
-	reiserfs_write_unlock(inode->i_sb);
-	return ret;
-}
-
-static int reiserfs_dquot_drop(struct inode *inode)
-{
-	struct reiserfs_transaction_handle th;
-	int ret, err;
-
-	/* We may delete quota structure so we need to reserve enough blocks */
-	reiserfs_write_lock(inode->i_sb);
-	ret =
-	    journal_begin(&th, inode->i_sb,
-			  2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (ret) {
-		/*
-		 * We call dquot_drop() anyway to at least release references
-		 * to quota structures so that umount does not hang.
-		 */
-		dquot_drop(inode);
-		goto out;
-	}
-	ret = dquot_drop(inode);
-	err =
-	    journal_end(&th, inode->i_sb,
-			2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (!ret && err)
-		ret = err;
-      out:
-	reiserfs_write_unlock(inode->i_sb);
-	return ret;
-}
-
 static int reiserfs_write_dquot(struct dquot *dquot)
 {
 	struct reiserfs_transaction_handle th;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 11/11] reiserfs: Remove unnecessary quota functions
@ 2009-01-16 18:08                         ` Jan Kara
  0 siblings, 0 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-16 18:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-ext4, linux-fsdevel, Jan Kara

reiserfs_dquot_initialize() and reiserfs_dquot_drop() is no longer
needed because of modified quota locking.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/reiserfs/super.c |   58 +-------------------------------------------------
 1 files changed, 2 insertions(+), 56 deletions(-)

diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index f3c820b..317c035 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -629,8 +629,6 @@ static const struct super_operations reiserfs_sops = {
 #ifdef CONFIG_QUOTA
 #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
 
-static int reiserfs_dquot_initialize(struct inode *, int);
-static int reiserfs_dquot_drop(struct inode *);
 static int reiserfs_write_dquot(struct dquot *);
 static int reiserfs_acquire_dquot(struct dquot *);
 static int reiserfs_release_dquot(struct dquot *);
@@ -639,8 +637,8 @@ static int reiserfs_write_info(struct super_block *, int);
 static int reiserfs_quota_on(struct super_block *, int, int, char *, int);
 
 static struct dquot_operations reiserfs_quota_operations = {
-	.initialize = reiserfs_dquot_initialize,
-	.drop = reiserfs_dquot_drop,
+	.initialize = dquot_initialize,
+	.drop = dquot_drop,
 	.alloc_space = dquot_alloc_space,
 	.alloc_inode = dquot_alloc_inode,
 	.free_space = dquot_free_space,
@@ -1896,58 +1894,6 @@ static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 }
 
 #ifdef CONFIG_QUOTA
-static int reiserfs_dquot_initialize(struct inode *inode, int type)
-{
-	struct reiserfs_transaction_handle th;
-	int ret, err;
-
-	/* We may create quota structure so we need to reserve enough blocks */
-	reiserfs_write_lock(inode->i_sb);
-	ret =
-	    journal_begin(&th, inode->i_sb,
-			  2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (ret)
-		goto out;
-	ret = dquot_initialize(inode, type);
-	err =
-	    journal_end(&th, inode->i_sb,
-			2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
-	if (!ret && err)
-		ret = err;
-      out:
-	reiserfs_write_unlock(inode->i_sb);
-	return ret;
-}
-
-static int reiserfs_dquot_drop(struct inode *inode)
-{
-	struct reiserfs_transaction_handle th;
-	int ret, err;
-
-	/* We may delete quota structure so we need to reserve enough blocks */
-	reiserfs_write_lock(inode->i_sb);
-	ret =
-	    journal_begin(&th, inode->i_sb,
-			  2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (ret) {
-		/*
-		 * We call dquot_drop() anyway to at least release references
-		 * to quota structures so that umount does not hang.
-		 */
-		dquot_drop(inode);
-		goto out;
-	}
-	ret = dquot_drop(inode);
-	err =
-	    journal_end(&th, inode->i_sb,
-			2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
-	if (!ret && err)
-		ret = err;
-      out:
-	reiserfs_write_unlock(inode->i_sb);
-	return ret;
-}

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 09/11] ext3: Remove unnecessary quota functions
  2009-01-16 18:08                   ` [PATCH 09/11] ext3: Remove unnecessary quota functions Jan Kara
@ 2009-01-20 21:41                       ` Mingming Cao
  2009-01-20 21:41                       ` Mingming Cao
  1 sibling, 0 replies; 716+ messages in thread
From: Mingming Cao @ 2009-01-20 21:41 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-kernel, linux-ext4, linux-fsdevel


在 2009-01-16五的 19:08 +0100,Jan Kara写道:
> ext3_dquot_initialize() and ext3_dquot_drop() is no longer
> needed because of modified quota locking.
> 
> Signed-off-by: Jan Kara <jack@suse.cz>

Reviewed_by: Mingming Cao <cmm@us.ibm.com>
> ---
>  fs/ext3/super.c |   44 ++------------------------------------------
>  1 files changed, 2 insertions(+), 42 deletions(-)
> 
> diff --git a/fs/ext3/super.c b/fs/ext3/super.c
> index b70d90e..ec410a9 100644
> --- a/fs/ext3/super.c
> +++ b/fs/ext3/super.c
> @@ -707,8 +707,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
>  #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
>  #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
> 
> -static int ext3_dquot_initialize(struct inode *inode, int type);
> -static int ext3_dquot_drop(struct inode *inode);
>  static int ext3_write_dquot(struct dquot *dquot);
>  static int ext3_acquire_dquot(struct dquot *dquot);
>  static int ext3_release_dquot(struct dquot *dquot);
> @@ -723,8 +721,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
>  				const char *data, size_t len, loff_t off);
> 
>  static struct dquot_operations ext3_quota_operations = {
> -	.initialize	= ext3_dquot_initialize,
> -	.drop		= ext3_dquot_drop,
> +	.initialize	= dquot_initialize,
> +	.drop		= dquot_drop,
>  	.alloc_space	= dquot_alloc_space,
>  	.alloc_inode	= dquot_alloc_inode,
>  	.free_space	= dquot_free_space,
> @@ -2713,44 +2711,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
>  	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
>  }
> 
> -static int ext3_dquot_initialize(struct inode *inode, int type)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may create quota structure so we need to reserve enough blocks */
> -	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle))
> -		return PTR_ERR(handle);
> -	ret = dquot_initialize(inode, type);
> -	err = ext3_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
> -static int ext3_dquot_drop(struct inode *inode)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may delete quota structure so we need to reserve enough blocks */
> -	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle)) {
> -		/*
> -		 * We call dquot_drop() anyway to at least release references
> -		 * to quota structures so that umount does not hang.
> -		 */
> -		dquot_drop(inode);
> -		return PTR_ERR(handle);
> -	}
> -	ret = dquot_drop(inode);
> -	err = ext3_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
>  static int ext3_write_dquot(struct dquot *dquot)
>  {
>  	int ret, err;


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 09/11] ext3: Remove unnecessary quota functions
@ 2009-01-20 21:41                       ` Mingming Cao
  0 siblings, 0 replies; 716+ messages in thread
From: Mingming Cao @ 2009-01-20 21:41 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-kernel, linux-ext4, linux-fsdevel


在 2009-01-16五的 19:08 +0100,Jan Kara写道:
> ext3_dquot_initialize() and ext3_dquot_drop() is no longer
> needed because of modified quota locking.
> 
> Signed-off-by: Jan Kara <jack@suse.cz>

Reviewed_by: Mingming Cao <cmm@us.ibm.com>
> ---
>  fs/ext3/super.c |   44 ++------------------------------------------
>  1 files changed, 2 insertions(+), 42 deletions(-)
> 
> diff --git a/fs/ext3/super.c b/fs/ext3/super.c
> index b70d90e..ec410a9 100644
> --- a/fs/ext3/super.c
> +++ b/fs/ext3/super.c
> @@ -707,8 +707,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
>  #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
>  #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
> 
> -static int ext3_dquot_initialize(struct inode *inode, int type);
> -static int ext3_dquot_drop(struct inode *inode);
>  static int ext3_write_dquot(struct dquot *dquot);
>  static int ext3_acquire_dquot(struct dquot *dquot);
>  static int ext3_release_dquot(struct dquot *dquot);
> @@ -723,8 +721,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
>  				const char *data, size_t len, loff_t off);
> 
>  static struct dquot_operations ext3_quota_operations = {
> -	.initialize	= ext3_dquot_initialize,
> -	.drop		= ext3_dquot_drop,
> +	.initialize	= dquot_initialize,
> +	.drop		= dquot_drop,
>  	.alloc_space	= dquot_alloc_space,
>  	.alloc_inode	= dquot_alloc_inode,
>  	.free_space	= dquot_free_space,
> @@ -2713,44 +2711,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
>  	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
>  }
> 
> -static int ext3_dquot_initialize(struct inode *inode, int type)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may create quota structure so we need to reserve enough blocks */
> -	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle))
> -		return PTR_ERR(handle);
> -	ret = dquot_initialize(inode, type);
> -	err = ext3_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
> -static int ext3_dquot_drop(struct inode *inode)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may delete quota structure so we need to reserve enough blocks */
> -	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle)) {
> -		/*
> -		 * We call dquot_drop() anyway to at least release references
> -		 * to quota structures so that umount does not hang.
> -		 */
> -		dquot_drop(inode);
> -		return PTR_ERR(handle);
> -	}
> -	ret = dquot_drop(inode);
> -	err = ext3_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
>  static int ext3_write_dquot(struct dquot *dquot)
>  {
>  	int ret, err;

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 10/11] ext4: Remove unnecessary quota functions
  2009-01-16 18:08                     ` [PATCH 10/11] ext4: " Jan Kara
@ 2009-01-20 21:41                         ` Mingming Cao
  2009-01-20 21:41                         ` Mingming Cao
  1 sibling, 0 replies; 716+ messages in thread
From: Mingming Cao @ 2009-01-20 21:41 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-kernel, linux-ext4, linux-fsdevel


在 2009-01-16五的 19:08 +0100,Jan Kara写道:
> ext4_dquot_initialize() and ext4_dquot_drop() is no longer
> needed because of modified quota locking.
> 
> Signed-off-by: Jan Kara <jack@suse.cz>

Reviewed_by: Mingming Cao <cmm@us.ibm.com>
> ---
>  fs/ext4/super.c |   44 ++------------------------------------------
>  1 files changed, 2 insertions(+), 42 deletions(-)
> 
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index e5f06a5..f0785fd 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -926,8 +926,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, gfp_
>  #define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
>  #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
> 
> -static int ext4_dquot_initialize(struct inode *inode, int type);
> -static int ext4_dquot_drop(struct inode *inode);
>  static int ext4_write_dquot(struct dquot *dquot);
>  static int ext4_acquire_dquot(struct dquot *dquot);
>  static int ext4_release_dquot(struct dquot *dquot);
> @@ -942,8 +940,8 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
>  				const char *data, size_t len, loff_t off);
> 
>  static struct dquot_operations ext4_quota_operations = {
> -	.initialize	= ext4_dquot_initialize,
> -	.drop		= ext4_dquot_drop,
> +	.initialize	= dquot_initialize,
> +	.drop		= dquot_drop,
>  	.alloc_space	= dquot_alloc_space,
>  	.alloc_inode	= dquot_alloc_inode,
>  	.free_space	= dquot_free_space,
> @@ -3378,44 +3376,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
>  	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
>  }
> 
> -static int ext4_dquot_initialize(struct inode *inode, int type)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may create quota structure so we need to reserve enough blocks */
> -	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle))
> -		return PTR_ERR(handle);
> -	ret = dquot_initialize(inode, type);
> -	err = ext4_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
> -static int ext4_dquot_drop(struct inode *inode)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may delete quota structure so we need to reserve enough blocks */
> -	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle)) {
> -		/*
> -		 * We call dquot_drop() anyway to at least release references
> -		 * to quota structures so that umount does not hang.
> -		 */
> -		dquot_drop(inode);
> -		return PTR_ERR(handle);
> -	}
> -	ret = dquot_drop(inode);
> -	err = ext4_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
>  static int ext4_write_dquot(struct dquot *dquot)
>  {
>  	int ret, err;


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 10/11] ext4: Remove unnecessary quota functions
@ 2009-01-20 21:41                         ` Mingming Cao
  0 siblings, 0 replies; 716+ messages in thread
From: Mingming Cao @ 2009-01-20 21:41 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-kernel, linux-ext4, linux-fsdevel


在 2009-01-16五的 19:08 +0100,Jan Kara写道:
> ext4_dquot_initialize() and ext4_dquot_drop() is no longer
> needed because of modified quota locking.
> 
> Signed-off-by: Jan Kara <jack@suse.cz>

Reviewed_by: Mingming Cao <cmm@us.ibm.com>
> ---
>  fs/ext4/super.c |   44 ++------------------------------------------
>  1 files changed, 2 insertions(+), 42 deletions(-)
> 
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index e5f06a5..f0785fd 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -926,8 +926,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, gfp_
>  #define QTYPE2NAME(t) ((t) == USRQUOTA ? "user" : "group")
>  #define QTYPE2MOPT(on, t) ((t) == USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
> 
> -static int ext4_dquot_initialize(struct inode *inode, int type);
> -static int ext4_dquot_drop(struct inode *inode);
>  static int ext4_write_dquot(struct dquot *dquot);
>  static int ext4_acquire_dquot(struct dquot *dquot);
>  static int ext4_release_dquot(struct dquot *dquot);
> @@ -942,8 +940,8 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
>  				const char *data, size_t len, loff_t off);
> 
>  static struct dquot_operations ext4_quota_operations = {
> -	.initialize	= ext4_dquot_initialize,
> -	.drop		= ext4_dquot_drop,
> +	.initialize	= dquot_initialize,
> +	.drop		= dquot_drop,
>  	.alloc_space	= dquot_alloc_space,
>  	.alloc_inode	= dquot_alloc_inode,
>  	.free_space	= dquot_free_space,
> @@ -3378,44 +3376,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot)
>  	return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
>  }
> 
> -static int ext4_dquot_initialize(struct inode *inode, int type)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may create quota structure so we need to reserve enough blocks */
> -	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle))
> -		return PTR_ERR(handle);
> -	ret = dquot_initialize(inode, type);
> -	err = ext4_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
> -static int ext4_dquot_drop(struct inode *inode)
> -{
> -	handle_t *handle;
> -	int ret, err;
> -
> -	/* We may delete quota structure so we need to reserve enough blocks */
> -	handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb));
> -	if (IS_ERR(handle)) {
> -		/*
> -		 * We call dquot_drop() anyway to at least release references
> -		 * to quota structures so that umount does not hang.
> -		 */
> -		dquot_drop(inode);
> -		return PTR_ERR(handle);
> -	}
> -	ret = dquot_drop(inode);
> -	err = ext4_journal_stop(handle);
> -	if (!ret)
> -		ret = err;
> -	return ret;
> -}
> -
>  static int ext4_write_dquot(struct dquot *dquot)
>  {
>  	int ret, err;

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 01/11] quota: Improve locking
  2009-01-16 18:08   ` [PATCH 01/11] quota: Improve locking Jan Kara
  2009-01-16 18:08     ` [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop() Jan Kara
@ 2009-01-24  7:49     ` Andrew Morton
  2009-01-26 10:04       ` Jan Kara
  1 sibling, 1 reply; 716+ messages in thread
From: Andrew Morton @ 2009-01-24  7:49 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-kernel, linux-ext4, linux-fsdevel

On Fri, 16 Jan 2009 19:08:09 +0100 Jan Kara <jack@suse.cz> wrote:

>  static DEFINE_SPINLOCK(dq_list_lock);
> +static DEFINE_SPINLOCK(dq_state_lock);
>  DEFINE_SPINLOCK(dq_data_lock);

The chances are very good that two or even three of these locks will
all get placed into the same cacheline in main memory.  The effects
will be quite bad if different CPUs (or, worse, different nodes) are
taking these locks.

For single, kernel-wide locks like these I think we should almost
always pad out to a cacheline.

With __cacheline_aligned_in_smp, rather than __cacheline_aligned. 
Because spinlocks do take space even in uniprocessor builds.

There are probably lots of existing locks which should be converted.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 01/11] quota: Improve locking
  2009-01-24  7:49     ` [PATCH 01/11] quota: Improve locking Andrew Morton
@ 2009-01-26 10:04       ` Jan Kara
  0 siblings, 0 replies; 716+ messages in thread
From: Jan Kara @ 2009-01-26 10:04 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, linux-ext4, linux-fsdevel

On Fri 23-01-09 23:49:12, Andrew Morton wrote:
> On Fri, 16 Jan 2009 19:08:09 +0100 Jan Kara <jack@suse.cz> wrote:
> 
> >  static DEFINE_SPINLOCK(dq_list_lock);
> > +static DEFINE_SPINLOCK(dq_state_lock);
> >  DEFINE_SPINLOCK(dq_data_lock);
> 
> The chances are very good that two or even three of these locks will
> all get placed into the same cacheline in main memory.  The effects
> will be quite bad if different CPUs (or, worse, different nodes) are
> taking these locks.
>
> For single, kernel-wide locks like these I think we should almost
> always pad out to a cacheline.
  I never thought about this. Thanks for the idea.

> With __cacheline_aligned_in_smp, rather than __cacheline_aligned. 
> Because spinlocks do take space even in uniprocessor builds.
  I've added this to my list of quota cleanups.

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 0/8] kernel:lockdep:replace DFS with BFS
       [not found] <yes>
  2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
@ 2009-05-31 14:49 ` tom.leiming
  2009-05-31 14:49   ` [PATCH 1/8] kernel:lockdep:improve implementation of BFS tom.leiming
  2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
  2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
                   ` (89 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra


Hi,
Currently lockdep uses recursion DFS(depth-first search) algorithm to
search target in checking lock circle(check_noncircular()),irq-safe
-> irq-unsafe(check_irq_usage()) and irq inversion when adding a new
lock dependency. This patches replace the current DFS with BFS, based on
the following consideration:

     1,no loss of efficiency, no matter DFS or BFS, the running time
     are O(V+E) (V is vertex count, and E is edge count of one
     graph);

     2,BFS may be easily implemented by circular queue and consumes
     much less kernel stack space than DFS for DFS is implemented by
     recursion.

     3, The shortest path can be obtained by BFS if the target is
     found, but can't be got by DFS. By the shortest path, we can
     shorten the lock dependency chain and help to troubleshoot lock
     problem easier than before.



^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/8] kernel:lockdep:improve implementation of BFS
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
@ 2009-05-31 14:49   ` tom.leiming
  2009-05-31 14:49     ` [PATCH 2/8] kernel:lockdep: introduce match function to BFS tom.leiming
  2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
  1 sibling, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

1,replace %MAX_CIRCULAR_QUE_SIZE with &(MAX_CIRCULAR_QUE_SIZE-1)
since we define MAX_CIRCULAR_QUE_SIZE as power of 2;

2,use bitmap to mark if a lock is accessed in BFS in order to
clear it quickly, because we may search a graph many times.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c           |   23 ++++++++++++++++-------
 kernel/lockdep_internals.h |   35 +++++++++++++++++++++++------------
 2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 93dc70d..5dcca26 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -42,7 +42,7 @@
 #include <linux/hash.h>
 #include <linux/ftrace.h>
 #include <linux/stringify.h>
-
+#include <linux/bitops.h>
 #include <asm/sections.h>
 
 #include "lockdep_internals.h"
@@ -118,7 +118,7 @@ static inline int debug_locks_off_graph_unlock(void)
 static int lockdep_initialized;
 
 unsigned long nr_list_entries;
-static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
 
 /*
  * All data structures here are protected by the global debug_lock.
@@ -897,30 +897,38 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
 	return 1;
 }
 
+unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
 static struct circular_queue  lock_cq;
+
 static int __search_shortest_path(struct lock_list *source_entry,
 				struct lock_class *target,
 				struct lock_list **target_entry,
 				int forward)
 {
 	struct lock_list *entry;
+	struct list_head *head;
 	struct circular_queue *cq = &lock_cq;
 	int ret = 1;
 
-	__cq_init(cq);
-
-	mark_lock_accessed(source_entry, NULL);
 	if (source_entry->class == target) {
 		*target_entry = source_entry;
 		ret = 0;
 		goto exit;
 	}
 
+	if (forward)
+		head = &source_entry->class->locks_after;
+	else
+		head = &source_entry->class->locks_before;
+
+	if (list_empty(head))
+		goto exit;
+
+	__cq_init(cq);
 	__cq_enqueue(cq, (unsigned long)source_entry);
 
 	while (!__cq_empty(cq)) {
 		struct lock_list *lock;
-		struct list_head *head;
 
 		__cq_dequeue(cq, (unsigned long *)&lock);
 
@@ -1040,6 +1048,7 @@ static noinline int print_circular_bug(void)
 		return 0;
 
 	this.class = hlock_class(check_source);
+	this.parent = NULL;
 	if (!save_trace(&this.trace))
 		return 0;
 
@@ -1580,10 +1589,10 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
 	 */
 	check_source = next;
 	check_target = prev;
+
 	if (check_noncircular(hlock_class(next), 0) == 2)
 		return print_circular_bug();
 
-
 	if (!check_prev_add_irq(curr, prev, next))
 		return 0;
 
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index 6f48d37..c2f6594 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -137,23 +137,28 @@ extern atomic_t nr_find_usage_backwards_recursions;
 # define debug_atomic_read(ptr)		0
 #endif
 
+
+extern unsigned long nr_list_entries;
+extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+extern unsigned long bfs_accessed[];
+
+/*For good efficiency of modular, we use power of 2*/
+#define  MAX_CIRCULAR_QUE_SIZE	    4096UL
+
 /* The circular_queue and helpers is used to implement the
  * breadth-first search(BFS)algorithem, by which we can build
  * the shortest path from the next lock to be acquired to the
  * previous held lock if there is a circular between them.
  * */
-#define  MAX_CIRCULAR_QUE_SIZE	    4096UL
 struct circular_queue{
 	unsigned long element[MAX_CIRCULAR_QUE_SIZE];
 	unsigned int  front, rear;
 };
 
-#define LOCK_ACCESSED 		1UL
-#define LOCK_ACCESSED_MASK	(~LOCK_ACCESSED)
-
 static inline void __cq_init(struct circular_queue *cq)
 {
 	cq->front = cq->rear = 0;
+	bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
 }
 
 static inline int __cq_empty(struct circular_queue *cq)
@@ -163,7 +168,7 @@ static inline int __cq_empty(struct circular_queue *cq)
 
 static inline int __cq_full(struct circular_queue *cq)
 {
-	return ((cq->rear + 1)%MAX_CIRCULAR_QUE_SIZE)  == cq->front;
+	return ((cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1))  == cq->front;
 }
 
 static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
@@ -172,7 +177,7 @@ static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
 		return -1;
 
 	cq->element[cq->rear] = elem;
-	cq->rear = (cq->rear + 1)%MAX_CIRCULAR_QUE_SIZE;
+	cq->rear = (cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
 	return 0;
 }
 
@@ -182,30 +187,36 @@ static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
 		return -1;
 
 	*elem = cq->element[cq->front];
-	cq->front = (cq->front + 1)%MAX_CIRCULAR_QUE_SIZE;
+	cq->front = (cq->front + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
 	return 0;
 }
 
 static inline int __cq_get_elem_count(struct circular_queue *cq)
 {
-	return (cq->rear - cq->front)%MAX_CIRCULAR_QUE_SIZE;
+	return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
 }
 
 static inline void mark_lock_accessed(struct lock_list *lock,
 					struct lock_list *parent)
 {
-	lock->parent = (void *) parent + LOCK_ACCESSED;
+	unsigned long nr;
+	nr = lock - list_entries;
+	WARN_ON(nr >= nr_list_entries);
+	lock->parent = parent;
+	set_bit(nr, bfs_accessed);
 }
 
 static inline unsigned long lock_accessed(struct lock_list *lock)
 {
-	return (unsigned long)lock->parent & LOCK_ACCESSED;
+	unsigned long nr;
+	nr = lock - list_entries;
+	WARN_ON(nr >= nr_list_entries);
+	return test_bit(nr, bfs_accessed);
 }
 
 static inline struct lock_list *get_lock_parent(struct lock_list *child)
 {
-	return (struct lock_list *)
-		((unsigned long)child->parent & LOCK_ACCESSED_MASK);
+	return child->parent;
 }
 
 static inline unsigned long get_lock_depth(struct lock_list *child)
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/8] kernel:lockdep: introduce match function to BFS
  2009-05-31 14:49   ` [PATCH 1/8] kernel:lockdep:improve implementation of BFS tom.leiming
@ 2009-05-31 14:49     ` tom.leiming
  2009-05-31 14:49       ` [PATCH 3/8] kernel:lockdep:implement check_noncircular() by BFS tom.leiming
  0 siblings, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

1,introduce match() to BFS in order to make it usable to
match different pattern;

2,also rename some functions to make them more suitable.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |   43 ++++++++++++++++++++++++++-----------------
 1 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 5dcca26..ce6d09e 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -900,17 +900,18 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
 unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
 static struct circular_queue  lock_cq;
 
-static int __search_shortest_path(struct lock_list *source_entry,
-				struct lock_class *target,
-				struct lock_list **target_entry,
-				int forward)
+static int __bfs(struct lock_list *source_entry,
+			void *data,
+			int (*match)(struct lock_list *entry, void *data),
+			struct lock_list **target_entry,
+			int forward)
 {
 	struct lock_list *entry;
 	struct list_head *head;
 	struct circular_queue *cq = &lock_cq;
 	int ret = 1;
 
-	if (source_entry->class == target) {
+	if (match(source_entry, data)) {
 		*target_entry = source_entry;
 		ret = 0;
 		goto exit;
@@ -945,7 +946,7 @@ static int __search_shortest_path(struct lock_list *source_entry,
 		list_for_each_entry(entry, head, entry) {
 			if (!lock_accessed(entry)) {
 				mark_lock_accessed(entry, lock);
-				if (entry->class == target) {
+				if (match(entry, data)) {
 					*target_entry = entry;
 					ret = 0;
 					goto exit;
@@ -962,19 +963,21 @@ exit:
 	return ret;
 }
 
-static inline int __search_forward_shortest_path(struct lock_list *src_entry,
-				struct lock_class *target,
-				struct lock_list **target_entry)
+static inline int __bfs_forward(struct lock_list *src_entry,
+			void *data,
+			int (*match)(struct lock_list *entry, void *data),
+			struct lock_list **target_entry)
 {
-	return __search_shortest_path(src_entry, target, target_entry, 1);
+	return __bfs(src_entry, data, match, target_entry, 1);
 
 }
 
-static inline int __search_backward_shortest_path(struct lock_list *src_entry,
-				struct lock_class *target,
-				struct lock_list **target_entry)
+static inline int __bfs_backward(struct lock_list *src_entry,
+			void *data,
+			int (*match)(struct lock_list *entry, void *data),
+			struct lock_list **target_entry)
 {
-	return __search_shortest_path(src_entry, target, target_entry, 0);
+	return __bfs(src_entry, data, match, target_entry, 0);
 
 }
 
@@ -1035,6 +1038,11 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
 	return 0;
 }
 
+static inline int class_equal(struct lock_list *entry, void *data)
+{
+	return entry->class == data;
+}
+
 static noinline int print_circular_bug(void)
 {
 	struct task_struct *curr = current;
@@ -1052,9 +1060,10 @@ static noinline int print_circular_bug(void)
 	if (!save_trace(&this.trace))
 		return 0;
 
-	result = __search_forward_shortest_path(&this,
-						hlock_class(check_target),
-						&target);
+	result = __bfs_forward(&this,
+			hlock_class(check_target),
+			class_equal,
+			&target);
 	if (result) {
 		printk("\n%s:search shortest path failed:%d\n", __func__,
 			result);
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/8] kernel:lockdep:implement check_noncircular() by BFS
  2009-05-31 14:49     ` [PATCH 2/8] kernel:lockdep: introduce match function to BFS tom.leiming
@ 2009-05-31 14:49       ` tom.leiming
  2009-05-31 14:49         ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards " tom.leiming
  0 siblings, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

This patch uses BFS to implement check_noncircular() and
prints the generated shortest circle if exists.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |   89 ++++++++++++++++++++++-------------------------------
 1 files changed, 37 insertions(+), 52 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index ce6d09e..f740088 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -985,12 +985,7 @@ static inline int __bfs_backward(struct lock_list *src_entry,
  * Recursive, forwards-direction lock-dependency checking, used for
  * both noncyclic checking and for hardirq-unsafe/softirq-unsafe
  * checking.
- *
- * (to keep the stackframe of the recursive functions small we
- *  use these global variables, and we also mark various helper
- *  functions as noinline.)
  */
-static struct held_lock *check_source, *check_target;
 
 /*
  * Print a dependency chain entry (this is only done when a deadlock
@@ -1014,7 +1009,9 @@ print_circular_bug_entry(struct lock_list *target, unsigned int depth)
  * header first:
  */
 static noinline int
-print_circular_bug_header(struct lock_list *entry, unsigned int depth)
+print_circular_bug_header(struct lock_list *entry, unsigned int depth,
+			struct held_lock *check_src,
+			struct held_lock *check_tgt)
 {
 	struct task_struct *curr = current;
 
@@ -1027,9 +1024,9 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
 	printk(  "-------------------------------------------------------\n");
 	printk("%s/%d is trying to acquire lock:\n",
 		curr->comm, task_pid_nr(curr));
-	print_lock(check_source);
+	print_lock(check_src);
 	printk("\nbut task is already holding lock:\n");
-	print_lock(check_target);
+	print_lock(check_tgt);
 	printk("\nwhich lock already depends on the new lock.\n\n");
 	printk("\nthe existing dependency chain (in reverse order) is:\n");
 
@@ -1043,36 +1040,24 @@ static inline int class_equal(struct lock_list *entry, void *data)
 	return entry->class == data;
 }
 
-static noinline int print_circular_bug(void)
+static noinline int print_circular_bug(struct lock_list *this,
+				struct lock_list *target,
+				struct held_lock *check_src,
+				struct held_lock *check_tgt)
 {
 	struct task_struct *curr = current;
-	struct lock_list this;
-	struct lock_list *target;
 	struct lock_list *parent;
-	int result;
 	unsigned long depth;
 
 	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
 		return 0;
 
-	this.class = hlock_class(check_source);
-	this.parent = NULL;
-	if (!save_trace(&this.trace))
+	if (!save_trace(&this->trace))
 		return 0;
 
-	result = __bfs_forward(&this,
-			hlock_class(check_target),
-			class_equal,
-			&target);
-	if (result) {
-		printk("\n%s:search shortest path failed:%d\n", __func__,
-			result);
-		return 0;
-	}
-
 	depth = get_lock_depth(target);
 
-	print_circular_bug_header(target, depth);
+	print_circular_bug_header(target, depth, check_src, check_tgt);
 
 	parent = get_lock_parent(target);
 
@@ -1090,6 +1075,16 @@ static noinline int print_circular_bug(void)
 	return 0;
 }
 
+static int noinline print_bfs_bug(int ret)
+{
+	if (!debug_locks_off_graph_unlock())
+		return 0;
+
+	WARN(1, "lockdep bfs error:%d\n", ret);
+
+	return 0;
+}
+
 #define RECURSION_LIMIT 40
 
 static int noinline print_infinite_recursion_bug(void)
@@ -1168,31 +1163,17 @@ unsigned long lockdep_count_backward_deps(struct lock_class *class)
  * lead to <target>. Print an error and return 0 if it does.
  */
 static noinline int
-check_noncircular(struct lock_class *source, unsigned int depth)
+check_noncircular(struct lock_list *root, struct lock_class *target,
+		struct lock_list **target_entry)
 {
-	struct lock_list *entry;
+	int result;
 
-	if (lockdep_dependency_visit(source, depth))
-		return 1;
+	debug_atomic_inc(&nr_cyclic_checks);
 
-	debug_atomic_inc(&nr_cyclic_check_recursions);
-	if (depth > max_recursion_depth)
-		max_recursion_depth = depth;
-	if (depth >= RECURSION_LIMIT)
-		return print_infinite_recursion_bug();
-	/*
-	 * Check this lock's dependency list:
-	 */
-	list_for_each_entry(entry, &source->locks_after, entry) {
-		if (entry->class == hlock_class(check_target))
-			return 2;
-		debug_atomic_inc(&nr_cyclic_checks);
-		if (check_noncircular(entry->class, depth+1) == 2)
-			return 2;
-	}
-	return 1;
-}
+	result = __bfs_forward(root, target, class_equal, target_entry);
 
+	return result;
+}
 
 #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING)
 /*
@@ -1586,6 +1567,8 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
 {
 	struct lock_list *entry;
 	int ret;
+	struct lock_list this;
+	struct lock_list *uninitialized_var(target_entry);
 
 	/*
 	 * Prove that the new <prev> -> <next> dependency would not
@@ -1596,11 +1579,13 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
 	 * We are using global variables to control the recursion, to
 	 * keep the stackframe size of the recursive functions low:
 	 */
-	check_source = next;
-	check_target = prev;
-
-	if (check_noncircular(hlock_class(next), 0) == 2)
-		return print_circular_bug();
+	this.class = hlock_class(next);
+	this.parent = NULL;
+	ret = check_noncircular(&this, hlock_class(prev), &target_entry);
+	if (unlikely(!ret))
+		return print_circular_bug(&this, target_entry, next, prev);
+	else if (unlikely(ret < 0))
+		return print_bfs_bug(ret);
 
 	if (!check_prev_add_irq(curr, prev, next))
 		return 0;
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS
  2009-05-31 14:49       ` [PATCH 3/8] kernel:lockdep:implement check_noncircular() by BFS tom.leiming
@ 2009-05-31 14:49         ` tom.leiming
  2009-05-31 14:49           ` [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
  2009-05-31 15:14           ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS Daniel Walker
  0 siblings, 2 replies; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

This patch uses BFS to implement find_usage_*wards(),which
was originally writen by DFS.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |  180 ++++++++++++++++++++++--------------------------------
 1 files changed, 72 insertions(+), 108 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index f740088..94b2f1f 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -963,7 +963,7 @@ exit:
 	return ret;
 }
 
-static inline int __bfs_forward(struct lock_list *src_entry,
+static inline int __bfs_forwards(struct lock_list *src_entry,
 			void *data,
 			int (*match)(struct lock_list *entry, void *data),
 			struct lock_list **target_entry)
@@ -972,7 +972,7 @@ static inline int __bfs_forward(struct lock_list *src_entry,
 
 }
 
-static inline int __bfs_backward(struct lock_list *src_entry,
+static inline int __bfs_backwards(struct lock_list *src_entry,
 			void *data,
 			int (*match)(struct lock_list *entry, void *data),
 			struct lock_list **target_entry)
@@ -1085,18 +1085,6 @@ static int noinline print_bfs_bug(int ret)
 	return 0;
 }
 
-#define RECURSION_LIMIT 40
-
-static int noinline print_infinite_recursion_bug(void)
-{
-	if (!debug_locks_off_graph_unlock())
-		return 0;
-
-	WARN_ON(1);
-
-	return 0;
-}
-
 unsigned long __lockdep_count_forward_deps(struct lock_class *class,
 					   unsigned int depth)
 {
@@ -1170,7 +1158,7 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
 
 	debug_atomic_inc(&nr_cyclic_checks);
 
-	result = __bfs_forward(root, target, class_equal, target_entry);
+	result = __bfs_forwards(root, target, class_equal, target_entry);
 
 	return result;
 }
@@ -1181,101 +1169,70 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
  * proving that two subgraphs can be connected by a new dependency
  * without creating any illegal irq-safe -> irq-unsafe lock dependency.
  */
-static enum lock_usage_bit find_usage_bit;
 static struct lock_class *forwards_match, *backwards_match;
 
+
+#define   BFS_PROCESS_RET(ret)	do { \
+					if (ret < 0) \
+						return print_bfs_bug(ret); \
+					if (ret == 1) \
+						return 1; \
+				} while (0)
+
+static inline int usage_match(struct lock_list *entry, void *bit)
+{
+	return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
+}
+
+
+
 /*
  * Find a node in the forwards-direction dependency sub-graph starting
- * at <source> that matches <find_usage_bit>.
+ * at @root->class that matches @bit.
  *
- * Return 2 if such a node exists in the subgraph, and put that node
- * into <forwards_match>.
+ * Return 0 if such a node exists in the subgraph, and put that node
+ * into *@target_entry.
  *
- * Return 1 otherwise and keep <forwards_match> unchanged.
- * Return 0 on error.
+ * Return 1 otherwise and keep *@target_entry unchanged.
+ * Return <0 on error.
  */
-static noinline int
-find_usage_forwards(struct lock_class *source, unsigned int depth)
+static int
+find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
+			struct lock_list **target_entry)
 {
-	struct lock_list *entry;
-	int ret;
-
-	if (lockdep_dependency_visit(source, depth))
-		return 1;
-
-	if (depth > max_recursion_depth)
-		max_recursion_depth = depth;
-	if (depth >= RECURSION_LIMIT)
-		return print_infinite_recursion_bug();
+	int result;
 
 	debug_atomic_inc(&nr_find_usage_forwards_checks);
-	if (source->usage_mask & (1 << find_usage_bit)) {
-		forwards_match = source;
-		return 2;
-	}
 
-	/*
-	 * Check this lock's dependency list:
-	 */
-	list_for_each_entry(entry, &source->locks_after, entry) {
-		debug_atomic_inc(&nr_find_usage_forwards_recursions);
-		ret = find_usage_forwards(entry->class, depth+1);
-		if (ret == 2 || ret == 0)
-			return ret;
-	}
-	return 1;
+	result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
+
+	return result;
 }
 
 /*
  * Find a node in the backwards-direction dependency sub-graph starting
- * at <source> that matches <find_usage_bit>.
+ * at @root->class that matches @bit.
  *
- * Return 2 if such a node exists in the subgraph, and put that node
- * into <backwards_match>.
+ * Return 0 if such a node exists in the subgraph, and put that node
+ * into *@target_entry.
  *
- * Return 1 otherwise and keep <backwards_match> unchanged.
- * Return 0 on error.
+ * Return 1 otherwise and keep *@target_entry unchanged.
+ * Return <0 on error.
  */
-static noinline int
-find_usage_backwards(struct lock_class *source, unsigned int depth)
+static int
+find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
+			struct lock_list **target_entry)
 {
-	struct lock_list *entry;
-	int ret;
-
-	if (lockdep_dependency_visit(source, depth))
-		return 1;
-
-	if (!__raw_spin_is_locked(&lockdep_lock))
-		return DEBUG_LOCKS_WARN_ON(1);
-
-	if (depth > max_recursion_depth)
-		max_recursion_depth = depth;
-	if (depth >= RECURSION_LIMIT)
-		return print_infinite_recursion_bug();
+	int result;
 
 	debug_atomic_inc(&nr_find_usage_backwards_checks);
-	if (source->usage_mask & (1 << find_usage_bit)) {
-		backwards_match = source;
-		return 2;
-	}
 
-	if (!source && debug_locks_off_graph_unlock()) {
-		WARN_ON(1);
-		return 0;
-	}
+	result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
 
-	/*
-	 * Check this lock's dependency list:
-	 */
-	list_for_each_entry(entry, &source->locks_before, entry) {
-		debug_atomic_inc(&nr_find_usage_backwards_recursions);
-		ret = find_usage_backwards(entry->class, depth+1);
-		if (ret == 2 || ret == 0)
-			return ret;
-	}
-	return 1;
+	return result;
 }
 
+
 static int
 print_bad_irq_dependency(struct task_struct *curr,
 			 struct held_lock *prev,
@@ -1343,18 +1300,21 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
 	    enum lock_usage_bit bit_forwards, const char *irqclass)
 {
 	int ret;
+	struct lock_list this;
+	struct lock_list *uninitialized_var(target_entry);
+
+	this.parent = NULL;
+
+	this.class = hlock_class(prev);
+	ret = find_usage_backwards(&this, bit_backwards, &target_entry);
+	BFS_PROCESS_RET(ret);
+	backwards_match = target_entry->class;
+
+	this.class = hlock_class(next);
+	ret = find_usage_forwards(&this, bit_forwards, &target_entry);
+	BFS_PROCESS_RET(ret);
+	forwards_match = target_entry->class;
 
-	find_usage_bit = bit_backwards;
-	/* fills in <backwards_match> */
-	ret = find_usage_backwards(hlock_class(prev), 0);
-	if (!ret || ret == 1)
-		return ret;
-
-	find_usage_bit = bit_forwards;
-	ret = find_usage_forwards(hlock_class(next), 0);
-	if (!ret || ret == 1)
-		return ret;
-	/* ret == 2 */
 	return print_bad_irq_dependency(curr, prev, next,
 			bit_backwards, bit_forwards, irqclass);
 }
@@ -2029,14 +1989,16 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
 		     enum lock_usage_bit bit, const char *irqclass)
 {
 	int ret;
+	struct lock_list root;
+	struct lock_list *uninitialized_var(target_entry);
 
-	find_usage_bit = bit;
-	/* fills in <forwards_match> */
-	ret = find_usage_forwards(hlock_class(this), 0);
-	if (!ret || ret == 1)
-		return ret;
+	root.parent = NULL;
+	root.class = hlock_class(this);
+	ret = find_usage_forwards(&root, bit, &target_entry);
+	BFS_PROCESS_RET(ret);
 
-	return print_irq_inversion_bug(curr, forwards_match, this, 1, irqclass);
+	return print_irq_inversion_bug(curr, target_entry->class,
+					this, 1, irqclass);
 }
 
 /*
@@ -2048,14 +2010,16 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
 		      enum lock_usage_bit bit, const char *irqclass)
 {
 	int ret;
+	struct lock_list root;
+	struct lock_list *uninitialized_var(target_entry);
 
-	find_usage_bit = bit;
-	/* fills in <backwards_match> */
-	ret = find_usage_backwards(hlock_class(this), 0);
-	if (!ret || ret == 1)
-		return ret;
+	root.parent = NULL;
+	root.class = hlock_class(this);
+	ret = find_usage_backwards(&root, bit, &target_entry);
+	BFS_PROCESS_RET(ret);
 
-	return print_irq_inversion_bug(curr, backwards_match, this, 0, irqclass);
+	return print_irq_inversion_bug(curr, target_entry->class,
+					this, 1, irqclass);
 }
 
 void print_irqtrace_events(struct task_struct *curr)
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies
  2009-05-31 14:49         ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards " tom.leiming
@ 2009-05-31 14:49           ` tom.leiming
  2009-05-31 14:49             ` [PATCH 6/8] kernel:lockdep: implement lockdep_count_*ward_deps by BFS tom.leiming
  2009-05-31 15:14           ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS Daniel Walker
  1 sibling, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>

Since the shortest lock dependencies' path may be obtained by BFS,
we print the shortest one by print_shortest_lock_dependencies().

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c           |   93 +++++++++++++++++++++++++++++++------------
 kernel/lockdep_internals.h |    4 +-
 2 files changed, 69 insertions(+), 28 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 94b2f1f..d839994 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -576,6 +576,36 @@ static void print_lock_class_header(struct lock_class *class, int depth)
 }
 
 /*
+ * printk the shortest lock dependencies from @start to @end in reverse order:
+ */
+static void __used
+print_shortest_lock_dependencies(struct lock_list *leaf,
+				struct lock_list *root)
+{
+	struct lock_list *entry = leaf;
+	int depth;
+
+	/*compute depth from generated tree by BFS*/
+	depth = get_lock_depth(leaf);
+
+	do {
+		print_lock_class_header(entry->class, depth);
+		printk("%*s ... acquired at:\n", depth, "");
+		print_stack_trace(&entry->trace, 2);
+		printk("\n");
+
+		if (depth == 0 && (entry != root)) {
+			printk("lockdep:%s bad BFS generated tree\n", __func__);
+			break;
+		}
+
+		entry = get_lock_parent(entry);
+		depth--;
+	} while (entry && (depth >= 0));
+
+	return;
+}
+/*
  * printk all lock dependencies starting at <entry>:
  */
 static void __used
@@ -992,7 +1022,7 @@ static inline int __bfs_backwards(struct lock_list *src_entry,
  * has been detected):
  */
 static noinline int
-print_circular_bug_entry(struct lock_list *target, unsigned int depth)
+print_circular_bug_entry(struct lock_list *target, int depth)
 {
 	if (debug_locks_silent)
 		return 0;
@@ -1047,7 +1077,7 @@ static noinline int print_circular_bug(struct lock_list *this,
 {
 	struct task_struct *curr = current;
 	struct lock_list *parent;
-	unsigned long depth;
+	int depth;
 
 	if (!debug_locks_off_graph_unlock() || debug_locks_silent)
 		return 0;
@@ -1169,7 +1199,6 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
  * proving that two subgraphs can be connected by a new dependency
  * without creating any illegal irq-safe -> irq-unsafe lock dependency.
  */
-static struct lock_class *forwards_match, *backwards_match;
 
 
 #define   BFS_PROCESS_RET(ret)	do { \
@@ -1235,6 +1264,10 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
 
 static int
 print_bad_irq_dependency(struct task_struct *curr,
+			 struct lock_list *prev_root,
+			 struct lock_list *next_root,
+			 struct lock_list *backwards_entry,
+			 struct lock_list *forwards_entry,
 			 struct held_lock *prev,
 			 struct held_lock *next,
 			 enum lock_usage_bit bit1,
@@ -1267,26 +1300,32 @@ print_bad_irq_dependency(struct task_struct *curr,
 
 	printk("\nbut this new dependency connects a %s-irq-safe lock:\n",
 		irqclass);
-	print_lock_name(backwards_match);
+	print_lock_name(backwards_entry->class);
 	printk("\n... which became %s-irq-safe at:\n", irqclass);
 
-	print_stack_trace(backwards_match->usage_traces + bit1, 1);
+	print_stack_trace(backwards_entry->class->usage_traces + bit1, 1);
 
 	printk("\nto a %s-irq-unsafe lock:\n", irqclass);
-	print_lock_name(forwards_match);
+	print_lock_name(forwards_entry->class);
 	printk("\n... which became %s-irq-unsafe at:\n", irqclass);
 	printk("...");
 
-	print_stack_trace(forwards_match->usage_traces + bit2, 1);
+	print_stack_trace(forwards_entry->class->usage_traces + bit2, 1);
 
 	printk("\nother info that might help us debug this:\n\n");
 	lockdep_print_held_locks(curr);
 
-	printk("\nthe %s-irq-safe lock's dependencies:\n", irqclass);
-	print_lock_dependencies(backwards_match, 0);
+	printk("\nthe dependencies between %s-irq-safe lock", irqclass);
+	printk(" and the holding lock:\n");
+	if (!save_trace(&prev_root->trace))
+		return 0;
+	print_shortest_lock_dependencies(backwards_entry, prev_root);
 
-	printk("\nthe %s-irq-unsafe lock's dependencies:\n", irqclass);
-	print_lock_dependencies(forwards_match, 0);
+	printk("\nthe dependencies between the lock to be acquired");
+	printk(" and %s-irq-unsafe lock:\n", irqclass);
+	if (!save_trace(&next_root->trace))
+		return 0;
+	print_shortest_lock_dependencies(forwards_entry, next_root);
 
 	printk("\nstack backtrace:\n");
 	dump_stack();
@@ -1300,22 +1339,24 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
 	    enum lock_usage_bit bit_forwards, const char *irqclass)
 {
 	int ret;
-	struct lock_list this;
+	struct lock_list this, that;
 	struct lock_list *uninitialized_var(target_entry);
+	struct lock_list *uninitialized_var(target_entry1);
 
 	this.parent = NULL;
 
 	this.class = hlock_class(prev);
 	ret = find_usage_backwards(&this, bit_backwards, &target_entry);
 	BFS_PROCESS_RET(ret);
-	backwards_match = target_entry->class;
 
-	this.class = hlock_class(next);
-	ret = find_usage_forwards(&this, bit_forwards, &target_entry);
+	that.parent = NULL;
+	that.class = hlock_class(next);
+	ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
 	BFS_PROCESS_RET(ret);
-	forwards_match = target_entry->class;
 
-	return print_bad_irq_dependency(curr, prev, next,
+	return print_bad_irq_dependency(curr, &this, &that,
+			target_entry, target_entry1,
+			prev, next,
 			bit_backwards, bit_forwards, irqclass);
 }
 
@@ -1944,7 +1985,8 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
  * print irq inversion bug:
  */
 static int
-print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
+print_irq_inversion_bug(struct task_struct *curr,
+			struct lock_list *root, struct lock_list *other,
 			struct held_lock *this, int forwards,
 			const char *irqclass)
 {
@@ -1962,17 +2004,16 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
 		printk("but this lock took another, %s-unsafe lock in the past:\n", irqclass);
 	else
 		printk("but this lock was taken by another, %s-safe lock in the past:\n", irqclass);
-	print_lock_name(other);
+	print_lock_name(other->class);
 	printk("\n\nand interrupts could create inverse lock ordering between them.\n\n");
 
 	printk("\nother info that might help us debug this:\n");
 	lockdep_print_held_locks(curr);
 
-	printk("\nthe first lock's dependencies:\n");
-	print_lock_dependencies(hlock_class(this), 0);
-
-	printk("\nthe second lock's dependencies:\n");
-	print_lock_dependencies(other, 0);
+	printk("\nthe shortest dependencies between 2nd lock and 1st lock:\n");
+	if (!save_trace(&root->trace))
+		return 0;
+	print_shortest_lock_dependencies(other, root);
 
 	printk("\nstack backtrace:\n");
 	dump_stack();
@@ -1997,7 +2038,7 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
 	ret = find_usage_forwards(&root, bit, &target_entry);
 	BFS_PROCESS_RET(ret);
 
-	return print_irq_inversion_bug(curr, target_entry->class,
+	return print_irq_inversion_bug(curr, &root, target_entry,
 					this, 1, irqclass);
 }
 
@@ -2018,7 +2059,7 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
 	ret = find_usage_backwards(&root, bit, &target_entry);
 	BFS_PROCESS_RET(ret);
 
-	return print_irq_inversion_bug(curr, target_entry->class,
+	return print_irq_inversion_bug(curr, &root, target_entry,
 					this, 1, irqclass);
 }
 
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index c2f6594..b115aaa 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -219,9 +219,9 @@ static inline struct lock_list *get_lock_parent(struct lock_list *child)
 	return child->parent;
 }
 
-static inline unsigned long get_lock_depth(struct lock_list *child)
+static inline int get_lock_depth(struct lock_list *child)
 {
-	unsigned long depth = 0;
+	int depth = 0;
 	struct lock_list *parent;
 
 	while ((parent = get_lock_parent(child))) {
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 6/8] kernel:lockdep: implement lockdep_count_*ward_deps by BFS
  2009-05-31 14:49           ` [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
@ 2009-05-31 14:49             ` tom.leiming
  2009-05-31 14:49               ` [PATCH 7/8] kernel:lockdep: update memory usage introduced " tom.leiming
  0 siblings, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>


Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |   52 +++++++++++++++++++++++++---------------------------
 1 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index d839994..6e31e4b 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -1115,61 +1115,59 @@ static int noinline print_bfs_bug(int ret)
 	return 0;
 }
 
-unsigned long __lockdep_count_forward_deps(struct lock_class *class,
-					   unsigned int depth)
+static int noop_count(struct lock_list *entry, void *data)
 {
-	struct lock_list *entry;
-	unsigned long ret = 1;
+	(*(unsigned long *)data)++;
+	return 0;
+}
 
-	if (lockdep_dependency_visit(class, depth))
-		return 0;
+unsigned long __lockdep_count_forward_deps(struct lock_list *this)
+{
+	unsigned long  count = 0;
+	struct lock_list *uninitialized_var(target_entry);
 
-	/*
-	 * Recurse this class's dependency list:
-	 */
-	list_for_each_entry(entry, &class->locks_after, entry)
-		ret += __lockdep_count_forward_deps(entry->class, depth + 1);
+	__bfs_forwards(this, (void *)&count, noop_count, &target_entry);
 
-	return ret;
+	return count;
 }
-
 unsigned long lockdep_count_forward_deps(struct lock_class *class)
 {
 	unsigned long ret, flags;
+	struct lock_list this;
+
+	this.parent = NULL;
+	this.class = class;
 
 	local_irq_save(flags);
 	__raw_spin_lock(&lockdep_lock);
-	ret = __lockdep_count_forward_deps(class, 0);
+	ret = __lockdep_count_forward_deps(&this);
 	__raw_spin_unlock(&lockdep_lock);
 	local_irq_restore(flags);
 
 	return ret;
 }
 
-unsigned long __lockdep_count_backward_deps(struct lock_class *class,
-					    unsigned int depth)
+unsigned long __lockdep_count_backward_deps(struct lock_list *this)
 {
-	struct lock_list *entry;
-	unsigned long ret = 1;
+	unsigned long  count = 0;
+	struct lock_list *uninitialized_var(target_entry);
 
-	if (lockdep_dependency_visit(class, depth))
-		return 0;
-	/*
-	 * Recurse this class's dependency list:
-	 */
-	list_for_each_entry(entry, &class->locks_before, entry)
-		ret += __lockdep_count_backward_deps(entry->class, depth + 1);
+	__bfs_backwards(this, (void *)&count, noop_count, &target_entry);
 
-	return ret;
+	return count;
 }
 
 unsigned long lockdep_count_backward_deps(struct lock_class *class)
 {
 	unsigned long ret, flags;
+	struct lock_list this;
+
+	this.parent = NULL;
+	this.class = class;
 
 	local_irq_save(flags);
 	__raw_spin_lock(&lockdep_lock);
-	ret = __lockdep_count_backward_deps(class, 0);
+	ret = __lockdep_count_backward_deps(&this);
 	__raw_spin_unlock(&lockdep_lock);
 	local_irq_restore(flags);
 
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 7/8] kernel:lockdep: update memory usage introduced by BFS
  2009-05-31 14:49             ` [PATCH 6/8] kernel:lockdep: implement lockdep_count_*ward_deps by BFS tom.leiming
@ 2009-05-31 14:49               ` tom.leiming
  2009-05-31 14:49                 ` [PATCH 8/8] kernel:lockdep:add statistics info for max bfs queue depth tom.leiming
  0 siblings, 1 reply; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>


Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 6e31e4b..faa39cb 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -3429,7 +3429,8 @@ void __init lockdep_info(void)
 		sizeof(struct list_head) * CLASSHASH_SIZE +
 		sizeof(struct lock_list) * MAX_LOCKDEP_ENTRIES +
 		sizeof(struct lock_chain) * MAX_LOCKDEP_CHAINS +
-		sizeof(struct list_head) * CHAINHASH_SIZE) / 1024);
+		sizeof(struct list_head) * CHAINHASH_SIZE) / 1024 +
+		sizeof(struct circular_queue) + sizeof(bfs_accessed));
 
 	printk(" per task-struct memory footprint: %lu bytes\n",
 		sizeof(struct held_lock) * MAX_LOCK_DEPTH);
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 8/8] kernel:lockdep:add statistics info for max bfs queue depth
  2009-05-31 14:49               ` [PATCH 7/8] kernel:lockdep: update memory usage introduced " tom.leiming
@ 2009-05-31 14:49                 ` tom.leiming
  0 siblings, 0 replies; 716+ messages in thread
From: tom.leiming @ 2009-05-31 14:49 UTC (permalink / raw)
  To: mingo; +Cc: linux-kernel, akpm, a.p.zijlstra, Ming Lei

From: Ming Lei <tom.leiming@gmail.com>


Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c           |    6 +++++-
 kernel/lockdep_internals.h |    3 ++-
 kernel/lockdep_proc.c      |    2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index faa39cb..b20f08b 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -929,7 +929,7 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
 
 unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
 static struct circular_queue  lock_cq;
-
+unsigned int max_bfs_queue_depth;
 static int __bfs(struct lock_list *source_entry,
 			void *data,
 			int (*match)(struct lock_list *entry, void *data),
@@ -975,6 +975,7 @@ static int __bfs(struct lock_list *source_entry,
 
 		list_for_each_entry(entry, head, entry) {
 			if (!lock_accessed(entry)) {
+				unsigned int cq_depth;
 				mark_lock_accessed(entry, lock);
 				if (match(entry, data)) {
 					*target_entry = entry;
@@ -986,6 +987,9 @@ static int __bfs(struct lock_list *source_entry,
 					ret = -1;
 					goto exit;
 				}
+				cq_depth = __cq_get_elem_count(cq);
+				if (max_bfs_queue_depth < cq_depth)
+					max_bfs_queue_depth = cq_depth;
 			}
 		}
 	}
diff --git a/kernel/lockdep_internals.h b/kernel/lockdep_internals.h
index b115aaa..6baa880 100644
--- a/kernel/lockdep_internals.h
+++ b/kernel/lockdep_internals.h
@@ -138,6 +138,7 @@ extern atomic_t nr_find_usage_backwards_recursions;
 #endif
 
 
+extern unsigned int max_bfs_queue_depth;
 extern unsigned long nr_list_entries;
 extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
 extern unsigned long bfs_accessed[];
@@ -191,7 +192,7 @@ static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
 	return 0;
 }
 
-static inline int __cq_get_elem_count(struct circular_queue *cq)
+static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
 {
 	return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
 }
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index d7135aa..9a1bf34 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -411,6 +411,8 @@ static int lockdep_stats_show(struct seq_file *m, void *v)
 			max_lockdep_depth);
 	seq_printf(m, " max recursion depth:           %11u\n",
 			max_recursion_depth);
+	seq_printf(m, " max bfs queue depth:           %11u\n",
+			max_bfs_queue_depth);
 	lockdep_stats_debug_show(m);
 	seq_printf(m, " debug_locks:                   %11u\n",
 			debug_locks);
-- 
1.6.0.GIT


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS
  2009-05-31 14:49         ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards " tom.leiming
  2009-05-31 14:49           ` [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
@ 2009-05-31 15:14           ` Daniel Walker
  2009-06-01  0:14             ` Ming Lei
  1 sibling, 1 reply; 716+ messages in thread
From: Daniel Walker @ 2009-05-31 15:14 UTC (permalink / raw)
  To: tom.leiming; +Cc: mingo, linux-kernel, akpm, a.p.zijlstra

On Sun, 2009-05-31 at 22:49 +0800, tom.leiming@gmail.com wrote:
> -static inline int __bfs_forward(struct lock_list *src_entry,
> +static inline int __bfs_forwards(struct lock_list *src_entry,

Your patchset seems a bit young still .. For instance, adding an "s" in
the above line, that's just flux that really shouldn't be there.. I was
reviewing your patches but I stopped because it just looks like you need
to organize them better. I wonder for one, if they bisect or if they
pass checkpatch .. Your code also seems to have a lot of other little
cleanup type issues..

Daniel


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS
  2009-05-31 15:14           ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS Daniel Walker
@ 2009-06-01  0:14             ` Ming Lei
  0 siblings, 0 replies; 716+ messages in thread
From: Ming Lei @ 2009-06-01  0:14 UTC (permalink / raw)
  To: Daniel Walker; +Cc: mingo, linux-kernel, akpm, a.p.zijlstra

2009/5/31 Daniel Walker <dwalker@fifo99.com>:
> On Sun, 2009-05-31 at 22:49 +0800, tom.leiming@gmail.com wrote:
>> -static inline int __bfs_forward(struct lock_list *src_entry,
>> +static inline int __bfs_forwards(struct lock_list *src_entry,
>
> Your patchset seems a bit young still .. For instance, adding an "s" in
> the above line, that's just flux that really shouldn't be there.. I was
> reviewing your patches but I stopped because it just looks like you need
> to organize them better. I wonder for one, if they bisect or if they
> pass checkpatch .. Your code also seems to have a lot of other little

Only No 3. patch has a checkpatch error, so we can continue to review them
now,  can't we?

> cleanup type issues..
>
> Daniel
>
>



-- 
Lei Ming

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
  2009-05-31 14:49   ` [PATCH 1/8] kernel:lockdep:improve implementation of BFS tom.leiming
@ 2009-06-08 12:22   ` Peter Zijlstra
  2009-06-08 13:38     ` Ming Lei
                       ` (2 more replies)
  1 sibling, 3 replies; 716+ messages in thread
From: Peter Zijlstra @ 2009-06-08 12:22 UTC (permalink / raw)
  To: tom.leiming; +Cc: mingo, linux-kernel, akpm

On Sun, 2009-05-31 at 22:49 +0800, tom.leiming@gmail.com wrote:
> Hi,
> Currently lockdep uses recursion DFS(depth-first search) algorithm to
> search target in checking lock circle(check_noncircular()),irq-safe
> -> irq-unsafe(check_irq_usage()) and irq inversion when adding a new
> lock dependency. This patches replace the current DFS with BFS, based on
> the following consideration:
> 
>      1,no loss of efficiency, no matter DFS or BFS, the running time
>      are O(V+E) (V is vertex count, and E is edge count of one
>      graph);
> 
>      2,BFS may be easily implemented by circular queue and consumes
>      much less kernel stack space than DFS for DFS is implemented by
>      recursion.
> 
>      3, The shortest path can be obtained by BFS if the target is
>      found, but can't be got by DFS. By the shortest path, we can
>      shorten the lock dependency chain and help to troubleshoot lock
>      problem easier than before.
> 

OK, so I applied the patches and the cleanup below.

mostly little style nits and moving the circular queue into lockdep.c
(nobody else uses it, so why share it?).

One thing though, macros with return statements?! that's seriously bad
style, don't do that.

One thing that worries me a little is that we loose DaveM's
lockdep_dependency_visit() optimization. My brain seems unwilling to
co-operate on determining if BFS would make that redundant, so a little
word on that would be appreciated.

Then I booted it and all hell broke loose, so either I wrecked something
or you did :-), would you terribly mind poking at that a little?

Over all I like that patches, but they need a little more work. Could
you send delta patches from now on?

---

[    0.000999] =================================
[    0.000999] [ BUG: bad contention detected! ]
[    0.000999] ---------------------------------
[    0.000999] swapper/0 is trying to contend lock (old_style_seqlock_init) at:
[    0.000999] [<ffffffff8133a795>] _spin_lock+0x6d/0x75
[    0.000999] but there are no locks held!
[    0.000999]
[    0.000999] other info that might help us debug this:
[    0.000999] 1 lock held by swapper/0:
[    0.000999]  #0:  (xtime_lock){-.....}, at: [<ffffffff8106a360>] tick_periodic+0x1d/0x74
[    0.000999]
[    0.000999] stack backtrace:
[    0.000999] Pid: 0, comm: swapper Not tainted 2.6.30-rc8-tip #1049
[    0.000999] Call Trace:
[    0.000999]  <IRQ>  [<ffffffff81071bd8>] print_lock_contention_bug+0x100/0x110
[    0.000999]  [<ffffffff81071ce0>] lock_acquired+0xf8/0x2b4
[    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
[    0.000999]  [<ffffffff8133a795>] _spin_lock+0x6d/0x75
[    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
[    0.000999]  [<ffffffff81010221>] update_vsyscall+0x2d/0xd0
[    0.000999]  [<ffffffff81067469>] update_wall_time+0x4c1/0x4cc
[    0.000999]  [<ffffffff8105274b>] do_timer+0x15/0x1c
[    0.000999]  [<ffffffff8106a37e>] tick_periodic+0x3b/0x74
[    0.000999]  [<ffffffff8106a3db>] tick_handle_periodic+0x24/0x71
[    0.000999]  [<ffffffff8100ea23>] timer_interrupt+0x1f/0x26
[    0.000999]  [<ffffffff8109348b>] handle_IRQ_event+0x8e/0x19c
[    0.000999]  [<ffffffff8109501e>] handle_level_irq+0x9d/0xf3
[    0.000999]  [<ffffffff8100e24b>] handle_irq+0x24/0x2c
[    0.000999]  [<ffffffff8133f55b>] do_IRQ+0x63/0xc2
[    0.000999]  [<ffffffff8100c713>] ret_from_intr+0x0/0xf
[    0.000999]  <EOI>  [<ffffffff8133a538>] ? _spin_unlock_irqrestore+0x47/0x6d
[    0.000999]  [<ffffffff81093eea>] ? __setup_irq+0x1ea/0x277
[    0.000999]  [<ffffffff81094120>] ? setup_irq+0x25/0x2a
[    0.000999]  [<ffffffff8158e63e>] ? hpet_time_init+0x20/0x22
[    0.000999]  [<ffffffff8158bbcc>] ? start_kernel+0x2ee/0x37a
[    0.000999]  [<ffffffff8158b29a>] ? x86_64_start_reservations+0xaa/0xae
[    0.000999]  [<ffffffff8158b37f>] ? x86_64_start_kernel+0xe1/0xe8

And ended in a stuck boot at:

[   65.411804] rmmod         R  running task        0   616      1 0x00000008
[   65.411804]  ffff8800023c41a0 ffffea0003336ba8 ffff88007e3a3c08 ffffffff8106f71a
[   65.411804]  ffff88007e3a3c48 0000000000000202 ffff88007f821600 0000000000001823
[   65.411804]  ffff88007e109d20 ffff88007f8b5c80 0000000000000000 ffff88007e3a3d18
[   65.411804] Call Trace:
[   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
[   65.411804]  [<ffffffff8113f1b6>] ? release_sysfs_dirent+0x91/0xb1
[   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
[   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
[   65.411804]  [<ffffffff8113eff3>] ? sysfs_addrm_start+0x7d/0xaa
[   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
[   65.411804]  [<ffffffff810113ff>] ? alternatives_smp_module_del+0x37/0xd0
[   65.411804]  [<ffffffff810e61ee>] ? free_percpu+0x38/0xf8
[   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
[   65.411804]  [<ffffffff8133a542>] ? _spin_unlock_irqrestore+0x51/0x6d
[   65.411804]  [<ffffffff810e62a5>] ? free_percpu+0xef/0xf8
[   65.411804]  [<ffffffff8107ade5>] ? free_module+0x104/0x118
[   65.411804]  [<ffffffff8107b0a8>] ? sys_delete_module+0x20c/0x22e
[   65.411804]  [<ffffffff81339f88>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[   65.411804]  [<ffffffff8100bcdb>] ? system_call_fastpath+0x16/0x1b

( I can send you my .config if you cannot reproduce, but I don't think
its anything special )

---

Subject: lockdep: clean up after BFS patches
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Mon Jun 08 13:32:31 CEST 2009


LKML-Reference: <new-submission>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 include/linux/lockdep.h    |    7 -
 kernel/lockdep.c           |  232 +++++++++++++++++++++++++++------------------
 kernel/lockdep_internals.h |   97 ------------------
 3 files changed, 147 insertions(+), 189 deletions(-)
===================================================================
===================================================================
--- linux-2.6.orig/include/linux/lockdep.h
+++ linux-2.6/include/linux/lockdep.h
@@ -58,7 +58,6 @@ struct lock_class {
 
 	struct lockdep_subclass_key	*key;
 	unsigned int			subclass;
-	unsigned int			dep_gen_id;
 
 	/*
 	 * IRQ/softirq usage tracking bits:
@@ -150,9 +149,9 @@ struct lock_list {
 	struct stack_trace		trace;
 	int				distance;
 
-	/*The parent field is used to implement breadth-first search,and
-	 *the bit 0 is reused to indicate if the lock has been accessed
-	 *in BFS.
+	/*
+	 * The parent field is used to implement breadth-first search, and the
+	 * bit 0 is reused to indicate if the lock has been accessed in BFS.
 	 */
 	struct lock_list		*parent;
 };
===================================================================
--- linux-2.6.orig/kernel/lockdep.c
+++ linux-2.6/kernel/lockdep.c
@@ -43,6 +43,7 @@
 #include <linux/ftrace.h>
 #include <linux/stringify.h>
 #include <linux/bitops.h>
+
 #include <asm/sections.h>
 
 #include "lockdep_internals.h"
@@ -118,7 +119,7 @@ static inline int debug_locks_off_graph_
 static int lockdep_initialized;
 
 unsigned long nr_list_entries;
-struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
 
 /*
  * All data structures here are protected by the global debug_lock.
@@ -390,19 +391,6 @@ unsigned int nr_process_chains;
 unsigned int max_lockdep_depth;
 unsigned int max_recursion_depth;
 
-static unsigned int lockdep_dependency_gen_id;
-
-static bool lockdep_dependency_visit(struct lock_class *source,
-				     unsigned int depth)
-{
-	if (!depth)
-		lockdep_dependency_gen_id++;
-	if (source->dep_gen_id == lockdep_dependency_gen_id)
-		return true;
-	source->dep_gen_id = lockdep_dependency_gen_id;
-	return false;
-}
-
 #ifdef CONFIG_DEBUG_LOCKDEP
 /*
  * We cannot printk in early bootup code. Not even early_printk()
@@ -575,64 +563,6 @@ static void print_lock_class_header(stru
 	print_ip_sym((unsigned long)class->key);
 }
 
-/*
- * printk the shortest lock dependencies from @start to @end in reverse order:
- */
-static void __used
-print_shortest_lock_dependencies(struct lock_list *leaf,
-				struct lock_list *root)
-{
-	struct lock_list *entry = leaf;
-	int depth;
-
-	/*compute depth from generated tree by BFS*/
-	depth = get_lock_depth(leaf);
-
-	do {
-		print_lock_class_header(entry->class, depth);
-		printk("%*s ... acquired at:\n", depth, "");
-		print_stack_trace(&entry->trace, 2);
-		printk("\n");
-
-		if (depth == 0 && (entry != root)) {
-			printk("lockdep:%s bad BFS generated tree\n", __func__);
-			break;
-		}
-
-		entry = get_lock_parent(entry);
-		depth--;
-	} while (entry && (depth >= 0));
-
-	return;
-}
-/*
- * printk all lock dependencies starting at <entry>:
- */
-static void __used
-print_lock_dependencies(struct lock_class *class, int depth)
-{
-	struct lock_list *entry;
-
-	if (lockdep_dependency_visit(class, depth))
-		return;
-
-	if (DEBUG_LOCKS_WARN_ON(depth >= 20))
-		return;
-
-	print_lock_class_header(class, depth);
-
-	list_for_each_entry(entry, &class->locks_after, entry) {
-		if (DEBUG_LOCKS_WARN_ON(!entry->class))
-			return;
-
-		print_lock_dependencies(entry->class, depth + 1);
-
-		printk("%*s ... acquired at:\n",depth,"");
-		print_stack_trace(&entry->trace, 2);
-		printk("\n");
-	}
-}
-
 static void print_kernel_version(void)
 {
 	printk("%s %.*s\n", init_utsname()->release,
@@ -927,14 +857,106 @@ static int add_lock_to_list(struct lock_
 	return 1;
 }
 
-unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
-static struct circular_queue  lock_cq;
+/*For good efficiency of modular, we use power of 2*/
+#define MAX_CIRCULAR_QUEUE_SIZE		4096UL
+#define CQ_MASK				(MAX_CIRCULAR_QUEUE_SIZE-1)
+
+/* The circular_queue and helpers is used to implement the
+ * breadth-first search(BFS)algorithem, by which we can build
+ * the shortest path from the next lock to be acquired to the
+ * previous held lock if there is a circular between them.
+ * */
+struct circular_queue {
+	unsigned long element[MAX_CIRCULAR_QUEUE_SIZE];
+	unsigned int  front, rear;
+};
+
+static struct circular_queue lock_cq;
+static unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
+
 unsigned int max_bfs_queue_depth;
+
+static inline void __cq_init(struct circular_queue *cq)
+{
+	cq->front = cq->rear = 0;
+	bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
+}
+
+static inline int __cq_empty(struct circular_queue *cq)
+{
+	return (cq->front == cq->rear);
+}
+
+static inline int __cq_full(struct circular_queue *cq)
+{
+	return ((cq->rear + 1) & CQ_MASK) == cq->front;
+}
+
+static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
+{
+	if (__cq_full(cq))
+		return -1;
+
+	cq->element[cq->rear] = elem;
+	cq->rear = (cq->rear + 1) & CQ_MASK;
+	return 0;
+}
+
+static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
+{
+	if (__cq_empty(cq))
+		return -1;
+
+	*elem = cq->element[cq->front];
+	cq->front = (cq->front + 1) & CQ_MASK;
+	return 0;
+}
+
+static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
+{
+	return (cq->rear - cq->front) & CQ_MASK;
+}
+
+static inline void mark_lock_accessed(struct lock_list *lock,
+					struct lock_list *parent)
+{
+	unsigned long nr;
+	nr = lock - list_entries;
+	WARN_ON(nr >= nr_list_entries);
+	lock->parent = parent;
+	set_bit(nr, bfs_accessed);
+}
+
+static inline unsigned long lock_accessed(struct lock_list *lock)
+{
+	unsigned long nr;
+	nr = lock - list_entries;
+	WARN_ON(nr >= nr_list_entries);
+	return test_bit(nr, bfs_accessed);
+}
+
+static inline struct lock_list *get_lock_parent(struct lock_list *child)
+{
+	return child->parent;
+}
+
+static inline int get_lock_depth(struct lock_list *child)
+{
+	int depth = 0;
+	struct lock_list *parent;
+
+	while ((parent = get_lock_parent(child))) {
+		child = parent;
+		depth++;
+	}
+	return depth;
+}
+
 static int __bfs(struct lock_list *source_entry,
-			void *data,
-			int (*match)(struct lock_list *entry, void *data),
-			struct lock_list **target_entry,
-			int forward)
+		 void *data,
+		 int (*match)(struct lock_list *entry, void *data),
+		 struct lock_list **target_entry,
+		 int forward)
 {
 	struct lock_list *entry;
 	struct list_head *head;
@@ -1202,14 +1224,6 @@ check_noncircular(struct lock_list *root
  * without creating any illegal irq-safe -> irq-unsafe lock dependency.
  */
 
-
-#define   BFS_PROCESS_RET(ret)	do { \
-					if (ret < 0) \
-						return print_bfs_bug(ret); \
-					if (ret == 1) \
-						return 1; \
-				} while (0)
-
 static inline int usage_match(struct lock_list *entry, void *bit)
 {
 	return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
@@ -1236,6 +1250,8 @@ find_usage_forwards(struct lock_list *ro
 	debug_atomic_inc(&nr_find_usage_forwards_checks);
 
 	result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
+	if (result < 0)
+		return print_bfs_bug(result);
 
 	return result;
 }
@@ -1259,10 +1275,42 @@ find_usage_backwards(struct lock_list *r
 	debug_atomic_inc(&nr_find_usage_backwards_checks);
 
 	result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
+	if (result < 0)
+		return print_bfs_bug(result);
 
 	return result;
 }
 
+/*
+ * printk the shortest lock dependencies from @start to @end in reverse order:
+ */
+static void __used
+print_shortest_lock_dependencies(struct lock_list *leaf,
+				struct lock_list *root)
+{
+	struct lock_list *entry = leaf;
+	int depth;
+
+	/*compute depth from generated tree by BFS*/
+	depth = get_lock_depth(leaf);
+
+	do {
+		print_lock_class_header(entry->class, depth);
+		printk("%*s ... acquired at:\n", depth, "");
+		print_stack_trace(&entry->trace, 2);
+		printk("\n");
+
+		if (depth == 0 && (entry != root)) {
+			printk("lockdep:%s bad BFS generated tree\n", __func__);
+			break;
+		}
+
+		entry = get_lock_parent(entry);
+		depth--;
+	} while (entry && (depth >= 0));
+
+	return;
+}
 
 static int
 print_bad_irq_dependency(struct task_struct *curr,
@@ -1349,12 +1397,14 @@ check_usage(struct task_struct *curr, st
 
 	this.class = hlock_class(prev);
 	ret = find_usage_backwards(&this, bit_backwards, &target_entry);
-	BFS_PROCESS_RET(ret);
+	if (!ret || ret == 1)
+		return ret;
 
 	that.parent = NULL;
 	that.class = hlock_class(next);
 	ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
-	BFS_PROCESS_RET(ret);
+	if (!ret || ret == 1)
+		return ret;
 
 	return print_bad_irq_dependency(curr, &this, &that,
 			target_entry, target_entry1,
@@ -2038,7 +2088,8 @@ check_usage_forwards(struct task_struct 
 	root.parent = NULL;
 	root.class = hlock_class(this);
 	ret = find_usage_forwards(&root, bit, &target_entry);
-	BFS_PROCESS_RET(ret);
+	if (!ret || ret == 1)
+		return ret;
 
 	return print_irq_inversion_bug(curr, &root, target_entry,
 					this, 1, irqclass);
@@ -2059,7 +2110,8 @@ check_usage_backwards(struct task_struct
 	root.parent = NULL;
 	root.class = hlock_class(this);
 	ret = find_usage_backwards(&root, bit, &target_entry);
-	BFS_PROCESS_RET(ret);
+	if (!ret || ret == 1)
+		return ret;
 
 	return print_irq_inversion_bug(curr, &root, target_entry,
 					this, 1, irqclass);
===================================================================
--- linux-2.6.orig/kernel/lockdep_internals.h
+++ linux-2.6/kernel/lockdep_internals.h
@@ -91,6 +91,8 @@ extern unsigned int nr_process_chains;
 extern unsigned int max_lockdep_depth;
 extern unsigned int max_recursion_depth;
 
+extern unsigned int max_bfs_queue_depth;
+
 #ifdef CONFIG_PROVE_LOCKING
 extern unsigned long lockdep_count_forward_deps(struct lock_class *);
 extern unsigned long lockdep_count_backward_deps(struct lock_class *);
@@ -136,98 +138,3 @@ extern atomic_t nr_find_usage_backwards_
 # define debug_atomic_dec(ptr)		do { } while (0)
 # define debug_atomic_read(ptr)		0
 #endif
-
-
-extern unsigned int max_bfs_queue_depth;
-extern unsigned long nr_list_entries;
-extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
-extern unsigned long bfs_accessed[];
-
-/*For good efficiency of modular, we use power of 2*/
-#define  MAX_CIRCULAR_QUE_SIZE	    4096UL
-
-/* The circular_queue and helpers is used to implement the
- * breadth-first search(BFS)algorithem, by which we can build
- * the shortest path from the next lock to be acquired to the
- * previous held lock if there is a circular between them.
- * */
-struct circular_queue{
-	unsigned long element[MAX_CIRCULAR_QUE_SIZE];
-	unsigned int  front, rear;
-};
-
-static inline void __cq_init(struct circular_queue *cq)
-{
-	cq->front = cq->rear = 0;
-	bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
-}
-
-static inline int __cq_empty(struct circular_queue *cq)
-{
-	return (cq->front == cq->rear);
-}
-
-static inline int __cq_full(struct circular_queue *cq)
-{
-	return ((cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1))  == cq->front;
-}
-
-static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
-{
-	if (__cq_full(cq))
-		return -1;
-
-	cq->element[cq->rear] = elem;
-	cq->rear = (cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
-	return 0;
-}
-
-static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
-{
-	if (__cq_empty(cq))
-		return -1;
-
-	*elem = cq->element[cq->front];
-	cq->front = (cq->front + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
-	return 0;
-}
-
-static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
-{
-	return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
-}
-
-static inline void mark_lock_accessed(struct lock_list *lock,
-					struct lock_list *parent)
-{
-	unsigned long nr;
-	nr = lock - list_entries;
-	WARN_ON(nr >= nr_list_entries);
-	lock->parent = parent;
-	set_bit(nr, bfs_accessed);
-}
-
-static inline unsigned long lock_accessed(struct lock_list *lock)
-{
-	unsigned long nr;
-	nr = lock - list_entries;
-	WARN_ON(nr >= nr_list_entries);
-	return test_bit(nr, bfs_accessed);
-}
-
-static inline struct lock_list *get_lock_parent(struct lock_list *child)
-{
-	return child->parent;
-}
-
-static inline int get_lock_depth(struct lock_list *child)
-{
-	int depth = 0;
-	struct lock_list *parent;
-
-	while ((parent = get_lock_parent(child))) {
-		child = parent;
-		depth++;
-	}
-	return depth;
-}



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
@ 2009-06-08 13:38     ` Ming Lei
  2009-06-08 13:58     ` Ming Lei
  2009-06-08 15:50     ` Ming Lei
  2 siblings, 0 replies; 716+ messages in thread
From: Ming Lei @ 2009-06-08 13:38 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, akpm

2009/6/8 Peter Zijlstra <a.p.zijlstra@chello.nl>:
>
> OK, so I applied the patches and the cleanup below.

Thank you for your review and feedback.

>
> mostly little style nits and moving the circular queue into lockdep.c
> (nobody else uses it, so why share it?).

Yes, I agree.

>
> One thing though, macros with return statements?! that's seriously bad
> style, don't do that.

Yes, I'll fix it.

>
> One thing that worries me a little is that we loose DaveM's
> lockdep_dependency_visit() optimization. My brain seems unwilling to
> co-operate on determining if BFS would make that redundant, so a little
> word on that would be appreciated.
>
> Then I booted it and all hell broke loose, so either I wrecked something
> or you did :-), would you terribly mind poking at that a little?

Oh, let me work out what's wrong with this, maybe I need a little time.

>
> Over all I like that patches, but they need a little more work. Could
> you send delta patches from now on?

Yes, I'd like to do it.

>
> ---
>
> [    0.000999] =================================
> [    0.000999] [ BUG: bad contention detected! ]
> [    0.000999] ---------------------------------
> [    0.000999] swapper/0 is trying to contend lock (old_style_seqlock_init) at:
> [    0.000999] [<ffffffff8133a795>] _spin_lock+0x6d/0x75
> [    0.000999] but there are no locks held!
> [    0.000999]
> [    0.000999] other info that might help us debug this:
> [    0.000999] 1 lock held by swapper/0:
> [    0.000999]  #0:  (xtime_lock){-.....}, at: [<ffffffff8106a360>] tick_periodic+0x1d/0x74
> [    0.000999]
> [    0.000999] stack backtrace:
> [    0.000999] Pid: 0, comm: swapper Not tainted 2.6.30-rc8-tip #1049
> [    0.000999] Call Trace:
> [    0.000999]  <IRQ>  [<ffffffff81071bd8>] print_lock_contention_bug+0x100/0x110
> [    0.000999]  [<ffffffff81071ce0>] lock_acquired+0xf8/0x2b4
> [    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff8133a795>] _spin_lock+0x6d/0x75
> [    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff81010221>] update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff81067469>] update_wall_time+0x4c1/0x4cc
> [    0.000999]  [<ffffffff8105274b>] do_timer+0x15/0x1c
> [    0.000999]  [<ffffffff8106a37e>] tick_periodic+0x3b/0x74
> [    0.000999]  [<ffffffff8106a3db>] tick_handle_periodic+0x24/0x71
> [    0.000999]  [<ffffffff8100ea23>] timer_interrupt+0x1f/0x26
> [    0.000999]  [<ffffffff8109348b>] handle_IRQ_event+0x8e/0x19c
> [    0.000999]  [<ffffffff8109501e>] handle_level_irq+0x9d/0xf3
> [    0.000999]  [<ffffffff8100e24b>] handle_irq+0x24/0x2c
> [    0.000999]  [<ffffffff8133f55b>] do_IRQ+0x63/0xc2
> [    0.000999]  [<ffffffff8100c713>] ret_from_intr+0x0/0xf
> [    0.000999]  <EOI>  [<ffffffff8133a538>] ? _spin_unlock_irqrestore+0x47/0x6d
> [    0.000999]  [<ffffffff81093eea>] ? __setup_irq+0x1ea/0x277
> [    0.000999]  [<ffffffff81094120>] ? setup_irq+0x25/0x2a
> [    0.000999]  [<ffffffff8158e63e>] ? hpet_time_init+0x20/0x22
> [    0.000999]  [<ffffffff8158bbcc>] ? start_kernel+0x2ee/0x37a
> [    0.000999]  [<ffffffff8158b29a>] ? x86_64_start_reservations+0xaa/0xae
> [    0.000999]  [<ffffffff8158b37f>] ? x86_64_start_kernel+0xe1/0xe8
>
> And ended in a stuck boot at:
>
> [   65.411804] rmmod         R  running task        0   616      1 0x00000008
> [   65.411804]  ffff8800023c41a0 ffffea0003336ba8 ffff88007e3a3c08 ffffffff8106f71a
> [   65.411804]  ffff88007e3a3c48 0000000000000202 ffff88007f821600 0000000000001823
> [   65.411804]  ffff88007e109d20 ffff88007f8b5c80 0000000000000000 ffff88007e3a3d18
> [   65.411804] Call Trace:
> [   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
> [   65.411804]  [<ffffffff8113f1b6>] ? release_sysfs_dirent+0x91/0xb1
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff8113eff3>] ? sysfs_addrm_start+0x7d/0xaa
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff810113ff>] ? alternatives_smp_module_del+0x37/0xd0
> [   65.411804]  [<ffffffff810e61ee>] ? free_percpu+0x38/0xf8
> [   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
> [   65.411804]  [<ffffffff8133a542>] ? _spin_unlock_irqrestore+0x51/0x6d
> [   65.411804]  [<ffffffff810e62a5>] ? free_percpu+0xef/0xf8
> [   65.411804]  [<ffffffff8107ade5>] ? free_module+0x104/0x118
> [   65.411804]  [<ffffffff8107b0a8>] ? sys_delete_module+0x20c/0x22e
> [   65.411804]  [<ffffffff81339f88>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [   65.411804]  [<ffffffff8100bcdb>] ? system_call_fastpath+0x16/0x1b
>
> ( I can send you my .config if you cannot reproduce, but I don't think
> its anything special )
>
> ---
>
> Subject: lockdep: clean up after BFS patches
> From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Mon Jun 08 13:32:31 CEST 2009
>
>
> LKML-Reference: <new-submission>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  include/linux/lockdep.h    |    7 -
>  kernel/lockdep.c           |  232 +++++++++++++++++++++++++++------------------
>  kernel/lockdep_internals.h |   97 ------------------
>  3 files changed, 147 insertions(+), 189 deletions(-)
> ===================================================================
> ===================================================================
> --- linux-2.6.orig/include/linux/lockdep.h
> +++ linux-2.6/include/linux/lockdep.h
> @@ -58,7 +58,6 @@ struct lock_class {
>
>        struct lockdep_subclass_key     *key;
>        unsigned int                    subclass;
> -       unsigned int                    dep_gen_id;
>
>        /*
>         * IRQ/softirq usage tracking bits:
> @@ -150,9 +149,9 @@ struct lock_list {
>        struct stack_trace              trace;
>        int                             distance;
>
> -       /*The parent field is used to implement breadth-first search,and
> -        *the bit 0 is reused to indicate if the lock has been accessed
> -        *in BFS.
> +       /*
> +        * The parent field is used to implement breadth-first search, and the
> +        * bit 0 is reused to indicate if the lock has been accessed in BFS.
>         */
>        struct lock_list                *parent;
>  };
> ===================================================================
> --- linux-2.6.orig/kernel/lockdep.c
> +++ linux-2.6/kernel/lockdep.c
> @@ -43,6 +43,7 @@
>  #include <linux/ftrace.h>
>  #include <linux/stringify.h>
>  #include <linux/bitops.h>
> +
>  #include <asm/sections.h>
>
>  #include "lockdep_internals.h"
> @@ -118,7 +119,7 @@ static inline int debug_locks_off_graph_
>  static int lockdep_initialized;
>
>  unsigned long nr_list_entries;
> -struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
> +static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
>
>  /*
>  * All data structures here are protected by the global debug_lock.
> @@ -390,19 +391,6 @@ unsigned int nr_process_chains;
>  unsigned int max_lockdep_depth;
>  unsigned int max_recursion_depth;
>
> -static unsigned int lockdep_dependency_gen_id;
> -
> -static bool lockdep_dependency_visit(struct lock_class *source,
> -                                    unsigned int depth)
> -{
> -       if (!depth)
> -               lockdep_dependency_gen_id++;
> -       if (source->dep_gen_id == lockdep_dependency_gen_id)
> -               return true;
> -       source->dep_gen_id = lockdep_dependency_gen_id;
> -       return false;
> -}
> -
>  #ifdef CONFIG_DEBUG_LOCKDEP
>  /*
>  * We cannot printk in early bootup code. Not even early_printk()
> @@ -575,64 +563,6 @@ static void print_lock_class_header(stru
>        print_ip_sym((unsigned long)class->key);
>  }
>
> -/*
> - * printk the shortest lock dependencies from @start to @end in reverse order:
> - */
> -static void __used
> -print_shortest_lock_dependencies(struct lock_list *leaf,
> -                               struct lock_list *root)
> -{
> -       struct lock_list *entry = leaf;
> -       int depth;
> -
> -       /*compute depth from generated tree by BFS*/
> -       depth = get_lock_depth(leaf);
> -
> -       do {
> -               print_lock_class_header(entry->class, depth);
> -               printk("%*s ... acquired at:\n", depth, "");
> -               print_stack_trace(&entry->trace, 2);
> -               printk("\n");
> -
> -               if (depth == 0 && (entry != root)) {
> -                       printk("lockdep:%s bad BFS generated tree\n", __func__);
> -                       break;
> -               }
> -
> -               entry = get_lock_parent(entry);
> -               depth--;
> -       } while (entry && (depth >= 0));
> -
> -       return;
> -}
> -/*
> - * printk all lock dependencies starting at <entry>:
> - */
> -static void __used
> -print_lock_dependencies(struct lock_class *class, int depth)
> -{
> -       struct lock_list *entry;
> -
> -       if (lockdep_dependency_visit(class, depth))
> -               return;
> -
> -       if (DEBUG_LOCKS_WARN_ON(depth >= 20))
> -               return;
> -
> -       print_lock_class_header(class, depth);
> -
> -       list_for_each_entry(entry, &class->locks_after, entry) {
> -               if (DEBUG_LOCKS_WARN_ON(!entry->class))
> -                       return;
> -
> -               print_lock_dependencies(entry->class, depth + 1);
> -
> -               printk("%*s ... acquired at:\n",depth,"");
> -               print_stack_trace(&entry->trace, 2);
> -               printk("\n");
> -       }
> -}
> -
>  static void print_kernel_version(void)
>  {
>        printk("%s %.*s\n", init_utsname()->release,
> @@ -927,14 +857,106 @@ static int add_lock_to_list(struct lock_
>        return 1;
>  }
>
> -unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
> -static struct circular_queue  lock_cq;
> +/*For good efficiency of modular, we use power of 2*/
> +#define MAX_CIRCULAR_QUEUE_SIZE                4096UL
> +#define CQ_MASK                                (MAX_CIRCULAR_QUEUE_SIZE-1)
> +
> +/* The circular_queue and helpers is used to implement the
> + * breadth-first search(BFS)algorithem, by which we can build
> + * the shortest path from the next lock to be acquired to the
> + * previous held lock if there is a circular between them.
> + * */
> +struct circular_queue {
> +       unsigned long element[MAX_CIRCULAR_QUEUE_SIZE];
> +       unsigned int  front, rear;
> +};
> +
> +static struct circular_queue lock_cq;
> +static unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
> +
>  unsigned int max_bfs_queue_depth;
> +
> +static inline void __cq_init(struct circular_queue *cq)
> +{
> +       cq->front = cq->rear = 0;
> +       bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
> +}
> +
> +static inline int __cq_empty(struct circular_queue *cq)
> +{
> +       return (cq->front == cq->rear);
> +}
> +
> +static inline int __cq_full(struct circular_queue *cq)
> +{
> +       return ((cq->rear + 1) & CQ_MASK) == cq->front;
> +}
> +
> +static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
> +{
> +       if (__cq_full(cq))
> +               return -1;
> +
> +       cq->element[cq->rear] = elem;
> +       cq->rear = (cq->rear + 1) & CQ_MASK;
> +       return 0;
> +}
> +
> +static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
> +{
> +       if (__cq_empty(cq))
> +               return -1;
> +
> +       *elem = cq->element[cq->front];
> +       cq->front = (cq->front + 1) & CQ_MASK;
> +       return 0;
> +}
> +
> +static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
> +{
> +       return (cq->rear - cq->front) & CQ_MASK;
> +}
> +
> +static inline void mark_lock_accessed(struct lock_list *lock,
> +                                       struct lock_list *parent)
> +{
> +       unsigned long nr;
> +       nr = lock - list_entries;
> +       WARN_ON(nr >= nr_list_entries);
> +       lock->parent = parent;
> +       set_bit(nr, bfs_accessed);
> +}
> +
> +static inline unsigned long lock_accessed(struct lock_list *lock)
> +{
> +       unsigned long nr;
> +       nr = lock - list_entries;
> +       WARN_ON(nr >= nr_list_entries);
> +       return test_bit(nr, bfs_accessed);
> +}
> +
> +static inline struct lock_list *get_lock_parent(struct lock_list *child)
> +{
> +       return child->parent;
> +}
> +
> +static inline int get_lock_depth(struct lock_list *child)
> +{
> +       int depth = 0;
> +       struct lock_list *parent;
> +
> +       while ((parent = get_lock_parent(child))) {
> +               child = parent;
> +               depth++;
> +       }
> +       return depth;
> +}
> +
>  static int __bfs(struct lock_list *source_entry,
> -                       void *data,
> -                       int (*match)(struct lock_list *entry, void *data),
> -                       struct lock_list **target_entry,
> -                       int forward)
> +                void *data,
> +                int (*match)(struct lock_list *entry, void *data),
> +                struct lock_list **target_entry,
> +                int forward)
>  {
>        struct lock_list *entry;
>        struct list_head *head;
> @@ -1202,14 +1224,6 @@ check_noncircular(struct lock_list *root
>  * without creating any illegal irq-safe -> irq-unsafe lock dependency.
>  */
>
> -
> -#define   BFS_PROCESS_RET(ret) do { \
> -                                       if (ret < 0) \
> -                                               return print_bfs_bug(ret); \
> -                                       if (ret == 1) \
> -                                               return 1; \
> -                               } while (0)
> -
>  static inline int usage_match(struct lock_list *entry, void *bit)
>  {
>        return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
> @@ -1236,6 +1250,8 @@ find_usage_forwards(struct lock_list *ro
>        debug_atomic_inc(&nr_find_usage_forwards_checks);
>
>        result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
> +       if (result < 0)
> +               return print_bfs_bug(result);
>
>        return result;
>  }
> @@ -1259,10 +1275,42 @@ find_usage_backwards(struct lock_list *r
>        debug_atomic_inc(&nr_find_usage_backwards_checks);
>
>        result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
> +       if (result < 0)
> +               return print_bfs_bug(result);
>
>        return result;
>  }
>
> +/*
> + * printk the shortest lock dependencies from @start to @end in reverse order:
> + */
> +static void __used
> +print_shortest_lock_dependencies(struct lock_list *leaf,
> +                               struct lock_list *root)
> +{
> +       struct lock_list *entry = leaf;
> +       int depth;
> +
> +       /*compute depth from generated tree by BFS*/
> +       depth = get_lock_depth(leaf);
> +
> +       do {
> +               print_lock_class_header(entry->class, depth);
> +               printk("%*s ... acquired at:\n", depth, "");
> +               print_stack_trace(&entry->trace, 2);
> +               printk("\n");
> +
> +               if (depth == 0 && (entry != root)) {
> +                       printk("lockdep:%s bad BFS generated tree\n", __func__);
> +                       break;
> +               }
> +
> +               entry = get_lock_parent(entry);
> +               depth--;
> +       } while (entry && (depth >= 0));
> +
> +       return;
> +}
>
>  static int
>  print_bad_irq_dependency(struct task_struct *curr,
> @@ -1349,12 +1397,14 @@ check_usage(struct task_struct *curr, st
>
>        this.class = hlock_class(prev);
>        ret = find_usage_backwards(&this, bit_backwards, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        that.parent = NULL;
>        that.class = hlock_class(next);
>        ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_bad_irq_dependency(curr, &this, &that,
>                        target_entry, target_entry1,
> @@ -2038,7 +2088,8 @@ check_usage_forwards(struct task_struct
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_forwards(&root, bit, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
>                                        this, 1, irqclass);
> @@ -2059,7 +2110,8 @@ check_usage_backwards(struct task_struct
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_backwards(&root, bit, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
>                                        this, 1, irqclass);
> ===================================================================
> --- linux-2.6.orig/kernel/lockdep_internals.h
> +++ linux-2.6/kernel/lockdep_internals.h
> @@ -91,6 +91,8 @@ extern unsigned int nr_process_chains;
>  extern unsigned int max_lockdep_depth;
>  extern unsigned int max_recursion_depth;
>
> +extern unsigned int max_bfs_queue_depth;
> +
>  #ifdef CONFIG_PROVE_LOCKING
>  extern unsigned long lockdep_count_forward_deps(struct lock_class *);
>  extern unsigned long lockdep_count_backward_deps(struct lock_class *);
> @@ -136,98 +138,3 @@ extern atomic_t nr_find_usage_backwards_
>  # define debug_atomic_dec(ptr)         do { } while (0)
>  # define debug_atomic_read(ptr)                0
>  #endif
> -
> -
> -extern unsigned int max_bfs_queue_depth;
> -extern unsigned long nr_list_entries;
> -extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
> -extern unsigned long bfs_accessed[];
> -
> -/*For good efficiency of modular, we use power of 2*/
> -#define  MAX_CIRCULAR_QUE_SIZE     4096UL
> -
> -/* The circular_queue and helpers is used to implement the
> - * breadth-first search(BFS)algorithem, by which we can build
> - * the shortest path from the next lock to be acquired to the
> - * previous held lock if there is a circular between them.
> - * */
> -struct circular_queue{
> -       unsigned long element[MAX_CIRCULAR_QUE_SIZE];
> -       unsigned int  front, rear;
> -};
> -
> -static inline void __cq_init(struct circular_queue *cq)
> -{
> -       cq->front = cq->rear = 0;
> -       bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
> -}
> -
> -static inline int __cq_empty(struct circular_queue *cq)
> -{
> -       return (cq->front == cq->rear);
> -}
> -
> -static inline int __cq_full(struct circular_queue *cq)
> -{
> -       return ((cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1))  == cq->front;
> -}
> -
> -static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
> -{
> -       if (__cq_full(cq))
> -               return -1;
> -
> -       cq->element[cq->rear] = elem;
> -       cq->rear = (cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
> -       return 0;
> -}
> -
> -static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
> -{
> -       if (__cq_empty(cq))
> -               return -1;
> -
> -       *elem = cq->element[cq->front];
> -       cq->front = (cq->front + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
> -       return 0;
> -}
> -
> -static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
> -{
> -       return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
> -}
> -
> -static inline void mark_lock_accessed(struct lock_list *lock,
> -                                       struct lock_list *parent)
> -{
> -       unsigned long nr;
> -       nr = lock - list_entries;
> -       WARN_ON(nr >= nr_list_entries);
> -       lock->parent = parent;
> -       set_bit(nr, bfs_accessed);
> -}
> -
> -static inline unsigned long lock_accessed(struct lock_list *lock)
> -{
> -       unsigned long nr;
> -       nr = lock - list_entries;
> -       WARN_ON(nr >= nr_list_entries);
> -       return test_bit(nr, bfs_accessed);
> -}
> -
> -static inline struct lock_list *get_lock_parent(struct lock_list *child)
> -{
> -       return child->parent;
> -}
> -
> -static inline int get_lock_depth(struct lock_list *child)
> -{
> -       int depth = 0;
> -       struct lock_list *parent;
> -
> -       while ((parent = get_lock_parent(child))) {
> -               child = parent;
> -               depth++;
> -       }
> -       return depth;
> -}
>
>
>



-- 
Lei Ming

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
  2009-06-08 13:38     ` Ming Lei
@ 2009-06-08 13:58     ` Ming Lei
  2009-06-08 14:04       ` Peter Zijlstra
  2009-06-08 15:50     ` Ming Lei
  2 siblings, 1 reply; 716+ messages in thread
From: Ming Lei @ 2009-06-08 13:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, akpm

2009/6/8 Peter Zijlstra <a.p.zijlstra@chello.nl>:

>
> Then I booted it and all hell broke loose, so either I wrecked something
> or you did :-), would you terribly mind poking at that a little?

I does not reproduce the break on 2.6.30-rc8 + 2009-06-04-next + BFS patches.

I guess you touch it on the latest tip + BFS patches, right?  If so,
I'll try to reproduce it on the current tip tree. If not, would you
mind provide the git
version to me?

Thanks.

>
> Over all I like that patches, but they need a little more work. Could
> you send delta patches from now on?
>
> ---
>
> [    0.000999] =================================
> [    0.000999] [ BUG: bad contention detected! ]
> [    0.000999] ---------------------------------
> [    0.000999] swapper/0 is trying to contend lock (old_style_seqlock_init) at:
> [    0.000999] [<ffffffff8133a795>] _spin_lock+0x6d/0x75
> [    0.000999] but there are no locks held!
> [    0.000999]
> [    0.000999] other info that might help us debug this:
> [    0.000999] 1 lock held by swapper/0:
> [    0.000999]  #0:  (xtime_lock){-.....}, at: [<ffffffff8106a360>] tick_periodic+0x1d/0x74
> [    0.000999]
> [    0.000999] stack backtrace:
> [    0.000999] Pid: 0, comm: swapper Not tainted 2.6.30-rc8-tip #1049
> [    0.000999] Call Trace:
> [    0.000999]  <IRQ>  [<ffffffff81071bd8>] print_lock_contention_bug+0x100/0x110
> [    0.000999]  [<ffffffff81071ce0>] lock_acquired+0xf8/0x2b4
> [    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff8133a795>] _spin_lock+0x6d/0x75
> [    0.000999]  [<ffffffff81010221>] ? update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff81010221>] update_vsyscall+0x2d/0xd0
> [    0.000999]  [<ffffffff81067469>] update_wall_time+0x4c1/0x4cc
> [    0.000999]  [<ffffffff8105274b>] do_timer+0x15/0x1c
> [    0.000999]  [<ffffffff8106a37e>] tick_periodic+0x3b/0x74
> [    0.000999]  [<ffffffff8106a3db>] tick_handle_periodic+0x24/0x71
> [    0.000999]  [<ffffffff8100ea23>] timer_interrupt+0x1f/0x26
> [    0.000999]  [<ffffffff8109348b>] handle_IRQ_event+0x8e/0x19c
> [    0.000999]  [<ffffffff8109501e>] handle_level_irq+0x9d/0xf3
> [    0.000999]  [<ffffffff8100e24b>] handle_irq+0x24/0x2c
> [    0.000999]  [<ffffffff8133f55b>] do_IRQ+0x63/0xc2
> [    0.000999]  [<ffffffff8100c713>] ret_from_intr+0x0/0xf
> [    0.000999]  <EOI>  [<ffffffff8133a538>] ? _spin_unlock_irqrestore+0x47/0x6d
> [    0.000999]  [<ffffffff81093eea>] ? __setup_irq+0x1ea/0x277
> [    0.000999]  [<ffffffff81094120>] ? setup_irq+0x25/0x2a
> [    0.000999]  [<ffffffff8158e63e>] ? hpet_time_init+0x20/0x22
> [    0.000999]  [<ffffffff8158bbcc>] ? start_kernel+0x2ee/0x37a
> [    0.000999]  [<ffffffff8158b29a>] ? x86_64_start_reservations+0xaa/0xae
> [    0.000999]  [<ffffffff8158b37f>] ? x86_64_start_kernel+0xe1/0xe8
>
> And ended in a stuck boot at:
>
> [   65.411804] rmmod         R  running task        0   616      1 0x00000008
> [   65.411804]  ffff8800023c41a0 ffffea0003336ba8 ffff88007e3a3c08 ffffffff8106f71a
> [   65.411804]  ffff88007e3a3c48 0000000000000202 ffff88007f821600 0000000000001823
> [   65.411804]  ffff88007e109d20 ffff88007f8b5c80 0000000000000000 ffff88007e3a3d18
> [   65.411804] Call Trace:
> [   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
> [   65.411804]  [<ffffffff8113f1b6>] ? release_sysfs_dirent+0x91/0xb1
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff8113eff3>] ? sysfs_addrm_start+0x7d/0xaa
> [   65.411804]  [<ffffffff81071af6>] ? print_lock_contention_bug+0x1e/0x110
> [   65.411804]  [<ffffffff810113ff>] ? alternatives_smp_module_del+0x37/0xd0
> [   65.411804]  [<ffffffff810e61ee>] ? free_percpu+0x38/0xf8
> [   65.411804]  [<ffffffff8106f71a>] ? trace_hardirqs_on+0xd/0xf
> [   65.411804]  [<ffffffff8133a542>] ? _spin_unlock_irqrestore+0x51/0x6d
> [   65.411804]  [<ffffffff810e62a5>] ? free_percpu+0xef/0xf8
> [   65.411804]  [<ffffffff8107ade5>] ? free_module+0x104/0x118
> [   65.411804]  [<ffffffff8107b0a8>] ? sys_delete_module+0x20c/0x22e
> [   65.411804]  [<ffffffff81339f88>] ? trace_hardirqs_on_thunk+0x3a/0x3f
> [   65.411804]  [<ffffffff8100bcdb>] ? system_call_fastpath+0x16/0x1b
>
> ( I can send you my .config if you cannot reproduce, but I don't think
> its anything special )
>
> ---
>
> Subject: lockdep: clean up after BFS patches
> From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Mon Jun 08 13:32:31 CEST 2009
>
>
> LKML-Reference: <new-submission>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  include/linux/lockdep.h    |    7 -
>  kernel/lockdep.c           |  232 +++++++++++++++++++++++++++------------------
>  kernel/lockdep_internals.h |   97 ------------------
>  3 files changed, 147 insertions(+), 189 deletions(-)
> ===================================================================
> ===================================================================
> --- linux-2.6.orig/include/linux/lockdep.h
> +++ linux-2.6/include/linux/lockdep.h
> @@ -58,7 +58,6 @@ struct lock_class {
>
>        struct lockdep_subclass_key     *key;
>        unsigned int                    subclass;
> -       unsigned int                    dep_gen_id;
>
>        /*
>         * IRQ/softirq usage tracking bits:
> @@ -150,9 +149,9 @@ struct lock_list {
>        struct stack_trace              trace;
>        int                             distance;
>
> -       /*The parent field is used to implement breadth-first search,and
> -        *the bit 0 is reused to indicate if the lock has been accessed
> -        *in BFS.
> +       /*
> +        * The parent field is used to implement breadth-first search, and the
> +        * bit 0 is reused to indicate if the lock has been accessed in BFS.
>         */
>        struct lock_list                *parent;
>  };
> ===================================================================
> --- linux-2.6.orig/kernel/lockdep.c
> +++ linux-2.6/kernel/lockdep.c
> @@ -43,6 +43,7 @@
>  #include <linux/ftrace.h>
>  #include <linux/stringify.h>
>  #include <linux/bitops.h>
> +
>  #include <asm/sections.h>
>
>  #include "lockdep_internals.h"
> @@ -118,7 +119,7 @@ static inline int debug_locks_off_graph_
>  static int lockdep_initialized;
>
>  unsigned long nr_list_entries;
> -struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
> +static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
>
>  /*
>  * All data structures here are protected by the global debug_lock.
> @@ -390,19 +391,6 @@ unsigned int nr_process_chains;
>  unsigned int max_lockdep_depth;
>  unsigned int max_recursion_depth;
>
> -static unsigned int lockdep_dependency_gen_id;
> -
> -static bool lockdep_dependency_visit(struct lock_class *source,
> -                                    unsigned int depth)
> -{
> -       if (!depth)
> -               lockdep_dependency_gen_id++;
> -       if (source->dep_gen_id == lockdep_dependency_gen_id)
> -               return true;
> -       source->dep_gen_id = lockdep_dependency_gen_id;
> -       return false;
> -}
> -
>  #ifdef CONFIG_DEBUG_LOCKDEP
>  /*
>  * We cannot printk in early bootup code. Not even early_printk()
> @@ -575,64 +563,6 @@ static void print_lock_class_header(stru
>        print_ip_sym((unsigned long)class->key);
>  }
>
> -/*
> - * printk the shortest lock dependencies from @start to @end in reverse order:
> - */
> -static void __used
> -print_shortest_lock_dependencies(struct lock_list *leaf,
> -                               struct lock_list *root)
> -{
> -       struct lock_list *entry = leaf;
> -       int depth;
> -
> -       /*compute depth from generated tree by BFS*/
> -       depth = get_lock_depth(leaf);
> -
> -       do {
> -               print_lock_class_header(entry->class, depth);
> -               printk("%*s ... acquired at:\n", depth, "");
> -               print_stack_trace(&entry->trace, 2);
> -               printk("\n");
> -
> -               if (depth == 0 && (entry != root)) {
> -                       printk("lockdep:%s bad BFS generated tree\n", __func__);
> -                       break;
> -               }
> -
> -               entry = get_lock_parent(entry);
> -               depth--;
> -       } while (entry && (depth >= 0));
> -
> -       return;
> -}
> -/*
> - * printk all lock dependencies starting at <entry>:
> - */
> -static void __used
> -print_lock_dependencies(struct lock_class *class, int depth)
> -{
> -       struct lock_list *entry;
> -
> -       if (lockdep_dependency_visit(class, depth))
> -               return;
> -
> -       if (DEBUG_LOCKS_WARN_ON(depth >= 20))
> -               return;
> -
> -       print_lock_class_header(class, depth);
> -
> -       list_for_each_entry(entry, &class->locks_after, entry) {
> -               if (DEBUG_LOCKS_WARN_ON(!entry->class))
> -                       return;
> -
> -               print_lock_dependencies(entry->class, depth + 1);
> -
> -               printk("%*s ... acquired at:\n",depth,"");
> -               print_stack_trace(&entry->trace, 2);
> -               printk("\n");
> -       }
> -}
> -
>  static void print_kernel_version(void)
>  {
>        printk("%s %.*s\n", init_utsname()->release,
> @@ -927,14 +857,106 @@ static int add_lock_to_list(struct lock_
>        return 1;
>  }
>
> -unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
> -static struct circular_queue  lock_cq;
> +/*For good efficiency of modular, we use power of 2*/
> +#define MAX_CIRCULAR_QUEUE_SIZE                4096UL
> +#define CQ_MASK                                (MAX_CIRCULAR_QUEUE_SIZE-1)
> +
> +/* The circular_queue and helpers is used to implement the
> + * breadth-first search(BFS)algorithem, by which we can build
> + * the shortest path from the next lock to be acquired to the
> + * previous held lock if there is a circular between them.
> + * */
> +struct circular_queue {
> +       unsigned long element[MAX_CIRCULAR_QUEUE_SIZE];
> +       unsigned int  front, rear;
> +};
> +
> +static struct circular_queue lock_cq;
> +static unsigned long bfs_accessed[BITS_TO_LONGS(MAX_LOCKDEP_ENTRIES)];
> +
>  unsigned int max_bfs_queue_depth;
> +
> +static inline void __cq_init(struct circular_queue *cq)
> +{
> +       cq->front = cq->rear = 0;
> +       bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
> +}
> +
> +static inline int __cq_empty(struct circular_queue *cq)
> +{
> +       return (cq->front == cq->rear);
> +}
> +
> +static inline int __cq_full(struct circular_queue *cq)
> +{
> +       return ((cq->rear + 1) & CQ_MASK) == cq->front;
> +}
> +
> +static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
> +{
> +       if (__cq_full(cq))
> +               return -1;
> +
> +       cq->element[cq->rear] = elem;
> +       cq->rear = (cq->rear + 1) & CQ_MASK;
> +       return 0;
> +}
> +
> +static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
> +{
> +       if (__cq_empty(cq))
> +               return -1;
> +
> +       *elem = cq->element[cq->front];
> +       cq->front = (cq->front + 1) & CQ_MASK;
> +       return 0;
> +}
> +
> +static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
> +{
> +       return (cq->rear - cq->front) & CQ_MASK;
> +}
> +
> +static inline void mark_lock_accessed(struct lock_list *lock,
> +                                       struct lock_list *parent)
> +{
> +       unsigned long nr;
> +       nr = lock - list_entries;
> +       WARN_ON(nr >= nr_list_entries);
> +       lock->parent = parent;
> +       set_bit(nr, bfs_accessed);
> +}
> +
> +static inline unsigned long lock_accessed(struct lock_list *lock)
> +{
> +       unsigned long nr;
> +       nr = lock - list_entries;
> +       WARN_ON(nr >= nr_list_entries);
> +       return test_bit(nr, bfs_accessed);
> +}
> +
> +static inline struct lock_list *get_lock_parent(struct lock_list *child)
> +{
> +       return child->parent;
> +}
> +
> +static inline int get_lock_depth(struct lock_list *child)
> +{
> +       int depth = 0;
> +       struct lock_list *parent;
> +
> +       while ((parent = get_lock_parent(child))) {
> +               child = parent;
> +               depth++;
> +       }
> +       return depth;
> +}
> +
>  static int __bfs(struct lock_list *source_entry,
> -                       void *data,
> -                       int (*match)(struct lock_list *entry, void *data),
> -                       struct lock_list **target_entry,
> -                       int forward)
> +                void *data,
> +                int (*match)(struct lock_list *entry, void *data),
> +                struct lock_list **target_entry,
> +                int forward)
>  {
>        struct lock_list *entry;
>        struct list_head *head;
> @@ -1202,14 +1224,6 @@ check_noncircular(struct lock_list *root
>  * without creating any illegal irq-safe -> irq-unsafe lock dependency.
>  */
>
> -
> -#define   BFS_PROCESS_RET(ret) do { \
> -                                       if (ret < 0) \
> -                                               return print_bfs_bug(ret); \
> -                                       if (ret == 1) \
> -                                               return 1; \
> -                               } while (0)
> -
>  static inline int usage_match(struct lock_list *entry, void *bit)
>  {
>        return entry->class->usage_mask & (1 << (enum lock_usage_bit)bit);
> @@ -1236,6 +1250,8 @@ find_usage_forwards(struct lock_list *ro
>        debug_atomic_inc(&nr_find_usage_forwards_checks);
>
>        result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
> +       if (result < 0)
> +               return print_bfs_bug(result);
>
>        return result;
>  }
> @@ -1259,10 +1275,42 @@ find_usage_backwards(struct lock_list *r
>        debug_atomic_inc(&nr_find_usage_backwards_checks);
>
>        result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
> +       if (result < 0)
> +               return print_bfs_bug(result);
>
>        return result;
>  }
>
> +/*
> + * printk the shortest lock dependencies from @start to @end in reverse order:
> + */
> +static void __used
> +print_shortest_lock_dependencies(struct lock_list *leaf,
> +                               struct lock_list *root)
> +{
> +       struct lock_list *entry = leaf;
> +       int depth;
> +
> +       /*compute depth from generated tree by BFS*/
> +       depth = get_lock_depth(leaf);
> +
> +       do {
> +               print_lock_class_header(entry->class, depth);
> +               printk("%*s ... acquired at:\n", depth, "");
> +               print_stack_trace(&entry->trace, 2);
> +               printk("\n");
> +
> +               if (depth == 0 && (entry != root)) {
> +                       printk("lockdep:%s bad BFS generated tree\n", __func__);
> +                       break;
> +               }
> +
> +               entry = get_lock_parent(entry);
> +               depth--;
> +       } while (entry && (depth >= 0));
> +
> +       return;
> +}
>
>  static int
>  print_bad_irq_dependency(struct task_struct *curr,
> @@ -1349,12 +1397,14 @@ check_usage(struct task_struct *curr, st
>
>        this.class = hlock_class(prev);
>        ret = find_usage_backwards(&this, bit_backwards, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        that.parent = NULL;
>        that.class = hlock_class(next);
>        ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_bad_irq_dependency(curr, &this, &that,
>                        target_entry, target_entry1,
> @@ -2038,7 +2088,8 @@ check_usage_forwards(struct task_struct
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_forwards(&root, bit, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
>                                        this, 1, irqclass);
> @@ -2059,7 +2110,8 @@ check_usage_backwards(struct task_struct
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_backwards(&root, bit, &target_entry);
> -       BFS_PROCESS_RET(ret);
> +       if (!ret || ret == 1)
> +               return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
>                                        this, 1, irqclass);
> ===================================================================
> --- linux-2.6.orig/kernel/lockdep_internals.h
> +++ linux-2.6/kernel/lockdep_internals.h
> @@ -91,6 +91,8 @@ extern unsigned int nr_process_chains;
>  extern unsigned int max_lockdep_depth;
>  extern unsigned int max_recursion_depth;
>
> +extern unsigned int max_bfs_queue_depth;
> +
>  #ifdef CONFIG_PROVE_LOCKING
>  extern unsigned long lockdep_count_forward_deps(struct lock_class *);
>  extern unsigned long lockdep_count_backward_deps(struct lock_class *);
> @@ -136,98 +138,3 @@ extern atomic_t nr_find_usage_backwards_
>  # define debug_atomic_dec(ptr)         do { } while (0)
>  # define debug_atomic_read(ptr)                0
>  #endif
> -
> -
> -extern unsigned int max_bfs_queue_depth;
> -extern unsigned long nr_list_entries;
> -extern struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
> -extern unsigned long bfs_accessed[];
> -
> -/*For good efficiency of modular, we use power of 2*/
> -#define  MAX_CIRCULAR_QUE_SIZE     4096UL
> -
> -/* The circular_queue and helpers is used to implement the
> - * breadth-first search(BFS)algorithem, by which we can build
> - * the shortest path from the next lock to be acquired to the
> - * previous held lock if there is a circular between them.
> - * */
> -struct circular_queue{
> -       unsigned long element[MAX_CIRCULAR_QUE_SIZE];
> -       unsigned int  front, rear;
> -};
> -
> -static inline void __cq_init(struct circular_queue *cq)
> -{
> -       cq->front = cq->rear = 0;
> -       bitmap_zero(bfs_accessed, MAX_LOCKDEP_ENTRIES);
> -}
> -
> -static inline int __cq_empty(struct circular_queue *cq)
> -{
> -       return (cq->front == cq->rear);
> -}
> -
> -static inline int __cq_full(struct circular_queue *cq)
> -{
> -       return ((cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1))  == cq->front;
> -}
> -
> -static inline int __cq_enqueue(struct circular_queue *cq, unsigned long elem)
> -{
> -       if (__cq_full(cq))
> -               return -1;
> -
> -       cq->element[cq->rear] = elem;
> -       cq->rear = (cq->rear + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
> -       return 0;
> -}
> -
> -static inline int __cq_dequeue(struct circular_queue *cq, unsigned long *elem)
> -{
> -       if (__cq_empty(cq))
> -               return -1;
> -
> -       *elem = cq->element[cq->front];
> -       cq->front = (cq->front + 1)&(MAX_CIRCULAR_QUE_SIZE-1);
> -       return 0;
> -}
> -
> -static inline unsigned int  __cq_get_elem_count(struct circular_queue *cq)
> -{
> -       return (cq->rear - cq->front)&(MAX_CIRCULAR_QUE_SIZE-1);
> -}
> -
> -static inline void mark_lock_accessed(struct lock_list *lock,
> -                                       struct lock_list *parent)
> -{
> -       unsigned long nr;
> -       nr = lock - list_entries;
> -       WARN_ON(nr >= nr_list_entries);
> -       lock->parent = parent;
> -       set_bit(nr, bfs_accessed);
> -}
> -
> -static inline unsigned long lock_accessed(struct lock_list *lock)
> -{
> -       unsigned long nr;
> -       nr = lock - list_entries;
> -       WARN_ON(nr >= nr_list_entries);
> -       return test_bit(nr, bfs_accessed);
> -}
> -
> -static inline struct lock_list *get_lock_parent(struct lock_list *child)
> -{
> -       return child->parent;
> -}
> -
> -static inline int get_lock_depth(struct lock_list *child)
> -{
> -       int depth = 0;
> -       struct lock_list *parent;
> -
> -       while ((parent = get_lock_parent(child))) {
> -               child = parent;
> -               depth++;
> -       }
> -       return depth;
> -}
>
>
>



-- 
Lei Ming

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-06-08 13:58     ` Ming Lei
@ 2009-06-08 14:04       ` Peter Zijlstra
  0 siblings, 0 replies; 716+ messages in thread
From: Peter Zijlstra @ 2009-06-08 14:04 UTC (permalink / raw)
  To: Ming Lei; +Cc: mingo, linux-kernel, akpm

On Mon, 2009-06-08 at 21:58 +0800, Ming Lei wrote:
> >
> > Then I booted it and all hell broke loose, so either I wrecked something
> > or you did :-), would you terribly mind poking at that a little?
> 
> I does not reproduce the break on 2.6.30-rc8 + 2009-06-04-next + BFS patches.
> 
> I guess you touch it on the latest tip + BFS patches, right?  If so,
> I'll try to reproduce it on the current tip tree. If not, would you
> mind provide the git
> version to me?

v2.6.30-rc8-2058-g1615bb0

---
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.30-rc8
# Mon Jun  8 13:40:26 2009
#
CONFIG_64BIT=y
# CONFIG_X86_32 is not set
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_FAST_CMPXCHG_LOCAL=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ZONE_DMA32=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_X86_64_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_TRAMPOLINE=y
# CONFIG_KTIME_SCALAR is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
# CONFIG_TASK_XACCT is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y

#
# RCU Subsystem
#
CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=20
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
# CONFIG_CGROUP_NS is not set
# CONFIG_CGROUP_FREEZER is not set
# CONFIG_CGROUP_DEVICE is not set
# CONFIG_CPUSETS is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_HAVE_PERF_COUNTERS=y

#
# Performance Counters
#
CONFIG_PERF_COUNTERS=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
CONFIG_MARKERS=y
CONFIG_OPROFILE=m
# CONFIG_OPROFILE_IBS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
CONFIG_BLOCK_COMPAT=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_FREEZER=y

#
# Processor type and features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_SMP=y
# CONFIG_SPARSE_IRQ is not set
CONFIG_X86_MPPARSE=y
CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_VSMP is not set
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_PARAVIRT_GUEST is not set
CONFIG_MEMTEST=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_CPU=y
CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_INTERNODE_CACHE_BYTES=64
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_X86_DS=y
CONFIG_X86_PTRACE_BTS=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_GART_IOMMU=y
CONFIG_CALGARY_IOMMU=y
CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
CONFIG_AMD_IOMMU=y
# CONFIG_AMD_IOMMU_STATS is not set
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
CONFIG_IOMMU_API=y
# CONFIG_MAXSMP is not set
CONFIG_NR_CPUS=8
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
CONFIG_X86_MCE=y
CONFIG_X86_NEW_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set
CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_I8K is not set
CONFIG_MICROCODE=m
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
# CONFIG_X86_CPU_DEBUG is not set
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_DIRECT_GBPAGES=y
# CONFIG_NUMA is not set
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_VMEMMAP=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_MMU_NOTIFIER=y
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_X86_RESERVE_LOW_64K=y
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
# CONFIG_X86_PAT is not set
# CONFIG_EFI is not set
# CONFIG_SECCOMP is not set
# CONFIG_CC_STACKPROTECTOR is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_SCHED_HRTICK=y
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_HOTPLUG_CPU=y
CONFIG_COMPAT_VDSO=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y

#
# Power management and ACPI options
#
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_HIBERNATION is not set
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_PROCFS_POWER=y
CONFIG_ACPI_SYSFS_POWER=y
CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_AC=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=y
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_CUSTOM_DSDT is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
# CONFIG_ACPI_PCI_SLOT is not set
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_CONTAINER=y
CONFIG_ACPI_SBS=m

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m

#
# CPUFreq processor drivers
#
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_POWERNOW_K8=y
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
# CONFIG_X86_P4_CLOCKMOD is not set

#
# shared options
#
# CONFIG_X86_SPEEDSTEP_LIB is not set
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y

#
# Memory power savings
#
# CONFIG_I7300_IDLE is not set

#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_DOMAINS=y
# CONFIG_DMAR is not set
# CONFIG_INTR_REMAP is not set
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=m
CONFIG_PCIEAER=y
# CONFIG_PCIEASPM is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
CONFIG_HT_IRQ=y
# CONFIG_PCI_IOV is not set
CONFIG_ISA_DMA_API=y
CONFIG_K8_NB=y
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_FAKE=m
CONFIG_HOTPLUG_PCI_ACPI=m
CONFIG_HOTPLUG_PCI_ACPI_IBM=m
# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_SHPC=m

#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=y
CONFIG_IA32_EMULATION=y
# CONFIG_IA32_AOUT is not set
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=y
CONFIG_TCP_CONG_CUBIC=m
CONFIG_TCP_CONG_WESTWOOD=m
CONFIG_TCP_CONG_HTCP=m
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_VEGAS=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
# CONFIG_TCP_CONG_YEAH is not set
# CONFIG_TCP_CONG_ILLINOIS is not set
CONFIG_DEFAULT_BIC=y
# CONFIG_DEFAULT_CUBIC is not set
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_WESTWOOD is not set
# CONFIG_DEFAULT_RENO is not set
CONFIG_DEFAULT_TCP_CONG="bic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_NETLABEL is not set
CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set

#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not set
# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
CONFIG_RFKILL=m
# CONFIG_RFKILL_INPUT is not set
CONFIG_RFKILL_LEDS=y

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
# CONFIG_MTD is not set
# CONFIG_PARPORT is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y

#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=m
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_BLK_DEV_XIP is not set
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_DELL_LAPTOP is not set
# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=m
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m
CONFIG_CHR_DEV_SCH=m

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set
CONFIG_SCSI_WAIT_SCAN=m

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=m
# CONFIG_SCSI_FC_TGT_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
CONFIG_SCSI_SAS_ATTRS=m
CONFIG_SCSI_SAS_LIBSAS=m
# CONFIG_SCSI_SAS_ATA is not set
CONFIG_SCSI_SAS_HOST_SMP=y
# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
CONFIG_SCSI_SRP_ATTRS=m
# CONFIG_SCSI_SRP_TGT_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_ACPI=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y
CONFIG_SATA_SVW=y
CONFIG_ATA_PIIX=y
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ACPI is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
CONFIG_ATA_GENERIC=y
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
CONFIG_PATA_MPIIX=y
CONFIG_PATA_OLDPIIX=y
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
CONFIG_PATA_SERVERWORKS=y
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_SCH is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#

#
# Enable only one of the two stacks, unless you know what you are doing
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
CONFIG_I2O=m
# CONFIG_I2O_LCT_NOTIFY_ON_CHANGES is not set
CONFIG_I2O_EXT_ADAPTEC=y
CONFIG_I2O_EXT_ADAPTEC_DMA64=y
CONFIG_I2O_BUS=m
CONFIG_I2O_BLOCK=m
CONFIG_I2O_SCSI=m
CONFIG_I2O_PROC=m
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
# CONFIG_VETH is not set
# CONFIG_NET_SB1000 is not set
# CONFIG_ARCNET is not set
# CONFIG_NET_ETHERNET is not set
CONFIG_MII=m
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
CONFIG_E1000E=y
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set

#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
# CONFIG_LIBERTAS is not set
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_IPW2100 is not set
# CONFIG_IPW2200 is not set
# CONFIG_HOSTAP is not set
# CONFIG_HERMES is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#

#
# USB Network Adapters
#
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
# CONFIG_USB_NET_CDC_EEM is not set
CONFIG_USB_NET_DM9601=m
# CONFIG_USB_NET_SMSC95XX is not set
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_NET1080=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_NET_CDC_SUBSET=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=m
# CONFIG_USB_HSO is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
CONFIG_NETCONSOLE=y
# CONFIG_NETCONSOLE_DYNAMIC is not set
CONFIG_NETPOLL=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_POLLDEV=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_KEYBOARD_STOWAWAY=m
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_BCM5974 is not set
CONFIG_MOUSE_VSXXXAA=m
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=m
CONFIG_JOYSTICK_A3D=m
CONFIG_JOYSTICK_ADI=m
CONFIG_JOYSTICK_COBRA=m
CONFIG_JOYSTICK_GF2K=m
CONFIG_JOYSTICK_GRIP=m
CONFIG_JOYSTICK_GRIP_MP=m
CONFIG_JOYSTICK_GUILLEMOT=m
CONFIG_JOYSTICK_INTERACT=m
CONFIG_JOYSTICK_SIDEWINDER=m
CONFIG_JOYSTICK_TMDC=m
CONFIG_JOYSTICK_IFORCE=m
CONFIG_JOYSTICK_IFORCE_USB=y
CONFIG_JOYSTICK_IFORCE_232=y
CONFIG_JOYSTICK_WARRIOR=m
CONFIG_JOYSTICK_MAGELLAN=m
CONFIG_JOYSTICK_SPACEORB=m
CONFIG_JOYSTICK_SPACEBALL=m
CONFIG_JOYSTICK_STINGER=m
CONFIG_JOYSTICK_TWIDJOY=m
# CONFIG_JOYSTICK_ZHENHUA is not set
CONFIG_JOYSTICK_JOYDUMP=m
# CONFIG_JOYSTICK_XPAD is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_ELO=m
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
CONFIG_TOUCHSCREEN_MTOUCH=m
# CONFIG_TOUCHSCREEN_INEXIO is not set
CONFIG_TOUCHSCREEN_MK712=m
CONFIG_TOUCHSCREEN_PENMOUNT=m
CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
CONFIG_TOUCHSCREEN_TOUCHWIN=m
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PCSPKR=m
# CONFIG_INPUT_APANEL is not set
CONFIG_INPUT_ATLAS_BTNS=m
# CONFIG_INPUT_ATI_REMOTE is not set
# CONFIG_INPUT_ATI_REMOTE2 is not set
# CONFIG_INPUT_KEYSPAN_REMOTE is not set
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
CONFIG_INPUT_UINPUT=m

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
CONFIG_GAMEPORT=m
CONFIG_GAMEPORT_NS558=m
CONFIG_GAMEPORT_L4=m
CONFIG_GAMEPORT_EMU10K1=m
CONFIG_GAMEPORT_FM801=m

#
# Character devices
#
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVKMEM=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_COMPUTONE is not set
# CONFIG_ROCKETPORT is not set
CONFIG_CYCLADES=m
# CONFIG_CYZ_INTR is not set
# CONFIG_DIGIEPCA is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
CONFIG_SYNCLINK=m
CONFIG_SYNCLINKMP=m
CONFIG_SYNCLINK_GT=m
CONFIG_N_HDLC=m
# CONFIG_RISCOM8 is not set
# CONFIG_SPECIALIX is not set
# CONFIG_SX is not set
# CONFIG_RIO is not set
# CONFIG_STALDRV is not set
# CONFIG_NOZOMI is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_NR_UARTS=32
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
CONFIG_SERIAL_JSM=m
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_IPMI_HANDLER=m
# CONFIG_IPMI_PANIC_EVENT is not set
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SI=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
CONFIG_HW_RANDOM_INTEL=m
CONFIG_HW_RANDOM_AMD=m
CONFIG_NVRAM=y
CONFIG_R3964=m
# CONFIG_APPLICOM is not set
CONFIG_MWAVE=m
CONFIG_PC8736x_GPIO=m
CONFIG_NSC_GPIO=m
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
CONFIG_HANGCHECK_TIMER=m
CONFIG_TCG_TPM=m
CONFIG_TCG_TIS=m
CONFIG_TCG_NSC=m
CONFIG_TCG_ATMEL=m
CONFIG_TCG_INFINEON=m
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=m

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD8111=m
CONFIG_I2C_I801=m
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
CONFIG_I2C_NFORCE2=m
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
CONFIG_I2C_SIS96X=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set

#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_PARPORT_LIGHT=m
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set

#
# Graphics adapter I2C/DDC channel drivers
#
CONFIG_I2C_VOODOO3=m

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
CONFIG_I2C_STUB=m

#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
CONFIG_SENSORS_PCF8574=m
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
CONFIG_SENSORS_MAX6875=m
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set

#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=m
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not set
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_SC520_WDT is not set
# CONFIG_EUROTECH_WDT is not set
# CONFIG_IB700_WDT is not set
# CONFIG_IBMASR is not set
# CONFIG_WAFER_WDT is not set
# CONFIG_I6300ESB_WDT is not set
# CONFIG_ITCO_WDT is not set
# CONFIG_IT8712F_WDT is not set
CONFIG_IT87_WDT=m
# CONFIG_HP_WATCHDOG is not set
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not set
# CONFIG_60XX_WDT is not set
# CONFIG_SBC8360_WDT is not set
# CONFIG_CPU5_WDT is not set
# CONFIG_SMSC_SCH311X_WDT is not set
# CONFIG_SMSC37B787_WDT is not set
# CONFIG_W83627HF_WDT is not set
# CONFIG_W83697HF_WDT is not set
# CONFIG_W83697UG_WDT is not set
# CONFIG_W83877F_WDT is not set
# CONFIG_W83977F_WDT is not set
# CONFIG_MACHZ_WDT is not set
# CONFIG_SBC_EPX_C3_WATCHDOG is not set

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set

#
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
CONFIG_SSB=m
CONFIG_SSB_SPROM=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
# CONFIG_SSB_B43_PCI_BRIDGE is not set
# CONFIG_SSB_DEBUG is not set
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set

#
# Multimedia devices
#

#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_VIDEO_MEDIA is not set

#
# Multimedia drivers
#
# CONFIG_DAB is not set

#
# Graphics support
#
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
CONFIG_AGP_SIS=y
CONFIG_AGP_VIA=y
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_GENERIC=y
CONFIG_BACKLIGHT_PROGEAR=m
# CONFIG_BACKLIGHT_MBP_NVIDIA is not set
# CONFIG_BACKLIGHT_SAHARA is not set

#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set

#
# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y

#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
CONFIG_LOGITECH_FF=y
# CONFIG_LOGIRUMBLEPAD2_FF is not set
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
# CONFIG_GREENASIA_FF is not set
CONFIG_HID_TOPSEED=y
CONFIG_THRUSTMASTER_FF=y
CONFIG_ZEROPLUS_FF=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
CONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not set
CONFIG_USB_MON=y
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
CONFIG_USB_ISP116X_HCD=m
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=m
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_HWA_HCD is not set

#
# USB Device Class drivers
#
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
CONFIG_USB_LIBUSUAL=y

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set

#
# USB port drivers
#
CONFIG_USB_SERIAL=m
CONFIG_USB_EZUSB=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
# CONFIG_USB_SERIAL_CH341 is not set
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
# CONFIG_USB_SERIAL_CP210X is not set
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_FUNSOFT=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
# CONFIG_USB_SERIAL_IUU is not set
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7840=m
# CONFIG_USB_SERIAL_MOTOROLA is not set
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_OTI6858 is not set
# CONFIG_USB_SERIAL_QUALCOMM is not set
# CONFIG_USB_SERIAL_SPCP8X5 is not set
CONFIG_USB_SERIAL_HP4X=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SAFE_PADDED=y
# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
# CONFIG_USB_SERIAL_SYMBOL is not set
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_XIRCOM=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
# CONFIG_USB_SERIAL_OPTICON is not set
CONFIG_USB_SERIAL_DEBUG=m

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set

#
# OTG and related infrastructure
#
# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#
# CONFIG_LEDS_ALIX2 is not set
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_CLEVO_MAIL is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set

#
# iptables trigger is under Netfilter config (LED target)
#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y

#
# Reporting subsystems
#
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=m
CONFIG_EDAC_E752X=m
# CONFIG_EDAC_I82975X is not set
# CONFIG_EDAC_I3000 is not set
# CONFIG_EDAC_X38 is not set
# CONFIG_EDAC_I5400 is not set
# CONFIG_EDAC_I5000 is not set
# CONFIG_EDAC_I5100 is not set
CONFIG_RTC_LIB=m
CONFIG_RTC_CLASS=m

#
# RTC interfaces
#
# CONFIG_RTC_INTF_SYSFS is not set
# CONFIG_RTC_INTF_PROC is not set
# CONFIG_RTC_INTF_DEV is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set

#
# SPI RTC drivers
#

#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set

#
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
CONFIG_X86_PLATFORM_DEVICES=y
# CONFIG_ACER_WMI is not set
# CONFIG_ASUS_LAPTOP is not set
# CONFIG_FUJITSU_LAPTOP is not set
# CONFIG_MSI_LAPTOP is not set
# CONFIG_PANASONIC_LAPTOP is not set
# CONFIG_COMPAL_LAPTOP is not set
# CONFIG_SONY_LAPTOP is not set
# CONFIG_THINKPAD_ACPI is not set
# CONFIG_INTEL_MENLOW is not set
# CONFIG_EEEPC_LAPTOP is not set
# CONFIG_ACPI_WMI is not set
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set

#
# Firmware Drivers
#
CONFIG_EDD=m
# CONFIG_EDD_OFF is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m
CONFIG_DMIID=y
# CONFIG_ISCSI_IBFT_FIND is not set

#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT2_FS_XIP=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
# CONFIG_EXT4_FS is not set
CONFIG_FS_XIP=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
CONFIG_XFS_FS=m
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
# CONFIG_QUOTA_NETLINK_INTERFACE is not set
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
CONFIG_GENERIC_ACL=y

#
# Caches
#
# CONFIG_FSCACHE is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
# CONFIG_NTFS_FS is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=m
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
CONFIG_AFFS_FS=m
CONFIG_ECRYPT_FS=m
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_CRAMFS=m
# CONFIG_SQUASHFS is not set
CONFIG_VXFS_FS=m
CONFIG_MINIX_FS=m
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_QNX4FS_FS=m
CONFIG_ROMFS_FS=m
CONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not set
CONFIG_ROMFS_ON_BLOCK=y
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_RPCSEC_GSS_SPKM3=m
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
CONFIG_ALLOW_WARNINGS=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCKDEP=y
CONFIG_LOCK_STAT=y
# CONFIG_DEBUG_LOCKDEP is not set
CONFIG_TRACE_IRQFLAGS=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VIRTUAL is not set
# CONFIG_DEBUG_WRITECOUNT is not set
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FTRACE_NMI_ENTER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_HW_BRANCH_TRACER=y
CONFIG_HAVE_FTRACE_SYSCALLS=y
CONFIG_RING_BUFFER=y
CONFIG_FTRACE_NMI_ENTER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SYSPROF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_BOOT_TRACER is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_POWER_TRACER is not set
# CONFIG_KSYM_TRACER is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_HW_BRANCH_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_DYNAMIC_FTRACE=y
# CONFIG_FUNCTION_PROFILER is not set
CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_MMIOTRACE is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
# CONFIG_KGDB_TESTS is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
# CONFIG_STRICT_DEVMEM is not set
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_X86_PTDUMP is not set
# CONFIG_DEBUG_RODATA is not set
# CONFIG_DEBUG_NX_TEST is not set
# CONFIG_IOMMU_DEBUG is not set
# CONFIG_IOMMU_STRESS is not set
CONFIG_X86_DS_SELFTEST=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=0
# CONFIG_DEBUG_BOOT_PARAMS is not set
# CONFIG_CPA_DEBUG is not set
# CONFIG_OPTIMIZE_INLINING is not set

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
# CONFIG_SECURITY_SELINUX is not set
# CONFIG_SECURITY_TOMOYO is not set
# CONFIG_IMA is not set
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
# CONFIG_CRYPTO_TEST is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set

#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m

#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRC32C_INTEL is not set
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_X86_64=m
CONFIG_CRYPTO_AES_NI_INTEL=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SALSA20_X86_64 is not set
# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_TWOFISH_X86_64=m

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_ZLIB=m
# CONFIG_CRYPTO_LZO is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m
# CONFIG_KVM_TRACE is not set
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not set
CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_NLATTR=y



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
  2009-06-08 13:38     ` Ming Lei
  2009-06-08 13:58     ` Ming Lei
@ 2009-06-08 15:50     ` Ming Lei
  2009-06-09 12:52       ` Ming Lei
  2 siblings, 1 reply; 716+ messages in thread
From: Ming Lei @ 2009-06-08 15:50 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, akpm

On Mon, 08 Jun 2009 14:22:07 +0200
Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:

> On Sun, 2009-05-31 at 22:49 +0800, tom.leiming@gmail.com wrote:
> > Hi,
> > Currently lockdep uses recursion DFS(depth-first search) algorithm
> > to search target in checking lock
> > circle(check_noncircular()),irq-safe ->
> > irq-unsafe(check_irq_usage()) and irq inversion when adding a new
> > lock dependency. This patches replace the current DFS with BFS,
> > based on the following consideration:
> > 
> >      1,no loss of efficiency, no matter DFS or BFS, the running time
> >      are O(V+E) (V is vertex count, and E is edge count of one
> >      graph);
> > 
> >      2,BFS may be easily implemented by circular queue and consumes
> >      much less kernel stack space than DFS for DFS is implemented by
> >      recursion.
> > 
> >      3, The shortest path can be obtained by BFS if the target is
> >      found, but can't be got by DFS. By the shortest path, we can
> >      shorten the lock dependency chain and help to troubleshoot lock
> >      problem easier than before.
> > 
> 
> OK, so I applied the patches and the cleanup below.
> 
> mostly little style nits and moving the circular queue into lockdep.c
> (nobody else uses it, so why share it?).
> 
> One thing though, macros with return statements?! that's seriously bad
> style, don't do that.
> 
> One thing that worries me a little is that we loose DaveM's
> lockdep_dependency_visit() optimization. My brain seems unwilling to
> co-operate on determining if BFS would make that redundant, so a
> little word on that would be appreciated.
> 
> Then I booted it and all hell broke loose, so either I wrecked
> something or you did :-), would you terribly mind poking at that a
> little?

I have fixed the bug, which is introduced in your patch:
	lockdep: clean up after BFS patches.

Please apply and verify the patch,thanks.

I'll go to bed,:-)

>From e99ce7b2b4985032e9f54b08a7790f3df2783286 Mon Sep 17 00:00:00 2001
From: Ming Lei <tom.leiming@gmail.com>
Date: Mon, 8 Jun 2009 23:38:59 +0800
Subject: [PATCH] kernel:lockdep:fix return value of check_usage*()

Return zero if BFS find the target, so fix return value of callers
of BFS.

The patch fixes the boot failure introduced by the patch:
	lockdep: clean up after BFS patches
.

Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
 kernel/lockdep.c |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 09a141f..48c3364 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -1250,8 +1250,6 @@ find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
 	debug_atomic_inc(&nr_find_usage_forwards_checks);
 
 	result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
-	if (result < 0)
-		return print_bfs_bug(result);
 
 	return result;
 }
@@ -1275,8 +1273,6 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
 	debug_atomic_inc(&nr_find_usage_backwards_checks);
 
 	result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
-	if (result < 0)
-		return print_bfs_bug(result);
 
 	return result;
 }
@@ -1397,13 +1393,17 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
 
 	this.class = hlock_class(prev);
 	ret = find_usage_backwards(&this, bit_backwards, &target_entry);
-	if (!ret || ret == 1)
+	if (ret < 0)
+		return print_bfs_bug(ret);
+	if (ret == 1)
 		return ret;
 
 	that.parent = NULL;
 	that.class = hlock_class(next);
 	ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
-	if (!ret || ret == 1)
+	if (ret < 0)
+		return print_bfs_bug(ret);
+	if (ret == 1)
 		return ret;
 
 	return print_bad_irq_dependency(curr, &this, &that,
@@ -2088,7 +2088,9 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
 	root.parent = NULL;
 	root.class = hlock_class(this);
 	ret = find_usage_forwards(&root, bit, &target_entry);
-	if (!ret || ret == 1)
+	if (ret < 0)
+		return print_bfs_bug(ret);
+	if (ret == 1)
 		return ret;
 
 	return print_irq_inversion_bug(curr, &root, target_entry,
@@ -2110,7 +2112,9 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
 	root.parent = NULL;
 	root.class = hlock_class(this);
 	ret = find_usage_backwards(&root, bit, &target_entry);
-	if (!ret || ret == 1)
+	if (ret < 0)
+		return print_bfs_bug(ret);
+	if (ret == 1)
 		return ret;
 
 	return print_irq_inversion_bug(curr, &root, target_entry,
-- 
1.6.0.GIT




-- 
Lei Ming

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/8] kernel:lockdep:replace DFS with BFS
  2009-06-08 15:50     ` Ming Lei
@ 2009-06-09 12:52       ` Ming Lei
  0 siblings, 0 replies; 716+ messages in thread
From: Ming Lei @ 2009-06-09 12:52 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, akpm

2009/6/8 Ming Lei <tom.leiming@gmail.com>:
> I have fixed the bug, which is introduced in your patch:
>        lockdep: clean up after BFS patches.
>
> Please apply and verify the patch,thanks.

Hi, Peter

Would you mind verifying the patch which fixes your kernel boot failure?

If it does work,  What do we need to do for this patches being accepted
by tip-tree?

Thanks.

>
> I'll go to bed,:-)
>
> From e99ce7b2b4985032e9f54b08a7790f3df2783286 Mon Sep 17 00:00:00 2001
> From: Ming Lei <tom.leiming@gmail.com>
> Date: Mon, 8 Jun 2009 23:38:59 +0800
> Subject: [PATCH] kernel:lockdep:fix return value of check_usage*()
>
> Return zero if BFS find the target, so fix return value of callers
> of BFS.
>
> The patch fixes the boot failure introduced by the patch:
>        lockdep: clean up after BFS patches
> .
>
> Signed-off-by: Ming Lei <tom.leiming@gmail.com>
> ---
>  kernel/lockdep.c |   20 ++++++++++++--------
>  1 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/kernel/lockdep.c b/kernel/lockdep.c
> index 09a141f..48c3364 100644
> --- a/kernel/lockdep.c
> +++ b/kernel/lockdep.c
> @@ -1250,8 +1250,6 @@ find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
>        debug_atomic_inc(&nr_find_usage_forwards_checks);
>
>        result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
> -       if (result < 0)
> -               return print_bfs_bug(result);
>
>        return result;
>  }
> @@ -1275,8 +1273,6 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
>        debug_atomic_inc(&nr_find_usage_backwards_checks);
>
>        result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
> -       if (result < 0)
> -               return print_bfs_bug(result);
>
>        return result;
>  }
> @@ -1397,13 +1393,17 @@ check_usage(struct task_struct *curr, struct held_lock *prev,
>
>        this.class = hlock_class(prev);
>        ret = find_usage_backwards(&this, bit_backwards, &target_entry);
> -       if (!ret || ret == 1)
> +       if (ret < 0)
> +               return print_bfs_bug(ret);
> +       if (ret == 1)
>                return ret;
>
>        that.parent = NULL;
>        that.class = hlock_class(next);
>        ret = find_usage_forwards(&that, bit_forwards, &target_entry1);
> -       if (!ret || ret == 1)
> +       if (ret < 0)
> +               return print_bfs_bug(ret);
> +       if (ret == 1)
>                return ret;
>
>        return print_bad_irq_dependency(curr, &this, &that,
> @@ -2088,7 +2088,9 @@ check_usage_forwards(struct task_struct *curr, struct held_lock *this,
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_forwards(&root, bit, &target_entry);
> -       if (!ret || ret == 1)
> +       if (ret < 0)
> +               return print_bfs_bug(ret);
> +       if (ret == 1)
>                return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
> @@ -2110,7 +2112,9 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
>        root.parent = NULL;
>        root.class = hlock_class(this);
>        ret = find_usage_backwards(&root, bit, &target_entry);
> -       if (!ret || ret == 1)
> +       if (ret < 0)
> +               return print_bfs_bug(ret);
> +       if (ret == 1)
>                return ret;
>
>        return print_irq_inversion_bug(curr, &root, target_entry,
> --
> 1.6.0.GIT
>
>
>
>
> --
> Lei Ming
>



-- 
Lei Ming

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
       [not found] <yes>
  2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
@ 2009-07-28 16:34 ` John Schmoller
  2009-07-28 17:49   ` Wolfgang Denk
  2009-07-28 16:34 ` [U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator John Schmoller
                   ` (88 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: John Schmoller @ 2009-07-28 16:34 UTC (permalink / raw)
  To: u-boot

Hello all,
 
I've been working on writing a User's Manual generation tool, and before
I get too far I'd like to see if this is something the U-Boot community
would be interested in.  
 
The thought was that everyone needs to develop User's Manuals for their
customers, and there's no reason for us all to reinvent the wheel for
each product we create.  I've written a Perl script, uboot-doc, which is
very loosely based on the kernel-doc documentation creator in Linux.
(Take it easy on my Perl, this is my first script.) The specific syntax
is described in uboot-doc, but the parser takes formatted comments with
@'s and converts the information into DocBook XML. The DocBook XML can be
used to generate HTML, XHTML, PDFs, and text, and can be extended to change
formatting and appearance. The static portions of the manual are taken
from .tmpl files in the doc/manual/ directory, which have basic
precompiler support (#ifdef, #else, #endif) and support for accessing
system environment variables (${TOPDIR}, for example) and any value
found in autoconf.mk, (@CONFIG_BAUDRATE, for example). All template
files in doc/manual/ can be over-ridden by a board specific file in
board/$BOARDDIR/manual. For example, doc/manual/manual.tmpl would be
over-ridden by board/$BOARDDIR/manual/manual.tmpl.

General Control Flow:
C pre-processor -> doc_stream.pl : pre-processed code gets everything but
comments with an @ stripped away
doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
file
autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
 *.tmpl -> uboot-doc : template files are processed into XML
 *.xml -> xsltproc : XML is converted into desired output format
 *.fo -> fop : (PDFs only) fo files are translated to PDF

Steps to compile your very own manual (using Ubuntu package names):
1) Install xsltproc. I'm using version
1.1.24-2ubuntu2.  If you've got no desire to make text, html, xhtml, or
pdf you don't need this tool.

2) Install docbook-xsl. I'm using version
1.73.2.dfsg.1-5. If you've got no desire to make text, html, xhtml, or
pdf you don't need this tool.

3) FOP needs to be installed with hyphenation support, which is not
available from Synaptic or apt-get.  Use the instructions from 
http://www.linuxfromscratch.org/blfs/view/svn/pst/fop.html to install
your version of FOP (yes, you do need OFFO and JAI). You will need to
install ant if you don't already have it (1.7.1-0ubuntu2).
If you've got no desire to make a PDF, you don't need this tool.

4) If you follow the steps above, the default values of DOCBOOK_XSL_DIR,
XSLT_PROCESSOR, and FO_PROCESSOR should be correct. If you decided to
try to go it your own, set them accordingly. DOCBOOK_XSL_DIR points to
your Docbook stylesheet directory, XSLT_PROCESSOR points to the default
program which compiles XML into it's various forms, and FO_PROCESSOR
points the the default program for turning FO images into PDFs.

5) Once you have the tools installed, you should be able to compile a
manual. This documentation feature was tested on the X-ES's XPedite5370.
make XPEDITE5370_config
make {xml/html/xhtml/pdf/text}
Note: text doesn't work yet as I believe there is an issue with the
docbook style sheets (or possibly how I'm using them).  It's being looked
into. Something about varlistentries not belonging in varlists?  I dunno.

The doc/manual directory also includes a PDF style sheet (uboot_manual.xsl).
By creating your own book_info.tmpl, you can add a company logo
and an address to the cover page. By default these two are left out. It is also
possible to create a completely new style sheet to customize your manual look.
Similarly, HTML output can be customized using CSS. The results of this output
as well as the HTML output can be found on the X-ES website:
www.xes-inc.com/sources/u-boot/index.html
www.xes-inc.com/sources/u-boot/xpedite5370.pdf
Note that I've defined a "mediaobject" and "address" in my custom
board/xes/xpedite5370/book_info.tmpl to place the address and company logo
on the cover page.

I see several advantages to adopting this scheme.
 - Documentation should be easier to keep in sync with code
 - DocBook XML output can be used to generate webpages, PDFs, text, etc, 
   which are all extensible
 - People don't have to reinvent the wheel when writing documentation
 - Source code ends up being thouroughly commented

These patches are just meant to be an example of how in-code documentation
could be used. You'll also notice there are many warnings regarding variables
the manual is referencing which aren't defined yet. I wanted to get some
feedback before diving in too far. What do others think? Is this worth
pursuing?

Thanks,
John

John Schmoller (3):
  uboot-doc: Initial support of user documentation generator
  uboot-doc: Add example support for uboot-doc
  xpedite5370: Add uboot-doc support

 Makefile                                           |    2 +
 board/xes/xpedite5370/manual/book_info.tmpl        |   52 ++
 board/xes/xpedite5370/manual/booting_linux.tmpl    |  179 ++++
 board/xes/xpedite5370/manual/booting_vxworks.tmpl  |  166 ++++
 board/xes/xpedite5370/manual/manual.tmpl           |   30 +
 board/xes/xpedite5370/manual/redundant_images.tmpl |   50 ++
 board/xes/xpedite5370/manual/scripting.tmpl        |  168 ++++
 common/cmd_i2c.c                                   |   71 ++-
 common/cmd_mem.c                                   |   45 +-
 common/cmd_net.c                                   |   30 +-
 common/env_common.c                                |   35 +
 config.mk                                          |    1 +
 doc/manual/85xx_program_flow.tmpl                  |   74 ++
 doc/manual/book_info.tmpl                          |   35 +
 doc/manual/booting_linux.tmpl                      |  249 ++++++
 doc/manual/config.mk                               |   74 ++
 doc/manual/doc-stream.pl                           |   34 +
 doc/manual/introduction.tmpl                       |  136 +++
 doc/manual/manual.tmpl                             |   26 +
 doc/manual/scripting.tmpl                          |  154 ++++
 doc/manual/setup.tmpl                              |  294 +++++++
 doc/manual/uboot-doc                               |  866 ++++++++++++++++++++
 doc/manual/uboot_manual.xsl                        |  286 +++++++
 include/configs/XPEDITE5370.h                      |   47 ++
 post/tests.c                                       |   16 +
 rules.mk                                           |    7 +
 26 files changed, 3122 insertions(+), 5 deletions(-)
 create mode 100644 board/xes/xpedite5370/manual/book_info.tmpl
 create mode 100644 board/xes/xpedite5370/manual/booting_linux.tmpl
 create mode 100644 board/xes/xpedite5370/manual/booting_vxworks.tmpl
 create mode 100644 board/xes/xpedite5370/manual/manual.tmpl
 create mode 100644 board/xes/xpedite5370/manual/redundant_images.tmpl
 create mode 100644 board/xes/xpedite5370/manual/scripting.tmpl
 create mode 100644 doc/manual/85xx_program_flow.tmpl
 create mode 100644 doc/manual/book_info.tmpl
 create mode 100644 doc/manual/booting_linux.tmpl
 create mode 100644 doc/manual/config.mk
 create mode 100644 doc/manual/doc-stream.pl
 create mode 100644 doc/manual/introduction.tmpl
 create mode 100644 doc/manual/manual.tmpl
 create mode 100644 doc/manual/scripting.tmpl
 create mode 100644 doc/manual/setup.tmpl
 create mode 100644 doc/manual/uboot-doc
 create mode 100644 doc/manual/uboot_manual.xsl

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator
       [not found] <yes>
                   ` (2 preceding siblings ...)
  2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
@ 2009-07-28 16:34 ` John Schmoller
  2009-07-28 16:34 ` [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc John Schmoller
                   ` (87 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: John Schmoller @ 2009-07-28 16:34 UTC (permalink / raw)
  To: u-boot

Initial support of U-Boot User's Manual documentation generator.
It makes use of the C pre-processor to gather context, and then
the doc-stream.pl program parses out interesting comments for
consideration by uboot-doc, which creates DocBook style XML from
autogenerated files as well as the template files.  Template
files are pseudo-XML with precompiler directives. Also includes
a stylesheet wrapper for manual customization.

Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
---
 Makefile                          |    2 +
 config.mk                         |    1 +
 doc/manual/85xx_program_flow.tmpl |   74 ++++
 doc/manual/book_info.tmpl         |   35 ++
 doc/manual/booting_linux.tmpl     |  249 +++++++++++
 doc/manual/config.mk              |   74 ++++
 doc/manual/doc-stream.pl          |   34 ++
 doc/manual/introduction.tmpl      |  136 ++++++
 doc/manual/manual.tmpl            |   26 ++
 doc/manual/scripting.tmpl         |  154 +++++++
 doc/manual/setup.tmpl             |  294 +++++++++++++
 doc/manual/uboot-doc              |  866 +++++++++++++++++++++++++++++++++++++
 doc/manual/uboot_manual.xsl       |  286 ++++++++++++
 rules.mk                          |    7 +
 14 files changed, 2238 insertions(+), 0 deletions(-)
 create mode 100644 doc/manual/85xx_program_flow.tmpl
 create mode 100644 doc/manual/book_info.tmpl
 create mode 100644 doc/manual/booting_linux.tmpl
 create mode 100644 doc/manual/config.mk
 create mode 100644 doc/manual/doc-stream.pl
 create mode 100644 doc/manual/introduction.tmpl
 create mode 100644 doc/manual/manual.tmpl
 create mode 100644 doc/manual/scripting.tmpl
 create mode 100644 doc/manual/setup.tmpl
 create mode 100644 doc/manual/uboot-doc
 create mode 100644 doc/manual/uboot_manual.xsl

diff --git a/Makefile b/Makefile
index ef535ed..ff4f242 100644
--- a/Makefile
+++ b/Makefile
@@ -153,6 +153,7 @@ ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
 all:
 sinclude $(obj)include/autoconf.mk.dep
 sinclude $(obj)include/autoconf.mk
+sinclude $(obj)doc/manual/config.mk
 
 # load ARCH, BOARD, and CPU configuration
 include $(obj)include/config.mk
@@ -3646,6 +3647,7 @@ clean:
 	@rm -f $(obj)include/bmp_logo.h
 	@rm -f $(obj)nand_spl/{u-boot-spl,u-boot-spl.map,System.map}
 	@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
+	@rm -f $(obj)doc/manual/{*.xml,*.html,*.fo,*.pdf,params.xsl}
 	@rm -f $(TIMESTAMP_FILE) $(VERSION_FILE)
 	@find $(OBJTREE) -type f \
 		\( -name 'core' -o -name '*.bak' -o -name '*~' \
diff --git a/config.mk b/config.mk
index fd56621..fb8bed0 100644
--- a/config.mk
+++ b/config.mk
@@ -96,6 +96,7 @@ BOARDDIR = $(VENDOR)/$(BOARD)
 else
 BOARDDIR = $(BOARD)
 endif
+export BOARDDIR
 ifdef	BOARD
 sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk	# include board specific rules
 endif
diff --git a/doc/manual/85xx_program_flow.tmpl b/doc/manual/85xx_program_flow.tmpl
new file mode 100644
index 0000000..1010780
--- /dev/null
+++ b/doc/manual/85xx_program_flow.tmpl
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+    <sect2 xmlns="http://docbook.org/ns/docbook"
+	   xml:id="uboot_setup_prog_flow">
+      <title>U-Boot Program Flow</title>
+      <para>U-Boot follows the following program flow.</para>
+      <orderedlist>
+	<listitem>
+	  <para>Reset</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Processor</para>
+	</listitem>
+	<listitem>
+	  <para>Set up data cache as stack</para>
+	</listitem>
+	<listitem>
+	  <para>Set up TLBs and LAWs</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize U-Boot environment</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize serial port</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize I2C</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize DRAM</para>
+	</listitem>
+	<listitem>
+	  <para>Relocate from Flash to RAM</para>
+	</listitem>
+	<listitem>
+	  <para>Set up data cache</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Flash Structure</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize malloc area</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize NAND device</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize PCI</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Vector Table</para>
+	</listitem>
+	<listitem>
+	  <para>Initialize Ethernet</para>
+	</listitem>
+#ifdef CONFIG_PREBOOT
+	<listitem>
+	  <para>Exectue <link linkend="env_preboot"><literal>preboot</literal>
+	    </link> environment variable
+	  </para>
+	</listitem>
+#endif
+	<listitem>
+	  <para>Wait <link linkend="env_bootdelay"><literal>bootdelay</literal>
+	    </link> seconds to stop autoboot
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>If not canceled, execute <link linkend="env_bootcmd">
+	      <literal>bootcmd</literal></link> or enter main loop.
+	  </para>
+	</listitem>
+      </orderedlist>
+    </sect2>
diff --git a/doc/manual/book_info.tmpl b/doc/manual/book_info.tmpl
new file mode 100644
index 0000000..a4cec17
--- /dev/null
+++ b/doc/manual/book_info.tmpl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<info>
+  <title>${BOARD} U-Boot Manual</title>
+  <subtitle>U-Boot User's Manual</subtitle>
+  <releaseinfo>U-Boot version: ${VERSION}</releaseinfo>
+  <titleabbrev>${BOARD}</titleabbrev>
+  <pubdate>${DATE}</pubdate>
+  <legalnotice>
+    <para>
+      U-Boot 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.
+    </para>
+
+    <para>
+      U-Boot 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.
+    </para>
+
+    <para>
+      You should have received a copy of the GNU General Public License
+      along with this program; if not, write to the
+      <orgname>Free Software Foundation, Inc.</orgname>,
+      <address><street>59 Temple Place, Suite 330</street>
+	<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+	<country>USA</country>
+      </address>
+    </para>
+  </legalnotice>
+</info>
+
diff --git a/doc/manual/booting_linux.tmpl b/doc/manual/booting_linux.tmpl
new file mode 100644
index 0000000..e0ab37c
--- /dev/null
+++ b/doc/manual/booting_linux.tmpl
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_linux_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Booting Linux</title>
+
+
+  <sect1 xml:id="uboot_booting_linux">
+    <title>Booting Linux with U-Boot</title>
+    <sect2 xml:id="uboot_booting_linux_intro">
+      <title>Booting Linux</title>
+      <para>The following is intended to be a Quick Start guide for booting a
+	Linux kernel. More information can be found in your Linux Manual.
+      </para>
+
+      <para>Your Linux kernel can be booted from either RAM or from Flash.
+	Images booted from RAM will need to be downloaded from the network
+	using <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	on every reset. Images booted from Flash will be copied from Flash to
+	RAM automatically.
+      </para>
+
+      <sect3 xml:id="uboot_booting_linux_ram">
+	<title>Booting from RAM</title>
+	<para>To boot an image from RAM, you will need to have your Linux
+	  kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and Flat Device Tree image
+#endif
+	  on a TFTP server. See
+	  <link linkend="uboot_setup_network">
+	  <literal>Networking</literal></link> for more information about
+	  TFTP and TFTP servers. Next, you will need to set up your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server.
+#ifdef CONFIG_CMD_DHCP
+	  You can use a DHCP server to accomplish this if
+	  your network has one set up using the
+	  <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> command.
+#endif
+	  Download the Linux kernel using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+	  </screen>
+#ifdef CONFIG_OF_LIBFDT
+	  Download the Flat Device Tree image using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+	  </screen>
+#endif
+	  Adjust the download address based on the size of your kernel image.
+	  Consult your Linux manual for the recommended
+	  <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+	  Set the <link linkend="uboot_env_bootargs">
+	  <literal>bootargs</literal></link> using the
+	  <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	  command. Finally, boot your kernel image.
+	  <screen>
+#ifdef CONFIG_OF_LIBFDT
+bootm 10000000 - c000000
+#else
+bootm 10000000
+#endif
+	  </screen>
+	  Since we didn't disguss downloading a file system, this option
+	  assumes you are booting an NFS file system.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> bootm 10000000 - c000000
+#else
+=> bootm 10000000
+#endif
+## Booting kernel from Legacy Image at 10000000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+
+      <sect3 xml:id="uboot_booting_linux_flash">
+	<title>Booting from Flash</title>
+	<para>To boot an image from Flash, you will need to follow a similar
+	  procedure to load the Kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and FDT
+#endif
+	  for the first time. Make sure you have your Kernel
+#ifdef CONFIG_OF_LIBFDT
+	  and FDT
+#endif
+	  on your TFTP server.  Set your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server. Download the Linux kernel using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command and then erase Flash and copy it using the
+	  <link linkend="uboot_cmd_erase"><literal>erase</literal></link> and
+	  <link linkend="uboot_cmd_cp"><literal>cp</literal></link> commands.
+	  <screen>
+tftp 10000000 &lt;Path to Linux Kernel&gt;
+erase &lt;Flash start + 1000000&gt; +$filesize
+cp.b 10000000 &lt;Flash start + 1000000&gt; $filesize
+	  </screen>
+#ifdef CONFIG_OF_LIBFDT
+	  Download the Flat Device Tree image using the
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	  command.
+	  <screen>
+tftp c000000 &lt;Path to Flat Device Tree image&gt;
+erase &lt;Flash start&gt; +$filesize
+cp.b c000000 &lt;Flash start&gt; $filesize
+	  </screen>
+#endif
+	  Consult your Linux manual for the recommended
+	  <link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>.
+	  Set the <link linkend="uboot_env_bootargs">
+	  <literal>bootargs</literal></link> using the
+	  <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	  command and then save them using <link linkend="uboot_cmd_saveenv">
+	  <literal>saveenv</literal></link>. Set up your
+	  <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+	  environment variable to automatically boot the Linux kernel.
+	  <screen>
+#ifdef CONFIG_OF_LIBFDT
+setenv bootcmd bootm &lt;Flash start + 1000000&gt; - &lt;Flash start&gt;
+#else
+setenv bootcmd bootm &lt;Flash start + 1000000&gt;
+#endif
+	  </screen>
+	  Finally, boot your kernel image by resetting the board.
+	  Since we didn't disguss downloading a file system, this option
+	  assumes you are booting an NFS file system.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv serverip 10.52.0.33
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.0.0
+=> setenv ipaddr 10.52.4.240
+=> tftp 10000000 /home/jschmoller/uImage
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/uImage'.
+Load address: 0x10000000
+Loading: #################################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+=> erase f9000000 +$filesize
+
+.............................. done
+Erased 30 sectors
+=> cp.b 10000000 f9000000 $filesize
+Copy to Flash... done
+#ifdef CONFIG_OF_LIBFDT
+=> tftp c000000 /home/jschmoller/dtb
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC2 device
+TFTP from server 10.52.0.33; our IP address is 10.52.4.240
+Filename '/home/jschmoller/dtb'.
+Load address: 0xc000000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+=> erase f8000000 +$filesize
+
+. done
+Erased 1 sectors
+=> cp.b c000000 f8000000 $filesize
+Copy to Flash... done
+#endif
+=> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw ip=on
+#ifdef CONFIG_OF_LIBFDT
+=> setenv bootcmd bootm f9000000 - f8000000
+#else
+=> setenv bootcmd bootm f9000000
+#endif
+=> saveenv
+=> reset
+&lt;Board resets&gt;
+Hit any key to stop autoboot:  0
+## Booting kernel from Legacy Image at f9000000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/doc/manual/config.mk b/doc/manual/config.mk
new file mode 100644
index 0000000..59bebb7
--- /dev/null
+++ b/doc/manual/config.mk
@@ -0,0 +1,74 @@
+#
+# (C) Copyright 2009 Extreme Engineering Solutions
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#########################################################################
+
+ifndef DOCBOOK_XSL_DIR
+DOCBOOK_XSL_DIR		= /usr/share/xml/docbook/stylesheet/nwalsh
+endif
+export DOCBOOK_XSL_DIR
+
+ifndef XSLT_PROCESSOR
+XSLT_PROCESSOR = xsltproc
+endif
+
+ifndef FO_PROCESSOR
+FO_PROCESSOR = fop
+endif
+
+.PHONY = $(obj)man_parse $(obj)xml
+
+$(obj)man_parse:	$(obj)include/autoconf.mk $(TIMESTAMP_FILE) \
+		$(VERSION_FILE)
+	@for f in $(dir $(LIBS)); do \
+		echo $$f; \
+		$(MAKE) -C $$f _man_parse; \
+	done
+
+$(obj)xml:	$(obj)man_parse
+	perl $(TOPDIR)/doc/manual/uboot-doc \
+		$(TOPDIR)/doc/manual/autoconf-doc.txt
+	rm $(TOPDIR)/doc/manual/autoconf-doc.txt
+
+$(obj)text:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		--stringparam pages.template \
+		$(DOCBOOK_XSL_DIR)/roundtrip/template.xml \
+		$(DOCBOOK_XSL_DIR)/roundtrip/dbk2wordml.xsl \
+		$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)html:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		$(DOCBOOK_XSL_DIR)/html/chunk.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)xhtml:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/ --xinclude \
+		$(DOCBOOK_XSL_DIR)/xhtml/chunk.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+
+$(obj)pdf:	$(obj)xml
+	$(XSLT_PROCESSOR) -o $(TOPDIR)/doc/manual/$(BOARD).fo \
+		--stringparam docbook_path ${DOCBOOK_XSL_DIR} --xinclude \
+		$(TOPDIR)/doc/manual/uboot_manual.xsl \
+			$(TOPDIR)/doc/manual/manual.xml
+		$(FO_PROCESSOR) -fo $(TOPDIR)/doc/manual/$(BOARD).fo -pdf \
+		$(TOPDIR)/doc/manual/$(BOARD).pdf
diff --git a/doc/manual/doc-stream.pl b/doc/manual/doc-stream.pl
new file mode 100644
index 0000000..71b7d02
--- /dev/null
+++ b/doc/manual/doc-stream.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $comment = "";
+my $in_comment = 0;
+
+# This file takes the output of the C pre-processor and scans it for
+# "interesting" comments (those that contain an @) and prints the comment.
+# Those comments are then dumped into a file that can be processed by
+# uboot-doc. Without this script, the output of the C pre-processor is
+# unnecesarily large (~36MB).
+while (<STDIN>) {
+    if (/^\s*\/\*\*\s*$/) {
+	$comment .= $_;
+	$in_comment = 1;
+    } elsif (/\*\//) {
+	if ($in_comment) {
+	    $comment .= $_;
+
+	    if ($comment =~ /.*[\s\*]+ at .*/) {
+		print $comment;
+	    }
+	}
+	$in_comment = 0;
+	$comment = "";
+    } elsif (/\s*\*\s*/) {
+	if ($in_comment) {
+	    $comment .= $_;
+	}
+    }
+}
+
+
diff --git a/doc/manual/introduction.tmpl b/doc/manual/introduction.tmpl
new file mode 100644
index 0000000..063a6b8
--- /dev/null
+++ b/doc/manual/introduction.tmpl
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_introduction_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Das U-Boot</title>
+
+  <sect1 xml:id="uboot_introduction">
+    <title>Introduction to U-Boot</title>
+    <para>The ${BOARD} utilizes the U-Boot bootloader. U-Boot
+    is an open-source bootloader which provides low-level hardware
+    initialization, power on self tests (POSTs), access to onboard peripherals
+    (Ethernet, flash, EEPROMs, sensors, etc.), and contains a powerful
+    set of commands that allow booting a variety of
+    operation systems and applications. Additional U-Boot information
+    can be found at <link ns1:href="http://www.denx.de/wiki/U-Boot/WebHome"
+    xmlns:ns1="http://www.w3.org/1999/xlink"
+    >http://www.denx.de/wiki/U-Boot/WebHome</link>.</para>
+  </sect1>
+
+  <sect1 xml:id="uboot_introduction_terminology">
+    <title>Terminology and Conventions</title>
+    <para>Below is a glossary of terminology that is relevant to U-Boot</para>
+    <table xml:id="uboot_introduction_term_table">
+      <title>Terminology</title>
+      <tgroup cols="2">
+        <colspec colnum="1" colname="c1"/>
+        <colspec colnum="2" colname="c2"/>
+        <thead>
+          <row>
+            <entry>Settings</entry>
+            <entry>Value</entry>
+          </row>
+        </thead>
+        <tbody>
+	  <row xml:id="uboot_term_target">
+            <entry>
+              <literal>Target</literal>
+            </entry>
+	    <entry>The single-board computer being used, e.g.: ${BOARD}</entry>
+	  </row>
+#ifdef CONFIG_CMD_DHCP
+	  <row xml:id="uboot_term_bootp">
+            <entry>
+              <literal>BOOTP</literal>
+            </entry>
+	    <entry>Bootstrap Protocol. BOOTP can be used to configure the
+		target&apos;s network settings based on information provided
+		by a BOOTP server.</entry>
+	  </row>
+	  <row xml:id="uboot_term_dhcp">
+            <entry>
+              <literal>DHCP</literal>
+            </entry>
+	    <entry>Dynamic Host Configuration Protocol. DHCP can be used to
+	      configure the target&apos;s network settings based on information
+	      provided by a DHCP server. DHCP is very similar to BOOTP. It
+	      is newer and provides some advanced features which BOOTP lacks.
+	      Most DHCP servers also provide support for BOOTP.</entry>
+	  </row>
+#endif
+#ifdef CONFIG_CMD_SNTP
+	  <row xml:id="uboot_term_ntp">
+            <entry>
+              <literal>NTP</literal>
+            </entry>
+	    <entry>Network Time Protocol. NTP is used to synchronize the
+	      target&apos;s date and time with an NTP server</entry>
+	  </row>
+#endif
+	  <row xml:id="uboot_term_os">
+            <entry>
+              <literal>OS</literal>
+            </entry>
+	    <entry>Operating System. e.g.: Linux, VxWorks, QNX, INTEGRITY.</entry>
+	  </row>
+	  <row xml:id="uboot_term_uimage">
+            <entry>
+              <literal>uImage</literal>
+            </entry>
+	    <entry>An image format which contains a payload (OS image,
+	      application image, filesystem, script, etc) as well as metadata
+	      describing the payload. The metadata includes such information
+	      as a checksum, payload name, timestamp, load address, etc.
+	    </entry>
+	  </row>
+#ifdef CONFIG_OF_LIBFDT
+	  <row xml:id="uboot_term_device_tree">
+            <entry>
+              <literal>Device Tree</literal>
+            </entry>
+	    <entry>A device tree is a text file which contains information in
+	      a tree structure based on the Open Firmware specification. The
+	      most common use of a device tree is to specify board-specific
+	      information such as baud rate, CPU speed, number of flashes, etc
+	      which U-Boot can manipulate and pass to an operating system such
+	      as Linux.</entry>
+	  </row>
+	  <row xml:id="uboot_term_dtb">
+            <entry>
+              <literal>DTB</literal>
+            </entry>
+	    <entry>Device Tree Blob. A commonly used acronym for a flattened
+	      device tree blob. DTB can be used interchangeably with FDT.
+	    </entry>
+	  </row>
+	  <row xml:id="uboot_term_fdt">
+            <entry>
+              <literal>FDT</literal>
+            </entry>
+	    <entry>Flattened device tree. A FDT blob is a device tree which
+	      has been converted into a binary form (a &quot;blob&quot;).
+	    </entry>
+	  </row>
+#endif
+	  <row xml:id="uboot_term_primary_flash">
+            <entry>
+              <literal>Primary Flash</literal>
+            </entry>
+	    <entry>The primary NOR flash device on the target. Also referred
+	      to as Flash 1.
+	    </entry>
+	  </row>
+	  <row xml:id="uboot_term_secondary_flash">
+            <entry>
+              <literal>Secondary Flash</literal>
+            </entry>
+	    <entry>The secondary NOR flash device on the target. Also referred
+	      to as Flash 2.
+	    </entry>
+	  </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </sect1>
+</chapter>
diff --git a/doc/manual/manual.tmpl b/doc/manual/manual.tmpl
new file mode 100644
index 0000000..37eb85d
--- /dev/null
+++ b/doc/manual/manual.tmpl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<book xmlns="http://docbook.org/ns/docbook"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      version="5.0"
+      xml:id="uboot_manual">
+
+  <xi:include href="${TOPDIR}/doc/manual/book_info.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/introduction.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/setup.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/booting_linux.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/memory_resources.xml"/>
+#ifdef CONFIG_POST
+  <xi:include href="${TOPDIR}/doc/manual/posts.xml"/>
+#endif
+  <xi:include href="${TOPDIR}/doc/manual/environment_variables.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/commands.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/scripting.xml"/>
+
+</book>
diff --git a/doc/manual/scripting.tmpl b/doc/manual/scripting.tmpl
new file mode 100644
index 0000000..21a7918
--- /dev/null
+++ b/doc/manual/scripting.tmpl
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_scripting_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Scripting</title>
+
+  <sect1 xml:id="uboot_scripting">
+    <title>Scripting in U-Boot</title>
+    <sect2 xml:id="uboot_scripting_dollar_sign">
+      <title>Variable Expansion with $</title>
+      <para>Variable substitution can be done with the $ character. For
+	instance, <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <link linkend="uboot_env_bootargs">
+	<literal>bootargs</literal></link> could also be executed with
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<link linkend="uboot_env_bootargs"><literal>$bootargs</literal></link>.
+	More powerfully, this variable substitution can be used in scripting.
+	See the example in the next section.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_conditionals">
+      <title>Conditionals</title>
+      <para>U-Boot has a scripting language which can be used to customize
+	command execution. It contains if..then..else..fi, for..do..done,
+	while..do..done and until..do..done control flow operations.
+      </para>
+
+      <para>As an example, take the environment variable bootcmd_net.
+	<screen>
+bootcmd_net=run set_bootargs; $download_cmd $osaddr $osfile; if test $? -eq 0;
+then if test -n $fdtaddr; then $download_cmd $fdtaddr $fdtfile;
+if test $? -eq 0; then bootm $osaddr - $fdtaddr; else; echo FDT DOWNLOAD FAILED;
+fi; else; bootm $osaddr; fi; else; echo OS DOWNLOAD FAILED; fi;
+	</screen>
+	To walk through the script, we start with
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<literal>set_bootargs</literal>, which executes the commands stored
+	in <literal>set_bootargs</literal>. Next, we execute the command stored
+	in <literal>download_cmd</literal> which we&apos;ll assume is set to
+	<link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link> and
+	download the file from the path stored in <literal>osfile</literal> to
+	the address stored in <literal>osaddr</literal>. The next step is
+	interesting. We start an <literal>if</literal> conditional, and use the
+	<link linkend="uboot_cmd_test"><literal>test</literal></link> command
+	to check to see if the return value (<literal>$?</literal>) of the
+	<literal>download_cmd</literal> is <literal>0</literal>. If it
+	isn&apos;t, meaning the download failed, we find the matching
+	<literal>then</literal> and see that we echo
+	<literal>DOWNLOAD FAILED</literal>. If it is <literal>0</literal>
+	meaning the download completed successfully, we start a new
+	<literal>if</literal> conditional and test to see if
+	<literal>fdtaddr</literal> is defined. If it is, use
+	<literal>download_cmd</literal> to download the file
+	stored in <literal>fdtfile</literal> to the address stored in
+	<literal>fdtaddr</literal>. Again, we verify that the download
+	completed successfully.  If everything has worked up until now, we
+	complete the script with
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<literal>osaddr - fdtaddr</literal> and boot the image we just
+	downloaded. If <literal>fdtaddr</literal> had been undefined, we would
+	have executed
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<literal>osaddr</literal> instead.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_and_or">
+      <title>&amp;&amp; and ||</title>
+      <para>Another feature of the U-Boot scripting language are the
+	<literal>&amp;&amp;</literal> and <literal>||</literal> functions. The
+	<literal>&amp;&amp;</literal> is an if and only if command. For
+	instance, the command
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<literal>$do_stuff &amp;&amp;</literal>
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<literal>$do_stuff</literal> would run <literal>do_stuff</literal>
+	only if the <link linkend="uboot_cmd_echo">
+	<literal>echo</literal></link> command returned successfully, meaning
+	that <literal>do_stuff</literal> is defined. If
+	<literal>do_stuff</literal> was not defined, the
+	<link linkend="uboot_cmd_run"><literal>run</literal></link> command
+	would not be executed. Similarly, the <literal>||</literal> command will
+	execute the second command only if the first command fails. For
+	instance, if <literal>bank1</literal> stored the location of the OS in
+	flash bank 1 and <literal>bank2</literal> stored the location of the
+	OS in flash bank 2, the following command would try to boot the image
+	in bank 1. If unsuccessful it would boot the image in bank 2.  If that
+	failed, it would attempt to download the file over the network, and if
+	that succeeded, it would boot the image.
+	<screen>
+<literal>bootm $bank1 || bootm $bank2 || tftp $osaddr $osfile &amp;&amp; bootm</literal>
+	</screen>
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_quotes_and_ticks">
+      <title>Quotes and tick marks</title>
+      <para>Quotation marks and tick marks also have a special meaning in
+	U-Boot scripting. Let&apos;s say you wanted to create an environment
+	variable called <literal>do_stuff</literal> and this variable was going
+	to run <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link>
+	<link linkend="uboot_env_bootargs"><literal>bootargs</literal></link>
+	then run
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>.
+	Depending on how you format the command, it&apos;s execution will
+	change. You could save the command as
+	<screen>
+setenv do_stuff &quot;print bootargs; run $bootcmd&quot;
+	</screen>
+	When you <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <literal>do_stuff</literal> you
+	should see something like
+	<screen>
+do_stuff=print bootargs; run bootm f8000000
+	</screen>
+	Notice how the variable specified with the $ was expanded. Now, if
+	you do the same thing, replacing the quotation marks with tick marks,
+	<screen>
+setenv do_stuff &apos;printenv bootargs; run $bootcmd&apos;
+	</screen>
+	you will see different behavior.
+	<screen>
+do_stuff=printenv bootargs; run $bootcmd
+	</screen>
+	Notice how the variables specified with the $ were not expanded. In
+	most cases, this would be the desired behavior as these variables
+	would be expanded when they are executed.  Then, any changes made to
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+	between the time that <literal>do_stuff</literal> was set and it was
+	run would change the functionality of <literal>do_stuff</literal>.
+	For example,
+	<screen>
+setenv printscript print
+setenv do_stuff &quot;$printscript&quot;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing all the environment variables, rather than
+	printing &quot;do nothing&quot;, whereas
+	<screen>
+setenv printscript print
+setenv do_stuff &apos;$printscript&apos;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing &quot;do nothing&quot.
+      </para>
+    </sect2>
+  </sect1>
+</chapter>
+
diff --git a/doc/manual/setup.tmpl b/doc/manual/setup.tmpl
new file mode 100644
index 0000000..2d43a72
--- /dev/null
+++ b/doc/manual/setup.tmpl
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_setup_chapter"
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>U-Boot Setup</title>
+
+  <sect1 xml:id="uboot_setup">
+    <title>Getting Started</title>
+#ifdef CONFIG_BAUDRATE
+    <sect2 xml:id="uboot_setup_serial">
+      <title>Serial</title>
+
+      <para>The U-Boot console can be accessed by a standard PC using terminal
+	software such as HyperTerminal or TeraTerm in Windows or minicom in
+	Linux.
+      </para>
+
+      <orderedlist>
+	<listitem>
+          <para>Plug the serial adapter cable into the ${BOARD}&apos;s serial
+	    connector.
+	  </para>
+	</listitem>
+	<listitem>
+          <para>Connect the other end of the serial adapter cable to the male
+	    DB9 to one of your host PC&apos;s COM ports; a DB9 extension cable
+	    may be required. A USB-to-Serial adapter may also be used if the
+	    host PC being used does not have a male DB9 port available.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Start up your host PC terminal emulator (eg: HyperTerminal,
+	    TeraTerm, minicom) using the following parameters:
+	  </para>
+
+	  <table xml:id="setup_default_serial">
+	    <title>Default serial port settings</title>
+	    <tgroup cols="2">
+              <colspec colnum="1" colname="c1"/>
+              <colspec colnum="2" colname="c2"/>
+              <thead>
+		<row>
+		  <entry>Settings</entry>
+		  <entry>Value</entry>
+		</row>
+              </thead>
+              <tbody>
+		<row>
+		  <entry>
+		    <literal>Baud Rate</literal>
+		  </entry>
+		  <entry>@CONFIG_BAUDRATE</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Data Bits</literal>
+		  </entry>
+		  <entry>8</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Parity</literal>
+		  </entry>
+		  <entry>None</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Stop Bits</literal>
+		  </entry>
+		  <entry>1</entry>
+		</row>
+		<row>
+		  <entry>
+		    <literal>Flow Control</literal>
+		  </entry>
+		  <entry>None</entry>
+		</row>
+              </tbody>
+	    </tgroup>
+	  </table>
+	</listitem>
+      </orderedlist>
+
+      <para>After configuring the serial terminal, you should be able to
+	interact with the target. When the target is powered on, the user should
+	be presented with output similar to the following:
+	<screen>
+U-Boot 1.3.4-xes_r3 (Jan 06 2009 - 11:42:40)
+
+CPU0:  8572E, Version: 1.0, (0x80e80010)
+Core:  E500, Version: 3.0, (0x80210030)
+Clock Configuration:
+       CPU:1500 MHz, CCB:600  MHz,
+       DDR:300  MHz (600 MT/s data rate) (Synchronous), LBC:75   MHz
+L1:    D-cache 32 kB enabled
+       I-cache 32 kB enabled
+Board: X-ES XPedite5370 3U VPX SBC
+       Rev SA, Serial# 26081001, Cfg 90030065-1
+I2C:   ready
+DTT1:  45 C
+DTT2:  35 C
+DRAM:   2 GB (bank interleaving, ECC enabled)
+FLASH: Executed from FLASH1
+FLASH: 256 MB
+L2:    1024 KB enabled
+
+    PCIE1 connected as Root Complex (x4)
+               Scanning PCI bus 01
+        02  01  10b5  8518  0604  00
+        02  02  10b5  8518  0604  00
+        02  03  10b5  8518  0604  00
+        01  00  10b5  8518  0604  00
+    PCIE1 on bus 00 - 05
+
+    PCIE2 connected as End Point (x4)
+    PCIE2 on bus 06 - 06
+In:    serial
+Out:   serial
+Err:   serial
+Net:   eTSEC1, eTSEC2
+Hit any key to stop autoboot:  0
+=>
+	</screen>
+      </para>
+
+      <para>If you don't see console output:</para>
+
+      <orderedlist>
+	<listitem>
+          <para>Verify the serial cable is firmly connected to both the board
+	    and your PC.
+	  </para>
+	</listitem>
+	<listitem>
+          <para>Verify that your serial port has the settings listed above.
+	    If it does, your board may have been changed to a different
+	    baudrate. Try setting your terminal to 9600 baud and reset the
+	    board.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Verify that your jumper settings are logical.</para>
+	</listitem>
+	<listitem>
+	  <para>Check to see if a reset LED is lit and stays lit. If it does,
+	    your board is being held in reset. Make sure the board has adequate
+	    power and that the shelf manager isn't powering it down.
+	  </para>
+	</listitem>
+#ifdef CONFIG_REDUNDANT_MONITORS
+	<listitem>
+	  <para>U-Boot has many valid baudrate options.  Rather than try all
+	    options, try booting from the other bank of flash, and thusly, the
+	    other set of environment variables. Power down the board and move
+	    the boot device select jumper to select the other bank.
+	  </para>
+	</listitem>
+#endif
+	<listitem>
+	  <para>Power on the board and wait for about a minute. If the board is
+	    working but the serial port is not, you should autoboot into an OS
+	    which may start a heartbeat LED. If you see an LED pulsing on and
+	    off after some time, your board is booting but your serial
+	    connection is bad. Try a different cable.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Contact Tech Support</para>
+	</listitem>
+      </orderedlist>
+    </sect2>
+#endif CONFIG_BAUDRATE
+
+#ifdef CONFIG_MPC85xx
+    <xi:include href="${TOPDIR}/doc/manual/85xx_program_flow.xml"/>
+#endif CONFIG MPC85xx
+
+    <sect2 xml:id="uboot_setup_autoboot">
+      <title>Autoboot</title>
+      <para>Your ${BOARD} may be set up to autoboot into an Operating System.
+	In order to stop autoboot and drop down to the U-Boot prompt, press
+	any key when the autoboot count down starts. To disable autobooting, use
+	the <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	command to set the <link linkend="uboot_env_bootdelay">
+	<literal>bootdelay</literal></link> environment variable to
+	<literal>-1</literal>. You must use the
+	<link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+	command to save this change.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_setup_shell">
+      <title>U-Boot Shell</title>
+      <para>U-Boot is designed to set up your ${BOARD} and turn execution over
+	to an OS. In order to transfer control, U-Boot provides many commands
+	to help customize the hardware.
+      </para>
+      <para>One way to customize your version of U-Boot is through the use of
+	<link linkend="uboot_env_vars">environment variables</link>. Variables
+	can be modified	with the
+	<link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+	command. These variables will return to defaults after a reset unless a
+	<link linkend="uboot_cmd_saveenv"><literal>saveenv</literal></link>
+	command is executed. You can create any number of environment variables
+	to store instruction sequences. These variables can then be executed
+	with the <link linkend="uboot_cmd_run"><literal>run</literal></link>
+	command. By modifying the
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link> and
+	<link linkend="uboot_env_preboot"><literal>preboot</literal></link>
+	environment varaibles, you can automate the use of your customized
+	variables. In order to save a string of commands to your environment
+	variable, you must insert a semicolon between every command. You will
+	either need to escape your semicolon (\;) or put the entire variable in
+	quotation marks (&quot;&quot;). See the <link linkend="uboot_scripting">
+	<literal>Scripting in U-Boot</literal></link> section for more
+	information on quotation marks.
+      </para>
+      <para>To see a list of the commands available to you, type
+	<link linkend="uboot_cmd_help"><literal>help</literal></link> at the
+	command prompt.
+      </para>
+      <para>After entering a command, you can re-execute it simply by pressing
+	the ENTER or RETURN key. Some commands, such as memory display
+	(<link linkend="uboot_cmd_md"><literal>md</literal></link>),
+	auto-increment to the next address on each subsequent auto-repeat.
+      </para>
+    </sect2>
+
+
+    <sect2 xml:id="uboot_setup_network">
+      <title>Network</title>
+      <para>If network operations will be performed on the target, connect any
+	applicable Ethernet interfaces. The ${BOARD} supports IP, TCP, ARP,
+	DHCP, TFTP, UDP, and ICMP transactions. Please also reference the
+	<link linkend="uboot_env_sect_networking">
+	<literal>Network Environment Variables</literal></link> and
+	<link linkend="uboot_cmd_sect_networking">
+	<literal>Network Commands</literal></link> for information
+	on using the ${BOARD}&apos;s Ethernet ports.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_setup_firmware_update">
+      <title>Firmware Update Procedure</title>
+      <para>In the even that you receive a firmware update or one of your
+	U-Boot images becomes corrupt, use the following procedure.
+      </para>
+      <orderedlist>
+	<listitem>
+	  <para>Place a good U-Boot image on a TFTP server.</para>
+	</listitem>
+	<listitem>
+	  <para>Set your <link linkend="uboot_env_sect_networking">
+	    <literal>network environment variables</literal></link> to reflect
+	    the location of your TFTP server.
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Download the new U-Boot image using the
+	    <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	    command.
+	    <screen>
+tftp $loadaddr &lt;path to U-Boot image&gt;
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Erase the old U-Boot image, beginning at ${TEXT_BASE} using
+	    the <link linkend="uboot_cmd_erase"><literal>erase</literal></link>
+	    command.
+	    <screen>
+erase ${TEXT_BASE} +800000
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Copy the downloaded image to flash using the
+	    <link linkend="uboot_cmd_cp"><literal>cp</literal></link> command.
+	    <screen>
+cp.b $loadaddr ${TEXT_BASE} $filesize
+	    </screen>
+	  </para>
+	</listitem>
+	<listitem>
+	  <para>Reset the board to load the new image using the
+	    <link linkend="uboot_cmd_reset"><literal>reset</literal></link>
+	    command.
+	  </para>
+	</listitem>
+      </orderedlist>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/doc/manual/uboot-doc b/doc/manual/uboot-doc
new file mode 100644
index 0000000..c2939bc
--- /dev/null
+++ b/doc/manual/uboot-doc
@@ -0,0 +1,866 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+## Copyright (C) 2009  Extreme Engineering Solutions
+##
+## Author: John Schmoller <jschmoller@xes-inc.com>
+##
+## This software falls under the GNU General Public License.
+## Please read the COPYING file for more information
+##
+## This file is loosly based on kernel-doc originally created by
+## Michael Zucchi from the Linux distribution.
+
+#
+# This will read a 'c' file and scan for embedded comments in the
+# style of gnome comments (+minor extensions - see below).
+#
+
+# usage:
+# uboot-doc inputfile ...
+#
+#  inputfile ... - a list of files which will be searched for comment
+#                  blocks to convert to XML.
+#
+#  All errors go to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+#                         (...)* signifies 0 or more structure elements
+# /**
+#  * @cmd: cmd_name
+# (* @sect: sect_name)?
+# (* a blank line)?
+# (* @param([(o)?(r)?])?: param_name - description)*
+#  * @desc: Description of function
+#  (*        Function description extends through comment end.)*
+#  (*)?*/
+#
+# The @sect is optional, and specifies which command sub-section
+# to place the common. Any string is a valid @sect descriptor (e.g. "Memory",
+# "Networking", "Environment Modifying". If not
+# specified, the command will be placed in the "Other" section.
+#
+# There are two optional suffixes to the @param specifier.  o states whether
+# the parameter is optional, r states whether the parameter is replaceable.
+# Non-replaceable parameters are entered litterally, like i2c *probe*.
+# Replaceable parameters are substituted before the command is valid, like
+# md *addr* to md *100000*. Valid options are [or], [ro], [o], [r], [], and
+# nothing. [] means not optional and non-replaceable.  Nothing defaults to
+# not optional and replaceable.
+#
+# The @desc and @entry fields can have links to other points in the document.
+# To specify a link to a command, use @ccommand_name, and for environment
+# variables, @eenv_name.  For example, @cprintenv or @ebootdelay.
+#
+# So .. the trivial example would be:
+#
+# /**
+#  * @cmd: my_command
+#  */
+#
+#  Or more compicated:
+# /**
+#  * @cmd: my_function
+#  * @sect: Memory
+#  * @param: my_arg - its mine
+#  * @desc: Does my stuff explained.
+#  */
+# etc.
+#
+# Besides functions you can also write documentation for environment varaibles,
+# POSTs, and memory maps. Instead of @cmd name you must write the name
+# of the declaration; @env, @post, or @memmap must always precede
+# the name. Nesting of declarations is not supported.
+# e.g.
+# /**
+#  * @env: env_name
+#  (* @sect: sect_name)?
+#  * @desc: Environment variable description.
+#  (* Additional description.)*
+#  (*)?*/
+#
+# /**
+#  * @post: post_name
+#  * @desc: POST description.
+#  (* Additional description.)*
+#  (*)?*/
+#
+# /**
+#  * @memmap: Memory Map Name
+#  (* @entry: start_addr: end_addr: Entry description)*
+#  (*)?*/
+#
+# All @desc can be multiline.
+#
+
+my $manual_dir = "doc/manual";
+
+sub usage {
+    print "Usage: $0 outputfile\n";
+    exit 1;
+}
+
+# read arguments
+if ( $#ARGV == -1 ) {
+    usage();
+}
+
+# states
+# 0 - normal code
+# 1 - looking for command, env var, post, or memmap
+# 2 - parsing params and the first line of desc
+# 3 - finish parsing desc's, parse memmap entries
+my $state;
+
+# Regular expressions for matching section types
+my $doc_special    = '@';
+my $doc_system_env = '\$';
+my $doc_cmd_link   = $doc_special . 'c';
+my $doc_env_link   = $doc_special . 'e';
+my $doc_start = '^\s*/\*\*\s*$';    # Allow whitespace at end of comment start.
+my $doc_end   = '\*/';
+my $doc_com   = '\s*\*\s*';
+my $doc_sect         = $doc_special . 'sect:';
+my $doc_cmd          = $doc_special . 'cmd:\s*';
+my $doc_param        = $doc_special . 'param\s*\[?[or]*\]?:\s*';
+my $doc_env          = $doc_special . 'env:\s*';
+my $doc_desc         = $doc_special . 'desc:\s*';
+my $doc_post         = $doc_special . 'post:\s*';
+my $doc_memmap       = $doc_special . 'memmap:\s*';
+my $doc_memmap_entry = $doc_special . 'entry:\s*';
+
+# Hashes and arrays for storing output to files
+my @valuetype;
+my @valuename;
+my @valuedesc;
+my %cmdhash;
+my %envhash;
+my %posthash;
+my %definehash;
+my %memmaphash;
+my @definecontext = (1);
+
+reset_state();
+
+# Open up commands.xml to write and add the XML header
+if ( !open( CMDOUT, ">$manual_dir/commands.xml" ) ) {
+    print STDERR "Error: Cannot open file commamds.xml\n";
+    return;
+}
+print CMDOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print CMDOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print CMDOUT "<chapter version=\"5.0\" xml:id=\"uboot_commands\"\n";
+print CMDOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print CMDOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print CMDOUT " <title>U-Boot Commands</title>\n\n";
+
+# Open up environment_variables.xml to write and add the XML header
+if ( !open( ENVOUT, ">$manual_dir/environment_variables.xml" ) ) {
+    print STDERR "Error: Cannot open file environment_variables.xml\n";
+    return;
+}
+print ENVOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print ENVOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print ENVOUT "<chapter version=\"5.0\" xml:id=\"uboot_env_vars\"\n";
+print ENVOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print ENVOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print ENVOUT " <title>U-Boot Environment Variables</title>\n\n";
+
+# Open up posts.xml to write and add XML header
+if ( !open( POSTOUT, ">$manual_dir/posts.xml" ) ) {
+    print STDERR "Error: Cannot open file posts.xml\n";
+    return;
+}
+print POSTOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print POSTOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print POSTOUT "<chapter version=\"5.0\" xml:id=\"uboot_posts\"\n";
+print POSTOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print POSTOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print POSTOUT " <title>U-Boot POST Descriptions</title>\n\n";
+
+# Open up memory_resources.xml to write and add XML header
+if ( !open( MEMOUT, ">$manual_dir/memory_resources.xml" ) ) {
+    print STDERR "Error: Cannot open file memory_resources.xml\n";
+    return;
+}
+print MEMOUT "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print MEMOUT "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print MEMOUT "<chapter version=\"5.0\" xml:id=\"uboot_mem_resources\"\n";
+print MEMOUT " xmlns=\"http://docbook.org/ns/docbook\"\n";
+print MEMOUT " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n\n";
+print MEMOUT " <title>U-Boot Memory Resources</title>\n\n";
+
+# Parse autoconf.mk for #defines
+if ( open( AUTOCONF, "<include/autoconf.mk" ) ) {
+    while (<AUTOCONF>) {
+        my $key   = $_;
+        my $value = $_;
+        $key   =~ s/=.*\s*$//;
+        $value =~ s/^.*?=//;
+        $value =~ s/\s*$//;
+        $definehash{$key} = $value;
+    }
+} else {
+    print STDERR "Error: Cannot open file autoconf.mk\n";
+}
+
+# Get date from timestamp_autogenerated.h
+my $DATE = "Jan 1, 2000";
+if ( open( TIMESTAMP, "<include/timestamp_autogenerated.h" ) ) {
+    while (<TIMESTAMP>) {
+        if (/U_BOOT_DATE\s*\"([\w\s]*)\"\s*$/) {
+            $DATE = $1;
+        }
+    }
+}
+
+# Get version from version_autogenerated.h
+my $VERSION = "U-Boot $DATE";
+if ( open( VERSION, "<include/version_autogenerated.h" ) ) {
+    while (<VERSION>) {
+        if (/U_BOOT_VERSION\s*\"U-Boot\s*(.*?)\"\s*$/) {
+            $VERSION = $1;
+        }
+    }
+}
+
+sub process_file($);
+
+foreach (@ARGV) {
+    chomp;
+    process_file($_);
+}
+
+# Finish off the commands.xml file
+foreach my $HoHkey ( sort ( keys(%cmdhash) ) ) {
+    my $tag_key = lc($HoHkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+    print CMDOUT " <sect1 xml:id=\"uboot_cmd_sect_$tag_key\">\n";
+    print CMDOUT "  <title>$HoHkey Commands</title>\n";
+    foreach my $key ( sort ( keys %{ $cmdhash{$HoHkey} } ) ) {
+        print CMDOUT $cmdhash{$HoHkey}{$key};
+    }
+    print CMDOUT " </sect1>\n";
+}
+print CMDOUT "</chapter>";
+
+# Finish off the environment_variables.xml file
+foreach my $HoHkey ( sort ( keys(%envhash) ) ) {
+    my $tag_key = lc($HoHkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+    print ENVOUT " <sect1 xml:id=\"uboot_env_sect_$tag_key\">\n";
+    print ENVOUT "  <title>$HoHkey Environment Variables</title>\n";
+    print ENVOUT "  <table xml:id=\"uboot_env_sect_" . $tag_key . "_table\">\n";
+    print ENVOUT "   <title>$HoHkey Environment Variables</title>\n";
+    print ENVOUT "   <tgroup cols=\"2\">\n";
+    print ENVOUT "    <colspec colname=\"c1\" colnum=\"1\"/>\n";
+    print ENVOUT "    <colspec colname=\"c2\" colnum=\"2\"/>\n";
+    print ENVOUT "    <thead>\n";
+    print ENVOUT "     <row>\n";
+    print ENVOUT "      <entry>Variable</entry>\n";
+    print ENVOUT "      <entry>Description</entry>\n";
+    print ENVOUT "     </row>\n";
+    print ENVOUT "    </thead>\n";
+    print ENVOUT "    <tbody>\n";
+
+    foreach my $key ( sort ( keys %{ $envhash{$HoHkey} } ) ) {
+        print ENVOUT $envhash{$HoHkey}{$key};
+    }
+    print ENVOUT "    </tbody>\n";
+    print ENVOUT "   </tgroup>\n";
+    print ENVOUT "  </table>\n";
+    print ENVOUT " </sect1>\n";
+}
+print ENVOUT "</chapter>";
+
+# Finish off the posts.xml file
+foreach my $key ( sort ( keys(%posthash) ) ) {
+    print POSTOUT $posthash{$key};
+}
+print POSTOUT "</chapter>";
+
+# Finish off the memory_resources.xml file
+# Set System Memory Map first, all others alphabetically
+foreach my $key ( sort ( keys(%memmaphash) ) ) {
+    my $tag_key = lc($key);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    print MEMOUT " <sect1 xml:id=\"uboot_memmap_$tag_key\">\n";
+    print MEMOUT "  <title>$key</title>\n";
+    print MEMOUT "  <table xml:id=\"uboot_memmap_" . $tag_key . "_table\">\n";
+    print MEMOUT "   <title>$key</title>\n";
+    print MEMOUT "   <tgroup cols=\"3\">\n";
+    print MEMOUT "    <colspec colname=\"c1\" colnum=\"1\"/>\n";
+    print MEMOUT "    <colspec colname=\"c2\" colnum=\"2\"/>\n";
+    print MEMOUT "    <colspec colname=\"c3\" colnum=\"3\"/>\n";
+    print MEMOUT "    <thead>\n";
+    print MEMOUT "     <row>\n";
+    print MEMOUT "      <entry>Start</entry>\n";
+    print MEMOUT "      <entry>End</entry>\n";
+    print MEMOUT "      <entry>Description</entry>\n";
+    print MEMOUT "     </row>\n";
+    print MEMOUT "    </thead>\n";
+    print MEMOUT "    <tbody>\n";
+    print MEMOUT $memmaphash{$key};
+    print MEMOUT "    </tbody>\n";
+    print MEMOUT "   </tgroup>\n";
+    print MEMOUT "  </table>\n";
+    print MEMOUT " </sect1>\n";
+}
+print MEMOUT "</chapter>";
+
+# Start processing the template files. Look first in $manual_dir/
+# then in board/$BOARDDIR/manual. Overwrite any duplicate
+# files found in $manual_dir/ with the ones found in board/.
+my %files;
+opendir( MANDIR, $ENV{'TOPDIR'} . "/$manual_dir" ) or die "$!";
+my @manfiles = grep { /.*\.tmpl/ } readdir MANDIR;
+close MANDIR;
+foreach my $file (@manfiles) {
+    $files{$file} = $ENV{'TOPDIR'} . "/$manual_dir/$file";
+}
+if ( opendir( BOARDDIR, $ENV{'TOPDIR'} . "/board/" .
+	      $ENV{'BOARDDIR'} . "/manual" ) )
+{
+    my @boardfiles = grep { /.*\.tmpl/ } readdir BOARDDIR;
+    close BOARDDIR;
+    foreach my $file (@boardfiles) {
+        $files{$file} =
+          $ENV{'TOPDIR'} . "/board/" . $ENV{'BOARDDIR'} . "/manual/$file";
+    }
+}
+
+foreach my $file ( keys(%files) ) {
+    @definecontext = ();
+    push( @definecontext, 1 );
+    my $define;
+    my $outfile = $file;
+    $outfile =~ s/\.tmpl//;
+    $outfile .= ".xml";
+    open( FH, "$files{$file}" ) or die "Cannot open file $files{$file}: $!";
+    open( OUT, ">$manual_dir/$outfile" ) or die "$!";
+
+    while (<FH>) {
+
+        # #else processing
+        if (/^#else/) {
+
+            if ( $definecontext[$#definecontext] ) {
+                $definecontext[$#definecontext] = 0;
+            } else {
+                $definecontext[$#definecontext] = 1;
+            }
+
+            # #endif processing
+        } elsif (/^#endif/) {
+            pop(@definecontext);
+
+            # #ifdef processing
+        } elsif (/^#ifdef\s*(\w*)\s*$/) {
+
+            if ( !$definecontext[$#definecontext] ) {
+                push( @definecontext, 0 );
+            } elsif ( exists( $definehash{$1} ) ) {
+                push( @definecontext, 1 );
+            } else {
+                push( @definecontext, 0 );
+            }
+
+            # ignore everything else until context changes
+        } elsif ( !$definecontext[$#definecontext] ) {
+            next;
+
+            # System environment and #define processing
+        } elsif (/[$doc_special$doc_system_env]/) {
+            my @words = split(/\s+/);
+            foreach my $word (@words) {
+                while ( $word =~ /^.*?$doc_special(\w*).*?$/ ) {
+                    $define = $1;
+
+                    if ( exists( $definehash{$define} ) ) {
+                        s/$doc_special\w*/$definehash{$define}/;
+                    } else {
+                        s/$doc_special/ at /;
+                    }
+                    $word =~ s/$doc_special/ at /;
+                }
+                while ( $word =~ /$doc_system_env\{(\w*)\}+/ ) {
+                    $define = $1;
+
+                    # Check for the special $VERSION and $DATE defines
+                    if ( $define eq "VERSION" ) {
+                        s/$doc_system_env\{\w*\}/$VERSION/;
+                    } elsif ( $define eq "DATE" ) {
+                        s/$doc_system_env\{\w*\}/$DATE/;
+                    } elsif ( exists $ENV{"$define"} ) {
+                        s/$doc_system_env\{\w*\}/$ENV{"$define"}/;
+                    } else {
+                        s/$doc_system_env\{(\w*)\}/\$$1/;
+                    }
+                    $word =~ s/$doc_system_env/ /;
+                }
+            }
+            print OUT $_;
+        } elsif ( $definecontext[$#definecontext] ) {
+            print OUT $_;
+        }
+    }
+    close(FH);
+}
+
+# Output the DOCBOOK_XSL_DIR variable so it's readable by the stylesheets
+if ( !open( PARAMS, ">$manual_dir/params.xsl" ) ) {
+    print STDERR "Error: Cannot open file params.xsl\n";
+    return;
+}
+print PARAMS "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n";
+print PARAMS "<!-- THIS FILE IS AUTOMATICALLY GENERATED -->\n\n";
+print PARAMS "<xsl:stylesheet xmlns:xsl=";
+print PARAMS "\"http://www.w3.org/1999/XSL/Transform\"\n";
+print PARAMS "                xmlns:d=\"http://docbook.org/ns/docbook\"\n";
+print PARAMS "                xmlns:fo=\"http://www.w3.org/1999/XSL/Format\"\n";
+print PARAMS "                exclude-result-prefixes=\"d\"\n";
+print PARAMS "                version='1.0'>\n\n";
+print PARAMS "  <xsl:import href=\"" . $ENV{"DOCBOOK_XSL_DIR"} .
+    "/fo/docbook.xsl\"/>\n\n";
+print PARAMS "</xsl:stylesheet>\n";
+close(PARAMS);
+
+# Function to parse descriptive text to find possible XML links
+sub output_link($) {
+    my @words;
+    my $retstr = "";
+    $_ = $_[0];
+
+    @words = split(/\s+/);
+    foreach (@words) {
+        if (/^$doc_env_link(\w*)/) {    #link to environment element in doc
+            $retstr .= "<link linkend=\"uboot_env_$1\">";
+            $retstr .= "<literal>$1</literal></link> ";
+        } elsif (/^$doc_cmd_link(\w*)/) {    #link to command element in doc
+            $retstr .= "<link linkend=\"uboot_cmd_$1\">";
+            $retstr .= "<literal>$1</literal></link> ";
+        } else {
+            $retstr .= "$_ ";
+        }
+    }
+    return $retstr;
+}
+
+# Writes XML for a command to the command hash
+sub output_command {
+    my $i                  = 0;
+    my $conditional_prints = 1;
+    my $hashvalue          = "";
+    my $hashkey;
+    my $tag_key;
+    my $hashofhasheskey;
+
+    # Make sure we're not re-processing a command
+    if ( exists( $cmdhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+        return;
+    }
+
+    # Cycle through all the elements to the command
+    foreach (@valuetype) {
+
+        # The @cmd and @sect lines
+        if (/$doc_cmd/) {
+            $hashkey = $valuename[$i];
+            $tag_key = lc( $valuename[$i] );
+            while ( $tag_key =~ / / ) {
+                $tag_key =~ s/ /_/;
+            }
+            $hashvalue .= "  <sect2 xml:id=\"uboot_cmd_$tag_key\">\n";
+            $hashvalue .= "   <title>$valuename[$i]</title>\n";
+            $hashvalue .= "   <cmdsynopsis>\n";
+            $hashvalue .= "    <command>$valuename[$i]</command>\n";
+            $hashofhasheskey = $valuedesc[$i];
+
+            if ( $hashofhasheskey eq '0' ) {
+                $hashofhasheskey = "Other";
+            }
+
+            if ( !exists( $cmdhash{$hashofhasheskey} ) ) {
+                $cmdhash{$hashofhasheskey} = {};
+            }
+        } elsif (/$doc_param/) {    # The @param line
+            if (/\[[or]*\]/) {      #arg options specified
+                if (/\[\w?o\w?\]/) {    #arg optional
+                    $hashvalue .= "    <arg choice=\"opt\">\n";
+                } else {                #arg required
+                    $hashvalue .= "    <arg choice=\"req\">\n";
+                }
+
+                if (/\[\w?r\w?\]/) {    #arg replaceable
+                    $hashvalue .= "     <replaceable>$valuename[$i]";
+                    $hashvalue .= "</replaceable>\n";
+                } else {                #arg literal
+                    $hashvalue .= "     $valuename[$i]\n";
+                }
+                $hashvalue .= "    </arg>\n";
+            } else {    #assume [r]
+                $hashvalue .= "    <arg choice=\"req\">\n";
+                $hashvalue .= "     <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+                $hashvalue .= "    </arg>\n";
+            }
+        } elsif (/$doc_desc/) {    # The @desc line
+            my @words;
+            if ($conditional_prints) {    #finish up the synopsis
+                $hashvalue .= "   </cmdsynopsis>\n";
+                $hashvalue .= "   <para>";
+                $conditional_prints = 0;
+            } else {
+                $hashvalue .= "  ";
+            }
+
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "   <para>";
+                }
+                $i++;
+                next;
+            }
+
+            $hashvalue .= output_link( $valuedesc[$i] );
+
+            if ( ($i) == $#valuetype ) {
+                $hashvalue .= "</para>";
+            }
+
+            $hashvalue .= "\n";
+        }
+        $i++;
+    }
+
+    # Make a second run through the command to get the XML formatted correctly
+    $conditional_prints = 1;
+    $i                  = 0;
+    my $param_present = 0;
+    foreach (@valuetype) {
+        if (/$doc_param/) {
+            if ($conditional_prints) {
+                $hashvalue .= "   <variablelist>\n";
+                $hashvalue .= "    <title>Arguments</title>\n";
+                $conditional_prints = 0;
+                $param_present      = 1;
+            }
+
+            $hashvalue .= "    <varlistentry>\n";
+            $hashvalue .= "     <term>\n";
+
+            if (/\[\w?r\w?\]/) {    #replaceable arg option specified
+                $hashvalue .= "      <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+            } elsif (/\[\w*\]/) {    #replaceable arg not specified
+                $hashvalue .= "      $valuename[$i]\n";
+            } else {                 #no args specified, default to replaceable
+                $hashvalue .= "      <replaceable>$valuename[$i]";
+                $hashvalue .= "</replaceable>\n";
+            }
+
+            $hashvalue .= "     </term>\n";
+            $hashvalue .= "     <listitem>\n";
+            $hashvalue .= "      <para>$valuedesc[$i]</para>\n";
+            $hashvalue .= "     </listitem>\n";
+            $hashvalue .= "    </varlistentry>\n";
+        }
+
+        if ( $i == $#valuetype ) {
+            if ($param_present) {
+                $hashvalue .= "   </variablelist>\n";
+            }
+            $hashvalue .= "  </sect2>\n";
+
+        }
+        $i++;
+    }
+
+    $cmdhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for an environment variable to the env hash
+sub output_env {
+    my @words;
+    my $conditional_prints = 1;
+    my $i                  = 0;
+    my $hashvalue          = "";
+    my $hashkey;
+    my $hashofhasheskey;
+
+    # Make sure we're not re-processing an environment variable
+    if ( exists( $envhash{ $valuedesc[0] }{ $valuename[0] } ) ) {
+        return;
+    }
+
+    $hashkey = $valuename[0];
+    $hashvalue .= "     <row xml:id=\"uboot_env_$valuename[0]\">\n";
+    $hashvalue .= "      <entry>\n";
+    $hashvalue .= "       <literal>$valuename[0]</literal>\n";
+    $hashvalue .= "      </entry>\n";
+    $hashvalue .= "      <entry>\n";
+    $hashvalue .= "       <para>";
+    $hashofhasheskey = $valuedesc[0];
+
+    if ( $hashofhasheskey eq '0' ) {
+        $hashofhasheskey = "Other";
+    }
+
+    if ( !exists( $envhash{$hashofhasheskey} ) ) {
+        $envhash{$hashofhasheskey} = {};
+    }
+
+    # For each description element, add to the env var description
+    foreach (@valuetype) {
+        if (/$doc_desc/) {
+            if ( $i != 0 ) {
+                $hashvalue .= "       ";
+            }
+
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "       <para>";
+                }
+            } else {
+
+                $hashvalue .= output_link( $valuedesc[$i] );
+
+                if ( ($i) == $#valuetype ) {
+                    $hashvalue .= "</para>";
+                }
+
+                $hashvalue .= "\n";
+            }
+        }
+        $i++;
+    }
+
+    $hashvalue .= "      </entry>\n";
+    $hashvalue .= "     </row>\n";
+
+    $envhash{$hashofhasheskey}{$hashkey} = $hashvalue;
+}
+
+sub output_post {
+    my $hashvalue = "";
+    my $i         = 0;
+
+    if ( exists( $posthash{ $valuename[0] } ) ) {
+        return;
+    }
+
+    my $hashkey = $valuename[0];
+    my $tag_key = $hashkey;
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    foreach (@valuetype) {
+        if (/$doc_post/) {
+            $hashvalue .= " <sect1 xml:id=\"uboot_post_$tag_key\">\n";
+            $hashvalue .= "  <title>$hashkey</title>\n";
+            $hashvalue .= "  <para>\n";
+        } elsif (/$doc_desc/) {
+            if ( $valuedesc[$i] eq "\n" ) {
+                $hashvalue .= "</para>\n";
+                if ( $i != $#valuetype ) {
+                    $hashvalue .= "  <para>";
+                }
+	    } else {
+                $hashvalue .= "   ";
+                $hashvalue .= output_link( $valuedesc[$i] );
+	    }
+        }
+        $i++;
+    }
+
+    $hashvalue .= "  </para>\n";
+    $hashvalue .= " </sect1>\n";
+
+    $posthash{$hashkey} = $hashvalue;
+}
+
+# Function writes XML for a memory map to the memmap hash
+sub output_memmap {
+    my @words;
+    my $conditional_prints = 1;
+    my $i                  = 0;
+    my $hashvalue          = "";
+    my $hashkey;
+
+    # Make sure we're not re-processing a memory map
+    if ( exists( $memmaphash{ $valuedesc[0] } ) ) {
+        return;
+    }
+
+    # Make a valid XML tag name out of memmap description
+    $hashkey = $valuedesc[0];
+    my $tag_key = lc($hashkey);
+    while ( $tag_key =~ / / ) {
+        $tag_key =~ s/ /_/;
+    }
+
+    # Cycle through all the memmap entries
+    foreach (@valuetype) {
+        my @words;
+        if (/$doc_memmap_entry/) {
+
+            $hashvalue .= "     <row>\n";
+
+            # Split up start and end and drop them in the table
+            @words = split( /\s*:\s*/, $valuedesc[$i] );
+            foreach my $word (@words) {
+                $hashvalue .= "      <entry>\n";
+                $hashvalue .= "       <literal>$word</literal>\n";
+                $hashvalue .= "      </entry>\n";
+            }
+
+            $hashvalue .= "      <entry>\n";
+            $hashvalue .= "       <para>";
+            $hashvalue .= output_link( $valuename[$i] );
+            $hashvalue .= "</para>\n";
+            $hashvalue .= "      </entry>\n";
+            $hashvalue .= "     </row>\n";
+
+        }
+        $i++;
+    }
+
+    $memmaphash{$hashkey} = $hashvalue;
+}
+
+# Call the appropriate output function
+sub output_section {
+    if ( $valuetype[0] =~ /$doc_cmd/io ) {
+        output_command();
+    } elsif ( $valuetype[0] =~ /$doc_env/io ) {
+        output_env();
+    } elsif ( $valuetype[0] =~ /$doc_post/io ) {
+        output_post();
+    } elsif ( $valuetype[0] =~ /$doc_memmap/io ) {
+        output_memmap();
+    }
+}
+
+# After each comment block, reset all our variables
+sub reset_state {
+
+    @valuetype = ();
+    @valuename = ();
+    @valuedesc = ();
+
+    $state = 0;
+}
+
+# Main processing loop
+sub process_file($) {
+    my $file;
+    my $identifier;
+    my $func;
+    my $descr;
+    my @links;
+
+    $file = "@_";
+
+    if ( !open( IN, "<$file" ) ) {
+        print STDERR "Error: Cannot open file $file\n";
+        return;
+    }
+
+    while (<IN>) {
+        if ( $state == 0 ) {    # Normal code
+            if (/$doc_start/io) {
+                $state = 1;
+            }
+        } elsif ( $state == 1 )
+        {                       # We got the start of a potential comment block
+            if (/^$doc_com$/io) {    # Got an empty line
+                next;
+
+            } elsif (/$doc_cmd\s*([\w\s-]*\w)\s*$/io) {    # Found a function
+                push @valuetype, $doc_cmd;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_env\s*([\w\s-]*\w)\s*$/io) {    # Found an env var
+                push @valuetype, $doc_env;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_post\s*([\w\s-]*\w)\s*$/io) { # Found POST descriptor
+                push @valuetype, $doc_post;
+                push @valuename, $1;
+                push @valuedesc, '0';
+
+                $state = 2;
+            } elsif (/$doc_memmap\s*([\w\s-]*\w)\s*$/io) {  # Found a memory map
+                push @valuetype, $doc_memmap;
+                push @valuename, '0';
+                push @valuedesc, $1;
+
+                $state = 3;
+            } elsif (/$doc_end/io) {    # Musta been a normal comment
+                $state = 0;
+            }
+        } elsif ( $state == 2 ) {    # Found a valid comment declaration
+            if (/^$doc_com$/io) {    # Got an empty line
+                next;
+            } elsif (/($doc_param)\s*([^-]*[^\s])\s*-\s*(.*)\s*$/io) {   # Param
+                push @valuetype, $1;
+                push @valuename, $2;
+                push @valuedesc, $3;
+            } elsif (/$doc_desc(.*\s*$)/io) {    # Got a description
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, $1;
+
+                $state = 3;
+            } elsif (/$doc_sect\s*(.*[^\s])\s*$/io) {   # Got a sub-section decl
+                $valuedesc[$#valuedesc] = $1;
+            } else {    # Something undefined happened
+                print STDERR "Warning(${file}:$.): bad line: $_";
+                reset_state();
+            }
+        } elsif ( $state == 3 ) {    # Process descriptions and memmap entries
+            if (/$doc_end/) {        # End of comment block
+                                     # Write comment to proper hash
+                output_section();
+
+                # Reset hash variables and state
+                reset_state();
+            } elsif (/^$doc_com$/) {    # Empty line, push a newline
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, "\n";
+
+                # Got memmap entry
+            } elsif (/$doc_memmap_entry\s*(\w*\s*:\s*\w*)\s*:\s*(.*)$/io) {
+                push @valuetype, $doc_memmap_entry;
+                push @valuename, $2;
+                push @valuedesc, $1;
+            } else {                    # No tag, keep pushing description
+                $descr = $_;
+                $descr =~ s/^$doc_com//io;
+
+                push @valuetype, $doc_desc;
+                push @valuename, $doc_desc;
+                push @valuedesc, $descr;
+            }
+        }
+    }
+}
+
diff --git a/doc/manual/uboot_manual.xsl b/doc/manual/uboot_manual.xsl
new file mode 100644
index 0000000..bc40b46
--- /dev/null
+++ b/doc/manual/uboot_manual.xsl
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- **********************************************************************
+       U-Boot manual FO stylesheet
+
+       This stylesheet (DocBook customization layer) transforms U-Boot
+       manual XML documents into FO.
+
+       Since the DocBook stylesheets are currently in XSLT 1.0, this
+       stylesheet has to be XSLT 1.0.
+     ********************************************************************** -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:d="http://docbook.org/ns/docbook"
+                xmlns:fo="http://www.w3.org/1999/XSL/Format"
+                exclude-result-prefixes="d"
+                version='1.0'>
+
+<!-- ======================================================================
+       Base DocBook stylesheet
+     ====================================================================== -->
+
+  <xsl:include href="params.xsl"/>
+
+<!-- ======================================================================
+       General customizations
+     ====================================================================== -->
+
+  <!-- General document settings. -->
+  <xsl:param name="draft.mode" select="'no'"/>
+  <xsl:param name="paper.type" select="'USletter'"/>
+  <xsl:param name="body.font.family" select="'sans-serif'"/>
+  <xsl:param name="body.font.master" select="10"/>
+
+<!-- ======================================================================
+       Section customizations
+     ====================================================================== -->
+
+  <!-- Add section numbering. -->
+  <xsl:param name="section.autolabel" select="1"/>
+  <xsl:param name="section.label.includes.component.label" select="1"/>
+
+  <!-- Section title properties. Only the 'space-before.*' attributes were
+       customized from their default values here. -->
+  <xsl:attribute-set name="section.title.properties">
+    <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family"/></xsl:attribute>
+    <xsl:attribute name="font-weight">bold</xsl:attribute>
+    <!-- font size is calculated dynamically by section.heading template -->
+    <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+    <xsl:attribute name="space-before.minimum">2.8em</xsl:attribute>
+    <xsl:attribute name="space-before.optimum">3em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">3.2em</xsl:attribute>
+    <xsl:attribute name="text-align">left</xsl:attribute>
+    <xsl:attribute name="start-indent"><xsl:value-of select="$title.margin.left"/></xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       Front matter customizations
+     ====================================================================== -->
+
+  <!-- Title page template. Customized from fo/titlepage.templates.xsl.  -->
+  <xsl:template name="book.titlepage.recto">
+    <fo:block font-family="Book Antiqua" text-align="left" hyphenate="false">
+      <fo:block font-size="45pt">
+	<!-- EDIT: CUSTOMIZE PRODUCT NAME HERE -->
+	<fo:inline>
+	  <xsl:value-of select="ancestor-or-self::book/info/titleabbrev"/>
+	</fo:inline>
+	<!-- CUSTOMIZE PRODUCT NAME HERE -->
+      </fo:block>
+      <fo:block font-size="20pt" font-weight="bold"
+		space-before="2in">U-Boot User's Manual</fo:block>
+      <fo:block-container absolute-position="absolute" height="100%"
+			  display-align="after" break-after="page"
+			  left="10pt" bottom="10pt">
+        <fo:table table-layout="fixed" width="100%">
+          <fo:table-column column-number="1"
+			   column-width="proportional-column-width(1)"/>
+          <fo:table-column column-number="2"
+			   column-width="proportional-column-width(1)"/>
+          <fo:table-body>
+            <fo:table-row>
+              <fo:table-cell>
+                <fo:block>
+                  <fo:external-graphic height="1.2in"
+				       content-height="scale-to-fit">
+		    <xsl:attribute name="src">
+		      <xsl:text>url('</xsl:text>
+		      <xsl:apply-templates select="ancestor-or-self::book/info/mediaobject/imageobject/imagedata/@fileref"/>
+		      <xsl:text>')</xsl:text>
+		    </xsl:attribute>
+		  </fo:external-graphic>
+                </fo:block>
+              </fo:table-cell>
+              <fo:table-cell>
+                <fo:block font-size="10pt" text-align="right">
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/personname"/>
+		  </fo:block>
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/street"/>
+		  </fo:block>
+                  <fo:block>
+		    <xsl:value-of select="ancestor-or-self::book/info/address/city"/> <xsl:value-of select="ancestor-or-self::book/info/address/state"/> <xsl:value-of select="ancestor-or-self::book/info/address/postcode"/> <xsl:value-of select="ancestor-or-self::book/info/address/country"/>
+		  </fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/phone"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/fax"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/uri"/></fo:block>
+                  <fo:block><xsl:value-of select="ancestor-or-self::book/info/address/email"/></fo:block>
+                </fo:block>
+              </fo:table-cell>
+            </fo:table-row>
+          </fo:table-body>
+        </fo:table>
+        <fo:block font-size="10pt" font-weight="bold" text-align="center"
+          border-top="0.5pt solid black" padding-top="0.05in">
+        </fo:block>
+      </fo:block-container>
+    </fo:block>
+  </xsl:template>
+
+  <!-- Second page (legal/revhistory) template. Customized from
+       fo/titlepage.templates.xsl.
+
+       This template needs to be rewritten as well (see the comment for the
+       template above).
+  -->
+  <xsl:template name="book.titlepage.verso">
+    <fo:block font-family="sans-serif" font-size="18pt" font-weight="bold"><xsl:value-of select="ancestor-or-self::book/info/title"/></fo:block>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/copyright"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/pubdate"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/releaseinfo"/>
+    <xsl:apply-templates mode="book.titlepage.verso.auto.mode" select="info/legalnotice"/>
+
+  </xsl:template>
+
+  <xsl:template match="legalnotice//emphasis">
+    <xsl:call-template name="inline.boldseq"/>
+  </xsl:template>
+
+<!-- ======================================================================
+       Header/footer customizations
+     ====================================================================== -->
+
+  <!-- Customized from fo/pagesetup.xsl. -->
+  <xsl:template name="header.content">
+    <xsl:param name="pageclass" select="''"/>
+    <xsl:param name="sequence" select="''"/>
+    <xsl:param name="position" select="''"/>
+    <xsl:param name="gentext-key" select="''"/>
+
+    <fo:block>
+      <xsl:choose>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+          <xsl:value-of select="ancestor-or-self::d:book/d:info/d:author/d:orgname"/>
+        </xsl:when>
+        <xsl:when test="$pageclass = 'body' and $position = 'right'">
+          <xsl:apply-templates select="." mode="title.markup"/>
+        </xsl:when>
+        <xsl:otherwise/>
+      </xsl:choose>
+    </fo:block>
+  </xsl:template>
+
+  <!-- Customized from fo/pagesetup.xsl. -->
+  <xsl:template name="footer.content">
+    <xsl:param name="pageclass" select="''"/>
+    <xsl:param name="sequence" select="''"/>
+    <xsl:param name="position" select="''"/>
+    <xsl:param name="gentext-key" select="''"/>
+
+    <fo:block>
+      <xsl:choose>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'left'">
+          <xsl:value-of select="ancestor-or-self::d:book/d:info/d:title"/>
+        </xsl:when>
+        <xsl:when test="($pageclass = 'body' or $pageclass = 'lot') and $position = 'right'">
+          <fo:page-number/>
+        </xsl:when>
+        <xsl:otherwise/>
+      </xsl:choose>
+    </fo:block>
+  </xsl:template>
+
+<!-- ======================================================================
+       Table customizations
+     ====================================================================== -->
+
+  <!-- Table customization. -->
+  <xsl:param name="default.table.frame" select="'none'"/>
+  <xsl:attribute-set name="table.properties" use-attribute-sets="formal.object.properties">
+    <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
+  </xsl:attribute-set>
+
+<xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing">
+  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+  <xsl:attribute name="font-weight">bold</xsl:attribute>
+  <xsl:attribute name="font-size">
+    <xsl:value-of select="$body.font.master * 1.2"></xsl:value-of>
+    <xsl:text>pt</xsl:text>
+  </xsl:attribute>
+  <xsl:attribute name="hyphenate">false</xsl:attribute>
+  <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
+  <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
+  <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
+</xsl:attribute-set>
+
+
+  <!-- Customized from fo/table.xsl. -->
+  <xsl:template name="table.row.properties">
+    <xsl:variable name="rownum">
+      <xsl:number from="d:tgroup" count="d:row"/>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="ancestor::d:thead">
+        <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+        <xsl:attribute name="border-bottom">1.5pt solid black</xsl:attribute>
+        <xsl:attribute name="text-align">left</xsl:attribute>
+        <xsl:if test="ancestor::d:table/@role = 'wide'">
+          <xsl:attribute name="font-size">75%</xsl:attribute>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:attribute name="text-align">left</xsl:attribute>
+        <xsl:if test="ancestor::d:table/@role = 'wide'">
+          <xsl:attribute name="font-size">60%</xsl:attribute>
+        </xsl:if>
+        <xsl:if test="$rownum mod 2 = 0">
+          <xsl:attribute name="background-color">#e6e6fb</xsl:attribute>
+        </xsl:if>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="d:tbody/d:row/d:entry/d:emphasis">
+    <xsl:call-template name="inline.boldseq"/>
+  </xsl:template>
+
+  <xsl:param name="table.footnote.number.symbols" select="'*&#x2020;&#x2021;&#x25CA;&#x2720;'"/>
+
+  <xsl:attribute-set name="table.footnote.properties">
+    <xsl:attribute name="font-family"><xsl:value-of select="$body.fontset"></xsl:value-of></xsl:attribute>
+    <xsl:attribute name="font-size"><xsl:value-of select="$footnote.font.size"></xsl:value-of></xsl:attribute>
+    <xsl:attribute name="font-weight">normal</xsl:attribute>
+    <xsl:attribute name="font-style">normal</xsl:attribute>
+    <xsl:attribute name="space-before">4pt</xsl:attribute>
+    <xsl:attribute name="text-align"><xsl:value-of select="$alignment"></xsl:value-of></xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       List customizations
+     ====================================================================== -->
+
+  <xsl:attribute-set name="list.block.spacing">
+    <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="margin-left">0.25in</xsl:attribute>
+  </xsl:attribute-set>
+
+<!-- ======================================================================
+       Shell command and software install instructions customizations
+     ====================================================================== -->
+
+  <xsl:param name="shade.verbatim" select="1"></xsl:param>
+  <xsl:attribute-set name="verbatim.properties">
+    <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+    <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+    <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+    <xsl:attribute name="hyphenate">false</xsl:attribute>
+    <xsl:attribute name="wrap-option">no-wrap</xsl:attribute>
+    <xsl:attribute name="white-space-collapse">false</xsl:attribute>
+    <xsl:attribute name="white-space-treatment">preserve</xsl:attribute>
+    <xsl:attribute name="linefeed-treatment">preserve</xsl:attribute>
+    <xsl:attribute name="text-align">start</xsl:attribute>
+    <xsl:attribute name="font-size">75%</xsl:attribute>
+  </xsl:attribute-set>
+
+</xsl:stylesheet>
diff --git a/rules.mk b/rules.mk
index 6f999dd..383bf6b 100644
--- a/rules.mk
+++ b/rules.mk
@@ -24,6 +24,7 @@
 #########################################################################
 
 _depend:	$(obj).depend
+_man_parse:	$(obj).man_parse
 
 $(obj).depend:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
 		@rm -f $@
@@ -32,4 +33,10 @@ $(obj).depend:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
 			$(CC) -M $(HOSTCFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \
 		done
 
+$(obj).man_parse:	$(src)Makefile $(TOPDIR)/config.mk $(SRCS)
+		@for f in $(SRCS); do \
+			$(CPP)  $(CPPFLAGS) -C $$f | \
+			perl $(TOPDIR)/doc/manual/doc-stream.pl >> \
+				$(TOPDIR)/doc/manual/autoconf-doc.txt; \
+		done
 #########################################################################
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc
       [not found] <yes>
                   ` (3 preceding siblings ...)
  2009-07-28 16:34 ` [U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator John Schmoller
@ 2009-07-28 16:34 ` John Schmoller
  2009-07-28 17:52   ` Wolfgang Denk
  2009-07-28 16:34 ` [U-Boot] [RFC 3/3] xpedite5370: Add uboot-doc support John Schmoller
                   ` (86 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: John Schmoller @ 2009-07-28 16:34 UTC (permalink / raw)
  To: u-boot

Add support to a small subset of commands, environment
variables, and POSTs. These are meant to show the
syntax and capabilities of the uboot-doc parser.

Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
---
 common/cmd_i2c.c    |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 common/cmd_mem.c    |   45 +++++++++++++++++++++++++++++++-
 common/cmd_net.c    |   30 ++++++++++++++++++++-
 common/env_common.c |   35 +++++++++++++++++++++++++
 post/tests.c        |   16 +++++++++++
 5 files changed, 192 insertions(+), 5 deletions(-)

diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 8f0fc9e..14d394c 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 }
 
 /***************************************************/
-
+/**
+ * @cmd: i2c speed
+ * @sect: I2C
+ * @param[or]: speed - target I2C bus speed
+ * @desc: Show or set I2C bus speed
+ */
+/**
+ * @cmd: i2c dev
+ * @sect: I2C
+ * @param[or]: dev - I2C device to make current
+ * @desc: Show or set current I2C bus
+ */
+/**
+ * @cmd: i2c md
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param[or]: # of objects - Numer of bytes to read
+ * @desc: Read from I2C device
+ */
+/**
+ * @cmd: i2c mm
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @desc: Write to I2C device (auto-incrementing)
+ */
+/**
+ * @cmd: i2c mw
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: value - Value to write to I2C address
+ * @param[or]: count - Number of bytes to write
+ * @desc: Write to I2C device (fill)
+ */
+/**
+ * @cmd: i2c nm
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @desc: Write to I2C device (constant address)
+ */
+/**
+ * @cmd: i2c crc32
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: count - Number of bytes to CRC
+ * @desc: Computes the CRC32 checksum of an address range
+ */
+/**
+ * @cmd: i2c probe
+ * @sect: I2C
+ * @desc: Shows all the devices on the I2C bus
+ */
+/**
+ * @cmd: i2c loop
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @param: address[.0, .1, .2] - Address into I2C device
+ * @param: # of objects - Number of bytes to loop over
+ * @desc: Looping read of device.  Never returns.
+ */
 U_BOOT_CMD(
 	i2c, 6, 1, do_i2c,
 	"I2C sub-system",
@@ -1317,6 +1380,12 @@ U_BOOT_CMD(
 	"i2c reset - re-init the I2C Controller\n"
 	"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device"
 #if defined(CONFIG_CMD_SDRAM)
+/**
+ * @cmd: isdram
+ * @sect: I2C
+ * @param: chip - I2C address of desired device
+ * @desc: Prints SDRAM configuration information
+ */
 	"\n"
 	"i2c sdram chip - print SDRAM configuration information"
 #endif
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index cdf8c79..2276a1a 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -1169,20 +1169,61 @@ int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
 
 /**************************************************/
+/**
+ * @cmd: md
+ * @sect: Memory
+ * @param[or]: address -  memory location to display
+ * @param[or]: objs - Number of objects to display
+ * @desc: The md command displays memory contents both as hexadecimal and
+ *	ASCII data. The last displayed memory address and the value of the
+ *	count argument are remembered, so when you enter md again without
+ *	arguments it will automatically continue at the next address, and use
+ *	the same count again.
+ *
+ *	If invoked as md or md.l, data is displayed as 32-bit long words. If
+ *	invoked as md.w or md.b instead, 16-bit words or 8-bit bytes are used,
+ *	respectively.
+ */
 U_BOOT_CMD(
 	md,	3,	1,	do_mem_md,
 	"memory display",
 	"[.b, .w, .l] address [# of objects]"
 );
 
-
+/**
+ * @cmd: mm
+ * @sect: Memory
+ * @param[or]: address -  memory location to modify
+ * @desc: The mm command is a method to interactively modify memory contents.
+ *	It will display the address and current contents and then prompt for
+ *	user input. If you enter a legal hexadecimal number, this new value
+ *	will be written to the address. Then, the next address will be
+ *	prompted. If you don't enter any value and just press ENTER, then the
+ *	contents of this address will remain unchanged. The command stops as
+ *	soon as you enter any data that is not a hex number.
+ *
+ *	If invoked as mm or mm.l, data is displayed as 32-bit long words. If
+ *	invoked as mm.w or mm.b instead, 16-bit words or 8-bit bytes are used,
+ *	respectively.
+ */
 U_BOOT_CMD(
 	mm,	2,	1,	do_mem_mm,
 	"memory modify (auto-incrementing address)",
 	"[.b, .w, .l] address"
 );
 
-
+/**
+ * @cmd: nm
+ * @sect: Memory
+ * @param[or]: address -  memory location to modify
+ * @desc: The nm command (non-incrementing memory modify) can be used to
+ *	interactively write different data several times to the same address.
+ *	This can be useful, for instance, to access and modify device registers.
+ *
+ *	If invoked as nm or nm.l, data is modified as a 32-bit long word. If
+ *	invoked as nm.w or nm.b instead, 16-bit words or 8-bit bytes are used,
+ *	respectively.
+ */
 U_BOOT_CMD(
 	nm,	2,	1,	do_mem_nm,
 	"memory modify (constant address)",
diff --git a/common/cmd_net.c b/common/cmd_net.c
index 88f4e5b..7760230 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -47,7 +47,24 @@ int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	return netboot_common (TFTP, cmdtp, argc, argv);
 }
-
+/**
+ * @cmd: tftpboot
+ * @sect: Networking
+ * @param[r]: loadAddress - address to store downloaded file
+ * @param[or]: [hostIPaddr:]bootfilename - file to download from specified IP
+ * @desc: The tftpboot command downloads a file from the
+ *      network using the TFTP protocol. @eipaddr, @eserverip,
+ *      @egatewayip, and @enetmask must be set prior to
+ *      calling tftpboot.
+ *      If loadAddress is specified, the file will be
+ *      downloaded to this address. If not specified, the
+ *      file will be downloaded to the address specified by the
+ *      @eloadaddr environment varaible.  A load file can
+ *      either be specified by the bootfilename or by the
+ *      @efileaddr. A host IP address can be specified when
+ *      a bootfilename is specified by prepending it to
+ *      bootfilename (ie XX.XX.XX.XX:file).
+ */
 U_BOOT_CMD(
 	tftpboot,	3,	1,	do_tftpb,
 	"boot image via network using TFTP protocol",
@@ -265,7 +282,16 @@ int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 
 	return 0;
 }
-
+/**
+ * @cmd: ping
+ * @sect: Networking
+ * @param[r]: addr - IP address to send Echo Request packet
+ * @desc: The ping command checks to see if a specific
+ *        IP address is alive by sending an ICMP Echo
+ *        Request packet. If the device specified by
+ *        addr responds before a timeout occurs, ping
+ *        reports that the board is alive.
+ */
 U_BOOT_CMD(
 	ping,	2,	1,	do_ping,
 	"send ICMP ECHO_REQUEST to network host",
diff --git a/common/env_common.c b/common/env_common.c
index 6be3bb0..e55ebce 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -97,9 +97,23 @@ uchar default_environment[] = {
 #ifdef	CONFIG_ETH5ADDR
 	"eth5addr="	MK_STR(CONFIG_ETH5ADDR)		"\0"
 #endif
+#ifdef	CONFIG_CMD_NET
+	/**
+	 * @env: ipaddr
+	 * @sect: Networking
+	 * @desc: IP address of this board
+	 */
+#endif
 #ifdef	CONFIG_IPADDR
 	"ipaddr="	MK_STR(CONFIG_IPADDR)		"\0"
 #endif
+#ifdef	CONFIG_CMD_NET
+	/**
+	 * @env: serverip
+	 * @sect: Networking
+	 * @desc: IP address of the server
+	 */
+#endif
 #ifdef	CONFIG_SERVERIP
 	"serverip="	MK_STR(CONFIG_SERVERIP)		"\0"
 #endif
@@ -112,9 +126,23 @@ uchar default_environment[] = {
 #ifdef	CONFIG_ROOTPATH
 	"rootpath="	MK_STR(CONFIG_ROOTPATH)		"\0"
 #endif
+#ifdef	CONFIG_CMD_NET
+	/**
+	 * @env: gatewayip
+	 * @sect: Networking
+	 * @desc: IP address of the next hop gateway
+	 */
+#endif
 #ifdef	CONFIG_GATEWAYIP
 	"gatewayip="	MK_STR(CONFIG_GATEWAYIP)	"\0"
 #endif
+#ifdef	CONFIG_CMD_NET
+	/**
+	 * @env: netmask
+	 * @sect: Networking
+	 * @desc: Network mask to reach gateway
+	 */
+#endif
 #ifdef	CONFIG_NETMASK
 	"netmask="	MK_STR(CONFIG_NETMASK)		"\0"
 #endif
@@ -124,6 +152,13 @@ uchar default_environment[] = {
 #ifdef	CONFIG_BOOTFILE
 	"bootfile="	MK_STR(CONFIG_BOOTFILE)		"\0"
 #endif
+#ifdef	CONFIG_CMD_NET
+	/**
+	 * @env: loadaddr
+	 * @sect: Networking
+	 * @desc: Address in memory to store downloaded files
+	 */
+#endif
 #ifdef	CONFIG_LOADADDR
 	"loadaddr="	MK_STR(CONFIG_LOADADDR)		"\0"
 #endif
diff --git a/post/tests.c b/post/tests.c
index 3224f00..1bee185 100644
--- a/post/tests.c
+++ b/post/tests.c
@@ -102,6 +102,14 @@ struct post_test post_list[] =
 #endif
 #endif
 #if CONFIG_POST & CONFIG_SYS_POST_I2C
+    /**
+     * @post: I2C Post
+     * @desc: The I2C POST verifies that a pre-assembled list of devices and
+     * only those devices respond to an I2C bus scan. This list is assembled
+     * in the board-specific config file as the board is developed. If a
+     * device doesn't respond, or a device which is not in the list responds,
+     * the POST will fail.
+     */
     {
 	"I2C test",
 	"i2c",
@@ -126,6 +134,14 @@ struct post_test post_list[] =
     },
 #endif
 #if CONFIG_POST & CONFIG_SYS_POST_MEMORY
+    /**
+     * @post: Memory Post
+     * @desc:The Memory POST verifies RAM by performing the following tests:
+     * pattern(zeros, ones, 0x5 checkerboard, 0xa checkerboard), bit-flip
+     * pattern, address pattern (offset), and address pattern (~offset).
+     * The POST verifies only small 4Kb regions of RAM around each 1Mb
+     * boundary.
+     */
     {
 	"Memory test",
 	"memory",
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 3/3] xpedite5370: Add uboot-doc support
       [not found] <yes>
                   ` (4 preceding siblings ...)
  2009-07-28 16:34 ` [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc John Schmoller
@ 2009-07-28 16:34 ` John Schmoller
  2009-10-07 13:49 ` [PATCH 1/1] perf tools: Up the verbose level for some really verbose stuff Arnaldo Carvalho de Melo
                   ` (85 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: John Schmoller @ 2009-07-28 16:34 UTC (permalink / raw)
  To: u-boot

Add uboot-doc support to the XPedite5370. Incorporates
templates to override the defaults and includes memory
maps.

Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
---
 board/xes/xpedite5370/manual/book_info.tmpl        |   52 ++++++
 board/xes/xpedite5370/manual/booting_linux.tmpl    |  179 ++++++++++++++++++++
 board/xes/xpedite5370/manual/booting_vxworks.tmpl  |  166 ++++++++++++++++++
 board/xes/xpedite5370/manual/manual.tmpl           |   30 ++++
 board/xes/xpedite5370/manual/redundant_images.tmpl |   50 ++++++
 board/xes/xpedite5370/manual/scripting.tmpl        |  168 ++++++++++++++++++
 include/configs/XPEDITE5370.h                      |   47 +++++
 7 files changed, 692 insertions(+), 0 deletions(-)
 create mode 100644 board/xes/xpedite5370/manual/book_info.tmpl
 create mode 100644 board/xes/xpedite5370/manual/booting_linux.tmpl
 create mode 100644 board/xes/xpedite5370/manual/booting_vxworks.tmpl
 create mode 100644 board/xes/xpedite5370/manual/manual.tmpl
 create mode 100644 board/xes/xpedite5370/manual/redundant_images.tmpl
 create mode 100644 board/xes/xpedite5370/manual/scripting.tmpl

diff --git a/board/xes/xpedite5370/manual/book_info.tmpl b/board/xes/xpedite5370/manual/book_info.tmpl
new file mode 100644
index 0000000..3e6ec85
--- /dev/null
+++ b/board/xes/xpedite5370/manual/book_info.tmpl
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<info>
+  <title>${BOARD} U-Boot Manual</title>
+  <subtitle>U-Boot User&apos;s Manual</subtitle>
+  <releaseinfo>U-Boot version: ${VERSION}</releaseinfo>
+  <titleabbrev>${BOARD}</titleabbrev>
+  <pubdate>${DATE}</pubdate>
+  <address>
+    <personname>Extreme Engineering Solutions, Inc.</personname>
+    <street>3225 Demming Way, Suite 120</street>
+    <city>Middleton, </city>
+    <state>WI </state>
+    <postcode>53562-1408 </postcode>
+    <country>USA</country>
+    <phone>Phone: (608) 833-1155</phone>
+    <fax>Fax: (608) 827-6171</fax>
+    <uri>Web: http://xes-inc.com</uri>
+    <email>E-mail: sales at xes-inc.com</email>
+  </address>
+  <mediaobject>
+    <imageobject>
+      <imagedata fileref="/home/jschmoller/trunk/share/src/images/xes_logo_with_name_left.svg"/>
+    </imageobject>
+  </mediaobject>
+  <legalnotice>
+    <para>
+      U-Boot 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.
+    </para>
+
+    <para>
+      U-Boot 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.
+    </para>
+
+    <para>
+      You should have received a copy of the GNU General Public License
+      along with this program; if not, write to the
+      <orgname>Free Software Foundation, Inc.</orgname>,
+      <address><street>59 Temple Place, Suite 330</street>
+	<city>Boston</city>, <state>MA</state> <postcode>02111-1307</postcode>
+	<country>USA</country>
+      </address>
+    </para>
+  </legalnotice>
+</info>
+
diff --git a/board/xes/xpedite5370/manual/booting_linux.tmpl b/board/xes/xpedite5370/manual/booting_linux.tmpl
new file mode 100644
index 0000000..d026d1b
--- /dev/null
+++ b/board/xes/xpedite5370/manual/booting_linux.tmpl
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_linux_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Booting Linux</title>
+
+
+  <sect1 xml:id="uboot_booting_linux">
+    <title>Booting Linux with U-Boot</title>
+    <sect2 xml:id="uboot_booting_linux_intro">
+      <title>Booting Linux</title>
+      <para>The following is intended to be a Quick Start guide for booting a
+	Linux kernel. More information can be found in your Linux Manual.
+      </para>
+
+      <para>Your Linux kernel can be booted from either RAM or from Flash.
+	Images booted from RAM will need to be downloaded from the network
+	using <link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link>
+	on every reset. Images booted from Flash will be copied from Flash to
+	RAM automatically.
+      </para>
+
+      <sect3 xml:id="uboot_booting_linux_ram">
+	<title>Booting from RAM</title>
+	<para>To boot an image from RAM, you will need to have your Linux
+	  kernel and Flat Device Tree image on a TFTP server. See
+	  <link linkend="uboot_setup_network">
+	  <literal>Networking</literal></link> for more information about
+	  TFTP and TFTP servers. Next, you will need to set up your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server.
+#ifdef CONFIG_CMD_DHCP
+	  You can use a DHCP server to accomplish this if
+	  your network has one set up using the
+	  <link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> command.
+#endif
+	  Set <link linkend="uboot_env_osfile"><literal>osfile</literal></link>
+	  to the path to your Linux kernel on your TFTP server and set
+	  <link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link>
+	  to the path to your Flat Device Tree image on your TFTP server.
+	  Finally,
+	  type <link linkend="uboot_cmd_run"><literal>run</literal></link>
+	  <link linkend="uboot_env_bootcmd_net">
+	  <literal>bootcmd_net</literal></link> to download and boot your
+	  Linux kernel. This option assumes you are booting an NFS file system.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> run bootcmd_net
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0x1000000
+Loading: *###############################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0xc00000
+Loading: *##
+done
+Bytes transferred = 16384 (4000 hex)
+## Booting kernel from Legacy Image at 01000000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+
+      <sect3 xml:id="uboot_booting_linux_flash">
+	<title>Booting from Flash</title>
+	<para>To boot an image from Flash, you will need to follow a similar
+	  procedure to load the Kernel and FDT for the first time. Make sure
+	  you have your Kernel and FDT on your TFTP server.  Set your
+	  <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server. Set
+	  <link linkend="uboot_env_osfile"><literal>osfile</literal></link> to
+	  the path to your Linux kernel on your TFTP server and set
+	  <link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link>
+	  to the path to your Flat Device Tree image on your TFTP server. Then,
+	  type <link linkend="uboot_cmd_run"><literal>run</literal></link>
+	  <link linkend="uboot_env_prog_os1"><literal>prog_os1</literal></link>
+	  to load the Primary OS, or type <link linkend="uboot_cmd_run">
+	  <literal>run</literal></link> <link linkend="uboot_env_prog_os2">
+	  <literal>prog_os2</literal></link> to load the Secondary OS. Next,
+	  you&apos;ll need to load the FDT by running either
+	  <link linkend="uboot_env_prog_fdt1">
+	  <literal>prog_fdt1</literal></link> or <link linkend="env_prog_fdt2">
+	  <literal>prog_fdt2</literal></link>. Once the image and FDT are
+	  loaded into Flash, you can boot the Primary Image by typing
+	  <link linkend="uboot_cmd_run"><literal>run</literal></link>
+	  <link linkend="uboot_env_bootcmd_flash1">
+	  <literal>bootcmd_flash1</literal></link> at the prompt or you can
+	  boot the Secondary Image by typing <link linkend="uboot_cmd_run">
+	  <literal>run</literal></link>
+	  <link linkend="uboot_env_bootcmd_flash2">
+	  <literal>bootcmd_flash2</literal></link> at the prompt.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> setenv osfile /home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1
+=> setenv fdtfile /home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1
+=> run prog_os1
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.254.15
+Filename &apos;/home/jschmoller/uImage-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+	 #################################################################
+	 #################################################################
+	 #################################################################
+	 ######
+done
+Bytes transferred = 3901275 (3b875b hex)
+
+.............................. done
+Erased 30 sectors
+Copy to Flash... done
+Total of 3901275 bytes were the same
+OS PROGRAM SUCCEEDED
+
+=> run prog_fdt1
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134
+Filename &apos;/home/jschmoller/xpedite5370.dtb-XPedite5370-S2.6.23.17-fsl_r1&apos;.
+Load address: 0xc00000
+Loading: ##
+done
+Bytes transferred = 16384 (4000 hex)
+
+. done
+Erased 1 sectors
+Copy to Flash... done
+Total of 16384 bytes were the same
+FDT PROGRAM SUCCEEDED
+=> run bootcmd_flash1
+## Booting kernel from Legacy Image at fef00000 ...
+   Image Name:   Linux-2.6.23.17-fsl_r1
+   Created:      2008-08-06  16:46:04 UTC
+   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
+   Data Size:    3901211 Bytes =  3.7 MB
+   Load Address: 00000000
+   Entry Point:  00000000
+   Verifying Checksum ... OK
+   Uncompressing Kernel Image ... OK
+	  </screen>
+	</para>
+      </sect3>
+    </sect2>
+  </sect1>
+</chapter>
diff --git a/board/xes/xpedite5370/manual/booting_vxworks.tmpl b/board/xes/xpedite5370/manual/booting_vxworks.tmpl
new file mode 100644
index 0000000..c10ba6f
--- /dev/null
+++ b/board/xes/xpedite5370/manual/booting_vxworks.tmpl
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_booting_vxworks_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Booting VxWorks</title>
+
+  <sect1 xml:id="uboot_booting_vxworks">
+    <title>Booting VxWorks with U-Boot</title>
+    <sect2 os="vxworks" xml:id="uboot_booting_vxworks_intro">
+      <title>VxWorks</title>
+
+      <para>The following is intended to be a Quick Start guide for booting a
+	VxWorks image. More information can be found in your VxWorks Manual.
+      </para>
+
+      <para>VxWorks images can be booted from either RAM or Flash. VxWorks
+	images also come in a uImage format and an ELF format.  The boot
+	command for an ELF image is <link linkend="uboot_cmd_bootvx">
+	<literal>bootvx</literal></link> and the boot command for a uImage is
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>.
+      </para>
+
+      <sect3 xml:id="uboot_booting_vxworks_ram">
+	<title>Booting from RAM</title>
+	<para>VxWorks requires a string of arguments to be passed to it in
+	  order to function properly. To boot from RAM, begin by setting the
+	  <link linkend="uboot_env_root_args">
+	  <literal>root_args</literal></link> string to something like the
+	  following: <literal>motetsec(0,0)host:&lt;Path to VxWorks image&gt;
+	  h=&lt;Host IP&gt; e=&lt;Board IP&gt;:&lt;Netmask&gt; u=drives
+	  pw=drives</literal> and the <link linkend="uboot_env_misc_args">
+	  <literal>misc_args</literal></link> to <literal>f=0x0</literal>.
+	  Replace the items in &lt;&gt;&apos;s with the appropriate values.
+	  Next, configure your <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server. Download the VxWorks image by typing
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftpboot</literal></link>
+	  <literal>0x1000000 &lt;Path to VxWorks image&gt;</literal>. Finally,
+	  use the boot command specified above and type
+	  <literal>&lt;Boot Command&gt; 0x1000000</literal> at the prompt to
+	  finish booting your VxWorks image.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv root_args motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives
+=> setenv misc_args f=0x0
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> tftp 1000000 /home/mstarzewski/xes8572-vxWorks.st
+Enet starting in 1000BT/FD
+
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/mstarzewski/xes8572-vxWorks.st&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+	 ######################################################
+done
+Bytes transferred = 1740761 (1a8fd9 hex)
+=> bootvx 1000000
+## Ethernet MAC address not copied to NV RAM
+Loading .text @ 0x00100000 (1263808 bytes)
+Loading .sdata2 @ 0x002348c0 (432 bytes)
+Loading .data @ 0x00234a70 (128320 bytes)
+Loading .sdata @ 0x00253fb0 (2752 bytes)
+Clearing .sbss @ 0x00254a70 (2144 bytes)
+Clearing .bss @ 0x002552d0 (252128 bytes)
+## Using bootline (@ 0x4200): motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives f=0x0
+## Starting vxWorks at 0x00100000 ...
+Target Name: vxTarget
+...
+	  </screen>
+	</para>
+      </sect3>
+
+      <sect3>
+	<title>Booting from Flash</title>
+	<para>VxWorks requires a string of arguments to be passed to it in
+	  order to function properly. To boot from Flash, begin by setting the
+	  <link linkend="uboot_env_root_args">
+	  <literal>root_args</literal></link> string to something like the
+	  following: <literal>motetsec(0,0)host:
+	  &lt;Path to VxWorks image&gt; h=&lt;Host IP&gt; e=&lt;Board IP&gt;:
+	  &lt;Netmask&gt; u=drives pw=drives</literal> and the
+	  <link linkend="uboot_env_misc_args">
+	  <literal>misc_args</literal></link> to <literal>f=0x0</literal>.
+	  Replace the items in &lt;&gt;&apos;s with the appropriate values.
+	  Next, configure your <link linkend="uboot_env_sect_networking">
+	  <literal>network environment variables</literal></link> to point to
+	  your TFTP server. Download the VxWorks image by typing
+	  <link linkend="uboot_cmd_tftpboot"><literal>tftpboot</literal></link>
+	  <literal>1000000 &lt;Path to VxWorks image&gt;</literal>. To program
+	  the image to Flash, start by clearing space for it. For the Primary
+	  image, type <link linkend="uboot_cmd_erase"><literal>erase</literal>
+	  </link> <literal>fef00000 +&amp;</literal>
+	  <link linkend="uboot_env_filesize"><literal>filesize</literal></link>
+	  and for the Secondary image, type <link linkend="uboot_cmd_erase">
+	  <literal>erase</literal></link> <literal>f6f00000</literal>
+	  <link linkend="uboot_env_filesize">
+	  <literal>+$filesize</literal></link>. Next, copy the image from RAM
+	  to Flash. Type <link linkend="uboot_cmd_cp">
+	  <literal>cp.b</literal></link>
+	  <literal>1000000 fef00000 $filesize</literal> for the Primary image
+	  and <link linkend="uboot_cmd_cp"><literal>cp.b</literal></link>
+	  <literal>1000000 f6f00000 $filesize</literal> for the Secondary image.
+	  Finally, use the boot command specified above and type
+	  <literal>&lt;Boot Command&gt; fef00000</literal> or
+	  <literal>&lt;Boot Command&gt; f6f00000</literal> at the prompt to
+	  finish booting your VxWorks image.
+	</para>
+
+	<para>Your console input/output should look something like this.
+	  <screen>
+=> setenv root_args motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives
+=> setenv misc_args f=0x0
+=> setenv gatewayip 10.52.0.1
+=> setenv netmask 255.255.255.0
+=> setenv ipaddr 10.52.250.134
+=> setenv serverip 10.52.0.33
+=> tftp 1000000 /home/mstarzewski/xes8572-vxWorks.st
+Enet starting in 1000BT/FD
+Speed: 1000, full duplex
+Using eTSEC1 device
+TFTP from server 10.52.0.33; our IP address is 10.52.250.134; sending through gateway 10.52.0.1
+Filename &apos;/home/mstarzewski/xes8572-vxWorks.st&apos;.
+Load address: 0x1000000
+Loading: #################################################################
+	 ######################################################
+done
+Bytes transferred = 1740761 (1a8fd9 hex)
+=> erase fef00000 +$filesize
+
+.............. done
+Erased 14 sectors
+=> cp.b 1000000 fef00000 $filesize
+
+Copy to Flash... done
+=> bootvx fef00000
+## Ethernet MAC address not copied to NV RAM
+Loading .text @ 0x00100000 (1296720 bytes)
+Loading .sdata2 @ 0x0023c950 (192 bytes)
+Loading .data @ 0x0023ca20 (136656 bytes)
+Loading .sdata @ 0x0025dff0 (2384 bytes)
+Clearing .sbss @ 0x0025e940 (2240 bytes)
+Clearing .bss @ 0x0025f200 (251184 bytes)
+## Using bootline (@ 0x4200): motetsec(0,0)host:/home/mstarzewski/xes8572-vxWorks.st
+h=10.52.0.33 e=10.52.250.134:ffff0000 u=drives pw=drives f=0x0
+## Starting vxWorks at 0x00100000 ...
+Target Name: vxTarget
+...
+	  </screen>
+	</para>
+      </sect3>
+    </sect2>
+  </sect1>
+</chapter>
+
+
diff --git a/board/xes/xpedite5370/manual/manual.tmpl b/board/xes/xpedite5370/manual/manual.tmpl
new file mode 100644
index 0000000..dfac2e6
--- /dev/null
+++ b/board/xes/xpedite5370/manual/manual.tmpl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<book xmlns="http://docbook.org/ns/docbook"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      version="5.0"
+      xml:id="uboot_manual">
+
+  <xi:include href="${TOPDIR}/doc/manual/book_info.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/introduction.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/setup.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/booting_linux.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/booting_vxworks.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/memory_resources.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/redundant_images.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/posts.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/environment_variables.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/commands.xml"/>
+
+  <xi:include href="${TOPDIR}/doc/manual/scripting.xml"/>
+
+</book>
diff --git a/board/xes/xpedite5370/manual/redundant_images.tmpl b/board/xes/xpedite5370/manual/redundant_images.tmpl
new file mode 100644
index 0000000..af6000c
--- /dev/null
+++ b/board/xes/xpedite5370/manual/redundant_images.tmpl
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_redundant_images_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Redundant Images</title>
+
+  <sect1 xml:id="uboot_redundant_images">
+    <title>Using Redundant Images with U-Boot</title>
+    <para>The ${BOARD} has two Flash banks, which can be used to hold dual or
+      redundant images. The board is configured with dual U-Boot images (see
+      <link linkend="uboot_memmap_recommended_flash_memory_map">
+      <literal>U-Boot Recommended Memory Regions</literal></link>). It can
+      also be configured with dual or redundant OS images. Sometimes it is
+      advantageous to store two different kernels in the primary and secondary
+      partitions. For example, the most recent version of the user&apos;s kernel
+      image could be stored in one partition, while a previous stable version
+      is kept in the other.
+    </para>
+
+    <para>Or, one kernel could be compiled with debug enabled
+      and the other without. Or the two OS partitions can also be used for
+      redundancy. The U-Boot uImage file has support for checksumming and can
+      be used to verify the integrity of an image. If the checksum fails on one
+      partition, U-Boot can be configured to boot the other partition&apos;s
+      image. This fallback image could be a carbon copy of the first, or could
+      send out notification of the first image&apos;s failure. Fallback is
+      easily configured; the fallback image does not necessarily need to be
+      from the same boot device.
+    </para>
+
+    <para>For example, if the checksum fails on an
+      image in flash, the fallback image could be downloaded over Ethernet.
+      For example, a simple script for booting one uImage and failing over to
+      the second could be written as
+      <link linkend="uboot_cmd_setenv"><literal>setenv</literal></link>
+      <link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+      <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+      <literal>0xfef00000\;</literal>
+      <link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+      <literal>0xf6f00000</literal>. In this example, U-Boot will attempt to
+      boot the Primary OS and will not return if the checksum is valid so
+      Secondary OS will not be called. If the Primary OS is corrupt, U-Boot
+      will return to a prompt where the Secondary OS will be executed.
+    </para>
+  </sect1>
+</chapter>
+
+
+
diff --git a/board/xes/xpedite5370/manual/scripting.tmpl b/board/xes/xpedite5370/manual/scripting.tmpl
new file mode 100644
index 0000000..f5e8a43
--- /dev/null
+++ b/board/xes/xpedite5370/manual/scripting.tmpl
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<chapter version="5.0" xml:id="uboot_scripting_chapter"
+	 xmlns="http://docbook.org/ns/docbook"
+	 xmlns:xi="http://www.w3.org/2001/XInclude">
+  <title>Scripting</title>
+
+  <sect1 xml:id="uboot_scripting">
+    <title>Scripting in U-Boot</title>
+    <sect2 xml:id="uboot_scripting_dollar_sign">
+      <title>Variable Expansion with $</title>
+      <para>Variable substitution can be done with the $ character. For
+	instance, <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <link linkend="uboot_env_bootargs">
+	<literal>bootargs</literal></link> could also be executed with
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<link linkend="uboot_env_bootargs"><literal>$bootargs</literal></link>.
+	More powerfully, this variable substitution can be used in scripting.
+	See the example in the next section.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_conditionals">
+      <title>Conditionals</title>
+      <para>U-Boot has a scripting language which can be used to customize
+	command execution. It contains if..then..else..fi, for..do..done,
+	while..do..done and until..do..done control flow operations.
+      </para>
+
+      <para>As an example, take the X-ES environment variable
+	<link linkend="uboot_env_bootcmd_net">
+	<literal>bootcmd_net</literal></link>.
+	<screen>
+bootcmd_net=run set_bootargs; $download_cmd $osaddr $osfile; if test $? -eq 0;
+then if test -n $fdtaddr; then $download_cmd $fdtaddr $fdtfile;
+if test $? -eq 0; then bootm $osaddr - $fdtaddr; else; echo FDT DOWNLOAD FAILED;
+fi; else; bootm $osaddr; fi; else; echo OS DOWNLOAD FAILED; fi;
+	</screen>
+	To walk through the script, we start with
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<link linkend="uboot_env_set_bootargs">
+	<literal>set_bootargs</literal></link>, which executes the commands
+	stored in <link linkend="uboot_env_set_bootargs">
+	<literal>set_bootargs</literal></link>. Next, we execute the command
+	stored in <link linkend="uboot_env_download_cmd">
+	<literal>download_cmd</literal></link> which in most cases is
+	<link linkend="uboot_cmd_dhcp"><literal>dhcp</literal></link> or
+	<link linkend="uboot_cmd_tftpboot"><literal>tftp</literal></link> and
+	download the file stored in <link linkend="uboot_env_osfile">
+	<literal>osfile</literal></link> to the address stored in
+	<link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>. The
+	next step is interesting. We start an <literal>if</literal> conditional,
+	and use the <link linkend="uboot_cmd_test">
+	<literal>test</literal></link> command to check to see if the return
+	value (<literal>$?</literal>) of the
+	<link linkend="uboot_env_download_cmd">
+	<literal>download_cmd</literal></link> is <literal>0</literal>.	If it
+	isn&apos;t, meaning the download failed, we find the matching
+	<literal>then</literal> and see that we echo
+	<literal>DOWNLOAD FAILED</literal>. If it is <literal>0</literal>
+	meaning the download completed successfully, we start a new
+	<literal>if</literal> conditional and test to see if
+	<link linkend="uboot_env_fdtaddr"><literal>fdtaddr</literal></link> is
+	defined. If it is, use <link linkend="uboot_env_download_cmd">
+	<literal>download_cmd</literal></link> to download the file stored in
+	<link linkend="uboot_env_fdtfile"><literal>fdtfile</literal></link> to
+	the address stored in <link linkend="uboot_env_fdtaddr">
+	<literal>fdtaddr</literal></link>. Again, we verify that the download
+	completed successfully.  If everything has worked up until now, we
+	complete the script with
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>
+	<literal>-</literal> <link linkend="uboot_env_fdtaddr">
+	<literal>fdtaddr</literal></link> and boot the image we just downloaded.
+	If <link linkend="uboot_env_fdtaddr"><literal>fdtaddr</literal></link>
+	had been undefined, we would have executed
+	<link linkend="uboot_cmd_bootm"><literal>bootm</literal></link>
+	<link linkend="uboot_env_osaddr"><literal>osaddr</literal></link>
+	instead.
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_and_or">
+      <title>&amp;&amp; and ||</title>
+      <para>Another feature of the U-Boot scripting language are the
+	<literal>&amp;&amp;</literal> and <literal>||</literal> functions. The
+	<literal>&amp;&amp;</literal> is an if and only if command. For
+	instance, the command
+	<link linkend="uboot_cmd_echo"><literal>echo</literal></link>
+	<literal>$do_stuff &amp;&amp;</literal>
+	<link linkend="uboot_cmd_run"><literal>run</literal></link>
+	<literal>$do_stuff</literal> would run <literal>do_stuff</literal>
+	only if the <link linkend="uboot_cmd_echo">
+	<literal>echo</literal></link> command returned successfully, meaning
+	that <literal>do_stuff</literal> is defined. If
+	<literal>do_stuff</literal> was not defined, the
+	<link linkend="uboot_cmd_run"><literal>run</literal></link> command
+	would not be executed. Similarly, the <literal>||</literal> command will
+	execute the second command only if the first command fails. For
+	instance, if <literal>bank1</literal> stored the location of the OS in
+	flash bank 1 and <literal>bank2</literal> stored the location of the
+	OS in flash bank 2, the following command would try to boot the image
+	in bank 1. If unsuccessful it would boot the image in bank 2.  If that
+	failed, it would attempt to download the file over the network, and if
+	that succeeded, it would boot the image.
+	<screen>
+<literal>bootm $bank1 || bootm $bank2 || tftp $osaddr $osfile &amp;&amp; bootm</literal>
+	</screen>
+      </para>
+    </sect2>
+
+    <sect2 xml:id="uboot_scripting_quotes_and_ticks">
+      <title>Quotes and tick marks</title>
+      <para>Quotation marks and tick marks also have a special meaning in
+	U-Boot scripting. Let&apos;s say you wanted to create an environment
+	variable called <literal>do_stuff</literal> and this variable was going
+	to run <link linkend="uboot_env_set_bootargs">
+	<literal>set_bootargs</literal></link> then run
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>.
+	Depending on how you format the command, it&apos;s execution will
+	change. You could save the command as
+	<screen>
+setenv do_stuff &quot;run $set_bootargs; run $bootcmd&quot;
+	</screen>
+	When you <link linkend="uboot_cmd_printenv">
+	<literal>printenv</literal></link> <literal>do_stuff</literal> you
+	should see something like
+	<screen>
+do_stuff=run setenv bootargs ${console_args} ${root_args} ${misc_args}; run run bootcmd_flash1
+	</screen>
+	Notice how the variables specified with the $ were expanded. Now, if
+	you do the same thing, replacing the quotation marks with tick marks,
+	<screen>
+setenv do_stuff &apos;run $set_bootargs; run $bootcmd&apos;
+	</screen>
+	you will see different behavior.
+	<screen>
+do_stuff=run $set_bootargs; run $bootcmd
+	</screen>
+	Notice how the variables specified with the $ were not expanded. In
+	most cases, this would be the desired behavior as these variables
+	would be expanded when they are executed.  Then, any changes made to
+	<link linkend="uboot_env_set_bootargs">
+	<literal>set_bootargs</literal></link> and
+	<link linkend="uboot_env_bootcmd"><literal>bootcmd</literal></link>
+	between the time that <literal>do_stuff</literal> was set and it was
+	run would change the functionality of <literal>do_stuff</literal>.
+	For example,
+	<screen>
+setenv printscript print
+setenv do_stuff &quot;$printscript&quot;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing all the environment variables, rather than
+	printing &quot;do nothing&quot;, whereas
+	<screen>
+setenv printscript print
+setenv do_stuff &apos;$printscript&apos;
+setenv printscript echo do nothing
+run do_stuff
+	</screen>
+	would result in printing &quot;do nothing&quot;.
+      </para>
+    </sect2>
+  </sect1>
+</chapter>
+
diff --git a/include/configs/XPEDITE5370.h b/include/configs/XPEDITE5370.h
index acb62ad..9322789 100644
--- a/include/configs/XPEDITE5370.h
+++ b/include/configs/XPEDITE5370.h
@@ -70,6 +70,15 @@
 #define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_SDRAM_BASE
 #define CONFIG_VERY_BIG_RAM
 
+/**
+ * @memmap: EEPROM Memory Map
+ * @entry: 0x2000: 0x3fff: Unused/Customer Available
+ * @entry: 0x1000: 0x1fff: Backup U-Boot Environment
+ * @entry: 0x0200: 0x0fff: Board Specific Information (SPD, etc.)
+ * @entry: 0x0100: 0x01ff: VxWorks Bootline (Optional)
+ * @entry: 0x0000: 0x00ff: Reset Configuration Data (Optional)
+ */
+
 #ifndef __ASSEMBLY__
 extern unsigned long get_board_sys_clk(unsigned long dummy);
 extern unsigned long get_board_ddr_clk(unsigned long dummy);
@@ -117,6 +126,24 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
  * 0xf800_0000	0xffff_ffff	NOR Flash 1		128M non-cacheable
  */
 
+/**
+ * @memmap: System Memory Map
+ * @entry: 0xf800_0000: 0xffff_ffff: NOR Flash 1
+ * @entry: 0xf000_0000: 0xf7ff_ffff: NOR Flash 2
+ * @entry: 0xef90_0000: 0xefff_ffff: Reserved
+ * @entry: 0xef80_0000: 0xef8f_ffff: NAND Flash
+ * @entry: 0xef10_0000: 0xef7f_ffff: Reserved
+ * @entry: 0xef00_0000: 0xef0f_ffff: CCSR/IMMR
+ * @entry: 0xe900_0000: 0xeeff_ffff: Reserved
+ * @entry: 0xe880_0000: 0xe8ff_ffff: PCI Express 2 I/O
+ * @entry: 0xe800_0000: 0xe87f_ffff: PCI Express 1 I/O
+ * @entry: 0xe000_0000: 0xe7ff_ffff: SRAM/SSRAM/L1 Cache
+ * @entry: 0xd000_0000: 0xdfff_ffff: Reserved
+ * @entry: 0xc000_0000: 0xcfff_ffff: PCI Express 2 Memory
+ * @entry: 0x8000_0000: 0xbfff_ffff: PCI Express 1 Memory
+ * @entry: 0x0000_0000: 0x7fff_ffff: DDR2 SDRAM
+ */
+
 #define CONFIG_SYS_LBC_LCRR	(LCRR_CLKDIV_4 | LCRR_EADC_3)
 
 /*
@@ -147,6 +174,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
 #define CONFIG_SYS_FLASH_AUTOPROTECT_LIST	{ {0xfff40000, 0xc0000}, \
 						  {0xf7f40000, 0xc0000} }
 #define CONFIG_SYS_MONITOR_BASE	TEXT_BASE	/* start of monitor */
+#define CONFIG_REDUNDANT_MONITORS
 
 /*
  * Chip select configuration
@@ -435,6 +463,10 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
 #define CONFIG_ENV_SECT_SIZE	0x20000		/* 128k (one sector) for env */
 #define CONFIG_ENV_SIZE		0x8000
 #define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE - (256 * 1024))
+#define	CONFIG_IPADDR		0.0.0.0
+#define CONFIG_SERVERIP		0.0.0.0
+#define CONFIG_GATEWAYIP	0.0.0.0
+#define CONFIG_NETMASK		255.255.0.0
 
 /*
  * Flash memory map:
@@ -450,6 +482,21 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
  * f6f00000 - f7efffff     Sec OS image (16MB)
  * f0000000 - f6efffff     Sec OS Use/Filesystem (111MB)
  */
+
+/**
+ * @memmap: Recommended Flash Memory Map
+ * @entry: 0xfff8_0000: 0xffff_ffff: Primary U-Boot Image
+ * @entry: 0xfff4_0000: 0xfff7_ffff: Primary U-Boot Environment
+ * @entry: 0xfff0_0000: 0xfff3_ffff: Primary Flat-Device Tree
+ * @entry: 0xfef0_0000: 0xffef_ffff: Primary Operating System Image
+ * @entry: 0xf800_0000: 0xfeef_ffff: Primary Operating System Use/Filesystem
+ * @entry: 0xf7f8_0000: 0xf7ff_ffff: Secondary U-Boot Image
+ * @entry: 0xf7f4_0000: 0xf7f7_ffff: Secondary U-Boot Environment
+ * @entry: 0xf7f0_0000: 0xf7f3_ffff: Secondary Flat-Device Tree
+ * @entry: 0xf6f0_0000: 0xf7ef_ffff: Secondary Operating System Image
+ * @entry: 0xf000_0000: 0xf6ef_ffff: Secondary Operating System Use/Filesystem
+ */
+
 #define CONFIG_UBOOT1_ENV_ADDR	MK_STR(0xfff80000)
 #define CONFIG_UBOOT2_ENV_ADDR	MK_STR(0xf7f80000)
 #define CONFIG_FDT1_ENV_ADDR	MK_STR(0xfff00000)
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
@ 2009-07-28 17:49   ` Wolfgang Denk
  2009-07-28 20:40     ` jschmoller
  0 siblings, 1 reply; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-28 17:49 UTC (permalink / raw)
  To: u-boot

Dear John Schmoller,

In message <cover.1248798202.git.jschmoller@xes-inc.com> you wrote:
>  
> I've been working on writing a User's Manual generation tool, and before
> I get too far I'd like to see if this is something the U-Boot community
> would be interested in.  

Anything wrong with the User's Manual generation tool we already have
in use (DUTS) for example to generate the DULG?

> General Control Flow:
> C pre-processor -> doc_stream.pl : pre-processed code gets everything but
> comments with an @ stripped away
> doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
> file
> autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
>  *.tmpl -> uboot-doc : template files are processed into XML
>  *.xml -> xsltproc : XML is converted into desired output format
>  *.fo -> fop : (PDFs only) fo files are translated to PDF

What you describe does not sound like a user's manual to me, but more
like some API documentation - whioch is a completely different  thing
(and something we really don't have yet).

Your approach may be suitable for standard  documents,  but  in  many
years  of  working  with U-Boot (and Linux) we found that it does not
work so well with the specific needs we have for a User's Manual. One
issue is that you have to support many different boards (well,  maybe
not  you  as  a user, but we as a community). And you have to include
examples. And examples must really fit the board. If you for  example
provide  a  manual entry for the "erase" command you better make sure
that your example does not erase a range of flash that on some  board
happens to hold the U-Boot image. etc.

That's how we came to the DULG we have today. I'm still convinced that
this is a really well-working approach.

It seems you don;t address this issue yet.


> I see several advantages to adopting this scheme.
>  - Documentation should be easier to keep in sync with code

Better than what we have with the DULG? I doubt it.

>  - DocBook XML output can be used to generate webpages, PDFs, text, etc, 
>    which are all extensible

We do the same with the DULG.

>  - People don't have to reinvent the wheel when writing documentation

Well, you just did that, it seems ;-)

>  - Source code ends up being thouroughly commented
> 
> These patches are just meant to be an example of how in-code documentation
> could be used. You'll also notice there are many warnings regarding variables
> the manual is referencing which aren't defined yet. I wanted to get some
> feedback before diving in too far. What do others think? Is this worth
> pursuing?

Hm... we cannot look at your patches, you just posted the patch
statistics, but no content.

The documentation itself seems to duplicate a lot of content we  have
in  the  DULG.  I  have  to  admit  that I'd prefer to see the effort
invested in improving the existing  manual,  than  to  come  up  with
something different (and, as it seems, less flexible).

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Reader, suppose you were an idiot. And suppose you were a  member  of
Congress. But I repeat myself.                           - Mark Twain

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc
  2009-07-28 16:34 ` [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc John Schmoller
@ 2009-07-28 17:52   ` Wolfgang Denk
  2009-07-28 20:42     ` jschmoller
  0 siblings, 1 reply; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-28 17:52 UTC (permalink / raw)
  To: u-boot

Dear John Schmoller,

In message <310e8398479f23a6bfaceccf6cc86631b7bff4dc.1248798202.git.jschmoller@xes-inc.com> you wrote:
> Add support to a small subset of commands, environment
> variables, and POSTs. These are meant to show the
> syntax and capabilities of the uboot-doc parser.
> 
> Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
> ---
>  common/cmd_i2c.c    |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  common/cmd_mem.c    |   45 +++++++++++++++++++++++++++++++-
>  common/cmd_net.c    |   30 ++++++++++++++++++++-
>  common/env_common.c |   35 +++++++++++++++++++++++++
>  post/tests.c        |   16 +++++++++++
>  5 files changed, 192 insertions(+), 5 deletions(-)
> 
> diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
> index 8f0fc9e..14d394c 100644
> --- a/common/cmd_i2c.c
> +++ b/common/cmd_i2c.c
> @@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
>  }
>  
>  /***************************************************/
> -
> +/**
> + * @cmd: i2c speed
> + * @sect: I2C
> + * @param[or]: speed - target I2C bus speed
> + * @desc: Show or set I2C bus speed
> + */
> +/**
> + * @cmd: i2c dev
> + * @sect: I2C
> + * @param[or]: dev - I2C device to make current
> + * @desc: Show or set current I2C bus
> + */
> +/**
> + * @cmd: i2c md
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param[or]: # of objects - Numer of bytes to read
> + * @desc: Read from I2C device
> + */
> +/**
> + * @cmd: i2c mm
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @desc: Write to I2C device (auto-incrementing)
> + */
> +/**
> + * @cmd: i2c mw
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: value - Value to write to I2C address
> + * @param[or]: count - Number of bytes to write
> + * @desc: Write to I2C device (fill)
> + */
> +/**
> + * @cmd: i2c nm
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @desc: Write to I2C device (constant address)
> + */
> +/**
> + * @cmd: i2c crc32
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: count - Number of bytes to CRC
> + * @desc: Computes the CRC32 checksum of an address range
> + */
> +/**
> + * @cmd: i2c probe
> + * @sect: I2C
> + * @desc: Shows all the devices on the I2C bus
> + */
> +/**
> + * @cmd: i2c loop
> + * @sect: I2C
> + * @param: chip - I2C address of desired device
> + * @param: address[.0, .1, .2] - Address into I2C device
> + * @param: # of objects - Number of bytes to loop over
> + * @desc: Looping read of device.  Never returns.
> + */

Hm... isn't this basicly duplicating the information you get when
running the "help" command? Then why don't you simply include that
output here, like we do in the DULG?

To me this seems to be a mix of API documentation (which would be
useful, but you do it for the wrong set of functions) and User's
Manual (where it mostly seems to be a duplication of information, and
maintaining redundant information has never been a good idea).

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It's certainly  convenient  the  way  the  crime  (or  condition)  of
stupidity   carries   with   it  its  own  punishment,  automatically
admisistered without remorse, pity, or prejudice. :-)
         -- Tom Christiansen in <559seq$ag1$1@csnews.cs.colorado.edu>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 17:49   ` Wolfgang Denk
@ 2009-07-28 20:40     ` jschmoller
  2009-07-28 21:27       ` Wolfgang Denk
  0 siblings, 1 reply; 716+ messages in thread
From: jschmoller @ 2009-07-28 20:40 UTC (permalink / raw)
  To: u-boot

On Tue, 2009-07-28 at 19:49 +0200, Wolfgang Denk wrote:
> Dear John Schmoller,
> 
> In message <cover.1248798202.git.jschmoller@xes-inc.com> you wrote:
> >  
> > I've been working on writing a User's Manual generation tool, and before
> > I get too far I'd like to see if this is something the U-Boot community
> > would be interested in.  
> 
> Anything wrong with the User's Manual generation tool we already have
> in use (DUTS) for example to generate the DULG?

I have to admit, I'm not very familiar with DUTS, so read up a little on
it before responding.  So please correct me if I've misinterpreted
something.

It seems to me that DUTS is designed to test U-Boot and also automates
the running of commands whose output can be put online in the DULG. I
didn't notice any documented procedure on how to turn the DULG into XML,
extensible PDFs, etc. It also seems as if the DULG is a combination of
hand-edited wiki pages as well as the DUTS output? I was hoping to
develop a system that's completely automated. I also noticed in a quick
probe around that a few items in the DULG seem to be out of sync (imd
vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
as well. Is the process for updating the DULG automatic? If so, how is
it done?

> 
> > General Control Flow:
> > C pre-processor -> doc_stream.pl : pre-processed code gets everything but
> > comments with an @ stripped away
> > doc_stream.pl -> autoconf_doc.txt : "interesting" comments get sent to this
> > file
> > autoconf_doc.txt -> uboot-doc : file is parsed and comments are turned to XML
> >  *.tmpl -> uboot-doc : template files are processed into XML
> >  *.xml -> xsltproc : XML is converted into desired output format
> >  *.fo -> fop : (PDFs only) fo files are translated to PDF
> 
> What you describe does not sound like a user's manual to me, but more
> like some API documentation - whioch is a completely different  thing
> (and something we really don't have yet).

As I mentioned, I borrowed this idea from the kernel-doc script in
Linux, which does do API documentation.  But my hope for the uboot-doc
tool would be to create user documentation, or a manual we'd provide to
a customer when they purchased a product that would describe available
commands, environment variables, common operations, etc.

> 
> Your approach may be suitable for standard  documents,  but  in  many
> years  of  working  with U-Boot (and Linux) we found that it does not
> work so well with the specific needs we have for a User's Manual. One
> issue is that you have to support many different boards (well,  maybe
> not  you  as  a user, but we as a community). And you have to include
> examples. And examples must really fit the board. If you for  example
> provide  a  manual entry for the "erase" command you better make sure
> that your example does not erase a range of flash that on some  board
> happens to hold the U-Boot image. etc.

It's my hope that the documentation system I proposed can be made
flexible enough to support things such as this without too much
headache.  That's the hope at least :)

> That's how we came to the DULG we have today. I'm still convinced that
> this is a really well-working approach.
> 
> It seems you don;t address this issue yet.
> 

That's correct, I wanted to get feedback before spending too much time
digging into the details.

> 
> > I see several advantages to adopting this scheme.
> >  - Documentation should be easier to keep in sync with code
> 
> Better than what we have with the DULG? I doubt it.
> 
> >  - DocBook XML output can be used to generate webpages, PDFs, text, etc, 
> >    which are all extensible
> 
> We do the same with the DULG.
> 

This would make DUTS/DULG more appealing.  What is the process of
generating DocBook XML from DUTS/DULG?

> >  - People don't have to reinvent the wheel when writing documentation
> 
> Well, you just did that, it seems ;-)
> 

It's true, I may have. :)  On the other hand, it seems that there are
still a lot of people who are in the same boat.  Most manuals I have
seen from other embedded companies (Freescale, Analog Devices, etc.)
seem to provide their own format/content. Additionally, most companies
will prefer to have their content formatted to match the rest of their
manuals, which is easily done from DocBook XML. Again, if you can do
that with DUTS/DULG, then that's great and probably eliminates the need
for this tool.

> >  - Source code ends up being thouroughly commented
> > 
> > These patches are just meant to be an example of how in-code documentation
> > could be used. You'll also notice there are many warnings regarding variables
> > the manual is referencing which aren't defined yet. I wanted to get some
> > feedback before diving in too far. What do others think? Is this worth
> > pursuing?
> 
> Hm... we cannot look at your patches, you just posted the patch
> statistics, but no content.

This is just the patch series introduction, the actual content appears
in 1-3.

> The documentation itself seems to duplicate a lot of content we  have
> in  the  DULG.  I  have  to  admit  that I'd prefer to see the effort
> invested in improving the existing  manual,  than  to  come  up  with
> something different (and, as it seems, less flexible).

As I mentioned, I'm not all that familiar with the abilities of
DUTS/DULG, but I got the impression that there was still a fair amount
of manual labor involved for each manual.  Thus most people (that I'm
familiar with) provide their own documentation and "reinvent the wheel".
I was hoping that creating documentation from comments in the source
would be easier to maintain and providing DocBook output would allow
others to more easily reuse the U-Boot manual contents.

Thanks for your time,
John

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc
  2009-07-28 17:52   ` Wolfgang Denk
@ 2009-07-28 20:42     ` jschmoller
  2009-07-28 21:37       ` Wolfgang Denk
  0 siblings, 1 reply; 716+ messages in thread
From: jschmoller @ 2009-07-28 20:42 UTC (permalink / raw)
  To: u-boot

On Tue, 2009-07-28 at 19:52 +0200, Wolfgang Denk wrote:
> Dear John Schmoller,
> 
> In message <310e8398479f23a6bfaceccf6cc86631b7bff4dc.1248798202.git.jschmoller@xes-inc.com> you wrote:
> > Add support to a small subset of commands, environment
> > variables, and POSTs. These are meant to show the
> > syntax and capabilities of the uboot-doc parser.
> > 
> > Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
> > ---
> >  common/cmd_i2c.c    |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  common/cmd_mem.c    |   45 +++++++++++++++++++++++++++++++-
> >  common/cmd_net.c    |   30 ++++++++++++++++++++-
> >  common/env_common.c |   35 +++++++++++++++++++++++++
> >  post/tests.c        |   16 +++++++++++
> >  5 files changed, 192 insertions(+), 5 deletions(-)
> > 
> > diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
> > index 8f0fc9e..14d394c 100644
> > --- a/common/cmd_i2c.c
> > +++ b/common/cmd_i2c.c
> > @@ -1297,7 +1297,70 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
> >  }
> >  
> >  /***************************************************/
> > -
> > +/**
> > + * @cmd: i2c speed
> > + * @sect: I2C
> > + * @param[or]: speed - target I2C bus speed
> > + * @desc: Show or set I2C bus speed
> > + */
> > +/**
> > + * @cmd: i2c dev
> > + * @sect: I2C
> > + * @param[or]: dev - I2C device to make current
> > + * @desc: Show or set current I2C bus
> > + */
> > +/**
> > + * @cmd: i2c md
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param[or]: # of objects - Numer of bytes to read
> > + * @desc: Read from I2C device
> > + */
> > +/**
> > + * @cmd: i2c mm
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @desc: Write to I2C device (auto-incrementing)
> > + */
> > +/**
> > + * @cmd: i2c mw
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: value - Value to write to I2C address
> > + * @param[or]: count - Number of bytes to write
> > + * @desc: Write to I2C device (fill)
> > + */
> > +/**
> > + * @cmd: i2c nm
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @desc: Write to I2C device (constant address)
> > + */
> > +/**
> > + * @cmd: i2c crc32
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: count - Number of bytes to CRC
> > + * @desc: Computes the CRC32 checksum of an address range
> > + */
> > +/**
> > + * @cmd: i2c probe
> > + * @sect: I2C
> > + * @desc: Shows all the devices on the I2C bus
> > + */
> > +/**
> > + * @cmd: i2c loop
> > + * @sect: I2C
> > + * @param: chip - I2C address of desired device
> > + * @param: address[.0, .1, .2] - Address into I2C device
> > + * @param: # of objects - Number of bytes to loop over
> > + * @desc: Looping read of device.  Never returns.
> > + */
> 
> Hm... isn't this basicly duplicating the information you get when
> running the "help" command? Then why don't you simply include that
> output here, like we do in the DULG?
> 
> To me this seems to be a mix of API documentation (which would be
> useful, but you do it for the wrong set of functions) and User's
> Manual (where it mostly seems to be a duplication of information, and
> maintaining redundant information has never been a good idea).
> 

It's true, I was a little lax on commenting the I2C commands. If I were
to move forward with this documentation tool, I would comment these
commands more thoroughly like I did with the Memory commands.

Thanks,
John

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 20:40     ` jschmoller
@ 2009-07-28 21:27       ` Wolfgang Denk
  2009-07-28 22:16         ` Robin Getz
  2009-07-29 14:48         ` jschmoller
  0 siblings, 2 replies; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-28 21:27 UTC (permalink / raw)
  To: u-boot

Dear John,

in message <1248813631.3915.102.camel@johns> you wrote:
>
> It seems to me that DUTS is designed to test U-Boot and also automates
> the running of commands whose output can be put online in the DULG. I

Correct. And the DULG itself is a wiki (TWiki at the moment, to be
converted to Foswiki ASAP) based framework which holds the "static"
parts of the documentation.

> didn't notice any documented procedure on how to turn the DULG into XML,
> extensible PDFs, etc. It also seems as if the DULG is a combination of
> hand-edited wiki pages as well as the DUTS output? I was hoping to

You probably can export the DULG into XML, too - but what would that
be good for? At the moment we export it into PDF, PostScript, HTML and
plain text.

> develop a system that's completely automated. I also noticed in a quick

Hm... "completely automated" is a nice buzzword, but you still have to
write the documentation in the first place.

The nice thing of the wiki based approach is that you can have a
(even random) collection of pages which can be "linearized" and
brought into arbitrary sets of linear doucumentation - this is what
the WebOrder pages are good for - see
http://www.denx.de/wiki/DULG/WebOrder

So you can use the same set of wiki pages an genreate for example the
full fledged manual, a short version including only the most
significant topics and an extended version including other stuff that
is normally not part of the manual - all from the same envrionment.

> probe around that a few items in the DULG seem to be out of sync (imd
> vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
> as well. Is the process for updating the DULG automatic? If so, how is
> it done?

Soemone still has to write the documentation - and this is not always
done  in  sync  with  the  code.  Your  approach  of  including   the
documentation  with  the  source  code  makes it more likely that one
remebers to update the docs as  well,  but  just  remember  how  many
places  there  are  where  code  and  comments  don't agree - it's no
guarantee either.

If you find such areas in the DULG that are out of sync or missing
please feel free to add them - everybody can contribute and modify the
pages or add new content. And everyboidy can modify and extend the
DUTS test cases, too.

> As I mentioned, I borrowed this idea from the kernel-doc script in
> Linux, which does do API documentation.  But my hope for the uboot-doc
> tool would be to create user documentation, or a manual we'd provide to
> a customer when they purchased a product that would describe available
> commands, environment variables, common operations, etc.

That's what the DULG does, so you are truely duplicating efforts.

> > Your approach may be suitable for standard  documents,  but  in  many
> > years  of  working  with U-Boot (and Linux) we found that it does not
> > work so well with the specific needs we have for a User's Manual. One
> > issue is that you have to support many different boards (well,  maybe
> > not  you  as  a user, but we as a community). And you have to include
> > examples. And examples must really fit the board. If you for  example
> > provide  a  manual entry for the "erase" command you better make sure
> > that your example does not erase a range of flash that on some  board
> > happens to hold the U-Boot image. etc.
> 
> It's my hope that the documentation system I proposed can be made
> flexible enough to support things such as this without too much
> headache.  That's the hope at least :)

Heh. Look at the DULG implementation... it's simple for the first 3 or
4 boards, especially when these are similar. But try supporting ARM
and PowerPC and MIPS boards from N different vendors, with different
kernel versions etc.

> This would make DUTS/DULG more appealing.  What is the process of
> generating DocBook XML from DUTS/DULG?

What would you need DocBook XML for?

> It's true, I may have. :)  On the other hand, it seems that there are
> still a lot of people who are in the same boat.  Most manuals I have
> seen from other embedded companies (Freescale, Analog Devices, etc.)
> seem to provide their own format/content. Additionally, most companies
> will prefer to have their content formatted to match the rest of their
> manuals, which is easily done from DocBook XML. Again, if you can do
> that with DUTS/DULG, then that's great and probably eliminates the need
> for this tool.

Ah, I see.

Well, we use htmldoc to generate .pdf and .ps files from HTML; you
could for example use Tidy to convert HTML to DocBook (and I'm sure
there are lots of other tools that can do that).

> > Hm... we cannot look at your patches, you just posted the patch
> > statistics, but no content.
> 
> This is just the patch series introduction, the actual content appears
> in 1-3.

Yes, I know. Sorry, patches arrived shortly after I started replying,
and I didn;t notice.

> As I mentioned, I'm not all that familiar with the abilities of
> DUTS/DULG, but I got the impression that there was still a fair amount
> of manual labor involved for each manual.  Thus most people (that I'm

Indeed there is a lot of manual labor involved in preparing and
updating the documentation (the framework, that is; once a board has
been configured and added to DUTS, generating the needed include
files is mostly an automatic procedure - just the upload of the files
to the web server has to be triggered manually, but even this is
scripted).

But you have to spend at least the same amount of writing and updating
the documentation, don't you?

> I was hoping that creating documentation from comments in the source
> would be easier to maintain and providing DocBook output would allow
> others to more easily reuse the U-Boot manual contents.

A very, very old version of the DULG was set up like this, using a set
of Perl scripts and generating DokBoot output. We switched to the wiki
based approach some 6 years ago, and I never had the slightest wish to
switch back.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I had the rare misfortune of being one of the first people to try and
implement a PL/1 compiler.                             -- T. Cheatham

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc
  2009-07-28 20:42     ` jschmoller
@ 2009-07-28 21:37       ` Wolfgang Denk
  0 siblings, 0 replies; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-28 21:37 UTC (permalink / raw)
  To: u-boot

Dear John,

in message <1248813749.3915.104.camel@johns> you wrote:
>
> It's true, I was a little lax on commenting the I2C commands. If I were
> to move forward with this documentation tool, I would comment these
> commands more thoroughly like I did with the Memory commands.

Hm... of course I'm biased. Everybody thinks his own solution is the
best of all. On the other hand, the DUTS/DULG setup has been under
continuous development for more than 6 years (8 years if you nclude
the old DocBook based approach). We have used it both for quality
assurance and for documentation purposes with a number of customers.
On our web server you can find board-specific versions for close to 40
different boards (OK, some of these are not maintained any more
[because the respective board vendors don't care]), so you can be
pretty sure that a lot of experience went into this to make this easy
and efficient to handle and to make sure it scales well.

Maybe you find the time to try to get DUTS running for one of your
boards; for the beginning, a manually controlled setup would be
sufficient - running in fully automatic mode like we do in our virtual
lab not needed for such a first test. If you send us a tarball with
the generated log files, we can put these on our web server, so you
can test yourself with minimal effort what such a version of the
documentation looks like.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Forty two.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 21:27       ` Wolfgang Denk
@ 2009-07-28 22:16         ` Robin Getz
  2009-07-30  9:59           ` Detlev Zundel
  2009-07-29 14:48         ` jschmoller
  1 sibling, 1 reply; 716+ messages in thread
From: Robin Getz @ 2009-07-28 22:16 UTC (permalink / raw)
  To: u-boot

On Tue 28 Jul 2009 17:27, Wolfgang Denk pondered:
> Dear John,
> 
> in message <1248813631.3915.102.camel@johns> you wrote:
> >
> > It seems to me that DUTS is designed to test U-Boot and also automates
> > the running of commands whose output can be put online in the DULG. I
> 
> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
> converted to Foswiki ASAP) based framework which holds the "static"
> parts of the documentation.

While we are on the topics of wikis, and U-Boot docs, can we discuss the 
license?

http://www.denx.de/wiki/view/DULG/Introduction#Section_2.1.

Since it is "is not permitted to sell this document or the derivative work or 
to include it into any package or distribution that is not freely available 
to everybody."

Not meaning to interpret licensing, but to me that means I can't copy/paste 
sections into end product documentation, and ship the product for a fee...

Was that the intent?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 21:27       ` Wolfgang Denk
  2009-07-28 22:16         ` Robin Getz
@ 2009-07-29 14:48         ` jschmoller
  1 sibling, 0 replies; 716+ messages in thread
From: jschmoller @ 2009-07-29 14:48 UTC (permalink / raw)
  To: u-boot

On Tue, 2009-07-28 at 23:27 +0200, Wolfgang Denk wrote:
> Dear John,
> 
> in message <1248813631.3915.102.camel@johns> you wrote:
> >
> > It seems to me that DUTS is designed to test U-Boot and also automates
> > the running of commands whose output can be put online in the DULG. I
> 
> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
> converted to Foswiki ASAP) based framework which holds the "static"
> parts of the documentation.
> 
> > didn't notice any documented procedure on how to turn the DULG into XML,
> > extensible PDFs, etc. It also seems as if the DULG is a combination of
> > hand-edited wiki pages as well as the DUTS output? I was hoping to
> 
> You probably can export the DULG into XML, too - but what would that
> be good for? At the moment we export it into PDF, PostScript, HTML and
> plain text.

Exporting to XML (and specifically DocBook XML, which is widely
supported and accepted as a standard (at least that's what the tech
writer next to me says :) ) is, I feel, a key to this whole process.
Since XML doesn't specify a style, but rather what the content *means*,
style sheets can be designed to turn the DocBook XML into anything, in
any format, rearranged in any way, and with any style (fonts, colors,
graphics).  Again, I'm not familiar with the process you use to export
HTML to PFD, PS, etc. but I'm guessing that the formatting and style end
up being very similar.

> > develop a system that's completely automated. I also noticed in a quick
> 
> Hm... "completely automated" is a nice buzzword, but you still have to
> write the documentation in the first place.

You're in luck, I've already volunteered to write it in the first
place :) and much of it is already done.  Take a look at the manual
posted on the X-ES website and see for yourself.
http://www.xes-inc.com/sources/u-boot/xpedite5370.pdf This manual was
completely generated with my tool.

> The nice thing of the wiki based approach is that you can have a
> (even random) collection of pages which can be "linearized" and
> brought into arbitrary sets of linear doucumentation - this is what
> the WebOrder pages are good for - see
> http://www.denx.de/wiki/DULG/WebOrder
> 
> So you can use the same set of wiki pages an genreate for example the
> full fledged manual, a short version including only the most
> significant topics and an extended version including other stuff that
> is normally not part of the manual - all from the same envrionment.

This is definitely possible with DocBook XML.  For those who care, I'm
thinking the @role attribute available in standard DocBook, though there
may be a better way.  I'll talk this through with our tech writers.

> > probe around that a few items in the DULG seem to be out of sync (imd
> > vs. i2c md, source vs. autoscr, etc.) and DHCP seems to be out of date
> > as well. Is the process for updating the DULG automatic? If so, how is
> > it done?
> 
> Soemone still has to write the documentation - and this is not always
> done  in  sync  with  the  code.  Your  approach  of  including   the
> documentation  with  the  source  code  makes it more likely that one
> remebers to update the docs as  well,  but  just  remember  how  many
> places  there  are  where  code  and  comments  don't agree - it's no
> guarantee either.

I would guess someone is several dozen times more likely to update a
documentation snippet in the source over modifying a Wiki page.

> If you find such areas in the DULG that are out of sync or missing
> please feel free to add them - everybody can contribute and modify the
> pages or add new content. And everyboidy can modify and extend the
> DUTS test cases, too.
> 
> > As I mentioned, I borrowed this idea from the kernel-doc script in
> > Linux, which does do API documentation.  But my hope for the uboot-doc
> > tool would be to create user documentation, or a manual we'd provide to
> > a customer when they purchased a product that would describe available
> > commands, environment variables, common operations, etc.
> 
> That's what the DULG does, so you are truely duplicating efforts.

As I mentioned earlier, it seems to me that most vendors are creating
their own manuals.  That either means knowledge of the existence of DULG
is limited, or the tool isn't meeting people's needs.  In order to use
it, you need to download a completely separate package (DUTS), learn to
use it, then hand edit the output into a Wiki page.  The advantage with
a documentation engine distributed with the sources is that there is no
learning curve.  "make pdf" creates a perfectly suitable PDF manual, and
with a little work (first time only) they can make it look like anything
and chug out manuals for all their boards in minutes.

> > > Your approach may be suitable for standard  documents,  but  in  many
> > > years  of  working  with U-Boot (and Linux) we found that it does not
> > > work so well with the specific needs we have for a User's Manual. One
> > > issue is that you have to support many different boards (well,  maybe
> > > not  you  as  a user, but we as a community). And you have to include
> > > examples. And examples must really fit the board. If you for  example
> > > provide  a  manual entry for the "erase" command you better make sure
> > > that your example does not erase a range of flash that on some  board
> > > happens to hold the U-Boot image. etc.
> > 
> > It's my hope that the documentation system I proposed can be made
> > flexible enough to support things such as this without too much
> > headache.  That's the hope at least :)
> 
> Heh. Look at the DULG implementation... it's simple for the first 3 or
> 4 boards, especially when these are similar. But try supporting ARM
> and PowerPC and MIPS boards from N different vendors, with different
> kernel versions etc.

That, I believe, is one of the strengths of the tool I created.  First,
it uses the C pre-compiler to conditionally include comments from
source.  Secondly, the common XML templates support pre-compiler
directives, so you can #ifdef in a section only when such-and-such is
defined.  And finally, if your manual requirements are dramatically
different than others, a whole template can be overridden (or a whole
new template added or deleted) in the board/${BOARDDIR}/manual
directory.  In my opinion, that's pretty flexible.

> > This would make DUTS/DULG more appealing.  What is the process of
> > generating DocBook XML from DUTS/DULG?
> 
> What would you need DocBook XML for?

As I mentioned above, I think the presence of DocBook XML is crucial to
gain wide acceptance.  When people see that this tool can generate
manuals that look just like the manuals they offer now, I think that
will make the sale.

> > It's true, I may have. :)  On the other hand, it seems that there are
> > still a lot of people who are in the same boat.  Most manuals I have
> > seen from other embedded companies (Freescale, Analog Devices, etc.)
> > seem to provide their own format/content. Additionally, most companies
> > will prefer to have their content formatted to match the rest of their
> > manuals, which is easily done from DocBook XML. Again, if you can do
> > that with DUTS/DULG, then that's great and probably eliminates the need
> > for this tool.
> 
> Ah, I see.
> 
> Well, we use htmldoc to generate .pdf and .ps files from HTML; you
> could for example use Tidy to convert HTML to DocBook (and I'm sure
> there are lots of other tools that can do that).

XML specifies what the data means.  HTML specifies what the data should
look like.  In my head, it's intuitive to say titles should be big and
bold, but it's not intuitive to say big and bold should be a title. The
conversion is imperfect.  DocBook has a page on doing just that, and
it's 5 steps which would probably several hours to get right for each
manual.
http://wiki.docbook.org/topic/Html2DocBook

> > > Hm... we cannot look at your patches, you just posted the patch
> > > statistics, but no content.
> > 
> > This is just the patch series introduction, the actual content appears
> > in 1-3.
> 
> Yes, I know. Sorry, patches arrived shortly after I started replying,
> and I didn;t notice.
> 
> > As I mentioned, I'm not all that familiar with the abilities of
> > DUTS/DULG, but I got the impression that there was still a fair amount
> > of manual labor involved for each manual.  Thus most people (that I'm
> 
> Indeed there is a lot of manual labor involved in preparing and
> updating the documentation (the framework, that is; once a board has
> been configured and added to DUTS, generating the needed include
> files is mostly an automatic procedure - just the upload of the files
> to the web server has to be triggered manually, but even this is
> scripted).
> 
> But you have to spend at least the same amount of writing and updating
> the documentation, don't you?

At least the way I see it, with your tool there's a fair amount of
manual labor for every manual.  With my tool, it's a similar amount of
manual labor once for everyone in the whole community.  Say we add a new
command, it's extra work to comment it properly, but then everyone in
the community reaps the benefits.  Or more complexly, we add an entirely
new interface of some sort, and a whole new manual section needs to be
written.  Someone writes it once and everyone in the community can reuse
that section.  And sure, you could do that with the DULG, but that's
copy-and-paste-and-edit manual labor.  For this tool, it would either be
just run "make pdf" again, or possibly add a #define to your config file
and then run "make pdf".

> > I was hoping that creating documentation from comments in the source
> > would be easier to maintain and providing DocBook output would allow
> > others to more easily reuse the U-Boot manual contents.
> 
> A very, very old version of the DULG was set up like this, using a set
> of Perl scripts and generating DokBoot output. We switched to the wiki
> based approach some 6 years ago, and I never had the slightest wish to
> switch back.

I do see the benefit of using a wiki, but I feel that it doesn't fit the
needs of many U-Boot developers who need to generate documentation in a
variety of styles and formats.  I have to assume the vast majority of
current U-Boot developers are rolling their own documentation as most
boards are not supported by DULG.  My hope is that if we generated
U-Boot User's manuals in a different, easier manner with a more flexible
output many more people could use it, thereby saving time which they can
put to improving U-Boot itself :)

Thanks,
John

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-28 22:16         ` Robin Getz
@ 2009-07-30  9:59           ` Detlev Zundel
  2009-07-30 18:45             ` Wolfgang Denk
  2009-08-13  7:32             ` Mike Frysinger
  0 siblings, 2 replies; 716+ messages in thread
From: Detlev Zundel @ 2009-07-30  9:59 UTC (permalink / raw)
  To: u-boot

Hi Robin,

> On Tue 28 Jul 2009 17:27, Wolfgang Denk pondered:
>> Dear John,
>> 
>> in message <1248813631.3915.102.camel@johns> you wrote:
>> >
>> > It seems to me that DUTS is designed to test U-Boot and also automates
>> > the running of commands whose output can be put online in the DULG. I
>> 
>> Correct. And the DULG itself is a wiki (TWiki at the moment, to be
>> converted to Foswiki ASAP) based framework which holds the "static"
>> parts of the documentation.
>
> While we are on the topics of wikis, and U-Boot docs, can we discuss the 
> license?
>
> http://www.denx.de/wiki/view/DULG/Introduction#Section_2.1.
>
> Since it is "is not permitted to sell this document or the derivative work or 
> to include it into any package or distribution that is not freely available 
> to everybody."
>
> Not meaning to interpret licensing, but to me that means I can't copy/paste 
> sections into end product documentation, and ship the product for a fee...

That's how it is currently, yes.

> Was that the intent?

Not really - but I'll better let Wolfgang answer that question as he
came up with the original licence text.

It is on my priority list however to assemble a list of all contributors
and ask them if they agree to relicence their contributions under the
FDL.

Cheers
  Detlev

-- 
Each language has its purpose, however humble. Each language expresses
the Yin and Yang of software. Each language has its place within the Tao.

But do not program in COBOL if you can avoid it.
                           -- The Tao of Programming
--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-30  9:59           ` Detlev Zundel
@ 2009-07-30 18:45             ` Wolfgang Denk
  2009-07-30 19:50               ` Robin Getz
  2009-08-13  7:32             ` Mike Frysinger
  1 sibling, 1 reply; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-30 18:45 UTC (permalink / raw)
  To: u-boot

Hi,

In message <m2eiryebkk.fsf@ohwell.denx.de> Detlev Zundel wrote:
...
> > Not meaning to interpret licensing, but to me that means I can't copy/paste 
> > sections into end product documentation, and ship the product for a fee...
> 
> That's how it is currently, yes.
> 
> > Was that the intent?
> 
> Not really - but I'll better let Wolfgang answer that question as he
> came up with the original licence text.

Originally this actualy has been my intent. But that was a long, long
time ago, back when I was writing all  these  documentation  only  by
myself.

> It is on my priority list however to assemble a list of all contributors
> and ask them if they agree to relicence their contributions under the
> FDL.

Consider my permission as granted :-)

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Celestial navigation is based on the premise that the  Earth  is  the
center  of  the  universe.  The  premise is wrong, but the navigation
works. An incorrect model can be a useful tool.   - Kelvin Throop III

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-30 18:45             ` Wolfgang Denk
@ 2009-07-30 19:50               ` Robin Getz
  2009-07-30 19:55                 ` Wolfgang Denk
  0 siblings, 1 reply; 716+ messages in thread
From: Robin Getz @ 2009-07-30 19:50 UTC (permalink / raw)
  To: u-boot

On Thu 30 Jul 2009 14:45, Wolfgang DenkVersion 1.3 pondered:
> Hi,
> 
> In message <m2eiryebkk.fsf@ohwell.denx.de> Detlev Zundel wrote:
> ...
> > > Not meaning to interpret licensing, but to me that means I 
> > > can't copy/paste sections into end product documentation, and ship
> > > the product for a fee... 
> > 
> > That's how it is currently, yes.
> > 
> > > Was that the intent?
> > 
> > Not really - but I'll better let Wolfgang answer that question as he
> > came up with the original licence text.
> 
> Originally this actualy has been my intent. But that was a long, long
> time ago, back when I was writing all  these  documentation  only  by
> myself.
> 
> > It is on my priority list however to assemble a list of all contributors
> > and ask them if they agree to relicence their contributions under the
> > FDL.
> 
> Consider my permission as granted :-)

I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover 
Texts? or did you desire something else?

Since Front-Cover Text is limited to 5 words, and Back-Cover Text is limited 
to 25 words - how about (as Back-Cover Text) "This manual includes sections 
from the Das U-Boot documentation, which can be found at 
http://www.denx.de/wiki/U-Boot and is copyright it's authors. Included under 
the Free Documentation License (v1.3)"

?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-30 19:50               ` Robin Getz
@ 2009-07-30 19:55                 ` Wolfgang Denk
  2009-07-31  1:49                   ` Robin Getz
  0 siblings, 1 reply; 716+ messages in thread
From: Wolfgang Denk @ 2009-07-30 19:55 UTC (permalink / raw)
  To: u-boot

Dear Robin Getz,

In message <200907301550.40651.rgetz@blackfin.uclinux.org> you wrote:
>
> I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover 
> Texts? or did you desire something else?

We don't have such detailed plans yet. I see no need for Invariant
Sections.

> Since Front-Cover Text is limited to 5 words, and Back-Cover Text is limited 
> to 25 words - how about (as Back-Cover Text) "This manual includes sections 
> from the Das U-Boot documentation, which can be found at 
> http://www.denx.de/wiki/U-Boot and is copyright it's authors. Included under 
> the Free Documentation License (v1.3)"
> 
> ?

Maybe something like that. Thanks for the proposal :-)

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Einstein argued that there must be simplified explanations of nature,
because God is not capricious or arbitrary. No  such  faith  comforts
the software engineer.                             - Fred Brooks, Jr.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-30 19:55                 ` Wolfgang Denk
@ 2009-07-31  1:49                   ` Robin Getz
  0 siblings, 0 replies; 716+ messages in thread
From: Robin Getz @ 2009-07-31  1:49 UTC (permalink / raw)
  To: u-boot

On Thu 30 Jul 2009 15:55, Wolfgang Denk pondered:
> Dear Robin Getz,
> 
> In message <200907301550.40651.rgetz@blackfin.uclinux.org> you wrote:
> >
> > I assume - no Invariant Sections, no Front-Cover Texts, and no Back-Cover 
> > Texts? or did you desire something else?
> 
> We don't have such detailed plans yet. 

Depending on the exact final plans, Analog Devices would be happy to donate 
anything from the U-Boot documentation we have created over the past few 
years....

https://docs.blackfin.uclinux.org/doku.php?id=bootloaders:u-boot

While the examples are Blackfin specific, most should be generic enough to 
ensure that the reader should understand what to do on their architecture. We 
see maintaining something separate a duplication of effort, and wasted 
resources spent on documentation creation (which is a task most developers 
don't like anyways)...


I think Mike brought this up awhile ago - 
http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg04491.html

Which gets back to the original question...

On Thu, 17 Apr 2008 11:02:18 -0700 Mike Frysinger pondered:
> On Thursday 17 April 2008, Detlev Zundel wrote:
> > Hi Mike,
> >
> > > On Monday 14 April 2008, Detlev Zundel wrote:
> > >> > we maintain a Blackfin-specific u-boot wiki that goes into quite a
> > >> > bit of detail, some of which is duplicated with the main u-boot
> > >> > wiki.  how do people feel about extending the u-boot wiki to allow
> > >> > for arch-specific details ?
> > >>
> > >> What exactly do you have in mind?  I surely don't see any principal
> > >> problem here.
> > >>
> > >> It would certainly be valuable to get all U-Boot related info
> > >> collected in a central place and have pointers wherever that make
> > >> sense...
> > >
> > > from my reading of the wiki, it's more of a technical/command reference
> > > than a guide.  the wiki we maintain is geared to be more of a guide.  i
> > > think the two can be merged, i just dont want to convert things only to
> > > find out people dont want to take it that direction.
> >
> > Just to be clear, we are discussing the DULG wiki, right?
>
> is there any other worth talking about :)
>
> > I agree that in the current state the documentation is more a reference
> > but IIRC that wasn't really a conscious design decision.  It simply
> > turned out this way in the end.
> >
> > So I do not see any general problem in adding "guide style" sections in
> > there.  Maybe then most of the current documentation can then be shifted
> > to a "commands reference" section.
>
> OK
>
> > One problem I see though is how to correctly adapt such sections to the
> > board specific nature of the DULG.  Hopefully we can get away with
> > mostly generic text passages and only a few ifdefs.  It would be very
> > helpful to know more concrete plans (outline!) to think further about
> > these implications.

Are there any thoughts about this?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool
  2009-07-30  9:59           ` Detlev Zundel
  2009-07-30 18:45             ` Wolfgang Denk
@ 2009-08-13  7:32             ` Mike Frysinger
  1 sibling, 0 replies; 716+ messages in thread
From: Mike Frysinger @ 2009-08-13  7:32 UTC (permalink / raw)
  To: u-boot

On Thursday 30 July 2009 05:59:07 Detlev Zundel wrote:
> It is on my priority list however to assemble a list of all contributors
> and ask them if they agree to relicence their contributions under the
> FDL.

why not CC-BY-SA ?  the wikipedia page has a bunch of references to FDL being 
a bad idea, and even the Debian guys declare it a non-free license.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20090813/46e096a6/attachment.pgp 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/1] perf tools: Up the verbose level for some really verbose stuff
       [not found] <yes>
                   ` (5 preceding siblings ...)
  2009-07-28 16:34 ` [U-Boot] [RFC 3/3] xpedite5370: Add uboot-doc support John Schmoller
@ 2009-10-07 13:49 ` Arnaldo Carvalho de Melo
  2009-10-08 17:31   ` [tip:perf/core] " tip-bot for Arnaldo Carvalho de Melo
  2010-06-22 15:20   ` Suresh Jayaraman
                   ` (84 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Arnaldo Carvalho de Melo @ 2009-10-07 13:49 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Frederic Weisbecker,
	Peter Zijlstra, Paul Mackerras, Mike Galbraith

Like printing every symbol created.

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-annotate.c |    4 ++--
 tools/perf/builtin-report.c   |    4 ++--
 tools/perf/util/symbol.c      |    4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 35ed97b..8c84320 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -658,10 +658,10 @@ more:
 	if (dump_trace)
 		return 0;
 
-	if (verbose >= 3)
+	if (verbose > 3)
 		threads__fprintf(stdout, &threads);
 
-	if (verbose >= 2)
+	if (verbose > 2)
 		dsos__fprintf(stdout);
 
 	collapse__resort();
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 12f8c86..3f0f1a4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -1021,10 +1021,10 @@ done:
 	if (dump_trace)
 		return 0;
 
-	if (verbose >= 3)
+	if (verbose > 3)
 		threads__fprintf(stdout, &threads);
 
-	if (verbose >= 2)
+	if (verbose > 2)
 		dsos__fprintf(stdout);
 
 	collapse__resort();
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 582ce72..a6887f9 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -74,7 +74,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name,
 	if (!self)
 		return NULL;
 
-	if (v >= 2)
+	if (v > 2)
 		printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n",
 			start, (unsigned long)len, name, self->hist);
 
@@ -685,7 +685,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 		}
 
 		if (self->adjust_symbols) {
-			if (v >= 2)
+			if (v > 2)
 				printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
 					(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
 
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [tip:perf/core] perf tools: Up the verbose level for some really verbose stuff
  2009-10-07 13:49 ` [PATCH 1/1] perf tools: Up the verbose level for some really verbose stuff Arnaldo Carvalho de Melo
@ 2009-10-08 17:31   ` tip-bot for Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 716+ messages in thread
From: tip-bot for Arnaldo Carvalho de Melo @ 2009-10-08 17:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, paulus, acme, hpa, mingo, efault, peterz, fweisbec,
	tglx, mingo

Commit-ID:  da21d1b547cbaa2c026cf645753651c25d340923
Gitweb:     http://git.kernel.org/tip/da21d1b547cbaa2c026cf645753651c25d340923
Author:     Arnaldo Carvalho de Melo <acme@redhat.com>
AuthorDate: Wed, 7 Oct 2009 10:49:00 -0300
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 8 Oct 2009 19:27:10 +0200

perf tools: Up the verbose level for some really verbose stuff

Like printing every symbol created.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <1254923340-4870-1-git-send-email-acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 tools/perf/builtin-annotate.c |    4 ++--
 tools/perf/builtin-report.c   |    4 ++--
 tools/perf/util/symbol.c      |    4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 35ed97b..8c84320 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -658,10 +658,10 @@ more:
 	if (dump_trace)
 		return 0;
 
-	if (verbose >= 3)
+	if (verbose > 3)
 		threads__fprintf(stdout, &threads);
 
-	if (verbose >= 2)
+	if (verbose > 2)
 		dsos__fprintf(stdout);
 
 	collapse__resort();
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 87c4582..f57a23b 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -880,10 +880,10 @@ static int __cmd_report(void)
 	if (dump_trace)
 		return 0;
 
-	if (verbose >= 3)
+	if (verbose > 3)
 		threads__fprintf(stdout, &threads);
 
-	if (verbose >= 2)
+	if (verbose > 2)
 		dsos__fprintf(stdout);
 
 	collapse__resort();
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 582ce72..a6887f9 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -74,7 +74,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name,
 	if (!self)
 		return NULL;
 
-	if (v >= 2)
+	if (v > 2)
 		printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n",
 			start, (unsigned long)len, name, self->hist);
 
@@ -685,7 +685,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 		}
 
 		if (self->adjust_symbols) {
-			if (v >= 2)
+			if (v > 2)
 				printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n",
 					(u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset);
 

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 00/10] cifs: local caching support using FS-Cache
       [not found] <yes>
@ 2010-06-22 15:20   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:20 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

This patchset is a first stab at adding persistent, local caching facility for
CIFS using the FS-Cache interface.

The index hierarchy which is mainly used to locate a file object or discard
a certain subset of the files cached, currently has three levels:
	- Server
	- Share 
	- File

The server index object is keyed by hostname of the server. The superblock
index object is keyed by the sharename and the inode object is keyed by the
UniqueId. The cache coherency is ensured by checking the 'LastWriteTime' and
size of file.

To use this, apply this patchset in order, mount the share with rsize=4096 and
try copying a huge file (say few hundred MBs) from mount point to local
filesystem. During the first time, the cache will be initialized. When you copy
the second time, it should read from the local cache.

To reduce the impact of page cache and see the local caching in action
readily, try doing a sync and drop the caches by doing:
	sync; echo 3 > /proc/sys/vm/drop_caches

Known issues
-------------
	- the cache coherency check may not be reliable always as some
	  CIFS servers are known not to update mtime until the filehandle is
	  closed.
	- not all the Servers under all circumstances provide a unique
	  'UniqueId'.

Todo's
-------
	- improvements to avoid potential key collisions
	- address the above known issues

This set is lightly tested and all the bugs seen during my testing have been
fixed. However, this can be considered as an RFC for now.

Any Comments or Suggestions are welcome.

Suresh Jayaraman (10)
  cifs: add kernel config option for CIFS Client caching support
  cifs: guard cifsglob.h against multiple inclusion
  cifs: register CIFS for caching
  cifs: define server-level cache index objects and register them with FS-Cache
  cifs: define superblock-level cache index objects and register them
  cifs: define inode-level cache object and register them
  cifs: FS-Cache page management
  cifs: store pages into local cache
  cifs: read pages from FS-Cache
  cifs: add mount option to enable local caching

 Kconfig      |    9 ++
 Makefile     |    2 
 cache.c      |  251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cifs_fs_sb.h |    1 
 cifsfs.c     |   15 +++
 cifsglob.h   |   14 +++
 connect.c    |   16 +++
 file.c       |   51 +++++++++++
 fscache.c    |  244 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fscache.h    |  135 +++++++++++++++++++++++++++++++
 inode.c      |    4 
 11 files changed, 742 insertions(+)

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 00/10] cifs: local caching support using FS-Cache
@ 2010-06-22 15:20   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:20 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

This patchset is a first stab at adding persistent, local caching facility for
CIFS using the FS-Cache interface.

The index hierarchy which is mainly used to locate a file object or discard
a certain subset of the files cached, currently has three levels:
	- Server
	- Share 
	- File

The server index object is keyed by hostname of the server. The superblock
index object is keyed by the sharename and the inode object is keyed by the
UniqueId. The cache coherency is ensured by checking the 'LastWriteTime' and
size of file.

To use this, apply this patchset in order, mount the share with rsize=4096 and
try copying a huge file (say few hundred MBs) from mount point to local
filesystem. During the first time, the cache will be initialized. When you copy
the second time, it should read from the local cache.

To reduce the impact of page cache and see the local caching in action
readily, try doing a sync and drop the caches by doing:
	sync; echo 3 > /proc/sys/vm/drop_caches

Known issues
-------------
	- the cache coherency check may not be reliable always as some
	  CIFS servers are known not to update mtime until the filehandle is
	  closed.
	- not all the Servers under all circumstances provide a unique
	  'UniqueId'.

Todo's
-------
	- improvements to avoid potential key collisions
	- address the above known issues

This set is lightly tested and all the bugs seen during my testing have been
fixed. However, this can be considered as an RFC for now.

Any Comments or Suggestions are welcome.

Suresh Jayaraman (10)
  cifs: add kernel config option for CIFS Client caching support
  cifs: guard cifsglob.h against multiple inclusion
  cifs: register CIFS for caching
  cifs: define server-level cache index objects and register them with FS-Cache
  cifs: define superblock-level cache index objects and register them
  cifs: define inode-level cache object and register them
  cifs: FS-Cache page management
  cifs: store pages into local cache
  cifs: read pages from FS-Cache
  cifs: add mount option to enable local caching

 Kconfig      |    9 ++
 Makefile     |    2 
 cache.c      |  251 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 cifs_fs_sb.h |    1 
 cifsfs.c     |   15 +++
 cifsglob.h   |   14 +++
 connect.c    |   16 +++
 file.c       |   51 +++++++++++
 fscache.c    |  244 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fscache.h    |  135 +++++++++++++++++++++++++++++++
 inode.c      |    4 
 11 files changed, 742 insertions(+)


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 01/10] cifs: add kernel config option for CIFS Client caching support
       [not found] <yes>
                   ` (7 preceding siblings ...)
  2010-06-22 15:20   ` Suresh Jayaraman
@ 2010-06-22 15:22 ` Suresh Jayaraman
  2010-06-22 15:22 ` [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion Suresh Jayaraman
                   ` (82 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:22 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Add a kernel config option to enable local caching for CIFS.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/Kconfig |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 80f3525..5739fd7 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -131,6 +131,15 @@ config CIFS_DFS_UPCALL
 	    IP addresses) which is needed for implicit mounts of DFS junction
 	    points. If unsure, say N.
 
+config CIFS_FSCACHE
+	  bool "Provide CIFS client caching support (EXPERIMENTAL)"
+	  depends on EXPERIMENTAL
+	  depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
+	  help
+	    Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
+	    to be cached locally on disk through the general filesystem cache
+	    manager. If unsure, say N.
+
 config CIFS_EXPERIMENTAL
 	  bool "CIFS Experimental Features (EXPERIMENTAL)"
 	  depends on CIFS && EXPERIMENTAL
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion
       [not found] <yes>
                   ` (8 preceding siblings ...)
  2010-06-22 15:22 ` [RFC][PATCH 01/10] cifs: add kernel config option for CIFS Client caching support Suresh Jayaraman
@ 2010-06-22 15:22 ` Suresh Jayaraman
       [not found]   ` <1277220170-3442-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
  2010-06-22 15:23   ` Suresh Jayaraman
                   ` (81 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:22 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Add conditional compile macros to guard the header file against multiple
inclusion.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/cifsglob.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a88479c..6b2c39d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -16,6 +16,9 @@
  *   the GNU Lesser General Public License for more details.
  *
  */
+#ifndef _CIFS_GLOB_H
+#define _CIFS_GLOB_H
+
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/slab.h>
@@ -733,3 +736,5 @@ GLOBAL_EXTERN unsigned int cifs_min_small;  /* min size of small buf pool */
 GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
 
 extern const struct slow_work_ops cifs_oplock_break_ops;
+
+#endif	/* _CIFS_GLOB_H */
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 03/10] cifs: register CIFS for caching
       [not found] <yes>
@ 2010-06-22 15:23   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

Define CIFS for FS-Cache and register for caching. Upon registration the
top-level index object cookie will be stuck to the netfs definition by
FS-Cache.

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/cifs/Makefile  |    2 ++
 fs/cifs/cache.c   |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/cifsfs.c  |    8 ++++++++
 fs/cifs/fscache.h |   40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 103 insertions(+), 0 deletions(-)
 create mode 100644 fs/cifs/cache.c
 create mode 100644 fs/cifs/fscache.h

diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 9948c00..e2de709 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -11,3 +11,5 @@ cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
+
+cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
new file mode 100644
index 0000000..1080b96
--- /dev/null
+++ b/fs/cifs/cache.c
@@ -0,0 +1,53 @@
+/*
+ *   fs/cifs/cache.c - CIFS filesystem cache index structure definitions
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include "fscache.h"
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
+/*
+ * CIFS filesystem definition for FS-Cache
+ */
+struct fscache_netfs cifs_fscache_netfs = {
+	.name = "cifs",
+	.version = 0,
+};
+
+/*
+ * Register CIFS for caching with FS-Cache
+ */
+int cifs_fscache_register(void)
+{
+	return fscache_register_netfs(&cifs_fscache_netfs);
+}
+
+/*
+ * Unregister CIFS for caching
+ */
+void cifs_fscache_unregister(void)
+{
+	fscache_unregister_netfs(&cifs_fscache_netfs);
+}
+
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 484e52b..c2a7aa9 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -47,6 +47,7 @@
 #include <linux/key-type.h>
 #include "dns_resolve.h"
 #include "cifs_spnego.h"
+#include "fscache.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42	/* the first four bytes of SMB PDUs */
 
 int cifsFYI = 0;
@@ -902,6 +903,10 @@ init_cifs(void)
 		cFYI(1, "cifs_max_pending set to max of 256");
 	}
 
+	rc = cifs_fscache_register();
+	if (rc)
+		goto out;
+
 	rc = cifs_init_inodecache();
 	if (rc)
 		goto out_clean_proc;
@@ -949,8 +954,10 @@ init_cifs(void)
 	cifs_destroy_mids();
  out_destroy_inodecache:
 	cifs_destroy_inodecache();
+	cifs_fscache_unregister();
  out_clean_proc:
 	cifs_proc_clean();
+ out:
 	return rc;
 }
 
@@ -959,6 +966,7 @@ exit_cifs(void)
 {
 	cFYI(DBG2, "exit_cifs");
 	cifs_proc_clean();
+	cifs_fscache_unregister();
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	cifs_dfs_release_automount_timer();
 	unregister_key_type(&key_type_dns_resolver);
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
new file mode 100644
index 0000000..cec9e2b
--- /dev/null
+++ b/fs/cifs/fscache.h
@@ -0,0 +1,40 @@
+/*
+ *   fs/cifs/fscache.h - CIFS filesystem cache interface definitions
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _CIFS_FSCACHE_H
+#define _CIFS_FSCACHE_H
+
+#include <linux/fscache.h>
+#include "cifsglob.h"
+
+#ifdef CONFIG_CIFS_FSCACHE
+
+extern struct fscache_netfs cifs_fscache_netfs;
+
+extern int cifs_fscache_register(void);
+extern void cifs_fscache_unregister(void);
+
+#else /* CONFIG_CIFS_FSCACHE */
+static inline int cifs_fscache_register(void) { return 0; }
+static inline void cifs_fscache_unregister(void) {}
+
+#endif /* CONFIG_CIFS_FSCACHE */
+
+#endif /* _CIFS_FSCACHE_H */
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 03/10] cifs: register CIFS for caching
@ 2010-06-22 15:23   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Define CIFS for FS-Cache and register for caching. Upon registration the
top-level index object cookie will be stuck to the netfs definition by
FS-Cache.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/Makefile  |    2 ++
 fs/cifs/cache.c   |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/cifsfs.c  |    8 ++++++++
 fs/cifs/fscache.h |   40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 103 insertions(+), 0 deletions(-)
 create mode 100644 fs/cifs/cache.c
 create mode 100644 fs/cifs/fscache.h

diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 9948c00..e2de709 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -11,3 +11,5 @@ cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
+
+cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
new file mode 100644
index 0000000..1080b96
--- /dev/null
+++ b/fs/cifs/cache.c
@@ -0,0 +1,53 @@
+/*
+ *   fs/cifs/cache.c - CIFS filesystem cache index structure definitions
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include "fscache.h"
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
+/*
+ * CIFS filesystem definition for FS-Cache
+ */
+struct fscache_netfs cifs_fscache_netfs = {
+	.name = "cifs",
+	.version = 0,
+};
+
+/*
+ * Register CIFS for caching with FS-Cache
+ */
+int cifs_fscache_register(void)
+{
+	return fscache_register_netfs(&cifs_fscache_netfs);
+}
+
+/*
+ * Unregister CIFS for caching
+ */
+void cifs_fscache_unregister(void)
+{
+	fscache_unregister_netfs(&cifs_fscache_netfs);
+}
+
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 484e52b..c2a7aa9 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -47,6 +47,7 @@
 #include <linux/key-type.h>
 #include "dns_resolve.h"
 #include "cifs_spnego.h"
+#include "fscache.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42	/* the first four bytes of SMB PDUs */
 
 int cifsFYI = 0;
@@ -902,6 +903,10 @@ init_cifs(void)
 		cFYI(1, "cifs_max_pending set to max of 256");
 	}
 
+	rc = cifs_fscache_register();
+	if (rc)
+		goto out;
+
 	rc = cifs_init_inodecache();
 	if (rc)
 		goto out_clean_proc;
@@ -949,8 +954,10 @@ init_cifs(void)
 	cifs_destroy_mids();
  out_destroy_inodecache:
 	cifs_destroy_inodecache();
+	cifs_fscache_unregister();
  out_clean_proc:
 	cifs_proc_clean();
+ out:
 	return rc;
 }
 
@@ -959,6 +966,7 @@ exit_cifs(void)
 {
 	cFYI(DBG2, "exit_cifs");
 	cifs_proc_clean();
+	cifs_fscache_unregister();
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	cifs_dfs_release_automount_timer();
 	unregister_key_type(&key_type_dns_resolver);
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
new file mode 100644
index 0000000..cec9e2b
--- /dev/null
+++ b/fs/cifs/fscache.h
@@ -0,0 +1,40 @@
+/*
+ *   fs/cifs/fscache.h - CIFS filesystem cache interface definitions
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _CIFS_FSCACHE_H
+#define _CIFS_FSCACHE_H
+
+#include <linux/fscache.h>
+#include "cifsglob.h"
+
+#ifdef CONFIG_CIFS_FSCACHE
+
+extern struct fscache_netfs cifs_fscache_netfs;
+
+extern int cifs_fscache_register(void);
+extern void cifs_fscache_unregister(void);
+
+#else /* CONFIG_CIFS_FSCACHE */
+static inline int cifs_fscache_register(void) { return 0; }
+static inline void cifs_fscache_unregister(void) {}
+
+#endif /* CONFIG_CIFS_FSCACHE */
+
+#endif /* _CIFS_FSCACHE_H */
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
       [not found] <yes>
@ 2010-06-22 15:23   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

Define server-level cache index objects (as managed by TCP_ServerInfo structs).
Each server object is created in the CIFS top-level index object and is itself
an index into which superblock-level objects are inserted.

Currently, the server objects are keyed by hostname.

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/cifs/Makefile   |    2 +-
 fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
 fs/cifs/cifsglob.h |    3 +++
 fs/cifs/connect.c  |    4 ++++
 fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fscache.h  |   12 ++++++++++++
 6 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 fs/cifs/fscache.c

Index: cifs-2.6/fs/cifs/Makefile
===================================================================
--- cifs-2.6.orig/fs/cifs/Makefile
+++ cifs-2.6/fs/cifs/Makefile
@@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
 
 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
 
-cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
+cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
Index: cifs-2.6/fs/cifs/cache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cache.c
+++ cifs-2.6/fs/cifs/cache.c
@@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
 	fscache_unregister_netfs(&cifs_fscache_netfs);
 }
 
+/*
+ * Server object currently keyed by hostname
+ */
+static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
+				   void *buffer, uint16_t maxbuf)
+{
+	const struct TCP_Server_Info *server = cookie_netfs_data;
+	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
+
+	if (len > maxbuf)
+		return 0;
+
+	memcpy(buffer, server->hostname, len);
+
+	return len;
+}
+
+/*
+ * Server object for FS-Cache
+ */
+const struct fscache_cookie_def cifs_fscache_server_index_def = {
+	.name = "CIFS.server",
+	.type = FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key = cifs_server_get_key,
+};
Index: cifs-2.6/fs/cifs/cifsglob.h
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsglob.h
+++ cifs-2.6/fs/cifs/cifsglob.h
@@ -193,6 +193,9 @@ struct TCP_Server_Info {
 	bool	sec_mskerberos;		/* supports legacy MS Kerberos */
 	bool	sec_kerberosu2u;	/* supports U2U Kerberos */
 	bool	sec_ntlmssp;		/* supports NTLMSSP */
+#ifdef CONFIG_CIFS_FSCACHE
+	struct fscache_cookie   *fscache; /* client index cache cookie */
+#endif
 };
 
 /*
Index: cifs-2.6/fs/cifs/connect.c
===================================================================
--- cifs-2.6.orig/fs/cifs/connect.c
+++ cifs-2.6/fs/cifs/connect.c
@@ -48,6 +48,7 @@
 #include "nterr.h"
 #include "rfc1002pdu.h"
 #include "cn_cifs.h"
+#include "fscache.h"
 
 #define CIFS_PORT 445
 #define RFC1001_PORT 139
@@ -1453,6 +1454,8 @@ cifs_put_tcp_session(struct TCP_Server_I
 		return;
 	}
 
+	cifs_fscache_release_client_cookie(server);
+
 	list_del_init(&server->tcp_ses_list);
 	write_unlock(&cifs_tcp_ses_lock);
 
@@ -1572,6 +1575,7 @@ cifs_get_tcp_session(struct smb_vol *vol
 		goto out_err;
 	}
 
+	cifs_fscache_get_client_cookie(tcp_ses);
 	/* thread spawned, put it on the list */
 	write_lock(&cifs_tcp_ses_lock);
 	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
Index: cifs-2.6/fs/cifs/fscache.c
===================================================================
--- /dev/null
+++ cifs-2.6/fs/cifs/fscache.c
@@ -0,0 +1,47 @@
+/*
+ *   fs/cifs/fscache.c - CIFS filesystem cache interface
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/in6.h>
+
+#include "fscache.h"
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
+void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
+{
+	server->fscache =
+		fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
+				&cifs_fscache_server_index_def, server);
+	cFYI(1, "CIFS: get client cookie (0x%p/0x%p)\n",
+				server, server->fscache);
+}
+
+void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
+{
+	cFYI(1, "CIFS: release client cookie (0x%p/0x%p)\n",
+				server, server->fscache);
+	fscache_relinquish_cookie(server->fscache, 0);
+	server->fscache = NULL;
+}
+
Index: cifs-2.6/fs/cifs/fscache.h
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.h
+++ cifs-2.6/fs/cifs/fscache.h
@@ -27,14 +27,26 @@
 #ifdef CONFIG_CIFS_FSCACHE
 
 extern struct fscache_netfs cifs_fscache_netfs;
+extern const struct fscache_cookie_def cifs_fscache_server_index_def;
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
 
+/*
+ * fscache.c
+ */
+extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
+extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
 
+static inline void
+cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
+static inline void
+cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
+
 #endif /* CONFIG_CIFS_FSCACHE */
 
 #endif /* _CIFS_FSCACHE_H */

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
@ 2010-06-22 15:23   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Define server-level cache index objects (as managed by TCP_ServerInfo structs).
Each server object is created in the CIFS top-level index object and is itself
an index into which superblock-level objects are inserted.

Currently, the server objects are keyed by hostname.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/Makefile   |    2 +-
 fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
 fs/cifs/cifsglob.h |    3 +++
 fs/cifs/connect.c  |    4 ++++
 fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fscache.h  |   12 ++++++++++++
 6 files changed, 92 insertions(+), 1 deletion(-)
 create mode 100644 fs/cifs/fscache.c

Index: cifs-2.6/fs/cifs/Makefile
===================================================================
--- cifs-2.6.orig/fs/cifs/Makefile
+++ cifs-2.6/fs/cifs/Makefile
@@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
 
 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
 
-cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
+cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
Index: cifs-2.6/fs/cifs/cache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cache.c
+++ cifs-2.6/fs/cifs/cache.c
@@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
 	fscache_unregister_netfs(&cifs_fscache_netfs);
 }
 
+/*
+ * Server object currently keyed by hostname
+ */
+static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
+				   void *buffer, uint16_t maxbuf)
+{
+	const struct TCP_Server_Info *server = cookie_netfs_data;
+	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
+
+	if (len > maxbuf)
+		return 0;
+
+	memcpy(buffer, server->hostname, len);
+
+	return len;
+}
+
+/*
+ * Server object for FS-Cache
+ */
+const struct fscache_cookie_def cifs_fscache_server_index_def = {
+	.name = "CIFS.server",
+	.type = FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key = cifs_server_get_key,
+};
Index: cifs-2.6/fs/cifs/cifsglob.h
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsglob.h
+++ cifs-2.6/fs/cifs/cifsglob.h
@@ -193,6 +193,9 @@ struct TCP_Server_Info {
 	bool	sec_mskerberos;		/* supports legacy MS Kerberos */
 	bool	sec_kerberosu2u;	/* supports U2U Kerberos */
 	bool	sec_ntlmssp;		/* supports NTLMSSP */
+#ifdef CONFIG_CIFS_FSCACHE
+	struct fscache_cookie   *fscache; /* client index cache cookie */
+#endif
 };
 
 /*
Index: cifs-2.6/fs/cifs/connect.c
===================================================================
--- cifs-2.6.orig/fs/cifs/connect.c
+++ cifs-2.6/fs/cifs/connect.c
@@ -48,6 +48,7 @@
 #include "nterr.h"
 #include "rfc1002pdu.h"
 #include "cn_cifs.h"
+#include "fscache.h"
 
 #define CIFS_PORT 445
 #define RFC1001_PORT 139
@@ -1453,6 +1454,8 @@ cifs_put_tcp_session(struct TCP_Server_I
 		return;
 	}
 
+	cifs_fscache_release_client_cookie(server);
+
 	list_del_init(&server->tcp_ses_list);
 	write_unlock(&cifs_tcp_ses_lock);
 
@@ -1572,6 +1575,7 @@ cifs_get_tcp_session(struct smb_vol *vol
 		goto out_err;
 	}
 
+	cifs_fscache_get_client_cookie(tcp_ses);
 	/* thread spawned, put it on the list */
 	write_lock(&cifs_tcp_ses_lock);
 	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
Index: cifs-2.6/fs/cifs/fscache.c
===================================================================
--- /dev/null
+++ cifs-2.6/fs/cifs/fscache.c
@@ -0,0 +1,47 @@
+/*
+ *   fs/cifs/fscache.c - CIFS filesystem cache interface
+ *
+ *   Copyright (c) 2010 Novell, Inc.
+ *   Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
+ *
+ *   This library is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published
+ *   by the Free Software Foundation; either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This library 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 Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/in6.h>
+
+#include "fscache.h"
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
+void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
+{
+	server->fscache =
+		fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
+				&cifs_fscache_server_index_def, server);
+	cFYI(1, "CIFS: get client cookie (0x%p/0x%p)\n",
+				server, server->fscache);
+}
+
+void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
+{
+	cFYI(1, "CIFS: release client cookie (0x%p/0x%p)\n",
+				server, server->fscache);
+	fscache_relinquish_cookie(server->fscache, 0);
+	server->fscache = NULL;
+}
+
Index: cifs-2.6/fs/cifs/fscache.h
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.h
+++ cifs-2.6/fs/cifs/fscache.h
@@ -27,14 +27,26 @@
 #ifdef CONFIG_CIFS_FSCACHE
 
 extern struct fscache_netfs cifs_fscache_netfs;
+extern const struct fscache_cookie_def cifs_fscache_server_index_def;
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
 
+/*
+ * fscache.c
+ */
+extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
+extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
 
+static inline void
+cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
+static inline void
+cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
+
 #endif /* CONFIG_CIFS_FSCACHE */
 
 #endif /* _CIFS_FSCACHE_H */

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
       [not found] <yes>
@ 2010-06-22 15:23   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

Define superblock-level cache index objects (managed by cifsTconInfo structs).
Each superblock object is created in a server-level index object and in itself
an index into which inode-level objects are inserted.

Currently, the superblock objects are keyed by sharename.

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/cifs/cache.c    |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/cifsglob.h |    3 ++
 fs/cifs/connect.c  |    4 +++
 fs/cifs/fscache.c  |   17 ++++++++++++++
 fs/cifs/fscache.h  |    6 +++++
 5 files changed, 92 insertions(+)

Index: cifs-2.6/fs/cifs/cache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cache.c
+++ cifs-2.6/fs/cifs/cache.c
@@ -76,3 +76,65 @@ const struct fscache_cookie_def cifs_fsc
 	.type = FSCACHE_COOKIE_TYPE_INDEX,
 	.get_key = cifs_server_get_key,
 };
+
+static char *extract_sharename(const char *treename)
+{
+	const char *src;
+	char *delim, *dst;
+	int len;
+
+	/* skip double chars at the beginning */
+	src = treename + 2;
+
+	/* share name is always preceded by '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+	delim++;
+	len = strlen(delim);
+
+	/* caller has to free the memory */
+	dst = kstrndup(delim, len, GFP_KERNEL);
+	if (!dst)
+		return ERR_PTR(-ENOMEM);
+
+	return dst;
+}
+
+/*
+ * Superblock object currently keyed by share name
+ */
+static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
+				   uint16_t maxbuf)
+{
+	const struct cifsTconInfo *tcon = cookie_netfs_data;
+	char *sharename;
+	uint16_t len;
+
+	sharename = extract_sharename(tcon->treeName);
+	if (IS_ERR(sharename)) {
+		cFYI(1, "CIFS: couldn't extract sharename\n");
+		sharename = NULL;
+		return 0;
+	}
+
+	len = strlen(sharename);
+	if (len > maxbuf)
+		return 0;
+
+	memcpy(buffer, sharename, len);
+
+	kfree(sharename);
+
+	return len;
+}
+
+/*
+ * Superblock object for FS-Cache
+ */
+const struct fscache_cookie_def cifs_fscache_super_index_def = {
+	.name = "CIFS.super",
+	.type = FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key = cifs_super_get_key,
+};
+
Index: cifs-2.6/fs/cifs/cifsglob.h
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsglob.h
+++ cifs-2.6/fs/cifs/cifsglob.h
@@ -317,6 +317,9 @@ struct cifsTconInfo {
 	bool local_lease:1; /* check leases (only) on local system not remote */
 	bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
 	bool need_reconnect:1; /* connection reset, tid now invalid */
+#ifdef CONFIG_CIFS_FSCACHE
+	struct fscache_cookie *fscache; /* cookie for share */
+#endif
 	/* BB add field for back pointer to sb struct(s)? */
 };
 
Index: cifs-2.6/fs/cifs/connect.c
===================================================================
--- cifs-2.6.orig/fs/cifs/connect.c
+++ cifs-2.6/fs/cifs/connect.c
@@ -1773,6 +1773,8 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
 	list_del_init(&tcon->tcon_list);
 	write_unlock(&cifs_tcp_ses_lock);
 
+	cifs_fscache_release_super_cookie(tcon);
+
 	xid = GetXid();
 	CIFSSMBTDis(xid, tcon);
 	_FreeXid(xid);
@@ -1843,6 +1845,8 @@ cifs_get_tcon(struct cifsSesInfo *ses, s
 	tcon->nocase = volume_info->nocase;
 	tcon->local_lease = volume_info->local_lease;
 
+	cifs_fscache_get_super_cookie(tcon);
+
 	write_lock(&cifs_tcp_ses_lock);
 	list_add(&tcon->tcon_list, &ses->tcon_list);
 	write_unlock(&cifs_tcp_ses_lock);
Index: cifs-2.6/fs/cifs/fscache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.c
+++ cifs-2.6/fs/cifs/fscache.c
@@ -45,3 +45,20 @@ void cifs_fscache_release_client_cookie(
 	server->fscache = NULL;
 }
 
+void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
+{
+	tcon->fscache =
+		fscache_acquire_cookie(tcon->ses->server->fscache,
+				&cifs_fscache_super_index_def, tcon);
+	cFYI(1, "CIFS: get superblock cookie (0x%p/0x%p)\n",
+				tcon, tcon->fscache);
+}
+
+void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon)
+{
+	cFYI(1, "CIFS: releasing superblock cookie (0x%p/0x%p)\n",
+			tcon, tcon->fscache);
+	fscache_relinquish_cookie(tcon->fscache, 0);
+	tcon->fscache = NULL;
+}
+
Index: cifs-2.6/fs/cifs/fscache.h
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.h
+++ cifs-2.6/fs/cifs/fscache.h
@@ -28,6 +28,7 @@
 
 extern struct fscache_netfs cifs_fscache_netfs;
 extern const struct fscache_cookie_def cifs_fscache_server_index_def;
+extern const struct fscache_cookie_def cifs_fscache_super_index_def;
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
@@ -37,6 +38,8 @@ extern void cifs_fscache_unregister(void
  */
 extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
 extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
+extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
+extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
 
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
@@ -46,6 +49,9 @@ static inline void
 cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
 static inline void
 cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
+static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {}
+static inline void
+cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {}
 
 #endif /* CONFIG_CIFS_FSCACHE */
 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
@ 2010-06-22 15:23   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Define superblock-level cache index objects (managed by cifsTconInfo structs).
Each superblock object is created in a server-level index object and in itself
an index into which inode-level objects are inserted.

Currently, the superblock objects are keyed by sharename.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/cache.c    |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/cifsglob.h |    3 ++
 fs/cifs/connect.c  |    4 +++
 fs/cifs/fscache.c  |   17 ++++++++++++++
 fs/cifs/fscache.h  |    6 +++++
 5 files changed, 92 insertions(+)

Index: cifs-2.6/fs/cifs/cache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cache.c
+++ cifs-2.6/fs/cifs/cache.c
@@ -76,3 +76,65 @@ const struct fscache_cookie_def cifs_fsc
 	.type = FSCACHE_COOKIE_TYPE_INDEX,
 	.get_key = cifs_server_get_key,
 };
+
+static char *extract_sharename(const char *treename)
+{
+	const char *src;
+	char *delim, *dst;
+	int len;
+
+	/* skip double chars at the beginning */
+	src = treename + 2;
+
+	/* share name is always preceded by '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+	delim++;
+	len = strlen(delim);
+
+	/* caller has to free the memory */
+	dst = kstrndup(delim, len, GFP_KERNEL);
+	if (!dst)
+		return ERR_PTR(-ENOMEM);
+
+	return dst;
+}
+
+/*
+ * Superblock object currently keyed by share name
+ */
+static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
+				   uint16_t maxbuf)
+{
+	const struct cifsTconInfo *tcon = cookie_netfs_data;
+	char *sharename;
+	uint16_t len;
+
+	sharename = extract_sharename(tcon->treeName);
+	if (IS_ERR(sharename)) {
+		cFYI(1, "CIFS: couldn't extract sharename\n");
+		sharename = NULL;
+		return 0;
+	}
+
+	len = strlen(sharename);
+	if (len > maxbuf)
+		return 0;
+
+	memcpy(buffer, sharename, len);
+
+	kfree(sharename);
+
+	return len;
+}
+
+/*
+ * Superblock object for FS-Cache
+ */
+const struct fscache_cookie_def cifs_fscache_super_index_def = {
+	.name = "CIFS.super",
+	.type = FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key = cifs_super_get_key,
+};
+
Index: cifs-2.6/fs/cifs/cifsglob.h
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsglob.h
+++ cifs-2.6/fs/cifs/cifsglob.h
@@ -317,6 +317,9 @@ struct cifsTconInfo {
 	bool local_lease:1; /* check leases (only) on local system not remote */
 	bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
 	bool need_reconnect:1; /* connection reset, tid now invalid */
+#ifdef CONFIG_CIFS_FSCACHE
+	struct fscache_cookie *fscache; /* cookie for share */
+#endif
 	/* BB add field for back pointer to sb struct(s)? */
 };
 
Index: cifs-2.6/fs/cifs/connect.c
===================================================================
--- cifs-2.6.orig/fs/cifs/connect.c
+++ cifs-2.6/fs/cifs/connect.c
@@ -1773,6 +1773,8 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
 	list_del_init(&tcon->tcon_list);
 	write_unlock(&cifs_tcp_ses_lock);
 
+	cifs_fscache_release_super_cookie(tcon);
+
 	xid = GetXid();
 	CIFSSMBTDis(xid, tcon);
 	_FreeXid(xid);
@@ -1843,6 +1845,8 @@ cifs_get_tcon(struct cifsSesInfo *ses, s
 	tcon->nocase = volume_info->nocase;
 	tcon->local_lease = volume_info->local_lease;
 
+	cifs_fscache_get_super_cookie(tcon);
+
 	write_lock(&cifs_tcp_ses_lock);
 	list_add(&tcon->tcon_list, &ses->tcon_list);
 	write_unlock(&cifs_tcp_ses_lock);
Index: cifs-2.6/fs/cifs/fscache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.c
+++ cifs-2.6/fs/cifs/fscache.c
@@ -45,3 +45,20 @@ void cifs_fscache_release_client_cookie(
 	server->fscache = NULL;
 }
 
+void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
+{
+	tcon->fscache =
+		fscache_acquire_cookie(tcon->ses->server->fscache,
+				&cifs_fscache_super_index_def, tcon);
+	cFYI(1, "CIFS: get superblock cookie (0x%p/0x%p)\n",
+				tcon, tcon->fscache);
+}
+
+void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon)
+{
+	cFYI(1, "CIFS: releasing superblock cookie (0x%p/0x%p)\n",
+			tcon, tcon->fscache);
+	fscache_relinquish_cookie(tcon->fscache, 0);
+	tcon->fscache = NULL;
+}
+
Index: cifs-2.6/fs/cifs/fscache.h
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.h
+++ cifs-2.6/fs/cifs/fscache.h
@@ -28,6 +28,7 @@
 
 extern struct fscache_netfs cifs_fscache_netfs;
 extern const struct fscache_cookie_def cifs_fscache_server_index_def;
+extern const struct fscache_cookie_def cifs_fscache_super_index_def;
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
@@ -37,6 +38,8 @@ extern void cifs_fscache_unregister(void
  */
 extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
 extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
+extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
+extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
 
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
@@ -46,6 +49,9 @@ static inline void
 cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
 static inline void
 cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
+static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {}
+static inline void
+cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {}
 
 #endif /* CONFIG_CIFS_FSCACHE */
 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
       [not found] <yes>
                   ` (12 preceding siblings ...)
  2010-06-22 15:23   ` Suresh Jayaraman
@ 2010-06-22 15:23 ` Suresh Jayaraman
  2010-06-22 15:23 ` [RFC][PATCH 07/10] cifs: FS-Cache page management Suresh Jayaraman
                   ` (77 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Define inode-level data storage objects (managed by cifsInodeInfo structs).
Each inode-level object is created in a super-block level object and is itself
a data storage object in to which pages from the inode are stored.

The inode object is keyed by UniqueId. The coherency data being used is
LastWriteTime and the file size.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/cache.c    |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/cifsfs.c   |    7 ++++
 fs/cifs/cifsglob.h |    3 +
 fs/cifs/file.c     |    6 +++
 fs/cifs/fscache.c  |   68 +++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fscache.h  |   12 +++++++
 fs/cifs/inode.c    |    4 ++
 7 files changed, 180 insertions(+)

Index: cifs-2.6/fs/cifs/cache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cache.c
+++ cifs-2.6/fs/cifs/cache.c
@@ -138,3 +138,83 @@ const struct fscache_cookie_def cifs_fsc
 	.get_key = cifs_super_get_key,
 };
 
+/*
+ * Auxiliary data attached to CIFS inode within the cache
+ */
+struct cifs_fscache_inode_auxdata {
+	struct timespec	last_write_time;
+	loff_t		size;
+};
+
+static uint16_t cifs_fscache_inode_get_key(const void *cookie_netfs_data,
+					   void *buffer, uint16_t maxbuf)
+{
+	const struct cifsInodeInfo *cifsi = cookie_netfs_data;
+	uint16_t keylen;
+
+	/* use the UniqueId as the key */
+	keylen = sizeof(cifsi->uniqueid);
+	if (keylen > maxbuf)
+		keylen = 0;
+	else
+		memcpy(buffer, &cifsi->uniqueid, keylen);
+
+	return keylen;
+}
+
+static void
+cifs_fscache_inode_get_attr(const void *cookie_netfs_data, uint64_t *size)
+{
+	const struct cifsInodeInfo *cifsi = cookie_netfs_data;
+
+	*size = cifsi->vfs_inode.i_size;
+}
+
+static uint16_t
+cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer,
+			   uint16_t maxbuf)
+{
+	struct cifs_fscache_inode_auxdata auxdata;
+	const struct cifsInodeInfo *cifsi = cookie_netfs_data;
+
+	memset(&auxdata, 0, sizeof(auxdata));
+	auxdata.size = cifsi->vfs_inode.i_size;
+	auxdata.last_write_time = cifsi->vfs_inode.i_ctime;
+
+	if (maxbuf > sizeof(auxdata))
+		maxbuf = sizeof(auxdata);
+
+	memcpy(buffer, &auxdata, maxbuf);
+
+	return maxbuf;
+}
+
+static enum
+fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
+					      const void *data,
+					      uint16_t datalen)
+{
+	struct cifs_fscache_inode_auxdata auxdata;
+	struct cifsInodeInfo *cifsi = cookie_netfs_data;
+
+	if (datalen != sizeof(auxdata))
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	memset(&auxdata, 0, sizeof(auxdata));
+	auxdata.size = cifsi->vfs_inode.i_size;
+	auxdata.last_write_time = cifsi->vfs_inode.i_ctime;
+
+	if (memcmp(data, &auxdata, datalen) != 0)
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	return FSCACHE_CHECKAUX_OKAY;
+}
+
+const struct fscache_cookie_def cifs_fscache_inode_object_def = {
+	.name		= "CIFS.uniqueid",
+	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
+	.get_key	= cifs_fscache_inode_get_key,
+	.get_attr	= cifs_fscache_inode_get_attr,
+	.get_aux	= cifs_fscache_inode_get_aux,
+	.check_aux	= cifs_fscache_inode_check_aux,
+};
Index: cifs-2.6/fs/cifs/cifsfs.c
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsfs.c
+++ cifs-2.6/fs/cifs/cifsfs.c
@@ -330,6 +330,12 @@ cifs_destroy_inode(struct inode *inode)
 }
 
 static void
+cifs_clear_inode(struct inode *inode)
+{
+	cifs_fscache_release_inode_cookie(inode);
+}
+
+static void
 cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
 {
 	seq_printf(s, ",addr=");
@@ -490,6 +496,7 @@ static const struct super_operations cif
 	.alloc_inode = cifs_alloc_inode,
 	.destroy_inode = cifs_destroy_inode,
 	.drop_inode	= cifs_drop_inode,
+	.clear_inode	= cifs_clear_inode,
 /*	.delete_inode	= cifs_delete_inode,  */  /* Do not need above
 	function unless later we add lazy close of inodes or unless the
 	kernel forgets to call us with the same number of releases (closes)
Index: cifs-2.6/fs/cifs/cifsglob.h
===================================================================
--- cifs-2.6.orig/fs/cifs/cifsglob.h
+++ cifs-2.6/fs/cifs/cifsglob.h
@@ -407,6 +407,9 @@ struct cifsInodeInfo {
 	bool invalid_mapping:1;		/* pagecache is invalid */
 	u64  server_eof;		/* current file size on server */
 	u64  uniqueid;			/* server inode number */
+#ifdef CONFIG_CIFS_FSCACHE
+	struct fscache_cookie *fscache;
+#endif
 	struct inode vfs_inode;
 };
 
Index: cifs-2.6/fs/cifs/file.c
===================================================================
--- cifs-2.6.orig/fs/cifs/file.c
+++ cifs-2.6/fs/cifs/file.c
@@ -40,6 +40,7 @@
 #include "cifs_unicode.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
+#include "fscache.h"
 
 static inline int cifs_convert_flags(unsigned int flags)
 {
@@ -282,6 +283,9 @@ int cifs_open(struct inode *inode, struc
 				CIFSSMBClose(xid, tcon, netfid);
 				rc = -ENOMEM;
 			}
+
+			cifs_fscache_set_inode_cookie(inode, file);
+
 			goto out;
 		} else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 			if (tcon->ses->serverNOS)
@@ -373,6 +377,8 @@ int cifs_open(struct inode *inode, struc
 		goto out;
 	}
 
+	cifs_fscache_set_inode_cookie(inode, file);
+
 	if (oplock & CIFS_CREATE_ACTION) {
 		/* time to set mode which we can not set earlier due to
 		   problems creating new read-only files */
Index: cifs-2.6/fs/cifs/fscache.c
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.c
+++ cifs-2.6/fs/cifs/fscache.c
@@ -62,3 +62,71 @@ void cifs_fscache_release_super_cookie(s
 	tcon->fscache = NULL;
 }
 
+static void cifs_fscache_enable_inode_cookie(struct inode *inode)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+
+	if (cifsi->fscache)
+		return;
+
+	cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache,
+				&cifs_fscache_inode_object_def,
+				cifsi);
+	cFYI(1, "CIFS: got FH cookie (0x%p/0x%p/0x%p)\n",
+			cifs_sb->tcon, cifsi, cifsi->fscache);
+}
+
+void cifs_fscache_release_inode_cookie(struct inode *inode)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+
+	if (cifsi->fscache) {
+		cFYI(1, "CIFS releasing inode cookie (0x%p/0x%p)\n",
+				cifsi, cifsi->fscache);
+		fscache_relinquish_cookie(cifsi->fscache, 0);
+		cifsi->fscache = NULL;
+	}
+}
+
+static void cifs_fscache_disable_inode_cookie(struct inode *inode)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+
+	if (cifsi->fscache) {
+		cFYI(1, "CIFS disabling inode cookie (0x%p/0x%p)\n",
+				cifsi, cifsi->fscache);
+		fscache_relinquish_cookie(cifsi->fscache, 1);
+		cifsi->fscache = NULL;
+	}
+}
+
+void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
+{
+	/* BB: parallel opens - need locking? */
+	if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+		cifs_fscache_disable_inode_cookie(inode);
+	else {
+		cifs_fscache_enable_inode_cookie(inode);
+		cFYI(1, "CIFS: fscache inode cookie set\n");
+	}
+}
+
+void cifs_fscache_reset_inode_cookie(struct inode *inode)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+	struct fscache_cookie *old = cifsi->fscache;
+
+	if (cifsi->fscache) {
+		/* retire the current fscache cache and get a new one */
+		fscache_relinquish_cookie(cifsi->fscache, 1);
+
+		cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache,
+					&cifs_fscache_inode_object_def,
+					cifsi);
+		cFYI(1, "CIFS: new cookie (0x%p/0x%p) oldcookie 0x%p\n",
+				cifsi, cifsi->fscache, old);
+	}
+}
+
Index: cifs-2.6/fs/cifs/fscache.h
===================================================================
--- cifs-2.6.orig/fs/cifs/fscache.h
+++ cifs-2.6/fs/cifs/fscache.h
@@ -29,6 +29,8 @@
 extern struct fscache_netfs cifs_fscache_netfs;
 extern const struct fscache_cookie_def cifs_fscache_server_index_def;
 extern const struct fscache_cookie_def cifs_fscache_super_index_def;
+extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
+
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
@@ -41,6 +43,10 @@ extern void cifs_fscache_release_client_
 extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
 extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
 
+extern void cifs_fscache_release_inode_cookie(struct inode *);
+extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
+extern void cifs_fscache_reset_inode_cookie(struct inode *);
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
@@ -53,6 +59,12 @@ static inline void cifs_fscache_get_supe
 static inline void
 cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {}
 
+static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
+static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
+			struct file *filp) {}
+static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {}
+
+
 #endif /* CONFIG_CIFS_FSCACHE */
 
 #endif /* _CIFS_FSCACHE_H */
Index: cifs-2.6/fs/cifs/inode.c
===================================================================
--- cifs-2.6.orig/fs/cifs/inode.c
+++ cifs-2.6/fs/cifs/inode.c
@@ -29,6 +29,7 @@
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
+#include "fscache.h"
 
 
 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
@@ -776,6 +777,8 @@ retry_iget5_locked:
 			inode->i_flags |= S_NOATIME | S_NOCMTIME;
 		if (inode->i_state & I_NEW) {
 			inode->i_ino = hash;
+			/* initialize per-inode cache cookie pointer */
+			CIFS_I(inode)->fscache = NULL;
 			unlock_new_inode(inode);
 		}
 	}
@@ -1568,6 +1571,7 @@ cifs_invalidate_mapping(struct inode *in
 			cifs_i->write_behind_rc = rc;
 	}
 	invalidate_remote_inode(inode);
+	cifs_fscache_reset_inode_cookie(inode);
 }
 
 int cifs_revalidate_file(struct file *filp)

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC][PATCH 07/10] cifs: FS-Cache page management
       [not found] <yes>
                   ` (13 preceding siblings ...)
  2010-06-22 15:23 ` [RFC][PATCH 06/10] cifs: define inode-level cache object " Suresh Jayaraman
@ 2010-06-22 15:23 ` Suresh Jayaraman
  2010-06-22 15:24 ` [RFC][PATCH 08/10] cifs: store pages into local cache Suresh Jayaraman
                   ` (76 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:23 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Takes care of invalidation and release of FS-Cache marked pages and also
invalidation of the FsCache page flag when the inode is removed.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/cache.c   |   31 +++++++++++++++++++++++++++++++
 fs/cifs/file.c    |   20 ++++++++++++++++++++
 fs/cifs/fscache.c |   26 ++++++++++++++++++++++++++
 fs/cifs/fscache.h |   16 ++++++++++++++++
 4 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index b205424..3a733c1 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -210,6 +210,36 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
 	return FSCACHE_CHECKAUX_OKAY;
 }
 
+static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data)
+{
+	struct cifsInodeInfo *cifsi = cookie_netfs_data;
+	struct pagevec pvec;
+	pgoff_t first;
+	int loop, nr_pages;
+
+	pagevec_init(&pvec, 0);
+	first = 0;
+
+	cFYI(1, "cifs inode 0x%p now uncached\n", cifsi);
+
+	for (;;) {
+		nr_pages = pagevec_lookup(&pvec,
+					  cifsi->vfs_inode.i_mapping, first,
+					  PAGEVEC_SIZE - pagevec_count(&pvec));
+		if (!nr_pages)
+			break;
+
+		for (loop = 0; loop < nr_pages; loop++)
+			ClearPageFsCache(pvec.pages[loop]);
+
+		first = pvec.pages[nr_pages - 1]->index + 1;
+
+		pvec.nr = nr_pages;
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+}
+
 const struct fscache_cookie_def cifs_fscache_inode_object_def = {
 	.name		= "CIFS.uniqueid",
 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
@@ -217,4 +247,5 @@ const struct fscache_cookie_def cifs_fscache_inode_object_def = {
 	.get_attr	= cifs_fscache_inode_get_attr,
 	.get_aux	= cifs_fscache_inode_get_aux,
 	.check_aux	= cifs_fscache_inode_check_aux,
+	.now_uncached	= cifs_fscache_inode_now_uncached,
 };
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 55ecb55..786ec04 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2271,6 +2271,22 @@ out:
 	return rc;
 }
 
+static int cifs_release_page(struct page *page, gfp_t gfp)
+{
+	if (PagePrivate(page))
+		return 0;
+
+	return cifs_fscache_release_page(page, gfp);
+}
+
+static void cifs_invalidate_page(struct page *page, unsigned long offset)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
+
+	if (offset == 0)
+		cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
+}
+
 static void
 cifs_oplock_break(struct slow_work *work)
 {
@@ -2344,6 +2360,8 @@ const struct address_space_operations cifs_addr_ops = {
 	.write_begin = cifs_write_begin,
 	.write_end = cifs_write_end,
 	.set_page_dirty = __set_page_dirty_nobuffers,
+	.releasepage = cifs_release_page,
+	.invalidatepage = cifs_invalidate_page,
 	/* .sync_page = cifs_sync_page, */
 	/* .direct_IO = */
 };
@@ -2360,6 +2378,8 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
 	.write_begin = cifs_write_begin,
 	.write_end = cifs_write_end,
 	.set_page_dirty = __set_page_dirty_nobuffers,
+	.releasepage = cifs_release_page,
+	.invalidatepage = cifs_invalidate_page,
 	/* .sync_page = cifs_sync_page, */
 	/* .direct_IO = */
 };
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index ddfd355..c09d3b8 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -130,3 +130,29 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode)
 	}
 }
 
+int cifs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+	if (PageFsCache(page)) {
+		struct inode *inode = page->mapping->host;
+		struct cifsInodeInfo *cifsi = CIFS_I(inode);
+
+		cFYI(1, "CIFS: fscache release page (0x%p/0x%p)\n",
+				cifsi->fscache, page);
+		if (!fscache_maybe_release_page(cifsi->fscache, page, gfp))
+			return 0;
+	}
+
+	return 1;
+}
+
+void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
+{
+	struct cifsInodeInfo *cifsi = CIFS_I(inode);
+	struct fscache_cookie *cookie = cifsi->fscache;
+
+	cFYI(1, "CIFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
+			cookie, page, cifsi);
+	fscache_wait_on_page_write(cookie, page);
+	fscache_uncache_page(cookie, page);
+}
+
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 836bb02..127cb0a 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -47,6 +47,16 @@ extern void cifs_fscache_release_inode_cookie(struct inode *);
 extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
 extern void cifs_fscache_reset_inode_cookie(struct inode *);
 
+extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
+extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
+
+static inline void cifs_fscache_invalidate_page(struct page *page,
+					       struct inode *inode)
+{
+	if (PageFsCache(page))
+		__cifs_fscache_invalidate_page(page, inode);
+}
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
@@ -63,7 +73,13 @@ static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
 static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
 			struct file *filp) {}
 static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {}
+static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+	return 1; /* May release page */
+}
 
+static inline int cifs_fscache_invalidate_page(struct page *page,
+			struct inode *) {}
 
 #endif /* CONFIG_CIFS_FSCACHE */
 
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 08/10] cifs: store pages into local cache
       [not found] <yes>
                   ` (14 preceding siblings ...)
  2010-06-22 15:23 ` [RFC][PATCH 07/10] cifs: FS-Cache page management Suresh Jayaraman
@ 2010-06-22 15:24 ` Suresh Jayaraman
  2010-06-22 15:24   ` Suresh Jayaraman
                   ` (75 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:24 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Store pages from an CIFS inode into the data storage object associated with
that inode.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/file.c    |    6 ++++++
 fs/cifs/fscache.c |   13 +++++++++++++
 fs/cifs/fscache.h |   11 +++++++++++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 786ec04..39c1ce0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2060,6 +2060,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 				   we will hit it on next read */
 
 				/* break; */
+				/* send this page to FS-Cache */
+				cifs_readpage_to_fscache(mapping->host, page);
 			}
 		} else {
 			cFYI(1, "No bytes read (%d) at offset %lld . "
@@ -2117,6 +2119,10 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
 
 	flush_dcache_page(page);
 	SetPageUptodate(page);
+
+	/* send this page to the cache */
+	cifs_readpage_to_fscache(file->f_path.dentry->d_inode, page);
+
 	rc = 0;
 
 io_error:
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index c09d3b8..13e47d5 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -145,6 +145,19 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
 	return 1;
 }
 
+void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
+{
+	int ret;
+
+	cFYI(1, "CIFS: readpage_to_fscache(fsc: %p, p: %p, i: %p\n",
+			CIFS_I(inode)->fscache, page, inode);
+	ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL);
+	cFYI(1, "CIFS: fscache_write_page returned %d\n", ret);
+
+	if (ret != 0)
+		fscache_uncache_page(CIFS_I(inode)->fscache, page);
+}
+
 void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
 {
 	struct cifsInodeInfo *cifsi = CIFS_I(inode);
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 127cb0a..e34d8ab 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -50,6 +50,8 @@ extern void cifs_fscache_reset_inode_cookie(struct inode *);
 extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
 extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
 
+extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
+
 static inline void cifs_fscache_invalidate_page(struct page *page,
 					       struct inode *inode)
 {
@@ -57,6 +59,13 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
 		__cifs_fscache_invalidate_page(page, inode);
 }
 
+static inline void cifs_readpage_to_fscache(struct inode *inode,
+					    struct page *page)
+{
+	if (PageFsCache(page))
+		__cifs_readpage_to_fscache(inode, page);
+}
+
 #else /* CONFIG_CIFS_FSCACHE */
 static inline int cifs_fscache_register(void) { return 0; }
 static inline void cifs_fscache_unregister(void) {}
@@ -80,6 +89,8 @@ static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)
 
 static inline int cifs_fscache_invalidate_page(struct page *page,
 			struct inode *) {}
+static inline void cifs_readpage_to_fscache(struct inode *inode,
+			struct page *page) {}
 
 #endif /* CONFIG_CIFS_FSCACHE */
 
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 09/10] cifs: read pages from FS-Cache
       [not found] <yes>
@ 2010-06-22 15:24   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:24 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

Read pages from a FS-Cache data storage object into a CIFS inode.

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/cifs/file.c    |   19 ++++++++++++++
 fs/cifs/fscache.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fscache.h |   40 ++++++++++++++++++++++++++++-
 3 files changed, 131 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 39c1ce0..42d2f25 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1978,6 +1978,16 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
 	pTcon = cifs_sb->tcon;
 
+	/*
+	 * Reads as many pages as possible from fscache. Returns -ENOBUFS
+	 * immediately if the cookie is negative
+	 */
+	rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
+					 &num_pages);
+	cFYI(1, "CIFS: readpages_from_fscache returned %d\n", rc);
+	if (rc == 0)
+		goto read_complete;
+
 	cFYI(DBG2, "rpages: num pages %d", num_pages);
 	for (i = 0; i < num_pages; ) {
 		unsigned contig_pages;
@@ -2090,6 +2100,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 		smb_read_data = NULL;
 	}
 
+read_complete:
 	FreeXid(xid);
 	return rc;
 }
@@ -2100,6 +2111,12 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
 	char *read_data;
 	int rc;
 
+	/* Is the page cached? */
+	rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
+	cFYI(1, "CIFS: cifs_readpage_from_fscache returned %d\n", rc);
+	if (rc == 0)
+		goto read_complete;
+
 	page_cache_get(page);
 	read_data = kmap(page);
 	/* for reads over a certain size could initiate async read ahead */
@@ -2128,6 +2145,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
 io_error:
 	kunmap(page);
 	page_cache_release(page);
+
+read_complete:
 	return rc;
 }
 
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 13e47d5..6813737 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -145,6 +145,79 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
 	return 1;
 }
 
+static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
+						int error)
+{
+	cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)\n",
+			page, error);
+	if (!error)
+		SetPageUptodate(page);
+	unlock_page(page);
+}
+
+/*
+ * Retrieve a page from FS-Cache
+ */
+int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
+{
+	int ret;
+
+	cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p\n",
+			CIFS_I(inode)->fscache, page, inode);
+	ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
+					 cifs_readpage_from_fscache_complete,
+					 NULL,
+					 GFP_KERNEL);
+	switch (ret) {
+
+	case 0: /* page found in fscache, read submitted */
+		cFYI(1, "CIFS: readpage_from_fscache: submitted\n");
+		return ret;
+	case -ENOBUFS:	/* page won't be cached */
+	case -ENODATA:	/* page not in cache */
+		cFYI(1, "CIFS: readpage_from_fscache %d\n", ret);
+		return 1;
+
+	default:
+		cFYI(1, "unknown error ret = %d", ret);
+	}
+	return ret;
+}
+
+/*
+ * Retrieve a set of pages from FS-Cache
+ */
+int __cifs_readpages_from_fscache(struct inode *inode,
+				struct address_space *mapping,
+				struct list_head *pages,
+				unsigned *nr_pages)
+{
+	int ret;
+
+	cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)\n",
+			CIFS_I(inode)->fscache, *nr_pages, inode);
+	ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
+					  pages, nr_pages,
+					  cifs_readpage_from_fscache_complete,
+					  NULL,
+					  mapping_gfp_mask(mapping));
+	switch (ret) {
+	case 0:	/* read submitted to the cache for all pages */
+		cFYI(1, "CIFS: readpages_from_fscache\n");
+		return ret;
+
+	case -ENOBUFS:	/* some pages are not cached and can't be */
+	case -ENODATA:	/* some pages are not cached */
+		cFYI(1, "CIFS: readpages_from_fscache: no page\n");
+		return 1;
+
+	default:
+		cFYI(1, "unknown error ret = %d", ret);
+	}
+
+	return ret;
+}
+
 void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
 {
 	int ret;
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index e34d8ab..03bd3fe 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -31,7 +31,6 @@ extern const struct fscache_cookie_def cifs_fscache_server_index_def;
 extern const struct fscache_cookie_def cifs_fscache_super_index_def;
 extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
 
-
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
 
@@ -49,6 +48,11 @@ extern void cifs_fscache_reset_inode_cookie(struct inode *);
 
 extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
 extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
+extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
+extern int __cifs_readpages_from_fscache(struct inode *,
+					 struct address_space *,
+					 struct list_head *,
+					 unsigned *);
 
 extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
 
@@ -59,6 +63,26 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
 		__cifs_fscache_invalidate_page(page, inode);
 }
 
+static inline int cifs_readpage_from_fscache(struct inode *inode,
+					     struct page *page)
+{
+	if (CIFS_I(inode)->fscache)
+		return __cifs_readpage_from_fscache(inode, page);
+
+	return -ENOBUFS;
+}
+
+static inline int cifs_readpages_from_fscache(struct inode *inode,
+					      struct address_space *mapping,
+					      struct list_head *pages,
+					      unsigned *nr_pages)
+{
+	if (CIFS_I(inode)->fscache)
+		return __cifs_readpages_from_fscache(inode, mapping, pages,
+						     nr_pages);
+	return -ENOBUFS;
+}
+
 static inline void cifs_readpage_to_fscache(struct inode *inode,
 					    struct page *page)
 {
@@ -89,6 +113,20 @@ static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)
 
 static inline int cifs_fscache_invalidate_page(struct page *page,
 			struct inode *) {}
+static inline int
+cifs_readpage_from_fscache(struct inode *inode, struct page *page)
+{
+	return -ENOBUFS;
+}
+
+static inline int cifs_readpages_from_fscache(struct inode *inode,
+					      struct address_space *mapping,
+					      struct list_head *pages,
+					      unsigned *nr_pages)
+{
+	return -ENOBUFS;
+}
+
 static inline void cifs_readpage_to_fscache(struct inode *inode,
 			struct page *page) {}
 
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 09/10] cifs: read pages from FS-Cache
@ 2010-06-22 15:24   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:24 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Read pages from a FS-Cache data storage object into a CIFS inode.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/file.c    |   19 ++++++++++++++
 fs/cifs/fscache.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fscache.h |   40 ++++++++++++++++++++++++++++-
 3 files changed, 131 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 39c1ce0..42d2f25 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1978,6 +1978,16 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
 	pTcon = cifs_sb->tcon;
 
+	/*
+	 * Reads as many pages as possible from fscache. Returns -ENOBUFS
+	 * immediately if the cookie is negative
+	 */
+	rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
+					 &num_pages);
+	cFYI(1, "CIFS: readpages_from_fscache returned %d\n", rc);
+	if (rc == 0)
+		goto read_complete;
+
 	cFYI(DBG2, "rpages: num pages %d", num_pages);
 	for (i = 0; i < num_pages; ) {
 		unsigned contig_pages;
@@ -2090,6 +2100,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 		smb_read_data = NULL;
 	}
 
+read_complete:
 	FreeXid(xid);
 	return rc;
 }
@@ -2100,6 +2111,12 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
 	char *read_data;
 	int rc;
 
+	/* Is the page cached? */
+	rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
+	cFYI(1, "CIFS: cifs_readpage_from_fscache returned %d\n", rc);
+	if (rc == 0)
+		goto read_complete;
+
 	page_cache_get(page);
 	read_data = kmap(page);
 	/* for reads over a certain size could initiate async read ahead */
@@ -2128,6 +2145,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
 io_error:
 	kunmap(page);
 	page_cache_release(page);
+
+read_complete:
 	return rc;
 }
 
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 13e47d5..6813737 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -145,6 +145,79 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
 	return 1;
 }
 
+static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
+						int error)
+{
+	cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)\n",
+			page, error);
+	if (!error)
+		SetPageUptodate(page);
+	unlock_page(page);
+}
+
+/*
+ * Retrieve a page from FS-Cache
+ */
+int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
+{
+	int ret;
+
+	cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p\n",
+			CIFS_I(inode)->fscache, page, inode);
+	ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
+					 cifs_readpage_from_fscache_complete,
+					 NULL,
+					 GFP_KERNEL);
+	switch (ret) {
+
+	case 0: /* page found in fscache, read submitted */
+		cFYI(1, "CIFS: readpage_from_fscache: submitted\n");
+		return ret;
+	case -ENOBUFS:	/* page won't be cached */
+	case -ENODATA:	/* page not in cache */
+		cFYI(1, "CIFS: readpage_from_fscache %d\n", ret);
+		return 1;
+
+	default:
+		cFYI(1, "unknown error ret = %d", ret);
+	}
+	return ret;
+}
+
+/*
+ * Retrieve a set of pages from FS-Cache
+ */
+int __cifs_readpages_from_fscache(struct inode *inode,
+				struct address_space *mapping,
+				struct list_head *pages,
+				unsigned *nr_pages)
+{
+	int ret;
+
+	cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)\n",
+			CIFS_I(inode)->fscache, *nr_pages, inode);
+	ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
+					  pages, nr_pages,
+					  cifs_readpage_from_fscache_complete,
+					  NULL,
+					  mapping_gfp_mask(mapping));
+	switch (ret) {
+	case 0:	/* read submitted to the cache for all pages */
+		cFYI(1, "CIFS: readpages_from_fscache\n");
+		return ret;
+
+	case -ENOBUFS:	/* some pages are not cached and can't be */
+	case -ENODATA:	/* some pages are not cached */
+		cFYI(1, "CIFS: readpages_from_fscache: no page\n");
+		return 1;
+
+	default:
+		cFYI(1, "unknown error ret = %d", ret);
+	}
+
+	return ret;
+}
+
 void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
 {
 	int ret;
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index e34d8ab..03bd3fe 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -31,7 +31,6 @@ extern const struct fscache_cookie_def cifs_fscache_server_index_def;
 extern const struct fscache_cookie_def cifs_fscache_super_index_def;
 extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
 
-
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
 
@@ -49,6 +48,11 @@ extern void cifs_fscache_reset_inode_cookie(struct inode *);
 
 extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
 extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
+extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
+extern int __cifs_readpages_from_fscache(struct inode *,
+					 struct address_space *,
+					 struct list_head *,
+					 unsigned *);
 
 extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
 
@@ -59,6 +63,26 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
 		__cifs_fscache_invalidate_page(page, inode);
 }
 
+static inline int cifs_readpage_from_fscache(struct inode *inode,
+					     struct page *page)
+{
+	if (CIFS_I(inode)->fscache)
+		return __cifs_readpage_from_fscache(inode, page);
+
+	return -ENOBUFS;
+}
+
+static inline int cifs_readpages_from_fscache(struct inode *inode,
+					      struct address_space *mapping,
+					      struct list_head *pages,
+					      unsigned *nr_pages)
+{
+	if (CIFS_I(inode)->fscache)
+		return __cifs_readpages_from_fscache(inode, mapping, pages,
+						     nr_pages);
+	return -ENOBUFS;
+}
+
 static inline void cifs_readpage_to_fscache(struct inode *inode,
 					    struct page *page)
 {
@@ -89,6 +113,20 @@ static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)
 
 static inline int cifs_fscache_invalidate_page(struct page *page,
 			struct inode *) {}
+static inline int
+cifs_readpage_from_fscache(struct inode *inode, struct page *page)
+{
+	return -ENOBUFS;
+}
+
+static inline int cifs_readpages_from_fscache(struct inode *inode,
+					      struct address_space *mapping,
+					      struct list_head *pages,
+					      unsigned *nr_pages)
+{
+	return -ENOBUFS;
+}
+
 static inline void cifs_readpage_to_fscache(struct inode *inode,
 			struct page *page) {}
 
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 10/10] cifs: add mount option to enable local caching
       [not found] <yes>
@ 2010-06-22 15:25   ` Suresh Jayaraman
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:25 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

Add a mount option 'fsc' to enable local caching on CIFS.

As the cifs-utils (userspace) changes are not done yet, this patch enables
'fsc' by default to assist testing.

Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
---
 fs/cifs/cifs_fs_sb.h |    1 +
 fs/cifs/connect.c    |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 246a167..9e77145 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -35,6 +35,7 @@
 #define CIFS_MOUNT_DYNPERM      0x1000 /* allow in-memory only mode setting   */
 #define CIFS_MOUNT_NOPOSIXBRL   0x2000 /* mandatory not posix byte range lock */
 #define CIFS_MOUNT_NOSSYNC      0x4000 /* don't do slow SMBflush on every sync*/
+#define CIFS_MOUNT_FSCACHE	0x8000 /* local caching enabled */
 
 struct cifs_sb_info {
 	struct cifsTconInfo *tcon;	/* primary mount */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4844dbd..6c6ff3c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -98,6 +98,7 @@ struct smb_vol {
 	bool noblocksnd:1;
 	bool noautotune:1;
 	bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
+	bool fsc:1;	/* enable fscache */
 	unsigned int rsize;
 	unsigned int wsize;
 	bool sockopt_tcp_nodelay:1;
@@ -843,6 +844,9 @@ cifs_parse_mount_options(char *options, const char *devname,
 	/* default to using server inode numbers where available */
 	vol->server_ino = 1;
 
+	/* XXX: default to fsc for testing until mount.cifs pieces are done */
+	vol->fsc = 1;
+
 	if (!options)
 		return 1;
 
@@ -1332,6 +1336,8 @@ cifs_parse_mount_options(char *options, const char *devname,
 			printk(KERN_WARNING "CIFS: Mount option noac not "
 				"supported. Instead set "
 				"/proc/fs/cifs/LookupCacheEnabled to 0\n");
+		} else if (strnicmp(data, "fsc", 3) == 0) {
+			vol->fsc = true;
 		} else
 			printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
 						data);
@@ -2405,6 +2411,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
 	if (pvolume_info->dynperm)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
+	if (pvolume_info->fsc)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
 	if (pvolume_info->direct_io) {
 		cFYI(1, "mounting share using direct i/o");
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
-- 
1.6.4.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC][PATCH 10/10] cifs: add mount option to enable local caching
@ 2010-06-22 15:25   ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-22 15:25 UTC (permalink / raw)
  To: Steve French; +Cc: linux-cifs, linux-fsdevel, linux-kernel, David Howells

Add a mount option 'fsc' to enable local caching on CIFS.

As the cifs-utils (userspace) changes are not done yet, this patch enables
'fsc' by default to assist testing.

Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
---
 fs/cifs/cifs_fs_sb.h |    1 +
 fs/cifs/connect.c    |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 246a167..9e77145 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -35,6 +35,7 @@
 #define CIFS_MOUNT_DYNPERM      0x1000 /* allow in-memory only mode setting   */
 #define CIFS_MOUNT_NOPOSIXBRL   0x2000 /* mandatory not posix byte range lock */
 #define CIFS_MOUNT_NOSSYNC      0x4000 /* don't do slow SMBflush on every sync*/
+#define CIFS_MOUNT_FSCACHE	0x8000 /* local caching enabled */
 
 struct cifs_sb_info {
 	struct cifsTconInfo *tcon;	/* primary mount */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4844dbd..6c6ff3c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -98,6 +98,7 @@ struct smb_vol {
 	bool noblocksnd:1;
 	bool noautotune:1;
 	bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
+	bool fsc:1;	/* enable fscache */
 	unsigned int rsize;
 	unsigned int wsize;
 	bool sockopt_tcp_nodelay:1;
@@ -843,6 +844,9 @@ cifs_parse_mount_options(char *options, const char *devname,
 	/* default to using server inode numbers where available */
 	vol->server_ino = 1;
 
+	/* XXX: default to fsc for testing until mount.cifs pieces are done */
+	vol->fsc = 1;
+
 	if (!options)
 		return 1;
 
@@ -1332,6 +1336,8 @@ cifs_parse_mount_options(char *options, const char *devname,
 			printk(KERN_WARNING "CIFS: Mount option noac not "
 				"supported. Instead set "
 				"/proc/fs/cifs/LookupCacheEnabled to 0\n");
+		} else if (strnicmp(data, "fsc", 3) == 0) {
+			vol->fsc = true;
 		} else
 			printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
 						data);
@@ -2405,6 +2411,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
 	if (pvolume_info->dynperm)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
+	if (pvolume_info->fsc)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
 	if (pvolume_info->direct_io) {
 		cFYI(1, "mounting share using direct i/o");
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
-- 
1.6.4.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion
  2010-06-22 15:22 ` [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion Suresh Jayaraman
@ 2010-06-22 21:37       ` Jeff Layton
  0 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-22 21:37 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

On Tue, 22 Jun 2010 20:52:50 +0530
Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Add conditional compile macros to guard the header file against multiple
> inclusion.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
> ---
>  fs/cifs/cifsglob.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index a88479c..6b2c39d 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -16,6 +16,9 @@
>   *   the GNU Lesser General Public License for more details.
>   *
>   */
> +#ifndef _CIFS_GLOB_H
> +#define _CIFS_GLOB_H
> +
>  #include <linux/in.h>
>  #include <linux/in6.h>
>  #include <linux/slab.h>
> @@ -733,3 +736,5 @@ GLOBAL_EXTERN unsigned int cifs_min_small;  /* min size of small buf pool */
>  GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
>  
>  extern const struct slow_work_ops cifs_oplock_break_ops;
> +
> +#endif	/* _CIFS_GLOB_H */

Strong ACK

Acked-by: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion
@ 2010-06-22 21:37       ` Jeff Layton
  0 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-22 21:37 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel, David Howells

On Tue, 22 Jun 2010 20:52:50 +0530
Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Add conditional compile macros to guard the header file against multiple
> inclusion.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
> ---
>  fs/cifs/cifsglob.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index a88479c..6b2c39d 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -16,6 +16,9 @@
>   *   the GNU Lesser General Public License for more details.
>   *
>   */
> +#ifndef _CIFS_GLOB_H
> +#define _CIFS_GLOB_H
> +
>  #include <linux/in.h>
>  #include <linux/in6.h>
>  #include <linux/slab.h>
> @@ -733,3 +736,5 @@ GLOBAL_EXTERN unsigned int cifs_min_small;  /* min size of small buf pool */
>  GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
>  
>  extern const struct slow_work_ops cifs_oplock_break_ops;
> +
> +#endif	/* _CIFS_GLOB_H */

Strong ACK

Acked-by: Jeff Layton <jlayton@samba.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
  2010-06-22 15:23   ` Suresh Jayaraman
@ 2010-06-22 21:52       ` Jeff Layton
  -1 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-22 21:52 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

On Tue, 22 Jun 2010 20:53:18 +0530
Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Define server-level cache index objects (as managed by TCP_ServerInfo structs).
> Each server object is created in the CIFS top-level index object and is itself
> an index into which superblock-level objects are inserted.
> 
> Currently, the server objects are keyed by hostname.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
> ---
>  fs/cifs/Makefile   |    2 +-
>  fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
>  fs/cifs/cifsglob.h |    3 +++
>  fs/cifs/connect.c  |    4 ++++
>  fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/cifs/fscache.h  |   12 ++++++++++++
>  6 files changed, 92 insertions(+), 1 deletion(-)
>  create mode 100644 fs/cifs/fscache.c
> 
> Index: cifs-2.6/fs/cifs/Makefile
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/Makefile
> +++ cifs-2.6/fs/cifs/Makefile
> @@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
>  
>  cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
>  
> -cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
> +cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
> Index: cifs-2.6/fs/cifs/cache.c
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/cache.c
> +++ cifs-2.6/fs/cifs/cache.c
> @@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
>  	fscache_unregister_netfs(&cifs_fscache_netfs);
>  }
>  
> +/*
> + * Server object currently keyed by hostname
> + */
> +static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
> +				   void *buffer, uint16_t maxbuf)
> +{
> +	const struct TCP_Server_Info *server = cookie_netfs_data;
> +	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
> +

Would a tuple of address/family/port be a better choice here? Imagine I
mount "foo" and then later mount "foor.bar.baz". If they are the same
address and only the UNC differs, then you won't get the benefit of
the cache, right?

> +	if (len > maxbuf)
> +		return 0;
> +
> +	memcpy(buffer, server->hostname, len);
> +
> +	return len;
> +}
> +
> +/*
> + * Server object for FS-Cache
> + */
> +const struct fscache_cookie_def cifs_fscache_server_index_def = {
> +	.name = "CIFS.server",
> +	.type = FSCACHE_COOKIE_TYPE_INDEX,
> +	.get_key = cifs_server_get_key,
> +};
> Index: cifs-2.6/fs/cifs/cifsglob.h
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/cifsglob.h
> +++ cifs-2.6/fs/cifs/cifsglob.h
> @@ -193,6 +193,9 @@ struct TCP_Server_Info {
>  	bool	sec_mskerberos;		/* supports legacy MS Kerberos */
>  	bool	sec_kerberosu2u;	/* supports U2U Kerberos */
>  	bool	sec_ntlmssp;		/* supports NTLMSSP */
> +#ifdef CONFIG_CIFS_FSCACHE
> +	struct fscache_cookie   *fscache; /* client index cache cookie */
> +#endif
>  };
>  
>  /*
> Index: cifs-2.6/fs/cifs/connect.c
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/connect.c
> +++ cifs-2.6/fs/cifs/connect.c
> @@ -48,6 +48,7 @@
>  #include "nterr.h"
>  #include "rfc1002pdu.h"
>  #include "cn_cifs.h"
> +#include "fscache.h"
>  
>  #define CIFS_PORT 445
>  #define RFC1001_PORT 139
> @@ -1453,6 +1454,8 @@ cifs_put_tcp_session(struct TCP_Server_I
>  		return;
>  	}
>  
> +	cifs_fscache_release_client_cookie(server);
> +
>  	list_del_init(&server->tcp_ses_list);
>  	write_unlock(&cifs_tcp_ses_lock);
>  
> @@ -1572,6 +1575,7 @@ cifs_get_tcp_session(struct smb_vol *vol
>  		goto out_err;
>  	}
>  
> +	cifs_fscache_get_client_cookie(tcp_ses);
>  	/* thread spawned, put it on the list */
>  	write_lock(&cifs_tcp_ses_lock);
>  	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
> Index: cifs-2.6/fs/cifs/fscache.c
> ===================================================================
> --- /dev/null
> +++ cifs-2.6/fs/cifs/fscache.c
> @@ -0,0 +1,47 @@
> +/*
> + *   fs/cifs/fscache.c - CIFS filesystem cache interface
> + *
> + *   Copyright (c) 2010 Novell, Inc.
> + *   Authors(s): Suresh Jayaraman (sjayaraman-l3A5Bk7waGM@public.gmane.org>
> + *
> + *   This library is free software; you can redistribute it and/or modify
> + *   it under the terms of the GNU Lesser General Public License as published
> + *   by the Free Software Foundation; either version 2.1 of the License, or
> + *   (at your option) any later version.
> + *
> + *   This library 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 Lesser General Public License for more details.
> + *
> + *   You should have received a copy of the GNU Lesser General Public License
> + *   along with this library; if not, write to the Free Software
> + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/mm.h>
> +#include <linux/in6.h>
> +
> +#include "fscache.h"
> +#include "cifsglob.h"
> +#include "cifs_debug.h"
> +
> +void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
> +{
> +	server->fscache =
> +		fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
> +				&cifs_fscache_server_index_def, server);
> +	cFYI(1, "CIFS: get client cookie (0x%p/0x%p)\n",
> +				server, server->fscache);
> +}
> +
> +void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
> +{
> +	cFYI(1, "CIFS: release client cookie (0x%p/0x%p)\n",
> +				server, server->fscache);
> +	fscache_relinquish_cookie(server->fscache, 0);
> +	server->fscache = NULL;
> +}
> +
> Index: cifs-2.6/fs/cifs/fscache.h
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/fscache.h
> +++ cifs-2.6/fs/cifs/fscache.h
> @@ -27,14 +27,26 @@
>  #ifdef CONFIG_CIFS_FSCACHE
>  
>  extern struct fscache_netfs cifs_fscache_netfs;
> +extern const struct fscache_cookie_def cifs_fscache_server_index_def;
>  
>  extern int cifs_fscache_register(void);
>  extern void cifs_fscache_unregister(void);
>  
> +/*
> + * fscache.c
> + */
> +extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
> +extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
> +
>  #else /* CONFIG_CIFS_FSCACHE */
>  static inline int cifs_fscache_register(void) { return 0; }
>  static inline void cifs_fscache_unregister(void) {}
>  
> +static inline void
> +cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
> +static inline void
> +cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
> +
>  #endif /* CONFIG_CIFS_FSCACHE */
>  
>  #endif /* _CIFS_FSCACHE_H */
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Jeff Layton <jlayton-vpEMnDpepFuMZCB2o+C8xQ@public.gmane.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
@ 2010-06-22 21:52       ` Jeff Layton
  0 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-22 21:52 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel, David Howells

On Tue, 22 Jun 2010 20:53:18 +0530
Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Define server-level cache index objects (as managed by TCP_ServerInfo structs).
> Each server object is created in the CIFS top-level index object and is itself
> an index into which superblock-level objects are inserted.
> 
> Currently, the server objects are keyed by hostname.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
> ---
>  fs/cifs/Makefile   |    2 +-
>  fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
>  fs/cifs/cifsglob.h |    3 +++
>  fs/cifs/connect.c  |    4 ++++
>  fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  fs/cifs/fscache.h  |   12 ++++++++++++
>  6 files changed, 92 insertions(+), 1 deletion(-)
>  create mode 100644 fs/cifs/fscache.c
> 
> Index: cifs-2.6/fs/cifs/Makefile
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/Makefile
> +++ cifs-2.6/fs/cifs/Makefile
> @@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
>  
>  cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
>  
> -cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
> +cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
> Index: cifs-2.6/fs/cifs/cache.c
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/cache.c
> +++ cifs-2.6/fs/cifs/cache.c
> @@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
>  	fscache_unregister_netfs(&cifs_fscache_netfs);
>  }
>  
> +/*
> + * Server object currently keyed by hostname
> + */
> +static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
> +				   void *buffer, uint16_t maxbuf)
> +{
> +	const struct TCP_Server_Info *server = cookie_netfs_data;
> +	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
> +

Would a tuple of address/family/port be a better choice here? Imagine I
mount "foo" and then later mount "foor.bar.baz". If they are the same
address and only the UNC differs, then you won't get the benefit of
the cache, right?

> +	if (len > maxbuf)
> +		return 0;
> +
> +	memcpy(buffer, server->hostname, len);
> +
> +	return len;
> +}
> +
> +/*
> + * Server object for FS-Cache
> + */
> +const struct fscache_cookie_def cifs_fscache_server_index_def = {
> +	.name = "CIFS.server",
> +	.type = FSCACHE_COOKIE_TYPE_INDEX,
> +	.get_key = cifs_server_get_key,
> +};
> Index: cifs-2.6/fs/cifs/cifsglob.h
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/cifsglob.h
> +++ cifs-2.6/fs/cifs/cifsglob.h
> @@ -193,6 +193,9 @@ struct TCP_Server_Info {
>  	bool	sec_mskerberos;		/* supports legacy MS Kerberos */
>  	bool	sec_kerberosu2u;	/* supports U2U Kerberos */
>  	bool	sec_ntlmssp;		/* supports NTLMSSP */
> +#ifdef CONFIG_CIFS_FSCACHE
> +	struct fscache_cookie   *fscache; /* client index cache cookie */
> +#endif
>  };
>  
>  /*
> Index: cifs-2.6/fs/cifs/connect.c
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/connect.c
> +++ cifs-2.6/fs/cifs/connect.c
> @@ -48,6 +48,7 @@
>  #include "nterr.h"
>  #include "rfc1002pdu.h"
>  #include "cn_cifs.h"
> +#include "fscache.h"
>  
>  #define CIFS_PORT 445
>  #define RFC1001_PORT 139
> @@ -1453,6 +1454,8 @@ cifs_put_tcp_session(struct TCP_Server_I
>  		return;
>  	}
>  
> +	cifs_fscache_release_client_cookie(server);
> +
>  	list_del_init(&server->tcp_ses_list);
>  	write_unlock(&cifs_tcp_ses_lock);
>  
> @@ -1572,6 +1575,7 @@ cifs_get_tcp_session(struct smb_vol *vol
>  		goto out_err;
>  	}
>  
> +	cifs_fscache_get_client_cookie(tcp_ses);
>  	/* thread spawned, put it on the list */
>  	write_lock(&cifs_tcp_ses_lock);
>  	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
> Index: cifs-2.6/fs/cifs/fscache.c
> ===================================================================
> --- /dev/null
> +++ cifs-2.6/fs/cifs/fscache.c
> @@ -0,0 +1,47 @@
> +/*
> + *   fs/cifs/fscache.c - CIFS filesystem cache interface
> + *
> + *   Copyright (c) 2010 Novell, Inc.
> + *   Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
> + *
> + *   This library is free software; you can redistribute it and/or modify
> + *   it under the terms of the GNU Lesser General Public License as published
> + *   by the Free Software Foundation; either version 2.1 of the License, or
> + *   (at your option) any later version.
> + *
> + *   This library 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 Lesser General Public License for more details.
> + *
> + *   You should have received a copy of the GNU Lesser General Public License
> + *   along with this library; if not, write to the Free Software
> + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/mm.h>
> +#include <linux/in6.h>
> +
> +#include "fscache.h"
> +#include "cifsglob.h"
> +#include "cifs_debug.h"
> +
> +void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
> +{
> +	server->fscache =
> +		fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
> +				&cifs_fscache_server_index_def, server);
> +	cFYI(1, "CIFS: get client cookie (0x%p/0x%p)\n",
> +				server, server->fscache);
> +}
> +
> +void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
> +{
> +	cFYI(1, "CIFS: release client cookie (0x%p/0x%p)\n",
> +				server, server->fscache);
> +	fscache_relinquish_cookie(server->fscache, 0);
> +	server->fscache = NULL;
> +}
> +
> Index: cifs-2.6/fs/cifs/fscache.h
> ===================================================================
> --- cifs-2.6.orig/fs/cifs/fscache.h
> +++ cifs-2.6/fs/cifs/fscache.h
> @@ -27,14 +27,26 @@
>  #ifdef CONFIG_CIFS_FSCACHE
>  
>  extern struct fscache_netfs cifs_fscache_netfs;
> +extern const struct fscache_cookie_def cifs_fscache_server_index_def;
>  
>  extern int cifs_fscache_register(void);
>  extern void cifs_fscache_unregister(void);
>  
> +/*
> + * fscache.c
> + */
> +extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
> +extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
> +
>  #else /* CONFIG_CIFS_FSCACHE */
>  static inline int cifs_fscache_register(void) { return 0; }
>  static inline void cifs_fscache_unregister(void) {}
>  
> +static inline void
> +cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
> +static inline void
> +cifs_fscache_get_client_cookie(struct TCP_Server_Info *server); {}
> +
>  #endif /* CONFIG_CIFS_FSCACHE */
>  
>  #endif /* _CIFS_FSCACHE_H */
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Jeff Layton <jlayton@poochiereds.net>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
  2010-06-22 21:52       ` Jeff Layton
@ 2010-06-23  5:34           ` Suresh Jayaraman
  -1 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-23  5:34 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

On 06/23/2010 03:22 AM, Jeff Layton wrote:
> On Tue, 22 Jun 2010 20:53:18 +0530
> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> 
>> Define server-level cache index objects (as managed by TCP_ServerInfo structs).
>> Each server object is created in the CIFS top-level index object and is itself
>> an index into which superblock-level objects are inserted.
>>
>> Currently, the server objects are keyed by hostname.
>>
>> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
>> ---
>>  fs/cifs/Makefile   |    2 +-
>>  fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
>>  fs/cifs/cifsglob.h |    3 +++
>>  fs/cifs/connect.c  |    4 ++++
>>  fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>  fs/cifs/fscache.h  |   12 ++++++++++++
>>  6 files changed, 92 insertions(+), 1 deletion(-)
>>  create mode 100644 fs/cifs/fscache.c
>>
>> Index: cifs-2.6/fs/cifs/Makefile
>> ===================================================================
>> --- cifs-2.6.orig/fs/cifs/Makefile
>> +++ cifs-2.6/fs/cifs/Makefile
>> @@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
>>  
>>  cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
>>  
>> -cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
>> +cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
>> Index: cifs-2.6/fs/cifs/cache.c
>> ===================================================================
>> --- cifs-2.6.orig/fs/cifs/cache.c
>> +++ cifs-2.6/fs/cifs/cache.c
>> @@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
>>  	fscache_unregister_netfs(&cifs_fscache_netfs);
>>  }
>>  
>> +/*
>> + * Server object currently keyed by hostname
>> + */
>> +static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
>> +				   void *buffer, uint16_t maxbuf)
>> +{
>> +	const struct TCP_Server_Info *server = cookie_netfs_data;
>> +	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
>> +
> 
> Would a tuple of address/family/port be a better choice here? Imagine I
> mount "foo" and then later mount "foor.bar.baz". If they are the same
> address and only the UNC differs, then you won't get the benefit of
> the cache, right?
> 

Good point. I'll fix it up when I do a respin.

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
@ 2010-06-23  5:34           ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-23  5:34 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel, David Howells

On 06/23/2010 03:22 AM, Jeff Layton wrote:
> On Tue, 22 Jun 2010 20:53:18 +0530
> Suresh Jayaraman <sjayaraman@suse.de> wrote:
> 
>> Define server-level cache index objects (as managed by TCP_ServerInfo structs).
>> Each server object is created in the CIFS top-level index object and is itself
>> an index into which superblock-level objects are inserted.
>>
>> Currently, the server objects are keyed by hostname.
>>
>> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>
>> ---
>>  fs/cifs/Makefile   |    2 +-
>>  fs/cifs/cache.c    |   25 +++++++++++++++++++++++++
>>  fs/cifs/cifsglob.h |    3 +++
>>  fs/cifs/connect.c  |    4 ++++
>>  fs/cifs/fscache.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>>  fs/cifs/fscache.h  |   12 ++++++++++++
>>  6 files changed, 92 insertions(+), 1 deletion(-)
>>  create mode 100644 fs/cifs/fscache.c
>>
>> Index: cifs-2.6/fs/cifs/Makefile
>> ===================================================================
>> --- cifs-2.6.orig/fs/cifs/Makefile
>> +++ cifs-2.6/fs/cifs/Makefile
>> @@ -12,4 +12,4 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spneg
>>  
>>  cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
>>  
>> -cifs-$(CONFIG_CIFS_FSCACHE) += cache.o
>> +cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
>> Index: cifs-2.6/fs/cifs/cache.c
>> ===================================================================
>> --- cifs-2.6.orig/fs/cifs/cache.c
>> +++ cifs-2.6/fs/cifs/cache.c
>> @@ -51,3 +51,28 @@ void cifs_fscache_unregister(void)
>>  	fscache_unregister_netfs(&cifs_fscache_netfs);
>>  }
>>  
>> +/*
>> + * Server object currently keyed by hostname
>> + */
>> +static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
>> +				   void *buffer, uint16_t maxbuf)
>> +{
>> +	const struct TCP_Server_Info *server = cookie_netfs_data;
>> +	uint16_t len = strnlen(server->hostname, sizeof(server->hostname));
>> +
> 
> Would a tuple of address/family/port be a better choice here? Imagine I
> mount "foo" and then later mount "foor.bar.baz". If they are the same
> address and only the UNC differs, then you won't get the benefit of
> the cache, right?
> 

Good point. I'll fix it up when I do a respin.

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 03/10] cifs: register CIFS for caching
       [not found] <yes>
@ 2010-06-23 16:51     ` David Howells
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                       ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 16:51 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> +	rc = cifs_fscache_register();
> +	if (rc)
> +		goto out;
> +
>  	rc = cifs_init_inodecache();
>  	if (rc)
>  		goto out_clean_proc;
> @@ -949,8 +954,10 @@ init_cifs(void)
>  	cifs_destroy_mids();
>   out_destroy_inodecache:
>  	cifs_destroy_inodecache();
> +	cifs_fscache_unregister();
>   out_clean_proc:

This is incorrect.  You need to call cifs_fscache_unregister() if
cifs_init_inodecache() fails.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 03/10] cifs: register CIFS for caching
@ 2010-06-23 16:51     ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 16:51 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> +	rc = cifs_fscache_register();
> +	if (rc)
> +		goto out;
> +
>  	rc = cifs_init_inodecache();
>  	if (rc)
>  		goto out_clean_proc;
> @@ -949,8 +954,10 @@ init_cifs(void)
>  	cifs_destroy_mids();
>   out_destroy_inodecache:
>  	cifs_destroy_inodecache();
> +	cifs_fscache_unregister();
>   out_clean_proc:

This is incorrect.  You need to call cifs_fscache_unregister() if
cifs_init_inodecache() fails.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache
       [not found] <yes>
                   ` (18 preceding siblings ...)
       [not found] ` <1277220189-3485-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
@ 2010-06-23 16:54 ` David Howells
       [not found] ` <1277220206-3559-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
                   ` (71 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 16:54 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Define server-level cache index objects (as managed by TCP_ServerInfo
> structs).  Each server object is created in the CIFS top-level index object
> and is itself an index into which superblock-level objects are inserted.
> 
> Currently, the server objects are keyed by hostname.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>

Looks reasonable, apart from the index key.  I agree with Jeff that you
probably want {address,port,family} rather than a hostname.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
       [not found] <yes>
@ 2010-06-23 16:58     ` David Howells
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                       ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 16:58 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Define superblock-level cache index objects (managed by cifsTconInfo
> structs).  Each superblock object is created in a server-level index object
> and in itself an index into which inode-level objects are inserted.
> 
> Currently, the superblock objects are keyed by sharename.

Seems reasonable.  Is there any way you can check that the share you are
looking at on a server is the same as the last time you looked?  Can you
validate the root directory of the share in some way?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
@ 2010-06-23 16:58     ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 16:58 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Define superblock-level cache index objects (managed by cifsTconInfo
> structs).  Each superblock object is created in a server-level index object
> and in itself an index into which inode-level objects are inserted.
> 
> Currently, the superblock objects are keyed by sharename.

Seems reasonable.  Is there any way you can check that the share you are
looking at on a server is the same as the last time you looked?  Can you
validate the root directory of the share in some way?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
       [not found] <yes>
@ 2010-06-23 17:02     ` David Howells
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                       ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:02 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Define inode-level data storage objects (managed by cifsInodeInfo structs).
> Each inode-level object is created in a super-block level object and is
> itself a data storage object in to which pages from the inode are stored.
> 
> The inode object is keyed by UniqueId. The coherency data being used is
> LastWriteTime and the file size.

Isn't there a file creation time too?

I take it you don't support caching on files that are open for writing at this
time?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-23 17:02     ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:02 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Define inode-level data storage objects (managed by cifsInodeInfo structs).
> Each inode-level object is created in a super-block level object and is
> itself a data storage object in to which pages from the inode are stored.
> 
> The inode object is keyed by UniqueId. The coherency data being used is
> LastWriteTime and the file size.

Isn't there a file creation time too?

I take it you don't support caching on files that are open for writing at this
time?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 07/10] cifs: FS-Cache page management
       [not found] <yes>
                   ` (21 preceding siblings ...)
       [not found] ` <1277220214-3597-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
@ 2010-06-23 17:05 ` David Howells
       [not found] ` <1277220240-3674-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
                   ` (68 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:05 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Takes care of invalidation and release of FS-Cache marked pages and also
> invalidation of the FsCache page flag when the inode is removed.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 08/10] cifs: store pages into local cache
       [not found] <yes>
@ 2010-06-23 17:06     ` David Howells
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                       ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:06 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Store pages from an CIFS inode into the data storage object associated with
> that inode.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>

Acked-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 08/10] cifs: store pages into local cache
@ 2010-06-23 17:06     ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:06 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Store pages from an CIFS inode into the data storage object associated with
> that inode.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 09/10] cifs: read pages from FS-Cache
       [not found] <yes>
@ 2010-06-23 17:07     ` David Howells
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                       ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:07 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> Read pages from a FS-Cache data storage object into a CIFS inode.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>

Acked-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 09/10] cifs: read pages from FS-Cache
@ 2010-06-23 17:07     ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:07 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Read pages from a FS-Cache data storage object into a CIFS inode.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 10/10] cifs: add mount option to enable local caching
       [not found] <yes>
                   ` (24 preceding siblings ...)
       [not found] ` <1277220261-3717-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
@ 2010-06-23 17:08 ` David Howells
  2010-08-11  5:21 ` [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1 Tanmay Upadhyay
                   ` (65 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-23 17:08 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Add a mount option 'fsc' to enable local caching on CIFS.
> 
> As the cifs-utils (userspace) changes are not done yet, this patch enables
> 'fsc' by default to assist testing.
> 
> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de>

Acked-by: David Howells <dhowells@redhat.com>

(Give or take the debugging bit)

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 10/10] cifs: add mount option to enable local caching
  2010-06-22 15:25   ` Suresh Jayaraman
  (?)
@ 2010-06-23 18:32   ` Scott Lovenberg
       [not found]     ` <4C225338.9010807-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  -1 siblings, 1 reply; 716+ messages in thread
From: Scott Lovenberg @ 2010-06-23 18:32 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel, David Howells

On 6/22/2010 11:25 AM, Suresh Jayaraman wrote:
> Add a mount option 'fsc' to enable local caching on CIFS.
>
> As the cifs-utils (userspace) changes are not done yet, this patch enables
> 'fsc' by default to assist testing.
>    
[...]
> @@ -1332,6 +1336,8 @@ cifs_parse_mount_options(char *options, const char *devname,
>   			printk(KERN_WARNING "CIFS: Mount option noac not "
>   				"supported. Instead set "
>   				"/proc/fs/cifs/LookupCacheEnabled to 0\n");
> +		} else if (strnicmp(data, "fsc", 3) == 0) {
> +			vol->fsc = true;
>   		} else
>   			printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
>   						data);
> @@ -2405,6 +2411,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
>   		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
>   	if (pvolume_info->dynperm)
>   		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
> +	if (pvolume_info->fsc)
> +		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
>   	if (pvolume_info->direct_io) {
>   		cFYI(1, "mounting share using direct i/o");
>   		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
>    
I reworked the CIFS mount option parsing a while back; I'm not sure 
whether that patch was going to be in the 2.6.35 tree or not (the window 
just opened, didn't it?).

Jeff, Steve, can you confirm if that patch is going to be in 2.6.35?

Patch refs: http://patchwork.ozlabs.org/patch/53059/  and 
http://patchwork.ozlabs.org/patch/53674/

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 10/10] cifs: add mount option to enable local caching
  2010-06-23 18:32   ` Scott Lovenberg
@ 2010-06-25 10:48         ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 10:48 UTC (permalink / raw)
  To: Scott Lovenberg
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Howells

On 06/24/2010 12:02 AM, Scott Lovenberg wrote:
> On 6/22/2010 11:25 AM, Suresh Jayaraman wrote:
>> Add a mount option 'fsc' to enable local caching on CIFS.
>>
>> As the cifs-utils (userspace) changes are not done yet, this patch
>> enables
>> 'fsc' by default to assist testing.
>>    
> [...]
>> @@ -1332,6 +1336,8 @@ cifs_parse_mount_options(char *options, const
>> char *devname,
>>               printk(KERN_WARNING "CIFS: Mount option noac not "
>>                   "supported. Instead set "
>>                   "/proc/fs/cifs/LookupCacheEnabled to 0\n");
>> +        } else if (strnicmp(data, "fsc", 3) == 0) {
>> +            vol->fsc = true;
>>           } else
>>               printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
>>                           data);
>> @@ -2405,6 +2411,8 @@ static void setup_cifs_sb(struct smb_vol
>> *pvolume_info,
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
>>       if (pvolume_info->dynperm)
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
>> +    if (pvolume_info->fsc)
>> +        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
>>       if (pvolume_info->direct_io) {
>>           cFYI(1, "mounting share using direct i/o");
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
>>    
> I reworked the CIFS mount option parsing a while back; I'm not sure
> whether that patch was going to be in the 2.6.35 tree or not (the window
> just opened, didn't it?).

Not a problem, I could redo this patch alone when the reworked option
parsing patches get in.

> Jeff, Steve, can you confirm if that patch is going to be in 2.6.35?
> 
> Patch refs: http://patchwork.ozlabs.org/patch/53059/  and
> http://patchwork.ozlabs.org/patch/53674/
> 

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 10/10] cifs: add mount option to enable local caching
@ 2010-06-25 10:48         ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 10:48 UTC (permalink / raw)
  To: Scott Lovenberg
  Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel, David Howells

On 06/24/2010 12:02 AM, Scott Lovenberg wrote:
> On 6/22/2010 11:25 AM, Suresh Jayaraman wrote:
>> Add a mount option 'fsc' to enable local caching on CIFS.
>>
>> As the cifs-utils (userspace) changes are not done yet, this patch
>> enables
>> 'fsc' by default to assist testing.
>>    
> [...]
>> @@ -1332,6 +1336,8 @@ cifs_parse_mount_options(char *options, const
>> char *devname,
>>               printk(KERN_WARNING "CIFS: Mount option noac not "
>>                   "supported. Instead set "
>>                   "/proc/fs/cifs/LookupCacheEnabled to 0\n");
>> +        } else if (strnicmp(data, "fsc", 3) == 0) {
>> +            vol->fsc = true;
>>           } else
>>               printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
>>                           data);
>> @@ -2405,6 +2411,8 @@ static void setup_cifs_sb(struct smb_vol
>> *pvolume_info,
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
>>       if (pvolume_info->dynperm)
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
>> +    if (pvolume_info->fsc)
>> +        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
>>       if (pvolume_info->direct_io) {
>>           cFYI(1, "mounting share using direct i/o");
>>           cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
>>    
> I reworked the CIFS mount option parsing a while back; I'm not sure
> whether that patch was going to be in the 2.6.35 tree or not (the window
> just opened, didn't it?).

Not a problem, I could redo this patch alone when the reworked option
parsing patches get in.

> Jeff, Steve, can you confirm if that patch is going to be in 2.6.35?
> 
> Patch refs: http://patchwork.ozlabs.org/patch/53059/  and
> http://patchwork.ozlabs.org/patch/53674/
> 

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 03/10] cifs: register CIFS for caching
  2010-06-23 16:51     ` David Howells
@ 2010-06-25 10:56         ` Suresh Jayaraman
  -1 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 10:56 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/23/2010 10:21 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> 
>> +	rc = cifs_fscache_register();
>> +	if (rc)
>> +		goto out;
>> +
>>  	rc = cifs_init_inodecache();
>>  	if (rc)
>>  		goto out_clean_proc;
>> @@ -949,8 +954,10 @@ init_cifs(void)
>>  	cifs_destroy_mids();
>>   out_destroy_inodecache:
>>  	cifs_destroy_inodecache();
>> +	cifs_fscache_unregister();
>>   out_clean_proc:
> 
> This is incorrect.  You need to call cifs_fscache_unregister() if
> cifs_init_inodecache() fails.
> 

Doh! I'll fix it.


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 03/10] cifs: register CIFS for caching
@ 2010-06-25 10:56         ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 10:56 UTC (permalink / raw)
  To: David Howells; +Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel

On 06/23/2010 10:21 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman@suse.de> wrote:
> 
>> +	rc = cifs_fscache_register();
>> +	if (rc)
>> +		goto out;
>> +
>>  	rc = cifs_init_inodecache();
>>  	if (rc)
>>  		goto out_clean_proc;
>> @@ -949,8 +954,10 @@ init_cifs(void)
>>  	cifs_destroy_mids();
>>   out_destroy_inodecache:
>>  	cifs_destroy_inodecache();
>> +	cifs_fscache_unregister();
>>   out_clean_proc:
> 
> This is incorrect.  You need to call cifs_fscache_unregister() if
> cifs_init_inodecache() fails.
> 

Doh! I'll fix it.


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
  2010-06-23 16:58     ` David Howells
@ 2010-06-25 12:44         ` Suresh Jayaraman
  -1 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 12:44 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/23/2010 10:28 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> 
>> Define superblock-level cache index objects (managed by cifsTconInfo
>> structs).  Each superblock object is created in a server-level index object
>> and in itself an index into which inode-level objects are inserted.
>>
>> Currently, the superblock objects are keyed by sharename.
> 
> Seems reasonable.  Is there any way you can check that the share you are
> looking at on a server is the same as the last time you looked?  Can you

Good point.

I thought of using TID (Tree identifier; a unique ID for a resource in
use by client) along with sharename. But, Server is free to reuse them
when the tree connection closes and does not guarantee the same Tid for
a particular resource across tree connections.

Also, considering the UNC name of the resource (//server/share) may not
be a good idea too as the cache will not be used when for e.g. IPaddress
is used to mount.

So, if a server does something like this:
   - export a share 'foo' (original server path: /export/vol1/foo)
   - client mounts and uses it
   - server unexports the share 'foo'
   - server exports 'foo' (original sever path: /export/vol2/foo)

we have a bit of problem..

> validate the root directory of the share in some way?
> 

I don't know if there is a way to do this.

Thanks,


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
@ 2010-06-25 12:44         ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 12:44 UTC (permalink / raw)
  To: David Howells; +Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel

On 06/23/2010 10:28 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman@suse.de> wrote:
> 
>> Define superblock-level cache index objects (managed by cifsTconInfo
>> structs).  Each superblock object is created in a server-level index object
>> and in itself an index into which inode-level objects are inserted.
>>
>> Currently, the superblock objects are keyed by sharename.
> 
> Seems reasonable.  Is there any way you can check that the share you are
> looking at on a server is the same as the last time you looked?  Can you

Good point.

I thought of using TID (Tree identifier; a unique ID for a resource in
use by client) along with sharename. But, Server is free to reuse them
when the tree connection closes and does not guarantee the same Tid for
a particular resource across tree connections.

Also, considering the UNC name of the resource (//server/share) may not
be a good idea too as the cache will not be used when for e.g. IPaddress
is used to mount.

So, if a server does something like this:
   - export a share 'foo' (original server path: /export/vol1/foo)
   - client mounts and uses it
   - server unexports the share 'foo'
   - server exports 'foo' (original sever path: /export/vol2/foo)

we have a bit of problem..

> validate the root directory of the share in some way?
> 

I don't know if there is a way to do this.

Thanks,


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-23 17:02     ` David Howells
@ 2010-06-25 12:50         ` Suresh Jayaraman
  -1 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 12:50 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/23/2010 10:32 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> 
>> Define inode-level data storage objects (managed by cifsInodeInfo structs).
>> Each inode-level object is created in a super-block level object and is
>> itself a data storage object in to which pages from the inode are stored.
>>
>> The inode object is keyed by UniqueId. The coherency data being used is
>> LastWriteTime and the file size.
> 
> Isn't there a file creation time too?

I think the creation time is currently being ignored as we won't be able
to accomodate in POSIX stat struct.

> I take it you don't support caching on files that are open for writing at this
> time?
> 

Yes.


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-25 12:50         ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-25 12:50 UTC (permalink / raw)
  To: David Howells; +Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel

On 06/23/2010 10:32 PM, David Howells wrote:
> Suresh Jayaraman <sjayaraman@suse.de> wrote:
> 
>> Define inode-level data storage objects (managed by cifsInodeInfo structs).
>> Each inode-level object is created in a super-block level object and is
>> itself a data storage object in to which pages from the inode are stored.
>>
>> The inode object is keyed by UniqueId. The coherency data being used is
>> LastWriteTime and the file size.
> 
> Isn't there a file creation time too?

I think the creation time is currently being ignored as we won't be able
to accomodate in POSIX stat struct.

> I take it you don't support caching on files that are open for writing at this
> time?
> 

Yes.


-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-23 17:02     ` David Howells
@ 2010-06-25 12:55         ` David Howells
  -1 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 12:55 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:

> I think the creation time is currently being ignored as we won't be able
> to accomodate in POSIX stat struct.

The FS-Cache interface doesn't use the POSIX stat struct, but it could be
really useful to save it and use it for cache coherency inside the kernel.

Out of interest, what does Samba do when it comes to generating a creation time
for UNIX where one does not exist?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-25 12:55         ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 12:55 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> I think the creation time is currently being ignored as we won't be able
> to accomodate in POSIX stat struct.

The FS-Cache interface doesn't use the POSIX stat struct, but it could be
really useful to save it and use it for cache coherency inside the kernel.

Out of interest, what does Samba do when it comes to generating a creation time
for UNIX where one does not exist?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
  2010-06-23 16:58     ` David Howells
  (?)
  (?)
@ 2010-06-25 12:58     ` David Howells
  -1 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 12:58 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Also, considering the UNC name of the resource (//server/share) may not
> be a good idea too as the cache will not be used when for e.g. IPaddress
> is used to mount.

You could convert the UNC name to an IP address, and just use that as your
key.

> > validate the root directory of the share in some way?
>
> I don't know if there is a way to do this.

Is there an inode number or something?  Even the creation time might do.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
  2010-06-23 16:58     ` David Howells
@ 2010-06-25 13:26         ` David Howells
  -1 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 13:26 UTC (permalink / raw)
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Suresh Jayaraman, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> > > validate the root directory of the share in some way?
> >
> > I don't know if there is a way to do this.
> 
> Is there an inode number or something?  Even the creation time might do.

Looking in cifspdu.h, there are a number of things that it might be possible
to use.

 (1) FILE_ALL_INFO: CreationTime, IndexNumber, IndexNumber1, FileName
     (assuming this isn't flattened to '\' or something for the root of a
     share.

 (2) FILE_UNIX_BASIC_INFO: DevMajor, DevMinor, UniqueId.

 (3) FILE_INFO_STANDARD: CreationDate, CreationTime.

 (4) FILE_INFO_BASIC: CreationTime.

 (5) FILE_DIRECTORY_INFO: FileIndex, CreationTime, FileName.

 (6) SEARCH_ID_FULL_DIR_INFO: FileIndex, CreationTime, UniqueId, FileName.

 (7) FILE_BOTH_DIRECTORY_INFO: FileIndex, CreationTime, ShortName, FileName.

 (8) OPEN_RSP_EXT: Fid, CreationTime, VolumeGUID, FileId.

You may have to choose different sets of things, depending on what the server
has on offer.  Also, don't forget, if you can't work out whether a share is
coherent or not from the above, you can always use LastWriteTime, ChangeTime
and EndOfFile and just discard the whole subtree if they differ.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
@ 2010-06-25 13:26         ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 13:26 UTC (permalink / raw)
  Cc: dhowells, Suresh Jayaraman, Steve French, linux-cifs,
	linux-fsdevel, linux-kernel

David Howells <dhowells@redhat.com> wrote:

> > > validate the root directory of the share in some way?
> >
> > I don't know if there is a way to do this.
> 
> Is there an inode number or something?  Even the creation time might do.

Looking in cifspdu.h, there are a number of things that it might be possible
to use.

 (1) FILE_ALL_INFO: CreationTime, IndexNumber, IndexNumber1, FileName
     (assuming this isn't flattened to '\' or something for the root of a
     share.

 (2) FILE_UNIX_BASIC_INFO: DevMajor, DevMinor, UniqueId.

 (3) FILE_INFO_STANDARD: CreationDate, CreationTime.

 (4) FILE_INFO_BASIC: CreationTime.

 (5) FILE_DIRECTORY_INFO: FileIndex, CreationTime, FileName.

 (6) SEARCH_ID_FULL_DIR_INFO: FileIndex, CreationTime, UniqueId, FileName.

 (7) FILE_BOTH_DIRECTORY_INFO: FileIndex, CreationTime, ShortName, FileName.

 (8) OPEN_RSP_EXT: Fid, CreationTime, VolumeGUID, FileId.

You may have to choose different sets of things, depending on what the server
has on offer.  Also, don't forget, if you can't work out whether a share is
coherent or not from the above, you can always use LastWriteTime, ChangeTime
and EndOfFile and just discard the whole subtree if they differ.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 12:55         ` David Howells
@ 2010-06-25 16:53             ` Jeff Layton
  -1 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-25 16:53 UTC (permalink / raw)
  To: David Howells
  Cc: Suresh Jayaraman, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	samba-technical-w/Ol4Ecudpl8XjKLYN78aQ

On Fri, 25 Jun 2010 13:55:49 +0100
David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org> wrote:
> 
> > I think the creation time is currently being ignored as we won't be able
> > to accomodate in POSIX stat struct.
> 
> The FS-Cache interface doesn't use the POSIX stat struct, but it could be
> really useful to save it and use it for cache coherency inside the kernel.
> 
> Out of interest, what does Samba do when it comes to generating a creation time
> for UNIX where one does not exist?
> 

(cc'ing samba-technical since we're talking about the create time)

Looks like it mostly uses the ctime. IMO, the mtime would be a better
choice since it changes less frequently, but I don't guess that it
matters very much.

I have a few patches that make the cifs_iget code do more stringent
checks. One of those makes it use the create time like an i_generation
field to guard against matching inodes that have the same number but
that have undergone a delete/create cycle. They need a bit more testing
but I'm planning to post them in time for 2.6.36.

Because of how samba generates this number, it could be somewhat
problematic to do this. What may save us though is that Linux<->Samba
mostly uses unix extensions unless someone has specifically disabled
them on either end. The unix extension calls don't generally send any
sort of create time field, so we can't rely on it in those codepaths
anyway.

-- 
Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-25 16:53             ` Jeff Layton
  0 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-25 16:53 UTC (permalink / raw)
  To: David Howells
  Cc: Suresh Jayaraman, Steve French, linux-cifs, linux-fsdevel,
	linux-kernel, samba-technical

On Fri, 25 Jun 2010 13:55:49 +0100
David Howells <dhowells@redhat.com> wrote:

> Suresh Jayaraman <sjayaraman@suse.de> wrote:
> 
> > I think the creation time is currently being ignored as we won't be able
> > to accomodate in POSIX stat struct.
> 
> The FS-Cache interface doesn't use the POSIX stat struct, but it could be
> really useful to save it and use it for cache coherency inside the kernel.
> 
> Out of interest, what does Samba do when it comes to generating a creation time
> for UNIX where one does not exist?
> 

(cc'ing samba-technical since we're talking about the create time)

Looks like it mostly uses the ctime. IMO, the mtime would be a better
choice since it changes less frequently, but I don't guess that it
matters very much.

I have a few patches that make the cifs_iget code do more stringent
checks. One of those makes it use the create time like an i_generation
field to guard against matching inodes that have the same number but
that have undergone a delete/create cycle. They need a bit more testing
but I'm planning to post them in time for 2.6.36.

Because of how samba generates this number, it could be somewhat
problematic to do this. What may save us though is that Linux<->Samba
mostly uses unix extensions unless someone has specifically disabled
them on either end. The unix extension calls don't generally send any
sort of create time field, so we can't rely on it in those codepaths
anyway.

-- 
Jeff Layton <jlayton@samba.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 12:55         ` David Howells
  (?)
  (?)
@ 2010-06-25 21:46         ` David Howells
  2010-06-25 22:26             ` Jeff Layton
       [not found]           ` <20100625182651.36800d06-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
  -1 siblings, 2 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 21:46 UTC (permalink / raw)
  To: Jeff Layton
  Cc: dhowells, Suresh Jayaraman, Steve French, linux-cifs,
	linux-fsdevel, linux-kernel, samba-technical

Jeff Layton <jlayton@samba.org> wrote:

> Looks like it mostly uses the ctime. IMO, the mtime would be a better
> choice since it changes less frequently, but I don't guess that it
> matters very much.

I'd've thought mtime changes more frequently since that's altered when data is
written.  ctime is changed when attributes are changed.

Note that Ext4 appears to have a file creation time field in its inode
(struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 21:46         ` David Howells
@ 2010-06-25 22:26             ` Jeff Layton
       [not found]           ` <20100625182651.36800d06-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
  1 sibling, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-25 22:26 UTC (permalink / raw)
  To: David Howells
  Cc: linux-cifs, samba-technical, linux-kernel, Steve French, linux-fsdevel

On Fri, 25 Jun 2010 22:46:38 +0100
David Howells <dhowells@redhat.com> wrote:

> Jeff Layton <jlayton@samba.org> wrote:
> 
> > Looks like it mostly uses the ctime. IMO, the mtime would be a better
> > choice since it changes less frequently, but I don't guess that it
> > matters very much.
> 
> I'd've thought mtime changes more frequently since that's altered when data is
> written.  ctime is changed when attributes are changed.
> 

IIUC, updating mtime for a write is also an attribute change, and that
affects ctime. According to the stat(2) manpage:

       The field st_ctime is changed by writing or by setting  inode  informa-
       tion (i.e., owner, group, link count, mode, etc.).

> Note that Ext4 appears to have a file creation time field in its inode
> (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> 

Is it exposed to userspace in any (standard) way? It would be handy to
have that. While we're wishing...it might also be nice to have a
standard way to get at the i_generation from userspace too.

-- 
Jeff Layton <jlayton@samba.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-25 22:26             ` Jeff Layton
  0 siblings, 0 replies; 716+ messages in thread
From: Jeff Layton @ 2010-06-25 22:26 UTC (permalink / raw)
  To: David Howells
  Cc: Suresh Jayaraman, Steve French, linux-cifs, linux-fsdevel,
	linux-kernel, samba-technical

On Fri, 25 Jun 2010 22:46:38 +0100
David Howells <dhowells@redhat.com> wrote:

> Jeff Layton <jlayton@samba.org> wrote:
> 
> > Looks like it mostly uses the ctime. IMO, the mtime would be a better
> > choice since it changes less frequently, but I don't guess that it
> > matters very much.
> 
> I'd've thought mtime changes more frequently since that's altered when data is
> written.  ctime is changed when attributes are changed.
> 

IIUC, updating mtime for a write is also an attribute change, and that
affects ctime. According to the stat(2) manpage:

       The field st_ctime is changed by writing or by setting  inode  informa-
       tion (i.e., owner, group, link count, mode, etc.).

> Note that Ext4 appears to have a file creation time field in its inode
> (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> 

Is it exposed to userspace in any (standard) way? It would be handy to
have that. While we're wishing...it might also be nice to have a
standard way to get at the i_generation from userspace too.

-- 
Jeff Layton <jlayton@samba.org>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 21:46         ` David Howells
@ 2010-06-25 23:04               ` David Howells
       [not found]           ` <20100625182651.36800d06-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
  1 sibling, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 23:04 UTC (permalink / raw)
  To: Jeff Layton
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Suresh Jayaraman, Steve French,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	samba-technical-w/Ol4Ecudpl8XjKLYN78aQ

Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org> wrote:

> IIUC, updating mtime for a write is also an attribute change, and that
> affects ctime. According to the stat(2) manpage:

You're right.  Okay, ctime is the more frequently changed.

> > Note that Ext4 appears to have a file creation time field in its inode
> > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> 
> Is it exposed to userspace in any (standard) way? It would be handy to
> have that. While we're wishing...it might also be nice to have a
> standard way to get at the i_generation from userspace too.

Not at present, but it's something that could be exported by ioctl() or
getxattr().

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-25 23:04               ` David Howells
  0 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-25 23:04 UTC (permalink / raw)
  To: Jeff Layton
  Cc: dhowells, Suresh Jayaraman, Steve French, linux-cifs,
	linux-fsdevel, linux-kernel, samba-technical

Jeff Layton <jlayton@samba.org> wrote:

> IIUC, updating mtime for a write is also an attribute change, and that
> affects ctime. According to the stat(2) manpage:

You're right.  Okay, ctime is the more frequently changed.

> > Note that Ext4 appears to have a file creation time field in its inode
> > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> 
> Is it exposed to userspace in any (standard) way? It would be handy to
> have that. While we're wishing...it might also be nice to have a
> standard way to get at the i_generation from userspace too.

Not at present, but it's something that could be exported by ioctl() or
getxattr().

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 22:26             ` Jeff Layton
@ 2010-06-25 23:05               ` Steve French
  -1 siblings, 0 replies; 716+ messages in thread
From: Steve French @ 2010-06-25 23:05 UTC (permalink / raw)
  To: Jeff Layton, Aneesh Kumar K.V, Mingming Cao
  Cc: David Howells, Suresh Jayaraman, linux-cifs, linux-fsdevel,
	linux-kernel, samba-technical, Jeff Layton

On Fri, Jun 25, 2010 at 5:26 PM, Jeff Layton <jlayton@samba.org> wrote:
>
> On Fri, 25 Jun 2010 22:46:38 +0100
> David Howells <dhowells@redhat.com> wrote:
>
> > Jeff Layton <jlayton@samba.org> wrote:
> >
> > > Looks like it mostly uses the ctime. IMO, the mtime would be a better
> > > choice since it changes less frequently, but I don't guess that it
> > > matters very much.
> >
> > I'd've thought mtime changes more frequently since that's altered when data is
> > written.  ctime is changed when attributes are changed.
> >
>
> IIUC, updating mtime for a write is also an attribute change, and that
> affects ctime. According to the stat(2) manpage:
>
>       The field st_ctime is changed by writing or by setting  inode  informa-
>       tion (i.e., owner, group, link count, mode, etc.).
>
> > Note that Ext4 appears to have a file creation time field in its inode
> > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> >
>
> Is it exposed to userspace in any (standard) way? It would be handy to
> have that. While we're wishing...it might also be nice to have a
> standard way to get at the i_generation from userspace too.
>

Yes - I have talked with MingMing and Aneesh about those (NFS may
someday be able to use those too).  An obstacle in the past had been
that samba server stores its own fake creation time in an ndr encoded
xattr which complicates things.

MingMing/Annesh -
Xattr or other way to get at birth time?


--
Thanks,

Steve

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and  register them
@ 2010-06-25 23:05               ` Steve French
  0 siblings, 0 replies; 716+ messages in thread
From: Steve French @ 2010-06-25 23:05 UTC (permalink / raw)
  To: Jeff Layton, Aneesh Kumar K.V, Mingming Cao
  Cc: David Howells, Suresh Jayaraman, linux-cifs, linux-fsdevel,
	linux-kernel, samba-technical, Jeff Layton

On Fri, Jun 25, 2010 at 5:26 PM, Jeff Layton <jlayton@samba.org> wrote:
>
> On Fri, 25 Jun 2010 22:46:38 +0100
> David Howells <dhowells@redhat.com> wrote:
>
> > Jeff Layton <jlayton@samba.org> wrote:
> >
> > > Looks like it mostly uses the ctime. IMO, the mtime would be a better
> > > choice since it changes less frequently, but I don't guess that it
> > > matters very much.
> >
> > I'd've thought mtime changes more frequently since that's altered when data is
> > written.  ctime is changed when attributes are changed.
> >
>
> IIUC, updating mtime for a write is also an attribute change, and that
> affects ctime. According to the stat(2) manpage:
>
>       The field st_ctime is changed by writing or by setting  inode  informa-
>       tion (i.e., owner, group, link count, mode, etc.).
>
> > Note that Ext4 appears to have a file creation time field in its inode
> > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use that?
> >
>
> Is it exposed to userspace in any (standard) way? It would be handy to
> have that. While we're wishing...it might also be nice to have a
> standard way to get at the i_generation from userspace too.
>

Yes - I have talked with MingMing and Aneesh about those (NFS may
someday be able to use those too).  An obstacle in the past had been
that samba server stores its own fake creation time in an ndr encoded
xattr which complicates things.

MingMing/Annesh -
Xattr or other way to get at birth time?


--
Thanks,

Steve

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-25 23:05               ` Steve French
  (?)
@ 2010-06-26  0:52               ` Mingming Cao
  2010-06-27 18:17                 ` Aneesh Kumar K. V
  -1 siblings, 1 reply; 716+ messages in thread
From: Mingming Cao @ 2010-06-26  0:52 UTC (permalink / raw)
  To: Steve French
  Cc: linux-cifs, Jeff Layton, samba-technical, linux-kernel,
	David Howells, linux-fsdevel, Aneesh Kumar K.V



Steve French <smfrench@gmail.com> wrote on 06/25/2010 04:05:30 PM:

> Steve French <smfrench@gmail.com>
> 06/25/2010 04:05 PM
>
> To
>
> Jeff Layton <jlayton@samba.org>, "Aneesh Kumar K.V"
> <aneesh.kumar@linux.vnet.ibm.com>, Mingming Cao/Beaverton/IBM@IBMUS
>
> cc
>
> David Howells <dhowells@redhat.com>, Suresh Jayaraman
> <sjayaraman@suse.de>, linux-cifs@vger.kernel.org, linux-
> fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, samba-
> technical@lists.samba.org, Jeff Layton <jlayton@redhat.com>
>
> Subject
>
> Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and
> register them
>
> On Fri, Jun 25, 2010 at 5:26 PM, Jeff Layton <jlayton@samba.org> wrote:
> >
> > On Fri, 25 Jun 2010 22:46:38 +0100
> > David Howells <dhowells@redhat.com> wrote:
> >
> > > Jeff Layton <jlayton@samba.org> wrote:
> > >
> > > > Looks like it mostly uses the ctime. IMO, the mtime would be a
better
> > > > choice since it changes less frequently, but I don't guess that it
> > > > matters very much.
> > >
> > > I'd've thought mtime changes more frequently since that's
> altered when data is
> > > written.  ctime is changed when attributes are changed.
> > >
> >
> > IIUC, updating mtime for a write is also an attribute change, and that
> > affects ctime. According to the stat(2) manpage:
> >
> >       The field st_ctime is changed by writing or by setting
>  inode  informa-
> >       tion (i.e., owner, group, link count, mode, etc.).
> >
> > > Note that Ext4 appears to have a file creation time field in its
inode
> > > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use
that?
> > >
> >
> > Is it exposed to userspace in any (standard) way? It would be handy to
> > have that. While we're wishing...it might also be nice to have a
> > standard way to get at the i_generation from userspace too.
> >
>
> Yes - I have talked with MingMing and Aneesh about those (NFS may
> someday be able to use those too).  An obstacle in the past had been
> that samba server stores its own fake creation time in an ndr encoded
> xattr which complicates things.
>
> MingMing/Annesh -
> Xattr or other way to get at birth time?
>
>

Not yet,
 The ext4 file creation time only accesable from the kernel at the moment.
There were discussion
to make this information avaliable via xattr before, but was rejected,
since most people
agree that making this info avalibele via stat() is more standard. However
modifying stat() would imply
big interface change. thus no action has been taken yet.

> --
> Thanks,
>
> Steve

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-26  0:52               ` Mingming Cao
@ 2010-06-27 18:17                 ` Aneesh Kumar K. V
       [not found]                   ` <871vbscpce.fsf-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
  0 siblings, 1 reply; 716+ messages in thread
From: Aneesh Kumar K. V @ 2010-06-27 18:17 UTC (permalink / raw)
  To: Mingming Cao, Steve French, DENIEL Philippe
  Cc: David Howells, Jeff Layton, Jeff Layton, linux-cifs,
	linux-fsdevel, linux-kernel, samba-technical, Suresh Jayaraman

On Fri, 25 Jun 2010 17:52:24 -0700, Mingming Cao <mcao@us.ibm.com> wrote:
> 
> 
> Steve French <smfrench@gmail.com> wrote on 06/25/2010 04:05:30 PM:
> 
> > Steve French <smfrench@gmail.com>
> > 06/25/2010 04:05 PM
> >
> > To
> >
> > Jeff Layton <jlayton@samba.org>, "Aneesh Kumar K.V"
> > <aneesh.kumar@linux.vnet.ibm.com>, Mingming Cao/Beaverton/IBM@IBMUS
> >
> > cc
> >
> > David Howells <dhowells@redhat.com>, Suresh Jayaraman
> > <sjayaraman@suse.de>, linux-cifs@vger.kernel.org, linux-
> > fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, samba-
> > technical@lists.samba.org, Jeff Layton <jlayton@redhat.com>
> >
> > Subject
> >
> > Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and
> > register them
> >
> > On Fri, Jun 25, 2010 at 5:26 PM, Jeff Layton <jlayton@samba.org> wrote:
> > >
> > > On Fri, 25 Jun 2010 22:46:38 +0100
> > > David Howells <dhowells@redhat.com> wrote:
> > >
> > > > Jeff Layton <jlayton@samba.org> wrote:
> > > >
> > > > > Looks like it mostly uses the ctime. IMO, the mtime would be a
> better
> > > > > choice since it changes less frequently, but I don't guess that it
> > > > > matters very much.
> > > >
> > > > I'd've thought mtime changes more frequently since that's
> > altered when data is
> > > > written.  ctime is changed when attributes are changed.
> > > >
> > >
> > > IIUC, updating mtime for a write is also an attribute change, and that
> > > affects ctime. According to the stat(2) manpage:
> > >
> > >       The field st_ctime is changed by writing or by setting
> >  inode  informa-
> > >       tion (i.e., owner, group, link count, mode, etc.).
> > >
> > > > Note that Ext4 appears to have a file creation time field in its
> inode
> > > > (struct ext4_inode::i_crtime[_extra]).  Can Samba be made to use
> that?
> > > >
> > >
> > > Is it exposed to userspace in any (standard) way? It would be handy to
> > > have that. While we're wishing...it might also be nice to have a
> > > standard way to get at the i_generation from userspace too.
> > >
> >
> > Yes - I have talked with MingMing and Aneesh about those (NFS may
> > someday be able to use those too).  An obstacle in the past had been
> > that samba server stores its own fake creation time in an ndr encoded
> > xattr which complicates things.
> >
> > MingMing/Annesh -
> > Xattr or other way to get at birth time?
> >
> >
> 
> Not yet,
>  The ext4 file creation time only accesable from the kernel at the moment.
> There were discussion
> to make this information avaliable via xattr before, but was rejected,
> since most people
> agree that making this info avalibele via stat() is more standard. However
> modifying stat() would imply
> big interface change. thus no action has been taken yet.

NFS ganesha pNFS also had a requirement for getting i_generation and
inode number in userspace. So may be we should now look at updating
stat or add a variant syscall that include i_generation and create time
in the return value

-aneesh

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
  2010-06-27 18:17                 ` Aneesh Kumar K. V
@ 2010-06-27 18:22                       ` Christoph Hellwig
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Hellwig @ 2010-06-27 18:22 UTC (permalink / raw)
  To: Aneesh Kumar K. V
  Cc: Mingming Cao, Steve French, DENIEL Philippe, David Howells,
	Jeff Layton, Jeff Layton, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	samba-technical-w/Ol4Ecudpl8XjKLYN78aQ, Suresh Jayaraman

On Sun, Jun 27, 2010 at 11:47:21PM +0530, Aneesh Kumar K. V wrote:
> NFS ganesha pNFS also had a requirement for getting i_generation and
> inode number in userspace. So may be we should now look at updating
> stat or add a variant syscall that include i_generation and create time
> in the return value

What's missing in knfsd that you feel the sudden urge to move backwards
to a userspace nfsd (one with a horribly crappy codebase, too).

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 06/10] cifs: define inode-level cache object and register them
@ 2010-06-27 18:22                       ` Christoph Hellwig
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Hellwig @ 2010-06-27 18:22 UTC (permalink / raw)
  To: Aneesh Kumar K. V
  Cc: Mingming Cao, Steve French, DENIEL Philippe, David Howells,
	Jeff Layton, Jeff Layton, linux-cifs, linux-fsdevel,
	linux-kernel, samba-technical, Suresh Jayaraman

On Sun, Jun 27, 2010 at 11:47:21PM +0530, Aneesh Kumar K. V wrote:
> NFS ganesha pNFS also had a requirement for getting i_generation and
> inode number in userspace. So may be we should now look at updating
> stat or add a variant syscall that include i_generation and create time
> in the return value

What's missing in knfsd that you feel the sudden urge to move backwards
to a userspace nfsd (one with a horribly crappy codebase, too).


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
  2010-06-25 13:26         ` David Howells
@ 2010-06-28 12:53             ` Suresh Jayaraman
  -1 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-28 12:53 UTC (permalink / raw)
  To: David Howells
  Cc: Steve French, linux-cifs-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 06/25/2010 06:56 PM, David Howells wrote:
> David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> 
>>>> validate the root directory of the share in some way?
>>>
>>> I don't know if there is a way to do this.
>>
>> Is there an inode number or something?  Even the creation time might do.
> 
> Looking in cifspdu.h, there are a number of things that it might be possible
> to use.
> 
>  (1) FILE_ALL_INFO: CreationTime, IndexNumber, IndexNumber1, FileName
>      (assuming this isn't flattened to '\' or something for the root of a
>      share.
> 
>  (2) FILE_UNIX_BASIC_INFO: DevMajor, DevMinor, UniqueId.
> 
>  (3) FILE_INFO_STANDARD: CreationDate, CreationTime.
> 
>  (4) FILE_INFO_BASIC: CreationTime.
> 
>  (5) FILE_DIRECTORY_INFO: FileIndex, CreationTime, FileName.
> 
>  (6) SEARCH_ID_FULL_DIR_INFO: FileIndex, CreationTime, UniqueId, FileName.
> 
>  (7) FILE_BOTH_DIRECTORY_INFO: FileIndex, CreationTime, ShortName, FileName.
> 
>  (8) OPEN_RSP_EXT: Fid, CreationTime, VolumeGUID, FileId.
> 
> You may have to choose different sets of things, depending on what the server
> has on offer.  Also, don't forget, if you can't work out whether a share is

Did you mean we need to validate differently for different servers?

I just did some testing and it looks like we could rely on CreationTime,
IndexNumber for validating with Windows servers (FileName is relative to
the mapped drive) and UniqueId for validating with Samba servers. I did
not test all possibilities (there could be more).

> coherent or not from the above, you can always use LastWriteTime, ChangeTime
> and EndOfFile and just discard the whole subtree if they differ.
> 

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
@ 2010-06-28 12:53             ` Suresh Jayaraman
  0 siblings, 0 replies; 716+ messages in thread
From: Suresh Jayaraman @ 2010-06-28 12:53 UTC (permalink / raw)
  To: David Howells; +Cc: Steve French, linux-cifs, linux-fsdevel, linux-kernel

On 06/25/2010 06:56 PM, David Howells wrote:
> David Howells <dhowells@redhat.com> wrote:
> 
>>>> validate the root directory of the share in some way?
>>>
>>> I don't know if there is a way to do this.
>>
>> Is there an inode number or something?  Even the creation time might do.
> 
> Looking in cifspdu.h, there are a number of things that it might be possible
> to use.
> 
>  (1) FILE_ALL_INFO: CreationTime, IndexNumber, IndexNumber1, FileName
>      (assuming this isn't flattened to '\' or something for the root of a
>      share.
> 
>  (2) FILE_UNIX_BASIC_INFO: DevMajor, DevMinor, UniqueId.
> 
>  (3) FILE_INFO_STANDARD: CreationDate, CreationTime.
> 
>  (4) FILE_INFO_BASIC: CreationTime.
> 
>  (5) FILE_DIRECTORY_INFO: FileIndex, CreationTime, FileName.
> 
>  (6) SEARCH_ID_FULL_DIR_INFO: FileIndex, CreationTime, UniqueId, FileName.
> 
>  (7) FILE_BOTH_DIRECTORY_INFO: FileIndex, CreationTime, ShortName, FileName.
> 
>  (8) OPEN_RSP_EXT: Fid, CreationTime, VolumeGUID, FileId.
> 
> You may have to choose different sets of things, depending on what the server
> has on offer.  Also, don't forget, if you can't work out whether a share is

Did you mean we need to validate differently for different servers?

I just did some testing and it looks like we could rely on CreationTime,
IndexNumber for validating with Windows servers (FileName is relative to
the mapped drive) and UniqueId for validating with Samba servers. I did
not test all possibilities (there could be more).

> coherent or not from the above, you can always use LastWriteTime, ChangeTime
> and EndOfFile and just discard the whole subtree if they differ.
> 

Thanks,

-- 
Suresh Jayaraman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them
  2010-06-25 13:26         ` David Howells
  (?)
  (?)
@ 2010-06-28 13:24         ` David Howells
  -1 siblings, 0 replies; 716+ messages in thread
From: David Howells @ 2010-06-28 13:24 UTC (permalink / raw)
  To: Suresh Jayaraman
  Cc: dhowells, Steve French, linux-cifs, linux-fsdevel, linux-kernel

Suresh Jayaraman <sjayaraman@suse.de> wrote:

> Did you mean we need to validate differently for different servers?

You may need to, yes, as different servers may make different attributes
available.

This isn't too bad.  Each server index record in the cache has freeform
auxiliary data, just as does each file data record.  You could, say, stick a
byte at the front that indicates what you've stored in there.

David

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1
       [not found] <yes>
                   ` (25 preceding siblings ...)
  2010-06-23 17:08 ` [RFC][PATCH 10/10] cifs: add mount option to enable local caching David Howells
@ 2010-08-11  5:21 ` Tanmay Upadhyay
  2010-08-11  7:27   ` Russell King - ARM Linux
  2011-02-03  9:49 ` [PATCH 1/7] usb: otg: enable regulator only on cable/device connect Hema HK
                   ` (64 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Tanmay Upadhyay @ 2010-08-11  5:21 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables user to use serial port 1 of the OpenRD device for SDIO
or UART(RS232/RS485). The selection can be done through kernel parameter.

By default the port would be used for SDIO. To select RS232 or RS485 mode,
pass string "uart=232" or "uart=485" respectively in the kernel parameters.
"uart=485" is ignored on OpenRD-Base as it doesn't have RS485 port.

Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 arch/arm/mach-kirkwood/openrd-setup.c |  101 ++++++++++++++++++++++++++++++++-
 1 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index fd06be6..46378c0 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -19,6 +19,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
+#include <mach/gpio.h>
 #include <plat/mvsdio.h>
 #include "common.h"
 #include "mpp.h"
@@ -57,7 +58,15 @@ static struct mvsdio_platform_data openrd_mvsdio_data = {
 };
 
 static unsigned int openrd_mpp_config[] __initdata = {
+	MPP12_SD_CLK,
+	MPP13_SD_CMD,
+	MPP14_SD_D0,
+	MPP15_SD_D1,
+	MPP16_SD_D2,
+	MPP17_SD_D3,
+	MPP28_GPIO,
 	MPP29_GPIO,
+	MPP34_GPIO,
 	0
 };
 
@@ -67,6 +76,75 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
 	},
 };
 
+static int __initdata uart1;
+
+static int __init sd_uart_selection(char *str)
+{
+	uart1 = -EINVAL;
+
+	/* Default is SD. Change if required, for UART */
+	if (!str)
+		return 0;
+
+	if (!strncmp(str, "232", 3)) {
+		uart1 = 232;
+	} else if (!strncmp(str, "485", 3)) {
+		/* OpenRD-Base doesn't have RS485. Treat is as an
+		 * unknown argument & just have default setting -
+		 * which is SD */
+		if (machine_is_openrd_base()) {
+			uart1 = -ENODEV;
+			return 1;
+		}
+
+		uart1 = 485;
+	}
+	return 1;
+}
+/* Parse boot_command_line string uart=232/485 */
+__setup("uart=", sd_uart_selection);
+
+static int __init uart1_mpp_config(void)
+{
+	/* Configure MPP for UART1 */
+	unsigned int uart1_mpp_config[] = {
+		MPP13_UART1_TXD,
+		MPP14_UART1_RXD,
+		0
+	};
+
+	kirkwood_mpp_conf(uart1_mpp_config);
+
+	if (gpio_request(34, "SD_UART1_SEL")) {
+		printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
+				", gpio: 34\n");
+		return -EIO;
+	}
+
+	if (gpio_request(28, "RS232_RS485_SEL")) {
+		printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
+				", gpio# 28\n");
+		gpio_free(34);
+		return -EIO;
+	}
+
+	/* Select UART1
+	 * Pin # 34: 0 => UART1, 1 => SD */
+	gpio_direction_output(34, 0);
+
+	/* Select RS232 OR RS485
+	 * Pin # 28: 0 => RS232, 1 => RS485 */
+	if (uart1 == 232)
+		gpio_direction_output(28, 0);
+	else
+		gpio_direction_output(28, 1);
+
+	gpio_free(34);
+	gpio_free(28);
+
+	return 0;
+}
+
 static void __init openrd_init(void)
 {
 	/*
@@ -90,7 +168,6 @@ static void __init openrd_init(void)
 		kirkwood_ge01_init(&openrd_ge01_data);
 
 	kirkwood_sata_init(&openrd_sata_data);
-	kirkwood_sdio_init(&openrd_mvsdio_data);
 
 	kirkwood_i2c_init();
 
@@ -99,6 +176,28 @@ static void __init openrd_init(void)
 			ARRAY_SIZE(i2c_board_info));
 		kirkwood_audio_init();
 	}
+
+	if (uart1 <= 0) {
+		if (uart1 < 0)
+			printk(KERN_ERR "Invalid kernel parameter to select "
+				"UART1. Defaulting to SD. ERROR CODE: %d\n",
+				uart1);
+
+		/* Select SD
+		 * Pin # 34: 0 => UART1, 1 => SD */
+		if (gpio_request(34, "SD_UART1_SEL")) {
+			printk(KERN_ERR "GPIO request failed for SD/UART1 "
+					"selection, gpio: 34\n");
+		} else {
+
+			gpio_direction_output(34, 1);
+			gpio_free(34);
+			kirkwood_sdio_init(&openrd_mvsdio_data);
+		}
+	} else {
+		if (!uart1_mpp_config())
+			kirkwood_uart1_init();
+	}
 }
 
 static int __init openrd_pci_init(void)
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1
  2010-08-11  5:21 ` [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1 Tanmay Upadhyay
@ 2010-08-11  7:27   ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2010-08-11  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 11, 2010 at 10:51:02AM +0530, Tanmay Upadhyay wrote:
> diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
> index fd06be6..46378c0 100644
> --- a/arch/arm/mach-kirkwood/openrd-setup.c
> +++ b/arch/arm/mach-kirkwood/openrd-setup.c
> @@ -19,6 +19,7 @@
>  #include <asm/mach-types.h>
>  #include <asm/mach/arch.h>
>  #include <mach/kirkwood.h>
> +#include <mach/gpio.h>

linux/gpio.h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/7] usb: otg: enable regulator only on cable/device connect
       [not found] <yes>
                   ` (26 preceding siblings ...)
  2010-08-11  5:21 ` [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1 Tanmay Upadhyay
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03  9:49 ` [PATCH 2/7] usb: otg: Remove one unnecessary I2C read request Hema HK
                   ` (63 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb; +Cc: linux-omap, Hema HK, Felipe Balbi

Remove the regulator enable while driver loading and enable it only when
the cable/device is connected and disable it when disconnected.

Remove the configuration of config_state and config_trans register
configuration as these registers are programmed when regulator 
enable/disable is called.

Signed-off-by: Hema HK <hemahk@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/otg/twl6030-usb.c |   27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================
--- linux-2.6.orig/drivers/usb/otg/twl6030-usb.c
+++ linux-2.6/drivers/usb/otg/twl6030-usb.c
@@ -158,8 +158,6 @@ static int twl6030_phy_init(struct otg_t
 	dev  = twl->dev;
 	pdata = dev->platform_data;
 
-	regulator_enable(twl->usb3v3);
-
 	hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);
 
 	if (hw_state & STS_USB_ID)
@@ -180,7 +178,6 @@ static void twl6030_phy_shutdown(struct 
 	dev  = twl->dev;
 	pdata = dev->platform_data;
 	pdata->phy_power(twl->dev, 0, 0);
-	regulator_disable(twl->usb3v3);
 }
 
 static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
@@ -199,16 +196,6 @@ static int twl6030_usb_ldo_init(struct t
 	if (IS_ERR(twl->usb3v3))
 		return -ENODEV;
 
-	regulator_enable(twl->usb3v3);
-
-	/* Program the VUSB_CFG_TRANS for ACTIVE state. */
-	twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0x3F,
-						VUSB_CFG_TRANS);
-
-	/* Program the VUSB_CFG_STATE register to ON on all groups. */
-	twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0xE1,
-						VUSB_CFG_STATE);
-
 	/* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */
 	twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET);
 
@@ -261,16 +248,23 @@ static irqreturn_t twl6030_usb_irq(int i
 						CONTROLLER_STAT1);
 	if (!(hw_state & STS_USB_ID)) {
 		if (vbus_state & VBUS_DET) {
+			regulator_enable(twl->usb3v3);
+			twl->asleep = 1;
 			status = USB_EVENT_VBUS;
 			twl->otg.default_a = false;
 			twl->otg.state = OTG_STATE_B_IDLE;
+			twl->linkstat = status;
+			blocking_notifier_call_chain(&twl->otg.notifier,
+						status, twl->otg.gadget);
 		} else {
 			status = USB_EVENT_NONE;
-		}
-		if (status >= 0) {
 			twl->linkstat = status;
 			blocking_notifier_call_chain(&twl->otg.notifier,
 						status, twl->otg.gadget);
+			if (twl->asleep) {
+				regulator_disable(twl->usb3v3);
+				twl->asleep = 0;
+			}
 		}
 	}
 	sysfs_notify(&twl->dev->kobj, NULL, "vbus");
@@ -288,6 +282,8 @@ static irqreturn_t twl6030_usbotg_irq(in
 
 	if (hw_state & STS_USB_ID) {
 
+		regulator_enable(twl->usb3v3);
+		twl->asleep = 1;
 		twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1);
 		twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET,
 								0x10);
@@ -437,6 +433,7 @@ static int __devinit twl6030_usb_probe(s
 		return status;
 	}
 
+	twl->asleep = 0;
 	pdata->phy_init(dev);
 	twl6030_enable_irq(&twl->otg);
 	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 2/7] usb: otg: Remove one unnecessary I2C read request.
       [not found] <yes>
                   ` (27 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 1/7] usb: otg: enable regulator only on cable/device connect Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03  9:49 ` [PATCH 3/7] usb: otg: OMAP4430: Introducing suspend function for power management Hema HK
                   ` (62 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA, Hema HK, Felipe Balbi

To get the ID status there was an I2C read transfer. Removed this I2C
read transfer as this info can be used from existing variable(linkstat).

Signed-off-by: Hema HK <hemahk-l0cyMroinI0@public.gmane.org>
Cc: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
---
 drivers/usb/otg/twl6030-usb.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================
--- linux-2.6.orig/drivers/usb/otg/twl6030-usb.c
+++ linux-2.6/drivers/usb/otg/twl6030-usb.c
@@ -149,7 +149,6 @@ static int twl6030_set_phy_clk(struct ot
 
 static int twl6030_phy_init(struct otg_transceiver *x)
 {
-	u8 hw_state;
 	struct twl6030_usb *twl;
 	struct device *dev;
 	struct twl4030_usb_data *pdata;
@@ -158,9 +157,7 @@ static int twl6030_phy_init(struct otg_t
 	dev  = twl->dev;
 	pdata = dev->platform_data;
 
-	hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS);

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 3/7] usb: otg: OMAP4430: Introducing suspend function for power management
       [not found] <yes>
                   ` (28 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 2/7] usb: otg: Remove one unnecessary I2C read request Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
                   ` (61 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb; +Cc: linux-omap, Hema HK, Felipe Balbi, Tony Lindgren

Introduced the suspend/resume function for the OMAP4430 internal PHY.
This will be used by the twl6030-usb transceiver driver.
Moved the clock enable/disable function calls and power on/off of the PHY
code from power on/off functions to suspend/resume function.

Signed-off-by: Hema HK <hemahk@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/omap_phy_internal.c |   22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

Index: linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
===================================================================
--- linux-2.6.orig/arch/arm/mach-omap2/omap_phy_internal.c
+++ linux-2.6/arch/arm/mach-omap2/omap_phy_internal.c
@@ -103,13 +103,6 @@ int omap4430_phy_set_clk(struct device *
 int omap4430_phy_power(struct device *dev, int ID, int on)
 {
 	if (on) {
-		/* enabled the clocks */
-		omap4430_phy_set_clk(dev, 1);
-		/* power on the phy */
-		if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
-			__raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
-			mdelay(200);
-		}
 		if (ID)
 			/* enable VBUS valid, IDDIG groung */
 			__raw_writel(AVALID | VBUSVALID, ctrl_base +
@@ -125,10 +118,25 @@ int omap4430_phy_power(struct device *de
 		/* Enable session END and IDIG to high impedence. */
 		__raw_writel(SESSEND | IDDIG, ctrl_base +
 					USBOTGHS_CONTROL);
+	}
+	return 0;
+}
+
+int omap4430_phy_suspend(struct device *dev, int suspend)
+{
+	if (suspend) {
 		/* Disable the clocks */
 		omap4430_phy_set_clk(dev, 0);
 		/* Power down the phy */
 		__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+	} else {
+		/* Enable the internel phy clcoks */
+		omap4430_phy_set_clk(dev, 1);
+		/* power on the phy */
+		if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+			__raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+			mdelay(200);
+		}
 	}
 
 	return 0;

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data
       [not found] <yes>
                   ` (29 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 3/7] usb: otg: OMAP4430: Introducing suspend function for power management Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03 13:45   ` Sergei Shtylyov
  2011-02-03 13:50   ` Sergei Shtylyov
  2011-02-03  9:49 ` [PATCH 5/7] usb: otg: TWL6030: Introduce the twl6030_phy_suspend function Hema HK
                   ` (60 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA, Hema HK, Felipe Balbi, Tony Lindgren

Introduce the .phy_suspend function pointer to twl4030_usb_data structure.
assign the function to it for both sdp board and panda boards.
This will be used by the twl6030-usb transceiver driver.

Signed-off-by: Hema HK <hemahk-l0cyMroinI0@public.gmane.org>
Cc: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/mach-omap2/board-4430sdp.c    |    1 +
 arch/arm/mach-omap2/board-omap4panda.c |    1 +
 arch/arm/plat-omap/include/plat/usb.h  |    1 +
 include/linux/i2c/twl.h                |    2 ++
 4 files changed, 5 insertions(+)

Index: linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
===================================================================
--- linux-2.6.orig/arch/arm/mach-omap2/board-4430sdp.c
+++ linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
@@ -272,6 +272,7 @@ static struct twl4030_usb_data omap4_usb
 	.phy_exit	= omap4430_phy_exit,
 	.phy_power	= omap4430_phy_power,
 	.phy_set_clock	= omap4430_phy_set_clk,
+	.phy_suspend	= omap4430_phy_suspend,
 };
 
 static struct omap2_hsmmc_info mmc[] = {
Index: linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
===================================================================
--- linux-2.6.orig/arch/arm/mach-omap2/board-omap4panda.c
+++ linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
@@ -153,6 +153,7 @@ static struct twl4030_usb_data omap4_usb
 	.phy_exit	= omap4430_phy_exit,
 	.phy_power	= omap4430_phy_power,
 	.phy_set_clock	= omap4430_phy_set_clk,
+	.phy_suspend	= omap4430_phy_suspend,
 };
 
 static struct omap2_hsmmc_info mmc[] = {
Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
===================================================================
--- linux-2.6.orig/arch/arm/plat-omap/include/plat/usb.h
+++ linux-2.6/arch/arm/plat-omap/include/plat/usb.h
@@ -88,6 +88,7 @@ extern int omap4430_phy_power(struct dev
 extern int omap4430_phy_set_clk(struct device *dev, int on);
 extern int omap4430_phy_init(struct device *dev);
 extern int omap4430_phy_exit(struct device *dev);
+extern int omap4430_phy_suspend(struct device *dev, int suspend);
 
 #endif
 
Index: linux-2.6/include/linux/i2c/twl.h
===================================================================
--- linux-2.6.orig/include/linux/i2c/twl.h
+++ linux-2.6/include/linux/i2c/twl.h
@@ -600,6 +600,8 @@ struct twl4030_usb_data {
 	int		(*phy_power)(struct device *dev, int iD, int on);
 	/* enable/disable  phy clocks */
 	int		(*phy_set_clock)(struct device *dev, int on);
+	/* suspend/resume of phy */
+	int		(*phy_suspend)(struct device *dev, int suspend);
 };
 
 struct twl4030_ins {
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 5/7] usb: otg: TWL6030: Introduce the twl6030_phy_suspend function.
       [not found] <yes>
                   ` (30 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03  9:49 ` [PATCH 6/7] usb: otg: TWL6030 Save the last event in otg_transceiver Hema HK
                   ` (59 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA, Hema HK, Felipe Balbi

Introduce the twl6030_phy_suspend function and assign to otg.set_suspend
function pointer.
This function is used by the musb-omap2430 platform driver
during suspend/resume.

Signed-off-by: Hema HK <hemahk-l0cyMroinI0@public.gmane.org>
Cc: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
---
 drivers/usb/otg/twl6030-usb.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================
--- linux-2.6.orig/drivers/usb/otg/twl6030-usb.c
+++ linux-2.6/drivers/usb/otg/twl6030-usb.c
@@ -177,6 +177,20 @@ static void twl6030_phy_shutdown(struct 
 	pdata->phy_power(twl->dev, 0, 0);
 }
 
+static int twl6030_phy_suspend(struct otg_transceiver *x, int suspend)
+{
+	struct twl6030_usb *twl;
+	struct device *dev;
+	struct twl4030_usb_data *pdata;
+
+	twl = xceiv_to_twl(x);
+	dev  = twl->dev;
+	pdata = dev->platform_data;
+	pdata->phy_suspend(twl->dev, suspend);
+
+	return 0;
+}
+
 static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
 {
 
@@ -388,6 +402,7 @@ static int __devinit twl6030_usb_probe(s
 	twl->otg.set_vbus	= twl6030_set_vbus;
 	twl->otg.init		= twl6030_phy_init;
 	twl->otg.shutdown	= twl6030_phy_shutdown;
+	twl->otg.set_suspend	= twl6030_phy_suspend;
 
 	/* init spinlock for workqueue */
 	spin_lock_init(&twl->lock);
@@ -432,6 +447,7 @@ static int __devinit twl6030_usb_probe(s
 
 	twl->asleep = 0;
 	pdata->phy_init(dev);
+	twl6030_phy_suspend(&twl->otg, 0);
 	twl6030_enable_irq(&twl->otg);
 	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");
 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 6/7] usb: otg: TWL6030 Save the last event in otg_transceiver
       [not found] <yes>
                   ` (31 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 5/7] usb: otg: TWL6030: Introduce the twl6030_phy_suspend function Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-03  9:49 ` [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot Hema HK
                   ` (58 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA, Hema HK, Felipe Balbi

Save the last event in the otg_transceiver so that it can used in the
musb driver and gadget driver to configure the musb and enable the 
vbus for host mode and OTG mode, if the device is connected during boot.

Signed-off-by: Hema HK <hemahk-l0cyMroinI0@public.gmane.org>
Cc: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
---
[Reusing some part of the patch[1] posted by Arnaud Mandy]
[1] http://permalink.gmane.org/gmane.linux.usb.general/37123
---
 drivers/usb/otg/twl6030-usb.c |    3 +++
 include/linux/usb/otg.h       |    1 +
 2 files changed, 4 insertions(+)

Index: linux-2.6/drivers/usb/otg/twl6030-usb.c
===================================================================
--- linux-2.6.orig/drivers/usb/otg/twl6030-usb.c
+++ linux-2.6/drivers/usb/otg/twl6030-usb.c
@@ -265,11 +265,13 @@ static irqreturn_t twl6030_usb_irq(int i
 			twl->otg.default_a = false;
 			twl->otg.state = OTG_STATE_B_IDLE;
 			twl->linkstat = status;
+			twl->otg.last_event = status;
 			blocking_notifier_call_chain(&twl->otg.notifier,
 						status, twl->otg.gadget);
 		} else {
 			status = USB_EVENT_NONE;
 			twl->linkstat = status;
+			twl->otg.last_event = status;
 			blocking_notifier_call_chain(&twl->otg.notifier,
 						status, twl->otg.gadget);
 			if (twl->asleep) {
@@ -302,6 +304,7 @@ static irqreturn_t twl6030_usbotg_irq(in
 		twl->otg.default_a = true;
 		twl->otg.state = OTG_STATE_A_IDLE;
 		twl->linkstat = status;
+		twl->otg.last_event = status;
 		blocking_notifier_call_chain(&twl->otg.notifier, status,
 							twl->otg.gadget);
 	} else  {
Index: linux-2.6/include/linux/usb/otg.h
===================================================================
--- linux-2.6.orig/include/linux/usb/otg.h
+++ linux-2.6/include/linux/usb/otg.h
@@ -66,6 +66,7 @@ struct otg_transceiver {
 
 	u8			default_a;
 	enum usb_otg_state	state;
+	enum usb_xceiv_events	last_event;
 
 	struct usb_bus		*host;
 	struct usb_gadget	*gadget;
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot
       [not found] <yes>
                   ` (32 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 6/7] usb: otg: TWL6030 Save the last event in otg_transceiver Hema HK
@ 2011-02-03  9:49 ` Hema HK
  2011-02-14 10:05   ` Felipe Balbi
  2011-04-13 22:08 ` [PATCH 2/2] ltp-ddt: New recipe to build ltp-ddt test tool Carlos Hernandez
                   ` (57 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Hema HK @ 2011-02-03  9:49 UTC (permalink / raw)
  To: linux-usb; +Cc: linux-omap, Hema HK, Felipe Balbi

OMAP4430 is embedded with UTMI PHY. This PHY does not support the
OTG features like ID pin detection and VBUS detection. This function
is exported to an external companion chip TWL6030. Software must retrieve
the OTG HNP and SRP status from the TWL6030 and configure the bits inside
the control module that drive the related USBOTGHS UTMI interface signals.
It must also read back the UTMI signals needed to configure the TWL6030 
OTG module.

Can find more details in the TRM[1].
[1]:http://focus.ti.com/pdfs/wtbu/OMAP4430_ES2.0_Public_TRM_vJ.pdf

In OMAP4430 musb driver VBUS and ID notifications are received from the
transceiver driver. If the cable/device is connected during boot,
notifications from transceiver driver will be missed till musb driver
is loaded.
Patch to configure the transceiver in the platform_enable/disable
functions and enable the vbus in the gadget driver based on the 
last_event of the otg_transceiver.

Signed-off-by: Hema HK <hemahk@ti.com>
Cc: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/musb_gadget.c |    4 +++
 drivers/usb/musb/omap2430.c    |   49 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 48 insertions(+), 5 deletions(-)

Index: linux-2.6/drivers/usb/musb/musb_gadget.c
===================================================================
--- linux-2.6.orig/drivers/usb/musb/musb_gadget.c
+++ linux-2.6/drivers/usb/musb/musb_gadget.c
@@ -1855,6 +1855,10 @@ int usb_gadget_probe_driver(struct usb_g
 			} else {
 				hcd->self.uses_pio_for_control = 1;
 			}
+
+			if ((musb->xceiv->last_event == USB_EVENT_ID)
+						&& musb->xceiv->set_vbus)
+				otg_set_vbus(musb->xceiv, 1);
 		}
 	}
 
Index: linux-2.6/drivers/usb/musb/omap2430.c
===================================================================
--- linux-2.6.orig/drivers/usb/musb/omap2430.c
+++ linux-2.6/drivers/usb/musb/omap2430.c
@@ -350,16 +350,55 @@ static int omap2430_musb_init(struct mus
 	if (status)
 		DBG(1, "notification register failed\n");
 
-	/* check whether cable is already connected */
-	if (musb->xceiv->state ==OTG_STATE_B_IDLE)
-		musb_otg_notifications(&musb->nb, 1,
-					musb->xceiv->gadget);
-
 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
 	return 0;
 }
 
+static void omap2430_musb_enable(struct musb *musb)
+{
+	u8		devctl;
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+	struct device *dev = musb->controller;
+	struct musb_hdrc_platform_data *pdata = dev->platform_data;
+	struct omap_musb_board_data *data = pdata->board_data;
+
+	switch (musb->xceiv->last_event) {
+
+	case USB_EVENT_ID:
+		otg_init(musb->xceiv);
+		if (data->interface_type == MUSB_INTERFACE_UTMI) {
+			devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+			/* start the session */
+			devctl |= MUSB_DEVCTL_SESSION;
+			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+			while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
+				cpu_relax();
+
+				if (time_after(jiffies, timeout)) {
+					dev_err(musb->controller,
+					"configured as A device timeout");
+					break;
+				}
+			}
+		}
+		break;
+
+	case USB_EVENT_VBUS:
+		otg_init(musb->xceiv);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void omap2430_musb_disable(struct musb *musb)
+{
+	if (musb->xceiv->last_event)
+		otg_shutdown(musb->xceiv);
+}
+
 static int omap2430_musb_exit(struct musb *musb)
 {
 
@@ -377,6 +416,9 @@ static const struct musb_platform_ops om
 	.try_idle	= omap2430_musb_try_idle,
 
 	.set_vbus	= omap2430_musb_set_vbus,
+
+	.enable		= omap2430_musb_enable,
+	.disable	= omap2430_musb_disable,
 };
 
 static u64 omap2430_dmamask = DMA_BIT_MASK(32);

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data
  2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
@ 2011-02-03 13:45   ` Sergei Shtylyov
       [not found]     ` <4D4AB187.50406-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
  2011-02-03 13:50   ` Sergei Shtylyov
  1 sibling, 1 reply; 716+ messages in thread
From: Sergei Shtylyov @ 2011-02-03 13:45 UTC (permalink / raw)
  To: Hema HK; +Cc: linux-usb, linux-omap, Felipe Balbi, Tony Lindgren

Hello.

On 03-02-2011 12:49, Hema HK wrote:

> Introduce the .phy_suspend function pointer to twl4030_usb_data structure.
> assign the function to it for both sdp board and panda boards.
> This will be used by the twl6030-usb transceiver driver.

> Signed-off-by: Hema HK<hemahk@ti.com>
> Cc: Felipe Balbi<balbi@ti.com>
> Cc: Tony Lindgren<tony@atomide.com>

> Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
> ===================================================================
> --- linux-2.6.orig/arch/arm/plat-omap/include/plat/usb.h
> +++ linux-2.6/arch/arm/plat-omap/include/plat/usb.h
> @@ -88,6 +88,7 @@ extern int omap4430_phy_power(struct dev
>   extern int omap4430_phy_set_clk(struct device *dev, int on);
>   extern int omap4430_phy_init(struct device *dev);
>   extern int omap4430_phy_exit(struct device *dev);
> +extern int omap4430_phy_suspend(struct device *dev, int suspend);

    And where it it defined? Why this doesn't happen in this patch?

WBR, Sergei

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data
  2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
  2011-02-03 13:45   ` Sergei Shtylyov
@ 2011-02-03 13:50   ` Sergei Shtylyov
       [not found]     ` <4D4AB2A5.7000002-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
  1 sibling, 1 reply; 716+ messages in thread
From: Sergei Shtylyov @ 2011-02-03 13:50 UTC (permalink / raw)
  To: Hema HK; +Cc: linux-usb, linux-omap, Felipe Balbi, Tony Lindgren

Hello.

On 03-02-2011 12:49, Hema HK wrote:

> Introduce the .phy_suspend function pointer to twl4030_usb_data structure.
> assign the function to it for both sdp board and panda boards.
> This will be used by the twl6030-usb transceiver driver.

> Signed-off-by: Hema HK<hemahk@ti.com>
> Cc: Felipe Balbi<balbi@ti.com>
> Cc: Tony Lindgren<tony@atomide.com>
[...]

> Index: linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
> ===================================================================
> --- linux-2.6.orig/arch/arm/mach-omap2/board-4430sdp.c
> +++ linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
> @@ -272,6 +272,7 @@ static struct twl4030_usb_data omap4_usb
>   	.phy_exit	= omap4430_phy_exit,
>   	.phy_power	= omap4430_phy_power,
>   	.phy_set_clock	= omap4430_phy_set_clk,
> +	.phy_suspend	= omap4430_phy_suspend,
>   };
>
>   static struct omap2_hsmmc_info mmc[] = {
> Index: linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
> ===================================================================
> --- linux-2.6.orig/arch/arm/mach-omap2/board-omap4panda.c
> +++ linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
> @@ -153,6 +153,7 @@ static struct twl4030_usb_data omap4_usb
>   	.phy_exit	= omap4430_phy_exit,
>   	.phy_power	= omap4430_phy_power,
>   	.phy_set_clock	= omap4430_phy_set_clk,
> +	.phy_suspend	= omap4430_phy_suspend,
>   };
>
>   static struct omap2_hsmmc_info mmc[] = {
> Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
> ===================================================================
> --- linux-2.6.orig/arch/arm/plat-omap/include/plat/usb.h
> +++ linux-2.6/arch/arm/plat-omap/include/plat/usb.h
> @@ -88,6 +88,7 @@ extern int omap4430_phy_power(struct dev
>   extern int omap4430_phy_set_clk(struct device *dev, int on);
>   extern int omap4430_phy_init(struct device *dev);
>   extern int omap4430_phy_exit(struct device *dev);
> +extern int omap4430_phy_suspend(struct device *dev, int suspend);
>
>   #endif
>
> Index: linux-2.6/include/linux/i2c/twl.h
> ===================================================================
> --- linux-2.6.orig/include/linux/i2c/twl.h
> +++ linux-2.6/include/linux/i2c/twl.h
> @@ -600,6 +600,8 @@ struct twl4030_usb_data {
>   	int		(*phy_power)(struct device *dev, int iD, int on);
>   	/* enable/disable  phy clocks */
>   	int		(*phy_set_clock)(struct device *dev, int on);
> +	/* suspend/resume of phy */
> +	int		(*phy_suspend)(struct device *dev, int suspend);
>   };

    I think this patch should contain only this change, and the initializers 
and 'extern' declaration should be merged to the previous patch.
    Also, where do you call this method? Ah, I see, in the next patch. I think 
it should be merged to this one then.

WBR, Sergei

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data
       [not found]     ` <4D4AB187.50406-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
@ 2011-02-04  5:23       ` Hema Kalliguddi
  0 siblings, 0 replies; 716+ messages in thread
From: Hema Kalliguddi @ 2011-02-04  5:23 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Tony Lindgren

 Hi,

>-----Original Message-----
>From: Sergei Shtylyov [mailto:sshtylyov-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org]
>Sent: Thursday, February 03, 2011 7:16 PM
>To: Hema HK
>Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
>Felipe Balbi; Tony Lindgren
>Subject: Re: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend
>function pointer to twl4030_usb_data
>
>Hello.
>
>On 03-02-2011 12:49, Hema HK wrote:
>
>> Introduce the .phy_suspend function pointer to
>twl4030_usb_data structure.
>> assign the function to it for both sdp board and panda boards.
>> This will be used by the twl6030-usb transceiver driver.
>
>> Signed-off-by: Hema HK<hemahk-l0cyMroinI0@public.gmane.org>
>> Cc: Felipe Balbi<balbi-l0cyMroinI0@public.gmane.org>
>> Cc: Tony Lindgren<tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>
>> Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
>> ===================================================================
>> --- linux-2.6.orig/arch/arm/plat-omap/include/plat/usb.h
>> +++ linux-2.6/arch/arm/plat-omap/include/plat/usb.h
>> @@ -88,6 +88,7 @@ extern int omap4430_phy_power(struct dev
>>   extern int omap4430_phy_set_clk(struct device *dev, int on);
>>   extern int omap4430_phy_init(struct device *dev);
>>   extern int omap4430_phy_exit(struct device *dev);
>> +extern int omap4430_phy_suspend(struct device *dev, int suspend);
>
>    And where it it defined? Why this doesn't happen in this patch?
>
This is defined in the previous patch. This could have been done in
previous patch
also, but it is just that extern is done only when using.

Regards,
Hema


>WBR, Sergei
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data
       [not found]     ` <4D4AB2A5.7000002-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
@ 2011-02-04  6:03       ` Hema Kalliguddi
  0 siblings, 0 replies; 716+ messages in thread
From: Hema Kalliguddi @ 2011-02-04  6:03 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Tony Lindgren

Hi,

>-----Original Message-----
>From: Sergei Shtylyov [mailto:sshtylyov-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org]
>Sent: Thursday, February 03, 2011 7:20 PM
>To: Hema HK
>Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
>Felipe Balbi; Tony Lindgren
>Subject: Re: [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend
>function pointer to twl4030_usb_data
>
>Hello.
>
>On 03-02-2011 12:49, Hema HK wrote:
>
>> Introduce the .phy_suspend function pointer to
>twl4030_usb_data structure.
>> assign the function to it for both sdp board and panda boards.
>> This will be used by the twl6030-usb transceiver driver.
>
>> Signed-off-by: Hema HK<hemahk-l0cyMroinI0@public.gmane.org>
>> Cc: Felipe Balbi<balbi-l0cyMroinI0@public.gmane.org>
>> Cc: Tony Lindgren<tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>[...]
>
>> Index: linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
>> ===================================================================
>> --- linux-2.6.orig/arch/arm/mach-omap2/board-4430sdp.c
>> +++ linux-2.6/arch/arm/mach-omap2/board-4430sdp.c
>> @@ -272,6 +272,7 @@ static struct twl4030_usb_data omap4_usb
>>   	.phy_exit	= omap4430_phy_exit,
>>   	.phy_power	= omap4430_phy_power,
>>   	.phy_set_clock	= omap4430_phy_set_clk,
>> +	.phy_suspend	= omap4430_phy_suspend,
>>   };
>>
>>   static struct omap2_hsmmc_info mmc[] = {
>> Index: linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
>> ===================================================================
>> --- linux-2.6.orig/arch/arm/mach-omap2/board-omap4panda.c
>> +++ linux-2.6/arch/arm/mach-omap2/board-omap4panda.c
>> @@ -153,6 +153,7 @@ static struct twl4030_usb_data omap4_usb
>>   	.phy_exit	= omap4430_phy_exit,
>>   	.phy_power	= omap4430_phy_power,
>>   	.phy_set_clock	= omap4430_phy_set_clk,
>> +	.phy_suspend	= omap4430_phy_suspend,
>>   };
>>
>>   static struct omap2_hsmmc_info mmc[] = {
>> Index: linux-2.6/arch/arm/plat-omap/include/plat/usb.h
>> ===================================================================
>> --- linux-2.6.orig/arch/arm/plat-omap/include/plat/usb.h
>> +++ linux-2.6/arch/arm/plat-omap/include/plat/usb.h
>> @@ -88,6 +88,7 @@ extern int omap4430_phy_power(struct dev
>>   extern int omap4430_phy_set_clk(struct device *dev, int on);
>>   extern int omap4430_phy_init(struct device *dev);
>>   extern int omap4430_phy_exit(struct device *dev);
>> +extern int omap4430_phy_suspend(struct device *dev, int suspend);
>>
>>   #endif
>>
>> Index: linux-2.6/include/linux/i2c/twl.h
>> ===================================================================
>> --- linux-2.6.orig/include/linux/i2c/twl.h
>> +++ linux-2.6/include/linux/i2c/twl.h
>> @@ -600,6 +600,8 @@ struct twl4030_usb_data {
>>   	int		(*phy_power)(struct device *dev, int
>iD, int on);
>>   	/* enable/disable  phy clocks */
>>   	int		(*phy_set_clock)(struct device *dev, int on);
>> +	/* suspend/resume of phy */
>> +	int		(*phy_suspend)(struct device *dev, int suspend);
>>   };
>
>    I think this patch should contain only this change, and
>the initializers
>and 'extern' declaration should be merged to the previous patch.
>    Also, where do you call this method? Ah, I see, in the
>next patch. I think
>it should be merged to this one then.

No. if I do that git bisect fails.
Initializer does not make any sense without function poointer declaration.
Only extern can be moved to previous patch but, I think it is OK to extern
it
while using.

Regards,
Hema
>
>WBR, Sergei
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot
  2011-02-03  9:49 ` [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot Hema HK
@ 2011-02-14 10:05   ` Felipe Balbi
  2011-02-15  8:23     ` Hema Kalliguddi
  0 siblings, 1 reply; 716+ messages in thread
From: Felipe Balbi @ 2011-02-14 10:05 UTC (permalink / raw)
  To: Hema HK; +Cc: linux-usb, linux-omap, Felipe Balbi

Hi,

On Thu, Feb 03, 2011 at 03:19:47PM +0530, Hema HK wrote:
> +static void omap2430_musb_enable(struct musb *musb)
> +{
> +	u8		devctl;
> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> +	struct device *dev = musb->controller;
> +	struct musb_hdrc_platform_data *pdata = dev->platform_data;
> +	struct omap_musb_board_data *data = pdata->board_data;
> +
> +	switch (musb->xceiv->last_event) {
> +
> +	case USB_EVENT_ID:
> +		otg_init(musb->xceiv);
> +		if (data->interface_type == MUSB_INTERFACE_UTMI) {
> +			devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
> +			/* start the session */
> +			devctl |= MUSB_DEVCTL_SESSION;
> +			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
> +			while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {

isn't this BDEVICE bit ? We have a define for that, please use it.

-- 
balbi

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot
  2011-02-14 10:05   ` Felipe Balbi
@ 2011-02-15  8:23     ` Hema Kalliguddi
  0 siblings, 0 replies; 716+ messages in thread
From: Hema Kalliguddi @ 2011-02-15  8:23 UTC (permalink / raw)
  To: balbi; +Cc: linux-usb, linux-omap

>-----Original Message-----
>From: Felipe Balbi [mailto:balbi@ti.com]
>Sent: Monday, February 14, 2011 3:36 PM
>To: Hema HK
>Cc: linux-usb@vger.kernel.org; linux-omap@vger.kernel.org; Felipe Balbi
>Subject: Re: [PATCH 7/7] usb: musb: OMAP4430: Fix usb device
>detection if connected during boot
>
>Hi,
>
>On Thu, Feb 03, 2011 at 03:19:47PM +0530, Hema HK wrote:
>> +static void omap2430_musb_enable(struct musb *musb)
>> +{
>> +	u8		devctl;
>> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
>> +	struct device *dev = musb->controller;
>> +	struct musb_hdrc_platform_data *pdata = dev->platform_data;
>> +	struct omap_musb_board_data *data = pdata->board_data;
>> +
>> +	switch (musb->xceiv->last_event) {
>> +
>> +	case USB_EVENT_ID:
>> +		otg_init(musb->xceiv);
>> +		if (data->interface_type == MUSB_INTERFACE_UTMI) {
>> +			devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
>> +			/* start the session */
>> +			devctl |= MUSB_DEVCTL_SESSION;
>> +			musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
>> +			while (musb_readb(musb->mregs,
>MUSB_DEVCTL) & 0x80) {
>
>isn't this BDEVICE bit ? We have a define for that, please use it.
>
OK.

Regards,
Hema
>--
>balbi
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 2/2] ltp-ddt: New recipe to build ltp-ddt test tool.
       [not found] <yes>
                   ` (33 preceding siblings ...)
  2011-02-03  9:49 ` [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot Hema HK
@ 2011-04-13 22:08 ` Carlos Hernandez
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2 Simon Guinot
                   ` (56 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Carlos Hernandez @ 2011-04-13 22:08 UTC (permalink / raw)
  To: openembedded-devel; +Cc: Carlos Hernandez

ltp-ddt is an open source test application for embedded linux devices.
It is based on the linux test project (ltp) but it has a smaller footprint
and it focus mainly on driver and system performance.
Design Highlights:
 * Based on LTP http://ltp.sourceforge.net/
 * Test cases are suitable for embedded devices w/ a limited shell.
 * Support dynamic selection/filtering of test cases based on platform.
 * Support test parameters overrides based on platform.

Signed-off-by: Carlos Hernandez <c-hernandez8@ti.com>
---
 recipes/ltp-ddt/ltp-ddt_0.0.1.bb |   54 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 recipes/ltp-ddt/ltp-ddt_0.0.1.bb

diff --git a/recipes/ltp-ddt/ltp-ddt_0.0.1.bb b/recipes/ltp-ddt/ltp-ddt_0.0.1.bb
new file mode 100644
index 0000000..157ee07
--- /dev/null
+++ b/recipes/ltp-ddt/ltp-ddt_0.0.1.bb
@@ -0,0 +1,54 @@
+DESCRIPTION = "Embedded Linux Device Driver Tests based on Linux Test Project"
+HOMEPAGE = "http://arago-project.org/git/projects/?p=test-automation/ltp-ddt.git;a=summary"
+LICENSE = "GPL"
+SECTION = "console/utils"
+DEPENDS += "zip-native virtual/kernel"
+PR = "r0"
+
+inherit autotools
+
+BRANCH ?= "master"
+TAG ?= "ltp-ddt_${PV}"
+
+SRC_URI = "\
+git://arago-project.org/git/projects/test-automation/ltp-ddt.git;protocol=git;\
+branch=${BRANCH};\
+tag=${TAG}\
+"
+S = "${WORKDIR}/git"
+
+EXTRA_OEMAKE_append = "prefix=/usr/ltp CROSS_COMPILE=${HOST_PREFIX} SKIP_IDCHECK=1 KERNEL_INC=${STAGING_KERNEL_DIR}/include"
+
+FILES_${PN}-dbg += "\
+ /usr/ltp/.debug \
+ /usr/ltp/bin/.debug \
+ /usr/ltp/runtest/.debug \
+ /usr/ltp/testcases/bin/.debug \
+ /usr/ltp/testcases/bin/*/bin/.debug \
+ /usr/ltp/testcases/bin/*/test/.debug \
+ /usr/ltp/testcases/bin/ddt/.debug \
+ /usr/ltp/testcases/bin/ddt/*/bin/.debug \
+ /usr/ltp/testcases/bin/ddt/*/test/.debug \
+"
+
+FILES_${PN} += "\
+ /usr/ltp/* \
+ /usr/ltp/bin/* \
+ /usr/ltp/runtest/* \
+ /usr/ltp/testcases/bin/* \
+ /usr/ltp/testcases/bin/*/bin/* \
+ /usr/ltp/testscripts/* \
+"
+
+do_configure(){
+        cp ${S}/include/config.h.default ${S}/include/config.h
+	cp ${S}/include/mk/config.mk.default ${S}/include/mk/config.mk
+	cp ${S}/include/mk/features.mk.default ${S}/include/mk/features.mk
+	echo "${TAG}" > ${S}/ChangeLog
+}
+
+do_install(){
+        oe_runmake DESTDIR=${D} install
+}
+
+
-- 
1.7.0.4




^ permalink raw reply related	[flat|nested] 716+ messages in thread

* ARM: pxa168: Add board support for gplugD
@ 2011-05-02  5:59 Tanmay Upadhyay
  2011-05-02  5:59 ` [PATCH 1/3] ARM: pxa168: Add support for UART3 Tanmay Upadhyay
                   ` (2 more replies)
  0 siblings, 3 replies; 716+ messages in thread
From: Tanmay Upadhyay @ 2011-05-02  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

GuruPlug Display (gplugD) is dropped from arch/arm/tools/mach-types as of now.
So, it will not build until it's back in 'mach-types'. For now, one can build
kernel for gplugD by adding below line in arch/arm/tools/mach-types

gplugd                 MACH_SHEEVAD            SHEEVAD                 2625

Patches tested on Linux 2.6.39-rc4 after adding above line in 'mach-types'.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/3] ARM: pxa168: Add support for UART3
  2011-05-02  5:59 ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
@ 2011-05-02  5:59 ` Tanmay Upadhyay
  2011-05-02  5:59 ` [PATCH 2/3] ARM: pxa168: Add support for Ethernet Tanmay Upadhyay
  2011-05-02  6:00 ` [PATCH 3/3] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
  2 siblings, 0 replies; 716+ messages in thread
From: Tanmay Upadhyay @ 2011-05-02  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

PXA168 has 3 onchip UARTs. Added support for the third one

Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 arch/arm/mach-mmp/include/mach/pxa168.h |    2 ++
 arch/arm/mach-mmp/pxa168.c              |    3 +++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index a52b3d2..705e963 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -17,6 +17,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_uart3;
 extern struct pxa_device_desc pxa168_device_twsi0;
 extern struct pxa_device_desc pxa168_device_twsi1;
 extern struct pxa_device_desc pxa168_device_pwm1;
@@ -39,6 +40,7 @@ static inline int pxa168_add_uart(int id)
 	switch (id) {
 	case 1: d = &pxa168_device_uart1; break;
 	case 2: d = &pxa168_device_uart2; break;
+	case 3: d = &pxa168_device_uart3; break;
 	}
 
 	if (d == NULL)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 72b4e76..dcb203b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -66,6 +66,7 @@ void __init pxa168_init_irq(void)
 /* APB peripheral clocks */
 static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
 static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
+static APBC_CLK(uart3, PXA168_UART3, 1, 14745600);
 static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
 static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
 static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000);
@@ -86,6 +87,7 @@ static APMU_CLK(lcd, LCD, 0x7f, 312000000);
 static struct clk_lookup pxa168_clkregs[] = {
 	INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
 	INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+	INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
 	INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
 	INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
 	INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
@@ -149,6 +151,7 @@ void pxa168_clear_keypad_wakeup(void)
 /* on-chip devices */
 PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
 PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
+PXA168_DEVICE(uart3, "pxa2xx-uart", 2, UART3, 0xd4026000, 0x30, 23, 24);
 PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
 PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
 PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/3] ARM: pxa168: Add support for Ethernet
  2011-05-02  5:59 ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
  2011-05-02  5:59 ` [PATCH 1/3] ARM: pxa168: Add support for UART3 Tanmay Upadhyay
@ 2011-05-02  5:59 ` Tanmay Upadhyay
  2011-06-10 13:31   ` Eric Miao
  2011-05-02  6:00 ` [PATCH 3/3] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
  2 siblings, 1 reply; 716+ messages in thread
From: Tanmay Upadhyay @ 2011-05-02  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

Add wrapper that creates resources for PXA168 Ethernet driver

Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 arch/arm/mach-mmp/include/mach/mfp-pxa168.h |   19 +++++++++++++++++++
 arch/arm/mach-mmp/include/mach/pxa168.h     |    6 ++++++
 arch/arm/mach-mmp/include/mach/regs-apmu.h  |    1 +
 arch/arm/mach-mmp/pxa168.c                  |    3 +++
 4 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index 713be15..8c78232 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -305,4 +305,23 @@
 #define GPIO112_KP_MKOUT6       MFP_CFG(GPIO112, AF7)
 #define GPIO121_KP_MKIN4        MFP_CFG(GPIO121, AF7)
 
+/* Fast Ethernet */
+#define GPIO86_TX_CLK		MFP_CFG(GPIO86, AF5)
+#define GPIO87_TX_EN		MFP_CFG(GPIO87, AF5)
+#define GPIO88_TX_DQ3		MFP_CFG(GPIO88, AF5)
+#define GPIO89_TX_DQ2		MFP_CFG(GPIO89, AF5)
+#define GPIO90_TX_DQ1		MFP_CFG(GPIO90, AF5)
+#define GPIO91_TX_DQ0		MFP_CFG(GPIO91, AF5)
+#define GPIO92_MII_CRS		MFP_CFG(GPIO92, AF5)
+#define GPIO93_MII_COL		MFP_CFG(GPIO93, AF5)
+#define GPIO94_RX_CLK		MFP_CFG(GPIO94, AF5)
+#define GPIO95_RX_ER		MFP_CFG(GPIO95, AF5)
+#define GPIO96_RX_DQ3		MFP_CFG(GPIO96, AF5)
+#define GPIO97_RX_DQ2		MFP_CFG(GPIO97, AF5)
+#define GPIO98_RX_DQ1		MFP_CFG(GPIO98, AF5)
+#define GPIO99_RX_DQ0		MFP_CFG(GPIO99, AF5)
+#define GPIO100_MII_MDC		MFP_CFG(GPIO100, AF5)
+#define GPIO101_MII_MDIO	MFP_CFG(GPIO101, AF5)
+#define GPIO103_RX_DV		MFP_CFG(GPIO103, AF5)
+
 #endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index 705e963..7f00584 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -14,6 +14,7 @@ extern void pxa168_clear_keypad_wakeup(void);
 #include <video/pxa168fb.h>
 #include <plat/pxa27x_keypad.h>
 #include <mach/cputype.h>
+#include <linux/pxa168_eth.h>
 
 extern struct pxa_device_desc pxa168_device_uart1;
 extern struct pxa_device_desc pxa168_device_uart2;
@@ -32,6 +33,7 @@ extern struct pxa_device_desc pxa168_device_ssp5;
 extern struct pxa_device_desc pxa168_device_nand;
 extern struct pxa_device_desc pxa168_device_fb;
 extern struct pxa_device_desc pxa168_device_keypad;
+extern struct pxa_device_desc pxa168_device_eth;
 
 static inline int pxa168_add_uart(int id)
 {
@@ -119,4 +121,8 @@ static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
 	return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
 }
 
+static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
+{
+	return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
+}
 #endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
index f7011ef..8447ac6 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -29,6 +29,7 @@
 #define APMU_BUS	APMU_REG(0x06c)
 #define APMU_SDH2	APMU_REG(0x0e8)
 #define APMU_SDH3	APMU_REG(0x0ec)
+#define APMU_ETH	APMU_REG(0x0fc)
 
 #define APMU_FNCLK_EN	(1 << 4)
 #define APMU_AXICLK_EN	(1 << 3)
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index dcb203b..96d451d 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -82,6 +82,7 @@ static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
 
 static APMU_CLK(nand, NAND, 0x01db, 208000000);
 static APMU_CLK(lcd, LCD, 0x7f, 312000000);
+static APMU_CLK(eth, ETH, 0x09, 0);
 
 /* device and clock bindings */
 static struct clk_lookup pxa168_clkregs[] = {
@@ -102,6 +103,7 @@ static struct clk_lookup pxa168_clkregs[] = {
 	INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
 	INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
 	INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
+	INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
 };
 
 static int __init pxa168_init(void)
@@ -166,3 +168,4 @@ PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
 PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
 PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
 PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
+PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/3] ARM: pxa168: Add board support for gplugD
  2011-05-02  5:59 ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
  2011-05-02  5:59 ` [PATCH 1/3] ARM: pxa168: Add support for UART3 Tanmay Upadhyay
  2011-05-02  5:59 ` [PATCH 2/3] ARM: pxa168: Add support for Ethernet Tanmay Upadhyay
@ 2011-05-02  6:00 ` Tanmay Upadhyay
  2011-06-20  5:55   ` Eric Miao
  2 siblings, 1 reply; 716+ messages in thread
From: Tanmay Upadhyay @ 2011-05-02  6:00 UTC (permalink / raw)
  To: linux-arm-kernel

Tested UART console, Ethernet & I2C interfaces

Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 arch/arm/mach-mmp/Kconfig                   |    7 +
 arch/arm/mach-mmp/Makefile                  |    1 +
 arch/arm/mach-mmp/gplugd.c                  |  189 +++++++++++++++++++++++++++
 arch/arm/mach-mmp/include/mach/mfp-gplugd.h |   52 ++++++++
 4 files changed, 249 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mmp/gplugd.c
 create mode 100644 arch/arm/mach-mmp/include/mach/mfp-gplugd.h

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 67793a6..56ef5f6 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -77,6 +77,13 @@ config MACH_TETON_BGA
 	  Say 'Y' here if you want to support the Marvell PXA168-based
 	  Teton BGA Development Board.
 
+config MACH_SHEEVAD
+	bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
+	select CPU_PXA168
+	help
+	  Say 'Y' here if you want to support the Marvell PXA168-based
+	  GuruPlug Display (gplugD) Board
+
 endmenu
 
 config CPU_PXA168
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 5c68382..b0ac942 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_BROWNSTONE)	+= brownstone.o
 obj-$(CONFIG_MACH_FLINT)	+= flint.o
 obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
 obj-$(CONFIG_MACH_TETON_BGA)	+= teton_bga.o
+obj-$(CONFIG_MACH_SHEEVAD)	+= gplugd.o
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
new file mode 100644
index 0000000..c070c24
--- /dev/null
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -0,0 +1,189 @@
+/*
+ *  linux/arch/arm/mach-mmp/gplugd.c
+ *
+ *  Support for the Marvell PXA168-based GuruPlug Display (gplugD) Platform.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <mach/pxa168.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/mfp-gplugd.h>
+
+#include "common.h"
+
+static unsigned long gplugd_pin_config[] __initdata = {
+	/* UART3 */
+	GPIO8_UART3_SOUT,
+	GPIO9_UART3_SIN,
+	GPI1O_UART3_CTS,
+	GPI11_UART3_RTS,
+
+	/* MMC2 */
+	GPIO28_MMC2_CMD,
+	GPIO29_MMC2_CLK,
+	GPIO30_MMC2_DAT0,
+	GPIO31_MMC2_DAT1,
+	GPIO32_MMC2_DAT2,
+	GPIO33_MMC2_DAT3,
+
+	/* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */
+	GPIO35_GPIO,
+	GPIO36_GPIO, /* CEC Interrupt */
+
+	/* MMC1 */
+	GPIO43_MMC1_CLK,
+	GPIO49_MMC1_CMD,
+	GPIO41_MMC1_DAT0,
+	GPIO40_MMC1_DAT1,
+	GPIO52_MMC1_DAT2,
+	GPIO51_MMC1_DAT3,
+	GPIO53_MMC1_CD,
+
+	/* LCD */
+	GPIO56_LCD_FCLK_RD,
+	GPIO57_LCD_LCLK_A0,
+	GPIO58_LCD_PCLK_WR,
+	GPIO59_LCD_DENA_BIAS,
+	GPIO60_LCD_DD0,
+	GPIO61_LCD_DD1,
+	GPIO62_LCD_DD2,
+	GPIO63_LCD_DD3,
+	GPIO64_LCD_DD4,
+	GPIO65_LCD_DD5,
+	GPIO66_LCD_DD6,
+	GPIO67_LCD_DD7,
+	GPIO68_LCD_DD8,
+	GPIO69_LCD_DD9,
+	GPIO70_LCD_DD10,
+	GPIO71_LCD_DD11,
+	GPIO72_LCD_DD12,
+	GPIO73_LCD_DD13,
+	GPIO74_LCD_DD14,
+	GPIO75_LCD_DD15,
+	GPIO76_LCD_DD16,
+	GPIO77_LCD_DD17,
+	GPIO78_LCD_DD18,
+	GPIO79_LCD_DD19,
+	GPIO80_LCD_DD20,
+	GPIO81_LCD_DD21,
+	GPIO82_LCD_DD22,
+	GPIO83_LCD_DD23,
+
+	/* GPIO */
+	GPIO84_GPIO,
+	GPIO85_GPIO,
+
+	/* Fast-Ethernet*/
+	GPIO86_TX_CLK,
+	GPIO87_TX_EN,
+	GPIO88_TX_DQ3,
+	GPIO89_TX_DQ2,
+	GPIO90_TX_DQ1,
+	GPIO91_TX_DQ0,
+	GPIO92_MII_CRS,
+	GPIO93_MII_COL,
+	GPIO94_RX_CLK,
+	GPIO95_RX_ER,
+	GPIO96_RX_DQ3,
+	GPIO97_RX_DQ2,
+	GPIO98_RX_DQ1,
+	GPIO99_RX_DQ0,
+	GPIO100_MII_MDC,
+	GPIO101_MII_MDIO,
+	GPIO103_RX_DV,
+	GPIO104_GPIO,     /* Reset PHY */
+
+	/* RTC interrupt */
+	GPIO102_GPIO,
+
+	/* I2C */
+	GPIO105_CI2C_SDA,
+	GPIO106_CI2C_SCL,
+
+	/* Select JTAG */
+	GPIO109_GPIO,
+
+	/* I2S */
+	GPIO114_I2S_FRM,
+	GPIO115_I2S_BCLK,
+	GPIO116_I2S_TXD
+};
+
+static struct i2c_board_info gplugd_i2c_board_info[] = {
+	{
+		.type = "isl1208",
+		.addr = 0x6F,
+	}
+};
+
+/* Bring PHY out of reset by setting GPIO 104 */
+static int gplugd_eth_init(void)
+{
+	if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
+				"PHY out of reset\n");
+		return -EIO;
+	}
+
+	gpio_direction_output(104, 1);
+	gpio_free(104);
+	return 0;
+}
+
+struct pxa168_eth_platform_data gplugd_eth_platform_data = {
+	.port_number = 0,
+	.phy_addr    = 0,
+	.speed       = 0, /* Autonagotiation */
+	.init        = gplugd_eth_init,
+};
+
+static void __init select_disp_freq(void)
+{
+	/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
+	if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 35 to select display "
+				"frequency\n");
+	} else {
+		gpio_direction_output(35, 1);
+		gpio_free(104);
+	}
+
+	if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 85 to select display "
+				"frequency\n");
+	} else {
+		gpio_direction_output(85, 0);
+		gpio_free(104);
+	}
+}
+
+static void __init gplugd_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
+
+	select_disp_freq();
+
+	/* on-chip devices */
+	pxa168_add_uart(3);
+	pxa168_add_ssp(0);
+	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+
+	pxa168_add_eth(&gplugd_eth_platform_data);
+}
+
+MACHINE_START(SHEEVAD, "PXA168-based GuruPlug Display (gplugD) Platform")
+	.map_io		= mmp_map_io,
+	.nr_irqs	= IRQ_BOARD_START,
+	.init_irq       = pxa168_init_irq,
+	.timer          = &pxa168_timer,
+	.init_machine   = gplugd_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/include/mach/mfp-gplugd.h b/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
new file mode 100644
index 0000000..b8cf38d
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
+ *
+ *   MFP definitions used in gplugD
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MFP_GPLUGD_H
+#define __MACH_MFP_GPLUGD_H
+
+#include <plat/mfp.h>
+#include <mach/mfp.h>
+
+/* UART3 */
+#define GPIO8_UART3_SOUT       MFP_CFG(GPIO8, AF2)
+#define GPIO9_UART3_SIN        MFP_CFG(GPIO9, AF2)
+#define GPI1O_UART3_CTS        MFP_CFG(GPIO10, AF2)
+#define GPI11_UART3_RTS        MFP_CFG(GPIO11, AF2)
+
+/* MMC2 */
+#define	GPIO28_MMC2_CMD		MFP_CFG_DRV(GPIO28, AF6, FAST)
+#define	GPIO29_MMC2_CLK		MFP_CFG_DRV(GPIO29, AF6, FAST)
+#define	GPIO30_MMC2_DAT0	MFP_CFG_DRV(GPIO30, AF6, FAST)
+#define	GPIO31_MMC2_DAT1	MFP_CFG_DRV(GPIO31, AF6, FAST)
+#define	GPIO32_MMC2_DAT2	MFP_CFG_DRV(GPIO32, AF6, FAST)
+#define	GPIO33_MMC2_DAT3	MFP_CFG_DRV(GPIO33, AF6, FAST)
+
+/* I2S */
+#undef GPIO114_I2S_FRM
+#undef GPIO115_I2S_BCLK
+
+#define GPIO114_I2S_FRM	        MFP_CFG_DRV(GPIO114, AF1, FAST)
+#define GPIO115_I2S_BCLK        MFP_CFG_DRV(GPIO115, AF1, FAST)
+#define GPIO116_I2S_TXD         MFP_CFG_DRV(GPIO116, AF1, FAST)
+
+/* MMC4 */
+#define GPIO125_MMC4_DAT3       MFP_CFG_DRV(GPIO125, AF7, FAST)
+#define GPIO126_MMC4_DAT2       MFP_CFG_DRV(GPIO126, AF7, FAST)
+#define GPIO127_MMC4_DAT1       MFP_CFG_DRV(GPIO127, AF7, FAST)
+#define GPIO0_2_MMC4_DAT0       MFP_CFG_DRV(GPIO0_2, AF7, FAST)
+#define GPIO1_2_MMC4_CMD        MFP_CFG_DRV(GPIO1_2, AF7, FAST)
+#define GPIO2_2_MMC4_CLK        MFP_CFG_DRV(GPIO2_2, AF7, FAST)
+
+/* OTG GPIO */
+#define GPIO_USB_OTG_PEN        18
+#define GPIO_USB_OIDIR          20
+
+/* Other GPIOs are 35, 84, 85 */
+#endif /* __MACH_MFP_GPLUGD_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2
       [not found] <yes>
                   ` (34 preceding siblings ...)
  2011-04-13 22:08 ` [PATCH 2/2] ltp-ddt: New recipe to build ltp-ddt test tool Carlos Hernandez
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 21:29   ` Wolfgang Denk
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash Simon Guinot
                   ` (55 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

This patch series adds support for Network Space v2 board and parents.

Changes since v1:
  - netconsole: restore NetOurIP check
  - add entries to MAINTAINERS file
  - move boards from root Makefile to boards.cfg
  - move MACH_TYPE definition into netspace_v2.h
  - remove CONFIG_SYS_HZ redefinition
  - turn PHY initialization message into debug()

Changes since v2:
  - drop patch for Macronix MX25L4005A
  - rewrite patch "sf: disable write protection for Macronix flash",
    using the common spi flash code
  - fix "Definitions" typo in mv-common.h
  - netconsole: add a "/* Fall through */" comment before the NETCONS
    case label

Changes since v3:
  - sf macronix: use spi_flash_cmd_write_enable()
  - enhance commit message for patch "Add support for Network Space v2"

Simon Guinot (5):
  sf: disable write protection for Macronix flash
  Kirkwood: allow to override CONFIG_SYS_TCLK
  mv-common.h: fix DRAM banks configuration
  netconsole: remove `serverip' check
  Add support for Network Space v2

 MAINTAINERS                                    |    6 +
 arch/arm/include/asm/arch-kirkwood/kw88f6281.h |    8 +-
 board/LaCie/netspace_v2/Makefile               |   49 +++++++
 board/LaCie/netspace_v2/kwbimage.cfg           |  162 ++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.c          |  144 +++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.h          |   39 ++++++
 boards.cfg                                     |    3 +
 drivers/mtd/spi/macronix.c                     |   42 ++++++
 include/configs/mv-common.h                    |    8 +-
 include/configs/netspace_v2.h                  |  149 ++++++++++++++++++++++
 net/net.c                                      |    3 +-
 11 files changed, 605 insertions(+), 8 deletions(-)
 create mode 100644 board/LaCie/netspace_v2/Makefile
 create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
 create mode 100644 include/configs/netspace_v2.h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash
       [not found] <yes>
                   ` (35 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2 Simon Guinot
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 21:07   ` Mike Frysinger
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
                   ` (54 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
 drivers/mtd/spi/macronix.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
 	},
 };
 
+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+	u8 cmd;
+	int ret;
+
+	ret = spi_flash_cmd_write_enable(flash);
+	if (ret < 0) {
+		debug("SF: enabling write failed\n");
+		return ret;
+	}
+
+	cmd = CMD_MX25XX_WRSR;
+	ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+	if (ret) {
+		debug("SF: fail to write status register\n");
+		return ret;
+	}
+
+	ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (ret < 0) {
+		debug("SF: write status register timed out\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+	int ret;
+
+	/* Enable status register writing and clear BP# bits */
+	ret = macronix_write_status(flash, 0);
+	if (ret)
+		debug("SF: fail to disable write protection\n");
+
+	return ret;
+}
+
 static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
 		* params->sectors_per_block;
 	flash->size = flash->sector_size * params->nr_blocks;
 
+	/* Clear BP# bits for read-only flash */
+	macronix_unlock(flash);
+
 	return flash;
 }
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK
       [not found] <yes>
                   ` (36 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash Simon Guinot
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
                   ` (53 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

This patch allow to override CONFIG_SYS_TCLK from board configuration
files. This is needed for the Network Space v2 which use a non standard
core clock frequency (166MHz instead of 200MHz for a 6281 SoC).

As a possible enhancement for 6281 and 6282 devices, TCLK could be
dynamically detected by checking the Sample at Reset register bit 21.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
Acked-by: Prafulla Wadaskar <Prafulla@marvell.com>
---
 arch/arm/include/asm/arch-kirkwood/kw88f6281.h |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
index 80723ea..22d10f1 100644
--- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
+++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
@@ -27,11 +27,13 @@
 #ifndef _ASM_ARCH_KW88F6281_H
 #define _ASM_ARCH_KW88F6281_H
 
-/* SOC specific definations */
+/* SOC specific definitions */
 #define KW88F6281_REGS_PHYS_BASE	0xf1000000
 #define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
 
-/* TCLK Core Clock defination*/
-#define CONFIG_SYS_TCLK	  200000000 /* 200MHz */
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK	200000000 /* 200MHz */
+#endif
 
 #endif /* _ASM_ARCH_KW88F6281_H */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 3/5] mv-common.h: fix DRAM banks configuration
       [not found] <yes>
                   ` (37 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 4/5] netconsole: remove `serverip' check Simon Guinot
                   ` (52 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
needed to configure DRAM banks.

This patch move the asm/arch/config.h header inclusion above the DRAM
banks configuration.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
 include/configs/mv-common.h |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index a8937dd..0a39257 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -113,6 +113,9 @@
 #define CONFIG_SYS_RESET_ADDRESS 0xffff0000	/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS	16	/* max number of command args */
 
+/* ====> Include platform Common Definitions */
+#include <asm/arch/config.h>
+
 /*
  * DRAM Banks configuration, Custom config can be done in <board>.h
  */
@@ -124,10 +127,7 @@
 #endif
 #endif /* CONFIG_NR_DRAM_BANKS */
 
-/* ====> Include platform Common Definations */
-#include <asm/arch/config.h>
-
-/* ====> Include driver Common Definations */
+/* ====> Include driver Common Definitions */
 /*
  * Common NAND configuration
  */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 4/5] netconsole: remove `serverip' check
       [not found] <yes>
                   ` (38 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 5/5] Add support for Network Space v2 Simon Guinot
                   ` (51 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

Netconsole use the environment variable `ncip' to configure the
destination IP. `serverip' don't need to be defined.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
 net/net.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/net.c b/net/net.c
index e50bdf1..19ac019 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1718,7 +1718,6 @@ static int net_check_prereq (proto_t protocol)
 #if defined(CONFIG_CMD_NFS)
 	case NFS:
 #endif
-	case NETCONS:
 	case TFTP:
 		if (NetServerIP == 0) {
 			puts ("*** ERROR: `serverip' not set\n");
@@ -1728,7 +1727,9 @@ static int net_check_prereq (proto_t protocol)
     defined(CONFIG_CMD_DNS)
     common:
 #endif
+		/* Fall through */
 
+	case NETCONS:
 		if (NetOurIP == 0) {
 			puts ("*** ERROR: `ipaddr' not set\n");
 			return (1);
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 5/5] Add support for Network Space v2
       [not found] <yes>
                   ` (39 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 4/5] netconsole: remove `serverip' check Simon Guinot
@ 2011-05-02 21:01 ` Simon Guinot
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS " Simon Guinot
                   ` (50 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 21:01 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

This patch add support for the Network Space v2 board and parents, based
on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
Internet Space v2.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
 MAINTAINERS                           |    6 +
 board/LaCie/netspace_v2/Makefile      |   49 ++++++++++
 board/LaCie/netspace_v2/kwbimage.cfg  |  162 +++++++++++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.c |  144 +++++++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.h |   39 ++++++++
 boards.cfg                            |    3 +
 include/configs/netspace_v2.h         |  149 ++++++++++++++++++++++++++++++
 7 files changed, 552 insertions(+), 0 deletions(-)
 create mode 100644 board/LaCie/netspace_v2/Makefile
 create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
 create mode 100644 include/configs/netspace_v2.h

diff --git a/MAINTAINERS b/MAINTAINERS
index e2a4ba9..f905a48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou@atmel.com>
 	at91sam9g10ek		ARM926EJS (AT91SAM9G10 SoC)
 	at91sam9m10g45ek	ARM926EJS (AT91SAM9G45 SoC)
 
+Simon Guinot <simon.guinot@sequanux.org>
+
+	inetspace_v2	ARM926EJS (Kirkwood SoC)
+	netspace_v2	ARM926EJS (Kirkwood SoC)
+	netspace_max_v2	ARM926EJS (Kirkwood SoC)
+
 Marius Gr?ger <mag@sysgo.de>
 
 	impa7		ARM720T (EP7211)
diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
new file mode 100644
index 0000000..a245f2c
--- /dev/null
+++ b/board/LaCie/netspace_v2/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= netspace_v2.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
new file mode 100644
index 0000000..361feeb
--- /dev/null
+++ b/board/LaCie/netspace_v2/kwbimage.cfg
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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.
+#
+# Refer docs/README.kwimage for more details about how-to configure
+# and create kirkwood boot image
+#
+
+# Boot Media configurations
+BOOT_FROM	spi	# Boot from SPI flash
+
+# SOC registers configuration using bootrom header extension
+# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
+
+# Configure RGMII-0 interface pad voltage to 1.8V
+DATA 0xFFD100e0 0x1B1B1B9B
+
+#Dram initalization for SINGLE x16 CL=5 @ 400MHz
+DATA 0xFFD01400 0x43000618	# DDR Configuration register
+# bit13-0:  0xa00 (2560 DDR2 clks refresh rate)
+# bit23-14: zero
+# bit24: 1= enable exit self refresh mode on DDR access
+# bit25: 1 required
+# bit29-26: zero
+# bit31-30: 01
+
+DATA 0xFFD01404 0x35143000	# DDR Controller Control Low
+# bit 4:    0=addr/cmd in smame cycle
+# bit 5:    0=clk is driven during self refresh, we don't care for APX
+# bit 6:    0=use recommended falling edge of clk for addr/cmd
+# bit14:    0=input buffer always powered up
+# bit18:    1=cpu lock transaction enabled
+# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
+# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
+# bit30-28: 3 required
+# bit31:    0=no additional STARTBURST delay
+
+DATA 0xFFD01408 0x11012228	# DDR Timing (Low) (active cycles value +1)
+# bit7-4:   TRCD
+# bit11- 8: TRP
+# bit15-12: TWR
+# bit19-16: TWTR
+# bit20:    TRAS msb
+# bit23-21: 0x0
+# bit27-24: TRRD
+# bit31-28: TRTP
+
+DATA 0xFFD0140C 0x00000A19	#  DDR Timing (High)
+# bit6-0:   TRFC
+# bit8-7:   TR2R
+# bit10-9:  TR2W
+# bit12-11: TW2W
+# bit31-13: zero required
+
+DATA 0xFFD01410 0x0000CCCC	#  DDR Address Control
+# bit1-0:   01, Cs0width=x16
+# bit3-2:   11, Cs0size=1Gb
+# bit5-4:   00, Cs2width=nonexistent
+# bit7-6:   00, Cs1size =nonexistent
+# bit9-8:   00, Cs2width=nonexistent
+# bit11-10: 00, Cs2size =nonexistent
+# bit13-12: 00, Cs3width=nonexistent
+# bit15-14: 00, Cs3size =nonexistent
+# bit16:    0,  Cs0AddrSel
+# bit17:    0,  Cs1AddrSel
+# bit18:    0,  Cs2AddrSel
+# bit19:    0,  Cs3AddrSel
+# bit31-20: 0 required
+
+DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
+# bit0:    0,  OpenPage enabled
+# bit31-1: 0 required
+
+DATA 0xFFD01418 0x00000000	#  DDR Operation
+# bit3-0:   0x0, DDR cmd
+# bit31-4:  0 required
+
+DATA 0xFFD0141C 0x00000632	#  DDR Mode
+# bit2-0:   2, BurstLen=2 required
+# bit3:     0, BurstType=0 required
+# bit6-4:   4, CL=5
+# bit7:     0, TestMode=0 normal
+# bit8:     0, DLL reset=0 normal
+# bit11-9:  6, auto-precharge write recovery ????????????
+# bit12:    0, PD must be zero
+# bit31-13: 0 required
+
+DATA 0xFFD01420 0x00000004	#  DDR Extended Mode
+# bit0:    0,  DDR DLL enabled
+# bit1:    1,  DDR drive strenght reduced
+# bit2:    1,  DDR ODT control lsd enabled
+# bit5-3:  000, required
+# bit6:    1,  DDR ODT control msb, enabled
+# bit9-7:  000, required
+# bit10:   0,  differential DQS enabled
+# bit11:   0, required
+# bit12:   0, DDR output buffer enabled
+# bit31-13: 0 required
+
+DATA 0xFFD01424 0x0000F07F	#  DDR Controller Control High
+# bit2-0:  111, required
+# bit3  :  1  , MBUS Burst Chop disabled
+# bit6-4:  111, required
+# bit7  :  1  , D2P Latency enabled
+# bit8  :  1  , add writepath sample stage, must be 1 for DDR freq >= 300MHz
+# bit9  :  0  , no half clock cycle addition to dataout
+# bit10 :  0  , 1/4 clock cycle skew enabled for addr/ctl signals
+# bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
+# bit15-12: 1111 required
+# bit31-16: 0    required
+
+DATA 0xFFD01428 0x00085520	# DDR2 ODT Read Timing (default values)
+DATA 0xFFD0147C 0x00008552	# DDR2 ODT Write Timing (default values)
+
+DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
+DATA 0xFFD01504 0x0FFFFFF1	# CS[0]n Size
+# bit0:    1,  Window enabled
+# bit1:    0,  Write Protect disabled
+# bit3-2:  00, CS0 hit selected
+# bit23-4: ones, required
+# bit31-24: 0x07, Size (i.e. 128MB)
+
+DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
+DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
+DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
+
+DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
+# bit3-0:  1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
+# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
+
+DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
+# bit1-0:  00, ODT0 controlled by ODT Control (low) register above
+# bit3-2:  01, ODT1 active NEVER!
+# bit31-4: zero, required
+
+DATA 0xFFD0149C 0x0000E40F	# CPU ODT Control
+# bit3-0:  1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
+# bit7-4:  1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
+# bit11-10:1, DQ_ODTSel. ODT select turned on
+
+DATA 0xFFD01480 0x00000001	# DDR Initialization Control
+#bit0=1, enable DDR init upon this register write
+
+# End of Header extension
+DATA 0x0 0x0
diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
new file mode 100644
index 0000000..9bc9940
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <command.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+#include <asm/arch/gpio.h>
+#include "netspace_v2.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+	/* Gpio configuration */
+	kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
+			NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
+
+	/* Multi-Purpose Pins Functionality configuration */
+	u32 kwmpp_config[] = {
+		MPP0_SPI_SCn,
+		MPP1_SPI_MOSI,
+		MPP2_SPI_SCK,
+		MPP3_SPI_MISO,
+		MPP4_NF_IO6,
+		MPP5_NF_IO7,
+		MPP6_SYSRST_OUTn,
+		MPP7_GPO,		/* Fan speed (bit 1) */
+		MPP8_TW_SDA,
+		MPP9_TW_SCK,
+		MPP10_UART0_TXD,
+		MPP11_UART0_RXD,
+		MPP12_GPO,		/* Red led */
+		MPP14_GPIO,		/* USB fuse */
+		MPP16_GPIO,		/* SATA 0 power */
+		MPP17_GPIO,		/* SATA 1 power */
+		MPP18_NF_IO0,
+		MPP19_NF_IO1,
+		MPP20_SATA1_ACTn,
+		MPP21_SATA0_ACTn,
+		MPP22_GPIO,		/* Fan speed (bit 0) */
+		MPP23_GPIO,		/* Fan power */
+		MPP24_GPIO,		/* USB mode select */
+		MPP25_GPIO,		/* Fan rotation fail */
+		MPP26_GPIO,		/* USB vbus-in detection */
+		MPP28_GPIO,		/* USB enable vbus-out */
+		MPP29_GPIO,		/* Blue led (slow register) */
+		MPP30_GPIO,		/* Blue led (command register) */
+		MPP31_GPIO,		/* Board power off */
+		MPP32_GPIO,		/* Button (0 = Released, 1 = Pushed) */
+		MPP33_GPIO,		/* Fan speed (bit 2) */
+		0
+	};
+	kirkwood_mpp_conf(kwmpp_config);
+
+	return 0;
+}
+
+int board_init(void)
+{
+	/* Machine number */
+	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+	/* Boot parameters address */
+	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+
+	return 0;
+}
+
+void mv_phy_88e1116_init(char *name)
+{
+	u16 reg;
+	u16 devadr;
+
+	if (miiphy_set_current_dev(name))
+		return;
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+		printf("Err..(%s) could not read PHY dev address\n", __func__);
+		return;
+	}
+
+	/*
+	 * Enable RGMII delay on Tx and Rx for CPU port
+	 * Ref: sec 4.7.2 of chip datasheet
+	 */
+	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+	miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+	reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+	miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
+	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+
+	/* reset the phy */
+	if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
+		printf("Err..(%s) PHY status read failed\n", __func__);
+		return;
+	}
+	if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
+		printf("Err..(%s) PHY reset failed\n", __func__);
+		return;
+	}
+
+	debug("88E1116 Initialized on %s\n", name);
+}
+
+/* Configure and initialize PHY */
+void reset_phy(void)
+{
+	mv_phy_88e1116_init("egiga0");
+}
+
+#define NETSPACE_V2_GPIO_BUTTON		32
+
+/* Return GPIO button status */
+static int
+do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
+}
+
+U_BOOT_CMD(button, 1, 1, do_read_button,
+	   "Return GPIO button status 0=off 1=on", "");
diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
new file mode 100644
index 0000000..c26a6e0
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#ifndef NETSPACE_V2_H
+#define NETSPACE_V2_H
+
+#define NETSPACE_V2_OE_LOW		0x06004000
+#define NETSPACE_V2_OE_HIGH		0x00000031
+#define NETSPACE_V2_OE_VAL_LOW		0x10030000
+#define NETSPACE_V2_OE_VAL_HIGH		0x00000000
+
+/* PHY related */
+#define MV88E1116_LED_FCTRL_REG		10
+#define MV88E1116_CPRSP_CR3_REG		21
+#define MV88E1116_MAC_CTRL_REG		21
+#define MV88E1116_PGADR_REG		22
+#define MV88E1116_RGMII_TXTM_CTRL	(1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL	(1 << 5)
+
+#endif /* NETSPACE_V2_H */
diff --git a/boards.cfg b/boards.cfg
index 2b0900a..459dee4 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -106,6 +106,9 @@ davinci_sonata               arm         arm926ejs   sonata              davinci
 suen3                        arm         arm926ejs   km_arm              keymile        kirkwood
 suen8                        arm         arm926ejs   km_arm              keymile        kirkwood
 mgcoge2un                    arm         arm926ejs   km_arm              keymile        kirkwood
+inetspace_v2                 arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:INETSPACE_V2
+netspace_v2                  arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_V2
+netspace_max_v2              arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_MAX_V2
 guruplug                     arm         arm926ejs   -                   Marvell        kirkwood
 mv88f6281gtw_ge              arm         arm926ejs   -                   Marvell        kirkwood
 openrd_base                  arm         arm926ejs   -                   Marvell        kirkwood
diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
new file mode 100644
index 0000000..ca4db53
--- /dev/null
+++ b/include/configs/netspace_v2.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#ifndef _CONFIG_NETSPACE_V2_H
+#define _CONFIG_NETSPACE_V2_H
+
+/*
+ * Machine number definition
+ */
+#if defined(CONFIG_INETSPACE_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_INETSPACE_V2
+#define CONFIG_IDENT_STRING		" LaCie Internet Space v2"
+#elif defined(CONFIG_NETSPACE_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_V2
+#define CONFIG_IDENT_STRING		" LaCie Network Space v2"
+#elif defined(CONFIG_NETSPACE_MAX_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_MAX_V2
+#define CONFIG_IDENT_STRING		" LaCie Network Space Max v2"
+#endif
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_FEROCEON_88FR131		1 /* CPU Core subversion */
+#define CONFIG_KIRKWOOD			1 /* SOC Family Name */
+#define CONFIG_KW88F6281		1 /* SOC Name */
+#define CONFIG_MACH_NETSPACE_V2		1 /* Machine type */
+#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IDE
+#define CONFIG_CMD_USB
+
+/*
+ * Core clock definition.
+ */
+#define CONFIG_SYS_TCLK			166000000 /* 166MHz */
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#define CONFIG_NR_DRAM_BANKS		2
+#include "mv-common.h"
+
+/* Remove or override few declarations from mv-common.h */
+#undef CONFIG_RBTREE
+#undef CONFIG_ENV_SPI_MAX_HZ
+#undef CONFIG_SYS_IDE_MAXBUS
+#undef CONFIG_SYS_IDE_MAXDEVICE
+#undef CONFIG_SYS_PROMPT
+#define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
+#define CONFIG_SYS_IDE_MAXBUS           1
+#define CONFIG_SYS_IDE_MAXDEVICE        1
+#define CONFIG_SYS_PROMPT		"ns2> "
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_MVGBE_PORTS		{1, 0} /* enable port 0 only */
+#define CONFIG_NETCONSOLE
+#endif
+
+/*
+ * SATA Driver configuration
+ */
+#ifdef CONFIG_MVSATA_IDE
+#define CONFIG_SYS_ATA_IDE0_OFFSET      MV_SATA_PORT0_OFFSET
+/* Network Space Max v2 use 2 SATA ports */
+#ifdef CONFIG_NETSPACE_MAX_V2
+#define CONFIG_SYS_ATA_IDE1_OFFSET      MV_SATA_PORT1_OFFSET
+#endif
+#endif
+
+/*
+ * Enable GPI0 support
+ */
+#define CONFIG_KIRKWOOD_GPIO
+
+/*
+ * File systems support
+ */
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+
+/*
+ * Use the HUSH parser
+ */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+
+/*
+ * Console configuration
+ */
+#define CONFIG_CONSOLE_MUX		1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+
+/*
+ * Environment variables configurations
+ */
+#define CONFIG_ENV_IS_IN_SPI_FLASH	1
+#define CONFIG_ENV_SECT_SIZE		0x10000	/* 64KB */
+#define CONFIG_ENV_SIZE			0x1000	/* 4KB */
+#define CONFIG_ENV_ADDR			0x70000
+#define CONFIG_ENV_OFFSET		0x70000	/* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTARGS "console=ttyS0,115200"
+
+#define CONFIG_BOOTCOMMAND				\
+	"if run usbload || run diskload; then bootm 0x800000; fi"
+
+#define CONFIG_EXTRA_ENV_SETTINGS			\
+	"stdin=serial,nc\0"				\
+	"stdout=serial,nc\0"				\
+	"stderr=serial,nc\0"				\
+	"ipaddr=192.168.1.111\0"			\
+	"diskload=ide reset && "			\
+	"ext2load ide 0:1 0x800000 /boot/uImage\0"	\
+	"usbload=usb start && "				\
+	"fatload usb 0:1 0x800000 /boot/uImage\0"
+
+#endif /* _CONFIG_NETSPACE_V2_H */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash Simon Guinot
@ 2011-05-02 21:07   ` Mike Frysinger
  0 siblings, 0 replies; 716+ messages in thread
From: Mike Frysinger @ 2011-05-02 21:07 UTC (permalink / raw)
  To: u-boot

thanks, ive added this to my sf branch
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110502/6fbac8c9/attachment.pgp 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2 Simon Guinot
@ 2011-05-02 21:29   ` Wolfgang Denk
  2011-05-02 22:46     ` Simon Guinot
  0 siblings, 1 reply; 716+ messages in thread
From: Wolfgang Denk @ 2011-05-02 21:29 UTC (permalink / raw)
  To: u-boot

Dear Simon Guinot,

In message <1304370102-5978-1-git-send-email-simon.guinot@sequanux.org> you wrote:
> From: Simon Guinot <sguinot@lacie.com>
> 
> This patch series adds support for Network Space v2 board and parents.
> 
> Changes since v1:
...

Please read
http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions

You are supposed to provide such a changelog not (only) in a header
message, but in each patch of the series.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If it happens once, it's a bug.
If it happens twice, it's a feature.
If it happens more than twice, it's a design philosophy.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS Network Space v2
       [not found] <yes>
                   ` (40 preceding siblings ...)
  2011-05-02 21:01 ` [U-Boot] [PATCH v4 5/5] Add support for Network Space v2 Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-05-03  9:59   ` Prafulla Wadaskar
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash Simon Guinot
                   ` (49 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

This patch series adds support for Network Space v2 board and parents.

Changes for v2:
  - netconsole: restore NetOurIP check
  - add entries to MAINTAINERS file
  - move boards from root Makefile to boards.cfg
  - move MACH_TYPE definition into netspace_v2.h
  - remove CONFIG_SYS_HZ redefinition
  - turn PHY initialization message into debug()

Changes for v3:
  - drop patch for Macronix MX25L4005A
  - rewrite patch "sf: disable write protection for Macronix flash",
    using the common spi flash code
  - fix "Definitions" typo in mv-common.h
  - netconsole: add a "/* Fall through */" comment before the NETCONS
    case label

Changes for v4:
  - sf macronix: use spi_flash_cmd_write_enable()
  - enhance commit message for patch "Add support for Network Space v2"

Changes for v5:
  - add a changelog per patch

Simon Guinot (5):
  sf: disable write protection for Macronix flash
  Kirkwood: allow to override CONFIG_SYS_TCLK
  mv-common.h: fix DRAM banks configuration
  netconsole: remove `serverip' check
  Add support for Network Space v2

 MAINTAINERS                                    |    6 +
 arch/arm/include/asm/arch-kirkwood/kw88f6281.h |    8 +-
 board/LaCie/netspace_v2/Makefile               |   49 +++++++
 board/LaCie/netspace_v2/kwbimage.cfg           |  162 ++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.c          |  144 +++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.h          |   39 ++++++
 boards.cfg                                     |    3 +
 drivers/mtd/spi/macronix.c                     |   42 ++++++
 include/configs/mv-common.h                    |    8 +-
 include/configs/netspace_v2.h                  |  149 ++++++++++++++++++++++
 net/net.c                                      |    3 +-
 11 files changed, 605 insertions(+), 8 deletions(-)
 create mode 100644 board/LaCie/netspace_v2/Makefile
 create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
 create mode 100644 include/configs/netspace_v2.h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash
       [not found] <yes>
                   ` (41 preceding siblings ...)
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS " Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-07-08 20:32   ` [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing Mike Frysinger
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
                   ` (48 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---

Changes for v2: none

Changes for v3:
  - rewrite patch using the common spi flash code

Changes for v4:
  - use spi_flash_cmd_write_enable()

Changes for v5: none

 drivers/mtd/spi/macronix.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
 	},
 };
 
+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+	u8 cmd;
+	int ret;
+
+	ret = spi_flash_cmd_write_enable(flash);
+	if (ret < 0) {
+		debug("SF: enabling write failed\n");
+		return ret;
+	}
+
+	cmd = CMD_MX25XX_WRSR;
+	ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+	if (ret) {
+		debug("SF: fail to write status register\n");
+		return ret;
+	}
+
+	ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (ret < 0) {
+		debug("SF: write status register timed out\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+	int ret;
+
+	/* Enable status register writing and clear BP# bits */
+	ret = macronix_write_status(flash, 0);
+	if (ret)
+		debug("SF: fail to disable write protection\n");
+
+	return ret;
+}
+
 static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
 		* params->sectors_per_block;
 	flash->size = flash->sector_size * params->nr_blocks;
 
+	/* Clear BP# bits for read-only flash */
+	macronix_unlock(flash);
+
 	return flash;
 }
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK
       [not found] <yes>
                   ` (42 preceding siblings ...)
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-05-03 12:09   ` Prafulla Wadaskar
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
                   ` (47 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

This patch allow to override CONFIG_SYS_TCLK from board configuration
files. This is needed for the Network Space v2 which use a non standard
core clock frequency (166MHz instead of 200MHz for a 6281 SoC).

As a possible enhancement for 6281 and 6282 devices, TCLK could be
dynamically detected by checking the Sample at Reset register bit 21.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
Acked-by: Prafulla Wadaskar <Prafulla@marvell.com>
---
Changes for v[1-5]: none

 arch/arm/include/asm/arch-kirkwood/kw88f6281.h |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
index 80723ea..22d10f1 100644
--- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
+++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
@@ -27,11 +27,13 @@
 #ifndef _ASM_ARCH_KW88F6281_H
 #define _ASM_ARCH_KW88F6281_H
 
-/* SOC specific definations */
+/* SOC specific definitions */
 #define KW88F6281_REGS_PHYS_BASE	0xf1000000
 #define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
 
-/* TCLK Core Clock defination*/
-#define CONFIG_SYS_TCLK	  200000000 /* 200MHz */
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK	200000000 /* 200MHz */
+#endif
 
 #endif /* _ASM_ARCH_KW88F6281_H */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration
       [not found] <yes>
                   ` (43 preceding siblings ...)
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-05-03 12:09   ` Prafulla Wadaskar
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 4/5] netconsole: remove `serverip' check Simon Guinot
                   ` (46 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
needed to configure DRAM banks.

This patch move the asm/arch/config.h header inclusion above the DRAM
banks configuration.

Additionally this patch fix a typo.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
Changes for v2: none

Changes for v3:
  - fix "Definitions" typo in mv-common.h

Changes for v4,5: none

 include/configs/mv-common.h |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index a8937dd..0a39257 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -113,6 +113,9 @@
 #define CONFIG_SYS_RESET_ADDRESS 0xffff0000	/* Rst Vector Adr */
 #define CONFIG_SYS_MAXARGS	16	/* max number of command args */
 
+/* ====> Include platform Common Definitions */
+#include <asm/arch/config.h>
+
 /*
  * DRAM Banks configuration, Custom config can be done in <board>.h
  */
@@ -124,10 +127,7 @@
 #endif
 #endif /* CONFIG_NR_DRAM_BANKS */
 
-/* ====> Include platform Common Definations */
-#include <asm/arch/config.h>
-
-/* ====> Include driver Common Definations */
+/* ====> Include driver Common Definitions */
 /*
  * Common NAND configuration
  */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 4/5] netconsole: remove `serverip' check
       [not found] <yes>
                   ` (44 preceding siblings ...)
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 5/5] Add support for Network Space v2 Simon Guinot
                   ` (45 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

Netconsole use the environment variable `ncip' to configure the
destination IP. `serverip' don't need to be defined.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
Changes for v2:
  - restore NetOurIP check

Changes for v3:
  - add a "/* Fall through */" comment before the NETCONS case label

Changes for v4,5: none

 net/net.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/net.c b/net/net.c
index e50bdf1..19ac019 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1718,7 +1718,6 @@ static int net_check_prereq (proto_t protocol)
 #if defined(CONFIG_CMD_NFS)
 	case NFS:
 #endif
-	case NETCONS:
 	case TFTP:
 		if (NetServerIP == 0) {
 			puts ("*** ERROR: `serverip' not set\n");
@@ -1728,7 +1727,9 @@ static int net_check_prereq (proto_t protocol)
     defined(CONFIG_CMD_DNS)
     common:
 #endif
+		/* Fall through */
 
+	case NETCONS:
 		if (NetOurIP == 0) {
 			puts ("*** ERROR: `ipaddr' not set\n");
 			return (1);
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 5/5] Add support for Network Space v2
       [not found] <yes>
                   ` (45 preceding siblings ...)
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 4/5] netconsole: remove `serverip' check Simon Guinot
@ 2011-05-02 22:42 ` Simon Guinot
  2011-05-03 13:19   ` Simon Guinot
  2011-06-15  0:46   ` Wu DaoGuang
                   ` (44 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:42 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

This patch add support for the Network Space v2 board and parents, based
on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
Internet Space v2.

Signed-off-by: Simon Guinot <sguinot@lacie.com>
---
Changes for v2:
  - add entries to MAINTAINERS file
  - move boards from root Makefile to boards.cfg
  - move MACH_TYPE definition into netspace_v2.h
  - remove CONFIG_SYS_HZ redefinition
  - turn PHY initialization message into debug()

Changes for v3: none

Changes for v4: 
  - enhance commit message: add SoC information

Changes for v5: none

 MAINTAINERS                           |    6 +
 board/LaCie/netspace_v2/Makefile      |   49 ++++++++++
 board/LaCie/netspace_v2/kwbimage.cfg  |  162 +++++++++++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.c |  144 +++++++++++++++++++++++++++++
 board/LaCie/netspace_v2/netspace_v2.h |   39 ++++++++
 boards.cfg                            |    3 +
 include/configs/netspace_v2.h         |  149 ++++++++++++++++++++++++++++++
 7 files changed, 552 insertions(+), 0 deletions(-)
 create mode 100644 board/LaCie/netspace_v2/Makefile
 create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
 create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
 create mode 100644 include/configs/netspace_v2.h

diff --git a/MAINTAINERS b/MAINTAINERS
index e2a4ba9..f905a48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou@atmel.com>
 	at91sam9g10ek		ARM926EJS (AT91SAM9G10 SoC)
 	at91sam9m10g45ek	ARM926EJS (AT91SAM9G45 SoC)
 
+Simon Guinot <simon.guinot@sequanux.org>
+
+	inetspace_v2	ARM926EJS (Kirkwood SoC)
+	netspace_v2	ARM926EJS (Kirkwood SoC)
+	netspace_max_v2	ARM926EJS (Kirkwood SoC)
+
 Marius Gr?ger <mag@sysgo.de>
 
 	impa7		ARM720T (EP7211)
diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
new file mode 100644
index 0000000..a245f2c
--- /dev/null
+++ b/board/LaCie/netspace_v2/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= netspace_v2.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
new file mode 100644
index 0000000..361feeb
--- /dev/null
+++ b/board/LaCie/netspace_v2/kwbimage.cfg
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+#
+# Based on Kirkwood support:
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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.
+#
+# Refer docs/README.kwimage for more details about how-to configure
+# and create kirkwood boot image
+#
+
+# Boot Media configurations
+BOOT_FROM	spi	# Boot from SPI flash
+
+# SOC registers configuration using bootrom header extension
+# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
+
+# Configure RGMII-0 interface pad voltage to 1.8V
+DATA 0xFFD100e0 0x1B1B1B9B
+
+#Dram initalization for SINGLE x16 CL=5 @ 400MHz
+DATA 0xFFD01400 0x43000618	# DDR Configuration register
+# bit13-0:  0xa00 (2560 DDR2 clks refresh rate)
+# bit23-14: zero
+# bit24: 1= enable exit self refresh mode on DDR access
+# bit25: 1 required
+# bit29-26: zero
+# bit31-30: 01
+
+DATA 0xFFD01404 0x35143000	# DDR Controller Control Low
+# bit 4:    0=addr/cmd in smame cycle
+# bit 5:    0=clk is driven during self refresh, we don't care for APX
+# bit 6:    0=use recommended falling edge of clk for addr/cmd
+# bit14:    0=input buffer always powered up
+# bit18:    1=cpu lock transaction enabled
+# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
+# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
+# bit30-28: 3 required
+# bit31:    0=no additional STARTBURST delay
+
+DATA 0xFFD01408 0x11012228	# DDR Timing (Low) (active cycles value +1)
+# bit7-4:   TRCD
+# bit11- 8: TRP
+# bit15-12: TWR
+# bit19-16: TWTR
+# bit20:    TRAS msb
+# bit23-21: 0x0
+# bit27-24: TRRD
+# bit31-28: TRTP
+
+DATA 0xFFD0140C 0x00000A19	#  DDR Timing (High)
+# bit6-0:   TRFC
+# bit8-7:   TR2R
+# bit10-9:  TR2W
+# bit12-11: TW2W
+# bit31-13: zero required
+
+DATA 0xFFD01410 0x0000CCCC	#  DDR Address Control
+# bit1-0:   01, Cs0width=x16
+# bit3-2:   11, Cs0size=1Gb
+# bit5-4:   00, Cs2width=nonexistent
+# bit7-6:   00, Cs1size =nonexistent
+# bit9-8:   00, Cs2width=nonexistent
+# bit11-10: 00, Cs2size =nonexistent
+# bit13-12: 00, Cs3width=nonexistent
+# bit15-14: 00, Cs3size =nonexistent
+# bit16:    0,  Cs0AddrSel
+# bit17:    0,  Cs1AddrSel
+# bit18:    0,  Cs2AddrSel
+# bit19:    0,  Cs3AddrSel
+# bit31-20: 0 required
+
+DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
+# bit0:    0,  OpenPage enabled
+# bit31-1: 0 required
+
+DATA 0xFFD01418 0x00000000	#  DDR Operation
+# bit3-0:   0x0, DDR cmd
+# bit31-4:  0 required
+
+DATA 0xFFD0141C 0x00000632	#  DDR Mode
+# bit2-0:   2, BurstLen=2 required
+# bit3:     0, BurstType=0 required
+# bit6-4:   4, CL=5
+# bit7:     0, TestMode=0 normal
+# bit8:     0, DLL reset=0 normal
+# bit11-9:  6, auto-precharge write recovery ????????????
+# bit12:    0, PD must be zero
+# bit31-13: 0 required
+
+DATA 0xFFD01420 0x00000004	#  DDR Extended Mode
+# bit0:    0,  DDR DLL enabled
+# bit1:    1,  DDR drive strenght reduced
+# bit2:    1,  DDR ODT control lsd enabled
+# bit5-3:  000, required
+# bit6:    1,  DDR ODT control msb, enabled
+# bit9-7:  000, required
+# bit10:   0,  differential DQS enabled
+# bit11:   0, required
+# bit12:   0, DDR output buffer enabled
+# bit31-13: 0 required
+
+DATA 0xFFD01424 0x0000F07F	#  DDR Controller Control High
+# bit2-0:  111, required
+# bit3  :  1  , MBUS Burst Chop disabled
+# bit6-4:  111, required
+# bit7  :  1  , D2P Latency enabled
+# bit8  :  1  , add writepath sample stage, must be 1 for DDR freq >= 300MHz
+# bit9  :  0  , no half clock cycle addition to dataout
+# bit10 :  0  , 1/4 clock cycle skew enabled for addr/ctl signals
+# bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
+# bit15-12: 1111 required
+# bit31-16: 0    required
+
+DATA 0xFFD01428 0x00085520	# DDR2 ODT Read Timing (default values)
+DATA 0xFFD0147C 0x00008552	# DDR2 ODT Write Timing (default values)
+
+DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
+DATA 0xFFD01504 0x0FFFFFF1	# CS[0]n Size
+# bit0:    1,  Window enabled
+# bit1:    0,  Write Protect disabled
+# bit3-2:  00, CS0 hit selected
+# bit23-4: ones, required
+# bit31-24: 0x07, Size (i.e. 128MB)
+
+DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
+DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
+DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
+
+DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
+# bit3-0:  1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
+# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
+
+DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
+# bit1-0:  00, ODT0 controlled by ODT Control (low) register above
+# bit3-2:  01, ODT1 active NEVER!
+# bit31-4: zero, required
+
+DATA 0xFFD0149C 0x0000E40F	# CPU ODT Control
+# bit3-0:  1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
+# bit7-4:  1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
+# bit11-10:1, DQ_ODTSel. ODT select turned on
+
+DATA 0xFFD01480 0x00000001	# DDR Initialization Control
+#bit0=1, enable DDR init upon this register write
+
+# End of Header extension
+DATA 0x0 0x0
diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
new file mode 100644
index 0000000..9bc9940
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <command.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/arch/mpp.h>
+#include <asm/arch/gpio.h>
+#include "netspace_v2.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+	/* Gpio configuration */
+	kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
+			NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
+
+	/* Multi-Purpose Pins Functionality configuration */
+	u32 kwmpp_config[] = {
+		MPP0_SPI_SCn,
+		MPP1_SPI_MOSI,
+		MPP2_SPI_SCK,
+		MPP3_SPI_MISO,
+		MPP4_NF_IO6,
+		MPP5_NF_IO7,
+		MPP6_SYSRST_OUTn,
+		MPP7_GPO,		/* Fan speed (bit 1) */
+		MPP8_TW_SDA,
+		MPP9_TW_SCK,
+		MPP10_UART0_TXD,
+		MPP11_UART0_RXD,
+		MPP12_GPO,		/* Red led */
+		MPP14_GPIO,		/* USB fuse */
+		MPP16_GPIO,		/* SATA 0 power */
+		MPP17_GPIO,		/* SATA 1 power */
+		MPP18_NF_IO0,
+		MPP19_NF_IO1,
+		MPP20_SATA1_ACTn,
+		MPP21_SATA0_ACTn,
+		MPP22_GPIO,		/* Fan speed (bit 0) */
+		MPP23_GPIO,		/* Fan power */
+		MPP24_GPIO,		/* USB mode select */
+		MPP25_GPIO,		/* Fan rotation fail */
+		MPP26_GPIO,		/* USB vbus-in detection */
+		MPP28_GPIO,		/* USB enable vbus-out */
+		MPP29_GPIO,		/* Blue led (slow register) */
+		MPP30_GPIO,		/* Blue led (command register) */
+		MPP31_GPIO,		/* Board power off */
+		MPP32_GPIO,		/* Button (0 = Released, 1 = Pushed) */
+		MPP33_GPIO,		/* Fan speed (bit 2) */
+		0
+	};
+	kirkwood_mpp_conf(kwmpp_config);
+
+	return 0;
+}
+
+int board_init(void)
+{
+	/* Machine number */
+	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+	/* Boot parameters address */
+	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
+
+	return 0;
+}
+
+void mv_phy_88e1116_init(char *name)
+{
+	u16 reg;
+	u16 devadr;
+
+	if (miiphy_set_current_dev(name))
+		return;
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
+		printf("Err..(%s) could not read PHY dev address\n", __func__);
+		return;
+	}
+
+	/*
+	 * Enable RGMII delay on Tx and Rx for CPU port
+	 * Ref: sec 4.7.2 of chip datasheet
+	 */
+	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
+	miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
+	reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
+	miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
+	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+
+	/* reset the phy */
+	if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
+		printf("Err..(%s) PHY status read failed\n", __func__);
+		return;
+	}
+	if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
+		printf("Err..(%s) PHY reset failed\n", __func__);
+		return;
+	}
+
+	debug("88E1116 Initialized on %s\n", name);
+}
+
+/* Configure and initialize PHY */
+void reset_phy(void)
+{
+	mv_phy_88e1116_init("egiga0");
+}
+
+#define NETSPACE_V2_GPIO_BUTTON		32
+
+/* Return GPIO button status */
+static int
+do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
+}
+
+U_BOOT_CMD(button, 1, 1, do_read_button,
+	   "Return GPIO button status 0=off 1=on", "");
diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
new file mode 100644
index 0000000..c26a6e0
--- /dev/null
+++ b/board/LaCie/netspace_v2/netspace_v2.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * Based on Kirkwood support:
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#ifndef NETSPACE_V2_H
+#define NETSPACE_V2_H
+
+#define NETSPACE_V2_OE_LOW		0x06004000
+#define NETSPACE_V2_OE_HIGH		0x00000031
+#define NETSPACE_V2_OE_VAL_LOW		0x10030000
+#define NETSPACE_V2_OE_VAL_HIGH		0x00000000
+
+/* PHY related */
+#define MV88E1116_LED_FCTRL_REG		10
+#define MV88E1116_CPRSP_CR3_REG		21
+#define MV88E1116_MAC_CTRL_REG		21
+#define MV88E1116_PGADR_REG		22
+#define MV88E1116_RGMII_TXTM_CTRL	(1 << 4)
+#define MV88E1116_RGMII_RXTM_CTRL	(1 << 5)
+
+#endif /* NETSPACE_V2_H */
diff --git a/boards.cfg b/boards.cfg
index 2b0900a..459dee4 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -106,6 +106,9 @@ davinci_sonata               arm         arm926ejs   sonata              davinci
 suen3                        arm         arm926ejs   km_arm              keymile        kirkwood
 suen8                        arm         arm926ejs   km_arm              keymile        kirkwood
 mgcoge2un                    arm         arm926ejs   km_arm              keymile        kirkwood
+inetspace_v2                 arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:INETSPACE_V2
+netspace_v2                  arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_V2
+netspace_max_v2              arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_MAX_V2
 guruplug                     arm         arm926ejs   -                   Marvell        kirkwood
 mv88f6281gtw_ge              arm         arm926ejs   -                   Marvell        kirkwood
 openrd_base                  arm         arm926ejs   -                   Marvell        kirkwood
diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
new file mode 100644
index 0000000..ca4db53
--- /dev/null
+++ b/include/configs/netspace_v2.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+#ifndef _CONFIG_NETSPACE_V2_H
+#define _CONFIG_NETSPACE_V2_H
+
+/*
+ * Machine number definition
+ */
+#if defined(CONFIG_INETSPACE_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_INETSPACE_V2
+#define CONFIG_IDENT_STRING		" LaCie Internet Space v2"
+#elif defined(CONFIG_NETSPACE_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_V2
+#define CONFIG_IDENT_STRING		" LaCie Network Space v2"
+#elif defined(CONFIG_NETSPACE_MAX_V2)
+#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_MAX_V2
+#define CONFIG_IDENT_STRING		" LaCie Network Space Max v2"
+#endif
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_FEROCEON_88FR131		1 /* CPU Core subversion */
+#define CONFIG_KIRKWOOD			1 /* SOC Family Name */
+#define CONFIG_KW88F6281		1 /* SOC Name */
+#define CONFIG_MACH_NETSPACE_V2		1 /* Machine type */
+#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
+
+/*
+ * Commands configuration
+ */
+#define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IDE
+#define CONFIG_CMD_USB
+
+/*
+ * Core clock definition.
+ */
+#define CONFIG_SYS_TCLK			166000000 /* 166MHz */
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#define CONFIG_NR_DRAM_BANKS		2
+#include "mv-common.h"
+
+/* Remove or override few declarations from mv-common.h */
+#undef CONFIG_RBTREE
+#undef CONFIG_ENV_SPI_MAX_HZ
+#undef CONFIG_SYS_IDE_MAXBUS
+#undef CONFIG_SYS_IDE_MAXDEVICE
+#undef CONFIG_SYS_PROMPT
+#define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
+#define CONFIG_SYS_IDE_MAXBUS           1
+#define CONFIG_SYS_IDE_MAXDEVICE        1
+#define CONFIG_SYS_PROMPT		"ns2> "
+
+/*
+ * Ethernet Driver configuration
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_MVGBE_PORTS		{1, 0} /* enable port 0 only */
+#define CONFIG_NETCONSOLE
+#endif
+
+/*
+ * SATA Driver configuration
+ */
+#ifdef CONFIG_MVSATA_IDE
+#define CONFIG_SYS_ATA_IDE0_OFFSET      MV_SATA_PORT0_OFFSET
+/* Network Space Max v2 use 2 SATA ports */
+#ifdef CONFIG_NETSPACE_MAX_V2
+#define CONFIG_SYS_ATA_IDE1_OFFSET      MV_SATA_PORT1_OFFSET
+#endif
+#endif
+
+/*
+ * Enable GPI0 support
+ */
+#define CONFIG_KIRKWOOD_GPIO
+
+/*
+ * File systems support
+ */
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+
+/*
+ * Use the HUSH parser
+ */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+
+/*
+ * Console configuration
+ */
+#define CONFIG_CONSOLE_MUX		1
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
+
+/*
+ * Environment variables configurations
+ */
+#define CONFIG_ENV_IS_IN_SPI_FLASH	1
+#define CONFIG_ENV_SECT_SIZE		0x10000	/* 64KB */
+#define CONFIG_ENV_SIZE			0x1000	/* 4KB */
+#define CONFIG_ENV_ADDR			0x70000
+#define CONFIG_ENV_OFFSET		0x70000	/* env starts here */
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_BOOTARGS "console=ttyS0,115200"
+
+#define CONFIG_BOOTCOMMAND				\
+	"if run usbload || run diskload; then bootm 0x800000; fi"
+
+#define CONFIG_EXTRA_ENV_SETTINGS			\
+	"stdin=serial,nc\0"				\
+	"stdout=serial,nc\0"				\
+	"stderr=serial,nc\0"				\
+	"ipaddr=192.168.1.111\0"			\
+	"diskload=ide reset && "			\
+	"ext2load ide 0:1 0x800000 /boot/uImage\0"	\
+	"usbload=usb start && "				\
+	"fatload usb 0:1 0x800000 /boot/uImage\0"
+
+#endif /* _CONFIG_NETSPACE_V2_H */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2
  2011-05-02 21:29   ` Wolfgang Denk
@ 2011-05-02 22:46     ` Simon Guinot
  0 siblings, 0 replies; 716+ messages in thread
From: Simon Guinot @ 2011-05-02 22:46 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Mon, May 02, 2011 at 11:29:35PM +0200, Wolfgang Denk wrote:
> Dear Simon Guinot,
> 
> In message <1304370102-5978-1-git-send-email-simon.guinot@sequanux.org> you wrote:
> > From: Simon Guinot <sguinot@lacie.com>
> > 
> > This patch series adds support for Network Space v2 board and parents.
> > 
> > Changes since v1:
> ...
> 
> Please read
> http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions
> 
> You are supposed to provide such a changelog not (only) in a header
> message, but in each patch of the series.

Added to v5.

Thanks,

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110502/99fc84d1/attachment.pgp 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS Network Space v2
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS " Simon Guinot
@ 2011-05-03  9:59   ` Prafulla Wadaskar
  0 siblings, 0 replies; 716+ messages in thread
From: Prafulla Wadaskar @ 2011-05-03  9:59 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 0/5] Add support for LaCie NAS Network Space v2
> 
> This patch series adds support for Network Space v2 board and parents.
> 
> Changes for v2:
>   - netconsole: restore NetOurIP check
>   - add entries to MAINTAINERS file
>   - move boards from root Makefile to boards.cfg
>   - move MACH_TYPE definition into netspace_v2.h
>   - remove CONFIG_SYS_HZ redefinition
>   - turn PHY initialization message into debug()
> 
> Changes for v3:
>   - drop patch for Macronix MX25L4005A
>   - rewrite patch "sf: disable write protection for Macronix flash",
>     using the common spi flash code
>   - fix "Definitions" typo in mv-common.h
>   - netconsole: add a "/* Fall through */" comment before the NETCONS
>     case label
> 
> Changes for v4:
>   - sf macronix: use spi_flash_cmd_write_enable()
>   - enhance commit message for patch "Add support for Network Space v2"
> 
> Changes for v5:
>   - add a changelog per patch
>

> Simon Guinot (5):
>   sf: disable write protection for Macronix flash

>   Kirkwood: allow to override CONFIG_SYS_TCLK
>   mv-common.h: fix DRAM banks configuration

Hi Simon

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
@ 2011-05-03 12:09   ` Prafulla Wadaskar
  0 siblings, 0 replies; 716+ messages in thread
From: Prafulla Wadaskar @ 2011-05-03 12:09 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration
> 
> From: Simon Guinot <sguinot@lacie.com>
> 
> The asm/arch/config.h header define CONFIG_NR_DRAM_BANKS_MAX, which is
> needed to configure DRAM banks.
> 
> This patch move the asm/arch/config.h header inclusion above the DRAM
> banks configuration.
> 
> Additionally this patch fix a typo.
> 
> Signed-off-by: Simon Guinot <sguinot@lacie.com>
> ---
> Changes for v2: none
> 
> Changes for v3:
>   - fix "Definitions" typo in mv-common.h
> 
> Changes for v4,5: none
> 
>  include/configs/mv-common.h |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
> index a8937dd..0a39257 100644
> --- a/include/configs/mv-common.h
> +++ b/include/configs/mv-common.h
> @@ -113,6 +113,9 @@
>  #define CONFIG_SYS_RESET_ADDRESS 0xffff0000	/* Rst Vector Adr */
>  #define CONFIG_SYS_MAXARGS	16	/* max number of command args */
> 
> +/* ====> Include platform Common Definitions */
> +#include <asm/arch/config.h>
> +
>  /*
>   * DRAM Banks configuration, Custom config can be done in <board>.h
>   */
> @@ -124,10 +127,7 @@
>  #endif
>  #endif /* CONFIG_NR_DRAM_BANKS */
> 
> -/* ====> Include platform Common Definations */
> -#include <asm/arch/config.h>
> -
> -/* ====> Include driver Common Definations */
> +/* ====> Include driver Common Definitions */
>  /*
>   * Common NAND configuration
>   */
> --
> 1.6.3.1

Applied to u-boot-marvell.git master branch

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
@ 2011-05-03 12:09   ` Prafulla Wadaskar
  0 siblings, 0 replies; 716+ messages in thread
From: Prafulla Wadaskar @ 2011-05-03 12:09 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Simon Guinot [mailto:simon.guinot at sequanux.org]
> Sent: Tuesday, May 03, 2011 4:12 AM
> To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk; Mike Frysinger
> Cc: u-boot at lists.denx.de; Simon Guinot
> Subject: [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK
> 
> From: Simon Guinot <sguinot@lacie.com>
> 
> This patch allow to override CONFIG_SYS_TCLK from board configuration
> files. This is needed for the Network Space v2 which use a non standard
> core clock frequency (166MHz instead of 200MHz for a 6281 SoC).
> 
> As a possible enhancement for 6281 and 6282 devices, TCLK could be
> dynamically detected by checking the Sample at Reset register bit 21.
> 
> Additionally this patch fix a typo.
> 
> Signed-off-by: Simon Guinot <sguinot@lacie.com>
> Acked-by: Prafulla Wadaskar <Prafulla@marvell.com>
> ---
> Changes for v[1-5]: none
> 
>  arch/arm/include/asm/arch-kirkwood/kw88f6281.h |    8 +++++---
>  1 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> index 80723ea..22d10f1 100644
> --- a/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> +++ b/arch/arm/include/asm/arch-kirkwood/kw88f6281.h
> @@ -27,11 +27,13 @@
>  #ifndef _ASM_ARCH_KW88F6281_H
>  #define _ASM_ARCH_KW88F6281_H
> 
> -/* SOC specific definations */
> +/* SOC specific definitions */
>  #define KW88F6281_REGS_PHYS_BASE	0xf1000000
>  #define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
> 
> -/* TCLK Core Clock defination*/
> -#define CONFIG_SYS_TCLK	  200000000 /* 200MHz */
> +/* TCLK Core Clock definition */
> +#ifndef CONFIG_SYS_TCLK
> +#define CONFIG_SYS_TCLK	200000000 /* 200MHz */
> +#endif
> 
>  #endif /* _ASM_ARCH_KW88F6281_H */
> --
> 1.6.3.1

Applied to u-boot-marvell.git master branch

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 5/5] Add support for Network Space v2
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 5/5] Add support for Network Space v2 Simon Guinot
@ 2011-05-03 13:19   ` Simon Guinot
  2011-05-12 17:24     ` Wolfgang Denk
  0 siblings, 1 reply; 716+ messages in thread
From: Simon Guinot @ 2011-05-03 13:19 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

I have failed to find an entry for this patch in the U-Boot patchwork
(and any previous version except the very first).

Have I missed something and/or done something wrong ?

Regards,

Simon

On Tue, May 03, 2011 at 12:42:28AM +0200, Simon Guinot wrote:
> From: Simon Guinot <sguinot@lacie.com>
> 
> This patch add support for the Network Space v2 board and parents, based
> on the Marvell Kirkwood SoC. This include Network Space (Max) v2 and
> Internet Space v2.
> 
> Signed-off-by: Simon Guinot <sguinot@lacie.com>
> ---
> Changes for v2:
>   - add entries to MAINTAINERS file
>   - move boards from root Makefile to boards.cfg
>   - move MACH_TYPE definition into netspace_v2.h
>   - remove CONFIG_SYS_HZ redefinition
>   - turn PHY initialization message into debug()
> 
> Changes for v3: none
> 
> Changes for v4: 
>   - enhance commit message: add SoC information
> 
> Changes for v5: none
> 
>  MAINTAINERS                           |    6 +
>  board/LaCie/netspace_v2/Makefile      |   49 ++++++++++
>  board/LaCie/netspace_v2/kwbimage.cfg  |  162 +++++++++++++++++++++++++++++++++
>  board/LaCie/netspace_v2/netspace_v2.c |  144 +++++++++++++++++++++++++++++
>  board/LaCie/netspace_v2/netspace_v2.h |   39 ++++++++
>  boards.cfg                            |    3 +
>  include/configs/netspace_v2.h         |  149 ++++++++++++++++++++++++++++++
>  7 files changed, 552 insertions(+), 0 deletions(-)
>  create mode 100644 board/LaCie/netspace_v2/Makefile
>  create mode 100644 board/LaCie/netspace_v2/kwbimage.cfg
>  create mode 100644 board/LaCie/netspace_v2/netspace_v2.c
>  create mode 100644 board/LaCie/netspace_v2/netspace_v2.h
>  create mode 100644 include/configs/netspace_v2.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e2a4ba9..f905a48 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -652,6 +652,12 @@ Sedji Gaouaou<sedji.gaouaou@atmel.com>
>  	at91sam9g10ek		ARM926EJS (AT91SAM9G10 SoC)
>  	at91sam9m10g45ek	ARM926EJS (AT91SAM9G45 SoC)
>  
> +Simon Guinot <simon.guinot@sequanux.org>
> +
> +	inetspace_v2	ARM926EJS (Kirkwood SoC)
> +	netspace_v2	ARM926EJS (Kirkwood SoC)
> +	netspace_max_v2	ARM926EJS (Kirkwood SoC)
> +
>  Marius Gr?ger <mag@sysgo.de>
>  
>  	impa7		ARM720T (EP7211)
> diff --git a/board/LaCie/netspace_v2/Makefile b/board/LaCie/netspace_v2/Makefile
> new file mode 100644
> index 0000000..a245f2c
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/Makefile
> @@ -0,0 +1,49 @@
> +#
> +# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
> +#
> +# Based on Kirkwood support:
> +# (C) Copyright 2009
> +# Marvell Semiconductor <www.marvell.com>
> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# 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.
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	= $(obj)lib$(BOARD).o
> +
> +COBJS	:= netspace_v2.o
> +
> +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS))
> +SOBJS	:= $(addprefix $(obj),$(SOBJS))
> +
> +$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
> +	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
> +
> +clean:
> +	rm -f $(SOBJS) $(OBJS)
> +
> +distclean:	clean
> +	rm -f $(LIB) core *.bak .depend
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/board/LaCie/netspace_v2/kwbimage.cfg b/board/LaCie/netspace_v2/kwbimage.cfg
> new file mode 100644
> index 0000000..361feeb
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/kwbimage.cfg
> @@ -0,0 +1,162 @@
> +#
> +# Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
> +#
> +# Based on Kirkwood support:
> +# (C) Copyright 2009
> +# Marvell Semiconductor <www.marvell.com>
> +# Written-by: Prafulla Wadaskar <prafulla@marvell.com>
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# 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.
> +#
> +# Refer docs/README.kwimage for more details about how-to configure
> +# and create kirkwood boot image
> +#
> +
> +# Boot Media configurations
> +BOOT_FROM	spi	# Boot from SPI flash
> +
> +# SOC registers configuration using bootrom header extension
> +# Maximum KWBIMAGE_MAX_CONFIG configurations allowed
> +
> +# Configure RGMII-0 interface pad voltage to 1.8V
> +DATA 0xFFD100e0 0x1B1B1B9B
> +
> +#Dram initalization for SINGLE x16 CL=5 @ 400MHz
> +DATA 0xFFD01400 0x43000618	# DDR Configuration register
> +# bit13-0:  0xa00 (2560 DDR2 clks refresh rate)
> +# bit23-14: zero
> +# bit24: 1= enable exit self refresh mode on DDR access
> +# bit25: 1 required
> +# bit29-26: zero
> +# bit31-30: 01
> +
> +DATA 0xFFD01404 0x35143000	# DDR Controller Control Low
> +# bit 4:    0=addr/cmd in smame cycle
> +# bit 5:    0=clk is driven during self refresh, we don't care for APX
> +# bit 6:    0=use recommended falling edge of clk for addr/cmd
> +# bit14:    0=input buffer always powered up
> +# bit18:    1=cpu lock transaction enabled
> +# bit23-20: 5=recommended value for CL=5 and STARTBURST_DEL disabled bit31=0
> +# bit27-24: 8= CL+3, STARTBURST sample stages, for freqs 400MHz, unbuffered DIMM
> +# bit30-28: 3 required
> +# bit31:    0=no additional STARTBURST delay
> +
> +DATA 0xFFD01408 0x11012228	# DDR Timing (Low) (active cycles value +1)
> +# bit7-4:   TRCD
> +# bit11- 8: TRP
> +# bit15-12: TWR
> +# bit19-16: TWTR
> +# bit20:    TRAS msb
> +# bit23-21: 0x0
> +# bit27-24: TRRD
> +# bit31-28: TRTP
> +
> +DATA 0xFFD0140C 0x00000A19	#  DDR Timing (High)
> +# bit6-0:   TRFC
> +# bit8-7:   TR2R
> +# bit10-9:  TR2W
> +# bit12-11: TW2W
> +# bit31-13: zero required
> +
> +DATA 0xFFD01410 0x0000CCCC	#  DDR Address Control
> +# bit1-0:   01, Cs0width=x16
> +# bit3-2:   11, Cs0size=1Gb
> +# bit5-4:   00, Cs2width=nonexistent
> +# bit7-6:   00, Cs1size =nonexistent
> +# bit9-8:   00, Cs2width=nonexistent
> +# bit11-10: 00, Cs2size =nonexistent
> +# bit13-12: 00, Cs3width=nonexistent
> +# bit15-14: 00, Cs3size =nonexistent
> +# bit16:    0,  Cs0AddrSel
> +# bit17:    0,  Cs1AddrSel
> +# bit18:    0,  Cs2AddrSel
> +# bit19:    0,  Cs3AddrSel
> +# bit31-20: 0 required
> +
> +DATA 0xFFD01414 0x00000000	#  DDR Open Pages Control
> +# bit0:    0,  OpenPage enabled
> +# bit31-1: 0 required
> +
> +DATA 0xFFD01418 0x00000000	#  DDR Operation
> +# bit3-0:   0x0, DDR cmd
> +# bit31-4:  0 required
> +
> +DATA 0xFFD0141C 0x00000632	#  DDR Mode
> +# bit2-0:   2, BurstLen=2 required
> +# bit3:     0, BurstType=0 required
> +# bit6-4:   4, CL=5
> +# bit7:     0, TestMode=0 normal
> +# bit8:     0, DLL reset=0 normal
> +# bit11-9:  6, auto-precharge write recovery ????????????
> +# bit12:    0, PD must be zero
> +# bit31-13: 0 required
> +
> +DATA 0xFFD01420 0x00000004	#  DDR Extended Mode
> +# bit0:    0,  DDR DLL enabled
> +# bit1:    1,  DDR drive strenght reduced
> +# bit2:    1,  DDR ODT control lsd enabled
> +# bit5-3:  000, required
> +# bit6:    1,  DDR ODT control msb, enabled
> +# bit9-7:  000, required
> +# bit10:   0,  differential DQS enabled
> +# bit11:   0, required
> +# bit12:   0, DDR output buffer enabled
> +# bit31-13: 0 required
> +
> +DATA 0xFFD01424 0x0000F07F	#  DDR Controller Control High
> +# bit2-0:  111, required
> +# bit3  :  1  , MBUS Burst Chop disabled
> +# bit6-4:  111, required
> +# bit7  :  1  , D2P Latency enabled
> +# bit8  :  1  , add writepath sample stage, must be 1 for DDR freq >= 300MHz
> +# bit9  :  0  , no half clock cycle addition to dataout
> +# bit10 :  0  , 1/4 clock cycle skew enabled for addr/ctl signals
> +# bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
> +# bit15-12: 1111 required
> +# bit31-16: 0    required
> +
> +DATA 0xFFD01428 0x00085520	# DDR2 ODT Read Timing (default values)
> +DATA 0xFFD0147C 0x00008552	# DDR2 ODT Write Timing (default values)
> +
> +DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
> +DATA 0xFFD01504 0x0FFFFFF1	# CS[0]n Size
> +# bit0:    1,  Window enabled
> +# bit1:    0,  Write Protect disabled
> +# bit3-2:  00, CS0 hit selected
> +# bit23-4: ones, required
> +# bit31-24: 0x07, Size (i.e. 128MB)
> +
> +DATA 0xFFD0150C 0x00000000	# CS[1]n Size, window disabled
> +DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
> +DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
> +
> +DATA 0xFFD01494 0x00010000	#  DDR ODT Control (Low)
> +# bit3-0:  1, ODT0Rd, MODT[0] asserted during read from DRAM CS0
> +# bit19-16:1, ODT0Wr, MODT[0] asserted during write to DRAM CS0
> +
> +DATA 0xFFD01498 0x00000000	#  DDR ODT Control (High)
> +# bit1-0:  00, ODT0 controlled by ODT Control (low) register above
> +# bit3-2:  01, ODT1 active NEVER!
> +# bit31-4: zero, required
> +
> +DATA 0xFFD0149C 0x0000E40F	# CPU ODT Control
> +# bit3-0:  1, ODT0Rd, Internal ODT asserted during read from DRAM bank0
> +# bit7-4:  1, ODT0Wr, Internal ODT asserted during write to DRAM bank0
> +# bit11-10:1, DQ_ODTSel. ODT select turned on
> +
> +DATA 0xFFD01480 0x00000001	# DDR Initialization Control
> +#bit0=1, enable DDR init upon this register write
> +
> +# End of Header extension
> +DATA 0x0 0x0
> diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
> new file mode 100644
> index 0000000..9bc9940
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/netspace_v2.c
> @@ -0,0 +1,144 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
> + *
> + * Based on Kirkwood support:
> + * (C) Copyright 2009
> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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.
> + */
> +
> +#include <common.h>
> +#include <miiphy.h>
> +#include <netdev.h>
> +#include <command.h>
> +#include <asm/arch/kirkwood.h>
> +#include <asm/arch/mpp.h>
> +#include <asm/arch/gpio.h>
> +#include "netspace_v2.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_early_init_f(void)
> +{
> +	/* Gpio configuration */
> +	kw_config_gpio(NETSPACE_V2_OE_VAL_LOW, NETSPACE_V2_OE_VAL_HIGH,
> +			NETSPACE_V2_OE_LOW, NETSPACE_V2_OE_HIGH);
> +
> +	/* Multi-Purpose Pins Functionality configuration */
> +	u32 kwmpp_config[] = {
> +		MPP0_SPI_SCn,
> +		MPP1_SPI_MOSI,
> +		MPP2_SPI_SCK,
> +		MPP3_SPI_MISO,
> +		MPP4_NF_IO6,
> +		MPP5_NF_IO7,
> +		MPP6_SYSRST_OUTn,
> +		MPP7_GPO,		/* Fan speed (bit 1) */
> +		MPP8_TW_SDA,
> +		MPP9_TW_SCK,
> +		MPP10_UART0_TXD,
> +		MPP11_UART0_RXD,
> +		MPP12_GPO,		/* Red led */
> +		MPP14_GPIO,		/* USB fuse */
> +		MPP16_GPIO,		/* SATA 0 power */
> +		MPP17_GPIO,		/* SATA 1 power */
> +		MPP18_NF_IO0,
> +		MPP19_NF_IO1,
> +		MPP20_SATA1_ACTn,
> +		MPP21_SATA0_ACTn,
> +		MPP22_GPIO,		/* Fan speed (bit 0) */
> +		MPP23_GPIO,		/* Fan power */
> +		MPP24_GPIO,		/* USB mode select */
> +		MPP25_GPIO,		/* Fan rotation fail */
> +		MPP26_GPIO,		/* USB vbus-in detection */
> +		MPP28_GPIO,		/* USB enable vbus-out */
> +		MPP29_GPIO,		/* Blue led (slow register) */
> +		MPP30_GPIO,		/* Blue led (command register) */
> +		MPP31_GPIO,		/* Board power off */
> +		MPP32_GPIO,		/* Button (0 = Released, 1 = Pushed) */
> +		MPP33_GPIO,		/* Fan speed (bit 2) */
> +		0
> +	};
> +	kirkwood_mpp_conf(kwmpp_config);
> +
> +	return 0;
> +}
> +
> +int board_init(void)
> +{
> +	/* Machine number */
> +	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
> +
> +	/* Boot parameters address */
> +	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
> +
> +	return 0;
> +}
> +
> +void mv_phy_88e1116_init(char *name)
> +{
> +	u16 reg;
> +	u16 devadr;
> +
> +	if (miiphy_set_current_dev(name))
> +		return;
> +
> +	/* command to read PHY dev address */
> +	if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
> +		printf("Err..(%s) could not read PHY dev address\n", __func__);
> +		return;
> +	}
> +
> +	/*
> +	 * Enable RGMII delay on Tx and Rx for CPU port
> +	 * Ref: sec 4.7.2 of chip datasheet
> +	 */
> +	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
> +	miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, &reg);
> +	reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
> +	miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg);
> +	miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
> +
> +	/* reset the phy */
> +	if (miiphy_read(name, devadr, MII_BMCR, &reg) != 0) {
> +		printf("Err..(%s) PHY status read failed\n", __func__);
> +		return;
> +	}
> +	if (miiphy_write(name, devadr, MII_BMCR, reg | 0x8000) != 0) {
> +		printf("Err..(%s) PHY reset failed\n", __func__);
> +		return;
> +	}
> +
> +	debug("88E1116 Initialized on %s\n", name);
> +}
> +
> +/* Configure and initialize PHY */
> +void reset_phy(void)
> +{
> +	mv_phy_88e1116_init("egiga0");
> +}
> +
> +#define NETSPACE_V2_GPIO_BUTTON		32
> +
> +/* Return GPIO button status */
> +static int
> +do_read_button(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	return kw_gpio_get_value(NETSPACE_V2_GPIO_BUTTON);
> +}
> +
> +U_BOOT_CMD(button, 1, 1, do_read_button,
> +	   "Return GPIO button status 0=off 1=on", "");
> diff --git a/board/LaCie/netspace_v2/netspace_v2.h b/board/LaCie/netspace_v2/netspace_v2.h
> new file mode 100644
> index 0000000..c26a6e0
> --- /dev/null
> +++ b/board/LaCie/netspace_v2/netspace_v2.h
> @@ -0,0 +1,39 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
> + *
> + * Based on Kirkwood support:
> + * (C) Copyright 2009
> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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.
> + */
> +
> +#ifndef NETSPACE_V2_H
> +#define NETSPACE_V2_H
> +
> +#define NETSPACE_V2_OE_LOW		0x06004000
> +#define NETSPACE_V2_OE_HIGH		0x00000031
> +#define NETSPACE_V2_OE_VAL_LOW		0x10030000
> +#define NETSPACE_V2_OE_VAL_HIGH		0x00000000
> +
> +/* PHY related */
> +#define MV88E1116_LED_FCTRL_REG		10
> +#define MV88E1116_CPRSP_CR3_REG		21
> +#define MV88E1116_MAC_CTRL_REG		21
> +#define MV88E1116_PGADR_REG		22
> +#define MV88E1116_RGMII_TXTM_CTRL	(1 << 4)
> +#define MV88E1116_RGMII_RXTM_CTRL	(1 << 5)
> +
> +#endif /* NETSPACE_V2_H */
> diff --git a/boards.cfg b/boards.cfg
> index 2b0900a..459dee4 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -106,6 +106,9 @@ davinci_sonata               arm         arm926ejs   sonata              davinci
>  suen3                        arm         arm926ejs   km_arm              keymile        kirkwood
>  suen8                        arm         arm926ejs   km_arm              keymile        kirkwood
>  mgcoge2un                    arm         arm926ejs   km_arm              keymile        kirkwood
> +inetspace_v2                 arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:INETSPACE_V2
> +netspace_v2                  arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_V2
> +netspace_max_v2              arm         arm926ejs   netspace_v2         LaCie          kirkwood    netspace_v2:NETSPACE_MAX_V2
>  guruplug                     arm         arm926ejs   -                   Marvell        kirkwood
>  mv88f6281gtw_ge              arm         arm926ejs   -                   Marvell        kirkwood
>  openrd_base                  arm         arm926ejs   -                   Marvell        kirkwood
> diff --git a/include/configs/netspace_v2.h b/include/configs/netspace_v2.h
> new file mode 100644
> index 0000000..ca4db53
> --- /dev/null
> +++ b/include/configs/netspace_v2.h
> @@ -0,0 +1,149 @@
> +/*
> + * Copyright (C) 2011 Simon Guinot <sguinot@lacie.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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.
> + */
> +
> +#ifndef _CONFIG_NETSPACE_V2_H
> +#define _CONFIG_NETSPACE_V2_H
> +
> +/*
> + * Machine number definition
> + */
> +#if defined(CONFIG_INETSPACE_V2)
> +#define CONFIG_MACH_TYPE		MACH_TYPE_INETSPACE_V2
> +#define CONFIG_IDENT_STRING		" LaCie Internet Space v2"
> +#elif defined(CONFIG_NETSPACE_V2)
> +#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_V2
> +#define CONFIG_IDENT_STRING		" LaCie Network Space v2"
> +#elif defined(CONFIG_NETSPACE_MAX_V2)
> +#define CONFIG_MACH_TYPE		MACH_TYPE_NETSPACE_MAX_V2
> +#define CONFIG_IDENT_STRING		" LaCie Network Space Max v2"
> +#endif
> +
> +/*
> + * High Level Configuration Options (easy to change)
> + */
> +#define CONFIG_FEROCEON_88FR131		1 /* CPU Core subversion */
> +#define CONFIG_KIRKWOOD			1 /* SOC Family Name */
> +#define CONFIG_KW88F6281		1 /* SOC Name */
> +#define CONFIG_MACH_NETSPACE_V2		1 /* Machine type */
> +#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */
> +
> +/*
> + * Commands configuration
> + */
> +#define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
> +#include <config_cmd_default.h>
> +#define CONFIG_CMD_ENV
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_PING
> +#define CONFIG_CMD_SF
> +#define CONFIG_CMD_I2C
> +#define CONFIG_CMD_IDE
> +#define CONFIG_CMD_USB
> +
> +/*
> + * Core clock definition.
> + */
> +#define CONFIG_SYS_TCLK			166000000 /* 166MHz */
> +
> +/*
> + * mv-common.h should be defined after CMD configs since it used them
> + * to enable certain macros
> + */
> +#define CONFIG_NR_DRAM_BANKS		2
> +#include "mv-common.h"
> +
> +/* Remove or override few declarations from mv-common.h */
> +#undef CONFIG_RBTREE
> +#undef CONFIG_ENV_SPI_MAX_HZ
> +#undef CONFIG_SYS_IDE_MAXBUS
> +#undef CONFIG_SYS_IDE_MAXDEVICE
> +#undef CONFIG_SYS_PROMPT
> +#define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
> +#define CONFIG_SYS_IDE_MAXBUS           1
> +#define CONFIG_SYS_IDE_MAXDEVICE        1
> +#define CONFIG_SYS_PROMPT		"ns2> "
> +
> +/*
> + * Ethernet Driver configuration
> + */
> +#ifdef CONFIG_CMD_NET
> +#define CONFIG_MVGBE_PORTS		{1, 0} /* enable port 0 only */
> +#define CONFIG_NETCONSOLE
> +#endif
> +
> +/*
> + * SATA Driver configuration
> + */
> +#ifdef CONFIG_MVSATA_IDE
> +#define CONFIG_SYS_ATA_IDE0_OFFSET      MV_SATA_PORT0_OFFSET
> +/* Network Space Max v2 use 2 SATA ports */
> +#ifdef CONFIG_NETSPACE_MAX_V2
> +#define CONFIG_SYS_ATA_IDE1_OFFSET      MV_SATA_PORT1_OFFSET
> +#endif
> +#endif
> +
> +/*
> + * Enable GPI0 support
> + */
> +#define CONFIG_KIRKWOOD_GPIO
> +
> +/*
> + * File systems support
> + */
> +#define CONFIG_CMD_EXT2
> +#define CONFIG_CMD_FAT
> +
> +/*
> + * Use the HUSH parser
> + */
> +#define CONFIG_SYS_HUSH_PARSER
> +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
> +
> +/*
> + * Console configuration
> + */
> +#define CONFIG_CONSOLE_MUX		1
> +#define CONFIG_SYS_CONSOLE_IS_IN_ENV	1
> +
> +/*
> + * Environment variables configurations
> + */
> +#define CONFIG_ENV_IS_IN_SPI_FLASH	1
> +#define CONFIG_ENV_SECT_SIZE		0x10000	/* 64KB */
> +#define CONFIG_ENV_SIZE			0x1000	/* 4KB */
> +#define CONFIG_ENV_ADDR			0x70000
> +#define CONFIG_ENV_OFFSET		0x70000	/* env starts here */
> +
> +/*
> + * Default environment variables
> + */
> +#define CONFIG_BOOTARGS "console=ttyS0,115200"
> +
> +#define CONFIG_BOOTCOMMAND				\
> +	"if run usbload || run diskload; then bootm 0x800000; fi"
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS			\
> +	"stdin=serial,nc\0"				\
> +	"stdout=serial,nc\0"				\
> +	"stderr=serial,nc\0"				\
> +	"ipaddr=192.168.1.111\0"			\
> +	"diskload=ide reset && "			\
> +	"ext2load ide 0:1 0x800000 /boot/uImage\0"	\
> +	"usbload=usb start && "				\
> +	"fatload usb 0:1 0x800000 /boot/uImage\0"
> +
> +#endif /* _CONFIG_NETSPACE_V2_H */
> -- 
> 1.6.3.1
> 

> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110503/9fab2f64/attachment.pgp 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v5 5/5] Add support for Network Space v2
  2011-05-03 13:19   ` Simon Guinot
@ 2011-05-12 17:24     ` Wolfgang Denk
  0 siblings, 0 replies; 716+ messages in thread
From: Wolfgang Denk @ 2011-05-12 17:24 UTC (permalink / raw)
  To: u-boot

Dear Simon Guinot,

In message <20110503131942.GU19806@kw.sim.vm.gnt> you wrote:
> 
> I have failed to find an entry for this patch in the U-Boot patchwork
> (and any previous version except the very first).

I don't see it either.

> Have I missed something and/or done something wrong ?

Unlikely. Can you please ask Jeremy Kerr on the patchwork mailing
list?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
God may be subtle, but He isn't plain mean.         - Albert Einstein

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 2/3] ARM: pxa168: Add support for Ethernet
  2011-05-02  5:59 ` [PATCH 2/3] ARM: pxa168: Add support for Ethernet Tanmay Upadhyay
@ 2011-06-10 13:31   ` Eric Miao
  0 siblings, 0 replies; 716+ messages in thread
From: Eric Miao @ 2011-06-10 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 2, 2011 at 1:59 PM, Tanmay Upadhyay
<tanmay.upadhyay@einfochips.com> wrote:
> Add wrapper that creates resources for PXA168 Ethernet driver
>
> Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>

Applied to 'devel'

> ---
> ?arch/arm/mach-mmp/include/mach/mfp-pxa168.h | ? 19 +++++++++++++++++++
> ?arch/arm/mach-mmp/include/mach/pxa168.h ? ? | ? ?6 ++++++
> ?arch/arm/mach-mmp/include/mach/regs-apmu.h ?| ? ?1 +
> ?arch/arm/mach-mmp/pxa168.c ? ? ? ? ? ? ? ? ?| ? ?3 +++
> ?4 files changed, 29 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
> index 713be15..8c78232 100644
> --- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
> +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
> @@ -305,4 +305,23 @@
> ?#define GPIO112_KP_MKOUT6 ? ? ? MFP_CFG(GPIO112, AF7)
> ?#define GPIO121_KP_MKIN4 ? ? ? ?MFP_CFG(GPIO121, AF7)
>
> +/* Fast Ethernet */
> +#define GPIO86_TX_CLK ? ? ? ? ?MFP_CFG(GPIO86, AF5)
> +#define GPIO87_TX_EN ? ? ? ? ? MFP_CFG(GPIO87, AF5)
> +#define GPIO88_TX_DQ3 ? ? ? ? ?MFP_CFG(GPIO88, AF5)
> +#define GPIO89_TX_DQ2 ? ? ? ? ?MFP_CFG(GPIO89, AF5)
> +#define GPIO90_TX_DQ1 ? ? ? ? ?MFP_CFG(GPIO90, AF5)
> +#define GPIO91_TX_DQ0 ? ? ? ? ?MFP_CFG(GPIO91, AF5)
> +#define GPIO92_MII_CRS ? ? ? ? MFP_CFG(GPIO92, AF5)
> +#define GPIO93_MII_COL ? ? ? ? MFP_CFG(GPIO93, AF5)
> +#define GPIO94_RX_CLK ? ? ? ? ?MFP_CFG(GPIO94, AF5)
> +#define GPIO95_RX_ER ? ? ? ? ? MFP_CFG(GPIO95, AF5)
> +#define GPIO96_RX_DQ3 ? ? ? ? ?MFP_CFG(GPIO96, AF5)
> +#define GPIO97_RX_DQ2 ? ? ? ? ?MFP_CFG(GPIO97, AF5)
> +#define GPIO98_RX_DQ1 ? ? ? ? ?MFP_CFG(GPIO98, AF5)
> +#define GPIO99_RX_DQ0 ? ? ? ? ?MFP_CFG(GPIO99, AF5)
> +#define GPIO100_MII_MDC ? ? ? ? ? ? ? ?MFP_CFG(GPIO100, AF5)
> +#define GPIO101_MII_MDIO ? ? ? MFP_CFG(GPIO101, AF5)
> +#define GPIO103_RX_DV ? ? ? ? ?MFP_CFG(GPIO103, AF5)
> +
> ?#endif /* __ASM_MACH_MFP_PXA168_H */
> diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
> index 705e963..7f00584 100644
> --- a/arch/arm/mach-mmp/include/mach/pxa168.h
> +++ b/arch/arm/mach-mmp/include/mach/pxa168.h
> @@ -14,6 +14,7 @@ extern void pxa168_clear_keypad_wakeup(void);
> ?#include <video/pxa168fb.h>
> ?#include <plat/pxa27x_keypad.h>
> ?#include <mach/cputype.h>
> +#include <linux/pxa168_eth.h>
>
> ?extern struct pxa_device_desc pxa168_device_uart1;
> ?extern struct pxa_device_desc pxa168_device_uart2;
> @@ -32,6 +33,7 @@ extern struct pxa_device_desc pxa168_device_ssp5;
> ?extern struct pxa_device_desc pxa168_device_nand;
> ?extern struct pxa_device_desc pxa168_device_fb;
> ?extern struct pxa_device_desc pxa168_device_keypad;
> +extern struct pxa_device_desc pxa168_device_eth;
>
> ?static inline int pxa168_add_uart(int id)
> ?{
> @@ -119,4 +121,8 @@ static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
> ? ? ? ?return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
> ?}
>
> +static inline int pxa168_add_eth(struct pxa168_eth_platform_data *data)
> +{
> + ? ? ? return pxa_register_device(&pxa168_device_eth, data, sizeof(*data));
> +}
> ?#endif /* __ASM_MACH_PXA168_H */
> diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
> index f7011ef..8447ac6 100644
> --- a/arch/arm/mach-mmp/include/mach/regs-apmu.h
> +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
> @@ -29,6 +29,7 @@
> ?#define APMU_BUS ? ? ? APMU_REG(0x06c)
> ?#define APMU_SDH2 ? ? ?APMU_REG(0x0e8)
> ?#define APMU_SDH3 ? ? ?APMU_REG(0x0ec)
> +#define APMU_ETH ? ? ? APMU_REG(0x0fc)
>
> ?#define APMU_FNCLK_EN ?(1 << 4)
> ?#define APMU_AXICLK_EN (1 << 3)
> diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
> index dcb203b..96d451d 100644
> --- a/arch/arm/mach-mmp/pxa168.c
> +++ b/arch/arm/mach-mmp/pxa168.c
> @@ -82,6 +82,7 @@ static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
>
> ?static APMU_CLK(nand, NAND, 0x01db, 208000000);
> ?static APMU_CLK(lcd, LCD, 0x7f, 312000000);
> +static APMU_CLK(eth, ETH, 0x09, 0);
>
> ?/* device and clock bindings */
> ?static struct clk_lookup pxa168_clkregs[] = {
> @@ -102,6 +103,7 @@ static struct clk_lookup pxa168_clkregs[] = {
> ? ? ? ?INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
> ? ? ? ?INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
> ? ? ? ?INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
> + ? ? ? INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
> ?};
>
> ?static int __init pxa168_init(void)
> @@ -166,3 +168,4 @@ PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
> ?PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
> ?PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
> ?PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
> +PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff);
> --
> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] Add ok2440 development board support.
       [not found] <yes>
@ 2011-06-15  0:46   ` Wu DaoGuang
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Wu DaoGuang @ 2011-06-15  0:46 UTC (permalink / raw)
  To: linux, ben-linux, wdgvip; +Cc: linux-arm-kernel, linux-kernel

This patch has been modified for the second time .Reduced the size
of the file ok2440_defconfig and updated to the latest APIs.

The ok2440 development board is based on SAMSUNG's S3C2440
microprocessor,which is developed with ARM920T core.

Thanks to Vasily Khoruzhick <anarsoul@gmail.com> for detailed
proposal in this patch.

This patch is against v3.0-rc3.

Signed-off-by: Wu DaoGuang <wdgvip@gmail.com>
---
 arch/arm/configs/ok2440_defconfig   |  384 +++++++++++++++++++++++++++++
 arch/arm/mach-s3c2440/Kconfig       |   10 +
 arch/arm/mach-s3c2440/Makefile      |    1 +
 arch/arm/mach-s3c2440/mach-ok2440.c |  457 +++++++++++++++++++++++++++++++++++
 4 files changed, 852 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/ok2440_defconfig
 create mode 100644 arch/arm/mach-s3c2440/mach-ok2440.c

diff --git a/arch/arm/configs/ok2440_defconfig b/arch/arm/configs/ok2440_defconfig
new file mode 100644
index 0000000..45f2c86
--- /dev/null
+++ b/arch/arm/configs/ok2440_defconfig
@@ -0,0 +1,384 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_RELAY=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_ARCH_S3C2410=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_MACH_OK2440=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_KEXEC=y
+CONFIG_CPU_IDLE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_PKTGEN=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=y
+CONFIG_RFD_FTL=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_S3C2410=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_LPDDR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_ZD1211RW=m
+CONFIG_ZD1211RW_DEBUG=y
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIO_RAW=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=128
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SIMTEC=y
+CONFIG_SPI=y
+CONFIG_SPI_S3C24XX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM75=y
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S3C2410=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_DISPLAY_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_S3C24XX_SOC=y
+CONFIG_HIDRAW=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_S3C2410=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_S3C=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_S3C24XX=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_DMADEVICES=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BOTH=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 50825a3..1214909 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -176,6 +176,16 @@ config MACH_AT2440EVB
 	help
 	  Say Y here if you are using the AT2440EVB development board
 
+config MACH_OK2440
+	bool "OK2440 development board"
+	select CPU_S3C2440
+	select S3C2440_XTAL_12000000
+	select S3C_DEV_NAND
+	select S3C_DEV_USB_HOST
+	help
+	  Say y here to select support for OK2440. Now it is widely used for
+	  many students and Companies.
+
 config MACH_MINI2440
 	bool "MINI2440 development board"
 	select CPU_S3C2440
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index d5440fa..da4ad71 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
 obj-$(CONFIG_MACH_OSIRIS)	+= mach-osiris.o
 obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
 obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
+obj-$(CONFIG_MACH_OK2440)	+= mach-ok2440.o
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
diff --git a/arch/arm/mach-s3c2440/mach-ok2440.c b/arch/arm/mach-s3c2440/mach-ok2440.c
new file mode 100644
index 0000000..43700e8
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-ok2440.c
@@ -0,0 +1,457 @@
+/* linux/arch/arm/mach-s3c2440/mach-ok2440.c
+ *
+ *	Copyright (c) 2011  Feiling Embedded
+ *	Base on mach-smdk2440.c by Ben Dooks <ben@simtec.co.uk>
+ *
+ *	Wu DaoGuang <wdgvip@gmail.com>
+ *
+ * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/dm9000.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mmc/host.h>
+#include <linux/memblock.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+
+#include <linux/leds.h>
+#include <linux/pwm.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/udc.h>
+#include <plat/mci.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-mem.h>
+#include <mach/irqs.h>
+
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/gpio-cfg.h>
+#include <plat/usb-control.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/common-smdk.h>
+#include <sound/s3c24xx_uda134x.h>
+
+#define MACH_OK2440_DM9K_BASE (S3C2410_CS4 + 0x300)
+
+static struct map_desc ok2440_iodesc[] __initdata = {
+	/* ISA IO Space map (memory space selected by A24) */
+
+	{
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}
+};
+
+#define UCON	(S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON	(S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON	(S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg ok2440_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	/* IR port */
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x43,
+		.ufcon	     = 0x51,
+	}
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display ok2440_lcd_cfg __initdata = {
+
+	.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+			  S3C2410_LCDCON5_INVVLINE |
+			  S3C2410_LCDCON5_INVVFRAME |
+			  S3C2410_LCDCON5_PWREN |
+			  S3C2410_LCDCON5_HWSWP,
+
+	.type		= S3C2410_LCDCON1_TFT,
+
+	.width		= 320,
+	.height		= 240,
+
+	.pixclock	= 270000, /* HCLK 60 MHz, divisor 10 */
+	.xres		= 320,
+	.yres		= 240,
+	.bpp		= 16,
+	.left_margin	= 8,
+	.right_margin	= 5,
+	.hsync_len	= 16,
+	.upper_margin	= 8,
+	.lower_margin	= 5,
+	.vsync_len	= 2,
+};
+
+static struct s3c2410fb_mach_info ok2440_fb_info __initdata = {
+	.displays	= &ok2440_lcd_cfg,
+	.num_displays	= 1,
+	.default_display = 0,
+	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+};
+
+/* Nand flash partitions on ok2440 */
+static struct mtd_partition ok2440_default_nand_part[] = {
+	[0] = {
+		.name	= "u-boot",
+		.size	= SZ_1M,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "App",
+		.size	= SZ_2M,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[2] = {
+		.name	= "Kernel",
+		.size	= SZ_1M*4,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[3] = {
+		.name	= "Ramdisk",
+		.size	= SZ_16M,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[3] = {
+		.name	= "Rootfs",
+		.size	= MTDPART_SIZ_FULL,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+};
+static struct s3c2410_nand_set ok2440_nand_sets[] = {
+	[0] = {
+		.name		= "nand",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(ok2440_default_nand_part),
+		.partitions	= ok2440_default_nand_part,
+		.flash_bbt	= 1, /* We use u-boot to creat a BBT*/
+	}
+};
+
+static struct s3c2410_platform_nand ok2440_nand_info __initdata = {
+	.tacls		= 20,
+	.twrph0		= 60,
+	.twrph1		= 20,
+	.nr_sets	= ARRAY_SIZE(ok2440_nand_sets),
+	.sets		= ok2440_nand_sets,
+	.ignore_unset_ecc = 1,
+};
+
+
+/* DM9000AEP 10/100 ethernet controller */
+static struct resource ok2440_dm9k_resource[] = {
+	[0] = {
+		.start = MACH_OK2440_DM9K_BASE,
+		.end   = MACH_OK2440_DM9K_BASE + 3,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = MACH_OK2440_DM9K_BASE + 4,
+		.end   = MACH_OK2440_DM9K_BASE + 7,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = IRQ_EINT7,
+		.end   = IRQ_EINT7,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+/* The DM9000 has no eeprom ,and it's MAC address is set by
+ * the bootloader before starting the kernel.
+ */
+static struct dm9000_plat_data ok2440_dm9k_pdata = {
+	.flags		= (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+static struct platform_device ok2440_device_eth = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ok2440_dm9k_resource),
+	.resource	= ok2440_dm9k_resource,
+	.dev		= {
+		.platform_data	= &ok2440_dm9k_pdata,
+	},
+};
+
+/* LEDS sourport */
+static struct gpio_led ok2440_leds_desc[] = {
+	{
+		.name			= "led0",
+		.default_trigger	= "heartbeat",
+		.gpio			= S3C2410_GPF(3),
+	},
+	{
+		.name			= "led1",
+		.default_trigger	= "nand-disk",
+		.gpio			= S3C2410_GPF(4),
+	},
+	{
+		.name			= "led2",
+		.default_trigger	= "mmc",
+		.gpio			= S3C2410_GPF(5),
+	},
+	{
+		.name			= "led3",
+		.default_trigger	= "network",
+		.gpio			= S3C2410_GPF(6),
+	},
+};
+
+static struct gpio_led_platform_data ok2440_leds_pdata = {
+	.num_leds	= ARRAY_SIZE(ok2440_leds_desc),
+	.leds		= ok2440_leds_desc,
+};
+
+static struct platform_device ok2440_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &ok2440_leds_pdata,
+	},
+};
+/* GPIO KEYS */
+static struct gpio_keys_button ok2440_gpio_keys_table[] = {
+	{
+		.code		= KEY_LEFT,
+		.gpio		= S3C2410_GPF(0),
+		.active_low	= 1,
+		.desc		= "Left button",
+	},
+	{
+		.code		= KEY_RIGHT,
+		.gpio		= S3C2410_GPF(2),
+		.active_low	= 1,
+		.desc		= "Right button",
+	},
+	{
+		.code		= KEY_UP,
+		.gpio		= S3C2410_GPB(5),
+		.active_low	= 1,
+		.desc		= "Up button",
+	},
+	{
+		.code		= KEY_DOWN,
+		.gpio		= S3C2410_GPB(6),
+		.active_low	= 1,
+		.desc		= "Down button",
+	},
+	{
+		.code		= KEY_ENTER,
+		.gpio		= S3C2410_GPB(7),
+		.active_low	= 1,
+		.desc		= "Ok button",
+	},
+
+};
+static struct gpio_keys_platform_data ok2440_gpio_keys_pdata = {
+	.buttons	= ok2440_gpio_keys_table,
+	.nbuttons	= ARRAY_SIZE(ok2440_gpio_keys_table),
+};
+static struct platform_device ok2440_device_gpiokeys = {
+	.name			= "gpio-keys",
+	.dev.platform_data	= &ok2440_gpio_keys_pdata,
+};
+/* AUDIO */
+static struct s3c24xx_uda134x_platform_data ok2440_audio_pins = {
+	.l3_clk = S3C2410_GPB(4),
+	.l3_mode = S3C2410_GPB(2),
+	.l3_data = S3C2410_GPB(3),
+	.model   = UDA134X_UDA1341
+};
+
+static struct platform_device ok2440_audio = {
+	.name		= "s3c24xx_uda134x",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &ok2440_audio_pins,
+	}
+};
+
+static struct platform_device uda1340_codec = {
+	.name = "uda134x-codec",
+	.id   = -1,
+};
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c08 = {
+	.byte_len	= SZ_8K / 8,
+	.page_size	= 16,
+};
+
+static struct i2c_board_info ok2440_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("24c08", 0x50),
+		.platform_data	= &at24c08,
+	},
+};
+
+/*  USB device UDC support */
+static struct s3c2410_udc_mach_info ok2440_udc_cfg __initdata = {
+	.pullup_pin = S3C2410_GPG(9),
+};
+
+/* USB */
+static struct s3c2410_hcd_info ok2440_usb_info __initdata = {
+	.port[0]	= {
+		.flags	= S3C_HCDFLG_USED,
+	},
+	.port[1]	= {
+		.flags	= 0,
+	},
+};
+
+/* MMC/SD */
+static struct s3c24xx_mci_pdata ok2440_mmc_cfg __initdata = {
+	.gpio_detect	= S3C2410_GPG(10),
+	.gpio_wprotect	= S3C2410_GPH(8),
+	.set_power	= NULL,
+	.ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
+
+static struct platform_device *ok2440_devices[] __initdata = {
+	&s3c_device_ohci,
+	&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c0,
+	&s3c_device_iis,
+	&s3c_device_sdi,
+	&s3c_device_nand,
+	&s3c_device_rtc,
+	&s3c_device_usbgadget,
+	&ok2440_device_gpiokeys,
+	&uda1340_codec,
+	&ok2440_device_eth,
+	&ok2440_audio,
+	&ok2440_leds,
+	&samsung_asoc_dma,
+
+};
+
+static void __init ok2440_map_io(void)
+{
+	s3c24xx_init_io(ok2440_iodesc, ARRAY_SIZE(ok2440_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(ok2440_uartcfgs, ARRAY_SIZE(ok2440_uartcfgs));
+}
+
+static void __init ok2440_machine_init(void)
+{
+	/*configure the mmc protect to pull high . */
+	WARN_ON(gpio_request(S3C2410_GPG(8), "mmc pull up"));
+	gpio_direction_output(S3C2410_GPG(8), 1);
+	s3c24xx_fb_set_platdata(&ok2440_fb_info);
+	s3c_i2c0_set_platdata(NULL);
+
+	s3c_ohci_set_platdata(&ok2440_usb_info);
+
+	s3c_nand_set_platdata(&ok2440_nand_info);
+	s3c24xx_udc_set_platdata(&ok2440_udc_cfg);
+	s3c24xx_mci_set_platdata(&ok2440_mmc_cfg);
+	i2c_register_board_info(0, ok2440_i2c_devs,
+				ARRAY_SIZE(ok2440_i2c_devs));
+
+	platform_add_devices(ok2440_devices, ARRAY_SIZE(ok2440_devices));
+	s3c_pm_init();
+}
+
+MACHINE_START(S3C2440, "OK2440 development board.")
+	/* Maintainer: Wu DaoGuang <wdgvip@gmail.com> */
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= ok2440_map_io,
+	.init_machine	= ok2440_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH] Add ok2440 development board support.
@ 2011-06-15  0:46   ` Wu DaoGuang
  0 siblings, 0 replies; 716+ messages in thread
From: Wu DaoGuang @ 2011-06-15  0:46 UTC (permalink / raw)
  To: linux-arm-kernel

This patch has been modified for the second time .Reduced the size
of the file ok2440_defconfig and updated to the latest APIs.

The ok2440 development board is based on SAMSUNG's S3C2440
microprocessor,which is developed with ARM920T core.

Thanks to Vasily Khoruzhick <anarsoul@gmail.com> for detailed
proposal in this patch.

This patch is against v3.0-rc3.

Signed-off-by: Wu DaoGuang <wdgvip@gmail.com>
---
 arch/arm/configs/ok2440_defconfig   |  384 +++++++++++++++++++++++++++++
 arch/arm/mach-s3c2440/Kconfig       |   10 +
 arch/arm/mach-s3c2440/Makefile      |    1 +
 arch/arm/mach-s3c2440/mach-ok2440.c |  457 +++++++++++++++++++++++++++++++++++
 4 files changed, 852 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/ok2440_defconfig
 create mode 100644 arch/arm/mach-s3c2440/mach-ok2440.c

diff --git a/arch/arm/configs/ok2440_defconfig b/arch/arm/configs/ok2440_defconfig
new file mode 100644
index 0000000..45f2c86
--- /dev/null
+++ b/arch/arm/configs/ok2440_defconfig
@@ -0,0 +1,384 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_RELAY=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_ARCH_S3C2410=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_MACH_OK2440=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_KEXEC=y
+CONFIG_CPU_IDLE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_PKTGEN=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=y
+CONFIG_RFD_FTL=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_S3C2410=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_LPDDR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_ZD1211RW=m
+CONFIG_ZD1211RW_DEBUG=y
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIO_RAW=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=128
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SIMTEC=y
+CONFIG_SPI=y
+CONFIG_SPI_S3C24XX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM75=y
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S3C2410=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_DISPLAY_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_S3C24XX_SOC=y
+CONFIG_HIDRAW=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_S3C2410=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_S3C=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_S3C24XX=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_DMADEVICES=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BOTH=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 50825a3..1214909 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -176,6 +176,16 @@ config MACH_AT2440EVB
 	help
 	  Say Y here if you are using the AT2440EVB development board
 
+config MACH_OK2440
+	bool "OK2440 development board"
+	select CPU_S3C2440
+	select S3C2440_XTAL_12000000
+	select S3C_DEV_NAND
+	select S3C_DEV_USB_HOST
+	help
+	  Say y here to select support for OK2440. Now it is widely used for
+	  many students and Companies.
+
 config MACH_MINI2440
 	bool "MINI2440 development board"
 	select CPU_S3C2440
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
index d5440fa..da4ad71 100644
--- a/arch/arm/mach-s3c2440/Makefile
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
 obj-$(CONFIG_MACH_OSIRIS)	+= mach-osiris.o
 obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
 obj-$(CONFIG_ARCH_S3C2440)	+= mach-smdk2440.o
+obj-$(CONFIG_MACH_OK2440)	+= mach-ok2440.o
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
diff --git a/arch/arm/mach-s3c2440/mach-ok2440.c b/arch/arm/mach-s3c2440/mach-ok2440.c
new file mode 100644
index 0000000..43700e8
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-ok2440.c
@@ -0,0 +1,457 @@
+/* linux/arch/arm/mach-s3c2440/mach-ok2440.c
+ *
+ *	Copyright (c) 2011  Feiling Embedded
+ *	Base on mach-smdk2440.c by Ben Dooks <ben@simtec.co.uk>
+ *
+ *	Wu DaoGuang <wdgvip@gmail.com>
+ *
+ * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/dm9000.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mmc/host.h>
+#include <linux/memblock.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+
+#include <linux/leds.h>
+#include <linux/pwm.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/udc.h>
+#include <plat/mci.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-mem.h>
+#include <mach/irqs.h>
+
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/gpio-cfg.h>
+#include <plat/usb-control.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/common-smdk.h>
+#include <sound/s3c24xx_uda134x.h>
+
+#define MACH_OK2440_DM9K_BASE (S3C2410_CS4 + 0x300)
+
+static struct map_desc ok2440_iodesc[] __initdata = {
+	/* ISA IO Space map (memory space selected by A24) */
+
+	{
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE,
+		.pfn		= __phys_to_pfn(S3C2410_CS2),
+		.length		= 0x10000,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+		.pfn		= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+		.length		= SZ_4M,
+		.type		= MT_DEVICE,
+	}
+};
+
+#define UCON	(S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON	(S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON	(S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg ok2440_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	/* IR port */
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x43,
+		.ufcon	     = 0x51,
+	}
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display ok2440_lcd_cfg __initdata = {
+
+	.lcdcon5	= S3C2410_LCDCON5_FRM565 |
+			  S3C2410_LCDCON5_INVVLINE |
+			  S3C2410_LCDCON5_INVVFRAME |
+			  S3C2410_LCDCON5_PWREN |
+			  S3C2410_LCDCON5_HWSWP,
+
+	.type		= S3C2410_LCDCON1_TFT,
+
+	.width		= 320,
+	.height		= 240,
+
+	.pixclock	= 270000, /* HCLK 60 MHz, divisor 10 */
+	.xres		= 320,
+	.yres		= 240,
+	.bpp		= 16,
+	.left_margin	= 8,
+	.right_margin	= 5,
+	.hsync_len	= 16,
+	.upper_margin	= 8,
+	.lower_margin	= 5,
+	.vsync_len	= 2,
+};
+
+static struct s3c2410fb_mach_info ok2440_fb_info __initdata = {
+	.displays	= &ok2440_lcd_cfg,
+	.num_displays	= 1,
+	.default_display = 0,
+	.lpcsel		= ((0xCE6) & ~7) | 1<<4,
+};
+
+/* Nand flash partitions on ok2440 */
+static struct mtd_partition ok2440_default_nand_part[] = {
+	[0] = {
+		.name	= "u-boot",
+		.size	= SZ_1M,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "App",
+		.size	= SZ_2M,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[2] = {
+		.name	= "Kernel",
+		.size	= SZ_1M*4,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[3] = {
+		.name	= "Ramdisk",
+		.size	= SZ_16M,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+	[3] = {
+		.name	= "Rootfs",
+		.size	= MTDPART_SIZ_FULL,
+		.offset	= MTDPART_OFS_APPEND,
+	},
+};
+static struct s3c2410_nand_set ok2440_nand_sets[] = {
+	[0] = {
+		.name		= "nand",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(ok2440_default_nand_part),
+		.partitions	= ok2440_default_nand_part,
+		.flash_bbt	= 1, /* We use u-boot to creat a BBT*/
+	}
+};
+
+static struct s3c2410_platform_nand ok2440_nand_info __initdata = {
+	.tacls		= 20,
+	.twrph0		= 60,
+	.twrph1		= 20,
+	.nr_sets	= ARRAY_SIZE(ok2440_nand_sets),
+	.sets		= ok2440_nand_sets,
+	.ignore_unset_ecc = 1,
+};
+
+
+/* DM9000AEP 10/100 ethernet controller */
+static struct resource ok2440_dm9k_resource[] = {
+	[0] = {
+		.start = MACH_OK2440_DM9K_BASE,
+		.end   = MACH_OK2440_DM9K_BASE + 3,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = MACH_OK2440_DM9K_BASE + 4,
+		.end   = MACH_OK2440_DM9K_BASE + 7,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = IRQ_EINT7,
+		.end   = IRQ_EINT7,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+	}
+};
+/* The DM9000 has no eeprom ,and it's MAC address is set by
+ * the bootloader before starting the kernel.
+ */
+static struct dm9000_plat_data ok2440_dm9k_pdata = {
+	.flags		= (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+static struct platform_device ok2440_device_eth = {
+	.name		= "dm9000",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ok2440_dm9k_resource),
+	.resource	= ok2440_dm9k_resource,
+	.dev		= {
+		.platform_data	= &ok2440_dm9k_pdata,
+	},
+};
+
+/* LEDS sourport */
+static struct gpio_led ok2440_leds_desc[] = {
+	{
+		.name			= "led0",
+		.default_trigger	= "heartbeat",
+		.gpio			= S3C2410_GPF(3),
+	},
+	{
+		.name			= "led1",
+		.default_trigger	= "nand-disk",
+		.gpio			= S3C2410_GPF(4),
+	},
+	{
+		.name			= "led2",
+		.default_trigger	= "mmc",
+		.gpio			= S3C2410_GPF(5),
+	},
+	{
+		.name			= "led3",
+		.default_trigger	= "network",
+		.gpio			= S3C2410_GPF(6),
+	},
+};
+
+static struct gpio_led_platform_data ok2440_leds_pdata = {
+	.num_leds	= ARRAY_SIZE(ok2440_leds_desc),
+	.leds		= ok2440_leds_desc,
+};
+
+static struct platform_device ok2440_leds = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &ok2440_leds_pdata,
+	},
+};
+/* GPIO KEYS */
+static struct gpio_keys_button ok2440_gpio_keys_table[] = {
+	{
+		.code		= KEY_LEFT,
+		.gpio		= S3C2410_GPF(0),
+		.active_low	= 1,
+		.desc		= "Left button",
+	},
+	{
+		.code		= KEY_RIGHT,
+		.gpio		= S3C2410_GPF(2),
+		.active_low	= 1,
+		.desc		= "Right button",
+	},
+	{
+		.code		= KEY_UP,
+		.gpio		= S3C2410_GPB(5),
+		.active_low	= 1,
+		.desc		= "Up button",
+	},
+	{
+		.code		= KEY_DOWN,
+		.gpio		= S3C2410_GPB(6),
+		.active_low	= 1,
+		.desc		= "Down button",
+	},
+	{
+		.code		= KEY_ENTER,
+		.gpio		= S3C2410_GPB(7),
+		.active_low	= 1,
+		.desc		= "Ok button",
+	},
+
+};
+static struct gpio_keys_platform_data ok2440_gpio_keys_pdata = {
+	.buttons	= ok2440_gpio_keys_table,
+	.nbuttons	= ARRAY_SIZE(ok2440_gpio_keys_table),
+};
+static struct platform_device ok2440_device_gpiokeys = {
+	.name			= "gpio-keys",
+	.dev.platform_data	= &ok2440_gpio_keys_pdata,
+};
+/* AUDIO */
+static struct s3c24xx_uda134x_platform_data ok2440_audio_pins = {
+	.l3_clk = S3C2410_GPB(4),
+	.l3_mode = S3C2410_GPB(2),
+	.l3_data = S3C2410_GPB(3),
+	.model   = UDA134X_UDA1341
+};
+
+static struct platform_device ok2440_audio = {
+	.name		= "s3c24xx_uda134x",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &ok2440_audio_pins,
+	}
+};
+
+static struct platform_device uda1340_codec = {
+	.name = "uda134x-codec",
+	.id   = -1,
+};
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c08 = {
+	.byte_len	= SZ_8K / 8,
+	.page_size	= 16,
+};
+
+static struct i2c_board_info ok2440_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("24c08", 0x50),
+		.platform_data	= &at24c08,
+	},
+};
+
+/*  USB device UDC support */
+static struct s3c2410_udc_mach_info ok2440_udc_cfg __initdata = {
+	.pullup_pin = S3C2410_GPG(9),
+};
+
+/* USB */
+static struct s3c2410_hcd_info ok2440_usb_info __initdata = {
+	.port[0]	= {
+		.flags	= S3C_HCDFLG_USED,
+	},
+	.port[1]	= {
+		.flags	= 0,
+	},
+};
+
+/* MMC/SD */
+static struct s3c24xx_mci_pdata ok2440_mmc_cfg __initdata = {
+	.gpio_detect	= S3C2410_GPG(10),
+	.gpio_wprotect	= S3C2410_GPH(8),
+	.set_power	= NULL,
+	.ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
+
+static struct platform_device *ok2440_devices[] __initdata = {
+	&s3c_device_ohci,
+	&s3c_device_lcd,
+	&s3c_device_wdt,
+	&s3c_device_i2c0,
+	&s3c_device_iis,
+	&s3c_device_sdi,
+	&s3c_device_nand,
+	&s3c_device_rtc,
+	&s3c_device_usbgadget,
+	&ok2440_device_gpiokeys,
+	&uda1340_codec,
+	&ok2440_device_eth,
+	&ok2440_audio,
+	&ok2440_leds,
+	&samsung_asoc_dma,
+
+};
+
+static void __init ok2440_map_io(void)
+{
+	s3c24xx_init_io(ok2440_iodesc, ARRAY_SIZE(ok2440_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(ok2440_uartcfgs, ARRAY_SIZE(ok2440_uartcfgs));
+}
+
+static void __init ok2440_machine_init(void)
+{
+	/*configure the mmc protect to pull high . */
+	WARN_ON(gpio_request(S3C2410_GPG(8), "mmc pull up"));
+	gpio_direction_output(S3C2410_GPG(8), 1);
+	s3c24xx_fb_set_platdata(&ok2440_fb_info);
+	s3c_i2c0_set_platdata(NULL);
+
+	s3c_ohci_set_platdata(&ok2440_usb_info);
+
+	s3c_nand_set_platdata(&ok2440_nand_info);
+	s3c24xx_udc_set_platdata(&ok2440_udc_cfg);
+	s3c24xx_mci_set_platdata(&ok2440_mmc_cfg);
+	i2c_register_board_info(0, ok2440_i2c_devs,
+				ARRAY_SIZE(ok2440_i2c_devs));
+
+	platform_add_devices(ok2440_devices, ARRAY_SIZE(ok2440_devices));
+	s3c_pm_init();
+}
+
+MACHINE_START(S3C2440, "OK2440 development board.")
+	/* Maintainer: Wu DaoGuang <wdgvip@gmail.com> */
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+
+	.init_irq	= s3c24xx_init_irq,
+	.map_io		= ok2440_map_io,
+	.init_machine	= ok2440_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/3] ARM: pxa168: Add board support for gplugD
  2011-05-02  6:00 ` [PATCH 3/3] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
@ 2011-06-20  5:55   ` Eric Miao
  0 siblings, 0 replies; 716+ messages in thread
From: Eric Miao @ 2011-06-20  5:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 2, 2011 at 2:00 PM, Tanmay Upadhyay
<tanmay.upadhyay@einfochips.com> wrote:
> Tested UART console, Ethernet & I2C interfaces
>
> Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
> ---
> ?arch/arm/mach-mmp/Kconfig ? ? ? ? ? ? ? ? ? | ? ?7 +
> ?arch/arm/mach-mmp/Makefile ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/mach-mmp/gplugd.c ? ? ? ? ? ? ? ? ?| ?189 +++++++++++++++++++++++++++
> ?arch/arm/mach-mmp/include/mach/mfp-gplugd.h | ? 52 ++++++++

I'm good to the patch. Yet if the definitions in mfp-gplugd.h is not that
gplugd _specific_, please move them into mfp-pxa168.c so other pxa168
platforms can benefit, if they are indeed gplugd specific, just incorporate
the differences into gplugd.c when defining those pins.


> ?4 files changed, 249 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/mach-mmp/gplugd.c
> ?create mode 100644 arch/arm/mach-mmp/include/mach/mfp-gplugd.h
>
> diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
> index 67793a6..56ef5f6 100644
> --- a/arch/arm/mach-mmp/Kconfig
> +++ b/arch/arm/mach-mmp/Kconfig
> @@ -77,6 +77,13 @@ config MACH_TETON_BGA
> ? ? ? ? ?Say 'Y' here if you want to support the Marvell PXA168-based
> ? ? ? ? ?Teton BGA Development Board.
>
> +config MACH_SHEEVAD
> + ? ? ? bool "Marvell's PXA168 GuruPlug Display (gplugD) Board"
> + ? ? ? select CPU_PXA168
> + ? ? ? help
> + ? ? ? ? Say 'Y' here if you want to support the Marvell PXA168-based
> + ? ? ? ? GuruPlug Display (gplugD) Board
> +
> ?endmenu
>
> ?config CPU_PXA168
> diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
> index 5c68382..b0ac942 100644
> --- a/arch/arm/mach-mmp/Makefile
> +++ b/arch/arm/mach-mmp/Makefile
> @@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o
> ?obj-$(CONFIG_MACH_FLINT) ? ? ? += flint.o
> ?obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
> ?obj-$(CONFIG_MACH_TETON_BGA) ? += teton_bga.o
> +obj-$(CONFIG_MACH_SHEEVAD) ? ? += gplugd.o
> diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
> new file mode 100644
> index 0000000..c070c24
> --- /dev/null
> +++ b/arch/arm/mach-mmp/gplugd.c
> @@ -0,0 +1,189 @@
> +/*
> + * ?linux/arch/arm/mach-mmp/gplugd.c
> + *
> + * ?Support for the Marvell PXA168-based GuruPlug Display (gplugD) Platform.
> + *
> + * ?This program is free software; you can redistribute it and/or modify
> + * ?it under the terms of the GNU General Public License version 2 as
> + * ?publishhed by the Free Software Foundation.
> + */
> +
> +#include <linux/init.h>
> +
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +
> +#include <mach/gpio.h>
> +#include <mach/pxa168.h>
> +#include <mach/mfp-pxa168.h>
> +#include <mach/mfp-gplugd.h>
> +
> +#include "common.h"
> +
> +static unsigned long gplugd_pin_config[] __initdata = {
> + ? ? ? /* UART3 */
> + ? ? ? GPIO8_UART3_SOUT,
> + ? ? ? GPIO9_UART3_SIN,
> + ? ? ? GPI1O_UART3_CTS,
> + ? ? ? GPI11_UART3_RTS,
> +
> + ? ? ? /* MMC2 */
> + ? ? ? GPIO28_MMC2_CMD,
> + ? ? ? GPIO29_MMC2_CLK,
> + ? ? ? GPIO30_MMC2_DAT0,
> + ? ? ? GPIO31_MMC2_DAT1,
> + ? ? ? GPIO32_MMC2_DAT2,
> + ? ? ? GPIO33_MMC2_DAT3,
> +
> + ? ? ? /* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */
> + ? ? ? GPIO35_GPIO,
> + ? ? ? GPIO36_GPIO, /* CEC Interrupt */
> +
> + ? ? ? /* MMC1 */
> + ? ? ? GPIO43_MMC1_CLK,
> + ? ? ? GPIO49_MMC1_CMD,
> + ? ? ? GPIO41_MMC1_DAT0,
> + ? ? ? GPIO40_MMC1_DAT1,
> + ? ? ? GPIO52_MMC1_DAT2,
> + ? ? ? GPIO51_MMC1_DAT3,
> + ? ? ? GPIO53_MMC1_CD,
> +
> + ? ? ? /* LCD */
> + ? ? ? GPIO56_LCD_FCLK_RD,
> + ? ? ? GPIO57_LCD_LCLK_A0,
> + ? ? ? GPIO58_LCD_PCLK_WR,
> + ? ? ? GPIO59_LCD_DENA_BIAS,
> + ? ? ? GPIO60_LCD_DD0,
> + ? ? ? GPIO61_LCD_DD1,
> + ? ? ? GPIO62_LCD_DD2,
> + ? ? ? GPIO63_LCD_DD3,
> + ? ? ? GPIO64_LCD_DD4,
> + ? ? ? GPIO65_LCD_DD5,
> + ? ? ? GPIO66_LCD_DD6,
> + ? ? ? GPIO67_LCD_DD7,
> + ? ? ? GPIO68_LCD_DD8,
> + ? ? ? GPIO69_LCD_DD9,
> + ? ? ? GPIO70_LCD_DD10,
> + ? ? ? GPIO71_LCD_DD11,
> + ? ? ? GPIO72_LCD_DD12,
> + ? ? ? GPIO73_LCD_DD13,
> + ? ? ? GPIO74_LCD_DD14,
> + ? ? ? GPIO75_LCD_DD15,
> + ? ? ? GPIO76_LCD_DD16,
> + ? ? ? GPIO77_LCD_DD17,
> + ? ? ? GPIO78_LCD_DD18,
> + ? ? ? GPIO79_LCD_DD19,
> + ? ? ? GPIO80_LCD_DD20,
> + ? ? ? GPIO81_LCD_DD21,
> + ? ? ? GPIO82_LCD_DD22,
> + ? ? ? GPIO83_LCD_DD23,
> +
> + ? ? ? /* GPIO */
> + ? ? ? GPIO84_GPIO,
> + ? ? ? GPIO85_GPIO,
> +
> + ? ? ? /* Fast-Ethernet*/
> + ? ? ? GPIO86_TX_CLK,
> + ? ? ? GPIO87_TX_EN,
> + ? ? ? GPIO88_TX_DQ3,
> + ? ? ? GPIO89_TX_DQ2,
> + ? ? ? GPIO90_TX_DQ1,
> + ? ? ? GPIO91_TX_DQ0,
> + ? ? ? GPIO92_MII_CRS,
> + ? ? ? GPIO93_MII_COL,
> + ? ? ? GPIO94_RX_CLK,
> + ? ? ? GPIO95_RX_ER,
> + ? ? ? GPIO96_RX_DQ3,
> + ? ? ? GPIO97_RX_DQ2,
> + ? ? ? GPIO98_RX_DQ1,
> + ? ? ? GPIO99_RX_DQ0,
> + ? ? ? GPIO100_MII_MDC,
> + ? ? ? GPIO101_MII_MDIO,
> + ? ? ? GPIO103_RX_DV,
> + ? ? ? GPIO104_GPIO, ? ? /* Reset PHY */
> +
> + ? ? ? /* RTC interrupt */
> + ? ? ? GPIO102_GPIO,
> +
> + ? ? ? /* I2C */
> + ? ? ? GPIO105_CI2C_SDA,
> + ? ? ? GPIO106_CI2C_SCL,
> +
> + ? ? ? /* Select JTAG */
> + ? ? ? GPIO109_GPIO,
> +
> + ? ? ? /* I2S */
> + ? ? ? GPIO114_I2S_FRM,
> + ? ? ? GPIO115_I2S_BCLK,
> + ? ? ? GPIO116_I2S_TXD
> +};
> +
> +static struct i2c_board_info gplugd_i2c_board_info[] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .type = "isl1208",
> + ? ? ? ? ? ? ? .addr = 0x6F,
> + ? ? ? }
> +};
> +
> +/* Bring PHY out of reset by setting GPIO 104 */
> +static int gplugd_eth_init(void)
> +{
> + ? ? ? if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "PHY out of reset\n");
> + ? ? ? ? ? ? ? return -EIO;
> + ? ? ? }
> +
> + ? ? ? gpio_direction_output(104, 1);
> + ? ? ? gpio_free(104);
> + ? ? ? return 0;
> +}
> +
> +struct pxa168_eth_platform_data gplugd_eth_platform_data = {
> + ? ? ? .port_number = 0,
> + ? ? ? .phy_addr ? ?= 0,
> + ? ? ? .speed ? ? ? = 0, /* Autonagotiation */
> + ? ? ? .init ? ? ? ?= gplugd_eth_init,
> +};
> +
> +static void __init select_disp_freq(void)
> +{
> + ? ? ? /* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
> + ? ? ? if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "Can't get hold of GPIO 35 to select display "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "frequency\n");
> + ? ? ? } else {
> + ? ? ? ? ? ? ? gpio_direction_output(35, 1);
> + ? ? ? ? ? ? ? gpio_free(104);
> + ? ? ? }
> +
> + ? ? ? if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "Can't get hold of GPIO 85 to select display "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "frequency\n");
> + ? ? ? } else {
> + ? ? ? ? ? ? ? gpio_direction_output(85, 0);
> + ? ? ? ? ? ? ? gpio_free(104);
> + ? ? ? }
> +}
> +
> +static void __init gplugd_init(void)
> +{
> + ? ? ? mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
> +
> + ? ? ? select_disp_freq();
> +
> + ? ? ? /* on-chip devices */
> + ? ? ? pxa168_add_uart(3);
> + ? ? ? pxa168_add_ssp(0);
> + ? ? ? pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
> +
> + ? ? ? pxa168_add_eth(&gplugd_eth_platform_data);
> +}
> +
> +MACHINE_START(SHEEVAD, "PXA168-based GuruPlug Display (gplugD) Platform")
> + ? ? ? .map_io ? ? ? ? = mmp_map_io,
> + ? ? ? .nr_irqs ? ? ? ?= IRQ_BOARD_START,
> + ? ? ? .init_irq ? ? ? = pxa168_init_irq,
> + ? ? ? .timer ? ? ? ? ?= &pxa168_timer,
> + ? ? ? .init_machine ? = gplugd_init,
> +MACHINE_END
> diff --git a/arch/arm/mach-mmp/include/mach/mfp-gplugd.h b/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
> new file mode 100644
> index 0000000..b8cf38d
> --- /dev/null
> +++ b/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
> @@ -0,0 +1,52 @@
> +/*
> + * linux/arch/arm/mach-mmp/include/mach/mfp-gplugd.h
> + *
> + * ? MFP definitions used in gplugD
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __MACH_MFP_GPLUGD_H
> +#define __MACH_MFP_GPLUGD_H
> +
> +#include <plat/mfp.h>
> +#include <mach/mfp.h>
> +
> +/* UART3 */
> +#define GPIO8_UART3_SOUT ? ? ? MFP_CFG(GPIO8, AF2)
> +#define GPIO9_UART3_SIN ? ? ? ?MFP_CFG(GPIO9, AF2)
> +#define GPI1O_UART3_CTS ? ? ? ?MFP_CFG(GPIO10, AF2)
> +#define GPI11_UART3_RTS ? ? ? ?MFP_CFG(GPIO11, AF2)
> +
> +/* MMC2 */
> +#define ? ? ? ?GPIO28_MMC2_CMD ? ? ? ? MFP_CFG_DRV(GPIO28, AF6, FAST)
> +#define ? ? ? ?GPIO29_MMC2_CLK ? ? ? ? MFP_CFG_DRV(GPIO29, AF6, FAST)
> +#define ? ? ? ?GPIO30_MMC2_DAT0 ? ? ? ?MFP_CFG_DRV(GPIO30, AF6, FAST)
> +#define ? ? ? ?GPIO31_MMC2_DAT1 ? ? ? ?MFP_CFG_DRV(GPIO31, AF6, FAST)
> +#define ? ? ? ?GPIO32_MMC2_DAT2 ? ? ? ?MFP_CFG_DRV(GPIO32, AF6, FAST)
> +#define ? ? ? ?GPIO33_MMC2_DAT3 ? ? ? ?MFP_CFG_DRV(GPIO33, AF6, FAST)
> +
> +/* I2S */
> +#undef GPIO114_I2S_FRM
> +#undef GPIO115_I2S_BCLK
> +
> +#define GPIO114_I2S_FRM ? ? ? ? ? ? ? ?MFP_CFG_DRV(GPIO114, AF1, FAST)
> +#define GPIO115_I2S_BCLK ? ? ? ?MFP_CFG_DRV(GPIO115, AF1, FAST)
> +#define GPIO116_I2S_TXD ? ? ? ? MFP_CFG_DRV(GPIO116, AF1, FAST)
> +
> +/* MMC4 */
> +#define GPIO125_MMC4_DAT3 ? ? ? MFP_CFG_DRV(GPIO125, AF7, FAST)
> +#define GPIO126_MMC4_DAT2 ? ? ? MFP_CFG_DRV(GPIO126, AF7, FAST)
> +#define GPIO127_MMC4_DAT1 ? ? ? MFP_CFG_DRV(GPIO127, AF7, FAST)
> +#define GPIO0_2_MMC4_DAT0 ? ? ? MFP_CFG_DRV(GPIO0_2, AF7, FAST)
> +#define GPIO1_2_MMC4_CMD ? ? ? ?MFP_CFG_DRV(GPIO1_2, AF7, FAST)
> +#define GPIO2_2_MMC4_CLK ? ? ? ?MFP_CFG_DRV(GPIO2_2, AF7, FAST)
> +
> +/* OTG GPIO */
> +#define GPIO_USB_OTG_PEN ? ? ? ?18
> +#define GPIO_USB_OIDIR ? ? ? ? ?20
> +
> +/* Other GPIOs are 35, 84, 85 */
> +#endif /* __MACH_MFP_GPLUGD_H */
> --
> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD
       [not found] <yes>
                   ` (47 preceding siblings ...)
  2011-06-15  0:46   ` Wu DaoGuang
@ 2011-06-22  5:55 ` Tanmay Upadhyay
  2011-07-06 12:20   ` Daniel Mack
  2011-07-21  4:54   ` Vishwanath BS
                   ` (42 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Tanmay Upadhyay @ 2011-06-22  5:55 UTC (permalink / raw)
  To: linux-arm-kernel

Tested UART console, Ethernet & I2C interfaces

v2 - move definitions from mfp-gplugd.h to mfp-pxa168.h

Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
---
 arch/arm/mach-mmp/Kconfig                   |    7 +
 arch/arm/mach-mmp/Makefile                  |    1 +
 arch/arm/mach-mmp/gplugd.c                  |  197 +++++++++++++++++++++++++++
 arch/arm/mach-mmp/include/mach/mfp-pxa168.h |   37 +++++-
 4 files changed, 237 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-mmp/gplugd.c

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 67793a6..019d70a 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -77,6 +77,13 @@ config MACH_TETON_BGA
 	  Say 'Y' here if you want to support the Marvell PXA168-based
 	  Teton BGA Development Board.
 
+config MACH_SHEEVAD
+	bool "Marvell's PXA168 gplugD Board"
+	select CPU_PXA168
+	help
+	  Say 'Y' here if you want to support the Marvell PXA168-based
+	  GuruPlug Display(gplugD) Development Board
+
 endmenu
 
 config CPU_PXA168
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
index 5c68382..b0ac942 100644
--- a/arch/arm/mach-mmp/Makefile
+++ b/arch/arm/mach-mmp/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_MACH_BROWNSTONE)	+= brownstone.o
 obj-$(CONFIG_MACH_FLINT)	+= flint.o
 obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
 obj-$(CONFIG_MACH_TETON_BGA)	+= teton_bga.o
+obj-$(CONFIG_MACH_SHEEVAD)	+= gplugd.o
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
new file mode 100644
index 0000000..7fe2d12
--- /dev/null
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -0,0 +1,197 @@
+/*
+ *  linux/arch/arm/mach-mmp/gplugd.c
+ *
+ *  Support for the Marvell PXA168-based gplugD Development Platform.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <mach/pxa168.h>
+#include <mach/mfp-pxa168.h>
+
+#include "common.h"
+
+static unsigned long gplugd_pin_config[] __initdata = {
+	/* UART3 */
+	GPIO8_UART3_TXD,
+	GPIO9_UART3_RXD,
+	GPI1O_UART3_CTS,
+	GPI11_UART3_RTS,
+
+	/* USB OTG PEN */
+	GPIO18_GPIO,
+
+	/* MMC2 */
+	GPIO28_MMC2_CMD,
+	GPIO29_MMC2_CLK,
+	GPIO30_MMC2_DAT0,
+	GPIO31_MMC2_DAT1,
+	GPIO32_MMC2_DAT2,
+	GPIO33_MMC2_DAT3,
+
+	/* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */
+	GPIO35_GPIO,
+	GPIO36_GPIO, /* CEC Interrupt */
+
+	/* MMC1 */
+	GPIO43_MMC1_CLK,
+	GPIO49_MMC1_CMD,
+	GPIO41_MMC1_DAT0,
+	GPIO40_MMC1_DAT1,
+	GPIO52_MMC1_DAT2,
+	GPIO51_MMC1_DAT3,
+	GPIO53_MMC1_CD,
+
+	/* LCD */
+	GPIO56_LCD_FCLK_RD,
+	GPIO57_LCD_LCLK_A0,
+	GPIO58_LCD_PCLK_WR,
+	GPIO59_LCD_DENA_BIAS,
+	GPIO60_LCD_DD0,
+	GPIO61_LCD_DD1,
+	GPIO62_LCD_DD2,
+	GPIO63_LCD_DD3,
+	GPIO64_LCD_DD4,
+	GPIO65_LCD_DD5,
+	GPIO66_LCD_DD6,
+	GPIO67_LCD_DD7,
+	GPIO68_LCD_DD8,
+	GPIO69_LCD_DD9,
+	GPIO70_LCD_DD10,
+	GPIO71_LCD_DD11,
+	GPIO72_LCD_DD12,
+	GPIO73_LCD_DD13,
+	GPIO74_LCD_DD14,
+	GPIO75_LCD_DD15,
+	GPIO76_LCD_DD16,
+	GPIO77_LCD_DD17,
+	GPIO78_LCD_DD18,
+	GPIO79_LCD_DD19,
+	GPIO80_LCD_DD20,
+	GPIO81_LCD_DD21,
+	GPIO82_LCD_DD22,
+	GPIO83_LCD_DD23,
+
+	/* GPIO */
+	GPIO84_GPIO,
+	GPIO85_GPIO,
+
+	/* Fast-Ethernet*/
+	GPIO86_TX_CLK,
+	GPIO87_TX_EN,
+	GPIO88_TX_DQ3,
+	GPIO89_TX_DQ2,
+	GPIO90_TX_DQ1,
+	GPIO91_TX_DQ0,
+	GPIO92_MII_CRS,
+	GPIO93_MII_COL,
+	GPIO94_RX_CLK,
+	GPIO95_RX_ER,
+	GPIO96_RX_DQ3,
+	GPIO97_RX_DQ2,
+	GPIO98_RX_DQ1,
+	GPIO99_RX_DQ0,
+	GPIO100_MII_MDC,
+	GPIO101_MII_MDIO,
+	GPIO103_RX_DV,
+	GPIO104_GPIO,     /* Reset PHY */
+
+	/* RTC interrupt */
+	GPIO102_GPIO,
+
+	/* I2C */
+	GPIO105_CI2C_SDA,
+	GPIO106_CI2C_SCL,
+
+	/* SPI NOR Flash no SSP2 */
+	GPIO107_SSP2_RXD,
+	GPIO108_SSP2_TXD,
+	GPIO110_GPIO,         /* SPI_CSn */
+	GPIO111_SSP2_CLK,
+
+	/* Select JTAG */
+	GPIO109_GPIO,
+
+	/* I2S */
+	GPIO114_I2S_FRM,
+	GPIO115_I2S_BCLK,
+	GPIO116_I2S_TXD
+};
+
+static struct i2c_board_info gplugd_i2c_board_info[] = {
+	{
+		.type = "isl1208",
+		.addr = 0x6F,
+	}
+};
+
+/* Bring PHY out of reset by setting GPIO 104 */
+static int gplugd_eth_init(void)
+{
+	if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
+				"PHY out of reset\n");
+		return -EIO;
+	}
+
+	gpio_direction_output(104, 1);
+	gpio_free(104);
+	return 0;
+}
+
+struct pxa168_eth_platform_data gplugd_eth_platform_data = {
+	.port_number = 0,
+	.phy_addr    = 0,
+	.speed       = 0, /* Autonagotiation */
+	.init        = gplugd_eth_init,
+};
+
+static void __init select_disp_freq(void)
+{
+	/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
+	if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 35 to select display "
+				"frequency\n");
+	} else {
+		gpio_direction_output(35, 1);
+		gpio_free(104);
+	}
+
+	if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) {
+		printk(KERN_ERR "Can't get hold of GPIO 85 to select display "
+				"frequency\n");
+	} else {
+		gpio_direction_output(85, 0);
+		gpio_free(104);
+	}
+}
+
+static void __init gplugd_init(void)
+{
+	mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
+
+	select_disp_freq();
+
+	/* on-chip devices */
+	pxa168_add_uart(3);
+	pxa168_add_ssp(0);
+	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
+
+	pxa168_add_eth(&gplugd_eth_platform_data);
+}
+
+MACHINE_START(SHEEVAD, "PXA168-based gplugD Development Platform")
+	.map_io		= mmp_map_io,
+	.nr_irqs	= IRQ_BOARD_START,
+	.init_irq       = pxa168_init_irq,
+	.timer          = &pxa168_timer,
+	.init_machine   = gplugd_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index 8c78232..bb2a4e1 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -217,6 +217,10 @@
 #define GPIO111_UART1_DSR	MFP_CFG(GPIO111, AF2)
 #define GPIO112_UART1_DTR	MFP_CFG(GPIO111, AF1)
 #define GPIO112_UART1_DCD	MFP_CFG(GPIO112, AF2)
+#define GPIO8_UART3_TXD		MFP_CFG(GPIO8, AF2)
+#define GPIO9_UART3_RXD		MFP_CFG(GPIO9, AF2)
+#define GPI1O_UART3_CTS		MFP_CFG(GPIO10, AF2)
+#define GPI11_UART3_RTS		MFP_CFG(GPIO11, AF2)
 
 /* MMC1 */
 #define GPIO37_MMC1_DAT7	MFP_CFG(GPIO37, AF1)
@@ -232,6 +236,22 @@
 #define GPIO53_MMC1_CD		MFP_CFG(GPIO53, AF1)
 #define GPIO46_MMC1_WP		MFP_CFG(GPIO46, AF1)
 
+/* MMC2 */
+#define	GPIO28_MMC2_CMD		MFP_CFG_DRV(GPIO28, AF6, FAST)
+#define	GPIO29_MMC2_CLK		MFP_CFG_DRV(GPIO29, AF6, FAST)
+#define	GPIO30_MMC2_DAT0	MFP_CFG_DRV(GPIO30, AF6, FAST)
+#define	GPIO31_MMC2_DAT1	MFP_CFG_DRV(GPIO31, AF6, FAST)
+#define	GPIO32_MMC2_DAT2	MFP_CFG_DRV(GPIO32, AF6, FAST)
+#define	GPIO33_MMC2_DAT3	MFP_CFG_DRV(GPIO33, AF6, FAST)
+
+/* MMC4 */
+#define GPIO125_MMC4_DAT3       MFP_CFG_DRV(GPIO125, AF7, FAST)
+#define GPIO126_MMC4_DAT2       MFP_CFG_DRV(GPIO126, AF7, FAST)
+#define GPIO127_MMC4_DAT1       MFP_CFG_DRV(GPIO127, AF7, FAST)
+#define GPIO0_2_MMC4_DAT0       MFP_CFG_DRV(GPIO0_2, AF7, FAST)
+#define GPIO1_2_MMC4_CMD        MFP_CFG_DRV(GPIO1_2, AF7, FAST)
+#define GPIO2_2_MMC4_CLK        MFP_CFG_DRV(GPIO2_2, AF7, FAST)
+
 /* LCD */
 #define GPIO84_LCD_CS		MFP_CFG(GPIO84, AF1)
 #define GPIO60_LCD_DD0		MFP_CFG(GPIO60, AF1)
@@ -269,11 +289,12 @@
 #define GPIO106_CI2C_SCL	MFP_CFG(GPIO106, AF1)
 
 /* I2S */
-#define GPIO113_I2S_MCLK	MFP_CFG(GPIO113,AF6)
-#define GPIO114_I2S_FRM		MFP_CFG(GPIO114,AF1)
-#define GPIO115_I2S_BCLK	MFP_CFG(GPIO115,AF1)
-#define GPIO116_I2S_RXD		MFP_CFG(GPIO116,AF2)
-#define GPIO117_I2S_TXD		MFP_CFG(GPIO117,AF2)
+#define GPIO113_I2S_MCLK	MFP_CFG(GPIO113, AF6)
+#define GPIO114_I2S_FRM		MFP_CFG(GPIO114, AF1)
+#define GPIO115_I2S_BCLK	MFP_CFG(GPIO115, AF1)
+#define GPIO116_I2S_RXD		MFP_CFG(GPIO116, AF2)
+#define GPIO117_I2S_TXD		MFP_CFG(GPIO117, AF2)
+#define GPIO116_I2S_TXD         MFP_CFG(GPIO116, AF1)
 
 /* PWM */
 #define GPIO96_PWM3_OUT		MFP_CFG(GPIO96, AF1)
@@ -324,4 +345,10 @@
 #define GPIO101_MII_MDIO	MFP_CFG(GPIO101, AF5)
 #define GPIO103_RX_DV		MFP_CFG(GPIO103, AF5)
 
+/* SSP2 */
+#define GPIO107_SSP2_RXD	MFP_CFG(GPIO107, AF4)
+#define GPIO108_SSP2_TXD	MFP_CFG(GPIO108, AF4)
+#define GPIO111_SSP2_CLK	MFP_CFG(GPIO111, AF4)
+#define GPIO112_SSP2_FRM	MFP_CFG(GPIO112, AF4)
+
 #endif /* __ASM_MACH_MFP_PXA168_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD
  2011-06-22  5:55 ` [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
@ 2011-07-06 12:20   ` Daniel Mack
  2011-07-06 12:44     ` Eric Miao
  0 siblings, 1 reply; 716+ messages in thread
From: Daniel Mack @ 2011-07-06 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 22, 2011 at 7:55 AM, Tanmay Upadhyay
<tanmay.upadhyay@einfochips.com> wrote:
> Tested UART console, Ethernet & I2C interfaces
>
> v2 - move definitions from mfp-gplugd.h to mfp-pxa168.h
>
> Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>

Thank you for this patch. Are you working on support for more
components of this device, for example the display controller?


Daniel

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD
  2011-07-06 12:20   ` Daniel Mack
@ 2011-07-06 12:44     ` Eric Miao
  0 siblings, 0 replies; 716+ messages in thread
From: Eric Miao @ 2011-07-06 12:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 6, 2011 at 8:20 PM, Daniel Mack <zonque@gmail.com> wrote:
> On Wed, Jun 22, 2011 at 7:55 AM, Tanmay Upadhyay
> <tanmay.upadhyay@einfochips.com> wrote:
>> Tested UART console, Ethernet & I2C interfaces
>>
>> v2 - move definitions from mfp-gplugd.h to mfp-pxa168.h
>>
>> Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
>
> Thank you for this patch. Are you working on support for more
> components of this device, for example the display controller?

Daniel,

The basic support should be there - pxa168fb.c, yet the HDMI part is
missing.  Another trend is to use KMS maybe for such a complicated
controller capable of different outputs.

>
>
> Daniel
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing
  2011-05-02 22:42 ` [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash Simon Guinot
@ 2011-07-08 20:32   ` Mike Frysinger
  2011-08-02 20:02     ` Wolfgang Denk
  0 siblings, 1 reply; 716+ messages in thread
From: Mike Frysinger @ 2011-07-08 20:32 UTC (permalink / raw)
  To: u-boot

From: Simon Guinot <sguinot@lacie.com>

Signed-off-by: Simon Guinot <sguinot@lacie.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
v6
	- tweak summary

 drivers/mtd/spi/macronix.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index 96fd5f0..dacbc28 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
 	},
 };
 
+static int macronix_write_status(struct spi_flash *flash, u8 sr)
+{
+	u8 cmd;
+	int ret;
+
+	ret = spi_flash_cmd_write_enable(flash);
+	if (ret < 0) {
+		debug("SF: enabling write failed\n");
+		return ret;
+	}
+
+	cmd = CMD_MX25XX_WRSR;
+	ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1);
+	if (ret) {
+		debug("SF: fail to write status register\n");
+		return ret;
+	}
+
+	ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
+	if (ret < 0) {
+		debug("SF: write status register timed out\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int macronix_unlock(struct spi_flash *flash)
+{
+	int ret;
+
+	/* Enable status register writing and clear BP# bits */
+	ret = macronix_write_status(flash, 0);
+	if (ret)
+		debug("SF: fail to disable write protection\n");
+
+	return ret;
+}
+
 static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
 {
 	return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len);
@@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
 		* params->sectors_per_block;
 	flash->size = flash->sector_size * params->nr_blocks;
 
+	/* Clear BP# bits for read-only flash */
+	macronix_unlock(flash);
+
 	return flash;
 }
-- 
1.7.6

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
       [not found] <yes>
@ 2011-07-21  4:54   ` Vishwanath BS
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Vishwanath BS @ 2011-07-21  4:54 UTC (permalink / raw)
  To: linux-omap; +Cc: Sripathy, Vishwanath, Nishanth Menon, linux-arm-kernel

From: Sripathy, Vishwanath <vishwanath.bs@ti.com>

Add OMAP4460 OPP definitions for voltage and frequencies based on
OMAP4460 ES1.0 DM Operating Condition Addendum Version 0.1

The following exceptions are present:
* Smartreflex support is still on experimental mode: the gains and min
  limits are currently pending characterization data. Currently OMAP4430 values
  are used.
* Efuse offset for core OPP100-OV setting is not clear in documentation.
* IVA OPPs beyond OPP100 are disabled due to the delta between max OMAP4460
  current requirements and Phoenix Max supply on VCORE2 in the default
  configuration - boards which have supply which can support this should
  explicitly call opp_enable and enable the same.
* MPU OPPs > OPPTURBO can easily be detected using a efuse burnt - currently
  disabled pending clock changes to support DCC feature.

[nm@ti.com: cleanups and updates from Datamanual]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
---
Patch is generated against latest lo master.
Changes in V2: Updated the commit log as per Nishant's comments.
Patch has some checkpatch warnings related to line over 80 chars. They have
been retained to keep the readability of the code.

 arch/arm/mach-omap2/control.h                 |    1 +
 arch/arm/mach-omap2/omap_opp_data.h           |    9 ++-
 arch/arm/mach-omap2/opp4xxx_data.c            |   96 ++++++++++++++++++++++---
 arch/arm/mach-omap2/voltagedomains44xx_data.c |   14 +++-
 4 files changed, 105 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a016c8b..a41b9a7 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -195,6 +195,7 @@
 #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO	0x249
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP50	0x254
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP100	0x257
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV	0x25A
 
 /* AM35XX only CONTROL_GENERAL register offsets */
 #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index c784c12..18a750e 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -89,8 +89,11 @@ extern struct omap_volt_data omap34xx_vddcore_volt_data[];
 extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
 extern struct omap_volt_data omap36xx_vddcore_volt_data[];
 
-extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap443x_vdd_core_volt_data[];
+extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap446x_vdd_core_volt_data[];
 
 #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index 2293ba2..8c285e4 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -1,7 +1,7 @@
 /*
  * OMAP4 OPP table definitions.
  *
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
  *	Nishanth Menon
  *	Kevin Hilman
  *	Thara Gopinath
@@ -36,7 +36,7 @@
 #define OMAP4430_VDD_MPU_OPPTURBO_UV		1313000
 #define OMAP4430_VDD_MPU_OPPNITRO_UV		1375000
 
-struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
@@ -48,7 +48,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
 #define OMAP4430_VDD_IVA_OPP100_UV		1188000
 #define OMAP4430_VDD_IVA_OPPTURBO_UV		1300000
 
-struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
@@ -58,14 +58,14 @@ struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
 #define OMAP4430_VDD_CORE_OPP50_UV		1025000
 #define OMAP4430_VDD_CORE_OPP100_UV		1200000
 
-struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+struct omap_volt_data omap443x_vdd_core_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
 
-static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
 	/* MPU OPP1 - OPP50 */
 	OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
 	/* MPU OPP2 - OPP100 */
@@ -87,6 +87,82 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
 	/* TODO: add DSP, aess, fdif, gpu */
 };
 
+#define OMAP4460_VDD_MPU_OPP50_UV		1025000
+#define OMAP4460_VDD_MPU_OPP100_UV		1200000
+#define OMAP4460_VDD_MPU_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_MPU_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_IVA_OPP50_UV		1025000
+#define OMAP4460_VDD_IVA_OPP100_UV		1200000
+#define OMAP4460_VDD_IVA_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_IVA_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_CORE_OPP50_UV		1025000
+#define OMAP4460_VDD_CORE_OPP100_UV		1200000
+#define OMAP4460_VDD_CORE_OPP100_OV_UV		1250000
+
+struct omap_volt_data omap446x_vdd_core_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
+	/* MPU OPP1 - OPP50 */
+	OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
+	/* MPU OPP2 - OPP100 */
+	OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
+	/* MPU OPP3 - OPP-Turbo */
+	OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
+	/*
+	 * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
+	 * recommends TPS623631 - confirm and enable the opp in board file
+	 * XXX: May be we should enable these based on mpu capability and
+	 * Exception board files disable it...
+	 */
+	OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* MPU OPP4 - OPP-Nitro SpeedBin */
+	OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* L3 OPP1 - OPP50 */
+	OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
+	/* L3 OPP2 - OPP100 */
+	OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
+	/* IVA OPP1 - OPP50 */
+	OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
+	/* IVA OPP2 - OPP100 */
+	OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
+	/*
+	 * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
+	 * recommends Phoenix VCORE2 which can supply only 600mA - so the ones
+	 * above this OPP frequency, even though OMAP is capable, should be
+	 * enabled by board file which is sure of the chip power capability
+	 */
+	OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
+	/* IVA OPP4 - OPP-Nitro */
+	OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+	/* IVA OPP5 - OPP-Nitro SpeedBin*/
+	OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+
+	/* TODO: add DSP, aess, fdif, gpu */
+};
+
 /**
  * omap4_opp_init() - initialize omap4 opp table
  */
@@ -96,10 +172,12 @@ int __init omap4_opp_init(void)
 
 	if (!cpu_is_omap44xx())
 		return r;
-
-	r = omap_init_opp_table(omap44xx_opp_def_list,
-			ARRAY_SIZE(omap44xx_opp_def_list));
-
+	if (cpu_is_omap443x())
+		r = omap_init_opp_table(omap443x_opp_def_list,
+			ARRAY_SIZE(omap443x_opp_def_list));
+	else if (cpu_is_omap446x())
+		r = omap_init_opp_table(omap446x_opp_def_list,
+			ARRAY_SIZE(omap446x_opp_def_list));
 	return r;
 }
 device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index cb64996..f516cfe 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -91,9 +91,17 @@ static int __init omap44xx_voltage_early_init(void)
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
-	omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
-	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
-	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+	if (cpu_is_omap443x()) {
+		omap4_vdd_mpu_info.volt_data = omap443x_vdd_mpu_volt_data;
+		omap4_vdd_iva_info.volt_data = omap443x_vdd_iva_volt_data;
+		omap4_vdd_core_info.volt_data = omap443x_vdd_core_volt_data;
+	} else if (cpu_is_omap446x()) {
+		omap4_vdd_mpu_info.volt_data = omap446x_vdd_mpu_volt_data;
+		omap4_vdd_iva_info.volt_data = omap446x_vdd_iva_volt_data;
+		omap4_vdd_core_info.volt_data = omap446x_vdd_core_volt_data;
+	} else {
+		return -ENODATA;
+	}
 
 	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
 				       omap4_vdd_info,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
@ 2011-07-21  4:54   ` Vishwanath BS
  0 siblings, 0 replies; 716+ messages in thread
From: Vishwanath BS @ 2011-07-21  4:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Sripathy, Vishwanath <vishwanath.bs@ti.com>

Add OMAP4460 OPP definitions for voltage and frequencies based on
OMAP4460 ES1.0 DM Operating Condition Addendum Version 0.1

The following exceptions are present:
* Smartreflex support is still on experimental mode: the gains and min
  limits are currently pending characterization data. Currently OMAP4430 values
  are used.
* Efuse offset for core OPP100-OV setting is not clear in documentation.
* IVA OPPs beyond OPP100 are disabled due to the delta between max OMAP4460
  current requirements and Phoenix Max supply on VCORE2 in the default
  configuration - boards which have supply which can support this should
  explicitly call opp_enable and enable the same.
* MPU OPPs > OPPTURBO can easily be detected using a efuse burnt - currently
  disabled pending clock changes to support DCC feature.

[nm at ti.com: cleanups and updates from Datamanual]
Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
---
Patch is generated against latest lo master.
Changes in V2: Updated the commit log as per Nishant's comments.
Patch has some checkpatch warnings related to line over 80 chars. They have
been retained to keep the readability of the code.

 arch/arm/mach-omap2/control.h                 |    1 +
 arch/arm/mach-omap2/omap_opp_data.h           |    9 ++-
 arch/arm/mach-omap2/opp4xxx_data.c            |   96 ++++++++++++++++++++++---
 arch/arm/mach-omap2/voltagedomains44xx_data.c |   14 +++-
 4 files changed, 105 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a016c8b..a41b9a7 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -195,6 +195,7 @@
 #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO	0x249
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP50	0x254
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP100	0x257
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV	0x25A
 
 /* AM35XX only CONTROL_GENERAL register offsets */
 #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index c784c12..18a750e 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -89,8 +89,11 @@ extern struct omap_volt_data omap34xx_vddcore_volt_data[];
 extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
 extern struct omap_volt_data omap36xx_vddcore_volt_data[];
 
-extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap443x_vdd_core_volt_data[];
+extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap446x_vdd_core_volt_data[];
 
 #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index 2293ba2..8c285e4 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -1,7 +1,7 @@
 /*
  * OMAP4 OPP table definitions.
  *
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
  *	Nishanth Menon
  *	Kevin Hilman
  *	Thara Gopinath
@@ -36,7 +36,7 @@
 #define OMAP4430_VDD_MPU_OPPTURBO_UV		1313000
 #define OMAP4430_VDD_MPU_OPPNITRO_UV		1375000
 
-struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
@@ -48,7 +48,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
 #define OMAP4430_VDD_IVA_OPP100_UV		1188000
 #define OMAP4430_VDD_IVA_OPPTURBO_UV		1300000
 
-struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
@@ -58,14 +58,14 @@ struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
 #define OMAP4430_VDD_CORE_OPP50_UV		1025000
 #define OMAP4430_VDD_CORE_OPP100_UV		1200000
 
-struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+struct omap_volt_data omap443x_vdd_core_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
 
-static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
 	/* MPU OPP1 - OPP50 */
 	OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
 	/* MPU OPP2 - OPP100 */
@@ -87,6 +87,82 @@ static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
 	/* TODO: add DSP, aess, fdif, gpu */
 };
 
+#define OMAP4460_VDD_MPU_OPP50_UV		1025000
+#define OMAP4460_VDD_MPU_OPP100_UV		1200000
+#define OMAP4460_VDD_MPU_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_MPU_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_IVA_OPP50_UV		1025000
+#define OMAP4460_VDD_IVA_OPP100_UV		1200000
+#define OMAP4460_VDD_IVA_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_IVA_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_CORE_OPP50_UV		1025000
+#define OMAP4460_VDD_CORE_OPP100_UV		1200000
+#define OMAP4460_VDD_CORE_OPP100_OV_UV		1250000
+
+struct omap_volt_data omap446x_vdd_core_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
+	/* MPU OPP1 - OPP50 */
+	OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
+	/* MPU OPP2 - OPP100 */
+	OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
+	/* MPU OPP3 - OPP-Turbo */
+	OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
+	/*
+	 * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
+	 * recommends TPS623631 - confirm and enable the opp in board file
+	 * XXX: May be we should enable these based on mpu capability and
+	 * Exception board files disable it...
+	 */
+	OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* MPU OPP4 - OPP-Nitro SpeedBin */
+	OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* L3 OPP1 - OPP50 */
+	OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
+	/* L3 OPP2 - OPP100 */
+	OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
+	/* IVA OPP1 - OPP50 */
+	OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
+	/* IVA OPP2 - OPP100 */
+	OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
+	/*
+	 * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
+	 * recommends Phoenix VCORE2 which can supply only 600mA - so the ones
+	 * above this OPP frequency, even though OMAP is capable, should be
+	 * enabled by board file which is sure of the chip power capability
+	 */
+	OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
+	/* IVA OPP4 - OPP-Nitro */
+	OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+	/* IVA OPP5 - OPP-Nitro SpeedBin*/
+	OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+
+	/* TODO: add DSP, aess, fdif, gpu */
+};
+
 /**
  * omap4_opp_init() - initialize omap4 opp table
  */
@@ -96,10 +172,12 @@ int __init omap4_opp_init(void)
 
 	if (!cpu_is_omap44xx())
 		return r;
-
-	r = omap_init_opp_table(omap44xx_opp_def_list,
-			ARRAY_SIZE(omap44xx_opp_def_list));
-
+	if (cpu_is_omap443x())
+		r = omap_init_opp_table(omap443x_opp_def_list,
+			ARRAY_SIZE(omap443x_opp_def_list));
+	else if (cpu_is_omap446x())
+		r = omap_init_opp_table(omap446x_opp_def_list,
+			ARRAY_SIZE(omap446x_opp_def_list));
 	return r;
 }
 device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index cb64996..f516cfe 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -91,9 +91,17 @@ static int __init omap44xx_voltage_early_init(void)
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
-	omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
-	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
-	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+	if (cpu_is_omap443x()) {
+		omap4_vdd_mpu_info.volt_data = omap443x_vdd_mpu_volt_data;
+		omap4_vdd_iva_info.volt_data = omap443x_vdd_iva_volt_data;
+		omap4_vdd_core_info.volt_data = omap443x_vdd_core_volt_data;
+	} else if (cpu_is_omap446x()) {
+		omap4_vdd_mpu_info.volt_data = omap446x_vdd_mpu_volt_data;
+		omap4_vdd_iva_info.volt_data = omap446x_vdd_iva_volt_data;
+		omap4_vdd_core_info.volt_data = omap446x_vdd_core_volt_data;
+	} else {
+		return -ENODATA;
+	}
 
 	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
 				       omap4_vdd_info,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* RE: [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
       [not found] ` <4e27b0d0.100e8e0a.43e0.ffffe6d9SMTPIN_ADDED@mx.google.com>
@ 2011-07-21  4:56     ` Vishwanath Sripathy
  0 siblings, 0 replies; 716+ messages in thread
From: Vishwanath Sripathy @ 2011-07-21  4:56 UTC (permalink / raw)
  To: yes, linux-omap; +Cc: linux-arm-kernel, Nishanth Menon

My mailer seems to have goofed the from email-id. Pls ignore this email. I
have sent another patch correcting the same.

Vishwa
> -----Original Message-----
> From: yes@dbdp31.itg.ti.com [mailto:yes@dbdp31.itg.ti.com]
> Sent: Thursday, July 21, 2011 10:23 AM
> To: linux-omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; Sripathy, Vishwanath;
> Nishanth Menon
> Subject: [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
>
> From: Sripathy, Vishwanath <vishwanath.bs@ti.com>
>
> Add OMAP4460 OPP definitions for voltage and frequencies based on
> OMAP4460 ES1.0 DM Operating Condition Addendum Version 0.1
>
> The following exceptions are present:
> * Smartreflex support is still on experimental mode: the gains and
> min
>   limits are currently pending characterization data. Currently
> OMAP4430 values
>   are used.
> * Efuse offset for core OPP100-OV setting is not clear in
> documentation.
> * IVA OPPs beyond OPP100 are disabled due to the delta between max
> OMAP4460
>   current requirements and Phoenix Max supply on VCORE2 in the
> default
>   configuration - boards which have supply which can support this
> should
>   explicitly call opp_enable and enable the same.
> * MPU OPPs > OPPTURBO can easily be detected using a efuse burnt -
> currently
>   disabled pending clock changes to support DCC feature.
>
> [nm@ti.com: cleanups and updates from Datamanual]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> ---
> Patch is generated against latest lo master.
> Changes in V2: Updated the commit log as per Nishant's comments.
> Patch has some checkpatch warnings related to line over 80 chars.
> They have
> been retained to keep the readability of the code.
>
>  arch/arm/mach-omap2/control.h                 |    1 +
>  arch/arm/mach-omap2/omap_opp_data.h           |    9 ++-
>  arch/arm/mach-omap2/opp4xxx_data.c            |   96
> ++++++++++++++++++++++---
>  arch/arm/mach-omap2/voltagedomains44xx_data.c |   14 +++-
>  4 files changed, 105 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-
> omap2/control.h
> index a016c8b..a41b9a7 100644
> --- a/arch/arm/mach-omap2/control.h
> +++ b/arch/arm/mach-omap2/control.h
> @@ -195,6 +195,7 @@
>  #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO	0x249
>  #define OMAP44XX_CONTROL_FUSE_CORE_OPP50	0x254
>  #define OMAP44XX_CONTROL_FUSE_CORE_OPP100	0x257
> +#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV	0x25A
>
>  /* AM35XX only CONTROL_GENERAL register offsets */
>  #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL +
> 0x0038)
> diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-
> omap2/omap_opp_data.h
> index c784c12..18a750e 100644
> --- a/arch/arm/mach-omap2/omap_opp_data.h
> +++ b/arch/arm/mach-omap2/omap_opp_data.h
> @@ -89,8 +89,11 @@ extern struct omap_volt_data
> omap34xx_vddcore_volt_data[];
>  extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
>  extern struct omap_volt_data omap36xx_vddcore_volt_data[];
>
> -extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
> -extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
> -extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_core_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_core_volt_data[];
>
>  #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
> diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-
> omap2/opp4xxx_data.c
> index 2293ba2..8c285e4 100644
> --- a/arch/arm/mach-omap2/opp4xxx_data.c
> +++ b/arch/arm/mach-omap2/opp4xxx_data.c
> @@ -1,7 +1,7 @@
>  /*
>   * OMAP4 OPP table definitions.
>   *
> - * Copyright (C) 2010 Texas Instruments Incorporated -
> http://www.ti.com/
> + * Copyright (C) 2010-2011 Texas Instruments Incorporated -
> http://www.ti.com/
>   *	Nishanth Menon
>   *	Kevin Hilman
>   *	Thara Gopinath
> @@ -36,7 +36,7 @@
>  #define OMAP4430_VDD_MPU_OPPTURBO_UV		1313000
>  #define OMAP4430_VDD_MPU_OPPNITRO_UV		1375000
>
> -struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> @@ -48,7 +48,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[]
> = {
>  #define OMAP4430_VDD_IVA_OPP100_UV		1188000
>  #define OMAP4430_VDD_IVA_OPPTURBO_UV		1300000
>
> -struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> @@ -58,14 +58,14 @@ struct omap_volt_data
> omap44xx_vdd_iva_volt_data[] = {
>  #define OMAP4430_VDD_CORE_OPP50_UV		1025000
>  #define OMAP4430_VDD_CORE_OPP100_UV		1200000
>
> -struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_core_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(0, 0, 0, 0),
>  };
>
>
> -static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
> +static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
>  	/* MPU OPP1 - OPP50 */
>  	OPP_INITIALIZER("mpu", true, 300000000,
> OMAP4430_VDD_MPU_OPP50_UV),
>  	/* MPU OPP2 - OPP100 */
> @@ -87,6 +87,82 @@ static struct omap_opp_def __initdata
> omap44xx_opp_def_list[] = {
>  	/* TODO: add DSP, aess, fdif, gpu */
>  };
>
> +#define OMAP4460_VDD_MPU_OPP50_UV		1025000
> +#define OMAP4460_VDD_MPU_OPP100_UV		1200000
> +#define OMAP4460_VDD_MPU_OPPTURBO_UV		1313000
> +#define OMAP4460_VDD_MPU_OPPNITRO_UV		1375000
> +
> +struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +#define OMAP4460_VDD_IVA_OPP50_UV		1025000
> +#define OMAP4460_VDD_IVA_OPP100_UV		1200000
> +#define OMAP4460_VDD_IVA_OPPTURBO_UV		1313000
> +#define OMAP4460_VDD_IVA_OPPNITRO_UV		1375000
> +
> +struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +#define OMAP4460_VDD_CORE_OPP50_UV		1025000
> +#define OMAP4460_VDD_CORE_OPP100_UV		1200000
> +#define OMAP4460_VDD_CORE_OPP100_OV_UV		1250000
> +
> +struct omap_volt_data omap446x_vdd_core_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
> +	/* MPU OPP1 - OPP50 */
> +	OPP_INITIALIZER("mpu", true, 350000000,
> OMAP4460_VDD_MPU_OPP50_UV),
> +	/* MPU OPP2 - OPP100 */
> +	OPP_INITIALIZER("mpu", true, 700000000,
> OMAP4460_VDD_MPU_OPP100_UV),
> +	/* MPU OPP3 - OPP-Turbo */
> +	OPP_INITIALIZER("mpu", true, 920000000,
> OMAP4460_VDD_MPU_OPPTURBO_UV),
> +	/*
> +	 * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
> +	 * recommends TPS623631 - confirm and enable the opp in board
> file
> +	 * XXX: May be we should enable these based on mpu capability
> and
> +	 * Exception board files disable it...
> +	 */
> +	OPP_INITIALIZER("mpu", false, 1200000000,
> OMAP4460_VDD_MPU_OPPNITRO_UV),
> +	/* MPU OPP4 - OPP-Nitro SpeedBin */
> +	OPP_INITIALIZER("mpu", false, 1500000000,
> OMAP4460_VDD_MPU_OPPNITRO_UV),
> +	/* L3 OPP1 - OPP50 */
> +	OPP_INITIALIZER("l3_main_1", true, 100000000,
> OMAP4460_VDD_CORE_OPP50_UV),
> +	/* L3 OPP2 - OPP100 */
> +	OPP_INITIALIZER("l3_main_1", true, 200000000,
> OMAP4460_VDD_CORE_OPP100_UV),
> +	/* IVA OPP1 - OPP50 */
> +	OPP_INITIALIZER("iva", true, 133000000,
> OMAP4460_VDD_IVA_OPP50_UV),
> +	/* IVA OPP2 - OPP100 */
> +	OPP_INITIALIZER("iva", true, 266100000,
> OMAP4460_VDD_IVA_OPP100_UV),
> +	/*
> +	 * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
> +	 * recommends Phoenix VCORE2 which can supply only 600mA - so
> the ones
> +	 * above this OPP frequency, even though OMAP is capable,
> should be
> +	 * enabled by board file which is sure of the chip power
> capability
> +	 */
> +	OPP_INITIALIZER("iva", false, 332000000,
> OMAP4460_VDD_IVA_OPPTURBO_UV),
> +	/* IVA OPP4 - OPP-Nitro */
> +	OPP_INITIALIZER("iva", false, 430000000,
> OMAP4460_VDD_IVA_OPPNITRO_UV),
> +	/* IVA OPP5 - OPP-Nitro SpeedBin*/
> +	OPP_INITIALIZER("iva", false, 500000000,
> OMAP4460_VDD_IVA_OPPNITRO_UV),
> +
> +	/* TODO: add DSP, aess, fdif, gpu */
> +};
> +
>  /**
>   * omap4_opp_init() - initialize omap4 opp table
>   */
> @@ -96,10 +172,12 @@ int __init omap4_opp_init(void)
>
>  	if (!cpu_is_omap44xx())
>  		return r;
> -
> -	r = omap_init_opp_table(omap44xx_opp_def_list,
> -			ARRAY_SIZE(omap44xx_opp_def_list));
> -
> +	if (cpu_is_omap443x())
> +		r = omap_init_opp_table(omap443x_opp_def_list,
> +			ARRAY_SIZE(omap443x_opp_def_list));
> +	else if (cpu_is_omap446x())
> +		r = omap_init_opp_table(omap446x_opp_def_list,
> +			ARRAY_SIZE(omap446x_opp_def_list));
>  	return r;
>  }
>  device_initcall(omap4_opp_init);
> diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c
> b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> index cb64996..f516cfe 100644
> --- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
> +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> @@ -91,9 +91,17 @@ static int __init
> omap44xx_voltage_early_init(void)
>  	 * XXX Will depend on the process, validation, and binning
>  	 * for the currently-running IC
>  	 */
> -	omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
> -	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
> -	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
> +	if (cpu_is_omap443x()) {
> +		omap4_vdd_mpu_info.volt_data =
> omap443x_vdd_mpu_volt_data;
> +		omap4_vdd_iva_info.volt_data =
> omap443x_vdd_iva_volt_data;
> +		omap4_vdd_core_info.volt_data =
> omap443x_vdd_core_volt_data;
> +	} else if (cpu_is_omap446x()) {
> +		omap4_vdd_mpu_info.volt_data =
> omap446x_vdd_mpu_volt_data;
> +		omap4_vdd_iva_info.volt_data =
> omap446x_vdd_iva_volt_data;
> +		omap4_vdd_core_info.volt_data =
> omap446x_vdd_core_volt_data;
> +	} else {
> +		return -ENODATA;
> +	}
>
>  	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
>  				       omap4_vdd_info,
> --
> 1.7.0.4

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
@ 2011-07-21  4:56     ` Vishwanath Sripathy
  0 siblings, 0 replies; 716+ messages in thread
From: Vishwanath Sripathy @ 2011-07-21  4:56 UTC (permalink / raw)
  To: linux-arm-kernel

My mailer seems to have goofed the from email-id. Pls ignore this email. I
have sent another patch correcting the same.

Vishwa
> -----Original Message-----
> From: yes at dbdp31.itg.ti.com [mailto:yes at dbdp31.itg.ti.com]
> Sent: Thursday, July 21, 2011 10:23 AM
> To: linux-omap at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; Sripathy, Vishwanath;
> Nishanth Menon
> Subject: [PATCHV2] OMAP4: OPP: add OMAP4460 definitions
>
> From: Sripathy, Vishwanath <vishwanath.bs@ti.com>
>
> Add OMAP4460 OPP definitions for voltage and frequencies based on
> OMAP4460 ES1.0 DM Operating Condition Addendum Version 0.1
>
> The following exceptions are present:
> * Smartreflex support is still on experimental mode: the gains and
> min
>   limits are currently pending characterization data. Currently
> OMAP4430 values
>   are used.
> * Efuse offset for core OPP100-OV setting is not clear in
> documentation.
> * IVA OPPs beyond OPP100 are disabled due to the delta between max
> OMAP4460
>   current requirements and Phoenix Max supply on VCORE2 in the
> default
>   configuration - boards which have supply which can support this
> should
>   explicitly call opp_enable and enable the same.
> * MPU OPPs > OPPTURBO can easily be detected using a efuse burnt -
> currently
>   disabled pending clock changes to support DCC feature.
>
> [nm at ti.com: cleanups and updates from Datamanual]
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
> ---
> Patch is generated against latest lo master.
> Changes in V2: Updated the commit log as per Nishant's comments.
> Patch has some checkpatch warnings related to line over 80 chars.
> They have
> been retained to keep the readability of the code.
>
>  arch/arm/mach-omap2/control.h                 |    1 +
>  arch/arm/mach-omap2/omap_opp_data.h           |    9 ++-
>  arch/arm/mach-omap2/opp4xxx_data.c            |   96
> ++++++++++++++++++++++---
>  arch/arm/mach-omap2/voltagedomains44xx_data.c |   14 +++-
>  4 files changed, 105 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-
> omap2/control.h
> index a016c8b..a41b9a7 100644
> --- a/arch/arm/mach-omap2/control.h
> +++ b/arch/arm/mach-omap2/control.h
> @@ -195,6 +195,7 @@
>  #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO	0x249
>  #define OMAP44XX_CONTROL_FUSE_CORE_OPP50	0x254
>  #define OMAP44XX_CONTROL_FUSE_CORE_OPP100	0x257
> +#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV	0x25A
>
>  /* AM35XX only CONTROL_GENERAL register offsets */
>  #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL +
> 0x0038)
> diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-
> omap2/omap_opp_data.h
> index c784c12..18a750e 100644
> --- a/arch/arm/mach-omap2/omap_opp_data.h
> +++ b/arch/arm/mach-omap2/omap_opp_data.h
> @@ -89,8 +89,11 @@ extern struct omap_volt_data
> omap34xx_vddcore_volt_data[];
>  extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
>  extern struct omap_volt_data omap36xx_vddcore_volt_data[];
>
> -extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
> -extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
> -extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
> +extern struct omap_volt_data omap443x_vdd_core_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
> +extern struct omap_volt_data omap446x_vdd_core_volt_data[];
>
>  #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
> diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-
> omap2/opp4xxx_data.c
> index 2293ba2..8c285e4 100644
> --- a/arch/arm/mach-omap2/opp4xxx_data.c
> +++ b/arch/arm/mach-omap2/opp4xxx_data.c
> @@ -1,7 +1,7 @@
>  /*
>   * OMAP4 OPP table definitions.
>   *
> - * Copyright (C) 2010 Texas Instruments Incorporated -
> http://www.ti.com/
> + * Copyright (C) 2010-2011 Texas Instruments Incorporated -
> http://www.ti.com/
>   *	Nishanth Menon
>   *	Kevin Hilman
>   *	Thara Gopinath
> @@ -36,7 +36,7 @@
>  #define OMAP4430_VDD_MPU_OPPTURBO_UV		1313000
>  #define OMAP4430_VDD_MPU_OPPNITRO_UV		1375000
>
> -struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> @@ -48,7 +48,7 @@ struct omap_volt_data omap44xx_vdd_mpu_volt_data[]
> = {
>  #define OMAP4430_VDD_IVA_OPP100_UV		1188000
>  #define OMAP4430_VDD_IVA_OPPTURBO_UV		1300000
>
> -struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> @@ -58,14 +58,14 @@ struct omap_volt_data
> omap44xx_vdd_iva_volt_data[] = {
>  #define OMAP4430_VDD_CORE_OPP50_UV		1025000
>  #define OMAP4430_VDD_CORE_OPP100_UV		1200000
>
> -struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
> +struct omap_volt_data omap443x_vdd_core_volt_data[] = {
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
>  	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
>  	VOLT_DATA_DEFINE(0, 0, 0, 0),
>  };
>
>
> -static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
> +static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
>  	/* MPU OPP1 - OPP50 */
>  	OPP_INITIALIZER("mpu", true, 300000000,
> OMAP4430_VDD_MPU_OPP50_UV),
>  	/* MPU OPP2 - OPP100 */
> @@ -87,6 +87,82 @@ static struct omap_opp_def __initdata
> omap44xx_opp_def_list[] = {
>  	/* TODO: add DSP, aess, fdif, gpu */
>  };
>
> +#define OMAP4460_VDD_MPU_OPP50_UV		1025000
> +#define OMAP4460_VDD_MPU_OPP100_UV		1200000
> +#define OMAP4460_VDD_MPU_OPPTURBO_UV		1313000
> +#define OMAP4460_VDD_MPU_OPPNITRO_UV		1375000
> +
> +struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV,
> OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +#define OMAP4460_VDD_IVA_OPP50_UV		1025000
> +#define OMAP4460_VDD_IVA_OPP100_UV		1200000
> +#define OMAP4460_VDD_IVA_OPPTURBO_UV		1313000
> +#define OMAP4460_VDD_IVA_OPPNITRO_UV		1375000
> +
> +struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV,
> OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +#define OMAP4460_VDD_CORE_OPP50_UV		1025000
> +#define OMAP4460_VDD_CORE_OPP100_UV		1200000
> +#define OMAP4460_VDD_CORE_OPP100_OV_UV		1250000
> +
> +struct omap_volt_data omap446x_vdd_core_volt_data[] = {
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV,
> OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
> +	VOLT_DATA_DEFINE(0, 0, 0, 0),
> +};
> +
> +static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
> +	/* MPU OPP1 - OPP50 */
> +	OPP_INITIALIZER("mpu", true, 350000000,
> OMAP4460_VDD_MPU_OPP50_UV),
> +	/* MPU OPP2 - OPP100 */
> +	OPP_INITIALIZER("mpu", true, 700000000,
> OMAP4460_VDD_MPU_OPP100_UV),
> +	/* MPU OPP3 - OPP-Turbo */
> +	OPP_INITIALIZER("mpu", true, 920000000,
> OMAP4460_VDD_MPU_OPPTURBO_UV),
> +	/*
> +	 * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
> +	 * recommends TPS623631 - confirm and enable the opp in board
> file
> +	 * XXX: May be we should enable these based on mpu capability
> and
> +	 * Exception board files disable it...
> +	 */
> +	OPP_INITIALIZER("mpu", false, 1200000000,
> OMAP4460_VDD_MPU_OPPNITRO_UV),
> +	/* MPU OPP4 - OPP-Nitro SpeedBin */
> +	OPP_INITIALIZER("mpu", false, 1500000000,
> OMAP4460_VDD_MPU_OPPNITRO_UV),
> +	/* L3 OPP1 - OPP50 */
> +	OPP_INITIALIZER("l3_main_1", true, 100000000,
> OMAP4460_VDD_CORE_OPP50_UV),
> +	/* L3 OPP2 - OPP100 */
> +	OPP_INITIALIZER("l3_main_1", true, 200000000,
> OMAP4460_VDD_CORE_OPP100_UV),
> +	/* IVA OPP1 - OPP50 */
> +	OPP_INITIALIZER("iva", true, 133000000,
> OMAP4460_VDD_IVA_OPP50_UV),
> +	/* IVA OPP2 - OPP100 */
> +	OPP_INITIALIZER("iva", true, 266100000,
> OMAP4460_VDD_IVA_OPP100_UV),
> +	/*
> +	 * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
> +	 * recommends Phoenix VCORE2 which can supply only 600mA - so
> the ones
> +	 * above this OPP frequency, even though OMAP is capable,
> should be
> +	 * enabled by board file which is sure of the chip power
> capability
> +	 */
> +	OPP_INITIALIZER("iva", false, 332000000,
> OMAP4460_VDD_IVA_OPPTURBO_UV),
> +	/* IVA OPP4 - OPP-Nitro */
> +	OPP_INITIALIZER("iva", false, 430000000,
> OMAP4460_VDD_IVA_OPPNITRO_UV),
> +	/* IVA OPP5 - OPP-Nitro SpeedBin*/
> +	OPP_INITIALIZER("iva", false, 500000000,
> OMAP4460_VDD_IVA_OPPNITRO_UV),
> +
> +	/* TODO: add DSP, aess, fdif, gpu */
> +};
> +
>  /**
>   * omap4_opp_init() - initialize omap4 opp table
>   */
> @@ -96,10 +172,12 @@ int __init omap4_opp_init(void)
>
>  	if (!cpu_is_omap44xx())
>  		return r;
> -
> -	r = omap_init_opp_table(omap44xx_opp_def_list,
> -			ARRAY_SIZE(omap44xx_opp_def_list));
> -
> +	if (cpu_is_omap443x())
> +		r = omap_init_opp_table(omap443x_opp_def_list,
> +			ARRAY_SIZE(omap443x_opp_def_list));
> +	else if (cpu_is_omap446x())
> +		r = omap_init_opp_table(omap446x_opp_def_list,
> +			ARRAY_SIZE(omap446x_opp_def_list));
>  	return r;
>  }
>  device_initcall(omap4_opp_init);
> diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c
> b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> index cb64996..f516cfe 100644
> --- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
> +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
> @@ -91,9 +91,17 @@ static int __init
> omap44xx_voltage_early_init(void)
>  	 * XXX Will depend on the process, validation, and binning
>  	 * for the currently-running IC
>  	 */
> -	omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
> -	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
> -	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
> +	if (cpu_is_omap443x()) {
> +		omap4_vdd_mpu_info.volt_data =
> omap443x_vdd_mpu_volt_data;
> +		omap4_vdd_iva_info.volt_data =
> omap443x_vdd_iva_volt_data;
> +		omap4_vdd_core_info.volt_data =
> omap443x_vdd_core_volt_data;
> +	} else if (cpu_is_omap446x()) {
> +		omap4_vdd_mpu_info.volt_data =
> omap446x_vdd_mpu_volt_data;
> +		omap4_vdd_iva_info.volt_data =
> omap446x_vdd_iva_volt_data;
> +		omap4_vdd_core_info.volt_data =
> omap446x_vdd_core_volt_data;
> +	} else {
> +		return -ENODATA;
> +	}
>
>  	return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
>  				       omap4_vdd_info,
> --
> 1.7.0.4

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing
  2011-07-08 20:32   ` [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing Mike Frysinger
@ 2011-08-02 20:02     ` Wolfgang Denk
  0 siblings, 0 replies; 716+ messages in thread
From: Wolfgang Denk @ 2011-08-02 20:02 UTC (permalink / raw)
  To: u-boot

Dear Mike Frysinger,

In message <1310157169-27623-1-git-send-email-vapier@gentoo.org> you wrote:
> From: Simon Guinot <sguinot@lacie.com>
> 
> Signed-off-by: Simon Guinot <sguinot@lacie.com>
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
> v6
> 	- tweak summary
> 
>  drivers/mtd/spi/macronix.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 42 insertions(+), 0 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Q:  How many DEC repairman does it take to fix a flat?
A:  Five; four to hold the car up and one to swap tires.
Q:  How long does it take?
A:  It's indeterminate.  It will depend upon how many flats they've
    brought with them.
Q:  What happens if you've got TWO flats?
A:  They replace your generator.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/1] ARM: Make debug UART optional for S3C devices
       [not found] <yes>
@ 2011-10-03  0:32   ` Thiago A. Correa
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Thiago A. Correa @ 2011-10-03  0:32 UTC (permalink / raw)
  To: Russell King, Ben Dooks, linux-arm-kernel, linux-kernel; +Cc: Thiago A. Correa

This patch makes serial debug messages optional on
Samsung SoC s3c devices making all UART ports available
for other uses.

Signed-off-by: Thiago A. Correa <thiago.correa@gmail.com>
---
 arch/arm/boot/compressed/head.S                 |    2 +-
 arch/arm/plat-samsung/Kconfig                   |   11 +++++++++++
 arch/arm/plat-samsung/include/plat/uncompress.h |    9 +++++++++
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9f5ac11..3afb755 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -58,7 +58,7 @@
 		add	\rb, \rb, #0x00010000	@ Ser1
 #endif
 		.endm
-#elif defined(CONFIG_ARCH_S3C2410)
+#elif defined(CONFIG_ARCH_S3C2410) && CONFIG_ENABLE_DEBUG_S3C_UART
 		.macro loadsp, rb, tmp
 		mov	\rb, #0x50000000
 		add	\rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index b3e1065..c2183f0 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -33,7 +33,17 @@ config S3C_BOOT_ERROR_RESET
 	  Say y here to use the watchdog to reset the system if the
 	  kernel decompressor detects an error during decompression.
 
+
+config ENABLE_DEBUG_S3C_UART
+	bool "Enable S3C Debug UART"
+	help
+	  Say Y here if you want debug print of low level kernel messages
+	  using S3C UARTS.
+
+	  If in doubt, say N.
+
 config S3C_BOOT_UART_FORCE_FIFO
+       depends on ENABLE_DEBUG_S3C_UART
        bool "Force UART FIFO on during boot process"
        default y
        help
@@ -42,6 +52,7 @@ config S3C_BOOT_UART_FORCE_FIFO
 
 
 config S3C_LOWLEVEL_UART_PORT
+	depends on ENABLE_DEBUG_S3C_UART
 	int "S3C UART to use for low-level messages"
 	default 0
 	help
diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h
index ee48e12..778c2df 100644
--- a/arch/arm/plat-samsung/include/plat/uncompress.h
+++ b/arch/arm/plat-samsung/include/plat/uncompress.h
@@ -37,6 +37,7 @@ static void arch_detect_cpu(void);
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX	 (14)
 
+#if defined(CONFIG_ENABLE_DEBUG_S3C_UART)
 #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
 
 static __inline__ void
@@ -85,11 +86,19 @@ static void putc(int ch)
 	/* write byte to transmission register */
 	uart_wr(S3C2410_UTXH, ch);
 }
+#else
+static inline void putc(int ch)
+{
+}
+
+
+#endif
 
 static inline void flush(void)
 {
 }
 
+
 #define __raw_writel(d, ad)			\
 	do {							\
 		*((volatile unsigned int __force *)(ad)) = (d); \
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 1/1] ARM: Make debug UART optional for S3C devices
@ 2011-10-03  0:32   ` Thiago A. Correa
  0 siblings, 0 replies; 716+ messages in thread
From: Thiago A. Correa @ 2011-10-03  0:32 UTC (permalink / raw)
  To: linux-arm-kernel

This patch makes serial debug messages optional on
Samsung SoC s3c devices making all UART ports available
for other uses.

Signed-off-by: Thiago A. Correa <thiago.correa@gmail.com>
---
 arch/arm/boot/compressed/head.S                 |    2 +-
 arch/arm/plat-samsung/Kconfig                   |   11 +++++++++++
 arch/arm/plat-samsung/include/plat/uncompress.h |    9 +++++++++
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9f5ac11..3afb755 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -58,7 +58,7 @@
 		add	\rb, \rb, #0x00010000	@ Ser1
 #endif
 		.endm
-#elif defined(CONFIG_ARCH_S3C2410)
+#elif defined(CONFIG_ARCH_S3C2410) && CONFIG_ENABLE_DEBUG_S3C_UART
 		.macro loadsp, rb, tmp
 		mov	\rb, #0x50000000
 		add	\rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index b3e1065..c2183f0 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -33,7 +33,17 @@ config S3C_BOOT_ERROR_RESET
 	  Say y here to use the watchdog to reset the system if the
 	  kernel decompressor detects an error during decompression.
 
+
+config ENABLE_DEBUG_S3C_UART
+	bool "Enable S3C Debug UART"
+	help
+	  Say Y here if you want debug print of low level kernel messages
+	  using S3C UARTS.
+
+	  If in doubt, say N.
+
 config S3C_BOOT_UART_FORCE_FIFO
+       depends on ENABLE_DEBUG_S3C_UART
        bool "Force UART FIFO on during boot process"
        default y
        help
@@ -42,6 +52,7 @@ config S3C_BOOT_UART_FORCE_FIFO
 
 
 config S3C_LOWLEVEL_UART_PORT
+	depends on ENABLE_DEBUG_S3C_UART
 	int "S3C UART to use for low-level messages"
 	default 0
 	help
diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h
index ee48e12..778c2df 100644
--- a/arch/arm/plat-samsung/include/plat/uncompress.h
+++ b/arch/arm/plat-samsung/include/plat/uncompress.h
@@ -37,6 +37,7 @@ static void arch_detect_cpu(void);
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX	 (14)
 
+#if defined(CONFIG_ENABLE_DEBUG_S3C_UART)
 #define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
 
 static __inline__ void
@@ -85,11 +86,19 @@ static void putc(int ch)
 	/* write byte to transmission register */
 	uart_wr(S3C2410_UTXH, ch);
 }
+#else
+static inline void putc(int ch)
+{
+}
+
+
+#endif
 
 static inline void flush(void)
 {
 }
 
+
 #define __raw_writel(d, ad)			\
 	do {							\
 		*((volatile unsigned int __force *)(ad)) = (d); \
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/1] ARM: Make debug UART optional for S3C devices
  2011-10-03  0:32   ` Thiago A. Correa
@ 2011-10-10 14:44     ` Thiago A. Corrêa
  -1 siblings, 0 replies; 716+ messages in thread
From: Thiago A. Corrêa @ 2011-10-10 14:44 UTC (permalink / raw)
  To: Russell King, Ben Dooks, linux-arm-kernel, linux-kernel; +Cc: Thiago A. Correa

Hi,

    This was the first patch I have submited, would appreciate an Ack
or comments.

Kind Regards,
   Thiago A. Correa

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/1] ARM: Make debug UART optional for S3C devices
@ 2011-10-10 14:44     ` Thiago A. Corrêa
  0 siblings, 0 replies; 716+ messages in thread
From: Thiago A. Corrêa @ 2011-10-10 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

    This was the first patch I have submited, would appreciate an Ack
or comments.

Kind Regards,
   Thiago A. Correa

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] block: Needn't read the size of device or partition again
       [not found] <yes>
                   ` (51 preceding siblings ...)
  2011-10-03  0:32   ` Thiago A. Correa
@ 2011-12-11 13:10 ` taco
  2012-01-08 15:28 ` [Qemu-devel] [PATCH] Add tab-completion for device_add Andrzej Zaborowski
                   ` (38 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: taco @ 2011-12-11 13:10 UTC (permalink / raw)
  To: axboe, linux-kernel; +Cc: taco, linux-scsi

It is not necessary to invoke i_size_read to get the size of device or
partition again, due to did it before.i_size_read maybe need to abtain
lock or disable preempt.

Signed-off-by: taco <tacoee@gmail.com>
---
 block/blk-core.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index ea70e6c..3aa3fc3 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1423,7 +1423,7 @@ static inline void blk_partition_remap(struct bio *bio)
 	}
 }
 
-static void handle_bad_sector(struct bio *bio)
+static void handle_bad_sector(struct bio *bio, sector_t maxsector)
 {
 	char b[BDEVNAME_SIZE];
 
@@ -1432,7 +1432,7 @@ static void handle_bad_sector(struct bio *bio)
 			bdevname(bio->bi_bdev, b),
 			bio->bi_rw,
 			(unsigned long long)bio->bi_sector + bio_sectors(bio),
-			(long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9));
+			(long long)maxsector);
 
 	set_bit(BIO_EOF, &bio->bi_flags);
 }
@@ -1493,7 +1493,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
 			 * without checking the size of the device, e.g., when
 			 * mounting a device.
 			 */
-			handle_bad_sector(bio);
+			handle_bad_sector(bio, maxsector);
 			return 1;
 		}
 	}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [Qemu-devel] [PATCH] Add tab-completion for device_add.
       [not found] <yes>
                   ` (52 preceding siblings ...)
  2011-12-11 13:10 ` [PATCH] block: Needn't read the size of device or partition again taco
@ 2012-01-08 15:28 ` Andrzej Zaborowski
  2012-01-12 17:01   ` Anthony Liguori
  2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
                   ` (37 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Andrzej Zaborowski @ 2012-01-08 15:28 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
---
There are other ways to do this, but adding an API for querying
available qdev drivers was the one that made most sense to me.
---
 hw/qdev.c |   38 ++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |    7 +++++++
 monitor.c |   41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index d0cf66d..ba97312 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1535,3 +1535,41 @@ void qdev_machine_init(void)
     qdev_get_peripheral_anon();
     qdev_get_peripheral();
 }
+
+int qdev_driver_foreach(qdev_driver_foreach_func func, void *opaque)
+{
+    DeviceInfo *info;
+    int ret = 0;
+
+    for (info = device_info_list; info != NULL; info = info->next) {
+        ret |= (*func)(info, opaque);
+    }
+
+    return ret;
+}
+
+int qdev_driver_prop_foreach(qdev_driver_prop_foreach_func func,
+                const char *driver, void *opaque)
+{
+    DeviceInfo *info;
+    Property *prop;
+    int ret = 0;
+
+    info = qdev_find_info(NULL, driver);
+    if (!info) {
+        return -1;
+    }
+
+    for (prop = info->props; prop && prop->name; prop++) {
+        /*
+         * TODO Properties without a parser are just for dirty hacks.
+         * See comment in qdev_device_help.
+         */
+        if (!prop->info->parse) {
+            continue;           /* no way to set it, don't show */
+        }
+        ret |= (*func)(prop, opaque);
+    }
+
+    return ret;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 2abb767..b72a31a 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -624,4 +624,11 @@ char *qdev_get_type(DeviceState *dev, Error **errp);
  */
 void qdev_machine_init(void);
 
+/* Driver querying */
+typedef int (*qdev_driver_foreach_func)(DeviceInfo *info, void *opaque);
+int qdev_driver_foreach(qdev_driver_foreach_func func, void *opaque);
+typedef int (*qdev_driver_prop_foreach_func)(Property *info, void *opaque);
+int qdev_driver_prop_foreach(qdev_driver_prop_foreach_func func,
+                const char *driver, void *opaque);
+
 #endif
diff --git a/monitor.c b/monitor.c
index 7334401..3eab307 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4069,6 +4069,28 @@ static void block_completion_it(void *opaque, BlockDriverState *bs)
     }
 }
 
+static int driver_completion_it(DeviceInfo *info, void *opaque)
+{
+    const char *input = opaque;
+
+    if (input[0] == '\0' || !strncmp(info->name, input, strlen(input))) {
+        readline_add_completion(cur_mon->rs, info->name);
+    }
+
+    return 0;
+}
+
+static int driver_prop_completion_it(Property *prop, void *opaque)
+{
+    const char *input = opaque;
+
+    if (input[0] == '\0' || !strncmp(prop->name, input, strlen(input))) {
+        readline_add_completion(cur_mon->rs, prop->name);
+    }
+
+    return 0;
+}
+
 /* NOTE: this parser is an approximate form of the real command parser */
 static void parse_cmdline(const char *cmdline,
                          int *pnb_args, char **args)
@@ -4109,6 +4131,7 @@ static void monitor_find_completion(const char *cmdline)
     const char *ptype, *str;
     const mon_cmd_t *cmd;
     const KeyDef *key;
+    char *pkey;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4147,6 +4170,7 @@ static void monitor_find_completion(const char *cmdline)
             goto cleanup;
         }
 
+        key_get_info(cmd->args_type, &pkey);
         ptype = next_arg_type(cmd->args_type);
         for(i = 0; i < nb_args - 2; i++) {
             if (*ptype != '\0') {
@@ -4192,9 +4216,26 @@ static void monitor_find_completion(const char *cmdline)
                 }
             }
             break;
+        case 'O':
+            if (!strcmp(pkey, "device")) {
+                char *sep = strrchr(str, ',');
+
+                readline_set_completion_index(cur_mon->rs,
+                                strlen(sep ? sep + 1 : str));
+                if (sep) {
+                    char *driver = g_strndup(str, strchr(str, ',') - str);
+                    qdev_driver_prop_foreach(driver_prop_completion_it,
+                                    driver, (void *) (sep + 1));
+                    g_free(driver);
+                } else {
+                    qdev_driver_foreach(driver_completion_it, (void *) str);
+                }
+            }
+            break;
         default:
             break;
         }
+        g_free(pkey);
     }
 
 cleanup:
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [Qemu-devel] [PATCH] Add tab-completion for device_add.
  2012-01-08 15:28 ` [Qemu-devel] [PATCH] Add tab-completion for device_add Andrzej Zaborowski
@ 2012-01-12 17:01   ` Anthony Liguori
  0 siblings, 0 replies; 716+ messages in thread
From: Anthony Liguori @ 2012-01-12 17:01 UTC (permalink / raw)
  To: Andrzej Zaborowski; +Cc: qemu-devel

On 01/08/2012 09:28 AM, Andrzej Zaborowski wrote:
> Signed-off-by: Andrzej Zaborowski<andrew.zaborowski@intel.com>
> ---
> There are other ways to do this, but adding an API for querying
> available qdev drivers was the one that made most sense to me.
> ---
>   hw/qdev.c |   38 ++++++++++++++++++++++++++++++++++++++
>   hw/qdev.h |    7 +++++++
>   monitor.c |   41 +++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 86 insertions(+), 0 deletions(-)
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index d0cf66d..ba97312 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -1535,3 +1535,41 @@ void qdev_machine_init(void)
>       qdev_get_peripheral_anon();
>       qdev_get_peripheral();
>   }
> +
> +int qdev_driver_foreach(qdev_driver_foreach_func func, void *opaque)
> +{
> +    DeviceInfo *info;
> +    int ret = 0;
> +
> +    for (info = device_info_list; info != NULL; info = info->next) {
> +        ret |= (*func)(info, opaque);
> +    }
> +
> +    return ret;
> +}
> +
> +int qdev_driver_prop_foreach(qdev_driver_prop_foreach_func func,
> +                const char *driver, void *opaque)
> +{
> +    DeviceInfo *info;
> +    Property *prop;
> +    int ret = 0;
> +
> +    info = qdev_find_info(NULL, driver);
> +    if (!info) {
> +        return -1;
> +    }
> +
> +    for (prop = info->props; prop&&  prop->name; prop++) {
> +        /*
> +         * TODO Properties without a parser are just for dirty hacks.
> +         * See comment in qdev_device_help.
> +         */
> +        if (!prop->info->parse) {
> +            continue;           /* no way to set it, don't show */
> +        }
> +        ret |= (*func)(prop, opaque);

Would be better to pass prop->name here as Property is going to go away soon.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board
       [not found] <yes>
                   ` (53 preceding siblings ...)
  2012-01-08 15:28 ` [Qemu-devel] [PATCH] Add tab-completion for device_add Andrzej Zaborowski
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-02-23  8:59   ` [U-Boot] reminder for " Mohamed Haneef
  2012-10-26 21:15   ` [U-Boot] " Albert ARIBAUD
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
                   ` (36 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

This is a patch series for msm7630 board. The Patches contain the following support
        * low speed uart for msm7630
        * interprocessor communication
        * msm7630 soc
        * msm7630 surf board


Mohamed Haneef (5):
  msm7x30: Add support for low speed uart on msm7x30
  msm7x30: Add support for interprocessor communication
  msm7x30: Add support for Qualcomm msm7630 soc
  Add support for mmc read and writes
  msm7x30: Add support for msm7630_surf board

 arch/arm/cpu/armv7/msm7630/Makefile           |   59 +++
 arch/arm/cpu/armv7/msm7630/acpuclock.c        |  328 +++++++++++++
 arch/arm/cpu/armv7/msm7630/board.c            |   58 +++
 arch/arm/cpu/armv7/msm7630/config.mk          |    1 +
 arch/arm/cpu/armv7/msm7630/gpio.c             |  229 +++++++++
 arch/arm/cpu/armv7/msm7630/lowlevel_init.S    |  626 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/msm7630/timer.c            |  148 ++++++
 arch/arm/include/asm/arch-msm7630/adm.h       |   28 ++
 arch/arm/include/asm/arch-msm7630/gpio.h      |   47 ++
 arch/arm/include/asm/arch-msm7630/gpio_hw.h   |  168 +++++++
 arch/arm/include/asm/arch-msm7630/iomap.h     |   96 ++++
 arch/arm/include/asm/arch-msm7630/mmc.h       |  399 ++++++++++++++++
 arch/arm/include/asm/arch-msm7630/proc_comm.h |   42 ++
 arch/arm/include/asm/arch-msm7630/sys_proto.h |   29 ++
 board/qcom/msm7630_surf/Makefile              |   55 +++
 board/qcom/msm7630_surf/msm7630_surf.c        |  155 ++++++
 board/qcom/msm7630_surf/msm7630_surf.h        |   30 ++
 boards.cfg                                    |    1 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/msm_proc_comm.c                  |  303 ++++++++++++
 drivers/mmc/Makefile                          |    1 +
 drivers/mmc/qc_mmc.c                          |  584 +++++++++++++++++++++++
 drivers/serial/Makefile                       |    1 +
 drivers/serial/serial_msm_uart.c              |  206 ++++++++
 include/configs/msm7630_surf.h                |  131 +++++
 25 files changed, 3726 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
 create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
 create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
 create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h
 create mode 100644 board/qcom/msm7630_surf/Makefile
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
 create mode 100644 drivers/misc/msm_proc_comm.c
 create mode 100644 drivers/mmc/qc_mmc.c
 create mode 100644 drivers/serial/serial_msm_uart.c
 create mode 100644 include/configs/msm7630_surf.h


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30
       [not found] <yes>
                   ` (54 preceding siblings ...)
  2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-02-28 23:44   ` Albert ARIBAUD
                     ` (4 more replies)
  2012-02-16  2:59 ` [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication mohamed.haneef at lntinfotech.com
                   ` (35 subsequent siblings)
  91 siblings, 5 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

        * Support for low speed uart

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
 drivers/serial/Makefile          |    1 +
 drivers/serial/serial_msm_uart.c |  206 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 207 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/serial_msm_uart.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 616b857..2801edc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -55,6 +55,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
 COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
 COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
 COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_MSM_UART) += serial_msm_uart.o

 ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_msm_uart.c b/drivers/serial/serial_msm_uart.c
new file mode 100644
index 0000000..8cafa7a
--- /dev/null
+++ b/drivers/serial/serial_msm_uart.c
@@ -0,0 +1,206 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+#define UART_MR1         0x0000
+
+#define UART_MR1_AUTO_RFR_LEVEL0(n) (((n) & 0x3f) << 8)
+#define UART_MR1_RX_RDY_CTL    (1 << 7)
+#define UART_MR1_CTS_CTL       (1 << 6)
+#define UART_MR1_AUTO_RFR_LEVEL1(n) ((n) & 0x3f)
+
+#define UART_MR2         0x0004
+#define UART_MR2_ERROR_MODE        (1 << 6)
+#define UART_MR2_BITS_PER_CHAR_5   (0 << 4)
+#define UART_MR2_BITS_PER_CHAR_6   (1 << 4)
+#define UART_MR2_BITS_PER_CHAR_7   (2 << 4)
+#define UART_MR2_BITS_PER_CHAR_8   (3 << 4)
+#define UART_MR2_STOP_BIT_LEN_0563 (0 << 2)
+#define UART_MR2_STOP_BIT_LEN_1000 (1 << 2)
+#define UART_MR2_STOP_BIT_LEN_1563 (2 << 2)
+#define UART_MR2_STOP_BIT_LEN_2000 (3 << 2)
+#define UART_MR2_PARITY_MODE_NONE  (0)
+#define UART_MR2_PARITY_MODE_ODD   (1)
+#define UART_MR2_PARITY_MODE_EVEN  (2)
+#define UART_MR2_PARITY_MODE_SPACE (3)
+
+#define UART_CSR         0x0008
+#define UART_CSR_115200  0xFF
+#define UART_CSR_57600   0xEE
+#define UART_CSR_38400   0xDD
+#define UART_CSR_19200   0xBB
+
+#define UART_TF          0x000C
+
+#define UART_CR          0x0010
+#define UART_CR_CMD_NULL           (0 << 4)
+#define UART_CR_CMD_RESET_RX       (1 << 4)
+#define UART_CR_CMD_RESET_TX       (2 << 4)
+#define UART_CR_CMD_RESET_ERR      (3 << 4)
+#define UART_CR_CMD_RESET_BCI      (4 << 4)
+#define UART_CR_CMD_START_BREAK    (5 << 4)
+#define UART_CR_CMD_STOP_BREAK     (6 << 4)
+#define UART_CR_CMD_RESET_CTS_N    (7 << 4)
+#define UART_CR_CMD_PACKET_MODE    (9 << 4)
+#define UART_CR_CMD_MODE_RESET     (12 << 4)
+#define UART_CR_CMD_SET_RFR_N      (13 << 4)
+#define UART_CR_CMD_RESET_RFR_ND   (14 << 4)
+#define UART_CR_TX_DISABLE         (1 << 3)
+#define UART_CR_TX_ENABLE          (1 << 3)
+#define UART_CR_RX_DISABLE         (1 << 3)
+#define UART_CR_RX_ENABLE          (1 << 3)
+
+#define UART_IMR         0x0014
+#define UART_IMR_RXLEV (1 << 4)
+#define UART_IMR_TXLEV (1 << 0)
+
+#define UART_IPR         0x0018
+#define UART_TFWR        0x001C
+#define UART_RFWR        0x0020
+#define UART_HCR         0x0024
+
+#define UART_MREG        0x0028
+#define UART_NREG        0x002C
+#define UART_DREG        0x0030
+#define UART_MNDREG      0x0034
+#define UART_IRDA        0x0038
+#define UART_MISR_MODE   0x0040
+#define UART_MISR_RESET  0x0044
+#define UART_MISR_EXPORT 0x0048
+#define UART_MISR_VAL    0x004C
+#define UART_TEST_CTRL   0x0050
+
+#define UART_SR          0x0008
+#define UART_SR_HUNT_CHAR      (1 << 7)
+#define UART_SR_RX_BREAK       (1 << 6)
+#define UART_SR_PAR_FRAME_ERR  (1 << 5)
+#define UART_SR_OVERRUN        (1 << 4)
+#define UART_SR_TX_EMPTY       (1 << 3)
+#define UART_SR_TX_READY       (1 << 2)
+#define UART_SR_RX_FULL        (1 << 1)
+#define UART_SR_RX_READY       (1 << 0)
+
+#define UART_RF          0x000C
+#define UART_MISR        0x0010
+#define UART_ISR         0x0014
+
+
+#if PLATFORM_MSM7X30
+static unsigned uart_base = MSM_UART2_BASE;
+#elif PLATFORM_MSM7X27A
+static unsigned uart_base = MSM_UART1_BASE;
+#else
+static unsigned uart_base = MSM_UART3_BASE;
+#endif
+
+#define uwr(v, a) writel(v, uart_base + (a))
+#define urd(a) readl(uart_base + (a))
+
+void uart_init(void)
+{
+       uwr(0x0A, UART_CR);  /* disable TX and RX */
+       uwr(0x30, UART_CR);  /* reset error status */
+       uwr(0x10, UART_CR);  /* reset receiver */
+       uwr(0x20, UART_CR);  /* reset transmitter */
+#if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM7X27A
+       /* TCXO */
+       uwr(0x06, UART_MREG);
+       uwr(0xF1, UART_NREG);
+       uwr(0x0F, UART_DREG);
+       uwr(0x1A, UART_MNDREG);
+#else
+       /* TCXO/4 */
+       uwr(0xC0, UART_MREG);
+       uwr(0xAF, UART_NREG);
+       uwr(0x80, UART_DREG);
+       uwr(0x19, UART_MNDREG);
+#endif
+       uwr(0x10, UART_CR);  /* reset RX */
+       uwr(0x20, UART_CR);  /* reset TX */
+       uwr(0x30, UART_CR);  /* reset error status */
+       uwr(0x40, UART_CR);  /* reset RX break */
+       uwr(0x70, UART_CR);  /* rest? */
+       uwr(0xD0, UART_CR);  /* reset */
+       uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */
+       uwr(0, UART_IMR);
+       uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */
+       uwr(10, UART_TFWR);  /* TX watermark */
+       uwr(0, UART_RFWR);
+       uwr(UART_CSR_115200, UART_CSR);
+       uwr(0, UART_IRDA);
+       uwr(0x1E, UART_HCR);
+       uwr(16, UART_MR1);
+       uwr(0x34, UART_MR2); /* 8N1 */
+       uwr(0x05, UART_CR); /* enable TX & RX */
+
+}
+
+static int _uart_putc(int port, char c)
+{
+       while (!(urd(UART_SR) & UART_SR_TX_READY))
+               ;
+       uwr(c, UART_TF);
+       return 0;
+}
+
+int serial_init(void)
+{
+       uart_init();
+       return 0;
+}
+
+void serial_putc(char c)
+{
+       if (c == '\n')
+               _uart_putc(0, '\r');
+       _uart_putc(0, c);
+}
+
+void serial_putc_raw(const char c)
+{
+       _uart_putc(0, c);
+}
+
+void serial_puts(const char *s)
+{
+       while (*s)
+               serial_putc(*s++);
+}
+
+int serial_getc()
+{
+       while (!(urd(UART_SR) & UART_SR_RX_READY))
+               ;
+       return urd(UART_RF);
+}
+
+int serial_tstc()
+{
+       return urd(UART_SR) & UART_SR_RX_READY;
+}
+
+void serial_setbrg()
+{
+}
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication
       [not found] <yes>
                   ` (55 preceding siblings ...)
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-02-28 23:46   ` Albert ARIBAUD
  2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
                   ` (34 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

        *Support for msm7x30 interprocessor communication

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
 drivers/misc/Makefile        |    1 +
 drivers/misc/msm_proc_comm.c |  303 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 304 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/msm_proc_comm.c

diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a709707..b324d73 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -39,6 +39,7 @@ COBJS-$(CONFIG_PMIC_FSL) += pmic_fsl.o
 COBJS-$(CONFIG_PMIC_I2C) += pmic_i2c.o
 COBJS-$(CONFIG_PMIC_SPI) += pmic_spi.o
 COBJS-$(CONFIG_PMIC_MAX8998) += pmic_max8998.o
+COBJS-$(CONFIG_MSM_PCOMM) += msm_proc_comm.o

 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/misc/msm_proc_comm.c b/drivers/misc/msm_proc_comm.c
new file mode 100644
index 0000000..f1db917
--- /dev/null
+++ b/drivers/misc/msm_proc_comm.c
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#define ACPU_CLK       0  /* Applications processor clock */
+#define ADM_CLK                1  /* Applications data mover clock */
+#define ADSP_CLK       2  /* ADSP clock */
+#define EBI1_CLK       3  /* External bus interface 1 clock */
+#define EBI2_CLK       4  /* External bus interface 2 clock */
+#define ECODEC_CLK     5  /* External CODEC clock */
+#define EMDH_CLK       6  /* External MDDI host clock */
+#define GP_CLK         7  /* General purpose clock */
+#define GRP_CLK                8  /* Graphics clock */
+#define I2C_CLK                9  /* I2C clock */
+#define ICODEC_RX_CLK  10  /* Internal CODEX RX clock */
+#define ICODEC_TX_CLK  11  /* Internal CODEX TX clock */
+#define IMEM_CLK       12  /* Internal graphics memory clock */
+#define MDC_CLK                13  /* MDDI client clock */
+#define MDP_CLK                14  /* Mobile display processor clock */
+#define PBUS_CLK       15  /* Peripheral bus clock */
+#define PCM_CLK                16  /* PCM clock */
+#define PMDH_CLK       17  /* Primary MDDI host clock */
+#define SDAC_CLK       18  /* Stereo DAC clock */
+#define SDC1_CLK       19  /* Secure Digital Card clocks */
+#define SDC1_PCLK      20
+#define SDC2_CLK       21
+#define SDC2_PCLK      22
+#define SDC3_CLK       23
+#define SDC3_PCLK      24
+#define SDC4_CLK       25
+#define SDC4_PCLK      26
+#define TSIF_CLK       27  /* Transport Stream Interface clocks */
+#define TSIF_REF_CLK   28
+#define TV_DAC_CLK     29  /* TV clocks */
+#define TV_ENC_CLK     30
+#define UART1_CLK      31  /* UART clocks */
+#define UART2_CLK      32
+#define UART3_CLK      33
+#define UART1DM_CLK    34
+#define UART2DM_CLK    35
+#define USB_HS_CLK     36  /* High speed USB core clock */
+#define USB_HS_PCLK    37  /* High speed USB pbus clock */
+#define USB_OTG_CLK    38  /* Full speed USB clock */
+#define VDC_CLK                39  /* Video controller clock */
+#define VFE_CLK                40  /* Camera / Video Front End clock */
+#define VFE_MDC_CLK    41  /* VFE MDDI client clock */
+
+/* qsd8k adds... */
+#define MDP_LCDC_PCLK_CLK      42
+#define MDP_LCDC_PAD_PCLK_CLK  43
+#define MDP_VSYNC_CLK          44
+
+#define P_USB_HS_CORE_CLK      53  /* High speed USB 1 core clock */
+/* msm7x30 adds... */
+#define PMDH_P_CLK             82
+#define MDP_P_CLK              86
+
+enum {
+       PCOM_CMD_IDLE = 0x0,
+       PCOM_CMD_DONE,
+       PCOM_RESET_APPS,
+       PCOM_RESET_CHIP,
+       PCOM_CONFIG_NAND_MPU,
+       PCOM_CONFIG_USB_CLKS,
+       PCOM_GET_POWER_ON_STATUS,
+       PCOM_GET_WAKE_UP_STATUS,
+       PCOM_GET_BATT_LEVEL,
+       PCOM_CHG_IS_CHARGING,
+       PCOM_POWER_DOWN,
+       PCOM_USB_PIN_CONFIG,
+       PCOM_USB_PIN_SEL,
+       PCOM_SET_RTC_ALARM,
+       PCOM_NV_READ,
+       PCOM_NV_WRITE,
+       PCOM_GET_UUID_HIGH,
+       PCOM_GET_UUID_LOW,
+       PCOM_GET_HW_ENTROPY,
+       PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+       PCOM_CLKCTL_RPC_ENABLE,
+       PCOM_CLKCTL_RPC_DISABLE,
+       PCOM_CLKCTL_RPC_RESET,
+       PCOM_CLKCTL_RPC_SET_FLAGS,
+       PCOM_CLKCTL_RPC_SET_RATE,
+       PCOM_CLKCTL_RPC_MIN_RATE,
+       PCOM_CLKCTL_RPC_MAX_RATE,
+       PCOM_CLKCTL_RPC_RATE,
+       PCOM_CLKCTL_RPC_PLL_REQUEST,
+       PCOM_CLKCTL_RPC_ENABLED,
+       PCOM_VREG_SWITCH,
+       PCOM_VREG_SET_LEVEL,
+       PCOM_GPIO_TLMM_CONFIG_GROUP,
+       PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+       PCOM_NV_READ_HIGH_BITS,
+       PCOM_NV_WRITE_HIGH_BITS,
+       PCOM_RPC_GPIO_TLMM_CONFIG_EX = 0x25,
+       PCOM_NUM_CMDS,
+};
+
+enum {
+        PCOM_INVALID_STATUS = 0x0,
+        PCOM_READY,
+        PCOM_CMD_RUNNING,
+        PCOM_CMD_SUCCESS,
+        PCOM_CMD_FAIL,
+};
+
+#ifndef PLATFORM_MSM7X30
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+#endif
+static inline void notify_other_proc_comm(void)
+{
+#ifndef PLATFORM_MSM7X30
+       writel(1, MSM_A2M_INT(6));
+#else
+       writel(1<<6, (MSM_GCC_BASE + 0x8));
+#endif
+}
+
+#define APP_COMMAND    (MSM_SHARED_BASE + 0x00)
+#define APP_STATUS     (MSM_SHARED_BASE + 0x04)
+#define APP_DATA1      (MSM_SHARED_BASE + 0x08)
+#define APP_DATA2      (MSM_SHARED_BASE + 0x0C)
+
+#define MDM_COMMAND    (MSM_SHARED_BASE + 0x10)
+#define MDM_STATUS     (MSM_SHARED_BASE + 0x14)
+#define MDM_DATA1      (MSM_SHARED_BASE + 0x18)
+#define MDM_DATA2      (MSM_SHARED_BASE + 0x1C)
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+       int ret = -1;
+       unsigned status;
+
+       while (readl(MDM_STATUS) != PCOM_READY)
+               /* XXX check for A9 reset */
+               ;
+       writel(cmd, APP_COMMAND);
+       if (data1)
+               writel(*data1, APP_DATA1);
+       if (data2)
+               writel(*data2, APP_DATA2);
+
+       notify_other_proc_comm();
+       while (readl(APP_COMMAND) != PCOM_CMD_DONE)
+               /* XXX check for A9 reset */
+               ;
+       status = readl(APP_STATUS);
+
+       if (status != PCOM_CMD_FAIL) {
+               if (data1)
+                       *data1 = readl(APP_DATA1);
+               if (data2)
+                       *data2 = readl(APP_DATA2);
+               ret = 0;
+       }
+       return ret;
+}
+
+static int clock_enable(unsigned id)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, 0);
+}
+
+static int clock_disable(unsigned id)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, 0);
+}
+
+static int clock_set_rate(unsigned id, unsigned rate)
+{
+       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+}
+
+static int clock_get_rate(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, 0))
+               return -1;
+       else
+               return (int) id;
+
+}
+
+void usb_clock_init(void)
+{
+       clock_enable(USB_HS_PCLK);
+       clock_enable(USB_HS_CLK);
+       clock_enable(P_USB_HS_CORE_CLK);
+}
+
+void lcdc_clock_init(unsigned rate)
+{
+       clock_set_rate(MDP_LCDC_PCLK_CLK, rate);
+       clock_enable(MDP_LCDC_PCLK_CLK);
+       clock_enable(MDP_LCDC_PAD_PCLK_CLK);
+}
+
+void mdp_clock_init(unsigned rate)
+{
+       clock_set_rate(MDP_CLK, rate);
+       clock_enable(MDP_CLK);
+       clock_enable(MDP_P_CLK);
+}
+
+void uart3_clock_init(void)
+{
+       clock_enable(UART3_CLK);
+       clock_set_rate(UART3_CLK, 19200000 / 4);
+}
+
+void uart2_clock_init(void)
+{
+       clock_enable(UART2_CLK);
+       clock_set_rate(UART2_CLK, 19200000);
+}
+
+void uart1_clock_init(void)
+{
+       clock_enable(UART1_CLK);
+       clock_set_rate(UART1_CLK, 19200000 / 4);
+}
+
+void mddi_clock_init(unsigned num, unsigned rate)
+{
+       unsigned clock_id;
+
+       if (num == 0)
+               clock_id = PMDH_CLK;
+       else
+               clock_id = EMDH_CLK;
+
+       clock_enable(clock_id);
+       clock_set_rate(clock_id, rate);
+#ifdef PLATFORM_MSM7X30
+       clock_enable(PMDH_P_CLK);
+#endif
+}
+
+void reboot(unsigned reboot_reason)
+{
+       msm_proc_comm(PCOM_RESET_CHIP, &reboot_reason, 0);
+       for (;;)
+               ;
+}
+
+int mmc_clock_enable_disable(unsigned id, unsigned enable)
+{
+       if (enable)
+               return clock_enable(id); /*Enable mmc clock rate*/
+       else
+               return clock_disable(id); /*Disable mmc clock rate*/
+}
+
+int mmc_clock_set_rate(unsigned id, unsigned rate)
+{
+       return clock_set_rate(id, rate); /*Set mmc clock rate*/
+}
+
+int mmc_clock_get_rate(unsigned id)
+{
+       return clock_get_rate(id); /*Get mmc clock rate*/
+}
+
+int gpio_tlmm_config(unsigned config, unsigned disable)
+{
+       return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
+}
+
+int vreg_set_level(unsigned id, unsigned mv)
+{
+       return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+}
+
+int vreg_enable(unsigned id)
+{
+       unsigned enable = 1;
+       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+}
+
+int vreg_disable(unsigned id)
+{
+       unsigned enable = 0;
+       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc
       [not found] <yes>
                   ` (56 preceding siblings ...)
  2012-02-16  2:59 ` [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication mohamed.haneef at lntinfotech.com
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-02-29  0:00   ` Albert ARIBAUD
  2012-03-05 14:39   ` [U-Boot] [PATCH v2 3/5] msm7x30: Add support for msm7x30 SoC Mohamed Haneef
  2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
                   ` (33 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

        *Support for Qualcomm msm7630 soc

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
 arch/arm/cpu/armv7/msm7630/Makefile           |   59 +++
 arch/arm/cpu/armv7/msm7630/acpuclock.c        |  328 +++++++++++++
 arch/arm/cpu/armv7/msm7630/board.c            |   58 +++
 arch/arm/cpu/armv7/msm7630/config.mk          |    1 +
 arch/arm/cpu/armv7/msm7630/gpio.c             |  229 +++++++++
 arch/arm/cpu/armv7/msm7630/lowlevel_init.S    |  626 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/msm7630/timer.c            |  148 ++++++
 arch/arm/include/asm/arch-msm7630/adm.h       |   28 ++
 arch/arm/include/asm/arch-msm7630/gpio.h      |   47 ++
 arch/arm/include/asm/arch-msm7630/gpio_hw.h   |  168 +++++++
 arch/arm/include/asm/arch-msm7630/iomap.h     |   96 ++++
 arch/arm/include/asm/arch-msm7630/proc_comm.h |   42 ++
 arch/arm/include/asm/arch-msm7630/sys_proto.h |   29 ++
 13 files changed, 1859 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
 create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
 create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
 create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h

diff --git a/arch/arm/cpu/armv7/msm7630/Makefile b/arch/arm/cpu/armv7/msm7630/Makefile
new file mode 100644
index 0000000..d9dfade
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/Makefile
@@ -0,0 +1,59 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011 Nvidia Corporation.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+#CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
+#CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+
+include $(TOPDIR)/config.mk
+
+LIB    =  $(obj)lib$(SOC).o
+
+SOBJS-y        := lowlevel_init.o
+COBJS-y                := board.o
+COBJS-y                += timer.o
+COBJS-y                += acpuclock.o
+COBJS-y                += gpio.o
+
+ SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(COBJS-y) $(SOBJS-y))
+
+all:    $(obj).depend $(LIB)
+
+$(LIB):        $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/msm7630/acpuclock.c b/arch/arm/cpu/armv7/msm7630/acpuclock.c
new file mode 100644
index 0000000..035ce04
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/acpuclock.c
@@ -0,0 +1,328 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <common.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/proc_comm.h>
+#define ACPU_806MHZ            42
+#define ACPU_1024MHZ           53
+#define ACPU_1200MHZ           125
+#define ACPU_1400MHZ           73
+
+/* Macros to select PLL2 with divide by 1 */
+#define ACPU_SRC_SEL           3
+#define ACPU_SRC_DIV           0
+
+#define BIT(n)         (1 << (n))
+#define VREG_CONFIG    (BIT(7) | BIT(6))
+#define VREG_DATA      (VREG_CONFIG | (VREF_SEL << 5))
+#define VREF_SEL       1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
+#define V_STEP         (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
+#define MV(mv)         ((mv) / (!((mv) % V_STEP)))
+/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
+#define VDD_RAW(mv)    (((MV(mv) / V_STEP) - 30) | VREG_DATA)
+
+
+/* enum for SDC CLK IDs */
+enum {
+       SDC1_CLK  = 19,
+       SDC1_PCLK = 20,
+       SDC2_CLK  = 21,
+       SDC2_PCLK = 22,
+       SDC3_CLK  = 23,
+       SDC3_PCLK = 24,
+       SDC4_CLK  = 25,
+       SDC4_PCLK = 26
+};
+
+/* Zero'th entry is dummy */
+static uint8_t sdc_clk[]  = {0, SDC1_CLK,  SDC2_CLK,  SDC3_CLK,  SDC4_CLK};
+static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK};
+
+void spm_init(void)
+{
+       writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */
+       writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */
+       writel(0x00006666, MSM_SAW_BASE + 0x18);
+       /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */
+       writel(0xFF000666, MSM_SAW_BASE + 0x1C);
+       /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */
+       writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */
+       writel(0x03, MSM_SAW_BASE + 0x28);
+       /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */
+       writel(0x00, MSM_SAW_BASE + 0x2C);
+       /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */
+       writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */
+       writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */
+       writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */
+}
+
+/* Configures msmc2 voltage. vlevel is in mV */
+void msmc2_config(unsigned vlevel)
+{
+       unsigned val;
+       val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+       val &= ~0xFF;
+       val |= VDD_RAW(vlevel);
+       writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+       /* Wait for PMIC state to return to idle and for VDD to stabilize */
+       while (((readl(MSM_SAW_BASE + 0x0C) >> 20) & 0x3) != 0)
+               ;
+       udelay(160);
+}
+
+void enable_pll(unsigned num)
+{
+       unsigned reg_val;
+       reg_val = readl(PLL_ENA_REG);
+       reg_val |= (1 << num);
+       writel(reg_val, PLL_ENA_REG);
+       /* Wait until PLL is enabled */
+       while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0)
+               ;
+}
+
+void acpu_clock_init(void)
+{
+       unsigned clk, reg_clksel, reg_clkctl, src_sel;
+       /* Fixing msmc2 voltage */
+       spm_init();
+       clk = readl(PLL2_L_VAL_ADDR) & 0xFF;
+       if (clk == ACPU_806MHZ)
+               msmc2_config(1100);
+       else if (clk == ACPU_1024MHZ || clk == ACPU_1200MHZ)
+               msmc2_config(1200);
+       else if (clk == ACPU_1400MHZ)
+               msmc2_config(1250);
+       /* Enable pll 2 */
+       enable_pll(2);
+       reg_clksel = readl(SCSS_CLK_SEL);
+       /* CLK_SEL_SRC1NO */
+       src_sel = reg_clksel & 1;
+       /* Program clock source and divider. */
+       reg_clkctl = readl(SCSS_CLK_CTL);
+       reg_clkctl &= ~(0xFF << (8 * src_sel));
+       reg_clkctl |= ACPU_SRC_SEL << (4 + 8 * src_sel);
+       reg_clkctl |= ACPU_SRC_DIV << (0 + 8 * src_sel);
+       writel(reg_clkctl, SCSS_CLK_CTL);
+       /* Toggle clock source. */
+       reg_clksel ^= 1;
+       /* Program clock source selection. */
+       writel(reg_clksel, SCSS_CLK_SEL);
+}
+
+void hsusb_clock_init(void)
+{
+       int val = 0;
+       unsigned sh2_own_row2;
+       unsigned sh2_own_row2_hsusb_mask = (1 << 11);
+
+       sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG);
+       if (sh2_own_row2 & sh2_own_row2_hsusb_mask) {
+               /* USB local clock control enabled */
+               /* Set value in MD register */
+               val = 0x5DF;
+               writel(val, SH2_USBH_MD_REG);
+               /* Set value in NS register */
+               val = 1 << 8;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 11;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 9;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 13;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               /* Enable USBH_P_CLK */
+               val = 1 << 25;
+               val = val | readl(SH2_GLBL_CLK_ENA_SC);
+               writel(val, SH2_GLBL_CLK_ENA_SC);
+       } else
+               /* USB local clock control not enabled; use proc comm */
+               usb_clock_init();
+
+}
+
+void adm_enable_clock(void)
+{
+       unsigned int val = 0;
+
+       /* Enable ADM_CLK */
+       val = 1 << 5;
+       val = val | readl(SH2_GLBL_CLK_ENA_SC);
+       writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+void mdp_lcdc_clock_init(void)
+{
+       unsigned int val = 0;
+       unsigned sh2_own_apps2;
+       unsigned sh2_own_apps2_lcdc_mask = (1 << 3);
+
+       sh2_own_apps2 = readl(SH2_OWN_APPS2_BASE_REG);
+       if (sh2_own_apps2 & sh2_own_apps2_lcdc_mask) {
+               /* MDP local clock control enabled */
+               /* Select clock source and divider */
+               val = 0x29;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable MDP source clock(root) */
+               val = 1 << 11;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable graphics clock(branch) */
+               val = 1 << 9;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable MDP_P_CLK */
+               val = 1 << 6;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+               /* Enable AXI_MDP_CLK */
+               val = 1 << 29;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+               /* LCDC local clock control enabled */
+               /* Set value in MD register */
+               val = 0x1FFF9;
+               writel(val, SH2_MDP_LCDC_MD_REG);
+
+               /* Set MDP_LCDC_N_VAL in NS register */
+               val = 0xFFFA << 16;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set clock source */
+               val = 1;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set divider */
+               val = 3 << 3;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set MN counter mode */
+               val = 2 << 5;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable MN counter */
+               val = 1 << 8;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_src(root) clock */
+               val = 1 << 11;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_pclk(branch) clock */
+               val = 1 << 9;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_pad_pclk(branch) clock */
+               val = 1 << 12;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+       } else {
+               /* MDP local clock control not enabled; use proc comm */
+               mdp_clock_init(122880000);
+               /* LCDC local clock control not enabled; use proc comm */
+               lcdc_clock_init(27648000);
+       }
+}
+
+void mddi_pmdh_clock_init(void)
+{
+       unsigned int val = 0;
+       unsigned sh2_own_row1;
+       unsigned sh2_own_row1_pmdh_mask = (1 << 19);
+
+       sh2_own_row1 = readl(SH2_OWN_ROW1_BASE_REG);
+       if (sh2_own_row1 & sh2_own_row1_pmdh_mask) {
+               /* Select clock source and divider */
+               val = 1;
+               val |= (1 << 3);
+               val = val | readl(SH2_PMDH_NS_REG);
+               writel(val, SH2_PMDH_NS_REG);
+
+               /* Enable PMDH_SRC (root) signal */
+               val = 1 << 11;
+               val = val | readl(SH2_PMDH_NS_REG);
+               writel(val, SH2_PMDH_NS_REG);
+
+               /* Enable PMDH_P_CLK */
+               val = 1 << 4;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+       } else
+               /* MDDI local clock control not enabled; use proc comm */
+               mddi_clock_init(0, 480000000);
+}
+
+void ce_clock_init(void)
+{
+       unsigned int val = 0;
+
+       /* Enable CE_CLK */
+       val = 1 << 6;
+       val = val | readl(SH2_GLBL_CLK_ENA_SC);
+       writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+#ifdef CONFIG_QC_MMC
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+       uint32_t reg = 0;
+
+       if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0)
+               printf("Failure setting clock rate for MCLK - "
+                                                 "clk_rate: %d\n!", freq);
+
+       /* enable clock */
+       if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0)
+               printf("Failure enabling MMC Clock!\n");
+
+       reg |= MMC_BOOT_MCI_CLK_ENABLE;
+       reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
+       reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
+       writel(reg, MMC_BOOT_MCI_CLK);
+}
+
+/* Intialize MMC clock */
+void clock_init_mmc(uint32_t interface)
+{
+       if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0)
+               printf("Failure enabling PCLK!\n");
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/board.c b/arch/arm/cpu/armv7/msm7630/board.c
new file mode 100644
index 0000000..8dd61b4
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/board.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void set_vector_base(unsigned long addr)
+{
+       __asm__ volatile ("mcr   p15, 0, %0, c12, c0, 0" : : "r" (addr));
+}
+
+int dram_init(void)
+{
+       /* We do not initialise DRAM here. We just query the size */
+       gd->ram_size = PHYS_SDRAM_1_SIZE;
+       /* Now check it dynamically */
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init()
+{
+       __cpu_early_init();
+       return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/config.mk b/arch/arm/cpu/armv7/msm7630/config.mk
new file mode 100644
index 0000000..935a147
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/config.mk
@@ -0,0 +1 @@
+PLATFORM_CPPFLAGS += -march=armv7-a
diff --git a/arch/arm/cpu/armv7/msm7630/gpio.c b/arch/arm/cpu/armv7/msm7630/gpio.c
new file mode 100644
index 0000000..daa6d66
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/gpio.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/proc_comm.h>
+#include <asm/arch/gpio_hw.h>
+
+struct gpioregs {
+       unsigned out;
+       unsigned in;
+       unsigned int_status;
+       unsigned int_clear;
+       unsigned int_en;
+       unsigned int_edge;
+       unsigned int_pos;
+       unsigned oe;
+};
+
+static struct gpioregs GPIO_REGS[] = {
+       {
+               .out =          GPIO_OUT_0,
+               .in =           GPIO_IN_0,
+               .int_status =   GPIO_INT_STATUS_0,
+               .int_clear =    GPIO_INT_CLEAR_0,
+               .int_en =       GPIO_INT_EN_0,
+               .int_edge =     GPIO_INT_EDGE_0,
+               .int_pos =      GPIO_INT_POS_0,
+               .oe =           GPIO_OE_0,
+       },
+       {
+               .out =          GPIO_OUT_1,
+               .in =           GPIO_IN_1,
+               .int_status =   GPIO_INT_STATUS_1,
+               .int_clear =    GPIO_INT_CLEAR_1,
+               .int_en =       GPIO_INT_EN_1,
+               .int_edge =     GPIO_INT_EDGE_1,
+               .int_pos =      GPIO_INT_POS_1,
+               .oe =           GPIO_OE_1,
+       },
+       {
+               .out =          GPIO_OUT_2,
+               .in =           GPIO_IN_2,
+               .int_status =   GPIO_INT_STATUS_2,
+               .int_clear =    GPIO_INT_CLEAR_2,
+               .int_en =       GPIO_INT_EN_2,
+               .int_edge =     GPIO_INT_EDGE_2,
+               .int_pos =      GPIO_INT_POS_2,
+               .oe =           GPIO_OE_2,
+       },
+       {
+               .out =          GPIO_OUT_3,
+               .in =           GPIO_IN_3,
+               .int_status =   GPIO_INT_STATUS_3,
+               .int_clear =    GPIO_INT_CLEAR_3,
+               .int_en =       GPIO_INT_EN_3,
+               .int_edge =     GPIO_INT_EDGE_3,
+               .int_pos =      GPIO_INT_POS_3,
+               .oe =           GPIO_OE_3,
+       },
+       {
+               .out =          GPIO_OUT_4,
+               .in =           GPIO_IN_4,
+               .int_status =   GPIO_INT_STATUS_4,
+               .int_clear =    GPIO_INT_CLEAR_4,
+               .int_en =       GPIO_INT_EN_4,
+               .int_edge =     GPIO_INT_EDGE_4,
+               .int_pos =      GPIO_INT_POS_4,
+               .oe =           GPIO_OE_4,
+       },
+       {
+               .out =          GPIO_OUT_5,
+               .in =           GPIO_IN_5,
+               .int_status =   GPIO_INT_STATUS_5,
+               .int_clear =    GPIO_INT_CLEAR_5,
+               .int_en =       GPIO_INT_EN_5,
+               .int_edge =     GPIO_INT_EDGE_5,
+               .int_pos =      GPIO_INT_POS_5,
+               .oe =           GPIO_OE_5,
+       },
+       {
+               .out =          GPIO_OUT_6,
+               .in =           GPIO_IN_6,
+               .int_status =   GPIO_INT_STATUS_6,
+               .int_clear =    GPIO_INT_CLEAR_6,
+               .int_en =       GPIO_INT_EN_6,
+               .int_edge =     GPIO_INT_EDGE_6,
+               .int_pos =      GPIO_INT_POS_6,
+               .oe =           GPIO_OE_6,
+       },
+       {
+               .out =          GPIO_OUT_7,
+               .in =           GPIO_IN_7,
+               .int_status =   GPIO_INT_STATUS_7,
+               .int_clear =    GPIO_INT_CLEAR_7,
+               .int_en =       GPIO_INT_EN_7,
+               .int_edge =     GPIO_INT_EDGE_7,
+               .int_pos =      GPIO_INT_POS_7,
+               .oe =           GPIO_OE_7,
+       },
+};
+
+static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
+{
+       if (n > 150) {
+               *bit = 1 << (n - 151);
+               return GPIO_REGS + 7;
+       }
+       if (n > 133) {
+               *bit = 1 << (n - 134);
+               return GPIO_REGS + 6;
+       }
+       if (n > 106) {
+               *bit = 1 << (n - 107);
+               return GPIO_REGS + 5;
+       }
+       if (n > 94) {
+               *bit = 1 << (n - 95);
+               return GPIO_REGS + 4;
+       }
+       if (n > 67) {
+               *bit = 1 << (n - 68);
+               return GPIO_REGS + 3;
+       }
+       if (n > 43) {
+               *bit = 1 << (n - 44);
+               return GPIO_REGS + 2;
+       }
+       if (n > 15) {
+               *bit = 1 << (n - 16);
+               return GPIO_REGS + 1;
+       }
+       *bit = 1 << n;
+       return GPIO_REGS + 0;
+}
+
+int gpio_config(unsigned n, unsigned flags)
+{
+       struct gpioregs *r;
+       unsigned b;
+       unsigned v;
+
+       r = find_gpio(n, &b);
+       if (!r)
+               return -1;
+
+       v = readl(r->oe);
+       if (flags & GPIO_OUTPUT)
+               writel(v | b, r->oe);
+       else
+               writel(v & (~b), r->oe);
+       return 0;
+}
+
+void gpio_set(unsigned n, unsigned on)
+{
+       struct gpioregs *r;
+       unsigned b;
+       unsigned v;
+
+       r = find_gpio(n, &b);
+       if (r == 0)
+               return;
+
+       v = readl(r->out);
+       if (on)
+               writel(v | b, r->out);
+       else
+               writel(v & (~b), r->out);
+}
+
+int gpio_get(unsigned n)
+{
+       struct gpioregs *r;
+       unsigned b;
+
+       r = find_gpio(n, &b);
+       if (r  == 0)
+               return 0;
+       return (readl(r->in) & b) ? 1 : 0;
+}
+
+void platform_config_interleaved_mode_gpios(void)
+{
+       /* configure EB2_CS1 through GPIO86 */
+       writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
+       writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
+       /* configure the EBI2_BUSY1_N through GPIO115 */
+       writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
+       writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
+}
+
+/* Enables all gpios passed in table*/
+int platform_gpios_enable(const struct msm_gpio *table, int size)
+{
+       int rc;
+       int i;
+       const struct msm_gpio *g;
+       for (i = 0; i < size; i++) {
+               g = table + i;
+               /* Enable gpio */
+               rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
+               if (rc)
+                       goto err;
+       }
+       return 0;
+err:
+       return rc;
+}
+
diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
new file mode 100644
index 0000000..d8d5b46
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
@@ -0,0 +1,626 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <config.h>
+#include <version.h>
+
+.text
+.code 32
+
+#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
+#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
+
+/*
+ ; LVT Ring Osc counter
+ ; used to determine sense amp settings
+ ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
+*/
+.equ CLK_CTL_BASE,     0xA8600000
+.equ A_GLBL_CLK_ENA,   0x0000
+.equ A_PRPH_WEB_NS_REG,0x0080
+.equ A_MSM_CLK_RINGOSC,0x00D0
+.equ A_TCXO_CNT,       0x00D4
+.equ A_TCXO_CNT_DONE,  0x00D8
+.equ A_RINGOSC_CNT,    0x00DC
+.equ A_MISC_CLK_CTL,   0x0108
+.equ CLK_TEST,         0xA8600114
+.equ SPSS_CSR_BASE,    0xAC100000
+.equ A_SCRINGOSC,      0x0510
+
+//;; Number of TCXO cycles to count ring oscillations
+.equ TCXO_CNT_VAL,     0x100
+
+//; Halcyon addresses
+.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
+.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
+
+//; SCORPION_L1_ACC (1:0) Fuses bit location
+.equ L1_ACC_BIT_0,     12       //;12th bit of TCSR_CONF_FUSE_4
+.equ L1_ACC_BIT_1,     13       //;13th bit of TCSR_CONF_FUSE_4
+//; SCORPION_L2_ACC (2:0) Fuses bit location
+.equ L2_ACC_BIT_0,     25       //;25th bit of TCSR_CONF_FUSE_1
+.equ L2_ACC_BIT_1,     10       //;10th bit of TCSR_CONF_FUSE_4
+.equ L2_ACC_BIT_2,     11       //;11th bit of TCSR_CONF_FUSE_4
+
+//; CP15: PVR2F0 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR2F0_00,        0x00000000
+.equ PVR2F0_01,        0x04000000
+.equ PVR2F0_10,        0x08000000
+.equ PVR2F0_11,        0x0C000000
+
+//; CP15: PVR2F1 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR2F1_00,        0x00000008
+.equ PVR2F1_01,        0x00000008
+.equ PVR2F1_10,        0x00000208
+.equ PVR2F1_11,        0x00000208
+
+//; CP15: PVR0F2 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR0F2_00,        0x00000000
+.equ PVR0F2_01,        0x00000000
+.equ PVR0F2_10,        0x00000200
+.equ PVR0F2_11,        0x00000200
+
+//; CP15: PVR0F0 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR0F0_00,        0x7F000000
+.equ PVR0F0_01,        0x7F000400
+.equ PVR0F0_10,        0x7F000000
+.equ PVR0F0_11,        0x7F000400
+
+//; CP15: L2VR3F1 values according to  SCORPION_L2_ACC (2:0)
+.equ L2VR3F1_000,      0x00FFFF60
+.equ L2VR3F1_001,      0x00FFFF40
+.equ L2VR3F1_010,      0x00FFFC60
+.equ L2VR3F1_011,      0x00FFFC40
+.equ L2VR3F1_100,      0x00FCFF60
+.equ L2VR3F1_101,      0x00FCFF40
+.equ L2VR3F1_110,      0x00FCFC60
+.equ L2VR3F1_111,      0x00FCFC40
+
+
+
+
+_TEXT_BASE:
+       .word   CONFIG_SYS_TEXT_BASE    @ sdram load addr from config file
+
+.global invalidate_dcache
+invalidate_dcache:
+       mov pc, lr
+
+       .align  5
+.globl lowlevel_init
+lowlevel_init:
+       mov     pc, lr                          @ back to arch calling code
+
+.global reset_cpu
+reset_cpu:
+_loop_forever:
+        b       _loop_forever
+
+.globl SET_SA
+SET_SA:
+
+        //;--------------------------------------------------------------------
+        //; Fuse bits used to determine sense amp settings
+        //;--------------------------------------------------------------------
+
+        //; Reading L1_ACC
+        ldr    r4, = 0x0
+
+        //; Read L1_ACC_BIT_0
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L1_ACC_BIT_0
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        orr    r4, r3, r4
+
+        //; Read L1_ACC_BIT_1
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L1_ACC_BIT_1
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #1
+        orr    r4, r3, r4
+
+l1_ck_0:
+        //; if L1_[1:0] == 00
+        ldr    r5, = 0x0
+        cmp    r4, r5
+        bne    l1_ck_1
+        ldr    r0, =PVR0F0_00
+        ldr    r1, =PVR0F2_00
+        ldr    r2, =PVR2F0_00
+        ldr    r3, =PVR2F1_00
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_1:
+        //; if L1_[1:0] == 01
+        ldr    r1, = 0x01
+        cmp    r4, r1
+        bne    l1_ck_2
+        ldr    r0, =PVR0F0_01
+        ldr    r1, =PVR0F2_01
+        ldr    r2, =PVR2F0_01
+        ldr    r3, =PVR2F1_01
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_2:
+        //; if L1_[2:0] == 10
+        ldr    r1, = 0x02
+        cmp    r4, r1
+        bne    l1_ck_3
+        ldr    r0, =PVR0F0_10
+        ldr    r1, =PVR0F2_10
+        ldr    r2, =PVR2F0_10
+        ldr    r3, =PVR2F1_10
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_3:
+        //; if L1_[2:0] == 11
+        ldr    r1, = 0x03
+        cmp    r4, r1
+        ldr    r0, =PVR0F0_11
+        ldr    r1, =PVR0F2_11
+        ldr    r2, =PVR2F0_11
+        ldr    r3, =PVR2F1_11
+        b      WRITE_L1_SA_SETTINGS
+
+
+WRITE_L1_SA_SETTINGS:
+
+        //;WCP15_PVR0F0   r0
+        mcr    p15, 0x0, r0, c15, c15, 0x0   //; write R0 to PVR0F0
+
+        //;WCP15_PVR0F2   r1
+        mcr    p15, 0x0, r1, c15, c15, 0x2   //; write R1 to PVR0F2
+
+        //;WCP15_PVR2F0   r2
+        mcr    p15, 0x2, r2, c15, c15, 0x0   //; write R2 to PVR2F0
+
+        // Disable predecode repair cache on certain Scorpion revisions
+        // (Raptor V2 and earlier, or Halcyon V1)
+        mrc    p15, 0, r1, c0, c0, 0      //; MIDR
+        BIC    r2, r1, #0xf0              //; check for Halcyon V1
+        ldr    r4, =0x511f0000
+        cmp    r2, r4
+        bne    PVR2F1
+
+DPRC:
+        mrc    p15, 0, r1, c15, c15, 2    //; PVR0F2
+        orr    r1, r1, #0x10              //; enable bit 4
+        mcr    p15, 0, r1, c15, c15, 2    //; disable predecode repair cache
+
+PVR2F1:
+        //;WCP15_PVR2F1   r3
+        mcr    p15, 0x2, r3, c15, c15, 0x1   //; write R3 to PVR2F1
+
+        //; Reading L2_ACC
+        ldr    r4, = 0x0
+
+        //; Read L2_ACC_BIT_0
+        ldr    r1, =TCSR_CONF_FUSE_1
+        ldr    r2, =L2_ACC_BIT_0
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        orr    r4, r3, r4
+
+        //; Read L2_ACC_BIT_1
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L2_ACC_BIT_1
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #1
+        orr    r4, r3, r4
+
+        //; Read L2_ACC_BIT_2
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L2_ACC_BIT_2
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #2
+        orr    r4, r3, r4
+
+l2_ck_0:
+        //; if L2_[2:0] == 000
+        ldr    r5, = 0x0
+        cmp    r4, r5
+        bne    l2_ck_1
+        ldr    r0, =L2VR3F1_000
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_1:
+        //; if L2_[2:0] == 001
+        ldr     r5, = 0x1
+        cmp     r4, r5
+        bne     l2_ck_2
+        ldr     r0, =L2VR3F1_001
+        b       WRITE_L2_SA_SETTINGS
+
+l2_ck_2:
+        //; if L2_[2:0] == 010
+        ldr    r5, = 0x2
+        cmp    r4, r5
+        bne    l2_ck_3
+        ldr    r0, =L2VR3F1_010
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_3:
+        //; if L2_[2:0] == 011
+        ldr    r5, = 0x3
+        cmp    r4, r5
+        bne    l2_ck_4
+        ldr    r0, =L2VR3F1_011
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_4:
+        //; if L2_[2:0] == 100
+        ldr    r5, = 0x4
+        cmp    r4, r5
+        bne    l2_ck_5
+        ldr    r0, =L2VR3F1_100
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_5:
+        //; if L2_[2:0] == 101
+        ldr    r5, = 0x5
+        cmp    r4, r5
+        bne    l2_ck_6
+        ldr    r0, =L2VR3F1_101
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_6:
+        //; if L2_[2:0] == 110
+        ldr    r5, = 0x6
+        cmp    r4, r5
+        bne    l2_ck_7
+        ldr    r0, =L2VR3F1_110
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_7:
+        //; if L2_[2:0] == 111
+        ldr    r5, = 0x7
+        cmp    r4, r5
+        ldr    r0, =L2VR3F1_111
+        b      WRITE_L2_SA_SETTINGS
+
+WRITE_L2_SA_SETTINGS:
+        //;WCP15_L2VR3F1  r0
+        mcr    p15, 0x3, r0, c15, c15, 0x1     //;write r0 to L2VR3F1
+       DSB
+       ISB
+
+        ldr    r0, =0                   //;make sure the registers we touched
+        ldr    r1, =0                   //;are cleared when we return
+        ldr    r2, =0
+        ldr    r3, =0
+        ldr    r4, =0
+        ldr    r5, =0
+
+       mrs     r0, cpsr
+       orr     r0, r0, #(1<<7)
+       msr     cpsr_c, r0
+
+       //; routine complete
+       pop     {r5-r12,pc}
+
+.ltorg
+
+.globl __cpu_early_init
+__cpu_early_init:
+
+        //; Zero out r0 for use throughout this code. All other GPRs
+        //; (r1-r3) are set throughout this code to help establish
+        //; a consistent startup state for any code that follows.
+        //; Users should add code@the end of this routine to establish
+        //; their own stack address (r13), add translation page tables, enable
+        //; the caches, etc.
+       push    {r5-r12,r14}
+        mov    r0,  #0x0
+
+
+        //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
+        //;   API to dynamically configure cache for slow/nominal/fast parts
+
+        //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
+       //; once per bank)
+        //; This must be done early in code (prior to enabling the caches)
+        mov    r1, #0x2
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank D ([15:14] == 2'b00)
+        orr    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank C ([15:14] == 2'b01)
+        add    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank B ([15:14] == 2'b10)
+        add    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank A ([15:14] == 2'b11)
+
+        //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
+        //; and have all address bits (AM) participate.
+        //; Different settings can be used to improve performance
+        // movW   r1, #0x01FF
+.word 0xe30011ff  // hardcoded movW instruction due to lack of compiler support
+        // movT   r1, #0x01FF
+.word 0xe34011ff  // hardcoded movT instruction due to lack of compiler support
+        mcr    p15, 7, r1, c15, c0, 2   //; WCP15_BPCR
+
+
+        //; Initialize all I$ Victim Registers to 0 for startup
+        mcr    p15, 0, r0, c9, c1, 0    //; WCP15_ICVIC0    r0
+        mcr    p15, 0, r0, c9, c1, 1    //; WCP15_ICVIC1    r0
+        mcr    p15, 0, r0, c9, c1, 2    //; WCP15_ICVIC2    r0
+        mcr    p15, 0, r0, c9, c1, 3    //; WCP15_ICVIC3    r0
+        mcr    p15, 0, r0, c9, c1, 4    //; WCP15_ICVIC4    r0
+        mcr    p15, 0, r0, c9, c1, 5    //; WCP15_ICVIC5    r0
+        mcr    p15, 0, r0, c9, c1, 6    //; WCP15_ICVIC5    r0
+        mcr    p15, 0, r0, c9, c1, 7    //; WCP15_ICVIC7    r0
+
+        //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
+        mcr    p15, 1, r0, c9, c1, 0    //; WCP15_ICFLOOR0  r0
+        mcr    p15, 1, r0, c9, c1, 1    //; WCP15_ICFLOOR1  r0
+        mcr    p15, 1, r0, c9, c1, 2    //; WCP15_ICFLOOR2  r0
+        mcr    p15, 1, r0, c9, c1, 3    //; WCP15_ICFLOOR3  r0
+        mcr    p15, 1, r0, c9, c1, 4    //; WCP15_ICFLOOR4  r0
+        mcr    p15, 1, r0, c9, c1, 5    //; WCP15_ICFLOOR5  r0
+        mcr    p15, 1, r0, c9, c1, 6    //; WCP15_ICFLOOR6  r0
+        mcr    p15, 1, r0, c9, c1, 7    //; WCP15_ICFLOOR7  r0
+
+        //; Initialize all D$ Victim Registers to 0
+        mcr    p15, 2, r0, c9, c1, 0    //; WP15_DCVIC0    r0
+        mcr    p15, 2, r0, c9, c1, 1    //; WP15_DCVIC1    r0
+        mcr    p15, 2, r0, c9, c1, 2    //; WP15_DCVIC2    r0
+        mcr    p15, 2, r0, c9, c1, 3    //; WP15_DCVIC3    r0
+        mcr    p15, 2, r0, c9, c1, 4    //; WP15_DCVIC4    r0
+        mcr    p15, 2, r0, c9, c1, 5    //; WP15_DCVIC5    r0
+        mcr    p15, 2, r0, c9, c1, 6    //; WP15_DCVIC6    r0
+        mcr    p15, 2, r0, c9, c1, 7    //; WP15_DCVIC7    r0
+
+        //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
+        mcr    p15, 3, r0, c9, c1, 0    //; WCP15_DCFLOOR0  r0
+        mcr    p15, 3, r0, c9, c1, 1    //; WCP15_DCFLOOR1  r0
+        mcr    p15, 3, r0, c9, c1, 2    //; WCP15_DCFLOOR2  r0
+        mcr    p15, 3, r0, c9, c1, 3    //; WCP15_DCFLOOR3  r0
+        mcr    p15, 3, r0, c9, c1, 4    //; WCP15_DCFLOOR4  r0
+        mcr    p15, 3, r0, c9, c1, 5    //; WCP15_DCFLOOR5  r0
+        mcr    p15, 3, r0, c9, c1, 6    //; WCP15_DCFLOOR6  r0
+        mcr    p15, 3, r0, c9, c1, 7    //; WCP15_DCFLOOR7  r0
+
+        //; Initialize ASID to zero
+        mcr    p15, 0, r0, c13, c0, 1   //; WCP15_CONTEXTIDR r0
+
+        //; ICIALL to invalidate entire I-Cache
+        mcr    p15, 0, r0, c7, c5, 0    //; ICIALLU
+
+        //; DCIALL to invalidate entire D-Cache
+        mcr    p15, 0, r0, c9, c0, 6    //; DCIALL  r0
+
+       //; Initialize ADFSR to zero
+        mcr    p15, 0, r0, c5, c1, 0    //; ADFSR   r0
+
+       //; Initialize EFSR to zero
+        mcr    p15, 7, r0, c15, c0, 1   //; EFSR    r0
+
+        //; The VBAR (Vector Base Address Register) should be initialized
+        //; early in your code. We are setting it to zero
+        mcr    p15, 0, r0, c12, c0, 0   //; WCP15_VBAR  r0
+
+        //; Ensure the mcr's above have completed their operation
+       //; before continuing
+        DSB
+        ISB
+
+        //; Setup CCPR - Cache Coherency Policy Register
+        //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
+        //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
+        movw   r2, #0x88
+        mcr    p15, 0, r2, c10, c4, 2
+
+        //;-------------------------------------------------------------------
+        //; There are a number of registers that must be set prior to enabling
+        //; the MMU. The DCAR is one of these registers. We are setting
+        //; it to zero (no access) to easily detect improper setup in subsequent
+        //; code sequences
+        //;-------------------------------------------------------------------
+        //; Setup DACR (Domain Access Control Register) to zero
+        mcr    p15, 0, r0, c3, c0, 0    //; WCP15_DACR  r0
+
+        //; Setup DCLKCR to allow normal D-Cache line fills
+        mcr    p15, 1, r0, c9, c0, 7    //; WCP15_DCLKCR r0
+
+        //; Setup the TLBLKCR
+        //; Victim = 6'b000000; Floor = 6'b000000;
+        //; IASIDCFG =
+       //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
+        mov    r1, #0x02
+        mcr    p15, 0, r1, c10, c1, 3     //; WCP15_TLBLKCR  r1
+
+        //;Make sure TLBLKCR is complete before continuing
+        ISB
+
+        //; Invalidate the UTLB
+        mcr    p15, 0, r0, c8, c7, 0      //; UTLBIALL
+
+        //; Make sure UTLB request has been presented to macro before continuing
+        ISB
+
+SYSI2:
+        //; setup L2CR1 to some default Instruction and data prefetching values
+        //; Users may want specific settings for various performance
+       //; enhancements
+        //; In Halcyon we do not have broadcasting barriers. So we need to turn
+        //  ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
+        ldr    r2, =0x133
+        mcr    p15, 3, r2, c15, c0, 3     //; WCP15_L2CR1  r0
+
+
+        //; Enable Z bit to enable branch prediction (default is off)
+        mrc    p15, 0, r2, c1, c0, 0      //; RCP15_SCTLR  r2
+        orr    r2, r2, #0x00000800
+        mcr    p15, 0, r2, c1, c0, 0      //; WCP15_SCTLR  r2
+
+        //; Make sure Link stack is initialized with branch and links to
+       //; sequential addresses
+        //; This aids in creating a predictable startup environment
+        bl     SEQ1
+SEQ1:   bl     SEQ2
+SEQ2:   bl     SEQ3
+SEQ3:   bl     SEQ4
+SEQ4:   bl     SEQ5
+SEQ5:   bl     SEQ6
+SEQ6:   bl     SEQ7
+SEQ7:   bl     SEQ8
+SEQ8:
+
+        //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
+        //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
+       //;debug registers
+        //; Writing anything but the "secret code" to the DBGOSLAR clears the
+       //;DBGOSLSR[LOCK] bit
+        mcr    p14, 0, r0, c1, c0, 4       //; WCP14_DBGOSLAR r0
+
+
+        //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
+        //; Any read to DBGPRSR clear the STICKYPD bit
+        //; ISB guarantees the read completes before attempting to
+        //; execute a CP14 instruction.
+        mrc    p14, 0, r3, c1, c5, 4       //; RCP14_DBGPRSR r3
+        ISB
+
+        //; Initialize the Watchpoint Control Registers to zero (optional)
+        //;;; mcr    p14, 0, r0, c0, c0, 7       ; WCP14_DBGWCR0  r0
+        //;;; mcr    p14, 0, r0, c0, c1, 7       ; WCP14_DBGWCR1  r0
+
+
+        //;--------------------------------------------------------------------
+        //; The saved Program Status Registers (SPSRs) should be setup
+        //; prior to any automatic mode switches. The following
+        //; code sets these registers up to a known state. Users will need to
+        //; customize these settings to meet their needs.
+        //;--------------------------------------------------------------------
+        mov    r2,  #0x1f
+        mov    r1,  #0xd7                 //;ABT mode
+        msr    cpsr_c, r1                 //;ABT mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xdb                 //;UND mode
+        msr    cpsr_c, r1                 //;UND mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd1                 //;FIQ mode
+        msr    cpsr_c, r1                 //;FIQ mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd2                 //;IRQ mode
+        msr    cpsr_c, r1                 //;IRQ mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd6                 //;Monitor mode
+        msr    cpsr_c, r1                 //;Monitor mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd3                 //;SVC mode
+        msr    cpsr_c, r1                 //;SVC mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+
+
+        //;--------------------------------------------------------------------
+        //; Enabling Error reporting is something users may want to do at
+        //; some other point in time. We have chosen some default settings
+        //; that should be reviewed. Most of these registers come up in an
+        //; unpredictable state after reset.
+        //;--------------------------------------------------------------------
+//;Start of error and control setting
+
+        //; setup L2CR0 with various L2/TCM control settings
+        //; enable out of order bus attributes and error reporting
+        //; this register comes up unpredictable after reset
+        // movw   r1, #0x0F0F
+.word 0xe3001f0f  // hardcoded movw instruction due to lack of compiler support
+        // movT   r1, #0xC005
+.word 0xe34c1005  // hardcoded movw instruction due to lack of compiler support
+        mcr    p15, 3, r1, c15, c0, 1    //; WCP15_L2CR0  r1
+
+        //; setup L2CPUCR
+        //; mov    r2, #0xFF
+        //; Enable I and D cache parity
+        //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
+        //;tag, and data parity errors
+        mov    r2, #0xe0
+        mcr    p15, 3, r2, c15, c0, 2    //; WCP15_L2CPUCR  r2
+
+        //; setup SPCR
+        //; enable all error reporting
+       //;(reset value is unpredicatble for most bits)
+        mov    r3, #0x0F
+        mcr    p15, 0, r3, c9, c7, 0     //; WCP15_SPCR  r3
+
+        //; setup DMACHCRs (reset value unpredictable)
+        //; control setting and enable all error reporting
+        mov    r1, #0x0F
+
+        //; DMACHCR0 = 0000000F
+        mov    r2, #0x00                  //; channel 0
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR1 = 0000000F
+        mov    r2, #0x01                  //; channel 1
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR2 = 0000000F
+        mov    r2, #0x02                  //; channel 2
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR3 = 0000000F
+        mov    r2, #0x03                  //; channel 3
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; Set ACTLR (reset unpredictable)
+        //; Set AVIVT control, error reporting, etc.
+        //; mov   r3, #0x07
+        //; Enable I and D cache parity
+        //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
+        //;ACTLR[5:4] = 2'h3 - enable parity
+        //;ACTLR[19:18] =2'h3 - always generate and
+       //;check parity(when MMU disabled).
+        //;Value to be written #0xC0037
+        // movw   r3, #0x0037
+.word 0xe3003037  // hardcoded movw instruction due to lack of compiler support
+        // movT   r3, #0x000C
+.word 0xe340300c  // hardcoded movw instruction due to lack of compiler support
+        mcr    p15, 0, r3, c1, c0, 1      //; WCP15_ACTLR  r3
+
+//;End of error and control setting
+
+        //;---------------------------------------------------------------------
+        //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
+        //; This is required for power saving whether the ETM is used or not.
+        //;---------------------------------------------------------------------
+
+        //;Clear ETMOSLSR[LOCK] bit
+        mov    r1, #0x00000000
+        mcr    p14, 1, r1, c1, c0, 4        //; WCP14_ETMOSLAR      r1
+
+        //;Clear ETMPDSR[STICKYPD] bit
+        mrc    p14, 1, r2, c1, c5, 4        //; RCP14_ETMPDSR       r2
+        b       SET_SA
+
+
+.ltorg
diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
new file mode 100644
index 0000000..1c3f7ba
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/timer.c
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Moahmmed Khasim <khasim@ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <config.h>
+#include <common.h>
+#include <asm/types.h>
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN        2
+#define GPT_ENABLE_EN                     1
+#define DGT_ENABLE_CLR_ON_MATCH_EN        2
+#define DGT_ENABLE_EN                     1
+
+#define SPSS_TIMER_STATUS_DGT_EN    (1 << 0)
+
+
+#define READ_TIMER    readl(GPT_COUNT_VAL)
+
+static ulong timestamp;
+static ulong lastinc;
+#define DGT_HZ 6750000         /* Uses LPXO/4 (27.0 MHz / 4) */
+
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+       uint32_t val = 0;
+
+       /* Disable timer */
+       writel(0, DGT_ENABLE);
+
+       /* Check for the hardware revision */
+       val = readl(HW_REVISION_NUMBER);
+       val = (val >> 28) & 0x0F;
+       if (val >= 1)
+               writel(1, DGT_CLK_CTL);
+       return 0;
+}
+
+
+ulong get_timer(ulong base)
+{
+       return get_timer_masked() - base;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay(unsigned long usecs)
+{
+       unsigned int val;
+       usecs = (usecs * 33 + 1000 - 33) / 1000;
+
+       writel(0, GPT_CLEAR);
+       writel(0, GPT_ENABLE);
+       do {
+               val = 0;
+               val = readl(GPT_COUNT_VAL);
+       } while (val != 0);
+
+       writel(GPT_ENABLE_EN, GPT_ENABLE);
+       do {
+               val = 0;
+               val = readl(GPT_COUNT_VAL);
+       } while (val < usecs) ;
+
+       writel(0, GPT_ENABLE);
+       writel(0, GPT_CLEAR);
+
+}
+
+void reset_timer_masked(void)
+{
+       /* reset time */
+       lastinc = READ_TIMER;   /* capure current decrementer value time */
+       timestamp = 0;          /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+       ulong now = READ_TIMER; /* current tick value */
+
+       if (lastinc <= now) {   /* normal mode (non roll) */
+               /* normal mode */
+               timestamp += now - lastinc;
+               /* move stamp forward with absolute diff ticks */
+       } else {                /* we have overflow of the count down timer */
+               timestamp += now + (TIMER_LOAD_VAL - lastinc);
+       }
+       lastinc = now;
+
+       return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+       return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+       return 19200000;
+}
diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
new file mode 100644
index 0000000..0e8af85
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/adm.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ADM_H
+#define __ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN         8
+#define ADM_SD          2
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
new file mode 100644
index 0000000..af6ddaa
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __GPIO_H
+#define __GPIO_H
+
+#ifndef GPIO_INPUT
+#define GPIO_INPUT     0x0000
+#endif
+#ifndef GPIO_OUTPUT
+#define GPIO_OUTPUT    0x0001
+#endif
+
+#define GPIO_LEVEL     0x0000
+#define GPIO_EDGE      0x0010
+
+#define GPIO_RISING    0x0020
+#define GPIO_FALLING   0x0040
+
+#define GPIO_HIGH      0x0020
+#define GPIO_LOW       0x0040
+
+#define GPIO_PULLUP    0x0100
+#define GPIO_PULLDOWN  0x0200
+
+int gpio_config(unsigned nr, unsigned flags);
+void gpio_set(unsigned nr, unsigned on);
+int gpio_get(unsigned nr);
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
new file mode 100644
index 0000000..c8244d8
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __GPIO_HW_H
+#define __GPIO_HW_H
+
+#define MSM_GPIO1_BASE 0xAC001000
+#define MSM_GPIO2_BASE 0xAC101000
+
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  43-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-44  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 133-107 */
+#define GPIO_OUT_6         GPIO1_REG(0xC4)  /* gpio 150-134 */
+#define GPIO_OUT_7         GPIO1_REG(0x214)  /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+#define GPIO_OE_6          GPIO1_REG(0xC8)
+#define GPIO_OE_7          GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+#define GPIO_IN_6          GPIO1_REG(0xCC)
+#define GPIO_IN_7          GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6     GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7     GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6      GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7      GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x234)
+
+
+#define GPIO_OUT_VAL_REG_BASE     0xABC00000
+#define GPIO_ALT_FUNC_PAGE_REG    (GPIO_OUT_VAL_REG_BASE + 0x20)
+#define GPIO_ALT_FUNC_CFG_REG     (GPIO_OUT_VAL_REG_BASE + 0x24)
+
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL    0
+#define GPIO_PULL_DOWN  1
+#define GPIO_KEEPER     2
+#define GPIO_PULL_UP    3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA        0
+#define GPIO_4MA        1
+#define GPIO_6MA        2
+#define GPIO_8MA        3
+#define GPIO_10MA       4
+#define GPIO_12MA       5
+#define GPIO_14MA       6
+#define GPIO_16MA       7
+
+#define GPIO38_GPIO_CNTRL      0x175
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE     0
+#define GPIO_DISABLE    1
+
+#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
+       ((((gpio) & 0x3FF) << 4)        |   \
+       ((func) & 0xf)                  |   \
+       (((dir) & 0x1) << 14)           |   \
+       (((pull) & 0x3) << 15)          |   \
+       (((drvstr) & 0xF) << 17))
+
+/**
+ * struct msm_gpio - GPIO pin description
+ * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
+ * @label - textual label
+ *
+ * Usually, GPIO's are operated by sets.
+ * This struct accumulate all GPIO information in single source
+ * and facilitete group operations provided by msm_gpios_xxx()
+ */
+struct msm_gpio {
+       unsigned gpio_cfg;
+       const char *label;
+};
+
+/**
+ * extract GPIO pin from bit-field used for gpio_tlmm_config
+ */
+#define GPIO_PIN(gpio_cfg)    (((gpio_cfg) >>  4) & 0x3ff)
+#define GPIO_FUNC(gpio_cfg)   (((gpio_cfg) >>  0) & 0xf)
+#define GPIO_DIR(gpio_cfg)    (((gpio_cfg) >> 14) & 0x1)
+#define GPIO_PULL(gpio_cfg)   (((gpio_cfg) >> 15) & 0x3)
+#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
new file mode 100644
index 0000000..186c6c2
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/iomap.h
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __IOMAP_H_
+#define __IOMAP_H_
+
+#define MSM_UART1_BASE 0xACA00000
+#define MSM_UART2_BASE 0xACB00000
+#define MSM_UART3_BASE 0xACC00000
+
+#define MSM_VIC_BASE   0xC0080000
+#define MSM_TMR_BASE   0xC0100000
+
+#define MSM_GPT_BASE      (MSM_TMR_BASE + 0x04)
+#define MSM_DGT_BASE      (MSM_TMR_BASE + 0x24)
+#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
+
+#define GPT_REG(off)      (MSM_GPT_BASE + (off))
+#define DGT_REG(off)      (MSM_DGT_BASE + (off))
+
+#define GPT_MATCH_VAL      GPT_REG(0x0000)
+#define GPT_COUNT_VAL      GPT_REG(0x0004)
+#define GPT_ENABLE         GPT_REG(0x0008)
+#define GPT_CLEAR          GPT_REG(0x000C)
+
+#define DGT_MATCH_VAL      DGT_REG(0x0000)
+#define DGT_COUNT_VAL      DGT_REG(0x0004)
+#define DGT_ENABLE         DGT_REG(0x0008)
+#define DGT_CLEAR          DGT_REG(0x000C)
+#define DGT_CLK_CTL        DGT_REG(0x0010)
+
+#define HW_REVISION_NUMBER   0xABC00270
+
+#define MSM_CSR_BASE    0xC0100000
+#define MSM_GCC_BASE   0xC0182000
+
+#define MSM_SDC1_BASE   0xA0400000
+#define MSM_SDC2_BASE   0xA0500000
+#define MSM_SDC3_BASE   0xA3000000
+#define MSM_SDC4_BASE   0xA3100000
+
+#define MSM_SHARED_BASE      0x00100000
+#define MSM_CLK_CTL_BASE        0xAB800000
+#define MSM_CLK_CTL_SH2_BASE    0xABA01000
+
+#define REG_BASE(off)           (MSM_CLK_CTL_BASE + (off))
+#define REG_SH2_BASE(off)       (MSM_CLK_CTL_SH2_BASE + (off))
+
+#define SCSS_CLK_CTL            0xC0101004
+#define SCSS_CLK_SEL            0xC0101008
+
+#define MSM_USB_BASE                   0xA3600000
+#define MSM_CRYPTO_BASE                        0xA8400000
+
+#define SH2_USBH_MD_REG         REG_SH2_BASE(0x2BC)
+#define SH2_USBH_NS_REG         REG_SH2_BASE(0x2C0)
+
+#define SH2_MDP_NS_REG          REG_SH2_BASE(0x14C)
+#define SH2_MDP_LCDC_MD_REG     REG_SH2_BASE(0x38C)
+#define SH2_MDP_LCDC_NS_REG     REG_SH2_BASE(0x390)
+#define SH2_MDP_VSYNC_REG       REG_SH2_BASE(0x460)
+#define SH2_PMDH_NS_REG         REG_SH2_BASE(0x8C)
+
+#define SH2_GLBL_CLK_ENA_SC     REG_SH2_BASE(0x3BC)
+#define SH2_GLBL_CLK_ENA_2_SC   REG_SH2_BASE(0x3C0)
+
+#define SH2_OWN_ROW1_BASE_REG   REG_BASE(0x041C)
+#define SH2_OWN_ROW2_BASE_REG   REG_BASE(0x0424)
+#define SH2_OWN_APPS2_BASE_REG  REG_BASE(0x0414)
+
+#define MSM_ADM_BASE            0xAC200000
+#define MSM_ADM_SD_OFFSET       0x00100400
+
+#define MSM_SAW_BASE            0xC0102000
+
+#define PLL_ENA_REG             REG_SH2_BASE(0x0264)
+#define PLL2_STATUS_BASE_REG    REG_BASE(0x0350)
+#define PLL2_L_VAL_ADDR         REG_BASE(0x033C)
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
new file mode 100644
index 0000000..3df08b9
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __PROC_COMM_H_
+#define __PROC_COMM_H_
+
+void usb_clock_init(void);
+void lcdc_clock_init(unsigned rate);
+void mdp_clock_init(unsigned rate);
+void uart3_clock_init(void);
+void uart2_clock_init(void);
+void uart1_clock_init(void);
+void mddi_clock_init(unsigned num, unsigned rate);
+void reboot(unsigned reboot_reason);
+int mmc_clock_enable_disable(unsigned id, unsigned enable);
+int mmc_clock_set_rate(unsigned id, unsigned rate);
+int mmc_clock_get_rate(unsigned id);
+int gpio_tlmm_config(unsigned config, unsigned disable);
+int vreg_set_level(unsigned id, unsigned mv);
+int vreg_enable(unsigned id);
+int vreg_disable(unsigned id);
+
+#endif
+
+
diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
new file mode 100644
index 0000000..c679d92
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void pll8_enable(void);
+void clock_init(void);
+void __cpu_early_init(void);
+
+#endif
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 4/5] Add support for mmc read and writes
       [not found] <yes>
                   ` (57 preceding siblings ...)
  2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-02-29  0:03   ` Albert ARIBAUD
  2012-03-05 14:40   ` [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller Mohamed Haneef
  2012-02-16  2:59 ` [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board mohamed.haneef at lntinfotech.com
                   ` (32 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

        *Support for msm7x30 mmc read and writes

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
 arch/arm/include/asm/arch-msm7630/mmc.h |  399 +++++++++++++++++++++
 drivers/mmc/Makefile                    |    1 +
 drivers/mmc/qc_mmc.c                    |  584 +++++++++++++++++++++++++++++++
 3 files changed, 984 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
 create mode 100644 drivers/mmc/qc_mmc.c

diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..949e43c
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,399 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#ifndef MMC_SLOT
+#define MMC_SLOT            0
+#endif
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER                 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN            (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF               0x00
+#define MMC_BOOT_MCI_PWR_UP                0x01
+#define MMC_BOOT_MCI_PWR_ON                0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN            (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF               0x00
+#define MMC_BOOT_MCI_PWR_UP                0x02
+#define MMC_BOOT_MCI_PWR_ON                0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK                  0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE           (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE          (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE     (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT    0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT    (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT    (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW         (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT       (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING       0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING        (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK      (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK      (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT          0
+#define MMC_BOOT_BUS_WIDTH_4_BIT          2
+#define MMC_BOOT_BUS_WIDTH_8_BIT          3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT              0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD                   0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE         (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP          (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT        (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING          (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE           (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA         (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD          (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT         (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE       (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE      (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD               0x010
+
+#define MMC_BOOT_MCI_RESP_0                 0x014
+#define MMC_BOOT_MCI_RESP_1                 0x018
+#define MMC_BOOT_MCI_RESP_2                 0x01C
+#define MMC_BOOT_MCI_RESP_3                 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER             0x024
+#define MMC_BOOT_MCI_DATA_LENGTH            0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL               0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE          (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR             (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE            (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE       (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS          4
+#define MMC_BOOT_MCI_DATA_COUNT            0x030
+#define MMC_BOOT_MCI_STATUS                0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL    (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL   (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT     (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT    (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN       (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN       (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END    (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT        (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END        (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR   (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END    (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE      (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE       (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE       (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL   (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL   (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL    (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL    (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY   (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY   (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL   (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL   (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR       (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE       (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL    (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP    (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT     (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS        (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+               MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+               MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+               MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+               MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+               MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+               MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+               MMC_BOOT_MCI_STAT_CMD_SENT| \
+               MMC_BOOT_MCI_STAT_DATA_END| \
+               MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+               MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+               MMC_BOOT_MCI_SDIO_INTR_CLR| \
+               MMC_BOOT_MCI_STAT_PROG_DONE| \
+               MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+               MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR                  0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR     (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR    (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR      (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR     (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR      (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR       (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR     (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR         (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR         (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR    (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR     (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR        (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR        (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR   (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR      (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0             0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK    (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK   (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK     (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK    (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK      (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK      (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK    (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK        (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK        (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK   (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK    (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK      (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK       (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK       (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK   (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK   (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK    (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK    (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK   (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK   (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK   (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK   (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK        (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK       (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK   (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK   (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK    (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1              0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT            0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER              0x0058
+
+#define MMC_BOOT_MCI_FIFO                   0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19                (1 << 7)
+#define MMC_BOOT_OCR_27_36                (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE             (2 << 29)
+#define MMC_BOOT_OCR_BUSY                 (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST                (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP         (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS              (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER       (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR         (1 << 3)
+#define MMC_BOOT_R1_APP_CMD               (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA          (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE       (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY        (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT      (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY       (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN       (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA       (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV        (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG        (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS        (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET           (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED     (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP         (1 << 15)
+#define MMC_BOOT_R1_ERROR                 (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR              (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED       (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD           (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR           (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL      (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED        (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION          (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM           (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR         (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR         (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR              (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE          (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS                0
+#define MMC_BOOT_E_FAILURE                1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT                2
+#define MMC_BOOT_E_INVAL                  3
+#define MMC_BOOT_E_CRC_FAIL               4
+#define MMC_BOOT_E_INIT_FAIL              5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH      6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL       7
+#define MMC_BOOT_E_NOT_SUPPORTED          8
+#define MMC_BOOT_E_CARD_BUSY              9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL         10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL        11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL       12
+#define MMC_BOOT_E_CID_DECODE_FAIL        13
+#define MMC_BOOT_E_BLOCKLEN_ERR           14
+#define MMC_BOOT_E_ADDRESS_ERR            15
+#define MMC_BOOT_E_DATA_CRC_FAIL          16
+#define MMC_BOOT_E_DATA_TIMEOUT           17
+#define MMC_BOOT_E_RX_OVRRUN              18
+#define MMC_BOOT_E_VREG_SET_FAILED        19
+#define MMC_BOOT_E_GPIO_CFG_FAIL          20
+#define MMC_BOOT_E_DATA_ADM_ERR           21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE             0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING       185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH       183
+
+#define MMC_BOOT_EXT_USER_WP              171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF      175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE       221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE    224
+
+#define MMC_BOOT_US_PERM_WP_EN            2
+#define MMC_BOOT_US_PWR_WP_DIS            3
+
+#define MMC_BOOT_US_PERM_WP_DIS           (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN             1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED      0x000001AA
+#define MMC_BOOT_SD_NEG_OCR               0x00FF8000
+#define MMC_BOOT_SD_HC_HCS                0x40000000
+#define MMC_BOOT_SD_DEV_READY             0x80000000
+#define MMC_BOOT_SD_SWITCH_HS             0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK          0
+#define MMC_BOOT_XFER_MODE_STREAM         1
+#define MMC_BOOT_PROGRAM_ENABLED          2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY    1000
+#define MMC_BOOT_RD_BLOCK_LEN         512
+#define MMC_BOOT_WR_BLOCK_LEN         512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH       16
+#define MMC_BOOT_MCI_HFIFO_COUNT      (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE        (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN        0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ                400000
+#define MMC_CLK_144KHZ                144000
+#define MMC_CLK_20MHZ                 20000000
+#define MMC_CLK_24MHZ                 24000000
+#define MMC_CLK_25MHZ                 25000000
+#define MMC_CLK_26MHZ                 26000000
+#define MMC_CLK_48MHZ                 48000000
+#define MMC_CLK_50MHZ                 49152000
+#define MMC_CLK_52MHZ                 52000000
+
+#define MMC_CLK_ENABLE      1
+#define MMC_CLK_DISABLE     0
+
+#if 0
+#define MSM_SDC1_BASE       0x12400000
+#define MSM_SDC2_BASE       0x12140000
+#define MSM_SDC3_BASE       0x12180000
+#define MSM_SDC4_BASE       0x121C0000
+#endif
+struct mmc_priv {
+       unsigned int instance;
+       unsigned int base;
+       unsigned int rd_timeout_ns;     /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+                                       struct mmc_cmd *cmd,
+                                       struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
 COBJS-$(CONFIG_SDHCI) += sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o

 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..7b7a1ed
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+#ifndef NULL
+#define NULL        0
+#endif
+
+#define MMC_BOOT_DATA_READ     0
+#define MMC_BOOT_DATA_WRITE    1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+       return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+       if (mmc == NULL)
+               return MMC_BOOT_E_INVAL;
+
+       /* todo: Add a check for HC, only if HC do this.
+        * If not, taac and nsac must be taken into account
+        */
+       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
+       debug(" Read timeout set: %d ns\n",
+       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+       if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+               return MMC_BOOT_E_BLOCKLEN_ERR;
+
+       /* Misaligned address not matching block length */
+       if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+               return MMC_BOOT_E_ADDRESS_ERR;
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+               /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+                * was detected by card/device during the data transfer
+                */
+       if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+               mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+               /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+                * exceeded the data timeout period without completing the
+                * transfer
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+               mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+               /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+                * receive data from the card before empty storage for new
+                * received data was available.
+                * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+                * the data xfer.
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+                * so no need to verify for now
+                */
+               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+               /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+                * data to the card before new data for sending was available.
+                * Verify that bit FLOW_ENA in MCI_CLK
+                * is set to 1 during the data xfer.
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+                * so skipping it now
+                */
+               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+       return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
+                                               unsigned int  data_len,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       unsigned int mmc_status = 0;
+       unsigned int mmc_count = 0;
+       unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+                                       MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \
+                                       MMC_BOOT_MCI_STAT_RX_OVRRUN;
+       unsigned int i;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg_status, reg_fifo;
+
+       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+       reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+       /* Read the data from the MCI_FIFO register as long as
+        * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+        * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+        * register are cleared to 0.
+        * Continue the reads until the whole transfer data is received
+        */
+
+       do {
+               mmc_ret = MMC_BOOT_E_SUCCESS;
+               mmc_status = readl(reg_status);
+
+               if (mmc_status & read_error) {
+                       mmc_ret = mmc_boot_status_error(mmc_status);
+                       break;
+               }
+
+               if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+                       unsigned read_count = 1;
+                       if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+                               read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+                       for (i = 0; i < read_count; i++) {
+                               /* FIFO contains 16 32-bit data buffer
+                                 * on 16 sequential addresses
+                                 */
+                               *mmc_ptr = readl(reg_fifo +
+                                       (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+                               mmc_ptr++;
+                               /* increase mmc_count by word size */
+                               mmc_count += sizeof(unsigned int);
+                       }
+                       /* quit if we have read enough of data */
+                       if (mmc_count == data_len)
+                               break;
+               } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+                       break;
+       }  while (1);
+       return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+                                                       unsigned int  data_len,
+                                                       unsigned char direction,
+                                                       struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       if (direction == MMC_BOOT_DATA_READ)
+               mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+       return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_cmd = 0;
+       unsigned int mmc_status = 0;
+       unsigned int mmc_resp = 0;
+       unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+       unsigned int cmd_index = 0;
+       int i = 0;
+       unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+
+       /* basic check */
+       if (cmd == NULL)
+               return MMC_BOOT_E_INVAL;
+
+       /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+       writel(cmd->cmdarg, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+       /* 2a. Write command index in CMD_INDEX field */
+       cmd_index = cmd->cmdidx;
+       mmc_cmd |= cmd->cmdidx;
+       /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+       if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+       /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+       if (cmd->resp_type & MMC_RSP_136)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+       /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+       /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+        * mode data transfer
+        */
+       if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+       /* 2f. Set ENABLE bit to 1 */
+       mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+       /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+        * write data transfer
+        */
+       if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+                       cmd_index == MMC_CMD_SEND_STATUS) &&
+                       (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+                       mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+       /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+       /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+        * of CE-ATA device is enabled
+        */
+
+       /* 2j. clear all static status bits */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+       writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+       /* 2k. Write to MMC_BOOT_MCI_CMD register */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+       writel(mmc_cmd, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+       reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+       reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+       /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+        * register
+        */
+       do {
+               /* 3a. Read MCI_STATUS register */
+               mmc_status = readl(reg_status);
+               while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+                       mmc_status = readl(reg_status);
+
+               /* 3b. CMD_SENT bit supposed to be set to 1 only
+                 * after CMD0 is sent -no response required.
+                 */
+               if ((cmd->resp_type == MMC_RSP_NONE) &&
+                               (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+                       break;
+
+               /* 3c. If CMD_TIMEOUT bit is set then no response
+                 * was received */
+               else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+                       mmc_return = TIMEOUT;
+                       break;
+               }
+               /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+                 * response was received and CRC check passed
+                 * Spcial case for ACMD41: it seems to always fail CRC even if
+                 * the response is valid
+                 */
+               else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+                               (cmd_index == MMC_CMD_SEND_OP_COND)
+                               || (cmd_index == SD_CMD_SEND_IF_COND)) {
+                       /* 3i. Read MCI_RESP_CMD register to verify that
+                         *  response index is equal to command index
+                         */
+                       mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+                       /* However, long response does not contain the
+                        * command index field.
+                        * In that case, response index field must be set to
+                        * 111111b (0x3F)
+                        */
+                       if ((mmc_resp == cmd_index) ||
+                               (cmd->resp_type == MMC_RSP_R2 ||
+                               cmd->resp_type == MMC_RSP_R3 ||
+                               cmd->resp_type == MMC_RSP_R6 ||
+                               cmd->resp_type == MMC_RSP_R7)){
+                               /* 3j. If resp index is equal to cmd index,
+                                 * read command resp from MCI_RESPn registers
+                                 * - MCI_RESP0/1/2/3 for CMD2/9/10
+                                 * - MCI_RESP0 for all other registers
+                                 */
+                               if (cmd->resp_type & MMC_RSP_136) {
+                                       for (i = 0; i < 4; i++)
+                                               cmd->response[3-i] =
+                                                       readl(reg_resp_0 + \
+                                                       (i * 4));
+                               } else
+                                       cmd->response[0] = readl(reg_resp_0);
+                       } else
+                               /* command index mis-match */
+                               mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+                       break;
+               }
+
+               /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+                * was recvd, but CRC check failed.
+                */
+               else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+                       if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+                               cmd->response[0] = readl(reg_resp_0);
+                       else
+                               mmc_return = MMC_BOOT_E_CRC_FAIL;
+                       break;
+               }
+
+       }  while (1);
+
+       return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+                       struct mmc_data *data)
+{
+       uint32_t data_ctrl, mmc_reg, data_len;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg;
+
+       /* Write data timeout period to MCI_DATA_TIMER register. */
+       /* Data timeout period should be in card bus clock periods */
+       mmc_reg = (unsigned long)(((struct mmc_priv *)
+                                               (mmc->priv))->rd_timeout_ns /
+                                               1000000) * (mmc->clock / 1000);
+       /* add some extra clock cycles to be safe */
+       mmc_reg += 1000;
+       mmc_reg = mmc_reg/2;
+
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+       writel(mmc_reg, reg);
+
+       /* Write the total size of the transfer data to MCI_DATA_LENGTH
+        * register. For block xfer it must be multiple of the block
+        * size.
+        */
+
+       data_len = data->blocks*data->blocksize;
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+       writel(data_len, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+               (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+       if (data->flags == MMC_DATA_READ)
+               data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+       writel(data_ctrl, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+                               struct mmc_cmd *cmd,
+                               struct mmc_data *data)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       /*  todo: do we need to fill in command type ?? */
+
+       if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+               /* u-boot doesn't fill in the correct argument value */
+               cmd->cmdarg =  mmc->rca << 16;
+               /* this is to explicitly disable the prg enabled flag */
+               cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+       } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+               if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+                               mmc->version & SD_VERSION_SD) {
+                       mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+                       data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+               }
+       } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+                       if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+                                       mmc->version & SD_VERSION_SD) {
+                               mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+                               data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+                       }
+       } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+                       /* explicitly disable the prg enabled flag */
+                       cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+                       /* set the XFER mode */
+                       cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+       }
+
+
+       /* For Data cmd's */
+       if (data != NULL)
+               mmc_boot_init_data(mmc, cmd, data);
+
+       /* send command */
+       mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+       if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+               debug("Return Error = %d\n", mmc_ret);
+               return mmc_ret;
+       }
+
+       if (data != NULL) {
+               mmc_ret = mmc_boot_check_read_data(cmd);
+               if (mmc_ret)
+                       return mmc_ret;
+               mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+                                       data->blocks * data->blocksize,
+                                       MMC_BOOT_DATA_READ,
+                                       mmc);
+       }
+
+       if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+               /* Set read timeout once csd is received */
+               mmc_ret = mmc_boot_set_read_timeout(mmc);
+               if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+                       printf("Error No.%d: Failure setting \
+                                       write Timeout value!\n",
+                                       mmc_ret);
+                       return mmc_ret;
+               }
+       } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+               /* cmd6 needs at least 8 clocks after the
+                * End Data of Status.
+                * ticks calculated using 400KHz clock speed
+                */
+               udelay(20);
+       }
+
+       return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+       unsigned int mmc_pwr = 0;
+       struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;
+       int mmc_slot = priv->instance;
+       unsigned long reg;
+
+       /* Initialize any clocks needed for SDC controller */
+       clock_init_mmc(mmc_slot);
+
+       /* Setup initial freq to 400KHz */
+       clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+       /* set power mode*/
+       mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+       mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+       mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+       writel(mmc_pwr, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_reg;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg;
+
+       /* set MCI_CLK accordingly */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+       mmc_reg = readl(reg);
+       mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+       if (width == 1)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+       else if (width == 4)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+       else if (width == 8)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+       else
+               return MMC_BOOT_E_INVAL;
+
+       writel(mmc_reg, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       debug("Setting bus width to %d\n", width);
+       return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       int mmc_slot = priv->instance;
+
+       /* clock frequency should be less than 400KHz in identification mode */
+       clock_config_mmc(mmc_slot, mmc->clock);
+       /*
+        * give atleast 2 MCLK cycles delay for clocks
+        * and SDCC core to stabilize.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(5);
+       mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+       if (mmc_ret != MMC_BOOT_E_SUCCESS)
+               printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       /* Initialize necessary data structure and enable/set clock and power */
+       debug(" Initializing MMC host data structure and clock!\n");
+       mmc_ret = mmc_boot_init(mmc);
+       if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+               printf("MMC Boot: Error Initializing MMC Card!!!\n");
+               return MMC_BOOT_E_FAILURE;
+       }
+
+       return MMC_BOOT_E_SUCCESS;
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board
       [not found] <yes>
                   ` (58 preceding siblings ...)
  2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
@ 2012-02-16  2:59 ` mohamed.haneef at lntinfotech.com
  2012-10-03  8:19   ` Albert ARIBAUD
  2012-06-08 17:23   ` Joonsoo Kim
                   ` (31 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-02-16  2:59 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

        *Support for msm7630_surf board

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
 board/qcom/msm7630_surf/Makefile       |   55 +++++++++++
 board/qcom/msm7630_surf/msm7630_surf.c |  155 ++++++++++++++++++++++++++++++++
 board/qcom/msm7630_surf/msm7630_surf.h |   30 ++++++
 boards.cfg                             |    1 +
 include/configs/msm7630_surf.h         |  131 +++++++++++++++++++++++++++
 5 files changed, 372 insertions(+), 0 deletions(-)
 create mode 100644 board/qcom/msm7630_surf/Makefile
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
 create mode 100644 include/configs/msm7630_surf.h

diff --git a/board/qcom/msm7630_surf/Makefile b/board/qcom/msm7630_surf/Makefile
new file mode 100644
index 0000000..f9dec32
--- /dev/null
+++ b/board/qcom/msm7630_surf/Makefile
@@ -0,0 +1,55 @@
+#
+#  (C) Copyright 2012
+#  LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+#  (C) Copyright 2010,2011
+#  NVIDIA Corporation <www.nvidia.com>
+#
+#
+#  See file CREDITS for list of people who contributed to this
+#  project.
+#
+#  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., 59 Temple Place, Suite 330, Boston,
+#  MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../../qcom/msm7630_surf/)
+endif
+
+LIB    = $(obj)lib$(BOARD).o
+
+COBJS  := $(BOARD).o
+SRCS   := $(COBJS:.o=.c)
+OBJS   := $(addprefix $(obj),$(COBJS))
+
+$(LIB):        $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+clean:
+       rm -f $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/qcom/msm7630_surf/msm7630_surf.c b/board/qcom/msm7630_surf/msm7630_surf.c
new file mode 100644
index 0000000..eb941c7
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.c
@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/mmc.h>
+#include <linux/string.h>
+#include <asm/mach-types.h>
+#include <asm/arch/proc_comm.h>
+#include "msm7630_surf.h"
+
+static struct msm_gpio uart2_gpio_table[] = {
+       {
+       .gpio_cfg = GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+       .label = NULL,
+       },
+       {
+       .gpio_cfg = GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+       .label = NULL,
+       },
+       {
+       .gpio_cfg = GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+       .label = NULL,
+       },
+       {
+       .gpio_cfg = GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+       .label = NULL,
+       },
+};
+
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void uart2_mux_init(void)
+{
+       platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table));
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f()
+{
+       uart2_mux_init();
+       uart2_clock_init();
+       return 0;
+}
+#endif
+int board_init()
+{
+       unsigned long new_addr;
+       unsigned long offset;
+       offset = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
+       new_addr = CONFIG_SYS_TEXT_BASE + offset;
+       set_vector_base(new_addr);
+       bd_t *bd = gd->bd;
+       bd->bi_arch_number = MACH_TYPE_MSM7X30_SURF;
+       acpu_clock_init();
+       adm_enable_clock();
+       return 0;
+}
+
+#ifdef CONFIG_QC_MMC
+
+/* called during the scan of each mmc device */
+int qc_board_mmc_init(struct mmc *mmc)
+{
+
+       struct mmc_priv *sd = (struct mmc_priv *)mmc->priv;
+       u32 smem_val;
+       do {
+               smem_val = 0;
+               smem_val = readl(MSM_SHARED_BASE + 0x14);
+       } while (smem_val != 1);
+
+       if (sd->instance == 2 || sd->instance == 4) {
+               mmc_boot_main(mmc);
+               return 0;
+       } else
+       /* this board does not have an sd/mmc card on this interface. */
+       return 1;
+       }
+int board_mmc_init(bd_t *bis)
+{
+#ifdef QC_SD
+       struct mmc *mmc_4;
+       struct mmc_priv *sdcc_4;
+       mmc_4 = (struct mmc *) malloc(sizeof(struct mmc));
+       if (!mmc_4)
+               return 1;
+       sdcc_4 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+       if (!sdcc_4) {
+               free(mmc_4);
+               return 1;
+       }
+       sdcc_4->instance = 4;
+       sdcc_4->base = MSM_SDC4_BASE;
+       mmc_4->priv = sdcc_4;
+       mmc_4->send_cmd = mmc_boot_send_command_map;
+       mmc_4->set_ios = mmc_boot_set_ios;
+       mmc_4->init = qc_board_mmc_init;
+       mmc_4->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+       mmc_4->host_caps = MMC_MODE_4BIT|MMC_MODE_HS;
+       mmc_4->f_min = MMC_CLK_400KHZ;
+       mmc_4->f_max = MMC_CLK_48MHZ;
+       sprintf(mmc_4->name, "External_Card");
+       mmc_register(mmc_4);
+#else
+       struct mmc *mmc_2;
+       struct mmc_priv *sdcc_2;
+       mmc_2 = (struct mmc *) malloc(sizeof(struct mmc));
+       if (!mmc_2)
+               return 1;
+       sdcc_2 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+       if (!sdcc_2) {
+               free(mmc_2);
+               return 1;
+       }
+       sdcc_2->instance = 2;
+       sdcc_2->base = MSM_SDC2_BASE;
+       mmc_2->priv = sdcc_2;
+       mmc_2->send_cmd = mmc_boot_send_command_map;
+       mmc_2->set_ios = mmc_boot_set_ios;
+       mmc_2->init = qc_board_mmc_init;
+       mmc_2->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+       mmc_2->host_caps = MMC_MODE_4BIT|MMC_MODE_HS|MMC_MODE_8BIT|
+                                       MMC_MODE_HS_52MHz;
+       mmc_2->f_min = MMC_CLK_400KHZ;
+       mmc_2->f_max = MMC_CLK_48MHZ;
+       sprintf(mmc_2->name, "Internal_Card");
+       mmc_register(mmc_2);
+#endif
+       return 0;
+}
+#endif
diff --git a/board/qcom/msm7630_surf/msm7630_surf.h b/board/qcom/msm7630_surf/msm7630_surf.h
new file mode 100644
index 0000000..a3d4bde
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.h
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __MSM7630_SURF_H_
+#define __MSM7630_SURF_H_
+#include <asm/arch/gpio_hw.h>
+
+extern void set_vector_base(unsigned long);
+extern void adm_enable_clock(void);
+extern void acpu_clock_init(void);
+extern void uart2_clock_init(void);
+extern int platform_gpios_enable(const struct msm_gpio *table, int size);
+#endif
diff --git a/boards.cfg b/boards.cfg
index bf71a66..4ab9330 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -190,6 +190,7 @@ integratorcp_cm946es         arm         arm946es    integrator          armltd
 ca9x4_ct_vxp                 arm         armv7       vexpress            armltd
 am335x_evm                   arm         armv7       am335x              ti             am33xx
 highbank                     arm         armv7       highbank            -              highbank
+msm7630_surf                 arm         armv7       msm7630_surf        qcom           msm7630
 efikamx                      arm         armv7       efikamx             -              mx5            efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg
 efikasb                      arm         armv7       efikamx             -              mx5            efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg
 mx51evk                      arm         armv7       mx51evk             freescale      mx5            mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
diff --git a/include/configs/msm7630_surf.h b/include/configs/msm7630_surf.h
new file mode 100644
index 0000000..3356611
--- /dev/null
+++ b/include/configs/msm7630_surf.h
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/sizes.h>
+#define PLATFORM_MSM7X30 1
+#define CONFIG_MSM_UART
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_L2_OFF
+#define CONFIG_SKIP_LOWLEVEL_INIT
+/* Environment */
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE                 0x20000        /* Total Size Environment */
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MSM_PCOMM
+#define CONFIG_ARCH_CPU_INIT
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN           (4 * 1024)     /* 4KB  */
+#define CONFIG_MSM7630
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX       1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE                 115200
+#define CONFIG_SYS_BAUDRATE_TABLE       {4800, 9600, 19200, 38400, 57600,\
+                                                               115200}
+
+#include <config_cmd_default.h>
+
+/* remove unused commands */
+#undef CONFIG_CMD_FLASH                /* flinfo, erase, protect */
+#undef CONFIG_CMD_FPGA         /* FPGA configuration support */
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NFS          /* NFS support */
+#undef CONFIG_CMD_NET          /* network support */
+#undef CONFIG_SYS_MAX_FLASH_SECT
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "console=ttyS0,115200n8\0" \
+
+#define CONFIG_BOOTDELAY        2      /* -1 to disable auto boot */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP    /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2      "> "
+#define V_PROMPT                        "(MSM 7x30) # "
+#define CONFIG_SYS_PROMPT               V_PROMPT
+/*
+ * Increasing the size of the IO buffer as default nfsargs size is more
+ *  than 256 and so it is not possible to edit it
+ */
+#define CONFIG_SYS_CBSIZE               (256 * 2) /* Console I/O Buffer Size */
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE               (CONFIG_SYS_CBSIZE + \
+                                               sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS              16     /* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE             (CONFIG_SYS_CBSIZE)
+
+#define CONFIG_SYS_HZ                   1000
+#define CONFIG_SYS_LOAD_ADDR           0x00208000
+#define CONFIG_SYS_MEMTEST_START       0x08008000
+#define CONFIG_SYS_MEMTEST_END         0x08008001
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+
+#define CONFIG_GENERIC_MMC
+#define CONFIG_QC_MMC
+
+/*---------------------------------------------------------------------
+ * IRQ Settings
+ */
+
+#define CONFIG_STACKSIZE_IRQ    (4*1024)       /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ    (4*1024)       /* FIQ stack */
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+
+
+#define CONFIG_NR_DRAM_BANKS           2
+
+#define PHYS_SDRAM_1                   0x00200000
+#define PHYS_SDRAM_1_SIZE              (60*1024*1024)  /* 512M */
+
+
+#define PHYS_SDRAM_2                   0x07A00000
+#define PHYS_SDRAM_2_SIZE              (134*1024*1024)
+
+#define CONFIG_SYS_TEXT_BASE           0x00000000
+#define CONFIG_SYS_INIT_RAM_ADDR       0x00000000
+#define CONFIG_SYS_INIT_RAM_SIZE       0x00100000
+
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_INIT_RAM_ADDR + \
+                                               CONFIG_SYS_INIT_RAM_SIZE - \
+                                               GENERATED_GBL_DATA_SIZE)
+
+#endif
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board
  2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
@ 2012-02-23  8:59   ` Mohamed Haneef
  2012-10-26 21:15   ` [U-Boot] " Albert ARIBAUD
  1 sibling, 0 replies; 716+ messages in thread
From: Mohamed Haneef @ 2012-02-23  8:59 UTC (permalink / raw)
  To: u-boot

This is a humbel reminder for verification of patch series for msm7630 board. The Patches contain the following support
        * low speed uart for msm7630
        * interprocessor communication
        * msm7630 soc
        * msm7630 surf board


Mohamed Haneef (5):
  msm7x30: Add support for low speed uart on msm7x30
  msm7x30: Add support for interprocessor communication
  msm7x30: Add support for Qualcomm msm7630 soc
  Add support for mmc read and writes
  msm7x30: Add support for msm7630_surf board

 arch/arm/cpu/armv7/msm7630/Makefile           |   59 +++
 arch/arm/cpu/armv7/msm7630/acpuclock.c        |  328 +++++++++++++
 arch/arm/cpu/armv7/msm7630/board.c            |   58 +++
 arch/arm/cpu/armv7/msm7630/config.mk          |    1 +
 arch/arm/cpu/armv7/msm7630/gpio.c             |  229 +++++++++
 arch/arm/cpu/armv7/msm7630/lowlevel_init.S    |  626 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/msm7630/timer.c            |  148 ++++++
 arch/arm/include/asm/arch-msm7630/adm.h       |   28 ++
 arch/arm/include/asm/arch-msm7630/gpio.h      |   47 ++
 arch/arm/include/asm/arch-msm7630/gpio_hw.h   |  168 +++++++
 arch/arm/include/asm/arch-msm7630/iomap.h     |   96 ++++
 arch/arm/include/asm/arch-msm7630/mmc.h       |  399 ++++++++++++++++
 arch/arm/include/asm/arch-msm7630/proc_comm.h |   42 ++
 arch/arm/include/asm/arch-msm7630/sys_proto.h |   29 ++
 board/qcom/msm7630_surf/Makefile              |   55 +++
 board/qcom/msm7630_surf/msm7630_surf.c        |  155 ++++++
 board/qcom/msm7630_surf/msm7630_surf.h        |   30 ++
 boards.cfg                                    |    1 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/msm_proc_comm.c                  |  303 ++++++++++++
 drivers/mmc/Makefile                          |    1 +
 drivers/mmc/qc_mmc.c                          |  584 +++++++++++++++++++++++
 drivers/serial/Makefile                       |    1 +
 drivers/serial/serial_msm_uart.c              |  206 ++++++++
 include/configs/msm7630_surf.h                |  131 +++++
 25 files changed, 3726 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
 create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
 create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
 create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h
 create mode 100644 board/qcom/msm7630_surf/Makefile
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
 create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
 create mode 100644 drivers/misc/msm_proc_comm.c
 create mode 100644 drivers/mmc/qc_mmc.c
 create mode 100644 drivers/serial/serial_msm_uart.c
 create mode 100644 include/configs/msm7630_surf.h


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
@ 2012-02-28 23:44   ` Albert ARIBAUD
  2012-03-05 14:34   ` [U-Boot] [PATCH v2 1/5] msm7x30: Add Support " Mohamed Haneef
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2012-02-28 23:44 UTC (permalink / raw)
  To: u-boot

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :

> +#define UART_CR_TX_DISABLE         (1<<  3)
> +#define UART_CR_TX_ENABLE          (1<<  3)

I doubt the same bit value can mean both enable and disable.

> +#define UART_CR_RX_DISABLE         (1<<  3)
> +#define UART_CR_RX_ENABLE          (1<<  3)

Ditto.

Besides, neither of these defines are used anyway. What's the point of 
having them? I suspect many others are unused, too. Unless there is a 
compelling reason to keep useless defines, remove them.

> The contents of this e-mail and any attachment(s) may contain
> confidential or privileged information for the intended recipient(s).
> Unintended recipients are prohibited from taking action on the basis
> of information in this e-mail and  using or disseminating the
> information,  and must notify the sender and delete it from their
> system. L&T Infotech will not accept responsibility or liability for
> the accuracy or completeness of, or the presence of any virus or
> disabling code in this e-mail"

Please do not post with this footer on the list. It os obnoxious (and 
quite purposeless on a public list :) )

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication
  2012-02-16  2:59 ` [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication mohamed.haneef at lntinfotech.com
@ 2012-02-28 23:46   ` Albert ARIBAUD
  2012-03-05 14:33     ` Mohamed Haneef
  0 siblings, 1 reply; 716+ messages in thread
From: Albert ARIBAUD @ 2012-02-28 23:46 UTC (permalink / raw)
  To: u-boot

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef@lntinfotech.com>
>
>          *Support for msm7x30 interprocessor communication

Is this used at some point in the patch set? If not, remove it and 
introduce it back within a patchset that uses it.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc
  2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
@ 2012-02-29  0:00   ` Albert ARIBAUD
  2012-03-05 14:39   ` [U-Boot] [PATCH v2 3/5] msm7x30: Add support for msm7x30 SoC Mohamed Haneef
  1 sibling, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2012-02-29  0:00 UTC (permalink / raw)
  To: u-boot

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :

> +#define BIT(n)         (1<<  (n))
> +#define VREG_CONFIG    (BIT(7) | BIT(6))

BIT() is not used elsewhere. It would be simpler not to define it and to 
define VREG_CONFIG as (3 << 6).

Besides, isn't that rather a VREG_CONFIG_MASK?

> +void set_vector_base(unsigned long addr)
> +{
> +       __asm__ volatile ("mcr   p15, 0, %0, c12, c0, 0" : : "r" (addr));
> +}

Where is it used?

> +int dram_init(void)
> +{
> +       /* We do not initialise DRAM here. We just query the size */
> +       gd->ram_size = PHYS_SDRAM_1_SIZE;
> +       /* Now check it dynamically */

It says 'check it dynamically', but does not seem to. Any reason not to 
detect RAM size dynamically?

> +static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
> +{
> +       if (n>  150) {
> +               *bit = 1<<  (n - 151);
> +               return GPIO_REGS + 7;
> +       }
> +       if (n>  133) {
> +               *bit = 1<<  (n - 134);
> +               return GPIO_REGS + 6;
> +       }
> +       if (n>  106) {
> +               *bit = 1<<  (n - 107);
> +               return GPIO_REGS + 5;
> +       }
> +       if (n>  94) {
> +               *bit = 1<<  (n - 95);
> +               return GPIO_REGS + 4;
> +       }
> +       if (n>  67) {
> +               *bit = 1<<  (n - 68);
> +               return GPIO_REGS + 3;
> +       }
> +       if (n>  43) {
> +               *bit = 1<<  (n - 44);
> +               return GPIO_REGS + 2;
> +       }
> +       if (n>  15) {
> +               *bit = 1<<  (n - 16);
> +               return GPIO_REGS + 1;
> +       }
> +       *bit = 1<<  n;
> +       return GPIO_REGS + 0;
> +}
> +
> +int gpio_config(unsigned n, unsigned flags)
> +{
> +       struct gpioregs *r;
> +       unsigned b;
> +       unsigned v;
> +
> +       r = find_gpio(n,&b);
> +       if (!r)
> +               return -1;
> +
> +       v = readl(r->oe);
> +       if (flags&  GPIO_OUTPUT)
> +               writel(v | b, r->oe);
> +       else
> +               writel(v&  (~b), r->oe);
> +       return 0;
> +}
> +
> +void gpio_set(unsigned n, unsigned on)
> +{
> +       struct gpioregs *r;
> +       unsigned b;
> +       unsigned v;
> +
> +       r = find_gpio(n,&b);
> +       if (r == 0)
> +               return;
> +
> +       v = readl(r->out);
> +       if (on)
> +               writel(v | b, r->out);
> +       else
> +               writel(v&  (~b), r->out);
> +}
> +
> +int gpio_get(unsigned n)
> +{
> +       struct gpioregs *r;
> +       unsigned b;
> +
> +       r = find_gpio(n,&b);
> +       if (r  == 0)
> +               return 0;
> +       return (readl(r->in)&  b) ? 1 : 0;
> +}
> +
> +void platform_config_interleaved_mode_gpios(void)
> +{
> +       /* configure EB2_CS1 through GPIO86 */
> +       writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
> +       writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
> +       /* configure the EBI2_BUSY1_N through GPIO115 */
> +       writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
> +       writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
> +}
> +
> +/* Enables all gpios passed in table*/
> +int platform_gpios_enable(const struct msm_gpio *table, int size)
> +{
> +       int rc;
> +       int i;
> +       const struct msm_gpio *g;
> +       for (i = 0; i<  size; i++) {
> +               g = table + i;
> +               /* Enable gpio */
> +               rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
> +               if (rc)
> +                       goto err;
> +       }
> +       return 0;
> +err:
> +       return rc;
> +}
> +
> diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
> new file mode 100644
> index 0000000..d8d5b46
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
> @@ -0,0 +1,626 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#include<config.h>
> +#include<version.h>
> +
> +.text
> +.code 32
> +
> +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
> +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
> +
> +/*
> + ; LVT Ring Osc counter
> + ; used to determine sense amp settings
> + ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
> +*/
> +.equ CLK_CTL_BASE,     0xA8600000
> +.equ A_GLBL_CLK_ENA,   0x0000
> +.equ A_PRPH_WEB_NS_REG,0x0080
> +.equ A_MSM_CLK_RINGOSC,0x00D0
> +.equ A_TCXO_CNT,       0x00D4
> +.equ A_TCXO_CNT_DONE,  0x00D8
> +.equ A_RINGOSC_CNT,    0x00DC
> +.equ A_MISC_CLK_CTL,   0x0108
> +.equ CLK_TEST,         0xA8600114
> +.equ SPSS_CSR_BASE,    0xAC100000
> +.equ A_SCRINGOSC,      0x0510
> +
> +//;; Number of TCXO cycles to count ring oscillations
> +.equ TCXO_CNT_VAL,     0x100
> +
> +//; Halcyon addresses
> +.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
> +.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
> +
> +//; SCORPION_L1_ACC (1:0) Fuses bit location
> +.equ L1_ACC_BIT_0,     12       //;12th bit of TCSR_CONF_FUSE_4
> +.equ L1_ACC_BIT_1,     13       //;13th bit of TCSR_CONF_FUSE_4
> +//; SCORPION_L2_ACC (2:0) Fuses bit location
> +.equ L2_ACC_BIT_0,     25       //;25th bit of TCSR_CONF_FUSE_1
> +.equ L2_ACC_BIT_1,     10       //;10th bit of TCSR_CONF_FUSE_4
> +.equ L2_ACC_BIT_2,     11       //;11th bit of TCSR_CONF_FUSE_4
> +
> +//; CP15: PVR2F0 values according to  SCORPION_L1_ACC (1:0)
> +.equ PVR2F0_00,        0x00000000
> +.equ PVR2F0_01,        0x04000000
> +.equ PVR2F0_10,        0x08000000
> +.equ PVR2F0_11,        0x0C000000
> +
> +//; CP15: PVR2F1 values according to  SCORPION_L1_ACC (1:0)
> +.equ PVR2F1_00,        0x00000008
> +.equ PVR2F1_01,        0x00000008
> +.equ PVR2F1_10,        0x00000208
> +.equ PVR2F1_11,        0x00000208
> +
> +//; CP15: PVR0F2 values according to  SCORPION_L1_ACC (1:0)
> +.equ PVR0F2_00,        0x00000000
> +.equ PVR0F2_01,        0x00000000
> +.equ PVR0F2_10,        0x00000200
> +.equ PVR0F2_11,        0x00000200
> +
> +//; CP15: PVR0F0 values according to  SCORPION_L1_ACC (1:0)
> +.equ PVR0F0_00,        0x7F000000
> +.equ PVR0F0_01,        0x7F000400
> +.equ PVR0F0_10,        0x7F000000
> +.equ PVR0F0_11,        0x7F000400
> +
> +//; CP15: L2VR3F1 values according to  SCORPION_L2_ACC (2:0)
> +.equ L2VR3F1_000,      0x00FFFF60
> +.equ L2VR3F1_001,      0x00FFFF40
> +.equ L2VR3F1_010,      0x00FFFC60
> +.equ L2VR3F1_011,      0x00FFFC40
> +.equ L2VR3F1_100,      0x00FCFF60
> +.equ L2VR3F1_101,      0x00FCFF40
> +.equ L2VR3F1_110,      0x00FCFC60
> +.equ L2VR3F1_111,      0x00FCFC40
> +
> +
> +
> +
> +_TEXT_BASE:
> +       .word   CONFIG_SYS_TEXT_BASE    @ sdram load addr from config file
> +
> +.global invalidate_dcache
> +invalidate_dcache:
> +       mov pc, lr
> +
> +       .align  5
> +.globl lowlevel_init
> +lowlevel_init:
> +       mov     pc, lr                          @ back to arch calling code
> +
> +.global reset_cpu
> +reset_cpu:
> +_loop_forever:
> +        b       _loop_forever
> +
> +.globl SET_SA
> +SET_SA:
> +
> +        //;--------------------------------------------------------------------
> +        //; Fuse bits used to determine sense amp settings
> +        //;--------------------------------------------------------------------
> +
> +        //; Reading L1_ACC
> +        ldr    r4, = 0x0
> +
> +        //; Read L1_ACC_BIT_0
> +        ldr    r1, =TCSR_CONF_FUSE_4
> +        ldr    r2, =L1_ACC_BIT_0
> +        ldr    r3, [r1]
> +        mov    r3, r3, LSR r2
> +        and    r3, r3, #1
> +        orr    r4, r3, r4
> +
> +        //; Read L1_ACC_BIT_1
> +        ldr    r1, =TCSR_CONF_FUSE_4
> +        ldr    r2, =L1_ACC_BIT_1
> +        ldr    r3, [r1]
> +        mov    r3, r3, LSR r2
> +        and    r3, r3, #1
> +        mov    r3, r3, LSL #1
> +        orr    r4, r3, r4
> +
> +l1_ck_0:
> +        //; if L1_[1:0] == 00
> +        ldr    r5, = 0x0
> +        cmp    r4, r5
> +        bne    l1_ck_1
> +        ldr    r0, =PVR0F0_00
> +        ldr    r1, =PVR0F2_00
> +        ldr    r2, =PVR2F0_00
> +        ldr    r3, =PVR2F1_00
> +        b      WRITE_L1_SA_SETTINGS
> +
> +l1_ck_1:
> +        //; if L1_[1:0] == 01
> +        ldr    r1, = 0x01
> +        cmp    r4, r1
> +        bne    l1_ck_2
> +        ldr    r0, =PVR0F0_01
> +        ldr    r1, =PVR0F2_01
> +        ldr    r2, =PVR2F0_01
> +        ldr    r3, =PVR2F1_01
> +        b      WRITE_L1_SA_SETTINGS
> +
> +l1_ck_2:
> +        //; if L1_[2:0] == 10
> +        ldr    r1, = 0x02
> +        cmp    r4, r1
> +        bne    l1_ck_3
> +        ldr    r0, =PVR0F0_10
> +        ldr    r1, =PVR0F2_10
> +        ldr    r2, =PVR2F0_10
> +        ldr    r3, =PVR2F1_10
> +        b      WRITE_L1_SA_SETTINGS
> +
> +l1_ck_3:
> +        //; if L1_[2:0] == 11
> +        ldr    r1, = 0x03
> +        cmp    r4, r1
> +        ldr    r0, =PVR0F0_11
> +        ldr    r1, =PVR0F2_11
> +        ldr    r2, =PVR2F0_11
> +        ldr    r3, =PVR2F1_11
> +        b      WRITE_L1_SA_SETTINGS
> +
> +
> +WRITE_L1_SA_SETTINGS:
> +
> +        //;WCP15_PVR0F0   r0
> +        mcr    p15, 0x0, r0, c15, c15, 0x0   //; write R0 to PVR0F0
> +
> +        //;WCP15_PVR0F2   r1
> +        mcr    p15, 0x0, r1, c15, c15, 0x2   //; write R1 to PVR0F2
> +
> +        //;WCP15_PVR2F0   r2
> +        mcr    p15, 0x2, r2, c15, c15, 0x0   //; write R2 to PVR2F0
> +
> +        // Disable predecode repair cache on certain Scorpion revisions
> +        // (Raptor V2 and earlier, or Halcyon V1)
> +        mrc    p15, 0, r1, c0, c0, 0      //; MIDR
> +        BIC    r2, r1, #0xf0              //; check for Halcyon V1
> +        ldr    r4, =0x511f0000
> +        cmp    r2, r4
> +        bne    PVR2F1
> +
> +DPRC:
> +        mrc    p15, 0, r1, c15, c15, 2    //; PVR0F2
> +        orr    r1, r1, #0x10              //; enable bit 4
> +        mcr    p15, 0, r1, c15, c15, 2    //; disable predecode repair cache
> +
> +PVR2F1:
> +        //;WCP15_PVR2F1   r3
> +        mcr    p15, 0x2, r3, c15, c15, 0x1   //; write R3 to PVR2F1
> +
> +        //; Reading L2_ACC
> +        ldr    r4, = 0x0
> +
> +        //; Read L2_ACC_BIT_0
> +        ldr    r1, =TCSR_CONF_FUSE_1
> +        ldr    r2, =L2_ACC_BIT_0
> +        ldr    r3, [r1]
> +        mov    r3, r3, LSR r2
> +        and    r3, r3, #1
> +        orr    r4, r3, r4
> +
> +        //; Read L2_ACC_BIT_1
> +        ldr    r1, =TCSR_CONF_FUSE_4
> +        ldr    r2, =L2_ACC_BIT_1
> +        ldr    r3, [r1]
> +        mov    r3, r3, LSR r2
> +        and    r3, r3, #1
> +        mov    r3, r3, LSL #1
> +        orr    r4, r3, r4
> +
> +        //; Read L2_ACC_BIT_2
> +        ldr    r1, =TCSR_CONF_FUSE_4
> +        ldr    r2, =L2_ACC_BIT_2
> +        ldr    r3, [r1]
> +        mov    r3, r3, LSR r2
> +        and    r3, r3, #1
> +        mov    r3, r3, LSL #2
> +        orr    r4, r3, r4
> +
> +l2_ck_0:
> +        //; if L2_[2:0] == 000
> +        ldr    r5, = 0x0
> +        cmp    r4, r5
> +        bne    l2_ck_1
> +        ldr    r0, =L2VR3F1_000
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_1:
> +        //; if L2_[2:0] == 001
> +        ldr     r5, = 0x1
> +        cmp     r4, r5
> +        bne     l2_ck_2
> +        ldr     r0, =L2VR3F1_001
> +        b       WRITE_L2_SA_SETTINGS
> +
> +l2_ck_2:
> +        //; if L2_[2:0] == 010
> +        ldr    r5, = 0x2
> +        cmp    r4, r5
> +        bne    l2_ck_3
> +        ldr    r0, =L2VR3F1_010
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_3:
> +        //; if L2_[2:0] == 011
> +        ldr    r5, = 0x3
> +        cmp    r4, r5
> +        bne    l2_ck_4
> +        ldr    r0, =L2VR3F1_011
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_4:
> +        //; if L2_[2:0] == 100
> +        ldr    r5, = 0x4
> +        cmp    r4, r5
> +        bne    l2_ck_5
> +        ldr    r0, =L2VR3F1_100
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_5:
> +        //; if L2_[2:0] == 101
> +        ldr    r5, = 0x5
> +        cmp    r4, r5
> +        bne    l2_ck_6
> +        ldr    r0, =L2VR3F1_101
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_6:
> +        //; if L2_[2:0] == 110
> +        ldr    r5, = 0x6
> +        cmp    r4, r5
> +        bne    l2_ck_7
> +        ldr    r0, =L2VR3F1_110
> +        b      WRITE_L2_SA_SETTINGS
> +
> +l2_ck_7:
> +        //; if L2_[2:0] == 111
> +        ldr    r5, = 0x7
> +        cmp    r4, r5
> +        ldr    r0, =L2VR3F1_111
> +        b      WRITE_L2_SA_SETTINGS
> +
> +WRITE_L2_SA_SETTINGS:
> +        //;WCP15_L2VR3F1  r0
> +        mcr    p15, 0x3, r0, c15, c15, 0x1     //;write r0 to L2VR3F1
> +       DSB
> +       ISB
> +
> +        ldr    r0, =0                   //;make sure the registers we touched
> +        ldr    r1, =0                   //;are cleared when we return
> +        ldr    r2, =0
> +        ldr    r3, =0
> +        ldr    r4, =0
> +        ldr    r5, =0
> +
> +       mrs     r0, cpsr
> +       orr     r0, r0, #(1<<7)
> +       msr     cpsr_c, r0
> +
> +       //; routine complete
> +       pop     {r5-r12,pc}
> +
> +.ltorg
> +
> +.globl __cpu_early_init
> +__cpu_early_init:
> +
> +        //; Zero out r0 for use throughout this code. All other GPRs
> +        //; (r1-r3) are set throughout this code to help establish
> +        //; a consistent startup state for any code that follows.
> +        //; Users should add code at the end of this routine to establish
> +        //; their own stack address (r13), add translation page tables, enable
> +        //; the caches, etc.
> +       push    {r5-r12,r14}
> +        mov    r0,  #0x0
> +
> +
> +        //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
> +        //;   API to dynamically configure cache for slow/nominal/fast parts
> +
> +        //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
> +       //; once per bank)
> +        //; This must be done early in code (prior to enabling the caches)
> +        mov    r1, #0x2
> +        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank D ([15:14] == 2'b00)
> +        orr    r1, r1, #0x00004000
> +        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank C ([15:14] == 2'b01)
> +        add    r1, r1, #0x00004000
> +        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank B ([15:14] == 2'b10)
> +        add    r1, r1, #0x00004000
> +        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank A ([15:14] == 2'b11)
> +
> +        //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
> +        //; and have all address bits (AM) participate.
> +        //; Different settings can be used to improve performance
> +        // movW   r1, #0x01FF
> +.word 0xe30011ff  // hardcoded movW instruction due to lack of compiler support
> +        // movT   r1, #0x01FF
> +.word 0xe34011ff  // hardcoded movT instruction due to lack of compiler support
> +        mcr    p15, 7, r1, c15, c0, 2   //; WCP15_BPCR
> +
> +
> +        //; Initialize all I$ Victim Registers to 0 for startup
> +        mcr    p15, 0, r0, c9, c1, 0    //; WCP15_ICVIC0    r0
> +        mcr    p15, 0, r0, c9, c1, 1    //; WCP15_ICVIC1    r0
> +        mcr    p15, 0, r0, c9, c1, 2    //; WCP15_ICVIC2    r0
> +        mcr    p15, 0, r0, c9, c1, 3    //; WCP15_ICVIC3    r0
> +        mcr    p15, 0, r0, c9, c1, 4    //; WCP15_ICVIC4    r0
> +        mcr    p15, 0, r0, c9, c1, 5    //; WCP15_ICVIC5    r0
> +        mcr    p15, 0, r0, c9, c1, 6    //; WCP15_ICVIC5    r0
> +        mcr    p15, 0, r0, c9, c1, 7    //; WCP15_ICVIC7    r0
> +
> +        //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
> +        mcr    p15, 1, r0, c9, c1, 0    //; WCP15_ICFLOOR0  r0
> +        mcr    p15, 1, r0, c9, c1, 1    //; WCP15_ICFLOOR1  r0
> +        mcr    p15, 1, r0, c9, c1, 2    //; WCP15_ICFLOOR2  r0
> +        mcr    p15, 1, r0, c9, c1, 3    //; WCP15_ICFLOOR3  r0
> +        mcr    p15, 1, r0, c9, c1, 4    //; WCP15_ICFLOOR4  r0
> +        mcr    p15, 1, r0, c9, c1, 5    //; WCP15_ICFLOOR5  r0
> +        mcr    p15, 1, r0, c9, c1, 6    //; WCP15_ICFLOOR6  r0
> +        mcr    p15, 1, r0, c9, c1, 7    //; WCP15_ICFLOOR7  r0
> +
> +        //; Initialize all D$ Victim Registers to 0
> +        mcr    p15, 2, r0, c9, c1, 0    //; WP15_DCVIC0    r0
> +        mcr    p15, 2, r0, c9, c1, 1    //; WP15_DCVIC1    r0
> +        mcr    p15, 2, r0, c9, c1, 2    //; WP15_DCVIC2    r0
> +        mcr    p15, 2, r0, c9, c1, 3    //; WP15_DCVIC3    r0
> +        mcr    p15, 2, r0, c9, c1, 4    //; WP15_DCVIC4    r0
> +        mcr    p15, 2, r0, c9, c1, 5    //; WP15_DCVIC5    r0
> +        mcr    p15, 2, r0, c9, c1, 6    //; WP15_DCVIC6    r0
> +        mcr    p15, 2, r0, c9, c1, 7    //; WP15_DCVIC7    r0
> +
> +        //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
> +        mcr    p15, 3, r0, c9, c1, 0    //; WCP15_DCFLOOR0  r0
> +        mcr    p15, 3, r0, c9, c1, 1    //; WCP15_DCFLOOR1  r0
> +        mcr    p15, 3, r0, c9, c1, 2    //; WCP15_DCFLOOR2  r0
> +        mcr    p15, 3, r0, c9, c1, 3    //; WCP15_DCFLOOR3  r0
> +        mcr    p15, 3, r0, c9, c1, 4    //; WCP15_DCFLOOR4  r0
> +        mcr    p15, 3, r0, c9, c1, 5    //; WCP15_DCFLOOR5  r0
> +        mcr    p15, 3, r0, c9, c1, 6    //; WCP15_DCFLOOR6  r0
> +        mcr    p15, 3, r0, c9, c1, 7    //; WCP15_DCFLOOR7  r0
> +
> +        //; Initialize ASID to zero
> +        mcr    p15, 0, r0, c13, c0, 1   //; WCP15_CONTEXTIDR r0
> +
> +        //; ICIALL to invalidate entire I-Cache
> +        mcr    p15, 0, r0, c7, c5, 0    //; ICIALLU
> +
> +        //; DCIALL to invalidate entire D-Cache
> +        mcr    p15, 0, r0, c9, c0, 6    //; DCIALL  r0
> +
> +       //; Initialize ADFSR to zero
> +        mcr    p15, 0, r0, c5, c1, 0    //; ADFSR   r0
> +
> +       //; Initialize EFSR to zero
> +        mcr    p15, 7, r0, c15, c0, 1   //; EFSR    r0
> +
> +        //; The VBAR (Vector Base Address Register) should be initialized
> +        //; early in your code. We are setting it to zero
> +        mcr    p15, 0, r0, c12, c0, 0   //; WCP15_VBAR  r0
> +
> +        //; Ensure the mcr's above have completed their operation
> +       //; before continuing
> +        DSB
> +        ISB
> +
> +        //; Setup CCPR - Cache Coherency Policy Register
> +        //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
> +        //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
> +        movw   r2, #0x88
> +        mcr    p15, 0, r2, c10, c4, 2
> +
> +        //;-------------------------------------------------------------------
> +        //; There are a number of registers that must be set prior to enabling
> +        //; the MMU. The DCAR is one of these registers. We are setting
> +        //; it to zero (no access) to easily detect improper setup in subsequent
> +        //; code sequences
> +        //;-------------------------------------------------------------------
> +        //; Setup DACR (Domain Access Control Register) to zero
> +        mcr    p15, 0, r0, c3, c0, 0    //; WCP15_DACR  r0
> +
> +        //; Setup DCLKCR to allow normal D-Cache line fills
> +        mcr    p15, 1, r0, c9, c0, 7    //; WCP15_DCLKCR r0
> +
> +        //; Setup the TLBLKCR
> +        //; Victim = 6'b000000; Floor = 6'b000000;
> +        //; IASIDCFG =
> +       //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
> +        mov    r1, #0x02
> +        mcr    p15, 0, r1, c10, c1, 3     //; WCP15_TLBLKCR  r1
> +
> +        //;Make sure TLBLKCR is complete before continuing
> +        ISB
> +
> +        //; Invalidate the UTLB
> +        mcr    p15, 0, r0, c8, c7, 0      //; UTLBIALL
> +
> +        //; Make sure UTLB request has been presented to macro before continuing
> +        ISB
> +
> +SYSI2:
> +        //; setup L2CR1 to some default Instruction and data prefetching values
> +        //; Users may want specific settings for various performance
> +       //; enhancements
> +        //; In Halcyon we do not have broadcasting barriers. So we need to turn
> +        //  ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
> +        ldr    r2, =0x133
> +        mcr    p15, 3, r2, c15, c0, 3     //; WCP15_L2CR1  r0
> +
> +
> +        //; Enable Z bit to enable branch prediction (default is off)
> +        mrc    p15, 0, r2, c1, c0, 0      //; RCP15_SCTLR  r2
> +        orr    r2, r2, #0x00000800
> +        mcr    p15, 0, r2, c1, c0, 0      //; WCP15_SCTLR  r2
> +
> +        //; Make sure Link stack is initialized with branch and links to
> +       //; sequential addresses
> +        //; This aids in creating a predictable startup environment
> +        bl     SEQ1
> +SEQ1:   bl     SEQ2
> +SEQ2:   bl     SEQ3
> +SEQ3:   bl     SEQ4
> +SEQ4:   bl     SEQ5
> +SEQ5:   bl     SEQ6
> +SEQ6:   bl     SEQ7
> +SEQ7:   bl     SEQ8
> +SEQ8:
> +
> +        //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
> +        //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
> +       //;debug registers
> +        //; Writing anything but the "secret code" to the DBGOSLAR clears the
> +       //;DBGOSLSR[LOCK] bit
> +        mcr    p14, 0, r0, c1, c0, 4       //; WCP14_DBGOSLAR r0
> +
> +
> +        //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
> +        //; Any read to DBGPRSR clear the STICKYPD bit
> +        //; ISB guarantees the read completes before attempting to
> +        //; execute a CP14 instruction.
> +        mrc    p14, 0, r3, c1, c5, 4       //; RCP14_DBGPRSR r3
> +        ISB
> +
> +        //; Initialize the Watchpoint Control Registers to zero (optional)

If that is optional, why do it?

> +        //;;; mcr    p14, 0, r0, c0, c0, 7       ; WCP14_DBGWCR0  r0
> +        //;;; mcr    p14, 0, r0, c0, c1, 7       ; WCP14_DBGWCR1  r0
> +
> +
> +        //;--------------------------------------------------------------------
> +        //; The saved Program Status Registers (SPSRs) should be setup
> +        //; prior to any automatic mode switches. The following
> +        //; code sets these registers up to a known state. Users will need to
> +        //; customize these settings to meet their needs.
> +        //;--------------------------------------------------------------------
> +        mov    r2,  #0x1f
> +        mov    r1,  #0xd7                 //;ABT mode
> +        msr    cpsr_c, r1                 //;ABT mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +        mov    r1,  #0xdb                 //;UND mode
> +        msr    cpsr_c, r1                 //;UND mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +        mov    r1,  #0xd1                 //;FIQ mode
> +        msr    cpsr_c, r1                 //;FIQ mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +        mov    r1,  #0xd2                 //;IRQ mode
> +        msr    cpsr_c, r1                 //;IRQ mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +        mov    r1,  #0xd6                 //;Monitor mode
> +        msr    cpsr_c, r1                 //;Monitor mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +        mov    r1,  #0xd3                 //;SVC mode
> +        msr    cpsr_c, r1                 //;SVC mode
> +        msr    spsr_cxfs, r2              //;clear the spsr
> +
> +
> +        //;--------------------------------------------------------------------
> +        //; Enabling Error reporting is something users may want to do at
> +        //; some other point in time. We have chosen some default settings
> +        //; that should be reviewed. Most of these registers come up in an
> +        //; unpredictable state after reset.
> +        //;--------------------------------------------------------------------
> +//;Start of error and control setting
> +
> +        //; setup L2CR0 with various L2/TCM control settings
> +        //; enable out of order bus attributes and error reporting
> +        //; this register comes up unpredictable after reset
> +        // movw   r1, #0x0F0F
> +.word 0xe3001f0f  // hardcoded movw instruction due to lack of compiler support
> +        // movT   r1, #0xC005
> +.word 0xe34c1005  // hardcoded movw instruction due to lack of compiler support
> +        mcr    p15, 3, r1, c15, c0, 1    //; WCP15_L2CR0  r1
> +
> +        //; setup L2CPUCR
> +        //; mov    r2, #0xFF
> +        //; Enable I and D cache parity
> +        //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
> +        //;tag, and data parity errors
> +        mov    r2, #0xe0
> +        mcr    p15, 3, r2, c15, c0, 2    //; WCP15_L2CPUCR  r2
> +
> +        //; setup SPCR
> +        //; enable all error reporting
> +       //;(reset value is unpredicatble for most bits)
> +        mov    r3, #0x0F
> +        mcr    p15, 0, r3, c9, c7, 0     //; WCP15_SPCR  r3
> +
> +        //; setup DMACHCRs (reset value unpredictable)
> +        //; control setting and enable all error reporting
> +        mov    r1, #0x0F
> +
> +        //; DMACHCR0 = 0000000F
> +        mov    r2, #0x00                  //; channel 0
> +        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
> +        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
> +
> +        //; DMACHCR1 = 0000000F
> +        mov    r2, #0x01                  //; channel 1
> +        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
> +        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
> +
> +        //; DMACHCR2 = 0000000F
> +        mov    r2, #0x02                  //; channel 2
> +        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
> +        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
> +
> +        //; DMACHCR3 = 0000000F
> +        mov    r2, #0x03                  //; channel 3
> +        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
> +        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
> +
> +        //; Set ACTLR (reset unpredictable)
> +        //; Set AVIVT control, error reporting, etc.
> +        //; mov   r3, #0x07
> +        //; Enable I and D cache parity
> +        //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
> +        //;ACTLR[5:4] = 2'h3 - enable parity
> +        //;ACTLR[19:18] =2'h3 - always generate and
> +       //;check parity(when MMU disabled).
> +        //;Value to be written #0xC0037
> +        // movw   r3, #0x0037
> +.word 0xe3003037  // hardcoded movw instruction due to lack of compiler support
> +        // movT   r3, #0x000C
> +.word 0xe340300c  // hardcoded movw instruction due to lack of compiler support
> +        mcr    p15, 0, r3, c1, c0, 1      //; WCP15_ACTLR  r3
> +
> +//;End of error and control setting
> +
> +        //;---------------------------------------------------------------------
> +        //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
> +        //; This is required for power saving whether the ETM is used or not.
> +        //;---------------------------------------------------------------------
> +
> +        //;Clear ETMOSLSR[LOCK] bit
> +        mov    r1, #0x00000000
> +        mcr    p14, 1, r1, c1, c0, 4        //; WCP14_ETMOSLAR      r1
> +
> +        //;Clear ETMPDSR[STICKYPD] bit
> +        mrc    p14, 1, r2, c1, c5, 4        //; RCP14_ETMPDSR       r2
> +        b       SET_SA
> +
> +
> +.ltorg
> diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
> new file mode 100644
> index 0000000..1c3f7ba
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/msm7630/timer.c
> @@ -0,0 +1,148 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * (C) Copyright 2010,2011
> + * NVIDIA Corporation<www.nvidia.com>
> + *
> + * (C) Copyright 2008
> + * Texas Instruments
> + *
> + * Richard Woodruff<r-woodruff2@ti.com>
> + * Syed Moahmmed Khasim<khasim@ti.com>
> + *
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH<www.elinos.com>
> + * Marius Groeger<mgroeger@sysgo.de>
> + * Alex Zuepke<azu@sysgo.de>
> + *
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering,<garyj@denx.de>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include<asm/arch/iomap.h>
> +#include<asm/io.h>
> +#include<config.h>
> +#include<common.h>
> +#include<asm/types.h>
> +#define TIMER_LOAD_VAL 0x21
> +
> +#define GPT_ENABLE_CLR_ON_MATCH_EN        2
> +#define GPT_ENABLE_EN                     1
> +#define DGT_ENABLE_CLR_ON_MATCH_EN        2
> +#define DGT_ENABLE_EN                     1
> +
> +#define SPSS_TIMER_STATUS_DGT_EN    (1<<  0)
> +
> +
> +#define READ_TIMER    readl(GPT_COUNT_VAL)
> +
> +static ulong timestamp;
> +static ulong lastinc;
> +#define DGT_HZ 6750000         /* Uses LPXO/4 (27.0 MHz / 4) */
> +
> +
> +/* nothing really to do with interrupts, just starts up a counter. */
> +int timer_init(void)
> +{
> +       uint32_t val = 0;
> +
> +       /* Disable timer */
> +       writel(0, DGT_ENABLE);
> +
> +       /* Check for the hardware revision */
> +       val = readl(HW_REVISION_NUMBER);
> +       val = (val>>  28)&  0x0F;
> +       if (val>= 1)
> +               writel(1, DGT_CLK_CTL);
> +       return 0;
> +}
> +
> +
> +ulong get_timer(ulong base)
> +{
> +       return get_timer_masked() - base;
> +}
> +
> +/* delay x useconds AND perserve advance timstamp value */
> +void __udelay(unsigned long usecs)
> +{
> +       unsigned int val;
> +       usecs = (usecs * 33 + 1000 - 33) / 1000;
> +
> +       writel(0, GPT_CLEAR);
> +       writel(0, GPT_ENABLE);
> +       do {
> +               val = 0;
> +               val = readl(GPT_COUNT_VAL);
> +       } while (val != 0);
> +
> +       writel(GPT_ENABLE_EN, GPT_ENABLE);
> +       do {
> +               val = 0;
> +               val = readl(GPT_COUNT_VAL);
> +       } while (val<  usecs) ;
> +
> +       writel(0, GPT_ENABLE);
> +       writel(0, GPT_CLEAR);
> +
> +}
> +
> +void reset_timer_masked(void)

Why do you need a timer reset function?

> +{
> +       /* reset time */
> +       lastinc = READ_TIMER;   /* capure current decrementer value time */
> +       timestamp = 0;          /* start "advancing" time stamp from 0 */
> +}
> +
> +ulong get_timer_masked(void)
> +{
> +       ulong now = READ_TIMER; /* current tick value */
> +
> +       if (lastinc<= now) {   /* normal mode (non roll) */
> +               /* normal mode */
> +               timestamp += now - lastinc;
> +               /* move stamp forward with absolute diff ticks */
> +       } else {                /* we have overflow of the count down timer */
> +               timestamp += now + (TIMER_LOAD_VAL - lastinc);
> +       }
> +       lastinc = now;
> +
> +       return timestamp;
> +}
> +
> +/*
> + * This function is derived from PowerPC code (read timebase as long long).
> + * On ARM it just returns the timer value.
> + */
> +unsigned long long get_ticks(void)
> +{
> +       return get_timer(0);
> +}
> +
> +/*
> + * This function is derived from PowerPC code (timebase clock frequency).
> + * On ARM it returns the number of timer ticks per second.
> + */
> +ulong get_tbclk(void)
> +{
> +       return 19200000;
> +}
> diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
> new file mode 100644
> index 0000000..0e8af85
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/adm.h
> @@ -0,0 +1,28 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef __ADM_H
> +#define __ADM_H
> +
> +/* Channel #s and security domain */
> +#define ADM_CHN         8
> +#define ADM_SD          2
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
> new file mode 100644
> index 0000000..af6ddaa
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/gpio.h
> @@ -0,0 +1,47 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef __GPIO_H
> +#define __GPIO_H
> +
> +#ifndef GPIO_INPUT
> +#define GPIO_INPUT     0x0000
> +#endif
> +#ifndef GPIO_OUTPUT
> +#define GPIO_OUTPUT    0x0001
> +#endif
> +
> +#define GPIO_LEVEL     0x0000
> +#define GPIO_EDGE      0x0010
> +
> +#define GPIO_RISING    0x0020
> +#define GPIO_FALLING   0x0040
> +
> +#define GPIO_HIGH      0x0020
> +#define GPIO_LOW       0x0040
> +
> +#define GPIO_PULLUP    0x0100
> +#define GPIO_PULLDOWN  0x0200
> +
> +int gpio_config(unsigned nr, unsigned flags);
> +void gpio_set(unsigned nr, unsigned on);
> +int gpio_get(unsigned nr);
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
> new file mode 100644
> index 0000000..c8244d8
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
> @@ -0,0 +1,168 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef __GPIO_HW_H
> +#define __GPIO_HW_H
> +
> +#define MSM_GPIO1_BASE 0xAC001000
> +#define MSM_GPIO2_BASE 0xAC101000
> +
> +#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
> +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
> +
> +/* output value */
> +#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0   */
> +#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  43-16  */
> +#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-44  */
> +#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68  */
> +#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95  */
> +#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 133-107 */
> +#define GPIO_OUT_6         GPIO1_REG(0xC4)  /* gpio 150-134 */
> +#define GPIO_OUT_7         GPIO1_REG(0x214)  /* gpio 181-151 */
> +
> +/* same pin map as above, output enable */
> +#define GPIO_OE_0          GPIO1_REG(0x10)
> +#define GPIO_OE_1          GPIO2_REG(0x08)
> +#define GPIO_OE_2          GPIO1_REG(0x14)
> +#define GPIO_OE_3          GPIO1_REG(0x18)
> +#define GPIO_OE_4          GPIO1_REG(0x1C)
> +#define GPIO_OE_5          GPIO1_REG(0x54)
> +#define GPIO_OE_6          GPIO1_REG(0xC8)
> +#define GPIO_OE_7          GPIO1_REG(0x218)
> +
> +/* same pin map as above, input read */
> +#define GPIO_IN_0          GPIO1_REG(0x34)
> +#define GPIO_IN_1          GPIO2_REG(0x20)
> +#define GPIO_IN_2          GPIO1_REG(0x38)
> +#define GPIO_IN_3          GPIO1_REG(0x3C)
> +#define GPIO_IN_4          GPIO1_REG(0x40)
> +#define GPIO_IN_5          GPIO1_REG(0x44)
> +#define GPIO_IN_6          GPIO1_REG(0xCC)
> +#define GPIO_IN_7          GPIO1_REG(0x21C)
> +
> +/* same pin map as above, 1=edge 0=level interrup */
> +#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
> +#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
> +#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
> +#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
> +#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
> +#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
> +#define GPIO_INT_EDGE_6    GPIO1_REG(0xD0)
> +#define GPIO_INT_EDGE_7    GPIO1_REG(0x240)
> +
> +/* same pin map as above, 1=positive 0=negative */
> +#define GPIO_INT_POS_0     GPIO1_REG(0x70)
> +#define GPIO_INT_POS_1     GPIO2_REG(0x58)
> +#define GPIO_INT_POS_2     GPIO1_REG(0x74)
> +#define GPIO_INT_POS_3     GPIO1_REG(0x78)
> +#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
> +#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
> +#define GPIO_INT_POS_6     GPIO1_REG(0xD4)
> +#define GPIO_INT_POS_7     GPIO1_REG(0x228)
> +
> +/* same pin map as above, interrupt enable */
> +#define GPIO_INT_EN_0      GPIO1_REG(0x80)
> +#define GPIO_INT_EN_1      GPIO2_REG(0x60)
> +#define GPIO_INT_EN_2      GPIO1_REG(0x84)
> +#define GPIO_INT_EN_3      GPIO1_REG(0x88)
> +#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
> +#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
> +#define GPIO_INT_EN_6      GPIO1_REG(0xD8)
> +#define GPIO_INT_EN_7      GPIO1_REG(0x22C)
> +
> +/* same pin map as above, write 1 to clear interrupt */
> +#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
> +#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
> +#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
> +#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
> +#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
> +#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
> +#define GPIO_INT_CLEAR_6   GPIO1_REG(0xDC)
> +#define GPIO_INT_CLEAR_7   GPIO1_REG(0x230)
> +
> +/* same pin map as above, 1=interrupt pending */
> +#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
> +#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
> +#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
> +#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
> +#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
> +#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
> +#define GPIO_INT_STATUS_6  GPIO1_REG(0xE0)
> +#define GPIO_INT_STATUS_7  GPIO1_REG(0x234)
> +
> +
> +#define GPIO_OUT_VAL_REG_BASE     0xABC00000
> +#define GPIO_ALT_FUNC_PAGE_REG    (GPIO_OUT_VAL_REG_BASE + 0x20)
> +#define GPIO_ALT_FUNC_CFG_REG     (GPIO_OUT_VAL_REG_BASE + 0x24)
> +
> +
> +/* GPIO TLMM: Pullup/Pulldown */
> +#define GPIO_NO_PULL    0
> +#define GPIO_PULL_DOWN  1
> +#define GPIO_KEEPER     2
> +#define GPIO_PULL_UP    3
> +
> +/* GPIO TLMM: Drive Strength */
> +#define GPIO_2MA        0
> +#define GPIO_4MA        1
> +#define GPIO_6MA        2
> +#define GPIO_8MA        3
> +#define GPIO_10MA       4
> +#define GPIO_12MA       5
> +#define GPIO_14MA       6
> +#define GPIO_16MA       7
> +
> +#define GPIO38_GPIO_CNTRL      0x175
> +
> +/* GPIO TLMM: Status */
> +#define GPIO_ENABLE     0
> +#define GPIO_DISABLE    1
> +
> +#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
> +       ((((gpio)&  0x3FF)<<  4)        |   \
> +       ((func)&  0xf)                  |   \
> +       (((dir)&  0x1)<<  14)           |   \
> +       (((pull)&  0x3)<<  15)          |   \
> +       (((drvstr)&  0xF)<<  17))
> +
> +/**
> + * struct msm_gpio - GPIO pin description
> + * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
> + * @label - textual label
> + *
> + * Usually, GPIO's are operated by sets.
> + * This struct accumulate all GPIO information in single source
> + * and facilitete group operations provided by msm_gpios_xxx()
> + */
> +struct msm_gpio {
> +       unsigned gpio_cfg;
> +       const char *label;
> +};
> +
> +/**
> + * extract GPIO pin from bit-field used for gpio_tlmm_config
> + */
> +#define GPIO_PIN(gpio_cfg)    (((gpio_cfg)>>   4)&  0x3ff)
> +#define GPIO_FUNC(gpio_cfg)   (((gpio_cfg)>>   0)&  0xf)
> +#define GPIO_DIR(gpio_cfg)    (((gpio_cfg)>>  14)&  0x1)
> +#define GPIO_PULL(gpio_cfg)   (((gpio_cfg)>>  15)&  0x3)
> +#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg)>>  17)&  0xf)
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
> new file mode 100644
> index 0000000..186c6c2
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/iomap.h
> @@ -0,0 +1,96 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef __IOMAP_H_
> +#define __IOMAP_H_
> +
> +#define MSM_UART1_BASE 0xACA00000
> +#define MSM_UART2_BASE 0xACB00000
> +#define MSM_UART3_BASE 0xACC00000
> +
> +#define MSM_VIC_BASE   0xC0080000
> +#define MSM_TMR_BASE   0xC0100000
> +
> +#define MSM_GPT_BASE      (MSM_TMR_BASE + 0x04)
> +#define MSM_DGT_BASE      (MSM_TMR_BASE + 0x24)
> +#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
> +
> +#define GPT_REG(off)      (MSM_GPT_BASE + (off))
> +#define DGT_REG(off)      (MSM_DGT_BASE + (off))
> +
> +#define GPT_MATCH_VAL      GPT_REG(0x0000)
> +#define GPT_COUNT_VAL      GPT_REG(0x0004)
> +#define GPT_ENABLE         GPT_REG(0x0008)
> +#define GPT_CLEAR          GPT_REG(0x000C)
> +
> +#define DGT_MATCH_VAL      DGT_REG(0x0000)
> +#define DGT_COUNT_VAL      DGT_REG(0x0004)
> +#define DGT_ENABLE         DGT_REG(0x0008)
> +#define DGT_CLEAR          DGT_REG(0x000C)
> +#define DGT_CLK_CTL        DGT_REG(0x0010)
> +
> +#define HW_REVISION_NUMBER   0xABC00270
> +
> +#define MSM_CSR_BASE    0xC0100000
> +#define MSM_GCC_BASE   0xC0182000
> +
> +#define MSM_SDC1_BASE   0xA0400000
> +#define MSM_SDC2_BASE   0xA0500000
> +#define MSM_SDC3_BASE   0xA3000000
> +#define MSM_SDC4_BASE   0xA3100000
> +
> +#define MSM_SHARED_BASE      0x00100000
> +#define MSM_CLK_CTL_BASE        0xAB800000
> +#define MSM_CLK_CTL_SH2_BASE    0xABA01000
> +
> +#define REG_BASE(off)           (MSM_CLK_CTL_BASE + (off))
> +#define REG_SH2_BASE(off)       (MSM_CLK_CTL_SH2_BASE + (off))
> +
> +#define SCSS_CLK_CTL            0xC0101004
> +#define SCSS_CLK_SEL            0xC0101008
> +
> +#define MSM_USB_BASE                   0xA3600000
> +#define MSM_CRYPTO_BASE                        0xA8400000
> +
> +#define SH2_USBH_MD_REG         REG_SH2_BASE(0x2BC)
> +#define SH2_USBH_NS_REG         REG_SH2_BASE(0x2C0)
> +
> +#define SH2_MDP_NS_REG          REG_SH2_BASE(0x14C)
> +#define SH2_MDP_LCDC_MD_REG     REG_SH2_BASE(0x38C)
> +#define SH2_MDP_LCDC_NS_REG     REG_SH2_BASE(0x390)
> +#define SH2_MDP_VSYNC_REG       REG_SH2_BASE(0x460)
> +#define SH2_PMDH_NS_REG         REG_SH2_BASE(0x8C)
> +
> +#define SH2_GLBL_CLK_ENA_SC     REG_SH2_BASE(0x3BC)
> +#define SH2_GLBL_CLK_ENA_2_SC   REG_SH2_BASE(0x3C0)
> +
> +#define SH2_OWN_ROW1_BASE_REG   REG_BASE(0x041C)
> +#define SH2_OWN_ROW2_BASE_REG   REG_BASE(0x0424)
> +#define SH2_OWN_APPS2_BASE_REG  REG_BASE(0x0414)
> +
> +#define MSM_ADM_BASE            0xAC200000
> +#define MSM_ADM_SD_OFFSET       0x00100400
> +
> +#define MSM_SAW_BASE            0xC0102000
> +
> +#define PLL_ENA_REG             REG_SH2_BASE(0x0264)
> +#define PLL2_STATUS_BASE_REG    REG_BASE(0x0350)
> +#define PLL2_L_VAL_ADDR         REG_BASE(0x033C)
> +#endif
> diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
> new file mode 100644
> index 0000000..3df08b9
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
> @@ -0,0 +1,42 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef __PROC_COMM_H_
> +#define __PROC_COMM_H_
> +
> +void usb_clock_init(void);
> +void lcdc_clock_init(unsigned rate);
> +void mdp_clock_init(unsigned rate);
> +void uart3_clock_init(void);
> +void uart2_clock_init(void);
> +void uart1_clock_init(void);
> +void mddi_clock_init(unsigned num, unsigned rate);
> +void reboot(unsigned reboot_reason);
> +int mmc_clock_enable_disable(unsigned id, unsigned enable);
> +int mmc_clock_set_rate(unsigned id, unsigned rate);
> +int mmc_clock_get_rate(unsigned id);
> +int gpio_tlmm_config(unsigned config, unsigned disable);
> +int vreg_set_level(unsigned id, unsigned mv);
> +int vreg_enable(unsigned id);
> +int vreg_disable(unsigned id);
> +
> +#endif
> +
> +
> diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
> new file mode 100644
> index 0000000..c679d92
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
> @@ -0,0 +1,29 @@
> +/*
> + * (C) Copyright 2012
> + * LARSEN&  TOUBRO INFOTECH LTD<www.lntinfotech.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + *
> + */
> +
> +#ifndef _SYS_PROTO_H_
> +#define _SYS_PROTO_H_
> +
> +void pll8_enable(void);
> +void clock_init(void);
> +void __cpu_early_init(void);
> +
> +#endif
> +
> --
> 1.7.1
>
>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
>


Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 4/5] Add support for mmc read and writes
  2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
@ 2012-02-29  0:03   ` Albert ARIBAUD
  2012-03-05 14:40   ` [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller Mohamed Haneef
  1 sibling, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2012-02-29  0:03 UTC (permalink / raw)
  To: u-boot

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef@lntinfotech.com>
>
>          *Support for msm7x30 mmc read and writes

The patch title is misleading. MMC reads and writes are already 
supported in U-Boot; what you add is support for the qc_mc MMC controller.

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication
  2012-02-28 23:46   ` Albert ARIBAUD
@ 2012-03-05 14:33     ` Mohamed Haneef
  0 siblings, 0 replies; 716+ messages in thread
From: Mohamed Haneef @ 2012-03-05 14:33 UTC (permalink / raw)
  To: u-boot

Hi Albert,

This driver uses shared memory region to pass message. this is used in acpuclock.c, gpio.c files. So need to retain this patch as it is.

Thanks and Regards,
Mohamed Haneef M.A
08985734122
________________________________________
From: Albert ARIBAUD [albert.u.boot at aribaud.net]
Sent: Wednesday, February 29, 2012 5:16 AM
To: Mohamed Haneef
Cc: u-boot at lists.denx.de; wd at denx.de
Subject: Re: [PATCH 2/5] msm7x30: Add support for interprocessor communication

Hi Mohamed,

Le 16/02/2012 03:59, mohamed.haneef at lntinfotech.com a ?crit :
> From: Mohamed Haneef<mohamed.haneef@lntinfotech.com>
>
>          *Support for msm7x30 interprocessor communication

Is this used at some point in the patch set? If not, remove it and
introduce it back within a patchset that uses it.

Amicalement,
--
Albert.

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v2 1/5] msm7x30: Add Support for low speed uart on msm7x30
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
  2012-02-28 23:44   ` Albert ARIBAUD
@ 2012-03-05 14:34   ` Mohamed Haneef
  2012-03-22  8:50   ` [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 716+ messages in thread
From: Mohamed Haneef @ 2012-03-05 14:34 UTC (permalink / raw)
  To: u-boot

        * Support for low speed uart

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
Changes for v2:
 - Removed unused macros

 drivers/serial/Makefile          |    1 +
 drivers/serial/serial_msm_uart.c |  156 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/serial_msm_uart.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 616b857..2801edc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -55,6 +55,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
 COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
 COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
 COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_MSM_UART) += serial_msm_uart.o

 ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_msm_uart.c b/drivers/serial/serial_msm_uart.c
new file mode 100644
index 0000000..8f80561
--- /dev/null
+++ b/drivers/serial/serial_msm_uart.c
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+#define UART_MR1         0x0000
+
+
+#define UART_MR2         0x0004
+
+#define UART_CSR         0x0008
+#define UART_CSR_115200  0xFF
+
+#define UART_TF          0x000C
+
+#define UART_CR          0x0010
+#define UART_CR_CMD_MODE_RESET     (12 << 4)
+
+#define UART_IMR         0x0014
+
+#define UART_IPR         0x0018
+#define UART_TFWR        0x001C
+#define UART_RFWR        0x0020
+#define UART_HCR         0x0024
+
+#define UART_MREG        0x0028
+#define UART_NREG        0x002C
+#define UART_DREG        0x0030
+#define UART_MNDREG      0x0034
+#define UART_IRDA        0x0038
+
+#define UART_SR          0x0008
+#define UART_SR_TX_READY       (1 << 2)
+#define UART_SR_RX_READY       (1 << 0)
+
+#define UART_RF          0x000C
+
+
+#if PLATFORM_MSM7X30
+static unsigned uart_base = MSM_UART2_BASE;
+#elif PLATFORM_MSM7X27A
+static unsigned uart_base = MSM_UART1_BASE;
+#else
+static unsigned uart_base = MSM_UART3_BASE;
+#endif
+
+#define uwr(v, a) writel(v, uart_base + (a))
+#define urd(a) readl(uart_base + (a))
+
+void uart_init(void)
+{
+       uwr(0x0A, UART_CR);  /* disable TX and RX */
+       uwr(0x30, UART_CR);  /* reset error status */
+       uwr(0x10, UART_CR);  /* reset receiver */
+       uwr(0x20, UART_CR);  /* reset transmitter */
+#if PLATFORM_QSD8K || PLATFORM_MSM7X30 || PLATFORM_MSM7X27A
+       /* TCXO */
+       uwr(0x06, UART_MREG);
+       uwr(0xF1, UART_NREG);
+       uwr(0x0F, UART_DREG);
+       uwr(0x1A, UART_MNDREG);
+#else
+       /* TCXO/4 */
+       uwr(0xC0, UART_MREG);
+       uwr(0xAF, UART_NREG);
+       uwr(0x80, UART_DREG);
+       uwr(0x19, UART_MNDREG);
+#endif
+       uwr(0x10, UART_CR);  /* reset RX */
+       uwr(0x20, UART_CR);  /* reset TX */
+       uwr(0x30, UART_CR);  /* reset error status */
+       uwr(0x40, UART_CR);  /* reset RX break */
+       uwr(0x70, UART_CR);  /* rest? */
+       uwr(0xD0, UART_CR);  /* reset */
+       uwr(0x7BF, UART_IPR); /* stale timeout = 630 * bitrate */
+       uwr(0, UART_IMR);
+       uwr(115, UART_RFWR); /* RX watermark = 58 * 2 - 1 */
+       uwr(10, UART_TFWR);  /* TX watermark */
+       uwr(0, UART_RFWR);
+       uwr(UART_CSR_115200, UART_CSR);
+       uwr(0, UART_IRDA);
+       uwr(0x1E, UART_HCR);
+       uwr(16, UART_MR1);
+       uwr(0x34, UART_MR2); /* 8N1 */
+       uwr(0x05, UART_CR); /* enable TX & RX */
+
+}
+
+static int _uart_putc(int port, char c)
+{
+       while (!(urd(UART_SR) & UART_SR_TX_READY))
+               ;
+       uwr(c, UART_TF);
+       return 0;
+}
+
+int serial_init(void)
+{
+       uart_init();
+       return 0;
+}
+
+void serial_putc(char c)
+{
+       if (c == '\n')
+               _uart_putc(0, '\r');
+       _uart_putc(0, c);
+}
+
+void serial_putc_raw(const char c)
+{
+       _uart_putc(0, c);
+}
+
+void serial_puts(const char *s)
+{
+       while (*s)
+               serial_putc(*s++);
+}
+
+int serial_getc()
+{
+       while (!(urd(UART_SR) & UART_SR_RX_READY))
+               ;
+       return urd(UART_RF);
+}
+
+int serial_tstc()
+{
+       return urd(UART_SR) & UART_SR_RX_READY;
+}
+
+void serial_setbrg()
+{
+}
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v2 3/5] msm7x30: Add support for msm7x30 SoC
  2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
  2012-02-29  0:00   ` Albert ARIBAUD
@ 2012-03-05 14:39   ` Mohamed Haneef
  1 sibling, 0 replies; 716+ messages in thread
From: Mohamed Haneef @ 2012-03-05 14:39 UTC (permalink / raw)
  To: u-boot

        * Support for Qualcomm msm7630 SoC

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---

Changes for v2:
 - removed BIT() macro and replacing with (3 << 6) in the macro VERG_CONFIG
 - removed the unwanted comment line
 - removed Intitalize the Watchpoint Controll Register to zero, since optional
 - removed reset_timer_masked function since it is not used any where


 arch/arm/cpu/armv7/msm7630/Makefile           |   59 +++
 arch/arm/cpu/armv7/msm7630/acpuclock.c        |  327 +++++++++++++
 arch/arm/cpu/armv7/msm7630/board.c            |   57 +++
 arch/arm/cpu/armv7/msm7630/config.mk          |    1 +
 arch/arm/cpu/armv7/msm7630/gpio.c             |  229 +++++++++
 arch/arm/cpu/armv7/msm7630/lowlevel_init.S    |  623 +++++++++++++++++++++++++
 arch/arm/cpu/armv7/msm7630/timer.c            |  142 ++++++
 arch/arm/include/asm/arch-msm7630/adm.h       |   28 ++
 arch/arm/include/asm/arch-msm7630/gpio.h      |   47 ++
 arch/arm/include/asm/arch-msm7630/gpio_hw.h   |  168 +++++++
 arch/arm/include/asm/arch-msm7630/iomap.h     |   96 ++++
 arch/arm/include/asm/arch-msm7630/proc_comm.h |   42 ++
 arch/arm/include/asm/arch-msm7630/sys_proto.h |   29 ++
 13 files changed, 1848 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/msm7630/Makefile
 create mode 100644 arch/arm/cpu/armv7/msm7630/acpuclock.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/board.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/config.mk
 create mode 100644 arch/arm/cpu/armv7/msm7630/gpio.c
 create mode 100644 arch/arm/cpu/armv7/msm7630/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/msm7630/timer.c
 create mode 100644 arch/arm/include/asm/arch-msm7630/adm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/gpio_hw.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/iomap.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/proc_comm.h
 create mode 100644 arch/arm/include/asm/arch-msm7630/sys_proto.h

diff --git a/arch/arm/cpu/armv7/msm7630/Makefile b/arch/arm/cpu/armv7/msm7630/Makefile
new file mode 100644
index 0000000..d9dfade
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/Makefile
@@ -0,0 +1,59 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011 Nvidia Corporation.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+#CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
+#CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+
+include $(TOPDIR)/config.mk
+
+LIB    =  $(obj)lib$(SOC).o
+
+SOBJS-y        := lowlevel_init.o
+COBJS-y                := board.o
+COBJS-y                += timer.o
+COBJS-y                += acpuclock.o
+COBJS-y                += gpio.o
+
+ SRCS  := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS  := $(addprefix $(obj),$(COBJS-y) $(SOBJS-y))
+
+all:    $(obj).depend $(LIB)
+
+$(LIB):        $(OBJS)
+       $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/msm7630/acpuclock.c b/arch/arm/cpu/armv7/msm7630/acpuclock.c
new file mode 100644
index 0000000..73570fc
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/acpuclock.c
@@ -0,0 +1,327 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <common.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/proc_comm.h>
+#define ACPU_806MHZ            42
+#define ACPU_1024MHZ           53
+#define ACPU_1200MHZ           125
+#define ACPU_1400MHZ           73
+
+/* Macros to select PLL2 with divide by 1 */
+#define ACPU_SRC_SEL           3
+#define ACPU_SRC_DIV           0
+
+#define VREG_CONFIG    (3 << 6)
+#define VREG_DATA      (VREG_CONFIG | (VREF_SEL << 5))
+#define VREF_SEL       1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
+#define V_STEP         (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
+#define MV(mv)         ((mv) / (!((mv) % V_STEP)))
+/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
+#define VDD_RAW(mv)    (((MV(mv) / V_STEP) - 30) | VREG_DATA)
+
+
+/* enum for SDC CLK IDs */
+enum {
+       SDC1_CLK  = 19,
+       SDC1_PCLK = 20,
+       SDC2_CLK  = 21,
+       SDC2_PCLK = 22,
+       SDC3_CLK  = 23,
+       SDC3_PCLK = 24,
+       SDC4_CLK  = 25,
+       SDC4_PCLK = 26
+};
+
+/* Zero'th entry is dummy */
+static uint8_t sdc_clk[]  = {0, SDC1_CLK,  SDC2_CLK,  SDC3_CLK,  SDC4_CLK};
+static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK};
+
+void spm_init(void)
+{
+       writel(0x05, MSM_SAW_BASE + 0x10); /* MSM_SPM_REG_SAW_CFG */
+       writel(0x18, MSM_SAW_BASE + 0x14); /* MSM_SPM_REG_SAW_SPM_CTL */
+       writel(0x00006666, MSM_SAW_BASE + 0x18);
+       /* MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY */
+       writel(0xFF000666, MSM_SAW_BASE + 0x1C);
+       /* MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY */
+       writel(0x01, MSM_SAW_BASE + 0x24); /* MSM_SPM_REG_SAW_SLP_CLK_EN */
+       writel(0x03, MSM_SAW_BASE + 0x28);
+       /* MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN */
+       writel(0x00, MSM_SAW_BASE + 0x2C);
+       /* MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN */
+       writel(0x01, MSM_SAW_BASE + 0x30); /* MSM_SPM_REG_SAW_SLP_CLMP_EN */
+       writel(0x00, MSM_SAW_BASE + 0x34); /* MSM_SPM_REG_SAW_SLP_RST_EN */
+       writel(0x00, MSM_SAW_BASE + 0x38); /* MSM_SPM_REG_SAW_SPM_MPM_CFG */
+}
+
+/* Configures msmc2 voltage. vlevel is in mV */
+void msmc2_config(unsigned vlevel)
+{
+       unsigned val;
+       val = readl(MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+       val &= ~0xFF;
+       val |= VDD_RAW(vlevel);
+       writel(val, MSM_SAW_BASE + 0x08); /* MSM_SPM_REG_SAW_VCTL */
+       /* Wait for PMIC state to return to idle and for VDD to stabilize */
+       while (((readl(MSM_SAW_BASE + 0x0C) >> 20) & 0x3) != 0)
+               ;
+       udelay(160);
+}
+
+void enable_pll(unsigned num)
+{
+       unsigned reg_val;
+       reg_val = readl(PLL_ENA_REG);
+       reg_val |= (1 << num);
+       writel(reg_val, PLL_ENA_REG);
+       /* Wait until PLL is enabled */
+       while ((readl(PLL2_STATUS_BASE_REG) & (1 << 16)) == 0)
+               ;
+}
+
+void acpu_clock_init(void)
+{
+       unsigned clk, reg_clksel, reg_clkctl, src_sel;
+       /* Fixing msmc2 voltage */
+       spm_init();
+       clk = readl(PLL2_L_VAL_ADDR) & 0xFF;
+       if (clk == ACPU_806MHZ)
+               msmc2_config(1100);
+       else if (clk == ACPU_1024MHZ || clk == ACPU_1200MHZ)
+               msmc2_config(1200);
+       else if (clk == ACPU_1400MHZ)
+               msmc2_config(1250);
+       /* Enable pll 2 */
+       enable_pll(2);
+       reg_clksel = readl(SCSS_CLK_SEL);
+       /* CLK_SEL_SRC1NO */
+       src_sel = reg_clksel & 1;
+       /* Program clock source and divider. */
+       reg_clkctl = readl(SCSS_CLK_CTL);
+       reg_clkctl &= ~(0xFF << (8 * src_sel));
+       reg_clkctl |= ACPU_SRC_SEL << (4 + 8 * src_sel);
+       reg_clkctl |= ACPU_SRC_DIV << (0 + 8 * src_sel);
+       writel(reg_clkctl, SCSS_CLK_CTL);
+       /* Toggle clock source. */
+       reg_clksel ^= 1;
+       /* Program clock source selection. */
+       writel(reg_clksel, SCSS_CLK_SEL);
+}
+
+void hsusb_clock_init(void)
+{
+       int val = 0;
+       unsigned sh2_own_row2;
+       unsigned sh2_own_row2_hsusb_mask = (1 << 11);
+
+       sh2_own_row2 = readl(SH2_OWN_ROW2_BASE_REG);
+       if (sh2_own_row2 & sh2_own_row2_hsusb_mask) {
+               /* USB local clock control enabled */
+               /* Set value in MD register */
+               val = 0x5DF;
+               writel(val, SH2_USBH_MD_REG);
+               /* Set value in NS register */
+               val = 1 << 8;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 11;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 9;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               val = 1 << 13;
+               val = val | readl(SH2_USBH_NS_REG);
+               writel(val, SH2_USBH_NS_REG);
+               /* Enable USBH_P_CLK */
+               val = 1 << 25;
+               val = val | readl(SH2_GLBL_CLK_ENA_SC);
+               writel(val, SH2_GLBL_CLK_ENA_SC);
+       } else
+               /* USB local clock control not enabled; use proc comm */
+               usb_clock_init();
+
+}
+
+void adm_enable_clock(void)
+{
+       unsigned int val = 0;
+
+       /* Enable ADM_CLK */
+       val = 1 << 5;
+       val = val | readl(SH2_GLBL_CLK_ENA_SC);
+       writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+void mdp_lcdc_clock_init(void)
+{
+       unsigned int val = 0;
+       unsigned sh2_own_apps2;
+       unsigned sh2_own_apps2_lcdc_mask = (1 << 3);
+
+       sh2_own_apps2 = readl(SH2_OWN_APPS2_BASE_REG);
+       if (sh2_own_apps2 & sh2_own_apps2_lcdc_mask) {
+               /* MDP local clock control enabled */
+               /* Select clock source and divider */
+               val = 0x29;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable MDP source clock(root) */
+               val = 1 << 11;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable graphics clock(branch) */
+               val = 1 << 9;
+               val = val | readl(SH2_MDP_NS_REG);
+               writel(val, SH2_MDP_NS_REG);
+
+               /* Enable MDP_P_CLK */
+               val = 1 << 6;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+               /* Enable AXI_MDP_CLK */
+               val = 1 << 29;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+
+               /* LCDC local clock control enabled */
+               /* Set value in MD register */
+               val = 0x1FFF9;
+               writel(val, SH2_MDP_LCDC_MD_REG);
+
+               /* Set MDP_LCDC_N_VAL in NS register */
+               val = 0xFFFA << 16;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set clock source */
+               val = 1;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set divider */
+               val = 3 << 3;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Set MN counter mode */
+               val = 2 << 5;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable MN counter */
+               val = 1 << 8;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_src(root) clock */
+               val = 1 << 11;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_pclk(branch) clock */
+               val = 1 << 9;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+
+               /* Enable mdp_lcdc_pad_pclk(branch) clock */
+               val = 1 << 12;
+               val = val | readl(SH2_MDP_LCDC_NS_REG);
+               writel(val, SH2_MDP_LCDC_NS_REG);
+       } else {
+               /* MDP local clock control not enabled; use proc comm */
+               mdp_clock_init(122880000);
+               /* LCDC local clock control not enabled; use proc comm */
+               lcdc_clock_init(27648000);
+       }
+}
+
+void mddi_pmdh_clock_init(void)
+{
+       unsigned int val = 0;
+       unsigned sh2_own_row1;
+       unsigned sh2_own_row1_pmdh_mask = (1 << 19);
+
+       sh2_own_row1 = readl(SH2_OWN_ROW1_BASE_REG);
+       if (sh2_own_row1 & sh2_own_row1_pmdh_mask) {
+               /* Select clock source and divider */
+               val = 1;
+               val |= (1 << 3);
+               val = val | readl(SH2_PMDH_NS_REG);
+               writel(val, SH2_PMDH_NS_REG);
+
+               /* Enable PMDH_SRC (root) signal */
+               val = 1 << 11;
+               val = val | readl(SH2_PMDH_NS_REG);
+               writel(val, SH2_PMDH_NS_REG);
+
+               /* Enable PMDH_P_CLK */
+               val = 1 << 4;
+               val = val | readl(SH2_GLBL_CLK_ENA_2_SC);
+               writel(val, SH2_GLBL_CLK_ENA_2_SC);
+       } else
+               /* MDDI local clock control not enabled; use proc comm */
+               mddi_clock_init(0, 480000000);
+}
+
+void ce_clock_init(void)
+{
+       unsigned int val = 0;
+
+       /* Enable CE_CLK */
+       val = 1 << 6;
+       val = val | readl(SH2_GLBL_CLK_ENA_SC);
+       writel(val, SH2_GLBL_CLK_ENA_SC);
+}
+
+#ifdef CONFIG_QC_MMC
+/* Configure MMC clock */
+void clock_config_mmc(uint32_t interface, uint32_t freq)
+{
+       uint32_t reg = 0;
+
+       if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0)
+               printf("Failure setting clock rate for MCLK - "
+                                                 "clk_rate: %d\n!", freq);
+
+       /* enable clock */
+       if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0)
+               printf("Failure enabling MMC Clock!\n");
+
+       reg |= MMC_BOOT_MCI_CLK_ENABLE;
+       reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
+       reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
+       writel(reg, MMC_BOOT_MCI_CLK);
+}
+
+/* Intialize MMC clock */
+void clock_init_mmc(uint32_t interface)
+{
+       if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0)
+               printf("Failure enabling PCLK!\n");
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/board.c b/arch/arm/cpu/armv7/msm7630/board.c
new file mode 100644
index 0000000..c7b8204
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/board.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void set_vector_base(unsigned long addr)
+{
+       __asm__ volatile ("mcr   p15, 0, %0, c12, c0, 0" : : "r" (addr));
+}
+
+int dram_init(void)
+{
+       /* We do not initialise DRAM here. We just query the size */
+       gd->ram_size = PHYS_SDRAM_1_SIZE;
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+
+}
+
+#ifdef CONFIG_ARCH_CPU_INIT
+int arch_cpu_init()
+{
+       __cpu_early_init();
+       return 0;
+}
+#endif
diff --git a/arch/arm/cpu/armv7/msm7630/config.mk b/arch/arm/cpu/armv7/msm7630/config.mk
new file mode 100644
index 0000000..935a147
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/config.mk
@@ -0,0 +1 @@
+PLATFORM_CPPFLAGS += -march=armv7-a
diff --git a/arch/arm/cpu/armv7/msm7630/gpio.c b/arch/arm/cpu/armv7/msm7630/gpio.c
new file mode 100644
index 0000000..daa6d66
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/gpio.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/proc_comm.h>
+#include <asm/arch/gpio_hw.h>
+
+struct gpioregs {
+       unsigned out;
+       unsigned in;
+       unsigned int_status;
+       unsigned int_clear;
+       unsigned int_en;
+       unsigned int_edge;
+       unsigned int_pos;
+       unsigned oe;
+};
+
+static struct gpioregs GPIO_REGS[] = {
+       {
+               .out =          GPIO_OUT_0,
+               .in =           GPIO_IN_0,
+               .int_status =   GPIO_INT_STATUS_0,
+               .int_clear =    GPIO_INT_CLEAR_0,
+               .int_en =       GPIO_INT_EN_0,
+               .int_edge =     GPIO_INT_EDGE_0,
+               .int_pos =      GPIO_INT_POS_0,
+               .oe =           GPIO_OE_0,
+       },
+       {
+               .out =          GPIO_OUT_1,
+               .in =           GPIO_IN_1,
+               .int_status =   GPIO_INT_STATUS_1,
+               .int_clear =    GPIO_INT_CLEAR_1,
+               .int_en =       GPIO_INT_EN_1,
+               .int_edge =     GPIO_INT_EDGE_1,
+               .int_pos =      GPIO_INT_POS_1,
+               .oe =           GPIO_OE_1,
+       },
+       {
+               .out =          GPIO_OUT_2,
+               .in =           GPIO_IN_2,
+               .int_status =   GPIO_INT_STATUS_2,
+               .int_clear =    GPIO_INT_CLEAR_2,
+               .int_en =       GPIO_INT_EN_2,
+               .int_edge =     GPIO_INT_EDGE_2,
+               .int_pos =      GPIO_INT_POS_2,
+               .oe =           GPIO_OE_2,
+       },
+       {
+               .out =          GPIO_OUT_3,
+               .in =           GPIO_IN_3,
+               .int_status =   GPIO_INT_STATUS_3,
+               .int_clear =    GPIO_INT_CLEAR_3,
+               .int_en =       GPIO_INT_EN_3,
+               .int_edge =     GPIO_INT_EDGE_3,
+               .int_pos =      GPIO_INT_POS_3,
+               .oe =           GPIO_OE_3,
+       },
+       {
+               .out =          GPIO_OUT_4,
+               .in =           GPIO_IN_4,
+               .int_status =   GPIO_INT_STATUS_4,
+               .int_clear =    GPIO_INT_CLEAR_4,
+               .int_en =       GPIO_INT_EN_4,
+               .int_edge =     GPIO_INT_EDGE_4,
+               .int_pos =      GPIO_INT_POS_4,
+               .oe =           GPIO_OE_4,
+       },
+       {
+               .out =          GPIO_OUT_5,
+               .in =           GPIO_IN_5,
+               .int_status =   GPIO_INT_STATUS_5,
+               .int_clear =    GPIO_INT_CLEAR_5,
+               .int_en =       GPIO_INT_EN_5,
+               .int_edge =     GPIO_INT_EDGE_5,
+               .int_pos =      GPIO_INT_POS_5,
+               .oe =           GPIO_OE_5,
+       },
+       {
+               .out =          GPIO_OUT_6,
+               .in =           GPIO_IN_6,
+               .int_status =   GPIO_INT_STATUS_6,
+               .int_clear =    GPIO_INT_CLEAR_6,
+               .int_en =       GPIO_INT_EN_6,
+               .int_edge =     GPIO_INT_EDGE_6,
+               .int_pos =      GPIO_INT_POS_6,
+               .oe =           GPIO_OE_6,
+       },
+       {
+               .out =          GPIO_OUT_7,
+               .in =           GPIO_IN_7,
+               .int_status =   GPIO_INT_STATUS_7,
+               .int_clear =    GPIO_INT_CLEAR_7,
+               .int_en =       GPIO_INT_EN_7,
+               .int_edge =     GPIO_INT_EDGE_7,
+               .int_pos =      GPIO_INT_POS_7,
+               .oe =           GPIO_OE_7,
+       },
+};
+
+static struct gpioregs *find_gpio(unsigned n, unsigned *bit)
+{
+       if (n > 150) {
+               *bit = 1 << (n - 151);
+               return GPIO_REGS + 7;
+       }
+       if (n > 133) {
+               *bit = 1 << (n - 134);
+               return GPIO_REGS + 6;
+       }
+       if (n > 106) {
+               *bit = 1 << (n - 107);
+               return GPIO_REGS + 5;
+       }
+       if (n > 94) {
+               *bit = 1 << (n - 95);
+               return GPIO_REGS + 4;
+       }
+       if (n > 67) {
+               *bit = 1 << (n - 68);
+               return GPIO_REGS + 3;
+       }
+       if (n > 43) {
+               *bit = 1 << (n - 44);
+               return GPIO_REGS + 2;
+       }
+       if (n > 15) {
+               *bit = 1 << (n - 16);
+               return GPIO_REGS + 1;
+       }
+       *bit = 1 << n;
+       return GPIO_REGS + 0;
+}
+
+int gpio_config(unsigned n, unsigned flags)
+{
+       struct gpioregs *r;
+       unsigned b;
+       unsigned v;
+
+       r = find_gpio(n, &b);
+       if (!r)
+               return -1;
+
+       v = readl(r->oe);
+       if (flags & GPIO_OUTPUT)
+               writel(v | b, r->oe);
+       else
+               writel(v & (~b), r->oe);
+       return 0;
+}
+
+void gpio_set(unsigned n, unsigned on)
+{
+       struct gpioregs *r;
+       unsigned b;
+       unsigned v;
+
+       r = find_gpio(n, &b);
+       if (r == 0)
+               return;
+
+       v = readl(r->out);
+       if (on)
+               writel(v | b, r->out);
+       else
+               writel(v & (~b), r->out);
+}
+
+int gpio_get(unsigned n)
+{
+       struct gpioregs *r;
+       unsigned b;
+
+       r = find_gpio(n, &b);
+       if (r  == 0)
+               return 0;
+       return (readl(r->in) & b) ? 1 : 0;
+}
+
+void platform_config_interleaved_mode_gpios(void)
+{
+       /* configure EB2_CS1 through GPIO86 */
+       writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
+       writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
+       /* configure the EBI2_BUSY1_N through GPIO115 */
+       writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
+       writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
+}
+
+/* Enables all gpios passed in table*/
+int platform_gpios_enable(const struct msm_gpio *table, int size)
+{
+       int rc;
+       int i;
+       const struct msm_gpio *g;
+       for (i = 0; i < size; i++) {
+               g = table + i;
+               /* Enable gpio */
+               rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
+               if (rc)
+                       goto err;
+       }
+       return 0;
+err:
+       return rc;
+}
+
diff --git a/arch/arm/cpu/armv7/msm7630/lowlevel_init.S b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
new file mode 100644
index 0000000..ef63770
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/lowlevel_init.S
@@ -0,0 +1,623 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <config.h>
+#include <version.h>
+
+.text
+.code 32
+
+#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
+#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
+
+/*
+ ; LVT Ring Osc counter
+ ; used to determine sense amp settings
+ ; Clobbers registers r0, r4, r5, r6, r7, r9, r10, r11
+*/
+.equ CLK_CTL_BASE,     0xA8600000
+.equ A_GLBL_CLK_ENA,   0x0000
+.equ A_PRPH_WEB_NS_REG,0x0080
+.equ A_MSM_CLK_RINGOSC,0x00D0
+.equ A_TCXO_CNT,       0x00D4
+.equ A_TCXO_CNT_DONE,  0x00D8
+.equ A_RINGOSC_CNT,    0x00DC
+.equ A_MISC_CLK_CTL,   0x0108
+.equ CLK_TEST,         0xA8600114
+.equ SPSS_CSR_BASE,    0xAC100000
+.equ A_SCRINGOSC,      0x0510
+
+//;; Number of TCXO cycles to count ring oscillations
+.equ TCXO_CNT_VAL,     0x100
+
+//; Halcyon addresses
+.equ TCSR_CONF_FUSE_1, 0xAB600060 //; TCSR_CONF_FUSE_1 register
+.equ TCSR_CONF_FUSE_4, 0xAB60006C //; TCSR_CONF_FUSE_4 register
+
+//; SCORPION_L1_ACC (1:0) Fuses bit location
+.equ L1_ACC_BIT_0,     12       //;12th bit of TCSR_CONF_FUSE_4
+.equ L1_ACC_BIT_1,     13       //;13th bit of TCSR_CONF_FUSE_4
+//; SCORPION_L2_ACC (2:0) Fuses bit location
+.equ L2_ACC_BIT_0,     25       //;25th bit of TCSR_CONF_FUSE_1
+.equ L2_ACC_BIT_1,     10       //;10th bit of TCSR_CONF_FUSE_4
+.equ L2_ACC_BIT_2,     11       //;11th bit of TCSR_CONF_FUSE_4
+
+//; CP15: PVR2F0 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR2F0_00,        0x00000000
+.equ PVR2F0_01,        0x04000000
+.equ PVR2F0_10,        0x08000000
+.equ PVR2F0_11,        0x0C000000
+
+//; CP15: PVR2F1 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR2F1_00,        0x00000008
+.equ PVR2F1_01,        0x00000008
+.equ PVR2F1_10,        0x00000208
+.equ PVR2F1_11,        0x00000208
+
+//; CP15: PVR0F2 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR0F2_00,        0x00000000
+.equ PVR0F2_01,        0x00000000
+.equ PVR0F2_10,        0x00000200
+.equ PVR0F2_11,        0x00000200
+
+//; CP15: PVR0F0 values according to  SCORPION_L1_ACC (1:0)
+.equ PVR0F0_00,        0x7F000000
+.equ PVR0F0_01,        0x7F000400
+.equ PVR0F0_10,        0x7F000000
+.equ PVR0F0_11,        0x7F000400
+
+//; CP15: L2VR3F1 values according to  SCORPION_L2_ACC (2:0)
+.equ L2VR3F1_000,      0x00FFFF60
+.equ L2VR3F1_001,      0x00FFFF40
+.equ L2VR3F1_010,      0x00FFFC60
+.equ L2VR3F1_011,      0x00FFFC40
+.equ L2VR3F1_100,      0x00FCFF60
+.equ L2VR3F1_101,      0x00FCFF40
+.equ L2VR3F1_110,      0x00FCFC60
+.equ L2VR3F1_111,      0x00FCFC40
+
+
+
+
+_TEXT_BASE:
+       .word   CONFIG_SYS_TEXT_BASE    @ sdram load addr from config file
+
+.global invalidate_dcache
+invalidate_dcache:
+       mov pc, lr
+
+       .align  5
+.globl lowlevel_init
+lowlevel_init:
+       mov     pc, lr                          @ back to arch calling code
+
+.global reset_cpu
+reset_cpu:
+_loop_forever:
+        b       _loop_forever
+
+.globl SET_SA
+SET_SA:
+
+        //;--------------------------------------------------------------------
+        //; Fuse bits used to determine sense amp settings
+        //;--------------------------------------------------------------------
+
+        //; Reading L1_ACC
+        ldr    r4, = 0x0
+
+        //; Read L1_ACC_BIT_0
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L1_ACC_BIT_0
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        orr    r4, r3, r4
+
+        //; Read L1_ACC_BIT_1
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L1_ACC_BIT_1
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #1
+        orr    r4, r3, r4
+
+l1_ck_0:
+        //; if L1_[1:0] == 00
+        ldr    r5, = 0x0
+        cmp    r4, r5
+        bne    l1_ck_1
+        ldr    r0, =PVR0F0_00
+        ldr    r1, =PVR0F2_00
+        ldr    r2, =PVR2F0_00
+        ldr    r3, =PVR2F1_00
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_1:
+        //; if L1_[1:0] == 01
+        ldr    r1, = 0x01
+        cmp    r4, r1
+        bne    l1_ck_2
+        ldr    r0, =PVR0F0_01
+        ldr    r1, =PVR0F2_01
+        ldr    r2, =PVR2F0_01
+        ldr    r3, =PVR2F1_01
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_2:
+        //; if L1_[2:0] == 10
+        ldr    r1, = 0x02
+        cmp    r4, r1
+        bne    l1_ck_3
+        ldr    r0, =PVR0F0_10
+        ldr    r1, =PVR0F2_10
+        ldr    r2, =PVR2F0_10
+        ldr    r3, =PVR2F1_10
+        b      WRITE_L1_SA_SETTINGS
+
+l1_ck_3:
+        //; if L1_[2:0] == 11
+        ldr    r1, = 0x03
+        cmp    r4, r1
+        ldr    r0, =PVR0F0_11
+        ldr    r1, =PVR0F2_11
+        ldr    r2, =PVR2F0_11
+        ldr    r3, =PVR2F1_11
+        b      WRITE_L1_SA_SETTINGS
+
+
+WRITE_L1_SA_SETTINGS:
+
+        //;WCP15_PVR0F0   r0
+        mcr    p15, 0x0, r0, c15, c15, 0x0   //; write R0 to PVR0F0
+
+        //;WCP15_PVR0F2   r1
+        mcr    p15, 0x0, r1, c15, c15, 0x2   //; write R1 to PVR0F2
+
+        //;WCP15_PVR2F0   r2
+        mcr    p15, 0x2, r2, c15, c15, 0x0   //; write R2 to PVR2F0
+
+        // Disable predecode repair cache on certain Scorpion revisions
+        // (Raptor V2 and earlier, or Halcyon V1)
+        mrc    p15, 0, r1, c0, c0, 0      //; MIDR
+        BIC    r2, r1, #0xf0              //; check for Halcyon V1
+        ldr    r4, =0x511f0000
+        cmp    r2, r4
+        bne    PVR2F1
+
+DPRC:
+        mrc    p15, 0, r1, c15, c15, 2    //; PVR0F2
+        orr    r1, r1, #0x10              //; enable bit 4
+        mcr    p15, 0, r1, c15, c15, 2    //; disable predecode repair cache
+
+PVR2F1:
+        //;WCP15_PVR2F1   r3
+        mcr    p15, 0x2, r3, c15, c15, 0x1   //; write R3 to PVR2F1
+
+        //; Reading L2_ACC
+        ldr    r4, = 0x0
+
+        //; Read L2_ACC_BIT_0
+        ldr    r1, =TCSR_CONF_FUSE_1
+        ldr    r2, =L2_ACC_BIT_0
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        orr    r4, r3, r4
+
+        //; Read L2_ACC_BIT_1
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L2_ACC_BIT_1
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #1
+        orr    r4, r3, r4
+
+        //; Read L2_ACC_BIT_2
+        ldr    r1, =TCSR_CONF_FUSE_4
+        ldr    r2, =L2_ACC_BIT_2
+        ldr    r3, [r1]
+        mov    r3, r3, LSR r2
+        and    r3, r3, #1
+        mov    r3, r3, LSL #2
+        orr    r4, r3, r4
+
+l2_ck_0:
+        //; if L2_[2:0] == 000
+        ldr    r5, = 0x0
+        cmp    r4, r5
+        bne    l2_ck_1
+        ldr    r0, =L2VR3F1_000
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_1:
+        //; if L2_[2:0] == 001
+        ldr     r5, = 0x1
+        cmp     r4, r5
+        bne     l2_ck_2
+        ldr     r0, =L2VR3F1_001
+        b       WRITE_L2_SA_SETTINGS
+
+l2_ck_2:
+        //; if L2_[2:0] == 010
+        ldr    r5, = 0x2
+        cmp    r4, r5
+        bne    l2_ck_3
+        ldr    r0, =L2VR3F1_010
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_3:
+        //; if L2_[2:0] == 011
+        ldr    r5, = 0x3
+        cmp    r4, r5
+        bne    l2_ck_4
+        ldr    r0, =L2VR3F1_011
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_4:
+        //; if L2_[2:0] == 100
+        ldr    r5, = 0x4
+        cmp    r4, r5
+        bne    l2_ck_5
+        ldr    r0, =L2VR3F1_100
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_5:
+        //; if L2_[2:0] == 101
+        ldr    r5, = 0x5
+        cmp    r4, r5
+        bne    l2_ck_6
+        ldr    r0, =L2VR3F1_101
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_6:
+        //; if L2_[2:0] == 110
+        ldr    r5, = 0x6
+        cmp    r4, r5
+        bne    l2_ck_7
+        ldr    r0, =L2VR3F1_110
+        b      WRITE_L2_SA_SETTINGS
+
+l2_ck_7:
+        //; if L2_[2:0] == 111
+        ldr    r5, = 0x7
+        cmp    r4, r5
+        ldr    r0, =L2VR3F1_111
+        b      WRITE_L2_SA_SETTINGS
+
+WRITE_L2_SA_SETTINGS:
+        //;WCP15_L2VR3F1  r0
+        mcr    p15, 0x3, r0, c15, c15, 0x1     //;write r0 to L2VR3F1
+       DSB
+       ISB
+
+        ldr    r0, =0                   //;make sure the registers we touched
+        ldr    r1, =0                   //;are cleared when we return
+        ldr    r2, =0
+        ldr    r3, =0
+        ldr    r4, =0
+        ldr    r5, =0
+
+       mrs     r0, cpsr
+       orr     r0, r0, #(1<<7)
+       msr     cpsr_c, r0
+
+       //; routine complete
+       pop     {r5-r12,pc}
+
+.ltorg
+
+.globl __cpu_early_init
+__cpu_early_init:
+
+        //; Zero out r0 for use throughout this code. All other GPRs
+        //; (r1-r3) are set throughout this code to help establish
+        //; a consistent startup state for any code that follows.
+        //; Users should add code@the end of this routine to establish
+        //; their own stack address (r13), add translation page tables, enable
+        //; the caches, etc.
+       push    {r5-r12,r14}
+        mov    r0,  #0x0
+
+
+        //; Remove hardcoded cache settings. appsbl_handler.s calls Set_SA
+        //;   API to dynamically configure cache for slow/nominal/fast parts
+
+        //; DCIALL to invalidate L2 cache bank (needs to be run 4 times,
+       //; once per bank)
+        //; This must be done early in code (prior to enabling the caches)
+        mov    r1, #0x2
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank D ([15:14] == 2'b00)
+        orr    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank C ([15:14] == 2'b01)
+        add    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank B ([15:14] == 2'b10)
+        add    r1, r1, #0x00004000
+        mcr    p15, 0, r1, c9, c0, 6   //; DCIALL bank A ([15:14] == 2'b11)
+
+        //; Initialize the BPCR - setup Global History Mask (GHRM) to all 1's
+        //; and have all address bits (AM) participate.
+        //; Different settings can be used to improve performance
+        // movW   r1, #0x01FF
+.word 0xe30011ff  // hardcoded movW instruction due to lack of compiler support
+        // movT   r1, #0x01FF
+.word 0xe34011ff  // hardcoded movT instruction due to lack of compiler support
+        mcr    p15, 7, r1, c15, c0, 2   //; WCP15_BPCR
+
+
+        //; Initialize all I$ Victim Registers to 0 for startup
+        mcr    p15, 0, r0, c9, c1, 0    //; WCP15_ICVIC0    r0
+        mcr    p15, 0, r0, c9, c1, 1    //; WCP15_ICVIC1    r0
+        mcr    p15, 0, r0, c9, c1, 2    //; WCP15_ICVIC2    r0
+        mcr    p15, 0, r0, c9, c1, 3    //; WCP15_ICVIC3    r0
+        mcr    p15, 0, r0, c9, c1, 4    //; WCP15_ICVIC4    r0
+        mcr    p15, 0, r0, c9, c1, 5    //; WCP15_ICVIC5    r0
+        mcr    p15, 0, r0, c9, c1, 6    //; WCP15_ICVIC5    r0
+        mcr    p15, 0, r0, c9, c1, 7    //; WCP15_ICVIC7    r0
+
+        //; Initialize all I$ Locked Victim Registers (Unlocked Floors) to 0
+        mcr    p15, 1, r0, c9, c1, 0    //; WCP15_ICFLOOR0  r0
+        mcr    p15, 1, r0, c9, c1, 1    //; WCP15_ICFLOOR1  r0
+        mcr    p15, 1, r0, c9, c1, 2    //; WCP15_ICFLOOR2  r0
+        mcr    p15, 1, r0, c9, c1, 3    //; WCP15_ICFLOOR3  r0
+        mcr    p15, 1, r0, c9, c1, 4    //; WCP15_ICFLOOR4  r0
+        mcr    p15, 1, r0, c9, c1, 5    //; WCP15_ICFLOOR5  r0
+        mcr    p15, 1, r0, c9, c1, 6    //; WCP15_ICFLOOR6  r0
+        mcr    p15, 1, r0, c9, c1, 7    //; WCP15_ICFLOOR7  r0
+
+        //; Initialize all D$ Victim Registers to 0
+        mcr    p15, 2, r0, c9, c1, 0    //; WP15_DCVIC0    r0
+        mcr    p15, 2, r0, c9, c1, 1    //; WP15_DCVIC1    r0
+        mcr    p15, 2, r0, c9, c1, 2    //; WP15_DCVIC2    r0
+        mcr    p15, 2, r0, c9, c1, 3    //; WP15_DCVIC3    r0
+        mcr    p15, 2, r0, c9, c1, 4    //; WP15_DCVIC4    r0
+        mcr    p15, 2, r0, c9, c1, 5    //; WP15_DCVIC5    r0
+        mcr    p15, 2, r0, c9, c1, 6    //; WP15_DCVIC6    r0
+        mcr    p15, 2, r0, c9, c1, 7    //; WP15_DCVIC7    r0
+
+        //; Initialize all D$ Locked VDCtim Registers (Unlocked Floors) to 0
+        mcr    p15, 3, r0, c9, c1, 0    //; WCP15_DCFLOOR0  r0
+        mcr    p15, 3, r0, c9, c1, 1    //; WCP15_DCFLOOR1  r0
+        mcr    p15, 3, r0, c9, c1, 2    //; WCP15_DCFLOOR2  r0
+        mcr    p15, 3, r0, c9, c1, 3    //; WCP15_DCFLOOR3  r0
+        mcr    p15, 3, r0, c9, c1, 4    //; WCP15_DCFLOOR4  r0
+        mcr    p15, 3, r0, c9, c1, 5    //; WCP15_DCFLOOR5  r0
+        mcr    p15, 3, r0, c9, c1, 6    //; WCP15_DCFLOOR6  r0
+        mcr    p15, 3, r0, c9, c1, 7    //; WCP15_DCFLOOR7  r0
+
+        //; Initialize ASID to zero
+        mcr    p15, 0, r0, c13, c0, 1   //; WCP15_CONTEXTIDR r0
+
+        //; ICIALL to invalidate entire I-Cache
+        mcr    p15, 0, r0, c7, c5, 0    //; ICIALLU
+
+        //; DCIALL to invalidate entire D-Cache
+        mcr    p15, 0, r0, c9, c0, 6    //; DCIALL  r0
+
+       //; Initialize ADFSR to zero
+        mcr    p15, 0, r0, c5, c1, 0    //; ADFSR   r0
+
+       //; Initialize EFSR to zero
+        mcr    p15, 7, r0, c15, c0, 1   //; EFSR    r0
+
+        //; The VBAR (Vector Base Address Register) should be initialized
+        //; early in your code. We are setting it to zero
+        mcr    p15, 0, r0, c12, c0, 0   //; WCP15_VBAR  r0
+
+        //; Ensure the mcr's above have completed their operation
+       //; before continuing
+        DSB
+        ISB
+
+        //; Setup CCPR - Cache Coherency Policy Register
+        //; setup CCPR[L1ISHP, L2ISHP] both to 0b00 (no forcing)
+        //; setup CCPR[L1OSHP, L2OSHP] both to 0b10 (force non-cacheable)
+        movw   r2, #0x88
+        mcr    p15, 0, r2, c10, c4, 2
+
+        //;-------------------------------------------------------------------
+        //; There are a number of registers that must be set prior to enabling
+        //; the MMU. The DCAR is one of these registers. We are setting
+        //; it to zero (no access) to easily detect improper setup in subsequent
+        //; code sequences
+        //;-------------------------------------------------------------------
+        //; Setup DACR (Domain Access Control Register) to zero
+        mcr    p15, 0, r0, c3, c0, 0    //; WCP15_DACR  r0
+
+        //; Setup DCLKCR to allow normal D-Cache line fills
+        mcr    p15, 1, r0, c9, c0, 7    //; WCP15_DCLKCR r0
+
+        //; Setup the TLBLKCR
+        //; Victim = 6'b000000; Floor = 6'b000000;
+        //; IASIDCFG =
+       //;2'b00 (State-Machine); IALLCFG = 2'b01 (Flash); BNA = 1'b0;
+        mov    r1, #0x02
+        mcr    p15, 0, r1, c10, c1, 3     //; WCP15_TLBLKCR  r1
+
+        //;Make sure TLBLKCR is complete before continuing
+        ISB
+
+        //; Invalidate the UTLB
+        mcr    p15, 0, r0, c8, c7, 0      //; UTLBIALL
+
+        //; Make sure UTLB request has been presented to macro before continuing
+        ISB
+
+SYSI2:
+        //; setup L2CR1 to some default Instruction and data prefetching values
+        //; Users may want specific settings for various performance
+       //; enhancements
+        //; In Halcyon we do not have broadcasting barriers. So we need to turn
+        //  ; on bit 8 of L2CR1; which DBB:( Disable barrier broadcast )
+        ldr    r2, =0x133
+        mcr    p15, 3, r2, c15, c0, 3     //; WCP15_L2CR1  r0
+
+
+        //; Enable Z bit to enable branch prediction (default is off)
+        mrc    p15, 0, r2, c1, c0, 0      //; RCP15_SCTLR  r2
+        orr    r2, r2, #0x00000800
+        mcr    p15, 0, r2, c1, c0, 0      //; WCP15_SCTLR  r2
+
+        //; Make sure Link stack is initialized with branch and links to
+       //; sequential addresses
+        //; This aids in creating a predictable startup environment
+        bl     SEQ1
+SEQ1:   bl     SEQ2
+SEQ2:   bl     SEQ3
+SEQ3:   bl     SEQ4
+SEQ4:   bl     SEQ5
+SEQ5:   bl     SEQ6
+SEQ6:   bl     SEQ7
+SEQ7:   bl     SEQ8
+SEQ8:
+
+        //; REMOVE FOLLOWING THREE INSTRUCTIONS WHEN POWER COLLAPSE IS ENA
+        //;Make sure the DBGOSLSR[LOCK] bit is cleared to allow access to the
+       //;debug registers
+        //; Writing anything but the "secret code" to the DBGOSLAR clears the
+       //;DBGOSLSR[LOCK] bit
+        mcr    p14, 0, r0, c1, c0, 4       //; WCP14_DBGOSLAR r0
+
+
+        //; Read the DBGPRSR to clear the DBGPRSR[STICKYPD]
+        //; Any read to DBGPRSR clear the STICKYPD bit
+        //; ISB guarantees the read completes before attempting to
+        //; execute a CP14 instruction.
+        mrc    p14, 0, r3, c1, c5, 4       //; RCP14_DBGPRSR r3
+        ISB
+
+
+
+        //;--------------------------------------------------------------------
+        //; The saved Program Status Registers (SPSRs) should be setup
+        //; prior to any automatic mode switches. The following
+        //; code sets these registers up to a known state. Users will need to
+        //; customize these settings to meet their needs.
+        //;--------------------------------------------------------------------
+        mov    r2,  #0x1f
+        mov    r1,  #0xd7                 //;ABT mode
+        msr    cpsr_c, r1                 //;ABT mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xdb                 //;UND mode
+        msr    cpsr_c, r1                 //;UND mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd1                 //;FIQ mode
+        msr    cpsr_c, r1                 //;FIQ mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd2                 //;IRQ mode
+        msr    cpsr_c, r1                 //;IRQ mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd6                 //;Monitor mode
+        msr    cpsr_c, r1                 //;Monitor mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+        mov    r1,  #0xd3                 //;SVC mode
+        msr    cpsr_c, r1                 //;SVC mode
+        msr    spsr_cxfs, r2              //;clear the spsr
+
+
+        //;--------------------------------------------------------------------
+        //; Enabling Error reporting is something users may want to do at
+        //; some other point in time. We have chosen some default settings
+        //; that should be reviewed. Most of these registers come up in an
+        //; unpredictable state after reset.
+        //;--------------------------------------------------------------------
+//;Start of error and control setting
+
+        //; setup L2CR0 with various L2/TCM control settings
+        //; enable out of order bus attributes and error reporting
+        //; this register comes up unpredictable after reset
+        // movw   r1, #0x0F0F
+.word 0xe3001f0f  // hardcoded movw instruction due to lack of compiler support
+        // movT   r1, #0xC005
+.word 0xe34c1005  // hardcoded movw instruction due to lack of compiler support
+        mcr    p15, 3, r1, c15, c0, 1    //; WCP15_L2CR0  r1
+
+        //; setup L2CPUCR
+        //; mov    r2, #0xFF
+        //; Enable I and D cache parity
+        //;L2CPUCR[7:5] = 3~Rh7 ~V enable parity error reporting for modified,
+        //;tag, and data parity errors
+        mov    r2, #0xe0
+        mcr    p15, 3, r2, c15, c0, 2    //; WCP15_L2CPUCR  r2
+
+        //; setup SPCR
+        //; enable all error reporting
+       //;(reset value is unpredicatble for most bits)
+        mov    r3, #0x0F
+        mcr    p15, 0, r3, c9, c7, 0     //; WCP15_SPCR  r3
+
+        //; setup DMACHCRs (reset value unpredictable)
+        //; control setting and enable all error reporting
+        mov    r1, #0x0F
+
+        //; DMACHCR0 = 0000000F
+        mov    r2, #0x00                  //; channel 0
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR1 = 0000000F
+        mov    r2, #0x01                  //; channel 1
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR2 = 0000000F
+        mov    r2, #0x02                  //; channel 2
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; DMACHCR3 = 0000000F
+        mov    r2, #0x03                  //; channel 3
+        mcr    p15, 0, r2, c11, c0, 0     //; WCP15_DMASELR  r2
+        mcr    p15, 0, r1, c11, c0, 2     //; WCP15_DMACHCR  r1
+
+        //; Set ACTLR (reset unpredictable)
+        //; Set AVIVT control, error reporting, etc.
+        //; mov   r3, #0x07
+        //; Enable I and D cache parity
+        //;ACTLR[2:0] = 3'h7 - enable parity error reporting from L2/I$/D$)
+        //;ACTLR[5:4] = 2'h3 - enable parity
+        //;ACTLR[19:18] =2'h3 - always generate and
+       //;check parity(when MMU disabled).
+        //;Value to be written #0xC0037
+        // movw   r3, #0x0037
+.word 0xe3003037  // hardcoded movw instruction due to lack of compiler support
+        // movT   r3, #0x000C
+.word 0xe340300c  // hardcoded movw instruction due to lack of compiler support
+        mcr    p15, 0, r3, c1, c0, 1      //; WCP15_ACTLR  r3
+
+//;End of error and control setting
+
+        //;---------------------------------------------------------------------
+        //; Unlock ETM and read StickyPD to halt the ETM clocks from running.
+        //; This is required for power saving whether the ETM is used or not.
+        //;---------------------------------------------------------------------
+
+        //;Clear ETMOSLSR[LOCK] bit
+        mov    r1, #0x00000000
+        mcr    p14, 1, r1, c1, c0, 4        //; WCP14_ETMOSLAR      r1
+
+        //;Clear ETMPDSR[STICKYPD] bit
+        mrc    p14, 1, r2, c1, c5, 4        //; RCP14_ETMPDSR       r2
+        b       SET_SA
+
+
+.ltorg
diff --git a/arch/arm/cpu/armv7/msm7630/timer.c b/arch/arm/cpu/armv7/msm7630/timer.c
new file mode 100644
index 0000000..007314e
--- /dev/null
+++ b/arch/arm/cpu/armv7/msm7630/timer.c
@@ -0,0 +1,142 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Moahmmed Khasim <khasim@ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/iomap.h>
+#include <asm/io.h>
+#include <config.h>
+#include <common.h>
+#include <asm/types.h>
+#define TIMER_LOAD_VAL 0x21
+
+#define GPT_ENABLE_CLR_ON_MATCH_EN        2
+#define GPT_ENABLE_EN                     1
+#define DGT_ENABLE_CLR_ON_MATCH_EN        2
+#define DGT_ENABLE_EN                     1
+
+#define SPSS_TIMER_STATUS_DGT_EN    (1 << 0)
+
+
+#define READ_TIMER    readl(GPT_COUNT_VAL)
+
+static ulong timestamp;
+static ulong lastinc;
+#define DGT_HZ 6750000         /* Uses LPXO/4 (27.0 MHz / 4) */
+
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init(void)
+{
+       uint32_t val = 0;
+
+       /* Disable timer */
+       writel(0, DGT_ENABLE);
+
+       /* Check for the hardware revision */
+       val = readl(HW_REVISION_NUMBER);
+       val = (val >> 28) & 0x0F;
+       if (val >= 1)
+               writel(1, DGT_CLK_CTL);
+       return 0;
+}
+
+
+ulong get_timer(ulong base)
+{
+       return get_timer_masked() - base;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void __udelay(unsigned long usecs)
+{
+       unsigned int val;
+       usecs = (usecs * 33 + 1000 - 33) / 1000;
+
+       writel(0, GPT_CLEAR);
+       writel(0, GPT_ENABLE);
+       do {
+               val = 0;
+               val = readl(GPT_COUNT_VAL);
+       } while (val != 0);
+
+       writel(GPT_ENABLE_EN, GPT_ENABLE);
+       do {
+               val = 0;
+               val = readl(GPT_COUNT_VAL);
+       } while (val < usecs) ;
+
+       writel(0, GPT_ENABLE);
+       writel(0, GPT_CLEAR);
+
+}
+
+
+ulong get_timer_masked(void)
+{
+       ulong now = READ_TIMER; /* current tick value */
+
+       if (lastinc <= now) {   /* normal mode (non roll) */
+               /* normal mode */
+               timestamp += now - lastinc;
+               /* move stamp forward with absolute diff ticks */
+       } else {                /* we have overflow of the count down timer */
+               timestamp += now + (TIMER_LOAD_VAL - lastinc);
+       }
+       lastinc = now;
+
+       return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+       return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+       return 19200000;
+}
diff --git a/arch/arm/include/asm/arch-msm7630/adm.h b/arch/arm/include/asm/arch-msm7630/adm.h
new file mode 100644
index 0000000..0e8af85
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/adm.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ADM_H
+#define __ADM_H
+
+/* Channel #s and security domain */
+#define ADM_CHN         8
+#define ADM_SD          2
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio.h b/arch/arm/include/asm/arch-msm7630/gpio.h
new file mode 100644
index 0000000..af6ddaa
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __GPIO_H
+#define __GPIO_H
+
+#ifndef GPIO_INPUT
+#define GPIO_INPUT     0x0000
+#endif
+#ifndef GPIO_OUTPUT
+#define GPIO_OUTPUT    0x0001
+#endif
+
+#define GPIO_LEVEL     0x0000
+#define GPIO_EDGE      0x0010
+
+#define GPIO_RISING    0x0020
+#define GPIO_FALLING   0x0040
+
+#define GPIO_HIGH      0x0020
+#define GPIO_LOW       0x0040
+
+#define GPIO_PULLUP    0x0100
+#define GPIO_PULLDOWN  0x0200
+
+int gpio_config(unsigned nr, unsigned flags);
+void gpio_set(unsigned nr, unsigned on);
+int gpio_get(unsigned nr);
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/gpio_hw.h b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
new file mode 100644
index 0000000..c8244d8
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/gpio_hw.h
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __GPIO_HW_H
+#define __GPIO_HW_H
+
+#define MSM_GPIO1_BASE 0xAC001000
+#define MSM_GPIO2_BASE 0xAC101000
+
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+
+/* output value */
+#define GPIO_OUT_0         GPIO1_REG(0x00)  /* gpio  15-0   */
+#define GPIO_OUT_1         GPIO2_REG(0x00)  /* gpio  43-16  */
+#define GPIO_OUT_2         GPIO1_REG(0x04)  /* gpio  67-44  */
+#define GPIO_OUT_3         GPIO1_REG(0x08)  /* gpio  94-68  */
+#define GPIO_OUT_4         GPIO1_REG(0x0C)  /* gpio 106-95  */
+#define GPIO_OUT_5         GPIO1_REG(0x50)  /* gpio 133-107 */
+#define GPIO_OUT_6         GPIO1_REG(0xC4)  /* gpio 150-134 */
+#define GPIO_OUT_7         GPIO1_REG(0x214)  /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0          GPIO1_REG(0x10)
+#define GPIO_OE_1          GPIO2_REG(0x08)
+#define GPIO_OE_2          GPIO1_REG(0x14)
+#define GPIO_OE_3          GPIO1_REG(0x18)
+#define GPIO_OE_4          GPIO1_REG(0x1C)
+#define GPIO_OE_5          GPIO1_REG(0x54)
+#define GPIO_OE_6          GPIO1_REG(0xC8)
+#define GPIO_OE_7          GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0          GPIO1_REG(0x34)
+#define GPIO_IN_1          GPIO2_REG(0x20)
+#define GPIO_IN_2          GPIO1_REG(0x38)
+#define GPIO_IN_3          GPIO1_REG(0x3C)
+#define GPIO_IN_4          GPIO1_REG(0x40)
+#define GPIO_IN_5          GPIO1_REG(0x44)
+#define GPIO_IN_6          GPIO1_REG(0xCC)
+#define GPIO_IN_7          GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define GPIO_INT_EDGE_0    GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1    GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2    GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3    GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4    GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5    GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6    GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7    GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0     GPIO1_REG(0x70)
+#define GPIO_INT_POS_1     GPIO2_REG(0x58)
+#define GPIO_INT_POS_2     GPIO1_REG(0x74)
+#define GPIO_INT_POS_3     GPIO1_REG(0x78)
+#define GPIO_INT_POS_4     GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5     GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6     GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7     GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0      GPIO1_REG(0x80)
+#define GPIO_INT_EN_1      GPIO2_REG(0x60)
+#define GPIO_INT_EN_2      GPIO1_REG(0x84)
+#define GPIO_INT_EN_3      GPIO1_REG(0x88)
+#define GPIO_INT_EN_4      GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5      GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6      GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7      GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0   GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1   GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2   GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3   GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4   GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5   GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6   GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7   GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0  GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1  GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2  GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3  GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4  GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5  GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6  GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7  GPIO1_REG(0x234)
+
+
+#define GPIO_OUT_VAL_REG_BASE     0xABC00000
+#define GPIO_ALT_FUNC_PAGE_REG    (GPIO_OUT_VAL_REG_BASE + 0x20)
+#define GPIO_ALT_FUNC_CFG_REG     (GPIO_OUT_VAL_REG_BASE + 0x24)
+
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL    0
+#define GPIO_PULL_DOWN  1
+#define GPIO_KEEPER     2
+#define GPIO_PULL_UP    3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA        0
+#define GPIO_4MA        1
+#define GPIO_6MA        2
+#define GPIO_8MA        3
+#define GPIO_10MA       4
+#define GPIO_12MA       5
+#define GPIO_14MA       6
+#define GPIO_16MA       7
+
+#define GPIO38_GPIO_CNTRL      0x175
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE     0
+#define GPIO_DISABLE    1
+
+#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
+       ((((gpio) & 0x3FF) << 4)        |   \
+       ((func) & 0xf)                  |   \
+       (((dir) & 0x1) << 14)           |   \
+       (((pull) & 0x3) << 15)          |   \
+       (((drvstr) & 0xF) << 17))
+
+/**
+ * struct msm_gpio - GPIO pin description
+ * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
+ * @label - textual label
+ *
+ * Usually, GPIO's are operated by sets.
+ * This struct accumulate all GPIO information in single source
+ * and facilitete group operations provided by msm_gpios_xxx()
+ */
+struct msm_gpio {
+       unsigned gpio_cfg;
+       const char *label;
+};
+
+/**
+ * extract GPIO pin from bit-field used for gpio_tlmm_config
+ */
+#define GPIO_PIN(gpio_cfg)    (((gpio_cfg) >>  4) & 0x3ff)
+#define GPIO_FUNC(gpio_cfg)   (((gpio_cfg) >>  0) & 0xf)
+#define GPIO_DIR(gpio_cfg)    (((gpio_cfg) >> 14) & 0x1)
+#define GPIO_PULL(gpio_cfg)   (((gpio_cfg) >> 15) & 0x3)
+#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
+
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/iomap.h b/arch/arm/include/asm/arch-msm7630/iomap.h
new file mode 100644
index 0000000..186c6c2
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/iomap.h
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __IOMAP_H_
+#define __IOMAP_H_
+
+#define MSM_UART1_BASE 0xACA00000
+#define MSM_UART2_BASE 0xACB00000
+#define MSM_UART3_BASE 0xACC00000
+
+#define MSM_VIC_BASE   0xC0080000
+#define MSM_TMR_BASE   0xC0100000
+
+#define MSM_GPT_BASE      (MSM_TMR_BASE + 0x04)
+#define MSM_DGT_BASE      (MSM_TMR_BASE + 0x24)
+#define SPSS_TIMER_STATUS (MSM_TMR_BASE + 0x88)
+
+#define GPT_REG(off)      (MSM_GPT_BASE + (off))
+#define DGT_REG(off)      (MSM_DGT_BASE + (off))
+
+#define GPT_MATCH_VAL      GPT_REG(0x0000)
+#define GPT_COUNT_VAL      GPT_REG(0x0004)
+#define GPT_ENABLE         GPT_REG(0x0008)
+#define GPT_CLEAR          GPT_REG(0x000C)
+
+#define DGT_MATCH_VAL      DGT_REG(0x0000)
+#define DGT_COUNT_VAL      DGT_REG(0x0004)
+#define DGT_ENABLE         DGT_REG(0x0008)
+#define DGT_CLEAR          DGT_REG(0x000C)
+#define DGT_CLK_CTL        DGT_REG(0x0010)
+
+#define HW_REVISION_NUMBER   0xABC00270
+
+#define MSM_CSR_BASE    0xC0100000
+#define MSM_GCC_BASE   0xC0182000
+
+#define MSM_SDC1_BASE   0xA0400000
+#define MSM_SDC2_BASE   0xA0500000
+#define MSM_SDC3_BASE   0xA3000000
+#define MSM_SDC4_BASE   0xA3100000
+
+#define MSM_SHARED_BASE      0x00100000
+#define MSM_CLK_CTL_BASE        0xAB800000
+#define MSM_CLK_CTL_SH2_BASE    0xABA01000
+
+#define REG_BASE(off)           (MSM_CLK_CTL_BASE + (off))
+#define REG_SH2_BASE(off)       (MSM_CLK_CTL_SH2_BASE + (off))
+
+#define SCSS_CLK_CTL            0xC0101004
+#define SCSS_CLK_SEL            0xC0101008
+
+#define MSM_USB_BASE                   0xA3600000
+#define MSM_CRYPTO_BASE                        0xA8400000
+
+#define SH2_USBH_MD_REG         REG_SH2_BASE(0x2BC)
+#define SH2_USBH_NS_REG         REG_SH2_BASE(0x2C0)
+
+#define SH2_MDP_NS_REG          REG_SH2_BASE(0x14C)
+#define SH2_MDP_LCDC_MD_REG     REG_SH2_BASE(0x38C)
+#define SH2_MDP_LCDC_NS_REG     REG_SH2_BASE(0x390)
+#define SH2_MDP_VSYNC_REG       REG_SH2_BASE(0x460)
+#define SH2_PMDH_NS_REG         REG_SH2_BASE(0x8C)
+
+#define SH2_GLBL_CLK_ENA_SC     REG_SH2_BASE(0x3BC)
+#define SH2_GLBL_CLK_ENA_2_SC   REG_SH2_BASE(0x3C0)
+
+#define SH2_OWN_ROW1_BASE_REG   REG_BASE(0x041C)
+#define SH2_OWN_ROW2_BASE_REG   REG_BASE(0x0424)
+#define SH2_OWN_APPS2_BASE_REG  REG_BASE(0x0414)
+
+#define MSM_ADM_BASE            0xAC200000
+#define MSM_ADM_SD_OFFSET       0x00100400
+
+#define MSM_SAW_BASE            0xC0102000
+
+#define PLL_ENA_REG             REG_SH2_BASE(0x0264)
+#define PLL2_STATUS_BASE_REG    REG_BASE(0x0350)
+#define PLL2_L_VAL_ADDR         REG_BASE(0x033C)
+#endif
diff --git a/arch/arm/include/asm/arch-msm7630/proc_comm.h b/arch/arm/include/asm/arch-msm7630/proc_comm.h
new file mode 100644
index 0000000..3df08b9
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/proc_comm.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __PROC_COMM_H_
+#define __PROC_COMM_H_
+
+void usb_clock_init(void);
+void lcdc_clock_init(unsigned rate);
+void mdp_clock_init(unsigned rate);
+void uart3_clock_init(void);
+void uart2_clock_init(void);
+void uart1_clock_init(void);
+void mddi_clock_init(unsigned num, unsigned rate);
+void reboot(unsigned reboot_reason);
+int mmc_clock_enable_disable(unsigned id, unsigned enable);
+int mmc_clock_set_rate(unsigned id, unsigned rate);
+int mmc_clock_get_rate(unsigned id);
+int gpio_tlmm_config(unsigned config, unsigned disable);
+int vreg_set_level(unsigned id, unsigned mv);
+int vreg_enable(unsigned id);
+int vreg_disable(unsigned id);
+
+#endif
+
+
diff --git a/arch/arm/include/asm/arch-msm7630/sys_proto.h b/arch/arm/include/asm/arch-msm7630/sys_proto.h
new file mode 100644
index 0000000..c679d92
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void pll8_enable(void);
+void clock_init(void);
+void __cpu_early_init(void);
+
+#endif
+
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller
  2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
  2012-02-29  0:03   ` Albert ARIBAUD
@ 2012-03-05 14:40   ` Mohamed Haneef
  2012-05-03 22:05     ` Andy Fleming
  1 sibling, 1 reply; 716+ messages in thread
From: Mohamed Haneef @ 2012-03-05 14:40 UTC (permalink / raw)
  To: u-boot

        * Support for qc_mmc MMC Controller

Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
---
change for v2:
 - changed the patch title to "support for qc_mmc MMC Controller"


 arch/arm/include/asm/arch-msm7630/mmc.h |  399 +++++++++++++++++++++
 drivers/mmc/Makefile                    |    1 +
 drivers/mmc/qc_mmc.c                    |  584 +++++++++++++++++++++++++++++++
 3 files changed, 984 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
 create mode 100644 drivers/mmc/qc_mmc.c

diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..949e43c
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,399 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#ifndef MMC_SLOT
+#define MMC_SLOT            0
+#endif
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER                 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN            (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF               0x00
+#define MMC_BOOT_MCI_PWR_UP                0x01
+#define MMC_BOOT_MCI_PWR_ON                0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN            (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF               0x00
+#define MMC_BOOT_MCI_PWR_UP                0x02
+#define MMC_BOOT_MCI_PWR_ON                0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK                  0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE           (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE          (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE     (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT    0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT    (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT    (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW         (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT       (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING       0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING        (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK      (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK      (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT          0
+#define MMC_BOOT_BUS_WIDTH_4_BIT          2
+#define MMC_BOOT_BUS_WIDTH_8_BIT          3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT              0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD                   0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE         (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP          (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT        (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING          (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE           (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA         (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD          (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT         (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE       (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE      (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD               0x010
+
+#define MMC_BOOT_MCI_RESP_0                 0x014
+#define MMC_BOOT_MCI_RESP_1                 0x018
+#define MMC_BOOT_MCI_RESP_2                 0x01C
+#define MMC_BOOT_MCI_RESP_3                 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER             0x024
+#define MMC_BOOT_MCI_DATA_LENGTH            0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL               0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE          (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR             (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE            (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE       (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS          4
+#define MMC_BOOT_MCI_DATA_COUNT            0x030
+#define MMC_BOOT_MCI_STATUS                0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL    (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL   (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT     (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT    (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN       (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN       (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END    (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT        (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END        (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR   (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END    (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE      (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE       (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE       (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL   (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL   (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL    (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL    (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY   (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY   (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL   (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL   (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR       (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE       (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL    (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP    (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT     (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS        (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+               MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+               MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+               MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+               MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+               MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+               MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+               MMC_BOOT_MCI_STAT_CMD_SENT| \
+               MMC_BOOT_MCI_STAT_DATA_END| \
+               MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+               MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+               MMC_BOOT_MCI_SDIO_INTR_CLR| \
+               MMC_BOOT_MCI_STAT_PROG_DONE| \
+               MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+               MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR                  0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR     (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR    (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR      (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR     (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR      (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR       (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR     (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR         (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR         (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR    (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR     (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR        (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR        (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR   (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR      (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0             0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK    (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK   (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK     (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK    (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK      (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK      (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK    (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK        (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK        (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK   (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK    (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK      (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK       (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK       (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK   (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK   (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK    (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK    (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK   (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK   (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK   (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK   (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK        (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK       (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK   (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK   (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK    (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1              0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT            0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER              0x0058
+
+#define MMC_BOOT_MCI_FIFO                   0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19                (1 << 7)
+#define MMC_BOOT_OCR_27_36                (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE             (2 << 29)
+#define MMC_BOOT_OCR_BUSY                 (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST                (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP         (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS              (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER       (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR         (1 << 3)
+#define MMC_BOOT_R1_APP_CMD               (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA          (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE       (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY        (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT      (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY       (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN       (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA       (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV        (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG        (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS        (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET           (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED     (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP         (1 << 15)
+#define MMC_BOOT_R1_ERROR                 (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR              (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED       (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD           (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR           (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL      (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED        (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION          (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM           (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR         (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR         (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR              (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE          (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS                0
+#define MMC_BOOT_E_FAILURE                1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT                2
+#define MMC_BOOT_E_INVAL                  3
+#define MMC_BOOT_E_CRC_FAIL               4
+#define MMC_BOOT_E_INIT_FAIL              5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH      6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL       7
+#define MMC_BOOT_E_NOT_SUPPORTED          8
+#define MMC_BOOT_E_CARD_BUSY              9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL         10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL        11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL       12
+#define MMC_BOOT_E_CID_DECODE_FAIL        13
+#define MMC_BOOT_E_BLOCKLEN_ERR           14
+#define MMC_BOOT_E_ADDRESS_ERR            15
+#define MMC_BOOT_E_DATA_CRC_FAIL          16
+#define MMC_BOOT_E_DATA_TIMEOUT           17
+#define MMC_BOOT_E_RX_OVRRUN              18
+#define MMC_BOOT_E_VREG_SET_FAILED        19
+#define MMC_BOOT_E_GPIO_CFG_FAIL          20
+#define MMC_BOOT_E_DATA_ADM_ERR           21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE             0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING       185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH       183
+
+#define MMC_BOOT_EXT_USER_WP              171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF      175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE       221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE    224
+
+#define MMC_BOOT_US_PERM_WP_EN            2
+#define MMC_BOOT_US_PWR_WP_DIS            3
+
+#define MMC_BOOT_US_PERM_WP_DIS           (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN             1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED      0x000001AA
+#define MMC_BOOT_SD_NEG_OCR               0x00FF8000
+#define MMC_BOOT_SD_HC_HCS                0x40000000
+#define MMC_BOOT_SD_DEV_READY             0x80000000
+#define MMC_BOOT_SD_SWITCH_HS             0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK          0
+#define MMC_BOOT_XFER_MODE_STREAM         1
+#define MMC_BOOT_PROGRAM_ENABLED          2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY    1000
+#define MMC_BOOT_RD_BLOCK_LEN         512
+#define MMC_BOOT_WR_BLOCK_LEN         512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH       16
+#define MMC_BOOT_MCI_HFIFO_COUNT      (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE        (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN        0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ                400000
+#define MMC_CLK_144KHZ                144000
+#define MMC_CLK_20MHZ                 20000000
+#define MMC_CLK_24MHZ                 24000000
+#define MMC_CLK_25MHZ                 25000000
+#define MMC_CLK_26MHZ                 26000000
+#define MMC_CLK_48MHZ                 48000000
+#define MMC_CLK_50MHZ                 49152000
+#define MMC_CLK_52MHZ                 52000000
+
+#define MMC_CLK_ENABLE      1
+#define MMC_CLK_DISABLE     0
+
+#if 0
+#define MSM_SDC1_BASE       0x12400000
+#define MSM_SDC2_BASE       0x12140000
+#define MSM_SDC3_BASE       0x12180000
+#define MSM_SDC4_BASE       0x121C0000
+#endif
+struct mmc_priv {
+       unsigned int instance;
+       unsigned int base;
+       unsigned int rd_timeout_ns;     /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+                                       struct mmc_cmd *cmd,
+                                       struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
 COBJS-$(CONFIG_SDHCI) += sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o

 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..7b7a1ed
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+#ifndef NULL
+#define NULL        0
+#endif
+
+#define MMC_BOOT_DATA_READ     0
+#define MMC_BOOT_DATA_WRITE    1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+       return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+       if (mmc == NULL)
+               return MMC_BOOT_E_INVAL;
+
+       /* todo: Add a check for HC, only if HC do this.
+        * If not, taac and nsac must be taken into account
+        */
+       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
+       debug(" Read timeout set: %d ns\n",
+       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+       if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+               return MMC_BOOT_E_BLOCKLEN_ERR;
+
+       /* Misaligned address not matching block length */
+       if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+               return MMC_BOOT_E_ADDRESS_ERR;
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+               /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+                * was detected by card/device during the data transfer
+                */
+       if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+               mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+               /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+                * exceeded the data timeout period without completing the
+                * transfer
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+               mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+               /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+                * receive data from the card before empty storage for new
+                * received data was available.
+                * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+                * the data xfer.
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+                * so no need to verify for now
+                */
+               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+               /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+                * data to the card before new data for sending was available.
+                * Verify that bit FLOW_ENA in MCI_CLK
+                * is set to 1 during the data xfer.
+                */
+       else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+                * so skipping it now
+                */
+               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+       return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
+                                               unsigned int  data_len,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       unsigned int mmc_status = 0;
+       unsigned int mmc_count = 0;
+       unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+                                       MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \
+                                       MMC_BOOT_MCI_STAT_RX_OVRRUN;
+       unsigned int i;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg_status, reg_fifo;
+
+       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+       reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+       /* Read the data from the MCI_FIFO register as long as
+        * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+        * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+        * register are cleared to 0.
+        * Continue the reads until the whole transfer data is received
+        */
+
+       do {
+               mmc_ret = MMC_BOOT_E_SUCCESS;
+               mmc_status = readl(reg_status);
+
+               if (mmc_status & read_error) {
+                       mmc_ret = mmc_boot_status_error(mmc_status);
+                       break;
+               }
+
+               if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+                       unsigned read_count = 1;
+                       if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+                               read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+                       for (i = 0; i < read_count; i++) {
+                               /* FIFO contains 16 32-bit data buffer
+                                 * on 16 sequential addresses
+                                 */
+                               *mmc_ptr = readl(reg_fifo +
+                                       (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+                               mmc_ptr++;
+                               /* increase mmc_count by word size */
+                               mmc_count += sizeof(unsigned int);
+                       }
+                       /* quit if we have read enough of data */
+                       if (mmc_count == data_len)
+                               break;
+               } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+                       break;
+       }  while (1);
+       return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+                                                       unsigned int  data_len,
+                                                       unsigned char direction,
+                                                       struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       if (direction == MMC_BOOT_DATA_READ)
+               mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+       return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_cmd = 0;
+       unsigned int mmc_status = 0;
+       unsigned int mmc_resp = 0;
+       unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+       unsigned int cmd_index = 0;
+       int i = 0;
+       unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+
+       /* basic check */
+       if (cmd == NULL)
+               return MMC_BOOT_E_INVAL;
+
+       /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+       writel(cmd->cmdarg, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+       /* 2a. Write command index in CMD_INDEX field */
+       cmd_index = cmd->cmdidx;
+       mmc_cmd |= cmd->cmdidx;
+       /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+       if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+       /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+       if (cmd->resp_type & MMC_RSP_136)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+       /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+       /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+        * mode data transfer
+        */
+       if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+               mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+       /* 2f. Set ENABLE bit to 1 */
+       mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+       /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+        * write data transfer
+        */
+       if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+                       cmd_index == MMC_CMD_SEND_STATUS) &&
+                       (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+                       mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+       /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+       /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+        * of CE-ATA device is enabled
+        */
+
+       /* 2j. clear all static status bits */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+       writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+       /* 2k. Write to MMC_BOOT_MCI_CMD register */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+       writel(mmc_cmd, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+       reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+       reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+       /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+        * register
+        */
+       do {
+               /* 3a. Read MCI_STATUS register */
+               mmc_status = readl(reg_status);
+               while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+                       mmc_status = readl(reg_status);
+
+               /* 3b. CMD_SENT bit supposed to be set to 1 only
+                 * after CMD0 is sent -no response required.
+                 */
+               if ((cmd->resp_type == MMC_RSP_NONE) &&
+                               (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+                       break;
+
+               /* 3c. If CMD_TIMEOUT bit is set then no response
+                 * was received */
+               else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+                       mmc_return = TIMEOUT;
+                       break;
+               }
+               /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+                 * response was received and CRC check passed
+                 * Spcial case for ACMD41: it seems to always fail CRC even if
+                 * the response is valid
+                 */
+               else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+                               (cmd_index == MMC_CMD_SEND_OP_COND)
+                               || (cmd_index == SD_CMD_SEND_IF_COND)) {
+                       /* 3i. Read MCI_RESP_CMD register to verify that
+                         *  response index is equal to command index
+                         */
+                       mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+                       /* However, long response does not contain the
+                        * command index field.
+                        * In that case, response index field must be set to
+                        * 111111b (0x3F)
+                        */
+                       if ((mmc_resp == cmd_index) ||
+                               (cmd->resp_type == MMC_RSP_R2 ||
+                               cmd->resp_type == MMC_RSP_R3 ||
+                               cmd->resp_type == MMC_RSP_R6 ||
+                               cmd->resp_type == MMC_RSP_R7)){
+                               /* 3j. If resp index is equal to cmd index,
+                                 * read command resp from MCI_RESPn registers
+                                 * - MCI_RESP0/1/2/3 for CMD2/9/10
+                                 * - MCI_RESP0 for all other registers
+                                 */
+                               if (cmd->resp_type & MMC_RSP_136) {
+                                       for (i = 0; i < 4; i++)
+                                               cmd->response[3-i] =
+                                                       readl(reg_resp_0 + \
+                                                       (i * 4));
+                               } else
+                                       cmd->response[0] = readl(reg_resp_0);
+                       } else
+                               /* command index mis-match */
+                               mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+                       break;
+               }
+
+               /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+                * was recvd, but CRC check failed.
+                */
+               else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+                       if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+                               cmd->response[0] = readl(reg_resp_0);
+                       else
+                               mmc_return = MMC_BOOT_E_CRC_FAIL;
+                       break;
+               }
+
+       }  while (1);
+
+       return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+                       struct mmc_data *data)
+{
+       uint32_t data_ctrl, mmc_reg, data_len;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg;
+
+       /* Write data timeout period to MCI_DATA_TIMER register. */
+       /* Data timeout period should be in card bus clock periods */
+       mmc_reg = (unsigned long)(((struct mmc_priv *)
+                                               (mmc->priv))->rd_timeout_ns /
+                                               1000000) * (mmc->clock / 1000);
+       /* add some extra clock cycles to be safe */
+       mmc_reg += 1000;
+       mmc_reg = mmc_reg/2;
+
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+       writel(mmc_reg, reg);
+
+       /* Write the total size of the transfer data to MCI_DATA_LENGTH
+        * register. For block xfer it must be multiple of the block
+        * size.
+        */
+
+       data_len = data->blocks*data->blocksize;
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+       writel(data_len, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+               (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+       if (data->flags == MMC_DATA_READ)
+               data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+       writel(data_ctrl, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+                               struct mmc_cmd *cmd,
+                               struct mmc_data *data)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       /*  todo: do we need to fill in command type ?? */
+
+       if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+               /* u-boot doesn't fill in the correct argument value */
+               cmd->cmdarg =  mmc->rca << 16;
+               /* this is to explicitly disable the prg enabled flag */
+               cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+       } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+               if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+                               mmc->version & SD_VERSION_SD) {
+                       mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+                       data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+               }
+       } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+                       if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+                                       mmc->version & SD_VERSION_SD) {
+                               mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+                               data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+                       }
+       } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+                       /* explicitly disable the prg enabled flag */
+                       cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+                       /* set the XFER mode */
+                       cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+       }
+
+
+       /* For Data cmd's */
+       if (data != NULL)
+               mmc_boot_init_data(mmc, cmd, data);
+
+       /* send command */
+       mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+       if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+               debug("Return Error = %d\n", mmc_ret);
+               return mmc_ret;
+       }
+
+       if (data != NULL) {
+               mmc_ret = mmc_boot_check_read_data(cmd);
+               if (mmc_ret)
+                       return mmc_ret;
+               mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+                                       data->blocks * data->blocksize,
+                                       MMC_BOOT_DATA_READ,
+                                       mmc);
+       }
+
+       if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+               /* Set read timeout once csd is received */
+               mmc_ret = mmc_boot_set_read_timeout(mmc);
+               if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+                       printf("Error No.%d: Failure setting \
+                                       write Timeout value!\n",
+                                       mmc_ret);
+                       return mmc_ret;
+               }
+       } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+               /* cmd6 needs at least 8 clocks after the
+                * End Data of Status.
+                * ticks calculated using 400KHz clock speed
+                */
+               udelay(20);
+       }
+
+       return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+       unsigned int mmc_pwr = 0;
+       struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;
+       int mmc_slot = priv->instance;
+       unsigned long reg;
+
+       /* Initialize any clocks needed for SDC controller */
+       clock_init_mmc(mmc_slot);
+
+       /* Setup initial freq to 400KHz */
+       clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+       /* set power mode*/
+       mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+       mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+       mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+       writel(mmc_pwr, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+                                               struct mmc *mmc)
+{
+       unsigned int mmc_reg;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg;
+
+       /* set MCI_CLK accordingly */
+       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+       mmc_reg = readl(reg);
+       mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+       if (width == 1)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+       else if (width == 4)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+       else if (width == 8)
+               mmc_reg |=  MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+       else
+               return MMC_BOOT_E_INVAL;
+
+       writel(mmc_reg, reg);
+
+       /* Writes to MCI port are not effective for 3 ticks of PCLK.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(8);
+
+       debug("Setting bus width to %d\n", width);
+       return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       int mmc_slot = priv->instance;
+
+       /* clock frequency should be less than 400KHz in identification mode */
+       clock_config_mmc(mmc_slot, mmc->clock);
+       /*
+        * give atleast 2 MCLK cycles delay for clocks
+        * and SDCC core to stabilize.
+        * ticks calculated using 400KHz clock speed
+        */
+       udelay(5);
+       mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+       if (mmc_ret != MMC_BOOT_E_SUCCESS)
+               printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+       /* Initialize necessary data structure and enable/set clock and power */
+       debug(" Initializing MMC host data structure and clock!\n");
+       mmc_ret = mmc_boot_init(mmc);
+       if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+               printf("MMC Boot: Error Initializing MMC Card!!!\n");
+               return MMC_BOOT_E_FAILURE;
+       }
+
+       return MMC_BOOT_E_SUCCESS;
+}
--
1.7.1


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
  2012-02-28 23:44   ` Albert ARIBAUD
  2012-03-05 14:34   ` [U-Boot] [PATCH v2 1/5] msm7x30: Add Support " Mohamed Haneef
@ 2012-03-22  8:50   ` mohamed.haneef at lntinfotech.com
  2012-04-23  9:24   ` [U-Boot] (no subject) mohamed.haneef at lntinfotech.com
  2012-04-23  9:31   ` [U-Boot] msm7630 mainline request mohamed.haneef at lntinfotech.com
  4 siblings, 0 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-03-22  8:50 UTC (permalink / raw)
  To: u-boot

From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>

This is a humbel reminder for review  of patch series for msm7630 board after making the changes proposed by u-boot community. The Patches contain the following support
        * low speed uart for msm7630
        * interprocessor communication
        * qc_mmc microcontroller
        * msm7630 soc
        * msm7630 surf board


The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] (no subject)
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
                     ` (2 preceding siblings ...)
  2012-03-22  8:50   ` [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
@ 2012-04-23  9:24   ` mohamed.haneef at lntinfotech.com
  2012-04-23  9:31   ` [U-Boot] msm7630 mainline request mohamed.haneef at lntinfotech.com
  4 siblings, 0 replies; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-04-23  9:24 UTC (permalink / raw)
  To: u-boot

The patch for msm7630 was released to the u-boot community on 16-feb-2-2012 can this be mainlined in v2012.07 release.The Patches contain the following support
        * low speed uart for msm7630
        * interprocessor communication
        * qc_mmc microcontroller
        * msm7630 soc
        * msm7630 surf board

Thanks and regards,
Mohamed Haneef M.A

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] msm7630 mainline request
  2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
                     ` (3 preceding siblings ...)
  2012-04-23  9:24   ` [U-Boot] (no subject) mohamed.haneef at lntinfotech.com
@ 2012-04-23  9:31   ` mohamed.haneef at lntinfotech.com
  2012-05-03  0:09     ` Marek Vasut
  4 siblings, 1 reply; 716+ messages in thread
From: mohamed.haneef at lntinfotech.com @ 2012-04-23  9:31 UTC (permalink / raw)
  To: u-boot

The patch for msm7630 was released to the u-boot community on 16-feb-2-2012 can this be mainlined in v2012.07 release.The Patches contain the following support
        * low speed uart for msm7630
        * interprocessor communication
        * qc_mmc microcontroller
        * msm7630 soc
        * msm7630 surf board

Thanks and regards,
Mohamed Haneef M.A

The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] msm7630 mainline request
  2012-04-23  9:31   ` [U-Boot] msm7630 mainline request mohamed.haneef at lntinfotech.com
@ 2012-05-03  0:09     ` Marek Vasut
  0 siblings, 0 replies; 716+ messages in thread
From: Marek Vasut @ 2012-05-03  0:09 UTC (permalink / raw)
  To: u-boot

Dear mohamed.haneef at lntinfotech.com,

> The patch for msm7630 was released to the u-boot community on 16-feb-2-2012
> can this be mainlined in v2012.07 release.The Patches contain the
> following support * low speed uart for msm7630
>         * interprocessor communication
>         * qc_mmc microcontroller
>         * msm7630 soc
>         * msm7630 surf board


It'd be great, CCing albert to review it as we don't have MSM maintainer.

> 
> Thanks and regards,
> Mohamed Haneef M.A
> 
> The contents of this e-mail and any attachment(s) may contain confidential
> or privileged information for the intended recipient(s). Unintended
> recipients are prohibited from taking action on the basis of information
> in this e-mail and  using or disseminating the information,  and must
> notify the sender and delete it from their system. L&T Infotech will not
> accept responsibility or liability for the accuracy or completeness of, or
> the presence of any virus or disabling code in this e-mail"
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller
  2012-03-05 14:40   ` [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller Mohamed Haneef
@ 2012-05-03 22:05     ` Andy Fleming
  2012-05-10 11:37       ` Mohamed Haneef
  0 siblings, 1 reply; 716+ messages in thread
From: Andy Fleming @ 2012-05-03 22:05 UTC (permalink / raw)
  To: u-boot

NAK, allow me to explain below:

On Mon, Mar 5, 2012 at 8:40 AM, Mohamed Haneef
<mohamed.haneef@lntinfotech.com> wrote:
> ? ? ? ?* Support for qc_mmc MMC Controller
>
> Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
> ---
> +#ifndef __MMC_H__
> +#define __MMC_H__
> +
> +#ifndef MMC_SLOT
> +#define MMC_SLOT ? ? ? ? ? ?0
> +#endif


This sort of thing should probably be passed in by the board code.




> +
> +#if 0
> +#define MSM_SDC1_BASE ? ? ? 0x12400000
> +#define MSM_SDC2_BASE ? ? ? 0x12140000
> +#define MSM_SDC3_BASE ? ? ? 0x12180000
> +#define MSM_SDC4_BASE ? ? ? 0x121C0000
> +#endif


Why's this still here?



> diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
> new file mode 100644
> index 0000000..7b7a1ed
> --- /dev/null
> +++ b/drivers/mmc/qc_mmc.c
> @@ -0,0 +1,584 @@

> +#if MMC_BOOT_ADM
> +#include "adm.h"
> +#endif
> +
> +#ifndef NULL
> +#define NULL ? ? ? ?0
> +#endif


?? Is NULL ever undefined in C?


> +
> +#define MMC_BOOT_DATA_READ ? ? 0
> +#define MMC_BOOT_DATA_WRITE ? ?1
> +/*
> + * Calculates the address of registers according to the base address
> + */
> +unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
> +{
> + ? ? ? return base + offset;
> +}
> +
> +
> +/*
> + * Sets a timeout for read operation.
> + */
> +static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
> +{
> + ? ? ? if (mmc == NULL)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_INVAL;
> +
> + ? ? ? /* todo: Add a check for HC, only if HC do this.
> + ? ? ? ?* If not, taac and nsac must be taken into account
> + ? ? ? ?*/
> + ? ? ? ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
> + ? ? ? debug(" Read timeout set: %d ns\n",
> + ? ? ? ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);


I think it's preferable to do:

struct mmc_priv *priv = mmc->priv;

priv->rd_timeout_ns = 100000000;


> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Check to ensure that there is no alignment or data length errors
> + */
> +static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
> +{
> +
> + ? ? ? if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_BLOCKLEN_ERR;
> +
> + ? ? ? /* Misaligned address not matching block length */
> + ? ? ? if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
> + ? ? ? ? ? ? ? return MMC_BOOT_E_ADDRESS_ERR;
> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Decode type of error caused during read and write
> + */
> +static unsigned int mmc_boot_status_error(unsigned mmc_status)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? ? ? ? ? /* If DATA_CRC_FAIL bit is set to 1 then CRC error
> + ? ? ? ? ? ? ? ?* was detected by card/device during the data transfer
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
> + ? ? ? ? ? ? ? /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
> + ? ? ? ? ? ? ? ?* exceeded the data timeout period without completing the
> + ? ? ? ? ? ? ? ?* transfer
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
> + ? ? ? ? ? ? ? /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
> + ? ? ? ? ? ? ? ?* receive data from the card before empty storage for new
> + ? ? ? ? ? ? ? ?* received data was available.
> + ? ? ? ? ? ? ? ?* Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
> + ? ? ? ? ? ? ? ?* the data xfer.
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
> + ? ? ? ? ? ? ? /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + ? ? ? ? ? ? ? ?* so no need to verify for now
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> + ? ? ? ? ? ? ? /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
> + ? ? ? ? ? ? ? ?* data to the card before new data for sending was available.
> + ? ? ? ? ? ? ? ?* Verify that bit FLOW_ENA in MCI_CLK
> + ? ? ? ? ? ? ? ?* is set to 1 during the data xfer.
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
> + ? ? ? ? ? ? ? /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> + ? ? ? ? ? ? ? ?* so skipping it now
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> +
> + ? ? ? return mmc_ret;
> +}
> +
> +/*
> + * Read data to SDC FIFO.
> + */
> +static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned int ?data_len,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc *mmc)
> +{


Why is mmc_ptr an unsigned int *?


> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> + ? ? ? unsigned int mmc_status = 0;
> + ? ? ? unsigned int mmc_count = 0;
> + ? ? ? unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MMC_BOOT_MCI_STAT_DATA_TIMEOUT ?| \
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MMC_BOOT_MCI_STAT_RX_OVRRUN;
> + ? ? ? unsigned int i;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv ?*)mmc->priv;


Unnecessary cast


> + ? ? ? unsigned long reg_status, reg_fifo;
> +
> + ? ? ? reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
> + ? ? ? reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
> +
> + ? ? ? /* Read the data from the MCI_FIFO register as long as
> + ? ? ? ?* RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
> + ? ? ? ?* DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
> + ? ? ? ?* register are cleared to 0.
> + ? ? ? ?* Continue the reads until the whole transfer data is received
> + ? ? ? ?*/
> +
> + ? ? ? do {
> + ? ? ? ? ? ? ? mmc_ret = MMC_BOOT_E_SUCCESS;
> + ? ? ? ? ? ? ? mmc_status = readl(reg_status);
> +
> + ? ? ? ? ? ? ? if (mmc_status & read_error) {
> + ? ? ? ? ? ? ? ? ? ? ? mmc_ret = mmc_boot_status_error(mmc_status);
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
> + ? ? ? ? ? ? ? ? ? ? ? unsigned read_count = 1;
> + ? ? ? ? ? ? ? ? ? ? ? if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? read_count = MMC_BOOT_MCI_HFIFO_COUNT;
> +
> + ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < read_count; i++) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* FIFO contains 16 32-bit data buffer
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * on 16 sequential addresses
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? *mmc_ptr = readl(reg_fifo +
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc_ptr++;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* increase mmc_count by word size */
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc_count += sizeof(unsigned int);


I don't remember if readl is explicitly sized, but it seems like there
are some implicit and explicit size dependencies, and they aren't
currently guaranteed to line up. If you're going to do this, I think
mmc_ptr should be u32*. And you should update mmc_count by
sizeof(*mmc_ptr) to lock in the connection between the increase in
mmc_count and the amount of data read.

Out of curiosity, I notice that you will read from the start of the
FIFO each time this function is called. Is there something that resets
the FIFO to put the oldest data at the first address? Or is this only
called once?


> +static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
> + ? ? ? ? ? ? ? ? ? ? ? struct mmc_data *data)
> +{
> + ? ? ? uint32_t data_ctrl, mmc_reg, data_len;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv ?*)mmc->priv;


Unnecessary cast


> + ? ? ? unsigned long reg;
> +
> + ? ? ? /* Write data timeout period to MCI_DATA_TIMER register. */
> + ? ? ? /* Data timeout period should be in card bus clock periods */
> + ? ? ? mmc_reg = (unsigned long)(((struct mmc_priv *)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (mmc->priv))->rd_timeout_ns /
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1000000) * (mmc->clock / 1000);


You've got priv already, why access it via complicated cast?


> + ? ? ? /* add some extra clock cycles to be safe */
> + ? ? ? mmc_reg += 1000;
> + ? ? ? mmc_reg = mmc_reg/2;


I'd prefer that the variables have names that indicate their purpose
(e.g. - mmc_timeout). It took me a few times looking at this to
realize you were updating a variable that will be written to a reg,
rather than a pointer to your mmc register space.

Also, I'm assuming that the register defines the timeout field so that
you need ns/2, but you might want to document that as why you divide
by 2.


> +
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
> + ? ? ? writel(mmc_reg, reg);


If you're going to repeat a sequence like this, frequently, it might
be better to create a qc_mmc_write() function which takes priv, reg,
and value as arguments:

qc_mmc_write(priv, MMC_BOOT_MCI_DATA_TIMER, mmc_reg);

BTW, are all of these prefixed with MMC_BOOT because this is only used
at boot time? Seems limiting. And it makes the constant names very
long.

> +
> + ? ? ? /* Write the total size of the transfer data to MCI_DATA_LENGTH
> + ? ? ? ?* register. For block xfer it must be multiple of the block
> + ? ? ? ?* size.
> + ? ? ? ?*/
> +
> + ? ? ? data_len = data->blocks*data->blocksize;
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
> + ? ? ? writel(data_len, reg);
> +
> + ? ? ? /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + ? ? ? ?* ticks calculated using 400KHz clock speed
> + ? ? ? ?*/
> + ? ? ? udelay(8);
> +
> + ? ? ? data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
> + ? ? ? ? ? ? ? (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
> +
> +
> + ? ? ? if (data->flags == MMC_DATA_READ)
> + ? ? ? ? ? ? ? data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
> +
> + ? ? ? reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
> + ? ? ? writel(data_ctrl, reg);
> +
> + ? ? ? /* Writes to MCI port are not effective for 3 ticks of PCLK.
> + ? ? ? ?* ticks calculated using 400KHz clock speed
> + ? ? ? ?*/
> + ? ? ? udelay(8);
> +
> +}
> +
> +/*
> + * Function to map mmc send command to board send command
> + */


This sounds...odd.


> +int mmc_boot_send_command_map(struct mmc *mmc,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc_cmd *cmd,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct mmc_data *data)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? /* ?todo: do we need to fill in command type ?? */
> +
> + ? ? ? if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
> + ? ? ? ? ? ? ? /* u-boot doesn't fill in the correct argument value */
> + ? ? ? ? ? ? ? cmd->cmdarg = ?mmc->rca << 16;


I'm not sure what this means. But if you think U-Boot should be
filling in a different value, we should change it in mmc.c, not
one-at-a-time in each driver...


> + ? ? ? ? ? ? ? /* this is to explicitly disable the prg enabled flag */
> + ? ? ? ? ? ? ? cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;


1) I'm not sure this field is ever used for anything
2) You shouldn't define your own constants for inspecting/setting data
in fields that haven't been explicitly set aside for driver-specific
implementation. While it doesn't look like any of the mmc code ever
sets this field, it could one day, and break your driver.


> +
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
> + ? ? ? ? ? ? ? if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->version & SD_VERSION_SD) {
> + ? ? ? ? ? ? ? ? ? ? ? mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? }
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
> + ? ? ? ? ? ? ? ? ? ? ? if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->version & SD_VERSION_SD) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
> + ? ? ? ? ? ? ? ? ? ? ? /* explicitly disable the prg enabled flag */
> + ? ? ? ? ? ? ? ? ? ? ? cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
> + ? ? ? ? ? ? ? ? ? ? ? /* set the XFER mode */
> + ? ? ? ? ? ? ? ? ? ? ? cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
> + ? ? ? }
> +
> +
> + ? ? ? /* For Data cmd's */


nit: no apostrophe needed



> +/*
> + * Initialize host structure, set and enable clock-rate and power mode.
> + */
> +unsigned int mmc_boot_init(struct mmc *mmc)
> +{
> + ? ? ? unsigned int mmc_pwr = 0;
> + ? ? ? struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;


No cast


> + ? ? ? int mmc_slot = priv->instance;


Whenever a driver has to be told which instance it is, a kitten
dies.... Ok, after reading through I see that it's only used to set
clocking. That's probably fine. More on this later.



> +/*
> + * Board specific initializations
> + */
> +unsigned int mmc_boot_main(struct mmc *mmc)
> +{
> + ? ? ? unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> + ? ? ? /* Initialize necessary data structure and enable/set clock and power */
> + ? ? ? debug(" Initializing MMC host data structure and clock!\n");
> + ? ? ? mmc_ret = mmc_boot_init(mmc);
> + ? ? ? if (mmc_ret != MMC_BOOT_E_SUCCESS) {
> + ? ? ? ? ? ? ? printf("MMC Boot: Error Initializing MMC Card!!!\n");
> + ? ? ? ? ? ? ? return MMC_BOOT_E_FAILURE;
> + ? ? ? }
> +
> + ? ? ? return MMC_BOOT_E_SUCCESS;
> +}


Why not put the actual initialization function here? We usually want
to contain the driver information, here. It looks like you have two
different initialization paths, but there should be some way to codify
that so that future readers/writers can understand which parts of the
driver are being used under a given set of conditions. As it currently
stands, they will have to investigate the board file to figure it out.
Use the board init function to pass in parameters the driver can use
to make those choices. For instance, the


>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and ?using or disseminating the information, ?and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"


These sorts of disclaimers really serve to irritate open source
developers. Also, it puts me in the legal void, as you neglected to CC
me, which means I might be an unintended recipient. In defiance of
your disclaimer, I decided to take action, anyway. Feel free to sue
me. :P

Andy

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller
  2012-05-03 22:05     ` Andy Fleming
@ 2012-05-10 11:37       ` Mohamed Haneef
  0 siblings, 0 replies; 716+ messages in thread
From: Mohamed Haneef @ 2012-05-10 11:37 UTC (permalink / raw)
  To: u-boot

Hi,



NAK, allow me to explain below:

On Mon, Mar 5, 2012 at 8:40 AM, Mohamed Haneef
<mohamed.haneef@lntinfotech.com> wrote:
>        * Support for qc_mmc MMC Controller
>
> Signed-off-by: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
> ---
> +#ifndef __MMC_H__
> +#define __MMC_H__
> +
> +#ifndef MMC_SLOT
> +#define MMC_SLOT            0
> +#endif


This sort of thing should probably be passed in by the board code.

it is removed.


> +
> +#if 0
> +#define MSM_SDC1_BASE       0x12400000
> +#define MSM_SDC2_BASE       0x12140000
> +#define MSM_SDC3_BASE       0x12180000
> +#define MSM_SDC4_BASE       0x121C0000
> +#endif


Why's this still here?

this got removed as well


> diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
> new file mode 100644
> index 0000000..7b7a1ed
> --- /dev/null
> +++ b/drivers/mmc/qc_mmc.c
> @@ -0,0 +1,584 @@

> +#if MMC_BOOT_ADM
> +#include "adm.h"
> +#endif
> +
> +#ifndef NULL
> +#define NULL        0
> +#endif


?? Is NULL ever undefined in C?



> +
> +#define MMC_BOOT_DATA_READ     0
> +#define MMC_BOOT_DATA_WRITE    1
> +/*
> + * Calculates the address of registers according to the base address
> + */
> +unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
> +{
> +       return base + offset;
> +}
> +
> +
> +/*
> + * Sets a timeout for read operation.
> + */
> +static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
> +{
> +       if (mmc == NULL)
> +               return MMC_BOOT_E_INVAL;
> +
> +       /* todo: Add a check for HC, only if HC do this.
> +        * If not, taac and nsac must be taken into account
> +        */
> +       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
> +       debug(" Read timeout set: %d ns\n",
> +       ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);


I think it's preferable to do:

struct mmc_priv *priv = mmc->priv;

priv->rd_timeout_ns = 100000000;


> +
> +       return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Check to ensure that there is no alignment or data length errors
> + */
> +static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
> +{
> +
> +       if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
> +               return MMC_BOOT_E_BLOCKLEN_ERR;
> +
> +       /* Misaligned address not matching block length */
> +       if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
> +               return MMC_BOOT_E_ADDRESS_ERR;
> +
> +       return MMC_BOOT_E_SUCCESS;
> +}
> +
> +/*
> + * Decode type of error caused during read and write
> + */
> +static unsigned int mmc_boot_status_error(unsigned mmc_status)
> +{
> +       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> +               /* If DATA_CRC_FAIL bit is set to 1 then CRC error
> +                * was detected by card/device during the data transfer
> +                */
> +       if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
> +               mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
> +               /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
> +                * exceeded the data timeout period without completing the
> +                * transfer
> +                */
> +       else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
> +               mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
> +               /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
> +                * receive data from the card before empty storage for new
> +                * received data was available.
> +                * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
> +                * the data xfer.
> +                */
> +       else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
> +               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> +                * so no need to verify for now
> +                */
> +               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> +               /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
> +                * data to the card before new data for sending was available.
> +                * Verify that bit FLOW_ENA in MCI_CLK
> +                * is set to 1 during the data xfer.
> +                */
> +       else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
> +               /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
> +                * so skipping it now
> +                */
> +               mmc_ret = MMC_BOOT_E_RX_OVRRUN;
> +
> +       return mmc_ret;
> +}
> +
> +/*
> + * Read data to SDC FIFO.
> + */
> +static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
> +                                               unsigned int  data_len,
> +                                               struct mmc *mmc)
> +{


Why is mmc_ptr an unsigned int *?


> +       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +       unsigned int mmc_status = 0;
> +       unsigned int mmc_count = 0;
> +       unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
> +                                       MMC_BOOT_MCI_STAT_DATA_TIMEOUT  | \
> +                                       MMC_BOOT_MCI_STAT_RX_OVRRUN;
> +       unsigned int i;
> +       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;


Unnecessary cast


> +       unsigned long reg_status, reg_fifo;
> +
> +       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
> +       reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
> +
> +       /* Read the data from the MCI_FIFO register as long as
> +        * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
> +        * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
> +        * register are cleared to 0.
> +        * Continue the reads until the whole transfer data is received
> +        */
> +
> +       do {
> +               mmc_ret = MMC_BOOT_E_SUCCESS;
> +               mmc_status = readl(reg_status);
> +
> +               if (mmc_status & read_error) {
> +                       mmc_ret = mmc_boot_status_error(mmc_status);
> +                       break;
> +               }
> +
> +               if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
> +                       unsigned read_count = 1;
> +                       if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
> +                               read_count = MMC_BOOT_MCI_HFIFO_COUNT;
> +
> +                       for (i = 0; i < read_count; i++) {
> +                               /* FIFO contains 16 32-bit data buffer
> +                                 * on 16 sequential addresses
> +                                 */
> +                               *mmc_ptr = readl(reg_fifo +
> +                                       (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
> +                               mmc_ptr++;
> +                               /* increase mmc_count by word size */
> +                               mmc_count += sizeof(unsigned int);


I don't remember if readl is explicitly sized, but it seems like there
are some implicit and explicit size dependencies, and they aren't
currently guaranteed to line up. If you're going to do this, I think
mmc_ptr should be u32*. And you should update mmc_count by
sizeof(*mmc_ptr) to lock in the connection between the increase in
mmc_count and the amount of data read.

Out of curiosity, I notice that you will read from the start of the
FIFO each time this function is called. Is there something that resets
the FIFO to put the oldest data at the first address? Or is this only
called once?


> +static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
> +                       struct mmc_data *data)
> +{
> +       uint32_t data_ctrl, mmc_reg, data_len;
> +       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;


Unnecessary cast


> +       unsigned long reg;
> +
> +       /* Write data timeout period to MCI_DATA_TIMER register. */
> +       /* Data timeout period should be in card bus clock periods */
> +       mmc_reg = (unsigned long)(((struct mmc_priv *)
> +                                               (mmc->priv))->rd_timeout_ns /
> +                                               1000000) * (mmc->clock / 1000);


You've got priv already, why access it via complicated cast?


> +       /* add some extra clock cycles to be safe */
> +       mmc_reg += 1000;
> +       mmc_reg = mmc_reg/2;


I'd prefer that the variables have names that indicate their purpose
(e.g. - mmc_timeout). It took me a few times looking at this to
realize you were updating a variable that will be written to a reg,
rather than a pointer to your mmc register space.

Also, I'm assuming that the register defines the timeout field so that
you need ns/2, but you might want to document that as why you divide
by 2.


> +
> +       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
> +       writel(mmc_reg, reg);


If you're going to repeat a sequence like this, frequently, it might
be better to create a qc_mmc_write() function which takes priv, reg,
and value as arguments:

qc_mmc_write(priv, MMC_BOOT_MCI_DATA_TIMER, mmc_reg);

BTW, are all of these prefixed with MMC_BOOT because this is only used
at boot time? Seems limiting. And it makes the constant names very
long.

> +
> +       /* Write the total size of the transfer data to MCI_DATA_LENGTH
> +        * register. For block xfer it must be multiple of the block
> +        * size.
> +        */
> +
> +       data_len = data->blocks*data->blocksize;
> +       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
> +       writel(data_len, reg);
> +
> +       /* Writes to MCI port are not effective for 3 ticks of PCLK.
> +        * ticks calculated using 400KHz clock speed
> +        */
> +       udelay(8);
> +
> +       data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
> +               (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
> +
> +
> +       if (data->flags == MMC_DATA_READ)
> +               data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
> +
> +       reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
> +       writel(data_ctrl, reg);
> +
> +       /* Writes to MCI port are not effective for 3 ticks of PCLK.
> +        * ticks calculated using 400KHz clock speed
> +        */
> +       udelay(8);
> +
> +}
> +
> +/*
> + * Function to map mmc send command to board send command
> + */


This sounds...odd.


> +int mmc_boot_send_command_map(struct mmc *mmc,
> +                               struct mmc_cmd *cmd,
> +                               struct mmc_data *data)
> +{
> +       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> +       /*  todo: do we need to fill in command type ?? */
> +
> +       if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
> +               /* u-boot doesn't fill in the correct argument value */
> +               cmd->cmdarg =  mmc->rca << 16;


I'm not sure what this means. But if you think U-Boot should be
filling in a different value, we should change it in mmc.c, not
one-at-a-time in each driver...


> +               /* this is to explicitly disable the prg enabled flag */
> +               cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;


1) I'm not sure this field is ever used for anything
2) You shouldn't define your own constants for inspecting/setting data
in fields that haven't been explicitly set aside for driver-specific
implementation. While it doesn't look like any of the mmc code ever
sets this field, it could one day, and break your driver.


> +
> +       } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
> +               if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> +                               mmc->version & SD_VERSION_SD) {
> +                       mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> +                       data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> +               }
> +       } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
> +                       if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
> +                                       mmc->version & SD_VERSION_SD) {
> +                               mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
> +                               data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
> +                       }
> +       } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
> +                       /* explicitly disable the prg enabled flag */
> +                       cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
> +                       /* set the XFER mode */
> +                       cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
> +       }
> +
> +
> +       /* For Data cmd's */


nit: no apostrophe needed



> +/*
> + * Initialize host structure, set and enable clock-rate and power mode.
> + */
> +unsigned int mmc_boot_init(struct mmc *mmc)
> +{
> +       unsigned int mmc_pwr = 0;
> +       struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;


No cast


> +       int mmc_slot = priv->instance;


Whenever a driver has to be told which instance it is, a kitten
dies.... Ok, after reading through I see that it's only used to set
clocking. That's probably fine. More on this later.



> +/*
> + * Board specific initializations
> + */
> +unsigned int mmc_boot_main(struct mmc *mmc)
> +{
> +       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
> +
> +       /* Initialize necessary data structure and enable/set clock and power */
> +       debug(" Initializing MMC host data structure and clock!\n");
> +       mmc_ret = mmc_boot_init(mmc);
> +       if (mmc_ret != MMC_BOOT_E_SUCCESS) {
> +               printf("MMC Boot: Error Initializing MMC Card!!!\n");
> +               return MMC_BOOT_E_FAILURE;
> +       }
> +
> +       return MMC_BOOT_E_SUCCESS;
> +}


Why not put the actual initialization function here? We usually want
to contain the driver information, here. It looks like you have two
different initialization paths, but there should be some way to codify
that so that future readers/writers can understand which parts of the
driver are being used under a given set of conditions. As it currently
stands, they will have to investigate the board file to figure it out.
Use the board init function to pass in parameters the driver can use
to make those choices. For instance, the


>
> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"


These sorts of disclaimers really serve to irritate open source
developers. Also, it puts me in the legal void, as you neglected to CC
me, which means I might be an unintended recipient. In defiance of
your disclaimer, I decided to take action, anyway. Feel free to sue
me. :P

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/4] slub: change declare of get_slab() to inline at all times
       [not found] <yes>
@ 2012-06-08 17:23   ` Joonsoo Kim
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

__kmalloc and it's variants are invoked much frequently
and these are performance critical functions,
so their callee functions are declared '__always_inline'
But, currently, get_slab() isn't declared '__always_inline'.
In result, __kmalloc and it's variants call get_slab() on x86.
It is not desirable result, so change it to inline at all times.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 71de9b5..30ceb6d 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3320,7 +3320,7 @@ static inline int size_index_elem(size_t bytes)
 	return (bytes - 1) / 8;
 }
 
-static struct kmem_cache *get_slab(size_t size, gfp_t flags)
+static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
 {
 	int index;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 1/4] slub: change declare of get_slab() to inline at all times
@ 2012-06-08 17:23   ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

__kmalloc and it's variants are invoked much frequently
and these are performance critical functions,
so their callee functions are declared '__always_inline'
But, currently, get_slab() isn't declared '__always_inline'.
In result, __kmalloc and it's variants call get_slab() on x86.
It is not desirable result, so change it to inline at all times.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 71de9b5..30ceb6d 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3320,7 +3320,7 @@ static inline int size_index_elem(size_t bytes)
 	return (bytes - 1) / 8;
 }
 
-static struct kmem_cache *get_slab(size_t size, gfp_t flags)
+static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
 {
 	int index;
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/4] slub: use __cmpxchg_double_slab() at interrupt disabled place
  2012-06-08 17:23   ` Joonsoo Kim
@ 2012-06-08 17:23     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

get_freelist(), unfreeze_partials() are only called with interrupt disabled,
so __cmpxchg_double_slab() is suitable.

Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 30ceb6d..686ed90 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1879,7 +1879,11 @@ redo:
 	}
 }
 
-/* Unfreeze all the cpu partial slabs */
+/*
+ * Unfreeze all the cpu partial slabs.
+ *
+ * This function must be called with interrupt disabled.
+ */
 static void unfreeze_partials(struct kmem_cache *s)
 {
 	struct kmem_cache_node *n = NULL;
@@ -1935,7 +1939,7 @@ static void unfreeze_partials(struct kmem_cache *s)
 				l = m;
 			}
 
-		} while (!cmpxchg_double_slab(s, page,
+		} while (!__cmpxchg_double_slab(s, page,
 				old.freelist, old.counters,
 				new.freelist, new.counters,
 				"unfreezing slab"));
@@ -2163,6 +2167,8 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
  * The page is still frozen if the return value is not NULL.
  *
  * If this function returns NULL then the page has been unfrozen.
+ *
+ * This function must be called with interrupt disabled.
  */
 static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 {
@@ -2179,7 +2185,7 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 		new.inuse = page->objects;
 		new.frozen = freelist != NULL;
 
-	} while (!cmpxchg_double_slab(s, page,
+	} while (!__cmpxchg_double_slab(s, page,
 		freelist, counters,
 		NULL, new.counters,
 		"get_freelist"));
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/4] slub: use __cmpxchg_double_slab() at interrupt disabled place
@ 2012-06-08 17:23     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

get_freelist(), unfreeze_partials() are only called with interrupt disabled,
so __cmpxchg_double_slab() is suitable.

Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 30ceb6d..686ed90 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1879,7 +1879,11 @@ redo:
 	}
 }
 
-/* Unfreeze all the cpu partial slabs */
+/*
+ * Unfreeze all the cpu partial slabs.
+ *
+ * This function must be called with interrupt disabled.
+ */
 static void unfreeze_partials(struct kmem_cache *s)
 {
 	struct kmem_cache_node *n = NULL;
@@ -1935,7 +1939,7 @@ static void unfreeze_partials(struct kmem_cache *s)
 				l = m;
 			}
 
-		} while (!cmpxchg_double_slab(s, page,
+		} while (!__cmpxchg_double_slab(s, page,
 				old.freelist, old.counters,
 				new.freelist, new.counters,
 				"unfreezing slab"));
@@ -2163,6 +2167,8 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
  * The page is still frozen if the return value is not NULL.
  *
  * If this function returns NULL then the page has been unfrozen.
+ *
+ * This function must be called with interrupt disabled.
  */
 static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 {
@@ -2179,7 +2185,7 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 		new.inuse = page->objects;
 		new.frozen = freelist != NULL;
 
-	} while (!cmpxchg_double_slab(s, page,
+	} while (!__cmpxchg_double_slab(s, page,
 		freelist, counters,
 		NULL, new.counters,
 		"get_freelist"));
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/4] slub: refactoring unfreeze_partials()
  2012-06-08 17:23   ` Joonsoo Kim
@ 2012-06-08 17:23     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Current implementation of unfreeze_partials() is so complicated,
but benefit from it is insignificant. In addition many code in
do {} while loop have a bad influence to a fail rate of cmpxchg_double_slab.
Under current implementation which test status of cpu partial slab
and acquire list_lock in do {} while loop,
we don't need to acquire a list_lock and gain a little benefit
when front of the cpu partial slab is to be discarded, but this is a rare case.
In case that add_partial is performed and cmpxchg_double_slab is failed,
remove_partial should be called case by case.

I think that these are disadvantages of current implementation,
so I do refactoring unfreeze_partials().

Minimizing code in do {} while loop introduce a reduced fail rate
of cmpxchg_double_slab. Below is output of 'slabinfo -r kmalloc-256'
when './perf stat -r 33 hackbench 50 process 4000 > /dev/null' is done.

** before **
Cmpxchg_double Looping
------------------------
Locked Cmpxchg Double redos   182685
Unlocked Cmpxchg Double redos 0

** after **
Cmpxchg_double Looping
------------------------
Locked Cmpxchg Double redos   177995
Unlocked Cmpxchg Double redos 1

We can see cmpxchg_double_slab fail rate is improved slightly.

Bolow is output of './perf stat -r 30 hackbench 50 process 4000 > /dev/null'.

** before **
 Performance counter stats for './hackbench 50 process 4000' (30 runs):

     108517.190463 task-clock                #    7.926 CPUs utilized            ( +-  0.24% )
         2,919,550 context-switches          #    0.027 M/sec                    ( +-  3.07% )
           100,774 CPU-migrations            #    0.929 K/sec                    ( +-  4.72% )
           124,201 page-faults               #    0.001 M/sec                    ( +-  0.15% )
   401,500,234,387 cycles                    #    3.700 GHz                      ( +-  0.24% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   250,576,913,354 instructions              #    0.62  insns per cycle          ( +-  0.13% )
    45,934,956,860 branches                  #  423.297 M/sec                    ( +-  0.14% )
       188,219,787 branch-misses             #    0.41% of all branches          ( +-  0.56% )

      13.691837307 seconds time elapsed                                          ( +-  0.24% )

** after **
 Performance counter stats for './hackbench 50 process 4000' (30 runs):

     107784.479767 task-clock                #    7.928 CPUs utilized            ( +-  0.22% )
         2,834,781 context-switches          #    0.026 M/sec                    ( +-  2.33% )
            93,083 CPU-migrations            #    0.864 K/sec                    ( +-  3.45% )
           123,967 page-faults               #    0.001 M/sec                    ( +-  0.15% )
   398,781,421,836 cycles                    #    3.700 GHz                      ( +-  0.22% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   250,189,160,419 instructions              #    0.63  insns per cycle          ( +-  0.09% )
    45,855,370,128 branches                  #  425.436 M/sec                    ( +-  0.10% )
       169,881,248 branch-misses             #    0.37% of all branches          ( +-  0.43% )

      13.596272341 seconds time elapsed                                          ( +-  0.22% )

No regression is found, but rather we can see slightly better result.

Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 686ed90..b5f2108 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1886,18 +1886,24 @@ redo:
  */
 static void unfreeze_partials(struct kmem_cache *s)
 {
-	struct kmem_cache_node *n = NULL;
+	struct kmem_cache_node *n = NULL, *n2 = NULL;
 	struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
 	struct page *page, *discard_page = NULL;
 
 	while ((page = c->partial)) {
-		enum slab_modes { M_PARTIAL, M_FREE };
-		enum slab_modes l, m;
 		struct page new;
 		struct page old;
 
 		c->partial = page->next;
-		l = M_FREE;
+
+		n2 = get_node(s, page_to_nid(page));
+		if (n != n2) {
+			if (n)
+				spin_unlock(&n->list_lock);
+
+			n = n2;
+			spin_lock(&n->list_lock);
+		}
 
 		do {
 
@@ -1910,43 +1916,17 @@ static void unfreeze_partials(struct kmem_cache *s)
 
 			new.frozen = 0;
 
-			if (!new.inuse && (!n || n->nr_partial > s->min_partial))
-				m = M_FREE;
-			else {
-				struct kmem_cache_node *n2 = get_node(s,
-							page_to_nid(page));
-
-				m = M_PARTIAL;
-				if (n != n2) {
-					if (n)
-						spin_unlock(&n->list_lock);
-
-					n = n2;
-					spin_lock(&n->list_lock);
-				}
-			}
-
-			if (l != m) {
-				if (l == M_PARTIAL) {
-					remove_partial(n, page);
-					stat(s, FREE_REMOVE_PARTIAL);
-				} else {
-					add_partial(n, page,
-						DEACTIVATE_TO_TAIL);
-					stat(s, FREE_ADD_PARTIAL);
-				}
-
-				l = m;
-			}
-
 		} while (!__cmpxchg_double_slab(s, page,
 				old.freelist, old.counters,
 				new.freelist, new.counters,
 				"unfreezing slab"));
 
-		if (m == M_FREE) {
+		if (unlikely(!new.inuse && n->nr_partial > s->min_partial)) {
 			page->next = discard_page;
 			discard_page = page;
+		} else {
+			add_partial(n, page, DEACTIVATE_TO_TAIL);
+			stat(s, FREE_ADD_PARTIAL);
 		}
 	}
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/4] slub: refactoring unfreeze_partials()
@ 2012-06-08 17:23     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Current implementation of unfreeze_partials() is so complicated,
but benefit from it is insignificant. In addition many code in
do {} while loop have a bad influence to a fail rate of cmpxchg_double_slab.
Under current implementation which test status of cpu partial slab
and acquire list_lock in do {} while loop,
we don't need to acquire a list_lock and gain a little benefit
when front of the cpu partial slab is to be discarded, but this is a rare case.
In case that add_partial is performed and cmpxchg_double_slab is failed,
remove_partial should be called case by case.

I think that these are disadvantages of current implementation,
so I do refactoring unfreeze_partials().

Minimizing code in do {} while loop introduce a reduced fail rate
of cmpxchg_double_slab. Below is output of 'slabinfo -r kmalloc-256'
when './perf stat -r 33 hackbench 50 process 4000 > /dev/null' is done.

** before **
Cmpxchg_double Looping
------------------------
Locked Cmpxchg Double redos   182685
Unlocked Cmpxchg Double redos 0

** after **
Cmpxchg_double Looping
------------------------
Locked Cmpxchg Double redos   177995
Unlocked Cmpxchg Double redos 1

We can see cmpxchg_double_slab fail rate is improved slightly.

Bolow is output of './perf stat -r 30 hackbench 50 process 4000 > /dev/null'.

** before **
 Performance counter stats for './hackbench 50 process 4000' (30 runs):

     108517.190463 task-clock                #    7.926 CPUs utilized            ( +-  0.24% )
         2,919,550 context-switches          #    0.027 M/sec                    ( +-  3.07% )
           100,774 CPU-migrations            #    0.929 K/sec                    ( +-  4.72% )
           124,201 page-faults               #    0.001 M/sec                    ( +-  0.15% )
   401,500,234,387 cycles                    #    3.700 GHz                      ( +-  0.24% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   250,576,913,354 instructions              #    0.62  insns per cycle          ( +-  0.13% )
    45,934,956,860 branches                  #  423.297 M/sec                    ( +-  0.14% )
       188,219,787 branch-misses             #    0.41% of all branches          ( +-  0.56% )

      13.691837307 seconds time elapsed                                          ( +-  0.24% )

** after **
 Performance counter stats for './hackbench 50 process 4000' (30 runs):

     107784.479767 task-clock                #    7.928 CPUs utilized            ( +-  0.22% )
         2,834,781 context-switches          #    0.026 M/sec                    ( +-  2.33% )
            93,083 CPU-migrations            #    0.864 K/sec                    ( +-  3.45% )
           123,967 page-faults               #    0.001 M/sec                    ( +-  0.15% )
   398,781,421,836 cycles                    #    3.700 GHz                      ( +-  0.22% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   250,189,160,419 instructions              #    0.63  insns per cycle          ( +-  0.09% )
    45,855,370,128 branches                  #  425.436 M/sec                    ( +-  0.10% )
       169,881,248 branch-misses             #    0.37% of all branches          ( +-  0.43% )

      13.596272341 seconds time elapsed                                          ( +-  0.22% )

No regression is found, but rather we can see slightly better result.

Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 686ed90..b5f2108 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1886,18 +1886,24 @@ redo:
  */
 static void unfreeze_partials(struct kmem_cache *s)
 {
-	struct kmem_cache_node *n = NULL;
+	struct kmem_cache_node *n = NULL, *n2 = NULL;
 	struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
 	struct page *page, *discard_page = NULL;
 
 	while ((page = c->partial)) {
-		enum slab_modes { M_PARTIAL, M_FREE };
-		enum slab_modes l, m;
 		struct page new;
 		struct page old;
 
 		c->partial = page->next;
-		l = M_FREE;
+
+		n2 = get_node(s, page_to_nid(page));
+		if (n != n2) {
+			if (n)
+				spin_unlock(&n->list_lock);
+
+			n = n2;
+			spin_lock(&n->list_lock);
+		}
 
 		do {
 
@@ -1910,43 +1916,17 @@ static void unfreeze_partials(struct kmem_cache *s)
 
 			new.frozen = 0;
 
-			if (!new.inuse && (!n || n->nr_partial > s->min_partial))
-				m = M_FREE;
-			else {
-				struct kmem_cache_node *n2 = get_node(s,
-							page_to_nid(page));
-
-				m = M_PARTIAL;
-				if (n != n2) {
-					if (n)
-						spin_unlock(&n->list_lock);
-
-					n = n2;
-					spin_lock(&n->list_lock);
-				}
-			}
-
-			if (l != m) {
-				if (l == M_PARTIAL) {
-					remove_partial(n, page);
-					stat(s, FREE_REMOVE_PARTIAL);
-				} else {
-					add_partial(n, page,
-						DEACTIVATE_TO_TAIL);
-					stat(s, FREE_ADD_PARTIAL);
-				}
-
-				l = m;
-			}
-
 		} while (!__cmpxchg_double_slab(s, page,
 				old.freelist, old.counters,
 				new.freelist, new.counters,
 				"unfreezing slab"));
 
-		if (m == M_FREE) {
+		if (unlikely(!new.inuse && n->nr_partial > s->min_partial)) {
 			page->next = discard_page;
 			discard_page = page;
+		} else {
+			add_partial(n, page, DEACTIVATE_TO_TAIL);
+			stat(s, FREE_ADD_PARTIAL);
 		}
 	}
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
  2012-06-08 17:23   ` Joonsoo Kim
@ 2012-06-08 17:23     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Current implementation of deactivate_slab() which deactivate
freelist of kmem_cache_cpu one by one is inefficient.
This patch changes it to deactivate freelist all at once.
But, there is no overall performance benefit,
because deactivate_slab() is invoked infrequently.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index b5f2108..7bcb434 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1733,16 +1733,14 @@ void init_kmem_cache_cpus(struct kmem_cache *s)
  */
 static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 {
-	enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
 	struct page *page = c->page;
 	struct kmem_cache_node *n = get_node(s, page_to_nid(page));
-	int lock = 0;
-	enum slab_modes l = M_NONE, m = M_NONE;
-	void *freelist;
-	void *nextfree;
-	int tail = DEACTIVATE_TO_HEAD;
+	void *freelist, *lastfree = NULL;
+	unsigned int nr_free = 0;
 	struct page new;
-	struct page old;
+	void *prior;
+	unsigned long counters;
+	int lock = 0, tail = DEACTIVATE_TO_HEAD;
 
 	if (page->freelist) {
 		stat(s, DEACTIVATE_REMOTE_FREES);
@@ -1752,127 +1750,54 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 	c->tid = next_tid(c->tid);
 	c->page = NULL;
 	freelist = c->freelist;
-	c->freelist = NULL;
-
-	/*
-	 * Stage one: Free all available per cpu objects back
-	 * to the page freelist while it is still frozen. Leave the
-	 * last one.
-	 *
-	 * There is no need to take the list->lock because the page
-	 * is still frozen.
-	 */
-	while (freelist && (nextfree = get_freepointer(s, freelist))) {
-		void *prior;
-		unsigned long counters;
-
-		do {
-			prior = page->freelist;
-			counters = page->counters;
-			set_freepointer(s, freelist, prior);
-			new.counters = counters;
-			new.inuse--;
-			VM_BUG_ON(!new.frozen);
-
-		} while (!__cmpxchg_double_slab(s, page,
-			prior, counters,
-			freelist, new.counters,
-			"drain percpu freelist"));
-
-		freelist = nextfree;
+	while (freelist) {
+		lastfree = freelist;
+		freelist = get_freepointer(s, freelist);
+		nr_free++;
 	}
 
-	/*
-	 * Stage two: Ensure that the page is unfrozen while the
-	 * list presence reflects the actual number of objects
-	 * during unfreeze.
-	 *
-	 * We setup the list membership and then perform a cmpxchg
-	 * with the count. If there is a mismatch then the page
-	 * is not unfrozen but the page is on the wrong list.
-	 *
-	 * Then we restart the process which may have to remove
-	 * the page from the list that we just put it on again
-	 * because the number of objects in the slab may have
-	 * changed.
-	 */
-redo:
+	freelist = c->freelist;
+	c->freelist = NULL;
 
-	old.freelist = page->freelist;
-	old.counters = page->counters;
-	VM_BUG_ON(!old.frozen);
+	do {
+		if (lock) {
+			lock = 0;
+			spin_unlock(&n->list_lock);
+		}
 
-	/* Determine target state of the slab */
-	new.counters = old.counters;
-	if (freelist) {
-		new.inuse--;
-		set_freepointer(s, freelist, old.freelist);
-		new.freelist = freelist;
-	} else
-		new.freelist = old.freelist;
+		prior = page->freelist;
+		counters = page->counters;
 
-	new.frozen = 0;
+		if (lastfree)
+			set_freepointer(s, lastfree, prior);
+		else
+			freelist = prior;
 
-	if (!new.inuse && n->nr_partial > s->min_partial)
-		m = M_FREE;
-	else if (new.freelist) {
-		m = M_PARTIAL;
-		if (!lock) {
-			lock = 1;
-			/*
-			 * Taking the spinlock removes the possiblity
-			 * that acquire_slab() will see a slab page that
-			 * is frozen
-			 */
-			spin_lock(&n->list_lock);
-		}
-	} else {
-		m = M_FULL;
-		if (kmem_cache_debug(s) && !lock) {
+		new.counters = counters;
+		VM_BUG_ON(!new.frozen);
+		new.inuse -= nr_free;
+		new.frozen = 0;
+
+		if (new.inuse || n->nr_partial <= s->min_partial) {
 			lock = 1;
-			/*
-			 * This also ensures that the scanning of full
-			 * slabs from diagnostic functions will not see
-			 * any frozen slabs.
-			 */
 			spin_lock(&n->list_lock);
 		}
-	}
-
-	if (l != m) {
-
-		if (l == M_PARTIAL)
-
-			remove_partial(n, page);
-
-		else if (l == M_FULL)
-
-			remove_full(s, page);
-
-		if (m == M_PARTIAL) {
 
+	} while (!__cmpxchg_double_slab(s, page,
+				prior, counters,
+				freelist, new.counters,
+				"drain percpu freelist"));
+	if (lock) {
+		if (kmem_cache_debug(s) && !freelist) {
+			add_full(s, n, page);
+			stat(s, DEACTIVATE_FULL);
+		} else {
 			add_partial(n, page, tail);
 			stat(s, tail);
-
-		} else if (m == M_FULL) {
-
-			stat(s, DEACTIVATE_FULL);
-			add_full(s, n, page);
-
 		}
-	}
-
-	l = m;
-	if (!__cmpxchg_double_slab(s, page,
-				old.freelist, old.counters,
-				new.freelist, new.counters,
-				"unfreezing slab"))
-		goto redo;
-
-	if (lock)
 		spin_unlock(&n->list_lock);
-
-	if (m == M_FREE) {
+	} else {
+		VM_BUG_ON(new.inuse);
 		stat(s, DEACTIVATE_EMPTY);
 		discard_slab(s, page);
 		stat(s, FREE_SLAB);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
@ 2012-06-08 17:23     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-08 17:23 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Current implementation of deactivate_slab() which deactivate
freelist of kmem_cache_cpu one by one is inefficient.
This patch changes it to deactivate freelist all at once.
But, there is no overall performance benefit,
because deactivate_slab() is invoked infrequently.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index b5f2108..7bcb434 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1733,16 +1733,14 @@ void init_kmem_cache_cpus(struct kmem_cache *s)
  */
 static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 {
-	enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
 	struct page *page = c->page;
 	struct kmem_cache_node *n = get_node(s, page_to_nid(page));
-	int lock = 0;
-	enum slab_modes l = M_NONE, m = M_NONE;
-	void *freelist;
-	void *nextfree;
-	int tail = DEACTIVATE_TO_HEAD;
+	void *freelist, *lastfree = NULL;
+	unsigned int nr_free = 0;
 	struct page new;
-	struct page old;
+	void *prior;
+	unsigned long counters;
+	int lock = 0, tail = DEACTIVATE_TO_HEAD;
 
 	if (page->freelist) {
 		stat(s, DEACTIVATE_REMOTE_FREES);
@@ -1752,127 +1750,54 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 	c->tid = next_tid(c->tid);
 	c->page = NULL;
 	freelist = c->freelist;
-	c->freelist = NULL;
-
-	/*
-	 * Stage one: Free all available per cpu objects back
-	 * to the page freelist while it is still frozen. Leave the
-	 * last one.
-	 *
-	 * There is no need to take the list->lock because the page
-	 * is still frozen.
-	 */
-	while (freelist && (nextfree = get_freepointer(s, freelist))) {
-		void *prior;
-		unsigned long counters;
-
-		do {
-			prior = page->freelist;
-			counters = page->counters;
-			set_freepointer(s, freelist, prior);
-			new.counters = counters;
-			new.inuse--;
-			VM_BUG_ON(!new.frozen);
-
-		} while (!__cmpxchg_double_slab(s, page,
-			prior, counters,
-			freelist, new.counters,
-			"drain percpu freelist"));
-
-		freelist = nextfree;
+	while (freelist) {
+		lastfree = freelist;
+		freelist = get_freepointer(s, freelist);
+		nr_free++;
 	}
 
-	/*
-	 * Stage two: Ensure that the page is unfrozen while the
-	 * list presence reflects the actual number of objects
-	 * during unfreeze.
-	 *
-	 * We setup the list membership and then perform a cmpxchg
-	 * with the count. If there is a mismatch then the page
-	 * is not unfrozen but the page is on the wrong list.
-	 *
-	 * Then we restart the process which may have to remove
-	 * the page from the list that we just put it on again
-	 * because the number of objects in the slab may have
-	 * changed.
-	 */
-redo:
+	freelist = c->freelist;
+	c->freelist = NULL;
 
-	old.freelist = page->freelist;
-	old.counters = page->counters;
-	VM_BUG_ON(!old.frozen);
+	do {
+		if (lock) {
+			lock = 0;
+			spin_unlock(&n->list_lock);
+		}
 
-	/* Determine target state of the slab */
-	new.counters = old.counters;
-	if (freelist) {
-		new.inuse--;
-		set_freepointer(s, freelist, old.freelist);
-		new.freelist = freelist;
-	} else
-		new.freelist = old.freelist;
+		prior = page->freelist;
+		counters = page->counters;
 
-	new.frozen = 0;
+		if (lastfree)
+			set_freepointer(s, lastfree, prior);
+		else
+			freelist = prior;
 
-	if (!new.inuse && n->nr_partial > s->min_partial)
-		m = M_FREE;
-	else if (new.freelist) {
-		m = M_PARTIAL;
-		if (!lock) {
-			lock = 1;
-			/*
-			 * Taking the spinlock removes the possiblity
-			 * that acquire_slab() will see a slab page that
-			 * is frozen
-			 */
-			spin_lock(&n->list_lock);
-		}
-	} else {
-		m = M_FULL;
-		if (kmem_cache_debug(s) && !lock) {
+		new.counters = counters;
+		VM_BUG_ON(!new.frozen);
+		new.inuse -= nr_free;
+		new.frozen = 0;
+
+		if (new.inuse || n->nr_partial <= s->min_partial) {
 			lock = 1;
-			/*
-			 * This also ensures that the scanning of full
-			 * slabs from diagnostic functions will not see
-			 * any frozen slabs.
-			 */
 			spin_lock(&n->list_lock);
 		}
-	}
-
-	if (l != m) {
-
-		if (l == M_PARTIAL)
-
-			remove_partial(n, page);
-
-		else if (l == M_FULL)
-
-			remove_full(s, page);
-
-		if (m == M_PARTIAL) {
 
+	} while (!__cmpxchg_double_slab(s, page,
+				prior, counters,
+				freelist, new.counters,
+				"drain percpu freelist"));
+	if (lock) {
+		if (kmem_cache_debug(s) && !freelist) {
+			add_full(s, n, page);
+			stat(s, DEACTIVATE_FULL);
+		} else {
 			add_partial(n, page, tail);
 			stat(s, tail);
-
-		} else if (m == M_FULL) {
-
-			stat(s, DEACTIVATE_FULL);
-			add_full(s, n, page);
-
 		}
-	}
-
-	l = m;
-	if (!__cmpxchg_double_slab(s, page,
-				old.freelist, old.counters,
-				new.freelist, new.counters,
-				"unfreezing slab"))
-		goto redo;
-
-	if (lock)
 		spin_unlock(&n->list_lock);
-
-	if (m == M_FREE) {
+	} else {
+		VM_BUG_ON(new.inuse);
 		stat(s, DEACTIVATE_EMPTY);
 		discard_slab(s, page);
 		stat(s, FREE_SLAB);
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
  2012-06-08 17:23   ` Joonsoo Kim
@ 2012-06-08 19:02     ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-08 19:02 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 9 Jun 2012, Joonsoo Kim wrote:

> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)

I thought that the compiler felt totally free to inline static functions
at will? This may be a matter of compiler optimization settings. I can
understand the use of always_inline in a header file but why in a .c file?



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
@ 2012-06-08 19:02     ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-08 19:02 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 9 Jun 2012, Joonsoo Kim wrote:

> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)

I thought that the compiler felt totally free to inline static functions
at will? This may be a matter of compiler optimization settings. I can
understand the use of always_inline in a header file but why in a .c file?


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
  2012-06-08 17:23     ` Joonsoo Kim
@ 2012-06-08 19:04       ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-08 19:04 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 9 Jun 2012, Joonsoo Kim wrote:

> Current implementation of deactivate_slab() which deactivate
> freelist of kmem_cache_cpu one by one is inefficient.
> This patch changes it to deactivate freelist all at once.
> But, there is no overall performance benefit,
> because deactivate_slab() is invoked infrequently.

Hmm, deactivate freelist can race with slab_free. Need to look at this in
detail.



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
@ 2012-06-08 19:04       ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-08 19:04 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 9 Jun 2012, Joonsoo Kim wrote:

> Current implementation of deactivate_slab() which deactivate
> freelist of kmem_cache_cpu one by one is inefficient.
> This patch changes it to deactivate freelist all at once.
> But, there is no overall performance benefit,
> because deactivate_slab() is invoked infrequently.

Hmm, deactivate freelist can race with slab_free. Need to look at this in
detail.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
  2012-06-08 19:02     ` Christoph Lameter
@ 2012-06-09 15:57       ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-09 15:57 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/9 Christoph Lameter <cl@linux.com>:
> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>
>> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
>> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
>
> I thought that the compiler felt totally free to inline static functions
> at will? This may be a matter of compiler optimization settings. I can
> understand the use of always_inline in a header file but why in a .c file?

Yes, but the compiler with -O2 doesn't inline get_slab() which
declared just 'static'.
I think that inlining get_slab() have a performance benefit, so add
'__always_inline' to declare of get_slab().
Other functions like slab_alloc, slab_free also use 'always_inline' in
.c file (slub.c)

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
@ 2012-06-09 15:57       ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-09 15:57 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/9 Christoph Lameter <cl@linux.com>:
> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>
>> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
>> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
>
> I thought that the compiler felt totally free to inline static functions
> at will? This may be a matter of compiler optimization settings. I can
> understand the use of always_inline in a header file but why in a .c file?

Yes, but the compiler with -O2 doesn't inline get_slab() which
declared just 'static'.
I think that inlining get_slab() have a performance benefit, so add
'__always_inline' to declare of get_slab().
Other functions like slab_alloc, slab_free also use 'always_inline' in
.c file (slub.c)

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
  2012-06-08 19:04       ` Christoph Lameter
@ 2012-06-10 10:27         ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-10 10:27 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/9 Christoph Lameter <cl@linux.com>:
> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>
>> Current implementation of deactivate_slab() which deactivate
>> freelist of kmem_cache_cpu one by one is inefficient.
>> This patch changes it to deactivate freelist all at once.
>> But, there is no overall performance benefit,
>> because deactivate_slab() is invoked infrequently.
>
> Hmm, deactivate freelist can race with slab_free. Need to look at this in
> detail.

Implemented logic is nearly same as previous one.
I just merge first step of previous deactivate_slab() with second one.
In case of failure of cmpxchg_double_slab(), reloading page->freelist,
page->counters and recomputing inuse
ensure that race with slab_free() cannot be possible.
In case that we need a lock, try to get a lock before invoking
cmpxchg_double_slab(),
so race with slab_free cannot be occured too.

Above is my humble opinion, please give me some comments.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
@ 2012-06-10 10:27         ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-10 10:27 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/9 Christoph Lameter <cl@linux.com>:
> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>
>> Current implementation of deactivate_slab() which deactivate
>> freelist of kmem_cache_cpu one by one is inefficient.
>> This patch changes it to deactivate freelist all at once.
>> But, there is no overall performance benefit,
>> because deactivate_slab() is invoked infrequently.
>
> Hmm, deactivate freelist can race with slab_free. Need to look at this in
> detail.

Implemented logic is nearly same as previous one.
I just merge first step of previous deactivate_slab() with second one.
In case of failure of cmpxchg_double_slab(), reloading page->freelist,
page->counters and recomputing inuse
ensure that race with slab_free() cannot be possible.
In case that we need a lock, try to get a lock before invoking
cmpxchg_double_slab(),
so race with slab_free cannot be occured too.

Above is my humble opinion, please give me some comments.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
  2012-06-09 15:57       ` JoonSoo Kim
@ 2012-06-11 15:04         ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-11 15:04 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sun, 10 Jun 2012, JoonSoo Kim wrote:

> 2012/6/9 Christoph Lameter <cl@linux.com>:
> > On Sat, 9 Jun 2012, Joonsoo Kim wrote:
> >
> >> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
> >> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
> >
> > I thought that the compiler felt totally free to inline static functions
> > at will? This may be a matter of compiler optimization settings. I can
> > understand the use of always_inline in a header file but why in a .c file?
>
> Yes, but the compiler with -O2 doesn't inline get_slab() which
> declared just 'static'.
> I think that inlining get_slab() have a performance benefit, so add
> '__always_inline' to declare of get_slab().
> Other functions like slab_alloc, slab_free also use 'always_inline' in
> .c file (slub.c)

Yea I thought about removing those since I would think that the compiler
should be doing the right thing.

Does gcc inline with higher optimization settings?


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/4] slub: change declare of get_slab() to inline at all times
@ 2012-06-11 15:04         ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-06-11 15:04 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sun, 10 Jun 2012, JoonSoo Kim wrote:

> 2012/6/9 Christoph Lameter <cl@linux.com>:
> > On Sat, 9 Jun 2012, Joonsoo Kim wrote:
> >
> >> -static struct kmem_cache *get_slab(size_t size, gfp_t flags)
> >> +static __always_inline struct kmem_cache *get_slab(size_t size, gfp_t flags)
> >
> > I thought that the compiler felt totally free to inline static functions
> > at will? This may be a matter of compiler optimization settings. I can
> > understand the use of always_inline in a header file but why in a .c file?
>
> Yes, but the compiler with -O2 doesn't inline get_slab() which
> declared just 'static'.
> I think that inlining get_slab() have a performance benefit, so add
> '__always_inline' to declare of get_slab().
> Other functions like slab_alloc, slab_free also use 'always_inline' in
> .c file (slub.c)

Yea I thought about removing those since I would think that the compiler
should be doing the right thing.

Does gcc inline with higher optimization settings?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/4] slub: refactoring unfreeze_partials()
  2012-06-08 17:23     ` Joonsoo Kim
@ 2012-06-20  7:19       ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-06-20  7:19 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 8, 2012 at 8:23 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> Current implementation of unfreeze_partials() is so complicated,
> but benefit from it is insignificant. In addition many code in
> do {} while loop have a bad influence to a fail rate of cmpxchg_double_slab.
> Under current implementation which test status of cpu partial slab
> and acquire list_lock in do {} while loop,
> we don't need to acquire a list_lock and gain a little benefit
> when front of the cpu partial slab is to be discarded, but this is a rare case.
> In case that add_partial is performed and cmpxchg_double_slab is failed,
> remove_partial should be called case by case.
>
> I think that these are disadvantages of current implementation,
> so I do refactoring unfreeze_partials().
>
> Minimizing code in do {} while loop introduce a reduced fail rate
> of cmpxchg_double_slab. Below is output of 'slabinfo -r kmalloc-256'
> when './perf stat -r 33 hackbench 50 process 4000 > /dev/null' is done.
>
> ** before **
> Cmpxchg_double Looping
> ------------------------
> Locked Cmpxchg Double redos   182685
> Unlocked Cmpxchg Double redos 0
>
> ** after **
> Cmpxchg_double Looping
> ------------------------
> Locked Cmpxchg Double redos   177995
> Unlocked Cmpxchg Double redos 1
>
> We can see cmpxchg_double_slab fail rate is improved slightly.
>
> Bolow is output of './perf stat -r 30 hackbench 50 process 4000 > /dev/null'.
>
> ** before **
>  Performance counter stats for './hackbench 50 process 4000' (30 runs):
>
>     108517.190463 task-clock                #    7.926 CPUs utilized            ( +-  0.24% )
>         2,919,550 context-switches          #    0.027 M/sec                    ( +-  3.07% )
>           100,774 CPU-migrations            #    0.929 K/sec                    ( +-  4.72% )
>           124,201 page-faults               #    0.001 M/sec                    ( +-  0.15% )
>   401,500,234,387 cycles                    #    3.700 GHz                      ( +-  0.24% )
>   <not supported> stalled-cycles-frontend
>   <not supported> stalled-cycles-backend
>   250,576,913,354 instructions              #    0.62  insns per cycle          ( +-  0.13% )
>    45,934,956,860 branches                  #  423.297 M/sec                    ( +-  0.14% )
>       188,219,787 branch-misses             #    0.41% of all branches          ( +-  0.56% )
>
>      13.691837307 seconds time elapsed                                          ( +-  0.24% )
>
> ** after **
>  Performance counter stats for './hackbench 50 process 4000' (30 runs):
>
>     107784.479767 task-clock                #    7.928 CPUs utilized            ( +-  0.22% )
>         2,834,781 context-switches          #    0.026 M/sec                    ( +-  2.33% )
>            93,083 CPU-migrations            #    0.864 K/sec                    ( +-  3.45% )
>           123,967 page-faults               #    0.001 M/sec                    ( +-  0.15% )
>   398,781,421,836 cycles                    #    3.700 GHz                      ( +-  0.22% )
>   <not supported> stalled-cycles-frontend
>   <not supported> stalled-cycles-backend
>   250,189,160,419 instructions              #    0.63  insns per cycle          ( +-  0.09% )
>    45,855,370,128 branches                  #  425.436 M/sec                    ( +-  0.10% )
>       169,881,248 branch-misses             #    0.37% of all branches          ( +-  0.43% )
>
>      13.596272341 seconds time elapsed                                          ( +-  0.22% )
>
> No regression is found, but rather we can see slightly better result.
>
> Acked-by: Christoph Lameter <cl@linux.com>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>

Applied, thanks!

> diff --git a/mm/slub.c b/mm/slub.c
> index 686ed90..b5f2108 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1886,18 +1886,24 @@ redo:
>  */
>  static void unfreeze_partials(struct kmem_cache *s)
>  {
> -       struct kmem_cache_node *n = NULL;
> +       struct kmem_cache_node *n = NULL, *n2 = NULL;
>        struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
>        struct page *page, *discard_page = NULL;
>
>        while ((page = c->partial)) {
> -               enum slab_modes { M_PARTIAL, M_FREE };
> -               enum slab_modes l, m;
>                struct page new;
>                struct page old;
>
>                c->partial = page->next;
> -               l = M_FREE;
> +
> +               n2 = get_node(s, page_to_nid(page));
> +               if (n != n2) {
> +                       if (n)
> +                               spin_unlock(&n->list_lock);
> +
> +                       n = n2;
> +                       spin_lock(&n->list_lock);
> +               }
>
>                do {
>
> @@ -1910,43 +1916,17 @@ static void unfreeze_partials(struct kmem_cache *s)
>
>                        new.frozen = 0;
>
> -                       if (!new.inuse && (!n || n->nr_partial > s->min_partial))
> -                               m = M_FREE;
> -                       else {
> -                               struct kmem_cache_node *n2 = get_node(s,
> -                                                       page_to_nid(page));
> -
> -                               m = M_PARTIAL;
> -                               if (n != n2) {
> -                                       if (n)
> -                                               spin_unlock(&n->list_lock);
> -
> -                                       n = n2;
> -                                       spin_lock(&n->list_lock);
> -                               }
> -                       }
> -
> -                       if (l != m) {
> -                               if (l == M_PARTIAL) {
> -                                       remove_partial(n, page);
> -                                       stat(s, FREE_REMOVE_PARTIAL);
> -                               } else {
> -                                       add_partial(n, page,
> -                                               DEACTIVATE_TO_TAIL);
> -                                       stat(s, FREE_ADD_PARTIAL);
> -                               }
> -
> -                               l = m;
> -                       }
> -
>                } while (!__cmpxchg_double_slab(s, page,
>                                old.freelist, old.counters,
>                                new.freelist, new.counters,
>                                "unfreezing slab"));
>
> -               if (m == M_FREE) {
> +               if (unlikely(!new.inuse && n->nr_partial > s->min_partial)) {
>                        page->next = discard_page;
>                        discard_page = page;
> +               } else {
> +                       add_partial(n, page, DEACTIVATE_TO_TAIL);
> +                       stat(s, FREE_ADD_PARTIAL);
>                }
>        }
>
> --
> 1.7.9.5
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/4] slub: refactoring unfreeze_partials()
@ 2012-06-20  7:19       ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-06-20  7:19 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 8, 2012 at 8:23 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> Current implementation of unfreeze_partials() is so complicated,
> but benefit from it is insignificant. In addition many code in
> do {} while loop have a bad influence to a fail rate of cmpxchg_double_slab.
> Under current implementation which test status of cpu partial slab
> and acquire list_lock in do {} while loop,
> we don't need to acquire a list_lock and gain a little benefit
> when front of the cpu partial slab is to be discarded, but this is a rare case.
> In case that add_partial is performed and cmpxchg_double_slab is failed,
> remove_partial should be called case by case.
>
> I think that these are disadvantages of current implementation,
> so I do refactoring unfreeze_partials().
>
> Minimizing code in do {} while loop introduce a reduced fail rate
> of cmpxchg_double_slab. Below is output of 'slabinfo -r kmalloc-256'
> when './perf stat -r 33 hackbench 50 process 4000 > /dev/null' is done.
>
> ** before **
> Cmpxchg_double Looping
> ------------------------
> Locked Cmpxchg Double redos   182685
> Unlocked Cmpxchg Double redos 0
>
> ** after **
> Cmpxchg_double Looping
> ------------------------
> Locked Cmpxchg Double redos   177995
> Unlocked Cmpxchg Double redos 1
>
> We can see cmpxchg_double_slab fail rate is improved slightly.
>
> Bolow is output of './perf stat -r 30 hackbench 50 process 4000 > /dev/null'.
>
> ** before **
>  Performance counter stats for './hackbench 50 process 4000' (30 runs):
>
>     108517.190463 task-clock                #    7.926 CPUs utilized            ( +-  0.24% )
>         2,919,550 context-switches          #    0.027 M/sec                    ( +-  3.07% )
>           100,774 CPU-migrations            #    0.929 K/sec                    ( +-  4.72% )
>           124,201 page-faults               #    0.001 M/sec                    ( +-  0.15% )
>   401,500,234,387 cycles                    #    3.700 GHz                      ( +-  0.24% )
>   <not supported> stalled-cycles-frontend
>   <not supported> stalled-cycles-backend
>   250,576,913,354 instructions              #    0.62  insns per cycle          ( +-  0.13% )
>    45,934,956,860 branches                  #  423.297 M/sec                    ( +-  0.14% )
>       188,219,787 branch-misses             #    0.41% of all branches          ( +-  0.56% )
>
>      13.691837307 seconds time elapsed                                          ( +-  0.24% )
>
> ** after **
>  Performance counter stats for './hackbench 50 process 4000' (30 runs):
>
>     107784.479767 task-clock                #    7.928 CPUs utilized            ( +-  0.22% )
>         2,834,781 context-switches          #    0.026 M/sec                    ( +-  2.33% )
>            93,083 CPU-migrations            #    0.864 K/sec                    ( +-  3.45% )
>           123,967 page-faults               #    0.001 M/sec                    ( +-  0.15% )
>   398,781,421,836 cycles                    #    3.700 GHz                      ( +-  0.22% )
>   <not supported> stalled-cycles-frontend
>   <not supported> stalled-cycles-backend
>   250,189,160,419 instructions              #    0.63  insns per cycle          ( +-  0.09% )
>    45,855,370,128 branches                  #  425.436 M/sec                    ( +-  0.10% )
>       169,881,248 branch-misses             #    0.37% of all branches          ( +-  0.43% )
>
>      13.596272341 seconds time elapsed                                          ( +-  0.22% )
>
> No regression is found, but rather we can see slightly better result.
>
> Acked-by: Christoph Lameter <cl@linux.com>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>

Applied, thanks!

> diff --git a/mm/slub.c b/mm/slub.c
> index 686ed90..b5f2108 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1886,18 +1886,24 @@ redo:
>  */
>  static void unfreeze_partials(struct kmem_cache *s)
>  {
> -       struct kmem_cache_node *n = NULL;
> +       struct kmem_cache_node *n = NULL, *n2 = NULL;
>        struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
>        struct page *page, *discard_page = NULL;
>
>        while ((page = c->partial)) {
> -               enum slab_modes { M_PARTIAL, M_FREE };
> -               enum slab_modes l, m;
>                struct page new;
>                struct page old;
>
>                c->partial = page->next;
> -               l = M_FREE;
> +
> +               n2 = get_node(s, page_to_nid(page));
> +               if (n != n2) {
> +                       if (n)
> +                               spin_unlock(&n->list_lock);
> +
> +                       n = n2;
> +                       spin_lock(&n->list_lock);
> +               }
>
>                do {
>
> @@ -1910,43 +1916,17 @@ static void unfreeze_partials(struct kmem_cache *s)
>
>                        new.frozen = 0;
>
> -                       if (!new.inuse && (!n || n->nr_partial > s->min_partial))
> -                               m = M_FREE;
> -                       else {
> -                               struct kmem_cache_node *n2 = get_node(s,
> -                                                       page_to_nid(page));
> -
> -                               m = M_PARTIAL;
> -                               if (n != n2) {
> -                                       if (n)
> -                                               spin_unlock(&n->list_lock);
> -
> -                                       n = n2;
> -                                       spin_lock(&n->list_lock);
> -                               }
> -                       }
> -
> -                       if (l != m) {
> -                               if (l == M_PARTIAL) {
> -                                       remove_partial(n, page);
> -                                       stat(s, FREE_REMOVE_PARTIAL);
> -                               } else {
> -                                       add_partial(n, page,
> -                                               DEACTIVATE_TO_TAIL);
> -                                       stat(s, FREE_ADD_PARTIAL);
> -                               }
> -
> -                               l = m;
> -                       }
> -
>                } while (!__cmpxchg_double_slab(s, page,
>                                old.freelist, old.counters,
>                                new.freelist, new.counters,
>                                "unfreezing slab"));
>
> -               if (m == M_FREE) {
> +               if (unlikely(!new.inuse && n->nr_partial > s->min_partial)) {
>                        page->next = discard_page;
>                        discard_page = page;
> +               } else {
> +                       add_partial(n, page, DEACTIVATE_TO_TAIL);
> +                       stat(s, FREE_ADD_PARTIAL);
>                }
>        }
>
> --
> 1.7.9.5
>
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/3] slub: prefetch next freelist pointer in __slab_alloc()
       [not found] <yes>
@ 2012-06-22 18:22   ` Joonsoo Kim
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
next freelist pointer in slab_alloc') add prefetch instruction to
fast path of allocation.

Same benefit is also available in slow path of allocation, but it is not
large portion of overall allocation. Nevertheless we could get
some benifit from it, so prefetch next freelist pointer in __slab_alloc.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index f96d8bc..92f1c0e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2248,6 +2248,7 @@ load_freelist:
 	VM_BUG_ON(!c->page->frozen);
 	c->freelist = get_freepointer(s, freelist);
 	c->tid = next_tid(c->tid);
+	prefetch_freepointer(s, c->freelist);
 	local_irq_restore(flags);
 	return freelist;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 1/3] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-06-22 18:22   ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
next freelist pointer in slab_alloc') add prefetch instruction to
fast path of allocation.

Same benefit is also available in slow path of allocation, but it is not
large portion of overall allocation. Nevertheless we could get
some benifit from it, so prefetch next freelist pointer in __slab_alloc.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index f96d8bc..92f1c0e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2248,6 +2248,7 @@ load_freelist:
 	VM_BUG_ON(!c->page->frozen);
 	c->freelist = get_freepointer(s, freelist);
 	c->tid = next_tid(c->tid);
+	prefetch_freepointer(s, c->freelist);
 	local_irq_restore(flags);
 	return freelist;
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
  2012-06-22 18:22   ` Joonsoo Kim
@ 2012-06-22 18:22     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

In current implementation, after unfreezing, we doesn't touch oldpage,
so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
with this old oldpage, this_cpu_cmpxchg() is mostly be failed.

We can change value of oldpage to NULL after unfreezing,
because unfreeze_partial() ensure that all the cpu partial slabs is removed
from cpu partial list. In this time, we could expect that
this_cpu_cmpxchg is mostly succeed.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 92f1c0e..531d8ed 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 				local_irq_save(flags);
 				unfreeze_partials(s);
 				local_irq_restore(flags);
+				oldpage = NULL;
 				pobjects = 0;
 				pages = 0;
 				stat(s, CPU_PARTIAL_DRAIN);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
@ 2012-06-22 18:22     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

In current implementation, after unfreezing, we doesn't touch oldpage,
so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
with this old oldpage, this_cpu_cmpxchg() is mostly be failed.

We can change value of oldpage to NULL after unfreezing,
because unfreeze_partial() ensure that all the cpu partial slabs is removed
from cpu partial list. In this time, we could expect that
this_cpu_cmpxchg is mostly succeed.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 92f1c0e..531d8ed 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 				local_irq_save(flags);
 				unfreeze_partials(s);
 				local_irq_restore(flags);
+				oldpage = NULL;
 				pobjects = 0;
 				pages = 0;
 				stat(s, CPU_PARTIAL_DRAIN);
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-06-22 18:22   ` Joonsoo Kim
@ 2012-06-22 18:22     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

In some case of __slab_free(), we need a lock for manipulating partial list.
If freeing object with a lock is failed, a lock doesn't needed anymore
for some reasons.

Case 1. prior is NULL, kmem_cache_debug(s) is true

In this case, another free is occured before our free is succeed.
When slab is full(prior is NULL), only possible operation is slab_free().
So in this case, we guess another free is occured.
It may make a slab frozen, so lock is not needed anymore.

Case 2. inuse is NULL

In this case, acquire_slab() is occured before out free is succeed.
We have a last object for slab, so other operation for this slab is
not possible except acquire_slab().
Acquire_slab() makes a slab frozen, so lock is not needed anymore.

Above two reason explain why we don't need a lock
when freeing object with a lock is failed.

So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
This may reduce lock contention.

This also make logic somehow simple that 'was_frozen with a lock' case
is never occured. Remove it.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 531d8ed..3e0b9db 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 	void *prior;
 	void **object = (void *)x;
 	int was_frozen;
-	int inuse;
 	struct page new;
 	unsigned long counters;
 	struct kmem_cache_node *n = NULL;
@@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 		return;
 
 	do {
+		if (unlikely(n)) {
+			spin_unlock_irqrestore(&n->list_lock, flags);
+			n = NULL;
+		}
 		prior = page->freelist;
 		counters = page->counters;
 		set_freepointer(s, object, prior);
 		new.counters = counters;
 		was_frozen = new.frozen;
 		new.inuse--;
-		if ((!new.inuse || !prior) && !was_frozen && !n) {
+		if ((!new.inuse || !prior) && !was_frozen) {
 
 			if (!kmem_cache_debug(s) && !prior)
 
@@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 
 			}
 		}
-		inuse = new.inuse;
 
 	} while (!cmpxchg_double_slab(s, page,
 		prior, counters,
@@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
                 return;
         }
 
+	if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
+		goto slab_empty;
+
 	/*
-	 * was_frozen may have been set after we acquired the list_lock in
-	 * an earlier loop. So we need to check it here again.
+	 * Objects left in the slab. If it was not on the partial list before
+	 * then add it.
 	 */
-	if (was_frozen)
-		stat(s, FREE_FROZEN);
-	else {
-		if (unlikely(!inuse && n->nr_partial > s->min_partial))
-                        goto slab_empty;
-
-		/*
-		 * Objects left in the slab. If it was not on the partial list before
-		 * then add it.
-		 */
-		if (unlikely(!prior)) {
-			remove_full(s, page);
-			add_partial(n, page, DEACTIVATE_TO_TAIL);
-			stat(s, FREE_ADD_PARTIAL);
-		}
+	if (kmem_cache_debug(s) && unlikely(!prior)) {
+		remove_full(s, page);
+		add_partial(n, page, DEACTIVATE_TO_TAIL);
+		stat(s, FREE_ADD_PARTIAL);
 	}
 	spin_unlock_irqrestore(&n->list_lock, flags);
 	return;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-06-22 18:22     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:22 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Joonsoo Kim

In some case of __slab_free(), we need a lock for manipulating partial list.
If freeing object with a lock is failed, a lock doesn't needed anymore
for some reasons.

Case 1. prior is NULL, kmem_cache_debug(s) is true

In this case, another free is occured before our free is succeed.
When slab is full(prior is NULL), only possible operation is slab_free().
So in this case, we guess another free is occured.
It may make a slab frozen, so lock is not needed anymore.

Case 2. inuse is NULL

In this case, acquire_slab() is occured before out free is succeed.
We have a last object for slab, so other operation for this slab is
not possible except acquire_slab().
Acquire_slab() makes a slab frozen, so lock is not needed anymore.

Above two reason explain why we don't need a lock
when freeing object with a lock is failed.

So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
This may reduce lock contention.

This also make logic somehow simple that 'was_frozen with a lock' case
is never occured. Remove it.

Signed-off-by: Joonsoo Kim <js1304@gmail.com>

diff --git a/mm/slub.c b/mm/slub.c
index 531d8ed..3e0b9db 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 	void *prior;
 	void **object = (void *)x;
 	int was_frozen;
-	int inuse;
 	struct page new;
 	unsigned long counters;
 	struct kmem_cache_node *n = NULL;
@@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 		return;
 
 	do {
+		if (unlikely(n)) {
+			spin_unlock_irqrestore(&n->list_lock, flags);
+			n = NULL;
+		}
 		prior = page->freelist;
 		counters = page->counters;
 		set_freepointer(s, object, prior);
 		new.counters = counters;
 		was_frozen = new.frozen;
 		new.inuse--;
-		if ((!new.inuse || !prior) && !was_frozen && !n) {
+		if ((!new.inuse || !prior) && !was_frozen) {
 
 			if (!kmem_cache_debug(s) && !prior)
 
@@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 
 			}
 		}
-		inuse = new.inuse;
 
 	} while (!cmpxchg_double_slab(s, page,
 		prior, counters,
@@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
                 return;
         }
 
+	if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
+		goto slab_empty;
+
 	/*
-	 * was_frozen may have been set after we acquired the list_lock in
-	 * an earlier loop. So we need to check it here again.
+	 * Objects left in the slab. If it was not on the partial list before
+	 * then add it.
 	 */
-	if (was_frozen)
-		stat(s, FREE_FROZEN);
-	else {
-		if (unlikely(!inuse && n->nr_partial > s->min_partial))
-                        goto slab_empty;
-
-		/*
-		 * Objects left in the slab. If it was not on the partial list before
-		 * then add it.
-		 */
-		if (unlikely(!prior)) {
-			remove_full(s, page);
-			add_partial(n, page, DEACTIVATE_TO_TAIL);
-			stat(s, FREE_ADD_PARTIAL);
-		}
+	if (kmem_cache_debug(s) && unlikely(!prior)) {
+		remove_full(s, page);
+		add_partial(n, page, DEACTIVATE_TO_TAIL);
+		stat(s, FREE_ADD_PARTIAL);
 	}
 	spin_unlock_irqrestore(&n->list_lock, flags);
 	return;
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
  2012-06-10 10:27         ` JoonSoo Kim
@ 2012-06-22 18:34           ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-22 18:34 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/10 JoonSoo Kim <js1304@gmail.com>:
> 2012/6/9 Christoph Lameter <cl@linux.com>:
>> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>>
>>> Current implementation of deactivate_slab() which deactivate
>>> freelist of kmem_cache_cpu one by one is inefficient.
>>> This patch changes it to deactivate freelist all at once.
>>> But, there is no overall performance benefit,
>>> because deactivate_slab() is invoked infrequently.
>>
>> Hmm, deactivate freelist can race with slab_free. Need to look at this in
>> detail.
>
> Implemented logic is nearly same as previous one.
> I just merge first step of previous deactivate_slab() with second one.
> In case of failure of cmpxchg_double_slab(), reloading page->freelist,
> page->counters and recomputing inuse
> ensure that race with slab_free() cannot be possible.
> In case that we need a lock, try to get a lock before invoking
> cmpxchg_double_slab(),
> so race with slab_free cannot be occured too.
>
> Above is my humble opinion, please give me some comments.

Hi Pekka and Christoph.
Could you give me some comments about this, please?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab()
@ 2012-06-22 18:34           ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-06-22 18:34 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/6/10 JoonSoo Kim <js1304@gmail.com>:
> 2012/6/9 Christoph Lameter <cl@linux.com>:
>> On Sat, 9 Jun 2012, Joonsoo Kim wrote:
>>
>>> Current implementation of deactivate_slab() which deactivate
>>> freelist of kmem_cache_cpu one by one is inefficient.
>>> This patch changes it to deactivate freelist all at once.
>>> But, there is no overall performance benefit,
>>> because deactivate_slab() is invoked infrequently.
>>
>> Hmm, deactivate freelist can race with slab_free. Need to look at this in
>> detail.
>
> Implemented logic is nearly same as previous one.
> I just merge first step of previous deactivate_slab() with second one.
> In case of failure of cmpxchg_double_slab(), reloading page->freelist,
> page->counters and recomputing inuse
> ensure that race with slab_free() cannot be possible.
> In case that we need a lock, try to get a lock before invoking
> cmpxchg_double_slab(),
> so race with slab_free cannot be occured too.
>
> Above is my humble opinion, please give me some comments.

Hi Pekka and Christoph.
Could you give me some comments about this, please?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-06-22 18:22   ` Joonsoo Kim
@ 2012-06-22 18:45     ` Joonsoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:45 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, Joonsoo Kim

Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
next freelist pointer in slab_alloc') add prefetch instruction to
fast path of allocation.

Same benefit is also available in slow path of allocation, but it is not
large portion of overall allocation. Nevertheless we could get
some benifit from it, so prefetch next freelist pointer in __slab_alloc.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
---
Add 'Cc: Eric Dumazet <eric.dumazet@gmail.com>'

diff --git a/mm/slub.c b/mm/slub.c
index f96d8bc..92f1c0e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2248,6 +2248,7 @@ load_freelist:
 	VM_BUG_ON(!c->page->frozen);
 	c->freelist = get_freepointer(s, freelist);
 	c->tid = next_tid(c->tid);
+	prefetch_freepointer(s, c->freelist);
 	local_irq_restore(flags);
 	return freelist;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-06-22 18:45     ` Joonsoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: Joonsoo Kim @ 2012-06-22 18:45 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, Joonsoo Kim

Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
next freelist pointer in slab_alloc') add prefetch instruction to
fast path of allocation.

Same benefit is also available in slow path of allocation, but it is not
large portion of overall allocation. Nevertheless we could get
some benifit from it, so prefetch next freelist pointer in __slab_alloc.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Joonsoo Kim <js1304@gmail.com>
---
Add 'Cc: Eric Dumazet <eric.dumazet@gmail.com>'

diff --git a/mm/slub.c b/mm/slub.c
index f96d8bc..92f1c0e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2248,6 +2248,7 @@ load_freelist:
 	VM_BUG_ON(!c->page->frozen);
 	c->freelist = get_freepointer(s, freelist);
 	c->tid = next_tid(c->tid);
+	prefetch_freepointer(s, c->freelist);
 	local_irq_restore(flags);
 	return freelist;
 
-- 
1.7.9.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-06-22 18:45     ` Joonsoo Kim
@ 2012-07-04 12:58       ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 12:58 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, Joonsoo Kim

Hi Pekka and Christoph.
Could you give me some comments for these patches?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 12:58       ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 12:58 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, Joonsoo Kim

Hi Pekka and Christoph.
Could you give me some comments for these patches?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-06-22 18:45     ` Joonsoo Kim
@ 2012-07-04 13:00       ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:00 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet

On Fri, Jun 22, 2012 at 9:45 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
> next freelist pointer in slab_alloc') add prefetch instruction to
> fast path of allocation.
>
> Same benefit is also available in slow path of allocation, but it is not
> large portion of overall allocation. Nevertheless we could get
> some benifit from it, so prefetch next freelist pointer in __slab_alloc.
>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> ---
> Add 'Cc: Eric Dumazet <eric.dumazet@gmail.com>'
>
> diff --git a/mm/slub.c b/mm/slub.c
> index f96d8bc..92f1c0e 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2248,6 +2248,7 @@ load_freelist:
>         VM_BUG_ON(!c->page->frozen);
>         c->freelist = get_freepointer(s, freelist);
>         c->tid = next_tid(c->tid);
> +       prefetch_freepointer(s, c->freelist);
>         local_irq_restore(flags);
>         return freelist;

Well, can you show improvement in any benchmark or workload?
Prefetching is not always an obvious win and the reason we merged
Eric's patch was that he was able to show an improvement in hackbench.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 13:00       ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:00 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet

On Fri, Jun 22, 2012 at 9:45 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> Commit 0ad9500e16fe24aa55809a2b00e0d2d0e658fc71 ('slub: prefetch
> next freelist pointer in slab_alloc') add prefetch instruction to
> fast path of allocation.
>
> Same benefit is also available in slow path of allocation, but it is not
> large portion of overall allocation. Nevertheless we could get
> some benifit from it, so prefetch next freelist pointer in __slab_alloc.
>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> ---
> Add 'Cc: Eric Dumazet <eric.dumazet@gmail.com>'
>
> diff --git a/mm/slub.c b/mm/slub.c
> index f96d8bc..92f1c0e 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2248,6 +2248,7 @@ load_freelist:
>         VM_BUG_ON(!c->page->frozen);
>         c->freelist = get_freepointer(s, freelist);
>         c->tid = next_tid(c->tid);
> +       prefetch_freepointer(s, c->freelist);
>         local_irq_restore(flags);
>         return freelist;

Well, can you show improvement in any benchmark or workload?
Prefetching is not always an obvious win and the reason we merged
Eric's patch was that he was able to show an improvement in hackbench.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
  2012-06-22 18:22     ` Joonsoo Kim
@ 2012-07-04 13:05       ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:05 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> In current implementation, after unfreezing, we doesn't touch oldpage,
> so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
>
> We can change value of oldpage to NULL after unfreezing,
> because unfreeze_partial() ensure that all the cpu partial slabs is removed
> from cpu partial list. In this time, we could expect that
> this_cpu_cmpxchg is mostly succeed.
>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 92f1c0e..531d8ed 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
>                                 local_irq_save(flags);
>                                 unfreeze_partials(s);
>                                 local_irq_restore(flags);
> +                               oldpage = NULL;
>                                 pobjects = 0;
>                                 pages = 0;
>                                 stat(s, CPU_PARTIAL_DRAIN);

Makes sense. Christoph, David?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
@ 2012-07-04 13:05       ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:05 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> In current implementation, after unfreezing, we doesn't touch oldpage,
> so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
>
> We can change value of oldpage to NULL after unfreezing,
> because unfreeze_partial() ensure that all the cpu partial slabs is removed
> from cpu partial list. In this time, we could expect that
> this_cpu_cmpxchg is mostly succeed.
>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 92f1c0e..531d8ed 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
>                                 local_irq_save(flags);
>                                 unfreeze_partials(s);
>                                 local_irq_restore(flags);
> +                               oldpage = NULL;
>                                 pobjects = 0;
>                                 pages = 0;
>                                 stat(s, CPU_PARTIAL_DRAIN);

Makes sense. Christoph, David?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-06-22 18:22     ` Joonsoo Kim
@ 2012-07-04 13:10       ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:10 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> In some case of __slab_free(), we need a lock for manipulating partial list.
> If freeing object with a lock is failed, a lock doesn't needed anymore
> for some reasons.
>
> Case 1. prior is NULL, kmem_cache_debug(s) is true
>
> In this case, another free is occured before our free is succeed.
> When slab is full(prior is NULL), only possible operation is slab_free().
> So in this case, we guess another free is occured.
> It may make a slab frozen, so lock is not needed anymore.
>
> Case 2. inuse is NULL
>
> In this case, acquire_slab() is occured before out free is succeed.
> We have a last object for slab, so other operation for this slab is
> not possible except acquire_slab().
> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>
> Above two reason explain why we don't need a lock
> when freeing object with a lock is failed.
>
> So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
> This may reduce lock contention.
>
> This also make logic somehow simple that 'was_frozen with a lock' case
> is never occured. Remove it.
>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 531d8ed..3e0b9db 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>         void *prior;
>         void **object = (void *)x;
>         int was_frozen;
> -       int inuse;
>         struct page new;
>         unsigned long counters;
>         struct kmem_cache_node *n = NULL;
> @@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>                 return;
>
>         do {
> +               if (unlikely(n)) {
> +                       spin_unlock_irqrestore(&n->list_lock, flags);
> +                       n = NULL;
> +               }
>                 prior = page->freelist;
>                 counters = page->counters;
>                 set_freepointer(s, object, prior);
>                 new.counters = counters;
>                 was_frozen = new.frozen;
>                 new.inuse--;
> -               if ((!new.inuse || !prior) && !was_frozen && !n) {
> +               if ((!new.inuse || !prior) && !was_frozen) {
>
>                         if (!kmem_cache_debug(s) && !prior)
>
> @@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>
>                         }
>                 }
> -               inuse = new.inuse;
>
>         } while (!cmpxchg_double_slab(s, page,
>                 prior, counters,
> @@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>                  return;
>          }
>
> +       if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
> +               goto slab_empty;
> +
>         /*
> -        * was_frozen may have been set after we acquired the list_lock in
> -        * an earlier loop. So we need to check it here again.
> +        * Objects left in the slab. If it was not on the partial list before
> +        * then add it.
>          */
> -       if (was_frozen)
> -               stat(s, FREE_FROZEN);
> -       else {
> -               if (unlikely(!inuse && n->nr_partial > s->min_partial))
> -                        goto slab_empty;
> -
> -               /*
> -                * Objects left in the slab. If it was not on the partial list before
> -                * then add it.
> -                */
> -               if (unlikely(!prior)) {
> -                       remove_full(s, page);
> -                       add_partial(n, page, DEACTIVATE_TO_TAIL);
> -                       stat(s, FREE_ADD_PARTIAL);
> -               }
> +       if (kmem_cache_debug(s) && unlikely(!prior)) {
> +               remove_full(s, page);
> +               add_partial(n, page, DEACTIVATE_TO_TAIL);
> +               stat(s, FREE_ADD_PARTIAL);
>         }
>         spin_unlock_irqrestore(&n->list_lock, flags);
>         return;

I'm confused. Does this fix a bug or is it an optimization?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-04 13:10       ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 13:10 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> In some case of __slab_free(), we need a lock for manipulating partial list.
> If freeing object with a lock is failed, a lock doesn't needed anymore
> for some reasons.
>
> Case 1. prior is NULL, kmem_cache_debug(s) is true
>
> In this case, another free is occured before our free is succeed.
> When slab is full(prior is NULL), only possible operation is slab_free().
> So in this case, we guess another free is occured.
> It may make a slab frozen, so lock is not needed anymore.
>
> Case 2. inuse is NULL
>
> In this case, acquire_slab() is occured before out free is succeed.
> We have a last object for slab, so other operation for this slab is
> not possible except acquire_slab().
> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>
> Above two reason explain why we don't need a lock
> when freeing object with a lock is failed.
>
> So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
> This may reduce lock contention.
>
> This also make logic somehow simple that 'was_frozen with a lock' case
> is never occured. Remove it.
>
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>
> diff --git a/mm/slub.c b/mm/slub.c
> index 531d8ed..3e0b9db 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>         void *prior;
>         void **object = (void *)x;
>         int was_frozen;
> -       int inuse;
>         struct page new;
>         unsigned long counters;
>         struct kmem_cache_node *n = NULL;
> @@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>                 return;
>
>         do {
> +               if (unlikely(n)) {
> +                       spin_unlock_irqrestore(&n->list_lock, flags);
> +                       n = NULL;
> +               }
>                 prior = page->freelist;
>                 counters = page->counters;
>                 set_freepointer(s, object, prior);
>                 new.counters = counters;
>                 was_frozen = new.frozen;
>                 new.inuse--;
> -               if ((!new.inuse || !prior) && !was_frozen && !n) {
> +               if ((!new.inuse || !prior) && !was_frozen) {
>
>                         if (!kmem_cache_debug(s) && !prior)
>
> @@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>
>                         }
>                 }
> -               inuse = new.inuse;
>
>         } while (!cmpxchg_double_slab(s, page,
>                 prior, counters,
> @@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>                  return;
>          }
>
> +       if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
> +               goto slab_empty;
> +
>         /*
> -        * was_frozen may have been set after we acquired the list_lock in
> -        * an earlier loop. So we need to check it here again.
> +        * Objects left in the slab. If it was not on the partial list before
> +        * then add it.
>          */
> -       if (was_frozen)
> -               stat(s, FREE_FROZEN);
> -       else {
> -               if (unlikely(!inuse && n->nr_partial > s->min_partial))
> -                        goto slab_empty;
> -
> -               /*
> -                * Objects left in the slab. If it was not on the partial list before
> -                * then add it.
> -                */
> -               if (unlikely(!prior)) {
> -                       remove_full(s, page);
> -                       add_partial(n, page, DEACTIVATE_TO_TAIL);
> -                       stat(s, FREE_ADD_PARTIAL);
> -               }
> +       if (kmem_cache_debug(s) && unlikely(!prior)) {
> +               remove_full(s, page);
> +               add_partial(n, page, DEACTIVATE_TO_TAIL);
> +               stat(s, FREE_ADD_PARTIAL);
>         }
>         spin_unlock_irqrestore(&n->list_lock, flags);
>         return;

I'm confused. Does this fix a bug or is it an optimization?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 13:00       ` Pekka Enberg
@ 2012-07-04 14:30         ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 14:30 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet

2012/7/4 Pekka Enberg <penberg@kernel.org>:
> Well, can you show improvement in any benchmark or workload?
> Prefetching is not always an obvious win and the reason we merged
> Eric's patch was that he was able to show an improvement in hackbench.

I thinks that this patch is perfectly same effect as Eric's patch, so
doesn't include benchmark result.
Eric's patch which add "prefetch instruction" in fastpath works for
second ~ last object of cpu slab.
This patch which add "prefetch instrunction" in slowpath works for
first object of cpu slab.

But, I do test "./perf stat -r 20 ./hackbench 50 process 4000 >
/dev/null" and gain following outputs.

***** vanilla *****

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     114189.571311 task-clock                #    7.924 CPUs utilized
          ( +-  0.29% )
         2,978,515 context-switches          #    0.026 M/sec
          ( +-  3.45% )
           102,635 CPU-migrations            #    0.899 K/sec
          ( +-  5.63% )
           123,948 page-faults               #    0.001 M/sec
          ( +-  0.16% )
   422,477,120,134 cycles                    #    3.700 GHz
          ( +-  0.29% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,943,851,074 instructions              #    0.60  insns per
cycle          ( +-  0.14% )
    46,214,207,979 branches                  #  404.715 M/sec
          ( +-  0.15% )
       215,342,095 branch-misses             #    0.47% of all
branches          ( +-  0.53% )

      14.409990448 seconds time elapsed
          ( +-  0.30% )

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     114576.053284 task-clock                #    7.921 CPUs utilized
          ( +-  0.35% )
         2,810,138 context-switches          #    0.025 M/sec
          ( +-  3.21% )
            85,641 CPU-migrations            #    0.747 K/sec
          ( +-  5.05% )
           124,299 page-faults               #    0.001 M/sec
          ( +-  0.18% )
   423,906,539,517 cycles                    #    3.700 GHz
          ( +-  0.35% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,354,351,283 instructions              #    0.59  insns per
cycle          ( +-  0.13% )
    46,098,601,012 branches                  #  402.341 M/sec
          ( +-  0.13% )
       213,448,657 branch-misses             #    0.46% of all
branches          ( +-  0.50% )

      14.464325969 seconds time elapsed
          ( +-  0.34% )


***** patch applied *****

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     112935.199731 task-clock                #    7.926 CPUs utilized
          ( +-  0.29% )
         2,810,157 context-switches          #    0.025 M/sec
          ( +-  2.95% )
           104,278 CPU-migrations            #    0.923 K/sec
          ( +-  6.83% )
           123,999 page-faults               #    0.001 M/sec
          ( +-  0.17% )
   417,834,406,420 cycles                    #    3.700 GHz
          ( +-  0.29% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,291,523,926 instructions              #    0.60  insns per
cycle          ( +-  0.11% )
    46,083,091,476 branches                  #  408.049 M/sec
          ( +-  0.12% )
       213,714,228 branch-misses             #    0.46% of all
branches          ( +-  0.43% )

      14.248980376 seconds time elapsed
          ( +-  0.29% )

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     113640.944855 task-clock                #    7.926 CPUs utilized
          ( +-  0.28% )
         2,776,983 context-switches          #    0.024 M/sec
          ( +-  5.66% )
            95,962 CPU-migrations            #    0.844 K/sec
          ( +- 10.69% )
           123,849 page-faults               #    0.001 M/sec
          ( +-  0.15% )
   420,446,572,595 cycles                    #    3.700 GHz
          ( +-  0.28% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,174,259,429 instructions              #    0.60  insns per
cycle          ( +-  0.21% )
    46,060,683,039 branches                  #  405.318 M/sec
          ( +-  0.23% )
       213,480,999 branch-misses             #    0.46% of all
branches          ( +-  0.75% )

      14.336843534 seconds time elapsed
          ( +-  0.28% )

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 14:30         ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 14:30 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet

2012/7/4 Pekka Enberg <penberg@kernel.org>:
> Well, can you show improvement in any benchmark or workload?
> Prefetching is not always an obvious win and the reason we merged
> Eric's patch was that he was able to show an improvement in hackbench.

I thinks that this patch is perfectly same effect as Eric's patch, so
doesn't include benchmark result.
Eric's patch which add "prefetch instruction" in fastpath works for
second ~ last object of cpu slab.
This patch which add "prefetch instrunction" in slowpath works for
first object of cpu slab.

But, I do test "./perf stat -r 20 ./hackbench 50 process 4000 >
/dev/null" and gain following outputs.

***** vanilla *****

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     114189.571311 task-clock                #    7.924 CPUs utilized
          ( +-  0.29% )
         2,978,515 context-switches          #    0.026 M/sec
          ( +-  3.45% )
           102,635 CPU-migrations            #    0.899 K/sec
          ( +-  5.63% )
           123,948 page-faults               #    0.001 M/sec
          ( +-  0.16% )
   422,477,120,134 cycles                    #    3.700 GHz
          ( +-  0.29% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,943,851,074 instructions              #    0.60  insns per
cycle          ( +-  0.14% )
    46,214,207,979 branches                  #  404.715 M/sec
          ( +-  0.15% )
       215,342,095 branch-misses             #    0.47% of all
branches          ( +-  0.53% )

      14.409990448 seconds time elapsed
          ( +-  0.30% )

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     114576.053284 task-clock                #    7.921 CPUs utilized
          ( +-  0.35% )
         2,810,138 context-switches          #    0.025 M/sec
          ( +-  3.21% )
            85,641 CPU-migrations            #    0.747 K/sec
          ( +-  5.05% )
           124,299 page-faults               #    0.001 M/sec
          ( +-  0.18% )
   423,906,539,517 cycles                    #    3.700 GHz
          ( +-  0.35% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,354,351,283 instructions              #    0.59  insns per
cycle          ( +-  0.13% )
    46,098,601,012 branches                  #  402.341 M/sec
          ( +-  0.13% )
       213,448,657 branch-misses             #    0.46% of all
branches          ( +-  0.50% )

      14.464325969 seconds time elapsed
          ( +-  0.34% )


***** patch applied *****

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     112935.199731 task-clock                #    7.926 CPUs utilized
          ( +-  0.29% )
         2,810,157 context-switches          #    0.025 M/sec
          ( +-  2.95% )
           104,278 CPU-migrations            #    0.923 K/sec
          ( +-  6.83% )
           123,999 page-faults               #    0.001 M/sec
          ( +-  0.17% )
   417,834,406,420 cycles                    #    3.700 GHz
          ( +-  0.29% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,291,523,926 instructions              #    0.60  insns per
cycle          ( +-  0.11% )
    46,083,091,476 branches                  #  408.049 M/sec
          ( +-  0.12% )
       213,714,228 branch-misses             #    0.46% of all
branches          ( +-  0.43% )

      14.248980376 seconds time elapsed
          ( +-  0.29% )

 Performance counter stats for './hackbench 50 process 4000' (20 runs):

     113640.944855 task-clock                #    7.926 CPUs utilized
          ( +-  0.28% )
         2,776,983 context-switches          #    0.024 M/sec
          ( +-  5.66% )
            95,962 CPU-migrations            #    0.844 K/sec
          ( +- 10.69% )
           123,849 page-faults               #    0.001 M/sec
          ( +-  0.15% )
   420,446,572,595 cycles                    #    3.700 GHz
          ( +-  0.28% )
   <not supported> stalled-cycles-frontend
   <not supported> stalled-cycles-backend
   251,174,259,429 instructions              #    0.60  insns per
cycle          ( +-  0.21% )
    46,060,683,039 branches                  #  405.318 M/sec
          ( +-  0.23% )
       213,480,999 branch-misses             #    0.46% of all
branches          ( +-  0.75% )

      14.336843534 seconds time elapsed
          ( +-  0.28% )

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-04 13:10       ` Pekka Enberg
@ 2012-07-04 14:48         ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 14:48 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/4 Pekka Enberg <penberg@kernel.org>:
> On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
>> In some case of __slab_free(), we need a lock for manipulating partial list.
>> If freeing object with a lock is failed, a lock doesn't needed anymore
>> for some reasons.
>>
>> Case 1. prior is NULL, kmem_cache_debug(s) is true
>>
>> In this case, another free is occured before our free is succeed.
>> When slab is full(prior is NULL), only possible operation is slab_free().
>> So in this case, we guess another free is occured.
>> It may make a slab frozen, so lock is not needed anymore.
>>
>> Case 2. inuse is NULL
>>
>> In this case, acquire_slab() is occured before out free is succeed.
>> We have a last object for slab, so other operation for this slab is
>> not possible except acquire_slab().
>> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>>
>> Above two reason explain why we don't need a lock
>> when freeing object with a lock is failed.
>>
>> So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
>> This may reduce lock contention.
>>
>> This also make logic somehow simple that 'was_frozen with a lock' case
>> is never occured. Remove it.
>>
>> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>>
>> diff --git a/mm/slub.c b/mm/slub.c
>> index 531d8ed..3e0b9db 100644
>> --- a/mm/slub.c
>> +++ b/mm/slub.c
>> @@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>         void *prior;
>>         void **object = (void *)x;
>>         int was_frozen;
>> -       int inuse;
>>         struct page new;
>>         unsigned long counters;
>>         struct kmem_cache_node *n = NULL;
>> @@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>                 return;
>>
>>         do {
>> +               if (unlikely(n)) {
>> +                       spin_unlock_irqrestore(&n->list_lock, flags);
>> +                       n = NULL;
>> +               }
>>                 prior = page->freelist;
>>                 counters = page->counters;
>>                 set_freepointer(s, object, prior);
>>                 new.counters = counters;
>>                 was_frozen = new.frozen;
>>                 new.inuse--;
>> -               if ((!new.inuse || !prior) && !was_frozen && !n) {
>> +               if ((!new.inuse || !prior) && !was_frozen) {
>>
>>                         if (!kmem_cache_debug(s) && !prior)
>>
>> @@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>
>>                         }
>>                 }
>> -               inuse = new.inuse;
>>
>>         } while (!cmpxchg_double_slab(s, page,
>>                 prior, counters,
>> @@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>                  return;
>>          }
>>
>> +       if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
>> +               goto slab_empty;
>> +
>>         /*
>> -        * was_frozen may have been set after we acquired the list_lock in
>> -        * an earlier loop. So we need to check it here again.
>> +        * Objects left in the slab. If it was not on the partial list before
>> +        * then add it.
>>          */
>> -       if (was_frozen)
>> -               stat(s, FREE_FROZEN);
>> -       else {
>> -               if (unlikely(!inuse && n->nr_partial > s->min_partial))
>> -                        goto slab_empty;
>> -
>> -               /*
>> -                * Objects left in the slab. If it was not on the partial list before
>> -                * then add it.
>> -                */
>> -               if (unlikely(!prior)) {
>> -                       remove_full(s, page);
>> -                       add_partial(n, page, DEACTIVATE_TO_TAIL);
>> -                       stat(s, FREE_ADD_PARTIAL);
>> -               }
>> +       if (kmem_cache_debug(s) && unlikely(!prior)) {
>> +               remove_full(s, page);
>> +               add_partial(n, page, DEACTIVATE_TO_TAIL);
>> +               stat(s, FREE_ADD_PARTIAL);
>>         }
>>         spin_unlock_irqrestore(&n->list_lock, flags);
>>         return;
>
> I'm confused. Does this fix a bug or is it an optimization?

It is for reducing lock contention and code clean-up.

If we aquire a lock and cmpxchg_double failed, we do releasing a lock.
This result in reducing lock contention.
And this remove "was_frozen and having a lock" case, so logic slightly
simpler than before.

Commit message which confuse u means that this patch do not decrease
performance for two reasons.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-04 14:48         ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 14:48 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/4 Pekka Enberg <penberg@kernel.org>:
> On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
>> In some case of __slab_free(), we need a lock for manipulating partial list.
>> If freeing object with a lock is failed, a lock doesn't needed anymore
>> for some reasons.
>>
>> Case 1. prior is NULL, kmem_cache_debug(s) is true
>>
>> In this case, another free is occured before our free is succeed.
>> When slab is full(prior is NULL), only possible operation is slab_free().
>> So in this case, we guess another free is occured.
>> It may make a slab frozen, so lock is not needed anymore.
>>
>> Case 2. inuse is NULL
>>
>> In this case, acquire_slab() is occured before out free is succeed.
>> We have a last object for slab, so other operation for this slab is
>> not possible except acquire_slab().
>> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>>
>> Above two reason explain why we don't need a lock
>> when freeing object with a lock is failed.
>>
>> So, when cmpxchg_double_slab() is failed, releasing a lock is more suitable.
>> This may reduce lock contention.
>>
>> This also make logic somehow simple that 'was_frozen with a lock' case
>> is never occured. Remove it.
>>
>> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
>>
>> diff --git a/mm/slub.c b/mm/slub.c
>> index 531d8ed..3e0b9db 100644
>> --- a/mm/slub.c
>> +++ b/mm/slub.c
>> @@ -2438,7 +2438,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>         void *prior;
>>         void **object = (void *)x;
>>         int was_frozen;
>> -       int inuse;
>>         struct page new;
>>         unsigned long counters;
>>         struct kmem_cache_node *n = NULL;
>> @@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>                 return;
>>
>>         do {
>> +               if (unlikely(n)) {
>> +                       spin_unlock_irqrestore(&n->list_lock, flags);
>> +                       n = NULL;
>> +               }
>>                 prior = page->freelist;
>>                 counters = page->counters;
>>                 set_freepointer(s, object, prior);
>>                 new.counters = counters;
>>                 was_frozen = new.frozen;
>>                 new.inuse--;
>> -               if ((!new.inuse || !prior) && !was_frozen && !n) {
>> +               if ((!new.inuse || !prior) && !was_frozen) {
>>
>>                         if (!kmem_cache_debug(s) && !prior)
>>
>> @@ -2481,7 +2484,6 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>
>>                         }
>>                 }
>> -               inuse = new.inuse;
>>
>>         } while (!cmpxchg_double_slab(s, page,
>>                 prior, counters,
>> @@ -2507,25 +2509,17 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
>>                  return;
>>          }
>>
>> +       if (unlikely(!new.inuse && n->nr_partial > s->min_partial))
>> +               goto slab_empty;
>> +
>>         /*
>> -        * was_frozen may have been set after we acquired the list_lock in
>> -        * an earlier loop. So we need to check it here again.
>> +        * Objects left in the slab. If it was not on the partial list before
>> +        * then add it.
>>          */
>> -       if (was_frozen)
>> -               stat(s, FREE_FROZEN);
>> -       else {
>> -               if (unlikely(!inuse && n->nr_partial > s->min_partial))
>> -                        goto slab_empty;
>> -
>> -               /*
>> -                * Objects left in the slab. If it was not on the partial list before
>> -                * then add it.
>> -                */
>> -               if (unlikely(!prior)) {
>> -                       remove_full(s, page);
>> -                       add_partial(n, page, DEACTIVATE_TO_TAIL);
>> -                       stat(s, FREE_ADD_PARTIAL);
>> -               }
>> +       if (kmem_cache_debug(s) && unlikely(!prior)) {
>> +               remove_full(s, page);
>> +               add_partial(n, page, DEACTIVATE_TO_TAIL);
>> +               stat(s, FREE_ADD_PARTIAL);
>>         }
>>         spin_unlock_irqrestore(&n->list_lock, flags);
>>         return;
>
> I'm confused. Does this fix a bug or is it an optimization?

It is for reducing lock contention and code clean-up.

If we aquire a lock and cmpxchg_double failed, we do releasing a lock.
This result in reducing lock contention.
And this remove "was_frozen and having a lock" case, so logic slightly
simpler than before.

Commit message which confuse u means that this patch do not decrease
performance for two reasons.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 14:30         ` JoonSoo Kim
@ 2012-07-04 15:08           ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 15:08 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

> 2012/7/4 Pekka Enberg <penberg@kernel.org>:
>> Well, can you show improvement in any benchmark or workload?
>> Prefetching is not always an obvious win and the reason we merged
>> Eric's patch was that he was able to show an improvement in hackbench.

On Wed, Jul 4, 2012 at 5:30 PM, JoonSoo Kim <js1304@gmail.com> wrote:
> I thinks that this patch is perfectly same effect as Eric's patch, so
> doesn't include benchmark result.
> Eric's patch which add "prefetch instruction" in fastpath works for
> second ~ last object of cpu slab.
> This patch which add "prefetch instrunction" in slowpath works for
> first object of cpu slab.

Prefetching can also have negative effect on overall performance:

http://lwn.net/Articles/444336/

> But, I do test "./perf stat -r 20 ./hackbench 50 process 4000 >
> /dev/null" and gain following outputs.
>
> ***** vanilla *****
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      114189.571311 task-clock                #    7.924 CPUs utilized
>           ( +-  0.29% )
>          2,978,515 context-switches          #    0.026 M/sec
>           ( +-  3.45% )
>            102,635 CPU-migrations            #    0.899 K/sec
>           ( +-  5.63% )
>            123,948 page-faults               #    0.001 M/sec
>           ( +-  0.16% )
>    422,477,120,134 cycles                    #    3.700 GHz
>           ( +-  0.29% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,943,851,074 instructions              #    0.60  insns per
> cycle          ( +-  0.14% )
>     46,214,207,979 branches                  #  404.715 M/sec
>           ( +-  0.15% )
>        215,342,095 branch-misses             #    0.47% of all
> branches          ( +-  0.53% )
>
>       14.409990448 seconds time elapsed
>           ( +-  0.30% )
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      114576.053284 task-clock                #    7.921 CPUs utilized
>           ( +-  0.35% )
>          2,810,138 context-switches          #    0.025 M/sec
>           ( +-  3.21% )
>             85,641 CPU-migrations            #    0.747 K/sec
>           ( +-  5.05% )
>            124,299 page-faults               #    0.001 M/sec
>           ( +-  0.18% )
>    423,906,539,517 cycles                    #    3.700 GHz
>           ( +-  0.35% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,354,351,283 instructions              #    0.59  insns per
> cycle          ( +-  0.13% )
>     46,098,601,012 branches                  #  402.341 M/sec
>           ( +-  0.13% )
>        213,448,657 branch-misses             #    0.46% of all
> branches          ( +-  0.50% )
>
>       14.464325969 seconds time elapsed
>           ( +-  0.34% )
>
>
> ***** patch applied *****
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      112935.199731 task-clock                #    7.926 CPUs utilized
>           ( +-  0.29% )
>          2,810,157 context-switches          #    0.025 M/sec
>           ( +-  2.95% )
>            104,278 CPU-migrations            #    0.923 K/sec
>           ( +-  6.83% )
>            123,999 page-faults               #    0.001 M/sec
>           ( +-  0.17% )
>    417,834,406,420 cycles                    #    3.700 GHz
>           ( +-  0.29% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,291,523,926 instructions              #    0.60  insns per
> cycle          ( +-  0.11% )
>     46,083,091,476 branches                  #  408.049 M/sec
>           ( +-  0.12% )
>        213,714,228 branch-misses             #    0.46% of all
> branches          ( +-  0.43% )
>
>       14.248980376 seconds time elapsed
>           ( +-  0.29% )
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      113640.944855 task-clock                #    7.926 CPUs utilized
>           ( +-  0.28% )
>          2,776,983 context-switches          #    0.024 M/sec
>           ( +-  5.66% )
>             95,962 CPU-migrations            #    0.844 K/sec
>           ( +- 10.69% )
>            123,849 page-faults               #    0.001 M/sec
>           ( +-  0.15% )
>    420,446,572,595 cycles                    #    3.700 GHz
>           ( +-  0.28% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,174,259,429 instructions              #    0.60  insns per
> cycle          ( +-  0.21% )
>     46,060,683,039 branches                  #  405.318 M/sec
>           ( +-  0.23% )
>        213,480,999 branch-misses             #    0.46% of all
> branches          ( +-  0.75% )
>
>       14.336843534 seconds time elapsed
>           ( +-  0.28% )

That doesn't seem like that obvious win to me... Eric, Christoph?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 15:08           ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 15:08 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

> 2012/7/4 Pekka Enberg <penberg@kernel.org>:
>> Well, can you show improvement in any benchmark or workload?
>> Prefetching is not always an obvious win and the reason we merged
>> Eric's patch was that he was able to show an improvement in hackbench.

On Wed, Jul 4, 2012 at 5:30 PM, JoonSoo Kim <js1304@gmail.com> wrote:
> I thinks that this patch is perfectly same effect as Eric's patch, so
> doesn't include benchmark result.
> Eric's patch which add "prefetch instruction" in fastpath works for
> second ~ last object of cpu slab.
> This patch which add "prefetch instrunction" in slowpath works for
> first object of cpu slab.

Prefetching can also have negative effect on overall performance:

http://lwn.net/Articles/444336/

> But, I do test "./perf stat -r 20 ./hackbench 50 process 4000 >
> /dev/null" and gain following outputs.
>
> ***** vanilla *****
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      114189.571311 task-clock                #    7.924 CPUs utilized
>           ( +-  0.29% )
>          2,978,515 context-switches          #    0.026 M/sec
>           ( +-  3.45% )
>            102,635 CPU-migrations            #    0.899 K/sec
>           ( +-  5.63% )
>            123,948 page-faults               #    0.001 M/sec
>           ( +-  0.16% )
>    422,477,120,134 cycles                    #    3.700 GHz
>           ( +-  0.29% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,943,851,074 instructions              #    0.60  insns per
> cycle          ( +-  0.14% )
>     46,214,207,979 branches                  #  404.715 M/sec
>           ( +-  0.15% )
>        215,342,095 branch-misses             #    0.47% of all
> branches          ( +-  0.53% )
>
>       14.409990448 seconds time elapsed
>           ( +-  0.30% )
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      114576.053284 task-clock                #    7.921 CPUs utilized
>           ( +-  0.35% )
>          2,810,138 context-switches          #    0.025 M/sec
>           ( +-  3.21% )
>             85,641 CPU-migrations            #    0.747 K/sec
>           ( +-  5.05% )
>            124,299 page-faults               #    0.001 M/sec
>           ( +-  0.18% )
>    423,906,539,517 cycles                    #    3.700 GHz
>           ( +-  0.35% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,354,351,283 instructions              #    0.59  insns per
> cycle          ( +-  0.13% )
>     46,098,601,012 branches                  #  402.341 M/sec
>           ( +-  0.13% )
>        213,448,657 branch-misses             #    0.46% of all
> branches          ( +-  0.50% )
>
>       14.464325969 seconds time elapsed
>           ( +-  0.34% )
>
>
> ***** patch applied *****
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      112935.199731 task-clock                #    7.926 CPUs utilized
>           ( +-  0.29% )
>          2,810,157 context-switches          #    0.025 M/sec
>           ( +-  2.95% )
>            104,278 CPU-migrations            #    0.923 K/sec
>           ( +-  6.83% )
>            123,999 page-faults               #    0.001 M/sec
>           ( +-  0.17% )
>    417,834,406,420 cycles                    #    3.700 GHz
>           ( +-  0.29% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,291,523,926 instructions              #    0.60  insns per
> cycle          ( +-  0.11% )
>     46,083,091,476 branches                  #  408.049 M/sec
>           ( +-  0.12% )
>        213,714,228 branch-misses             #    0.46% of all
> branches          ( +-  0.43% )
>
>       14.248980376 seconds time elapsed
>           ( +-  0.29% )
>
>  Performance counter stats for './hackbench 50 process 4000' (20 runs):
>
>      113640.944855 task-clock                #    7.926 CPUs utilized
>           ( +-  0.28% )
>          2,776,983 context-switches          #    0.024 M/sec
>           ( +-  5.66% )
>             95,962 CPU-migrations            #    0.844 K/sec
>           ( +- 10.69% )
>            123,849 page-faults               #    0.001 M/sec
>           ( +-  0.15% )
>    420,446,572,595 cycles                    #    3.700 GHz
>           ( +-  0.28% )
>    <not supported> stalled-cycles-frontend
>    <not supported> stalled-cycles-backend
>    251,174,259,429 instructions              #    0.60  insns per
> cycle          ( +-  0.21% )
>     46,060,683,039 branches                  #  405.318 M/sec
>           ( +-  0.23% )
>        213,480,999 branch-misses             #    0.46% of all
> branches          ( +-  0.75% )
>
>       14.336843534 seconds time elapsed
>           ( +-  0.28% )

That doesn't seem like that obvious win to me... Eric, Christoph?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:08           ` Pekka Enberg
@ 2012-07-04 15:26             ` Eric Dumazet
  -1 siblings, 0 replies; 716+ messages in thread
From: Eric Dumazet @ 2012-07-04 15:26 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: JoonSoo Kim, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Wed, 2012-07-04 at 18:08 +0300, Pekka Enberg wrote:

> That doesn't seem like that obvious win to me... Eric, Christoph?

Its the slow path. I am not convinced its useful on real workloads (not
a benchmark)

I mean, if a workload hits badly slow path, some more important work
should be done to avoid this at a higher level.



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 15:26             ` Eric Dumazet
  0 siblings, 0 replies; 716+ messages in thread
From: Eric Dumazet @ 2012-07-04 15:26 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: JoonSoo Kim, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Wed, 2012-07-04 at 18:08 +0300, Pekka Enberg wrote:

> That doesn't seem like that obvious win to me... Eric, Christoph?

Its the slow path. I am not convinced its useful on real workloads (not
a benchmark)

I mean, if a workload hits badly slow path, some more important work
should be done to avoid this at a higher level.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:08           ` Pekka Enberg
@ 2012-07-04 15:45             ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 15:45 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

2012/7/5 Pekka Enberg <penberg@kernel.org>:
>> 2012/7/4 Pekka Enberg <penberg@kernel.org>:
>>> Well, can you show improvement in any benchmark or workload?
>>> Prefetching is not always an obvious win and the reason we merged
>>> Eric's patch was that he was able to show an improvement in hackbench.
>
> On Wed, Jul 4, 2012 at 5:30 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>> I thinks that this patch is perfectly same effect as Eric's patch, so
>> doesn't include benchmark result.
>> Eric's patch which add "prefetch instruction" in fastpath works for
>> second ~ last object of cpu slab.
>> This patch which add "prefetch instrunction" in slowpath works for
>> first object of cpu slab.
>
> Prefetching can also have negative effect on overall performance:
>
> http://lwn.net/Articles/444336/
>

Thanks for good article which is very helpful to me.

> That doesn't seem like that obvious win to me... Eric, Christoph?

Could you tell me how I test this patch more deeply, plz?
I am a kernel newbie and in the process of learning.
I doesn't know what I can do more for this.
I googling previous patch related to slub, some people use netperf.

Just do below is sufficient?
How is this test related to slub?

for in in `seq 1 32`
do
 netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
done
wait

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 15:45             ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 15:45 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

2012/7/5 Pekka Enberg <penberg@kernel.org>:
>> 2012/7/4 Pekka Enberg <penberg@kernel.org>:
>>> Well, can you show improvement in any benchmark or workload?
>>> Prefetching is not always an obvious win and the reason we merged
>>> Eric's patch was that he was able to show an improvement in hackbench.
>
> On Wed, Jul 4, 2012 at 5:30 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>> I thinks that this patch is perfectly same effect as Eric's patch, so
>> doesn't include benchmark result.
>> Eric's patch which add "prefetch instruction" in fastpath works for
>> second ~ last object of cpu slab.
>> This patch which add "prefetch instrunction" in slowpath works for
>> first object of cpu slab.
>
> Prefetching can also have negative effect on overall performance:
>
> http://lwn.net/Articles/444336/
>

Thanks for good article which is very helpful to me.

> That doesn't seem like that obvious win to me... Eric, Christoph?

Could you tell me how I test this patch more deeply, plz?
I am a kernel newbie and in the process of learning.
I doesn't know what I can do more for this.
I googling previous patch related to slub, some people use netperf.

Just do below is sufficient?
How is this test related to slub?

for in in `seq 1 32`
do
 netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
done
wait

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:26             ` Eric Dumazet
@ 2012-07-04 15:48               ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 15:48 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> Its the slow path. I am not convinced its useful on real workloads (not
> a benchmark)
>
> I mean, if a workload hits badly slow path, some more important work
> should be done to avoid this at a higher level.
>

In hackbench test, fast path allocation is about to 93%.
Is it insufficient?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 15:48               ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 15:48 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> Its the slow path. I am not convinced its useful on real workloads (not
> a benchmark)
>
> I mean, if a workload hits badly slow path, some more important work
> should be done to avoid this at a higher level.
>

In hackbench test, fast path allocation is about to 93%.
Is it insufficient?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:45             ` JoonSoo Kim
@ 2012-07-04 15:59               ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 15:59 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

On Wed, Jul 4, 2012 at 6:45 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>> Prefetching can also have negative effect on overall performance:
>>
>> http://lwn.net/Articles/444336/
>
> Thanks for good article which is very helpful to me.
>
>> That doesn't seem like that obvious win to me... Eric, Christoph?
>
> Could you tell me how I test this patch more deeply, plz?
> I am a kernel newbie and in the process of learning.
> I doesn't know what I can do more for this.
> I googling previous patch related to slub, some people use netperf.
>
> Just do below is sufficient?
> How is this test related to slub?
>
> for in in `seq 1 32`
> do
>  netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
> done
> wait

The networking subsystem is sensitive to slab allocator performance
which makes netperf an interesting benchmark, that's all.

As for slab benchmarking, you might want to look at what Mel Gorman
has done in the past:

https://lkml.org/lkml/2009/2/16/252

For something like prefetch optimization, you'd really want to see a
noticeable win in some benchmark. The kind of improvement you're
seeing with your patch is likely to be lost in the noise - or even
worse, cause negative performance for real world workloads.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 15:59               ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-07-04 15:59 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

On Wed, Jul 4, 2012 at 6:45 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>> Prefetching can also have negative effect on overall performance:
>>
>> http://lwn.net/Articles/444336/
>
> Thanks for good article which is very helpful to me.
>
>> That doesn't seem like that obvious win to me... Eric, Christoph?
>
> Could you tell me how I test this patch more deeply, plz?
> I am a kernel newbie and in the process of learning.
> I doesn't know what I can do more for this.
> I googling previous patch related to slub, some people use netperf.
>
> Just do below is sufficient?
> How is this test related to slub?
>
> for in in `seq 1 32`
> do
>  netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
> done
> wait

The networking subsystem is sensitive to slab allocator performance
which makes netperf an interesting benchmark, that's all.

As for slab benchmarking, you might want to look at what Mel Gorman
has done in the past:

https://lkml.org/lkml/2009/2/16/252

For something like prefetch optimization, you'd really want to see a
noticeable win in some benchmark. The kind of improvement you're
seeing with your patch is likely to be lost in the noise - or even
worse, cause negative performance for real world workloads.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:59               ` Pekka Enberg
@ 2012-07-04 16:04                 ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 16:04 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

2012/7/5 Pekka Enberg <penberg@kernel.org>:
> On Wed, Jul 4, 2012 at 6:45 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>>> Prefetching can also have negative effect on overall performance:
>>>
>>> http://lwn.net/Articles/444336/
>>
>> Thanks for good article which is very helpful to me.
>>
>>> That doesn't seem like that obvious win to me... Eric, Christoph?
>>
>> Could you tell me how I test this patch more deeply, plz?
>> I am a kernel newbie and in the process of learning.
>> I doesn't know what I can do more for this.
>> I googling previous patch related to slub, some people use netperf.
>>
>> Just do below is sufficient?
>> How is this test related to slub?
>>
>> for in in `seq 1 32`
>> do
>>  netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
>> done
>> wait
>
> The networking subsystem is sensitive to slab allocator performance
> which makes netperf an interesting benchmark, that's all.
>
> As for slab benchmarking, you might want to look at what Mel Gorman
> has done in the past:
>
> https://lkml.org/lkml/2009/2/16/252
>
> For something like prefetch optimization, you'd really want to see a
> noticeable win in some benchmark. The kind of improvement you're
> seeing with your patch is likely to be lost in the noise - or even
> worse, cause negative performance for real world workloads.

Okay.
Thanks for comments.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 16:04                 ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 16:04 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Christoph Lameter, linux-kernel, linux-mm, Eric Dumazet, David Rientjes

2012/7/5 Pekka Enberg <penberg@kernel.org>:
> On Wed, Jul 4, 2012 at 6:45 PM, JoonSoo Kim <js1304@gmail.com> wrote:
>>> Prefetching can also have negative effect on overall performance:
>>>
>>> http://lwn.net/Articles/444336/
>>
>> Thanks for good article which is very helpful to me.
>>
>>> That doesn't seem like that obvious win to me... Eric, Christoph?
>>
>> Could you tell me how I test this patch more deeply, plz?
>> I am a kernel newbie and in the process of learning.
>> I doesn't know what I can do more for this.
>> I googling previous patch related to slub, some people use netperf.
>>
>> Just do below is sufficient?
>> How is this test related to slub?
>>
>> for in in `seq 1 32`
>> do
>>  netperf -H 192.168.0.8 -v 0 -l -100000 -t TCP_RR > /dev/null &
>> done
>> wait
>
> The networking subsystem is sensitive to slab allocator performance
> which makes netperf an interesting benchmark, that's all.
>
> As for slab benchmarking, you might want to look at what Mel Gorman
> has done in the past:
>
> https://lkml.org/lkml/2009/2/16/252
>
> For something like prefetch optimization, you'd really want to see a
> noticeable win in some benchmark. The kind of improvement you're
> seeing with your patch is likely to be lost in the noise - or even
> worse, cause negative performance for real world workloads.

Okay.
Thanks for comments.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 15:48               ` JoonSoo Kim
@ 2012-07-04 16:15                 ` Eric Dumazet
  -1 siblings, 0 replies; 716+ messages in thread
From: Eric Dumazet @ 2012-07-04 16:15 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Thu, 2012-07-05 at 00:48 +0900, JoonSoo Kim wrote:
> 2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> > Its the slow path. I am not convinced its useful on real workloads (not
> > a benchmark)
> >
> > I mean, if a workload hits badly slow path, some more important work
> > should be done to avoid this at a higher level.
> >
> 
> In hackbench test, fast path allocation is about to 93%.
> Is it insufficient?

7% is insufficient I am afraid.

One prefetch() in the fast path serves 93% of the allocations,
so added icache pressure is ok.

One prefetch() in slow path serves 7% of the allocations, do you see the
difference ?

Adding a prefetch() is usually a win when a benchmark uses the path one
million times per second.

But adding prefetches also increases kernel size and it hurts globally.
(Latency of the kernel depends on its size, when cpu caches are cold)




^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 16:15                 ` Eric Dumazet
  0 siblings, 0 replies; 716+ messages in thread
From: Eric Dumazet @ 2012-07-04 16:15 UTC (permalink / raw)
  To: JoonSoo Kim
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

On Thu, 2012-07-05 at 00:48 +0900, JoonSoo Kim wrote:
> 2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> > Its the slow path. I am not convinced its useful on real workloads (not
> > a benchmark)
> >
> > I mean, if a workload hits badly slow path, some more important work
> > should be done to avoid this at a higher level.
> >
> 
> In hackbench test, fast path allocation is about to 93%.
> Is it insufficient?

7% is insufficient I am afraid.

One prefetch() in the fast path serves 93% of the allocations,
so added icache pressure is ok.

One prefetch() in slow path serves 7% of the allocations, do you see the
difference ?

Adding a prefetch() is usually a win when a benchmark uses the path one
million times per second.

But adding prefetches also increases kernel size and it hurts globally.
(Latency of the kernel depends on its size, when cpu caches are cold)



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
  2012-07-04 16:15                 ` Eric Dumazet
@ 2012-07-04 16:24                   ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 16:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> On Thu, 2012-07-05 at 00:48 +0900, JoonSoo Kim wrote:
>> 2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
>> > Its the slow path. I am not convinced its useful on real workloads (not
>> > a benchmark)
>> >
>> > I mean, if a workload hits badly slow path, some more important work
>> > should be done to avoid this at a higher level.
>> >
>>
>> In hackbench test, fast path allocation is about to 93%.
>> Is it insufficient?
>
> 7% is insufficient I am afraid.
>
> One prefetch() in the fast path serves 93% of the allocations,
> so added icache pressure is ok.
>
> One prefetch() in slow path serves 7% of the allocations, do you see the
> difference ?
>
> Adding a prefetch() is usually a win when a benchmark uses the path one
> million times per second.
>
> But adding prefetches also increases kernel size and it hurts globally.
> (Latency of the kernel depends on its size, when cpu caches are cold)
>

Okay.
Thanks for comments which is very helpful to me.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc()
@ 2012-07-04 16:24                   ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-04 16:24 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Pekka Enberg, Christoph Lameter, linux-kernel, linux-mm, David Rientjes

2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
> On Thu, 2012-07-05 at 00:48 +0900, JoonSoo Kim wrote:
>> 2012/7/5 Eric Dumazet <eric.dumazet@gmail.com>:
>> > Its the slow path. I am not convinced its useful on real workloads (not
>> > a benchmark)
>> >
>> > I mean, if a workload hits badly slow path, some more important work
>> > should be done to avoid this at a higher level.
>> >
>>
>> In hackbench test, fast path allocation is about to 93%.
>> Is it insufficient?
>
> 7% is insufficient I am afraid.
>
> One prefetch() in the fast path serves 93% of the allocations,
> so added icache pressure is ok.
>
> One prefetch() in slow path serves 7% of the allocations, do you see the
> difference ?
>
> Adding a prefetch() is usually a win when a benchmark uses the path one
> million times per second.
>
> But adding prefetches also increases kernel size and it hurts globally.
> (Latency of the kernel depends on its size, when cpu caches are cold)
>

Okay.
Thanks for comments which is very helpful to me.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
  2012-07-04 13:05       ` Pekka Enberg
@ 2012-07-05 14:20         ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-05 14:20 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Joonsoo Kim, linux-kernel, linux-mm, David Rientjes

On Wed, 4 Jul 2012, Pekka Enberg wrote:

> On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> > In current implementation, after unfreezing, we doesn't touch oldpage,
> > so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> > with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
> >
> > We can change value of oldpage to NULL after unfreezing,
> > because unfreeze_partial() ensure that all the cpu partial slabs is removed
> > from cpu partial list. In this time, we could expect that
> > this_cpu_cmpxchg is mostly succeed.
> >
> > Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> >
> > diff --git a/mm/slub.c b/mm/slub.c
> > index 92f1c0e..531d8ed 100644
> > --- a/mm/slub.c
> > +++ b/mm/slub.c
> > @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
> >                                 local_irq_save(flags);
> >                                 unfreeze_partials(s);
> >                                 local_irq_restore(flags);
> > +                               oldpage = NULL;
> >                                 pobjects = 0;
> >                                 pages = 0;
> >                                 stat(s, CPU_PARTIAL_DRAIN);
>
> Makes sense. Christoph, David?

Acked-by: Christoph Lameter <cl@linux.com>


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
@ 2012-07-05 14:20         ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-05 14:20 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: Joonsoo Kim, linux-kernel, linux-mm, David Rientjes

On Wed, 4 Jul 2012, Pekka Enberg wrote:

> On Fri, Jun 22, 2012 at 9:22 PM, Joonsoo Kim <js1304@gmail.com> wrote:
> > In current implementation, after unfreezing, we doesn't touch oldpage,
> > so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> > with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
> >
> > We can change value of oldpage to NULL after unfreezing,
> > because unfreeze_partial() ensure that all the cpu partial slabs is removed
> > from cpu partial list. In this time, we could expect that
> > this_cpu_cmpxchg is mostly succeed.
> >
> > Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> >
> > diff --git a/mm/slub.c b/mm/slub.c
> > index 92f1c0e..531d8ed 100644
> > --- a/mm/slub.c
> > +++ b/mm/slub.c
> > @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
> >                                 local_irq_save(flags);
> >                                 unfreeze_partials(s);
> >                                 local_irq_restore(flags);
> > +                               oldpage = NULL;
> >                                 pobjects = 0;
> >                                 pages = 0;
> >                                 stat(s, CPU_PARTIAL_DRAIN);
>
> Makes sense. Christoph, David?

Acked-by: Christoph Lameter <cl@linux.com>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-06-22 18:22     ` Joonsoo Kim
@ 2012-07-05 14:26       ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-05 14:26 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 23 Jun 2012, Joonsoo Kim wrote:

> In some case of __slab_free(), we need a lock for manipulating partial list.
> If freeing object with a lock is failed, a lock doesn't needed anymore
> for some reasons.
>
> Case 1. prior is NULL, kmem_cache_debug(s) is true
>
> In this case, another free is occured before our free is succeed.
> When slab is full(prior is NULL), only possible operation is slab_free().
> So in this case, we guess another free is occured.
> It may make a slab frozen, so lock is not needed anymore.

A free cannot freeze the slab without taking the lock. The taken lock
makes sure that the thread that first enters slab_free() will be able to
hold back the thread that wants to freeze the slab.

> Case 2. inuse is NULL
>
> In this case, acquire_slab() is occured before out free is succeed.
> We have a last object for slab, so other operation for this slab is
> not possible except acquire_slab().
> Acquire_slab() makes a slab frozen, so lock is not needed anymore.

acquire_slab() also requires lock acquisition and would be held of by
slab_free holding the lock.

> This also make logic somehow simple that 'was_frozen with a lock' case
> is never occured. Remove it.

That is actually interesting and would be a good optimization.


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-05 14:26       ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-05 14:26 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Sat, 23 Jun 2012, Joonsoo Kim wrote:

> In some case of __slab_free(), we need a lock for manipulating partial list.
> If freeing object with a lock is failed, a lock doesn't needed anymore
> for some reasons.
>
> Case 1. prior is NULL, kmem_cache_debug(s) is true
>
> In this case, another free is occured before our free is succeed.
> When slab is full(prior is NULL), only possible operation is slab_free().
> So in this case, we guess another free is occured.
> It may make a slab frozen, so lock is not needed anymore.

A free cannot freeze the slab without taking the lock. The taken lock
makes sure that the thread that first enters slab_free() will be able to
hold back the thread that wants to freeze the slab.

> Case 2. inuse is NULL
>
> In this case, acquire_slab() is occured before out free is succeed.
> We have a last object for slab, so other operation for this slab is
> not possible except acquire_slab().
> Acquire_slab() makes a slab frozen, so lock is not needed anymore.

acquire_slab() also requires lock acquisition and would be held of by
slab_free holding the lock.

> This also make logic somehow simple that 'was_frozen with a lock' case
> is never occured. Remove it.

That is actually interesting and would be a good optimization.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-05 14:26       ` Christoph Lameter
@ 2012-07-06 14:19         ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-06 14:19 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/5 Christoph Lameter <cl@linux.com>:
> On Sat, 23 Jun 2012, Joonsoo Kim wrote:
>
>> In some case of __slab_free(), we need a lock for manipulating partial list.
>> If freeing object with a lock is failed, a lock doesn't needed anymore
>> for some reasons.
>>
>> Case 1. prior is NULL, kmem_cache_debug(s) is true
>>
>> In this case, another free is occured before our free is succeed.
>> When slab is full(prior is NULL), only possible operation is slab_free().
>> So in this case, we guess another free is occured.
>> It may make a slab frozen, so lock is not needed anymore.
>
> A free cannot freeze the slab without taking the lock. The taken lock
> makes sure that the thread that first enters slab_free() will be able to
> hold back the thread that wants to freeze the slab.

I don't mean we can freeze the slab without taking the lock.
We can fail cmpxchg_double_slab with taking the lock.
And in this case, we don't need lock anymore, so let's release lock.

For example,
When we try to free object A at cpu 1, another process try to free
object B at cpu 2 at the same time.
object A, B is in same slab, and this slab is in full list.

CPU 1                           CPU 2
prior = page->freelist;    prior = page->freelist
....                                  ...
new.inuse--;                   new.inuse--;
taking lock                      try to take the lock, but failed, so
spinning...
free success                   spinning...
add_partial
release lock                    taking lock
                                       fail cmpxchg_double_slab
                                       retry
                                       currently, we don't need lock

At CPU2, we don't need lock anymore, because this slab already in partial list.

Case 2 is similar as case 1.
So skip explain.

Case 1, 2 in commit message explain almost retry case with taking lock.
So, below is reasonable.

@@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s,
struct page *page,
                return;

        do {
+               if (unlikely(n)) {
+                       spin_unlock_irqrestore(&n->list_lock, flags);
+                       n = NULL;
+               }
                prior = page->freelist;
                counters = page->counters;
                set_freepointer(s, object, prior);


>> Case 2. inuse is NULL
>>
>> In this case, acquire_slab() is occured before out free is succeed.
>> We have a last object for slab, so other operation for this slab is
>> not possible except acquire_slab().
>> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>
> acquire_slab() also requires lock acquisition and would be held of by
> slab_free holding the lock.

See above explain.

>> This also make logic somehow simple that 'was_frozen with a lock' case
>> is never occured. Remove it.
>
> That is actually interesting and would be a good optimization.
>

So, I think patch is valid.
Thanks for comments.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-06 14:19         ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-06 14:19 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/5 Christoph Lameter <cl@linux.com>:
> On Sat, 23 Jun 2012, Joonsoo Kim wrote:
>
>> In some case of __slab_free(), we need a lock for manipulating partial list.
>> If freeing object with a lock is failed, a lock doesn't needed anymore
>> for some reasons.
>>
>> Case 1. prior is NULL, kmem_cache_debug(s) is true
>>
>> In this case, another free is occured before our free is succeed.
>> When slab is full(prior is NULL), only possible operation is slab_free().
>> So in this case, we guess another free is occured.
>> It may make a slab frozen, so lock is not needed anymore.
>
> A free cannot freeze the slab without taking the lock. The taken lock
> makes sure that the thread that first enters slab_free() will be able to
> hold back the thread that wants to freeze the slab.

I don't mean we can freeze the slab without taking the lock.
We can fail cmpxchg_double_slab with taking the lock.
And in this case, we don't need lock anymore, so let's release lock.

For example,
When we try to free object A at cpu 1, another process try to free
object B at cpu 2 at the same time.
object A, B is in same slab, and this slab is in full list.

CPU 1                           CPU 2
prior = page->freelist;    prior = page->freelist
....                                  ...
new.inuse--;                   new.inuse--;
taking lock                      try to take the lock, but failed, so
spinning...
free success                   spinning...
add_partial
release lock                    taking lock
                                       fail cmpxchg_double_slab
                                       retry
                                       currently, we don't need lock

At CPU2, we don't need lock anymore, because this slab already in partial list.

Case 2 is similar as case 1.
So skip explain.

Case 1, 2 in commit message explain almost retry case with taking lock.
So, below is reasonable.

@@ -2450,13 +2449,17 @@ static void __slab_free(struct kmem_cache *s,
struct page *page,
                return;

        do {
+               if (unlikely(n)) {
+                       spin_unlock_irqrestore(&n->list_lock, flags);
+                       n = NULL;
+               }
                prior = page->freelist;
                counters = page->counters;
                set_freepointer(s, object, prior);


>> Case 2. inuse is NULL
>>
>> In this case, acquire_slab() is occured before out free is succeed.
>> We have a last object for slab, so other operation for this slab is
>> not possible except acquire_slab().
>> Acquire_slab() makes a slab frozen, so lock is not needed anymore.
>
> acquire_slab() also requires lock acquisition and would be held of by
> slab_free holding the lock.

See above explain.

>> This also make logic somehow simple that 'was_frozen with a lock' case
>> is never occured. Remove it.
>
> That is actually interesting and would be a good optimization.
>

So, I think patch is valid.
Thanks for comments.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-06 14:19         ` JoonSoo Kim
@ 2012-07-06 14:34           ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-06 14:34 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Fri, 6 Jul 2012, JoonSoo Kim wrote:

> For example,
> When we try to free object A at cpu 1, another process try to free
> object B at cpu 2 at the same time.
> object A, B is in same slab, and this slab is in full list.
>
> CPU 1                           CPU 2
> prior = page->freelist;    prior = page->freelist
> ....                                  ...
> new.inuse--;                   new.inuse--;
> taking lock                      try to take the lock, but failed, so
> spinning...
> free success                   spinning...
> add_partial
> release lock                    taking lock
>                                        fail cmpxchg_double_slab
>                                        retry
>                                        currently, we don't need lock
>
> At CPU2, we don't need lock anymore, because this slab already in partial list.

For that scenario we could also simply do a trylock there and redo
the loop if we fail. But still what guarantees that another process will
not modify the page struct between fetching the data and a successful
trylock?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-06 14:34           ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-06 14:34 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Fri, 6 Jul 2012, JoonSoo Kim wrote:

> For example,
> When we try to free object A at cpu 1, another process try to free
> object B at cpu 2 at the same time.
> object A, B is in same slab, and this slab is in full list.
>
> CPU 1                           CPU 2
> prior = page->freelist;    prior = page->freelist
> ....                                  ...
> new.inuse--;                   new.inuse--;
> taking lock                      try to take the lock, but failed, so
> spinning...
> free success                   spinning...
> add_partial
> release lock                    taking lock
>                                        fail cmpxchg_double_slab
>                                        retry
>                                        currently, we don't need lock
>
> At CPU2, we don't need lock anymore, because this slab already in partial list.

For that scenario we could also simply do a trylock there and redo
the loop if we fail. But still what guarantees that another process will
not modify the page struct between fetching the data and a successful
trylock?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-06 14:34           ` Christoph Lameter
@ 2012-07-06 14:59             ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-06 14:59 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/6 Christoph Lameter <cl@linux.com>:
> On Fri, 6 Jul 2012, JoonSoo Kim wrote:
>
>> For example,
>> When we try to free object A at cpu 1, another process try to free
>> object B at cpu 2 at the same time.
>> object A, B is in same slab, and this slab is in full list.
>>
>> CPU 1                           CPU 2
>> prior = page->freelist;    prior = page->freelist
>> ....                                  ...
>> new.inuse--;                   new.inuse--;
>> taking lock                      try to take the lock, but failed, so
>> spinning...
>> free success                   spinning...
>> add_partial
>> release lock                    taking lock
>>                                        fail cmpxchg_double_slab
>>                                        retry
>>                                        currently, we don't need lock
>>
>> At CPU2, we don't need lock anymore, because this slab already in partial list.
>
> For that scenario we could also simply do a trylock there and redo
> the loop if we fail. But still what guarantees that another process will
> not modify the page struct between fetching the data and a successful
> trylock?


I'm not familiar with English, so take my ability to understand into
consideration.

we don't need guarantees that another process will not modify
the page struct between fetching the data and a successful trylock.

As I understand, do u ask below scenario?

CPU A               CPU B
lock
cmpxchg fail
retry
unlock
...                       modify page strcut
...
cmpxchg~~

In this case, cmpxchg will fail and just redo the loop.
If we need the lock again during redo, re-take the lock.
But I think this is not common case.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-06 14:59             ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-06 14:59 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/6 Christoph Lameter <cl@linux.com>:
> On Fri, 6 Jul 2012, JoonSoo Kim wrote:
>
>> For example,
>> When we try to free object A at cpu 1, another process try to free
>> object B at cpu 2 at the same time.
>> object A, B is in same slab, and this slab is in full list.
>>
>> CPU 1                           CPU 2
>> prior = page->freelist;    prior = page->freelist
>> ....                                  ...
>> new.inuse--;                   new.inuse--;
>> taking lock                      try to take the lock, but failed, so
>> spinning...
>> free success                   spinning...
>> add_partial
>> release lock                    taking lock
>>                                        fail cmpxchg_double_slab
>>                                        retry
>>                                        currently, we don't need lock
>>
>> At CPU2, we don't need lock anymore, because this slab already in partial list.
>
> For that scenario we could also simply do a trylock there and redo
> the loop if we fail. But still what guarantees that another process will
> not modify the page struct between fetching the data and a successful
> trylock?


I'm not familiar with English, so take my ability to understand into
consideration.

we don't need guarantees that another process will not modify
the page struct between fetching the data and a successful trylock.

As I understand, do u ask below scenario?

CPU A               CPU B
lock
cmpxchg fail
retry
unlock
...                       modify page strcut
...
cmpxchg~~

In this case, cmpxchg will fail and just redo the loop.
If we need the lock again during redo, re-take the lock.
But I think this is not common case.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-06 14:59             ` JoonSoo Kim
@ 2012-07-06 15:10               ` Christoph Lameter
  -1 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-06 15:10 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Fri, 6 Jul 2012, JoonSoo Kim wrote:

> >> At CPU2, we don't need lock anymore, because this slab already in partial list.
> >
> > For that scenario we could also simply do a trylock there and redo
> > the loop if we fail. But still what guarantees that another process will
> > not modify the page struct between fetching the data and a successful
> > trylock?
>
>
> I'm not familiar with English, so take my ability to understand into
> consideration.

I have a hard time understanding what you want to accomplish here.

> we don't need guarantees that another process will not modify
> the page struct between fetching the data and a successful trylock.

No we do not need that since the cmpxchg will then fail.

Maybe it would be useful to split this patch into two?

One where you introduce the dropping of the lock and the other where you
get rid of certain code paths?


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-06 15:10               ` Christoph Lameter
  0 siblings, 0 replies; 716+ messages in thread
From: Christoph Lameter @ 2012-07-06 15:10 UTC (permalink / raw)
  To: JoonSoo Kim; +Cc: Pekka Enberg, linux-kernel, linux-mm

On Fri, 6 Jul 2012, JoonSoo Kim wrote:

> >> At CPU2, we don't need lock anymore, because this slab already in partial list.
> >
> > For that scenario we could also simply do a trylock there and redo
> > the loop if we fail. But still what guarantees that another process will
> > not modify the page struct between fetching the data and a successful
> > trylock?
>
>
> I'm not familiar with English, so take my ability to understand into
> consideration.

I have a hard time understanding what you want to accomplish here.

> we don't need guarantees that another process will not modify
> the page struct between fetching the data and a successful trylock.

No we do not need that since the cmpxchg will then fail.

Maybe it would be useful to split this patch into two?

One where you introduce the dropping of the lock and the other where you
get rid of certain code paths?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
  2012-07-06 15:10               ` Christoph Lameter
@ 2012-07-08 16:19                 ` JoonSoo Kim
  -1 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-08 16:19 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/7 Christoph Lameter <cl@linux.com>:
> On Fri, 6 Jul 2012, JoonSoo Kim wrote:
>
>> >> At CPU2, we don't need lock anymore, because this slab already in partial list.
>> >
>> > For that scenario we could also simply do a trylock there and redo
>> > the loop if we fail. But still what guarantees that another process will
>> > not modify the page struct between fetching the data and a successful
>> > trylock?
>>
>>
>> I'm not familiar with English, so take my ability to understand into
>> consideration.
>
> I have a hard time understanding what you want to accomplish here.
>
>> we don't need guarantees that another process will not modify
>> the page struct between fetching the data and a successful trylock.
>
> No we do not need that since the cmpxchg will then fail.
>
> Maybe it would be useful to split this patch into two?
>
> One where you introduce the dropping of the lock and the other where you
> get rid of certain code paths?
>

Dropping of the lock is need for getting rid of certain code paths.
So, I can't split this patch into two.

Sorry for confusing all the people.
I think that I don't explain my purpose well.
I will prepare new version in which I explain purpose of patch better.

Thanks for kind review.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free()
@ 2012-07-08 16:19                 ` JoonSoo Kim
  0 siblings, 0 replies; 716+ messages in thread
From: JoonSoo Kim @ 2012-07-08 16:19 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: Pekka Enberg, linux-kernel, linux-mm

2012/7/7 Christoph Lameter <cl@linux.com>:
> On Fri, 6 Jul 2012, JoonSoo Kim wrote:
>
>> >> At CPU2, we don't need lock anymore, because this slab already in partial list.
>> >
>> > For that scenario we could also simply do a trylock there and redo
>> > the loop if we fail. But still what guarantees that another process will
>> > not modify the page struct between fetching the data and a successful
>> > trylock?
>>
>>
>> I'm not familiar with English, so take my ability to understand into
>> consideration.
>
> I have a hard time understanding what you want to accomplish here.
>
>> we don't need guarantees that another process will not modify
>> the page struct between fetching the data and a successful trylock.
>
> No we do not need that since the cmpxchg will then fail.
>
> Maybe it would be useful to split this patch into two?
>
> One where you introduce the dropping of the lock and the other where you
> get rid of certain code paths?
>

Dropping of the lock is need for getting rid of certain code paths.
So, I can't split this patch into two.

Sorry for confusing all the people.
I think that I don't explain my purpose well.
I will prepare new version in which I explain purpose of patch better.

Thanks for kind review.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing
       [not found] <yes>
                   ` (61 preceding siblings ...)
  2012-06-22 18:22   ` Joonsoo Kim
@ 2012-08-10  9:35 ` Vani-dineshbhai PATEL
  2012-08-13 11:27   ` Luiz Augusto von Dentz
  2012-09-20  7:28 ` [PATCH] mac80211 : Fix Ibss debug message Tx authentication yes
                   ` (28 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Vani-dineshbhai PATEL @ 2012-08-10  9:35 UTC (permalink / raw)
  To: User Name, Luiz Augusto; +Cc: Vani, Joohi, Vani

From: Vani Patel <vani.patel@stericsson.com>

Adds SDP record to support browsing
---
 audio/avctp.c |    4 ++--
 audio/avctp.h |    3 ++-
 audio/avrcp.c |   25 +++++++++++++++++++++----
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index 074eabd..a20dba9 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -802,7 +802,7 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
 	io = bt_io_listen(BT_IO_L2CAP, NULL, avctp_confirm_cb, NULL,
 				NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, src,
-				BT_IO_OPT_PSM, AVCTP_PSM,
+				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 				BT_IO_OPT_MASTER, master,
 				BT_IO_OPT_INVALID);
@@ -1090,7 +1090,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 	io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, session, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
 				BT_IO_OPT_DEST_BDADDR, &session->dst,
-				BT_IO_OPT_PSM, AVCTP_PSM,
+				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
 				BT_IO_OPT_INVALID);
 	if (err) {
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
diff --git a/audio/avctp.h b/audio/avctp.h
index d0cbd97..34b0c1c 100644
--- a/audio/avctp.h
+++ b/audio/avctp.h
@@ -22,7 +22,8 @@
  *
  */
 
-#define AVCTP_PSM 23
+#define AVCTP_CONTROL_PSM	23
+#define AVCTP_BROWSING_PSM	27
 
 #define AVC_MTU 512
 #define AVC_HEADER_LENGTH 3
diff --git a/audio/avrcp.c b/audio/avrcp.c
index d925365..ca40c1e 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -190,7 +190,7 @@ static sdp_record_t *avrcp_ct_record(void)
 	sdp_list_t *aproto, *proto[2];
 	sdp_record_t *record;
 	sdp_data_t *psm, *version, *features;
-	uint16_t lp = AVCTP_PSM;
+	uint16_t lp = AVCTP_CONTROL_PSM;
 	uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
 	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
 						AVRCP_FEATURE_CATEGORY_2 |
@@ -252,13 +252,15 @@ static sdp_record_t *avrcp_ct_record(void)
 
 static sdp_record_t *avrcp_tg_record(void)
 {
-	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
 	uuid_t root_uuid, l2cap, avctp, avrtg;
 	sdp_profile_desc_t profile[1];
 	sdp_list_t *aproto, *proto[2];
 	sdp_record_t *record;
-	sdp_data_t *psm, *version, *features;
-	uint16_t lp = AVCTP_PSM;
+	sdp_data_t *psm, *version, *features, *psm_browsing;
+	sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
+	uint16_t lp = AVCTP_CONTROL_PSM;
+	uint16_t lp_browsing = AVCTP_BROWSING_PSM;
 	uint16_t avrcp_ver = 0x0104, avctp_ver = 0x0103;
 	uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
 					AVRCP_FEATURE_CATEGORY_2 |
@@ -294,6 +296,17 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	aproto = sdp_list_append(0, apseq);
 	sdp_set_access_protos(record, aproto);
+	proto_browsing[0] = sdp_list_append(0, &l2cap);
+	psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
+	proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
+	apseq_browsing = sdp_list_append(0, proto_browsing[0]);
+
+	proto_browsing[1] = sdp_list_append(0, &avctp);
+	proto_browsing[1] = sdp_list_append(proto_browsing[1], version);
+	apseq_browsing = sdp_list_append(apseq_browsing, proto_browsing[1]);
+
+	aproto_browsing = sdp_list_append(0, apseq_browsing);
+	sdp_set_add_access_protos(record, aproto_browsing);
 
 	/* Bluetooth Profile Descriptor List */
 	sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
@@ -306,6 +319,10 @@ static sdp_record_t *avrcp_tg_record(void)
 
 	sdp_set_info_attr(record, "AVRCP TG", 0, 0);
 
+	free(psm_browsing);
+	sdp_list_free(proto_browsing[0], 0);
+	sdp_list_free(proto_browsing[1], 0);
+	sdp_list_free(aproto_browsing, 0);
 	free(psm);
 	free(version);
 	sdp_list_free(proto[0], 0);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing
  2012-08-10  9:35 ` [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing Vani-dineshbhai PATEL
@ 2012-08-13 11:27   ` Luiz Augusto von Dentz
  2012-08-13 11:49     ` Michal.Labedzki
  0 siblings, 1 reply; 716+ messages in thread
From: Luiz Augusto von Dentz @ 2012-08-13 11:27 UTC (permalink / raw)
  To: Vani-dineshbhai PATEL; +Cc: User Name, Joohi, Vani

Hi Vani,

On Fri, Aug 10, 2012 at 12:35 PM, Vani-dineshbhai PATEL
<vani.patel@stericsson.com> wrote:
> From: Vani Patel <vani.patel@stericsson.com>
>
> Adds SDP record to support browsing
> ---
>  audio/avctp.c |    4 ++--
>  audio/avctp.h |    3 ++-
>  audio/avrcp.c |   25 +++++++++++++++++++++----
>  3 files changed, 25 insertions(+), 7 deletions(-)
>
> diff --git a/audio/avctp.c b/audio/avctp.c
> index 074eabd..a20dba9 100644
> --- a/audio/avctp.c
> +++ b/audio/avctp.c
> @@ -802,7 +802,7 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
>         io = bt_io_listen(BT_IO_L2CAP, NULL, avctp_confirm_cb, NULL,
>                                 NULL, &err,
>                                 BT_IO_OPT_SOURCE_BDADDR, src,
> -                               BT_IO_OPT_PSM, AVCTP_PSM,
> +                               BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
>                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
>                                 BT_IO_OPT_MASTER, master,
>                                 BT_IO_OPT_INVALID);
> @@ -1090,7 +1090,7 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
>         io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, session, NULL, &err,
>                                 BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
>                                 BT_IO_OPT_DEST_BDADDR, &session->dst,
> -                               BT_IO_OPT_PSM, AVCTP_PSM,
> +                               BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
>                                 BT_IO_OPT_INVALID);
>         if (err) {
>                 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
> diff --git a/audio/avctp.h b/audio/avctp.h
> index d0cbd97..34b0c1c 100644
> --- a/audio/avctp.h
> +++ b/audio/avctp.h
> @@ -22,7 +22,8 @@
>   *
>   */
>
> -#define AVCTP_PSM 23
> +#define AVCTP_CONTROL_PSM      23
> +#define AVCTP_BROWSING_PSM     27
>
>  #define AVC_MTU 512
>  #define AVC_HEADER_LENGTH 3
> diff --git a/audio/avrcp.c b/audio/avrcp.c
> index d925365..ca40c1e 100644
> --- a/audio/avrcp.c
> +++ b/audio/avrcp.c
> @@ -190,7 +190,7 @@ static sdp_record_t *avrcp_ct_record(void)
>         sdp_list_t *aproto, *proto[2];
>         sdp_record_t *record;
>         sdp_data_t *psm, *version, *features;
> -       uint16_t lp = AVCTP_PSM;
> +       uint16_t lp = AVCTP_CONTROL_PSM;
>         uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>                                                 AVRCP_FEATURE_CATEGORY_2 |
> @@ -252,13 +252,15 @@ static sdp_record_t *avrcp_ct_record(void)
>
>  static sdp_record_t *avrcp_tg_record(void)
>  {
> -       sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> +       sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
>         uuid_t root_uuid, l2cap, avctp, avrtg;
>         sdp_profile_desc_t profile[1];
>         sdp_list_t *aproto, *proto[2];
>         sdp_record_t *record;
> -       sdp_data_t *psm, *version, *features;
> -       uint16_t lp = AVCTP_PSM;
> +       sdp_data_t *psm, *version, *features, *psm_browsing;
> +       sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
> +       uint16_t lp = AVCTP_CONTROL_PSM;
> +       uint16_t lp_browsing = AVCTP_BROWSING_PSM;
>         uint16_t avrcp_ver = 0x0104, avctp_ver = 0x0103;
>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>                                         AVRCP_FEATURE_CATEGORY_2 |

According to the spec if we register the browsing channel we should
set it in feature bits, btw apparently apseq_browsing is leaking
please make sure you run your patches with valgrind/gdb to catch this
type of errors.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing
  2012-08-13 11:27   ` Luiz Augusto von Dentz
@ 2012-08-13 11:49     ` Michal.Labedzki
  2012-08-13 12:15       ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 716+ messages in thread
From: Michal.Labedzki @ 2012-08-13 11:49 UTC (permalink / raw)
  To: luiz.dentz, vani.patel; +Cc: linux-bluetooth, Joohi.rastogi, vani273

Hi Luiz,


>> diff --git a/audio/avrcp.c b/audio/avrcp.c
>> index d925365..ca40c1e 100644
>> --- a/audio/avrcp.c
> +++ b/audio/avrcp.c
>> @@ -190,7 +190,7 @@ static sdp_record_t *avrcp_ct_record(void)
>>         sdp_list_t *aproto, *proto[2];
>>         sdp_record_t *record;
>>         sdp_data_t *psm, *version, *features;
>> -       uint16_t lp = AVCTP_PSM;
>> +       uint16_t lp = AVCTP_CONTROL_PSM;
>>         uint16_t avrcp_ver = 0x0100, avctp_ver = 0x0103;
>>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>>                                                 AVRCP_FEATURE_CATEGORY_2 |
>> @@ -252,13 +252,15 @@ static sdp_record_t *avrcp_ct_record(void)
>>
>>  static sdp_record_t *avrcp_tg_record(void)
>>  {
>> -       sdp_list_t *svclass_id, *pfseq, *apseq, *root;
> +       sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
>>         uuid_t root_uuid, l2cap, avctp, avrtg;
>>         sdp_profile_desc_t profile[1];
>>         sdp_list_t *aproto, *proto[2];
>>         sdp_record_t *record;
>> -       sdp_data_t *psm, *version, *features;
>> -       uint16_t lp = AVCTP_PSM;
>> +       sdp_data_t *psm, *version, *features, *psm_browsing;
>> +       sdp_list_t *aproto_browsing, *proto_browsing[2] = {0};
>> +       uint16_t lp = AVCTP_CONTROL_PSM;
>> +       uint16_t lp_browsing = AVCTP_BROWSING_PSM;
>>         uint16_t avrcp_ver = 0x0104, avctp_ver = 0x0103;
>>         uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
>>                                         AVRCP_FEATURE_CATEGORY_2 |

>According to the spec if we register the browsing channel we should
>set it in feature bits, btw apparently apseq_browsing is leaking
>please make sure you run your patches with valgrind/gdb to catch this
>type of errors.
>
>--
>Luiz Augusto von Dentz

According to the specification we should not expose browsing in feature bits:
"*4: Bit 6 (Browsing supported) is not set based on category. Bit 6 in the SDP record shall only be set if
browsing of the "Media Player Virtual Filesystem" is supported."

So no GetFolderItems on VFS scope - no browsing.


Regards / Pozdrawiam
-------------------------------------------------------------------------------------------------------------
Michał Łabędzki
ASCII: Michal Labedzki
e-mail: michal.labedzki@tieto.com
office communicator: michal.labedzki@tieto.com
location: Poland, Wrocław, Legnicka 55F
room: 420
phone: +48 717 740 340
---
Tieto Corporation / Tieto Poland
http://www.tieto.com / http://www.tieto.pl
---
Tieto Poland spółka z ograniczoną odpowiedzialnością z siedzibą w Szczecinie, ul. Malczewskiego 26. Zarejestrowana w Sądzie Rejonowym Szczecin-Centrum w Szczecinie, XIII Wydział Gospodarczy Krajowego Rejestru Sądowego pod numerem 0000124858. NIP: 8542085557. REGON: 812023656. Kapitał zakładowy: 4 271500 PLN
________________________________________


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing
  2012-08-13 11:49     ` Michal.Labedzki
@ 2012-08-13 12:15       ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 716+ messages in thread
From: Luiz Augusto von Dentz @ 2012-08-13 12:15 UTC (permalink / raw)
  To: Michal.Labedzki; +Cc: vani.patel, linux-bluetooth, Joohi.rastogi, vani273

Hi Michal,

On Mon, Aug 13, 2012 at 2:49 PM,  <Michal.Labedzki@tieto.com> wrote:
> According to the specification we should not expose browsing in feature bits:
> "*4: Bit 6 (Browsing supported) is not set based on category. Bit 6 in the SDP record shall only be set if
> browsing of the "Media Player Virtual Filesystem" is supported."
>
> So no GetFolderItems on VFS scope - no browsing.

Well since SDP actually rely on the player to support that feature so
we might actually make it always be set and if the player doesn't
support we return an error or empty list. The spec itself states that
PlayerFeatureBitmask should be used instead, so the way I interpreted
it is that Bit 6 is there to tell if the transport support that not
the player itself.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
  2012-06-22 18:22     ` Joonsoo Kim
@ 2012-08-16  7:06       ` Pekka Enberg
  -1 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-08-16  7:06 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm

On Sat, 23 Jun 2012, Joonsoo Kim wrote:
> In current implementation, after unfreezing, we doesn't touch oldpage,
> so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
> 
> We can change value of oldpage to NULL after unfreezing,
> because unfreeze_partial() ensure that all the cpu partial slabs is removed
> from cpu partial list. In this time, we could expect that
> this_cpu_cmpxchg is mostly succeed.
> 
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> 
> diff --git a/mm/slub.c b/mm/slub.c
> index 92f1c0e..531d8ed 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
>  				local_irq_save(flags);
>  				unfreeze_partials(s);
>  				local_irq_restore(flags);
> +				oldpage = NULL;
>  				pobjects = 0;
>  				pages = 0;
>  				stat(s, CPU_PARTIAL_DRAIN);

Applied, thanks!

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing
@ 2012-08-16  7:06       ` Pekka Enberg
  0 siblings, 0 replies; 716+ messages in thread
From: Pekka Enberg @ 2012-08-16  7:06 UTC (permalink / raw)
  To: Joonsoo Kim; +Cc: Christoph Lameter, linux-kernel, linux-mm

On Sat, 23 Jun 2012, Joonsoo Kim wrote:
> In current implementation, after unfreezing, we doesn't touch oldpage,
> so it remain 'NOT NULL'. When we call this_cpu_cmpxchg()
> with this old oldpage, this_cpu_cmpxchg() is mostly be failed.
> 
> We can change value of oldpage to NULL after unfreezing,
> because unfreeze_partial() ensure that all the cpu partial slabs is removed
> from cpu partial list. In this time, we could expect that
> this_cpu_cmpxchg is mostly succeed.
> 
> Signed-off-by: Joonsoo Kim <js1304@gmail.com>
> 
> diff --git a/mm/slub.c b/mm/slub.c
> index 92f1c0e..531d8ed 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1968,6 +1968,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
>  				local_irq_save(flags);
>  				unfreeze_partials(s);
>  				local_irq_restore(flags);
> +				oldpage = NULL;
>  				pobjects = 0;
>  				pages = 0;
>  				stat(s, CPU_PARTIAL_DRAIN);

Applied, thanks!

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] mac80211 : Fix Ibss debug message Tx authentication
       [not found] <yes>
                   ` (62 preceding siblings ...)
  2012-08-10  9:35 ` [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing Vani-dineshbhai PATEL
@ 2012-09-20  7:28 ` yes
  2012-09-20  7:55   ` Johannes Berg
  2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
                   ` (27 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: yes @ 2012-09-20  7:28 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, nbd, Sylvain Roger Rieunier

From: Sylvain Roger Rieunier <sylvain.roger.rieunier@gmail.com>

In ibss debug message Tx authentication BSSID and DA address Were reversed
---
 net/mac80211/ibss.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a9d9328..a4f7d37 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -278,7 +278,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
 	if (auth && !sdata->u.ibss.auth_frame_registrations) {
 		ibss_dbg(sdata,
 			 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
-			 sdata->vif.addr, sdata->u.ibss.bssid, addr);
+			 sdata->vif.addr, addr, sdata->u.ibss.bssid);
 		ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
 				    addr, sdata->u.ibss.bssid, NULL, 0, 0);
 	}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] mac80211 : Fix Ibss debug message Tx authentication
  2012-09-20  7:28 ` [PATCH] mac80211 : Fix Ibss debug message Tx authentication yes
@ 2012-09-20  7:55   ` Johannes Berg
  0 siblings, 0 replies; 716+ messages in thread
From: Johannes Berg @ 2012-09-20  7:55 UTC (permalink / raw)
  To: yes; +Cc: linux-wireless, nbd, Sylvain Roger Rieunier

On Thu, 2012-09-20 at 09:28 +0200, yes@test.org wrote:
> From: Sylvain Roger Rieunier <sylvain.roger.rieunier@gmail.com>
> 
> In ibss debug message Tx authentication BSSID and DA address Were reversed

Thanks, please send a patch with signed-off-by though, see section 12 in
http://www.kernel.org/doc/Documentation/SubmittingPatches

johannes



^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board
  2012-02-16  2:59 ` [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board mohamed.haneef at lntinfotech.com
@ 2012-10-03  8:19   ` Albert ARIBAUD
  0 siblings, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2012-10-03  8:19 UTC (permalink / raw)
  To: u-boot

Hi Mohamed,

There never seemed to be a 4/5 patch in this set, neither on the list
nor in patchwork. Was it lost somehow?

Also, could you please not append this to your mails to the list?

> The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and  using or disseminating the information,  and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board
  2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
  2012-02-23  8:59   ` [U-Boot] reminder for " Mohamed Haneef
@ 2012-10-26 21:15   ` Albert ARIBAUD
  1 sibling, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2012-10-26 21:15 UTC (permalink / raw)
  To: u-boot

Hi mohamed.haneef at lntinfotech.com,

On Thu, 16 Feb 2012 08:29:18 +0530, <mohamed.haneef@lntinfotech.com>
wrote:

> From: Mohamed Haneef <mohamed.haneef@lntinfotech.com>
> 
> This is a patch series for msm7630 board. The Patches contain the following support
>         * low speed uart for msm7630
>         * interprocessor communication
>         * msm7630 soc
>         * msm7630 surf board
> 
> 
> Mohamed Haneef (5):
>   msm7x30: Add support for low speed uart on msm7x30
>   msm7x30: Add support for interprocessor communication
>   msm7x30: Add support for Qualcomm msm7630 soc
>   Add support for mmc read and writes
>   msm7x30: Add support for msm7630_surf board

There were successive versions of this patch series, and not all change
requests were answered -- notably patch 4/5 V2 was NAKed and a 3rd
version seemed to be expected. Is a new series in the works?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
       [not found] <yes>
                   ` (63 preceding siblings ...)
  2012-09-20  7:28 ` [PATCH] mac80211 : Fix Ibss debug message Tx authentication yes
@ 2012-11-16  8:53 ` yanjun.zhu
  2012-11-16 12:21   ` Otavio Salvador
  2012-11-29 14:07   ` Paul Eggleton
  2013-02-07 17:33 ` [PATCH 00/10] usb: ehci: more bus glues as separate modules manjunath.goudar at linaro.org
                   ` (26 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: yanjun.zhu @ 2012-11-16  8:53 UTC (permalink / raw)
  To: openembedded-devel

The utf-16 decoder in Python 3.1 through 3.3 does not update the
aligned_end variable after calling the unicode_decode_call_errorhandler
function, which allows remote attackers to obtain sensitive information
(process memory) or cause a denial of service (memory corruption and crash)
via unspecified vectors.

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135

Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
---
 .../python/python/python-2.7.2-CVE-2012-2135.patch |   12 ++++++++++++
 recipes-devtools/python/python_2.7.2.bbappend      |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)
 create mode 100644 recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch

diff --git a/recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch b/recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch
new file mode 100644
index 0000000..b913097
--- /dev/null
+++ b/recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch
@@ -0,0 +1,12 @@
+diff -urpN a/Objects/unicodeobject.c b/Objects/unicodeobject.c
+--- a/Objects/unicodeobject.c	2012-11-12 16:25:33.000000000 +0800
++++ b/Objects/unicodeobject.c	2012-11-12 16:26:22.000000000 +0800
+@@ -2568,7 +2568,7 @@ PyUnicode_DecodeUTF16Stateful(const char
+         }
+ 
+         /* UTF-16 code pair: */
+-        if (q >= e) {
++        if (e - q < 2) {
+             errmsg = "unexpected end of data";
+             startinpos = (((const char *)q)-2)-starts;
+             endinpos = ((const char *)e)-starts;
diff --git a/recipes-devtools/python/python_2.7.2.bbappend b/recipes-devtools/python/python_2.7.2.bbappend
index 87be410..64ada6c 100644
--- a/recipes-devtools/python/python_2.7.2.bbappend
+++ b/recipes-devtools/python/python_2.7.2.bbappend
@@ -5,5 +5,6 @@ SRC_URI += "\
     file://python-CVE-2010-3492.patch \
     file://python-2.7.2-CVE-2012-0845.patch \
     file://python-2.7.2-CVE-2012-1150.patch \
+    file://python-2.7.2-CVE-2012-2135.patch \
 "
 PRINC = "2"
-- 
1.6.3.1




^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
@ 2012-11-16 12:21   ` Otavio Salvador
  2012-11-19  2:26     ` yzhu1
  2012-11-29 14:07   ` Paul Eggleton
  1 sibling, 1 reply; 716+ messages in thread
From: Otavio Salvador @ 2012-11-16 12:21 UTC (permalink / raw)
  To: openembedded-devel

On Fri, Nov 16, 2012 at 6:53 AM, yanjun.zhu <yanjun.zhu@windriver.com>wrote:

> The utf-16 decoder in Python 3.1 through 3.3 does not update the
> aligned_end variable after calling the unicode_decode_call_errorhandler
> function, which allows remote attackers to obtain sensitive information
> (process memory) or cause a denial of service (memory corruption and crash)
> via unspecified vectors.
>
> http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135
>
> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
>

I think this needs to be backported to previous releases, right?

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-16 12:21   ` Otavio Salvador
@ 2012-11-19  2:26     ` yzhu1
  2012-11-19  2:36       ` yzhu1
  0 siblings, 1 reply; 716+ messages in thread
From: yzhu1 @ 2012-11-19  2:26 UTC (permalink / raw)
  To: openembedded-devel

On 11/16/2012 08:21 PM, Otavio Salvador wrote:
> On Fri, Nov 16, 2012 at 6:53 AM, yanjun.zhu <yanjun.zhu@windriver.com>wrote:
>
>> The utf-16 decoder in Python 3.1 through 3.3 does not update the
>> aligned_end variable after calling the unicode_decode_call_errorhandler
>> function, which allows remote attackers to obtain sensitive information
>> (process memory) or cause a denial of service (memory corruption and crash)
>> via unspecified vectors.
>>
>> http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135
>>
>> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
>>
> I think this needs to be backported to previous releases, right?
Hi, Otavio

OK. I will do it.

Thanks a lot.
Zhu Yanjun





^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-19  2:26     ` yzhu1
@ 2012-11-19  2:36       ` yzhu1
  2012-11-19 10:21         ` Otavio Salvador
  0 siblings, 1 reply; 716+ messages in thread
From: yzhu1 @ 2012-11-19  2:36 UTC (permalink / raw)
  To: openembedded-devel

On 11/19/2012 10:26 AM, yzhu1 wrote:
> On 11/16/2012 08:21 PM, Otavio Salvador wrote:
>> On Fri, Nov 16, 2012 at 6:53 AM, yanjun.zhu 
>> <yanjun.zhu@windriver.com>wrote:
>>
>>> The utf-16 decoder in Python 3.1 through 3.3 does not update the
>>> aligned_end variable after calling the unicode_decode_call_errorhandler
>>> function, which allows remote attackers to obtain sensitive information
>>> (process memory) or cause a denial of service (memory corruption and 
>>> crash)
>>> via unspecified vectors.
>>>
>>> http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135
>>>
>>> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
>>>
>> I think this needs to be backported to previous releases, right?
> Hi, Otavio
>
> OK. I will do it.
>
> Thanks a lot.
> Zhu Yanjun
>
>
Hi, Otavio

Sorry. I do not know what is the previous releases. Do you mean denzil 
branch or others?
Would you like to make it clear?

Thanks a lot.
Zhu Yanjun
>
> _______________________________________________
> Openembedded-devel mailing list
> Openembedded-devel@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel




^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-19  2:36       ` yzhu1
@ 2012-11-19 10:21         ` Otavio Salvador
  0 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2012-11-19 10:21 UTC (permalink / raw)
  To: openembedded-devel

On Mon, Nov 19, 2012 at 12:36 AM, yzhu1 <Yanjun.Zhu@windriver.com> wrote:

> On 11/19/2012 10:26 AM, yzhu1 wrote:
>
>> On 11/16/2012 08:21 PM, Otavio Salvador wrote:
>>
>>> On Fri, Nov 16, 2012 at 6:53 AM, yanjun.zhu <yanjun.zhu@windriver.com>**
>>> wrote:
>>>
>>>  The utf-16 decoder in Python 3.1 through 3.3 does not update the
>>>> aligned_end variable after calling the unicode_decode_call_**
>>>> errorhandler
>>>> function, which allows remote attackers to obtain sensitive information
>>>> (process memory) or cause a denial of service (memory corruption and
>>>> crash)
>>>> via unspecified vectors.
>>>>
>>>> http://web.nvd.nist.gov/view/**vuln/detail?vulnId=CVE-2012-**2135<http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135>
>>>>
>>>> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
>>>>
>>>>  I think this needs to be backported to previous releases, right?
>>>
>> Hi, Otavio
>>
>> OK. I will do it.
>>
>> Thanks a lot.
>> Zhu Yanjun
>>
>>
>>  Hi, Otavio
>
> Sorry. I do not know what is the previous releases. Do you mean denzil
> branch or others?
> Would you like to make it clear?


Yes, I meant denzil and danny (both released and maintained for now).

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
  2012-11-16 12:21   ` Otavio Salvador
@ 2012-11-29 14:07   ` Paul Eggleton
  2012-11-30  2:49     ` yzhu1
  1 sibling, 1 reply; 716+ messages in thread
From: Paul Eggleton @ 2012-11-29 14:07 UTC (permalink / raw)
  To: yanjun.zhu; +Cc: openembedded-devel

On Friday 16 November 2012 16:53:42 yanjun.zhu wrote:
> The utf-16 decoder in Python 3.1 through 3.3 does not update the
> aligned_end variable after calling the unicode_decode_call_errorhandler
> function, which allows remote attackers to obtain sensitive information
> (process memory) or cause a denial of service (memory corruption and crash)
> via unspecified vectors.
> 
> http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135
> 
> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
> ---
>  .../python/python/python-2.7.2-CVE-2012-2135.patch |   12 ++++++++++++
>  recipes-devtools/python/python_2.7.2.bbappend      |    1 +
>  2 files changed, 13 insertions(+), 0 deletions(-)
>  create mode 100644
> recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch

This patch is also against OE-Core, could you send this to the OE-Core list as 
well?

Thanks,
Paul

-- 

Paul Eggleton
Intel Open Source Technology Centre



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] python: fix for Security Advisory - python - CVE-2012-2135
  2012-11-29 14:07   ` Paul Eggleton
@ 2012-11-30  2:49     ` yzhu1
  0 siblings, 0 replies; 716+ messages in thread
From: yzhu1 @ 2012-11-30  2:49 UTC (permalink / raw)
  To: Paul Eggleton; +Cc: openembedded-devel

On 11/29/2012 10:07 PM, Paul Eggleton wrote:
> On Friday 16 November 2012 16:53:42 yanjun.zhu wrote:
>> The utf-16 decoder in Python 3.1 through 3.3 does not update the
>> aligned_end variable after calling the unicode_decode_call_errorhandler
>> function, which allows remote attackers to obtain sensitive information
>> (process memory) or cause a denial of service (memory corruption and crash)
>> via unspecified vectors.
>>
>> http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-2135
>>
>> Signed-off-by: yanjun.zhu <yanjun.zhu@windriver.com>
>> ---
>>   .../python/python/python-2.7.2-CVE-2012-2135.patch |   12 ++++++++++++
>>   recipes-devtools/python/python_2.7.2.bbappend      |    1 +
>>   2 files changed, 13 insertions(+), 0 deletions(-)
>>   create mode 100644
>> recipes-devtools/python/python/python-2.7.2-CVE-2012-2135.patch
> This patch is also against OE-Core, could you send this to the OE-Core list as
> well?
OK. I will follow your advice.

Thanks a lot.
Zhu Yanjun
> Thanks,
> Paul
>




^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 00/10] usb: ehci: more bus glues as separate modules
       [not found] <yes>
                   ` (64 preceding siblings ...)
  2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
@ 2013-02-07 17:33 ` manjunath.goudar at linaro.org
  2013-02-07 20:13   ` Ezequiel Garcia
  2013-02-08 15:23   ` Alan Stern
       [not found] ` <1360258447-27247-1-git-send-email-yes>
                   ` (25 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>


Separate the SOC On-Chip host controller driver from ehci-hcd
host code into its own driver module.

Manjunath Goudar (10):
  USB:Changed omap2plus_defconfig to support OMAP USB static driver
  USB: EHCI: make ehci-omap a separate driver
  USB: EHCI: make ehci-spear a separate driver
  USB: EHCI: make ehci-orion a separate driver
  USB: EHCI: make ehci-atmel a separate driver
  USB: EHCI: make ehci-s5p a separate driver
  USB: EHCI: make ehci-mv a separate driver
  USB: EHCI: make ehci-vt8500 a separate driver
  USB: EHCI: make ehci-msm a separate driver
  USB: EHCI: make ehci-w90X900 a separate driver

 arch/arm/configs/omap2plus_defconfig |    4 ++
 drivers/usb/host/Kconfig             |   43 ++++++++++++---
 drivers/usb/host/Makefile            |   10 +++-
 drivers/usb/host/ehci-atmel.c        |   78 ++++++++++++++-------------
 drivers/usb/host/ehci-hcd.c          |   75 +++++++-------------------
 drivers/usb/host/ehci-msm.c          |   84 +++++++++++++----------------
 drivers/usb/host/ehci-mv.c           |   81 +++++++++++++---------------
 drivers/usb/host/ehci-omap.c         |   69 ++++++++++--------------
 drivers/usb/host/ehci-orion.c        |   98 +++++++++++++++++-----------------
 drivers/usb/host/ehci-s5p.c          |   69 +++++++++++++-----------
 drivers/usb/host/ehci-spear.c        |   77 +++++++++++++-------------
 drivers/usb/host/ehci-vt8500.c       |   73 ++++++++++++-------------
 drivers/usb/host/ehci-w90x900.c      |   90 ++++++++++++++-----------------
 13 files changed, 415 insertions(+), 436 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 01/10] USB:Changed omap2plus_defconfig to support OMAP USB static driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:33   ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Selected EHCI and OMAP driver as static drivers using omap2plus_defconfig
configuration

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/configs/omap2plus_defconfig |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 82ce8d7..9ea7a9c 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -182,6 +182,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_SUSPEND=y
 CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_HCD_OMAP=y
 CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_LIBUSUAL=y
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
  2013-02-07 17:33   ` [PATCH 01/10] USB:Changed omap2plus_defconfig to support OMAP USB static driver manjunath.goudar at linaro.org
@ 2013-02-07 17:33   ` manjunath.goudar at linaro.org
  2013-02-08  7:42     ` Felipe Balbi
  2013-02-07 17:34   ` [PATCH 03/10] USB: EHCI: make ehci-spear " manjunath.goudar at linaro.org
                     ` (7 subsequent siblings)
  9 siblings, 1 reply; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the OMAP host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@linaro.org>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb at vger.kernel.org
Cc: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/host/Kconfig     |    2 +-
 drivers/usb/host/Makefile    |    2 +-
 drivers/usb/host/ehci-hcd.c  |    6 +---
 drivers/usb/host/ehci-omap.c |   69 ++++++++++++++++++------------------------
 4 files changed, 32 insertions(+), 47 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3a21c5d..11e102e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -155,7 +155,7 @@ config USB_EHCI_MXC
 	  Variation of ARC USB block used in some Freescale chips.
 
 config USB_EHCI_HCD_OMAP
-	bool "EHCI support for OMAP3 and later chips"
+	tristate "EHCI support for OMAP3 and later chips"
 	depends on USB_EHCI_HCD && ARCH_OMAP
 	default y
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 001fbff..b54a597 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
 obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
 obj-$(CONFIG_USB_EHCI_MXC)	+= ehci-mxc.o
-
+obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index b416a3f..aaf93ca 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1252,11 +1252,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_hcd_sh_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_HCD_OMAP
-#include "ehci-omap.c"
-#define        PLATFORM_DRIVER         ehci_hcd_omap_driver
-#endif
-
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
@@ -1347,6 +1342,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
 	!defined(PLATFORM_DRIVER) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index ac17a7c..9c10fc3 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -43,6 +43,11 @@
 #include <linux/pm_runtime.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
 
 #include <linux/platform_data/usb-omap.h>
 
@@ -58,9 +63,12 @@
 #define	EHCI_INSNREG05_ULPI_WRDATA_SHIFT		0
 
 /*-------------------------------------------------------------------------*/
+#include "ehci.h"
 
-static const struct hc_driver ehci_omap_hc_driver;
+#define DRIVER_DESC "EHCI OMAP driver"
 
+static const char hcd_name[] = "ehci-omap";
+static struct hc_driver __read_mostly ehci_omap_hc_driver;
 
 static inline void ehci_write(void __iomem *base, u32 reg, u32 val)
 {
@@ -323,56 +331,37 @@ static struct platform_driver ehci_hcd_omap_driver = {
 	/*.suspend		= ehci_hcd_omap_suspend, */
 	/*.resume		= ehci_hcd_omap_resume, */
 	.driver = {
-		.name		= "ehci-omap",
+		.name		= hcd_name,
 	}
 };
 
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ehci_omap_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "OMAP-EHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
 
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
+static const struct ehci_driver_overrides omap_overrides __initdata = {
+	.reset = omap_ehci_init,
+};
 
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset			= omap_ehci_init,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
+static int __init ehci_omap_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
 
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
 
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
+	ehci_init_driver(&ehci_omap_hc_driver, &omap_overrides);
+	return platform_driver_register(&ehci_hcd_omap_driver);
+}
+module_init(ehci_omap_init);
 
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
+static void __exit ehci_omap_cleanup(void)
+{
+	platform_driver_unregister(&ehci_hcd_omap_driver);
+}
+module_exit(ehci_omap_cleanup);
 
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
+MODULE_DESCRIPTION(DRIVER_DESC);
 
 MODULE_ALIAS("platform:omap-ehci");
 MODULE_AUTHOR("Texas Instruments, Inc.");
 MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
+MODULE_LICENSE("GPL");
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 03/10] USB: EHCI: make ehci-spear a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
  2013-02-07 17:33   ` [PATCH 01/10] USB:Changed omap2plus_defconfig to support OMAP USB static driver manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
@ 2013-02-07 17:34   ` manjunath.goudar at linaro.org
  2013-02-08  4:27     ` Viresh Kumar
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Spear host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Shiraz Hashim <shiraz.hashim@st.com>
Cc: linux-usb at vger.kernel.org
Cc: spear-devel at list.st.com
---
 drivers/usb/host/Kconfig      |    8 +++++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ehci-hcd.c   |    6 +---
 drivers/usb/host/ehci-spear.c |   77 ++++++++++++++++++++++-------------------
 4 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 11e102e..4413075 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -162,6 +162,14 @@ config USB_EHCI_HCD_OMAP
 	  Enables support for the on-chip EHCI controller on
 	  OMAP3 and later chips.
 
+config USB_EHCI_HCD_SPEAR
+        tristate "Support for ST spear on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && PLAT_SPEAR
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          ST spear chips.
+
 config USB_EHCI_MSM
 	bool "Support for MSM on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && ARCH_MSM
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index b54a597..c97f4ab 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
 obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
 obj-$(CONFIG_USB_EHCI_MXC)	+= ehci-mxc.o
 obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
+obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index aaf93ca..68cea63 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1292,11 +1292,6 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		vt8500_ehci_driver
 #endif
 
-#ifdef CONFIG_PLAT_SPEAR
-#include "ehci-spear.c"
-#define PLATFORM_DRIVER		spear_ehci_hcd_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_MSM
 #include "ehci-msm.c"
 #define PLATFORM_DRIVER		ehci_msm_driver
@@ -1343,6 +1338,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
 	!defined(PLATFORM_DRIVER) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
+	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index 466c1bb..6e42cee 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -11,11 +11,25 @@
 * more details.
 */
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+
+
 #include <linux/clk.h>
 #include <linux/jiffies.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI spear driver"
+
+static const char hcd_name[] = "ehci-spear";
 
 struct spear_ehci {
 	struct ehci_hcd ehci;
@@ -43,40 +57,7 @@ static int ehci_spear_setup(struct usb_hcd *hcd)
 
 	return ehci_setup(hcd);
 }
-
-static const struct hc_driver ehci_spear_hc_driver = {
-	.description			= hcd_name,
-	.product_desc			= "SPEAr EHCI",
-	.hcd_priv_size			= sizeof(struct spear_ehci),
-
-	/* generic hardware linkage */
-	.irq				= ehci_irq,
-	.flags				= HCD_MEMORY | HCD_USB2,
-
-	/* basic lifecycle operations */
-	.reset				= ehci_spear_setup,
-	.start				= ehci_run,
-	.stop				= ehci_stop,
-	.shutdown			= ehci_shutdown,
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue			= ehci_urb_enqueue,
-	.urb_dequeue			= ehci_urb_dequeue,
-	.endpoint_disable		= ehci_endpoint_disable,
-	.endpoint_reset			= ehci_endpoint_reset,
-
-	/* scheduling support */
-	.get_frame_number		= ehci_get_frame,
-
-	/* root hub support */
-	.hub_status_data		= ehci_hub_status_data,
-	.hub_control			= ehci_hub_control,
-	.bus_suspend			= ehci_bus_suspend,
-	.bus_resume			= ehci_bus_resume,
-	.relinquish_port		= ehci_relinquish_port,
-	.port_handed_over		= ehci_port_handed_over,
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
-};
+static struct hc_driver __read_mostly ehci_spear_hc_driver;
 
 #ifdef CONFIG_PM
 static int ehci_spear_drv_suspend(struct device *dev)
@@ -209,11 +190,35 @@ static struct platform_driver spear_ehci_hcd_driver = {
 	.remove		= spear_ehci_hcd_drv_remove,
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver		= {
-		.name = "spear-ehci",
+		.name = hcd_name,
 		.bus = &platform_bus_type,
 		.pm = &ehci_spear_pm_ops,
 		.of_match_table = of_match_ptr(spear_ehci_id_table),
 	}
 };
 
-MODULE_ALIAS("platform:spear-ehci");
+
+static const struct ehci_driver_overrides spear_overrides __initdata = {
+	.reset = ehci_spear_setup,
+};
+
+static int __init ehci_spear_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ehci_init_driver(&ehci_spear_hc_driver, &spear_overrides);
+	return platform_driver_register(&spear_ehci_hcd_driver);
+}
+module_init(ehci_spear_init);
+
+static void __exit ehci_spear_cleanup(void)
+{
+	platform_driver_unregister(&spear_ehci_hcd_driver);
+}
+module_exit(ehci_spear_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, Jason Cooper, Andrew Lunn, Russell King, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Marvell Orion host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig      |    7 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ehci-hcd.c   |   27 +++++-------
 drivers/usb/host/ehci-orion.c |   98 +++++++++++++++++++++--------------------
 4 files changed, 69 insertions(+), 64 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 4413075..3689b7b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -169,6 +169,13 @@ config USB_EHCI_HCD_SPEAR
         ---help---
           Enables support for the on-chip EHCI controller on
           ST spear chips.
+config USB_EHCI_HCD_ORION
+        tristate  "Support for Marvell Orion on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && PLAT_ORION
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          Morvell Orion chips.
 
 config USB_EHCI_MSM
 	bool "Support for MSM on-chip EHCI USB controller"
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index c97f4ab..23b07dd 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
 obj-$(CONFIG_USB_EHCI_MXC)	+= ehci-mxc.o
 obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
 obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
+obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 68cea63..5a19a57 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
  * before driver shutdown. But it also seems to be caused by bugs in cardbus
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
-static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
+int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
 		      u32 mask, u32 done, int usec)
 {
 	u32	result;
@@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
 	} while (usec > 0);
 	return -ETIMEDOUT;
 }
-
+EXPORT_SYMBOL_GPL(handshake);
 /* check TDI/ARC silicon is in host mode */
-static int tdi_in_host_mode (struct ehci_hcd *ehci)
+static int tdi_in_host_mode(struct ehci_hcd *ehci)
 {
 	u32		tmp;
 
@@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
  * Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  */
-static int ehci_halt (struct ehci_hcd *ehci)
+int ehci_halt(struct ehci_hcd *ehci)
 {
 	u32	temp;
 
@@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
 	return handshake(ehci, &ehci->regs->status,
 			  STS_HALT, STS_HALT, 16 * 125);
 }
-
+EXPORT_SYMBOL_GPL(ehci_halt);
 /* put TDI/ARC silicon into EHCI mode */
-static void tdi_reset (struct ehci_hcd *ehci)
+void tdi_reset(struct ehci_hcd *ehci)
 {
 	u32		tmp;
 
@@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
 		tmp |= USBMODE_BE;
 	ehci_writel(ehci, tmp, &ehci->regs->usbmode);
 }
-
+EXPORT_SYMBOL_GPL(tdi_reset);
 /*
  * Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  */
-static int ehci_reset (struct ehci_hcd *ehci)
+int ehci_reset(struct ehci_hcd *ehci)
 {
 	int	retval;
 	u32	command = ehci_readl(ehci, &ehci->regs->command);
@@ -272,7 +272,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
 			ehci->resuming_ports = 0;
 	return retval;
 }
-
+EXPORT_SYMBOL_GPL(ehci_reset);
 /*
  * Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
@@ -352,7 +352,7 @@ static void ehci_silence_controller(struct ehci_hcd *ehci)
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
  */
-static void ehci_shutdown(struct usb_hcd *hcd)
+void ehci_shutdown(struct usb_hcd *hcd)
 {
 	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
 
@@ -366,7 +366,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
 
 	hrtimer_cancel(&ehci->hrtimer);
 }
-
+EXPORT_SYMBOL_GPL(ehci_shutdown);
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1267,11 +1267,6 @@ MODULE_LICENSE ("GPL");
 #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_ORION
-#include "ehci-orion.c"
-#define	PLATFORM_DRIVER		ehci_orion_driver
-#endif
-
 #ifdef CONFIG_USB_W90X900_EHCI
 #include "ehci-w90x900.c"
 #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 914a3ec..de4dde2 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -8,6 +8,17 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+
+#include <linux/slab.h>
+#include <linux/usb/ulpi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -17,6 +28,9 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
+#include <linux/dma-mapping.h>
+#include "ehci.h"
+
 
 #define rdl(off)	__raw_readl(hcd->regs + (off))
 #define wrl(off, val)	__raw_writel((val), hcd->regs + (off))
@@ -34,6 +48,17 @@
 #define USB_PHY_IVREF_CTRL	0x440
 #define USB_PHY_TST_GRP_CTRL	0x450
 
+#define DRIVER_DESC "EHCI orion driver"
+
+static const char hcd_name[] = "ehci-orion";
+
+static struct hc_driver __read_mostly ehci_orion_hc_driver;
+
+static const struct ehci_driver_overrides orion_overrides __initdata = {
+	.reset = ehci_setup,
+};
+
+
 /*
  * Implement Orion USB controller specification guidelines
  */
@@ -104,51 +129,6 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
 	wrl(USB_MODE, 0x13);
 }
 
-static const struct hc_driver ehci_orion_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Marvell Orion EHCI",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = ehci_setup,
-	.start = ehci_run,
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-	.relinquish_port = ehci_relinquish_port,
-	.port_handed_over = ehci_port_handed_over,
-
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
 static void
 ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
 			     const struct mbus_dram_target_info *dram)
@@ -323,8 +303,6 @@ static int __exit ehci_orion_drv_remove(struct platform_device *pdev)
 	return 0;
 }
 
-MODULE_ALIAS("platform:orion-ehci");
-
 static const struct of_device_id ehci_orion_dt_ids[] = {
 	{ .compatible = "marvell,orion-ehci", },
 	{},
@@ -336,8 +314,32 @@ static struct platform_driver ehci_orion_driver = {
 	.remove		= __exit_p(ehci_orion_drv_remove),
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver = {
-		.name	= "orion-ehci",
+		.name	= hcd_name,
 		.owner  = THIS_MODULE,
 		.of_match_table = of_match_ptr(ehci_orion_dt_ids),
 	},
 };
+
+static int __init ehci_orion_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ehci_init_driver(&ehci_orion_hc_driver, &orion_overrides);
+	return platform_driver_register(&ehci_orion_driver);
+}
+module_init(ehci_orion_init);
+
+static void __exit ehci_orion_cleanup(void)
+{
+	platform_driver_unregister(&ehci_orion_driver);
+}
+module_exit(ehci_orion_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:ehci-orion");
+MODULE_AUTHOR("Tzachi Perelstein");
+MODULE_LICENSE("GPL");
+
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Marvell Orion host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    7 +++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ehci-hcd.c   |   27 +++++-------
 drivers/usb/host/ehci-orion.c |   98 +++++++++++++++++++++--------------------
 4 files changed, 69 insertions(+), 64 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 4413075..3689b7b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -169,6 +169,13 @@ config USB_EHCI_HCD_SPEAR
         ---help---
           Enables support for the on-chip EHCI controller on
           ST spear chips.
+config USB_EHCI_HCD_ORION
+        tristate  "Support for Marvell Orion on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && PLAT_ORION
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          Morvell Orion chips.
 
 config USB_EHCI_MSM
 	bool "Support for MSM on-chip EHCI USB controller"
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index c97f4ab..23b07dd 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
 obj-$(CONFIG_USB_EHCI_MXC)	+= ehci-mxc.o
 obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
 obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
+obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 68cea63..5a19a57 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
  * before driver shutdown. But it also seems to be caused by bugs in cardbus
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
-static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
+int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
 		      u32 mask, u32 done, int usec)
 {
 	u32	result;
@@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
 	} while (usec > 0);
 	return -ETIMEDOUT;
 }
-
+EXPORT_SYMBOL_GPL(handshake);
 /* check TDI/ARC silicon is in host mode */
-static int tdi_in_host_mode (struct ehci_hcd *ehci)
+static int tdi_in_host_mode(struct ehci_hcd *ehci)
 {
 	u32		tmp;
 
@@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
  * Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  */
-static int ehci_halt (struct ehci_hcd *ehci)
+int ehci_halt(struct ehci_hcd *ehci)
 {
 	u32	temp;
 
@@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
 	return handshake(ehci, &ehci->regs->status,
 			  STS_HALT, STS_HALT, 16 * 125);
 }
-
+EXPORT_SYMBOL_GPL(ehci_halt);
 /* put TDI/ARC silicon into EHCI mode */
-static void tdi_reset (struct ehci_hcd *ehci)
+void tdi_reset(struct ehci_hcd *ehci)
 {
 	u32		tmp;
 
@@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
 		tmp |= USBMODE_BE;
 	ehci_writel(ehci, tmp, &ehci->regs->usbmode);
 }
-
+EXPORT_SYMBOL_GPL(tdi_reset);
 /*
  * Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  */
-static int ehci_reset (struct ehci_hcd *ehci)
+int ehci_reset(struct ehci_hcd *ehci)
 {
 	int	retval;
 	u32	command = ehci_readl(ehci, &ehci->regs->command);
@@ -272,7 +272,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
 			ehci->resuming_ports = 0;
 	return retval;
 }
-
+EXPORT_SYMBOL_GPL(ehci_reset);
 /*
  * Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
@@ -352,7 +352,7 @@ static void ehci_silence_controller(struct ehci_hcd *ehci)
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
  */
-static void ehci_shutdown(struct usb_hcd *hcd)
+void ehci_shutdown(struct usb_hcd *hcd)
 {
 	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
 
@@ -366,7 +366,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
 
 	hrtimer_cancel(&ehci->hrtimer);
 }
-
+EXPORT_SYMBOL_GPL(ehci_shutdown);
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1267,11 +1267,6 @@ MODULE_LICENSE ("GPL");
 #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
 #endif
 
-#ifdef CONFIG_PLAT_ORION
-#include "ehci-orion.c"
-#define	PLATFORM_DRIVER		ehci_orion_driver
-#endif
-
 #ifdef CONFIG_USB_W90X900_EHCI
 #include "ehci-w90x900.c"
 #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 914a3ec..de4dde2 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -8,6 +8,17 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+
+#include <linux/slab.h>
+#include <linux/usb/ulpi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -17,6 +28,9 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
+#include <linux/dma-mapping.h>
+#include "ehci.h"
+
 
 #define rdl(off)	__raw_readl(hcd->regs + (off))
 #define wrl(off, val)	__raw_writel((val), hcd->regs + (off))
@@ -34,6 +48,17 @@
 #define USB_PHY_IVREF_CTRL	0x440
 #define USB_PHY_TST_GRP_CTRL	0x450
 
+#define DRIVER_DESC "EHCI orion driver"
+
+static const char hcd_name[] = "ehci-orion";
+
+static struct hc_driver __read_mostly ehci_orion_hc_driver;
+
+static const struct ehci_driver_overrides orion_overrides __initdata = {
+	.reset = ehci_setup,
+};
+
+
 /*
  * Implement Orion USB controller specification guidelines
  */
@@ -104,51 +129,6 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
 	wrl(USB_MODE, 0x13);
 }
 
-static const struct hc_driver ehci_orion_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Marvell Orion EHCI",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = ehci_setup,
-	.start = ehci_run,
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-	.relinquish_port = ehci_relinquish_port,
-	.port_handed_over = ehci_port_handed_over,
-
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
 static void
 ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
 			     const struct mbus_dram_target_info *dram)
@@ -323,8 +303,6 @@ static int __exit ehci_orion_drv_remove(struct platform_device *pdev)
 	return 0;
 }
 
-MODULE_ALIAS("platform:orion-ehci");
-
 static const struct of_device_id ehci_orion_dt_ids[] = {
 	{ .compatible = "marvell,orion-ehci", },
 	{},
@@ -336,8 +314,32 @@ static struct platform_driver ehci_orion_driver = {
 	.remove		= __exit_p(ehci_orion_drv_remove),
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver = {
-		.name	= "orion-ehci",
+		.name	= hcd_name,
 		.owner  = THIS_MODULE,
 		.of_match_table = of_match_ptr(ehci_orion_dt_ids),
 	},
 };
+
+static int __init ehci_orion_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ehci_init_driver(&ehci_orion_hc_driver, &orion_overrides);
+	return platform_driver_register(&ehci_orion_driver);
+}
+module_init(ehci_orion_init);
+
+static void __exit ehci_orion_cleanup(void)
+{
+	platform_driver_unregister(&ehci_orion_driver);
+}
+module_exit(ehci_orion_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:ehci-orion");
+MODULE_AUTHOR("Tzachi Perelstein");
+MODULE_LICENSE("GPL");
+
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, Grant Likely, Rob Herring, Andrew Victor, Nicolas Ferre,
	Jean-Christophe Plagniol-Villard, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Atmel host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Andrew Victor <linux@maxim.org.za>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig      |    7 ++++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
 drivers/usb/host/ehci-hcd.c   |    6 +---
 4 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3689b7b..5a13f9d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
         ---help---
           Enables support for the on-chip EHCI controller on
           Morvell Orion chips.
+config USB_EHCI_HCD_AT91
+        tristate  "Support for Atmel on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          Atmel chips.
 
 config USB_EHCI_MSM
 	bool "Support for MSM on-chip EHCI USB controller"
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 23b07dd..96b4839 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
 obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
 obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
+obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 27639487..2f06711 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -15,6 +15,19 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI atmel driver"
+
+static const char hcd_name[] = "ehci-atmel";
+static struct hc_driver __read_mostly ehci_atmel_hc_driver;
 
 /* interface and function clocks */
 static struct clk *iclk, *fclk;
@@ -60,41 +73,6 @@ static int ehci_atmel_setup(struct usb_hcd *hcd)
 	return ehci_setup(hcd);
 }
 
-static const struct hc_driver ehci_atmel_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "Atmel EHCI UHP HS",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	/* generic hardware linkage */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/* basic lifecycle operations */
-	.reset			= ehci_atmel_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-
-	/* scheduling support */
-	.get_frame_number	= ehci_get_frame,
-
-	/* root hub support */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
-};
-
 static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
 
 static int ehci_atmel_drv_probe(struct platform_device *pdev)
@@ -210,7 +188,35 @@ static struct platform_driver ehci_atmel_driver = {
 	.remove		= ehci_atmel_drv_remove,
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver		= {
-		.name	= "atmel-ehci",
+		.name	= hcd_name,
 		.of_match_table	= of_match_ptr(atmel_ehci_dt_ids),
 	},
 };
+
+static const struct ehci_driver_overrides atmel_overrides __initdata = {
+	.reset = ehci_atmel_setup,
+};
+
+static int __init ehci_atmel_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&ehci_atmel_hc_driver, &atmel_overrides);
+	return platform_driver_register(&ehci_atmel_driver);
+}
+module_init(ehci_atmel_init);
+
+static void __exit ehci_atmel_cleanup(void)
+{
+	platform_driver_unregister(&ehci_atmel_driver);
+}
+module_exit(ehci_atmel_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+MODULE_ALIAS("platform:ehci-atmel");
+MODULE_AUTHOR("Nicolas Ferre");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 5a19a57..628ed139 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1272,11 +1272,6 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ehci-atmel.c"
-#define	PLATFORM_DRIVER		ehci_atmel_driver
-#endif
-
 #ifdef CONFIG_USB_OCTEON_EHCI
 #include "ehci-octeon.c"
 #define PLATFORM_DRIVER		ehci_octeon_driver
@@ -1334,6 +1329,7 @@ MODULE_LICENSE ("GPL");
 	!defined(PLATFORM_DRIVER) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
 	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
+	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Atmel host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Greg KH <greg@kroah.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Andrew Victor <linux@maxim.org.za>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: linux-usb at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig      |    7 ++++
 drivers/usb/host/Makefile     |    1 +
 drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
 drivers/usb/host/ehci-hcd.c   |    6 +---
 4 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3689b7b..5a13f9d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
         ---help---
           Enables support for the on-chip EHCI controller on
           Morvell Orion chips.
+config USB_EHCI_HCD_AT91
+        tristate  "Support for Atmel on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && ARCH_AT91
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          Atmel chips.
 
 config USB_EHCI_MSM
 	bool "Support for MSM on-chip EHCI USB controller"
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 23b07dd..96b4839 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
 obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
 obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
+obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 27639487..2f06711 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -15,6 +15,19 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI atmel driver"
+
+static const char hcd_name[] = "ehci-atmel";
+static struct hc_driver __read_mostly ehci_atmel_hc_driver;
 
 /* interface and function clocks */
 static struct clk *iclk, *fclk;
@@ -60,41 +73,6 @@ static int ehci_atmel_setup(struct usb_hcd *hcd)
 	return ehci_setup(hcd);
 }
 
-static const struct hc_driver ehci_atmel_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "Atmel EHCI UHP HS",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	/* generic hardware linkage */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/* basic lifecycle operations */
-	.reset			= ehci_atmel_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	/* managing i/o requests and associated device resources */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-
-	/* scheduling support */
-	.get_frame_number	= ehci_get_frame,
-
-	/* root hub support */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
-};
-
 static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
 
 static int ehci_atmel_drv_probe(struct platform_device *pdev)
@@ -210,7 +188,35 @@ static struct platform_driver ehci_atmel_driver = {
 	.remove		= ehci_atmel_drv_remove,
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver		= {
-		.name	= "atmel-ehci",
+		.name	= hcd_name,
 		.of_match_table	= of_match_ptr(atmel_ehci_dt_ids),
 	},
 };
+
+static const struct ehci_driver_overrides atmel_overrides __initdata = {
+	.reset = ehci_atmel_setup,
+};
+
+static int __init ehci_atmel_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&ehci_atmel_hc_driver, &atmel_overrides);
+	return platform_driver_register(&ehci_atmel_driver);
+}
+module_init(ehci_atmel_init);
+
+static void __exit ehci_atmel_cleanup(void)
+{
+	platform_driver_unregister(&ehci_atmel_driver);
+}
+module_exit(ehci_atmel_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+MODULE_ALIAS("platform:ehci-atmel");
+MODULE_AUTHOR("Nicolas Ferre");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 5a19a57..628ed139 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1272,11 +1272,6 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
 #endif
 
-#ifdef CONFIG_ARCH_AT91
-#include "ehci-atmel.c"
-#define	PLATFORM_DRIVER		ehci_atmel_driver
-#endif
-
 #ifdef CONFIG_USB_OCTEON_EHCI
 #include "ehci-octeon.c"
 #define PLATFORM_DRIVER		ehci_octeon_driver
@@ -1334,6 +1329,7 @@ MODULE_LICENSE ("GPL");
 	!defined(PLATFORM_DRIVER) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
 	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
+	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 06/10] USB: EHCI: make ehci-s5p a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
                     ` (4 preceding siblings ...)
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-07 17:34   ` manjunath.goudar at linaro.org
  2013-02-07 18:49     ` Stephen Warren
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the s5p host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: linux-usb at vger.kernel.org
---
 drivers/usb/host/Kconfig    |    2 +-
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ehci-hcd.c |    6 +---
 drivers/usb/host/ehci-s5p.c |   69 +++++++++++++++++++++++--------------------
 4 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 5a13f9d..f2e0ed3 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -221,7 +221,7 @@ config USB_EHCI_SH
 	  If you use the PCI EHCI controller, this option is not necessary.
 
 config USB_EHCI_S5P
-       boolean "S5P EHCI support"
+       tristate "S5P EHCI support"
        depends on USB_EHCI_HCD && PLAT_S5P
        help
 	 Enable support for the S5P SOC's on-chip EHCI controller.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 96b4839..5c4f5e1 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
 obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
+obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 628ed139..36557e3 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1297,11 +1297,6 @@ MODULE_LICENSE ("GPL");
 #define	PLATFORM_DRIVER		ehci_hcd_msp_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_TEGRA
-#include "ehci-tegra.c"
-#define PLATFORM_DRIVER		tegra_ehci_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_S5P
 #include "ehci-s5p.c"
 #define PLATFORM_DRIVER		s5p_ehci_driver
@@ -1330,6 +1325,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
 	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
 	!IS_ENABLED(CONFIG_ARCH_AT91) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 319dcfa..653e096 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -18,6 +18,16 @@
 #include <linux/of_gpio.h>
 #include <linux/platform_data/usb-ehci-s5p.h>
 #include <plat/usb-phy.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI s5p driver"
 
 #define EHCI_INSNREG00(base)			(base + 0x90)
 #define EHCI_INSNREG00_ENA_INCR16		(0x1 << 25)
@@ -28,43 +38,16 @@
 	(EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 |	\
 	 EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
 
+static const char hcd_name[] = "ehci-s5p";
+static struct hc_driver __read_mostly s5p_ehci_hc_driver;
+
+
 struct s5p_ehci_hcd {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct clk *clk;
 };
 
-static const struct hc_driver s5p_ehci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "S5P EHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	.reset			= ehci_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	.get_frame_number	= ehci_get_frame,
-
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
-};
-
 static void s5p_setup_vbus_gpio(struct platform_device *pdev)
 {
 	int err;
@@ -283,5 +266,27 @@ static struct platform_driver s5p_ehci_driver = {
 		.of_match_table = of_match_ptr(exynos_ehci_match),
 	}
 };
+static const struct ehci_driver_overrides s5p_overrides __initdata = {
+	.reset = ehci_setup,
+};
+
+static int __init ehci_s5p_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&s5p_ehci_hc_driver, &s5p_overrides);
+	return platform_driver_register(&s5p_ehci_driver);
+}
+module_init(ehci_s5p_init);
+
+static void __exit ehci_s5p_cleanup(void)
+{
+	platform_driver_unregister(&s5p_ehci_driver);
+}
+module_exit(ehci_s5p_cleanup);
 
-MODULE_ALIAS("platform:s5p-ehci");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:ehci-s5p");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 07/10] USB: EHCI: make ehci-mv a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, Jason Cooper, Andrew Lunn, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the mv(marvell) host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig    |    2 +-
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ehci-hcd.c |    6 +---
 drivers/usb/host/ehci-mv.c  |   81 ++++++++++++++++++++-----------------------
 4 files changed, 40 insertions(+), 50 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f2e0ed3..e7c3ce0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -227,7 +227,7 @@ config USB_EHCI_S5P
 	 Enable support for the S5P SOC's on-chip EHCI controller.
 
 config USB_EHCI_MV
-	bool "EHCI support for Marvell on-chip controller"
+	tristate "EHCI support for Marvell on-chip controller"
 	depends on USB_EHCI_HCD && (ARCH_PXA || ARCH_MMP)
 	select USB_EHCI_ROOT_HUB_TT
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 5c4f5e1..677f1d3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
+obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 36557e3..e636719 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1307,11 +1307,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_grlib_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_MV
-#include "ehci-mv.c"
-#define        PLATFORM_DRIVER         ehci_mv_driver
-#endif
-
 #ifdef CONFIG_MIPS_SEAD3
 #include "ehci-sead3.c"
 #define	PLATFORM_DRIVER		ehci_hcd_sead3_driver
@@ -1326,6 +1321,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
 	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c
index 6c56297..67de419 100644
--- a/drivers/usb/host/ehci-mv.c
+++ b/drivers/usb/host/ehci-mv.c
@@ -17,7 +17,18 @@
 #include <linux/usb/otg.h>
 #include <linux/platform_data/mv_usb.h>
 
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI mv driver"
+
 #define CAPLENGTH_MASK         (0xff)
+static const char hcd_name[] = "ehci-mv";
+static struct hc_driver __read_mostly mv_ehci_hc_driver;
 
 struct ehci_hcd_mv {
 	struct usb_hcd *hcd;
@@ -95,48 +106,6 @@ static int mv_ehci_reset(struct usb_hcd *hcd)
 	return retval;
 }
 
-static const struct hc_driver mv_ehci_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Marvell EHCI",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = mv_ehci_reset,
-	.start = ehci_run,
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-};
-
 static int mv_ehci_probe(struct platform_device *pdev)
 {
 	struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
@@ -302,7 +271,6 @@ static int mv_ehci_remove(struct platform_device *pdev)
 {
 	struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
 	struct usb_hcd *hcd = ehci_mv->hcd;
-	int clk_i;
 
 	if (hcd->rh_registered)
 		usb_remove_hcd(hcd);
@@ -351,8 +319,33 @@ static struct platform_driver ehci_mv_driver = {
 	.remove = mv_ehci_remove,
 	.shutdown = mv_ehci_shutdown,
 	.driver = {
-		   .name = "mv-ehci",
+		   .name = hcd_name,
 		   .bus = &platform_bus_type,
 		   },
 	.id_table = ehci_id_table,
 };
+static const struct ehci_driver_overrides mv_overrides __initdata = {
+	.reset = mv_ehci_reset,
+};
+
+static int __init ehci_mv_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&mv_ehci_hc_driver, &mv_overrides);
+	return platform_driver_register(&ehci_mv_driver);
+}
+module_init(ehci_mv_init);
+
+static void __exit ehci_mv_cleanup(void)
+{
+	platform_driver_unregister(&ehci_mv_driver);
+}
+module_exit(ehci_mv_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:ehci-mv");
+MODULE_AUTHOR("Marvell");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 07/10] USB: EHCI: make ehci-mv a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the mv(marvell) host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: linux-usb at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig    |    2 +-
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ehci-hcd.c |    6 +---
 drivers/usb/host/ehci-mv.c  |   81 ++++++++++++++++++++-----------------------
 4 files changed, 40 insertions(+), 50 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f2e0ed3..e7c3ce0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -227,7 +227,7 @@ config USB_EHCI_S5P
 	 Enable support for the S5P SOC's on-chip EHCI controller.
 
 config USB_EHCI_MV
-	bool "EHCI support for Marvell on-chip controller"
+	tristate "EHCI support for Marvell on-chip controller"
 	depends on USB_EHCI_HCD && (ARCH_PXA || ARCH_MMP)
 	select USB_EHCI_ROOT_HUB_TT
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 5c4f5e1..677f1d3 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
 obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
+obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 36557e3..e636719 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1307,11 +1307,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_grlib_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_MV
-#include "ehci-mv.c"
-#define        PLATFORM_DRIVER         ehci_mv_driver
-#endif
-
 #ifdef CONFIG_MIPS_SEAD3
 #include "ehci-sead3.c"
 #define	PLATFORM_DRIVER		ehci_hcd_sead3_driver
@@ -1326,6 +1321,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
 	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c
index 6c56297..67de419 100644
--- a/drivers/usb/host/ehci-mv.c
+++ b/drivers/usb/host/ehci-mv.c
@@ -17,7 +17,18 @@
 #include <linux/usb/otg.h>
 #include <linux/platform_data/mv_usb.h>
 
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include "ehci.h"
+
+#define DRIVER_DESC "EHCI mv driver"
+
 #define CAPLENGTH_MASK         (0xff)
+static const char hcd_name[] = "ehci-mv";
+static struct hc_driver __read_mostly mv_ehci_hc_driver;
 
 struct ehci_hcd_mv {
 	struct usb_hcd *hcd;
@@ -95,48 +106,6 @@ static int mv_ehci_reset(struct usb_hcd *hcd)
 	return retval;
 }
 
-static const struct hc_driver mv_ehci_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Marvell EHCI",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = mv_ehci_reset,
-	.start = ehci_run,
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-};
-
 static int mv_ehci_probe(struct platform_device *pdev)
 {
 	struct mv_usb_platform_data *pdata = pdev->dev.platform_data;
@@ -302,7 +271,6 @@ static int mv_ehci_remove(struct platform_device *pdev)
 {
 	struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev);
 	struct usb_hcd *hcd = ehci_mv->hcd;
-	int clk_i;
 
 	if (hcd->rh_registered)
 		usb_remove_hcd(hcd);
@@ -351,8 +319,33 @@ static struct platform_driver ehci_mv_driver = {
 	.remove = mv_ehci_remove,
 	.shutdown = mv_ehci_shutdown,
 	.driver = {
-		   .name = "mv-ehci",
+		   .name = hcd_name,
 		   .bus = &platform_bus_type,
 		   },
 	.id_table = ehci_id_table,
 };
+static const struct ehci_driver_overrides mv_overrides __initdata = {
+	.reset = mv_ehci_reset,
+};
+
+static int __init ehci_mv_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&mv_ehci_hc_driver, &mv_overrides);
+	return platform_driver_register(&ehci_mv_driver);
+}
+module_init(ehci_mv_init);
+
+static void __exit ehci_mv_cleanup(void)
+{
+	platform_driver_unregister(&ehci_mv_driver);
+}
+module_exit(ehci_mv_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:ehci-mv");
+MODULE_AUTHOR("Marvell");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 08/10] USB: EHCI: make ehci-vt8500 a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, Tony Prisk, Alexey Charkov, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the vt8500 host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Alexey Charkov <alchark@gmail.com>
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig       |    8 +++++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ehci-hcd.c    |    5 ---
 drivers/usb/host/ehci-vt8500.c |   73 ++++++++++++++++++----------------------
 4 files changed, 42 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e7c3ce0..d20d22c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -162,6 +162,14 @@ config USB_EHCI_HCD_OMAP
 	  Enables support for the on-chip EHCI controller on
 	  OMAP3 and later chips.
 
+config USB_EHCI_HCD_VT8500
+        tristate "Support for VT8500 on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && ARCH_VT8500
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          VT8500 chips.
+
 config USB_EHCI_HCD_SPEAR
         tristate "Support for ST spear on-chip EHCI USB controller"
         depends on USB_EHCI_HCD && PLAT_SPEAR
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 677f1d3..cf71e5d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
+obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e636719..952f85e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1277,11 +1277,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define	PLATFORM_DRIVER		vt8500_ehci_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_MSM
 #include "ehci-msm.c"
 #define PLATFORM_DRIVER		ehci_msm_driver
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index 11695d5..ff4e3ae 100644
--- a/drivers/usb/host/ehci-vt8500.c
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -16,52 +16,25 @@
  *
  */
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 
-static const struct hc_driver vt8500_ehci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "VT8500 EHCI",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
+#include "ehci.h"
 
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset			= ehci_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
+#define DRIVER_DESC "vt8500 On-Chip EHCI Host driver"
 
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
+static const char hcd_name[] = "ehci-vt8500";
 
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
+static struct hc_driver __read_mostly vt8500_ehci_hc_driver;
 
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+static const struct ehci_driver_overrides ehci_vt8500_overrides __initdata = {
+	.reset = ehci_setup,
 };
 
 static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
@@ -140,11 +113,31 @@ static struct platform_driver vt8500_ehci_driver = {
 	.remove		= vt8500_ehci_drv_remove,
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver = {
-		.name	= "vt8500-ehci",
+		.name	= hcd_name,
 		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(vt8500_ehci_ids),
 	}
 };
 
+static int __init ehci_vt8500_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&vt8500_ehci_hc_driver, &ehci_vt8500_overrides);
+	return platform_driver_register(&vt8500_ehci_driver);
+}
+module_init(ehci_vt8500_init);
+
+static void __exit ehci_vt8500_cleanup(void)
+{
+	platform_driver_unregister(&vt8500_ehci_driver);
+}
+module_exit(ehci_vt8500_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Alexey Charkov");
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:vt8500-ehci");
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 08/10] USB: EHCI: make ehci-vt8500 a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the vt8500 host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Tony Prisk <linux@prisktech.co.nz>
Cc: Alexey Charkov <alchark@gmail.com>
Cc: linux-usb at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig       |    8 +++++
 drivers/usb/host/Makefile      |    1 +
 drivers/usb/host/ehci-hcd.c    |    5 ---
 drivers/usb/host/ehci-vt8500.c |   73 ++++++++++++++++++----------------------
 4 files changed, 42 insertions(+), 45 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index e7c3ce0..d20d22c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -162,6 +162,14 @@ config USB_EHCI_HCD_OMAP
 	  Enables support for the on-chip EHCI controller on
 	  OMAP3 and later chips.
 
+config USB_EHCI_HCD_VT8500
+        tristate "Support for VT8500 on-chip EHCI USB controller"
+        depends on USB_EHCI_HCD && ARCH_VT8500
+        default y
+        ---help---
+          Enables support for the on-chip EHCI controller on
+          VT8500 chips.
+
 config USB_EHCI_HCD_SPEAR
         tristate "Support for ST spear on-chip EHCI USB controller"
         depends on USB_EHCI_HCD && PLAT_SPEAR
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 677f1d3..cf71e5d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
+obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e636719..952f85e 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1277,11 +1277,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_ARCH_VT8500
-#include "ehci-vt8500.c"
-#define	PLATFORM_DRIVER		vt8500_ehci_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_MSM
 #include "ehci-msm.c"
 #define PLATFORM_DRIVER		ehci_msm_driver
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index 11695d5..ff4e3ae 100644
--- a/drivers/usb/host/ehci-vt8500.c
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -16,52 +16,25 @@
  *
  */
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 
-static const struct hc_driver vt8500_ehci_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "VT8500 EHCI",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
+#include "ehci.h"
 
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset			= ehci_setup,
-	.start			= ehci_run,
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
+#define DRIVER_DESC "vt8500 On-Chip EHCI Host driver"
 
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
+static const char hcd_name[] = "ehci-vt8500";
 
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
+static struct hc_driver __read_mostly vt8500_ehci_hc_driver;
 
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+static const struct ehci_driver_overrides ehci_vt8500_overrides __initdata = {
+	.reset = ehci_setup,
 };
 
 static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
@@ -140,11 +113,31 @@ static struct platform_driver vt8500_ehci_driver = {
 	.remove		= vt8500_ehci_drv_remove,
 	.shutdown	= usb_hcd_platform_shutdown,
 	.driver = {
-		.name	= "vt8500-ehci",
+		.name	= hcd_name,
 		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(vt8500_ehci_ids),
 	}
 };
 
+static int __init ehci_vt8500_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&vt8500_ehci_hc_driver, &ehci_vt8500_overrides);
+	return platform_driver_register(&vt8500_ehci_driver);
+}
+module_init(ehci_vt8500_init);
+
+static void __exit ehci_vt8500_cleanup(void)
+{
+	platform_driver_unregister(&vt8500_ehci_driver);
+}
+module_exit(ehci_vt8500_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Alexey Charkov");
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:vt8500-ehci");
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, David Brown, Daniel Walker, Bryan Huntsman,
	Brian Swetland, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Qualcomm On-Chip host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: David Brown <davidb@codeaurora.org>
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Cc: Brian Swetland <swetland@google.com>
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig    |    5 +--
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ehci-hcd.c |    7 ++--
 drivers/usb/host/ehci-msm.c |   84 +++++++++++++++++++------------------------
 4 files changed, 43 insertions(+), 54 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d20d22c..8d18a6c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -184,6 +184,7 @@ config USB_EHCI_HCD_ORION
         ---help---
           Enables support for the on-chip EHCI controller on
           Morvell Orion chips.
+
 config USB_EHCI_HCD_AT91
         tristate  "Support for Atmel on-chip EHCI USB controller"
         depends on USB_EHCI_HCD && ARCH_AT91
@@ -193,7 +194,7 @@ config USB_EHCI_HCD_AT91
           Atmel chips.
 
 config USB_EHCI_MSM
-	bool "Support for MSM on-chip EHCI USB controller"
+	tristate "Support for MSM on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && ARCH_MSM
 	select USB_EHCI_ROOT_HUB_TT
 	select USB_MSM_OTG
@@ -209,7 +210,7 @@ config USB_EHCI_TEGRA
        boolean "NVIDIA Tegra HCD support"
        depends on USB_EHCI_HCD && ARCH_TEGRA
        select USB_EHCI_ROOT_HUB_TT
-       help
+      --- help---
          This driver enables support for the internal USB Host Controllers
          found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cf71e5d..6c1d0e0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
+obj-$(CONFIG_USB_EHCI_MSM)      += ehci-msm.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 952f85e..d44115b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1277,11 +1277,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_MSM
-#include "ehci-msm.c"
-#define PLATFORM_DRIVER		ehci_msm_driver
-#endif
-
 #ifdef CONFIG_TILE_USB
 #include "ehci-tilegx.c"
 #define	PLATFORM_DRIVER		ehci_hcd_tilegx_driver
@@ -1317,6 +1312,8 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
+	!IS_ENABLED(CONFIG_ARCH_VT8500) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 88a49c8..fdf66a9 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -30,8 +30,19 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/msm_hsusb_hw.h>
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include "ehci.h"
+
 #define MSM_USB_BASE (hcd->regs)
 
+#define DRIVER_DESC "Qualcomm On-Chip EHCI Host Controller"
+
+static const char hcd_name[] = "msm_hsusb_host";
+static struct hc_driver __read_mostly msm_hc_driver;
 static struct usb_phy *phy;
 
 static int ehci_msm_reset(struct usb_hcd *hcd)
@@ -56,52 +67,6 @@ static int ehci_msm_reset(struct usb_hcd *hcd)
 	return 0;
 }
 
-static struct hc_driver msm_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "Qualcomm On-Chip EHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_USB2 | HCD_MEMORY,
-
-	.reset			= ehci_msm_reset,
-	.start			= ehci_run,
-
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	/*
-	 * PM support
-	 */
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-};
-
 static int ehci_msm_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd;
@@ -222,7 +187,32 @@ static struct platform_driver ehci_msm_driver = {
 	.probe	= ehci_msm_probe,
 	.remove	= ehci_msm_remove,
 	.driver = {
-		   .name = "msm_hsusb_host",
+		   .name = hcd_name,
 		   .pm = &ehci_msm_dev_pm_ops,
 	},
 };
+
+static const struct ehci_driver_overrides msm_overrides __initdata = {
+	.reset = ehci_msm_reset,
+};
+
+static int __init ehci_msm_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&msm_hc_driver, &msm_overrides);
+	return platform_driver_register(&ehci_msm_driver);
+}
+module_init(ehci_msm_init);
+
+static void __exit ehci_msm_cleanup(void)
+{
+	platform_driver_unregister(&ehci_msm_driver);
+}
+module_exit(ehci_msm_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:omap-msm");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Qualcomm On-Chip host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: David Brown <davidb@codeaurora.org>
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Cc: Brian Swetland <swetland@google.com>
Cc: linux-usb at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig    |    5 +--
 drivers/usb/host/Makefile   |    1 +
 drivers/usb/host/ehci-hcd.c |    7 ++--
 drivers/usb/host/ehci-msm.c |   84 +++++++++++++++++++------------------------
 4 files changed, 43 insertions(+), 54 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d20d22c..8d18a6c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -184,6 +184,7 @@ config USB_EHCI_HCD_ORION
         ---help---
           Enables support for the on-chip EHCI controller on
           Morvell Orion chips.
+
 config USB_EHCI_HCD_AT91
         tristate  "Support for Atmel on-chip EHCI USB controller"
         depends on USB_EHCI_HCD && ARCH_AT91
@@ -193,7 +194,7 @@ config USB_EHCI_HCD_AT91
           Atmel chips.
 
 config USB_EHCI_MSM
-	bool "Support for MSM on-chip EHCI USB controller"
+	tristate "Support for MSM on-chip EHCI USB controller"
 	depends on USB_EHCI_HCD && ARCH_MSM
 	select USB_EHCI_ROOT_HUB_TT
 	select USB_MSM_OTG
@@ -209,7 +210,7 @@ config USB_EHCI_TEGRA
        boolean "NVIDIA Tegra HCD support"
        depends on USB_EHCI_HCD && ARCH_TEGRA
        select USB_EHCI_ROOT_HUB_TT
-       help
+      --- help---
          This driver enables support for the internal USB Host Controllers
          found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
 
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index cf71e5d..6c1d0e0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
+obj-$(CONFIG_USB_EHCI_MSM)      += ehci-msm.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 952f85e..d44115b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1277,11 +1277,6 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_octeon_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_MSM
-#include "ehci-msm.c"
-#define PLATFORM_DRIVER		ehci_msm_driver
-#endif
-
 #ifdef CONFIG_TILE_USB
 #include "ehci-tilegx.c"
 #define	PLATFORM_DRIVER		ehci_hcd_tilegx_driver
@@ -1317,6 +1312,8 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_ARCH_AT91) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_S5P) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
+	!IS_ENABLED(CONFIG_ARCH_VT8500) && \
+	!IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 88a49c8..fdf66a9 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -30,8 +30,19 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/msm_hsusb_hw.h>
 
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include "ehci.h"
+
 #define MSM_USB_BASE (hcd->regs)
 
+#define DRIVER_DESC "Qualcomm On-Chip EHCI Host Controller"
+
+static const char hcd_name[] = "msm_hsusb_host";
+static struct hc_driver __read_mostly msm_hc_driver;
 static struct usb_phy *phy;
 
 static int ehci_msm_reset(struct usb_hcd *hcd)
@@ -56,52 +67,6 @@ static int ehci_msm_reset(struct usb_hcd *hcd)
 	return 0;
 }
 
-static struct hc_driver msm_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "Qualcomm On-Chip EHCI Host Controller",
-	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= ehci_irq,
-	.flags			= HCD_USB2 | HCD_MEMORY,
-
-	.reset			= ehci_msm_reset,
-	.start			= ehci_run,
-
-	.stop			= ehci_stop,
-	.shutdown		= ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= ehci_urb_enqueue,
-	.urb_dequeue		= ehci_urb_dequeue,
-	.endpoint_disable	= ehci_endpoint_disable,
-	.endpoint_reset		= ehci_endpoint_reset,
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= ehci_hub_control,
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	/*
-	 * PM support
-	 */
-	.bus_suspend		= ehci_bus_suspend,
-	.bus_resume		= ehci_bus_resume,
-};
-
 static int ehci_msm_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd;
@@ -222,7 +187,32 @@ static struct platform_driver ehci_msm_driver = {
 	.probe	= ehci_msm_probe,
 	.remove	= ehci_msm_remove,
 	.driver = {
-		   .name = "msm_hsusb_host",
+		   .name = hcd_name,
 		   .pm = &ehci_msm_dev_pm_ops,
 	},
 };
+
+static const struct ehci_driver_overrides msm_overrides __initdata = {
+	.reset = ehci_msm_reset,
+};
+
+static int __init ehci_msm_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	ehci_init_driver(&msm_hc_driver, &msm_overrides);
+	return platform_driver_register(&ehci_msm_driver);
+}
+module_init(ehci_msm_init);
+
+static void __exit ehci_msm_cleanup(void)
+{
+	platform_driver_unregister(&ehci_msm_driver);
+}
+module_exit(ehci_msm_cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_ALIAS("platform:omap-msm");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 10/10] USB: EHCI: make ehci-w90X900 a separate driver
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-usb
  Cc: linux-arm-kernel, patches, stern, arnd, gregkh, Manjunath Goudar,
	Greg KH, Wan ZongShun, linux-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Nuvoton On-Chip host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/usb/host/Kconfig        |    2 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-hcd.c     |    6 +--
 drivers/usb/host/ehci-w90x900.c |   90 +++++++++++++++++----------------------
 4 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8d18a6c..1b5e30b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -245,7 +245,7 @@ config USB_EHCI_MV
 	  only be EHCI host. OTG is controller that can switch to host mode.
 
 config USB_W90X900_EHCI
-	bool "W90X900(W90P910) EHCI support"
+	 tristate "W90X900(W90P910) EHCI support"
 	depends on USB_EHCI_HCD && ARCH_W90X900
 	---help---
 		Enables support for the W90X900 USB controller
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 6c1d0e0..74db4d4 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
 obj-$(CONFIG_USB_EHCI_MSM)      += ehci-msm.o
+obj-$(CONFIG_USB_W90X900_EHCI)  += ehci-w90x900.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d44115b..84ed7d7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1267,11 +1267,6 @@ MODULE_LICENSE ("GPL");
 #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
 #endif
 
-#ifdef CONFIG_USB_W90X900_EHCI
-#include "ehci-w90x900.c"
-#define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
-#endif
-
 #ifdef CONFIG_USB_OCTEON_EHCI
 #include "ehci-octeon.c"
 #define PLATFORM_DRIVER		ehci_octeon_driver
@@ -1314,6 +1309,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
 	!IS_ENABLED(CONFIG_ARCH_VT8500) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
+	!IS_ENABLED(CONFIG_USB_W90X900_EHCI) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index 59e0e24..0b677ec 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -13,11 +13,31 @@
 
 #include <linux/platform_device.h>
 
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include "ehci.h"
+
 /* enable phy0 and phy1 for w90p910 */
 #define	ENPHY		(0x01<<8)
 #define PHY0_CTR	(0xA4)
 #define PHY1_CTR	(0xA8)
 
+#define DRIVER_DESC "Nuvoton w90x900 On-Chip EHCI Host driver"
+
+static const char hcd_name[] = "ehci-w90x900";
+
+static struct hc_driver __read_mostly ehci_w90x900_hc_driver;
+
+static const struct ehci_driver_overrides ehci_w90X900_overrides __initdata = {
+	.reset = ehci_setup,
+};
+
 static int usb_w90x900_probe(const struct hc_driver *driver,
 		      struct platform_device *pdev)
 {
@@ -99,54 +119,6 @@ void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev)
 	usb_put_hcd(hcd);
 }
 
-static const struct hc_driver ehci_w90x900_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Nuvoton w90x900 EHCI Host Controller",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_USB2|HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = ehci_setup,
-	.start = ehci_run,
-
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-#endif
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
 static int ehci_w90x900_probe(struct platform_device *pdev)
 {
 	if (usb_disabled())
@@ -168,12 +140,30 @@ static struct platform_driver ehci_hcd_w90x900_driver = {
 	.probe  = ehci_w90x900_probe,
 	.remove = ehci_w90x900_remove,
 	.driver = {
-		.name = "w90x900-ehci",
+		.name = hcd_name,
 		.owner = THIS_MODULE,
 	},
 };
 
+static int __init ehci_w90X900_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ehci_init_driver(&ehci_w90x900_hc_driver, &ehci_w90X900_overrides);
+	return platform_driver_register(&ehci_hcd_w90x900_driver);
+}
+module_init(ehci_w90X900_init);
+
+static void __exit ehci_w90X900_cleanup(void)
+{
+	platform_driver_unregister(&ehci_hcd_w90x900_driver);
+}
+module_exit(ehci_w90X900_cleanup);
+
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("w90p910 usb ehci driver!");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:w90p910-ehci");
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 10/10] USB: EHCI: make ehci-w90X900 a separate driver
@ 2013-02-07 17:34     ` manjunath.goudar at linaro.org
  0 siblings, 0 replies; 716+ messages in thread
From: manjunath.goudar at linaro.org @ 2013-02-07 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

From: Manjunath Goudar <manjunath.goudar@linaro.org>

Separate the Nuvoton On-Chip host controller driver from ehci-hcd host code
into its own driver module.

Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Cc: Greg KH <greg@kroah.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: linux-usb at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/usb/host/Kconfig        |    2 +-
 drivers/usb/host/Makefile       |    1 +
 drivers/usb/host/ehci-hcd.c     |    6 +--
 drivers/usb/host/ehci-w90x900.c |   90 +++++++++++++++++----------------------
 4 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8d18a6c..1b5e30b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -245,7 +245,7 @@ config USB_EHCI_MV
 	  only be EHCI host. OTG is controller that can switch to host mode.
 
 config USB_W90X900_EHCI
-	bool "W90X900(W90P910) EHCI support"
+	 tristate "W90X900(W90P910) EHCI support"
 	depends on USB_EHCI_HCD && ARCH_W90X900
 	---help---
 		Enables support for the W90X900 USB controller
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 6c1d0e0..74db4d4 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_USB_EHCI_S5P)      += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_MV)       += ehci-mv.o
 obj-$(CONFIG_USB_EHCI_HCD_VT8500)+= ehci-vt8500.o
 obj-$(CONFIG_USB_EHCI_MSM)      += ehci-msm.o
+obj-$(CONFIG_USB_W90X900_EHCI)  += ehci-w90x900.o
 obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d44115b..84ed7d7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1267,11 +1267,6 @@ MODULE_LICENSE ("GPL");
 #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver
 #endif
 
-#ifdef CONFIG_USB_W90X900_EHCI
-#include "ehci-w90x900.c"
-#define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
-#endif
-
 #ifdef CONFIG_USB_OCTEON_EHCI
 #include "ehci-octeon.c"
 #define PLATFORM_DRIVER		ehci_octeon_driver
@@ -1314,6 +1309,7 @@ MODULE_LICENSE ("GPL");
 	!IS_ENABLED(CONFIG_USB_EHCI_MV) && \
 	!IS_ENABLED(CONFIG_ARCH_VT8500) && \
 	!IS_ENABLED(CONFIG_USB_EHCI_MSM) && \
+	!IS_ENABLED(CONFIG_USB_W90X900_EHCI) && \
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(OF_PLATFORM_DRIVER) && \
 	!defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index 59e0e24..0b677ec 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -13,11 +13,31 @@
 
 #include <linux/platform_device.h>
 
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/io.h>
+#include "ehci.h"
+
 /* enable phy0 and phy1 for w90p910 */
 #define	ENPHY		(0x01<<8)
 #define PHY0_CTR	(0xA4)
 #define PHY1_CTR	(0xA8)
 
+#define DRIVER_DESC "Nuvoton w90x900 On-Chip EHCI Host driver"
+
+static const char hcd_name[] = "ehci-w90x900";
+
+static struct hc_driver __read_mostly ehci_w90x900_hc_driver;
+
+static const struct ehci_driver_overrides ehci_w90X900_overrides __initdata = {
+	.reset = ehci_setup,
+};
+
 static int usb_w90x900_probe(const struct hc_driver *driver,
 		      struct platform_device *pdev)
 {
@@ -99,54 +119,6 @@ void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev)
 	usb_put_hcd(hcd);
 }
 
-static const struct hc_driver ehci_w90x900_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "Nuvoton w90x900 EHCI Host Controller",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_USB2|HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = ehci_setup,
-	.start = ehci_run,
-
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-	.endpoint_reset = ehci_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-#endif
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
-
-	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
-
 static int ehci_w90x900_probe(struct platform_device *pdev)
 {
 	if (usb_disabled())
@@ -168,12 +140,30 @@ static struct platform_driver ehci_hcd_w90x900_driver = {
 	.probe  = ehci_w90x900_probe,
 	.remove = ehci_w90x900_remove,
 	.driver = {
-		.name = "w90x900-ehci",
+		.name = hcd_name,
 		.owner = THIS_MODULE,
 	},
 };
 
+static int __init ehci_w90X900_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+	ehci_init_driver(&ehci_w90x900_hc_driver, &ehci_w90X900_overrides);
+	return platform_driver_register(&ehci_hcd_w90x900_driver);
+}
+module_init(ehci_w90X900_init);
+
+static void __exit ehci_w90X900_cleanup(void)
+{
+	platform_driver_unregister(&ehci_hcd_w90x900_driver);
+}
+module_exit(ehci_w90X900_cleanup);
+
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("w90p910 usb ehci driver!");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:w90p910-ehci");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-07 18:48       ` Stephen Warren
  -1 siblings, 0 replies; 716+ messages in thread
From: Stephen Warren @ 2013-02-07 18:48 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, arnd, gregkh,
	Greg KH, David Brown, Daniel Walker, Bryan Huntsman,
	Brian Swetland, linux-kernel

On 02/07/2013 10:34 AM, manjunath.goudar@linaro.org wrote:
> Separate the Qualcomm On-Chip host controller driver from ehci-hcd host code
> into its own driver module.

> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig

> @@ -209,7 +210,7 @@ config USB_EHCI_TEGRA
>         boolean "NVIDIA Tegra HCD support"
>         depends on USB_EHCI_HCD && ARCH_TEGRA
>         select USB_EHCI_ROOT_HUB_TT
> -       help
> +      --- help---
>           This driver enables support for the internal USB Host Controllers
>           found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.

That seems like an unrelated change. The indentation and space after
first "---" looks wrong too. It looks pretty random which of "help" and
"---help---" is used in this file; if you're going to fix that, I think
fix them all, but in a separate patch.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
@ 2013-02-07 18:48       ` Stephen Warren
  0 siblings, 0 replies; 716+ messages in thread
From: Stephen Warren @ 2013-02-07 18:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/07/2013 10:34 AM, manjunath.goudar at linaro.org wrote:
> Separate the Qualcomm On-Chip host controller driver from ehci-hcd host code
> into its own driver module.

> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig

> @@ -209,7 +210,7 @@ config USB_EHCI_TEGRA
>         boolean "NVIDIA Tegra HCD support"
>         depends on USB_EHCI_HCD && ARCH_TEGRA
>         select USB_EHCI_ROOT_HUB_TT
> -       help
> +      --- help---
>           This driver enables support for the internal USB Host Controllers
>           found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.

That seems like an unrelated change. The indentation and space after
first "---" looks wrong too. It looks pretty random which of "help" and
"---help---" is used in this file; if you're going to fix that, I think
fix them all, but in a separate patch.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 06/10] USB: EHCI: make ehci-s5p a separate driver
  2013-02-07 17:34   ` [PATCH 06/10] USB: EHCI: make ehci-s5p " manjunath.goudar at linaro.org
@ 2013-02-07 18:49     ` Stephen Warren
  0 siblings, 0 replies; 716+ messages in thread
From: Stephen Warren @ 2013-02-07 18:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/07/2013 10:34 AM, manjunath.goudar at linaro.org wrote:
> Separate the s5p host controller driver from ehci-hcd host code
> into its own driver module.

> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c

> @@ -1297,11 +1297,6 @@ MODULE_LICENSE ("GPL");
>  #define	PLATFORM_DRIVER		ehci_hcd_msp_driver
>  #endif
>  
> -#ifdef CONFIG_USB_EHCI_TEGRA
> -#include "ehci-tegra.c"
> -#define PLATFORM_DRIVER		tegra_ehci_driver
> -#endif
> -

That also looks wrong.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 08/10] USB: EHCI: make ehci-vt8500 a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-07 18:54       ` Tony Prisk
  -1 siblings, 0 replies; 716+ messages in thread
From: Tony Prisk @ 2013-02-07 18:54 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, arnd, gregkh,
	Greg KH, Alexey Charkov, linux-kernel

On Thu, 2013-02-07 at 23:04 +0530, manjunath.goudar@linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> Separate the vt8500 host controller driver from ehci-hcd host code
> into its own driver module.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Tony Prisk <linux@prisktech.co.nz>
> Cc: Alexey Charkov <alchark@gmail.com>
> Cc: linux-usb@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  drivers/usb/host/Kconfig       |    8 +++++
>  drivers/usb/host/Makefile      |    1 +
>  drivers/usb/host/ehci-hcd.c    |    5 ---
>  drivers/usb/host/ehci-vt8500.c |   73 ++++++++++++++++++----------------------
>  4 files changed, 42 insertions(+), 45 deletions(-)
> 
...
> diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
> index 11695d5..ff4e3ae 100644
> --- a/drivers/usb/host/ehci-vt8500.c
> +++ b/drivers/usb/host/ehci-vt8500.c
> @@ -16,52 +16,25 @@
...
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_AUTHOR("Alexey Charkov");
> +MODULE_LICENSE("GPL");
Should be "GPL v2" as per the license header.

>  MODULE_ALIAS("platform:vt8500-ehci");
>  MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);

Regards
Tony Prisk


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 08/10] USB: EHCI: make ehci-vt8500 a separate driver
@ 2013-02-07 18:54       ` Tony Prisk
  0 siblings, 0 replies; 716+ messages in thread
From: Tony Prisk @ 2013-02-07 18:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2013-02-07 at 23:04 +0530, manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> Separate the vt8500 host controller driver from ehci-hcd host code
> into its own driver module.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Tony Prisk <linux@prisktech.co.nz>
> Cc: Alexey Charkov <alchark@gmail.com>
> Cc: linux-usb at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  drivers/usb/host/Kconfig       |    8 +++++
>  drivers/usb/host/Makefile      |    1 +
>  drivers/usb/host/ehci-hcd.c    |    5 ---
>  drivers/usb/host/ehci-vt8500.c |   73 ++++++++++++++++++----------------------
>  4 files changed, 42 insertions(+), 45 deletions(-)
> 
...
> diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
> index 11695d5..ff4e3ae 100644
> --- a/drivers/usb/host/ehci-vt8500.c
> +++ b/drivers/usb/host/ehci-vt8500.c
> @@ -16,52 +16,25 @@
...
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_AUTHOR("Alexey Charkov");
> +MODULE_LICENSE("GPL");
Should be "GPL v2" as per the license header.

>  MODULE_ALIAS("platform:vt8500-ehci");
>  MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);

Regards
Tony Prisk

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-07 19:05       ` David Brown
  -1 siblings, 0 replies; 716+ messages in thread
From: David Brown @ 2013-02-07 19:05 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, arnd, gregkh,
	Greg KH, Daniel Walker, Bryan Huntsman, Brian Swetland,
	linux-kernel

manjunath.goudar@linaro.org writes:

> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_ALIAS("platform:omap-msm");
> +MODULE_LICENSE("GPL");

omap-msm?  I think you mean msm-ehci.

I don't have any hardware to test this on, so hopefully someone can
chime in after testing it.

David

-- 
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 09/10] USB: EHCI: make ehci-msm a separate driver
@ 2013-02-07 19:05       ` David Brown
  0 siblings, 0 replies; 716+ messages in thread
From: David Brown @ 2013-02-07 19:05 UTC (permalink / raw)
  To: linux-arm-kernel

manjunath.goudar at linaro.org writes:

> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_ALIAS("platform:omap-msm");
> +MODULE_LICENSE("GPL");

omap-msm?  I think you mean msm-ehci.

I don't have any hardware to test this on, so hopefully someone can
chime in after testing it.

David

-- 
sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-07 19:41       ` Arnd Bergmann
  -1 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-02-07 19:41 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, gregkh, Greg KH,
	Jason Cooper, Andrew Lunn, Russell King, linux-kernel

On Thursday 07 February 2013, manjunath.goudar@linaro.org wrote:
> @@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
>   * before driver shutdown. But it also seems to be caused by bugs in cardbus
>   * bridge shutdown:  shutting down the bridge before the devices using it.
>   */
> -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
> +int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
>                       u32 mask, u32 done, int usec)
>  {
>         u32     result;

I had not noticed this before, but apparently it belongs into the
tegra patch that you dropped, rather than this patch.

Same thing for all the changes below.

> @@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
>         } while (usec > 0);
>         return -ETIMEDOUT;
>  }
> -
> +EXPORT_SYMBOL_GPL(handshake);
>  /* check TDI/ARC silicon is in host mode */
> -static int tdi_in_host_mode (struct ehci_hcd *ehci)
> +static int tdi_in_host_mode(struct ehci_hcd *ehci)
>  {
>         u32             tmp;
>  
> @@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
>   * Force HC to halt state from unknown (EHCI spec section 2.3).
>   * Must be called with interrupts enabled and the lock not held.
>   */
> -static int ehci_halt (struct ehci_hcd *ehci)
> +int ehci_halt(struct ehci_hcd *ehci)
>  {
>         u32     temp;
>  
> @@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
>         return handshake(ehci, &ehci->regs->status,
>                           STS_HALT, STS_HALT, 16 * 125);
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_halt);
>  /* put TDI/ARC silicon into EHCI mode */
> -static void tdi_reset (struct ehci_hcd *ehci)
> +void tdi_reset(struct ehci_hcd *ehci)
>  {
>         u32             tmp;
>  
> @@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
>                 tmp |= USBMODE_BE;
>         ehci_writel(ehci, tmp, &ehci->regs->usbmode);
>  }
> -
> +EXPORT_SYMBOL_GPL(tdi_reset);
>  /*
>   * Reset a non-running (STS_HALT == 1) controller.
>   * Must be called with interrupts enabled and the lock not held.
>   */
> -static int ehci_reset (struct ehci_hcd *ehci)
> +int ehci_reset(struct ehci_hcd *ehci)
>  {
>         int     retval;
>         u32     command = ehci_readl(ehci, &ehci->regs->command);
> @@ -272,7 +272,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
>                         ehci->resuming_ports = 0;
>         return retval;
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_reset);
>  /*
>   * Idle the controller (turn off the schedules).
>   * Must be called with interrupts enabled and the lock not held.
> @@ -352,7 +352,7 @@ static void ehci_silence_controller(struct ehci_hcd *ehci)
>   * This forcibly disables dma and IRQs, helping kexec and other cases
>   * where the next system software may expect clean state.
>   */
> -static void ehci_shutdown(struct usb_hcd *hcd)
> +void ehci_shutdown(struct usb_hcd *hcd)
>  {
>         struct ehci_hcd *ehci = hcd_to_ehci(hcd);
>  
> @@ -366,7 +366,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
>  
>         hrtimer_cancel(&ehci->hrtimer);
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_shutdown);

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
@ 2013-02-07 19:41       ` Arnd Bergmann
  0 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-02-07 19:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 07 February 2013, manjunath.goudar at linaro.org wrote:
> @@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
>   * before driver shutdown. But it also seems to be caused by bugs in cardbus
>   * bridge shutdown:  shutting down the bridge before the devices using it.
>   */
> -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
> +int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
>                       u32 mask, u32 done, int usec)
>  {
>         u32     result;

I had not noticed this before, but apparently it belongs into the
tegra patch that you dropped, rather than this patch.

Same thing for all the changes below.

> @@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
>         } while (usec > 0);
>         return -ETIMEDOUT;
>  }
> -
> +EXPORT_SYMBOL_GPL(handshake);
>  /* check TDI/ARC silicon is in host mode */
> -static int tdi_in_host_mode (struct ehci_hcd *ehci)
> +static int tdi_in_host_mode(struct ehci_hcd *ehci)
>  {
>         u32             tmp;
>  
> @@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
>   * Force HC to halt state from unknown (EHCI spec section 2.3).
>   * Must be called with interrupts enabled and the lock not held.
>   */
> -static int ehci_halt (struct ehci_hcd *ehci)
> +int ehci_halt(struct ehci_hcd *ehci)
>  {
>         u32     temp;
>  
> @@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
>         return handshake(ehci, &ehci->regs->status,
>                           STS_HALT, STS_HALT, 16 * 125);
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_halt);
>  /* put TDI/ARC silicon into EHCI mode */
> -static void tdi_reset (struct ehci_hcd *ehci)
> +void tdi_reset(struct ehci_hcd *ehci)
>  {
>         u32             tmp;
>  
> @@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
>                 tmp |= USBMODE_BE;
>         ehci_writel(ehci, tmp, &ehci->regs->usbmode);
>  }
> -
> +EXPORT_SYMBOL_GPL(tdi_reset);
>  /*
>   * Reset a non-running (STS_HALT == 1) controller.
>   * Must be called with interrupts enabled and the lock not held.
>   */
> -static int ehci_reset (struct ehci_hcd *ehci)
> +int ehci_reset(struct ehci_hcd *ehci)
>  {
>         int     retval;
>         u32     command = ehci_readl(ehci, &ehci->regs->command);
> @@ -272,7 +272,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
>                         ehci->resuming_ports = 0;
>         return retval;
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_reset);
>  /*
>   * Idle the controller (turn off the schedules).
>   * Must be called with interrupts enabled and the lock not held.
> @@ -352,7 +352,7 @@ static void ehci_silence_controller(struct ehci_hcd *ehci)
>   * This forcibly disables dma and IRQs, helping kexec and other cases
>   * where the next system software may expect clean state.
>   */
> -static void ehci_shutdown(struct usb_hcd *hcd)
> +void ehci_shutdown(struct usb_hcd *hcd)
>  {
>         struct ehci_hcd *ehci = hcd_to_ehci(hcd);
>  
> @@ -366,7 +366,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
>  
>         hrtimer_cancel(&ehci->hrtimer);
>  }
> -
> +EXPORT_SYMBOL_GPL(ehci_shutdown);

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 00/10] usb: ehci: more bus glues as separate modules
  2013-02-07 17:33 ` [PATCH 00/10] usb: ehci: more bus glues as separate modules manjunath.goudar at linaro.org
@ 2013-02-07 20:13   ` Ezequiel Garcia
  2013-02-08 15:23   ` Alan Stern
  1 sibling, 0 replies; 716+ messages in thread
From: Ezequiel Garcia @ 2013-02-07 20:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Manjunath,

Nice work.

On Thu, Feb 07, 2013 at 11:03:57PM +0530, manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> 
> Separate the SOC On-Chip host controller driver from ehci-hcd
> host code into its own driver module.

Perhaps you could add a few lines explaining why you're doing this.

> 
> Manjunath Goudar (10):
>   USB:Changed omap2plus_defconfig to support OMAP USB static driver
>   USB: EHCI: make ehci-omap a separate driver
>   USB: EHCI: make ehci-spear a separate driver
>   USB: EHCI: make ehci-orion a separate driver
>   USB: EHCI: make ehci-atmel a separate driver
>   USB: EHCI: make ehci-s5p a separate driver
>   USB: EHCI: make ehci-mv a separate driver
>   USB: EHCI: make ehci-vt8500 a separate driver
>   USB: EHCI: make ehci-msm a separate driver
>   USB: EHCI: make ehci-w90X900 a separate driver
> 
>  arch/arm/configs/omap2plus_defconfig |    4 ++
>  drivers/usb/host/Kconfig             |   43 ++++++++++++---
>  drivers/usb/host/Makefile            |   10 +++-
>  drivers/usb/host/ehci-atmel.c        |   78 ++++++++++++++-------------
>  drivers/usb/host/ehci-hcd.c          |   75 +++++++-------------------
>  drivers/usb/host/ehci-msm.c          |   84 +++++++++++++----------------
>  drivers/usb/host/ehci-mv.c           |   81 +++++++++++++---------------
>  drivers/usb/host/ehci-omap.c         |   69 ++++++++++--------------
>  drivers/usb/host/ehci-orion.c        |   98 +++++++++++++++++-----------------
>  drivers/usb/host/ehci-s5p.c          |   69 +++++++++++++-----------
>  drivers/usb/host/ehci-spear.c        |   77 +++++++++++++-------------
>  drivers/usb/host/ehci-vt8500.c       |   73 ++++++++++++-------------
>  drivers/usb/host/ehci-w90x900.c      |   90 ++++++++++++++-----------------
>  13 files changed, 415 insertions(+), 436 deletions(-)
> 
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Thanks,

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-08  2:58       ` Bo Shen
  -1 siblings, 0 replies; 716+ messages in thread
From: Bo Shen @ 2013-02-08  2:58 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, patches, gregkh, Nicolas Ferre, linux-kernel,
	Rob Herring, Andrew Victor, Grant Likely, stern, Greg KH,
	Jean-Christophe Plagniol-Villard, arnd, linux-arm-kernel

Hi Manjunath Goudar,
   I test this patch based on linux master branch, the commit id is: 
6bacaa9ddacb71c691d32c678d37bc59ffc71fac. (I am not sure this is the 
right place for testing).
   First, it has an compile error as following. After fix it, and 
tested, the EHCI doesn't work.
---<8---
drivers/usb/host/ehci-atmel.c: In function 'ehci_atmel_drv_remove':
drivers/usb/host/ehci-atmel.c:167: error: implicit declaration of 
function 'ehci_shutdown'
--->8---

And a little code style comments as following.

On 2/8/2013 1:34, manjunath.goudar@linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>
> Separate the Atmel host controller driver from ehci-hcd host code
> into its own driver module.
>
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Greg KH <greg@kroah.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Andrew Victor <linux@maxim.org.za>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: linux-usb@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
>   drivers/usb/host/Kconfig      |    7 ++++
>   drivers/usb/host/Makefile     |    1 +
>   drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
>   drivers/usb/host/ehci-hcd.c   |    6 +---
>   4 files changed, 51 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 3689b7b..5a13f9d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
>           ---help---
>             Enables support for the on-chip EHCI controller on
>             Morvell Orion chips.

Need blank line here.

> +config USB_EHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip EHCI USB controller"
> +        depends on USB_EHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip EHCI controller on
> +          Atmel chips.
>
>   config USB_EHCI_MSM
>   	bool "Support for MSM on-chip EHCI USB controller"

[snip]

> +static void __exit ehci_atmel_cleanup(void)
> +{
> +	platform_driver_unregister(&ehci_atmel_driver);
> +}
> +module_exit(ehci_atmel_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> +MODULE_ALIAS("platform:ehci-atmel");
> +MODULE_AUTHOR("Nicolas Ferre");
> +MODULE_LICENSE("GPL");
> +

Remove the blank line here. As to it is the EOF.

Best Regards,
Bo Shen

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
@ 2013-02-08  2:58       ` Bo Shen
  0 siblings, 0 replies; 716+ messages in thread
From: Bo Shen @ 2013-02-08  2:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Manjunath Goudar,
   I test this patch based on linux master branch, the commit id is: 
6bacaa9ddacb71c691d32c678d37bc59ffc71fac. (I am not sure this is the 
right place for testing).
   First, it has an compile error as following. After fix it, and 
tested, the EHCI doesn't work.
---<8---
drivers/usb/host/ehci-atmel.c: In function 'ehci_atmel_drv_remove':
drivers/usb/host/ehci-atmel.c:167: error: implicit declaration of 
function 'ehci_shutdown'
--->8---

And a little code style comments as following.

On 2/8/2013 1:34, manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>
> Separate the Atmel host controller driver from ehci-hcd host code
> into its own driver module.
>
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Greg KH <greg@kroah.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Andrew Victor <linux@maxim.org.za>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: linux-usb at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> ---
>   drivers/usb/host/Kconfig      |    7 ++++
>   drivers/usb/host/Makefile     |    1 +
>   drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
>   drivers/usb/host/ehci-hcd.c   |    6 +---
>   4 files changed, 51 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 3689b7b..5a13f9d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
>           ---help---
>             Enables support for the on-chip EHCI controller on
>             Morvell Orion chips.

Need blank line here.

> +config USB_EHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip EHCI USB controller"
> +        depends on USB_EHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip EHCI controller on
> +          Atmel chips.
>
>   config USB_EHCI_MSM
>   	bool "Support for MSM on-chip EHCI USB controller"

[snip]

> +static void __exit ehci_atmel_cleanup(void)
> +{
> +	platform_driver_unregister(&ehci_atmel_driver);
> +}
> +module_exit(ehci_atmel_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> +MODULE_ALIAS("platform:ehci-atmel");
> +MODULE_AUTHOR("Nicolas Ferre");
> +MODULE_LICENSE("GPL");
> +

Remove the blank line here. As to it is the EOF.

Best Regards,
Bo Shen

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 03/10] USB: EHCI: make ehci-spear a separate driver
  2013-02-07 17:34   ` [PATCH 03/10] USB: EHCI: make ehci-spear " manjunath.goudar at linaro.org
@ 2013-02-08  4:27     ` Viresh Kumar
  0 siblings, 0 replies; 716+ messages in thread
From: Viresh Kumar @ 2013-02-08  4:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 7, 2013 at 11:04 PM,  <manjunath.goudar@linaro.org> wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>
> Separate the Spear host controller driver from ehci-hcd host code
> into its own driver module.

Please write spear as SPEAr everywhere, leaving
functions/variables/config options.

> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Deepak Saxena <dsaxena@linaro.org>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Viresh Kumar <viresh.linux@gmail.com>
> Cc: Shiraz Hashim <shiraz.hashim@st.com>
> Cc: linux-usb at vger.kernel.org
> Cc: spear-devel at list.st.com
> ---
>  drivers/usb/host/Kconfig      |    8 +++++
>  drivers/usb/host/Makefile     |    1 +
>  drivers/usb/host/ehci-hcd.c   |    6 +---
>  drivers/usb/host/ehci-spear.c |   77 ++++++++++++++++++++++-------------------
>  4 files changed, 51 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 11e102e..4413075 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -162,6 +162,14 @@ config USB_EHCI_HCD_OMAP
>           Enables support for the on-chip EHCI controller on
>           OMAP3 and later chips.
>
> +config USB_EHCI_HCD_SPEAR
> +        tristate "Support for ST spear on-chip EHCI USB controller"
> +        depends on USB_EHCI_HCD && PLAT_SPEAR
> +        default y
> +        ---help---
> +          Enables support for the on-chip EHCI controller on
> +          ST spear chips.
> +
>  config USB_EHCI_MSM
>         bool "Support for MSM on-chip EHCI USB controller"
>         depends on USB_EHCI_HCD && ARCH_MSM
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index b54a597..c97f4ab 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_EHCI_PCI)    += ehci-pci.o
>  obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)    += ehci-platform.o
>  obj-$(CONFIG_USB_EHCI_MXC)     += ehci-mxc.o
>  obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
> +obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
>  obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
>  obj-$(CONFIG_USB_ISP116X_HCD)  += isp116x-hcd.o
>  obj-$(CONFIG_USB_ISP1362_HCD)  += isp1362-hcd.o
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index aaf93ca..68cea63 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -1292,11 +1292,6 @@ MODULE_LICENSE ("GPL");
>  #define        PLATFORM_DRIVER         vt8500_ehci_driver
>  #endif
>
> -#ifdef CONFIG_PLAT_SPEAR
> -#include "ehci-spear.c"
> -#define PLATFORM_DRIVER                spear_ehci_hcd_driver
> -#endif
> -
>  #ifdef CONFIG_USB_EHCI_MSM
>  #include "ehci-msm.c"
>  #define PLATFORM_DRIVER                ehci_msm_driver
> @@ -1343,6 +1338,7 @@ MODULE_LICENSE ("GPL");
>         !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \
>         !defined(PLATFORM_DRIVER) && \
>         !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
> +       !IS_ENABLED(CONFIG_PLAT_SPEAR) && \
>         !defined(PS3_SYSTEM_BUS_DRIVER) && \
>         !defined(OF_PLATFORM_DRIVER) && \
>         !defined(XILINX_OF_PLATFORM_DRIVER)
> diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
> index 466c1bb..6e42cee 100644
> --- a/drivers/usb/host/ehci-spear.c
> +++ b/drivers/usb/host/ehci-spear.c
> @@ -11,11 +11,25 @@
>  * more details.
>  */
>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +#include <linux/io.h>
> +
> +

remove these blank lines.

>  #include <linux/clk.h>
>  #include <linux/jiffies.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm.h>
> +#include <linux/dma-mapping.h>


Keep all of them in alphabetical order.

> +#include "ehci.h"
> +
> +#define DRIVER_DESC "EHCI spear driver"
> +
> +static const char hcd_name[] = "ehci-spear";
>
>  struct spear_ehci {
>         struct ehci_hcd ehci;
> @@ -43,40 +57,7 @@ static int ehci_spear_setup(struct usb_hcd *hcd)
>
>         return ehci_setup(hcd);
>  }
> -
> -static const struct hc_driver ehci_spear_hc_driver = {
> -       .description                    = hcd_name,
> -       .product_desc                   = "SPEAr EHCI",
> -       .hcd_priv_size                  = sizeof(struct spear_ehci),
> -
> -       /* generic hardware linkage */
> -       .irq                            = ehci_irq,
> -       .flags                          = HCD_MEMORY | HCD_USB2,
> -
> -       /* basic lifecycle operations */
> -       .reset                          = ehci_spear_setup,
> -       .start                          = ehci_run,
> -       .stop                           = ehci_stop,
> -       .shutdown                       = ehci_shutdown,
> -
> -       /* managing i/o requests and associated device resources */
> -       .urb_enqueue                    = ehci_urb_enqueue,
> -       .urb_dequeue                    = ehci_urb_dequeue,
> -       .endpoint_disable               = ehci_endpoint_disable,
> -       .endpoint_reset                 = ehci_endpoint_reset,
> -
> -       /* scheduling support */
> -       .get_frame_number               = ehci_get_frame,
> -
> -       /* root hub support */
> -       .hub_status_data                = ehci_hub_status_data,
> -       .hub_control                    = ehci_hub_control,
> -       .bus_suspend                    = ehci_bus_suspend,
> -       .bus_resume                     = ehci_bus_resume,
> -       .relinquish_port                = ehci_relinquish_port,
> -       .port_handed_over               = ehci_port_handed_over,
> -       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
> -};
> +static struct hc_driver __read_mostly ehci_spear_hc_driver;
>
>  #ifdef CONFIG_PM
>  static int ehci_spear_drv_suspend(struct device *dev)
> @@ -209,11 +190,35 @@ static struct platform_driver spear_ehci_hcd_driver = {
>         .remove         = spear_ehci_hcd_drv_remove,
>         .shutdown       = usb_hcd_platform_shutdown,
>         .driver         = {
> -               .name = "spear-ehci",
> +               .name = hcd_name,
>                 .bus = &platform_bus_type,
>                 .pm = &ehci_spear_pm_ops,
>                 .of_match_table = of_match_ptr(spear_ehci_id_table),
>         }
>  };
>
> -MODULE_ALIAS("platform:spear-ehci");
> +
> +static const struct ehci_driver_overrides spear_overrides __initdata = {
> +       .reset = ehci_spear_setup,
> +};
> +
> +static int __init ehci_spear_init(void)
> +{
> +       if (usb_disabled())
> +               return -ENODEV;
> +
> +       pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +
> +       ehci_init_driver(&ehci_spear_hc_driver, &spear_overrides);
> +       return platform_driver_register(&spear_ehci_hcd_driver);
> +}
> +module_init(ehci_spear_init);
> +
> +static void __exit ehci_spear_cleanup(void)
> +{
> +       platform_driver_unregister(&spear_ehci_hcd_driver);
> +}
> +module_exit(ehci_spear_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
> --
> 1.7.9.5
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver
  2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
@ 2013-02-08  7:42     ` Felipe Balbi
  2013-02-08  8:56       ` Roger Quadros
  0 siblings, 1 reply; 716+ messages in thread
From: Felipe Balbi @ 2013-02-08  7:42 UTC (permalink / raw)
  To: linux-arm-kernel

HI,

On Thu, Feb 07, 2013 at 11:03:59PM +0530, manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> Separate the OMAP host controller driver from ehci-hcd host code
> into its own driver module.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Signed-off-by: Arnd Bergmann <arnd@linaro.org>
> Cc: Felipe Balbi <balbi@ti.com>
> Cc: Greg KH <greg@kroah.com>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: linux-usb at vger.kernel.org
> Cc: Tony Lindgren <tony@atomide.com>

Alan and Roger have already been working on this for ehci-omap. Their
patches might already be in Greg's queue...

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130208/736d8670/attachment.sig>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver
  2013-02-08  7:42     ` Felipe Balbi
@ 2013-02-08  8:56       ` Roger Quadros
  0 siblings, 0 replies; 716+ messages in thread
From: Roger Quadros @ 2013-02-08  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/08/2013 09:42 AM, Felipe Balbi wrote:
> HI,
> 
> On Thu, Feb 07, 2013 at 11:03:59PM +0530, manjunath.goudar at linaro.org wrote:
>> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>>
>> Separate the OMAP host controller driver from ehci-hcd host code
>> into its own driver module.
>>
>> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
>> Signed-off-by: Arnd Bergmann <arnd@linaro.org>
>> Cc: Felipe Balbi <balbi@ti.com>
>> Cc: Greg KH <greg@kroah.com>
>> Cc: Alan Stern <stern@rowland.harvard.edu>
>> Cc: linux-usb at vger.kernel.org
>> Cc: Tony Lindgren <tony@atomide.com>
> 
> Alan and Roger have already been working on this for ehci-omap. Their
> patches might already be in Greg's queue...
> 

Manjunath,

ehci-omap will be taken care of so in [1] so you can please skip it
from your patches. Thanks.

cheers,
-roger

[1] https://patchwork.kernel.org/patch/2055131/

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-02-08 10:38       ` Florian Fainelli
  -1 siblings, 0 replies; 716+ messages in thread
From: Florian Fainelli @ 2013-02-08 10:38 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, arnd, gregkh,
	Greg KH, Jason Cooper, Andrew Lunn, Russell King, linux-kernel

Hello Manjunath,

On 02/07/2013 06:34 PM, manjunath.goudar@linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>
> Separate the Marvell Orion host controller driver from ehci-hcd host code
> into its own driver module.
>
[snip]

The changes you introduce in ehci-hcd.c would certainly deserve their 
own preliminary patch in this serie and not be squashed into this one imho.

> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
>    * before driver shutdown. But it also seems to be caused by bugs in cardbus
>    * bridge shutdown:  shutting down the bridge before the devices using it.
>    */
> -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
> +int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
>   		      u32 mask, u32 done, int usec)
>   {
>   	u32	result;
> @@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
>   	} while (usec > 0);
>   	return -ETIMEDOUT;
>   }
> -
> +EXPORT_SYMBOL_GPL(handshake);

This sounds way too generic as a name to be exported as is, so please 
namespace this with ehci_hcd_ at least.

>   /* check TDI/ARC silicon is in host mode */
> -static int tdi_in_host_mode (struct ehci_hcd *ehci)
> +static int tdi_in_host_mode(struct ehci_hcd *ehci)

Looks unrelated to the goals of your patches.

>   {
>   	u32		tmp;
>
> @@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
>    * Force HC to halt state from unknown (EHCI spec section 2.3).
>    * Must be called with interrupts enabled and the lock not held.
>    */
> -static int ehci_halt (struct ehci_hcd *ehci)
> +int ehci_halt(struct ehci_hcd *ehci)
>   {
>   	u32	temp;
>
> @@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
>   	return handshake(ehci, &ehci->regs->status,
>   			  STS_HALT, STS_HALT, 16 * 125);
>   }
> -
> +EXPORT_SYMBOL_GPL(ehci_halt);

I would rename this to ehci_hcd_halt to express the fact that it takes 
an ehci_hcd structure pointer as parameter, can be addressed later.

>   /* put TDI/ARC silicon into EHCI mode */
> -static void tdi_reset (struct ehci_hcd *ehci)
> +void tdi_reset(struct ehci_hcd *ehci)
>   {
>   	u32		tmp;
>
> @@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
>   		tmp |= USBMODE_BE;
>   	ehci_writel(ehci, tmp, &ehci->regs->usbmode);
>   }
> -
> +EXPORT_SYMBOL_GPL(tdi_reset);

Same here, way too generic to be exported as is as a symbol name.
--
Florian

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 04/10] USB: EHCI: make ehci-orion a separate driver
@ 2013-02-08 10:38       ` Florian Fainelli
  0 siblings, 0 replies; 716+ messages in thread
From: Florian Fainelli @ 2013-02-08 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Manjunath,

On 02/07/2013 06:34 PM, manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
>
> Separate the Marvell Orion host controller driver from ehci-hcd host code
> into its own driver module.
>
[snip]

The changes you introduce in ehci-hcd.c would certainly deserve their 
own preliminary patch in this serie and not be squashed into this one imho.

> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -155,7 +155,7 @@ static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
>    * before driver shutdown. But it also seems to be caused by bugs in cardbus
>    * bridge shutdown:  shutting down the bridge before the devices using it.
>    */
> -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
> +int handshake(struct ehci_hcd *ehci, void __iomem *ptr,
>   		      u32 mask, u32 done, int usec)
>   {
>   	u32	result;
> @@ -172,9 +172,9 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
>   	} while (usec > 0);
>   	return -ETIMEDOUT;
>   }
> -
> +EXPORT_SYMBOL_GPL(handshake);

This sounds way too generic as a name to be exported as is, so please 
namespace this with ehci_hcd_ at least.

>   /* check TDI/ARC silicon is in host mode */
> -static int tdi_in_host_mode (struct ehci_hcd *ehci)
> +static int tdi_in_host_mode(struct ehci_hcd *ehci)

Looks unrelated to the goals of your patches.

>   {
>   	u32		tmp;
>
> @@ -186,7 +186,7 @@ static int tdi_in_host_mode (struct ehci_hcd *ehci)
>    * Force HC to halt state from unknown (EHCI spec section 2.3).
>    * Must be called with interrupts enabled and the lock not held.
>    */
> -static int ehci_halt (struct ehci_hcd *ehci)
> +int ehci_halt(struct ehci_hcd *ehci)
>   {
>   	u32	temp;
>
> @@ -215,9 +215,9 @@ static int ehci_halt (struct ehci_hcd *ehci)
>   	return handshake(ehci, &ehci->regs->status,
>   			  STS_HALT, STS_HALT, 16 * 125);
>   }
> -
> +EXPORT_SYMBOL_GPL(ehci_halt);

I would rename this to ehci_hcd_halt to express the fact that it takes 
an ehci_hcd structure pointer as parameter, can be addressed later.

>   /* put TDI/ARC silicon into EHCI mode */
> -static void tdi_reset (struct ehci_hcd *ehci)
> +void tdi_reset(struct ehci_hcd *ehci)
>   {
>   	u32		tmp;
>
> @@ -231,12 +231,12 @@ static void tdi_reset (struct ehci_hcd *ehci)
>   		tmp |= USBMODE_BE;
>   	ehci_writel(ehci, tmp, &ehci->regs->usbmode);
>   }
> -
> +EXPORT_SYMBOL_GPL(tdi_reset);

Same here, way too generic to be exported as is as a symbol name.
--
Florian

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 00/10] usb: ehci: more bus glues as separate modules
  2013-02-07 17:33 ` [PATCH 00/10] usb: ehci: more bus glues as separate modules manjunath.goudar at linaro.org
  2013-02-07 20:13   ` Ezequiel Garcia
@ 2013-02-08 15:23   ` Alan Stern
  1 sibling, 0 replies; 716+ messages in thread
From: Alan Stern @ 2013-02-08 15:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 7 Feb 2013 manjunath.goudar at linaro.org wrote:

> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> 
> Separate the SOC On-Chip host controller driver from ehci-hcd
> host code into its own driver module.
> 
> Manjunath Goudar (10):
>   USB:Changed omap2plus_defconfig to support OMAP USB static driver
>   USB: EHCI: make ehci-omap a separate driver
>   USB: EHCI: make ehci-spear a separate driver
>   USB: EHCI: make ehci-orion a separate driver
>   USB: EHCI: make ehci-atmel a separate driver
>   USB: EHCI: make ehci-s5p a separate driver
>   USB: EHCI: make ehci-mv a separate driver
>   USB: EHCI: make ehci-vt8500 a separate driver
>   USB: EHCI: make ehci-msm a separate driver
>   USB: EHCI: make ehci-w90X900 a separate driver

I'm going on vacation for a week, so I won't be able to review these 
right away.  If you want to submit updated patches based on feedback 
from other people, go right ahead.

Alan Stern

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware
       [not found] <yes>
                   ` (66 preceding siblings ...)
       [not found] ` <1360258447-27247-1-git-send-email-yes>
@ 2013-03-09 15:39 ` John Weber
  2013-03-09 19:05   ` Otavio Salvador
  2013-03-12 19:16 ` [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README John Weber
                   ` (23 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-09 15:39 UTC (permalink / raw)
  To: meta-freescale


Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 conf/machine/include/imx-base.inc |    1 +
 1 file changed, 1 insertion(+)

diff --git a/conf/machine/include/imx-base.inc b/conf/machine/include/imx-base.inc
index dd7948b..743474c 100644
--- a/conf/machine/include/imx-base.inc
+++ b/conf/machine/include/imx-base.inc
@@ -36,6 +36,7 @@ MACHINE_EXTRA_RRECOMMENDS = "kernel-modules"
 MACHINE_FIRMWARE ?= ""
 MACHINE_FIRMWARE_mx6q = "firmware-imx-vpu-imx6q"
 MACHINE_FIRMWARE_mx6d = "firmware-imx-vpu-imx6d"
+MACHINE_FIRMWARE_mx6dl = "firmware-imx-vpu-imx6d"
 MACHINE_FIRMWARE_mx53 = "firmware-imx-vpu-imx53 firmware-imx-sdma-imx53"
 MACHINE_FIRMWARE_mx51 = "firmware-imx-vpu-imx51 firmware-imx-sdma-imx51"
 MACHINE_FIRMWARE_mx35 = "firmware-imx-sdma-imx35"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware
  2013-03-09 15:39 ` [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware John Weber
@ 2013-03-09 19:05   ` Otavio Salvador
  0 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-09 19:05 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 9, 2013 at 12:39 PM, John Weber <rjohnweber@gmail.com> wrote:
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

Applied.

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README
       [not found] <yes>
                   ` (67 preceding siblings ...)
  2013-03-09 15:39 ` [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware John Weber
@ 2013-03-12 19:16 ` John Weber
  2013-03-12 19:20   ` Otavio Salvador
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
                   ` (22 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-12 19:16 UTC (permalink / raw)
  To: meta-freescale


Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 README |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README b/README
index 5585b08..7118882 100644
--- a/README
+++ b/README
@@ -37,7 +37,7 @@ processors:
    * Freescale i.MX6Q SABRE Lite (imx6qsabrelite)
    * Freescale i.MX6Q SABRE SD (imx6qsabresd)
    * Boundary Devices Nitrogen6X (nitrogen6x)
-
+   * Wandboard.org Wandboard Dual (wandboard-dual)
 
 Quick Start Guide
 -----------------
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README
  2013-03-12 19:16 ` [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README John Weber
@ 2013-03-12 19:20   ` Otavio Salvador
  0 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-12 19:20 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Tue, Mar 12, 2013 at 4:16 PM, John Weber <rjohnweber@gmail.com> wrote:
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

Applied.

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data
       [not found] <yes>
                   ` (68 preceding siblings ...)
  2013-03-12 19:16 ` [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README John Weber
@ 2013-03-16 13:45 ` John Weber
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
                     ` (6 more replies)
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
                   ` (21 subsequent siblings)
  91 siblings, 7 replies; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Fixes esdhc platform data for wandboard dual.  Without this fix, 
wandboard-dual is unable to load firmware from the filesystem into
the kernel.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ...002-wandboard-dual-fix-sdhc-platform-data.patch |   53 ++++++++++++++++++++
 1 files changed, 56 insertions(+), 2 deletions(-)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
new file mode 100644
index 0000000..3aefebe
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
@@ -0,0 +1,53 @@
+From ea530483ad42e5b9a89934fbdfd57df81b3a90ab Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Fri, 15 Mar 2013 08:43:15 -0500
+Subject: [PATCH] wandboard: fix sdhc platform data
+
+Fixes sdhc platfrom data structure to solve a problem when loading
+the firmware files for the on-board Wifi module on Wandboard-dual.
+This problem only occured when udev is tasked with loading firmware
+from the filesystem.
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ arch/arm/mach-mx6/board-wand.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-mx6/board-wand.c b/arch/arm/mach-mx6/board-wand.c
+index 7f972eb..7be6726 100644
+--- a/arch/arm/mach-mx6/board-wand.c
++++ b/arch/arm/mach-mx6/board-wand.c
+@@ -184,13 +184,17 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
+ 		.cd_gpio		= WAND_SD1_CD,
+ 		.wp_gpio		=-EINVAL,
+ 		.keep_power_at_suspend	= 1,
+-	        .support_8bit		= 0,
++	  .support_8bit		= 0,
++	  .delay_line = 0,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.cd_type = ESDHC_CD_CONTROLLER,
+ 	}, {
+-		.cd_gpio		=-EINVAL,
+-		.wp_gpio		=-EINVAL,
+ 		.keep_power_at_suspend	= 1,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.always_present = 1,
++		.support_8bit = 0,
++		.delay_line = 0,
++		.cd_type = ESDHC_CD_PERMANENT,
+ 	}, {
+ 		.cd_gpio		= WAND_SD3_CD,
+ 		.wp_gpio		= WAND_SD3_WP,
+@@ -198,6 +202,7 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
+ 		.support_8bit		= 0,
+ 		.delay_line		= 0,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.cd_type = ESDHC_CD_CONTROLLER,
+ 	}
+ };
+ 
+-- 
+1.7.9.5
+
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 14:39     ` Otavio Salvador
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): add brcm80211 driver backported from v3.5 John Weber
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Removes brcm80211 driver in drivers/staging.  This is meant to be
applied with a patch to add a backported driver from kernel v3.5
which is loaded into drivers/net/wireless.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ...mx-3.0.35-remove-brcm80211-staging-driver.patch |123141 ++++++++++++++++++++
 1 files changed, 123142 insertions(+)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
new file mode 100644
index 0000000..96d3ce1
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
@@ -0,0 +1,123141 @@
+From 748eb185cad62c456dcd316c941f9835520a946d Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Sat, 9 Mar 2013 09:23:58 -0600
+Subject: [meta-fsl-arm-extra][PATCH 1/2] linux-imx (3.0.35): remove brcm80211
+ staging driver
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ drivers/staging/Kconfig                            |    2 -
+ drivers/staging/Makefile                           |    2 -
+ drivers/staging/brcm80211/Kconfig                  |   40 -
+ drivers/staging/brcm80211/Makefile                 |   24 -
+ drivers/staging/brcm80211/README                   |   64 -
+ drivers/staging/brcm80211/TODO                     |   15 -
+ drivers/staging/brcm80211/brcmfmac/Makefile        |   56 -
+ drivers/staging/brcm80211/brcmfmac/README          |    2 -
+ drivers/staging/brcm80211/brcmfmac/aiutils.c       |    1 -
+ drivers/staging/brcm80211/brcmfmac/bcmcdc.h        |   98 -
+ drivers/staging/brcm80211/brcmfmac/bcmchip.h       |   35 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdbus.h      |  113 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh.c        |  631 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c  |  386 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c  | 1239 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h  |  134 -
+ .../brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c        |  235 -
+ drivers/staging/brcm80211/brcmfmac/dhd.h           |  414 -
+ drivers/staging/brcm80211/brcmfmac/dhd_bus.h       |   82 -
+ drivers/staging/brcm80211/brcmfmac/dhd_cdc.c       |  474 -
+ drivers/staging/brcm80211/brcmfmac/dhd_common.c    | 1848 --
+ .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c   |  158 -
+ drivers/staging/brcm80211/brcmfmac/dhd_dbg.h       |  103 -
+ drivers/staging/brcm80211/brcmfmac/dhd_linux.c     | 2862 --
+ .../staging/brcm80211/brcmfmac/dhd_linux_sched.c   |   25 -
+ drivers/staging/brcm80211/brcmfmac/dhd_proto.h     |   90 -
+ drivers/staging/brcm80211/brcmfmac/dhd_sdio.c      | 6390 -----
+ drivers/staging/brcm80211/brcmfmac/dhdioctl.h      |  100 -
+ drivers/staging/brcm80211/brcmfmac/dngl_stats.h    |   32 -
+ .../staging/brcm80211/brcmfmac/hndrte_armtrap.h    |   75 -
+ drivers/staging/brcm80211/brcmfmac/hndrte_cons.h   |   62 -
+ drivers/staging/brcm80211/brcmfmac/msgtrace.h      |   61 -
+ drivers/staging/brcm80211/brcmfmac/sdioh.h         |   63 -
+ drivers/staging/brcm80211/brcmfmac/sdiovar.h       |   38 -
+ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c   | 4428 ---
+ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h   |  414 -
+ drivers/staging/brcm80211/brcmfmac/wl_iw.c         | 3693 ---
+ drivers/staging/brcm80211/brcmfmac/wl_iw.h         |  142 -
+ drivers/staging/brcm80211/brcmsmac/Makefile        |   59 -
+ drivers/staging/brcm80211/brcmsmac/aiutils.c       | 2054 --
+ drivers/staging/brcm80211/brcmsmac/aiutils.h       |  546 -
+ drivers/staging/brcm80211/brcmsmac/bcmotp.c        |  936 -
+ drivers/staging/brcm80211/brcmsmac/bcmsrom.c       |  714 -
+ drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h   |  513 -
+ drivers/staging/brcm80211/brcmsmac/d11.h           | 1773 --
+ drivers/staging/brcm80211/brcmsmac/hnddma.c        | 1756 --
+ drivers/staging/brcm80211/brcmsmac/nicpci.c        |  836 -
+ drivers/staging/brcm80211/brcmsmac/nvram.c         |  215 -
+ .../staging/brcm80211/brcmsmac/phy/phy_version.h   |   36 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c   | 3307 ---
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h   |  256 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_int.h   | 1226 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c   | 5302 ----
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h   |  119 -
+ drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c |29169 --------------------
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c |  296 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h |   40 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h | 1533 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h  |  167 -
+ .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c        | 3639 ---
+ .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h        |   49 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c  |10632 -------
+ .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h  |   39 -
+ drivers/staging/brcm80211/brcmsmac/wl_dbg.h        |   92 -
+ drivers/staging/brcm80211/brcmsmac/wl_export.h     |   47 -
+ drivers/staging/brcm80211/brcmsmac/wl_mac80211.c   | 1942 --
+ drivers/staging/brcm80211/brcmsmac/wl_mac80211.h   |   85 -
+ drivers/staging/brcm80211/brcmsmac/wl_ucode.h      |   49 -
+ .../staging/brcm80211/brcmsmac/wl_ucode_loader.c   |  111 -
+ drivers/staging/brcm80211/brcmsmac/wlc_alloc.c     |  300 -
+ drivers/staging/brcm80211/brcmsmac/wlc_alloc.h     |   18 -
+ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c     | 1253 -
+ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h     |   29 -
+ drivers/staging/brcm80211/brcmsmac/wlc_antsel.c    |  320 -
+ drivers/staging/brcm80211/brcmsmac/wlc_antsel.h    |   29 -
+ drivers/staging/brcm80211/brcmsmac/wlc_bmac.c      | 3602 ---
+ drivers/staging/brcm80211/brcmsmac/wlc_bmac.h      |  179 -
+ drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h    |  135 -
+ drivers/staging/brcm80211/brcmsmac/wlc_cfg.h       |  280 -
+ drivers/staging/brcm80211/brcmsmac/wlc_channel.c   | 1557 --
+ drivers/staging/brcm80211/brcmsmac/wlc_channel.h   |  120 -
+ drivers/staging/brcm80211/brcmsmac/wlc_key.h       |  140 -
+ drivers/staging/brcm80211/brcmsmac/wlc_main.c      | 7537 -----
+ drivers/staging/brcm80211/brcmsmac/wlc_main.h      |  939 -
+ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c  |  243 -
+ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h  |  112 -
+ drivers/staging/brcm80211/brcmsmac/wlc_pmu.c       | 1929 --
+ drivers/staging/brcm80211/brcmsmac/wlc_pmu.h       |   58 -
+ drivers/staging/brcm80211/brcmsmac/wlc_pub.h       |  584 -
+ drivers/staging/brcm80211/brcmsmac/wlc_rate.c      |  499 -
+ drivers/staging/brcm80211/brcmsmac/wlc_rate.h      |  169 -
+ drivers/staging/brcm80211/brcmsmac/wlc_scb.h       |   80 -
+ drivers/staging/brcm80211/brcmsmac/wlc_stf.c       |  523 -
+ drivers/staging/brcm80211/brcmsmac/wlc_stf.h       |   38 -
+ drivers/staging/brcm80211/brcmsmac/wlc_types.h     |   37 -
+ drivers/staging/brcm80211/include/aidmp.h          |  374 -
+ drivers/staging/brcm80211/include/bcmdefs.h        |  150 -
+ drivers/staging/brcm80211/include/bcmdevs.h        |  124 -
+ drivers/staging/brcm80211/include/bcmnvram.h       |  153 -
+ drivers/staging/brcm80211/include/bcmotp.h         |   44 -
+ drivers/staging/brcm80211/include/bcmsdh.h         |  205 -
+ drivers/staging/brcm80211/include/bcmsdpcm.h       |  208 -
+ drivers/staging/brcm80211/include/bcmsrom.h        |   34 -
+ drivers/staging/brcm80211/include/bcmsrom_fmt.h    |  367 -
+ drivers/staging/brcm80211/include/bcmutils.h       |  500 -
+ drivers/staging/brcm80211/include/bcmwifi.h        |  167 -
+ drivers/staging/brcm80211/include/hnddma.h         |  226 -
+ drivers/staging/brcm80211/include/hndsoc.h         |  199 -
+ drivers/staging/brcm80211/include/nicpci.h         |   79 -
+ drivers/staging/brcm80211/include/pci_core.h       |  122 -
+ drivers/staging/brcm80211/include/pcicfg.h         |   50 -
+ drivers/staging/brcm80211/include/pcie_core.h      |  299 -
+ drivers/staging/brcm80211/include/proto/802.11.h   |  200 -
+ drivers/staging/brcm80211/include/proto/bcmeth.h   |   44 -
+ drivers/staging/brcm80211/include/proto/bcmevent.h |  207 -
+ drivers/staging/brcm80211/include/sbchipc.h        | 1588 --
+ drivers/staging/brcm80211/include/sbconfig.h       |  272 -
+ drivers/staging/brcm80211/include/sbhnddma.h       |  315 -
+ drivers/staging/brcm80211/include/sbsdio.h         |  152 -
+ drivers/staging/brcm80211/include/sbsdpcmdev.h     |  281 -
+ drivers/staging/brcm80211/include/sdio.h           |  552 -
+ drivers/staging/brcm80211/include/wlioctl.h        | 1365 -
+ drivers/staging/brcm80211/util/Makefile            |   29 -
+ drivers/staging/brcm80211/util/bcmutils.c          |  796 -
+ drivers/staging/brcm80211/util/bcmwifi.c           |  137 -
+ 125 files changed, 122118 deletions(-)
+ delete mode 100644 drivers/staging/brcm80211/Kconfig
+ delete mode 100644 drivers/staging/brcm80211/Makefile
+ delete mode 100644 drivers/staging/brcm80211/README
+ delete mode 100644 drivers/staging/brcm80211/TODO
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/Makefile
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/README
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/aiutils.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmcdc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmchip.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_bus.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_common.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_proto.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhdioctl.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dngl_stats.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/msgtrace.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/sdioh.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/sdiovar.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/Makefile
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/aiutils.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/aiutils.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmotp.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmsrom.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/d11.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/hnddma.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/nicpci.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/nvram.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_dbg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_export.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_key.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pub.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_scb.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_types.h
+ delete mode 100644 drivers/staging/brcm80211/include/aidmp.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmdefs.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmdevs.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmnvram.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmotp.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsdh.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsdpcm.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsrom.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsrom_fmt.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmutils.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmwifi.h
+ delete mode 100644 drivers/staging/brcm80211/include/hnddma.h
+ delete mode 100644 drivers/staging/brcm80211/include/hndsoc.h
+ delete mode 100644 drivers/staging/brcm80211/include/nicpci.h
+ delete mode 100644 drivers/staging/brcm80211/include/pci_core.h
+ delete mode 100644 drivers/staging/brcm80211/include/pcicfg.h
+ delete mode 100644 drivers/staging/brcm80211/include/pcie_core.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/802.11.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/bcmeth.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/bcmevent.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbchipc.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbconfig.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbhnddma.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbsdio.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbsdpcmdev.h
+ delete mode 100644 drivers/staging/brcm80211/include/sdio.h
+ delete mode 100644 drivers/staging/brcm80211/include/wlioctl.h
+ delete mode 100644 drivers/staging/brcm80211/util/Makefile
+ delete mode 100644 drivers/staging/brcm80211/util/bcmutils.c
+ delete mode 100644 drivers/staging/brcm80211/util/bcmwifi.c
+
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+index 196284d..f73909f 100644
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -48,8 +48,6 @@ source "drivers/staging/wlan-ng/Kconfig"
+ 
+ source "drivers/staging/echo/Kconfig"
+ 
+-source "drivers/staging/brcm80211/Kconfig"
+-
+ source "drivers/staging/comedi/Kconfig"
+ 
+ source "drivers/staging/olpc_dcon/Kconfig"
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
+index fa41b9c..482897c 100644
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -16,8 +16,6 @@ obj-$(CONFIG_USBIP_CORE)	+= usbip/
+ obj-$(CONFIG_W35UND)		+= winbond/
+ obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
+ obj-$(CONFIG_ECHO)		+= echo/
+-obj-$(CONFIG_BRCMSMAC)		+= brcm80211/
+-obj-$(CONFIG_BRCMFMAC)		+= brcm80211/
+ obj-$(CONFIG_COMEDI)		+= comedi/
+ obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
+ obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
+diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig
+deleted file mode 100644
+index 379cf16..0000000
+--- a/drivers/staging/brcm80211/Kconfig
++++ /dev/null
+@@ -1,40 +0,0 @@
+-config BRCMUTIL
+-	tristate
+-	default n
+-
+-config BRCMSMAC
+-	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
+-	default n
+-	depends on PCI
+-	depends on WLAN && MAC80211
+-	depends on X86 || MIPS
+-	select BRCMUTIL
+-	select FW_LOADER
+-	select CRC_CCITT
+-	---help---
+-	  This module adds support for PCIe wireless adapters based on Broadcom
+-	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
+-	  be called brcmsmac.ko.
+-
+-config BRCMFMAC
+-	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
+-	default n
+-	depends on MMC
+-	depends on WLAN && CFG80211
+-	depends on X86 || MIPS
+-	select BRCMUTIL
+-	select FW_LOADER
+-	select WIRELESS_EXT
+-	select WEXT_PRIV
+-	---help---
+-	  This module adds support for embedded wireless adapters based on
+-	  Broadcom IEEE802.11n FullMAC chipsets.  This driver uses the kernel's
+-	  wireless extensions subsystem.  If you choose to build a module,
+-	  it'll be called brcmfmac.ko.
+-
+-config BRCMDBG
+-	bool "Broadcom driver debug functions"
+-	default n
+-	depends on BRCMSMAC || BRCMFMAC
+-	---help---
+-	  Selecting this enables additional code for debug purposes.
+diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile
+deleted file mode 100644
+index e7b3f27..0000000
+--- a/drivers/staging/brcm80211/Makefile
++++ /dev/null
+@@ -1,24 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-# common flags
+-subdir-ccflags-y					:= -DBCMDMA32
+-subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DBCMDBG -DBCMDBG_ASSERT
+-
+-obj-$(CONFIG_BRCMUTIL)	+= util/
+-obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
+-obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
+diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
+deleted file mode 100644
+index 8ad5586..0000000
+--- a/drivers/staging/brcm80211/README
++++ /dev/null
+@@ -1,64 +0,0 @@
+-Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers.
+-
+-Completely open source host drivers, no binary object files.
+-
+-Support for the following chips:
+-===============================
+-
+-    brcmsmac (PCIe)
+-    Name        Device ID
+-    BCM4313     0x4727
+-    BCM43224    0x4353
+-    BCM43225    0x4357
+-
+-    brcmfmac (SDIO)
+-    Name
+-    BCM4329
+-
+-Both brcmsmac and brcmfmac drivers require firmware files that need to be
+-separately downloaded.
+-
+-Firmware
+-======================
+-Firmware is available from the Linux firmware repository at:
+-
+-    git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
+-    http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+-    https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+-
+-
+-===============================================================
+-Broadcom brcmsmac driver
+-===============================================================
+-- Support for both 32 and 64 bit Linux kernels
+-
+-
+-Firmware installation
+-======================
+-Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to
+-/lib/firmware/brcm (or wherever firmware is normally installed
+-on your system).
+-
+-
+-===============================================================
+-Broadcom brcmfmac driver
+-===============================================================
+-- Support for 32 bit Linux kernel, 64 bit untested
+-
+-
+-Firmware installation
+-======================
+-Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt
+-to /lib/firmware/brcm (or wherever firmware is normally installed on your
+-system).
+-
+-
+-Contact Info:
+-=============
+-Brett Rudley		brudley@broadcom.com
+-Henry Ptasinski		henryp@broadcom.com
+-Dowan Kim		dowan@broadcom.com
+-Roland Vossen		rvossen@broadcom.com
+-Arend van Spriel	arend@broadcom.com
+-
+-For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
+diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
+deleted file mode 100644
+index e9c1393..0000000
+--- a/drivers/staging/brcm80211/TODO
++++ /dev/null
+@@ -1,15 +0,0 @@
+-To Do List for Broadcom Mac80211 driver before getting in mainline
+-
+-Bugs
+-====
+-- Oops on AMPDU traffic, to be solved by new ucode (currently under test)
+-
+-brcmfmac and brcmsmac
+-=====================
+-- ASSERTS not allowed in mainline, replace by warning + error handling
+-- Replace printk and WL_ERROR() with proper routines
+-
+-brcmfmac
+-=====================
+-- Replace driver's proprietary ssb interface with generic kernel ssb module
+-- Build and test on 64 bit linux kernel
+diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile
+deleted file mode 100644
+index c5ec562..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/Makefile
++++ /dev/null
+@@ -1,56 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=			\
+-	-DARP_OFFLOAD_SUPPORT	\
+-	-DBCMLXSDMMC		\
+-	-DBCMPLATFORM_BUS	\
+-	-DBCMSDIO		\
+-	-DBDC			\
+-	-DBRCM_FULLMAC		\
+-	-DDHD_FIRSTREAD=64	\
+-	-DDHD_SCHED		\
+-	-DDHD_SDALIGN=64	\
+-	-DEMBEDDED_PLATFORM	\
+-	-DMAX_HDR_READ=64	\
+-	-DMMC_SDIO_ABORT	\
+-	-DPKT_FILTER_SUPPORT	\
+-	-DSHOW_EVENTS		\
+-	-DTOE
+-
+-ccflags-$(CONFIG_BRCMDBG)	+= -DDHD_DEBUG
+-
+-ccflags-y += \
+-	-Idrivers/staging/brcm80211/brcmfmac	\
+-	-Idrivers/staging/brcm80211/include
+-
+-DHDOFILES = \
+-	wl_cfg80211.o \
+-	wl_iw.o \
+-	dhd_cdc.o \
+-	dhd_common.o \
+-	dhd_custom_gpio.o \
+-	dhd_sdio.o	\
+-	dhd_linux.o \
+-	dhd_linux_sched.o \
+-	bcmsdh.o \
+-	bcmsdh_linux.o	\
+-	bcmsdh_sdmmc.o \
+-	bcmsdh_sdmmc_linux.o
+-
+-obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
+-brcmfmac-objs += $(DHDOFILES)
+diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README
+deleted file mode 100644
+index 139597f..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/README
++++ /dev/null
+@@ -1,2 +0,0 @@
+-
+-
+diff --git a/drivers/staging/brcm80211/brcmfmac/aiutils.c b/drivers/staging/brcm80211/brcmfmac/aiutils.c
+deleted file mode 100644
+index e648086..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/aiutils.c
++++ /dev/null
+@@ -1 +0,0 @@
+-#include "../util/aiutils.c"
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h b/drivers/staging/brcm80211/brcmfmac/bcmcdc.h
+deleted file mode 100644
+index ed4c4a5..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/if_ether.h>
+-
+-typedef struct cdc_ioctl {
+-	u32 cmd;		/* ioctl command value */
+-	u32 len;		/* lower 16: output buflen; upper 16:
+-				 input buflen (excludes header) */
+-	u32 flags;		/* flag defns given below */
+-	u32 status;		/* status code returned from the device */
+-} cdc_ioctl_t;
+-
+-/* Max valid buffer size that can be sent to the dongle */
+-#define CDC_MAX_MSG_SIZE	(ETH_FRAME_LEN+ETH_FCS_LEN)
+-
+-/* len field is divided into input and output buffer lengths */
+-#define CDCL_IOC_OUTLEN_MASK   0x0000FFFF	/* maximum or expected
+-						 response length, */
+-					   /* excluding IOCTL header */
+-#define CDCL_IOC_OUTLEN_SHIFT  0
+-#define CDCL_IOC_INLEN_MASK    0xFFFF0000	/* input buffer length,
+-						 excluding IOCTL header */
+-#define CDCL_IOC_INLEN_SHIFT   16
+-
+-/* CDC flag definitions */
+-#define CDCF_IOC_ERROR		0x01	/* 0=success, 1=ioctl cmd failed */
+-#define CDCF_IOC_SET		0x02	/* 0=get, 1=set cmd */
+-#define CDCF_IOC_IF_MASK	0xF000	/* I/F index */
+-#define CDCF_IOC_IF_SHIFT	12
+-#define CDCF_IOC_ID_MASK	0xFFFF0000	/* used to uniquely id an ioctl
+-						 req/resp pairing */
+-#define CDCF_IOC_ID_SHIFT	16	/* # of bits of shift for ID Mask */
+-
+-#define CDC_IOC_IF_IDX(flags)	\
+-	(((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)
+-#define CDC_IOC_ID(flags)	\
+-	(((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
+-
+-#define CDC_GET_IF_IDX(hdr) \
+-	((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT))
+-#define CDC_SET_IF_IDX(hdr, idx) \
+-	((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
+-	((idx) << CDCF_IOC_IF_SHIFT)))
+-
+-/*
+- * BDC header
+- *
+- *   The BDC header is used on data packets to convey priority across USB.
+- */
+-
+-#define	BDC_HEADER_LEN		4
+-
+-#define BDC_PROTO_VER		1	/* Protocol version */
+-
+-#define BDC_FLAG_VER_MASK	0xf0	/* Protocol version mask */
+-#define BDC_FLAG_VER_SHIFT	4	/* Protocol version shift */
+-
+-#define BDC_FLAG__UNUSED	0x03	/* Unassigned */
+-#define BDC_FLAG_SUM_GOOD	0x04	/* Dongle has verified good
+-					 RX checksums */
+-#define BDC_FLAG_SUM_NEEDED	0x08	/* Dongle needs to do TX checksums */
+-
+-#define BDC_PRIORITY_MASK	0x7
+-
+-#define BDC_FLAG2_FC_FLAG	0x10	/* flag to indicate if pkt contains */
+-						/* FLOW CONTROL info only */
+-#define BDC_PRIORITY_FC_SHIFT	4	/* flow control info shift */
+-
+-#define BDC_FLAG2_IF_MASK	0x0f	/* APSTA: interface on which the
+-					 packet was received */
+-#define BDC_FLAG2_IF_SHIFT	0
+-
+-#define BDC_GET_IF_IDX(hdr) \
+-	((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
+-#define BDC_SET_IF_IDX(hdr, idx) \
+-	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
+-	((idx) << BDC_FLAG2_IF_SHIFT)))
+-
+-struct bdc_header {
+-	u8 flags;		/* Flags */
+-	u8 priority;		/* 802.1d Priority 0:2 bits, 4:7 flow
+-				 control info for usb */
+-	u8 flags2;
+-	u8 rssi;
+-};
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmchip.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h
+deleted file mode 100644
+index c0d4c3b..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmchip.h
++++ /dev/null
+@@ -1,35 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _bcmchip_h_
+-#define _bcmchip_h_
+-
+-/* Core reg address translation */
+-#define CORE_CC_REG(base, field)	(base + offsetof(chipcregs_t, field))
+-#define CORE_BUS_REG(base, field)	(base + offsetof(sdpcmd_regs_t, field))
+-#define CORE_SB(base, field) \
+-		(base + SBCONFIGOFF + offsetof(sbconfig_t, field))
+-
+-/* bcm4329 */
+-/* SDIO device core, ID 0x829 */
+-#define BCM4329_CORE_BUS_BASE		0x18011000
+-/* internal memory core, ID 0x80e */
+-#define BCM4329_CORE_SOCRAM_BASE	0x18003000
+-/* ARM Cortex M3 core, ID 0x82a */
+-#define BCM4329_CORE_ARM_BASE		0x18002000
+-#define BCM4329_RAMSIZE			0x48000
+-
+-#endif				/* _bcmchip_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
+deleted file mode 100644
+index 53c3291..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
++++ /dev/null
+@@ -1,113 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sdio_api_h_
+-#define	_sdio_api_h_
+-
+-#define SDIOH_API_RC_SUCCESS                          (0x00)
+-#define SDIOH_API_RC_FAIL	                      (0x01)
+-#define SDIOH_API_SUCCESS(status) (status == 0)
+-
+-#define SDIOH_READ              0	/* Read request */
+-#define SDIOH_WRITE             1	/* Write request */
+-
+-#define SDIOH_DATA_FIX          0	/* Fixed addressing */
+-#define SDIOH_DATA_INC          1	/* Incremental addressing */
+-
+-#define SDIOH_CMD_TYPE_NORMAL   0	/* Normal command */
+-#define SDIOH_CMD_TYPE_APPEND   1	/* Append command */
+-#define SDIOH_CMD_TYPE_CUTTHRU  2	/* Cut-through command */
+-
+-#define SDIOH_DATA_PIO          0	/* PIO mode */
+-#define SDIOH_DATA_DMA          1	/* DMA mode */
+-
+-typedef int SDIOH_API_RC;
+-
+-/* SDio Host structure */
+-typedef struct sdioh_info sdioh_info_t;
+-
+-/* callback function, taking one arg */
+-typedef void (*sdioh_cb_fn_t) (void *);
+-
+-/* attach, return handler on success, NULL if failed.
+- *  The handler shall be provided by all subsequent calls. No local cache
+- *  cfghdl points to the starting address of pci device mapped memory
+- */
+-extern sdioh_info_t *sdioh_attach(void *cfghdl, uint irq);
+-extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si);
+-extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si,
+-					     sdioh_cb_fn_t fn, void *argh);
+-extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si);
+-
+-/* query whether SD interrupt is enabled or not */
+-extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff);
+-
+-/* enable or disable SD interrupt */
+-extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable);
+-
+-#if defined(DHD_DEBUG)
+-extern bool sdioh_interrupt_pending(sdioh_info_t *si);
+-#endif
+-
+-extern int sdioh_claim_host_and_lock(sdioh_info_t *si);
+-extern int sdioh_release_host_and_unlock(sdioh_info_t *si);
+-
+-/* read or write one byte using cmd52 */
+-extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc,
+-				       uint addr, u8 *byte);
+-
+-/* read or write 2/4 bytes using cmd53 */
+-extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type,
+-				       uint rw, uint fnc, uint addr,
+-				       u32 *word, uint nbyte);
+-
+-/* read or write any buffer using cmd53 */
+-extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma,
+-					 uint fix_inc, uint rw, uint fnc_num,
+-					 u32 addr, uint regwidth,
+-					 u32 buflen, u8 *buffer,
+-					 struct sk_buff *pkt);
+-
+-/* get cis data */
+-extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis,
+-				   u32 length);
+-
+-extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr,
+-				   u8 *data);
+-extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr,
+-				    u8 *data);
+-
+-/* query number of io functions */
+-extern uint sdioh_query_iofnum(sdioh_info_t *si);
+-
+-/* handle iovars */
+-extern int sdioh_iovar_op(sdioh_info_t *si, const char *name,
+-			  void *params, int plen, void *arg, int len, bool set);
+-
+-/* Issue abort to the specified function and clear controller as needed */
+-extern int sdioh_abort(sdioh_info_t *si, uint fnc);
+-
+-/* Start and Stop SDIO without re-enumerating the SD card. */
+-extern int sdioh_start(sdioh_info_t *si, int stage);
+-extern int sdioh_stop(sdioh_info_t *si);
+-
+-/* Reset and re-initialize the device */
+-extern int sdioh_sdio_reset(sdioh_info_t *si);
+-
+-/* Helper function */
+-void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+-
+-#endif				/* _sdio_api_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+deleted file mode 100644
+index 3750fcf..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
++++ /dev/null
+@@ -1,631 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-/* ****************** BCMSDH Interface Functions *************************** */
+-
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <linux/pci_ids.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <hndsoc.h>
+-
+-#include <bcmsdh.h>		/* BRCM API for SDIO
+-			 clients (such as wl, dhd) */
+-#include <bcmsdbus.h>		/* common SDIO/controller interface */
+-#include <sbsdio.h>		/* BRCM sdio device core */
+-
+-#include <sdio.h>		/* sdio spec */
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-#define SDIOH_API_ACCESS_RETRY_LIMIT	2
+-const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
+-
+-struct bcmsdh_info {
+-	bool init_success;	/* underlying driver successfully attached */
+-	void *sdioh;		/* handler for sdioh */
+-	u32 vendevid;	/* Target Vendor and Device ID on SD bus */
+-	bool regfail;		/* Save status of last
+-				 reg_read/reg_write call */
+-	u32 sbwad;		/* Save backplane window address */
+-};
+-/* local copy of bcm sd handler */
+-bcmsdh_info_t *l_bcmsdh;
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
+-
+-void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
+-{
+-	sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
+-}
+-#endif
+-
+-bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq)
+-{
+-	bcmsdh_info_t *bcmsdh;
+-
+-	bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC);
+-	if (bcmsdh == NULL) {
+-		BCMSDH_ERROR(("bcmsdh_attach: out of memory"));
+-		return NULL;
+-	}
+-
+-	/* save the handler locally */
+-	l_bcmsdh = bcmsdh;
+-
+-	bcmsdh->sdioh = sdioh_attach(cfghdl, irq);
+-	if (!bcmsdh->sdioh) {
+-		bcmsdh_detach(bcmsdh);
+-		return NULL;
+-	}
+-
+-	bcmsdh->init_success = true;
+-
+-	*regsva = (u32 *) SI_ENUM_BASE;
+-
+-	/* Report the BAR, to fix if needed */
+-	bcmsdh->sbwad = SI_ENUM_BASE;
+-	return bcmsdh;
+-}
+-
+-int bcmsdh_detach(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (bcmsdh != NULL) {
+-		if (bcmsdh->sdioh) {
+-			sdioh_detach(bcmsdh->sdioh);
+-			bcmsdh->sdioh = NULL;
+-		}
+-		kfree(bcmsdh);
+-	}
+-
+-	l_bcmsdh = NULL;
+-	return 0;
+-}
+-
+-int
+-bcmsdh_iovar_op(void *sdh, const char *name,
+-		void *params, int plen, void *arg, int len, bool set)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
+-}
+-
+-bool bcmsdh_intr_query(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	bool on;
+-
+-	ASSERT(bcmsdh);
+-	status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
+-	if (SDIOH_API_SUCCESS(status))
+-		return false;
+-	else
+-		return on;
+-}
+-
+-int bcmsdh_intr_enable(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_set(bcmsdh->sdioh, true);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_disable(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_set(bcmsdh->sdioh, false);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_dereg(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_deregister(bcmsdh->sdioh);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-#if defined(DHD_DEBUG)
+-bool bcmsdh_intr_pending(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	ASSERT(sdh);
+-	return sdioh_interrupt_pending(bcmsdh->sdioh);
+-}
+-#endif
+-
+-int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+-{
+-	ASSERT(sdh);
+-
+-	/* don't support yet */
+-	return -ENOTSUPP;
+-}
+-
+-u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	s32 retry = 0;
+-#endif
+-	u8 data = 0;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	do {
+-		if (retry)	/* wait for 1 ms till bus get settled down */
+-			udelay(1000);
+-#endif
+-		status =
+-		    sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr,
+-				   (u8 *) &data);
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	} while (!SDIOH_API_SUCCESS(status)
+-		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+-#endif
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-
+-	return data;
+-}
+-
+-void
+-bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	s32 retry = 0;
+-#endif
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	do {
+-		if (retry)	/* wait for 1 ms till bus get settled down */
+-			udelay(1000);
+-#endif
+-		status =
+-		    sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr,
+-				    (u8 *) &data);
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	} while (!SDIOH_API_SUCCESS(status)
+-		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+-#endif
+-	if (err)
+-		*err = SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-}
+-
+-u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	u32 data = 0;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ,
+-			       fnc_num, addr, &data, 4);
+-
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-
+-	return data;
+-}
+-
+-void
+-bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data,
+-		      int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-			       SDIOH_WRITE, fnc_num, addr, &data, 4);
+-
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-}
+-
+-int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	u8 *tmp_buf, *tmp_ptr;
+-	u8 *ptr;
+-	bool ascii = func & ~0xf;
+-	func &= 0x7;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-	ASSERT(cis);
+-	ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
+-
+-	status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
+-
+-	if (ascii) {
+-		/* Move binary bits to tmp and format them
+-			 into the provided buffer. */
+-		tmp_buf = kmalloc(length, GFP_ATOMIC);
+-		if (tmp_buf == NULL) {
+-			BCMSDH_ERROR(("%s: out of memory\n", __func__));
+-			return -ENOMEM;
+-		}
+-		memcpy(tmp_buf, cis, length);
+-		for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
+-		     tmp_ptr++) {
+-			ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
+-			if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
+-				ptr += sprintf((char *)ptr, "\n");
+-		}
+-		kfree(tmp_buf);
+-	}
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
+-{
+-	int err = 0;
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+-			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+-				 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+-				 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
+-				 &err);
+-
+-	return err;
+-}
+-
+-u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	u32 word = 0;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))
+-			return 0xFFFFFFFF;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	if (size == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-				    SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
+-
+-	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+-
+-	BCMSDH_INFO(("u32data = 0x%x\n", word));
+-
+-	/* if ok, return appropriately masked word */
+-	if (SDIOH_API_SUCCESS(status)) {
+-		switch (size) {
+-		case sizeof(u8):
+-			return word & 0xff;
+-		case sizeof(u16):
+-			return word & 0xffff;
+-		case sizeof(u32):
+-			return word;
+-		default:
+-			bcmsdh->regfail = true;
+-
+-		}
+-	}
+-
+-	/* otherwise, bad sdio access or invalid size */
+-	BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
+-		      addr, size));
+-	return 0xFFFFFFFF;
+-}
+-
+-u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
+-		     __func__, addr, size * 8, data));
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	if (size == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-			       SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
+-	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+-
+-	if (SDIOH_API_SUCCESS(status))
+-		return 0;
+-
+-	BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
+-		      __func__, data, addr, size));
+-	return 0xFFFFFFFF;
+-}
+-
+-bool bcmsdh_regfail(void *sdh)
+-{
+-	return ((bcmsdh_info_t *) sdh)->regfail;
+-}
+-
+-int
+-bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
+-		u8 *buf, uint nbytes, struct sk_buff *pkt,
+-		bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint incr_fix;
+-	uint width;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+-		     __func__, fn, addr, nbytes));
+-
+-	/* Async not implemented yet */
+-	ASSERT(!(flags & SDIO_REQ_ASYNC));
+-	if (flags & SDIO_REQ_ASYNC)
+-		return -ENOTSUPP;
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+-	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+-	if (width == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+-				      SDIOH_READ, fn, addr, width, nbytes, buf,
+-				      pkt);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int
+-bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
+-		u8 *buf, uint nbytes, void *pkt,
+-		bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint incr_fix;
+-	uint width;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+-		     __func__, fn, addr, nbytes));
+-
+-	/* Async not implemented yet */
+-	ASSERT(!(flags & SDIO_REQ_ASYNC));
+-	if (flags & SDIO_REQ_ASYNC)
+-		return -ENOTSUPP;
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+-	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+-	if (width == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+-				      SDIOH_WRITE, fn, addr, width, nbytes, buf,
+-				      pkt);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-	ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status =
+-	    sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
+-				 (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
+-				 addr, 4, nbytes, buf, NULL);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_abort(void *sdh, uint fn)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_abort(bcmsdh->sdioh, fn);
+-}
+-
+-int bcmsdh_start(void *sdh, int stage)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_start(bcmsdh->sdioh, stage);
+-}
+-
+-int bcmsdh_stop(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_stop(bcmsdh->sdioh);
+-}
+-
+-int bcmsdh_query_device(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
+-	return bcmsdh->vendevid;
+-}
+-
+-uint bcmsdh_query_iofnum(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	return sdioh_query_iofnum(bcmsdh->sdioh);
+-}
+-
+-int bcmsdh_reset(bcmsdh_info_t *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_sdio_reset(bcmsdh->sdioh);
+-}
+-
+-void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
+-{
+-	ASSERT(sdh);
+-	return sdh->sdioh;
+-}
+-
+-/* Function to pass device-status bits to DHD. */
+-u32 bcmsdh_get_dstatus(void *sdh)
+-{
+-	return 0;
+-}
+-
+-u32 bcmsdh_cur_sbwad(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	return bcmsdh->sbwad;
+-}
+-
+-void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev)
+-{
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+deleted file mode 100644
+index 465f623..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
++++ /dev/null
+@@ -1,386 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/**
+- * @file bcmsdh_linux.c
+- */
+-
+-#define __UNDEF_NO_VERSION__
+-
+-#include <linux/netdevice.h>
+-#include <linux/pci.h>
+-#include <linux/completion.h>
+-
+-#include <pcicfg.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-
+-#if defined(OOB_INTR_ONLY)
+-#include <linux/irq.h>
+-extern void dhdsdio_isr(void *args);
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#endif				/* defined(OOB_INTR_ONLY) */
+-#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
+-#if !defined(BCMPLATFORM_BUS)
+-#define BCMPLATFORM_BUS
+-#endif				/* !defined(BCMPLATFORM_BUS) */
+-
+-#include <linux/platform_device.h>
+-#endif				/* CONFIG_MACH_SANDGATE2G */
+-
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-/**
+- * SDIO Host Controller info
+- */
+-typedef struct bcmsdh_hc bcmsdh_hc_t;
+-
+-struct bcmsdh_hc {
+-	bcmsdh_hc_t *next;
+-#ifdef BCMPLATFORM_BUS
+-	struct device *dev;	/* platform device handle */
+-#else
+-	struct pci_dev *dev;	/* pci device handle */
+-#endif				/* BCMPLATFORM_BUS */
+-	void *regs;		/* SDIO Host Controller address */
+-	bcmsdh_info_t *sdh;	/* SDIO Host Controller handle */
+-	void *ch;
+-	unsigned int oob_irq;
+-	unsigned long oob_flags;	/* OOB Host specifiction
+-					as edge and etc */
+-	bool oob_irq_registered;
+-#if defined(OOB_INTR_ONLY)
+-	spinlock_t irq_lock;
+-#endif
+-};
+-static bcmsdh_hc_t *sdhcinfo;
+-
+-/* driver info, initialized when bcmsdh_register is called */
+-static bcmsdh_driver_t drvinfo = { NULL, NULL };
+-
+-/* debugging macros */
+-#define SDLX_MSG(x)
+-
+-/**
+- * Checks to see if vendor and device IDs match a supported SDIO Host Controller.
+- */
+-bool bcmsdh_chipmatch(u16 vendor, u16 device)
+-{
+-	/* Add other vendors and devices as required */
+-
+-#ifdef BCMSDIOH_STD
+-	/* Check for Arasan host controller */
+-	if (vendor == VENDOR_SI_IMAGE)
+-		return true;
+-
+-	/* Check for BRCM 27XX Standard host controller */
+-	if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM)
+-		return true;
+-
+-	/* Check for BRCM Standard host controller */
+-	if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM)
+-		return true;
+-
+-	/* Check for TI PCIxx21 Standard host controller */
+-	if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI)
+-		return true;
+-
+-	if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI)
+-		return true;
+-
+-	/* Ricoh R5C822 Standard SDIO Host */
+-	if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH)
+-		return true;
+-
+-	/* JMicron Standard SDIO Host */
+-	if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON)
+-		return true;
+-#endif				/* BCMSDIOH_STD */
+-#ifdef BCMSDIOH_SPI
+-	/* This is the PciSpiHost. */
+-	if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) {
+-		return true;
+-	}
+-#endif				/* BCMSDIOH_SPI */
+-
+-	return false;
+-}
+-
+-#if defined(BCMPLATFORM_BUS)
+-#if defined(BCMLXSDMMC)
+-/* forward declarations */
+-int bcmsdh_probe(struct device *dev);
+-EXPORT_SYMBOL(bcmsdh_probe);
+-
+-int bcmsdh_remove(struct device *dev);
+-EXPORT_SYMBOL(bcmsdh_remove);
+-
+-#else
+-/* forward declarations */
+-static int __devinit bcmsdh_probe(struct device *dev);
+-static int __devexit bcmsdh_remove(struct device *dev);
+-#endif				/* BCMLXSDMMC */
+-
+-#ifndef BCMLXSDMMC
+-static
+-#endif				/* BCMLXSDMMC */
+-int bcmsdh_probe(struct device *dev)
+-{
+-	bcmsdh_hc_t *sdhc = NULL;
+-	unsigned long regs = 0;
+-	bcmsdh_info_t *sdh = NULL;
+-#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+-	struct platform_device *pdev;
+-	struct resource *r;
+-#endif				/* BCMLXSDMMC */
+-	int irq = 0;
+-	u32 vendevid;
+-	unsigned long irq_flags = 0;
+-
+-#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+-	pdev = to_platform_device(dev);
+-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	irq = platform_get_irq(pdev, 0);
+-	if (!r || irq == NO_IRQ)
+-		return -ENXIO;
+-#endif				/* BCMLXSDMMC */
+-
+-#if defined(OOB_INTR_ONLY)
+-#ifdef HW_OOB
+-	irq_flags =
+-	    IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
+-	    IORESOURCE_IRQ_SHAREABLE;
+-#else
+-	irq_flags = IRQF_TRIGGER_FALLING;
+-#endif				/* HW_OOB */
+-	irq = dhd_customer_oob_irq_map(&irq_flags);
+-	if (irq < 0) {
+-		SDLX_MSG(("%s: Host irq is not defined\n", __func__));
+-		return 1;
+-	}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-	/* allocate SDIO Host Controller state info */
+-	sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
+-	if (!sdhc) {
+-		SDLX_MSG(("%s: out of memory\n", __func__));
+-		goto err;
+-	}
+-	sdhc->dev = (void *)dev;
+-
+-#ifdef BCMLXSDMMC
+-	sdh = bcmsdh_attach((void *)0, (void **)&regs, irq);
+-	if (!sdh) {
+-		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
+-		goto err;
+-	}
+-#else
+-	sdh = bcmsdh_attach((void *)r->start, (void **)&regs, irq);
+-	if (!sdh) {
+-		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
+-		goto err;
+-	}
+-#endif				/* BCMLXSDMMC */
+-	sdhc->sdh = sdh;
+-	sdhc->oob_irq = irq;
+-	sdhc->oob_flags = irq_flags;
+-	sdhc->oob_irq_registered = false;	/* to make sure.. */
+-#if defined(OOB_INTR_ONLY)
+-	spin_lock_init(&sdhc->irq_lock);
+-#endif
+-
+-	/* chain SDIO Host Controller info together */
+-	sdhc->next = sdhcinfo;
+-	sdhcinfo = sdhc;
+-	/* Read the vendor/device ID from the CIS */
+-	vendevid = bcmsdh_query_device(sdh);
+-
+-	/* try to attach to the target device */
+-	sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
+-				  0, 0, 0, 0, (void *)regs, sdh);
+-	if (!sdhc->ch) {
+-		SDLX_MSG(("%s: device attach failed\n", __func__));
+-		goto err;
+-	}
+-
+-	return 0;
+-
+-	/* error handling */
+-err:
+-	if (sdhc) {
+-		if (sdhc->sdh)
+-			bcmsdh_detach(sdhc->sdh);
+-		kfree(sdhc);
+-	}
+-
+-	return -ENODEV;
+-}
+-
+-#ifndef BCMLXSDMMC
+-static
+-#endif				/* BCMLXSDMMC */
+-int bcmsdh_remove(struct device *dev)
+-{
+-	bcmsdh_hc_t *sdhc, *prev;
+-
+-	sdhc = sdhcinfo;
+-	drvinfo.detach(sdhc->ch);
+-	bcmsdh_detach(sdhc->sdh);
+-	/* find the SDIO Host Controller state for this pdev
+-		 and take it out from the list */
+-	for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
+-		if (sdhc->dev == (void *)dev) {
+-			if (prev)
+-				prev->next = sdhc->next;
+-			else
+-				sdhcinfo = NULL;
+-			break;
+-		}
+-		prev = sdhc;
+-	}
+-	if (!sdhc) {
+-		SDLX_MSG(("%s: failed\n", __func__));
+-		return 0;
+-	}
+-
+-	/* release SDIO Host Controller info */
+-	kfree(sdhc);
+-
+-#if !defined(BCMLXSDMMC)
+-	dev_set_drvdata(dev, NULL);
+-#endif				/* !defined(BCMLXSDMMC) */
+-
+-	return 0;
+-}
+-#endif				/* BCMPLATFORM_BUS */
+-
+-extern int sdio_function_init(void);
+-
+-int bcmsdh_register(bcmsdh_driver_t *driver)
+-{
+-	drvinfo = *driver;
+-
+-	SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
+-	return sdio_function_init();
+-}
+-
+-extern void sdio_function_cleanup(void);
+-
+-void bcmsdh_unregister(void)
+-{
+-	sdio_function_cleanup();
+-}
+-
+-#if defined(OOB_INTR_ONLY)
+-void bcmsdh_oob_intr_set(bool enable)
+-{
+-	static bool curstate = 1;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
+-	if (curstate != enable) {
+-		if (enable)
+-			enable_irq(sdhcinfo->oob_irq);
+-		else
+-			disable_irq_nosync(sdhcinfo->oob_irq);
+-		curstate = enable;
+-	}
+-	spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
+-}
+-
+-static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
+-{
+-	dhd_pub_t *dhdp;
+-
+-	dhdp = (dhd_pub_t *) dev_get_drvdata(sdhcinfo->dev);
+-
+-	bcmsdh_oob_intr_set(0);
+-
+-	if (dhdp == NULL) {
+-		SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
+-		return IRQ_HANDLED;
+-	}
+-
+-	dhdsdio_isr((void *)dhdp->bus);
+-
+-	return IRQ_HANDLED;
+-}
+-
+-int bcmsdh_register_oob_intr(void *dhdp)
+-{
+-	int error = 0;
+-
+-	SDLX_MSG(("%s Enter\n", __func__));
+-
+-	sdhcinfo->oob_flags =
+-	    IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
+-	    IORESOURCE_IRQ_SHAREABLE;
+-	dev_set_drvdata(sdhcinfo->dev, dhdp);
+-
+-	if (!sdhcinfo->oob_irq_registered) {
+-		SDLX_MSG(("%s IRQ=%d Type=%X\n", __func__,
+-			  (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
+-		/* Refer to customer Host IRQ docs about
+-			 proper irqflags definition */
+-		error =
+-		    request_irq(sdhcinfo->oob_irq, wlan_oob_irq,
+-				sdhcinfo->oob_flags, "bcmsdh_sdmmc", NULL);
+-		if (error)
+-			return -ENODEV;
+-
+-		irq_set_irq_wake(sdhcinfo->oob_irq, 1);
+-		sdhcinfo->oob_irq_registered = true;
+-	}
+-
+-	return 0;
+-}
+-
+-void bcmsdh_unregister_oob_intr(void)
+-{
+-	SDLX_MSG(("%s: Enter\n", __func__));
+-
+-	irq_set_irq_wake(sdhcinfo->oob_irq, 0);
+-	disable_irq(sdhcinfo->oob_irq);	/* just in case.. */
+-	free_irq(sdhcinfo->oob_irq, NULL);
+-	sdhcinfo->oob_irq_registered = false;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-/* Module parameters specific to each host-controller driver */
+-
+-extern uint sd_msglevel;	/* Debug message level */
+-module_param(sd_msglevel, uint, 0);
+-
+-extern uint sd_power;		/* 0 = SD Power OFF,
+-					 1 = SD Power ON. */
+-module_param(sd_power, uint, 0);
+-
+-extern uint sd_clock;		/* SD Clock Control, 0 = SD Clock OFF,
+-				 1 = SD Clock ON */
+-module_param(sd_clock, uint, 0);
+-
+-extern uint sd_divisor;		/* Divisor (-1 means external clock) */
+-module_param(sd_divisor, uint, 0);
+-
+-extern uint sd_sdmode;		/* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
+-module_param(sd_sdmode, uint, 0);
+-
+-extern uint sd_hiok;		/* Ok to use hi-speed mode */
+-module_param(sd_hiok, uint, 0);
+-
+-extern uint sd_f2_blocksize;
+-module_param(sd_f2_blocksize, int, 0);
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+deleted file mode 100644
+index c0ffbd3..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
++++ /dev/null
+@@ -1,1239 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <sdio.h>		/* SDIO Device and Protocol Specs */
+-#include <sdioh.h>		/* SDIO Host Controller Specification */
+-#include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
+-#include <sdiovar.h>		/* ioctl/iovars */
+-
+-#include <linux/mmc/core.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/mmc/sdio_ids.h>
+-#include <linux/suspend.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#include "bcmsdh_sdmmc.h"
+-
+-extern int sdio_function_init(void);
+-extern void sdio_function_cleanup(void);
+-
+-#if !defined(OOB_INTR_ONLY)
+-static void IRQHandler(struct sdio_func *func);
+-static void IRQHandlerF2(struct sdio_func *func);
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr);
+-extern int sdio_reset_comm(struct mmc_card *card);
+-
+-extern PBCMSDH_SDMMC_INSTANCE gInstance;
+-
+-uint sd_sdmode = SDIOH_MODE_SD4;	/* Use SD4 mode by default */
+-uint sd_f2_blocksize = 512;	/* Default blocksize */
+-
+-uint sd_divisor = 2;		/* Default 48MHz/2 = 24MHz */
+-
+-uint sd_power = 1;		/* Default to SD Slot powered ON */
+-uint sd_clock = 1;		/* Default to SD Clock turned ON */
+-uint sd_hiok = false;		/* Don't use hi-speed mode by default */
+-uint sd_msglevel = 0x01;
+-uint sd_use_dma = true;
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait);
+-
+-#define DMA_ALIGN_MASK	0x03
+-
+-int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
+-			     int regsize, u32 *data);
+-
+-void sdioh_sdio_set_host_pm_flags(int flag)
+-{
+-	if (sdio_set_host_pm_flags(gInstance->func[1], flag))
+-		printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\
+-			 __func__, (unsigned int)flag);
+-}
+-
+-static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
+-{
+-	int err_ret;
+-	u32 fbraddr;
+-	u8 func;
+-
+-	sd_trace(("%s\n", __func__));
+-
+-	/* Get the Card's common CIS address */
+-	sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0);
+-	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+-	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
+-		 sd->com_cis_ptr));
+-
+-	/* Get the Card's function CIS (for each function) */
+-	for (fbraddr = SDIOD_FBR_STARTADDR, func = 1;
+-	     func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
+-		sd->func_cis_ptr[func] =
+-		    sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr);
+-		sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func,
+-			 sd->func_cis_ptr[func]));
+-	}
+-
+-	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+-	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
+-		 sd->com_cis_ptr));
+-
+-	/* Enable Function 1 */
+-	sdio_claim_host(gInstance->func[1]);
+-	err_ret = sdio_enable_func(gInstance->func[1]);
+-	sdio_release_host(gInstance->func[1]);
+-	if (err_ret) {
+-		sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x",
+-			err_ret));
+-	}
+-
+-	return false;
+-}
+-
+-/*
+- *	Public entry points & extern's
+- */
+-sdioh_info_t *sdioh_attach(void *bar0, uint irq)
+-{
+-	sdioh_info_t *sd;
+-	int err_ret;
+-
+-	sd_trace(("%s\n", __func__));
+-
+-	if (gInstance == NULL) {
+-		sd_err(("%s: SDIO Device not present\n", __func__));
+-		return NULL;
+-	}
+-
+-	sd = kzalloc(sizeof(sdioh_info_t), GFP_ATOMIC);
+-	if (sd == NULL) {
+-		sd_err(("sdioh_attach: out of memory\n"));
+-		return NULL;
+-	}
+-	if (sdioh_sdmmc_osinit(sd) != 0) {
+-		sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__));
+-		kfree(sd);
+-		return NULL;
+-	}
+-
+-	sd->num_funcs = 2;
+-	sd->sd_blockmode = true;
+-	sd->use_client_ints = true;
+-	sd->client_block_size[0] = 64;
+-
+-	gInstance->sd = sd;
+-
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[1]);
+-
+-	sd->client_block_size[1] = 64;
+-	err_ret = sdio_set_block_size(gInstance->func[1], 64);
+-	if (err_ret)
+-		sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n"));
+-
+-	/* Release host controller F1 */
+-	sdio_release_host(gInstance->func[1]);
+-
+-	if (gInstance->func[2]) {
+-		/* Claim host controller F2 */
+-		sdio_claim_host(gInstance->func[2]);
+-
+-		sd->client_block_size[2] = sd_f2_blocksize;
+-		err_ret =
+-		    sdio_set_block_size(gInstance->func[2], sd_f2_blocksize);
+-		if (err_ret)
+-			sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize "
+-				"to %d\n", sd_f2_blocksize));
+-
+-		/* Release host controller F2 */
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	sdioh_sdmmc_card_enablefuncs(sd);
+-
+-	sd_trace(("%s: Done\n", __func__));
+-	return sd;
+-}
+-
+-extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s\n", __func__));
+-
+-	if (sd) {
+-
+-		/* Disable Function 2 */
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_disable_func(gInstance->func[2]);
+-		sdio_release_host(gInstance->func[2]);
+-
+-		/* Disable Function 1 */
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_disable_func(gInstance->func[1]);
+-		sdio_release_host(gInstance->func[1]);
+-
+-		/* deregister irq */
+-		sdioh_sdmmc_osfree(sd);
+-
+-		kfree(sd);
+-	}
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-
+-extern SDIOH_API_RC sdioh_enable_func_intr(void)
+-{
+-	u8 reg;
+-	int err;
+-
+-	if (gInstance->func[0]) {
+-		sdio_claim_host(gInstance->func[0]);
+-
+-		reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+-		if (err) {
+-			sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			sdio_release_host(gInstance->func[0]);
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* Enable F1 and F2 interrupts, set master enable */
+-		reg |=
+-		    (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN |
+-		     INTR_CTL_MASTER_EN);
+-
+-		sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+-		sdio_release_host(gInstance->func[0]);
+-
+-		if (err) {
+-			sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-	}
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_disable_func_intr(void)
+-{
+-	u8 reg;
+-	int err;
+-
+-	if (gInstance->func[0]) {
+-		sdio_claim_host(gInstance->func[0]);
+-		reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+-		if (err) {
+-			sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			sdio_release_host(gInstance->func[0]);
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+-		/* Disable master interrupt with the last function interrupt */
+-		if (!(reg & 0xFE))
+-			reg = 0;
+-		sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+-
+-		sdio_release_host(gInstance->func[0]);
+-		if (err) {
+-			sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-	}
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+-
+-/* Configure callback to client when we receive client interrupt */
+-extern SDIOH_API_RC
+-sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-	if (fn == NULL) {
+-		sd_err(("%s: interrupt handler is NULL, not registering\n",
+-			__func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-#if !defined(OOB_INTR_ONLY)
+-	sd->intr_handler = fn;
+-	sd->intr_handler_arg = argh;
+-	sd->intr_handler_valid = true;
+-
+-	/* register and unmask irq */
+-	if (gInstance->func[2]) {
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_claim_irq(gInstance->func[2], IRQHandlerF2);
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	if (gInstance->func[1]) {
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_claim_irq(gInstance->func[1], IRQHandler);
+-		sdio_release_host(gInstance->func[1]);
+-	}
+-#elif defined(HW_OOB)
+-	sdioh_enable_func_intr();
+-#endif				/* defined(OOB_INTR_ONLY) */
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-
+-#if !defined(OOB_INTR_ONLY)
+-	if (gInstance->func[1]) {
+-		/* register and unmask irq */
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_release_irq(gInstance->func[1]);
+-		sdio_release_host(gInstance->func[1]);
+-	}
+-
+-	if (gInstance->func[2]) {
+-		/* Claim host controller F2 */
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_release_irq(gInstance->func[2]);
+-		/* Release host controller F2 */
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	sd->intr_handler_valid = false;
+-	sd->intr_handler = NULL;
+-	sd->intr_handler_arg = NULL;
+-#elif defined(HW_OOB)
+-	sdioh_disable_func_intr();
+-#endif				/*  !defined(OOB_INTR_ONLY) */
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-	*onoff = sd->client_intr_enabled;
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-#if defined(DHD_DEBUG)
+-extern bool sdioh_interrupt_pending(sdioh_info_t *sd)
+-{
+-	return 0;
+-}
+-#endif
+-
+-uint sdioh_query_iofnum(sdioh_info_t *sd)
+-{
+-	return sd->num_funcs;
+-}
+-
+-/* IOVar table */
+-enum {
+-	IOV_MSGLEVEL = 1,
+-	IOV_BLOCKMODE,
+-	IOV_BLOCKSIZE,
+-	IOV_DMA,
+-	IOV_USEINTS,
+-	IOV_NUMINTS,
+-	IOV_NUMLOCALINTS,
+-	IOV_HOSTREG,
+-	IOV_DEVREG,
+-	IOV_DIVISOR,
+-	IOV_SDMODE,
+-	IOV_HISPEED,
+-	IOV_HCIREGS,
+-	IOV_POWER,
+-	IOV_CLOCK,
+-	IOV_RXCHAIN
+-};
+-
+-const bcm_iovar_t sdioh_iovars[] = {
+-	{"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0},
+-	{"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0},
+-	{"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) |
+-								 size) */
+-	{"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0},
+-	{"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0},
+-	{"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0},
+-	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0},
+-	{"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_power", IOV_POWER, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}
+-	,
+-	{"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0}
+-	,
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-int
+-sdioh_iovar_op(sdioh_info_t *si, const char *name,
+-	       void *params, int plen, void *arg, int len, bool set)
+-{
+-	const bcm_iovar_t *vi = NULL;
+-	int bcmerror = 0;
+-	int val_size;
+-	s32 int_val = 0;
+-	bool bool_val;
+-	u32 actionid;
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get must have return space; Set does not take qualifiers */
+-	ASSERT(set || (arg && len));
+-	ASSERT(!set || (!params && !plen));
+-
+-	sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"),
+-		  name));
+-
+-	vi = bcm_iovar_lookup(sdioh_iovars, name);
+-	if (vi == NULL) {
+-		bcmerror = -ENOTSUPP;
+-		goto exit;
+-	}
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, set);
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	/* Set up params so get and set can share the convenience variables */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		val_size = sizeof(int);
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	bool_val = (int_val != 0) ? true : false;
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_MSGLEVEL):
+-		int_val = (s32) sd_msglevel;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_MSGLEVEL):
+-		sd_msglevel = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_BLOCKMODE):
+-		int_val = (s32) si->sd_blockmode;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_BLOCKMODE):
+-		si->sd_blockmode = (bool) int_val;
+-		/* Haven't figured out how to make non-block mode with DMA */
+-		break;
+-
+-	case IOV_GVAL(IOV_BLOCKSIZE):
+-		if ((u32) int_val > si->num_funcs) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		int_val = (s32) si->client_block_size[int_val];
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_BLOCKSIZE):
+-		{
+-			uint func = ((u32) int_val >> 16);
+-			uint blksize = (u16) int_val;
+-			uint maxsize;
+-
+-			if (func > si->num_funcs) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			switch (func) {
+-			case 0:
+-				maxsize = 32;
+-				break;
+-			case 1:
+-				maxsize = BLOCK_SIZE_4318;
+-				break;
+-			case 2:
+-				maxsize = BLOCK_SIZE_4328;
+-				break;
+-			default:
+-				maxsize = 0;
+-			}
+-			if (blksize > maxsize) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-			if (!blksize)
+-				blksize = maxsize;
+-
+-			/* Now set it */
+-			si->client_block_size[func] = blksize;
+-
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_RXCHAIN):
+-		int_val = false;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_DMA):
+-		int_val = (s32) si->sd_use_dma;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DMA):
+-		si->sd_use_dma = (bool) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_USEINTS):
+-		int_val = (s32) si->use_client_ints;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_USEINTS):
+-		si->use_client_ints = (bool) int_val;
+-		if (si->use_client_ints)
+-			si->intmask |= CLIENT_INTR;
+-		else
+-			si->intmask &= ~CLIENT_INTR;
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_DIVISOR):
+-		int_val = (u32) sd_divisor;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DIVISOR):
+-		sd_divisor = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_POWER):
+-		int_val = (u32) sd_power;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_POWER):
+-		sd_power = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_CLOCK):
+-		int_val = (u32) sd_clock;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_CLOCK):
+-		sd_clock = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDMODE):
+-		int_val = (u32) sd_sdmode;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDMODE):
+-		sd_sdmode = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_HISPEED):
+-		int_val = (u32) sd_hiok;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_HISPEED):
+-		sd_hiok = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_NUMINTS):
+-		int_val = (s32) si->intrcount;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_NUMLOCALINTS):
+-		int_val = (s32) 0;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_HOSTREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-
+-			if (sd_ptr->offset < SD_SysAddr
+-			    || sd_ptr->offset > SD_MaxCurCap) {
+-				sd_err(("%s: bad offset 0x%x\n", __func__,
+-					sd_ptr->offset));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			sd_trace(("%s: rreg%d at offset %d\n", __func__,
+-				  (sd_ptr->offset & 1) ? 8
+-				  : ((sd_ptr->offset & 2) ? 16 : 32),
+-				  sd_ptr->offset));
+-			if (sd_ptr->offset & 1)
+-				int_val = 8;	/* sdioh_sdmmc_rreg8(si,
+-						 sd_ptr->offset); */
+-			else if (sd_ptr->offset & 2)
+-				int_val = 16;	/* sdioh_sdmmc_rreg16(si,
+-						 sd_ptr->offset); */
+-			else
+-				int_val = 32;	/* sdioh_sdmmc_rreg(si,
+-						 sd_ptr->offset); */
+-
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_HOSTREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-
+-			if (sd_ptr->offset < SD_SysAddr
+-			    || sd_ptr->offset > SD_MaxCurCap) {
+-				sd_err(("%s: bad offset 0x%x\n", __func__,
+-					sd_ptr->offset));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			sd_trace(("%s: wreg%d value 0x%08x at offset %d\n",
+-				  __func__, sd_ptr->value,
+-				  (sd_ptr->offset & 1) ? 8
+-				  : ((sd_ptr->offset & 2) ? 16 : 32),
+-				  sd_ptr->offset));
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_DEVREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-			u8 data = 0;
+-
+-			if (sdioh_cfg_read
+-			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
+-				bcmerror = -EIO;
+-				break;
+-			}
+-
+-			int_val = (int)data;
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_DEVREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-			u8 data = (u8) sd_ptr->value;
+-
+-			if (sdioh_cfg_write
+-			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
+-				bcmerror = -EIO;
+-				break;
+-			}
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-exit:
+-
+-	return bcmerror;
+-}
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-
+-SDIOH_API_RC sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
+-{
+-	SDIOH_API_RC status;
+-	u8 data;
+-
+-	if (enable)
+-		data = 3;	/* enable hw oob interrupt */
+-	else
+-		data = 4;	/* disable hw oob interrupt */
+-	data |= 4;		/* Active HIGH */
+-
+-	status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
+-	return status;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+-
+-extern SDIOH_API_RC
+-sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data)
+-{
+-	SDIOH_API_RC status;
+-	/* No lock needed since sdioh_request_byte does locking */
+-	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
+-	return status;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data)
+-{
+-	/* No lock needed since sdioh_request_byte does locking */
+-	SDIOH_API_RC status;
+-	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
+-	return status;
+-}
+-
+-static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr)
+-{
+-	/* read 24 bits and return valid 17 bit addr */
+-	int i;
+-	u32 scratch, regdata;
+-	u8 *ptr = (u8 *)&scratch;
+-	for (i = 0; i < 3; i++) {
+-		if ((sdioh_sdmmc_card_regread(sd, 0, regaddr, 1, &regdata)) !=
+-		    SUCCESS)
+-			sd_err(("%s: Can't read!\n", __func__));
+-
+-		*ptr++ = (u8) regdata;
+-		regaddr++;
+-	}
+-
+-	/* Only the lower 17-bits are valid */
+-	scratch = le32_to_cpu(scratch);
+-	scratch &= 0x0001FFFF;
+-	return scratch;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length)
+-{
+-	u32 count;
+-	int offset;
+-	u32 foo;
+-	u8 *cis = cisd;
+-
+-	sd_trace(("%s: Func = %d\n", __func__, func));
+-
+-	if (!sd->func_cis_ptr[func]) {
+-		memset(cis, 0, length);
+-		sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-
+-	sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func,
+-		sd->func_cis_ptr[func]));
+-
+-	for (count = 0; count < length; count++) {
+-		offset = sd->func_cis_ptr[func] + count;
+-		if (sdioh_sdmmc_card_regread(sd, 0, offset, 1, &foo) < 0) {
+-			sd_err(("%s: regread failed: Can't read CIS\n",
+-				__func__));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		*cis = (u8) (foo & 0xff);
+-		cis++;
+-	}
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr,
+-		   u8 *byte)
+-{
+-	int err_ret;
+-
+-	sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func,
+-		 regaddr));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_byte_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	if (rw) {		/* CMD52 Write */
+-		if (func == 0) {
+-			/* Can only directly write to some F0 registers.
+-			 * Handle F2 enable
+-			 * as a special case.
+-			 */
+-			if (regaddr == SDIOD_CCCR_IOEN) {
+-				if (gInstance->func[2]) {
+-					sdio_claim_host(gInstance->func[2]);
+-					if (*byte & SDIO_FUNC_ENABLE_2) {
+-						/* Enable Function 2 */
+-						err_ret =
+-						    sdio_enable_func
+-						    (gInstance->func[2]);
+-						if (err_ret)
+-							sd_err(("bcmsdh_sdmmc: enable F2 failed:%d",
+-								 err_ret));
+-					} else {
+-						/* Disable Function 2 */
+-						err_ret =
+-						    sdio_disable_func
+-						    (gInstance->func[2]);
+-						if (err_ret)
+-							sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d",
+-								 err_ret));
+-					}
+-					sdio_release_host(gInstance->func[2]);
+-				}
+-			}
+-#if defined(MMC_SDIO_ABORT)
+-			/* to allow abort command through F1 */
+-			else if (regaddr == SDIOD_CCCR_IOABORT) {
+-				sdio_claim_host(gInstance->func[func]);
+-				/*
+-				 * this sdio_f0_writeb() can be replaced
+-				 * with another api
+-				 * depending upon MMC driver change.
+-				 * As of this time, this is temporaray one
+-				 */
+-				sdio_writeb(gInstance->func[func], *byte,
+-					    regaddr, &err_ret);
+-				sdio_release_host(gInstance->func[func]);
+-			}
+-#endif				/* MMC_SDIO_ABORT */
+-			else if (regaddr < 0xF0) {
+-				sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write "
+-					"disallowed\n", regaddr));
+-			} else {
+-				/* Claim host controller, perform F0 write,
+-				 and release */
+-				sdio_claim_host(gInstance->func[func]);
+-				sdio_f0_writeb(gInstance->func[func], *byte,
+-					       regaddr, &err_ret);
+-				sdio_release_host(gInstance->func[func]);
+-			}
+-		} else {
+-			/* Claim host controller, perform Fn write,
+-			 and release */
+-			sdio_claim_host(gInstance->func[func]);
+-			sdio_writeb(gInstance->func[func], *byte, regaddr,
+-				    &err_ret);
+-			sdio_release_host(gInstance->func[func]);
+-		}
+-	} else {		/* CMD52 Read */
+-		/* Claim host controller, perform Fn read, and release */
+-		sdio_claim_host(gInstance->func[func]);
+-
+-		if (func == 0) {
+-			*byte =
+-			    sdio_f0_readb(gInstance->func[func], regaddr,
+-					  &err_ret);
+-		} else {
+-			*byte =
+-			    sdio_readb(gInstance->func[func], regaddr,
+-				       &err_ret);
+-		}
+-
+-		sdio_release_host(gInstance->func[func]);
+-	}
+-
+-	if (err_ret)
+-		sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, "
+-			"Err: %d\n", rw ? "Write" : "Read", func, regaddr,
+-			*byte, err_ret));
+-
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func,
+-		   uint addr, u32 *word, uint nbytes)
+-{
+-	int err_ret = SDIOH_API_RC_FAIL;
+-
+-	if (func == 0) {
+-		sd_err(("%s: Only CMD52 allowed to F0.\n", __func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-
+-	sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
+-		 __func__, cmd_type, rw, func, addr, nbytes));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_word_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[func]);
+-
+-	if (rw) {		/* CMD52 Write */
+-		if (nbytes == 4) {
+-			sdio_writel(gInstance->func[func], *word, addr,
+-				    &err_ret);
+-		} else if (nbytes == 2) {
+-			sdio_writew(gInstance->func[func], (*word & 0xFFFF),
+-				    addr, &err_ret);
+-		} else {
+-			sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
+-		}
+-	} else {		/* CMD52 Read */
+-		if (nbytes == 4) {
+-			*word =
+-			    sdio_readl(gInstance->func[func], addr, &err_ret);
+-		} else if (nbytes == 2) {
+-			*word =
+-			    sdio_readw(gInstance->func[func], addr,
+-				       &err_ret) & 0xFFFF;
+-		} else {
+-			sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
+-		}
+-	}
+-
+-	/* Release host controller */
+-	sdio_release_host(gInstance->func[func]);
+-
+-	if (err_ret) {
+-		sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x",
+-			rw ? "Write" : "Read", err_ret));
+-	}
+-
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-static SDIOH_API_RC
+-sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
+-		     uint addr, struct sk_buff *pkt)
+-{
+-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
+-	u32 SGCount = 0;
+-	int err_ret = 0;
+-
+-	struct sk_buff *pnext;
+-
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-	ASSERT(pkt);
+-	DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[func]);
+-	for (pnext = pkt; pnext; pnext = pnext->next) {
+-		uint pkt_len = pnext->len;
+-		pkt_len += 3;
+-		pkt_len &= 0xFFFFFFFC;
+-
+-#ifdef CONFIG_MMC_MSM7X00A
+-		if ((pkt_len % 64) == 32) {
+-			sd_trace(("%s: Rounding up TX packet +=32\n",
+-				  __func__));
+-			pkt_len += 32;
+-		}
+-#endif				/* CONFIG_MMC_MSM7X00A */
+-		/* Make sure the packet is aligned properly.
+-		 * If it isn't, then this
+-		 * is the fault of sdioh_request_buffer() which
+-		 * is supposed to give
+-		 * us something we can work with.
+-		 */
+-		ASSERT(((u32) (pkt->data) & DMA_ALIGN_MASK) == 0);
+-
+-		if ((write) && (!fifo)) {
+-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
+-						   ((u8 *) (pnext->data)),
+-						   pkt_len);
+-		} else if (write) {
+-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
+-						   ((u8 *) (pnext->data)),
+-						   pkt_len);
+-		} else if (fifo) {
+-			err_ret = sdio_readsb(gInstance->func[func],
+-					      ((u8 *) (pnext->data)),
+-					      addr, pkt_len);
+-		} else {
+-			err_ret = sdio_memcpy_fromio(gInstance->func[func],
+-						     ((u8 *) (pnext->data)),
+-						     addr, pkt_len);
+-		}
+-
+-		if (err_ret) {
+-			sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d,"
+-				 "ERR=0x%08x\n", __func__,
+-				 (write) ? "TX" : "RX",
+-				 pnext, SGCount, addr, pkt_len, err_ret));
+-		} else {
+-			sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
+-				  __func__,
+-				  (write) ? "TX" : "RX",
+-				  pnext, SGCount, addr, pkt_len));
+-		}
+-
+-		if (!fifo)
+-			addr += pkt_len;
+-		SGCount++;
+-
+-	}
+-
+-	/* Release host controller */
+-	sdio_release_host(gInstance->func[func]);
+-
+-	sd_trace(("%s: Exit\n", __func__));
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-/*
+- * This function takes a buffer or packet, and fixes everything up
+- * so that in the end, a DMA-able packet is created.
+- *
+- * A buffer does not have an associated packet pointer,
+- * and may or may not be aligned.
+- * A packet may consist of a single packet, or a packet chain.
+- * If it is a packet chain, then all the packets in the chain
+- * must be properly aligned.
+- *
+- * If the packet data is not aligned, then there may only be
+- * one packet, and in this case,  it is copied to a new
+- * aligned packet.
+- *
+- */
+-extern SDIOH_API_RC
+-sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write,
+-		     uint func, uint addr, uint reg_width, uint buflen_u,
+-		     u8 *buffer, struct sk_buff *pkt)
+-{
+-	SDIOH_API_RC Status;
+-	struct sk_buff *mypkt = NULL;
+-
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	/* Case 1: we don't have a packet. */
+-	if (pkt == NULL) {
+-		sd_data(("%s: Creating new %s Packet, len=%d\n",
+-			 __func__, write ? "TX" : "RX", buflen_u));
+-		mypkt = bcm_pkt_buf_get_skb(buflen_u);
+-		if (!mypkt) {
+-			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
+-				__func__, buflen_u));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* For a write, copy the buffer data into the packet. */
+-		if (write)
+-			memcpy(mypkt->data, buffer, buflen_u);
+-
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+-
+-		/* For a read, copy the packet data back to the buffer. */
+-		if (!write)
+-			memcpy(buffer, mypkt->data, buflen_u);
+-
+-		bcm_pkt_buf_free_skb(mypkt);
+-	} else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
+-		/* Case 2: We have a packet, but it is unaligned. */
+-
+-		/* In this case, we cannot have a chain. */
+-		ASSERT(pkt->next == NULL);
+-
+-		sd_data(("%s: Creating aligned %s Packet, len=%d\n",
+-			 __func__, write ? "TX" : "RX", pkt->len));
+-		mypkt = bcm_pkt_buf_get_skb(pkt->len);
+-		if (!mypkt) {
+-			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
+-				__func__, pkt->len));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* For a write, copy the buffer data into the packet. */
+-		if (write)
+-			memcpy(mypkt->data, pkt->data, pkt->len);
+-
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+-
+-		/* For a read, copy the packet data back to the buffer. */
+-		if (!write)
+-			memcpy(pkt->data, mypkt->data, mypkt->len);
+-
+-		bcm_pkt_buf_free_skb(mypkt);
+-	} else {		/* case 3: We have a packet and
+-				 it is aligned. */
+-		sd_data(("%s: Aligned %s Packet, direct DMA\n",
+-			 __func__, write ? "Tx" : "Rx"));
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, pkt);
+-	}
+-
+-	return Status;
+-}
+-
+-/* this function performs "abort" for both of host & device */
+-extern int sdioh_abort(sdioh_info_t *sd, uint func)
+-{
+-#if defined(MMC_SDIO_ABORT)
+-	char t_func = (char)func;
+-#endif				/* defined(MMC_SDIO_ABORT) */
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-#if defined(MMC_SDIO_ABORT)
+-	/* issue abort cmd52 command through F1 */
+-	sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT,
+-			   &t_func);
+-#endif				/* defined(MMC_SDIO_ABORT) */
+-
+-	sd_trace(("%s: Exit\n", __func__));
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/* Reset and re-initialize the device */
+-int sdioh_sdio_reset(sdioh_info_t *si)
+-{
+-	sd_trace(("%s: Enter\n", __func__));
+-	sd_trace(("%s: Exit\n", __func__));
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/* Disable device interrupt */
+-void sdioh_sdmmc_devintr_off(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
+-	sd->intmask &= ~CLIENT_INTR;
+-}
+-
+-/* Enable device interrupt */
+-void sdioh_sdmmc_devintr_on(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
+-	sd->intmask |= CLIENT_INTR;
+-}
+-
+-/* Read client card reg */
+-int
+-sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
+-			 int regsize, u32 *data)
+-{
+-
+-	if ((func == 0) || (regsize == 1)) {
+-		u8 temp = 0;
+-
+-		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+-		*data = temp;
+-		*data &= 0xff;
+-		sd_data(("%s: byte read data=0x%02x\n", __func__, *data));
+-	} else {
+-		sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data,
+-				   regsize);
+-		if (regsize == 2)
+-			*data &= 0xffff;
+-
+-		sd_data(("%s: word read data=0x%08x\n", __func__, *data));
+-	}
+-
+-	return SUCCESS;
+-}
+-
+-#if !defined(OOB_INTR_ONLY)
+-/* bcmsdh_sdmmc interrupt handler */
+-static void IRQHandler(struct sdio_func *func)
+-{
+-	sdioh_info_t *sd;
+-
+-	sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n"));
+-	sd = gInstance->sd;
+-
+-	ASSERT(sd != NULL);
+-	sdio_release_host(gInstance->func[0]);
+-
+-	if (sd->use_client_ints) {
+-		sd->intrcount++;
+-		ASSERT(sd->intr_handler);
+-		ASSERT(sd->intr_handler_arg);
+-		(sd->intr_handler) (sd->intr_handler_arg);
+-	} else {
+-		sd_err(("bcmsdh_sdmmc: ***IRQHandler\n"));
+-
+-		sd_err(("%s: Not ready for intr: enabled %d, handler %p\n",
+-			__func__, sd->client_intr_enabled, sd->intr_handler));
+-	}
+-
+-	sdio_claim_host(gInstance->func[0]);
+-}
+-
+-/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */
+-static void IRQHandlerF2(struct sdio_func *func)
+-{
+-	sdioh_info_t *sd;
+-
+-	sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n"));
+-
+-	sd = gInstance->sd;
+-
+-	ASSERT(sd != NULL);
+-}
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-
+-#ifdef NOTUSED
+-/* Write client card reg */
+-static int
+-sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, u32 regaddr,
+-			  int regsize, u32 data)
+-{
+-
+-	if ((func == 0) || (regsize == 1)) {
+-		u8 temp;
+-
+-		temp = data & 0xff;
+-		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+-		sd_data(("%s: byte write data=0x%02x\n", __func__, data));
+-	} else {
+-		if (regsize == 2)
+-			data &= 0xffff;
+-
+-		sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data,
+-				   regsize);
+-
+-		sd_data(("%s: word write data=0x%08x\n", __func__, data));
+-	}
+-
+-	return SUCCESS;
+-}
+-#endif				/* NOTUSED */
+-
+-int sdioh_start(sdioh_info_t *si, int stage)
+-{
+-	return 0;
+-}
+-
+-int sdioh_stop(sdioh_info_t *si)
+-{
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
+deleted file mode 100644
+index 3ef42b3..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
++++ /dev/null
+@@ -1,134 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef __BCMSDH_SDMMC_H__
+-#define __BCMSDH_SDMMC_H__
+-
+-#ifdef BCMDBG
+-#define sd_err(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_trace(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_info(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_debug(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_data(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_ctrl(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#else
+-#define sd_err(x)
+-#define sd_trace(x)
+-#define sd_info(x)
+-#define sd_debug(x)
+-#define sd_data(x)
+-#define sd_ctrl(x)
+-#endif
+-
+-/* Allocate/init/free per-OS private data */
+-extern int sdioh_sdmmc_osinit(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_osfree(sdioh_info_t *sd);
+-
+-#define BLOCK_SIZE_64 64
+-#define BLOCK_SIZE_512 512
+-#define BLOCK_SIZE_4318 64
+-#define BLOCK_SIZE_4328 512
+-
+-/* internal return code */
+-#define SUCCESS	0
+-#define ERROR	1
+-
+-/* private bus modes */
+-#define SDIOH_MODE_SD4		2
+-#define CLIENT_INTR 		0x100	/* Get rid of this! */
+-
+-struct sdioh_info {
+-	struct osl_info *osh;		/* osh handler */
+-	bool client_intr_enabled;	/* interrupt connnected flag */
+-	bool intr_handler_valid;	/* client driver interrupt handler valid */
+-	sdioh_cb_fn_t intr_handler;	/* registered interrupt handler */
+-	void *intr_handler_arg;	/* argument to call interrupt handler */
+-	u16 intmask;		/* Current active interrupts */
+-	void *sdos_info;	/* Pointer to per-OS private data */
+-
+-	uint irq;		/* Client irq */
+-	int intrcount;		/* Client interrupts */
+-	bool sd_use_dma;	/* DMA on CMD53 */
+-	bool sd_blockmode;	/* sd_blockmode == false => 64 Byte Cmd 53s. */
+-	/*  Must be on for sd_multiblock to be effective */
+-	bool use_client_ints;	/* If this is false, make sure to restore */
+-	int sd_mode;		/* SD1/SD4/SPI */
+-	int client_block_size[SDIOD_MAX_IOFUNCS];	/* Blocksize */
+-	u8 num_funcs;	/* Supported funcs on client */
+-	u32 com_cis_ptr;
+-	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+-	uint max_dma_len;
+-	uint max_dma_descriptors;	/* DMA Descriptors supported by this controller. */
+-	/*	SDDMA_DESCRIPTOR	SGList[32]; *//* Scatter/Gather DMA List */
+-};
+-
+-/************************************************************
+- * Internal interfaces: per-port references into bcmsdh_sdmmc.c
+- */
+-
+-/* Global message bits */
+-extern uint sd_msglevel;
+-
+-/* OS-independent interrupt handler */
+-extern bool check_client_intr(sdioh_info_t *sd);
+-
+-/* Core interrupt enable/disable of device interrupts */
+-extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+-
+-/**************************************************************
+- * Internal interfaces: bcmsdh_sdmmc.c references to per-port code
+- */
+-
+-/* Register mapping routines */
+-extern u32 *sdioh_sdmmc_reg_map(s32 addr, int size);
+-extern void sdioh_sdmmc_reg_unmap(s32 addr, int size);
+-
+-/* Interrupt (de)registration routines */
+-extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq);
+-extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd);
+-
+-typedef struct _BCMSDH_SDMMC_INSTANCE {
+-	sdioh_info_t *sd;
+-	struct sdio_func *func[SDIOD_MAX_IOFUNCS];
+-	u32 host_claimed;
+-} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE;
+-
+-#endif				/* __BCMSDH_SDMMC_H__ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
+deleted file mode 100644
+index 2792a4d..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
++++ /dev/null
+@@ -1,235 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/types.h>
+-#include <linux/sched.h>	/* request_irq() */
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <sdio.h>		/* SDIO Specs */
+-#include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
+-#include <sdiovar.h>		/* to get msglevel bit values */
+-
+-#include <linux/mmc/core.h>
+-#include <linux/mmc/card.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/mmc/sdio_ids.h>
+-
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-#if !defined(SDIO_VENDOR_ID_BROADCOM)
+-#define SDIO_VENDOR_ID_BROADCOM		0x02d0
+-#endif				/* !defined(SDIO_VENDOR_ID_BROADCOM) */
+-
+-#define SDIO_DEVICE_ID_BROADCOM_DEFAULT	0x0000
+-
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
+-#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB	0x0492	/* BCM94325SDGWB */
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
+-#define SDIO_DEVICE_ID_BROADCOM_4325	0x0493
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
+-#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
+-#define SDIO_DEVICE_ID_BROADCOM_4319	0x4319
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+-
+-#include <bcmsdh_sdmmc.h>
+-
+-#include <dhd_dbg.h>
+-#include <wl_cfg80211.h>
+-
+-extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+-
+-int sdio_function_init(void);
+-void sdio_function_cleanup(void);
+-
+-/* module param defaults */
+-static int clockoverride;
+-
+-module_param(clockoverride, int, 0644);
+-MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
+-
+-PBCMSDH_SDMMC_INSTANCE gInstance;
+-
+-/* Maximum number of bcmsdh_sdmmc devices supported by driver */
+-#define BCMSDH_SDMMC_MAX_DEVICES 1
+-
+-extern int bcmsdh_probe(struct device *dev);
+-extern int bcmsdh_remove(struct device *dev);
+-struct device sdmmc_dev;
+-
+-static int bcmsdh_sdmmc_probe(struct sdio_func *func,
+-			      const struct sdio_device_id *id)
+-{
+-	int ret = 0;
+-	static struct sdio_func sdio_func_0;
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-	sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class));
+-	sd_trace(("sdio_vendor: 0x%04x\n", func->vendor));
+-	sd_trace(("sdio_device: 0x%04x\n", func->device));
+-	sd_trace(("Function#: 0x%04x\n", func->num));
+-
+-	if (func->num == 1) {
+-		sdio_func_0.num = 0;
+-		sdio_func_0.card = func->card;
+-		gInstance->func[0] = &sdio_func_0;
+-		if (func->device == 0x4) {	/* 4318 */
+-			gInstance->func[2] = NULL;
+-			sd_trace(("NIC found, calling bcmsdh_probe...\n"));
+-			ret = bcmsdh_probe(&sdmmc_dev);
+-		}
+-	}
+-
+-	gInstance->func[func->num] = func;
+-
+-	if (func->num == 2) {
+-		wl_cfg80211_sdio_func(func);
+-		sd_trace(("F2 found, calling bcmsdh_probe...\n"));
+-		ret = bcmsdh_probe(&sdmmc_dev);
+-	}
+-
+-	return ret;
+-}
+-
+-static void bcmsdh_sdmmc_remove(struct sdio_func *func)
+-{
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-	sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
+-	sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
+-	sd_info(("sdio_device: 0x%04x\n", func->device));
+-	sd_info(("Function#: 0x%04x\n", func->num));
+-
+-	if (func->num == 2) {
+-		sd_trace(("F2 found, calling bcmsdh_remove...\n"));
+-		bcmsdh_remove(&sdmmc_dev);
+-	}
+-}
+-
+-/* devices we support, null terminated */
+-static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)},
+-	{SDIO_DEVICE
+-	 (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)},
+-	{ /* end: all zeroes */ },
+-};
+-
+-MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+-
+-static struct sdio_driver bcmsdh_sdmmc_driver = {
+-	.probe = bcmsdh_sdmmc_probe,
+-	.remove = bcmsdh_sdmmc_remove,
+-	.name = "brcmfmac",
+-	.id_table = bcmsdh_sdmmc_ids,
+-};
+-
+-struct sdos_info {
+-	sdioh_info_t *sd;
+-	spinlock_t lock;
+-};
+-
+-int sdioh_sdmmc_osinit(sdioh_info_t *sd)
+-{
+-	struct sdos_info *sdos;
+-
+-	sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
+-	sd->sdos_info = (void *)sdos;
+-	if (sdos == NULL)
+-		return -ENOMEM;
+-
+-	sdos->sd = sd;
+-	spin_lock_init(&sdos->lock);
+-	return 0;
+-}
+-
+-void sdioh_sdmmc_osfree(sdioh_info_t *sd)
+-{
+-	struct sdos_info *sdos;
+-	ASSERT(sd && sd->sdos_info);
+-
+-	sdos = (struct sdos_info *)sd->sdos_info;
+-	kfree(sdos);
+-}
+-
+-/* Interrupt enable/disable */
+-SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
+-{
+-	unsigned long flags;
+-	struct sdos_info *sdos;
+-
+-	sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling"));
+-
+-	sdos = (struct sdos_info *)sd->sdos_info;
+-	ASSERT(sdos);
+-
+-#if !defined(OOB_INTR_ONLY)
+-	if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
+-		sd_err(("%s: no handler registered, will not enable\n",
+-			__func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-
+-	/* Ensure atomicity for enable/disable calls */
+-	spin_lock_irqsave(&sdos->lock, flags);
+-
+-	sd->client_intr_enabled = enable;
+-	if (enable)
+-		sdioh_sdmmc_devintr_on(sd);
+-	else
+-		sdioh_sdmmc_devintr_off(sd);
+-
+-	spin_unlock_irqrestore(&sdos->lock, flags);
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/*
+- * module init
+-*/
+-int sdio_function_init(void)
+-{
+-	int error = 0;
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-
+-	gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
+-	if (!gInstance)
+-		return -ENOMEM;
+-
+-	memset(&sdmmc_dev, 0, sizeof(sdmmc_dev));
+-	error = sdio_register_driver(&bcmsdh_sdmmc_driver);
+-
+-	return error;
+-}
+-
+-/*
+- * module cleanup
+-*/
+-extern int bcmsdh_remove(struct device *dev);
+-void sdio_function_cleanup(void)
+-{
+-	sd_trace(("%s Enter\n", __func__));
+-
+-	sdio_unregister_driver(&bcmsdh_sdmmc_driver);
+-
+-	kfree(gInstance);
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h
+deleted file mode 100644
+index a726b49..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd.h
++++ /dev/null
+@@ -1,414 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/****************
+- * Common types *
+- */
+-
+-#ifndef _dhd_h_
+-#define _dhd_h_
+-
+-#include <linux/sched.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/skbuff.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/random.h>
+-#include <linux/spinlock.h>
+-#include <linux/ethtool.h>
+-#include <linux/suspend.h>
+-#include <asm/uaccess.h>
+-#include <asm/unaligned.h>
+-/* The kernel threading is sdio-specific */
+-
+-#include <wlioctl.h>
+-
+-/* Forward decls */
+-struct dhd_bus;
+-struct dhd_prot;
+-struct dhd_info;
+-
+-/* The level of bus communication with the dongle */
+-enum dhd_bus_state {
+-	DHD_BUS_DOWN,		/* Not ready for frame transfers */
+-	DHD_BUS_LOAD,		/* Download access only (CPU reset) */
+-	DHD_BUS_DATA		/* Ready for frame transfers */
+-};
+-
+-/* Common structure for module and instance linkage */
+-typedef struct dhd_pub {
+-	/* Linkage ponters */
+-	struct dhd_bus *bus;	/* Bus module handle */
+-	struct dhd_prot *prot;	/* Protocol module handle */
+-	struct dhd_info *info;	/* Info module handle */
+-
+-	/* Internal dhd items */
+-	bool up;		/* Driver up/down (to OS) */
+-	bool txoff;		/* Transmit flow-controlled */
+-	bool dongle_reset;	/* true = DEVRESET put dongle into reset */
+-	enum dhd_bus_state busstate;
+-	uint hdrlen;		/* Total DHD header length (proto + bus) */
+-	uint maxctl;		/* Max size rxctl request from proto to bus */
+-	uint rxsz;		/* Rx buffer size bus module should use */
+-	u8 wme_dp;		/* wme discard priority */
+-
+-	/* Dongle media info */
+-	bool iswl;		/* Dongle-resident driver is wl */
+-	unsigned long drv_version;	/* Version of dongle-resident driver */
+-	u8 mac[ETH_ALEN];			/* MAC address obtained from dongle */
+-	dngl_stats_t dstats;		/* Stats for dongle-based data */
+-
+-	/* Additional stats for the bus level */
+-	unsigned long tx_packets;	/* Data packets sent to dongle */
+-	unsigned long tx_multicast;	/* Multicast data packets sent to dongle */
+-	unsigned long tx_errors;	/* Errors in sending data to dongle */
+-	unsigned long tx_ctlpkts;	/* Control packets sent to dongle */
+-	unsigned long tx_ctlerrs;	/* Errors sending control frames to dongle */
+-	unsigned long rx_packets;	/* Packets sent up the network interface */
+-	unsigned long rx_multicast;	/* Multicast packets sent up the network
+-					 interface */
+-	unsigned long rx_errors;	/* Errors processing rx data packets */
+-	unsigned long rx_ctlpkts;	/* Control frames processed from dongle */
+-	unsigned long rx_ctlerrs;	/* Errors in processing rx control frames */
+-	unsigned long rx_dropped;	/* Packets dropped locally (no memory) */
+-	unsigned long rx_flushed;	/* Packets flushed due to
+-				unscheduled sendup thread */
+-	unsigned long wd_dpc_sched;	/* Number of times dhd dpc scheduled by
+-					 watchdog timer */
+-
+-	unsigned long rx_readahead_cnt;	/* Number of packets where header read-ahead
+-					 was used. */
+-	unsigned long tx_realloc;	/* Number of tx packets we had to realloc for
+-					 headroom */
+-	unsigned long fc_packets;	/* Number of flow control pkts recvd */
+-
+-	/* Last error return */
+-	int bcmerror;
+-	uint tickcnt;
+-
+-	/* Last error from dongle */
+-	int dongle_error;
+-
+-	/* Suspend disable flag  flag */
+-	int suspend_disable_flag;	/* "1" to disable all extra powersaving
+-					 during suspend */
+-	int in_suspend;		/* flag set to 1 when early suspend called */
+-#ifdef PNO_SUPPORT
+-	int pno_enable;		/* pno status : "1" is pno enable */
+-#endif				/* PNO_SUPPORT */
+-	int dtim_skip;		/* dtim skip , default 0 means wake each dtim */
+-
+-	/* Pkt filter defination */
+-	char *pktfilter[100];
+-	int pktfilter_count;
+-
+-	u8 country_code[WLC_CNTRY_BUF_SZ];
+-	char eventmask[WL_EVENTING_MASK_LEN];
+-
+-} dhd_pub_t;
+-
+-#if defined(CONFIG_PM_SLEEP)
+-extern atomic_t dhd_mmc_suspend;
+-#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+-#define _DHD_PM_RESUME_WAIT(a, b) do { \
+-		int retry = 0; \
+-		while (atomic_read(&dhd_mmc_suspend) && retry++ != b) { \
+-			wait_event_timeout(a, false, HZ/100); \
+-		} \
+-	}	while (0)
+-#define DHD_PM_RESUME_WAIT(a)	_DHD_PM_RESUME_WAIT(a, 30)
+-#define DHD_PM_RESUME_WAIT_FOREVER(a)	_DHD_PM_RESUME_WAIT(a, ~0)
+-#define DHD_PM_RESUME_RETURN_ERROR(a)	\
+-	do { if (atomic_read(&dhd_mmc_suspend)) return a; } while (0)
+-#define DHD_PM_RESUME_RETURN	do { \
+-	if (atomic_read(&dhd_mmc_suspend)) \
+-		return; \
+-	} while (0)
+-
+-#define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+-#define SPINWAIT_SLEEP(a, exp, us) do { \
+-		uint countdown = (us) + 9999; \
+-		while ((exp) && (countdown >= 10000)) { \
+-			wait_event_timeout(a, false, HZ/100); \
+-			countdown -= 10000; \
+-		} \
+-	} while (0)
+-
+-#else
+-
+-#define DHD_PM_RESUME_WAIT_INIT(a)
+-#define DHD_PM_RESUME_WAIT(a)
+-#define DHD_PM_RESUME_WAIT_FOREVER(a)
+-#define DHD_PM_RESUME_RETURN_ERROR(a)
+-#define DHD_PM_RESUME_RETURN
+-
+-#define DHD_SPINWAIT_SLEEP_INIT(a)
+-#define SPINWAIT_SLEEP(a, exp, us)  do { \
+-		uint countdown = (us) + 9; \
+-		while ((exp) && (countdown >= 10)) { \
+-			udelay(10);  \
+-			countdown -= 10;  \
+-		} \
+-	} while (0)
+-
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-#define DHD_IF_VIF	0x01	/* Virtual IF (Hidden from user) */
+-
+-static inline void MUTEX_LOCK_INIT(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_WL_SCAN_SET_INIT(void)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_WL_SCAN_SET(void)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK_WL_SCAN_SET(void)
+-{
+-}
+-
+-typedef struct dhd_if_event {
+-	u8 ifidx;
+-	u8 action;
+-	u8 flags;
+-	u8 bssidx;
+-} dhd_if_event_t;
+-
+-/*
+- * Exported from dhd OS modules (dhd_linux/dhd_ndis)
+- */
+-
+-/* Indication from bus module regarding presence/insertion of dongle.
+- * Return dhd_pub_t pointer, used as handle to OS module in later calls.
+- * Returned structure should have bus and prot pointers filled in.
+- * bus_hdrlen specifies required headroom for bus module header.
+- */
+-extern dhd_pub_t *dhd_attach(struct dhd_bus *bus,
+-				uint bus_hdrlen);
+-extern int dhd_net_attach(dhd_pub_t *dhdp, int idx);
+-
+-/* Indication from bus module regarding removal/absence of dongle */
+-extern void dhd_detach(dhd_pub_t *dhdp);
+-
+-/* Indication from bus module to change flow-control state */
+-extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on);
+-
+-extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q,
+-			 struct sk_buff *pkt, int prec);
+-
+-/* Receive frame for delivery to OS.  Callee disposes of rxp. */
+-extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx,
+-			 struct sk_buff *rxp, int numpkt);
+-
+-/* Return pointer to interface name */
+-extern char *dhd_ifname(dhd_pub_t *dhdp, int idx);
+-
+-/* Request scheduling of the bus dpc */
+-extern void dhd_sched_dpc(dhd_pub_t *dhdp);
+-
+-/* Notify tx completion */
+-extern void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success);
+-
+-/* Query ioctl */
+-extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			      uint len);
+-
+-/* OS independent layer functions */
+-extern int dhd_os_proto_block(dhd_pub_t *pub);
+-extern int dhd_os_proto_unblock(dhd_pub_t *pub);
+-extern int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition,
+-				  bool *pending);
+-extern int dhd_os_ioctl_resp_wake(dhd_pub_t *pub);
+-extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
+-extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
+-extern void *dhd_os_open_image(char *filename);
+-extern int dhd_os_get_image_block(char *buf, int len, void *image);
+-extern void dhd_os_close_image(void *image);
+-extern void dhd_os_wd_timer(void *bus, uint wdtick);
+-extern void dhd_os_sdlock(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_txq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_txq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t *pub);
+-extern void dhd_customer_gpio_wlan_ctrl(int onoff);
+-extern int dhd_custom_get_mac_address(unsigned char *buf);
+-extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_eventq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_eventq(dhd_pub_t *pub);
+-#ifdef DHD_DEBUG
+-extern int write_to_file(dhd_pub_t *dhd, u8 *buf, int size);
+-#endif				/* DHD_DEBUG */
+-#if defined(OOB_INTR_ONLY)
+-extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-extern void dhd_os_sdtxlock(dhd_pub_t *pub);
+-extern void dhd_os_sdtxunlock(dhd_pub_t *pub);
+-
+-int setScheduler(struct task_struct *p, int policy, struct sched_param *param);
+-
+-typedef struct {
+-	u32 limit;		/* Expiration time (usec) */
+-	u32 increment;	/* Current expiration increment (usec) */
+-	u32 elapsed;		/* Current elapsed time (usec) */
+-	u32 tick;		/* O/S tick time (usec) */
+-} dhd_timeout_t;
+-
+-extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
+-extern int dhd_timeout_expired(dhd_timeout_t *tmo);
+-
+-extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+-extern u8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx);
+-extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata,
+-			 wl_event_msg_t *, void **data_ptr);
+-
+-extern void dhd_common_init(void);
+-
+-extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
+-		      char *name, u8 *mac_addr, u32 flags, u8 bssidx);
+-extern void dhd_del_if(struct dhd_info *dhd, int ifidx);
+-
+-extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char *name);
+-extern void dhd_vif_del(struct dhd_info *dhd, int ifidx);
+-
+-extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx);
+-extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, unsigned char * cp,
+-			   int len);
+-
+-/* Send packet to dongle via data channel */
+-extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pkt);
+-
+-/* Send event to host */
+-extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event,
+-			     void *data);
+-extern int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag);
+-extern uint dhd_bus_status(dhd_pub_t *dhdp);
+-extern int dhd_bus_start(dhd_pub_t *dhdp);
+-
+-enum cust_gpio_modes {
+-	WLAN_RESET_ON,
+-	WLAN_RESET_OFF,
+-	WLAN_POWER_ON,
+-	WLAN_POWER_OFF
+-};
+-/*
+- * Insmod parameters for debug/test
+- */
+-
+-/* Watchdog timer interval */
+-extern uint dhd_watchdog_ms;
+-
+-#if defined(DHD_DEBUG)
+-/* Console output poll interval */
+-extern uint dhd_console_ms;
+-#endif				/* defined(DHD_DEBUG) */
+-
+-/* Use interrupts */
+-extern uint dhd_intr;
+-
+-/* Use polling */
+-extern uint dhd_poll;
+-
+-/* ARP offload agent mode */
+-extern uint dhd_arp_mode;
+-
+-/* ARP offload enable */
+-extern uint dhd_arp_enable;
+-
+-/* Pkt filte enable control */
+-extern uint dhd_pkt_filter_enable;
+-
+-/*  Pkt filter init setup */
+-extern uint dhd_pkt_filter_init;
+-
+-/* Pkt filter mode control */
+-extern uint dhd_master_mode;
+-
+-/* Roaming mode control */
+-extern uint dhd_roam;
+-
+-/* Roaming mode control */
+-extern uint dhd_radio_up;
+-
+-/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
+-extern int dhd_idletime;
+-#define DHD_IDLETIME_TICKS 1
+-
+-/* SDIO Drive Strength */
+-extern uint dhd_sdiod_drive_strength;
+-
+-/* Override to force tx queueing all the time */
+-extern uint dhd_force_tx_queueing;
+-
+-#ifdef SDTEST
+-/* Echo packet generator (SDIO), pkts/s */
+-extern uint dhd_pktgen;
+-
+-/* Echo packet len (0 => sawtooth, max 1800) */
+-extern uint dhd_pktgen_len;
+-#define MAX_PKTGEN_LEN 1800
+-#endif
+-
+-/* optionally set by a module_param_string() */
+-#define MOD_PARAM_PATHLEN	2048
+-extern char fw_path[MOD_PARAM_PATHLEN];
+-extern char nv_path[MOD_PARAM_PATHLEN];
+-
+-/* For supporting multiple interfaces */
+-#define DHD_MAX_IFS	16
+-#define DHD_DEL_IF	-0xe
+-#define DHD_BAD_IF	-0xf
+-
+-extern void dhd_wait_for_event(dhd_pub_t *dhd, bool * lockvar);
+-extern void dhd_wait_event_wakeup(dhd_pub_t *dhd);
+-
+-extern u32 g_assert_type;
+-
+-#ifdef BCMDBG
+-#define ASSERT(exp) \
+-	  do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
+-extern void osl_assert(char *exp, char *file, int line);
+-#else
+-#define ASSERT(exp)	do {} while (0)
+-#endif  /* defined(BCMDBG) */
+-
+-#endif				/* _dhd_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
+deleted file mode 100644
+index 065f1ae..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
++++ /dev/null
+@@ -1,82 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_bus_h_
+-#define _dhd_bus_h_
+-
+-/*
+- * Exported from dhd bus module (dhd_usb, dhd_sdio)
+- */
+-
+-/* Indicate (dis)interest in finding dongles. */
+-extern int dhd_bus_register(void);
+-extern void dhd_bus_unregister(void);
+-
+-/* Download firmware image and nvram image */
+-extern bool dhd_bus_download_firmware(struct dhd_bus *bus,
+-				      char *fw_path, char *nv_path);
+-
+-/* Stop bus module: clear pending frames, disable data flow */
+-extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
+-
+-/* Initialize bus module: prepare for communication w/dongle */
+-extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
+-
+-/* Send a data frame to the dongle.  Callee disposes of txp. */
+-extern int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *txp);
+-
+-/* Send/receive a control message to/from the dongle.
+- * Expects caller to enforce a single outstanding transaction.
+- */
+-extern int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
+-extern int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
+-
+-/* Watchdog timer function */
+-extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+-
+-#ifdef DHD_DEBUG
+-/* Device console input function */
+-extern int dhd_bus_console_in(dhd_pub_t *dhd, unsigned char *msg, uint msglen);
+-#endif				/* DHD_DEBUG */
+-
+-/* Deferred processing for the bus, return true requests reschedule */
+-extern bool dhd_bus_dpc(struct dhd_bus *bus);
+-extern void dhd_bus_isr(bool *InterruptRecognized,
+-			bool *QueueMiniportHandleInterrupt, void *arg);
+-
+-/* Check for and handle local prot-specific iovar commands */
+-extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+-			    void *params, int plen, void *arg, int len,
+-			    bool set);
+-
+-/* Add bus dump output to a buffer */
+-extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+-
+-/* Clear any bus counters */
+-extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
+-
+-/* return the dongle chipid */
+-extern uint dhd_bus_chip(struct dhd_bus *bus);
+-
+-/* Set user-specified nvram parameters. */
+-extern void dhd_bus_set_nvram_params(struct dhd_bus *bus,
+-				     const char *nvram_params);
+-
+-extern void *dhd_bus_pub(struct dhd_bus *bus);
+-extern void *dhd_bus_txq(struct dhd_bus *bus);
+-extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
+-
+-#endif				/* _dhd_bus_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+deleted file mode 100644
+index ba5a5cb..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
++++ /dev/null
+@@ -1,474 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-
+-#include <bcmutils.h>
+-#include <bcmcdc.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_proto.h>
+-#include <dhd_bus.h>
+-#include <dhd_dbg.h>
+-#ifdef CUSTOMER_HW2
+-int wifi_get_mac_addr(unsigned char *buf);
+-#endif
+-
+-extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#define RETRIES 2	/* # of retries to retrieve matching ioctl response */
+-#define BUS_HEADER_LEN	(16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE
+-					 * defined in dhd_sdio.c
+-					 * (amount of header tha might be added)
+-					 * plus any space that might be needed
+-					 * for alignment padding.
+-					 */
+-#define ROUND_UP_MARGIN	2048	/* Biggest SDIO block size possible for
+-				 * round off at the end of buffer
+-				 */
+-
+-typedef struct dhd_prot {
+-	u16 reqid;
+-	u8 pending;
+-	u32 lastcmd;
+-	u8 bus_header[BUS_HEADER_LEN];
+-	cdc_ioctl_t msg;
+-	unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
+-} dhd_prot_t;
+-
+-static int dhdcdc_msg(dhd_pub_t *dhd)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	int len = le32_to_cpu(prot->msg.len) + sizeof(cdc_ioctl_t);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
+-	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
+-	 *        is actually sent to the dongle
+-	 */
+-	if (len > CDC_MAX_MSG_SIZE)
+-		len = CDC_MAX_MSG_SIZE;
+-
+-	/* Send request */
+-	return dhd_bus_txctl(dhd->bus, (unsigned char *)&prot->msg, len);
+-}
+-
+-static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len)
+-{
+-	int ret;
+-	dhd_prot_t *prot = dhd->prot;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	do {
+-		ret =
+-		    dhd_bus_rxctl(dhd->bus, (unsigned char *)&prot->msg,
+-				  len + sizeof(cdc_ioctl_t));
+-		if (ret < 0)
+-			break;
+-	} while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
+-
+-	return ret;
+-}
+-
+-int
+-dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	cdc_ioctl_t *msg = &prot->msg;
+-	void *info;
+-	int ret = 0, retries = 0;
+-	u32 id, flags = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
+-
+-	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
+-	if (cmd == WLC_GET_VAR && buf) {
+-		if (!strcmp((char *)buf, "bcmerrorstr")) {
+-			strncpy((char *)buf, "bcm_error",
+-				BCME_STRLEN);
+-			goto done;
+-		} else if (!strcmp((char *)buf, "bcmerror")) {
+-			*(int *)buf = dhd->dongle_error;
+-			goto done;
+-		}
+-	}
+-
+-	memset(msg, 0, sizeof(cdc_ioctl_t));
+-
+-	msg->cmd = cpu_to_le32(cmd);
+-	msg->len = cpu_to_le32(len);
+-	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+-	CDC_SET_IF_IDX(msg, ifidx);
+-	msg->flags = cpu_to_le32(msg->flags);
+-
+-	if (buf)
+-		memcpy(prot->buf, buf, len);
+-
+-	ret = dhdcdc_msg(dhd);
+-	if (ret < 0) {
+-		DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status "
+-			"%d\n", ret));
+-		goto done;
+-	}
+-
+-retry:
+-	/* wait for interrupt and get first fragment */
+-	ret = dhdcdc_cmplt(dhd, prot->reqid, len);
+-	if (ret < 0)
+-		goto done;
+-
+-	flags = le32_to_cpu(msg->flags);
+-	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+-
+-	if ((id < prot->reqid) && (++retries < RETRIES))
+-		goto retry;
+-	if (id != prot->reqid) {
+-		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+-			   dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
+-		ret = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Check info buffer */
+-	info = (void *)&msg[1];
+-
+-	/* Copy info buffer */
+-	if (buf) {
+-		if (ret < (int)len)
+-			len = ret;
+-		memcpy(buf, info, len);
+-	}
+-
+-	/* Check the ERROR flag */
+-	if (flags & CDCF_IOC_ERROR) {
+-		ret = le32_to_cpu(msg->status);
+-		/* Cache error from dongle */
+-		dhd->dongle_error = ret;
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	cdc_ioctl_t *msg = &prot->msg;
+-	int ret = 0;
+-	u32 flags, id;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
+-
+-	memset(msg, 0, sizeof(cdc_ioctl_t));
+-
+-	msg->cmd = cpu_to_le32(cmd);
+-	msg->len = cpu_to_le32(len);
+-	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
+-	CDC_SET_IF_IDX(msg, ifidx);
+-	msg->flags = cpu_to_le32(msg->flags);
+-
+-	if (buf)
+-		memcpy(prot->buf, buf, len);
+-
+-	ret = dhdcdc_msg(dhd);
+-	if (ret < 0)
+-		goto done;
+-
+-	ret = dhdcdc_cmplt(dhd, prot->reqid, len);
+-	if (ret < 0)
+-		goto done;
+-
+-	flags = le32_to_cpu(msg->flags);
+-	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+-
+-	if (id != prot->reqid) {
+-		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+-			   dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
+-		ret = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Check the ERROR flag */
+-	if (flags & CDCF_IOC_ERROR) {
+-		ret = le32_to_cpu(msg->status);
+-		/* Cache error from dongle */
+-		dhd->dongle_error = ret;
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void *arg2);
+-int
+-dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	int ret = -1;
+-
+-	if (dhd->busstate == DHD_BUS_DOWN) {
+-		DHD_ERROR(("%s : bus is down. we have nothing to do\n",
+-			   __func__));
+-		return ret;
+-	}
+-	dhd_os_proto_block(dhd);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(len <= WLC_IOCTL_MAXLEN);
+-
+-	if (len > WLC_IOCTL_MAXLEN)
+-		goto done;
+-
+-	if (prot->pending == true) {
+-		DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
+-			"lastcmd=0x%x (%lu)\n",
+-			ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
+-			(unsigned long)prot->lastcmd));
+-		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR))
+-			DHD_TRACE(("iovar cmd=%s\n", (char *)buf));
+-
+-		goto done;
+-	}
+-
+-	prot->pending = true;
+-	prot->lastcmd = ioc->cmd;
+-	if (ioc->set)
+-		ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len);
+-	else {
+-		ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len);
+-		if (ret > 0)
+-			ioc->used = ret - sizeof(cdc_ioctl_t);
+-	}
+-
+-	/* Too many programs assume ioctl() returns 0 on success */
+-	if (ret >= 0)
+-		ret = 0;
+-	else {
+-		cdc_ioctl_t *msg = &prot->msg;
+-		/* len == needed when set/query fails from dongle */
+-		ioc->needed = le32_to_cpu(msg->len);
+-	}
+-
+-	/* Intercept the wme_dp ioctl here */
+-	if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
+-		int slen, val = 0;
+-
+-		slen = strlen("wme_dp") + 1;
+-		if (len >= (int)(slen + sizeof(int)))
+-			memcpy(&val, (char *)buf + slen, sizeof(int));
+-		dhd->wme_dp = (u8) le32_to_cpu(val);
+-	}
+-
+-	prot->pending = false;
+-
+-done:
+-	dhd_os_proto_unblock(dhd);
+-
+-	return ret;
+-}
+-
+-#define PKTSUMNEEDED(skb) \
+-		(((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL)
+-#define PKTSETSUMGOOD(skb, x) \
+-		(((struct sk_buff *)(skb))->ip_summed = \
+-		((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+-
+-/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because
+-	skb->ip_summed is overloaded */
+-
+-int
+-dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+-		  void *params, int plen, void *arg, int len, bool set)
+-{
+-	return -ENOTSUPP;
+-}
+-
+-void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+-{
+-	bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
+-}
+-
+-void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf)
+-{
+-#ifdef BDC
+-	struct bdc_header *h;
+-#endif				/* BDC */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef BDC
+-	/* Push BDC header used to convey priority for buses that don't */
+-
+-	skb_push(pktbuf, BDC_HEADER_LEN);
+-
+-	h = (struct bdc_header *)(pktbuf->data);
+-
+-	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+-	if (PKTSUMNEEDED(pktbuf))
+-		h->flags |= BDC_FLAG_SUM_NEEDED;
+-
+-	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
+-	h->flags2 = 0;
+-	h->rssi = 0;
+-#endif				/* BDC */
+-	BDC_SET_IF_IDX(h, ifidx);
+-}
+-
+-int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf)
+-{
+-#ifdef BDC
+-	struct bdc_header *h;
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef BDC
+-	/* Pop BDC header used to convey priority for buses that don't */
+-
+-	if (pktbuf->len < BDC_HEADER_LEN) {
+-		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
+-			   pktbuf->len, BDC_HEADER_LEN));
+-		return -EBADE;
+-	}
+-
+-	h = (struct bdc_header *)(pktbuf->data);
+-
+-	*ifidx = BDC_GET_IF_IDX(h);
+-	if (*ifidx >= DHD_MAX_IFS) {
+-		DHD_ERROR(("%s: rx data ifnum out of range (%d)\n",
+-			   __func__, *ifidx));
+-		return -EBADE;
+-	}
+-
+-	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
+-	    BDC_PROTO_VER) {
+-		DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
+-			   dhd_ifname(dhd, *ifidx), h->flags));
+-		return -EBADE;
+-	}
+-
+-	if (h->flags & BDC_FLAG_SUM_GOOD) {
+-		DHD_INFO(("%s: BDC packet received with good rx-csum, "
+-			"flags 0x%x\n",
+-			dhd_ifname(dhd, *ifidx), h->flags));
+-		PKTSETSUMGOOD(pktbuf, true);
+-	}
+-
+-	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
+-
+-	skb_pull(pktbuf, BDC_HEADER_LEN);
+-#endif				/* BDC */
+-
+-	return 0;
+-}
+-
+-int dhd_prot_attach(dhd_pub_t *dhd)
+-{
+-	dhd_prot_t *cdc;
+-
+-	cdc = kzalloc(sizeof(dhd_prot_t), GFP_ATOMIC);
+-	if (!cdc) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* ensure that the msg buf directly follows the cdc msg struct */
+-	if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
+-		DHD_ERROR(("dhd_prot_t is not correctly defined\n"));
+-		goto fail;
+-	}
+-
+-	dhd->prot = cdc;
+-#ifdef BDC
+-	dhd->hdrlen += BDC_HEADER_LEN;
+-#endif
+-	dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
+-	return 0;
+-
+-fail:
+-	kfree(cdc);
+-	return -ENOMEM;
+-}
+-
+-/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
+-void dhd_prot_detach(dhd_pub_t *dhd)
+-{
+-	kfree(dhd->prot);
+-	dhd->prot = NULL;
+-}
+-
+-void dhd_prot_dstats(dhd_pub_t *dhd)
+-{
+-	/* No stats from dongle added yet, copy bus stats */
+-	dhd->dstats.tx_packets = dhd->tx_packets;
+-	dhd->dstats.tx_errors = dhd->tx_errors;
+-	dhd->dstats.rx_packets = dhd->rx_packets;
+-	dhd->dstats.rx_errors = dhd->rx_errors;
+-	dhd->dstats.rx_dropped = dhd->rx_dropped;
+-	dhd->dstats.multicast = dhd->rx_multicast;
+-	return;
+-}
+-
+-int dhd_prot_init(dhd_pub_t *dhd)
+-{
+-	int ret = 0;
+-	char buf[128];
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhd_os_proto_block(dhd);
+-
+-	/* Get the device MAC address */
+-	strcpy(buf, "cur_etheraddr");
+-	ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
+-	if (ret < 0) {
+-		dhd_os_proto_unblock(dhd);
+-		return ret;
+-	}
+-	memcpy(dhd->mac, buf, ETH_ALEN);
+-
+-	dhd_os_proto_unblock(dhd);
+-
+-#ifdef EMBEDDED_PLATFORM
+-	ret = dhd_preinit_ioctls(dhd);
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	/* Always assumes wl for now */
+-	dhd->iswl = true;
+-
+-	return ret;
+-}
+-
+-void dhd_prot_stop(dhd_pub_t *dhd)
+-{
+-	/* Nothing to do for CDC */
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
+deleted file mode 100644
+index 0bfb93c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c
++++ /dev/null
+@@ -1,1848 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <linux/netdevice.h>
+-#include <bcmutils.h>
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-#include <msgtrace.h>
+-#include <wlioctl.h>
+-
+-int dhd_msg_level;
+-char fw_path[MOD_PARAM_PATHLEN];
+-char nv_path[MOD_PARAM_PATHLEN];
+-
+-/* Last connection success/failure status */
+-u32 dhd_conn_event;
+-u32 dhd_conn_status;
+-u32 dhd_conn_reason;
+-
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-extern void dhd_ind_scan_confirm(void *h, bool status);
+-extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen);
+-void dhd_iscan_lock(void);
+-void dhd_iscan_unlock(void);
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#define EPI_VERSION_STR         "4.218.248.5"
+-#ifdef DHD_DEBUG
+-const char dhd_version[] =
+-"Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " __DATE__
+-" at " __TIME__;
+-#else
+-const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR;
+-#endif
+-
+-void dhd_set_timer(void *bus, uint wdtick);
+-
+-/* IOVar table */
+-enum {
+-	IOV_VERSION = 1,
+-	IOV_MSGLEVEL,
+-	IOV_BCMERRORSTR,
+-	IOV_BCMERROR,
+-	IOV_WDTICK,
+-	IOV_DUMP,
+-#ifdef DHD_DEBUG
+-	IOV_CONS,
+-	IOV_DCONSOLE_POLL,
+-#endif
+-	IOV_CLEARCOUNTS,
+-	IOV_LOGDUMP,
+-	IOV_LOGCAL,
+-	IOV_LOGSTAMP,
+-	IOV_GPIOOB,
+-	IOV_IOCTLTIMEOUT,
+-	IOV_LAST
+-};
+-
+-const bcm_iovar_t dhd_iovars[] = {
+-	{"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version)}
+-	,
+-#ifdef DHD_DEBUG
+-	{"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}
+-	,
+-#endif				/* DHD_DEBUG */
+-	{"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN}
+-	,
+-	{"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0}
+-	,
+-	{"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0}
+-	,
+-	{"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN}
+-	,
+-#ifdef DHD_DEBUG
+-	{"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0}
+-	,
+-	{"cons", IOV_CONS, 0, IOVT_BUFFER, 0}
+-	,
+-#endif
+-	{"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0}
+-	,
+-	{"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0}
+-	,
+-	{"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0}
+-	,
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-void dhd_common_init(void)
+-{
+-	/* Init global variables at run-time, not as part of the declaration.
+-	 * This is required to support init/de-init of the driver.
+-	 * Initialization
+-	 * of globals as part of the declaration results in non-deterministic
+-	 * behaviour since the value of the globals may be different on the
+-	 * first time that the driver is initialized vs subsequent
+-	 * initializations.
+-	 */
+-	dhd_msg_level = DHD_ERROR_VAL;
+-#ifdef CONFIG_BCM4329_FW_PATH
+-	strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN - 1);
+-#else
+-	fw_path[0] = '\0';
+-#endif
+-#ifdef CONFIG_BCM4329_NVRAM_PATH
+-	strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN - 1);
+-#else
+-	nv_path[0] = '\0';
+-#endif
+-}
+-
+-static int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
+-{
+-	struct bcmstrbuf b;
+-	struct bcmstrbuf *strbuf = &b;
+-
+-	bcm_binit(strbuf, buf, buflen);
+-
+-	/* Base DHD info */
+-	bcm_bprintf(strbuf, "%s\n", dhd_version);
+-	bcm_bprintf(strbuf, "\n");
+-	bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
+-		    dhdp->up, dhdp->txoff, dhdp->busstate);
+-	bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
+-		    dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
+-	bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n",
+-		    dhdp->iswl, dhdp->drv_version, &dhdp->mac);
+-	bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror,
+-		    dhdp->tickcnt);
+-
+-	bcm_bprintf(strbuf, "dongle stats:\n");
+-	bcm_bprintf(strbuf,
+-		    "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
+-		    dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes,
+-		    dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped);
+-	bcm_bprintf(strbuf,
+-		    "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
+-		    dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes,
+-		    dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped);
+-	bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast);
+-
+-	bcm_bprintf(strbuf, "bus stats:\n");
+-	bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
+-		    dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors);
+-	bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
+-		    dhdp->tx_ctlpkts, dhdp->tx_ctlerrs);
+-	bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n",
+-		    dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors);
+-	bcm_bprintf(strbuf,
+-		    "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n",
+-		    dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped,
+-		    dhdp->rx_flushed);
+-	bcm_bprintf(strbuf,
+-		    "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n",
+-		    dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets);
+-	bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched);
+-	bcm_bprintf(strbuf, "\n");
+-
+-	/* Add any prot info */
+-	dhd_prot_dump(dhdp, strbuf);
+-	bcm_bprintf(strbuf, "\n");
+-
+-	/* Add any bus info */
+-	dhd_bus_dump(dhdp, strbuf);
+-
+-	return !strbuf->size ? -EOVERFLOW : 0;
+-}
+-
+-static int
+-dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid,
+-	    const char *name, void *params, int plen, void *arg, int len,
+-	    int val_size)
+-{
+-	int bcmerror = 0;
+-	s32 int_val = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_VERSION):
+-		/* Need to have checked buffer length */
+-		strncpy((char *)arg, dhd_version, len);
+-		break;
+-
+-	case IOV_GVAL(IOV_MSGLEVEL):
+-		int_val = (s32) dhd_msg_level;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_MSGLEVEL):
+-		dhd_msg_level = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_BCMERRORSTR):
+-		strncpy((char *)arg, "bcm_error",
+-			BCME_STRLEN);
+-		((char *)arg)[BCME_STRLEN - 1] = 0x00;
+-		break;
+-
+-	case IOV_GVAL(IOV_BCMERROR):
+-		int_val = (s32) dhd_pub->bcmerror;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_WDTICK):
+-		int_val = (s32) dhd_watchdog_ms;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_WDTICK):
+-		if (!dhd_pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-		dhd_os_wd_timer(dhd_pub, (uint) int_val);
+-		break;
+-
+-	case IOV_GVAL(IOV_DUMP):
+-		bcmerror = dhd_dump(dhd_pub, arg, len);
+-		break;
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_DCONSOLE_POLL):
+-		int_val = (s32) dhd_console_ms;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DCONSOLE_POLL):
+-		dhd_console_ms = (uint) int_val;
+-		break;
+-
+-	case IOV_SVAL(IOV_CONS):
+-		if (len > 0)
+-			bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
+-		break;
+-#endif
+-
+-	case IOV_SVAL(IOV_CLEARCOUNTS):
+-		dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
+-		dhd_pub->tx_errors = dhd_pub->rx_errors = 0;
+-		dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0;
+-		dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0;
+-		dhd_pub->rx_dropped = 0;
+-		dhd_pub->rx_readahead_cnt = 0;
+-		dhd_pub->tx_realloc = 0;
+-		dhd_pub->wd_dpc_sched = 0;
+-		memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats));
+-		dhd_bus_clearcounts(dhd_pub);
+-		break;
+-
+-	case IOV_GVAL(IOV_IOCTLTIMEOUT):{
+-			int_val = (s32) dhd_os_get_ioctl_resp_timeout();
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_IOCTLTIMEOUT):{
+-			if (int_val <= 0)
+-				bcmerror = -EINVAL;
+-			else
+-				dhd_os_set_ioctl_resp_timeout((unsigned int)
+-							      int_val);
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt,
+-		  int prec)
+-{
+-	struct sk_buff *p;
+-	int eprec = -1;		/* precedence to evict from */
+-	bool discard_oldest;
+-
+-	/* Fast case, precedence queue is not full and we are also not
+-	 * exceeding total queue length
+-	 */
+-	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
+-		bcm_pktq_penq(q, prec, pkt);
+-		return true;
+-	}
+-
+-	/* Determine precedence from which to evict packet, if any */
+-	if (pktq_pfull(q, prec))
+-		eprec = prec;
+-	else if (pktq_full(q)) {
+-		p = bcm_pktq_peek_tail(q, &eprec);
+-		ASSERT(p);
+-		if (eprec > prec)
+-			return false;
+-	}
+-
+-	/* Evict if needed */
+-	if (eprec >= 0) {
+-		/* Detect queueing to unconfigured precedence */
+-		ASSERT(!pktq_pempty(q, eprec));
+-		discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec);
+-		if (eprec == prec && !discard_oldest)
+-			return false;	/* refuse newer (incoming) packet */
+-		/* Evict packet according to discard policy */
+-		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+-			bcm_pktq_pdeq_tail(q, eprec);
+-		if (p == NULL) {
+-			DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.",
+-				   __func__, discard_oldest));
+-			ASSERT(p);
+-		}
+-
+-		bcm_pkt_buf_free_skb(p);
+-	}
+-
+-	/* Enqueue */
+-	p = bcm_pktq_penq(q, prec, pkt);
+-	if (p == NULL) {
+-		DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__));
+-		ASSERT(p);
+-	}
+-
+-	return true;
+-}
+-
+-static int
+-dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name,
+-	     void *params, int plen, void *arg, int len, bool set)
+-{
+-	int bcmerror = 0;
+-	int val_size;
+-	const bcm_iovar_t *vi = NULL;
+-	u32 actionid;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get MUST have return space */
+-	ASSERT(set || (arg && len));
+-
+-	/* Set does NOT take qualifiers */
+-	ASSERT(!set || (!params && !plen));
+-
+-	vi = bcm_iovar_lookup(dhd_iovars, name);
+-	if (vi == NULL) {
+-		bcmerror = -ENOTSUPP;
+-		goto exit;
+-	}
+-
+-	DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__,
+-		 name, (set ? "set" : "get"), len, plen));
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	bcmerror =
+-	    dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len,
+-			val_size);
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
+-{
+-	int bcmerror = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (!buf)
+-		return -EINVAL;
+-
+-	switch (ioc->cmd) {
+-	case DHD_GET_MAGIC:
+-		if (buflen < sizeof(int))
+-			bcmerror = -EOVERFLOW;
+-		else
+-			*(int *)buf = DHD_IOCTL_MAGIC;
+-		break;
+-
+-	case DHD_GET_VERSION:
+-		if (buflen < sizeof(int))
+-			bcmerror = -EOVERFLOW;
+-		else
+-			*(int *)buf = DHD_IOCTL_VERSION;
+-		break;
+-
+-	case DHD_GET_VAR:
+-	case DHD_SET_VAR:{
+-			char *arg;
+-			uint arglen;
+-
+-			/* scan past the name to any arguments */
+-			for (arg = buf, arglen = buflen; *arg && arglen;
+-			     arg++, arglen--)
+-				;
+-
+-			if (*arg) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* account for the NUL terminator */
+-			arg++, arglen--;
+-
+-			/* call with the appropriate arguments */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror =
+-				    dhd_iovar_op(dhd_pub, buf, arg, arglen, buf,
+-						 buflen, IOV_GET);
+-			else
+-				bcmerror =
+-				    dhd_iovar_op(dhd_pub, buf, NULL, 0, arg,
+-						 arglen, IOV_SET);
+-			if (bcmerror != -ENOTSUPP)
+-				break;
+-
+-			/* not in generic table, try protocol module */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg,
+-							     arglen, buf,
+-							     buflen, IOV_GET);
+-			else
+-				bcmerror = dhd_prot_iovar_op(dhd_pub, buf,
+-							     NULL, 0, arg,
+-							     arglen, IOV_SET);
+-			if (bcmerror != -ENOTSUPP)
+-				break;
+-
+-			/* if still not found, try bus module */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+-							    arg, arglen, buf,
+-							    buflen, IOV_GET);
+-			else
+-				bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+-							    NULL, 0, arg,
+-							    arglen, IOV_SET);
+-
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-	}
+-
+-	return bcmerror;
+-}
+-
+-#ifdef SHOW_EVENTS
+-static void wl_show_host_event(wl_event_msg_t *event, void *event_data)
+-{
+-	uint i, status, reason;
+-	bool group = false, flush_txq = false, link = false;
+-	char *auth_str, *event_name;
+-	unsigned char *buf;
+-	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
+-	static struct {
+-		uint event;
+-		char *event_name;
+-	} event_names[] = {
+-		{
+-		WLC_E_SET_SSID, "SET_SSID"}, {
+-		WLC_E_JOIN, "JOIN"}, {
+-		WLC_E_START, "START"}, {
+-		WLC_E_AUTH, "AUTH"}, {
+-		WLC_E_AUTH_IND, "AUTH_IND"}, {
+-		WLC_E_DEAUTH, "DEAUTH"}, {
+-		WLC_E_DEAUTH_IND, "DEAUTH_IND"}, {
+-		WLC_E_ASSOC, "ASSOC"}, {
+-		WLC_E_ASSOC_IND, "ASSOC_IND"}, {
+-		WLC_E_REASSOC, "REASSOC"}, {
+-		WLC_E_REASSOC_IND, "REASSOC_IND"}, {
+-		WLC_E_DISASSOC, "DISASSOC"}, {
+-		WLC_E_DISASSOC_IND, "DISASSOC_IND"}, {
+-		WLC_E_QUIET_START, "START_QUIET"}, {
+-		WLC_E_QUIET_END, "END_QUIET"}, {
+-		WLC_E_BEACON_RX, "BEACON_RX"}, {
+-		WLC_E_LINK, "LINK"}, {
+-		WLC_E_MIC_ERROR, "MIC_ERROR"}, {
+-		WLC_E_NDIS_LINK, "NDIS_LINK"}, {
+-		WLC_E_ROAM, "ROAM"}, {
+-		WLC_E_TXFAIL, "TXFAIL"}, {
+-		WLC_E_PMKID_CACHE, "PMKID_CACHE"}, {
+-		WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
+-		WLC_E_PRUNE, "PRUNE"}, {
+-		WLC_E_AUTOAUTH, "AUTOAUTH"}, {
+-		WLC_E_EAPOL_MSG, "EAPOL_MSG"}, {
+-		WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
+-		WLC_E_ADDTS_IND, "ADDTS_IND"}, {
+-		WLC_E_DELTS_IND, "DELTS_IND"}, {
+-		WLC_E_BCNSENT_IND, "BCNSENT_IND"}, {
+-		WLC_E_BCNRX_MSG, "BCNRX_MSG"}, {
+-		WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
+-		WLC_E_ROAM_PREP, "ROAM_PREP"}, {
+-		WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
+-		WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
+-		WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
+-		WLC_E_JOIN_START, "JOIN_START"}, {
+-		WLC_E_ROAM_START, "ROAM_START"}, {
+-		WLC_E_ASSOC_START, "ASSOC_START"}, {
+-		WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
+-		WLC_E_RADIO, "RADIO"}, {
+-		WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
+-		WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
+-		WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
+-		WLC_E_PSK_SUP, "PSK_SUP"}, {
+-		WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
+-		WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
+-		WLC_E_ICV_ERROR, "ICV_ERROR"}, {
+-		WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
+-		WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
+-		WLC_E_TRACE, "TRACE"}, {
+-		WLC_E_ACTION_FRAME, "ACTION FRAME"}, {
+-		WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
+-		WLC_E_IF, "IF"}, {
+-		WLC_E_RSSI, "RSSI"}, {
+-		WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
+-	};
+-	uint event_type, flags, auth_type, datalen;
+-	event_type = be32_to_cpu(event->event_type);
+-	flags = be16_to_cpu(event->flags);
+-	status = be32_to_cpu(event->status);
+-	reason = be32_to_cpu(event->reason);
+-	auth_type = be32_to_cpu(event->auth_type);
+-	datalen = be32_to_cpu(event->datalen);
+-	/* debug dump of event messages */
+-	sprintf(eabuf, "%pM", event->addr);
+-
+-	event_name = "UNKNOWN";
+-	for (i = 0; i < ARRAY_SIZE(event_names); i++) {
+-		if (event_names[i].event == event_type)
+-			event_name = event_names[i].event_name;
+-	}
+-
+-	DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type));
+-	DHD_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
+-				flags, status, reason, auth_type, eabuf));
+-
+-	if (flags & WLC_EVENT_MSG_LINK)
+-		link = true;
+-	if (flags & WLC_EVENT_MSG_GROUP)
+-		group = true;
+-	if (flags & WLC_EVENT_MSG_FLUSHTXQ)
+-		flush_txq = true;
+-
+-	switch (event_type) {
+-	case WLC_E_START:
+-	case WLC_E_DEAUTH:
+-	case WLC_E_DISASSOC:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_ASSOC:
+-	case WLC_E_REASSOC:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n",
+-				   event_name, eabuf));
+-		} else if (status == WLC_E_STATUS_TIMEOUT) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n",
+-				   event_name, eabuf));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
+-				   event_name, eabuf, (int)reason));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status "
+-				"%d\n", event_name, eabuf, (int)status));
+-		}
+-		break;
+-
+-	case WLC_E_DEAUTH_IND:
+-	case WLC_E_DISASSOC_IND:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name,
+-			   eabuf, (int)reason));
+-		break;
+-
+-	case WLC_E_AUTH:
+-	case WLC_E_AUTH_IND:
+-		if (auth_type == WLAN_AUTH_OPEN)
+-			auth_str = "Open System";
+-		else if (auth_type == WLAN_AUTH_SHARED_KEY)
+-			auth_str = "Shared Key";
+-		else {
+-			sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
+-			auth_str = err_msg;
+-		}
+-		if (event_type == WLC_E_AUTH_IND) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name,
+-				   eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n",
+-				   event_name, eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_TIMEOUT) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
+-				   event_name, eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, "
+-				"reason %d\n",
+-				event_name, eabuf, auth_str, (int)reason));
+-		}
+-
+-		break;
+-
+-	case WLC_E_JOIN:
+-	case WLC_E_ROAM:
+-	case WLC_E_SET_SSID:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name,
+-				   eabuf));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, failed\n", event_name));
+-		} else if (status == WLC_E_STATUS_NO_NETWORKS) {
+-			DHD_EVENT(("MACEVENT: %s, no networks found\n",
+-				   event_name));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, unexpected status %d\n",
+-				   event_name, (int)status));
+-		}
+-		break;
+-
+-	case WLC_E_BEACON_RX:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, status %d\n", event_name,
+-				   status));
+-		}
+-		break;
+-
+-	case WLC_E_LINK:
+-		DHD_EVENT(("MACEVENT: %s %s\n", event_name,
+-			   link ? "UP" : "DOWN"));
+-		break;
+-
+-	case WLC_E_MIC_ERROR:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
+-			   event_name, eabuf, group, flush_txq));
+-		break;
+-
+-	case WLC_E_ICV_ERROR:
+-	case WLC_E_UNICAST_DECODE_ERROR:
+-	case WLC_E_MULTICAST_DECODE_ERROR:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_TXFAIL:
+-		DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_SCAN_COMPLETE:
+-	case WLC_E_PMKID_CACHE:
+-		DHD_EVENT(("MACEVENT: %s\n", event_name));
+-		break;
+-
+-	case WLC_E_PFN_NET_FOUND:
+-	case WLC_E_PFN_NET_LOST:
+-	case WLC_E_PFN_SCAN_COMPLETE:
+-		DHD_EVENT(("PNOEVENT: %s\n", event_name));
+-		break;
+-
+-	case WLC_E_PSK_SUP:
+-	case WLC_E_PRUNE:
+-		DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n",
+-			   event_name, (int)status, (int)reason));
+-		break;
+-
+-	case WLC_E_TRACE:
+-		{
+-			static u32 seqnum_prev;
+-			msgtrace_hdr_t hdr;
+-			u32 nblost;
+-			char *s, *p;
+-
+-			buf = (unsigned char *) event_data;
+-			memcpy(&hdr, buf, MSGTRACE_HDRLEN);
+-
+-			if (hdr.version != MSGTRACE_VERSION) {
+-				DHD_ERROR(
+-				    ("\nMACEVENT: %s [unsupported version --> "
+-				     "dhd version:%d dongle version:%d]\n",
+-				     event_name, MSGTRACE_VERSION, hdr.version)
+-				);
+-				/* Reset datalen to avoid display below */
+-				datalen = 0;
+-				break;
+-			}
+-
+-			/* There are 2 bytes available at the end of data */
+-			buf[MSGTRACE_HDRLEN + be16_to_cpu(hdr.len)] = '\0';
+-
+-			if (be32_to_cpu(hdr.discarded_bytes)
+-			    || be32_to_cpu(hdr.discarded_printf)) {
+-				DHD_ERROR(
+-				    ("\nWLC_E_TRACE: [Discarded traces in dongle -->"
+-				     "discarded_bytes %d discarded_printf %d]\n",
+-				     be32_to_cpu(hdr.discarded_bytes),
+-				     be32_to_cpu(hdr.discarded_printf)));
+-			}
+-
+-			nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
+-			if (nblost > 0) {
+-				DHD_ERROR(
+-				    ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n",
+-				     be32_to_cpu(hdr.seqnum), nblost));
+-			}
+-			seqnum_prev = be32_to_cpu(hdr.seqnum);
+-
+-			/* Display the trace buffer. Advance from \n to \n to
+-			 * avoid display big
+-			 * printf (issue with Linux printk )
+-			 */
+-			p = (char *)&buf[MSGTRACE_HDRLEN];
+-			while ((s = strstr(p, "\n")) != NULL) {
+-				*s = '\0';
+-				printk(KERN_DEBUG"%s\n", p);
+-				p = s + 1;
+-			}
+-			printk(KERN_DEBUG "%s\n", p);
+-
+-			/* Reset datalen to avoid display below */
+-			datalen = 0;
+-		}
+-		break;
+-
+-	case WLC_E_RSSI:
+-		DHD_EVENT(("MACEVENT: %s %d\n", event_name,
+-			   be32_to_cpu(*((int *)event_data))));
+-		break;
+-
+-	default:
+-		DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, "
+-			"auth %d\n", event_name, event_type, eabuf,
+-			(int)status, (int)reason, (int)auth_type));
+-		break;
+-	}
+-
+-	/* show any appended data */
+-	if (datalen) {
+-		buf = (unsigned char *) event_data;
+-		DHD_EVENT((" data (%d) : ", datalen));
+-		for (i = 0; i < datalen; i++)
+-			DHD_EVENT((" 0x%02x ", *buf++));
+-		DHD_EVENT(("\n"));
+-	}
+-}
+-#endif				/* SHOW_EVENTS */
+-
+-int
+-wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata,
+-	      wl_event_msg_t *event, void **data_ptr)
+-{
+-	/* check whether packet is a BRCM event pkt */
+-	bcm_event_t *pvt_data = (bcm_event_t *) pktdata;
+-	char *event_data;
+-	u32 type, status;
+-	u16 flags;
+-	int evlen;
+-
+-	if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
+-		DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__));
+-		return -EBADE;
+-	}
+-
+-	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
+-	if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) !=
+-	    BCMILCP_BCM_SUBTYPE_EVENT) {
+-		DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__));
+-		return -EBADE;
+-	}
+-
+-	*data_ptr = &pvt_data[1];
+-	event_data = *data_ptr;
+-
+-	/* memcpy since BRCM event pkt may be unaligned. */
+-	memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t));
+-
+-	type = get_unaligned_be32(&event->event_type);
+-	flags = get_unaligned_be16(&event->flags);
+-	status = get_unaligned_be32(&event->status);
+-	evlen = get_unaligned_be32(&event->datalen) + sizeof(bcm_event_t);
+-
+-	switch (type) {
+-	case WLC_E_IF:
+-		{
+-			dhd_if_event_t *ifevent = (dhd_if_event_t *) event_data;
+-			DHD_TRACE(("%s: if event\n", __func__));
+-
+-			if (ifevent->ifidx > 0 &&
+-				 ifevent->ifidx < DHD_MAX_IFS) {
+-				if (ifevent->action == WLC_E_IF_ADD)
+-					dhd_add_if(dhd, ifevent->ifidx,
+-						   NULL, event->ifname,
+-						   pvt_data->eth.h_dest,
+-						   ifevent->flags,
+-						   ifevent->bssidx);
+-				else
+-					dhd_del_if(dhd, ifevent->ifidx);
+-			} else {
+-				DHD_ERROR(("%s: Invalid ifidx %d for %s\n",
+-					   __func__, ifevent->ifidx,
+-					   event->ifname));
+-			}
+-		}
+-		/* send up the if event: btamp user needs it */
+-		*ifidx = dhd_ifname2idx(dhd, event->ifname);
+-		/* push up to external supp/auth */
+-		dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
+-		break;
+-
+-#ifdef P2P
+-	case WLC_E_NDIS_LINK:
+-		break;
+-#endif
+-		/* fall through */
+-		/* These are what external supplicant/authenticator wants */
+-	case WLC_E_LINK:
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-	case WLC_E_DISASSOC_IND:
+-	case WLC_E_MIC_ERROR:
+-	default:
+-		/* Fall through: this should get _everything_  */
+-
+-		*ifidx = dhd_ifname2idx(dhd, event->ifname);
+-		/* push up to external supp/auth */
+-		dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
+-		DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n",
+-			   __func__, type, flags, status));
+-
+-		/* put it back to WLC_E_NDIS_LINK */
+-		if (type == WLC_E_NDIS_LINK) {
+-			u32 temp;
+-
+-			temp = get_unaligned_be32(&event->event_type);
+-			DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp));
+-
+-			temp = be32_to_cpu(WLC_E_NDIS_LINK);
+-			memcpy((void *)(&pvt_data->event.event_type), &temp,
+-			       sizeof(pvt_data->event.event_type));
+-		}
+-		break;
+-	}
+-
+-#ifdef SHOW_EVENTS
+-	wl_show_host_event(event, event_data);
+-#endif				/* SHOW_EVENTS */
+-
+-	return 0;
+-}
+-
+-/* Convert user's input in hex pattern to byte-size mask */
+-static int wl_pattern_atoh(char *src, char *dst)
+-{
+-	int i;
+-	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
+-		DHD_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+-		return -1;
+-	}
+-	src = src + 2;		/* Skip past 0x */
+-	if (strlen(src) % 2 != 0) {
+-		DHD_ERROR(("Mask invalid format. Length must be even.\n"));
+-		return -1;
+-	}
+-	for (i = 0; *src != '\0'; i++) {
+-		char num[3];
+-		strncpy(num, src, 2);
+-		num[2] = '\0';
+-		dst[i] = (u8) simple_strtoul(num, NULL, 16);
+-		src += 2;
+-	}
+-	return i;
+-}
+-
+-void
+-dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable,
+-			     int master_mode)
+-{
+-	char *argv[8];
+-	int i = 0;
+-	const char *str;
+-	int buf_len;
+-	int str_len;
+-	char *arg_save = 0, *arg_org = 0;
+-	int rc;
+-	char buf[128];
+-	wl_pkt_filter_enable_t enable_parm;
+-	wl_pkt_filter_enable_t *pkt_filterp;
+-
+-	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
+-	if (!arg_save) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-	arg_org = arg_save;
+-	memcpy(arg_save, arg, strlen(arg) + 1);
+-
+-	argv[i] = strsep(&arg_save, " ");
+-
+-	i = 0;
+-	if (NULL == argv[i]) {
+-		DHD_ERROR(("No args provided\n"));
+-		goto fail;
+-	}
+-
+-	str = "pkt_filter_enable";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (wl_pkt_filter_enable_t *) (buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	enable_parm.id = simple_strtoul(argv[i], NULL, 0);
+-
+-	/* Parse enable/disable value. */
+-	enable_parm.enable = enable;
+-
+-	buf_len += sizeof(enable_parm);
+-	memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
+-
+-	/* Enable/disable the specified filter. */
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+-	rc = rc >= 0 ? 0 : rc;
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-	else
+-		DHD_TRACE(("%s: successfully added pktfilter %s\n",
+-			   __func__, arg));
+-
+-	/* Contorl the master mode */
+-	bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf,
+-		    sizeof(buf));
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+-	rc = rc >= 0 ? 0 : rc;
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-
+-fail:
+-	kfree(arg_org);
+-}
+-
+-void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg)
+-{
+-	const char *str;
+-	wl_pkt_filter_t pkt_filter;
+-	wl_pkt_filter_t *pkt_filterp;
+-	int buf_len;
+-	int str_len;
+-	int rc;
+-	u32 mask_size;
+-	u32 pattern_size;
+-	char *argv[8], *buf = 0;
+-	int i = 0;
+-	char *arg_save = 0, *arg_org = 0;
+-#define BUF_SIZE		2048
+-
+-	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
+-	if (!arg_save) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	arg_org = arg_save;
+-
+-	buf = kmalloc(BUF_SIZE, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	memcpy(arg_save, arg, strlen(arg) + 1);
+-
+-	if (strlen(arg) > BUF_SIZE) {
+-		DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg),
+-			   (int)sizeof(buf)));
+-		goto fail;
+-	}
+-
+-	argv[i] = strsep(&arg_save, " ");
+-	while (argv[i++])
+-		argv[i] = strsep(&arg_save, " ");
+-
+-	i = 0;
+-	if (NULL == argv[i]) {
+-		DHD_ERROR(("No args provided\n"));
+-		goto fail;
+-	}
+-
+-	str = "pkt_filter_add";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	pkt_filter.id = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Polarity not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse filter polarity. */
+-	pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Filter type not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse filter type. */
+-	pkt_filter.type = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Offset not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter offset. */
+-	pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Bitmask not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter mask. */
+-	mask_size =
+-	    wl_pattern_atoh
+-		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Pattern not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter pattern. */
+-	pattern_size =
+-	    wl_pattern_atoh(argv[i],
+-				   (char *)&pkt_filterp->u.pattern.
+-				   mask_and_pattern[mask_size]);
+-
+-	if (mask_size != pattern_size) {
+-		DHD_ERROR(("Mask and pattern not the same size\n"));
+-		goto fail;
+-	}
+-
+-	pkt_filter.u.pattern.size_bytes = mask_size;
+-	buf_len += WL_PKT_FILTER_FIXED_LEN;
+-	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+-
+-	/* Keep-alive attributes are set in local
+-	 * variable (keep_alive_pkt), and
+-	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
+-	 ** guarantee that the buffer is properly aligned.
+-	 */
+-	memcpy((char *)pkt_filterp,
+-	       &pkt_filter,
+-	       WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+-
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+-	rc = rc >= 0 ? 0 : rc;
+-
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-	else
+-		DHD_TRACE(("%s: successfully added pktfilter %s\n",
+-			   __func__, arg));
+-
+-fail:
+-	kfree(arg_org);
+-
+-	kfree(buf);
+-}
+-
+-void dhd_arp_offload_set(dhd_pub_t *dhd, int arp_mode)
+-{
+-	char iovbuf[32];
+-	int retcode;
+-
+-	bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+-	retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	retcode = retcode >= 0 ? 0 : retcode;
+-	if (retcode)
+-		DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, "
+-			"retcode = %d\n", __func__, arp_mode, retcode));
+-	else
+-		DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n",
+-			   __func__, arp_mode));
+-}
+-
+-void dhd_arp_offload_enable(dhd_pub_t *dhd, int arp_enable)
+-{
+-	char iovbuf[32];
+-	int retcode;
+-
+-	bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
+-	retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	retcode = retcode >= 0 ? 0 : retcode;
+-	if (retcode)
+-		DHD_TRACE(("%s: failed to enabe ARP offload to %d, "
+-			"retcode = %d\n", __func__, arp_enable, retcode));
+-	else
+-		DHD_TRACE(("%s: successfully enabed ARP offload to %d\n",
+-			   __func__, arp_enable));
+-}
+-
+-int dhd_preinit_ioctls(dhd_pub_t *dhd)
+-{
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for
+-				 "event_msgs" + '\0' + bitvec  */
+-	uint up = 0;
+-	char buf[128], *ptr;
+-	uint power_mode = PM_FAST;
+-	u32 dongle_align = DHD_SDALIGN;
+-	u32 glom = 0;
+-	uint bcn_timeout = 3;
+-	int scan_assoc_time = 40;
+-	int scan_unassoc_time = 40;
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-	int ret = 0;
+-	u8 ea_addr[ETH_ALEN];
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+-
+-	dhd_os_proto_block(dhd);
+-
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-	/* Read MAC address from external customer place
+-	 ** NOTE that default mac address has to be present in
+-	 ** otp or nvram file to bring up
+-	 ** firmware but unique per board mac address maybe provided by
+-	 ** customer code
+-	 */
+-	ret = dhd_custom_get_mac_address(ea_addr);
+-	if (!ret) {
+-		bcm_mkiovar("cur_etheraddr", (void *)ea_addr, ETH_ALEN,
+-			    buf, sizeof(buf));
+-		ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+-		if (ret < 0) {
+-			DHD_ERROR(("%s: can't set MAC address , error=%d\n",
+-				   __func__, ret));
+-		} else
+-			memcpy(dhd->mac.octet, (void *)&ea_addr,
+-			       ETH_ALEN);
+-	}
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+-
+-	/* Set Country code */
+-	if (dhd->country_code[0] != 0) {
+-		if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
+-				     dhd->country_code,
+-				     sizeof(dhd->country_code)) < 0) {
+-			DHD_ERROR(("%s: country code setting failed\n",
+-				   __func__));
+-		}
+-	}
+-
+-	/* query for 'ver' to get version info from firmware */
+-	memset(buf, 0, sizeof(buf));
+-	ptr = buf;
+-	bcm_mkiovar("ver", 0, 0, buf, sizeof(buf));
+-	dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
+-	strsep(&ptr, "\n");
+-	/* Print fw version info */
+-	DHD_ERROR(("Firmware version = %s\n", buf));
+-
+-	/* Set PowerSave mode */
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode,
+-			 sizeof(power_mode));
+-
+-	/* Match Host and Dongle rx alignment */
+-	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* disable glom option per default */
+-	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Setup timeout if Beacons are lost and roam is off to report
+-		 link down */
+-	bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Enable/Disable build-in roaming to allowed ext supplicant to take
+-		 of romaing */
+-	bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Force STA UP */
+-	if (dhd_radio_up)
+-		dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));
+-
+-	/* Setup event_msgs */
+-	bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME,
+-			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME,
+-			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
+-
+-#ifdef ARP_OFFLOAD_SUPPORT
+-	/* Set and enable ARP offload feature */
+-	if (dhd_arp_enable)
+-		dhd_arp_offload_set(dhd, dhd_arp_mode);
+-	dhd_arp_offload_enable(dhd, dhd_arp_enable);
+-#endif				/* ARP_OFFLOAD_SUPPORT */
+-
+-#ifdef PKT_FILTER_SUPPORT
+-	{
+-		int i;
+-		/* Set up pkt filter */
+-		if (dhd_pkt_filter_enable) {
+-			for (i = 0; i < dhd->pktfilter_count; i++) {
+-				dhd_pktfilter_offload_set(dhd,
+-							  dhd->pktfilter[i]);
+-				dhd_pktfilter_offload_enable(dhd,
+-				     dhd->pktfilter[i],
+-				     dhd_pkt_filter_init,
+-				     dhd_master_mode);
+-			}
+-		}
+-	}
+-#endif				/* PKT_FILTER_SUPPORT */
+-
+-	dhd_os_proto_unblock(dhd);
+-
+-	return 0;
+-}
+-
+-#ifdef SIMPLE_ISCAN
+-uint iscan_thread_id;
+-iscan_buf_t *iscan_chain;
+-
+-iscan_buf_t *dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
+-{
+-	iscan_buf_t *iscanbuf_alloc = 0;
+-	iscan_buf_t *iscanbuf_head;
+-
+-	dhd_iscan_lock();
+-
+-	iscanbuf_alloc = kmalloc(sizeof(iscan_buf_t), GFP_ATOMIC);
+-	if (iscanbuf_alloc == NULL)
+-		goto fail;
+-
+-	iscanbuf_alloc->next = NULL;
+-	iscanbuf_head = *iscanbuf;
+-
+-	DHD_ISCAN(("%s: addr of allocated node = 0x%X"
+-		   "addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
+-		   __func__, iscanbuf_alloc, iscanbuf_head, dhd));
+-
+-	if (iscanbuf_head == NULL) {
+-		*iscanbuf = iscanbuf_alloc;
+-		DHD_ISCAN(("%s: Head is allocated\n", __func__));
+-		goto fail;
+-	}
+-
+-	while (iscanbuf_head->next)
+-		iscanbuf_head = iscanbuf_head->next;
+-
+-	iscanbuf_head->next = iscanbuf_alloc;
+-
+-fail:
+-	dhd_iscan_unlock();
+-	return iscanbuf_alloc;
+-}
+-
+-void dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
+-{
+-	iscan_buf_t *iscanbuf_free = 0;
+-	iscan_buf_t *iscanbuf_prv = 0;
+-	iscan_buf_t *iscanbuf_cur = iscan_chain;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-
+-	dhd_iscan_lock();
+-	/* If iscan_delete is null then delete the entire
+-	 * chain or else delete specific one provided
+-	 */
+-	if (!iscan_delete) {
+-		while (iscanbuf_cur) {
+-			iscanbuf_free = iscanbuf_cur;
+-			iscanbuf_cur = iscanbuf_cur->next;
+-			iscanbuf_free->next = 0;
+-			kfree(iscanbuf_free);
+-		}
+-		iscan_chain = 0;
+-	} else {
+-		while (iscanbuf_cur) {
+-			if (iscanbuf_cur == iscan_delete)
+-				break;
+-			iscanbuf_prv = iscanbuf_cur;
+-			iscanbuf_cur = iscanbuf_cur->next;
+-		}
+-		if (iscanbuf_prv)
+-			iscanbuf_prv->next = iscan_delete->next;
+-
+-		iscan_delete->next = 0;
+-		kfree(iscan_delete);
+-
+-		if (!iscanbuf_prv)
+-			iscan_chain = 0;
+-	}
+-	dhd_iscan_unlock();
+-}
+-
+-iscan_buf_t *dhd_iscan_result_buf(void)
+-{
+-	return iscan_chain;
+-}
+-
+-/*
+-* print scan cache
+-* print partial iscan_skip list differently
+-*/
+-int dhd_iscan_print_cache(iscan_buf_t *iscan_skip)
+-{
+-	int i = 0, l = 0;
+-	iscan_buf_t *iscan_cur;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi;
+-
+-	dhd_iscan_lock();
+-
+-	iscan_cur = dhd_iscan_result_buf();
+-
+-	while (iscan_cur) {
+-		list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-		if (!list)
+-			break;
+-
+-		results = (wl_scan_results_t *)&list->results;
+-		if (!results)
+-			break;
+-
+-		if (results->version != WL_BSS_INFO_VERSION) {
+-			DHD_ISCAN(("%s: results->version %d != "
+-				"WL_BSS_INFO_VERSION\n",
+-				__func__, results->version));
+-			goto done;
+-		}
+-
+-		bi = results->bss_info;
+-		for (i = 0; i < results->count; i++) {
+-			if (!bi)
+-				break;
+-
+-			DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
+-				   iscan_cur != iscan_skip ? "BSS" : "bss", l,
+-				   i, bi->BSSID.octet[0], bi->BSSID.octet[1],
+-				   bi->BSSID.octet[2], bi->BSSID.octet[3],
+-				   bi->BSSID.octet[4], bi->BSSID.octet[5]));
+-
+-			bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
+-		}
+-		iscan_cur = iscan_cur->next;
+-		l++;
+-	}
+-
+-done:
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-/*
+-* delete disappeared AP from specific scan cache but skip partial
+-* list in iscan_skip
+-*/
+-int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip)
+-{
+-	int i = 0, j = 0, l = 0;
+-	iscan_buf_t *iscan_cur;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;
+-
+-	unsigned char *s_addr = addr;
+-
+-	dhd_iscan_lock();
+-	DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n",
+-		   __func__, s_addr[0], s_addr[1], s_addr[2],
+-		   s_addr[3], s_addr[4], s_addr[5]));
+-
+-	iscan_cur = dhd_iscan_result_buf();
+-
+-	while (iscan_cur) {
+-		if (iscan_cur != iscan_skip) {
+-			list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-			if (!list)
+-				break;
+-
+-			results = (wl_scan_results_t *)&list->results;
+-			if (!results)
+-				break;
+-
+-			if (results->version != WL_BSS_INFO_VERSION) {
+-				DHD_ERROR(("%s: results->version %d != "
+-					"WL_BSS_INFO_VERSION\n",
+-					__func__, results->version));
+-				goto done;
+-			}
+-
+-			bi = results->bss_info;
+-			for (i = 0; i < results->count; i++) {
+-				if (!bi)
+-					break;
+-
+-				if (!memcmp
+-				    (bi->BSSID.octet, addr, ETH_ALEN)) {
+-					DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] "
+-					"%X:%X:%X:%X:%X:%X\n",
+-					__func__, l, i, bi->BSSID.octet[0],
+-					bi->BSSID.octet[1], bi->BSSID.octet[2],
+-					bi->BSSID.octet[3], bi->BSSID.octet[4],
+-					bi->BSSID.octet[5]));
+-
+-					bi_new = bi;
+-					bi = (wl_bss_info_t *)((unsigned long)
+-							       bi + bi->length);
+-/*
+-			if(bi && bi_new) {
+-				memcpy(bi_new, bi, results->buflen -
+-				bi_new->length);
+-				results->buflen -= bi_new->length;
+-			}
+-*/
+-					results->buflen -= bi_new->length;
+-					results->count--;
+-
+-					for (j = i; j < results->count; j++) {
+-						if (bi && bi_new) {
+-							DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" "%X:%X:%X:%X:%X:%X\n",
+-							__func__, l, j,
+-							bi->BSSID.octet[0],
+-							bi->BSSID.octet[1],
+-							bi->BSSID.octet[2],
+-							bi->BSSID.octet[3],
+-							bi->BSSID.octet[4],
+-							bi->BSSID.octet[5]));
+-
+-							bi_next =
+-							    (wl_bss_info_t *)((unsigned long)bi +
+-								 bi->length);
+-							memcpy(bi_new, bi,
+-							      bi->length);
+-							bi_new =
+-							    (wl_bss_info_t *)((unsigned long)bi_new +
+-								 bi_new->
+-								  length);
+-							bi = bi_next;
+-						}
+-					}
+-
+-					if (results->count == 0) {
+-						/* Prune now empty partial
+-						scan list */
+-						dhd_iscan_free_buf(dhdp,
+-								   iscan_cur);
+-						goto done;
+-					}
+-					break;
+-				}
+-				bi = (wl_bss_info_t *)((unsigned long)bi +
+-							bi->length);
+-			}
+-		}
+-		iscan_cur = iscan_cur->next;
+-		l++;
+-	}
+-
+-done:
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-int dhd_iscan_remove_duplicates(void *dhdp, iscan_buf_t *iscan_cur)
+-{
+-	int i = 0;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;
+-
+-	dhd_iscan_lock();
+-
+-	DHD_ISCAN(("%s: Scan cache before delete\n", __func__));
+-	dhd_iscan_print_cache(iscan_cur);
+-
+-	if (!iscan_cur)
+-		goto done;
+-
+-	list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-	if (!list)
+-		goto done;
+-
+-	results = (wl_scan_results_t *)&list->results;
+-	if (!results)
+-		goto done;
+-
+-	if (results->version != WL_BSS_INFO_VERSION) {
+-		DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n",
+-			   __func__, results->version));
+-		goto done;
+-	}
+-
+-	bi = results->bss_info;
+-	for (i = 0; i < results->count; i++) {
+-		if (!bi)
+-			break;
+-
+-		DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n",
+-			   __func__, i, bi->BSSID.octet[0],
+-			   bi->BSSID.octet[1], bi->BSSID.octet[2],
+-			   bi->BSSID.octet[3], bi->BSSID.octet[4],
+-			   bi->BSSID.octet[5]));
+-
+-		dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur);
+-
+-		bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
+-	}
+-
+-done:
+-	DHD_ISCAN(("%s: Scan cache after delete\n", __func__));
+-	dhd_iscan_print_cache(iscan_cur);
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-void dhd_iscan_ind_scan_confirm(void *dhdp, bool status)
+-{
+-
+-	dhd_ind_scan_confirm(dhdp, status);
+-}
+-
+-int dhd_iscan_request(void *dhdp, u16 action)
+-{
+-	int rc;
+-	wl_iscan_params_t params;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-	char buf[WLC_IOCTL_SMLEN];
+-
+-	memset(&params, 0, sizeof(wl_iscan_params_t));
+-	memcpy(&params.params.bssid, &ether_bcast, ETH_ALEN);
+-
+-	params.params.bss_type = DOT11_BSSTYPE_ANY;
+-	params.params.scan_type = DOT11_SCANTYPE_ACTIVE;
+-
+-	params.params.nprobes = -1;
+-	params.params.active_time = -1;
+-	params.params.passive_time = -1;
+-	params.params.home_time = -1;
+-	params.params.channel_num = 0;
+-
+-	params.version = ISCAN_REQ_VERSION;
+-	params.action = action;
+-	params.scan_duration = 0;
+-
+-	bcm_mkiovar("iscan", (char *)&params, sizeof(wl_iscan_params_t), buf,
+-		    WLC_IOCTL_SMLEN);
+-	rc = dhd_wl_ioctl(dhdp, WLC_SET_VAR, buf, WLC_IOCTL_SMLEN);
+-
+-	return rc;
+-}
+-
+-static int dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
+-{
+-	wl_iscan_results_t *list_buf;
+-	wl_iscan_results_t list;
+-	wl_scan_results_t *results;
+-	iscan_buf_t *iscan_cur;
+-	int status = -1;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-	int rc;
+-
+-	iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain);
+-	if (!iscan_cur) {
+-		DHD_ERROR(("%s: Failed to allocate node\n", __func__));
+-		dhd_iscan_free_buf(dhdp, 0);
+-		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
+-		goto fail;
+-	}
+-
+-	dhd_iscan_lock();
+-
+-	memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+-	list_buf = (wl_iscan_results_t *) iscan_cur->iscan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = WLC_IW_ISCAN_MAXLEN;
+-	bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE,
+-		    iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+-	rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf,
+-			  WLC_IW_ISCAN_MAXLEN);
+-
+-	results->buflen = results->buflen;
+-	results->version = results->version;
+-	*scan_count = results->count = results->count;
+-	status = list_buf->status;
+-
+-	dhd_iscan_unlock();
+-
+-	if (!(*scan_count))
+-		dhd_iscan_free_buf(dhdp, iscan_cur);
+-	else
+-		dhd_iscan_remove_duplicates(dhdp, iscan_cur);
+-
+-fail:
+-	return status;
+-}
+-#endif				/* SIMPLE_ISCAN */
+-
+-#ifdef PNO_SUPPORT
+-int dhd_pno_clean(dhd_pub_t *dhd)
+-{
+-	char iovbuf[128];
+-	int pfn_enabled = 0;
+-	int iov_len = 0;
+-	int ret;
+-
+-	/* Disable pfn */
+-	iov_len =
+-	    bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf));
+-	ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (ret >= 0) {
+-		/* clear pfn */
+-		iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf));
+-		if (iov_len) {
+-			ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					iov_len);
+-			if (ret < 0) {
+-				DHD_ERROR(("%s failed code %d\n", __func__,
+-					   ret));
+-			}
+-		} else {
+-			ret = -1;
+-			DHD_ERROR(("%s failed code %d\n", __func__, iov_len));
+-		}
+-	} else
+-		DHD_ERROR(("%s failed code %d\n", __func__, ret));
+-
+-	return ret;
+-}
+-
+-int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
+-{
+-	char iovbuf[128];
+-	int ret = -1;
+-
+-	if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
+-		DHD_ERROR(("%s error exit\n", __func__));
+-		return ret;
+-	}
+-
+-	/* Enable/disable PNO */
+-	ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf,
+-			sizeof(iovbuf));
+-	if (ret > 0) {
+-		ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-				sizeof(iovbuf));
+-		if (ret < 0) {
+-			DHD_ERROR(("%s failed for error=%d\n", __func__, ret));
+-			return ret;
+-		} else {
+-			dhd->pno_enable = pfn_enabled;
+-			DHD_TRACE(("%s set pno as %d\n", __func__,
+-				   dhd->pno_enable));
+-		}
+-	} else
+-		DHD_ERROR(("%s failed err=%d\n", __func__, ret));
+-
+-	return ret;
+-}
+-
+-/* Function to execute combined scan */
+-int
+-dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char scan_fr)
+-{
+-	int err = -1;
+-	char iovbuf[128];
+-	int k, i;
+-	wl_pfn_param_t pfn_param;
+-	wl_pfn_t pfn_element;
+-
+-	DHD_TRACE(("%s nssid=%d nchan=%d\n", __func__, nssid, scan_fr));
+-
+-	if ((!dhd) && (!ssids_local)) {
+-		DHD_ERROR(("%s error exit\n", __func__));
+-		err = -1;
+-	}
+-
+-	/* Check for broadcast ssid */
+-	for (k = 0; k < nssid; k++) {
+-		if (!ssids_local[k].SSID_len) {
+-			DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO "
+-				"setting\n", k));
+-			return err;
+-		}
+-	}
+-/* #define  PNO_DUMP 1 */
+-#ifdef PNO_DUMP
+-	{
+-		int j;
+-		for (j = 0; j < nssid; j++) {
+-			DHD_ERROR(("%d: scan  for  %s size =%d\n", j,
+-				   ssids_local[j].SSID,
+-				   ssids_local[j].SSID_len));
+-		}
+-	}
+-#endif				/* PNO_DUMP */
+-
+-	/* clean up everything */
+-	err = dhd_pno_clean(dhd);
+-	if (err < 0) {
+-		DHD_ERROR(("%s failed error=%d\n", __func__, err));
+-		return err;
+-	}
+-	memset(&pfn_param, 0, sizeof(pfn_param));
+-	memset(&pfn_element, 0, sizeof(pfn_element));
+-
+-	/* set pfn parameters */
+-	pfn_param.version = PFN_VERSION;
+-	pfn_param.flags = (PFN_LIST_ORDER << SORT_CRITERIA_BIT);
+-
+-	/* set up pno scan fr */
+-	if (scan_fr != 0)
+-		pfn_param.scan_freq = scan_fr;
+-
+-	bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* set all pfn ssid */
+-	for (i = 0; i < nssid; i++) {
+-
+-		pfn_element.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE;
+-		pfn_element.auth = WLAN_AUTH_OPEN;
+-		pfn_element.wpa_auth = WPA_AUTH_PFN_ANY;
+-		pfn_element.wsec = 0;
+-		pfn_element.infra = 1;
+-
+-		memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID,
+-		       ssids_local[i].SSID_len);
+-		pfn_element.ssid.SSID_len = ssids_local[i].SSID_len;
+-
+-		err = bcm_mkiovar("pfn_add", (char *)&pfn_element,
+-				sizeof(pfn_element), iovbuf, sizeof(iovbuf));
+-		if (err > 0) {
+-			err = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					sizeof(iovbuf));
+-			if (err < 0) {
+-				DHD_ERROR(("%s failed for i=%d error=%d\n",
+-					   __func__, i, err));
+-				return err;
+-			}
+-		} else
+-			DHD_ERROR(("%s failed err=%d\n", __func__, err));
+-	}
+-
+-	/* Enable PNO */
+-	/* dhd_pno_enable(dhd, 1); */
+-	return err;
+-}
+-
+-int dhd_pno_get_status(dhd_pub_t *dhd)
+-{
+-	int ret = -1;
+-
+-	if (!dhd)
+-		return ret;
+-	else
+-		return dhd->pno_enable;
+-}
+-
+-#endif				/* PNO_SUPPORT */
+-
+-/* Androd ComboSCAN support */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
+deleted file mode 100644
+index 1cf6c5d..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
++++ /dev/null
+@@ -1,158 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/netdevice.h>
+-#include <bcmutils.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#include <wlioctl.h>
+-#include <wl_iw.h>
+-
+-#define WL_ERROR(fmt, args...) printk(fmt, ##args)
+-#define WL_TRACE(fmt, args...) no_printk(fmt, ##args)
+-
+-#ifdef CUSTOMER_HW
+-extern void bcm_wlan_power_off(int);
+-extern void bcm_wlan_power_on(int);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-int wifi_set_carddetect(int on);
+-int wifi_set_power(int on, unsigned long msec);
+-int wifi_get_irq_number(unsigned long *irq_flags_ptr);
+-#endif
+-
+-#if defined(OOB_INTR_ONLY)
+-
+-#if defined(BCMLXSDMMC)
+-extern int sdioh_mmc_irq(int irq);
+-#endif				/* (BCMLXSDMMC)  */
+-
+-#ifdef CUSTOMER_HW3
+-#include <mach/gpio.h>
+-#endif
+-
+-/* Customer specific Host GPIO definition  */
+-static int dhd_oob_gpio_num = -1;	/* GG 19 */
+-
+-module_param(dhd_oob_gpio_num, int, 0644);
+-MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
+-
+-int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
+-{
+-	int host_oob_irq = 0;
+-
+-#ifdef CUSTOMER_HW2
+-	host_oob_irq = wifi_get_irq_number(irq_flags_ptr);
+-
+-#else				/* for NOT  CUSTOMER_HW2 */
+-#if defined(CUSTOM_OOB_GPIO_NUM)
+-	if (dhd_oob_gpio_num < 0)
+-		dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
+-#endif
+-
+-	if (dhd_oob_gpio_num < 0) {
+-		WL_ERROR("%s: ERROR customer specific Host GPIO is NOT defined\n",
+-			 __func__);
+-		return dhd_oob_gpio_num;
+-	}
+-
+-	WL_ERROR("%s: customer specific Host GPIO number is (%d)\n",
+-		 __func__, dhd_oob_gpio_num);
+-
+-#if defined CUSTOMER_HW
+-	host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
+-#elif defined CUSTOMER_HW3
+-	gpio_request(dhd_oob_gpio_num, "oob irq");
+-	host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
+-	gpio_direction_input(dhd_oob_gpio_num);
+-#endif				/* CUSTOMER_HW */
+-#endif				/* CUSTOMER_HW2 */
+-
+-	return host_oob_irq;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-/* Customer function to control hw specific wlan gpios */
+-void dhd_customer_gpio_wlan_ctrl(int onoff)
+-{
+-	switch (onoff) {
+-	case WLAN_RESET_OFF:
+-		WL_TRACE("%s: call customer specific GPIO to insert WLAN RESET\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_off(2);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-		wifi_set_power(0, 0);
+-#endif
+-		WL_ERROR("=========== WLAN placed in RESET ========\n");
+-		break;
+-
+-	case WLAN_RESET_ON:
+-		WL_TRACE("%s: callc customer specific GPIO to remove WLAN RESET\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_on(2);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-		wifi_set_power(1, 0);
+-#endif
+-		WL_ERROR("=========== WLAN going back to live  ========\n");
+-		break;
+-
+-	case WLAN_POWER_OFF:
+-		WL_TRACE("%s: call customer specific GPIO to turn off WL_REG_ON\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_off(1);
+-#endif				/* CUSTOMER_HW */
+-		break;
+-
+-	case WLAN_POWER_ON:
+-		WL_TRACE("%s: call customer specific GPIO to turn on WL_REG_ON\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_on(1);
+-#endif				/* CUSTOMER_HW */
+-		/* Lets customer power to get stable */
+-		udelay(200);
+-		break;
+-	}
+-}
+-
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-/* Function to get custom MAC address */
+-int dhd_custom_get_mac_address(unsigned char *buf)
+-{
+-	WL_TRACE("%s Enter\n", __func__);
+-	if (!buf)
+-		return -EINVAL;
+-
+-	/* Customer access to MAC address stored outside of DHD driver */
+-
+-#ifdef EXAMPLE_GET_MAC
+-	/* EXAMPLE code */
+-	{
+-		u8 ea_example[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF};
+-		memcpy(buf, ea_example, ETH_ALEN);
+-	}
+-#endif				/* EXAMPLE_GET_MAC */
+-
+-	return 0;
+-}
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
+deleted file mode 100644
+index 0817f13..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_dbg_
+-#define _dhd_dbg_
+-
+-#if defined(DHD_DEBUG)
+-
+-#define DHD_ERROR(args)	       \
+-	do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
+-		printk args; } while (0)
+-#define DHD_TRACE(args)		do {if (dhd_msg_level & DHD_TRACE_VAL)	\
+-					printk args; } while (0)
+-#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL)	\
+-					printk args; } while (0)
+-#define DHD_DATA(args)		do {if (dhd_msg_level & DHD_DATA_VAL)	\
+-					printk args; } while (0)
+-#define DHD_CTL(args)		do {if (dhd_msg_level & DHD_CTL_VAL)	\
+-					printk args; } while (0)
+-#define DHD_TIMER(args)		do {if (dhd_msg_level & DHD_TIMER_VAL)	\
+-					printk args; } while (0)
+-#define DHD_HDRS(args)		do {if (dhd_msg_level & DHD_HDRS_VAL)	\
+-					printk args; } while (0)
+-#define DHD_BYTES(args)		do {if (dhd_msg_level & DHD_BYTES_VAL)	\
+-					printk args; } while (0)
+-#define DHD_INTR(args)		do {if (dhd_msg_level & DHD_INTR_VAL)	\
+-					printk args; } while (0)
+-#define DHD_GLOM(args)		do {if (dhd_msg_level & DHD_GLOM_VAL)	\
+-					printk args; } while (0)
+-#define DHD_EVENT(args)		do {if (dhd_msg_level & DHD_EVENT_VAL)	\
+-					printk args; } while (0)
+-#define DHD_BTA(args)		do {if (dhd_msg_level & DHD_BTA_VAL)	\
+-					printk args; } while (0)
+-#define DHD_ISCAN(args)		do {if (dhd_msg_level & DHD_ISCAN_VAL)	\
+-					printk args; } while (0)
+-
+-#define DHD_ERROR_ON()		(dhd_msg_level & DHD_ERROR_VAL)
+-#define DHD_TRACE_ON()		(dhd_msg_level & DHD_TRACE_VAL)
+-#define DHD_INFO_ON()		(dhd_msg_level & DHD_INFO_VAL)
+-#define DHD_DATA_ON()		(dhd_msg_level & DHD_DATA_VAL)
+-#define DHD_CTL_ON()		(dhd_msg_level & DHD_CTL_VAL)
+-#define DHD_TIMER_ON()		(dhd_msg_level & DHD_TIMER_VAL)
+-#define DHD_HDRS_ON()		(dhd_msg_level & DHD_HDRS_VAL)
+-#define DHD_BYTES_ON()		(dhd_msg_level & DHD_BYTES_VAL)
+-#define DHD_INTR_ON()		(dhd_msg_level & DHD_INTR_VAL)
+-#define DHD_GLOM_ON()		(dhd_msg_level & DHD_GLOM_VAL)
+-#define DHD_EVENT_ON()		(dhd_msg_level & DHD_EVENT_VAL)
+-#define DHD_BTA_ON()		(dhd_msg_level & DHD_BTA_VAL)
+-#define DHD_ISCAN_ON()		(dhd_msg_level & DHD_ISCAN_VAL)
+-
+-#else	/* (defined BCMDBG) || (defined DHD_DEBUG) */
+-
+-#define DHD_ERROR(args)  do {if (net_ratelimit()) printk args; } while (0)
+-#define DHD_TRACE(args)
+-#define DHD_INFO(args)
+-#define DHD_DATA(args)
+-#define DHD_CTL(args)
+-#define DHD_TIMER(args)
+-#define DHD_HDRS(args)
+-#define DHD_BYTES(args)
+-#define DHD_INTR(args)
+-#define DHD_GLOM(args)
+-#define DHD_EVENT(args)
+-#define DHD_BTA(args)
+-#define DHD_ISCAN(args)
+-
+-#define DHD_ERROR_ON()		0
+-#define DHD_TRACE_ON()		0
+-#define DHD_INFO_ON()		0
+-#define DHD_DATA_ON()		0
+-#define DHD_CTL_ON()		0
+-#define DHD_TIMER_ON()		0
+-#define DHD_HDRS_ON()		0
+-#define DHD_BYTES_ON()		0
+-#define DHD_INTR_ON()		0
+-#define DHD_GLOM_ON()		0
+-#define DHD_EVENT_ON()		0
+-#define DHD_BTA_ON()		0
+-#define DHD_ISCAN_ON()		0
+-#endif				/* defined(DHD_DEBUG) */
+-
+-#define DHD_LOG(args)
+-
+-#define DHD_NONE(args)
+-extern int dhd_msg_level;
+-
+-/* Defines msg bits */
+-#include <dhdioctl.h>
+-
+-#endif				/* _dhd_dbg_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+deleted file mode 100644
+index f356c56..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
++++ /dev/null
+@@ -1,2862 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifdef CONFIG_WIFI_CONTROL_FUNC
+-#include <linux/platform_device.h>
+-#endif
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/kthread.h>
+-#include <linux/slab.h>
+-#include <linux/skbuff.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/random.h>
+-#include <linux/spinlock.h>
+-#include <linux/ethtool.h>
+-#include <linux/fcntl.h>
+-#include <linux/fs.h>
+-#include <linux/uaccess.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-
+-#include <wl_cfg80211.h>
+-
+-#define EPI_VERSION_STR		"4.218.248.5"
+-#define ETH_P_BRCM			0x886c
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-#include <linux/wifi_tiwlan.h>
+-
+-struct semaphore wifi_control_sem;
+-
+-struct dhd_bus *g_bus;
+-
+-static struct wifi_platform_data *wifi_control_data;
+-static struct resource *wifi_irqres;
+-
+-int wifi_get_irq_number(unsigned long *irq_flags_ptr)
+-{
+-	if (wifi_irqres) {
+-		*irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;
+-		return (int)wifi_irqres->start;
+-	}
+-#ifdef CUSTOM_OOB_GPIO_NUM
+-	return CUSTOM_OOB_GPIO_NUM;
+-#else
+-	return -1;
+-#endif
+-}
+-
+-int wifi_set_carddetect(int on)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_carddetect)
+-		wifi_control_data->set_carddetect(on);
+-	return 0;
+-}
+-
+-int wifi_set_power(int on, unsigned long msec)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_power)
+-		wifi_control_data->set_power(on);
+-	if (msec)
+-		mdelay(msec);
+-	return 0;
+-}
+-
+-int wifi_set_reset(int on, unsigned long msec)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_reset)
+-		wifi_control_data->set_reset(on);
+-	if (msec)
+-		mdelay(msec);
+-	return 0;
+-}
+-
+-static int wifi_probe(struct platform_device *pdev)
+-{
+-	struct wifi_platform_data *wifi_ctrl =
+-	    (struct wifi_platform_data *)(pdev->dev.platform_data);
+-
+-	printk(KERN_ERR "## %s\n", __func__);
+-	wifi_irqres =
+-	    platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+-					 "bcm4329_wlan_irq");
+-	wifi_control_data = wifi_ctrl;
+-
+-	wifi_set_power(1, 0);	/* Power On */
+-	wifi_set_carddetect(1);	/* CardDetect (0->1) */
+-
+-	up(&wifi_control_sem);
+-	return 0;
+-}
+-
+-static int wifi_remove(struct platform_device *pdev)
+-{
+-	struct wifi_platform_data *wifi_ctrl =
+-	    (struct wifi_platform_data *)(pdev->dev.platform_data);
+-
+-	printk(KERN_ERR "## %s\n", __func__);
+-	wifi_control_data = wifi_ctrl;
+-
+-	wifi_set_carddetect(0);	/* CardDetect (1->0) */
+-	wifi_set_power(0, 0);	/* Power Off */
+-
+-	up(&wifi_control_sem);
+-	return 0;
+-}
+-
+-static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
+-{
+-	DHD_TRACE(("##> %s\n", __func__));
+-	return 0;
+-}
+-
+-static int wifi_resume(struct platform_device *pdev)
+-{
+-	DHD_TRACE(("##> %s\n", __func__));
+-	return 0;
+-}
+-
+-static struct platform_driver wifi_device = {
+-	.probe = wifi_probe,
+-	.remove = wifi_remove,
+-	.suspend = wifi_suspend,
+-	.resume = wifi_resume,
+-	.driver = {
+-		   .name = KBUILD_MODNAME,
+-		   }
+-};
+-
+-int wifi_add_dev(void)
+-{
+-	DHD_TRACE(("## Calling platform_driver_register\n"));
+-	return platform_driver_register(&wifi_device);
+-}
+-
+-void wifi_del_dev(void)
+-{
+-	DHD_TRACE(("## Unregister platform_driver_register\n"));
+-	platform_driver_unregister(&wifi_device);
+-}
+-#endif	/* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+-
+-#if defined(CONFIG_PM_SLEEP)
+-#include <linux/suspend.h>
+-atomic_t dhd_mmc_suspend;
+-DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-#if defined(OOB_INTR_ONLY)
+-extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable);
+-#endif	/* defined(OOB_INTR_ONLY) */
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-#define DRV_MODULE_NAME "brcmfmac"
+-
+-/* Linux wireless extension support */
+-#if defined(CONFIG_WIRELESS_EXT)
+-#include <wl_iw.h>
+-extern wl_iw_extra_params_t g_wl_iw_params;
+-#endif		/* defined(CONFIG_WIRELESS_EXT) */
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-#include <linux/earlysuspend.h>
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-#endif		/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-#ifdef PKT_FILTER_SUPPORT
+-extern void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg);
+-extern void dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable,
+-					 int master_mode);
+-#endif
+-
+-/* Interface control information */
+-typedef struct dhd_if {
+-	struct dhd_info *info;	/* back pointer to dhd_info */
+-	/* OS/stack specifics */
+-	struct net_device *net;
+-	struct net_device_stats stats;
+-	int idx;		/* iface idx in dongle */
+-	int state;		/* interface state */
+-	uint subunit;		/* subunit */
+-	u8 mac_addr[ETH_ALEN];	/* assigned MAC address */
+-	bool attached;		/* Delayed attachment when unset */
+-	bool txflowcontrol;	/* Per interface flow control indicator */
+-	char name[IFNAMSIZ];	/* linux interface name */
+-} dhd_if_t;
+-
+-/* Local private structure (extension of pub) */
+-typedef struct dhd_info {
+-#if defined(CONFIG_WIRELESS_EXT)
+-	wl_iw_t iw;		/* wireless extensions state (must be first) */
+-#endif				/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	dhd_pub_t pub;
+-
+-	/* OS/stack specifics */
+-	dhd_if_t *iflist[DHD_MAX_IFS];
+-
+-	struct semaphore proto_sem;
+-	wait_queue_head_t ioctl_resp_wait;
+-	struct timer_list timer;
+-	bool wd_timer_valid;
+-	struct tasklet_struct tasklet;
+-	spinlock_t sdlock;
+-	spinlock_t txqlock;
+-	/* Thread based operation */
+-	bool threads_only;
+-	struct semaphore sdsem;
+-	struct task_struct *watchdog_tsk;
+-	struct semaphore watchdog_sem;
+-	struct task_struct *dpc_tsk;
+-	struct semaphore dpc_sem;
+-
+-	/* Thread to issue ioctl for multicast */
+-	struct task_struct *sysioc_tsk;
+-	struct semaphore sysioc_sem;
+-	bool set_multicast;
+-	bool set_macaddress;
+-	u8 macvalue[ETH_ALEN];
+-	wait_queue_head_t ctrl_wait;
+-	atomic_t pend_8021x_cnt;
+-
+-#ifdef CONFIG_HAS_EARLYSUSPEND
+-	struct early_suspend early_suspend;
+-#endif				/* CONFIG_HAS_EARLYSUSPEND */
+-} dhd_info_t;
+-
+-/* Definitions to provide path to the firmware and nvram
+- * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt"
+- */
+-char firmware_path[MOD_PARAM_PATHLEN];
+-char nvram_path[MOD_PARAM_PATHLEN];
+-
+-/* load firmware and/or nvram values from the filesystem */
+-module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0);
+-module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0);
+-
+-/* Error bits */
+-module_param(dhd_msg_level, int, 0);
+-
+-/* Spawn a thread for system ioctls (set mac, set mcast) */
+-uint dhd_sysioc = true;
+-module_param(dhd_sysioc, uint, 0);
+-
+-/* Watchdog interval */
+-uint dhd_watchdog_ms = 10;
+-module_param(dhd_watchdog_ms, uint, 0);
+-
+-#ifdef DHD_DEBUG
+-/* Console poll interval */
+-uint dhd_console_ms;
+-module_param(dhd_console_ms, uint, 0);
+-#endif				/* DHD_DEBUG */
+-
+-/* ARP offload agent mode : Enable ARP Host Auto-Reply
+-and ARP Peer Auto-Reply */
+-uint dhd_arp_mode = 0xb;
+-module_param(dhd_arp_mode, uint, 0);
+-
+-/* ARP offload enable */
+-uint dhd_arp_enable = true;
+-module_param(dhd_arp_enable, uint, 0);
+-
+-/* Global Pkt filter enable control */
+-uint dhd_pkt_filter_enable = true;
+-module_param(dhd_pkt_filter_enable, uint, 0);
+-
+-/*  Pkt filter init setup */
+-uint dhd_pkt_filter_init;
+-module_param(dhd_pkt_filter_init, uint, 0);
+-
+-/* Pkt filter mode control */
+-uint dhd_master_mode = true;
+-module_param(dhd_master_mode, uint, 1);
+-
+-/* Watchdog thread priority, -1 to use kernel timer */
+-int dhd_watchdog_prio = 97;
+-module_param(dhd_watchdog_prio, int, 0);
+-
+-/* DPC thread priority, -1 to use tasklet */
+-int dhd_dpc_prio = 98;
+-module_param(dhd_dpc_prio, int, 0);
+-
+-/* DPC thread priority, -1 to use tasklet */
+-extern int dhd_dongle_memsize;
+-module_param(dhd_dongle_memsize, int, 0);
+-
+-/* Contorl fw roaming */
+-#ifdef CUSTOMER_HW2
+-uint dhd_roam;
+-#else
+-uint dhd_roam = 1;
+-#endif
+-
+-/* Control radio state */
+-uint dhd_radio_up = 1;
+-
+-/* Network inteface name */
+-char iface_name[IFNAMSIZ] = "wlan";
+-module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
+-
+-/* The following are specific to the SDIO dongle */
+-
+-/* IOCTL response timeout */
+-int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
+-
+-/* Idle timeout for backplane clock */
+-int dhd_idletime = DHD_IDLETIME_TICKS;
+-module_param(dhd_idletime, int, 0);
+-
+-/* Use polling */
+-uint dhd_poll = false;
+-module_param(dhd_poll, uint, 0);
+-
+-/* Use cfg80211 */
+-uint dhd_cfg80211 = true;
+-module_param(dhd_cfg80211, uint, 0);
+-
+-/* Use interrupts */
+-uint dhd_intr = true;
+-module_param(dhd_intr, uint, 0);
+-
+-/* SDIO Drive Strength (in milliamps) */
+-uint dhd_sdiod_drive_strength = 6;
+-module_param(dhd_sdiod_drive_strength, uint, 0);
+-
+-/* Tx/Rx bounds */
+-extern uint dhd_txbound;
+-extern uint dhd_rxbound;
+-module_param(dhd_txbound, uint, 0);
+-module_param(dhd_rxbound, uint, 0);
+-
+-/* Deferred transmits */
+-extern uint dhd_deferred_tx;
+-module_param(dhd_deferred_tx, uint, 0);
+-
+-#ifdef SDTEST
+-/* Echo packet generator (pkts/s) */
+-uint dhd_pktgen;
+-module_param(dhd_pktgen, uint, 0);
+-
+-/* Echo packet len (0 => sawtooth, max 2040) */
+-uint dhd_pktgen_len;
+-module_param(dhd_pktgen_len, uint, 0);
+-#endif
+-
+-#define FAVORITE_WIFI_CP	(!!dhd_cfg80211)
+-#define IS_CFG80211_FAVORITE() FAVORITE_WIFI_CP
+-#define DBG_CFG80211_GET() ((dhd_cfg80211 & WL_DBG_MASK) >> 1)
+-#define NO_FW_REQ() (dhd_cfg80211 & 0x80)
+-
+-/* Version string to report */
+-#ifdef DHD_DEBUG
+-#define DHD_COMPILED "\nCompiled in " SRCBASE
+-#else
+-#define DHD_COMPILED
+-#endif
+-
+-static void dhd_dpc(unsigned long data);
+-/* forward decl */
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-
+-#ifdef TOE
+-#ifndef BDC
+-#error TOE requires BDC
+-#endif				/* !BDC */
+-static int dhd_toe_get(dhd_info_t *dhd, int idx, u32 *toe_ol);
+-static int dhd_toe_set(dhd_info_t *dhd, int idx, u32 toe_ol);
+-#endif				/* TOE */
+-
+-static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+-			     wl_event_msg_t *event_ptr, void **data_ptr);
+-
+-#if defined(CONFIG_PM_SLEEP)
+-static int dhd_sleep_pm_callback(struct notifier_block *nfb,
+-				 unsigned long action, void *ignored)
+-{
+-	switch (action) {
+-	case PM_HIBERNATION_PREPARE:
+-	case PM_SUSPEND_PREPARE:
+-		atomic_set(&dhd_mmc_suspend, true);
+-		return NOTIFY_OK;
+-	case PM_POST_HIBERNATION:
+-	case PM_POST_SUSPEND:
+-		atomic_set(&dhd_mmc_suspend, false);
+-		return NOTIFY_OK;
+-	}
+-	return 0;
+-}
+-
+-static struct notifier_block dhd_sleep_pm_notifier = {
+-	.notifier_call = dhd_sleep_pm_callback,
+-	.priority = 0
+-};
+-
+-extern int register_pm_notifier(struct notifier_block *nb);
+-extern int unregister_pm_notifier(struct notifier_block *nb);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-	/* && defined(DHD_GPL) */
+-static void dhd_set_packet_filter(int value, dhd_pub_t *dhd)
+-{
+-#ifdef PKT_FILTER_SUPPORT
+-	DHD_TRACE(("%s: %d\n", __func__, value));
+-	/* 1 - Enable packet filter, only allow unicast packet to send up */
+-	/* 0 - Disable packet filter */
+-	if (dhd_pkt_filter_enable) {
+-		int i;
+-
+-		for (i = 0; i < dhd->pktfilter_count; i++) {
+-			dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+-			dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+-						     value, dhd_master_mode);
+-		}
+-	}
+-#endif
+-}
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-static int dhd_set_suspend(int value, dhd_pub_t *dhd)
+-{
+-	int power_mode = PM_MAX;
+-	/* wl_pkt_filter_enable_t       enable_parm; */
+-	char iovbuf[32];
+-	int bcn_li_dtim = 3;
+-#ifdef CUSTOMER_HW2
+-	uint roamvar = 1;
+-#endif				/* CUSTOMER_HW2 */
+-
+-	DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n",
+-		   __func__, value, dhd->in_suspend));
+-
+-	if (dhd && dhd->up) {
+-		if (value && dhd->in_suspend) {
+-
+-			/* Kernel suspended */
+-			DHD_TRACE(("%s: force extra Suspend setting\n",
+-				   __func__));
+-
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
+-					 (char *)&power_mode,
+-					 sizeof(power_mode));
+-
+-			/* Enable packet filter, only allow unicast
+-				 packet to send up */
+-			dhd_set_packet_filter(1, dhd);
+-
+-			/* if dtim skip setup as default force it
+-			 * to wake each third dtim
+-			 * for better power saving.
+-			 * Note that side effect is chance to miss BC/MC
+-			 * packet
+-			 */
+-			if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
+-				bcn_li_dtim = 3;
+-			else
+-				bcn_li_dtim = dhd->dtim_skip;
+-			bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
+-				    4, iovbuf, sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#ifdef CUSTOMER_HW2
+-			/* Disable build-in roaming to allowed \
+-			 * supplicant to take of romaing
+-			 */
+-			bcm_mkiovar("roam_off", (char *)&roamvar, 4,
+-				    iovbuf, sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#endif				/* CUSTOMER_HW2 */
+-		} else {
+-
+-			/* Kernel resumed  */
+-			DHD_TRACE(("%s: Remove extra suspend setting\n",
+-				   __func__));
+-
+-			power_mode = PM_FAST;
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
+-					 (char *)&power_mode,
+-					 sizeof(power_mode));
+-
+-			/* disable pkt filter */
+-			dhd_set_packet_filter(0, dhd);
+-
+-			/* restore pre-suspend setting for dtim_skip */
+-			bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
+-				    4, iovbuf, sizeof(iovbuf));
+-
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#ifdef CUSTOMER_HW2
+-			roamvar = 0;
+-			bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf,
+-				    sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#endif				/* CUSTOMER_HW2 */
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static void dhd_suspend_resume_helper(struct dhd_info *dhd, int val)
+-{
+-	dhd_pub_t *dhdp = &dhd->pub;
+-
+-	dhd_os_proto_block(dhdp);
+-	/* Set flag when early suspend was called */
+-	dhdp->in_suspend = val;
+-	if (!dhdp->suspend_disable_flag)
+-		dhd_set_suspend(val, dhdp);
+-	dhd_os_proto_unblock(dhdp);
+-}
+-
+-static void dhd_early_suspend(struct early_suspend *h)
+-{
+-	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+-
+-	DHD_TRACE(("%s: enter\n", __func__));
+-
+-	if (dhd)
+-		dhd_suspend_resume_helper(dhd, 1);
+-
+-}
+-
+-static void dhd_late_resume(struct early_suspend *h)
+-{
+-	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+-
+-	DHD_TRACE(("%s: enter\n", __func__));
+-
+-	if (dhd)
+-		dhd_suspend_resume_helper(dhd, 0);
+-}
+-#endif				/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-/*
+- * Generalized timeout mechanism.  Uses spin sleep with exponential
+- * back-off until
+- * the sleep time reaches one jiffy, then switches over to task delay.  Usage:
+- *
+- *      dhd_timeout_start(&tmo, usec);
+- *      while (!dhd_timeout_expired(&tmo))
+- *              if (poll_something())
+- *                      break;
+- *      if (dhd_timeout_expired(&tmo))
+- *              fatal();
+- */
+-
+-void dhd_timeout_start(dhd_timeout_t *tmo, uint usec)
+-{
+-	tmo->limit = usec;
+-	tmo->increment = 0;
+-	tmo->elapsed = 0;
+-	tmo->tick = 1000000 / HZ;
+-}
+-
+-int dhd_timeout_expired(dhd_timeout_t *tmo)
+-{
+-	/* Does nothing the first call */
+-	if (tmo->increment == 0) {
+-		tmo->increment = 1;
+-		return 0;
+-	}
+-
+-	if (tmo->elapsed >= tmo->limit)
+-		return 1;
+-
+-	/* Add the delay that's about to take place */
+-	tmo->elapsed += tmo->increment;
+-
+-	if (tmo->increment < tmo->tick) {
+-		udelay(tmo->increment);
+-		tmo->increment *= 2;
+-		if (tmo->increment > tmo->tick)
+-			tmo->increment = tmo->tick;
+-	} else {
+-		wait_queue_head_t delay_wait;
+-		DECLARE_WAITQUEUE(wait, current);
+-		int pending;
+-		init_waitqueue_head(&delay_wait);
+-		add_wait_queue(&delay_wait, &wait);
+-		set_current_state(TASK_INTERRUPTIBLE);
+-		schedule_timeout(1);
+-		pending = signal_pending(current);
+-		remove_wait_queue(&delay_wait, &wait);
+-		set_current_state(TASK_RUNNING);
+-		if (pending)
+-			return 1;	/* Interrupted */
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
+-{
+-	int i = 0;
+-
+-	ASSERT(dhd);
+-	while (i < DHD_MAX_IFS) {
+-		if (dhd->iflist[i] && (dhd->iflist[i]->net == net))
+-			return i;
+-		i++;
+-	}
+-
+-	return DHD_BAD_IF;
+-}
+-
+-int dhd_ifname2idx(dhd_info_t *dhd, char *name)
+-{
+-	int i = DHD_MAX_IFS;
+-
+-	ASSERT(dhd);
+-
+-	if (name == NULL || *name == '\0')
+-		return 0;
+-
+-	while (--i > 0)
+-		if (dhd->iflist[i]
+-		    && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ))
+-			break;
+-
+-	DHD_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name));
+-
+-	return i;		/* default - the primary interface */
+-}
+-
+-char *dhd_ifname(dhd_pub_t *dhdp, int ifidx)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-
+-	ASSERT(dhd);
+-
+-	if (ifidx < 0 || ifidx >= DHD_MAX_IFS) {
+-		DHD_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx));
+-		return "<if_bad>";
+-	}
+-
+-	if (dhd->iflist[ifidx] == NULL) {
+-		DHD_ERROR(("%s: null i/f %d\n", __func__, ifidx));
+-		return "<if_null>";
+-	}
+-
+-	if (dhd->iflist[ifidx]->net)
+-		return dhd->iflist[ifidx]->net->name;
+-
+-	return "<if_none>";
+-}
+-
+-static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
+-{
+-	struct net_device *dev;
+-	struct netdev_hw_addr *ha;
+-	u32 allmulti, cnt;
+-
+-	wl_ioctl_t ioc;
+-	char *buf, *bufp;
+-	uint buflen;
+-	int ret;
+-
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-	dev = dhd->iflist[ifidx]->net;
+-	cnt = netdev_mc_count(dev);
+-
+-	/* Determine initial value of allmulti flag */
+-	allmulti = (dev->flags & IFF_ALLMULTI) ? true : false;
+-
+-	/* Send down the multicast list first. */
+-
+-	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
+-	bufp = buf = kmalloc(buflen, GFP_ATOMIC);
+-	if (!bufp) {
+-		DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), cnt));
+-		return;
+-	}
+-
+-	strcpy(bufp, "mcast_list");
+-	bufp += strlen("mcast_list") + 1;
+-
+-	cnt = cpu_to_le32(cnt);
+-	memcpy(bufp, &cnt, sizeof(cnt));
+-	bufp += sizeof(cnt);
+-
+-	netdev_for_each_mc_addr(ha, dev) {
+-		if (!cnt)
+-			break;
+-		memcpy(bufp, ha->addr, ETH_ALEN);
+-		bufp += ETH_ALEN;
+-		cnt--;
+-	}
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = buflen;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set mcast_list failed, cnt %d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), cnt));
+-		allmulti = cnt ? true : allmulti;
+-	}
+-
+-	kfree(buf);
+-
+-	/* Now send the allmulti setting.  This is based on the setting in the
+-	 * net_device flags, but might be modified above to be turned on if we
+-	 * were trying to set some addresses and dongle rejected it...
+-	 */
+-
+-	buflen = sizeof("allmulti") + sizeof(allmulti);
+-	buf = kmalloc(buflen, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: out of memory for allmulti\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		return;
+-	}
+-	allmulti = cpu_to_le32(allmulti);
+-
+-	if (!bcm_mkiovar
+-	    ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) {
+-		DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d "
+-			"buflen %u\n", dhd_ifname(&dhd->pub, ifidx),
+-			(int)sizeof(allmulti), buflen));
+-		kfree(buf);
+-		return;
+-	}
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = buflen;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set allmulti %d failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx),
+-			   le32_to_cpu(allmulti)));
+-	}
+-
+-	kfree(buf);
+-
+-	/* Finally, pick up the PROMISC flag as well, like the NIC
+-		 driver does */
+-
+-	allmulti = (dev->flags & IFF_PROMISC) ? true : false;
+-	allmulti = cpu_to_le32(allmulti);
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_PROMISC;
+-	ioc.buf = &allmulti;
+-	ioc.len = sizeof(allmulti);
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set promisc %d failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx),
+-			   le32_to_cpu(allmulti)));
+-	}
+-}
+-
+-static int
+-_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, u8 *addr)
+-{
+-	char buf[32];
+-	wl_ioctl_t ioc;
+-	int ret;
+-
+-	DHD_TRACE(("%s enter\n", __func__));
+-	if (!bcm_mkiovar
+-	    ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) {
+-		DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		return -1;
+-	}
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = 32;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set cur_etheraddr failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-	} else {
+-		memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN);
+-	}
+-
+-	return ret;
+-}
+-
+-#ifdef SOFTAP
+-extern struct net_device *ap_net_dev;
+-#endif
+-
+-static void dhd_op_if(dhd_if_t *ifp)
+-{
+-	dhd_info_t *dhd;
+-	int ret = 0, err = 0;
+-
+-	ASSERT(ifp && ifp->info && ifp->idx);	/* Virtual interfaces only */
+-
+-	dhd = ifp->info;
+-
+-	DHD_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state));
+-
+-	switch (ifp->state) {
+-	case WLC_E_IF_ADD:
+-		/*
+-		 * Delete the existing interface before overwriting it
+-		 * in case we missed the WLC_E_IF_DEL event.
+-		 */
+-		if (ifp->net != NULL) {
+-			DHD_ERROR(("%s: ERROR: netdev:%s already exists, "
+-			"try free & unregister\n",
+-			__func__, ifp->net->name));
+-			netif_stop_queue(ifp->net);
+-			unregister_netdev(ifp->net);
+-			free_netdev(ifp->net);
+-		}
+-		/* Allocate etherdev, including space for private structure */
+-		ifp->net = alloc_etherdev(sizeof(dhd));
+-		if (!ifp->net) {
+-			DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
+-			ret = -ENOMEM;
+-		}
+-		if (ret == 0) {
+-			strcpy(ifp->net->name, ifp->name);
+-			memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
+-			err = dhd_net_attach(&dhd->pub, ifp->idx);
+-			if (err != 0) {
+-				DHD_ERROR(("%s: dhd_net_attach failed, "
+-					"err %d\n",
+-					__func__, err));
+-				ret = -EOPNOTSUPP;
+-			} else {
+-#ifdef SOFTAP
+-				/* semaphore that the soft AP CODE
+-					 waits on */
+-				extern struct semaphore ap_eth_sema;
+-
+-				/* save ptr to wl0.1 netdev for use
+-					 in wl_iw.c  */
+-				ap_net_dev = ifp->net;
+-				/* signal to the SOFTAP 'sleeper' thread,
+-					 wl0.1 is ready */
+-				up(&ap_eth_sema);
+-#endif
+-				DHD_TRACE(("\n ==== pid:%x, net_device for "
+-					"if:%s created ===\n\n",
+-					current->pid, ifp->net->name));
+-				ifp->state = 0;
+-			}
+-		}
+-		break;
+-	case WLC_E_IF_DEL:
+-		if (ifp->net != NULL) {
+-			DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n",
+-				   __func__));
+-			netif_stop_queue(ifp->net);
+-			unregister_netdev(ifp->net);
+-			ret = DHD_DEL_IF;	/* Make sure the free_netdev()
+-							 is called */
+-		}
+-		break;
+-	default:
+-		DHD_ERROR(("%s: bad op %d\n", __func__, ifp->state));
+-		ASSERT(!ifp->state);
+-		break;
+-	}
+-
+-	if (ret < 0) {
+-		if (ifp->net)
+-			free_netdev(ifp->net);
+-
+-		dhd->iflist[ifp->idx] = NULL;
+-		kfree(ifp);
+-#ifdef SOFTAP
+-		if (ifp->net == ap_net_dev)
+-			ap_net_dev = NULL;	/*  NULL  SOFTAP global
+-							 wl0.1 as well */
+-#endif				/*  SOFTAP */
+-	}
+-}
+-
+-static int _dhd_sysioc_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-	int i;
+-#ifdef SOFTAP
+-	bool in_ap = false;
+-#endif
+-
+-	allow_signal(SIGTERM);
+-
+-	while (down_interruptible(&dhd->sysioc_sem) == 0) {
+-		if (kthread_should_stop())
+-			break;
+-		for (i = 0; i < DHD_MAX_IFS; i++) {
+-			if (dhd->iflist[i]) {
+-#ifdef SOFTAP
+-				in_ap = (ap_net_dev != NULL);
+-#endif				/* SOFTAP */
+-				if (dhd->iflist[i]->state)
+-					dhd_op_if(dhd->iflist[i]);
+-#ifdef SOFTAP
+-				if (dhd->iflist[i] == NULL) {
+-					DHD_TRACE(("\n\n %s: interface %d "
+-						"removed!\n", __func__, i));
+-					continue;
+-				}
+-
+-				if (in_ap && dhd->set_macaddress) {
+-					DHD_TRACE(("attempt to set MAC for %s "
+-						"in AP Mode," "blocked. \n",
+-						dhd->iflist[i]->net->name));
+-					dhd->set_macaddress = false;
+-					continue;
+-				}
+-
+-				if (in_ap && dhd->set_multicast) {
+-					DHD_TRACE(("attempt to set MULTICAST list for %s" "in AP Mode, blocked. \n",
+-						dhd->iflist[i]->net->name));
+-					dhd->set_multicast = false;
+-					continue;
+-				}
+-#endif				/* SOFTAP */
+-				if (dhd->set_multicast) {
+-					dhd->set_multicast = false;
+-					_dhd_set_multicast_list(dhd, i);
+-				}
+-				if (dhd->set_macaddress) {
+-					dhd->set_macaddress = false;
+-					_dhd_set_mac_address(dhd, i,
+-							     dhd->macvalue);
+-				}
+-			}
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int dhd_set_mac_address(struct net_device *dev, void *addr)
+-{
+-	int ret = 0;
+-
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	struct sockaddr *sa = (struct sockaddr *)addr;
+-	int ifidx;
+-
+-	ifidx = dhd_net2idx(dhd, dev);
+-	if (ifidx == DHD_BAD_IF)
+-		return -1;
+-
+-	ASSERT(dhd->sysioc_tsk);
+-	memcpy(&dhd->macvalue, sa->sa_data, ETH_ALEN);
+-	dhd->set_macaddress = true;
+-	up(&dhd->sysioc_sem);
+-
+-	return ret;
+-}
+-
+-static void dhd_set_multicast_list(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	int ifidx;
+-
+-	ifidx = dhd_net2idx(dhd, dev);
+-	if (ifidx == DHD_BAD_IF)
+-		return;
+-
+-	ASSERT(dhd->sysioc_tsk);
+-	dhd->set_multicast = true;
+-	up(&dhd->sysioc_sem);
+-}
+-
+-int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf)
+-{
+-	int ret;
+-	dhd_info_t *dhd = (dhd_info_t *) (dhdp->info);
+-
+-	/* Reject if down */
+-	if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN))
+-		return -ENODEV;
+-
+-	/* Update multicast statistic */
+-	if (pktbuf->len >= ETH_ALEN) {
+-		u8 *pktdata = (u8 *) (pktbuf->data);
+-		struct ethhdr *eh = (struct ethhdr *)pktdata;
+-
+-		if (is_multicast_ether_addr(eh->h_dest))
+-			dhdp->tx_multicast++;
+-		if (ntohs(eh->h_proto) == ETH_P_PAE)
+-			atomic_inc(&dhd->pend_8021x_cnt);
+-	}
+-
+-	/* If the protocol uses a data header, apply it */
+-	dhd_prot_hdrpush(dhdp, ifidx, pktbuf);
+-
+-	/* Use bus module to send data frame */
+-#ifdef BCMDBUS
+-	ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */);
+-#else
+-	ret = dhd_bus_txdata(dhdp->bus, pktbuf);
+-#endif				/* BCMDBUS */
+-
+-	return ret;
+-}
+-
+-static inline void *
+-osl_pkt_frmnative(struct sk_buff *skb)
+-{
+-	return (void *)skb;
+-}
+-#define PKTFRMNATIVE(osh, skb)	\
+-	osl_pkt_frmnative((struct sk_buff *)(skb))
+-
+-static inline struct sk_buff *
+-osl_pkt_tonative(void *pkt)
+-{
+-	return (struct sk_buff *)pkt;
+-}
+-#define PKTTONATIVE(osh, pkt)	\
+-	osl_pkt_tonative((pkt))
+-
+-static int dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
+-{
+-	int ret;
+-	void *pktbuf;
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	int ifidx;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Reject if down */
+-	if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) {
+-		DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n",
+-			   __func__, dhd->pub.up, dhd->pub.busstate));
+-		netif_stop_queue(net);
+-		return -ENODEV;
+-	}
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	if (ifidx == DHD_BAD_IF) {
+-		DHD_ERROR(("%s: bad ifidx %d\n", __func__, ifidx));
+-		netif_stop_queue(net);
+-		return -ENODEV;
+-	}
+-
+-	/* Make sure there's enough room for any header */
+-	if (skb_headroom(skb) < dhd->pub.hdrlen) {
+-		struct sk_buff *skb2;
+-
+-		DHD_INFO(("%s: insufficient headroom\n",
+-			  dhd_ifname(&dhd->pub, ifidx)));
+-		dhd->pub.tx_realloc++;
+-		skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen);
+-		dev_kfree_skb(skb);
+-		skb = skb2;
+-		if (skb == NULL) {
+-			DHD_ERROR(("%s: skb_realloc_headroom failed\n",
+-				   dhd_ifname(&dhd->pub, ifidx)));
+-			ret = -ENOMEM;
+-			goto done;
+-		}
+-	}
+-
+-	/* Convert to packet */
+-	pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb);
+-	if (!pktbuf) {
+-		DHD_ERROR(("%s: PKTFRMNATIVE failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		dev_kfree_skb_any(skb);
+-		ret = -ENOMEM;
+-		goto done;
+-	}
+-
+-	ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf);
+-
+-done:
+-	if (ret)
+-		dhd->pub.dstats.tx_dropped++;
+-	else
+-		dhd->pub.tx_packets++;
+-
+-	/* Return ok: we always eat the packet */
+-	return 0;
+-}
+-
+-void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state)
+-{
+-	struct net_device *net;
+-	dhd_info_t *dhd = dhdp->info;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhdp->txoff = state;
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-	net = dhd->iflist[ifidx]->net;
+-	if (state == ON)
+-		netif_stop_queue(net);
+-	else
+-		netif_wake_queue(net);
+-}
+-
+-void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf,
+-		  int numpkt)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-	struct sk_buff *skb;
+-	unsigned char *eth;
+-	uint len;
+-	void *data;
+-	struct sk_buff *pnext, *save_pktbuf;
+-	int i;
+-	dhd_if_t *ifp;
+-	wl_event_msg_t event;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	save_pktbuf = pktbuf;
+-
+-	for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) {
+-
+-		pnext = pktbuf->next;
+-		pktbuf->next = NULL;
+-
+-		skb = PKTTONATIVE(dhdp->osh, pktbuf);
+-
+-		/* Get the protocol, maintain skb around eth_type_trans()
+-		 * The main reason for this hack is for the limitation of
+-		 * Linux 2.4 where 'eth_type_trans' uses the
+-		 * 'net->hard_header_len'
+-		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
+-		 * coping of the packet coming from the network stack to add
+-		 * BDC, Hardware header etc, during network interface
+-		 * registration
+-		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
+-		 * required
+-		 * for BDC, Hardware header etc. and not just the ETH_HLEN
+-		 */
+-		eth = skb->data;
+-		len = skb->len;
+-
+-		ifp = dhd->iflist[ifidx];
+-		if (ifp == NULL)
+-			ifp = dhd->iflist[0];
+-
+-		ASSERT(ifp);
+-		skb->dev = ifp->net;
+-		skb->protocol = eth_type_trans(skb, skb->dev);
+-
+-		if (skb->pkt_type == PACKET_MULTICAST)
+-			dhd->pub.rx_multicast++;
+-
+-		skb->data = eth;
+-		skb->len = len;
+-
+-		/* Strip header, count, deliver upward */
+-		skb_pull(skb, ETH_HLEN);
+-
+-		/* Process special event packets and then discard them */
+-		if (ntohs(skb->protocol) == ETH_P_BRCM)
+-			dhd_wl_host_event(dhd, &ifidx,
+-					  skb_mac_header(skb),
+-					  &event, &data);
+-
+-		ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
+-		if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state)
+-			ifp = dhd->iflist[ifidx];
+-
+-		if (ifp->net)
+-			ifp->net->last_rx = jiffies;
+-
+-		dhdp->dstats.rx_bytes += skb->len;
+-		dhdp->rx_packets++;	/* Local count */
+-
+-		if (in_interrupt()) {
+-			netif_rx(skb);
+-		} else {
+-			/* If the receive is not processed inside an ISR,
+-			 * the softirqd must be woken explicitly to service
+-			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
+-			 * by netif_rx_ni(), but in earlier kernels, we need
+-			 * to do it manually.
+-			 */
+-			netif_rx_ni(skb);
+-		}
+-	}
+-}
+-
+-void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx)
+-{
+-	/* Linux version has nothing to do */
+-	return;
+-}
+-
+-void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success)
+-{
+-	uint ifidx;
+-	dhd_info_t *dhd = (dhd_info_t *) (dhdp->info);
+-	struct ethhdr *eh;
+-	u16 type;
+-
+-	dhd_prot_hdrpull(dhdp, &ifidx, txp);
+-
+-	eh = (struct ethhdr *)(txp->data);
+-	type = ntohs(eh->h_proto);
+-
+-	if (type == ETH_P_PAE)
+-		atomic_dec(&dhd->pend_8021x_cnt);
+-
+-}
+-
+-static struct net_device_stats *dhd_get_stats(struct net_device *net)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	dhd_if_t *ifp;
+-	int ifidx;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	if (ifidx == DHD_BAD_IF)
+-		return NULL;
+-
+-	ifp = dhd->iflist[ifidx];
+-	ASSERT(dhd && ifp);
+-
+-	if (dhd->pub.up) {
+-		/* Use the protocol to get dongle stats */
+-		dhd_prot_dstats(&dhd->pub);
+-	}
+-
+-	/* Copy dongle stats to net device stats */
+-	ifp->stats.rx_packets = dhd->pub.dstats.rx_packets;
+-	ifp->stats.tx_packets = dhd->pub.dstats.tx_packets;
+-	ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes;
+-	ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes;
+-	ifp->stats.rx_errors = dhd->pub.dstats.rx_errors;
+-	ifp->stats.tx_errors = dhd->pub.dstats.tx_errors;
+-	ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped;
+-	ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped;
+-	ifp->stats.multicast = dhd->pub.dstats.multicast;
+-
+-	return &ifp->stats;
+-}
+-
+-static int dhd_watchdog_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	/* This thread doesn't need any user-level access,
+-	 * so get rid of all our resources
+-	 */
+-#ifdef DHD_SCHED
+-	if (dhd_watchdog_prio > 0) {
+-		struct sched_param param;
+-		param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO) ?
+-		    dhd_watchdog_prio : (MAX_RT_PRIO - 1);
+-		setScheduler(current, SCHED_FIFO, &param);
+-	}
+-#endif				/* DHD_SCHED */
+-
+-	allow_signal(SIGTERM);
+-	/* Run until signal received */
+-	while (1) {
+-		if (kthread_should_stop())
+-			break;
+-		if (down_interruptible(&dhd->watchdog_sem) == 0) {
+-			if (dhd->pub.dongle_reset == false) {
+-				/* Call the bus module watchdog */
+-				dhd_bus_watchdog(&dhd->pub);
+-			}
+-			/* Count the tick for reference */
+-			dhd->pub.tickcnt++;
+-		} else
+-			break;
+-	}
+-	return 0;
+-}
+-
+-static void dhd_watchdog(unsigned long data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	if (dhd->watchdog_tsk) {
+-		up(&dhd->watchdog_sem);
+-
+-		/* Reschedule the watchdog */
+-		if (dhd->wd_timer_valid) {
+-			mod_timer(&dhd->timer,
+-				  jiffies + dhd_watchdog_ms * HZ / 1000);
+-		}
+-		return;
+-	}
+-
+-	/* Call the bus module watchdog */
+-	dhd_bus_watchdog(&dhd->pub);
+-
+-	/* Count the tick for reference */
+-	dhd->pub.tickcnt++;
+-
+-	/* Reschedule the watchdog */
+-	if (dhd->wd_timer_valid)
+-		mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+-}
+-
+-static int dhd_dpc_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	/* This thread doesn't need any user-level access,
+-	 * so get rid of all our resources
+-	 */
+-#ifdef DHD_SCHED
+-	if (dhd_dpc_prio > 0) {
+-		struct sched_param param;
+-		param.sched_priority =
+-		    (dhd_dpc_prio <
+-		     MAX_RT_PRIO) ? dhd_dpc_prio : (MAX_RT_PRIO - 1);
+-		setScheduler(current, SCHED_FIFO, &param);
+-	}
+-#endif				/* DHD_SCHED */
+-
+-	allow_signal(SIGTERM);
+-	/* Run until signal received */
+-	while (1) {
+-		if (kthread_should_stop())
+-			break;
+-		if (down_interruptible(&dhd->dpc_sem) == 0) {
+-			/* Call bus dpc unless it indicated down
+-				 (then clean stop) */
+-			if (dhd->pub.busstate != DHD_BUS_DOWN) {
+-				if (dhd_bus_dpc(dhd->pub.bus)) {
+-					up(&dhd->dpc_sem);
+-				}
+-			} else {
+-				dhd_bus_stop(dhd->pub.bus, true);
+-			}
+-		} else
+-			break;
+-	}
+-	return 0;
+-}
+-
+-static void dhd_dpc(unsigned long data)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) data;
+-
+-	/* Call bus dpc unless it indicated down (then clean stop) */
+-	if (dhd->pub.busstate != DHD_BUS_DOWN) {
+-		if (dhd_bus_dpc(dhd->pub.bus))
+-			tasklet_schedule(&dhd->tasklet);
+-	} else {
+-		dhd_bus_stop(dhd->pub.bus, true);
+-	}
+-}
+-
+-void dhd_sched_dpc(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-
+-	if (dhd->dpc_tsk) {
+-		up(&dhd->dpc_sem);
+-		return;
+-	}
+-
+-	tasklet_schedule(&dhd->tasklet);
+-}
+-
+-#ifdef TOE
+-/* Retrieve current toe component enables, which are kept
+-	 as a bitmap in toe_ol iovar */
+-static int dhd_toe_get(dhd_info_t *dhd, int ifidx, u32 *toe_ol)
+-{
+-	wl_ioctl_t ioc;
+-	char buf[32];
+-	int ret;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = WLC_GET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = (uint) sizeof(buf);
+-	ioc.set = false;
+-
+-	strcpy(buf, "toe_ol");
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		/* Check for older dongle image that doesn't support toe_ol */
+-		if (ret == -EIO) {
+-			DHD_ERROR(("%s: toe not supported by device\n",
+-				   dhd_ifname(&dhd->pub, ifidx)));
+-			return -EOPNOTSUPP;
+-		}
+-
+-		DHD_INFO(("%s: could not get toe_ol: ret=%d\n",
+-			  dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	memcpy(toe_ol, buf, sizeof(u32));
+-	return 0;
+-}
+-
+-/* Set current toe component enables in toe_ol iovar,
+-	 and set toe global enable iovar */
+-static int dhd_toe_set(dhd_info_t *dhd, int ifidx, u32 toe_ol)
+-{
+-	wl_ioctl_t ioc;
+-	char buf[32];
+-	int toe, ret;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = (uint) sizeof(buf);
+-	ioc.set = true;
+-
+-	/* Set toe_ol as requested */
+-
+-	strcpy(buf, "toe_ol");
+-	memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: could not set toe_ol: ret=%d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	/* Enable toe globally only if any components are enabled. */
+-
+-	toe = (toe_ol != 0);
+-
+-	strcpy(buf, "toe");
+-	memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: could not set toe: ret=%d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* TOE */
+-
+-static void dhd_ethtool_get_drvinfo(struct net_device *net,
+-				    struct ethtool_drvinfo *info)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-
+-	sprintf(info->driver, DRV_MODULE_NAME);
+-	sprintf(info->version, "%lu", dhd->pub.drv_version);
+-	sprintf(info->fw_version, "%s", wl_cfg80211_get_fwname());
+-	sprintf(info->bus_info, "%s", dev_name(&wl_cfg80211_get_sdio_func()->dev));
+-}
+-
+-struct ethtool_ops dhd_ethtool_ops = {
+-	.get_drvinfo = dhd_ethtool_get_drvinfo
+-};
+-
+-static int dhd_ethtool(dhd_info_t *dhd, void *uaddr)
+-{
+-	struct ethtool_drvinfo info;
+-	char drvname[sizeof(info.driver)];
+-	u32 cmd;
+-#ifdef TOE
+-	struct ethtool_value edata;
+-	u32 toe_cmpnt, csum_dir;
+-	int ret;
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* all ethtool calls start with a cmd word */
+-	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
+-		return -EFAULT;
+-
+-	switch (cmd) {
+-	case ETHTOOL_GDRVINFO:
+-		/* Copy out any request driver name */
+-		if (copy_from_user(&info, uaddr, sizeof(info)))
+-			return -EFAULT;
+-		strncpy(drvname, info.driver, sizeof(info.driver));
+-		drvname[sizeof(info.driver) - 1] = '\0';
+-
+-		/* clear struct for return */
+-		memset(&info, 0, sizeof(info));
+-		info.cmd = cmd;
+-
+-		/* if dhd requested, identify ourselves */
+-		if (strcmp(drvname, "?dhd") == 0) {
+-			sprintf(info.driver, "dhd");
+-			strcpy(info.version, EPI_VERSION_STR);
+-		}
+-
+-		/* otherwise, require dongle to be up */
+-		else if (!dhd->pub.up) {
+-			DHD_ERROR(("%s: dongle is not up\n", __func__));
+-			return -ENODEV;
+-		}
+-
+-		/* finally, report dongle driver type */
+-		else if (dhd->pub.iswl)
+-			sprintf(info.driver, "wl");
+-		else
+-			sprintf(info.driver, "xx");
+-
+-		sprintf(info.version, "%lu", dhd->pub.drv_version);
+-		if (copy_to_user(uaddr, &info, sizeof(info)))
+-			return -EFAULT;
+-		DHD_CTL(("%s: given %*s, returning %s\n", __func__,
+-			 (int)sizeof(drvname), drvname, info.driver));
+-		break;
+-
+-#ifdef TOE
+-		/* Get toe offload components from dongle */
+-	case ETHTOOL_GRXCSUM:
+-	case ETHTOOL_GTXCSUM:
+-		ret = dhd_toe_get(dhd, 0, &toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		csum_dir =
+-		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+-
+-		edata.cmd = cmd;
+-		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
+-
+-		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+-			return -EFAULT;
+-		break;
+-
+-		/* Set toe offload components in dongle */
+-	case ETHTOOL_SRXCSUM:
+-	case ETHTOOL_STXCSUM:
+-		if (copy_from_user(&edata, uaddr, sizeof(edata)))
+-			return -EFAULT;
+-
+-		/* Read the current settings, update and write back */
+-		ret = dhd_toe_get(dhd, 0, &toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		csum_dir =
+-		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+-
+-		if (edata.data != 0)
+-			toe_cmpnt |= csum_dir;
+-		else
+-			toe_cmpnt &= ~csum_dir;
+-
+-		ret = dhd_toe_set(dhd, 0, toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		/* If setting TX checksum mode, tell Linux the new mode */
+-		if (cmd == ETHTOOL_STXCSUM) {
+-			if (edata.data)
+-				dhd->iflist[0]->net->features |=
+-				    NETIF_F_IP_CSUM;
+-			else
+-				dhd->iflist[0]->net->features &=
+-				    ~NETIF_F_IP_CSUM;
+-		}
+-
+-		break;
+-#endif				/* TOE */
+-
+-	default:
+-		return -EOPNOTSUPP;
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	dhd_ioctl_t ioc;
+-	int bcmerror = 0;
+-	int buflen = 0;
+-	void *buf = NULL;
+-	uint driver = 0;
+-	int ifidx;
+-	bool is_set_key_cmd;
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd));
+-
+-	if (ifidx == DHD_BAD_IF)
+-		return -1;
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-	/* linux wireless extensions */
+-	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+-		/* may recurse, do NOT lock */
+-		return wl_iw_ioctl(net, ifr, cmd);
+-	}
+-#endif				/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	if (cmd == SIOCETHTOOL)
+-		return dhd_ethtool(dhd, (void *)ifr->ifr_data);
+-
+-	if (cmd != SIOCDEVPRIVATE)
+-		return -EOPNOTSUPP;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	/* Copy the ioc control structure part of ioctl request */
+-	if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Copy out any buffer passed */
+-	if (ioc.buf) {
+-		buflen = min_t(int, ioc.len, DHD_IOCTL_MAXLEN);
+-		/* optimization for direct ioctl calls from kernel */
+-		/*
+-		   if (segment_eq(get_fs(), KERNEL_DS)) {
+-		   buf = ioc.buf;
+-		   } else {
+-		 */
+-		{
+-			buf = kmalloc(buflen, GFP_ATOMIC);
+-			if (!buf) {
+-				bcmerror = -ENOMEM;
+-				goto done;
+-			}
+-			if (copy_from_user(buf, ioc.buf, buflen)) {
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-		}
+-	}
+-
+-	/* To differentiate between wl and dhd read 4 more byes */
+-	if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
+-			    sizeof(uint)) != 0)) {
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	if (!capable(CAP_NET_ADMIN)) {
+-		bcmerror = -EPERM;
+-		goto done;
+-	}
+-
+-	/* check for local dhd ioctl and handle it */
+-	if (driver == DHD_IOCTL_MAGIC) {
+-		bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen);
+-		if (bcmerror)
+-			dhd->pub.bcmerror = bcmerror;
+-		goto done;
+-	}
+-
+-	/* send to dongle (must be up, and wl) */
+-	if ((dhd->pub.busstate != DHD_BUS_DATA)) {
+-		DHD_ERROR(("%s DONGLE_DOWN,__func__\n", __func__));
+-		bcmerror = -EIO;
+-		goto done;
+-	}
+-
+-	if (!dhd->pub.iswl) {
+-		bcmerror = -EIO;
+-		goto done;
+-	}
+-
+-	/* Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to
+-	 * prevent M4 encryption.
+-	 */
+-	is_set_key_cmd = ((ioc.cmd == WLC_SET_KEY) ||
+-			  ((ioc.cmd == WLC_SET_VAR) &&
+-			   !(strncmp("wsec_key", ioc.buf, 9))) ||
+-			  ((ioc.cmd == WLC_SET_VAR) &&
+-			   !(strncmp("bsscfg:wsec_key", ioc.buf, 15))));
+-	if (is_set_key_cmd)
+-		dhd_wait_pend8021x(net);
+-
+-	bcmerror =
+-	    dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
+-
+-done:
+-	if (!bcmerror && buf && ioc.buf) {
+-		if (copy_to_user(ioc.buf, buf, buflen))
+-			bcmerror = -EFAULT;
+-	}
+-
+-	kfree(buf);
+-
+-	if (bcmerror > 0)
+-		bcmerror = 0;
+-
+-	return bcmerror;
+-}
+-
+-static int dhd_stop(struct net_device *net)
+-{
+-#if !defined(IGNORE_ETH0_DOWN)
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	if (IS_CFG80211_FAVORITE()) {
+-		wl_cfg80211_down();
+-	}
+-	if (dhd->pub.up == 0)
+-		return 0;
+-
+-	/* Set state and stop OS transmissions */
+-	dhd->pub.up = 0;
+-	netif_stop_queue(net);
+-#else
+-	DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation\n",
+-		__func__));
+-#endif				/* !defined(IGNORE_ETH0_DOWN) */
+-
+-	return 0;
+-}
+-
+-static int dhd_open(struct net_device *net)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-#ifdef TOE
+-	u32 toe_ol;
+-#endif
+-	int ifidx = dhd_net2idx(dhd, net);
+-	s32 ret = 0;
+-
+-	DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx));
+-
+-	if (ifidx == 0) {	/* do it only for primary eth0 */
+-
+-		/* try to bring up bus */
+-		ret = dhd_bus_start(&dhd->pub);
+-		if (ret != 0) {
+-			DHD_ERROR(("%s: failed with code %d\n", __func__, ret));
+-			return -1;
+-		}
+-		atomic_set(&dhd->pend_8021x_cnt, 0);
+-
+-		memcpy(net->dev_addr, dhd->pub.mac, ETH_ALEN);
+-
+-#ifdef TOE
+-		/* Get current TOE mode from dongle */
+-		if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0
+-		    && (toe_ol & TOE_TX_CSUM_OL) != 0)
+-			dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM;
+-		else
+-			dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM;
+-#endif
+-	}
+-	/* Allow transmit calls */
+-	netif_start_queue(net);
+-	dhd->pub.up = 1;
+-	if (IS_CFG80211_FAVORITE()) {
+-		if (unlikely(wl_cfg80211_up())) {
+-			DHD_ERROR(("%s: failed to bring up cfg80211\n",
+-				   __func__));
+-			return -1;
+-		}
+-	}
+-
+-	return ret;
+-}
+-
+-int
+-dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name,
+-	   u8 *mac_addr, u32 flags, u8 bssidx)
+-{
+-	dhd_if_t *ifp;
+-
+-	DHD_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle));
+-
+-	ASSERT(dhd && (ifidx < DHD_MAX_IFS));
+-
+-	ifp = dhd->iflist[ifidx];
+-	if (!ifp && !(ifp = kmalloc(sizeof(dhd_if_t), GFP_ATOMIC))) {
+-		DHD_ERROR(("%s: OOM - dhd_if_t\n", __func__));
+-		return -ENOMEM;
+-	}
+-
+-	memset(ifp, 0, sizeof(dhd_if_t));
+-	ifp->info = dhd;
+-	dhd->iflist[ifidx] = ifp;
+-	strlcpy(ifp->name, name, IFNAMSIZ);
+-	if (mac_addr != NULL)
+-		memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
+-
+-	if (handle == NULL) {
+-		ifp->state = WLC_E_IF_ADD;
+-		ifp->idx = ifidx;
+-		ASSERT(dhd->sysioc_tsk);
+-		up(&dhd->sysioc_sem);
+-	} else
+-		ifp->net = (struct net_device *)handle;
+-
+-	return 0;
+-}
+-
+-void dhd_del_if(dhd_info_t *dhd, int ifidx)
+-{
+-	dhd_if_t *ifp;
+-
+-	DHD_TRACE(("%s: idx %d\n", __func__, ifidx));
+-
+-	ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS));
+-	ifp = dhd->iflist[ifidx];
+-	if (!ifp) {
+-		DHD_ERROR(("%s: Null interface\n", __func__));
+-		return;
+-	}
+-
+-	ifp->state = WLC_E_IF_DEL;
+-	ifp->idx = ifidx;
+-	ASSERT(dhd->sysioc_tsk);
+-	up(&dhd->sysioc_sem);
+-}
+-
+-dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen)
+-{
+-	dhd_info_t *dhd = NULL;
+-	struct net_device *net;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	/* updates firmware nvram path if it was provided as module
+-		 paramters */
+-	if ((firmware_path != NULL) && (firmware_path[0] != '\0'))
+-		strcpy(fw_path, firmware_path);
+-	if ((nvram_path != NULL) && (nvram_path[0] != '\0'))
+-		strcpy(nv_path, nvram_path);
+-
+-	/* Allocate etherdev, including space for private structure */
+-	net = alloc_etherdev(sizeof(dhd));
+-	if (!net) {
+-		DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Allocate primary dhd_info */
+-	dhd = kzalloc(sizeof(dhd_info_t), GFP_ATOMIC);
+-	if (!dhd) {
+-		DHD_ERROR(("%s: OOM - alloc dhd_info\n", __func__));
+-		goto fail;
+-	}
+-
+-	/*
+-	 * Save the dhd_info into the priv
+-	 */
+-	memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+-
+-	/* Set network interface name if it was provided as module parameter */
+-	if (iface_name[0]) {
+-		int len;
+-		char ch;
+-		strncpy(net->name, iface_name, IFNAMSIZ);
+-		net->name[IFNAMSIZ - 1] = 0;
+-		len = strlen(net->name);
+-		ch = net->name[len - 1];
+-		if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
+-			strcat(net->name, "%d");
+-	}
+-
+-	if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) ==
+-	    DHD_BAD_IF)
+-		goto fail;
+-
+-	net->netdev_ops = NULL;
+-	sema_init(&dhd->proto_sem, 1);
+-	/* Initialize other structure content */
+-	init_waitqueue_head(&dhd->ioctl_resp_wait);
+-	init_waitqueue_head(&dhd->ctrl_wait);
+-
+-	/* Initialize the spinlocks */
+-	spin_lock_init(&dhd->sdlock);
+-	spin_lock_init(&dhd->txqlock);
+-
+-	/* Link to info module */
+-	dhd->pub.info = dhd;
+-
+-	/* Link to bus module */
+-	dhd->pub.bus = bus;
+-	dhd->pub.hdrlen = bus_hdrlen;
+-
+-	/* Attach and link in the protocol */
+-	if (dhd_prot_attach(&dhd->pub) != 0) {
+-		DHD_ERROR(("dhd_prot_attach failed\n"));
+-		goto fail;
+-	}
+-#if defined(CONFIG_WIRELESS_EXT)
+-	/* Attach and link in the iw */
+-	if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
+-		DHD_ERROR(("wl_iw_attach failed\n"));
+-		goto fail;
+-	}
+-#endif	/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	/* Attach and link in the cfg80211 */
+-	if (IS_CFG80211_FAVORITE()) {
+-		if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
+-			DHD_ERROR(("wl_cfg80211_attach failed\n"));
+-			goto fail;
+-		}
+-		if (!NO_FW_REQ()) {
+-			strcpy(fw_path, wl_cfg80211_get_fwname());
+-			strcpy(nv_path, wl_cfg80211_get_nvramname());
+-		}
+-	}
+-
+-	/* Set up the watchdog timer */
+-	init_timer(&dhd->timer);
+-	dhd->timer.data = (unsigned long) dhd;
+-	dhd->timer.function = dhd_watchdog;
+-
+-	/* Initialize thread based operation and lock */
+-	sema_init(&dhd->sdsem, 1);
+-	if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0))
+-		dhd->threads_only = true;
+-	else
+-		dhd->threads_only = false;
+-
+-	if (dhd_dpc_prio >= 0) {
+-		/* Initialize watchdog thread */
+-		sema_init(&dhd->watchdog_sem, 0);
+-		dhd->watchdog_tsk = kthread_run(dhd_watchdog_thread, dhd,
+-						"dhd_watchdog");
+-		if (IS_ERR(dhd->watchdog_tsk)) {
+-			printk(KERN_WARNING
+-				"dhd_watchdog thread failed to start\n");
+-			dhd->watchdog_tsk = NULL;
+-		}
+-	} else {
+-		dhd->watchdog_tsk = NULL;
+-	}
+-
+-	/* Set up the bottom half handler */
+-	if (dhd_dpc_prio >= 0) {
+-		/* Initialize DPC thread */
+-		sema_init(&dhd->dpc_sem, 0);
+-		dhd->dpc_tsk = kthread_run(dhd_dpc_thread, dhd, "dhd_dpc");
+-		if (IS_ERR(dhd->dpc_tsk)) {
+-			printk(KERN_WARNING
+-				"dhd_dpc thread failed to start\n");
+-			dhd->dpc_tsk = NULL;
+-		}
+-	} else {
+-		tasklet_init(&dhd->tasklet, dhd_dpc, (unsigned long) dhd);
+-		dhd->dpc_tsk = NULL;
+-	}
+-
+-	if (dhd_sysioc) {
+-		sema_init(&dhd->sysioc_sem, 0);
+-		dhd->sysioc_tsk = kthread_run(_dhd_sysioc_thread, dhd,
+-						"_dhd_sysioc");
+-		if (IS_ERR(dhd->sysioc_tsk)) {
+-			printk(KERN_WARNING
+-				"_dhd_sysioc thread failed to start\n");
+-			dhd->sysioc_tsk = NULL;
+-		}
+-	} else
+-		dhd->sysioc_tsk = NULL;
+-
+-	/*
+-	 * Save the dhd_info into the priv
+-	 */
+-	memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	g_bus = bus;
+-#endif
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, false);
+-	if (!IS_CFG80211_FAVORITE())
+-		register_pm_notifier(&dhd_sleep_pm_notifier);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-	/* && defined(DHD_GPL) */
+-	/* Init lock suspend to prevent kernel going to suspend */
+-#ifdef CONFIG_HAS_EARLYSUSPEND
+-	dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20;
+-	dhd->early_suspend.suspend = dhd_early_suspend;
+-	dhd->early_suspend.resume = dhd_late_resume;
+-	register_early_suspend(&dhd->early_suspend);
+-#endif
+-
+-	return &dhd->pub;
+-
+-fail:
+-	if (net)
+-		free_netdev(net);
+-	if (dhd)
+-		dhd_detach(&dhd->pub);
+-
+-	return NULL;
+-}
+-
+-int dhd_bus_start(dhd_pub_t *dhdp)
+-{
+-	int ret = -1;
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-#ifdef EMBEDDED_PLATFORM
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	ASSERT(dhd);
+-
+-	DHD_TRACE(("%s:\n", __func__));
+-
+-	/* try to download image and nvram to the dongle */
+-	if (dhd->pub.busstate == DHD_BUS_DOWN) {
+-		if (!(dhd_bus_download_firmware(dhd->pub.bus,
+-						fw_path, nv_path))) {
+-			DHD_ERROR(("%s: dhdsdio_probe_download failed. "
+-				"firmware = %s nvram = %s\n",
+-				__func__, fw_path, nv_path));
+-			return -1;
+-		}
+-	}
+-
+-	/* Start the watchdog timer */
+-	dhd->pub.tickcnt = 0;
+-	dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+-
+-	/* Bring up the bus */
+-	ret = dhd_bus_init(&dhd->pub, true);
+-	if (ret != 0) {
+-		DHD_ERROR(("%s, dhd_bus_init failed %d\n", __func__, ret));
+-		return ret;
+-	}
+-#if defined(OOB_INTR_ONLY)
+-	/* Host registration for OOB interrupt */
+-	if (bcmsdh_register_oob_intr(dhdp)) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		DHD_ERROR(("%s Host failed to resgister for OOB\n", __func__));
+-		return -ENODEV;
+-	}
+-
+-	/* Enable oob at firmware */
+-	dhd_enable_oob_intr(dhd->pub.bus, true);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-	/* If bus is not ready, can't come up */
+-	if (dhd->pub.busstate != DHD_BUS_DATA) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		DHD_ERROR(("%s failed bus is not ready\n", __func__));
+-		return -ENODEV;
+-	}
+-#ifdef EMBEDDED_PLATFORM
+-	bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+-	memcpy(dhdp->eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-
+-	setbit(dhdp->eventmask, WLC_E_SET_SSID);
+-	setbit(dhdp->eventmask, WLC_E_PRUNE);
+-	setbit(dhdp->eventmask, WLC_E_AUTH);
+-	setbit(dhdp->eventmask, WLC_E_REASSOC);
+-	setbit(dhdp->eventmask, WLC_E_REASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_DEAUTH_IND);
+-	setbit(dhdp->eventmask, WLC_E_DISASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_DISASSOC);
+-	setbit(dhdp->eventmask, WLC_E_JOIN);
+-	setbit(dhdp->eventmask, WLC_E_ASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_PSK_SUP);
+-	setbit(dhdp->eventmask, WLC_E_LINK);
+-	setbit(dhdp->eventmask, WLC_E_NDIS_LINK);
+-	setbit(dhdp->eventmask, WLC_E_MIC_ERROR);
+-	setbit(dhdp->eventmask, WLC_E_PMKID_CACHE);
+-	setbit(dhdp->eventmask, WLC_E_TXFAIL);
+-	setbit(dhdp->eventmask, WLC_E_JOIN_START);
+-	setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
+-#ifdef PNO_SUPPORT
+-	setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
+-#endif				/* PNO_SUPPORT */
+-
+-/* enable dongle roaming event */
+-
+-	dhdp->pktfilter_count = 1;
+-	/* Setup filter to allow only unicast */
+-	dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00";
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	/* Bus is ready, do any protocol initialization */
+-	ret = dhd_prot_init(&dhd->pub);
+-	if (ret < 0)
+-		return ret;
+-
+-	return 0;
+-}
+-
+-int
+-dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len,
+-	  int set)
+-{
+-	char buf[strlen(name) + 1 + cmd_len];
+-	int len = sizeof(buf);
+-	wl_ioctl_t ioc;
+-	int ret;
+-
+-	len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = set ? WLC_SET_VAR : WLC_GET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = len;
+-	ioc.set = set;
+-
+-	ret = dhd_prot_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (!set && ret >= 0)
+-		memcpy(cmd_buf, buf, cmd_len);
+-
+-	return ret;
+-}
+-
+-static struct net_device_ops dhd_ops_pri = {
+-	.ndo_open = dhd_open,
+-	.ndo_stop = dhd_stop,
+-	.ndo_get_stats = dhd_get_stats,
+-	.ndo_do_ioctl = dhd_ioctl_entry,
+-	.ndo_start_xmit = dhd_start_xmit,
+-	.ndo_set_mac_address = dhd_set_mac_address,
+-	.ndo_set_multicast_list = dhd_set_multicast_list
+-};
+-
+-int dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-	struct net_device *net;
+-	u8 temp_addr[ETH_ALEN] = {
+-		0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
+-
+-	DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx));
+-
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-
+-	net = dhd->iflist[ifidx]->net;
+-	ASSERT(net);
+-
+-	ASSERT(!net->netdev_ops);
+-	net->netdev_ops = &dhd_ops_pri;
+-
+-	/*
+-	 * We have to use the primary MAC for virtual interfaces
+-	 */
+-	if (ifidx != 0) {
+-		/* for virtual interfaces use the primary MAC  */
+-		memcpy(temp_addr, dhd->pub.mac, ETH_ALEN);
+-
+-	}
+-
+-	if (ifidx == 1) {
+-		DHD_TRACE(("%s ACCESS POINT MAC: \n", __func__));
+-		/*  ACCESSPOINT INTERFACE CASE */
+-		temp_addr[0] |= 0X02;	/* set bit 2 ,
+-			 - Locally Administered address  */
+-
+-	}
+-	net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
+-	net->ethtool_ops = &dhd_ethtool_ops;
+-
+-	dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen;
+-
+-	memcpy(net->dev_addr, temp_addr, ETH_ALEN);
+-
+-	if (register_netdev(net) != 0) {
+-		DHD_ERROR(("%s: couldn't register the net device\n",
+-			__func__));
+-		goto fail;
+-	}
+-
+-	DHD_INFO(("%s: Broadcom Dongle Host Driver\n", net->name));
+-
+-	return 0;
+-
+-fail:
+-	net->netdev_ops = NULL;
+-	return -EBADE;
+-}
+-
+-void dhd_bus_detach(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (dhdp) {
+-		dhd = (dhd_info_t *) dhdp->info;
+-		if (dhd) {
+-			/* Stop the protocol module */
+-			dhd_prot_stop(&dhd->pub);
+-
+-			/* Stop the bus module */
+-			dhd_bus_stop(dhd->pub.bus, true);
+-#if defined(OOB_INTR_ONLY)
+-			bcmsdh_unregister_oob_intr();
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-			/* Clear the watchdog timer */
+-			del_timer_sync(&dhd->timer);
+-			dhd->wd_timer_valid = false;
+-		}
+-	}
+-}
+-
+-void dhd_detach(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (dhdp) {
+-		dhd = (dhd_info_t *) dhdp->info;
+-		if (dhd) {
+-			dhd_if_t *ifp;
+-			int i;
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-			if (dhd->early_suspend.suspend)
+-				unregister_early_suspend(&dhd->early_suspend);
+-#endif				/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-			for (i = 1; i < DHD_MAX_IFS; i++)
+-				if (dhd->iflist[i])
+-					dhd_del_if(dhd, i);
+-
+-			ifp = dhd->iflist[0];
+-			ASSERT(ifp);
+-			if (ifp->net->netdev_ops == &dhd_ops_pri) {
+-				dhd_stop(ifp->net);
+-				unregister_netdev(ifp->net);
+-			}
+-
+-			if (dhd->watchdog_tsk) {
+-				send_sig(SIGTERM, dhd->watchdog_tsk, 1);
+-				kthread_stop(dhd->watchdog_tsk);
+-				dhd->watchdog_tsk = NULL;
+-			}
+-
+-			if (dhd->dpc_tsk) {
+-				send_sig(SIGTERM, dhd->dpc_tsk, 1);
+-				kthread_stop(dhd->dpc_tsk);
+-				dhd->dpc_tsk = NULL;
+-			} else
+-				tasklet_kill(&dhd->tasklet);
+-
+-			if (dhd->sysioc_tsk) {
+-				send_sig(SIGTERM, dhd->sysioc_tsk, 1);
+-				kthread_stop(dhd->sysioc_tsk);
+-				dhd->sysioc_tsk = NULL;
+-			}
+-
+-			dhd_bus_detach(dhdp);
+-
+-			if (dhdp->prot)
+-				dhd_prot_detach(dhdp);
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-			wl_iw_detach();
+-#endif				/* (CONFIG_WIRELESS_EXT) */
+-
+-			if (IS_CFG80211_FAVORITE())
+-				wl_cfg80211_detach();
+-
+-#if defined(CONFIG_PM_SLEEP)
+-			if (!IS_CFG80211_FAVORITE())
+-				unregister_pm_notifier(&dhd_sleep_pm_notifier);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-			/* && defined(DHD_GPL) */
+-			free_netdev(ifp->net);
+-			kfree(ifp);
+-			kfree(dhd);
+-		}
+-	}
+-}
+-
+-static void __exit dhd_module_cleanup(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhd_bus_unregister();
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	wifi_del_dev();
+-#endif
+-	/* Call customer gpio to turn off power with WL_REG_ON signal */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+-}
+-
+-static int __init dhd_module_init(void)
+-{
+-	int error;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Sanity check on the module parameters */
+-	do {
+-		/* Both watchdog and DPC as tasklets are ok */
+-		if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0))
+-			break;
+-
+-		/* If both watchdog and DPC are threads, TX must be deferred */
+-		if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)
+-		    && dhd_deferred_tx)
+-			break;
+-
+-		DHD_ERROR(("Invalid module parameters.\n"));
+-		return -EINVAL;
+-	} while (0);
+-	/* Call customer gpio to turn on power with WL_REG_ON signal */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	sema_init(&wifi_control_sem, 0);
+-
+-	error = wifi_add_dev();
+-	if (error) {
+-		DHD_ERROR(("%s: platform_driver_register failed\n", __func__));
+-		goto failed;
+-	}
+-
+-	/* Waiting callback after platform_driver_register is done or
+-		 exit with error */
+-	if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
+-		printk(KERN_ERR "%s: platform_driver_register timeout\n",
+-			__func__);
+-		/* remove device */
+-		wifi_del_dev();
+-		goto failed;
+-	}
+-#endif	/* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+-
+-	error = dhd_bus_register();
+-
+-	if (error) {
+-		DHD_ERROR(("%s: sdio_register_driver failed\n", __func__));
+-		goto failed;
+-	}
+-	return error;
+-
+-failed:
+-	/* turn off power and exit */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+-	return -EINVAL;
+-}
+-
+-module_init(dhd_module_init);
+-module_exit(dhd_module_cleanup);
+-
+-/*
+- * OS specific functions required to implement DHD driver in OS independent way
+- */
+-int dhd_os_proto_block(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd) {
+-		down(&dhd->proto_sem);
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-int dhd_os_proto_unblock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd) {
+-		up(&dhd->proto_sem);
+-		return 1;
+-	}
+-
+-	return 0;
+-}
+-
+-unsigned int dhd_os_get_ioctl_resp_timeout(void)
+-{
+-	return (unsigned int)dhd_ioctl_timeout_msec;
+-}
+-
+-void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
+-{
+-	dhd_ioctl_timeout_msec = (int)timeout_msec;
+-}
+-
+-int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-	DECLARE_WAITQUEUE(wait, current);
+-	int timeout = dhd_ioctl_timeout_msec;
+-
+-	/* Convert timeout in millsecond to jiffies */
+-	timeout = timeout * HZ / 1000;
+-
+-	/* Wait until control frame is available */
+-	add_wait_queue(&dhd->ioctl_resp_wait, &wait);
+-	set_current_state(TASK_INTERRUPTIBLE);
+-
+-	while (!(*condition) && (!signal_pending(current) && timeout))
+-		timeout = schedule_timeout(timeout);
+-
+-	if (signal_pending(current))
+-		*pending = true;
+-
+-	set_current_state(TASK_RUNNING);
+-	remove_wait_queue(&dhd->ioctl_resp_wait, &wait);
+-
+-	return timeout;
+-}
+-
+-int dhd_os_ioctl_resp_wake(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (waitqueue_active(&dhd->ioctl_resp_wait))
+-		wake_up_interruptible(&dhd->ioctl_resp_wait);
+-
+-	return 0;
+-}
+-
+-void dhd_os_wd_timer(void *bus, uint wdtick)
+-{
+-	dhd_pub_t *pub = bus;
+-	static uint save_dhd_watchdog_ms;
+-	dhd_info_t *dhd = (dhd_info_t *) pub->info;
+-
+-	/* don't start the wd until fw is loaded */
+-	if (pub->busstate == DHD_BUS_DOWN)
+-		return;
+-
+-	/* Totally stop the timer */
+-	if (!wdtick && dhd->wd_timer_valid == true) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		save_dhd_watchdog_ms = wdtick;
+-		return;
+-	}
+-
+-	if (wdtick) {
+-		dhd_watchdog_ms = (uint) wdtick;
+-
+-		if (save_dhd_watchdog_ms != dhd_watchdog_ms) {
+-
+-			if (dhd->wd_timer_valid == true)
+-				/* Stop timer and restart at new value */
+-				del_timer_sync(&dhd->timer);
+-
+-			/* Create timer again when watchdog period is
+-			   dynamically changed or in the first instance
+-			 */
+-			dhd->timer.expires =
+-			    jiffies + dhd_watchdog_ms * HZ / 1000;
+-			add_timer(&dhd->timer);
+-
+-		} else {
+-			/* Re arm the timer, at last watchdog period */
+-			mod_timer(&dhd->timer,
+-				  jiffies + dhd_watchdog_ms * HZ / 1000);
+-		}
+-
+-		dhd->wd_timer_valid = true;
+-		save_dhd_watchdog_ms = wdtick;
+-	}
+-}
+-
+-void *dhd_os_open_image(char *filename)
+-{
+-	struct file *fp;
+-
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_request_fw(filename);
+-
+-	fp = filp_open(filename, O_RDONLY, 0);
+-	/*
+-	 * 2.6.11 (FC4) supports filp_open() but later revs don't?
+-	 * Alternative:
+-	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
+-	 * ???
+-	 */
+-	if (IS_ERR(fp))
+-		fp = NULL;
+-
+-	return fp;
+-}
+-
+-int dhd_os_get_image_block(char *buf, int len, void *image)
+-{
+-	struct file *fp = (struct file *)image;
+-	int rdlen;
+-
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_read_fw(buf, len);
+-
+-	if (!image)
+-		return 0;
+-
+-	rdlen = kernel_read(fp, fp->f_pos, buf, len);
+-	if (rdlen > 0)
+-		fp->f_pos += rdlen;
+-
+-	return rdlen;
+-}
+-
+-void dhd_os_close_image(void *image)
+-{
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_release_fw();
+-	if (image)
+-		filp_close((struct file *)image, NULL);
+-}
+-
+-void dhd_os_sdlock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd->threads_only)
+-		down(&dhd->sdsem);
+-	else
+-		spin_lock_bh(&dhd->sdlock);
+-}
+-
+-void dhd_os_sdunlock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd->threads_only)
+-		up(&dhd->sdsem);
+-	else
+-		spin_unlock_bh(&dhd->sdlock);
+-}
+-
+-void dhd_os_sdlock_txq(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-	spin_lock_bh(&dhd->txqlock);
+-}
+-
+-void dhd_os_sdunlock_txq(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-	spin_unlock_bh(&dhd->txqlock);
+-}
+-
+-void dhd_os_sdlock_rxq(dhd_pub_t *pub)
+-{
+-}
+-
+-void dhd_os_sdunlock_rxq(dhd_pub_t *pub)
+-{
+-}
+-
+-void dhd_os_sdtxlock(dhd_pub_t *pub)
+-{
+-	dhd_os_sdlock(pub);
+-}
+-
+-void dhd_os_sdtxunlock(dhd_pub_t *pub)
+-{
+-	dhd_os_sdunlock(pub);
+-}
+-
+-static int
+-dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+-		  wl_event_msg_t *event, void **data)
+-{
+-	int bcmerror = 0;
+-
+-	ASSERT(dhd != NULL);
+-
+-	bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data);
+-	if (bcmerror != 0)
+-		return bcmerror;
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-	if (!IS_CFG80211_FAVORITE()) {
+-		if ((dhd->iflist[*ifidx] == NULL)
+-		    || (dhd->iflist[*ifidx]->net == NULL)) {
+-			DHD_ERROR(("%s Exit null pointer\n", __func__));
+-			return bcmerror;
+-		}
+-
+-		if (dhd->iflist[*ifidx]->net)
+-			wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+-	}
+-#endif				/* defined(CONFIG_WIRELESS_EXT)  */
+-
+-	if (IS_CFG80211_FAVORITE()) {
+-		ASSERT(dhd->iflist[*ifidx] != NULL);
+-		ASSERT(dhd->iflist[*ifidx]->net != NULL);
+-		if (dhd->iflist[*ifidx]->net)
+-			wl_cfg80211_event(dhd->iflist[*ifidx]->net, event,
+-					  *data);
+-	}
+-
+-	return bcmerror;
+-}
+-
+-/* send up locally generated event */
+-void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
+-{
+-	switch (be32_to_cpu(event->event_type)) {
+-	default:
+-		break;
+-	}
+-}
+-
+-void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
+-{
+-	struct dhd_info *dhdinfo = dhd->info;
+-	dhd_os_sdunlock(dhd);
+-	wait_event_interruptible_timeout(dhdinfo->ctrl_wait,
+-					 (*lockvar == false), HZ * 2);
+-	dhd_os_sdlock(dhd);
+-	return;
+-}
+-
+-void dhd_wait_event_wakeup(dhd_pub_t *dhd)
+-{
+-	struct dhd_info *dhdinfo = dhd->info;
+-	if (waitqueue_active(&dhdinfo->ctrl_wait))
+-		wake_up_interruptible(&dhdinfo->ctrl_wait);
+-	return;
+-}
+-
+-int dhd_dev_reset(struct net_device *dev, u8 flag)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	/* Turning off watchdog */
+-	if (flag)
+-		dhd_os_wd_timer(&dhd->pub, 0);
+-
+-	dhd_bus_devreset(&dhd->pub, flag);
+-
+-	/* Turning on watchdog back */
+-	if (!flag)
+-		dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+-	DHD_ERROR(("%s:  WLAN OFF DONE\n", __func__));
+-
+-	return 1;
+-}
+-
+-int net_os_set_suspend_disable(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-	int ret = 0;
+-
+-	if (dhd) {
+-		ret = dhd->pub.suspend_disable_flag;
+-		dhd->pub.suspend_disable_flag = val;
+-	}
+-	return ret;
+-}
+-
+-int net_os_set_suspend(struct net_device *dev, int val)
+-{
+-	int ret = 0;
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	if (dhd) {
+-		dhd_os_proto_block(&dhd->pub);
+-		ret = dhd_set_suspend(val, &dhd->pub);
+-		dhd_os_proto_unblock(&dhd->pub);
+-	}
+-#endif		/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-	return ret;
+-}
+-
+-int net_os_set_dtim_skip(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-
+-	if (dhd)
+-		dhd->pub.dtim_skip = val;
+-
+-	return 0;
+-}
+-
+-int net_os_set_packet_filter(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	int ret = 0;
+-
+-	/* Packet filtering is set only if we still in early-suspend and
+-	 * we need either to turn it ON or turn it OFF
+-	 * We can always turn it OFF in case of early-suspend, but we turn it
+-	 * back ON only if suspend_disable_flag was not set
+-	 */
+-	if (dhd && dhd->pub.up) {
+-		dhd_os_proto_block(&dhd->pub);
+-		if (dhd->pub.in_suspend) {
+-			if (!val || (val && !dhd->pub.suspend_disable_flag))
+-				dhd_set_packet_filter(val, &dhd->pub);
+-		}
+-		dhd_os_proto_unblock(&dhd->pub);
+-	}
+-	return ret;
+-}
+-
+-void dhd_dev_init_ioctl(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	dhd_preinit_ioctls(&dhd->pub);
+-}
+-
+-#ifdef PNO_SUPPORT
+-/* Linux wrapper to call common dhd_pno_clean */
+-int dhd_dev_pno_reset(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_clean(&dhd->pub);
+-}
+-
+-/* Linux wrapper to call common dhd_pno_enable */
+-int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_enable(&dhd->pub, pfn_enabled);
+-}
+-
+-/* Linux wrapper to call common dhd_pno_set */
+-int
+-dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local, int nssid,
+-		unsigned char scan_fr)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr);
+-}
+-
+-/* Linux wrapper to get  pno status */
+-int dhd_dev_get_pno_status(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_get_status(&dhd->pub);
+-}
+-
+-#endif				/* PNO_SUPPORT */
+-
+-static int dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
+-{
+-	return atomic_read(&dhd->pend_8021x_cnt);
+-}
+-
+-#define MAX_WAIT_FOR_8021X_TX	10
+-
+-int dhd_wait_pend8021x(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-	int timeout = 10 * HZ / 1000;
+-	int ntimes = MAX_WAIT_FOR_8021X_TX;
+-	int pend = dhd_get_pend_8021x_cnt(dhd);
+-
+-	while (ntimes && pend) {
+-		if (pend) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(timeout);
+-			set_current_state(TASK_RUNNING);
+-			ntimes--;
+-		}
+-		pend = dhd_get_pend_8021x_cnt(dhd);
+-	}
+-	return pend;
+-}
+-
+-void wl_os_wd_timer(struct net_device *ndev, uint wdtick)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+-
+-	dhd_os_wd_timer(&dhd->pub, wdtick);
+-}
+-
+-#ifdef DHD_DEBUG
+-int write_to_file(dhd_pub_t *dhd, u8 *buf, int size)
+-{
+-	int ret = 0;
+-	struct file *fp;
+-	mm_segment_t old_fs;
+-	loff_t pos = 0;
+-
+-	/* change to KERNEL_DS address limit */
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-
+-	/* open file to write */
+-	fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
+-	if (!fp) {
+-		DHD_ERROR(("%s: open file error\n", __func__));
+-		ret = -1;
+-		goto exit;
+-	}
+-
+-	/* Write buf to file */
+-	fp->f_op->write(fp, buf, size, &pos);
+-
+-exit:
+-	/* free buf before return */
+-	kfree(buf);
+-	/* close file before return */
+-	if (fp)
+-		filp_close(fp, current->files);
+-	/* restore previous address limit */
+-	set_fs(old_fs);
+-
+-	return ret;
+-}
+-#endif				/* DHD_DEBUG */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
+deleted file mode 100644
+index c66f1c2..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-
+-int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
+-{
+-	int rc = 0;
+-	rc = sched_setscheduler(p, policy, param);
+-	return rc;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
+deleted file mode 100644
+index 030d5ff..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_proto_h_
+-#define _dhd_proto_h_
+-
+-#include <dhdioctl.h>
+-#include <wlioctl.h>
+-
+-#ifndef IOCTL_RESP_TIMEOUT
+-#define IOCTL_RESP_TIMEOUT  2000	/* In milli second */
+-#endif
+-
+-#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT
+-#define IOCTL_CHIP_ACTIVE_TIMEOUT  10	/* In milli second */
+-#endif
+-
+-/*
+- * Exported from the dhd protocol module (dhd_cdc, dhd_rndis)
+- */
+-
+-/* Linkage, sets prot link and updates hdrlen in pub */
+-extern int dhd_prot_attach(dhd_pub_t *dhdp);
+-
+-/* Unlink, frees allocated protocol memory (including dhd_prot) */
+-extern void dhd_prot_detach(dhd_pub_t *dhdp);
+-
+-/* Initialize protocol: sync w/dongle state.
+- * Sets dongle media info (iswl, drv_version, mac address).
+- */
+-extern int dhd_prot_init(dhd_pub_t *dhdp);
+-
+-/* Stop protocol: sync w/dongle state. */
+-extern void dhd_prot_stop(dhd_pub_t *dhdp);
+-
+-/* Add any protocol-specific data header.
+- * Caller must reserve prot_hdrlen prepend space.
+- */
+-extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, struct sk_buff *txp);
+-
+-/* Remove any protocol-specific data header. */
+-extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, struct sk_buff *rxp);
+-
+-/* Use protocol to issue ioctl to dongle */
+-extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc,
+-			  void *buf, int len);
+-
+-/* Check for and handle local prot-specific iovar commands */
+-extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+-			     void *params, int plen, void *arg, int len,
+-			     bool set);
+-
+-/* Add prot dump output to a buffer */
+-extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+-
+-/* Update local copy of dongle statistics */
+-extern void dhd_prot_dstats(dhd_pub_t *dhdp);
+-
+-extern int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf,
+-		     uint buflen);
+-
+-extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
+-
+-/********************************
+- * For version-string expansion *
+- */
+-#if defined(BDC)
+-#define DHD_PROTOCOL "bdc"
+-#elif defined(CDC)
+-#define DHD_PROTOCOL "cdc"
+-#elif defined(RNDIS)
+-#define DHD_PROTOCOL "rndis"
+-#else
+-#define DHD_PROTOCOL "unknown"
+-#endif				/* proto */
+-
+-#endif				/* _dhd_proto_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+deleted file mode 100644
+index a71c6f8..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
++++ /dev/null
+@@ -1,6390 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/printk.h>
+-#include <linux/pci_ids.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmsdh.h>
+-
+-#ifdef BCMEMBEDIMAGE
+-#include BCMEMBEDIMAGE
+-#endif				/* BCMEMBEDIMAGE */
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmdevs.h>
+-
+-#include <hndsoc.h>
+-#ifdef DHD_DEBUG
+-#include <hndrte_armtrap.h>
+-#include <hndrte_cons.h>
+-#endif				/* DHD_DEBUG */
+-#include <sbchipc.h>
+-#include <sbhnddma.h>
+-
+-#include <sdio.h>
+-#include <sbsdio.h>
+-#include <sbsdpcmdev.h>
+-#include <bcmsdpcm.h>
+-
+-#include <proto/802.11.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-#include <dhdioctl.h>
+-#include <sdiovar.h>
+-#include <bcmchip.h>
+-
+-#ifndef DHDSDIO_MEM_DUMP_FNAME
+-#define DHDSDIO_MEM_DUMP_FNAME         "mem_dump"
+-#endif
+-
+-#define TXQLEN		2048	/* bulk tx queue length */
+-#define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
+-#define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
+-#define PRIOMASK	7
+-
+-#define TXRETRIES	2	/* # of retries for tx frames */
+-
+-#if defined(CONFIG_MACH_SANDGATE2G)
+-#define DHD_RXBOUND	250	/* Default for max rx frames in
+-				 one scheduling */
+-#else
+-#define DHD_RXBOUND	50	/* Default for max rx frames in
+-				 one scheduling */
+-#endif				/* defined(CONFIG_MACH_SANDGATE2G) */
+-
+-#define DHD_TXBOUND	20	/* Default for max tx frames in
+-				 one scheduling */
+-
+-#define DHD_TXMINMAX	1	/* Max tx frames if rx still pending */
+-
+-#define MEMBLOCK	2048	/* Block size used for downloading
+-				 of dongle image */
+-#define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
+-				 biggest possible glom */
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#ifndef DHD_FIRSTREAD
+-#define DHD_FIRSTREAD	32
+-#endif
+-#if !ISPOWEROF2(DHD_FIRSTREAD)
+-#error DHD_FIRSTREAD is not a power of 2!
+-#endif
+-
+-/* Total length of frame header for dongle protocol */
+-#define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
+-#ifdef SDTEST
+-#define SDPCM_RESERVE	(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN)
+-#else
+-#define SDPCM_RESERVE	(SDPCM_HDRLEN + DHD_SDALIGN)
+-#endif
+-
+-/* Space for header read, limit for data packets */
+-#ifndef MAX_HDR_READ
+-#define MAX_HDR_READ	32
+-#endif
+-#if !ISPOWEROF2(MAX_HDR_READ)
+-#error MAX_HDR_READ is not a power of 2!
+-#endif
+-
+-#define MAX_RX_DATASZ	2048
+-
+-/* Maximum milliseconds to wait for F2 to come up */
+-#define DHD_WAIT_F2RDY	3000
+-
+-/* Bump up limit on waiting for HT to account for first startup;
+- * if the image is doing a CRC calculation before programming the PMU
+- * for HT availability, it could take a couple hundred ms more, so
+- * max out at a 1 second (1000000us).
+- */
+-#if (PMU_MAX_TRANSITION_DLY <= 1000000)
+-#undef PMU_MAX_TRANSITION_DLY
+-#define PMU_MAX_TRANSITION_DLY 1000000
+-#endif
+-
+-/* Value for ChipClockCSR during initial setup */
+-#define DHD_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
+-					SBSDIO_ALP_AVAIL_REQ)
+-#define DHD_INIT_CLKCTL2	(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP)
+-
+-/* Flags for SDH calls */
+-#define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
+-
+-/*
+- * Conversion of 802.1D priority to precedence level
+- */
+-#define PRIO2PREC(prio) \
+-	(((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \
+-	((prio^2)) : (prio))
+-
+-DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-
+-#ifdef DHD_DEBUG
+-/* Device console log buffer state */
+-typedef struct dhd_console {
+-	uint count;		/* Poll interval msec counter */
+-	uint log_addr;		/* Log struct address (fixed) */
+-	hndrte_log_t log;	/* Log struct (host copy) */
+-	uint bufsize;		/* Size of log buffer */
+-	u8 *buf;		/* Log buffer (host copy) */
+-	uint last;		/* Last buffer read index */
+-} dhd_console_t;
+-#endif				/* DHD_DEBUG */
+-
+-/* misc chip info needed by some of the routines */
+-struct chip_info {
+-	u32 chip;
+-	u32 chiprev;
+-	u32 cccorebase;
+-	u32 ccrev;
+-	u32 cccaps;
+-	u32 buscorebase;
+-	u32 buscorerev;
+-	u32 buscoretype;
+-	u32 ramcorebase;
+-	u32 armcorebase;
+-	u32 pmurev;
+-	u32 ramsize;
+-};
+-
+-/* Private data for SDIO bus interaction */
+-typedef struct dhd_bus {
+-	dhd_pub_t *dhd;
+-
+-	bcmsdh_info_t *sdh;	/* Handle for BCMSDH calls */
+-	struct chip_info *ci;	/* Chip info struct */
+-	char *vars;		/* Variables (from CIS and/or other) */
+-	uint varsz;		/* Size of variables buffer */
+-	u32 sbaddr;		/* Current SB window pointer (-1, invalid) */
+-
+-	sdpcmd_regs_t *regs;	/* Registers for SDIO core */
+-	uint sdpcmrev;		/* SDIO core revision */
+-	uint armrev;		/* CPU core revision */
+-	uint ramrev;		/* SOCRAM core revision */
+-	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
+-	u32 orig_ramsize;	/* Size of RAM in SOCRAM (bytes) */
+-
+-	u32 bus;		/* gSPI or SDIO bus */
+-	u32 hostintmask;	/* Copy of Host Interrupt Mask */
+-	u32 intstatus;	/* Intstatus bits (events) pending */
+-	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
+-	bool fcstate;		/* State of dongle flow-control */
+-
+-	u16 cl_devid;	/* cached devid for dhdsdio_probe_attach() */
+-	char *fw_path;		/* module_param: path to firmware image */
+-	char *nv_path;		/* module_param: path to nvram vars file */
+-	const char *nvram_params;	/* user specified nvram params. */
+-
+-	uint blocksize;		/* Block size of SDIO transfers */
+-	uint roundup;		/* Max roundup limit */
+-
+-	struct pktq txq;	/* Queue length used for flow-control */
+-	u8 flowcontrol;	/* per prio flow control bitmask */
+-	u8 tx_seq;		/* Transmit sequence number (next) */
+-	u8 tx_max;		/* Maximum transmit sequence allowed */
+-
+-	u8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN];
+-	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
+-	u16 nextlen;		/* Next Read Len from last header */
+-	u8 rx_seq;		/* Receive sequence number (expected) */
+-	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
+-
+-	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
+-	struct sk_buff *glom;	/* Packet chain for glommed superframe */
+-	uint glomerr;		/* Glom packet read errors */
+-
+-	u8 *rxbuf;		/* Buffer for receiving control packets */
+-	uint rxblen;		/* Allocated length of rxbuf */
+-	u8 *rxctl;		/* Aligned pointer into rxbuf */
+-	u8 *databuf;		/* Buffer for receiving big glom packet */
+-	u8 *dataptr;		/* Aligned pointer into databuf */
+-	uint rxlen;		/* Length of valid data in buffer */
+-
+-	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
+-
+-	bool intr;		/* Use interrupts */
+-	bool poll;		/* Use polling */
+-	bool ipend;		/* Device interrupt is pending */
+-	bool intdis;		/* Interrupts disabled by isr */
+-	uint intrcount;		/* Count of device interrupt callbacks */
+-	uint lastintrs;		/* Count as of last watchdog timer */
+-	uint spurious;		/* Count of spurious interrupts */
+-	uint pollrate;		/* Ticks between device polls */
+-	uint polltick;		/* Tick counter */
+-	uint pollcnt;		/* Count of active polls */
+-
+-#ifdef DHD_DEBUG
+-	dhd_console_t console;	/* Console output polling support */
+-	uint console_addr;	/* Console address from shared struct */
+-#endif				/* DHD_DEBUG */
+-
+-	uint regfails;		/* Count of R_REG/W_REG failures */
+-
+-	uint clkstate;		/* State of sd and backplane clock(s) */
+-	bool activity;		/* Activity flag for clock down */
+-	s32 idletime;		/* Control for activity timeout */
+-	s32 idlecount;	/* Activity timeout counter */
+-	s32 idleclock;	/* How to set bus driver when idle */
+-	s32 sd_divisor;	/* Speed control to bus driver */
+-	s32 sd_mode;		/* Mode control to bus driver */
+-	s32 sd_rxchain;	/* If bcmsdh api accepts PKT chains */
+-	bool use_rxchain;	/* If dhd should use PKT chains */
+-	bool sleeping;		/* Is SDIO bus sleeping? */
+-	bool rxflow_mode;	/* Rx flow control mode */
+-	bool rxflow;		/* Is rx flow control on */
+-	uint prev_rxlim_hit;	/* Is prev rx limit exceeded
+-					 (per dpc schedule) */
+-	bool alp_only;		/* Don't use HT clock (ALP only) */
+-/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
+-	bool usebufpool;
+-
+-#ifdef SDTEST
+-	/* external loopback */
+-	bool ext_loop;
+-	u8 loopid;
+-
+-	/* pktgen configuration */
+-	uint pktgen_freq;	/* Ticks between bursts */
+-	uint pktgen_count;	/* Packets to send each burst */
+-	uint pktgen_print;	/* Bursts between count displays */
+-	uint pktgen_total;	/* Stop after this many */
+-	uint pktgen_minlen;	/* Minimum packet data len */
+-	uint pktgen_maxlen;	/* Maximum packet data len */
+-	uint pktgen_mode;	/* Configured mode: tx, rx, or echo */
+-	uint pktgen_stop;	/* Number of tx failures causing stop */
+-
+-	/* active pktgen fields */
+-	uint pktgen_tick;	/* Tick counter for bursts */
+-	uint pktgen_ptick;	/* Burst counter for printing */
+-	uint pktgen_sent;	/* Number of test packets generated */
+-	uint pktgen_rcvd;	/* Number of test packets received */
+-	uint pktgen_fail;	/* Number of failed send attempts */
+-	u16 pktgen_len;	/* Length of next packet to send */
+-#endif				/* SDTEST */
+-
+-	/* Some additional counters */
+-	uint tx_sderrs;		/* Count of tx attempts with sd errors */
+-	uint fcqueued;		/* Tx packets that got queued */
+-	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
+-	uint rx_toolong;	/* Receive frames too long to receive */
+-	uint rxc_errors;	/* SDIO errors when reading control frames */
+-	uint rx_hdrfail;	/* SDIO errors on header reads */
+-	uint rx_badhdr;		/* Bad received headers (roosync?) */
+-	uint rx_badseq;		/* Mismatched rx sequence number */
+-	uint fc_rcvd;		/* Number of flow-control events received */
+-	uint fc_xoff;		/* Number which turned on flow-control */
+-	uint fc_xon;		/* Number which turned off flow-control */
+-	uint rxglomfail;	/* Failed deglom attempts */
+-	uint rxglomframes;	/* Number of glom frames (superframes) */
+-	uint rxglompkts;	/* Number of packets from glom frames */
+-	uint f2rxhdrs;		/* Number of header reads */
+-	uint f2rxdata;		/* Number of frame data reads */
+-	uint f2txdata;		/* Number of f2 frame writes */
+-	uint f1regdata;		/* Number of f1 register accesses */
+-
+-	u8 *ctrl_frame_buf;
+-	u32 ctrl_frame_len;
+-	bool ctrl_frame_stat;
+-} dhd_bus_t;
+-
+-/* clkstate */
+-#define CLK_NONE	0
+-#define CLK_SDONLY	1
+-#define CLK_PENDING	2	/* Not used yet */
+-#define CLK_AVAIL	3
+-
+-#define DHD_NOPMU(dhd)	(false)
+-
+-#ifdef DHD_DEBUG
+-static int qcount[NUMPRIO];
+-static int tx_packets[NUMPRIO];
+-#endif				/* DHD_DEBUG */
+-
+-/* Deferred transmit */
+-const uint dhd_deferred_tx = 1;
+-
+-extern uint dhd_watchdog_ms;
+-extern void dhd_os_wd_timer(void *bus, uint wdtick);
+-
+-/* Tx/Rx bounds */
+-uint dhd_txbound;
+-uint dhd_rxbound;
+-uint dhd_txminmax;
+-
+-/* override the RAM size if possible */
+-#define DONGLE_MIN_MEMSIZE (128 * 1024)
+-int dhd_dongle_memsize;
+-
+-static bool dhd_alignctl;
+-
+-static bool sd1idle;
+-
+-static bool retrydata;
+-#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata)
+-
+-static const uint watermark = 8;
+-static const uint firstread = DHD_FIRSTREAD;
+-
+-#define HDATLEN (firstread - (SDPCM_HDRLEN))
+-
+-/* Retry count for register access failures */
+-static const uint retry_limit = 2;
+-
+-/* Force even SD lengths (some host controllers mess up on odd bytes) */
+-static bool forcealign;
+-
+-#define ALIGNMENT  4
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable);
+-#endif
+-
+-#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD)
+-#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD
+-#endif	/* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */
+-#define PKTALIGN(_p, _len, _align)				\
+-	do {								\
+-		uint datalign;						\
+-		datalign = (unsigned long)((_p)->data);			\
+-		datalign = roundup(datalign, (_align)) - datalign;	\
+-		ASSERT(datalign < (_align));				\
+-		ASSERT((_p)->len >= ((_len) + datalign));		\
+-		if (datalign)						\
+-			skb_pull((_p), datalign);			\
+-		__skb_trim((_p), (_len));				\
+-	} while (0)
+-
+-/* Limit on rounding up frames */
+-static const uint max_roundup = 512;
+-
+-/* Try doing readahead */
+-static bool dhd_readahead;
+-
+-/* To check if there's window offered */
+-#define DATAOK(bus) \
+-	(((u8)(bus->tx_max - bus->tx_seq) != 0) && \
+-	(((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
+-
+-/* Macros to get register read/write status */
+-/* NOTE: these assume a local dhdsdio_bus_t *bus! */
+-#define R_SDREG(regvar, regaddr, retryvar) \
+-do { \
+-	retryvar = 0; \
+-	do { \
+-		regvar = R_REG(regaddr); \
+-	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+-	if (retryvar) { \
+-		bus->regfails += (retryvar-1); \
+-		if (retryvar > retry_limit) { \
+-			DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \
+-			__func__, __LINE__)); \
+-			regvar = 0; \
+-		} \
+-	} \
+-} while (0)
+-
+-#define W_SDREG(regval, regaddr, retryvar) \
+-do { \
+-	retryvar = 0; \
+-	do { \
+-		W_REG(regaddr, regval); \
+-	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+-	if (retryvar) { \
+-		bus->regfails += (retryvar-1); \
+-		if (retryvar > retry_limit) \
+-			DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \
+-			__func__, __LINE__)); \
+-	} \
+-} while (0)
+-
+-#define DHD_BUS			SDIO_BUS
+-
+-#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
+-
+-#define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
+-
+-#ifdef SDTEST
+-static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
+-static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
+-#endif
+-
+-#ifdef DHD_DEBUG
+-static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size);
+-static int dhdsdio_mem_dump(dhd_bus_t *bus);
+-#endif				/* DHD_DEBUG  */
+-static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
+-
+-static void dhdsdio_release(dhd_bus_t *bus);
+-static void dhdsdio_release_malloc(dhd_bus_t *bus);
+-static void dhdsdio_disconnect(void *ptr);
+-static bool dhdsdio_chipmatch(u16 chipid);
+-static bool dhdsdio_probe_attach(dhd_bus_t *bus, void *sdh,
+-				 void *regsva, u16 devid);
+-static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh);
+-static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh);
+-static void dhdsdio_release_dongle(dhd_bus_t *bus);
+-
+-static uint process_nvram_vars(char *varbuf, uint len);
+-
+-static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size);
+-static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn,
+-			       uint flags, u8 *buf, uint nbytes,
+-			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
+-			       void *handle);
+-
+-static bool dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh);
+-static int _dhdsdio_download_firmware(struct dhd_bus *bus);
+-
+-static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path);
+-static int dhdsdio_download_nvram(struct dhd_bus *bus);
+-#ifdef BCMEMBEDIMAGE
+-static int dhdsdio_download_code_array(struct dhd_bus *bus);
+-#endif
+-static void dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase);
+-static int dhdsdio_chip_attach(struct dhd_bus *bus, void *regs);
+-static void dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase);
+-static void dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus,
+-					u32 drivestrength);
+-static void dhdsdio_chip_detach(struct dhd_bus *bus);
+-
+-/* Packet free applicable unconditionally for sdio and sdspi.
+- * Conditional if bufpool was present for gspi bus.
+- */
+-static void dhdsdio_pktfree2(dhd_bus_t *bus, struct sk_buff *pkt)
+-{
+-	dhd_os_sdlock_rxq(bus->dhd);
+-	if ((bus->bus != SPI_BUS) || bus->usebufpool)
+-		bcm_pkt_buf_free_skb(pkt);
+-	dhd_os_sdunlock_rxq(bus->dhd);
+-}
+-
+-static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size)
+-{
+-	s32 min_size = DONGLE_MIN_MEMSIZE;
+-	/* Restrict the memsize to user specified limit */
+-	DHD_ERROR(("user: Restrict the dongle ram size to %d, min %d\n",
+-		dhd_dongle_memsize, min_size));
+-	if ((dhd_dongle_memsize > min_size) &&
+-	    (dhd_dongle_memsize < (s32) bus->orig_ramsize))
+-		bus->ramsize = dhd_dongle_memsize;
+-}
+-
+-static int dhdsdio_set_siaddr_window(dhd_bus_t *bus, u32 address)
+-{
+-	int err = 0;
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+-			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+-				 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+-				 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
+-				 &err);
+-	return err;
+-}
+-
+-/* Turn backplane clock on or off */
+-static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
+-{
+-	int err;
+-	u8 clkctl, clkreq, devctl;
+-	bcmsdh_info_t *sdh;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#if defined(OOB_INTR_ONLY)
+-	pendok = false;
+-#endif
+-	clkctl = 0;
+-	sdh = bus->sdh;
+-
+-	if (on) {
+-		/* Request HT Avail */
+-		clkreq =
+-		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
+-
+-		if ((bus->ci->chip == BCM4329_CHIP_ID)
+-		    && (bus->ci->chiprev == 0))
+-			clkreq |= SBSDIO_FORCE_ALP;
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 clkreq, &err);
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail request error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-
+-		if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+-			       && (bus->ci->buscorerev == 9))) {
+-			u32 dummy, retries;
+-			R_SDREG(dummy, &bus->regs->clockctlstatus, retries);
+-		}
+-
+-		/* Check current status */
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail read error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-
+-		/* Go to pending and await interrupt if appropriate */
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
+-			/* Allow only clock-available interrupt */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			if (err) {
+-				DHD_ERROR(("%s: Devctl error setting CA: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-
+-			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-			DHD_INFO(("CLKCTL: set PENDING\n"));
+-			bus->clkstate = CLK_PENDING;
+-
+-			return 0;
+-		} else if (bus->clkstate == CLK_PENDING) {
+-			/* Cancel CA-only interrupt filter */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-		}
+-
+-		/* Otherwise, wait here (polling) for HT Avail */
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+-			SPINWAIT_SLEEP(sdioh_spinwait_sleep,
+-				       ((clkctl =
+-					 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						 SBSDIO_FUNC1_CHIPCLKCSR,
+-							 &err)),
+-					!SBSDIO_CLKAV(clkctl, bus->alp_only)),
+-				       PMU_MAX_TRANSITION_DLY);
+-		}
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail request error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+-			DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n",
+-				   __func__, PMU_MAX_TRANSITION_DLY, clkctl));
+-			return -EBADE;
+-		}
+-
+-		/* Mark clock available */
+-		bus->clkstate = CLK_AVAIL;
+-		DHD_INFO(("CLKCTL: turned ON\n"));
+-
+-#if defined(DHD_DEBUG)
+-		if (bus->alp_only == true) {
+-#if !defined(BCMLXSDMMC)
+-			if (!SBSDIO_ALPONLY(clkctl)) {
+-				DHD_ERROR(("%s: HT Clock, when ALP Only\n",
+-					   __func__));
+-			}
+-#endif				/* !defined(BCMLXSDMMC) */
+-		} else {
+-			if (SBSDIO_ALPONLY(clkctl)) {
+-				DHD_ERROR(("%s: HT Clock should be on.\n",
+-					   __func__));
+-			}
+-		}
+-#endif				/* defined (DHD_DEBUG) */
+-
+-		bus->activity = true;
+-	} else {
+-		clkreq = 0;
+-
+-		if (bus->clkstate == CLK_PENDING) {
+-			/* Cancel CA-only interrupt filter */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-		}
+-
+-		bus->clkstate = CLK_SDONLY;
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 clkreq, &err);
+-		DHD_INFO(("CLKCTL: turned OFF\n"));
+-		if (err) {
+-			DHD_ERROR(("%s: Failed access turning clock off: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/* Change idle/active SD state */
+-static int dhdsdio_sdclk(dhd_bus_t *bus, bool on)
+-{
+-	int err;
+-	s32 iovalue;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (on) {
+-		if (bus->idleclock == DHD_IDLE_STOP) {
+-			/* Turn on clock and restore mode */
+-			iovalue = 1;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error enabling sd_clock: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-
+-			iovalue = bus->sd_mode;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error changing sd_mode: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+-			/* Restore clock speed */
+-			iovalue = bus->sd_divisor;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error restoring sd_divisor: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-		}
+-		bus->clkstate = CLK_SDONLY;
+-	} else {
+-		/* Stop or slow the SD clock itself */
+-		if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) {
+-			DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n",
+-				   __func__, bus->sd_divisor, bus->sd_mode));
+-			return -EBADE;
+-		}
+-		if (bus->idleclock == DHD_IDLE_STOP) {
+-			if (sd1idle) {
+-				/* Change to SD1 mode and turn off clock */
+-				iovalue = 1;
+-				err =
+-				    bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL,
+-						    0, &iovalue,
+-						    sizeof(iovalue), true);
+-				if (err) {
+-					DHD_ERROR(("%s: error changing sd_clock: %d\n",
+-						__func__, err));
+-					return -EBADE;
+-				}
+-			}
+-
+-			iovalue = 0;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error disabling sd_clock: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+-			/* Set divisor to idle value */
+-			iovalue = bus->idleclock;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error changing sd_divisor: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-		}
+-		bus->clkstate = CLK_NONE;
+-	}
+-
+-	return 0;
+-}
+-
+-/* Transition SD and backplane clock readiness */
+-static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
+-{
+-#ifdef DHD_DEBUG
+-	uint oldstate = bus->clkstate;
+-#endif				/* DHD_DEBUG */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Early exit if we're already there */
+-	if (bus->clkstate == target) {
+-		if (target == CLK_AVAIL) {
+-			dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-			bus->activity = true;
+-		}
+-		return 0;
+-	}
+-
+-	switch (target) {
+-	case CLK_AVAIL:
+-		/* Make sure SD clock is available */
+-		if (bus->clkstate == CLK_NONE)
+-			dhdsdio_sdclk(bus, true);
+-		/* Now request HT Avail on the backplane */
+-		dhdsdio_htclk(bus, true, pendok);
+-		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-		bus->activity = true;
+-		break;
+-
+-	case CLK_SDONLY:
+-		/* Remove HT request, or bring up SD clock */
+-		if (bus->clkstate == CLK_NONE)
+-			dhdsdio_sdclk(bus, true);
+-		else if (bus->clkstate == CLK_AVAIL)
+-			dhdsdio_htclk(bus, false, false);
+-		else
+-			DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
+-				   bus->clkstate, target));
+-		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-		break;
+-
+-	case CLK_NONE:
+-		/* Make sure to remove HT request */
+-		if (bus->clkstate == CLK_AVAIL)
+-			dhdsdio_htclk(bus, false, false);
+-		/* Now remove the SD clock */
+-		dhdsdio_sdclk(bus, false);
+-		dhd_os_wd_timer(bus->dhd, 0);
+-		break;
+-	}
+-#ifdef DHD_DEBUG
+-	DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
+-#endif				/* DHD_DEBUG */
+-
+-	return 0;
+-}
+-
+-int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-
+-	DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n",
+-		  (sleep ? "SLEEP" : "WAKE"),
+-		  (bus->sleeping ? "SLEEP" : "WAKE")));
+-
+-	/* Done if we're already in the requested state */
+-	if (sleep == bus->sleeping)
+-		return 0;
+-
+-	/* Going to sleep: set the alarm and turn off the lights... */
+-	if (sleep) {
+-		/* Don't sleep if something is pending */
+-		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
+-			return -EBUSY;
+-
+-		/* Disable SDIO interrupts (no longer interested) */
+-		bcmsdh_intr_disable(bus->sdh);
+-
+-		/* Make sure the controller has the bus up */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		/* Tell device to start using OOB wakeup */
+-		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
+-
+-		/* Turn off our contribution to the HT clock request */
+-		dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
+-
+-		/* Isolate the bus */
+-		if (bus->ci->chip != BCM4329_CHIP_ID
+-		    && bus->ci->chip != BCM4319_CHIP_ID) {
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 SBSDIO_DEVCTL_PADS_ISO, NULL);
+-		}
+-
+-		/* Change state */
+-		bus->sleeping = true;
+-
+-	} else {
+-		/* Waking up: bus power up is ok, set local state */
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 0, NULL);
+-
+-		/* Force pad isolation off if possible
+-			 (in case power never toggled) */
+-		if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+-		    && (bus->ci->buscorerev >= 10))
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0,
+-					 NULL);
+-
+-		/* Make sure the controller has the bus up */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		/* Send misc interrupt to indicate OOB not needed */
+-		W_SDREG(0, &regs->tosbmailboxdata, retries);
+-		if (retries <= retry_limit)
+-			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+-
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"));
+-
+-		/* Make sure we have SD bus access */
+-		dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-		/* Change state */
+-		bus->sleeping = false;
+-
+-		/* Enable interrupts again */
+-		if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) {
+-			bus->intdis = false;
+-			bcmsdh_intr_enable(bus->sdh);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-#if defined(OOB_INTR_ONLY)
+-void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable)
+-{
+-#if defined(HW_OOB)
+-	bcmsdh_enable_hw_oob_intr(bus->sdh, enable);
+-#else
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	if (enable == true) {
+-
+-		/* Tell device to start using OOB wakeup */
+-		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
+-
+-	} else {
+-		/* Send misc interrupt to indicate OOB not needed */
+-		W_SDREG(0, &regs->tosbmailboxdata, retries);
+-		if (retries <= retry_limit)
+-			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+-	}
+-
+-	/* Turn off our contribution to the HT clock request */
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-#endif				/* !defined(HW_OOB) */
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-#define BUS_WAKE(bus) \
+-	do { \
+-		if ((bus)->sleeping) \
+-			dhdsdio_bussleep((bus), false); \
+-	} while (0);
+-
+-/* Writes a HW/SW header into the packet and sends it. */
+-/* Assumes: (a) header space already there, (b) caller holds lock */
+-static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan,
+-			 bool free_pkt)
+-{
+-	int ret;
+-	u8 *frame;
+-	u16 len, pad = 0;
+-	u32 swheader;
+-	uint retries = 0;
+-	bcmsdh_info_t *sdh;
+-	struct sk_buff *new;
+-	int i;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	sdh = bus->sdh;
+-
+-	if (bus->dhd->dongle_reset) {
+-		ret = -EPERM;
+-		goto done;
+-	}
+-
+-	frame = (u8 *) (pkt->data);
+-
+-	/* Add alignment padding, allocate new packet if needed */
+-	pad = ((unsigned long)frame % DHD_SDALIGN);
+-	if (pad) {
+-		if (skb_headroom(pkt) < pad) {
+-			DHD_INFO(("%s: insufficient headroom %d for %d pad\n",
+-				  __func__, skb_headroom(pkt), pad));
+-			bus->dhd->tx_realloc++;
+-			new = bcm_pkt_buf_get_skb(pkt->len + DHD_SDALIGN);
+-			if (!new) {
+-				DHD_ERROR(("%s: couldn't allocate new %d-byte "
+-					"packet\n",
+-					__func__, pkt->len + DHD_SDALIGN));
+-				ret = -ENOMEM;
+-				goto done;
+-			}
+-
+-			PKTALIGN(new, pkt->len, DHD_SDALIGN);
+-			memcpy(new->data, pkt->data, pkt->len);
+-			if (free_pkt)
+-				bcm_pkt_buf_free_skb(pkt);
+-			/* free the pkt if canned one is not used */
+-			free_pkt = true;
+-			pkt = new;
+-			frame = (u8 *) (pkt->data);
+-			ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0);
+-			pad = 0;
+-		} else {
+-			skb_push(pkt, pad);
+-			frame = (u8 *) (pkt->data);
+-
+-			ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len));
+-			memset(frame, 0, pad + SDPCM_HDRLEN);
+-		}
+-	}
+-	ASSERT(pad < DHD_SDALIGN);
+-
+-	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+-	len = (u16) (pkt->len);
+-	*(u16 *) frame = cpu_to_le16(len);
+-	*(((u16 *) frame) + 1) = cpu_to_le16(~len);
+-
+-	/* Software tag: channel, sequence number, data offset */
+-	swheader =
+-	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
+-	    (((pad +
+-	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+-
+-	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
+-	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+-
+-#ifdef DHD_DEBUG
+-	tx_packets[pkt->priority]++;
+-	if (DHD_BYTES_ON() &&
+-	    (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
+-	      (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
+-		printk(KERN_DEBUG "Tx Frame:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
+-	} else if (DHD_HDRS_ON()) {
+-		printk(KERN_DEBUG "TxHdr:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-				     frame, min_t(u16, len, 16));
+-	}
+-#endif
+-
+-	/* Raise len to next SDIO block to eliminate tail command */
+-	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+-		u16 pad = bus->blocksize - (len % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize))
+-#ifdef NOTUSED
+-			if (pad <= skb_tailroom(pkt))
+-#endif				/* NOTUSED */
+-				len += pad;
+-	} else if (len % DHD_SDALIGN) {
+-		len += DHD_SDALIGN - (len % DHD_SDALIGN);
+-	}
+-
+-	/* Some controllers have trouble with odd bytes -- round to even */
+-	if (forcealign && (len & (ALIGNMENT - 1))) {
+-#ifdef NOTUSED
+-		if (skb_tailroom(pkt))
+-#endif
+-			len = roundup(len, ALIGNMENT);
+-#ifdef NOTUSED
+-		else
+-			DHD_ERROR(("%s: sending unrounded %d-byte packet\n",
+-				   __func__, len));
+-#endif
+-	}
+-
+-	do {
+-		ret =
+-		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, frame, len, pkt, NULL, NULL);
+-		bus->f2txdata++;
+-		ASSERT(ret != -BCME_PENDING);
+-
+-		if (ret < 0) {
+-			/* On failure, abort the command
+-			 and terminate the frame */
+-			DHD_INFO(("%s: sdio error %d, abort command and "
+-				"terminate frame.\n", __func__, ret));
+-			bus->tx_sderrs++;
+-
+-			bcmsdh_abort(sdh, SDIO_FUNC_2);
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
+-					 NULL);
+-			bus->f1regdata++;
+-
+-			for (i = 0; i < 3; i++) {
+-				u8 hi, lo;
+-				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCHI,
+-						     NULL);
+-				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCLO,
+-						     NULL);
+-				bus->f1regdata += 2;
+-				if ((hi == 0) && (lo == 0))
+-					break;
+-			}
+-
+-		}
+-		if (ret == 0)
+-			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-
+-	} while ((ret < 0) && retrydata && retries++ < TXRETRIES);
+-
+-done:
+-	/* restore pkt buffer pointer before calling tx complete routine */
+-	skb_pull(pkt, SDPCM_HDRLEN + pad);
+-	dhd_os_sdunlock(bus->dhd);
+-	dhd_txcomplete(bus->dhd, pkt, ret != 0);
+-	dhd_os_sdlock(bus->dhd);
+-
+-	if (free_pkt)
+-		bcm_pkt_buf_free_skb(pkt);
+-
+-	return ret;
+-}
+-
+-int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt)
+-{
+-	int ret = -EBADE;
+-	uint datalen, prec;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	datalen = pkt->len;
+-
+-#ifdef SDTEST
+-	/* Push the test header if doing loopback */
+-	if (bus->ext_loop) {
+-		u8 *data;
+-		skb_push(pkt, SDPCM_TEST_HDRLEN);
+-		data = pkt->data;
+-		*data++ = SDPCM_TEST_ECHOREQ;
+-		*data++ = (u8) bus->loopid++;
+-		*data++ = (datalen >> 0);
+-		*data++ = (datalen >> 8);
+-		datalen += SDPCM_TEST_HDRLEN;
+-	}
+-#endif				/* SDTEST */
+-
+-	/* Add space for the header */
+-	skb_push(pkt, SDPCM_HDRLEN);
+-	ASSERT(IS_ALIGNED((unsigned long)(pkt->data), 2));
+-
+-	prec = PRIO2PREC((pkt->priority & PRIOMASK));
+-
+-	/* Check for existing queue, current flow-control,
+-			 pending event, or pending clock */
+-	if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq)
+-	    || bus->dpc_sched || (!DATAOK(bus))
+-	    || (bus->flowcontrol & NBITVAL(prec))
+-	    || (bus->clkstate != CLK_AVAIL)) {
+-		DHD_TRACE(("%s: deferring pktq len %d\n", __func__,
+-			   pktq_len(&bus->txq)));
+-		bus->fcqueued++;
+-
+-		/* Priority based enq */
+-		dhd_os_sdlock_txq(bus->dhd);
+-		if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) {
+-			skb_pull(pkt, SDPCM_HDRLEN);
+-			dhd_txcomplete(bus->dhd, pkt, false);
+-			bcm_pkt_buf_free_skb(pkt);
+-			DHD_ERROR(("%s: out of bus->txq !!!\n", __func__));
+-			ret = -ENOSR;
+-		} else {
+-			ret = 0;
+-		}
+-		dhd_os_sdunlock_txq(bus->dhd);
+-
+-		if (pktq_len(&bus->txq) >= TXHI)
+-			dhd_txflowcontrol(bus->dhd, 0, ON);
+-
+-#ifdef DHD_DEBUG
+-		if (pktq_plen(&bus->txq, prec) > qcount[prec])
+-			qcount[prec] = pktq_plen(&bus->txq, prec);
+-#endif
+-		/* Schedule DPC if needed to send queued packet(s) */
+-		if (dhd_deferred_tx && !bus->dpc_sched) {
+-			bus->dpc_sched = true;
+-			dhd_sched_dpc(bus->dhd);
+-		}
+-	} else {
+-		/* Lock: we're about to use shared data/code (and SDIO) */
+-		dhd_os_sdlock(bus->dhd);
+-
+-		/* Otherwise, send it now */
+-		BUS_WAKE(bus);
+-		/* Make sure back plane ht clk is on, no pending allowed */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, true);
+-
+-#ifndef SDTEST
+-		DHD_TRACE(("%s: calling txpkt\n", __func__));
+-		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
+-#else
+-		ret = dhdsdio_txpkt(bus, pkt,
+-				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
+-				     SDPCM_DATA_CHANNEL), true);
+-#endif
+-		if (ret)
+-			bus->dhd->tx_errors++;
+-		else
+-			bus->dhd->dstats.tx_bytes += datalen;
+-
+-		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-			bus->activity = false;
+-			dhdsdio_clkctl(bus, CLK_NONE, true);
+-		}
+-
+-		dhd_os_sdunlock(bus->dhd);
+-	}
+-
+-	return ret;
+-}
+-
+-static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
+-{
+-	struct sk_buff *pkt;
+-	u32 intstatus = 0;
+-	uint retries = 0;
+-	int ret = 0, prec_out;
+-	uint cnt = 0;
+-	uint datalen;
+-	u8 tx_prec_map;
+-
+-	dhd_pub_t *dhd = bus->dhd;
+-	sdpcmd_regs_t *regs = bus->regs;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	tx_prec_map = ~bus->flowcontrol;
+-
+-	/* Send frames until the limit or some other event */
+-	for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
+-		dhd_os_sdlock_txq(bus->dhd);
+-		pkt = bcm_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
+-		if (pkt == NULL) {
+-			dhd_os_sdunlock_txq(bus->dhd);
+-			break;
+-		}
+-		dhd_os_sdunlock_txq(bus->dhd);
+-		datalen = pkt->len - SDPCM_HDRLEN;
+-
+-#ifndef SDTEST
+-		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
+-#else
+-		ret = dhdsdio_txpkt(bus, pkt,
+-				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
+-				     SDPCM_DATA_CHANNEL), true);
+-#endif
+-		if (ret)
+-			bus->dhd->tx_errors++;
+-		else
+-			bus->dhd->dstats.tx_bytes += datalen;
+-
+-		/* In poll mode, need to check for other events */
+-		if (!bus->intr && cnt) {
+-			/* Check device status, signal pending interrupt */
+-			R_SDREG(intstatus, &regs->intstatus, retries);
+-			bus->f2txdata++;
+-			if (bcmsdh_regfail(bus->sdh))
+-				break;
+-			if (intstatus & bus->hostintmask)
+-				bus->ipend = true;
+-		}
+-	}
+-
+-	/* Deflow-control stack if needed */
+-	if (dhd->up && (dhd->busstate == DHD_BUS_DATA) &&
+-	    dhd->txoff && (pktq_len(&bus->txq) < TXLOW))
+-		dhd_txflowcontrol(dhd, 0, OFF);
+-
+-	return cnt;
+-}
+-
+-int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
+-{
+-	u8 *frame;
+-	u16 len;
+-	u32 swheader;
+-	uint retries = 0;
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	u8 doff = 0;
+-	int ret = -1;
+-	int i;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->dongle_reset)
+-		return -EIO;
+-
+-	/* Back the pointer to make a room for bus header */
+-	frame = msg - SDPCM_HDRLEN;
+-	len = (msglen += SDPCM_HDRLEN);
+-
+-	/* Add alignment padding (optional for ctl frames) */
+-	if (dhd_alignctl) {
+-		doff = ((unsigned long)frame % DHD_SDALIGN);
+-		if (doff) {
+-			frame -= doff;
+-			len += doff;
+-			msglen += doff;
+-			memset(frame, 0, doff + SDPCM_HDRLEN);
+-		}
+-		ASSERT(doff < DHD_SDALIGN);
+-	}
+-	doff += SDPCM_HDRLEN;
+-
+-	/* Round send length to next SDIO block */
+-	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+-		u16 pad = bus->blocksize - (len % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize))
+-			len += pad;
+-	} else if (len % DHD_SDALIGN) {
+-		len += DHD_SDALIGN - (len % DHD_SDALIGN);
+-	}
+-
+-	/* Satisfy length-alignment requirements */
+-	if (forcealign && (len & (ALIGNMENT - 1)))
+-		len = roundup(len, ALIGNMENT);
+-
+-	ASSERT(IS_ALIGNED((unsigned long)frame, 2));
+-
+-	/* Need to lock here to protect txseq and SDIO tx calls */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	BUS_WAKE(bus);
+-
+-	/* Make sure backplane clock is on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+-	*(u16 *) frame = cpu_to_le16((u16) msglen);
+-	*(((u16 *) frame) + 1) = cpu_to_le16(~msglen);
+-
+-	/* Software tag: channel, sequence number, data offset */
+-	swheader =
+-	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
+-	     SDPCM_CHANNEL_MASK)
+-	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
+-			     SDPCM_DOFFSET_MASK);
+-	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
+-	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+-
+-	if (!DATAOK(bus)) {
+-		DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n",
+-			  __func__, bus->tx_max, bus->tx_seq));
+-		bus->ctrl_frame_stat = true;
+-		/* Send from dpc */
+-		bus->ctrl_frame_buf = frame;
+-		bus->ctrl_frame_len = len;
+-
+-		dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+-
+-		if (bus->ctrl_frame_stat == false) {
+-			DHD_INFO(("%s: ctrl_frame_stat == false\n", __func__));
+-			ret = 0;
+-		} else {
+-			DHD_INFO(("%s: ctrl_frame_stat == true\n", __func__));
+-			ret = -1;
+-		}
+-	}
+-
+-	if (ret == -1) {
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+-			printk(KERN_DEBUG "Tx Frame:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     frame, len);
+-		} else if (DHD_HDRS_ON()) {
+-			printk(KERN_DEBUG "TxHdr:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     frame, min_t(u16, len, 16));
+-		}
+-#endif
+-
+-		do {
+-			bus->ctrl_frame_stat = false;
+-			ret =
+-			    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh),
+-						SDIO_FUNC_2, F2SYNC, frame, len,
+-						NULL, NULL, NULL);
+-
+-			ASSERT(ret != -BCME_PENDING);
+-
+-			if (ret < 0) {
+-				/* On failure, abort the command and
+-				 terminate the frame */
+-				DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n",
+-					__func__, ret));
+-				bus->tx_sderrs++;
+-
+-				bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-				bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-						 SBSDIO_FUNC1_FRAMECTRL,
+-						 SFC_WF_TERM, NULL);
+-				bus->f1regdata++;
+-
+-				for (i = 0; i < 3; i++) {
+-					u8 hi, lo;
+-					hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-					     SBSDIO_FUNC1_WFRAMEBCHI,
+-					     NULL);
+-					lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-					     SBSDIO_FUNC1_WFRAMEBCLO,
+-							     NULL);
+-					bus->f1regdata += 2;
+-					if ((hi == 0) && (lo == 0))
+-						break;
+-				}
+-
+-			}
+-			if (ret == 0) {
+-				bus->tx_seq =
+-				    (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-			}
+-		} while ((ret < 0) && retries++ < TXRETRIES);
+-	}
+-
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (ret)
+-		bus->dhd->tx_ctlerrs++;
+-	else
+-		bus->dhd->tx_ctlpkts++;
+-
+-	return ret ? -EIO : 0;
+-}
+-
+-int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
+-{
+-	int timeleft;
+-	uint rxlen = 0;
+-	bool pending;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->dongle_reset)
+-		return -EIO;
+-
+-	/* Wait until control frame is available */
+-	timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending);
+-
+-	dhd_os_sdlock(bus->dhd);
+-	rxlen = bus->rxlen;
+-	memcpy(msg, bus->rxctl, min(msglen, rxlen));
+-	bus->rxlen = 0;
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (rxlen) {
+-		DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
+-			 __func__, rxlen, msglen));
+-	} else if (timeleft == 0) {
+-		DHD_ERROR(("%s: resumed on timeout\n", __func__));
+-#ifdef DHD_DEBUG
+-		dhd_os_sdlock(bus->dhd);
+-		dhdsdio_checkdied(bus, NULL, 0);
+-		dhd_os_sdunlock(bus->dhd);
+-#endif				/* DHD_DEBUG */
+-	} else if (pending == true) {
+-		DHD_CTL(("%s: cancelled\n", __func__));
+-		return -ERESTARTSYS;
+-	} else {
+-		DHD_CTL(("%s: resumed for unknown reason?\n", __func__));
+-#ifdef DHD_DEBUG
+-		dhd_os_sdlock(bus->dhd);
+-		dhdsdio_checkdied(bus, NULL, 0);
+-		dhd_os_sdunlock(bus->dhd);
+-#endif				/* DHD_DEBUG */
+-	}
+-
+-	if (rxlen)
+-		bus->dhd->rx_ctlpkts++;
+-	else
+-		bus->dhd->rx_ctlerrs++;
+-
+-	return rxlen ? (int)rxlen : -ETIMEDOUT;
+-}
+-
+-/* IOVar table */
+-enum {
+-	IOV_INTR = 1,
+-	IOV_POLLRATE,
+-	IOV_SDREG,
+-	IOV_SBREG,
+-	IOV_SDCIS,
+-	IOV_MEMBYTES,
+-	IOV_MEMSIZE,
+-#ifdef DHD_DEBUG
+-	IOV_CHECKDIED,
+-#endif
+-	IOV_DOWNLOAD,
+-	IOV_FORCEEVEN,
+-	IOV_SDIOD_DRIVE,
+-	IOV_READAHEAD,
+-	IOV_SDRXCHAIN,
+-	IOV_ALIGNCTL,
+-	IOV_SDALIGN,
+-	IOV_DEVRESET,
+-	IOV_CPU,
+-#ifdef SDTEST
+-	IOV_PKTGEN,
+-	IOV_EXTLOOP,
+-#endif				/* SDTEST */
+-	IOV_SPROM,
+-	IOV_TXBOUND,
+-	IOV_RXBOUND,
+-	IOV_TXMINMAX,
+-	IOV_IDLETIME,
+-	IOV_IDLECLOCK,
+-	IOV_SD1IDLE,
+-	IOV_SLEEP,
+-	IOV_VARS
+-};
+-
+-const bcm_iovar_t dhdsdio_iovars[] = {
+-	{"intr", IOV_INTR, 0, IOVT_BOOL, 0},
+-	{"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0},
+-	{"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0},
+-	{"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0},
+-	{"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0},
+-	{"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0},
+-	{"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)},
+-	{"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0},
+-	{"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0},
+-	{"vars", IOV_VARS, 0, IOVT_BUFFER, 0},
+-	{"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0},
+-	{"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0},
+-	{"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0},
+-	{"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0},
+-	{"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0},
+-	{"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0},
+-#ifdef DHD_DEBUG
+-	{"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN}
+-	,
+-	{"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0}
+-	,
+-	{"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0}
+-	,
+-	{"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0}
+-	,
+-	{"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0}
+-	,
+-	{"cpu", IOV_CPU, 0, IOVT_BOOL, 0}
+-	,
+-#ifdef DHD_DEBUG
+-	{"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0}
+-	,
+-#endif				/* DHD_DEBUG  */
+-#endif				/* DHD_DEBUG */
+-#ifdef SDTEST
+-	{"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0}
+-	,
+-	{"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t)}
+-	,
+-#endif				/* SDTEST */
+-
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-static void
+-dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div)
+-{
+-	uint q1, q2;
+-
+-	if (!div) {
+-		bcm_bprintf(strbuf, "%s N/A", desc);
+-	} else {
+-		q1 = num / div;
+-		q2 = (100 * (num - (q1 * div))) / div;
+-		bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
+-	}
+-}
+-
+-void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-
+-	bcm_bprintf(strbuf, "Bus SDIO structure:\n");
+-	bcm_bprintf(strbuf,
+-		    "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
+-		    bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
+-	bcm_bprintf(strbuf,
+-		    "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
+-		    bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max,
+-		    bus->rxskip, bus->rxlen, bus->rx_seq);
+-	bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
+-		    bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
+-	bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
+-		    bus->pollrate, bus->pollcnt, bus->regfails);
+-
+-	bcm_bprintf(strbuf, "\nAdditional counters:\n");
+-	bcm_bprintf(strbuf,
+-		    "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
+-		    bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
+-		    bus->rxc_errors);
+-	bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
+-		    bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
+-	bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", bus->fc_rcvd,
+-		    bus->fc_xoff, bus->fc_xon);
+-	bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
+-		    bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
+-	bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n",
+-		    (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs,
+-		    bus->f2rxdata, bus->f2txdata, bus->f1regdata);
+-	{
+-		dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets,
+-			     (bus->f2rxhdrs + bus->f2rxdata));
+-		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets,
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets,
+-			     (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets,
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
+-			     bus->dhd->rx_packets);
+-		dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts,
+-			     bus->rxglomframes);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets,
+-			     bus->f2txdata);
+-		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets,
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets,
+-			     (bus->f2txdata + bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets,
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Total: pkts/f2rw",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
+-		dhd_dump_pct(strbuf, ", pkts/f1sd",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata +
+-			      bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n\n");
+-	}
+-
+-#ifdef SDTEST
+-	if (bus->pktgen_count) {
+-		bcm_bprintf(strbuf, "pktgen config and count:\n");
+-		bcm_bprintf(strbuf,
+-			    "freq %d count %d print %d total %d min %d len %d\n",
+-			    bus->pktgen_freq, bus->pktgen_count,
+-			    bus->pktgen_print, bus->pktgen_total,
+-			    bus->pktgen_minlen, bus->pktgen_maxlen);
+-		bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n",
+-			    bus->pktgen_sent, bus->pktgen_rcvd,
+-			    bus->pktgen_fail);
+-	}
+-#endif				/* SDTEST */
+-#ifdef DHD_DEBUG
+-	bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
+-		    bus->dpc_sched,
+-		    (bcmsdh_intr_pending(bus->sdh) ? " " : " not "));
+-	bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize,
+-		    bus->roundup);
+-#endif				/* DHD_DEBUG */
+-	bcm_bprintf(strbuf,
+-		    "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
+-		    bus->clkstate, bus->activity, bus->idletime, bus->idlecount,
+-		    bus->sleeping);
+-}
+-
+-void dhd_bus_clearcounts(dhd_pub_t *dhdp)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *) dhdp->bus;
+-
+-	bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
+-	bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
+-	bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
+-	bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
+-	bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
+-	bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
+-}
+-
+-#ifdef SDTEST
+-static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg)
+-{
+-	dhd_pktgen_t pktgen;
+-
+-	pktgen.version = DHD_PKTGEN_VERSION;
+-	pktgen.freq = bus->pktgen_freq;
+-	pktgen.count = bus->pktgen_count;
+-	pktgen.print = bus->pktgen_print;
+-	pktgen.total = bus->pktgen_total;
+-	pktgen.minlen = bus->pktgen_minlen;
+-	pktgen.maxlen = bus->pktgen_maxlen;
+-	pktgen.numsent = bus->pktgen_sent;
+-	pktgen.numrcvd = bus->pktgen_rcvd;
+-	pktgen.numfail = bus->pktgen_fail;
+-	pktgen.mode = bus->pktgen_mode;
+-	pktgen.stop = bus->pktgen_stop;
+-
+-	memcpy(arg, &pktgen, sizeof(pktgen));
+-
+-	return 0;
+-}
+-
+-static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg)
+-{
+-	dhd_pktgen_t pktgen;
+-	uint oldcnt, oldmode;
+-
+-	memcpy(&pktgen, arg, sizeof(pktgen));
+-	if (pktgen.version != DHD_PKTGEN_VERSION)
+-		return -EINVAL;
+-
+-	oldcnt = bus->pktgen_count;
+-	oldmode = bus->pktgen_mode;
+-
+-	bus->pktgen_freq = pktgen.freq;
+-	bus->pktgen_count = pktgen.count;
+-	bus->pktgen_print = pktgen.print;
+-	bus->pktgen_total = pktgen.total;
+-	bus->pktgen_minlen = pktgen.minlen;
+-	bus->pktgen_maxlen = pktgen.maxlen;
+-	bus->pktgen_mode = pktgen.mode;
+-	bus->pktgen_stop = pktgen.stop;
+-
+-	bus->pktgen_tick = bus->pktgen_ptick = 0;
+-	bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen);
+-	bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen);
+-
+-	/* Clear counts for a new pktgen (mode change, or was stopped) */
+-	if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode))
+-		bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0;
+-
+-	return 0;
+-}
+-#endif				/* SDTEST */
+-
+-static int
+-dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data,
+-		 uint size)
+-{
+-	int bcmerror = 0;
+-	u32 sdaddr;
+-	uint dsize;
+-
+-	/* Determine initial transfer parameters */
+-	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
+-	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
+-		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
+-	else
+-		dsize = size;
+-
+-	/* Set the backplane window to include the start address */
+-	bcmerror = dhdsdio_set_siaddr_window(bus, address);
+-	if (bcmerror) {
+-		DHD_ERROR(("%s: window change failed\n", __func__));
+-		goto xfer_done;
+-	}
+-
+-	/* Do the transfer(s) */
+-	while (size) {
+-		DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
+-			  __func__, (write ? "write" : "read"), dsize,
+-			  sdaddr, (address & SBSDIO_SBWINDOW_MASK)));
+-		bcmerror =
+-		     bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: membytes transfer failed\n", __func__));
+-			break;
+-		}
+-
+-		/* Adjust for next transfer (if any) */
+-		size -= dsize;
+-		if (size) {
+-			data += dsize;
+-			address += dsize;
+-			bcmerror = dhdsdio_set_siaddr_window(bus, address);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: window change failed\n",
+-					   __func__));
+-				break;
+-			}
+-			sdaddr = 0;
+-			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
+-		}
+-	}
+-
+-xfer_done:
+-	/* Return the window to backplane enumeration space for core access */
+-	if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) {
+-		DHD_ERROR(("%s: FAILED to set window back to 0x%x\n",
+-			   __func__, bcmsdh_cur_sbwad(bus->sdh)));
+-	}
+-
+-	return bcmerror;
+-}
+-
+-#ifdef DHD_DEBUG
+-static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
+-{
+-	u32 addr;
+-	int rv;
+-
+-	/* Read last word in memory to determine address of
+-			 sdpcm_shared structure */
+-	rv = dhdsdio_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, 4);
+-	if (rv < 0)
+-		return rv;
+-
+-	addr = le32_to_cpu(addr);
+-
+-	DHD_INFO(("sdpcm_shared address 0x%08X\n", addr));
+-
+-	/*
+-	 * Check if addr is valid.
+-	 * NVRAM length at the end of memory should have been overwritten.
+-	 */
+-	if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
+-		DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
+-			   __func__, addr));
+-		return -EBADE;
+-	}
+-
+-	/* Read hndrte_shared structure */
+-	rv = dhdsdio_membytes(bus, false, addr, (u8 *) sh,
+-			      sizeof(sdpcm_shared_t));
+-	if (rv < 0)
+-		return rv;
+-
+-	/* Endianness */
+-	sh->flags = le32_to_cpu(sh->flags);
+-	sh->trap_addr = le32_to_cpu(sh->trap_addr);
+-	sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr);
+-	sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr);
+-	sh->assert_line = le32_to_cpu(sh->assert_line);
+-	sh->console_addr = le32_to_cpu(sh->console_addr);
+-	sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr);
+-
+-	if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
+-		DHD_ERROR(("%s: sdpcm_shared version %d in dhd "
+-			   "is different than sdpcm_shared version %d in dongle\n",
+-			   __func__, SDPCM_SHARED_VERSION,
+-			   sh->flags & SDPCM_SHARED_VERSION_MASK));
+-		return -EBADE;
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size)
+-{
+-	int bcmerror = 0;
+-	uint msize = 512;
+-	char *mbuffer = NULL;
+-	uint maxstrlen = 256;
+-	char *str = NULL;
+-	trap_t tr;
+-	sdpcm_shared_t sdpcm_shared;
+-	struct bcmstrbuf strbuf;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (data == NULL) {
+-		/*
+-		 * Called after a rx ctrl timeout. "data" is NULL.
+-		 * allocate memory to trace the trap or assert.
+-		 */
+-		size = msize;
+-		mbuffer = data = kmalloc(msize, GFP_ATOMIC);
+-		if (mbuffer == NULL) {
+-			DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__,
+-				   msize));
+-			bcmerror = -ENOMEM;
+-			goto done;
+-		}
+-	}
+-
+-	str = kmalloc(maxstrlen, GFP_ATOMIC);
+-	if (str == NULL) {
+-		DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen));
+-		bcmerror = -ENOMEM;
+-		goto done;
+-	}
+-
+-	bcmerror = dhdsdio_readshared(bus, &sdpcm_shared);
+-	if (bcmerror < 0)
+-		goto done;
+-
+-	bcm_binit(&strbuf, data, size);
+-
+-	bcm_bprintf(&strbuf,
+-		    "msgtrace address : 0x%08X\nconsole address  : 0x%08X\n",
+-		    sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
+-
+-	if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
+-		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
+-		 * (Avoids conflict with real asserts for programmatic
+-		 * parsing of output.)
+-		 */
+-		bcm_bprintf(&strbuf, "Assrt not built in dongle\n");
+-	}
+-
+-	if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) ==
+-	    0) {
+-		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
+-		 * (Avoids conflict with real asserts for programmatic
+-		 * parsing of output.)
+-		 */
+-		bcm_bprintf(&strbuf, "No trap%s in dongle",
+-			    (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT)
+-			    ? "/assrt" : "");
+-	} else {
+-		if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) {
+-			/* Download assert */
+-			bcm_bprintf(&strbuf, "Dongle assert");
+-			if (sdpcm_shared.assert_exp_addr != 0) {
+-				str[0] = '\0';
+-				bcmerror = dhdsdio_membytes(bus, false,
+-						sdpcm_shared.assert_exp_addr,
+-						(u8 *) str, maxstrlen);
+-				if (bcmerror < 0)
+-					goto done;
+-
+-				str[maxstrlen - 1] = '\0';
+-				bcm_bprintf(&strbuf, " expr \"%s\"", str);
+-			}
+-
+-			if (sdpcm_shared.assert_file_addr != 0) {
+-				str[0] = '\0';
+-				bcmerror = dhdsdio_membytes(bus, false,
+-						sdpcm_shared.assert_file_addr,
+-						(u8 *) str, maxstrlen);
+-				if (bcmerror < 0)
+-					goto done;
+-
+-				str[maxstrlen - 1] = '\0';
+-				bcm_bprintf(&strbuf, " file \"%s\"", str);
+-			}
+-
+-			bcm_bprintf(&strbuf, " line %d ",
+-				    sdpcm_shared.assert_line);
+-		}
+-
+-		if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+-			bcmerror = dhdsdio_membytes(bus, false,
+-					sdpcm_shared.trap_addr, (u8 *)&tr,
+-					sizeof(trap_t));
+-			if (bcmerror < 0)
+-				goto done;
+-
+-			bcm_bprintf(&strbuf,
+-				    "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
+-				    "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
+-				    "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n",
+-				    tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13,
+-				    tr.r14, tr.pc, sdpcm_shared.trap_addr,
+-				    tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5,
+-				    tr.r6, tr.r7);
+-		}
+-	}
+-
+-	if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP))
+-		DHD_ERROR(("%s: %s\n", __func__, strbuf.origbuf));
+-
+-#ifdef DHD_DEBUG
+-	if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+-		/* Mem dump to a file on device */
+-		dhdsdio_mem_dump(bus);
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-done:
+-	kfree(mbuffer);
+-	kfree(str);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_mem_dump(dhd_bus_t *bus)
+-{
+-	int ret = 0;
+-	int size;		/* Full mem size */
+-	int start = 0;		/* Start address */
+-	int read_size = 0;	/* Read size of each iteration */
+-	u8 *buf = NULL, *databuf = NULL;
+-
+-	/* Get full mem size */
+-	size = bus->ramsize;
+-	buf = kmalloc(size, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size));
+-		return -1;
+-	}
+-
+-	/* Read mem content */
+-	printk(KERN_DEBUG "Dump dongle memory");
+-	databuf = buf;
+-	while (size) {
+-		read_size = min(MEMBLOCK, size);
+-		ret = dhdsdio_membytes(bus, false, start, databuf, read_size);
+-		if (ret) {
+-			DHD_ERROR(("%s: Error membytes %d\n", __func__, ret));
+-			kfree(buf);
+-			return -1;
+-		}
+-		printk(".");
+-
+-		/* Decrement size and increment start address */
+-		size -= read_size;
+-		start += read_size;
+-		databuf += read_size;
+-	}
+-	printk(KERN_DEBUG "Done\n");
+-
+-	/* free buf before return !!! */
+-	if (write_to_file(bus->dhd, buf, bus->ramsize)) {
+-		DHD_ERROR(("%s: Error writing to files\n", __func__));
+-		return -1;
+-	}
+-
+-	/* buf free handled in write_to_file, not here */
+-	return 0;
+-}
+-
+-#define CONSOLE_LINE_MAX	192
+-
+-static int dhdsdio_readconsole(dhd_bus_t *bus)
+-{
+-	dhd_console_t *c = &bus->console;
+-	u8 line[CONSOLE_LINE_MAX], ch;
+-	u32 n, idx, addr;
+-	int rv;
+-
+-	/* Don't do anything until FWREADY updates console address */
+-	if (bus->console_addr == 0)
+-		return 0;
+-
+-	/* Read console log struct */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, log);
+-	rv = dhdsdio_membytes(bus, false, addr, (u8 *)&c->log,
+-				sizeof(c->log));
+-	if (rv < 0)
+-		return rv;
+-
+-	/* Allocate console buffer (one time only) */
+-	if (c->buf == NULL) {
+-		c->bufsize = le32_to_cpu(c->log.buf_size);
+-		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
+-		if (c->buf == NULL)
+-			return -ENOMEM;
+-	}
+-
+-	idx = le32_to_cpu(c->log.idx);
+-
+-	/* Protect against corrupt value */
+-	if (idx > c->bufsize)
+-		return -EBADE;
+-
+-	/* Skip reading the console buffer if the index pointer
+-	 has not moved */
+-	if (idx == c->last)
+-		return 0;
+-
+-	/* Read the console buffer */
+-	addr = le32_to_cpu(c->log.buf);
+-	rv = dhdsdio_membytes(bus, false, addr, c->buf, c->bufsize);
+-	if (rv < 0)
+-		return rv;
+-
+-	while (c->last != idx) {
+-		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
+-			if (c->last == idx) {
+-				/* This would output a partial line.
+-				 * Instead, back up
+-				 * the buffer pointer and output this
+-				 * line next time around.
+-				 */
+-				if (c->last >= n)
+-					c->last -= n;
+-				else
+-					c->last = c->bufsize - n;
+-				goto break2;
+-			}
+-			ch = c->buf[c->last];
+-			c->last = (c->last + 1) % c->bufsize;
+-			if (ch == '\n')
+-				break;
+-			line[n] = ch;
+-		}
+-
+-		if (n > 0) {
+-			if (line[n - 1] == '\r')
+-				n--;
+-			line[n] = 0;
+-			printk(KERN_DEBUG "CONSOLE: %s\n", line);
+-		}
+-	}
+-break2:
+-
+-	return 0;
+-}
+-#endif				/* DHD_DEBUG */
+-
+-int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len)
+-{
+-	int bcmerror = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Basic sanity checks */
+-	if (bus->dhd->up) {
+-		bcmerror = -EISCONN;
+-		goto err;
+-	}
+-	if (!len) {
+-		bcmerror = -EOVERFLOW;
+-		goto err;
+-	}
+-
+-	/* Free the old ones and replace with passed variables */
+-	kfree(bus->vars);
+-
+-	bus->vars = kmalloc(len, GFP_ATOMIC);
+-	bus->varsz = bus->vars ? len : 0;
+-	if (bus->vars == NULL) {
+-		bcmerror = -ENOMEM;
+-		goto err;
+-	}
+-
+-	/* Copy the passed variables, which should include the
+-		 terminating double-null */
+-	memcpy(bus->vars, arg, bus->varsz);
+-err:
+-	return bcmerror;
+-}
+-
+-static int
+-dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid,
+-		const char *name, void *params, int plen, void *arg, int len,
+-		int val_size)
+-{
+-	int bcmerror = 0;
+-	s32 int_val = 0;
+-	bool bool_val = 0;
+-
+-	DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p "
+-		"len %d val_size %d\n",
+-		__func__, actionid, name, params, plen, arg, len, val_size));
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	bool_val = (int_val != 0) ? true : false;
+-
+-	/* Some ioctls use the bus */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Check if dongle is in reset. If so, only allow DEVRESET iovars */
+-	if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
+-					actionid == IOV_GVAL(IOV_DEVRESET))) {
+-		bcmerror = -EPERM;
+-		goto exit;
+-	}
+-
+-	/* Handle sleep stuff before any clock mucking */
+-	if (vi->varid == IOV_SLEEP) {
+-		if (IOV_ISSET(actionid)) {
+-			bcmerror = dhdsdio_bussleep(bus, bool_val);
+-		} else {
+-			int_val = (s32) bus->sleeping;
+-			memcpy(arg, &int_val, val_size);
+-		}
+-		goto exit;
+-	}
+-
+-	/* Request clock to allow SDIO accesses */
+-	if (!bus->dhd->dongle_reset) {
+-		BUS_WAKE(bus);
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	}
+-
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_INTR):
+-		int_val = (s32) bus->intr;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_INTR):
+-		bus->intr = bool_val;
+-		bus->intdis = false;
+-		if (bus->dhd->up) {
+-			if (bus->intr) {
+-				DHD_INTR(("%s: enable SDIO device interrupts\n",
+-					  __func__));
+-				bcmsdh_intr_enable(bus->sdh);
+-			} else {
+-				DHD_INTR(("%s: disable SDIO interrupts\n",
+-					  __func__));
+-				bcmsdh_intr_disable(bus->sdh);
+-			}
+-		}
+-		break;
+-
+-	case IOV_GVAL(IOV_POLLRATE):
+-		int_val = (s32) bus->pollrate;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_POLLRATE):
+-		bus->pollrate = (uint) int_val;
+-		bus->poll = (bus->pollrate != 0);
+-		break;
+-
+-	case IOV_GVAL(IOV_IDLETIME):
+-		int_val = bus->idletime;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_IDLETIME):
+-		if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE))
+-			bcmerror = -EINVAL;
+-		else
+-			bus->idletime = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_IDLECLOCK):
+-		int_val = (s32) bus->idleclock;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_IDLECLOCK):
+-		bus->idleclock = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SD1IDLE):
+-		int_val = (s32) sd1idle;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SD1IDLE):
+-		sd1idle = bool_val;
+-		break;
+-
+-	case IOV_SVAL(IOV_MEMBYTES):
+-	case IOV_GVAL(IOV_MEMBYTES):
+-		{
+-			u32 address;
+-			uint size, dsize;
+-			u8 *data;
+-
+-			bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
+-
+-			ASSERT(plen >= 2 * sizeof(int));
+-
+-			address = (u32) int_val;
+-			memcpy(&int_val, (char *)params + sizeof(int_val),
+-			       sizeof(int_val));
+-			size = (uint) int_val;
+-
+-			/* Do some validation */
+-			dsize = set ? plen - (2 * sizeof(int)) : len;
+-			if (dsize < size) {
+-				DHD_ERROR(("%s: error on %s membytes, addr "
+-				"0x%08x size %d dsize %d\n",
+-				__func__, (set ? "set" : "get"),
+-				address, size, dsize));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			DHD_INFO(("%s: Request to %s %d bytes at address "
+-			"0x%08x\n",
+-			__func__, (set ? "write" : "read"), size, address));
+-
+-			/* If we know about SOCRAM, check for a fit */
+-			if ((bus->orig_ramsize) &&
+-			    ((address > bus->orig_ramsize)
+-			     || (address + size > bus->orig_ramsize))) {
+-				DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d "
+-				"bytes at 0x%08x\n",
+-				__func__, bus->orig_ramsize, size, address));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* Generate the actual data pointer */
+-			data =
+-			    set ? (u8 *) params +
+-			    2 * sizeof(int) : (u8 *) arg;
+-
+-			/* Call to do the transfer */
+-			bcmerror =
+-			    dhdsdio_membytes(bus, set, address, data, size);
+-
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_MEMSIZE):
+-		int_val = (s32) bus->ramsize;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_SDIOD_DRIVE):
+-		int_val = (s32) dhd_sdiod_drive_strength;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDIOD_DRIVE):
+-		dhd_sdiod_drive_strength = int_val;
+-		dhdsdio_sdiod_drive_strength_init(bus,
+-					     dhd_sdiod_drive_strength);
+-		break;
+-
+-	case IOV_SVAL(IOV_DOWNLOAD):
+-		bcmerror = dhdsdio_download_state(bus, bool_val);
+-		break;
+-
+-	case IOV_SVAL(IOV_VARS):
+-		bcmerror = dhdsdio_downloadvars(bus, arg, len);
+-		break;
+-
+-	case IOV_GVAL(IOV_READAHEAD):
+-		int_val = (s32) dhd_readahead;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_READAHEAD):
+-		if (bool_val && !dhd_readahead)
+-			bus->nextlen = 0;
+-		dhd_readahead = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDRXCHAIN):
+-		int_val = (s32) bus->use_rxchain;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDRXCHAIN):
+-		if (bool_val && !bus->sd_rxchain)
+-			bcmerror = -ENOTSUPP;
+-		else
+-			bus->use_rxchain = bool_val;
+-		break;
+-	case IOV_GVAL(IOV_ALIGNCTL):
+-		int_val = (s32) dhd_alignctl;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_ALIGNCTL):
+-		dhd_alignctl = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDALIGN):
+-		int_val = DHD_SDALIGN;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_VARS):
+-		if (bus->varsz < (uint) len)
+-			memcpy(arg, bus->vars, bus->varsz);
+-		else
+-			bcmerror = -EOVERFLOW;
+-		break;
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_SDREG):
+-		{
+-			sdreg_t *sd_ptr;
+-			u32 addr, size;
+-
+-			sd_ptr = (sdreg_t *) params;
+-
+-			addr = (unsigned long)bus->regs + sd_ptr->offset;
+-			size = sd_ptr->func;
+-			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			memcpy(arg, &int_val, sizeof(s32));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_SDREG):
+-		{
+-			sdreg_t *sd_ptr;
+-			u32 addr, size;
+-
+-			sd_ptr = (sdreg_t *) params;
+-
+-			addr = (unsigned long)bus->regs + sd_ptr->offset;
+-			size = sd_ptr->func;
+-			bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			break;
+-		}
+-
+-		/* Same as above, but offset is not backplane
+-		 (not SDIO core) */
+-	case IOV_GVAL(IOV_SBREG):
+-		{
+-			sdreg_t sdreg;
+-			u32 addr, size;
+-
+-			memcpy(&sdreg, params, sizeof(sdreg));
+-
+-			addr = SI_ENUM_BASE + sdreg.offset;
+-			size = sdreg.func;
+-			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			memcpy(arg, &int_val, sizeof(s32));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_SBREG):
+-		{
+-			sdreg_t sdreg;
+-			u32 addr, size;
+-
+-			memcpy(&sdreg, params, sizeof(sdreg));
+-
+-			addr = SI_ENUM_BASE + sdreg.offset;
+-			size = sdreg.func;
+-			bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_SDCIS):
+-		{
+-			*(char *)arg = 0;
+-
+-			strcat(arg, "\nFunc 0\n");
+-			bcmsdh_cis_read(bus->sdh, 0x10,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			strcat(arg, "\nFunc 1\n");
+-			bcmsdh_cis_read(bus->sdh, 0x11,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			strcat(arg, "\nFunc 2\n");
+-			bcmsdh_cis_read(bus->sdh, 0x12,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_FORCEEVEN):
+-		int_val = (s32) forcealign;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_FORCEEVEN):
+-		forcealign = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_TXBOUND):
+-		int_val = (s32) dhd_txbound;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_TXBOUND):
+-		dhd_txbound = (uint) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_RXBOUND):
+-		int_val = (s32) dhd_rxbound;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_RXBOUND):
+-		dhd_rxbound = (uint) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_TXMINMAX):
+-		int_val = (s32) dhd_txminmax;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_TXMINMAX):
+-		dhd_txminmax = (uint) int_val;
+-		break;
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef SDTEST
+-	case IOV_GVAL(IOV_EXTLOOP):
+-		int_val = (s32) bus->ext_loop;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_EXTLOOP):
+-		bus->ext_loop = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_PKTGEN):
+-		bcmerror = dhdsdio_pktgen_get(bus, arg);
+-		break;
+-
+-	case IOV_SVAL(IOV_PKTGEN):
+-		bcmerror = dhdsdio_pktgen_set(bus, arg);
+-		break;
+-#endif				/* SDTEST */
+-
+-	case IOV_SVAL(IOV_DEVRESET):
+-		DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d "
+-			"busstate=%d\n",
+-			__func__, bool_val, bus->dhd->dongle_reset,
+-			bus->dhd->busstate));
+-
+-		dhd_bus_devreset(bus->dhd, (u8) bool_val);
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_DEVRESET):
+-		DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __func__));
+-
+-		/* Get its status */
+-		int_val = (bool) bus->dhd->dongle_reset;
+-		memcpy(arg, &int_val, val_size);
+-
+-		break;
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-
+-exit:
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false)
+-		dhd_preinit_ioctls((dhd_pub_t *) bus->dhd);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_write_vars(dhd_bus_t *bus)
+-{
+-	int bcmerror = 0;
+-	u32 varsize;
+-	u32 varaddr;
+-	u8 *vbuffer;
+-	u32 varsizew;
+-#ifdef DHD_DEBUG
+-	char *nvram_ularray;
+-#endif				/* DHD_DEBUG */
+-
+-	/* Even if there are no vars are to be written, we still
+-		 need to set the ramsize. */
+-	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
+-	varaddr = (bus->ramsize - 4) - varsize;
+-
+-	if (bus->vars) {
+-		vbuffer = kzalloc(varsize, GFP_ATOMIC);
+-		if (!vbuffer)
+-			return -ENOMEM;
+-
+-		memcpy(vbuffer, bus->vars, bus->varsz);
+-
+-		/* Write the vars list */
+-		bcmerror =
+-		    dhdsdio_membytes(bus, true, varaddr, vbuffer, varsize);
+-#ifdef DHD_DEBUG
+-		/* Verify NVRAM bytes */
+-		DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
+-		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
+-		if (!nvram_ularray)
+-			return -ENOMEM;
+-
+-		/* Upload image to verify downloaded contents. */
+-		memset(nvram_ularray, 0xaa, varsize);
+-
+-		/* Read the vars list to temp buffer for comparison */
+-		bcmerror =
+-		    dhdsdio_membytes(bus, false, varaddr, nvram_ularray,
+-				     varsize);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on reading %d nvram bytes at "
+-			"0x%08x\n", __func__, bcmerror, varsize, varaddr));
+-		}
+-		/* Compare the org NVRAM with the one read from RAM */
+-		if (memcmp(vbuffer, nvram_ularray, varsize)) {
+-			DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n",
+-				   __func__));
+-		} else
+-			DHD_ERROR(("%s: Download/Upload/Compare of NVRAM ok.\n",
+-				__func__));
+-
+-		kfree(nvram_ularray);
+-#endif				/* DHD_DEBUG */
+-
+-		kfree(vbuffer);
+-	}
+-
+-	/* adjust to the user specified RAM */
+-	DHD_INFO(("Physical memory size: %d, usable memory size: %d\n",
+-		  bus->orig_ramsize, bus->ramsize));
+-	DHD_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize));
+-	varsize = ((bus->orig_ramsize - 4) - varaddr);
+-
+-	/*
+-	 * Determine the length token:
+-	 * Varsize, converted to words, in lower 16-bits, checksum
+-	 * in upper 16-bits.
+-	 */
+-	if (bcmerror) {
+-		varsizew = 0;
+-	} else {
+-		varsizew = varsize / 4;
+-		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
+-		varsizew = cpu_to_le32(varsizew);
+-	}
+-
+-	DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize,
+-		  varsizew));
+-
+-	/* Write the length token to the last word */
+-	bcmerror = dhdsdio_membytes(bus, true, (bus->orig_ramsize - 4),
+-				    (u8 *)&varsizew, 4);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_download_state(dhd_bus_t *bus, bool enter)
+-{
+-	uint retries;
+-	u32 regdata;
+-	int bcmerror = 0;
+-
+-	/* To enter download state, disable ARM and reset SOCRAM.
+-	 * To exit download state, simply reset ARM (default is RAM boot).
+-	 */
+-	if (enter) {
+-		bus->alp_only = true;
+-
+-		dhdsdio_chip_disablecore(bus->sdh, bus->ci->armcorebase);
+-
+-		dhdsdio_chip_resetcore(bus->sdh, bus->ci->ramcorebase);
+-
+-		/* Clear the top bit of memory */
+-		if (bus->ramsize) {
+-			u32 zeros = 0;
+-			dhdsdio_membytes(bus, true, bus->ramsize - 4,
+-					 (u8 *)&zeros, 4);
+-		}
+-	} else {
+-		regdata = bcmsdh_reg_read(bus->sdh,
+-			CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
+-		regdata &= (SBTML_RESET | SBTML_REJ_MASK |
+-			(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-		if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
+-			DHD_ERROR(("%s: SOCRAM core is down after reset?\n",
+-				   __func__));
+-			bcmerror = -EBADE;
+-			goto fail;
+-		}
+-
+-		bcmerror = dhdsdio_write_vars(bus);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: no vars written to RAM\n", __func__));
+-			bcmerror = 0;
+-		}
+-
+-		W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
+-
+-		dhdsdio_chip_resetcore(bus->sdh, bus->ci->armcorebase);
+-
+-		/* Allow HT Clock now that the ARM is running. */
+-		bus->alp_only = false;
+-
+-		bus->dhd->busstate = DHD_BUS_LOAD;
+-	}
+-fail:
+-	return bcmerror;
+-}
+-
+-int
+-dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+-		 void *params, int plen, void *arg, int len, bool set)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	const bcm_iovar_t *vi = NULL;
+-	int bcmerror = 0;
+-	int val_size;
+-	u32 actionid;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get MUST have return space */
+-	ASSERT(set || (arg && len));
+-
+-	/* Set does NOT take qualifiers */
+-	ASSERT(!set || (!params && !plen));
+-
+-	/* Look up var locally; if not found pass to host driver */
+-	vi = bcm_iovar_lookup(dhdsdio_iovars, name);
+-	if (vi == NULL) {
+-		dhd_os_sdlock(bus->dhd);
+-
+-		BUS_WAKE(bus);
+-
+-		/* Turn on clock in case SD command needs backplane */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		bcmerror =
+-		    bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len,
+-				    set);
+-
+-		/* Check for bus configuration changes of interest */
+-
+-		/* If it was divisor change, read the new one */
+-		if (set && strcmp(name, "sd_divisor") == 0) {
+-			if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					    &bus->sd_divisor, sizeof(s32),
+-					    false) != 0) {
+-				bus->sd_divisor = -1;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   name));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, name, bus->sd_divisor));
+-			}
+-		}
+-		/* If it was a mode change, read the new one */
+-		if (set && strcmp(name, "sd_mode") == 0) {
+-			if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+-					    &bus->sd_mode, sizeof(s32),
+-					    false) != 0) {
+-				bus->sd_mode = -1;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   name));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, name, bus->sd_mode));
+-			}
+-		}
+-		/* Similar check for blocksize change */
+-		if (set && strcmp(name, "sd_blocksize") == 0) {
+-			s32 fnum = 2;
+-			if (bcmsdh_iovar_op
+-			    (bus->sdh, "sd_blocksize", &fnum, sizeof(s32),
+-			     &bus->blocksize, sizeof(s32),
+-			     false) != 0) {
+-				bus->blocksize = 0;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   "sd_blocksize"));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, "sd_blocksize",
+-					  bus->blocksize));
+-			}
+-		}
+-		bus->roundup = min(max_roundup, bus->blocksize);
+-
+-		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-			bus->activity = false;
+-			dhdsdio_clkctl(bus, CLK_NONE, true);
+-		}
+-
+-		dhd_os_sdunlock(bus->dhd);
+-		goto exit;
+-	}
+-
+-	DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__,
+-		 name, (set ? "set" : "get"), len, plen));
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	bcmerror =
+-	    dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len,
+-			    val_size);
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
+-{
+-	u32 local_hostintmask;
+-	u8 saveclk;
+-	uint retries;
+-	int err;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (enforce_mutex)
+-		dhd_os_sdlock(bus->dhd);
+-
+-	BUS_WAKE(bus);
+-
+-	/* Enable clock for device interrupts */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Disable and clear interrupts at the chip level also */
+-	W_SDREG(0, &bus->regs->hostintmask, retries);
+-	local_hostintmask = bus->hostintmask;
+-	bus->hostintmask = 0;
+-
+-	/* Change our idea of bus state */
+-	bus->dhd->busstate = DHD_BUS_DOWN;
+-
+-	/* Force clocks on backplane to be sure F2 interrupt propagates */
+-	saveclk =
+-	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			    &err);
+-	if (!err) {
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 (saveclk | SBSDIO_FORCE_HT), &err);
+-	}
+-	if (err) {
+-		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
+-			   __func__, err));
+-	}
+-
+-	/* Turn off the bus (F2), free any pending packets */
+-	DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-	bcmsdh_intr_disable(bus->sdh);
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
+-			 SDIO_FUNC_ENABLE_1, NULL);
+-
+-	/* Clear any pending interrupts now that F2 is disabled */
+-	W_SDREG(local_hostintmask, &bus->regs->intstatus, retries);
+-
+-	/* Turn off the backplane clock (only) */
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-	/* Clear the data packet queues */
+-	bcm_pktq_flush(&bus->txq, true, NULL, NULL);
+-
+-	/* Clear any held glomming stuff */
+-	if (bus->glomd)
+-		bcm_pkt_buf_free_skb(bus->glomd);
+-
+-	if (bus->glom)
+-		bcm_pkt_buf_free_skb(bus->glom);
+-
+-	bus->glom = bus->glomd = NULL;
+-
+-	/* Clear rx control and wake any waiters */
+-	bus->rxlen = 0;
+-	dhd_os_ioctl_resp_wake(bus->dhd);
+-
+-	/* Reset some F2 state stuff */
+-	bus->rxskip = false;
+-	bus->tx_seq = bus->rx_seq = 0;
+-
+-	if (enforce_mutex)
+-		dhd_os_sdunlock(bus->dhd);
+-}
+-
+-int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	dhd_timeout_t tmo;
+-	uint retries = 0;
+-	u8 ready, enable;
+-	int err, ret = 0;
+-	u8 saveclk;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(bus->dhd);
+-	if (!bus->dhd)
+-		return 0;
+-
+-	if (enforce_mutex)
+-		dhd_os_sdlock(bus->dhd);
+-
+-	/* Make sure backplane clock is on, needed to generate F2 interrupt */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	if (bus->clkstate != CLK_AVAIL)
+-		goto exit;
+-
+-	/* Force clocks on backplane to be sure F2 interrupt propagates */
+-	saveclk =
+-	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			    &err);
+-	if (!err) {
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 (saveclk | SBSDIO_FORCE_HT), &err);
+-	}
+-	if (err) {
+-		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
+-			   __func__, err));
+-		goto exit;
+-	}
+-
+-	/* Enable function 2 (frame transfers) */
+-	W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT),
+-		&bus->regs->tosbmailboxdata, retries);
+-	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
+-
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
+-
+-	/* Give the dongle some time to do its thing and set IOR2 */
+-	dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000);
+-
+-	ready = 0;
+-	while (ready != enable && !dhd_timeout_expired(&tmo))
+-		ready =
+-		    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY,
+-				    NULL);
+-
+-	DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
+-		  __func__, enable, ready, tmo.elapsed));
+-
+-	/* If F2 successfully enabled, set core and enable interrupts */
+-	if (ready == enable) {
+-		/* Set up the interrupt mask and enable interrupts */
+-		bus->hostintmask = HOSTINTMASK;
+-		W_SDREG(bus->hostintmask,
+-			(unsigned int *)CORE_BUS_REG(bus->ci->buscorebase,
+-			hostintmask), retries);
+-
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK,
+-				 (u8) watermark, &err);
+-
+-		/* Set bus state according to enable result */
+-		dhdp->busstate = DHD_BUS_DATA;
+-
+-		/* bcmsdh_intr_unmask(bus->sdh); */
+-
+-		bus->intdis = false;
+-		if (bus->intr) {
+-			DHD_INTR(("%s: enable SDIO device interrupts\n",
+-				  __func__));
+-			bcmsdh_intr_enable(bus->sdh);
+-		} else {
+-			DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-			bcmsdh_intr_disable(bus->sdh);
+-		}
+-
+-	}
+-
+-	else {
+-		/* Disable F2 again */
+-		enable = SDIO_FUNC_ENABLE_1;
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable,
+-				 NULL);
+-	}
+-
+-	/* Restore previous clock setting */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			 saveclk, &err);
+-
+-	/* If we didn't come up, turn off backplane clock */
+-	if (dhdp->busstate != DHD_BUS_DATA)
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-
+-exit:
+-	if (enforce_mutex)
+-		dhd_os_sdunlock(bus->dhd);
+-
+-	return ret;
+-}
+-
+-static void dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-	u16 lastrbc;
+-	u8 hi, lo;
+-	int err;
+-
+-	DHD_ERROR(("%s: %sterminate frame%s\n", __func__,
+-		   (abort ? "abort command, " : ""),
+-		   (rtx ? ", send NAK" : "")));
+-
+-	if (abort)
+-		bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
+-			 &err);
+-	bus->f1regdata++;
+-
+-	/* Wait until the packet has been flushed (device/FIFO stable) */
+-	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
+-		hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI,
+-				     NULL);
+-		lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO,
+-				     NULL);
+-		bus->f1regdata += 2;
+-
+-		if ((hi == 0) && (lo == 0))
+-			break;
+-
+-		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
+-			DHD_ERROR(("%s: count growing: last 0x%04x now "
+-				"0x%04x\n",
+-				__func__, lastrbc, ((hi << 8) + lo)));
+-		}
+-		lastrbc = (hi << 8) + lo;
+-	}
+-
+-	if (!retries) {
+-		DHD_ERROR(("%s: count never zeroed: last 0x%04x\n",
+-			   __func__, lastrbc));
+-	} else {
+-		DHD_INFO(("%s: flush took %d iterations\n", __func__,
+-			  (0xffff - retries)));
+-	}
+-
+-	if (rtx) {
+-		bus->rxrtx++;
+-		W_SDREG(SMB_NAK, &regs->tosbmailbox, retries);
+-		bus->f1regdata++;
+-		if (retries <= retry_limit)
+-			bus->rxskip = true;
+-	}
+-
+-	/* Clear partial in any case */
+-	bus->nextlen = 0;
+-
+-	/* If we can't reach the device, signal failure */
+-	if (err || bcmsdh_regfail(sdh))
+-		bus->dhd->busstate = DHD_BUS_DOWN;
+-}
+-
+-static void
+-dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	uint rdlen, pad;
+-
+-	int sdret;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Control data already received in aligned rxctl */
+-	if ((bus->bus == SPI_BUS) && (!bus->usebufpool))
+-		goto gotpkt;
+-
+-	ASSERT(bus->rxbuf);
+-	/* Set rxctl for frame (w/optional alignment) */
+-	bus->rxctl = bus->rxbuf;
+-	if (dhd_alignctl) {
+-		bus->rxctl += firstread;
+-		pad = ((unsigned long)bus->rxctl % DHD_SDALIGN);
+-		if (pad)
+-			bus->rxctl += (DHD_SDALIGN - pad);
+-		bus->rxctl -= firstread;
+-	}
+-	ASSERT(bus->rxctl >= bus->rxbuf);
+-
+-	/* Copy the already-read portion over */
+-	memcpy(bus->rxctl, hdr, firstread);
+-	if (len <= firstread)
+-		goto gotpkt;
+-
+-	/* Copy the full data pkt in gSPI case and process ioctl. */
+-	if (bus->bus == SPI_BUS) {
+-		memcpy(bus->rxctl, hdr, len);
+-		goto gotpkt;
+-	}
+-
+-	/* Raise rdlen to next SDIO block to avoid tail command */
+-	rdlen = len - firstread;
+-	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
+-		pad = bus->blocksize - (rdlen % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+-		    ((len + pad) < bus->dhd->maxctl))
+-			rdlen += pad;
+-	} else if (rdlen % DHD_SDALIGN) {
+-		rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-	}
+-
+-	/* Satisfy length-alignment requirements */
+-	if (forcealign && (rdlen & (ALIGNMENT - 1)))
+-		rdlen = roundup(rdlen, ALIGNMENT);
+-
+-	/* Drop if the read is too big or it exceeds our maximum */
+-	if ((rdlen + firstread) > bus->dhd->maxctl) {
+-		DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n",
+-			   __func__, rdlen, bus->dhd->maxctl));
+-		bus->dhd->rx_errors++;
+-		dhdsdio_rxfail(bus, false, false);
+-		goto done;
+-	}
+-
+-	if ((len - doff) > bus->dhd->maxctl) {
+-		DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds "
+-			"%d-byte limit\n",
+-			__func__, len, (len - doff), bus->dhd->maxctl));
+-		bus->dhd->rx_errors++;
+-		bus->rx_toolong++;
+-		dhdsdio_rxfail(bus, false, false);
+-		goto done;
+-	}
+-
+-	/* Read remainder of frame body into the rxctl buffer */
+-	sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-				F2SYNC, (bus->rxctl + firstread), rdlen,
+-				NULL, NULL, NULL);
+-	bus->f2rxdata++;
+-	ASSERT(sdret != -BCME_PENDING);
+-
+-	/* Control frame failures need retransmission */
+-	if (sdret < 0) {
+-		DHD_ERROR(("%s: read %d control bytes failed: %d\n",
+-			   __func__, rdlen, sdret));
+-		bus->rxc_errors++;	/* dhd.rx_ctlerrs is higher level */
+-		dhdsdio_rxfail(bus, true, true);
+-		goto done;
+-	}
+-
+-gotpkt:
+-
+-#ifdef DHD_DEBUG
+-	if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+-		printk(KERN_DEBUG "RxCtrl:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
+-	}
+-#endif
+-
+-	/* Point to valid data and indicate its length */
+-	bus->rxctl += doff;
+-	bus->rxlen = len - doff;
+-
+-done:
+-	/* Awake any waiters */
+-	dhd_os_ioctl_resp_wake(bus->dhd);
+-}
+-
+-static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq)
+-{
+-	u16 dlen, totlen;
+-	u8 *dptr, num = 0;
+-
+-	u16 sublen, check;
+-	struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
+-
+-	int errcode;
+-	u8 chan, seq, doff, sfdoff;
+-	u8 txmax;
+-
+-	int ifidx = 0;
+-	bool usechain = bus->use_rxchain;
+-
+-	/* If packets, issue read(s) and send up packet chain */
+-	/* Return sequence numbers consumed? */
+-
+-	DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd,
+-		   bus->glom));
+-
+-	/* If there's a descriptor, generate the packet chain */
+-	if (bus->glomd) {
+-		dhd_os_sdlock_rxq(bus->dhd);
+-
+-		pfirst = plast = pnext = NULL;
+-		dlen = (u16) (bus->glomd->len);
+-		dptr = bus->glomd->data;
+-		if (!dlen || (dlen & 1)) {
+-			DHD_ERROR(("%s: bad glomd len(%d), ignore descriptor\n",
+-			__func__, dlen));
+-			dlen = 0;
+-		}
+-
+-		for (totlen = num = 0; dlen; num++) {
+-			/* Get (and move past) next length */
+-			sublen = get_unaligned_le16(dptr);
+-			dlen -= sizeof(u16);
+-			dptr += sizeof(u16);
+-			if ((sublen < SDPCM_HDRLEN) ||
+-			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
+-				DHD_ERROR(("%s: descriptor len %d bad: %d\n",
+-					   __func__, num, sublen));
+-				pnext = NULL;
+-				break;
+-			}
+-			if (sublen % DHD_SDALIGN) {
+-				DHD_ERROR(("%s: sublen %d not multiple of %d\n",
+-				__func__, sublen, DHD_SDALIGN));
+-				usechain = false;
+-			}
+-			totlen += sublen;
+-
+-			/* For last frame, adjust read len so total
+-				 is a block multiple */
+-			if (!dlen) {
+-				sublen +=
+-				    (roundup(totlen, bus->blocksize) - totlen);
+-				totlen = roundup(totlen, bus->blocksize);
+-			}
+-
+-			/* Allocate/chain packet for next subframe */
+-			pnext = bcm_pkt_buf_get_skb(sublen + DHD_SDALIGN);
+-			if (pnext == NULL) {
+-				DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed, "
+-					"num %d len %d\n", __func__,
+-					num, sublen));
+-				break;
+-			}
+-			ASSERT(!(pnext->prev));
+-			if (!pfirst) {
+-				ASSERT(!plast);
+-				pfirst = plast = pnext;
+-			} else {
+-				ASSERT(plast);
+-				plast->next = pnext;
+-				plast = pnext;
+-			}
+-
+-			/* Adhere to start alignment requirements */
+-			PKTALIGN(pnext, sublen, DHD_SDALIGN);
+-		}
+-
+-		/* If all allocations succeeded, save packet chain
+-			 in bus structure */
+-		if (pnext) {
+-			DHD_GLOM(("%s: allocated %d-byte packet chain for %d "
+-				"subframes\n", __func__, totlen, num));
+-			if (DHD_GLOM_ON() && bus->nextlen) {
+-				if (totlen != bus->nextlen) {
+-					DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " "rxseq %d\n",
+-						__func__, bus->nextlen,
+-						totlen, rxseq));
+-				}
+-			}
+-			bus->glom = pfirst;
+-			pfirst = pnext = NULL;
+-		} else {
+-			if (pfirst)
+-				bcm_pkt_buf_free_skb(pfirst);
+-			bus->glom = NULL;
+-			num = 0;
+-		}
+-
+-		/* Done with descriptor packet */
+-		bcm_pkt_buf_free_skb(bus->glomd);
+-		bus->glomd = NULL;
+-		bus->nextlen = 0;
+-
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-	}
+-
+-	/* Ok -- either we just generated a packet chain,
+-		 or had one from before */
+-	if (bus->glom) {
+-		if (DHD_GLOM_ON()) {
+-			DHD_GLOM(("%s: try superframe read, packet chain:\n",
+-				__func__));
+-			for (pnext = bus->glom; pnext; pnext = pnext->next) {
+-				DHD_GLOM(("    %p: %p len 0x%04x (%d)\n",
+-					  pnext, (u8 *) (pnext->data),
+-					  pnext->len, pnext->len));
+-			}
+-		}
+-
+-		pfirst = bus->glom;
+-		dlen = (u16) bcm_pkttotlen(pfirst);
+-
+-		/* Do an SDIO read for the superframe.  Configurable iovar to
+-		 * read directly into the chained packet, or allocate a large
+-		 * packet and and copy into the chain.
+-		 */
+-		if (usechain) {
+-			errcode = bcmsdh_recv_buf(bus,
+-					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+-					F2SYNC, (u8 *) pfirst->data, dlen,
+-					pfirst, NULL, NULL);
+-		} else if (bus->dataptr) {
+-			errcode = bcmsdh_recv_buf(bus,
+-					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+-					F2SYNC, bus->dataptr, dlen,
+-					NULL, NULL, NULL);
+-			sublen = (u16) bcm_pktfrombuf(pfirst, 0, dlen,
+-						bus->dataptr);
+-			if (sublen != dlen) {
+-				DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n",
+-					__func__, dlen, sublen));
+-				errcode = -1;
+-			}
+-			pnext = NULL;
+-		} else {
+-			DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
+-				dlen));
+-			errcode = -1;
+-		}
+-		bus->f2rxdata++;
+-		ASSERT(errcode != -BCME_PENDING);
+-
+-		/* On failure, kill the superframe, allow a couple retries */
+-		if (errcode < 0) {
+-			DHD_ERROR(("%s: glom read of %d bytes failed: %d\n",
+-				   __func__, dlen, errcode));
+-			bus->dhd->rx_errors++;
+-
+-			if (bus->glomerr++ < 3) {
+-				dhdsdio_rxfail(bus, true, true);
+-			} else {
+-				bus->glomerr = 0;
+-				dhdsdio_rxfail(bus, true, false);
+-				dhd_os_sdlock_rxq(bus->dhd);
+-				bcm_pkt_buf_free_skb(bus->glom);
+-				dhd_os_sdunlock_rxq(bus->dhd);
+-				bus->rxglomfail++;
+-				bus->glom = NULL;
+-			}
+-			return 0;
+-		}
+-#ifdef DHD_DEBUG
+-		if (DHD_GLOM_ON()) {
+-			printk(KERN_DEBUG "SUPERFRAME:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-				pfirst->data, min_t(int, pfirst->len, 48));
+-		}
+-#endif
+-
+-		/* Validate the superframe header */
+-		dptr = (u8 *) (pfirst->data);
+-		sublen = get_unaligned_le16(dptr);
+-		check = get_unaligned_le16(dptr + sizeof(u16));
+-
+-		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+-		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+-		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-			DHD_INFO(("%s: nextlen too large (%d) seq %d\n",
+-				__func__, bus->nextlen, seq));
+-			bus->nextlen = 0;
+-		}
+-		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-
+-		errcode = 0;
+-		if ((u16)~(sublen ^ check)) {
+-			DHD_ERROR(("%s (superframe): HW hdr error: len/check "
+-				"0x%04x/0x%04x\n", __func__, sublen, check));
+-			errcode = -1;
+-		} else if (roundup(sublen, bus->blocksize) != dlen) {
+-			DHD_ERROR(("%s (superframe): len 0x%04x, rounded "
+-				"0x%04x, expect 0x%04x\n",
+-				__func__, sublen,
+-				roundup(sublen, bus->blocksize), dlen));
+-			errcode = -1;
+-		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
+-			   SDPCM_GLOM_CHANNEL) {
+-			DHD_ERROR(("%s (superframe): bad channel %d\n",
+-				   __func__,
+-				   SDPCM_PACKET_CHANNEL(&dptr
+-							[SDPCM_FRAMETAG_LEN])));
+-			errcode = -1;
+-		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
+-			DHD_ERROR(("%s (superframe): got second descriptor?\n",
+-				   __func__));
+-			errcode = -1;
+-		} else if ((doff < SDPCM_HDRLEN) ||
+-			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
+-			DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d "
+-				"pkt %d min %d\n",
+-				__func__, doff, sublen,
+-				pfirst->len, SDPCM_HDRLEN));
+-			errcode = -1;
+-		}
+-
+-		/* Check sequence number of superframe SW header */
+-		if (rxseq != seq) {
+-			DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n",
+-				  __func__, seq, rxseq));
+-			bus->rx_badseq++;
+-			rxseq = seq;
+-		}
+-
+-		/* Check window for sanity */
+-		if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
+-				__func__, txmax, bus->tx_seq));
+-			txmax = bus->tx_seq + 2;
+-		}
+-		bus->tx_max = txmax;
+-
+-		/* Remove superframe header, remember offset */
+-		skb_pull(pfirst, doff);
+-		sfdoff = doff;
+-
+-		/* Validate all the subframe headers */
+-		for (num = 0, pnext = pfirst; pnext && !errcode;
+-		     num++, pnext = pnext->next) {
+-			dptr = (u8 *) (pnext->data);
+-			dlen = (u16) (pnext->len);
+-			sublen = get_unaligned_le16(dptr);
+-			check = get_unaligned_le16(dptr + sizeof(u16));
+-			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-#ifdef DHD_DEBUG
+-			if (DHD_GLOM_ON()) {
+-				printk(KERN_DEBUG "subframe:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     dptr, 32);
+-			}
+-#endif
+-
+-			if ((u16)~(sublen ^ check)) {
+-				DHD_ERROR(("%s (subframe %d): HW hdr error: "
+-					   "len/check 0x%04x/0x%04x\n",
+-					   __func__, num, sublen, check));
+-				errcode = -1;
+-			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
+-				DHD_ERROR(("%s (subframe %d): length mismatch: "
+-					   "len 0x%04x, expect 0x%04x\n",
+-					   __func__, num, sublen, dlen));
+-				errcode = -1;
+-			} else if ((chan != SDPCM_DATA_CHANNEL) &&
+-				   (chan != SDPCM_EVENT_CHANNEL)) {
+-				DHD_ERROR(("%s (subframe %d): bad channel %d\n",
+-					   __func__, num, chan));
+-				errcode = -1;
+-			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
+-				DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n",
+-					__func__, num, doff, sublen,
+-					SDPCM_HDRLEN));
+-				errcode = -1;
+-			}
+-		}
+-
+-		if (errcode) {
+-			/* Terminate frame on error, request
+-				 a couple retries */
+-			if (bus->glomerr++ < 3) {
+-				/* Restore superframe header space */
+-				skb_push(pfirst, sfdoff);
+-				dhdsdio_rxfail(bus, true, true);
+-			} else {
+-				bus->glomerr = 0;
+-				dhdsdio_rxfail(bus, true, false);
+-				dhd_os_sdlock_rxq(bus->dhd);
+-				bcm_pkt_buf_free_skb(bus->glom);
+-				dhd_os_sdunlock_rxq(bus->dhd);
+-				bus->rxglomfail++;
+-				bus->glom = NULL;
+-			}
+-			bus->nextlen = 0;
+-			return 0;
+-		}
+-
+-		/* Basic SD framing looks ok - process each packet (header) */
+-		save_pfirst = pfirst;
+-		bus->glom = NULL;
+-		plast = NULL;
+-
+-		dhd_os_sdlock_rxq(bus->dhd);
+-		for (num = 0; pfirst; rxseq++, pfirst = pnext) {
+-			pnext = pfirst->next;
+-			pfirst->next = NULL;
+-
+-			dptr = (u8 *) (pfirst->data);
+-			sublen = get_unaligned_le16(dptr);
+-			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-
+-			DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d "
+-				"chan %d seq %d\n",
+-				__func__, num, pfirst, pfirst->data,
+-				pfirst->len, sublen, chan, seq));
+-
+-			ASSERT((chan == SDPCM_DATA_CHANNEL)
+-			       || (chan == SDPCM_EVENT_CHANNEL));
+-
+-			if (rxseq != seq) {
+-				DHD_GLOM(("%s: rx_seq %d, expected %d\n",
+-					  __func__, seq, rxseq));
+-				bus->rx_badseq++;
+-				rxseq = seq;
+-			}
+-#ifdef DHD_DEBUG
+-			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-				printk(KERN_DEBUG "Rx Subframe Data:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     dptr, dlen);
+-			}
+-#endif
+-
+-			__skb_trim(pfirst, sublen);
+-			skb_pull(pfirst, doff);
+-
+-			if (pfirst->len == 0) {
+-				bcm_pkt_buf_free_skb(pfirst);
+-				if (plast) {
+-					plast->next = pnext;
+-				} else {
+-					ASSERT(save_pfirst == pfirst);
+-					save_pfirst = pnext;
+-				}
+-				continue;
+-			} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) !=
+-				   0) {
+-				DHD_ERROR(("%s: rx protocol error\n",
+-					   __func__));
+-				bus->dhd->rx_errors++;
+-				bcm_pkt_buf_free_skb(pfirst);
+-				if (plast) {
+-					plast->next = pnext;
+-				} else {
+-					ASSERT(save_pfirst == pfirst);
+-					save_pfirst = pnext;
+-				}
+-				continue;
+-			}
+-
+-			/* this packet will go up, link back into
+-				 chain and count it */
+-			pfirst->next = pnext;
+-			plast = pfirst;
+-			num++;
+-
+-#ifdef DHD_DEBUG
+-			if (DHD_GLOM_ON()) {
+-				DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) "
+-				"nxt/lnk %p/%p\n",
+-				__func__, num, pfirst, pfirst->data,
+-				pfirst->len, pfirst->next,
+-				pfirst->prev));
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						pfirst->data,
+-						min_t(int, pfirst->len, 32));
+-			}
+-#endif				/* DHD_DEBUG */
+-		}
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-		if (num) {
+-			dhd_os_sdunlock(bus->dhd);
+-			dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num);
+-			dhd_os_sdlock(bus->dhd);
+-		}
+-
+-		bus->rxglomframes++;
+-		bus->rxglompkts += num;
+-	}
+-	return num;
+-}
+-
+-/* Return true if there may be more frames to read */
+-static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-
+-	u16 len, check;	/* Extracted hardware header fields */
+-	u8 chan, seq, doff;	/* Extracted software header fields */
+-	u8 fcbits;		/* Extracted fcbits from software header */
+-
+-	struct sk_buff *pkt;		/* Packet for event or data frames */
+-	u16 pad;		/* Number of pad bytes to read */
+-	u16 rdlen;		/* Total number of bytes to read */
+-	u8 rxseq;		/* Next sequence number to expect */
+-	uint rxleft = 0;	/* Remaining number of frames allowed */
+-	int sdret;		/* Return code from bcmsdh calls */
+-	u8 txmax;		/* Maximum tx sequence offered */
+-	bool len_consistent;	/* Result of comparing readahead len and
+-					 len from hw-hdr */
+-	u8 *rxbuf;
+-	int ifidx = 0;
+-	uint rxcount = 0;	/* Total frames read */
+-
+-#if defined(DHD_DEBUG) || defined(SDTEST)
+-	bool sdtest = false;	/* To limit message spew from test mode */
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(maxframes);
+-
+-#ifdef SDTEST
+-	/* Allow pktgen to override maxframes */
+-	if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) {
+-		maxframes = bus->pktgen_count;
+-		sdtest = true;
+-	}
+-#endif
+-
+-	/* Not finished unless we encounter no more frames indication */
+-	*finished = false;
+-
+-	for (rxseq = bus->rx_seq, rxleft = maxframes;
+-	     !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN;
+-	     rxseq++, rxleft--) {
+-
+-		/* Handle glomming separately */
+-		if (bus->glom || bus->glomd) {
+-			u8 cnt;
+-			DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n",
+-				  __func__, bus->glomd, bus->glom));
+-			cnt = dhdsdio_rxglom(bus, rxseq);
+-			DHD_GLOM(("%s: rxglom returned %d\n", __func__, cnt));
+-			rxseq += cnt - 1;
+-			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
+-			continue;
+-		}
+-
+-		/* Try doing single read if we can */
+-		if (dhd_readahead && bus->nextlen) {
+-			u16 nextlen = bus->nextlen;
+-			bus->nextlen = 0;
+-
+-			if (bus->bus == SPI_BUS) {
+-				rdlen = len = nextlen;
+-			} else {
+-				rdlen = len = nextlen << 4;
+-
+-				/* Pad read to blocksize for efficiency */
+-				if (bus->roundup && bus->blocksize
+-				    && (rdlen > bus->blocksize)) {
+-					pad =
+-					    bus->blocksize -
+-					    (rdlen % bus->blocksize);
+-					if ((pad <= bus->roundup)
+-					    && (pad < bus->blocksize)
+-					    && ((rdlen + pad + firstread) <
+-						MAX_RX_DATASZ))
+-						rdlen += pad;
+-				} else if (rdlen % DHD_SDALIGN) {
+-					rdlen +=
+-					    DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-				}
+-			}
+-
+-			/* We use bus->rxctl buffer in WinXP for initial
+-			 * control pkt receives.
+-			 * Later we use buffer-poll for data as well
+-			 * as control packets.
+-			 * This is required because dhd receives full
+-			 * frame in gSPI unlike SDIO.
+-			 * After the frame is received we have to
+-			 * distinguish whether it is data
+-			 * or non-data frame.
+-			 */
+-			/* Allocate a packet buffer */
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			pkt = bcm_pkt_buf_get_skb(rdlen + DHD_SDALIGN);
+-			if (!pkt) {
+-				if (bus->bus == SPI_BUS) {
+-					bus->usebufpool = false;
+-					bus->rxctl = bus->rxbuf;
+-					if (dhd_alignctl) {
+-						bus->rxctl += firstread;
+-						pad = ((unsigned long)bus->rxctl %
+-						      DHD_SDALIGN);
+-						if (pad)
+-							bus->rxctl +=
+-							    (DHD_SDALIGN - pad);
+-						bus->rxctl -= firstread;
+-					}
+-					ASSERT(bus->rxctl >= bus->rxbuf);
+-					rxbuf = bus->rxctl;
+-					/* Read the entire frame */
+-					sdret = bcmsdh_recv_buf(bus,
+-						    bcmsdh_cur_sbwad(sdh),
+-						    SDIO_FUNC_2, F2SYNC,
+-						    rxbuf, rdlen,
+-						    NULL, NULL, NULL);
+-					bus->f2rxdata++;
+-					ASSERT(sdret != -BCME_PENDING);
+-
+-					/* Control frame failures need
+-					 retransmission */
+-					if (sdret < 0) {
+-						DHD_ERROR(("%s: read %d control bytes failed: %d\n",
+-							__func__,
+-							rdlen, sdret));
+-						/* dhd.rx_ctlerrs is higher */
+-						bus->rxc_errors++;
+-						dhd_os_sdunlock_rxq(bus->dhd);
+-						dhdsdio_rxfail(bus, true,
+-						       (bus->bus ==
+-							SPI_BUS) ? false
+-						       : true);
+-						continue;
+-					}
+-				} else {
+-					/* Give up on data,
+-					request rtx of events */
+-					DHD_ERROR(("%s (nextlen): "
+-						   "bcm_pkt_buf_get_skb failed:"
+-						   " len %d rdlen %d expected"
+-						   " rxseq %d\n", __func__,
+-						   len, rdlen, rxseq));
+-					/* Just go try again w/normal
+-					header read */
+-					dhd_os_sdunlock_rxq(bus->dhd);
+-					continue;
+-				}
+-			} else {
+-				if (bus->bus == SPI_BUS)
+-					bus->usebufpool = true;
+-
+-				ASSERT(!(pkt->prev));
+-				PKTALIGN(pkt, rdlen, DHD_SDALIGN);
+-				rxbuf = (u8 *) (pkt->data);
+-				/* Read the entire frame */
+-				sdret = bcmsdh_recv_buf(bus,
+-						bcmsdh_cur_sbwad(sdh),
+-						SDIO_FUNC_2, F2SYNC,
+-						rxbuf, rdlen,
+-						pkt, NULL, NULL);
+-				bus->f2rxdata++;
+-				ASSERT(sdret != -BCME_PENDING);
+-
+-				if (sdret < 0) {
+-					DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n",
+-						__func__, rdlen, sdret));
+-					bcm_pkt_buf_free_skb(pkt);
+-					bus->dhd->rx_errors++;
+-					dhd_os_sdunlock_rxq(bus->dhd);
+-					/* Force retry w/normal header read.
+-					 * Don't attempt NAK for
+-					 * gSPI
+-					 */
+-					dhdsdio_rxfail(bus, true,
+-						       (bus->bus ==
+-							SPI_BUS) ? false :
+-						       true);
+-					continue;
+-				}
+-			}
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-
+-			/* Now check the header */
+-			memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
+-
+-			/* Extract hardware header fields */
+-			len = get_unaligned_le16(bus->rxhdr);
+-			check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
+-
+-			/* All zeros means readahead info was bad */
+-			if (!(len | check)) {
+-				DHD_INFO(("%s (nextlen): read zeros in HW "
+-					"header???\n", __func__));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Validate check bytes */
+-			if ((u16)~(len ^ check)) {
+-				DHD_ERROR(("%s (nextlen): HW hdr error:"
+-					" nextlen/len/check"
+-					" 0x%04x/0x%04x/0x%04x\n",
+-					__func__, nextlen, len, check));
+-				bus->rx_badhdr++;
+-				dhdsdio_rxfail(bus, false, false);
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Validate frame length */
+-			if (len < SDPCM_HDRLEN) {
+-				DHD_ERROR(("%s (nextlen): HW hdr length "
+-					"invalid: %d\n", __func__, len));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Check for consistency withreadahead info */
+-			len_consistent = (nextlen != (roundup(len, 16) >> 4));
+-			if (len_consistent) {
+-				/* Mismatch, force retry w/normal
+-					header (may be >4K) */
+-				DHD_ERROR(("%s (nextlen): mismatch, "
+-					"nextlen %d len %d rnd %d; "
+-					"expected rxseq %d\n",
+-					__func__, nextlen,
+-					len, roundup(len, 16), rxseq));
+-				dhdsdio_rxfail(bus, true, (bus->bus != SPI_BUS));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Extract software header fields */
+-			chan = SDPCM_PACKET_CHANNEL(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			seq = SDPCM_PACKET_SEQUENCE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			txmax = SDPCM_WINDOW_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-			bus->nextlen =
+-			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
+-				       SDPCM_NEXTLEN_OFFSET];
+-			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-				DHD_INFO(("%s (nextlen): got frame w/nextlen too large" " (%d), seq %d\n",
+-					__func__, bus->nextlen, seq));
+-				bus->nextlen = 0;
+-			}
+-
+-			bus->dhd->rx_readahead_cnt++;
+-
+-			/* Handle Flow Control */
+-			fcbits = SDPCM_FCMASK_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-			if (bus->flowcontrol != fcbits) {
+-				if (~bus->flowcontrol & fcbits)
+-					bus->fc_xoff++;
+-
+-				if (bus->flowcontrol & ~fcbits)
+-					bus->fc_xon++;
+-
+-				bus->fc_rcvd++;
+-				bus->flowcontrol = fcbits;
+-			}
+-
+-			/* Check and update sequence number */
+-			if (rxseq != seq) {
+-				DHD_INFO(("%s (nextlen): rx_seq %d, expected "
+-					"%d\n", __func__, seq, rxseq));
+-				bus->rx_badseq++;
+-				rxseq = seq;
+-			}
+-
+-			/* Check window for sanity */
+-			if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-				DHD_ERROR(("%s: got unlikely tx max %d with "
+-					"tx_seq %d\n",
+-					__func__, txmax, bus->tx_seq));
+-				txmax = bus->tx_seq + 2;
+-			}
+-			bus->tx_max = txmax;
+-
+-#ifdef DHD_DEBUG
+-			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-				printk(KERN_DEBUG "Rx Data:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     rxbuf, len);
+-			} else if (DHD_HDRS_ON()) {
+-				printk(KERN_DEBUG "RxHdr:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     bus->rxhdr, SDPCM_HDRLEN);
+-			}
+-#endif
+-
+-			if (chan == SDPCM_CONTROL_CHANNEL) {
+-				if (bus->bus == SPI_BUS) {
+-					dhdsdio_read_control(bus, rxbuf, len,
+-							     doff);
+-				} else {
+-					DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n",
+-						__func__, seq));
+-					/* Force retry w/normal header read */
+-					bus->nextlen = 0;
+-					dhdsdio_rxfail(bus, false, true);
+-				}
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
+-				DHD_ERROR(("Received %d bytes on %d channel. Running out of " "rx pktbuf's or not yet malloced.\n",
+-					len, chan));
+-				continue;
+-			}
+-
+-			/* Validate data offset */
+-			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
+-				DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n",
+-					__func__, doff, len, SDPCM_HDRLEN));
+-				dhdsdio_rxfail(bus, false, false);
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* All done with this one -- now deliver the packet */
+-			goto deliver;
+-		}
+-		/* gSPI frames should not be handled in fractions */
+-		if (bus->bus == SPI_BUS)
+-			break;
+-
+-		/* Read frame header (hardware and software) */
+-		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh),
+-				SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread,
+-				NULL, NULL, NULL);
+-		bus->f2rxhdrs++;
+-		ASSERT(sdret != -BCME_PENDING);
+-
+-		if (sdret < 0) {
+-			DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__,
+-				   sdret));
+-			bus->rx_hdrfail++;
+-			dhdsdio_rxfail(bus, true, true);
+-			continue;
+-		}
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() || DHD_HDRS_ON()) {
+-			printk(KERN_DEBUG "RxHdr:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     bus->rxhdr, SDPCM_HDRLEN);
+-		}
+-#endif
+-
+-		/* Extract hardware header fields */
+-		len = get_unaligned_le16(bus->rxhdr);
+-		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
+-
+-		/* All zeros means no more frames */
+-		if (!(len | check)) {
+-			*finished = true;
+-			break;
+-		}
+-
+-		/* Validate check bytes */
+-		if ((u16) ~(len ^ check)) {
+-			DHD_ERROR(("%s: HW hdr err: len/check 0x%04x/0x%04x\n",
+-				__func__, len, check));
+-			bus->rx_badhdr++;
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		/* Validate frame length */
+-		if (len < SDPCM_HDRLEN) {
+-			DHD_ERROR(("%s: HW hdr length invalid: %d\n",
+-				   __func__, len));
+-			continue;
+-		}
+-
+-		/* Extract software header fields */
+-		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-		/* Validate data offset */
+-		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
+-			DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d "
+-				"seq %d\n",
+-				__func__, doff, len, SDPCM_HDRLEN, seq));
+-			bus->rx_badhdr++;
+-			ASSERT(0);
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		/* Save the readahead length if there is one */
+-		bus->nextlen =
+-		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+-		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-			DHD_INFO(("%s (nextlen): got frame w/nextlen too large "
+-				"(%d), seq %d\n",
+-				__func__, bus->nextlen, seq));
+-			bus->nextlen = 0;
+-		}
+-
+-		/* Handle Flow Control */
+-		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-		if (bus->flowcontrol != fcbits) {
+-			if (~bus->flowcontrol & fcbits)
+-				bus->fc_xoff++;
+-
+-			if (bus->flowcontrol & ~fcbits)
+-				bus->fc_xon++;
+-
+-			bus->fc_rcvd++;
+-			bus->flowcontrol = fcbits;
+-		}
+-
+-		/* Check and update sequence number */
+-		if (rxseq != seq) {
+-			DHD_INFO(("%s: rx_seq %d, expected %d\n", __func__,
+-				  seq, rxseq));
+-			bus->rx_badseq++;
+-			rxseq = seq;
+-		}
+-
+-		/* Check window for sanity */
+-		if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
+-				__func__, txmax, bus->tx_seq));
+-			txmax = bus->tx_seq + 2;
+-		}
+-		bus->tx_max = txmax;
+-
+-		/* Call a separate function for control frames */
+-		if (chan == SDPCM_CONTROL_CHANNEL) {
+-			dhdsdio_read_control(bus, bus->rxhdr, len, doff);
+-			continue;
+-		}
+-
+-		ASSERT((chan == SDPCM_DATA_CHANNEL)
+-		       || (chan == SDPCM_EVENT_CHANNEL)
+-		       || (chan == SDPCM_TEST_CHANNEL)
+-		       || (chan == SDPCM_GLOM_CHANNEL));
+-
+-		/* Length to read */
+-		rdlen = (len > firstread) ? (len - firstread) : 0;
+-
+-		/* May pad read to blocksize for efficiency */
+-		if (bus->roundup && bus->blocksize &&
+-			(rdlen > bus->blocksize)) {
+-			pad = bus->blocksize - (rdlen % bus->blocksize);
+-			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+-			    ((rdlen + pad + firstread) < MAX_RX_DATASZ))
+-				rdlen += pad;
+-		} else if (rdlen % DHD_SDALIGN) {
+-			rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-		}
+-
+-		/* Satisfy length-alignment requirements */
+-		if (forcealign && (rdlen & (ALIGNMENT - 1)))
+-			rdlen = roundup(rdlen, ALIGNMENT);
+-
+-		if ((rdlen + firstread) > MAX_RX_DATASZ) {
+-			/* Too long -- skip this frame */
+-			DHD_ERROR(("%s: too long: len %d rdlen %d\n",
+-				   __func__, len, rdlen));
+-			bus->dhd->rx_errors++;
+-			bus->rx_toolong++;
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		dhd_os_sdlock_rxq(bus->dhd);
+-		pkt = bcm_pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN);
+-		if (!pkt) {
+-			/* Give up on data, request rtx of events */
+-			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed: rdlen %d "
+-				"chan %d\n", __func__, rdlen, chan));
+-			bus->dhd->rx_dropped++;
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			dhdsdio_rxfail(bus, false, RETRYCHAN(chan));
+-			continue;
+-		}
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-
+-		ASSERT(!(pkt->prev));
+-
+-		/* Leave room for what we already read, and align remainder */
+-		ASSERT(firstread < pkt->len);
+-		skb_pull(pkt, firstread);
+-		PKTALIGN(pkt, rdlen, DHD_SDALIGN);
+-
+-		/* Read the remaining frame data */
+-		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, ((u8 *) (pkt->data)), rdlen,
+-					pkt, NULL, NULL);
+-		bus->f2rxdata++;
+-		ASSERT(sdret != -BCME_PENDING);
+-
+-		if (sdret < 0) {
+-			DHD_ERROR(("%s: read %d %s bytes failed: %d\n",
+-				   __func__, rdlen,
+-				   ((chan ==
+-				     SDPCM_EVENT_CHANNEL) ? "event" : ((chan ==
+-					SDPCM_DATA_CHANNEL)
+-				       ? "data" : "test")),
+-				   sdret));
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			bus->dhd->rx_errors++;
+-			dhdsdio_rxfail(bus, true, RETRYCHAN(chan));
+-			continue;
+-		}
+-
+-		/* Copy the already-read portion */
+-		skb_push(pkt, firstread);
+-		memcpy(pkt->data, bus->rxhdr, firstread);
+-
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-			printk(KERN_DEBUG "Rx Data:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     pkt->data, len);
+-		}
+-#endif
+-
+-deliver:
+-		/* Save superframe descriptor and allocate packet frame */
+-		if (chan == SDPCM_GLOM_CHANNEL) {
+-			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
+-				DHD_GLOM(("%s: glom descriptor, %d bytes:\n",
+-					__func__, len));
+-#ifdef DHD_DEBUG
+-				if (DHD_GLOM_ON()) {
+-					printk(KERN_DEBUG "Glom Data:\n");
+-					print_hex_dump_bytes("",
+-							     DUMP_PREFIX_OFFSET,
+-							     pkt->data, len);
+-				}
+-#endif
+-				__skb_trim(pkt, len);
+-				ASSERT(doff == SDPCM_HDRLEN);
+-				skb_pull(pkt, SDPCM_HDRLEN);
+-				bus->glomd = pkt;
+-			} else {
+-				DHD_ERROR(("%s: glom superframe w/o "
+-					"descriptor!\n", __func__));
+-				dhdsdio_rxfail(bus, false, false);
+-			}
+-			continue;
+-		}
+-
+-		/* Fill in packet len and prio, deliver upward */
+-		__skb_trim(pkt, len);
+-		skb_pull(pkt, doff);
+-
+-#ifdef SDTEST
+-		/* Test channel packets are processed separately */
+-		if (chan == SDPCM_TEST_CHANNEL) {
+-			dhdsdio_testrcv(bus, pkt, seq);
+-			continue;
+-		}
+-#endif				/* SDTEST */
+-
+-		if (pkt->len == 0) {
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			continue;
+-		} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) {
+-			DHD_ERROR(("%s: rx protocol error\n", __func__));
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			bus->dhd->rx_errors++;
+-			continue;
+-		}
+-
+-		/* Unlock during rx call */
+-		dhd_os_sdunlock(bus->dhd);
+-		dhd_rx_frame(bus->dhd, ifidx, pkt, 1);
+-		dhd_os_sdlock(bus->dhd);
+-	}
+-	rxcount = maxframes - rxleft;
+-#ifdef DHD_DEBUG
+-	/* Message if we hit the limit */
+-	if (!rxleft && !sdtest)
+-		DHD_DATA(("%s: hit rx limit of %d frames\n", __func__,
+-			  maxframes));
+-	else
+-#endif				/* DHD_DEBUG */
+-		DHD_DATA(("%s: processed %d frames\n", __func__, rxcount));
+-	/* Back off rxseq if awaiting rtx, update rx_seq */
+-	if (bus->rxskip)
+-		rxseq--;
+-	bus->rx_seq = rxseq;
+-
+-	return rxcount;
+-}
+-
+-static u32 dhdsdio_hostmail(dhd_bus_t *bus)
+-{
+-	sdpcmd_regs_t *regs = bus->regs;
+-	u32 intstatus = 0;
+-	u32 hmb_data;
+-	u8 fcbits;
+-	uint retries = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Read mailbox data and ack that we did so */
+-	R_SDREG(hmb_data, &regs->tohostmailboxdata, retries);
+-	if (retries <= retry_limit)
+-		W_SDREG(SMB_INT_ACK, &regs->tosbmailbox, retries);
+-	bus->f1regdata += 2;
+-
+-	/* Dongle recomposed rx frames, accept them again */
+-	if (hmb_data & HMB_DATA_NAKHANDLED) {
+-		DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n",
+-			  bus->rx_seq));
+-		if (!bus->rxskip)
+-			DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __func__));
+-
+-		bus->rxskip = false;
+-		intstatus |= I_HMB_FRAME_IND;
+-	}
+-
+-	/*
+-	 * DEVREADY does not occur with gSPI.
+-	 */
+-	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
+-		bus->sdpcm_ver =
+-		    (hmb_data & HMB_DATA_VERSION_MASK) >>
+-		    HMB_DATA_VERSION_SHIFT;
+-		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
+-			DHD_ERROR(("Version mismatch, dongle reports %d, "
+-				"expecting %d\n",
+-				bus->sdpcm_ver, SDPCM_PROT_VERSION));
+-		else
+-			DHD_INFO(("Dongle ready, protocol version %d\n",
+-				  bus->sdpcm_ver));
+-	}
+-
+-	/*
+-	 * Flow Control has been moved into the RX headers and this out of band
+-	 * method isn't used any more.
+-	 * remaining backward compatible with older dongles.
+-	 */
+-	if (hmb_data & HMB_DATA_FC) {
+-		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
+-							HMB_DATA_FCDATA_SHIFT;
+-
+-		if (fcbits & ~bus->flowcontrol)
+-			bus->fc_xoff++;
+-
+-		if (bus->flowcontrol & ~fcbits)
+-			bus->fc_xon++;
+-
+-		bus->fc_rcvd++;
+-		bus->flowcontrol = fcbits;
+-	}
+-
+-	/* Shouldn't be any others */
+-	if (hmb_data & ~(HMB_DATA_DEVREADY |
+-			 HMB_DATA_NAKHANDLED |
+-			 HMB_DATA_FC |
+-			 HMB_DATA_FWREADY |
+-			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
+-		DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data));
+-	}
+-
+-	return intstatus;
+-}
+-
+-bool dhdsdio_dpc(dhd_bus_t *bus)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	u32 intstatus, newstatus = 0;
+-	uint retries = 0;
+-	uint rxlimit = dhd_rxbound;	/* Rx frames to read before resched */
+-	uint txlimit = dhd_txbound;	/* Tx frames to send before resched */
+-	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
+-	bool rxdone = true;	/* Flag for no more read data */
+-	bool resched = false;	/* Flag indicating resched wanted */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Start with leftover status bits */
+-	intstatus = bus->intstatus;
+-
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* If waiting for HTAVAIL, check status */
+-	if (bus->clkstate == CLK_PENDING) {
+-		int err;
+-		u8 clkctl, devctl = 0;
+-
+-#ifdef DHD_DEBUG
+-		/* Check for inconsistent device control */
+-		devctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+-		if (err) {
+-			DHD_ERROR(("%s: error reading DEVCTL: %d\n",
+-				   __func__, err));
+-			bus->dhd->busstate = DHD_BUS_DOWN;
+-		} else {
+-			ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY);
+-		}
+-#endif				/* DHD_DEBUG */
+-
+-		/* Read CSR, if clock on switch to AVAIL, else ignore */
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-		if (err) {
+-			DHD_ERROR(("%s: error reading CSR: %d\n", __func__,
+-				   err));
+-			bus->dhd->busstate = DHD_BUS_DOWN;
+-		}
+-
+-		DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl,
+-			  clkctl));
+-
+-		if (SBSDIO_HTAV(clkctl)) {
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			if (err) {
+-				DHD_ERROR(("%s: error reading DEVCTL: %d\n",
+-					   __func__, err));
+-				bus->dhd->busstate = DHD_BUS_DOWN;
+-			}
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-			if (err) {
+-				DHD_ERROR(("%s: error writing DEVCTL: %d\n",
+-					   __func__, err));
+-				bus->dhd->busstate = DHD_BUS_DOWN;
+-			}
+-			bus->clkstate = CLK_AVAIL;
+-		} else {
+-			goto clkwait;
+-		}
+-	}
+-
+-	BUS_WAKE(bus);
+-
+-	/* Make sure backplane clock is on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, true);
+-	if (bus->clkstate == CLK_PENDING)
+-		goto clkwait;
+-
+-	/* Pending interrupt indicates new device status */
+-	if (bus->ipend) {
+-		bus->ipend = false;
+-		R_SDREG(newstatus, &regs->intstatus, retries);
+-		bus->f1regdata++;
+-		if (bcmsdh_regfail(bus->sdh))
+-			newstatus = 0;
+-		newstatus &= bus->hostintmask;
+-		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
+-		if (newstatus) {
+-			W_SDREG(newstatus, &regs->intstatus, retries);
+-			bus->f1regdata++;
+-		}
+-	}
+-
+-	/* Merge new bits with previous */
+-	intstatus |= newstatus;
+-	bus->intstatus = 0;
+-
+-	/* Handle flow-control change: read new state in case our ack
+-	 * crossed another change interrupt.  If change still set, assume
+-	 * FC ON for safety, let next loop through do the debounce.
+-	 */
+-	if (intstatus & I_HMB_FC_CHANGE) {
+-		intstatus &= ~I_HMB_FC_CHANGE;
+-		W_SDREG(I_HMB_FC_CHANGE, &regs->intstatus, retries);
+-		R_SDREG(newstatus, &regs->intstatus, retries);
+-		bus->f1regdata += 2;
+-		bus->fcstate =
+-		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
+-		intstatus |= (newstatus & bus->hostintmask);
+-	}
+-
+-	/* Handle host mailbox indication */
+-	if (intstatus & I_HMB_HOST_INT) {
+-		intstatus &= ~I_HMB_HOST_INT;
+-		intstatus |= dhdsdio_hostmail(bus);
+-	}
+-
+-	/* Generally don't ask for these, can get CRC errors... */
+-	if (intstatus & I_WR_OOSYNC) {
+-		DHD_ERROR(("Dongle reports WR_OOSYNC\n"));
+-		intstatus &= ~I_WR_OOSYNC;
+-	}
+-
+-	if (intstatus & I_RD_OOSYNC) {
+-		DHD_ERROR(("Dongle reports RD_OOSYNC\n"));
+-		intstatus &= ~I_RD_OOSYNC;
+-	}
+-
+-	if (intstatus & I_SBINT) {
+-		DHD_ERROR(("Dongle reports SBINT\n"));
+-		intstatus &= ~I_SBINT;
+-	}
+-
+-	/* Would be active due to wake-wlan in gSPI */
+-	if (intstatus & I_CHIPACTIVE) {
+-		DHD_INFO(("Dongle reports CHIPACTIVE\n"));
+-		intstatus &= ~I_CHIPACTIVE;
+-	}
+-
+-	/* Ignore frame indications if rxskip is set */
+-	if (bus->rxskip)
+-		intstatus &= ~I_HMB_FRAME_IND;
+-
+-	/* On frame indication, read available frames */
+-	if (PKT_AVAILABLE()) {
+-		framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone);
+-		if (rxdone || bus->rxskip)
+-			intstatus &= ~I_HMB_FRAME_IND;
+-		rxlimit -= min(framecnt, rxlimit);
+-	}
+-
+-	/* Keep still-pending events for next scheduling */
+-	bus->intstatus = intstatus;
+-
+-clkwait:
+-#if defined(OOB_INTR_ONLY)
+-	bcmsdh_oob_intr_set(1);
+-#endif				/* (OOB_INTR_ONLY) */
+-	/* Re-enable interrupts to detect new device events (mailbox, rx frame)
+-	 * or clock availability.  (Allows tx loop to check ipend if desired.)
+-	 * (Unless register access seems hosed, as we may not be able to ACK...)
+-	 */
+-	if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
+-		DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
+-			  __func__, rxdone, framecnt));
+-		bus->intdis = false;
+-		bcmsdh_intr_enable(sdh);
+-	}
+-
+-	if (DATAOK(bus) && bus->ctrl_frame_stat &&
+-		(bus->clkstate == CLK_AVAIL)) {
+-		int ret, i;
+-
+-		ret =
+-		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, (u8 *) bus->ctrl_frame_buf,
+-					(u32) bus->ctrl_frame_len, NULL,
+-					NULL, NULL);
+-		ASSERT(ret != -BCME_PENDING);
+-
+-		if (ret < 0) {
+-			/* On failure, abort the command and
+-				terminate the frame */
+-			DHD_INFO(("%s: sdio error %d, abort command and "
+-				"terminate frame.\n", __func__, ret));
+-			bus->tx_sderrs++;
+-
+-			bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
+-					 NULL);
+-			bus->f1regdata++;
+-
+-			for (i = 0; i < 3; i++) {
+-				u8 hi, lo;
+-				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCHI,
+-						     NULL);
+-				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCLO,
+-						     NULL);
+-				bus->f1regdata += 2;
+-				if ((hi == 0) && (lo == 0))
+-					break;
+-			}
+-
+-		}
+-		if (ret == 0)
+-			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-
+-		DHD_INFO(("Return_dpc value is : %d\n", ret));
+-		bus->ctrl_frame_stat = false;
+-		dhd_wait_event_wakeup(bus->dhd);
+-	}
+-	/* Send queued frames (limit 1 if rx may still be pending) */
+-	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
+-		 bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
+-		 && DATAOK(bus)) {
+-		framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax);
+-		framecnt = dhdsdio_sendfromq(bus, framecnt);
+-		txlimit -= framecnt;
+-	}
+-
+-	/* Resched if events or tx frames are pending,
+-		 else await next interrupt */
+-	/* On failed register access, all bets are off:
+-		 no resched or interrupts */
+-	if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) {
+-		DHD_ERROR(("%s: failed backplane access over SDIO, halting "
+-			"operation %d\n", __func__, bcmsdh_regfail(sdh)));
+-		bus->dhd->busstate = DHD_BUS_DOWN;
+-		bus->intstatus = 0;
+-	} else if (bus->clkstate == CLK_PENDING) {
+-		DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting "
+-			"I_CHIPACTIVE interrupt\n", __func__));
+-		resched = true;
+-	} else if (bus->intstatus || bus->ipend ||
+-		(!bus->fcstate && bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
+-			DATAOK(bus)) || PKT_AVAILABLE()) {
+-		resched = true;
+-	}
+-
+-	bus->dpc_sched = resched;
+-
+-	/* If we're done for now, turn off clock request. */
+-	if ((bus->clkstate != CLK_PENDING)
+-	    && bus->idletime == DHD_IDLE_IMMEDIATE) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return resched;
+-}
+-
+-bool dhd_bus_dpc(struct dhd_bus *bus)
+-{
+-	bool resched;
+-
+-	/* Call the DPC directly. */
+-	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
+-	resched = dhdsdio_dpc(bus);
+-
+-	return resched;
+-}
+-
+-void dhdsdio_isr(void *arg)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *) arg;
+-	bcmsdh_info_t *sdh;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (!bus) {
+-		DHD_ERROR(("%s : bus is null pointer , exit\n", __func__));
+-		return;
+-	}
+-	sdh = bus->sdh;
+-
+-	if (bus->dhd->busstate == DHD_BUS_DOWN) {
+-		DHD_ERROR(("%s : bus is down. we have nothing to do\n",
+-			   __func__));
+-		return;
+-	}
+-	/* Count the interrupt call */
+-	bus->intrcount++;
+-	bus->ipend = true;
+-
+-	/* Shouldn't get this interrupt if we're sleeping? */
+-	if (bus->sleeping) {
+-		DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n"));
+-		return;
+-	}
+-
+-	/* Disable additional interrupts (is this needed now)? */
+-	if (bus->intr)
+-		DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-	else
+-		DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n"));
+-
+-	bcmsdh_intr_disable(sdh);
+-	bus->intdis = true;
+-
+-#if defined(SDIO_ISR_THREAD)
+-	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
+-	while (dhdsdio_dpc(bus))
+-		;
+-#else
+-	bus->dpc_sched = true;
+-	dhd_sched_dpc(bus->dhd);
+-#endif
+-
+-}
+-
+-#ifdef SDTEST
+-static void dhdsdio_pktgen_init(dhd_bus_t *bus)
+-{
+-	/* Default to specified length, or full range */
+-	if (dhd_pktgen_len) {
+-		bus->pktgen_maxlen = min(dhd_pktgen_len, MAX_PKTGEN_LEN);
+-		bus->pktgen_minlen = bus->pktgen_maxlen;
+-	} else {
+-		bus->pktgen_maxlen = MAX_PKTGEN_LEN;
+-		bus->pktgen_minlen = 0;
+-	}
+-	bus->pktgen_len = (u16) bus->pktgen_minlen;
+-
+-	/* Default to per-watchdog burst with 10s print time */
+-	bus->pktgen_freq = 1;
+-	bus->pktgen_print = 10000 / dhd_watchdog_ms;
+-	bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000;
+-
+-	/* Default to echo mode */
+-	bus->pktgen_mode = DHD_PKTGEN_ECHO;
+-	bus->pktgen_stop = 1;
+-}
+-
+-static void dhdsdio_pktgen(dhd_bus_t *bus)
+-{
+-	struct sk_buff *pkt;
+-	u8 *data;
+-	uint pktcount;
+-	uint fillbyte;
+-	u16 len;
+-
+-	/* Display current count if appropriate */
+-	if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) {
+-		bus->pktgen_ptick = 0;
+-		printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n",
+-		       __func__, bus->pktgen_sent, bus->pktgen_rcvd);
+-	}
+-
+-	/* For recv mode, just make sure dongle has started sending */
+-	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+-		if (!bus->pktgen_rcvd)
+-			dhdsdio_sdtest_set(bus, true);
+-		return;
+-	}
+-
+-	/* Otherwise, generate or request the specified number of packets */
+-	for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) {
+-		/* Stop if total has been reached */
+-		if (bus->pktgen_total
+-		    && (bus->pktgen_sent >= bus->pktgen_total)) {
+-			bus->pktgen_count = 0;
+-			break;
+-		}
+-
+-		/* Allocate an appropriate-sized packet */
+-		len = bus->pktgen_len;
+-		pkt = bcm_pkt_buf_get_skb(
+-			(len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN),
+-			true);
+-		if (!pkt) {
+-			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n",
+-				__func__));
+-			break;
+-		}
+-		PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN),
+-			 DHD_SDALIGN);
+-		data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-
+-		/* Write test header cmd and extra based on mode */
+-		switch (bus->pktgen_mode) {
+-		case DHD_PKTGEN_ECHO:
+-			*data++ = SDPCM_TEST_ECHOREQ;
+-			*data++ = (u8) bus->pktgen_sent;
+-			break;
+-
+-		case DHD_PKTGEN_SEND:
+-			*data++ = SDPCM_TEST_DISCARD;
+-			*data++ = (u8) bus->pktgen_sent;
+-			break;
+-
+-		case DHD_PKTGEN_RXBURST:
+-			*data++ = SDPCM_TEST_BURST;
+-			*data++ = (u8) bus->pktgen_count;
+-			break;
+-
+-		default:
+-			DHD_ERROR(("Unrecognized pktgen mode %d\n",
+-				   bus->pktgen_mode));
+-			bcm_pkt_buf_free_skb(pkt, true);
+-			bus->pktgen_count = 0;
+-			return;
+-		}
+-
+-		/* Write test header length field */
+-		*data++ = (len >> 0);
+-		*data++ = (len >> 8);
+-
+-		/* Then fill in the remainder -- N/A for burst,
+-			 but who cares... */
+-		for (fillbyte = 0; fillbyte < len; fillbyte++)
+-			*data++ =
+-			    SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent);
+-
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-			data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-			printk(KERN_DEBUG "dhdsdio_pktgen: Tx Data:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data,
+-					     pkt->len - SDPCM_HDRLEN);
+-		}
+-#endif
+-
+-		/* Send it */
+-		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) {
+-			bus->pktgen_fail++;
+-			if (bus->pktgen_stop
+-			    && bus->pktgen_stop == bus->pktgen_fail)
+-				bus->pktgen_count = 0;
+-		}
+-		bus->pktgen_sent++;
+-
+-		/* Bump length if not fixed, wrap at max */
+-		if (++bus->pktgen_len > bus->pktgen_maxlen)
+-			bus->pktgen_len = (u16) bus->pktgen_minlen;
+-
+-		/* Special case for burst mode: just send one request! */
+-		if (bus->pktgen_mode == DHD_PKTGEN_RXBURST)
+-			break;
+-	}
+-}
+-
+-static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start)
+-{
+-	struct sk_buff *pkt;
+-	u8 *data;
+-
+-	/* Allocate the packet */
+-	pkt = bcm_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
+-		DHD_SDALIGN, true);
+-	if (!pkt) {
+-		DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", __func__));
+-		return;
+-	}
+-	PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN);
+-	data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-
+-	/* Fill in the test header */
+-	*data++ = SDPCM_TEST_SEND;
+-	*data++ = start;
+-	*data++ = (bus->pktgen_maxlen >> 0);
+-	*data++ = (bus->pktgen_maxlen >> 8);
+-
+-	/* Send it */
+-	if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true))
+-		bus->pktgen_fail++;
+-}
+-
+-static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq)
+-{
+-	u8 *data;
+-	uint pktlen;
+-
+-	u8 cmd;
+-	u8 extra;
+-	u16 len;
+-	u16 offset;
+-
+-	/* Check for min length */
+-	pktlen = pkt->len;
+-	if (pktlen < SDPCM_TEST_HDRLEN) {
+-		DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n",
+-			   pktlen));
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		return;
+-	}
+-
+-	/* Extract header fields */
+-	data = pkt->data;
+-	cmd = *data++;
+-	extra = *data++;
+-	len = *data++;
+-	len += *data++ << 8;
+-
+-	/* Check length for relevant commands */
+-	if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ
+-	    || cmd == SDPCM_TEST_ECHORSP) {
+-		if (pktlen != len + SDPCM_TEST_HDRLEN) {
+-			DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, "
+-				"pktlen %d seq %d" " cmd %d extra %d len %d\n",
+-				pktlen, seq, cmd, extra, len));
+-			bcm_pkt_buf_free_skb(pkt, false);
+-			return;
+-		}
+-	}
+-
+-	/* Process as per command */
+-	switch (cmd) {
+-	case SDPCM_TEST_ECHOREQ:
+-		/* Rx->Tx turnaround ok (even on NDIS w/current
+-			 implementation) */
+-		*(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP;
+-		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) {
+-			bus->pktgen_sent++;
+-		} else {
+-			bus->pktgen_fail++;
+-			bcm_pkt_buf_free_skb(pkt, false);
+-		}
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_ECHORSP:
+-		if (bus->ext_loop) {
+-			bcm_pkt_buf_free_skb(pkt, false);
+-			bus->pktgen_rcvd++;
+-			break;
+-		}
+-
+-		for (offset = 0; offset < len; offset++, data++) {
+-			if (*data != SDPCM_TEST_FILL(offset, extra)) {
+-				DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n",
+-					offset, len,
+-					SDPCM_TEST_FILL(offset, extra), *data));
+-				break;
+-			}
+-		}
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_DISCARD:
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_BURST:
+-	case SDPCM_TEST_SEND:
+-	default:
+-		DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, "
+-			"pktlen %d seq %d" " cmd %d extra %d len %d\n",
+-			pktlen, seq, cmd, extra, len));
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		break;
+-	}
+-
+-	/* For recv mode, stop at limie (and tell dongle to stop sending) */
+-	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+-		if (bus->pktgen_total
+-		    && (bus->pktgen_rcvd >= bus->pktgen_total)) {
+-			bus->pktgen_count = 0;
+-			dhdsdio_sdtest_set(bus, false);
+-		}
+-	}
+-}
+-#endif				/* SDTEST */
+-
+-extern bool dhd_bus_watchdog(dhd_pub_t *dhdp)
+-{
+-	dhd_bus_t *bus;
+-
+-	DHD_TIMER(("%s: Enter\n", __func__));
+-
+-	bus = dhdp->bus;
+-
+-	if (bus->dhd->dongle_reset)
+-		return false;
+-
+-	/* Ignore the timer if simulating bus down */
+-	if (bus->sleeping)
+-		return false;
+-
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Poll period: check device if appropriate. */
+-	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
+-		u32 intstatus = 0;
+-
+-		/* Reset poll tick */
+-		bus->polltick = 0;
+-
+-		/* Check device if no interrupts */
+-		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
+-
+-			if (!bus->dpc_sched) {
+-				u8 devpend;
+-				devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
+-							  SDIOD_CCCR_INTPEND,
+-							  NULL);
+-				intstatus =
+-				    devpend & (INTR_STATUS_FUNC1 |
+-					       INTR_STATUS_FUNC2);
+-			}
+-
+-			/* If there is something, make like the ISR and
+-				 schedule the DPC */
+-			if (intstatus) {
+-				bus->pollcnt++;
+-				bus->ipend = true;
+-				if (bus->intr)
+-					bcmsdh_intr_disable(bus->sdh);
+-
+-				bus->dpc_sched = true;
+-				dhd_sched_dpc(bus->dhd);
+-
+-			}
+-		}
+-
+-		/* Update interrupt tracking */
+-		bus->lastintrs = bus->intrcount;
+-	}
+-#ifdef DHD_DEBUG
+-	/* Poll for console output periodically */
+-	if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) {
+-		bus->console.count += dhd_watchdog_ms;
+-		if (bus->console.count >= dhd_console_ms) {
+-			bus->console.count -= dhd_console_ms;
+-			/* Make sure backplane clock is on */
+-			dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-			if (dhdsdio_readconsole(bus) < 0)
+-				dhd_console_ms = 0;	/* On error,
+-							 stop trying */
+-		}
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef SDTEST
+-	/* Generate packets if configured */
+-	if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) {
+-		/* Make sure backplane clock is on */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-		bus->pktgen_tick = 0;
+-		dhdsdio_pktgen(bus);
+-	}
+-#endif
+-
+-	/* On idle timeout clear activity flag and/or turn off clock */
+-	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+-		if (++bus->idlecount >= bus->idletime) {
+-			bus->idlecount = 0;
+-			if (bus->activity) {
+-				bus->activity = false;
+-				dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-			} else {
+-				dhdsdio_clkctl(bus, CLK_NONE, false);
+-			}
+-		}
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return bus->ipend;
+-}
+-
+-#ifdef DHD_DEBUG
+-extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	u32 addr, val;
+-	int rv;
+-	struct sk_buff *pkt;
+-
+-	/* Address could be zero if CONSOLE := 0 in dongle Makefile */
+-	if (bus->console_addr == 0)
+-		return -ENOTSUPP;
+-
+-	/* Exclusive bus access */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Don't allow input if dongle is in reset */
+-	if (bus->dhd->dongle_reset) {
+-		dhd_os_sdunlock(bus->dhd);
+-		return -EPERM;
+-	}
+-
+-	/* Request clock to allow SDIO accesses */
+-	BUS_WAKE(bus);
+-	/* No pend allowed since txpkt is called later, ht clk has to be on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Zero cbuf_index */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf_idx);
+-	val = cpu_to_le32(0);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Write message into cbuf */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)msg, msglen);
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Write length into vcons_in */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, vcons_in);
+-	val = cpu_to_le32(msglen);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Bump dongle by sending an empty event pkt.
+-	 * sdpcm_sendup (RX) checks for virtual console input.
+-	 */
+-	pkt = bcm_pkt_buf_get_skb(4 + SDPCM_RESERVE);
+-	if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
+-		dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
+-
+-done:
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return rv;
+-}
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef DHD_DEBUG
+-static void dhd_dump_cis(uint fn, u8 *cis)
+-{
+-	uint byte, tag, tdata;
+-	DHD_INFO(("Function %d CIS:\n", fn));
+-
+-	for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) {
+-		if ((byte % 16) == 0)
+-			DHD_INFO(("    "));
+-		DHD_INFO(("%02x ", cis[byte]));
+-		if ((byte % 16) == 15)
+-			DHD_INFO(("\n"));
+-		if (!tdata--) {
+-			tag = cis[byte];
+-			if (tag == 0xff)
+-				break;
+-			else if (!tag)
+-				tdata = 0;
+-			else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT)
+-				tdata = cis[byte + 1] + 1;
+-			else
+-				DHD_INFO(("]"));
+-		}
+-	}
+-	if ((byte % 16) != 15)
+-		DHD_INFO(("\n"));
+-}
+-#endif				/* DHD_DEBUG */
+-
+-static bool dhdsdio_chipmatch(u16 chipid)
+-{
+-	if (chipid == BCM4325_CHIP_ID)
+-		return true;
+-	if (chipid == BCM4329_CHIP_ID)
+-		return true;
+-	if (chipid == BCM4319_CHIP_ID)
+-		return true;
+-	return false;
+-}
+-
+-static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no,
+-			   u16 slot, u16 func, uint bustype, void *regsva,
+-			   void *sdh)
+-{
+-	int ret;
+-	dhd_bus_t *bus;
+-
+-	/* Init global variables at run-time, not as part of the declaration.
+-	 * This is required to support init/de-init of the driver.
+-	 * Initialization
+-	 * of globals as part of the declaration results in non-deterministic
+-	 * behavior since the value of the globals may be different on the
+-	 * first time that the driver is initialized vs subsequent
+-	 * initializations.
+-	 */
+-	dhd_txbound = DHD_TXBOUND;
+-	dhd_rxbound = DHD_RXBOUND;
+-	dhd_alignctl = true;
+-	sd1idle = true;
+-	dhd_readahead = true;
+-	retrydata = false;
+-	dhd_dongle_memsize = 0;
+-	dhd_txminmax = DHD_TXMINMAX;
+-
+-	forcealign = true;
+-
+-	dhd_common_init();
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid));
+-
+-	/* We make assumptions about address window mappings */
+-	ASSERT((unsigned long)regsva == SI_ENUM_BASE);
+-
+-	/* BCMSDH passes venid and devid based on CIS parsing -- but
+-	 * low-power start
+-	 * means early parse could fail, so here we should get either an ID
+-	 * we recognize OR (-1) indicating we must request power first.
+-	 */
+-	/* Check the Vendor ID */
+-	switch (venid) {
+-	case 0x0000:
+-	case PCI_VENDOR_ID_BROADCOM:
+-		break;
+-	default:
+-		DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid));
+-		return NULL;
+-	}
+-
+-	/* Check the Device ID and make sure it's one that we support */
+-	switch (devid) {
+-	case BCM4325_D11DUAL_ID:	/* 4325 802.11a/g id */
+-	case BCM4325_D11G_ID:	/* 4325 802.11g 2.4Ghz band id */
+-	case BCM4325_D11A_ID:	/* 4325 802.11a 5Ghz band id */
+-		DHD_INFO(("%s: found 4325 Dongle\n", __func__));
+-		break;
+-	case BCM4329_D11NDUAL_ID:	/* 4329 802.11n dualband device */
+-	case BCM4329_D11N2G_ID:	/* 4329 802.11n 2.4G device */
+-	case BCM4329_D11N5G_ID:	/* 4329 802.11n 5G device */
+-	case 0x4329:
+-		DHD_INFO(("%s: found 4329 Dongle\n", __func__));
+-		break;
+-	case BCM4319_D11N_ID:	/* 4319 802.11n id */
+-	case BCM4319_D11N2G_ID:	/* 4319 802.11n2g id */
+-	case BCM4319_D11N5G_ID:	/* 4319 802.11n5g id */
+-		DHD_INFO(("%s: found 4319 Dongle\n", __func__));
+-		break;
+-	case 0:
+-		DHD_INFO(("%s: allow device id 0, will check chip internals\n",
+-			  __func__));
+-		break;
+-
+-	default:
+-		DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n",
+-			   __func__, venid, devid));
+-		return NULL;
+-	}
+-
+-	/* Allocate private bus interface state */
+-	bus = kzalloc(sizeof(dhd_bus_t), GFP_ATOMIC);
+-	if (!bus) {
+-		DHD_ERROR(("%s: kmalloc of dhd_bus_t failed\n", __func__));
+-		goto fail;
+-	}
+-	bus->sdh = sdh;
+-	bus->cl_devid = (u16) devid;
+-	bus->bus = DHD_BUS;
+-	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
+-	bus->usebufpool = false;	/* Use bufpool if allocated,
+-					 else use locally malloced rxbuf */
+-
+-	/* attempt to attach to the dongle */
+-	if (!(dhdsdio_probe_attach(bus, sdh, regsva, devid))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Attach to the dhd/OS/network interface */
+-	bus->dhd = dhd_attach(bus, SDPCM_RESERVE);
+-	if (!bus->dhd) {
+-		DHD_ERROR(("%s: dhd_attach failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Allocate buffers */
+-	if (!(dhdsdio_probe_malloc(bus, sdh))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	if (!(dhdsdio_probe_init(bus, sdh))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Register interrupt callback, but mask it (not operational yet). */
+-	DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n",
+-		  __func__));
+-	bcmsdh_intr_disable(sdh);
+-	ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus);
+-	if (ret != 0) {
+-		DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n",
+-			   __func__, ret));
+-		goto fail;
+-	}
+-	DHD_INTR(("%s: registered SDIO interrupt function ok\n", __func__));
+-
+-	DHD_INFO(("%s: completed!!\n", __func__));
+-
+-	/* if firmware path present try to download and bring up bus */
+-	ret = dhd_bus_start(bus->dhd);
+-	if (ret != 0) {
+-		if (ret == -ENOLINK) {
+-			DHD_ERROR(("%s: dongle is not responding\n", __func__));
+-			goto fail;
+-		}
+-	}
+-	/* Ok, have the per-port tell the stack we're open for business */
+-	if (dhd_net_attach(bus->dhd, 0) != 0) {
+-		DHD_ERROR(("%s: Net attach failed!!\n", __func__));
+-		goto fail;
+-	}
+-
+-	return bus;
+-
+-fail:
+-	dhdsdio_release(bus);
+-	return NULL;
+-}
+-
+-static bool
+-dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid)
+-{
+-	u8 clkctl = 0;
+-	int err = 0;
+-
+-	bus->alp_only = true;
+-
+-	/* Return the window to backplane enumeration space for core access */
+-	if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE))
+-		DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __func__));
+-
+-#ifdef DHD_DEBUG
+-	printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
+-	       bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4));
+-
+-#endif				/* DHD_DEBUG */
+-
+-	/*
+-	 * Force PLL off until dhdsdio_chip_attach()
+-	 * programs PLL control regs
+-	 */
+-
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			 DHD_INIT_CLKCTL1, &err);
+-	if (!err)
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-
+-	if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
+-		DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote "
+-			"0x%02x read 0x%02x\n",
+-			err, DHD_INIT_CLKCTL1, clkctl));
+-		goto fail;
+-	}
+-#ifdef DHD_DEBUG
+-	if (DHD_INFO_ON()) {
+-		uint fn, numfn;
+-		u8 *cis[SDIOD_MAX_IOFUNCS];
+-		int err = 0;
+-
+-		numfn = bcmsdh_query_iofnum(sdh);
+-		ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
+-
+-		/* Make sure ALP is available before trying to read CIS */
+-		SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						    SBSDIO_FUNC1_CHIPCLKCSR,
+-						    NULL)),
+-			  !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
+-
+-		/* Now request ALP be put on the bus */
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 DHD_INIT_CLKCTL2, &err);
+-		udelay(65);
+-
+-		for (fn = 0; fn <= numfn; fn++) {
+-			cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC);
+-			if (!cis[fn]) {
+-				DHD_INFO(("dhdsdio_probe: fn %d cis malloc "
+-					"failed\n", fn));
+-				break;
+-			}
+-
+-			err = bcmsdh_cis_read(sdh, fn, cis[fn],
+-						SBSDIO_CIS_SIZE_LIMIT);
+-			if (err) {
+-				DHD_INFO(("dhdsdio_probe: fn %d cis read "
+-					"err %d\n", fn, err));
+-				kfree(cis[fn]);
+-				break;
+-			}
+-			dhd_dump_cis(fn, cis[fn]);
+-		}
+-
+-		while (fn-- > 0) {
+-			ASSERT(cis[fn]);
+-			kfree(cis[fn]);
+-		}
+-
+-		if (err) {
+-			DHD_ERROR(("dhdsdio_probe: error read/parsing CIS\n"));
+-			goto fail;
+-		}
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-	if (dhdsdio_chip_attach(bus, regsva)) {
+-		DHD_ERROR(("%s: dhdsdio_chip_attach failed!\n", __func__));
+-		goto fail;
+-	}
+-
+-	bcmsdh_chipinfo(sdh, bus->ci->chip, bus->ci->chiprev);
+-
+-	if (!dhdsdio_chipmatch((u16) bus->ci->chip)) {
+-		DHD_ERROR(("%s: unsupported chip: 0x%04x\n",
+-			   __func__, bus->ci->chip));
+-		goto fail;
+-	}
+-
+-	dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength);
+-
+-	/* Get info on the ARM and SOCRAM cores... */
+-	if (!DHD_NOPMU(bus)) {
+-		bus->armrev = SBCOREREV(bcmsdh_reg_read(bus->sdh,
+-			CORE_SB(bus->ci->armcorebase, sbidhigh), 4));
+-		bus->orig_ramsize = bus->ci->ramsize;
+-		if (!(bus->orig_ramsize)) {
+-			DHD_ERROR(("%s: failed to find SOCRAM memory!\n",
+-				   __func__));
+-			goto fail;
+-		}
+-		bus->ramsize = bus->orig_ramsize;
+-		if (dhd_dongle_memsize)
+-			dhd_dongle_setmemsize(bus, dhd_dongle_memsize);
+-
+-		DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n",
+-			   bus->ramsize, bus->orig_ramsize));
+-	}
+-
+-	bus->regs = (void *)bus->ci->buscorebase;
+-
+-	/* Set core control so an SDIO reset does a backplane reset */
+-	OR_REG(&bus->regs->corecontrol, CC_BPRESEN);
+-
+-	bcm_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
+-
+-	/* Locate an appropriately-aligned portion of hdrbuf */
+-	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN);
+-
+-	/* Set the poll and/or interrupt flags */
+-	bus->intr = (bool) dhd_intr;
+-	bus->poll = (bool) dhd_poll;
+-	if (bus->poll)
+-		bus->pollrate = 1;
+-
+-	return true;
+-
+-fail:
+-	return false;
+-}
+-
+-static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->maxctl) {
+-		bus->rxblen =
+-		    roundup((bus->dhd->maxctl + SDPCM_HDRLEN),
+-			    ALIGNMENT) + DHD_SDALIGN;
+-		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
+-		if (!(bus->rxbuf)) {
+-			DHD_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n",
+-				   __func__, bus->rxblen));
+-			goto fail;
+-		}
+-	}
+-
+-	/* Allocate buffer to receive glomed packet */
+-	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
+-	if (!(bus->databuf)) {
+-		DHD_ERROR(("%s: kmalloc of %d-byte databuf failed\n",
+-			   __func__, MAX_DATA_BUF));
+-		/* release rxbuf which was already located as above */
+-		if (!bus->rxblen)
+-			kfree(bus->rxbuf);
+-		goto fail;
+-	}
+-
+-	/* Align the buffer */
+-	if ((unsigned long)bus->databuf % DHD_SDALIGN)
+-		bus->dataptr =
+-		    bus->databuf + (DHD_SDALIGN -
+-				    ((unsigned long)bus->databuf % DHD_SDALIGN));
+-	else
+-		bus->dataptr = bus->databuf;
+-
+-	return true;
+-
+-fail:
+-	return false;
+-}
+-
+-static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh)
+-{
+-	s32 fnum;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef SDTEST
+-	dhdsdio_pktgen_init(bus);
+-#endif				/* SDTEST */
+-
+-	/* Disable F2 to clear any intermediate frame state on the dongle */
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1,
+-			 NULL);
+-
+-	bus->dhd->busstate = DHD_BUS_DOWN;
+-	bus->sleeping = false;
+-	bus->rxflow = false;
+-	bus->prev_rxlim_hit = 0;
+-
+-	/* Done with backplane-dependent accesses, can drop clock... */
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
+-
+-	/* ...and initialize clock/power states */
+-	bus->clkstate = CLK_SDONLY;
+-	bus->idletime = (s32) dhd_idletime;
+-	bus->idleclock = DHD_IDLE_ACTIVE;
+-
+-	/* Query the SD clock speed */
+-	if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0,
+-			    &bus->sd_divisor, sizeof(s32),
+-			    false) != 0) {
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor"));
+-		bus->sd_divisor = -1;
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_divisor", bus->sd_divisor));
+-	}
+-
+-	/* Query the SD bus mode */
+-	if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0,
+-			    &bus->sd_mode, sizeof(s32), false) != 0) {
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode"));
+-		bus->sd_mode = -1;
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_mode", bus->sd_mode));
+-	}
+-
+-	/* Query the F2 block size, set roundup accordingly */
+-	fnum = 2;
+-	if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32),
+-			    &bus->blocksize, sizeof(s32), false) != 0) {
+-		bus->blocksize = 0;
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize"));
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_blocksize", bus->blocksize));
+-	}
+-	bus->roundup = min(max_roundup, bus->blocksize);
+-
+-	/* Query if bus module supports packet chaining,
+-		 default to use if supported */
+-	if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0,
+-			    &bus->sd_rxchain, sizeof(s32),
+-			    false) != 0) {
+-		bus->sd_rxchain = false;
+-	} else {
+-		DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n",
+-			  __func__,
+-			  (bus->sd_rxchain ? "supports" : "does not support")));
+-	}
+-	bus->use_rxchain = (bool) bus->sd_rxchain;
+-
+-	return true;
+-}
+-
+-bool
+-dhd_bus_download_firmware(struct dhd_bus *bus, char *fw_path, char *nv_path)
+-{
+-	bool ret;
+-	bus->fw_path = fw_path;
+-	bus->nv_path = nv_path;
+-
+-	ret = dhdsdio_download_firmware(bus, bus->sdh);
+-
+-	return ret;
+-}
+-
+-static bool
+-dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh)
+-{
+-	bool ret;
+-
+-	/* Download the firmware */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	ret = _dhdsdio_download_firmware(bus) == 0;
+-
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-	return ret;
+-}
+-
+-/* Detach and free everything */
+-static void dhdsdio_release(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus) {
+-		/* De-register interrupt handler */
+-		bcmsdh_intr_disable(bus->sdh);
+-		bcmsdh_intr_dereg(bus->sdh);
+-
+-		if (bus->dhd) {
+-			dhd_detach(bus->dhd);
+-			dhdsdio_release_dongle(bus);
+-			bus->dhd = NULL;
+-		}
+-
+-		dhdsdio_release_malloc(bus);
+-
+-		kfree(bus);
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-static void dhdsdio_release_malloc(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd && bus->dhd->dongle_reset)
+-		return;
+-
+-	if (bus->rxbuf) {
+-		kfree(bus->rxbuf);
+-		bus->rxctl = bus->rxbuf = NULL;
+-		bus->rxlen = 0;
+-	}
+-
+-	kfree(bus->databuf);
+-	bus->databuf = NULL;
+-}
+-
+-static void dhdsdio_release_dongle(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd && bus->dhd->dongle_reset)
+-		return;
+-
+-	if (bus->ci) {
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-		dhdsdio_chip_detach(bus);
+-		if (bus->vars && bus->varsz)
+-			kfree(bus->vars);
+-		bus->vars = NULL;
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-static void dhdsdio_disconnect(void *ptr)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *)ptr;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus) {
+-		ASSERT(bus->dhd);
+-		dhdsdio_release(bus);
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-/* Register/Unregister functions are called by the main DHD entry
+- * point (e.g. module insertion) to link with the bus driver, in
+- * order to look for or await the device.
+- */
+-
+-static bcmsdh_driver_t dhd_sdio = {
+-	dhdsdio_probe,
+-	dhdsdio_disconnect
+-};
+-
+-int dhd_bus_register(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	return bcmsdh_register(&dhd_sdio);
+-}
+-
+-void dhd_bus_unregister(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	bcmsdh_unregister();
+-}
+-
+-#ifdef BCMEMBEDIMAGE
+-static int dhdsdio_download_code_array(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-	int offset = 0;
+-
+-	DHD_INFO(("%s: download embedded firmware...\n", __func__));
+-
+-	/* Download image */
+-	while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+-		bcmerror =
+-		    dhdsdio_membytes(bus, true, offset, dlarray + offset,
+-				     MEMBLOCK);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-				"0x%08x\n",
+-				__func__, bcmerror, MEMBLOCK, offset));
+-			goto err;
+-		}
+-
+-		offset += MEMBLOCK;
+-	}
+-
+-	if (offset < sizeof(dlarray)) {
+-		bcmerror = dhdsdio_membytes(bus, true, offset,
+-					    dlarray + offset,
+-					    sizeof(dlarray) - offset);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-				"0x%08x\n", __func__, bcmerror,
+-				sizeof(dlarray) - offset, offset));
+-			goto err;
+-		}
+-	}
+-#ifdef DHD_DEBUG
+-	/* Upload and compare the downloaded code */
+-	{
+-		unsigned char *ularray;
+-
+-		ularray = kmalloc(bus->ramsize, GFP_ATOMIC);
+-		if (!ularray) {
+-			bcmerror = -ENOMEM;
+-			goto err;
+-		}
+-		/* Upload image to verify downloaded contents. */
+-		offset = 0;
+-		memset(ularray, 0xaa, bus->ramsize);
+-		while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+-			bcmerror =
+-			    dhdsdio_membytes(bus, false, offset,
+-					     ularray + offset, MEMBLOCK);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: error %d on reading %d membytes"
+-					" at 0x%08x\n",
+-					__func__, bcmerror, MEMBLOCK, offset));
+-				goto free;
+-			}
+-
+-			offset += MEMBLOCK;
+-		}
+-
+-		if (offset < sizeof(dlarray)) {
+-			bcmerror = dhdsdio_membytes(bus, false, offset,
+-						    ularray + offset,
+-						    sizeof(dlarray) - offset);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n",
+-				__func__, bcmerror,
+-				sizeof(dlarray) - offset, offset));
+-				goto free;
+-			}
+-		}
+-
+-		if (memcmp(dlarray, ularray, sizeof(dlarray))) {
+-			DHD_ERROR(("%s: Downloaded image is corrupted.\n",
+-				   __func__));
+-			ASSERT(0);
+-			goto free;
+-		} else
+-			DHD_ERROR(("%s: Download/Upload/Compare succeeded.\n",
+-				__func__));
+-free:
+-		kfree(ularray);
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-err:
+-	return bcmerror;
+-}
+-#endif				/* BCMEMBEDIMAGE */
+-
+-static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
+-{
+-	int bcmerror = -1;
+-	int offset = 0;
+-	uint len;
+-	void *image = NULL;
+-	u8 *memblock = NULL, *memptr;
+-
+-	DHD_INFO(("%s: download firmware %s\n", __func__, fw_path));
+-
+-	image = dhd_os_open_image(fw_path);
+-	if (image == NULL)
+-		goto err;
+-
+-	memptr = memblock = kmalloc(MEMBLOCK + DHD_SDALIGN, GFP_ATOMIC);
+-	if (memblock == NULL) {
+-		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+-			   __func__, MEMBLOCK));
+-		goto err;
+-	}
+-	if ((u32)(unsigned long)memblock % DHD_SDALIGN)
+-		memptr +=
+-		    (DHD_SDALIGN - ((u32)(unsigned long)memblock % DHD_SDALIGN));
+-
+-	/* Download image */
+-	while ((len =
+-		dhd_os_get_image_block((char *)memptr, MEMBLOCK, image))) {
+-		bcmerror = dhdsdio_membytes(bus, true, offset, memptr, len);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-			"0x%08x\n", __func__, bcmerror, MEMBLOCK, offset));
+-			goto err;
+-		}
+-
+-		offset += MEMBLOCK;
+-	}
+-
+-err:
+-	kfree(memblock);
+-
+-	if (image)
+-		dhd_os_close_image(image);
+-
+-	return bcmerror;
+-}
+-
+-/*
+- * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
+- * and ending in a NUL.
+- * Removes carriage returns, empty lines, comment lines, and converts
+- * newlines to NULs.
+- * Shortens buffer as needed and pads with NULs.  End of buffer is marked
+- * by two NULs.
+-*/
+-
+-static uint process_nvram_vars(char *varbuf, uint len)
+-{
+-	char *dp;
+-	bool findNewline;
+-	int column;
+-	uint buf_len, n;
+-
+-	dp = varbuf;
+-
+-	findNewline = false;
+-	column = 0;
+-
+-	for (n = 0; n < len; n++) {
+-		if (varbuf[n] == 0)
+-			break;
+-		if (varbuf[n] == '\r')
+-			continue;
+-		if (findNewline && varbuf[n] != '\n')
+-			continue;
+-		findNewline = false;
+-		if (varbuf[n] == '#') {
+-			findNewline = true;
+-			continue;
+-		}
+-		if (varbuf[n] == '\n') {
+-			if (column == 0)
+-				continue;
+-			*dp++ = 0;
+-			column = 0;
+-			continue;
+-		}
+-		*dp++ = varbuf[n];
+-		column++;
+-	}
+-	buf_len = dp - varbuf;
+-
+-	while (dp < varbuf + n)
+-		*dp++ = 0;
+-
+-	return buf_len;
+-}
+-
+-/*
+-	EXAMPLE: nvram_array
+-	nvram_arry format:
+-	name=value
+-	Use carriage return at the end of each assignment,
+-	 and an empty string with
+-	carriage return at the end of array.
+-
+-	For example:
+-	unsigned char  nvram_array[] = {"name1=value1\n",
+-	"name2=value2\n", "\n"};
+-	Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx.
+-
+-	Search "EXAMPLE: nvram_array" to see how the array is activated.
+-*/
+-
+-void dhd_bus_set_nvram_params(struct dhd_bus *bus, const char *nvram_params)
+-{
+-	bus->nvram_params = nvram_params;
+-}
+-
+-static int dhdsdio_download_nvram(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-	uint len;
+-	void *image = NULL;
+-	char *memblock = NULL;
+-	char *bufp;
+-	char *nv_path;
+-	bool nvram_file_exists;
+-
+-	nv_path = bus->nv_path;
+-
+-	nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
+-	if (!nvram_file_exists && (bus->nvram_params == NULL))
+-		return 0;
+-
+-	if (nvram_file_exists) {
+-		image = dhd_os_open_image(nv_path);
+-		if (image == NULL)
+-			goto err;
+-	}
+-
+-	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
+-	if (memblock == NULL) {
+-		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+-			   __func__, MEMBLOCK));
+-		goto err;
+-	}
+-
+-	/* Download variables */
+-	if (nvram_file_exists) {
+-		len = dhd_os_get_image_block(memblock, MEMBLOCK, image);
+-	} else {
+-		len = strlen(bus->nvram_params);
+-		ASSERT(len <= MEMBLOCK);
+-		if (len > MEMBLOCK)
+-			len = MEMBLOCK;
+-		memcpy(memblock, bus->nvram_params, len);
+-	}
+-
+-	if (len > 0 && len < MEMBLOCK) {
+-		bufp = (char *)memblock;
+-		bufp[len] = 0;
+-		len = process_nvram_vars(bufp, len);
+-		bufp += len;
+-		*bufp++ = 0;
+-		if (len)
+-			bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error downloading vars: %d\n",
+-				   __func__, bcmerror));
+-		}
+-	} else {
+-		DHD_ERROR(("%s: error reading nvram file: %d\n",
+-			   __func__, len));
+-		bcmerror = -EIO;
+-	}
+-
+-err:
+-	kfree(memblock);
+-
+-	if (image)
+-		dhd_os_close_image(image);
+-
+-	return bcmerror;
+-}
+-
+-static int _dhdsdio_download_firmware(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-
+-	bool embed = false;	/* download embedded firmware */
+-	bool dlok = false;	/* download firmware succeeded */
+-
+-	/* Out immediately if no image to download */
+-	if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) {
+-#ifdef BCMEMBEDIMAGE
+-		embed = true;
+-#else
+-		return bcmerror;
+-#endif
+-	}
+-
+-	/* Keep arm in reset */
+-	if (dhdsdio_download_state(bus, true)) {
+-		DHD_ERROR(("%s: error placing ARM core in reset\n", __func__));
+-		goto err;
+-	}
+-
+-	/* External image takes precedence if specified */
+-	if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) {
+-		if (dhdsdio_download_code_file(bus, bus->fw_path)) {
+-			DHD_ERROR(("%s: dongle image file download failed\n",
+-				   __func__));
+-#ifdef BCMEMBEDIMAGE
+-			embed = true;
+-#else
+-			goto err;
+-#endif
+-		} else {
+-			embed = false;
+-			dlok = true;
+-		}
+-	}
+-#ifdef BCMEMBEDIMAGE
+-	if (embed) {
+-		if (dhdsdio_download_code_array(bus)) {
+-			DHD_ERROR(("%s: dongle image array download failed\n",
+-				   __func__));
+-			goto err;
+-		} else {
+-			dlok = true;
+-		}
+-	}
+-#endif
+-	if (!dlok) {
+-		DHD_ERROR(("%s: dongle image download failed\n", __func__));
+-		goto err;
+-	}
+-
+-	/* EXAMPLE: nvram_array */
+-	/* If a valid nvram_arry is specified as above, it can be passed
+-		 down to dongle */
+-	/* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */
+-
+-	/* External nvram takes precedence if specified */
+-	if (dhdsdio_download_nvram(bus)) {
+-		DHD_ERROR(("%s: dongle nvram file download failed\n",
+-			   __func__));
+-	}
+-
+-	/* Take arm out of reset */
+-	if (dhdsdio_download_state(bus, false)) {
+-		DHD_ERROR(("%s: error getting out of ARM core reset\n",
+-			   __func__));
+-		goto err;
+-	}
+-
+-	bcmerror = 0;
+-
+-err:
+-	return bcmerror;
+-}
+-
+-
+-static int
+-dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
+-		    u8 *buf, uint nbytes, struct sk_buff *pkt,
+-		    bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	return bcmsdh_send_buf
+-		(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete,
+-		 handle);
+-}
+-
+-uint dhd_bus_chip(struct dhd_bus *bus)
+-{
+-	ASSERT(bus->ci != NULL);
+-	return bus->ci->chip;
+-}
+-
+-void *dhd_bus_pub(struct dhd_bus *bus)
+-{
+-	return bus->dhd;
+-}
+-
+-void *dhd_bus_txq(struct dhd_bus *bus)
+-{
+-	return &bus->txq;
+-}
+-
+-uint dhd_bus_hdrlen(struct dhd_bus *bus)
+-{
+-	return SDPCM_HDRLEN;
+-}
+-
+-int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag)
+-{
+-	int bcmerror = 0;
+-	dhd_bus_t *bus;
+-
+-	bus = dhdp->bus;
+-
+-	if (flag == true) {
+-		if (!bus->dhd->dongle_reset) {
+-			/* Expect app to have torn down any
+-			 connection before calling */
+-			/* Stop the bus, disable F2 */
+-			dhd_bus_stop(bus, false);
+-
+-			/* Clean tx/rx buffer pointers,
+-			 detach from the dongle */
+-			dhdsdio_release_dongle(bus);
+-
+-			bus->dhd->dongle_reset = true;
+-			bus->dhd->up = false;
+-
+-			DHD_TRACE(("%s:  WLAN OFF DONE\n", __func__));
+-			/* App can now remove power from device */
+-		} else
+-			bcmerror = -EIO;
+-	} else {
+-		/* App must have restored power to device before calling */
+-
+-		DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __func__));
+-
+-		if (bus->dhd->dongle_reset) {
+-			/* Turn on WLAN */
+-			/* Reset SD client */
+-			bcmsdh_reset(bus->sdh);
+-
+-			/* Attempt to re-attach & download */
+-			if (dhdsdio_probe_attach(bus, bus->sdh,
+-						 (u32 *) SI_ENUM_BASE,
+-						 bus->cl_devid)) {
+-				/* Attempt to download binary to the dongle */
+-				if (dhdsdio_probe_init
+-				    (bus, bus->sdh)
+-				    && dhdsdio_download_firmware(bus,
+-								 bus->sdh)) {
+-
+-					/* Re-init bus, enable F2 transfer */
+-					dhd_bus_init((dhd_pub_t *) bus->dhd,
+-						     false);
+-
+-#if defined(OOB_INTR_ONLY)
+-					dhd_enable_oob_intr(bus, true);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-					bus->dhd->dongle_reset = false;
+-					bus->dhd->up = true;
+-
+-					DHD_TRACE(("%s: WLAN ON DONE\n",
+-						   __func__));
+-				} else
+-					bcmerror = -EIO;
+-			} else
+-				bcmerror = -EIO;
+-		} else {
+-			bcmerror = -EISCONN;
+-			DHD_ERROR(("%s: Set DEVRESET=false invoked when device "
+-				"is on\n", __func__));
+-			bcmerror = -EIO;
+-		}
+-	}
+-	return bcmerror;
+-}
+-
+-static int
+-dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs)
+-{
+-	u32 regdata;
+-
+-	/*
+-	 * Get CC core rev
+-	 * Chipid is assume to be at offset 0 from regs arg
+-	 * For different chiptypes or old sdio hosts w/o chipcommon,
+-	 * other ways of recognition should be added here.
+-	 */
+-	ci->cccorebase = (u32)regs;
+-	regdata = bcmsdh_reg_read(sdh, CORE_CC_REG(ci->cccorebase, chipid), 4);
+-	ci->chip = regdata & CID_ID_MASK;
+-	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
+-
+-	DHD_INFO(("%s: chipid=0x%x chiprev=%d\n",
+-		__func__, ci->chip, ci->chiprev));
+-
+-	/* Address of cores for new chips should be added here */
+-	switch (ci->chip) {
+-	case BCM4329_CHIP_ID:
+-		ci->buscorebase = BCM4329_CORE_BUS_BASE;
+-		ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
+-		ci->armcorebase	= BCM4329_CORE_ARM_BASE;
+-		ci->ramsize = BCM4329_RAMSIZE;
+-		break;
+-	default:
+-		DHD_ERROR(("%s: chipid 0x%x is not supported\n",
+-			__func__, ci->chip));
+-		return -ENODEV;
+-	}
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(ci->cccorebase, sbidhigh), 4);
+-	ci->ccrev = SBCOREREV(regdata);
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
+-	ci->pmurev = regdata & PCAP_REV_MASK;
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(ci->buscorebase, sbidhigh), 4);
+-	ci->buscorerev = SBCOREREV(regdata);
+-	ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
+-
+-	DHD_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
+-		__func__, ci->ccrev, ci->pmurev,
+-		ci->buscorerev, ci->buscoretype));
+-
+-	/* get chipcommon capabilites */
+-	ci->cccaps = bcmsdh_reg_read(sdh,
+-		CORE_CC_REG(ci->cccorebase, capabilities), 4);
+-
+-	return 0;
+-}
+-
+-static void
+-dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase)
+-{
+-	u32 regdata;
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(corebase, sbtmstatelow), 4);
+-	if (regdata & SBTML_RESET)
+-		return;
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(corebase, sbtmstatelow), 4);
+-	if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
+-		/*
+-		 * set target reject and spin until busy is clear
+-		 * (preserve core-specific bits)
+-		 */
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-			regdata | SBTML_REJ);
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		udelay(1);
+-		SPINWAIT((bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatehigh), 4) &
+-			SBTMH_BUSY), 100000);
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatehigh), 4);
+-		if (regdata & SBTMH_BUSY)
+-			DHD_ERROR(("%s: ARM core still busy\n", __func__));
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbidlow), 4);
+-		if (regdata & SBIDL_INIT) {
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) |
+-				SBIM_RJ;
+-			bcmsdh_reg_write(sdh,
+-				CORE_SB(corebase, sbimstate), 4,
+-				regdata);
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4);
+-			udelay(1);
+-			SPINWAIT((bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) &
+-				SBIM_BY), 100000);
+-		}
+-
+-		/* set reset and reject while enabling the clocks */
+-		bcmsdh_reg_write(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4,
+-			(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+-			SBTML_REJ | SBTML_RESET));
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		udelay(10);
+-
+-		/* clear the initiator reject bit */
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbidlow), 4);
+-		if (regdata & SBIDL_INIT) {
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) &
+-				~SBIM_RJ;
+-			bcmsdh_reg_write(sdh,
+-				CORE_SB(corebase, sbimstate), 4,
+-				regdata);
+-		}
+-	}
+-
+-	/* leave reset and reject asserted */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SBTML_REJ | SBTML_RESET));
+-	udelay(1);
+-}
+-
+-static int
+-dhdsdio_chip_attach(struct dhd_bus *bus, void *regs)
+-{
+-	struct chip_info *ci;
+-	int err;
+-	u8 clkval, clkset;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* alloc chip_info_t */
+-	ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC);
+-	if (NULL == ci) {
+-		DHD_ERROR(("%s: malloc failed!\n", __func__));
+-		return -ENOMEM;
+-	}
+-
+-	memset((unsigned char *)ci, 0, sizeof(struct chip_info));
+-
+-	/* bus/core/clk setup for register access */
+-	/* Try forcing SDIO core to do ALPAvail request only */
+-	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			clkset, &err);
+-	if (err) {
+-		DHD_ERROR(("%s: error writing for HT off\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* If register supported, wait for ALPAvail and then force ALP */
+-	/* This may take up to 15 milliseconds */
+-	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-			SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+-	if ((clkval & ~SBSDIO_AVBITS) == clkset) {
+-		SPINWAIT(((clkval =
+-				bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-						SBSDIO_FUNC1_CHIPCLKCSR,
+-						NULL)),
+-				!SBSDIO_ALPAV(clkval)),
+-				PMU_MAX_TRANSITION_DLY);
+-		if (!SBSDIO_ALPAV(clkval)) {
+-			DHD_ERROR(("%s: timeout on ALPAV wait, clkval 0x%02x\n",
+-				__func__, clkval));
+-			err = -EBUSY;
+-			goto fail;
+-		}
+-		clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
+-				SBSDIO_FORCE_ALP;
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+-				SBSDIO_FUNC1_CHIPCLKCSR,
+-				clkset, &err);
+-		udelay(65);
+-	} else {
+-		DHD_ERROR(("%s: ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
+-			__func__, clkset, clkval));
+-		err = -EACCES;
+-		goto fail;
+-	}
+-
+-	/* Also, disable the extra SDIO pull-ups */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
+-			 NULL);
+-
+-	err = dhdsdio_chip_recognition(bus->sdh, ci, regs);
+-	if (err)
+-		goto fail;
+-
+-	/*
+-	 * Make sure any on-chip ARM is off (in case strapping is wrong),
+-	 * or downloaded code was already running.
+-	 */
+-	dhdsdio_chip_disablecore(bus->sdh, ci->armcorebase);
+-
+-	bcmsdh_reg_write(bus->sdh,
+-		CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
+-	bcmsdh_reg_write(bus->sdh,
+-		CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
+-
+-	/* Disable F2 to clear any intermediate frame state on the dongle */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
+-		SDIO_FUNC_ENABLE_1, NULL);
+-
+-	/* WAR: cmd52 backplane read so core HW will drop ALPReq */
+-	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-			0, NULL);
+-
+-	/* Done with backplane-dependent accesses, can drop clock... */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0,
+-			 NULL);
+-
+-	bus->ci = ci;
+-	return 0;
+-fail:
+-	bus->ci = NULL;
+-	kfree(ci);
+-	return err;
+-}
+-
+-static void
+-dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase)
+-{
+-	u32 regdata;
+-
+-	/*
+-	 * Must do the disable sequence first to work for
+-	 * arbitrary current core state.
+-	 */
+-	dhdsdio_chip_disablecore(sdh, corebase);
+-
+-	/*
+-	 * Now do the initialization sequence.
+-	 * set reset while enabling the clock and
+-	 * forcing them on throughout the core
+-	 */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+-		SBTML_RESET);
+-	udelay(1);
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbtmstatehigh), 4);
+-	if (regdata & SBTMH_SERR)
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatehigh), 4, 0);
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbimstate), 4);
+-	if (regdata & (SBIM_IBE | SBIM_TO))
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbimstate), 4,
+-			regdata & ~(SBIM_IBE | SBIM_TO));
+-
+-	/* clear reset and allow it to propagate throughout the core */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SICF_FGC << SBTML_SICF_SHIFT) |
+-		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-	udelay(1);
+-
+-	/* leave clock enabled */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-	udelay(1);
+-}
+-
+-/* SDIO Pad drive strength to select value mappings */
+-struct sdiod_drive_str {
+-	u8 strength;	/* Pad Drive Strength in mA */
+-	u8 sel;		/* Chip-specific select value */
+-};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 1 */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
+-	{
+-	4, 0x2}, {
+-	2, 0x3}, {
+-	1, 0x0}, {
+-	0, 0x0}
+-	};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
+-	{
+-	12, 0x7}, {
+-	10, 0x6}, {
+-	8, 0x5}, {
+-	6, 0x4}, {
+-	4, 0x2}, {
+-	2, 0x1}, {
+-	0, 0x0}
+-	};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
+-	{
+-	32, 0x7}, {
+-	26, 0x6}, {
+-	22, 0x5}, {
+-	16, 0x4}, {
+-	12, 0x3}, {
+-	8, 0x2}, {
+-	4, 0x1}, {
+-	0, 0x0}
+-	};
+-
+-#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
+-
+-static void
+-dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) {
+-	struct sdiod_drive_str *str_tab = NULL;
+-	u32 str_mask = 0;
+-	u32 str_shift = 0;
+-	char chn[8];
+-
+-	if (!(bus->ci->cccaps & CC_CAP_PMU))
+-		return;
+-
+-	switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
+-		str_mask = 0x30000000;
+-		str_shift = 28;
+-		break;
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
+-		str_mask = 0x00003800;
+-		str_shift = 11;
+-		break;
+-	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
+-		str_mask = 0x00003800;
+-		str_shift = 11;
+-		break;
+-	default:
+-		DHD_ERROR(("No SDIO Drive strength init"
+-			"done for chip %s rev %d pmurev %d\n",
+-			bcm_chipname(bus->ci->chip, chn, 8),
+-			bus->ci->chiprev, bus->ci->pmurev));
+-		break;
+-	}
+-
+-	if (str_tab != NULL) {
+-		u32 drivestrength_sel = 0;
+-		u32 cc_data_temp;
+-		int i;
+-
+-		for (i = 0; str_tab[i].strength != 0; i++) {
+-			if (drivestrength >= str_tab[i].strength) {
+-				drivestrength_sel = str_tab[i].sel;
+-				break;
+-			}
+-		}
+-
+-		bcmsdh_reg_write(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+-			4, 1);
+-		cc_data_temp = bcmsdh_reg_read(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
+-		cc_data_temp &= ~str_mask;
+-		drivestrength_sel <<= str_shift;
+-		cc_data_temp |= drivestrength_sel;
+-		bcmsdh_reg_write(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+-			4, cc_data_temp);
+-
+-		DHD_INFO(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
+-			drivestrength, cc_data_temp));
+-	}
+-}
+-
+-static void
+-dhdsdio_chip_detach(struct dhd_bus *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	kfree(bus->ci);
+-	bus->ci = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h b/drivers/staging/brcm80211/brcmfmac/dhdioctl.h
+deleted file mode 100644
+index f0ba535..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h
++++ /dev/null
+@@ -1,100 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhdioctl_h_
+-#define	_dhdioctl_h_
+-
+-/* Linux network driver ioctl encoding */
+-typedef struct dhd_ioctl {
+-	uint cmd;		/* common ioctl definition */
+-	void *buf;		/* pointer to user buffer */
+-	uint len;		/* length of user buffer */
+-	bool set;		/* get or set request (optional) */
+-	uint used;		/* bytes read or written (optional) */
+-	uint needed;		/* bytes needed (optional) */
+-	uint driver;		/* to identify target driver */
+-} dhd_ioctl_t;
+-
+-/* per-driver magic numbers */
+-#define DHD_IOCTL_MAGIC		0x00444944
+-
+-/* bump this number if you change the ioctl interface */
+-#define DHD_IOCTL_VERSION	1
+-
+-#define	DHD_IOCTL_MAXLEN	8192	/* max length ioctl buffer required */
+-#define	DHD_IOCTL_SMLEN	256	/* "small" length ioctl buffer required */
+-
+-/* common ioctl definitions */
+-#define DHD_GET_MAGIC				0
+-#define DHD_GET_VERSION				1
+-#define DHD_GET_VAR				2
+-#define DHD_SET_VAR				3
+-
+-/* message levels */
+-#define DHD_ERROR_VAL	0x0001
+-#define DHD_TRACE_VAL	0x0002
+-#define DHD_INFO_VAL	0x0004
+-#define DHD_DATA_VAL	0x0008
+-#define DHD_CTL_VAL	0x0010
+-#define DHD_TIMER_VAL	0x0020
+-#define DHD_HDRS_VAL	0x0040
+-#define DHD_BYTES_VAL	0x0080
+-#define DHD_INTR_VAL	0x0100
+-#define DHD_LOG_VAL	0x0200
+-#define DHD_GLOM_VAL	0x0400
+-#define DHD_EVENT_VAL	0x0800
+-#define DHD_BTA_VAL	0x1000
+-#define DHD_ISCAN_VAL 0x2000
+-
+-#ifdef SDTEST
+-/* For pktgen iovar */
+-typedef struct dhd_pktgen {
+-	uint version;		/* To allow structure change tracking */
+-	uint freq;		/* Max ticks between tx/rx attempts */
+-	uint count;		/* Test packets to send/rcv each attempt */
+-	uint print;		/* Print counts every <print> attempts */
+-	uint total;		/* Total packets (or bursts) */
+-	uint minlen;		/* Minimum length of packets to send */
+-	uint maxlen;		/* Maximum length of packets to send */
+-	uint numsent;		/* Count of test packets sent */
+-	uint numrcvd;		/* Count of test packets received */
+-	uint numfail;		/* Count of test send failures */
+-	uint mode;		/* Test mode (type of test packets) */
+-	uint stop;		/* Stop after this many tx failures */
+-} dhd_pktgen_t;
+-
+-/* Version in case structure changes */
+-#define DHD_PKTGEN_VERSION 2
+-
+-/* Type of test packets to use */
+-#define DHD_PKTGEN_ECHO		1	/* Send echo requests */
+-#define DHD_PKTGEN_SEND		2	/* Send discard packets */
+-#define DHD_PKTGEN_RXBURST	3	/* Request dongle send N packets */
+-#define DHD_PKTGEN_RECV		4	/* Continuous rx from continuous
+-					 tx dongle */
+-#endif				/* SDTEST */
+-
+-/* Enter idle immediately (no timeout) */
+-#define DHD_IDLE_IMMEDIATE	(-1)
+-
+-/* Values for idleclock iovar: other values are the sd_divisor to use
+-	 when idle */
+-#define DHD_IDLE_ACTIVE	0	/* Do not request any SD clock change
+-				 when idle */
+-#define DHD_IDLE_STOP   (-1)	/* Request SD clock be stopped
+-				 (and use SD1 mode) */
+-
+-#endif				/* _dhdioctl_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h b/drivers/staging/brcm80211/brcmfmac/dngl_stats.h
+deleted file mode 100644
+index 699cbff..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h
++++ /dev/null
+@@ -1,32 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dngl_stats_h_
+-#define _dngl_stats_h_
+-
+-typedef struct {
+-	unsigned long rx_packets;	/* total packets received */
+-	unsigned long tx_packets;	/* total packets transmitted */
+-	unsigned long rx_bytes;	/* total bytes received */
+-	unsigned long tx_bytes;	/* total bytes transmitted */
+-	unsigned long rx_errors;	/* bad packets received */
+-	unsigned long tx_errors;	/* packet transmit problems */
+-	unsigned long rx_dropped;	/* packets dropped by dongle */
+-	unsigned long tx_dropped;	/* packets dropped by dongle */
+-	unsigned long multicast;	/* multicast packets received */
+-} dngl_stats_t;
+-
+-#endif				/* _dngl_stats_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h b/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
+deleted file mode 100644
+index 28f092c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
++++ /dev/null
+@@ -1,75 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_hndrte_armtrap_h
+-#define	_hndrte_armtrap_h
+-
+-/* ARM trap handling */
+-
+-/* Trap types defined by ARM (see arminc.h) */
+-
+-/* Trap locations in lo memory */
+-#define	TRAP_STRIDE	4
+-#define FIRST_TRAP	TR_RST
+-#define LAST_TRAP	(TR_FIQ * TRAP_STRIDE)
+-
+-#if defined(__ARM_ARCH_4T__)
+-#define	MAX_TRAP_TYPE	(TR_FIQ + 1)
+-#elif defined(__ARM_ARCH_7M__)
+-#define	MAX_TRAP_TYPE	(TR_ISR + ARMCM3_NUMINTS)
+-#endif				/* __ARM_ARCH_7M__ */
+-
+-/* The trap structure is defined here as offsets for assembly */
+-#define	TR_TYPE		0x00
+-#define	TR_EPC		0x04
+-#define	TR_CPSR		0x08
+-#define	TR_SPSR		0x0c
+-#define	TR_REGS		0x10
+-#define	TR_REG(n)	(TR_REGS + (n) * 4)
+-#define	TR_SP		TR_REG(13)
+-#define	TR_LR		TR_REG(14)
+-#define	TR_PC		TR_REG(15)
+-
+-#define	TRAP_T_SIZE	80
+-
+-#ifndef	_LANGUAGE_ASSEMBLY
+-
+-typedef struct _trap_struct {
+-	u32 type;
+-	u32 epc;
+-	u32 cpsr;
+-	u32 spsr;
+-	u32 r0;
+-	u32 r1;
+-	u32 r2;
+-	u32 r3;
+-	u32 r4;
+-	u32 r5;
+-	u32 r6;
+-	u32 r7;
+-	u32 r8;
+-	u32 r9;
+-	u32 r10;
+-	u32 r11;
+-	u32 r12;
+-	u32 r13;
+-	u32 r14;
+-	u32 pc;
+-} trap_t;
+-
+-#endif				/* !_LANGUAGE_ASSEMBLY */
+-
+-#endif				/* _hndrte_armtrap_h */
+diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
+deleted file mode 100644
+index 4df3eec..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#ifndef _hndrte_cons_h
+-#define _hndrte_cons_h
+-
+-#define CBUF_LEN	(128)
+-
+-#define LOG_BUF_LEN	1024
+-
+-typedef struct {
+-	u32 buf;		/* Can't be pointer on (64-bit) hosts */
+-	uint buf_size;
+-	uint idx;
+-	char *_buf_compat;	/* Redundant pointer for backward compat. */
+-} hndrte_log_t;
+-
+-typedef struct {
+-	/* Virtual UART
+-	 * When there is no UART (e.g. Quickturn),
+-	 * the host should write a complete
+-	 * input line directly into cbuf and then write
+-	 * the length into vcons_in.
+-	 * This may also be used when there is a real UART
+-	 * (at risk of conflicting with
+-	 * the real UART).  vcons_out is currently unused.
+-	 */
+-	volatile uint vcons_in;
+-	volatile uint vcons_out;
+-
+-	/* Output (logging) buffer
+-	 * Console output is written to a ring buffer log_buf at index log_idx.
+-	 * The host may read the output when it sees log_idx advance.
+-	 * Output will be lost if the output wraps around faster than the host
+-	 * polls.
+-	 */
+-	hndrte_log_t log;
+-
+-	/* Console input line buffer
+-	 * Characters are read one at a time into cbuf
+-	 * until <CR> is received, then
+-	 * the buffer is processed as a command line.
+-	 * Also used for virtual UART.
+-	 */
+-	uint cbuf_idx;
+-	char cbuf[CBUF_LEN];
+-} hndrte_cons_t;
+-
+-#endif /* _hndrte_cons_h */
+-
+diff --git a/drivers/staging/brcm80211/brcmfmac/msgtrace.h b/drivers/staging/brcm80211/brcmfmac/msgtrace.h
+deleted file mode 100644
+index d654671..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/msgtrace.h
++++ /dev/null
+@@ -1,61 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_MSGTRACE_H
+-#define	_MSGTRACE_H
+-
+-#define MSGTRACE_VERSION 1
+-
+-/* Message trace header */
+-typedef struct msgtrace_hdr {
+-	u8 version;
+-	u8 spare;
+-	u16 len;		/* Len of the trace */
+-	u32 seqnum;		/* Sequence number of message. Useful
+-				 * if the messsage has been lost
+-				 * because of DMA error or a bus reset
+-				 * (ex: SDIO Func2)
+-				 */
+-	u32 discarded_bytes;	/* Number of discarded bytes because of
+-				 trace overflow  */
+-	u32 discarded_printf;	/* Number of discarded printf
+-				 because of trace overflow */
+-} __attribute__((packed)) msgtrace_hdr_t;
+-
+-#define MSGTRACE_HDRLEN		sizeof(msgtrace_hdr_t)
+-
+-/* The hbus driver generates traces when sending a trace message.
+- * This causes endless traces.
+- * This flag must be set to true in any hbus traces.
+- * The flag is reset in the function msgtrace_put.
+- * This prevents endless traces but generates hasardous
+- * lost of traces only in bus device code.
+- * It is recommendat to set this flag in macro SD_TRACE
+- * but not in SD_ERROR for avoiding missing
+- * hbus error traces. hbus error trace should not generates endless traces.
+- */
+-extern bool msgtrace_hbus_trace;
+-
+-typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr,
+-				      u16 hdrlen, u8 *buf,
+-				      u16 buflen);
+-
+-extern void msgtrace_sent(void);
+-extern void msgtrace_put(char *buf, int count);
+-extern void msgtrace_init(void *hdl1, void *hdl2,
+-			  msgtrace_func_send_t func_send);
+-
+-#endif				/* _MSGTRACE_H */
+diff --git a/drivers/staging/brcm80211/brcmfmac/sdioh.h b/drivers/staging/brcm80211/brcmfmac/sdioh.h
+deleted file mode 100644
+index f96aaf9..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/sdioh.h
++++ /dev/null
+@@ -1,63 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SDIOH_H
+-#define	_SDIOH_H
+-
+-#define SD_SysAddr			0x000
+-#define SD_BlockSize			0x004
+-#define SD_BlockCount 			0x006
+-#define SD_Arg0				0x008
+-#define SD_Arg1 			0x00A
+-#define SD_TransferMode			0x00C
+-#define SD_Command 			0x00E
+-#define SD_Response0			0x010
+-#define SD_Response1 			0x012
+-#define SD_Response2			0x014
+-#define SD_Response3 			0x016
+-#define SD_Response4			0x018
+-#define SD_Response5 			0x01A
+-#define SD_Response6			0x01C
+-#define SD_Response7 			0x01E
+-#define SD_BufferDataPort0		0x020
+-#define SD_BufferDataPort1 		0x022
+-#define SD_PresentState			0x024
+-#define SD_HostCntrl			0x028
+-#define SD_PwrCntrl			0x029
+-#define SD_BlockGapCntrl 		0x02A
+-#define SD_WakeupCntrl 			0x02B
+-#define SD_ClockCntrl			0x02C
+-#define SD_TimeoutCntrl 		0x02E
+-#define SD_SoftwareReset		0x02F
+-#define SD_IntrStatus			0x030
+-#define SD_ErrorIntrStatus 		0x032
+-#define SD_IntrStatusEnable		0x034
+-#define SD_ErrorIntrStatusEnable 	0x036
+-#define SD_IntrSignalEnable		0x038
+-#define SD_ErrorIntrSignalEnable 	0x03A
+-#define SD_CMD12ErrorStatus		0x03C
+-#define SD_Capabilities			0x040
+-#define SD_Capabilities_Reserved	0x044
+-#define SD_MaxCurCap			0x048
+-#define SD_MaxCurCap_Reserved		0x04C
+-#define SD_ADMA_SysAddr			0x58
+-#define SD_SlotInterruptStatus		0x0FC
+-#define SD_HostControllerVersion 	0x0FE
+-
+-/* SD specific registers in PCI config space */
+-#define SD_SlotInfo	0x40
+-
+-#endif				/* _SDIOH_H */
+diff --git a/drivers/staging/brcm80211/brcmfmac/sdiovar.h b/drivers/staging/brcm80211/brcmfmac/sdiovar.h
+deleted file mode 100644
+index d1cfa5f..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/sdiovar.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _sdiovar_h_
+-#define _sdiovar_h_
+-
+-typedef struct sdreg {
+-	int func;
+-	int offset;
+-	int value;
+-} sdreg_t;
+-
+-/* Common msglevel constants */
+-#define SDH_ERROR_VAL		0x0001	/* Error */
+-#define SDH_TRACE_VAL		0x0002	/* Trace */
+-#define SDH_INFO_VAL		0x0004	/* Info */
+-#define SDH_DEBUG_VAL		0x0008	/* Debug */
+-#define SDH_DATA_VAL		0x0010	/* Data */
+-#define SDH_CTRL_VAL		0x0020	/* Control Regs */
+-#define SDH_LOG_VAL		0x0040	/* Enable bcmlog */
+-#define SDH_DMA_VAL		0x0080	/* DMA */
+-
+-#define NUM_PREV_TRANSACTIONS	16
+-
+-#endif				/* _sdiovar_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+deleted file mode 100644
+index 1827b0b..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
++++ /dev/null
+@@ -1,4428 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/if_arp.h>
+-
+-#include <bcmutils.h>
+-
+-#include <asm/uaccess.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhdioctl.h>
+-#include <wlioctl.h>
+-
+-#include <linux/kthread.h>
+-#include <linux/netdevice.h>
+-#include <linux/sched.h>
+-#include <linux/etherdevice.h>
+-#include <linux/wireless.h>
+-#include <linux/ieee80211.h>
+-#include <net/cfg80211.h>
+-
+-#include <net/rtnetlink.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/firmware.h>
+-#include <wl_cfg80211.h>
+-
+-void sdioh_sdio_set_host_pm_flags(int flag);
+-
+-static struct sdio_func *cfg80211_sdio_func;
+-static struct wl_dev *wl_cfg80211_dev;
+-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-
+-u32 wl_dbg_level = WL_DBG_ERR;
+-
+-#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
+-#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
+-
+-/*
+-** cfg80211_ops api/callback list
+-*/
+-static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
+-				      struct net_device *ndev,
+-				      enum nl80211_iftype type, u32 *flags,
+-				      struct vif_params *params);
+-static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-				struct cfg80211_scan_request *request,
+-				struct cfg80211_ssid *this_ssid);
+-static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-			      struct cfg80211_scan_request *request);
+-static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+-static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_ibss_params *params);
+-static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
+-				    struct net_device *dev);
+-static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+-				     struct net_device *dev, u8 *mac,
+-				     struct station_info *sinfo);
+-static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+-					struct net_device *dev, bool enabled,
+-					s32 timeout);
+-static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+-					  struct net_device *dev,
+-					  const u8 *addr,
+-					  const struct cfg80211_bitrate_mask
+-					  *mask);
+-static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+-			       struct cfg80211_connect_params *sme);
+-static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+-				    u16 reason_code);
+-static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+-				      enum nl80211_tx_power_setting type,
+-				      s32 dbm);
+-static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
+-static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+-					  struct net_device *dev, u8 key_idx,
+-					  bool unicast, bool multicast);
+-static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr,
+-				 struct key_params *params);
+-static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr);
+-static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr,
+-				 void *cookie, void (*callback) (void *cookie,
+-								 struct
+-								 key_params *
+-								 params));
+-static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+-						 struct net_device *dev,
+-						 u8 key_idx);
+-static s32 wl_cfg80211_resume(struct wiphy *wiphy);
+-static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
+-static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_pmksa *pmksa);
+-static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_pmksa *pmksa);
+-static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
+-				     struct net_device *dev);
+-/*
+-** event & event Q handlers for cfg80211 interfaces
+-*/
+-static s32 wl_create_event_handler(struct wl_priv *wl);
+-static void wl_destroy_event_handler(struct wl_priv *wl);
+-static s32 wl_event_handler(void *data);
+-static void wl_init_eq(struct wl_priv *wl);
+-static void wl_flush_eq(struct wl_priv *wl);
+-static void wl_lock_eq(struct wl_priv *wl);
+-static void wl_unlock_eq(struct wl_priv *wl);
+-static void wl_init_eq_lock(struct wl_priv *wl);
+-static void wl_init_eloop_handler(struct wl_event_loop *el);
+-static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
+-static s32 wl_enq_event(struct wl_priv *wl, u32 type,
+-			  const wl_event_msg_t *msg, void *data);
+-static void wl_put_event(struct wl_event_q *e);
+-static void wl_wakeup_event(struct wl_priv *wl);
+-static s32 wl_notify_connect_status(struct wl_priv *wl,
+-				      struct net_device *ndev,
+-				      const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_roaming_status(struct wl_priv *wl,
+-				      struct net_device *ndev,
+-				      const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+-				   const wl_event_msg_t *e, void *data);
+-static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+-				 const wl_event_msg_t *e, void *data,
+-				bool completed);
+-static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+-				 const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+-				  const wl_event_msg_t *e, void *data);
+-
+-/*
+-** register/deregister sdio function
+-*/
+-struct sdio_func *wl_cfg80211_get_sdio_func(void);
+-static void wl_clear_sdio_func(void);
+-
+-/*
+-** ioctl utilites
+-*/
+-static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
+-			       s32 buf_len);
+-static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
+-				      s8 *buf, s32 len);
+-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
+-static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
+-			       s32 *retval);
+-static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
+-			  u32 len);
+-
+-/*
+-** cfg80211 set_wiphy_params utilities
+-*/
+-static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
+-static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
+-static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
+-
+-/*
+-** wl profile utilities
+-*/
+-static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
+-			    void *data, s32 item);
+-static void *wl_read_prof(struct wl_priv *wl, s32 item);
+-static void wl_init_prof(struct wl_profile *prof);
+-
+-/*
+-** cfg80211 connect utilites
+-*/
+-static s32 wl_set_wpa_version(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_auth_type(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_set_cipher(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_key_mgmt(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_set_sharedkey(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_get_assoc_ies(struct wl_priv *wl);
+-static void wl_clear_assoc_ies(struct wl_priv *wl);
+-static void wl_ch_to_chanspec(int ch,
+-	struct wl_join_params *join_params, size_t *join_params_size);
+-
+-/*
+-** information element utilities
+-*/
+-static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
+-static s32 wl_mode_to_nl80211_iftype(s32 mode);
+-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
+-			struct device *dev);
+-static void wl_free_wdev(struct wl_priv *wl);
+-static s32 wl_inform_bss(struct wl_priv *wl);
+-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
+-static s32 wl_update_bss_info(struct wl_priv *wl);
+-static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+-			u8 key_idx, const u8 *mac_addr,
+-			struct key_params *params);
+-
+-/*
+-** key indianess swap utilities
+-*/
+-static void swap_key_from_BE(struct wl_wsec_key *key);
+-static void swap_key_to_BE(struct wl_wsec_key *key);
+-
+-/*
+-** wl_priv memory init/deinit utilities
+-*/
+-static s32 wl_init_priv_mem(struct wl_priv *wl);
+-static void wl_deinit_priv_mem(struct wl_priv *wl);
+-
+-static void wl_delay(u32 ms);
+-
+-/*
+-** store/restore cfg80211 instance data
+-*/
+-static void wl_set_drvdata(struct wl_dev *dev, void *data);
+-static void *wl_get_drvdata(struct wl_dev *dev);
+-
+-/*
+-** ibss mode utilities
+-*/
+-static bool wl_is_ibssmode(struct wl_priv *wl);
+-
+-/*
+-** dongle up/down , default configuration utilities
+-*/
+-static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
+-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
+-static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
+-static void wl_link_down(struct wl_priv *wl);
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
+-static s32 __wl_cfg80211_up(struct wl_priv *wl);
+-static s32 __wl_cfg80211_down(struct wl_priv *wl);
+-static s32 wl_dongle_probecap(struct wl_priv *wl);
+-static void wl_init_conf(struct wl_conf *conf);
+-
+-/*
+-** dongle configuration utilities
+-*/
+-#ifndef EMBEDDED_PLATFORM
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
+-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
+-static s32 wl_dongle_up(struct net_device *ndev, u32 up);
+-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
+-static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
+-			    u32 dongle_align);
+-static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
+-			       s32 arp_ol);
+-static s32 wl_pattern_atoh(s8 *src, s8 *dst);
+-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
+-static s32 wl_update_wiphybands(struct wl_priv *wl);
+-#endif				/* !EMBEDDED_PLATFORM */
+-
+-static s32 wl_dongle_eventmsg(struct net_device *ndev);
+-static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+-				s32 scan_unassoc_time, s32 scan_passive_time);
+-static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
+-static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
+-			    u32 bcn_timeout);
+-
+-/*
+-** iscan handler
+-*/
+-static void wl_iscan_timer(unsigned long data);
+-static void wl_term_iscan(struct wl_priv *wl);
+-static s32 wl_init_iscan(struct wl_priv *wl);
+-static s32 wl_iscan_thread(void *data);
+-static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
+-				 void *param, s32 paramlen, void *bufptr,
+-				 s32 buflen);
+-static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
+-				 void *param, s32 paramlen, void *bufptr,
+-				 s32 buflen);
+-static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
+-			  u16 action);
+-static s32 wl_do_iscan(struct wl_priv *wl);
+-static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
+-static s32 wl_invoke_iscan(struct wl_priv *wl);
+-static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+-				  struct wl_scan_results **bss_list);
+-static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
+-static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
+-static s32 wl_iscan_done(struct wl_priv *wl);
+-static s32 wl_iscan_pending(struct wl_priv *wl);
+-static s32 wl_iscan_inprogress(struct wl_priv *wl);
+-static s32 wl_iscan_aborted(struct wl_priv *wl);
+-
+-/*
+-** fw/nvram downloading handler
+-*/
+-static void wl_init_fw(struct wl_fw_ctrl *fw);
+-
+-/*
+-* find most significant bit set
+-*/
+-static __used u32 wl_find_msb(u16 bit16);
+-
+-/*
+-* update pmklist to dongle
+-*/
+-static __used s32 wl_update_pmklist(struct net_device *dev,
+-				      struct wl_pmk_list *pmk_list, s32 err);
+-
+-static void wl_set_mpc(struct net_device *ndev, int mpc);
+-
+-/*
+-* debufs support
+-*/
+-static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
+-static void wl_debugfs_remove_netdev(struct wl_priv *wl);
+-
+-#define WL_PRIV_GET() 							\
+-	({								\
+-	struct wl_iface *ci;						\
+-	if (unlikely(!(wl_cfg80211_dev && 				\
+-		(ci = wl_get_drvdata(wl_cfg80211_dev))))) {		\
+-		WL_ERR("wl_cfg80211_dev is unavailable\n");		\
+-		BUG();							\
+-	} 								\
+-	ci_to_wl(ci);							\
+-})
+-
+-#define CHECK_SYS_UP()							\
+-do {									\
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);			\
+-	if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {	\
+-		WL_INFO("device is not ready : status (%d)\n",		\
+-			(int)wl->status);				\
+-		return -EIO;						\
+-	}								\
+-} while (0)
+-
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-#define CHAN2G(_channel, _freq, _flags) {			\
+-	.band			= IEEE80211_BAND_2GHZ,		\
+-	.center_freq		= (_freq),			\
+-	.hw_value		= (_channel),			\
+-	.flags			= (_flags),			\
+-	.max_antenna_gain	= 0,				\
+-	.max_power		= 30,				\
+-}
+-
+-#define CHAN5G(_channel, _flags) {				\
+-	.band			= IEEE80211_BAND_5GHZ,		\
+-	.center_freq		= 5000 + (5 * (_channel)),	\
+-	.hw_value		= (_channel),			\
+-	.flags			= (_flags),			\
+-	.max_antenna_gain	= 0,				\
+-	.max_power		= 30,				\
+-}
+-
+-#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
+-#define RATETAB_ENT(_rateid, _flags) \
+-	{                                                               \
+-		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
+-		.hw_value       = (_rateid),                            \
+-		.flags          = (_flags),                             \
+-	}
+-
+-static struct ieee80211_rate __wl_rates[] = {
+-	RATETAB_ENT(WLC_RATE_1M, 0),
+-	RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_6M, 0),
+-	RATETAB_ENT(WLC_RATE_9M, 0),
+-	RATETAB_ENT(WLC_RATE_12M, 0),
+-	RATETAB_ENT(WLC_RATE_18M, 0),
+-	RATETAB_ENT(WLC_RATE_24M, 0),
+-	RATETAB_ENT(WLC_RATE_36M, 0),
+-	RATETAB_ENT(WLC_RATE_48M, 0),
+-	RATETAB_ENT(WLC_RATE_54M, 0),
+-};
+-
+-#define wl_a_rates		(__wl_rates + 4)
+-#define wl_a_rates_size	8
+-#define wl_g_rates		(__wl_rates + 0)
+-#define wl_g_rates_size	12
+-
+-static struct ieee80211_channel __wl_2ghz_channels[] = {
+-	CHAN2G(1, 2412, 0),
+-	CHAN2G(2, 2417, 0),
+-	CHAN2G(3, 2422, 0),
+-	CHAN2G(4, 2427, 0),
+-	CHAN2G(5, 2432, 0),
+-	CHAN2G(6, 2437, 0),
+-	CHAN2G(7, 2442, 0),
+-	CHAN2G(8, 2447, 0),
+-	CHAN2G(9, 2452, 0),
+-	CHAN2G(10, 2457, 0),
+-	CHAN2G(11, 2462, 0),
+-	CHAN2G(12, 2467, 0),
+-	CHAN2G(13, 2472, 0),
+-	CHAN2G(14, 2484, 0),
+-};
+-
+-static struct ieee80211_channel __wl_5ghz_a_channels[] = {
+-	CHAN5G(34, 0), CHAN5G(36, 0),
+-	CHAN5G(38, 0), CHAN5G(40, 0),
+-	CHAN5G(42, 0), CHAN5G(44, 0),
+-	CHAN5G(46, 0), CHAN5G(48, 0),
+-	CHAN5G(52, 0), CHAN5G(56, 0),
+-	CHAN5G(60, 0), CHAN5G(64, 0),
+-	CHAN5G(100, 0), CHAN5G(104, 0),
+-	CHAN5G(108, 0), CHAN5G(112, 0),
+-	CHAN5G(116, 0), CHAN5G(120, 0),
+-	CHAN5G(124, 0), CHAN5G(128, 0),
+-	CHAN5G(132, 0), CHAN5G(136, 0),
+-	CHAN5G(140, 0), CHAN5G(149, 0),
+-	CHAN5G(153, 0), CHAN5G(157, 0),
+-	CHAN5G(161, 0), CHAN5G(165, 0),
+-	CHAN5G(184, 0), CHAN5G(188, 0),
+-	CHAN5G(192, 0), CHAN5G(196, 0),
+-	CHAN5G(200, 0), CHAN5G(204, 0),
+-	CHAN5G(208, 0), CHAN5G(212, 0),
+-	CHAN5G(216, 0),
+-};
+-
+-static struct ieee80211_channel __wl_5ghz_n_channels[] = {
+-	CHAN5G(32, 0), CHAN5G(34, 0),
+-	CHAN5G(36, 0), CHAN5G(38, 0),
+-	CHAN5G(40, 0), CHAN5G(42, 0),
+-	CHAN5G(44, 0), CHAN5G(46, 0),
+-	CHAN5G(48, 0), CHAN5G(50, 0),
+-	CHAN5G(52, 0), CHAN5G(54, 0),
+-	CHAN5G(56, 0), CHAN5G(58, 0),
+-	CHAN5G(60, 0), CHAN5G(62, 0),
+-	CHAN5G(64, 0), CHAN5G(66, 0),
+-	CHAN5G(68, 0), CHAN5G(70, 0),
+-	CHAN5G(72, 0), CHAN5G(74, 0),
+-	CHAN5G(76, 0), CHAN5G(78, 0),
+-	CHAN5G(80, 0), CHAN5G(82, 0),
+-	CHAN5G(84, 0), CHAN5G(86, 0),
+-	CHAN5G(88, 0), CHAN5G(90, 0),
+-	CHAN5G(92, 0), CHAN5G(94, 0),
+-	CHAN5G(96, 0), CHAN5G(98, 0),
+-	CHAN5G(100, 0), CHAN5G(102, 0),
+-	CHAN5G(104, 0), CHAN5G(106, 0),
+-	CHAN5G(108, 0), CHAN5G(110, 0),
+-	CHAN5G(112, 0), CHAN5G(114, 0),
+-	CHAN5G(116, 0), CHAN5G(118, 0),
+-	CHAN5G(120, 0), CHAN5G(122, 0),
+-	CHAN5G(124, 0), CHAN5G(126, 0),
+-	CHAN5G(128, 0), CHAN5G(130, 0),
+-	CHAN5G(132, 0), CHAN5G(134, 0),
+-	CHAN5G(136, 0), CHAN5G(138, 0),
+-	CHAN5G(140, 0), CHAN5G(142, 0),
+-	CHAN5G(144, 0), CHAN5G(145, 0),
+-	CHAN5G(146, 0), CHAN5G(147, 0),
+-	CHAN5G(148, 0), CHAN5G(149, 0),
+-	CHAN5G(150, 0), CHAN5G(151, 0),
+-	CHAN5G(152, 0), CHAN5G(153, 0),
+-	CHAN5G(154, 0), CHAN5G(155, 0),
+-	CHAN5G(156, 0), CHAN5G(157, 0),
+-	CHAN5G(158, 0), CHAN5G(159, 0),
+-	CHAN5G(160, 0), CHAN5G(161, 0),
+-	CHAN5G(162, 0), CHAN5G(163, 0),
+-	CHAN5G(164, 0), CHAN5G(165, 0),
+-	CHAN5G(166, 0), CHAN5G(168, 0),
+-	CHAN5G(170, 0), CHAN5G(172, 0),
+-	CHAN5G(174, 0), CHAN5G(176, 0),
+-	CHAN5G(178, 0), CHAN5G(180, 0),
+-	CHAN5G(182, 0), CHAN5G(184, 0),
+-	CHAN5G(186, 0), CHAN5G(188, 0),
+-	CHAN5G(190, 0), CHAN5G(192, 0),
+-	CHAN5G(194, 0), CHAN5G(196, 0),
+-	CHAN5G(198, 0), CHAN5G(200, 0),
+-	CHAN5G(202, 0), CHAN5G(204, 0),
+-	CHAN5G(206, 0), CHAN5G(208, 0),
+-	CHAN5G(210, 0), CHAN5G(212, 0),
+-	CHAN5G(214, 0), CHAN5G(216, 0),
+-	CHAN5G(218, 0), CHAN5G(220, 0),
+-	CHAN5G(222, 0), CHAN5G(224, 0),
+-	CHAN5G(226, 0), CHAN5G(228, 0),
+-};
+-
+-static struct ieee80211_supported_band __wl_band_2ghz = {
+-	.band = IEEE80211_BAND_2GHZ,
+-	.channels = __wl_2ghz_channels,
+-	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
+-	.bitrates = wl_g_rates,
+-	.n_bitrates = wl_g_rates_size,
+-};
+-
+-static struct ieee80211_supported_band __wl_band_5ghz_a = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = __wl_5ghz_a_channels,
+-	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
+-	.bitrates = wl_a_rates,
+-	.n_bitrates = wl_a_rates_size,
+-};
+-
+-static struct ieee80211_supported_band __wl_band_5ghz_n = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = __wl_5ghz_n_channels,
+-	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
+-	.bitrates = wl_a_rates,
+-	.n_bitrates = wl_a_rates_size,
+-};
+-
+-static const u32 __wl_cipher_suites[] = {
+-	WLAN_CIPHER_SUITE_WEP40,
+-	WLAN_CIPHER_SUITE_WEP104,
+-	WLAN_CIPHER_SUITE_TKIP,
+-	WLAN_CIPHER_SUITE_CCMP,
+-	WLAN_CIPHER_SUITE_AES_CMAC,
+-};
+-
+-static void swap_key_from_BE(struct wl_wsec_key *key)
+-{
+-	key->index = cpu_to_le32(key->index);
+-	key->len = cpu_to_le32(key->len);
+-	key->algo = cpu_to_le32(key->algo);
+-	key->flags = cpu_to_le32(key->flags);
+-	key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
+-	key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
+-	key->iv_initialized = cpu_to_le32(key->iv_initialized);
+-}
+-
+-static void swap_key_to_BE(struct wl_wsec_key *key)
+-{
+-	key->index = le32_to_cpu(key->index);
+-	key->len = le32_to_cpu(key->len);
+-	key->algo = le32_to_cpu(key->algo);
+-	key->flags = le32_to_cpu(key->flags);
+-	key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
+-	key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
+-	key->iv_initialized = le32_to_cpu(key->iv_initialized);
+-}
+-
+-static s32
+-wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
+-{
+-	struct ifreq ifr;
+-	struct wl_ioctl ioc;
+-	mm_segment_t fs;
+-	s32 err = 0;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = cmd;
+-	ioc.buf = arg;
+-	ioc.len = len;
+-	strcpy(ifr.ifr_name, dev->name);
+-	ifr.ifr_data = (caddr_t)&ioc;
+-
+-	fs = get_fs();
+-	set_fs(get_ds());
+-	err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-	set_fs(fs);
+-
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+-			 enum nl80211_iftype type, u32 *flags,
+-			 struct vif_params *params)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wireless_dev *wdev;
+-	s32 infra = 0;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	switch (type) {
+-	case NL80211_IFTYPE_MONITOR:
+-	case NL80211_IFTYPE_WDS:
+-		WL_ERR("type (%d) : currently we do not support this type\n",
+-		       type);
+-		return -EOPNOTSUPP;
+-	case NL80211_IFTYPE_ADHOC:
+-		wl->conf->mode = WL_MODE_IBSS;
+-		infra = 0;
+-		break;
+-	case NL80211_IFTYPE_STATION:
+-		wl->conf->mode = WL_MODE_BSS;
+-		infra = 1;
+-		break;
+-	default:
+-		err = -EINVAL;
+-		goto done;
+-	}
+-
+-	infra = cpu_to_le32(infra);
+-	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
+-		err = -EAGAIN;
+-	} else {
+-		wdev = ndev->ieee80211_ptr;
+-		wdev->iftype = type;
+-	}
+-
+-	WL_INFO("IF Type = %s\n",
+-		(wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
+-
+-done:
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
+-{
+-	memcpy(params->bssid, ether_bcast, ETH_ALEN);
+-	params->bss_type = DOT11_BSSTYPE_ANY;
+-	params->scan_type = 0;
+-	params->nprobes = -1;
+-	params->active_time = -1;
+-	params->passive_time = -1;
+-	params->home_time = -1;
+-	params->channel_num = 0;
+-
+-	params->nprobes = cpu_to_le32(params->nprobes);
+-	params->active_time = cpu_to_le32(params->active_time);
+-	params->passive_time = cpu_to_le32(params->passive_time);
+-	params->home_time = cpu_to_le32(params->home_time);
+-	if (ssid && ssid->SSID_len)
+-		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+-
+-}
+-
+-static s32
+-wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
+-		    s32 paramlen, void *bufptr, s32 buflen)
+-{
+-	s32 iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	BUG_ON(!iolen);
+-
+-	return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
+-}
+-
+-static s32
+-wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
+-		    s32 paramlen, void *bufptr, s32 buflen)
+-{
+-	s32 iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	BUG_ON(!iolen);
+-
+-	return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
+-}
+-
+-static s32
+-wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
+-{
+-	s32 params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+-	struct wl_iscan_params *params;
+-	s32 err = 0;
+-
+-	if (ssid && ssid->SSID_len)
+-		params_size += sizeof(struct wlc_ssid);
+-	params = kzalloc(params_size, GFP_KERNEL);
+-	if (unlikely(!params))
+-		return -ENOMEM;
+-	BUG_ON(params_size >= WLC_IOCTL_SMLEN);
+-
+-	wl_iscan_prep(&params->params, ssid);
+-
+-	params->version = cpu_to_le32(ISCAN_REQ_VERSION);
+-	params->action = cpu_to_le16(action);
+-	params->scan_duration = cpu_to_le16(0);
+-
+-	/* params_size += offsetof(wl_iscan_params_t, params); */
+-	err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
+-				iscan->ioctl_buf, WLC_IOCTL_SMLEN);
+-	if (unlikely(err)) {
+-		if (err == -EBUSY) {
+-			WL_INFO("system busy : iscan canceled\n");
+-		} else {
+-			WL_ERR("error (%d)\n", err);
+-		}
+-	}
+-	kfree(params);
+-	return err;
+-}
+-
+-static s32 wl_do_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	struct wlc_ssid ssid;
+-	s32 passive_scan;
+-	s32 err = 0;
+-
+-	/* Broadcast scan by default */
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-	iscan->state = WL_ISCAN_STATE_SCANING;
+-
+-	passive_scan = wl->active_scan ? 0 : 1;
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
+-			&passive_scan, sizeof(passive_scan));
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	wl_set_mpc(ndev, 0);
+-	wl->iscan_kickstart = true;
+-	wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32
+-__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-		   struct cfg80211_scan_request *request,
+-		   struct cfg80211_ssid *this_ssid)
+-{
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-	struct cfg80211_ssid *ssids;
+-	struct wl_scan_req *sr = wl_to_sr(wl);
+-	s32 passive_scan;
+-	bool iscan_req;
+-	bool spec_scan;
+-	s32 err = 0;
+-
+-	if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scanning already : status (%d)\n", (int)wl->status);
+-		return -EAGAIN;
+-	}
+-	if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
+-		WL_ERR("Scanning being aborted : status (%d)\n",
+-		       (int)wl->status);
+-		return -EAGAIN;
+-	}
+-	if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
+-		WL_ERR("Connecting : status (%d)\n",
+-		       (int)wl->status);
+-		return -EAGAIN;
+-	}
+-
+-	iscan_req = false;
+-	spec_scan = false;
+-	if (request) {
+-		/* scan bss */
+-		ssids = request->ssids;
+-		if (wl->iscan_on && (!ssids || !ssids->ssid_len))
+-			iscan_req = true;
+-	} else {
+-		/* scan in ibss */
+-		/* we don't do iscan in ibss */
+-		ssids = this_ssid;
+-	}
+-
+-	wl->scan_request = request;
+-	set_bit(WL_STATUS_SCANNING, &wl->status);
+-	if (iscan_req) {
+-		err = wl_do_iscan(wl);
+-		if (likely(!err))
+-			return err;
+-		else
+-			goto scan_out;
+-	} else {
+-		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
+-		       ssids->ssid, ssids->ssid_len);
+-		memset(&sr->ssid, 0, sizeof(sr->ssid));
+-		sr->ssid.SSID_len =
+-			    min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
+-		if (sr->ssid.SSID_len) {
+-			memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
+-			sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
+-			spec_scan = true;
+-		} else {
+-			WL_SCAN("Broadcast scan\n");
+-		}
+-
+-		passive_scan = wl->active_scan ? 0 : 1;
+-		err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+-				&passive_scan, sizeof(passive_scan));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
+-			goto scan_out;
+-		}
+-		wl_set_mpc(ndev, 0);
+-		err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
+-				sizeof(sr->ssid));
+-		if (err) {
+-			if (err == -EBUSY) {
+-				WL_INFO("system busy : scan for \"%s\" canceled\n",
+-					sr->ssid.SSID);
+-			} else {
+-				WL_ERR("WLC_SCAN error (%d)\n", err);
+-			}
+-			wl_set_mpc(ndev, 1);
+-			goto scan_out;
+-		}
+-	}
+-
+-	return 0;
+-
+-scan_out:
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	wl->scan_request = NULL;
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-		 struct cfg80211_scan_request *request)
+-{
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	CHECK_SYS_UP();
+-
+-	err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
+-	if (unlikely(err))
+-		WL_ERR("scan error (%d)\n", err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
+-{
+-	s8 buf[WLC_IOCTL_SMLEN];
+-	u32 len;
+-	s32 err = 0;
+-
+-	val = cpu_to_le32(val);
+-	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+-	BUG_ON(!len);
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32
+-wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
+-{
+-	union {
+-		s8 buf[WLC_IOCTL_SMLEN];
+-		s32 val;
+-	} var;
+-	u32 len;
+-	u32 data_null;
+-	s32 err = 0;
+-
+-	len =
+-	    bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
+-			sizeof(var.buf));
+-	BUG_ON(!len);
+-	err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	*retval = le32_to_cpu(var.val);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
+-	if (unlikely(err))
+-		WL_ERR("Error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
+-	if (unlikely(err))
+-		WL_ERR("Error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
+-{
+-	s32 err = 0;
+-	u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
+-
+-	retry = cpu_to_le32(retry);
+-	err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
+-	if (unlikely(err)) {
+-		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
+-		return err;
+-	}
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+-	    (wl->conf->rts_threshold != wiphy->rts_threshold)) {
+-		wl->conf->rts_threshold = wiphy->rts_threshold;
+-		err = wl_set_rts(ndev, wl->conf->rts_threshold);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+-	    (wl->conf->frag_threshold != wiphy->frag_threshold)) {
+-		wl->conf->frag_threshold = wiphy->frag_threshold;
+-		err = wl_set_frag(ndev, wl->conf->frag_threshold);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_RETRY_LONG
+-	    && (wl->conf->retry_long != wiphy->retry_long)) {
+-		wl->conf->retry_long = wiphy->retry_long;
+-		err = wl_set_retry(ndev, wl->conf->retry_long, true);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_RETRY_SHORT
+-	    && (wl->conf->retry_short != wiphy->retry_short)) {
+-		wl->conf->retry_short = wiphy->retry_short;
+-		err = wl_set_retry(ndev, wl->conf->retry_short, false);
+-		if (!err)
+-			goto done;
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_ibss_params *params)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wl_join_params join_params;
+-	size_t join_params_size = 0;
+-	s32 err = 0;
+-	s32 wsec = 0;
+-	s32 bcnprd;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (params->ssid)
+-		WL_CONN("SSID: %s\n", params->ssid);
+-	else {
+-		WL_CONN("SSID: NULL, Not supported\n");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	if (params->bssid)
+-		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
+-		params->bssid[0], params->bssid[1], params->bssid[2],
+-		params->bssid[3], params->bssid[4], params->bssid[5]);
+-	else
+-		WL_CONN("No BSSID specified\n");
+-
+-	if (params->channel)
+-		WL_CONN("channel: %d\n", params->channel->center_freq);
+-	else
+-		WL_CONN("no channel specified\n");
+-
+-	if (params->channel_fixed)
+-		WL_CONN("fixed channel required\n");
+-	else
+-		WL_CONN("no fixed channel required\n");
+-
+-	if (params->ie && params->ie_len)
+-		WL_CONN("ie len: %d\n", params->ie_len);
+-	else
+-		WL_CONN("no ie specified\n");
+-
+-	if (params->beacon_interval)
+-		WL_CONN("beacon interval: %d\n", params->beacon_interval);
+-	else
+-		WL_CONN("no beacon interval specified\n");
+-
+-	if (params->basic_rates)
+-		WL_CONN("basic rates: %08X\n", params->basic_rates);
+-	else
+-		WL_CONN("no basic rates specified\n");
+-
+-	if (params->privacy)
+-		WL_CONN("privacy required\n");
+-	else
+-		WL_CONN("no privacy required\n");
+-
+-	/* Configure Privacy for starter */
+-	if (params->privacy)
+-		wsec |= WEP_ENABLED;
+-
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("wsec failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	/* Configure Beacon Interval for starter */
+-	if (params->beacon_interval)
+-		bcnprd = cpu_to_le32(params->beacon_interval);
+-	else
+-		bcnprd = cpu_to_le32(100);
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	/* Configure required join parameter */
+-	memset(&join_params, 0, sizeof(wl_join_params_t));
+-
+-	/* SSID */
+-	join_params.ssid.SSID_len =
+-			(params->ssid_len > 32) ? 32 : params->ssid_len;
+-	memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
+-	join_params_size = sizeof(join_params.ssid);
+-	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+-
+-	/* BSSID */
+-	if (params->bssid) {
+-		memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
+-		join_params_size =
+-			sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE;
+-	} else {
+-		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-	}
+-	wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID);
+-
+-	/* Channel */
+-	if (params->channel) {
+-		u32 target_channel;
+-
+-		wl->channel =
+-			ieee80211_frequency_to_channel(
+-				params->channel->center_freq);
+-		if (params->channel_fixed) {
+-			/* adding chanspec */
+-			wl_ch_to_chanspec(wl->channel,
+-				&join_params, &join_params_size);
+-		}
+-
+-		/* set channel for starter */
+-		target_channel = cpu_to_le32(wl->channel);
+-		err = wl_dev_ioctl(dev, WLC_SET_CHANNEL,
+-			&target_channel, sizeof(target_channel));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
+-			goto done;
+-		}
+-	} else
+-		wl->channel = 0;
+-
+-	wl->ibss_starter = false;
+-
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	set_bit(WL_STATUS_CONNECTING, &wl->status);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	wl_link_down(wl);
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+-		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+-	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+-		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+-	else
+-		val = WPA_AUTH_DISABLED;
+-	WL_CONN("setting wpa_auth to 0x%0x\n", val);
+-	err = wl_dev_intvar_set(dev, "wpa_auth", val);
+-	if (unlikely(err)) {
+-		WL_ERR("set wpa_auth failed (%d)\n", err);
+-		return err;
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->wpa_versions = sme->crypto.wpa_versions;
+-	return err;
+-}
+-
+-static s32
+-wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	switch (sme->auth_type) {
+-	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+-		val = 0;
+-		WL_CONN("open system\n");
+-		break;
+-	case NL80211_AUTHTYPE_SHARED_KEY:
+-		val = 1;
+-		WL_CONN("shared key\n");
+-		break;
+-	case NL80211_AUTHTYPE_AUTOMATIC:
+-		val = 2;
+-		WL_CONN("automatic\n");
+-		break;
+-	case NL80211_AUTHTYPE_NETWORK_EAP:
+-		WL_CONN("network eap\n");
+-	default:
+-		val = 2;
+-		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
+-		break;
+-	}
+-
+-	err = wl_dev_intvar_set(dev, "auth", val);
+-	if (unlikely(err)) {
+-		WL_ERR("set auth failed (%d)\n", err);
+-		return err;
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->auth_type = sme->auth_type;
+-	return err;
+-}
+-
+-static s32
+-wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 pval = 0;
+-	s32 gval = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.n_ciphers_pairwise) {
+-		switch (sme->crypto.ciphers_pairwise[0]) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			pval = WEP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			pval = TKIP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			pval = AES_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			pval = AES_ENABLED;
+-			break;
+-		default:
+-			WL_ERR("invalid cipher pairwise (%d)\n",
+-			       sme->crypto.ciphers_pairwise[0]);
+-			return -EINVAL;
+-		}
+-	}
+-	if (sme->crypto.cipher_group) {
+-		switch (sme->crypto.cipher_group) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			gval = WEP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			gval = TKIP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			gval = AES_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			gval = AES_ENABLED;
+-			break;
+-		default:
+-			WL_ERR("invalid cipher group (%d)\n",
+-			       sme->crypto.cipher_group);
+-			return -EINVAL;
+-		}
+-	}
+-
+-	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
+-	err = wl_dev_intvar_set(dev, "wsec", pval | gval);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
+-	sec->cipher_group = sme->crypto.cipher_group;
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.n_akm_suites) {
+-		err = wl_dev_intvar_get(dev, "wpa_auth", &val);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get wpa_auth (%d)\n", err);
+-			return err;
+-		}
+-		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+-			switch (sme->crypto.akm_suites[0]) {
+-			case WLAN_AKM_SUITE_8021X:
+-				val = WPA_AUTH_UNSPECIFIED;
+-				break;
+-			case WLAN_AKM_SUITE_PSK:
+-				val = WPA_AUTH_PSK;
+-				break;
+-			default:
+-				WL_ERR("invalid cipher group (%d)\n",
+-				       sme->crypto.cipher_group);
+-				return -EINVAL;
+-			}
+-		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+-			switch (sme->crypto.akm_suites[0]) {
+-			case WLAN_AKM_SUITE_8021X:
+-				val = WPA2_AUTH_UNSPECIFIED;
+-				break;
+-			case WLAN_AKM_SUITE_PSK:
+-				val = WPA2_AUTH_PSK;
+-				break;
+-			default:
+-				WL_ERR("invalid cipher group (%d)\n",
+-				       sme->crypto.cipher_group);
+-				return -EINVAL;
+-			}
+-		}
+-
+-		WL_CONN("setting wpa_auth to %d\n", val);
+-		err = wl_dev_intvar_set(dev, "wpa_auth", val);
+-		if (unlikely(err)) {
+-			WL_ERR("could not set wpa_auth (%d)\n", err);
+-			return err;
+-		}
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->wpa_auth = sme->crypto.akm_suites[0];
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_set_sharedkey(struct net_device *dev,
+-		     struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	struct wl_wsec_key key;
+-	s32 val;
+-	s32 err = 0;
+-
+-	WL_CONN("key len (%d)\n", sme->key_len);
+-	if (sme->key_len) {
+-		sec = wl_read_prof(wl, WL_PROF_SEC);
+-		WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+-		       sec->wpa_versions, sec->cipher_pairwise);
+-		if (!
+-		    (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
+-					  NL80211_WPA_VERSION_2))
+-&& (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
+-			    WLAN_CIPHER_SUITE_WEP104))) {
+-			memset(&key, 0, sizeof(key));
+-			key.len = (u32) sme->key_len;
+-			key.index = (u32) sme->key_idx;
+-			if (unlikely(key.len > sizeof(key.data))) {
+-				WL_ERR("Too long key length (%u)\n", key.len);
+-				return -EINVAL;
+-			}
+-			memcpy(key.data, sme->key, key.len);
+-			key.flags = WL_PRIMARY_KEY;
+-			switch (sec->cipher_pairwise) {
+-			case WLAN_CIPHER_SUITE_WEP40:
+-				key.algo = CRYPTO_ALGO_WEP1;
+-				break;
+-			case WLAN_CIPHER_SUITE_WEP104:
+-				key.algo = CRYPTO_ALGO_WEP128;
+-				break;
+-			default:
+-				WL_ERR("Invalid algorithm (%d)\n",
+-				       sme->crypto.ciphers_pairwise[0]);
+-				return -EINVAL;
+-			}
+-			/* Set the new key/index */
+-			WL_CONN("key length (%d) key index (%d) algo (%d)\n",
+-			       key.len, key.index, key.algo);
+-			WL_CONN("key \"%s\"\n", key.data);
+-			swap_key_from_BE(&key);
+-			err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
+-					sizeof(key));
+-			if (unlikely(err)) {
+-				WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-				return err;
+-			}
+-			if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
+-				WL_CONN("set auth_type to shared key\n");
+-				val = 1;	/* shared key */
+-				err = wl_dev_intvar_set(dev, "auth", val);
+-				if (unlikely(err)) {
+-					WL_ERR("set auth failed (%d)\n", err);
+-					return err;
+-				}
+-			}
+-		}
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+-		    struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct ieee80211_channel *chan = sme->channel;
+-	struct wl_join_params join_params;
+-	size_t join_params_size;
+-
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (unlikely(!sme->ssid)) {
+-		WL_ERR("Invalid ssid\n");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	if (chan) {
+-		wl->channel =
+-			ieee80211_frequency_to_channel(chan->center_freq);
+-		WL_CONN("channel (%d), center_req (%d)\n",
+-			wl->channel, chan->center_freq);
+-	} else
+-		wl->channel = 0;
+-
+-	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+-
+-	err = wl_set_wpa_version(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_auth_type(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_set_cipher(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_key_mgmt(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_set_sharedkey(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
+-	/*
+-	 **  Join with specific BSSID and cached SSID
+-	 **  If SSID is zero join based on BSSID only
+-	 */
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
+-	memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
+-	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+-
+-	if (sme->bssid)
+-		memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
+-	else
+-		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-
+-	if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
+-		WL_CONN("ssid \"%s\", len (%d)\n",
+-		       join_params.ssid.SSID, join_params.ssid.SSID_len);
+-	}
+-
+-	wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
+-	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	set_bit(WL_STATUS_CONNECTING, &wl->status);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+-		       u16 reason_code)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	scb_val_t scbval;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter. Reason code = %d\n", reason_code);
+-	CHECK_SYS_UP();
+-
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	scbval.val = reason_code;
+-	memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN);
+-	scbval.val = cpu_to_le32(scbval.val);
+-	err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
+-			sizeof(scb_val_t));
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	wl->link_up = false;
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+-			 enum nl80211_tx_power_setting type, s32 dbm)
+-{
+-
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	u16 txpwrmw;
+-	s32 err = 0;
+-	s32 disable = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	switch (type) {
+-	case NL80211_TX_POWER_AUTOMATIC:
+-		break;
+-	case NL80211_TX_POWER_LIMITED:
+-		if (dbm < 0) {
+-			WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
+-			err = -EINVAL;
+-			goto done;
+-		}
+-		break;
+-	case NL80211_TX_POWER_FIXED:
+-		if (dbm < 0) {
+-			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
+-			err = -EINVAL;
+-			goto done;
+-		}
+-		break;
+-	}
+-	/* Make sure radio is off or on as far as software is concerned */
+-	disable = WL_RADIO_SW_DISABLE << 16;
+-	disable = cpu_to_le32(disable);
+-	err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
+-	if (unlikely(err))
+-		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
+-
+-	if (dbm > 0xffff)
+-		txpwrmw = 0xffff;
+-	else
+-		txpwrmw = (u16) dbm;
+-	err = wl_dev_intvar_set(ndev, "qtxpower",
+-			(s32) (bcm_mw_to_qdbm(txpwrmw)));
+-	if (unlikely(err))
+-		WL_ERR("qtxpower error (%d)\n", err);
+-	wl->conf->tx_power = dbm;
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	s32 txpwrdbm;
+-	u8 result;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+-	*dbm = (s32) bcm_qdbm_to_mw(result);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
+-			       u8 key_idx, bool unicast, bool multicast)
+-{
+-	u32 index;
+-	s32 wsec;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	wsec = le32_to_cpu(wsec);
+-	if (wsec & WEP_ENABLED) {
+-		/* Just select a new current key */
+-		index = (u32) key_idx;
+-		index = cpu_to_le32(index);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
+-				sizeof(index));
+-		if (unlikely(err))
+-			WL_ERR("error (%d)\n", err);
+-	}
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+-	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
+-{
+-	struct wl_wsec_key key;
+-	s32 err = 0;
+-
+-	memset(&key, 0, sizeof(key));
+-	key.index = (u32) key_idx;
+-	/* Instead of bcast for ea address for default wep keys,
+-		 driver needs it to be Null */
+-	if (!is_multicast_ether_addr(mac_addr))
+-		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
+-	key.len = (u32) params->key_len;
+-	/* check for key index change */
+-	if (key.len == 0) {
+-		/* key delete */
+-		swap_key_from_BE(&key);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (unlikely(err)) {
+-			WL_ERR("key delete error (%d)\n", err);
+-			return err;
+-		}
+-	} else {
+-		if (key.len > sizeof(key.data)) {
+-			WL_ERR("Invalid key length (%d)\n", key.len);
+-			return -EINVAL;
+-		}
+-
+-		WL_CONN("Setting the key index %d\n", key.index);
+-		memcpy(key.data, params->key, key.len);
+-
+-		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
+-			u8 keybuf[8];
+-			memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-			memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		}
+-
+-		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
+-		if (params->seq && params->seq_len == 6) {
+-			/* rx iv */
+-			u8 *ivptr;
+-			ivptr = (u8 *) params->seq;
+-			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+-			    (ivptr[3] << 8) | ivptr[2];
+-			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+-			key.iv_initialized = true;
+-		}
+-
+-		switch (params->cipher) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-			key.algo = CRYPTO_ALGO_WEP1;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			key.algo = CRYPTO_ALGO_WEP128;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
+-			break;
+-		default:
+-			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
+-			return -EINVAL;
+-		}
+-		swap_key_from_BE(&key);
+-
+-		dhd_wait_pend8021x(dev);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-			return err;
+-		}
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr,
+-		    struct key_params *params)
+-{
+-	struct wl_wsec_key key;
+-	s32 val;
+-	s32 wsec;
+-	s32 err = 0;
+-	u8 keybuf[8];
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	if (mac_addr) {
+-		WL_TRACE("Exit");
+-		return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
+-	}
+-	memset(&key, 0, sizeof(key));
+-
+-	key.len = (u32) params->key_len;
+-	key.index = (u32) key_idx;
+-
+-	if (unlikely(key.len > sizeof(key.data))) {
+-		WL_ERR("Too long key length (%u)\n", key.len);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-	memcpy(key.data, params->key, key.len);
+-
+-	key.flags = WL_PRIMARY_KEY;
+-	switch (params->cipher) {
+-	case WLAN_CIPHER_SUITE_WEP40:
+-		key.algo = CRYPTO_ALGO_WEP1;
+-		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_WEP104:
+-		key.algo = CRYPTO_ALGO_WEP128;
+-		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_TKIP:
+-		memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-		memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		key.algo = CRYPTO_ALGO_TKIP;
+-		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_AES_CMAC:
+-		key.algo = CRYPTO_ALGO_AES_CCM;
+-		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_CCMP:
+-		key.algo = CRYPTO_ALGO_AES_CCM;
+-		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
+-		break;
+-	default:
+-		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Set the new key/index */
+-	swap_key_from_BE(&key);
+-	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	val = WEP_ENABLED;
+-	err = wl_dev_intvar_get(dev, "wsec", &wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("get wsec error (%d)\n", err);
+-		goto done;
+-	}
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("set wsec error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	val = 1;		/* assume shared key. otherwise 0 */
+-	val = cpu_to_le32(val);
+-	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (unlikely(err))
+-		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr)
+-{
+-	struct wl_wsec_key key;
+-	s32 err = 0;
+-	s32 val;
+-	s32 wsec;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-	memset(&key, 0, sizeof(key));
+-
+-	key.index = (u32) key_idx;
+-	key.flags = WL_PRIMARY_KEY;
+-	key.algo = CRYPTO_ALGO_OFF;
+-
+-	WL_CONN("key index (%d)\n", key_idx);
+-	/* Set the new key/index */
+-	swap_key_from_BE(&key);
+-	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-	if (unlikely(err)) {
+-		if (err == -EINVAL) {
+-			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-				/* we ignore this key index in this case */
+-				WL_ERR("invalid key index (%d)\n", key_idx);
+-		} else
+-			WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-
+-	val = 0;
+-	err = wl_dev_intvar_get(dev, "wsec", &wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("get wsec error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("set wsec error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-
+-	val = 0;		/* assume open key. otherwise 1 */
+-	val = cpu_to_le32(val);
+-	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-	}
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
+-		    void (*callback) (void *cookie, struct key_params * params))
+-{
+-	struct key_params params;
+-	struct wl_wsec_key key;
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wl_security *sec;
+-	s32 wsec;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	memset(&key, 0, sizeof(key));
+-	key.index = key_idx;
+-	swap_key_to_BE(&key);
+-	memset(&params, 0, sizeof(params));
+-	params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
+-	memcpy(params.key, key.data, params.key_len);
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-	wsec = le32_to_cpu(wsec);
+-	switch (wsec) {
+-	case WEP_ENABLED:
+-		sec = wl_read_prof(wl, WL_PROF_SEC);
+-		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
+-			params.cipher = WLAN_CIPHER_SUITE_WEP40;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
+-			params.cipher = WLAN_CIPHER_SUITE_WEP104;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-		}
+-		break;
+-	case TKIP_ENABLED:
+-		params.cipher = WLAN_CIPHER_SUITE_TKIP;
+-		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-		break;
+-	case AES_ENABLED:
+-		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+-		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-		break;
+-	default:
+-		WL_ERR("Invalid algo (0x%x)\n", wsec);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-	callback(cookie, &params);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+-				    struct net_device *dev, u8 key_idx)
+-{
+-	WL_INFO("Not supported\n");
+-
+-	CHECK_SYS_UP();
+-	return -EOPNOTSUPP;
+-}
+-
+-static s32
+-wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+-			u8 *mac, struct station_info *sinfo)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	scb_val_t scb_val;
+-	int rssi;
+-	s32 rate;
+-	s32 err = 0;
+-	u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID);
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (unlikely
+-	    (memcmp(mac, bssid, ETH_ALEN))) {
+-		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
+-			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
+-			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+-			bssid[0], bssid[1], bssid[2], bssid[3],
+-			bssid[4], bssid[5]);
+-		err = -ENOENT;
+-		goto done;
+-	}
+-
+-	/* Report the current tx rate */
+-	err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+-	if (err) {
+-		WL_ERR("Could not get rate (%d)\n", err);
+-	} else {
+-		rate = le32_to_cpu(rate);
+-		sinfo->filled |= STATION_INFO_TX_BITRATE;
+-		sinfo->txrate.legacy = rate * 5;
+-		WL_CONN("Rate %d Mbps\n", rate / 2);
+-	}
+-
+-	if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
+-		scb_val.val = 0;
+-		err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+-				sizeof(scb_val_t));
+-		if (unlikely(err)) {
+-			WL_ERR("Could not get rssi (%d)\n", err);
+-		}
+-		rssi = le32_to_cpu(scb_val.val);
+-		sinfo->filled |= STATION_INFO_SIGNAL;
+-		sinfo->signal = rssi;
+-		WL_CONN("RSSI %d dBm\n", rssi);
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+-			   bool enabled, s32 timeout)
+-{
+-	s32 pm;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	pm = enabled ? PM_FAST : PM_OFF;
+-	pm = cpu_to_le32(pm);
+-	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+-	if (unlikely(err)) {
+-		if (err == -ENODEV)
+-			WL_ERR("net_device is not ready yet\n");
+-		else
+-			WL_ERR("error (%d)\n", err);
+-	}
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static __used u32 wl_find_msb(u16 bit16)
+-{
+-	u32 ret = 0;
+-
+-	if (bit16 & 0xff00) {
+-		ret += 8;
+-		bit16 >>= 8;
+-	}
+-
+-	if (bit16 & 0xf0) {
+-		ret += 4;
+-		bit16 >>= 4;
+-	}
+-
+-	if (bit16 & 0xc) {
+-		ret += 2;
+-		bit16 >>= 2;
+-	}
+-
+-	if (bit16 & 2)
+-		ret += bit16 & 2;
+-	else if (bit16)
+-		ret += bit16;
+-
+-	return ret;
+-}
+-
+-static s32
+-wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
+-			     const u8 *addr,
+-			     const struct cfg80211_bitrate_mask *mask)
+-{
+-	struct wl_rateset rateset;
+-	s32 rate;
+-	s32 val;
+-	s32 err_bg;
+-	s32 err_a;
+-	u32 legacy;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	/* addr param is always NULL. ignore it */
+-	/* Get current rateset */
+-	err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-			sizeof(rateset));
+-	if (unlikely(err)) {
+-		WL_ERR("could not get current rateset (%d)\n", err);
+-		goto done;
+-	}
+-
+-	rateset.count = le32_to_cpu(rateset.count);
+-
+-	legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
+-	if (!legacy)
+-		legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
+-
+-	val = wl_g_rates[legacy - 1].bitrate * 100000;
+-
+-	if (val < rateset.count)
+-		/* Select rate by rateset index */
+-		rate = rateset.rates[val] & 0x7f;
+-	else
+-		/* Specified rate in bps */
+-		rate = val / 500000;
+-
+-	WL_CONN("rate %d mbps\n", rate / 2);
+-
+-	/*
+-	 *
+-	 *      Set rate override,
+-	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
+-	 */
+-	err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
+-	err_a = wl_dev_intvar_set(dev, "a_rate", rate);
+-	if (unlikely(err_bg && err_a)) {
+-		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
+-		err = err_bg | err_a;
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_resume(struct wiphy *wiphy)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	/*
+-	 * Check for WL_STATUS_READY before any function call which
+-	 * could result is bus access. Don't block the resume for
+-	 * any driver error conditions
+-	 */
+-	WL_TRACE("Enter\n");
+-
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, false);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		/* Turn on Watchdog timer */
+-		wl_os_wd_timer(ndev, dhd_watchdog_ms);
+-		wl_invoke_iscan(wiphy_to_wl(wiphy));
+-	}
+-
+-	WL_TRACE("Exit\n");
+-	return 0;
+-}
+-
+-static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	WL_TRACE("Enter\n");
+-
+-	/*
+-	 * Check for WL_STATUS_READY before any function call which
+-	 * could result is bus access. Don't block the suspend for
+-	 * any driver error conditions
+-	 */
+-
+-	/*
+-	 * While going to suspend if associated with AP disassociate
+-	 * from AP to save power while system is in suspended state
+-	 */
+-	if (test_bit(WL_STATUS_CONNECTED, &wl->status) &&
+-		test_bit(WL_STATUS_READY, &wl->status)) {
+-		WL_INFO("Disassociating from AP"
+-			" while entering suspend state\n");
+-		wl_link_down(wl);
+-
+-		/*
+-		 * Make sure WPA_Supplicant receives all the event
+-		 * generated due to DISASSOC call to the fw to keep
+-		 * the state fw and WPA_Supplicant state consistent
+-		 */
+-		rtnl_unlock();
+-		wl_delay(500);
+-		rtnl_lock();
+-	}
+-
+-	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	if (test_bit(WL_STATUS_READY, &wl->status))
+-		wl_term_iscan(wl);
+-
+-	if (wl->scan_request) {
+-		/* Indidate scan abort to cfg80211 layer */
+-		WL_INFO("Terminating scan in progress\n");
+-		cfg80211_scan_done(wl->scan_request, true);
+-		wl->scan_request = NULL;
+-	}
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	/* Inform SDIO stack not to switch off power to the chip */
+-	sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER);
+-
+-	/* Turn off watchdog timer */
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		WL_INFO("Terminate watchdog timer and enable MPC\n");
+-		wl_set_mpc(ndev, 1);
+-		wl_os_wd_timer(ndev, 0);
+-	}
+-
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, true);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-	WL_TRACE("Exit\n");
+-
+-	return 0;
+-}
+-
+-static __used s32
+-wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
+-		  s32 err)
+-{
+-	int i, j;
+-
+-	WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
+-	for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
+-		WL_CONN("PMKID[%d]: %pM =\n", i,
+-			&pmk_list->pmkids.pmkid[i].BSSID);
+-		for (j = 0; j < WLAN_PMKID_LEN; j++)
+-			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
+-	}
+-
+-	if (likely(!err))
+-		wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
+-					sizeof(*pmk_list));
+-
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_pmksa *pmksa)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-	int i;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+-		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+-			    ETH_ALEN))
+-			break;
+-	if (i < WL_NUM_PMKIDS_MAX) {
+-		memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
+-		       ETH_ALEN);
+-		memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
+-		       WLAN_PMKID_LEN);
+-		if (i == wl->pmk_list->pmkids.npmkid)
+-			wl->pmk_list->pmkids.npmkid++;
+-	} else
+-		err = -EINVAL;
+-
+-	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
+-	       &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
+-	for (i = 0; i < WLAN_PMKID_LEN; i++)
+-		WL_CONN("%02x\n",
+-		       wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
+-		       PMKID[i]);
+-
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_pmksa *pmksa)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct _pmkid_list pmkid;
+-	s32 err = 0;
+-	int i;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
+-	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
+-
+-	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
+-	       &pmkid.pmkid[0].BSSID);
+-	for (i = 0; i < WLAN_PMKID_LEN; i++)
+-		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
+-
+-	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+-		if (!memcmp
+-		    (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+-		     ETH_ALEN))
+-			break;
+-
+-	if ((wl->pmk_list->pmkids.npmkid > 0)
+-	    && (i < wl->pmk_list->pmkids.npmkid)) {
+-		memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
+-		for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
+-			memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
+-			       &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
+-			       ETH_ALEN);
+-			memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
+-			       &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
+-			       WLAN_PMKID_LEN);
+-		}
+-		wl->pmk_list->pmkids.npmkid--;
+-	} else
+-		err = -EINVAL;
+-
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-
+-}
+-
+-static s32
+-wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-
+-}
+-
+-static struct cfg80211_ops wl_cfg80211_ops = {
+-	.change_virtual_intf = wl_cfg80211_change_iface,
+-	.scan = wl_cfg80211_scan,
+-	.set_wiphy_params = wl_cfg80211_set_wiphy_params,
+-	.join_ibss = wl_cfg80211_join_ibss,
+-	.leave_ibss = wl_cfg80211_leave_ibss,
+-	.get_station = wl_cfg80211_get_station,
+-	.set_tx_power = wl_cfg80211_set_tx_power,
+-	.get_tx_power = wl_cfg80211_get_tx_power,
+-	.add_key = wl_cfg80211_add_key,
+-	.del_key = wl_cfg80211_del_key,
+-	.get_key = wl_cfg80211_get_key,
+-	.set_default_key = wl_cfg80211_config_default_key,
+-	.set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
+-	.set_power_mgmt = wl_cfg80211_set_power_mgmt,
+-	.set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
+-	.connect = wl_cfg80211_connect,
+-	.disconnect = wl_cfg80211_disconnect,
+-	.suspend = wl_cfg80211_suspend,
+-	.resume = wl_cfg80211_resume,
+-	.set_pmksa = wl_cfg80211_set_pmksa,
+-	.del_pmksa = wl_cfg80211_del_pmksa,
+-	.flush_pmksa = wl_cfg80211_flush_pmksa
+-};
+-
+-static s32 wl_mode_to_nl80211_iftype(s32 mode)
+-{
+-	s32 err = 0;
+-
+-	switch (mode) {
+-	case WL_MODE_BSS:
+-		return NL80211_IFTYPE_STATION;
+-	case WL_MODE_IBSS:
+-		return NL80211_IFTYPE_ADHOC;
+-	default:
+-		return NL80211_IFTYPE_UNSPECIFIED;
+-	}
+-
+-	return err;
+-}
+-
+-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
+-					  struct device *dev)
+-{
+-	struct wireless_dev *wdev;
+-	s32 err = 0;
+-
+-	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+-	if (unlikely(!wdev)) {
+-		WL_ERR("Could not allocate wireless device\n");
+-		return ERR_PTR(-ENOMEM);
+-	}
+-	wdev->wiphy =
+-	    wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
+-	if (unlikely(!wdev->wiphy)) {
+-		WL_ERR("Couldn not allocate wiphy device\n");
+-		err = -ENOMEM;
+-		goto wiphy_new_out;
+-	}
+-	set_wiphy_dev(wdev->wiphy, dev);
+-	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+-	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+-	wdev->wiphy->interface_modes =
+-	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+-	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+-	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
+-						* it as 11a by default.
+-						* This will be updated with
+-						* 11n phy tables in
+-						* "ifconfig up"
+-						* if phy has 11n capability
+-						*/
+-	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+-	wdev->wiphy->cipher_suites = __wl_cipher_suites;
+-	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+-#ifndef WL_POWERSAVE_DISABLED
+-	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
+-								 * save mode
+-								 * by default
+-								 */
+-#else
+-	wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+-#endif				/* !WL_POWERSAVE_DISABLED */
+-	err = wiphy_register(wdev->wiphy);
+-	if (unlikely(err < 0)) {
+-		WL_ERR("Couldn not register wiphy device (%d)\n", err);
+-		goto wiphy_register_out;
+-	}
+-	return wdev;
+-
+-wiphy_register_out:
+-	wiphy_free(wdev->wiphy);
+-
+-wiphy_new_out:
+-	kfree(wdev);
+-
+-	return ERR_PTR(err);
+-}
+-
+-static void wl_free_wdev(struct wl_priv *wl)
+-{
+-	struct wireless_dev *wdev = wl_to_wdev(wl);
+-
+-	if (unlikely(!wdev)) {
+-		WL_ERR("wdev is invalid\n");
+-		return;
+-	}
+-	wiphy_unregister(wdev->wiphy);
+-	wiphy_free(wdev->wiphy);
+-	kfree(wdev);
+-	wl_to_wdev(wl) = NULL;
+-}
+-
+-static s32 wl_inform_bss(struct wl_priv *wl)
+-{
+-	struct wl_scan_results *bss_list;
+-	struct wl_bss_info *bi = NULL;	/* must be initialized */
+-	s32 err = 0;
+-	int i;
+-
+-	bss_list = wl->bss_list;
+-	if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
+-		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
+-		       bss_list->version);
+-		return -EOPNOTSUPP;
+-	}
+-	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
+-	bi = next_bss(bss_list, bi);
+-	for_each_bss(bss_list, bi, i) {
+-		err = wl_inform_single_bss(wl, bi);
+-		if (unlikely(err))
+-			break;
+-	}
+-	return err;
+-}
+-
+-
+-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	struct ieee80211_channel *notify_channel;
+-	struct cfg80211_bss *bss;
+-	struct ieee80211_supported_band *band;
+-	s32 err = 0;
+-	u16 channel;
+-	u32 freq;
+-	u64 notify_timestamp;
+-	u16 notify_capability;
+-	u16 notify_interval;
+-	u8 *notify_ie;
+-	size_t notify_ielen;
+-	s32 notify_signal;
+-
+-	if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
+-		WL_ERR("Bss info is larger than buffer. Discarding\n");
+-		return 0;
+-	}
+-
+-	channel = bi->ctl_ch ? bi->ctl_ch :
+-				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+-
+-	if (channel <= CH_MAX_2G_CHANNEL)
+-		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+-	else
+-		band = wiphy->bands[IEEE80211_BAND_5GHZ];
+-
+-	freq = ieee80211_channel_to_frequency(channel, band->band);
+-	notify_channel = ieee80211_get_channel(wiphy, freq);
+-
+-	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+-	notify_capability = le16_to_cpu(bi->capability);
+-	notify_interval = le16_to_cpu(bi->beacon_period);
+-	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+-	notify_ielen = le16_to_cpu(bi->ie_length);
+-	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+-
+-	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+-			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
+-			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
+-	WL_CONN("Channel: %d(%d)\n", channel, freq);
+-	WL_CONN("Capability: %X\n", notify_capability);
+-	WL_CONN("Beacon interval: %d\n", notify_interval);
+-	WL_CONN("Signal: %d\n", notify_signal);
+-	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+-
+-	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
+-		notify_timestamp, notify_capability, notify_interval, notify_ie,
+-		notify_ielen, notify_signal, GFP_KERNEL);
+-
+-	if (unlikely(!bss)) {
+-		WL_ERR("cfg80211_inform_bss_frame error\n");
+-		return -EINVAL;
+-	}
+-
+-	return err;
+-}
+-
+-static s32
+-wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	struct ieee80211_channel *notify_channel;
+-	struct wl_bss_info *bi = NULL;
+-	struct ieee80211_supported_band *band;
+-	u8 *buf = NULL;
+-	s32 err = 0;
+-	u16 channel;
+-	u32 freq;
+-	u64 notify_timestamp;
+-	u16 notify_capability;
+-	u16 notify_interval;
+-	u8 *notify_ie;
+-	size_t notify_ielen;
+-	s32 notify_signal;
+-
+-	WL_TRACE("Enter\n");
+-
+-	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+-	if (buf == NULL) {
+-		WL_ERR("kzalloc() failed\n");
+-		err = -ENOMEM;
+-		goto CleanUp;
+-	}
+-
+-	*(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
+-		goto CleanUp;
+-	}
+-
+-	bi = (wl_bss_info_t *)(buf + 4);
+-
+-	channel = bi->ctl_ch ? bi->ctl_ch :
+-				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+-
+-	if (channel <= CH_MAX_2G_CHANNEL)
+-		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+-	else
+-		band = wiphy->bands[IEEE80211_BAND_5GHZ];
+-
+-	freq = ieee80211_channel_to_frequency(channel, band->band);
+-	notify_channel = ieee80211_get_channel(wiphy, freq);
+-
+-	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+-	notify_capability = le16_to_cpu(bi->capability);
+-	notify_interval = le16_to_cpu(bi->beacon_period);
+-	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+-	notify_ielen = le16_to_cpu(bi->ie_length);
+-	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+-
+-	WL_CONN("channel: %d(%d)\n", channel, freq);
+-	WL_CONN("capability: %X\n", notify_capability);
+-	WL_CONN("beacon interval: %d\n", notify_interval);
+-	WL_CONN("signal: %d\n", notify_signal);
+-	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+-
+-	cfg80211_inform_bss(wiphy, notify_channel, bssid,
+-		notify_timestamp, notify_capability, notify_interval,
+-		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
+-
+-CleanUp:
+-
+-	kfree(buf);
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-
+-	if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) {
+-		WL_CONN("Processing set ssid\n");
+-		wl->link_up = true;
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u16 flags = be16_to_cpu(e->flags);
+-
+-	if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) {
+-		WL_CONN("Processing link down\n");
+-		return true;
+-	}
+-	return false;
+-}
+-
+-static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-	u16 flags = be16_to_cpu(e->flags);
+-
+-	if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) {
+-		WL_CONN("Processing Link %s & no network found\n",
+-				flags & WLC_EVENT_MSG_LINK ? "up" : "down");
+-		return true;
+-	}
+-
+-	if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
+-		WL_CONN("Processing connecting & no network found\n");
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static s32
+-wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+-			 const wl_event_msg_t *e, void *data)
+-{
+-	s32 err = 0;
+-
+-	if (wl_is_linkup(wl, e)) {
+-		WL_CONN("Linkup\n");
+-		if (wl_is_ibssmode(wl)) {
+-			wl_update_prof(wl, NULL, (void *)e->addr,
+-				WL_PROF_BSSID);
+-			wl_inform_ibss(wl, ndev, e->addr);
+-			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
+-			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-			set_bit(WL_STATUS_CONNECTED, &wl->status);
+-		} else
+-			wl_bss_connect_done(wl, ndev, e, data, true);
+-	} else if (wl_is_linkdown(wl, e)) {
+-		WL_CONN("Linkdown\n");
+-		if (wl_is_ibssmode(wl)) {
+-			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+-				&wl->status))
+-				wl_link_down(wl);
+-		} else {
+-			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+-				&wl->status)) {
+-				cfg80211_disconnected(ndev, 0, NULL, 0,
+-					GFP_KERNEL);
+-				wl_link_down(wl);
+-			}
+-		}
+-		wl_init_prof(wl->profile);
+-	} else if (wl_is_nonetwork(wl, e)) {
+-		if (wl_is_ibssmode(wl))
+-			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-		else
+-			wl_bss_connect_done(wl, ndev, e, data, false);
+-	}
+-
+-	return err;
+-}
+-
+-static s32
+-wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
+-			 const wl_event_msg_t *e, void *data)
+-{
+-	s32 err = 0;
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-
+-	if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
+-		if (test_bit(WL_STATUS_CONNECTED, &wl->status))
+-			wl_bss_roaming_done(wl, ndev, e, data);
+-		else
+-			wl_bss_connect_done(wl, ndev, e, data, true);
+-	}
+-
+-	return err;
+-}
+-
+-static __used s32
+-wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	u32 buflen;
+-
+-	buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+-	BUG_ON(!buflen);
+-
+-	return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
+-}
+-
+-static s32
+-wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
+-		  s32 buf_len)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	u32 len;
+-	s32 err = 0;
+-
+-	len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+-	BUG_ON(!len);
+-	err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
+-			WL_IOCTL_LEN_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	memcpy(buf, wl->ioctl_buf, buf_len);
+-
+-	return err;
+-}
+-
+-static s32 wl_get_assoc_ies(struct wl_priv *wl)
+-{
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	struct wl_assoc_ielen *assoc_info;
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	u32 req_len;
+-	u32 resp_len;
+-	s32 err = 0;
+-
+-	wl_clear_assoc_ies(wl);
+-
+-	err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
+-				WL_ASSOC_INFO_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("could not get assoc info (%d)\n", err);
+-		return err;
+-	}
+-	assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
+-	req_len = assoc_info->req_len;
+-	resp_len = assoc_info->resp_len;
+-	if (req_len) {
+-		err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
+-					WL_ASSOC_INFO_MAX);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get assoc req (%d)\n", err);
+-			return err;
+-		}
+-		conn_info->req_ie_len = req_len;
+-		conn_info->req_ie =
+-		    kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
+-	} else {
+-		conn_info->req_ie_len = 0;
+-		conn_info->req_ie = NULL;
+-	}
+-	if (resp_len) {
+-		err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
+-					WL_ASSOC_INFO_MAX);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get assoc resp (%d)\n", err);
+-			return err;
+-		}
+-		conn_info->resp_ie_len = resp_len;
+-		conn_info->resp_ie =
+-		    kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
+-	} else {
+-		conn_info->resp_ie_len = 0;
+-		conn_info->resp_ie = NULL;
+-	}
+-	WL_CONN("req len (%d) resp len (%d)\n",
+-	       conn_info->req_ie_len, conn_info->resp_ie_len);
+-
+-	return err;
+-}
+-
+-static void wl_clear_assoc_ies(struct wl_priv *wl)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-
+-	kfree(conn_info->req_ie);
+-	conn_info->req_ie = NULL;
+-	conn_info->req_ie_len = 0;
+-	kfree(conn_info->resp_ie);
+-	conn_info->resp_ie = NULL;
+-	conn_info->resp_ie_len = 0;
+-}
+-
+-
+-static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
+-	size_t *join_params_size)
+-{
+-	chanspec_t chanspec = 0;
+-
+-	if (ch != 0) {
+-		join_params->params.chanspec_num = 1;
+-		join_params->params.chanspec_list[0] = ch;
+-
+-		if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
+-			chanspec |= WL_CHANSPEC_BAND_2G;
+-		else
+-			chanspec |= WL_CHANSPEC_BAND_5G;
+-
+-		chanspec |= WL_CHANSPEC_BW_20;
+-		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+-
+-		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+-			join_params->params.chanspec_num * sizeof(chanspec_t);
+-
+-		join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+-		join_params->params.chanspec_list[0] |= chanspec;
+-		join_params->params.chanspec_list[0] =
+-		cpu_to_le16(join_params->params.chanspec_list[0]);
+-
+-		join_params->params.chanspec_num =
+-			cpu_to_le32(join_params->params.chanspec_num);
+-
+-		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
+-			"channel %d, chanspec %#X\n",
+-		       join_params->params.chanspec_list[0], ch, chanspec);
+-	}
+-}
+-
+-static s32 wl_update_bss_info(struct wl_priv *wl)
+-{
+-	struct wl_bss_info *bi;
+-	struct wlc_ssid *ssid;
+-	struct bcm_tlv *tim;
+-	u16 beacon_interval;
+-	u8 dtim_period;
+-	size_t ie_len;
+-	u8 *ie;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	if (wl_is_ibssmode(wl))
+-		return err;
+-
+-	ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
+-
+-	*(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
+-			wl->extra_buf, WL_EXTRA_BUF_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("Could not get bss info %d\n", err);
+-		goto update_bss_info_out;
+-	}
+-
+-	bi = (struct wl_bss_info *)(wl->extra_buf + 4);
+-	err = wl_inform_single_bss(wl, bi);
+-	if (unlikely(err))
+-		goto update_bss_info_out;
+-
+-	ie = ((u8 *)bi) + bi->ie_offset;
+-	ie_len = bi->ie_length;
+-	beacon_interval = cpu_to_le16(bi->beacon_period);
+-
+-	tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+-	if (tim)
+-		dtim_period = tim->data[1];
+-	else {
+-		/*
+-		* active scan was done so we could not get dtim
+-		* information out of probe response.
+-		* so we speficially query dtim information to dongle.
+-		*/
+-		u32 var;
+-		err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var);
+-		if (unlikely(err)) {
+-			WL_ERR("wl dtim_assoc failed (%d)\n", err);
+-			goto update_bss_info_out;
+-		}
+-		dtim_period = (u8)var;
+-	}
+-
+-	wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
+-	wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
+-
+-update_bss_info_out:
+-	WL_TRACE("Exit");
+-	return err;
+-}
+-
+-static s32
+-wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+-		    const wl_event_msg_t *e, void *data)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	wl_get_assoc_ies(wl);
+-	wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
+-	wl_update_bss_info(wl);
+-
+-	cfg80211_roamed(ndev, NULL,
+-			(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
+-			conn_info->req_ie, conn_info->req_ie_len,
+-			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
+-	WL_CONN("Report roaming result\n");
+-
+-	set_bit(WL_STATUS_CONNECTED, &wl->status);
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+-		    const wl_event_msg_t *e, void *data, bool completed)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
+-		if (completed) {
+-			wl_get_assoc_ies(wl);
+-			wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
+-			wl_update_bss_info(wl);
+-		}
+-		cfg80211_connect_result(ndev,
+-					(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
+-					conn_info->req_ie,
+-					conn_info->req_ie_len,
+-					conn_info->resp_ie,
+-					conn_info->resp_ie_len,
+-					completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
+-					GFP_KERNEL);
+-		if (completed)
+-			set_bit(WL_STATUS_CONNECTED, &wl->status);
+-		WL_CONN("Report connect result - connection %s\n",
+-				completed ? "succeeded" : "failed");
+-	}
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+-		     const wl_event_msg_t *e, void *data)
+-{
+-	u16 flags = be16_to_cpu(e->flags);
+-	enum nl80211_key_type key_type;
+-
+-	rtnl_lock();
+-	if (flags & WLC_EVENT_MSG_GROUP)
+-		key_type = NL80211_KEYTYPE_GROUP;
+-	else
+-		key_type = NL80211_KEYTYPE_PAIRWISE;
+-
+-	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
+-				     NULL, GFP_KERNEL);
+-	rtnl_unlock();
+-
+-	return 0;
+-}
+-
+-static s32
+-wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+-		      const wl_event_msg_t *e, void *data)
+-{
+-	struct channel_info channel_inform;
+-	struct wl_scan_results *bss_list;
+-	u32 len = WL_SCAN_BUF_MAX;
+-	s32 err = 0;
+-	bool scan_abort = false;
+-
+-	WL_TRACE("Enter\n");
+-
+-	if (wl->iscan_on && wl->iscan_kickstart) {
+-		WL_TRACE("Exit\n");
+-		return wl_wakeup_iscan(wl_to_iscan(wl));
+-	}
+-
+-	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scan complete while device not scanning\n");
+-		scan_abort = true;
+-		err = -EINVAL;
+-		goto scan_done_out;
+-	}
+-
+-	err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
+-			sizeof(channel_inform));
+-	if (unlikely(err)) {
+-		WL_ERR("scan busy (%d)\n", err);
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-	channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
+-	if (unlikely(channel_inform.scan_channel)) {
+-
+-		WL_CONN("channel_inform.scan_channel (%d)\n",
+-		       channel_inform.scan_channel);
+-	}
+-	wl->bss_list = wl->scan_results;
+-	bss_list = wl->bss_list;
+-	memset(bss_list, 0, len);
+-	bss_list->buflen = cpu_to_le32(len);
+-
+-	err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
+-	if (unlikely(err)) {
+-		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
+-		err = -EINVAL;
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-	bss_list->buflen = le32_to_cpu(bss_list->buflen);
+-	bss_list->version = le32_to_cpu(bss_list->version);
+-	bss_list->count = le32_to_cpu(bss_list->count);
+-
+-	err = wl_inform_bss(wl);
+-	if (err) {
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-
+-scan_done_out:
+-	if (wl->scan_request) {
+-		WL_SCAN("calling cfg80211_scan_done\n");
+-		cfg80211_scan_done(wl->scan_request, scan_abort);
+-		wl_set_mpc(ndev, 1);
+-		wl->scan_request = NULL;
+-	}
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static void wl_init_conf(struct wl_conf *conf)
+-{
+-	conf->mode = (u32)-1;
+-	conf->frag_threshold = (u32)-1;
+-	conf->rts_threshold = (u32)-1;
+-	conf->retry_short = (u32)-1;
+-	conf->retry_long = (u32)-1;
+-	conf->tx_power = -1;
+-}
+-
+-static void wl_init_prof(struct wl_profile *prof)
+-{
+-	memset(prof, 0, sizeof(*prof));
+-}
+-
+-static void wl_init_eloop_handler(struct wl_event_loop *el)
+-{
+-	memset(el, 0, sizeof(*el));
+-	el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
+-	el->handler[WLC_E_LINK] = wl_notify_connect_status;
+-	el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
+-	el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
+-	el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
+-}
+-
+-static s32 wl_init_priv_mem(struct wl_priv *wl)
+-{
+-	wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->scan_results)) {
+-		WL_ERR("Scan results alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+-	if (unlikely(!wl->conf)) {
+-		WL_ERR("wl_conf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
+-	if (unlikely(!wl->profile)) {
+-		WL_ERR("wl_profile alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->bss_info)) {
+-		WL_ERR("Bss information alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+-	if (unlikely(!wl->scan_req_int)) {
+-		WL_ERR("Scan req alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->ioctl_buf)) {
+-		WL_ERR("Ioctl buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->extra_buf)) {
+-		WL_ERR("Extra buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
+-	if (unlikely(!wl->iscan)) {
+-		WL_ERR("Iscan buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
+-	if (unlikely(!wl->fw)) {
+-		WL_ERR("fw object alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+-	if (unlikely(!wl->pmk_list)) {
+-		WL_ERR("pmk list alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-
+-	return 0;
+-
+-init_priv_mem_out:
+-	wl_deinit_priv_mem(wl);
+-
+-	return -ENOMEM;
+-}
+-
+-static void wl_deinit_priv_mem(struct wl_priv *wl)
+-{
+-	kfree(wl->scan_results);
+-	wl->scan_results = NULL;
+-	kfree(wl->bss_info);
+-	wl->bss_info = NULL;
+-	kfree(wl->conf);
+-	wl->conf = NULL;
+-	kfree(wl->profile);
+-	wl->profile = NULL;
+-	kfree(wl->scan_req_int);
+-	wl->scan_req_int = NULL;
+-	kfree(wl->ioctl_buf);
+-	wl->ioctl_buf = NULL;
+-	kfree(wl->extra_buf);
+-	wl->extra_buf = NULL;
+-	kfree(wl->iscan);
+-	wl->iscan = NULL;
+-	kfree(wl->fw);
+-	wl->fw = NULL;
+-	kfree(wl->pmk_list);
+-	wl->pmk_list = NULL;
+-}
+-
+-static s32 wl_create_event_handler(struct wl_priv *wl)
+-{
+-	sema_init(&wl->event_sync, 0);
+-	wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
+-	if (IS_ERR(wl->event_tsk)) {
+-		wl->event_tsk = NULL;
+-		WL_ERR("failed to create event thread\n");
+-		return -ENOMEM;
+-	}
+-	return 0;
+-}
+-
+-static void wl_destroy_event_handler(struct wl_priv *wl)
+-{
+-	if (wl->event_tsk) {
+-		send_sig(SIGTERM, wl->event_tsk, 1);
+-		kthread_stop(wl->event_tsk);
+-		wl->event_tsk = NULL;
+-	}
+-}
+-
+-static void wl_term_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-
+-	if (wl->iscan_on && iscan->tsk) {
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		send_sig(SIGTERM, iscan->tsk, 1);
+-		kthread_stop(iscan->tsk);
+-		iscan->tsk = NULL;
+-	}
+-}
+-
+-static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
+-{
+-	struct wl_priv *wl = iscan_to_wl(iscan);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scan complete while device not scanning\n");
+-		return;
+-	}
+-	if (likely(wl->scan_request)) {
+-		WL_SCAN("ISCAN Completed scan: %s\n",
+-				aborted ? "Aborted" : "Done");
+-		cfg80211_scan_done(wl->scan_request, aborted);
+-		wl_set_mpc(ndev, 1);
+-		wl->scan_request = NULL;
+-	}
+-	wl->iscan_kickstart = false;
+-}
+-
+-static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
+-{
+-	if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
+-		WL_SCAN("wake up iscan\n");
+-		up(&iscan->sync);
+-		return 0;
+-	}
+-
+-	return -EIO;
+-}
+-
+-static s32
+-wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+-		     struct wl_scan_results **bss_list)
+-{
+-	struct wl_iscan_results list;
+-	struct wl_scan_results *results;
+-	struct wl_iscan_results *list_buf;
+-	s32 err = 0;
+-
+-	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
+-	list_buf = (struct wl_iscan_results *)iscan->scan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
+-	err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
+-				WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
+-				WL_ISCAN_BUF_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	results->buflen = le32_to_cpu(results->buflen);
+-	results->version = le32_to_cpu(results->version);
+-	results->count = le32_to_cpu(results->count);
+-	WL_SCAN("results->count = %d\n", results->count);
+-	WL_SCAN("results->buflen = %d\n", results->buflen);
+-	*status = le32_to_cpu(list_buf->status);
+-	*bss_list = results;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_done(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	iscan->state = WL_ISCAN_STATE_IDLE;
+-	rtnl_lock();
+-	wl_inform_bss(wl);
+-	wl_notify_iscan_complete(iscan, false);
+-	rtnl_unlock();
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_pending(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	/* Reschedule the timer */
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_inprogress(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	rtnl_lock();
+-	wl_inform_bss(wl);
+-	wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+-	rtnl_unlock();
+-	/* Reschedule the timer */
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_aborted(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	iscan->state = WL_ISCAN_STATE_IDLE;
+-	rtnl_lock();
+-	wl_notify_iscan_complete(iscan, true);
+-	rtnl_unlock();
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_thread(void *data)
+-{
+-	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+-	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+-	struct wl_priv *wl = iscan_to_wl(iscan);
+-	struct wl_iscan_eloop *el = &iscan->el;
+-	u32 status;
+-	int err = 0;
+-
+-	sched_setscheduler(current, SCHED_FIFO, &param);
+-	allow_signal(SIGTERM);
+-	status = WL_SCAN_RESULTS_PARTIAL;
+-	while (likely(!down_interruptible(&iscan->sync))) {
+-		if (kthread_should_stop())
+-			break;
+-		if (iscan->timer_on) {
+-			del_timer_sync(&iscan->timer);
+-			iscan->timer_on = 0;
+-		}
+-		rtnl_lock();
+-		err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
+-		if (unlikely(err)) {
+-			status = WL_SCAN_RESULTS_ABORTED;
+-			WL_ERR("Abort iscan\n");
+-		}
+-		rtnl_unlock();
+-		el->handler[status] (wl);
+-	}
+-	if (iscan->timer_on) {
+-		del_timer_sync(&iscan->timer);
+-		iscan->timer_on = 0;
+-	}
+-	WL_SCAN("ISCAN thread terminated\n");
+-
+-	return 0;
+-}
+-
+-static void wl_iscan_timer(unsigned long data)
+-{
+-	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+-
+-	if (iscan) {
+-		iscan->timer_on = 0;
+-		WL_SCAN("timer expired\n");
+-		wl_wakeup_iscan(iscan);
+-	}
+-}
+-
+-static s32 wl_invoke_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	int err = 0;
+-
+-	if (wl->iscan_on && !iscan->tsk) {
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		sema_init(&iscan->sync, 0);
+-		iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+-		if (IS_ERR(iscan->tsk)) {
+-			WL_ERR("Could not create iscan thread\n");
+-			iscan->tsk = NULL;
+-			return -ENOMEM;
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
+-{
+-	memset(el, 0, sizeof(*el));
+-	el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
+-	el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
+-	el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
+-	el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
+-	el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
+-}
+-
+-static s32 wl_init_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	int err = 0;
+-
+-	if (wl->iscan_on) {
+-		iscan->dev = wl_to_ndev(wl);
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		wl_init_iscan_eloop(&iscan->el);
+-		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
+-		init_timer(&iscan->timer);
+-		iscan->timer.data = (unsigned long) iscan;
+-		iscan->timer.function = wl_iscan_timer;
+-		sema_init(&iscan->sync, 0);
+-		iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+-		if (IS_ERR(iscan->tsk)) {
+-			WL_ERR("Could not create iscan thread\n");
+-			iscan->tsk = NULL;
+-			return -ENOMEM;
+-		}
+-		iscan->data = wl;
+-	}
+-
+-	return err;
+-}
+-
+-static void wl_init_fw(struct wl_fw_ctrl *fw)
+-{
+-	fw->status = 0;		/* init fw loading status.
+-				 0 means nothing was loaded yet */
+-}
+-
+-static s32 wl_init_priv(struct wl_priv *wl)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	s32 err = 0;
+-
+-	wl->scan_request = NULL;
+-	wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
+-	wl->iscan_on = true;	/* iscan on & off switch.
+-				 we enable iscan per default */
+-	wl->roam_on = false;	/* roam on & off switch.
+-				 we enable roam per default */
+-
+-	wl->iscan_kickstart = false;
+-	wl->active_scan = true;	/* we do active scan for
+-				 specific scan per default */
+-	wl->dongle_up = false;	/* dongle is not up yet */
+-	wl_init_eq(wl);
+-	err = wl_init_priv_mem(wl);
+-	if (unlikely(err))
+-		return err;
+-	if (unlikely(wl_create_event_handler(wl)))
+-		return -ENOMEM;
+-	wl_init_eloop_handler(&wl->el);
+-	mutex_init(&wl->usr_sync);
+-	err = wl_init_iscan(wl);
+-	if (unlikely(err))
+-		return err;
+-	wl_init_fw(wl->fw);
+-	wl_init_conf(wl->conf);
+-	wl_init_prof(wl->profile);
+-	wl_link_down(wl);
+-
+-	return err;
+-}
+-
+-static void wl_deinit_priv(struct wl_priv *wl)
+-{
+-	wl_destroy_event_handler(wl);
+-	wl->dongle_up = false;	/* dongle down */
+-	wl_flush_eq(wl);
+-	wl_link_down(wl);
+-	wl_term_iscan(wl);
+-	wl_deinit_priv_mem(wl);
+-}
+-
+-s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
+-{
+-	struct wireless_dev *wdev;
+-	struct wl_priv *wl;
+-	struct wl_iface *ci;
+-	s32 err = 0;
+-
+-	if (unlikely(!ndev)) {
+-		WL_ERR("ndev is invalid\n");
+-		return -ENODEV;
+-	}
+-	wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
+-	if (unlikely(!wl_cfg80211_dev)) {
+-		WL_ERR("wl_cfg80211_dev is invalid\n");
+-		return -ENOMEM;
+-	}
+-	WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
+-	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
+-	if (IS_ERR(wdev))
+-		return -ENOMEM;
+-
+-	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+-	wl = wdev_to_wl(wdev);
+-	wl->wdev = wdev;
+-	wl->pub = data;
+-	ci = (struct wl_iface *)wl_to_ci(wl);
+-	ci->wl = wl;
+-	ndev->ieee80211_ptr = wdev;
+-	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+-	wdev->netdev = ndev;
+-	err = wl_init_priv(wl);
+-	if (unlikely(err)) {
+-		WL_ERR("Failed to init iwm_priv (%d)\n", err);
+-		goto cfg80211_attach_out;
+-	}
+-	wl_set_drvdata(wl_cfg80211_dev, ci);
+-
+-	return err;
+-
+-cfg80211_attach_out:
+-	wl_free_wdev(wl);
+-	return err;
+-}
+-
+-void wl_cfg80211_detach(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-
+-	wl_deinit_priv(wl);
+-	wl_free_wdev(wl);
+-	wl_set_drvdata(wl_cfg80211_dev, NULL);
+-	kfree(wl_cfg80211_dev);
+-	wl_cfg80211_dev = NULL;
+-	wl_clear_sdio_func();
+-}
+-
+-static void wl_wakeup_event(struct wl_priv *wl)
+-{
+-	up(&wl->event_sync);
+-}
+-
+-static s32 wl_event_handler(void *data)
+-{
+-	struct wl_priv *wl = (struct wl_priv *)data;
+-	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+-	struct wl_event_q *e;
+-
+-	sched_setscheduler(current, SCHED_FIFO, &param);
+-	allow_signal(SIGTERM);
+-	while (likely(!down_interruptible(&wl->event_sync))) {
+-		if (kthread_should_stop())
+-			break;
+-		e = wl_deq_event(wl);
+-		if (unlikely(!e)) {
+-			WL_ERR("event queue empty...\n");
+-			BUG();
+-		}
+-		WL_INFO("event type (%d)\n", e->etype);
+-		if (wl->el.handler[e->etype]) {
+-			wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
+-						  e->edata);
+-		} else {
+-			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
+-		}
+-		wl_put_event(e);
+-	}
+-	WL_INFO("was terminated\n");
+-	return 0;
+-}
+-
+-void
+-wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
+-{
+-	u32 event_type = be32_to_cpu(e->event_type);
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-
+-	if (likely(!wl_enq_event(wl, event_type, e, data)))
+-		wl_wakeup_event(wl);
+-}
+-
+-static void wl_init_eq(struct wl_priv *wl)
+-{
+-	wl_init_eq_lock(wl);
+-	INIT_LIST_HEAD(&wl->eq_list);
+-}
+-
+-static void wl_flush_eq(struct wl_priv *wl)
+-{
+-	struct wl_event_q *e;
+-
+-	wl_lock_eq(wl);
+-	while (!list_empty(&wl->eq_list)) {
+-		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+-		list_del(&e->eq_list);
+-		kfree(e);
+-	}
+-	wl_unlock_eq(wl);
+-}
+-
+-/*
+-* retrieve first queued event from head
+-*/
+-
+-static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
+-{
+-	struct wl_event_q *e = NULL;
+-
+-	wl_lock_eq(wl);
+-	if (likely(!list_empty(&wl->eq_list))) {
+-		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+-		list_del(&e->eq_list);
+-	}
+-	wl_unlock_eq(wl);
+-
+-	return e;
+-}
+-
+-/*
+-** push event to tail of the queue
+-*/
+-
+-static s32
+-wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
+-	     void *data)
+-{
+-	struct wl_event_q *e;
+-	s32 err = 0;
+-
+-	e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
+-	if (unlikely(!e)) {
+-		WL_ERR("event alloc failed\n");
+-		return -ENOMEM;
+-	}
+-
+-	e->etype = event;
+-	memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
+-	if (data) {
+-	}
+-	wl_lock_eq(wl);
+-	list_add_tail(&e->eq_list, &wl->eq_list);
+-	wl_unlock_eq(wl);
+-
+-	return err;
+-}
+-
+-static void wl_put_event(struct wl_event_q *e)
+-{
+-	kfree(e);
+-}
+-
+-void wl_cfg80211_sdio_func(void *func)
+-{
+-	cfg80211_sdio_func = (struct sdio_func *)func;
+-}
+-
+-static void wl_clear_sdio_func(void)
+-{
+-	cfg80211_sdio_func = NULL;
+-}
+-
+-struct sdio_func *wl_cfg80211_get_sdio_func(void)
+-{
+-	return cfg80211_sdio_func;
+-}
+-
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
+-{
+-	s32 infra = 0;
+-	s32 err = 0;
+-
+-	switch (iftype) {
+-	case NL80211_IFTYPE_MONITOR:
+-	case NL80211_IFTYPE_WDS:
+-		WL_ERR("type (%d) : currently we do not support this mode\n",
+-		       iftype);
+-		err = -EINVAL;
+-		return err;
+-	case NL80211_IFTYPE_ADHOC:
+-		infra = 0;
+-		break;
+-	case NL80211_IFTYPE_STATION:
+-		infra = 1;
+-		break;
+-	default:
+-		err = -EINVAL;
+-		WL_ERR("invalid type (%d)\n", iftype);
+-		return err;
+-	}
+-	infra = cpu_to_le32(infra);
+-	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
+-		return err;
+-	}
+-
+-	return 0;
+-}
+-
+-#ifndef EMBEDDED_PLATFORM
+-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
+-{
+-
+-	s32 err = 0;
+-
+-	return err;
+-}
+-
+-static s32 wl_dongle_up(struct net_device *ndev, u32 up)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_UP error (%d)\n", err);
+-	}
+-	return err;
+-}
+-
+-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_PM error (%d)\n", err);
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-	s32 err = 0;
+-
+-	/* Match Host and Dongle rx alignment */
+-	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("txglomalign error (%d)\n", err);
+-		goto dongle_glom_out;
+-	}
+-	/* disable glom option per default */
+-	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("txglom error (%d)\n", err);
+-		goto dongle_glom_out;
+-	}
+-dongle_glom_out:
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-							 '\0' + bitvec  */
+-	s32 err = 0;
+-
+-	/* Set ARP offload */
+-	bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("arpoe is not supported\n");
+-		else
+-			WL_ERR("arpoe error (%d)\n", err);
+-
+-		goto dongle_offload_out;
+-	}
+-	bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("arp_ol is not supported\n");
+-		else
+-			WL_ERR("arp_ol error (%d)\n", err);
+-
+-		goto dongle_offload_out;
+-	}
+-
+-dongle_offload_out:
+-	return err;
+-}
+-
+-static s32 wl_pattern_atoh(s8 *src, s8 *dst)
+-{
+-	int i;
+-	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
+-		WL_ERR("Mask invalid format. Needs to start with 0x\n");
+-		return -1;
+-	}
+-	src = src + 2;		/* Skip past 0x */
+-	if (strlen(src) % 2 != 0) {
+-		WL_ERR("Mask invalid format. Needs to be of even length\n");
+-		return -1;
+-	}
+-	for (i = 0; *src != '\0'; i++) {
+-		char num[3];
+-		strncpy(num, src, 2);
+-		num[2] = '\0';
+-		dst[i] = (u8) simple_strtoul(num, NULL, 16);
+-		src += 2;
+-	}
+-	return i;
+-}
+-
+-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-							 '\0' + bitvec  */
+-	const s8 *str;
+-	struct wl_pkt_filter pkt_filter;
+-	struct wl_pkt_filter *pkt_filterp;
+-	s32 buf_len;
+-	s32 str_len;
+-	u32 mask_size;
+-	u32 pattern_size;
+-	s8 buf[256];
+-	s32 err = 0;
+-
+-/* add a default packet filter pattern */
+-	str = "pkt_filter_add";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	pkt_filter.id = cpu_to_le32(100);
+-
+-	/* Parse filter polarity. */
+-	pkt_filter.negate_match = cpu_to_le32(0);
+-
+-	/* Parse filter type. */
+-	pkt_filter.type = cpu_to_le32(0);
+-
+-	/* Parse pattern filter offset. */
+-	pkt_filter.u.pattern.offset = cpu_to_le32(0);
+-
+-	/* Parse pattern filter mask. */
+-	mask_size = cpu_to_le32(wl_pattern_atoh("0xff",
+-						(char *)pkt_filterp->u.pattern.
+-						mask_and_pattern));
+-
+-	/* Parse pattern filter pattern. */
+-	pattern_size = cpu_to_le32(wl_pattern_atoh("0x00",
+-						   (char *)&pkt_filterp->u.
+-						   pattern.
+-						   mask_and_pattern
+-						   [mask_size]));
+-
+-	if (mask_size != pattern_size) {
+-		WL_ERR("Mask and pattern not the same size\n");
+-		err = -EINVAL;
+-		goto dongle_filter_out;
+-	}
+-
+-	pkt_filter.u.pattern.size_bytes = mask_size;
+-	buf_len += WL_PKT_FILTER_FIXED_LEN;
+-	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+-
+-	/* Keep-alive attributes are set in local
+-	 * variable (keep_alive_pkt), and
+-	 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
+-	 * guarantee that the buffer is properly aligned.
+-	 */
+-	memcpy((char *)pkt_filterp, &pkt_filter,
+-	       WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
+-	if (err) {
+-		if (err == -EOPNOTSUPP) {
+-			WL_INFO("filter not supported\n");
+-		} else {
+-			WL_ERR("filter (%d)\n", err);
+-		}
+-		goto dongle_filter_out;
+-	}
+-
+-	/* set mode to allow pattern */
+-	bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP) {
+-			WL_INFO("filter_mode not supported\n");
+-		} else {
+-			WL_ERR("filter_mode (%d)\n", err);
+-		}
+-		goto dongle_filter_out;
+-	}
+-
+-dongle_filter_out:
+-	return err;
+-}
+-#endif				/* !EMBEDDED_PLATFORM */
+-
+-static s32 wl_dongle_eventmsg(struct net_device *ndev)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-	s8 eventmask[WL_EVENTING_MASK_LEN];
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	/* Setup event_msgs */
+-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("Get event_msgs error (%d)\n", err);
+-		goto dongle_eventmsg_out;
+-	}
+-	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-
+-	setbit(eventmask, WLC_E_SET_SSID);
+-	setbit(eventmask, WLC_E_ROAM);
+-	setbit(eventmask, WLC_E_PRUNE);
+-	setbit(eventmask, WLC_E_AUTH);
+-	setbit(eventmask, WLC_E_REASSOC);
+-	setbit(eventmask, WLC_E_REASSOC_IND);
+-	setbit(eventmask, WLC_E_DEAUTH_IND);
+-	setbit(eventmask, WLC_E_DISASSOC_IND);
+-	setbit(eventmask, WLC_E_DISASSOC);
+-	setbit(eventmask, WLC_E_JOIN);
+-	setbit(eventmask, WLC_E_ASSOC_IND);
+-	setbit(eventmask, WLC_E_PSK_SUP);
+-	setbit(eventmask, WLC_E_LINK);
+-	setbit(eventmask, WLC_E_NDIS_LINK);
+-	setbit(eventmask, WLC_E_MIC_ERROR);
+-	setbit(eventmask, WLC_E_PMKID_CACHE);
+-	setbit(eventmask, WLC_E_TXFAIL);
+-	setbit(eventmask, WLC_E_JOIN_START);
+-	setbit(eventmask, WLC_E_SCAN_COMPLETE);
+-
+-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("Set event_msgs error (%d)\n", err);
+-		goto dongle_eventmsg_out;
+-	}
+-
+-dongle_eventmsg_out:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
+-{
+-	s8 iovbuf[32];
+-	s32 roamtrigger[2];
+-	s32 roam_delta[2];
+-	s32 err = 0;
+-
+-	/*
+-	 * Setup timeout if Beacons are lost and roam is
+-	 * off to report link down
+-	 */
+-	if (roamvar) {
+-		bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout,
+-			sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
+-		err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-		if (unlikely(err)) {
+-			WL_ERR("bcn_timeout error (%d)\n", err);
+-			goto dongle_rom_out;
+-		}
+-	}
+-
+-	/*
+-	 * Enable/Disable built-in roaming to allow supplicant
+-	 * to take care of roaming
+-	 */
+-	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
+-	bcm_mkiovar("roam_off", (char *)&roamvar,
+-				sizeof(roamvar), iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("roam_off error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-	roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
+-	roamtrigger[1] = WLC_BAND_ALL;
+-	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_TRIGGER,
+-			(void *)roamtrigger, sizeof(roamtrigger));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-	roam_delta[0] = WL_ROAM_DELTA;
+-	roam_delta[1] = WLC_BAND_ALL;
+-	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_DELTA,
+-				(void *)roam_delta, sizeof(roam_delta));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-dongle_rom_out:
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+-		s32 scan_unassoc_time, s32 scan_passive_time)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
+-			sizeof(scan_assoc_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan assoc time is not supported\n");
+-		else
+-			WL_ERR("Scan assoc time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
+-			sizeof(scan_unassoc_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan unassoc time is not supported\n");
+-		else
+-			WL_ERR("Scan unassoc time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME, &scan_passive_time,
+-			sizeof(scan_passive_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan passive time is not supported\n");
+-		else
+-			WL_ERR("Scan passive time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-
+-dongle_scantime_out:
+-	return err;
+-}
+-
+-s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
+-{
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-	struct net_device *ndev;
+-	struct wireless_dev *wdev;
+-	s32 err = 0;
+-
+-	if (wl->dongle_up)
+-		return err;
+-
+-	ndev = wl_to_ndev(wl);
+-	wdev = ndev->ieee80211_ptr;
+-	if (need_lock)
+-		rtnl_lock();
+-
+-#ifndef EMBEDDED_PLATFORM
+-	err = wl_dongle_up(ndev, 0);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_country(ndev, 0);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_power(ndev, PM_FAST);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-
+-	wl_dongle_offload(ndev, 1, 0xf);
+-	wl_dongle_filter(ndev, 1);
+-#endif /* !EMBEDDED_PLATFORM */
+-
+-	wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
+-			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
+-
+-	err = wl_dongle_eventmsg(ndev);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_mode(ndev, wdev->iftype);
+-	if (unlikely(err && err != -EINPROGRESS))
+-		goto default_conf_out;
+-	err = wl_dongle_probecap(wl);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-
+-	/* -EINPROGRESS: Call commit handler */
+-
+-default_conf_out:
+-	if (need_lock)
+-		rtnl_unlock();
+-
+-	wl->dongle_up = true;
+-
+-	return err;
+-
+-}
+-
+-static s32 wl_update_wiphybands(struct wl_priv *wl)
+-{
+-	struct wiphy *wiphy;
+-	s32 phy_list;
+-	s8 phy;
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
+-			sizeof(phy_list));
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-
+-	phy = ((char *)&phy_list)[1];
+-	WL_INFO("%c phy\n", phy);
+-	if (phy == 'n' || phy == 'a') {
+-		wiphy = wl_to_wiphy(wl);
+-		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
+-	}
+-
+-	return err;
+-}
+-
+-static s32 __wl_cfg80211_up(struct wl_priv *wl)
+-{
+-	s32 err = 0;
+-
+-	set_bit(WL_STATUS_READY, &wl->status);
+-
+-	wl_debugfs_add_netdev_params(wl);
+-
+-	err = wl_config_dongle(wl, false);
+-	if (unlikely(err))
+-		return err;
+-
+-	wl_invoke_iscan(wl);
+-
+-	return err;
+-}
+-
+-static s32 __wl_cfg80211_down(struct wl_priv *wl)
+-{
+-	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	wl_term_iscan(wl);
+-	if (wl->scan_request) {
+-		cfg80211_scan_done(wl->scan_request, true);
+-		/* May need to perform this to cover rmmod */
+-		/* wl_set_mpc(wl_to_ndev(wl), 1); */
+-		wl->scan_request = NULL;
+-	}
+-	clear_bit(WL_STATUS_READY, &wl->status);
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	wl_debugfs_remove_netdev(wl);
+-
+-	return 0;
+-}
+-
+-s32 wl_cfg80211_up(void)
+-{
+-	struct wl_priv *wl;
+-	s32 err = 0;
+-
+-	wl = WL_PRIV_GET();
+-	mutex_lock(&wl->usr_sync);
+-	err = __wl_cfg80211_up(wl);
+-	mutex_unlock(&wl->usr_sync);
+-
+-	return err;
+-}
+-
+-s32 wl_cfg80211_down(void)
+-{
+-	struct wl_priv *wl;
+-	s32 err = 0;
+-
+-	wl = WL_PRIV_GET();
+-	mutex_lock(&wl->usr_sync);
+-	err = __wl_cfg80211_down(wl);
+-	mutex_unlock(&wl->usr_sync);
+-
+-	return err;
+-}
+-
+-static s32 wl_dongle_probecap(struct wl_priv *wl)
+-{
+-	s32 err = 0;
+-
+-	err = wl_update_wiphybands(wl);
+-	if (unlikely(err))
+-		return err;
+-
+-	return err;
+-}
+-
+-static void *wl_read_prof(struct wl_priv *wl, s32 item)
+-{
+-	switch (item) {
+-	case WL_PROF_SEC:
+-		return &wl->profile->sec;
+-	case WL_PROF_BSSID:
+-		return &wl->profile->bssid;
+-	case WL_PROF_SSID:
+-		return &wl->profile->ssid;
+-	}
+-	WL_ERR("invalid item (%d)\n", item);
+-	return NULL;
+-}
+-
+-static s32
+-wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
+-	       s32 item)
+-{
+-	s32 err = 0;
+-	struct wlc_ssid *ssid;
+-
+-	switch (item) {
+-	case WL_PROF_SSID:
+-		ssid = (wlc_ssid_t *) data;
+-		memset(wl->profile->ssid.SSID, 0,
+-		       sizeof(wl->profile->ssid.SSID));
+-		memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
+-		wl->profile->ssid.SSID_len = ssid->SSID_len;
+-		break;
+-	case WL_PROF_BSSID:
+-		if (data)
+-			memcpy(wl->profile->bssid, data, ETH_ALEN);
+-		else
+-			memset(wl->profile->bssid, 0, ETH_ALEN);
+-		break;
+-	case WL_PROF_SEC:
+-		memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
+-		break;
+-	case WL_PROF_BEACONINT:
+-		wl->profile->beacon_interval = *(u16 *)data;
+-		break;
+-	case WL_PROF_DTIMPERIOD:
+-		wl->profile->dtim_period = *(u8 *)data;
+-		break;
+-	default:
+-		WL_ERR("unsupported item (%d)\n", item);
+-		err = -EOPNOTSUPP;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-static bool wl_is_ibssmode(struct wl_priv *wl)
+-{
+-	return wl->conf->mode == WL_MODE_IBSS;
+-}
+-
+-static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
+-{
+-	struct wl_ie *ie = wl_to_ie(wl);
+-	s32 err = 0;
+-
+-	if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
+-		WL_ERR("ei crosses buffer boundary\n");
+-		return -ENOSPC;
+-	}
+-	ie->buf[ie->offset] = t;
+-	ie->buf[ie->offset + 1] = l;
+-	memcpy(&ie->buf[ie->offset + 2], v, l);
+-	ie->offset += l + 2;
+-
+-	return err;
+-}
+-
+-
+-static void wl_link_down(struct wl_priv *wl)
+-{
+-	struct net_device *dev = NULL;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	if (wl->link_up) {
+-		dev = wl_to_ndev(wl);
+-		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
+-		err = wl_dev_ioctl(dev, WLC_DISASSOC, NULL, 0);
+-		if (unlikely(err))
+-			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
+-		wl->link_up = false;
+-	}
+-	WL_TRACE("Exit\n");
+-}
+-
+-static void wl_lock_eq(struct wl_priv *wl)
+-{
+-	spin_lock_irq(&wl->eq_lock);
+-}
+-
+-static void wl_unlock_eq(struct wl_priv *wl)
+-{
+-	spin_unlock_irq(&wl->eq_lock);
+-}
+-
+-static void wl_init_eq_lock(struct wl_priv *wl)
+-{
+-	spin_lock_init(&wl->eq_lock);
+-}
+-
+-static void wl_delay(u32 ms)
+-{
+-	if (ms < 1000 / HZ) {
+-		cond_resched();
+-		mdelay(ms);
+-	} else {
+-		msleep(ms);
+-	}
+-}
+-
+-static void wl_set_drvdata(struct wl_dev *dev, void *data)
+-{
+-	dev->driver_data = data;
+-}
+-
+-static void *wl_get_drvdata(struct wl_dev *dev)
+-{
+-	return dev->driver_data;
+-}
+-
+-s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
+-{
+-	const struct firmware *fw_entry;
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-
+-	fw_entry = wl->fw->fw_entry;
+-
+-	if (fw_entry->size < wl->fw->ptr + size)
+-		size = fw_entry->size - wl->fw->ptr;
+-
+-	memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
+-	wl->fw->ptr += size;
+-	return size;
+-}
+-
+-void wl_cfg80211_release_fw(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	release_firmware(wl->fw->fw_entry);
+-	wl->fw->ptr = 0;
+-}
+-
+-void *wl_cfg80211_request_fw(s8 *file_name)
+-{
+-	struct wl_priv *wl;
+-	const struct firmware *fw_entry = NULL;
+-	s32 err = 0;
+-
+-	WL_INFO("file name : \"%s\"\n", file_name);
+-	wl = WL_PRIV_GET();
+-
+-	if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
+-		err = request_firmware(&wl->fw->fw_entry, file_name,
+-				&wl_cfg80211_get_sdio_func()->dev);
+-		if (unlikely(err)) {
+-			WL_ERR("Could not download fw (%d)\n", err);
+-			goto req_fw_out;
+-		}
+-		set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
+-		fw_entry = wl->fw->fw_entry;
+-		if (fw_entry) {
+-			WL_INFO("fw size (%zd), data (%p)\n",
+-			       fw_entry->size, fw_entry->data);
+-		}
+-	} else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
+-		err = request_firmware(&wl->fw->fw_entry, file_name,
+-				&wl_cfg80211_get_sdio_func()->dev);
+-		if (unlikely(err)) {
+-			WL_ERR("Could not download nvram (%d)\n", err);
+-			goto req_fw_out;
+-		}
+-		set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
+-		fw_entry = wl->fw->fw_entry;
+-		if (fw_entry) {
+-			WL_INFO("nvram size (%zd), data (%p)\n",
+-			       fw_entry->size, fw_entry->data);
+-		}
+-	} else {
+-		WL_INFO("Downloading already done. Nothing to do more\n");
+-		err = -EPERM;
+-	}
+-
+-req_fw_out:
+-	if (unlikely(err)) {
+-		return NULL;
+-	}
+-	wl->fw->ptr = 0;
+-	return (void *)fw_entry->data;
+-}
+-
+-s8 *wl_cfg80211_get_fwname(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
+-	return wl->fw->fw_name;
+-}
+-
+-s8 *wl_cfg80211_get_nvramname(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
+-	return wl->fw->nvram_name;
+-}
+-
+-static void wl_set_mpc(struct net_device *ndev, int mpc)
+-{
+-	s32 err = 0;
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		err = wl_dev_intvar_set(ndev, "mpc", mpc);
+-		if (unlikely(err)) {
+-			WL_ERR("fail to set mpc\n");
+-			return;
+-		}
+-		WL_INFO("MPC : %d\n", mpc);
+-	}
+-}
+-
+-static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
+-{
+-	char buf[10+IFNAMSIZ];
+-	struct dentry *fd;
+-	s32 err = 0;
+-
+-	sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
+-	wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
+-
+-	fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
+-		(u16 *)&wl->profile->beacon_interval);
+-	if (!fd) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-
+-	fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
+-		(u8 *)&wl->profile->dtim_period);
+-	if (!fd) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-
+-err_out:
+-	return err;
+-}
+-
+-static void wl_debugfs_remove_netdev(struct wl_priv *wl)
+-{
+-	debugfs_remove_recursive(wl->debugfsdir);
+-	wl->debugfsdir = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+deleted file mode 100644
+index 996033c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
++++ /dev/null
+@@ -1,414 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_cfg80211_h_
+-#define _wl_cfg80211_h_
+-
+-#include <linux/wireless.h>
+-#include <linux/wireless.h>
+-#include <net/cfg80211.h>
+-#include <wlioctl.h>
+-
+-struct wl_conf;
+-struct wl_iface;
+-struct wl_priv;
+-struct wl_security;
+-struct wl_ibss;
+-
+-#define WL_DBG_NONE		0
+-#define WL_DBG_CONN		(1 << 5)
+-#define WL_DBG_SCAN		(1 << 4)
+-#define WL_DBG_TRACE		(1 << 3)
+-#define WL_DBG_INFO		(1 << 1)
+-#define WL_DBG_ERR		(1 << 0)
+-#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
+-				(WL_DBG_SCAN) | (WL_DBG_CONN))
+-
+-#define	WL_ERR(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_ERR) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "ERROR @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#if (defined BCMDBG)
+-#define	WL_INFO(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_INFO) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "INFO @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_TRACE(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_TRACE) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "TRACE @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_SCAN(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_SCAN) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "SCAN @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_CONN(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_CONN) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "CONN @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#else /* (defined BCMDBG) */
+-#define	WL_INFO(fmt, args...)
+-#define	WL_TRACE(fmt, args...)
+-#define	WL_SCAN(fmt, args...)
+-#define	WL_CONN(fmt, args...)
+-#endif /* (defined BCMDBG) */
+-
+-
+-#define WL_SCAN_RETRY_MAX	3	/* used for ibss scan */
+-#define WL_NUM_SCAN_MAX		1
+-#define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
+-						 * for 2.6.33 kernel
+-						 * or later
+-						 */
+-#define WL_SCAN_BUF_MAX 		(1024 * 8)
+-#define WL_TLV_INFO_MAX 		1024
+-#define WL_BSS_INFO_MAX			2048
+-#define WL_ASSOC_INFO_MAX	512	/*
+-				 * needs to grab assoc info from dongle to
+-				 * report it to cfg80211 through "connect"
+-				 * event
+-				 */
+-#define WL_IOCTL_LEN_MAX	1024
+-#define WL_EXTRA_BUF_MAX	2048
+-#define WL_ISCAN_BUF_MAX	2048	/*
+-				 * the buf lengh can be WLC_IOCTL_MAXLEN (8K)
+-				 * to reduce iteration
+-				 */
+-#define WL_ISCAN_TIMER_INTERVAL_MS	3000
+-#define WL_SCAN_ERSULTS_LAST 	(WL_SCAN_RESULTS_NO_MEM+1)
+-#define WL_AP_MAX	256	/* virtually unlimitted as long
+-				 * as kernel memory allows
+-				 */
+-#define WL_FILE_NAME_MAX		256
+-
+-#define WL_ROAM_TRIGGER_LEVEL		-75
+-#define WL_ROAM_DELTA			20
+-#define WL_BEACON_TIMEOUT		3
+-
+-#define WL_SCAN_CHANNEL_TIME		40
+-#define WL_SCAN_UNASSOC_TIME		40
+-#define WL_SCAN_PASSIVE_TIME		120
+-
+-/* dongle status */
+-enum wl_status {
+-	WL_STATUS_READY,
+-	WL_STATUS_SCANNING,
+-	WL_STATUS_SCAN_ABORTING,
+-	WL_STATUS_CONNECTING,
+-	WL_STATUS_CONNECTED
+-};
+-
+-/* wi-fi mode */
+-enum wl_mode {
+-	WL_MODE_BSS,
+-	WL_MODE_IBSS,
+-	WL_MODE_AP
+-};
+-
+-/* dongle profile list */
+-enum wl_prof_list {
+-	WL_PROF_MODE,
+-	WL_PROF_SSID,
+-	WL_PROF_SEC,
+-	WL_PROF_IBSS,
+-	WL_PROF_BAND,
+-	WL_PROF_BSSID,
+-	WL_PROF_ACT,
+-	WL_PROF_BEACONINT,
+-	WL_PROF_DTIMPERIOD
+-};
+-
+-/* dongle iscan state */
+-enum wl_iscan_state {
+-	WL_ISCAN_STATE_IDLE,
+-	WL_ISCAN_STATE_SCANING
+-};
+-
+-/* fw downloading status */
+-enum wl_fw_status {
+-	WL_FW_LOADING_DONE,
+-	WL_NVRAM_LOADING_DONE
+-};
+-
+-/* beacon / probe_response */
+-struct beacon_proberesp {
+-	__le64 timestamp;
+-	__le16 beacon_int;
+-	__le16 capab_info;
+-	u8 variable[0];
+-} __attribute__ ((packed));
+-
+-/* dongle configuration */
+-struct wl_conf {
+-	u32 mode;		/* adhoc , infrastructure or ap */
+-	u32 frag_threshold;
+-	u32 rts_threshold;
+-	u32 retry_short;
+-	u32 retry_long;
+-	s32 tx_power;
+-	struct ieee80211_channel channel;
+-};
+-
+-/* cfg80211 main event loop */
+-struct wl_event_loop {
+-	s32(*handler[WLC_E_LAST]) (struct wl_priv *wl,
+-				     struct net_device *ndev,
+-				     const wl_event_msg_t *e, void *data);
+-};
+-
+-/* representing interface of cfg80211 plane */
+-struct wl_iface {
+-	struct wl_priv *wl;
+-};
+-
+-struct wl_dev {
+-	void *driver_data;	/* to store cfg80211 object information */
+-};
+-
+-/* bss inform structure for cfg80211 interface */
+-struct wl_cfg80211_bss_info {
+-	u16 band;
+-	u16 channel;
+-	s16 rssi;
+-	u16 frame_len;
+-	u8 frame_buf[1];
+-};
+-
+-/* basic structure of scan request */
+-struct wl_scan_req {
+-	struct wlc_ssid ssid;
+-};
+-
+-/* basic structure of information element */
+-struct wl_ie {
+-	u16 offset;
+-	u8 buf[WL_TLV_INFO_MAX];
+-};
+-
+-/* event queue for cfg80211 main event */
+-struct wl_event_q {
+-	struct list_head eq_list;
+-	u32 etype;
+-	wl_event_msg_t emsg;
+-	s8 edata[1];
+-};
+-
+-/* security information with currently associated ap */
+-struct wl_security {
+-	u32 wpa_versions;
+-	u32 auth_type;
+-	u32 cipher_pairwise;
+-	u32 cipher_group;
+-	u32 wpa_auth;
+-};
+-
+-/* ibss information for currently joined ibss network */
+-struct wl_ibss {
+-	u8 beacon_interval;	/* in millisecond */
+-	u8 atim;		/* in millisecond */
+-	s8 join_only;
+-	u8 band;
+-	u8 channel;
+-};
+-
+-/* dongle profile */
+-struct wl_profile {
+-	u32 mode;
+-	struct wlc_ssid ssid;
+-	u8 bssid[ETH_ALEN];
+-	u16 beacon_interval;
+-	u8 dtim_period;
+-	struct wl_security sec;
+-	struct wl_ibss ibss;
+-	s32 band;
+-};
+-
+-/* dongle iscan event loop */
+-struct wl_iscan_eloop {
+-	s32(*handler[WL_SCAN_ERSULTS_LAST]) (struct wl_priv *wl);
+-};
+-
+-/* dongle iscan controller */
+-struct wl_iscan_ctrl {
+-	struct net_device *dev;
+-	struct timer_list timer;
+-	u32 timer_ms;
+-	u32 timer_on;
+-	s32 state;
+-	struct task_struct *tsk;
+-	struct semaphore sync;
+-	struct wl_iscan_eloop el;
+-	void *data;
+-	s8 ioctl_buf[WLC_IOCTL_SMLEN];
+-	s8 scan_buf[WL_ISCAN_BUF_MAX];
+-};
+-
+-/* association inform */
+-struct wl_connect_info {
+-	u8 *req_ie;
+-	s32 req_ie_len;
+-	u8 *resp_ie;
+-	s32 resp_ie_len;
+-};
+-
+-/* firmware /nvram downloading controller */
+-struct wl_fw_ctrl {
+-	const struct firmware *fw_entry;
+-	unsigned long status;
+-	u32 ptr;
+-	s8 fw_name[WL_FILE_NAME_MAX];
+-	s8 nvram_name[WL_FILE_NAME_MAX];
+-};
+-
+-/* assoc ie length */
+-struct wl_assoc_ielen {
+-	u32 req_len;
+-	u32 resp_len;
+-};
+-
+-/* wpa2 pmk list */
+-struct wl_pmk_list {
+-	pmkid_list_t pmkids;
+-	pmkid_t foo[MAXPMKID - 1];
+-};
+-
+-/* dongle private data of cfg80211 interface */
+-struct wl_priv {
+-	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
+-	struct wl_conf *conf;	/* dongle configuration */
+-	struct cfg80211_scan_request *scan_request;	/* scan request
+-							 object */
+-	struct wl_event_loop el;	/* main event loop */
+-	struct list_head eq_list;	/* used for event queue */
+-	spinlock_t eq_lock;	/* for event queue synchronization */
+-	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
+-	struct wl_scan_results *bss_list;	/* bss_list holding scanned
+-						 ap information */
+-	struct wl_scan_results *scan_results;
+-	struct wl_scan_req *scan_req_int;	/* scan request object for
+-						 internal purpose */
+-	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
+-						 cfg80211 layer */
+-	struct wl_ie ie;	/* information element object for
+-					 internal purpose */
+-	struct semaphore event_sync;	/* for synchronization of main event
+-					 thread */
+-	struct wl_profile *profile;	/* holding dongle profile */
+-	struct wl_iscan_ctrl *iscan;	/* iscan controller */
+-	struct wl_connect_info conn_info;	/* association information
+-						 container */
+-	struct wl_fw_ctrl *fw;	/* control firwmare / nvram paramter
+-				 downloading */
+-	struct wl_pmk_list *pmk_list;	/* wpa2 pmk list */
+-	struct task_struct *event_tsk;	/* task of main event handler thread */
+-	unsigned long status;		/* current dongle status */
+-	void *pub;
+-	u32 channel;		/* current channel */
+-	bool iscan_on;		/* iscan on/off switch */
+-	bool iscan_kickstart;	/* indicate iscan already started */
+-	bool active_scan;	/* current scan mode */
+-	bool ibss_starter;	/* indicates this sta is ibss starter */
+-	bool link_up;		/* link/connection up flag */
+-	bool pwr_save;		/* indicate whether dongle to support
+-					 power save mode */
+-	bool dongle_up;		/* indicate whether dongle up or not */
+-	bool roam_on;		/* on/off switch for dongle self-roaming */
+-	bool scan_tried;	/* indicates if first scan attempted */
+-	u8 *ioctl_buf;	/* ioctl buffer */
+-	u8 *extra_buf;	/* maily to grab assoc information */
+-	struct dentry *debugfsdir;
+-	u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
+-};
+-
+-#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
+-#define wl_to_wiphy(w) (w->wdev->wiphy)
+-#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w)))
+-#define wl_to_wdev(w) (w->wdev)
+-#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w)))
+-#define wl_to_ndev(w) (w->wdev->netdev)
+-#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
+-#define ci_to_wl(c) (ci->wl)
+-#define wl_to_ci(w) (&w->ci)
+-#define wl_to_sr(w) (w->scan_req_int)
+-#define wl_to_ie(w) (&w->ie)
+-#define iscan_to_wl(i) ((struct wl_priv *)(i->data))
+-#define wl_to_iscan(w) (w->iscan)
+-#define wl_to_conn(w) (&w->conn_info)
+-
+-static inline struct wl_bss_info *next_bss(struct wl_scan_results *list,
+-					   struct wl_bss_info *bss)
+-{
+-	return bss = bss ?
+-		(struct wl_bss_info *)((unsigned long)bss +
+-				       le32_to_cpu(bss->length)) :
+-		list->bss_info;
+-}
+-
+-#define for_each_bss(list, bss, __i)	\
+-	for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
+-
+-extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data);
+-extern void wl_cfg80211_detach(void);
+-/* event handler from dongle */
+-extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
+-			      void *data);
+-extern void wl_cfg80211_sdio_func(void *func);	/* set sdio function info */
+-extern struct sdio_func *wl_cfg80211_get_sdio_func(void);	/* set sdio function info */
+-extern s32 wl_cfg80211_up(void);	/* dongle up */
+-extern s32 wl_cfg80211_down(void);	/* dongle down */
+-extern void wl_cfg80211_dbg_level(u32 level);	/* set dongle
+-							 debugging level */
+-extern void *wl_cfg80211_request_fw(s8 *file_name);	/* request fw /nvram
+-							 downloading */
+-extern s32 wl_cfg80211_read_fw(s8 *buf, u32 size);	/* read fw
+-								 image */
+-extern void wl_cfg80211_release_fw(void);	/* release fw */
+-extern s8 *wl_cfg80211_get_fwname(void);	/* get firmware name for
+-						 the dongle */
+-extern s8 *wl_cfg80211_get_nvramname(void);	/* get nvram name for
+-						 the dongle */
+-extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick);
+-
+-#endif				/* _wl_cfg80211_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c
+deleted file mode 100644
+index 15e1b05..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c
++++ /dev/null
+@@ -1,3693 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kthread.h>
+-#include <linux/semaphore.h>
+-#include <bcmdefs.h>
+-#include <linux/netdevice.h>
+-#include <wlioctl.h>
+-
+-#include <bcmutils.h>
+-
+-#include <linux/if_arp.h>
+-#include <asm/uaccess.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhdioctl.h>
+-#include <linux/ieee80211.h>
+-typedef const struct si_pub si_t;
+-#include <wlioctl.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#define WL_ERROR(fmt, args...)	printk(fmt, ##args)
+-#define WL_TRACE(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_INFORM(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_WSEC(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_SCAN(fmt, args...)	no_printk(fmt, ##args)
+-
+-#include <wl_iw.h>
+-
+-#define IW_WSEC_ENABLED(wsec)	((wsec) & (WEP_ENABLED |	\
+-					 TKIP_ENABLED | AES_ENABLED))
+-
+-#include <linux/rtnetlink.h>
+-
+-#define WL_IW_USE_ISCAN  1
+-#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS  1
+-
+-bool g_set_essid_before_scan = true;
+-
+-#define WL_IW_IOCTL_CALL(func_call) \
+-	do {				\
+-		func_call;		\
+-	} while (0)
+-
+-static int g_onoff = G_WLAN_SET_ON;
+-wl_iw_extra_params_t g_wl_iw_params;
+-
+-extern bool wl_iw_conn_status_str(u32 event_type, u32 status,
+-				  u32 reason, char *stringBuf, uint buflen);
+-
+-#define MAX_WLIW_IOCTL_LEN 1024
+-
+-#ifdef CONFIG_WIRELESS_EXT
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-#endif
+-
+-#if WIRELESS_EXT < 19
+-#define IW_IOCTL_IDX(cmd)	((cmd) - SIOCIWFIRST)
+-#define IW_EVENT_IDX(cmd)	((cmd) - IWEVFIRST)
+-#endif
+-
+-static void *g_scan;
+-static volatile uint g_scan_specified_ssid;
+-static wlc_ssid_t g_specific_ssid;
+-
+-static wlc_ssid_t g_ssid;
+-
+-#if defined(WL_IW_USE_ISCAN)
+-#define ISCAN_STATE_IDLE   0
+-#define ISCAN_STATE_SCANING 1
+-
+-#define WLC_IW_ISCAN_MAXLEN   2048
+-typedef struct iscan_buf {
+-	struct iscan_buf *next;
+-	char iscan_buf[WLC_IW_ISCAN_MAXLEN];
+-} iscan_buf_t;
+-
+-typedef struct iscan_info {
+-	struct net_device *dev;
+-	struct timer_list timer;
+-	u32 timer_ms;
+-	u32 timer_on;
+-	int iscan_state;
+-	iscan_buf_t *list_hdr;
+-	iscan_buf_t *list_cur;
+-
+-	struct task_struct *sysioc_tsk;
+-	struct semaphore sysioc_sem;
+-
+-#if defined CSCAN
+-	char ioctlbuf[WLC_IOCTL_MEDLEN];
+-#else
+-	char ioctlbuf[WLC_IOCTL_SMLEN];
+-#endif
+-	wl_iscan_params_t *iscan_ex_params_p;
+-	int iscan_ex_param_size;
+-} iscan_info_t;
+-iscan_info_t *g_iscan;
+-
+-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-
+-/* Global ASSERT type flag */
+-u32 g_assert_type;
+-
+-static void wl_iw_timerfunc(unsigned long data);
+-static void wl_iw_set_event_mask(struct net_device *dev);
+-static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action);
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-static int
+-wl_iw_set_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       union iwreq_data *wrqu, char *extra);
+-
+-static int
+-wl_iw_get_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       struct iw_point *dwrq, char *extra);
+-
+-static uint
+-wl_iw_get_scan_prep(wl_scan_results_t *list,
+-		    struct iw_request_info *info, char *extra, short max_size);
+-
+-static void swap_key_from_BE(wl_wsec_key_t *key)
+-{
+-	key->index = cpu_to_le32(key->index);
+-	key->len = cpu_to_le32(key->len);
+-	key->algo = cpu_to_le32(key->algo);
+-	key->flags = cpu_to_le32(key->flags);
+-	key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
+-	key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
+-	key->iv_initialized = cpu_to_le32(key->iv_initialized);
+-}
+-
+-static void swap_key_to_BE(wl_wsec_key_t *key)
+-{
+-	key->index = le32_to_cpu(key->index);
+-	key->len = le32_to_cpu(key->len);
+-	key->algo = le32_to_cpu(key->algo);
+-	key->flags = le32_to_cpu(key->flags);
+-	key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
+-	key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
+-	key->iv_initialized = le32_to_cpu(key->iv_initialized);
+-}
+-
+-static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len)
+-{
+-	struct ifreq ifr;
+-	wl_ioctl_t ioc;
+-	mm_segment_t fs;
+-	int ret = -EINVAL;
+-
+-	if (!dev) {
+-		WL_ERROR("%s: dev is null\n", __func__);
+-		return ret;
+-	}
+-
+-	WL_INFORM("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n",
+-		  __func__, current->pid, cmd, arg, len);
+-
+-	if (g_onoff == G_WLAN_SET_ON) {
+-		memset(&ioc, 0, sizeof(ioc));
+-		ioc.cmd = cmd;
+-		ioc.buf = arg;
+-		ioc.len = len;
+-
+-		strcpy(ifr.ifr_name, dev->name);
+-		ifr.ifr_data = (caddr_t)&ioc;
+-
+-		ret = dev_open(dev);
+-		if (ret) {
+-			WL_ERROR("%s: Error dev_open: %d\n", __func__, ret);
+-			return ret;
+-		}
+-
+-		fs = get_fs();
+-		set_fs(get_ds());
+-		ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-		set_fs(fs);
+-	} else {
+-		WL_TRACE("%s: call after driver stop : ignored\n", __func__);
+-	}
+-	return ret;
+-}
+-
+-static int dev_wlc_intvar_set(struct net_device *dev, char *name, int val)
+-{
+-	char buf[WLC_IOCTL_SMLEN];
+-	uint len;
+-
+-	val = cpu_to_le32(val);
+-	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+-	ASSERT(len);
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len);
+-}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-static int
+-dev_iw_iovar_setbuf(struct net_device *dev,
+-		    char *iovar,
+-		    void *param, int paramlen, void *bufptr, int buflen)
+-{
+-	int iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	ASSERT(iolen);
+-
+-	if (iolen == 0)
+-		return 0;
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
+-}
+-
+-static int
+-dev_iw_iovar_getbuf(struct net_device *dev,
+-		    char *iovar,
+-		    void *param, int paramlen, void *bufptr, int buflen)
+-{
+-	int iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	ASSERT(iolen);
+-
+-	return dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
+-}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-#if WIRELESS_EXT > 17
+-static int
+-dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
+-{
+-	static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
+-	uint buflen;
+-
+-	buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));
+-	ASSERT(buflen);
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen);
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-dev_wlc_bufvar_get(struct net_device *dev, char *name, char *buf, int buflen)
+-{
+-	static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
+-	int error;
+-	uint len;
+-
+-	len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf));
+-	ASSERT(len);
+-	error =
+-	    dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf,
+-			  MAX_WLIW_IOCTL_LEN);
+-	if (!error)
+-		memcpy(buf, ioctlbuf, buflen);
+-
+-	return error;
+-}
+-
+-static int dev_wlc_intvar_get(struct net_device *dev, char *name, int *retval)
+-{
+-	union {
+-		char buf[WLC_IOCTL_SMLEN];
+-		int val;
+-	} var;
+-	int error;
+-
+-	uint len;
+-	uint data_null;
+-
+-	len =
+-	    bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
+-			sizeof(var.buf));
+-	ASSERT(len);
+-	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
+-
+-	*retval = le32_to_cpu(var.val);
+-
+-	return error;
+-}
+-
+-#if WIRELESS_EXT < 13
+-struct iw_request_info {
+-	__u16 cmd;
+-	__u16 flags;
+-};
+-
+-typedef int (*iw_handler) (struct net_device *dev,
+-			   struct iw_request_info *info,
+-			   void *wrqu, char *extra);
+-#endif
+-
+-static int
+-wl_iw_config_commit(struct net_device *dev,
+-		    struct iw_request_info *info, void *zwrq, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	int error;
+-	struct sockaddr bssid;
+-
+-	WL_TRACE("%s: SIOCSIWCOMMIT\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
+-	if (error)
+-		return error;
+-
+-	ssid.SSID_len = le32_to_cpu(ssid.SSID_len);
+-
+-	if (!ssid.SSID_len)
+-		return 0;
+-
+-	memset(&bssid, 0, sizeof(struct sockaddr));
+-	error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN);
+-	if (error) {
+-		WL_ERROR("%s: WLC_REASSOC to %s failed\n",
+-			 __func__, ssid.SSID);
+-		return error;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_name(struct net_device *dev,
+-	       struct iw_request_info *info, char *cwrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWNAME\n", dev->name);
+-
+-	strcpy(cwrq, "IEEE 802.11-DS");
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_freq(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_freq *fwrq, char *extra)
+-{
+-	int error, chan;
+-	uint sf = 0;
+-
+-	WL_TRACE("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name);
+-
+-	if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {
+-		chan = fwrq->m;
+-	} else {
+-		if (fwrq->e >= 6) {
+-			fwrq->e -= 6;
+-			while (fwrq->e--)
+-				fwrq->m *= 10;
+-		} else if (fwrq->e < 6) {
+-			while (fwrq->e++ < 6)
+-				fwrq->m /= 10;
+-		}
+-		if (fwrq->m > 4000 && fwrq->m < 5000)
+-			sf = WF_CHAN_FACTOR_4_G;
+-
+-		chan = bcm_mhz2channel(fwrq->m, sf);
+-	}
+-	chan = cpu_to_le32(chan);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan));
+-	if (error)
+-		return error;
+-
+-	g_wl_iw_params.target_channel = chan;
+-	return -EINPROGRESS;
+-}
+-
+-static int
+-wl_iw_get_freq(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_freq *fwrq, char *extra)
+-{
+-	channel_info_t ci;
+-	int error;
+-
+-	WL_TRACE("%s: SIOCGIWFREQ\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci));
+-	if (error)
+-		return error;
+-
+-	fwrq->m = le32_to_cpu(ci.hw_channel);
+-	fwrq->e = le32_to_cpu(0);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_mode(struct net_device *dev,
+-	       struct iw_request_info *info, __u32 *uwrq, char *extra)
+-{
+-	int infra = 0, ap = 0, error = 0;
+-
+-	WL_TRACE("%s: SIOCSIWMODE\n", dev->name);
+-
+-	switch (*uwrq) {
+-	case IW_MODE_MASTER:
+-		infra = ap = 1;
+-		break;
+-	case IW_MODE_ADHOC:
+-	case IW_MODE_AUTO:
+-		break;
+-	case IW_MODE_INFRA:
+-		infra = 1;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-	infra = cpu_to_le32(infra);
+-	ap = cpu_to_le32(ap);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap));
+-	if (error)
+-		return error;
+-
+-	return -EINPROGRESS;
+-}
+-
+-static int
+-wl_iw_get_mode(struct net_device *dev,
+-	       struct iw_request_info *info, __u32 *uwrq, char *extra)
+-{
+-	int error, infra = 0, ap = 0;
+-
+-	WL_TRACE("%s: SIOCGIWMODE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap));
+-	if (error)
+-		return error;
+-
+-	infra = le32_to_cpu(infra);
+-	ap = le32_to_cpu(ap);
+-	*uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_range(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	struct iw_range *range = (struct iw_range *)extra;
+-	wl_u32_list_t *list;
+-	wl_rateset_t rateset;
+-	s8 *channels;
+-	int error, i, k;
+-	uint ch;
+-
+-	int phytype;
+-	int bw_cap = 0, sgi_tx = 0, nmode = 0;
+-	channel_info_t ci;
+-	u8 nrate_list2copy = 0;
+-	u16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130},
+-	{14, 29, 43, 58, 87, 116, 130, 144},
+-	{27, 54, 81, 108, 162, 216, 243, 270},
+-	{30, 60, 90, 120, 180, 240, 270, 300}
+-	};
+-
+-	WL_TRACE("%s: SIOCGIWRANGE\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	channels = kmalloc((MAXCHANNEL + 1) * 4, GFP_KERNEL);
+-	if (!channels) {
+-		WL_ERROR("Could not alloc channels\n");
+-		return -ENOMEM;
+-	}
+-	list = (wl_u32_list_t *) channels;
+-
+-	dwrq->length = sizeof(struct iw_range);
+-	memset(range, 0, sizeof(*range));
+-
+-	list->count = cpu_to_le32(MAXCHANNEL);
+-	error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels,
+-				(MAXCHANNEL + 1) * 4);
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	for (i = 0; i < le32_to_cpu(list->count) && i < IW_MAX_FREQUENCIES;
+-	     i++) {
+-		range->freq[i].i = le32_to_cpu(list->element[i]);
+-
+-		ch = le32_to_cpu(list->element[i]);
+-		if (ch <= CH_MAX_2G_CHANNEL) {
+-			range->freq[i].m = ieee80211_dsss_chan_to_freq(ch);
+-		} else {
+-			range->freq[i].m = ieee80211_ofdm_chan_to_freq(
+-						WF_CHAN_FACTOR_5_G/2, ch);
+-		}
+-		range->freq[i].e = 6;
+-	}
+-	range->num_frequency = range->num_channels = i;
+-
+-	range->max_qual.qual = 5;
+-	range->max_qual.level = 0x100 - 200;
+-	range->max_qual.noise = 0x100 - 200;
+-	range->sensitivity = 65535;
+-
+-#if WIRELESS_EXT > 11
+-	range->avg_qual.qual = 3;
+-	range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD;
+-	range->avg_qual.noise = 0x100 - 75;
+-#endif
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-				sizeof(rateset));
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	rateset.count = le32_to_cpu(rateset.count);
+-	range->num_bitrates = rateset.count;
+-	for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++)
+-		range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000;
+-	dev_wlc_intvar_get(dev, "nmode", &nmode);
+-	dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype));
+-
+-	if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) {
+-		dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap);
+-		dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx);
+-		dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci,
+-			      sizeof(channel_info_t));
+-		ci.hw_channel = le32_to_cpu(ci.hw_channel);
+-
+-		if (bw_cap == 0 || (bw_cap == 2 && ci.hw_channel <= 14)) {
+-			if (sgi_tx == 0)
+-				nrate_list2copy = 0;
+-			else
+-				nrate_list2copy = 1;
+-		}
+-		if (bw_cap == 1 || (bw_cap == 2 && ci.hw_channel >= 36)) {
+-			if (sgi_tx == 0)
+-				nrate_list2copy = 2;
+-			else
+-				nrate_list2copy = 3;
+-		}
+-		range->num_bitrates += 8;
+-		for (k = 0; i < range->num_bitrates; k++, i++) {
+-			range->bitrate[i] =
+-			    (nrate_list[nrate_list2copy][k]) * 500000;
+-		}
+-	}
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i));
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	i = le32_to_cpu(i);
+-	if (i == WLC_PHY_TYPE_A)
+-		range->throughput = 24000000;
+-	else
+-		range->throughput = 1500000;
+-
+-	range->min_rts = 0;
+-	range->max_rts = 2347;
+-	range->min_frag = 256;
+-	range->max_frag = 2346;
+-
+-	range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS;
+-	range->num_encoding_sizes = 4;
+-	range->encoding_size[0] = WLAN_KEY_LEN_WEP40;
+-	range->encoding_size[1] = WLAN_KEY_LEN_WEP104;
+-#if WIRELESS_EXT > 17
+-	range->encoding_size[2] = WLAN_KEY_LEN_TKIP;
+-#else
+-	range->encoding_size[2] = 0;
+-#endif
+-	range->encoding_size[3] = WLAN_KEY_LEN_AES_CMAC;
+-
+-	range->min_pmp = 0;
+-	range->max_pmp = 0;
+-	range->min_pmt = 0;
+-	range->max_pmt = 0;
+-	range->pmp_flags = 0;
+-	range->pm_capa = 0;
+-
+-	range->num_txpower = 2;
+-	range->txpower[0] = 1;
+-	range->txpower[1] = 255;
+-	range->txpower_capa = IW_TXPOW_MWATT;
+-
+-#if WIRELESS_EXT > 10
+-	range->we_version_compiled = WIRELESS_EXT;
+-	range->we_version_source = 19;
+-
+-	range->retry_capa = IW_RETRY_LIMIT;
+-	range->retry_flags = IW_RETRY_LIMIT;
+-	range->r_time_flags = 0;
+-	range->min_retry = 1;
+-	range->max_retry = 255;
+-	range->min_r_time = 0;
+-	range->max_r_time = 0;
+-#endif
+-
+-#if WIRELESS_EXT > 17
+-	range->enc_capa = IW_ENC_CAPA_WPA;
+-	range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+-	range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+-	range->enc_capa |= IW_ENC_CAPA_WPA2;
+-
+-	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND);
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-	kfree(channels);
+-
+-	return 0;
+-}
+-
+-static int rssi_to_qual(int rssi)
+-{
+-	if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+-		return 0;
+-	else if (rssi <= WL_IW_RSSI_VERY_LOW)
+-		return 1;
+-	else if (rssi <= WL_IW_RSSI_LOW)
+-		return 2;
+-	else if (rssi <= WL_IW_RSSI_GOOD)
+-		return 3;
+-	else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+-		return 4;
+-	else
+-		return 5;
+-}
+-
+-static int
+-wl_iw_set_spy(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	int i;
+-
+-	WL_TRACE("%s: SIOCSIWSPY\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length);
+-	for (i = 0; i < iw->spy_num; i++)
+-		memcpy(iw->spy_addr[i], addr[i].sa_data, ETH_ALEN);
+-	memset(iw->spy_qual, 0, sizeof(iw->spy_qual));
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_spy(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality *qual = (struct iw_quality *)&addr[iw->spy_num];
+-	int i;
+-
+-	WL_TRACE("%s: SIOCGIWSPY\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	dwrq->length = iw->spy_num;
+-	for (i = 0; i < iw->spy_num; i++) {
+-		memcpy(addr[i].sa_data, iw->spy_addr[i], ETH_ALEN);
+-		addr[i].sa_family = AF_UNIX;
+-		memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality));
+-		iw->spy_qual[i].updated = 0;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params,
+-		     int *join_params_size)
+-{
+-	chanspec_t chanspec = 0;
+-
+-	if (ch != 0) {
+-		join_params->params.chanspec_num = 1;
+-		join_params->params.chanspec_list[0] = ch;
+-
+-		if (join_params->params.chanspec_list[0])
+-			chanspec |= WL_CHANSPEC_BAND_2G;
+-		else
+-			chanspec |= WL_CHANSPEC_BAND_5G;
+-
+-		chanspec |= WL_CHANSPEC_BW_20;
+-		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+-
+-		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+-		    join_params->params.chanspec_num * sizeof(chanspec_t);
+-
+-		join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+-		join_params->params.chanspec_list[0] |= chanspec;
+-		join_params->params.chanspec_list[0] =
+-		    cpu_to_le16(join_params->params.chanspec_list[0]);
+-
+-		join_params->params.chanspec_num =
+-		    cpu_to_le32(join_params->params.chanspec_num);
+-
+-		WL_TRACE("%s  join_params->params.chanspec_list[0]= %X\n",
+-			 __func__, join_params->params.chanspec_list[0]);
+-	}
+-	return 1;
+-}
+-
+-static int
+-wl_iw_set_wap(struct net_device *dev,
+-	      struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	int error = -EINVAL;
+-	wl_join_params_t join_params;
+-	int join_params_size;
+-
+-	WL_TRACE("%s: SIOCSIWAP\n", dev->name);
+-
+-	if (awrq->sa_family != ARPHRD_ETHER) {
+-		WL_ERROR("Invalid Header...sa_family\n");
+-		return -EINVAL;
+-	}
+-
+-	if (is_broadcast_ether_addr(awrq->sa_data) ||
+-	    is_zero_ether_addr(awrq->sa_data)) {
+-		scb_val_t scbval;
+-		memset(&scbval, 0, sizeof(scb_val_t));
+-		(void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval,
+-				    sizeof(scb_val_t));
+-		return 0;
+-	}
+-
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-	memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN);
+-
+-	WL_TRACE("%s  target_channel=%d\n",
+-		 __func__, g_wl_iw_params.target_channel);
+-	wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params,
+-			     &join_params_size);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params,
+-				join_params_size);
+-	if (error) {
+-		WL_ERROR("%s Invalid ioctl data=%d\n", __func__, error);
+-	}
+-
+-	if (g_ssid.SSID_len) {
+-		WL_TRACE("%s: join SSID=%s BSSID=%pM ch=%d\n",
+-			 __func__, g_ssid.SSID, awrq->sa_data,
+-			 g_wl_iw_params.target_channel);
+-	}
+-
+-	memset(&g_ssid, 0, sizeof(g_ssid));
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_wap(struct net_device *dev,
+-	      struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWAP\n", dev->name);
+-
+-	awrq->sa_family = ARPHRD_ETHER;
+-	memset(awrq->sa_data, 0, ETH_ALEN);
+-
+-	(void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETH_ALEN);
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-static int
+-wl_iw_mlme(struct net_device *dev,
+-	   struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	struct iw_mlme *mlme;
+-	scb_val_t scbval;
+-	int error = -EINVAL;
+-
+-	WL_TRACE("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name);
+-
+-	mlme = (struct iw_mlme *)extra;
+-	if (mlme == NULL) {
+-		WL_ERROR("Invalid ioctl data\n");
+-		return error;
+-	}
+-
+-	scbval.val = mlme->reason_code;
+-	memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN);
+-
+-	if (mlme->cmd == IW_MLME_DISASSOC) {
+-		scbval.val = cpu_to_le32(scbval.val);
+-		error =
+-		    dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval,
+-				  sizeof(scb_val_t));
+-	} else if (mlme->cmd == IW_MLME_DEAUTH) {
+-		scbval.val = cpu_to_le32(scbval.val);
+-		error =
+-		    dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON,
+-				  &scbval, sizeof(scb_val_t));
+-	} else {
+-		WL_ERROR("Invalid ioctl data\n");
+-		return error;
+-	}
+-
+-	return error;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-#ifndef WL_IW_USE_ISCAN
+-static int
+-wl_iw_get_aplist(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality qual[IW_MAX_AP];
+-	wl_bss_info_t *bi = NULL;
+-	int error, i;
+-	uint buflen = dwrq->length;
+-
+-	WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	list = kzalloc(buflen, GFP_KERNEL);
+-	if (!list)
+-		return -ENOMEM;
+-	list->buflen = cpu_to_le32(buflen);
+-	error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen);
+-	if (error) {
+-		WL_ERROR("%d: Scan results error %d\n", __LINE__, error);
+-		kfree(list);
+-		return error;
+-	}
+-	list->buflen = le32_to_cpu(list->buflen);
+-	list->version = le32_to_cpu(list->version);
+-	list->count = le32_to_cpu(list->count);
+-	if (list->version != WL_BSS_INFO_VERSION) {
+-		WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-			 __func__, list->version);
+-		kfree(list);
+-		return -EINVAL;
+-	}
+-
+-	for (i = 0, dwrq->length = 0;
+-	     i < list->count && dwrq->length < IW_MAX_AP; i++) {
+-		bi = bi ? (wl_bss_info_t *) ((unsigned long)bi +
+-					     le32_to_cpu(bi->length)) : list->
+-		    bss_info;
+-		ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-		       ((unsigned long)list + buflen));
+-
+-		if (!(le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS))
+-			continue;
+-
+-		memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN);
+-		addr[dwrq->length].sa_family = ARPHRD_ETHER;
+-		qual[dwrq->length].qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-		qual[dwrq->length].level = 0x100 + le16_to_cpu(bi->RSSI);
+-		qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+-
+-#if WIRELESS_EXT > 18
+-		qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+-#else
+-		qual[dwrq->length].updated = 7;
+-#endif
+-		dwrq->length++;
+-	}
+-
+-	kfree(list);
+-
+-	if (dwrq->length) {
+-		memcpy(&addr[dwrq->length], qual,
+-		       sizeof(struct iw_quality) * dwrq->length);
+-		dwrq->flags = 1;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-#ifdef WL_IW_USE_ISCAN
+-static int
+-wl_iw_iscan_get_aplist(struct net_device *dev,
+-		       struct iw_request_info *info,
+-		       struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	iscan_buf_t *buf;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality qual[IW_MAX_AP];
+-	wl_bss_info_t *bi = NULL;
+-	int i;
+-
+-	WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk)) {
+-		WL_ERROR("%s error\n", __func__);
+-		return 0;
+-	}
+-
+-	buf = iscan->list_hdr;
+-	while (buf) {
+-		list = &((wl_iscan_results_t *) buf->iscan_buf)->results;
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return -EINVAL;
+-		}
+-
+-		bi = NULL;
+-		for (i = 0, dwrq->length = 0;
+-		     i < list->count && dwrq->length < IW_MAX_AP; i++) {
+-			bi = bi ? (wl_bss_info_t *) ((unsigned long)bi +
+-						     le32_to_cpu(bi->length)) :
+-			    list->bss_info;
+-			ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-			       ((unsigned long)list + WLC_IW_ISCAN_MAXLEN));
+-
+-			if (!(le16_to_cpu(bi->capability) &
+-			      WLAN_CAPABILITY_ESS))
+-				continue;
+-
+-			memcpy(addr[dwrq->length].sa_data, &bi->BSSID,
+-			       ETH_ALEN);
+-			addr[dwrq->length].sa_family = ARPHRD_ETHER;
+-			qual[dwrq->length].qual =
+-			    rssi_to_qual(le16_to_cpu(bi->RSSI));
+-			qual[dwrq->length].level = 0x100 +
+-							le16_to_cpu(bi->RSSI);
+-			qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+-
+-#if WIRELESS_EXT > 18
+-			qual[dwrq->length].updated =
+-			    IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+-#else
+-			qual[dwrq->length].updated = 7;
+-#endif
+-
+-			dwrq->length++;
+-		}
+-		buf = buf->next;
+-	}
+-	if (dwrq->length) {
+-		memcpy(&addr[dwrq->length], qual,
+-		       sizeof(struct iw_quality) * dwrq->length);
+-		dwrq->flags = 1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid)
+-{
+-	int err = 0;
+-
+-	memcpy(params->bssid, ether_bcast, ETH_ALEN);
+-	params->bss_type = DOT11_BSSTYPE_ANY;
+-	params->scan_type = 0;
+-	params->nprobes = -1;
+-	params->active_time = -1;
+-	params->passive_time = -1;
+-	params->home_time = -1;
+-	params->channel_num = 0;
+-
+-	params->nprobes = cpu_to_le32(params->nprobes);
+-	params->active_time = cpu_to_le32(params->active_time);
+-	params->passive_time = cpu_to_le32(params->passive_time);
+-	params->home_time = cpu_to_le32(params->home_time);
+-	if (ssid && ssid->SSID_len)
+-		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+-
+-	return err;
+-}
+-
+-static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action)
+-{
+-	int err = 0;
+-
+-	iscan->iscan_ex_params_p->version = cpu_to_le32(ISCAN_REQ_VERSION);
+-	iscan->iscan_ex_params_p->action = cpu_to_le16(action);
+-	iscan->iscan_ex_params_p->scan_duration = cpu_to_le16(0);
+-
+-	WL_SCAN("%s : nprobes=%d\n",
+-		__func__, iscan->iscan_ex_params_p->params.nprobes);
+-	WL_SCAN("active_time=%d\n",
+-		 iscan->iscan_ex_params_p->params.active_time);
+-	WL_SCAN("passive_time=%d\n",
+-		 iscan->iscan_ex_params_p->params.passive_time);
+-	WL_SCAN("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time);
+-	WL_SCAN("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type);
+-	WL_SCAN("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type);
+-
+-	(void)dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p,
+-				  iscan->iscan_ex_param_size, iscan->ioctlbuf,
+-				  sizeof(iscan->ioctlbuf));
+-
+-	return err;
+-}
+-
+-static void wl_iw_timerfunc(unsigned long data)
+-{
+-	iscan_info_t *iscan = (iscan_info_t *) data;
+-	if (iscan) {
+-		iscan->timer_on = 0;
+-		if (iscan->iscan_state != ISCAN_STATE_IDLE) {
+-			WL_TRACE("timer trigger\n");
+-			up(&iscan->sysioc_sem);
+-		}
+-	}
+-}
+-
+-static void wl_iw_set_event_mask(struct net_device *dev)
+-{
+-	char eventmask[WL_EVENTING_MASK_LEN];
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];
+-
+-	dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf));
+-	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-	setbit(eventmask, WLC_E_SCAN_COMPLETE);
+-	dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN,
+-			    iovbuf, sizeof(iovbuf));
+-}
+-
+-static u32 wl_iw_iscan_get(iscan_info_t *iscan)
+-{
+-	iscan_buf_t *buf;
+-	iscan_buf_t *ptr;
+-	wl_iscan_results_t *list_buf;
+-	wl_iscan_results_t list;
+-	wl_scan_results_t *results;
+-	u32 status;
+-	int res = 0;
+-
+-	MUTEX_LOCK_WL_SCAN_SET();
+-	if (iscan->list_cur) {
+-		buf = iscan->list_cur;
+-		iscan->list_cur = buf->next;
+-	} else {
+-		buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL);
+-		if (!buf) {
+-			WL_ERROR("%s can't alloc iscan_buf_t : going to abort current iscan\n",
+-				 __func__);
+-			MUTEX_UNLOCK_WL_SCAN_SET();
+-			return WL_SCAN_RESULTS_NO_MEM;
+-		}
+-		buf->next = NULL;
+-		if (!iscan->list_hdr)
+-			iscan->list_hdr = buf;
+-		else {
+-			ptr = iscan->list_hdr;
+-			while (ptr->next) {
+-				ptr = ptr->next;
+-			}
+-			ptr->next = buf;
+-		}
+-	}
+-	memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+-	list_buf = (wl_iscan_results_t *) buf->iscan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = cpu_to_le32(WLC_IW_ISCAN_MAXLEN);
+-	res = dev_iw_iovar_getbuf(iscan->dev,
+-				  "iscanresults",
+-				  &list,
+-				  WL_ISCAN_RESULTS_FIXED_SIZE,
+-				  buf->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+-	if (res == 0) {
+-		results->buflen = le32_to_cpu(results->buflen);
+-		results->version = le32_to_cpu(results->version);
+-		results->count = le32_to_cpu(results->count);
+-		WL_TRACE("results->count = %d\n", results->count);
+-		WL_TRACE("results->buflen = %d\n", results->buflen);
+-		status = le32_to_cpu(list_buf->status);
+-	} else {
+-		WL_ERROR("%s returns error %d\n", __func__, res);
+-		status = WL_SCAN_RESULTS_NO_MEM;
+-	}
+-	MUTEX_UNLOCK_WL_SCAN_SET();
+-	return status;
+-}
+-
+-static void wl_iw_force_specific_scan(iscan_info_t *iscan)
+-{
+-	WL_TRACE("%s force Specific SCAN for %s\n",
+-		 __func__, g_specific_ssid.SSID);
+-	rtnl_lock();
+-
+-	(void)dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid,
+-			    sizeof(g_specific_ssid));
+-
+-	rtnl_unlock();
+-}
+-
+-static void wl_iw_send_scan_complete(iscan_info_t *iscan)
+-{
+-#ifndef SANDGATE2G
+-	union iwreq_data wrqu;
+-
+-	memset(&wrqu, 0, sizeof(wrqu));
+-
+-	wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL);
+-	WL_TRACE("Send Event ISCAN complete\n");
+-#endif
+-}
+-
+-static int _iscan_sysioc_thread(void *data)
+-{
+-	u32 status;
+-	iscan_info_t *iscan = (iscan_info_t *) data;
+-	static bool iscan_pass_abort = false;
+-
+-	allow_signal(SIGTERM);
+-	status = WL_SCAN_RESULTS_PARTIAL;
+-	while (down_interruptible(&iscan->sysioc_sem) == 0) {
+-		if (kthread_should_stop())
+-			break;
+-
+-		if (iscan->timer_on) {
+-			del_timer_sync(&iscan->timer);
+-			iscan->timer_on = 0;
+-		}
+-		rtnl_lock();
+-		status = wl_iw_iscan_get(iscan);
+-		rtnl_unlock();
+-		if (g_scan_specified_ssid && (iscan_pass_abort == true)) {
+-			WL_TRACE("%s Get results from specific scan status = %d\n",
+-				 __func__, status);
+-			wl_iw_send_scan_complete(iscan);
+-			iscan_pass_abort = false;
+-			status = -1;
+-		}
+-
+-		switch (status) {
+-		case WL_SCAN_RESULTS_PARTIAL:
+-			WL_TRACE("iscanresults incomplete\n");
+-			rtnl_lock();
+-			wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+-			rtnl_unlock();
+-			mod_timer(&iscan->timer,
+-				  jiffies + iscan->timer_ms * HZ / 1000);
+-			iscan->timer_on = 1;
+-			break;
+-		case WL_SCAN_RESULTS_SUCCESS:
+-			WL_TRACE("iscanresults complete\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			wl_iw_send_scan_complete(iscan);
+-			break;
+-		case WL_SCAN_RESULTS_PENDING:
+-			WL_TRACE("iscanresults pending\n");
+-			mod_timer(&iscan->timer,
+-				  jiffies + iscan->timer_ms * HZ / 1000);
+-			iscan->timer_on = 1;
+-			break;
+-		case WL_SCAN_RESULTS_ABORTED:
+-			WL_TRACE("iscanresults aborted\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			if (g_scan_specified_ssid == 0)
+-				wl_iw_send_scan_complete(iscan);
+-			else {
+-				iscan_pass_abort = true;
+-				wl_iw_force_specific_scan(iscan);
+-			}
+-			break;
+-		case WL_SCAN_RESULTS_NO_MEM:
+-			WL_TRACE("iscanresults can't alloc memory: skip\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			break;
+-		default:
+-			WL_TRACE("iscanresults returned unknown status %d\n",
+-				 status);
+-			break;
+-		}
+-	}
+-
+-	if (iscan->timer_on) {
+-		del_timer_sync(&iscan->timer);
+-		iscan->timer_on = 0;
+-	}
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-static int
+-wl_iw_set_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       union iwreq_data *wrqu, char *extra)
+-{
+-	int error;
+-	WL_TRACE("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name);
+-
+-	g_set_essid_before_scan = false;
+-#if defined(CSCAN)
+-	WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__);
+-	return -EINVAL;
+-#endif
+-
+-	if (g_onoff == G_WLAN_SET_OFF)
+-		return 0;
+-
+-	memset(&g_specific_ssid, 0, sizeof(g_specific_ssid));
+-#ifndef WL_IW_USE_ISCAN
+-	g_scan_specified_ssid = 0;
+-#endif
+-
+-#if WIRELESS_EXT > 17
+-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+-		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+-			struct iw_scan_req *req = (struct iw_scan_req *)extra;
+-			if (g_scan_specified_ssid) {
+-				WL_TRACE("%s Specific SCAN is not done ignore scan for = %s\n",
+-					 __func__, req->essid);
+-				return -EBUSY;
+-			} else {
+-				g_specific_ssid.SSID_len = min_t(size_t,
+-						sizeof(g_specific_ssid.SSID),
+-						req->essid_len);
+-				memcpy(g_specific_ssid.SSID, req->essid,
+-				       g_specific_ssid.SSID_len);
+-				g_specific_ssid.SSID_len =
+-				    cpu_to_le32(g_specific_ssid.SSID_len);
+-				g_scan_specified_ssid = 1;
+-				WL_TRACE("### Specific scan ssid=%s len=%d\n",
+-					 g_specific_ssid.SSID,
+-					 g_specific_ssid.SSID_len);
+-			}
+-		}
+-	}
+-#endif				/* WIRELESS_EXT > 17 */
+-	error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid,
+-				sizeof(g_specific_ssid));
+-	if (error) {
+-		WL_TRACE("#### Set SCAN for %s failed with %d\n",
+-			 g_specific_ssid.SSID, error);
+-		g_scan_specified_ssid = 0;
+-		return -EBUSY;
+-	}
+-
+-	return 0;
+-}
+-
+-#ifdef WL_IW_USE_ISCAN
+-int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
+-{
+-	wlc_ssid_t ssid;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	if (flag)
+-		rtnl_lock();
+-
+-	wl_iw_set_event_mask(dev);
+-
+-	WL_TRACE("+++: Set Broadcast ISCAN\n");
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-	iscan->list_cur = iscan->list_hdr;
+-	iscan->iscan_state = ISCAN_STATE_SCANING;
+-
+-	memset(&iscan->iscan_ex_params_p->params, 0,
+-	       iscan->iscan_ex_param_size);
+-	wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid);
+-	wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+-
+-	if (flag)
+-		rtnl_unlock();
+-
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-
+-	iscan->timer_on = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_iscan_set_scan(struct net_device *dev,
+-		     struct iw_request_info *info,
+-		     union iwreq_data *wrqu, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	WL_TRACE("%s: SIOCSIWSCAN : ISCAN\n", dev->name);
+-
+-#if defined(CSCAN)
+-	WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__);
+-	return -EINVAL;
+-#endif
+-
+-	if (g_onoff == G_WLAN_SET_OFF) {
+-		WL_TRACE("%s: driver is not up yet after START\n", __func__);
+-		return 0;
+-	}
+-#ifdef PNO_SUPPORT
+-	if (dhd_dev_get_pno_status(dev)) {
+-		WL_ERROR("%s: Scan called when PNO is active\n", __func__);
+-	}
+-#endif
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk))
+-		return wl_iw_set_scan(dev, info, wrqu, extra);
+-
+-	if (g_scan_specified_ssid) {
+-		WL_TRACE("%s Specific SCAN already running ignoring BC scan\n",
+-			 __func__);
+-		return -EBUSY;
+-	}
+-
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-#if WIRELESS_EXT > 17
+-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+-		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+-			struct iw_scan_req *req = (struct iw_scan_req *)extra;
+-			ssid.SSID_len = min_t(size_t, sizeof(ssid.SSID),
+-						req->essid_len);
+-			memcpy(ssid.SSID, req->essid, ssid.SSID_len);
+-			ssid.SSID_len = cpu_to_le32(ssid.SSID_len);
+-		} else {
+-			g_scan_specified_ssid = 0;
+-
+-			if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+-				WL_TRACE("%s ISCAN already in progress\n",
+-					 __func__);
+-				return 0;
+-			}
+-		}
+-	}
+-#endif				/* WIRELESS_EXT > 17 */
+-	wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
+-
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-#if WIRELESS_EXT > 17
+-static bool ie_is_wpa_ie(u8 **wpaie, u8 **tlvs, int *tlvs_len)
+-{
+-
+-	u8 *ie = *wpaie;
+-
+-	if ((ie[1] >= 6) &&
+-	    !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) {
+-		return true;
+-	}
+-
+-	ie += ie[1] + 2;
+-	*tlvs_len -= (int)(ie - *tlvs);
+-	*tlvs = ie;
+-	return false;
+-}
+-
+-static bool ie_is_wps_ie(u8 **wpsie, u8 **tlvs, int *tlvs_len)
+-{
+-
+-	u8 *ie = *wpsie;
+-
+-	if ((ie[1] >= 4) &&
+-	    !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) {
+-		return true;
+-	}
+-
+-	ie += ie[1] + 2;
+-	*tlvs_len -= (int)(ie - *tlvs);
+-	*tlvs = ie;
+-	return false;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-wl_iw_handle_scanresults_ies(char **event_p, char *end,
+-			     struct iw_request_info *info, wl_bss_info_t *bi)
+-{
+-#if WIRELESS_EXT > 17
+-	struct iw_event iwe;
+-	char *event;
+-
+-	event = *event_p;
+-	if (bi->ie_length) {
+-		bcm_tlv_t *ie;
+-		u8 *ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-		int ptr_len = bi->ie_length;
+-
+-		ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID);
+-		if (ie) {
+-			iwe.cmd = IWEVGENIE;
+-			iwe.u.data.length = ie->len + 2;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 (char *)ie);
+-		}
+-		ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-
+-		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+-			if (ie_is_wps_ie(((u8 **)&ie), &ptr, &ptr_len)) {
+-				iwe.cmd = IWEVGENIE;
+-				iwe.u.data.length = ie->len + 2;
+-				event =
+-				    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-							 (char *)ie);
+-				break;
+-			}
+-		}
+-
+-		ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-		ptr_len = bi->ie_length;
+-		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+-			if (ie_is_wpa_ie(((u8 **)&ie), &ptr, &ptr_len)) {
+-				iwe.cmd = IWEVGENIE;
+-				iwe.u.data.length = ie->len + 2;
+-				event =
+-				    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-							 (char *)ie);
+-				break;
+-			}
+-		}
+-
+-		*event_p = event;
+-	}
+-#endif		/* WIRELESS_EXT > 17 */
+-	return 0;
+-}
+-
+-static uint
+-wl_iw_get_scan_prep(wl_scan_results_t *list,
+-		    struct iw_request_info *info, char *extra, short max_size)
+-{
+-	int i, j;
+-	struct iw_event iwe;
+-	wl_bss_info_t *bi = NULL;
+-	char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value;
+-	int ret = 0;
+-
+-	ASSERT(list);
+-
+-	for (i = 0; i < list->count && i < IW_MAX_AP; i++) {
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return ret;
+-		}
+-
+-		bi = bi ? (wl_bss_info_t *)((unsigned long)bi +
+-					     le32_to_cpu(bi->length)) : list->
+-		    bss_info;
+-
+-		WL_TRACE("%s : %s\n", __func__, bi->SSID);
+-
+-		iwe.cmd = SIOCGIWAP;
+-		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+-		memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETH_ALEN);
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_ADDR_LEN);
+-		iwe.u.data.length = le32_to_cpu(bi->SSID_len);
+-		iwe.cmd = SIOCGIWESSID;
+-		iwe.u.data.flags = 1;
+-		event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+-
+-		if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS |
+-		    WLAN_CAPABILITY_IBSS)) {
+-			iwe.cmd = SIOCGIWMODE;
+-			if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS)
+-				iwe.u.mode = IW_MODE_INFRA;
+-			else
+-				iwe.u.mode = IW_MODE_ADHOC;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_UINT_LEN);
+-		}
+-
+-		iwe.cmd = SIOCGIWFREQ;
+-
+-		if (CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL)
+-			iwe.u.freq.m = ieee80211_dsss_chan_to_freq(
+-						CHSPEC_CHANNEL(bi->chanspec));
+-		else
+-			iwe.u.freq.m = ieee80211_ofdm_chan_to_freq(
+-						WF_CHAN_FACTOR_5_G/2,
+-						CHSPEC_CHANNEL(bi->chanspec));
+-
+-		iwe.u.freq.e = 6;
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_FREQ_LEN);
+-
+-		iwe.cmd = IWEVQUAL;
+-		iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-		iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI);
+-		iwe.u.qual.noise = 0x100 + bi->phy_noise;
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_QUAL_LEN);
+-
+-		wl_iw_handle_scanresults_ies(&event, end, info, bi);
+-
+-		iwe.cmd = SIOCGIWENCODE;
+-		if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_PRIVACY)
+-			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+-		else
+-			iwe.u.data.flags = IW_ENCODE_DISABLED;
+-		iwe.u.data.length = 0;
+-		event =
+-		    IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+-
+-		if (bi->rateset.count) {
+-			if (((event - extra) +
+-				IW_EV_LCP_LEN) <= (unsigned long)end) {
+-				value = event + IW_EV_LCP_LEN;
+-				iwe.cmd = SIOCGIWRATE;
+-				iwe.u.bitrate.fixed = iwe.u.bitrate.disabled =
+-				    0;
+-				for (j = 0;
+-				     j < bi->rateset.count
+-				     && j < IW_MAX_BITRATES; j++) {
+-					iwe.u.bitrate.value =
+-					    (bi->rateset.rates[j] & 0x7f) *
+-					    500000;
+-					value =
+-					    IWE_STREAM_ADD_VALUE(info, event,
+-						 value, end, &iwe,
+-						 IW_EV_PARAM_LEN);
+-				}
+-				event = value;
+-			}
+-		}
+-	}
+-
+-	ret = event - extra;
+-	if (ret < 0) {
+-		WL_ERROR("==> Wrong size\n");
+-		ret = 0;
+-	}
+-	WL_TRACE("%s: size=%d bytes prepared\n",
+-		 __func__, (unsigned int)(event - extra));
+-	return (uint)ret;
+-}
+-
+-static int
+-wl_iw_get_scan(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	channel_info_t ci;
+-	wl_scan_results_t *list_merge;
+-	wl_scan_results_t *list = (wl_scan_results_t *) g_scan;
+-	int error;
+-	uint buflen_from_user = dwrq->length;
+-	uint len = G_SCAN_RESULTS;
+-	__u16 len_ret = 0;
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_info_t *iscan = g_iscan;
+-	iscan_buf_t *p_buf;
+-#endif
+-
+-	WL_TRACE("%s: buflen_from_user %d:\n", dev->name, buflen_from_user);
+-
+-	if (!extra) {
+-		WL_TRACE("%s: wl_iw_get_scan return -EINVAL\n", dev->name);
+-		return -EINVAL;
+-	}
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci));
+-	if (error)
+-		return error;
+-	ci.scan_channel = le32_to_cpu(ci.scan_channel);
+-	if (ci.scan_channel)
+-		return -EAGAIN;
+-
+-	if (g_scan_specified_ssid) {
+-		list = kmalloc(len, GFP_KERNEL);
+-		if (!list) {
+-			WL_TRACE("%s: wl_iw_get_scan return -ENOMEM\n",
+-				 dev->name);
+-			g_scan_specified_ssid = 0;
+-			return -ENOMEM;
+-		}
+-	}
+-
+-	memset(list, 0, len);
+-	list->buflen = cpu_to_le32(len);
+-	error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len);
+-	if (error) {
+-		WL_ERROR("%s: %s : Scan_results ERROR %d\n",
+-			 dev->name, __func__, error);
+-		dwrq->length = len;
+-		if (g_scan_specified_ssid) {
+-			g_scan_specified_ssid = 0;
+-			kfree(list);
+-		}
+-		return 0;
+-	}
+-	list->buflen = le32_to_cpu(list->buflen);
+-	list->version = le32_to_cpu(list->version);
+-	list->count = le32_to_cpu(list->count);
+-
+-	if (list->version != WL_BSS_INFO_VERSION) {
+-		WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-			 __func__, list->version);
+-		if (g_scan_specified_ssid) {
+-			g_scan_specified_ssid = 0;
+-			kfree(list);
+-		}
+-		return -EINVAL;
+-	}
+-
+-	if (g_scan_specified_ssid) {
+-		WL_TRACE("%s: Specified scan APs in the list =%d\n",
+-			 __func__, list->count);
+-		len_ret =
+-		    (__u16) wl_iw_get_scan_prep(list, info, extra,
+-						buflen_from_user);
+-		kfree(list);
+-
+-#if defined(WL_IW_USE_ISCAN)
+-		p_buf = iscan->list_hdr;
+-		while (p_buf != iscan->list_cur) {
+-			list_merge =
+-			    &((wl_iscan_results_t *) p_buf->iscan_buf)->results;
+-			WL_TRACE("%s: Bcast APs list=%d\n",
+-				 __func__, list_merge->count);
+-			if (list_merge->count > 0)
+-				len_ret +=
+-				    (__u16) wl_iw_get_scan_prep(list_merge,
+-					info, extra + len_ret,
+-					buflen_from_user - len_ret);
+-			p_buf = p_buf->next;
+-		}
+-#else
+-		list_merge = (wl_scan_results_t *) g_scan;
+-		WL_TRACE("%s: Bcast APs list=%d\n",
+-			 __func__, list_merge->count);
+-		if (list_merge->count > 0)
+-			len_ret +=
+-			    (__u16) wl_iw_get_scan_prep(list_merge, info,
+-							extra + len_ret,
+-							buflen_from_user -
+-							len_ret);
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-	} else {
+-		list = (wl_scan_results_t *) g_scan;
+-		len_ret =
+-		    (__u16) wl_iw_get_scan_prep(list, info, extra,
+-						buflen_from_user);
+-	}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-	g_scan_specified_ssid = 0;
+-#endif
+-	if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user)
+-		len = len_ret;
+-
+-	dwrq->length = len;
+-	dwrq->flags = 0;
+-
+-	WL_TRACE("%s return to WE %d bytes APs=%d\n",
+-		 __func__, dwrq->length, list->count);
+-	return 0;
+-}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-static int
+-wl_iw_iscan_get_scan(struct net_device *dev,
+-		     struct iw_request_info *info,
+-		     struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	struct iw_event iwe;
+-	wl_bss_info_t *bi = NULL;
+-	int ii, j;
+-	int apcnt;
+-	char *event = extra, *end = extra + dwrq->length, *value;
+-	iscan_info_t *iscan = g_iscan;
+-	iscan_buf_t *p_buf;
+-	u32 counter = 0;
+-	u8 channel;
+-
+-	WL_TRACE("%s %s buflen_from_user %d:\n",
+-		 dev->name, __func__, dwrq->length);
+-
+-	if (!extra) {
+-		WL_TRACE("%s: INVALID SIOCGIWSCAN GET bad parameter\n",
+-			 dev->name);
+-		return -EINVAL;
+-	}
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk)) {
+-		WL_ERROR("%ssysioc_tsk\n", __func__);
+-		return wl_iw_get_scan(dev, info, dwrq, extra);
+-	}
+-
+-	if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+-		WL_TRACE("%s: SIOCGIWSCAN GET still scanning\n", dev->name);
+-		return -EAGAIN;
+-	}
+-
+-	WL_TRACE("%s: SIOCGIWSCAN GET broadcast results\n", dev->name);
+-	apcnt = 0;
+-	p_buf = iscan->list_hdr;
+-	while (p_buf != iscan->list_cur) {
+-		list = &((wl_iscan_results_t *) p_buf->iscan_buf)->results;
+-
+-		counter += list->count;
+-
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return -EINVAL;
+-		}
+-
+-		bi = NULL;
+-		for (ii = 0; ii < list->count && apcnt < IW_MAX_AP;
+-		     apcnt++, ii++) {
+-			bi = bi ? (wl_bss_info_t *)((unsigned long)bi +
+-						     le32_to_cpu(bi->length)) :
+-			    list->bss_info;
+-			ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-			       ((unsigned long)list + WLC_IW_ISCAN_MAXLEN));
+-
+-			if (event + ETH_ALEN + bi->SSID_len +
+-			    IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >=
+-			    end)
+-				return -E2BIG;
+-			iwe.cmd = SIOCGIWAP;
+-			iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+-			memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID,
+-			       ETH_ALEN);
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_ADDR_LEN);
+-
+-			iwe.u.data.length = le32_to_cpu(bi->SSID_len);
+-			iwe.cmd = SIOCGIWESSID;
+-			iwe.u.data.flags = 1;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 bi->SSID);
+-
+-			if (le16_to_cpu(bi->capability) &
+-			    (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+-				iwe.cmd = SIOCGIWMODE;
+-				if (le16_to_cpu(bi->capability) &
+-				    WLAN_CAPABILITY_ESS)
+-					iwe.u.mode = IW_MODE_INFRA;
+-				else
+-					iwe.u.mode = IW_MODE_ADHOC;
+-				event =
+-				    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-							 IW_EV_UINT_LEN);
+-			}
+-
+-			iwe.cmd = SIOCGIWFREQ;
+-			channel =
+-			    (bi->ctl_ch ==
+-			     0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
+-
+-			if (channel <= CH_MAX_2G_CHANNEL)
+-				iwe.u.freq.m =
+-					ieee80211_dsss_chan_to_freq(channel);
+-			else
+-				iwe.u.freq.m = ieee80211_ofdm_chan_to_freq(
+-							WF_CHAN_FACTOR_5_G/2,
+-							channel);
+-
+-			iwe.u.freq.e = 6;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_FREQ_LEN);
+-
+-			iwe.cmd = IWEVQUAL;
+-			iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-			iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI);
+-			iwe.u.qual.noise = 0x100 + bi->phy_noise;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_QUAL_LEN);
+-
+-			wl_iw_handle_scanresults_ies(&event, end, info, bi);
+-
+-			iwe.cmd = SIOCGIWENCODE;
+-			if (le16_to_cpu(bi->capability) &
+-			    WLAN_CAPABILITY_PRIVACY)
+-				iwe.u.data.flags =
+-				    IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+-			else
+-				iwe.u.data.flags = IW_ENCODE_DISABLED;
+-			iwe.u.data.length = 0;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 (char *)event);
+-
+-			if (bi->rateset.count) {
+-				if (event + IW_MAX_BITRATES * IW_EV_PARAM_LEN >=
+-				    end)
+-					return -E2BIG;
+-
+-				value = event + IW_EV_LCP_LEN;
+-				iwe.cmd = SIOCGIWRATE;
+-				iwe.u.bitrate.fixed = iwe.u.bitrate.disabled =
+-				    0;
+-				for (j = 0;
+-				     j < bi->rateset.count
+-				     && j < IW_MAX_BITRATES; j++) {
+-					iwe.u.bitrate.value =
+-					    (bi->rateset.rates[j] & 0x7f) *
+-					    500000;
+-					value =
+-					    IWE_STREAM_ADD_VALUE(info, event,
+-						 value, end,
+-						 &iwe,
+-						 IW_EV_PARAM_LEN);
+-				}
+-				event = value;
+-			}
+-		}
+-		p_buf = p_buf->next;
+-	}
+-
+-	dwrq->length = event - extra;
+-	dwrq->flags = 0;
+-
+-	WL_TRACE("%s return to WE %d bytes APs=%d\n",
+-		 __func__, dwrq->length, counter);
+-
+-	if (!dwrq->length)
+-		return -EAGAIN;
+-
+-	return 0;
+-}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-static int
+-wl_iw_set_essid(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	int error;
+-	wl_join_params_t join_params;
+-	int join_params_size;
+-
+-	WL_TRACE("%s: SIOCSIWESSID\n", dev->name);
+-
+-	if (g_set_essid_before_scan)
+-		return -EAGAIN;
+-
+-	memset(&g_ssid, 0, sizeof(g_ssid));
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	if (dwrq->length && extra) {
+-#if WIRELESS_EXT > 20
+-		g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID),
+-					dwrq->length);
+-#else
+-		g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID),
+-					dwrq->length - 1);
+-#endif
+-		memcpy(g_ssid.SSID, extra, g_ssid.SSID_len);
+-	} else {
+-		g_ssid.SSID_len = 0;
+-	}
+-	g_ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-	memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-
+-	wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params,
+-			     &join_params_size);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params,
+-				join_params_size);
+-	if (error)
+-		WL_ERROR("Invalid ioctl data=%d\n", error);
+-
+-	if (g_ssid.SSID_len) {
+-		WL_TRACE("%s: join SSID=%s ch=%d\n",
+-			 __func__, g_ssid.SSID, g_wl_iw_params.target_channel);
+-	}
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_essid(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	int error;
+-
+-	WL_TRACE("%s: SIOCGIWESSID\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
+-	if (error) {
+-		WL_ERROR("Error getting the SSID\n");
+-		return error;
+-	}
+-
+-	ssid.SSID_len = le32_to_cpu(ssid.SSID_len);
+-
+-	memcpy(extra, ssid.SSID, ssid.SSID_len);
+-
+-	dwrq->length = ssid.SSID_len;
+-
+-	dwrq->flags = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_nick(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCSIWNICKN\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	if (dwrq->length > sizeof(iw->nickname))
+-		return -E2BIG;
+-
+-	memcpy(iw->nickname, extra, dwrq->length);
+-	iw->nickname[dwrq->length - 1] = '\0';
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_nick(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCGIWNICKN\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	strcpy(extra, iw->nickname);
+-	dwrq->length = strlen(extra) + 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_rate(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	wl_rateset_t rateset;
+-	int error, rate, i, error_bg, error_a;
+-
+-	WL_TRACE("%s: SIOCSIWRATE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-				sizeof(rateset));
+-	if (error)
+-		return error;
+-
+-	rateset.count = le32_to_cpu(rateset.count);
+-
+-	if (vwrq->value < 0)
+-		rate = rateset.rates[rateset.count - 1] & 0x7f;
+-	else if (vwrq->value < rateset.count)
+-		rate = rateset.rates[vwrq->value] & 0x7f;
+-	else
+-		rate = vwrq->value / 500000;
+-
+-	if (vwrq->fixed) {
+-		error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate);
+-		error_a = dev_wlc_intvar_set(dev, "a_rate", rate);
+-
+-		if (error_bg && error_a)
+-			return error_bg | error_a;
+-	} else {
+-		error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0);
+-		error_a = dev_wlc_intvar_set(dev, "a_rate", 0);
+-
+-		if (error_bg && error_a)
+-			return error_bg | error_a;
+-
+-		for (i = 0; i < rateset.count; i++)
+-			if ((rateset.rates[i] & 0x7f) > rate)
+-				break;
+-		rateset.count = cpu_to_le32(i);
+-
+-		error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset,
+-					sizeof(rateset));
+-		if (error)
+-			return error;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_rate(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rate;
+-
+-	WL_TRACE("%s: SIOCGIWRATE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+-	if (error)
+-		return error;
+-	rate = le32_to_cpu(rate);
+-	vwrq->value = rate * 500000;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_rts(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rts;
+-
+-	WL_TRACE("%s: SIOCSIWRTS\n", dev->name);
+-
+-	if (vwrq->disabled)
+-		rts = DOT11_DEFAULT_RTS_LEN;
+-	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN)
+-		return -EINVAL;
+-	else
+-		rts = vwrq->value;
+-
+-	error = dev_wlc_intvar_set(dev, "rtsthresh", rts);
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_rts(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rts;
+-
+-	WL_TRACE("%s: SIOCGIWRTS\n", dev->name);
+-
+-	error = dev_wlc_intvar_get(dev, "rtsthresh", &rts);
+-	if (error)
+-		return error;
+-
+-	vwrq->value = rts;
+-	vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN);
+-	vwrq->fixed = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_frag(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, frag;
+-
+-	WL_TRACE("%s: SIOCSIWFRAG\n", dev->name);
+-
+-	if (vwrq->disabled)
+-		frag = DOT11_DEFAULT_FRAG_LEN;
+-	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN)
+-		return -EINVAL;
+-	else
+-		frag = vwrq->value;
+-
+-	error = dev_wlc_intvar_set(dev, "fragthresh", frag);
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_frag(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, fragthreshold;
+-
+-	WL_TRACE("%s: SIOCGIWFRAG\n", dev->name);
+-
+-	error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold);
+-	if (error)
+-		return error;
+-
+-	vwrq->value = fragthreshold;
+-	vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN);
+-	vwrq->fixed = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_txpow(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, disable;
+-	u16 txpwrmw;
+-	WL_TRACE("%s: SIOCSIWTXPOW\n", dev->name);
+-
+-	disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0;
+-	disable += WL_RADIO_SW_DISABLE << 16;
+-
+-	disable = cpu_to_le32(disable);
+-	error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable));
+-	if (error)
+-		return error;
+-
+-	if (disable & WL_RADIO_SW_DISABLE)
+-		return 0;
+-
+-	if (!(vwrq->flags & IW_TXPOW_MWATT))
+-		return -EINVAL;
+-
+-	if (vwrq->value < 0)
+-		return 0;
+-
+-	if (vwrq->value > 0xffff)
+-		txpwrmw = 0xffff;
+-	else
+-		txpwrmw = (u16) vwrq->value;
+-
+-	error =
+-	    dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw)));
+-	return error;
+-}
+-
+-static int
+-wl_iw_get_txpow(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, disable, txpwrdbm;
+-	u8 result;
+-
+-	WL_TRACE("%s: SIOCGIWTXPOW\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm);
+-	if (error)
+-		return error;
+-
+-	disable = le32_to_cpu(disable);
+-	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+-	vwrq->value = (s32) bcm_qdbm_to_mw(result);
+-	vwrq->fixed = 0;
+-	vwrq->disabled =
+-	    (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0;
+-	vwrq->flags = IW_TXPOW_MWATT;
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 10
+-static int
+-wl_iw_set_retry(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, lrl, srl;
+-
+-	WL_TRACE("%s: SIOCSIWRETRY\n", dev->name);
+-
+-	if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME))
+-		return -EINVAL;
+-
+-	if (vwrq->flags & IW_RETRY_LIMIT) {
+-
+-#if WIRELESS_EXT > 20
+-		if ((vwrq->flags & IW_RETRY_LONG)
+-		    || (vwrq->flags & IW_RETRY_MAX)
+-		    || !((vwrq->flags & IW_RETRY_SHORT)
+-			 || (vwrq->flags & IW_RETRY_MIN))) {
+-#else
+-		if ((vwrq->flags & IW_RETRY_MAX)
+-		    || !(vwrq->flags & IW_RETRY_MIN)) {
+-#endif
+-			lrl = cpu_to_le32(vwrq->value);
+-			error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl,
+-						sizeof(lrl));
+-			if (error)
+-				return error;
+-		}
+-#if WIRELESS_EXT > 20
+-		if ((vwrq->flags & IW_RETRY_SHORT)
+-		    || (vwrq->flags & IW_RETRY_MIN)
+-		    || !((vwrq->flags & IW_RETRY_LONG)
+-			 || (vwrq->flags & IW_RETRY_MAX))) {
+-#else
+-		if ((vwrq->flags & IW_RETRY_MIN)
+-		    || !(vwrq->flags & IW_RETRY_MAX)) {
+-#endif
+-			srl = cpu_to_le32(vwrq->value);
+-			error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl,
+-						sizeof(srl));
+-			if (error)
+-				return error;
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_retry(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, lrl, srl;
+-
+-	WL_TRACE("%s: SIOCGIWRETRY\n", dev->name);
+-
+-	vwrq->disabled = 0;
+-
+-	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
+-		return -EINVAL;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl));
+-	if (error)
+-		return error;
+-
+-	lrl = le32_to_cpu(lrl);
+-	srl = le32_to_cpu(srl);
+-
+-	if (vwrq->flags & IW_RETRY_MAX) {
+-		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+-		vwrq->value = lrl;
+-	} else {
+-		vwrq->flags = IW_RETRY_LIMIT;
+-		vwrq->value = srl;
+-		if (srl != lrl)
+-			vwrq->flags |= IW_RETRY_MIN;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* WIRELESS_EXT > 10 */
+-
+-static int
+-wl_iw_set_encode(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error, val, wsec;
+-
+-	WL_TRACE("%s: SIOCSIWENCODE\n", dev->name);
+-
+-	memset(&key, 0, sizeof(key));
+-
+-	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+-		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS;
+-		     key.index++) {
+-			val = cpu_to_le32(key.index);
+-			error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val,
+-						sizeof(val));
+-			if (error)
+-				return error;
+-			val = le32_to_cpu(val);
+-			if (val)
+-				break;
+-		}
+-		if (key.index == DOT11_MAX_DEFAULT_KEYS)
+-			key.index = 0;
+-	} else {
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-		if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-			return -EINVAL;
+-	}
+-
+-	if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) {
+-		val = cpu_to_le32(key.index);
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val,
+-					sizeof(val));
+-		if (error)
+-			return error;
+-	} else {
+-		key.len = dwrq->length;
+-
+-		if (dwrq->length > sizeof(key.data))
+-			return -EINVAL;
+-
+-		memcpy(key.data, extra, dwrq->length);
+-
+-		key.flags = WL_PRIMARY_KEY;
+-		switch (key.len) {
+-		case WLAN_KEY_LEN_WEP40:
+-			key.algo = CRYPTO_ALGO_WEP1;
+-			break;
+-		case WLAN_KEY_LEN_WEP104:
+-			key.algo = CRYPTO_ALGO_WEP128;
+-			break;
+-		case WLAN_KEY_LEN_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			break;
+-		case WLAN_KEY_LEN_AES_CMAC:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			break;
+-		default:
+-			return -EINVAL;
+-		}
+-
+-		swap_key_from_BE(&key);
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (error)
+-			return error;
+-	}
+-
+-	val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED;
+-
+-	error = dev_wlc_intvar_get(dev, "wsec", &wsec);
+-	if (error)
+-		return error;
+-
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-
+-	error = dev_wlc_intvar_set(dev, "wsec", wsec);
+-	if (error)
+-		return error;
+-
+-	val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0;
+-	val = cpu_to_le32(val);
+-	error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_encode(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error, val, wsec, auth;
+-
+-	WL_TRACE("%s: SIOCGIWENCODE\n", dev->name);
+-
+-	memset(&key, 0, sizeof(wl_wsec_key_t));
+-
+-	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+-		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS;
+-		     key.index++) {
+-			val = key.index;
+-			error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val,
+-						sizeof(val));
+-			if (error)
+-				return error;
+-			val = le32_to_cpu(val);
+-			if (val)
+-				break;
+-		}
+-	} else
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-
+-	if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-		key.index = 0;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth));
+-	if (error)
+-		return error;
+-
+-	swap_key_to_BE(&key);
+-
+-	wsec = le32_to_cpu(wsec);
+-	auth = le32_to_cpu(auth);
+-	dwrq->length = min_t(u16, WLAN_MAX_KEY_LEN, key.len);
+-
+-	dwrq->flags = key.index + 1;
+-	if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)))
+-		dwrq->flags |= IW_ENCODE_DISABLED;
+-
+-	if (auth)
+-		dwrq->flags |= IW_ENCODE_RESTRICTED;
+-
+-	if (dwrq->length && extra)
+-		memcpy(extra, key.data, dwrq->length);
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_power(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, pm;
+-
+-	WL_TRACE("%s: SIOCSIWPOWER\n", dev->name);
+-
+-	pm = vwrq->disabled ? PM_OFF : PM_MAX;
+-
+-	pm = cpu_to_le32(pm);
+-	error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_power(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, pm;
+-
+-	WL_TRACE("%s: SIOCGIWPOWER\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
+-	if (error)
+-		return error;
+-
+-	pm = le32_to_cpu(pm);
+-	vwrq->disabled = pm ? 0 : 1;
+-	vwrq->flags = IW_POWER_ALL_R;
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-static int
+-wl_iw_set_wpaie(struct net_device *dev,
+-		struct iw_request_info *info, struct iw_point *iwp, char *extra)
+-{
+-
+-	WL_TRACE("%s: SIOCSIWGENIE\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length);
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_wpaie(struct net_device *dev,
+-		struct iw_request_info *info, struct iw_point *iwp, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWGENIE\n", dev->name);
+-	iwp->length = 64;
+-	dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_encodeext(struct net_device *dev,
+-		    struct iw_request_info *info,
+-		    struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error;
+-	struct iw_encode_ext *iwe;
+-
+-	WL_TRACE("%s: SIOCSIWENCODEEXT\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	memset(&key, 0, sizeof(key));
+-	iwe = (struct iw_encode_ext *)extra;
+-
+-	if (dwrq->flags & IW_ENCODE_DISABLED) {
+-
+-	}
+-
+-	key.index = 0;
+-	if (dwrq->flags & IW_ENCODE_INDEX)
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-
+-	key.len = iwe->key_len;
+-
+-	if (!is_multicast_ether_addr(iwe->addr.sa_data))
+-		memcpy(&key.ea, &iwe->addr.sa_data, ETH_ALEN);
+-
+-	if (key.len == 0) {
+-		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+-			WL_WSEC("Changing the the primary Key to %d\n",
+-				key.index);
+-			key.index = cpu_to_le32(key.index);
+-			error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY,
+-					      &key.index, sizeof(key.index));
+-			if (error)
+-				return error;
+-		} else {
+-			swap_key_from_BE(&key);
+-			dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		}
+-	} else {
+-		if (iwe->key_len > sizeof(key.data))
+-			return -EINVAL;
+-
+-		WL_WSEC("Setting the key index %d\n", key.index);
+-		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+-			WL_WSEC("key is a Primary Key\n");
+-			key.flags = WL_PRIMARY_KEY;
+-		}
+-
+-		memcpy(key.data, iwe->key, iwe->key_len);
+-
+-		if (iwe->alg == IW_ENCODE_ALG_TKIP) {
+-			u8 keybuf[8];
+-			memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-			memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		}
+-
+-		if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+-			unsigned char *ivptr;
+-			ivptr = (unsigned char *) iwe->rx_seq;
+-			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+-			    (ivptr[3] << 8) | ivptr[2];
+-			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+-			key.iv_initialized = true;
+-		}
+-
+-		switch (iwe->alg) {
+-		case IW_ENCODE_ALG_NONE:
+-			key.algo = CRYPTO_ALGO_OFF;
+-			break;
+-		case IW_ENCODE_ALG_WEP:
+-			if (iwe->key_len == WLAN_KEY_LEN_WEP40)
+-				key.algo = CRYPTO_ALGO_WEP1;
+-			else
+-				key.algo = CRYPTO_ALGO_WEP128;
+-			break;
+-		case IW_ENCODE_ALG_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			break;
+-		case IW_ENCODE_ALG_CCMP:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			break;
+-		default:
+-			break;
+-		}
+-		swap_key_from_BE(&key);
+-
+-		dhd_wait_pend8021x(dev);
+-
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (error)
+-			return error;
+-	}
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-struct {
+-	pmkid_list_t pmkids;
+-	pmkid_t foo[MAXPMKID - 1];
+-} pmkid_list;
+-
+-static int
+-wl_iw_set_pmksa(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	struct iw_pmksa *iwpmksa;
+-	uint i;
+-	int ret = 0;
+-
+-	WL_WSEC("%s: SIOCSIWPMKSA\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	iwpmksa = (struct iw_pmksa *)extra;
+-
+-	if (iwpmksa->cmd == IW_PMKSA_FLUSH) {
+-		WL_WSEC("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n");
+-		memset((char *)&pmkid_list, 0, sizeof(pmkid_list));
+-	}
+-
+-	else if (iwpmksa->cmd == IW_PMKSA_REMOVE) {
+-		{
+-			pmkid_list_t pmkid, *pmkidptr;
+-			uint j;
+-			pmkidptr = &pmkid;
+-
+-			memcpy(&pmkidptr->pmkid[0].BSSID,
+-			       &iwpmksa->bssid.sa_data[0],
+-			       ETH_ALEN);
+-			memcpy(&pmkidptr->pmkid[0].PMKID,
+-			       &iwpmksa->pmkid[0],
+-			       WLAN_PMKID_LEN);
+-
+-			WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: "
+-				"%pM = ", &pmkidptr->pmkid[0].BSSID);
+-			for (j = 0; j < WLAN_PMKID_LEN; j++)
+-				WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]);
+-			WL_WSEC("\n");
+-		}
+-
+-		for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+-			if (!memcmp
+-			    (&iwpmksa->bssid.sa_data[0],
+-			     &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN))
+-				break;
+-
+-		if ((pmkid_list.pmkids.npmkid > 0)
+-		    && (i < pmkid_list.pmkids.npmkid)) {
+-			memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t));
+-			for (; i < (pmkid_list.pmkids.npmkid - 1); i++) {
+-				memcpy(&pmkid_list.pmkids.pmkid[i].BSSID,
+-				       &pmkid_list.pmkids.pmkid[i + 1].BSSID,
+-				       ETH_ALEN);
+-				memcpy(&pmkid_list.pmkids.pmkid[i].PMKID,
+-				       &pmkid_list.pmkids.pmkid[i + 1].PMKID,
+-				       WLAN_PMKID_LEN);
+-			}
+-			pmkid_list.pmkids.npmkid--;
+-		} else
+-			ret = -EINVAL;
+-	}
+-
+-	else if (iwpmksa->cmd == IW_PMKSA_ADD) {
+-		for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+-			if (!memcmp
+-			    (&iwpmksa->bssid.sa_data[0],
+-			     &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN))
+-				break;
+-		if (i < MAXPMKID) {
+-			memcpy(&pmkid_list.pmkids.pmkid[i].BSSID,
+-			       &iwpmksa->bssid.sa_data[0],
+-			       ETH_ALEN);
+-			memcpy(&pmkid_list.pmkids.pmkid[i].PMKID,
+-			       &iwpmksa->pmkid[0],
+-			       WLAN_PMKID_LEN);
+-			if (i == pmkid_list.pmkids.npmkid)
+-				pmkid_list.pmkids.npmkid++;
+-		} else
+-			ret = -EINVAL;
+-		{
+-			uint j;
+-			uint k;
+-			k = pmkid_list.pmkids.npmkid;
+-			WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ",
+-				&pmkid_list.pmkids.pmkid[k].BSSID);
+-			for (j = 0; j < WLAN_PMKID_LEN; j++)
+-				WL_WSEC("%02x ",
+-					pmkid_list.pmkids.pmkid[k].PMKID[j]);
+-			WL_WSEC("\n");
+-		}
+-	}
+-	WL_WSEC("PRINTING pmkid LIST - No of elements %d\n",
+-		pmkid_list.pmkids.npmkid);
+-	for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
+-		uint j;
+-		WL_WSEC("PMKID[%d]: %pM = ",
+-			i, &pmkid_list.pmkids.pmkid[i].BSSID);
+-		for (j = 0; j < WLAN_PMKID_LEN; j++)
+-			WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]);
+-		WL_WSEC("\n");
+-	}
+-	WL_WSEC("\n");
+-
+-	if (!ret)
+-		ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list,
+-					 sizeof(pmkid_list));
+-	return ret;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-wl_iw_get_encodeext(struct net_device *dev,
+-		    struct iw_request_info *info,
+-		    struct iw_param *vwrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWENCODEEXT\n", dev->name);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_wpaauth(struct net_device *dev,
+-		  struct iw_request_info *info,
+-		  struct iw_param *vwrq, char *extra)
+-{
+-	int error = 0;
+-	int paramid;
+-	int paramval;
+-	int val = 0;
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCSIWAUTH\n", dev->name);
+-
+-	paramid = vwrq->flags & IW_AUTH_INDEX;
+-	paramval = vwrq->value;
+-
+-	WL_TRACE("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
+-		 dev->name, paramid, paramval);
+-
+-	switch (paramid) {
+-	case IW_AUTH_WPA_VERSION:
+-		if (paramval & IW_AUTH_WPA_VERSION_DISABLED)
+-			val = WPA_AUTH_DISABLED;
+-		else if (paramval & (IW_AUTH_WPA_VERSION_WPA))
+-			val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+-		else if (paramval & IW_AUTH_WPA_VERSION_WPA2)
+-			val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+-		WL_INFORM("%s: %d: setting wpa_auth to 0x%0x\n",
+-			  __func__, __LINE__, val);
+-		error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+-		if (error)
+-			return error;
+-		break;
+-	case IW_AUTH_CIPHER_PAIRWISE:
+-	case IW_AUTH_CIPHER_GROUP:
+-		if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+-			val = WEP_ENABLED;
+-		if (paramval & IW_AUTH_CIPHER_TKIP)
+-			val = TKIP_ENABLED;
+-		if (paramval & IW_AUTH_CIPHER_CCMP)
+-			val = AES_ENABLED;
+-
+-		if (paramid == IW_AUTH_CIPHER_PAIRWISE) {
+-			iw->pwsec = val;
+-			val |= iw->gwsec;
+-		} else {
+-			iw->gwsec = val;
+-			val |= iw->pwsec;
+-		}
+-
+-		if (iw->privacy_invoked && !val) {
+-			WL_WSEC("%s: %s: 'Privacy invoked' true but clearing wsec, assuming we're a WPS enrollee\n",
+-				dev->name, __func__);
+-			error = dev_wlc_intvar_set(dev, "is_WPS_enrollee",
+-							true);
+-			if (error) {
+-				WL_WSEC("Failed to set is_WPS_enrollee\n");
+-				return error;
+-			}
+-		} else if (val) {
+-			error = dev_wlc_intvar_set(dev, "is_WPS_enrollee",
+-							false);
+-			if (error) {
+-				WL_WSEC("Failed to clear is_WPS_enrollee\n");
+-				return error;
+-			}
+-		}
+-
+-		error = dev_wlc_intvar_set(dev, "wsec", val);
+-		if (error)
+-			return error;
+-
+-		break;
+-
+-	case IW_AUTH_KEY_MGMT:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-
+-		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+-			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+-				val = WPA_AUTH_PSK;
+-			else
+-				val = WPA_AUTH_UNSPECIFIED;
+-		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+-			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+-				val = WPA2_AUTH_PSK;
+-			else
+-				val = WPA2_AUTH_UNSPECIFIED;
+-		}
+-		WL_INFORM("%s: %d: setting wpa_auth to %d\n",
+-			  __func__, __LINE__, val);
+-		error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+-		if (error)
+-			return error;
+-
+-		break;
+-	case IW_AUTH_TKIP_COUNTERMEASURES:
+-		dev_wlc_bufvar_set(dev, "tkip_countermeasures",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_80211_AUTH_ALG:
+-		WL_INFORM("Setting the D11auth %d\n", paramval);
+-		if (paramval == IW_AUTH_ALG_OPEN_SYSTEM)
+-			val = 0;
+-		else if (paramval == IW_AUTH_ALG_SHARED_KEY)
+-			val = 1;
+-		else if (paramval ==
+-			 (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY))
+-			val = 2;
+-		else
+-			error = 1;
+-		if (!error) {
+-			error = dev_wlc_intvar_set(dev, "auth", val);
+-			if (error)
+-				return error;
+-		}
+-		break;
+-
+-	case IW_AUTH_WPA_ENABLED:
+-		if (paramval == 0) {
+-			iw->pwsec = 0;
+-			iw->gwsec = 0;
+-			error = dev_wlc_intvar_get(dev, "wsec", &val);
+-			if (error)
+-				return error;
+-			if (val & (TKIP_ENABLED | AES_ENABLED)) {
+-				val &= ~(TKIP_ENABLED | AES_ENABLED);
+-				dev_wlc_intvar_set(dev, "wsec", val);
+-			}
+-			val = 0;
+-			WL_INFORM("%s: %d: setting wpa_auth to %d\n",
+-				  __func__, __LINE__, val);
+-			dev_wlc_intvar_set(dev, "wpa_auth", 0);
+-			return error;
+-		}
+-		break;
+-
+-	case IW_AUTH_DROP_UNENCRYPTED:
+-		dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+-		dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-#if WIRELESS_EXT > 17
+-	case IW_AUTH_ROAMING_CONTROL:
+-		WL_INFORM("%s: IW_AUTH_ROAMING_CONTROL\n", __func__);
+-		break;
+-	case IW_AUTH_PRIVACY_INVOKED:
+-		{
+-			int wsec;
+-
+-			if (paramval == 0) {
+-				iw->privacy_invoked = false;
+-				error = dev_wlc_intvar_set(dev,
+-						"is_WPS_enrollee", false);
+-				if (error) {
+-					WL_WSEC("Failed to clear iovar is_WPS_enrollee\n");
+-					return error;
+-				}
+-			} else {
+-				iw->privacy_invoked = true;
+-				error = dev_wlc_intvar_get(dev, "wsec", &wsec);
+-				if (error)
+-					return error;
+-
+-				if (!(IW_WSEC_ENABLED(wsec))) {
+-					error = dev_wlc_intvar_set(dev,
+-							"is_WPS_enrollee",
+-							true);
+-					if (error) {
+-						WL_WSEC("Failed to set iovar is_WPS_enrollee\n");
+-						return error;
+-					}
+-				} else {
+-					error = dev_wlc_intvar_set(dev,
+-							"is_WPS_enrollee",
+-							false);
+-					if (error) {
+-						WL_WSEC("Failed to clear is_WPS_enrollee\n");
+-						return error;
+-					}
+-				}
+-			}
+-			break;
+-		}
+-#endif				/* WIRELESS_EXT > 17 */
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK))
+-
+-static int
+-wl_iw_get_wpaauth(struct net_device *dev,
+-		  struct iw_request_info *info,
+-		  struct iw_param *vwrq, char *extra)
+-{
+-	int error;
+-	int paramid;
+-	int paramval = 0;
+-	int val;
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCGIWAUTH\n", dev->name);
+-
+-	paramid = vwrq->flags & IW_AUTH_INDEX;
+-
+-	switch (paramid) {
+-	case IW_AUTH_WPA_VERSION:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED))
+-			paramval = IW_AUTH_WPA_VERSION_DISABLED;
+-		else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED))
+-			paramval = IW_AUTH_WPA_VERSION_WPA;
+-		else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED))
+-			paramval = IW_AUTH_WPA_VERSION_WPA2;
+-		break;
+-	case IW_AUTH_CIPHER_PAIRWISE:
+-	case IW_AUTH_CIPHER_GROUP:
+-		if (paramid == IW_AUTH_CIPHER_PAIRWISE)
+-			val = iw->pwsec;
+-		else
+-			val = iw->gwsec;
+-
+-		paramval = 0;
+-		if (val) {
+-			if (val & WEP_ENABLED)
+-				paramval |=
+-				    (IW_AUTH_CIPHER_WEP40 |
+-				     IW_AUTH_CIPHER_WEP104);
+-			if (val & TKIP_ENABLED)
+-				paramval |= (IW_AUTH_CIPHER_TKIP);
+-			if (val & AES_ENABLED)
+-				paramval |= (IW_AUTH_CIPHER_CCMP);
+-		} else
+-			paramval = IW_AUTH_CIPHER_NONE;
+-		break;
+-	case IW_AUTH_KEY_MGMT:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (VAL_PSK(val))
+-			paramval = IW_AUTH_KEY_MGMT_PSK;
+-		else
+-			paramval = IW_AUTH_KEY_MGMT_802_1X;
+-
+-		break;
+-	case IW_AUTH_TKIP_COUNTERMEASURES:
+-		dev_wlc_bufvar_get(dev, "tkip_countermeasures",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_DROP_UNENCRYPTED:
+-		dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+-		dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_80211_AUTH_ALG:
+-		error = dev_wlc_intvar_get(dev, "auth", &val);
+-		if (error)
+-			return error;
+-		if (!val)
+-			paramval = IW_AUTH_ALG_OPEN_SYSTEM;
+-		else
+-			paramval = IW_AUTH_ALG_SHARED_KEY;
+-		break;
+-	case IW_AUTH_WPA_ENABLED:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (val)
+-			paramval = true;
+-		else
+-			paramval = false;
+-		break;
+-#if WIRELESS_EXT > 17
+-	case IW_AUTH_ROAMING_CONTROL:
+-		WL_ERROR("%s: IW_AUTH_ROAMING_CONTROL\n", __func__);
+-		break;
+-	case IW_AUTH_PRIVACY_INVOKED:
+-		paramval = iw->privacy_invoked;
+-		break;
+-
+-#endif
+-	}
+-	vwrq->value = paramval;
+-	return 0;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static const iw_handler wl_iw_handler[] = {
+-	(iw_handler) wl_iw_config_commit,
+-	(iw_handler) wl_iw_get_name,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_freq,
+-	(iw_handler) wl_iw_get_freq,
+-	(iw_handler) wl_iw_set_mode,
+-	(iw_handler) wl_iw_get_mode,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_get_range,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_spy,
+-	(iw_handler) wl_iw_get_spy,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_wap,
+-	(iw_handler) wl_iw_get_wap,
+-#if WIRELESS_EXT > 17
+-	(iw_handler) wl_iw_mlme,
+-#else
+-	(iw_handler) NULL,
+-#endif
+-#if defined(WL_IW_USE_ISCAN)
+-	(iw_handler) wl_iw_iscan_get_aplist,
+-#else
+-	(iw_handler) wl_iw_get_aplist,
+-#endif
+-#if WIRELESS_EXT > 13
+-#if defined(WL_IW_USE_ISCAN)
+-	(iw_handler) wl_iw_iscan_set_scan,
+-	(iw_handler) wl_iw_iscan_get_scan,
+-#else
+-	(iw_handler) wl_iw_set_scan,
+-	(iw_handler) wl_iw_get_scan,
+-#endif
+-#else
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-#endif				/* WIRELESS_EXT > 13 */
+-	(iw_handler) wl_iw_set_essid,
+-	(iw_handler) wl_iw_get_essid,
+-	(iw_handler) wl_iw_set_nick,
+-	(iw_handler) wl_iw_get_nick,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_rate,
+-	(iw_handler) wl_iw_get_rate,
+-	(iw_handler) wl_iw_set_rts,
+-	(iw_handler) wl_iw_get_rts,
+-	(iw_handler) wl_iw_set_frag,
+-	(iw_handler) wl_iw_get_frag,
+-	(iw_handler) wl_iw_set_txpow,
+-	(iw_handler) wl_iw_get_txpow,
+-#if WIRELESS_EXT > 10
+-	(iw_handler) wl_iw_set_retry,
+-	(iw_handler) wl_iw_get_retry,
+-#endif
+-	(iw_handler) wl_iw_set_encode,
+-	(iw_handler) wl_iw_get_encode,
+-	(iw_handler) wl_iw_set_power,
+-	(iw_handler) wl_iw_get_power,
+-#if WIRELESS_EXT > 17
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_wpaie,
+-	(iw_handler) wl_iw_get_wpaie,
+-	(iw_handler) wl_iw_set_wpaauth,
+-	(iw_handler) wl_iw_get_wpaauth,
+-	(iw_handler) wl_iw_set_encodeext,
+-	(iw_handler) wl_iw_get_encodeext,
+-	(iw_handler) wl_iw_set_pmksa,
+-#endif				/* WIRELESS_EXT > 17 */
+-};
+-
+-#if WIRELESS_EXT > 12
+-
+-const struct iw_handler_def wl_iw_handler_def = {
+-	.num_standard = ARRAY_SIZE(wl_iw_handler),
+-	.standard = (iw_handler *) wl_iw_handler,
+-	.num_private = 0,
+-	.num_private_args = 0,
+-	.private = 0,
+-	.private_args = 0,
+-
+-#if WIRELESS_EXT >= 19
+-	.get_wireless_stats = NULL,
+-#endif
+-};
+-#endif				/* WIRELESS_EXT > 12 */
+-
+-int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+-{
+-	struct iwreq *wrq = (struct iwreq *)rq;
+-	struct iw_request_info info;
+-	iw_handler handler;
+-	char *extra = NULL;
+-	int token_size = 1, max_tokens = 0, ret = 0;
+-
+-	WL_TRACE("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n",
+-		 __func__, cmd);
+-	if (cmd < SIOCIWFIRST ||
+-		IW_IOCTL_IDX(cmd) >= ARRAY_SIZE(wl_iw_handler)) {
+-		WL_ERROR("%s: error in cmd=%x : out of range\n",
+-			 __func__, cmd);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	handler = wl_iw_handler[IW_IOCTL_IDX(cmd)];
+-	if (!handler) {
+-		WL_ERROR("%s: error in cmd=%x : not supported\n",
+-			 __func__, cmd);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	switch (cmd) {
+-
+-	case SIOCSIWESSID:
+-	case SIOCGIWESSID:
+-	case SIOCSIWNICKN:
+-	case SIOCGIWNICKN:
+-		max_tokens = IW_ESSID_MAX_SIZE + 1;
+-		break;
+-
+-	case SIOCSIWENCODE:
+-	case SIOCGIWENCODE:
+-#if WIRELESS_EXT > 17
+-	case SIOCSIWENCODEEXT:
+-	case SIOCGIWENCODEEXT:
+-#endif
+-		max_tokens = wrq->u.data.length;
+-		break;
+-
+-	case SIOCGIWRANGE:
+-		max_tokens = sizeof(struct iw_range) + 500;
+-		break;
+-
+-	case SIOCGIWAPLIST:
+-		token_size =
+-		    sizeof(struct sockaddr) + sizeof(struct iw_quality);
+-		max_tokens = IW_MAX_AP;
+-		break;
+-
+-#if WIRELESS_EXT > 13
+-	case SIOCGIWSCAN:
+-#if defined(WL_IW_USE_ISCAN)
+-		if (g_iscan)
+-			max_tokens = wrq->u.data.length;
+-		else
+-#endif
+-			max_tokens = IW_SCAN_MAX_DATA;
+-		break;
+-#endif				/* WIRELESS_EXT > 13 */
+-
+-	case SIOCSIWSPY:
+-		token_size = sizeof(struct sockaddr);
+-		max_tokens = IW_MAX_SPY;
+-		break;
+-
+-	case SIOCGIWSPY:
+-		token_size =
+-		    sizeof(struct sockaddr) + sizeof(struct iw_quality);
+-		max_tokens = IW_MAX_SPY;
+-		break;
+-
+-#if WIRELESS_EXT > 17
+-	case SIOCSIWPMKSA:
+-	case SIOCSIWGENIE:
+-#endif
+-	case SIOCSIWPRIV:
+-		max_tokens = wrq->u.data.length;
+-		break;
+-	}
+-
+-	if (max_tokens && wrq->u.data.pointer) {
+-		if (wrq->u.data.length > max_tokens) {
+-			WL_ERROR("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n",
+-				 __func__, cmd, wrq->u.data.length, max_tokens);
+-			return -E2BIG;
+-		}
+-		extra = kmalloc(max_tokens * token_size, GFP_KERNEL);
+-		if (!extra)
+-			return -ENOMEM;
+-
+-		if (copy_from_user
+-		    (extra, wrq->u.data.pointer,
+-		     wrq->u.data.length * token_size)) {
+-			kfree(extra);
+-			return -EFAULT;
+-		}
+-	}
+-
+-	info.cmd = cmd;
+-	info.flags = 0;
+-
+-	ret = handler(dev, &info, &wrq->u, extra);
+-
+-	if (extra) {
+-		if (copy_to_user
+-		    (wrq->u.data.pointer, extra,
+-		     wrq->u.data.length * token_size)) {
+-			kfree(extra);
+-			return -EFAULT;
+-		}
+-
+-		kfree(extra);
+-	}
+-
+-	return ret;
+-}
+-
+-bool
+-wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason,
+-		      char *stringBuf, uint buflen)
+-{
+-	typedef struct conn_fail_event_map_t {
+-		u32 inEvent;
+-		u32 inStatus;
+-		u32 inReason;
+-		const char *outName;
+-		const char *outCause;
+-	} conn_fail_event_map_t;
+-
+-#define WL_IW_DONT_CARE	9999
+-	const conn_fail_event_map_t event_map[] = {
+-		{WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE,
+-		 "Conn", "Success"},
+-		{WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE,
+-		 "Conn", "NoNetworks"},
+-		{WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "ConfigMismatch"},
+-		{WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH,
+-		 "Conn", "EncrypMismatch"},
+-		{WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH,
+-		 "Conn", "RsnMismatch"},
+-		{WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+-		 "Conn", "AuthTimeout"},
+-		{WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "AuthFail"},
+-		{WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE,
+-		 "Conn", "AuthNoAck"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocFail"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocTimeout"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocAbort"},
+-		{WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE,
+-		 "Sup", "ConnSuccess"},
+-		{WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Sup", "WpaHandshakeFail"},
+-		{WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "Deauth"},
+-		{WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "DisassocInd"},
+-		{WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "Disassoc"}
+-	};
+-
+-	const char *name = "";
+-	const char *cause = NULL;
+-	int i;
+-
+-	for (i = 0; i < sizeof(event_map) / sizeof(event_map[0]); i++) {
+-		const conn_fail_event_map_t *row = &event_map[i];
+-		if (row->inEvent == event_type &&
+-		    (row->inStatus == status
+-		     || row->inStatus == WL_IW_DONT_CARE)
+-		    && (row->inReason == reason
+-			|| row->inReason == WL_IW_DONT_CARE)) {
+-			name = row->outName;
+-			cause = row->outCause;
+-			break;
+-		}
+-	}
+-
+-	if (cause) {
+-		memset(stringBuf, 0, buflen);
+-		snprintf(stringBuf, buflen, "%s %s %02d %02d",
+-			 name, cause, status, reason);
+-		WL_INFORM("Connection status: %s\n", stringBuf);
+-		return true;
+-	} else {
+-		return false;
+-	}
+-}
+-
+-#if WIRELESS_EXT > 14
+-
+-static bool
+-wl_iw_check_conn_fail(wl_event_msg_t *e, char *stringBuf, uint buflen)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-	u32 reason = be32_to_cpu(e->reason);
+-
+-	if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) {
+-		return true;
+-	} else
+-		return false;
+-}
+-#endif
+-
+-#ifndef IW_CUSTOM_MAX
+-#define IW_CUSTOM_MAX 256
+-#endif
+-
+-void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data)
+-{
+-#if WIRELESS_EXT > 13
+-	union iwreq_data wrqu;
+-	char extra[IW_CUSTOM_MAX + 1];
+-	int cmd = 0;
+-	u32 event_type = be32_to_cpu(e->event_type);
+-	u16 flags = be16_to_cpu(e->flags);
+-	u32 datalen = be32_to_cpu(e->datalen);
+-	u32 status = be32_to_cpu(e->status);
+-	wl_iw_t *iw;
+-	u32 toto;
+-	memset(&wrqu, 0, sizeof(wrqu));
+-	memset(extra, 0, sizeof(extra));
+-	iw = 0;
+-
+-	if (!dev) {
+-		WL_ERROR("%s: dev is null\n", __func__);
+-		return;
+-	}
+-
+-	iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: dev=%s event=%d\n", __func__, dev->name, event_type);
+-
+-	switch (event_type) {
+-	case WLC_E_TXFAIL:
+-		cmd = IWEVTXDROP;
+-		memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		break;
+-#if WIRELESS_EXT > 14
+-	case WLC_E_JOIN:
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-		memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		cmd = IWEVREGISTERED;
+-		break;
+-	case WLC_E_DEAUTH_IND:
+-	case WLC_E_DISASSOC_IND:
+-		cmd = SIOCGIWAP;
+-		memset(wrqu.addr.sa_data, 0, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		memset(&extra, 0, ETH_ALEN);
+-		break;
+-	case WLC_E_LINK:
+-	case WLC_E_NDIS_LINK:
+-		cmd = SIOCGIWAP;
+-		if (!(flags & WLC_EVENT_MSG_LINK)) {
+-			memset(wrqu.addr.sa_data, 0, ETH_ALEN);
+-			memset(&extra, 0, ETH_ALEN);
+-		} else {
+-			memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-			WL_TRACE("Link UP\n");
+-
+-		}
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		break;
+-	case WLC_E_ACTION_FRAME:
+-		cmd = IWEVCUSTOM;
+-		if (datalen + 1 <= sizeof(extra)) {
+-			wrqu.data.length = datalen + 1;
+-			extra[0] = WLC_E_ACTION_FRAME;
+-			memcpy(&extra[1], data, datalen);
+-			WL_TRACE("WLC_E_ACTION_FRAME len %d\n",
+-				 wrqu.data.length);
+-		}
+-		break;
+-
+-	case WLC_E_ACTION_FRAME_COMPLETE:
+-		cmd = IWEVCUSTOM;
+-		memcpy(&toto, data, 4);
+-		if (sizeof(status) + 1 <= sizeof(extra)) {
+-			wrqu.data.length = sizeof(status) + 1;
+-			extra[0] = WLC_E_ACTION_FRAME_COMPLETE;
+-			memcpy(&extra[1], &status, sizeof(status));
+-			WL_TRACE("wl_iw_event status %d PacketId %d\n", status,
+-				 toto);
+-			WL_TRACE("WLC_E_ACTION_FRAME_COMPLETE len %d\n",
+-				 wrqu.data.length);
+-		}
+-		break;
+-#endif				/* WIRELESS_EXT > 14 */
+-#if WIRELESS_EXT > 17
+-	case WLC_E_MIC_ERROR:
+-		{
+-			struct iw_michaelmicfailure *micerrevt =
+-			    (struct iw_michaelmicfailure *)&extra;
+-			cmd = IWEVMICHAELMICFAILURE;
+-			wrqu.data.length = sizeof(struct iw_michaelmicfailure);
+-			if (flags & WLC_EVENT_MSG_GROUP)
+-				micerrevt->flags |= IW_MICFAILURE_GROUP;
+-			else
+-				micerrevt->flags |= IW_MICFAILURE_PAIRWISE;
+-			memcpy(micerrevt->src_addr.sa_data, &e->addr,
+-			       ETH_ALEN);
+-			micerrevt->src_addr.sa_family = ARPHRD_ETHER;
+-
+-			break;
+-		}
+-	case WLC_E_PMKID_CACHE:
+-		{
+-			if (data) {
+-				struct iw_pmkid_cand *iwpmkidcand =
+-				    (struct iw_pmkid_cand *)&extra;
+-				pmkid_cand_list_t *pmkcandlist;
+-				pmkid_cand_t *pmkidcand;
+-				int count;
+-
+-				cmd = IWEVPMKIDCAND;
+-				pmkcandlist = data;
+-				count = get_unaligned_be32(&pmkcandlist->
+-							   npmkid_cand);
+-				ASSERT(count >= 0);
+-				wrqu.data.length = sizeof(struct iw_pmkid_cand);
+-				pmkidcand = pmkcandlist->pmkid_cand;
+-				while (count) {
+-					memset(iwpmkidcand, 0,
+-					      sizeof(struct iw_pmkid_cand));
+-					if (pmkidcand->preauth)
+-						iwpmkidcand->flags |=
+-						    IW_PMKID_CAND_PREAUTH;
+-					memcpy(&iwpmkidcand->bssid.sa_data,
+-					       &pmkidcand->BSSID,
+-					       ETH_ALEN);
+-#ifndef SANDGATE2G
+-					wireless_send_event(dev, cmd, &wrqu,
+-							    extra);
+-#endif
+-					pmkidcand++;
+-					count--;
+-				}
+-			}
+-			return;
+-		}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-	case WLC_E_SCAN_COMPLETE:
+-#if defined(WL_IW_USE_ISCAN)
+-		if ((g_iscan) && (g_iscan->sysioc_tsk) &&
+-		    (g_iscan->iscan_state != ISCAN_STATE_IDLE)) {
+-			up(&g_iscan->sysioc_sem);
+-		} else {
+-			cmd = SIOCGIWSCAN;
+-			wrqu.data.length = strlen(extra);
+-			WL_TRACE("Event WLC_E_SCAN_COMPLETE from specific scan %d\n",
+-				 g_iscan->iscan_state);
+-		}
+-#else
+-		cmd = SIOCGIWSCAN;
+-		wrqu.data.length = strlen(extra);
+-		WL_TRACE("Event WLC_E_SCAN_COMPLETE\n");
+-#endif
+-		break;
+-
+-	case WLC_E_PFN_NET_FOUND:
+-		{
+-			wlc_ssid_t *ssid;
+-			ssid = (wlc_ssid_t *) data;
+-			WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n",
+-				 __func__, PNO_EVENT_UP,
+-				 ssid->SSID, ssid->SSID_len);
+-			cmd = IWEVCUSTOM;
+-			memset(&wrqu, 0, sizeof(wrqu));
+-			strcpy(extra, PNO_EVENT_UP);
+-			wrqu.data.length = strlen(extra);
+-		}
+-		break;
+-
+-	default:
+-		WL_TRACE("Unknown Event %d: ignoring\n", event_type);
+-		break;
+-	}
+-#ifndef SANDGATE2G
+-	if (cmd) {
+-		if (cmd == SIOCGIWSCAN)
+-			wireless_send_event(dev, cmd, &wrqu, NULL);
+-		else
+-			wireless_send_event(dev, cmd, &wrqu, extra);
+-	}
+-#endif
+-
+-#if WIRELESS_EXT > 14
+-	memset(extra, 0, sizeof(extra));
+-	if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) {
+-		cmd = IWEVCUSTOM;
+-		wrqu.data.length = strlen(extra);
+-#ifndef SANDGATE2G
+-		wireless_send_event(dev, cmd, &wrqu, extra);
+-#endif
+-	}
+-#endif				/* WIRELESS_EXT > 14 */
+-#endif				/* WIRELESS_EXT > 13 */
+-}
+-
+-int wl_iw_attach(struct net_device *dev, void *dhdp)
+-{
+-	int params_size;
+-	wl_iw_t *iw;
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_info_t *iscan = NULL;
+-
+-	if (!dev)
+-		return 0;
+-
+-	memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t));
+-
+-#ifdef CSCAN
+-	params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)) +
+-	    (WL_NUMCHANNELS * sizeof(u16)) +
+-	    WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t);
+-#else
+-	params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+-#endif
+-	iscan = kzalloc(sizeof(iscan_info_t), GFP_KERNEL);
+-
+-	if (!iscan)
+-		return -ENOMEM;
+-
+-	iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL);
+-	if (!iscan->iscan_ex_params_p) {
+-		kfree(iscan);
+-		return -ENOMEM;
+-	}
+-	iscan->iscan_ex_param_size = params_size;
+-	iscan->sysioc_tsk = NULL;
+-
+-	g_iscan = iscan;
+-	iscan->dev = dev;
+-	iscan->iscan_state = ISCAN_STATE_IDLE;
+-
+-	iscan->timer_ms = 3000;
+-	init_timer(&iscan->timer);
+-	iscan->timer.data = (unsigned long) iscan;
+-	iscan->timer.function = wl_iw_timerfunc;
+-
+-	sema_init(&iscan->sysioc_sem, 0);
+-	iscan->sysioc_tsk = kthread_run(_iscan_sysioc_thread, iscan,
+-					"_iscan_sysioc");
+-	if (IS_ERR(iscan->sysioc_tsk)) {
+-		iscan->sysioc_tsk = NULL;
+-		return -ENOMEM;
+-	}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-	iw = *(wl_iw_t **) netdev_priv(dev);
+-	iw->pub = (dhd_pub_t *) dhdp;
+-	MUTEX_LOCK_INIT(iw->pub);
+-	MUTEX_LOCK_WL_SCAN_SET_INIT();
+-#ifdef SOFTAP
+-	priv_dev = dev;
+-	MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub);
+-#endif
+-	g_scan = kzalloc(G_SCAN_RESULTS, GFP_KERNEL);
+-	if (!g_scan)
+-		return -ENOMEM;
+-
+-	g_scan_specified_ssid = 0;
+-
+-	return 0;
+-}
+-
+-void wl_iw_detach(void)
+-{
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_buf_t *buf;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	if (!iscan)
+-		return;
+-	if (iscan->sysioc_tsk) {
+-		send_sig(SIGTERM, iscan->sysioc_tsk, 1);
+-		kthread_stop(iscan->sysioc_tsk);
+-		iscan->sysioc_tsk = NULL;
+-	}
+-
+-	MUTEX_LOCK_WL_SCAN_SET();
+-	while (iscan->list_hdr) {
+-		buf = iscan->list_hdr->next;
+-		kfree(iscan->list_hdr);
+-		iscan->list_hdr = buf;
+-	}
+-	MUTEX_UNLOCK_WL_SCAN_SET();
+-	kfree(iscan->iscan_ex_params_p);
+-	kfree(iscan);
+-	g_iscan = NULL;
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-	kfree(g_scan);
+-
+-	g_scan = NULL;
+-}
+-
+-#if defined(BCMDBG)
+-void osl_assert(char *exp, char *file, int line)
+-{
+-	char tempbuf[256];
+-	char *basename;
+-
+-	basename = strrchr(file, '/');
+-	/* skip the '/' */
+-	if (basename)
+-		basename++;
+-
+-	if (!basename)
+-		basename = file;
+-
+-	snprintf(tempbuf, 256,
+-		 "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
+-		 basename, line);
+-
+-	/*
+-	 * Print assert message and give it time to
+-	 * be written to /var/log/messages
+-	 */
+-	if (!in_interrupt()) {
+-		const int delay = 3;
+-		printk(KERN_ERR "%s", tempbuf);
+-		printk(KERN_ERR "panic in %d seconds\n", delay);
+-		set_current_state(TASK_INTERRUPTIBLE);
+-		schedule_timeout(delay * HZ);
+-	}
+-
+-	switch (g_assert_type) {
+-	case 0:
+-		panic(KERN_ERR "%s", tempbuf);
+-		break;
+-	case 1:
+-		printk(KERN_ERR "%s", tempbuf);
+-		BUG();
+-		break;
+-	case 2:
+-		printk(KERN_ERR "%s", tempbuf);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-#endif				/* defined(BCMDBG) */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h
+deleted file mode 100644
+index fe06174..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h
++++ /dev/null
+@@ -1,142 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_iw_h_
+-#define _wl_iw_h_
+-
+-#include <linux/wireless.h>
+-
+-#include <wlioctl.h>
+-
+-#define WL_SCAN_PARAMS_SSID_MAX	10
+-#define GET_SSID	"SSID="
+-#define GET_CHANNEL	"CH="
+-#define GET_NPROBE 			"NPROBE="
+-#define GET_ACTIVE_ASSOC_DWELL  	"ACTIVE="
+-#define GET_PASSIVE_ASSOC_DWELL	"PASSIVE="
+-#define GET_HOME_DWELL		"HOME="
+-#define GET_SCAN_TYPE			"TYPE="
+-
+-#define BAND_GET_CMD				"BANDGET"
+-#define BAND_SET_CMD				"BANDSET"
+-#define DTIM_SKIP_GET_CMD			"DTIMSKIPGET"
+-#define DTIM_SKIP_SET_CMD			"DTIMSKIPSET"
+-#define SETSUSPEND_CMD				"SETSUSPENDOPT"
+-#define PNOSSIDCLR_SET_CMD			"PNOSSIDCLR"
+-#define PNOSETUP_SET_CMD			"PNOSETUP"
+-#define PNOENABLE_SET_CMD			"PNOFORCE"
+-#define PNODEBUG_SET_CMD			"PNODEBUG"
+-
+-typedef struct wl_iw_extra_params {
+-	int target_channel;
+-} wl_iw_extra_params_t;
+-
+-#define	WL_IW_RSSI_MINVAL		-200
+-#define	WL_IW_RSSI_NO_SIGNAL	-91
+-#define	WL_IW_RSSI_VERY_LOW	-80
+-#define	WL_IW_RSSI_LOW		-70
+-#define	WL_IW_RSSI_GOOD		-68
+-#define	WL_IW_RSSI_VERY_GOOD	-58
+-#define	WL_IW_RSSI_EXCELLENT	-57
+-#define	WL_IW_RSSI_INVALID	 0
+-#define MAX_WX_STRING 80
+-#define WL_IW_SET_ACTIVE_SCAN	(SIOCIWFIRSTPRIV+1)
+-#define WL_IW_GET_RSSI			(SIOCIWFIRSTPRIV+3)
+-#define WL_IW_SET_PASSIVE_SCAN	(SIOCIWFIRSTPRIV+5)
+-#define WL_IW_GET_LINK_SPEED	(SIOCIWFIRSTPRIV+7)
+-#define WL_IW_GET_CURR_MACADDR	(SIOCIWFIRSTPRIV+9)
+-#define WL_IW_SET_STOP				(SIOCIWFIRSTPRIV+11)
+-#define WL_IW_SET_START			(SIOCIWFIRSTPRIV+13)
+-
+-#define WL_SET_AP_CFG           (SIOCIWFIRSTPRIV+15)
+-#define WL_AP_STA_LIST          (SIOCIWFIRSTPRIV+17)
+-#define WL_AP_MAC_FLTR	        (SIOCIWFIRSTPRIV+19)
+-#define WL_AP_BSS_START         (SIOCIWFIRSTPRIV+21)
+-#define AP_LPB_CMD              (SIOCIWFIRSTPRIV+23)
+-#define WL_AP_STOP              (SIOCIWFIRSTPRIV+25)
+-#define WL_FW_RELOAD            (SIOCIWFIRSTPRIV+27)
+-#define WL_COMBO_SCAN            (SIOCIWFIRSTPRIV+29)
+-#define WL_AP_SPARE3            (SIOCIWFIRSTPRIV+31)
+-#define G_SCAN_RESULTS		(8*1024)
+-#define	WE_ADD_EVENT_FIX	0x80
+-#define          G_WLAN_SET_ON	0
+-#define          G_WLAN_SET_OFF	1
+-
+-#define CHECK_EXTRA_FOR_NULL(extra) \
+-if (!extra) { \
+-	WL_ERROR("%s: error : extra is null pointer\n", __func__);	\
+-	return -EINVAL; \
+-}
+-
+-typedef struct wl_iw {
+-	char nickname[IW_ESSID_MAX_SIZE];
+-
+-	struct iw_statistics wstats;
+-
+-	int spy_num;
+-	u32 pwsec;
+-	u32 gwsec;
+-	bool privacy_invoked;
+-
+-	u8 spy_addr[IW_MAX_SPY][ETH_ALEN];
+-	struct iw_quality spy_qual[IW_MAX_SPY];
+-	void *wlinfo;
+-	dhd_pub_t *pub;
+-} wl_iw_t;
+-
+-#if WIRELESS_EXT > 12
+-#include <net/iw_handler.h>
+-extern const struct iw_handler_def wl_iw_handler_def;
+-#endif
+-
+-extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+-extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data);
+-extern int wl_iw_get_wireless_stats(struct net_device *dev,
+-				    struct iw_statistics *wstats);
+-int wl_iw_attach(struct net_device *dev, void *dhdp);
+-void wl_iw_detach(void);
+-extern int net_os_set_suspend_disable(struct net_device *dev, int val);
+-extern int net_os_set_suspend(struct net_device *dev, int val);
+-extern int net_os_set_dtim_skip(struct net_device *dev, int val);
+-extern int net_os_set_packet_filter(struct net_device *dev, int val);
+-
+-#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+-	iwe_stream_add_event(info, stream, ends, iwe, extra)
+-#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+-	iwe_stream_add_value(info, event, value, ends, iwe, event_len)
+-#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+-	iwe_stream_add_point(info, stream, ends, iwe, extra)
+-
+-extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+-extern int dhd_pno_clean(dhd_pub_t *dhd);
+-extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid,
+-		       unsigned char scan_fr);
+-extern int dhd_pno_get_status(dhd_pub_t *dhd);
+-extern int dhd_dev_pno_reset(struct net_device *dev);
+-extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local,
+-			   int nssid, unsigned char scan_fr);
+-extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
+-extern int dhd_dev_get_pno_status(struct net_device *dev);
+-
+-#define PNO_TLV_PREFIX			'S'
+-#define PNO_TLV_VERSION			1
+-#define PNO_TLV_SUBVERSION		0
+-#define PNO_TLV_RESERVED		0
+-#define PNO_TLV_TYPE_SSID_IE		'S'
+-#define PNO_TLV_TYPE_TIME		'T'
+-#define  PNO_EVENT_UP			"PNO_EVENT"
+-
+-#endif				/* _wl_iw_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile
+deleted file mode 100644
+index 8d75fe1..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/Makefile
++++ /dev/null
+@@ -1,59 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=				\
+-	-DWLC_HIGH				\
+-	-DWLC_LOW				\
+-	-DSTA					\
+-	-DWME					\
+-	-DWL11N					\
+-	-DDBAND					\
+-	-DBCMNVRAMR				\
+-	-Idrivers/staging/brcm80211/brcmsmac \
+-	-Idrivers/staging/brcm80211/brcmsmac/phy \
+-	-Idrivers/staging/brcm80211/include
+-
+-BRCMSMAC_OFILES := \
+-	wl_mac80211.o \
+-	wl_ucode_loader.o \
+-	wlc_alloc.o \
+-	wlc_ampdu.o \
+-	wlc_antsel.o \
+-	wlc_bmac.o \
+-	wlc_channel.o \
+-	wlc_main.o \
+-	wlc_phy_shim.o \
+-	wlc_pmu.o \
+-	wlc_rate.o \
+-	wlc_stf.o \
+-	aiutils.o \
+-	phy/wlc_phy_cmn.o \
+-	phy/wlc_phy_lcn.o \
+-	phy/wlc_phy_n.o \
+-	phy/wlc_phytbl_lcn.o \
+-	phy/wlc_phytbl_n.o \
+-	phy/wlc_phy_qmath.o \
+-	bcmotp.o \
+-	bcmsrom.o \
+-	hnddma.o \
+-	nicpci.o \
+-	nvram.o
+-
+-MODULEPFX := brcmsmac
+-
+-obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
+-$(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
+diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c
+deleted file mode 100644
+index a61185f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/aiutils.c
++++ /dev/null
+@@ -1,2054 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <bcmdevs.h>
+-
+-/* ********** from siutils.c *********** */
+-#include <pci_core.h>
+-#include <pcie_core.h>
+-#include <nicpci.h>
+-#include <bcmnvram.h>
+-#include <bcmsrom.h>
+-#include <wlc_pmu.h>
+-
+-#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
+-		(sih->chiprev == 0) && \
+-		(sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
+-
+-/* EROM parsing */
+-
+-static u32
+-get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match)
+-{
+-	u32 ent;
+-	uint inv = 0, nom = 0;
+-
+-	while (true) {
+-		ent = R_REG(*eromptr);
+-		(*eromptr)++;
+-
+-		if (mask == 0)
+-			break;
+-
+-		if ((ent & ER_VALID) == 0) {
+-			inv++;
+-			continue;
+-		}
+-
+-		if (ent == (ER_END | ER_VALID))
+-			break;
+-
+-		if ((ent & mask) == match)
+-			break;
+-
+-		nom++;
+-	}
+-
+-	SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
+-	if (inv + nom) {
+-		SI_VMSG(("  after %d invalid and %d non-matching entries\n",
+-			 inv, nom));
+-	}
+-	return ent;
+-}
+-
+-static u32
+-get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st,
+-	u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
+-{
+-	u32 asd, sz, szd;
+-
+-	asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+-	if (((asd & ER_TAG1) != ER_ADD) ||
+-	    (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+-	    ((asd & AD_ST_MASK) != st)) {
+-		/* This is not what we want, "push" it back */
+-		(*eromptr)--;
+-		return 0;
+-	}
+-	*addrl = asd & AD_ADDR_MASK;
+-	if (asd & AD_AG32)
+-		*addrh = get_erom_ent(sih, eromptr, 0, 0);
+-	else
+-		*addrh = 0;
+-	*sizeh = 0;
+-	sz = asd & AD_SZ_MASK;
+-	if (sz == AD_SZ_SZD) {
+-		szd = get_erom_ent(sih, eromptr, 0, 0);
+-		*sizel = szd & SD_SZ_MASK;
+-		if (szd & SD_SG32)
+-			*sizeh = get_erom_ent(sih, eromptr, 0, 0);
+-	} else
+-		*sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+-
+-	SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+-		 sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
+-
+-	return asd;
+-}
+-
+-static void ai_hwfixup(si_info_t *sii)
+-{
+-}
+-
+-/* parse the enumeration rom to identify all cores */
+-void ai_scan(si_t *sih, void *regs, uint devid)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	chipcregs_t *cc = (chipcregs_t *) regs;
+-	u32 erombase, *eromptr, *eromlim;
+-
+-	erombase = R_REG(&cc->eromptr);
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-		eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
+-		break;
+-
+-	case PCI_BUS:
+-		/* Set wrappers address */
+-		sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
+-
+-		/* Now point the window at the erom */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
+-		eromptr = regs;
+-		break;
+-
+-	case SPI_BUS:
+-	case SDIO_BUS:
+-		eromptr = (u32 *)(unsigned long)erombase;
+-		break;
+-
+-	default:
+-		SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
+-			  sih->bustype));
+-		return;
+-	}
+-	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
+-
+-	SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
+-	while (eromptr < eromlim) {
+-		u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+-		u32 mpd, asd, addrl, addrh, sizel, sizeh;
+-		u32 *base;
+-		uint i, j, idx;
+-		bool br;
+-
+-		br = false;
+-
+-		/* Grok a component */
+-		cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+-		if (cia == (ER_END | ER_VALID)) {
+-			SI_VMSG(("Found END of erom after %d cores\n",
+-				 sii->numcores));
+-			ai_hwfixup(sii);
+-			return;
+-		}
+-		base = eromptr - 1;
+-		cib = get_erom_ent(sih, &eromptr, 0, 0);
+-
+-		if ((cib & ER_TAG) != ER_CI) {
+-			SI_ERROR(("CIA not followed by CIB\n"));
+-			goto error;
+-		}
+-
+-		cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+-		mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+-		crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+-		nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+-		nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+-		nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+-		nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+-
+-		SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
+-
+-		if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
+-			continue;
+-		if ((nmw + nsw == 0)) {
+-			/* A component which is not a core */
+-			if (cid == OOB_ROUTER_CORE_ID) {
+-				asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+-					      &addrl, &addrh, &sizel, &sizeh);
+-				if (asd != 0) {
+-					sii->oob_router = addrl;
+-				}
+-			}
+-			continue;
+-		}
+-
+-		idx = sii->numcores;
+-/*		sii->eromptr[idx] = base; */
+-		sii->cia[idx] = cia;
+-		sii->cib[idx] = cib;
+-		sii->coreid[idx] = cid;
+-
+-		for (i = 0; i < nmp; i++) {
+-			mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+-			if ((mpd & ER_TAG) != ER_MP) {
+-				SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
+-				goto error;
+-			}
+-			SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
+-				 (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+-				 (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
+-		}
+-
+-		/* First Slave Address Descriptor should be port 0:
+-		 * the main register space for the core
+-		 */
+-		asd =
+-		    get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
+-			    &sizel, &sizeh);
+-		if (asd == 0) {
+-			/* Try again to see if it is a bridge */
+-			asd =
+-			    get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if (asd != 0)
+-				br = true;
+-			else if ((addrh != 0) || (sizeh != 0)
+-				 || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
+-				goto error;
+-			}
+-		}
+-		sii->coresba[idx] = addrl;
+-		sii->coresba_size[idx] = sizel;
+-		/* Get any more ASDs in port 0 */
+-		j = 1;
+-		do {
+-			asd =
+-			    get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
+-				sii->coresba2[idx] = addrl;
+-				sii->coresba2_size[idx] = sizel;
+-			}
+-			j++;
+-		} while (asd != 0);
+-
+-		/* Go through the ASDs for other slave ports */
+-		for (i = 1; i < nsp; i++) {
+-			j = 0;
+-			do {
+-				asd =
+-				    get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
+-					    &addrl, &addrh, &sizel, &sizeh);
+-			} while (asd != 0);
+-			if (j == 0) {
+-				SI_ERROR((" SP %d has no address descriptors\n",
+-					  i));
+-				goto error;
+-			}
+-		}
+-
+-		/* Now get master wrappers */
+-		for (i = 0; i < nmw; i++) {
+-			asd =
+-			    get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if (asd == 0) {
+-				SI_ERROR(("Missing descriptor for MW %d\n", i));
+-				goto error;
+-			}
+-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("Master wrapper %d is not 4KB\n", i));
+-				goto error;
+-			}
+-			if (i == 0)
+-				sii->wrapba[idx] = addrl;
+-		}
+-
+-		/* And finally slave wrappers */
+-		for (i = 0; i < nsw; i++) {
+-			uint fwp = (nsp == 1) ? 0 : 1;
+-			asd =
+-			    get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
+-				    &addrl, &addrh, &sizel, &sizeh);
+-			if (asd == 0) {
+-				SI_ERROR(("Missing descriptor for SW %d\n", i));
+-				goto error;
+-			}
+-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
+-				goto error;
+-			}
+-			if ((nmw == 0) && (i == 0))
+-				sii->wrapba[idx] = addrl;
+-		}
+-
+-		/* Don't record bridges */
+-		if (br)
+-			continue;
+-
+-		/* Done with core */
+-		sii->numcores++;
+-	}
+-
+-	SI_ERROR(("Reached end of erom without finding END"));
+-
+- error:
+-	sii->numcores = 0;
+-	return;
+-}
+-
+-/* This function changes the logical "focus" to the indicated core.
+- * Return the current core's virtual address.
+- */
+-void *ai_setcoreidx(si_t *sih, uint coreidx)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	u32 addr = sii->coresba[coreidx];
+-	u32 wrap = sii->wrapba[coreidx];
+-	void *regs;
+-
+-	if (coreidx >= sii->numcores)
+-		return NULL;
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-		/* map new one */
+-		if (!sii->regs[coreidx]) {
+-			sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
+-		}
+-		sii->curmap = regs = sii->regs[coreidx];
+-		if (!sii->wrappers[coreidx]) {
+-			sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+-		}
+-		sii->curwrap = sii->wrappers[coreidx];
+-		break;
+-
+-	case PCI_BUS:
+-		/* point bar0 window */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
+-		regs = sii->curmap;
+-		/* point bar0 2nd 4KB window */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
+-		break;
+-
+-	case SPI_BUS:
+-	case SDIO_BUS:
+-		sii->curmap = regs = (void *)(unsigned long)addr;
+-		sii->curwrap = (void *)(unsigned long)wrap;
+-		break;
+-
+-	default:
+-		regs = NULL;
+-		break;
+-	}
+-
+-	sii->curmap = regs;
+-	sii->curidx = coreidx;
+-
+-	return regs;
+-}
+-
+-/* Return the number of address spaces in current core */
+-int ai_numaddrspaces(si_t *sih)
+-{
+-	return 2;
+-}
+-
+-/* Return the address of the nth address space in the current core */
+-u32 ai_addrspace(si_t *sih, uint asidx)
+-{
+-	si_info_t *sii;
+-	uint cidx;
+-
+-	sii = SI_INFO(sih);
+-	cidx = sii->curidx;
+-
+-	if (asidx == 0)
+-		return sii->coresba[cidx];
+-	else if (asidx == 1)
+-		return sii->coresba2[cidx];
+-	else {
+-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+-		return 0;
+-	}
+-}
+-
+-/* Return the size of the nth address space in the current core */
+-u32 ai_addrspacesize(si_t *sih, uint asidx)
+-{
+-	si_info_t *sii;
+-	uint cidx;
+-
+-	sii = SI_INFO(sih);
+-	cidx = sii->curidx;
+-
+-	if (asidx == 0)
+-		return sii->coresba_size[cidx];
+-	else if (asidx == 1)
+-		return sii->coresba2_size[cidx];
+-	else {
+-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+-		return 0;
+-	}
+-}
+-
+-uint ai_flag(si_t *sih)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
+-		return sii->curidx;
+-	}
+-	ai = sii->curwrap;
+-
+-	return R_REG(&ai->oobselouta30) & 0x1f;
+-}
+-
+-void ai_setint(si_t *sih, int siflag)
+-{
+-}
+-
+-uint ai_corevendor(si_t *sih)
+-{
+-	si_info_t *sii;
+-	u32 cia;
+-
+-	sii = SI_INFO(sih);
+-	cia = sii->cia[sii->curidx];
+-	return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+-}
+-
+-uint ai_corerev(si_t *sih)
+-{
+-	si_info_t *sii;
+-	u32 cib;
+-
+-	sii = SI_INFO(sih);
+-	cib = sii->cib[sii->curidx];
+-	return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+-}
+-
+-bool ai_iscoreup(si_t *sih)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-	ai = sii->curwrap;
+-
+-	return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
+-		 SICF_CLOCK_EN)
+-		&& ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
+-}
+-
+-void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+-			  __func__));
+-		return;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+-		W_REG(&ai->ioctrl, w);
+-	}
+-}
+-
+-u32 ai_core_cflags(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+-			  __func__));
+-		return 0;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+-		W_REG(&ai->ioctrl, w);
+-	}
+-
+-	return R_REG(&ai->ioctrl);
+-}
+-
+-u32 ai_core_sflags(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
+-		return 0;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->iostatus) & ~mask) | val);
+-		W_REG(&ai->iostatus, w);
+-	}
+-
+-	return R_REG(&ai->iostatus);
+-}
+-
+-/* *************** from siutils.c ************** */
+-/* local prototypes */
+-static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs,
+-			      uint bustype, void *sdh, char **vars,
+-			      uint *varsz);
+-static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+-			    void *sdh);
+-static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+-			     u32 savewin, uint *origidx, void *regs);
+-static void ai_nvram_process(si_info_t *sii, char *pvars);
+-
+-/* dev path concatenation util */
+-static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name);
+-static bool _ai_clkctl_cc(si_info_t *sii, uint mode);
+-static bool ai_ispcie(si_info_t *sii);
+-
+-/* global variable to indicate reservation/release of gpio's */
+-static u32 ai_gpioreservation;
+-
+-/*
+- * Allocate a si handle.
+- * devid - pci device id (used to determine chip#)
+- * osh - opaque OS handle
+- * regs - virtual address of initial core registers
+- * bustype - pci/sb/sdio/etc
+- * vars - pointer to a pointer area for "environment" variables
+- * varsz - pointer to int to return the size of the vars
+- */
+-si_t *ai_attach(uint devid, void *regs, uint bustype,
+-		void *sdh, char **vars, uint *varsz)
+-{
+-	si_info_t *sii;
+-
+-	/* alloc si_info_t */
+-	sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
+-	if (sii == NULL) {
+-		SI_ERROR(("si_attach: malloc failed!\n"));
+-		return NULL;
+-	}
+-
+-	if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
+-	    NULL) {
+-		kfree(sii);
+-		return NULL;
+-	}
+-	sii->vars = vars ? *vars : NULL;
+-	sii->varsz = varsz ? *varsz : 0;
+-
+-	return (si_t *) sii;
+-}
+-
+-/* global kernel resource */
+-static si_info_t ksii;
+-
+-static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+-			    void *sdh)
+-{
+-	/* kludge to enable the clock on the 4306 which lacks a slowclock */
+-	if (bustype == PCI_BUS && !ai_ispcie(sii))
+-		ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
+-	return true;
+-}
+-
+-static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+-			     u32 savewin, uint *origidx, void *regs)
+-{
+-	bool pci, pcie;
+-	uint i;
+-	uint pciidx, pcieidx, pcirev, pcierev;
+-
+-	cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
+-
+-	/* get chipcommon rev */
+-	sii->pub.ccrev = (int)ai_corerev(&sii->pub);
+-
+-	/* get chipcommon chipstatus */
+-	if (sii->pub.ccrev >= 11)
+-		sii->pub.chipst = R_REG(&cc->chipstatus);
+-
+-	/* get chipcommon capabilites */
+-	sii->pub.cccaps = R_REG(&cc->capabilities);
+-	/* get chipcommon extended capabilities */
+-
+-	if (sii->pub.ccrev >= 35)
+-		sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
+-
+-	/* get pmu rev and caps */
+-	if (sii->pub.cccaps & CC_CAP_PMU) {
+-		sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
+-		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+-	}
+-
+-	/* figure out bus/orignal core idx */
+-	sii->pub.buscoretype = NODEV_CORE_ID;
+-	sii->pub.buscorerev = NOREV;
+-	sii->pub.buscoreidx = BADIDX;
+-
+-	pci = pcie = false;
+-	pcirev = pcierev = NOREV;
+-	pciidx = pcieidx = BADIDX;
+-
+-	for (i = 0; i < sii->numcores; i++) {
+-		uint cid, crev;
+-
+-		ai_setcoreidx(&sii->pub, i);
+-		cid = ai_coreid(&sii->pub);
+-		crev = ai_corerev(&sii->pub);
+-
+-		/* Display cores found */
+-		SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
+-			 i, cid, crev, sii->coresba[i], sii->regs[i]));
+-
+-		if (bustype == PCI_BUS) {
+-			if (cid == PCI_CORE_ID) {
+-				pciidx = i;
+-				pcirev = crev;
+-				pci = true;
+-			} else if (cid == PCIE_CORE_ID) {
+-				pcieidx = i;
+-				pcierev = crev;
+-				pcie = true;
+-			}
+-		}
+-
+-		/* find the core idx before entering this func. */
+-		if ((savewin && (savewin == sii->coresba[i])) ||
+-		    (regs == sii->regs[i]))
+-			*origidx = i;
+-	}
+-
+-	if (pci && pcie) {
+-		if (ai_ispcie(sii))
+-			pci = false;
+-		else
+-			pcie = false;
+-	}
+-	if (pci) {
+-		sii->pub.buscoretype = PCI_CORE_ID;
+-		sii->pub.buscorerev = pcirev;
+-		sii->pub.buscoreidx = pciidx;
+-	} else if (pcie) {
+-		sii->pub.buscoretype = PCIE_CORE_ID;
+-		sii->pub.buscorerev = pcierev;
+-		sii->pub.buscoreidx = pcieidx;
+-	}
+-
+-	SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
+-		 sii->pub.buscoretype, sii->pub.buscorerev));
+-
+-	/* fixup necessary chip/core configurations */
+-	if (sii->pub.bustype == PCI_BUS) {
+-		if (SI_FAST(sii)) {
+-			if (!sii->pch) {
+-				sii->pch = (void *)pcicore_init(
+-					&sii->pub, sii->pbus,
+-					(void *)PCIEREGS(sii));
+-				if (sii->pch == NULL)
+-					return false;
+-			}
+-		}
+-		if (ai_pci_fixcfg(&sii->pub)) {
+-			SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
+-			return false;
+-		}
+-	}
+-
+-	/* return to the original core */
+-	ai_setcoreidx(&sii->pub, *origidx);
+-
+-	return true;
+-}
+-
+-static __used void ai_nvram_process(si_info_t *sii, char *pvars)
+-{
+-	uint w = 0;
+-
+-	/* get boardtype and boardrev */
+-	switch (sii->pub.bustype) {
+-	case PCI_BUS:
+-		/* do a pci config read to get subsystem id and subvendor id */
+-		pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
+-		/* Let nvram variables override subsystem Vend/ID */
+-		sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
+-			"boardvendor");
+-		if (sii->pub.boardvendor == 0)
+-			sii->pub.boardvendor = w & 0xffff;
+-		else
+-			SI_ERROR(("Overriding boardvendor: 0x%x instead of "
+-				  "0x%x\n", sii->pub.boardvendor, w & 0xffff));
+-		sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
+-			"boardtype");
+-		if (sii->pub.boardtype == 0)
+-			sii->pub.boardtype = (w >> 16) & 0xffff;
+-		else
+-			SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
+-				  , sii->pub.boardtype, (w >> 16) & 0xffff));
+-		break;
+-
+-		sii->pub.boardvendor = getintvar(pvars, "manfid");
+-		sii->pub.boardtype = getintvar(pvars, "prodid");
+-		break;
+-
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
+-		sii->pub.boardtype = getintvar(pvars, "prodid");
+-		if (pvars == NULL || (sii->pub.boardtype == 0)) {
+-			sii->pub.boardtype = getintvar(NULL, "boardtype");
+-			if (sii->pub.boardtype == 0)
+-				sii->pub.boardtype = 0xffff;
+-		}
+-		break;
+-	}
+-
+-	if (sii->pub.boardtype == 0) {
+-		SI_ERROR(("si_doattach: unknown board type\n"));
+-	}
+-
+-	sii->pub.boardflags = getintvar(pvars, "boardflags");
+-}
+-
+-static si_info_t *ai_doattach(si_info_t *sii, uint devid,
+-			      void *regs, uint bustype, void *pbus,
+-			      char **vars, uint *varsz)
+-{
+-	struct si_pub *sih = &sii->pub;
+-	u32 w, savewin;
+-	chipcregs_t *cc;
+-	char *pvars = NULL;
+-	uint socitype;
+-	uint origidx;
+-
+-	memset((unsigned char *) sii, 0, sizeof(si_info_t));
+-
+-	savewin = 0;
+-
+-	sih->buscoreidx = BADIDX;
+-
+-	sii->curmap = regs;
+-	sii->pbus = pbus;
+-
+-	/* check to see if we are a si core mimic'ing a pci core */
+-	if (bustype == PCI_BUS) {
+-		pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
+-		if (w == 0xffffffff) {
+-			SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
+-				" switching to SI devid:0x%x\n",
+-				__func__, devid));
+-			bustype = SI_BUS;
+-		}
+-	}
+-
+-	/* find Chipcommon address */
+-	if (bustype == PCI_BUS) {
+-		pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
+-		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
+-			savewin = SI_ENUM_BASE;
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
+-				       SI_ENUM_BASE);
+-		cc = (chipcregs_t *) regs;
+-	} else {
+-		cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+-	}
+-
+-	sih->bustype = bustype;
+-
+-	/* bus/core/clk setup for register access */
+-	if (!ai_buscore_prep(sii, bustype, devid, pbus)) {
+-		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
+-			  bustype));
+-		return NULL;
+-	}
+-
+-	/*
+-	 * ChipID recognition.
+-	 *   We assume we can read chipid at offset 0 from the regs arg.
+-	 *   If we add other chiptypes (or if we need to support old sdio
+-	 *   hosts w/o chipcommon), some way of recognizing them needs to
+-	 *   be added here.
+-	 */
+-	w = R_REG(&cc->chipid);
+-	socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+-	/* Might as wll fill in chip id rev & pkg */
+-	sih->chip = w & CID_ID_MASK;
+-	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+-	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+-
+-	sih->issim = IS_SIM(sih->chippkg);
+-
+-	/* scan for cores */
+-	if (socitype == SOCI_AI) {
+-		SI_MSG(("Found chip type AI (0x%08x)\n", w));
+-		/* pass chipc address instead of original core base */
+-		ai_scan(&sii->pub, (void *)cc, devid);
+-	} else {
+-		SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
+-		return NULL;
+-	}
+-	/* no cores found, bail out */
+-	if (sii->numcores == 0) {
+-		SI_ERROR(("si_doattach: could not find any cores\n"));
+-		return NULL;
+-	}
+-	/* bus/core/clk setup */
+-	origidx = SI_CC_IDX;
+-	if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+-		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
+-		goto exit;
+-	}
+-
+-	/* assume current core is CC */
+-	if ((sii->pub.ccrev == 0x25)
+-	    &&
+-	    ((sih->chip == BCM43236_CHIP_ID
+-	      || sih->chip == BCM43235_CHIP_ID
+-	      || sih->chip == BCM43238_CHIP_ID)
+-	     && (sii->pub.chiprev <= 2))) {
+-
+-		if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
+-			uint clkdiv;
+-			clkdiv = R_REG(&cc->clkdiv);
+-			/* otp_clk_div is even number, 120/14 < 9mhz */
+-			clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
+-			W_REG(&cc->clkdiv, clkdiv);
+-			SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
+-		}
+-		udelay(10);
+-	}
+-
+-	/* Init nvram from flash if it exists */
+-	nvram_init();
+-
+-	/* Init nvram from sprom/otp if they exist */
+-	if (srom_var_init
+-	    (&sii->pub, bustype, regs, vars, varsz)) {
+-		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
+-		goto exit;
+-	}
+-	pvars = vars ? *vars : NULL;
+-	ai_nvram_process(sii, pvars);
+-
+-	/* === NVRAM, clock is ready === */
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-	W_REG(&cc->gpiopullup, 0);
+-	W_REG(&cc->gpiopulldown, 0);
+-	ai_setcoreidx(sih, origidx);
+-
+-	/* PMU specific initializations */
+-	if (PMUCTL_ENAB(sih)) {
+-		u32 xtalfreq;
+-		si_pmu_init(sih);
+-		si_pmu_chip_init(sih);
+-		xtalfreq = getintvar(pvars, "xtalfreq");
+-		/* If xtalfreq var not available, try to measure it */
+-		if (xtalfreq == 0)
+-			xtalfreq = si_pmu_measure_alpclk(sih);
+-		si_pmu_pll_init(sih, xtalfreq);
+-		si_pmu_res_init(sih);
+-		si_pmu_swreg_init(sih);
+-	}
+-
+-	/* setup the GPIO based LED powersave register */
+-	w = getintvar(pvars, "leddc");
+-	if (w == 0)
+-		w = DEFAULT_GPIOTIMERVAL;
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
+-
+-	if (PCIE(sii)) {
+-		pcicore_attach(sii->pch, pvars, SI_DOATTACH);
+-	}
+-
+-	if ((sih->chip == BCM43224_CHIP_ID) ||
+-	    (sih->chip == BCM43421_CHIP_ID)) {
+-		/*
+-		 * enable 12 mA drive strenth for 43224 and
+-		 * set chipControl register bit 15
+-		 */
+-		if (sih->chiprev == 0) {
+-			SI_MSG(("Applying 43224A0 WARs\n"));
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol),
+-				   CCTRL43224_GPIO_TOGGLE,
+-				   CCTRL43224_GPIO_TOGGLE);
+-			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
+-					   CCTRL_43224A0_12MA_LED_DRIVE);
+-		}
+-		if (sih->chiprev >= 1) {
+-			SI_MSG(("Applying 43224B0+ WARs\n"));
+-			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
+-					   CCTRL_43224B0_12MA_LED_DRIVE);
+-		}
+-	}
+-
+-	if (sih->chip == BCM4313_CHIP_ID) {
+-		/*
+-		 * enable 12 mA drive strenth for 4313 and
+-		 * set chipControl register bit 1
+-		 */
+-		SI_MSG(("Applying 4313 WARs\n"));
+-		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
+-				   CCTRL_4313_12MA_LED_DRIVE);
+-	}
+-
+-	if (sih->chip == BCM4331_CHIP_ID) {
+-		/* Enable Ext PA lines depending on chip package option */
+-		ai_chipcontrl_epa4331(sih, true);
+-	}
+-
+-	return sii;
+- exit:
+-	if (sih->bustype == PCI_BUS) {
+-		if (sii->pch)
+-			pcicore_deinit(sii->pch);
+-		sii->pch = NULL;
+-	}
+-
+-	return NULL;
+-}
+-
+-/* may be called with core in reset */
+-void ai_detach(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint idx;
+-
+-	struct si_pub *si_local = NULL;
+-	bcopy(&sih, &si_local, sizeof(si_t **));
+-
+-	sii = SI_INFO(sih);
+-
+-	if (sii == NULL)
+-		return;
+-
+-	if (sih->bustype == SI_BUS)
+-		for (idx = 0; idx < SI_MAXCORES; idx++)
+-			if (sii->regs[idx]) {
+-				iounmap(sii->regs[idx]);
+-				sii->regs[idx] = NULL;
+-			}
+-
+-	nvram_exit();	/* free up nvram buffers */
+-
+-	if (sih->bustype == PCI_BUS) {
+-		if (sii->pch)
+-			pcicore_deinit(sii->pch);
+-		sii->pch = NULL;
+-	}
+-
+-	if (sii != &ksii)
+-		kfree(sii);
+-}
+-
+-/* register driver interrupt disabling and restoring callback functions */
+-void
+-ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+-			  void *intrsenabled_fn, void *intr_arg)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	sii->intr_arg = intr_arg;
+-	sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
+-	sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
+-	sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
+-	/* save current core id.  when this function called, the current core
+-	 * must be the core which provides driver functions(il, et, wl, etc.)
+-	 */
+-	sii->dev_coreid = sii->coreid[sii->curidx];
+-}
+-
+-void ai_deregister_intr_callback(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	sii->intrsoff_fn = NULL;
+-}
+-
+-uint ai_coreid(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	return sii->coreid[sii->curidx];
+-}
+-
+-uint ai_coreidx(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	return sii->curidx;
+-}
+-
+-bool ai_backplane64(si_t *sih)
+-{
+-	return (sih->cccaps & CC_CAP_BKPLN64) != 0;
+-}
+-
+-/* return index of coreid or BADIDX if not found */
+-uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit)
+-{
+-	si_info_t *sii;
+-	uint found;
+-	uint i;
+-
+-	sii = SI_INFO(sih);
+-
+-	found = 0;
+-
+-	for (i = 0; i < sii->numcores; i++)
+-		if (sii->coreid[i] == coreid) {
+-			if (found == coreunit)
+-				return i;
+-			found++;
+-		}
+-
+-	return BADIDX;
+-}
+-
+-/*
+- * This function changes logical "focus" to the indicated core;
+- * must be called with interrupts off.
+- * Moreover, callers should keep interrupts off during switching
+- * out of and back to d11 core.
+- */
+-void *ai_setcore(si_t *sih, uint coreid, uint coreunit)
+-{
+-	uint idx;
+-
+-	idx = ai_findcoreidx(sih, coreid, coreunit);
+-	if (!GOODIDX(idx))
+-		return NULL;
+-
+-	return ai_setcoreidx(sih, idx);
+-}
+-
+-/* Turn off interrupt as required by ai_setcore, before switch core */
+-void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
+-{
+-	void *cc;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (SI_FAST(sii)) {
+-		/* Overloading the origidx variable to remember the coreid,
+-		 * this works because the core ids cannot be confused with
+-		 * core indices.
+-		 */
+-		*origidx = coreid;
+-		if (coreid == CC_CORE_ID)
+-			return (void *)CCREGS_FAST(sii);
+-		else if (coreid == sih->buscoretype)
+-			return (void *)PCIEREGS(sii);
+-	}
+-	INTR_OFF(sii, *intr_val);
+-	*origidx = sii->curidx;
+-	cc = ai_setcore(sih, coreid, 0);
+-	return cc;
+-}
+-
+-/* restore coreidx and restore interrupt */
+-void ai_restore_core(si_t *sih, uint coreid, uint intr_val)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	if (SI_FAST(sii)
+-	    && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+-		return;
+-
+-	ai_setcoreidx(sih, coreid);
+-	INTR_RESTORE(sii, intr_val);
+-}
+-
+-void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	u32 *w = (u32 *) sii->curwrap;
+-	W_REG(w + (offset / 4), val);
+-	return;
+-}
+-
+-/*
+- * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
+- * operation, switch back to the original core, and return the new value.
+- *
+- * When using the silicon backplane, no fiddling with interrupts or core
+- * switches is needed.
+- *
+- * Also, when using pci/pcie, we can optimize away the core switching for pci
+- * registers and (on newer pci cores) chipcommon registers.
+- */
+-uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+-{
+-	uint origidx = 0;
+-	u32 *r = NULL;
+-	uint w;
+-	uint intr_val = 0;
+-	bool fast = false;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (coreidx >= SI_MAXCORES)
+-		return 0;
+-
+-	if (sih->bustype == SI_BUS) {
+-		/* If internal bus, we can always get at everything */
+-		fast = true;
+-		/* map if does not exist */
+-		if (!sii->regs[coreidx]) {
+-			sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+-						     SI_CORE_SIZE);
+-		}
+-		r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
+-	} else if (sih->bustype == PCI_BUS) {
+-		/*
+-		 * If pci/pcie, we can get at pci/pcie regs
+-		 * and on newer cores to chipc
+-		 */
+-		if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+-			/* Chipc registers are mapped at 12KB */
+-
+-			fast = true;
+-			r = (u32 *) ((char *)sii->curmap +
+-					PCI_16KB0_CCREGS_OFFSET + regoff);
+-		} else if (sii->pub.buscoreidx == coreidx) {
+-			/*
+-			 * pci registers are at either in the last 2KB of
+-			 * an 8KB window or, in pcie and pci rev 13 at 8KB
+-			 */
+-			fast = true;
+-			if (SI_FAST(sii))
+-				r = (u32 *) ((char *)sii->curmap +
+-						PCI_16KB0_PCIREGS_OFFSET +
+-						regoff);
+-			else
+-				r = (u32 *) ((char *)sii->curmap +
+-						((regoff >= SBCONFIGOFF) ?
+-						 PCI_BAR0_PCISBR_OFFSET :
+-						 PCI_BAR0_PCIREGS_OFFSET) +
+-						regoff);
+-		}
+-	}
+-
+-	if (!fast) {
+-		INTR_OFF(sii, intr_val);
+-
+-		/* save current core index */
+-		origidx = ai_coreidx(&sii->pub);
+-
+-		/* switch core */
+-		r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
+-				+ regoff);
+-	}
+-
+-	/* mask and set */
+-	if (mask || val) {
+-		w = (R_REG(r) & ~mask) | val;
+-		W_REG(r, w);
+-	}
+-
+-	/* readback */
+-	w = R_REG(r);
+-
+-	if (!fast) {
+-		/* restore core index */
+-		if (origidx != coreidx)
+-			ai_setcoreidx(&sii->pub, origidx);
+-
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-
+-	return w;
+-}
+-
+-void ai_core_disable(si_t *sih, u32 bits)
+-{
+-	si_info_t *sii;
+-	u32 dummy;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-
+-	ai = sii->curwrap;
+-
+-	/* if core is already in reset, just return */
+-	if (R_REG(&ai->resetctrl) & AIRC_RESET)
+-		return;
+-
+-	W_REG(&ai->ioctrl, bits);
+-	dummy = R_REG(&ai->ioctrl);
+-	udelay(10);
+-
+-	W_REG(&ai->resetctrl, AIRC_RESET);
+-	udelay(1);
+-}
+-
+-/* reset and re-enable a core
+- * inputs:
+- * bits - core specific bits that are set during and after reset sequence
+- * resetbits - core specific bits that are set only during reset sequence
+- */
+-void ai_core_reset(si_t *sih, u32 bits, u32 resetbits)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 dummy;
+-
+-	sii = SI_INFO(sih);
+-	ai = sii->curwrap;
+-
+-	/*
+-	 * Must do the disable sequence first to work
+-	 * for arbitrary current core state.
+-	 */
+-	ai_core_disable(sih, (bits | resetbits));
+-
+-	/*
+-	 * Now do the initialization sequence.
+-	 */
+-	W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+-	dummy = R_REG(&ai->ioctrl);
+-	W_REG(&ai->resetctrl, 0);
+-	udelay(1);
+-
+-	W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
+-	dummy = R_REG(&ai->ioctrl);
+-	udelay(1);
+-}
+-
+-/* return the slow clock source - LPO, XTAL, or PCI */
+-static uint ai_slowclk_src(si_info_t *sii)
+-{
+-	chipcregs_t *cc;
+-	u32 val;
+-
+-	if (sii->pub.ccrev < 6) {
+-		if (sii->pub.bustype == PCI_BUS) {
+-			pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
+-					      &val);
+-			if (val & PCI_CFG_GPIO_SCS)
+-				return SCC_SS_PCI;
+-		}
+-		return SCC_SS_XTAL;
+-	} else if (sii->pub.ccrev < 10) {
+-		cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
+-		return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
+-	} else			/* Insta-clock */
+-		return SCC_SS_XTAL;
+-}
+-
+-/*
+-* return the ILP (slowclock) min or max frequency
+-* precondition: we've established the chip has dynamic clk control
+-*/
+-static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+-{
+-	u32 slowclk;
+-	uint div;
+-
+-	slowclk = ai_slowclk_src(sii);
+-	if (sii->pub.ccrev < 6) {
+-		if (slowclk == SCC_SS_PCI)
+-			return max_freq ? (PCIMAXFREQ / 64)
+-				: (PCIMINFREQ / 64);
+-		else
+-			return max_freq ? (XTALMAXFREQ / 32)
+-				: (XTALMINFREQ / 32);
+-	} else if (sii->pub.ccrev < 10) {
+-		div = 4 *
+-		    (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
+-		      SCC_CD_SHIFT) + 1);
+-		if (slowclk == SCC_SS_LPO)
+-			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
+-		else if (slowclk == SCC_SS_XTAL)
+-			return max_freq ? (XTALMAXFREQ / div)
+-				: (XTALMINFREQ / div);
+-		else if (slowclk == SCC_SS_PCI)
+-			return max_freq ? (PCIMAXFREQ / div)
+-				: (PCIMINFREQ / div);
+-	} else {
+-		/* Chipc rev 10 is InstaClock */
+-		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+-		div = 4 * (div + 1);
+-		return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
+-	}
+-	return 0;
+-}
+-
+-static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs)
+-{
+-	chipcregs_t *cc = (chipcregs_t *) chipcregs;
+-	uint slowmaxfreq, pll_delay, slowclk;
+-	uint pll_on_delay, fref_sel_delay;
+-
+-	pll_delay = PLL_DELAY;
+-
+-	/*
+-	 * If the slow clock is not sourced by the xtal then
+-	 * add the xtal_on_delay since the xtal will also be
+-	 * powered down by dynamic clk control logic.
+-	 */
+-
+-	slowclk = ai_slowclk_src(sii);
+-	if (slowclk != SCC_SS_XTAL)
+-		pll_delay += XTAL_ON_DELAY;
+-
+-	/* Starting with 4318 it is ILP that is used for the delays */
+-	slowmaxfreq =
+-	    ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
+-
+-	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+-	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+-
+-	W_REG(&cc->pll_on_delay, pll_on_delay);
+-	W_REG(&cc->fref_sel_delay, fref_sel_delay);
+-}
+-
+-/* initialize power control delay registers */
+-void ai_clkctl_init(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	bool fast;
+-
+-	if (!CCCTL_ENAB(sih))
+-		return;
+-
+-	sii = SI_INFO(sih);
+-	fast = SI_FAST(sii);
+-	if (!fast) {
+-		origidx = sii->curidx;
+-		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-		if (cc == NULL)
+-			return;
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			return;
+-	}
+-
+-	/* set all Instaclk chip ILP to 1 MHz */
+-	if (sih->ccrev >= 10)
+-		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
+-			(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+-
+-	ai_clkctl_setdelay(sii, (void *)cc);
+-
+-	if (!fast)
+-		ai_setcoreidx(sih, origidx);
+-}
+-
+-/*
+- * return the value suitable for writing to the
+- * dot11 core FAST_PWRUP_DELAY register
+- */
+-u16 ai_clkctl_fast_pwrup_delay(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	uint slowminfreq;
+-	u16 fpdelay;
+-	uint intr_val = 0;
+-	bool fast;
+-
+-	sii = SI_INFO(sih);
+-	if (PMUCTL_ENAB(sih)) {
+-		INTR_OFF(sii, intr_val);
+-		fpdelay = si_pmu_fast_pwrup_delay(sih);
+-		INTR_RESTORE(sii, intr_val);
+-		return fpdelay;
+-	}
+-
+-	if (!CCCTL_ENAB(sih))
+-		return 0;
+-
+-	fast = SI_FAST(sii);
+-	fpdelay = 0;
+-	if (!fast) {
+-		origidx = sii->curidx;
+-		INTR_OFF(sii, intr_val);
+-		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-		if (cc == NULL)
+-			goto done;
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			goto done;
+-	}
+-
+-	slowminfreq = ai_slowclk_freq(sii, false, cc);
+-	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
+-		   (slowminfreq - 1)) / slowminfreq;
+-
+- done:
+-	if (!fast) {
+-		ai_setcoreidx(sih, origidx);
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-	return fpdelay;
+-}
+-
+-/* turn primary xtal and/or pll off/on */
+-int ai_clkctl_xtal(si_t *sih, uint what, bool on)
+-{
+-	si_info_t *sii;
+-	u32 in, out, outen;
+-
+-	sii = SI_INFO(sih);
+-
+-	switch (sih->bustype) {
+-
+-	case PCI_BUS:
+-		/* pcie core doesn't have any mapping to control the xtal pu */
+-		if (PCIE(sii))
+-			return -1;
+-
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
+-
+-		/*
+-		 * Avoid glitching the clock if GPRS is already using it.
+-		 * We can't actually read the state of the PLLPD so we infer it
+-		 * by the value of XTAL_PU which *is* readable via gpioin.
+-		 */
+-		if (on && (in & PCI_CFG_GPIO_XTAL))
+-			return 0;
+-
+-		if (what & XTAL)
+-			outen |= PCI_CFG_GPIO_XTAL;
+-		if (what & PLL)
+-			outen |= PCI_CFG_GPIO_PLL;
+-
+-		if (on) {
+-			/* turn primary xtal on */
+-			if (what & XTAL) {
+-				out |= PCI_CFG_GPIO_XTAL;
+-				if (what & PLL)
+-					out |= PCI_CFG_GPIO_PLL;
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUT, out);
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUTEN, outen);
+-				udelay(XTAL_ON_DELAY);
+-			}
+-
+-			/* turn pll on */
+-			if (what & PLL) {
+-				out &= ~PCI_CFG_GPIO_PLL;
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUT, out);
+-				mdelay(2);
+-			}
+-		} else {
+-			if (what & XTAL)
+-				out &= ~PCI_CFG_GPIO_XTAL;
+-			if (what & PLL)
+-				out |= PCI_CFG_GPIO_PLL;
+-			pci_write_config_dword(sii->pbus,
+-					       PCI_GPIO_OUT, out);
+-			pci_write_config_dword(sii->pbus,
+-					       PCI_GPIO_OUTEN, outen);
+-		}
+-
+-	default:
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- *  clock control policy function throught chipcommon
+- *
+- *    set dynamic clk control mode (forceslow, forcefast, dynamic)
+- *    returns true if we are forcing fast clock
+- *    this is a wrapper over the next internal function
+- *      to allow flexible policy settings for outside caller
+- */
+-bool ai_clkctl_cc(si_t *sih, uint mode)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+-	if (sih->ccrev < 6)
+-		return false;
+-
+-	if (PCI_FORCEHT(sii))
+-		return mode == CLK_FAST;
+-
+-	return _ai_clkctl_cc(sii, mode);
+-}
+-
+-/* clk control mechanism through chipcommon, no policy checking */
+-static bool _ai_clkctl_cc(si_info_t *sii, uint mode)
+-{
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	u32 scc;
+-	uint intr_val = 0;
+-	bool fast = SI_FAST(sii);
+-
+-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+-	if (sii->pub.ccrev < 6)
+-		return false;
+-
+-	if (!fast) {
+-		INTR_OFF(sii, intr_val);
+-		origidx = sii->curidx;
+-
+-		if ((sii->pub.bustype == SI_BUS) &&
+-		    ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
+-		    (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
+-			goto done;
+-
+-		cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			goto done;
+-	}
+-
+-	if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
+-		goto done;
+-
+-	switch (mode) {
+-	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
+-		if (sii->pub.ccrev < 10) {
+-			/*
+-			 * don't forget to force xtal back
+-			 * on before we clear SCC_DYN_XTAL..
+-			 */
+-			ai_clkctl_xtal(&sii->pub, XTAL, ON);
+-			SET_REG(&cc->slow_clk_ctl,
+-				(SCC_XC | SCC_FS | SCC_IP), SCC_IP);
+-		} else if (sii->pub.ccrev < 20) {
+-			OR_REG(&cc->system_clk_ctl, SYCC_HR);
+-		} else {
+-			OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
+-		}
+-
+-		/* wait for the PLL */
+-		if (PMUCTL_ENAB(&sii->pub)) {
+-			u32 htavail = CCS_HTAVAIL;
+-			SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
+-				  == 0), PMU_MAX_TRANSITION_DLY);
+-		} else {
+-			udelay(PLL_DELAY);
+-		}
+-		break;
+-
+-	case CLK_DYNAMIC:	/* enable dynamic clock control */
+-		if (sii->pub.ccrev < 10) {
+-			scc = R_REG(&cc->slow_clk_ctl);
+-			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
+-			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
+-				scc |= SCC_XC;
+-			W_REG(&cc->slow_clk_ctl, scc);
+-
+-			/*
+-			 * for dynamic control, we have to
+-			 * release our xtal_pu "force on"
+-			 */
+-			if (scc & SCC_XC)
+-				ai_clkctl_xtal(&sii->pub, XTAL, OFF);
+-		} else if (sii->pub.ccrev < 20) {
+-			/* Instaclock */
+-			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
+-		} else {
+-			AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
+-		}
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+- done:
+-	if (!fast) {
+-		ai_setcoreidx(&sii->pub, origidx);
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-	return mode == CLK_FAST;
+-}
+-
+-/* Build device path. Support SI, PCI, and JTAG for now. */
+-int ai_devpath(si_t *sih, char *path, int size)
+-{
+-	int slen;
+-
+-	if (!path || size <= 0)
+-		return -1;
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
+-		break;
+-	case PCI_BUS:
+-		slen = snprintf(path, (size_t) size, "pci/%u/%u/",
+-			((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
+-			PCI_SLOT(
+-			    ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
+-		break;
+-
+-	default:
+-		slen = -1;
+-		break;
+-	}
+-
+-	if (slen < 0 || slen >= size) {
+-		path[0] = '\0';
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-/* Get a variable, but only if it has a devpath prefix */
+-char *ai_getdevpathvar(si_t *sih, const char *name)
+-{
+-	char varname[SI_DEVPATH_BUFSZ + 32];
+-
+-	ai_devpathvar(sih, varname, sizeof(varname), name);
+-
+-	return getvar(NULL, varname);
+-}
+-
+-/* Get a variable, but only if it has a devpath prefix */
+-int ai_getdevpathintvar(si_t *sih, const char *name)
+-{
+-#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
+-	return getintvar(NULL, name);
+-#else
+-	char varname[SI_DEVPATH_BUFSZ + 32];
+-
+-	ai_devpathvar(sih, varname, sizeof(varname), name);
+-
+-	return getintvar(NULL, varname);
+-#endif
+-}
+-
+-char *ai_getnvramflvar(si_t *sih, const char *name)
+-{
+-	return getvar(NULL, name);
+-}
+-
+-/* Concatenate the dev path with a varname into the given 'var' buffer
+- * and return the 'var' pointer. Nothing is done to the arguments if
+- * len == 0 or var is NULL, var is still returned. On overflow, the
+- * first char will be set to '\0'.
+- */
+-static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name)
+-{
+-	uint path_len;
+-
+-	if (!var || len <= 0)
+-		return var;
+-
+-	if (ai_devpath(sih, var, len) == 0) {
+-		path_len = strlen(var);
+-
+-		if (strlen(name) + 1 > (uint) (len - path_len))
+-			var[0] = '\0';
+-		else
+-			strncpy(var + path_len, name, len - path_len - 1);
+-	}
+-
+-	return var;
+-}
+-
+-/* return true if PCIE capability exists in the pci config space */
+-static __used bool ai_ispcie(si_info_t *sii)
+-{
+-	u8 cap_ptr;
+-
+-	if (sii->pub.bustype != PCI_BUS)
+-		return false;
+-
+-	cap_ptr =
+-	    pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
+-					NULL);
+-	if (!cap_ptr)
+-		return false;
+-
+-	return true;
+-}
+-
+-bool ai_pci_war16165(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	return PCI(sii) && (sih->buscorerev <= 10);
+-}
+-
+-void ai_pci_up(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* if not pci bus, we're done */
+-	if (sih->bustype != PCI_BUS)
+-		return;
+-
+-	if (PCI_FORCEHT(sii))
+-		_ai_clkctl_cc(sii, CLK_FAST);
+-
+-	if (PCIE(sii))
+-		pcicore_up(sii->pch, SI_PCIUP);
+-
+-}
+-
+-/* Unconfigure and/or apply various WARs when system is going to sleep mode */
+-void ai_pci_sleep(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	pcicore_sleep(sii->pch);
+-}
+-
+-/* Unconfigure and/or apply various WARs when going down */
+-void ai_pci_down(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* if not pci bus, we're done */
+-	if (sih->bustype != PCI_BUS)
+-		return;
+-
+-	/* release FORCEHT since chip is going to "down" state */
+-	if (PCI_FORCEHT(sii))
+-		_ai_clkctl_cc(sii, CLK_DYNAMIC);
+-
+-	pcicore_down(sii->pch, SI_PCIDOWN);
+-}
+-
+-/*
+- * Configure the pci core for pci client (NIC) action
+- * coremask is the bitvec of cores by index to be enabled.
+- */
+-void ai_pci_setup(si_t *sih, uint coremask)
+-{
+-	si_info_t *sii;
+-	struct sbpciregs *pciregs = NULL;
+-	u32 siflag = 0, w;
+-	uint idx = 0;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (sii->pub.bustype != PCI_BUS)
+-		return;
+-
+-	if (PCI(sii)) {
+-		/* get current core index */
+-		idx = sii->curidx;
+-
+-		/* we interrupt on this backplane flag number */
+-		siflag = ai_flag(sih);
+-
+-		/* switch over to pci core */
+-		pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx);
+-	}
+-
+-	/*
+-	 * Enable sb->pci interrupts.  Assume
+-	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
+-	 */
+-	if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
+-		/* pci config write to set this core bit in PCIIntMask */
+-		pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
+-		w |= (coremask << PCI_SBIM_SHIFT);
+-		pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
+-	} else {
+-		/* set sbintvec bit for our flag number */
+-		ai_setint(sih, siflag);
+-	}
+-
+-	if (PCI(sii)) {
+-		OR_REG(&pciregs->sbtopci2,
+-		       (SBTOPCI_PREF | SBTOPCI_BURST));
+-		if (sii->pub.buscorerev >= 11) {
+-			OR_REG(&pciregs->sbtopci2,
+-			       SBTOPCI_RC_READMULTI);
+-			w = R_REG(&pciregs->clkrun);
+-			W_REG(&pciregs->clkrun,
+-			      (w | PCI_CLKRUN_DSBL));
+-			w = R_REG(&pciregs->clkrun);
+-		}
+-
+-		/* switch back to previous core */
+-		ai_setcoreidx(sih, idx);
+-	}
+-}
+-
+-/*
+- * Fixup SROMless PCI device's configuration.
+- * The current core may be changed upon return.
+- */
+-int ai_pci_fixcfg(si_t *sih)
+-{
+-	uint origidx, pciidx;
+-	struct sbpciregs *pciregs = NULL;
+-	sbpcieregs_t *pcieregs = NULL;
+-	void *regs = NULL;
+-	u16 val16, *reg16 = NULL;
+-
+-	si_info_t *sii = SI_INFO(sih);
+-
+-	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
+-	/* save the current index */
+-	origidx = ai_coreidx(&sii->pub);
+-
+-	/* check 'pi' is correct and fix it if not */
+-	if (sii->pub.buscoretype == PCIE_CORE_ID) {
+-		pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0);
+-		regs = pcieregs;
+-		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
+-	} else if (sii->pub.buscoretype == PCI_CORE_ID) {
+-		pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0);
+-		regs = pciregs;
+-		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
+-	}
+-	pciidx = ai_coreidx(&sii->pub);
+-	val16 = R_REG(reg16);
+-	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) {
+-		val16 =
+-		    (u16) (pciidx << SRSH_PI_SHIFT) | (val16 &
+-							  ~SRSH_PI_MASK);
+-		W_REG(reg16, val16);
+-	}
+-
+-	/* restore the original index */
+-	ai_setcoreidx(&sii->pub, origidx);
+-
+-	pcicore_hwup(sii->pch);
+-	return 0;
+-}
+-
+-/* mask&set gpiocontrol bits */
+-u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
+-{
+-	uint regoff;
+-
+-	regoff = 0;
+-
+-	/* gpios could be shared on router platforms
+-	 * ignore reservation if it's high priority (e.g., test apps)
+-	 */
+-	if ((priority != GPIO_HI_PRIORITY) &&
+-	    (sih->bustype == SI_BUS) && (val || mask)) {
+-		mask = priority ? (ai_gpioreservation & mask) :
+-		    ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
+-		val &= mask;
+-	}
+-
+-	regoff = offsetof(chipcregs_t, gpiocontrol);
+-	return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
+-}
+-
+-void ai_chipcontrl_epa4331(si_t *sih, bool on)
+-{
+-	si_info_t *sii;
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 val;
+-
+-	sii = SI_INFO(sih);
+-	origidx = ai_coreidx(sih);
+-
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-
+-	val = R_REG(&cc->chipcontrol);
+-
+-	if (on) {
+-		if (sih->chippkg == 9 || sih->chippkg == 0xb) {
+-			/* Ext PA Controls for 4331 12x9 Package */
+-			W_REG(&cc->chipcontrol, val |
+-			      (CCTRL4331_EXTPA_EN |
+-			       CCTRL4331_EXTPA_ON_GPIO2_5));
+-		} else {
+-			/* Ext PA Controls for 4331 12x12 Package */
+-			W_REG(&cc->chipcontrol,
+-			      val | (CCTRL4331_EXTPA_EN));
+-		}
+-	} else {
+-		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+-		W_REG(&cc->chipcontrol, val);
+-	}
+-
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* Enable BT-COEX & Ex-PA for 4313 */
+-void ai_epa_4313war(si_t *sih)
+-{
+-	si_info_t *sii;
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	sii = SI_INFO(sih);
+-	origidx = ai_coreidx(sih);
+-
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-
+-	/* EPA Fix */
+-	W_REG(&cc->gpiocontrol,
+-	      R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
+-
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* check if the device is removed */
+-bool ai_deviceremoved(si_t *sih)
+-{
+-	u32 w;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	switch (sih->bustype) {
+-	case PCI_BUS:
+-		pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
+-		if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
+-			return true;
+-		break;
+-	}
+-	return false;
+-}
+-
+-bool ai_is_sprom_available(si_t *sih)
+-{
+-	if (sih->ccrev >= 31) {
+-		si_info_t *sii;
+-		uint origidx;
+-		chipcregs_t *cc;
+-		u32 sromctrl;
+-
+-		if ((sih->cccaps & CC_CAP_SROM) == 0)
+-			return false;
+-
+-		sii = SI_INFO(sih);
+-		origidx = sii->curidx;
+-		cc = ai_setcoreidx(sih, SI_CC_IDX);
+-		sromctrl = R_REG(&cc->sromcontrol);
+-		ai_setcoreidx(sih, origidx);
+-		return sromctrl & SRC_PRESENT;
+-	}
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return (sih->chipst & CST4329_SPROM_SEL) != 0;
+-	case BCM4319_CHIP_ID:
+-		return (sih->chipst & CST4319_SPROM_SEL) != 0;
+-	case BCM4336_CHIP_ID:
+-		return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+-	case BCM4330_CHIP_ID:
+-		return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+-	case BCM4313_CHIP_ID:
+-		return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+-	case BCM4331_CHIP_ID:
+-		return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
+-	default:
+-		return true;
+-	}
+-}
+-
+-bool ai_is_otp_disabled(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
+-		    CST4329_OTP_PWRDN;
+-	case BCM4319_CHIP_ID:
+-		return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
+-		    CST4319_OTP_PWRDN;
+-	case BCM4336_CHIP_ID:
+-		return (sih->chipst & CST4336_OTP_PRESENT) == 0;
+-	case BCM4330_CHIP_ID:
+-		return (sih->chipst & CST4330_OTP_PRESENT) == 0;
+-	case BCM4313_CHIP_ID:
+-		return (sih->chipst & CST4313_OTP_PRESENT) == 0;
+-		/* These chips always have their OTP on */
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	default:
+-		return false;
+-	}
+-}
+-
+-bool ai_is_otp_powered(si_t *sih)
+-{
+-	if (PMUCTL_ENAB(sih))
+-		return si_pmu_is_otp_powered(sih);
+-	return true;
+-}
+-
+-void ai_otp_power(si_t *sih, bool on)
+-{
+-	if (PMUCTL_ENAB(sih))
+-		si_pmu_otp_power(sih, on);
+-	udelay(1000);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h
+deleted file mode 100644
+index b98099e..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/aiutils.h
++++ /dev/null
+@@ -1,546 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_aiutils_h_
+-#define	_aiutils_h_
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* Include the soci specific files */
+-#include <aidmp.h>
+-
+-/*
+- * SOC Interconnect Address Map.
+- * All regions may not exist on all chips.
+- */
+-/* Physical SDRAM */
+-#define SI_SDRAM_BASE		0x00000000
+-/* Host Mode sb2pcitranslation0 (64 MB) */
+-#define SI_PCI_MEM		0x08000000
+-#define SI_PCI_MEM_SZ		(64 * 1024 * 1024)
+-/* Host Mode sb2pcitranslation1 (64 MB) */
+-#define SI_PCI_CFG		0x0c000000
+-/* Byteswapped Physical SDRAM */
+-#define	SI_SDRAM_SWAPPED	0x10000000
+-/* Region 2 for sdram (512 MB) */
+-#define SI_SDRAM_R2		0x80000000
+-
+-#ifdef SI_ENUM_BASE_VARIABLE
+-#define SI_ENUM_BASE		(sii->pub.si_enum_base)
+-#else
+-#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
+-#endif				/* SI_ENUM_BASE_VARIABLE */
+-
+-/* Wrapper space base */
+-#define SI_WRAP_BASE		0x18100000
+-/* each core gets 4Kbytes for registers */
+-#define SI_CORE_SIZE		0x1000
+-/*
+- * Max cores (this is arbitrary, for software
+- * convenience and could be changed if we
+- * make any larger chips
+- */
+-#define	SI_MAXCORES		16
+-
+-/* On-chip RAM on chips that also have DDR */
+-#define	SI_FASTRAM		0x19000000
+-#define	SI_FASTRAM_SWAPPED	0x19800000
+-
+-/* Flash Region 2 (region 1 shadowed here) */
+-#define	SI_FLASH2		0x1c000000
+-/* Size of Flash Region 2 */
+-#define	SI_FLASH2_SZ		0x02000000
+-/* ARM Cortex-M3 ROM */
+-#define	SI_ARMCM3_ROM		0x1e000000
+-/* MIPS Flash Region 1 */
+-#define	SI_FLASH1		0x1fc00000
+-/* MIPS Size of Flash Region 1 */
+-#define	SI_FLASH1_SZ		0x00400000
+-/* ARM7TDMI-S ROM */
+-#define	SI_ARM7S_ROM		0x20000000
+-/* ARM Cortex-M3 SRAM Region 2 */
+-#define	SI_ARMCM3_SRAM2		0x60000000
+-/* ARM7TDMI-S SRAM Region 2 */
+-#define	SI_ARM7S_SRAM2		0x80000000
+-/* ARM Flash Region 1 */
+-#define	SI_ARM_FLASH1		0xffff0000
+-/* ARM Size of Flash Region 1 */
+-#define	SI_ARM_FLASH1_SZ	0x00010000
+-
+-/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA		0x40000000
+-/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA2		0x80000000
+-/* Client Mode sb2pcitranslation2 size in bytes */
+-#define SI_PCI_DMA_SZ		0x40000000
+-/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
+-#define SI_PCIE_DMA_L32		0x00000000
+-/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
+-#define SI_PCIE_DMA_H32		0x80000000
+-
+-/* core codes */
+-#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
+-#define	CC_CORE_ID		0x800	/* chipcommon core */
+-#define	ILINE20_CORE_ID		0x801	/* iline20 core */
+-#define	SRAM_CORE_ID		0x802	/* sram core */
+-#define	SDRAM_CORE_ID		0x803	/* sdram core */
+-#define	PCI_CORE_ID		0x804	/* pci core */
+-#define	MIPS_CORE_ID		0x805	/* mips core */
+-#define	ENET_CORE_ID		0x806	/* enet mac core */
+-#define	CODEC_CORE_ID		0x807	/* v90 codec core */
+-#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
+-#define	ADSL_CORE_ID		0x809	/* ADSL core */
+-#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
+-#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
+-#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
+-#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
+-#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
+-#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
+-#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
+-#define	EXTIF_CORE_ID		0x811	/* external interface core */
+-#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
+-#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
+-#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
+-#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
+-#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
+-#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
+-#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
+-#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
+-#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
+-#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
+-#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
+-#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
+-#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
+-#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
+-#define	PCIE_CORE_ID		0x820	/* pci express core */
+-#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
+-#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
+-#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
+-#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
+-#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
+-#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
+-#define	PMU_CORE_ID		0x827	/* PMU core */
+-#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
+-#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
+-#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
+-#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
+-#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
+-#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
+-#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
+-#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
+-#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
+-#define	SC_CORE_ID		0x831	/* shared common core */
+-#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
+-#define	SPIH_CORE_ID		0x833	/* SPI host core */
+-#define	I2S_CORE_ID		0x834	/* I2S core */
+-#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
+-#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
+-#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
+-#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
+-					 * maps all unused address ranges
+-					 */
+-
+-/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+- * and chipcommon being the first core:
+- */
+-#define	SI_CC_IDX		0
+-
+-/* SOC Interconnect types (aka chip types) */
+-#define	SOCI_AI			1
+-
+-/* Common core control flags */
+-#define	SICF_BIST_EN		0x8000
+-#define	SICF_PME_EN		0x4000
+-#define	SICF_CORE_BITS		0x3ffc
+-#define	SICF_FGC		0x0002
+-#define	SICF_CLOCK_EN		0x0001
+-
+-/* Common core status flags */
+-#define	SISF_BIST_DONE		0x8000
+-#define	SISF_BIST_ERROR		0x4000
+-#define	SISF_GATED_CLK		0x2000
+-#define	SISF_DMA64		0x1000
+-#define	SISF_CORE_BITS		0x0fff
+-
+-/* A register that is common to all cores to
+- * communicate w/PMU regarding clock control.
+- */
+-#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
+-
+-/* clk_ctl_st register */
+-#define	CCS_FORCEALP		0x00000001	/* force ALP request */
+-#define	CCS_FORCEHT		0x00000002	/* force HT request */
+-#define	CCS_FORCEILP		0x00000004	/* force ILP request */
+-#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
+-#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
+-#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
+-#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
+-#define CCS_ERSRC_REQ_SHIFT	8
+-#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
+-#define	CCS_HTAVAIL		0x00020000	/* HT is available */
+-#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
+-#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
+-#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
+-#define CCS_ERSRC_STS_SHIFT	24
+-
+-/* HT avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_HTAVAIL		0x00010000
+-/* ALP avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_ALPAVAIL		0x00020000
+-
+-/* Not really related to SOC Interconnect, but a couple of software
+- * conventions for the use the flash space:
+- */
+-
+-/* Minumum amount of flash we support */
+-#define FLASH_MIN		0x00020000	/* Minimum flash size */
+-
+-/* A boot/binary may have an embedded block that describes its size  */
+-#define	BISZ_OFFSET		0x3e0	/* At this offset into the binary */
+-#define	BISZ_MAGIC		0x4249535a	/* Marked with value: 'BISZ' */
+-#define	BISZ_MAGIC_IDX		0	/* Word 0: magic */
+-#define	BISZ_TXTST_IDX		1	/*      1: text start */
+-#define	BISZ_TXTEND_IDX		2	/*      2: text end */
+-#define	BISZ_DATAST_IDX		3	/*      3: data start */
+-#define	BISZ_DATAEND_IDX	4	/*      4: data end */
+-#define	BISZ_BSSST_IDX		5	/*      5: bss start */
+-#define	BISZ_BSSEND_IDX		6	/*      6: bss end */
+-#define BISZ_SIZE		7	/* descriptor size in 32-bit integers */
+-
+-#define	SI_INFO(sih)	(si_info_t *)sih
+-
+-#define	GOODCOREADDR(x, b) \
+-	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
+-		IS_ALIGNED((x), SI_CORE_SIZE))
+-#define	GOODREGS(regs) \
+-	((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
+-#define BADCOREADDR	0
+-#define	GOODIDX(idx)	(((uint)idx) < SI_MAXCORES)
+-#define	NOREV		-1	/* Invalid rev */
+-
+-/* Newer chips can access PCI/PCIE and CC core without requiring to change
+- * PCI BAR0 WIN
+- */
+-#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) ||	\
+-		     (((si)->pub.buscoretype == PCI_CORE_ID) && \
+-		      (si)->pub.buscorerev >= 13))
+-
+-#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
+-#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
+-
+-/*
+- * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
+- * before after core switching to avoid invalid register accesss inside ISR.
+- */
+-#define INTR_OFF(si, intr_val) \
+-	if ((si)->intrsoff_fn && \
+-	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+-		intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
+-#define INTR_RESTORE(si, intr_val) \
+-	if ((si)->intrsrestore_fn && \
+-	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+-		(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
+-
+-/* dynamic clock control defines */
+-#define	LPOMINFREQ		25000	/* low power oscillator min */
+-#define	LPOMAXFREQ		43000	/* low power oscillator max */
+-#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
+-#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
+-#define	PCIMINFREQ		25000000	/* 25 MHz */
+-#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
+-
+-#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
+-#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
+-
+-#define PCI(si)		(((si)->pub.bustype == PCI_BUS) &&	\
+-			 ((si)->pub.buscoretype == PCI_CORE_ID))
+-#define PCIE(si)	(((si)->pub.bustype == PCI_BUS) &&	\
+-			 ((si)->pub.buscoretype == PCIE_CORE_ID))
+-#define PCI_FORCEHT(si)	\
+-	(PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
+-
+-/* GPIO Based LED powersave defines */
+-#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
+-#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
+-
+-#ifndef DEFAULT_GPIOTIMERVAL
+-#define DEFAULT_GPIOTIMERVAL \
+-	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
+-#endif
+-
+-/*
+- * Data structure to export all chip specific common variables
+- *   public (read-only) portion of aiutils handle returned by si_attach()
+- */
+-struct si_pub {
+-	uint bustype;		/* SI_BUS, PCI_BUS */
+-	uint buscoretype;	/* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+-	uint buscorerev;	/* buscore rev */
+-	uint buscoreidx;	/* buscore index */
+-	int ccrev;		/* chip common core rev */
+-	u32 cccaps;		/* chip common capabilities */
+-	u32 cccaps_ext;	/* chip common capabilities extension */
+-	int pmurev;		/* pmu core rev */
+-	u32 pmucaps;		/* pmu capabilities */
+-	uint boardtype;		/* board type */
+-	uint boardvendor;	/* board vendor */
+-	uint boardflags;	/* board flags */
+-	uint boardflags2;	/* board flags2 */
+-	uint chip;		/* chip number */
+-	uint chiprev;		/* chip revision */
+-	uint chippkg;		/* chip package option */
+-	u32 chipst;		/* chip status */
+-	bool issim;		/* chip is in simulation or emulation */
+-	uint socirev;		/* SOC interconnect rev */
+-	bool pci_pr32414;
+-
+-};
+-
+-/*
+- * for HIGH_ONLY driver, the si_t must be writable to allow states sync from
+- * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident
+- * change
+- */
+-typedef const struct si_pub si_t;
+-
+-/*
+- * Many of the routines below take an 'sih' handle as their first arg.
+- * Allocate this by calling si_attach().  Free it by calling si_detach().
+- * At any one time, the sih is logically focused on one particular si core
+- * (the "current core").
+- * Use si_setcore() or si_setcoreidx() to change the association to another core
+- */
+-
+-#define	BADIDX		(SI_MAXCORES + 1)
+-
+-/* clkctl xtal what flags */
+-#define	XTAL			0x1	/* primary crystal oscillator (2050) */
+-#define	PLL			0x2	/* main chip pll */
+-
+-/* clkctl clk mode */
+-#define	CLK_FAST		0	/* force fast (pll) clock */
+-#define	CLK_DYNAMIC		2	/* enable dynamic clock control */
+-
+-/* GPIO usage priorities */
+-#define GPIO_DRV_PRIORITY	0	/* Driver */
+-#define GPIO_APP_PRIORITY	1	/* Application */
+-#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
+-					 * reservation
+-					 */
+-
+-/* GPIO pull up/down */
+-#define GPIO_PULLUP		0
+-#define GPIO_PULLDN		1
+-
+-/* GPIO event regtype */
+-#define GPIO_REGEVT		0	/* GPIO register event */
+-#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
+-#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
+-
+-/* device path */
+-#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
+-
+-/* SI routine enumeration: to be used by update function with multiple hooks */
+-#define	SI_DOATTACH	1
+-#define SI_PCIDOWN	2
+-#define SI_PCIUP	3
+-
+-#define	ISSIM_ENAB(sih)	0
+-
+-/* PMU clock/power control */
+-#if defined(BCMPMUCTL)
+-#define PMUCTL_ENAB(sih)	(BCMPMUCTL)
+-#else
+-#define PMUCTL_ENAB(sih)	((sih)->cccaps & CC_CAP_PMU)
+-#endif
+-
+-/* chipcommon clock/power control (exclusive with PMU's) */
+-#if defined(BCMPMUCTL) && BCMPMUCTL
+-#define CCCTL_ENAB(sih)		(0)
+-#define CCPLL_ENAB(sih)		(0)
+-#else
+-#define CCCTL_ENAB(sih)		((sih)->cccaps & CC_CAP_PWR_CTL)
+-#define CCPLL_ENAB(sih)		((sih)->cccaps & CC_CAP_PLL_MASK)
+-#endif
+-
+-typedef void (*gpio_handler_t) (u32 stat, void *arg);
+-
+-/* External PA enable mask */
+-#define GPIO_CTRL_EPA_EN_MASK 0x40
+-
+-#define	SI_ERROR(args)
+-
+-#ifdef BCMDBG
+-#define	SI_MSG(args)	printk args
+-#else
+-#define	SI_MSG(args)
+-#endif				/* BCMDBG */
+-
+-/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
+-#define	SI_VMSG(args)
+-
+-#define	IS_SIM(chippkg)	\
+-	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
+-
+-typedef u32(*si_intrsoff_t) (void *intr_arg);
+-typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
+-typedef bool(*si_intrsenabled_t) (void *intr_arg);
+-
+-typedef struct gpioh_item {
+-	void *arg;
+-	bool level;
+-	gpio_handler_t handler;
+-	u32 event;
+-	struct gpioh_item *next;
+-} gpioh_item_t;
+-
+-/* misc si info needed by some of the routines */
+-typedef struct si_info {
+-	struct si_pub pub;	/* back plane public state (must be first) */
+-	void *pbus;		/* handle to bus (pci/sdio/..) */
+-	uint dev_coreid;	/* the core provides driver functions */
+-	void *intr_arg;		/* interrupt callback function arg */
+-	si_intrsoff_t intrsoff_fn;	/* turns chip interrupts off */
+-	si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+-	si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+-
+-	void *pch;		/* PCI/E core handle */
+-
+-	gpioh_item_t *gpioh_head;	/* GPIO event handlers list */
+-
+-	bool memseg;		/* flag to toggle MEM_SEG register */
+-
+-	char *vars;
+-	uint varsz;
+-
+-	void *curmap;		/* current regs va */
+-	void *regs[SI_MAXCORES];	/* other regs va */
+-
+-	uint curidx;		/* current core index */
+-	uint numcores;		/* # discovered cores */
+-	uint coreid[SI_MAXCORES]; /* id of each core */
+-	u32 coresba[SI_MAXCORES]; /* backplane address of each core */
+-	void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
+-	u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
+-	u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
+-	u32 coresba2_size[SI_MAXCORES];	/* second address space size */
+-
+-	void *curwrap;		/* current wrapper va */
+-	void *wrappers[SI_MAXCORES];	/* other cores wrapper va */
+-	u32 wrapba[SI_MAXCORES];	/* address of controlling wrapper */
+-
+-	u32 cia[SI_MAXCORES];	/* erom cia entry for each core */
+-	u32 cib[SI_MAXCORES];	/* erom cia entry for each core */
+-	u32 oob_router;	/* oob router registers for axi */
+-} si_info_t;
+-
+-/* AMBA Interconnect exported externs */
+-extern void ai_scan(si_t *sih, void *regs, uint devid);
+-
+-extern uint ai_flag(si_t *sih);
+-extern void ai_setint(si_t *sih, int siflag);
+-extern uint ai_coreidx(si_t *sih);
+-extern uint ai_corevendor(si_t *sih);
+-extern uint ai_corerev(si_t *sih);
+-extern bool ai_iscoreup(si_t *sih);
+-extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+-extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+-extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val);
+-extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+-extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+-		       uint val);
+-extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+-extern void ai_core_disable(si_t *sih, u32 bits);
+-extern int ai_numaddrspaces(si_t *sih);
+-extern u32 ai_addrspace(si_t *sih, uint asidx);
+-extern u32 ai_addrspacesize(si_t *sih, uint asidx);
+-extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val);
+-
+-/* === exported functions === */
+-extern si_t *ai_attach(uint pcidev, void *regs, uint bustype,
+-		       void *sdh, char **vars, uint *varsz);
+-
+-extern void ai_detach(si_t *sih);
+-extern bool ai_pci_war16165(si_t *sih);
+-
+-extern uint ai_coreid(si_t *sih);
+-extern uint ai_corerev(si_t *sih);
+-extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+-		uint val);
+-extern void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val);
+-extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+-extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+-extern bool ai_iscoreup(si_t *sih);
+-extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit);
+-extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+-extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit);
+-extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx,
+-			    uint *intr_val);
+-extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val);
+-extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+-extern void ai_core_disable(si_t *sih, u32 bits);
+-extern u32 ai_alp_clock(si_t *sih);
+-extern u32 ai_ilp_clock(si_t *sih);
+-extern void ai_pci_setup(si_t *sih, uint coremask);
+-extern void ai_setint(si_t *sih, int siflag);
+-extern bool ai_backplane64(si_t *sih);
+-extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn,
+-				      void *intrsrestore_fn,
+-				      void *intrsenabled_fn, void *intr_arg);
+-extern void ai_deregister_intr_callback(si_t *sih);
+-extern void ai_clkctl_init(si_t *sih);
+-extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih);
+-extern bool ai_clkctl_cc(si_t *sih, uint mode);
+-extern int ai_clkctl_xtal(si_t *sih, uint what, bool on);
+-extern bool ai_deviceremoved(si_t *sih);
+-extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val,
+-			     u8 priority);
+-
+-/* OTP status */
+-extern bool ai_is_otp_disabled(si_t *sih);
+-extern bool ai_is_otp_powered(si_t *sih);
+-extern void ai_otp_power(si_t *sih, bool on);
+-
+-/* SPROM availability */
+-extern bool ai_is_sprom_available(si_t *sih);
+-
+-/*
+- * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
+- * The returned path is NULL terminated and has trailing '/'.
+- * Return 0 on success, nonzero otherwise.
+- */
+-extern int ai_devpath(si_t *sih, char *path, int size);
+-/* Read variable with prepending the devpath to the name */
+-extern char *ai_getdevpathvar(si_t *sih, const char *name);
+-extern int ai_getdevpathintvar(si_t *sih, const char *name);
+-
+-extern void ai_pci_sleep(si_t *sih);
+-extern void ai_pci_down(si_t *sih);
+-extern void ai_pci_up(si_t *sih);
+-extern int ai_pci_fixcfg(si_t *sih);
+-
+-extern void ai_chipcontrl_epa4331(si_t *sih, bool on);
+-/* Enable Ex-PA for 4313 */
+-extern void ai_epa_4313war(si_t *sih);
+-
+-char *ai_getnvramflvar(si_t *sih, const char *name);
+-
+-#endif				/* _aiutils_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmotp.c b/drivers/staging/brcm80211/brcmsmac/bcmotp.c
+deleted file mode 100644
+index d09628b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmotp.c
++++ /dev/null
+@@ -1,936 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/crc-ccitt.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <bcmotp.h>
+-
+-/*
+- * There are two different OTP controllers so far:
+- * 	1. new IPX OTP controller:	chipc 21, >=23
+- * 	2. older HND OTP controller:	chipc 12, 17, 22
+- *
+- * Define BCMHNDOTP to include support for the HND OTP controller.
+- * Define BCMIPXOTP to include support for the IPX OTP controller.
+- *
+- * NOTE 1: More than one may be defined
+- * NOTE 2: If none are defined, the default is to include them all.
+- */
+-
+-#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
+-#define BCMHNDOTP	1
+-#define BCMIPXOTP	1
+-#endif
+-
+-#define OTPTYPE_HND(ccrev)	((ccrev) < 21 || (ccrev) == 22)
+-#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)
+-
+-#define OTPP_TRIES	10000000	/* # of tries for OTPP */
+-
+-#ifdef BCMIPXOTP
+-#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
+-#endif
+-
+-/* OTP common function type */
+-typedef int (*otp_status_t) (void *oh);
+-typedef int (*otp_size_t) (void *oh);
+-typedef void *(*otp_init_t) (si_t *sih);
+-typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
+-typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
+-				  uint *wlen);
+-typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
+-
+-/* OTP function struct */
+-typedef struct otp_fn_s {
+-	otp_size_t size;
+-	otp_read_bit_t read_bit;
+-	otp_init_t init;
+-	otp_read_region_t read_region;
+-	otp_nvread_t nvread;
+-	otp_status_t status;
+-} otp_fn_t;
+-
+-typedef struct {
+-	uint ccrev;		/* chipc revision */
+-	otp_fn_t *fn;		/* OTP functions */
+-	si_t *sih;		/* Saved sb handle */
+-
+-#ifdef BCMIPXOTP
+-	/* IPX OTP section */
+-	u16 wsize;		/* Size of otp in words */
+-	u16 rows;		/* Geometry */
+-	u16 cols;		/* Geometry */
+-	u32 status;		/* Flag bits (lock/prog/rv).
+-				 * (Reflected only when OTP is power cycled)
+-				 */
+-	u16 hwbase;		/* hardware subregion offset */
+-	u16 hwlim;		/* hardware subregion boundary */
+-	u16 swbase;		/* software subregion offset */
+-	u16 swlim;		/* software subregion boundary */
+-	u16 fbase;		/* fuse subregion offset */
+-	u16 flim;		/* fuse subregion boundary */
+-	int otpgu_base;		/* offset to General Use Region */
+-#endif				/* BCMIPXOTP */
+-
+-#ifdef BCMHNDOTP
+-	/* HND OTP section */
+-	uint size;		/* Size of otp in bytes */
+-	uint hwprot;		/* Hardware protection bits */
+-	uint signvalid;		/* Signature valid bits */
+-	int boundary;		/* hw/sw boundary */
+-#endif				/* BCMHNDOTP */
+-} otpinfo_t;
+-
+-static otpinfo_t otpinfo;
+-
+-/*
+- * IPX OTP Code
+- *
+- *   Exported functions:
+- *	ipxotp_status()
+- *	ipxotp_size()
+- *	ipxotp_init()
+- *	ipxotp_read_bit()
+- *	ipxotp_read_region()
+- *	ipxotp_nvread()
+- *
+- */
+-
+-#ifdef BCMIPXOTP
+-
+-#define HWSW_RGN(rgn)		(((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
+-
+-/* OTP layout */
+-/* CC revs 21, 24 and 27 OTP General Use Region word offset */
+-#define REVA4_OTPGU_BASE	12
+-
+-/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
+-#define REVB8_OTPGU_BASE	20
+-
+-/* CC rev 36 OTP General Use Region word offset */
+-#define REV36_OTPGU_BASE	12
+-
+-/* Subregion word offsets in General Use region */
+-#define OTPGU_HSB_OFF		0
+-#define OTPGU_SFB_OFF		1
+-#define OTPGU_CI_OFF		2
+-#define OTPGU_P_OFF		3
+-#define OTPGU_SROM_OFF		4
+-
+-/* Flag bit offsets in General Use region  */
+-#define OTPGU_HWP_OFF		60
+-#define OTPGU_SWP_OFF		61
+-#define OTPGU_CIP_OFF		62
+-#define OTPGU_FUSEP_OFF		63
+-#define OTPGU_CIP_MSK		0x4000
+-#define OTPGU_P_MSK		0xf000
+-#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)
+-
+-/* OTP Size */
+-#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
+-#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
+-#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
+-#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
+-#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
+-#define OTP4315_SWREG_SZ	178	/* 178 bytes */
+-#define OTP_SZ_FU_144		(144/8)	/* 144 bits */
+-
+-static int ipxotp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->status);
+-}
+-
+-/* Return size in bytes */
+-static int ipxotp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)oi->wsize * 2;
+-}
+-
+-static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+-{
+-	otpinfo_t *oi;
+-
+-	oi = (otpinfo_t *) oh;
+-
+-	return R_REG(&cc->sromotp[wn]);
+-}
+-
+-static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint k, row, col;
+-	u32 otpp, st;
+-
+-	row = off / oi->cols;
+-	col = off % oi->cols;
+-
+-	otpp = OTPP_START_BUSY |
+-	    ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
+-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
+-	    ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
+-	W_REG(&cc->otpprog, otpp);
+-
+-	for (k = 0;
+-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+-	     && (k < OTPP_TRIES); k++)
+-		;
+-	if (k >= OTPP_TRIES) {
+-		return 0xffff;
+-	}
+-	if (st & OTPP_READERR) {
+-		return 0xffff;
+-	}
+-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+-
+-	return (int)st;
+-}
+-
+-/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
+- * osizew is oi->wsize (OTP size - GU size) in words
+- */
+-static int ipxotp_max_rgnsz(si_t *sih, int osizew)
+-{
+-	int ret = 0;
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+-		break;
+-	case BCM4313_CHIP_ID:
+-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+-		break;
+-	default:
+-		break;	/* Don't know about this chip */
+-	}
+-
+-	return ret;
+-}
+-
+-static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
+-{
+-	uint k;
+-	u32 otpp, st;
+-
+-	/* record word offset of General Use Region for various chipcommon revs */
+-	if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
+-	    || oi->sih->ccrev == 27) {
+-		oi->otpgu_base = REVA4_OTPGU_BASE;
+-	} else if (oi->sih->ccrev == 36) {
+-		/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
+-		if (oi->wsize >= 128)
+-			oi->otpgu_base = REVB8_OTPGU_BASE;
+-		else
+-			oi->otpgu_base = REV36_OTPGU_BASE;
+-	} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
+-		oi->otpgu_base = REVB8_OTPGU_BASE;
+-	}
+-
+-	/* First issue an init command so the status is up to date */
+-	otpp =
+-	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
+-
+-	W_REG(&cc->otpprog, otpp);
+-	for (k = 0;
+-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+-	     && (k < OTPP_TRIES); k++)
+-		;
+-	if (k >= OTPP_TRIES) {
+-		return;
+-	}
+-
+-	/* Read OTP lock bits and subregion programmed indication bits */
+-	oi->status = R_REG(&cc->otpstatus);
+-
+-	if ((oi->sih->chip == BCM43224_CHIP_ID)
+-	    || (oi->sih->chip == BCM43225_CHIP_ID)) {
+-		u32 p_bits;
+-		p_bits =
+-		    (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
+-		     OTPGU_P_MSK)
+-		    >> OTPGU_P_SHIFT;
+-		oi->status |= (p_bits << OTPS_GUP_SHIFT);
+-	}
+-
+-	/*
+-	 * h/w region base and fuse region limit are fixed to the top and
+-	 * the bottom of the general use region. Everything else can be flexible.
+-	 */
+-	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
+-	oi->hwlim = oi->wsize;
+-	if (oi->status & OTPS_GUP_HW) {
+-		oi->hwlim =
+-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
+-		oi->swbase = oi->hwlim;
+-	} else
+-		oi->swbase = oi->hwbase;
+-
+-	/* subtract fuse and checksum from beginning */
+-	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
+-
+-	if (oi->status & OTPS_GUP_SW) {
+-		oi->swlim =
+-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
+-		oi->fbase = oi->swlim;
+-	} else
+-		oi->fbase = oi->swbase;
+-
+-	oi->flim = oi->wsize;
+-}
+-
+-static void *ipxotp_init(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	otpinfo_t *oi;
+-
+-	/* Make sure we're running IPX OTP */
+-	if (!OTPTYPE_IPX(sih->ccrev))
+-		return NULL;
+-
+-	/* Make sure OTP is not disabled */
+-	if (ai_is_otp_disabled(sih))
+-		return NULL;
+-
+-	/* Make sure OTP is powered up */
+-	if (!ai_is_otp_powered(sih))
+-		return NULL;
+-
+-	oi = &otpinfo;
+-
+-	/* Check for otp size */
+-	switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
+-	case 0:
+-		/* Nothing there */
+-		return NULL;
+-	case 1:		/* 32x64 */
+-		oi->rows = 32;
+-		oi->cols = 64;
+-		oi->wsize = 128;
+-		break;
+-	case 2:		/* 64x64 */
+-		oi->rows = 64;
+-		oi->cols = 64;
+-		oi->wsize = 256;
+-		break;
+-	case 5:		/* 96x64 */
+-		oi->rows = 96;
+-		oi->cols = 64;
+-		oi->wsize = 384;
+-		break;
+-	case 7:		/* 16x64 *//* 1024 bits */
+-		oi->rows = 16;
+-		oi->cols = 64;
+-		oi->wsize = 64;
+-		break;
+-	default:
+-		/* Don't know the geometry */
+-		return NULL;
+-	}
+-
+-	/* Retrieve OTP region info */
+-	idx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	_ipxotp_init(oi, cc);
+-
+-	ai_setcoreidx(sih, idx);
+-
+-	return (void *)oi;
+-}
+-
+-static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint idx;
+-	chipcregs_t *cc;
+-	uint base, i, sz;
+-
+-	/* Validate region selection */
+-	switch (region) {
+-	case OTP_HW_RGN:
+-		sz = (uint) oi->hwlim - oi->hwbase;
+-		if (!(oi->status & OTPS_GUP_HW)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->hwbase;
+-		break;
+-	case OTP_SW_RGN:
+-		sz = ((uint) oi->swlim - oi->swbase);
+-		if (!(oi->status & OTPS_GUP_SW)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->swbase;
+-		break;
+-	case OTP_CI_RGN:
+-		sz = OTPGU_CI_SZ;
+-		if (!(oi->status & OTPS_GUP_CI)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->otpgu_base + OTPGU_CI_OFF;
+-		break;
+-	case OTP_FUSE_RGN:
+-		sz = (uint) oi->flim - oi->fbase;
+-		if (!(oi->status & OTPS_GUP_FUSE)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->fbase;
+-		break;
+-	case OTP_ALL_RGN:
+-		sz = ((uint) oi->flim - oi->hwbase);
+-		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->hwbase;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	/* Read the data */
+-	for (i = 0; i < sz; i++)
+-		data[i] = ipxotp_otpr(oh, cc, base + i);
+-
+-	ai_setcoreidx(oi->sih, idx);
+-	*wlen = sz;
+-	return 0;
+-}
+-
+-static int ipxotp_nvread(void *oh, char *data, uint *len)
+-{
+-	return -ENOTSUPP;
+-}
+-
+-static otp_fn_t ipxotp_fn = {
+-	(otp_size_t) ipxotp_size,
+-	(otp_read_bit_t) ipxotp_read_bit,
+-
+-	(otp_init_t) ipxotp_init,
+-	(otp_read_region_t) ipxotp_read_region,
+-	(otp_nvread_t) ipxotp_nvread,
+-
+-	(otp_status_t) ipxotp_status
+-};
+-
+-#endif				/* BCMIPXOTP */
+-
+-/*
+- * HND OTP Code
+- *
+- *   Exported functions:
+- *	hndotp_status()
+- *	hndotp_size()
+- *	hndotp_init()
+- *	hndotp_read_bit()
+- *	hndotp_read_region()
+- *	hndotp_nvread()
+- *
+- */
+-
+-#ifdef BCMHNDOTP
+-
+-/* Fields in otpstatus */
+-#define	OTPS_PROGFAIL		0x80000000
+-#define	OTPS_PROTECT		0x00000007
+-#define	OTPS_HW_PROTECT		0x00000001
+-#define	OTPS_SW_PROTECT		0x00000002
+-#define	OTPS_CID_PROTECT	0x00000004
+-#define	OTPS_RCEV_MSK		0x00003f00
+-#define	OTPS_RCEV_SHIFT		8
+-
+-/* Fields in the otpcontrol register */
+-#define	OTPC_RECWAIT		0xff000000
+-#define	OTPC_PROGWAIT		0x00ffff00
+-#define	OTPC_PRW_SHIFT		8
+-#define	OTPC_MAXFAIL		0x00000038
+-#define	OTPC_VSEL		0x00000006
+-#define	OTPC_SELVL		0x00000001
+-
+-/* OTP regions (Word offsets from otp size) */
+-#define	OTP_SWLIM_OFF	(-4)
+-#define	OTP_CIDBASE_OFF	0
+-#define	OTP_CIDLIM_OFF	4
+-
+-/* Predefined OTP words (Word offset from otp size) */
+-#define	OTP_BOUNDARY_OFF (-4)
+-#define	OTP_HWSIGN_OFF	(-3)
+-#define	OTP_SWSIGN_OFF	(-2)
+-#define	OTP_CIDSIGN_OFF	(-1)
+-#define	OTP_CID_OFF	0
+-#define	OTP_PKG_OFF	1
+-#define	OTP_FID_OFF	2
+-#define	OTP_RSV_OFF	3
+-#define	OTP_LIM_OFF	4
+-#define	OTP_RD_OFF	4	/* Redundancy row starts here */
+-#define	OTP_RC0_OFF	28	/* Redundancy control word 1 */
+-#define	OTP_RC1_OFF	32	/* Redundancy control word 2 */
+-#define	OTP_RC_LIM_OFF	36	/* Redundancy control word end */
+-
+-#define	OTP_HW_REGION	OTPS_HW_PROTECT
+-#define	OTP_SW_REGION	OTPS_SW_PROTECT
+-#define	OTP_CID_REGION	OTPS_CID_PROTECT
+-
+-#if OTP_HW_REGION != OTP_HW_RGN
+-#error "incompatible OTP_HW_RGN"
+-#endif
+-#if OTP_SW_REGION != OTP_SW_RGN
+-#error "incompatible OTP_SW_RGN"
+-#endif
+-#if OTP_CID_REGION != OTP_CI_RGN
+-#error "incompatible OTP_CI_RGN"
+-#endif
+-
+-/* Redundancy entry definitions */
+-#define	OTP_RCE_ROW_SZ		6
+-#define	OTP_RCE_SIGN_MASK	0x7fff
+-#define	OTP_RCE_ROW_MASK	0x3f
+-#define	OTP_RCE_BITS		21
+-#define	OTP_RCE_SIGN_SZ		15
+-#define	OTP_RCE_BIT0		1
+-
+-#define	OTP_WPR		4
+-#define	OTP_SIGNATURE	0x578a
+-#define	OTP_MAGIC	0x4e56
+-
+-static int hndotp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->hwprot | oi->signvalid);
+-}
+-
+-static int hndotp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->size);
+-}
+-
+-static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+-{
+-	volatile u16 *ptr;
+-
+-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+-	return R_REG(&ptr[wn]);
+-}
+-
+-static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	volatile u16 *ptr;
+-
+-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+-
+-	return R_REG(&ptr[(oi->size / 2) + woff]);
+-}
+-
+-static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
+-{
+-	uint k, row, col;
+-	u32 otpp, st;
+-
+-	row = idx / 65;
+-	col = idx % 65;
+-
+-	otpp = OTPP_START_BUSY | OTPP_READ |
+-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
+-
+-	W_REG(&cc->otpprog, otpp);
+-	st = R_REG(&cc->otpprog);
+-	for (k = 0;
+-	     ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
+-	     k++)
+-		st = R_REG(&cc->otpprog);
+-
+-	if (k >= OTPP_TRIES) {
+-		return 0xffff;
+-	}
+-	if (st & OTPP_READERR) {
+-		return 0xffff;
+-	}
+-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+-	return (u16) st;
+-}
+-
+-static void *hndotp_init(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	otpinfo_t *oi;
+-	u32 cap = 0, clkdiv, otpdiv = 0;
+-	void *ret = NULL;
+-
+-	oi = &otpinfo;
+-
+-	idx = ai_coreidx(sih);
+-
+-	/* Check for otp */
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-	if (cc != NULL) {
+-		cap = R_REG(&cc->capabilities);
+-		if ((cap & CC_CAP_OTPSIZE) == 0) {
+-			/* Nothing there */
+-			goto out;
+-		}
+-
+-		if (!((oi->ccrev == 12) || (oi->ccrev == 17)
+-		     || (oi->ccrev == 22)))
+-			return NULL;
+-
+-		/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
+-		 * 8 row (64 bytes) smaller
+-		 */
+-		oi->size =
+-		    1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
+-			  + CC_CAP_OTPSIZE_BASE);
+-		if (oi->ccrev >= 18)
+-			oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
+-
+-		oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
+-		oi->boundary = -1;
+-
+-		/* Check the region signature */
+-		if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
+-			oi->signvalid |= OTP_HW_REGION;
+-			oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
+-		}
+-
+-		if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
+-			oi->signvalid |= OTP_SW_REGION;
+-
+-		if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
+-			oi->signvalid |= OTP_CID_REGION;
+-
+-		/* Set OTP clkdiv for stability */
+-		if (oi->ccrev == 22)
+-			otpdiv = 12;
+-
+-		if (otpdiv) {
+-			clkdiv = R_REG(&cc->clkdiv);
+-			clkdiv =
+-			    (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
+-			W_REG(&cc->clkdiv, clkdiv);
+-		}
+-		udelay(10);
+-
+-		ret = (void *)oi;
+-	}
+-
+- out:				/* All done */
+-	ai_setcoreidx(sih, idx);
+-
+-	return ret;
+-}
+-
+-static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	u32 idx, st;
+-	chipcregs_t *cc;
+-	int i;
+-
+-
+-	if (region != OTP_HW_REGION) {
+-		/*
+-		 * Only support HW region
+-		 * (no active chips use HND OTP SW region)
+-		 * */
+-		return -ENOTSUPP;
+-	}
+-
+-	/* Region empty? */
+-	st = oi->hwprot | oi->signvalid;
+-	if ((st & region) == 0)
+-		return -ENODATA;
+-
+-	*wlen =
+-	    ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
+-
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	for (i = 0; i < (int)*wlen; i++)
+-		data[i] = hndotp_otpr(oh, cc, i);
+-
+-	ai_setcoreidx(oi->sih, idx);
+-
+-	return 0;
+-}
+-
+-static int hndotp_nvread(void *oh, char *data, uint *len)
+-{
+-	int rc = 0;
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	u32 base, bound, lim = 0, st;
+-	int i, chunk, gchunks, tsz = 0;
+-	u32 idx;
+-	chipcregs_t *cc;
+-	uint offset;
+-	u16 *rawotp = NULL;
+-
+-	/* save the orig core */
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	st = hndotp_status(oh);
+-	if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
+-		rc = -1;
+-		goto out;
+-	}
+-
+-	/* Read the whole otp so we can easily manipulate it */
+-	lim = hndotp_size(oh);
+-	rawotp = kmalloc(lim, GFP_ATOMIC);
+-	if (rawotp == NULL) {
+-		rc = -2;
+-		goto out;
+-	}
+-	for (i = 0; i < (int)(lim / 2); i++)
+-		rawotp[i] = hndotp_otpr(oh, cc, i);
+-
+-	if ((st & OTP_HW_REGION) == 0) {
+-		/* This could be a programming failure in the first
+-		 * chunk followed by one or more good chunks
+-		 */
+-		for (i = 0; i < (int)(lim / 2); i++)
+-			if (rawotp[i] == OTP_MAGIC)
+-				break;
+-
+-		if (i < (int)(lim / 2)) {
+-			base = i;
+-			bound = (i * 2) + rawotp[i + 1];
+-		} else {
+-			rc = -3;
+-			goto out;
+-		}
+-	} else {
+-		bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
+-
+-		/* There are two cases: 1) The whole otp is used as nvram
+-		 * and 2) There is a hardware header followed by nvram.
+-		 */
+-		if (rawotp[0] == OTP_MAGIC) {
+-			base = 0;
+-		} else
+-			base = bound;
+-	}
+-
+-	/* Find and copy the data */
+-
+-	chunk = 0;
+-	gchunks = 0;
+-	i = base / 2;
+-	offset = 0;
+-	while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
+-		int dsz, rsz = rawotp[i + 1];
+-
+-		if (((i * 2) + rsz) >= (int)lim) {
+-			/* Bad length, try to find another chunk anyway */
+-			rsz = 6;
+-		}
+-		if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) ==
+-			CRC16_GOOD_VALUE) {
+-			/* Good crc, copy the vars */
+-			gchunks++;
+-			dsz = rsz - 6;
+-			tsz += dsz;
+-			if (offset + dsz >= *len) {
+-				goto out;
+-			}
+-			memcpy(&data[offset], &rawotp[i + 2], dsz);
+-			offset += dsz;
+-			/* Remove extra null characters at the end */
+-			while (offset > 1 &&
+-			       data[offset - 1] == 0 && data[offset - 2] == 0)
+-				offset--;
+-			i += rsz / 2;
+-		} else {
+-			/* bad length or crc didn't check, try to find the next set */
+-			if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
+-				/* Assume length is good */
+-				i += rsz / 2;
+-			} else {
+-				while (++i < (int)(lim / 2))
+-					if (rawotp[i] == OTP_MAGIC)
+-						break;
+-			}
+-		}
+-		chunk++;
+-	}
+-
+-	*len = offset;
+-
+- out:
+-	kfree(rawotp);
+-	ai_setcoreidx(oi->sih, idx);
+-
+-	return rc;
+-}
+-
+-static otp_fn_t hndotp_fn = {
+-	(otp_size_t) hndotp_size,
+-	(otp_read_bit_t) hndotp_read_bit,
+-
+-	(otp_init_t) hndotp_init,
+-	(otp_read_region_t) hndotp_read_region,
+-	(otp_nvread_t) hndotp_nvread,
+-
+-	(otp_status_t) hndotp_status
+-};
+-
+-#endif				/* BCMHNDOTP */
+-
+-/*
+- * Common Code: Compiled for IPX / HND / AUTO
+- *	otp_status()
+- *	otp_size()
+- *	otp_read_bit()
+- *	otp_init()
+- * 	otp_read_region()
+- * 	otp_nvread()
+- */
+-
+-int otp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->status(oh);
+-}
+-
+-int otp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->size(oh);
+-}
+-
+-u16 otp_read_bit(void *oh, uint offset)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint idx = ai_coreidx(oi->sih);
+-	chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-	u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
+-	ai_setcoreidx(oi->sih, idx);
+-	return readBit;
+-}
+-
+-void *otp_init(si_t *sih)
+-{
+-	otpinfo_t *oi;
+-	void *ret = NULL;
+-
+-	oi = &otpinfo;
+-	memset(oi, 0, sizeof(otpinfo_t));
+-
+-	oi->ccrev = sih->ccrev;
+-
+-#ifdef BCMIPXOTP
+-	if (OTPTYPE_IPX(oi->ccrev))
+-		oi->fn = &ipxotp_fn;
+-#endif
+-
+-#ifdef BCMHNDOTP
+-	if (OTPTYPE_HND(oi->ccrev))
+-		oi->fn = &hndotp_fn;
+-#endif
+-
+-	if (oi->fn == NULL) {
+-		return NULL;
+-	}
+-
+-	oi->sih = sih;
+-
+-	ret = (oi->fn->init) (sih);
+-
+-	return ret;
+-}
+-
+-int
+-otp_read_region(si_t *sih, int region, u16 *data,
+-				 uint *wlen) {
+-	bool wasup = false;
+-	void *oh;
+-	int err = 0;
+-
+-	wasup = ai_is_otp_powered(sih);
+-	if (!wasup)
+-		ai_otp_power(sih, true);
+-
+-	if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) {
+-		err = -EPERM;
+-		goto out;
+-	}
+-
+-	oh = otp_init(sih);
+-	if (oh == NULL) {
+-		err = -EBADE;
+-		goto out;
+-	}
+-
+-	err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
+-
+- out:
+-	if (!wasup)
+-		ai_otp_power(sih, false);
+-
+-	return err;
+-}
+-
+-int otp_nvread(void *oh, char *data, uint *len)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->nvread(oh, data, len);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c
+deleted file mode 100644
+index bbfc642..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c
++++ /dev/null
+@@ -1,714 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/etherdevice.h>
+-#include <bcmdefs.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <stdarg.h>
+-#include <bcmutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <pcicfg.h>
+-#include <aiutils.h>
+-#include <bcmsrom.h>
+-#include <bcmsrom_tbl.h>
+-
+-#include <bcmnvram.h>
+-#include <bcmotp.h>
+-
+-#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
+-	(((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
+-	 ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
+-	((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
+-
+-#if defined(BCMDBG)
+-#define WRITE_ENABLE_DELAY	500	/* 500 ms after write enable/disable toggle */
+-#define WRITE_WORD_DELAY	20	/* 20 ms between each word write */
+-#endif
+-
+-typedef struct varbuf {
+-	char *base;		/* pointer to buffer base */
+-	char *buf;		/* pointer to current position */
+-	unsigned int size;	/* current (residual) size in bytes */
+-} varbuf_t;
+-extern char *_vars;
+-extern uint _varsz;
+-
+-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count);
+-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b);
+-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
+-static int initvars_flash_si(si_t *sih, char **vars, uint *count);
+-static int sprom_read_pci(si_t *sih, u16 *sprom,
+-			  uint wordoff, u16 *buf, uint nwords, bool check_crc);
+-#if defined(BCMNVRAMR)
+-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz);
+-#endif
+-static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+-			  uint wordoff, u16 data);
+-
+-static int initvars_table(char *start, char *end,
+-			  char **vars, uint *count);
+-static int initvars_flash(si_t *sih, char **vp,
+-			  uint len);
+-
+-/* Initialization of varbuf structure */
+-static void varbuf_init(varbuf_t *b, char *buf, uint size)
+-{
+-	b->size = size;
+-	b->base = b->buf = buf;
+-}
+-
+-/* append a null terminated var=value string */
+-static int varbuf_append(varbuf_t *b, const char *fmt, ...)
+-{
+-	va_list ap;
+-	int r;
+-	size_t len;
+-	char *s;
+-
+-	if (b->size < 2)
+-		return 0;
+-
+-	va_start(ap, fmt);
+-	r = vsnprintf(b->buf, b->size, fmt, ap);
+-	va_end(ap);
+-
+-	/* C99 snprintf behavior returns r >= size on overflow,
+-	 * others return -1 on overflow.
+-	 * All return -1 on format error.
+-	 * We need to leave room for 2 null terminations, one for the current var
+-	 * string, and one for final null of the var table. So check that the
+-	 * strlen written, r, leaves room for 2 chars.
+-	 */
+-	if ((r == -1) || (r > (int)(b->size - 2))) {
+-		b->size = 0;
+-		return 0;
+-	}
+-
+-	/* Remove any earlier occurrence of the same variable */
+-	s = strchr(b->buf, '=');
+-	if (s != NULL) {
+-		len = (size_t) (s - b->buf);
+-		for (s = b->base; s < b->buf;) {
+-			if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
+-				len = strlen(s) + 1;
+-				memmove(s, (s + len),
+-					((b->buf + r + 1) - (s + len)));
+-				b->buf -= len;
+-				b->size += (unsigned int)len;
+-				break;
+-			}
+-
+-			while (*s++)
+-				;
+-		}
+-	}
+-
+-	/* skip over this string's null termination */
+-	r++;
+-	b->size -= r;
+-	b->buf += r;
+-
+-	return r;
+-}
+-
+-/*
+- * Initialize local vars from the right source for this platform.
+- * Return 0 on success, nonzero on error.
+- */
+-int srom_var_init(si_t *sih, uint bustype, void *curmap,
+-		  char **vars, uint *count)
+-{
+-	uint len;
+-
+-	len = 0;
+-
+-	if (vars == NULL || count == NULL)
+-		return 0;
+-
+-	*vars = NULL;
+-	*count = 0;
+-
+-	switch (bustype) {
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		return initvars_srom_si(sih, curmap, vars, count);
+-
+-	case PCI_BUS:
+-		if (curmap == NULL)
+-			return -1;
+-
+-		return initvars_srom_pci(sih, curmap, vars, count);
+-
+-	default:
+-		break;
+-	}
+-	return -1;
+-}
+-
+-/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
+- * not in the bus cores.
+- */
+-static u16
+-srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+-	    uint wordoff, u16 data)
+-{
+-	chipcregs_t *cc = (chipcregs_t *) ccregs;
+-	uint wait_cnt = 1000;
+-
+-	if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
+-		W_REG(&cc->sromaddress, wordoff * 2);
+-		if (cmd == SRC_OP_WRITE)
+-			W_REG(&cc->sromdata, data);
+-	}
+-
+-	W_REG(&cc->sromcontrol, SRC_START | cmd);
+-
+-	while (wait_cnt--) {
+-		if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0)
+-			break;
+-	}
+-
+-	if (!wait_cnt) {
+-		return 0xffff;
+-	}
+-	if (cmd == SRC_OP_READ)
+-		return (u16) R_REG(&cc->sromdata);
+-	else
+-		return 0xffff;
+-}
+-
+-static inline void ltoh16_buf(u16 *buf, unsigned int size)
+-{
+-	for (size /= 2; size; size--)
+-		*(buf + size) = le16_to_cpu(*(buf + size));
+-}
+-
+-static inline void htol16_buf(u16 *buf, unsigned int size)
+-{
+-	for (size /= 2; size; size--)
+-		*(buf + size) = cpu_to_le16(*(buf + size));
+-}
+-
+-/*
+- * Read in and validate sprom.
+- * Return 0 on success, nonzero on error.
+- */
+-static int
+-sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff,
+-	       u16 *buf, uint nwords, bool check_crc)
+-{
+-	int err = 0;
+-	uint i;
+-	void *ccregs = NULL;
+-
+-	/* read the sprom */
+-	for (i = 0; i < nwords; i++) {
+-
+-		if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
+-			/* use indirect since direct is too slow on QT */
+-			if ((sih->cccaps & CC_CAP_SROM) == 0)
+-				return 1;
+-
+-			ccregs = (void *)((u8 *) sprom - CC_SROM_OTP);
+-			buf[i] =
+-			    srom_cc_cmd(sih, ccregs, SRC_OP_READ,
+-					wordoff + i, 0);
+-
+-		} else {
+-			if (ISSIM_ENAB(sih))
+-				buf[i] = R_REG(&sprom[wordoff + i]);
+-
+-			buf[i] = R_REG(&sprom[wordoff + i]);
+-		}
+-
+-	}
+-
+-	/* bypass crc checking for simulation to allow srom hack */
+-	if (ISSIM_ENAB(sih))
+-		return err;
+-
+-	if (check_crc) {
+-
+-		if (buf[0] == 0xffff) {
+-			/* The hardware thinks that an srom that starts with 0xffff
+-			 * is blank, regardless of the rest of the content, so declare
+-			 * it bad.
+-			 */
+-			return 1;
+-		}
+-
+-		/* fixup the endianness so crc8 will pass */
+-		htol16_buf(buf, nwords * 2);
+-		if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
+-		    CRC8_GOOD_VALUE) {
+-			/* DBG only pci always read srom4 first, then srom8/9 */
+-			err = 1;
+-		}
+-		/* now correct the endianness of the byte array */
+-		ltoh16_buf(buf, nwords * 2);
+-	}
+-	return err;
+-}
+-
+-#if defined(BCMNVRAMR)
+-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz)
+-{
+-	u8 *otp;
+-	uint sz = OTP_SZ_MAX / 2;	/* size in words */
+-	int err = 0;
+-
+-	otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
+-	if (otp == NULL) {
+-		return -EBADE;
+-	}
+-
+-	err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
+-
+-	memcpy(buf, otp, bufsz);
+-
+-	kfree(otp);
+-
+-	/* Check CRC */
+-	if (buf[0] == 0xffff) {
+-		/* The hardware thinks that an srom that starts with 0xffff
+-		 * is blank, regardless of the rest of the content, so declare
+-		 * it bad.
+-		 */
+-		return 1;
+-	}
+-
+-	/* fixup the endianness so crc8 will pass */
+-	htol16_buf(buf, bufsz);
+-	if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
+-	    CRC8_GOOD_VALUE) {
+-		err = 1;
+-	}
+-	/* now correct the endianness of the byte array */
+-	ltoh16_buf(buf, bufsz);
+-
+-	return err;
+-}
+-#endif				/* defined(BCMNVRAMR) */
+-/*
+-* Create variable table from memory.
+-* Return 0 on success, nonzero on error.
+-*/
+-static int initvars_table(char *start, char *end,
+-			  char **vars, uint *count)
+-{
+-	int c = (int)(end - start);
+-
+-	/* do it only when there is more than just the null string */
+-	if (c > 1) {
+-		char *vp = kmalloc(c, GFP_ATOMIC);
+-		if (!vp)
+-			return -ENOMEM;
+-		memcpy(vp, start, c);
+-		*vars = vp;
+-		*count = c;
+-	} else {
+-		*vars = NULL;
+-		*count = 0;
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * Find variables with <devpath> from flash. 'base' points to the beginning
+- * of the table upon enter and to the end of the table upon exit when success.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_flash(si_t *sih, char **base, uint len)
+-{
+-	char *vp = *base;
+-	char *flash;
+-	int err;
+-	char *s;
+-	uint l, dl, copy_len;
+-	char devpath[SI_DEVPATH_BUFSZ];
+-
+-	/* allocate memory and read in flash */
+-	flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC);
+-	if (!flash)
+-		return -ENOMEM;
+-	err = nvram_getall(flash, NVRAM_SPACE);
+-	if (err)
+-		goto exit;
+-
+-	ai_devpath(sih, devpath, sizeof(devpath));
+-
+-	/* grab vars with the <devpath> prefix in name */
+-	dl = strlen(devpath);
+-	for (s = flash; s && *s; s += l + 1) {
+-		l = strlen(s);
+-
+-		/* skip non-matching variable */
+-		if (strncmp(s, devpath, dl))
+-			continue;
+-
+-		/* is there enough room to copy? */
+-		copy_len = l - dl + 1;
+-		if (len < copy_len) {
+-			err = -EOVERFLOW;
+-			goto exit;
+-		}
+-
+-		/* no prefix, just the name=value */
+-		strncpy(vp, &s[dl], copy_len);
+-		vp += copy_len;
+-		len -= copy_len;
+-	}
+-
+-	/* add null string as terminator */
+-	if (len < 1) {
+-		err = -EOVERFLOW;
+-		goto exit;
+-	}
+-	*vp++ = '\0';
+-
+-	*base = vp;
+-
+- exit:	kfree(flash);
+-	return err;
+-}
+-
+-/*
+- * Initialize nonvolatile variable table from flash.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_flash_si(si_t *sih, char **vars, uint *count)
+-{
+-	char *vp, *base;
+-	int err;
+-
+-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+-	if (!vp)
+-		return -ENOMEM;
+-
+-	err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+-	if (err == 0)
+-		err = initvars_table(base, vp, vars, count);
+-
+-	kfree(base);
+-
+-	return err;
+-}
+-
+-/* Parse SROM and create name=value pairs. 'srom' points to
+- * the SROM word array. 'off' specifies the offset of the
+- * first word 'srom' points to, which should be either 0 or
+- * SROM3_SWRG_OFF (full SROM or software region).
+- */
+-
+-static uint mask_shift(u16 mask)
+-{
+-	uint i;
+-	for (i = 0; i < (sizeof(mask) << 3); i++) {
+-		if (mask & (1 << i))
+-			return i;
+-	}
+-	return 0;
+-}
+-
+-static uint mask_width(u16 mask)
+-{
+-	int i;
+-	for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
+-		if (mask & (1 << i))
+-			return (uint) (i - mask_shift(mask) + 1);
+-	}
+-	return 0;
+-}
+-
+-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b)
+-{
+-	u16 w;
+-	u32 val;
+-	const sromvar_t *srv;
+-	uint width;
+-	uint flags;
+-	u32 sr = (1 << sromrev);
+-
+-	varbuf_append(b, "sromrev=%d", sromrev);
+-
+-	for (srv = pci_sromvars; srv->name != NULL; srv++) {
+-		const char *name;
+-
+-		if ((srv->revmask & sr) == 0)
+-			continue;
+-
+-		if (srv->off < off)
+-			continue;
+-
+-		flags = srv->flags;
+-		name = srv->name;
+-
+-		/* This entry is for mfgc only. Don't generate param for it, */
+-		if (flags & SRFL_NOVAR)
+-			continue;
+-
+-		if (flags & SRFL_ETHADDR) {
+-			u8 ea[ETH_ALEN];
+-
+-			ea[0] = (srom[srv->off - off] >> 8) & 0xff;
+-			ea[1] = srom[srv->off - off] & 0xff;
+-			ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
+-			ea[3] = srom[srv->off + 1 - off] & 0xff;
+-			ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
+-			ea[5] = srom[srv->off + 2 - off] & 0xff;
+-
+-			varbuf_append(b, "%s=%pM", name, ea);
+-		} else {
+-			w = srom[srv->off - off];
+-			val = (w & srv->mask) >> mask_shift(srv->mask);
+-			width = mask_width(srv->mask);
+-
+-			while (srv->flags & SRFL_MORE) {
+-				srv++;
+-				if (srv->off == 0 || srv->off < off)
+-					continue;
+-
+-				w = srom[srv->off - off];
+-				val +=
+-				    ((w & srv->mask) >> mask_shift(srv->
+-								   mask)) <<
+-				    width;
+-				width += mask_width(srv->mask);
+-			}
+-
+-			if ((flags & SRFL_NOFFS)
+-			    && ((int)val == (1 << width) - 1))
+-				continue;
+-
+-			if (flags & SRFL_CCODE) {
+-				if (val == 0)
+-					varbuf_append(b, "ccode=");
+-				else
+-					varbuf_append(b, "ccode=%c%c",
+-						      (val >> 8), (val & 0xff));
+-			}
+-			/* LED Powersave duty cycle has to be scaled:
+-			 *(oncount >> 24) (offcount >> 8)
+-			 */
+-			else if (flags & SRFL_LEDDC) {
+-				u32 w32 = (((val >> 8) & 0xff) << 24) |	/* oncount */
+-				    (((val & 0xff)) << 8);	/* offcount */
+-				varbuf_append(b, "leddc=%d", w32);
+-			} else if (flags & SRFL_PRHEX)
+-				varbuf_append(b, "%s=0x%x", name, val);
+-			else if ((flags & SRFL_PRSIGN)
+-				 && (val & (1 << (width - 1))))
+-				varbuf_append(b, "%s=%d", name,
+-					      (int)(val | (~0 << width)));
+-			else
+-				varbuf_append(b, "%s=%u", name, val);
+-		}
+-	}
+-
+-	if (sromrev >= 4) {
+-		/* Do per-path variables */
+-		uint p, pb, psz;
+-
+-		if (sromrev >= 8) {
+-			pb = SROM8_PATH0;
+-			psz = SROM8_PATH1 - SROM8_PATH0;
+-		} else {
+-			pb = SROM4_PATH0;
+-			psz = SROM4_PATH1 - SROM4_PATH0;
+-		}
+-
+-		for (p = 0; p < MAX_PATH_SROM; p++) {
+-			for (srv = perpath_pci_sromvars; srv->name != NULL;
+-			     srv++) {
+-				if ((srv->revmask & sr) == 0)
+-					continue;
+-
+-				if (pb + srv->off < off)
+-					continue;
+-
+-				/* This entry is for mfgc only. Don't generate param for it, */
+-				if (srv->flags & SRFL_NOVAR)
+-					continue;
+-
+-				w = srom[pb + srv->off - off];
+-				val = (w & srv->mask) >> mask_shift(srv->mask);
+-				width = mask_width(srv->mask);
+-
+-				/* Cheating: no per-path var is more than 1 word */
+-
+-				if ((srv->flags & SRFL_NOFFS)
+-				    && ((int)val == (1 << width) - 1))
+-					continue;
+-
+-				if (srv->flags & SRFL_PRHEX)
+-					varbuf_append(b, "%s%d=0x%x", srv->name,
+-						      p, val);
+-				else
+-					varbuf_append(b, "%s%d=%d", srv->name,
+-						      p, val);
+-			}
+-			pb += psz;
+-		}
+-	}
+-}
+-
+-/*
+- * Initialize nonvolatile variable table from sprom.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count)
+-{
+-	u16 *srom, *sromwindow;
+-	u8 sromrev = 0;
+-	u32 sr;
+-	varbuf_t b;
+-	char *vp, *base = NULL;
+-	bool flash = false;
+-	int err = 0;
+-
+-	/*
+-	 * Apply CRC over SROM content regardless SROM is present or not,
+-	 * and use variable <devpath>sromrev's existence in flash to decide
+-	 * if we should return an error when CRC fails or read SROM variables
+-	 * from flash.
+-	 */
+-	srom = kmalloc(SROM_MAX, GFP_ATOMIC);
+-	if (!srom)
+-		return -2;
+-
+-	sromwindow = (u16 *) SROM_OFFSET(sih);
+-	if (ai_is_sprom_available(sih)) {
+-		err =
+-		    sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
+-				   true);
+-
+-		if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
+-		    (((sih->buscoretype == PCIE_CORE_ID)
+-		      && (sih->buscorerev >= 6))
+-		     || ((sih->buscoretype == PCI_CORE_ID)
+-			 && (sih->buscorerev >= 0xe)))) {
+-			/* sromrev >= 4, read more */
+-			err =
+-			    sprom_read_pci(sih, sromwindow, 0, srom,
+-					   SROM4_WORDS, true);
+-			sromrev = srom[SROM4_CRCREV] & 0xff;
+-		} else if (err == 0) {
+-			/* srom is good and is rev < 4 */
+-			/* top word of sprom contains version and crc8 */
+-			sromrev = srom[SROM_CRCREV] & 0xff;
+-			/* bcm4401 sroms misprogrammed */
+-			if (sromrev == 0x10)
+-				sromrev = 1;
+-		}
+-	}
+-#if defined(BCMNVRAMR)
+-	/* Use OTP if SPROM not available */
+-	else {
+-		err = otp_read_pci(sih, srom, SROM_MAX);
+-		if (err == 0)
+-			/* OTP only contain SROM rev8/rev9 for now */
+-			sromrev = srom[SROM4_CRCREV] & 0xff;
+-		else
+-			err = 1;
+-	}
+-#else
+-	else
+-		err = 1;
+-#endif
+-
+-	/*
+-	 * We want internal/wltest driver to come up with default
+-	 * sromvars so we can program a blank SPROM/OTP.
+-	 */
+-	if (err) {
+-		char *value;
+-		u32 val;
+-		val = 0;
+-
+-		value = ai_getdevpathvar(sih, "sromrev");
+-		if (value) {
+-			sromrev = (u8) simple_strtoul(value, NULL, 0);
+-			flash = true;
+-			goto varscont;
+-		}
+-
+-		value = ai_getnvramflvar(sih, "sromrev");
+-		if (value) {
+-			err = 0;
+-			goto errout;
+-		}
+-
+-		{
+-			err = -1;
+-			goto errout;
+-		}
+-	}
+-
+- varscont:
+-	/* Bitmask for the sromrev */
+-	sr = 1 << sromrev;
+-
+-	/* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
+-	if ((sr & 0x33e) == 0) {
+-		err = -2;
+-		goto errout;
+-	}
+-
+-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+-	if (!vp) {
+-		err = -2;
+-		goto errout;
+-	}
+-
+-	/* read variables from flash */
+-	if (flash) {
+-		err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+-		if (err)
+-			goto errout;
+-		goto varsdone;
+-	}
+-
+-	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
+-
+-	/* parse SROM into name=value pairs. */
+-	_initvars_srom_pci(sromrev, srom, 0, &b);
+-
+-	/* final nullbyte terminator */
+-	vp = b.buf;
+-	*vp++ = '\0';
+-
+- varsdone:
+-	err = initvars_table(base, vp, vars, count);
+-
+- errout:
+-	if (base)
+-		kfree(base);
+-
+-	kfree(srom);
+-	return err;
+-}
+-
+-
+-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz)
+-{
+-	/* Search flash nvram section for srom variables */
+-	return initvars_flash_si(sih, vars, varsz);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h b/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
+deleted file mode 100644
+index f4b3e61..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
++++ /dev/null
+@@ -1,513 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_tbl_h_
+-#define	_bcmsrom_tbl_h_
+-
+-#include "wlioctl.h"
+-
+-typedef struct {
+-	const char *name;
+-	u32 revmask;
+-	u32 flags;
+-	u16 off;
+-	u16 mask;
+-} sromvar_t;
+-
+-#define SRFL_MORE	1	/* value continues as described by the next entry */
+-#define	SRFL_NOFFS	2	/* value bits can't be all one's */
+-#define	SRFL_PRHEX	4	/* value is in hexdecimal format */
+-#define	SRFL_PRSIGN	8	/* value is in signed decimal format */
+-#define	SRFL_CCODE	0x10	/* value is in country code format */
+-#define	SRFL_ETHADDR	0x20	/* value is an Ethernet address */
+-#define SRFL_LEDDC	0x40	/* value is an LED duty cycle */
+-#define SRFL_NOVAR	0x80	/* do not generate a nvram param, entry is for mfgc */
+-
+-/* Assumptions:
+- * - Ethernet address spans across 3 consective words
+- *
+- * Table rules:
+- * - Add multiple entries next to each other if a value spans across multiple words
+- *   (even multiple fields in the same word) with each entry except the last having
+- *   it's SRFL_MORE bit set.
+- * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
+- *   bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
+- * - The last entry's name field must be NULL to indicate the end of the table. Other
+- *   entries must have non-NULL name.
+- */
+-
+-static const sromvar_t pci_sromvars[] = {
+-	{"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
+-	{"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
+-	{"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
+-	{"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
+-	{"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
+-	{"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+-	{"", 0, 0, SROM_BFL2, 0xffff},
+-	{"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+-	{"", 0, 0, SROM3_BFL2, 0xffff},
+-	{"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
+-	{"", 0, 0, SROM4_BFL1, 0xffff},
+-	{"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
+-	{"", 0, 0, SROM5_BFL1, 0xffff},
+-	{"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
+-	{"", 0, 0, SROM8_BFL1, 0xffff},
+-	{"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
+-	{"", 0, 0, SROM4_BFL3, 0xffff},
+-	{"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
+-	{"", 0, 0, SROM5_BFL3, 0xffff},
+-	{"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
+-	{"", 0, 0, SROM8_BFL3, 0xffff},
+-	{"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
+-	{"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
+-	{"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
+-	{"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
+-	{"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
+-	{"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
+-	{"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
+-	{"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
+-	{"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
+-	{"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
+-	{"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
+-	{"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
+-	{"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
+-	{"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
+-	{"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
+-	{"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
+-	{"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
+-	{"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
+-	{"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
+-	{"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
+-	{"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
+-	{"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
+-	{"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
+-	{"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
+-	{"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
+-	{"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
+-	{"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
+-	{"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
+-	{"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
+-	{"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
+-	{"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
+-	{"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
+-	{"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
+-	{"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
+-	{"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
+-	{"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
+-	{"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
+-	{"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
+-	{"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
+-	{"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
+-	{"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
+-	{"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
+-	{"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
+-	{"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
+-	{"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
+-	{"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
+-	{"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
+-	{"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
+-	{"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
+-	{"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
+-	{"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
+-	{"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
+-	{"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
+-	{"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
+-	{"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
+-	{"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
+-	{"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
+-	{"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
+-	{"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
+-	{"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
+-	{"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
+-	{"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
+-	{"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
+-	{"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
+-	{"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
+-	{"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
+-	{"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
+-	{"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
+-	{"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
+-	{"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
+-	{"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
+-	{"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
+-	{"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
+-	{"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
+-	{"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
+-	{"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
+-	{"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
+-	{"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
+-	{"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
+-	{"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
+-	{"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
+-	{"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
+-	{"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
+-	{"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
+-	{"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
+-	{"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
+-	{"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
+-	{"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
+-	{"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
+-	{"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
+-	{"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
+-	{"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
+-	{"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
+-	{"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
+-	{"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
+-	{"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
+-	{"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
+-	{"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
+-	{"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
+-	{"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
+-	{"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
+-	{"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
+-	{"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
+-	{"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
+-	{"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
+-	{"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
+-	{"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
+-	{"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
+-	{"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
+-	{"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
+-	{"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
+-	{"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
+-	{"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
+-	{"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
+-	{"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
+-	{"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
+-	{"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
+-	{"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
+-	{"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
+-	{"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
+-	{"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
+-	{"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
+-	{"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
+-	{"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
+-	{"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
+-	{"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
+-	{"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
+-	{"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
+-	{"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
+-	{"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
+-	{"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
+-	{"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
+-	{"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
+-	{"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
+-	{"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
+-	{"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
+-	{"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
+-
+-	{"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
+-	{"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
+-	{"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
+-	{"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
+-	{"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
+-	{"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
+-	{"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
+-	{"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
+-	{"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
+-	{"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
+-	{"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
+-	{"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
+-	{"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
+-	{"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
+-	{"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
+-	{"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
+-	{"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+-	 0x00ff},
+-	{"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
+-	{"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+-	 0x0300},
+-	{"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
+-	 0x000f},
+-	{"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
+-	{"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
+-	{"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
+-
+-	{"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
+-	{"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
+-	{"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
+-	{"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
+-	{"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
+-	{"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
+-	{"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
+-	{"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
+-	{"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
+-	{"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
+-	{"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
+-	{"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
+-	{"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
+-	{"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
+-	{"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
+-	{"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
+-	{"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
+-	{"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
+-	{"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
+-	{"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
+-	{"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
+-	{"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
+-	{"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
+-	{"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
+-	{"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
+-	{"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
+-	{"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
+-	{"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
+-	{"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
+-	{"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
+-	{"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
+-	{"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
+-	{"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
+-	{"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
+-	{"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
+-	{"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
+-	{"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
+-	{"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
+-	{"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
+-	{"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
+-	{"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
+-	{"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
+-	{"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
+-	{"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
+-	{"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
+-	{"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
+-	{"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
+-	{"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
+-	{"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
+-	{"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
+-	{"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
+-	{"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
+-	{"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
+-	{"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
+-	{"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
+-	{"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
+-	{"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
+-	{"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
+-	{"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
+-	{"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
+-	{"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
+-	{"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
+-	{"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
+-	{"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
+-	{"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
+-	{"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
+-	{"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
+-	{"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
+-	{"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
+-	{"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
+-	{"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
+-	{"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
+-	{"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
+-	{"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
+-	{"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
+-	{"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
+-	{"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
+-	{"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
+-	{"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
+-	{"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
+-	{"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
+-	{"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
+-
+-	/* power per rate from sromrev 9 */
+-	{"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
+-	{"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
+-	{"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
+-	{"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
+-	{"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
+-	{"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
+-
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-static const sromvar_t perpath_pci_sromvars[] = {
+-	{"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
+-	{"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
+-	{"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
+-	{"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
+-	{"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
+-	{"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
+-	{"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
+-	{"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
+-	{"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
+-	{"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
+-	{"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
+-	{"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
+-	{"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
+-	{"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
+-	{"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
+-	{"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
+-	{"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
+-	{"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
+-	{"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
+-	{"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
+-	{"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
+-	{"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
+-	{"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
+-	{"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
+-	{"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
+-	{"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
+-	{"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
+-	{"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
+-	{"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
+-	{"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
+-	{"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
+-	{"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
+-	{"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
+-	{"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
+-	{"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
+-	{"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
+-	{"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
+-	{"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
+-	{"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
+-	{"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
+-#define	PHY_TYPE_N		4	/* N-Phy value */
+-#define	PHY_TYPE_LP		5	/* LP-Phy value */
+-#endif				/* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
+-#if !defined(PHY_TYPE_NULL)
+-#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
+-#endif				/* !defined(PHY_TYPE_NULL) */
+-
+-typedef struct {
+-	u16 phy_type;
+-	u16 bandrange;
+-	u16 chain;
+-	const char *vars;
+-} pavars_t;
+-
+-static const pavars_t pavars[] = {
+-	/* NPHY */
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0,
+-	 "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1,
+-	 "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0,
+-	 "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1,
+-	 "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
+-	/* LPPHY */
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
+-	{PHY_TYPE_NULL, 0, 0, ""}
+-};
+-
+-typedef struct {
+-	u16 phy_type;
+-	u16 bandrange;
+-	const char *vars;
+-} povars_t;
+-
+-static const povars_t povars[] = {
+-	/* NPHY */
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
+-	 "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
+-	 "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
+-	 "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
+-	 "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
+-	 "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
+-	 "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
+-	 "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
+-	 "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
+-	{PHY_TYPE_NULL, 0, ""}
+-};
+-
+-typedef struct {
+-	u8 tag;		/* Broadcom subtag name */
+-	u8 len;		/* Length field of the tuple, note that it includes the
+-				 * subtag name (1 byte): 1 + tuple content length
+-				 */
+-	const char *params;
+-} cis_tuple_t;
+-
+-#define OTP_RAW		(0xff - 1)	/* Reserved tuple number for wrvar Raw input */
+-#define OTP_VERS_1	(0xff - 2)	/* CISTPL_VERS_1 */
+-#define OTP_MANFID	(0xff - 3)	/* CISTPL_MANFID */
+-#define OTP_RAW1	(0xff - 4)	/* Like RAW, but comes first */
+-
+-#endif				/* _bcmsrom_tbl_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h
+deleted file mode 100644
+index d91e418..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/d11.h
++++ /dev/null
+@@ -1,1773 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_D11_H
+-#define	_D11_H
+-
+-#include <sbconfig.h>
+-
+-#ifndef WL_RSSI_ANT_MAX
+-#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
+-#elif WL_RSSI_ANT_MAX != 4
+-#error "WL_RSSI_ANT_MAX does not match"
+-#endif
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef	PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-#define	BCN_TMPL_LEN		512	/* length of the BCN template area */
+-
+-/* RX FIFO numbers */
+-#define	RX_FIFO			0	/* data and ctl frames */
+-#define	RX_TXSTATUS_FIFO	3	/* RX fifo for tx status packages */
+-
+-/* TX FIFO numbers using WME Access Classes */
+-#define	TX_AC_BK_FIFO		0	/* Access Category Background TX FIFO */
+-#define	TX_AC_BE_FIFO		1	/* Access Category Best-Effort TX FIFO */
+-#define	TX_AC_VI_FIFO		2	/* Access Class Video TX FIFO */
+-#define	TX_AC_VO_FIFO		3	/* Access Class Voice TX FIFO */
+-#define	TX_BCMC_FIFO		4	/* Broadcast/Multicast TX FIFO */
+-#define	TX_ATIM_FIFO		5	/* TX fifo for ATIM window info */
+-
+-/* Addr is byte address used by SW; offset is word offset used by uCode */
+-
+-/* Per AC TX limit settings */
+-#define M_AC_TXLMT_BASE_ADDR         (0x180 * 2)
+-#define M_AC_TXLMT_ADDR(_ac)         (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
+-
+-/* Legacy TX FIFO numbers */
+-#define	TX_DATA_FIFO		TX_AC_BE_FIFO
+-#define	TX_CTL_FIFO		TX_AC_VO_FIFO
+-
+-typedef volatile struct {
+-	u32 intstatus;
+-	u32 intmask;
+-} intctrlregs_t;
+-
+-/* PIO structure,
+- *  support two PIO format: 2 bytes access and 4 bytes access
+- *  basic FIFO register set is per channel(transmit or receive)
+- *  a pair of channels is defined for convenience
+- */
+-/* 2byte-wide pio register set per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u16 fifocontrol;
+-	u16 fifodata;
+-	u16 fifofree;	/* only valid in xmt channel, not in rcv channel */
+-	u16 PAD;
+-} pio2regs_t;
+-
+-/* a pair of pio channels(tx and rx) */
+-typedef volatile struct {
+-	pio2regs_t tx;
+-	pio2regs_t rx;
+-} pio2regp_t;
+-
+-/* 4byte-wide pio register set per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 fifocontrol;
+-	u32 fifodata;
+-} pio4regs_t;
+-
+-/* a pair of pio channels(tx and rx) */
+-typedef volatile struct {
+-	pio4regs_t tx;
+-	pio4regs_t rx;
+-} pio4regp_t;
+-
+-/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
+- * write: only low 16b-it half can be written
+- */
+-typedef volatile union {
+-	u32 pmqhostdata;	/* read only! */
+-	struct {
+-		u16 pmqctrlstatus;	/* read/write */
+-		u16 PAD;
+-	} w;
+-} pmqreg_t;
+-
+-typedef volatile struct {
+-	dma64regs_t dmaxmt;	/* dma tx */
+-	pio4regs_t piotx;	/* pio tx */
+-	dma64regs_t dmarcv;	/* dma rx */
+-	pio4regs_t piorx;	/* pio rx */
+-} fifo64_t;
+-
+-/*
+- * Host Interface Registers
+- * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h
+- * - but definitely not complete
+- */
+-typedef volatile struct _d11regs {
+-	/* Device Control ("semi-standard host registers") */
+-	u32 PAD[3];		/* 0x0 - 0x8 */
+-	u32 biststatus;	/* 0xC */
+-	u32 biststatus2;	/* 0x10 */
+-	u32 PAD;		/* 0x14 */
+-	u32 gptimer;		/* 0x18 */
+-	u32 usectimer;	/* 0x1c *//* for corerev >= 26 */
+-
+-	/* Interrupt Control *//* 0x20 */
+-	intctrlregs_t intctrlregs[8];
+-
+-	u32 PAD[40];		/* 0x60 - 0xFC */
+-
+-	u32 intrcvlazy[4];	/* 0x100 - 0x10C */
+-
+-	u32 PAD[4];		/* 0x110 - 0x11c */
+-
+-	u32 maccontrol;	/* 0x120 */
+-	u32 maccommand;	/* 0x124 */
+-	u32 macintstatus;	/* 0x128 */
+-	u32 macintmask;	/* 0x12C */
+-
+-	/* Transmit Template Access */
+-	u32 tplatewrptr;	/* 0x130 */
+-	u32 tplatewrdata;	/* 0x134 */
+-	u32 PAD[2];		/* 0x138 - 0x13C */
+-
+-	/* PMQ registers */
+-	pmqreg_t pmqreg;	/* 0x140 */
+-	u32 pmqpatl;		/* 0x144 */
+-	u32 pmqpath;		/* 0x148 */
+-	u32 PAD;		/* 0x14C */
+-
+-	u32 chnstatus;	/* 0x150 */
+-	u32 psmdebug;	/* 0x154 */
+-	u32 phydebug;	/* 0x158 */
+-	u32 machwcap;	/* 0x15C */
+-
+-	/* Extended Internal Objects */
+-	u32 objaddr;		/* 0x160 */
+-	u32 objdata;		/* 0x164 */
+-	u32 PAD[2];		/* 0x168 - 0x16c */
+-
+-	u32 frmtxstatus;	/* 0x170 */
+-	u32 frmtxstatus2;	/* 0x174 */
+-	u32 PAD[2];		/* 0x178 - 0x17c */
+-
+-	/* TSF host access */
+-	u32 tsf_timerlow;	/* 0x180 */
+-	u32 tsf_timerhigh;	/* 0x184 */
+-	u32 tsf_cfprep;	/* 0x188 */
+-	u32 tsf_cfpstart;	/* 0x18c */
+-	u32 tsf_cfpmaxdur32;	/* 0x190 */
+-	u32 PAD[3];		/* 0x194 - 0x19c */
+-
+-	u32 maccontrol1;	/* 0x1a0 */
+-	u32 machwcap1;	/* 0x1a4 */
+-	u32 PAD[14];		/* 0x1a8 - 0x1dc */
+-
+-	/* Clock control and hardware workarounds*/
+-	u32 clk_ctl_st;	/* 0x1e0 */
+-	u32 hw_war;
+-	u32 d11_phypllctl;	/* the phypll request/avail bits are
+-				 * moved to clk_ctl_st
+-				 */
+-	u32 PAD[5];		/* 0x1ec - 0x1fc */
+-
+-	/* 0x200-0x37F dma/pio registers */
+-	fifo64_t fifo64regs[6];
+-
+-	/* FIFO diagnostic port access */
+-	dma32diag_t dmafifo;	/* 0x380 - 0x38C */
+-
+-	u32 aggfifocnt;	/* 0x390 */
+-	u32 aggfifodata;	/* 0x394 */
+-	u32 PAD[16];		/* 0x398 - 0x3d4 */
+-	u16 radioregaddr;	/* 0x3d8 */
+-	u16 radioregdata;	/* 0x3da */
+-
+-	/*
+-	 * time delay between the change on rf disable input and
+-	 * radio shutdown
+-	 */
+-	u32 rfdisabledly;	/* 0x3DC */
+-
+-	/* PHY register access */
+-	u16 phyversion;	/* 0x3e0 - 0x0 */
+-	u16 phybbconfig;	/* 0x3e2 - 0x1 */
+-	u16 phyadcbias;	/* 0x3e4 - 0x2  Bphy only */
+-	u16 phyanacore;	/* 0x3e6 - 0x3  pwwrdwn on aphy */
+-	u16 phyrxstatus0;	/* 0x3e8 - 0x4 */
+-	u16 phyrxstatus1;	/* 0x3ea - 0x5 */
+-	u16 phycrsth;	/* 0x3ec - 0x6 */
+-	u16 phytxerror;	/* 0x3ee - 0x7 */
+-	u16 phychannel;	/* 0x3f0 - 0x8 */
+-	u16 PAD[1];		/* 0x3f2 - 0x9 */
+-	u16 phytest;		/* 0x3f4 - 0xa */
+-	u16 phy4waddr;	/* 0x3f6 - 0xb */
+-	u16 phy4wdatahi;	/* 0x3f8 - 0xc */
+-	u16 phy4wdatalo;	/* 0x3fa - 0xd */
+-	u16 phyregaddr;	/* 0x3fc - 0xe */
+-	u16 phyregdata;	/* 0x3fe - 0xf */
+-
+-	/* IHR *//* 0x400 - 0x7FE */
+-
+-	/* RXE Block */
+-	u16 PAD[3];		/* 0x400 - 0x406 */
+-	u16 rcv_fifo_ctl;	/* 0x406 */
+-	u16 PAD;		/* 0x408 - 0x40a */
+-	u16 rcv_frm_cnt;	/* 0x40a */
+-	u16 PAD[4];		/* 0x40a - 0x414 */
+-	u16 rssi;		/* 0x414 */
+-	u16 PAD[5];		/* 0x414 - 0x420 */
+-	u16 rcm_ctl;		/* 0x420 */
+-	u16 rcm_mat_data;	/* 0x422 */
+-	u16 rcm_mat_mask;	/* 0x424 */
+-	u16 rcm_mat_dly;	/* 0x426 */
+-	u16 rcm_cond_mask_l;	/* 0x428 */
+-	u16 rcm_cond_mask_h;	/* 0x42A */
+-	u16 rcm_cond_dly;	/* 0x42C */
+-	u16 PAD[1];		/* 0x42E */
+-	u16 ext_ihr_addr;	/* 0x430 */
+-	u16 ext_ihr_data;	/* 0x432 */
+-	u16 rxe_phyrs_2;	/* 0x434 */
+-	u16 rxe_phyrs_3;	/* 0x436 */
+-	u16 phy_mode;	/* 0x438 */
+-	u16 rcmta_ctl;	/* 0x43a */
+-	u16 rcmta_size;	/* 0x43c */
+-	u16 rcmta_addr0;	/* 0x43e */
+-	u16 rcmta_addr1;	/* 0x440 */
+-	u16 rcmta_addr2;	/* 0x442 */
+-	u16 PAD[30];		/* 0x444 - 0x480 */
+-
+-	/* PSM Block *//* 0x480 - 0x500 */
+-
+-	u16 PAD;		/* 0x480 */
+-	u16 psm_maccontrol_h;	/* 0x482 */
+-	u16 psm_macintstatus_l;	/* 0x484 */
+-	u16 psm_macintstatus_h;	/* 0x486 */
+-	u16 psm_macintmask_l;	/* 0x488 */
+-	u16 psm_macintmask_h;	/* 0x48A */
+-	u16 PAD;		/* 0x48C */
+-	u16 psm_maccommand;	/* 0x48E */
+-	u16 psm_brc;		/* 0x490 */
+-	u16 psm_phy_hdr_param;	/* 0x492 */
+-	u16 psm_postcard;	/* 0x494 */
+-	u16 psm_pcard_loc_l;	/* 0x496 */
+-	u16 psm_pcard_loc_h;	/* 0x498 */
+-	u16 psm_gpio_in;	/* 0x49A */
+-	u16 psm_gpio_out;	/* 0x49C */
+-	u16 psm_gpio_oe;	/* 0x49E */
+-
+-	u16 psm_bred_0;	/* 0x4A0 */
+-	u16 psm_bred_1;	/* 0x4A2 */
+-	u16 psm_bred_2;	/* 0x4A4 */
+-	u16 psm_bred_3;	/* 0x4A6 */
+-	u16 psm_brcl_0;	/* 0x4A8 */
+-	u16 psm_brcl_1;	/* 0x4AA */
+-	u16 psm_brcl_2;	/* 0x4AC */
+-	u16 psm_brcl_3;	/* 0x4AE */
+-	u16 psm_brpo_0;	/* 0x4B0 */
+-	u16 psm_brpo_1;	/* 0x4B2 */
+-	u16 psm_brpo_2;	/* 0x4B4 */
+-	u16 psm_brpo_3;	/* 0x4B6 */
+-	u16 psm_brwk_0;	/* 0x4B8 */
+-	u16 psm_brwk_1;	/* 0x4BA */
+-	u16 psm_brwk_2;	/* 0x4BC */
+-	u16 psm_brwk_3;	/* 0x4BE */
+-
+-	u16 psm_base_0;	/* 0x4C0 */
+-	u16 psm_base_1;	/* 0x4C2 */
+-	u16 psm_base_2;	/* 0x4C4 */
+-	u16 psm_base_3;	/* 0x4C6 */
+-	u16 psm_base_4;	/* 0x4C8 */
+-	u16 psm_base_5;	/* 0x4CA */
+-	u16 psm_base_6;	/* 0x4CC */
+-	u16 psm_pc_reg_0;	/* 0x4CE */
+-	u16 psm_pc_reg_1;	/* 0x4D0 */
+-	u16 psm_pc_reg_2;	/* 0x4D2 */
+-	u16 psm_pc_reg_3;	/* 0x4D4 */
+-	u16 PAD[0xD];	/* 0x4D6 - 0x4DE */
+-	u16 psm_corectlsts;	/* 0x4f0 *//* Corerev >= 13 */
+-	u16 PAD[0x7];	/* 0x4f2 - 0x4fE */
+-
+-	/* TXE0 Block *//* 0x500 - 0x580 */
+-	u16 txe_ctl;		/* 0x500 */
+-	u16 txe_aux;		/* 0x502 */
+-	u16 txe_ts_loc;	/* 0x504 */
+-	u16 txe_time_out;	/* 0x506 */
+-	u16 txe_wm_0;	/* 0x508 */
+-	u16 txe_wm_1;	/* 0x50A */
+-	u16 txe_phyctl;	/* 0x50C */
+-	u16 txe_status;	/* 0x50E */
+-	u16 txe_mmplcp0;	/* 0x510 */
+-	u16 txe_mmplcp1;	/* 0x512 */
+-	u16 txe_phyctl1;	/* 0x514 */
+-
+-	u16 PAD[0x05];	/* 0x510 - 0x51E */
+-
+-	/* Transmit control */
+-	u16 xmtfifodef;	/* 0x520 */
+-	u16 xmtfifo_frame_cnt;	/* 0x522 *//* Corerev >= 16 */
+-	u16 xmtfifo_byte_cnt;	/* 0x524 *//* Corerev >= 16 */
+-	u16 xmtfifo_head;	/* 0x526 *//* Corerev >= 16 */
+-	u16 xmtfifo_rd_ptr;	/* 0x528 *//* Corerev >= 16 */
+-	u16 xmtfifo_wr_ptr;	/* 0x52A *//* Corerev >= 16 */
+-	u16 xmtfifodef1;	/* 0x52C *//* Corerev >= 16 */
+-
+-	u16 PAD[0x09];	/* 0x52E - 0x53E */
+-
+-	u16 xmtfifocmd;	/* 0x540 */
+-	u16 xmtfifoflush;	/* 0x542 */
+-	u16 xmtfifothresh;	/* 0x544 */
+-	u16 xmtfifordy;	/* 0x546 */
+-	u16 xmtfifoprirdy;	/* 0x548 */
+-	u16 xmtfiforqpri;	/* 0x54A */
+-	u16 xmttplatetxptr;	/* 0x54C */
+-	u16 PAD;		/* 0x54E */
+-	u16 xmttplateptr;	/* 0x550 */
+-	u16 smpl_clct_strptr;	/* 0x552 *//* Corerev >= 22 */
+-	u16 smpl_clct_stpptr;	/* 0x554 *//* Corerev >= 22 */
+-	u16 smpl_clct_curptr;	/* 0x556 *//* Corerev >= 22 */
+-	u16 PAD[0x04];	/* 0x558 - 0x55E */
+-	u16 xmttplatedatalo;	/* 0x560 */
+-	u16 xmttplatedatahi;	/* 0x562 */
+-
+-	u16 PAD[2];		/* 0x564 - 0x566 */
+-
+-	u16 xmtsel;		/* 0x568 */
+-	u16 xmttxcnt;	/* 0x56A */
+-	u16 xmttxshmaddr;	/* 0x56C */
+-
+-	u16 PAD[0x09];	/* 0x56E - 0x57E */
+-
+-	/* TXE1 Block */
+-	u16 PAD[0x40];	/* 0x580 - 0x5FE */
+-
+-	/* TSF Block */
+-	u16 PAD[0X02];	/* 0x600 - 0x602 */
+-	u16 tsf_cfpstrt_l;	/* 0x604 */
+-	u16 tsf_cfpstrt_h;	/* 0x606 */
+-	u16 PAD[0X05];	/* 0x608 - 0x610 */
+-	u16 tsf_cfppretbtt;	/* 0x612 */
+-	u16 PAD[0XD];	/* 0x614 - 0x62C */
+-	u16 tsf_clk_frac_l;	/* 0x62E */
+-	u16 tsf_clk_frac_h;	/* 0x630 */
+-	u16 PAD[0X14];	/* 0x632 - 0x658 */
+-	u16 tsf_random;	/* 0x65A */
+-	u16 PAD[0x05];	/* 0x65C - 0x664 */
+-	/* GPTimer 2 registers */
+-	u16 tsf_gpt2_stat;	/* 0x666 */
+-	u16 tsf_gpt2_ctr_l;	/* 0x668 */
+-	u16 tsf_gpt2_ctr_h;	/* 0x66A */
+-	u16 tsf_gpt2_val_l;	/* 0x66C */
+-	u16 tsf_gpt2_val_h;	/* 0x66E */
+-	u16 tsf_gptall_stat;	/* 0x670 */
+-	u16 PAD[0x07];	/* 0x672 - 0x67E */
+-
+-	/* IFS Block */
+-	u16 ifs_sifs_rx_tx_tx;	/* 0x680 */
+-	u16 ifs_sifs_nav_tx;	/* 0x682 */
+-	u16 ifs_slot;	/* 0x684 */
+-	u16 PAD;		/* 0x686 */
+-	u16 ifs_ctl;		/* 0x688 */
+-	u16 PAD[0x3];	/* 0x68a - 0x68F */
+-	u16 ifsstat;		/* 0x690 */
+-	u16 ifsmedbusyctl;	/* 0x692 */
+-	u16 iftxdur;		/* 0x694 */
+-	u16 PAD[0x3];	/* 0x696 - 0x69b */
+-	/* EDCF support in dot11macs */
+-	u16 ifs_aifsn;	/* 0x69c */
+-	u16 ifs_ctl1;	/* 0x69e */
+-
+-	/* slow clock registers */
+-	u16 scc_ctl;		/* 0x6a0 */
+-	u16 scc_timer_l;	/* 0x6a2 */
+-	u16 scc_timer_h;	/* 0x6a4 */
+-	u16 scc_frac;	/* 0x6a6 */
+-	u16 scc_fastpwrup_dly;	/* 0x6a8 */
+-	u16 scc_per;		/* 0x6aa */
+-	u16 scc_per_frac;	/* 0x6ac */
+-	u16 scc_cal_timer_l;	/* 0x6ae */
+-	u16 scc_cal_timer_h;	/* 0x6b0 */
+-	u16 PAD;		/* 0x6b2 */
+-
+-	u16 PAD[0x26];
+-
+-	/* NAV Block */
+-	u16 nav_ctl;		/* 0x700 */
+-	u16 navstat;		/* 0x702 */
+-	u16 PAD[0x3e];	/* 0x702 - 0x77E */
+-
+-	/* WEP/PMQ Block *//* 0x780 - 0x7FE */
+-	u16 PAD[0x20];	/* 0x780 - 0x7BE */
+-
+-	u16 wepctl;		/* 0x7C0 */
+-	u16 wepivloc;	/* 0x7C2 */
+-	u16 wepivkey;	/* 0x7C4 */
+-	u16 wepwkey;		/* 0x7C6 */
+-
+-	u16 PAD[4];		/* 0x7C8 - 0x7CE */
+-	u16 pcmctl;		/* 0X7D0 */
+-	u16 pcmstat;		/* 0X7D2 */
+-	u16 PAD[6];		/* 0x7D4 - 0x7DE */
+-
+-	u16 pmqctl;		/* 0x7E0 */
+-	u16 pmqstatus;	/* 0x7E2 */
+-	u16 pmqpat0;		/* 0x7E4 */
+-	u16 pmqpat1;		/* 0x7E6 */
+-	u16 pmqpat2;		/* 0x7E8 */
+-
+-	u16 pmqdat;		/* 0x7EA */
+-	u16 pmqdator;	/* 0x7EC */
+-	u16 pmqhst;		/* 0x7EE */
+-	u16 pmqpath0;	/* 0x7F0 */
+-	u16 pmqpath1;	/* 0x7F2 */
+-	u16 pmqpath2;	/* 0x7F4 */
+-	u16 pmqdath;		/* 0x7F6 */
+-
+-	u16 PAD[0x04];	/* 0x7F8 - 0x7FE */
+-
+-	/* SHM *//* 0x800 - 0xEFE */
+-	u16 PAD[0x380];	/* 0x800 - 0xEFE */
+-
+-	/* SB configuration registers: 0xF00 */
+-	sbconfig_t sbconfig;	/* sb config regs occupy top 256 bytes */
+-} d11regs_t;
+-
+-#define	PIHR_BASE	0x0400	/* byte address of packed IHR region */
+-
+-/* biststatus */
+-#define	BT_DONE		(1U << 31)	/* bist done */
+-#define	BT_B2S		(1 << 30)	/* bist2 ram summary bit */
+-
+-/* intstatus and intmask */
+-#define	I_PC		(1 << 10)	/* pci descriptor error */
+-#define	I_PD		(1 << 11)	/* pci data error */
+-#define	I_DE		(1 << 12)	/* descriptor protocol error */
+-#define	I_RU		(1 << 13)	/* receive descriptor underflow */
+-#define	I_RO		(1 << 14)	/* receive fifo overflow */
+-#define	I_XU		(1 << 15)	/* transmit fifo underflow */
+-#define	I_RI		(1 << 16)	/* receive interrupt */
+-#define	I_XI		(1 << 24)	/* transmit interrupt */
+-
+-/* interrupt receive lazy */
+-#define	IRL_TO_MASK		0x00ffffff	/* timeout */
+-#define	IRL_FC_MASK		0xff000000	/* frame count */
+-#define	IRL_FC_SHIFT		24	/* frame count */
+-
+-/* maccontrol register */
+-#define	MCTL_GMODE		(1U << 31)
+-#define	MCTL_DISCARD_PMQ	(1 << 30)
+-#define	MCTL_WAKE		(1 << 26)
+-#define	MCTL_HPS		(1 << 25)
+-#define	MCTL_PROMISC		(1 << 24)
+-#define	MCTL_KEEPBADFCS		(1 << 23)
+-#define	MCTL_KEEPCONTROL	(1 << 22)
+-#define	MCTL_PHYLOCK		(1 << 21)
+-#define	MCTL_BCNS_PROMISC	(1 << 20)
+-#define	MCTL_LOCK_RADIO		(1 << 19)
+-#define	MCTL_AP			(1 << 18)
+-#define	MCTL_INFRA		(1 << 17)
+-#define	MCTL_BIGEND		(1 << 16)
+-#define	MCTL_GPOUT_SEL_MASK	(3 << 14)
+-#define	MCTL_GPOUT_SEL_SHIFT	14
+-#define	MCTL_EN_PSMDBG		(1 << 13)
+-#define	MCTL_IHR_EN		(1 << 10)
+-#define	MCTL_SHM_UPPER		(1 <<  9)
+-#define	MCTL_SHM_EN		(1 <<  8)
+-#define	MCTL_PSM_JMP_0		(1 <<  2)
+-#define	MCTL_PSM_RUN		(1 <<  1)
+-#define	MCTL_EN_MAC		(1 <<  0)
+-
+-/* maccommand register */
+-#define	MCMD_BCN0VLD		(1 <<  0)
+-#define	MCMD_BCN1VLD		(1 <<  1)
+-#define	MCMD_DIRFRMQVAL		(1 <<  2)
+-#define	MCMD_CCA		(1 <<  3)
+-#define	MCMD_BG_NOISE		(1 <<  4)
+-#define	MCMD_SKIP_SHMINIT	(1 <<  5)	/* only used for simulation */
+-#define MCMD_SAMPLECOLL		MCMD_SKIP_SHMINIT	/* reuse for sample collect */
+-
+-/* macintstatus/macintmask */
+-#define	MI_MACSSPNDD		(1 <<  0)	/* MAC has gracefully suspended */
+-#define	MI_BCNTPL		(1 <<  1)	/* beacon template available */
+-#define	MI_TBTT			(1 <<  2)	/* TBTT indication */
+-#define	MI_BCNSUCCESS		(1 <<  3)	/* beacon successfully tx'd */
+-#define	MI_BCNCANCLD		(1 <<  4)	/* beacon canceled (IBSS) */
+-#define	MI_ATIMWINEND		(1 <<  5)	/* end of ATIM-window (IBSS) */
+-#define	MI_PMQ			(1 <<  6)	/* PMQ entries available */
+-#define	MI_NSPECGEN_0		(1 <<  7)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_NSPECGEN_1		(1 <<  8)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_MACTXERR		(1 <<  9)	/* MAC level Tx error */
+-#define	MI_NSPECGEN_3		(1 << 10)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_PHYTXERR		(1 << 11)	/* PHY Tx error */
+-#define	MI_PME			(1 << 12)	/* Power Management Event */
+-#define	MI_GP0			(1 << 13)	/* General-purpose timer0 */
+-#define	MI_GP1			(1 << 14)	/* General-purpose timer1 */
+-#define	MI_DMAINT		(1 << 15)	/* (ORed) DMA-interrupts */
+-#define	MI_TXSTOP		(1 << 16)	/* MAC has completed a TX FIFO Suspend/Flush */
+-#define	MI_CCA			(1 << 17)	/* MAC has completed a CCA measurement */
+-#define	MI_BG_NOISE		(1 << 18)	/* MAC has collected background noise samples */
+-#define	MI_DTIM_TBTT		(1 << 19)	/* MBSS DTIM TBTT indication */
+-#define MI_PRQ			(1 << 20)	/* Probe response queue needs attention */
+-#define	MI_PWRUP		(1 << 21)	/* Radio/PHY has been powered back up. */
+-#define	MI_RESERVED3		(1 << 22)
+-#define	MI_RESERVED2		(1 << 23)
+-#define MI_RESERVED1		(1 << 25)
+-/* MAC detected change on RF Disable input*/
+-#define MI_RFDISABLE		(1 << 28)
+-#define	MI_TFS			(1 << 29)	/* MAC has completed a TX */
+-#define	MI_PHYCHANGED		(1 << 30)	/* A phy status change wrt G mode */
+-#define	MI_TO			(1U << 31)	/* general purpose timeout */
+-
+-/* Mac capabilities registers */
+-/* machwcap */
+-#define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
+-
+-/* pmqhost data */
+-#define	PMQH_DATA_MASK		0xffff0000	/* data entry of head pmq entry */
+-#define	PMQH_BSSCFG		0x00100000	/* PM entry for BSS config */
+-#define	PMQH_PMOFF		0x00010000	/* PM Mode OFF: power save off */
+-#define	PMQH_PMON		0x00020000	/* PM Mode ON: power save on */
+-#define	PMQH_DASAT		0x00040000	/* Dis-associated or De-authenticated */
+-#define	PMQH_ATIMFAIL		0x00080000	/* ATIM not acknowledged */
+-#define	PMQH_DEL_ENTRY		0x00000001	/* delete head entry */
+-#define	PMQH_DEL_MULT		0x00000002	/* delete head entry to cur read pointer -1 */
+-#define	PMQH_OFLO		0x00000004	/* pmq overflow indication */
+-#define	PMQH_NOT_EMPTY		0x00000008	/* entries are present in pmq */
+-
+-/* phydebug */
+-#define	PDBG_CRS		(1 << 0)	/* phy is asserting carrier sense */
+-#define	PDBG_TXA		(1 << 1)	/* phy is taking xmit byte from mac this cycle */
+-#define	PDBG_TXF		(1 << 2)	/* mac is instructing the phy to transmit a frame */
+-#define	PDBG_TXE		(1 << 3)	/* phy is signalling a transmit Error to the mac */
+-#define	PDBG_RXF		(1 << 4)	/* phy detected the end of a valid frame preamble */
+-#define	PDBG_RXS		(1 << 5)	/* phy detected the end of a valid PLCP header */
+-#define	PDBG_RXFRG		(1 << 6)	/* rx start not asserted */
+-#define	PDBG_RXV		(1 << 7)	/* mac is taking receive byte from phy this cycle */
+-#define	PDBG_RFD		(1 << 16)	/* RF portion of the radio is disabled */
+-
+-/* objaddr register */
+-#define	OBJADDR_SEL_MASK	0x000F0000
+-#define	OBJADDR_UCM_SEL		0x00000000
+-#define	OBJADDR_SHM_SEL		0x00010000
+-#define	OBJADDR_SCR_SEL		0x00020000
+-#define	OBJADDR_IHR_SEL		0x00030000
+-#define	OBJADDR_RCMTA_SEL	0x00040000
+-#define	OBJADDR_SRCHM_SEL	0x00060000
+-#define	OBJADDR_WINC		0x01000000
+-#define	OBJADDR_RINC		0x02000000
+-#define	OBJADDR_AUTO_INC	0x03000000
+-
+-#define	WEP_PCMADDR		0x07d4
+-#define	WEP_PCMDATA		0x07d6
+-
+-/* frmtxstatus */
+-#define	TXS_V			(1 << 0)	/* valid bit */
+-#define	TXS_STATUS_MASK		0xffff
+-#define	TXS_FID_MASK		0xffff0000
+-#define	TXS_FID_SHIFT		16
+-
+-/* frmtxstatus2 */
+-#define	TXS_SEQ_MASK		0xffff
+-#define	TXS_PTX_MASK		0xff0000
+-#define	TXS_PTX_SHIFT		16
+-#define	TXS_MU_MASK		0x01000000
+-#define	TXS_MU_SHIFT		24
+-
+-/* clk_ctl_st */
+-#define CCS_ERSRC_REQ_D11PLL	0x00000100	/* d11 core pll request */
+-#define CCS_ERSRC_REQ_PHYPLL	0x00000200	/* PHY pll request */
+-#define CCS_ERSRC_AVAIL_D11PLL	0x01000000	/* d11 core pll available */
+-#define CCS_ERSRC_AVAIL_PHYPLL	0x02000000	/* PHY pll available */
+-
+-/* HT Cloclk Ctrl and Clock Avail for 4313 */
+-#define CCS_ERSRC_REQ_HT    0x00000010	/* HT avail request */
+-#define CCS_ERSRC_AVAIL_HT  0x00020000	/* HT clock available */
+-
+-/* tsf_cfprep register */
+-#define	CFPREP_CBI_MASK		0xffffffc0
+-#define	CFPREP_CBI_SHIFT	6
+-#define	CFPREP_CFPP		0x00000001
+-
+-/* tx fifo sizes values are in terms of 256 byte blocks */
+-#define TXFIFOCMD_RESET_MASK	(1 << 15)	/* reset */
+-#define TXFIFOCMD_FIFOSEL_SHIFT	8	/* fifo */
+-#define TXFIFO_FIFOTOP_SHIFT	8	/* fifo start */
+-
+-#define TXFIFO_START_BLK16	 65	/* Base address + 32 * 512 B/P */
+-#define TXFIFO_START_BLK	 6	/* Base address + 6 * 256 B */
+-#define TXFIFO_SIZE_UNIT	256	/* one unit corresponds to 256 bytes */
+-#define MBSS16_TEMPLMEM_MINBLKS	65	/* one unit corresponds to 256 bytes */
+-
+-/* phy versions, PhyVersion:Revision field */
+-#define	PV_AV_MASK		0xf000	/* analog block version */
+-#define	PV_AV_SHIFT		12	/* analog block version bitfield offset */
+-#define	PV_PT_MASK		0x0f00	/* phy type */
+-#define	PV_PT_SHIFT		8	/* phy type bitfield offset */
+-#define	PV_PV_MASK		0x000f	/* phy version */
+-#define	PHY_TYPE(v)		((v & PV_PT_MASK) >> PV_PT_SHIFT)
+-
+-/* phy types, PhyVersion:PhyType field */
+-#define	PHY_TYPE_N		4	/* N-Phy value */
+-#define	PHY_TYPE_SSN		6	/* SSLPN-Phy value */
+-#define	PHY_TYPE_LCN		8	/* LCN-Phy value */
+-#define	PHY_TYPE_LCNXN		9	/* LCNXN-Phy value */
+-#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
+-
+-/* analog types, PhyVersion:AnalogType field */
+-#define	ANA_11N_013		5
+-
+-/* 802.11a PLCP header def */
+-typedef struct ofdm_phy_hdr ofdm_phy_hdr_t;
+-struct ofdm_phy_hdr {
+-	u8 rlpt[3];		/* rate, length, parity, tail */
+-	u16 service;
+-	u8 pad;
+-} __attribute__((packed));
+-
+-#define	D11A_PHY_HDR_GRATE(phdr)	((phdr)->rlpt[0] & 0x0f)
+-#define	D11A_PHY_HDR_GRES(phdr)		(((phdr)->rlpt[0] >> 4) & 0x01)
+-#define	D11A_PHY_HDR_GLENGTH(phdr)	(((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
+-#define	D11A_PHY_HDR_GPARITY(phdr)	(((phdr)->rlpt[3] >> 1) & 0x01)
+-#define	D11A_PHY_HDR_GTAIL(phdr)	(((phdr)->rlpt[3] >> 2) & 0x3f)
+-
+-/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
+-#define	D11A_PHY_HDR_SRATE(phdr, rate)		\
+-	((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
+-/* set reserved field to zero */
+-#define	D11A_PHY_HDR_SRES(phdr)		((phdr)->rlpt[0] &= 0xef)
+-/* length is number of octets in PSDU */
+-#define	D11A_PHY_HDR_SLENGTH(phdr, length)	\
+-	(*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
+-	(((length) & 0x0fff) << 5))
+-/* set the tail to all zeros */
+-#define	D11A_PHY_HDR_STAIL(phdr)	((phdr)->rlpt[3] &= 0x03)
+-
+-#define	D11A_PHY_HDR_LEN_L	3	/* low-rate part of PLCP header */
+-#define	D11A_PHY_HDR_LEN_R	2	/* high-rate part of PLCP header */
+-
+-#define	D11A_PHY_TX_DELAY	(2)	/* 2.1 usec */
+-
+-#define	D11A_PHY_HDR_TIME	(4)	/* low-rate part of PLCP header */
+-#define	D11A_PHY_PRE_TIME	(16)
+-#define	D11A_PHY_PREHDR_TIME	(D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
+-
+-/* 802.11b PLCP header def */
+-typedef struct cck_phy_hdr cck_phy_hdr_t;
+-struct cck_phy_hdr {
+-	u8 signal;
+-	u8 service;
+-	u16 length;
+-	u16 crc;
+-} __attribute__((packed));
+-
+-#define	D11B_PHY_HDR_LEN	6
+-
+-#define	D11B_PHY_TX_DELAY	(3)	/* 3.4 usec */
+-
+-#define	D11B_PHY_LHDR_TIME	(D11B_PHY_HDR_LEN << 3)
+-#define	D11B_PHY_LPRE_TIME	(144)
+-#define	D11B_PHY_LPREHDR_TIME	(D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
+-
+-#define	D11B_PHY_SHDR_TIME	(D11B_PHY_LHDR_TIME >> 1)
+-#define	D11B_PHY_SPRE_TIME	(D11B_PHY_LPRE_TIME >> 1)
+-#define	D11B_PHY_SPREHDR_TIME	(D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
+-
+-#define	D11B_PLCP_SIGNAL_LOCKED	(1 << 2)
+-#define	D11B_PLCP_SIGNAL_LE	(1 << 7)
+-
+-#define MIMO_PLCP_MCS_MASK	0x7f	/* mcs index */
+-#define MIMO_PLCP_40MHZ		0x80	/* 40 Hz frame */
+-#define MIMO_PLCP_AMPDU		0x08	/* ampdu */
+-
+-#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
+-#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
+-#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \
+-	do { \
+-		plcp[1] = len & 0xff; \
+-		plcp[2] = ((len >> 8) & 0xff); \
+-	} while (0);
+-
+-#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
+-#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
+-#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
+-
+-/* The dot11a PLCP header is 5 bytes.  To simplify the software (so that we
+- * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has
+- * padding added in the ucode.
+- */
+-#define	D11_PHY_HDR_LEN	6
+-
+-/* TX DMA buffer header */
+-typedef struct d11txh d11txh_t;
+-struct d11txh {
+-	u16 MacTxControlLow;	/* 0x0 */
+-	u16 MacTxControlHigh;	/* 0x1 */
+-	u16 MacFrameControl;	/* 0x2 */
+-	u16 TxFesTimeNormal;	/* 0x3 */
+-	u16 PhyTxControlWord;	/* 0x4 */
+-	u16 PhyTxControlWord_1;	/* 0x5 */
+-	u16 PhyTxControlWord_1_Fbr;	/* 0x6 */
+-	u16 PhyTxControlWord_1_Rts;	/* 0x7 */
+-	u16 PhyTxControlWord_1_FbrRts;	/* 0x8 */
+-	u16 MainRates;	/* 0x9 */
+-	u16 XtraFrameTypes;	/* 0xa */
+-	u8 IV[16];		/* 0x0b - 0x12 */
+-	u8 TxFrameRA[6];	/* 0x13 - 0x15 */
+-	u16 TxFesTimeFallback;	/* 0x16 */
+-	u8 RTSPLCPFallback[6];	/* 0x17 - 0x19 */
+-	u16 RTSDurFallback;	/* 0x1a */
+-	u8 FragPLCPFallback[6];	/* 0x1b - 1d */
+-	u16 FragDurFallback;	/* 0x1e */
+-	u16 MModeLen;	/* 0x1f */
+-	u16 MModeFbrLen;	/* 0x20 */
+-	u16 TstampLow;	/* 0x21 */
+-	u16 TstampHigh;	/* 0x22 */
+-	u16 ABI_MimoAntSel;	/* 0x23 */
+-	u16 PreloadSize;	/* 0x24 */
+-	u16 AmpduSeqCtl;	/* 0x25 */
+-	u16 TxFrameID;	/* 0x26 */
+-	u16 TxStatus;	/* 0x27 */
+-	u16 MaxNMpdus;	/* 0x28 */
+-	u16 MaxABytes_MRT;	/* 0x29 */
+-	u16 MaxABytes_FBR;	/* 0x2a */
+-	u16 MinMBytes;	/* 0x2b */
+-	u8 RTSPhyHeader[D11_PHY_HDR_LEN];	/* 0x2c - 0x2e */
+-	struct ieee80211_rts rts_frame;	/* 0x2f - 0x36 */
+-	u16 PAD;		/* 0x37 */
+-} __attribute__((packed));
+-
+-#define	D11_TXH_LEN		112	/* bytes */
+-
+-/* Frame Types */
+-#define FT_CCK	0
+-#define FT_OFDM	1
+-#define FT_HT	2
+-#define FT_N	3
+-
+-/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */
+-#define TXC_AMPDU_SHIFT		9	/* shift for ampdu settings */
+-#define TXC_AMPDU_NONE		0	/* Regular MPDU, not an A-MPDU */
+-#define TXC_AMPDU_FIRST		1	/* first MPDU of an A-MPDU */
+-#define TXC_AMPDU_MIDDLE	2	/* intermediate MPDU of an A-MPDU */
+-#define TXC_AMPDU_LAST		3	/* last (or single) MPDU of an A-MPDU */
+-
+-/* MacTxControlLow */
+-#define TXC_AMIC		0x8000
+-#define	TXC_SENDCTS		0x0800
+-#define TXC_AMPDU_MASK		0x0600
+-#define TXC_BW_40		0x0100
+-#define TXC_FREQBAND_5G		0x0080
+-#define	TXC_DFCS		0x0040
+-#define	TXC_IGNOREPMQ		0x0020
+-#define	TXC_HWSEQ		0x0010
+-#define	TXC_STARTMSDU		0x0008
+-#define	TXC_SENDRTS		0x0004
+-#define	TXC_LONGFRAME		0x0002
+-#define	TXC_IMMEDACK		0x0001
+-
+-/* MacTxControlHigh */
+-#define TXC_PREAMBLE_RTS_FB_SHORT	0x8000	/* RTS fallback preamble type 1 = SHORT 0 = LONG */
+-#define TXC_PREAMBLE_RTS_MAIN_SHORT	0x4000	/* RTS main rate preamble type 1 = SHORT 0 = LONG */
+-#define TXC_PREAMBLE_DATA_FB_SHORT	0x2000	/* Main fallback rate preamble type
+-						 * 1 = SHORT for OFDM/GF for MIMO
+-						 * 0 = LONG for CCK/MM for MIMO
+-						 */
+-/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
+-#define	TXC_AMPDU_FBR		0x1000	/* use fallback rate for this AMPDU */
+-#define	TXC_SECKEY_MASK		0x0FF0
+-#define	TXC_SECKEY_SHIFT	4
+-#define	TXC_ALT_TXPWR		0x0008	/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
+-#define	TXC_SECTYPE_MASK	0x0007
+-#define	TXC_SECTYPE_SHIFT	0
+-
+-/* Null delimiter for Fallback rate */
+-#define AMPDU_FBR_NULL_DELIM  5	/* Location of Null delimiter count for AMPDU */
+-
+-/* PhyTxControl for Mimophy */
+-#define	PHY_TXC_PWR_MASK	0xFC00
+-#define	PHY_TXC_PWR_SHIFT	10
+-#define	PHY_TXC_ANT_MASK	0x03C0	/* bit 6, 7, 8, 9 */
+-#define	PHY_TXC_ANT_SHIFT	6
+-#define	PHY_TXC_ANT_0_1		0x00C0	/* auto, last rx */
+-#define	PHY_TXC_LCNPHY_ANT_LAST	0x0000
+-#define	PHY_TXC_ANT_3		0x0200	/* virtual antenna 3 */
+-#define	PHY_TXC_ANT_2		0x0100	/* virtual antenna 2 */
+-#define	PHY_TXC_ANT_1		0x0080	/* virtual antenna 1 */
+-#define	PHY_TXC_ANT_0		0x0040	/* virtual antenna 0 */
+-#define	PHY_TXC_SHORT_HDR	0x0010
+-
+-#define	PHY_TXC_OLD_ANT_0	0x0000
+-#define	PHY_TXC_OLD_ANT_1	0x0100
+-#define	PHY_TXC_OLD_ANT_LAST	0x0300
+-
+-/* PhyTxControl_1 for Mimophy */
+-#define PHY_TXC1_BW_MASK		0x0007
+-#define PHY_TXC1_BW_10MHZ		0
+-#define PHY_TXC1_BW_10MHZ_UP		1
+-#define PHY_TXC1_BW_20MHZ		2
+-#define PHY_TXC1_BW_20MHZ_UP		3
+-#define PHY_TXC1_BW_40MHZ		4
+-#define PHY_TXC1_BW_40MHZ_DUP		5
+-#define PHY_TXC1_MODE_SHIFT		3
+-#define PHY_TXC1_MODE_MASK		0x0038
+-#define PHY_TXC1_MODE_SISO		0
+-#define PHY_TXC1_MODE_CDD		1
+-#define PHY_TXC1_MODE_STBC		2
+-#define PHY_TXC1_MODE_SDM		3
+-
+-/* PhyTxControl for HTphy that are different from Mimophy */
+-#define	PHY_TXC_HTANT_MASK		0x3fC0	/* bit 6, 7, 8, 9, 10, 11, 12, 13 */
+-
+-/* XtraFrameTypes */
+-#define XFTS_RTS_FT_SHIFT	2
+-#define XFTS_FBRRTS_FT_SHIFT	4
+-#define XFTS_CHANNEL_SHIFT	8
+-
+-/* Antenna diversity bit in ant_wr_settle */
+-#define	PHY_AWS_ANTDIV		0x2000
+-
+-/* IFS ctl */
+-#define IFS_USEEDCF	(1 << 2)
+-
+-/* IFS ctl1 */
+-#define IFS_CTL1_EDCRS	(1 << 3)
+-#define IFS_CTL1_EDCRS_20L (1 << 4)
+-#define IFS_CTL1_EDCRS_40 (1 << 5)
+-
+-/* ABI_MimoAntSel */
+-#define ABI_MAS_ADDR_BMP_IDX_MASK	0x0f00
+-#define ABI_MAS_ADDR_BMP_IDX_SHIFT	8
+-#define ABI_MAS_FBR_ANT_PTN_MASK	0x00f0
+-#define ABI_MAS_FBR_ANT_PTN_SHIFT	4
+-#define ABI_MAS_MRT_ANT_PTN_MASK	0x000f
+-
+-/* tx status packet */
+-typedef struct tx_status tx_status_t;
+-struct tx_status {
+-	u16 framelen;
+-	u16 PAD;
+-	u16 frameid;
+-	u16 status;
+-	u16 lasttxtime;
+-	u16 sequence;
+-	u16 phyerr;
+-	u16 ackphyrxsh;
+-} __attribute__((packed));
+-
+-#define	TXSTATUS_LEN	16
+-
+-/* status field bit definitions */
+-#define	TX_STATUS_FRM_RTX_MASK	0xF000
+-#define	TX_STATUS_FRM_RTX_SHIFT	12
+-#define	TX_STATUS_RTS_RTX_MASK	0x0F00
+-#define	TX_STATUS_RTS_RTX_SHIFT	8
+-#define TX_STATUS_MASK		0x00FE
+-#define	TX_STATUS_PMINDCTD	(1 << 7)	/* PM mode indicated to AP */
+-#define	TX_STATUS_INTERMEDIATE	(1 << 6)	/* intermediate or 1st ampdu pkg */
+-#define	TX_STATUS_AMPDU		(1 << 5)	/* AMPDU status */
+-#define TX_STATUS_SUPR_MASK	0x1C	/* suppress status bits (4:2) */
+-#define TX_STATUS_SUPR_SHIFT	2
+-#define	TX_STATUS_ACK_RCV	(1 << 1)	/* ACK received */
+-#define	TX_STATUS_VALID		(1 << 0)	/* Tx status valid */
+-#define	TX_STATUS_NO_ACK	0
+-
+-/* suppress status reason codes */
+-#define	TX_STATUS_SUPR_PMQ	(1 << 2)	/* PMQ entry */
+-#define	TX_STATUS_SUPR_FLUSH	(2 << 2)	/* flush request */
+-#define	TX_STATUS_SUPR_FRAG	(3 << 2)	/* previous frag failure */
+-#define	TX_STATUS_SUPR_TBTT	(3 << 2)	/* SHARED: Probe response supr for TBTT */
+-#define	TX_STATUS_SUPR_BADCH	(4 << 2)	/* channel mismatch */
+-#define	TX_STATUS_SUPR_EXPTIME	(5 << 2)	/* lifetime expiry */
+-#define	TX_STATUS_SUPR_UF	(6 << 2)	/* underflow */
+-
+-/* Unexpected tx status for rate update */
+-#define TX_STATUS_UNEXP(status) \
+-	((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
+-	 TX_STATUS_UNEXP_AMPDU(status))
+-
+-/* Unexpected tx status for A-MPDU rate update */
+-#define TX_STATUS_UNEXP_AMPDU(status) \
+-	((((status) & TX_STATUS_SUPR_MASK) != 0) && \
+-	 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
+-
+-#define TX_STATUS_BA_BMAP03_MASK	0xF000	/* ba bitmap 0:3 in 1st pkg */
+-#define TX_STATUS_BA_BMAP03_SHIFT	12	/* ba bitmap 0:3 in 1st pkg */
+-#define TX_STATUS_BA_BMAP47_MASK	0x001E	/* ba bitmap 4:7 in 2nd pkg */
+-#define TX_STATUS_BA_BMAP47_SHIFT	3	/* ba bitmap 4:7 in 2nd pkg */
+-
+-/* RXE (Receive Engine) */
+-
+-/* RCM_CTL */
+-#define	RCM_INC_MASK_H		0x0080
+-#define	RCM_INC_MASK_L		0x0040
+-#define	RCM_INC_DATA		0x0020
+-#define	RCM_INDEX_MASK		0x001F
+-#define	RCM_SIZE		15
+-
+-#define	RCM_MAC_OFFSET		0	/* current MAC address */
+-#define	RCM_BSSID_OFFSET	3	/* current BSSID address */
+-#define	RCM_F_BSSID_0_OFFSET	6	/* foreign BSS CFP tracking */
+-#define	RCM_F_BSSID_1_OFFSET	9	/* foreign BSS CFP tracking */
+-#define	RCM_F_BSSID_2_OFFSET	12	/* foreign BSS CFP tracking */
+-
+-#define RCM_WEP_TA0_OFFSET	16
+-#define RCM_WEP_TA1_OFFSET	19
+-#define RCM_WEP_TA2_OFFSET	22
+-#define RCM_WEP_TA3_OFFSET	25
+-
+-/* PSM Block */
+-
+-/* psm_phy_hdr_param bits */
+-#define MAC_PHY_RESET		1
+-#define MAC_PHY_CLOCK_EN	2
+-#define MAC_PHY_FORCE_CLK	4
+-
+-/* WEP Block */
+-
+-/* WEP_WKEY */
+-#define	WKEY_START		(1 << 8)
+-#define	WKEY_SEL_MASK		0x1F
+-
+-/* WEP data formats */
+-
+-/* the number of RCMTA entries */
+-#define RCMTA_SIZE 50
+-
+-#define M_ADDR_BMP_BLK		(0x37e * 2)
+-#define M_ADDR_BMP_BLK_SZ	12
+-
+-#define ADDR_BMP_RA		(1 << 0)	/* Receiver Address (RA) */
+-#define ADDR_BMP_TA		(1 << 1)	/* Transmitter Address (TA) */
+-#define ADDR_BMP_BSSID		(1 << 2)	/* BSSID */
+-#define ADDR_BMP_AP		(1 << 3)	/* Infra-BSS Access Point (AP) */
+-#define ADDR_BMP_STA		(1 << 4)	/* Infra-BSS Station (STA) */
+-#define ADDR_BMP_RESERVED1	(1 << 5)
+-#define ADDR_BMP_RESERVED2	(1 << 6)
+-#define ADDR_BMP_RESERVED3	(1 << 7)
+-#define ADDR_BMP_BSS_IDX_MASK	(3 << 8)	/* BSS control block index */
+-#define ADDR_BMP_BSS_IDX_SHIFT	8
+-
+-#define	WSEC_MAX_RCMTA_KEYS	54
+-
+-/* max keys in M_TKMICKEYS_BLK */
+-#define	WSEC_MAX_TKMIC_ENGINE_KEYS		12	/* 8 + 4 default */
+-
+-/* max RXE match registers */
+-#define WSEC_MAX_RXE_KEYS	4
+-
+-/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
+-/* SKL (Security Key Lookup) */
+-#define	SKL_ALGO_MASK		0x0007
+-#define	SKL_ALGO_SHIFT		0
+-#define	SKL_KEYID_MASK		0x0008
+-#define	SKL_KEYID_SHIFT		3
+-#define	SKL_INDEX_MASK		0x03F0
+-#define	SKL_INDEX_SHIFT		4
+-#define	SKL_GRP_ALGO_MASK	0x1c00
+-#define	SKL_GRP_ALGO_SHIFT	10
+-
+-/* additional bits defined for IBSS group key support */
+-#define	SKL_IBSS_INDEX_MASK	0x01F0
+-#define	SKL_IBSS_INDEX_SHIFT	4
+-#define	SKL_IBSS_KEYID1_MASK	0x0600
+-#define	SKL_IBSS_KEYID1_SHIFT	9
+-#define	SKL_IBSS_KEYID2_MASK	0x1800
+-#define	SKL_IBSS_KEYID2_SHIFT	11
+-#define	SKL_IBSS_KEYALGO_MASK	0xE000
+-#define	SKL_IBSS_KEYALGO_SHIFT	13
+-
+-#define	WSEC_MODE_OFF		0
+-#define	WSEC_MODE_HW		1
+-#define	WSEC_MODE_SW		2
+-
+-#define	WSEC_ALGO_OFF		0
+-#define	WSEC_ALGO_WEP1		1
+-#define	WSEC_ALGO_TKIP		2
+-#define	WSEC_ALGO_AES		3
+-#define	WSEC_ALGO_WEP128	4
+-#define	WSEC_ALGO_AES_LEGACY	5
+-#define	WSEC_ALGO_NALG		6
+-
+-#define	AES_MODE_NONE		0
+-#define	AES_MODE_CCM		1
+-
+-/* WEP_CTL (Rev 0) */
+-#define	WECR0_KEYREG_SHIFT	0
+-#define	WECR0_KEYREG_MASK	0x7
+-#define	WECR0_DECRYPT		(1 << 3)
+-#define	WECR0_IVINLINE		(1 << 4)
+-#define	WECR0_WEPALG_SHIFT	5
+-#define	WECR0_WEPALG_MASK	(0x7 << 5)
+-#define	WECR0_WKEYSEL_SHIFT	8
+-#define	WECR0_WKEYSEL_MASK	(0x7 << 8)
+-#define	WECR0_WKEYSTART		(1 << 11)
+-#define	WECR0_WEPINIT		(1 << 14)
+-#define	WECR0_ICVERR		(1 << 15)
+-
+-/* Frame template map byte offsets */
+-#define	T_ACTS_TPL_BASE		(0)
+-#define	T_NULL_TPL_BASE		(0xc * 2)
+-#define	T_QNULL_TPL_BASE	(0x1c * 2)
+-#define	T_RR_TPL_BASE		(0x2c * 2)
+-#define	T_BCN0_TPL_BASE		(0x34 * 2)
+-#define	T_PRS_TPL_BASE		(0x134 * 2)
+-#define	T_BCN1_TPL_BASE		(0x234 * 2)
+-#define T_TX_FIFO_TXRAM_BASE	(T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
+-
+-#define T_BA_TPL_BASE		T_QNULL_TPL_BASE	/* template area for BA */
+-
+-#define T_RAM_ACCESS_SZ		4	/* template ram is 4 byte access only */
+-
+-/* Shared Mem byte offsets */
+-
+-/* Location where the ucode expects the corerev */
+-#define	M_MACHW_VER		(0x00b * 2)
+-
+-/* Location where the ucode expects the MAC capabilities */
+-#define	M_MACHW_CAP_L		(0x060 * 2)
+-#define	M_MACHW_CAP_H	(0x061 * 2)
+-
+-/* WME shared memory */
+-#define M_EDCF_STATUS_OFF	(0x007 * 2)
+-#define M_TXF_CUR_INDEX		(0x018 * 2)
+-#define M_EDCF_QINFO		(0x120 * 2)
+-
+-/* PS-mode related parameters */
+-#define	M_DOT11_SLOT		(0x008 * 2)
+-#define	M_DOT11_DTIMPERIOD	(0x009 * 2)
+-#define	M_NOSLPZNATDTIM		(0x026 * 2)
+-
+-/* Beacon-related parameters */
+-#define	M_BCN0_FRM_BYTESZ	(0x00c * 2)	/* Bcn 0 template length */
+-#define	M_BCN1_FRM_BYTESZ	(0x00d * 2)	/* Bcn 1 template length */
+-#define	M_BCN_TXTSF_OFFSET	(0x00e * 2)
+-#define	M_TIMBPOS_INBEACON	(0x00f * 2)
+-#define	M_SFRMTXCNTFBRTHSD	(0x022 * 2)
+-#define	M_LFRMTXCNTFBRTHSD	(0x023 * 2)
+-#define	M_BCN_PCTLWD		(0x02a * 2)
+-#define M_BCN_LI		(0x05b * 2)	/* beacon listen interval */
+-
+-/* MAX Rx Frame len */
+-#define M_MAXRXFRM_LEN		(0x010 * 2)
+-
+-/* ACK/CTS related params */
+-#define	M_RSP_PCTLWD		(0x011 * 2)
+-
+-/* Hardware Power Control */
+-#define M_TXPWR_N		(0x012 * 2)
+-#define M_TXPWR_TARGET		(0x013 * 2)
+-#define M_TXPWR_MAX		(0x014 * 2)
+-#define M_TXPWR_CUR		(0x019 * 2)
+-
+-/* Rx-related parameters */
+-#define	M_RX_PAD_DATA_OFFSET	(0x01a * 2)
+-
+-/* WEP Shared mem data */
+-#define	M_SEC_DEFIVLOC		(0x01e * 2)
+-#define	M_SEC_VALNUMSOFTMCHTA	(0x01f * 2)
+-#define	M_PHYVER		(0x028 * 2)
+-#define	M_PHYTYPE		(0x029 * 2)
+-#define	M_SECRXKEYS_PTR		(0x02b * 2)
+-#define	M_TKMICKEYS_PTR		(0x059 * 2)
+-#define	M_SECKINDXALGO_BLK	(0x2ea * 2)
+-#define M_SECKINDXALGO_BLK_SZ	54
+-#define	M_SECPSMRXTAMCH_BLK	(0x2fa * 2)
+-#define	M_TKIP_TSC_TTAK		(0x18c * 2)
+-#define	D11_MAX_KEY_SIZE	16
+-
+-#define	M_MAX_ANTCNT		(0x02e * 2)	/* antenna swap threshold */
+-
+-/* Probe response related parameters */
+-#define	M_SSIDLEN		(0x024 * 2)
+-#define	M_PRB_RESP_FRM_LEN	(0x025 * 2)
+-#define	M_PRS_MAXTIME		(0x03a * 2)
+-#define	M_SSID			(0xb0 * 2)
+-#define	M_CTXPRS_BLK		(0xc0 * 2)
+-#define	C_CTX_PCTLWD_POS	(0x4 * 2)
+-
+-/* Delta between OFDM and CCK power in CCK power boost mode */
+-#define M_OFDM_OFFSET		(0x027 * 2)
+-
+-/* TSSI for last 4 11b/g CCK packets transmitted */
+-#define	M_B_TSSI_0		(0x02c * 2)
+-#define	M_B_TSSI_1		(0x02d * 2)
+-
+-/* Host flags to turn on ucode options */
+-#define	M_HOST_FLAGS1		(0x02f * 2)
+-#define	M_HOST_FLAGS2		(0x030 * 2)
+-#define	M_HOST_FLAGS3		(0x031 * 2)
+-#define	M_HOST_FLAGS4		(0x03c * 2)
+-#define	M_HOST_FLAGS5		(0x06a * 2)
+-#define	M_HOST_FLAGS_SZ		16
+-
+-#define M_RADAR_REG		(0x033 * 2)
+-
+-/* TSSI for last 4 11a OFDM packets transmitted */
+-#define	M_A_TSSI_0		(0x034 * 2)
+-#define	M_A_TSSI_1		(0x035 * 2)
+-
+-/* noise interference measurement */
+-#define M_NOISE_IF_COUNT	(0x034 * 2)
+-#define M_NOISE_IF_TIMEOUT	(0x035 * 2)
+-
+-#define	M_RF_RX_SP_REG1		(0x036 * 2)
+-
+-/* TSSI for last 4 11g OFDM packets transmitted */
+-#define	M_G_TSSI_0		(0x038 * 2)
+-#define	M_G_TSSI_1		(0x039 * 2)
+-
+-/* Background noise measure */
+-#define	M_JSSI_0		(0x44 * 2)
+-#define	M_JSSI_1		(0x45 * 2)
+-#define	M_JSSI_AUX		(0x46 * 2)
+-
+-#define	M_CUR_2050_RADIOCODE	(0x47 * 2)
+-
+-/* TX fifo sizes */
+-#define M_FIFOSIZE0		(0x4c * 2)
+-#define M_FIFOSIZE1		(0x4d * 2)
+-#define M_FIFOSIZE2		(0x4e * 2)
+-#define M_FIFOSIZE3		(0x4f * 2)
+-#define D11_MAX_TX_FRMS		32	/* max frames allowed in tx fifo */
+-
+-/* Current channel number plus upper bits */
+-#define M_CURCHANNEL		(0x50 * 2)
+-#define D11_CURCHANNEL_5G	0x0100;
+-#define D11_CURCHANNEL_40	0x0200;
+-#define D11_CURCHANNEL_MAX	0x00FF;
+-
+-/* last posted frameid on the bcmc fifo */
+-#define M_BCMC_FID		(0x54 * 2)
+-#define INVALIDFID		0xffff
+-
+-/* extended beacon phyctl bytes for 11N */
+-#define	M_BCN_PCTL1WD		(0x058 * 2)
+-
+-/* idle busy ratio to duty_cycle requirement  */
+-#define M_TX_IDLE_BUSY_RATIO_X_16_CCK  (0x52 * 2)
+-#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
+-
+-/* CW RSSI for LCNPHY */
+-#define M_LCN_RSSI_0 		0x1332
+-#define M_LCN_RSSI_1 		0x1338
+-#define M_LCN_RSSI_2 		0x133e
+-#define M_LCN_RSSI_3 		0x1344
+-
+-/* SNR for LCNPHY */
+-#define M_LCN_SNR_A_0 	0x1334
+-#define M_LCN_SNR_B_0 	0x1336
+-
+-#define M_LCN_SNR_A_1 	0x133a
+-#define M_LCN_SNR_B_1 	0x133c
+-
+-#define M_LCN_SNR_A_2 	0x1340
+-#define M_LCN_SNR_B_2 	0x1342
+-
+-#define M_LCN_SNR_A_3 	0x1346
+-#define M_LCN_SNR_B_3 	0x1348
+-
+-#define M_LCN_LAST_RESET 	(81*2)
+-#define M_LCN_LAST_LOC	(63*2)
+-#define M_LCNPHY_RESET_STATUS (4902)
+-#define M_LCNPHY_DSC_TIME	(0x98d*2)
+-#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
+-#define M_LCNPHY_RESET_CNT	(0x98c*2)
+-
+-/* Rate table offsets */
+-#define	M_RT_DIRMAP_A		(0xe0 * 2)
+-#define	M_RT_BBRSMAP_A		(0xf0 * 2)
+-#define	M_RT_DIRMAP_B		(0x100 * 2)
+-#define	M_RT_BBRSMAP_B		(0x110 * 2)
+-
+-/* Rate table entry offsets */
+-#define	M_RT_PRS_PLCP_POS	10
+-#define	M_RT_PRS_DUR_POS	16
+-#define	M_RT_OFDM_PCTL1_POS	18
+-
+-#define M_20IN40_IQ			(0x380 * 2)
+-
+-/* SHM locations where ucode stores the current power index */
+-#define M_CURR_IDX1		(0x384 * 2)
+-#define M_CURR_IDX2		(0x387 * 2)
+-
+-#define M_BSCALE_ANT0	(0x5e * 2)
+-#define M_BSCALE_ANT1	(0x5f * 2)
+-
+-/* Antenna Diversity Testing */
+-#define M_MIMO_ANTSEL_RXDFLT	(0x63 * 2)
+-#define M_ANTSEL_CLKDIV	(0x61 * 2)
+-#define M_MIMO_ANTSEL_TXDFLT	(0x64 * 2)
+-
+-#define M_MIMO_MAXSYM	(0x5d * 2)
+-#define MIMO_MAXSYM_DEF		0x8000	/* 32k */
+-#define MIMO_MAXSYM_MAX		0xffff	/* 64k */
+-
+-#define M_WATCHDOG_8TU		(0x1e * 2)
+-#define WATCHDOG_8TU_DEF	5
+-#define WATCHDOG_8TU_MAX	10
+-
+-/* Manufacturing Test Variables */
+-#define M_PKTENG_CTRL		(0x6c * 2)	/* PER test mode */
+-#define M_PKTENG_IFS		(0x6d * 2)	/* IFS for TX mode */
+-#define M_PKTENG_FRMCNT_LO		(0x6e * 2)	/* Lower word of tx frmcnt/rx lostcnt */
+-#define M_PKTENG_FRMCNT_HI		(0x6f * 2)	/* Upper word of tx frmcnt/rx lostcnt */
+-
+-/* Index variation in vbat ripple */
+-#define M_LCN_PWR_IDX_MAX	(0x67 * 2)	/* highest index read by ucode */
+-#define M_LCN_PWR_IDX_MIN	(0x66 * 2)	/* lowest index read by ucode */
+-
+-/* M_PKTENG_CTRL bit definitions */
+-#define M_PKTENG_MODE_TX		0x0001
+-#define M_PKTENG_MODE_TX_RIFS	        0x0004
+-#define M_PKTENG_MODE_TX_CTS            0x0008
+-#define M_PKTENG_MODE_RX		0x0002
+-#define M_PKTENG_MODE_RX_WITH_ACK	0x0402
+-#define M_PKTENG_MODE_MASK		0x0003
+-#define M_PKTENG_FRMCNT_VLD		0x0100	/* TX frames indicated in the frmcnt reg */
+-
+-/* Sample Collect parameters (bitmap and type) */
+-#define M_SMPL_COL_BMP		(0x37d * 2)	/* Trigger bitmap for sample collect */
+-#define M_SMPL_COL_CTL		(0x3b2 * 2)	/* Sample collect type */
+-
+-#define ANTSEL_CLKDIV_4MHZ	6
+-#define MIMO_ANTSEL_BUSY	0x4000	/* bit 14 (busy) */
+-#define MIMO_ANTSEL_SEL		0x8000	/* bit 15 write the value */
+-#define MIMO_ANTSEL_WAIT	50	/* 50us wait */
+-#define MIMO_ANTSEL_OVERRIDE	0x8000	/* flag */
+-
+-typedef struct shm_acparams shm_acparams_t;
+-struct shm_acparams {
+-	u16 txop;
+-	u16 cwmin;
+-	u16 cwmax;
+-	u16 cwcur;
+-	u16 aifs;
+-	u16 bslots;
+-	u16 reggap;
+-	u16 status;
+-	u16 rsvd[8];
+-} __attribute__((packed));
+-#define M_EDCF_QLEN	(16 * 2)
+-
+-#define WME_STATUS_NEWAC	(1 << 8)
+-
+-/* M_HOST_FLAGS */
+-#define MHFMAX		5	/* Number of valid hostflag half-word (u16) */
+-#define MHF1		0	/* Hostflag 1 index */
+-#define MHF2		1	/* Hostflag 2 index */
+-#define MHF3		2	/* Hostflag 3 index */
+-#define MHF4		3	/* Hostflag 4 index */
+-#define MHF5		4	/* Hostflag 5 index */
+-
+-/* Flags in M_HOST_FLAGS */
+-#define	MHF1_ANTDIV		0x0001	/* Enable ucode antenna diversity help */
+-#define	MHF1_EDCF		0x0100	/* Enable EDCF access control */
+-#define MHF1_IQSWAP_WAR		0x0200
+-#define	MHF1_FORCEFASTCLK	0x0400	/* Disable Slow clock request, for corerev < 11 */
+-
+-/* Flags in M_HOST_FLAGS2 */
+-#define MHF2_PCISLOWCLKWAR	0x0008	/* PR16165WAR : Enable ucode PCI slow clock WAR */
+-#define MHF2_TXBCMC_NOW		0x0040	/* Flush BCMC FIFO immediately */
+-#define MHF2_HWPWRCTL		0x0080	/* Enable ucode/hw power control */
+-#define MHF2_NPHY40MHZ_WAR	0x0800
+-
+-/* Flags in M_HOST_FLAGS3 */
+-#define MHF3_ANTSEL_EN		0x0001	/* enabled mimo antenna selection */
+-#define MHF3_ANTSEL_MODE	0x0002	/* antenna selection mode: 0: 2x3, 1: 2x4 */
+-#define MHF3_RESERVED1		0x0004
+-#define MHF3_RESERVED2		0x0008
+-#define MHF3_NPHY_MLADV_WAR	0x0010
+-
+-/* Flags in M_HOST_FLAGS4 */
+-#define MHF4_BPHY_TXCORE0	0x0080	/* force bphy Tx on core 0 (board level WAR) */
+-#define MHF4_EXTPA_ENABLE  	0x4000	/* for 4313A0 FEM boards */
+-
+-/* Flags in M_HOST_FLAGS5 */
+-#define MHF5_4313_GPIOCTRL	0x0001
+-#define MHF5_RESERVED1		0x0002
+-#define MHF5_RESERVED2		0x0004
+-/* Radio power setting for ucode */
+-#define	M_RADIO_PWR		(0x32 * 2)
+-
+-/* phy noise recorded by ucode right after tx */
+-#define	M_PHY_NOISE		(0x037 * 2)
+-#define	PHY_NOISE_MASK		0x00ff
+-
+-/* Receive Frame Data Header for 802.11b DCF-only frames */
+-typedef struct d11rxhdr d11rxhdr_t;
+-struct d11rxhdr {
+-	u16 RxFrameSize;	/* Actual byte length of the frame data received */
+-	u16 PAD;
+-	u16 PhyRxStatus_0;	/* PhyRxStatus 15:0 */
+-	u16 PhyRxStatus_1;	/* PhyRxStatus 31:16 */
+-	u16 PhyRxStatus_2;	/* PhyRxStatus 47:32 */
+-	u16 PhyRxStatus_3;	/* PhyRxStatus 63:48 */
+-	u16 PhyRxStatus_4;	/* PhyRxStatus 79:64 */
+-	u16 PhyRxStatus_5;	/* PhyRxStatus 95:80 */
+-	u16 RxStatus1;	/* MAC Rx Status */
+-	u16 RxStatus2;	/* extended MAC Rx status */
+-	u16 RxTSFTime;	/* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
+-	u16 RxChan;		/* gain code, channel radio code, and phy type */
+-} __attribute__((packed));
+-
+-#define	RXHDR_LEN		24	/* sizeof d11rxhdr_t */
+-#define	FRAMELEN(h)		((h)->RxFrameSize)
+-
+-typedef struct wlc_d11rxhdr wlc_d11rxhdr_t;
+-struct wlc_d11rxhdr {
+-	d11rxhdr_t rxhdr;
+-	u32 tsf_l;		/* TSF_L reading */
+-	s8 rssi;		/* computed instanteneous rssi in BMAC */
+-	s8 rxpwr0;		/* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+-	s8 rxpwr1;		/* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+-	s8 do_rssi_ma;	/* do per-pkt sampling for per-antenna ma in HIGH */
+-	s8 rxpwr[WL_RSSI_ANT_MAX];	/* rssi for supported antennas */
+-} __attribute__((packed));
+-
+-/* PhyRxStatus_0: */
+-#define	PRXS0_FT_MASK		0x0003	/* NPHY only: CCK, OFDM, preN, N */
+-#define	PRXS0_CLIP_MASK		0x000C	/* NPHY only: clip count adjustment steps by AGC */
+-#define	PRXS0_CLIP_SHIFT	2
+-#define	PRXS0_UNSRATE		0x0010	/* PHY received a frame with unsupported rate */
+-#define	PRXS0_RXANT_UPSUBBAND	0x0020	/* GPHY: rx ant, NPHY: upper sideband */
+-#define	PRXS0_LCRS		0x0040	/* CCK frame only: lost crs during cck frame reception */
+-#define	PRXS0_SHORTH		0x0080	/* Short Preamble */
+-#define	PRXS0_PLCPFV		0x0100	/* PLCP violation */
+-#define	PRXS0_PLCPHCF		0x0200	/* PLCP header integrity check failed */
+-#define	PRXS0_GAIN_CTL		0x4000	/* legacy PHY gain control */
+-#define PRXS0_ANTSEL_MASK	0xF000	/* NPHY: Antennas used for received frame, bitmask */
+-#define PRXS0_ANTSEL_SHIFT	0x12
+-
+-/* subfield PRXS0_FT_MASK */
+-#define	PRXS0_CCK		0x0000
+-#define	PRXS0_OFDM		0x0001	/* valid only for G phy, use rxh->RxChan for A phy */
+-#define	PRXS0_PREN		0x0002
+-#define	PRXS0_STDN		0x0003
+-
+-/* subfield PRXS0_ANTSEL_MASK */
+-#define PRXS0_ANTSEL_0		0x0	/* antenna 0 is used */
+-#define PRXS0_ANTSEL_1		0x2	/* antenna 1 is used */
+-#define PRXS0_ANTSEL_2		0x4	/* antenna 2 is used */
+-#define PRXS0_ANTSEL_3		0x8	/* antenna 3 is used */
+-
+-/* PhyRxStatus_1: */
+-#define	PRXS1_JSSI_MASK		0x00FF
+-#define	PRXS1_JSSI_SHIFT	0
+-#define	PRXS1_SQ_MASK		0xFF00
+-#define	PRXS1_SQ_SHIFT		8
+-
+-/* nphy PhyRxStatus_1: */
+-#define PRXS1_nphy_PWR0_MASK	0x00FF
+-#define PRXS1_nphy_PWR1_MASK	0xFF00
+-
+-/* HTPHY Rx Status defines */
+-/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
+-#define PRXS0_BAND	        0x0400	/* 0 = 2.4G, 1 = 5G */
+-#define PRXS0_RSVD	        0x0800	/* reserved; set to 0 */
+-#define PRXS0_UNUSED	        0xF000	/* unused and not defined; set to 0 */
+-
+-/* htphy PhyRxStatus_1: */
+-#define PRXS1_HTPHY_CORE_MASK	0x000F	/* core enables for {3..0}, 0=disabled, 1=enabled */
+-#define PRXS1_HTPHY_ANTCFG_MASK	0x00F0	/* antenna configation */
+-#define PRXS1_HTPHY_MMPLCPLenL_MASK	0xFF00	/* Mixmode PLCP Length low byte mask */
+-
+-/* htphy PhyRxStatus_2: */
+-#define PRXS2_HTPHY_MMPLCPLenH_MASK	0x000F	/* Mixmode PLCP Length high byte maskw */
+-#define PRXS2_HTPHY_MMPLCH_RATE_MASK	0x00F0	/* Mixmode PLCP rate mask */
+-#define PRXS2_HTPHY_RXPWR_ANT0	0xFF00	/* Rx power on core 0 */
+-
+-/* htphy PhyRxStatus_3: */
+-#define PRXS3_HTPHY_RXPWR_ANT1	0x00FF	/* Rx power on core 1 */
+-#define PRXS3_HTPHY_RXPWR_ANT2	0xFF00	/* Rx power on core 2 */
+-
+-/* htphy PhyRxStatus_4: */
+-#define PRXS4_HTPHY_RXPWR_ANT3	0x00FF	/* Rx power on core 3 */
+-#define PRXS4_HTPHY_CFO		0xFF00	/* Coarse frequency offset */
+-
+-/* htphy PhyRxStatus_5: */
+-#define PRXS5_HTPHY_FFO	        0x00FF	/* Fine frequency offset */
+-#define PRXS5_HTPHY_AR	        0xFF00	/* Advance Retard */
+-
+-#define HTPHY_MMPLCPLen(rxs)	((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
+-	(((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
+-/* Get Rx power on core 0 */
+-#define HTPHY_RXPWR_ANT0(rxs)	((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
+-/* Get Rx power on core 1 */
+-#define HTPHY_RXPWR_ANT1(rxs)	(((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
+-/* Get Rx power on core 2 */
+-#define HTPHY_RXPWR_ANT2(rxs)	((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
+-
+-/* ucode RxStatus1: */
+-#define	RXS_BCNSENT		0x8000
+-#define	RXS_SECKINDX_MASK	0x07e0
+-#define	RXS_SECKINDX_SHIFT	5
+-#define	RXS_DECERR		(1 << 4)
+-#define	RXS_DECATMPT		(1 << 3)
+-#define	RXS_PBPRES		(1 << 2)	/* PAD bytes to make IP data 4 bytes aligned */
+-#define	RXS_RESPFRAMETX		(1 << 1)
+-#define	RXS_FCSERR		(1 << 0)
+-
+-/* ucode RxStatus2: */
+-#define RXS_AMSDU_MASK		1
+-#define	RXS_AGGTYPE_MASK	0x6
+-#define	RXS_AGGTYPE_SHIFT	1
+-#define	RXS_PHYRXST_VALID	(1 << 8)
+-#define RXS_RXANT_MASK		0x3
+-#define RXS_RXANT_SHIFT		12
+-
+-/* RxChan */
+-#define RXS_CHAN_40		0x1000
+-#define RXS_CHAN_5G		0x0800
+-#define	RXS_CHAN_ID_MASK	0x07f8
+-#define	RXS_CHAN_ID_SHIFT	3
+-#define	RXS_CHAN_PHYTYPE_MASK	0x0007
+-#define	RXS_CHAN_PHYTYPE_SHIFT	0
+-
+-/* Index of attenuations used during ucode power control. */
+-#define M_PWRIND_BLKS	(0x184 * 2)
+-#define M_PWRIND_MAP0	(M_PWRIND_BLKS + 0x0)
+-#define M_PWRIND_MAP1	(M_PWRIND_BLKS + 0x2)
+-#define M_PWRIND_MAP2	(M_PWRIND_BLKS + 0x4)
+-#define M_PWRIND_MAP3	(M_PWRIND_BLKS + 0x6)
+-/* M_PWRIND_MAP(core) macro */
+-#define M_PWRIND_MAP(core)  (M_PWRIND_BLKS + ((core)<<1))
+-
+-/* PSM SHM variable offsets */
+-#define	M_PSM_SOFT_REGS	0x0
+-#define	M_BOM_REV_MAJOR	(M_PSM_SOFT_REGS + 0x0)
+-#define	M_BOM_REV_MINOR	(M_PSM_SOFT_REGS + 0x2)
+-#define	M_UCODE_DBGST	(M_PSM_SOFT_REGS + 0x40)	/* ucode debug status code */
+-#define	M_UCODE_MACSTAT	(M_PSM_SOFT_REGS + 0xE0)	/* macstat counters */
+-
+-#define M_AGING_THRSH	(0x3e * 2)	/* max time waiting for medium before tx */
+-#define	M_MBURST_SIZE	(0x40 * 2)	/* max frames in a frameburst */
+-#define	M_MBURST_TXOP	(0x41 * 2)	/* max frameburst TXOP in unit of us */
+-#define M_SYNTHPU_DLY	(0x4a * 2)	/* pre-wakeup for synthpu, default: 500 */
+-#define	M_PRETBTT	(0x4b * 2)
+-
+-#define M_ALT_TXPWR_IDX		(M_PSM_SOFT_REGS + (0x3b * 2))	/* offset to the target txpwr */
+-#define M_PHY_TX_FLT_PTR	(M_PSM_SOFT_REGS + (0x3d * 2))
+-#define M_CTS_DURATION		(M_PSM_SOFT_REGS + (0x5c * 2))
+-#define M_LP_RCCAL_OVR		(M_PSM_SOFT_REGS + (0x6b * 2))
+-
+-/* PKTENG Rx Stats Block */
+-#define M_RXSTATS_BLK_PTR	(M_PSM_SOFT_REGS + (0x65 * 2))
+-
+-/* ucode debug status codes */
+-#define	DBGST_INACTIVE		0	/* not valid really */
+-#define	DBGST_INIT		1	/* after zeroing SHM, before suspending at init */
+-#define	DBGST_ACTIVE		2	/* "normal" state */
+-#define	DBGST_SUSPENDED		3	/* suspended */
+-#define	DBGST_ASLEEP		4	/* asleep (PS mode) */
+-
+-/* Scratch Reg defs */
+-typedef enum {
+-	S_RSV0 = 0,
+-	S_RSV1,
+-	S_RSV2,
+-
+-	/* scratch registers for Dot11-contants */
+-	S_DOT11_CWMIN,		/* CW-minimum                                   0x03 */
+-	S_DOT11_CWMAX,		/* CW-maximum                                   0x04 */
+-	S_DOT11_CWCUR,		/* CW-current                                   0x05 */
+-	S_DOT11_SRC_LMT,	/* short retry count limit                      0x06 */
+-	S_DOT11_LRC_LMT,	/* long retry count limit                       0x07 */
+-	S_DOT11_DTIMCOUNT,	/* DTIM-count                                   0x08 */
+-
+-	/* Tx-side scratch registers */
+-	S_SEQ_NUM,		/* hardware sequence number reg                 0x09 */
+-	S_SEQ_NUM_FRAG,		/* seq-num for frags (Set at the start os MSDU  0x0A */
+-	S_FRMRETX_CNT,		/* frame retx count                             0x0B */
+-	S_SSRC,			/* Station short retry count                    0x0C */
+-	S_SLRC,			/* Station long retry count                     0x0D */
+-	S_EXP_RSP,		/* Expected response frame                      0x0E */
+-	S_OLD_BREM,		/* Remaining backoff ctr                        0x0F */
+-	S_OLD_CWWIN,		/* saved-off CW-cur                             0x10 */
+-	S_TXECTL,		/* TXE-Ctl word constructed in scr-pad          0x11 */
+-	S_CTXTST,		/* frm type-subtype as read from Tx-descr       0x12 */
+-
+-	/* Rx-side scratch registers */
+-	S_RXTST,		/* Type and subtype in Rxframe                  0x13 */
+-
+-	/* Global state register */
+-	S_STREG,		/* state storage actual bit maps below          0x14 */
+-
+-	S_TXPWR_SUM,		/* Tx power control: accumulator                0x15 */
+-	S_TXPWR_ITER,		/* Tx power control: iteration                  0x16 */
+-	S_RX_FRMTYPE,		/* Rate and PHY type for frames                 0x17 */
+-	S_THIS_AGG,		/* Size of this AGG (A-MSDU)                    0x18 */
+-
+-	S_KEYINDX,		/*                                              0x19 */
+-	S_RXFRMLEN,		/* Receive MPDU length in bytes                 0x1A */
+-
+-	/* Receive TSF time stored in SCR */
+-	S_RXTSFTMRVAL_WD3,	/* TSF value at the start of rx                 0x1B */
+-	S_RXTSFTMRVAL_WD2,	/* TSF value at the start of rx                 0x1C */
+-	S_RXTSFTMRVAL_WD1,	/* TSF value at the start of rx                 0x1D */
+-	S_RXTSFTMRVAL_WD0,	/* TSF value at the start of rx                 0x1E */
+-	S_RXSSN,		/* Received start seq number for A-MPDU BA      0x1F */
+-	S_RXQOSFLD,		/* Rx-QoS field (if present)                    0x20 */
+-
+-	/* Scratch pad regs used in microcode as temp storage */
+-	S_TMP0,			/* stmp0                                        0x21 */
+-	S_TMP1,			/* stmp1                                        0x22 */
+-	S_TMP2,			/* stmp2                                        0x23 */
+-	S_TMP3,			/* stmp3                                        0x24 */
+-	S_TMP4,			/* stmp4                                        0x25 */
+-	S_TMP5,			/* stmp5                                        0x26 */
+-	S_PRQPENALTY_CTR,	/* Probe response queue penalty counter         0x27 */
+-	S_ANTCNT,		/* unsuccessful attempts on current ant.        0x28 */
+-	S_SYMBOL,		/* flag for possible symbol ctl frames          0x29 */
+-	S_RXTP,			/* rx frame type                                0x2A */
+-	S_STREG2,		/* extra state storage                          0x2B */
+-	S_STREG3,		/* even more extra state storage                0x2C */
+-	S_STREG4,		/* ...                                          0x2D */
+-	S_STREG5,		/* remember to initialize it to zero            0x2E */
+-
+-	S_ADJPWR_IDX,
+-	S_CUR_PTR,		/* Temp pointer for A-MPDU re-Tx SHM table      0x32 */
+-	S_REVID4,		/* 0x33 */
+-	S_INDX,			/* 0x34 */
+-	S_ADDR0,		/* 0x35 */
+-	S_ADDR1,		/* 0x36 */
+-	S_ADDR2,		/* 0x37 */
+-	S_ADDR3,		/* 0x38 */
+-	S_ADDR4,		/* 0x39 */
+-	S_ADDR5,		/* 0x3A */
+-	S_TMP6,			/* 0x3B */
+-	S_KEYINDX_BU,		/* Backup for Key index                         0x3C */
+-	S_MFGTEST_TMP0,		/* Temp register used for RX test calculations  0x3D */
+-	S_RXESN,		/* Received end sequence number for A-MPDU BA   0x3E */
+-	S_STREG6,		/* 0x3F */
+-} ePsmScratchPadRegDefinitions;
+-
+-#define S_BEACON_INDX	S_OLD_BREM
+-#define S_PRS_INDX	S_OLD_CWWIN
+-#define S_PHYTYPE	S_SSRC
+-#define S_PHYVER	S_SLRC
+-
+-/* IHR SLOW_CTRL values */
+-#define SLOW_CTRL_PDE		(1 << 0)
+-#define SLOW_CTRL_FD		(1 << 8)
+-
+-/* ucode mac statistic counters in shared memory */
+-typedef struct macstat {
+-	u16 txallfrm;	/* 0x80 */
+-	u16 txrtsfrm;	/* 0x82 */
+-	u16 txctsfrm;	/* 0x84 */
+-	u16 txackfrm;	/* 0x86 */
+-	u16 txdnlfrm;	/* 0x88 */
+-	u16 txbcnfrm;	/* 0x8a */
+-	u16 txfunfl[8];	/* 0x8c - 0x9b */
+-	u16 txtplunfl;	/* 0x9c */
+-	u16 txphyerr;	/* 0x9e */
+-	u16 pktengrxducast;	/* 0xa0 */
+-	u16 pktengrxdmcast;	/* 0xa2 */
+-	u16 rxfrmtoolong;	/* 0xa4 */
+-	u16 rxfrmtooshrt;	/* 0xa6 */
+-	u16 rxinvmachdr;	/* 0xa8 */
+-	u16 rxbadfcs;	/* 0xaa */
+-	u16 rxbadplcp;	/* 0xac */
+-	u16 rxcrsglitch;	/* 0xae */
+-	u16 rxstrt;		/* 0xb0 */
+-	u16 rxdfrmucastmbss;	/* 0xb2 */
+-	u16 rxmfrmucastmbss;	/* 0xb4 */
+-	u16 rxcfrmucast;	/* 0xb6 */
+-	u16 rxrtsucast;	/* 0xb8 */
+-	u16 rxctsucast;	/* 0xba */
+-	u16 rxackucast;	/* 0xbc */
+-	u16 rxdfrmocast;	/* 0xbe */
+-	u16 rxmfrmocast;	/* 0xc0 */
+-	u16 rxcfrmocast;	/* 0xc2 */
+-	u16 rxrtsocast;	/* 0xc4 */
+-	u16 rxctsocast;	/* 0xc6 */
+-	u16 rxdfrmmcast;	/* 0xc8 */
+-	u16 rxmfrmmcast;	/* 0xca */
+-	u16 rxcfrmmcast;	/* 0xcc */
+-	u16 rxbeaconmbss;	/* 0xce */
+-	u16 rxdfrmucastobss;	/* 0xd0 */
+-	u16 rxbeaconobss;	/* 0xd2 */
+-	u16 rxrsptmout;	/* 0xd4 */
+-	u16 bcntxcancl;	/* 0xd6 */
+-	u16 PAD;
+-	u16 rxf0ovfl;	/* 0xda */
+-	u16 rxf1ovfl;	/* 0xdc */
+-	u16 rxf2ovfl;	/* 0xde */
+-	u16 txsfovfl;	/* 0xe0 */
+-	u16 pmqovfl;		/* 0xe2 */
+-	u16 rxcgprqfrm;	/* 0xe4 */
+-	u16 rxcgprsqovfl;	/* 0xe6 */
+-	u16 txcgprsfail;	/* 0xe8 */
+-	u16 txcgprssuc;	/* 0xea */
+-	u16 prs_timeout;	/* 0xec */
+-	u16 rxnack;
+-	u16 frmscons;
+-	u16 txnack;
+-	u16 txglitch_nack;
+-	u16 txburst;		/* 0xf6 # tx bursts */
+-	u16 bphy_rxcrsglitch;	/* bphy rx crs glitch */
+-	u16 phywatchdog;	/* 0xfa # of phy watchdog events */
+-	u16 PAD;
+-	u16 bphy_badplcp;	/* bphy bad plcp */
+-} macstat_t;
+-
+-/* dot11 core-specific control flags */
+-#define	SICF_PCLKE		0x0004	/* PHY clock enable */
+-#define	SICF_PRST		0x0008	/* PHY reset */
+-#define	SICF_MPCLKE		0x0010	/* MAC PHY clockcontrol enable */
+-#define	SICF_FREF		0x0020	/* PLL FreqRefSelect */
+-/* NOTE: the following bw bits only apply when the core is attached
+- * to a NPHY
+- */
+-#define	SICF_BWMASK		0x00c0	/* phy clock mask (b6 & b7) */
+-#define	SICF_BW40		0x0080	/* 40MHz BW (160MHz phyclk) */
+-#define	SICF_BW20		0x0040	/* 20MHz BW (80MHz phyclk) */
+-#define	SICF_BW10		0x0000	/* 10MHz BW (40MHz phyclk) */
+-#define	SICF_GMODE		0x2000	/* gmode enable */
+-
+-/* dot11 core-specific status flags */
+-#define	SISF_2G_PHY		0x0001	/* 2.4G capable phy */
+-#define	SISF_5G_PHY		0x0002	/* 5G capable phy */
+-#define	SISF_FCLKA		0x0004	/* FastClkAvailable */
+-#define	SISF_DB_PHY		0x0008	/* Dualband phy */
+-
+-/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */
+-
+-#define	BPHY_REG_OFT_BASE	0x0
+-/* offsets for indirect access to bphy registers */
+-#define	BPHY_BB_CONFIG		0x01
+-#define	BPHY_ADCBIAS		0x02
+-#define	BPHY_ANACORE		0x03
+-#define	BPHY_PHYCRSTH		0x06
+-#define	BPHY_TEST		0x0a
+-#define	BPHY_PA_TX_TO		0x10
+-#define	BPHY_SYNTH_DC_TO	0x11
+-#define	BPHY_PA_TX_TIME_UP	0x12
+-#define	BPHY_RX_FLTR_TIME_UP	0x13
+-#define	BPHY_TX_POWER_OVERRIDE	0x14
+-#define	BPHY_RF_OVERRIDE	0x15
+-#define	BPHY_RF_TR_LOOKUP1	0x16
+-#define	BPHY_RF_TR_LOOKUP2	0x17
+-#define	BPHY_COEFFS		0x18
+-#define	BPHY_PLL_OUT		0x19
+-#define	BPHY_REFRESH_MAIN	0x1a
+-#define	BPHY_REFRESH_TO0	0x1b
+-#define	BPHY_REFRESH_TO1	0x1c
+-#define	BPHY_RSSI_TRESH		0x20
+-#define	BPHY_IQ_TRESH_HH	0x21
+-#define	BPHY_IQ_TRESH_H		0x22
+-#define	BPHY_IQ_TRESH_L		0x23
+-#define	BPHY_IQ_TRESH_LL	0x24
+-#define	BPHY_GAIN		0x25
+-#define	BPHY_LNA_GAIN_RANGE	0x26
+-#define	BPHY_JSSI		0x27
+-#define	BPHY_TSSI_CTL		0x28
+-#define	BPHY_TSSI		0x29
+-#define	BPHY_TR_LOSS_CTL	0x2a
+-#define	BPHY_LO_LEAKAGE		0x2b
+-#define	BPHY_LO_RSSI_ACC	0x2c
+-#define	BPHY_LO_IQMAG_ACC	0x2d
+-#define	BPHY_TX_DC_OFF1		0x2e
+-#define	BPHY_TX_DC_OFF2		0x2f
+-#define	BPHY_PEAK_CNT_THRESH	0x30
+-#define	BPHY_FREQ_OFFSET	0x31
+-#define	BPHY_DIVERSITY_CTL	0x32
+-#define	BPHY_PEAK_ENERGY_LO	0x33
+-#define	BPHY_PEAK_ENERGY_HI	0x34
+-#define	BPHY_SYNC_CTL		0x35
+-#define	BPHY_TX_PWR_CTRL	0x36
+-#define BPHY_TX_EST_PWR 	0x37
+-#define	BPHY_STEP		0x38
+-#define	BPHY_WARMUP		0x39
+-#define	BPHY_LMS_CFF_READ	0x3a
+-#define	BPHY_LMS_COEFF_I	0x3b
+-#define	BPHY_LMS_COEFF_Q	0x3c
+-#define	BPHY_SIG_POW		0x3d
+-#define	BPHY_RFDC_CANCEL_CTL	0x3e
+-#define	BPHY_HDR_TYPE		0x40
+-#define	BPHY_SFD_TO		0x41
+-#define	BPHY_SFD_CTL		0x42
+-#define	BPHY_DEBUG		0x43
+-#define	BPHY_RX_DELAY_COMP	0x44
+-#define	BPHY_CRS_DROP_TO	0x45
+-#define	BPHY_SHORT_SFD_NZEROS	0x46
+-#define	BPHY_DSSS_COEFF1	0x48
+-#define	BPHY_DSSS_COEFF2	0x49
+-#define	BPHY_CCK_COEFF1		0x4a
+-#define	BPHY_CCK_COEFF2		0x4b
+-#define	BPHY_TR_CORR		0x4c
+-#define	BPHY_ANGLE_SCALE	0x4d
+-#define	BPHY_TX_PWR_BASE_IDX	0x4e
+-#define	BPHY_OPTIONAL_MODES2	0x4f
+-#define	BPHY_CCK_LMS_STEP	0x50
+-#define	BPHY_BYPASS		0x51
+-#define	BPHY_CCK_DELAY_LONG	0x52
+-#define	BPHY_CCK_DELAY_SHORT	0x53
+-#define	BPHY_PPROC_CHAN_DELAY	0x54
+-#define	BPHY_DDFS_ENABLE	0x58
+-#define	BPHY_PHASE_SCALE	0x59
+-#define	BPHY_FREQ_CONTROL	0x5a
+-#define	BPHY_LNA_GAIN_RANGE_10	0x5b
+-#define	BPHY_LNA_GAIN_RANGE_32	0x5c
+-#define	BPHY_OPTIONAL_MODES	0x5d
+-#define	BPHY_RX_STATUS2		0x5e
+-#define	BPHY_RX_STATUS3		0x5f
+-#define	BPHY_DAC_CONTROL	0x60
+-#define	BPHY_ANA11G_FILT_CTRL	0x62
+-#define	BPHY_REFRESH_CTRL	0x64
+-#define	BPHY_RF_OVERRIDE2	0x65
+-#define	BPHY_SPUR_CANCEL_CTRL	0x66
+-#define	BPHY_FINE_DIGIGAIN_CTRL	0x67
+-#define	BPHY_RSSI_LUT		0x88
+-#define	BPHY_RSSI_LUT_END	0xa7
+-#define	BPHY_TSSI_LUT		0xa8
+-#define	BPHY_TSSI_LUT_END	0xc7
+-#define	BPHY_TSSI2PWR_LUT	0x380
+-#define	BPHY_TSSI2PWR_LUT_END	0x39f
+-#define	BPHY_LOCOMP_LUT		0x3a0
+-#define	BPHY_LOCOMP_LUT_END	0x3bf
+-#define	BPHY_TXGAIN_LUT		0x3c0
+-#define	BPHY_TXGAIN_LUT_END	0x3ff
+-
+-/* Bits in BB_CONFIG: */
+-#define	PHY_BBC_ANT_MASK	0x0180
+-#define	PHY_BBC_ANT_SHIFT	7
+-#define	BB_DARWIN		0x1000
+-#define BBCFG_RESETCCA		0x4000
+-#define BBCFG_RESETRX		0x8000
+-
+-/* Bits in phytest(0x0a): */
+-#define	TST_DDFS		0x2000
+-#define	TST_TXFILT1		0x0800
+-#define	TST_UNSCRAM		0x0400
+-#define	TST_CARR_SUPP		0x0200
+-#define	TST_DC_COMP_LOOP	0x0100
+-#define	TST_LOOPBACK		0x0080
+-#define	TST_TXFILT0		0x0040
+-#define	TST_TXTEST_ENABLE	0x0020
+-#define	TST_TXTEST_RATE		0x0018
+-#define	TST_TXTEST_PHASE	0x0007
+-
+-/* phytest txTestRate values */
+-#define	TST_TXTEST_RATE_1MBPS	0
+-#define	TST_TXTEST_RATE_2MBPS	1
+-#define	TST_TXTEST_RATE_5_5MBPS	2
+-#define	TST_TXTEST_RATE_11MBPS	3
+-#define	TST_TXTEST_RATE_SHIFT	3
+-
+-#define SHM_BYT_CNT	0x2	/* IHR location */
+-#define MAX_BYT_CNT	0x600	/* Maximum frame len */
+-
+-#endif				/* _D11_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/hnddma.c b/drivers/staging/brcm80211/brcmsmac/hnddma.c
+deleted file mode 100644
+index f607315..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/hnddma.c
++++ /dev/null
+@@ -1,1756 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/netdevice.h>
+-#include <linux/pci.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <hndsoc.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#if defined(__mips__)
+-#include <asm/addrspace.h>
+-#endif
+-
+-#ifdef BRCM_FULLMAC
+-#error "hnddma.c shouldn't be needed for FULLMAC"
+-#endif
+-
+-/* debug/trace */
+-#ifdef BCMDBG
+-#define	DMA_ERROR(args) \
+-	do { \
+-		if (!(*di->msg_level & 1)) \
+-			; \
+-		else \
+-			printk args; \
+-	} while (0)
+-#define	DMA_TRACE(args) \
+-	do { \
+-		if (!(*di->msg_level & 2)) \
+-			; \
+-		else \
+-			printk args; \
+-	} while (0)
+-#else
+-#define	DMA_ERROR(args)
+-#define	DMA_TRACE(args)
+-#endif				/* BCMDBG */
+-
+-#define	DMA_NONE(args)
+-
+-#define d64txregs	dregs.d64_u.txregs_64
+-#define d64rxregs	dregs.d64_u.rxregs_64
+-#define txd64		dregs.d64_u.txd_64
+-#define rxd64		dregs.d64_u.rxd_64
+-
+-/* default dma message level (if input msg_level pointer is null in dma_attach()) */
+-static uint dma_msg_level;
+-
+-#define	MAXNAMEL	8	/* 8 char names */
+-
+-#define	DI_INFO(dmah)	((dma_info_t *)dmah)
+-
+-#define R_SM(r)		(*(r))
+-#define W_SM(r, v)	(*(r) = (v))
+-
+-/* dma engine software state */
+-typedef struct dma_info {
+-	struct hnddma_pub hnddma; /* exported structure */
+-	uint *msg_level;	/* message level pointer */
+-	char name[MAXNAMEL];	/* callers name for diag msgs */
+-
+-	void *pbus;		/* bus handle */
+-
+-	bool dma64;		/* this dma engine is operating in 64-bit mode */
+-	bool addrext;		/* this dma engine supports DmaExtendedAddrChanges */
+-
+-	union {
+-		struct {
+-			dma64regs_t *txregs_64;	/* 64-bit dma tx engine registers */
+-			dma64regs_t *rxregs_64;	/* 64-bit dma rx engine registers */
+-			dma64dd_t *txd_64;	/* pointer to dma64 tx descriptor ring */
+-			dma64dd_t *rxd_64;	/* pointer to dma64 rx descriptor ring */
+-		} d64_u;
+-	} dregs;
+-
+-	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
+-
+-	u16 ntxd;		/* # tx descriptors tunable */
+-	u16 txin;		/* index of next descriptor to reclaim */
+-	u16 txout;		/* index of next descriptor to post */
+-	void **txp;		/* pointer to parallel array of pointers to packets */
+-	hnddma_seg_map_t *txp_dmah;	/* DMA MAP meta-data handle */
+-	dmaaddr_t txdpa;	/* Aligned physical address of descriptor ring */
+-	dmaaddr_t txdpaorig;	/* Original physical address of descriptor ring */
+-	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
+-	u32 txdalloc;	/* #bytes allocated for the ring */
+-	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
+-				 * is not just an index, it needs all 13 bits to be
+-				 * an offset from the addr register.
+-				 */
+-
+-	u16 nrxd;		/* # rx descriptors tunable */
+-	u16 rxin;		/* index of next descriptor to reclaim */
+-	u16 rxout;		/* index of next descriptor to post */
+-	void **rxp;		/* pointer to parallel array of pointers to packets */
+-	hnddma_seg_map_t *rxp_dmah;	/* DMA MAP meta-data handle */
+-	dmaaddr_t rxdpa;	/* Aligned physical address of descriptor ring */
+-	dmaaddr_t rxdpaorig;	/* Original physical address of descriptor ring */
+-	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
+-	u32 rxdalloc;	/* #bytes allocated for the ring */
+-	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
+-
+-	/* tunables */
+-	unsigned int rxbufsize;	/* rx buffer size in bytes,
+-				 * not including the extra headroom
+-				 */
+-	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper stack
+-				 *  e.g. some rx pkt buffers will be bridged to tx side
+-				 *  without byte copying. The extra headroom needs to be
+-				 *  large enough to fit txheader needs.
+-				 *  Some dongle driver may not need it.
+-				 */
+-	uint nrxpost;		/* # rx buffers to keep posted */
+-	unsigned int rxoffset;	/* rxcontrol offset */
+-	uint ddoffsetlow;	/* add to get dma address of descriptor ring, low 32 bits */
+-	uint ddoffsethigh;	/*   high 32 bits */
+-	uint dataoffsetlow;	/* add to get dma address of data buffer, low 32 bits */
+-	uint dataoffsethigh;	/*   high 32 bits */
+-	bool aligndesc_4k;	/* descriptor base need to be aligned or not */
+-} dma_info_t;
+-
+-/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
+-#ifdef BCMDMASGLISTOSL
+-#define DMASGLIST_ENAB true
+-#else
+-#define DMASGLIST_ENAB false
+-#endif				/* BCMDMASGLISTOSL */
+-
+-/* descriptor bumping macros */
+-#define	XXD(x, n)	((x) & ((n) - 1))	/* faster than %, but n must be power of 2 */
+-#define	TXD(x)		XXD((x), di->ntxd)
+-#define	RXD(x)		XXD((x), di->nrxd)
+-#define	NEXTTXD(i)	TXD((i) + 1)
+-#define	PREVTXD(i)	TXD((i) - 1)
+-#define	NEXTRXD(i)	RXD((i) + 1)
+-#define	PREVRXD(i)	RXD((i) - 1)
+-
+-#define	NTXDACTIVE(h, t)	TXD((t) - (h))
+-#define	NRXDACTIVE(h, t)	RXD((t) - (h))
+-
+-/* macros to convert between byte offsets and indexes */
+-#define	B2I(bytes, type)	((bytes) / sizeof(type))
+-#define	I2B(index, type)	((index) * sizeof(type))
+-
+-#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
+-#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
+-
+-#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
+-#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
+-
+-/* Common prototypes */
+-static bool _dma_isaddrext(dma_info_t *di);
+-static bool _dma_descriptor_align(dma_info_t *di);
+-static bool _dma_alloc(dma_info_t *di, uint direction);
+-static void _dma_detach(dma_info_t *di);
+-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
+-static void _dma_rxinit(dma_info_t *di);
+-static void *_dma_rx(dma_info_t *di);
+-static bool _dma_rxfill(dma_info_t *di);
+-static void _dma_rxreclaim(dma_info_t *di);
+-static void _dma_rxenable(dma_info_t *di);
+-static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
+-static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
+-			      u16 *rxbufsize);
+-
+-static void _dma_txblock(dma_info_t *di);
+-static void _dma_txunblock(dma_info_t *di);
+-static uint _dma_txactive(dma_info_t *di);
+-static uint _dma_rxactive(dma_info_t *di);
+-static uint _dma_txpending(dma_info_t *di);
+-static uint _dma_txcommitted(dma_info_t *di);
+-
+-static void *_dma_peeknexttxp(dma_info_t *di);
+-static void *_dma_peeknextrxp(dma_info_t *di);
+-static unsigned long _dma_getvar(dma_info_t *di, const char *name);
+-static void _dma_counterreset(dma_info_t *di);
+-static void _dma_fifoloopbackenable(dma_info_t *di);
+-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
+-static u8 dma_align_sizetobits(uint size);
+-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+-			   u16 *alignbits, uint *alloced,
+-			   dmaaddr_t *descpa);
+-
+-/* Prototypes for 64-bit routines */
+-static bool dma64_alloc(dma_info_t *di, uint direction);
+-static bool dma64_txreset(dma_info_t *di);
+-static bool dma64_rxreset(dma_info_t *di);
+-static bool dma64_txsuspendedidle(dma_info_t *di);
+-static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit);
+-static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
+-static void *dma64_getpos(dma_info_t *di, bool direction);
+-static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
+-static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
+-static void dma64_txrotate(dma_info_t *di);
+-
+-static bool dma64_rxidle(dma_info_t *di);
+-static void dma64_txinit(dma_info_t *di);
+-static bool dma64_txenabled(dma_info_t *di);
+-static void dma64_txsuspend(dma_info_t *di);
+-static void dma64_txresume(dma_info_t *di);
+-static bool dma64_txsuspended(dma_info_t *di);
+-static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
+-static bool dma64_txstopped(dma_info_t *di);
+-static bool dma64_rxstopped(dma_info_t *di);
+-static bool dma64_rxenabled(dma_info_t *di);
+-static bool _dma64_addrext(dma64regs_t *dma64regs);
+-
+-static inline u32 parity32(u32 data);
+-
+-const di_fcn_t dma64proc = {
+-	(di_detach_t) _dma_detach,
+-	(di_txinit_t) dma64_txinit,
+-	(di_txreset_t) dma64_txreset,
+-	(di_txenabled_t) dma64_txenabled,
+-	(di_txsuspend_t) dma64_txsuspend,
+-	(di_txresume_t) dma64_txresume,
+-	(di_txsuspended_t) dma64_txsuspended,
+-	(di_txsuspendedidle_t) dma64_txsuspendedidle,
+-	(di_txfast_t) dma64_txfast,
+-	(di_txunframed_t) dma64_txunframed,
+-	(di_getpos_t) dma64_getpos,
+-	(di_txstopped_t) dma64_txstopped,
+-	(di_txreclaim_t) dma64_txreclaim,
+-	(di_getnexttxp_t) dma64_getnexttxp,
+-	(di_peeknexttxp_t) _dma_peeknexttxp,
+-	(di_txblock_t) _dma_txblock,
+-	(di_txunblock_t) _dma_txunblock,
+-	(di_txactive_t) _dma_txactive,
+-	(di_txrotate_t) dma64_txrotate,
+-
+-	(di_rxinit_t) _dma_rxinit,
+-	(di_rxreset_t) dma64_rxreset,
+-	(di_rxidle_t) dma64_rxidle,
+-	(di_rxstopped_t) dma64_rxstopped,
+-	(di_rxenable_t) _dma_rxenable,
+-	(di_rxenabled_t) dma64_rxenabled,
+-	(di_rx_t) _dma_rx,
+-	(di_rxfill_t) _dma_rxfill,
+-	(di_rxreclaim_t) _dma_rxreclaim,
+-	(di_getnextrxp_t) _dma_getnextrxp,
+-	(di_peeknextrxp_t) _dma_peeknextrxp,
+-	(di_rxparam_get_t) _dma_rx_param_get,
+-
+-	(di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+-	(di_getvar_t) _dma_getvar,
+-	(di_counterreset_t) _dma_counterreset,
+-	(di_ctrlflags_t) _dma_ctrlflags,
+-	NULL,
+-	NULL,
+-	NULL,
+-	(di_rxactive_t) _dma_rxactive,
+-	(di_txpending_t) _dma_txpending,
+-	(di_txcommitted_t) _dma_txcommitted,
+-	39
+-};
+-
+-struct hnddma_pub *dma_attach(char *name, si_t *sih,
+-		     void *dmaregstx, void *dmaregsrx, uint ntxd,
+-		     uint nrxd, uint rxbufsize, int rxextheadroom,
+-		     uint nrxpost, uint rxoffset, uint *msg_level)
+-{
+-	dma_info_t *di;
+-	uint size;
+-
+-	/* allocate private info structure */
+-	di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
+-	if (di == NULL) {
+-#ifdef BCMDBG
+-		printk(KERN_ERR "dma_attach: out of memory\n");
+-#endif
+-		return NULL;
+-	}
+-
+-	di->msg_level = msg_level ? msg_level : &dma_msg_level;
+-
+-
+-	di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
+-
+-	/* init dma reg pointer */
+-	di->d64txregs = (dma64regs_t *) dmaregstx;
+-	di->d64rxregs = (dma64regs_t *) dmaregsrx;
+-	di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
+-
+-	/* Default flags (which can be changed by the driver calling dma_ctrlflags
+-	 * before enable): For backwards compatibility both Rx Overflow Continue
+-	 * and Parity are DISABLED.
+-	 * supports it.
+-	 */
+-	di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
+-				    0);
+-
+-	DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
+-		   "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
+-		   "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
+-		   di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize,
+-		   rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+-
+-	/* make a private copy of our callers name */
+-	strncpy(di->name, name, MAXNAMEL);
+-	di->name[MAXNAMEL - 1] = '\0';
+-
+-	di->pbus = ((struct si_info *)sih)->pbus;
+-
+-	/* save tunables */
+-	di->ntxd = (u16) ntxd;
+-	di->nrxd = (u16) nrxd;
+-
+-	/* the actual dma size doesn't include the extra headroom */
+-	di->rxextrahdrroom =
+-	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
+-	if (rxbufsize > BCMEXTRAHDROOM)
+-		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
+-	else
+-		di->rxbufsize = (u16) rxbufsize;
+-
+-	di->nrxpost = (u16) nrxpost;
+-	di->rxoffset = (u8) rxoffset;
+-
+-	/*
+-	 * figure out the DMA physical address offset for dd and data
+-	 *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+-	 *     Other bus: use zero
+-	 *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+-	 */
+-	di->ddoffsetlow = 0;
+-	di->dataoffsetlow = 0;
+-	/* for pci bus, add offset */
+-	if (sih->bustype == PCI_BUS) {
+-		/* pcie with DMA64 */
+-		di->ddoffsetlow = 0;
+-		di->ddoffsethigh = SI_PCIE_DMA_H32;
+-		di->dataoffsetlow = di->ddoffsetlow;
+-		di->dataoffsethigh = di->ddoffsethigh;
+-	}
+-#if defined(__mips__) && defined(IL_BIGENDIAN)
+-	di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
+-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+-	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
+-	if ((ai_coreid(sih) == SDIOD_CORE_ID)
+-	    && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
+-		di->addrext = 0;
+-	else if ((ai_coreid(sih) == I2S_CORE_ID) &&
+-		 ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
+-		di->addrext = 0;
+-	else
+-		di->addrext = _dma_isaddrext(di);
+-
+-	/* does the descriptors need to be aligned and if yes, on 4K/8K or not */
+-	di->aligndesc_4k = _dma_descriptor_align(di);
+-	if (di->aligndesc_4k) {
+-		di->dmadesc_align = D64RINGALIGN_BITS;
+-		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
+-			/* for smaller dd table, HW relax alignment reqmnt */
+-			di->dmadesc_align = D64RINGALIGN_BITS - 1;
+-		}
+-	} else
+-		di->dmadesc_align = 4;	/* 16 byte alignment */
+-
+-	DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
+-		  di->aligndesc_4k, di->dmadesc_align));
+-
+-	/* allocate tx packet pointer vector */
+-	if (ntxd) {
+-		size = ntxd * sizeof(void *);
+-		di->txp = kzalloc(size, GFP_ATOMIC);
+-		if (di->txp == NULL) {
+-			DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
+-			goto fail;
+-		}
+-	}
+-
+-	/* allocate rx packet pointer vector */
+-	if (nrxd) {
+-		size = nrxd * sizeof(void *);
+-		di->rxp = kzalloc(size, GFP_ATOMIC);
+-		if (di->rxp == NULL) {
+-			DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
+-			goto fail;
+-		}
+-	}
+-
+-	/* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+-	if (ntxd) {
+-		if (!_dma_alloc(di, DMA_TX))
+-			goto fail;
+-	}
+-
+-	/* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+-	if (nrxd) {
+-		if (!_dma_alloc(di, DMA_RX))
+-			goto fail;
+-	}
+-
+-	if ((di->ddoffsetlow != 0) && !di->addrext) {
+-		if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
+-			DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
+-			goto fail;
+-		}
+-		if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
+-			DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
+-			goto fail;
+-		}
+-	}
+-
+-	DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+-
+-	/* allocate DMA mapping vectors */
+-	if (DMASGLIST_ENAB) {
+-		if (ntxd) {
+-			size = ntxd * sizeof(hnddma_seg_map_t);
+-			di->txp_dmah = kzalloc(size, GFP_ATOMIC);
+-			if (di->txp_dmah == NULL)
+-				goto fail;
+-		}
+-
+-		if (nrxd) {
+-			size = nrxd * sizeof(hnddma_seg_map_t);
+-			di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
+-			if (di->rxp_dmah == NULL)
+-				goto fail;
+-		}
+-	}
+-
+-	return (struct hnddma_pub *) di;
+-
+- fail:
+-	_dma_detach(di);
+-	return NULL;
+-}
+-
+-/* Check for odd number of 1's */
+-static inline u32 parity32(u32 data)
+-{
+-	data ^= data >> 16;
+-	data ^= data >> 8;
+-	data ^= data >> 4;
+-	data ^= data >> 2;
+-	data ^= data >> 1;
+-
+-	return data & 1;
+-}
+-
+-#define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
+-
+-static inline void
+-dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
+-	     u32 *flags, u32 bufcount)
+-{
+-	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+-
+-	/* PCI bus with big(>1G) physical address, use address extension */
+-#if defined(__mips__) && defined(IL_BIGENDIAN)
+-	if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
+-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-#else
+-	if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+-
+-		W_SM(&ddring[outidx].addrlow,
+-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+-		W_SM(&ddring[outidx].addrhigh,
+-		     BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
+-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+-	} else {
+-		/* address extension for 32-bit PCI */
+-		u32 ae;
+-
+-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+-
+-		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+-		W_SM(&ddring[outidx].addrlow,
+-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+-		W_SM(&ddring[outidx].addrhigh,
+-		     BUS_SWAP32(0 + di->dataoffsethigh));
+-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+-	}
+-	if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
+-		if (DMA64_DD_PARITY(&ddring[outidx])) {
+-			W_SM(&ddring[outidx].ctrl2,
+-			     BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
+-		}
+-	}
+-}
+-
+-static bool _dma_alloc(dma_info_t *di, uint direction)
+-{
+-	return dma64_alloc(di, direction);
+-}
+-
+-void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
+-			       uint *alloced, unsigned long *pap)
+-{
+-	if (align_bits) {
+-		u16 align = (1 << align_bits);
+-		if (!IS_ALIGNED(PAGE_SIZE, align))
+-			size += align;
+-		*alloced = size;
+-	}
+-	return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
+-}
+-
+-/* !! may be called with core in reset */
+-static void _dma_detach(dma_info_t *di)
+-{
+-
+-	DMA_TRACE(("%s: dma_detach\n", di->name));
+-
+-	/* free dma descriptor rings */
+-	if (di->txd64)
+-		pci_free_consistent(di->pbus, di->txdalloc,
+-				    ((s8 *)di->txd64 - di->txdalign),
+-				    (di->txdpaorig));
+-	if (di->rxd64)
+-		pci_free_consistent(di->pbus, di->rxdalloc,
+-				    ((s8 *)di->rxd64 - di->rxdalign),
+-				    (di->rxdpaorig));
+-
+-	/* free packet pointer vectors */
+-	kfree(di->txp);
+-	kfree(di->rxp);
+-
+-	/* free tx packet DMA handles */
+-	kfree(di->txp_dmah);
+-
+-	/* free rx packet DMA handles */
+-	kfree(di->rxp_dmah);
+-
+-	/* free our private info structure */
+-	kfree(di);
+-
+-}
+-
+-static bool _dma_descriptor_align(dma_info_t *di)
+-{
+-	u32 addrl;
+-
+-	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
+-	if (di->d64txregs != NULL) {
+-		W_REG(&di->d64txregs->addrlow, 0xff0);
+-		addrl = R_REG(&di->d64txregs->addrlow);
+-		if (addrl != 0)
+-			return false;
+-	} else if (di->d64rxregs != NULL) {
+-		W_REG(&di->d64rxregs->addrlow, 0xff0);
+-		addrl = R_REG(&di->d64rxregs->addrlow);
+-		if (addrl != 0)
+-			return false;
+-	}
+-	return true;
+-}
+-
+-/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
+-static bool _dma_isaddrext(dma_info_t *di)
+-{
+-	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
+-
+-	/* not all tx or rx channel are available */
+-	if (di->d64txregs != NULL) {
+-		if (!_dma64_addrext(di->d64txregs)) {
+-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
+-				   "AE set\n", di->name));
+-		}
+-		return true;
+-	} else if (di->d64rxregs != NULL) {
+-		if (!_dma64_addrext(di->d64rxregs)) {
+-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
+-				   "AE set\n", di->name));
+-		}
+-		return true;
+-	}
+-	return false;
+-}
+-
+-/* initialize descriptor table base address */
+-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
+-{
+-	if (!di->aligndesc_4k) {
+-		if (direction == DMA_TX)
+-			di->xmtptrbase = PHYSADDRLO(pa);
+-		else
+-			di->rcvptrbase = PHYSADDRLO(pa);
+-	}
+-
+-	if ((di->ddoffsetlow == 0)
+-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-		if (direction == DMA_TX) {
+-			W_REG(&di->d64txregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64txregs->addrhigh,
+-			      (PHYSADDRHI(pa) + di->ddoffsethigh));
+-		} else {
+-			W_REG(&di->d64rxregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64rxregs->addrhigh,
+-				(PHYSADDRHI(pa) + di->ddoffsethigh));
+-		}
+-	} else {
+-		/* DMA64 32bits address extension */
+-		u32 ae;
+-
+-		/* shift the high bit(s) from pa to ae */
+-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
+-		    PCI32ADDR_HIGH_SHIFT;
+-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+-
+-		if (direction == DMA_TX) {
+-			W_REG(&di->d64txregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64txregs->addrhigh,
+-			      di->ddoffsethigh);
+-			SET_REG(&di->d64txregs->control,
+-				D64_XC_AE, (ae << D64_XC_AE_SHIFT));
+-		} else {
+-			W_REG(&di->d64rxregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64rxregs->addrhigh,
+-			      di->ddoffsethigh);
+-			SET_REG(&di->d64rxregs->control,
+-				D64_RC_AE, (ae << D64_RC_AE_SHIFT));
+-		}
+-	}
+-}
+-
+-static void _dma_fifoloopbackenable(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
+-
+-	OR_REG(&di->d64txregs->control, D64_XC_LE);
+-}
+-
+-static void _dma_rxinit(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_rxinit\n", di->name));
+-
+-	if (di->nrxd == 0)
+-		return;
+-
+-	di->rxin = di->rxout = 0;
+-
+-	/* clear rx descriptor ring */
+-	memset((void *)di->rxd64, '\0',
+-		(di->nrxd * sizeof(dma64dd_t)));
+-
+-	/* DMA engine with out alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (!di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+-
+-	_dma_rxenable(di);
+-
+-	if (di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+-}
+-
+-static void _dma_rxenable(dma_info_t *di)
+-{
+-	uint dmactrlflags = di->hnddma.dmactrlflags;
+-	u32 control;
+-
+-	DMA_TRACE(("%s: dma_rxenable\n", di->name));
+-
+-	control =
+-	    (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
+-	    D64_RC_RE;
+-
+-	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
+-		control |= D64_RC_PD;
+-
+-	if (dmactrlflags & DMA_CTRL_ROC)
+-		control |= D64_RC_OC;
+-
+-	W_REG(&di->d64rxregs->control,
+-		((di->rxoffset << D64_RC_RO_SHIFT) | control));
+-}
+-
+-static void
+-_dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
+-{
+-	/* the normal values fit into 16 bits */
+-	*rxoffset = (u16) di->rxoffset;
+-	*rxbufsize = (u16) di->rxbufsize;
+-}
+-
+-/* !! rx entry routine
+- * returns a pointer to the next frame received, or NULL if there are no more
+- *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
+- *      with pkts chain
+- *   otherwise, it's treated as giant pkt and will be tossed.
+- *   The DMA scattering starts with normal DMA header, followed by first buffer data.
+- *   After it reaches the max size of buffer, the data continues in next DMA descriptor
+- *   buffer WITHOUT DMA header
+- */
+-static void *_dma_rx(dma_info_t *di)
+-{
+-	struct sk_buff *p, *head, *tail;
+-	uint len;
+-	uint pkt_len;
+-	int resid = 0;
+-
+- next_frame:
+-	head = _dma_getnextrxp(di, false);
+-	if (head == NULL)
+-		return NULL;
+-
+-	len = le16_to_cpu(*(u16 *) (head->data));
+-	DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
+-	dma_spin_for_len(len, head);
+-
+-	/* set actual length */
+-	pkt_len = min((di->rxoffset + len), di->rxbufsize);
+-	__skb_trim(head, pkt_len);
+-	resid = len - (di->rxbufsize - di->rxoffset);
+-
+-	/* check for single or multi-buffer rx */
+-	if (resid > 0) {
+-		tail = head;
+-		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
+-			tail->next = p;
+-			pkt_len = min(resid, (int)di->rxbufsize);
+-			__skb_trim(p, pkt_len);
+-
+-			tail = p;
+-			resid -= di->rxbufsize;
+-		}
+-
+-#ifdef BCMDBG
+-		if (resid > 0) {
+-			uint cur;
+-			cur =
+-			    B2I(((R_REG(&di->d64rxregs->status0) &
+-				  D64_RS0_CD_MASK) -
+-				 di->rcvptrbase) & D64_RS0_CD_MASK,
+-				dma64dd_t);
+-			DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
+-				   di->rxin, di->rxout, cur));
+-		}
+-#endif				/* BCMDBG */
+-
+-		if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
+-			DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
+-				   di->name, len));
+-			bcm_pkt_buf_free_skb(head);
+-			di->hnddma.rxgiants++;
+-			goto next_frame;
+-		}
+-	}
+-
+-	return head;
+-}
+-
+-/* post receive buffers
+- *  return false is refill failed completely and ring is empty
+- *  this will stall the rx dma and user might want to call rxfill again asap
+- *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
+- */
+-static bool _dma_rxfill(dma_info_t *di)
+-{
+-	struct sk_buff *p;
+-	u16 rxin, rxout;
+-	u32 flags = 0;
+-	uint n;
+-	uint i;
+-	dmaaddr_t pa;
+-	uint extra_offset = 0;
+-	bool ring_empty;
+-
+-	ring_empty = false;
+-
+-	/*
+-	 * Determine how many receive buffers we're lacking
+-	 * from the full complement, allocate, initialize,
+-	 * and post them, then update the chip rx lastdscr.
+-	 */
+-
+-	rxin = di->rxin;
+-	rxout = di->rxout;
+-
+-	n = di->nrxpost - NRXDACTIVE(rxin, rxout);
+-
+-	DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
+-
+-	if (di->rxbufsize > BCMEXTRAHDROOM)
+-		extra_offset = di->rxextrahdrroom;
+-
+-	for (i = 0; i < n; i++) {
+-		/* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+-		   size to be allocated
+-		 */
+-
+-		p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset);
+-
+-		if (p == NULL) {
+-			DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
+-				   di->name));
+-			if (i == 0 && dma64_rxidle(di)) {
+-				DMA_ERROR(("%s: rxfill64: ring is empty !\n",
+-					   di->name));
+-				ring_empty = true;
+-			}
+-			di->hnddma.rxnobuf++;
+-			break;
+-		}
+-		/* reserve an extra headroom, if applicable */
+-		if (extra_offset)
+-			skb_pull(p, extra_offset);
+-
+-		/* Do a cached write instead of uncached write since DMA_MAP
+-		 * will flush the cache.
+-		 */
+-		*(u32 *) (p->data) = 0;
+-
+-		if (DMASGLIST_ENAB)
+-			memset(&di->rxp_dmah[rxout], 0,
+-				sizeof(hnddma_seg_map_t));
+-
+-		pa = pci_map_single(di->pbus, p->data,
+-			di->rxbufsize, PCI_DMA_FROMDEVICE);
+-
+-		/* save the free packet pointer */
+-		di->rxp[rxout] = p;
+-
+-		/* reset flags for each descriptor */
+-		flags = 0;
+-		if (rxout == (di->nrxd - 1))
+-			flags = D64_CTRL1_EOT;
+-
+-		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
+-			     di->rxbufsize);
+-		rxout = NEXTRXD(rxout);
+-	}
+-
+-	di->rxout = rxout;
+-
+-	/* update the chip lastdscr pointer */
+-	W_REG(&di->d64rxregs->ptr,
+-	      di->rcvptrbase + I2B(rxout, dma64dd_t));
+-
+-	return ring_empty;
+-}
+-
+-/* like getnexttxp but no reclaim */
+-static void *_dma_peeknexttxp(dma_info_t *di)
+-{
+-	uint end, i;
+-
+-	if (di->ntxd == 0)
+-		return NULL;
+-
+-	end =
+-	    B2I(((R_REG(&di->d64txregs->status0) &
+-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	for (i = di->txin; i != end; i = NEXTTXD(i))
+-		if (di->txp[i])
+-			return di->txp[i];
+-
+-	return NULL;
+-}
+-
+-/* like getnextrxp but not take off the ring */
+-static void *_dma_peeknextrxp(dma_info_t *di)
+-{
+-	uint end, i;
+-
+-	if (di->nrxd == 0)
+-		return NULL;
+-
+-	end =
+-	    B2I(((R_REG(&di->d64rxregs->status0) &
+-		  D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	for (i = di->rxin; i != end; i = NEXTRXD(i))
+-		if (di->rxp[i])
+-			return di->rxp[i];
+-
+-	return NULL;
+-}
+-
+-static void _dma_rxreclaim(dma_info_t *di)
+-{
+-	void *p;
+-
+-	DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+-
+-	while ((p = _dma_getnextrxp(di, true)))
+-		bcm_pkt_buf_free_skb(p);
+-}
+-
+-static void *_dma_getnextrxp(dma_info_t *di, bool forceall)
+-{
+-	if (di->nrxd == 0)
+-		return NULL;
+-
+-	return dma64_getnextrxp(di, forceall);
+-}
+-
+-static void _dma_txblock(dma_info_t *di)
+-{
+-	di->hnddma.txavail = 0;
+-}
+-
+-static void _dma_txunblock(dma_info_t *di)
+-{
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-}
+-
+-static uint _dma_txactive(dma_info_t *di)
+-{
+-	return NTXDACTIVE(di->txin, di->txout);
+-}
+-
+-static uint _dma_txpending(dma_info_t *di)
+-{
+-	uint curr;
+-
+-	curr =
+-	    B2I(((R_REG(&di->d64txregs->status0) &
+-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	return NTXDACTIVE(curr, di->txout);
+-}
+-
+-static uint _dma_txcommitted(dma_info_t *di)
+-{
+-	uint ptr;
+-	uint txin = di->txin;
+-
+-	if (txin == di->txout)
+-		return 0;
+-
+-	ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t);
+-
+-	return NTXDACTIVE(di->txin, ptr);
+-}
+-
+-static uint _dma_rxactive(dma_info_t *di)
+-{
+-	return NRXDACTIVE(di->rxin, di->rxout);
+-}
+-
+-static void _dma_counterreset(dma_info_t *di)
+-{
+-	/* reset all software counter */
+-	di->hnddma.rxgiants = 0;
+-	di->hnddma.rxnobuf = 0;
+-	di->hnddma.txnobuf = 0;
+-}
+-
+-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
+-{
+-	uint dmactrlflags = di->hnddma.dmactrlflags;
+-
+-	if (di == NULL) {
+-		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+-		return 0;
+-	}
+-
+-	dmactrlflags &= ~mask;
+-	dmactrlflags |= flags;
+-
+-	/* If trying to enable parity, check if parity is actually supported */
+-	if (dmactrlflags & DMA_CTRL_PEN) {
+-		u32 control;
+-
+-		control = R_REG(&di->d64txregs->control);
+-		W_REG(&di->d64txregs->control,
+-		      control | D64_XC_PD);
+-		if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
+-			/* We *can* disable it so it is supported,
+-			 * restore control register
+-			 */
+-			W_REG(&di->d64txregs->control,
+-			control);
+-		} else {
+-			/* Not supported, don't allow it to be enabled */
+-			dmactrlflags &= ~DMA_CTRL_PEN;
+-		}
+-	}
+-
+-	di->hnddma.dmactrlflags = dmactrlflags;
+-
+-	return dmactrlflags;
+-}
+-
+-/* get the address of the var in order to change later */
+-static unsigned long _dma_getvar(dma_info_t *di, const char *name)
+-{
+-	if (!strcmp(name, "&txavail"))
+-		return (unsigned long)&(di->hnddma.txavail);
+-	return 0;
+-}
+-
+-static
+-u8 dma_align_sizetobits(uint size)
+-{
+-	u8 bitpos = 0;
+-	while (size >>= 1) {
+-		bitpos++;
+-	}
+-	return bitpos;
+-}
+-
+-/* This function ensures that the DMA descriptor ring will not get allocated
+- * across Page boundary. If the allocation is done across the page boundary
+- * at the first time, then it is freed and the allocation is done at
+- * descriptor ring size aligned location. This will ensure that the ring will
+- * not cross page boundary
+- */
+-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+-			   u16 *alignbits, uint *alloced,
+-			   dmaaddr_t *descpa)
+-{
+-	void *va;
+-	u32 desc_strtaddr;
+-	u32 alignbytes = 1 << *alignbits;
+-
+-	va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
+-
+-	if (NULL == va)
+-		return NULL;
+-
+-	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
+-	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
+-							& boundary)) {
+-		*alignbits = dma_align_sizetobits(size);
+-		pci_free_consistent(di->pbus, size, va, *descpa);
+-		va = dma_alloc_consistent(di->pbus, size, *alignbits,
+-			alloced, descpa);
+-	}
+-	return va;
+-}
+-
+-/* 64-bit DMA functions */
+-
+-static void dma64_txinit(dma_info_t *di)
+-{
+-	u32 control = D64_XC_XE;
+-
+-	DMA_TRACE(("%s: dma_txinit\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	di->txin = di->txout = 0;
+-	di->hnddma.txavail = di->ntxd - 1;
+-
+-	/* clear tx descriptor ring */
+-	memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t)));
+-
+-	/* DMA engine with out alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (!di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+-
+-	if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
+-		control |= D64_XC_PD;
+-	OR_REG(&di->d64txregs->control, control);
+-
+-	/* DMA engine with alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+-}
+-
+-static bool dma64_txenabled(dma_info_t *di)
+-{
+-	u32 xc;
+-
+-	/* If the chip is dead, it is not enabled :-) */
+-	xc = R_REG(&di->d64txregs->control);
+-	return (xc != 0xffffffff) && (xc & D64_XC_XE);
+-}
+-
+-static void dma64_txsuspend(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	OR_REG(&di->d64txregs->control, D64_XC_SE);
+-}
+-
+-static void dma64_txresume(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_txresume\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	AND_REG(&di->d64txregs->control, ~D64_XC_SE);
+-}
+-
+-static bool dma64_txsuspended(dma_info_t *di)
+-{
+-	return (di->ntxd == 0) ||
+-	    ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
+-	     D64_XC_SE);
+-}
+-
+-static void dma64_txreclaim(dma_info_t *di, txd_range_t range)
+-{
+-	void *p;
+-
+-	DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
+-		   (range == HNDDMA_RANGE_ALL) ? "all" :
+-		   ((range ==
+-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+-		    "transferred")));
+-
+-	if (di->txin == di->txout)
+-		return;
+-
+-	while ((p = dma64_getnexttxp(di, range))) {
+-		/* For unframed data, we don't have any packets to free */
+-		if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
+-			bcm_pkt_buf_free_skb(p);
+-	}
+-}
+-
+-static bool dma64_txstopped(dma_info_t *di)
+-{
+-	return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+-		D64_XS0_XS_STOPPED);
+-}
+-
+-static bool dma64_rxstopped(dma_info_t *di)
+-{
+-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+-		D64_RS0_RS_STOPPED);
+-}
+-
+-static bool dma64_alloc(dma_info_t *di, uint direction)
+-{
+-	u16 size;
+-	uint ddlen;
+-	void *va;
+-	uint alloced = 0;
+-	u16 align;
+-	u16 align_bits;
+-
+-	ddlen = sizeof(dma64dd_t);
+-
+-	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+-	align_bits = di->dmadesc_align;
+-	align = (1 << align_bits);
+-
+-	if (direction == DMA_TX) {
+-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+-			&alloced, &di->txdpaorig);
+-		if (va == NULL) {
+-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
+-			return false;
+-		}
+-		align = (1 << align_bits);
+-		di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+-		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
+-		PHYSADDRLOSET(di->txdpa,
+-			      PHYSADDRLO(di->txdpaorig) + di->txdalign);
+-		PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
+-		di->txdalloc = alloced;
+-	} else {
+-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+-			&alloced, &di->rxdpaorig);
+-		if (va == NULL) {
+-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
+-			return false;
+-		}
+-		align = (1 << align_bits);
+-		di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+-		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
+-		PHYSADDRLOSET(di->rxdpa,
+-			      PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
+-		PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
+-		di->rxdalloc = alloced;
+-	}
+-
+-	return true;
+-}
+-
+-static bool dma64_txreset(dma_info_t *di)
+-{
+-	u32 status;
+-
+-	if (di->ntxd == 0)
+-		return true;
+-
+-	/* suspend tx DMA first */
+-	W_REG(&di->d64txregs->control, D64_XC_SE);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+-		  != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+-		 && (status != D64_XS0_XS_STOPPED), 10000);
+-
+-	W_REG(&di->d64txregs->control, 0);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+-		  != D64_XS0_XS_DISABLED), 10000);
+-
+-	/* wait for the last transaction to complete */
+-	udelay(300);
+-
+-	return status == D64_XS0_XS_DISABLED;
+-}
+-
+-static bool dma64_rxidle(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_rxidle\n", di->name));
+-
+-	if (di->nrxd == 0)
+-		return true;
+-
+-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+-		(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
+-}
+-
+-static bool dma64_rxreset(dma_info_t *di)
+-{
+-	u32 status;
+-
+-	if (di->nrxd == 0)
+-		return true;
+-
+-	W_REG(&di->d64rxregs->control, 0);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
+-		  != D64_RS0_RS_DISABLED), 10000);
+-
+-	return status == D64_RS0_RS_DISABLED;
+-}
+-
+-static bool dma64_rxenabled(dma_info_t *di)
+-{
+-	u32 rc;
+-
+-	rc = R_REG(&di->d64rxregs->control);
+-	return (rc != 0xffffffff) && (rc & D64_RC_RE);
+-}
+-
+-static bool dma64_txsuspendedidle(dma_info_t *di)
+-{
+-
+-	if (di->ntxd == 0)
+-		return true;
+-
+-	if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
+-		return 0;
+-
+-	if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+-	    D64_XS0_XS_IDLE)
+-		return 1;
+-
+-	return 0;
+-}
+-
+-/* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
+- * We return a pointer to the beginning of the DATA buffer of the current descriptor.
+- * If DMA is idle, we return NULL.
+- */
+-static void *dma64_getpos(dma_info_t *di, bool direction)
+-{
+-	void *va;
+-	bool idle;
+-	u32 cd_offset;
+-
+-	if (direction == DMA_TX) {
+-		cd_offset =
+-		    R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
+-		idle = !NTXDACTIVE(di->txin, di->txout);
+-		va = di->txp[B2I(cd_offset, dma64dd_t)];
+-	} else {
+-		cd_offset =
+-		    R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
+-		idle = !NRXDACTIVE(di->rxin, di->rxout);
+-		va = di->rxp[B2I(cd_offset, dma64dd_t)];
+-	}
+-
+-	/* If DMA is IDLE, return NULL */
+-	if (idle) {
+-		DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
+-		va = NULL;
+-	}
+-
+-	return va;
+-}
+-
+-/* TX of unframed data
+- *
+- * Adds a DMA ring descriptor for the data pointed to by "buf".
+- * This is for DMA of a buffer of data and is unlike other hnddma TX functions
+- * that take a pointer to a "packet"
+- * Each call to this is results in a single descriptor being added for "len" bytes of
+- * data starting at "buf", it doesn't handle chained buffers.
+- */
+-static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
+-{
+-	u16 txout;
+-	u32 flags = 0;
+-	dmaaddr_t pa;		/* phys addr */
+-
+-	txout = di->txout;
+-
+-	/* return nonzero if out of tx descriptors */
+-	if (NEXTTXD(txout) == di->txin)
+-		goto outoftxd;
+-
+-	if (len == 0)
+-		return 0;
+-
+-	pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
+-
+-	flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
+-
+-	if (txout == (di->ntxd - 1))
+-		flags |= D64_CTRL1_EOT;
+-
+-	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+-
+-	/* save the buffer pointer - used by dma_getpos */
+-	di->txp[txout] = buf;
+-
+-	txout = NEXTTXD(txout);
+-	/* bump the tx descriptor index */
+-	di->txout = txout;
+-
+-	/* kick the chip */
+-	if (commit) {
+-		W_REG(&di->d64txregs->ptr,
+-		      di->xmtptrbase + I2B(txout, dma64dd_t));
+-	}
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return 0;
+-
+- outoftxd:
+-	DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
+-	di->hnddma.txavail = 0;
+-	di->hnddma.txnobuf++;
+-	return -1;
+-}
+-
+-/* !! tx entry routine
+- * WARNING: call must check the return value for error.
+- *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
+- */
+-static int dma64_txfast(dma_info_t *di, struct sk_buff *p0,
+-				    bool commit)
+-{
+-	struct sk_buff *p, *next;
+-	unsigned char *data;
+-	uint len;
+-	u16 txout;
+-	u32 flags = 0;
+-	dmaaddr_t pa;
+-
+-	DMA_TRACE(("%s: dma_txfast\n", di->name));
+-
+-	txout = di->txout;
+-
+-	/*
+-	 * Walk the chain of packet buffers
+-	 * allocating and initializing transmit descriptor entries.
+-	 */
+-	for (p = p0; p; p = next) {
+-		uint nsegs, j;
+-		hnddma_seg_map_t *map;
+-
+-		data = p->data;
+-		len = p->len;
+-		next = p->next;
+-
+-		/* return nonzero if out of tx descriptors */
+-		if (NEXTTXD(txout) == di->txin)
+-			goto outoftxd;
+-
+-		if (len == 0)
+-			continue;
+-
+-		/* get physical address of buffer start */
+-		if (DMASGLIST_ENAB)
+-			memset(&di->txp_dmah[txout], 0,
+-				sizeof(hnddma_seg_map_t));
+-
+-		pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
+-
+-		if (DMASGLIST_ENAB) {
+-			map = &di->txp_dmah[txout];
+-
+-			/* See if all the segments can be accounted for */
+-			if (map->nsegs >
+-			    (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
+-				    1))
+-				goto outoftxd;
+-
+-			nsegs = map->nsegs;
+-		} else
+-			nsegs = 1;
+-
+-		for (j = 1; j <= nsegs; j++) {
+-			flags = 0;
+-			if (p == p0 && j == 1)
+-				flags |= D64_CTRL1_SOF;
+-
+-			/* With a DMA segment list, Descriptor table is filled
+-			 * using the segment list instead of looping over
+-			 * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
+-			 * end of segment list is reached.
+-			 */
+-			if ((!DMASGLIST_ENAB && next == NULL) ||
+-			    (DMASGLIST_ENAB && j == nsegs))
+-				flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+-			if (txout == (di->ntxd - 1))
+-				flags |= D64_CTRL1_EOT;
+-
+-			if (DMASGLIST_ENAB) {
+-				len = map->segs[j - 1].length;
+-				pa = map->segs[j - 1].addr;
+-			}
+-			dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+-
+-			txout = NEXTTXD(txout);
+-		}
+-
+-		/* See above. No need to loop over individual buffers */
+-		if (DMASGLIST_ENAB)
+-			break;
+-	}
+-
+-	/* if last txd eof not set, fix it */
+-	if (!(flags & D64_CTRL1_EOF))
+-		W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
+-		     BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+-
+-	/* save the packet */
+-	di->txp[PREVTXD(txout)] = p0;
+-
+-	/* bump the tx descriptor index */
+-	di->txout = txout;
+-
+-	/* kick the chip */
+-	if (commit)
+-		W_REG(&di->d64txregs->ptr,
+-		      di->xmtptrbase + I2B(txout, dma64dd_t));
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return 0;
+-
+- outoftxd:
+-	DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
+-	bcm_pkt_buf_free_skb(p0);
+-	di->hnddma.txavail = 0;
+-	di->hnddma.txnobuf++;
+-	return -1;
+-}
+-
+-/*
+- * Reclaim next completed txd (txds if using chained buffers) in the range
+- * specified and return associated packet.
+- * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
+- * transmitted as noted by the hardware "CurrDescr" pointer.
+- * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
+- * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
+- * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
+- * return associated packet regardless of the value of hardware pointers.
+- */
+-static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range)
+-{
+-	u16 start, end, i;
+-	u16 active_desc;
+-	void *txp;
+-
+-	DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
+-		   (range == HNDDMA_RANGE_ALL) ? "all" :
+-		   ((range ==
+-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+-		    "transferred")));
+-
+-	if (di->ntxd == 0)
+-		return NULL;
+-
+-	txp = NULL;
+-
+-	start = di->txin;
+-	if (range == HNDDMA_RANGE_ALL)
+-		end = di->txout;
+-	else {
+-		dma64regs_t *dregs = di->d64txregs;
+-
+-		end =
+-		    (u16) (B2I
+-			      (((R_REG(&dregs->status0) &
+-				 D64_XS0_CD_MASK) -
+-				di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
+-
+-		if (range == HNDDMA_RANGE_TRANSFERED) {
+-			active_desc =
+-			    (u16) (R_REG(&dregs->status1) &
+-				      D64_XS1_AD_MASK);
+-			active_desc =
+-			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
+-			active_desc = B2I(active_desc, dma64dd_t);
+-			if (end != active_desc)
+-				end = PREVTXD(active_desc);
+-		}
+-	}
+-
+-	if ((start == 0) && (end > di->txout))
+-		goto bogus;
+-
+-	for (i = start; i != end && !txp; i = NEXTTXD(i)) {
+-		dmaaddr_t pa;
+-		hnddma_seg_map_t *map = NULL;
+-		uint size, j, nsegs;
+-
+-		PHYSADDRLOSET(pa,
+-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
+-			       di->dataoffsetlow));
+-		PHYSADDRHISET(pa,
+-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
+-			       di->dataoffsethigh));
+-
+-		if (DMASGLIST_ENAB) {
+-			map = &di->txp_dmah[i];
+-			size = map->origsize;
+-			nsegs = map->nsegs;
+-		} else {
+-			size =
+-			    (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
+-			     D64_CTRL2_BC_MASK);
+-			nsegs = 1;
+-		}
+-
+-		for (j = nsegs; j > 0; j--) {
+-			W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
+-			W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+-
+-			txp = di->txp[i];
+-			di->txp[i] = NULL;
+-			if (j > 1)
+-				i = NEXTTXD(i);
+-		}
+-
+-		pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
+-	}
+-
+-	di->txin = i;
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return txp;
+-
+- bogus:
+-	DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
+-	return NULL;
+-}
+-
+-static void *dma64_getnextrxp(dma_info_t *di, bool forceall)
+-{
+-	uint i, curr;
+-	void *rxp;
+-	dmaaddr_t pa;
+-
+-	i = di->rxin;
+-
+-	/* return if no packets posted */
+-	if (i == di->rxout)
+-		return NULL;
+-
+-	curr =
+-	    B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
+-		 di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
+-
+-	/* ignore curr if forceall */
+-	if (!forceall && (i == curr))
+-		return NULL;
+-
+-	/* get the packet pointer that corresponds to the rx descriptor */
+-	rxp = di->rxp[i];
+-	di->rxp[i] = NULL;
+-
+-	PHYSADDRLOSET(pa,
+-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
+-		       di->dataoffsetlow));
+-	PHYSADDRHISET(pa,
+-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
+-		       di->dataoffsethigh));
+-
+-	/* clear this packet from the descriptor ring */
+-	pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
+-
+-	W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
+-	W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+-
+-	di->rxin = NEXTRXD(i);
+-
+-	return rxp;
+-}
+-
+-static bool _dma64_addrext(dma64regs_t *dma64regs)
+-{
+-	u32 w;
+-	OR_REG(&dma64regs->control, D64_XC_AE);
+-	w = R_REG(&dma64regs->control);
+-	AND_REG(&dma64regs->control, ~D64_XC_AE);
+-	return (w & D64_XC_AE) == D64_XC_AE;
+-}
+-
+-/*
+- * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
+- */
+-static void dma64_txrotate(dma_info_t *di)
+-{
+-	u16 ad;
+-	uint nactive;
+-	uint rot;
+-	u16 old, new;
+-	u32 w;
+-	u16 first, last;
+-
+-	nactive = _dma_txactive(di);
+-	ad = (u16) (B2I
+-		       ((((R_REG(&di->d64txregs->status1) &
+-			   D64_XS1_AD_MASK)
+-			  - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
+-	rot = TXD(ad - di->txin);
+-
+-	/* full-ring case is a lot harder - don't worry about this */
+-	if (rot >= (di->ntxd - nactive)) {
+-		DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
+-		return;
+-	}
+-
+-	first = di->txin;
+-	last = PREVTXD(di->txout);
+-
+-	/* move entries starting at last and moving backwards to first */
+-	for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
+-		new = TXD(old + rot);
+-
+-		/*
+-		 * Move the tx dma descriptor.
+-		 * EOT is set only in the last entry in the ring.
+-		 */
+-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+-		if (new == (di->ntxd - 1))
+-			w |= D64_CTRL1_EOT;
+-		W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
+-
+-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
+-		W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
+-
+-		W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
+-		W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
+-
+-		/* zap the old tx dma descriptor address field */
+-		W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
+-		W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
+-
+-		/* move the corresponding txp[] entry */
+-		di->txp[new] = di->txp[old];
+-
+-		/* Move the map */
+-		if (DMASGLIST_ENAB) {
+-			memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
+-			       sizeof(hnddma_seg_map_t));
+-			memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t));
+-		}
+-
+-		di->txp[old] = NULL;
+-	}
+-
+-	/* update txin and txout */
+-	di->txin = ad;
+-	di->txout = TXD(di->txout + rot);
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	/* kick the chip */
+-	W_REG(&di->d64txregs->ptr,
+-	      di->xmtptrbase + I2B(di->txout, dma64dd_t));
+-}
+-
+-uint dma_addrwidth(si_t *sih, void *dmaregs)
+-{
+-	/* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
+-	/* DMA engine is 64-bit capable */
+-	if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
+-		/* backplane are 64-bit capable */
+-		if (ai_backplane64(sih))
+-			/* If bus is System Backplane or PCIE then we can access 64-bits */
+-			if ((sih->bustype == SI_BUS) ||
+-			    ((sih->bustype == PCI_BUS) &&
+-			     (sih->buscoretype == PCIE_CORE_ID)))
+-				return DMADDRWIDTH_64;
+-	}
+-	/* DMA hardware not supported by this driver*/
+-	return DMADDRWIDTH_64;
+-}
+-
+-/*
+- * Mac80211 initiated actions sometimes require packets in the DMA queue to be
+- * modified. The modified portion of the packet is not under control of the DMA
+- * engine. This function calls a caller-supplied function for each packet in
+- * the caller specified dma chain.
+- */
+-void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
+-		      (void *pkt, void *arg_a), void *arg_a)
+-{
+-	dma_info_t *di = (dma_info_t *) dmah;
+-	uint i =   di->txin;
+-	uint end = di->txout;
+-	struct sk_buff *skb;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	while (i != end) {
+-		skb = (struct sk_buff *)di->txp[i];
+-		if (skb != NULL) {
+-			tx_info = (struct ieee80211_tx_info *)skb->cb;
+-			(callback_fnc)(tx_info, arg_a);
+-		}
+-		i = NEXTTXD(i);
+-	}
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c
+deleted file mode 100644
+index 18b844a..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/nicpci.c
++++ /dev/null
+@@ -1,836 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/string.h>
+-#include <linux/pci.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <bcmdevs.h>
+-#include <sbchipc.h>
+-#include <pci_core.h>
+-#include <pcie_core.h>
+-#include <nicpci.h>
+-#include <pcicfg.h>
+-
+-typedef struct {
+-	union {
+-		sbpcieregs_t *pcieregs;
+-		struct sbpciregs *pciregs;
+-	} regs;			/* Memory mapped register to the core */
+-
+-	si_t *sih;		/* System interconnect handle */
+-	struct pci_dev *dev;
+-	u8 pciecap_lcreg_offset;	/* PCIE capability LCreg offset in the config space */
+-	bool pcie_pr42767;
+-	u8 pcie_polarity;
+-	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
+-
+-	u8 pmecap_offset;	/* PM Capability offset in the config space */
+-	bool pmecap;		/* Capable of generating PME */
+-} pcicore_info_t;
+-
+-/* debug/trace */
+-#define	PCI_ERROR(args)
+-#define PCIE_PUB(sih) \
+-	(((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))
+-
+-/* routines to access mdio slave device registers */
+-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
+-static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
+-		       bool write, uint *val);
+-static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
+-			  uint val);
+-static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
+-			 uint *ret_val);
+-
+-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
+-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);
+-
+-static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
+-static void pcie_war_serdes(pcicore_info_t *pi);
+-static void pcie_war_noplldown(pcicore_info_t *pi);
+-static void pcie_war_polarity(pcicore_info_t *pi);
+-static void pcie_war_pci_setup(pcicore_info_t *pi);
+-
+-static bool pcicore_pmecap(pcicore_info_t *pi);
+-
+-#define PCIE_ASPM(sih)	((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))
+-
+-
+-/* delay needed between the mdio control/ mdiodata register data access */
+-#define PR28829_DELAY() udelay(10)
+-
+-/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
+- * only once
+- */
+-void *pcicore_init(si_t *sih, void *pdev, void *regs)
+-{
+-	pcicore_info_t *pi;
+-
+-	/* alloc pcicore_info_t */
+-	pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC);
+-	if (pi == NULL) {
+-		PCI_ERROR(("pci_attach: malloc failed!\n"));
+-		return NULL;
+-	}
+-
+-	pi->sih = sih;
+-	pi->dev = pdev;
+-
+-	if (sih->buscoretype == PCIE_CORE_ID) {
+-		u8 cap_ptr;
+-		pi->regs.pcieregs = (sbpcieregs_t *) regs;
+-		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
+-						      NULL, NULL);
+-		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
+-	} else
+-		pi->regs.pciregs = (struct sbpciregs *) regs;
+-
+-	return pi;
+-}
+-
+-void pcicore_deinit(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (pi == NULL)
+-		return;
+-	kfree(pi);
+-}
+-
+-/* return cap_offset if requested capability exists in the PCI config space */
+-/* Note that it's caller's responsibility to make sure it's a pci bus */
+-u8
+-pcicore_find_pci_capability(void *dev, u8 req_cap_id,
+-			    unsigned char *buf, u32 *buflen)
+-{
+-	u8 cap_id;
+-	u8 cap_ptr = 0;
+-	u32 bufsize;
+-	u8 byte_val;
+-
+-	/* check for Header type 0 */
+-	pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
+-	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
+-		goto end;
+-
+-	/* check if the capability pointer field exists */
+-	pci_read_config_byte(dev, PCI_STATUS, &byte_val);
+-	if (!(byte_val & PCI_STATUS_CAP_LIST))
+-		goto end;
+-
+-	pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
+-	/* check if the capability pointer is 0x00 */
+-	if (cap_ptr == 0x00)
+-		goto end;
+-
+-	/* loop thr'u the capability list and see if the pcie capabilty exists */
+-
+-	pci_read_config_byte(dev, cap_ptr, &cap_id);
+-
+-	while (cap_id != req_cap_id) {
+-		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
+-		if (cap_ptr == 0x00)
+-			break;
+-		pci_read_config_byte(dev, cap_ptr, &cap_id);
+-	}
+-	if (cap_id != req_cap_id) {
+-		goto end;
+-	}
+-	/* found the caller requested capability */
+-	if ((buf != NULL) && (buflen != NULL)) {
+-		u8 cap_data;
+-
+-		bufsize = *buflen;
+-		if (!bufsize)
+-			goto end;
+-		*buflen = 0;
+-		/* copy the cpability data excluding cap ID and next ptr */
+-		cap_data = cap_ptr + 2;
+-		if ((bufsize + cap_data) > PCI_SZPCR)
+-			bufsize = PCI_SZPCR - cap_data;
+-		*buflen = bufsize;
+-		while (bufsize--) {
+-			pci_read_config_byte(dev, cap_data, buf);
+-			cap_data++;
+-			buf++;
+-		}
+-	}
+- end:
+-	return cap_ptr;
+-}
+-
+-/* ***** Register Access API */
+-uint
+-pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype,
+-	     uint offset)
+-{
+-	uint retval = 0xFFFFFFFF;
+-
+-	switch (addrtype) {
+-	case PCIE_CONFIGREGS:
+-		W_REG((&pcieregs->configaddr), offset);
+-		(void)R_REG((&pcieregs->configaddr));
+-		retval = R_REG(&(pcieregs->configdata));
+-		break;
+-	case PCIE_PCIEREGS:
+-		W_REG(&(pcieregs->pcieindaddr), offset);
+-		(void)R_REG((&pcieregs->pcieindaddr));
+-		retval = R_REG(&(pcieregs->pcieinddata));
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	return retval;
+-}
+-
+-uint
+-pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype,
+-	      uint offset, uint val)
+-{
+-	switch (addrtype) {
+-	case PCIE_CONFIGREGS:
+-		W_REG((&pcieregs->configaddr), offset);
+-		W_REG((&pcieregs->configdata), val);
+-		break;
+-	case PCIE_PCIEREGS:
+-		W_REG((&pcieregs->pcieindaddr), offset);
+-		W_REG((&pcieregs->pcieinddata), val);
+-		break;
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	uint mdiodata, i = 0;
+-	uint pcie_serdes_spinwait = 200;
+-
+-	mdiodata =
+-	    MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
+-					       MDIODATA_DEVADDR_SHF) |
+-	    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
+-									 4);
+-	W_REG(&pcieregs->mdiodata, mdiodata);
+-
+-	PR28829_DELAY();
+-	/* retry till the transaction is complete */
+-	while (i < pcie_serdes_spinwait) {
+-		if (R_REG(&(pcieregs->mdiocontrol)) &
+-		    MDIOCTL_ACCESS_DONE) {
+-			break;
+-		}
+-		udelay(1000);
+-		i++;
+-	}
+-
+-	if (i >= pcie_serdes_spinwait) {
+-		PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-static int
+-pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
+-	    uint *val)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	uint mdiodata;
+-	uint i = 0;
+-	uint pcie_serdes_spinwait = 10;
+-
+-	/* enable mdio access to SERDES */
+-	W_REG((&pcieregs->mdiocontrol),
+-	      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+-
+-	if (pi->sih->buscorerev >= 10) {
+-		/* new serdes is slower in rw, using two layers of reg address mapping */
+-		if (!pcie_mdiosetblock(pi, physmedia))
+-			return 1;
+-		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
+-		    (regaddr << MDIODATA_REGADDR_SHF);
+-		pcie_serdes_spinwait *= 20;
+-	} else {
+-		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
+-		    (regaddr << MDIODATA_REGADDR_SHF_OLD);
+-	}
+-
+-	if (!write)
+-		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
+-	else
+-		mdiodata |=
+-		    (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);
+-
+-	W_REG(&pcieregs->mdiodata, mdiodata);
+-
+-	PR28829_DELAY();
+-
+-	/* retry till the transaction is complete */
+-	while (i < pcie_serdes_spinwait) {
+-		if (R_REG(&(pcieregs->mdiocontrol)) &
+-		    MDIOCTL_ACCESS_DONE) {
+-			if (!write) {
+-				PR28829_DELAY();
+-				*val =
+-				    (R_REG(&(pcieregs->mdiodata)) &
+-				     MDIODATA_MASK);
+-			}
+-			/* Disable mdio access to SERDES */
+-			W_REG((&pcieregs->mdiocontrol), 0);
+-			return 0;
+-		}
+-		udelay(1000);
+-		i++;
+-	}
+-
+-	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
+-	/* Disable mdio access to SERDES */
+-	W_REG((&pcieregs->mdiocontrol), 0);
+-	return 1;
+-}
+-
+-/* use the mdio interface to read from mdio slaves */
+-static int
+-pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
+-{
+-	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
+-}
+-
+-/* use the mdio interface to write to mdio slaves */
+-static int
+-pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
+-{
+-	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
+-}
+-
+-/* ***** Support functions ***** */
+-u8 pcie_clkreq(void *pch, u32 mask, u32 val)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 reg_val;
+-	u8 offset;
+-
+-	offset = pi->pciecap_lcreg_offset;
+-	if (!offset)
+-		return 0;
+-
+-	pci_read_config_dword(pi->dev, offset, &reg_val);
+-	/* set operation */
+-	if (mask) {
+-		if (val)
+-			reg_val |= PCIE_CLKREQ_ENAB;
+-		else
+-			reg_val &= ~PCIE_CLKREQ_ENAB;
+-		pci_write_config_dword(pi->dev, offset, reg_val);
+-		pci_read_config_dword(pi->dev, offset, &reg_val);
+-	}
+-	if (reg_val & PCIE_CLKREQ_ENAB)
+-		return 1;
+-	else
+-		return 0;
+-}
+-
+-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
+-{
+-	u32 w;
+-	si_t *sih = pi->sih;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-
+-	if (!PCIE_PUB(sih) || sih->buscorerev < 7)
+-		return;
+-
+-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+-	if (extend)
+-		w |= PCIE_ASPMTIMER_EXTEND;
+-	else
+-		w &= ~PCIE_ASPMTIMER_EXTEND;
+-	pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
+-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+-}
+-
+-/* centralized clkreq control policy */
+-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
+-{
+-	si_t *sih = pi->sih;
+-
+-	switch (state) {
+-	case SI_DOATTACH:
+-		if (PCIE_ASPM(sih))
+-			pcie_clkreq((void *)pi, 1, 0);
+-		break;
+-	case SI_PCIDOWN:
+-		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-				   0);
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_data),
+-				   ~0x40, 0);
+-		} else if (pi->pcie_pr42767) {
+-			pcie_clkreq((void *)pi, 1, 1);
+-		}
+-		break;
+-	case SI_PCIUP:
+-		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-				   0);
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_data),
+-				   ~0x40, 0x40);
+-		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
+-			pcie_clkreq((void *)pi, 1, 0);
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-/* ***** PCI core WARs ***** */
+-/* Done only once at attach time */
+-static void pcie_war_polarity(pcicore_info_t *pi)
+-{
+-	u32 w;
+-
+-	if (pi->pcie_polarity != 0)
+-		return;
+-
+-	w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS,
+-			 PCIE_PLP_STATUSREG);
+-
+-	/* Detect the current polarity at attach and force that polarity and
+-	 * disable changing the polarity
+-	 */
+-	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
+-		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
+-	else
+-		pi->pcie_polarity =
+-		    (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
+-}
+-
+-/* enable ASPM and CLKREQ if srom doesn't have it */
+-/* Needs to happen when update to shadow SROM is needed
+- *   : Coming out of 'standby'/'hibernate'
+- *   : If pcie_war_aspm_ovr state changed
+- */
+-static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	si_t *sih = pi->sih;
+-	u16 val16, *reg16;
+-	u32 w;
+-
+-	if (!PCIE_ASPM(sih))
+-		return;
+-
+-	/* bypass this on QT or VSIM */
+-	if (!ISSIM_ENAB(sih)) {
+-
+-		reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
+-		val16 = R_REG(reg16);
+-
+-		val16 &= ~SRSH_ASPM_ENB;
+-		if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
+-			val16 |= SRSH_ASPM_ENB;
+-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
+-			val16 |= SRSH_ASPM_L1_ENB;
+-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
+-			val16 |= SRSH_ASPM_L0s_ENB;
+-
+-		W_REG(reg16, val16);
+-
+-		pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset,
+-					&w);
+-		w &= ~PCIE_ASPM_ENAB;
+-		w |= pi->pcie_war_aspm_ovr;
+-		pci_write_config_dword(pi->dev,
+-					pi->pciecap_lcreg_offset, w);
+-	}
+-
+-	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
+-	val16 = R_REG(reg16);
+-
+-	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
+-		val16 |= SRSH_CLKREQ_ENB;
+-		pi->pcie_pr42767 = true;
+-	} else
+-		val16 &= ~SRSH_CLKREQ_ENB;
+-
+-	W_REG(reg16, val16);
+-}
+-
+-/* Apply the polarity determined at the start */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_serdes(pcicore_info_t *pi)
+-{
+-	u32 w = 0;
+-
+-	if (pi->pcie_polarity != 0)
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
+-			       pi->pcie_polarity);
+-
+-	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
+-	if (w & PLL_CTRL_FREQDET_EN) {
+-		w &= ~PLL_CTRL_FREQDET_EN;
+-		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
+-	}
+-}
+-
+-/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_misc_config_fixup(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u16 val16, *reg16;
+-
+-	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
+-	val16 = R_REG(reg16);
+-
+-	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
+-		val16 |= SRSH_L23READY_EXIT_NOPERST;
+-		W_REG(reg16, val16);
+-	}
+-}
+-
+-/* quick hack for testing */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_noplldown(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u16 *reg16;
+-
+-	/* turn off serdes PLL down */
+-	ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
+-		   CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
+-
+-	/*  clear srom shadow backdoor */
+-	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
+-	W_REG(reg16, 0);
+-}
+-
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_pci_setup(pcicore_info_t *pi)
+-{
+-	si_t *sih = pi->sih;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u32 w;
+-
+-	if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+-				 PCIE_TLP_WORKAROUNDSREG);
+-		w |= 0x8;
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+-			      PCIE_TLP_WORKAROUNDSREG, w);
+-	}
+-
+-	if (sih->buscorerev == 1) {
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
+-		w |= (0x40);
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
+-	}
+-
+-	if (sih->buscorerev == 0) {
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
+-	} else if (PCIE_ASPM(sih)) {
+-		/* Change the L1 threshold for better performance */
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+-				 PCIE_DLLP_PMTHRESHREG);
+-		w &= ~(PCIE_L1THRESHOLDTIME_MASK);
+-		w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+-			      PCIE_DLLP_PMTHRESHREG, w);
+-
+-		pcie_war_serdes(pi);
+-
+-		pcie_war_aspm_clkreq(pi);
+-	} else if (pi->sih->buscorerev == 7)
+-		pcie_war_noplldown(pi);
+-
+-	/* Note that the fix is actually in the SROM, that's why this is open-ended */
+-	if (pi->sih->buscorerev >= 6)
+-		pcie_misc_config_fixup(pi);
+-}
+-
+-void pcie_war_ovr_aspm_update(void *pch, u8 aspm)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!PCIE_ASPM(pi->sih))
+-		return;
+-
+-	/* Validate */
+-	if (aspm > PCIE_ASPM_ENAB)
+-		return;
+-
+-	pi->pcie_war_aspm_ovr = aspm;
+-
+-	/* Update the current state */
+-	pcie_war_aspm_clkreq(pi);
+-}
+-
+-/* ***** Functions called during driver state changes ***** */
+-void pcicore_attach(void *pch, char *pvars, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	si_t *sih = pi->sih;
+-
+-	/* Determine if this board needs override */
+-	if (PCIE_ASPM(sih)) {
+-		if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
+-			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
+-		} else {
+-			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
+-		}
+-	}
+-
+-	/* These need to happen in this order only */
+-	pcie_war_polarity(pi);
+-
+-	pcie_war_serdes(pi);
+-
+-	pcie_war_aspm_clkreq(pi);
+-
+-	pcie_clkreq_upd(pi, state);
+-
+-}
+-
+-void pcicore_hwup(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	pcie_war_pci_setup(pi);
+-}
+-
+-void pcicore_up(void *pch, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	/* Restore L1 timer for better performance */
+-	pcie_extendL1timer(pi, true);
+-
+-	pcie_clkreq_upd(pi, state);
+-}
+-
+-/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
+-void pcicore_sleep(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pi || !PCIE_ASPM(pi->sih))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
+-	w &= ~PCIE_CAP_LCREG_ASPML1;
+-	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
+-
+-	pi->pcie_pr42767 = false;
+-}
+-
+-void pcicore_down(void *pch, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	pcie_clkreq_upd(pi, state);
+-
+-	/* Reduce L1 timer for better power savings */
+-	pcie_extendL1timer(pi, false);
+-}
+-
+-/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
+-/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
+-bool pcicore_pmecap_fast(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u8 cap_ptr;
+-	u32 pmecap;
+-
+-	cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_PM, NULL,
+-					      NULL);
+-
+-	if (!cap_ptr)
+-		return false;
+-
+-	pci_read_config_dword(pi->dev, cap_ptr, &pmecap);
+-
+-	return (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+-}
+-
+-/* return true if PM capability exists in the pci config space
+- * Uses and caches the information using core handle
+- */
+-static bool pcicore_pmecap(pcicore_info_t *pi)
+-{
+-	u8 cap_ptr;
+-	u32 pmecap;
+-
+-	if (!pi->pmecap_offset) {
+-		cap_ptr = pcicore_find_pci_capability(pi->dev,
+-						      PCI_CAP_ID_PM,
+-						      NULL, NULL);
+-		if (!cap_ptr)
+-			return false;
+-
+-		pi->pmecap_offset = cap_ptr;
+-
+-		pci_read_config_dword(pi->dev, pi->pmecap_offset,
+-					&pmecap);
+-
+-		/* At least one state can generate PME */
+-		pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+-	}
+-
+-	return pi->pmecap;
+-}
+-
+-/* Enable PME generation */
+-void pcicore_pmeen(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	/* if not pmecapable return */
+-	if (!pcicore_pmecap(pi))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-	w |= (PCI_PM_CTRL_PME_ENABLE);
+-	pci_write_config_dword(pi->dev,
+-				pi->pmecap_offset + PCI_PM_CTRL, w);
+-}
+-
+-/*
+- * Return true if PME status set
+- */
+-bool pcicore_pmestat(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pcicore_pmecap(pi))
+-		return false;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-
+-	return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS;
+-}
+-
+-/* Disable PME generation, clear the PME status bit if set
+- */
+-void pcicore_pmeclr(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pcicore_pmecap(pi))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-
+-	PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));
+-
+-	/* PMESTAT is cleared by writing 1 to it */
+-	w &= ~(PCI_PM_CTRL_PME_ENABLE);
+-
+-	pci_write_config_dword(pi->dev,
+-				pi->pmecap_offset + PCI_PM_CTRL, w);
+-}
+-
+-u32 pcie_lcreg(void *pch, u32 mask, u32 val)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u8 offset;
+-	u32 tmpval;
+-
+-	offset = pi->pciecap_lcreg_offset;
+-	if (!offset)
+-		return 0;
+-
+-	/* set operation */
+-	if (mask)
+-		pci_write_config_dword(pi->dev, offset, val);
+-
+-	pci_read_config_dword(pi->dev, offset, &tmpval);
+-	return tmpval;
+-}
+-
+-u32
+-pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type)
+-{
+-	u32 reg_val = 0;
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-
+-	if (mask) {
+-		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
+-		pcie_writereg(pcieregs, type, offset, val);
+-	}
+-
+-	/* Should not read register 0x154 */
+-	if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
+-	    && type == PCIE_PCIEREGS)
+-		return reg_val;
+-
+-	reg_val = pcie_readreg(pcieregs, type, offset);
+-	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));
+-
+-	return reg_val;
+-}
+-
+-u32
+-pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask,
+-		      u32 val)
+-{
+-	u32 reg_val = 0;
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (mask) {
+-		PCI_ERROR(("PCIEMDIOREG: 0x%x writeval  0x%x\n", offset, val));
+-		pcie_mdiowrite(pi, mdioslave, offset, val);
+-	}
+-
+-	if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
+-		reg_val = 0xFFFFFFFF;
+-	PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
+-		   offset, reg_val));
+-
+-	return reg_val;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/nvram.c b/drivers/staging/brcm80211/brcmsmac/nvram.c
+deleted file mode 100644
+index 085ec0b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/nvram.c
++++ /dev/null
+@@ -1,215 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <hndsoc.h>
+-
+-#define NVR_MSG(x)
+-
+-typedef struct _vars {
+-	struct _vars *next;
+-	int bufsz;		/* allocated size */
+-	int size;		/* actual vars size */
+-	char *vars;
+-} vars_t;
+-
+-#define	VARS_T_OH	sizeof(vars_t)
+-
+-static vars_t *vars;
+-
+-#define NVRAM_FILE	1
+-
+-static char *findvar(char *vars, char *lim, const char *name);
+-
+-int nvram_init(void)
+-{
+-
+-	/* Make sure we read nvram in flash just once before freeing the memory */
+-	if (vars != NULL) {
+-		NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
+-		return 0;
+-	}
+-	return 0;
+-}
+-
+-int nvram_append(char *varlst, uint varsz)
+-{
+-	uint bufsz = VARS_T_OH;
+-	vars_t *new;
+-
+-	new = kmalloc(bufsz, GFP_ATOMIC);
+-	if (new == NULL)
+-		return -ENOMEM;
+-
+-	new->vars = varlst;
+-	new->bufsz = bufsz;
+-	new->size = varsz;
+-	new->next = vars;
+-	vars = new;
+-
+-	return 0;
+-}
+-
+-void nvram_exit(void)
+-{
+-	vars_t *this, *next;
+-
+-	this = vars;
+-	if (this)
+-		kfree(this->vars);
+-
+-	while (this) {
+-		next = this->next;
+-		kfree(this);
+-		this = next;
+-	}
+-	vars = NULL;
+-}
+-
+-static char *findvar(char *vars, char *lim, const char *name)
+-{
+-	char *s;
+-	int len;
+-
+-	len = strlen(name);
+-
+-	for (s = vars; (s < lim) && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-
+-	return NULL;
+-}
+-
+-/*
+- * Search the name=value vars for a specific one and return its value.
+- * Returns NULL if not found.
+- */
+-char *getvar(char *vars, const char *name)
+-{
+-	char *s;
+-	int len;
+-
+-	if (!name)
+-		return NULL;
+-
+-	len = strlen(name);
+-	if (len == 0)
+-		return NULL;
+-
+-	/* first look in vars[] */
+-	for (s = vars; s && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-	/* then query nvram */
+-	return nvram_get(name);
+-}
+-
+-/*
+- * Search the vars for a specific one and return its value as
+- * an integer. Returns 0 if not found.
+- */
+-int getintvar(char *vars, const char *name)
+-{
+-	char *val;
+-
+-	val = getvar(vars, name);
+-	if (val == NULL)
+-		return 0;
+-
+-	return simple_strtoul(val, NULL, 0);
+-}
+-
+-char *nvram_get(const char *name)
+-{
+-	char *v = NULL;
+-	vars_t *cur;
+-
+-	for (cur = vars; cur; cur = cur->next) {
+-		v = findvar(cur->vars, cur->vars + cur->size, name);
+-		if (v)
+-			break;
+-	}
+-
+-	return v;
+-}
+-
+-int nvram_set(const char *name, const char *value)
+-{
+-	return 0;
+-}
+-
+-int nvram_unset(const char *name)
+-{
+-	return 0;
+-}
+-
+-int nvram_reset(void)
+-{
+-	return 0;
+-}
+-
+-int nvram_commit(void)
+-{
+-	return 0;
+-}
+-
+-int nvram_getall(char *buf, int count)
+-{
+-	int len, resid = count;
+-	vars_t *this;
+-
+-	this = vars;
+-	while (this) {
+-		char *from, *lim, *to;
+-		int acc;
+-
+-		from = this->vars;
+-		lim = (char *)(this->vars + this->size);
+-		to = buf;
+-		acc = 0;
+-		while ((from < lim) && (*from)) {
+-			len = strlen(from) + 1;
+-			if (resid < (acc + len))
+-				return -EOVERFLOW;
+-			memcpy(to, from, len);
+-			acc += len;
+-			from += len;
+-			to += len;
+-		}
+-
+-		resid -= acc;
+-		buf += acc;
+-		this = this->next;
+-	}
+-	if (resid < 1)
+-		return -EOVERFLOW;
+-	*buf = '\0';
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
+deleted file mode 100644
+index 51a2238..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
++++ /dev/null
+@@ -1,36 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef phy_version_h_
+-#define phy_version_h_
+-
+-#define	PHY_MAJOR_VERSION		1
+-
+-#define	PHY_MINOR_VERSION		82
+-
+-#define	PHY_RC_NUMBER		8
+-
+-#define	PHY_INCREMENTAL_NUMBER	0
+-
+-#define	PHY_BUILD_NUMBER		0
+-
+-#define	PHY_VERSION			{ 1, 82, 8, 0 }
+-
+-#define	PHY_VERSION_NUM		0x01520800
+-
+-#define	PHY_VERSION_STR		"1.82.8.0"
+-
+-#endif				/* phy_version_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
+deleted file mode 100644
+index 6cba4df..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
++++ /dev/null
+@@ -1,3307 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <wlc_cfg.h>
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/bitops.h>
+-#include <linux/delay.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmnvram.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include <wlc_phy_int.h>
+-#include <wlc_phyreg_n.h>
+-#include <wlc_phy_radio.h>
+-#include <wlc_phy_lcn.h>
+-
+-u32 phyhal_msg_level = PHYHAL_ERROR;
+-
+-typedef struct _chan_info_basic {
+-	u16 chan;
+-	u16 freq;
+-} chan_info_basic_t;
+-
+-static chan_info_basic_t chan_info_all[] = {
+-
+-	{1, 2412},
+-	{2, 2417},
+-	{3, 2422},
+-	{4, 2427},
+-	{5, 2432},
+-	{6, 2437},
+-	{7, 2442},
+-	{8, 2447},
+-	{9, 2452},
+-	{10, 2457},
+-	{11, 2462},
+-	{12, 2467},
+-	{13, 2472},
+-	{14, 2484},
+-
+-	{34, 5170},
+-	{38, 5190},
+-	{42, 5210},
+-	{46, 5230},
+-
+-	{36, 5180},
+-	{40, 5200},
+-	{44, 5220},
+-	{48, 5240},
+-	{52, 5260},
+-	{56, 5280},
+-	{60, 5300},
+-	{64, 5320},
+-
+-	{100, 5500},
+-	{104, 5520},
+-	{108, 5540},
+-	{112, 5560},
+-	{116, 5580},
+-	{120, 5600},
+-	{124, 5620},
+-	{128, 5640},
+-	{132, 5660},
+-	{136, 5680},
+-	{140, 5700},
+-
+-	{149, 5745},
+-	{153, 5765},
+-	{157, 5785},
+-	{161, 5805},
+-	{165, 5825},
+-
+-	{184, 4920},
+-	{188, 4940},
+-	{192, 4960},
+-	{196, 4980},
+-	{200, 5000},
+-	{204, 5020},
+-	{208, 5040},
+-	{212, 5060},
+-	{216, 50800}
+-};
+-
+-u16 ltrn_list[PHY_LTRN_LIST_LEN] = {
+-	0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc,
+-	0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010,
+-	0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc,
+-	0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318,
+-	0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312,
+-	0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc,
+-	0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01,
+-	0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff,
+-	0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec,
+-	0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814,
+-	0x0507, 0x0fea, 0xe4f2, 0xf6e6
+-};
+-
+-const u8 ofdm_rate_lookup[] = {
+-
+-	WLC_RATE_48M,
+-	WLC_RATE_24M,
+-	WLC_RATE_12M,
+-	WLC_RATE_6M,
+-	WLC_RATE_54M,
+-	WLC_RATE_36M,
+-	WLC_RATE_18M,
+-	WLC_RATE_9M
+-};
+-
+-#define PHY_WREG_LIMIT	24
+-
+-static void wlc_set_phy_uninitted(phy_info_t *pi);
+-static u32 wlc_phy_get_radio_ver(phy_info_t *pi);
+-static void wlc_phy_timercb_phycal(void *arg);
+-
+-static bool wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr,
+-				   s8 *pwr_ant);
+-
+-static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay);
+-static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm);
+-static void wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason,
+-					 u8 ch);
+-
+-static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi,
+-					   struct txpwr_limits *tp, chanspec_t);
+-static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi);
+-
+-static s8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan,
+-					     u32 band, u8 rate);
+-static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band);
+-static s8 wlc_phy_env_measure_vbat(phy_info_t *pi);
+-static s8 wlc_phy_env_measure_temperature(phy_info_t *pi);
+-
+-char *phy_getvar(phy_info_t *pi, const char *name)
+-{
+-	char *vars = pi->vars;
+-	char *s;
+-	int len;
+-
+-	if (!name)
+-		return NULL;
+-
+-	len = strlen(name);
+-	if (len == 0)
+-		return NULL;
+-
+-	for (s = vars; s && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-
+-	return nvram_get(name);
+-}
+-
+-int phy_getintvar(phy_info_t *pi, const char *name)
+-{
+-	char *val;
+-
+-	val = PHY_GETVAR(pi, name);
+-	if (val == NULL)
+-		return 0;
+-
+-	return simple_strtoul(val, NULL, 0);
+-}
+-
+-void wlc_phyreg_enter(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
+-}
+-
+-void wlc_phyreg_exit(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
+-}
+-
+-void wlc_radioreg_enter(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
+-
+-	udelay(10);
+-}
+-
+-void wlc_radioreg_exit(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	volatile u16 dummy;
+-
+-	dummy = R_REG(&pi->regs->phyversion);
+-	pi->phy_wreg = 0;
+-	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
+-}
+-
+-u16 read_radio_reg(phy_info_t *pi, u16 addr)
+-{
+-	u16 data;
+-
+-	if ((addr == RADIO_IDCODE))
+-		return 0xffff;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return NORADIO_IDCODE & 0xffff;
+-
+-	switch (pi->pubpi.phy_type) {
+-	case PHY_TYPE_N:
+-		CASECHECK(PHYTYPE, PHY_TYPE_N);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7))
+-			addr |= RADIO_2057_READ_OFF;
+-		else
+-			addr |= RADIO_2055_READ_OFF;
+-		break;
+-
+-	case PHY_TYPE_LCN:
+-		CASECHECK(PHYTYPE, PHY_TYPE_LCN);
+-		addr |= RADIO_2064_READ_OFF;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	if ((D11REV_GE(pi->sh->corerev, 24)) ||
+-	    (D11REV_IS(pi->sh->corerev, 22)
+-	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+-		W_REG(&pi->regs->radioregaddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		data = R_REG(&pi->regs->radioregdata);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-
+-#ifdef __ARM_ARCH_4T__
+-		__asm__(" .align 4 ");
+-		__asm__(" nop ");
+-		data = R_REG(&pi->regs->phy4wdatalo);
+-#else
+-		data = R_REG(&pi->regs->phy4wdatalo);
+-#endif
+-
+-	}
+-	pi->phy_wreg = 0;
+-
+-	return data;
+-}
+-
+-void write_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if ((D11REV_GE(pi->sh->corerev, 24)) ||
+-	    (D11REV_IS(pi->sh->corerev, 22)
+-	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+-
+-		W_REG(&pi->regs->radioregaddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		W_REG(&pi->regs->radioregdata, val);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-		W_REG(&pi->regs->phy4wdatalo, val);
+-	}
+-
+-	if (pi->sh->bustype == PCI_BUS) {
+-		if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+-			(void)R_REG(&pi->regs->maccontrol);
+-			pi->phy_wreg = 0;
+-		}
+-	}
+-}
+-
+-static u32 read_radio_id(phy_info_t *pi)
+-{
+-	u32 id;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return NORADIO_IDCODE;
+-
+-	if (D11REV_GE(pi->sh->corerev, 24)) {
+-		u32 b0, b1, b2;
+-
+-		W_REG(&pi->regs->radioregaddr, 0);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b0 = (u32) R_REG(&pi->regs->radioregdata);
+-		W_REG(&pi->regs->radioregaddr, 1);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b1 = (u32) R_REG(&pi->regs->radioregdata);
+-		W_REG(&pi->regs->radioregaddr, 2);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b2 = (u32) R_REG(&pi->regs->radioregdata);
+-
+-		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
+-								      & 0xf);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, RADIO_IDCODE);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-		id = (u32) R_REG(&pi->regs->phy4wdatalo);
+-		id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16;
+-	}
+-	pi->phy_wreg = 0;
+-	return id;
+-}
+-
+-void and_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval & val));
+-}
+-
+-void or_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval | val));
+-}
+-
+-void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval ^ mask));
+-}
+-
+-void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
+-}
+-
+-void write_phy_channel_reg(phy_info_t *pi, uint val)
+-{
+-	W_REG(&pi->regs->phychannel, val);
+-}
+-
+-u16 read_phy_reg(phy_info_t *pi, u16 addr)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	pi->phy_wreg = 0;
+-	return R_REG(&regs->phyregdata);
+-}
+-
+-void write_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-#ifdef __mips__
+-	W_REG(&regs->phyregaddr, addr);
+-	(void)R_REG(&regs->phyregaddr);
+-	W_REG(&regs->phyregdata, val);
+-	if (addr == 0x72)
+-		(void)R_REG(&regs->phyregdata);
+-#else
+-	W_REG((u32 *)(&regs->phyregaddr),
+-	      addr | (val << 16));
+-	if (pi->sh->bustype == PCI_BUS) {
+-		if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+-			pi->phy_wreg = 0;
+-			(void)R_REG(&regs->phyversion);
+-		}
+-	}
+-#endif
+-}
+-
+-void and_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) & val));
+-	pi->phy_wreg = 0;
+-}
+-
+-void or_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) | val));
+-	pi->phy_wreg = 0;
+-}
+-
+-void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata,
+-	      ((R_REG(&regs->phyregdata) & ~mask) | (val & mask)));
+-	pi->phy_wreg = 0;
+-}
+-
+-static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi)
+-{
+-	int i, j;
+-
+-	pi->initialized = false;
+-
+-	pi->tx_vos = 0xffff;
+-	pi->nrssi_table_delta = 0x7fffffff;
+-	pi->rc_cal = 0xffff;
+-	pi->mintxbias = 0xffff;
+-	pi->txpwridx = -1;
+-	if (ISNPHY(pi)) {
+-		pi->phy_spuravoid = SPURAVOID_DISABLE;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)
+-		    && NREV_LT(pi->pubpi.phy_rev, 7))
+-			pi->phy_spuravoid = SPURAVOID_AUTO;
+-
+-		pi->nphy_papd_skip = 0;
+-		pi->nphy_papd_epsilon_offset[0] = 0xf588;
+-		pi->nphy_papd_epsilon_offset[1] = 0xf588;
+-		pi->nphy_txpwr_idx[0] = 128;
+-		pi->nphy_txpwr_idx[1] = 128;
+-		pi->nphy_txpwrindex[0].index_internal = 40;
+-		pi->nphy_txpwrindex[1].index_internal = 40;
+-		pi->phy_pabias = 0;
+-	} else {
+-		pi->phy_spuravoid = SPURAVOID_AUTO;
+-	}
+-	pi->radiopwr = 0xffff;
+-	for (i = 0; i < STATIC_NUM_RF; i++) {
+-		for (j = 0; j < STATIC_NUM_BB; j++) {
+-			pi->stats_11b_txpower[i][j] = -1;
+-		}
+-	}
+-}
+-
+-shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp)
+-{
+-	shared_phy_t *sh;
+-
+-	sh = kzalloc(sizeof(shared_phy_t), GFP_ATOMIC);
+-	if (sh == NULL) {
+-		return NULL;
+-	}
+-
+-	sh->sih = shp->sih;
+-	sh->physhim = shp->physhim;
+-	sh->unit = shp->unit;
+-	sh->corerev = shp->corerev;
+-
+-	sh->vid = shp->vid;
+-	sh->did = shp->did;
+-	sh->chip = shp->chip;
+-	sh->chiprev = shp->chiprev;
+-	sh->chippkg = shp->chippkg;
+-	sh->sromrev = shp->sromrev;
+-	sh->boardtype = shp->boardtype;
+-	sh->boardrev = shp->boardrev;
+-	sh->boardvendor = shp->boardvendor;
+-	sh->boardflags = shp->boardflags;
+-	sh->boardflags2 = shp->boardflags2;
+-	sh->bustype = shp->bustype;
+-	sh->buscorerev = shp->buscorerev;
+-
+-	sh->fast_timer = PHY_SW_TIMER_FAST;
+-	sh->slow_timer = PHY_SW_TIMER_SLOW;
+-	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
+-
+-	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
+-
+-	return sh;
+-}
+-
+-void wlc_phy_shared_detach(shared_phy_t *phy_sh)
+-{
+-	if (phy_sh) {
+-		kfree(phy_sh);
+-	}
+-}
+-
+-wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+-			  char *vars, struct wiphy *wiphy)
+-{
+-	phy_info_t *pi;
+-	u32 sflags = 0;
+-	uint phyversion;
+-	int i;
+-
+-	if (D11REV_IS(sh->corerev, 4))
+-		sflags = SISF_2G_PHY | SISF_5G_PHY;
+-	else
+-		sflags = ai_core_sflags(sh->sih, 0, 0);
+-
+-	if (BAND_5G(bandtype)) {
+-		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) {
+-			return NULL;
+-		}
+-	}
+-
+-	pi = sh->phy_head;
+-	if ((sflags & SISF_DB_PHY) && pi) {
+-
+-		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+-		pi->refcnt++;
+-		return &pi->pubpi_ro;
+-	}
+-
+-	pi = kzalloc(sizeof(phy_info_t), GFP_ATOMIC);
+-	if (pi == NULL) {
+-		return NULL;
+-	}
+-	pi->wiphy = wiphy;
+-	pi->regs = (d11regs_t *) regs;
+-	pi->sh = sh;
+-	pi->phy_init_por = true;
+-	pi->phy_wreg_limit = PHY_WREG_LIMIT;
+-
+-	pi->vars = vars;
+-
+-	pi->txpwr_percent = 100;
+-
+-	pi->do_initcal = true;
+-
+-	pi->phycal_tempdelta = 0;
+-
+-	if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) {
+-
+-		pi->pubpi.coreflags = SICF_GMODE;
+-	}
+-
+-	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+-	phyversion = R_REG(&pi->regs->phyversion);
+-
+-	pi->pubpi.phy_type = PHY_TYPE(phyversion);
+-	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
+-
+-	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
+-		pi->pubpi.phy_type = PHY_TYPE_N;
+-		pi->pubpi.phy_rev += LCNXN_BASEREV;
+-	}
+-	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
+-	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
+-
+-	if (!VALID_PHYTYPE(pi->pubpi.phy_type)) {
+-		goto err;
+-	}
+-	if (BAND_5G(bandtype)) {
+-		if (!ISNPHY(pi)) {
+-			goto err;
+-		}
+-	} else {
+-		if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
+-			goto err;
+-		}
+-	}
+-
+-	if (ISSIM_ENAB(pi->sh->sih)) {
+-		pi->pubpi.radioid = NORADIO_ID;
+-		pi->pubpi.radiorev = 5;
+-	} else {
+-		u32 idcode;
+-
+-		wlc_phy_anacore((wlc_phy_t *) pi, ON);
+-
+-		idcode = wlc_phy_get_radio_ver(pi);
+-		pi->pubpi.radioid =
+-		    (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
+-		pi->pubpi.radiorev =
+-		    (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
+-		pi->pubpi.radiover =
+-		    (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
+-		if (!VALID_RADIO(pi, pi->pubpi.radioid)) {
+-			goto err;
+-		}
+-
+-		wlc_phy_switch_radio((wlc_phy_t *) pi, OFF);
+-	}
+-
+-	wlc_set_phy_uninitted(pi);
+-
+-	pi->bw = WL_CHANSPEC_BW_20;
+-	pi->radio_chanspec =
+-	    BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36);
+-
+-	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+-	pi->rxiq_antsel = ANT_RX_DIV_DEF;
+-
+-	pi->watchdog_override = true;
+-
+-	pi->cal_type_override = PHY_PERICAL_AUTO;
+-
+-	pi->nphy_saved_noisevars.bufcount = 0;
+-
+-	if (ISNPHY(pi))
+-		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
+-	else
+-		pi->min_txpower = PHY_TXPWR_MIN;
+-
+-	pi->sh->phyrxchain = 0x3;
+-
+-	pi->rx2tx_biasentry = -1;
+-
+-	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+-	pi->phy_txcore_enable_temp =
+-	    PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
+-	pi->phy_tempsense_offset = 0;
+-	pi->phy_txcore_heatedup = false;
+-
+-	pi->nphy_lastcal_temp = -50;
+-
+-	pi->phynoise_polling = true;
+-	if (ISNPHY(pi) || ISLCNPHY(pi))
+-		pi->phynoise_polling = false;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++) {
+-		pi->txpwr_limit[i] = WLC_TXPWR_MAX;
+-		pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+-		pi->tx_user_target[i] = WLC_TXPWR_MAX;
+-	}
+-
+-	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
+-
+-	pi->user_txpwr_at_rfport = false;
+-
+-	if (ISNPHY(pi)) {
+-
+-		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
+-							  wlc_phy_timercb_phycal,
+-							  pi, "phycal");
+-		if (!pi->phycal_timer) {
+-			goto err;
+-		}
+-
+-		if (!wlc_phy_attach_nphy(pi))
+-			goto err;
+-
+-	} else if (ISLCNPHY(pi)) {
+-		if (!wlc_phy_attach_lcnphy(pi))
+-			goto err;
+-
+-	} else {
+-
+-	}
+-
+-	pi->refcnt++;
+-	pi->next = pi->sh->phy_head;
+-	sh->phy_head = pi;
+-
+-	pi->vars = (char *)&pi->vars;
+-
+-	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(wlc_phy_t));
+-
+-	return &pi->pubpi_ro;
+-
+- err:
+-	kfree(pi);
+-	return NULL;
+-}
+-
+-void wlc_phy_detach(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (pih) {
+-		if (--pi->refcnt) {
+-			return;
+-		}
+-
+-		if (pi->phycal_timer) {
+-			wlapi_free_timer(pi->sh->physhim, pi->phycal_timer);
+-			pi->phycal_timer = NULL;
+-		}
+-
+-		if (pi->sh->phy_head == pi)
+-			pi->sh->phy_head = pi->next;
+-		else if (pi->sh->phy_head->next == pi)
+-			pi->sh->phy_head->next = NULL;
+-
+-		if (pi->pi_fptr.detach)
+-			(pi->pi_fptr.detach) (pi);
+-
+-		kfree(pi);
+-	}
+-}
+-
+-bool
+-wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev,
+-		       u16 *radioid, u16 *radiover)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	*phytype = (u16) pi->pubpi.phy_type;
+-	*phyrev = (u16) pi->pubpi.phy_rev;
+-	*radioid = pi->pubpi.radioid;
+-	*radiover = pi->pubpi.radiorev;
+-
+-	return true;
+-}
+-
+-bool wlc_phy_get_encore(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	return pi->pubpi.abgphy_encore;
+-}
+-
+-u32 wlc_phy_get_coreflags(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	return pi->pubpi.coreflags;
+-}
+-
+-static void wlc_phy_timercb_phycal(void *arg)
+-{
+-	phy_info_t *pi = (phy_info_t *) arg;
+-	uint delay = 5;
+-
+-	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-		if (!pi->sh->up) {
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			return;
+-		}
+-
+-		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
+-
+-			delay = 1000;
+-			wlc_phy_cal_perical_mphase_restart(pi);
+-		} else
+-			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
+-		wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+-		return;
+-	}
+-
+-}
+-
+-void wlc_phy_anacore(wlc_phy_t *pih, bool on)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (ISNPHY(pi)) {
+-		if (on) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				write_phy_reg(pi, 0xa6, 0x0d);
+-				write_phy_reg(pi, 0x8f, 0x0);
+-				write_phy_reg(pi, 0xa7, 0x0d);
+-				write_phy_reg(pi, 0xa5, 0x0);
+-			} else {
+-				write_phy_reg(pi, 0xa5, 0x0);
+-			}
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				write_phy_reg(pi, 0x8f, 0x07ff);
+-				write_phy_reg(pi, 0xa6, 0x0fd);
+-				write_phy_reg(pi, 0xa5, 0x07ff);
+-				write_phy_reg(pi, 0xa7, 0x0fd);
+-			} else {
+-				write_phy_reg(pi, 0xa5, 0x7fff);
+-			}
+-		}
+-	} else if (ISLCNPHY(pi)) {
+-		if (on) {
+-			and_phy_reg(pi, 0x43b,
+-				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-		} else {
+-			or_phy_reg(pi, 0x43c,
+-				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-			or_phy_reg(pi, 0x43b,
+-				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-		}
+-	}
+-}
+-
+-u32 wlc_phy_clk_bwbits(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	u32 phy_bw_clkbits = 0;
+-
+-	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
+-		switch (pi->bw) {
+-		case WL_CHANSPEC_BW_10:
+-			phy_bw_clkbits = SICF_BW10;
+-			break;
+-		case WL_CHANSPEC_BW_20:
+-			phy_bw_clkbits = SICF_BW20;
+-			break;
+-		case WL_CHANSPEC_BW_40:
+-			phy_bw_clkbits = SICF_BW40;
+-			break;
+-		default:
+-			break;
+-		}
+-	}
+-
+-	return phy_bw_clkbits;
+-}
+-
+-void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->phy_init_por = true;
+-}
+-
+-void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->edcrs_threshold_lock = lock;
+-
+-	write_phy_reg(pi, 0x22c, 0x46b);
+-	write_phy_reg(pi, 0x22d, 0x46b);
+-	write_phy_reg(pi, 0x22e, 0x3c0);
+-	write_phy_reg(pi, 0x22f, 0x3c0);
+-}
+-
+-void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->do_initcal = initcal;
+-}
+-
+-void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!pi || !pi->sh)
+-		return;
+-
+-	pi->sh->clk = newstate;
+-}
+-
+-void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!pi || !pi->sh)
+-		return;
+-
+-	pi->sh->up = newstate;
+-}
+-
+-void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec)
+-{
+-	u32 mc;
+-	initfn_t phy_init = NULL;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (pi->init_in_progress)
+-		return;
+-
+-	pi->init_in_progress = true;
+-
+-	pi->radio_chanspec = chanspec;
+-
+-	mc = R_REG(&pi->regs->maccontrol);
+-	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
+-		return;
+-
+-	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+-		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+-	}
+-
+-	if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
+-		 "HW error SISF_FCLKA\n"))
+-		return;
+-
+-	phy_init = pi->pi_fptr.init;
+-
+-	if (phy_init == NULL) {
+-		return;
+-	}
+-
+-	wlc_phy_anacore(pih, ON);
+-
+-	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
+-		wlapi_bmac_bw_set(pi->sh->physhim,
+-				  CHSPEC_BW(pi->radio_chanspec));
+-
+-	pi->nphy_gain_boost = true;
+-
+-	wlc_phy_switch_radio((wlc_phy_t *) pi, ON);
+-
+-	(*phy_init) (pi);
+-
+-	pi->phy_init_por = false;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlc_phy_do_dummy_tx(pi, true, OFF);
+-
+-	if (!(ISNPHY(pi)))
+-		wlc_phy_txpower_update_shm(pi);
+-
+-	wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv);
+-
+-	pi->init_in_progress = false;
+-}
+-
+-void wlc_phy_cal_init(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	initfn_t cal_init = NULL;
+-
+-	if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
+-		 "HW error: MAC enabled during phy cal\n"))
+-		return;
+-
+-	if (!pi->initialized) {
+-		cal_init = pi->pi_fptr.calinit;
+-		if (cal_init)
+-			(*cal_init) (pi);
+-
+-		pi->initialized = true;
+-	}
+-}
+-
+-int wlc_phy_down(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	int callbacks = 0;
+-
+-	if (pi->phycal_timer
+-	    && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
+-		callbacks++;
+-
+-	pi->nphy_iqcal_chanspec_2G = 0;
+-	pi->nphy_iqcal_chanspec_5G = 0;
+-
+-	return callbacks;
+-}
+-
+-static u32 wlc_phy_get_radio_ver(phy_info_t *pi)
+-{
+-	u32 ver;
+-
+-	ver = read_radio_id(pi);
+-
+-	return ver;
+-}
+-
+-void
+-wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+-		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	pi->tbl_data_hi = tblDataHi;
+-	pi->tbl_data_lo = tblDataLo;
+-
+-	if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-	     pi->sh->chip == BCM43421_CHIP_ID) &&
+-	    (pi->sh->chiprev == 1)) {
+-		pi->tbl_addr = tblAddr;
+-		pi->tbl_save_id = tbl_id;
+-		pi->tbl_save_offset = tbl_offset;
+-	}
+-}
+-
+-void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val)
+-{
+-	if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-	     pi->sh->chip == BCM43421_CHIP_ID) &&
+-	    (pi->sh->chiprev == 1) &&
+-	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+-		read_phy_reg(pi, pi->tbl_data_lo);
+-
+-		write_phy_reg(pi, pi->tbl_addr,
+-			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
+-		pi->tbl_save_offset++;
+-	}
+-
+-	if (width == 32) {
+-
+-		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
+-		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
+-	} else {
+-
+-		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
+-	}
+-}
+-
+-void
+-wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	uint idx;
+-	uint tbl_id = ptbl_info->tbl_id;
+-	uint tbl_offset = ptbl_info->tbl_offset;
+-	uint tbl_width = ptbl_info->tbl_width;
+-	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
+-	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
+-	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
+-
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-		     pi->sh->chip == BCM43421_CHIP_ID) &&
+-		    (pi->sh->chiprev == 1) &&
+-		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+-			read_phy_reg(pi, tblDataLo);
+-
+-			write_phy_reg(pi, tblAddr,
+-				      (tbl_id << 10) | (tbl_offset + idx));
+-		}
+-
+-		if (tbl_width == 32) {
+-
+-			write_phy_reg(pi, tblDataHi,
+-				      (u16) (ptbl_32b[idx] >> 16));
+-			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
+-		} else if (tbl_width == 16) {
+-
+-			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
+-		} else {
+-
+-			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
+-		}
+-	}
+-}
+-
+-void
+-wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	uint idx;
+-	uint tbl_id = ptbl_info->tbl_id;
+-	uint tbl_offset = ptbl_info->tbl_offset;
+-	uint tbl_width = ptbl_info->tbl_width;
+-	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
+-	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
+-	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
+-
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-		     pi->sh->chip == BCM43421_CHIP_ID) &&
+-		    (pi->sh->chiprev == 1)) {
+-			(void)read_phy_reg(pi, tblDataLo);
+-
+-			write_phy_reg(pi, tblAddr,
+-				      (tbl_id << 10) | (tbl_offset + idx));
+-		}
+-
+-		if (tbl_width == 32) {
+-
+-			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
+-			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
+-		} else if (tbl_width == 16) {
+-
+-			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
+-		} else {
+-
+-			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
+-		}
+-	}
+-}
+-
+-uint
+-wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs)
+-{
+-	uint i = 0;
+-
+-	do {
+-		if (radioregs[i].do_init) {
+-			write_radio_reg(pi, radioregs[i].address,
+-					(u16) radioregs[i].init);
+-		}
+-
+-		i++;
+-	} while (radioregs[i].address != 0xffff);
+-
+-	return i;
+-}
+-
+-uint
+-wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+-			u16 core_offset)
+-{
+-	uint i = 0;
+-	uint count = 0;
+-
+-	do {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			if (radioregs[i].do_init_a) {
+-				write_radio_reg(pi,
+-						radioregs[i].
+-						address | core_offset,
+-						(u16) radioregs[i].init_a);
+-				if (ISNPHY(pi) && (++count % 4 == 0))
+-					WLC_PHY_WAR_PR51571(pi);
+-			}
+-		} else {
+-			if (radioregs[i].do_init_g) {
+-				write_radio_reg(pi,
+-						radioregs[i].
+-						address | core_offset,
+-						(u16) radioregs[i].init_g);
+-				if (ISNPHY(pi) && (++count % 4 == 0))
+-					WLC_PHY_WAR_PR51571(pi);
+-			}
+-		}
+-
+-		i++;
+-	} while (radioregs[i].address != 0xffff);
+-
+-	return i;
+-}
+-
+-void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on)
+-{
+-#define	DUMMY_PKT_LEN	20
+-	d11regs_t *regs = pi->regs;
+-	int i, count;
+-	u8 ofdmpkt[DUMMY_PKT_LEN] = {
+-		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+-		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+-	};
+-	u8 cckpkt[DUMMY_PKT_LEN] = {
+-		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+-		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+-	};
+-	u32 *dummypkt;
+-
+-	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
+-	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
+-				      dummypkt);
+-
+-	W_REG(&regs->xmtsel, 0);
+-
+-	if (D11REV_GE(pi->sh->corerev, 11))
+-		W_REG(&regs->wepctl, 0x100);
+-	else
+-		W_REG(&regs->wepctl, 0);
+-
+-	W_REG(&regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
+-	if (ISNPHY(pi) || ISLCNPHY(pi)) {
+-		W_REG(&regs->txe_phyctl1, 0x1A02);
+-	}
+-
+-	W_REG(&regs->txe_wm_0, 0);
+-	W_REG(&regs->txe_wm_1, 0);
+-
+-	W_REG(&regs->xmttplatetxptr, 0);
+-	W_REG(&regs->xmttxcnt, DUMMY_PKT_LEN);
+-
+-	W_REG(&regs->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
+-
+-	W_REG(&regs->txe_ctl, 0);
+-
+-	if (!pa_on) {
+-		if (ISNPHY(pi))
+-			wlc_phy_pa_override_nphy(pi, OFF);
+-	}
+-
+-	if (ISNPHY(pi) || ISLCNPHY(pi))
+-		W_REG(&regs->txe_aux, 0xD0);
+-	else
+-		W_REG(&regs->txe_aux, ((1 << 5) | (1 << 4)));
+-
+-	(void)R_REG(&regs->txe_aux);
+-
+-	i = 0;
+-	count = ofdm ? 30 : 250;
+-
+-	if (ISSIM_ENAB(pi->sh->sih)) {
+-		count *= 100;
+-	}
+-
+-	while ((i++ < count)
+-	       && (R_REG(&regs->txe_status) & (1 << 7))) {
+-		udelay(10);
+-	}
+-
+-	i = 0;
+-
+-	while ((i++ < 10)
+-	       && ((R_REG(&regs->txe_status) & (1 << 10)) == 0)) {
+-		udelay(10);
+-	}
+-
+-	i = 0;
+-
+-	while ((i++ < 10) && ((R_REG(&regs->ifsstat) & (1 << 8))))
+-		udelay(10);
+-
+-	if (!pa_on) {
+-		if (ISNPHY(pi))
+-			wlc_phy_pa_override_nphy(pi, ON);
+-	}
+-}
+-
+-void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (set) {
+-		mboolset(pi->measure_hold, id);
+-	} else {
+-		mboolclr(pi->measure_hold, id);
+-	}
+-
+-	return;
+-}
+-
+-void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (mute) {
+-		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+-	} else {
+-		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+-	}
+-
+-	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
+-		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
+-	return;
+-}
+-
+-void wlc_phy_clear_tssi(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (ISNPHY(pi)) {
+-		return;
+-	} else {
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
+-	}
+-}
+-
+-static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi)
+-{
+-	return false;
+-}
+-
+-void wlc_phy_switch_radio(wlc_phy_t *pih, bool on)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	{
+-		uint mc;
+-
+-		mc = R_REG(&pi->regs->maccontrol);
+-	}
+-
+-	if (ISNPHY(pi)) {
+-		wlc_phy_switch_radio_nphy(pi, on);
+-
+-	} else if (ISLCNPHY(pi)) {
+-		if (on) {
+-			and_phy_reg(pi, 0x44c,
+-				    ~((0x1 << 8) |
+-				      (0x1 << 9) |
+-				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
+-			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
+-			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
+-		} else {
+-			and_phy_reg(pi, 0x44d,
+-				    ~((0x1 << 10) |
+-				      (0x1 << 11) |
+-				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
+-			or_phy_reg(pi, 0x44c,
+-				   (0x1 << 8) |
+-				   (0x1 << 9) |
+-				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
+-
+-			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
+-			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
+-			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
+-			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
+-			or_phy_reg(pi, 0x4f9, (0x1 << 3));
+-		}
+-	}
+-}
+-
+-u16 wlc_phy_bw_state_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->bw;
+-}
+-
+-void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->bw = bw;
+-}
+-
+-void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	pi->radio_chanspec = newch;
+-
+-}
+-
+-chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->radio_chanspec;
+-}
+-
+-void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 m_cur_channel;
+-	chansetfn_t chanspec_set = NULL;
+-
+-	m_cur_channel = CHSPEC_CHANNEL(chanspec);
+-	if (CHSPEC_IS5G(chanspec))
+-		m_cur_channel |= D11_CURCHANNEL_5G;
+-	if (CHSPEC_IS40(chanspec))
+-		m_cur_channel |= D11_CURCHANNEL_40;
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
+-
+-	chanspec_set = pi->pi_fptr.chanset;
+-	if (chanspec_set)
+-		(*chanspec_set) (pi, chanspec);
+-
+-}
+-
+-int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
+-{
+-	int range = -1;
+-
+-	if (freq < 2500)
+-		range = WL_CHAN_FREQ_RANGE_2G;
+-	else if (freq <= 5320)
+-		range = WL_CHAN_FREQ_RANGE_5GL;
+-	else if (freq <= 5700)
+-		range = WL_CHAN_FREQ_RANGE_5GM;
+-	else
+-		range = WL_CHAN_FREQ_RANGE_5GH;
+-
+-	return range;
+-}
+-
+-int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	int range = -1;
+-	uint channel = CHSPEC_CHANNEL(chanspec);
+-	uint freq = wlc_phy_channel2freq(channel);
+-
+-	if (ISNPHY(pi)) {
+-		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
+-	} else if (ISLCNPHY(pi)) {
+-		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
+-	}
+-
+-	return range;
+-}
+-
+-void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->channel_14_wide_filter = wide_filter;
+-
+-}
+-
+-int wlc_phy_channel2freq(uint channel)
+-{
+-	uint i;
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
+-		if (chan_info_all[i].chan == channel)
+-			return chan_info_all[i].freq;
+-	return 0;
+-}
+-
+-void
+-wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-	uint channel;
+-
+-	memset(channels, 0, sizeof(chanvec_t));
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-		channel = chan_info_all[i].chan;
+-
+-		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+-		    && (channel <= LAST_REF5_CHANNUM))
+-			continue;
+-
+-		if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+-		    ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+-			setbit(channels->vec, channel);
+-	}
+-}
+-
+-chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-	uint channel;
+-	chanspec_t chspec;
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-		channel = chan_info_all[i].chan;
+-
+-		if (ISNPHY(pi) && IS40MHZ(pi)) {
+-			uint j;
+-
+-			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
+-				if (chan_info_all[j].chan ==
+-				    channel + CH_10MHZ_APART)
+-					break;
+-			}
+-
+-			if (j == ARRAY_SIZE(chan_info_all))
+-				continue;
+-
+-			channel = UPPER_20_SB(channel);
+-			chspec =
+-			    channel | WL_CHANSPEC_BW_40 |
+-			    WL_CHANSPEC_CTL_SB_LOWER;
+-			if (band == WLC_BAND_2G)
+-				chspec |= WL_CHANSPEC_BAND_2G;
+-			else
+-				chspec |= WL_CHANSPEC_BAND_5G;
+-		} else
+-			chspec = CH20MHZ_CHSPEC(channel);
+-
+-		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+-		    && (channel <= LAST_REF5_CHANNUM))
+-			continue;
+-
+-		if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+-		    ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+-			return chspec;
+-	}
+-
+-	return (chanspec_t) INVCHANSPEC;
+-}
+-
+-int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	*qdbm = pi->tx_user_target[0];
+-	if (override != NULL)
+-		*override = pi->txpwroverride;
+-	return 0;
+-}
+-
+-void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr)
+-{
+-	bool mac_enabled = false;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
+-	       &txpwr->cck[0], WLC_NUM_RATES_CCK);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
+-	       &txpwr->ofdm[0], WLC_NUM_RATES_OFDM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
+-	       &txpwr->ofdm_cdd[0], WLC_NUM_RATES_OFDM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
+-	       &txpwr->ofdm_40_siso[0], WLC_NUM_RATES_OFDM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
+-	       &txpwr->ofdm_40_cdd[0], WLC_NUM_RATES_OFDM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
+-	       &txpwr->mcs_20_siso[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
+-	       &txpwr->mcs_20_cdd[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
+-	       &txpwr->mcs_20_stbc[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
+-	       &txpwr->mcs_20_mimo[0], WLC_NUM_RATES_MCS_2_STREAM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
+-	       &txpwr->mcs_40_siso[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
+-	       &txpwr->mcs_40_cdd[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
+-	       &txpwr->mcs_40_stbc[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
+-	       &txpwr->mcs_40_mimo[0], WLC_NUM_RATES_MCS_2_STREAM);
+-
+-	if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)
+-		mac_enabled = true;
+-
+-	if (mac_enabled)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phy_txpower_recalc_target(pi);
+-	wlc_phy_cal_txpower_recalc_sw(pi);
+-
+-	if (mac_enabled)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	int i;
+-
+-	if (qdbm > 127)
+-		return 5;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++)
+-		pi->tx_user_target[i] = (u8) qdbm;
+-
+-	pi->txpwroverride = false;
+-
+-	if (pi->sh->up) {
+-		if (!SCAN_INPROG_PHY(pi)) {
+-			bool suspend;
+-
+-			suspend =
+-			    (0 ==
+-			     (R_REG(&pi->regs->maccontrol) &
+-			      MCTL_EN_MAC));
+-
+-			if (!suspend)
+-				wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-			wlc_phy_txpower_recalc_target(pi);
+-			wlc_phy_cal_txpower_recalc_sw(pi);
+-
+-			if (!suspend)
+-				wlapi_enable_mac(pi->sh->physhim);
+-		}
+-	}
+-	return 0;
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr,
+-			  u8 *max_pwr, int txp_rate_idx)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-
+-	*min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR;
+-
+-	if (ISNPHY(pi)) {
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_CCK;
+-		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
+-						   (u8) txp_rate_idx);
+-
+-	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_CCK;
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-	} else {
+-
+-		*max_pwr = WLC_TXPWR_MAX;
+-
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_OFDM;
+-
+-		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-			if (channel == chan_info_all[i].chan) {
+-				break;
+-			}
+-		}
+-
+-		if (pi->hwtxpwr) {
+-			*max_pwr = pi->hwtxpwr[i];
+-		} else {
+-
+-			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+-			if ((i >= FIRST_HIGH_5G_CHAN)
+-			    && (i <= LAST_HIGH_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+-			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+-		}
+-	}
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr,
+-				  u8 *min_txpwr)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u8 tx_pwr_max = 0;
+-	u8 tx_pwr_min = 255;
+-	u8 max_num_rate;
+-	u8 maxtxpwr, mintxpwr, rate, pactrl;
+-
+-	pactrl = 0;
+-
+-	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
+-	    ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1);
+-
+-	for (rate = 0; rate < max_num_rate; rate++) {
+-
+-		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
+-					  rate);
+-
+-		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+-
+-		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+-
+-		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
+-		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
+-	}
+-	*max_txpwr = tx_pwr_max;
+-	*min_txpwr = tx_pwr_min;
+-}
+-
+-void
+-wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, s32 *max_pwr,
+-				s32 *min_pwr, u32 *step_pwr)
+-{
+-	return;
+-}
+-
+-u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->tx_power_min;
+-}
+-
+-u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->tx_power_max;
+-}
+-
+-void wlc_phy_txpower_recalc_target(phy_info_t *pi)
+-{
+-	u8 maxtxpwr, mintxpwr, rate, pactrl;
+-	uint target_chan;
+-	u8 tx_pwr_target[TXP_NUM_RATES];
+-	u8 tx_pwr_max = 0;
+-	u8 tx_pwr_min = 255;
+-	u8 tx_pwr_max_rate_ind = 0;
+-	u8 max_num_rate;
+-	u8 start_rate = 0;
+-	chanspec_t chspec;
+-	u32 band = CHSPEC2WLC_BAND(pi->radio_chanspec);
+-	initfn_t txpwr_recalc_fn = NULL;
+-
+-	chspec = pi->radio_chanspec;
+-	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
+-		target_chan = CHSPEC_CHANNEL(chspec);
+-	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
+-		target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+-	else
+-		target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+-
+-	pactrl = 0;
+-	if (ISLCNPHY(pi)) {
+-		u32 offset_mcs, i;
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			offset_mcs = pi->mcs40_po;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i - 8] =
+-				    pi->tx_srom_max_2g -
+-				    ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		} else {
+-			offset_mcs = pi->mcs20_po;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i - 8] =
+-				    pi->tx_srom_max_2g -
+-				    ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		}
+-	}
+-#if WL11N
+-	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+-			((ISLCNPHY(pi)) ?
+-			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
+-#else
+-	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1));
+-#endif
+-
+-	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
+-
+-	for (rate = start_rate; rate < max_num_rate; rate++) {
+-
+-		tx_pwr_target[rate] = pi->tx_user_target[rate];
+-
+-		if (pi->user_txpwr_at_rfport) {
+-			tx_pwr_target[rate] +=
+-			    wlc_user_txpwr_antport_to_rfport(pi, target_chan,
+-							     band, rate);
+-		}
+-
+-		{
+-
+-			wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan,
+-						  &mintxpwr, &maxtxpwr, rate);
+-
+-			maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
+-
+-			maxtxpwr =
+-			    (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+-
+-			maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+-
+-			maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
+-
+-			if (pi->txpwr_percent <= 100)
+-				maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
+-
+-			tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
+-		}
+-
+-		tx_pwr_target[rate] =
+-		    min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
+-
+-		if (tx_pwr_target[rate] > tx_pwr_max)
+-			tx_pwr_max_rate_ind = rate;
+-
+-		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
+-		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
+-	}
+-
+-	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
+-	pi->tx_power_max = tx_pwr_max;
+-	pi->tx_power_min = tx_pwr_min;
+-	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
+-	for (rate = 0; rate < max_num_rate; rate++) {
+-
+-		pi->tx_power_target[rate] = tx_pwr_target[rate];
+-
+-		if (!pi->hwpwrctrl || ISNPHY(pi)) {
+-			pi->tx_power_offset[rate] =
+-			    pi->tx_power_max - pi->tx_power_target[rate];
+-		} else {
+-			pi->tx_power_offset[rate] =
+-			    pi->tx_power_target[rate] - pi->tx_power_min;
+-		}
+-	}
+-
+-	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
+-	if (txpwr_recalc_fn)
+-		(*txpwr_recalc_fn) (pi);
+-}
+-
+-void
+-wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr,
+-			       chanspec_t chanspec)
+-{
+-	u8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM];
+-	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
+-	int rate_start_index = 0, rate1, rate2, k;
+-
+-	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
+-	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
+-		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
+-
+-	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
+-	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
+-		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
+-
+-	if (ISNPHY(pi)) {
+-
+-		for (k = 0; k < 4; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				txpwr_ptr1 = txpwr->mcs_20_siso;
+-				txpwr_ptr2 = txpwr->ofdm;
+-				rate_start_index = WL_TX_POWER_OFDM_FIRST;
+-				break;
+-			case 1:
+-
+-				txpwr_ptr1 = txpwr->mcs_20_cdd;
+-				txpwr_ptr2 = txpwr->ofdm_cdd;
+-				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
+-				break;
+-			case 2:
+-
+-				txpwr_ptr1 = txpwr->mcs_40_siso;
+-				txpwr_ptr2 = txpwr->ofdm_40_siso;
+-				rate_start_index =
+-				    WL_TX_POWER_OFDM40_SISO_FIRST;
+-				break;
+-			case 3:
+-
+-				txpwr_ptr1 = txpwr->mcs_40_cdd;
+-				txpwr_ptr2 = txpwr->ofdm_40_cdd;
+-				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
+-				break;
+-			}
+-
+-			for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+-				tmp_txpwr_limit[rate2] = 0;
+-				tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+-				    txpwr_ptr1[rate2];
+-			}
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0,
+-							WLC_NUM_RATES_OFDM - 1,
+-							WLC_NUM_RATES_OFDM);
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++)
+-				pi->txpwr_limit[rate1] =
+-				    min(txpwr_ptr2[rate2],
+-					tmp_txpwr_limit[rate2]);
+-		}
+-
+-		for (k = 0; k < 4; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				txpwr_ptr1 = txpwr->ofdm;
+-				txpwr_ptr2 = txpwr->mcs_20_siso;
+-				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
+-				break;
+-			case 1:
+-
+-				txpwr_ptr1 = txpwr->ofdm_cdd;
+-				txpwr_ptr2 = txpwr->mcs_20_cdd;
+-				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
+-				break;
+-			case 2:
+-
+-				txpwr_ptr1 = txpwr->ofdm_40_siso;
+-				txpwr_ptr2 = txpwr->mcs_40_siso;
+-				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
+-				break;
+-			case 3:
+-
+-				txpwr_ptr1 = txpwr->ofdm_40_cdd;
+-				txpwr_ptr2 = txpwr->mcs_40_cdd;
+-				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
+-				break;
+-			}
+-			for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+-				tmp_txpwr_limit[rate2] = 0;
+-				tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+-				    txpwr_ptr1[rate2];
+-			}
+-			wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0,
+-							WLC_NUM_RATES_OFDM - 1,
+-							WLC_NUM_RATES_OFDM);
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] =
+-				    min(txpwr_ptr2[rate2],
+-					tmp_txpwr_limit[rate2]);
+-		}
+-
+-		for (k = 0; k < 2; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_20_stbc;
+-				break;
+-			case 1:
+-
+-				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_40_stbc;
+-				break;
+-			}
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+-		}
+-
+-		for (k = 0; k < 2; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_20_mimo;
+-				break;
+-			case 1:
+-
+-				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_40_mimo;
+-				break;
+-			}
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_2_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+-		}
+-
+-		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
+-
+-		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
+-		    min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
+-			pi->txpwr_limit[WL_TX_POWER_MCS_32]);
+-		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
+-		    pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
+-	}
+-}
+-
+-void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->txpwr_percent = txpwr_percent;
+-}
+-
+-void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->sh->machwcap = machwcap;
+-}
+-
+-void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 rxc;
+-	rxc = 0;
+-
+-	if (start_end == ON) {
+-		if (!ISNPHY(pi))
+-			return;
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)
+-		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			W_REG(&pi->regs->phyregaddr, 0xa0);
+-			(void)R_REG(&pi->regs->phyregaddr);
+-			rxc = R_REG(&pi->regs->phyregdata);
+-			W_REG(&pi->regs->phyregdata,
+-			      (0x1 << 15) | rxc);
+-		}
+-	} else {
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)
+-		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			W_REG(&pi->regs->phyregaddr, 0xa0);
+-			(void)R_REG(&pi->regs->phyregaddr);
+-			W_REG(&pi->regs->phyregdata, rxc);
+-		}
+-
+-		wlc_phy_por_inform(ppi);
+-	}
+-}
+-
+-void
+-wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr,
+-			  chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
+-
+-	if (ISLCNPHY(pi)) {
+-		int i, j;
+-		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
+-		     j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) {
+-			if (txpwr->mcs_20_siso[j])
+-				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
+-			else
+-				pi->txpwr_limit[i] = txpwr->ofdm[j];
+-		}
+-	}
+-
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phy_txpower_recalc_target(pi);
+-	wlc_phy_cal_txpower_recalc_sw(pi);
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->ofdm_rateset_war = war;
+-}
+-
+-void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->bf_preempt_4306 = bf_preempt;
+-}
+-
+-void wlc_phy_txpower_update_shm(phy_info_t *pi)
+-{
+-	int j;
+-	if (ISNPHY(pi)) {
+-		return;
+-	}
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	if (pi->hwpwrctrl) {
+-		u16 offset;
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
+-				     1 << NUM_TSSI_FRAMES);
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
+-				     pi->tx_power_min << NUM_TSSI_FRAMES);
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
+-				     pi->hwpwr_txcur);
+-
+-		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
+-			const u8 ucode_ofdm_rates[] = {
+-				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
+-			};
+-			offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim,
+-							    ucode_ofdm_rates[j -
+-									     TXP_FIRST_OFDM]);
+-			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
+-					     pi->tx_power_offset[j]);
+-			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
+-					     -(pi->tx_power_offset[j] / 2));
+-		}
+-
+-		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
+-			       MHF2_HWPWRCTL, WLC_BAND_ALL);
+-	} else {
+-		int i;
+-
+-		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
+-			pi->tx_power_offset[i] =
+-			    (u8) roundup(pi->tx_power_offset[i], 8);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
+-				     (u16) ((pi->
+-						tx_power_offset[TXP_FIRST_OFDM]
+-						+ 7) >> 3));
+-	}
+-}
+-
+-bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	if (ISNPHY(pi)) {
+-		return pi->nphy_txpwrctrl;
+-	} else {
+-		return pi->hwpwrctrl;
+-	}
+-}
+-
+-void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool cur_hwpwrctrl = pi->hwpwrctrl;
+-	bool suspend;
+-
+-	if (!pi->hwpwrctrl_capable) {
+-		return;
+-	}
+-
+-	pi->hwpwrctrl = hwpwrctrl;
+-	pi->nphy_txpwrctrl = hwpwrctrl;
+-	pi->txpwrctrl = hwpwrctrl;
+-
+-	if (ISNPHY(pi)) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+-		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-			wlc_phy_txpwr_fixpower_nphy(pi);
+-		} else {
+-
+-			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-				    pi->saved_txpwr_idx);
+-		}
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	} else if (hwpwrctrl != cur_hwpwrctrl) {
+-
+-		return;
+-	}
+-}
+-
+-void wlc_phy_txpower_ipa_upd(phy_info_t *pi)
+-{
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
+-		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
+-	} else {
+-		pi->ipa2g_on = false;
+-		pi->ipa5g_on = false;
+-	}
+-}
+-
+-static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi);
+-
+-static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi)
+-{
+-	s16 tx0_status, tx1_status;
+-	u16 estPower1, estPower2;
+-	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
+-	u32 est_pwr;
+-
+-	estPower1 = read_phy_reg(pi, 0x118);
+-	estPower2 = read_phy_reg(pi, 0x119);
+-
+-	if ((estPower1 & (0x1 << 8))
+-	    == (0x1 << 8)) {
+-		pwr0 = (u8) (estPower1 & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		pwr0 = 0x80;
+-	}
+-
+-	if ((estPower2 & (0x1 << 8))
+-	    == (0x1 << 8)) {
+-		pwr1 = (u8) (estPower2 & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		pwr1 = 0x80;
+-	}
+-
+-	tx0_status = read_phy_reg(pi, 0x1ed);
+-	tx1_status = read_phy_reg(pi, 0x1ee);
+-
+-	if ((tx0_status & (0x1 << 15))
+-	    == (0x1 << 15)) {
+-		adj_pwr0 = (u8) (tx0_status & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		adj_pwr0 = 0x80;
+-	}
+-	if ((tx1_status & (0x1 << 15))
+-	    == (0x1 << 15)) {
+-		adj_pwr1 = (u8) (tx1_status & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		adj_pwr1 = 0x80;
+-	}
+-
+-	est_pwr =
+-	    (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1);
+-	return est_pwr;
+-}
+-
+-void
+-wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint rate, num_rates;
+-	u8 min_pwr, max_pwr;
+-
+-#if WL_TX_POWER_RATES != TXP_NUM_RATES
+-#error "tx_power_t struct out of sync with this fn"
+-#endif
+-
+-	if (ISNPHY(pi)) {
+-		power->rf_cores = 2;
+-		power->flags |= (WL_TX_POWER_F_MIMO);
+-		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+-			power->flags |=
+-			    (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
+-	} else if (ISLCNPHY(pi)) {
+-		power->rf_cores = 1;
+-		power->flags |= (WL_TX_POWER_F_SISO);
+-		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
+-			power->flags |= WL_TX_POWER_F_ENABLED;
+-		if (pi->hwpwrctrl)
+-			power->flags |= WL_TX_POWER_F_HW;
+-	}
+-
+-	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+-		     ((ISLCNPHY(pi)) ?
+-		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
+-
+-	for (rate = 0; rate < num_rates; rate++) {
+-		power->user_limit[rate] = pi->tx_user_target[rate];
+-		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
+-					  rate);
+-		power->board_limit[rate] = (u8) max_pwr;
+-		power->target[rate] = pi->tx_power_target[rate];
+-	}
+-
+-	if (ISNPHY(pi)) {
+-		u32 est_pout;
+-
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_phyreg_enter((wlc_phy_t *) pi);
+-		est_pout = wlc_phy_txpower_est_power_nphy(pi);
+-		wlc_phyreg_exit((wlc_phy_t *) pi);
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-		power->est_Pout[0] = (est_pout >> 8) & 0xff;
+-		power->est_Pout[1] = est_pout & 0xff;
+-
+-		power->est_Pout_act[0] = est_pout >> 24;
+-		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
+-
+-		if (power->est_Pout[0] == 0x80)
+-			power->est_Pout[0] = 0;
+-		if (power->est_Pout[1] == 0x80)
+-			power->est_Pout[1] = 0;
+-
+-		if (power->est_Pout_act[0] == 0x80)
+-			power->est_Pout_act[0] = 0;
+-		if (power->est_Pout_act[1] == 0x80)
+-			power->est_Pout_act[1] = 0;
+-
+-		power->est_Pout_cck = 0;
+-
+-		power->tx_power_max[0] = pi->tx_power_max;
+-		power->tx_power_max[1] = pi->tx_power_max;
+-
+-		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
+-		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
+-	} else if (!pi->hwpwrctrl) {
+-	} else if (pi->sh->up) {
+-
+-		wlc_phyreg_enter(ppi);
+-		if (ISLCNPHY(pi)) {
+-
+-			power->tx_power_max[0] = pi->tx_power_max;
+-			power->tx_power_max[1] = pi->tx_power_max;
+-
+-			power->tx_power_max_rate_ind[0] =
+-			    pi->tx_power_max_rate_ind;
+-			power->tx_power_max_rate_ind[1] =
+-			    pi->tx_power_max_rate_ind;
+-
+-			if (wlc_phy_tpc_isenabled_lcnphy(pi))
+-				power->flags |=
+-				    (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+-			else
+-				power->flags &=
+-				    ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+-
+-			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
+-					    (s8 *) &power->est_Pout_cck);
+-		}
+-		wlc_phyreg_exit(ppi);
+-	}
+-}
+-
+-void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->antsel_type = antsel_type;
+-}
+-
+-bool wlc_phy_test_ison(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->phytest_on;
+-}
+-
+-bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool ret = true;
+-
+-	wlc_phyreg_enter(ppi);
+-
+-	if (ISNPHY(pi)) {
+-
+-		ret = false;
+-	} else if (ISLCNPHY(pi)) {
+-		u16 crsctrl = read_phy_reg(pi, 0x410);
+-		u16 div = crsctrl & (0x1 << 1);
+-		*pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1)));
+-	}
+-
+-	wlc_phyreg_exit(ppi);
+-
+-	return ret;
+-}
+-
+-void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool suspend;
+-
+-	pi->sh->rx_antdiv = val;
+-
+-	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
+-		if (val > ANT_RX_DIV_FORCE_1)
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
+-				       MHF1_ANTDIV, WLC_BAND_ALL);
+-		else
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
+-				       WLC_BAND_ALL);
+-	}
+-
+-	if (ISNPHY(pi)) {
+-
+-		return;
+-	}
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (ISLCNPHY(pi)) {
+-		if (val > ANT_RX_DIV_FORCE_1) {
+-			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
+-			mod_phy_reg(pi, 0x410,
+-				    (0x1 << 0),
+-				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
+-		} else {
+-			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
+-			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
+-		}
+-	}
+-
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-	return;
+-}
+-
+-static bool
+-wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant)
+-{
+-	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
+-	u8 i;
+-
+-	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
+-	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3))
+-			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
+-		else
+-
+-			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
+-	}
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
+-		pwr_ant[i] = cmplx_pwr_dbm[i];
+-	}
+-	pi->nphy_noise_index =
+-	    MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+-	return true;
+-}
+-
+-static void
+-wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-	bool sampling_in_progress = (pi->phynoise_state != 0);
+-	bool wait_for_intr = true;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		return;
+-	}
+-
+-	switch (reason) {
+-	case PHY_NOISE_SAMPLE_MON:
+-
+-		pi->phynoise_chan_watchdog = ch;
+-		pi->phynoise_state |= PHY_NOISE_STATE_MON;
+-
+-		break;
+-
+-	case PHY_NOISE_SAMPLE_EXTERNAL:
+-
+-		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	if (sampling_in_progress)
+-		return;
+-
+-	pi->phynoise_now = pi->sh->now;
+-
+-	if (pi->phy_fixed_noise) {
+-		if (ISNPHY(pi)) {
+-			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
+-			    PHY_NOISE_FIXED_VAL_NPHY;
+-			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
+-			    PHY_NOISE_FIXED_VAL_NPHY;
+-			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+-							   PHY_NOISE_WINDOW_SZ);
+-
+-			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-		} else {
+-
+-			noise_dbm = PHY_NOISE_FIXED_VAL;
+-		}
+-
+-		wait_for_intr = false;
+-		goto done;
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		if (!pi->phynoise_polling
+-		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+-
+-			OR_REG(&pi->regs->maccommand,
+-			       MCMD_BG_NOISE);
+-		} else {
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			wlc_lcnphy_deaf_mode(pi, (bool) 0);
+-			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
+-			wlc_lcnphy_deaf_mode(pi, (bool) 1);
+-			wlapi_enable_mac(pi->sh->physhim);
+-			wait_for_intr = false;
+-		}
+-	} else if (ISNPHY(pi)) {
+-		if (!pi->phynoise_polling
+-		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+-
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+-
+-			OR_REG(&pi->regs->maccommand,
+-			       MCMD_BG_NOISE);
+-		} else {
+-			phy_iq_est_t est[PHY_CORE_MAX];
+-			u32 cmplx_pwr[PHY_CORE_MAX];
+-			s8 noise_dbm_ant[PHY_CORE_MAX];
+-			u16 log_num_samps, num_samps, classif_state = 0;
+-			u8 wait_time = 32;
+-			u8 wait_crs = 0;
+-			u8 i;
+-
+-			memset((u8 *) est, 0, sizeof(est));
+-			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
+-			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
+-
+-			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+-			num_samps = 1 << log_num_samps;
+-
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-			wlc_phy_classifier_nphy(pi, 3, 0);
+-			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
+-					       wait_crs);
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-			wlapi_enable_mac(pi->sh->physhim);
+-
+-			for (i = 0; i < pi->pubpi.phy_corenum; i++)
+-				cmplx_pwr[i] =
+-				    (est[i].i_pwr +
+-				     est[i].q_pwr) >> log_num_samps;
+-
+-			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+-
+-			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-				pi->nphy_noise_win[i][pi->nphy_noise_index] =
+-				    noise_dbm_ant[i];
+-
+-				if (noise_dbm_ant[i] > noise_dbm)
+-					noise_dbm = noise_dbm_ant[i];
+-			}
+-			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+-							   PHY_NOISE_WINDOW_SZ);
+-
+-			wait_for_intr = false;
+-		}
+-	}
+-
+- done:
+-
+-	if (!wait_for_intr)
+-		wlc_phy_noise_cb(pi, ch, noise_dbm);
+-
+-}
+-
+-void wlc_phy_noise_sample_request_external(wlc_phy_t *pih)
+-{
+-	u8 channel;
+-
+-	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
+-
+-	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
+-}
+-
+-static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm)
+-{
+-	if (!pi->phynoise_state)
+-		return;
+-
+-	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
+-		if (pi->phynoise_chan_watchdog == channel) {
+-			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
+-			    noise_dbm;
+-			pi->sh->phy_noise_index =
+-			    MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
+-		}
+-		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
+-	}
+-
+-	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) {
+-		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
+-	}
+-
+-}
+-
+-static s8 wlc_phy_noise_read_shmem(phy_info_t *pi)
+-{
+-	u32 cmplx_pwr[PHY_CORE_MAX];
+-	s8 noise_dbm_ant[PHY_CORE_MAX];
+-	u16 lo, hi;
+-	u32 cmplx_pwr_tot = 0;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-	u8 idx, core;
+-
+-	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
+-	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
+-
+-	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) {
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim,
+-					 M_PWRIND_MAP(idx + 1));
+-		cmplx_pwr[core] = (hi << 16) + lo;
+-		cmplx_pwr_tot += cmplx_pwr[core];
+-		if (cmplx_pwr[core] == 0) {
+-			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
+-		} else
+-			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
+-	}
+-
+-	if (cmplx_pwr_tot != 0)
+-		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		pi->nphy_noise_win[core][pi->nphy_noise_index] =
+-		    noise_dbm_ant[core];
+-
+-		if (noise_dbm_ant[core] > noise_dbm)
+-			noise_dbm = noise_dbm_ant[core];
+-	}
+-	pi->nphy_noise_index =
+-	    MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+-
+-	return noise_dbm;
+-
+-}
+-
+-void wlc_phy_noise_sample_intr(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u16 jssi_aux;
+-	u8 channel = 0;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-
+-	if (ISLCNPHY(pi)) {
+-		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
+-		u16 lo, hi;
+-		s32 pwr_offset_dB, gain_dB;
+-		u16 status_0, status_1;
+-
+-		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+-		channel = jssi_aux & D11_CURCHANNEL_MAX;
+-
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
+-		cmplx_pwr0 = (hi << 16) + lo;
+-
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
+-		cmplx_pwr1 = (hi << 16) + lo;
+-		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
+-
+-		status_0 = 0x44;
+-		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
+-		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
+-		    && ((status_1 & 0xc000) == 0x4000)) {
+-
+-			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
+-					   pi->pubpi.phy_corenum);
+-			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
+-			if (pwr_offset_dB > 127)
+-				pwr_offset_dB -= 256;
+-
+-			noise_dbm += (s8) (pwr_offset_dB - 30);
+-
+-			gain_dB = (status_0 & 0x1ff);
+-			noise_dbm -= (s8) (gain_dB);
+-		} else {
+-			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
+-		}
+-	} else if (ISNPHY(pi)) {
+-
+-		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+-		channel = jssi_aux & D11_CURCHANNEL_MAX;
+-
+-		noise_dbm = wlc_phy_noise_read_shmem(pi);
+-	}
+-
+-	wlc_phy_noise_cb(pi, channel, noise_dbm);
+-
+-}
+-
+-s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	9,
+-	10,
+-	8,
+-	8,
+-	7,
+-	7,
+-	1,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	1,
+-	1,
+-	0,
+-	0,
+-	0,
+-	0
+-};
+-
+-void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
+-{
+-	u8 msb, secondmsb, i;
+-	u32 tmp;
+-
+-	for (i = 0; i < core; i++) {
+-		secondmsb = 0;
+-		tmp = cmplx_pwr[i];
+-		msb = fls(tmp);
+-		if (msb)
+-			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
+-		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
+-	}
+-}
+-
+-void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx)
+-{
+-	wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx;
+-	d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr;
+-	int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK;
+-	uint radioid = pih->radioid;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		rssi = WLC_RSSI_INVALID;
+-		goto end;
+-	}
+-
+-	if ((pi->sh->corerev >= 11)
+-	    && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) {
+-		rssi = WLC_RSSI_INVALID;
+-		goto end;
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		u8 gidx = (le16_to_cpu(rxh->PhyRxStatus_2) & 0xFC00) >> 10;
+-		phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-		if (rssi > 127)
+-			rssi -= 256;
+-
+-		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
+-		if ((rssi > -46) && (gidx > 18))
+-			rssi = rssi + 7;
+-
+-		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
+-
+-		rssi = rssi + 2;
+-
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-
+-		if (rssi > 127)
+-			rssi -= 256;
+-	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
+-		   || radioid == BCM2057_ID) {
+-		rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr);
+-	}
+-
+- end:
+-	wlc_rxhdr->rssi = (s8) rssi;
+-}
+-
+-void wlc_phy_freqtrack_start(wlc_phy_t *pih)
+-{
+-	return;
+-}
+-
+-void wlc_phy_freqtrack_end(wlc_phy_t *pih)
+-{
+-	return;
+-}
+-
+-void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag)
+-{
+-	phy_info_t *pi;
+-	pi = (phy_info_t *) ppi;
+-
+-	if (ISLCNPHY(pi))
+-		wlc_lcnphy_deaf_mode(pi, true);
+-	else if (ISNPHY(pi))
+-		wlc_nphy_deaf_mode(pi, true);
+-}
+-
+-void wlc_phy_watchdog(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	bool delay_phy_cal = false;
+-	pi->sh->now++;
+-
+-	if (!pi->watchdog_override)
+-		return;
+-
+-	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) {
+-		wlc_phy_noise_sample_request((wlc_phy_t *) pi,
+-					     PHY_NOISE_SAMPLE_MON,
+-					     CHSPEC_CHANNEL(pi->
+-							    radio_chanspec));
+-	}
+-
+-	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) {
+-		pi->phynoise_state = 0;
+-	}
+-
+-	if ((!pi->phycal_txpower) ||
+-	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
+-
+-		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) {
+-			pi->phycal_txpower = pi->sh->now;
+-		}
+-	}
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+-	     || ASSOC_INPROG_PHY(pi)))
+-		return;
+-
+-	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
+-
+-		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
+-		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
+-		    ((pi->sh->now - pi->nphy_perical_last) >=
+-		     pi->sh->glacial_timer))
+-			wlc_phy_cal_perical((wlc_phy_t *) pi,
+-					    PHY_PERICAL_WATCHDOG);
+-
+-		wlc_phy_txpwr_papd_cal_nphy(pi);
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		if (pi->phy_forcecal ||
+-		    ((pi->sh->now - pi->phy_lastcal) >=
+-		     pi->sh->glacial_timer)) {
+-			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
+-				wlc_lcnphy_calib_modes(pi,
+-						       LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+-			if (!
+-			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+-			     || ASSOC_INPROG_PHY(pi)
+-			     || pi->carrier_suppr_disable
+-			     || pi->disable_percal))
+-				wlc_lcnphy_calib_modes(pi,
+-						       PHY_PERICAL_WATCHDOG);
+-		}
+-	}
+-}
+-
+-void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	uint i;
+-	uint k;
+-
+-	for (i = 0; i < MA_WINDOW_SZ; i++) {
+-		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
+-	}
+-	if (ISLCNPHY(pi)) {
+-		for (i = 0; i < MA_WINDOW_SZ; i++)
+-			pi->sh->phy_noise_window[i] =
+-			    PHY_NOISE_FIXED_VAL_LCNPHY;
+-	}
+-	pi->sh->phy_noise_index = 0;
+-
+-	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
+-		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
+-			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
+-	}
+-	pi->nphy_noise_index = 0;
+-}
+-
+-void
+-wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
+-{
+-	*eps_imag = (epsilon >> 13);
+-	if (*eps_imag > 0xfff)
+-		*eps_imag -= 0x2000;
+-
+-	*eps_real = (epsilon & 0x1fff);
+-	if (*eps_real > 0xfff)
+-		*eps_real -= 0x2000;
+-}
+-
+-static const fixed AtanTbl[] = {
+-	2949120,
+-	1740967,
+-	919879,
+-	466945,
+-	234379,
+-	117304,
+-	58666,
+-	29335,
+-	14668,
+-	7334,
+-	3667,
+-	1833,
+-	917,
+-	458,
+-	229,
+-	115,
+-	57,
+-	29
+-};
+-
+-void wlc_phy_cordic(fixed theta, cs32 *val)
+-{
+-	fixed angle, valtmp;
+-	unsigned iter;
+-	int signx = 1;
+-	int signtheta;
+-
+-	val[0].i = CORDIC_AG;
+-	val[0].q = 0;
+-	angle = 0;
+-
+-	signtheta = (theta < 0) ? -1 : 1;
+-	theta =
+-	    ((theta + FIXED(180) * signtheta) % FIXED(360)) -
+-	    FIXED(180) * signtheta;
+-
+-	if (FLOAT(theta) > 90) {
+-		theta -= FIXED(180);
+-		signx = -1;
+-	} else if (FLOAT(theta) < -90) {
+-		theta += FIXED(180);
+-		signx = -1;
+-	}
+-
+-	for (iter = 0; iter < CORDIC_NI; iter++) {
+-		if (theta > angle) {
+-			valtmp = val[0].i - (val[0].q >> iter);
+-			val[0].q = (val[0].i >> iter) + val[0].q;
+-			val[0].i = valtmp;
+-			angle += AtanTbl[iter];
+-		} else {
+-			valtmp = val[0].i + (val[0].q >> iter);
+-			val[0].q = -(val[0].i >> iter) + val[0].q;
+-			val[0].i = valtmp;
+-			angle -= AtanTbl[iter];
+-		}
+-	}
+-
+-	val[0].i = val[0].i * signx;
+-	val[0].q = val[0].q * signx;
+-}
+-
+-void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi)
+-{
+-	wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+-
+-	pi->cal_type_override = PHY_PERICAL_AUTO;
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+-	pi->mphase_txcal_cmdidx = 0;
+-}
+-
+-static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay)
+-{
+-
+-	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
+-	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
+-		return;
+-
+-	wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+-
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+-	wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+-}
+-
+-void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason)
+-{
+-	s16 nphy_currtemp = 0;
+-	s16 delta_temp = 0;
+-	bool do_periodic_cal = true;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!ISNPHY(pi))
+-		return;
+-
+-	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
+-	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
+-		return;
+-
+-	switch (reason) {
+-	case PHY_PERICAL_DRIVERUP:
+-		break;
+-
+-	case PHY_PERICAL_PHYINIT:
+-		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+-			if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-			}
+-			wlc_phy_cal_perical_mphase_schedule(pi,
+-							    PHY_PERICAL_INIT_DELAY);
+-		}
+-		break;
+-
+-	case PHY_PERICAL_JOIN_BSS:
+-	case PHY_PERICAL_START_IBSS:
+-	case PHY_PERICAL_UP_BSS:
+-		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
+-		    PHY_PERICAL_MPHASE_PENDING(pi)) {
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-		}
+-
+-		pi->first_cal_after_assoc = true;
+-
+-		pi->cal_type_override = PHY_PERICAL_FULL;
+-
+-		if (pi->phycal_tempdelta) {
+-			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
+-		}
+-		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
+-		break;
+-
+-	case PHY_PERICAL_WATCHDOG:
+-		if (pi->phycal_tempdelta) {
+-			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+-			delta_temp =
+-			    (nphy_currtemp > pi->nphy_lastcal_temp) ?
+-			    nphy_currtemp - pi->nphy_lastcal_temp :
+-			    pi->nphy_lastcal_temp - nphy_currtemp;
+-
+-			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
+-			    (pi->nphy_txiqlocal_chanspec ==
+-			     pi->radio_chanspec)) {
+-				do_periodic_cal = false;
+-			} else {
+-				pi->nphy_lastcal_temp = nphy_currtemp;
+-			}
+-		}
+-
+-		if (do_periodic_cal) {
+-
+-			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+-
+-				if (!PHY_PERICAL_MPHASE_PENDING(pi))
+-					wlc_phy_cal_perical_mphase_schedule(pi,
+-									    PHY_PERICAL_WDOG_DELAY);
+-			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
+-				wlc_phy_cal_perical_nphy_run(pi,
+-							     PHY_PERICAL_AUTO);
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi)
+-{
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+-	pi->mphase_txcal_cmdidx = 0;
+-}
+-
+-u8 wlc_phy_nbits(s32 value)
+-{
+-	s32 abs_val;
+-	u8 nbits = 0;
+-
+-	abs_val = ABS(value);
+-	while ((abs_val >> nbits) > 0)
+-		nbits++;
+-
+-	return nbits;
+-}
+-
+-void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->sh->hw_phytxchain = txchain;
+-	pi->sh->hw_phyrxchain = rxchain;
+-	pi->sh->phytxchain = txchain;
+-	pi->sh->phyrxchain = rxchain;
+-	pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
+-}
+-
+-void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->sh->phytxchain = txchain;
+-
+-	if (ISNPHY(pi)) {
+-		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
+-	}
+-	pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
+-}
+-
+-void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, u8 *rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	*txchain = pi->sh->phytxchain;
+-	*rxchain = pi->sh->phyrxchain;
+-}
+-
+-u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih)
+-{
+-	s16 nphy_currtemp;
+-	u8 active_bitmap;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
+-
+-	if (!pi->watchdog_override)
+-		return active_bitmap;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-		if (!pi->phy_txcore_heatedup) {
+-			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
+-				active_bitmap &= 0xFD;
+-				pi->phy_txcore_heatedup = true;
+-			}
+-		} else {
+-			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
+-				active_bitmap |= 0x2;
+-				pi->phy_txcore_heatedup = false;
+-			}
+-		}
+-	}
+-
+-	return active_bitmap;
+-}
+-
+-s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u8 siso_mcs_id, cdd_mcs_id;
+-
+-	siso_mcs_id =
+-	    (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
+-	    TXP_FIRST_MCS_20_SISO;
+-	cdd_mcs_id =
+-	    (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
+-	    TXP_FIRST_MCS_20_CDD;
+-
+-	if (pi->tx_power_target[siso_mcs_id] >
+-	    (pi->tx_power_target[cdd_mcs_id] + 12))
+-		return PHY_TXC1_MODE_SISO;
+-	else
+-		return PHY_TXC1_MODE_CDD;
+-}
+-
+-const u8 *wlc_phy_get_ofdm_rate_lookup(void)
+-{
+-	return ofdm_rate_lookup;
+-}
+-
+-void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode)
+-{
+-	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
+-	    (pi->sh->boardflags & BFL_FEM)) {
+-		if (mode) {
+-			u16 txant = 0;
+-			txant = wlapi_bmac_get_txant(pi->sh->physhim);
+-			if (txant == 1) {
+-				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+-
+-				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
+-
+-			}
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
+-				   0x0);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioout), 0x40, 0x40);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioouten), 0x40,
+-				   0x40);
+-		} else {
+-			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
+-
+-			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
+-
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioout), 0x40, 0x00);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioouten), 0x40, 0x0);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
+-				   0x40);
+-		}
+-	}
+-}
+-
+-static s8
+-wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band,
+-				 u8 rate)
+-{
+-	s8 offset = 0;
+-
+-	if (!pi->user_txpwr_at_rfport)
+-		return offset;
+-	return offset;
+-}
+-
+-static s8 wlc_phy_env_measure_vbat(phy_info_t *pi)
+-{
+-	if (ISLCNPHY(pi))
+-		return wlc_lcnphy_vbatsense(pi, 0);
+-	else
+-		return 0;
+-}
+-
+-static s8 wlc_phy_env_measure_temperature(phy_info_t *pi)
+-{
+-	if (ISLCNPHY(pi))
+-		return wlc_lcnphy_tempsense_degree(pi, 0);
+-	else
+-		return 0;
+-}
+-
+-static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band)
+-{
+-	u8 i;
+-	s8 temp, vbat;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++)
+-		pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+-
+-	vbat = wlc_phy_env_measure_vbat(pi);
+-	temp = wlc_phy_env_measure_temperature(pi);
+-
+-}
+-
+-void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc)
+-{
+-	return;
+-}
+-
+-void
+-wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset)
+-{
+-	*cckoffset = 0;
+-	*ofdmoffset = 0;
+-}
+-
+-s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec)
+-{
+-
+-	return rssi;
+-}
+-
+-bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	if (ISNPHY(pi))
+-		return wlc_phy_n_txpower_ipa_ison(pi);
+-	else
+-		return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
+deleted file mode 100644
+index 8939153..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
++++ /dev/null
+@@ -1,256 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_h_
+-#define _wlc_phy_h_
+-
+-#include <wlioctl.h>
+-#include <aiutils.h>
+-#include <d11.h>
+-#include <wlc_phy_shim.h>
+-#include <net/mac80211.h>	/* struct wiphy */
+-
+-#define	IDCODE_VER_MASK		0x0000000f
+-#define	IDCODE_VER_SHIFT	0
+-#define	IDCODE_MFG_MASK		0x00000fff
+-#define	IDCODE_MFG_SHIFT	0
+-#define	IDCODE_ID_MASK		0x0ffff000
+-#define	IDCODE_ID_SHIFT		12
+-#define	IDCODE_REV_MASK		0xf0000000
+-#define	IDCODE_REV_SHIFT	28
+-
+-#define	NORADIO_ID		0xe4f5
+-#define	NORADIO_IDCODE		0x4e4f5246
+-
+-#define BCM2055_ID		0x2055
+-#define BCM2055_IDCODE		0x02055000
+-#define BCM2055A0_IDCODE	0x1205517f
+-
+-#define BCM2056_ID		0x2056
+-#define BCM2056_IDCODE		0x02056000
+-#define BCM2056A0_IDCODE	0x1205617f
+-
+-#define BCM2057_ID		0x2057
+-#define BCM2057_IDCODE		0x02057000
+-#define BCM2057A0_IDCODE	0x1205717f
+-
+-#define BCM2064_ID		0x2064
+-#define BCM2064_IDCODE		0x02064000
+-#define BCM2064A0_IDCODE	0x0206417f
+-
+-#define PHY_TPC_HW_OFF		false
+-#define PHY_TPC_HW_ON		true
+-
+-#define PHY_PERICAL_DRIVERUP	1
+-#define PHY_PERICAL_WATCHDOG	2
+-#define PHY_PERICAL_PHYINIT	3
+-#define PHY_PERICAL_JOIN_BSS	4
+-#define PHY_PERICAL_START_IBSS	5
+-#define PHY_PERICAL_UP_BSS	6
+-#define PHY_PERICAL_CHAN	7
+-#define PHY_FULLCAL	8
+-
+-#define PHY_PERICAL_DISABLE	0
+-#define PHY_PERICAL_SPHASE	1
+-#define PHY_PERICAL_MPHASE	2
+-#define PHY_PERICAL_MANUAL	3
+-
+-#define PHY_HOLD_FOR_ASSOC	1
+-#define PHY_HOLD_FOR_SCAN	2
+-#define PHY_HOLD_FOR_RM		4
+-#define PHY_HOLD_FOR_PLT	8
+-#define PHY_HOLD_FOR_MUTE	16
+-#define PHY_HOLD_FOR_NOT_ASSOC 0x20
+-
+-#define PHY_MUTE_FOR_PREISM	1
+-#define PHY_MUTE_ALL		0xffffffff
+-
+-#define PHY_NOISE_FIXED_VAL 		(-95)
+-#define PHY_NOISE_FIXED_VAL_NPHY       	(-92)
+-#define PHY_NOISE_FIXED_VAL_LCNPHY     	(-92)
+-
+-#define PHY_MODE_CAL		0x0002
+-#define PHY_MODE_NOISEM		0x0004
+-
+-#define WLC_TXPWR_DB_FACTOR	4
+-
+-#define WLC_NUM_RATES_CCK           4
+-#define WLC_NUM_RATES_OFDM          8
+-#define WLC_NUM_RATES_MCS_1_STREAM  8
+-#define WLC_NUM_RATES_MCS_2_STREAM  8
+-#define WLC_NUM_RATES_MCS_3_STREAM  8
+-#define WLC_NUM_RATES_MCS_4_STREAM  8
+-typedef struct txpwr_limits {
+-	u8 cck[WLC_NUM_RATES_CCK];
+-	u8 ofdm[WLC_NUM_RATES_OFDM];
+-
+-	u8 ofdm_cdd[WLC_NUM_RATES_OFDM];
+-
+-	u8 ofdm_40_siso[WLC_NUM_RATES_OFDM];
+-	u8 ofdm_40_cdd[WLC_NUM_RATES_OFDM];
+-
+-	u8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+-
+-	u8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+-	u8 mcs32;
+-} txpwr_limits_t;
+-
+-typedef struct {
+-	u8 vec[MAXCHANNEL / NBBY];
+-} chanvec_t;
+-
+-struct rpc_info;
+-typedef struct shared_phy shared_phy_t;
+-
+-struct phy_pub;
+-
+-typedef struct phy_pub wlc_phy_t;
+-
+-typedef struct shared_phy_params {
+-	si_t *sih;
+-	void *physhim;
+-	uint unit;
+-	uint corerev;
+-	uint bustype;
+-	uint buscorerev;
+-	char *vars;
+-	u16 vid;
+-	u16 did;
+-	uint chip;
+-	uint chiprev;
+-	uint chippkg;
+-	uint sromrev;
+-	uint boardtype;
+-	uint boardrev;
+-	uint boardvendor;
+-	u32 boardflags;
+-	u32 boardflags2;
+-} shared_phy_params_t;
+-
+-
+-extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp);
+-extern void wlc_phy_shared_detach(shared_phy_t *phy_sh);
+-extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+-				 char *vars, struct wiphy *wiphy);
+-extern void wlc_phy_detach(wlc_phy_t *ppi);
+-
+-extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype,
+-				   u16 *phyrev, u16 *radioid,
+-				   u16 *radiover);
+-extern bool wlc_phy_get_encore(wlc_phy_t *pih);
+-extern u32 wlc_phy_get_coreflags(wlc_phy_t *pih);
+-
+-extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate);
+-extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate);
+-extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec);
+-extern void wlc_phy_watchdog(wlc_phy_t *ppi);
+-extern int wlc_phy_down(wlc_phy_t *ppi);
+-extern u32 wlc_phy_clk_bwbits(wlc_phy_t *pih);
+-extern void wlc_phy_cal_init(wlc_phy_t *ppi);
+-extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init);
+-
+-extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec);
+-extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi);
+-extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch);
+-extern u16 wlc_phy_bw_state_get(wlc_phy_t *ppi);
+-extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw);
+-
+-extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx);
+-extern void wlc_phy_por_inform(wlc_phy_t *ppi);
+-extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi);
+-extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi);
+-
+-extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag);
+-
+-extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on);
+-extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on);
+-
+-
+-extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi);
+-
+-extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi,
+-						 bool wide_filter);
+-extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band,
+-					  chanvec_t *channels);
+-extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band);
+-
+-extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan,
+-				      u8 *_min_, u8 *_max_, int rate);
+-extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan,
+-					      u8 *_max_, u8 *_min_);
+-extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, s32 *,
+-					    s32 *, u32 *);
+-extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *,
+-				      chanspec_t chanspec);
+-extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override);
+-extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override);
+-extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *);
+-extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi);
+-extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl);
+-extern u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi);
+-extern u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi);
+-extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih);
+-
+-extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain,
+-				   u8 rxchain);
+-extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain,
+-				  u8 rxchain);
+-extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain,
+-				  u8 *rxchain);
+-extern u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih);
+-extern s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec);
+-extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val);
+-
+-extern void wlc_phy_cal_perical(wlc_phy_t *ppi, u8 reason);
+-extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi);
+-extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock);
+-extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi);
+-
+-extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val);
+-extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval);
+-extern void wlc_phy_clear_tssi(wlc_phy_t *ppi);
+-extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val);
+-extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags);
+-
+-extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type);
+-
+-extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power,
+-					uint channel);
+-
+-extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal);
+-extern bool wlc_phy_test_ison(wlc_phy_t *ppi);
+-extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent);
+-extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war);
+-extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt);
+-extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap);
+-
+-extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end);
+-
+-extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi);
+-extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi);
+-
+-extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
+-
+-extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi,
+-					       u8 mcs_offset);
+-extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset);
+-#endif				/* _wlc_phy_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
+deleted file mode 100644
+index 10cbf52..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
++++ /dev/null
+@@ -1,1226 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_int_h_
+-#define _wlc_phy_int_h_
+-
+-#include <linux/kernel.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-
+-#include <bcmsrom_fmt.h>
+-#include <wlc_phy_hal.h>
+-
+-#define PHYHAL_ERROR	0x0001
+-#define PHYHAL_TRACE	0x0002
+-#define PHYHAL_INFORM	0x0004
+-
+-extern u32 phyhal_msg_level;
+-
+-#define PHY_INFORM_ON()		(phyhal_msg_level & PHYHAL_INFORM)
+-#define PHY_THERMAL_ON()	(phyhal_msg_level & PHYHAL_THERMAL)
+-#define PHY_CAL_ON()		(phyhal_msg_level & PHYHAL_CAL)
+-
+-#ifdef BOARD_TYPE
+-#define BOARDTYPE(_type) BOARD_TYPE
+-#else
+-#define BOARDTYPE(_type) _type
+-#endif
+-
+-#define LCNXN_BASEREV		16
+-
+-struct wlc_hw_info;
+-typedef struct phy_info phy_info_t;
+-typedef void (*initfn_t) (phy_info_t *);
+-typedef void (*chansetfn_t) (phy_info_t *, chanspec_t);
+-typedef int (*longtrnfn_t) (phy_info_t *, int);
+-typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *);
+-typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16);
+-typedef u16(*txloccgetfn_t) (phy_info_t *);
+-typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *,
+-				  u8 *);
+-typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32);
+-typedef void (*detachfn_t) (phy_info_t *);
+-
+-#undef ISNPHY
+-#undef ISLCNPHY
+-#define ISNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
+-#define ISLCNPHY(pi)  	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
+-
+-#define ISPHY_11N_CAP(pi)	(ISNPHY(pi) || ISLCNPHY(pi))
+-
+-#define IS20MHZ(pi)	((pi)->bw == WL_CHANSPEC_BW_20)
+-#define IS40MHZ(pi)	((pi)->bw == WL_CHANSPEC_BW_40)
+-
+-#define PHY_GET_RFATTN(rfgain)	((rfgain) & 0x0f)
+-#define PHY_GET_PADMIX(rfgain)	(((rfgain) & 0x10) >> 4)
+-#define PHY_GET_RFGAINID(rfattn, padmix, width)	((rfattn) + ((padmix)*(width)))
+-#define PHY_SAT(x, n)		((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
+-				((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
+-#define PHY_SHIFT_ROUND(x, n)	((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
+-#define PHY_HW_ROUND(x, s)		((x >> s) + ((x >> (s-1)) & (s != 0)))
+-
+-#define CH_5G_GROUP	3
+-#define A_LOW_CHANS	0
+-#define A_MID_CHANS	1
+-#define A_HIGH_CHANS	2
+-#define CH_2G_GROUP	1
+-#define G_ALL_CHANS	0
+-
+-#define FIRST_REF5_CHANNUM	149
+-#define LAST_REF5_CHANNUM	165
+-#define	FIRST_5G_CHAN		14
+-#define	LAST_5G_CHAN		50
+-#define	FIRST_MID_5G_CHAN	14
+-#define	LAST_MID_5G_CHAN	35
+-#define	FIRST_HIGH_5G_CHAN	36
+-#define	LAST_HIGH_5G_CHAN	41
+-#define	FIRST_LOW_5G_CHAN	42
+-#define	LAST_LOW_5G_CHAN	50
+-
+-#define BASE_LOW_5G_CHAN	4900
+-#define BASE_MID_5G_CHAN	5100
+-#define BASE_HIGH_5G_CHAN	5500
+-
+-#define CHAN5G_FREQ(chan)  (5000 + chan*5)
+-#define CHAN2G_FREQ(chan)  (2407 + chan*5)
+-
+-#define TXP_FIRST_CCK		0
+-#define TXP_LAST_CCK		3
+-#define TXP_FIRST_OFDM		4
+-#define TXP_LAST_OFDM		11
+-#define TXP_FIRST_OFDM_20_CDD	12
+-#define TXP_LAST_OFDM_20_CDD	19
+-#define TXP_FIRST_MCS_20_SISO	20
+-#define TXP_LAST_MCS_20_SISO	27
+-#define TXP_FIRST_MCS_20_CDD	28
+-#define TXP_LAST_MCS_20_CDD	35
+-#define TXP_FIRST_MCS_20_STBC	36
+-#define TXP_LAST_MCS_20_STBC	43
+-#define TXP_FIRST_MCS_20_SDM	44
+-#define TXP_LAST_MCS_20_SDM	51
+-#define TXP_FIRST_OFDM_40_SISO	52
+-#define TXP_LAST_OFDM_40_SISO	59
+-#define TXP_FIRST_OFDM_40_CDD	60
+-#define TXP_LAST_OFDM_40_CDD	67
+-#define TXP_FIRST_MCS_40_SISO	68
+-#define TXP_LAST_MCS_40_SISO	75
+-#define TXP_FIRST_MCS_40_CDD	76
+-#define TXP_LAST_MCS_40_CDD	83
+-#define TXP_FIRST_MCS_40_STBC	84
+-#define TXP_LAST_MCS_40_STBC	91
+-#define TXP_FIRST_MCS_40_SDM	92
+-#define TXP_LAST_MCS_40_SDM	99
+-#define TXP_MCS_32	        100
+-#define TXP_NUM_RATES		101
+-#define ADJ_PWR_TBL_LEN		84
+-
+-#define TXP_FIRST_SISO_MCS_20	20
+-#define TXP_LAST_SISO_MCS_20	27
+-
+-#define PHY_CORE_NUM_1	1
+-#define PHY_CORE_NUM_2	2
+-#define PHY_CORE_NUM_3	3
+-#define PHY_CORE_NUM_4	4
+-#define PHY_CORE_MAX	PHY_CORE_NUM_4
+-#define PHY_CORE_0	0
+-#define PHY_CORE_1	1
+-#define PHY_CORE_2	2
+-#define PHY_CORE_3	3
+-
+-#define MA_WINDOW_SZ		8
+-
+-#define PHY_NOISE_SAMPLE_MON		1
+-#define PHY_NOISE_SAMPLE_EXTERNAL	2
+-#define PHY_NOISE_WINDOW_SZ	16
+-#define PHY_NOISE_GLITCH_INIT_MA 10
+-#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
+-#define PHY_NOISE_STATE_MON		0x1
+-#define PHY_NOISE_STATE_EXTERNAL	0x2
+-#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY	10
+-#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE	9
+-
+-#define PHY_NOISE_OFFSETFACT_4322  (-103)
+-#define PHY_NOISE_MA_WINDOW_SZ	2
+-
+-#define	PHY_RSSI_TABLE_SIZE	64
+-#define RSSI_ANT_MERGE_MAX	0
+-#define RSSI_ANT_MERGE_MIN	1
+-#define RSSI_ANT_MERGE_AVG	2
+-
+-#define	PHY_TSSI_TABLE_SIZE	64
+-#define	APHY_TSSI_TABLE_SIZE	256
+-#define	TX_GAIN_TABLE_LENGTH	64
+-#define	DEFAULT_11A_TXP_IDX	24
+-#define NUM_TSSI_FRAMES        4
+-#define	NULL_TSSI		0x7f
+-#define	NULL_TSSI_W		0x7f7f
+-
+-#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
+-
+-#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
+-
+-#define PHY_TXPWR_MIN		10
+-#define PHY_TXPWR_MIN_NPHY	8
+-#define RADIOPWR_OVERRIDE_DEF	(-1)
+-
+-#define PWRTBL_NUM_COEFF	3
+-
+-#define SPURAVOID_DISABLE	0
+-#define SPURAVOID_AUTO		1
+-#define SPURAVOID_FORCEON	2
+-#define SPURAVOID_FORCEON2	3
+-
+-#define PHY_SW_TIMER_FAST		15
+-#define PHY_SW_TIMER_SLOW		60
+-#define PHY_SW_TIMER_GLACIAL	120
+-
+-#define PHY_PERICAL_AUTO	0
+-#define PHY_PERICAL_FULL	1
+-#define PHY_PERICAL_PARTIAL	2
+-
+-#define PHY_PERICAL_NODELAY	0
+-#define PHY_PERICAL_INIT_DELAY	5
+-#define PHY_PERICAL_ASSOC_DELAY	5
+-#define PHY_PERICAL_WDOG_DELAY	5
+-
+-#define MPHASE_TXCAL_NUMCMDS	2
+-#define PHY_PERICAL_MPHASE_PENDING(pi)	(pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
+-
+-enum {
+-	MPHASE_CAL_STATE_IDLE = 0,
+-	MPHASE_CAL_STATE_INIT = 1,
+-	MPHASE_CAL_STATE_TXPHASE0,
+-	MPHASE_CAL_STATE_TXPHASE1,
+-	MPHASE_CAL_STATE_TXPHASE2,
+-	MPHASE_CAL_STATE_TXPHASE3,
+-	MPHASE_CAL_STATE_TXPHASE4,
+-	MPHASE_CAL_STATE_TXPHASE5,
+-	MPHASE_CAL_STATE_PAPDCAL,
+-	MPHASE_CAL_STATE_RXCAL,
+-	MPHASE_CAL_STATE_RSSICAL,
+-	MPHASE_CAL_STATE_IDLETSSI
+-};
+-
+-typedef enum {
+-	CAL_FULL,
+-	CAL_RECAL,
+-	CAL_CURRECAL,
+-	CAL_DIGCAL,
+-	CAL_GCTRL,
+-	CAL_SOFT,
+-	CAL_DIGLO
+-} phy_cal_mode_t;
+-
+-#define RDR_NTIERS  1
+-#define RDR_TIER_SIZE 64
+-#define RDR_LIST_SIZE (512/3)
+-#define RDR_EPOCH_SIZE 40
+-#define RDR_NANTENNAS 2
+-#define RDR_NTIER_SIZE  RDR_LIST_SIZE
+-#define RDR_LP_BUFFER_SIZE 64
+-#define LP_LEN_HIS_SIZE 10
+-
+-#define STATIC_NUM_RF 32
+-#define STATIC_NUM_BB 9
+-
+-#define BB_MULT_MASK		0x0000ffff
+-#define BB_MULT_VALID_MASK	0x80000000
+-
+-#define CORDIC_AG	39797
+-#define	CORDIC_NI	18
+-#define	FIXED(X)	((s32)((X) << 16))
+-#define	FLOAT(X)	(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
+-
+-#define PHY_CHAIN_TX_DISABLE_TEMP	115
+-#define PHY_HYSTERESIS_DELTATEMP	5
+-
+-#define PHY_BITSCNT(x)	bcm_bitcount((u8 *)&(x), sizeof(u8))
+-
+-#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \
+-	mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \
+-	(value) << phy_type##_##reg_name##_##field##_##SHIFT);
+-#define READ_PHY_REG(pi, phy_type, reg_name, field) \
+-	((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\
+-	>> phy_type##_##reg_name##_##field##_##SHIFT)
+-
+-#define	VALID_PHYTYPE(phytype)	(((uint)phytype == PHY_TYPE_N) || \
+-				((uint)phytype == PHY_TYPE_LCN))
+-
+-#define VALID_N_RADIO(radioid)	((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \
+-				(radioid == BCM2057_ID))
+-#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
+-
+-#define	VALID_RADIO(pi, radioid)	(\
+-	(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
+-	(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
+-
+-#define SCAN_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
+-#define RM_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM))
+-#define PLT_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
+-#define ASSOC_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
+-#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
+-#define PHY_MUTED(pi)		(mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
+-#define PUB_NOT_ASSOC(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
+-
+-#if defined(EXT_CBALL)
+-#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID)
+-#else
+-#define NORADIO_ENAB(pub) 0
+-#endif
+-
+-#define PHY_LTRN_LIST_LEN	64
+-extern u16 ltrn_list[PHY_LTRN_LIST_LEN];
+-
+-typedef struct _phy_table_info {
+-	uint table;
+-	int q;
+-	uint max;
+-} phy_table_info_t;
+-
+-typedef struct phytbl_info {
+-	const void *tbl_ptr;
+-	u32 tbl_len;
+-	u32 tbl_id;
+-	u32 tbl_offset;
+-	u32 tbl_width;
+-} phytbl_info_t;
+-
+-typedef struct {
+-	u8 curr_home_channel;
+-	u16 crsminpwrthld_40_stored;
+-	u16 crsminpwrthld_20L_stored;
+-	u16 crsminpwrthld_20U_stored;
+-	u16 init_gain_code_core1_stored;
+-	u16 init_gain_code_core2_stored;
+-	u16 init_gain_codeb_core1_stored;
+-	u16 init_gain_codeb_core2_stored;
+-	u16 init_gain_table_stored[4];
+-
+-	u16 clip1_hi_gain_code_core1_stored;
+-	u16 clip1_hi_gain_code_core2_stored;
+-	u16 clip1_hi_gain_codeb_core1_stored;
+-	u16 clip1_hi_gain_codeb_core2_stored;
+-	u16 nb_clip_thresh_core1_stored;
+-	u16 nb_clip_thresh_core2_stored;
+-	u16 init_ofdmlna2gainchange_stored[4];
+-	u16 init_ccklna2gainchange_stored[4];
+-	u16 clip1_lo_gain_code_core1_stored;
+-	u16 clip1_lo_gain_code_core2_stored;
+-	u16 clip1_lo_gain_codeb_core1_stored;
+-	u16 clip1_lo_gain_codeb_core2_stored;
+-	u16 w1_clip_thresh_core1_stored;
+-	u16 w1_clip_thresh_core2_stored;
+-	u16 radio_2056_core1_rssi_gain_stored;
+-	u16 radio_2056_core2_rssi_gain_stored;
+-	u16 energy_drop_timeout_len_stored;
+-
+-	u16 ed_crs40_assertthld0_stored;
+-	u16 ed_crs40_assertthld1_stored;
+-	u16 ed_crs40_deassertthld0_stored;
+-	u16 ed_crs40_deassertthld1_stored;
+-	u16 ed_crs20L_assertthld0_stored;
+-	u16 ed_crs20L_assertthld1_stored;
+-	u16 ed_crs20L_deassertthld0_stored;
+-	u16 ed_crs20L_deassertthld1_stored;
+-	u16 ed_crs20U_assertthld0_stored;
+-	u16 ed_crs20U_assertthld1_stored;
+-	u16 ed_crs20U_deassertthld0_stored;
+-	u16 ed_crs20U_deassertthld1_stored;
+-
+-	u16 badplcp_ma;
+-	u16 badplcp_ma_previous;
+-	u16 badplcp_ma_total;
+-	u16 badplcp_ma_list[MA_WINDOW_SZ];
+-	int badplcp_ma_index;
+-	s16 pre_badplcp_cnt;
+-	s16 bphy_pre_badplcp_cnt;
+-
+-	u16 init_gain_core1;
+-	u16 init_gain_core2;
+-	u16 init_gainb_core1;
+-	u16 init_gainb_core2;
+-	u16 init_gain_rfseq[4];
+-
+-	u16 crsminpwr0;
+-	u16 crsminpwrl0;
+-	u16 crsminpwru0;
+-
+-	s16 crsminpwr_index;
+-
+-	u16 radio_2057_core1_rssi_wb1a_gc_stored;
+-	u16 radio_2057_core2_rssi_wb1a_gc_stored;
+-	u16 radio_2057_core1_rssi_wb1g_gc_stored;
+-	u16 radio_2057_core2_rssi_wb1g_gc_stored;
+-	u16 radio_2057_core1_rssi_wb2_gc_stored;
+-	u16 radio_2057_core2_rssi_wb2_gc_stored;
+-	u16 radio_2057_core1_rssi_nb_gc_stored;
+-	u16 radio_2057_core2_rssi_nb_gc_stored;
+-
+-} interference_info_t;
+-
+-typedef struct {
+-	u16 rc_cal_ovr;
+-	u16 phycrsth1;
+-	u16 phycrsth2;
+-	u16 init_n1p1_gain;
+-	u16 p1_p2_gain;
+-	u16 n1_n2_gain;
+-	u16 n1_p1_gain;
+-	u16 div_search_gain;
+-	u16 div_p1_p2_gain;
+-	u16 div_search_gn_change;
+-	u16 table_7_2;
+-	u16 table_7_3;
+-	u16 cckshbits_gnref;
+-	u16 clip_thresh;
+-	u16 clip2_thresh;
+-	u16 clip3_thresh;
+-	u16 clip_p2_thresh;
+-	u16 clip_pwdn_thresh;
+-	u16 clip_n1p1_thresh;
+-	u16 clip_n1_pwdn_thresh;
+-	u16 bbconfig;
+-	u16 cthr_sthr_shdin;
+-	u16 energy;
+-	u16 clip_p1_p2_thresh;
+-	u16 threshold;
+-	u16 reg15;
+-	u16 reg16;
+-	u16 reg17;
+-	u16 div_srch_idx;
+-	u16 div_srch_p1_p2;
+-	u16 div_srch_gn_back;
+-	u16 ant_dwell;
+-	u16 ant_wr_settle;
+-} aci_save_gphy_t;
+-
+-typedef struct _lo_complex_t {
+-	s8 i;
+-	s8 q;
+-} lo_complex_abgphy_info_t;
+-
+-typedef struct _nphy_iq_comp {
+-	s16 a0;
+-	s16 b0;
+-	s16 a1;
+-	s16 b1;
+-} nphy_iq_comp_t;
+-
+-typedef struct _nphy_txpwrindex {
+-	s8 index;
+-	s8 index_internal;
+-	s8 index_internal_save;
+-	u16 AfectrlOverride;
+-	u16 AfeCtrlDacGain;
+-	u16 rad_gain;
+-	u8 bbmult;
+-	u16 iqcomp_a;
+-	u16 iqcomp_b;
+-	u16 locomp;
+-} phy_txpwrindex_t;
+-
+-typedef struct {
+-
+-	u16 txcal_coeffs_2G[8];
+-	u16 txcal_radio_regs_2G[8];
+-	nphy_iq_comp_t rxcal_coeffs_2G;
+-
+-	u16 txcal_coeffs_5G[8];
+-	u16 txcal_radio_regs_5G[8];
+-	nphy_iq_comp_t rxcal_coeffs_5G;
+-} txiqcal_cache_t;
+-
+-typedef struct _nphy_pwrctrl {
+-	s8 max_pwr_2g;
+-	s8 idle_targ_2g;
+-	s16 pwrdet_2g_a1;
+-	s16 pwrdet_2g_b0;
+-	s16 pwrdet_2g_b1;
+-	s8 max_pwr_5gm;
+-	s8 idle_targ_5gm;
+-	s8 max_pwr_5gh;
+-	s8 max_pwr_5gl;
+-	s16 pwrdet_5gm_a1;
+-	s16 pwrdet_5gm_b0;
+-	s16 pwrdet_5gm_b1;
+-	s16 pwrdet_5gl_a1;
+-	s16 pwrdet_5gl_b0;
+-	s16 pwrdet_5gl_b1;
+-	s16 pwrdet_5gh_a1;
+-	s16 pwrdet_5gh_b0;
+-	s16 pwrdet_5gh_b1;
+-	s8 idle_targ_5gl;
+-	s8 idle_targ_5gh;
+-	s8 idle_tssi_2g;
+-	s8 idle_tssi_5g;
+-	s8 idle_tssi;
+-	s16 a1;
+-	s16 b0;
+-	s16 b1;
+-} phy_pwrctrl_t;
+-
+-typedef struct _nphy_txgains {
+-	u16 txlpf[2];
+-	u16 txgm[2];
+-	u16 pga[2];
+-	u16 pad[2];
+-	u16 ipa[2];
+-} nphy_txgains_t;
+-
+-#define PHY_NOISEVAR_BUFSIZE 10
+-
+-typedef struct _nphy_noisevar_buf {
+-	int bufcount;
+-	int tone_id[PHY_NOISEVAR_BUFSIZE];
+-	u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
+-	u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
+-} phy_noisevar_buf_t;
+-
+-typedef struct {
+-	u16 rssical_radio_regs_2G[2];
+-	u16 rssical_phyregs_2G[12];
+-
+-	u16 rssical_radio_regs_5G[2];
+-	u16 rssical_phyregs_5G[12];
+-} rssical_cache_t;
+-
+-typedef struct {
+-
+-	u16 txiqlocal_a;
+-	u16 txiqlocal_b;
+-	u16 txiqlocal_didq;
+-	u8 txiqlocal_ei0;
+-	u8 txiqlocal_eq0;
+-	u8 txiqlocal_fi0;
+-	u8 txiqlocal_fq0;
+-
+-	u16 txiqlocal_bestcoeffs[11];
+-	u16 txiqlocal_bestcoeffs_valid;
+-
+-	u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
+-	u16 analog_gain_ref;
+-	u16 lut_begin;
+-	u16 lut_end;
+-	u16 lut_step;
+-	u16 rxcompdbm;
+-	u16 papdctrl;
+-	u16 sslpnCalibClkEnCtrl;
+-
+-	u16 rxiqcal_coeff_a0;
+-	u16 rxiqcal_coeff_b0;
+-} lcnphy_cal_results_t;
+-
+-struct shared_phy {
+-	struct phy_info *phy_head;
+-	uint unit;
+-	si_t *sih;
+-	void *physhim;
+-	uint corerev;
+-	u32 machwcap;
+-	bool up;
+-	bool clk;
+-	uint now;
+-	u16 vid;
+-	u16 did;
+-	uint chip;
+-	uint chiprev;
+-	uint chippkg;
+-	uint sromrev;
+-	uint boardtype;
+-	uint boardrev;
+-	uint boardvendor;
+-	u32 boardflags;
+-	u32 boardflags2;
+-	uint bustype;
+-	uint buscorerev;
+-	uint fast_timer;
+-	uint slow_timer;
+-	uint glacial_timer;
+-	u8 rx_antdiv;
+-	s8 phy_noise_window[MA_WINDOW_SZ];
+-	uint phy_noise_index;
+-	u8 hw_phytxchain;
+-	u8 hw_phyrxchain;
+-	u8 phytxchain;
+-	u8 phyrxchain;
+-	u8 rssi_mode;
+-	bool _rifs_phy;
+-};
+-
+-struct phy_pub {
+-	uint phy_type;
+-	uint phy_rev;
+-	u8 phy_corenum;
+-	u16 radioid;
+-	u8 radiorev;
+-	u8 radiover;
+-
+-	uint coreflags;
+-	uint ana_rev;
+-	bool abgphy_encore;
+-};
+-
+-struct phy_info_nphy;
+-typedef struct phy_info_nphy phy_info_nphy_t;
+-
+-struct phy_info_lcnphy;
+-typedef struct phy_info_lcnphy phy_info_lcnphy_t;
+-
+-struct phy_func_ptr {
+-	initfn_t init;
+-	initfn_t calinit;
+-	chansetfn_t chanset;
+-	initfn_t txpwrrecalc;
+-	longtrnfn_t longtrn;
+-	txiqccgetfn_t txiqccget;
+-	txiqccsetfn_t txiqccset;
+-	txloccgetfn_t txloccget;
+-	radioloftgetfn_t radioloftget;
+-	initfn_t carrsuppr;
+-	rxsigpwrfn_t rxsigpwr;
+-	detachfn_t detach;
+-};
+-typedef struct phy_func_ptr phy_func_ptr_t;
+-
+-struct phy_info {
+-	wlc_phy_t pubpi_ro;
+-	shared_phy_t *sh;
+-	phy_func_ptr_t pi_fptr;
+-	void *pi_ptr;
+-
+-	union {
+-		phy_info_lcnphy_t *pi_lcnphy;
+-	} u;
+-	bool user_txpwr_at_rfport;
+-
+-	d11regs_t *regs;
+-	struct phy_info *next;
+-	char *vars;
+-	wlc_phy_t pubpi;
+-
+-	bool do_initcal;
+-	bool phytest_on;
+-	bool ofdm_rateset_war;
+-	bool bf_preempt_4306;
+-	chanspec_t radio_chanspec;
+-	u8 antsel_type;
+-	u16 bw;
+-	u8 txpwr_percent;
+-	bool phy_init_por;
+-
+-	bool init_in_progress;
+-	bool initialized;
+-	bool sbtml_gm;
+-	uint refcnt;
+-	bool watchdog_override;
+-	u8 phynoise_state;
+-	uint phynoise_now;
+-	int phynoise_chan_watchdog;
+-	bool phynoise_polling;
+-	bool disable_percal;
+-	mbool measure_hold;
+-
+-	s16 txpa_2g[PWRTBL_NUM_COEFF];
+-	s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
+-	s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_low[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
+-
+-	u8 tx_srom_max_2g;
+-	u8 tx_srom_max_5g_low;
+-	u8 tx_srom_max_5g_mid;
+-	u8 tx_srom_max_5g_hi;
+-	u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
+-	u8 tx_user_target[TXP_NUM_RATES];
+-	s8 tx_power_offset[TXP_NUM_RATES];
+-	u8 tx_power_target[TXP_NUM_RATES];
+-
+-	srom_fem_t srom_fem2g;
+-	srom_fem_t srom_fem5g;
+-
+-	u8 tx_power_max;
+-	u8 tx_power_max_rate_ind;
+-	bool hwpwrctrl;
+-	u8 nphy_txpwrctrl;
+-	s8 nphy_txrx_chain;
+-	bool phy_5g_pwrgain;
+-
+-	u16 phy_wreg;
+-	u16 phy_wreg_limit;
+-
+-	s8 n_preamble_override;
+-	u8 antswitch;
+-	u8 aa2g, aa5g;
+-
+-	s8 idle_tssi[CH_5G_GROUP];
+-	s8 target_idle_tssi;
+-	s8 txpwr_est_Pout;
+-	u8 tx_power_min;
+-	u8 txpwr_limit[TXP_NUM_RATES];
+-	u8 txpwr_env_limit[TXP_NUM_RATES];
+-	u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
+-
+-	bool channel_14_wide_filter;
+-
+-	bool txpwroverride;
+-	bool txpwridx_override_aphy;
+-	s16 radiopwr_override;
+-	u16 hwpwr_txcur;
+-	u8 saved_txpwr_idx;
+-
+-	bool edcrs_threshold_lock;
+-
+-	u32 tr_R_gain_val;
+-	u32 tr_T_gain_val;
+-
+-	s16 ofdm_analog_filt_bw_override;
+-	s16 cck_analog_filt_bw_override;
+-	s16 ofdm_rccal_override;
+-	s16 cck_rccal_override;
+-	u16 extlna_type;
+-
+-	uint interference_mode_crs_time;
+-	u16 crsglitch_prev;
+-	bool interference_mode_crs;
+-
+-	u32 phy_tx_tone_freq;
+-	uint phy_lastcal;
+-	bool phy_forcecal;
+-	bool phy_fixed_noise;
+-	u32 xtalfreq;
+-	u8 pdiv;
+-	s8 carrier_suppr_disable;
+-
+-	bool phy_bphy_evm;
+-	bool phy_bphy_rfcs;
+-	s8 phy_scraminit;
+-	u8 phy_gpiosel;
+-
+-	s16 phy_txcore_disable_temp;
+-	s16 phy_txcore_enable_temp;
+-	s8 phy_tempsense_offset;
+-	bool phy_txcore_heatedup;
+-
+-	u16 radiopwr;
+-	u16 bb_atten;
+-	u16 txctl1;
+-
+-	u16 mintxbias;
+-	u16 mintxmag;
+-	lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB];
+-	s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
+-	u16 gain_table[TX_GAIN_TABLE_LENGTH];
+-	bool loopback_gain;
+-	s16 max_lpback_gain_hdB;
+-	s16 trsw_rx_gain_hdB;
+-	u8 power_vec[8];
+-
+-	u16 rc_cal;
+-	int nrssi_table_delta;
+-	int nrssi_slope_scale;
+-	int nrssi_slope_offset;
+-	int min_rssi;
+-	int max_rssi;
+-
+-	s8 txpwridx;
+-	u8 min_txpower;
+-
+-	u8 a_band_high_disable;
+-
+-	u16 tx_vos;
+-	u16 global_tx_bb_dc_bias_loft;
+-
+-	int rf_max;
+-	int bb_max;
+-	int rf_list_size;
+-	int bb_list_size;
+-	u16 *rf_attn_list;
+-	u16 *bb_attn_list;
+-	u16 padmix_mask;
+-	u16 padmix_reg;
+-	u16 *txmag_list;
+-	uint txmag_len;
+-	bool txmag_enable;
+-
+-	s8 *a_tssi_to_dbm;
+-	s8 *m_tssi_to_dbm;
+-	s8 *l_tssi_to_dbm;
+-	s8 *h_tssi_to_dbm;
+-	u8 *hwtxpwr;
+-
+-	u16 freqtrack_saved_regs[2];
+-	int cur_interference_mode;
+-	bool hwpwrctrl_capable;
+-	bool temppwrctrl_capable;
+-
+-	uint phycal_nslope;
+-	uint phycal_noffset;
+-	uint phycal_mlo;
+-	uint phycal_txpower;
+-
+-	u8 phy_aa2g;
+-
+-	bool nphy_tableloaded;
+-	s8 nphy_rssisel;
+-	u32 nphy_bb_mult_save;
+-	u16 nphy_txiqlocal_bestc[11];
+-	bool nphy_txiqlocal_coeffsvalid;
+-	phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2];
+-	phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2];
+-	u16 cck2gpo;
+-	u32 ofdm2gpo;
+-	u32 ofdm5gpo;
+-	u32 ofdm5glpo;
+-	u32 ofdm5ghpo;
+-	u8 bw402gpo;
+-	u8 bw405gpo;
+-	u8 bw405glpo;
+-	u8 bw405ghpo;
+-	u8 cdd2gpo;
+-	u8 cdd5gpo;
+-	u8 cdd5glpo;
+-	u8 cdd5ghpo;
+-	u8 stbc2gpo;
+-	u8 stbc5gpo;
+-	u8 stbc5glpo;
+-	u8 stbc5ghpo;
+-	u8 bwdup2gpo;
+-	u8 bwdup5gpo;
+-	u8 bwdup5glpo;
+-	u8 bwdup5ghpo;
+-	u16 mcs2gpo[8];
+-	u16 mcs5gpo[8];
+-	u16 mcs5glpo[8];
+-	u16 mcs5ghpo[8];
+-	u32 nphy_rxcalparams;
+-
+-	u8 phy_spuravoid;
+-	bool phy_isspuravoid;
+-
+-	u8 phy_pabias;
+-	u8 nphy_papd_skip;
+-	u8 nphy_tssi_slope;
+-
+-	s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
+-	u8 nphy_noise_index;
+-
+-	u8 nphy_txpid2g[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5g[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5gl[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5gh[PHY_CORE_NUM_2];
+-
+-	bool nphy_gain_boost;
+-	bool nphy_elna_gain_config;
+-	u16 old_bphy_test;
+-	u16 old_bphy_testcontrol;
+-
+-	bool phyhang_avoid;
+-
+-	bool rssical_nphy;
+-	u8 nphy_perical;
+-	uint nphy_perical_last;
+-	u8 cal_type_override;
+-	u8 mphase_cal_phase_id;
+-	u8 mphase_txcal_cmdidx;
+-	u8 mphase_txcal_numcmds;
+-	u16 mphase_txcal_bestcoeffs[11];
+-	chanspec_t nphy_txiqlocal_chanspec;
+-	chanspec_t nphy_iqcal_chanspec_2G;
+-	chanspec_t nphy_iqcal_chanspec_5G;
+-	chanspec_t nphy_rssical_chanspec_2G;
+-	chanspec_t nphy_rssical_chanspec_5G;
+-	struct wlapi_timer *phycal_timer;
+-	bool use_int_tx_iqlo_cal_nphy;
+-	bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
+-	s16 nphy_lastcal_temp;
+-
+-	txiqcal_cache_t calibration_cache;
+-	rssical_cache_t rssical_cache;
+-
+-	u8 nphy_txpwr_idx[2];
+-	u8 nphy_papd_cal_type;
+-	uint nphy_papd_last_cal;
+-	u16 nphy_papd_tx_gain_at_last_cal[2];
+-	u8 nphy_papd_cal_gain_index[2];
+-	s16 nphy_papd_epsilon_offset[2];
+-	bool nphy_papd_recal_enable;
+-	u32 nphy_papd_recal_counter;
+-	bool nphy_force_papd_cal;
+-	bool nphy_papdcomp;
+-	bool ipa2g_on;
+-	bool ipa5g_on;
+-
+-	u16 classifier_state;
+-	u16 clip_state[2];
+-	uint nphy_deaf_count;
+-	u8 rxiq_samps;
+-	u8 rxiq_antsel;
+-
+-	u16 rfctrlIntc1_save;
+-	u16 rfctrlIntc2_save;
+-	bool first_cal_after_assoc;
+-	u16 tx_rx_cal_radio_saveregs[22];
+-	u16 tx_rx_cal_phy_saveregs[15];
+-
+-	u8 nphy_cal_orig_pwr_idx[2];
+-	u8 nphy_txcal_pwr_idx[2];
+-	u8 nphy_rxcal_pwr_idx[2];
+-	u16 nphy_cal_orig_tx_gain[2];
+-	nphy_txgains_t nphy_cal_target_gain;
+-	u16 nphy_txcal_bbmult;
+-	u16 nphy_gmval;
+-
+-	u16 nphy_saved_bbconf;
+-
+-	bool nphy_gband_spurwar_en;
+-	bool nphy_gband_spurwar2_en;
+-	bool nphy_aband_spurwar_en;
+-	u16 nphy_rccal_value;
+-	u16 nphy_crsminpwr[3];
+-	phy_noisevar_buf_t nphy_saved_noisevars;
+-	bool nphy_anarxlpf_adjusted;
+-	bool nphy_crsminpwr_adjusted;
+-	bool nphy_noisevars_adjusted;
+-
+-	bool nphy_rxcal_active;
+-	u16 radar_percal_mask;
+-	bool dfs_lp_buffer_nphy;
+-
+-	u16 nphy_fineclockgatecontrol;
+-
+-	s8 rx2tx_biasentry;
+-
+-	u16 crsminpwr0;
+-	u16 crsminpwrl0;
+-	u16 crsminpwru0;
+-	s16 noise_crsminpwr_index;
+-	u16 init_gain_core1;
+-	u16 init_gain_core2;
+-	u16 init_gainb_core1;
+-	u16 init_gainb_core2;
+-	u8 aci_noise_curr_channel;
+-	u16 init_gain_rfseq[4];
+-
+-	bool radio_is_on;
+-
+-	bool nphy_sample_play_lpf_bw_ctl_ovr;
+-
+-	u16 tbl_data_hi;
+-	u16 tbl_data_lo;
+-	u16 tbl_addr;
+-
+-	uint tbl_save_id;
+-	uint tbl_save_offset;
+-
+-	u8 txpwrctrl;
+-	s8 txpwrindex[PHY_CORE_MAX];
+-
+-	u8 phycal_tempdelta;
+-	u32 mcs20_po;
+-	u32 mcs40_po;
+-	struct wiphy *wiphy;
+-};
+-
+-typedef s32 fixed;
+-
+-typedef struct _cs32 {
+-	fixed q;
+-	fixed i;
+-} cs32;
+-
+-typedef struct radio_regs {
+-	u16 address;
+-	u32 init_a;
+-	u32 init_g;
+-	u8 do_init_a;
+-	u8 do_init_g;
+-} radio_regs_t;
+-
+-typedef struct radio_20xx_regs {
+-	u16 address;
+-	u8 init;
+-	u8 do_init;
+-} radio_20xx_regs_t;
+-
+-typedef struct lcnphy_radio_regs {
+-	u16 address;
+-	u8 init_a;
+-	u8 init_g;
+-	u8 do_init_a;
+-	u8 do_init_g;
+-} lcnphy_radio_regs_t;
+-
+-extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[];
+-extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[];
+-extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[],
+-    regs_RX_2056[];
+-extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[];
+-extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
+-    regs_RX_2056_rev5[];
+-extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
+-    regs_RX_2056_rev6[];
+-extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
+-    regs_RX_2056_rev7[];
+-extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
+-    regs_RX_2056_rev8[];
+-extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[];
+-extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[];
+-
+-extern char *phy_getvar(phy_info_t *pi, const char *name);
+-extern int phy_getintvar(phy_info_t *pi, const char *name);
+-#define PHY_GETVAR(pi, name)	phy_getvar(pi, name)
+-#define PHY_GETINTVAR(pi, name)	phy_getintvar(pi, name)
+-
+-extern u16 read_phy_reg(phy_info_t *pi, u16 addr);
+-extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val);
+-
+-extern u16 read_radio_reg(phy_info_t *pi, u16 addr);
+-extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask,
+-			  u16 val);
+-extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask);
+-
+-extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-
+-extern void wlc_phyreg_enter(wlc_phy_t *pih);
+-extern void wlc_phyreg_exit(wlc_phy_t *pih);
+-extern void wlc_radioreg_enter(wlc_phy_t *pih);
+-extern void wlc_radioreg_exit(wlc_phy_t *pih);
+-
+-extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-			       u16 tblAddr, u16 tblDataHi,
+-			       u16 tblDatalo);
+-extern void wlc_phy_write_table(phy_info_t *pi,
+-				const phytbl_info_t *ptbl_info, u16 tblAddr,
+-				u16 tblDataHi, u16 tblDatalo);
+-extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+-			       u16 tblAddr, u16 tblDataHi,
+-			       u16 tblDataLo);
+-extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val);
+-
+-extern void write_phy_channel_reg(phy_info_t *pi, uint val);
+-extern void wlc_phy_txpower_update_shm(phy_info_t *pi);
+-
+-extern void wlc_phy_cordic(fixed theta, cs32 *val);
+-extern u8 wlc_phy_nbits(s32 value);
+-extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
+-
+-extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi,
+-					     radio_20xx_regs_t *radioregs);
+-extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+-				    u16 core_offset);
+-
+-extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi);
+-
+-extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on);
+-extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
+-					s32 *eps_imag);
+-
+-extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi);
+-extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi);
+-
+-extern bool wlc_phy_attach_nphy(phy_info_t *pi);
+-extern bool wlc_phy_attach_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_detach_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_init_nphy(phy_info_t *pi);
+-extern void wlc_phy_init_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_cal_init_nphy(phy_info_t *pi);
+-extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec);
+-extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec);
+-extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi,
+-					      chanspec_t chanspec);
+-extern int wlc_phy_channel2freq(uint channel);
+-extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
+-extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t);
+-
+-extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode);
+-extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi);
+-
+-extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi);
+-extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi);
+-extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index);
+-extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable);
+-extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi);
+-extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz,
+-				     u16 max_val, bool iqcalmode);
+-
+-extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan,
+-					       u8 *max_pwr, u8 rate_id);
+-extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
+-					    u8 rate_mcs_end,
+-					    u8 rate_ofdm_start);
+-extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
+-					    u8 rate_ofdm_start,
+-					    u8 rate_ofdm_end,
+-					    u8 rate_mcs_start);
+-
+-extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode);
+-extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode);
+-extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode);
+-extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode);
+-extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi);
+-extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel);
+-extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode);
+-extern void wlc_2064_vco_cal(phy_info_t *pi);
+-
+-extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
+-
+-#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
+-#define LCNPHY_TX_POWER_TABLE_SIZE	128
+-#define LCNPHY_MAX_TX_POWER_INDEX	(LCNPHY_TX_POWER_TABLE_SIZE - 1)
+-#define LCNPHY_TBL_ID_TXPWRCTL 	0x07
+-#define LCNPHY_TX_PWR_CTRL_OFF	0
+-#define LCNPHY_TX_PWR_CTRL_SW		(0x1 << 15)
+-#define LCNPHY_TX_PWR_CTRL_HW         ((0x1 << 15) | \
+-					(0x1 << 14) | \
+-					(0x1 << 13))
+-
+-#define LCNPHY_TX_PWR_CTRL_TEMPBASED	0xE001
+-
+-extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti);
+-extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti);
+-extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b);
+-extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq);
+-extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b);
+-extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi);
+-extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0,
+-				      u8 *eq0, u8 *fi0, u8 *fq0);
+-extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode);
+-extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode);
+-extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi);
+-extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi);
+-extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
+-extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr,
+-				s8 *cck_pwr);
+-extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi);
+-
+-extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index);
+-
+-#define NPHY_MAX_HPVGA1_INDEX		10
+-#define NPHY_DEF_HPVGA1_INDEXLIMIT	7
+-
+-typedef struct _phy_iq_est {
+-	s32 iq_prod;
+-	u32 i_pwr;
+-	u32 q_pwr;
+-} phy_iq_est_t;
+-
+-extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable);
+-extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode);
+-
+-#define wlc_phy_write_table_nphy(pi, pti)	wlc_phy_write_table(pi, pti, 0x72, \
+-	0x74, 0x73)
+-#define wlc_phy_read_table_nphy(pi, pti)	wlc_phy_read_table(pi, pti, 0x72, \
+-	0x74, 0x73)
+-#define wlc_nphy_table_addr(pi, id, off)	wlc_phy_table_addr((pi), (id), (off), \
+-	0x72, 0x74, 0x73)
+-#define wlc_nphy_table_data_write(pi, w, v)	wlc_phy_table_data_write((pi), (w), (v))
+-
+-extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o,
+-				    u32 w, void *d);
+-extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32,
+-				     u32, const void *);
+-
+-#define	PHY_IPA(pi) \
+-	((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
+-	 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
+-
+-#define WLC_PHY_WAR_PR51571(pi) \
+-	if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \
+-		(void)R_REG(&(pi)->regs->maccontrol)
+-
+-extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype);
+-extern void wlc_phy_aci_reset_nphy(phy_info_t *pi);
+-extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en);
+-
+-extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan);
+-extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on);
+-
+-extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi);
+-
+-extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd);
+-extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi);
+-
+-extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val);
+-
+-extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est,
+-				   u16 num_samps, u8 wait_time,
+-				   u8 wait_for_crs);
+-
+-extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write,
+-				      nphy_iq_comp_t *comp);
+-extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi);
+-
+-extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask);
+-extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih);
+-
+-extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type);
+-extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi);
+-extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi);
+-extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi);
+-extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi);
+-
+-extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi);
+-extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-				   bool full, bool m);
+-extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-				 u8 type, bool d);
+-extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask,
+-				     s8 txpwrindex, bool res);
+-extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type);
+-extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type,
+-				  s32 *rssi_buf, u8 nsamps);
+-extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi);
+-extern int wlc_phy_aci_scan_nphy(phy_info_t *pi);
+-extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower,
+-					bool debug);
+-extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-				u8 mode, u8, bool);
+-extern void wlc_phy_stopplayback_nphy(phy_info_t *pi);
+-extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf,
+-				     u8 num_samps);
+-extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi);
+-
+-extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh);
+-
+-#define NPHY_TESTPATTERN_BPHY_EVM   0
+-#define NPHY_TESTPATTERN_BPHY_RFCS  1
+-
+-extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs);
+-
+-void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset,
+-				s8 *ofdmoffset);
+-extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi,
+-				    chanspec_t chanspec);
+-
+-extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih);
+-#endif				/* _wlc_phy_int_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
+deleted file mode 100644
+index b8864c5..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
++++ /dev/null
+@@ -1,5302 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/bitops.h>
+-#include <linux/delay.h>
+-#include <wlc_cfg.h>
+-#include <linux/pci.h>
+-#include <aiutils.h>
+-#include <wlc_pmu.h>
+-#include <bcmnvram.h>
+-
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_phy_radio.h"
+-#include "wlc_phy_int.h"
+-#include "wlc_phy_qmath.h"
+-#include "wlc_phy_lcn.h"
+-#include "wlc_phytbl_lcn.h"
+-
+-#define PLL_2064_NDIV		90
+-#define PLL_2064_LOW_END_VCO 	3000
+-#define PLL_2064_LOW_END_KVCO 	27
+-#define PLL_2064_HIGH_END_VCO	4200
+-#define PLL_2064_HIGH_END_KVCO	68
+-#define PLL_2064_LOOP_BW_DOUBLER	200
+-#define PLL_2064_D30_DOUBLER		10500
+-#define PLL_2064_LOOP_BW	260
+-#define PLL_2064_D30		8000
+-#define PLL_2064_CAL_REF_TO	8
+-#define PLL_2064_MHZ		1000000
+-#define PLL_2064_OPEN_LOOP_DELAY	5
+-
+-#define TEMPSENSE 			1
+-#define VBATSENSE           2
+-
+-#define NOISE_IF_UPD_CHK_INTERVAL	1
+-#define NOISE_IF_UPD_RST_INTERVAL	60
+-#define NOISE_IF_UPD_THRESHOLD_CNT	1
+-#define NOISE_IF_UPD_TRHRESHOLD	50
+-#define NOISE_IF_UPD_TIMEOUT		1000
+-#define NOISE_IF_OFF			0
+-#define NOISE_IF_CHK			1
+-#define NOISE_IF_ON			2
+-
+-#define PAPD_BLANKING_PROFILE 		3
+-#define PAPD2LUT			0
+-#define PAPD_CORR_NORM 			0
+-#define PAPD_BLANKING_THRESHOLD 	0
+-#define PAPD_STOP_AFTER_LAST_UPDATE	0
+-
+-#define LCN_TARGET_PWR  60
+-
+-#define LCN_VBAT_OFFSET_433X 34649679
+-#define LCN_VBAT_SLOPE_433X  8258032
+-
+-#define LCN_VBAT_SCALE_NOM  53
+-#define LCN_VBAT_SCALE_DEN  432
+-
+-#define LCN_TEMPSENSE_OFFSET  80812
+-#define LCN_TEMPSENSE_DEN  2647
+-
+-#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
+-	(0 + 8)
+-#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
+-	(0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
+-
+-#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
+-	(0 + 8)
+-#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
+-	(0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
+-
+-#define wlc_lcnphy_enable_tx_gain_override(pi) \
+-	wlc_lcnphy_set_tx_gain_override(pi, true)
+-#define wlc_lcnphy_disable_tx_gain_override(pi) \
+-	wlc_lcnphy_set_tx_gain_override(pi, false)
+-
+-#define wlc_lcnphy_iqcal_active(pi)	\
+-	(read_phy_reg((pi), 0x451) & \
+-	((0x1 << 15) | (0x1 << 14)))
+-
+-#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
+-#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \
+-	(pi->temppwrctrl_capable)
+-#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
+-	(pi->hwpwrctrl_capable)
+-
+-#define SWCTRL_BT_TX		0x18
+-#define SWCTRL_OVR_DISABLE	0x40
+-
+-#define	AFE_CLK_INIT_MODE_TXRX2X	1
+-#define	AFE_CLK_INIT_MODE_PAPD		0
+-
+-#define LCNPHY_TBL_ID_IQLOCAL			0x00
+-
+-#define LCNPHY_TBL_ID_RFSEQ         0x08
+-#define LCNPHY_TBL_ID_GAIN_IDX		0x0d
+-#define LCNPHY_TBL_ID_SW_CTRL			0x0f
+-#define LCNPHY_TBL_ID_GAIN_TBL		0x12
+-#define LCNPHY_TBL_ID_SPUR			0x14
+-#define LCNPHY_TBL_ID_SAMPLEPLAY		0x15
+-#define LCNPHY_TBL_ID_SAMPLEPLAY1		0x16
+-
+-#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 	832
+-#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 	128
+-#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 	192
+-#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET		320
+-#define LCNPHY_TX_PWR_CTRL_LO_OFFSET		448
+-#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET		576
+-
+-#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313	140
+-
+-#define LCNPHY_TX_PWR_CTRL_START_NPT		1
+-#define LCNPHY_TX_PWR_CTRL_MAX_NPT			7
+-
+-#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
+-
+-#define LCNPHY_ACI_DETECT_START      1
+-#define LCNPHY_ACI_DETECT_PROGRESS   2
+-#define LCNPHY_ACI_DETECT_STOP       3
+-
+-#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
+-#define LCNPHY_ACI_GLITCH_TRSH 2000
+-#define	LCNPHY_ACI_TMOUT 250
+-#define LCNPHY_ACI_DETECT_TIMEOUT  2
+-#define LCNPHY_ACI_START_DELAY 0
+-
+-#define wlc_lcnphy_tx_gain_override_enabled(pi) \
+-	(0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
+-
+-#define wlc_lcnphy_total_tx_frames(pi) \
+-	wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + offsetof(macstat_t, txallfrm))
+-
+-typedef struct {
+-	u16 gm_gain;
+-	u16 pga_gain;
+-	u16 pad_gain;
+-	u16 dac_gain;
+-} lcnphy_txgains_t;
+-
+-typedef enum {
+-	LCNPHY_CAL_FULL,
+-	LCNPHY_CAL_RECAL,
+-	LCNPHY_CAL_CURRECAL,
+-	LCNPHY_CAL_DIGCAL,
+-	LCNPHY_CAL_GCTRL
+-} lcnphy_cal_mode_t;
+-
+-typedef struct {
+-	lcnphy_txgains_t gains;
+-	bool useindex;
+-	u8 index;
+-} lcnphy_txcalgains_t;
+-
+-typedef struct {
+-	u8 chan;
+-	s16 a;
+-	s16 b;
+-} lcnphy_rx_iqcomp_t;
+-
+-typedef struct {
+-	s16 re;
+-	s16 im;
+-} lcnphy_spb_tone_t;
+-
+-typedef struct {
+-	u16 re;
+-	u16 im;
+-} lcnphy_unsign16_struct;
+-
+-typedef struct {
+-	u32 iq_prod;
+-	u32 i_pwr;
+-	u32 q_pwr;
+-} lcnphy_iq_est_t;
+-
+-typedef struct {
+-	u16 ptcentreTs20;
+-	u16 ptcentreFactor;
+-} lcnphy_sfo_cfg_t;
+-
+-typedef enum {
+-	LCNPHY_PAPD_CAL_CW,
+-	LCNPHY_PAPD_CAL_OFDM
+-} lcnphy_papd_cal_type_t;
+-
+-typedef u16 iqcal_gain_params_lcnphy[9];
+-
+-static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
+-	{0, 0, 0, 0, 0, 0, 0, 0, 0},
+-};
+-
+-static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
+-	tbl_iqcal_gainparams_lcnphy_2G,
+-};
+-
+-static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
+-	sizeof(tbl_iqcal_gainparams_lcnphy_2G) /
+-	    sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
+-};
+-
+-static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = {
+-	{965, 1087},
+-	{967, 1085},
+-	{969, 1082},
+-	{971, 1080},
+-	{973, 1078},
+-	{975, 1076},
+-	{977, 1073},
+-	{979, 1071},
+-	{981, 1069},
+-	{983, 1067},
+-	{985, 1065},
+-	{987, 1063},
+-	{989, 1060},
+-	{994, 1055}
+-};
+-
+-static const
+-u16 lcnphy_iqcal_loft_gainladder[] = {
+-	((2 << 8) | 0),
+-	((3 << 8) | 0),
+-	((4 << 8) | 0),
+-	((6 << 8) | 0),
+-	((8 << 8) | 0),
+-	((11 << 8) | 0),
+-	((16 << 8) | 0),
+-	((16 << 8) | 1),
+-	((16 << 8) | 2),
+-	((16 << 8) | 3),
+-	((16 << 8) | 4),
+-	((16 << 8) | 5),
+-	((16 << 8) | 6),
+-	((16 << 8) | 7),
+-	((23 << 8) | 7),
+-	((32 << 8) | 7),
+-	((45 << 8) | 7),
+-	((64 << 8) | 7),
+-	((91 << 8) | 7),
+-	((128 << 8) | 7)
+-};
+-
+-static const
+-u16 lcnphy_iqcal_ir_gainladder[] = {
+-	((1 << 8) | 0),
+-	((2 << 8) | 0),
+-	((4 << 8) | 0),
+-	((6 << 8) | 0),
+-	((8 << 8) | 0),
+-	((11 << 8) | 0),
+-	((16 << 8) | 0),
+-	((23 << 8) | 0),
+-	((32 << 8) | 0),
+-	((45 << 8) | 0),
+-	((64 << 8) | 0),
+-	((64 << 8) | 1),
+-	((64 << 8) | 2),
+-	((64 << 8) | 3),
+-	((64 << 8) | 4),
+-	((64 << 8) | 5),
+-	((64 << 8) | 6),
+-	((64 << 8) | 7),
+-	((91 << 8) | 7),
+-	((128 << 8) | 7)
+-};
+-
+-static const
+-lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = {
+-	{88, 0},
+-	{73, 49},
+-	{34, 81},
+-	{-17, 86},
+-	{-62, 62},
+-	{-86, 17},
+-	{-81, -34},
+-	{-49, -73},
+-	{0, -88},
+-	{49, -73},
+-	{81, -34},
+-	{86, 17},
+-	{62, 62},
+-	{17, 86},
+-	{-34, 81},
+-	{-73, 49},
+-	{-88, 0},
+-	{-73, -49},
+-	{-34, -81},
+-	{17, -86},
+-	{62, -62},
+-	{86, -17},
+-	{81, 34},
+-	{49, 73},
+-	{0, 88},
+-	{-49, 73},
+-	{-81, 34},
+-	{-86, -17},
+-	{-62, -62},
+-	{-17, -86},
+-	{34, -81},
+-	{73, -49},
+-};
+-
+-static const
+-u16 iqlo_loopback_rf_regs[20] = {
+-	RADIO_2064_REG036,
+-	RADIO_2064_REG11A,
+-	RADIO_2064_REG03A,
+-	RADIO_2064_REG025,
+-	RADIO_2064_REG028,
+-	RADIO_2064_REG005,
+-	RADIO_2064_REG112,
+-	RADIO_2064_REG0FF,
+-	RADIO_2064_REG11F,
+-	RADIO_2064_REG00B,
+-	RADIO_2064_REG113,
+-	RADIO_2064_REG007,
+-	RADIO_2064_REG0FC,
+-	RADIO_2064_REG0FD,
+-	RADIO_2064_REG012,
+-	RADIO_2064_REG057,
+-	RADIO_2064_REG059,
+-	RADIO_2064_REG05C,
+-	RADIO_2064_REG078,
+-	RADIO_2064_REG092,
+-};
+-
+-static const
+-u16 tempsense_phy_regs[14] = {
+-	0x503,
+-	0x4a4,
+-	0x4d0,
+-	0x4d9,
+-	0x4da,
+-	0x4a6,
+-	0x938,
+-	0x939,
+-	0x4d8,
+-	0x4d0,
+-	0x4d7,
+-	0x4a5,
+-	0x40d,
+-	0x4a2,
+-};
+-
+-static const
+-u16 rxiq_cal_rf_reg[11] = {
+-	RADIO_2064_REG098,
+-	RADIO_2064_REG116,
+-	RADIO_2064_REG12C,
+-	RADIO_2064_REG06A,
+-	RADIO_2064_REG00B,
+-	RADIO_2064_REG01B,
+-	RADIO_2064_REG113,
+-	RADIO_2064_REG01D,
+-	RADIO_2064_REG114,
+-	RADIO_2064_REG02E,
+-	RADIO_2064_REG12A,
+-};
+-
+-static const
+-lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = {
+-	{1, 0, 0},
+-	{2, 0, 0},
+-	{3, 0, 0},
+-	{4, 0, 0},
+-	{5, 0, 0},
+-	{6, 0, 0},
+-	{7, 0, 0},
+-	{8, 0, 0},
+-	{9, 0, 0},
+-	{10, 0, 0},
+-	{11, 0, 0},
+-	{12, 0, 0},
+-	{13, 0, 0},
+-	{14, 0, 0},
+-	{34, 0, 0},
+-	{38, 0, 0},
+-	{42, 0, 0},
+-	{46, 0, 0},
+-	{36, 0, 0},
+-	{40, 0, 0},
+-	{44, 0, 0},
+-	{48, 0, 0},
+-	{52, 0, 0},
+-	{56, 0, 0},
+-	{60, 0, 0},
+-	{64, 0, 0},
+-	{100, 0, 0},
+-	{104, 0, 0},
+-	{108, 0, 0},
+-	{112, 0, 0},
+-	{116, 0, 0},
+-	{120, 0, 0},
+-	{124, 0, 0},
+-	{128, 0, 0},
+-	{132, 0, 0},
+-	{136, 0, 0},
+-	{140, 0, 0},
+-	{149, 0, 0},
+-	{153, 0, 0},
+-	{157, 0, 0},
+-	{161, 0, 0},
+-	{165, 0, 0},
+-	{184, 0, 0},
+-	{188, 0, 0},
+-	{192, 0, 0},
+-	{196, 0, 0},
+-	{200, 0, 0},
+-	{204, 0, 0},
+-	{208, 0, 0},
+-	{212, 0, 0},
+-	{216, 0, 0},
+-};
+-
+-static const u32 lcnphy_23bitgaincode_table[] = {
+-	0x200100,
+-	0x200200,
+-	0x200004,
+-	0x200014,
+-	0x200024,
+-	0x200034,
+-	0x200134,
+-	0x200234,
+-	0x200334,
+-	0x200434,
+-	0x200037,
+-	0x200137,
+-	0x200237,
+-	0x200337,
+-	0x200437,
+-	0x000035,
+-	0x000135,
+-	0x000235,
+-	0x000037,
+-	0x000137,
+-	0x000237,
+-	0x000337,
+-	0x00013f,
+-	0x00023f,
+-	0x00033f,
+-	0x00034f,
+-	0x00044f,
+-	0x00144f,
+-	0x00244f,
+-	0x00254f,
+-	0x00354f,
+-	0x00454f,
+-	0x00464f,
+-	0x01464f,
+-	0x02464f,
+-	0x03464f,
+-	0x04464f,
+-};
+-
+-static const s8 lcnphy_gain_table[] = {
+-	-16,
+-	-13,
+-	10,
+-	7,
+-	4,
+-	0,
+-	3,
+-	6,
+-	9,
+-	12,
+-	15,
+-	18,
+-	21,
+-	24,
+-	27,
+-	30,
+-	33,
+-	36,
+-	39,
+-	42,
+-	45,
+-	48,
+-	50,
+-	53,
+-	56,
+-	59,
+-	62,
+-	65,
+-	68,
+-	71,
+-	74,
+-	77,
+-	80,
+-	83,
+-	86,
+-	89,
+-	92,
+-};
+-
+-static const s8 lcnphy_gain_index_offset_for_rssi[] = {
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	8,
+-	7,
+-	7,
+-	6,
+-	7,
+-	7,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	3,
+-	3,
+-	3,
+-	3,
+-	3,
+-	3,
+-	4,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	-1,
+-	-2,
+-	-2,
+-	-2
+-};
+-
+-extern const u8 spur_tbl_rev0[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev1;
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[];
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
+-
+-typedef struct _chan_info_2064_lcnphy {
+-	uint chan;
+-	uint freq;
+-	u8 logen_buftune;
+-	u8 logen_rccr_tx;
+-	u8 txrf_mix_tune_ctrl;
+-	u8 pa_input_tune_g;
+-	u8 logen_rccr_rx;
+-	u8 pa_rxrf_lna1_freq_tune;
+-	u8 pa_rxrf_lna2_freq_tune;
+-	u8 rxrf_rxrf_spare1;
+-} chan_info_2064_lcnphy_t;
+-
+-static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = {
+-	{1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-};
+-
+-lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = {
+-	{0x00, 0, 0, 0, 0},
+-	{0x01, 0x64, 0x64, 0, 0},
+-	{0x02, 0x20, 0x20, 0, 0},
+-	{0x03, 0x66, 0x66, 0, 0},
+-	{0x04, 0xf8, 0xf8, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0x10, 0x10, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0x37, 0x37, 0, 0},
+-	{0x0B, 0x6, 0x6, 0, 0},
+-	{0x0C, 0x55, 0x55, 0, 0},
+-	{0x0D, 0x8b, 0x8b, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0x5, 0x5, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0xe, 0xe, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0xb, 0xb, 0, 0},
+-	{0x14, 0x2, 0x2, 0, 0},
+-	{0x15, 0x12, 0x12, 0, 0},
+-	{0x16, 0x12, 0x12, 0, 0},
+-	{0x17, 0xc, 0xc, 0, 0},
+-	{0x18, 0xc, 0xc, 0, 0},
+-	{0x19, 0xc, 0xc, 0, 0},
+-	{0x1A, 0x8, 0x8, 0, 0},
+-	{0x1B, 0x2, 0x2, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0x1, 0x1, 0, 0},
+-	{0x1E, 0x12, 0x12, 0, 0},
+-	{0x1F, 0x6e, 0x6e, 0, 0},
+-	{0x20, 0x2, 0x2, 0, 0},
+-	{0x21, 0x23, 0x23, 0, 0},
+-	{0x22, 0x8, 0x8, 0, 0},
+-	{0x23, 0, 0, 0, 0},
+-	{0x24, 0, 0, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0x33, 0x33, 0, 0},
+-	{0x27, 0x55, 0x55, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x30, 0x30, 0, 0},
+-	{0x2A, 0xb, 0xb, 0, 0},
+-	{0x2B, 0x1b, 0x1b, 0, 0},
+-	{0x2C, 0x3, 0x3, 0, 0},
+-	{0x2D, 0x1b, 0x1b, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x20, 0x20, 0, 0},
+-	{0x30, 0xa, 0xa, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0x62, 0x62, 0, 0},
+-	{0x33, 0x19, 0x19, 0, 0},
+-	{0x34, 0x33, 0x33, 0, 0},
+-	{0x35, 0x77, 0x77, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x70, 0x70, 0, 0},
+-	{0x38, 0x3, 0x3, 0, 0},
+-	{0x39, 0xf, 0xf, 0, 0},
+-	{0x3A, 0x6, 0x6, 0, 0},
+-	{0x3B, 0xcf, 0xcf, 0, 0},
+-	{0x3C, 0x1a, 0x1a, 0, 0},
+-	{0x3D, 0x6, 0x6, 0, 0},
+-	{0x3E, 0x42, 0x42, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0xfb, 0xfb, 0, 0},
+-	{0x41, 0x9a, 0x9a, 0, 0},
+-	{0x42, 0x7a, 0x7a, 0, 0},
+-	{0x43, 0x29, 0x29, 0, 0},
+-	{0x44, 0, 0, 0, 0},
+-	{0x45, 0x8, 0x8, 0, 0},
+-	{0x46, 0xce, 0xce, 0, 0},
+-	{0x47, 0x27, 0x27, 0, 0},
+-	{0x48, 0x62, 0x62, 0, 0},
+-	{0x49, 0x6, 0x6, 0, 0},
+-	{0x4A, 0x58, 0x58, 0, 0},
+-	{0x4B, 0xf7, 0xf7, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0xb3, 0xb3, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0, 0, 0, 0},
+-	{0x51, 0x9, 0x9, 0, 0},
+-	{0x52, 0x5, 0x5, 0, 0},
+-	{0x53, 0x17, 0x17, 0, 0},
+-	{0x54, 0x38, 0x38, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0xb, 0xb, 0, 0},
+-	{0x58, 0, 0, 0, 0},
+-	{0x59, 0, 0, 0, 0},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0, 0, 0, 0},
+-	{0x5C, 0, 0, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x88, 0x88, 0, 0},
+-	{0x5F, 0xcc, 0xcc, 0, 0},
+-	{0x60, 0x74, 0x74, 0, 0},
+-	{0x61, 0x74, 0x74, 0, 0},
+-	{0x62, 0x74, 0x74, 0, 0},
+-	{0x63, 0x44, 0x44, 0, 0},
+-	{0x64, 0x77, 0x77, 0, 0},
+-	{0x65, 0x44, 0x44, 0, 0},
+-	{0x66, 0x77, 0x77, 0, 0},
+-	{0x67, 0x55, 0x55, 0, 0},
+-	{0x68, 0x77, 0x77, 0, 0},
+-	{0x69, 0x77, 0x77, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0x7f, 0x7f, 0, 0},
+-	{0x6C, 0x8, 0x8, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0x88, 0x88, 0, 0},
+-	{0x6F, 0x66, 0x66, 0, 0},
+-	{0x70, 0x66, 0x66, 0, 0},
+-	{0x71, 0x28, 0x28, 0, 0},
+-	{0x72, 0x55, 0x55, 0, 0},
+-	{0x73, 0x4, 0x4, 0, 0},
+-	{0x74, 0, 0, 0, 0},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0, 0, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0xd6, 0xd6, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0xb4, 0xb4, 0, 0},
+-	{0x84, 0x1, 0x1, 0, 0},
+-	{0x85, 0x20, 0x20, 0, 0},
+-	{0x86, 0x5, 0x5, 0, 0},
+-	{0x87, 0xff, 0xff, 0, 0},
+-	{0x88, 0x7, 0x7, 0, 0},
+-	{0x89, 0x77, 0x77, 0, 0},
+-	{0x8A, 0x77, 0x77, 0, 0},
+-	{0x8B, 0x77, 0x77, 0, 0},
+-	{0x8C, 0x77, 0x77, 0, 0},
+-	{0x8D, 0x8, 0x8, 0, 0},
+-	{0x8E, 0xa, 0xa, 0, 0},
+-	{0x8F, 0x8, 0x8, 0, 0},
+-	{0x90, 0x18, 0x18, 0, 0},
+-	{0x91, 0x5, 0x5, 0, 0},
+-	{0x92, 0x1f, 0x1f, 0, 0},
+-	{0x93, 0x10, 0x10, 0, 0},
+-	{0x94, 0x3, 0x3, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0xaa, 0xaa, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0x23, 0x23, 0, 0},
+-	{0x9A, 0x7, 0x7, 0, 0},
+-	{0x9B, 0xf, 0xf, 0, 0},
+-	{0x9C, 0x10, 0x10, 0, 0},
+-	{0x9D, 0x3, 0x3, 0, 0},
+-	{0x9E, 0x4, 0x4, 0, 0},
+-	{0x9F, 0x20, 0x20, 0, 0},
+-	{0xA0, 0, 0, 0, 0},
+-	{0xA1, 0, 0, 0, 0},
+-	{0xA2, 0, 0, 0, 0},
+-	{0xA3, 0, 0, 0, 0},
+-	{0xA4, 0x1, 0x1, 0, 0},
+-	{0xA5, 0x77, 0x77, 0, 0},
+-	{0xA6, 0x77, 0x77, 0, 0},
+-	{0xA7, 0x77, 0x77, 0, 0},
+-	{0xA8, 0x77, 0x77, 0, 0},
+-	{0xA9, 0x8c, 0x8c, 0, 0},
+-	{0xAA, 0x88, 0x88, 0, 0},
+-	{0xAB, 0x78, 0x78, 0, 0},
+-	{0xAC, 0x57, 0x57, 0, 0},
+-	{0xAD, 0x88, 0x88, 0, 0},
+-	{0xAE, 0, 0, 0, 0},
+-	{0xAF, 0x8, 0x8, 0, 0},
+-	{0xB0, 0x88, 0x88, 0, 0},
+-	{0xB1, 0, 0, 0, 0},
+-	{0xB2, 0x1b, 0x1b, 0, 0},
+-	{0xB3, 0x3, 0x3, 0, 0},
+-	{0xB4, 0x24, 0x24, 0, 0},
+-	{0xB5, 0x3, 0x3, 0, 0},
+-	{0xB6, 0x1b, 0x1b, 0, 0},
+-	{0xB7, 0x24, 0x24, 0, 0},
+-	{0xB8, 0x3, 0x3, 0, 0},
+-	{0xB9, 0, 0, 0, 0},
+-	{0xBA, 0xaa, 0xaa, 0, 0},
+-	{0xBB, 0, 0, 0, 0},
+-	{0xBC, 0x4, 0x4, 0, 0},
+-	{0xBD, 0, 0, 0, 0},
+-	{0xBE, 0x8, 0x8, 0, 0},
+-	{0xBF, 0x11, 0x11, 0, 0},
+-	{0xC0, 0, 0, 0, 0},
+-	{0xC1, 0, 0, 0, 0},
+-	{0xC2, 0x62, 0x62, 0, 0},
+-	{0xC3, 0x1e, 0x1e, 0, 0},
+-	{0xC4, 0x33, 0x33, 0, 0},
+-	{0xC5, 0x37, 0x37, 0, 0},
+-	{0xC6, 0, 0, 0, 0},
+-	{0xC7, 0x70, 0x70, 0, 0},
+-	{0xC8, 0x1e, 0x1e, 0, 0},
+-	{0xC9, 0x6, 0x6, 0, 0},
+-	{0xCA, 0x4, 0x4, 0, 0},
+-	{0xCB, 0x2f, 0x2f, 0, 0},
+-	{0xCC, 0xf, 0xf, 0, 0},
+-	{0xCD, 0, 0, 0, 0},
+-	{0xCE, 0xff, 0xff, 0, 0},
+-	{0xCF, 0x8, 0x8, 0, 0},
+-	{0xD0, 0x3f, 0x3f, 0, 0},
+-	{0xD1, 0x3f, 0x3f, 0, 0},
+-	{0xD2, 0x3f, 0x3f, 0, 0},
+-	{0xD3, 0, 0, 0, 0},
+-	{0xD4, 0, 0, 0, 0},
+-	{0xD5, 0, 0, 0, 0},
+-	{0xD6, 0xcc, 0xcc, 0, 0},
+-	{0xD7, 0, 0, 0, 0},
+-	{0xD8, 0x8, 0x8, 0, 0},
+-	{0xD9, 0x8, 0x8, 0, 0},
+-	{0xDA, 0x8, 0x8, 0, 0},
+-	{0xDB, 0x11, 0x11, 0, 0},
+-	{0xDC, 0, 0, 0, 0},
+-	{0xDD, 0x87, 0x87, 0, 0},
+-	{0xDE, 0x88, 0x88, 0, 0},
+-	{0xDF, 0x8, 0x8, 0, 0},
+-	{0xE0, 0x8, 0x8, 0, 0},
+-	{0xE1, 0x8, 0x8, 0, 0},
+-	{0xE2, 0, 0, 0, 0},
+-	{0xE3, 0, 0, 0, 0},
+-	{0xE4, 0, 0, 0, 0},
+-	{0xE5, 0xf5, 0xf5, 0, 0},
+-	{0xE6, 0x30, 0x30, 0, 0},
+-	{0xE7, 0x1, 0x1, 0, 0},
+-	{0xE8, 0, 0, 0, 0},
+-	{0xE9, 0xff, 0xff, 0, 0},
+-	{0xEA, 0, 0, 0, 0},
+-	{0xEB, 0, 0, 0, 0},
+-	{0xEC, 0x22, 0x22, 0, 0},
+-	{0xED, 0, 0, 0, 0},
+-	{0xEE, 0, 0, 0, 0},
+-	{0xEF, 0, 0, 0, 0},
+-	{0xF0, 0x3, 0x3, 0, 0},
+-	{0xF1, 0x1, 0x1, 0, 0},
+-	{0xF2, 0, 0, 0, 0},
+-	{0xF3, 0, 0, 0, 0},
+-	{0xF4, 0, 0, 0, 0},
+-	{0xF5, 0, 0, 0, 0},
+-	{0xF6, 0, 0, 0, 0},
+-	{0xF7, 0x6, 0x6, 0, 0},
+-	{0xF8, 0, 0, 0, 0},
+-	{0xF9, 0, 0, 0, 0},
+-	{0xFA, 0x40, 0x40, 0, 0},
+-	{0xFB, 0, 0, 0, 0},
+-	{0xFC, 0x1, 0x1, 0, 0},
+-	{0xFD, 0x80, 0x80, 0, 0},
+-	{0xFE, 0x2, 0x2, 0, 0},
+-	{0xFF, 0x10, 0x10, 0, 0},
+-	{0x100, 0x2, 0x2, 0, 0},
+-	{0x101, 0x1e, 0x1e, 0, 0},
+-	{0x102, 0x1e, 0x1e, 0, 0},
+-	{0x103, 0, 0, 0, 0},
+-	{0x104, 0x1f, 0x1f, 0, 0},
+-	{0x105, 0, 0x8, 0, 1},
+-	{0x106, 0x2a, 0x2a, 0, 0},
+-	{0x107, 0xf, 0xf, 0, 0},
+-	{0x108, 0, 0, 0, 0},
+-	{0x109, 0, 0, 0, 0},
+-	{0x10A, 0, 0, 0, 0},
+-	{0x10B, 0, 0, 0, 0},
+-	{0x10C, 0, 0, 0, 0},
+-	{0x10D, 0, 0, 0, 0},
+-	{0x10E, 0, 0, 0, 0},
+-	{0x10F, 0, 0, 0, 0},
+-	{0x110, 0, 0, 0, 0},
+-	{0x111, 0, 0, 0, 0},
+-	{0x112, 0, 0, 0, 0},
+-	{0x113, 0, 0, 0, 0},
+-	{0x114, 0, 0, 0, 0},
+-	{0x115, 0, 0, 0, 0},
+-	{0x116, 0, 0, 0, 0},
+-	{0x117, 0, 0, 0, 0},
+-	{0x118, 0, 0, 0, 0},
+-	{0x119, 0, 0, 0, 0},
+-	{0x11A, 0, 0, 0, 0},
+-	{0x11B, 0, 0, 0, 0},
+-	{0x11C, 0x1, 0x1, 0, 0},
+-	{0x11D, 0, 0, 0, 0},
+-	{0x11E, 0, 0, 0, 0},
+-	{0x11F, 0, 0, 0, 0},
+-	{0x120, 0, 0, 0, 0},
+-	{0x121, 0, 0, 0, 0},
+-	{0x122, 0x80, 0x80, 0, 0},
+-	{0x123, 0, 0, 0, 0},
+-	{0x124, 0xf8, 0xf8, 0, 0},
+-	{0x125, 0, 0, 0, 0},
+-	{0x126, 0, 0, 0, 0},
+-	{0x127, 0, 0, 0, 0},
+-	{0x128, 0, 0, 0, 0},
+-	{0x129, 0, 0, 0, 0},
+-	{0x12A, 0, 0, 0, 0},
+-	{0x12B, 0, 0, 0, 0},
+-	{0x12C, 0, 0, 0, 0},
+-	{0x12D, 0, 0, 0, 0},
+-	{0x12E, 0, 0, 0, 0},
+-	{0x12F, 0, 0, 0, 0},
+-	{0x130, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-#define LCNPHY_NUM_DIG_FILT_COEFFS 16
+-#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
+-
+-u16
+-    LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
+-    [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+-	{0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
+-	 128, 64,},
+-	{1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
+-	 167, 93,},
+-	{2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
+-	 128, 64,},
+-	{3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
+-	 170, 340, 170,},
+-	{20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
+-	 256, 185, 256,},
+-	{21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
+-	 256, 273, 256,},
+-	{22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
+-	 256, 352, 256,},
+-	{23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
+-	 128, 233, 128,},
+-	{24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
+-	 1881, 256,},
+-	{25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
+-	 1881, 256,},
+-	{26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
+-	 384, 288,},
+-	{27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
+-	 128, 384, 288,},
+-	{30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
+-	 170, 340, 170,},
+-};
+-
+-#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
+-u16
+-    LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
+-    [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+-	{0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
+-	 0x278, 0xfea0, 0x80, 0x100, 0x80,},
+-	{1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
+-	 750, 0xFE2B, 212, 0xFFCE, 212,},
+-	{2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
+-	 0xFEF2, 128, 0xFFE2, 128}
+-};
+-
+-#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
+-	mod_phy_reg(pi, 0x4a4, \
+-		(0x1ff << 0), \
+-		(u16)(idx) << 0)
+-
+-#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
+-	mod_phy_reg(pi, 0x4a5, \
+-		(0x7 << 8), \
+-		(u16)(npt) << 8)
+-
+-#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
+-	(read_phy_reg((pi), 0x4a4) & \
+-			((0x1 << 15) | \
+-			(0x1 << 14) | \
+-			(0x1 << 13)))
+-
+-#define wlc_lcnphy_get_tx_pwr_npt(pi) \
+-	((read_phy_reg(pi, 0x4a5) & \
+-		(0x7 << 8)) >> \
+-		8)
+-
+-#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
+-	(read_phy_reg(pi, 0x473) & 0x1ff)
+-
+-#define wlc_lcnphy_get_target_tx_pwr(pi) \
+-	((read_phy_reg(pi, 0x4a7) & \
+-		(0xff << 0)) >> \
+-		0)
+-
+-#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
+-	mod_phy_reg(pi, 0x4a7, \
+-		(0xff << 0), \
+-		(u16)(target) << 0)
+-
+-#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
+-#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
+-
+-#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
+-#define FIXED_TXPWR 78
+-#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
+-
+-static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor,
+-				      u8 precision);
+-static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+-						   u16 ext_lna, u16 trsw,
+-						   u16 biq2, u16 biq1,
+-						   u16 tia, u16 lna2,
+-						   u16 lna1);
+-static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi);
+-static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain);
+-static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx);
+-static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0);
+-static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi);
+-static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains);
+-static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable);
+-static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi);
+-static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable);
+-static void wlc_lcnphy_set_tx_gain(phy_info_t *pi,
+-				   lcnphy_txgains_t *target_gains);
+-static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, u16 num_samps,
+-				 u8 wait_time, lcnphy_iq_est_t *iq_est);
+-static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps);
+-static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi);
+-static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode);
+-extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi);
+-static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi,
+-						    u8 channel);
+-
+-static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi,
+-					  const lcnphy_tx_gain_tbl_entry *g);
+-
+-static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo,
+-				u16 thresh, s16 *ptr, int mode);
+-static int wlc_lcnphy_calc_floor(s16 coeff, int type);
+-static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi,
+-					u16 *values_to_save);
+-static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi,
+-						u16 *values_to_save);
+-static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x,
+-			      s16 coeff_y);
+-static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type);
+-static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type,
+-			  int num_levels, int step_size_lg2);
+-static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi);
+-
+-static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi,
+-					   chanspec_t chanspec);
+-static void wlc_lcnphy_agc_temp_init(phy_info_t *pi);
+-static void wlc_lcnphy_temp_adj(phy_info_t *pi);
+-static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi);
+-static void wlc_lcnphy_baseband_init(phy_info_t *pi);
+-static void wlc_lcnphy_radio_init(phy_info_t *pi);
+-static void wlc_lcnphy_rc_cal(phy_info_t *pi);
+-static void wlc_lcnphy_rcal(phy_info_t *pi);
+-static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable);
+-static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm,
+-					 s16 filt_type);
+-static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b);
+-
+-void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti)
+-{
+-	wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
+-}
+-
+-void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti)
+-{
+-	wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
+-}
+-
+-static void
+-wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id,
+-			     const void *tbl_ptr, u32 tbl_len,
+-			     u32 tbl_width, u32 tbl_offset)
+-{
+-	phytbl_info_t tab;
+-	tab.tbl_id = tbl_id;
+-	tab.tbl_ptr = tbl_ptr;
+-	tab.tbl_len = tbl_len;
+-	tab.tbl_width = tbl_width;
+-	tab.tbl_offset = tbl_offset;
+-	wlc_lcnphy_read_table(pi, &tab);
+-}
+-
+-static void
+-wlc_lcnphy_common_write_table(phy_info_t *pi, u32 tbl_id,
+-			      const void *tbl_ptr, u32 tbl_len,
+-			      u32 tbl_width, u32 tbl_offset)
+-{
+-
+-	phytbl_info_t tab;
+-	tab.tbl_id = tbl_id;
+-	tab.tbl_ptr = tbl_ptr;
+-	tab.tbl_len = tbl_len;
+-	tab.tbl_width = tbl_width;
+-	tab.tbl_offset = tbl_offset;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-static u32
+-wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
+-{
+-	u32 quotient, remainder, roundup, rbit;
+-
+-	quotient = dividend / divisor;
+-	remainder = dividend % divisor;
+-	rbit = divisor & 1;
+-	roundup = (divisor >> 1) + rbit;
+-
+-	while (precision--) {
+-		quotient <<= 1;
+-		if (remainder >= roundup) {
+-			quotient++;
+-			remainder = ((remainder - roundup) << 1) + rbit;
+-		} else {
+-			remainder <<= 1;
+-		}
+-	}
+-
+-	if (remainder >= roundup)
+-		quotient++;
+-
+-	return quotient;
+-}
+-
+-static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
+-{
+-	int k;
+-	k = 0;
+-	if (type == 0) {
+-		if (coeff_x < 0) {
+-			k = (coeff_x - 1) / 2;
+-		} else {
+-			k = coeff_x / 2;
+-		}
+-	}
+-	if (type == 1) {
+-		if ((coeff_x + 1) < 0)
+-			k = (coeff_x) / 2;
+-		else
+-			k = (coeff_x + 1) / 2;
+-	}
+-	return k;
+-}
+-
+-s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi)
+-{
+-	s8 index;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (txpwrctrl_off(pi))
+-		index = pi_lcn->lcnphy_current_index;
+-	else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		index =
+-		    (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi)
+-			    / 2);
+-	else
+-		index = pi_lcn->lcnphy_current_index;
+-	return index;
+-}
+-
+-static u32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, u16 nsamples)
+-{
+-	lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+-
+-	if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
+-		return 0;
+-	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
+-}
+-
+-void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel)
+-{
+-	u16 afectrlovr, afectrlovrval;
+-	afectrlovr = read_phy_reg(pi, 0x43b);
+-	afectrlovrval = read_phy_reg(pi, 0x43c);
+-	if (channel != 0) {
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
+-
+-		write_phy_reg(pi, 0x44b, 0xffff);
+-		wlc_lcnphy_tx_pu(pi, 1);
+-
+-		mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
+-
+-		or_phy_reg(pi, 0x6da, 0x0080);
+-
+-		or_phy_reg(pi, 0x00a, 0x228);
+-	} else {
+-		and_phy_reg(pi, 0x00a, ~(0x228));
+-
+-		and_phy_reg(pi, 0x6da, 0xFF7F);
+-		write_phy_reg(pi, 0x43b, afectrlovr);
+-		write_phy_reg(pi, 0x43c, afectrlovrval);
+-	}
+-}
+-
+-static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi)
+-{
+-	u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
+-
+-	save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
+-	save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
+-}
+-
+-static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable)
+-{
+-	if (enable) {
+-		write_phy_reg(pi, 0x942, 0x7);
+-		write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
+-		write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
+-
+-		write_phy_reg(pi, 0x44a, 0x084);
+-		write_phy_reg(pi, 0x44a, 0x080);
+-		write_phy_reg(pi, 0x6d3, 0x2222);
+-		write_phy_reg(pi, 0x6d3, 0x2220);
+-	} else {
+-		write_phy_reg(pi, 0x942, 0x0);
+-		write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
+-		write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
+-	}
+-	wlapi_switch_macfreq(pi->sh->physhim, enable);
+-}
+-
+-void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	u8 channel = CHSPEC_CHANNEL(chanspec);
+-
+-	wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+-
+-	wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-
+-	if (!NORADIO_ENAB(pi->pubpi)) {
+-		wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
+-		udelay(1000);
+-	}
+-
+-	wlc_lcnphy_toggle_afe_pwdn(pi);
+-
+-	write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
+-	write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
+-
+-	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+-
+-		wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
+-	} else {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+-
+-		wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
+-	}
+-
+-	wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+-
+-}
+-
+-static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain)
+-{
+-	u16 dac_ctrl;
+-
+-	dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
+-	dac_ctrl = dac_ctrl & 0xc7f;
+-	dac_ctrl = dac_ctrl | (dac_gain << 7);
+-	mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
+-
+-}
+-
+-static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable)
+-{
+-	u16 bit = bEnable ? 1 : 0;
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
+-}
+-
+-static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi)
+-{
+-	u16 pa_gain;
+-
+-	pa_gain = (read_phy_reg(pi, 0x4fb) &
+-		   LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
+-	    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
+-
+-	return pa_gain;
+-}
+-
+-static void
+-wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains)
+-{
+-	u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
+-
+-	mod_phy_reg(pi, 0x4b5,
+-		    (0xffff << 0),
+-		    ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+-		    0);
+-	mod_phy_reg(pi, 0x4fb,
+-		    (0x7fff << 0),
+-		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+-
+-	mod_phy_reg(pi, 0x4fc,
+-		    (0xffff << 0),
+-		    ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+-		    0);
+-	mod_phy_reg(pi, 0x4fd,
+-		    (0x7fff << 0),
+-		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+-
+-	wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-}
+-
+-static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0)
+-{
+-	u16 m0m1 = (u16) m0 << 8;
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = &m0m1;
+-	tab.tbl_len = 1;
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_offset = 87;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi)
+-{
+-	u32 data_buf[64];
+-	phytbl_info_t tab;
+-
+-	memset(data_buf, 0, sizeof(data_buf));
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = data_buf;
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-
+-		tab.tbl_len = 30;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	tab.tbl_len = 64;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-typedef enum {
+-	LCNPHY_TSSI_PRE_PA,
+-	LCNPHY_TSSI_POST_PA,
+-	LCNPHY_TSSI_EXT
+-} lcnphy_tssi_mode_t;
+-
+-static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos)
+-{
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
+-
+-	if (LCNPHY_TSSI_POST_PA == pos) {
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
+-
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
+-			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+-		}
+-	} else {
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
+-
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+-			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+-		}
+-	}
+-	mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
+-
+-	if (LCNPHY_TSSI_EXT == pos) {
+-		write_radio_reg(pi, RADIO_2064_REG07F, 1);
+-		mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
+-		mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
+-		mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
+-	}
+-}
+-
+-static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi)
+-{
+-	u16 N1, N2, N3, N4, N5, N6, N;
+-	N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
+-	      >> 0);
+-	N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
+-		   >> 12);
+-	N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
+-	      >> 0);
+-	N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
+-		   >> 8);
+-	N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
+-	      >> 0);
+-	N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
+-		   >> 8);
+-	N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
+-	if (N < 1600)
+-		N = 1600;
+-	return N;
+-}
+-
+-static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi)
+-{
+-	u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	auxpga_vmid =
+-	    (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
+-	auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
+-	auxpga_gain_temp = 2;
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
+-
+-	mod_phy_reg(pi, 0x4db,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x4dc,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x40a,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x40b,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+-
+-	mod_phy_reg(pi, 0x40c,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+-
+-	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+-}
+-
+-static void wlc_lcnphy_tssi_setup(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 rfseq, ind;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &ind;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 0;
+-	for (ind = 0; ind < 128; ind++) {
+-		wlc_lcnphy_write_table(pi, &tab);
+-		tab.tbl_offset++;
+-	}
+-	tab.tbl_offset = 704;
+-	for (ind = 0; ind < 128; ind++) {
+-		wlc_lcnphy_write_table(pi, &tab);
+-		tab.tbl_offset++;
+-	}
+-	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
+-
+-	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
+-
+-	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
+-
+-	mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
+-
+-	wlc_lcnphy_clear_tx_power_offsets(pi);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
+-
+-	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+-		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-	} else {
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+-		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xc);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+-	} else {
+-		if (CHSPEC_IS2G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
+-	}
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+-	else
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-		mod_phy_reg(pi, 0x4d7,
+-			    (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
+-	}
+-
+-	rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &rfseq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 6;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
+-
+-	wlc_lcnphy_pwrctrl_rssiparams(pi);
+-}
+-
+-void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi)
+-{
+-	u16 tx_cnt, tx_total, npt;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	tx_total = wlc_lcnphy_total_tx_frames(pi);
+-	tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
+-	npt = wlc_lcnphy_get_tx_pwr_npt(pi);
+-
+-	if (tx_cnt > (1 << npt)) {
+-
+-		pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
+-
+-		pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+-		pi_lcn->lcnphy_tssi_npt = npt;
+-
+-	}
+-}
+-
+-s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
+-{
+-	s32 a, b, p;
+-
+-	a = 32768 + (a1 * tssi);
+-	b = (1024 * b0) + (64 * b1 * tssi);
+-	p = ((2 * b) + a) / (2 * a);
+-
+-	return p;
+-}
+-
+-static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi)
+-{
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
+-	pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
+-}
+-
+-void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM +
+-			  WLC_NUM_RATES_MCS_1_STREAM];
+-	uint i, j;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
+-
+-		if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM)
+-			j = TXP_FIRST_MCS_20_SISO;
+-
+-		rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
+-	}
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = ARRAY_SIZE(rate_table);
+-	tab.tbl_ptr = rate_table;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
+-		wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
+-
+-		wlc_lcnphy_txpower_reset_npt(pi);
+-	}
+-}
+-
+-static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index)
+-{
+-	u32 cck_offset[4] = { 22, 22, 22, 22 };
+-	u32 ofdm_offset, reg_offset_cck;
+-	int i;
+-	u16 index2;
+-	phytbl_info_t tab;
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
+-
+-	or_phy_reg(pi, 0x6da, 0x0040);
+-
+-	reg_offset_cck = 0;
+-	for (i = 0; i < 4; i++)
+-		cck_offset[i] -= reg_offset_cck;
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 4;
+-	tab.tbl_ptr = cck_offset;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-	ofdm_offset = 0;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &ofdm_offset;
+-	for (i = 836; i < 862; i++) {
+-		tab.tbl_offset = i;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
+-
+-	mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
+-
+-	index2 = (u16) (index * 2);
+-	mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+-
+-	mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
+-
+-}
+-
+-static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi)
+-{
+-	s8 index, delta_brd, delta_temp, new_index, tempcorrx;
+-	s16 manp, meas_temp, temp_diff;
+-	bool neg = 0;
+-	u16 temp;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		return pi_lcn->lcnphy_current_index;
+-
+-	index = FIXED_TXPWR;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return index;
+-
+-	if (pi_lcn->lcnphy_tempsense_slope == 0) {
+-		return index;
+-	}
+-	temp = (u16) wlc_lcnphy_tempsense(pi, 0);
+-	meas_temp = LCNPHY_TEMPSENSE(temp);
+-
+-	if (pi->tx_power_min != 0) {
+-		delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
+-	} else {
+-		delta_brd = 0;
+-	}
+-
+-	manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
+-	temp_diff = manp - meas_temp;
+-	if (temp_diff < 0) {
+-
+-		neg = 1;
+-
+-		temp_diff = -temp_diff;
+-	}
+-
+-	delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
+-						    (u32) (pi_lcn->
+-							      lcnphy_tempsense_slope
+-							      * 10), 0);
+-	if (neg)
+-		delta_temp = -delta_temp;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 3
+-	    && LCNREV_IS(pi->pubpi.phy_rev, 0))
+-		delta_temp = 0;
+-	if (pi_lcn->lcnphy_tempcorrx > 31)
+-		tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
+-	else
+-		tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		tempcorrx = 4;
+-	new_index =
+-	    index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
+-	new_index += tempcorrx;
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		index = 127;
+-	if (new_index < 0 || new_index > 126) {
+-		return index;
+-	}
+-	return new_index;
+-}
+-
+-static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode)
+-{
+-
+-	u16 current_mode = mode;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
+-	    mode == LCNPHY_TX_PWR_CTRL_HW)
+-		current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+-	    mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
+-		current_mode = LCNPHY_TX_PWR_CTRL_HW;
+-	return current_mode;
+-}
+-
+-void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode)
+-{
+-	u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	s8 index;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
+-	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 6),
+-		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
+-
+-	mod_phy_reg(pi, 0x6a3, (0x1 << 4),
+-		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
+-
+-	if (old_mode != mode) {
+-		if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
+-
+-			wlc_lcnphy_tx_pwr_update_npt(pi);
+-
+-			wlc_lcnphy_clear_tx_power_offsets(pi);
+-		}
+-		if (LCNPHY_TX_PWR_CTRL_HW == mode) {
+-
+-			wlc_lcnphy_txpower_recalc_target(pi);
+-
+-			wlc_lcnphy_set_start_tx_pwr_idx(pi,
+-							pi_lcn->
+-							lcnphy_tssi_idx);
+-			wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
+-			mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
+-
+-			pi_lcn->lcnphy_tssi_tx_cnt =
+-			    wlc_lcnphy_total_tx_frames(pi);
+-
+-			wlc_lcnphy_disable_tx_gain_override(pi);
+-			pi_lcn->lcnphy_tx_power_idx_override = -1;
+-		} else
+-			wlc_lcnphy_enable_tx_gain_override(pi);
+-
+-		mod_phy_reg(pi, 0x4a4,
+-			    ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
+-		if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
+-			index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+-			wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
+-			pi_lcn->lcnphy_current_index = (s8)
+-			    ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+-		}
+-	}
+-}
+-
+-static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi)
+-{
+-	uint delay_count = 0;
+-
+-	while (wlc_lcnphy_iqcal_active(pi)) {
+-		udelay(100);
+-		delay_count++;
+-
+-		if (delay_count > (10 * 500))
+-			break;
+-	}
+-
+-	return (0 == wlc_lcnphy_iqcal_active(pi));
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi,
+-		       lcnphy_txgains_t *target_gains,
+-		       lcnphy_cal_mode_t cal_mode, bool keep_tone)
+-{
+-
+-	lcnphy_txgains_t cal_gains, temp_gains;
+-	u16 hash;
+-	u8 band_idx;
+-	int j;
+-	u16 ncorr_override[5];
+-	u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+-	};
+-
+-	u16 commands_fullcal[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+-
+-	u16 commands_recal[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+-
+-	u16 command_nums_fullcal[] = {
+-		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+-
+-	u16 command_nums_recal[] = {
+-		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+-	u16 *command_nums = command_nums_fullcal;
+-
+-	u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
+-	u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
+-	u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
+-	bool tx_gain_override_old;
+-	lcnphy_txgains_t old_gains;
+-	uint i, n_cal_cmds = 0, n_cal_start = 0;
+-	u16 *values_to_save;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
+-	if (NULL == values_to_save) {
+-		return;
+-	}
+-
+-	save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+-	save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-
+-	or_phy_reg(pi, 0x6da, 0x40);
+-	or_phy_reg(pi, 0x6db, 0x3);
+-
+-	switch (cal_mode) {
+-	case LCNPHY_CAL_FULL:
+-		start_coeffs = syst_coeffs;
+-		cal_cmds = commands_fullcal;
+-		n_cal_cmds = ARRAY_SIZE(commands_fullcal);
+-		break;
+-
+-	case LCNPHY_CAL_RECAL:
+-		start_coeffs = syst_coeffs;
+-		cal_cmds = commands_recal;
+-		n_cal_cmds = ARRAY_SIZE(commands_recal);
+-		command_nums = command_nums_recal;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      start_coeffs, 11, 16, 64);
+-
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-	mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
+-
+-	tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
+-
+-	mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
+-
+-	mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
+-
+-	wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
+-
+-	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-	if (tx_gain_override_old)
+-		wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-
+-	if (!target_gains) {
+-		if (!tx_gain_override_old)
+-			wlc_lcnphy_set_tx_pwr_by_index(pi,
+-						       pi_lcn->lcnphy_tssi_idx);
+-		wlc_lcnphy_get_tx_gain(pi, &temp_gains);
+-		target_gains = &temp_gains;
+-	}
+-
+-	hash = (target_gains->gm_gain << 8) |
+-	    (target_gains->pga_gain << 4) | (target_gains->pad_gain);
+-
+-	band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+-
+-	cal_gains = *target_gains;
+-	memset(ncorr_override, 0, sizeof(ncorr_override));
+-	for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
+-		if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
+-			cal_gains.gm_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
+-			cal_gains.pga_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
+-			cal_gains.pad_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
+-			memcpy(ncorr_override,
+-			       &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
+-			       sizeof(ncorr_override));
+-			break;
+-		}
+-	}
+-
+-	wlc_lcnphy_set_tx_gain(pi, &cal_gains);
+-
+-	write_phy_reg(pi, 0x453, 0xaa9);
+-	write_phy_reg(pi, 0x93d, 0xc0);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      (const void *)
+-				      lcnphy_iqcal_loft_gainladder,
+-				      ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
+-				      16, 0);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      (const void *)lcnphy_iqcal_ir_gainladder,
+-				      ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16,
+-				      32);
+-
+-	if (pi->phy_tx_tone_freq) {
+-
+-		wlc_lcnphy_stop_tx_tone(pi);
+-		udelay(5);
+-		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+-	} else {
+-		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+-	}
+-
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-
+-	for (i = n_cal_start; i < n_cal_cmds; i++) {
+-		u16 zero_diq = 0;
+-		u16 best_coeffs[11];
+-		u16 command_num;
+-
+-		cal_type = (cal_cmds[i] & 0x0f00) >> 8;
+-
+-		command_num = command_nums[i];
+-		if (ncorr_override[cal_type])
+-			command_num =
+-			    ncorr_override[cal_type] << 8 | (command_num &
+-							     0xff);
+-
+-		write_phy_reg(pi, 0x452, command_num);
+-
+-		if ((cal_type == 3) || (cal_type == 4)) {
+-
+-			wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						     &diq_start, 1, 16, 69);
+-
+-			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						      &zero_diq, 1, 16, 69);
+-		}
+-
+-		write_phy_reg(pi, 0x451, cal_cmds[i]);
+-
+-		if (!wlc_lcnphy_iqcal_wait(pi)) {
+-
+-			goto cleanup;
+-		}
+-
+-		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					     best_coeffs,
+-					     ARRAY_SIZE(best_coeffs), 16, 96);
+-		wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					      best_coeffs,
+-					      ARRAY_SIZE(best_coeffs), 16, 64);
+-
+-		if ((cal_type == 3) || (cal_type == 4)) {
+-			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						      &diq_start, 1, 16, 69);
+-		}
+-		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					     pi_lcn->lcnphy_cal_results.
+-					     txiqlocal_bestcoeffs,
+-					     ARRAY_SIZE(pi_lcn->
+-						       lcnphy_cal_results.
+-						       txiqlocal_bestcoeffs),
+-					     16, 96);
+-	}
+-
+-	wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				     pi_lcn->lcnphy_cal_results.
+-				     txiqlocal_bestcoeffs,
+-				     ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
+-					       txiqlocal_bestcoeffs), 16, 96);
+-	pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      &pi_lcn->lcnphy_cal_results.
+-				      txiqlocal_bestcoeffs[0], 4, 16, 80);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      &pi_lcn->lcnphy_cal_results.
+-				      txiqlocal_bestcoeffs[5], 2, 16, 85);
+-
+- cleanup:
+-	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
+-	kfree(values_to_save);
+-
+-	if (!keep_tone)
+-		wlc_lcnphy_stop_tx_tone(pi);
+-
+-	write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
+-
+-	write_phy_reg(pi, 0x453, 0);
+-
+-	if (tx_gain_override_old)
+-		wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
+-
+-	write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
+-	write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
+-
+-}
+-
+-static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi)
+-{
+-	bool suspend, tx_gain_override_old;
+-	lcnphy_txgains_t old_gains;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
+-	    idleTssi0_regvalue_2C;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
+-	u16 SAVE_jtag_bb_afe_switch =
+-	    read_radio_reg(pi, RADIO_2064_REG007) & 1;
+-	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
+-	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+-	idleTssi = read_phy_reg(pi, 0x4ab);
+-	suspend =
+-	    (0 ==
+-	     (R_REG(&((phy_info_t *) pi)->regs->maccontrol) &
+-	      MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-	wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+-	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
+-	wlc_lcnphy_tssi_setup(pi);
+-	wlc_phy_do_dummy_tx(pi, true, OFF);
+-	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+-		    >> 0);
+-
+-	idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
+-			>> 0);
+-
+-	if (idleTssi0_2C >= 256)
+-		idleTssi0_OB = idleTssi0_2C - 256;
+-	else
+-		idleTssi0_OB = idleTssi0_2C + 256;
+-
+-	idleTssi0_regvalue_OB = idleTssi0_OB;
+-	if (idleTssi0_regvalue_OB >= 256)
+-		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
+-	else
+-		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
+-	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
+-
+-	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
+-	wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-
+-	write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
+-	mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode)
+-{
+-	bool suspend;
+-	u16 save_txpwrCtrlEn;
+-	u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
+-	u16 auxpga_vmid;
+-	phytbl_info_t tab;
+-	u32 val;
+-	u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
+-	    save_reg112;
+-	u16 values_to_save[14];
+-	s8 index;
+-	int i;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	udelay(999);
+-
+-	save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
+-	save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
+-	save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
+-	save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
+-	save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
+-	save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
+-
+-	for (i = 0; i < 14; i++)
+-		values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-	index = pi_lcn->lcnphy_current_index;
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
+-	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+-
+-	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
+-
+-	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
+-
+-	mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
+-
+-	mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xC);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
+-
+-	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &val;
+-	tab.tbl_offset = 6;
+-	wlc_lcnphy_write_table(pi, &tab);
+-	if (mode == TEMPSENSE) {
+-		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+-
+-		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
+-
+-		auxpga_vmidcourse = 8;
+-		auxpga_vmidfine = 0x4;
+-		auxpga_gain = 2;
+-		mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
+-	} else {
+-		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+-
+-		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
+-
+-		auxpga_vmidcourse = 7;
+-		auxpga_vmidfine = 0xa;
+-		auxpga_gain = 2;
+-	}
+-	auxpga_vmid =
+-	    (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
+-
+-	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-
+-	wlc_phy_do_dummy_tx(pi, true, OFF);
+-	if (!tempsense_done(pi))
+-		udelay(10);
+-
+-	write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
+-	write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
+-	write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
+-	write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
+-	write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
+-	write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
+-	for (i = 0; i < 14; i++)
+-		write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
+-
+-	write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-	udelay(999);
+-}
+-
+-void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi)
+-{
+-	lcnphy_txgains_t tx_gains;
+-	u8 bbmult;
+-	phytbl_info_t tab;
+-	s32 a1, b0, b1;
+-	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
+-	bool suspend;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		wlc_lcnphy_set_bbmult(pi, 0x30);
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-		return;
+-	}
+-
+-	if (!pi->hwpwrctrl_capable) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			tx_gains.gm_gain = 4;
+-			tx_gains.pga_gain = 12;
+-			tx_gains.pad_gain = 12;
+-			tx_gains.dac_gain = 0;
+-
+-			bbmult = 150;
+-		} else {
+-			tx_gains.gm_gain = 7;
+-			tx_gains.pga_gain = 15;
+-			tx_gains.pad_gain = 14;
+-			tx_gains.dac_gain = 0;
+-
+-			bbmult = 150;
+-		}
+-		wlc_lcnphy_set_tx_gain(pi, &tx_gains);
+-		wlc_lcnphy_set_bbmult(pi, bbmult);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	} else {
+-
+-		wlc_lcnphy_idle_tssi_est(ppi);
+-
+-		wlc_lcnphy_clear_tx_power_offsets(pi);
+-
+-		b0 = pi->txpa_2g[0];
+-		b1 = pi->txpa_2g[1];
+-		a1 = pi->txpa_2g[2];
+-		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+-		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+-
+-		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-		tab.tbl_width = 32;
+-		tab.tbl_ptr = &pwr;
+-		tab.tbl_len = 1;
+-		tab.tbl_offset = 0;
+-		for (tssi = 0; tssi < 128; tssi++) {
+-			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+-
+-			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+-			wlc_lcnphy_write_table(pi, &tab);
+-			tab.tbl_offset++;
+-		}
+-
+-		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
+-
+-		write_phy_reg(pi, 0x4a8, 10);
+-
+-		wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
+-
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+-	}
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi)
+-{
+-	u16 m0m1;
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = &m0m1;
+-	tab.tbl_len = 1;
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_offset = 87;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	return (u8) ((m0m1 & 0xff00) >> 8);
+-}
+-
+-static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain)
+-{
+-	mod_phy_reg(pi, 0x4fb,
+-		    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
+-		    gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
+-	mod_phy_reg(pi, 0x4fd,
+-		    LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
+-		    gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
+-}
+-
+-void
+-wlc_lcnphy_get_radio_loft(phy_info_t *pi,
+-			  u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
+-{
+-	*ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
+-	*eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
+-	*fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
+-	*fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
+-}
+-
+-static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains)
+-{
+-	u16 dac_gain;
+-
+-	dac_gain = read_phy_reg(pi, 0x439) >> 0;
+-	gains->dac_gain = (dac_gain & 0x380) >> 7;
+-
+-	{
+-		u16 rfgain0, rfgain1;
+-
+-		rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
+-		rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
+-
+-		gains->gm_gain = rfgain0 & 0xff;
+-		gains->pga_gain = (rfgain0 >> 8) & 0xff;
+-		gains->pad_gain = rfgain1 & 0xff;
+-	}
+-}
+-
+-void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b)
+-{
+-	phytbl_info_t tab;
+-	u16 iqcc[2];
+-
+-	iqcc[0] = a;
+-	iqcc[1] = b;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = iqcc;
+-	tab.tbl_len = 2;
+-	tab.tbl_offset = 80;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq)
+-{
+-	phytbl_info_t tab;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &didq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 85;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index)
+-{
+-	phytbl_info_t tab;
+-	u16 a, b;
+-	u8 bb_mult;
+-	u32 bbmultiqcomp, txgain, locoeffs, rfpower;
+-	lcnphy_txgains_t gains;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
+-	pi_lcn->lcnphy_current_index = (u8) index;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+-	tab.tbl_ptr = &bbmultiqcomp;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &txgain;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	gains.gm_gain = (u16) (txgain & 0xff);
+-	gains.pga_gain = (u16) (txgain >> 8) & 0xff;
+-	gains.pad_gain = (u16) (txgain >> 16) & 0xff;
+-	gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
+-	wlc_lcnphy_set_tx_gain(pi, &gains);
+-	wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
+-
+-	bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
+-	wlc_lcnphy_set_bbmult(pi, bb_mult);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-
+-		a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
+-		b = (u16) (bbmultiqcomp & 0x3ff);
+-		wlc_lcnphy_set_tx_iqcc(pi, a, b);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
+-		tab.tbl_ptr = &locoeffs;
+-		wlc_lcnphy_read_table(pi, &tab);
+-
+-		wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+-		tab.tbl_ptr = &rfpower;
+-		wlc_lcnphy_read_table(pi, &tab);
+-		mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
+-
+-	}
+-}
+-
+-static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx)
+-{
+-
+-	mod_phy_reg(pi, 0x44d,
+-		    (0x1 << 1) |
+-		    (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
+-
+-	or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
+-}
+-
+-static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi)
+-{
+-	u32 j;
+-	phytbl_info_t tab;
+-	u32 temp_offset[128];
+-	tab.tbl_ptr = temp_offset;
+-	tab.tbl_len = 128;
+-	tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
+-	tab.tbl_width = 32;
+-	tab.tbl_offset = 0;
+-
+-	memset(temp_offset, 0, sizeof(temp_offset));
+-	for (j = 1; j < 128; j += 2)
+-		temp_offset[j] = 0x80000;
+-
+-	wlc_lcnphy_write_table(pi, &tab);
+-	return;
+-}
+-
+-static void
+-wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+-				       u16 trsw,
+-				       u16 ext_lna,
+-				       u16 biq2,
+-				       u16 biq1,
+-				       u16 tia, u16 lna2, u16 lna1)
+-{
+-	u16 gain0_15, gain16_19;
+-
+-	gain16_19 = biq2 & 0xf;
+-	gain0_15 = ((biq1 & 0xf) << 12) |
+-	    ((tia & 0xf) << 8) |
+-	    ((lna2 & 0x3) << 6) |
+-	    ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+-
+-	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+-	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+-	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+-	} else {
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
+-
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
+-
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-	}
+-
+-	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+-
+-}
+-
+-static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable)
+-{
+-	u16 ebit = enable ? 1 : 0;
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
+-		mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
+-	} else {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
+-		mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
+-	}
+-}
+-
+-void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable)
+-{
+-	if (!bEnable) {
+-
+-		and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
+-
+-		and_phy_reg(pi, 0x44c,
+-			    ~(u16) ((0x1 << 3) |
+-				       (0x1 << 5) |
+-				       (0x1 << 12) |
+-				       (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-
+-		and_phy_reg(pi, 0x44d,
+-			    ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
+-
+-		and_phy_reg(pi, 0x4f9,
+-			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-
+-		and_phy_reg(pi, 0x4fa,
+-			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-	} else {
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
+-
+-		mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+-		mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+-
+-		wlc_lcnphy_set_trsw_override(pi, true, false);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
+-		mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
+-		} else {
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+-		}
+-	}
+-}
+-
+-static void
+-wlc_lcnphy_run_samples(phy_info_t *pi,
+-		       u16 num_samps,
+-		       u16 num_loops, u16 wait, bool iqcalmode)
+-{
+-
+-	or_phy_reg(pi, 0x6da, 0x8080);
+-
+-	mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
+-	if (num_loops != 0xffff)
+-		num_loops--;
+-	mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
+-
+-	mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
+-
+-	if (iqcalmode) {
+-
+-		and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
+-		or_phy_reg(pi, 0x453, (0x1 << 15));
+-	} else {
+-		write_phy_reg(pi, 0x63f, 1);
+-		wlc_lcnphy_tx_pu(pi, 1);
+-	}
+-
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-}
+-
+-void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode)
+-{
+-
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+-	} else {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+-	}
+-
+-	if (phybw40 == 0) {
+-		mod_phy_reg((pi), 0x410,
+-			    (0x1 << 6) |
+-			    (0x1 << 5),
+-			    ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) <<
+-			    6 | (!mode) << 5);
+-		mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
+-	}
+-}
+-
+-void
+-wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val,
+-			 bool iqcalmode)
+-{
+-	u8 phy_bw;
+-	u16 num_samps, t, k;
+-	u32 bw;
+-	fixed theta = 0, rot = 0;
+-	cs32 tone_samp;
+-	u32 data_buf[64];
+-	u16 i_samp, q_samp;
+-	phytbl_info_t tab;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi->phy_tx_tone_freq = f_kHz;
+-
+-	wlc_lcnphy_deaf_mode(pi, true);
+-
+-	phy_bw = 40;
+-	if (pi_lcn->lcnphy_spurmod) {
+-		write_phy_reg(pi, 0x942, 0x2);
+-		write_phy_reg(pi, 0x93b, 0x0);
+-		write_phy_reg(pi, 0x93c, 0x0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
+-	}
+-
+-	if (f_kHz) {
+-		k = 1;
+-		do {
+-			bw = phy_bw * 1000 * k;
+-			num_samps = bw / ABS(f_kHz);
+-			k++;
+-		} while ((num_samps * (u32) (ABS(f_kHz))) != bw);
+-	} else
+-		num_samps = 2;
+-
+-	rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+-	theta = 0;
+-
+-	for (t = 0; t < num_samps; t++) {
+-
+-		wlc_phy_cordic(theta, &tone_samp);
+-
+-		theta += rot;
+-
+-		i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
+-		q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
+-		data_buf[t] = (i_samp << 10) | q_samp;
+-	}
+-
+-	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
+-
+-	tab.tbl_ptr = data_buf;
+-	tab.tbl_len = num_samps;
+-	tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
+-	tab.tbl_offset = 0;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
+-}
+-
+-void wlc_lcnphy_stop_tx_tone(phy_info_t *pi)
+-{
+-	s16 playback_status;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi->phy_tx_tone_freq = 0;
+-	if (pi_lcn->lcnphy_spurmod) {
+-		write_phy_reg(pi, 0x942, 0x7);
+-		write_phy_reg(pi, 0x93b, 0x2017);
+-		write_phy_reg(pi, 0x93c, 0x27c5);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
+-	}
+-
+-	playback_status = read_phy_reg(pi, 0x644);
+-	if (playback_status & (0x1 << 0)) {
+-		wlc_lcnphy_tx_pu(pi, 0);
+-		mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
+-	} else if (playback_status & (0x1 << 1))
+-		mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
+-
+-	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
+-
+-	and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
+-
+-	wlc_lcnphy_deaf_mode(pi, false);
+-}
+-
+-static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
+-}
+-
+-void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b)
+-{
+-	u16 iqcc[2];
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = iqcc;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = 0;
+-	tab.tbl_offset = 80;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	*a = iqcc[0];
+-	*b = iqcc[1];
+-}
+-
+-u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u16 didq;
+-
+-	tab.tbl_id = 0;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &didq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 85;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	return didq;
+-}
+-
+-static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi)
+-{
+-
+-	lcnphy_txgains_t target_gains, old_gains;
+-	u8 save_bb_mult;
+-	u16 a, b, didq, save_pa_gain = 0;
+-	uint idx, SAVE_txpwrindex = 0xFF;
+-	u32 val;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phytbl_info_t tab;
+-	u8 ei0, eq0, fi0, fq0;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-	save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
+-
+-	save_bb_mult = wlc_lcnphy_get_bbmult(pi);
+-
+-	if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
+-		SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	target_gains.gm_gain = 7;
+-	target_gains.pga_gain = 0;
+-	target_gains.pad_gain = 21;
+-	target_gains.dac_gain = 0;
+-	wlc_lcnphy_set_tx_gain(pi, &target_gains);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
+-
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
+-
+-		wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+-				       (pi_lcn->
+-					lcnphy_recal ? LCNPHY_CAL_RECAL :
+-					LCNPHY_CAL_FULL), false);
+-	} else {
+-
+-		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+-	}
+-
+-	wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
+-	if ((ABS((s8) fi0) == 15) && (ABS((s8) fq0) == 15)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			target_gains.gm_gain = 255;
+-			target_gains.pga_gain = 255;
+-			target_gains.pad_gain = 0xf0;
+-			target_gains.dac_gain = 0;
+-		} else {
+-			target_gains.gm_gain = 7;
+-			target_gains.pga_gain = 45;
+-			target_gains.pad_gain = 186;
+-			target_gains.dac_gain = 0;
+-		}
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 1)
+-		    || pi_lcn->lcnphy_hw_iqcal_en) {
+-
+-			target_gains.pga_gain = 0;
+-			target_gains.pad_gain = 30;
+-			wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+-			wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+-					       LCNPHY_CAL_FULL, false);
+-		} else {
+-
+-			wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+-		}
+-
+-	}
+-
+-	wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+-
+-	didq = wlc_lcnphy_get_tx_locc(pi);
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &val;
+-
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-
+-	for (idx = 0; idx < 128; idx++) {
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
+-
+-		wlc_lcnphy_read_table(pi, &tab);
+-		val = (val & 0xfff00000) |
+-		    ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
+-		wlc_lcnphy_write_table(pi, &tab);
+-
+-		val = didq;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
+-
+-	wlc_lcnphy_set_bbmult(pi, save_bb_mult);
+-	wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
+-	wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-
+-	if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-	else
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
+-}
+-
+-s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode)
+-{
+-	u16 tempsenseval1, tempsenseval2;
+-	s16 avg = 0;
+-	bool suspend = 0;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	}
+-	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+-	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+-
+-	if (tempsenseval1 > 255)
+-		avg = (s16) (tempsenseval1 - 512);
+-	else
+-		avg = (s16) tempsenseval1;
+-
+-	if (tempsenseval2 > 255)
+-		avg += (s16) (tempsenseval2 - 512);
+-	else
+-		avg += (s16) tempsenseval2;
+-
+-	avg /= 2;
+-
+-	if (mode == 1) {
+-
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-		udelay(100);
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return avg;
+-}
+-
+-u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode)
+-{
+-	u16 tempsenseval1, tempsenseval2;
+-	s32 avg = 0;
+-	bool suspend = 0;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	}
+-	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+-	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+-
+-	if (tempsenseval1 > 255)
+-		avg = (int)(tempsenseval1 - 512);
+-	else
+-		avg = (int)tempsenseval1;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
+-		if (tempsenseval2 > 255)
+-			avg = (int)(avg - tempsenseval2 + 512);
+-		else
+-			avg = (int)(avg - tempsenseval2);
+-	} else {
+-		if (tempsenseval2 > 255)
+-			avg = (int)(avg + tempsenseval2 - 512);
+-		else
+-			avg = (int)(avg + tempsenseval2);
+-		avg = avg / 2;
+-	}
+-	if (avg < 0)
+-		avg = avg + 512;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 2)
+-		avg = tempsenseval1;
+-
+-	if (mode)
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-
+-	if (mode == 1) {
+-
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-		udelay(100);
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return (u16) avg;
+-}
+-
+-s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode)
+-{
+-	s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
+-	degree =
+-	    ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
+-	    / LCN_TEMPSENSE_DEN;
+-	return (s8) degree;
+-}
+-
+-s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode)
+-{
+-	u16 vbatsenseval;
+-	s32 avg = 0;
+-	bool suspend = 0;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
+-	}
+-
+-	vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
+-
+-	if (vbatsenseval > 255)
+-		avg = (s32) (vbatsenseval - 512);
+-	else
+-		avg = (s32) vbatsenseval;
+-
+-	avg =
+-	    (avg * LCN_VBAT_SCALE_NOM +
+-	     (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
+-
+-	if (mode == 1) {
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return (s8) avg;
+-}
+-
+-static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode)
+-{
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
+-
+-	if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
+-	    (mode == AFE_CLK_INIT_MODE_TXRX2X))
+-		write_phy_reg(pi, 0x6d0, 0x7);
+-
+-	wlc_lcnphy_toggle_afe_pwdn(pi);
+-}
+-
+-static bool
+-wlc_lcnphy_rx_iq_est(phy_info_t *pi,
+-		     u16 num_samps,
+-		     u8 wait_time, lcnphy_iq_est_t *iq_est)
+-{
+-	int wait_count = 0;
+-	bool result = true;
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
+-
+-	mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
+-
+-	mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
+-
+-	mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
+-
+-	mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
+-
+-	while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
+-
+-		if (wait_count > (10 * 500)) {
+-			result = false;
+-			goto cleanup;
+-		}
+-		udelay(100);
+-		wait_count++;
+-	}
+-
+-	iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
+-	    (u32) read_phy_reg(pi, 0x484);
+-	iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
+-	    (u32) read_phy_reg(pi, 0x486);
+-	iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
+-	    (u32) read_phy_reg(pi, 0x488);
+-
+- cleanup:
+-	mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
+-
+-	return result;
+-}
+-
+-static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps)
+-{
+-#define LCNPHY_MIN_RXIQ_PWR 2
+-	bool result;
+-	u16 a0_new, b0_new;
+-	lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+-	s32 a, b, temp;
+-	s16 iq_nbits, qq_nbits, arsh, brsh;
+-	s32 iq;
+-	u32 ii, qq;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
+-	b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
+-	mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
+-
+-	wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
+-
+-	result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
+-	if (!result)
+-		goto cleanup;
+-
+-	iq = (s32) iq_est.iq_prod;
+-	ii = iq_est.i_pwr;
+-	qq = iq_est.q_pwr;
+-
+-	if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
+-		result = false;
+-		goto cleanup;
+-	}
+-
+-	iq_nbits = wlc_phy_nbits(iq);
+-	qq_nbits = wlc_phy_nbits(qq);
+-
+-	arsh = 10 - (30 - iq_nbits);
+-	if (arsh >= 0) {
+-		a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+-		temp = (s32) (ii >> arsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	} else {
+-		a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+-		temp = (s32) (ii << -arsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	}
+-	a /= temp;
+-	brsh = qq_nbits - 31 + 20;
+-	if (brsh >= 0) {
+-		b = (qq << (31 - qq_nbits));
+-		temp = (s32) (ii >> brsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	} else {
+-		b = (qq << (31 - qq_nbits));
+-		temp = (s32) (ii << -brsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	}
+-	b /= temp;
+-	b -= a * a;
+-	b = (s32) int_sqrt((unsigned long) b);
+-	b -= (1 << 10);
+-	a0_new = (u16) (a & 0x3ff);
+-	b0_new = (u16) (b & 0x3ff);
+- cleanup:
+-
+-	wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
+-
+-	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
+-	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
+-
+-	return result;
+-}
+-
+-static bool
+-wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp,
+-		     int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
+-		     int tx_gain_idx)
+-{
+-	lcnphy_txgains_t old_gains;
+-	u16 tx_pwr_ctrl;
+-	u8 tx_gain_index_old = 0;
+-	bool result = false, tx_gain_override_old = false;
+-	u16 i, Core1TxControl_old, RFOverride0_old,
+-	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
+-	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
+-	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
+-	int tia_gain;
+-	u32 received_power, rx_pwr_threshold;
+-	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
+-	u16 values_to_save[11];
+-	s16 *ptr;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
+-	if (NULL == ptr) {
+-		return false;
+-	}
+-	if (module == 2) {
+-		while (iqcomp_sz--) {
+-			if (iqcomp[iqcomp_sz].chan ==
+-			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
+-
+-				wlc_lcnphy_set_rx_iq_comp(pi,
+-							  (u16)
+-							  iqcomp[iqcomp_sz].a,
+-							  (u16)
+-							  iqcomp[iqcomp_sz].b);
+-				result = true;
+-				break;
+-			}
+-		}
+-		goto cal_done;
+-	}
+-
+-	if (module == 1) {
+-
+-		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-		for (i = 0; i < 11; i++) {
+-			values_to_save[i] =
+-			    read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+-		}
+-		Core1TxControl_old = read_phy_reg(pi, 0x631);
+-
+-		or_phy_reg(pi, 0x631, 0x0015);
+-
+-		RFOverride0_old = read_phy_reg(pi, 0x44c);
+-		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+-		rfoverride2_old = read_phy_reg(pi, 0x4b0);
+-		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+-		rfoverride3_old = read_phy_reg(pi, 0x4f9);
+-		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+-		rfoverride4_old = read_phy_reg(pi, 0x938);
+-		rfoverride4val_old = read_phy_reg(pi, 0x939);
+-		afectrlovr_old = read_phy_reg(pi, 0x43b);
+-		afectrlovrval_old = read_phy_reg(pi, 0x43c);
+-		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+-
+-		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-		if (tx_gain_override_old) {
+-			wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-			tx_gain_index_old = pi_lcn->lcnphy_current_index;
+-		}
+-
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+-
+-		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+-		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+-		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+-		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+-		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+-		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+-		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+-		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+-		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+-		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+-
+-		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+-		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+-		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+-		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+-		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+-		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+-		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+-
+-		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
+-		write_phy_reg(pi, 0x6da, 0xffff);
+-		or_phy_reg(pi, 0x6db, 0x3);
+-		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+-		wlc_lcnphy_rx_gain_override_enable(pi, true);
+-
+-		tia_gain = 8;
+-		rx_pwr_threshold = 950;
+-		while (tia_gain > 0) {
+-			tia_gain -= 1;
+-			wlc_lcnphy_set_rx_gain_by_distribution(pi,
+-							       0, 0, 2, 2,
+-							       (u16)
+-							       tia_gain, 1, 0);
+-			udelay(500);
+-
+-			received_power =
+-			    wlc_lcnphy_measure_digital_power(pi, 2000);
+-			if (received_power < rx_pwr_threshold)
+-				break;
+-		}
+-		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+-
+-		wlc_lcnphy_stop_tx_tone(pi);
+-
+-		write_phy_reg(pi, 0x631, Core1TxControl_old);
+-
+-		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+-		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+-		write_phy_reg(pi, 0x4b0, rfoverride2_old);
+-		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+-		write_phy_reg(pi, 0x4f9, rfoverride3_old);
+-		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+-		write_phy_reg(pi, 0x938, rfoverride4_old);
+-		write_phy_reg(pi, 0x939, rfoverride4val_old);
+-		write_phy_reg(pi, 0x43b, afectrlovr_old);
+-		write_phy_reg(pi, 0x43c, afectrlovrval_old);
+-		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+-		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+-
+-		wlc_lcnphy_clear_trsw_override(pi);
+-
+-		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+-
+-		for (i = 0; i < 11; i++) {
+-			write_radio_reg(pi, rxiq_cal_rf_reg[i],
+-					values_to_save[i]);
+-		}
+-
+-		if (tx_gain_override_old) {
+-			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+-		} else
+-			wlc_lcnphy_disable_tx_gain_override(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+-
+-		wlc_lcnphy_rx_gain_override_enable(pi, false);
+-	}
+-
+- cal_done:
+-	kfree(ptr);
+-	return result;
+-}
+-
+-static void wlc_lcnphy_temp_adj(phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-}
+-
+-static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi)
+-{
+-	bool suspend;
+-	s8 index;
+-	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	wlc_lcnphy_deaf_mode(pi, true);
+-	pi->phy_lastcal = pi->sh->now;
+-	pi->phy_forcecal = false;
+-	index = pi_lcn->lcnphy_current_index;
+-
+-	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+-
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+-	wlc_lcnphy_deaf_mode(pi, false);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-}
+-
+-static void wlc_lcnphy_periodic_cal(phy_info_t *pi)
+-{
+-	bool suspend, full_cal;
+-	const lcnphy_rx_iqcomp_t *rx_iqcomp;
+-	int rx_iqcomp_sz;
+-	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	s8 index;
+-	phytbl_info_t tab;
+-	s32 a1, b0, b1;
+-	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	pi->phy_lastcal = pi->sh->now;
+-	pi->phy_forcecal = false;
+-	full_cal =
+-	    (pi_lcn->lcnphy_full_cal_channel !=
+-	     CHSPEC_CHANNEL(pi->radio_chanspec));
+-	pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-	index = pi_lcn->lcnphy_current_index;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend) {
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-	wlc_lcnphy_deaf_mode(pi, true);
+-
+-	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+-
+-	rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
+-	rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
+-	else
+-		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+-
+-		wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi);
+-
+-		b0 = pi->txpa_2g[0];
+-		b1 = pi->txpa_2g[1];
+-		a1 = pi->txpa_2g[2];
+-		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+-		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+-
+-		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-		tab.tbl_width = 32;
+-		tab.tbl_ptr = &pwr;
+-		tab.tbl_len = 1;
+-		tab.tbl_offset = 0;
+-		for (tssi = 0; tssi < 128; tssi++) {
+-			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+-			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+-			wlc_lcnphy_write_table(pi, &tab);
+-			tab.tbl_offset++;
+-		}
+-	}
+-
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+-	wlc_lcnphy_deaf_mode(pi, false);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode)
+-{
+-	u16 temp_new;
+-	int temp1, temp2, temp_diff;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	switch (mode) {
+-	case PHY_PERICAL_CHAN:
+-
+-		break;
+-	case PHY_FULLCAL:
+-		wlc_lcnphy_periodic_cal(pi);
+-		break;
+-	case PHY_PERICAL_PHYINIT:
+-		wlc_lcnphy_periodic_cal(pi);
+-		break;
+-	case PHY_PERICAL_WATCHDOG:
+-		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-			temp_new = wlc_lcnphy_tempsense(pi, 0);
+-			temp1 = LCNPHY_TEMPSENSE(temp_new);
+-			temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
+-			temp_diff = temp1 - temp2;
+-			if ((pi_lcn->lcnphy_cal_counter > 90) ||
+-			    (temp_diff > 60) || (temp_diff < -60)) {
+-				wlc_lcnphy_glacial_timer_based_cal(pi);
+-				wlc_2064_vco_cal(pi);
+-				pi_lcn->lcnphy_cal_temper = temp_new;
+-				pi_lcn->lcnphy_cal_counter = 0;
+-			} else
+-				pi_lcn->lcnphy_cal_counter++;
+-		}
+-		break;
+-	case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
+-		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-			wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi);
+-		break;
+-	}
+-}
+-
+-void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr)
+-{
+-	s8 cck_offset;
+-	u16 status;
+-	status = (read_phy_reg(pi, 0x4ab));
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+-	    (status  & (0x1 << 15))) {
+-		*ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+-				     >> 0) >> 1);
+-
+-		if (wlc_phy_tpc_isenabled_lcnphy(pi))
+-			cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
+-		else
+-			cck_offset = 0;
+-
+-		*cck_pwr = *ofdm_pwr + cck_offset;
+-	} else {
+-		*cck_pwr = 0;
+-		*ofdm_pwr = 0;
+-	}
+-}
+-
+-void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi)
+-{
+-	return;
+-
+-}
+-
+-static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	u8 channel = CHSPEC_CHANNEL(chanspec);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if (channel == 14) {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+-
+-	} else {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+-
+-	}
+-	pi_lcn->lcnphy_bandedge_corr = 2;
+-	if (channel == 1)
+-		pi_lcn->lcnphy_bandedge_corr = 4;
+-
+-	if (channel == 1 || channel == 2 || channel == 3 ||
+-	    channel == 4 || channel == 9 ||
+-	    channel == 10 || channel == 11 || channel == 12) {
+-		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
+-
+-		si_pmu_pllupd(pi->sh->sih);
+-		write_phy_reg(pi, 0x942, 0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
+-		pi_lcn->lcnphy_spurmod = 0;
+-		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
+-
+-		write_phy_reg(pi, 0x425, 0x5907);
+-	} else {
+-		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
+-
+-		si_pmu_pllupd(pi->sh->sih);
+-		write_phy_reg(pi, 0x942, 0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
+-
+-		pi_lcn->lcnphy_spurmod = 0;
+-		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
+-
+-		write_phy_reg(pi, 0x425, 0x590a);
+-	}
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-}
+-
+-void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi)
+-{
+-	s8 index;
+-	u16 index2;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) {
+-		index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+-		index2 = (u16) (index * 2);
+-		mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+-
+-		pi_lcn->lcnphy_current_index = (s8)
+-		    ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+-	}
+-}
+-
+-static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b)
+-{
+-	mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
+-
+-	mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
+-
+-	mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
+-
+-}
+-
+-void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi)
+-{
+-	u8 phybw40;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	pi_lcn->lcnphy_cal_counter = 0;
+-	pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
+-
+-	or_phy_reg(pi, 0x44a, 0x80);
+-	and_phy_reg(pi, 0x44a, 0x7f);
+-
+-	wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
+-
+-	write_phy_reg(pi, 0x60a, 160);
+-
+-	write_phy_reg(pi, 0x46a, 25);
+-
+-	wlc_lcnphy_baseband_init(pi);
+-
+-	wlc_lcnphy_radio_init(pi);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi);
+-
+-	wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+-
+-	si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
+-
+-	si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
+-
+-	if ((pi->sh->boardflags & BFL_FEM)
+-	    && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
+-
+-	wlc_lcnphy_agc_temp_init(pi);
+-
+-	wlc_lcnphy_temp_adj(pi);
+-
+-	mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-	udelay(100);
+-	mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+-	pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
+-	wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save)
+-{
+-	u16 vmid;
+-	int i;
+-	for (i = 0; i < 20; i++) {
+-		values_to_save[i] =
+-		    read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
+-	}
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+-	mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
+-	mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
+-	else
+-		and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
+-	or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
+-
+-	or_radio_reg(pi, RADIO_2064_REG036, 0x01);
+-	or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
+-	udelay(20);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+-		else
+-			or_radio_reg(pi, RADIO_2064_REG03A, 1);
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
+-		else
+-			or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
+-	}
+-
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xF);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
+-	}
+-
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG005, 0x8);
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x80);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+-	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+-	or_radio_reg(pi, RADIO_2064_REG113, 0x10);
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG007, 0x1);
+-	udelay(20);
+-
+-	vmid = 0x2A6;
+-	mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
+-	write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
+-	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+-	udelay(20);
+-	write_radio_reg(pi, RADIO_2064_REG012, 0x02);
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x06);
+-	write_radio_reg(pi, RADIO_2064_REG036, 0x11);
+-	write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
+-	write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
+-	write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
+-	write_radio_reg(pi, RADIO_2064_REG092, 0x15);
+-}
+-
+-static void
+-wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh,
+-		    s16 *ptr, int mode)
+-{
+-	u32 curval1, curval2, stpptr, curptr, strptr, val;
+-	u16 sslpnCalibClkEnCtrl, timer;
+-	u16 old_sslpnCalibClkEnCtrl;
+-	s16 imag, real;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	timer = 0;
+-	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-
+-	curval1 = R_REG(&pi->regs->psm_corectlsts);
+-	ptr[130] = 0;
+-	W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1));
+-
+-	W_REG(&pi->regs->smpl_clct_strptr, 0x7E00);
+-	W_REG(&pi->regs->smpl_clct_stpptr, 0x8000);
+-	udelay(20);
+-	curval2 = R_REG(&pi->regs->psm_phy_hdr_param);
+-	W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30);
+-
+-	write_phy_reg(pi, 0x555, 0x0);
+-	write_phy_reg(pi, 0x5a6, 0x5);
+-
+-	write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
+-	write_phy_reg(pi, 0x5cf, 3);
+-	write_phy_reg(pi, 0x5a5, 0x3);
+-	write_phy_reg(pi, 0x583, 0x0);
+-	write_phy_reg(pi, 0x584, 0x0);
+-	write_phy_reg(pi, 0x585, 0x0fff);
+-	write_phy_reg(pi, 0x586, 0x0000);
+-
+-	write_phy_reg(pi, 0x580, 0x4501);
+-
+-	sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-	write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
+-	stpptr = R_REG(&pi->regs->smpl_clct_stpptr);
+-	curptr = R_REG(&pi->regs->smpl_clct_curptr);
+-	do {
+-		udelay(10);
+-		curptr = R_REG(&pi->regs->smpl_clct_curptr);
+-		timer++;
+-	} while ((curptr != stpptr) && (timer < 500));
+-
+-	W_REG(&pi->regs->psm_phy_hdr_param, 0x2);
+-	strptr = 0x7E00;
+-	W_REG(&pi->regs->tplatewrptr, strptr);
+-	while (strptr < 0x8000) {
+-		val = R_REG(&pi->regs->tplatewrdata);
+-		imag = ((val >> 16) & 0x3ff);
+-		real = ((val) & 0x3ff);
+-		if (imag > 511) {
+-			imag -= 1024;
+-		}
+-		if (real > 511) {
+-			real -= 1024;
+-		}
+-		if (pi_lcn->lcnphy_iqcal_swp_dis)
+-			ptr[(strptr - 0x7E00) / 4] = real;
+-		else
+-			ptr[(strptr - 0x7E00) / 4] = imag;
+-		if (clip_detect_algo) {
+-			if (imag > thresh || imag < -thresh) {
+-				strptr = 0x8000;
+-				ptr[130] = 1;
+-			}
+-		}
+-		strptr += 4;
+-	}
+-
+-	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+-	W_REG(&pi->regs->psm_phy_hdr_param, curval2);
+-	W_REG(&pi->regs->psm_corectlsts, curval1);
+-}
+-
+-static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi)
+-{
+-	lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
+-
+-	wlc_lcnphy_set_cc(pi, 0, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 2, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 3, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 4, 0, 0);
+-
+-	wlc_lcnphy_a1(pi, 4, 0, 0);
+-	wlc_lcnphy_a1(pi, 3, 0, 0);
+-	wlc_lcnphy_a1(pi, 2, 3, 2);
+-	wlc_lcnphy_a1(pi, 0, 5, 8);
+-	wlc_lcnphy_a1(pi, 2, 2, 1);
+-	wlc_lcnphy_a1(pi, 0, 4, 3);
+-
+-	iqcc0 = wlc_lcnphy_get_cc(pi, 0);
+-	locc2 = wlc_lcnphy_get_cc(pi, 2);
+-	locc3 = wlc_lcnphy_get_cc(pi, 3);
+-	locc4 = wlc_lcnphy_get_cc(pi, 4);
+-}
+-
+-static void
+-wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y)
+-{
+-	u16 di0dq0;
+-	u16 x, y, data_rf;
+-	int k;
+-	switch (cal_type) {
+-	case 0:
+-		wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
+-		break;
+-	case 2:
+-		di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
+-		wlc_lcnphy_set_tx_locc(pi, di0dq0);
+-		break;
+-	case 3:
+-		k = wlc_lcnphy_calc_floor(coeff_x, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_x, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG089, data_rf);
+-		k = wlc_lcnphy_calc_floor(coeff_y, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_y, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
+-		break;
+-	case 4:
+-		k = wlc_lcnphy_calc_floor(coeff_x, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_x, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
+-		k = wlc_lcnphy_calc_floor(coeff_y, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_y, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
+-		break;
+-	}
+-}
+-
+-static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type)
+-{
+-	u16 a, b, didq;
+-	u8 di0, dq0, ei, eq, fi, fq;
+-	lcnphy_unsign16_struct cc;
+-	cc.re = 0;
+-	cc.im = 0;
+-	switch (cal_type) {
+-	case 0:
+-		wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+-		cc.re = a;
+-		cc.im = b;
+-		break;
+-	case 2:
+-		didq = wlc_lcnphy_get_tx_locc(pi);
+-		di0 = (((didq & 0xff00) << 16) >> 24);
+-		dq0 = (((didq & 0x00ff) << 24) >> 24);
+-		cc.re = (u16) di0;
+-		cc.im = (u16) dq0;
+-		break;
+-	case 3:
+-		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+-		cc.re = (u16) ei;
+-		cc.im = (u16) eq;
+-		break;
+-	case 4:
+-		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+-		cc.re = (u16) fi;
+-		cc.im = (u16) fq;
+-		break;
+-	}
+-	return cc;
+-}
+-
+-static void
+-wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2)
+-{
+-	const lcnphy_spb_tone_t *phy_c1;
+-	lcnphy_spb_tone_t phy_c2;
+-	lcnphy_unsign16_struct phy_c3;
+-	int phy_c4, phy_c5, k, l, j, phy_c6;
+-	u16 phy_c7, phy_c8, phy_c9;
+-	s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
+-	s16 *ptr, phy_c17;
+-	s32 phy_c18, phy_c19;
+-	u32 phy_c20, phy_c21;
+-	bool phy_c22, phy_c23, phy_c24, phy_c25;
+-	u16 phy_c26, phy_c27;
+-	u16 phy_c28, phy_c29, phy_c30;
+-	u16 phy_c31;
+-	u16 *phy_c32;
+-	phy_c21 = 0;
+-	phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
+-	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
+-	if (NULL == ptr) {
+-		return;
+-	}
+-
+-	phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
+-	if (NULL == phy_c32) {
+-		kfree(ptr);
+-		return;
+-	}
+-	phy_c26 = read_phy_reg(pi, 0x6da);
+-	phy_c27 = read_phy_reg(pi, 0x6db);
+-	phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
+-	write_phy_reg(pi, 0x93d, 0xC0);
+-
+-	wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-	or_phy_reg(pi, 0x6db, 0x3);
+-
+-	wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
+-	udelay(500);
+-	phy_c28 = read_phy_reg(pi, 0x938);
+-	phy_c29 = read_phy_reg(pi, 0x4d7);
+-	phy_c30 = read_phy_reg(pi, 0x4d8);
+-	or_phy_reg(pi, 0x938, 0x1 << 2);
+-	or_phy_reg(pi, 0x4d7, 0x1 << 2);
+-	or_phy_reg(pi, 0x4d7, 0x1 << 3);
+-	mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
+-	or_phy_reg(pi, 0x4d8, 1 << 0);
+-	or_phy_reg(pi, 0x4d8, 1 << 1);
+-	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
+-	mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
+-	phy_c1 = &lcnphy_spb_tone_3750[0];
+-	phy_c4 = 32;
+-
+-	if (num_levels == 0) {
+-		if (cal_type != 0) {
+-			num_levels = 4;
+-		} else {
+-			num_levels = 9;
+-		}
+-	}
+-	if (step_size_lg2 == 0) {
+-		if (cal_type != 0) {
+-			step_size_lg2 = 3;
+-		} else {
+-			step_size_lg2 = 8;
+-		}
+-	}
+-
+-	phy_c7 = (1 << step_size_lg2);
+-	phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
+-	phy_c15 = (s16) phy_c3.re;
+-	phy_c16 = (s16) phy_c3.im;
+-	if (cal_type == 2) {
+-		if (phy_c3.re > 127)
+-			phy_c15 = phy_c3.re - 256;
+-		if (phy_c3.im > 127)
+-			phy_c16 = phy_c3.im - 256;
+-	}
+-	wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+-	udelay(20);
+-	for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
+-		phy_c23 = 1;
+-		phy_c22 = 0;
+-		switch (cal_type) {
+-		case 0:
+-			phy_c10 = 511;
+-			break;
+-		case 2:
+-			phy_c10 = 127;
+-			break;
+-		case 3:
+-			phy_c10 = 15;
+-			break;
+-		case 4:
+-			phy_c10 = 15;
+-			break;
+-		}
+-
+-		phy_c9 = read_phy_reg(pi, 0x93d);
+-		phy_c9 = 2 * phy_c9;
+-		phy_c24 = 0;
+-		phy_c5 = 7;
+-		phy_c25 = 1;
+-		while (1) {
+-			write_radio_reg(pi, RADIO_2064_REG026,
+-					(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
+-			udelay(50);
+-			phy_c22 = 0;
+-			ptr[130] = 0;
+-			wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
+-			if (ptr[130] == 1)
+-				phy_c22 = 1;
+-			if (phy_c22)
+-				phy_c5 -= 1;
+-			if ((phy_c22 != phy_c24) && (!phy_c25))
+-				break;
+-			if (!phy_c22)
+-				phy_c5 += 1;
+-			if (phy_c5 <= 0 || phy_c5 >= 7)
+-				break;
+-			phy_c24 = phy_c22;
+-			phy_c25 = 0;
+-		}
+-
+-		if (phy_c5 < 0)
+-			phy_c5 = 0;
+-		else if (phy_c5 > 7)
+-			phy_c5 = 7;
+-
+-		for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
+-			for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
+-				phy_c11 = phy_c15 + k;
+-				phy_c12 = phy_c16 + l;
+-
+-				if (phy_c11 < -phy_c10)
+-					phy_c11 = -phy_c10;
+-				else if (phy_c11 > phy_c10)
+-					phy_c11 = phy_c10;
+-				if (phy_c12 < -phy_c10)
+-					phy_c12 = -phy_c10;
+-				else if (phy_c12 > phy_c10)
+-					phy_c12 = phy_c10;
+-				wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
+-						  phy_c12);
+-				udelay(20);
+-				wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
+-
+-				phy_c18 = 0;
+-				phy_c19 = 0;
+-				for (j = 0; j < 128; j++) {
+-					if (cal_type != 0) {
+-						phy_c6 = j % phy_c4;
+-					} else {
+-						phy_c6 = (2 * j) % phy_c4;
+-					}
+-					phy_c2.re = phy_c1[phy_c6].re;
+-					phy_c2.im = phy_c1[phy_c6].im;
+-					phy_c17 = ptr[j];
+-					phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
+-					phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
+-				}
+-
+-				phy_c18 = phy_c18 >> 10;
+-				phy_c19 = phy_c19 >> 10;
+-				phy_c20 =
+-				    ((phy_c18 * phy_c18) + (phy_c19 * phy_c19));
+-
+-				if (phy_c23 || phy_c20 < phy_c21) {
+-					phy_c21 = phy_c20;
+-					phy_c13 = phy_c11;
+-					phy_c14 = phy_c12;
+-				}
+-				phy_c23 = 0;
+-			}
+-		}
+-		phy_c23 = 1;
+-		phy_c15 = phy_c13;
+-		phy_c16 = phy_c14;
+-		phy_c7 = phy_c7 >> 1;
+-		wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+-		udelay(20);
+-	}
+-	goto cleanup;
+- cleanup:
+-	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
+-	wlc_lcnphy_stop_tx_tone(pi);
+-	write_phy_reg(pi, 0x6da, phy_c26);
+-	write_phy_reg(pi, 0x6db, phy_c27);
+-	write_phy_reg(pi, 0x938, phy_c28);
+-	write_phy_reg(pi, 0x4d7, phy_c29);
+-	write_phy_reg(pi, 0x4d8, phy_c30);
+-	write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
+-
+-	kfree(phy_c32);
+-	kfree(ptr);
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save)
+-{
+-	int i;
+-
+-	and_phy_reg(pi, 0x44c, 0x0 >> 11);
+-
+-	and_phy_reg(pi, 0x43b, 0xC);
+-
+-	for (i = 0; i < 20; i++) {
+-		write_radio_reg(pi, iqlo_loopback_rf_regs[i],
+-				values_to_save[i]);
+-	}
+-}
+-
+-static void
+-WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi,
+-					     const lcnphy_tx_gain_tbl_entry *
+-					     gain_table) {
+-	u32 j;
+-	phytbl_info_t tab;
+-	u32 val;
+-	u16 pa_gain;
+-	u16 gm_gain;
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec))
+-		pa_gain = 0x70;
+-	else
+-		pa_gain = 0x70;
+-
+-	if (pi->sh->boardflags & BFL_FEM)
+-		pa_gain = 0x10;
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &val;
+-
+-	for (j = 0; j < 128; j++) {
+-		gm_gain = gain_table[j].gm;
+-		val = (((u32) pa_gain << 24) |
+-		       (gain_table[j].pad << 16) |
+-		       (gain_table[j].pga << 8) | gm_gain);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
+-		wlc_lcnphy_write_table(pi, &tab);
+-
+-		val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-}
+-
+-static void wlc_lcnphy_load_rfpower(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 val, bbmult, rfgain;
+-	u8 index;
+-	u8 scale_factor = 1;
+-	s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-
+-	for (index = 0; index < 128; index++) {
+-		tab.tbl_ptr = &bbmult;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+-		wlc_lcnphy_read_table(pi, &tab);
+-		bbmult = bbmult >> 20;
+-
+-		tab.tbl_ptr = &rfgain;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+-		wlc_lcnphy_read_table(pi, &tab);
+-
+-		qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
+-		qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
+-
+-		if (qQ1 < qQ2) {
+-			temp2 = qm_shr16(temp2, qQ2 - qQ1);
+-			qQ = qQ1;
+-		} else {
+-			temp1 = qm_shr16(temp1, qQ1 - qQ2);
+-			qQ = qQ2;
+-		}
+-		temp = qm_sub16(temp1, temp2);
+-
+-		if (qQ >= 4)
+-			shift = qQ - 4;
+-		else
+-			shift = 4 - qQ;
+-
+-		val = (((index << shift) + (5 * temp) +
+-			(1 << (scale_factor + shift - 3))) >> (scale_factor +
+-							       shift - 2));
+-
+-		tab.tbl_ptr = &val;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi)
+-{
+-	uint idx;
+-	u8 phybw40;
+-	phytbl_info_t tab;
+-	u32 val;
+-
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) {
+-		wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
+-	}
+-
+-	if (pi->sh->boardflags & BFL_FEM_BT) {
+-		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-		tab.tbl_width = 16;
+-		tab.tbl_ptr = &val;
+-		tab.tbl_len = 1;
+-		val = 100;
+-		tab.tbl_offset = 4;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &val;
+-	tab.tbl_len = 1;
+-
+-	val = 114;
+-	tab.tbl_offset = 0;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	val = 130;
+-	tab.tbl_offset = 1;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	val = 6;
+-	tab.tbl_offset = 8;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->sh->boardflags & BFL_FEM)
+-			wlc_lcnphy_load_tx_gain_table(pi,
+-						      dot11lcnphy_2GHz_extPA_gaintable_rev0);
+-		else
+-			wlc_lcnphy_load_tx_gain_table(pi,
+-						      dot11lcnphy_2GHz_gaintable_rev0);
+-	}
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			for (idx = 0;
+-			     idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+-			     idx++)
+-				if (pi->sh->boardflags & BFL_EXTLNA)
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2
+-							       [idx]);
+-				else
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_2G_rev2
+-							       [idx]);
+-		} else {
+-			for (idx = 0;
+-			     idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+-			     idx++)
+-				if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2
+-							       [idx]);
+-				else
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_5G_rev2
+-							       [idx]);
+-		}
+-	}
+-
+-	if ((pi->sh->boardflags & BFL_FEM)
+-	    && !(pi->sh->boardflags & BFL_FEM_BT))
+-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
+-	else if (pi->sh->boardflags & BFL_FEM_BT) {
+-		if (pi->sh->boardrev < 0x1250)
+-			wlc_lcnphy_write_table(pi,
+-					       &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
+-		else
+-			wlc_lcnphy_write_table(pi,
+-					       &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
+-	} else
+-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
+-
+-	wlc_lcnphy_load_rfpower(pi);
+-
+-	wlc_lcnphy_clear_papd_comptable(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi)
+-{
+-	u16 afectrl1;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
+-
+-	write_phy_reg(pi, 0x43b, 0x0);
+-	write_phy_reg(pi, 0x43c, 0x0);
+-	write_phy_reg(pi, 0x44c, 0x0);
+-	write_phy_reg(pi, 0x4e6, 0x0);
+-	write_phy_reg(pi, 0x4f9, 0x0);
+-	write_phy_reg(pi, 0x4b0, 0x0);
+-	write_phy_reg(pi, 0x938, 0x0);
+-	write_phy_reg(pi, 0x4b0, 0x0);
+-	write_phy_reg(pi, 0x44e, 0);
+-
+-	or_phy_reg(pi, 0x567, 0x03);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-
+-	if (!(pi->sh->boardflags & BFL_FEM))
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
+-
+-	if (0) {
+-		afectrl1 = 0;
+-		afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
+-				     (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn->
+-								      lcnphy_rssi_gs
+-								      << 10));
+-		write_phy_reg(pi, 0x43e, afectrl1);
+-	}
+-
+-	mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
+-	if (pi->sh->boardflags & BFL_FEM) {
+-		mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
+-
+-		write_phy_reg(pi, 0x910, 0x1);
+-	}
+-
+-	mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
+-	mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
+-	mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
+-
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi)
+-{
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
+-
+-		mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
+-	}
+-}
+-
+-static void wlc_lcnphy_agc_temp_init(phy_info_t *pi)
+-{
+-	s16 temp;
+-	phytbl_info_t tab;
+-	u32 tableBuffer[2];
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	temp = (s16) read_phy_reg(pi, 0x4df);
+-	pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
+-
+-	if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
+-		pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
+-
+-	pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
+-
+-	if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
+-		pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
+-
+-	tab.tbl_ptr = tableBuffer;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = 17;
+-	tab.tbl_offset = 59;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	if (tableBuffer[0] > 63)
+-		tableBuffer[0] -= 128;
+-	pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
+-
+-	if (tableBuffer[1] > 63)
+-		tableBuffer[1] -= 128;
+-	pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
+-
+-	temp = (s16) (read_phy_reg(pi, 0x434)
+-			& (0xff << 0));
+-	if (temp > 127)
+-		temp -= 256;
+-	pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
+-
+-	pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424)
+-					  & (0xff << 8))
+-	    >> 8;
+-	pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425)
+-					   & (0xff << 0))
+-	    >> 0;
+-
+-	tab.tbl_ptr = tableBuffer;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
+-	tab.tbl_offset = 28;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
+-	pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
+-
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	or_phy_reg(pi, 0x805, 0x1);
+-
+-	mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
+-
+-	mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
+-
+-	write_phy_reg(pi, 0x414, 0x1e10);
+-	write_phy_reg(pi, 0x415, 0x0640);
+-
+-	mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-	mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
+-
+-	mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
+-
+-	if (!(pi->sh->boardrev < 0x1204))
+-		mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
+-
+-	write_phy_reg(pi, 0x7d6, 0x0902);
+-	mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
+-
+-	mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-		mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
+-
+-		mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
+-
+-		mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+-
+-		mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
+-		mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
+-		mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
+-		mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
+-		mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
+-
+-		mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
+-
+-		wlc_lcnphy_clear_tx_power_offsets(pi);
+-		mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
+-
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi)
+-{
+-
+-	wlc_lcnphy_tbl_init(pi);
+-	wlc_lcnphy_rev0_baseband_init(pi);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		wlc_lcnphy_rev2_baseband_init(pi);
+-	wlc_lcnphy_bu_tweaks(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi)
+-{
+-	u32 i;
+-	lcnphy_radio_regs_t *lcnphyregs = NULL;
+-
+-	lcnphyregs = lcnphy_radio_regs_2064;
+-
+-	for (i = 0; lcnphyregs[i].address != 0xffff; i++)
+-		if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
+-			write_radio_reg(pi,
+-					((lcnphyregs[i].address & 0x3fff) |
+-					 RADIO_DEFAULT_CORE),
+-					(u16) lcnphyregs[i].init_a);
+-		else if (lcnphyregs[i].do_init_g)
+-			write_radio_reg(pi,
+-					((lcnphyregs[i].address & 0x3fff) |
+-					 RADIO_DEFAULT_CORE),
+-					(u16) lcnphyregs[i].init_g);
+-
+-	write_radio_reg(pi, RADIO_2064_REG032, 0x62);
+-	write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+-
+-	write_radio_reg(pi, RADIO_2064_REG090, 0x10);
+-
+-	write_radio_reg(pi, RADIO_2064_REG010, 0x00);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-
+-		write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
+-		write_radio_reg(pi, RADIO_2064_REG061, 0x72);
+-		write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
+-	write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
+-
+-	write_phy_reg(pi, 0x4ea, 0x4688);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
+-
+-	mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
+-
+-	wlc_lcnphy_set_tx_locc(pi, 0);
+-
+-	wlc_lcnphy_rcal(pi);
+-
+-	wlc_lcnphy_rc_cal(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	wlc_radio_2064_init(pi);
+-}
+-
+-static void wlc_lcnphy_rcal(phy_info_t *pi)
+-{
+-	u8 rcal_value;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+-
+-	or_radio_reg(pi, RADIO_2064_REG004, 0x40);
+-	or_radio_reg(pi, RADIO_2064_REG120, 0x10);
+-
+-	or_radio_reg(pi, RADIO_2064_REG078, 0x80);
+-	or_radio_reg(pi, RADIO_2064_REG129, 0x02);
+-
+-	or_radio_reg(pi, RADIO_2064_REG057, 0x01);
+-
+-	or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
+-	mdelay(5);
+-	SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
+-
+-	if (wlc_radio_2064_rcal_done(pi)) {
+-		rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
+-		rcal_value = rcal_value & 0x1f;
+-	}
+-
+-	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+-
+-	and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
+-}
+-
+-static void wlc_lcnphy_rc_cal(phy_info_t *pi)
+-{
+-	u8 dflt_rc_cal_val;
+-	u16 flt_val;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	dflt_rc_cal_val = 7;
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		dflt_rc_cal_val = 11;
+-	flt_val =
+-	    (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
+-	    (dflt_rc_cal_val);
+-	write_phy_reg(pi, 0x933, flt_val);
+-	write_phy_reg(pi, 0x934, flt_val);
+-	write_phy_reg(pi, 0x935, flt_val);
+-	write_phy_reg(pi, 0x936, flt_val);
+-	write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
+-
+-	return;
+-}
+-
+-static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi)
+-{
+-	s8 txpwr = 0;
+-	int i;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		u16 cckpo = 0;
+-		u32 offset_ofdm, offset_mcs;
+-
+-		pi_lcn->lcnphy_tr_isolation_mid =
+-		    (u8) PHY_GETINTVAR(pi, "triso2g");
+-
+-		pi_lcn->lcnphy_rx_power_offset =
+-		    (u8) PHY_GETINTVAR(pi, "rxpo2g");
+-
+-		pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0");
+-		pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1");
+-		pi->txpa_2g[2] = (s16) PHY_GETINTVAR(pi, "pa0b2");
+-
+-		pi_lcn->lcnphy_rssi_vf = (u8) PHY_GETINTVAR(pi, "rssismf2g");
+-		pi_lcn->lcnphy_rssi_vc = (u8) PHY_GETINTVAR(pi, "rssismc2g");
+-		pi_lcn->lcnphy_rssi_gs = (u8) PHY_GETINTVAR(pi, "rssisav2g");
+-
+-		{
+-			pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
+-			pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
+-			pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
+-
+-			pi_lcn->lcnphy_rssi_vf_hightemp =
+-			    pi_lcn->lcnphy_rssi_vf;
+-			pi_lcn->lcnphy_rssi_vc_hightemp =
+-			    pi_lcn->lcnphy_rssi_vc;
+-			pi_lcn->lcnphy_rssi_gs_hightemp =
+-			    pi_lcn->lcnphy_rssi_gs;
+-		}
+-
+-		txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0");
+-		pi->tx_srom_max_2g = txpwr;
+-
+-		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
+-			pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
+-			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
+-		}
+-
+-		cckpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
+-		if (cckpo) {
+-			uint max_pwr_chan = txpwr;
+-
+-			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+-				pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+-				    ((cckpo & 0xf) * 2);
+-				cckpo >>= 4;
+-			}
+-
+-			offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+-				pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+-				    ((offset_ofdm & 0xf) * 2);
+-				offset_ofdm >>= 4;
+-			}
+-		} else {
+-			u8 opo = 0;
+-
+-			opo = (u8) PHY_GETINTVAR(pi, "opo");
+-
+-			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+-				pi->tx_srom_max_rate_2g[i] = txpwr;
+-			}
+-
+-			offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-
+-			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+-				pi->tx_srom_max_rate_2g[i] = txpwr -
+-				    ((offset_ofdm & 0xf) * 2);
+-				offset_ofdm >>= 4;
+-			}
+-			offset_mcs =
+-			    ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) |
+-			    (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
+-			pi_lcn->lcnphy_mcs20_po = offset_mcs;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i] =
+-				    txpwr - ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		}
+-
+-		pi_lcn->lcnphy_rawtempsense =
+-		    (u16) PHY_GETINTVAR(pi, "rawtempsense");
+-		pi_lcn->lcnphy_measPower =
+-		    (u8) PHY_GETINTVAR(pi, "measpower");
+-		pi_lcn->lcnphy_tempsense_slope =
+-		    (u8) PHY_GETINTVAR(pi, "tempsense_slope");
+-		pi_lcn->lcnphy_hw_iqcal_en =
+-		    (bool) PHY_GETINTVAR(pi, "hw_iqcal_en");
+-		pi_lcn->lcnphy_iqcal_swp_dis =
+-		    (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis");
+-		pi_lcn->lcnphy_tempcorrx =
+-		    (u8) PHY_GETINTVAR(pi, "tempcorrx");
+-		pi_lcn->lcnphy_tempsense_option =
+-		    (u8) PHY_GETINTVAR(pi, "tempsense_option");
+-		pi_lcn->lcnphy_freqoffset_corr =
+-		    (u8) PHY_GETINTVAR(pi, "freqoffset_corr");
+-		if ((u8) getintvar(pi->vars, "aa2g") > 1)
+-			wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi,
+-					      (u8) getintvar(pi->vars,
+-								"aa2g"));
+-	}
+-	pi_lcn->lcnphy_cck_dig_filt_type = -1;
+-	if (PHY_GETVAR(pi, "cckdigfilttype")) {
+-		s16 temp;
+-		temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype");
+-		if (temp >= 0) {
+-			pi_lcn->lcnphy_cck_dig_filt_type = temp;
+-		}
+-	}
+-
+-	return true;
+-}
+-
+-void wlc_2064_vco_cal(phy_info_t *pi)
+-{
+-	u8 calnrst;
+-
+-	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
+-	calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst);
+-	udelay(1);
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
+-	udelay(1);
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
+-	udelay(300);
+-	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
+-}
+-
+-static void
+-wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel)
+-{
+-	uint i;
+-	const chan_info_2064_lcnphy_t *ci;
+-	u8 rfpll_doubler = 0;
+-	u8 pll_pwrup, pll_pwrup_ovr;
+-	fixed qFxtal, qFref, qFvco, qFcal;
+-	u8 d15, d16, f16, e44, e45;
+-	u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
+-	u16 loop_bw, d30, setCount;
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-	ci = &chan_info_2064_lcnphy[0];
+-	rfpll_doubler = 1;
+-
+-	mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
+-
+-	write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
+-	if (!rfpll_doubler) {
+-		loop_bw = PLL_2064_LOOP_BW;
+-		d30 = PLL_2064_D30;
+-	} else {
+-		loop_bw = PLL_2064_LOOP_BW_DOUBLER;
+-		d30 = PLL_2064_D30_DOUBLER;
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
+-			if (chan_info_2064_lcnphy[i].chan == channel)
+-				break;
+-
+-		if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) {
+-			return;
+-		}
+-
+-		ci = &chan_info_2064_lcnphy[i];
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
+-		      (ci->logen_rccr_rx) << 2);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
+-		      (ci->pa_rxrf_lna2_freq_tune) << 4);
+-
+-	write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
+-
+-	pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
+-	pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
+-
+-	or_radio_reg(pi, RADIO_2064_REG044, 0x07);
+-
+-	or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
+-	e44 = 0;
+-	e45 = 0;
+-
+-	fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
+-	if (pi->xtalfreq > 26000000)
+-		e44 = 1;
+-	if (pi->xtalfreq > 52000000)
+-		e45 = 1;
+-	if (e44 == 0)
+-		fcal_div = 1;
+-	else if (e45 == 0)
+-		fcal_div = 2;
+-	else
+-		fcal_div = 4;
+-	fvco3 = (ci->freq * 3);
+-	fref3 = 2 * fpfd;
+-
+-	qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
+-	qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
+-	qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
+-	qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
+-
+-	write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
+-
+-	d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
+-	write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
+-	write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
+-
+-	d16 = (qFcal * 8 / (d15 + 1)) - 1;
+-	write_radio_reg(pi, RADIO_2064_REG051, d16);
+-
+-	f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
+-	setCount = f16 * 3 * (ci->freq) / 32 - 1;
+-	mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
+-		      (u8) (setCount >> 8));
+-
+-	or_radio_reg(pi, RADIO_2064_REG053, 0x10);
+-	write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
+-
+-	div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
+-
+-	div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
+-	while (div_frac >= fref3) {
+-		div_int++;
+-		div_frac -= fref3;
+-	}
+-	div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
+-		      (u8) (div_int >> 4));
+-	mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
+-		      (u8) (div_int << 4));
+-	mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
+-		      (u8) (div_frac >> 16));
+-	write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
+-	write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
+-
+-	write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
+-
+-	write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
+-	write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
+-	write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
+-
+-	{
+-		u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current;
+-		u16 c29, c38, c30, g30, d28;
+-		c29 = loop_bw;
+-		d29 = 200;
+-		c38 = 1250;
+-		h29 = d29 / c29;
+-		h23 = 1;
+-		c28 = 30;
+-		d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
+-			(fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
+-		       (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
+-		    + PLL_2064_LOW_END_KVCO;
+-		h28_ten = (d28 * 10) / c28;
+-		c30 = 2640;
+-		e30 = (d30 - 680) / 490;
+-		g30 = 680 + (e30 * 490);
+-		h30_ten = (g30 * 10) / c30;
+-		cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten;
+-		mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
+-	}
+-	if (channel >= 1 && channel <= 5)
+-		write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
+-	else
+-		write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
+-	write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
+-	udelay(1);
+-
+-	wlc_2064_vco_cal(pi);
+-
+-	write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
+-	write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-		write_radio_reg(pi, RADIO_2064_REG038, 3);
+-		write_radio_reg(pi, RADIO_2064_REG091, 7);
+-	}
+-}
+-
+-bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi)
+-{
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return 0;
+-	else
+-		return (LCNPHY_TX_PWR_CTRL_HW ==
+-			wlc_lcnphy_get_tx_pwr_ctrl((pi)));
+-}
+-
+-void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi)
+-{
+-	u16 pwr_ctrl;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-		wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+-	} else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+-
+-		pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-		wlc_lcnphy_txpower_recalc_target(pi);
+-
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
+-	} else
+-		return;
+-}
+-
+-void wlc_phy_detach_lcnphy(phy_info_t *pi)
+-{
+-	kfree(pi->u.pi_lcnphy);
+-}
+-
+-bool wlc_phy_attach_lcnphy(phy_info_t *pi)
+-{
+-	phy_info_lcnphy_t *pi_lcn;
+-
+-	pi->u.pi_lcnphy = kzalloc(sizeof(phy_info_lcnphy_t), GFP_ATOMIC);
+-	if (pi->u.pi_lcnphy == NULL) {
+-		return false;
+-	}
+-
+-	pi_lcn = pi->u.pi_lcnphy;
+-
+-	if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) {
+-		pi->hwpwrctrl = true;
+-		pi->hwpwrctrl_capable = true;
+-	}
+-
+-	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
+-	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
+-
+-	pi->pi_fptr.init = wlc_phy_init_lcnphy;
+-	pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
+-	pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
+-	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
+-	pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
+-	pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
+-	pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
+-	pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
+-	pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
+-
+-	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
+-		return false;
+-
+-	if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+-		if (pi_lcn->lcnphy_tempsense_option == 3) {
+-			pi->hwpwrctrl = true;
+-			pi->hwpwrctrl_capable = true;
+-			pi->temppwrctrl_capable = false;
+-		} else {
+-			pi->hwpwrctrl = false;
+-			pi->hwpwrctrl_capable = false;
+-			pi->temppwrctrl_capable = true;
+-		}
+-	}
+-
+-	return true;
+-}
+-
+-static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain)
+-{
+-	u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
+-
+-	trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
+-	ext_lna = (u16) (gain >> 29) & 0x01;
+-	lna1 = (u16) (gain >> 0) & 0x0f;
+-	lna2 = (u16) (gain >> 4) & 0x0f;
+-	tia = (u16) (gain >> 8) & 0xf;
+-	biq0 = (u16) (gain >> 12) & 0xf;
+-	biq1 = (u16) (gain >> 16) & 0xf;
+-
+-	gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
+-			     ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
+-			     ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
+-	gain16_19 = biq1;
+-
+-	mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
+-	mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-	mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+-	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+-	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+-		mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
+-	}
+-	wlc_lcnphy_rx_gain_override_enable(pi, true);
+-}
+-
+-static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index)
+-{
+-	u32 received_power = 0;
+-	s32 max_index = 0;
+-	u32 gain_code = 0;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	max_index = 36;
+-	if (*gain_index >= 0)
+-		gain_code = lcnphy_23bitgaincode_table[*gain_index];
+-
+-	if (-1 == *gain_index) {
+-		*gain_index = 0;
+-		while ((*gain_index <= (s32) max_index)
+-		       && (received_power < 700)) {
+-			wlc_lcnphy_set_rx_gain(pi,
+-					       lcnphy_23bitgaincode_table
+-					       [*gain_index]);
+-			received_power =
+-			    wlc_lcnphy_measure_digital_power(pi,
+-							     pi_lcn->
+-							     lcnphy_noise_samples);
+-			(*gain_index)++;
+-		}
+-		(*gain_index)--;
+-	} else {
+-		wlc_lcnphy_set_rx_gain(pi, gain_code);
+-		received_power =
+-		    wlc_lcnphy_measure_digital_power(pi,
+-						     pi_lcn->
+-						     lcnphy_noise_samples);
+-	}
+-
+-	return received_power;
+-}
+-
+-s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index)
+-{
+-	s32 gain = 0;
+-	s32 nominal_power_db;
+-	s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
+-	    input_power_db;
+-	s32 received_power, temperature;
+-	uint freq;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
+-
+-	gain = lcnphy_gain_table[gain_index];
+-
+-	nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
+-
+-	{
+-		u32 power = (received_power * 16);
+-		u32 msb1, msb2, val1, val2, diff1, diff2;
+-		msb1 = ffs(power) - 1;
+-		msb2 = msb1 + 1;
+-		val1 = 1 << msb1;
+-		val2 = 1 << msb2;
+-		diff1 = (power - val1);
+-		diff2 = (val2 - power);
+-		if (diff1 < diff2)
+-			log_val = msb1;
+-		else
+-			log_val = msb2;
+-	}
+-
+-	log_val = log_val * 3;
+-
+-	gain_mismatch = (nominal_power_db / 2) - (log_val);
+-
+-	desired_gain = gain + gain_mismatch;
+-
+-	input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
+-
+-	if (input_power_offset_db > 127)
+-		input_power_offset_db -= 256;
+-
+-	input_power_db = input_power_offset_db - desired_gain;
+-
+-	input_power_db =
+-	    input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
+-
+-	freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
+-	if ((freq > 2427) && (freq <= 2467))
+-		input_power_db = input_power_db - 1;
+-
+-	temperature = pi_lcn->lcnphy_lastsensed_temperature;
+-
+-	if ((temperature - 15) < -30) {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+-		    7;
+-	} else if ((temperature - 15) < 4) {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+-		    3;
+-	} else {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12);
+-	}
+-
+-	wlc_lcnphy_rx_gain_override_enable(pi, 0);
+-
+-	return input_power_db;
+-}
+-
+-static int
+-wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type)
+-{
+-	s16 filt_index = -1;
+-	int j;
+-
+-	u16 addr[] = {
+-		0x910,
+-		0x91e,
+-		0x91f,
+-		0x924,
+-		0x925,
+-		0x926,
+-		0x920,
+-		0x921,
+-		0x927,
+-		0x928,
+-		0x929,
+-		0x922,
+-		0x923,
+-		0x930,
+-		0x931,
+-		0x932
+-	};
+-
+-	u16 addr_ofdm[] = {
+-		0x90f,
+-		0x900,
+-		0x901,
+-		0x906,
+-		0x907,
+-		0x908,
+-		0x902,
+-		0x903,
+-		0x909,
+-		0x90a,
+-		0x90b,
+-		0x904,
+-		0x905,
+-		0x90c,
+-		0x90d,
+-		0x90e
+-	};
+-
+-	if (!is_ofdm) {
+-		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
+-			if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
+-				filt_index = (s16) j;
+-				break;
+-			}
+-		}
+-
+-		if (filt_index != -1) {
+-			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, addr[j],
+-					      LCNPHY_txdigfiltcoeffs_cck
+-					      [filt_index][j + 1]);
+-			}
+-		}
+-	} else {
+-		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
+-			if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
+-				filt_index = (s16) j;
+-				break;
+-			}
+-		}
+-
+-		if (filt_index != -1) {
+-			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, addr_ofdm[j],
+-					      LCNPHY_txdigfiltcoeffs_ofdm
+-					      [filt_index][j + 1]);
+-			}
+-		}
+-	}
+-
+-	return (filt_index != -1) ? 0 : -1;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
+deleted file mode 100644
+index b7bfc72..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
++++ /dev/null
+@@ -1,119 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_lcn_h_
+-#define _wlc_phy_lcn_h_
+-
+-struct phy_info_lcnphy {
+-	int lcnphy_txrf_sp_9_override;
+-	u8 lcnphy_full_cal_channel;
+-	u8 lcnphy_cal_counter;
+-	u16 lcnphy_cal_temper;
+-	bool lcnphy_recal;
+-
+-	u8 lcnphy_rc_cap;
+-	u32 lcnphy_mcs20_po;
+-
+-	u8 lcnphy_tr_isolation_mid;
+-	u8 lcnphy_tr_isolation_low;
+-	u8 lcnphy_tr_isolation_hi;
+-
+-	u8 lcnphy_bx_arch;
+-	u8 lcnphy_rx_power_offset;
+-	u8 lcnphy_rssi_vf;
+-	u8 lcnphy_rssi_vc;
+-	u8 lcnphy_rssi_gs;
+-	u8 lcnphy_tssi_val;
+-	u8 lcnphy_rssi_vf_lowtemp;
+-	u8 lcnphy_rssi_vc_lowtemp;
+-	u8 lcnphy_rssi_gs_lowtemp;
+-
+-	u8 lcnphy_rssi_vf_hightemp;
+-	u8 lcnphy_rssi_vc_hightemp;
+-	u8 lcnphy_rssi_gs_hightemp;
+-
+-	s16 lcnphy_pa0b0;
+-	s16 lcnphy_pa0b1;
+-	s16 lcnphy_pa0b2;
+-
+-	u16 lcnphy_rawtempsense;
+-	u8 lcnphy_measPower;
+-	u8 lcnphy_tempsense_slope;
+-	u8 lcnphy_freqoffset_corr;
+-	u8 lcnphy_tempsense_option;
+-	u8 lcnphy_tempcorrx;
+-	bool lcnphy_iqcal_swp_dis;
+-	bool lcnphy_hw_iqcal_en;
+-	uint lcnphy_bandedge_corr;
+-	bool lcnphy_spurmod;
+-	u16 lcnphy_tssi_tx_cnt;
+-	u16 lcnphy_tssi_idx;
+-	u16 lcnphy_tssi_npt;
+-
+-	u16 lcnphy_target_tx_freq;
+-	s8 lcnphy_tx_power_idx_override;
+-	u16 lcnphy_noise_samples;
+-
+-	u32 lcnphy_papdRxGnIdx;
+-	u32 lcnphy_papd_rxGnCtrl_init;
+-
+-	u32 lcnphy_gain_idx_14_lowword;
+-	u32 lcnphy_gain_idx_14_hiword;
+-	u32 lcnphy_gain_idx_27_lowword;
+-	u32 lcnphy_gain_idx_27_hiword;
+-	s16 lcnphy_ofdmgainidxtableoffset;
+-	s16 lcnphy_dsssgainidxtableoffset;
+-	u32 lcnphy_tr_R_gain_val;
+-	u32 lcnphy_tr_T_gain_val;
+-	s8 lcnphy_input_pwr_offset_db;
+-	u16 lcnphy_Med_Low_Gain_db;
+-	u16 lcnphy_Very_Low_Gain_db;
+-	s8 lcnphy_lastsensed_temperature;
+-	s8 lcnphy_pkteng_rssi_slope;
+-	u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
+-	u8 lcnphy_volt_winner;
+-	u8 lcnphy_volt_low;
+-	u8 lcnphy_54_48_36_24mbps_backoff;
+-	u8 lcnphy_11n_backoff;
+-	u8 lcnphy_lowerofdm;
+-	u8 lcnphy_cck;
+-	u8 lcnphy_psat_2pt3_detected;
+-	s32 lcnphy_lowest_Re_div_Im;
+-	s8 lcnphy_final_papd_cal_idx;
+-	u16 lcnphy_extstxctrl4;
+-	u16 lcnphy_extstxctrl0;
+-	u16 lcnphy_extstxctrl1;
+-	s16 lcnphy_cck_dig_filt_type;
+-	s16 lcnphy_ofdm_dig_filt_type;
+-	lcnphy_cal_results_t lcnphy_cal_results;
+-
+-	u8 lcnphy_psat_pwr;
+-	u8 lcnphy_psat_indx;
+-	s32 lcnphy_min_phase;
+-	u8 lcnphy_final_idx;
+-	u8 lcnphy_start_idx;
+-	u8 lcnphy_current_index;
+-	u16 lcnphy_logen_buf_1;
+-	u16 lcnphy_local_ovr_2;
+-	u16 lcnphy_local_oval_6;
+-	u16 lcnphy_local_oval_5;
+-	u16 lcnphy_logen_mixer_1;
+-
+-	u8 lcnphy_aci_stat;
+-	uint lcnphy_aci_start_time;
+-	s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
+-};
+-#endif				/* _wlc_phy_lcn_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
+deleted file mode 100644
+index 7127509..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
++++ /dev/null
+@@ -1,29169 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <wlc_cfg.h>
+-#include <linux/delay.h>
+-#include <linux/pci.h>
+-#include <aiutils.h>
+-#include <sbchipc.h>
+-#include <wlc_pmu.h>
+-
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include <wlc_phy_radio.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phyreg_n.h>
+-#include <wlc_phytbl_n.h>
+-
+-#define	READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+-	((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1))
+-#define	WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+-	((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value);
+-#define	WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
+-	write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value);
+-
+-#define	READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+-	radio_type##_##jspace##1##_##reg_name));
+-#define	WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+-	radio_type##_##jspace##1##_##reg_name), value);
+-#define	READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+-	radio_type##_##reg_name##_##jspace##1));
+-#define	WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+-	radio_type##_##reg_name##_##jspace##1), value);
+-
+-#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
+-#define NPHY_ACI_CHANNEL_DELTA 5
+-#define NPHY_ACI_CHANNEL_SKIP 4
+-#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
+-#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
+-#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
+-#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
+-#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
+-#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
+-
+-#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_NOASSOC_ENTER_TH  400
+-
+-#define NPHY_NOISE_ASSOC_ENTER_TH  400
+-
+-#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH  400
+-
+-#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
+-#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
+-
+-#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
+-
+-#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
+-
+-#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
+-
+-#define NPHY_RSSICAL_MAXREAD 31
+-
+-#define NPHY_RSSICAL_NPOLL 8
+-#define NPHY_RSSICAL_MAXD  (1<<20)
+-#define NPHY_MIN_RXIQ_PWR 2
+-
+-#define NPHY_RSSICAL_W1_TARGET 25
+-#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
+-#define NPHY_RSSICAL_NB_TARGET 0
+-
+-#define NPHY_RSSICAL_W1_TARGET_REV3 29
+-#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
+-
+-#define NPHY_CALSANITY_RSSI_NB_MAX_POS  9
+-#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
+-#define NPHY_CALSANITY_RSSI_W1_MAX_POS  12
+-#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD)
+-#define NPHY_CALSANITY_RSSI_W2_MAX_POS  NPHY_CALSANITY_RSSI_W1_MAX_POS
+-#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD)
+-#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
+-#define NPHY_RSSI_NB_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
+-#define NPHY_RSSI_W1_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
+-#define NPHY_RSSI_W2_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
+-
+-#define NPHY_IQCAL_NUMGAINS 9
+-#define NPHY_N_GCTL 0x66
+-
+-#define NPHY_PAPD_EPS_TBL_SIZE 64
+-#define NPHY_PAPD_SCL_TBL_SIZE 64
+-#define NPHY_NUM_DIG_FILT_COEFFS 15
+-
+-#define NPHY_PAPD_COMP_OFF 0
+-#define NPHY_PAPD_COMP_ON  1
+-
+-#define NPHY_SROM_TEMPSHIFT		32
+-#define NPHY_SROM_MAXTEMPOFFSET		16
+-#define NPHY_SROM_MINTEMPOFFSET		-16
+-
+-#define NPHY_CAL_MAXTEMPDELTA		64
+-
+-#define NPHY_NOISEVAR_TBLLEN40 256
+-#define NPHY_NOISEVAR_TBLLEN20 128
+-
+-#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
+-
+-#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
+-
+-typedef struct _nphy_iqcal_params {
+-	u16 txlpf;
+-	u16 txgm;
+-	u16 pga;
+-	u16 pad;
+-	u16 ipa;
+-	u16 cal_gain;
+-	u16 ncorr[5];
+-} nphy_iqcal_params_t;
+-
+-typedef struct _nphy_txiqcal_ladder {
+-	u8 percent;
+-	u8 g_env;
+-} nphy_txiqcal_ladder_t;
+-
+-typedef struct {
+-	nphy_txgains_t gains;
+-	bool useindex;
+-	u8 index;
+-} nphy_ipa_txcalgains_t;
+-
+-typedef struct nphy_papd_restore_state_t {
+-	u16 fbmix[2];
+-	u16 vga_master[2];
+-	u16 intpa_master[2];
+-	u16 afectrl[2];
+-	u16 afeoverride[2];
+-	u16 pwrup[2];
+-	u16 atten[2];
+-	u16 mm;
+-} nphy_papd_restore_state;
+-
+-typedef struct _nphy_ipa_txrxgain {
+-	u16 hpvga;
+-	u16 lpf_biq1;
+-	u16 lpf_biq0;
+-	u16 lna2;
+-	u16 lna1;
+-	s8 txpwrindex;
+-} nphy_ipa_txrxgain_t;
+-
+-#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100},
+-{0, 0, 0, 0, 0, 50},
+-{0, 0, 0, 0, 0, -1},
+-{0, 0, 0, 3, 0, -1},
+-{0, 0, 3, 3, 0, -1},
+-{0, 2, 3, 3, 0, -1}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128},
+-{0, 0, 0, 0, 0, 70},
+-{0, 0, 0, 0, 0, 20},
+-{0, 0, 0, 3, 0, 20},
+-{0, 0, 3, 3, 0, 20},
+-{0, 2, 3, 3, 0, 20}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100},
+-{0, 0, 0, 0, 0, 50},
+-{0, 0, 0, 0, 0, -1},
+-{0, 0, 0, 3, 0, -1},
+-{0, 0, 3, 3, 0, -1},
+-{0, 0, 5, 3, 0, -1}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10},
+-{0, 0, 0, 1, 0, 10},
+-{0, 0, 1, 2, 0, 10},
+-{0, 0, 1, 3, 0, 10},
+-{0, 0, 4, 3, 0, 10},
+-{0, 0, 6, 3, 0, 10}
+-};
+-
+-#define NPHY_RXCAL_TONEAMP 181
+-#define NPHY_RXCAL_TONEFREQ_40MHz 4000
+-#define NPHY_RXCAL_TONEFREQ_20MHz 2000
+-
+-enum {
+-	NPHY_RXCAL_GAIN_INIT = 0,
+-	NPHY_RXCAL_GAIN_UP,
+-	NPHY_RXCAL_GAIN_DOWN
+-};
+-
+-#define wlc_phy_get_papd_nphy(pi) \
+-	(read_phy_reg((pi), 0x1e7) & \
+-			((0x1 << 15) | \
+-			(0x1 << 14) | \
+-			(0x1 << 13)))
+-
+-#define TXFILT_SHAPING_OFDM20   0
+-#define TXFILT_SHAPING_OFDM40   1
+-#define TXFILT_SHAPING_CCK      2
+-#define TXFILT_DEFAULT_OFDM20   3
+-#define TXFILT_DEFAULT_OFDM40   4
+-
+-u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
+-	{-377, 137, -407, 208, -1527, 956, 93, 186, 93,
+-	 230, -44, 230, 201, -191, 201},
+-	{-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
+-	 26, 34, -32, 34},
+-	{-360, 164, -376, 164, -1533, 576, 308, -314, 308,
+-	 121, -73, 121, 91, 124, 91},
+-	{-295, 200, -363, 142, -1391, 826, 151, 301, 151,
+-	 151, 301, 151, 602, -752, 602},
+-	{-92, 58, -96, 49, -104, 44, 17, 35, 17,
+-	 12, 25, 12, 13, 27, 13},
+-	{-375, 136, -399, 209, -1479, 949, 130, 260, 130,
+-	 230, -44, 230, 201, -191, 201},
+-	{0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
+-	 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
+-};
+-
+-typedef struct _chan_info_nphy_2055 {
+-	u16 chan;
+-	u16 freq;
+-	uint unknown;
+-	u8 RF_pll_ref;
+-	u8 RF_rf_pll_mod1;
+-	u8 RF_rf_pll_mod0;
+-	u8 RF_vco_cap_tail;
+-	u8 RF_vco_cal1;
+-	u8 RF_vco_cal2;
+-	u8 RF_pll_lf_c1;
+-	u8 RF_pll_lf_r1;
+-	u8 RF_pll_lf_c2;
+-	u8 RF_lgbuf_cen_buf;
+-	u8 RF_lgen_tune1;
+-	u8 RF_lgen_tune2;
+-	u8 RF_core1_lgbuf_a_tune;
+-	u8 RF_core1_lgbuf_g_tune;
+-	u8 RF_core1_rxrf_reg1;
+-	u8 RF_core1_tx_pga_pad_tn;
+-	u8 RF_core1_tx_mx_bgtrim;
+-	u8 RF_core2_lgbuf_a_tune;
+-	u8 RF_core2_lgbuf_g_tune;
+-	u8 RF_core2_rxrf_reg1;
+-	u8 RF_core2_tx_pga_pad_tn;
+-	u8 RF_core2_tx_mx_bgtrim;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_2055_t;
+-
+-typedef struct _chan_info_nphy_radio205x {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_SYN_pll_vcocal1;
+-	u8 RF_SYN_pll_vcocal2;
+-	u8 RF_SYN_pll_refdiv;
+-	u8 RF_SYN_pll_mmd2;
+-	u8 RF_SYN_pll_mmd1;
+-	u8 RF_SYN_pll_loopfilter1;
+-	u8 RF_SYN_pll_loopfilter2;
+-	u8 RF_SYN_pll_loopfilter3;
+-	u8 RF_SYN_pll_loopfilter4;
+-	u8 RF_SYN_pll_loopfilter5;
+-	u8 RF_SYN_reserved_addr27;
+-	u8 RF_SYN_reserved_addr28;
+-	u8 RF_SYN_reserved_addr29;
+-	u8 RF_SYN_logen_VCOBUF1;
+-	u8 RF_SYN_logen_MIXER2;
+-	u8 RF_SYN_logen_BUF3;
+-	u8 RF_SYN_logen_BUF4;
+-	u8 RF_RX0_lnaa_tune;
+-	u8 RF_RX0_lnag_tune;
+-	u8 RF_TX0_intpaa_boost_tune;
+-	u8 RF_TX0_intpag_boost_tune;
+-	u8 RF_TX0_pada_boost_tune;
+-	u8 RF_TX0_padg_boost_tune;
+-	u8 RF_TX0_pgaa_boost_tune;
+-	u8 RF_TX0_pgag_boost_tune;
+-	u8 RF_TX0_mixa_boost_tune;
+-	u8 RF_TX0_mixg_boost_tune;
+-	u8 RF_RX1_lnaa_tune;
+-	u8 RF_RX1_lnag_tune;
+-	u8 RF_TX1_intpaa_boost_tune;
+-	u8 RF_TX1_intpag_boost_tune;
+-	u8 RF_TX1_pada_boost_tune;
+-	u8 RF_TX1_padg_boost_tune;
+-	u8 RF_TX1_pgaa_boost_tune;
+-	u8 RF_TX1_pgag_boost_tune;
+-	u8 RF_TX1_mixa_boost_tune;
+-	u8 RF_TX1_mixg_boost_tune;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio205x_t;
+-
+-typedef struct _chan_info_nphy_radio2057 {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_vcocal_countval0;
+-	u8 RF_vcocal_countval1;
+-	u8 RF_rfpll_refmaster_sparextalsize;
+-	u8 RF_rfpll_loopfilter_r1;
+-	u8 RF_rfpll_loopfilter_c2;
+-	u8 RF_rfpll_loopfilter_c1;
+-	u8 RF_cp_kpd_idac;
+-	u8 RF_rfpll_mmd0;
+-	u8 RF_rfpll_mmd1;
+-	u8 RF_vcobuf_tune;
+-	u8 RF_logen_mx2g_tune;
+-	u8 RF_logen_mx5g_tune;
+-	u8 RF_logen_indbuf2g_tune;
+-	u8 RF_logen_indbuf5g_tune;
+-	u8 RF_txmix2g_tune_boost_pu_core0;
+-	u8 RF_pad2g_tune_pus_core0;
+-	u8 RF_pga_boost_tune_core0;
+-	u8 RF_txmix5g_boost_tune_core0;
+-	u8 RF_pad5g_tune_misc_pus_core0;
+-	u8 RF_lna2g_tune_core0;
+-	u8 RF_lna5g_tune_core0;
+-	u8 RF_txmix2g_tune_boost_pu_core1;
+-	u8 RF_pad2g_tune_pus_core1;
+-	u8 RF_pga_boost_tune_core1;
+-	u8 RF_txmix5g_boost_tune_core1;
+-	u8 RF_pad5g_tune_misc_pus_core1;
+-	u8 RF_lna2g_tune_core1;
+-	u8 RF_lna5g_tune_core1;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio2057_t;
+-
+-typedef struct _chan_info_nphy_radio2057_rev5 {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_vcocal_countval0;
+-	u8 RF_vcocal_countval1;
+-	u8 RF_rfpll_refmaster_sparextalsize;
+-	u8 RF_rfpll_loopfilter_r1;
+-	u8 RF_rfpll_loopfilter_c2;
+-	u8 RF_rfpll_loopfilter_c1;
+-	u8 RF_cp_kpd_idac;
+-	u8 RF_rfpll_mmd0;
+-	u8 RF_rfpll_mmd1;
+-	u8 RF_vcobuf_tune;
+-	u8 RF_logen_mx2g_tune;
+-	u8 RF_logen_indbuf2g_tune;
+-	u8 RF_txmix2g_tune_boost_pu_core0;
+-	u8 RF_pad2g_tune_pus_core0;
+-	u8 RF_lna2g_tune_core0;
+-	u8 RF_txmix2g_tune_boost_pu_core1;
+-	u8 RF_pad2g_tune_pus_core1;
+-	u8 RF_lna2g_tune_core1;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio2057_rev5_t;
+-
+-typedef struct nphy_sfo_cfg {
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} nphy_sfo_cfg_t;
+-
+-static chan_info_nphy_2055_t chan_info_nphy_2055[] = {
+-	{
+-	 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
+-	{
+-	 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
+-	{
+-	 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
+-	{
+-	 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
+-	{
+-	 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
+-	{
+-	 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
+-	{
+-	 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
+-	{
+-	 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
+-	{
+-	 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
+-	{
+-	 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
+-	{
+-	 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
+-	{
+-	 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
+-	{
+-	 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
+-	{
+-	 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
+-	{
+-	 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+-	 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
+-	{
+-	 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+-	 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
+-	{
+-	 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+-	 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
+-	{
+-	 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+-	 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
+-	{
+-	 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+-	 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
+-	{
+-	 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+-	 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
+-	{
+-	 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+-	 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
+-	{
+-	 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+-	 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
+-	{
+-	 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
+-	 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
+-	{
+-	 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+-	 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
+-	{
+-	 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+-	 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
+-	{
+-	 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+-	 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
+-	{
+-	 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+-	 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
+-	{
+-	 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+-	 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
+-	{
+-	 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+-	 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
+-	{
+-	 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+-	 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
+-	{
+-	 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+-	 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
+-	{
+-	 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+-	 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
+-	{
+-	 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+-	 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
+-	{
+-	 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+-	 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
+-	{
+-	 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+-	 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
+-	{
+-	 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+-	 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
+-	{
+-	 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+-	 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
+-	{
+-	 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+-	 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
+-	{
+-	 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+-	 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
+-	{
+-	 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+-	 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
+-	{
+-	 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+-	 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
+-	{
+-	 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+-	 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
+-	{
+-	 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+-	 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
+-	{
+-	 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+-	 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
+-	{
+-	 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+-	 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
+-	{
+-	 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+-	 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
+-	{
+-	 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+-	 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
+-	{
+-	 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+-	 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
+-	{
+-	 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+-	 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
+-	{
+-	 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+-	 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
+-	{
+-	 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+-	 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
+-	{
+-	 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+-	 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
+-	{
+-	 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+-	 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
+-	{
+-	 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+-	 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
+-	{
+-	 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+-	 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
+-	{
+-	 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
+-	{
+-	 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
+-	{
+-	 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
+-	{
+-	 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
+-	{
+-	 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
+-	{
+-	 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
+-	{
+-	 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
+-	{
+-	 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
+-	{
+-	 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
+-	{
+-	 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
+-	{
+-	 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
+-	{
+-	 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
+-	{
+-	 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
+-	{
+-	 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
+-	{
+-	 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+-	 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
+-	{
+-	 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
+-	{
+-	 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
+-	{
+-	 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
+-	{
+-	 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
+-	{
+-	 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
+-	{
+-	 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
+-	{
+-	 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
+-	{
+-	 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
+-	{
+-	 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
+-	{
+-	 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
+-	{
+-	 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
+-	{
+-	 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
+-	{
+-	 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
+-	{
+-	 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
+-	{
+-	 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
+-	{
+-	 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
+-	{
+-	 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
+-	{
+-	 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
+-	{
+-	 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
+-	{
+-	 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
+-	{
+-	 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
+-	{
+-	 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
+-	{
+-	 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
+-	{
+-	 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
+-	{
+-	 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
+-	{
+-	 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
+-	{
+-	 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
+-	{
+-	 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
+-	{
+-	 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
+-	{
+-	 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
+-	{
+-	 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
+-	{
+-	 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
+-	{
+-	 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
+-	{
+-	 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
+-	{
+-	 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
+-	{
+-	 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
+-	{
+-	 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
+-	{
+-	 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
+-	{
+-	 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
+-	{
+-	 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
+-	{
+-	 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
+-	 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
+-	{
+-	 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
+-	{
+-	 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
+-	{
+-	 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
+-	{
+-	 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
+-	{
+-	 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
+-	 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
+-	{
+-	 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
+-	 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
+-	{
+-	 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
+-	 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
+-	{
+-	 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
+-	 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
+-	{
+-	 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
+-	 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
+-	{
+-	 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
+-	 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
+-	{
+-	 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
+-	 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
+-	{
+-	 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
+-	 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
+-	{
+-	 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
+-	 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+-	 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+-	 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = {
+-	{
+-	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+-	 0x0215,
+-	 0x0216,
+-	 },
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215,
+-	 },
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214,
+-	 },
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213,
+-	 },
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212,
+-	 },
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211,
+-	 },
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f,
+-	 },
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e,
+-	 },
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d,
+-	 },
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c,
+-	 },
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b,
+-	 },
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a,
+-	 },
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209,
+-	 },
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208,
+-	 },
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207,
+-	 },
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206,
+-	 },
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205,
+-	 },
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204,
+-	 },
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203,
+-	 },
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202,
+-	 },
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201,
+-	 },
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200,
+-	 },
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff,
+-	 },
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd,
+-	 },
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc,
+-	 },
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb,
+-	 },
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa,
+-	 },
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9,
+-	 },
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8,
+-	 },
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7,
+-	 },
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6,
+-	 },
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5,
+-	 },
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4,
+-	 },
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3,
+-	 },
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2,
+-	 },
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1,
+-	 },
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0,
+-	 },
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0,
+-	 },
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef,
+-	 },
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee,
+-	 },
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed,
+-	 },
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec,
+-	 },
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb,
+-	 },
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea,
+-	 },
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9,
+-	 },
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8,
+-	 },
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7,
+-	 },
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6,
+-	 },
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5,
+-	 },
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5,
+-	 },
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4,
+-	 },
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3,
+-	 },
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2,
+-	 },
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1,
+-	 },
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0,
+-	 },
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df,
+-	 },
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de,
+-	 },
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd,
+-	 },
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd,
+-	 },
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc,
+-	 },
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db,
+-	 },
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da,
+-	 },
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9,
+-	 },
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8,
+-	 },
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7,
+-	 },
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7,
+-	 },
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6,
+-	 },
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5,
+-	 },
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4,
+-	 },
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3,
+-	 },
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2,
+-	 },
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2,
+-	 },
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1,
+-	 },
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0,
+-	 },
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf,
+-	 },
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce,
+-	 },
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce,
+-	 },
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd,
+-	 },
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc,
+-	 },
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb,
+-	 },
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb,
+-	 },
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca,
+-	 },
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca,
+-	 },
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9,
+-	 },
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9,
+-	 },
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9,
+-	 },
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8,
+-	 },
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8,
+-	 },
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8,
+-	 },
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7,
+-	 },
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7,
+-	 },
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6,
+-	 },
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6,
+-	 },
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6,
+-	 },
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5,
+-	 },
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5,
+-	 },
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4,
+-	 },
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4,
+-	 },
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4,
+-	 },
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3,
+-	 },
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3,
+-	 },
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2,
+-	 },
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2,
+-	 },
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1,
+-	 },
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0,
+-	 },
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf,
+-	 },
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf,
+-	 },
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be,
+-	 },
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd,
+-	 },
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443,
+-	 },
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441,
+-	 },
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f,
+-	 },
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d,
+-	 },
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a,
+-	 },
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438,
+-	 },
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436,
+-	 },
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434,
+-	 },
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431,
+-	 },
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f,
+-	 },
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d,
+-	 },
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+-	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b,
+-	 },
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+-	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429,
+-	 },
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
+-	 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = {
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+-	 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+-	 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+-	 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+-	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+-	 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+-	 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+-	 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+-	 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+-	 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+-	 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+-	 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+-	 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+-	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+-	 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+-	 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+-	 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = {
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+-	 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+-	 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+-	 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+-	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+-	 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+-	 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+-	 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+-	 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+-	 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+-	 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+-	 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+-	 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+-	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+-	 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+-	 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+-	 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = {
+-	{
+-	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+-	 0x0215,
+-	 0x0216},
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215},
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214},
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213},
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212},
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211},
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f},
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e},
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d},
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c},
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b},
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a},
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209},
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208},
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207},
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206},
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205},
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204},
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203},
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202},
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201},
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200},
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff},
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd},
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc},
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb},
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa},
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9},
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8},
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7},
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6},
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5},
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4},
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3},
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2},
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1},
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0},
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0},
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef},
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee},
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed},
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec},
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb},
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea},
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9},
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8},
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7},
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6},
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5},
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5},
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4},
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3},
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2},
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1},
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0},
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df},
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de},
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd},
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd},
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc},
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db},
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9},
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8},
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7},
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7},
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6},
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5},
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4},
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3},
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2},
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2},
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1},
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0},
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf},
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce},
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce},
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd},
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc},
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9},
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8},
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6},
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4},
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2},
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2},
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1},
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0},
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf},
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf},
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be},
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd},
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = {
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215},
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214},
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213},
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212},
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211},
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f},
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e},
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d},
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c},
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b},
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a},
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209},
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208},
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207},
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206},
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205},
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204},
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203},
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202},
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201},
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200},
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff},
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd},
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc},
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb},
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa},
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9},
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8},
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7},
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6},
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5},
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4},
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3},
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2},
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1},
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0},
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0},
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef},
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee},
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed},
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec},
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb},
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea},
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9},
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8},
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7},
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6},
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5},
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5},
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4},
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3},
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2},
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1},
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0},
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df},
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de},
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd},
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd},
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc},
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db},
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9},
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8},
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7},
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7},
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6},
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5},
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4},
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3},
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2},
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2},
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1},
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0},
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf},
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce},
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce},
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd},
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc},
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9},
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8},
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6},
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4},
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2},
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2},
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1},
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0},
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf},
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf},
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be},
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd},
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-radio_regs_t regs_2055[] = {
+-	{0x02, 0x80, 0x80, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0x27, 0x27, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0x27, 0x27, 0, 0},
+-	{0x07, 0x7f, 0x7f, 1, 1},
+-	{0x08, 0x7, 0x7, 1, 1},
+-	{0x09, 0x7f, 0x7f, 1, 1},
+-	{0x0A, 0x7, 0x7, 1, 1},
+-	{0x0B, 0x15, 0x15, 0, 0},
+-	{0x0C, 0x15, 0x15, 0, 0},
+-	{0x0D, 0x4f, 0x4f, 1, 1},
+-	{0x0E, 0x5, 0x5, 1, 1},
+-	{0x0F, 0x4f, 0x4f, 1, 1},
+-	{0x10, 0x5, 0x5, 1, 1},
+-	{0x11, 0xd0, 0xd0, 0, 0},
+-	{0x12, 0x2, 0x2, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0x40, 0x40, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0xc0, 0xc0, 0, 0},
+-	{0x1E, 0xff, 0xff, 0, 0},
+-	{0x1F, 0xc0, 0xc0, 0, 0},
+-	{0x20, 0xff, 0xff, 0, 0},
+-	{0x21, 0xc0, 0xc0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x2c, 0x2c, 0, 0},
+-	{0x24, 0, 0, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0xa4, 0xa4, 0, 0},
+-	{0x2E, 0x38, 0x38, 0, 0},
+-	{0x2F, 0, 0, 0, 0},
+-	{0x30, 0x4, 0x4, 1, 1},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0xa, 0xa, 0, 0},
+-	{0x33, 0x87, 0x87, 0, 0},
+-	{0x34, 0x9, 0x9, 0, 0},
+-	{0x35, 0x70, 0x70, 0, 0},
+-	{0x36, 0x11, 0x11, 0, 0},
+-	{0x37, 0x18, 0x18, 1, 1},
+-	{0x38, 0x6, 0x6, 0, 0},
+-	{0x39, 0x4, 0x4, 1, 1},
+-	{0x3A, 0x6, 0x6, 0, 0},
+-	{0x3B, 0x9e, 0x9e, 0, 0},
+-	{0x3C, 0x9, 0x9, 0, 0},
+-	{0x3D, 0xc8, 0xc8, 1, 1},
+-	{0x3E, 0x88, 0x88, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0, 0, 0, 0},
+-	{0x42, 0x1, 0x1, 0, 0},
+-	{0x43, 0x2, 0x2, 0, 0},
+-	{0x44, 0x96, 0x96, 0, 0},
+-	{0x45, 0x3e, 0x3e, 0, 0},
+-	{0x46, 0x3e, 0x3e, 0, 0},
+-	{0x47, 0x13, 0x13, 0, 0},
+-	{0x48, 0x2, 0x2, 0, 0},
+-	{0x49, 0x15, 0x15, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0, 0, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0, 0, 0, 0},
+-	{0x50, 0x8, 0x8, 0, 0},
+-	{0x51, 0x8, 0x8, 0, 0},
+-	{0x52, 0x6, 0x6, 0, 0},
+-	{0x53, 0x84, 0x84, 1, 1},
+-	{0x54, 0xc3, 0xc3, 0, 0},
+-	{0x55, 0x8f, 0x8f, 0, 0},
+-	{0x56, 0xff, 0xff, 0, 0},
+-	{0x57, 0xff, 0xff, 0, 0},
+-	{0x58, 0x88, 0x88, 0, 0},
+-	{0x59, 0x88, 0x88, 0, 0},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0xcc, 0xcc, 0, 0},
+-	{0x5C, 0x6, 0x6, 0, 0},
+-	{0x5D, 0x80, 0x80, 0, 0},
+-	{0x5E, 0x80, 0x80, 0, 0},
+-	{0x5F, 0xf8, 0xf8, 0, 0},
+-	{0x60, 0x88, 0x88, 0, 0},
+-	{0x61, 0x88, 0x88, 0, 0},
+-	{0x62, 0x88, 0x8, 1, 1},
+-	{0x63, 0x88, 0x88, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0x1, 0x1, 1, 1},
+-	{0x66, 0x8a, 0x8a, 0, 0},
+-	{0x67, 0x8, 0x8, 0, 0},
+-	{0x68, 0x83, 0x83, 0, 0},
+-	{0x69, 0x6, 0x6, 0, 0},
+-	{0x6A, 0xa0, 0xa0, 0, 0},
+-	{0x6B, 0xa, 0xa, 0, 0},
+-	{0x6C, 0x87, 0x87, 1, 1},
+-	{0x6D, 0x2a, 0x2a, 0, 0},
+-	{0x6E, 0x2a, 0x2a, 0, 0},
+-	{0x6F, 0x2a, 0x2a, 0, 0},
+-	{0x70, 0x2a, 0x2a, 0, 0},
+-	{0x71, 0x18, 0x18, 0, 0},
+-	{0x72, 0x6a, 0x6a, 1, 1},
+-	{0x73, 0xab, 0xab, 1, 1},
+-	{0x74, 0x13, 0x13, 1, 1},
+-	{0x75, 0xc1, 0xc1, 1, 1},
+-	{0x76, 0xaa, 0xaa, 1, 1},
+-	{0x77, 0x87, 0x87, 1, 1},
+-	{0x78, 0, 0, 0, 0},
+-	{0x79, 0x6, 0x6, 0, 0},
+-	{0x7A, 0x7, 0x7, 0, 0},
+-	{0x7B, 0x7, 0x7, 0, 0},
+-	{0x7C, 0x15, 0x15, 0, 0},
+-	{0x7D, 0x55, 0x55, 0, 0},
+-	{0x7E, 0x97, 0x97, 1, 1},
+-	{0x7F, 0x8, 0x8, 0, 0},
+-	{0x80, 0x14, 0x14, 1, 1},
+-	{0x81, 0x33, 0x33, 0, 0},
+-	{0x82, 0x88, 0x88, 0, 0},
+-	{0x83, 0x6, 0x6, 0, 0},
+-	{0x84, 0x3, 0x3, 1, 1},
+-	{0x85, 0xa, 0xa, 0, 0},
+-	{0x86, 0x3, 0x3, 1, 1},
+-	{0x87, 0x2a, 0x2a, 0, 0},
+-	{0x88, 0xa4, 0xa4, 0, 0},
+-	{0x89, 0x18, 0x18, 0, 0},
+-	{0x8A, 0x28, 0x28, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0x4a, 0x4a, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0xf8, 0xf8, 0, 0},
+-	{0x8F, 0x88, 0x88, 0, 0},
+-	{0x90, 0x88, 0x88, 0, 0},
+-	{0x91, 0x88, 0x8, 1, 1},
+-	{0x92, 0x88, 0x88, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0x1, 0x1, 1, 1},
+-	{0x95, 0x8a, 0x8a, 0, 0},
+-	{0x96, 0x8, 0x8, 0, 0},
+-	{0x97, 0x83, 0x83, 0, 0},
+-	{0x98, 0x6, 0x6, 0, 0},
+-	{0x99, 0xa0, 0xa0, 0, 0},
+-	{0x9A, 0xa, 0xa, 0, 0},
+-	{0x9B, 0x87, 0x87, 1, 1},
+-	{0x9C, 0x2a, 0x2a, 0, 0},
+-	{0x9D, 0x2a, 0x2a, 0, 0},
+-	{0x9E, 0x2a, 0x2a, 0, 0},
+-	{0x9F, 0x2a, 0x2a, 0, 0},
+-	{0xA0, 0x18, 0x18, 0, 0},
+-	{0xA1, 0x6a, 0x6a, 1, 1},
+-	{0xA2, 0xab, 0xab, 1, 1},
+-	{0xA3, 0x13, 0x13, 1, 1},
+-	{0xA4, 0xc1, 0xc1, 1, 1},
+-	{0xA5, 0xaa, 0xaa, 1, 1},
+-	{0xA6, 0x87, 0x87, 1, 1},
+-	{0xA7, 0, 0, 0, 0},
+-	{0xA8, 0x6, 0x6, 0, 0},
+-	{0xA9, 0x7, 0x7, 0, 0},
+-	{0xAA, 0x7, 0x7, 0, 0},
+-	{0xAB, 0x15, 0x15, 0, 0},
+-	{0xAC, 0x55, 0x55, 0, 0},
+-	{0xAD, 0x97, 0x97, 1, 1},
+-	{0xAE, 0x8, 0x8, 0, 0},
+-	{0xAF, 0x14, 0x14, 1, 1},
+-	{0xB0, 0x33, 0x33, 0, 0},
+-	{0xB1, 0x88, 0x88, 0, 0},
+-	{0xB2, 0x6, 0x6, 0, 0},
+-	{0xB3, 0x3, 0x3, 1, 1},
+-	{0xB4, 0xa, 0xa, 0, 0},
+-	{0xB5, 0x3, 0x3, 1, 1},
+-	{0xB6, 0x2a, 0x2a, 0, 0},
+-	{0xB7, 0xa4, 0xa4, 0, 0},
+-	{0xB8, 0x18, 0x18, 0, 0},
+-	{0xB9, 0x28, 0x28, 0, 0},
+-	{0xBA, 0, 0, 0, 0},
+-	{0xBB, 0x4a, 0x4a, 0, 0},
+-	{0xBC, 0, 0, 0, 0},
+-	{0xBD, 0x71, 0x71, 0, 0},
+-	{0xBE, 0x72, 0x72, 0, 0},
+-	{0xBF, 0x73, 0x73, 0, 0},
+-	{0xC0, 0x74, 0x74, 0, 0},
+-	{0xC1, 0x75, 0x75, 0, 0},
+-	{0xC2, 0x76, 0x76, 0, 0},
+-	{0xC3, 0x77, 0x77, 0, 0},
+-	{0xC4, 0x78, 0x78, 0, 0},
+-	{0xC5, 0x79, 0x79, 0, 0},
+-	{0xC6, 0x7a, 0x7a, 0, 0},
+-	{0xC7, 0, 0, 0, 0},
+-	{0xC8, 0, 0, 0, 0},
+-	{0xC9, 0, 0, 0, 0},
+-	{0xCA, 0, 0, 0, 0},
+-	{0xCB, 0, 0, 0, 0},
+-	{0xCC, 0, 0, 0, 0},
+-	{0xCD, 0, 0, 0, 0},
+-	{0xCE, 0x6, 0x6, 0, 0},
+-	{0xCF, 0, 0, 0, 0},
+-	{0xD0, 0, 0, 0, 0},
+-	{0xD1, 0x18, 0x18, 0, 0},
+-	{0xD2, 0x88, 0x88, 0, 0},
+-	{0xD3, 0, 0, 0, 0},
+-	{0xD4, 0, 0, 0, 0},
+-	{0xD5, 0, 0, 0, 0},
+-	{0xD6, 0, 0, 0, 0},
+-	{0xD7, 0, 0, 0, 0},
+-	{0xD8, 0, 0, 0, 0},
+-	{0xD9, 0, 0, 0, 0},
+-	{0xDA, 0x6, 0x6, 0, 0},
+-	{0xDB, 0, 0, 0, 0},
+-	{0xDC, 0, 0, 0, 0},
+-	{0xDD, 0x18, 0x18, 0, 0},
+-	{0xDE, 0x88, 0x88, 0, 0},
+-	{0xDF, 0, 0, 0, 0},
+-	{0xE0, 0, 0, 0, 0},
+-	{0xE1, 0, 0, 0, 0},
+-	{0xE2, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0xd, 0xd, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0x74, 0x74, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x99, 0x99, 0, 0},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x44, 0x44, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0xf, 0xf, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0x50, 0x50, 1, 1},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x99, 0x99, 0, 0},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x66, 0x66, 0, 0},
+-	{0x50, 0x66, 0x66, 0, 0},
+-	{0x51, 0x57, 0x57, 0, 0},
+-	{0x52, 0x57, 0x57, 0, 0},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x23, 0x23, 0, 0},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0x2, 0x2, 0, 0},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0xd, 0xd, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0x72, 0x72, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x44, 0x44, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0xf, 0xf, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0x50, 0x50, 1, 1},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x2f, 0x2f, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x71, 0x71, 1, 1},
+-	{0x96, 0x71, 0x71, 1, 1},
+-	{0x97, 0x72, 0x72, 1, 1},
+-	{0x98, 0x73, 0x73, 1, 1},
+-	{0x99, 0x74, 0x74, 1, 1},
+-	{0x9A, 0x75, 0x75, 1, 1},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 1, 1},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0, 0, 1, 1},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x71, 0x71, 1, 1},
+-	{0x96, 0x71, 0x71, 1, 1},
+-	{0x97, 0x72, 0x72, 1, 1},
+-	{0x98, 0x73, 0x73, 1, 1},
+-	{0x99, 0x74, 0x74, 1, 1},
+-	{0x9A, 0x75, 0x75, 1, 1},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 1, 1},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0, 0, 1, 1},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x6, 0x6, 1, 1},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x3f, 0x3f, 1, 1},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0x6, 0x6, 1, 1},
+-	{0x4C, 0x6, 0x6, 1, 1},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x2b, 0x2b, 1, 1},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_20xx_regs_t regs_2057_rev4[] = {
+-	{0x00, 0x84, 0},
+-	{0x01, 0, 0},
+-	{0x02, 0x60, 0},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 1},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0xf7, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x4, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x26, 1},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 1},
+-	{0x3D, 0xff, 1},
+-	{0x3E, 0xff, 1},
+-	{0x3F, 0xff, 1},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x75, 0},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0xa8, 0},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x30, 0},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0x19, 0},
+-	{0x64, 0x62, 0},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0xc8, 0},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x1e, 0},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x1e, 0},
+-	{0x7C, 0x62, 0},
+-	{0x7D, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x9c, 0},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 1},
+-	{0x8B, 0x10, 1},
+-	{0x8C, 0xf0, 1},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0xe1, 0},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 1},
+-	{0xA5, 0x6d, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 1},
+-	{0xA9, 0xc, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 1},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x75, 0},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0xa8, 0},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x30, 0},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0x19, 0},
+-	{0xE9, 0x62, 0},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0xc8, 0},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x1e, 0},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x1e, 0},
+-	{0x101, 0x62, 0},
+-	{0x102, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x9c, 0},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 1},
+-	{0x110, 0x10, 1},
+-	{0x111, 0xf0, 1},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0xe1, 0},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 1},
+-	{0x12A, 0x6d, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 1},
+-	{0x12E, 0xc, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 1},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x152, 0, 0},
+-	{0x153, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0x2, 1},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0xFFFF, 0, 0},
+-};
+-
+-radio_20xx_regs_t regs_2057_rev5[] = {
+-	{0x00, 0, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 1},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0xc, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0x1, 1},
+-	{0x1C2, 0x80, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev5v1[] = {
+-	{0x00, 0x15, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 1},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0x1, 1},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0x1, 1},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0xc, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0x1, 1},
+-	{0x1C2, 0x80, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev7[] = {
+-	{0x00, 0, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x3E, 0xff, 0},
+-	{0x3F, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0x13, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0xee, 1},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0x58, 1},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x13, 1},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x13, 1},
+-	{0x7C, 0x14, 1},
+-	{0x7D, 0xee, 1},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0x13, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0xee, 1},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0x58, 1},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x13, 1},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x13, 1},
+-	{0x101, 0x14, 1},
+-	{0x102, 0xee, 1},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0x5, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0, 0},
+-	{0x1C2, 0xa0, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev8[] = {
+-	{0x00, 0x8, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x3E, 0xff, 0},
+-	{0x3F, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0x58, 1},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x13, 1},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x13, 1},
+-	{0x7C, 0xf, 1},
+-	{0x7D, 0xee, 1},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0x1, 1},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0x58, 1},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x13, 1},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x13, 1},
+-	{0x101, 0xf, 1},
+-	{0x102, 0xee, 1},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0x1, 1},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0x5, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0, 0},
+-	{0x1C2, 0xa0, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
+-
+-static s32 nphy_lnagain_est0[] = { -315, 40370 };
+-static s32 nphy_lnagain_est1[] = { -224, 23242 };
+-
+-static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
+-	{
+-	 {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
+-	 {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
+-	 {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
+-	 {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
+-	 {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
+-	 {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
+-	 {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
+-	 {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
+-	 {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
+-	 },
+-	{
+-	 {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
+-	 {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
+-	 {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
+-	 }
+-};
+-
+-static const u32 nphy_tpc_txgain[] = {
+-	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
+-	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
+-	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
+-	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
+-	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
+-	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
+-	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
+-	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
+-	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
+-	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
+-	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
+-	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
+-	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
+-	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
+-	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
+-	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
+-	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
+-	0x03902942, 0x03902844, 0x03902842, 0x03902744,
+-	0x03902742, 0x03902644, 0x03902642, 0x03902544,
+-	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
+-	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
+-	0x03802842, 0x03802744, 0x03802742, 0x03802644,
+-	0x03802642, 0x03802544, 0x03802542, 0x03802444,
+-	0x03802442, 0x03802344, 0x03802342, 0x03802244,
+-	0x03802242, 0x03802144, 0x03802142, 0x03802044,
+-	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
+-	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
+-	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
+-	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
+-	0x03801842, 0x03801744, 0x03801742, 0x03801644,
+-	0x03801642, 0x03801544, 0x03801542, 0x03801444,
+-	0x03801442, 0x03801344, 0x03801342, 0x00002b00
+-};
+-
+-static const u16 nphy_tpc_loscale[] = {
+-	256, 256, 271, 271, 287, 256, 256, 271,
+-	271, 287, 287, 304, 304, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 341,
+-	341, 362, 362, 383, 383, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 256,
+-	256, 271, 271, 287, 287, 304, 304, 322,
+-	322, 341, 341, 362, 362, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 256,
+-	256, 271, 271, 287, 287, 304, 304, 322,
+-	322, 341, 341, 362, 362, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 341,
+-	341, 362, 362, 383, 383, 406, 406, 430,
+-	430, 455, 455, 482, 482, 511, 511, 541,
+-	541, 573, 573, 607, 607, 643, 643, 681,
+-	681, 722, 722, 764, 764, 810, 810, 858,
+-	858, 908, 908, 962, 962, 1019, 1019, 256
+-};
+-
+-static u32 nphy_tpc_txgain_ipa[] = {
+-	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
+-	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
+-	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
+-	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
+-	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
+-	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
+-	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
+-	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
+-	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
+-	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
+-	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
+-	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
+-	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
+-	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
+-	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
+-	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
+-	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
+-	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
+-	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
+-	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
+-	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
+-	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
+-	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
+-	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
+-	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
+-	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
+-	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
+-	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
+-	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
+-	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
+-	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
+-	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_rev5[] = {
+-	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
+-	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
+-	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
+-	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
+-	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
+-	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
+-	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
+-	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
+-	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
+-	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
+-	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
+-	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
+-	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
+-	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
+-	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
+-	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
+-	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
+-	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
+-	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
+-	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
+-	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
+-	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
+-	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
+-	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
+-	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
+-	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
+-	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
+-	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
+-	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
+-	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
+-	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
+-	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_rev6[] = {
+-	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
+-	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
+-	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
+-	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
+-	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
+-	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
+-	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
+-	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
+-	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
+-	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
+-	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
+-	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
+-	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
+-	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
+-	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
+-	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
+-	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
+-	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
+-	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
+-	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
+-	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
+-	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
+-	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
+-	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
+-	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
+-	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
+-	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
+-	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
+-	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
+-	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
+-	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
+-	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
+-	0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
+-	0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
+-	0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
+-	0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
+-	0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
+-	0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
+-	0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
+-	0x70470028, 0x70470026, 0x70470024, 0x70470022,
+-	0x7047001f, 0x70370027, 0x70370024, 0x70370022,
+-	0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
+-	0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
+-	0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
+-	0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
+-	0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
+-	0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
+-	0x70170019, 0x70170018, 0x70170016, 0x70170015,
+-	0x70170014, 0x70170013, 0x70170012, 0x70170010,
+-	0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
+-	0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
+-	0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
+-	0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
+-	0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
+-	0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
+-	0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
+-	0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
+-	0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
+-	0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
+-	0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
+-	0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
+-	0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
+-	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
+-	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
+-	0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
+-	0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
+-	0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
+-	0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
+-	0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
+-	0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
+-	0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
+-	0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
+-	0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
+-	0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
+-	0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
+-	0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
+-	0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
+-	0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
+-	0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
+-	0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
+-	0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
+-	0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
+-	0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
+-	0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
+-	0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
+-	0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
+-	0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
+-	0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
+-	0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
+-	0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
+-	0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
+-	0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
+-	0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
+-	0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
+-	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
+-	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
+-	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+-	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+-	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+-	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+-	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+-	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+-	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+-	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+-	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+-	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+-	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+-	0x30170028, 0x30170026, 0x30170024, 0x30170022,
+-	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+-	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+-	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+-	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+-	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+-	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+-	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
+-	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+-	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+-	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+-	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+-	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+-	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+-	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+-	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+-	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+-	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+-	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+-	0x30170028, 0x30170026, 0x30170024, 0x30170022,
+-	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+-	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+-	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+-	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+-	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+-	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+-	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g[] = {
+-	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
+-	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
+-	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
+-	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
+-	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
+-	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
+-	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
+-	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
+-	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
+-	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
+-	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
+-	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
+-	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
+-	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
+-	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
+-	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
+-	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
+-	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
+-	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
+-	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
+-	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
+-	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
+-	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
+-	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
+-	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
+-	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
+-	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
+-	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
+-	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
+-	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
+-	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
+-	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
+-	0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
+-	0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
+-	0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
+-	0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
+-	0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
+-	0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
+-	0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
+-	0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
+-	0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
+-	0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
+-	0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
+-	0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
+-	0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
+-	0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
+-	0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
+-	0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
+-	0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
+-	0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
+-	0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
+-	0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
+-	0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
+-	0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
+-	0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
+-	0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
+-	0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
+-	0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
+-	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
+-	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
+-	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+-	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+-	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
+-	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
+-	0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
+-	0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
+-	0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
+-	0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
+-	0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
+-	0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
+-	0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
+-	0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
+-	0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
+-	0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
+-	0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
+-	0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
+-	0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
+-	0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
+-	0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
+-	0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
+-	0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
+-	0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
+-	0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
+-	0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
+-	0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
+-	0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
+-	0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
+-	0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
+-	0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
+-	0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
+-	0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
+-	0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
+-};
+-
+-static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
+-	-114, -108, -98, -91, -84, -78, -70, -62,
+-	-54, -46, -39, -31, -23, -15, -8, 0
+-};
+-
+-static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
+-	-100, -95, -89, -83, -77, -70, -63, -56,
+-	-48, -41, -33, -25, -19, -12, -6, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
+-	-159, -113, -86, -72, -62, -54, -48, -43,
+-	-39, -35, -31, -28, -25, -23, -20, -18,
+-	-17, -15, -13, -11, -10, -8, -7, -6,
+-	-5, -4, -3, -3, -2, -1, -1, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
+-	-109, -109, -82, -68, -58, -50, -44, -39,
+-	-35, -31, -28, -26, -23, -21, -19, -17,
+-	-16, -14, -13, -11, -10, -9, -8, -7,
+-	-5, -5, -4, -3, -2, -1, -1, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
+-	-122, -122, -95, -80, -69, -61, -54, -49,
+-	-43, -39, -35, -32, -28, -26, -23, -21,
+-	-18, -16, -15, -13, -11, -10, -8, -7,
+-	-6, -5, -4, -3, -2, -1, -1, 0
+-};
+-
+-static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
+-	-107, -101, -92, -85, -78, -71, -62, -55,
+-	-47, -39, -32, -24, -19, -12, -6, 0
+-};
+-
+-static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
+-	-110, -104, -95, -88, -81, -74, -66, -58,
+-	-50, -44, -36, -28, -23, -15, -8, 0
+-};
+-
+-static u8 pad_gain_codes_used_2057rev5[] = {
+-	20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
+-	10, 9, 8, 7, 6, 5, 4, 3, 2, 1
+-};
+-
+-static u8 pad_gain_codes_used_2057rev7[] = {
+-	15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+-	5, 4, 3, 2, 1
+-};
+-
+-static u8 pad_all_gain_codes_2057[] = {
+-	31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
+-	21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+-	11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
+-	1, 0
+-};
+-
+-static u8 pga_all_gain_codes_2057[] = {
+-	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+-};
+-
+-static u32 nphy_papd_scaltbl[] = {
+-	0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
+-	0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
+-	0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
+-	0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
+-	0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
+-	0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
+-	0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
+-	0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
+-	0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
+-	0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
+-	0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
+-	0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
+-	0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
+-	0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
+-	0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
+-	0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
+-};
+-
+-static u32 nphy_tpc_txgain_rev3[] = {
+-	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
+-	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
+-	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
+-	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
+-	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
+-	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
+-	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
+-	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
+-	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
+-	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
+-	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
+-	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
+-	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
+-	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
+-	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
+-	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
+-	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
+-	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
+-	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
+-	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
+-	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
+-	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
+-	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
+-	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
+-	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
+-	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
+-	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
+-	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
+-	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
+-	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
+-	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
+-	0x1041003c, 0x1041003b, 0x10410039, 0x10410037
+-};
+-
+-static u32 nphy_tpc_txgain_HiPwrEPA[] = {
+-	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
+-	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
+-	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
+-	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
+-	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
+-	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
+-	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
+-	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
+-	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
+-	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
+-	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
+-	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
+-	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
+-	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
+-	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
+-	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
+-	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
+-	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
+-	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
+-	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
+-	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
+-	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
+-	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
+-	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
+-	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
+-	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
+-	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
+-	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
+-	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
+-	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
+-	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
+-	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
+-};
+-
+-static u32 nphy_tpc_txgain_epa_2057rev3[] = {
+-	0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
+-	0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
+-	0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
+-	0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
+-	0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
+-	0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
+-	0x80390038, 0x80390035, 0x8031003a, 0x80310036,
+-	0x80310033, 0x8029003a, 0x80290037, 0x80290034,
+-	0x80290031, 0x80210039, 0x80210036, 0x80210033,
+-	0x80210030, 0x8019003c, 0x80190039, 0x80190036,
+-	0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
+-	0x80190028, 0x8011003a, 0x80110036, 0x80110033,
+-	0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
+-	0x80110027, 0x80110024, 0x80110022, 0x80110020,
+-	0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
+-	0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
+-	0x80090029, 0x80090027, 0x80090025, 0x80090023,
+-	0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
+-	0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
+-	0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
+-};
+-
+-static u32 nphy_tpc_txgain_epa_2057rev5[] = {
+-	0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
+-	0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
+-	0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
+-	0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
+-	0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
+-	0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
+-	0x10390038, 0x10390035, 0x1031003a, 0x10310036,
+-	0x10310033, 0x1029003a, 0x10290037, 0x10290034,
+-	0x10290031, 0x10210039, 0x10210036, 0x10210033,
+-	0x10210030, 0x1019003c, 0x10190039, 0x10190036,
+-	0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
+-	0x10190028, 0x1011003a, 0x10110036, 0x10110033,
+-	0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
+-	0x10110027, 0x10110024, 0x10110022, 0x10110020,
+-	0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
+-	0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
+-	0x10090029, 0x10090027, 0x10090025, 0x10090023,
+-	0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
+-	0x1009001a, 0x10090018, 0x10090017, 0x10090016,
+-	0x10090015, 0x10090013, 0x10090012, 0x10090011,
+-	0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
+-	0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
+-	0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
+-	0x10090008, 0x10090008, 0x10090007, 0x10090007,
+-	0x10090007, 0x10090006, 0x10090006, 0x10090005,
+-	0x10090005, 0x10090005, 0x10090005, 0x10090004,
+-	0x10090004, 0x10090004, 0x10090004, 0x10090003,
+-	0x10090003, 0x10090003, 0x10090003, 0x10090003,
+-	0x10090003, 0x10090002, 0x10090002, 0x10090002,
+-	0x10090002, 0x10090002, 0x10090002, 0x10090002,
+-	0x10090002, 0x10090002, 0x10090001, 0x10090001,
+-	0x10090001, 0x10090001, 0x10090001, 0x10090001
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev3[] = {
+-	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
+-	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
+-	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
+-	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
+-	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
+-	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
+-	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
+-	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
+-	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
+-	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
+-	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
+-	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
+-	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
+-	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
+-	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
+-	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
+-	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
+-	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
+-	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
+-	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
+-	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
+-	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
+-	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
+-	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
+-	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
+-	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
+-	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
+-	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
+-	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
+-	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
+-	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
+-	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev4[] = {
+-	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
+-	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
+-	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
+-	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
+-	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
+-	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
+-	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
+-	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
+-	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
+-	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
+-	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
+-	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
+-	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
+-	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
+-	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
+-	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
+-	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
+-	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
+-	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
+-	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
+-	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
+-	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
+-	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
+-	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
+-	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
+-	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
+-	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
+-	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
+-	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
+-	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
+-	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
+-	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev5[] = {
+-	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
+-	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
+-	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
+-	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
+-	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
+-	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
+-	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
+-	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
+-	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
+-	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
+-	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
+-	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
+-	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
+-	0x09620039, 0x09620037, 0x09620035, 0x09620033,
+-	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
+-	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
+-	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
+-	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
+-	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
+-	0x06620039, 0x06620037, 0x06620035, 0x06620033,
+-	0x05620046, 0x05620044, 0x05620042, 0x05620040,
+-	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
+-	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
+-	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
+-	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
+-	0x03620038, 0x03620037, 0x03620035, 0x03620033,
+-	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
+-	0x02620046, 0x02620044, 0x02620043, 0x02620042,
+-	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
+-	0x01620043, 0x01620042, 0x01620041, 0x01620040,
+-	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
+-	0x0062003b, 0x00620039, 0x00620037, 0x00620035
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
+-	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
+-	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
+-	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
+-	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
+-	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
+-	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
+-	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
+-	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
+-	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
+-	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
+-	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
+-	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
+-	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
+-	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
+-	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
+-	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
+-	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
+-	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
+-	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
+-	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
+-	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
+-	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
+-	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
+-	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
+-	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
+-	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
+-	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
+-	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
+-	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
+-	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
+-	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
+-	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
+-};
+-
+-static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
+-static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
+-static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
+-	0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a };
+-static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
+-	0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 };
+-
+-static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+-				   chan_info_nphy_radio2057_t **t0,
+-				   chan_info_nphy_radio205x_t **t1,
+-				   chan_info_nphy_radio2057_rev5_t **t2,
+-				   chan_info_nphy_2055_t **t3);
+-static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans,
+-					const nphy_sfo_cfg_t *c);
+-
+-static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi,
+-					    u16 reduction_factr);
+-static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *,
+-					     u32 *buf);
+-static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr);
+-static void wlc_phy_txlpfbw_nphy(phy_info_t *pi);
+-static void wlc_phy_spurwar_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_radio_preinit_2055(phy_info_t *pi);
+-static void wlc_phy_radio_init_2055(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2055(phy_info_t *pi);
+-static void wlc_phy_radio_preinit_205x(phy_info_t *pi);
+-static void wlc_phy_radio_init_2056(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2056(phy_info_t *pi);
+-static void wlc_phy_radio_init_2057(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2057(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi);
+-static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_restore_rssical_nphy(phy_info_t *pi);
+-static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi);
+-static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi);
+-static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg,
+-				      u8 type, bool d);
+-static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rxcore,
+-					     u16 *rg, u8 type);
+-static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble);
+-static void wlc_phy_savecal_nphy(phy_info_t *pi);
+-static void wlc_phy_restorecal_nphy(phy_info_t *pi);
+-static void wlc_phy_resetcca_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi);
+-static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi);
+-static void wlc_phy_precal_txgain_nphy(phy_info_t *pi);
+-static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core);
+-
+-static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi);
+-static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1);
+-static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32,
+-			    u32 e);
+-static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core);
+-static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *,
+-			    phy_cal_mode_t, u8);
+-static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi,
+-					  nphy_papd_restore_state *state);
+-static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi,
+-					nphy_papd_restore_state *state, u8);
+-
+-static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals);
+-
+-static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *evts,
+-				   u8 *dlys, u8 len);
+-
+-static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset);
+-
+-static void
+-wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value,
+-				  u8 core_mask, u8 off,
+-				  u8 override_id);
+-
+-static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type);
+-static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi);
+-
+-static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max,
+-					    u16 *pwr_offset,
+-					    u8 tmp_max_pwr, u8 rate_start,
+-					    u8 rate_end);
+-
+-static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi);
+-
+-static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi);
+-static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core);
+-static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0,
+-					   u8 idx1);
+-static void wlc_phy_a4(phy_info_t *pi, bool full_cal);
+-
+-static u16 wlc_phy_radio205x_rcal(phy_info_t *pi);
+-
+-static u16 wlc_phy_radio2057_rccal(phy_info_t *pi);
+-
+-static u16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz,
+-					    u16 max_val,
+-					    u8 dac_test_mode);
+-static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf,
+-					 u16 num_samps);
+-static void wlc_phy_runsamples_nphy(phy_info_t *pi, u16 n, u16 lps,
+-				    u16 wait, u8 iq, u8 dac_test_mode,
+-				    bool modify_bbmult);
+-
+-bool wlc_phy_bist_check_phy(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u32 phybist0, phybist1, phybist2, phybist3, phybist4;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 16))
+-		return true;
+-
+-	phybist0 = read_phy_reg(pi, 0x0e);
+-	phybist1 = read_phy_reg(pi, 0x0f);
+-	phybist2 = read_phy_reg(pi, 0xea);
+-	phybist3 = read_phy_reg(pi, 0xeb);
+-	phybist4 = read_phy_reg(pi, 0x156);
+-
+-	if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
+-	    (phybist3 == 0) && (phybist4 == 0)) {
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi)
+-{
+-	u16 addr, val;
+-
+-	val = 0x1e1f;
+-	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
+-	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
+-		write_phy_reg(pi, addr, val);
+-		if (addr == (NPHY_TO_BPHY_OFF + 0x97))
+-			val = 0x3e3f;
+-		else
+-			val -= 0x0202;
+-	}
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206);
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e);
+-
+-		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a);
+-
+-	} else {
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
+-	}
+-}
+-
+-void
+-wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset,
+-			 u32 width, const void *data)
+-{
+-	mimophytbl_info_t tbl;
+-
+-	tbl.tbl_id = id;
+-	tbl.tbl_len = len;
+-	tbl.tbl_offset = offset;
+-	tbl.tbl_width = width;
+-	tbl.tbl_ptr = data;
+-	wlc_phy_write_table_nphy(pi, &tbl);
+-}
+-
+-void
+-wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset,
+-			u32 width, void *data)
+-{
+-	mimophytbl_info_t tbl;
+-
+-	tbl.tbl_id = id;
+-	tbl.tbl_len = len;
+-	tbl.tbl_offset = offset;
+-	tbl.tbl_width = width;
+-	tbl.tbl_ptr = data;
+-	wlc_phy_read_table_nphy(pi, &tbl);
+-}
+-
+-static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi)
+-{
+-	uint idx;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 16)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev16[idx]);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev7[idx]);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev3[idx]);
+-	} else {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev0[idx]);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi)
+-{
+-	uint idx = 0;
+-	u8 antswctrllut;
+-
+-	if (pi->phy_init_por)
+-		wlc_phy_static_table_download_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+-		    pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut;
+-
+-		switch (antswctrllut) {
+-		case 0:
+-
+-			break;
+-
+-		case 1:
+-
+-			if (pi->aa2g == 7) {
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_ANTSWCTRLLUT,
+-							 2, 0x21, 8,
+-							 &ant_sw_ctrl_tbl_rev8_2o3
+-							 [0]);
+-			} else {
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_ANTSWCTRLLUT,
+-							 2, 0x21, 8,
+-							 &ant_sw_ctrl_tbl_rev8
+-							 [0]);
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x25, 8,
+-						 &ant_sw_ctrl_tbl_rev8[2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x29, 8,
+-						 &ant_sw_ctrl_tbl_rev8[4]);
+-			break;
+-
+-		case 2:
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x1, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [0]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x5, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x9, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [4]);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x21, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [0]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x25, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x29, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [4]);
+-			break;
+-
+-		default:
+-			break;
+-		}
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
+-
+-			if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
+-				antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+-				    pi->srom_fem2g.antswctrllut : pi->
+-				    srom_fem5g.antswctrllut;
+-				switch (antswctrllut) {
+-				case 0:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile
+-								 [idx]);
+-					break;
+-				case 1:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile1
+-								 [idx]);
+-					break;
+-				case 2:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile2
+-								 [idx]);
+-					break;
+-				case 3:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile3
+-								 [idx]);
+-					break;
+-				default:
+-					break;
+-				}
+-			} else {
+-				wlc_phy_write_table_nphy(pi,
+-							 &mimophytbl_info_rev3_volatile
+-							 [idx]);
+-			}
+-		}
+-	} else {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) {
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev0_volatile
+-						 [idx]);
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_write_txmacreg_nphy(phy_info_t *pi, u16 holdoff, u16 delay)
+-{
+-	write_phy_reg(pi, 0x77, holdoff);
+-	write_phy_reg(pi, 0xb4, delay);
+-}
+-
+-void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs)
+-{
+-	u16 holdoff, delay;
+-
+-	if (rifs) {
+-
+-		holdoff = 0x10;
+-		delay = 0x258;
+-	} else {
+-
+-		holdoff = 0x15;
+-		delay = 0x320;
+-	}
+-
+-	wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
+-
+-	if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) {
+-		pi->sh->_rifs_phy = rifs;
+-	}
+-}
+-
+-bool wlc_phy_attach_nphy(phy_info_t *pi)
+-{
+-	uint i;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) {
+-		pi->phyhang_avoid = true;
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		pi->nphy_gband_spurwar_en = true;
+-
+-		if (pi->sh->boardflags2 & BFL2_SPUR_WAR) {
+-			pi->nphy_aband_spurwar_en = true;
+-		}
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) {
+-			pi->nphy_gband_spurwar2_en = true;
+-		}
+-	}
+-
+-	pi->n_preamble_override = AUTO;
+-	if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
+-		pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE;
+-
+-	pi->nphy_txrx_chain = AUTO;
+-	pi->phy_scraminit = AUTO;
+-
+-	pi->nphy_rxcalparams = 0x010100B5;
+-
+-	pi->nphy_perical = PHY_PERICAL_MPHASE;
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+-	pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
+-
+-	pi->nphy_gain_boost = true;
+-	pi->nphy_elna_gain_config = false;
+-	pi->radio_is_on = false;
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		pi->nphy_txpwrindex[i].index = AUTO;
+-	}
+-
+-	wlc_phy_txpwrctrl_config_nphy(pi);
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+-		pi->hwpwrctrl_capable = true;
+-
+-	pi->pi_fptr.init = wlc_phy_init_nphy;
+-	pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
+-	pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
+-	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
+-
+-	if (!wlc_phy_txpwr_srom_read_nphy(pi))
+-		return false;
+-
+-	return true;
+-}
+-
+-static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi)
+-{
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+-		pi->phy_5g_pwrgain = true;
+-		return;
+-	}
+-
+-	pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
+-	pi->phy_5g_pwrgain = false;
+-
+-	if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
+-	    NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
+-		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+-	else if ((pi->sh->sromrev >= 4)
+-		 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
+-		pi->phy_5g_pwrgain = true;
+-}
+-
+-void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi)
+-{
+-	u16 val;
+-	u16 clip1_ths[2];
+-	nphy_txgains_t target_gain;
+-	u8 tx_pwr_ctrl_state;
+-	bool do_nphy_cal = false;
+-	uint core;
+-	uint origidx, intr_val;
+-	d11regs_t *regs;
+-	u32 d11_clk_ctl_st;
+-
+-	core = 0;
+-
+-	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+-		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+-	}
+-
+-	if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
+-	    ((pi->sh->chippkg == BCM4717_PKG_ID) ||
+-	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
+-		if ((pi->sh->boardflags & BFL_EXTLNA) &&
+-		    (CHSPEC_IS2G(pi->radio_chanspec))) {
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol), 0x40,
+-				   0x40);
+-		}
+-	}
+-
+-	if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) {
+-		si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA,
+-				   CCTRL5357_EXTPA);
+-	}
+-
+-	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
+-	    CHSPEC_IS40(pi->radio_chanspec)) {
+-
+-		regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID,
+-						    &origidx, &intr_val);
+-		d11_clk_ctl_st = R_REG(&regs->clk_ctl_st);
+-		AND_REG(&regs->clk_ctl_st,
+-			~(CCS_FORCEHT | CCS_HTAREQ));
+-
+-		W_REG(&regs->clk_ctl_st, d11_clk_ctl_st);
+-
+-		ai_restore_core(pi->sh->sih, origidx, intr_val);
+-	}
+-
+-	pi->use_int_tx_iqlo_cal_nphy =
+-	    (PHY_IPA(pi) ||
+-	     (NREV_GE(pi->pubpi.phy_rev, 7) ||
+-	      (NREV_GE(pi->pubpi.phy_rev, 5)
+-	       && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
+-
+-	pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
+-
+-	pi->nphy_deaf_count = 0;
+-
+-	wlc_phy_tbl_init_nphy(pi);
+-
+-	pi->nphy_crsminpwr_adjusted = false;
+-	pi->nphy_noisevars_adjusted = false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xe7, 0);
+-		write_phy_reg(pi, 0xec, 0);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			write_phy_reg(pi, 0x342, 0);
+-			write_phy_reg(pi, 0x343, 0);
+-			write_phy_reg(pi, 0x346, 0);
+-			write_phy_reg(pi, 0x347, 0);
+-		}
+-		write_phy_reg(pi, 0xe5, 0);
+-		write_phy_reg(pi, 0xe6, 0);
+-	} else {
+-		write_phy_reg(pi, 0xec, 0);
+-	}
+-
+-	write_phy_reg(pi, 0x91, 0);
+-	write_phy_reg(pi, 0x92, 0);
+-	if (NREV_LT(pi->pubpi.phy_rev, 6)) {
+-		write_phy_reg(pi, 0x93, 0);
+-		write_phy_reg(pi, 0x94, 0);
+-	}
+-
+-	and_phy_reg(pi, 0xa1, ~3);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0x8f, 0);
+-		write_phy_reg(pi, 0xa5, 0);
+-	} else {
+-		write_phy_reg(pi, 0xa5, 0);
+-	}
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 2))
+-		mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+-	else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-		mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+-
+-	write_phy_reg(pi, 0x203, 32);
+-	write_phy_reg(pi, 0x201, 32);
+-
+-	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
+-		write_phy_reg(pi, 0x20d, 160);
+-	else
+-		write_phy_reg(pi, 0x20d, 184);
+-
+-	write_phy_reg(pi, 0x13a, 200);
+-
+-	write_phy_reg(pi, 0x70, 80);
+-
+-	write_phy_reg(pi, 0x1ff, 48);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 8)) {
+-		wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
+-	}
+-
+-	wlc_phy_stf_chain_upd_nphy(pi);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0x180, 0xaa8);
+-		write_phy_reg(pi, 0x181, 0x9a4);
+-	}
+-
+-	if (PHY_IPA(pi)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 0), (1) << 0);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7),
+-				    (pi->nphy_papd_epsilon_offset[core]) << 7);
+-
+-		}
+-
+-		wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-			wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_workarounds_nphy(pi);
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-	val = read_phy_reg(pi, 0x01);
+-	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+-	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-	wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
+-
+-	wlc_phy_pa_override_nphy(pi, OFF);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-	wlc_phy_pa_override_nphy(pi, ON);
+-
+-	wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		wlc_phy_bphy_init_nphy(pi);
+-
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	wlc_phy_txpwr_fixpower_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		u32 *tx_pwrctrl_tbl = NULL;
+-		u16 idx;
+-		s16 pga_gn = 0;
+-		s16 pad_gn = 0;
+-		s32 rfpwr_offset = 0;
+-
+-		if (PHY_IPA(pi)) {
+-			tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if NREV_IS
+-					(pi->pubpi.phy_rev, 3) {
+-					tx_pwrctrl_tbl =
+-					    nphy_tpc_5GHz_txgain_rev3;
+-				} else if NREV_IS
+-					(pi->pubpi.phy_rev, 4) {
+-					tx_pwrctrl_tbl =
+-					    (pi->srom_fem5g.extpagain == 3) ?
+-					    nphy_tpc_5GHz_txgain_HiPwrEPA :
+-					    nphy_tpc_5GHz_txgain_rev4;
+-				} else {
+-					tx_pwrctrl_tbl =
+-					    nphy_tpc_5GHz_txgain_rev5;
+-				}
+-
+-			} else {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (pi->pubpi.radiorev == 5) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_epa_2057rev5;
+-					} else if (pi->pubpi.radiorev == 3) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_epa_2057rev3;
+-					}
+-
+-				} else {
+-					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-					    (pi->srom_fem2g.extpagain == 3)) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_HiPwrEPA;
+-					} else {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_rev3;
+-					}
+-				}
+-			}
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+-					 192, 32, tx_pwrctrl_tbl);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+-					 192, 32, tx_pwrctrl_tbl);
+-
+-		pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			for (idx = 0; idx < 128; idx++) {
+-				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+-				pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
+-
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					if ((pi->pubpi.radiorev == 3) ||
+-					    (pi->pubpi.radiorev == 4) ||
+-					    (pi->pubpi.radiorev == 6)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev3n4
+-						    [pad_gn];
+-					} else if (pi->pubpi.radiorev == 5) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev5
+-						    [pad_gn];
+-					} else if ((pi->pubpi.radiorev == 7)
+-						   || (pi->pubpi.radiorev ==
+-						       8)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev7
+-						    [pad_gn];
+-					}
+-				} else {
+-					if ((pi->pubpi.radiorev == 3) ||
+-					    (pi->pubpi.radiorev == 4) ||
+-					    (pi->pubpi.radiorev == 6)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_pgagain_dlt_5g_2057
+-						    [pga_gn];
+-					} else if ((pi->pubpi.radiorev == 7)
+-						   || (pi->pubpi.radiorev ==
+-						       8)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_pgagain_dlt_5g_2057rev7
+-						    [pga_gn];
+-					}
+-				}
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE1TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE2TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-			}
+-		} else {
+-
+-			for (idx = 0; idx < 128; idx++) {
+-				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					rfpwr_offset = (s16)
+-					    nphy_papd_pga_gain_delta_ipa_2g
+-					    [pga_gn];
+-				} else {
+-					rfpwr_offset = (s16)
+-					    nphy_papd_pga_gain_delta_ipa_5g
+-					    [pga_gn];
+-				}
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE1TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE2TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-			}
+-
+-		}
+-	} else {
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+-					 192, 32, nphy_tpc_txgain);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+-					 192, 32, nphy_tpc_txgain);
+-	}
+-
+-	if (pi->sh->phyrxchain != 0x3) {
+-		wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi,
+-					     pi->sh->phyrxchain);
+-	}
+-
+-	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-		wlc_phy_cal_perical_mphase_restart(pi);
+-	}
+-
+-	if (!NORADIO_ENAB(pi->pubpi)) {
+-		bool do_rssi_cal = false;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+-			    (pi->nphy_rssical_chanspec_2G == 0) :
+-			    (pi->nphy_rssical_chanspec_5G == 0);
+-
+-			if (do_rssi_cal) {
+-				wlc_phy_rssi_cal_nphy(pi);
+-			} else {
+-				wlc_phy_restore_rssical_nphy(pi);
+-			}
+-		} else {
+-			wlc_phy_rssi_cal_nphy(pi);
+-		}
+-
+-		if (!SCAN_RM_IN_PROGRESS(pi)) {
+-			do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+-			    (pi->nphy_iqcal_chanspec_2G == 0) :
+-			    (pi->nphy_iqcal_chanspec_5G == 0);
+-		}
+-
+-		if (!pi->do_initcal)
+-			do_nphy_cal = false;
+-
+-		if (do_nphy_cal) {
+-
+-			target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-
+-			if (pi->antsel_type == ANTSEL_2x3)
+-				wlc_phy_antsel_init((wlc_phy_t *) pi, true);
+-
+-			if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
+-				wlc_phy_rssi_cal_nphy(pi);
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					pi->nphy_cal_orig_pwr_idx[0] =
+-					    pi->nphy_txpwrindex[PHY_CORE_0].
+-					    index_internal;
+-					pi->nphy_cal_orig_pwr_idx[1] =
+-					    pi->nphy_txpwrindex[PHY_CORE_1].
+-					    index_internal;
+-
+-					wlc_phy_precal_txgain_nphy(pi);
+-					target_gain =
+-					    wlc_phy_get_tx_gain_nphy(pi);
+-				}
+-
+-				if (wlc_phy_cal_txiqlo_nphy
+-				    (pi, target_gain, true, false) == 0) {
+-					if (wlc_phy_cal_rxiq_nphy
+-					    (pi, target_gain, 2,
+-					     false) == 0) {
+-						wlc_phy_savecal_nphy(pi);
+-
+-					}
+-				}
+-			} else if (pi->mphase_cal_phase_id ==
+-				   MPHASE_CAL_STATE_IDLE) {
+-
+-				wlc_phy_cal_perical((wlc_phy_t *) pi,
+-						    PHY_PERICAL_PHYINIT);
+-			}
+-		} else {
+-			wlc_phy_restorecal_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-
+-	wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
+-
+-		write_phy_reg(pi, 0x70, 50);
+-
+-	wlc_phy_txlpfbw_nphy(pi);
+-
+-	wlc_phy_spurwar_nphy(pi);
+-
+-}
+-
+-static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble)
+-{
+-	bool gf_preamble = false;
+-	u16 val;
+-
+-	if (preamble == WLC_N_PREAMBLE_GF) {
+-		gf_preamble = true;
+-	}
+-
+-	val = read_phy_reg(pi, 0xed);
+-
+-	val |= RX_GF_MM_AUTO;
+-	val &= ~RX_GF_OR_MM;
+-	if (gf_preamble)
+-		val |= RX_GF_OR_MM;
+-
+-	write_phy_reg(pi, 0xed, val);
+-}
+-
+-static void wlc_phy_resetcca_nphy(phy_info_t *pi)
+-{
+-	u16 val;
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-	val = read_phy_reg(pi, 0x01);
+-	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+-	udelay(1);
+-	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-}
+-
+-void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en)
+-{
+-	u16 rfctrlintc_override_val;
+-
+-	if (!en) {
+-
+-		pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
+-		pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			rfctrlintc_override_val = 0x1480;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			rfctrlintc_override_val =
+-			    CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
+-		} else {
+-			rfctrlintc_override_val =
+-			    CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+-		}
+-
+-		write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+-		write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+-	} else {
+-
+-		write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
+-		write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
+-	}
+-
+-}
+-
+-void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi)
+-{
+-
+-	u16 txrx_chain =
+-	    (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
+-	bool CoreActv_override = false;
+-
+-	if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) {
+-		txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
+-		CoreActv_override = true;
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+-			and_phy_reg(pi, 0xa0, ~0x20);
+-		}
+-	} else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) {
+-		txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
+-		CoreActv_override = true;
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+-			or_phy_reg(pi, 0xa0, 0x20);
+-		}
+-	}
+-
+-	mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
+-
+-	if (CoreActv_override) {
+-
+-		pi->nphy_perical = PHY_PERICAL_DISABLE;
+-		or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+-	} else {
+-		pi->nphy_perical = PHY_PERICAL_MPHASE;
+-		and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
+-	}
+-}
+-
+-void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask)
+-{
+-	u16 regval;
+-	u16 tbl_buf[16];
+-	uint i;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u16 tbl_opcode;
+-	bool suspend;
+-
+-	pi->sh->phyrxchain = rxcore_bitmask;
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	regval = read_phy_reg(pi, 0xa2);
+-	regval &= ~(0xf << 4);
+-	regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
+-	write_phy_reg(pi, 0xa2, regval);
+-
+-	if ((rxcore_bitmask & 0x3) != 0x3) {
+-
+-		write_phy_reg(pi, 0x20e, 1);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (pi->rx2tx_biasentry == -1) {
+-				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							ARRAY_SIZE(tbl_buf), 80,
+-							16, tbl_buf);
+-
+-				for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
+-					if (tbl_buf[i] ==
+-					    NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
+-
+-						pi->rx2tx_biasentry = (u8) i;
+-						tbl_opcode =
+-						    NPHY_REV3_RFSEQ_CMD_NOP;
+-						wlc_phy_table_write_nphy(pi,
+-									 NPHY_TBL_ID_RFSEQ,
+-									 1, i,
+-									 16,
+-									 &tbl_opcode);
+-						break;
+-					} else if (tbl_buf[i] ==
+-						   NPHY_REV3_RFSEQ_CMD_END) {
+-						break;
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		write_phy_reg(pi, 0x20e, 30);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (pi->rx2tx_biasentry != -1) {
+-				tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1, pi->rx2tx_biasentry,
+-							 16, &tbl_opcode);
+-				pi->rx2tx_biasentry = -1;
+-			}
+-		}
+-	}
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih)
+-{
+-	u16 regval, rxen_bits;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	regval = read_phy_reg(pi, 0xa2);
+-	rxen_bits = (regval >> 4) & 0xf;
+-
+-	return (u8) rxen_bits;
+-}
+-
+-bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi)
+-{
+-	return PHY_IPA(pi);
+-}
+-
+-static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi)
+-{
+-	u8 idx, idx2, i, delta_ind;
+-
+-	for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) {
+-		pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
+-	}
+-
+-	for (i = 0; i < 4; i++) {
+-		idx2 = 0;
+-
+-		delta_ind = 0;
+-
+-		switch (i) {
+-		case 0:
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)
+-			    && NPHY_IS_SROM_REINTERPRET) {
+-				idx = TXP_FIRST_MCS_40_SISO;
+-			} else {
+-				idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-				    TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
+-				delta_ind = 1;
+-			}
+-			break;
+-
+-		case 1:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
+-			break;
+-
+-		case 2:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
+-			break;
+-
+-		case 3:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
+-			break;
+-		}
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		idx = idx + delta_ind;
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		idx = idx + 1 - delta_ind;
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-	}
+-}
+-
+-void wlc_phy_cal_init_nphy(phy_info_t *pi)
+-{
+-}
+-
+-static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core)
+-{
+-	if (core == PHY_CORE_0) {
+-		write_phy_reg(pi, 0x38, 0x4);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x37, 0x0060);
+-		} else {
+-			write_phy_reg(pi, 0x37, 0x1080);
+-		}
+-	} else if (core == PHY_CORE_1) {
+-		write_phy_reg(pi, 0x2ae, 0x4);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x2ad, 0x0060);
+-		} else {
+-			write_phy_reg(pi, 0x2ad, 0x1080);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain)
+-{
+-	u8 txchain0, txchain1;
+-
+-	txchain0 = txchain & 0x1;
+-	txchain1 = (txchain & 0x2) >> 1;
+-	if (!txchain0) {
+-		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+-	}
+-
+-	if (!txchain1) {
+-		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy(phy_info_t *pi)
+-{
+-	u8 rfseq_rx2tx_events[] = {
+-		NPHY_RFSEQ_CMD_NOP,
+-		NPHY_RFSEQ_CMD_RXG_FBW,
+-		NPHY_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_RFSEQ_CMD_TX_GAIN,
+-		NPHY_RFSEQ_CMD_EXT_PA
+-	};
+-	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
+-	u8 rfseq_tx2rx_events[] = {
+-		NPHY_RFSEQ_CMD_NOP,
+-		NPHY_RFSEQ_CMD_EXT_PA,
+-		NPHY_RFSEQ_CMD_TX_GAIN,
+-		NPHY_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_RFSEQ_CMD_RXG_FBW,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
+-	};
+-	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+-	u8 rfseq_tx2rx_events_rev3[] = {
+-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+-	u8 rfseq_rx2tx_events_rev3[] = {
+-		NPHY_REV3_RFSEQ_CMD_NOP,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
+-
+-	u8 rfseq_rx2tx_events_rev3_ipa[] = {
+-		NPHY_REV3_RFSEQ_CMD_NOP,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+-	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
+-
+-	s16 alpha0, alpha1, alpha2;
+-	s16 beta0, beta1, beta2;
+-	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
+-	    stbc_data_weights;
+-	u8 chan_freq_range = 0;
+-	u16 dac_control = 0x0002;
+-	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
+-	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
+-	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+-	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+-	u16 *aux_adc_vmid;
+-	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
+-	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
+-	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
+-	u16 *aux_adc_gain;
+-	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+-	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+-	s32 min_nvar_val = 0x18d;
+-	s32 min_nvar_offset_6mbps = 20;
+-	u8 pdetrange;
+-	u8 triso;
+-	u16 regval;
+-	u16 afectrl_adc_ctrl1_rev7 = 0x20;
+-	u16 afectrl_adc_ctrl2_rev7 = 0x0;
+-	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
+-	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+-	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+-	u16 ipalvlshift_3p3_war_en = 0;
+-	u16 rccal_bcap_val, rccal_scap_val;
+-	u16 rccal_tx20_11b_bcap = 0;
+-	u16 rccal_tx20_11b_scap = 0;
+-	u16 rccal_tx20_11n_bcap = 0;
+-	u16 rccal_tx20_11n_scap = 0;
+-	u16 rccal_tx40_11n_bcap = 0;
+-	u16 rccal_tx40_11n_scap = 0;
+-	u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
+-	u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
+-	u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
+-	u16 tx_lpf_bw_ofdm_20mhz = 0;
+-	u16 tx_lpf_bw_ofdm_40mhz = 0;
+-	u16 tx_lpf_bw_11b = 0;
+-	u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
+-	u16 txgm_idac_bleed = 0;
+-	bool rccal_ovrd = false;
+-	u16 freq;
+-	int coreNum;
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
+-	} else {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (!ISSIM_ENAB(pi->sh->sih)) {
+-		or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
+-
+-			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
+-			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
+-			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
+-			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
+-			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
+-			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
+-			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
+-			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
+-			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
+-			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
+-			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
+-			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
+-			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
+-			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
+-			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
+-			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
+-		}
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
+-			write_phy_reg(pi, 0x23f, 0x1b0);
+-			write_phy_reg(pi, 0x240, 0x1b0);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+-					 &dac_control);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+-					 &dac_control);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					1, 0, 32, &leg_data_weights);
+-		leg_data_weights = leg_data_weights & 0xffffff;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 0, 32, &leg_data_weights);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 2, 0x15e, 16,
+-					 rfseq_rx2tx_dacbufpu_rev7);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
+-					 rfseq_rx2tx_dacbufpu_rev7);
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3_ipa,
+-					       rfseq_rx2tx_dlys_rev3_ipa,
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa) /
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa
+-						[0]));
+-		}
+-
+-		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
+-		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
+-
+-		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
+-		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
+-		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
+-
+-		if (PHY_IPA(pi)) {
+-
+-			if (((pi->pubpi.radiorev == 5)
+-			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
+-			    || (pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-
+-				rccal_bcap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_BCAP_VAL);
+-				rccal_scap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_SCAP_VAL);
+-
+-				rccal_tx20_11b_bcap = rccal_bcap_val;
+-				rccal_tx20_11b_scap = rccal_scap_val;
+-
+-				if ((pi->pubpi.radiorev == 5) &&
+-				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
+-
+-					rccal_tx20_11n_bcap = rccal_bcap_val;
+-					rccal_tx20_11n_scap = rccal_scap_val;
+-					rccal_tx40_11n_bcap = 0xc;
+-					rccal_tx40_11n_scap = 0xc;
+-
+-					rccal_ovrd = true;
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					tx_lpf_bw_ofdm_20mhz = 4;
+-					tx_lpf_bw_11b = 1;
+-
+-					if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-						rccal_tx20_11n_bcap = 0xc;
+-						rccal_tx20_11n_scap = 0xc;
+-						rccal_tx40_11n_bcap = 0xa;
+-						rccal_tx40_11n_scap = 0xa;
+-					} else {
+-						rccal_tx20_11n_bcap = 0x14;
+-						rccal_tx20_11n_scap = 0x14;
+-						rccal_tx40_11n_bcap = 0xf;
+-						rccal_tx40_11n_scap = 0xf;
+-					}
+-
+-					rccal_ovrd = true;
+-				}
+-			}
+-
+-		} else {
+-
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				tx_lpf_bw_ofdm_20mhz = 1;
+-				tx_lpf_bw_ofdm_40mhz = 3;
+-
+-				rccal_bcap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_BCAP_VAL);
+-				rccal_scap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_SCAP_VAL);
+-
+-				rccal_tx20_11b_bcap = rccal_bcap_val;
+-				rccal_tx20_11b_scap = rccal_scap_val;
+-
+-				rccal_tx20_11n_bcap = 0x13;
+-				rccal_tx20_11n_scap = 0x11;
+-				rccal_tx40_11n_bcap = 0x13;
+-				rccal_tx40_11n_scap = 0x11;
+-
+-				rccal_ovrd = true;
+-			}
+-		}
+-
+-		if (rccal_ovrd) {
+-
+-			rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) |
+-			    (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
+-			rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) |
+-			    (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
+-			rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) |
+-			    (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
+-
+-			for (coreNum = 0; coreNum <= 1; coreNum++) {
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x152 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11b);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x153 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x154 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x155 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x156 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x157 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x158 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x159 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-			}
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		}
+-
+-		if (!NORADIO_ENAB(pi->pubpi)) {
+-			write_phy_reg(pi, 0x32f, 0x3);
+-		}
+-
+-		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		}
+-
+-		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
+-		    (pi->pubpi.radiorev == 6)) {
+-			if ((pi->sh->sromrev >= 8)
+-			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
+-				ipalvlshift_3p3_war_en = 1;
+-
+-			if (ipalvlshift_3p3_war_en) {
+-				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
+-						0x5);
+-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
+-						0x30);
+-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
+-				or_radio_reg(pi,
+-					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
+-					     0x1);
+-				or_radio_reg(pi,
+-					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
+-					     0x1);
+-
+-				ipa2g_mainbias = 0x1f;
+-
+-				ipa2g_casconv = 0x6f;
+-
+-				ipa2g_biasfilt = 0xaa;
+-			} else {
+-
+-				ipa2g_mainbias = 0x2b;
+-
+-				ipa2g_casconv = 0x7f;
+-
+-				ipa2g_biasfilt = 0xee;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum, IPA2G_IMAIN,
+-							 ipa2g_mainbias);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum, IPA2G_CASCONV,
+-							 ipa2g_casconv);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 IPA2G_BIAS_FILTER,
+-							 ipa2g_biasfilt);
+-				}
+-			}
+-		}
+-
+-		if (PHY_IPA(pi)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if ((pi->pubpi.radiorev == 3)
+-				    || (pi->pubpi.radiorev == 4)
+-				    || (pi->pubpi.radiorev == 6)) {
+-
+-					txgm_idac_bleed = 0x7f;
+-				}
+-
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					if (txgm_idac_bleed != 0)
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 TXGM_IDAC_BLEED,
+-								 txgm_idac_bleed);
+-				}
+-
+-				if (pi->pubpi.radiorev == 5) {
+-
+-					for (coreNum = 0; coreNum <= 1;
+-					     coreNum++) {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_CASCONV,
+-								 0x13);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_IMAIN,
+-								 0x1f);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_BIAS_FILTER,
+-								 0xee);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 PAD2G_IDACS,
+-								 0x8a);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 PAD_BIAS_FILTER_BWS,
+-								 0x3e);
+-					}
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					if (CHSPEC_IS40(pi->radio_chanspec) ==
+-					    0) {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 0,
+-								 IPA2G_IMAIN,
+-								 0x14);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 1,
+-								 IPA2G_IMAIN,
+-								 0x12);
+-					} else {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 0,
+-								 IPA2G_IMAIN,
+-								 0x16);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 1,
+-								 IPA2G_IMAIN,
+-								 0x16);
+-					}
+-				}
+-
+-			} else {
+-				freq =
+-				    CHAN5G_FREQ(CHSPEC_CHANNEL
+-						(pi->radio_chanspec));
+-				if (((freq >= 5180) && (freq <= 5230))
+-				    || ((freq >= 5745) && (freq <= 5805))) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 0, IPA5G_BIAS_FILTER,
+-							 0xff);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 1, IPA5G_BIAS_FILTER,
+-							 0xff);
+-				}
+-			}
+-		} else {
+-
+-			if (pi->pubpi.radiorev != 5) {
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 TXMIX2G_TUNE_BOOST_PU,
+-							 0x61);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 TXGM_IDAC_BLEED, 0x70);
+-				}
+-			}
+-		}
+-
+-		if (pi->pubpi.radiorev == 4) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x05, 16,
+-						 &afectrl_adc_ctrl1_rev7);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x15, 16,
+-						 &afectrl_adc_ctrl1_rev7);
+-
+-			for (coreNum = 0; coreNum <= 1; coreNum++) {
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_VCM_CAL_MASTER, 0x0);
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_SET_VCM_I, 0x3f);
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_SET_VCM_Q, 0x3f);
+-			}
+-		} else {
+-			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+-
+-			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
+-			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x05, 16,
+-						 &afectrl_adc_ctrl2_rev7);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x15, 16,
+-						 &afectrl_adc_ctrl2_rev7);
+-
+-			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
+-		}
+-
+-		write_phy_reg(pi, 0x6a, 0x2);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
+-					 &min_nvar_offset_6mbps);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
+-					 &rfseq_pktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
+-					 &rfseq_pktgn_lpf_h_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
+-					 &rfseq_htpktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
+-					 &rfseq_cckpktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
+-					 &rfseq_tx2rx_lpf_h_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
+-					 &rfseq_rx2tx_lpf_h_hpc_rev7);
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		} else {
+-			min_nvar_val = noise_var_tbl_rev7[3];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-
+-			min_nvar_val = noise_var_tbl_rev7[127];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		}
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		pdetrange =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    pdetrange : pi->srom_fem2g.pdetrange;
+-
+-		if (pdetrange == 0) {
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x70;
+-				aux_adc_vmid_rev7_core1[3] = 0x70;
+-				aux_adc_gain_rev7[3] = 2;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x80;
+-				aux_adc_vmid_rev7_core1[3] = 0x80;
+-				aux_adc_gain_rev7[3] = 3;
+-			}
+-		} else if (pdetrange == 1) {
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x7c;
+-				aux_adc_vmid_rev7_core1[3] = 0x7c;
+-				aux_adc_gain_rev7[3] = 2;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x8c;
+-				aux_adc_vmid_rev7_core1[3] = 0x8c;
+-				aux_adc_gain_rev7[3] = 1;
+-			}
+-		} else if (pdetrange == 2) {
+-			if (pi->pubpi.radioid == BCM2057_ID) {
+-				if ((pi->pubpi.radiorev == 5)
+-				    || (pi->pubpi.radiorev == 7)
+-				    || (pi->pubpi.radiorev == 8)) {
+-					if (chan_freq_range ==
+-					    WL_CHAN_FREQ_RANGE_2G) {
+-						aux_adc_vmid_rev7_core0[3] =
+-						    0x8c;
+-						aux_adc_vmid_rev7_core1[3] =
+-						    0x8c;
+-						aux_adc_gain_rev7[3] = 0;
+-					} else {
+-						aux_adc_vmid_rev7_core0[3] =
+-						    0x96;
+-						aux_adc_vmid_rev7_core1[3] =
+-						    0x96;
+-						aux_adc_gain_rev7[3] = 0;
+-					}
+-				}
+-			}
+-
+-		} else if (pdetrange == 3) {
+-			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x89;
+-				aux_adc_vmid_rev7_core1[3] = 0x89;
+-				aux_adc_gain_rev7[3] = 0;
+-			}
+-
+-		} else if (pdetrange == 5) {
+-
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x80;
+-				aux_adc_vmid_rev7_core1[3] = 0x80;
+-				aux_adc_gain_rev7[3] = 3;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x70;
+-				aux_adc_vmid_rev7_core1[3] = 0x70;
+-				aux_adc_gain_rev7[3] = 2;
+-			}
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
+-					 &aux_adc_vmid_rev7_core0);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
+-					 &aux_adc_vmid_rev7_core1);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
+-					 &aux_adc_gain_rev7);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
+-					 &aux_adc_gain_rev7);
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		write_phy_reg(pi, 0x23f, 0x1f8);
+-		write_phy_reg(pi, 0x240, 0x1f8);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					1, 0, 32, &leg_data_weights);
+-		leg_data_weights = leg_data_weights & 0xffffff;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 0, 32, &leg_data_weights);
+-
+-		alpha0 = 293;
+-		alpha1 = 435;
+-		alpha2 = 261;
+-		beta0 = 366;
+-		beta1 = 205;
+-		beta2 = 32;
+-		write_phy_reg(pi, 0x145, alpha0);
+-		write_phy_reg(pi, 0x146, alpha1);
+-		write_phy_reg(pi, 0x147, alpha2);
+-		write_phy_reg(pi, 0x148, beta0);
+-		write_phy_reg(pi, 0x149, beta1);
+-		write_phy_reg(pi, 0x14a, beta2);
+-
+-		write_phy_reg(pi, 0x38, 0xC);
+-		write_phy_reg(pi, 0x2ae, 0xC);
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
+-				       rfseq_tx2rx_events_rev3,
+-				       rfseq_tx2rx_dlys_rev3,
+-				       sizeof(rfseq_tx2rx_events_rev3) /
+-				       sizeof(rfseq_tx2rx_events_rev3[0]));
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3_ipa,
+-					       rfseq_rx2tx_dlys_rev3_ipa,
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa) /
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa
+-						[0]));
+-		}
+-
+-		if ((pi->sh->hw_phyrxchain != 0x3) &&
+-		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
+-
+-			if (PHY_IPA(pi)) {
+-				rfseq_rx2tx_dlys_rev3[5] = 59;
+-				rfseq_rx2tx_dlys_rev3[6] = 1;
+-				rfseq_rx2tx_events_rev3[7] =
+-				    NPHY_REV3_RFSEQ_CMD_END;
+-			}
+-
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3,
+-					       rfseq_rx2tx_dlys_rev3,
+-					       sizeof(rfseq_rx2tx_events_rev3) /
+-					       sizeof(rfseq_rx2tx_events_rev3
+-						      [0]));
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x6a, 0x2);
+-		} else {
+-			write_phy_reg(pi, 0x6a, 0x9c40);
+-		}
+-
+-		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		} else {
+-			min_nvar_val = noise_var_tbl_rev3[3];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-
+-			min_nvar_val = noise_var_tbl_rev3[127];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		}
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+-					 &dac_control);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+-					 &dac_control);
+-
+-		pdetrange =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    pdetrange : pi->srom_fem2g.pdetrange;
+-
+-		if (pdetrange == 0) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-				aux_adc_vmid = aux_adc_vmid_rev4;
+-				aux_adc_gain = aux_adc_gain_rev4;
+-			} else {
+-				aux_adc_vmid = aux_adc_vmid_rev3;
+-				aux_adc_gain = aux_adc_gain_rev3;
+-			}
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				switch (chan_freq_range) {
+-				case WL_CHAN_FREQ_RANGE_5GL:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				case WL_CHAN_FREQ_RANGE_5GM:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				case WL_CHAN_FREQ_RANGE_5GH:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				default:
+-					break;
+-				}
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, aux_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, aux_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, aux_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, aux_adc_gain);
+-		} else if (pdetrange == 1) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, sk_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, sk_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, sk_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, sk_adc_gain);
+-		} else if (pdetrange == 2) {
+-
+-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
+-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				chan_freq_range =
+-				    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-					bcm_adc_vmid[3] = 0x8e;
+-					bcm_adc_gain[3] = 0x03;
+-				} else {
+-					bcm_adc_vmid[3] = 0x94;
+-					bcm_adc_gain[3] = 0x03;
+-				}
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				bcm_adc_vmid[3] = 0x84;
+-				bcm_adc_gain[3] = 0x02;
+-			}
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, bcm_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, bcm_adc_gain);
+-		} else if (pdetrange == 3) {
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if ((NREV_GE(pi->pubpi.phy_rev, 4))
+-			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
+-
+-				u16 auxadc_vmid[] = {
+-					0xa2, 0xb4, 0xb4, 0x270 };
+-				u16 auxadc_gain[] = {
+-					0x02, 0x02, 0x02, 0x00 };
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x08, 16, auxadc_vmid);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x18, 16, auxadc_vmid);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x0c, 16, auxadc_gain);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x1c, 16, auxadc_gain);
+-			}
+-		} else if ((pdetrange == 4) || (pdetrange == 5)) {
+-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
+-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
+-			u16 Vmid[2], Av[2];
+-
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
+-				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
+-				Av[0] = (pdetrange == 4) ? 2 : 0;
+-				Av[1] = (pdetrange == 4) ? 2 : 0;
+-			} else {
+-				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
+-				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
+-				Av[0] = (pdetrange == 4) ? 2 : 0;
+-				Av[1] = (pdetrange == 4) ? 2 : 0;
+-			}
+-
+-			bcm_adc_vmid[3] = Vmid[0];
+-			bcm_adc_gain[3] = Av[0];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, bcm_adc_gain);
+-
+-			bcm_adc_vmid[3] = Vmid[1];
+-			bcm_adc_gain[3] = Av[1];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, bcm_adc_gain);
+-		}
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
+-				0x6);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
+-				0x6);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
+-				0x7);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
+-				0x7);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
+-				0x88);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
+-				0x88);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
+-				0x0);
+-
+-		triso =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    triso : pi->srom_fem2g.triso;
+-		if (triso == 7) {
+-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+-		}
+-
+-		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
+-
+-		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
+-		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
+-		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
+-		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
+-		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-			nss1_data_weights = 0x00088888;
+-			ht_data_weights = 0x00088888;
+-			stbc_data_weights = 0x00088888;
+-		} else {
+-			nss1_data_weights = 0x88888888;
+-			ht_data_weights = 0x88888888;
+-			stbc_data_weights = 0x88888888;
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 1, 32, &nss1_data_weights);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 2, 32, &ht_data_weights);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 3, 32, &stbc_data_weights);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_GMBB_IDAC |
+-						RADIO_2056_TX0, 0x70);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_GMBB_IDAC |
+-						RADIO_2056_TX1, 0x70);
+-			}
+-		}
+-
+-		if (!pi->edcrs_threshold_lock) {
+-			write_phy_reg(pi, 0x224, 0x3eb);
+-			write_phy_reg(pi, 0x225, 0x3eb);
+-			write_phy_reg(pi, 0x226, 0x341);
+-			write_phy_reg(pi, 0x227, 0x341);
+-			write_phy_reg(pi, 0x228, 0x42b);
+-			write_phy_reg(pi, 0x229, 0x42b);
+-			write_phy_reg(pi, 0x22a, 0x381);
+-			write_phy_reg(pi, 0x22b, 0x381);
+-			write_phy_reg(pi, 0x22c, 0x42b);
+-			write_phy_reg(pi, 0x22d, 0x42b);
+-			write_phy_reg(pi, 0x22e, 0x381);
+-			write_phy_reg(pi, 0x22f, 0x381);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-
+-			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) {
+-				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
+-					       MHF4_BPHY_TXCORE0,
+-					       MHF4_BPHY_TXCORE0, WLC_BAND_ALL);
+-			}
+-		}
+-	} else {
+-
+-		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
+-		    (pi->sh->boardtype == 0x8b)) {
+-			uint i;
+-			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
+-			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
+-				rfseq_rx2tx_dlys[i] = war_dlys[i];
+-		}
+-
+-		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
+-			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
+-			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
+-		} else {
+-			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
+-			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
+-		}
+-
+-		regval = 0x000a;
+-		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
+-		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-			regval = 0xcdaa;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-			regval = 0x0000;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
+-
+-			regval = 0x7aab;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
+-
+-			regval = 0x0800;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
+-		}
+-
+-		write_phy_reg(pi, 0xf8, 0x02d8);
+-		write_phy_reg(pi, 0xf9, 0x0301);
+-		write_phy_reg(pi, 0xfa, 0x02d8);
+-		write_phy_reg(pi, 0xfb, 0x0301);
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
+-				       rfseq_rx2tx_dlys,
+-				       sizeof(rfseq_rx2tx_events) /
+-				       sizeof(rfseq_rx2tx_events[0]));
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
+-				       rfseq_tx2rx_dlys,
+-				       sizeof(rfseq_tx2rx_events) /
+-				       sizeof(rfseq_tx2rx_events[0]));
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
+-				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
+-					       MHF3_NPHY_MLADV_WAR,
+-					       MHF3_NPHY_MLADV_WAR,
+-					       WLC_BAND_ALL);
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			write_phy_reg(pi, 0x1e3, 0x0);
+-			write_phy_reg(pi, 0x1e4, 0x0);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
+-
+-		alpha0 = 293;
+-		alpha1 = 435;
+-		alpha2 = 261;
+-		beta0 = 366;
+-		beta1 = 205;
+-		beta2 = 32;
+-		write_phy_reg(pi, 0x145, alpha0);
+-		write_phy_reg(pi, 0x146, alpha1);
+-		write_phy_reg(pi, 0x147, alpha2);
+-		write_phy_reg(pi, 0x148, beta0);
+-		write_phy_reg(pi, 0x149, beta1);
+-		write_phy_reg(pi, 0x14a, beta2);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
+-
+-			write_phy_reg(pi, 0x192, 0xb5);
+-			write_phy_reg(pi, 0x193, 0xa4);
+-			write_phy_reg(pi, 0x194, 0x0);
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_phy_reg(pi, 0x221,
+-				    NPHY_FORCESIG_DECODEGATEDCLKS,
+-				    NPHY_FORCESIG_DECODEGATEDCLKS);
+-		}
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi)
+-{
+-	u16 w1th, hpf_code, currband;
+-	int ctr;
+-	u8 rfseq_updategainu_events[] = {
+-		NPHY_RFSEQ_CMD_RX_GAIN,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_RFSEQ_CMD_SET_HPF_BW
+-	};
+-	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
+-	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
+-	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
+-	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
+-	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
+-	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
+-	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
+-	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
+-	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
+-	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
+-	s8 *lna1_gain_db = NULL;
+-	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
+-	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
+-	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
+-	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
+-	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
+-	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
+-	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
+-	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
+-	s8 *lna2_gain_db = NULL;
+-	s8 tiaG_gain_db[] = {
+-		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
+-	s8 tiaA_gain_db[] = {
+-		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
+-	s8 tiaA_gain_db_rev4[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 tiaA_gain_db_rev5[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 tiaA_gain_db_rev6[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 *tia_gain_db;
+-	s8 tiaG_gainbits[] = {
+-		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+-	s8 tiaA_gainbits[] = {
+-		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
+-	s8 tiaA_gainbits_rev4[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 tiaA_gainbits_rev5[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 tiaA_gainbits_rev6[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 *tia_gainbits;
+-	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
+-	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
+-	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
+-	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
+-	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
+-	u16 rfseqG_init_gain_rev5_elna[] = {
+-		0x013f, 0x013f, 0x013f, 0x013f };
+-	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
+-	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
+-	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
+-	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
+-	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
+-	u16 rfseqA_init_gain_rev4_elna[] = {
+-		0x314f, 0x314f, 0x314f, 0x314f };
+-	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
+-	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
+-	u16 *rfseq_init_gain;
+-	u16 initG_gaincode = 0x627e;
+-	u16 initG_gaincode_rev4 = 0x527e;
+-	u16 initG_gaincode_rev5 = 0x427e;
+-	u16 initG_gaincode_rev5_elna = 0x027e;
+-	u16 initG_gaincode_rev6 = 0x527e;
+-	u16 initG_gaincode_rev6_224B0 = 0x427e;
+-	u16 initG_gaincode_rev6_elna = 0x127e;
+-	u16 initA_gaincode = 0x52de;
+-	u16 initA_gaincode_rev4 = 0x629e;
+-	u16 initA_gaincode_rev4_elna = 0x329e;
+-	u16 initA_gaincode_rev5 = 0x729e;
+-	u16 initA_gaincode_rev6 = 0x729e;
+-	u16 init_gaincode;
+-	u16 clip1hiG_gaincode = 0x107e;
+-	u16 clip1hiG_gaincode_rev4 = 0x007e;
+-	u16 clip1hiG_gaincode_rev5 = 0x1076;
+-	u16 clip1hiG_gaincode_rev6 = 0x007e;
+-	u16 clip1hiA_gaincode = 0x00de;
+-	u16 clip1hiA_gaincode_rev4 = 0x029e;
+-	u16 clip1hiA_gaincode_rev5 = 0x029e;
+-	u16 clip1hiA_gaincode_rev6 = 0x029e;
+-	u16 clip1hi_gaincode;
+-	u16 clip1mdG_gaincode = 0x0066;
+-	u16 clip1mdA_gaincode = 0x00ca;
+-	u16 clip1mdA_gaincode_rev4 = 0x1084;
+-	u16 clip1mdA_gaincode_rev5 = 0x2084;
+-	u16 clip1mdA_gaincode_rev6 = 0x2084;
+-	u16 clip1md_gaincode = 0;
+-	u16 clip1loG_gaincode = 0x0074;
+-	u16 clip1loG_gaincode_rev5[] = {
+-		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
+-	};
+-	u16 clip1loG_gaincode_rev6[] = {
+-		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
+-	};
+-	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
+-	u16 clip1loA_gaincode = 0x00cc;
+-	u16 clip1loA_gaincode_rev4 = 0x0086;
+-	u16 clip1loA_gaincode_rev5 = 0x2086;
+-	u16 clip1loA_gaincode_rev6 = 0x2086;
+-	u16 clip1lo_gaincode;
+-	u8 crsminG_th = 0x18;
+-	u8 crsminG_th_rev5 = 0x18;
+-	u8 crsminG_th_rev6 = 0x18;
+-	u8 crsminA_th = 0x1e;
+-	u8 crsminA_th_rev4 = 0x24;
+-	u8 crsminA_th_rev5 = 0x24;
+-	u8 crsminA_th_rev6 = 0x24;
+-	u8 crsmin_th;
+-	u8 crsminlG_th = 0x18;
+-	u8 crsminlG_th_rev5 = 0x18;
+-	u8 crsminlG_th_rev6 = 0x18;
+-	u8 crsminlA_th = 0x1e;
+-	u8 crsminlA_th_rev4 = 0x24;
+-	u8 crsminlA_th_rev5 = 0x24;
+-	u8 crsminlA_th_rev6 = 0x24;
+-	u8 crsminl_th = 0;
+-	u8 crsminuG_th = 0x18;
+-	u8 crsminuG_th_rev5 = 0x18;
+-	u8 crsminuG_th_rev6 = 0x18;
+-	u8 crsminuA_th = 0x1e;
+-	u8 crsminuA_th_rev4 = 0x24;
+-	u8 crsminuA_th_rev5 = 0x24;
+-	u8 crsminuA_th_rev6 = 0x24;
+-	u8 crsminuA_th_rev6_224B0 = 0x2d;
+-	u8 crsminu_th;
+-	u16 nbclipG_th = 0x20d;
+-	u16 nbclipG_th_rev4 = 0x1a1;
+-	u16 nbclipG_th_rev5 = 0x1d0;
+-	u16 nbclipG_th_rev6 = 0x1d0;
+-	u16 nbclipA_th = 0x1a1;
+-	u16 nbclipA_th_rev4 = 0x107;
+-	u16 nbclipA_th_rev5 = 0x0a9;
+-	u16 nbclipA_th_rev6 = 0x0f0;
+-	u16 nbclip_th = 0;
+-	u8 w1clipG_th = 5;
+-	u8 w1clipG_th_rev5 = 9;
+-	u8 w1clipG_th_rev6 = 5;
+-	u8 w1clipA_th = 25, w1clip_th;
+-	u8 rssi_gain_default = 0x50;
+-	u8 rssiG_gain_rev6_224B0 = 0x50;
+-	u8 rssiA_gain_rev5 = 0x90;
+-	u8 rssiA_gain_rev6 = 0x90;
+-	u8 rssi_gain;
+-	u16 regval[21];
+-	u8 triso;
+-
+-	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
+-	    pi->srom_fem2g.triso;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
+-		} else if (pi->pubpi.radiorev == 7) {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-
+-			mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
+-
+-		} else if ((pi->pubpi.radiorev == 3)
+-			   || (pi->pubpi.radiorev == 8)) {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-
+-			if (pi->pubpi.radiorev == 8) {
+-				mod_phy_reg(pi, 0x283,
+-					    (0xff << 0), (0x44 << 0));
+-				mod_phy_reg(pi, 0x280,
+-					    (0xff << 0), (0x44 << 0));
+-			}
+-		} else {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
+-
+-		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-		currband =
+-		    read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-		if (currband == 0) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				if (pi->pubpi.radiorev == 11) {
+-					lna1_gain_db = lna1G_gain_db_rev6_224B0;
+-					lna2_gain_db = lna2G_gain_db_rev6_224B0;
+-					rfseq_init_gain =
+-					    rfseqG_init_gain_rev6_224B0;
+-					init_gaincode =
+-					    initG_gaincode_rev6_224B0;
+-					clip1hi_gaincode =
+-					    clip1hiG_gaincode_rev6;
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev6_224B0;
+-					nbclip_th = nbclipG_th_rev6;
+-					w1clip_th = w1clipG_th_rev6;
+-					crsmin_th = crsminG_th_rev6;
+-					crsminl_th = crsminlG_th_rev6;
+-					crsminu_th = crsminuG_th_rev6;
+-					rssi_gain = rssiG_gain_rev6_224B0;
+-				} else {
+-					lna1_gain_db = lna1G_gain_db_rev6;
+-					lna2_gain_db = lna2G_gain_db_rev6;
+-					if (pi->sh->boardflags & BFL_EXTLNA) {
+-
+-						rfseq_init_gain =
+-						    rfseqG_init_gain_rev6_elna;
+-						init_gaincode =
+-						    initG_gaincode_rev6_elna;
+-					} else {
+-						rfseq_init_gain =
+-						    rfseqG_init_gain_rev6;
+-						init_gaincode =
+-						    initG_gaincode_rev6;
+-					}
+-					clip1hi_gaincode =
+-					    clip1hiG_gaincode_rev6;
+-					switch (triso) {
+-					case 0:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[0];
+-						break;
+-					case 1:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[1];
+-						break;
+-					case 2:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[2];
+-						break;
+-					case 3:
+-					default:
+-
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[3];
+-						break;
+-					case 4:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[4];
+-						break;
+-					case 5:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[5];
+-						break;
+-					case 6:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[6];
+-						break;
+-					case 7:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[7];
+-						break;
+-					}
+-					nbclip_th = nbclipG_th_rev6;
+-					w1clip_th = w1clipG_th_rev6;
+-					crsmin_th = crsminG_th_rev6;
+-					crsminl_th = crsminlG_th_rev6;
+-					crsminu_th = crsminuG_th_rev6;
+-					rssi_gain = rssi_gain_default;
+-				}
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				lna1_gain_db = lna1G_gain_db_rev5;
+-				lna2_gain_db = lna2G_gain_db_rev5;
+-				if (pi->sh->boardflags & BFL_EXTLNA) {
+-
+-					rfseq_init_gain =
+-					    rfseqG_init_gain_rev5_elna;
+-					init_gaincode =
+-					    initG_gaincode_rev5_elna;
+-				} else {
+-					rfseq_init_gain = rfseqG_init_gain_rev5;
+-					init_gaincode = initG_gaincode_rev5;
+-				}
+-				clip1hi_gaincode = clip1hiG_gaincode_rev5;
+-				switch (triso) {
+-				case 0:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[0];
+-					break;
+-				case 1:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[1];
+-					break;
+-				case 2:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[2];
+-					break;
+-				case 3:
+-
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[3];
+-					break;
+-				case 4:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[4];
+-					break;
+-				case 5:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[5];
+-					break;
+-				case 6:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[6];
+-					break;
+-				case 7:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[7];
+-					break;
+-				default:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[3];
+-					break;
+-				}
+-				nbclip_th = nbclipG_th_rev5;
+-				w1clip_th = w1clipG_th_rev5;
+-				crsmin_th = crsminG_th_rev5;
+-				crsminl_th = crsminlG_th_rev5;
+-				crsminu_th = crsminuG_th_rev5;
+-				rssi_gain = rssi_gain_default;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-				lna1_gain_db = lna1G_gain_db_rev4;
+-				lna2_gain_db = lna2G_gain_db;
+-				rfseq_init_gain = rfseqG_init_gain_rev4;
+-				init_gaincode = initG_gaincode_rev4;
+-				clip1hi_gaincode = clip1hiG_gaincode_rev4;
+-				clip1lo_gaincode = clip1loG_gaincode;
+-				nbclip_th = nbclipG_th_rev4;
+-				w1clip_th = w1clipG_th;
+-				crsmin_th = crsminG_th;
+-				crsminl_th = crsminlG_th;
+-				crsminu_th = crsminuG_th;
+-				rssi_gain = rssi_gain_default;
+-			} else {
+-				lna1_gain_db = lna1G_gain_db;
+-				lna2_gain_db = lna2G_gain_db;
+-				rfseq_init_gain = rfseqG_init_gain;
+-				init_gaincode = initG_gaincode;
+-				clip1hi_gaincode = clip1hiG_gaincode;
+-				clip1lo_gaincode = clip1loG_gaincode;
+-				nbclip_th = nbclipG_th;
+-				w1clip_th = w1clipG_th;
+-				crsmin_th = crsminG_th;
+-				crsminl_th = crsminlG_th;
+-				crsminu_th = crsminuG_th;
+-				rssi_gain = rssi_gain_default;
+-			}
+-			tia_gain_db = tiaG_gain_db;
+-			tia_gainbits = tiaG_gainbits;
+-			clip1md_gaincode = clip1mdG_gaincode;
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				lna1_gain_db = lna1A_gain_db_rev6;
+-				lna2_gain_db = lna2A_gain_db_rev6;
+-				tia_gain_db = tiaA_gain_db_rev6;
+-				tia_gainbits = tiaA_gainbits_rev6;
+-				rfseq_init_gain = rfseqA_init_gain_rev6;
+-				init_gaincode = initA_gaincode_rev6;
+-				clip1hi_gaincode = clip1hiA_gaincode_rev6;
+-				clip1md_gaincode = clip1mdA_gaincode_rev6;
+-				clip1lo_gaincode = clip1loA_gaincode_rev6;
+-				crsmin_th = crsminA_th_rev6;
+-				crsminl_th = crsminlA_th_rev6;
+-				if ((pi->pubpi.radiorev == 11) &&
+-				    (CHSPEC_IS40(pi->radio_chanspec) == 0)) {
+-					crsminu_th = crsminuA_th_rev6_224B0;
+-				} else {
+-					crsminu_th = crsminuA_th_rev6;
+-				}
+-				nbclip_th = nbclipA_th_rev6;
+-				rssi_gain = rssiA_gain_rev6;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				lna1_gain_db = lna1A_gain_db_rev5;
+-				lna2_gain_db = lna2A_gain_db_rev5;
+-				tia_gain_db = tiaA_gain_db_rev5;
+-				tia_gainbits = tiaA_gainbits_rev5;
+-				rfseq_init_gain = rfseqA_init_gain_rev5;
+-				init_gaincode = initA_gaincode_rev5;
+-				clip1hi_gaincode = clip1hiA_gaincode_rev5;
+-				clip1md_gaincode = clip1mdA_gaincode_rev5;
+-				clip1lo_gaincode = clip1loA_gaincode_rev5;
+-				crsmin_th = crsminA_th_rev5;
+-				crsminl_th = crsminlA_th_rev5;
+-				crsminu_th = crsminuA_th_rev5;
+-				nbclip_th = nbclipA_th_rev5;
+-				rssi_gain = rssiA_gain_rev5;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-				lna1_gain_db = lna1A_gain_db_rev4;
+-				lna2_gain_db = lna2A_gain_db_rev4;
+-				tia_gain_db = tiaA_gain_db_rev4;
+-				tia_gainbits = tiaA_gainbits_rev4;
+-				if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
+-
+-					rfseq_init_gain =
+-					    rfseqA_init_gain_rev4_elna;
+-					init_gaincode =
+-					    initA_gaincode_rev4_elna;
+-				} else {
+-					rfseq_init_gain = rfseqA_init_gain_rev4;
+-					init_gaincode = initA_gaincode_rev4;
+-				}
+-				clip1hi_gaincode = clip1hiA_gaincode_rev4;
+-				clip1md_gaincode = clip1mdA_gaincode_rev4;
+-				clip1lo_gaincode = clip1loA_gaincode_rev4;
+-				crsmin_th = crsminA_th_rev4;
+-				crsminl_th = crsminlA_th_rev4;
+-				crsminu_th = crsminuA_th_rev4;
+-				nbclip_th = nbclipA_th_rev4;
+-				rssi_gain = rssi_gain_default;
+-			} else {
+-				lna1_gain_db = lna1A_gain_db;
+-				lna2_gain_db = lna2A_gain_db;
+-				tia_gain_db = tiaA_gain_db;
+-				tia_gainbits = tiaA_gainbits;
+-				rfseq_init_gain = rfseqA_init_gain;
+-				init_gaincode = initA_gaincode;
+-				clip1hi_gaincode = clip1hiA_gaincode;
+-				clip1md_gaincode = clip1mdA_gaincode;
+-				clip1lo_gaincode = clip1loA_gaincode;
+-				crsmin_th = crsminA_th;
+-				crsminl_th = crsminlA_th;
+-				crsminu_th = crsminuA_th;
+-				nbclip_th = nbclipA_th;
+-				rssi_gain = rssi_gain_default;
+-			}
+-			w1clip_th = w1clipA_th;
+-		}
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+-				 RADIO_2056_RX0), 0x17);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+-				 RADIO_2056_RX1), 0x17);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
+-				0xf0);
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
+-				0xf0);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
+-				rssi_gain);
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
+-				rssi_gain);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+-				 RADIO_2056_RX0), 0x17);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+-				 RADIO_2056_RX1), 0x17);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
+-				0xFF);
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
+-				0xFF);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
+-					 8, lna1_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
+-					 8, lna1_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+-					 8, lna2_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+-					 8, lna2_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
+-					 8, tia_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
+-					 8, tia_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
+-					 8, tia_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
+-					 8, tia_gainbits);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
+-					 8, &lpf_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
+-					 8, &lpf_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
+-					 8, &lpf_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
+-					 8, &lpf_gainbits);
+-
+-		write_phy_reg(pi, 0x20, init_gaincode);
+-		write_phy_reg(pi, 0x2a7, init_gaincode);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 pi->pubpi.phy_corenum, 0x106, 16,
+-					 rfseq_init_gain);
+-
+-		write_phy_reg(pi, 0x22, clip1hi_gaincode);
+-		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+-
+-		write_phy_reg(pi, 0x24, clip1md_gaincode);
+-		write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+-
+-		write_phy_reg(pi, 0x37, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+-
+-		mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
+-		mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+-
+-		write_phy_reg(pi, 0x2b, nbclip_th);
+-		write_phy_reg(pi, 0x41, nbclip_th);
+-
+-		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
+-		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
+-
+-		write_phy_reg(pi, 0x150, 0x809c);
+-
+-	} else {
+-
+-		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-		write_phy_reg(pi, 0x2b, 0x84);
+-		write_phy_reg(pi, 0x41, 0x84);
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x6b, 0x2b);
+-			write_phy_reg(pi, 0x6c, 0x2b);
+-			write_phy_reg(pi, 0x6d, 0x9);
+-			write_phy_reg(pi, 0x6e, 0x9);
+-		}
+-
+-		w1th = NPHY_RSSICAL_W1_TARGET - 4;
+-		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
+-		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
+-
+-			mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
+-		}
+-
+-		write_phy_reg(pi, 0x150, 0x809c);
+-
+-		if (pi->nphy_gain_boost)
+-			if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
+-			    (CHSPEC_IS40(pi->radio_chanspec)))
+-				hpf_code = 4;
+-			else
+-				hpf_code = 5;
+-		else if (CHSPEC_IS40(pi->radio_chanspec))
+-			hpf_code = 6;
+-		else
+-			hpf_code = 7;
+-
+-		mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
+-		mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
+-
+-		for (ctr = 0; ctr < 4; ctr++) {
+-			regval[ctr] = (hpf_code << 8) | 0x7c;
+-		}
+-		wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+-
+-		wlc_phy_adjust_lnagaintbl_nphy(pi);
+-
+-		if (pi->nphy_elna_gain_config) {
+-			regval[0] = 0;
+-			regval[1] = 1;
+-			regval[2] = 1;
+-			regval[3] = 1;
+-			wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
+-
+-			for (ctr = 0; ctr < 4; ctr++) {
+-				regval[ctr] = (hpf_code << 8) | 0x74;
+-			}
+-			wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			for (ctr = 0; ctr < 21; ctr++) {
+-				regval[ctr] = 3 * ctr;
+-			}
+-			wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
+-
+-			for (ctr = 0; ctr < 21; ctr++) {
+-				regval[ctr] = (u16) ctr;
+-			}
+-			wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
+-		}
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
+-				       rfseq_updategainu_events,
+-				       rfseq_updategainu_dlys,
+-				       sizeof(rfseq_updategainu_events) /
+-				       sizeof(rfseq_updategainu_events[0]));
+-
+-		mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec))
+-			mod_phy_reg(pi,
+-				    (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
+-				    0x7f, 0x4);
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi)
+-{
+-	s8 lna1_gain_db[] = { 8, 13, 17, 22 };
+-	s8 lna2_gain_db[] = { -2, 7, 11, 15 };
+-	s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
+-	s8 tia_gainbits[] = {
+-		0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+-
+-	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-	mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+-
+-	mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
+-	mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
+-				 lna1_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
+-				 lna1_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
+-				 lna2_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
+-				 lna2_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+-				 tia_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+-				 tia_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+-				 tia_gainbits);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+-				 tia_gainbits);
+-
+-	write_phy_reg(pi, 0x37, 0x74);
+-	write_phy_reg(pi, 0x2ad, 0x74);
+-	write_phy_reg(pi, 0x38, 0x18);
+-	write_phy_reg(pi, 0x2ae, 0x18);
+-
+-	write_phy_reg(pi, 0x2b, 0xe8);
+-	write_phy_reg(pi, 0x41, 0xe8);
+-
+-	if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
+-	} else {
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi)
+-{
+-	u16 currband;
+-	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
+-	s8 *lna1_gain_db = NULL;
+-	s8 *lna1_gain_db_2 = NULL;
+-	s8 *lna2_gain_db = NULL;
+-	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
+-	s8 *tia_gain_db;
+-	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
+-	s8 *tia_gainbits;
+-	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
+-	u16 *rfseq_init_gain;
+-	u16 init_gaincode;
+-	u16 clip1hi_gaincode;
+-	u16 clip1md_gaincode = 0;
+-	u16 clip1md_gaincode_B;
+-	u16 clip1lo_gaincode;
+-	u16 clip1lo_gaincode_B;
+-	u8 crsminl_th = 0;
+-	u8 crsminu_th;
+-	u16 nbclip_th = 0;
+-	u8 w1clip_th;
+-	u16 freq;
+-	s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
+-	u8 chg_nbclip_th = 0;
+-
+-	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-	currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-	if (currband == 0) {
+-
+-		lna1_gain_db = lna1G_gain_db_rev7;
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+-					 lna1_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+-					 lna1_gain_db);
+-
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
+-			mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
+-		}
+-
+-		mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
+-			mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
+-		}
+-	} else {
+-
+-		init_gaincode = 0x9e;
+-		clip1hi_gaincode = 0x9e;
+-		clip1md_gaincode_B = 0x24;
+-		clip1lo_gaincode = 0x8a;
+-		clip1lo_gaincode_B = 8;
+-		rfseq_init_gain = rfseqA_init_gain_rev7;
+-
+-		tia_gain_db = tiaA_gain_db_rev7;
+-		tia_gainbits = tiaA_gainbits_rev7;
+-
+-		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-			w1clip_th = 25;
+-			clip1md_gaincode = 0x82;
+-
+-			if ((freq <= 5080) || (freq == 5825)) {
+-
+-				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					11, 17, 22, 25 };
+-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+-
+-				crsminu_th = 0x3e;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			} else if ((freq >= 5500) && (freq <= 5700)) {
+-
+-				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					12, 18, 22, 26 };
+-				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
+-
+-				crsminu_th = 0x45;
+-				clip1md_gaincode_B = 0x14;
+-				nbclip_th = 0xff;
+-				chg_nbclip_th = 1;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			} else {
+-
+-				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					12, 18, 22, 26 };
+-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+-
+-				crsminu_th = 0x41;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			}
+-
+-			if (freq <= 4920) {
+-				nvar_baseline_offset0 = 5;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 4920) && (freq <= 5320)) {
+-				nvar_baseline_offset0 = 3;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 5320) && (freq <= 5700)) {
+-				nvar_baseline_offset0 = 3;
+-				nvar_baseline_offset1 = 2;
+-			} else {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 0;
+-			}
+-		} else {
+-
+-			crsminu_th = 0x3a;
+-			crsminl_th = 0x3a;
+-			w1clip_th = 20;
+-
+-			if ((freq >= 4920) && (freq <= 5320)) {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 5320) && (freq <= 5550)) {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 2;
+-			} else {
+-				nvar_baseline_offset0 = 5;
+-				nvar_baseline_offset1 = 3;
+-			}
+-		}
+-
+-		write_phy_reg(pi, 0x20, init_gaincode);
+-		write_phy_reg(pi, 0x2a7, init_gaincode);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 pi->pubpi.phy_corenum, 0x106, 16,
+-					 rfseq_init_gain);
+-
+-		write_phy_reg(pi, 0x22, clip1hi_gaincode);
+-		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+-
+-		write_phy_reg(pi, 0x36, clip1md_gaincode_B);
+-		write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
+-
+-		write_phy_reg(pi, 0x37, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
+-		write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+-					 tia_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+-					 tia_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+-					 tia_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+-					 tia_gainbits);
+-
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+-
+-		if (chg_nbclip_th == 1) {
+-			write_phy_reg(pi, 0x2b, nbclip_th);
+-			write_phy_reg(pi, 0x41, nbclip_th);
+-		}
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
+-
+-		mod_phy_reg(pi, 0x2e4,
+-			    (0x3f << 0), (nvar_baseline_offset0 << 0));
+-
+-		mod_phy_reg(pi, 0x2e4,
+-			    (0x3f << 6), (nvar_baseline_offset1 << 6));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+-						 lna1_gain_db);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+-						 lna1_gain_db_2);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+-						 8, lna2_gain_db);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+-						 8, lna2_gain_db);
+-
+-			write_phy_reg(pi, 0x24, clip1md_gaincode);
+-			write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+-		} else {
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+-		}
+-
+-	}
+-
+-}
+-
+-static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi)
+-{
+-	uint core;
+-	int ctr;
+-	s16 gain_delta[2];
+-	u8 curr_channel;
+-	u16 minmax_gain[2];
+-	u16 regval[4];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (pi->nphy_gain_boost) {
+-		if ((CHSPEC_IS2G(pi->radio_chanspec))) {
+-
+-			gain_delta[0] = 6;
+-			gain_delta[1] = 6;
+-		} else {
+-
+-			curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-			gain_delta[0] =
+-			    (s16)
+-			    PHY_HW_ROUND(((nphy_lnagain_est0[0] *
+-					   curr_channel) +
+-					  nphy_lnagain_est0[1]), 13);
+-			gain_delta[1] =
+-			    (s16)
+-			    PHY_HW_ROUND(((nphy_lnagain_est1[0] *
+-					   curr_channel) +
+-					  nphy_lnagain_est1[1]), 13);
+-		}
+-	} else {
+-
+-		gain_delta[0] = 0;
+-		gain_delta[1] = 0;
+-	}
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (pi->nphy_elna_gain_config) {
+-
+-			regval[0] = nphy_def_lnagains[2] + gain_delta[core];
+-			regval[1] = nphy_def_lnagains[3] + gain_delta[core];
+-			regval[2] = nphy_def_lnagains[3] + gain_delta[core];
+-			regval[3] = nphy_def_lnagains[3] + gain_delta[core];
+-		} else {
+-			for (ctr = 0; ctr < 4; ctr++) {
+-				regval[ctr] =
+-				    nphy_def_lnagains[ctr] + gain_delta[core];
+-			}
+-		}
+-		wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
+-
+-		minmax_gain[core] =
+-		    (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
+-	}
+-
+-	mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
+-	mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on)
+-{
+-	if (on) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (!pi->radio_is_on) {
+-				wlc_phy_radio_preinit_205x(pi);
+-				wlc_phy_radio_init_2057(pi);
+-				wlc_phy_radio_postinit_2057(pi);
+-			}
+-
+-			wlc_phy_chanspec_set((wlc_phy_t *) pi,
+-					     pi->radio_chanspec);
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_radio_preinit_205x(pi);
+-			wlc_phy_radio_init_2056(pi);
+-			wlc_phy_radio_postinit_2056(pi);
+-
+-			wlc_phy_chanspec_set((wlc_phy_t *) pi,
+-					     pi->radio_chanspec);
+-		} else {
+-			wlc_phy_radio_preinit_2055(pi);
+-			wlc_phy_radio_init_2055(pi);
+-			wlc_phy_radio_postinit_2055(pi);
+-		}
+-
+-		pi->radio_is_on = true;
+-
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)
+-		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-			mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADA_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAA_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_TX_MIXA_BOOST_TUNE |
+-				      RADIO_2056_TX0, 0xf0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_MIXG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADA_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAA_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_TX_MIXA_BOOST_TUNE |
+-				      RADIO_2056_TX1, 0xf0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_MIXG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-
+-			pi->radio_is_on = false;
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-			pi->radio_is_on = false;
+-		}
+-
+-	}
+-}
+-
+-static void wlc_phy_radio_preinit_2055(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
+-	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
+-
+-	or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
+-}
+-
+-static void wlc_phy_radio_init_2055(phy_info_t *pi)
+-{
+-	wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
+-}
+-
+-static void wlc_phy_radio_postinit_2055(phy_info_t *pi)
+-{
+-
+-	and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
+-		      ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
+-
+-	if (((pi->sh->sromrev >= 4)
+-	     && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
+-	    || ((pi->sh->sromrev < 4))) {
+-		and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
+-		and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
+-	write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
+-
+-	and_radio_reg(pi, RADIO_2055_CAL_MISC,
+-		      ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
+-
+-	udelay(1000);
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
+-
+-	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+-		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
+-
+-	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+-		 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
+-		 "HW error: radio calibration1\n"))
+-		return;
+-
+-	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
+-		      ~(RADIO_2055_CAL_LPO_ENABLE));
+-
+-	wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
+-
+-	mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
+-		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+-	mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
+-		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+-	if (pi->nphy_gain_boost) {
+-		and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+-			      ~(RADIO_2055_GAINBST_DISABLE));
+-		and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+-			      ~(RADIO_2055_GAINBST_DISABLE));
+-	} else {
+-		or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+-			     RADIO_2055_GAINBST_DISABLE);
+-		or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+-			     RADIO_2055_GAINBST_DISABLE);
+-	}
+-
+-	udelay(2);
+-}
+-
+-static void wlc_phy_radio_preinit_205x(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-	and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
+-
+-	or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
+-	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
+-
+-}
+-
+-static void wlc_phy_radio_init_2056(phy_info_t *pi)
+-{
+-	radio_regs_t *regs_SYN_2056_ptr = NULL;
+-	radio_regs_t *regs_TX_2056_ptr = NULL;
+-	radio_regs_t *regs_RX_2056_ptr = NULL;
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-		regs_SYN_2056_ptr = regs_SYN_2056;
+-		regs_TX_2056_ptr = regs_TX_2056;
+-		regs_RX_2056_ptr = regs_RX_2056;
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-		regs_SYN_2056_ptr = regs_SYN_2056_A1;
+-		regs_TX_2056_ptr = regs_TX_2056_A1;
+-		regs_RX_2056_ptr = regs_RX_2056_A1;
+-	} else {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+-			regs_TX_2056_ptr = regs_TX_2056_rev5;
+-			regs_RX_2056_ptr = regs_RX_2056_rev5;
+-			break;
+-
+-		case 6:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+-			regs_TX_2056_ptr = regs_TX_2056_rev6;
+-			regs_RX_2056_ptr = regs_RX_2056_rev6;
+-			break;
+-
+-		case 7:
+-		case 9:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+-			regs_TX_2056_ptr = regs_TX_2056_rev7;
+-			regs_RX_2056_ptr = regs_RX_2056_rev7;
+-			break;
+-
+-		case 8:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+-			regs_TX_2056_ptr = regs_TX_2056_rev8;
+-			regs_RX_2056_ptr = regs_RX_2056_rev8;
+-			break;
+-
+-		case 11:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+-			regs_TX_2056_ptr = regs_TX_2056_rev11;
+-			regs_RX_2056_ptr = regs_RX_2056_rev11;
+-			break;
+-
+-		default:
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
+-
+-	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
+-
+-	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
+-
+-	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
+-
+-	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
+-}
+-
+-static void wlc_phy_radio_postinit_2056(phy_info_t *pi)
+-{
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
+-
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
+-	udelay(1000);
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
+-
+-	if ((pi->sh->boardflags2 & BFL2_LEGACY)
+-	    || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) {
+-
+-		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
+-	} else {
+-
+-		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
+-
+-	if (pi->phy_init_por) {
+-		wlc_phy_radio205x_rcal(pi);
+-	}
+-}
+-
+-static void wlc_phy_radio_init_2057(phy_info_t *pi)
+-{
+-	radio_20xx_regs_t *regs_2057_ptr = NULL;
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-		regs_2057_ptr = regs_2057_rev4;
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 8)
+-		   || NREV_IS(pi->pubpi.phy_rev, 9)) {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-
+-			if (pi->pubpi.radiover == 0x0) {
+-
+-				regs_2057_ptr = regs_2057_rev5;
+-
+-			} else if (pi->pubpi.radiover == 0x1) {
+-
+-				regs_2057_ptr = regs_2057_rev5v1;
+-			} else {
+-				break;
+-			}
+-
+-		case 7:
+-
+-			regs_2057_ptr = regs_2057_rev7;
+-			break;
+-
+-		case 8:
+-
+-			regs_2057_ptr = regs_2057_rev8;
+-			break;
+-
+-		default:
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
+-}
+-
+-static void wlc_phy_radio_postinit_2057(phy_info_t *pi)
+-{
+-
+-	mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
+-
+-	if (pi->sh->chip == !BCM6362_CHIP_ID) {
+-
+-		mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
+-	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
+-	mdelay(2);
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
+-	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
+-
+-	if (pi->phy_init_por) {
+-		wlc_phy_radio205x_rcal(pi);
+-		wlc_phy_radio2057_rccal(pi);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
+-}
+-
+-static bool
+-wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+-		       chan_info_nphy_radio2057_t **t0,
+-		       chan_info_nphy_radio205x_t **t1,
+-		       chan_info_nphy_radio2057_rev5_t **t2,
+-		       chan_info_nphy_2055_t **t3)
+-{
+-	uint i;
+-	chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL;
+-	chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL;
+-	u32 tbl_len = 0;
+-
+-	int freq = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-			chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 8)
+-			   || NREV_IS(pi->pubpi.phy_rev, 9)) {
+-			switch (pi->pubpi.radiorev) {
+-
+-			case 5:
+-
+-				if (pi->pubpi.radiover == 0x0) {
+-
+-					chan_info_tbl_p_2 =
+-					    chan_info_nphyrev8_2057_rev5;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (chan_info_nphyrev8_2057_rev5);
+-
+-				} else if (pi->pubpi.radiover == 0x1) {
+-
+-					chan_info_tbl_p_2 =
+-					    chan_info_nphyrev9_2057_rev5v1;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (chan_info_nphyrev9_2057_rev5v1);
+-
+-				}
+-				break;
+-
+-			case 7:
+-				chan_info_tbl_p_0 =
+-				    chan_info_nphyrev8_2057_rev7;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev8_2057_rev7);
+-				break;
+-
+-			case 8:
+-				chan_info_tbl_p_0 =
+-				    chan_info_nphyrev8_2057_rev8;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
+-				break;
+-
+-			default:
+-				if (NORADIO_ENAB(pi->pubpi)) {
+-					goto fail;
+-				}
+-				break;
+-			}
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
+-
+-			chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
+-		} else {
+-			goto fail;
+-		}
+-
+-		for (i = 0; i < tbl_len; i++) {
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				if (chan_info_tbl_p_2[i].chan == channel)
+-					break;
+-			} else {
+-
+-				if (chan_info_tbl_p_0[i].chan == channel)
+-					break;
+-			}
+-		}
+-
+-		if (i >= tbl_len) {
+-			goto fail;
+-		}
+-		if (pi->pubpi.radiorev == 5) {
+-			*t2 = &chan_info_tbl_p_2[i];
+-			freq = chan_info_tbl_p_2[i].freq;
+-		} else {
+-			*t0 = &chan_info_tbl_p_0[i];
+-			freq = chan_info_tbl_p_0[i].freq;
+-		}
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-			chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)
+-			   || NREV_IS(pi->pubpi.phy_rev, 6)) {
+-			switch (pi->pubpi.radiorev) {
+-			case 5:
+-				chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
+-				break;
+-			case 6:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
+-				break;
+-			case 7:
+-			case 9:
+-				chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
+-				break;
+-			case 8:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
+-				break;
+-			case 11:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11);
+-				break;
+-			default:
+-				if (NORADIO_ENAB(pi->pubpi)) {
+-					goto fail;
+-				}
+-				break;
+-			}
+-		}
+-
+-		for (i = 0; i < tbl_len; i++) {
+-			if (chan_info_tbl_p_1[i].chan == channel)
+-				break;
+-		}
+-
+-		if (i >= tbl_len) {
+-			goto fail;
+-		}
+-		*t1 = &chan_info_tbl_p_1[i];
+-		freq = chan_info_tbl_p_1[i].freq;
+-
+-	} else {
+-		for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
+-			if (chan_info_nphy_2055[i].chan == channel)
+-				break;
+-
+-		if (i >= ARRAY_SIZE(chan_info_nphy_2055)) {
+-			goto fail;
+-		}
+-		*t3 = &chan_info_nphy_2055[i];
+-		freq = chan_info_nphy_2055[i].freq;
+-	}
+-
+-	*f = freq;
+-	return true;
+-
+- fail:
+-	*f = WL_CHAN_FREQ_RANGE_2G;
+-	return false;
+-}
+-
+-u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel)
+-{
+-	int freq;
+-	chan_info_nphy_radio2057_t *t0 = NULL;
+-	chan_info_nphy_radio205x_t *t1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+-	chan_info_nphy_2055_t *t3 = NULL;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return WL_CHAN_FREQ_RANGE_2G;
+-
+-	if (channel == 0)
+-		channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-
+-	wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		return WL_CHAN_FREQ_RANGE_2G;
+-
+-	if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) {
+-		return WL_CHAN_FREQ_RANGE_5GL;
+-	} else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) {
+-		return WL_CHAN_FREQ_RANGE_5GM;
+-	} else {
+-		return WL_CHAN_FREQ_RANGE_5GH;
+-	}
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci)
+-{
+-
+-	write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
+-	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
+-	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
+-	write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
+-	write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
+-	write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
+-			ci->RF_core1_lgbuf_a_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
+-			ci->RF_core1_lgbuf_g_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
+-	write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
+-			ci->RF_core1_tx_pga_pad_tn);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
+-			ci->RF_core1_tx_mx_bgtrim);
+-	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
+-			ci->RF_core2_lgbuf_a_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
+-			ci->RF_core2_lgbuf_g_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
+-			ci->RF_core2_tx_pga_pad_tn);
+-	write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
+-			ci->RF_core2_tx_mx_bgtrim);
+-
+-	udelay(50);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
+-
+-	udelay(300);
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2056_setup(phy_info_t *pi,
+-				 const chan_info_nphy_radio205x_t *ci)
+-{
+-	radio_regs_t *regs_SYN_2056_ptr = NULL;
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_vcocal1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_vcocal2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_refdiv);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_mmd2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_mmd1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter3);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter4);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter5);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr27);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr28);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr29);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_VCOBUF1);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_MIXER2);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_BUF3);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_BUF4);
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
+-			ci->RF_RX0_lnaa_tune);
+-	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
+-			ci->RF_RX0_lnag_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_intpaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_intpag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pada_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_padg_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pgaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pgag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_mixa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_mixg_boost_tune);
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
+-			ci->RF_RX1_lnaa_tune);
+-	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
+-			ci->RF_RX1_lnag_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_intpaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_intpag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pada_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_padg_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pgaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pgag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_mixa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_mixg_boost_tune);
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 3))
+-		regs_SYN_2056_ptr = regs_SYN_2056;
+-	else if (NREV_IS(pi->pubpi.phy_rev, 4))
+-		regs_SYN_2056_ptr = regs_SYN_2056_A1;
+-	else {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+-			break;
+-		case 6:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+-			break;
+-		case 7:
+-		case 9:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+-			break;
+-		case 8:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+-			break;
+-		case 11:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+-			break;
+-		}
+-	}
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-				RADIO_2056_SYN,
+-				(u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
+-	} else {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-				RADIO_2056_SYN,
+-				(u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
+-	}
+-
+-	if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+-					RADIO_2056_SYN, 0x1f);
+-
+-			if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-			    (pi->sh->chip == BCM47162_CHIP_ID)) {
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-						RADIO_2056_SYN, 0x14);
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_CP2 |
+-						RADIO_2056_SYN, 0x00);
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-						RADIO_2056_SYN, 0xb);
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_CP2 |
+-						RADIO_2056_SYN, 0x14);
+-			}
+-		}
+-	}
+-
+-	if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
+-	    (CHSPEC_IS2G(pi->radio_chanspec))) {
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+-				0x1f);
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+-				0x1f);
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+-				0xb);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
+-				0x20);
+-	}
+-
+-	if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-					RADIO_2056_SYN, 0x5);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-					RADIO_2056_SYN, 0xc);
+-		}
+-	}
+-
+-	if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
+-		u16 pag_boost_tune;
+-		u16 padg_boost_tune;
+-		u16 pgag_boost_tune;
+-		u16 mixg_boost_tune;
+-		u16 bias, cascbias;
+-		uint core;
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PADG_IDAC, 0xcc);
+-
+-				if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-				    (pi->sh->chip ==
+-				     BCM47162_CHIP_ID)) {
+-					bias = 0x40;
+-					cascbias = 0x45;
+-					pag_boost_tune = 0x5;
+-					pgag_boost_tune = 0x33;
+-					padg_boost_tune = 0x77;
+-					mixg_boost_tune = 0x55;
+-				} else {
+-					bias = 0x25;
+-					cascbias = 0x20;
+-
+-					if ((pi->sh->chip ==
+-					     BCM43224_CHIP_ID)
+-					    || (pi->sh->chip ==
+-						BCM43225_CHIP_ID)
+-					    || (pi->sh->chip ==
+-						BCM43421_CHIP_ID)) {
+-						if (pi->sh->chippkg ==
+-						    BCM43224_FAB_SMIC) {
+-							bias = 0x2a;
+-							cascbias = 0x38;
+-						}
+-					}
+-
+-					pag_boost_tune = 0x4;
+-					pgag_boost_tune = 0x03;
+-					padg_boost_tune = 0x77;
+-					mixg_boost_tune = 0x65;
+-				}
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IMAIN_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IAUX_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_CASCBIAS, cascbias);
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_BOOST_TUNE,
+-						 pag_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PGAG_BOOST_TUNE,
+-						 pgag_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PADG_BOOST_TUNE,
+-						 padg_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 MIXG_BOOST_TUNE,
+-						 mixg_boost_tune);
+-			} else {
+-
+-				bias = IS40MHZ(pi) ? 0x40 : 0x20;
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IMAIN_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IAUX_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_CASCBIAS, 0x30);
+-			}
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
+-					 0xee);
+-		}
+-	}
+-
+-	if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
+-	    && CHSPEC_IS5G(pi->radio_chanspec)) {
+-		u16 paa_boost_tune;
+-		u16 pada_boost_tune;
+-		u16 pgaa_boost_tune;
+-		u16 mixa_boost_tune;
+-		u16 freq, pabias, cascbias;
+-		uint core;
+-
+-		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+-
+-		if (freq < 5150) {
+-
+-			paa_boost_tune = 0xa;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xf;
+-			mixa_boost_tune = 0xf;
+-		} else if (freq < 5340) {
+-
+-			paa_boost_tune = 0x8;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xfb;
+-			mixa_boost_tune = 0xf;
+-		} else if (freq < 5650) {
+-
+-			paa_boost_tune = 0x0;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xb;
+-			mixa_boost_tune = 0xf;
+-		} else {
+-
+-			paa_boost_tune = 0x0;
+-			pada_boost_tune = 0x77;
+-			if (freq != 5825) {
+-				pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
+-			} else {
+-				pgaa_boost_tune = 6;
+-			}
+-			mixa_boost_tune = 0xf;
+-		}
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_BOOST_TUNE, paa_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PADA_BOOST_TUNE, pada_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PGAA_BOOST_TUNE, pgaa_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 MIXA_BOOST_TUNE, mixa_boost_tune);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 TXSPARE1, 0x30);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PA_SPARE2, 0xee);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PADA_CASCBIAS, 0x3);
+-
+-			cascbias = 0x30;
+-
+-			if ((pi->sh->chip == BCM43224_CHIP_ID) ||
+-			    (pi->sh->chip == BCM43225_CHIP_ID) ||
+-			    (pi->sh->chip == BCM43421_CHIP_ID)) {
+-				if (pi->sh->chippkg == BCM43224_FAB_SMIC) {
+-					cascbias = 0x35;
+-				}
+-			}
+-
+-			pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_IAUX_STAT, pabias);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_IMAIN_STAT, pabias);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_CASCBIAS, cascbias);
+-		}
+-	}
+-
+-	udelay(50);
+-
+-	wlc_phy_radio205x_vcocal_nphy(pi);
+-}
+-
+-void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
+-			      (1 << 2));
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
+-	}
+-
+-	udelay(300);
+-}
+-
+-#define MAX_205x_RCAL_WAITLOOPS 10000
+-
+-static u16 wlc_phy_radio205x_rcal(phy_info_t *pi)
+-{
+-	u16 rcal_reg = 0;
+-	int i;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			and_phy_reg(pi, 0x342, ~(0x1 << 1));
+-
+-			udelay(10);
+-
+-			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
+-			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+-				      0x1);
+-		}
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
+-
+-		udelay(10);
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
+-
+-		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-			rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
+-			if (rcal_reg & 0x1) {
+-				break;
+-			}
+-			udelay(100);
+-		}
+-
+-		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+-			 "HW error: radio calib2"))
+-			return 0;
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
+-
+-		rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
+-			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+-				      0x0);
+-		}
+-
+-		if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+-
+-			mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
+-				      rcal_reg);
+-			mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
+-				      rcal_reg << 2);
+-		}
+-
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-		u16 savereg;
+-
+-		savereg =
+-		    read_radio_reg(pi,
+-				   RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+-				savereg | 0x7);
+-		udelay(10);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x1);
+-		udelay(10);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x9);
+-
+-		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-			rcal_reg = read_radio_reg(pi,
+-						  RADIO_2056_SYN_RCAL_CODE_OUT |
+-						  RADIO_2056_SYN);
+-			if (rcal_reg & 0x80) {
+-				break;
+-			}
+-			udelay(100);
+-		}
+-
+-		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+-			 "HW error: radio calib3"))
+-			return 0;
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x1);
+-
+-		rcal_reg =
+-		    read_radio_reg(pi,
+-				   RADIO_2056_SYN_RCAL_CODE_OUT |
+-				   RADIO_2056_SYN);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x0);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+-				savereg);
+-
+-		return rcal_reg & 0x1f;
+-	}
+-	return rcal_reg & 0x3e;
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2057_setup(phy_info_t *pi,
+-				 const chan_info_nphy_radio2057_t *ci,
+-				 const chan_info_nphy_radio2057_rev5_t *ci2)
+-{
+-	int coreNum;
+-	u16 txmix2g_tune_boost_pu = 0;
+-	u16 pad2g_tune_pus = 0;
+-
+-	if (pi->pubpi.radiorev == 5) {
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOCAL_COUNTVAL0,
+-				ci2->RF_vcocal_countval0);
+-		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+-				ci2->RF_vcocal_countval1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+-				ci2->RF_rfpll_refmaster_sparextalsize);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-				ci2->RF_rfpll_loopfilter_r1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-				ci2->RF_rfpll_loopfilter_c2);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-				ci2->RF_rfpll_loopfilter_c1);
+-		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
+-				ci2->RF_cp_kpd_idac);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
+-		write_radio_reg(pi,
+-				RADIO_2057_LOGEN_MX2G_TUNE,
+-				ci2->RF_logen_mx2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+-				ci2->RF_logen_indbuf2g_tune);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+-				ci2->RF_txmix2g_tune_boost_pu_core0);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-				ci2->RF_pad2g_tune_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+-				ci2->RF_lna2g_tune_core0);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+-				ci2->RF_txmix2g_tune_boost_pu_core1);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-				ci2->RF_pad2g_tune_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+-				ci2->RF_lna2g_tune_core1);
+-
+-	} else {
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOCAL_COUNTVAL0,
+-				ci->RF_vcocal_countval0);
+-		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+-				ci->RF_vcocal_countval1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+-				ci->RF_rfpll_refmaster_sparextalsize);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-				ci->RF_rfpll_loopfilter_r1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-				ci->RF_rfpll_loopfilter_c2);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-				ci->RF_rfpll_loopfilter_c1);
+-		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
+-		write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
+-		write_radio_reg(pi,
+-				RADIO_2057_LOGEN_MX2G_TUNE,
+-				ci->RF_logen_mx2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
+-				ci->RF_logen_mx5g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+-				ci->RF_logen_indbuf2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
+-				ci->RF_logen_indbuf5g_tune);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+-				ci->RF_txmix2g_tune_boost_pu_core0);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-				ci->RF_pad2g_tune_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
+-				ci->RF_pga_boost_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
+-				ci->RF_txmix5g_boost_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
+-				ci->RF_pad5g_tune_misc_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+-				ci->RF_lna2g_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
+-				ci->RF_lna5g_tune_core0);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+-				ci->RF_txmix2g_tune_boost_pu_core1);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-				ci->RF_pad2g_tune_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
+-				ci->RF_pga_boost_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
+-				ci->RF_txmix5g_boost_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
+-				ci->RF_pad5g_tune_misc_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+-				ci->RF_lna2g_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
+-				ci->RF_lna5g_tune_core1);
+-	}
+-
+-	if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x3f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		} else {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		}
+-	} else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
+-		   (pi->pubpi.radiorev == 8)) {
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1b);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0xa);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0xa);
+-		} else {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		}
+-
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (PHY_IPA(pi)) {
+-			if (pi->pubpi.radiorev == 3) {
+-				txmix2g_tune_boost_pu = 0x6b;
+-			}
+-
+-			if (pi->pubpi.radiorev == 5)
+-				pad2g_tune_pus = 0x73;
+-
+-		} else {
+-			if (pi->pubpi.radiorev != 5) {
+-				pad2g_tune_pus = 0x3;
+-
+-				txmix2g_tune_boost_pu = 0x61;
+-			}
+-		}
+-
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			if (txmix2g_tune_boost_pu != 0)
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 TXMIX2G_TUNE_BOOST_PU,
+-						 txmix2g_tune_boost_pu);
+-
+-			if (pad2g_tune_pus != 0)
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 PAD2G_TUNE_PUS,
+-						 pad2g_tune_pus);
+-		}
+-	}
+-
+-	udelay(50);
+-
+-	wlc_phy_radio205x_vcocal_nphy(pi);
+-}
+-
+-static u16 wlc_phy_radio2057_rccal(phy_info_t *pi)
+-{
+-	u16 rccal_valid;
+-	int i;
+-	bool chip43226_6362A0;
+-
+-	chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
+-			    || (pi->pubpi.radiorev == 4)
+-			    || (pi->pubpi.radiorev == 6));
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
+-		return 0;
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	return rccal_valid;
+-}
+-
+-static void
+-wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+-		    CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (!pi->nphy_anarxlpf_adjusted) {
+-				write_radio_reg(pi,
+-						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-						 RADIO_2056_RX0),
+-						((pi->nphy_rccal_value +
+-						  reduction_factr) | 0x80));
+-
+-				pi->nphy_anarxlpf_adjusted = true;
+-			}
+-		} else {
+-			if (pi->nphy_anarxlpf_adjusted) {
+-				write_radio_reg(pi,
+-						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-						 RADIO_2056_RX0),
+-						(pi->nphy_rccal_value | 0x80));
+-
+-				pi->nphy_anarxlpf_adjusted = false;
+-			}
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf,
+-				 u32 *noise_var_buf)
+-{
+-	int i;
+-	u32 offset;
+-	int tone_id;
+-	int tbllen =
+-	    CHSPEC_IS40(pi->
+-			radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 :
+-	    NPHY_NOISEVAR_TBLLEN20;
+-
+-	if (pi->nphy_noisevars_adjusted) {
+-		for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
+-			tone_id = pi->nphy_saved_noisevars.tone_id[i];
+-			offset = (tone_id >= 0) ?
+-			    ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 offset, 32,
+-						 (void *)&pi->
+-						 nphy_saved_noisevars.
+-						 min_noise_vars[i]);
+-		}
+-
+-		pi->nphy_saved_noisevars.bufcount = 0;
+-		pi->nphy_noisevars_adjusted = false;
+-	}
+-
+-	if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
+-		pi->nphy_saved_noisevars.bufcount = 0;
+-
+-		for (i = 0; i < ntones; i++) {
+-			tone_id = tone_id_buf[i];
+-			offset = (tone_id >= 0) ?
+-			    ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+-			pi->nphy_saved_noisevars.tone_id[i] = tone_id;
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						offset, 32,
+-						&pi->nphy_saved_noisevars.
+-						min_noise_vars[i]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 offset, 32,
+-						 (void *)&noise_var_buf[i]);
+-			pi->nphy_saved_noisevars.bufcount++;
+-		}
+-
+-		pi->nphy_noisevars_adjusted = true;
+-	}
+-}
+-
+-static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr)
+-{
+-	u16 regval;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+-		    CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (!pi->nphy_crsminpwr_adjusted) {
+-				regval = read_phy_reg(pi, 0x27d);
+-				pi->nphy_crsminpwr[0] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x27d, regval);
+-
+-				regval = read_phy_reg(pi, 0x280);
+-				pi->nphy_crsminpwr[1] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x280, regval);
+-
+-				regval = read_phy_reg(pi, 0x283);
+-				pi->nphy_crsminpwr[2] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x283, regval);
+-
+-				pi->nphy_crsminpwr_adjusted = true;
+-			}
+-		} else {
+-			if (pi->nphy_crsminpwr_adjusted) {
+-				regval = read_phy_reg(pi, 0x27d);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[0];
+-				write_phy_reg(pi, 0x27d, regval);
+-
+-				regval = read_phy_reg(pi, 0x280);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[1];
+-				write_phy_reg(pi, 0x280, regval);
+-
+-				regval = read_phy_reg(pi, 0x283);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[2];
+-				write_phy_reg(pi, 0x283, regval);
+-
+-				pi->nphy_crsminpwr_adjusted = false;
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txlpfbw_nphy(phy_info_t *pi)
+-{
+-	u8 tx_lpf_bw = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			tx_lpf_bw = 3;
+-		} else {
+-			tx_lpf_bw = 1;
+-		}
+-
+-		if (PHY_IPA(pi)) {
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				tx_lpf_bw = 5;
+-			} else {
+-				tx_lpf_bw = 4;
+-			}
+-		}
+-		write_phy_reg(pi, 0xe8,
+-			      (tx_lpf_bw << 0) |
+-			      (tx_lpf_bw << 3) |
+-			      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+-
+-		if (PHY_IPA(pi)) {
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				tx_lpf_bw = 4;
+-			} else {
+-				tx_lpf_bw = 1;
+-			}
+-
+-			write_phy_reg(pi, 0xe9,
+-				      (tx_lpf_bw << 0) |
+-				      (tx_lpf_bw << 3) |
+-				      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+-		}
+-	}
+-}
+-
+-static void wlc_phy_spurwar_nphy(phy_info_t *pi)
+-{
+-	u16 cur_channel = 0;
+-	int nphy_adj_tone_id_buf[] = { 57, 58 };
+-	u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
+-	bool isAdjustNoiseVar = false;
+-	uint numTonesAdjust = 0;
+-	u32 tempval = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-		cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-
+-		if (pi->nphy_gband_spurwar_en) {
+-
+-			wlc_phy_adjust_rx_analpfbw_nphy(pi,
+-							NPHY_ANARXLPFBW_REDUCTIONFACT);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if ((cur_channel == 11)
+-				    && CHSPEC_IS40(pi->radio_chanspec)) {
+-
+-					wlc_phy_adjust_min_noisevar_nphy(pi, 2,
+-									 nphy_adj_tone_id_buf,
+-									 nphy_adj_noise_var_buf);
+-				} else {
+-
+-					wlc_phy_adjust_min_noisevar_nphy(pi, 0,
+-									 NULL,
+-									 NULL);
+-				}
+-			}
+-			wlc_phy_adjust_crsminpwr_nphy(pi,
+-						      NPHY_ADJUSTED_MINCRSPOWER);
+-		}
+-
+-		if ((pi->nphy_gband_spurwar2_en)
+-		    && CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				switch (cur_channel) {
+-				case 3:
+-					nphy_adj_tone_id_buf[0] = 57;
+-					nphy_adj_tone_id_buf[1] = 58;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 4:
+-					nphy_adj_tone_id_buf[0] = 41;
+-					nphy_adj_tone_id_buf[1] = 42;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 5:
+-					nphy_adj_tone_id_buf[0] = 25;
+-					nphy_adj_tone_id_buf[1] = 26;
+-					nphy_adj_noise_var_buf[0] = 0x24f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 6:
+-					nphy_adj_tone_id_buf[0] = 9;
+-					nphy_adj_tone_id_buf[1] = 10;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 7:
+-					nphy_adj_tone_id_buf[0] = 121;
+-					nphy_adj_tone_id_buf[1] = 122;
+-					nphy_adj_noise_var_buf[0] = 0x18f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 8:
+-					nphy_adj_tone_id_buf[0] = 105;
+-					nphy_adj_tone_id_buf[1] = 106;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 9:
+-					nphy_adj_tone_id_buf[0] = 89;
+-					nphy_adj_tone_id_buf[1] = 90;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 10:
+-					nphy_adj_tone_id_buf[0] = 73;
+-					nphy_adj_tone_id_buf[1] = 74;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				default:
+-					isAdjustNoiseVar = false;
+-					break;
+-				}
+-			}
+-
+-			if (isAdjustNoiseVar) {
+-				numTonesAdjust = sizeof(nphy_adj_tone_id_buf) /
+-				    sizeof(nphy_adj_tone_id_buf[0]);
+-
+-				wlc_phy_adjust_min_noisevar_nphy(pi,
+-								 numTonesAdjust,
+-								 nphy_adj_tone_id_buf,
+-								 nphy_adj_noise_var_buf);
+-
+-				tempval = 0;
+-
+-			} else {
+-
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+-								 NULL);
+-			}
+-		}
+-
+-		if ((pi->nphy_aband_spurwar_en) &&
+-		    (CHSPEC_IS5G(pi->radio_chanspec))) {
+-			switch (cur_channel) {
+-			case 54:
+-				nphy_adj_tone_id_buf[0] = 32;
+-				nphy_adj_noise_var_buf[0] = 0x25f;
+-				break;
+-			case 38:
+-			case 102:
+-			case 118:
+-				if ((pi->sh->chip == BCM4716_CHIP_ID) &&
+-				    (pi->sh->chippkg == BCM4717_PKG_ID)) {
+-					nphy_adj_tone_id_buf[0] = 32;
+-					nphy_adj_noise_var_buf[0] = 0x21f;
+-				} else {
+-					nphy_adj_tone_id_buf[0] = 0;
+-					nphy_adj_noise_var_buf[0] = 0x0;
+-				}
+-				break;
+-			case 134:
+-				nphy_adj_tone_id_buf[0] = 32;
+-				nphy_adj_noise_var_buf[0] = 0x21f;
+-				break;
+-			case 151:
+-				nphy_adj_tone_id_buf[0] = 16;
+-				nphy_adj_noise_var_buf[0] = 0x23f;
+-				break;
+-			case 153:
+-			case 161:
+-				nphy_adj_tone_id_buf[0] = 48;
+-				nphy_adj_noise_var_buf[0] = 0x23f;
+-				break;
+-			default:
+-				nphy_adj_tone_id_buf[0] = 0;
+-				nphy_adj_noise_var_buf[0] = 0x0;
+-				break;
+-			}
+-
+-			if (nphy_adj_tone_id_buf[0]
+-			    && nphy_adj_noise_var_buf[0]) {
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 1,
+-								 nphy_adj_tone_id_buf,
+-								 nphy_adj_noise_var_buf);
+-			} else {
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+-								 NULL);
+-			}
+-		}
+-
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-	}
+-}
+-
+-static void
+-wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec,
+-			    const nphy_sfo_cfg_t *ci)
+-{
+-	u16 val;
+-
+-	val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-	if (CHSPEC_IS5G(chanspec) && !val) {
+-
+-		val = R_REG(&pi->regs->psm_phy_hdr_param);
+-		W_REG(&pi->regs->psm_phy_hdr_param,
+-		      (val | MAC_PHY_FORCE_CLK));
+-
+-		or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+-			   (BBCFG_RESETCCA | BBCFG_RESETRX));
+-
+-		W_REG(&pi->regs->psm_phy_hdr_param, val);
+-
+-		or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
+-	} else if (!CHSPEC_IS5G(chanspec) && val) {
+-
+-		and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
+-
+-		val = R_REG(&pi->regs->psm_phy_hdr_param);
+-		W_REG(&pi->regs->psm_phy_hdr_param,
+-		      (val | MAC_PHY_FORCE_CLK));
+-
+-		and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+-			    (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
+-
+-		W_REG(&pi->regs->psm_phy_hdr_param, val);
+-	}
+-
+-	write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
+-	write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
+-	write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
+-
+-	write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
+-	write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
+-	write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
+-
+-	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
+-
+-		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
+-	} else {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
+-					NPHY_ClassifierCtrl_ofdm_en);
+-
+-		if (CHSPEC_IS2G(chanspec))
+-			and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
+-	}
+-
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-		wlc_phy_txpwr_fixpower_nphy(pi);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-		wlc_phy_adjust_lnagaintbl_nphy(pi);
+-	}
+-
+-	wlc_phy_txlpfbw_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)
+-	    && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
+-		u8 spuravoid = 0;
+-
+-		val = CHSPEC_CHANNEL(chanspec);
+-		if (!CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				if ((val == 13) || (val == 14) || (val == 153)) {
+-					spuravoid = 1;
+-				}
+-			} else {
+-
+-				if (((val >= 5) && (val <= 8)) || (val == 13)
+-				    || (val == 14)) {
+-					spuravoid = 1;
+-				}
+-			}
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				if (val == 54) {
+-					spuravoid = 1;
+-				}
+-			} else {
+-
+-				if (pi->nphy_aband_spurwar_en &&
+-				    ((val == 38) || (val == 102)
+-				     || (val == 118))) {
+-					if ((pi->sh->chip ==
+-					     BCM4716_CHIP_ID)
+-					    && (pi->sh->chippkg ==
+-						BCM4717_PKG_ID)) {
+-						spuravoid = 0;
+-					} else {
+-						spuravoid = 1;
+-					}
+-				}
+-			}
+-		}
+-
+-		if (pi->phy_spuravoid == SPURAVOID_FORCEON)
+-			spuravoid = 1;
+-
+-		if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-		    (pi->sh->chip == BCM47162_CHIP_ID)) {
+-			si_pmu_spuravoid(pi->sh->sih, spuravoid);
+-		} else {
+-			wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
+-			si_pmu_spuravoid(pi->sh->sih, spuravoid);
+-			wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
+-		}
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID) ||
+-		    (pi->sh->chip == BCM43225_CHIP_ID) ||
+-		    (pi->sh->chip == BCM43421_CHIP_ID)) {
+-
+-			if (spuravoid == 1) {
+-
+-				W_REG(&pi->regs->tsf_clk_frac_l,
+-				      0x5341);
+-				W_REG(&pi->regs->tsf_clk_frac_h,
+-				      0x8);
+-			} else {
+-
+-				W_REG(&pi->regs->tsf_clk_frac_l,
+-				      0x8889);
+-				W_REG(&pi->regs->tsf_clk_frac_h,
+-				      0x8);
+-			}
+-		}
+-
+-		if (!((pi->sh->chip == BCM4716_CHIP_ID) ||
+-		      (pi->sh->chip == BCM47162_CHIP_ID))) {
+-			wlapi_bmac_core_phypll_reset(pi->sh->physhim);
+-		}
+-
+-		mod_phy_reg(pi, 0x01, (0x1 << 15),
+-			    ((spuravoid > 0) ? (0x1 << 15) : 0));
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-		pi->phy_isspuravoid = (spuravoid > 0);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7))
+-		write_phy_reg(pi, 0x17e, 0x3830);
+-
+-	wlc_phy_spurwar_nphy(pi);
+-}
+-
+-void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	int freq;
+-	chan_info_nphy_radio2057_t *t0 = NULL;
+-	chan_info_nphy_radio205x_t *t1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+-	chan_info_nphy_2055_t *t3 = NULL;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		return;
+-	}
+-
+-	if (!wlc_phy_chan2freq_nphy
+-	    (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
+-		return;
+-
+-	wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+-
+-	if (CHSPEC_BW(chanspec) != pi->bw)
+-		wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
+-
+-	if (CHSPEC_IS40(chanspec)) {
+-		if (CHSPEC_SB_UPPER(chanspec)) {
+-			or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
+-			}
+-		} else {
+-			and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				and_phy_reg(pi, 0x310,
+-					    (~PRIM_SEL_UP20 & 0xffff));
+-			}
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			if ((pi->pubpi.radiorev <= 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
+-					      0x2,
+-					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
+-					       : 0));
+-				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
+-					      0x2,
+-					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
+-					       : 0));
+-			}
+-
+-			wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
+-			wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-						    (pi->pubpi.radiorev ==
+-						     5) ? (const nphy_sfo_cfg_t
+-							   *)&(t2->
+-							       PHY_BW1a)
+-						    : (const nphy_sfo_cfg_t *)
+-						    &(t0->PHY_BW1a));
+-
+-		} else {
+-
+-			mod_radio_reg(pi,
+-				      RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
+-				      0x4,
+-				      (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
+-			wlc_phy_chanspec_radio2056_setup(pi, t1);
+-
+-			wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-						    (const nphy_sfo_cfg_t *)
+-						    &(t1->PHY_BW1a));
+-		}
+-
+-	} else {
+-
+-		mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
+-			      (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
+-			       : (0x05 << 4)));
+-
+-		wlc_phy_chanspec_radio2055_setup(pi, t3);
+-		wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-					    (const nphy_sfo_cfg_t *)&(t3->
+-								      PHY_BW1a));
+-	}
+-
+-}
+-
+-static void wlc_phy_savecal_nphy(phy_info_t *pi)
+-{
+-	void *tbl_ptr;
+-	int coreNum;
+-	u16 *txcal_radio_regs = NULL;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_2G);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_2G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			pi->calibration_cache.txcal_radio_regs_2G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_2G[3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX1);
+-
+-			pi->calibration_cache.txcal_radio_regs_2G[4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[6] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_2G[7] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX1);
+-		} else {
+-			pi->calibration_cache.txcal_radio_regs_2G[0] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_2G[1] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_2G[2] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+-			pi->calibration_cache.txcal_radio_regs_2G[3] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+-		}
+-
+-		pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+-	} else {
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_5G);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_5G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			pi->calibration_cache.txcal_radio_regs_5G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_5G[3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX1);
+-
+-			pi->calibration_cache.txcal_radio_regs_5G[4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[6] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_5G[7] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX1);
+-		} else {
+-			pi->calibration_cache.txcal_radio_regs_5G[0] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_5G[1] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_5G[2] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+-			pi->calibration_cache.txcal_radio_regs_5G[3] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+-		}
+-
+-		pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			txcal_radio_regs[2 * coreNum] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_FINE_I);
+-			txcal_radio_regs[2 * coreNum + 1] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_FINE_Q);
+-
+-			txcal_radio_regs[2 * coreNum + 4] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_COARSE_I);
+-			txcal_radio_regs[2 * coreNum + 5] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_COARSE_Q);
+-		}
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_restorecal_nphy(phy_info_t *pi)
+-{
+-	u16 *loft_comp;
+-	u16 txcal_coeffs_bphy[4];
+-	u16 *tbl_ptr;
+-	int coreNum;
+-	u16 *txcal_radio_regs = NULL;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->nphy_iqcal_chanspec_2G == 0)
+-			return;
+-
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+-		loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
+-	} else {
+-		if (pi->nphy_iqcal_chanspec_5G == 0)
+-			return;
+-
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+-		loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16,
+-				 (void *)tbl_ptr);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		txcal_coeffs_bphy[0] = tbl_ptr[0];
+-		txcal_coeffs_bphy[1] = tbl_ptr[1];
+-		txcal_coeffs_bphy[2] = tbl_ptr[2];
+-		txcal_coeffs_bphy[3] = tbl_ptr[3];
+-	} else {
+-		txcal_coeffs_bphy[0] = 0;
+-		txcal_coeffs_bphy[1] = 0;
+-		txcal_coeffs_bphy[2] = 0;
+-		txcal_coeffs_bphy[3] = 0;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
+-				 txcal_coeffs_bphy);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2))
+-		wlc_phy_tx_iq_war_nphy(pi);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_2G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[0]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[1]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[2]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[4]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[5]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[6]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[7]);
+-		} else {
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[0]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[1]);
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[2]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[3]);
+-		}
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_2G);
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_5G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[0]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[1]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[2]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[4]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[5]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[6]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[7]);
+-		} else {
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[0]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[1]);
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[2]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[3]);
+-		}
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_5G);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_FINE_I,
+-					 txcal_radio_regs[2 * coreNum]);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_FINE_Q,
+-					 txcal_radio_regs[2 * coreNum + 1]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_COARSE_I,
+-					 txcal_radio_regs[2 * coreNum + 4]);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_COARSE_Q,
+-					 txcal_radio_regs[2 * coreNum + 5]);
+-		}
+-	}
+-}
+-
+-void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 mask = 0xfc00;
+-	u32 mc = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7))
+-		return;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
+-
+-		if (lut_init == false)
+-			return;
+-
+-		if (pi->srom_fem2g.antswctrllut == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x02, 16, &v0);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x03, 16, &v1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x08, 16, &v2);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x0C, 16, &v3);
+-		}
+-
+-		if (pi->srom_fem5g.antswctrllut == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x12, 16, &v0);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x13, 16, &v1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x18, 16, &v2);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x1C, 16, &v3);
+-		}
+-	} else {
+-
+-		write_phy_reg(pi, 0xc8, 0x0);
+-		write_phy_reg(pi, 0xc9, 0x0);
+-
+-		ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
+-
+-		mc = R_REG(&pi->regs->maccontrol);
+-		mc &= ~MCTL_GPOUT_SEL_MASK;
+-		W_REG(&pi->regs->maccontrol, mc);
+-
+-		OR_REG(&pi->regs->psm_gpio_oe, mask);
+-
+-		AND_REG(&pi->regs->psm_gpio_out, ~mask);
+-
+-		if (lut_init) {
+-			write_phy_reg(pi, 0xf8, 0x02d8);
+-			write_phy_reg(pi, 0xf9, 0x0301);
+-			write_phy_reg(pi, 0xfa, 0x02d8);
+-			write_phy_reg(pi, 0xfb, 0x0301);
+-		}
+-	}
+-}
+-
+-u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val)
+-{
+-	u16 curr_ctl, new_ctl;
+-	bool suspended = false;
+-
+-	if (D11REV_IS(pi->sh->corerev, 16)) {
+-		suspended =
+-		    (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ?
+-		    false : true;
+-		if (!suspended)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-
+-	curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
+-
+-	new_ctl = (curr_ctl & (~mask)) | (val & mask);
+-
+-	mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
+-
+-	if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-	return new_ctl;
+-}
+-
+-static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals)
+-{
+-
+-	if (write == 0) {
+-		vals[0] = read_phy_reg(pi, 0x2c);
+-		vals[1] = read_phy_reg(pi, 0x42);
+-	} else {
+-		write_phy_reg(pi, 0x2c, vals[0]);
+-		write_phy_reg(pi, 0x42, vals[1]);
+-	}
+-}
+-
+-void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd)
+-{
+-	u16 trigger_mask, status_mask;
+-	u16 orig_RfseqCoreActv;
+-
+-	switch (cmd) {
+-	case NPHY_RFSEQ_RX2TX:
+-		trigger_mask = NPHY_RfseqTrigger_rx2tx;
+-		status_mask = NPHY_RfseqStatus_rx2tx;
+-		break;
+-	case NPHY_RFSEQ_TX2RX:
+-		trigger_mask = NPHY_RfseqTrigger_tx2rx;
+-		status_mask = NPHY_RfseqStatus_tx2rx;
+-		break;
+-	case NPHY_RFSEQ_RESET2RX:
+-		trigger_mask = NPHY_RfseqTrigger_reset2rx;
+-		status_mask = NPHY_RfseqStatus_reset2rx;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINH:
+-		trigger_mask = NPHY_RfseqTrigger_updategainh;
+-		status_mask = NPHY_RfseqStatus_updategainh;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINL:
+-		trigger_mask = NPHY_RfseqTrigger_updategainl;
+-		status_mask = NPHY_RfseqStatus_updategainl;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINU:
+-		trigger_mask = NPHY_RfseqTrigger_updategainu;
+-		status_mask = NPHY_RfseqStatus_updategainu;
+-		break;
+-	default:
+-		return;
+-	}
+-
+-	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+-	or_phy_reg(pi, 0xa1,
+-		   (NPHY_RfseqMode_CoreActv_override |
+-		    NPHY_RfseqMode_Trigger_override));
+-	or_phy_reg(pi, 0xa3, trigger_mask);
+-	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
+-	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+-	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
+-}
+-
+-static void
+-wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys,
+-		       u8 len)
+-{
+-	u32 t1_offset, t2_offset;
+-	u8 ctr;
+-	u8 end_event =
+-	    NREV_GE(pi->pubpi.phy_rev,
+-		    3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
+-	u8 end_dly = 1;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	t1_offset = cmd << 4;
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
+-				 events);
+-	t2_offset = t1_offset + 0x080;
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
+-				 dlys);
+-
+-	for (ctr = len; ctr < 16; ctr++) {
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-					 t1_offset + ctr, 8, &end_event);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-					 t2_offset + ctr, 8, &end_dly);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset)
+-{
+-	u16 lpf_bw_ctl_val = 0;
+-	u16 rx2tx_lpf_rc_lut_offset = 0;
+-
+-	if (offset == 0) {
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			rx2tx_lpf_rc_lut_offset = 0x159;
+-		} else {
+-			rx2tx_lpf_rc_lut_offset = 0x154;
+-		}
+-	} else {
+-		rx2tx_lpf_rc_lut_offset = offset;
+-	}
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-				(u32) rx2tx_lpf_rc_lut_offset, 16,
+-				&lpf_bw_ctl_val);
+-
+-	lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
+-
+-	return lpf_bw_ctl_val;
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value,
+-				  u8 core_mask, u8 off, u8 override_id)
+-{
+-	u8 core_num;
+-	u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
+-	u8 val_shift = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		en_mask = field;
+-		for (core_num = 0; core_num < 2; core_num++) {
+-			if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
+-
+-				switch (field) {
+-				case (0x1 << 2):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 5):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 5);
+-					val_shift = 5;
+-					break;
+-				case (0x1 << 6):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 6);
+-					val_shift = 6;
+-					break;
+-				case (0x1 << 7):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 7);
+-					val_shift = 7;
+-					break;
+-				case (0x1 << 10):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0xf8 :
+-					    0xfa;
+-					val_mask = (0x7 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 11):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7b :
+-					    0x7e;
+-					val_mask = (0xffff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 12):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7c :
+-					    0x7f;
+-					val_mask = (0xffff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x3 << 13):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x348 :
+-					    0x349;
+-					val_mask = (0xff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 13):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x348 :
+-					    0x349;
+-					val_mask = (0xf << 0);
+-					val_shift = 0;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			} else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) {
+-
+-				switch (field) {
+-				case (0x1 << 1):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 3);
+-					val_shift = 3;
+-					break;
+-				case (0x1 << 5):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 5);
+-					val_shift = 5;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 2):
+-
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 7):
+-
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x7 << 8);
+-					val_shift = 8;
+-					break;
+-				case (0x1 << 11):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 14);
+-					val_shift = 14;
+-					break;
+-				case (0x1 << 10):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 13);
+-					val_shift = 13;
+-					break;
+-				case (0x1 << 9):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 12);
+-					val_shift = 12;
+-					break;
+-				case (0x1 << 8):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 11);
+-					val_shift = 11;
+-					break;
+-				case (0x1 << 6):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 6);
+-					val_shift = 6;
+-					break;
+-				case (0x1 << 0):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 0);
+-					val_shift = 0;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			} else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) {
+-
+-				switch (field) {
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 3);
+-					val_shift = 3;
+-					break;
+-				case (0x1 << 1):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 0):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 2):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			}
+-
+-			if (off) {
+-				and_phy_reg(pi, en_addr, ~en_mask);
+-				and_phy_reg(pi, val_addr, ~val_mask);
+-			} else {
+-
+-				if ((core_mask == 0)
+-				    || (core_mask & (1 << core_num))) {
+-					or_phy_reg(pi, en_addr, en_mask);
+-
+-					if (addr != 0xffff) {
+-						mod_phy_reg(pi, val_addr,
+-							    val_mask,
+-							    (value <<
+-							     val_shift));
+-					}
+-				}
+-			}
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value,
+-			     u8 core_mask, u8 off)
+-{
+-	u8 core_num;
+-	u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
+-	    0, val_mask = 0;
+-	u8 shift = 0, val_shift = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		en_mask = field;
+-		for (core_num = 0; core_num < 2; core_num++) {
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 2):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 1);
+-				val_shift = 1;
+-				break;
+-			case (0x1 << 3):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 2);
+-				val_shift = 2;
+-				break;
+-			case (0x1 << 4):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 4);
+-				val_shift = 4;
+-				break;
+-			case (0x1 << 5):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 5);
+-				val_shift = 5;
+-				break;
+-			case (0x1 << 6):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 6);
+-				val_shift = 6;
+-				break;
+-			case (0x1 << 7):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 7);
+-				val_shift = 7;
+-				break;
+-			case (0x1 << 8):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x7 << 8);
+-				val_shift = 8;
+-				break;
+-			case (0x1 << 11):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x7 << 13);
+-				val_shift = 13;
+-				break;
+-
+-			case (0x1 << 9):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+-				val_mask = (0x7 << 0);
+-				val_shift = 0;
+-				break;
+-
+-			case (0x1 << 10):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+-				val_mask = (0x7 << 4);
+-				val_shift = 4;
+-				break;
+-
+-			case (0x1 << 12):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7b : 0x7e;
+-				val_mask = (0xffff << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 13):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7c : 0x7f;
+-				val_mask = (0xffff << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 14):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+-				val_mask = (0x3 << 6);
+-				val_shift = 6;
+-				break;
+-			case (0x1 << 0):
+-				en_addr = (core_num == 0) ? 0xe5 : 0xe6;
+-				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+-				val_mask = (0x1 << 15);
+-				val_shift = 15;
+-				break;
+-			default:
+-				addr = 0xffff;
+-				break;
+-			}
+-
+-			if (off) {
+-				and_phy_reg(pi, en_addr, ~en_mask);
+-				and_phy_reg(pi, val_addr, ~val_mask);
+-			} else {
+-
+-				if ((core_mask == 0)
+-				    || (core_mask & (1 << core_num))) {
+-					or_phy_reg(pi, en_addr, en_mask);
+-
+-					if (addr != 0xffff) {
+-						mod_phy_reg(pi, val_addr,
+-							    val_mask,
+-							    (value <<
+-							     val_shift));
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		if (off) {
+-			and_phy_reg(pi, 0xec, ~field);
+-			value = 0x0;
+-		} else {
+-			or_phy_reg(pi, 0xec, field);
+-		}
+-
+-		for (core_num = 0; core_num < 2; core_num++) {
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-			case (0x1 << 9):
+-			case (0x1 << 12):
+-			case (0x1 << 13):
+-			case (0x1 << 14):
+-				addr = 0x78;
+-
+-				core_mask = 0x1;
+-				break;
+-			case (0x1 << 2):
+-			case (0x1 << 3):
+-			case (0x1 << 4):
+-			case (0x1 << 5):
+-			case (0x1 << 6):
+-			case (0x1 << 7):
+-			case (0x1 << 8):
+-				addr = (core_num == 0) ? 0x7a : 0x7d;
+-				break;
+-			case (0x1 << 10):
+-				addr = (core_num == 0) ? 0x7b : 0x7e;
+-				break;
+-			case (0x1 << 11):
+-				addr = (core_num == 0) ? 0x7c : 0x7f;
+-				break;
+-			default:
+-				addr = 0xffff;
+-			}
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-				mask = (0x7 << 3);
+-				shift = 3;
+-				break;
+-			case (0x1 << 9):
+-				mask = (0x1 << 2);
+-				shift = 2;
+-				break;
+-			case (0x1 << 12):
+-				mask = (0x1 << 8);
+-				shift = 8;
+-				break;
+-			case (0x1 << 13):
+-				mask = (0x1 << 9);
+-				shift = 9;
+-				break;
+-			case (0x1 << 14):
+-				mask = (0xf << 12);
+-				shift = 12;
+-				break;
+-			case (0x1 << 2):
+-				mask = (0x1 << 0);
+-				shift = 0;
+-				break;
+-			case (0x1 << 3):
+-				mask = (0x1 << 1);
+-				shift = 1;
+-				break;
+-			case (0x1 << 4):
+-				mask = (0x1 << 2);
+-				shift = 2;
+-				break;
+-			case (0x1 << 5):
+-				mask = (0x3 << 4);
+-				shift = 4;
+-				break;
+-			case (0x1 << 6):
+-				mask = (0x3 << 6);
+-				shift = 6;
+-				break;
+-			case (0x1 << 7):
+-				mask = (0x1 << 8);
+-				shift = 8;
+-				break;
+-			case (0x1 << 8):
+-				mask = (0x1 << 9);
+-				shift = 9;
+-				break;
+-			case (0x1 << 10):
+-				mask = 0x1fff;
+-				shift = 0x0;
+-				break;
+-			case (0x1 << 11):
+-				mask = 0x1fff;
+-				shift = 0x0;
+-				break;
+-			default:
+-				mask = 0x0;
+-				shift = 0x0;
+-				break;
+-			}
+-
+-			if ((addr != 0xffff) && (core_mask & (1 << core_num))) {
+-				mod_phy_reg(pi, addr, mask, (value << shift));
+-			}
+-		}
+-
+-		or_phy_reg(pi, 0xec, (0x1 << 0));
+-		or_phy_reg(pi, 0x78, (0x1 << 0));
+-		udelay(1);
+-		and_phy_reg(pi, 0xec, ~(0x1 << 0));
+-	}
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value,
+-				     u8 core_mask, u8 off)
+-{
+-	u16 rfmxgain = 0, lpfgain = 0;
+-	u16 tgain = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		switch (cmd) {
+-		case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_rxgain:
+-			rfmxgain = value & 0x000ff;
+-			lpfgain = value & 0x0ff00;
+-			lpfgain = lpfgain >> 8;
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+-							  rfmxgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13),
+-							  lpfgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_txgain:
+-			tgain = value & 0x7fff;
+-			lpfgain = value & 0x8000;
+-			lpfgain = lpfgain >> 14;
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-							  tgain, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13),
+-							  lpfgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			break;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset,
+-			       u8 coresel, u8 rail, u8 rssi_type)
+-{
+-	u16 valuetostuff;
+-
+-	offset = (offset > NPHY_RSSICAL_MAXREAD) ?
+-	    NPHY_RSSICAL_MAXREAD : offset;
+-	offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
+-	    -NPHY_RSSICAL_MAXREAD - 1 : offset;
+-
+-	valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1a6, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1ac, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1b2, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1b8, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1a4, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1aa, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1b0, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1b6, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1a5, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1ab, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1b1, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1b7, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1a7, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1ad, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1b3, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1b9, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1a8, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1ae, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1b4, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1ba, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+-		write_phy_reg(pi, 0x1a9, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+-		write_phy_reg(pi, 0x1b5, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+-		write_phy_reg(pi, 0x1af, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+-		write_phy_reg(pi, 0x1bb, valuetostuff);
+-	}
+-}
+-
+-void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type)
+-{
+-	u16 mask, val;
+-	u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
+-	    startseq;
+-	u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
+-	    rfctrlovr_trigger_val;
+-	u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
+-	u16 rfctrlcmd_val, rfctrlovr_val;
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (core_code == RADIO_MIMO_CORESEL_OFF) {
+-			mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
+-
+-			mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
+-			mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
+-
+-			mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
+-			mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
+-
+-			mask = (0x1 << 2) |
+-			    (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
+-			mod_phy_reg(pi, 0xf9, mask, 0);
+-			mod_phy_reg(pi, 0xfb, mask, 0);
+-
+-		} else {
+-			for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-				if (core_code == RADIO_MIMO_CORESEL_CORE1
+-				    && core == PHY_CORE_1)
+-					continue;
+-				else if (core_code == RADIO_MIMO_CORESEL_CORE2
+-					 && core == PHY_CORE_0)
+-					continue;
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ?
+-					    0x8f : 0xa5, (0x1 << 9), 1 << 9);
+-
+-				if (rssi_type == NPHY_RSSI_SEL_W1 ||
+-				    rssi_type == NPHY_RSSI_SEL_W2 ||
+-				    rssi_type == NPHY_RSSI_SEL_NB) {
+-
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xa6 : 0xa7,
+-						    (0x3 << 8), 0);
+-
+-					mask = (0x1 << 2) |
+-					    (0x1 << 3) |
+-					    (0x1 << 4) | (0x1 << 5);
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xf9 : 0xfb,
+-						    mask, 0);
+-
+-					if (rssi_type == NPHY_RSSI_SEL_W1) {
+-						if (CHSPEC_IS5G
+-						    (pi->radio_chanspec)) {
+-							mask = (0x1 << 2);
+-							val = 1 << 2;
+-						} else {
+-							mask = (0x1 << 3);
+-							val = 1 << 3;
+-						}
+-					} else if (rssi_type ==
+-						   NPHY_RSSI_SEL_W2) {
+-						mask = (0x1 << 4);
+-						val = 1 << 4;
+-					} else {
+-						mask = (0x1 << 5);
+-						val = 1 << 5;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xf9 : 0xfb,
+-						    mask, val);
+-
+-					mask = (0x1 << 5);
+-					val = 1 << 5;
+-					mod_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xe5 : 0xe6, mask, val);
+-				} else {
+-					if (rssi_type == NPHY_RSSI_SEL_TBD) {
+-
+-						mask = (0x3 << 8);
+-						val = 1 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 1 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-					} else if (rssi_type ==
+-						   NPHY_RSSI_SEL_IQ) {
+-
+-						mask = (0x3 << 8);
+-						val = 2 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 2 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-					} else {
+-
+-						mask = (0x3 << 8);
+-						val = 3 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 3 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-
+-						if (PHY_IPA(pi)) {
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     7)) {
+-
+-								write_radio_reg
+-								    (pi,
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2057_TX0_TX_SSI_MUX
+-								      :
+-								      RADIO_2057_TX1_TX_SSI_MUX),
+-								     (CHSPEC_IS5G
+-								      (pi->
+-								       radio_chanspec)
+-								      ? 0xc :
+-								      0xe));
+-							} else {
+-								write_radio_reg
+-								    (pi,
+-								     RADIO_2056_TX_TX_SSI_MUX
+-								     |
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2056_TX0
+-								      :
+-								      RADIO_2056_TX1),
+-								     (CHSPEC_IS5G
+-								      (pi->
+-								       radio_chanspec)
+-								      ? 0xc :
+-								      0xe));
+-							}
+-						} else {
+-
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     7)) {
+-								write_radio_reg
+-								    (pi,
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2057_TX0_TX_SSI_MUX
+-								      :
+-								      RADIO_2057_TX1_TX_SSI_MUX),
+-								     0x11);
+-
+-								if (pi->pubpi.
+-								    radioid ==
+-								    BCM2057_ID)
+-									write_radio_reg
+-									    (pi,
+-									     RADIO_2057_IQTEST_SEL_PU,
+-									     0x1);
+-
+-							} else {
+-								write_radio_reg
+-								    (pi,
+-								     RADIO_2056_TX_TX_SSI_MUX
+-								     |
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2056_TX0
+-								      :
+-								      RADIO_2056_TX1),
+-								     0x11);
+-							}
+-						}
+-
+-						afectrlovr_rssi_val = 1 << 9;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x8f
+-							    : 0xa5, (0x1 << 9),
+-							    afectrlovr_rssi_val);
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-
+-			val = 0x0;
+-		} else if (rssi_type == NPHY_RSSI_SEL_TBD) {
+-
+-			val = 0x1;
+-		} else if (rssi_type == NPHY_RSSI_SEL_IQ) {
+-
+-			val = 0x2;
+-		} else {
+-
+-			val = 0x3;
+-		}
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		val = (val << 12) | (val << 14);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-			if (rssi_type == NPHY_RSSI_SEL_W1) {
+-				val = 0x1;
+-			}
+-			if (rssi_type == NPHY_RSSI_SEL_W2) {
+-				val = 0x2;
+-			}
+-			if (rssi_type == NPHY_RSSI_SEL_NB) {
+-				val = 0x3;
+-			}
+-			mask = (0x3 << 4);
+-			val = (val << 4);
+-			mod_phy_reg(pi, 0x7a, mask, val);
+-			mod_phy_reg(pi, 0x7d, mask, val);
+-		}
+-
+-		if (core_code == RADIO_MIMO_CORESEL_OFF) {
+-			afectrlovr_rssi_val = 0;
+-			rfctrlcmd_rxen_val = 0;
+-			rfctrlcmd_coresel_val = 0;
+-			rfctrlovr_rssi_val = 0;
+-			rfctrlovr_rxen_val = 0;
+-			rfctrlovr_coresel_val = 0;
+-			rfctrlovr_trigger_val = 0;
+-			startseq = 0;
+-		} else {
+-			afectrlovr_rssi_val = 1;
+-			rfctrlcmd_rxen_val = 1;
+-			rfctrlcmd_coresel_val = core_code;
+-			rfctrlovr_rssi_val = 1;
+-			rfctrlovr_rxen_val = 1;
+-			rfctrlovr_coresel_val = 1;
+-			rfctrlovr_trigger_val = 1;
+-			startseq = 1;
+-		}
+-
+-		afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
+-		afectrlovr_rssi_val = (afectrlovr_rssi_val <<
+-				       12) | (afectrlovr_rssi_val << 13);
+-		mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
+-			    afectrlovr_rssi_val);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-			rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
+-			rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
+-			    (rfctrlcmd_coresel_val << 3);
+-
+-			rfctrlovr_mask = ((0x1 << 5) |
+-					  (0x1 << 12) |
+-					  (0x1 << 1) | (0x1 << 0));
+-			rfctrlovr_val = (rfctrlovr_rssi_val <<
+-					 5) |
+-			    (rfctrlovr_rxen_val << 12) |
+-			    (rfctrlovr_coresel_val << 1) |
+-			    (rfctrlovr_trigger_val << 0);
+-
+-			mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
+-			mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
+-
+-			mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
+-			udelay(20);
+-
+-			mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+-		}
+-	}
+-}
+-
+-int
+-wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf,
+-		       u8 nsamps)
+-{
+-	s16 rssi0, rssi1;
+-	u16 afectrlCore1_save = 0;
+-	u16 afectrlCore2_save = 0;
+-	u16 afectrlOverride1_save = 0;
+-	u16 afectrlOverride2_save = 0;
+-	u16 rfctrlOverrideAux0_save = 0;
+-	u16 rfctrlOverrideAux1_save = 0;
+-	u16 rfctrlMiscReg1_save = 0;
+-	u16 rfctrlMiscReg2_save = 0;
+-	u16 rfctrlcmd_save = 0;
+-	u16 rfctrloverride_save = 0;
+-	u16 rfctrlrssiothers1_save = 0;
+-	u16 rfctrlrssiothers2_save = 0;
+-	s8 tmp_buf[4];
+-	u8 ctr = 0, samp = 0;
+-	s32 rssi_out_val;
+-	u16 gpiosel_orig;
+-
+-	afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-	afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+-		rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+-		afectrlOverride1_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+-		rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+-	} else {
+-		afectrlOverride1_save = read_phy_reg(pi, 0xa5);
+-		rfctrlcmd_save = read_phy_reg(pi, 0x78);
+-		rfctrloverride_save = read_phy_reg(pi, 0xec);
+-		rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
+-		rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
+-	}
+-
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+-
+-	gpiosel_orig = read_phy_reg(pi, 0xca);
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0xca, 5);
+-	}
+-
+-	for (ctr = 0; ctr < 4; ctr++) {
+-		rssi_buf[ctr] = 0;
+-	}
+-
+-	for (samp = 0; samp < nsamps; samp++) {
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-			rssi0 = read_phy_reg(pi, 0x1c9);
+-			rssi1 = read_phy_reg(pi, 0x1ca);
+-		} else {
+-			rssi0 = read_phy_reg(pi, 0x219);
+-			rssi1 = read_phy_reg(pi, 0x21a);
+-		}
+-
+-		ctr = 0;
+-		tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
+-
+-		for (ctr = 0; ctr < 4; ctr++) {
+-			rssi_buf[ctr] += tmp_buf[ctr];
+-		}
+-
+-	}
+-
+-	rssi_out_val = rssi_buf[3] & 0xff;
+-	rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
+-	rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
+-	rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0xca, gpiosel_orig);
+-	}
+-
+-	write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-	write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
+-		write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride1_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-		write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
+-		write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
+-	} else {
+-		write_phy_reg(pi, 0xa5, afectrlOverride1_save);
+-		write_phy_reg(pi, 0x78, rfctrlcmd_save);
+-		write_phy_reg(pi, 0xec, rfctrloverride_save);
+-		write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
+-		write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
+-	}
+-
+-	return rssi_out_val;
+-}
+-
+-s16 wlc_phy_tempsense_nphy(phy_info_t *pi)
+-{
+-	u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
+-	u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
+-	u16 pwrdet_rxtx_core1_save;
+-	u16 pwrdet_rxtx_core2_save;
+-	u16 afectrlCore1_save;
+-	u16 afectrlCore2_save;
+-	u16 afectrlOverride_save;
+-	u16 afectrlOverride2_save;
+-	u16 pd_pll_ts_save;
+-	u16 gpioSel_save;
+-	s32 radio_temp[4];
+-	s32 radio_temp2[4];
+-	u16 syn_tempprocsense_save;
+-	s16 offset = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
+-		u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
+-		u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
+-		s32 auxADC_Vl;
+-		u16 RfctrlOverride5_save, RfctrlOverride6_save;
+-		u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
+-		u16 RSSIMultCoef0QPowerDet_save;
+-		u16 tempsense_Rcal;
+-
+-		syn_tempprocsense_save =
+-		    read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
+-		RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+-		RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+-		RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+-		RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					&auxADC_Vmid_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					&auxADC_Av_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					&auxADC_rssi_ctrlL_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					&auxADC_rssi_ctrlH_save);
+-
+-		write_phy_reg(pi, 0x1ae, 0x0);
+-
+-		auxADC_rssi_ctrlL = 0x0;
+-		auxADC_rssi_ctrlH = 0x20;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					 &auxADC_rssi_ctrlL);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					 &auxADC_rssi_ctrlH);
+-
+-		tempsense_Rcal = syn_tempprocsense_save & 0x1c;
+-
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x01);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+-						  1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
+-
+-		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+-		udelay(5);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
+-		mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
+-
+-		auxADC_Vmid = 0xA3;
+-		auxADC_Av = 0x0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av);
+-
+-		udelay(3);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x03);
+-
+-		udelay(5);
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-
+-		auxADC_Av = 0x7;
+-		if (radio_temp[1] + radio_temp2[1] < -30) {
+-			auxADC_Vmid = 0x45;
+-			auxADC_Vl = 263;
+-		} else if (radio_temp[1] + radio_temp2[1] < -9) {
+-			auxADC_Vmid = 0x200;
+-			auxADC_Vl = 467;
+-		} else if (radio_temp[1] + radio_temp2[1] < 11) {
+-			auxADC_Vmid = 0x266;
+-			auxADC_Vl = 634;
+-		} else {
+-			auxADC_Vmid = 0x2D5;
+-			auxADC_Vl = 816;
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av);
+-
+-		udelay(3);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x01);
+-
+-		udelay(5);
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				syn_tempprocsense_save);
+-
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-		write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
+-		write_phy_reg(pi, 0x346, RfctrlOverride5_save);
+-		write_phy_reg(pi, 0x347, RfctrlOverride6_save);
+-		write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
+-		write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					 &auxADC_rssi_ctrlL_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					 &auxADC_rssi_ctrlH_save);
+-
+-		if (pi->sh->chip == BCM5357_CHIP_ID) {
+-			radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1])
+-					 + 88 * (auxADC_Vl) - 27111 +
+-					 128) / 256;
+-		} else if (pi->sh->chip == BCM43236_CHIP_ID) {
+-			radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1])
+-					 + 91 * (auxADC_Vl) - 27243 +
+-					 128) / 256;
+-		} else {
+-			radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
+-					 + 82 * (auxADC_Vl) - 28861 +
+-					 128) / 256;
+-		}
+-
+-		offset = (s16) pi->phy_tempsense_offset;
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		syn_tempprocsense_save =
+-		    read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		gpioSel_save = read_phy_reg(pi, 0xca);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		} else {
+-			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
+-		}
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
+-		} else {
+-			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+-		}
+-
+-		radio_temp[0] =
+-		    (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
+-				syn_tempprocsense_save);
+-
+-		write_phy_reg(pi, 0xca, gpioSel_save);
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-
+-		offset = (s16) pi->phy_tempsense_offset;
+-	} else {
+-
+-		pwrdet_rxtx_core1_save =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+-		pwrdet_rxtx_core2_save =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+-		core1_txrf_iqcal1_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+-		core1_txrf_iqcal2_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+-		core2_txrf_iqcal1_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+-		core2_txrf_iqcal2_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+-		pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0xa5);
+-		gpioSel_save = read_phy_reg(pi, 0xca);
+-
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+-		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
+-		radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
+-		radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
+-		radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
+-
+-		radio_temp[0] =
+-		    (radio_temp[0] + radio_temp[1] + radio_temp[2] +
+-		     radio_temp[3]);
+-
+-		radio_temp[0] =
+-		    (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8);
+-
+-		radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
+-
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+-				pwrdet_rxtx_core1_save);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+-				pwrdet_rxtx_core2_save);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+-				core1_txrf_iqcal1_save);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+-				core2_txrf_iqcal1_save);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+-				core1_txrf_iqcal2_save);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+-				core2_txrf_iqcal2_save);
+-		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
+-
+-		write_phy_reg(pi, 0xca, gpioSel_save);
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride_save);
+-	}
+-
+-	return (s16) radio_temp[0] + offset;
+-}
+-
+-static void
+-wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf)
+-{
+-	u8 core;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (rssi_type == NPHY_RSSI_SEL_NB) {
+-			if (core == PHY_CORE_0) {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_B0_NBRSSI_VCM,
+-					      RADIO_2055_NBRSSI_VCM_I_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_NBRSSI_VCM_Q_MASK,
+-					      vcm_buf[2 * core +
+-						      1] <<
+-					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+-			} else {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_B0_NBRSSI_VCM,
+-					      RADIO_2055_NBRSSI_VCM_I_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_NBRSSI_VCM_Q_MASK,
+-					      vcm_buf[2 * core +
+-						      1] <<
+-					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+-			}
+-		} else {
+-
+-			if (core == PHY_CORE_0) {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+-			} else {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+-			}
+-		}
+-	}
+-}
+-
+-void wlc_phy_rssi_cal_nphy(phy_info_t *pi)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		wlc_phy_rssi_cal_nphy_rev3(pi);
+-	} else {
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
+-	}
+-}
+-
+-static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type)
+-{
+-	s32 target_code;
+-	u16 classif_state;
+-	u16 clip_state[2];
+-	u16 rssi_ctrl_state[2], pd_state[2];
+-	u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
+-	u16 rfctrlintc_override_val;
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-	u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
+-	u8 vcm, min_vcm, vcm_tmp[4];
+-	u8 vcm_final[4] = { 0, 0, 0, 0 };
+-	u8 result_idx, ctr;
+-	s32 poll_results[4][4] = {
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0}
+-	};
+-	s32 poll_miniq[4][2] = {
+-		{0, 0},
+-		{0, 0},
+-		{0, 0},
+-		{0, 0}
+-	};
+-	s32 min_d, curr_d;
+-	s32 fine_digital_offset[4];
+-	s32 poll_results_min[4] = { 0, 0, 0, 0 };
+-	s32 min_poll;
+-
+-	switch (rssi_type) {
+-	case NPHY_RSSI_SEL_NB:
+-		target_code = NPHY_RSSICAL_NB_TARGET;
+-		break;
+-	case NPHY_RSSI_SEL_W1:
+-		target_code = NPHY_RSSICAL_W1_TARGET;
+-		break;
+-	case NPHY_RSSI_SEL_W2:
+-		target_code = NPHY_RSSICAL_W2_TARGET;
+-		break;
+-	default:
+-		return;
+-		break;
+-	}
+-
+-	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-	wlc_phy_clip_det_nphy(pi, 0, clip_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-
+-	rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
+-	rfctrlintc_override_val =
+-	    CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
+-
+-	rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
+-	rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
+-	write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
+-
+-	rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
+-	rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
+-	write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
+-
+-	pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
+-	    RADIO_2055_WBRSSI_G2_PD;
+-	pd_state[0] =
+-	    read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
+-	pd_state[1] =
+-	    read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
+-	rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
+-	    RADIO_2055_WBRSSI_G2_SEL;
+-	rssi_ctrl_state[0] =
+-	    read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
+-	rssi_ctrl_state[1] =
+-	    read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+-
+-	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+-				       NPHY_RAIL_I, rssi_type);
+-	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+-				       NPHY_RAIL_Q, rssi_type);
+-
+-	for (vcm = 0; vcm < 4; vcm++) {
+-
+-		vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
+-		if (rssi_type != NPHY_RSSI_SEL_W2) {
+-			wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
+-		}
+-
+-		wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
+-				       NPHY_RSSICAL_NPOLL);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1)
+-		    || (rssi_type == NPHY_RSSI_SEL_W2)) {
+-			for (ctr = 0; ctr < 2; ctr++) {
+-				poll_miniq[vcm][ctr] =
+-				    min(poll_results[vcm][ctr * 2 + 0],
+-					poll_results[vcm][ctr * 2 + 1]);
+-			}
+-		}
+-	}
+-
+-	for (result_idx = 0; result_idx < 4; result_idx++) {
+-		min_d = NPHY_RSSICAL_MAXD;
+-		min_vcm = 0;
+-		min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
+-		for (vcm = 0; vcm < 4; vcm++) {
+-			curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ?
+-				      poll_results[vcm][result_idx] :
+-				      poll_miniq[vcm][result_idx / 2]) -
+-				     (target_code * NPHY_RSSICAL_NPOLL));
+-			if (curr_d < min_d) {
+-				min_d = curr_d;
+-				min_vcm = vcm;
+-			}
+-			if (poll_results[vcm][result_idx] < min_poll) {
+-				min_poll = poll_results[vcm][result_idx];
+-			}
+-		}
+-		vcm_final[result_idx] = min_vcm;
+-		poll_results_min[result_idx] = min_poll;
+-	}
+-
+-	if (rssi_type != NPHY_RSSI_SEL_W2) {
+-		wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
+-	}
+-
+-	for (result_idx = 0; result_idx < 4; result_idx++) {
+-		fine_digital_offset[result_idx] =
+-		    (target_code * NPHY_RSSICAL_NPOLL) -
+-		    poll_results[vcm_final[result_idx]][result_idx];
+-		if (fine_digital_offset[result_idx] < 0) {
+-			fine_digital_offset[result_idx] =
+-			    ABS(fine_digital_offset[result_idx]);
+-			fine_digital_offset[result_idx] +=
+-			    (NPHY_RSSICAL_NPOLL / 2);
+-			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+-			fine_digital_offset[result_idx] =
+-			    -fine_digital_offset[result_idx];
+-		} else {
+-			fine_digital_offset[result_idx] +=
+-			    (NPHY_RSSICAL_NPOLL / 2);
+-			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+-		}
+-
+-		if (poll_results_min[result_idx] ==
+-		    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+-			fine_digital_offset[result_idx] =
+-			    (target_code - NPHY_RSSICAL_MAXREAD - 1);
+-		}
+-
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-					       (s8)
+-					       fine_digital_offset[result_idx],
+-					       (result_idx / 2 ==
+-						0) ? RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       (result_idx % 2 ==
+-						0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
+-					       rssi_type);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
+-	if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_NB);
+-	} else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W1);
+-	} else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W2);
+-	} else {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W2);
+-	}
+-	if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_NB);
+-	} else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W1);
+-	} else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W2);
+-	} else {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W2);
+-	}
+-
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
+-
+-	write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
+-	write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
+-
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_state);
+-
+-	wlc_phy_resetcca_nphy(pi);
+-}
+-
+-int
+-wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh)
+-{
+-	d11rxhdr_t *rxh = &wlc_rxh->rxhdr;
+-	s16 rxpwr, rxpwr0, rxpwr1;
+-	s16 phyRx0_l, phyRx2_l;
+-
+-	rxpwr = 0;
+-	rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK;
+-	rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8;
+-
+-	if (rxpwr0 > 127)
+-		rxpwr0 -= 256;
+-	if (rxpwr1 > 127)
+-		rxpwr1 -= 256;
+-
+-	phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff;
+-	phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff;
+-	if (phyRx2_l > 127)
+-		phyRx2_l -= 256;
+-
+-	if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
+-		rxpwr0 = rxpwr1;
+-		rxpwr1 = phyRx2_l;
+-	}
+-
+-	wlc_rxh->rxpwr[0] = (s8) rxpwr0;
+-	wlc_rxh->rxpwr[1] = (s8) rxpwr1;
+-	wlc_rxh->do_rssi_ma = 0;
+-
+-	if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
+-		rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
+-	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
+-		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
+-	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
+-		rxpwr = (rxpwr0 + rxpwr1) >> 1;
+-
+-	return rxpwr;
+-}
+-
+-static void
+-wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value,
+-				 u8 core_code)
+-{
+-	u16 mask;
+-	u16 val;
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			if (core_code == RADIO_MIMO_CORESEL_CORE1
+-			    && core == PHY_CORE_1)
+-				continue;
+-			else if (core_code == RADIO_MIMO_CORESEL_CORE2
+-				 && core == PHY_CORE_0)
+-				continue;
+-
+-			if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-				mask = (0x1 << 10);
+-				val = 1 << 10;
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+-					    0x92, mask, val);
+-			}
+-
+-			if (field == NPHY_RfctrlIntc_override_OFF) {
+-
+-				write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+-					      0x92, 0);
+-
+-				wlc_phy_force_rfseq_nphy(pi,
+-							 NPHY_RFSEQ_RESET2RX);
+-			} else if (field == NPHY_RfctrlIntc_override_TRSW) {
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-					mask = (0x1 << 6) | (0x1 << 7);
+-
+-					val = value << 6;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					or_phy_reg(pi,
+-						   (core ==
+-						    PHY_CORE_0) ? 0x91 : 0x92,
+-						   (0x1 << 10));
+-
+-					and_phy_reg(pi, 0x2ff, (u16)
+-						    ~(0x3 << 14));
+-					or_phy_reg(pi, 0x2ff, (0x1 << 13));
+-					or_phy_reg(pi, 0x2ff, (0x1 << 0));
+-				} else {
+-
+-					mask = (0x1 << 6) |
+-					    (0x1 << 7) |
+-					    (0x1 << 8) | (0x1 << 9);
+-					val = value << 6;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					mask = (0x1 << 0);
+-					val = 1 << 0;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xe7 : 0xec,
+-						    mask, val);
+-
+-					mask = (core == PHY_CORE_0) ? (0x1 << 0)
+-					    : (0x1 << 1);
+-					val = 1 << ((core == PHY_CORE_0) ?
+-						    0 : 1);
+-					mod_phy_reg(pi, 0x78, mask, val);
+-
+-					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
+-						  != 0), 10000);
+-					if (WARN(read_phy_reg(pi, 0x78) & val,
+-						"HW error: override failed"))
+-						return;
+-
+-					mask = (0x1 << 0);
+-					val = 0 << 0;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xe7 : 0xec,
+-						    mask, val);
+-				}
+-			} else if (field == NPHY_RfctrlIntc_override_PA) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-					mask = (0x1 << 4) | (0x1 << 5);
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						val = value << 5;
+-					} else {
+-						val = value << 4;
+-					}
+-
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					or_phy_reg(pi,
+-						   (core ==
+-						    PHY_CORE_0) ? 0x91 : 0x92,
+-						   (0x1 << 12));
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 5);
+-						val = value << 5;
+-					} else {
+-						mask = (0x1 << 4);
+-						val = value << 4;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			} else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-						mask = (0x1 << 0);
+-						val = value << 0;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 2);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					} else {
+-
+-						mask = (0x1 << 2);
+-						val = value << 2;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 0);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					}
+-
+-					mask = (0x1 << 11);
+-					val = 1 << 11;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 0);
+-						val = value << 0;
+-					} else {
+-						mask = (0x1 << 2);
+-						val = value << 2;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			} else if (field ==
+-				   NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-						mask = (0x1 << 1);
+-						val = value << 1;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 3);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					} else {
+-
+-						mask = (0x1 << 3);
+-						val = value << 3;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 1);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					}
+-
+-					mask = (0x1 << 11);
+-					val = 1 << 11;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 1);
+-						val = value << 1;
+-					} else {
+-						mask = (0x1 << 3);
+-						val = value << 3;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			}
+-		}
+-	} else {
+-		return;
+-	}
+-}
+-
+-static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi)
+-{
+-	u16 classif_state;
+-	u16 clip_state[2];
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-	s32 target_code;
+-	u8 vcm, min_vcm;
+-	u8 vcm_final = 0;
+-	u8 result_idx;
+-	s32 poll_results[8][4] = {
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0}
+-	};
+-	s32 poll_result_core[4] = { 0, 0, 0, 0 };
+-	s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
+-	s32 fine_digital_offset[4];
+-	s32 poll_results_min[4] = { 0, 0, 0, 0 };
+-	s32 min_poll;
+-	u8 vcm_level_max;
+-	u8 core;
+-	u8 wb_cnt;
+-	u8 rssi_type;
+-	u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
+-	u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
+-	u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
+-	u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
+-	u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
+-	u16 NPHY_RfctrlCmd_save;
+-	u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
+-	u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
+-	u8 rxcore_state;
+-	u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
+-	u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
+-	u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
+-	u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
+-
+-	NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save =
+-	    NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save =
+-	    NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save =
+-	    NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0;
+-
+-	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-	wlc_phy_clip_det_nphy(pi, 0, clip_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-
+-	NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
+-	NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
+-	NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
+-	NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-	NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
+-	NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
+-	NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
+-	NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
+-		NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
+-		NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+-		NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+-	}
+-	NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+-	NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+-	NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
+-	NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+-	NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
+-		NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
+-		NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+-		NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+-	}
+-	NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
+-	NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
+-
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
+-					 RADIO_MIMO_CORESEL_ALLRXTX);
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
+-					 RADIO_MIMO_CORESEL_ALLRXTX);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
+-						     0, 0, 0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rx_pu,
+-						     1, 0, 0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-						  1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
+-	}
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0,
+-							  0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
+-		}
+-
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0,
+-							  0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
+-		}
+-	}
+-
+-	rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+-
+-	vcm_level_max = 8;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((rxcore_state & (1 << core)) == 0)
+-			continue;
+-
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-					       core ==
+-					       PHY_CORE_0 ?
+-					       RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-					       core ==
+-					       PHY_CORE_0 ?
+-					       RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
+-
+-		for (vcm = 0; vcm < vcm_level_max; vcm++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-				mod_radio_reg(pi, (core == PHY_CORE_0) ?
+-					      RADIO_2057_NB_MASTER_CORE0 :
+-					      RADIO_2057_NB_MASTER_CORE1,
+-					      RADIO_2057_VCM_MASK, vcm);
+-			} else {
+-
+-				mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+-					      ((core ==
+-						PHY_CORE_0) ? RADIO_2056_RX0 :
+-					       RADIO_2056_RX1),
+-					      RADIO_2056_VCM_MASK,
+-					      vcm << RADIO_2056_RSSI_VCM_SHIFT);
+-			}
+-
+-			wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
+-					       &poll_results[vcm][0],
+-					       NPHY_RSSICAL_NPOLL);
+-		}
+-
+-		for (result_idx = 0; result_idx < 4; result_idx++) {
+-			if ((core == result_idx / 2) && (result_idx % 2 == 0)) {
+-
+-				min_d = NPHY_RSSICAL_MAXD;
+-				min_vcm = 0;
+-				min_poll =
+-				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL +
+-				    1;
+-				for (vcm = 0; vcm < vcm_level_max; vcm++) {
+-					curr_d = poll_results[vcm][result_idx] *
+-					    poll_results[vcm][result_idx] +
+-					    poll_results[vcm][result_idx + 1] *
+-					    poll_results[vcm][result_idx + 1];
+-					if (curr_d < min_d) {
+-						min_d = curr_d;
+-						min_vcm = vcm;
+-					}
+-					if (poll_results[vcm][result_idx] <
+-					    min_poll) {
+-						min_poll =
+-						    poll_results[vcm]
+-						    [result_idx];
+-					}
+-				}
+-				vcm_final = min_vcm;
+-				poll_results_min[result_idx] = min_poll;
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, (core == PHY_CORE_0) ?
+-				      RADIO_2057_NB_MASTER_CORE0 :
+-				      RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK, vcm_final);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+-				      ((core ==
+-					PHY_CORE_0) ? RADIO_2056_RX0 :
+-				       RADIO_2056_RX1), RADIO_2056_VCM_MASK,
+-				      vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
+-		}
+-
+-		for (result_idx = 0; result_idx < 4; result_idx++) {
+-			if (core == result_idx / 2) {
+-				fine_digital_offset[result_idx] =
+-				    (NPHY_RSSICAL_NB_TARGET *
+-				     NPHY_RSSICAL_NPOLL) -
+-				    poll_results[vcm_final][result_idx];
+-				if (fine_digital_offset[result_idx] < 0) {
+-					fine_digital_offset[result_idx] =
+-					    ABS(fine_digital_offset
+-						[result_idx]);
+-					fine_digital_offset[result_idx] +=
+-					    (NPHY_RSSICAL_NPOLL / 2);
+-					fine_digital_offset[result_idx] /=
+-					    NPHY_RSSICAL_NPOLL;
+-					fine_digital_offset[result_idx] =
+-					    -fine_digital_offset[result_idx];
+-				} else {
+-					fine_digital_offset[result_idx] +=
+-					    (NPHY_RSSICAL_NPOLL / 2);
+-					fine_digital_offset[result_idx] /=
+-					    NPHY_RSSICAL_NPOLL;
+-				}
+-
+-				if (poll_results_min[result_idx] ==
+-				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+-					fine_digital_offset[result_idx] =
+-					    (NPHY_RSSICAL_NB_TARGET -
+-					     NPHY_RSSICAL_MAXREAD - 1);
+-				}
+-
+-				wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-							       (s8)
+-							       fine_digital_offset
+-							       [result_idx],
+-							       (result_idx /
+-								2 ==
+-								0) ?
+-							       RADIO_MIMO_CORESEL_CORE1
+-							       :
+-							       RADIO_MIMO_CORESEL_CORE2,
+-							       (result_idx %
+-								2 ==
+-								0) ? NPHY_RAIL_I
+-							       : NPHY_RAIL_Q,
+-							       NPHY_RSSI_SEL_NB);
+-			}
+-		}
+-
+-	}
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((rxcore_state & (1 << core)) == 0)
+-			continue;
+-
+-		for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
+-			if (wb_cnt == 0) {
+-				rssi_type = NPHY_RSSI_SEL_W1;
+-				target_code = NPHY_RSSICAL_W1_TARGET_REV3;
+-			} else {
+-				rssi_type = NPHY_RSSI_SEL_W2;
+-				target_code = NPHY_RSSICAL_W2_TARGET_REV3;
+-			}
+-
+-			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-						       core ==
+-						       PHY_CORE_0 ?
+-						       RADIO_MIMO_CORESEL_CORE1
+-						       :
+-						       RADIO_MIMO_CORESEL_CORE2,
+-						       NPHY_RAIL_I, rssi_type);
+-			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-						       core ==
+-						       PHY_CORE_0 ?
+-						       RADIO_MIMO_CORESEL_CORE1
+-						       :
+-						       RADIO_MIMO_CORESEL_CORE2,
+-						       NPHY_RAIL_Q, rssi_type);
+-
+-			wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
+-					       NPHY_RSSICAL_NPOLL);
+-
+-			for (result_idx = 0; result_idx < 4; result_idx++) {
+-				if (core == result_idx / 2) {
+-					fine_digital_offset[result_idx] =
+-					    (target_code * NPHY_RSSICAL_NPOLL) -
+-					    poll_result_core[result_idx];
+-					if (fine_digital_offset[result_idx] < 0) {
+-						fine_digital_offset[result_idx]
+-						    =
+-						    ABS(fine_digital_offset
+-							[result_idx]);
+-						fine_digital_offset[result_idx]
+-						    += (NPHY_RSSICAL_NPOLL / 2);
+-						fine_digital_offset[result_idx]
+-						    /= NPHY_RSSICAL_NPOLL;
+-						fine_digital_offset[result_idx]
+-						    =
+-						    -fine_digital_offset
+-						    [result_idx];
+-					} else {
+-						fine_digital_offset[result_idx]
+-						    += (NPHY_RSSICAL_NPOLL / 2);
+-						fine_digital_offset[result_idx]
+-						    /= NPHY_RSSICAL_NPOLL;
+-					}
+-
+-					wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-								       (s8)
+-								       fine_digital_offset
+-								       [core *
+-									2],
+-								       (core ==
+-									PHY_CORE_0)
+-								       ?
+-								       RADIO_MIMO_CORESEL_CORE1
+-								       :
+-								       RADIO_MIMO_CORESEL_CORE2,
+-								       (result_idx
+-									% 2 ==
+-									0) ?
+-								       NPHY_RAIL_I
+-								       :
+-								       NPHY_RAIL_Q,
+-								       rssi_type);
+-				}
+-			}
+-
+-		}
+-	}
+-
+-	write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
+-	write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
+-
+-	mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
+-	mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+-
+-	write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
+-	write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
+-	write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
+-	write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
+-	write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
+-	write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
+-		write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
+-		write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
+-		write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
+-	}
+-	write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
+-	write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
+-	write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
+-	write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
+-	write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
+-		write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
+-		write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
+-		write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
+-	}
+-	write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
+-	write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			pi->rssical_cache.rssical_radio_regs_2G[0] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+-			pi->rssical_cache.rssical_radio_regs_2G[1] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+-		} else {
+-			pi->rssical_cache.rssical_radio_regs_2G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX0);
+-			pi->rssical_cache.rssical_radio_regs_2G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX1);
+-		}
+-
+-		pi->rssical_cache.rssical_phyregs_2G[0] =
+-		    read_phy_reg(pi, 0x1a6);
+-		pi->rssical_cache.rssical_phyregs_2G[1] =
+-		    read_phy_reg(pi, 0x1ac);
+-		pi->rssical_cache.rssical_phyregs_2G[2] =
+-		    read_phy_reg(pi, 0x1b2);
+-		pi->rssical_cache.rssical_phyregs_2G[3] =
+-		    read_phy_reg(pi, 0x1b8);
+-		pi->rssical_cache.rssical_phyregs_2G[4] =
+-		    read_phy_reg(pi, 0x1a4);
+-		pi->rssical_cache.rssical_phyregs_2G[5] =
+-		    read_phy_reg(pi, 0x1aa);
+-		pi->rssical_cache.rssical_phyregs_2G[6] =
+-		    read_phy_reg(pi, 0x1b0);
+-		pi->rssical_cache.rssical_phyregs_2G[7] =
+-		    read_phy_reg(pi, 0x1b6);
+-		pi->rssical_cache.rssical_phyregs_2G[8] =
+-		    read_phy_reg(pi, 0x1a5);
+-		pi->rssical_cache.rssical_phyregs_2G[9] =
+-		    read_phy_reg(pi, 0x1ab);
+-		pi->rssical_cache.rssical_phyregs_2G[10] =
+-		    read_phy_reg(pi, 0x1b1);
+-		pi->rssical_cache.rssical_phyregs_2G[11] =
+-		    read_phy_reg(pi, 0x1b7);
+-
+-		pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			pi->rssical_cache.rssical_radio_regs_5G[0] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+-			pi->rssical_cache.rssical_radio_regs_5G[1] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+-		} else {
+-			pi->rssical_cache.rssical_radio_regs_5G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX0);
+-			pi->rssical_cache.rssical_radio_regs_5G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX1);
+-		}
+-
+-		pi->rssical_cache.rssical_phyregs_5G[0] =
+-		    read_phy_reg(pi, 0x1a6);
+-		pi->rssical_cache.rssical_phyregs_5G[1] =
+-		    read_phy_reg(pi, 0x1ac);
+-		pi->rssical_cache.rssical_phyregs_5G[2] =
+-		    read_phy_reg(pi, 0x1b2);
+-		pi->rssical_cache.rssical_phyregs_5G[3] =
+-		    read_phy_reg(pi, 0x1b8);
+-		pi->rssical_cache.rssical_phyregs_5G[4] =
+-		    read_phy_reg(pi, 0x1a4);
+-		pi->rssical_cache.rssical_phyregs_5G[5] =
+-		    read_phy_reg(pi, 0x1aa);
+-		pi->rssical_cache.rssical_phyregs_5G[6] =
+-		    read_phy_reg(pi, 0x1b0);
+-		pi->rssical_cache.rssical_phyregs_5G[7] =
+-		    read_phy_reg(pi, 0x1b6);
+-		pi->rssical_cache.rssical_phyregs_5G[8] =
+-		    read_phy_reg(pi, 0x1a5);
+-		pi->rssical_cache.rssical_phyregs_5G[9] =
+-		    read_phy_reg(pi, 0x1ab);
+-		pi->rssical_cache.rssical_phyregs_5G[10] =
+-		    read_phy_reg(pi, 0x1b1);
+-		pi->rssical_cache.rssical_phyregs_5G[11] =
+-		    read_phy_reg(pi, 0x1b7);
+-
+-		pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
+-	}
+-
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_state);
+-}
+-
+-static void wlc_phy_restore_rssical_nphy(phy_info_t *pi)
+-{
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->nphy_rssical_chanspec_2G == 0)
+-			return;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[0]);
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[1]);
+-		} else {
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[0]);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[1]);
+-		}
+-
+-		write_phy_reg(pi, 0x1a6,
+-			      pi->rssical_cache.rssical_phyregs_2G[0]);
+-		write_phy_reg(pi, 0x1ac,
+-			      pi->rssical_cache.rssical_phyregs_2G[1]);
+-		write_phy_reg(pi, 0x1b2,
+-			      pi->rssical_cache.rssical_phyregs_2G[2]);
+-		write_phy_reg(pi, 0x1b8,
+-			      pi->rssical_cache.rssical_phyregs_2G[3]);
+-		write_phy_reg(pi, 0x1a4,
+-			      pi->rssical_cache.rssical_phyregs_2G[4]);
+-		write_phy_reg(pi, 0x1aa,
+-			      pi->rssical_cache.rssical_phyregs_2G[5]);
+-		write_phy_reg(pi, 0x1b0,
+-			      pi->rssical_cache.rssical_phyregs_2G[6]);
+-		write_phy_reg(pi, 0x1b6,
+-			      pi->rssical_cache.rssical_phyregs_2G[7]);
+-		write_phy_reg(pi, 0x1a5,
+-			      pi->rssical_cache.rssical_phyregs_2G[8]);
+-		write_phy_reg(pi, 0x1ab,
+-			      pi->rssical_cache.rssical_phyregs_2G[9]);
+-		write_phy_reg(pi, 0x1b1,
+-			      pi->rssical_cache.rssical_phyregs_2G[10]);
+-		write_phy_reg(pi, 0x1b7,
+-			      pi->rssical_cache.rssical_phyregs_2G[11]);
+-
+-	} else {
+-		if (pi->nphy_rssical_chanspec_5G == 0)
+-			return;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[0]);
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[1]);
+-		} else {
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[0]);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[1]);
+-		}
+-
+-		write_phy_reg(pi, 0x1a6,
+-			      pi->rssical_cache.rssical_phyregs_5G[0]);
+-		write_phy_reg(pi, 0x1ac,
+-			      pi->rssical_cache.rssical_phyregs_5G[1]);
+-		write_phy_reg(pi, 0x1b2,
+-			      pi->rssical_cache.rssical_phyregs_5G[2]);
+-		write_phy_reg(pi, 0x1b8,
+-			      pi->rssical_cache.rssical_phyregs_5G[3]);
+-		write_phy_reg(pi, 0x1a4,
+-			      pi->rssical_cache.rssical_phyregs_5G[4]);
+-		write_phy_reg(pi, 0x1aa,
+-			      pi->rssical_cache.rssical_phyregs_5G[5]);
+-		write_phy_reg(pi, 0x1b0,
+-			      pi->rssical_cache.rssical_phyregs_5G[6]);
+-		write_phy_reg(pi, 0x1b6,
+-			      pi->rssical_cache.rssical_phyregs_5G[7]);
+-		write_phy_reg(pi, 0x1a5,
+-			      pi->rssical_cache.rssical_phyregs_5G[8]);
+-		write_phy_reg(pi, 0x1ab,
+-			      pi->rssical_cache.rssical_phyregs_5G[9]);
+-		write_phy_reg(pi, 0x1b1,
+-			      pi->rssical_cache.rssical_phyregs_5G[10]);
+-		write_phy_reg(pi, 0x1b7,
+-			      pi->rssical_cache.rssical_phyregs_5G[11]);
+-	}
+-}
+-
+-static u16
+-wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-			      u8 dac_test_mode)
+-{
+-	u8 phy_bw, is_phybw40;
+-	u16 num_samps, t, spur;
+-	fixed theta = 0, rot = 0;
+-	u32 tbl_len;
+-	cs32 *tone_buf = NULL;
+-
+-	is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-	phy_bw = (is_phybw40 == 1) ? 40 : 20;
+-	tbl_len = (phy_bw << 3);
+-
+-	if (dac_test_mode == 1) {
+-		spur = read_phy_reg(pi, 0x01);
+-		spur = (spur >> 15) & 1;
+-		phy_bw = (spur == 1) ? 82 : 80;
+-		phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
+-
+-		tbl_len = (phy_bw << 1);
+-	}
+-
+-	tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC);
+-	if (tone_buf == NULL) {
+-		return 0;
+-	}
+-
+-	num_samps = (u16) tbl_len;
+-	rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+-	theta = 0;
+-
+-	for (t = 0; t < num_samps; t++) {
+-
+-		wlc_phy_cordic(theta, &tone_buf[t]);
+-
+-		theta += rot;
+-
+-		tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
+-		tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
+-	}
+-
+-	wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
+-
+-	kfree(tone_buf);
+-
+-	return num_samps;
+-}
+-
+-int
+-wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-		     u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
+-{
+-	u16 num_samps;
+-	u16 loops = 0xffff;
+-	u16 wait = 0;
+-
+-	num_samps =
+-		wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode);
+-	if (num_samps == 0) {
+-		return -EBADE;
+-	}
+-
+-	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
+-				dac_test_mode, modify_bbmult);
+-
+-	return 0;
+-}
+-
+-static void
+-wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf,
+-			     u16 num_samps)
+-{
+-	u16 t;
+-	u32 *data_buf = NULL;
+-
+-	data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
+-	if (data_buf == NULL) {
+-		return;
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	for (t = 0; t < num_samps; t++) {
+-		data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
+-		    (((unsigned int)tone_buf[t].q) & 0x3ff);
+-	}
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
+-				 data_buf);
+-
+-	kfree(data_buf);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void
+-wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops,
+-			u16 wait, u8 iqmode, u8 dac_test_mode,
+-			bool modify_bbmult)
+-{
+-	u16 bb_mult;
+-	u8 phy_bw, sample_cmd;
+-	u16 orig_RfseqCoreActv;
+-	u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
+-	    lpf_bw_ctl_miscreg4;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	phy_bw = 20;
+-	if (CHSPEC_IS40(pi->radio_chanspec))
+-		phy_bw = 40;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
+-		lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
+-		if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
+-			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+-			    (0x7 << 8);
+-			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+-			    (0x7 << 8);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-			pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
+-
+-			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+-			    (0x7 << 8);
+-			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+-			    (0x7 << 8);
+-		}
+-	}
+-
+-	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					&bb_mult);
+-		pi->nphy_bb_mult_save =
+-		    BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
+-	}
+-
+-	if (modify_bbmult) {
+-		bb_mult = (phy_bw == 20) ? 100 : 71;
+-		bb_mult = (bb_mult << 8) + bb_mult;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					 &bb_mult);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	write_phy_reg(pi, 0xc6, num_samps - 1);
+-
+-	if (loops != 0xffff) {
+-		write_phy_reg(pi, 0xc4, loops - 1);
+-	} else {
+-		write_phy_reg(pi, 0xc4, loops);
+-	}
+-	write_phy_reg(pi, 0xc5, wait);
+-
+-	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+-	or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+-	if (iqmode) {
+-
+-		and_phy_reg(pi, 0xc2, 0x7FFF);
+-
+-		or_phy_reg(pi, 0xc2, 0x8000);
+-	} else {
+-
+-		sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
+-		write_phy_reg(pi, 0xc3, sample_cmd);
+-	}
+-
+-	SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
+-
+-	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+-}
+-
+-void wlc_phy_stopplayback_nphy(phy_info_t *pi)
+-{
+-	u16 playback_status;
+-	u16 bb_mult;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	playback_status = read_phy_reg(pi, 0xc7);
+-	if (playback_status & 0x1) {
+-		or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
+-	} else if (playback_status & 0x2) {
+-
+-		and_phy_reg(pi, 0xc2,
+-			    (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
+-	}
+-
+-	and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
+-
+-	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
+-
+-		bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					 &bb_mult);
+-
+-		pi->nphy_bb_mult_save = 0;
+-	}
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-		if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  0, 0, 1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
+-		}
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi)
+-{
+-	u16 base_idx[2], curr_gain[2];
+-	u8 core_no;
+-	nphy_txgains_t target_gain;
+-	u32 *tx_pwrctrl_tbl = NULL;
+-
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-					curr_gain);
+-
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-		for (core_no = 0; core_no < 2; core_no++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x0007;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x00F8) >> 3);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0F00) >> 8);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x7000) >> 12);
+-				target_gain.txlpf[core_no] =
+-				    ((curr_gain[core_no] & 0x8000) >> 15);
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x000F;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x00F0) >> 4);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0F00) >> 8);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x7000) >> 12);
+-			} else {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x0003;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x000C) >> 2);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0070) >> 4);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x0380) >> 7);
+-			}
+-		}
+-	} else {
+-		base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
+-		base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
+-		for (core_no = 0; core_no < 2; core_no++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				if (PHY_IPA(pi)) {
+-					tx_pwrctrl_tbl =
+-					    wlc_phy_get_ipa_gaintbl_nphy(pi);
+-				} else {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						if NREV_IS
+-							(pi->pubpi.phy_rev, 3) {
+-							tx_pwrctrl_tbl =
+-							    nphy_tpc_5GHz_txgain_rev3;
+-						} else if NREV_IS
+-							(pi->pubpi.phy_rev, 4) {
+-							tx_pwrctrl_tbl =
+-							    (pi->srom_fem5g.
+-							     extpagain ==
+-							     3) ?
+-							    nphy_tpc_5GHz_txgain_HiPwrEPA
+-							    :
+-							    nphy_tpc_5GHz_txgain_rev4;
+-						} else {
+-							tx_pwrctrl_tbl =
+-							    nphy_tpc_5GHz_txgain_rev5;
+-						}
+-					} else {
+-						if (NREV_GE
+-						    (pi->pubpi.phy_rev, 7)) {
+-							if (pi->pubpi.
+-							    radiorev == 3) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_epa_2057rev3;
+-							} else if (pi->pubpi.
+-								   radiorev ==
+-								   5) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_epa_2057rev5;
+-							}
+-
+-						} else {
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     5)
+-							    && (pi->srom_fem2g.
+-								extpagain ==
+-								3)) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_HiPwrEPA;
+-							} else {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_rev3;
+-							}
+-						}
+-					}
+-				}
+-				if NREV_GE
+-					(pi->pubpi.phy_rev, 7) {
+-					target_gain.ipa[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 16) & 0x7;
+-					target_gain.pad[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 19) & 0x1f;
+-					target_gain.pga[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 24) & 0xf;
+-					target_gain.txgm[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 28) & 0x7;
+-					target_gain.txlpf[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 31) & 0x1;
+-				} else {
+-					target_gain.ipa[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 16) & 0xf;
+-					target_gain.pad[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 20) & 0xf;
+-					target_gain.pga[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 24) & 0xf;
+-					target_gain.txgm[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 28) & 0x7;
+-				}
+-			} else {
+-				target_gain.ipa[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 16) &
+-				    0x3;
+-				target_gain.pad[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 18) &
+-				    0x3;
+-				target_gain.pga[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 20) &
+-				    0x7;
+-				target_gain.txgm[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 23) &
+-				    0x7;
+-			}
+-		}
+-	}
+-
+-	return target_gain;
+-}
+-
+-static void
+-wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no,
+-			      nphy_txgains_t target_gain,
+-			      nphy_iqcal_params_t *params)
+-{
+-	u8 k;
+-	int idx;
+-	u16 gain_index;
+-	u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			params->txlpf = target_gain.txlpf[core_no];
+-		}
+-		params->txgm = target_gain.txgm[core_no];
+-		params->pga = target_gain.pga[core_no];
+-		params->pad = target_gain.pad[core_no];
+-		params->ipa = target_gain.ipa[core_no];
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			params->cal_gain =
+-			    ((params->txlpf << 15) | (params->
+-						      txgm << 12) | (params->
+-								     pga << 8) |
+-			     (params->pad << 3) | (params->ipa));
+-		} else {
+-			params->cal_gain =
+-			    ((params->txgm << 12) | (params->
+-						     pga << 8) | (params->
+-								  pad << 4) |
+-			     (params->ipa));
+-		}
+-		params->ncorr[0] = 0x79;
+-		params->ncorr[1] = 0x79;
+-		params->ncorr[2] = 0x79;
+-		params->ncorr[3] = 0x79;
+-		params->ncorr[4] = 0x79;
+-	} else {
+-
+-		gain_index = ((target_gain.pad[core_no] << 0) |
+-			      (target_gain.pga[core_no] << 4) | (target_gain.
+-								 txgm[core_no]
+-								 << 8));
+-
+-		idx = -1;
+-		for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
+-			if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
+-			    gain_index) {
+-				idx = k;
+-				break;
+-			}
+-		}
+-
+-		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
+-		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
+-		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
+-		params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
+-				    (params->pad << 2));
+-		params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
+-		params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
+-		params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
+-		params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
+-	}
+-}
+-
+-static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi)
+-{
+-	u16 jtag_core, core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		for (core = 0; core <= 1; core++) {
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TX_SSI_MASTER);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    IQCAL_VCM_HG);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    IQCAL_IDAC);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TX_SSI_MUX);
+-
+-			if (pi->pubpi.radiorev != 5)
+-				pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+-				    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						    TSSIA);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TSSI_MISC1);
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x0a);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_VCM_HG, 0x43);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_IDAC, 0x55);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_VCM, 0x00);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIG, 0x00);
+-				if (pi->use_int_tx_iqlo_cal_nphy) {
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TX_SSI_MUX, 0x4);
+-					if (!
+-					    (pi->
+-					     internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x31);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x21);
+-					}
+-				}
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_MISC1, 0x00);
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x06);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_VCM_HG, 0x43);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_IDAC, 0x55);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_VCM, 0x00);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIA, 0x00);
+-				if (pi->use_int_tx_iqlo_cal_nphy) {
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TX_SSI_MUX,
+-							 0x06);
+-					if (!
+-					    (pi->
+-					     internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIG, 0x31);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIG, 0x21);
+-					}
+-				}
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_MISC1, 0x00);
+-			}
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		for (core = 0; core <= 1; core++) {
+-			jtag_core =
+-			    (core ==
+-			     PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_SSI_MASTER |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_IQCAL_VCM_HG |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_IQCAL_IDAC |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_VCM | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_AMP_DET |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_SSI_MUX |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+-			    read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+-			    read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC1 |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC2 |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC3 |
+-					   jtag_core);
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MASTER |
+-						jtag_core, 0x0a);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_VCM_HG |
+-						jtag_core, 0x40);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_IDAC |
+-						jtag_core, 0x55);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_VCM |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_AMP_DET |
+-						jtag_core, 0x00);
+-
+-				if (PHY_IPA(pi)) {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x4);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIA |
+-							jtag_core, 0x1);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x00);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIA |
+-							jtag_core, 0x2f);
+-				}
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSIG | jtag_core,
+-						0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC1 |
+-						jtag_core, 0x00);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC2 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC3 |
+-						jtag_core, 0x00);
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MASTER |
+-						jtag_core, 0x06);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_VCM_HG |
+-						jtag_core, 0x40);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_IDAC |
+-						jtag_core, 0x55);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_VCM |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_AMP_DET |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSIA | jtag_core,
+-						0x00);
+-
+-				if (PHY_IPA(pi)) {
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x06);
+-					if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-
+-						write_radio_reg(pi,
+-								RADIO_2056_TX_TSSIG
+-								| jtag_core,
+-								0x11);
+-					} else {
+-
+-						write_radio_reg(pi,
+-								RADIO_2056_TX_TSSIG
+-								| jtag_core,
+-								0x1);
+-					}
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x00);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIG |
+-							jtag_core, 0x20);
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC1 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC2 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC3 |
+-						jtag_core, 0x00);
+-			}
+-		}
+-	} else {
+-
+-		pi->tx_rx_cal_radio_saveregs[0] =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
+-		pi->tx_rx_cal_radio_saveregs[1] =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
+-
+-		pi->tx_rx_cal_radio_saveregs[2] =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
+-		pi->tx_rx_cal_radio_saveregs[3] =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
+-
+-		pi->tx_rx_cal_radio_saveregs[4] =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+-		pi->tx_rx_cal_radio_saveregs[5] =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+-
+-		if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
+-		    0) {
+-
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+-		} else {
+-
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-			or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
+-			or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
+-		} else {
+-
+-			and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
+-			and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi)
+-{
+-	u16 jtag_core, core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (core = 0; core <= 1; core++) {
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TX_SSI_MASTER,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  0]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  1]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  2]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  3]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  5]);
+-
+-			if (pi->pubpi.radiorev != 5)
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIA,
+-						 pi->
+-						 tx_rx_cal_radio_saveregs[(core
+-									   *
+-									   11) +
+-									  6]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  7]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  8]);
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (core = 0; core <= 1; core++) {
+-			jtag_core =
+-			    (core ==
+-			     PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 1]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_IQCAL_IDAC | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 2]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_AMP_DET | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 4]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_SSI_MUX | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 5]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 6]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 7]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC1 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 8]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC2 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 9]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC3 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 10]);
+-		}
+-	} else {
+-
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+-				pi->tx_rx_cal_radio_saveregs[0]);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+-				pi->tx_rx_cal_radio_saveregs[1]);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+-				pi->tx_rx_cal_radio_saveregs[2]);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+-				pi->tx_rx_cal_radio_saveregs[3]);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+-				pi->tx_rx_cal_radio_saveregs[4]);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+-				pi->tx_rx_cal_radio_saveregs[5]);
+-	}
+-}
+-
+-static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi)
+-{
+-	u16 val, mask;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+-		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+-
+-		mask = ((0x3 << 8) | (0x3 << 10));
+-		val = (0x2 << 8);
+-		val |= (0x2 << 10);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		val = read_phy_reg(pi, 0x8f);
+-		pi->tx_rx_cal_phy_saveregs[2] = val;
+-		val |= ((0x1 << 9) | (0x1 << 10));
+-		write_phy_reg(pi, 0x8f, val);
+-
+-		val = read_phy_reg(pi, 0xa5);
+-		pi->tx_rx_cal_phy_saveregs[3] = val;
+-		val |= ((0x1 << 9) | (0x1 << 10));
+-		write_phy_reg(pi, 0xa5, val);
+-
+-		pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
+-		mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[5] = val;
+-		val = 0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					 &val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[6] = val;
+-		val = 0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					 &val);
+-
+-		pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
+-		pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
+-
+-		if (!(pi->use_int_tx_iqlo_cal_nphy)) {
+-
+-			wlc_phy_rfctrlintc_override_nphy(pi,
+-							 NPHY_RfctrlIntc_override_PA,
+-							 1,
+-							 RADIO_MIMO_CORESEL_CORE1
+-							 |
+-							 RADIO_MIMO_CORESEL_CORE2);
+-		} else {
+-
+-			wlc_phy_rfctrlintc_override_nphy(pi,
+-							 NPHY_RfctrlIntc_override_PA,
+-							 0,
+-							 RADIO_MIMO_CORESEL_CORE1
+-							 |
+-							 RADIO_MIMO_CORESEL_CORE2);
+-		}
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x2, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x8, RADIO_MIMO_CORESEL_CORE2);
+-
+-		pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+-		pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		if (pi->use_int_tx_iqlo_cal_nphy
+-		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+-					      1 << 4);
+-
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-						      1, 0);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-						      1, 0);
+-				} else {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+-						      1, 0);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+-						      1, 0);
+-				}
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-				wlc_phy_rfctrl_override_nphy_rev7(pi,
+-								  (0x1 << 3), 0,
+-								  0x3, 0,
+-								  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			}
+-		}
+-	} else {
+-		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+-		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+-
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		val = (0x2 << 12);
+-		val |= (0x2 << 14);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		val = read_phy_reg(pi, 0xa5);
+-		pi->tx_rx_cal_phy_saveregs[2] = val;
+-		val |= ((0x1 << 12) | (0x1 << 13));
+-		write_phy_reg(pi, 0xa5, val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[3] = val;
+-		val |= 0x2000;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					 &val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[4] = val;
+-		val |= 0x2000;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					 &val);
+-
+-		pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
+-		pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
+-		val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+-		write_phy_reg(pi, 0x91, val);
+-		write_phy_reg(pi, 0x92, val);
+-	}
+-}
+-
+-static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi)
+-{
+-	u16 mask;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
+-		write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
+-		write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
+-		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
+-		write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[5]);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[6]);
+-
+-		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
+-		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
+-
+-		write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+-		write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+-							  1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-		if (pi->use_int_tx_iqlo_cal_nphy
+-		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-						      1, 1);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-						      1, 1);
+-				} else {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+-						      1, 1);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+-						      1, 1);
+-				}
+-
+-				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+-					      0);
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-				wlc_phy_rfctrl_override_nphy_rev7(pi,
+-								  (0x1 << 3), 0,
+-								  0x3, 1,
+-								  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			}
+-		}
+-	} else {
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
+-		mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
+-		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[3]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[4]);
+-
+-		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
+-		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
+-	}
+-}
+-
+-#define NPHY_CAL_TSSISAMPS	64
+-#define NPHY_TEST_TONE_FREQ_40MHz 4000
+-#define NPHY_TEST_TONE_FREQ_20MHz 2500
+-
+-void
+-wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps)
+-{
+-	u16 tssi_reg;
+-	s32 temp, pwrindex[2];
+-	s32 idle_tssi[2];
+-	s32 rssi_buf[4];
+-	s32 tssival[2];
+-	u8 tssi_type;
+-
+-	tssi_reg = read_phy_reg(pi, 0x1e9);
+-
+-	temp = (s32) (tssi_reg & 0x3f);
+-	idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
+-
+-	temp = (s32) ((tssi_reg >> 8) & 0x3f);
+-	idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
+-
+-	tssi_type =
+-	    CHSPEC_IS5G(pi->radio_chanspec) ?
+-	    (u8)NPHY_RSSI_SEL_TSSI_5G:(u8)NPHY_RSSI_SEL_TSSI_2G;
+-
+-	wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
+-
+-	tssival[0] = rssi_buf[0] / ((s32) num_samps);
+-	tssival[1] = rssi_buf[2] / ((s32) num_samps);
+-
+-	pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
+-	pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
+-
+-	if (pwrindex[0] < 0) {
+-		pwrindex[0] = 0;
+-	} else if (pwrindex[0] > 63) {
+-		pwrindex[0] = 63;
+-	}
+-
+-	if (pwrindex[1] < 0) {
+-		pwrindex[1] = 0;
+-	} else if (pwrindex[1] > 63) {
+-		pwrindex[1] = 63;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
+-				(u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
+-				(u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
+-}
+-
+-static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi)
+-{
+-	u16 txcal_gain[2];
+-
+-	pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
+-	pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				txcal_gain);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
+-		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
+-	} else {
+-		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
+-		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 txcal_gain);
+-}
+-
+-static void wlc_phy_precal_txgain_nphy(phy_info_t *pi)
+-{
+-	bool save_bbmult = false;
+-	u8 txcal_index_2057_rev5n7 = 0;
+-	u8 txcal_index_2057_rev3n4n6 = 10;
+-
+-	if (pi->use_int_tx_iqlo_cal_nphy) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				pi->nphy_txcal_pwr_idx[0] =
+-				    txcal_index_2057_rev3n4n6;
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    txcal_index_2057_rev3n4n6;
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 txcal_index_2057_rev3n4n6,
+-							 false);
+-			} else {
+-
+-				pi->nphy_txcal_pwr_idx[0] =
+-				    txcal_index_2057_rev5n7;
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    txcal_index_2057_rev5n7;
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 txcal_index_2057_rev5n7,
+-							 false);
+-			}
+-			save_bbmult = true;
+-
+-		} else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-			wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
+-			if (pi->sh->hw_phytxchain != 3) {
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    pi->nphy_txcal_pwr_idx[0];
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 pi->
+-							 nphy_txcal_pwr_idx[0],
+-							 true);
+-				save_bbmult = true;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-			if (PHY_IPA(pi)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 12,
+-								    false);
+-				} else {
+-					pi->nphy_txcal_pwr_idx[0] = 80;
+-					pi->nphy_txcal_pwr_idx[1] = 80;
+-					wlc_phy_txpwr_index_nphy(pi, 3, 80,
+-								 false);
+-					save_bbmult = true;
+-				}
+-			} else {
+-
+-				wlc_phy_internal_cal_txgain_nphy(pi);
+-				save_bbmult = true;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+-			if (PHY_IPA(pi)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 12,
+-								    false);
+-				} else {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 14,
+-								    false);
+-				}
+-			} else {
+-
+-				wlc_phy_internal_cal_txgain_nphy(pi);
+-				save_bbmult = true;
+-			}
+-		}
+-
+-	} else {
+-		wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
+-	}
+-
+-	if (save_bbmult) {
+-		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+-					&pi->nphy_txcal_bbmult);
+-	}
+-}
+-
+-void
+-wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug)
+-{
+-	int gainctrl_loopidx;
+-	uint core;
+-	u16 m0m1, curr_m0m1;
+-	s32 delta_power;
+-	s32 txpwrindex;
+-	s32 qdBm_power[2];
+-	u16 orig_BBConfig;
+-	u16 phy_saveregs[4];
+-	u32 freq_test;
+-	u16 ampl_test = 250;
+-	uint stepsize;
+-	bool phyhang_avoid_state = false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		stepsize = 2;
+-	} else {
+-
+-		stepsize = 1;
+-	}
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		freq_test = 5000;
+-	} else {
+-		freq_test = 2500;
+-	}
+-
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	phyhang_avoid_state = pi->phyhang_avoid;
+-	pi->phyhang_avoid = false;
+-
+-	phy_saveregs[0] = read_phy_reg(pi, 0x91);
+-	phy_saveregs[1] = read_phy_reg(pi, 0x92);
+-	phy_saveregs[2] = read_phy_reg(pi, 0xe7);
+-	phy_saveregs[3] = read_phy_reg(pi, 0xec);
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
+-					 RADIO_MIMO_CORESEL_CORE1 |
+-					 RADIO_MIMO_CORESEL_CORE2);
+-
+-	if (!debug) {
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x2, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x8, RADIO_MIMO_CORESEL_CORE2);
+-	} else {
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x1, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x7, RADIO_MIMO_CORESEL_CORE2);
+-	}
+-
+-	orig_BBConfig = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
+-
+-		for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
+-		     gainctrl_loopidx++) {
+-			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+-					     false);
+-
+-			if (core == PHY_CORE_0) {
+-				curr_m0m1 = m0m1 & 0xff00;
+-			} else {
+-				curr_m0m1 = m0m1 & 0x00ff;
+-			}
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
+-			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
+-
+-			udelay(50);
+-
+-			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+-						 NPHY_CAL_TSSISAMPS);
+-
+-			pi->nphy_bb_mult_save = 0;
+-			wlc_phy_stopplayback_nphy(pi);
+-
+-			delta_power = (dBm_targetpower * 4) - qdBm_power[core];
+-
+-			txpwrindex -= stepsize * delta_power;
+-			if (txpwrindex < 0) {
+-				txpwrindex = 0;
+-			} else if (txpwrindex > 127) {
+-				txpwrindex = 127;
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (NREV_IS(pi->pubpi.phy_rev, 4) &&
+-				    (pi->srom_fem5g.extpagain == 3)) {
+-					if (txpwrindex < 30) {
+-						txpwrindex = 30;
+-					}
+-				}
+-			} else {
+-				if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-				    (pi->srom_fem2g.extpagain == 3)) {
+-					if (txpwrindex < 50) {
+-						txpwrindex = 50;
+-					}
+-				}
+-			}
+-
+-			wlc_phy_txpwr_index_nphy(pi, (1 << core),
+-						 (u8) txpwrindex, true);
+-		}
+-
+-		pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
+-
+-		if (debug) {
+-			u16 radio_gain;
+-			u16 dbg_m0m1;
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+-
+-			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+-					     false);
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+-			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
+-
+-			udelay(100);
+-
+-			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+-						 NPHY_CAL_TSSISAMPS);
+-
+-			wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
+-						&radio_gain);
+-
+-			mdelay(4000);
+-			pi->nphy_bb_mult_save = 0;
+-			wlc_phy_stopplayback_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
+-
+-	write_phy_reg(pi, 0x01, orig_BBConfig);
+-
+-	write_phy_reg(pi, 0x91, phy_saveregs[0]);
+-	write_phy_reg(pi, 0x92, phy_saveregs[1]);
+-	write_phy_reg(pi, 0xe7, phy_saveregs[2]);
+-	write_phy_reg(pi, 0xec, phy_saveregs[3]);
+-
+-	pi->phyhang_avoid = phyhang_avoid_state;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core)
+-{
+-	int index;
+-	u32 bbmult_scale;
+-	u16 bbmult;
+-	u16 tblentry;
+-
+-	nphy_txiqcal_ladder_t ladder_lo[] = {
+-		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+-		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
+-		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
+-	};
+-
+-	nphy_txiqcal_ladder_t ladder_iq[] = {
+-		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+-		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
+-		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
+-	};
+-
+-	bbmult = (core == PHY_CORE_0) ?
+-	    ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi->
+-						     nphy_txcal_bbmult & 0xff);
+-
+-	for (index = 0; index < 18; index++) {
+-		bbmult_scale = ladder_lo[index].percent * bbmult;
+-		bbmult_scale /= 100;
+-
+-		tblentry =
+-		    ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
+-					 &tblentry);
+-
+-		bbmult_scale = ladder_iq[index].percent * bbmult;
+-		bbmult_scale /= 100;
+-
+-		tblentry =
+-		    ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
+-					 16, &tblentry);
+-	}
+-}
+-
+-void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype)
+-{
+-	nphy_txgains_t target_gain;
+-	u8 tx_pwr_ctrl_state;
+-	bool fullcal = true;
+-	bool restore_tx_gain = false;
+-	bool mphase;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		wlc_phy_cal_perical_mphase_reset(pi);
+-		return;
+-	}
+-
+-	if (PHY_MUTED(pi))
+-		return;
+-
+-	if (caltype == PHY_PERICAL_AUTO)
+-		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
+-	else if (caltype == PHY_PERICAL_PARTIAL)
+-		fullcal = false;
+-
+-	if (pi->cal_type_override != PHY_PERICAL_AUTO) {
+-		fullcal =
+-		    (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false;
+-	}
+-
+-	if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
+-		if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
+-			wlc_phy_cal_perical_mphase_restart(pi);
+-	}
+-
+-	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) {
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+-	}
+-
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phyreg_enter((wlc_phy_t *) pi);
+-
+-	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
+-	    (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
+-		pi->nphy_cal_orig_pwr_idx[0] =
+-		    (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
+-		pi->nphy_cal_orig_pwr_idx[1] =
+-		    (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
+-
+-		if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
+-						0x110, 16,
+-						pi->nphy_cal_orig_tx_gain);
+-		} else {
+-			pi->nphy_cal_orig_tx_gain[0] = 0;
+-			pi->nphy_cal_orig_tx_gain[1] = 0;
+-		}
+-	}
+-	target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	if (pi->antsel_type == ANTSEL_2x3)
+-		wlc_phy_antsel_init((wlc_phy_t *) pi, true);
+-
+-	mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
+-	if (!mphase) {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_precal_txgain_nphy(pi);
+-			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-			restore_tx_gain = true;
+-
+-			target_gain = pi->nphy_cal_target_gain;
+-		}
+-		if (0 ==
+-		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) {
+-			if (PHY_IPA(pi))
+-				wlc_phy_a4(pi, true);
+-
+-			wlc_phyreg_exit((wlc_phy_t *) pi);
+-			wlapi_enable_mac(pi->sh->physhim);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
+-					     10000);
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			wlc_phyreg_enter((wlc_phy_t *) pi);
+-
+-			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
+-							     (pi->
+-							      first_cal_after_assoc
+-							      || (pi->
+-								  cal_type_override
+-								  ==
+-								  PHY_PERICAL_FULL))
+-							     ? 2 : 0, false)) {
+-				wlc_phy_savecal_nphy(pi);
+-
+-				wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-
+-				pi->nphy_perical_last = pi->sh->now;
+-			}
+-		}
+-		if (caltype != PHY_PERICAL_AUTO) {
+-			wlc_phy_rssi_cal_nphy(pi);
+-		}
+-
+-		if (pi->first_cal_after_assoc
+-		    || (pi->cal_type_override == PHY_PERICAL_FULL)) {
+-			pi->first_cal_after_assoc = false;
+-			wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-			wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_radio205x_vcocal_nphy(pi);
+-		}
+-	} else {
+-		switch (pi->mphase_cal_phase_id) {
+-		case MPHASE_CAL_STATE_INIT:
+-			pi->nphy_perical_last = pi->sh->now;
+-			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				wlc_phy_precal_txgain_nphy(pi);
+-			}
+-			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_TXPHASE0:
+-		case MPHASE_CAL_STATE_TXPHASE1:
+-		case MPHASE_CAL_STATE_TXPHASE2:
+-		case MPHASE_CAL_STATE_TXPHASE3:
+-		case MPHASE_CAL_STATE_TXPHASE4:
+-		case MPHASE_CAL_STATE_TXPHASE5:
+-			if ((pi->radar_percal_mask & 0x10) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (wlc_phy_cal_txiqlo_nphy
+-			    (pi, pi->nphy_cal_target_gain, fullcal,
+-			     true) != 0) {
+-
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-				break;
+-			}
+-
+-			if (NREV_LE(pi->pubpi.phy_rev, 2) &&
+-			    (pi->mphase_cal_phase_id ==
+-			     MPHASE_CAL_STATE_TXPHASE4)) {
+-				pi->mphase_cal_phase_id += 2;
+-			} else {
+-				pi->mphase_cal_phase_id++;
+-			}
+-			break;
+-
+-		case MPHASE_CAL_STATE_PAPDCAL:
+-			if ((pi->radar_percal_mask & 0x2) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (PHY_IPA(pi)) {
+-				wlc_phy_a4(pi, true);
+-			}
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_RXCAL:
+-			if ((pi->radar_percal_mask & 0x1) != 0)
+-				pi->nphy_rxcal_active = true;
+-			if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
+-						  (pi->first_cal_after_assoc ||
+-						   (pi->cal_type_override ==
+-						    PHY_PERICAL_FULL)) ? 2 : 0,
+-						  false) == 0) {
+-				wlc_phy_savecal_nphy(pi);
+-			}
+-
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_RSSICAL:
+-			if ((pi->radar_percal_mask & 0x4) != 0)
+-				pi->nphy_rxcal_active = true;
+-			wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-			wlc_phy_rssi_cal_nphy(pi);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				wlc_phy_radio205x_vcocal_nphy(pi);
+-			}
+-			restore_tx_gain = true;
+-
+-			if (pi->first_cal_after_assoc) {
+-				pi->mphase_cal_phase_id++;
+-			} else {
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-			}
+-
+-			break;
+-
+-		case MPHASE_CAL_STATE_IDLETSSI:
+-			if ((pi->radar_percal_mask & 0x8) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (pi->first_cal_after_assoc) {
+-				pi->first_cal_after_assoc = false;
+-				wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-				wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-			}
+-
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			break;
+-
+-		default:
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			break;
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (restore_tx_gain) {
+-			if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
+-
+-				wlc_phy_txpwr_index_nphy(pi, 1,
+-							 pi->
+-							 nphy_cal_orig_pwr_idx
+-							 [0], false);
+-				wlc_phy_txpwr_index_nphy(pi, 2,
+-							 pi->
+-							 nphy_cal_orig_pwr_idx
+-							 [1], false);
+-
+-				pi->nphy_txpwrindex[0].index = -1;
+-				pi->nphy_txpwrindex[1].index = -1;
+-			} else {
+-				wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+-							 (s8) (pi->
+-								 nphy_txpwrindex
+-								 [0].
+-								 index_internal),
+-							 false);
+-				wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+-							 (s8) (pi->
+-								 nphy_txpwrindex
+-								 [1].
+-								 index_internal),
+-							 false);
+-			}
+-		}
+-	}
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-	wlc_phyreg_exit((wlc_phy_t *) pi);
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-int
+-wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-			bool fullcal, bool mphase)
+-{
+-	u16 val;
+-	u16 tbl_buf[11];
+-	u8 cal_cnt;
+-	u16 cal_cmd;
+-	u8 num_cals, max_cal_cmds;
+-	u16 core_no, cal_type;
+-	u16 diq_start = 0;
+-	u8 phy_bw;
+-	u16 max_val;
+-	u16 tone_freq;
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u32 tbl_len;
+-	void *tbl_ptr;
+-	bool ladder_updated[2];
+-	u8 mphase_cal_lastphase = 0;
+-	int bcmerror = 0;
+-	bool phyhang_avoid_state = false;
+-
+-	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+-		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
+-		    0x1902,
+-		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
+-		    0x6407
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+-		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
+-		    0x3200,
+-		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
+-		    0x6407
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+-		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
+-		    0x1202,
+-		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
+-		    0x4707
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+-		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
+-		    0x2300,
+-		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
+-		    0x4707
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_startcoefs[] = {
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		    0x0000
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+-		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
+-		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
+-		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
+-		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
+-		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+-		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
+-		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
+-	};
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		phyhang_avoid_state = pi->phyhang_avoid;
+-		pi->phyhang_avoid = false;
+-	}
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		phy_bw = 40;
+-	} else {
+-		phy_bw = 20;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	wlc_phy_txcal_radio_setup_nphy(pi);
+-
+-	wlc_phy_txcal_physetup_nphy(pi);
+-
+-	ladder_updated[0] = ladder_updated[1] = false;
+-	if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
+-	      (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
+-	       && (CHSPEC_IS2G(pi->radio_chanspec))))) {
+-
+-		if (phy_bw == 40) {
+-			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
+-		} else {
+-			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
+-					 16, tbl_ptr);
+-
+-		if (phy_bw == 40) {
+-			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
+-		} else {
+-			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
+-					 16, tbl_ptr);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0xc2, 0x8ad9);
+-	} else {
+-		write_phy_reg(pi, 0xc2, 0x8aa9);
+-	}
+-
+-	max_val = 250;
+-	tone_freq = (phy_bw == 20) ? 2500 : 5000;
+-
+-	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+-		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
+-		bcmerror = 0;
+-	} else {
+-		bcmerror =
+-		    wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false);
+-	}
+-
+-	if (bcmerror == 0) {
+-
+-		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+-			tbl_ptr = pi->mphase_txcal_bestcoeffs;
+-			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-		} else {
+-			if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
+-
+-				tbl_ptr = pi->nphy_txiqlocal_bestc;
+-				tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
+-				if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-					tbl_len -= 2;
+-				}
+-			} else {
+-
+-				fullcal = true;
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					tbl_ptr =
+-					    tbl_tx_iqlo_cal_startcoefs_nphyrev3;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (tbl_tx_iqlo_cal_startcoefs_nphyrev3);
+-				} else {
+-					tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (tbl_tx_iqlo_cal_startcoefs);
+-				}
+-			}
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
+-					 16, tbl_ptr);
+-
+-		if (fullcal) {
+-			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
+-		} else {
+-			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
+-		}
+-
+-		if (mphase) {
+-			cal_cnt = pi->mphase_txcal_cmdidx;
+-			if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) {
+-				num_cals = cal_cnt + pi->mphase_txcal_numcmds;
+-			} else {
+-				num_cals = max_cal_cmds;
+-			}
+-		} else {
+-			cal_cnt = 0;
+-			num_cals = max_cal_cmds;
+-		}
+-
+-		for (; cal_cnt < num_cals; cal_cnt++) {
+-
+-			if (fullcal) {
+-				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-				    tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
+-				    [cal_cnt] :
+-				    tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
+-			} else {
+-				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-				    tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt]
+-				    : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
+-			}
+-
+-			core_no = ((cal_cmd & 0x3000) >> 12);
+-			cal_type = ((cal_cmd & 0x0F00) >> 8);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 6) ||
+-			    (NREV_IS(pi->pubpi.phy_rev, 5) &&
+-			     PHY_IPA(pi)
+-			     && (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-				if (!ladder_updated[core_no]) {
+-					wlc_phy_update_txcal_ladder_nphy(pi,
+-									 core_no);
+-					ladder_updated[core_no] = true;
+-				}
+-			}
+-
+-			val =
+-			    (cal_params[core_no].
+-			     ncorr[cal_type] << 8) | NPHY_N_GCTL;
+-			write_phy_reg(pi, 0xc1, val);
+-
+-			if ((cal_type == 1) || (cal_type == 3)
+-			    || (cal_type == 4)) {
+-
+-				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-							1, 69 + core_no, 16,
+-							tbl_buf);
+-
+-				diq_start = tbl_buf[0];
+-
+-				tbl_buf[0] = 0;
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_IQLOCAL, 1,
+-							 69 + core_no, 16,
+-							 tbl_buf);
+-			}
+-
+-			write_phy_reg(pi, 0xc0, cal_cmd);
+-
+-			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
+-				 20000);
+-			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
+-				 "HW error: txiq calib"))
+-				return -EIO;
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						 tbl_len, 64, 16, tbl_buf);
+-
+-			if ((cal_type == 1) || (cal_type == 3)
+-			    || (cal_type == 4)) {
+-
+-				tbl_buf[0] = diq_start;
+-
+-			}
+-
+-		}
+-
+-		if (mphase) {
+-			pi->mphase_txcal_cmdidx = num_cals;
+-			if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
+-				pi->mphase_txcal_cmdidx = 0;
+-		}
+-
+-		mphase_cal_lastphase =
+-		    (NREV_LE(pi->pubpi.phy_rev, 2)) ?
+-		    MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
+-
+-		if (!mphase
+-		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
+-						16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+-						 16, tbl_buf);
+-
+-			if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-				tbl_buf[0] = 0;
+-				tbl_buf[1] = 0;
+-				tbl_buf[2] = 0;
+-				tbl_buf[3] = 0;
+-
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
+-						16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+-						 16, tbl_buf);
+-
+-			tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16,
+-						pi->nphy_txiqlocal_bestc);
+-
+-			pi->nphy_txiqlocal_coeffsvalid = true;
+-			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+-		} else {
+-			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16,
+-						pi->mphase_txcal_bestcoeffs);
+-		}
+-
+-		wlc_phy_stopplayback_nphy(pi);
+-
+-		write_phy_reg(pi, 0xc2, 0x0000);
+-
+-	}
+-
+-	wlc_phy_txcal_phycleanup_nphy(pi);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	wlc_phy_txcal_radio_cleanup_nphy(pi);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		if (!mphase
+-		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
+-			wlc_phy_tx_iq_war_nphy(pi);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		pi->phyhang_avoid = phyhang_avoid_state;
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return bcmerror;
+-}
+-
+-static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi)
+-{
+-	u16 tbl_buf[7];
+-
+-	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
+-	    (pi->nphy_txiqlocal_coeffsvalid)) {
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-					ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
+-
+-		if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
+-		    (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
+-		    (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
+-		    (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+-						 16, pi->nphy_txiqlocal_bestc);
+-
+-			tbl_buf[0] = 0;
+-			tbl_buf[1] = 0;
+-			tbl_buf[2] = 0;
+-			tbl_buf[3] = 0;
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+-						 16,
+-						 &pi->nphy_txiqlocal_bestc[5]);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+-						 16,
+-						 &pi->nphy_txiqlocal_bestc[5]);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi)
+-{
+-	nphy_iq_comp_t tx_comp;
+-
+-	wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp);
+-
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
+-}
+-
+-void
+-wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp)
+-{
+-	if (write) {
+-		write_phy_reg(pi, 0x9a, pcomp->a0);
+-		write_phy_reg(pi, 0x9b, pcomp->b0);
+-		write_phy_reg(pi, 0x9c, pcomp->a1);
+-		write_phy_reg(pi, 0x9d, pcomp->b1);
+-	} else {
+-		pcomp->a0 = read_phy_reg(pi, 0x9a);
+-		pcomp->b0 = read_phy_reg(pi, 0x9b);
+-		pcomp->a1 = read_phy_reg(pi, 0x9c);
+-		pcomp->b1 = read_phy_reg(pi, 0x9d);
+-	}
+-}
+-
+-void
+-wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps,
+-		       u8 wait_time, u8 wait_for_crs)
+-{
+-	u8 core;
+-
+-	write_phy_reg(pi, 0x12b, num_samps);
+-	mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
+-	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
+-		    (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
+-
+-	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
+-
+-	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
+-		 10000);
+-	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
+-		 "HW error: rxiq est"))
+-		return;
+-
+-	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			est[core].i_pwr =
+-			    (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16)
+-			    | read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
+-			est[core].q_pwr =
+-			    (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16)
+-			    | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
+-			est[core].iq_prod =
+-			    (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) |
+-			    read_phy_reg(pi, NPHY_IqestIqAccLo(core));
+-		}
+-	}
+-}
+-
+-#define CAL_RETRY_CNT 2
+-static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask)
+-{
+-	u8 curr_core;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	nphy_iq_comp_t old_comp, new_comp;
+-	s32 iq = 0;
+-	u32 ii = 0, qq = 0;
+-	s16 iq_nbits, qq_nbits, brsh, arsh;
+-	s32 a, b, temp;
+-	int bcmerror = 0;
+-	uint cal_retry = 0;
+-
+-	if (core_mask == 0x0)
+-		return;
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
+-	new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+-
+- cal_try:
+-	wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
+-
+-	new_comp = old_comp;
+-
+-	for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
+-
+-		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+-			iq = est[curr_core].iq_prod;
+-			ii = est[curr_core].i_pwr;
+-			qq = est[curr_core].q_pwr;
+-		} else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+-			iq = est[curr_core].iq_prod;
+-			ii = est[curr_core].i_pwr;
+-			qq = est[curr_core].q_pwr;
+-		} else {
+-			continue;
+-		}
+-
+-		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
+-			bcmerror = -EBADE;
+-			break;
+-		}
+-
+-		iq_nbits = wlc_phy_nbits(iq);
+-		qq_nbits = wlc_phy_nbits(qq);
+-
+-		arsh = 10 - (30 - iq_nbits);
+-		if (arsh >= 0) {
+-			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+-			temp = (s32) (ii >> arsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		} else {
+-			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+-			temp = (s32) (ii << -arsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		}
+-
+-		a /= temp;
+-
+-		brsh = qq_nbits - 31 + 20;
+-		if (brsh >= 0) {
+-			b = (qq << (31 - qq_nbits));
+-			temp = (s32) (ii >> brsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		} else {
+-			b = (qq << (31 - qq_nbits));
+-			temp = (s32) (ii << -brsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		}
+-		b /= temp;
+-		b -= a * a;
+-		b = (s32) int_sqrt((unsigned long) b);
+-		b -= (1 << 10);
+-
+-		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				new_comp.a0 = (s16) a & 0x3ff;
+-				new_comp.b0 = (s16) b & 0x3ff;
+-			} else {
+-
+-				new_comp.a0 = (s16) b & 0x3ff;
+-				new_comp.b0 = (s16) a & 0x3ff;
+-			}
+-		}
+-		if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				new_comp.a1 = (s16) a & 0x3ff;
+-				new_comp.b1 = (s16) b & 0x3ff;
+-			} else {
+-
+-				new_comp.a1 = (s16) b & 0x3ff;
+-				new_comp.b1 = (s16) a & 0x3ff;
+-			}
+-		}
+-	}
+-
+-	if (bcmerror != 0) {
+-		printk("%s: Failed, cnt = %d\n", __func__, cal_retry);
+-
+-		if (cal_retry < CAL_RETRY_CNT) {
+-			cal_retry++;
+-			goto cal_try;
+-		}
+-
+-		new_comp = old_comp;
+-	} else if (cal_retry > 0) {
+-	}
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+-}
+-
+-static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	u16 offtune_val;
+-	u16 bias_g = 0;
+-	u16 bias_a = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (rx_core == PHY_CORE_0) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+-						0xaf);
+-
+-			} else {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+-						0x7f);
+-			}
+-
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+-						0xaf);
+-
+-			} else {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+-						0x7f);
+-			}
+-		}
+-
+-	} else {
+-		if (rx_core == PHY_CORE_0) {
+-			pi->tx_rx_cal_radio_saveregs[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_RXIQCAL_TXMUX |
+-					   RADIO_2056_TX1);
+-			pi->tx_rx_cal_radio_saveregs[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RXIQCAL_RXMUX |
+-					   RADIO_2056_RX0);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				pi->tx_rx_cal_radio_saveregs[2] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_RX_RXSPARE2 |
+-						   RADIO_2056_RX0);
+-				pi->tx_rx_cal_radio_saveregs[3] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_TX_TXSPARE2 |
+-						   RADIO_2056_TX1);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_MASTER
+-							   | RADIO_2056_RX0);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX0, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX1, bias_a);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX0, bias_a);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_TUNE
+-							   | RADIO_2056_RX0);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAA_TUNE |
+-						      RADIO_2056_RX0, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX1, 0x9);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX0, 0x9);
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_MASTER
+-							   | RADIO_2056_RX0);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX0, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX1, bias_g);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX0, bias_g);
+-
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_TUNE
+-							   | RADIO_2056_RX0);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAG_TUNE |
+-						      RADIO_2056_RX0, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX1, 0x6);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX0, 0x6);
+-			}
+-
+-		} else {
+-			pi->tx_rx_cal_radio_saveregs[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_RXIQCAL_TXMUX |
+-					   RADIO_2056_TX0);
+-			pi->tx_rx_cal_radio_saveregs[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RXIQCAL_RXMUX |
+-					   RADIO_2056_RX1);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				pi->tx_rx_cal_radio_saveregs[2] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_RX_RXSPARE2 |
+-						   RADIO_2056_RX1);
+-				pi->tx_rx_cal_radio_saveregs[3] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_TX_TXSPARE2 |
+-						   RADIO_2056_TX0);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_MASTER
+-							   | RADIO_2056_RX1);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX1, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX0, bias_a);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX1, bias_a);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_TUNE
+-							   | RADIO_2056_RX1);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAA_TUNE |
+-						      RADIO_2056_RX1, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX0, 0x9);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX1, 0x9);
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_MASTER
+-							   | RADIO_2056_RX1);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX1, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX0, bias_g);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX1, bias_g);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_TUNE
+-							   | RADIO_2056_RX1);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAG_TUNE |
+-						      RADIO_2056_RX1, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX0, 0x6);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX1, 0x6);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (rx_core == PHY_CORE_0) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-			}
+-
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-			}
+-		}
+-
+-	} else {
+-		if (rx_core == PHY_CORE_0) {
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_RXIQCAL_TXMUX |
+-					RADIO_2056_TX1,
+-					pi->tx_rx_cal_radio_saveregs[0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_RX_RXIQCAL_RXMUX |
+-					RADIO_2056_RX0,
+-					pi->tx_rx_cal_radio_saveregs[1]);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXSPARE2 |
+-						RADIO_2056_RX0,
+-						pi->
+-						tx_rx_cal_radio_saveregs[2]);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TXSPARE2 |
+-						RADIO_2056_TX1,
+-						pi->
+-						tx_rx_cal_radio_saveregs[3]);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_TUNE
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_TUNE
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			}
+-
+-		} else {
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_RXIQCAL_TXMUX |
+-					RADIO_2056_TX0,
+-					pi->tx_rx_cal_radio_saveregs[0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_RX_RXIQCAL_RXMUX |
+-					RADIO_2056_RX1,
+-					pi->tx_rx_cal_radio_saveregs[1]);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXSPARE2 |
+-						RADIO_2056_RX1,
+-						pi->
+-						tx_rx_cal_radio_saveregs[2]);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TXSPARE2 |
+-						RADIO_2056_TX0,
+-						pi->
+-						tx_rx_cal_radio_saveregs[3]);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_TUNE
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_TUNE
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	u8 tx_core;
+-	u16 rx_antval, tx_antval;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		tx_core = rx_core;
+-	} else {
+-		tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
+-	}
+-
+-	pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
+-	pi->tx_rx_cal_phy_saveregs[1] =
+-	    read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
+-	pi->tx_rx_cal_phy_saveregs[2] =
+-	    read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
+-	pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
+-	pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
+-	pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
+-	pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
+-	pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
+-	pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
+-		pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
+-		pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
+-		pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
+-	}
+-
+-	pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+-	pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+-	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (0) << 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
+-
+-	} else {
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-		mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
+-		mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
+-	}
+-
+-	mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
+-	mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+-		    (0x1 << 2), (0x1 << 2));
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 0) | (0x1 << 1), 0);
+-		mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-			    0x8f : 0xa5,
+-			    (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
+-	}
+-
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
+-					 RADIO_MIMO_CORESEL_CORE1 |
+-					 RADIO_MIMO_CORESEL_CORE2);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  2, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-						  0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
+-	}
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x1, rx_core + 1);
+-	} else {
+-
+-		if (rx_core == PHY_CORE_0) {
+-			rx_antval = 0x1;
+-			tx_antval = 0x8;
+-		} else {
+-			rx_antval = 0x4;
+-			tx_antval = 0x2;
+-		}
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 rx_antval, rx_core + 1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 tx_antval, tx_core + 1);
+-	}
+-}
+-
+-static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-
+-	write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
+-	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
+-		      pi->tx_rx_cal_phy_saveregs[1]);
+-	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+-		      pi->tx_rx_cal_phy_saveregs[2]);
+-	write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
+-	write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
+-
+-	write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
+-	write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
+-	write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
+-	write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
+-		write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
+-		write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
+-		write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
+-	}
+-
+-	write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+-	write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+-}
+-
+-static void
+-wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core,
+-				 u16 *rxgain, u8 cal_type)
+-{
+-
+-	u16 num_samps;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	u8 tx_core;
+-	nphy_iq_comp_t save_comp, zero_comp;
+-	u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr =
+-	    10000;
+-	s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
+-	bool gainctrl_done = false;
+-	u8 mix_tia_gain = 3;
+-	s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
+-	s8 curr_gaintbl_index = 3;
+-	u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
+-	nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl;
+-	u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
+-	int fine_gain_idx;
+-	s8 txpwrindex;
+-	u16 nphy_rxcal_txgain[2];
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		tx_core = rx_core;
+-	} else {
+-		tx_core = 1 - rx_core;
+-	}
+-
+-	num_samps = 1024;
+-	desired_log2_pwr = (cal_type == 0) ? 13 : 13;
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
+-	zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mix_tia_gain = 3;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-			mix_tia_gain = 4;
+-		} else {
+-			mix_tia_gain = 6;
+-		}
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
+-		} else {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
+-		}
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
+-		} else {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
+-		}
+-	}
+-
+-	do {
+-
+-		hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
+-		    0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
+-		lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
+-		lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
+-		lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
+-		lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
+-		txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-							     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-							     ((lpf_biq1 << 12) |
+-							      (lpf_biq0 << 8) |
+-							      (mix_tia_gain <<
+-							       4) | (lna2 << 2)
+-							      | lna1), 0x3, 0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+-						     ((hpvga << 12) |
+-						      (lpf_biq1 << 10) |
+-						      (lpf_biq0 << 8) |
+-						      (mix_tia_gain << 4) |
+-						      (lna2 << 2) | lna1), 0x3,
+-						     0);
+-		}
+-
+-		pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
+-
+-		if (txpwrindex == -1) {
+-			nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
+-			nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-						 2, 0x110, 16,
+-						 nphy_rxcal_txgain);
+-		} else {
+-			wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
+-						 false);
+-		}
+-
+-		wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
+-				     NPHY_RXCAL_TONEFREQ_40MHz :
+-				     NPHY_RXCAL_TONEFREQ_20MHz,
+-				     NPHY_RXCAL_TONEAMP, 0, cal_type, false);
+-
+-		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-		i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
+-		q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
+-		curr_pwr = i_pwr + q_pwr;
+-
+-		switch (gainctrl_dirn) {
+-		case NPHY_RXCAL_GAIN_INIT:
+-			if (curr_pwr > thresh_pwr) {
+-				gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index--;
+-			} else {
+-				gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index++;
+-			}
+-			break;
+-
+-		case NPHY_RXCAL_GAIN_UP:
+-			if (curr_pwr > thresh_pwr) {
+-				gainctrl_done = true;
+-				optim_pwr = prev_pwr;
+-				optim_gaintbl_index = prev_gaintbl_index;
+-			} else {
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index++;
+-			}
+-			break;
+-
+-		case NPHY_RXCAL_GAIN_DOWN:
+-			if (curr_pwr > thresh_pwr) {
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index--;
+-			} else {
+-				gainctrl_done = true;
+-				optim_pwr = curr_pwr;
+-				optim_gaintbl_index = curr_gaintbl_index;
+-			}
+-			break;
+-
+-		default:
+-			break;
+-		}
+-
+-		if ((curr_gaintbl_index < 0) ||
+-		    (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
+-			gainctrl_done = true;
+-			optim_pwr = curr_pwr;
+-			optim_gaintbl_index = prev_gaintbl_index;
+-		} else {
+-			prev_pwr = curr_pwr;
+-		}
+-
+-		wlc_phy_stopplayback_nphy(pi);
+-	} while (!gainctrl_done);
+-
+-	hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
+-	lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
+-	lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
+-	lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
+-	lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
+-	txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
+-
+-	actual_log2_pwr = wlc_phy_nbits(optim_pwr);
+-	delta_pwr = desired_log2_pwr - actual_log2_pwr;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		fine_gain_idx = (int)lpf_biq1 + delta_pwr;
+-
+-		if (fine_gain_idx + (int)lpf_biq0 > 10) {
+-			lpf_biq1 = 10 - lpf_biq0;
+-		} else {
+-			lpf_biq1 = (u16) max(fine_gain_idx, 0);
+-		}
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-						     ((lpf_biq1 << 12) |
+-						      (lpf_biq0 << 8) |
+-						      (mix_tia_gain << 4) |
+-						      (lna2 << 2) | lna1), 0x3,
+-						     0);
+-	} else {
+-		hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+-					     ((hpvga << 12) | (lpf_biq1 << 10) |
+-					      (lpf_biq0 << 8) | (mix_tia_gain <<
+-								 4) | (lna2 <<
+-								       2) |
+-					      lna1), 0x3, 0);
+-
+-	}
+-
+-	if (rxgain != NULL) {
+-		*rxgain++ = lna1;
+-		*rxgain++ = lna2;
+-		*rxgain++ = mix_tia_gain;
+-		*rxgain++ = lpf_biq0;
+-		*rxgain++ = lpf_biq1;
+-		*rxgain = hpvga;
+-	}
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
+-}
+-
+-static void
+-wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, u8 rx_core, u16 *rxgain,
+-			    u8 cal_type)
+-{
+-	wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
+-}
+-
+-static u8
+-wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type)
+-{
+-	u32 target_bws[2] = { 9500, 21000 };
+-	u32 ref_tones[2] = { 3000, 6000 };
+-	u32 target_bw, ref_tone;
+-
+-	u32 target_pwr_ratios[2] = { 28606, 18468 };
+-	u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
+-
+-	u16 start_rccal_ovr_val = 128;
+-	u16 txlpf_rccal_lpc_ovr_val = 128;
+-	u16 rxlpf_rccal_hpc_ovr_val = 159;
+-
+-	u16 orig_txlpf_rccal_lpc_ovr_val;
+-	u16 orig_rxlpf_rccal_hpc_ovr_val;
+-	u16 radio_addr_offset_rx;
+-	u16 radio_addr_offset_tx;
+-	u16 orig_dcBypass;
+-	u16 orig_RxStrnFilt40Num[6];
+-	u16 orig_RxStrnFilt40Den[4];
+-	u16 orig_rfctrloverride[2];
+-	u16 orig_rfctrlauxreg[2];
+-	u16 orig_rfctrlrssiothers;
+-	u16 tx_lpf_bw = 4;
+-
+-	u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
+-	u16 lpf_hpc = 7, hpvga_hpc = 7;
+-
+-	s8 rccal_stepsize;
+-	u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
+-	u32 ref_iq_vals = 0, target_iq_vals = 0;
+-	u16 num_samps, log_num_samps = 10;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		return 0;
+-	}
+-
+-	num_samps = (1 << log_num_samps);
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		target_bw = target_bws[1];
+-		target_pwr_ratio = target_pwr_ratios[1];
+-		ref_tone = ref_tones[1];
+-		rx_lpf_bw = rx_lpf_bws[1];
+-	} else {
+-		target_bw = target_bws[0];
+-		target_pwr_ratio = target_pwr_ratios[0];
+-		ref_tone = ref_tones[0];
+-		rx_lpf_bw = rx_lpf_bws[0];
+-	}
+-
+-	if (core_idx == 0) {
+-		radio_addr_offset_rx = RADIO_2056_RX0;
+-		radio_addr_offset_tx =
+-		    (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-	} else {
+-		radio_addr_offset_rx = RADIO_2056_RX1;
+-		radio_addr_offset_tx =
+-		    (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
+-	}
+-
+-	orig_txlpf_rccal_lpc_ovr_val =
+-	    read_radio_reg(pi,
+-			   (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx));
+-	orig_rxlpf_rccal_hpc_ovr_val =
+-	    read_radio_reg(pi,
+-			   (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+-			    radio_addr_offset_rx));
+-
+-	orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
+-
+-	orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
+-	orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
+-	orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
+-	orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
+-	orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
+-	orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
+-	orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
+-	orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
+-	orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
+-	orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
+-
+-	orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
+-	orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
+-	orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
+-	orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
+-	orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
+-
+-	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+-			txlpf_rccal_lpc_ovr_val);
+-
+-	write_radio_reg(pi,
+-			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+-			rxlpf_rccal_hpc_ovr_val);
+-
+-	mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
+-
+-	write_phy_reg(pi, 0x267, 0x02d4);
+-	write_phy_reg(pi, 0x268, 0x0000);
+-	write_phy_reg(pi, 0x269, 0x0000);
+-	write_phy_reg(pi, 0x26a, 0x0000);
+-	write_phy_reg(pi, 0x26b, 0x0000);
+-	write_phy_reg(pi, 0x26c, 0x02d4);
+-	write_phy_reg(pi, 0x26d, 0x0000);
+-	write_phy_reg(pi, 0x26e, 0x0000);
+-	write_phy_reg(pi, 0x26f, 0x0000);
+-	write_phy_reg(pi, 0x270, 0x0000);
+-
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
+-
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
+-		    (0x7 << 10), (tx_lpf_bw << 10));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+-		    (0x7 << 0), (hpvga_hpc << 0));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+-		    (0x7 << 4), (lpf_hpc << 4));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
+-		    (0x7 << 8), (rx_lpf_bw << 8));
+-
+-	rccal_stepsize = 16;
+-	rccal_val = start_rccal_ovr_val + rccal_stepsize;
+-
+-	while (rccal_stepsize >= 0) {
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-				 radio_addr_offset_rx), rccal_val);
+-
+-		if (rccal_stepsize == 16) {
+-
+-			wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
+-					     0, 1, false);
+-			udelay(2);
+-
+-			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-
+-			if (core_idx == 0) {
+-				ref_iq_vals =
+-				    max_t(u32, (est[0].i_pwr +
+-					 est[0].q_pwr) >> (log_num_samps + 1),
+-					1);
+-			} else {
+-				ref_iq_vals =
+-				    max_t(u32, (est[1].i_pwr +
+-					 est[1].q_pwr) >> (log_num_samps + 1),
+-					1);
+-			}
+-
+-			wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
+-					     0, 1, false);
+-			udelay(2);
+-		}
+-
+-		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-
+-		if (core_idx == 0) {
+-			target_iq_vals =
+-			    (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps +
+-							      1);
+-		} else {
+-			target_iq_vals =
+-			    (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps +
+-							      1);
+-		}
+-		pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
+-
+-		if (rccal_stepsize == 0) {
+-			rccal_stepsize--;
+-		} else if (rccal_stepsize == 1) {
+-			last_rccal_val = rccal_val;
+-			rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
+-			last_pwr_ratio = pwr_ratio;
+-			rccal_stepsize--;
+-		} else {
+-			rccal_stepsize = (rccal_stepsize >> 1);
+-			rccal_val += ((pwr_ratio > target_pwr_ratio) ?
+-				      rccal_stepsize : (-rccal_stepsize));
+-		}
+-
+-		if (rccal_stepsize == -1) {
+-			best_rccal_val =
+-			    (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) <
+-			     ABS((int)pwr_ratio -
+-				 (int)target_pwr_ratio)) ? last_rccal_val :
+-			    rccal_val;
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				if ((best_rccal_val > 140)
+-				    || (best_rccal_val < 135)) {
+-					best_rccal_val = 138;
+-				}
+-			} else {
+-				if ((best_rccal_val > 142)
+-				    || (best_rccal_val < 137)) {
+-					best_rccal_val = 140;
+-				}
+-			}
+-
+-			write_radio_reg(pi,
+-					(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-					 radio_addr_offset_rx), best_rccal_val);
+-		}
+-	}
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+-			orig_txlpf_rccal_lpc_ovr_val);
+-	write_radio_reg(pi,
+-			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+-			orig_rxlpf_rccal_hpc_ovr_val);
+-
+-	mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
+-
+-	write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
+-	write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
+-	write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
+-	write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
+-	write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
+-	write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
+-	write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
+-	write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
+-	write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
+-	write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
+-
+-	write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
+-	write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
+-	write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
+-	write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
+-	write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
+-
+-	pi->nphy_anarxlpf_adjusted = false;
+-
+-	return best_rccal_val - 0x80;
+-}
+-
+-#define WAIT_FOR_SCOPE	4000
+-static int
+-wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain,
+-			   u8 cal_type, bool debug)
+-{
+-	u16 orig_BBConfig;
+-	u8 core_no, rx_core;
+-	u8 best_rccal[2];
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u8 rxcore_state;
+-	s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
+-	s8 txlpf_idac;
+-	bool phyhang_avoid_state = false;
+-	bool skip_rxiqcal = false;
+-
+-	orig_BBConfig = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		phyhang_avoid_state = pi->phyhang_avoid;
+-		pi->phyhang_avoid = false;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+-
+-	for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+-
+-		skip_rxiqcal =
+-		    ((rxcore_state & (1 << rx_core)) == 0) ? true : false;
+-
+-		wlc_phy_rxcal_physetup_nphy(pi, rx_core);
+-
+-		wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
+-
+-		if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
+-
+-			wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
+-
+-			wlc_phy_tx_tone_nphy(pi,
+-					     (CHSPEC_IS40(pi->radio_chanspec)) ?
+-					     NPHY_RXCAL_TONEFREQ_40MHz :
+-					     NPHY_RXCAL_TONEFREQ_20MHz,
+-					     NPHY_RXCAL_TONEAMP, 0, cal_type,
+-					     false);
+-
+-			if (debug)
+-				mdelay(WAIT_FOR_SCOPE);
+-
+-			wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
+-			wlc_phy_stopplayback_nphy(pi);
+-		}
+-
+-		if (((cal_type == 1) || (cal_type == 2))
+-		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-			if (rx_core == PHY_CORE_1) {
+-
+-				if (rxcore_state == 1) {
+-					wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+-								      *) pi, 3);
+-				}
+-
+-				wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
+-							    1);
+-
+-				best_rccal[rx_core] =
+-				    wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
+-				pi->nphy_rccal_value = best_rccal[rx_core];
+-
+-				if (rxcore_state == 1) {
+-					wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+-								      *) pi,
+-								     rxcore_state);
+-				}
+-			}
+-		}
+-
+-		wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
+-
+-		wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
+-		wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-	}
+-
+-	if ((cal_type == 1) || (cal_type == 2)) {
+-
+-		best_rccal[0] = best_rccal[1];
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-				 RADIO_2056_RX0), (best_rccal[0] | 0x80));
+-
+-		for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+-			rxlpf_rccal_hpc =
+-			    (((int)best_rccal[rx_core] - 12) >> 1) + 10;
+-			txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
+-
+-			if (PHY_IPA(pi)) {
+-				txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12;
+-				txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13;
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
+-						 TXLPF_IDAC_4, txlpf_idac);
+-			}
+-
+-			rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0);
+-			txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0);
+-
+-			write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+-					     ((rx_core ==
+-					       PHY_CORE_0) ? RADIO_2056_RX0 :
+-					      RADIO_2056_RX1)),
+-					(rxlpf_rccal_hpc | 0x80));
+-
+-			write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
+-					     ((rx_core ==
+-					       PHY_CORE_0) ? RADIO_2056_TX0 :
+-					      RADIO_2056_TX1)),
+-					(txlpf_rccal_lpc | 0x80));
+-		}
+-	}
+-
+-	write_phy_reg(pi, 0x01, orig_BBConfig);
+-
+-	wlc_phy_resetcca_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-						     0, 0x3, 1);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+-	}
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		pi->phyhang_avoid = phyhang_avoid_state;
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return 0;
+-}
+-
+-static int
+-wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain,
+-			   bool debug)
+-{
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	u8 core_num, rx_core, tx_core;
+-	u16 lna_vals[] = { 0x3, 0x3, 0x1 };
+-	u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
+-	u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
+-	s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
+-	s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
+-	u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
+-	u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
+-	u16 num_samps;
+-	u32 i_pwr, q_pwr, tot_pwr[3];
+-	u8 gain_pass, use_hpf_num;
+-	u16 mask, val1, val2;
+-	u16 core_no;
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u8 phy_bw;
+-	int bcmerror = 0;
+-	bool first_playtone = true;
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-		wlc_phy_reapply_txcal_coeffs_nphy(pi);
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	num_samps = 1024;
+-	desired_log2_pwr = 13;
+-
+-	for (core_num = 0; core_num < 2; core_num++) {
+-
+-		rx_core = core_num;
+-		tx_core = 1 - core_num;
+-
+-		orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
+-		orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-						0xa6 : 0xa7);
+-		orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
+-		orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-						 0x91 : 0x92);
+-		orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
+-						 0x91 : 0x92);
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-
+-		or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			   ((0x1 << 1) | (0x1 << 2)));
+-		or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
+-
+-		if (((pi->nphy_rxcalparams) & 0xff000000)) {
+-
+-			write_phy_reg(pi,
+-				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-				      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 :
+-				       0x110));
+-		} else {
+-
+-			write_phy_reg(pi,
+-				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-				      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 :
+-				       0x120));
+-		}
+-
+-		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-			      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
+-			       0x114));
+-
+-		mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
+-		if (rx_core == PHY_CORE_0) {
+-			val1 = RADIO_2055_COUPLE_RX_MASK;
+-			val2 = RADIO_2055_COUPLE_TX_MASK;
+-		} else {
+-			val1 = RADIO_2055_COUPLE_TX_MASK;
+-			val2 = RADIO_2055_COUPLE_RX_MASK;
+-		}
+-
+-		if ((pi->nphy_rxcalparams & 0x10000)) {
+-			mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
+-				      val1);
+-			mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
+-				      val2);
+-		}
+-
+-		for (gain_pass = 0; gain_pass < 4; gain_pass++) {
+-
+-			if (debug)
+-				mdelay(WAIT_FOR_SCOPE);
+-
+-			if (gain_pass < 3) {
+-				curr_lna = lna_vals[gain_pass];
+-				curr_hpf1 = hpf1_vals[gain_pass];
+-				curr_hpf2 = hpf2_vals[gain_pass];
+-			} else {
+-
+-				if (tot_pwr[1] > 10000) {
+-					curr_lna = lna_vals[2];
+-					curr_hpf1 = hpf1_vals[2];
+-					curr_hpf2 = hpf2_vals[2];
+-					use_hpf_num = 1;
+-					curr_hpf = curr_hpf1;
+-					actual_log2_pwr =
+-					    wlc_phy_nbits(tot_pwr[2]);
+-				} else {
+-					if (tot_pwr[0] > 10000) {
+-						curr_lna = lna_vals[1];
+-						curr_hpf1 = hpf1_vals[1];
+-						curr_hpf2 = hpf2_vals[1];
+-						use_hpf_num = 1;
+-						curr_hpf = curr_hpf1;
+-						actual_log2_pwr =
+-						    wlc_phy_nbits(tot_pwr[1]);
+-					} else {
+-						curr_lna = lna_vals[0];
+-						curr_hpf1 = hpf1_vals[0];
+-						curr_hpf2 = hpf2_vals[0];
+-						use_hpf_num = 2;
+-						curr_hpf = curr_hpf2;
+-						actual_log2_pwr =
+-						    wlc_phy_nbits(tot_pwr[0]);
+-					}
+-				}
+-
+-				hpf_change = desired_log2_pwr - actual_log2_pwr;
+-				curr_hpf += hpf_change;
+-				curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
+-				if (use_hpf_num == 1) {
+-					curr_hpf1 = curr_hpf;
+-				} else {
+-					curr_hpf2 = curr_hpf;
+-				}
+-			}
+-
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
+-						     ((curr_hpf2 << 8) |
+-						      (curr_hpf1 << 4) |
+-						      (curr_lna << 2)), 0x3, 0);
+-			wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-			wlc_phy_stopplayback_nphy(pi);
+-
+-			if (first_playtone) {
+-				bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
+-								(u16) (pi->
+-									  nphy_rxcalparams
+-									  &
+-									  0xffff),
+-								0, 0, true);
+-				first_playtone = false;
+-			} else {
+-				phy_bw =
+-				    (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20;
+-				wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
+-							0, 0, 0, true);
+-			}
+-
+-			if (bcmerror == 0) {
+-				if (gain_pass < 3) {
+-
+-					wlc_phy_rx_iq_est_nphy(pi, est,
+-							       num_samps, 32,
+-							       0);
+-					i_pwr =
+-					    (est[rx_core].i_pwr +
+-					     num_samps / 2) / num_samps;
+-					q_pwr =
+-					    (est[rx_core].q_pwr +
+-					     num_samps / 2) / num_samps;
+-					tot_pwr[gain_pass] = i_pwr + q_pwr;
+-				} else {
+-
+-					wlc_phy_calc_rx_iq_comp_nphy(pi,
+-								     (1 <<
+-								      rx_core));
+-				}
+-
+-				wlc_phy_stopplayback_nphy(pi);
+-			}
+-
+-			if (bcmerror != 0)
+-				break;
+-		}
+-
+-		and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
+-		and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
+-
+-		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
+-			      0x92, orig_RfctrlIntcTx);
+-		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
+-			      0x92, orig_RfctrlIntcRx);
+-		write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
+-		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
+-			      0xa7, orig_AfectrlCore);
+-		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
+-
+-		if (bcmerror != 0)
+-			break;
+-	}
+-
+-	wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return bcmerror;
+-}
+-
+-int
+-wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-		      u8 cal_type, bool debug)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		cal_type = 0;
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
+-						  debug);
+-	} else {
+-		return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
+-	}
+-}
+-
+-static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j, type = 2;
+-	u16 addr_offset = 0x2c5;
+-
+-	for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-		write_phy_reg(pi, addr_offset + j,
+-			      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+-	}
+-}
+-
+-static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j, type;
+-	u16 addr_offset[] = { 0x186, 0x195,
+-		0x2c5
+-	};
+-
+-	for (type = 0; type < 3; type++) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, addr_offset[type] + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+-		}
+-	}
+-
+-	if (IS40MHZ(pi)) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x186 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+-		}
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, 0x186 + j,
+-					      NPHY_IPA_REV4_txdigi_filtcoeffs[5]
+-					      [j]);
+-			}
+-		}
+-
+-		if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, 0x2c5 + j,
+-					      NPHY_IPA_REV4_txdigi_filtcoeffs[6]
+-					      [j]);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j;
+-
+-	if (IS40MHZ(pi)) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x195 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
+-		}
+-	} else {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x186 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+-		}
+-	}
+-}
+-
+-static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi)
+-{
+-	u16 m0m1;
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+-
+-	return m0m1;
+-}
+-
+-static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1)
+-{
+-	u16 m0m1 = (u16) ((m0 << 8) | m1);
+-
+-	wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
+-	wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
+-}
+-
+-static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi)
+-{
+-	u32 *tx_pwrctrl_tbl = NULL;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			if ((pi->pubpi.radiorev == 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev4n6;
+-			} else if (pi->pubpi.radiorev == 3) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev3;
+-			} else if (pi->pubpi.radiorev == 5) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev5;
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev7;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
+-			if (pi->sh->chip == BCM47162_CHIP_ID) {
+-
+-				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+-		} else {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
+-		}
+-
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_5g_2057rev7;
+-			}
+-
+-		} else {
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
+-		}
+-	}
+-
+-	return tx_pwrctrl_tbl;
+-}
+-
+-static void
+-wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state,
+-			    u8 core)
+-{
+-	s32 tone_freq;
+-	u8 off_core;
+-	u16 mixgain = 0;
+-
+-	off_core = core ^ 0x1;
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->pubpi.radiorev == 5) {
+-				mixgain = (core == 0) ? 0x20 : 0x00;
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				mixgain = 0x00;
+-
+-			} else if ((pi->pubpi.radiorev <= 4)
+-				   || (pi->pubpi.radiorev == 6)) {
+-
+-				mixgain = 0x00;
+-			}
+-
+-		} else {
+-			if ((pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				mixgain = 0x50;
+-			} else if ((pi->pubpi.radiorev == 3)
+-				   || (pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				mixgain = 0x0;
+-			}
+-		}
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+-						  mixgain, (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+-						     1, (1 << core), 0);
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+-						     0, (1 << off_core), 0);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-						  0, (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xa6 : 0xa7);
+-		state->afeoverride[core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+-		state->afectrl[off_core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
+-		state->afeoverride[off_core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 2), 0);
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-				 0xa5), (0x1 << 2), (0x1 << 2));
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
+-			    (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
+-				 0x8f), (0x1 << 2), (0x1 << 2));
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			state->pwrup[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_2G_PWRUP);
+-			state->atten[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_2G_ATTEN);
+-			state->pwrup[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_2G_PWRUP);
+-			state->atten[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_2G_ATTEN);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TXRXCOUPLE_2G_PWRUP, 0xc);
+-
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN, 0xf0);
+-
+-			} else if (pi->pubpi.radiorev == 5) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN,
+-						 (core == 0) ? 0xf7 : 0xf2);
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN, 0xf0);
+-
+-			}
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_2G_PWRUP, 0x0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_2G_ATTEN, 0xff);
+-
+-		} else {
+-			state->pwrup[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_5G_PWRUP);
+-			state->atten[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_5G_ATTEN);
+-			state->pwrup[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_5G_PWRUP);
+-			state->atten[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_5G_ATTEN);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TXRXCOUPLE_5G_PWRUP, 0xc);
+-
+-			if ((pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN, 0xf4);
+-
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN, 0xf0);
+-			}
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_5G_PWRUP, 0x0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_5G_ATTEN, 0xff);
+-		}
+-
+-		tone_freq = 4000;
+-
+-		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (1) << 13);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-	} else {
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
+-
+-		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xa6 : 0xa7);
+-		state->afeoverride[core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-				 0xa5),
+-			    (0x1 << 0) |
+-			    (0x1 << 1) |
+-			    (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-
+-		state->vga_master[core] =
+-		    READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
+-		WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			state->fbmix[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+-					    TXFBMIX_G);
+-			state->intpa_master[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					    INTPAG_MASTER);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
+-					 0x03);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAG_MASTER, 0x04);
+-		} else {
+-			state->fbmix[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+-					    TXFBMIX_A);
+-			state->intpa_master[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					    INTPAA_MASTER);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
+-					 0x03);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_MASTER, 0x04);
+-
+-		}
+-
+-		tone_freq = 4000;
+-
+-		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+-	}
+-}
+-
+-static void
+-wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state)
+-{
+-	u8 core;
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_PWRUP, 0);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN,
+-						 state->atten[core]);
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_PWRUP, 0);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN,
+-						 state->atten[core]);
+-			}
+-		}
+-
+-		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  0, 0x3, 1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		}
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+-						  0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xa6 : 0xa7, state->afectrl[core]);
+-			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+-				      0xa5, state->afeoverride[core]);
+-		}
+-
+-		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+-					    (state->mm & 0xff));
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+-							  1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-	} else {
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
+-					 state->vga_master[core]);
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+-						 TXFBMIX_G, state->fbmix[core]);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_MASTER,
+-						 state->intpa_master[core]);
+-			} else {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+-						 TXFBMIX_A, state->fbmix[core]);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAA_MASTER,
+-						 state->intpa_master[core]);
+-			}
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xa6 : 0xa7, state->afectrl[core]);
+-			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+-				      0xa5, state->afeoverride[core]);
+-		}
+-
+-		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+-					    (state->mm & 0xff));
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
+-	}
+-}
+-
+-static void
+-wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start,
+-		u32 end)
+-{
+-	u32 *buf, *src, *dst, sz;
+-
+-	sz = end - start + 1;
+-
+-	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
+-	if (NULL == buf) {
+-		return;
+-	}
+-
+-	src = buf;
+-	dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
+-
+-	wlc_phy_table_read_nphy(pi,
+-				(core ==
+-				 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
+-				 NPHY_TBL_ID_EPSILONTBL1),
+-				NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
+-
+-	do {
+-		u32 phy_a1, phy_a2;
+-		s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
+-
+-		phy_a1 = end - min(end, (winsz >> 1));
+-		phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1));
+-		phy_a3 = phy_a2 - phy_a1 + 1;
+-		phy_a6 = 0;
+-		phy_a7 = 0;
+-
+-		do {
+-			wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
+-						    &phy_a5);
+-			phy_a6 += phy_a4;
+-			phy_a7 += phy_a5;
+-		} while (phy_a2-- != phy_a1);
+-
+-		phy_a6 /= phy_a3;
+-		phy_a7 /= phy_a3;
+-		dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
+-	} while (end-- != start);
+-
+-	wlc_phy_table_write_nphy(pi,
+-				 (core ==
+-				  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
+-				 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
+-
+-	kfree(buf);
+-}
+-
+-static void
+-wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains,
+-		phy_cal_mode_t cal_mode, u8 core)
+-{
+-	u16 phy_a1, phy_a2, phy_a3;
+-	u16 phy_a4, phy_a5;
+-	bool phy_a6;
+-	u8 phy_a7, m[2];
+-	u32 phy_a8 = 0;
+-	nphy_txgains_t phy_a9;
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 3))
+-		return;
+-
+-	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
+-
+-	phy_a6 = ((cal_mode == CAL_GCTRL)
+-		  || (cal_mode == CAL_SOFT)) ? true : false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			phy_a5 = ((phy_a9.txlpf[core] << 15) |
+-				  (phy_a9.txgm[core] << 12) |
+-				  (phy_a9.pga[core] << 8) |
+-				  (txgains->gains.pad[core] << 3) |
+-				  (phy_a9.ipa[core]));
+-		} else {
+-			phy_a5 = ((phy_a9.txlpf[core] << 15) |
+-				  (phy_a9.txgm[core] << 12) |
+-				  (txgains->gains.pga[core] << 8) |
+-				  (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
+-		}
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_txgain,
+-						     phy_a5, (1 << core), 0);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if ((pi->pubpi.radiorev <= 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-
+-				m[core] = IS40MHZ(pi) ? 60 : 79;
+-			} else {
+-
+-				m[core] = IS40MHZ(pi) ? 45 : 64;
+-			}
+-
+-		} else {
+-			m[core] = IS40MHZ(pi) ? 75 : 107;
+-		}
+-
+-		m[phy_a7] = 0;
+-		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+-
+-		phy_a2 = 63;
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->sh->chip == BCM6362_CHIP_ID) {
+-				phy_a1 = 35;
+-				phy_a3 = 35;
+-			} else if ((pi->pubpi.radiorev == 4)
+-				   || (pi->pubpi.radiorev == 6)) {
+-				phy_a1 = 30;
+-				phy_a3 = 30;
+-			} else {
+-				phy_a1 = 25;
+-				phy_a3 = 25;
+-			}
+-		} else {
+-			if ((pi->pubpi.radiorev == 5)
+-			    || (pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-				phy_a1 = 25;
+-				phy_a3 = 25;
+-			} else {
+-				phy_a1 = 35;
+-				phy_a3 = 35;
+-			}
+-		}
+-
+-		if (cal_mode == CAL_GCTRL) {
+-			if ((pi->pubpi.radiorev == 5)
+-			    && (CHSPEC_IS2G(pi->radio_chanspec))) {
+-				phy_a1 = 55;
+-			} else if (((pi->pubpi.radiorev == 7) &&
+-				    (CHSPEC_IS2G(pi->radio_chanspec))) ||
+-				   ((pi->pubpi.radiorev == 8) &&
+-				    (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-				phy_a1 = 60;
+-			} else {
+-				phy_a1 = 63;
+-			}
+-
+-		} else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
+-
+-			phy_a1 = 35;
+-			phy_a3 = 35;
+-		}
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (1) << 13);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-		write_phy_reg(pi, 0x2a1, 0x80);
+-		write_phy_reg(pi, 0x2a2, 0x100);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 4), (11) << 4);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 8), (11) << 8);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 0), (0x3) << 0);
+-
+-		write_phy_reg(pi, 0x2e5, 0x20);
+-
+-		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  1, ((core == 0) ? 1 : 2), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, ((core == 0) ? 2 : 1), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		write_phy_reg(pi, 0x2be, 1);
+-		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		wlc_phy_table_write_nphy(pi,
+-					 (core ==
+-					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+-					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+-					 32, &phy_a8);
+-
+-		if (cal_mode != CAL_GCTRL) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				wlc_phy_a1_nphy(pi, core, 5, 0, 35);
+-			}
+-		}
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_txgain,
+-						     phy_a5, (1 << core), 1);
+-
+-	} else {
+-
+-		if (txgains) {
+-			if (txgains->useindex) {
+-				phy_a4 = 15 - ((txgains->index) >> 3);
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-						phy_a5 = 0x00f7 | (phy_a4 << 8);
+-
+-						if (pi->sh->chip ==
+-						    BCM47162_CHIP_ID) {
+-							phy_a5 =
+-							    0x10f7 | (phy_a4 <<
+-								      8);
+-						}
+-					} else
+-					    if (NREV_IS(pi->pubpi.phy_rev, 5))
+-						phy_a5 = 0x10f7 | (phy_a4 << 8);
+-					else
+-						phy_a5 = 0x50f7 | (phy_a4 << 8);
+-				} else {
+-					phy_a5 = 0x70f7 | (phy_a4 << 8);
+-				}
+-				wlc_phy_rfctrl_override_nphy(pi,
+-							     (0x1 << 13),
+-							     phy_a5,
+-							     (1 << core), 0);
+-			} else {
+-				wlc_phy_rfctrl_override_nphy(pi,
+-							     (0x1 << 13),
+-							     0x5bf7,
+-							     (1 << core), 0);
+-			}
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			m[core] = IS40MHZ(pi) ? 45 : 64;
+-		} else {
+-			m[core] = IS40MHZ(pi) ? 75 : 107;
+-		}
+-
+-		m[phy_a7] = 0;
+-		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+-
+-		phy_a2 = 63;
+-
+-		if (cal_mode == CAL_FULL) {
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		} else if (cal_mode == CAL_SOFT) {
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		} else if (cal_mode == CAL_GCTRL) {
+-			phy_a1 = 63;
+-			phy_a3 = 25;
+-		} else {
+-
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		}
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 13), (1) << 13);
+-
+-			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 13), (0) << 13);
+-
+-			write_phy_reg(pi, 0x2a1, 0x20);
+-			write_phy_reg(pi, 0x2a2, 0x60);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 4), (9) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 8), (9) << 8);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 0), (0x2) << 0);
+-
+-			write_phy_reg(pi, 0x2e5, 0x20);
+-		} else {
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 11), (1) << 11);
+-
+-			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 11), (0) << 11);
+-
+-			write_phy_reg(pi, 0x2a1, 0x80);
+-			write_phy_reg(pi, 0x2a2, 0x600);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 4), (0) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 8), (0) << 8);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 0), (0x3) << 0);
+-
+-			mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
+-
+-		}
+-
+-		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
+-
+-		write_phy_reg(pi, 0x2be, 1);
+-		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+-
+-		wlc_phy_table_write_nphy(pi,
+-					 (core ==
+-					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+-					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+-					 32, &phy_a8);
+-
+-		if (cal_mode != CAL_GCTRL) {
+-			wlc_phy_a1_nphy(pi, core, 5, 0, 40);
+-		}
+-	}
+-}
+-
+-static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core)
+-{
+-	int phy_a1;
+-	int phy_a2;
+-	bool phy_a3;
+-	nphy_ipa_txcalgains_t phy_a4;
+-	bool phy_a5 = false;
+-	bool phy_a6 = true;
+-	s32 phy_a7, phy_a8;
+-	u32 phy_a9;
+-	int phy_a10;
+-	bool phy_a11 = false;
+-	int phy_a12;
+-	u8 phy_a13 = 0;
+-	u8 phy_a14;
+-	u8 *phy_a15 = NULL;
+-
+-	phy_a4.useindex = true;
+-	phy_a12 = start_gain;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		phy_a2 = 20;
+-		phy_a1 = 1;
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				phy_a15 = pad_gain_codes_used_2057rev5;
+-				phy_a13 = sizeof(pad_gain_codes_used_2057rev5) /
+-				    sizeof(pad_gain_codes_used_2057rev5[0]) - 1;
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				phy_a15 = pad_gain_codes_used_2057rev7;
+-				phy_a13 = sizeof(pad_gain_codes_used_2057rev7) /
+-				    sizeof(pad_gain_codes_used_2057rev7[0]) - 1;
+-
+-			} else {
+-
+-				phy_a15 = pad_all_gain_codes_2057;
+-				phy_a13 = sizeof(pad_all_gain_codes_2057) /
+-				    sizeof(pad_all_gain_codes_2057[0]) - 1;
+-			}
+-
+-		} else {
+-
+-			phy_a15 = pga_all_gain_codes_2057;
+-			phy_a13 = sizeof(pga_all_gain_codes_2057) /
+-			    sizeof(pga_all_gain_codes_2057[0]) - 1;
+-		}
+-
+-		phy_a14 = 0;
+-
+-		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_a4.gains.pad[core] =
+-				    (u16) phy_a15[phy_a12];
+-			} else {
+-				phy_a4.gains.pga[core] =
+-				    (u16) phy_a15[phy_a12];
+-			}
+-
+-			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+-
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_EPSILONTBL0 :
+-						 NPHY_TBL_ID_EPSILONTBL1), 1,
+-						63, 32, &phy_a9);
+-
+-			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+-
+-			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+-				  (phy_a8 == 4095) || (phy_a8 == -4096));
+-
+-			if (!phy_a6 && (phy_a3 != phy_a5)) {
+-				if (!phy_a3) {
+-					phy_a12 -= (u8) phy_a1;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			if (phy_a3)
+-				phy_a12 += (u8) phy_a1;
+-			else
+-				phy_a12 -= (u8) phy_a1;
+-
+-			if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
+-				if (phy_a12 < phy_a14) {
+-					phy_a12 = phy_a14;
+-				} else {
+-					phy_a12 = phy_a13;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			phy_a6 = false;
+-			phy_a5 = phy_a3;
+-		}
+-
+-	} else {
+-		phy_a2 = 10;
+-		phy_a1 = 8;
+-		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+-			phy_a4.index = (u8) phy_a12;
+-			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+-
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_EPSILONTBL0 :
+-						 NPHY_TBL_ID_EPSILONTBL1), 1,
+-						63, 32, &phy_a9);
+-
+-			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+-
+-			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+-				  (phy_a8 == 4095) || (phy_a8 == -4096));
+-
+-			if (!phy_a6 && (phy_a3 != phy_a5)) {
+-				if (!phy_a3) {
+-					phy_a12 -= (u8) phy_a1;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			if (phy_a3)
+-				phy_a12 += (u8) phy_a1;
+-			else
+-				phy_a12 -= (u8) phy_a1;
+-
+-			if ((phy_a12 < 0) || (phy_a12 > 127)) {
+-				if (phy_a12 < 0) {
+-					phy_a12 = 0;
+-				} else {
+-					phy_a12 = 127;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			phy_a6 = false;
+-			phy_a5 = phy_a3;
+-		}
+-
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		return (u8) phy_a15[phy_a12];
+-	} else {
+-		return (u8) phy_a12;
+-	}
+-
+-}
+-
+-static void wlc_phy_a4(phy_info_t *pi, bool full_cal)
+-{
+-	nphy_ipa_txcalgains_t phy_b1[2];
+-	nphy_papd_restore_state phy_b2;
+-	bool phy_b3;
+-	u8 phy_b4;
+-	u8 phy_b5;
+-	s16 phy_b6, phy_b7, phy_b8;
+-	u16 phy_b9;
+-	s16 phy_b10, phy_b11, phy_b12;
+-
+-	phy_b11 = 0;
+-	phy_b12 = 0;
+-	phy_b7 = 0;
+-	phy_b8 = 0;
+-	phy_b6 = 0;
+-
+-	if (pi->nphy_papd_skip == 1)
+-		return;
+-
+-	phy_b3 =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!phy_b3) {
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	pi->nphy_force_papd_cal = false;
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
+-		pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
+-		    wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
+-
+-	pi->nphy_papd_last_cal = pi->sh->now;
+-	pi->nphy_papd_recal_counter++;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	phy_b4 = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
+-				 nphy_papd_scaltbl);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
+-				 nphy_papd_scaltbl);
+-
+-	phy_b9 = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		s32 i, val = 0;
+-		for (i = 0; i < 64; i++) {
+-			wlc_phy_table_write_nphy(pi,
+-						 ((phy_b5 ==
+-						   PHY_CORE_0) ?
+-						  NPHY_TBL_ID_EPSILONTBL0 :
+-						  NPHY_TBL_ID_EPSILONTBL1), 1,
+-						 i, 32, &val);
+-		}
+-	}
+-
+-	wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
+-
+-	phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-				if ((pi->pubpi.radiorev == 3)
+-				    || (pi->pubpi.radiorev == 4)
+-				    || (pi->pubpi.radiorev == 6)) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    23;
+-
+-				} else if (pi->pubpi.radiorev == 5) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    0;
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    wlc_phy_a3_nphy(pi,
+-							    pi->
+-							    nphy_papd_cal_gain_index
+-							    [phy_b5], phy_b5);
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    0;
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    wlc_phy_a3_nphy(pi,
+-							    pi->
+-							    nphy_papd_cal_gain_index
+-							    [phy_b5], phy_b5);
+-
+-				}
+-
+-				phy_b1[phy_b5].gains.pad[phy_b5] =
+-				    pi->nphy_papd_cal_gain_index[phy_b5];
+-
+-			} else {
+-				pi->nphy_papd_cal_gain_index[phy_b5] = 0;
+-				pi->nphy_papd_cal_gain_index[phy_b5] =
+-				    wlc_phy_a3_nphy(pi,
+-						    pi->
+-						    nphy_papd_cal_gain_index
+-						    [phy_b5], phy_b5);
+-				phy_b1[phy_b5].gains.pga[phy_b5] =
+-				    pi->nphy_papd_cal_gain_index[phy_b5];
+-			}
+-		} else {
+-			phy_b1[phy_b5].useindex = true;
+-			phy_b1[phy_b5].index = 16;
+-			phy_b1[phy_b5].index =
+-			    wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5);
+-
+-			pi->nphy_papd_cal_gain_index[phy_b5] =
+-			    15 - ((phy_b1[phy_b5].index) >> 3);
+-		}
+-
+-		switch (pi->nphy_papd_cal_type) {
+-		case 0:
+-			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
+-			break;
+-		case 1:
+-			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
+-			break;
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+-		}
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+-	}
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		int eps_offset = 0;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev == 3) {
+-					eps_offset = -2;
+-				} else if (pi->pubpi.radiorev == 5) {
+-					eps_offset = 3;
+-				} else {
+-					eps_offset = -1;
+-				}
+-			} else {
+-				eps_offset = 2;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
+-				phy_b10 = 0;
+-				if ((pi->pubpi.radiorev == 3) ||
+-				    (pi->pubpi.radiorev == 4) ||
+-				    (pi->pubpi.radiorev == 6)) {
+-					phy_b12 =
+-					    -
+-					    (nphy_papd_padgain_dlt_2g_2057rev3n4
+-					     [phy_b8]
+-					     + 1) / 2;
+-					phy_b10 = -1;
+-				} else if (pi->pubpi.radiorev == 5) {
+-					phy_b12 =
+-					    -(nphy_papd_padgain_dlt_2g_2057rev5
+-					      [phy_b8]
+-					      + 1) / 2;
+-				} else if ((pi->pubpi.radiorev == 7) ||
+-					   (pi->pubpi.radiorev == 8)) {
+-					phy_b12 =
+-					    -(nphy_papd_padgain_dlt_2g_2057rev7
+-					      [phy_b8]
+-					      + 1) / 2;
+-				}
+-			} else {
+-				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
+-				if ((pi->pubpi.radiorev == 3) ||
+-				    (pi->pubpi.radiorev == 4) ||
+-				    (pi->pubpi.radiorev == 6)) {
+-					phy_b11 =
+-					    -(nphy_papd_pgagain_dlt_5g_2057
+-					      [phy_b7]
+-					      + 1) / 2;
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-					phy_b11 =
+-					    -(nphy_papd_pgagain_dlt_5g_2057rev7
+-					      [phy_b7]
+-					      + 1) / 2;
+-				}
+-
+-				phy_b10 = -9;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b6 =
+-				    -60 + 27 + eps_offset + phy_b12 + phy_b10;
+-			} else {
+-				phy_b6 =
+-				    -60 + 27 + eps_offset + phy_b11 + phy_b10;
+-			}
+-
+-			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7), (phy_b6) << 7);
+-
+-			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+-		} else {
+-			if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-				eps_offset = 4;
+-			} else {
+-				eps_offset = 2;
+-			}
+-
+-			phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b11 =
+-				    -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] +
+-				      1) / 2;
+-				phy_b10 = 0;
+-			} else {
+-				phy_b11 =
+-				    -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] +
+-				      1) / 2;
+-				phy_b10 = -9;
+-			}
+-
+-			phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
+-
+-			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7), (phy_b6) << 7);
+-
+-			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+-		}
+-	}
+-
+-	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-	} else {
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 11), (0) << 11);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 11), (0) << 11);
+-
+-	}
+-	pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
+-
+-	write_phy_reg(pi, 0x01, phy_b9);
+-
+-	wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
+-	if (phy_b4 == PHY_TPC_HW_OFF) {
+-		wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+-					 (s8) (pi->nphy_txpwrindex[0].
+-						 index_internal), false);
+-		wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+-					 (s8) (pi->nphy_txpwrindex[1].
+-						 index_internal), false);
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	if (!phy_b3) {
+-		wlapi_enable_mac(pi->sh->physhim);
+-	}
+-}
+-
+-void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi)
+-{
+-	uint core;
+-	u32 txgain;
+-	u16 rad_gain, dac_gain, bbmult, m1m2;
+-	u8 txpi[2], chan_freq_range;
+-	s32 rfpwr_offset;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (pi->sh->sromrev < 4) {
+-		txpi[0] = txpi[1] = 72;
+-	} else {
+-
+-		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-		switch (chan_freq_range) {
+-		case WL_CHAN_FREQ_RANGE_2G:
+-			txpi[0] = pi->nphy_txpid2g[0];
+-			txpi[1] = pi->nphy_txpid2g[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GL:
+-			txpi[0] = pi->nphy_txpid5gl[0];
+-			txpi[1] = pi->nphy_txpid5gl[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GM:
+-			txpi[0] = pi->nphy_txpid5g[0];
+-			txpi[1] = pi->nphy_txpid5g[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GH:
+-			txpi[0] = pi->nphy_txpid5gh[0];
+-			txpi[1] = pi->nphy_txpid5gh[1];
+-			break;
+-		default:
+-			txpi[0] = txpi[1] = 91;
+-			break;
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		txpi[0] = txpi[1] = 30;
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		txpi[0] = txpi[1] = 40;
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		if ((txpi[0] < 40) || (txpi[0] > 100) ||
+-		    (txpi[1] < 40) || (txpi[1] > 100))
+-			txpi[0] = txpi[1] = 91;
+-	}
+-
+-	pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
+-	pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
+-	pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
+-	pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (PHY_IPA(pi)) {
+-				u32 *tx_gaintbl =
+-				    wlc_phy_get_ipa_gaintbl_nphy(pi);
+-				txgain = tx_gaintbl[txpi[core]];
+-			} else {
+-				if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-					if NREV_IS
+-						(pi->pubpi.phy_rev, 3) {
+-						txgain =
+-						    nphy_tpc_5GHz_txgain_rev3
+-						    [txpi[core]];
+-					} else if NREV_IS
+-						(pi->pubpi.phy_rev, 4) {
+-						txgain =
+-						    (pi->srom_fem5g.extpagain ==
+-						     3) ?
+-						    nphy_tpc_5GHz_txgain_HiPwrEPA
+-						    [txpi[core]] :
+-						    nphy_tpc_5GHz_txgain_rev4
+-						    [txpi[core]];
+-					} else {
+-						txgain =
+-						    nphy_tpc_5GHz_txgain_rev5
+-						    [txpi[core]];
+-					}
+-				} else {
+-					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-					    (pi->srom_fem2g.extpagain == 3)) {
+-						txgain =
+-						    nphy_tpc_txgain_HiPwrEPA
+-						    [txpi[core]];
+-					} else {
+-						txgain =
+-						    nphy_tpc_txgain_rev3[txpi
+-									 [core]];
+-					}
+-				}
+-			}
+-		} else {
+-			txgain = nphy_tpc_txgain[txpi[core]];
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+-		} else {
+-			rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
+-		} else {
+-			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+-		}
+-		bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-					 0xa5), (0x1 << 8), (0x1 << 8));
+-		} else {
+-			mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+-		}
+-		write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
+-
+-		wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-					 &rad_gain);
+-
+-		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-		m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-		m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+-		wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_CORE1TXPWRCTL :
+-						 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
+-						576 + txpi[core], 32,
+-						&rfpwr_offset);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1ff << 4),
+-				    ((s16) rfpwr_offset) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (1) << 2);
+-
+-		}
+-	}
+-
+-	and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void
+-wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
+-				u8 tmp_max_pwr, u8 rate_start,
+-				u8 rate_end)
+-{
+-	u8 rate;
+-	u8 word_num, nibble_num;
+-	u8 tmp_nibble;
+-
+-	for (rate = rate_start; rate <= rate_end; rate++) {
+-		word_num = (rate - rate_start) >> 2;
+-		nibble_num = (rate - rate_start) & 0x3;
+-		tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
+-
+-		srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
+-	}
+-}
+-
+-static void
+-wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
+-			    u8 rate_start, u8 rate_end)
+-{
+-	u8 rate;
+-
+-	for (rate = rate_start; rate <= rate_end; rate++) {
+-		srom_max[rate] -= 2 * pwr_offset;
+-	}
+-}
+-
+-void
+-wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
+-				u8 rate_mcs_end, u8 rate_ofdm_start)
+-{
+-	u8 rate1, rate2;
+-
+-	rate2 = rate_ofdm_start;
+-	for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
+-		power[rate1] = power[rate2];
+-		rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
+-	}
+-	power[rate_mcs_end] = power[rate_mcs_end - 1];
+-}
+-
+-void
+-wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
+-				u8 rate_ofdm_end, u8 rate_mcs_start)
+-{
+-	u8 rate1, rate2;
+-
+-	for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
+-	     rate1 <= rate_ofdm_end; rate1++, rate2++) {
+-		power[rate1] = power[rate2];
+-		if (rate1 == rate_ofdm_start)
+-			power[++rate1] = power[rate2];
+-	}
+-}
+-
+-void wlc_phy_txpwr_apply_nphy(phy_info_t *pi)
+-{
+-	uint rate1, rate2, band_num;
+-	u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
+-	u8 tmp_max_pwr = 0;
+-	u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
+-	u8 *tx_srom_max_rate = NULL;
+-
+-	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+-		switch (band_num) {
+-		case 0:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_2g);
+-
+-			pwr_offsets1[0] = pi->cck2gpo;
+-			wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
+-							pwr_offsets1,
+-							tmp_max_pwr,
+-							TXP_FIRST_CCK,
+-							TXP_LAST_CCK);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm2gpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs2gpo;
+-
+-			tmp_cddpo = pi->cdd2gpo;
+-			tmp_stbcpo = pi->stbc2gpo;
+-			tmp_bw40po = pi->bw402gpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_2g;
+-			break;
+-		case 1:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gm);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5gpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5gpo;
+-
+-			tmp_cddpo = pi->cdd5gpo;
+-			tmp_stbcpo = pi->stbc5gpo;
+-			tmp_bw40po = pi->bw405gpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
+-			break;
+-		case 2:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gl);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5glpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5glpo;
+-
+-			tmp_cddpo = pi->cdd5glpo;
+-			tmp_stbcpo = pi->stbc5glpo;
+-			tmp_bw40po = pi->bw405glpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
+-			break;
+-		case 3:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gh);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5ghpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5ghpo;
+-
+-			tmp_cddpo = pi->cdd5ghpo;
+-			tmp_stbcpo = pi->stbc5ghpo;
+-			tmp_bw40po = pi->bw405ghpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
+-			break;
+-		}
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
+-						tmp_max_pwr, TXP_FIRST_OFDM,
+-						TXP_LAST_OFDM);
+-
+-		wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
+-						TXP_FIRST_MCS_20_SISO,
+-						TXP_LAST_MCS_20_SISO,
+-						TXP_FIRST_OFDM);
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+-						tmp_max_pwr,
+-						TXP_FIRST_MCS_20_CDD,
+-						TXP_LAST_MCS_20_CDD);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+-						    TXP_FIRST_MCS_20_CDD,
+-						    TXP_LAST_MCS_20_CDD);
+-		}
+-
+-		wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-						TXP_FIRST_OFDM_20_CDD,
+-						TXP_LAST_OFDM_20_CDD,
+-						TXP_FIRST_MCS_20_CDD);
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+-						tmp_max_pwr,
+-						TXP_FIRST_MCS_20_STBC,
+-						TXP_LAST_MCS_20_STBC);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_stbcpo,
+-						    TXP_FIRST_MCS_20_STBC,
+-						    TXP_LAST_MCS_20_STBC);
+-		}
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-						&pwr_offsets2[2], tmp_max_pwr,
+-						TXP_FIRST_MCS_20_SDM,
+-						TXP_LAST_MCS_20_SDM);
+-
+-		if (NPHY_IS_SROM_REINTERPRET) {
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_SISO,
+-							TXP_LAST_MCS_40_SISO);
+-
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-							TXP_FIRST_OFDM_40_SISO,
+-							TXP_LAST_OFDM_40_SISO,
+-							TXP_FIRST_MCS_40_SISO);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_CDD,
+-							TXP_LAST_MCS_40_CDD);
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+-						    TXP_FIRST_MCS_40_CDD,
+-						    TXP_LAST_MCS_40_CDD);
+-
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-							TXP_FIRST_OFDM_40_CDD,
+-							TXP_LAST_OFDM_40_CDD,
+-							TXP_FIRST_MCS_40_CDD);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_STBC,
+-							TXP_LAST_MCS_40_STBC);
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_stbcpo,
+-						    TXP_FIRST_MCS_40_STBC,
+-						    TXP_LAST_MCS_40_STBC);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[6],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_SDM,
+-							TXP_LAST_MCS_40_SDM);
+-		} else {
+-
+-			for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
+-			     TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM;
+-			     rate1++, rate2++)
+-				tx_srom_max_rate[rate1] =
+-				    tx_srom_max_rate[rate2];
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_bw40po,
+-						    TXP_FIRST_OFDM_40_SISO,
+-						    TXP_LAST_MCS_40_SDM);
+-		}
+-
+-		tx_srom_max_rate[TXP_MCS_32] =
+-		    tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
+-	}
+-
+-	return;
+-}
+-
+-static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi)
+-{
+-	u16 bw40po, cddpo, stbcpo, bwduppo;
+-	uint band_num;
+-
+-	if (pi->sh->sromrev >= 9) {
+-
+-		return;
+-	}
+-
+-	bw40po = (u16) PHY_GETINTVAR(pi, "bw40po");
+-	pi->bw402gpo = bw40po & 0xf;
+-	pi->bw405gpo = (bw40po & 0xf0) >> 4;
+-	pi->bw405glpo = (bw40po & 0xf00) >> 8;
+-	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
+-
+-	cddpo = (u16) PHY_GETINTVAR(pi, "cddpo");
+-	pi->cdd2gpo = cddpo & 0xf;
+-	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
+-	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
+-	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
+-
+-	stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo");
+-	pi->stbc2gpo = stbcpo & 0xf;
+-	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
+-	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
+-	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
+-
+-	bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo");
+-	pi->bwdup2gpo = bwduppo & 0xf;
+-	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
+-	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
+-	pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
+-
+-	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+-		switch (band_num) {
+-		case 0:
+-
+-			pi->nphy_txpid2g[PHY_CORE_0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid2ga0");
+-			pi->nphy_txpid2g[PHY_CORE_1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid2ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
+-			    (s8) PHY_GETINTVAR(pi, "maxp2ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
+-			    (s8) PHY_GETINTVAR(pi, "maxp2ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw0a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw0a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw1a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw1a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw2a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw2a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
+-			    (s8) PHY_GETINTVAR(pi, "itt2ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
+-			    (s8) PHY_GETINTVAR(pi, "itt2ga1");
+-
+-			pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
+-
+-			pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-
+-			pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
+-			pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1");
+-			pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2");
+-			pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3");
+-			pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4");
+-			pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5");
+-			pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6");
+-			pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7");
+-			break;
+-		case 1:
+-
+-			pi->nphy_txpid5g[PHY_CORE_0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5ga0");
+-			pi->nphy_txpid5g[PHY_CORE_1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw0a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw0a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw1a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw1a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw2a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw2a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "itt5ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "itt5ga1");
+-
+-			pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo");
+-
+-			pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0");
+-			pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1");
+-			pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2");
+-			pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3");
+-			pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4");
+-			pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5");
+-			pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6");
+-			pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7");
+-			break;
+-		case 2:
+-
+-			pi->nphy_txpid5gl[0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gla0");
+-			pi->nphy_txpid5gl[1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gla1");
+-			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gla0");
+-			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gla1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw0a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw0a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw1a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw1a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw2a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw2a1");
+-			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
+-			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
+-
+-			pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo");
+-
+-			pi->mcs5glpo[0] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo0");
+-			pi->mcs5glpo[1] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo1");
+-			pi->mcs5glpo[2] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo2");
+-			pi->mcs5glpo[3] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo3");
+-			pi->mcs5glpo[4] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo4");
+-			pi->mcs5glpo[5] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo5");
+-			pi->mcs5glpo[6] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo6");
+-			pi->mcs5glpo[7] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo7");
+-			break;
+-		case 3:
+-
+-			pi->nphy_txpid5gh[0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gha0");
+-			pi->nphy_txpid5gh[1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gha1");
+-			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gha0");
+-			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gha1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw0a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw0a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw1a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw1a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw2a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw2a1");
+-			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
+-			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
+-
+-			pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo");
+-
+-			pi->mcs5ghpo[0] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo0");
+-			pi->mcs5ghpo[1] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo1");
+-			pi->mcs5ghpo[2] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo2");
+-			pi->mcs5ghpo[3] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo3");
+-			pi->mcs5ghpo[4] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo4");
+-			pi->mcs5ghpo[5] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo5");
+-			pi->mcs5ghpo[6] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo6");
+-			pi->mcs5ghpo[7] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo7");
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_txpwr_apply_nphy(pi);
+-}
+-
+-static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi)
+-{
+-
+-	pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch");
+-	pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g");
+-	pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g");
+-
+-	pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g");
+-	pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g");
+-	pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g");
+-	pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g");
+-	pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g");
+-
+-	pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g");
+-	pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g");
+-	pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g");
+-	pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g");
+-	if (PHY_GETVAR(pi, "antswctl5g")) {
+-
+-		pi->srom_fem5g.antswctrllut =
+-		    (u8) PHY_GETINTVAR(pi, "antswctl5g");
+-	} else {
+-
+-		pi->srom_fem5g.antswctrllut =
+-		    (u8) PHY_GETINTVAR(pi, "antswctl2g");
+-	}
+-
+-	wlc_phy_txpower_ipa_upd(pi);
+-
+-	pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh");
+-	if (pi->phy_txcore_disable_temp == 0) {
+-		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+-	}
+-
+-	pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset");
+-	if (pi->phy_tempsense_offset != 0) {
+-		if (pi->phy_tempsense_offset >
+-		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) {
+-			pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
+-		} else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
+-						    NPHY_SROM_MINTEMPOFFSET)) {
+-			pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
+-		} else {
+-			pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
+-		}
+-	}
+-
+-	pi->phy_txcore_enable_temp =
+-	    pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
+-
+-	pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta");
+-	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) {
+-		pi->phycal_tempdelta = 0;
+-	}
+-
+-	wlc_phy_txpwr_srom_read_ppr_nphy(pi);
+-
+-	return true;
+-}
+-
+-void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi)
+-{
+-	u8 tx_pwr_ctrl_state;
+-	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+-	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-}
+-
+-static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi)
+-{
+-	u32 idx;
+-	u16 iqloCalbuf[7];
+-	u32 iqcomp, locomp, curr_locomp;
+-	s8 locomp_i, locomp_q;
+-	s8 curr_locomp_i, curr_locomp_q;
+-	u32 tbl_id, tbl_len, tbl_offset;
+-	u32 regval[128];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
+-
+-	tbl_len = 128;
+-	tbl_offset = 320;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-		iqcomp =
+-		    (tbl_id ==
+-		     26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
+-		    (iqloCalbuf[1] & 0x3ff)
+-		    : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
+-		    (iqloCalbuf[3] & 0x3ff);
+-
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			regval[idx] = iqcomp;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	tbl_offset = 448;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-
+-		locomp =
+-		    (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
+-		locomp_i = (s8) ((locomp >> 8) & 0xff);
+-		locomp_q = (s8) ((locomp) & 0xff);
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				curr_locomp_i = locomp_i;
+-				curr_locomp_q = locomp_q;
+-			} else {
+-				curr_locomp_i = (s8) ((locomp_i *
+-							 nphy_tpc_loscale[idx] +
+-							 128) >> 8);
+-				curr_locomp_q =
+-				    (s8) ((locomp_q * nphy_tpc_loscale[idx] +
+-					     128) >> 8);
+-			}
+-			curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
+-			curr_locomp |= (u32) (curr_locomp_q & 0xff);
+-			regval[idx] = curr_locomp;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi)
+-{
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x5);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MUX, 0xe);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIA, 0);
+-
+-				if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIG, 0x1);
+-				} else {
+-
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIG, 0x31);
+-				}
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x9);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MUX, 0xc);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIG, 0);
+-
+-				if (pi->pubpi.radiorev != 5) {
+-					if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x1);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x31);
+-					}
+-				}
+-			}
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+-					 0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+-					 0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+-					 0x3);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+-					 0x0);
+-		}
+-	} else {
+-		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
+-				(CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
+-				0x80);
+-		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
+-		WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
+-					 0x3);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
+-					 0x8);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
+-					 0x0);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MASTER, 0x5);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIA, 0x0);
+-				if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIG, 0x31);
+-				} else {
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIG, 0x11);
+-				}
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MUX, 0xe);
+-			} else {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MASTER, 0x9);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TSSIA, 0x31);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TSSIG, 0x0);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MUX, 0xc);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi)
+-{
+-	s32 rssi_buf[4];
+-	s32 int_val;
+-
+-	if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
+-
+-		return;
+-
+-	if (PHY_IPA(pi)) {
+-		wlc_phy_ipa_internal_tssi_setup_nphy(pi);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
+-	}
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
+-
+-	udelay(20);
+-	int_val =
+-	    wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
+-				   1);
+-	wlc_phy_stopplayback_nphy(pi);
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-						  0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-	} else {
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+-		    (u8) ((int_val >> 16) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+-		    (u8) ((int_val) & 0xff);
+-	}
+-
+-}
+-
+-static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi)
+-{
+-	u32 idx;
+-	s16 a1[2], b0[2], b1[2];
+-	s8 target_pwr_qtrdbm[2];
+-	s32 num, den, pwr_est;
+-	u8 chan_freq_range;
+-	u8 idle_tssi[2];
+-	u32 tbl_id, tbl_len, tbl_offset;
+-	u32 regval[64];
+-	u8 core;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	or_phy_reg(pi, 0x122, (0x1 << 0));
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
+-	} else {
+-
+-		or_phy_reg(pi, 0x1e7, (0x1 << 15));
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-
+-	if (pi->sh->sromrev < 4) {
+-		idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-		idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-		target_pwr_qtrdbm[0] = 13 * 4;
+-		target_pwr_qtrdbm[1] = 13 * 4;
+-		a1[0] = -424;
+-		a1[1] = -424;
+-		b0[0] = 5612;
+-		b0[1] = 5612;
+-		b1[1] = -1393;
+-		b1[0] = -1393;
+-	} else {
+-
+-		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-		switch (chan_freq_range) {
+-		case WL_CHAN_FREQ_RANGE_2G:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_2g;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_2g;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GL:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gl;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gl;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GM:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gm;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gm;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GH:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gh;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gh;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
+-			break;
+-		default:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-			target_pwr_qtrdbm[0] = 13 * 4;
+-			target_pwr_qtrdbm[1] = 13 * 4;
+-			a1[0] = -424;
+-			a1[1] = -424;
+-			b0[0] = 5612;
+-			b0[1] = 5612;
+-			b1[1] = -1393;
+-			b1[0] = -1393;
+-			break;
+-		}
+-	}
+-
+-	target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
+-	target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (pi->srom_fem2g.tssipos) {
+-			or_phy_reg(pi, 0x1e9, (0x1 << 14));
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			for (core = 0; core <= 1; core++) {
+-				if (PHY_IPA(pi)) {
+-
+-					if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TX_SSI_MUX,
+-								 0xe);
+-					} else {
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TX_SSI_MUX,
+-								 0xc);
+-					}
+-				} else {
+-				}
+-			}
+-		} else {
+-			if (PHY_IPA(pi)) {
+-
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX0,
+-						(CHSPEC_IS5G
+-						 (pi->
+-						  radio_chanspec)) ? 0xc : 0xe);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX1,
+-						(CHSPEC_IS5G
+-						 (pi->
+-						  radio_chanspec)) ? 0xc : 0xe);
+-			} else {
+-
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX0, 0x11);
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX1, 0x11);
+-			}
+-		}
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+-	} else {
+-		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, 0x222, (0xff << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+-	} else if (NREV_GT(pi->pubpi.phy_rev, 1)) {
+-		mod_phy_reg(pi, 0x222, (0xff << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-
+-	write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
+-
+-	write_phy_reg(pi, 0x1e9,
+-		      (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
+-
+-	write_phy_reg(pi, 0x1ea,
+-		      (target_pwr_qtrdbm[0] << 0) |
+-		      (target_pwr_qtrdbm[1] << 8));
+-
+-	tbl_len = 64;
+-	tbl_offset = 0;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			num =
+-			    8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
+-			den = 32768 + a1[tbl_id - 26] * idx;
+-			pwr_est = max(((4 * num + den / 2) / den), -8);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-				if (idx <=
+-				    (uint) (31 - idle_tssi[tbl_id - 26] + 1))
+-					pwr_est =
+-					    max(pwr_est,
+-						target_pwr_qtrdbm[tbl_id - 26] +
+-						1);
+-			}
+-			regval[idx] = (u32) pwr_est;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
+-				 pi->adj_pwr_tbl_nphy);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
+-				 pi->adj_pwr_tbl_nphy);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi)
+-{
+-	return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
+-					     (0x1 << 14) | (0x1 << 13));
+-}
+-
+-static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core)
+-{
+-	u16 tmp;
+-	tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
+-
+-	tmp = (tmp & (0x7f << 8)) >> 8;
+-	return (u8) tmp;
+-}
+-
+-static void
+-wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1)
+-{
+-	mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
+-
+-	if (NREV_GT(pi->pubpi.phy_rev, 1))
+-		mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
+-}
+-
+-u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi)
+-{
+-	u16 tmp;
+-	u16 pwr_idx[2];
+-
+-	if (wlc_phy_txpwr_ison_nphy(pi)) {
+-		pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
+-		pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
+-
+-		tmp = (pwr_idx[0] << 8) | pwr_idx[1];
+-	} else {
+-		tmp =
+-		    ((pi->nphy_txpwrindex[PHY_CORE_0].
+-		      index_internal & 0xff) << 8) | (pi->
+-						      nphy_txpwrindex
+-						      [PHY_CORE_1].
+-						      index_internal & 0xff);
+-	}
+-
+-	return tmp;
+-}
+-
+-void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi)
+-{
+-	if (PHY_IPA(pi)
+-	    && (pi->nphy_force_papd_cal
+-		|| (wlc_phy_txpwr_ison_nphy(pi)
+-		    &&
+-		    (((u32)
+-		      ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
+-			  pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
+-		     || ((u32)
+-			 ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
+-			     pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) {
+-		wlc_phy_a4(pi, true);
+-	}
+-}
+-
+-void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type)
+-{
+-	u16 mask = 0, val = 0, ishw = 0;
+-	u8 ctr;
+-	uint core;
+-	u32 tbl_offset;
+-	u32 tbl_len;
+-	u16 regval[84];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	switch (ctrl_type) {
+-	case PHY_TPC_HW_OFF:
+-	case PHY_TPC_HW_ON:
+-		pi->nphy_txpwrctrl = ctrl_type;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	if (ctrl_type == PHY_TPC_HW_OFF) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			if (wlc_phy_txpwr_ison_nphy(pi)) {
+-				for (core = 0; core < pi->pubpi.phy_corenum;
+-				     core++)
+-					pi->nphy_txpwr_idx[core] =
+-					    wlc_phy_txpwr_idx_cur_get_nphy(pi,
+-									   (u8)
+-									   core);
+-			}
+-
+-		}
+-
+-		tbl_len = 84;
+-		tbl_offset = 64;
+-		for (ctr = 0; ctr < tbl_len; ctr++) {
+-			regval[ctr] = 0;
+-		}
+-		wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
+-					 regval);
+-		wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
+-					 regval);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			and_phy_reg(pi, 0x1e7,
+-				    (u16) (~((0x1 << 15) |
+-						(0x1 << 14) | (0x1 << 13))));
+-		} else {
+-			and_phy_reg(pi, 0x1e7,
+-				    (u16) (~((0x1 << 14) | (0x1 << 13))));
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			or_phy_reg(pi, 0x8f, (0x1 << 8));
+-			or_phy_reg(pi, 0xa5, (0x1 << 8));
+-		} else {
+-			or_phy_reg(pi, 0xa5, (0x1 << 14));
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
+-		else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+-				       MHF1_IQSWAP_WAR, WLC_BAND_ALL);
+-
+-	} else {
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
+-					 8, pi->adj_pwr_tbl_nphy);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
+-					 8, pi->adj_pwr_tbl_nphy);
+-
+-		ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
+-		mask = (0x1 << 14) | (0x1 << 13);
+-		val = (ishw << 14) | (ishw << 13);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			mask |= (0x1 << 15);
+-			val |= (ishw << 15);
+-		}
+-
+-		mod_phy_reg(pi, 0x1e7, mask, val);
+-
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
+-				mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
+-			} else {
+-				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
+-				if (NREV_GT(pi->pubpi.phy_rev, 1))
+-					mod_phy_reg(pi, 0x222,
+-						    (0xff << 0), 0x64);
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if ((pi->nphy_txpwr_idx[0] != 128)
+-			    && (pi->nphy_txpwr_idx[1] != 128)) {
+-				wlc_phy_txpwr_idx_cur_set_nphy(pi,
+-							       pi->
+-							       nphy_txpwr_idx
+-							       [0],
+-							       pi->
+-							       nphy_txpwr_idx
+-							       [1]);
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			and_phy_reg(pi, 0x8f, ~(0x1 << 8));
+-			and_phy_reg(pi, 0xa5, ~(0x1 << 8));
+-		} else {
+-			and_phy_reg(pi, 0xa5, ~(0x1 << 14));
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+-		else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+-				       0x0, WLC_BAND_ALL);
+-
+-		if (PHY_IPA(pi)) {
+-			mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (0) << 2);
+-
+-			mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (0) << 2);
+-
+-		}
+-
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void
+-wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex,
+-			 bool restore_cals)
+-{
+-	u8 core, txpwrctl_tbl;
+-	u16 tx_ind0, iq_ind0, lo_ind0;
+-	u16 m1m2;
+-	u32 txgain;
+-	u16 rad_gain, dac_gain;
+-	u8 bbmult;
+-	u32 iqcomp;
+-	u16 iqcomp_a, iqcomp_b;
+-	u32 locomp;
+-	u16 tmpval;
+-	u8 tx_pwr_ctrl_state;
+-	s32 rfpwr_offset;
+-	u16 regval[2];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	tx_ind0 = 192;
+-	iq_ind0 = 320;
+-	lo_ind0 = 448;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((core_mask & (1 << core)) == 0) {
+-			continue;
+-		}
+-
+-		txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
+-
+-		if (txpwrindex < 0) {
+-			if (pi->nphy_txpwrindex[core].index < 0) {
+-
+-				continue;
+-			}
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				mod_phy_reg(pi, 0x8f,
+-					    (0x1 << 8),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-				mod_phy_reg(pi, 0xa5, (0x1 << 8),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-			} else {
+-				mod_phy_reg(pi, 0xa5,
+-					    (0x1 << 14),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-			}
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xaa : 0xab,
+-				      pi->nphy_txpwrindex[core].AfeCtrlDacGain);
+-
+-			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-						 &pi->nphy_txpwrindex[core].
+-						 rad_gain);
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-			m1m2 |= ((core == PHY_CORE_0) ?
+-				 (pi->nphy_txpwrindex[core].bbmult << 8) :
+-				 (pi->nphy_txpwrindex[core].bbmult << 0));
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-			if (restore_cals) {
+-
+-				wlc_phy_table_write_nphy(pi, 15, 2,
+-							 (80 + 2 * core), 16,
+-							 (void *)&pi->
+-							 nphy_txpwrindex[core].
+-							 iqcomp_a);
+-
+-				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+-							 16,
+-							 &pi->
+-							 nphy_txpwrindex[core].
+-							 locomp);
+-				wlc_phy_table_write_nphy(pi, 15, 1, (93 + core),
+-							 16,
+-							 (void *)&pi->
+-							 nphy_txpwrindex[core].
+-							 locomp);
+-			}
+-
+-			wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+-
+-			pi->nphy_txpwrindex[core].index_internal =
+-			    pi->nphy_txpwrindex[core].index_internal_save;
+-		} else {
+-
+-			if (pi->nphy_txpwrindex[core].index < 0) {
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					mod_phy_reg(pi, 0x8f,
+-						    (0x1 << 8),
+-						    pi->nphy_txpwrindex[core].
+-						    AfectrlOverride);
+-					mod_phy_reg(pi, 0xa5, (0x1 << 8),
+-						    pi->nphy_txpwrindex[core].
+-						    AfectrlOverride);
+-				} else {
+-					pi->nphy_txpwrindex[core].
+-					    AfectrlOverride =
+-					    read_phy_reg(pi, 0xa5);
+-				}
+-
+-				pi->nphy_txpwrindex[core].AfeCtrlDacGain =
+-				    read_phy_reg(pi,
+-						 (core ==
+-						  PHY_CORE_0) ? 0xaa : 0xab);
+-
+-				wlc_phy_table_read_nphy(pi, 7, 1,
+-							(0x110 + core), 16,
+-							&pi->
+-							nphy_txpwrindex[core].
+-							rad_gain);
+-
+-				wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+-							&tmpval);
+-				tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
+-				tmpval &= 0xff;
+-				pi->nphy_txpwrindex[core].bbmult =
+-				    (u8) tmpval;
+-
+-				wlc_phy_table_read_nphy(pi, 15, 2,
+-							(80 + 2 * core), 16,
+-							(void *)&pi->
+-							nphy_txpwrindex[core].
+-							iqcomp_a);
+-
+-				wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
+-							16,
+-							(void *)&pi->
+-							nphy_txpwrindex[core].
+-							locomp);
+-
+-				pi->nphy_txpwrindex[core].index_internal_save =
+-				    pi->nphy_txpwrindex[core].index_internal;
+-			}
+-
+-			tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-			wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 1))
+-				wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(tx_ind0 + txpwrindex), 32,
+-						&txgain);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				rad_gain =
+-				    (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+-			} else {
+-				rad_gain =
+-				    (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+-			}
+-			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+-			bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-						 0xa5), (0x1 << 8), (0x1 << 8));
+-			} else {
+-				mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+-			}
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xaa : 0xab, dac_gain);
+-
+-			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-						 &rad_gain);
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-			m1m2 |=
+-			    ((core ==
+-			      PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(iq_ind0 + txpwrindex), 32,
+-						&iqcomp);
+-			iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
+-			iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
+-
+-			if (restore_cals) {
+-				regval[0] = (u16) iqcomp_a;
+-				regval[1] = (u16) iqcomp_b;
+-				wlc_phy_table_write_nphy(pi, 15, 2,
+-							 (80 + 2 * core), 16,
+-							 regval);
+-			}
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(lo_ind0 + txpwrindex), 32,
+-						&locomp);
+-			if (restore_cals) {
+-				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+-							 16, &locomp);
+-			}
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 1))
+-				wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-			if (PHY_IPA(pi)) {
+-				wlc_phy_table_read_nphy(pi,
+-							(core ==
+-							 PHY_CORE_0 ?
+-							 NPHY_TBL_ID_CORE1TXPWRCTL
+-							 :
+-							 NPHY_TBL_ID_CORE2TXPWRCTL),
+-							1, 576 + txpwrindex, 32,
+-							&rfpwr_offset);
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-					    0x29b, (0x1ff << 4),
+-					    ((s16) rfpwr_offset) << 4);
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-					    0x29b, (0x1 << 2), (1) << 2);
+-
+-			}
+-
+-			wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-		}
+-
+-		pi->nphy_txpwrindex[core].index = txpwrindex;
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr,
+-				   u8 txp_rate_idx)
+-{
+-	u8 chan_freq_range;
+-
+-	chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
+-	switch (chan_freq_range) {
+-	case WL_CHAN_FREQ_RANGE_2G:
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GM:
+-		*max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GL:
+-		*max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GH:
+-		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+-		break;
+-	default:
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-		break;
+-	}
+-
+-	return;
+-}
+-
+-void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable)
+-{
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-
+-	if (enable) {
+-		if (pi->nphy_deaf_count == 0) {
+-			pi->classifier_state =
+-			    wlc_phy_classifier_nphy(pi, 0, 0);
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-			wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
+-			wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-		}
+-
+-		pi->nphy_deaf_count++;
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-	} else {
+-		pi->nphy_deaf_count--;
+-
+-		if (pi->nphy_deaf_count == 0) {
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0),
+-						pi->classifier_state);
+-			wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
+-		}
+-	}
+-}
+-
+-void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode)
+-{
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (mode) {
+-		if (pi->nphy_deaf_count == 0)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-	} else {
+-		if (pi->nphy_deaf_count > 0)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-	}
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
+deleted file mode 100644
+index c98176f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
++++ /dev/null
+@@ -1,296 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-
+-#include "wlc_phy_qmath.h"
+-
+-/*
+-Description: This function make 16 bit unsigned multiplication. To fit the output into
+-16 bits the 32 bit multiplication result is right shifted by 16 bits.
+-*/
+-u16 qm_mulu16(u16 op1, u16 op2)
+-{
+-	return (u16) (((u32) op1 * (u32) op2) >> 16);
+-}
+-
+-/*
+-Description: This function make 16 bit multiplication and return the result in 16 bits.
+-To fit the multiplication result into 16 bits the multiplication result is right shifted by
+-15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
+-due to the multiplication.
+-When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
+-*/
+-s16 qm_muls16(s16 op1, s16 op2)
+-{
+-	s32 result;
+-	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
+-		result = 0x7fffffff;
+-	} else {
+-		result = ((s32) (op1) * (s32) (op2));
+-	}
+-	return (s16) (result >> 15);
+-}
+-
+-/*
+-Description: This function add two 32 bit numbers and return the 32bit result.
+-If the result overflow 32 bits, the output will be saturated to 32bits.
+-*/
+-s32 qm_add32(s32 op1, s32 op2)
+-{
+-	s32 result;
+-	result = op1 + op2;
+-	if (op1 < 0 && op2 < 0 && result > 0) {
+-		result = 0x80000000;
+-	} else if (op1 > 0 && op2 > 0 && result < 0) {
+-		result = 0x7fffffff;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function add two 16 bit numbers and return the 16bit result.
+-If the result overflow 16 bits, the output will be saturated to 16bits.
+-*/
+-s16 qm_add16(s16 op1, s16 op2)
+-{
+-	s16 result;
+-	s32 temp = (s32) op1 + (s32) op2;
+-	if (temp > (s32) 0x7fff) {
+-		result = (s16) 0x7fff;
+-	} else if (temp < (s32) 0xffff8000) {
+-		result = (s16) 0xffff8000;
+-	} else {
+-		result = (s16) temp;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make 16 bit subtraction and return the 16bit result.
+-If the result overflow 16 bits, the output will be saturated to 16bits.
+-*/
+-s16 qm_sub16(s16 op1, s16 op2)
+-{
+-	s16 result;
+-	s32 temp = (s32) op1 - (s32) op2;
+-	if (temp > (s32) 0x7fff) {
+-		result = (s16) 0x7fff;
+-	} else if (temp < (s32) 0xffff8000) {
+-		result = (s16) 0xffff8000;
+-	} else {
+-		result = (s16) temp;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 32 bit saturated left shift when the specified shift
+-is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
+-This function return the result after shifting operation.
+-*/
+-s32 qm_shl32(s32 op, int shift)
+-{
+-	int i;
+-	s32 result;
+-	result = op;
+-	if (shift > 31)
+-		shift = 31;
+-	else if (shift < -31)
+-		shift = -31;
+-	if (shift >= 0) {
+-		for (i = 0; i < shift; i++) {
+-			result = qm_add32(result, result);
+-		}
+-	} else {
+-		result = result >> (-shift);
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 16 bit saturated left shift when the specified shift
+-is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
+-This function return the result after shifting operation.
+-*/
+-s16 qm_shl16(s16 op, int shift)
+-{
+-	int i;
+-	s16 result;
+-	result = op;
+-	if (shift > 15)
+-		shift = 15;
+-	else if (shift < -15)
+-		shift = -15;
+-	if (shift > 0) {
+-		for (i = 0; i < shift; i++) {
+-			result = qm_add16(result, result);
+-		}
+-	} else {
+-		result = result >> (-shift);
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 16 bit right shift when shift is +ve.
+-This function make a 16 bit saturated left shift when shift is -ve. This function
+-return the result of the shift operation.
+-*/
+-s16 qm_shr16(s16 op, int shift)
+-{
+-	return qm_shl16(op, -shift);
+-}
+-
+-/*
+-Description: This function return the number of redundant sign bits in a 32 bit number.
+-Example: qm_norm32(0x00000080) = 23
+-*/
+-s16 qm_norm32(s32 op)
+-{
+-	u16 u16extraSignBits;
+-	if (op == 0) {
+-		return 31;
+-	} else {
+-		u16extraSignBits = 0;
+-		while ((op >> 31) == (op >> 30)) {
+-			u16extraSignBits++;
+-			op = op << 1;
+-		}
+-	}
+-	return u16extraSignBits;
+-}
+-
+-/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
+-static const s16 log_table[] = {
+-	0,
+-	1455,
+-	2866,
+-	4236,
+-	5568,
+-	6863,
+-	8124,
+-	9352,
+-	10549,
+-	11716,
+-	12855,
+-	13968,
+-	15055,
+-	16117,
+-	17156,
+-	18173,
+-	19168,
+-	20143,
+-	21098,
+-	22034,
+-	22952,
+-	23852,
+-	24736,
+-	25604,
+-	26455,
+-	27292,
+-	28114,
+-	28922,
+-	29717,
+-	30498,
+-	31267,
+-	32024
+-};
+-
+-#define LOG_TABLE_SIZE 32	/* log_table size */
+-#define LOG2_LOG_TABLE_SIZE 5	/* log2(log_table size) */
+-#define Q_LOG_TABLE 15		/* qformat of log_table */
+-#define LOG10_2		19728	/* log10(2) in q.16 */
+-
+-/*
+-Description:
+-This routine takes the input number N and its q format qN and compute
+-the log10(N). This routine first normalizes the input no N.	Then N is in mag*(2^x) format.
+-mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
+-From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
+-This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
+-As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
+-Next 16 MSBs are used for interpolation.
+-Inputs:
+-N - number to which log10 has to be found.
+-qN - q format of N
+-log10N - address where log10(N) will be written.
+-qLog10N - address where log10N qformat will be written.
+-Note/Problem:
+-For accurate results input should be in normalized or near normalized form.
+-*/
+-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
+-{
+-	s16 s16norm, s16tableIndex, s16errorApproximation;
+-	u16 u16offset;
+-	s32 s32log;
+-
+-	/* normalize the N. */
+-	s16norm = qm_norm32(N);
+-	N = N << s16norm;
+-
+-	/* The qformat of N after normalization.
+-	 * -30 is added to treat the no as between 1.0 to 2.0
+-	 * i.e. after adding the -30 to the qformat the decimal point will be
+-	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
+-	 * at the right side of 30th bit.
+-	 */
+-	qN = qN + s16norm - 30;
+-
+-	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
+-	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
+-
+-	/* remove the MSB. the MSB is always 1 after normalization. */
+-	s16tableIndex =
+-	    s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
+-
+-	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
+-	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
+-
+-	/* take the offset as the 16 MSBS after table index.
+-	 */
+-	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
+-
+-	/* look the log value in the table. */
+-	s32log = log_table[s16tableIndex];	/* q.15 format */
+-
+-	/* interpolate using the offset. */
+-	s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex]));	/* q.15 */
+-
+-	s32log = qm_add16((s16) s32log, s16errorApproximation);	/* q.15 format */
+-
+-	/* adjust for the qformat of the N as
+-	 * log2(mag * 2^x) = log2(mag) + x
+-	 */
+-	s32log = qm_add32(s32log, ((s32) -qN) << 15);	/* q.15 format */
+-
+-	/* normalize the result. */
+-	s16norm = qm_norm32(s32log);
+-
+-	/* bring all the important bits into lower 16 bits */
+-	s32log = qm_shl32(s32log, s16norm - 16);	/* q.15+s16norm-16 format */
+-
+-	/* compute the log10(N) by multiplying log2(N) with log10(2).
+-	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
+-	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
+-	 */
+-	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
+-
+-	/* write the q format of the result. */
+-	*qLog10N = 15 + s16norm - 16 + 1;
+-
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
+deleted file mode 100644
+index 3dcee1c..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef __QMATH_H__
+-#define __QMATH_H__
+-
+-u16 qm_mulu16(u16 op1, u16 op2);
+-
+-s16 qm_muls16(s16 op1, s16 op2);
+-
+-s32 qm_add32(s32 op1, s32 op2);
+-
+-s16 qm_add16(s16 op1, s16 op2);
+-
+-s16 qm_sub16(s16 op1, s16 op2);
+-
+-s32 qm_shl32(s32 op, int shift);
+-
+-s16 qm_shl16(s16 op, int shift);
+-
+-s16 qm_shr16(s16 op, int shift);
+-
+-s16 qm_norm32(s32 op);
+-
+-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
+-
+-#endif				/* #ifndef __QMATH_H__ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
+deleted file mode 100644
+index 72176ae..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
++++ /dev/null
+@@ -1,1533 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_BCM20XX_H
+-#define	_BCM20XX_H
+-
+-#define	RADIO_IDCODE			0x01
+-
+-#define RADIO_DEFAULT_CORE		0
+-
+-#define	RXC0_RSSI_RST			0x80
+-#define	RXC0_MODE_RSSI			0x40
+-#define	RXC0_MODE_OFF			0x20
+-#define	RXC0_MODE_CM			0x10
+-#define	RXC0_LAN_LOAD			0x08
+-#define	RXC0_OFF_ADJ_MASK		0x07
+-
+-#define	TXC0_MODE_TXLPF			0x04
+-#define	TXC0_PA_TSSI_EN			0x02
+-#define	TXC0_TSSI_EN			0x01
+-
+-#define	TXC1_PA_GAIN_MASK		0x60
+-#define	TXC1_PA_GAIN_3DB		0x40
+-#define	TXC1_PA_GAIN_2DB		0x20
+-#define	TXC1_TX_MIX_GAIN		0x10
+-#define	TXC1_OFF_I_MASK			0x0c
+-#define	TXC1_OFF_Q_MASK			0x03
+-
+-#define	RADIO_2055_READ_OFF		0x100
+-#define	RADIO_2057_READ_OFF		0x200
+-
+-#define RADIO_2055_GEN_SPARE		0x00
+-#define RADIO_2055_SP_PIN_PD		0x02
+-#define RADIO_2055_SP_RSSI_CORE1	0x03
+-#define RADIO_2055_SP_PD_MISC_CORE1	0x04
+-#define RADIO_2055_SP_RSSI_CORE2	0x05
+-#define RADIO_2055_SP_PD_MISC_CORE2	0x06
+-#define RADIO_2055_SP_RX_GC1_CORE1	0x07
+-#define RADIO_2055_SP_RX_GC2_CORE1	0x08
+-#define RADIO_2055_SP_RX_GC1_CORE2	0x09
+-#define RADIO_2055_SP_RX_GC2_CORE2	0x0a
+-#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
+-#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
+-#define RADIO_2055_SP_TX_GC1_CORE1	0x0d
+-#define RADIO_2055_SP_TX_GC2_CORE1	0x0e
+-#define RADIO_2055_SP_TX_GC1_CORE2	0x0f
+-#define RADIO_2055_SP_TX_GC2_CORE2	0x10
+-#define RADIO_2055_MASTER_CNTRL1	0x11
+-#define RADIO_2055_MASTER_CNTRL2	0x12
+-#define RADIO_2055_PD_LGEN		0x13
+-#define RADIO_2055_PD_PLL_TS		0x14
+-#define RADIO_2055_PD_CORE1_LGBUF	0x15
+-#define RADIO_2055_PD_CORE1_TX		0x16
+-#define RADIO_2055_PD_CORE1_RXTX	0x17
+-#define RADIO_2055_PD_CORE1_RSSI_MISC	0x18
+-#define RADIO_2055_PD_CORE2_LGBUF	0x19
+-#define RADIO_2055_PD_CORE2_TX		0x1a
+-#define RADIO_2055_PD_CORE2_RXTX	0x1b
+-#define RADIO_2055_PD_CORE2_RSSI_MISC	0x1c
+-#define RADIO_2055_PWRDET_LGEN		0x1d
+-#define RADIO_2055_PWRDET_LGBUF_CORE1	0x1e
+-#define RADIO_2055_PWRDET_RXTX_CORE1	0x1f
+-#define RADIO_2055_PWRDET_LGBUF_CORE2	0x20
+-#define RADIO_2055_PWRDET_RXTX_CORE2	0x21
+-#define RADIO_2055_RRCCAL_CNTRL_SPARE	0x22
+-#define RADIO_2055_RRCCAL_N_OPT_SEL	0x23
+-#define RADIO_2055_CAL_MISC		0x24
+-#define RADIO_2055_CAL_COUNTER_OUT	0x25
+-#define RADIO_2055_CAL_COUNTER_OUT2	0x26
+-#define RADIO_2055_CAL_CVAR_CNTRL	0x27
+-#define RADIO_2055_CAL_RVAR_CNTRL	0x28
+-#define RADIO_2055_CAL_LPO_CNTRL	0x29
+-#define RADIO_2055_CAL_TS		0x2a
+-#define RADIO_2055_CAL_RCCAL_READ_TS	0x2b
+-#define RADIO_2055_CAL_RCAL_READ_TS	0x2c
+-#define RADIO_2055_PAD_DRIVER		0x2d
+-#define RADIO_2055_XO_CNTRL1		0x2e
+-#define RADIO_2055_XO_CNTRL2		0x2f
+-#define RADIO_2055_XO_REGULATOR		0x30
+-#define RADIO_2055_XO_MISC		0x31
+-#define RADIO_2055_PLL_LF_C1		0x32
+-#define RADIO_2055_PLL_CAL_VTH		0x33
+-#define RADIO_2055_PLL_LF_C2		0x34
+-#define RADIO_2055_PLL_REF		0x35
+-#define RADIO_2055_PLL_LF_R1		0x36
+-#define RADIO_2055_PLL_PFD_CP		0x37
+-#define RADIO_2055_PLL_IDAC_CPOPAMP	0x38
+-#define RADIO_2055_PLL_CP_REGULATOR	0x39
+-#define RADIO_2055_PLL_RCAL		0x3a
+-#define RADIO_2055_RF_PLL_MOD0		0x3b
+-#define RADIO_2055_RF_PLL_MOD1		0x3c
+-#define RADIO_2055_RF_MMD_IDAC1		0x3d
+-#define RADIO_2055_RF_MMD_IDAC0		0x3e
+-#define RADIO_2055_RF_MMD_SPARE		0x3f
+-#define RADIO_2055_VCO_CAL1		0x40
+-#define RADIO_2055_VCO_CAL2		0x41
+-#define RADIO_2055_VCO_CAL3		0x42
+-#define RADIO_2055_VCO_CAL4		0x43
+-#define RADIO_2055_VCO_CAL5		0x44
+-#define RADIO_2055_VCO_CAL6		0x45
+-#define RADIO_2055_VCO_CAL7		0x46
+-#define RADIO_2055_VCO_CAL8		0x47
+-#define RADIO_2055_VCO_CAL9		0x48
+-#define RADIO_2055_VCO_CAL10		0x49
+-#define RADIO_2055_VCO_CAL11		0x4a
+-#define RADIO_2055_VCO_CAL12		0x4b
+-#define RADIO_2055_VCO_CAL13		0x4c
+-#define RADIO_2055_VCO_CAL14		0x4d
+-#define RADIO_2055_VCO_CAL15		0x4e
+-#define RADIO_2055_VCO_CAL16		0x4f
+-#define RADIO_2055_VCO_KVCO		0x50
+-#define RADIO_2055_VCO_CAP_TAIL		0x51
+-#define RADIO_2055_VCO_IDAC_VCO		0x52
+-#define RADIO_2055_VCO_REGULATOR	0x53
+-#define RADIO_2055_PLL_RF_VTH		0x54
+-#define RADIO_2055_LGBUF_CEN_BUF	0x55
+-#define RADIO_2055_LGEN_TUNE1		0x56
+-#define RADIO_2055_LGEN_TUNE2		0x57
+-#define RADIO_2055_LGEN_IDAC1		0x58
+-#define RADIO_2055_LGEN_IDAC2		0x59
+-#define RADIO_2055_LGEN_BIAS_CNT	0x5a
+-#define RADIO_2055_LGEN_BIAS_IDAC	0x5b
+-#define RADIO_2055_LGEN_RCAL		0x5c
+-#define RADIO_2055_LGEN_DIV		0x5d
+-#define RADIO_2055_LGEN_SPARE2		0x5e
+-#define RADIO_2055_CORE1_LGBUF_A_TUNE	0x5f
+-#define RADIO_2055_CORE1_LGBUF_G_TUNE	0x60
+-#define RADIO_2055_CORE1_LGBUF_DIV	0x61
+-#define RADIO_2055_CORE1_LGBUF_A_IDAC	0x62
+-#define RADIO_2055_CORE1_LGBUF_G_IDAC	0x63
+-#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
+-#define RADIO_2055_CORE1_LGBUF_SPARE	0x65
+-#define RADIO_2055_CORE1_RXRF_SPC1	0x66
+-#define RADIO_2055_CORE1_RXRF_REG1	0x67
+-#define RADIO_2055_CORE1_RXRF_REG2	0x68
+-#define RADIO_2055_CORE1_RXRF_RCAL	0x69
+-#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
+-#define RADIO_2055_CORE1_RXBB_LPF	0x6b
+-#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
+-#define RADIO_2055_CORE1_RXBB_VGA1_IDAC	0x6d
+-#define RADIO_2055_CORE1_RXBB_VGA2_IDAC	0x6e
+-#define RADIO_2055_CORE1_RXBB_VGA3_IDAC	0x6f
+-#define RADIO_2055_CORE1_RXBB_BUFO_CTRL	0x70
+-#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
+-#define RADIO_2055_CORE1_RXBB_REGULATOR	0x77
+-#define RADIO_2055_CORE1_RXBB_SPARE1	0x78
+-#define RADIO_2055_CORE1_RXTXBB_RCAL	0x79
+-#define RADIO_2055_CORE1_TXRF_SGM_PGA	0x7a
+-#define RADIO_2055_CORE1_TXRF_SGM_PAD	0x7b
+-#define RADIO_2055_CORE1_TXRF_CNTR_PGA1	0x7c
+-#define RADIO_2055_CORE1_TXRF_CNTR_PAD1	0x7d
+-#define RADIO_2055_CORE1_TX_RFPGA_IDAC	0x7e
+-#define RADIO_2055_CORE1_TX_PGA_PAD_TN	0x7f
+-#define RADIO_2055_CORE1_TX_PAD_IDAC1	0x80
+-#define RADIO_2055_CORE1_TX_PAD_IDAC2	0x81
+-#define RADIO_2055_CORE1_TX_MX_BGTRIM	0x82
+-#define RADIO_2055_CORE1_TXRF_RCAL	0x83
+-#define RADIO_2055_CORE1_TXRF_PAD_TSSI1	0x84
+-#define RADIO_2055_CORE1_TXRF_PAD_TSSI2	0x85
+-#define RADIO_2055_CORE1_TX_RF_SPARE	0x86
+-#define RADIO_2055_CORE1_TXRF_IQCAL1	0x87
+-#define RADIO_2055_CORE1_TXRF_IQCAL2	0x88
+-#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
+-#define RADIO_2055_CORE1_TXBB_LPF1	0x8a
+-#define RADIO_2055_CORE1_TX_VOS_CNCL	0x8b
+-#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
+-#define RADIO_2055_CORE1_TX_BB_MXGM	0x8d
+-#define RADIO_2055_CORE2_LGBUF_A_TUNE	0x8e
+-#define RADIO_2055_CORE2_LGBUF_G_TUNE	0x8f
+-#define RADIO_2055_CORE2_LGBUF_DIV	0x90
+-#define RADIO_2055_CORE2_LGBUF_A_IDAC	0x91
+-#define RADIO_2055_CORE2_LGBUF_G_IDAC	0x92
+-#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
+-#define RADIO_2055_CORE2_LGBUF_SPARE	0x94
+-#define RADIO_2055_CORE2_RXRF_SPC1	0x95
+-#define RADIO_2055_CORE2_RXRF_REG1	0x96
+-#define RADIO_2055_CORE2_RXRF_REG2	0x97
+-#define RADIO_2055_CORE2_RXRF_RCAL	0x98
+-#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
+-#define RADIO_2055_CORE2_RXBB_LPF	0x9a
+-#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
+-#define RADIO_2055_CORE2_RXBB_VGA1_IDAC	0x9c
+-#define RADIO_2055_CORE2_RXBB_VGA2_IDAC	0x9d
+-#define RADIO_2055_CORE2_RXBB_VGA3_IDAC	0x9e
+-#define RADIO_2055_CORE2_RXBB_BUFO_CTRL	0x9f
+-#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
+-#define RADIO_2055_CORE2_RXBB_REGULATOR	0xa6
+-#define RADIO_2055_CORE2_RXBB_SPARE1	0xa7
+-#define RADIO_2055_CORE2_RXTXBB_RCAL	0xa8
+-#define RADIO_2055_CORE2_TXRF_SGM_PGA	0xa9
+-#define RADIO_2055_CORE2_TXRF_SGM_PAD	0xaa
+-#define RADIO_2055_CORE2_TXRF_CNTR_PGA1	0xab
+-#define RADIO_2055_CORE2_TXRF_CNTR_PAD1	0xac
+-#define RADIO_2055_CORE2_TX_RFPGA_IDAC	0xad
+-#define RADIO_2055_CORE2_TX_PGA_PAD_TN	0xae
+-#define RADIO_2055_CORE2_TX_PAD_IDAC1	0xaf
+-#define RADIO_2055_CORE2_TX_PAD_IDAC2	0xb0
+-#define RADIO_2055_CORE2_TX_MX_BGTRIM	0xb1
+-#define RADIO_2055_CORE2_TXRF_RCAL	0xb2
+-#define RADIO_2055_CORE2_TXRF_PAD_TSSI1	0xb3
+-#define RADIO_2055_CORE2_TXRF_PAD_TSSI2	0xb4
+-#define RADIO_2055_CORE2_TX_RF_SPARE	0xb5
+-#define RADIO_2055_CORE2_TXRF_IQCAL1	0xb6
+-#define RADIO_2055_CORE2_TXRF_IQCAL2	0xb7
+-#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
+-#define RADIO_2055_CORE2_TXBB_LPF1	0xb9
+-#define RADIO_2055_CORE2_TX_VOS_CNCL	0xba
+-#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
+-#define RADIO_2055_CORE2_TX_BB_MXGM	0xbc
+-#define RADIO_2055_PRG_GC_HPVGA23_21	0xbd
+-#define RADIO_2055_PRG_GC_HPVGA23_22	0xbe
+-#define RADIO_2055_PRG_GC_HPVGA23_23	0xbf
+-#define RADIO_2055_PRG_GC_HPVGA23_24	0xc0
+-#define RADIO_2055_PRG_GC_HPVGA23_25	0xc1
+-#define RADIO_2055_PRG_GC_HPVGA23_26	0xc2
+-#define RADIO_2055_PRG_GC_HPVGA23_27	0xc3
+-#define RADIO_2055_PRG_GC_HPVGA23_28	0xc4
+-#define RADIO_2055_PRG_GC_HPVGA23_29	0xc5
+-#define RADIO_2055_PRG_GC_HPVGA23_30	0xc6
+-#define RADIO_2055_CORE1_LNA_GAINBST	0xcd
+-#define RADIO_2055_CORE1_B0_NBRSSI_VCM	0xd2
+-#define RADIO_2055_CORE1_GEN_SPARE2		0xd6
+-#define RADIO_2055_CORE2_LNA_GAINBST	0xd9
+-#define RADIO_2055_CORE2_B0_NBRSSI_VCM	0xde
+-#define RADIO_2055_CORE2_GEN_SPARE2		0xe2
+-
+-#define RADIO_2055_GAINBST_GAIN_DB	6
+-#define RADIO_2055_GAINBST_CODE		0x6
+-
+-#define RADIO_2055_JTAGCTRL_MASK	0x04
+-#define RADIO_2055_JTAGSYNC_MASK	0x08
+-#define RADIO_2055_RRCAL_START		0x40
+-#define RADIO_2055_RRCAL_RST_N		0x01
+-#define RADIO_2055_CAL_LPO_ENABLE	0x80
+-#define RADIO_2055_RCAL_DONE		0x80
+-#define RADIO_2055_NBRSSI_VCM_I_MASK	0x03
+-#define RADIO_2055_NBRSSI_VCM_I_SHIFT	0x00
+-#define RADIO_2055_NBRSSI_VCM_Q_MASK	0x03
+-#define RADIO_2055_NBRSSI_VCM_Q_SHIFT	0x00
+-#define RADIO_2055_WBRSSI_VCM_IQ_MASK	0x0c
+-#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT	0x02
+-#define RADIO_2055_NBRSSI_PD		0x01
+-#define RADIO_2055_WBRSSI_G1_PD		0x04
+-#define RADIO_2055_WBRSSI_G2_PD		0x02
+-#define RADIO_2055_NBRSSI_SEL		0x01
+-#define RADIO_2055_WBRSSI_G1_SEL	0x04
+-#define RADIO_2055_WBRSSI_G2_SEL	0x02
+-#define RADIO_2055_COUPLE_RX_MASK	0x01
+-#define RADIO_2055_COUPLE_TX_MASK	0x02
+-#define RADIO_2055_GAINBST_DISABLE	0x02
+-#define RADIO_2055_GAINBST_VAL_MASK	0x07
+-#define RADIO_2055_RXMX_GC_MASK		0x0c
+-
+-#define RADIO_MIMO_CORESEL_OFF		0x0
+-#define RADIO_MIMO_CORESEL_CORE1	0x1
+-#define RADIO_MIMO_CORESEL_CORE2	0x2
+-#define RADIO_MIMO_CORESEL_CORE3	0x3
+-#define RADIO_MIMO_CORESEL_CORE4	0x4
+-#define RADIO_MIMO_CORESEL_ALLRX	0x5
+-#define RADIO_MIMO_CORESEL_ALLTX	0x6
+-#define RADIO_MIMO_CORESEL_ALLRXTX	0x7
+-
+-#define	RADIO_2064_READ_OFF		0x200
+-
+-#define RADIO_2064_REG000               0x0
+-#define RADIO_2064_REG001               0x1
+-#define RADIO_2064_REG002               0x2
+-#define RADIO_2064_REG003               0x3
+-#define RADIO_2064_REG004               0x4
+-#define RADIO_2064_REG005               0x5
+-#define RADIO_2064_REG006               0x6
+-#define RADIO_2064_REG007               0x7
+-#define RADIO_2064_REG008               0x8
+-#define RADIO_2064_REG009               0x9
+-#define RADIO_2064_REG00A               0xa
+-#define RADIO_2064_REG00B               0xb
+-#define RADIO_2064_REG00C               0xc
+-#define RADIO_2064_REG00D               0xd
+-#define RADIO_2064_REG00E               0xe
+-#define RADIO_2064_REG00F               0xf
+-#define RADIO_2064_REG010               0x10
+-#define RADIO_2064_REG011               0x11
+-#define RADIO_2064_REG012               0x12
+-#define RADIO_2064_REG013               0x13
+-#define RADIO_2064_REG014               0x14
+-#define RADIO_2064_REG015               0x15
+-#define RADIO_2064_REG016               0x16
+-#define RADIO_2064_REG017               0x17
+-#define RADIO_2064_REG018               0x18
+-#define RADIO_2064_REG019               0x19
+-#define RADIO_2064_REG01A               0x1a
+-#define RADIO_2064_REG01B               0x1b
+-#define RADIO_2064_REG01C               0x1c
+-#define RADIO_2064_REG01D               0x1d
+-#define RADIO_2064_REG01E               0x1e
+-#define RADIO_2064_REG01F               0x1f
+-#define RADIO_2064_REG020               0x20
+-#define RADIO_2064_REG021               0x21
+-#define RADIO_2064_REG022               0x22
+-#define RADIO_2064_REG023               0x23
+-#define RADIO_2064_REG024               0x24
+-#define RADIO_2064_REG025               0x25
+-#define RADIO_2064_REG026               0x26
+-#define RADIO_2064_REG027               0x27
+-#define RADIO_2064_REG028               0x28
+-#define RADIO_2064_REG029               0x29
+-#define RADIO_2064_REG02A               0x2a
+-#define RADIO_2064_REG02B               0x2b
+-#define RADIO_2064_REG02C               0x2c
+-#define RADIO_2064_REG02D               0x2d
+-#define RADIO_2064_REG02E               0x2e
+-#define RADIO_2064_REG02F               0x2f
+-#define RADIO_2064_REG030               0x30
+-#define RADIO_2064_REG031               0x31
+-#define RADIO_2064_REG032               0x32
+-#define RADIO_2064_REG033               0x33
+-#define RADIO_2064_REG034               0x34
+-#define RADIO_2064_REG035               0x35
+-#define RADIO_2064_REG036               0x36
+-#define RADIO_2064_REG037               0x37
+-#define RADIO_2064_REG038               0x38
+-#define RADIO_2064_REG039               0x39
+-#define RADIO_2064_REG03A               0x3a
+-#define RADIO_2064_REG03B               0x3b
+-#define RADIO_2064_REG03C               0x3c
+-#define RADIO_2064_REG03D               0x3d
+-#define RADIO_2064_REG03E               0x3e
+-#define RADIO_2064_REG03F               0x3f
+-#define RADIO_2064_REG040               0x40
+-#define RADIO_2064_REG041               0x41
+-#define RADIO_2064_REG042               0x42
+-#define RADIO_2064_REG043               0x43
+-#define RADIO_2064_REG044               0x44
+-#define RADIO_2064_REG045               0x45
+-#define RADIO_2064_REG046               0x46
+-#define RADIO_2064_REG047               0x47
+-#define RADIO_2064_REG048               0x48
+-#define RADIO_2064_REG049               0x49
+-#define RADIO_2064_REG04A               0x4a
+-#define RADIO_2064_REG04B               0x4b
+-#define RADIO_2064_REG04C               0x4c
+-#define RADIO_2064_REG04D               0x4d
+-#define RADIO_2064_REG04E               0x4e
+-#define RADIO_2064_REG04F               0x4f
+-#define RADIO_2064_REG050               0x50
+-#define RADIO_2064_REG051               0x51
+-#define RADIO_2064_REG052               0x52
+-#define RADIO_2064_REG053               0x53
+-#define RADIO_2064_REG054               0x54
+-#define RADIO_2064_REG055               0x55
+-#define RADIO_2064_REG056               0x56
+-#define RADIO_2064_REG057               0x57
+-#define RADIO_2064_REG058               0x58
+-#define RADIO_2064_REG059               0x59
+-#define RADIO_2064_REG05A               0x5a
+-#define RADIO_2064_REG05B               0x5b
+-#define RADIO_2064_REG05C               0x5c
+-#define RADIO_2064_REG05D               0x5d
+-#define RADIO_2064_REG05E               0x5e
+-#define RADIO_2064_REG05F               0x5f
+-#define RADIO_2064_REG060               0x60
+-#define RADIO_2064_REG061               0x61
+-#define RADIO_2064_REG062               0x62
+-#define RADIO_2064_REG063               0x63
+-#define RADIO_2064_REG064               0x64
+-#define RADIO_2064_REG065               0x65
+-#define RADIO_2064_REG066               0x66
+-#define RADIO_2064_REG067               0x67
+-#define RADIO_2064_REG068               0x68
+-#define RADIO_2064_REG069               0x69
+-#define RADIO_2064_REG06A               0x6a
+-#define RADIO_2064_REG06B               0x6b
+-#define RADIO_2064_REG06C               0x6c
+-#define RADIO_2064_REG06D               0x6d
+-#define RADIO_2064_REG06E               0x6e
+-#define RADIO_2064_REG06F               0x6f
+-#define RADIO_2064_REG070               0x70
+-#define RADIO_2064_REG071               0x71
+-#define RADIO_2064_REG072               0x72
+-#define RADIO_2064_REG073               0x73
+-#define RADIO_2064_REG074               0x74
+-#define RADIO_2064_REG075               0x75
+-#define RADIO_2064_REG076               0x76
+-#define RADIO_2064_REG077               0x77
+-#define RADIO_2064_REG078               0x78
+-#define RADIO_2064_REG079               0x79
+-#define RADIO_2064_REG07A               0x7a
+-#define RADIO_2064_REG07B               0x7b
+-#define RADIO_2064_REG07C               0x7c
+-#define RADIO_2064_REG07D               0x7d
+-#define RADIO_2064_REG07E               0x7e
+-#define RADIO_2064_REG07F               0x7f
+-#define RADIO_2064_REG080               0x80
+-#define RADIO_2064_REG081               0x81
+-#define RADIO_2064_REG082               0x82
+-#define RADIO_2064_REG083               0x83
+-#define RADIO_2064_REG084               0x84
+-#define RADIO_2064_REG085               0x85
+-#define RADIO_2064_REG086               0x86
+-#define RADIO_2064_REG087               0x87
+-#define RADIO_2064_REG088               0x88
+-#define RADIO_2064_REG089               0x89
+-#define RADIO_2064_REG08A               0x8a
+-#define RADIO_2064_REG08B               0x8b
+-#define RADIO_2064_REG08C               0x8c
+-#define RADIO_2064_REG08D               0x8d
+-#define RADIO_2064_REG08E               0x8e
+-#define RADIO_2064_REG08F               0x8f
+-#define RADIO_2064_REG090               0x90
+-#define RADIO_2064_REG091               0x91
+-#define RADIO_2064_REG092               0x92
+-#define RADIO_2064_REG093               0x93
+-#define RADIO_2064_REG094               0x94
+-#define RADIO_2064_REG095               0x95
+-#define RADIO_2064_REG096               0x96
+-#define RADIO_2064_REG097               0x97
+-#define RADIO_2064_REG098               0x98
+-#define RADIO_2064_REG099               0x99
+-#define RADIO_2064_REG09A               0x9a
+-#define RADIO_2064_REG09B               0x9b
+-#define RADIO_2064_REG09C               0x9c
+-#define RADIO_2064_REG09D               0x9d
+-#define RADIO_2064_REG09E               0x9e
+-#define RADIO_2064_REG09F               0x9f
+-#define RADIO_2064_REG0A0               0xa0
+-#define RADIO_2064_REG0A1               0xa1
+-#define RADIO_2064_REG0A2               0xa2
+-#define RADIO_2064_REG0A3               0xa3
+-#define RADIO_2064_REG0A4               0xa4
+-#define RADIO_2064_REG0A5               0xa5
+-#define RADIO_2064_REG0A6               0xa6
+-#define RADIO_2064_REG0A7               0xa7
+-#define RADIO_2064_REG0A8               0xa8
+-#define RADIO_2064_REG0A9               0xa9
+-#define RADIO_2064_REG0AA               0xaa
+-#define RADIO_2064_REG0AB               0xab
+-#define RADIO_2064_REG0AC               0xac
+-#define RADIO_2064_REG0AD               0xad
+-#define RADIO_2064_REG0AE               0xae
+-#define RADIO_2064_REG0AF               0xaf
+-#define RADIO_2064_REG0B0               0xb0
+-#define RADIO_2064_REG0B1               0xb1
+-#define RADIO_2064_REG0B2               0xb2
+-#define RADIO_2064_REG0B3               0xb3
+-#define RADIO_2064_REG0B4               0xb4
+-#define RADIO_2064_REG0B5               0xb5
+-#define RADIO_2064_REG0B6               0xb6
+-#define RADIO_2064_REG0B7               0xb7
+-#define RADIO_2064_REG0B8               0xb8
+-#define RADIO_2064_REG0B9               0xb9
+-#define RADIO_2064_REG0BA               0xba
+-#define RADIO_2064_REG0BB               0xbb
+-#define RADIO_2064_REG0BC               0xbc
+-#define RADIO_2064_REG0BD               0xbd
+-#define RADIO_2064_REG0BE               0xbe
+-#define RADIO_2064_REG0BF               0xbf
+-#define RADIO_2064_REG0C0               0xc0
+-#define RADIO_2064_REG0C1               0xc1
+-#define RADIO_2064_REG0C2               0xc2
+-#define RADIO_2064_REG0C3               0xc3
+-#define RADIO_2064_REG0C4               0xc4
+-#define RADIO_2064_REG0C5               0xc5
+-#define RADIO_2064_REG0C6               0xc6
+-#define RADIO_2064_REG0C7               0xc7
+-#define RADIO_2064_REG0C8               0xc8
+-#define RADIO_2064_REG0C9               0xc9
+-#define RADIO_2064_REG0CA               0xca
+-#define RADIO_2064_REG0CB               0xcb
+-#define RADIO_2064_REG0CC               0xcc
+-#define RADIO_2064_REG0CD               0xcd
+-#define RADIO_2064_REG0CE               0xce
+-#define RADIO_2064_REG0CF               0xcf
+-#define RADIO_2064_REG0D0               0xd0
+-#define RADIO_2064_REG0D1               0xd1
+-#define RADIO_2064_REG0D2               0xd2
+-#define RADIO_2064_REG0D3               0xd3
+-#define RADIO_2064_REG0D4               0xd4
+-#define RADIO_2064_REG0D5               0xd5
+-#define RADIO_2064_REG0D6               0xd6
+-#define RADIO_2064_REG0D7               0xd7
+-#define RADIO_2064_REG0D8               0xd8
+-#define RADIO_2064_REG0D9               0xd9
+-#define RADIO_2064_REG0DA               0xda
+-#define RADIO_2064_REG0DB               0xdb
+-#define RADIO_2064_REG0DC               0xdc
+-#define RADIO_2064_REG0DD               0xdd
+-#define RADIO_2064_REG0DE               0xde
+-#define RADIO_2064_REG0DF               0xdf
+-#define RADIO_2064_REG0E0               0xe0
+-#define RADIO_2064_REG0E1               0xe1
+-#define RADIO_2064_REG0E2               0xe2
+-#define RADIO_2064_REG0E3               0xe3
+-#define RADIO_2064_REG0E4               0xe4
+-#define RADIO_2064_REG0E5               0xe5
+-#define RADIO_2064_REG0E6               0xe6
+-#define RADIO_2064_REG0E7               0xe7
+-#define RADIO_2064_REG0E8               0xe8
+-#define RADIO_2064_REG0E9               0xe9
+-#define RADIO_2064_REG0EA               0xea
+-#define RADIO_2064_REG0EB               0xeb
+-#define RADIO_2064_REG0EC               0xec
+-#define RADIO_2064_REG0ED               0xed
+-#define RADIO_2064_REG0EE               0xee
+-#define RADIO_2064_REG0EF               0xef
+-#define RADIO_2064_REG0F0               0xf0
+-#define RADIO_2064_REG0F1               0xf1
+-#define RADIO_2064_REG0F2               0xf2
+-#define RADIO_2064_REG0F3               0xf3
+-#define RADIO_2064_REG0F4               0xf4
+-#define RADIO_2064_REG0F5               0xf5
+-#define RADIO_2064_REG0F6               0xf6
+-#define RADIO_2064_REG0F7               0xf7
+-#define RADIO_2064_REG0F8               0xf8
+-#define RADIO_2064_REG0F9               0xf9
+-#define RADIO_2064_REG0FA               0xfa
+-#define RADIO_2064_REG0FB               0xfb
+-#define RADIO_2064_REG0FC               0xfc
+-#define RADIO_2064_REG0FD               0xfd
+-#define RADIO_2064_REG0FE               0xfe
+-#define RADIO_2064_REG0FF               0xff
+-#define RADIO_2064_REG100               0x100
+-#define RADIO_2064_REG101               0x101
+-#define RADIO_2064_REG102               0x102
+-#define RADIO_2064_REG103               0x103
+-#define RADIO_2064_REG104               0x104
+-#define RADIO_2064_REG105               0x105
+-#define RADIO_2064_REG106               0x106
+-#define RADIO_2064_REG107               0x107
+-#define RADIO_2064_REG108               0x108
+-#define RADIO_2064_REG109               0x109
+-#define RADIO_2064_REG10A               0x10a
+-#define RADIO_2064_REG10B               0x10b
+-#define RADIO_2064_REG10C               0x10c
+-#define RADIO_2064_REG10D               0x10d
+-#define RADIO_2064_REG10E               0x10e
+-#define RADIO_2064_REG10F               0x10f
+-#define RADIO_2064_REG110               0x110
+-#define RADIO_2064_REG111               0x111
+-#define RADIO_2064_REG112               0x112
+-#define RADIO_2064_REG113               0x113
+-#define RADIO_2064_REG114               0x114
+-#define RADIO_2064_REG115               0x115
+-#define RADIO_2064_REG116               0x116
+-#define RADIO_2064_REG117               0x117
+-#define RADIO_2064_REG118               0x118
+-#define RADIO_2064_REG119               0x119
+-#define RADIO_2064_REG11A               0x11a
+-#define RADIO_2064_REG11B               0x11b
+-#define RADIO_2064_REG11C               0x11c
+-#define RADIO_2064_REG11D               0x11d
+-#define RADIO_2064_REG11E               0x11e
+-#define RADIO_2064_REG11F               0x11f
+-#define RADIO_2064_REG120               0x120
+-#define RADIO_2064_REG121               0x121
+-#define RADIO_2064_REG122               0x122
+-#define RADIO_2064_REG123               0x123
+-#define RADIO_2064_REG124               0x124
+-#define RADIO_2064_REG125               0x125
+-#define RADIO_2064_REG126               0x126
+-#define RADIO_2064_REG127               0x127
+-#define RADIO_2064_REG128               0x128
+-#define RADIO_2064_REG129               0x129
+-#define RADIO_2064_REG12A               0x12a
+-#define RADIO_2064_REG12B               0x12b
+-#define RADIO_2064_REG12C               0x12c
+-#define RADIO_2064_REG12D               0x12d
+-#define RADIO_2064_REG12E               0x12e
+-#define RADIO_2064_REG12F               0x12f
+-#define RADIO_2064_REG130               0x130
+-
+-#define RADIO_2056_SYN                           (0x0 << 12)
+-#define RADIO_2056_TX0                           (0x2 << 12)
+-#define RADIO_2056_TX1                           (0x3 << 12)
+-#define RADIO_2056_RX0                           (0x6 << 12)
+-#define RADIO_2056_RX1                           (0x7 << 12)
+-#define RADIO_2056_ALLTX                         (0xe << 12)
+-#define RADIO_2056_ALLRX                         (0xf << 12)
+-
+-#define RADIO_2056_SYN_RESERVED_ADDR0            0x0
+-#define RADIO_2056_SYN_IDCODE                    0x1
+-#define RADIO_2056_SYN_RESERVED_ADDR2            0x2
+-#define RADIO_2056_SYN_RESERVED_ADDR3            0x3
+-#define RADIO_2056_SYN_RESERVED_ADDR4            0x4
+-#define RADIO_2056_SYN_RESERVED_ADDR5            0x5
+-#define RADIO_2056_SYN_RESERVED_ADDR6            0x6
+-#define RADIO_2056_SYN_RESERVED_ADDR7            0x7
+-#define RADIO_2056_SYN_COM_CTRL                  0x8
+-#define RADIO_2056_SYN_COM_PU                    0x9
+-#define RADIO_2056_SYN_COM_OVR                   0xa
+-#define RADIO_2056_SYN_COM_RESET                 0xb
+-#define RADIO_2056_SYN_COM_RCAL                  0xc
+-#define RADIO_2056_SYN_COM_RC_RXLPF              0xd
+-#define RADIO_2056_SYN_COM_RC_TXLPF              0xe
+-#define RADIO_2056_SYN_COM_RC_RXHPF              0xf
+-#define RADIO_2056_SYN_RESERVED_ADDR16           0x10
+-#define RADIO_2056_SYN_RESERVED_ADDR17           0x11
+-#define RADIO_2056_SYN_RESERVED_ADDR18           0x12
+-#define RADIO_2056_SYN_RESERVED_ADDR19           0x13
+-#define RADIO_2056_SYN_RESERVED_ADDR20           0x14
+-#define RADIO_2056_SYN_RESERVED_ADDR21           0x15
+-#define RADIO_2056_SYN_RESERVED_ADDR22           0x16
+-#define RADIO_2056_SYN_RESERVED_ADDR23           0x17
+-#define RADIO_2056_SYN_RESERVED_ADDR24           0x18
+-#define RADIO_2056_SYN_RESERVED_ADDR25           0x19
+-#define RADIO_2056_SYN_RESERVED_ADDR26           0x1a
+-#define RADIO_2056_SYN_RESERVED_ADDR27           0x1b
+-#define RADIO_2056_SYN_RESERVED_ADDR28           0x1c
+-#define RADIO_2056_SYN_RESERVED_ADDR29           0x1d
+-#define RADIO_2056_SYN_RESERVED_ADDR30           0x1e
+-#define RADIO_2056_SYN_RESERVED_ADDR31           0x1f
+-#define RADIO_2056_SYN_GPIO_MASTER1              0x20
+-#define RADIO_2056_SYN_GPIO_MASTER2              0x21
+-#define RADIO_2056_SYN_TOPBIAS_MASTER            0x22
+-#define RADIO_2056_SYN_TOPBIAS_RCAL              0x23
+-#define RADIO_2056_SYN_AFEREG                    0x24
+-#define RADIO_2056_SYN_TEMPPROCSENSE             0x25
+-#define RADIO_2056_SYN_TEMPPROCSENSEIDAC         0x26
+-#define RADIO_2056_SYN_TEMPPROCSENSERCAL         0x27
+-#define RADIO_2056_SYN_LPO                       0x28
+-#define RADIO_2056_SYN_VDDCAL_MASTER             0x29
+-#define RADIO_2056_SYN_VDDCAL_IDAC               0x2a
+-#define RADIO_2056_SYN_VDDCAL_STATUS             0x2b
+-#define RADIO_2056_SYN_RCAL_MASTER               0x2c
+-#define RADIO_2056_SYN_RCAL_CODE_OUT             0x2d
+-#define RADIO_2056_SYN_RCCAL_CTRL0               0x2e
+-#define RADIO_2056_SYN_RCCAL_CTRL1               0x2f
+-#define RADIO_2056_SYN_RCCAL_CTRL2               0x30
+-#define RADIO_2056_SYN_RCCAL_CTRL3               0x31
+-#define RADIO_2056_SYN_RCCAL_CTRL4               0x32
+-#define RADIO_2056_SYN_RCCAL_CTRL5               0x33
+-#define RADIO_2056_SYN_RCCAL_CTRL6               0x34
+-#define RADIO_2056_SYN_RCCAL_CTRL7               0x35
+-#define RADIO_2056_SYN_RCCAL_CTRL8               0x36
+-#define RADIO_2056_SYN_RCCAL_CTRL9               0x37
+-#define RADIO_2056_SYN_RCCAL_CTRL10              0x38
+-#define RADIO_2056_SYN_RCCAL_CTRL11              0x39
+-#define RADIO_2056_SYN_ZCAL_SPARE1               0x3a
+-#define RADIO_2056_SYN_ZCAL_SPARE2               0x3b
+-#define RADIO_2056_SYN_PLL_MAST1                 0x3c
+-#define RADIO_2056_SYN_PLL_MAST2                 0x3d
+-#define RADIO_2056_SYN_PLL_MAST3                 0x3e
+-#define RADIO_2056_SYN_PLL_BIAS_RESET            0x3f
+-#define RADIO_2056_SYN_PLL_XTAL0                 0x40
+-#define RADIO_2056_SYN_PLL_XTAL1                 0x41
+-#define RADIO_2056_SYN_PLL_XTAL3                 0x42
+-#define RADIO_2056_SYN_PLL_XTAL4                 0x43
+-#define RADIO_2056_SYN_PLL_XTAL5                 0x44
+-#define RADIO_2056_SYN_PLL_XTAL6                 0x45
+-#define RADIO_2056_SYN_PLL_REFDIV                0x46
+-#define RADIO_2056_SYN_PLL_PFD                   0x47
+-#define RADIO_2056_SYN_PLL_CP1                   0x48
+-#define RADIO_2056_SYN_PLL_CP2                   0x49
+-#define RADIO_2056_SYN_PLL_CP3                   0x4a
+-#define RADIO_2056_SYN_PLL_LOOPFILTER1           0x4b
+-#define RADIO_2056_SYN_PLL_LOOPFILTER2           0x4c
+-#define RADIO_2056_SYN_PLL_LOOPFILTER3           0x4d
+-#define RADIO_2056_SYN_PLL_LOOPFILTER4           0x4e
+-#define RADIO_2056_SYN_PLL_LOOPFILTER5           0x4f
+-#define RADIO_2056_SYN_PLL_MMD1                  0x50
+-#define RADIO_2056_SYN_PLL_MMD2                  0x51
+-#define RADIO_2056_SYN_PLL_VCO1                  0x52
+-#define RADIO_2056_SYN_PLL_VCO2                  0x53
+-#define RADIO_2056_SYN_PLL_MONITOR1              0x54
+-#define RADIO_2056_SYN_PLL_MONITOR2              0x55
+-#define RADIO_2056_SYN_PLL_VCOCAL1               0x56
+-#define RADIO_2056_SYN_PLL_VCOCAL2               0x57
+-#define RADIO_2056_SYN_PLL_VCOCAL4               0x58
+-#define RADIO_2056_SYN_PLL_VCOCAL5               0x59
+-#define RADIO_2056_SYN_PLL_VCOCAL6               0x5a
+-#define RADIO_2056_SYN_PLL_VCOCAL7               0x5b
+-#define RADIO_2056_SYN_PLL_VCOCAL8               0x5c
+-#define RADIO_2056_SYN_PLL_VCOCAL9               0x5d
+-#define RADIO_2056_SYN_PLL_VCOCAL10              0x5e
+-#define RADIO_2056_SYN_PLL_VCOCAL11              0x5f
+-#define RADIO_2056_SYN_PLL_VCOCAL12              0x60
+-#define RADIO_2056_SYN_PLL_VCOCAL13              0x61
+-#define RADIO_2056_SYN_PLL_VREG                  0x62
+-#define RADIO_2056_SYN_PLL_STATUS1               0x63
+-#define RADIO_2056_SYN_PLL_STATUS2               0x64
+-#define RADIO_2056_SYN_PLL_STATUS3               0x65
+-#define RADIO_2056_SYN_LOGEN_PU0                 0x66
+-#define RADIO_2056_SYN_LOGEN_PU1                 0x67
+-#define RADIO_2056_SYN_LOGEN_PU2                 0x68
+-#define RADIO_2056_SYN_LOGEN_PU3                 0x69
+-#define RADIO_2056_SYN_LOGEN_PU5                 0x6a
+-#define RADIO_2056_SYN_LOGEN_PU6                 0x6b
+-#define RADIO_2056_SYN_LOGEN_PU7                 0x6c
+-#define RADIO_2056_SYN_LOGEN_PU8                 0x6d
+-#define RADIO_2056_SYN_LOGEN_BIAS_RESET          0x6e
+-#define RADIO_2056_SYN_LOGEN_RCCR1               0x6f
+-#define RADIO_2056_SYN_LOGEN_VCOBUF1             0x70
+-#define RADIO_2056_SYN_LOGEN_MIXER1              0x71
+-#define RADIO_2056_SYN_LOGEN_MIXER2              0x72
+-#define RADIO_2056_SYN_LOGEN_BUF1                0x73
+-#define RADIO_2056_SYN_LOGENBUF2                 0x74
+-#define RADIO_2056_SYN_LOGEN_BUF3                0x75
+-#define RADIO_2056_SYN_LOGEN_BUF4                0x76
+-#define RADIO_2056_SYN_LOGEN_DIV1                0x77
+-#define RADIO_2056_SYN_LOGEN_DIV2                0x78
+-#define RADIO_2056_SYN_LOGEN_DIV3                0x79
+-#define RADIO_2056_SYN_LOGEN_ACL1                0x7a
+-#define RADIO_2056_SYN_LOGEN_ACL2                0x7b
+-#define RADIO_2056_SYN_LOGEN_ACL3                0x7c
+-#define RADIO_2056_SYN_LOGEN_ACL4                0x7d
+-#define RADIO_2056_SYN_LOGEN_ACL5                0x7e
+-#define RADIO_2056_SYN_LOGEN_ACL6                0x7f
+-#define RADIO_2056_SYN_LOGEN_ACLOUT              0x80
+-#define RADIO_2056_SYN_LOGEN_ACLCAL1             0x81
+-#define RADIO_2056_SYN_LOGEN_ACLCAL2             0x82
+-#define RADIO_2056_SYN_LOGEN_ACLCAL3             0x83
+-#define RADIO_2056_SYN_CALEN                     0x84
+-#define RADIO_2056_SYN_LOGEN_PEAKDET1            0x85
+-#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR        0x86
+-#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR     0x87
+-#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR     0x88
+-#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR     0x89
+-#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR     0x8a
+-#define RADIO_2056_SYN_LOGEN_VCOBUF2             0x8b
+-#define RADIO_2056_SYN_LOGEN_MIXER3              0x8c
+-#define RADIO_2056_SYN_LOGEN_BUF5                0x8d
+-#define RADIO_2056_SYN_LOGEN_BUF6                0x8e
+-#define RADIO_2056_SYN_LOGEN_CBUFRX1             0x8f
+-#define RADIO_2056_SYN_LOGEN_CBUFRX2             0x90
+-#define RADIO_2056_SYN_LOGEN_CBUFRX3             0x91
+-#define RADIO_2056_SYN_LOGEN_CBUFRX4             0x92
+-#define RADIO_2056_SYN_LOGEN_CBUFTX1             0x93
+-#define RADIO_2056_SYN_LOGEN_CBUFTX2             0x94
+-#define RADIO_2056_SYN_LOGEN_CBUFTX3             0x95
+-#define RADIO_2056_SYN_LOGEN_CBUFTX4             0x96
+-#define RADIO_2056_SYN_LOGEN_CMOSRX1             0x97
+-#define RADIO_2056_SYN_LOGEN_CMOSRX2             0x98
+-#define RADIO_2056_SYN_LOGEN_CMOSRX3             0x99
+-#define RADIO_2056_SYN_LOGEN_CMOSRX4             0x9a
+-#define RADIO_2056_SYN_LOGEN_CMOSTX1             0x9b
+-#define RADIO_2056_SYN_LOGEN_CMOSTX2             0x9c
+-#define RADIO_2056_SYN_LOGEN_CMOSTX3             0x9d
+-#define RADIO_2056_SYN_LOGEN_CMOSTX4             0x9e
+-#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL      0x9f
+-#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL       0xa0
+-#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL         0xa1
+-#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL         0xa2
+-#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL      0xa3
+-#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL      0xa4
+-#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL      0xa5
+-#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL      0xa6
+-#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL      0xa7
+-#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL      0xa8
+-#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL      0xa9
+-#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL      0xaa
+-#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL      0xab
+-#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL      0xac
+-#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL      0xad
+-#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL      0xae
+-#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL      0xaf
+-#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL      0xb0
+-#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL      0xb1
+-#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL      0xb2
+-#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT         0xb3
+-#define RADIO_2056_SYN_LOGEN_CORE_CALVALID       0xb4
+-#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID    0xb5
+-#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID       0xb6
+-
+-#define RADIO_2056_TX_RESERVED_ADDR0             0x0
+-#define RADIO_2056_TX_IDCODE                     0x1
+-#define RADIO_2056_TX_RESERVED_ADDR2             0x2
+-#define RADIO_2056_TX_RESERVED_ADDR3             0x3
+-#define RADIO_2056_TX_RESERVED_ADDR4             0x4
+-#define RADIO_2056_TX_RESERVED_ADDR5             0x5
+-#define RADIO_2056_TX_RESERVED_ADDR6             0x6
+-#define RADIO_2056_TX_RESERVED_ADDR7             0x7
+-#define RADIO_2056_TX_COM_CTRL                   0x8
+-#define RADIO_2056_TX_COM_PU                     0x9
+-#define RADIO_2056_TX_COM_OVR                    0xa
+-#define RADIO_2056_TX_COM_RESET                  0xb
+-#define RADIO_2056_TX_COM_RCAL                   0xc
+-#define RADIO_2056_TX_COM_RC_RXLPF               0xd
+-#define RADIO_2056_TX_COM_RC_TXLPF               0xe
+-#define RADIO_2056_TX_COM_RC_RXHPF               0xf
+-#define RADIO_2056_TX_RESERVED_ADDR16            0x10
+-#define RADIO_2056_TX_RESERVED_ADDR17            0x11
+-#define RADIO_2056_TX_RESERVED_ADDR18            0x12
+-#define RADIO_2056_TX_RESERVED_ADDR19            0x13
+-#define RADIO_2056_TX_RESERVED_ADDR20            0x14
+-#define RADIO_2056_TX_RESERVED_ADDR21            0x15
+-#define RADIO_2056_TX_RESERVED_ADDR22            0x16
+-#define RADIO_2056_TX_RESERVED_ADDR23            0x17
+-#define RADIO_2056_TX_RESERVED_ADDR24            0x18
+-#define RADIO_2056_TX_RESERVED_ADDR25            0x19
+-#define RADIO_2056_TX_RESERVED_ADDR26            0x1a
+-#define RADIO_2056_TX_RESERVED_ADDR27            0x1b
+-#define RADIO_2056_TX_RESERVED_ADDR28            0x1c
+-#define RADIO_2056_TX_RESERVED_ADDR29            0x1d
+-#define RADIO_2056_TX_RESERVED_ADDR30            0x1e
+-#define RADIO_2056_TX_RESERVED_ADDR31            0x1f
+-#define RADIO_2056_TX_IQCAL_GAIN_BW              0x20
+-#define RADIO_2056_TX_LOFT_FINE_I                0x21
+-#define RADIO_2056_TX_LOFT_FINE_Q                0x22
+-#define RADIO_2056_TX_LOFT_COARSE_I              0x23
+-#define RADIO_2056_TX_LOFT_COARSE_Q              0x24
+-#define RADIO_2056_TX_TX_COM_MASTER1             0x25
+-#define RADIO_2056_TX_TX_COM_MASTER2             0x26
+-#define RADIO_2056_TX_RXIQCAL_TXMUX              0x27
+-#define RADIO_2056_TX_TX_SSI_MASTER              0x28
+-#define RADIO_2056_TX_IQCAL_VCM_HG               0x29
+-#define RADIO_2056_TX_IQCAL_IDAC                 0x2a
+-#define RADIO_2056_TX_TSSI_VCM                   0x2b
+-#define RADIO_2056_TX_TX_AMP_DET                 0x2c
+-#define RADIO_2056_TX_TX_SSI_MUX                 0x2d
+-#define RADIO_2056_TX_TSSIA                      0x2e
+-#define RADIO_2056_TX_TSSIG                      0x2f
+-#define RADIO_2056_TX_TSSI_MISC1                 0x30
+-#define RADIO_2056_TX_TSSI_MISC2                 0x31
+-#define RADIO_2056_TX_TSSI_MISC3                 0x32
+-#define RADIO_2056_TX_PA_SPARE1                  0x33
+-#define RADIO_2056_TX_PA_SPARE2                  0x34
+-#define RADIO_2056_TX_INTPAA_MASTER              0x35
+-#define RADIO_2056_TX_INTPAA_GAIN                0x36
+-#define RADIO_2056_TX_INTPAA_BOOST_TUNE          0x37
+-#define RADIO_2056_TX_INTPAA_IAUX_STAT           0x38
+-#define RADIO_2056_TX_INTPAA_IAUX_DYN            0x39
+-#define RADIO_2056_TX_INTPAA_IMAIN_STAT          0x3a
+-#define RADIO_2056_TX_INTPAA_IMAIN_DYN           0x3b
+-#define RADIO_2056_TX_INTPAA_CASCBIAS            0x3c
+-#define RADIO_2056_TX_INTPAA_PASLOPE             0x3d
+-#define RADIO_2056_TX_INTPAA_PA_MISC             0x3e
+-#define RADIO_2056_TX_INTPAG_MASTER              0x3f
+-#define RADIO_2056_TX_INTPAG_GAIN                0x40
+-#define RADIO_2056_TX_INTPAG_BOOST_TUNE          0x41
+-#define RADIO_2056_TX_INTPAG_IAUX_STAT           0x42
+-#define RADIO_2056_TX_INTPAG_IAUX_DYN            0x43
+-#define RADIO_2056_TX_INTPAG_IMAIN_STAT          0x44
+-#define RADIO_2056_TX_INTPAG_IMAIN_DYN           0x45
+-#define RADIO_2056_TX_INTPAG_CASCBIAS            0x46
+-#define RADIO_2056_TX_INTPAG_PASLOPE             0x47
+-#define RADIO_2056_TX_INTPAG_PA_MISC             0x48
+-#define RADIO_2056_TX_PADA_MASTER                0x49
+-#define RADIO_2056_TX_PADA_IDAC                  0x4a
+-#define RADIO_2056_TX_PADA_CASCBIAS              0x4b
+-#define RADIO_2056_TX_PADA_GAIN                  0x4c
+-#define RADIO_2056_TX_PADA_BOOST_TUNE            0x4d
+-#define RADIO_2056_TX_PADA_SLOPE                 0x4e
+-#define RADIO_2056_TX_PADG_MASTER                0x4f
+-#define RADIO_2056_TX_PADG_IDAC                  0x50
+-#define RADIO_2056_TX_PADG_CASCBIAS              0x51
+-#define RADIO_2056_TX_PADG_GAIN                  0x52
+-#define RADIO_2056_TX_PADG_BOOST_TUNE            0x53
+-#define RADIO_2056_TX_PADG_SLOPE                 0x54
+-#define RADIO_2056_TX_PGAA_MASTER                0x55
+-#define RADIO_2056_TX_PGAA_IDAC                  0x56
+-#define RADIO_2056_TX_PGAA_GAIN                  0x57
+-#define RADIO_2056_TX_PGAA_BOOST_TUNE            0x58
+-#define RADIO_2056_TX_PGAA_SLOPE                 0x59
+-#define RADIO_2056_TX_PGAA_MISC                  0x5a
+-#define RADIO_2056_TX_PGAG_MASTER                0x5b
+-#define RADIO_2056_TX_PGAG_IDAC                  0x5c
+-#define RADIO_2056_TX_PGAG_GAIN                  0x5d
+-#define RADIO_2056_TX_PGAG_BOOST_TUNE            0x5e
+-#define RADIO_2056_TX_PGAG_SLOPE                 0x5f
+-#define RADIO_2056_TX_PGAG_MISC                  0x60
+-#define RADIO_2056_TX_MIXA_MASTER                0x61
+-#define RADIO_2056_TX_MIXA_BOOST_TUNE            0x62
+-#define RADIO_2056_TX_MIXG                       0x63
+-#define RADIO_2056_TX_MIXG_BOOST_TUNE            0x64
+-#define RADIO_2056_TX_BB_GM_MASTER               0x65
+-#define RADIO_2056_TX_GMBB_GM                    0x66
+-#define RADIO_2056_TX_GMBB_IDAC                  0x67
+-#define RADIO_2056_TX_TXLPF_MASTER               0x68
+-#define RADIO_2056_TX_TXLPF_RCCAL                0x69
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF0           0x6a
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF1           0x6b
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF2           0x6c
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF3           0x6d
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF4           0x6e
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF5           0x6f
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF6           0x70
+-#define RADIO_2056_TX_TXLPF_BW                   0x71
+-#define RADIO_2056_TX_TXLPF_GAIN                 0x72
+-#define RADIO_2056_TX_TXLPF_IDAC                 0x73
+-#define RADIO_2056_TX_TXLPF_IDAC_0               0x74
+-#define RADIO_2056_TX_TXLPF_IDAC_1               0x75
+-#define RADIO_2056_TX_TXLPF_IDAC_2               0x76
+-#define RADIO_2056_TX_TXLPF_IDAC_3               0x77
+-#define RADIO_2056_TX_TXLPF_IDAC_4               0x78
+-#define RADIO_2056_TX_TXLPF_IDAC_5               0x79
+-#define RADIO_2056_TX_TXLPF_IDAC_6               0x7a
+-#define RADIO_2056_TX_TXLPF_OPAMP_IDAC           0x7b
+-#define RADIO_2056_TX_TXLPF_MISC                 0x7c
+-#define RADIO_2056_TX_TXSPARE1                   0x7d
+-#define RADIO_2056_TX_TXSPARE2                   0x7e
+-#define RADIO_2056_TX_TXSPARE3                   0x7f
+-#define RADIO_2056_TX_TXSPARE4                   0x80
+-#define RADIO_2056_TX_TXSPARE5                   0x81
+-#define RADIO_2056_TX_TXSPARE6                   0x82
+-#define RADIO_2056_TX_TXSPARE7                   0x83
+-#define RADIO_2056_TX_TXSPARE8                   0x84
+-#define RADIO_2056_TX_TXSPARE9                   0x85
+-#define RADIO_2056_TX_TXSPARE10                  0x86
+-#define RADIO_2056_TX_TXSPARE11                  0x87
+-#define RADIO_2056_TX_TXSPARE12                  0x88
+-#define RADIO_2056_TX_TXSPARE13                  0x89
+-#define RADIO_2056_TX_TXSPARE14                  0x8a
+-#define RADIO_2056_TX_TXSPARE15                  0x8b
+-#define RADIO_2056_TX_TXSPARE16                  0x8c
+-#define RADIO_2056_TX_STATUS_INTPA_GAIN          0x8d
+-#define RADIO_2056_TX_STATUS_PAD_GAIN            0x8e
+-#define RADIO_2056_TX_STATUS_PGA_GAIN            0x8f
+-#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN       0x90
+-#define RADIO_2056_TX_STATUS_TXLPF_BW            0x91
+-#define RADIO_2056_TX_STATUS_TXLPF_RC            0x92
+-#define RADIO_2056_TX_GMBB_IDAC0                 0x93
+-#define RADIO_2056_TX_GMBB_IDAC1                 0x94
+-#define RADIO_2056_TX_GMBB_IDAC2                 0x95
+-#define RADIO_2056_TX_GMBB_IDAC3                 0x96
+-#define RADIO_2056_TX_GMBB_IDAC4                 0x97
+-#define RADIO_2056_TX_GMBB_IDAC5                 0x98
+-#define RADIO_2056_TX_GMBB_IDAC6                 0x99
+-#define RADIO_2056_TX_GMBB_IDAC7                 0x9a
+-
+-#define RADIO_2056_RX_RESERVED_ADDR0             0x0
+-#define RADIO_2056_RX_IDCODE                     0x1
+-#define RADIO_2056_RX_RESERVED_ADDR2             0x2
+-#define RADIO_2056_RX_RESERVED_ADDR3             0x3
+-#define RADIO_2056_RX_RESERVED_ADDR4             0x4
+-#define RADIO_2056_RX_RESERVED_ADDR5             0x5
+-#define RADIO_2056_RX_RESERVED_ADDR6             0x6
+-#define RADIO_2056_RX_RESERVED_ADDR7             0x7
+-#define RADIO_2056_RX_COM_CTRL                   0x8
+-#define RADIO_2056_RX_COM_PU                     0x9
+-#define RADIO_2056_RX_COM_OVR                    0xa
+-#define RADIO_2056_RX_COM_RESET                  0xb
+-#define RADIO_2056_RX_COM_RCAL                   0xc
+-#define RADIO_2056_RX_COM_RC_RXLPF               0xd
+-#define RADIO_2056_RX_COM_RC_TXLPF               0xe
+-#define RADIO_2056_RX_COM_RC_RXHPF               0xf
+-#define RADIO_2056_RX_RESERVED_ADDR16            0x10
+-#define RADIO_2056_RX_RESERVED_ADDR17            0x11
+-#define RADIO_2056_RX_RESERVED_ADDR18            0x12
+-#define RADIO_2056_RX_RESERVED_ADDR19            0x13
+-#define RADIO_2056_RX_RESERVED_ADDR20            0x14
+-#define RADIO_2056_RX_RESERVED_ADDR21            0x15
+-#define RADIO_2056_RX_RESERVED_ADDR22            0x16
+-#define RADIO_2056_RX_RESERVED_ADDR23            0x17
+-#define RADIO_2056_RX_RESERVED_ADDR24            0x18
+-#define RADIO_2056_RX_RESERVED_ADDR25            0x19
+-#define RADIO_2056_RX_RESERVED_ADDR26            0x1a
+-#define RADIO_2056_RX_RESERVED_ADDR27            0x1b
+-#define RADIO_2056_RX_RESERVED_ADDR28            0x1c
+-#define RADIO_2056_RX_RESERVED_ADDR29            0x1d
+-#define RADIO_2056_RX_RESERVED_ADDR30            0x1e
+-#define RADIO_2056_RX_RESERVED_ADDR31            0x1f
+-#define RADIO_2056_RX_RXIQCAL_RXMUX              0x20
+-#define RADIO_2056_RX_RSSI_PU                    0x21
+-#define RADIO_2056_RX_RSSI_SEL                   0x22
+-#define RADIO_2056_RX_RSSI_GAIN                  0x23
+-#define RADIO_2056_RX_RSSI_NB_IDAC               0x24
+-#define RADIO_2056_RX_RSSI_WB2I_IDAC_1           0x25
+-#define RADIO_2056_RX_RSSI_WB2I_IDAC_2           0x26
+-#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1           0x27
+-#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2           0x28
+-#define RADIO_2056_RX_RSSI_POLE                  0x29
+-#define RADIO_2056_RX_RSSI_WB1_IDAC              0x2a
+-#define RADIO_2056_RX_RSSI_MISC                  0x2b
+-#define RADIO_2056_RX_LNAA_MASTER                0x2c
+-#define RADIO_2056_RX_LNAA_TUNE                  0x2d
+-#define RADIO_2056_RX_LNAA_GAIN                  0x2e
+-#define RADIO_2056_RX_LNA_A_SLOPE                0x2f
+-#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC        0x30
+-#define RADIO_2056_RX_LNAA2_IDAC                 0x31
+-#define RADIO_2056_RX_LNA1A_MISC                 0x32
+-#define RADIO_2056_RX_LNAG_MASTER                0x33
+-#define RADIO_2056_RX_LNAG_TUNE                  0x34
+-#define RADIO_2056_RX_LNAG_GAIN                  0x35
+-#define RADIO_2056_RX_LNA_G_SLOPE                0x36
+-#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC        0x37
+-#define RADIO_2056_RX_LNAG2_IDAC                 0x38
+-#define RADIO_2056_RX_LNA1G_MISC                 0x39
+-#define RADIO_2056_RX_MIXA_MASTER                0x3a
+-#define RADIO_2056_RX_MIXA_VCM                   0x3b
+-#define RADIO_2056_RX_MIXA_CTRLPTAT              0x3c
+-#define RADIO_2056_RX_MIXA_LOB_BIAS              0x3d
+-#define RADIO_2056_RX_MIXA_CORE_IDAC             0x3e
+-#define RADIO_2056_RX_MIXA_CMFB_IDAC             0x3f
+-#define RADIO_2056_RX_MIXA_BIAS_AUX              0x40
+-#define RADIO_2056_RX_MIXA_BIAS_MAIN             0x41
+-#define RADIO_2056_RX_MIXA_BIAS_MISC             0x42
+-#define RADIO_2056_RX_MIXA_MAST_BIAS             0x43
+-#define RADIO_2056_RX_MIXG_MASTER                0x44
+-#define RADIO_2056_RX_MIXG_VCM                   0x45
+-#define RADIO_2056_RX_MIXG_CTRLPTAT              0x46
+-#define RADIO_2056_RX_MIXG_LOB_BIAS              0x47
+-#define RADIO_2056_RX_MIXG_CORE_IDAC             0x48
+-#define RADIO_2056_RX_MIXG_CMFB_IDAC             0x49
+-#define RADIO_2056_RX_MIXG_BIAS_AUX              0x4a
+-#define RADIO_2056_RX_MIXG_BIAS_MAIN             0x4b
+-#define RADIO_2056_RX_MIXG_BIAS_MISC             0x4c
+-#define RADIO_2056_RX_MIXG_MAST_BIAS             0x4d
+-#define RADIO_2056_RX_TIA_MASTER                 0x4e
+-#define RADIO_2056_RX_TIA_IOPAMP                 0x4f
+-#define RADIO_2056_RX_TIA_QOPAMP                 0x50
+-#define RADIO_2056_RX_TIA_IMISC                  0x51
+-#define RADIO_2056_RX_TIA_QMISC                  0x52
+-#define RADIO_2056_RX_TIA_GAIN                   0x53
+-#define RADIO_2056_RX_TIA_SPARE1                 0x54
+-#define RADIO_2056_RX_TIA_SPARE2                 0x55
+-#define RADIO_2056_RX_BB_LPF_MASTER              0x56
+-#define RADIO_2056_RX_AACI_MASTER                0x57
+-#define RADIO_2056_RX_RXLPF_IDAC                 0x58
+-#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ       0x59
+-#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ      0x5a
+-#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL        0x5b
+-#define RADIO_2056_RX_RXLPF_OUTVCM               0x5c
+-#define RADIO_2056_RX_RXLPF_INVCM_BODY           0x5d
+-#define RADIO_2056_RX_RXLPF_CC_OP                0x5e
+-#define RADIO_2056_RX_RXLPF_GAIN                 0x5f
+-#define RADIO_2056_RX_RXLPF_Q_BW                 0x60
+-#define RADIO_2056_RX_RXLPF_HP_CORNER_BW         0x61
+-#define RADIO_2056_RX_RXLPF_RCCAL_HPC            0x62
+-#define RADIO_2056_RX_RXHPF_OFF0                 0x63
+-#define RADIO_2056_RX_RXHPF_OFF1                 0x64
+-#define RADIO_2056_RX_RXHPF_OFF2                 0x65
+-#define RADIO_2056_RX_RXHPF_OFF3                 0x66
+-#define RADIO_2056_RX_RXHPF_OFF4                 0x67
+-#define RADIO_2056_RX_RXHPF_OFF5                 0x68
+-#define RADIO_2056_RX_RXHPF_OFF6                 0x69
+-#define RADIO_2056_RX_RXHPF_OFF7                 0x6a
+-#define RADIO_2056_RX_RXLPF_RCCAL_LPC            0x6b
+-#define RADIO_2056_RX_RXLPF_OFF_0                0x6c
+-#define RADIO_2056_RX_RXLPF_OFF_1                0x6d
+-#define RADIO_2056_RX_RXLPF_OFF_2                0x6e
+-#define RADIO_2056_RX_RXLPF_OFF_3                0x6f
+-#define RADIO_2056_RX_RXLPF_OFF_4                0x70
+-#define RADIO_2056_RX_UNUSED                     0x71
+-#define RADIO_2056_RX_VGA_MASTER                 0x72
+-#define RADIO_2056_RX_VGA_BIAS                   0x73
+-#define RADIO_2056_RX_VGA_BIAS_DCCANCEL          0x74
+-#define RADIO_2056_RX_VGA_GAIN                   0x75
+-#define RADIO_2056_RX_VGA_HP_CORNER_BW           0x76
+-#define RADIO_2056_RX_VGABUF_BIAS                0x77
+-#define RADIO_2056_RX_VGABUF_GAIN_BW             0x78
+-#define RADIO_2056_RX_TXFBMIX_A                  0x79
+-#define RADIO_2056_RX_TXFBMIX_G                  0x7a
+-#define RADIO_2056_RX_RXSPARE1                   0x7b
+-#define RADIO_2056_RX_RXSPARE2                   0x7c
+-#define RADIO_2056_RX_RXSPARE3                   0x7d
+-#define RADIO_2056_RX_RXSPARE4                   0x7e
+-#define RADIO_2056_RX_RXSPARE5                   0x7f
+-#define RADIO_2056_RX_RXSPARE6                   0x80
+-#define RADIO_2056_RX_RXSPARE7                   0x81
+-#define RADIO_2056_RX_RXSPARE8                   0x82
+-#define RADIO_2056_RX_RXSPARE9                   0x83
+-#define RADIO_2056_RX_RXSPARE10                  0x84
+-#define RADIO_2056_RX_RXSPARE11                  0x85
+-#define RADIO_2056_RX_RXSPARE12                  0x86
+-#define RADIO_2056_RX_RXSPARE13                  0x87
+-#define RADIO_2056_RX_RXSPARE14                  0x88
+-#define RADIO_2056_RX_RXSPARE15                  0x89
+-#define RADIO_2056_RX_RXSPARE16                  0x8a
+-#define RADIO_2056_RX_STATUS_LNAA_GAIN           0x8b
+-#define RADIO_2056_RX_STATUS_LNAG_GAIN           0x8c
+-#define RADIO_2056_RX_STATUS_MIXTIA_GAIN         0x8d
+-#define RADIO_2056_RX_STATUS_RXLPF_GAIN          0x8e
+-#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN        0x8f
+-#define RADIO_2056_RX_STATUS_RXLPF_Q             0x90
+-#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW        0x91
+-#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC       0x92
+-#define RADIO_2056_RX_STATUS_RXLPF_RC            0x93
+-#define RADIO_2056_RX_STATUS_HPC_RC              0x94
+-
+-#define RADIO_2056_LNA1_A_PU		0x01
+-#define RADIO_2056_LNA2_A_PU		0x02
+-#define RADIO_2056_LNA1_G_PU		0x01
+-#define RADIO_2056_LNA2_G_PU		0x02
+-#define RADIO_2056_MIXA_PU_I		0x01
+-#define RADIO_2056_MIXA_PU_Q		0x02
+-#define RADIO_2056_MIXA_PU_GM		0x10
+-#define RADIO_2056_MIXG_PU_I		0x01
+-#define RADIO_2056_MIXG_PU_Q		0x02
+-#define RADIO_2056_MIXG_PU_GM		0x10
+-#define RADIO_2056_TIA_PU			0x01
+-#define RADIO_2056_BB_LPF_PU		0x20
+-#define RADIO_2056_W1_PU			0x02
+-#define RADIO_2056_W2_PU			0x04
+-#define RADIO_2056_NB_PU			0x08
+-#define RADIO_2056_RSSI_W1_SEL		0x02
+-#define RADIO_2056_RSSI_W2_SEL		0x04
+-#define RADIO_2056_RSSI_NB_SEL		0x08
+-#define RADIO_2056_VCM_MASK			0x1c
+-#define RADIO_2056_RSSI_VCM_SHIFT	0x02
+-
+-#define RADIO_2057_DACBUF_VINCM_CORE0            0x0
+-#define RADIO_2057_IDCODE                        0x1
+-#define RADIO_2057_RCCAL_MASTER                  0x2
+-#define RADIO_2057_RCCAL_CAP_SIZE                0x3
+-#define RADIO_2057_RCAL_CONFIG                   0x4
+-#define RADIO_2057_GPAIO_CONFIG                  0x5
+-#define RADIO_2057_GPAIO_SEL1                    0x6
+-#define RADIO_2057_GPAIO_SEL0                    0x7
+-#define RADIO_2057_CLPO_CONFIG                   0x8
+-#define RADIO_2057_BANDGAP_CONFIG                0x9
+-#define RADIO_2057_BANDGAP_RCAL_TRIM             0xa
+-#define RADIO_2057_AFEREG_CONFIG                 0xb
+-#define RADIO_2057_TEMPSENSE_CONFIG              0xc
+-#define RADIO_2057_XTAL_CONFIG1                  0xd
+-#define RADIO_2057_XTAL_ICORE_SIZE               0xe
+-#define RADIO_2057_XTAL_BUF_SIZE                 0xf
+-#define RADIO_2057_XTAL_PULLCAP_SIZE             0x10
+-#define RADIO_2057_RFPLL_MASTER                  0x11
+-#define RADIO_2057_VCOMONITOR_VTH_L              0x12
+-#define RADIO_2057_VCOMONITOR_VTH_H              0x13
+-#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
+-#define RADIO_2057_VCO_VARCSIZE_IDAC             0x15
+-#define RADIO_2057_VCOCAL_COUNTVAL0              0x16
+-#define RADIO_2057_VCOCAL_COUNTVAL1              0x17
+-#define RADIO_2057_VCOCAL_INTCLK_COUNT           0x18
+-#define RADIO_2057_VCOCAL_MASTER                 0x19
+-#define RADIO_2057_VCOCAL_NUMCAPCHANGE           0x1a
+-#define RADIO_2057_VCOCAL_WINSIZE                0x1b
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH    0x1c
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP  0x1d
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP   0x1e
+-#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP  0x1f
+-#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1      0x20
+-#define RADIO_2057_VCO_FORCECAP0                 0x21
+-#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
+-#define RADIO_2057_RFPLL_PFD_RESET_PW            0x23
+-#define RADIO_2057_RFPLL_LOOPFILTER_R2           0x24
+-#define RADIO_2057_RFPLL_LOOPFILTER_R1           0x25
+-#define RADIO_2057_RFPLL_LOOPFILTER_C3           0x26
+-#define RADIO_2057_RFPLL_LOOPFILTER_C2           0x27
+-#define RADIO_2057_RFPLL_LOOPFILTER_C1           0x28
+-#define RADIO_2057_CP_KPD_IDAC                   0x29
+-#define RADIO_2057_RFPLL_IDACS                   0x2a
+-#define RADIO_2057_RFPLL_MISC_EN                 0x2b
+-#define RADIO_2057_RFPLL_MMD0                    0x2c
+-#define RADIO_2057_RFPLL_MMD1                    0x2d
+-#define RADIO_2057_RFPLL_MISC_CAL_RESETN         0x2e
+-#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES  0x2f
+-#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE     0x30
+-#define RADIO_2057_VCOCAL_READCAP0               0x31
+-#define RADIO_2057_VCOCAL_READCAP1               0x32
+-#define RADIO_2057_VCOCAL_STATUS                 0x33
+-#define RADIO_2057_LOGEN_PUS                     0x34
+-#define RADIO_2057_LOGEN_PTAT_RESETS             0x35
+-#define RADIO_2057_VCOBUF_IDACS                  0x36
+-#define RADIO_2057_VCOBUF_TUNE                   0x37
+-#define RADIO_2057_CMOSBUF_TX2GQ_IDACS           0x38
+-#define RADIO_2057_CMOSBUF_TX2GI_IDACS           0x39
+-#define RADIO_2057_CMOSBUF_TX5GQ_IDACS           0x3a
+-#define RADIO_2057_CMOSBUF_TX5GI_IDACS           0x3b
+-#define RADIO_2057_CMOSBUF_RX2GQ_IDACS           0x3c
+-#define RADIO_2057_CMOSBUF_RX2GI_IDACS           0x3d
+-#define RADIO_2057_CMOSBUF_RX5GQ_IDACS           0x3e
+-#define RADIO_2057_CMOSBUF_RX5GI_IDACS           0x3f
+-#define RADIO_2057_LOGEN_MX2G_IDACS              0x40
+-#define RADIO_2057_LOGEN_MX2G_TUNE               0x41
+-#define RADIO_2057_LOGEN_MX5G_IDACS              0x42
+-#define RADIO_2057_LOGEN_MX5G_TUNE               0x43
+-#define RADIO_2057_LOGEN_MX5G_RCCR               0x44
+-#define RADIO_2057_LOGEN_INDBUF2G_IDAC           0x45
+-#define RADIO_2057_LOGEN_INDBUF2G_IBOOST         0x46
+-#define RADIO_2057_LOGEN_INDBUF2G_TUNE           0x47
+-#define RADIO_2057_LOGEN_INDBUF5G_IDAC           0x48
+-#define RADIO_2057_LOGEN_INDBUF5G_IBOOST         0x49
+-#define RADIO_2057_LOGEN_INDBUF5G_TUNE           0x4a
+-#define RADIO_2057_CMOSBUF_TX_RCCR               0x4b
+-#define RADIO_2057_CMOSBUF_RX_RCCR               0x4c
+-#define RADIO_2057_LOGEN_SEL_PKDET               0x4d
+-#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT          0x4e
+-#define RADIO_2057_RXTXBIAS_CONFIG_CORE0         0x4f
+-#define RADIO_2057_TXGM_TXRF_PUS_CORE0           0x50
+-#define RADIO_2057_TXGM_IDAC_BLEED_CORE0         0x51
+-#define RADIO_2057_TXGM_GAIN_CORE0               0x56
+-#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0        0x57
+-#define RADIO_2057_PAD2G_PTATS_CORE0             0x58
+-#define RADIO_2057_PAD2G_IDACS_CORE0             0x59
+-#define RADIO_2057_PAD2G_BOOST_PU_CORE0          0x5a
+-#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0        0x5b
+-#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0   0x5c
+-#define RADIO_2057_TXMIX2G_LODC_CORE0            0x5d
+-#define RADIO_2057_PAD2G_TUNE_PUS_CORE0          0x5e
+-#define RADIO_2057_IPA2G_GAIN_CORE0              0x5f
+-#define RADIO_2057_TSSI2G_SPARE1_CORE0           0x60
+-#define RADIO_2057_TSSI2G_SPARE2_CORE0           0x61
+-#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0  0x62
+-#define RADIO_2057_IPA2G_IMAIN_CORE0             0x63
+-#define RADIO_2057_IPA2G_CASCONV_CORE0           0x64
+-#define RADIO_2057_IPA2G_CASCOFFV_CORE0          0x65
+-#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0       0x66
+-#define RADIO_2057_TX5G_PKDET_CORE0              0x69
+-#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0      0x6a
+-#define RADIO_2057_PAD5G_PTATS1_CORE0            0x6b
+-#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0      0x6c
+-#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0     0x6d
+-#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0       0x6e
+-#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
+-#define RADIO_2057_PGA_BOOST_TUNE_CORE0          0x70
+-#define RADIO_2057_PGA_GAIN_CORE0                0x71
+-#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
+-#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0      0x73
+-#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0     0x74
+-#define RADIO_2057_IPA5G_IAUX_CORE0              0x75
+-#define RADIO_2057_IPA5G_GAIN_CORE0              0x76
+-#define RADIO_2057_TSSI5G_SPARE1_CORE0           0x77
+-#define RADIO_2057_TSSI5G_SPARE2_CORE0           0x78
+-#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0       0x79
+-#define RADIO_2057_IPA5G_PTAT_CORE0              0x7a
+-#define RADIO_2057_IPA5G_IMAIN_CORE0             0x7b
+-#define RADIO_2057_IPA5G_CASCONV_CORE0           0x7c
+-#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0       0x7d
+-#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0     0x80
+-#define RADIO_2057_TR2G_CONFIG1_CORE0_NU         0x81
+-#define RADIO_2057_TR2G_CONFIG2_CORE0_NU         0x82
+-#define RADIO_2057_LNA5G_RFEN_CORE0              0x83
+-#define RADIO_2057_TR5G_CONFIG2_CORE0_NU         0x84
+-#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0      0x85
+-#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
+-#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0  0x87
+-#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0   0x88
+-#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0      0x89
+-#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0      0x8a
+-#define RADIO_2057_LNA2_IAUX_PTAT_CORE0          0x8b
+-#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0      0x8c
+-#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
+-#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0        0x8e
+-#define RADIO_2057_TIA_CONFIG_CORE0              0x8f
+-#define RADIO_2057_TIA_IQGAIN_CORE0              0x90
+-#define RADIO_2057_TIA_IBIAS2_CORE0              0x91
+-#define RADIO_2057_TIA_IBIAS1_CORE0              0x92
+-#define RADIO_2057_TIA_SPARE_Q_CORE0             0x93
+-#define RADIO_2057_TIA_SPARE_I_CORE0             0x94
+-#define RADIO_2057_RXMIX2G_PUS_CORE0             0x95
+-#define RADIO_2057_RXMIX2G_VCMREFS_CORE0         0x96
+-#define RADIO_2057_RXMIX2G_LODC_QI_CORE0         0x97
+-#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0       0x98
+-#define RADIO_2057_LNA2G_GAIN_CORE0              0x99
+-#define RADIO_2057_LNA2G_TUNE_CORE0              0x9a
+-#define RADIO_2057_RXMIX5G_PUS_CORE0             0x9b
+-#define RADIO_2057_RXMIX5G_VCMREFS_CORE0         0x9c
+-#define RADIO_2057_RXMIX5G_LODC_QI_CORE0         0x9d
+-#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0       0x9e
+-#define RADIO_2057_LNA5G_GAIN_CORE0              0x9f
+-#define RADIO_2057_LNA5G_TUNE_CORE0              0xa0
+-#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0    0xa1
+-#define RADIO_2057_RXBB_BIAS_MASTER_CORE0        0xa2
+-#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0       0xa3
+-#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
+-#define RADIO_2057_TXBUF_VINCM_CORE0             0xa5
+-#define RADIO_2057_TXBUF_IDACS_CORE0             0xa6
+-#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0       0xa7
+-#define RADIO_2057_RXBB_CC_CORE0                 0xa8
+-#define RADIO_2057_RXBB_SPARE3_CORE0             0xa9
+-#define RADIO_2057_RXBB_RCCAL_HPC_CORE0          0xaa
+-#define RADIO_2057_LPF_IDACS_CORE0               0xab
+-#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0  0xac
+-#define RADIO_2057_TXBUF_GAIN_CORE0              0xad
+-#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0   0xae
+-#define RADIO_2057_RXBUF_DEGEN_CORE0             0xaf
+-#define RADIO_2057_RXBB_SPARE2_CORE0             0xb0
+-#define RADIO_2057_RXBB_SPARE1_CORE0             0xb1
+-#define RADIO_2057_RSSI_MASTER_CORE0             0xb2
+-#define RADIO_2057_W2_MASTER_CORE0               0xb3
+-#define RADIO_2057_NB_MASTER_CORE0               0xb4
+-#define RADIO_2057_W2_IDACS0_Q_CORE0             0xb5
+-#define RADIO_2057_W2_IDACS1_Q_CORE0             0xb6
+-#define RADIO_2057_W2_IDACS0_I_CORE0             0xb7
+-#define RADIO_2057_W2_IDACS1_I_CORE0             0xb8
+-#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0  0xb9
+-#define RADIO_2057_NB_IDACS_Q_CORE0              0xba
+-#define RADIO_2057_NB_IDACS_I_CORE0              0xbb
+-#define RADIO_2057_BACKUP4_CORE0                 0xc1
+-#define RADIO_2057_BACKUP3_CORE0                 0xc2
+-#define RADIO_2057_BACKUP2_CORE0                 0xc3
+-#define RADIO_2057_BACKUP1_CORE0                 0xc4
+-#define RADIO_2057_SPARE16_CORE0                 0xc5
+-#define RADIO_2057_SPARE15_CORE0                 0xc6
+-#define RADIO_2057_SPARE14_CORE0                 0xc7
+-#define RADIO_2057_SPARE13_CORE0                 0xc8
+-#define RADIO_2057_SPARE12_CORE0                 0xc9
+-#define RADIO_2057_SPARE11_CORE0                 0xca
+-#define RADIO_2057_TX2G_BIAS_RESETS_CORE0        0xcb
+-#define RADIO_2057_TX5G_BIAS_RESETS_CORE0        0xcc
+-#define RADIO_2057_IQTEST_SEL_PU                 0xcd
+-#define RADIO_2057_XTAL_CONFIG2                  0xce
+-#define RADIO_2057_BUFS_MISC_LPFBW_CORE0         0xcf
+-#define RADIO_2057_TXLPF_RCCAL_CORE0             0xd0
+-#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
+-#define RADIO_2057_LPF_GAIN_CORE0                0xd2
+-#define RADIO_2057_DACBUF_IDACS_BW_CORE0         0xd3
+-#define RADIO_2057_RXTXBIAS_CONFIG_CORE1         0xd4
+-#define RADIO_2057_TXGM_TXRF_PUS_CORE1           0xd5
+-#define RADIO_2057_TXGM_IDAC_BLEED_CORE1         0xd6
+-#define RADIO_2057_TXGM_GAIN_CORE1               0xdb
+-#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1        0xdc
+-#define RADIO_2057_PAD2G_PTATS_CORE1             0xdd
+-#define RADIO_2057_PAD2G_IDACS_CORE1             0xde
+-#define RADIO_2057_PAD2G_BOOST_PU_CORE1          0xdf
+-#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1        0xe0
+-#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1   0xe1
+-#define RADIO_2057_TXMIX2G_LODC_CORE1            0xe2
+-#define RADIO_2057_PAD2G_TUNE_PUS_CORE1          0xe3
+-#define RADIO_2057_IPA2G_GAIN_CORE1              0xe4
+-#define RADIO_2057_TSSI2G_SPARE1_CORE1           0xe5
+-#define RADIO_2057_TSSI2G_SPARE2_CORE1           0xe6
+-#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1  0xe7
+-#define RADIO_2057_IPA2G_IMAIN_CORE1             0xe8
+-#define RADIO_2057_IPA2G_CASCONV_CORE1           0xe9
+-#define RADIO_2057_IPA2G_CASCOFFV_CORE1          0xea
+-#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1       0xeb
+-#define RADIO_2057_TX5G_PKDET_CORE1              0xee
+-#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1      0xef
+-#define RADIO_2057_PAD5G_PTATS1_CORE1            0xf0
+-#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1      0xf1
+-#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1     0xf2
+-#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1       0xf3
+-#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
+-#define RADIO_2057_PGA_BOOST_TUNE_CORE1          0xf5
+-#define RADIO_2057_PGA_GAIN_CORE1                0xf6
+-#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
+-#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1      0xf8
+-#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1     0xf9
+-#define RADIO_2057_IPA5G_IAUX_CORE1              0xfa
+-#define RADIO_2057_IPA5G_GAIN_CORE1              0xfb
+-#define RADIO_2057_TSSI5G_SPARE1_CORE1           0xfc
+-#define RADIO_2057_TSSI5G_SPARE2_CORE1           0xfd
+-#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1       0xfe
+-#define RADIO_2057_IPA5G_PTAT_CORE1              0xff
+-#define RADIO_2057_IPA5G_IMAIN_CORE1             0x100
+-#define RADIO_2057_IPA5G_CASCONV_CORE1           0x101
+-#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1       0x102
+-#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1     0x105
+-#define RADIO_2057_TR2G_CONFIG1_CORE1_NU         0x106
+-#define RADIO_2057_TR2G_CONFIG2_CORE1_NU         0x107
+-#define RADIO_2057_LNA5G_RFEN_CORE1              0x108
+-#define RADIO_2057_TR5G_CONFIG2_CORE1_NU         0x109
+-#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1      0x10a
+-#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
+-#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1  0x10c
+-#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1   0x10d
+-#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1      0x10e
+-#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1      0x10f
+-#define RADIO_2057_LNA2_IAUX_PTAT_CORE1          0x110
+-#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1      0x111
+-#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
+-#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1        0x113
+-#define RADIO_2057_TIA_CONFIG_CORE1              0x114
+-#define RADIO_2057_TIA_IQGAIN_CORE1              0x115
+-#define RADIO_2057_TIA_IBIAS2_CORE1              0x116
+-#define RADIO_2057_TIA_IBIAS1_CORE1              0x117
+-#define RADIO_2057_TIA_SPARE_Q_CORE1             0x118
+-#define RADIO_2057_TIA_SPARE_I_CORE1             0x119
+-#define RADIO_2057_RXMIX2G_PUS_CORE1             0x11a
+-#define RADIO_2057_RXMIX2G_VCMREFS_CORE1         0x11b
+-#define RADIO_2057_RXMIX2G_LODC_QI_CORE1         0x11c
+-#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1       0x11d
+-#define RADIO_2057_LNA2G_GAIN_CORE1              0x11e
+-#define RADIO_2057_LNA2G_TUNE_CORE1              0x11f
+-#define RADIO_2057_RXMIX5G_PUS_CORE1             0x120
+-#define RADIO_2057_RXMIX5G_VCMREFS_CORE1         0x121
+-#define RADIO_2057_RXMIX5G_LODC_QI_CORE1         0x122
+-#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1       0x123
+-#define RADIO_2057_LNA5G_GAIN_CORE1              0x124
+-#define RADIO_2057_LNA5G_TUNE_CORE1              0x125
+-#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1    0x126
+-#define RADIO_2057_RXBB_BIAS_MASTER_CORE1        0x127
+-#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1       0x128
+-#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
+-#define RADIO_2057_TXBUF_VINCM_CORE1             0x12a
+-#define RADIO_2057_TXBUF_IDACS_CORE1             0x12b
+-#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1       0x12c
+-#define RADIO_2057_RXBB_CC_CORE1                 0x12d
+-#define RADIO_2057_RXBB_SPARE3_CORE1             0x12e
+-#define RADIO_2057_RXBB_RCCAL_HPC_CORE1          0x12f
+-#define RADIO_2057_LPF_IDACS_CORE1               0x130
+-#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1  0x131
+-#define RADIO_2057_TXBUF_GAIN_CORE1              0x132
+-#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1   0x133
+-#define RADIO_2057_RXBUF_DEGEN_CORE1             0x134
+-#define RADIO_2057_RXBB_SPARE2_CORE1             0x135
+-#define RADIO_2057_RXBB_SPARE1_CORE1             0x136
+-#define RADIO_2057_RSSI_MASTER_CORE1             0x137
+-#define RADIO_2057_W2_MASTER_CORE1               0x138
+-#define RADIO_2057_NB_MASTER_CORE1               0x139
+-#define RADIO_2057_W2_IDACS0_Q_CORE1             0x13a
+-#define RADIO_2057_W2_IDACS1_Q_CORE1             0x13b
+-#define RADIO_2057_W2_IDACS0_I_CORE1             0x13c
+-#define RADIO_2057_W2_IDACS1_I_CORE1             0x13d
+-#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1  0x13e
+-#define RADIO_2057_NB_IDACS_Q_CORE1              0x13f
+-#define RADIO_2057_NB_IDACS_I_CORE1              0x140
+-#define RADIO_2057_BACKUP4_CORE1                 0x146
+-#define RADIO_2057_BACKUP3_CORE1                 0x147
+-#define RADIO_2057_BACKUP2_CORE1                 0x148
+-#define RADIO_2057_BACKUP1_CORE1                 0x149
+-#define RADIO_2057_SPARE16_CORE1                 0x14a
+-#define RADIO_2057_SPARE15_CORE1                 0x14b
+-#define RADIO_2057_SPARE14_CORE1                 0x14c
+-#define RADIO_2057_SPARE13_CORE1                 0x14d
+-#define RADIO_2057_SPARE12_CORE1                 0x14e
+-#define RADIO_2057_SPARE11_CORE1                 0x14f
+-#define RADIO_2057_TX2G_BIAS_RESETS_CORE1        0x150
+-#define RADIO_2057_TX5G_BIAS_RESETS_CORE1        0x151
+-#define RADIO_2057_SPARE8_CORE1                  0x152
+-#define RADIO_2057_SPARE7_CORE1                  0x153
+-#define RADIO_2057_BUFS_MISC_LPFBW_CORE1         0x154
+-#define RADIO_2057_TXLPF_RCCAL_CORE1             0x155
+-#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
+-#define RADIO_2057_LPF_GAIN_CORE1                0x157
+-#define RADIO_2057_DACBUF_IDACS_BW_CORE1         0x158
+-#define RADIO_2057_DACBUF_VINCM_CORE1            0x159
+-#define RADIO_2057_RCCAL_START_R1_Q1_P1          0x15a
+-#define RADIO_2057_RCCAL_X1                      0x15b
+-#define RADIO_2057_RCCAL_TRC0                    0x15c
+-#define RADIO_2057_RCCAL_TRC1                    0x15d
+-#define RADIO_2057_RCCAL_DONE_OSCCAP             0x15e
+-#define RADIO_2057_RCCAL_N0_0                    0x15f
+-#define RADIO_2057_RCCAL_N0_1                    0x160
+-#define RADIO_2057_RCCAL_N1_0                    0x161
+-#define RADIO_2057_RCCAL_N1_1                    0x162
+-#define RADIO_2057_RCAL_STATUS                   0x163
+-#define RADIO_2057_XTALPUOVR_PINCTRL             0x164
+-#define RADIO_2057_OVR_REG0                      0x165
+-#define RADIO_2057_OVR_REG1                      0x166
+-#define RADIO_2057_OVR_REG2                      0x167
+-#define RADIO_2057_OVR_REG3                      0x168
+-#define RADIO_2057_OVR_REG4                      0x169
+-#define RADIO_2057_RCCAL_SCAP_VAL                0x16a
+-#define RADIO_2057_RCCAL_BCAP_VAL                0x16b
+-#define RADIO_2057_RCCAL_HPC_VAL                 0x16c
+-#define RADIO_2057_RCCAL_OVERRIDES               0x16d
+-#define RADIO_2057_TX0_IQCAL_GAIN_BW             0x170
+-#define RADIO_2057_TX0_LOFT_FINE_I               0x171
+-#define RADIO_2057_TX0_LOFT_FINE_Q               0x172
+-#define RADIO_2057_TX0_LOFT_COARSE_I             0x173
+-#define RADIO_2057_TX0_LOFT_COARSE_Q             0x174
+-#define RADIO_2057_TX0_TX_SSI_MASTER             0x175
+-#define RADIO_2057_TX0_IQCAL_VCM_HG              0x176
+-#define RADIO_2057_TX0_IQCAL_IDAC                0x177
+-#define RADIO_2057_TX0_TSSI_VCM                  0x178
+-#define RADIO_2057_TX0_TX_SSI_MUX                0x179
+-#define RADIO_2057_TX0_TSSIA                     0x17a
+-#define RADIO_2057_TX0_TSSIG                     0x17b
+-#define RADIO_2057_TX0_TSSI_MISC1                0x17c
+-#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN       0x17d
+-#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP       0x17e
+-#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN       0x17f
+-#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP       0x180
+-#define RADIO_2057_TX1_IQCAL_GAIN_BW             0x190
+-#define RADIO_2057_TX1_LOFT_FINE_I               0x191
+-#define RADIO_2057_TX1_LOFT_FINE_Q               0x192
+-#define RADIO_2057_TX1_LOFT_COARSE_I             0x193
+-#define RADIO_2057_TX1_LOFT_COARSE_Q             0x194
+-#define RADIO_2057_TX1_TX_SSI_MASTER             0x195
+-#define RADIO_2057_TX1_IQCAL_VCM_HG              0x196
+-#define RADIO_2057_TX1_IQCAL_IDAC                0x197
+-#define RADIO_2057_TX1_TSSI_VCM                  0x198
+-#define RADIO_2057_TX1_TX_SSI_MUX                0x199
+-#define RADIO_2057_TX1_TSSIA                     0x19a
+-#define RADIO_2057_TX1_TSSIG                     0x19b
+-#define RADIO_2057_TX1_TSSI_MISC1                0x19c
+-#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN       0x19d
+-#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP       0x19e
+-#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN       0x19f
+-#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP       0x1a0
+-#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0      0x1a1
+-#define RADIO_2057_AFE_SET_VCM_I_CORE0           0x1a2
+-#define RADIO_2057_AFE_SET_VCM_Q_CORE0           0x1a3
+-#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0    0x1a4
+-#define RADIO_2057_AFE_STATUS_VCM_I_CORE0        0x1a5
+-#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0        0x1a6
+-#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1      0x1a7
+-#define RADIO_2057_AFE_SET_VCM_I_CORE1           0x1a8
+-#define RADIO_2057_AFE_SET_VCM_Q_CORE1           0x1a9
+-#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1    0x1aa
+-#define RADIO_2057_AFE_STATUS_VCM_I_CORE1        0x1ab
+-#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1        0x1ac
+-
+-#define RADIO_2057v7_DACBUF_VINCM_CORE0          0x1ad
+-#define RADIO_2057v7_RCCAL_MASTER                0x1ae
+-#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU       0x1af
+-#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU       0x1b0
+-#define RADIO_2057v7_LOGEN_PUS1                  0x1b1
+-#define RADIO_2057v7_OVR_REG5                    0x1b2
+-#define RADIO_2057v7_OVR_REG6                    0x1b3
+-#define RADIO_2057v7_OVR_REG7                    0x1b4
+-#define RADIO_2057v7_OVR_REG8                    0x1b5
+-#define RADIO_2057v7_OVR_REG9                    0x1b6
+-#define RADIO_2057v7_OVR_REG10                   0x1b7
+-#define RADIO_2057v7_OVR_REG11                   0x1b8
+-#define RADIO_2057v7_OVR_REG12                   0x1b9
+-#define RADIO_2057v7_OVR_REG13                   0x1ba
+-#define RADIO_2057v7_OVR_REG14                   0x1bb
+-#define RADIO_2057v7_OVR_REG15                   0x1bc
+-#define RADIO_2057v7_OVR_REG16                   0x1bd
+-#define RADIO_2057v7_OVR_REG1                    0x1be
+-#define RADIO_2057v7_OVR_REG18                   0x1bf
+-#define RADIO_2057v7_OVR_REG19                   0x1c0
+-#define RADIO_2057v7_OVR_REG20                   0x1c1
+-#define RADIO_2057v7_OVR_REG21                   0x1c2
+-#define RADIO_2057v7_OVR_REG2                    0x1c3
+-#define RADIO_2057v7_OVR_REG23                   0x1c4
+-#define RADIO_2057v7_OVR_REG24                   0x1c5
+-#define RADIO_2057v7_OVR_REG25                   0x1c6
+-#define RADIO_2057v7_OVR_REG26                   0x1c7
+-#define RADIO_2057v7_OVR_REG27                   0x1c8
+-#define RADIO_2057v7_OVR_REG28                   0x1c9
+-#define RADIO_2057v7_IQTEST_SEL_PU2              0x1ca
+-
+-#define RADIO_2057_VCM_MASK			 0x7
+-
+-#endif				/* _BCM20XX_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
+deleted file mode 100644
+index 211bc3a..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define NPHY_TBL_ID_GAIN1		0
+-#define NPHY_TBL_ID_GAIN2		1
+-#define NPHY_TBL_ID_GAINBITS1		2
+-#define NPHY_TBL_ID_GAINBITS2		3
+-#define NPHY_TBL_ID_GAINLIMIT		4
+-#define NPHY_TBL_ID_WRSSIGainLimit	5
+-#define NPHY_TBL_ID_RFSEQ		7
+-#define NPHY_TBL_ID_AFECTRL		8
+-#define NPHY_TBL_ID_ANTSWCTRLLUT	9
+-#define NPHY_TBL_ID_IQLOCAL		15
+-#define NPHY_TBL_ID_NOISEVAR		16
+-#define NPHY_TBL_ID_SAMPLEPLAY		17
+-#define NPHY_TBL_ID_CORE1TXPWRCTL	26
+-#define NPHY_TBL_ID_CORE2TXPWRCTL	27
+-#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL	30
+-
+-#define NPHY_TBL_ID_EPSILONTBL0   31
+-#define NPHY_TBL_ID_SCALARTBL0    32
+-#define NPHY_TBL_ID_EPSILONTBL1   33
+-#define NPHY_TBL_ID_SCALARTBL1    34
+-
+-#define	NPHY_TO_BPHY_OFF	0xc00
+-
+-#define NPHY_BandControl_currentBand			0x0001
+-#define RFCC_CHIP0_PU			0x0400
+-#define RFCC_POR_FORCE			0x0040
+-#define RFCC_OE_POR_FORCE		0x0080
+-#define NPHY_RfctrlIntc_override_OFF			0
+-#define NPHY_RfctrlIntc_override_TRSW			1
+-#define NPHY_RfctrlIntc_override_PA				2
+-#define NPHY_RfctrlIntc_override_EXT_LNA_PU		3
+-#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN	4
+-#define RIFS_ENABLE			0x80
+-#define BPHY_BAND_SEL_UP20		0x10
+-#define NPHY_MLenable			0x02
+-
+-#define NPHY_RfseqMode_CoreActv_override 0x0001
+-#define NPHY_RfseqMode_Trigger_override	0x0002
+-#define NPHY_RfseqCoreActv_TxRxChain0	(0x11)
+-#define NPHY_RfseqCoreActv_TxRxChain1	(0x22)
+-
+-#define NPHY_RfseqTrigger_rx2tx		0x0001
+-#define NPHY_RfseqTrigger_tx2rx		0x0002
+-#define NPHY_RfseqTrigger_updategainh	0x0004
+-#define NPHY_RfseqTrigger_updategainl	0x0008
+-#define NPHY_RfseqTrigger_updategainu	0x0010
+-#define NPHY_RfseqTrigger_reset2rx	0x0020
+-#define NPHY_RfseqStatus_rx2tx		0x0001
+-#define NPHY_RfseqStatus_tx2rx		0x0002
+-#define NPHY_RfseqStatus_updategainh	0x0004
+-#define NPHY_RfseqStatus_updategainl	0x0008
+-#define NPHY_RfseqStatus_updategainu	0x0010
+-#define NPHY_RfseqStatus_reset2rx	0x0020
+-#define NPHY_ClassifierCtrl_cck_en	0x1
+-#define NPHY_ClassifierCtrl_ofdm_en	0x2
+-#define NPHY_ClassifierCtrl_waited_en	0x4
+-#define NPHY_IQFlip_ADC1		0x0001
+-#define NPHY_IQFlip_ADC2		0x0010
+-#define NPHY_sampleCmd_STOP		0x0002
+-
+-#define RX_GF_OR_MM			0x0004
+-#define RX_GF_MM_AUTO			0x0100
+-
+-#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN	0x8000
+-
+-#define NPHY_IqestCmd_iqstart		0x1
+-#define NPHY_IqestCmd_iqMode		0x2
+-
+-#define NPHY_TxPwrCtrlCmd_pwrIndex_init		0x40
+-#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7	0x19
+-
+-#define PRIM_SEL_UP20		0x8000
+-
+-#define NPHY_RFSEQ_RX2TX		0x0
+-#define NPHY_RFSEQ_TX2RX		0x1
+-#define NPHY_RFSEQ_RESET2RX		0x2
+-#define NPHY_RFSEQ_UPDATEGAINH		0x3
+-#define NPHY_RFSEQ_UPDATEGAINL		0x4
+-#define NPHY_RFSEQ_UPDATEGAINU		0x5
+-
+-#define NPHY_RFSEQ_CMD_NOP		0x0
+-#define NPHY_RFSEQ_CMD_RXG_FBW		0x1
+-#define NPHY_RFSEQ_CMD_TR_SWITCH	0x2
+-#define NPHY_RFSEQ_CMD_EXT_PA		0x3
+-#define NPHY_RFSEQ_CMD_RXPD_TXPD	0x4
+-#define NPHY_RFSEQ_CMD_TX_GAIN		0x5
+-#define NPHY_RFSEQ_CMD_RX_GAIN		0x6
+-#define NPHY_RFSEQ_CMD_SET_HPF_BW	0x7
+-#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS	0x8
+-#define NPHY_RFSEQ_CMD_END		0xf
+-
+-#define NPHY_REV3_RFSEQ_CMD_NOP		0x0
+-#define NPHY_REV3_RFSEQ_CMD_RXG_FBW	0x1
+-#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH	0x2
+-#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU	0x3
+-#define NPHY_REV3_RFSEQ_CMD_EXT_PA	0x4
+-#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD	0x5
+-#define NPHY_REV3_RFSEQ_CMD_TX_GAIN	0x6
+-#define NPHY_REV3_RFSEQ_CMD_RX_GAIN	0x7
+-#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS	0x8
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC	0x9
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC	0xa
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC	0xb
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC	0xc
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC	0xd
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC	0xe
+-#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS	0xf
+-#define NPHY_REV3_RFSEQ_CMD_END		0x1f
+-
+-#define NPHY_RSSI_SEL_W1 		0x0
+-#define NPHY_RSSI_SEL_W2 		0x1
+-#define NPHY_RSSI_SEL_NB 		0x2
+-#define NPHY_RSSI_SEL_IQ 		0x3
+-#define NPHY_RSSI_SEL_TSSI_2G 		0x4
+-#define NPHY_RSSI_SEL_TSSI_5G 		0x5
+-#define NPHY_RSSI_SEL_TBD 		0x6
+-
+-#define NPHY_RAIL_I			0x0
+-#define NPHY_RAIL_Q			0x1
+-
+-#define NPHY_FORCESIG_DECODEGATEDCLKS	0x8
+-
+-#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
+-#define NPHY_REV7_RfctrlOverride_cmd_rx_pu   0x1
+-#define NPHY_REV7_RfctrlOverride_cmd_tx_pu   0x2
+-#define NPHY_REV7_RfctrlOverride_cmd_rxgain  0x3
+-#define NPHY_REV7_RfctrlOverride_cmd_txgain  0x4
+-
+-#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
+-#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK  0x0ff00
+-#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
+-
+-#define NPHY_REV7_TXGAINCODE_TGAIN_MASK     0x7fff
+-#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK   0x8000
+-#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
+-
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
+-
+-#define NPHY_IqestIqAccLo(core)  ((core == 0) ? 0x12c : 0x134)
+-
+-#define NPHY_IqestIqAccHi(core)  ((core == 0) ? 0x12d : 0x135)
+-
+-#define NPHY_IqestipwrAccLo(core)  ((core == 0) ? 0x12e : 0x136)
+-
+-#define NPHY_IqestipwrAccHi(core)  ((core == 0) ? 0x12f : 0x137)
+-
+-#define NPHY_IqestqpwrAccLo(core)  ((core == 0) ? 0x130 : 0x138)
+-
+-#define NPHY_IqestqpwrAccHi(core)  ((core == 0) ? 0x131 : 0x139)
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
+deleted file mode 100644
+index 81c59b0..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
++++ /dev/null
+@@ -1,3639 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <sbhnddma.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phytbl_lcn.h>
+-
+-const u32 dot11lcn_gain_tbl_rev0[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000004,
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x000000cd,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x000000d3,
+-	0x00000113,
+-	0x00000513,
+-	0x00000913,
+-	0x00000953,
+-	0x00000d53,
+-	0x00001153,
+-	0x00001193,
+-	0x00005193,
+-	0x00009193,
+-	0x0000d193,
+-	0x00011193,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000004,
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x000000cd,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x000000d3,
+-	0x00000113,
+-	0x00000513,
+-	0x00000913,
+-	0x00000953,
+-	0x00000d53,
+-	0x00001153,
+-	0x00005153,
+-	0x00009153,
+-	0x0000d153,
+-	0x00011153,
+-	0x00015153,
+-	0x00019153,
+-	0x0001d153,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 dot11lcn_gain_tbl_rev1[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000D,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x000000d1,
+-	0x00000053,
+-	0x00000093,
+-	0x000000d3,
+-	0x000000d7,
+-	0x00000117,
+-	0x00000517,
+-	0x00000917,
+-	0x00000957,
+-	0x00000d57,
+-	0x00001157,
+-	0x00001197,
+-	0x00005197,
+-	0x00009197,
+-	0x0000d197,
+-	0x00011197,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000D,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x000000d1,
+-	0x00000053,
+-	0x00000093,
+-	0x000000d3,
+-	0x000000d7,
+-	0x00000117,
+-	0x00000517,
+-	0x00000917,
+-	0x00000957,
+-	0x00000d57,
+-	0x00001157,
+-	0x00005157,
+-	0x00009157,
+-	0x0000d157,
+-	0x00011157,
+-	0x00015157,
+-	0x00019157,
+-	0x0001d157,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
+-	0x0401,
+-	0x0402,
+-	0x0403,
+-	0x0404,
+-	0x0405,
+-	0x0406,
+-	0x0407,
+-	0x0408,
+-	0x0409,
+-	0x040a,
+-	0x058b,
+-	0x058c,
+-	0x058d,
+-	0x058e,
+-	0x058f,
+-	0x0090,
+-	0x0091,
+-	0x0092,
+-	0x0193,
+-	0x0194,
+-	0x0195,
+-	0x0196,
+-	0x0197,
+-	0x0198,
+-	0x0199,
+-	0x019a,
+-	0x019b,
+-	0x019c,
+-	0x019d,
+-	0x019e,
+-	0x019f,
+-	0x01a0,
+-	0x01a1,
+-	0x01a2,
+-	0x01a3,
+-	0x01a4,
+-	0x01a5,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_rev0[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x20000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000000,
+-	0x40000000,
+-	0x00000000,
+-	0x50000000,
+-	0x00000000,
+-	0x60000000,
+-	0x00000000,
+-	0x70000000,
+-	0x00000000,
+-	0x80000000,
+-	0x00000000,
+-	0x90000000,
+-	0x00000008,
+-	0xa0000000,
+-	0x00000008,
+-	0xb0000000,
+-	0x00000008,
+-	0xc0000000,
+-	0x00000008,
+-	0xd0000000,
+-	0x00000008,
+-	0xe0000000,
+-	0x00000008,
+-	0xf0000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000009,
+-	0x10000000,
+-	0x00000009,
+-	0x20000000,
+-	0x00000019,
+-	0x30000000,
+-	0x00000019,
+-	0x40000000,
+-	0x00000019,
+-	0x50000000,
+-	0x00000019,
+-	0x60000000,
+-	0x00000019,
+-	0x70000000,
+-	0x00000019,
+-	0x80000000,
+-	0x00000019,
+-	0x90000000,
+-	0x00000019,
+-	0xa0000000,
+-	0x00000019,
+-	0xb0000000,
+-	0x00000019,
+-	0xc0000000,
+-	0x00000019,
+-	0xd0000000,
+-	0x00000019,
+-	0xe0000000,
+-	0x00000019,
+-	0xf0000000,
+-	0x00000019,
+-	0x00000000,
+-	0x0000001a,
+-	0x10000000,
+-	0x0000001a,
+-	0x20000000,
+-	0x0000001a,
+-	0x30000000,
+-	0x0000001a,
+-	0x40000000,
+-	0x0000001a,
+-	0x50000000,
+-	0x00000002,
+-	0x60000000,
+-	0x00000002,
+-	0x70000000,
+-	0x00000002,
+-	0x80000000,
+-	0x00000002,
+-	0x90000000,
+-	0x00000002,
+-	0xa0000000,
+-	0x00000002,
+-	0xb0000000,
+-	0x00000002,
+-	0xc0000000,
+-	0x0000000a,
+-	0xd0000000,
+-	0x0000000a,
+-	0xe0000000,
+-	0x0000000a,
+-	0xf0000000,
+-	0x0000000a,
+-	0x00000000,
+-	0x0000000b,
+-	0x10000000,
+-	0x0000000b,
+-	0x20000000,
+-	0x0000000b,
+-	0x30000000,
+-	0x0000000b,
+-	0x40000000,
+-	0x0000000b,
+-	0x50000000,
+-	0x0000001b,
+-	0x60000000,
+-	0x0000001b,
+-	0x70000000,
+-	0x0000001b,
+-	0x80000000,
+-	0x0000001b,
+-	0x90000000,
+-	0x0000001b,
+-	0xa0000000,
+-	0x0000001b,
+-	0xb0000000,
+-	0x0000001b,
+-	0xc0000000,
+-	0x0000001b,
+-	0xd0000000,
+-	0x0000001b,
+-	0xe0000000,
+-	0x0000001b,
+-	0xf0000000,
+-	0x0000001b,
+-	0x00000000,
+-	0x0000001c,
+-	0x10000000,
+-	0x0000001c,
+-	0x20000000,
+-	0x0000001c,
+-	0x30000000,
+-	0x0000001c,
+-	0x40000000,
+-	0x0000001c,
+-	0x50000000,
+-	0x0000001c,
+-	0x60000000,
+-	0x0000001c,
+-	0x70000000,
+-	0x0000001c,
+-	0x80000000,
+-	0x0000001c,
+-	0x90000000,
+-	0x0000001c,
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0001,
+-	0x0080,
+-	0x0081,
+-	0x0100,
+-	0x0101,
+-	0x0180,
+-	0x0181,
+-	0x0182,
+-	0x0183,
+-	0x0184,
+-	0x0185,
+-	0x0186,
+-	0x0187,
+-	0x0188,
+-	0x0285,
+-	0x0289,
+-	0x028a,
+-	0x028b,
+-	0x028c,
+-	0x028d,
+-	0x028e,
+-	0x028f,
+-	0x0290,
+-	0x0291,
+-	0x0292,
+-	0x0293,
+-	0x0294,
+-	0x0295,
+-	0x0296,
+-	0x0297,
+-	0x0298,
+-	0x0299,
+-	0x029a,
+-	0x0000
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_2G[] = {
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x00,
+-	0x0c,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_2G[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x10000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000010,
+-	0x10000000,
+-	0x00000010,
+-	0x00000000,
+-	0x00000018,
+-	0x10000000,
+-	0x00000018,
+-	0x20000000,
+-	0x00000018,
+-	0x30000000,
+-	0x00000018,
+-	0x40000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000018,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000028,
+-	0x90000000,
+-	0x00000028,
+-	0xa0000000,
+-	0x00000028,
+-	0xb0000000,
+-	0x00000028,
+-	0xc0000000,
+-	0x00000028,
+-	0xd0000000,
+-	0x00000028,
+-	0xe0000000,
+-	0x00000028,
+-	0xf0000000,
+-	0x00000028,
+-	0x00000000,
+-	0x00000029,
+-	0x10000000,
+-	0x00000029,
+-	0x20000000,
+-	0x00000029,
+-	0x30000000,
+-	0x00000029,
+-	0x40000000,
+-	0x00000029,
+-	0x50000000,
+-	0x00000029,
+-	0x60000000,
+-	0x00000029,
+-	0x70000000,
+-	0x00000029,
+-	0x80000000,
+-	0x00000029,
+-	0x90000000,
+-	0x00000029,
+-	0xa0000000,
+-	0x00000029,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x10000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000010,
+-	0x10000000,
+-	0x00000010,
+-	0x00000000,
+-	0x00000018,
+-	0x10000000,
+-	0x00000018,
+-	0x20000000,
+-	0x00000018,
+-	0x30000000,
+-	0x00000018,
+-	0x40000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000018,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000028,
+-	0x90000000,
+-	0x00000028,
+-	0xa0000000,
+-	0x00000028,
+-	0xb0000000,
+-	0x00000028,
+-	0xc0000000,
+-	0x00000028,
+-	0xd0000000,
+-	0x00000028,
+-	0xe0000000,
+-	0x00000028,
+-	0xf0000000,
+-	0x00000028,
+-	0x00000000,
+-	0x00000029,
+-	0x10000000,
+-	0x00000029,
+-	0x20000000,
+-	0x00000029,
+-	0x30000000,
+-	0x00000029,
+-	0x40000000,
+-	0x00000029,
+-	0x50000000,
+-	0x00000029,
+-	0x60000000,
+-	0x00000029,
+-	0x70000000,
+-	0x00000029,
+-	0x80000000,
+-	0x00000029,
+-	0x90000000,
+-	0x00000029,
+-	0xa0000000,
+-	0x00000029,
+-	0xb0000000,
+-	0x00000029,
+-	0xc0000000,
+-	0x00000029,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_2G[] = {
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x00000049,
+-	0x00000089,
+-	0x000000c9,
+-	0x0000004b,
+-	0x0000008b,
+-	0x000000cb,
+-	0x000000cf,
+-	0x0000010f,
+-	0x0000050f,
+-	0x0000090f,
+-	0x0000094f,
+-	0x00000d4f,
+-	0x0000114f,
+-	0x0000118f,
+-	0x0000518f,
+-	0x0000918f,
+-	0x0000d18f,
+-	0x0001118f,
+-	0x0001518f,
+-	0x0001918f,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_extlna_2G[] = {
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x00000003,
+-	0x00000007,
+-	0x0000000b,
+-	0x0000000f,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x0000010f,
+-	0x0000014f,
+-	0x0000018f,
+-	0x0000058f,
+-	0x0000098f,
+-	0x00000d8f,
+-	0x00008000,
+-	0x00008004,
+-	0x00008008,
+-	0x00008001,
+-	0x00008005,
+-	0x00008009,
+-	0x0000800d,
+-	0x00008003,
+-	0x00008007,
+-	0x0000800b,
+-	0x0000800f,
+-	0x0000804f,
+-	0x0000808f,
+-	0x000080cf,
+-	0x0000810f,
+-	0x0000814f,
+-	0x0000818f,
+-	0x0000858f,
+-	0x0000898f,
+-	0x00008d8f,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0401,
+-	0x0402,
+-	0x0403,
+-	0x0404,
+-	0x0483,
+-	0x0484,
+-	0x0485,
+-	0x0486,
+-	0x0583,
+-	0x0584,
+-	0x0585,
+-	0x0587,
+-	0x0588,
+-	0x0589,
+-	0x058a,
+-	0x0687,
+-	0x0688,
+-	0x0689,
+-	0x068a,
+-	0x068b,
+-	0x068c,
+-	0x068d,
+-	0x068e,
+-	0x068f,
+-	0x0690,
+-	0x0691,
+-	0x0692,
+-	0x0693,
+-	0x0000
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x00,
+-	0x0f,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x10000000,
+-	0x00000040,
+-	0x20000000,
+-	0x00000040,
+-	0x30000000,
+-	0x00000040,
+-	0x40000000,
+-	0x00000040,
+-	0x30000000,
+-	0x00000048,
+-	0x40000000,
+-	0x00000048,
+-	0x50000000,
+-	0x00000048,
+-	0x60000000,
+-	0x00000048,
+-	0x30000000,
+-	0x00000058,
+-	0x40000000,
+-	0x00000058,
+-	0x50000000,
+-	0x00000058,
+-	0x70000000,
+-	0x00000058,
+-	0x80000000,
+-	0x00000058,
+-	0x90000000,
+-	0x00000058,
+-	0xa0000000,
+-	0x00000058,
+-	0x70000000,
+-	0x00000068,
+-	0x80000000,
+-	0x00000068,
+-	0x90000000,
+-	0x00000068,
+-	0xa0000000,
+-	0x00000068,
+-	0xb0000000,
+-	0x00000068,
+-	0xc0000000,
+-	0x00000068,
+-	0xd0000000,
+-	0x00000068,
+-	0xe0000000,
+-	0x00000068,
+-	0xf0000000,
+-	0x00000068,
+-	0x00000000,
+-	0x00000069,
+-	0x10000000,
+-	0x00000069,
+-	0x20000000,
+-	0x00000069,
+-	0x30000000,
+-	0x00000069,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x50000000,
+-	0x00000041,
+-	0x60000000,
+-	0x00000041,
+-	0x70000000,
+-	0x00000041,
+-	0x80000000,
+-	0x00000041,
+-	0x70000000,
+-	0x00000049,
+-	0x80000000,
+-	0x00000049,
+-	0x90000000,
+-	0x00000049,
+-	0xa0000000,
+-	0x00000049,
+-	0x70000000,
+-	0x00000059,
+-	0x80000000,
+-	0x00000059,
+-	0x90000000,
+-	0x00000059,
+-	0xb0000000,
+-	0x00000059,
+-	0xc0000000,
+-	0x00000059,
+-	0xd0000000,
+-	0x00000059,
+-	0xe0000000,
+-	0x00000059,
+-	0xb0000000,
+-	0x00000069,
+-	0xc0000000,
+-	0x00000069,
+-	0xd0000000,
+-	0x00000069,
+-	0xe0000000,
+-	0x00000069,
+-	0xf0000000,
+-	0x00000069,
+-	0x00000000,
+-	0x0000006a,
+-	0x10000000,
+-	0x0000006a,
+-	0x20000000,
+-	0x0000006a,
+-	0x30000000,
+-	0x0000006a,
+-	0x40000000,
+-	0x0000006a,
+-	0x50000000,
+-	0x0000006a,
+-	0x60000000,
+-	0x0000006a,
+-	0x70000000,
+-	0x0000006a,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0001,
+-	0x0002,
+-	0x0003,
+-	0x0004,
+-	0x0083,
+-	0x0084,
+-	0x0085,
+-	0x0086,
+-	0x0087,
+-	0x0186,
+-	0x0187,
+-	0x0188,
+-	0x0189,
+-	0x018a,
+-	0x018b,
+-	0x018c,
+-	0x018d,
+-	0x018e,
+-	0x018f,
+-	0x0190,
+-	0x0191,
+-	0x0192,
+-	0x0193,
+-	0x0194,
+-	0x0195,
+-	0x0196,
+-	0x0197,
+-	0x0198,
+-	0x0199,
+-	0x019a,
+-	0x019b,
+-	0x019c,
+-	0x019d,
+-	0x0000
+-};
+-
+-const u32 dot11lcn_gain_val_tbl_5G[] = {
+-	0xf7,
+-	0xfd,
+-	0x00,
+-	0x04,
+-	0x04,
+-	0x04,
+-	0xf7,
+-	0xfd,
+-	0x00,
+-	0x04,
+-	0x04,
+-	0x04,
+-	0xf6,
+-	0x00,
+-	0x0c,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x06,
+-	0x0a,
+-	0x10,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_5G[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x20000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000000,
+-	0x40000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000008,
+-	0x40000000,
+-	0x00000008,
+-	0x50000000,
+-	0x00000008,
+-	0x60000000,
+-	0x00000008,
+-	0x70000000,
+-	0x00000008,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x90000000,
+-	0x00000018,
+-	0xa0000000,
+-	0x00000018,
+-	0xb0000000,
+-	0x00000018,
+-	0xc0000000,
+-	0x00000018,
+-	0xd0000000,
+-	0x00000018,
+-	0xe0000000,
+-	0x00000018,
+-	0xf0000000,
+-	0x00000018,
+-	0x00000000,
+-	0x00000019,
+-	0x10000000,
+-	0x00000019,
+-	0x20000000,
+-	0x00000019,
+-	0x30000000,
+-	0x00000019,
+-	0x40000000,
+-	0x00000019,
+-	0x50000000,
+-	0x00000019,
+-	0x60000000,
+-	0x00000019,
+-	0x70000000,
+-	0x00000019,
+-	0x80000000,
+-	0x00000019,
+-	0x90000000,
+-	0x00000019,
+-	0xa0000000,
+-	0x00000019,
+-	0xb0000000,
+-	0x00000019,
+-	0xc0000000,
+-	0x00000019,
+-	0xd0000000,
+-	0x00000019,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_5G[] = {
+-	0x00000000,
+-	0x00000040,
+-	0x00000080,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x00000011,
+-	0x00000015,
+-	0x00000055,
+-	0x00000095,
+-	0x00000017,
+-	0x0000001b,
+-	0x0000005b,
+-	0x0000009b,
+-	0x000000db,
+-	0x0000011b,
+-	0x0000015b,
+-	0x0000019b,
+-	0x0000059b,
+-	0x0000099b,
+-	0x00000d9b,
+-	0x0000119b,
+-	0x0000519b,
+-	0x0000919b,
+-	0x0000d19b,
+-	0x0001119b,
+-	0x0001519b,
+-	0x0001919b,
+-	0x0001d19b,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = {
+-	{&dot11lcn_gain_tbl_rev0,
+-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = {
+-	{&dot11lcn_gain_tbl_rev1,
+-	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
+-	{&dot11lcn_gain_tbl_2G,
+-	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_2G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_2G,
+-	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_2G,
+-	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
+-	 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
+-	{&dot11lcn_gain_tbl_5G,
+-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_5G,
+-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+-	 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
+-	{&dot11lcn_gain_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
+-	{&dot11lcn_gain_tbl_5G,
+-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_5G,
+-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+-	 17, 0, 8}
+-};
+-
+-const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 =
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
+-    sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
+-    sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
+-
+-const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-};
+-
+-const u16 dot11lcn_noise_scale_tbl_rev0[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
+-	0x000141f8,
+-	0x000021f8,
+-	0x000021fb,
+-	0x000041fb,
+-	0x0001fe4b,
+-	0x0000217b,
+-	0x00002133,
+-	0x000040eb,
+-	0x0001fea3,
+-	0x0000024b,
+-};
+-
+-const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
+-	0x00100001,
+-	0x00200010,
+-	0x00300001,
+-	0x00400010,
+-	0x00500022,
+-	0x00600122,
+-	0x00700222,
+-	0x00800322,
+-	0x00900422,
+-	0x00a00522,
+-	0x00b00622,
+-	0x00c00722,
+-	0x00d00822,
+-	0x00f00922,
+-	0x00100a22,
+-	0x00200b22,
+-	0x00300c22,
+-	0x00400d22,
+-	0x00500e22,
+-	0x00600f22,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-};
+-
+-const u8 dot11lcn_nf_table_rev0[] = {
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_rev0[] = {
+-	0x09,
+-	0x0f,
+-	0x14,
+-	0x18,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0xeb,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 dot11lcn_spur_tbl_rev0[] = {
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x02,
+-	0x03,
+-	0x01,
+-	0x03,
+-	0x02,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x02,
+-	0x03,
+-	0x01,
+-	0x03,
+-	0x02,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-};
+-
+-const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
+-	0x001a,
+-	0x0034,
+-	0x004e,
+-	0x0068,
+-	0x009c,
+-	0x00d0,
+-	0x00ea,
+-	0x0104,
+-	0x0034,
+-	0x0068,
+-	0x009c,
+-	0x00d0,
+-	0x0138,
+-	0x01a0,
+-	0x01d4,
+-	0x0208,
+-	0x004e,
+-	0x009c,
+-	0x00ea,
+-	0x0138,
+-	0x01d4,
+-	0x0270,
+-	0x02be,
+-	0x030c,
+-	0x0068,
+-	0x00d0,
+-	0x0138,
+-	0x01a0,
+-	0x0270,
+-	0x0340,
+-	0x03a8,
+-	0x0410,
+-	0x0018,
+-	0x009c,
+-	0x00d0,
+-	0x0104,
+-	0x00ea,
+-	0x0138,
+-	0x0186,
+-	0x00d0,
+-	0x0104,
+-	0x0104,
+-	0x0138,
+-	0x016c,
+-	0x016c,
+-	0x01a0,
+-	0x0138,
+-	0x0186,
+-	0x0186,
+-	0x01d4,
+-	0x0222,
+-	0x0222,
+-	0x0270,
+-	0x0104,
+-	0x0138,
+-	0x016c,
+-	0x0138,
+-	0x016c,
+-	0x01a0,
+-	0x01d4,
+-	0x01a0,
+-	0x01d4,
+-	0x0208,
+-	0x0208,
+-	0x023c,
+-	0x0186,
+-	0x01d4,
+-	0x0222,
+-	0x01d4,
+-	0x0222,
+-	0x0270,
+-	0x02be,
+-	0x0270,
+-	0x02be,
+-	0x030c,
+-	0x030c,
+-	0x035a,
+-	0x0036,
+-	0x006c,
+-	0x00a2,
+-	0x00d8,
+-	0x0144,
+-	0x01b0,
+-	0x01e6,
+-	0x021c,
+-	0x006c,
+-	0x00d8,
+-	0x0144,
+-	0x01b0,
+-	0x0288,
+-	0x0360,
+-	0x03cc,
+-	0x0438,
+-	0x00a2,
+-	0x0144,
+-	0x01e6,
+-	0x0288,
+-	0x03cc,
+-	0x0510,
+-	0x05b2,
+-	0x0654,
+-	0x00d8,
+-	0x01b0,
+-	0x0288,
+-	0x0360,
+-	0x0510,
+-	0x06c0,
+-	0x0798,
+-	0x0870,
+-	0x0018,
+-	0x0144,
+-	0x01b0,
+-	0x021c,
+-	0x01e6,
+-	0x0288,
+-	0x032a,
+-	0x01b0,
+-	0x021c,
+-	0x021c,
+-	0x0288,
+-	0x02f4,
+-	0x02f4,
+-	0x0360,
+-	0x0288,
+-	0x032a,
+-	0x032a,
+-	0x03cc,
+-	0x046e,
+-	0x046e,
+-	0x0510,
+-	0x021c,
+-	0x0288,
+-	0x02f4,
+-	0x0288,
+-	0x02f4,
+-	0x0360,
+-	0x03cc,
+-	0x0360,
+-	0x03cc,
+-	0x0438,
+-	0x0438,
+-	0x04a4,
+-	0x032a,
+-	0x03cc,
+-	0x046e,
+-	0x03cc,
+-	0x046e,
+-	0x0510,
+-	0x05b2,
+-	0x0510,
+-	0x05b2,
+-	0x0654,
+-	0x0654,
+-	0x06f6,
+-};
+-
+-const u16 dot11lcn_iq_local_tbl_rev0[] = {
+-	0x0200,
+-	0x0300,
+-	0x0400,
+-	0x0600,
+-	0x0800,
+-	0x0b00,
+-	0x1000,
+-	0x1001,
+-	0x1002,
+-	0x1003,
+-	0x1004,
+-	0x1005,
+-	0x1006,
+-	0x1007,
+-	0x1707,
+-	0x2007,
+-	0x2d07,
+-	0x4007,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0200,
+-	0x0300,
+-	0x0400,
+-	0x0600,
+-	0x0800,
+-	0x0b00,
+-	0x1000,
+-	0x1001,
+-	0x1002,
+-	0x1003,
+-	0x1004,
+-	0x1005,
+-	0x1006,
+-	0x1007,
+-	0x1707,
+-	0x2007,
+-	0x2d07,
+-	0x4007,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x4000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = {
+-	{&dot11lcn_min_sig_sq_tbl_rev0,
+-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
+-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
+-	,
+-	{&dot11lcn_noise_scale_tbl_rev0,
+-	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
+-	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
+-	,
+-	{&dot11lcn_fltr_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
+-	,
+-	{&dot11lcn_ps_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_sw_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
+-	,
+-	{&dot11lcn_nf_table_rev0,
+-	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
+-	 0, 8}
+-	,
+-	{&dot11lcn_gain_val_tbl_rev0,
+-	 sizeof(dot11lcn_gain_val_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
+-	,
+-	{&dot11lcn_gain_tbl_rev0,
+-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_spur_tbl_rev0,
+-	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
+-	 0, 8}
+-	,
+-	{&dot11lcn_unsup_mcs_tbl_rev0,
+-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
+-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
+-	,
+-	{&dot11lcn_iq_local_tbl_rev0,
+-	 sizeof(dot11lcn_iq_local_tbl_rev0) /
+-	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
+-	,
+-	{&dot11lcn_papd_compdelta_tbl_rev0,
+-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
+-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = {
+-	&dot11lcn_sw_ctrl_tbl_4313_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = {
+-	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
+-	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
+-	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
+-};
+-
+-const u32 dot11lcnphytbl_info_sz_rev0 =
+-    sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
+-	{3, 0, 31, 0, 72,}
+-	,
+-	{3, 0, 31, 0, 70,}
+-	,
+-	{3, 0, 31, 0, 68,}
+-	,
+-	{3, 0, 30, 0, 67,}
+-	,
+-	{3, 0, 29, 0, 68,}
+-	,
+-	{3, 0, 28, 0, 68,}
+-	,
+-	{3, 0, 27, 0, 69,}
+-	,
+-	{3, 0, 26, 0, 70,}
+-	,
+-	{3, 0, 25, 0, 70,}
+-	,
+-	{3, 0, 24, 0, 71,}
+-	,
+-	{3, 0, 23, 0, 72,}
+-	,
+-	{3, 0, 23, 0, 70,}
+-	,
+-	{3, 0, 22, 0, 71,}
+-	,
+-	{3, 0, 21, 0, 72,}
+-	,
+-	{3, 0, 21, 0, 70,}
+-	,
+-	{3, 0, 21, 0, 68,}
+-	,
+-	{3, 0, 21, 0, 66,}
+-	,
+-	{3, 0, 21, 0, 64,}
+-	,
+-	{3, 0, 21, 0, 63,}
+-	,
+-	{3, 0, 20, 0, 64,}
+-	,
+-	{3, 0, 19, 0, 65,}
+-	,
+-	{3, 0, 19, 0, 64,}
+-	,
+-	{3, 0, 18, 0, 65,}
+-	,
+-	{3, 0, 18, 0, 64,}
+-	,
+-	{3, 0, 17, 0, 65,}
+-	,
+-	{3, 0, 17, 0, 64,}
+-	,
+-	{3, 0, 16, 0, 65,}
+-	,
+-	{3, 0, 16, 0, 64,}
+-	,
+-	{3, 0, 16, 0, 62,}
+-	,
+-	{3, 0, 16, 0, 60,}
+-	,
+-	{3, 0, 16, 0, 58,}
+-	,
+-	{3, 0, 15, 0, 61,}
+-	,
+-	{3, 0, 15, 0, 59,}
+-	,
+-	{3, 0, 14, 0, 61,}
+-	,
+-	{3, 0, 14, 0, 60,}
+-	,
+-	{3, 0, 14, 0, 58,}
+-	,
+-	{3, 0, 13, 0, 60,}
+-	,
+-	{3, 0, 13, 0, 59,}
+-	,
+-	{3, 0, 12, 0, 62,}
+-	,
+-	{3, 0, 12, 0, 60,}
+-	,
+-	{3, 0, 12, 0, 58,}
+-	,
+-	{3, 0, 11, 0, 62,}
+-	,
+-	{3, 0, 11, 0, 60,}
+-	,
+-	{3, 0, 11, 0, 59,}
+-	,
+-	{3, 0, 11, 0, 57,}
+-	,
+-	{3, 0, 10, 0, 61,}
+-	,
+-	{3, 0, 10, 0, 59,}
+-	,
+-	{3, 0, 10, 0, 57,}
+-	,
+-	{3, 0, 9, 0, 62,}
+-	,
+-	{3, 0, 9, 0, 60,}
+-	,
+-	{3, 0, 9, 0, 58,}
+-	,
+-	{3, 0, 9, 0, 57,}
+-	,
+-	{3, 0, 8, 0, 62,}
+-	,
+-	{3, 0, 8, 0, 60,}
+-	,
+-	{3, 0, 8, 0, 58,}
+-	,
+-	{3, 0, 8, 0, 57,}
+-	,
+-	{3, 0, 8, 0, 55,}
+-	,
+-	{3, 0, 7, 0, 61,}
+-	,
+-	{3, 0, 7, 0, 60,}
+-	,
+-	{3, 0, 7, 0, 58,}
+-	,
+-	{3, 0, 7, 0, 56,}
+-	,
+-	{3, 0, 7, 0, 55,}
+-	,
+-	{3, 0, 6, 0, 62,}
+-	,
+-	{3, 0, 6, 0, 60,}
+-	,
+-	{3, 0, 6, 0, 58,}
+-	,
+-	{3, 0, 6, 0, 57,}
+-	,
+-	{3, 0, 6, 0, 55,}
+-	,
+-	{3, 0, 6, 0, 54,}
+-	,
+-	{3, 0, 6, 0, 52,}
+-	,
+-	{3, 0, 5, 0, 61,}
+-	,
+-	{3, 0, 5, 0, 59,}
+-	,
+-	{3, 0, 5, 0, 57,}
+-	,
+-	{3, 0, 5, 0, 56,}
+-	,
+-	{3, 0, 5, 0, 54,}
+-	,
+-	{3, 0, 5, 0, 53,}
+-	,
+-	{3, 0, 5, 0, 51,}
+-	,
+-	{3, 0, 4, 0, 62,}
+-	,
+-	{3, 0, 4, 0, 60,}
+-	,
+-	{3, 0, 4, 0, 58,}
+-	,
+-	{3, 0, 4, 0, 57,}
+-	,
+-	{3, 0, 4, 0, 55,}
+-	,
+-	{3, 0, 4, 0, 54,}
+-	,
+-	{3, 0, 4, 0, 52,}
+-	,
+-	{3, 0, 4, 0, 51,}
+-	,
+-	{3, 0, 4, 0, 49,}
+-	,
+-	{3, 0, 4, 0, 48,}
+-	,
+-	{3, 0, 4, 0, 46,}
+-	,
+-	{3, 0, 3, 0, 60,}
+-	,
+-	{3, 0, 3, 0, 58,}
+-	,
+-	{3, 0, 3, 0, 57,}
+-	,
+-	{3, 0, 3, 0, 55,}
+-	,
+-	{3, 0, 3, 0, 54,}
+-	,
+-	{3, 0, 3, 0, 52,}
+-	,
+-	{3, 0, 3, 0, 51,}
+-	,
+-	{3, 0, 3, 0, 49,}
+-	,
+-	{3, 0, 3, 0, 48,}
+-	,
+-	{3, 0, 3, 0, 46,}
+-	,
+-	{3, 0, 3, 0, 45,}
+-	,
+-	{3, 0, 3, 0, 44,}
+-	,
+-	{3, 0, 3, 0, 43,}
+-	,
+-	{3, 0, 3, 0, 41,}
+-	,
+-	{3, 0, 2, 0, 61,}
+-	,
+-	{3, 0, 2, 0, 59,}
+-	,
+-	{3, 0, 2, 0, 57,}
+-	,
+-	{3, 0, 2, 0, 56,}
+-	,
+-	{3, 0, 2, 0, 54,}
+-	,
+-	{3, 0, 2, 0, 53,}
+-	,
+-	{3, 0, 2, 0, 51,}
+-	,
+-	{3, 0, 2, 0, 50,}
+-	,
+-	{3, 0, 2, 0, 48,}
+-	,
+-	{3, 0, 2, 0, 47,}
+-	,
+-	{3, 0, 2, 0, 46,}
+-	,
+-	{3, 0, 2, 0, 44,}
+-	,
+-	{3, 0, 2, 0, 43,}
+-	,
+-	{3, 0, 2, 0, 42,}
+-	,
+-	{3, 0, 2, 0, 41,}
+-	,
+-	{3, 0, 2, 0, 39,}
+-	,
+-	{3, 0, 2, 0, 38,}
+-	,
+-	{3, 0, 2, 0, 37,}
+-	,
+-	{3, 0, 2, 0, 36,}
+-	,
+-	{3, 0, 2, 0, 35,}
+-	,
+-	{3, 0, 2, 0, 34,}
+-	,
+-	{3, 0, 2, 0, 33,}
+-	,
+-	{3, 0, 2, 0, 32,}
+-	,
+-	{3, 0, 1, 0, 63,}
+-	,
+-	{3, 0, 1, 0, 61,}
+-	,
+-	{3, 0, 1, 0, 59,}
+-	,
+-	{3, 0, 1, 0, 57,}
+-	,
+-};
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
+-	{7, 0, 31, 0, 72,}
+-	,
+-	{7, 0, 31, 0, 70,}
+-	,
+-	{7, 0, 31, 0, 68,}
+-	,
+-	{7, 0, 30, 0, 67,}
+-	,
+-	{7, 0, 29, 0, 68,}
+-	,
+-	{7, 0, 28, 0, 68,}
+-	,
+-	{7, 0, 27, 0, 69,}
+-	,
+-	{7, 0, 26, 0, 70,}
+-	,
+-	{7, 0, 25, 0, 70,}
+-	,
+-	{7, 0, 24, 0, 71,}
+-	,
+-	{7, 0, 23, 0, 72,}
+-	,
+-	{7, 0, 23, 0, 70,}
+-	,
+-	{7, 0, 22, 0, 71,}
+-	,
+-	{7, 0, 21, 0, 72,}
+-	,
+-	{7, 0, 21, 0, 70,}
+-	,
+-	{7, 0, 21, 0, 68,}
+-	,
+-	{7, 0, 21, 0, 66,}
+-	,
+-	{7, 0, 21, 0, 64,}
+-	,
+-	{7, 0, 21, 0, 63,}
+-	,
+-	{7, 0, 20, 0, 64,}
+-	,
+-	{7, 0, 19, 0, 65,}
+-	,
+-	{7, 0, 19, 0, 64,}
+-	,
+-	{7, 0, 18, 0, 65,}
+-	,
+-	{7, 0, 18, 0, 64,}
+-	,
+-	{7, 0, 17, 0, 65,}
+-	,
+-	{7, 0, 17, 0, 64,}
+-	,
+-	{7, 0, 16, 0, 65,}
+-	,
+-	{7, 0, 16, 0, 64,}
+-	,
+-	{7, 0, 16, 0, 62,}
+-	,
+-	{7, 0, 16, 0, 60,}
+-	,
+-	{7, 0, 16, 0, 58,}
+-	,
+-	{7, 0, 15, 0, 61,}
+-	,
+-	{7, 0, 15, 0, 59,}
+-	,
+-	{7, 0, 14, 0, 61,}
+-	,
+-	{7, 0, 14, 0, 60,}
+-	,
+-	{7, 0, 14, 0, 58,}
+-	,
+-	{7, 0, 13, 0, 60,}
+-	,
+-	{7, 0, 13, 0, 59,}
+-	,
+-	{7, 0, 12, 0, 62,}
+-	,
+-	{7, 0, 12, 0, 60,}
+-	,
+-	{7, 0, 12, 0, 58,}
+-	,
+-	{7, 0, 11, 0, 62,}
+-	,
+-	{7, 0, 11, 0, 60,}
+-	,
+-	{7, 0, 11, 0, 59,}
+-	,
+-	{7, 0, 11, 0, 57,}
+-	,
+-	{7, 0, 10, 0, 61,}
+-	,
+-	{7, 0, 10, 0, 59,}
+-	,
+-	{7, 0, 10, 0, 57,}
+-	,
+-	{7, 0, 9, 0, 62,}
+-	,
+-	{7, 0, 9, 0, 60,}
+-	,
+-	{7, 0, 9, 0, 58,}
+-	,
+-	{7, 0, 9, 0, 57,}
+-	,
+-	{7, 0, 8, 0, 62,}
+-	,
+-	{7, 0, 8, 0, 60,}
+-	,
+-	{7, 0, 8, 0, 58,}
+-	,
+-	{7, 0, 8, 0, 57,}
+-	,
+-	{7, 0, 8, 0, 55,}
+-	,
+-	{7, 0, 7, 0, 61,}
+-	,
+-	{7, 0, 7, 0, 60,}
+-	,
+-	{7, 0, 7, 0, 58,}
+-	,
+-	{7, 0, 7, 0, 56,}
+-	,
+-	{7, 0, 7, 0, 55,}
+-	,
+-	{7, 0, 6, 0, 62,}
+-	,
+-	{7, 0, 6, 0, 60,}
+-	,
+-	{7, 0, 6, 0, 58,}
+-	,
+-	{7, 0, 6, 0, 57,}
+-	,
+-	{7, 0, 6, 0, 55,}
+-	,
+-	{7, 0, 6, 0, 54,}
+-	,
+-	{7, 0, 6, 0, 52,}
+-	,
+-	{7, 0, 5, 0, 61,}
+-	,
+-	{7, 0, 5, 0, 59,}
+-	,
+-	{7, 0, 5, 0, 57,}
+-	,
+-	{7, 0, 5, 0, 56,}
+-	,
+-	{7, 0, 5, 0, 54,}
+-	,
+-	{7, 0, 5, 0, 53,}
+-	,
+-	{7, 0, 5, 0, 51,}
+-	,
+-	{7, 0, 4, 0, 62,}
+-	,
+-	{7, 0, 4, 0, 60,}
+-	,
+-	{7, 0, 4, 0, 58,}
+-	,
+-	{7, 0, 4, 0, 57,}
+-	,
+-	{7, 0, 4, 0, 55,}
+-	,
+-	{7, 0, 4, 0, 54,}
+-	,
+-	{7, 0, 4, 0, 52,}
+-	,
+-	{7, 0, 4, 0, 51,}
+-	,
+-	{7, 0, 4, 0, 49,}
+-	,
+-	{7, 0, 4, 0, 48,}
+-	,
+-	{7, 0, 4, 0, 46,}
+-	,
+-	{7, 0, 3, 0, 60,}
+-	,
+-	{7, 0, 3, 0, 58,}
+-	,
+-	{7, 0, 3, 0, 57,}
+-	,
+-	{7, 0, 3, 0, 55,}
+-	,
+-	{7, 0, 3, 0, 54,}
+-	,
+-	{7, 0, 3, 0, 52,}
+-	,
+-	{7, 0, 3, 0, 51,}
+-	,
+-	{7, 0, 3, 0, 49,}
+-	,
+-	{7, 0, 3, 0, 48,}
+-	,
+-	{7, 0, 3, 0, 46,}
+-	,
+-	{7, 0, 3, 0, 45,}
+-	,
+-	{7, 0, 3, 0, 44,}
+-	,
+-	{7, 0, 3, 0, 43,}
+-	,
+-	{7, 0, 3, 0, 41,}
+-	,
+-	{7, 0, 2, 0, 61,}
+-	,
+-	{7, 0, 2, 0, 59,}
+-	,
+-	{7, 0, 2, 0, 57,}
+-	,
+-	{7, 0, 2, 0, 56,}
+-	,
+-	{7, 0, 2, 0, 54,}
+-	,
+-	{7, 0, 2, 0, 53,}
+-	,
+-	{7, 0, 2, 0, 51,}
+-	,
+-	{7, 0, 2, 0, 50,}
+-	,
+-	{7, 0, 2, 0, 48,}
+-	,
+-	{7, 0, 2, 0, 47,}
+-	,
+-	{7, 0, 2, 0, 46,}
+-	,
+-	{7, 0, 2, 0, 44,}
+-	,
+-	{7, 0, 2, 0, 43,}
+-	,
+-	{7, 0, 2, 0, 42,}
+-	,
+-	{7, 0, 2, 0, 41,}
+-	,
+-	{7, 0, 2, 0, 39,}
+-	,
+-	{7, 0, 2, 0, 38,}
+-	,
+-	{7, 0, 2, 0, 37,}
+-	,
+-	{7, 0, 2, 0, 36,}
+-	,
+-	{7, 0, 2, 0, 35,}
+-	,
+-	{7, 0, 2, 0, 34,}
+-	,
+-	{7, 0, 2, 0, 33,}
+-	,
+-	{7, 0, 2, 0, 32,}
+-	,
+-	{7, 0, 1, 0, 63,}
+-	,
+-	{7, 0, 1, 0, 61,}
+-	,
+-	{7, 0, 1, 0, 59,}
+-	,
+-	{7, 0, 1, 0, 57,}
+-	,
+-};
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
+-	{255, 255, 0xf0, 0, 152,}
+-	,
+-	{255, 255, 0xf0, 0, 147,}
+-	,
+-	{255, 255, 0xf0, 0, 143,}
+-	,
+-	{255, 255, 0xf0, 0, 139,}
+-	,
+-	{255, 255, 0xf0, 0, 135,}
+-	,
+-	{255, 255, 0xf0, 0, 131,}
+-	,
+-	{255, 255, 0xf0, 0, 128,}
+-	,
+-	{255, 255, 0xf0, 0, 124,}
+-	,
+-	{255, 255, 0xf0, 0, 121,}
+-	,
+-	{255, 255, 0xf0, 0, 117,}
+-	,
+-	{255, 255, 0xf0, 0, 114,}
+-	,
+-	{255, 255, 0xf0, 0, 111,}
+-	,
+-	{255, 255, 0xf0, 0, 107,}
+-	,
+-	{255, 255, 0xf0, 0, 104,}
+-	,
+-	{255, 255, 0xf0, 0, 101,}
+-	,
+-	{255, 255, 0xf0, 0, 99,}
+-	,
+-	{255, 255, 0xf0, 0, 96,}
+-	,
+-	{255, 255, 0xf0, 0, 93,}
+-	,
+-	{255, 255, 0xf0, 0, 90,}
+-	,
+-	{255, 255, 0xf0, 0, 88,}
+-	,
+-	{255, 255, 0xf0, 0, 85,}
+-	,
+-	{255, 255, 0xf0, 0, 83,}
+-	,
+-	{255, 255, 0xf0, 0, 81,}
+-	,
+-	{255, 255, 0xf0, 0, 78,}
+-	,
+-	{255, 255, 0xf0, 0, 76,}
+-	,
+-	{255, 255, 0xf0, 0, 74,}
+-	,
+-	{255, 255, 0xf0, 0, 72,}
+-	,
+-	{255, 255, 0xf0, 0, 70,}
+-	,
+-	{255, 255, 0xf0, 0, 68,}
+-	,
+-	{255, 255, 0xf0, 0, 66,}
+-	,
+-	{255, 255, 0xf0, 0, 64,}
+-	,
+-	{255, 248, 0xf0, 0, 64,}
+-	,
+-	{255, 241, 0xf0, 0, 64,}
+-	,
+-	{255, 251, 0xe0, 0, 64,}
+-	,
+-	{255, 244, 0xe0, 0, 64,}
+-	,
+-	{255, 254, 0xd0, 0, 64,}
+-	,
+-	{255, 246, 0xd0, 0, 64,}
+-	,
+-	{255, 239, 0xd0, 0, 64,}
+-	,
+-	{255, 249, 0xc0, 0, 64,}
+-	,
+-	{255, 242, 0xc0, 0, 64,}
+-	,
+-	{255, 255, 0xb0, 0, 64,}
+-	,
+-	{255, 248, 0xb0, 0, 64,}
+-	,
+-	{255, 241, 0xb0, 0, 64,}
+-	,
+-	{255, 254, 0xa0, 0, 64,}
+-	,
+-	{255, 246, 0xa0, 0, 64,}
+-	,
+-	{255, 239, 0xa0, 0, 64,}
+-	,
+-	{255, 255, 0x90, 0, 64,}
+-	,
+-	{255, 248, 0x90, 0, 64,}
+-	,
+-	{255, 241, 0x90, 0, 64,}
+-	,
+-	{255, 234, 0x90, 0, 64,}
+-	,
+-	{255, 255, 0x80, 0, 64,}
+-	,
+-	{255, 248, 0x80, 0, 64,}
+-	,
+-	{255, 241, 0x80, 0, 64,}
+-	,
+-	{255, 234, 0x80, 0, 64,}
+-	,
+-	{255, 255, 0x70, 0, 64,}
+-	,
+-	{255, 248, 0x70, 0, 64,}
+-	,
+-	{255, 241, 0x70, 0, 64,}
+-	,
+-	{255, 234, 0x70, 0, 64,}
+-	,
+-	{255, 227, 0x70, 0, 64,}
+-	,
+-	{255, 221, 0x70, 0, 64,}
+-	,
+-	{255, 215, 0x70, 0, 64,}
+-	,
+-	{255, 208, 0x70, 0, 64,}
+-	,
+-	{255, 203, 0x70, 0, 64,}
+-	,
+-	{255, 197, 0x70, 0, 64,}
+-	,
+-	{255, 255, 0x60, 0, 64,}
+-	,
+-	{255, 248, 0x60, 0, 64,}
+-	,
+-	{255, 241, 0x60, 0, 64,}
+-	,
+-	{255, 234, 0x60, 0, 64,}
+-	,
+-	{255, 227, 0x60, 0, 64,}
+-	,
+-	{255, 221, 0x60, 0, 64,}
+-	,
+-	{255, 255, 0x50, 0, 64,}
+-	,
+-	{255, 248, 0x50, 0, 64,}
+-	,
+-	{255, 241, 0x50, 0, 64,}
+-	,
+-	{255, 234, 0x50, 0, 64,}
+-	,
+-	{255, 227, 0x50, 0, 64,}
+-	,
+-	{255, 221, 0x50, 0, 64,}
+-	,
+-	{255, 215, 0x50, 0, 64,}
+-	,
+-	{255, 208, 0x50, 0, 64,}
+-	,
+-	{255, 255, 0x40, 0, 64,}
+-	,
+-	{255, 248, 0x40, 0, 64,}
+-	,
+-	{255, 241, 0x40, 0, 64,}
+-	,
+-	{255, 234, 0x40, 0, 64,}
+-	,
+-	{255, 227, 0x40, 0, 64,}
+-	,
+-	{255, 221, 0x40, 0, 64,}
+-	,
+-	{255, 215, 0x40, 0, 64,}
+-	,
+-	{255, 208, 0x40, 0, 64,}
+-	,
+-	{255, 203, 0x40, 0, 64,}
+-	,
+-	{255, 197, 0x40, 0, 64,}
+-	,
+-	{255, 255, 0x30, 0, 64,}
+-	,
+-	{255, 248, 0x30, 0, 64,}
+-	,
+-	{255, 241, 0x30, 0, 64,}
+-	,
+-	{255, 234, 0x30, 0, 64,}
+-	,
+-	{255, 227, 0x30, 0, 64,}
+-	,
+-	{255, 221, 0x30, 0, 64,}
+-	,
+-	{255, 215, 0x30, 0, 64,}
+-	,
+-	{255, 208, 0x30, 0, 64,}
+-	,
+-	{255, 203, 0x30, 0, 64,}
+-	,
+-	{255, 197, 0x30, 0, 64,}
+-	,
+-	{255, 191, 0x30, 0, 64,}
+-	,
+-	{255, 186, 0x30, 0, 64,}
+-	,
+-	{255, 181, 0x30, 0, 64,}
+-	,
+-	{255, 175, 0x30, 0, 64,}
+-	,
+-	{255, 255, 0x20, 0, 64,}
+-	,
+-	{255, 248, 0x20, 0, 64,}
+-	,
+-	{255, 241, 0x20, 0, 64,}
+-	,
+-	{255, 234, 0x20, 0, 64,}
+-	,
+-	{255, 227, 0x20, 0, 64,}
+-	,
+-	{255, 221, 0x20, 0, 64,}
+-	,
+-	{255, 215, 0x20, 0, 64,}
+-	,
+-	{255, 208, 0x20, 0, 64,}
+-	,
+-	{255, 203, 0x20, 0, 64,}
+-	,
+-	{255, 197, 0x20, 0, 64,}
+-	,
+-	{255, 191, 0x20, 0, 64,}
+-	,
+-	{255, 186, 0x20, 0, 64,}
+-	,
+-	{255, 181, 0x20, 0, 64,}
+-	,
+-	{255, 175, 0x20, 0, 64,}
+-	,
+-	{255, 170, 0x20, 0, 64,}
+-	,
+-	{255, 166, 0x20, 0, 64,}
+-	,
+-	{255, 161, 0x20, 0, 64,}
+-	,
+-	{255, 156, 0x20, 0, 64,}
+-	,
+-	{255, 152, 0x20, 0, 64,}
+-	,
+-	{255, 148, 0x20, 0, 64,}
+-	,
+-	{255, 143, 0x20, 0, 64,}
+-	,
+-	{255, 139, 0x20, 0, 64,}
+-	,
+-	{255, 135, 0x20, 0, 64,}
+-	,
+-	{255, 132, 0x20, 0, 64,}
+-	,
+-	{255, 255, 0x10, 0, 64,}
+-	,
+-	{255, 248, 0x10, 0, 64,}
+-	,
+-};
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
+deleted file mode 100644
+index 5a64a98..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-typedef phytbl_info_t dot11lcnphytbl_info_t;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[];
+-extern const u32 dot11lcnphytbl_info_sz_rev0;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
+-
+-typedef struct {
+-	unsigned char gm;
+-	unsigned char pga;
+-	unsigned char pad;
+-	unsigned char dac;
+-	unsigned char bb_mult;
+-} lcnphy_tx_gain_tbl_entry;
+-
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
+-
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
+deleted file mode 100644
+index 742df99..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
++++ /dev/null
+@@ -1,10632 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-
+-#include <sbhnddma.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phytbl_n.h>
+-
+-const u32 frame_struct_rev0[] = {
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x09804506,
+-	0x00100030,
+-	0x09804507,
+-	0x00100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100004,
+-	0x01000a0d,
+-	0x00100024,
+-	0x0980450e,
+-	0x00100034,
+-	0x0980450f,
+-	0x00100034,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x01800504,
+-	0x00100030,
+-	0x11808505,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x11808504,
+-	0x00100030,
+-	0x3981ca05,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a04,
+-	0x00100000,
+-	0x3981ca05,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100008,
+-	0x01000a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1180850c,
+-	0x00100038,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a0c,
+-	0x00100008,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x02001405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x0200140d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x5b02ca04,
+-	0x00100060,
+-	0x3b01d405,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d404,
+-	0x00100000,
+-	0x3b01d405,
+-	0x00100060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x5002940c,
+-	0x00100010,
+-	0x3201940d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x5b02ca0c,
+-	0x00100070,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d40c,
+-	0x00100010,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x000f4800,
+-	0x62031405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x53028a07,
+-	0x01900060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x000f4808,
+-	0x6203140d,
+-	0x00100048,
+-	0x53028a0e,
+-	0x01900068,
+-	0x53028a0f,
+-	0x01900068,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100004,
+-	0x11008a0d,
+-	0x00100024,
+-	0x1980c50e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x0180c506,
+-	0x00100030,
+-	0x0180c506,
+-	0x00100030,
+-	0x2180c50c,
+-	0x00100030,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x2000ca0c,
+-	0x00100000,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x1980c50e,
+-	0x00100030,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100008,
+-	0x0200140d,
+-	0x00100048,
+-	0x0b004a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x03004a06,
+-	0x01900060,
+-	0x03004a06,
+-	0x01900060,
+-	0x6b030a0c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x6b03140c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x0b004a0e,
+-	0x01900060,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x53028a0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u8 frame_lut_rev0[] = {
+-	0x02,
+-	0x04,
+-	0x14,
+-	0x14,
+-	0x03,
+-	0x05,
+-	0x16,
+-	0x16,
+-	0x0a,
+-	0x0c,
+-	0x1c,
+-	0x1c,
+-	0x0b,
+-	0x0d,
+-	0x1e,
+-	0x1e,
+-	0x06,
+-	0x08,
+-	0x18,
+-	0x18,
+-	0x07,
+-	0x09,
+-	0x1a,
+-	0x1a,
+-	0x0e,
+-	0x10,
+-	0x20,
+-	0x28,
+-	0x0f,
+-	0x11,
+-	0x22,
+-	0x2a,
+-};
+-
+-const u32 tmap_tbl_rev0[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdtrn_tbl_rev0[] = {
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0xfa58fa58,
+-	0xf895043b,
+-	0xff4c09c0,
+-	0xfbc6ffa8,
+-	0xfb84f384,
+-	0x0798f6f9,
+-	0x05760122,
+-	0x058409f6,
+-	0x0b500000,
+-	0x05b7f542,
+-	0x08860432,
+-	0x06ddfee7,
+-	0xfb84f384,
+-	0xf9d90664,
+-	0xf7e8025c,
+-	0x00fff7bd,
+-	0x05a805a8,
+-	0xf7bd00ff,
+-	0x025cf7e8,
+-	0x0664f9d9,
+-	0xf384fb84,
+-	0xfee706dd,
+-	0x04320886,
+-	0xf54205b7,
+-	0x00000b50,
+-	0x09f60584,
+-	0x01220576,
+-	0xf6f90798,
+-	0xf384fb84,
+-	0xffa8fbc6,
+-	0x09c0ff4c,
+-	0x043bf895,
+-	0x02d402d4,
+-	0x07de0270,
+-	0xfc96079c,
+-	0xf90afe94,
+-	0xfe00ff2c,
+-	0x02d4065d,
+-	0x092a0096,
+-	0x0014fbb8,
+-	0xfd2cfd2c,
+-	0x076afb3c,
+-	0x0096f752,
+-	0xf991fd87,
+-	0xfb2c0200,
+-	0xfeb8f960,
+-	0x08e0fc96,
+-	0x049802a8,
+-	0xfd2cfd2c,
+-	0x02a80498,
+-	0xfc9608e0,
+-	0xf960feb8,
+-	0x0200fb2c,
+-	0xfd87f991,
+-	0xf7520096,
+-	0xfb3c076a,
+-	0xfd2cfd2c,
+-	0xfbb80014,
+-	0x0096092a,
+-	0x065d02d4,
+-	0xff2cfe00,
+-	0xfe94f90a,
+-	0x079cfc96,
+-	0x027007de,
+-	0x02d402d4,
+-	0x027007de,
+-	0x079cfc96,
+-	0xfe94f90a,
+-	0xff2cfe00,
+-	0x065d02d4,
+-	0x0096092a,
+-	0xfbb80014,
+-	0xfd2cfd2c,
+-	0xfb3c076a,
+-	0xf7520096,
+-	0xfd87f991,
+-	0x0200fb2c,
+-	0xf960feb8,
+-	0xfc9608e0,
+-	0x02a80498,
+-	0xfd2cfd2c,
+-	0x049802a8,
+-	0x08e0fc96,
+-	0xfeb8f960,
+-	0xfb2c0200,
+-	0xf991fd87,
+-	0x0096f752,
+-	0x076afb3c,
+-	0xfd2cfd2c,
+-	0x0014fbb8,
+-	0x092a0096,
+-	0x02d4065d,
+-	0xfe00ff2c,
+-	0xf90afe94,
+-	0xfc96079c,
+-	0x07de0270,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x061c061c,
+-	0xff30009d,
+-	0xffb21141,
+-	0xfd87fb54,
+-	0xf65dfe59,
+-	0x02eef99e,
+-	0x0166f03c,
+-	0xfff809b6,
+-	0x000008a4,
+-	0x000af42b,
+-	0x00eff577,
+-	0xfa840bf2,
+-	0xfc02ff51,
+-	0x08260f67,
+-	0xfff0036f,
+-	0x0842f9c3,
+-	0x00000000,
+-	0x063df7be,
+-	0xfc910010,
+-	0xf099f7da,
+-	0x00af03fe,
+-	0xf40e057c,
+-	0x0a89ff11,
+-	0x0bd5fff6,
+-	0xf75c0000,
+-	0xf64a0008,
+-	0x0fc4fe9a,
+-	0x0662fd12,
+-	0x01a709a3,
+-	0x04ac0279,
+-	0xeebf004e,
+-	0xff6300d0,
+-	0xf9e4f9e4,
+-	0x00d0ff63,
+-	0x004eeebf,
+-	0x027904ac,
+-	0x09a301a7,
+-	0xfd120662,
+-	0xfe9a0fc4,
+-	0x0008f64a,
+-	0x0000f75c,
+-	0xfff60bd5,
+-	0xff110a89,
+-	0x057cf40e,
+-	0x03fe00af,
+-	0xf7daf099,
+-	0x0010fc91,
+-	0xf7be063d,
+-	0x00000000,
+-	0xf9c30842,
+-	0x036ffff0,
+-	0x0f670826,
+-	0xff51fc02,
+-	0x0bf2fa84,
+-	0xf57700ef,
+-	0xf42b000a,
+-	0x08a40000,
+-	0x09b6fff8,
+-	0xf03c0166,
+-	0xf99e02ee,
+-	0xfe59f65d,
+-	0xfb54fd87,
+-	0x1141ffb2,
+-	0x009dff30,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0xfa58fa58,
+-	0xf8f0fe00,
+-	0x0448073d,
+-	0xfdc9fe46,
+-	0xf9910258,
+-	0x089d0407,
+-	0xfd5cf71a,
+-	0x02affde0,
+-	0x083e0496,
+-	0xff5a0740,
+-	0xff7afd97,
+-	0x00fe01f1,
+-	0x0009082e,
+-	0xfa94ff75,
+-	0xfecdf8ea,
+-	0xffb0f693,
+-	0xfd2cfa58,
+-	0x0433ff16,
+-	0xfba405dd,
+-	0xfa610341,
+-	0x06a606cb,
+-	0x0039fd2d,
+-	0x0677fa97,
+-	0x01fa05e0,
+-	0xf896003e,
+-	0x075a068b,
+-	0x012cfc3e,
+-	0xfa23f98d,
+-	0xfc7cfd43,
+-	0xff90fc0d,
+-	0x01c10982,
+-	0x00c601d6,
+-	0xfd2cfd2c,
+-	0x01d600c6,
+-	0x098201c1,
+-	0xfc0dff90,
+-	0xfd43fc7c,
+-	0xf98dfa23,
+-	0xfc3e012c,
+-	0x068b075a,
+-	0x003ef896,
+-	0x05e001fa,
+-	0xfa970677,
+-	0xfd2d0039,
+-	0x06cb06a6,
+-	0x0341fa61,
+-	0x05ddfba4,
+-	0xff160433,
+-	0xfa58fd2c,
+-	0xf693ffb0,
+-	0xf8eafecd,
+-	0xff75fa94,
+-	0x082e0009,
+-	0x01f100fe,
+-	0xfd97ff7a,
+-	0x0740ff5a,
+-	0x0496083e,
+-	0xfde002af,
+-	0xf71afd5c,
+-	0x0407089d,
+-	0x0258f991,
+-	0xfe46fdc9,
+-	0x073d0448,
+-	0xfe00f8f0,
+-	0xfd2cfd2c,
+-	0xfce00500,
+-	0xfc09fddc,
+-	0xfe680157,
+-	0x04c70571,
+-	0xfc3aff21,
+-	0xfcd70228,
+-	0x056d0277,
+-	0x0200fe00,
+-	0x0022f927,
+-	0xfe3c032b,
+-	0xfc44ff3c,
+-	0x03e9fbdb,
+-	0x04570313,
+-	0x04c9ff5c,
+-	0x000d03b8,
+-	0xfa580000,
+-	0xfbe900d2,
+-	0xf9d0fe0b,
+-	0x0125fdf9,
+-	0x042501bf,
+-	0x0328fa2b,
+-	0xffa902f0,
+-	0xfa250157,
+-	0x0200fe00,
+-	0x03740438,
+-	0xff0405fd,
+-	0x030cfe52,
+-	0x0037fb39,
+-	0xff6904c5,
+-	0x04f8fd23,
+-	0xfd31fc1b,
+-	0xfd2cfd2c,
+-	0xfc1bfd31,
+-	0xfd2304f8,
+-	0x04c5ff69,
+-	0xfb390037,
+-	0xfe52030c,
+-	0x05fdff04,
+-	0x04380374,
+-	0xfe000200,
+-	0x0157fa25,
+-	0x02f0ffa9,
+-	0xfa2b0328,
+-	0x01bf0425,
+-	0xfdf90125,
+-	0xfe0bf9d0,
+-	0x00d2fbe9,
+-	0x0000fa58,
+-	0x03b8000d,
+-	0xff5c04c9,
+-	0x03130457,
+-	0xfbdb03e9,
+-	0xff3cfc44,
+-	0x032bfe3c,
+-	0xf9270022,
+-	0xfe000200,
+-	0x0277056d,
+-	0x0228fcd7,
+-	0xff21fc3a,
+-	0x057104c7,
+-	0x0157fe68,
+-	0xfddcfc09,
+-	0x0500fce0,
+-	0xfd2cfd2c,
+-	0x0500fce0,
+-	0xfddcfc09,
+-	0x0157fe68,
+-	0x057104c7,
+-	0xff21fc3a,
+-	0x0228fcd7,
+-	0x0277056d,
+-	0xfe000200,
+-	0xf9270022,
+-	0x032bfe3c,
+-	0xff3cfc44,
+-	0xfbdb03e9,
+-	0x03130457,
+-	0xff5c04c9,
+-	0x03b8000d,
+-	0x0000fa58,
+-	0x00d2fbe9,
+-	0xfe0bf9d0,
+-	0xfdf90125,
+-	0x01bf0425,
+-	0xfa2b0328,
+-	0x02f0ffa9,
+-	0x0157fa25,
+-	0xfe000200,
+-	0x04380374,
+-	0x05fdff04,
+-	0xfe52030c,
+-	0xfb390037,
+-	0x04c5ff69,
+-	0xfd2304f8,
+-	0xfc1bfd31,
+-	0xfd2cfd2c,
+-	0xfd31fc1b,
+-	0x04f8fd23,
+-	0xff6904c5,
+-	0x0037fb39,
+-	0x030cfe52,
+-	0xff0405fd,
+-	0x03740438,
+-	0x0200fe00,
+-	0xfa250157,
+-	0xffa902f0,
+-	0x0328fa2b,
+-	0x042501bf,
+-	0x0125fdf9,
+-	0xf9d0fe0b,
+-	0xfbe900d2,
+-	0xfa580000,
+-	0x000d03b8,
+-	0x04c9ff5c,
+-	0x04570313,
+-	0x03e9fbdb,
+-	0xfc44ff3c,
+-	0xfe3c032b,
+-	0x0022f927,
+-	0x0200fe00,
+-	0x056d0277,
+-	0xfcd70228,
+-	0xfc3aff21,
+-	0x04c70571,
+-	0xfe680157,
+-	0xfc09fddc,
+-	0xfce00500,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-};
+-
+-const u32 intlv_tbl_rev0[] = {
+-	0x00802070,
+-	0x0671188d,
+-	0x0a60192c,
+-	0x0a300e46,
+-	0x00c1188d,
+-	0x080024d2,
+-	0x00000070,
+-};
+-
+-const u16 pilot_tbl_rev0[] = {
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0xff0a,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xff0a,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xf83f,
+-	0xfa1f,
+-	0xfa97,
+-	0xfab5,
+-	0xf2bd,
+-	0xf0bf,
+-	0xffff,
+-	0xffff,
+-	0xf017,
+-	0xf815,
+-	0xf215,
+-	0xf095,
+-	0xf035,
+-	0xf01d,
+-	0xffff,
+-	0xffff,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xf01f,
+-	0xf817,
+-	0xfa15,
+-	0xf295,
+-	0xf0b5,
+-	0xf03d,
+-	0xffff,
+-	0xffff,
+-	0xf82a,
+-	0xfa0a,
+-	0xfa82,
+-	0xfaa0,
+-	0xf2a8,
+-	0xf0aa,
+-	0xffff,
+-	0xffff,
+-	0xf002,
+-	0xf800,
+-	0xf200,
+-	0xf080,
+-	0xf020,
+-	0xf008,
+-	0xffff,
+-	0xffff,
+-	0xf00a,
+-	0xf802,
+-	0xfa00,
+-	0xf280,
+-	0xf0a0,
+-	0xf028,
+-	0xffff,
+-	0xffff,
+-};
+-
+-const u32 pltlut_tbl_rev0[] = {
+-	0x76540123,
+-	0x62407351,
+-	0x76543201,
+-	0x76540213,
+-	0x76540123,
+-	0x76430521,
+-};
+-
+-const u32 tdi_tbl20_ant0_rev0[] = {
+-	0x00091226,
+-	0x000a1429,
+-	0x000b56ad,
+-	0x000c58b0,
+-	0x000d5ab3,
+-	0x000e9cb6,
+-	0x000f9eba,
+-	0x0000c13d,
+-	0x00020301,
+-	0x00030504,
+-	0x00040708,
+-	0x0005090b,
+-	0x00064b8e,
+-	0x00095291,
+-	0x000a5494,
+-	0x000b9718,
+-	0x000c9927,
+-	0x000d9b2a,
+-	0x000edd2e,
+-	0x000fdf31,
+-	0x000101b4,
+-	0x000243b7,
+-	0x000345bb,
+-	0x000447be,
+-	0x00058982,
+-	0x00068c05,
+-	0x00099309,
+-	0x000a950c,
+-	0x000bd78f,
+-	0x000cd992,
+-	0x000ddb96,
+-	0x000f1d99,
+-	0x00005fa8,
+-	0x0001422c,
+-	0x0002842f,
+-	0x00038632,
+-	0x00048835,
+-	0x0005ca38,
+-	0x0006ccbc,
+-	0x0009d3bf,
+-	0x000b1603,
+-	0x000c1806,
+-	0x000d1a0a,
+-	0x000e1c0d,
+-	0x000f5e10,
+-	0x00008093,
+-	0x00018297,
+-	0x0002c49a,
+-	0x0003c680,
+-	0x0004c880,
+-	0x00060b00,
+-	0x00070d00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl20_ant1_rev0[] = {
+-	0x00014b26,
+-	0x00028d29,
+-	0x000393ad,
+-	0x00049630,
+-	0x0005d833,
+-	0x0006da36,
+-	0x00099c3a,
+-	0x000a9e3d,
+-	0x000bc081,
+-	0x000cc284,
+-	0x000dc488,
+-	0x000f068b,
+-	0x0000488e,
+-	0x00018b91,
+-	0x0002d214,
+-	0x0003d418,
+-	0x0004d6a7,
+-	0x000618aa,
+-	0x00071aae,
+-	0x0009dcb1,
+-	0x000b1eb4,
+-	0x000c0137,
+-	0x000d033b,
+-	0x000e053e,
+-	0x000f4702,
+-	0x00008905,
+-	0x00020c09,
+-	0x0003128c,
+-	0x0004148f,
+-	0x00051712,
+-	0x00065916,
+-	0x00091b19,
+-	0x000a1d28,
+-	0x000b5f2c,
+-	0x000c41af,
+-	0x000d43b2,
+-	0x000e85b5,
+-	0x000f87b8,
+-	0x0000c9bc,
+-	0x00024cbf,
+-	0x00035303,
+-	0x00045506,
+-	0x0005978a,
+-	0x0006998d,
+-	0x00095b90,
+-	0x000a5d93,
+-	0x000b9f97,
+-	0x000c821a,
+-	0x000d8400,
+-	0x000ec600,
+-	0x000fc800,
+-	0x00010a00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant0_rev0[] = {
+-	0x0011a346,
+-	0x00136ccf,
+-	0x0014f5d9,
+-	0x001641e2,
+-	0x0017cb6b,
+-	0x00195475,
+-	0x001b2383,
+-	0x001cad0c,
+-	0x001e7616,
+-	0x0000821f,
+-	0x00020ba8,
+-	0x0003d4b2,
+-	0x00056447,
+-	0x00072dd0,
+-	0x0008b6da,
+-	0x000a02e3,
+-	0x000b8c6c,
+-	0x000d15f6,
+-	0x0011e484,
+-	0x0013ae0d,
+-	0x00153717,
+-	0x00168320,
+-	0x00180ca9,
+-	0x00199633,
+-	0x001b6548,
+-	0x001ceed1,
+-	0x001eb7db,
+-	0x0000c3e4,
+-	0x00024d6d,
+-	0x000416f7,
+-	0x0005a585,
+-	0x00076f0f,
+-	0x0008f818,
+-	0x000a4421,
+-	0x000bcdab,
+-	0x000d9734,
+-	0x00122649,
+-	0x0013efd2,
+-	0x001578dc,
+-	0x0016c4e5,
+-	0x00184e6e,
+-	0x001a17f8,
+-	0x001ba686,
+-	0x001d3010,
+-	0x001ef999,
+-	0x00010522,
+-	0x00028eac,
+-	0x00045835,
+-	0x0005e74a,
+-	0x0007b0d3,
+-	0x00093a5d,
+-	0x000a85e6,
+-	0x000c0f6f,
+-	0x000dd8f9,
+-	0x00126787,
+-	0x00143111,
+-	0x0015ba9a,
+-	0x00170623,
+-	0x00188fad,
+-	0x001a5936,
+-	0x001be84b,
+-	0x001db1d4,
+-	0x001f3b5e,
+-	0x000146e7,
+-	0x00031070,
+-	0x000499fa,
+-	0x00062888,
+-	0x0007f212,
+-	0x00097b9b,
+-	0x000ac7a4,
+-	0x000c50ae,
+-	0x000e1a37,
+-	0x0012a94c,
+-	0x001472d5,
+-	0x0015fc5f,
+-	0x00174868,
+-	0x0018d171,
+-	0x001a9afb,
+-	0x001c2989,
+-	0x001df313,
+-	0x001f7c9c,
+-	0x000188a5,
+-	0x000351af,
+-	0x0004db38,
+-	0x0006aa4d,
+-	0x000833d7,
+-	0x0009bd60,
+-	0x000b0969,
+-	0x000c9273,
+-	0x000e5bfc,
+-	0x00132a8a,
+-	0x0014b414,
+-	0x00163d9d,
+-	0x001789a6,
+-	0x001912b0,
+-	0x001adc39,
+-	0x001c6bce,
+-	0x001e34d8,
+-	0x001fbe61,
+-	0x0001ca6a,
+-	0x00039374,
+-	0x00051cfd,
+-	0x0006ec0b,
+-	0x00087515,
+-	0x0009fe9e,
+-	0x000b4aa7,
+-	0x000cd3b1,
+-	0x000e9d3a,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant1_rev0[] = {
+-	0x001edb36,
+-	0x000129ca,
+-	0x0002b353,
+-	0x00047cdd,
+-	0x0005c8e6,
+-	0x000791ef,
+-	0x00091bf9,
+-	0x000aaa07,
+-	0x000c3391,
+-	0x000dfd1a,
+-	0x00120923,
+-	0x0013d22d,
+-	0x00155c37,
+-	0x0016eacb,
+-	0x00187454,
+-	0x001a3dde,
+-	0x001b89e7,
+-	0x001d12f0,
+-	0x001f1cfa,
+-	0x00016b88,
+-	0x00033492,
+-	0x0004be1b,
+-	0x00060a24,
+-	0x0007d32e,
+-	0x00095d38,
+-	0x000aec4c,
+-	0x000c7555,
+-	0x000e3edf,
+-	0x00124ae8,
+-	0x001413f1,
+-	0x0015a37b,
+-	0x00172c89,
+-	0x0018b593,
+-	0x001a419c,
+-	0x001bcb25,
+-	0x001d942f,
+-	0x001f63b9,
+-	0x0001ad4d,
+-	0x00037657,
+-	0x0004c260,
+-	0x00068be9,
+-	0x000814f3,
+-	0x0009a47c,
+-	0x000b2d8a,
+-	0x000cb694,
+-	0x000e429d,
+-	0x00128c26,
+-	0x001455b0,
+-	0x0015e4ba,
+-	0x00176e4e,
+-	0x0018f758,
+-	0x001a8361,
+-	0x001c0cea,
+-	0x001dd674,
+-	0x001fa57d,
+-	0x0001ee8b,
+-	0x0003b795,
+-	0x0005039e,
+-	0x0006cd27,
+-	0x000856b1,
+-	0x0009e5c6,
+-	0x000b6f4f,
+-	0x000cf859,
+-	0x000e8462,
+-	0x00130deb,
+-	0x00149775,
+-	0x00162603,
+-	0x0017af8c,
+-	0x00193896,
+-	0x001ac49f,
+-	0x001c4e28,
+-	0x001e17b2,
+-	0x0000a6c7,
+-	0x00023050,
+-	0x0003f9da,
+-	0x00054563,
+-	0x00070eec,
+-	0x00089876,
+-	0x000a2704,
+-	0x000bb08d,
+-	0x000d3a17,
+-	0x001185a0,
+-	0x00134f29,
+-	0x0014d8b3,
+-	0x001667c8,
+-	0x0017f151,
+-	0x00197adb,
+-	0x001b0664,
+-	0x001c8fed,
+-	0x001e5977,
+-	0x0000e805,
+-	0x0002718f,
+-	0x00043b18,
+-	0x000586a1,
+-	0x0007502b,
+-	0x0008d9b4,
+-	0x000a68c9,
+-	0x000bf252,
+-	0x000dbbdc,
+-	0x0011c7e5,
+-	0x001390ee,
+-	0x00151a78,
+-	0x0016a906,
+-	0x00183290,
+-	0x0019bc19,
+-	0x001b4822,
+-	0x001cd12c,
+-	0x001e9ab5,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 bdi_tbl_rev0[] = {
+-	0x0070,
+-	0x0126,
+-	0x012c,
+-	0x0246,
+-	0x048d,
+-	0x04d2,
+-};
+-
+-const u32 chanest_tbl_rev0[] = {
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-};
+-
+-const u8 mcs_tbl_rev0[] = {
+-	0x00,
+-	0x08,
+-	0x0a,
+-	0x10,
+-	0x12,
+-	0x19,
+-	0x1a,
+-	0x1c,
+-	0x40,
+-	0x48,
+-	0x4a,
+-	0x50,
+-	0x52,
+-	0x59,
+-	0x5a,
+-	0x5c,
+-	0x80,
+-	0x88,
+-	0x8a,
+-	0x90,
+-	0x92,
+-	0x99,
+-	0x9a,
+-	0x9c,
+-	0xc0,
+-	0xc8,
+-	0xca,
+-	0xd0,
+-	0xd2,
+-	0xd9,
+-	0xda,
+-	0xdc,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x01,
+-	0x02,
+-	0x04,
+-	0x08,
+-	0x09,
+-	0x0a,
+-	0x0c,
+-	0x10,
+-	0x11,
+-	0x12,
+-	0x14,
+-	0x18,
+-	0x19,
+-	0x1a,
+-	0x1c,
+-	0x20,
+-	0x21,
+-	0x22,
+-	0x24,
+-	0x40,
+-	0x41,
+-	0x42,
+-	0x44,
+-	0x48,
+-	0x49,
+-	0x4a,
+-	0x4c,
+-	0x50,
+-	0x51,
+-	0x52,
+-	0x54,
+-	0x58,
+-	0x59,
+-	0x5a,
+-	0x5c,
+-	0x60,
+-	0x61,
+-	0x62,
+-	0x64,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 noise_var_tbl0_rev0[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u32 noise_var_tbl1_rev0[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u8 est_pwr_lut_core0_rev0[] = {
+-	0x50,
+-	0x4f,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3b,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x34,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x30,
+-	0x2f,
+-	0x2e,
+-	0x2d,
+-	0x2c,
+-	0x2b,
+-	0x2a,
+-	0x29,
+-	0x28,
+-	0x27,
+-	0x26,
+-	0x25,
+-	0x24,
+-	0x23,
+-	0x22,
+-	0x21,
+-	0x20,
+-	0x1f,
+-	0x1e,
+-	0x1d,
+-	0x1c,
+-	0x1b,
+-	0x1a,
+-	0x19,
+-	0x18,
+-	0x17,
+-	0x16,
+-	0x15,
+-	0x14,
+-	0x13,
+-	0x12,
+-	0x11,
+-};
+-
+-const u8 est_pwr_lut_core1_rev0[] = {
+-	0x50,
+-	0x4f,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3b,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x34,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x30,
+-	0x2f,
+-	0x2e,
+-	0x2d,
+-	0x2c,
+-	0x2b,
+-	0x2a,
+-	0x29,
+-	0x28,
+-	0x27,
+-	0x26,
+-	0x25,
+-	0x24,
+-	0x23,
+-	0x22,
+-	0x21,
+-	0x20,
+-	0x1f,
+-	0x1e,
+-	0x1d,
+-	0x1c,
+-	0x1b,
+-	0x1a,
+-	0x19,
+-	0x18,
+-	0x17,
+-	0x16,
+-	0x15,
+-	0x14,
+-	0x13,
+-	0x12,
+-	0x11,
+-};
+-
+-const u8 adj_pwr_lut_core0_rev0[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 adj_pwr_lut_core1_rev0[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 gainctrl_lut_core0_rev0[] = {
+-	0x03cc2b44,
+-	0x03cc2b42,
+-	0x03cc2b40,
+-	0x03cc2b3e,
+-	0x03cc2b3d,
+-	0x03cc2b3b,
+-	0x03c82b44,
+-	0x03c82b42,
+-	0x03c82b40,
+-	0x03c82b3e,
+-	0x03c82b3d,
+-	0x03c82b3b,
+-	0x03c82b39,
+-	0x03c82b38,
+-	0x03c82b36,
+-	0x03c82b34,
+-	0x03c42b44,
+-	0x03c42b42,
+-	0x03c42b40,
+-	0x03c42b3e,
+-	0x03c42b3d,
+-	0x03c42b3b,
+-	0x03c42b39,
+-	0x03c42b38,
+-	0x03c42b36,
+-	0x03c42b34,
+-	0x03c42b33,
+-	0x03c42b32,
+-	0x03c42b30,
+-	0x03c42b2f,
+-	0x03c42b2d,
+-	0x03c02b44,
+-	0x03c02b42,
+-	0x03c02b40,
+-	0x03c02b3e,
+-	0x03c02b3d,
+-	0x03c02b3b,
+-	0x03c02b39,
+-	0x03c02b38,
+-	0x03c02b36,
+-	0x03c02b34,
+-	0x03b02b44,
+-	0x03b02b42,
+-	0x03b02b40,
+-	0x03b02b3e,
+-	0x03b02b3d,
+-	0x03b02b3b,
+-	0x03b02b39,
+-	0x03b02b38,
+-	0x03b02b36,
+-	0x03b02b34,
+-	0x03b02b33,
+-	0x03b02b32,
+-	0x03b02b30,
+-	0x03b02b2f,
+-	0x03b02b2d,
+-	0x03a02b44,
+-	0x03a02b42,
+-	0x03a02b40,
+-	0x03a02b3e,
+-	0x03a02b3d,
+-	0x03a02b3b,
+-	0x03a02b39,
+-	0x03a02b38,
+-	0x03a02b36,
+-	0x03a02b34,
+-	0x03902b44,
+-	0x03902b42,
+-	0x03902b40,
+-	0x03902b3e,
+-	0x03902b3d,
+-	0x03902b3b,
+-	0x03902b39,
+-	0x03902b38,
+-	0x03902b36,
+-	0x03902b34,
+-	0x03902b33,
+-	0x03902b32,
+-	0x03902b30,
+-	0x03802b44,
+-	0x03802b42,
+-	0x03802b40,
+-	0x03802b3e,
+-	0x03802b3d,
+-	0x03802b3b,
+-	0x03802b39,
+-	0x03802b38,
+-	0x03802b36,
+-	0x03802b34,
+-	0x03802b33,
+-	0x03802b32,
+-	0x03802b30,
+-	0x03802b2f,
+-	0x03802b2d,
+-	0x03802b2c,
+-	0x03802b2b,
+-	0x03802b2a,
+-	0x03802b29,
+-	0x03802b27,
+-	0x03802b26,
+-	0x03802b25,
+-	0x03802b24,
+-	0x03802b23,
+-	0x03802b22,
+-	0x03802b21,
+-	0x03802b20,
+-	0x03802b1f,
+-	0x03802b1e,
+-	0x03802b1e,
+-	0x03802b1d,
+-	0x03802b1c,
+-	0x03802b1b,
+-	0x03802b1a,
+-	0x03802b1a,
+-	0x03802b19,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x00002b00,
+-};
+-
+-const u32 gainctrl_lut_core1_rev0[] = {
+-	0x03cc2b44,
+-	0x03cc2b42,
+-	0x03cc2b40,
+-	0x03cc2b3e,
+-	0x03cc2b3d,
+-	0x03cc2b3b,
+-	0x03c82b44,
+-	0x03c82b42,
+-	0x03c82b40,
+-	0x03c82b3e,
+-	0x03c82b3d,
+-	0x03c82b3b,
+-	0x03c82b39,
+-	0x03c82b38,
+-	0x03c82b36,
+-	0x03c82b34,
+-	0x03c42b44,
+-	0x03c42b42,
+-	0x03c42b40,
+-	0x03c42b3e,
+-	0x03c42b3d,
+-	0x03c42b3b,
+-	0x03c42b39,
+-	0x03c42b38,
+-	0x03c42b36,
+-	0x03c42b34,
+-	0x03c42b33,
+-	0x03c42b32,
+-	0x03c42b30,
+-	0x03c42b2f,
+-	0x03c42b2d,
+-	0x03c02b44,
+-	0x03c02b42,
+-	0x03c02b40,
+-	0x03c02b3e,
+-	0x03c02b3d,
+-	0x03c02b3b,
+-	0x03c02b39,
+-	0x03c02b38,
+-	0x03c02b36,
+-	0x03c02b34,
+-	0x03b02b44,
+-	0x03b02b42,
+-	0x03b02b40,
+-	0x03b02b3e,
+-	0x03b02b3d,
+-	0x03b02b3b,
+-	0x03b02b39,
+-	0x03b02b38,
+-	0x03b02b36,
+-	0x03b02b34,
+-	0x03b02b33,
+-	0x03b02b32,
+-	0x03b02b30,
+-	0x03b02b2f,
+-	0x03b02b2d,
+-	0x03a02b44,
+-	0x03a02b42,
+-	0x03a02b40,
+-	0x03a02b3e,
+-	0x03a02b3d,
+-	0x03a02b3b,
+-	0x03a02b39,
+-	0x03a02b38,
+-	0x03a02b36,
+-	0x03a02b34,
+-	0x03902b44,
+-	0x03902b42,
+-	0x03902b40,
+-	0x03902b3e,
+-	0x03902b3d,
+-	0x03902b3b,
+-	0x03902b39,
+-	0x03902b38,
+-	0x03902b36,
+-	0x03902b34,
+-	0x03902b33,
+-	0x03902b32,
+-	0x03902b30,
+-	0x03802b44,
+-	0x03802b42,
+-	0x03802b40,
+-	0x03802b3e,
+-	0x03802b3d,
+-	0x03802b3b,
+-	0x03802b39,
+-	0x03802b38,
+-	0x03802b36,
+-	0x03802b34,
+-	0x03802b33,
+-	0x03802b32,
+-	0x03802b30,
+-	0x03802b2f,
+-	0x03802b2d,
+-	0x03802b2c,
+-	0x03802b2b,
+-	0x03802b2a,
+-	0x03802b29,
+-	0x03802b27,
+-	0x03802b26,
+-	0x03802b25,
+-	0x03802b24,
+-	0x03802b23,
+-	0x03802b22,
+-	0x03802b21,
+-	0x03802b20,
+-	0x03802b1f,
+-	0x03802b1e,
+-	0x03802b1e,
+-	0x03802b1d,
+-	0x03802b1c,
+-	0x03802b1b,
+-	0x03802b1a,
+-	0x03802b1a,
+-	0x03802b19,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x00002b00,
+-};
+-
+-const u32 iq_lut_core0_rev0[] = {
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-};
+-
+-const u32 iq_lut_core1_rev0[] = {
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-};
+-
+-const u16 loft_lut_core0_rev0[] = {
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-};
+-
+-const u16 loft_lut_core1_rev0[] = {
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = {
+-	{&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
+-	 16}
+-	,
+-	{&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
+-	 20, 0, 32}
+-	,
+-	{&gainctrl_lut_core0_rev0,
+-	 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev0,
+-	 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
+-	 27, 192, 32}
+-	,
+-
+-	{&est_pwr_lut_core0_rev0,
+-	 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev0,
+-	 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev0,
+-	 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev0,
+-	 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
+-	 64, 8}
+-	,
+-	{&iq_lut_core0_rev0,
+-	 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev0,
+-	 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev0,
+-	 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev0,
+-	 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev0[] = {
+-	{&frame_struct_rev0,
+-	 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
+-	,
+-	{&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
+-	 24, 0, 8}
+-	,
+-	{&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
+-	 0, 32}
+-	,
+-	{&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
+-	 14, 0, 32}
+-	,
+-	{&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
+-	 13, 0, 32}
+-	,
+-	{&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
+-	 11, 0, 16}
+-	,
+-	{&tdi_tbl20_ant0_rev0,
+-	 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev0,
+-	 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev0,
+-	 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev0,
+-	 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
+-	 32}
+-	,
+-	{&chanest_tbl_rev0,
+-	 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
+-	,
+-	{&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8}
+-	,
+-	{&noise_var_tbl0_rev0,
+-	 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
+-	 32}
+-	,
+-	{&noise_var_tbl1_rev0,
+-	 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
+-	 32}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev0 =
+-    sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
+-const u32 mimophytbl_info_sz_rev0_volatile =
+-    sizeof(mimophytbl_info_rev0_volatile) /
+-    sizeof(mimophytbl_info_rev0_volatile[0]);
+-
+-const u16 ant_swctrl_tbl_rev3[] = {
+-	0x0082,
+-	0x0082,
+-	0x0211,
+-	0x0222,
+-	0x0328,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0144,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0188,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0082,
+-	0x0082,
+-	0x0211,
+-	0x0222,
+-	0x0328,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0144,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0188,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_1[] = {
+-	0x0022,
+-	0x0022,
+-	0x0011,
+-	0x0022,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0011,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0022,
+-	0x0011,
+-	0x0022,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0011,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_2[] = {
+-	0x0088,
+-	0x0088,
+-	0x0044,
+-	0x0088,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0044,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0088,
+-	0x0044,
+-	0x0088,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0044,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_3[] = {
+-	0x022,
+-	0x022,
+-	0x011,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x011,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x3cc,
+-	0x022,
+-	0x022,
+-	0x011,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x011,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x3cc
+-};
+-
+-const u32 frame_struct_rev3[] = {
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x09804506,
+-	0x00100030,
+-	0x09804507,
+-	0x00100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100004,
+-	0x01000a0d,
+-	0x00100024,
+-	0x0980450e,
+-	0x00100034,
+-	0x0980450f,
+-	0x00100034,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x01800504,
+-	0x00100030,
+-	0x11808505,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x11808504,
+-	0x00100030,
+-	0x3981ca05,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a04,
+-	0x00100000,
+-	0x3981ca05,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100008,
+-	0x01000a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1180850c,
+-	0x00100038,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a0c,
+-	0x00100008,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x02001405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x0200140d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x5b02ca04,
+-	0x00100060,
+-	0x3b01d405,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d404,
+-	0x00100000,
+-	0x3b01d405,
+-	0x00100060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x5002940c,
+-	0x00100010,
+-	0x3201940d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x5b02ca0c,
+-	0x00100070,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d40c,
+-	0x00100010,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x000f4800,
+-	0x62031405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x53028a07,
+-	0x01900060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x000f4808,
+-	0x6203140d,
+-	0x00100048,
+-	0x53028a0e,
+-	0x01900068,
+-	0x53028a0f,
+-	0x01900068,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100004,
+-	0x11008a0d,
+-	0x00100024,
+-	0x1980c50e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x0180c506,
+-	0x00100030,
+-	0x0180c506,
+-	0x00100030,
+-	0x2180c50c,
+-	0x00100030,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x2000ca0c,
+-	0x00100000,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x1980c50e,
+-	0x00100030,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100008,
+-	0x0200140d,
+-	0x00100048,
+-	0x0b004a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x03004a06,
+-	0x01900060,
+-	0x03004a06,
+-	0x01900060,
+-	0x6b030a0c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x6b03140c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x0b004a0e,
+-	0x01900060,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x53028a0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 pilot_tbl_rev3[] = {
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0xff0a,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xff0a,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xf83f,
+-	0xfa1f,
+-	0xfa97,
+-	0xfab5,
+-	0xf2bd,
+-	0xf0bf,
+-	0xffff,
+-	0xffff,
+-	0xf017,
+-	0xf815,
+-	0xf215,
+-	0xf095,
+-	0xf035,
+-	0xf01d,
+-	0xffff,
+-	0xffff,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xf01f,
+-	0xf817,
+-	0xfa15,
+-	0xf295,
+-	0xf0b5,
+-	0xf03d,
+-	0xffff,
+-	0xffff,
+-	0xf82a,
+-	0xfa0a,
+-	0xfa82,
+-	0xfaa0,
+-	0xf2a8,
+-	0xf0aa,
+-	0xffff,
+-	0xffff,
+-	0xf002,
+-	0xf800,
+-	0xf200,
+-	0xf080,
+-	0xf020,
+-	0xf008,
+-	0xffff,
+-	0xffff,
+-	0xf00a,
+-	0xf802,
+-	0xfa00,
+-	0xf280,
+-	0xf0a0,
+-	0xf028,
+-	0xffff,
+-	0xffff,
+-};
+-
+-const u32 tmap_tbl_rev3[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 intlv_tbl_rev3[] = {
+-	0x00802070,
+-	0x0671188d,
+-	0x0a60192c,
+-	0x0a300e46,
+-	0x00c1188d,
+-	0x080024d2,
+-	0x00000070,
+-};
+-
+-const u32 tdtrn_tbl_rev3[] = {
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0xfa58fa58,
+-	0xf895043b,
+-	0xff4c09c0,
+-	0xfbc6ffa8,
+-	0xfb84f384,
+-	0x0798f6f9,
+-	0x05760122,
+-	0x058409f6,
+-	0x0b500000,
+-	0x05b7f542,
+-	0x08860432,
+-	0x06ddfee7,
+-	0xfb84f384,
+-	0xf9d90664,
+-	0xf7e8025c,
+-	0x00fff7bd,
+-	0x05a805a8,
+-	0xf7bd00ff,
+-	0x025cf7e8,
+-	0x0664f9d9,
+-	0xf384fb84,
+-	0xfee706dd,
+-	0x04320886,
+-	0xf54205b7,
+-	0x00000b50,
+-	0x09f60584,
+-	0x01220576,
+-	0xf6f90798,
+-	0xf384fb84,
+-	0xffa8fbc6,
+-	0x09c0ff4c,
+-	0x043bf895,
+-	0x02d402d4,
+-	0x07de0270,
+-	0xfc96079c,
+-	0xf90afe94,
+-	0xfe00ff2c,
+-	0x02d4065d,
+-	0x092a0096,
+-	0x0014fbb8,
+-	0xfd2cfd2c,
+-	0x076afb3c,
+-	0x0096f752,
+-	0xf991fd87,
+-	0xfb2c0200,
+-	0xfeb8f960,
+-	0x08e0fc96,
+-	0x049802a8,
+-	0xfd2cfd2c,
+-	0x02a80498,
+-	0xfc9608e0,
+-	0xf960feb8,
+-	0x0200fb2c,
+-	0xfd87f991,
+-	0xf7520096,
+-	0xfb3c076a,
+-	0xfd2cfd2c,
+-	0xfbb80014,
+-	0x0096092a,
+-	0x065d02d4,
+-	0xff2cfe00,
+-	0xfe94f90a,
+-	0x079cfc96,
+-	0x027007de,
+-	0x02d402d4,
+-	0x027007de,
+-	0x079cfc96,
+-	0xfe94f90a,
+-	0xff2cfe00,
+-	0x065d02d4,
+-	0x0096092a,
+-	0xfbb80014,
+-	0xfd2cfd2c,
+-	0xfb3c076a,
+-	0xf7520096,
+-	0xfd87f991,
+-	0x0200fb2c,
+-	0xf960feb8,
+-	0xfc9608e0,
+-	0x02a80498,
+-	0xfd2cfd2c,
+-	0x049802a8,
+-	0x08e0fc96,
+-	0xfeb8f960,
+-	0xfb2c0200,
+-	0xf991fd87,
+-	0x0096f752,
+-	0x076afb3c,
+-	0xfd2cfd2c,
+-	0x0014fbb8,
+-	0x092a0096,
+-	0x02d4065d,
+-	0xfe00ff2c,
+-	0xf90afe94,
+-	0xfc96079c,
+-	0x07de0270,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x061c061c,
+-	0xff30009d,
+-	0xffb21141,
+-	0xfd87fb54,
+-	0xf65dfe59,
+-	0x02eef99e,
+-	0x0166f03c,
+-	0xfff809b6,
+-	0x000008a4,
+-	0x000af42b,
+-	0x00eff577,
+-	0xfa840bf2,
+-	0xfc02ff51,
+-	0x08260f67,
+-	0xfff0036f,
+-	0x0842f9c3,
+-	0x00000000,
+-	0x063df7be,
+-	0xfc910010,
+-	0xf099f7da,
+-	0x00af03fe,
+-	0xf40e057c,
+-	0x0a89ff11,
+-	0x0bd5fff6,
+-	0xf75c0000,
+-	0xf64a0008,
+-	0x0fc4fe9a,
+-	0x0662fd12,
+-	0x01a709a3,
+-	0x04ac0279,
+-	0xeebf004e,
+-	0xff6300d0,
+-	0xf9e4f9e4,
+-	0x00d0ff63,
+-	0x004eeebf,
+-	0x027904ac,
+-	0x09a301a7,
+-	0xfd120662,
+-	0xfe9a0fc4,
+-	0x0008f64a,
+-	0x0000f75c,
+-	0xfff60bd5,
+-	0xff110a89,
+-	0x057cf40e,
+-	0x03fe00af,
+-	0xf7daf099,
+-	0x0010fc91,
+-	0xf7be063d,
+-	0x00000000,
+-	0xf9c30842,
+-	0x036ffff0,
+-	0x0f670826,
+-	0xff51fc02,
+-	0x0bf2fa84,
+-	0xf57700ef,
+-	0xf42b000a,
+-	0x08a40000,
+-	0x09b6fff8,
+-	0xf03c0166,
+-	0xf99e02ee,
+-	0xfe59f65d,
+-	0xfb54fd87,
+-	0x1141ffb2,
+-	0x009dff30,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0xfa58fa58,
+-	0xf8f0fe00,
+-	0x0448073d,
+-	0xfdc9fe46,
+-	0xf9910258,
+-	0x089d0407,
+-	0xfd5cf71a,
+-	0x02affde0,
+-	0x083e0496,
+-	0xff5a0740,
+-	0xff7afd97,
+-	0x00fe01f1,
+-	0x0009082e,
+-	0xfa94ff75,
+-	0xfecdf8ea,
+-	0xffb0f693,
+-	0xfd2cfa58,
+-	0x0433ff16,
+-	0xfba405dd,
+-	0xfa610341,
+-	0x06a606cb,
+-	0x0039fd2d,
+-	0x0677fa97,
+-	0x01fa05e0,
+-	0xf896003e,
+-	0x075a068b,
+-	0x012cfc3e,
+-	0xfa23f98d,
+-	0xfc7cfd43,
+-	0xff90fc0d,
+-	0x01c10982,
+-	0x00c601d6,
+-	0xfd2cfd2c,
+-	0x01d600c6,
+-	0x098201c1,
+-	0xfc0dff90,
+-	0xfd43fc7c,
+-	0xf98dfa23,
+-	0xfc3e012c,
+-	0x068b075a,
+-	0x003ef896,
+-	0x05e001fa,
+-	0xfa970677,
+-	0xfd2d0039,
+-	0x06cb06a6,
+-	0x0341fa61,
+-	0x05ddfba4,
+-	0xff160433,
+-	0xfa58fd2c,
+-	0xf693ffb0,
+-	0xf8eafecd,
+-	0xff75fa94,
+-	0x082e0009,
+-	0x01f100fe,
+-	0xfd97ff7a,
+-	0x0740ff5a,
+-	0x0496083e,
+-	0xfde002af,
+-	0xf71afd5c,
+-	0x0407089d,
+-	0x0258f991,
+-	0xfe46fdc9,
+-	0x073d0448,
+-	0xfe00f8f0,
+-	0xfd2cfd2c,
+-	0xfce00500,
+-	0xfc09fddc,
+-	0xfe680157,
+-	0x04c70571,
+-	0xfc3aff21,
+-	0xfcd70228,
+-	0x056d0277,
+-	0x0200fe00,
+-	0x0022f927,
+-	0xfe3c032b,
+-	0xfc44ff3c,
+-	0x03e9fbdb,
+-	0x04570313,
+-	0x04c9ff5c,
+-	0x000d03b8,
+-	0xfa580000,
+-	0xfbe900d2,
+-	0xf9d0fe0b,
+-	0x0125fdf9,
+-	0x042501bf,
+-	0x0328fa2b,
+-	0xffa902f0,
+-	0xfa250157,
+-	0x0200fe00,
+-	0x03740438,
+-	0xff0405fd,
+-	0x030cfe52,
+-	0x0037fb39,
+-	0xff6904c5,
+-	0x04f8fd23,
+-	0xfd31fc1b,
+-	0xfd2cfd2c,
+-	0xfc1bfd31,
+-	0xfd2304f8,
+-	0x04c5ff69,
+-	0xfb390037,
+-	0xfe52030c,
+-	0x05fdff04,
+-	0x04380374,
+-	0xfe000200,
+-	0x0157fa25,
+-	0x02f0ffa9,
+-	0xfa2b0328,
+-	0x01bf0425,
+-	0xfdf90125,
+-	0xfe0bf9d0,
+-	0x00d2fbe9,
+-	0x0000fa58,
+-	0x03b8000d,
+-	0xff5c04c9,
+-	0x03130457,
+-	0xfbdb03e9,
+-	0xff3cfc44,
+-	0x032bfe3c,
+-	0xf9270022,
+-	0xfe000200,
+-	0x0277056d,
+-	0x0228fcd7,
+-	0xff21fc3a,
+-	0x057104c7,
+-	0x0157fe68,
+-	0xfddcfc09,
+-	0x0500fce0,
+-	0xfd2cfd2c,
+-	0x0500fce0,
+-	0xfddcfc09,
+-	0x0157fe68,
+-	0x057104c7,
+-	0xff21fc3a,
+-	0x0228fcd7,
+-	0x0277056d,
+-	0xfe000200,
+-	0xf9270022,
+-	0x032bfe3c,
+-	0xff3cfc44,
+-	0xfbdb03e9,
+-	0x03130457,
+-	0xff5c04c9,
+-	0x03b8000d,
+-	0x0000fa58,
+-	0x00d2fbe9,
+-	0xfe0bf9d0,
+-	0xfdf90125,
+-	0x01bf0425,
+-	0xfa2b0328,
+-	0x02f0ffa9,
+-	0x0157fa25,
+-	0xfe000200,
+-	0x04380374,
+-	0x05fdff04,
+-	0xfe52030c,
+-	0xfb390037,
+-	0x04c5ff69,
+-	0xfd2304f8,
+-	0xfc1bfd31,
+-	0xfd2cfd2c,
+-	0xfd31fc1b,
+-	0x04f8fd23,
+-	0xff6904c5,
+-	0x0037fb39,
+-	0x030cfe52,
+-	0xff0405fd,
+-	0x03740438,
+-	0x0200fe00,
+-	0xfa250157,
+-	0xffa902f0,
+-	0x0328fa2b,
+-	0x042501bf,
+-	0x0125fdf9,
+-	0xf9d0fe0b,
+-	0xfbe900d2,
+-	0xfa580000,
+-	0x000d03b8,
+-	0x04c9ff5c,
+-	0x04570313,
+-	0x03e9fbdb,
+-	0xfc44ff3c,
+-	0xfe3c032b,
+-	0x0022f927,
+-	0x0200fe00,
+-	0x056d0277,
+-	0xfcd70228,
+-	0xfc3aff21,
+-	0x04c70571,
+-	0xfe680157,
+-	0xfc09fddc,
+-	0xfce00500,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-};
+-
+-const u32 noise_var_tbl_rev3[] = {
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-};
+-
+-const u16 mcs_tbl_rev3[] = {
+-	0x0000,
+-	0x0008,
+-	0x000a,
+-	0x0010,
+-	0x0012,
+-	0x0019,
+-	0x001a,
+-	0x001c,
+-	0x0080,
+-	0x0088,
+-	0x008a,
+-	0x0090,
+-	0x0092,
+-	0x0099,
+-	0x009a,
+-	0x009c,
+-	0x0100,
+-	0x0108,
+-	0x010a,
+-	0x0110,
+-	0x0112,
+-	0x0119,
+-	0x011a,
+-	0x011c,
+-	0x0180,
+-	0x0188,
+-	0x018a,
+-	0x0190,
+-	0x0192,
+-	0x0199,
+-	0x019a,
+-	0x019c,
+-	0x0000,
+-	0x0098,
+-	0x00a0,
+-	0x00a8,
+-	0x009a,
+-	0x00a2,
+-	0x00aa,
+-	0x0120,
+-	0x0128,
+-	0x0128,
+-	0x0130,
+-	0x0138,
+-	0x0138,
+-	0x0140,
+-	0x0122,
+-	0x012a,
+-	0x012a,
+-	0x0132,
+-	0x013a,
+-	0x013a,
+-	0x0142,
+-	0x01a8,
+-	0x01b0,
+-	0x01b8,
+-	0x01b0,
+-	0x01b8,
+-	0x01c0,
+-	0x01c8,
+-	0x01c0,
+-	0x01c8,
+-	0x01d0,
+-	0x01d0,
+-	0x01d8,
+-	0x01aa,
+-	0x01b2,
+-	0x01ba,
+-	0x01b2,
+-	0x01ba,
+-	0x01c2,
+-	0x01ca,
+-	0x01c2,
+-	0x01ca,
+-	0x01d2,
+-	0x01d2,
+-	0x01da,
+-	0x0001,
+-	0x0002,
+-	0x0004,
+-	0x0009,
+-	0x000c,
+-	0x0011,
+-	0x0014,
+-	0x0018,
+-	0x0020,
+-	0x0021,
+-	0x0022,
+-	0x0024,
+-	0x0081,
+-	0x0082,
+-	0x0084,
+-	0x0089,
+-	0x008c,
+-	0x0091,
+-	0x0094,
+-	0x0098,
+-	0x00a0,
+-	0x00a1,
+-	0x00a2,
+-	0x00a4,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-};
+-
+-const u32 tdi_tbl20_ant0_rev3[] = {
+-	0x00091226,
+-	0x000a1429,
+-	0x000b56ad,
+-	0x000c58b0,
+-	0x000d5ab3,
+-	0x000e9cb6,
+-	0x000f9eba,
+-	0x0000c13d,
+-	0x00020301,
+-	0x00030504,
+-	0x00040708,
+-	0x0005090b,
+-	0x00064b8e,
+-	0x00095291,
+-	0x000a5494,
+-	0x000b9718,
+-	0x000c9927,
+-	0x000d9b2a,
+-	0x000edd2e,
+-	0x000fdf31,
+-	0x000101b4,
+-	0x000243b7,
+-	0x000345bb,
+-	0x000447be,
+-	0x00058982,
+-	0x00068c05,
+-	0x00099309,
+-	0x000a950c,
+-	0x000bd78f,
+-	0x000cd992,
+-	0x000ddb96,
+-	0x000f1d99,
+-	0x00005fa8,
+-	0x0001422c,
+-	0x0002842f,
+-	0x00038632,
+-	0x00048835,
+-	0x0005ca38,
+-	0x0006ccbc,
+-	0x0009d3bf,
+-	0x000b1603,
+-	0x000c1806,
+-	0x000d1a0a,
+-	0x000e1c0d,
+-	0x000f5e10,
+-	0x00008093,
+-	0x00018297,
+-	0x0002c49a,
+-	0x0003c680,
+-	0x0004c880,
+-	0x00060b00,
+-	0x00070d00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl20_ant1_rev3[] = {
+-	0x00014b26,
+-	0x00028d29,
+-	0x000393ad,
+-	0x00049630,
+-	0x0005d833,
+-	0x0006da36,
+-	0x00099c3a,
+-	0x000a9e3d,
+-	0x000bc081,
+-	0x000cc284,
+-	0x000dc488,
+-	0x000f068b,
+-	0x0000488e,
+-	0x00018b91,
+-	0x0002d214,
+-	0x0003d418,
+-	0x0004d6a7,
+-	0x000618aa,
+-	0x00071aae,
+-	0x0009dcb1,
+-	0x000b1eb4,
+-	0x000c0137,
+-	0x000d033b,
+-	0x000e053e,
+-	0x000f4702,
+-	0x00008905,
+-	0x00020c09,
+-	0x0003128c,
+-	0x0004148f,
+-	0x00051712,
+-	0x00065916,
+-	0x00091b19,
+-	0x000a1d28,
+-	0x000b5f2c,
+-	0x000c41af,
+-	0x000d43b2,
+-	0x000e85b5,
+-	0x000f87b8,
+-	0x0000c9bc,
+-	0x00024cbf,
+-	0x00035303,
+-	0x00045506,
+-	0x0005978a,
+-	0x0006998d,
+-	0x00095b90,
+-	0x000a5d93,
+-	0x000b9f97,
+-	0x000c821a,
+-	0x000d8400,
+-	0x000ec600,
+-	0x000fc800,
+-	0x00010a00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant0_rev3[] = {
+-	0x0011a346,
+-	0x00136ccf,
+-	0x0014f5d9,
+-	0x001641e2,
+-	0x0017cb6b,
+-	0x00195475,
+-	0x001b2383,
+-	0x001cad0c,
+-	0x001e7616,
+-	0x0000821f,
+-	0x00020ba8,
+-	0x0003d4b2,
+-	0x00056447,
+-	0x00072dd0,
+-	0x0008b6da,
+-	0x000a02e3,
+-	0x000b8c6c,
+-	0x000d15f6,
+-	0x0011e484,
+-	0x0013ae0d,
+-	0x00153717,
+-	0x00168320,
+-	0x00180ca9,
+-	0x00199633,
+-	0x001b6548,
+-	0x001ceed1,
+-	0x001eb7db,
+-	0x0000c3e4,
+-	0x00024d6d,
+-	0x000416f7,
+-	0x0005a585,
+-	0x00076f0f,
+-	0x0008f818,
+-	0x000a4421,
+-	0x000bcdab,
+-	0x000d9734,
+-	0x00122649,
+-	0x0013efd2,
+-	0x001578dc,
+-	0x0016c4e5,
+-	0x00184e6e,
+-	0x001a17f8,
+-	0x001ba686,
+-	0x001d3010,
+-	0x001ef999,
+-	0x00010522,
+-	0x00028eac,
+-	0x00045835,
+-	0x0005e74a,
+-	0x0007b0d3,
+-	0x00093a5d,
+-	0x000a85e6,
+-	0x000c0f6f,
+-	0x000dd8f9,
+-	0x00126787,
+-	0x00143111,
+-	0x0015ba9a,
+-	0x00170623,
+-	0x00188fad,
+-	0x001a5936,
+-	0x001be84b,
+-	0x001db1d4,
+-	0x001f3b5e,
+-	0x000146e7,
+-	0x00031070,
+-	0x000499fa,
+-	0x00062888,
+-	0x0007f212,
+-	0x00097b9b,
+-	0x000ac7a4,
+-	0x000c50ae,
+-	0x000e1a37,
+-	0x0012a94c,
+-	0x001472d5,
+-	0x0015fc5f,
+-	0x00174868,
+-	0x0018d171,
+-	0x001a9afb,
+-	0x001c2989,
+-	0x001df313,
+-	0x001f7c9c,
+-	0x000188a5,
+-	0x000351af,
+-	0x0004db38,
+-	0x0006aa4d,
+-	0x000833d7,
+-	0x0009bd60,
+-	0x000b0969,
+-	0x000c9273,
+-	0x000e5bfc,
+-	0x00132a8a,
+-	0x0014b414,
+-	0x00163d9d,
+-	0x001789a6,
+-	0x001912b0,
+-	0x001adc39,
+-	0x001c6bce,
+-	0x001e34d8,
+-	0x001fbe61,
+-	0x0001ca6a,
+-	0x00039374,
+-	0x00051cfd,
+-	0x0006ec0b,
+-	0x00087515,
+-	0x0009fe9e,
+-	0x000b4aa7,
+-	0x000cd3b1,
+-	0x000e9d3a,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant1_rev3[] = {
+-	0x001edb36,
+-	0x000129ca,
+-	0x0002b353,
+-	0x00047cdd,
+-	0x0005c8e6,
+-	0x000791ef,
+-	0x00091bf9,
+-	0x000aaa07,
+-	0x000c3391,
+-	0x000dfd1a,
+-	0x00120923,
+-	0x0013d22d,
+-	0x00155c37,
+-	0x0016eacb,
+-	0x00187454,
+-	0x001a3dde,
+-	0x001b89e7,
+-	0x001d12f0,
+-	0x001f1cfa,
+-	0x00016b88,
+-	0x00033492,
+-	0x0004be1b,
+-	0x00060a24,
+-	0x0007d32e,
+-	0x00095d38,
+-	0x000aec4c,
+-	0x000c7555,
+-	0x000e3edf,
+-	0x00124ae8,
+-	0x001413f1,
+-	0x0015a37b,
+-	0x00172c89,
+-	0x0018b593,
+-	0x001a419c,
+-	0x001bcb25,
+-	0x001d942f,
+-	0x001f63b9,
+-	0x0001ad4d,
+-	0x00037657,
+-	0x0004c260,
+-	0x00068be9,
+-	0x000814f3,
+-	0x0009a47c,
+-	0x000b2d8a,
+-	0x000cb694,
+-	0x000e429d,
+-	0x00128c26,
+-	0x001455b0,
+-	0x0015e4ba,
+-	0x00176e4e,
+-	0x0018f758,
+-	0x001a8361,
+-	0x001c0cea,
+-	0x001dd674,
+-	0x001fa57d,
+-	0x0001ee8b,
+-	0x0003b795,
+-	0x0005039e,
+-	0x0006cd27,
+-	0x000856b1,
+-	0x0009e5c6,
+-	0x000b6f4f,
+-	0x000cf859,
+-	0x000e8462,
+-	0x00130deb,
+-	0x00149775,
+-	0x00162603,
+-	0x0017af8c,
+-	0x00193896,
+-	0x001ac49f,
+-	0x001c4e28,
+-	0x001e17b2,
+-	0x0000a6c7,
+-	0x00023050,
+-	0x0003f9da,
+-	0x00054563,
+-	0x00070eec,
+-	0x00089876,
+-	0x000a2704,
+-	0x000bb08d,
+-	0x000d3a17,
+-	0x001185a0,
+-	0x00134f29,
+-	0x0014d8b3,
+-	0x001667c8,
+-	0x0017f151,
+-	0x00197adb,
+-	0x001b0664,
+-	0x001c8fed,
+-	0x001e5977,
+-	0x0000e805,
+-	0x0002718f,
+-	0x00043b18,
+-	0x000586a1,
+-	0x0007502b,
+-	0x0008d9b4,
+-	0x000a68c9,
+-	0x000bf252,
+-	0x000dbbdc,
+-	0x0011c7e5,
+-	0x001390ee,
+-	0x00151a78,
+-	0x0016a906,
+-	0x00183290,
+-	0x0019bc19,
+-	0x001b4822,
+-	0x001cd12c,
+-	0x001e9ab5,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 pltlut_tbl_rev3[] = {
+-	0x76540213,
+-	0x62407351,
+-	0x76543210,
+-	0x76540213,
+-	0x76540213,
+-	0x76430521,
+-};
+-
+-const u32 chanest_tbl_rev3[] = {
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-};
+-
+-const u8 frame_lut_rev3[] = {
+-	0x02,
+-	0x04,
+-	0x14,
+-	0x14,
+-	0x03,
+-	0x05,
+-	0x16,
+-	0x16,
+-	0x0a,
+-	0x0c,
+-	0x1c,
+-	0x1c,
+-	0x0b,
+-	0x0d,
+-	0x1e,
+-	0x1e,
+-	0x06,
+-	0x08,
+-	0x18,
+-	0x18,
+-	0x07,
+-	0x09,
+-	0x1a,
+-	0x1a,
+-	0x0e,
+-	0x10,
+-	0x20,
+-	0x28,
+-	0x0f,
+-	0x11,
+-	0x22,
+-	0x2a,
+-};
+-
+-const u8 est_pwr_lut_core0_rev3[] = {
+-	0x55,
+-	0x54,
+-	0x54,
+-	0x53,
+-	0x52,
+-	0x52,
+-	0x51,
+-	0x51,
+-	0x50,
+-	0x4f,
+-	0x4f,
+-	0x4e,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x2f,
+-	0x2e,
+-	0x2c,
+-	0x2b,
+-	0x29,
+-	0x27,
+-	0x25,
+-	0x23,
+-	0x21,
+-	0x1f,
+-	0x1d,
+-	0x1a,
+-	0x18,
+-	0x15,
+-	0x12,
+-	0x0e,
+-	0x0b,
+-	0x07,
+-	0x02,
+-	0xfd,
+-};
+-
+-const u8 est_pwr_lut_core1_rev3[] = {
+-	0x55,
+-	0x54,
+-	0x54,
+-	0x53,
+-	0x52,
+-	0x52,
+-	0x51,
+-	0x51,
+-	0x50,
+-	0x4f,
+-	0x4f,
+-	0x4e,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x2f,
+-	0x2e,
+-	0x2c,
+-	0x2b,
+-	0x29,
+-	0x27,
+-	0x25,
+-	0x23,
+-	0x21,
+-	0x1f,
+-	0x1d,
+-	0x1a,
+-	0x18,
+-	0x15,
+-	0x12,
+-	0x0e,
+-	0x0b,
+-	0x07,
+-	0x02,
+-	0xfd,
+-};
+-
+-const u8 adj_pwr_lut_core0_rev3[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 adj_pwr_lut_core1_rev3[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 gainctrl_lut_core0_rev3[] = {
+-	0x5bf70044,
+-	0x5bf70042,
+-	0x5bf70040,
+-	0x5bf7003e,
+-	0x5bf7003c,
+-	0x5bf7003b,
+-	0x5bf70039,
+-	0x5bf70037,
+-	0x5bf70036,
+-	0x5bf70034,
+-	0x5bf70033,
+-	0x5bf70031,
+-	0x5bf70030,
+-	0x5ba70044,
+-	0x5ba70042,
+-	0x5ba70040,
+-	0x5ba7003e,
+-	0x5ba7003c,
+-	0x5ba7003b,
+-	0x5ba70039,
+-	0x5ba70037,
+-	0x5ba70036,
+-	0x5ba70034,
+-	0x5ba70033,
+-	0x5b770044,
+-	0x5b770042,
+-	0x5b770040,
+-	0x5b77003e,
+-	0x5b77003c,
+-	0x5b77003b,
+-	0x5b770039,
+-	0x5b770037,
+-	0x5b770036,
+-	0x5b770034,
+-	0x5b770033,
+-	0x5b770031,
+-	0x5b770030,
+-	0x5b77002f,
+-	0x5b77002d,
+-	0x5b77002c,
+-	0x5b470044,
+-	0x5b470042,
+-	0x5b470040,
+-	0x5b47003e,
+-	0x5b47003c,
+-	0x5b47003b,
+-	0x5b470039,
+-	0x5b470037,
+-	0x5b470036,
+-	0x5b470034,
+-	0x5b470033,
+-	0x5b470031,
+-	0x5b470030,
+-	0x5b47002f,
+-	0x5b47002d,
+-	0x5b47002c,
+-	0x5b47002b,
+-	0x5b47002a,
+-	0x5b270044,
+-	0x5b270042,
+-	0x5b270040,
+-	0x5b27003e,
+-	0x5b27003c,
+-	0x5b27003b,
+-	0x5b270039,
+-	0x5b270037,
+-	0x5b270036,
+-	0x5b270034,
+-	0x5b270033,
+-	0x5b270031,
+-	0x5b270030,
+-	0x5b27002f,
+-	0x5b170044,
+-	0x5b170042,
+-	0x5b170040,
+-	0x5b17003e,
+-	0x5b17003c,
+-	0x5b17003b,
+-	0x5b170039,
+-	0x5b170037,
+-	0x5b170036,
+-	0x5b170034,
+-	0x5b170033,
+-	0x5b170031,
+-	0x5b170030,
+-	0x5b17002f,
+-	0x5b17002d,
+-	0x5b17002c,
+-	0x5b17002b,
+-	0x5b17002a,
+-	0x5b170028,
+-	0x5b170027,
+-	0x5b170026,
+-	0x5b170025,
+-	0x5b170024,
+-	0x5b170023,
+-	0x5b070044,
+-	0x5b070042,
+-	0x5b070040,
+-	0x5b07003e,
+-	0x5b07003c,
+-	0x5b07003b,
+-	0x5b070039,
+-	0x5b070037,
+-	0x5b070036,
+-	0x5b070034,
+-	0x5b070033,
+-	0x5b070031,
+-	0x5b070030,
+-	0x5b07002f,
+-	0x5b07002d,
+-	0x5b07002c,
+-	0x5b07002b,
+-	0x5b07002a,
+-	0x5b070028,
+-	0x5b070027,
+-	0x5b070026,
+-	0x5b070025,
+-	0x5b070024,
+-	0x5b070023,
+-	0x5b070022,
+-	0x5b070021,
+-	0x5b070020,
+-	0x5b07001f,
+-	0x5b07001e,
+-	0x5b07001d,
+-	0x5b07001d,
+-	0x5b07001c,
+-};
+-
+-const u32 gainctrl_lut_core1_rev3[] = {
+-	0x5bf70044,
+-	0x5bf70042,
+-	0x5bf70040,
+-	0x5bf7003e,
+-	0x5bf7003c,
+-	0x5bf7003b,
+-	0x5bf70039,
+-	0x5bf70037,
+-	0x5bf70036,
+-	0x5bf70034,
+-	0x5bf70033,
+-	0x5bf70031,
+-	0x5bf70030,
+-	0x5ba70044,
+-	0x5ba70042,
+-	0x5ba70040,
+-	0x5ba7003e,
+-	0x5ba7003c,
+-	0x5ba7003b,
+-	0x5ba70039,
+-	0x5ba70037,
+-	0x5ba70036,
+-	0x5ba70034,
+-	0x5ba70033,
+-	0x5b770044,
+-	0x5b770042,
+-	0x5b770040,
+-	0x5b77003e,
+-	0x5b77003c,
+-	0x5b77003b,
+-	0x5b770039,
+-	0x5b770037,
+-	0x5b770036,
+-	0x5b770034,
+-	0x5b770033,
+-	0x5b770031,
+-	0x5b770030,
+-	0x5b77002f,
+-	0x5b77002d,
+-	0x5b77002c,
+-	0x5b470044,
+-	0x5b470042,
+-	0x5b470040,
+-	0x5b47003e,
+-	0x5b47003c,
+-	0x5b47003b,
+-	0x5b470039,
+-	0x5b470037,
+-	0x5b470036,
+-	0x5b470034,
+-	0x5b470033,
+-	0x5b470031,
+-	0x5b470030,
+-	0x5b47002f,
+-	0x5b47002d,
+-	0x5b47002c,
+-	0x5b47002b,
+-	0x5b47002a,
+-	0x5b270044,
+-	0x5b270042,
+-	0x5b270040,
+-	0x5b27003e,
+-	0x5b27003c,
+-	0x5b27003b,
+-	0x5b270039,
+-	0x5b270037,
+-	0x5b270036,
+-	0x5b270034,
+-	0x5b270033,
+-	0x5b270031,
+-	0x5b270030,
+-	0x5b27002f,
+-	0x5b170044,
+-	0x5b170042,
+-	0x5b170040,
+-	0x5b17003e,
+-	0x5b17003c,
+-	0x5b17003b,
+-	0x5b170039,
+-	0x5b170037,
+-	0x5b170036,
+-	0x5b170034,
+-	0x5b170033,
+-	0x5b170031,
+-	0x5b170030,
+-	0x5b17002f,
+-	0x5b17002d,
+-	0x5b17002c,
+-	0x5b17002b,
+-	0x5b17002a,
+-	0x5b170028,
+-	0x5b170027,
+-	0x5b170026,
+-	0x5b170025,
+-	0x5b170024,
+-	0x5b170023,
+-	0x5b070044,
+-	0x5b070042,
+-	0x5b070040,
+-	0x5b07003e,
+-	0x5b07003c,
+-	0x5b07003b,
+-	0x5b070039,
+-	0x5b070037,
+-	0x5b070036,
+-	0x5b070034,
+-	0x5b070033,
+-	0x5b070031,
+-	0x5b070030,
+-	0x5b07002f,
+-	0x5b07002d,
+-	0x5b07002c,
+-	0x5b07002b,
+-	0x5b07002a,
+-	0x5b070028,
+-	0x5b070027,
+-	0x5b070026,
+-	0x5b070025,
+-	0x5b070024,
+-	0x5b070023,
+-	0x5b070022,
+-	0x5b070021,
+-	0x5b070020,
+-	0x5b07001f,
+-	0x5b07001e,
+-	0x5b07001d,
+-	0x5b07001d,
+-	0x5b07001c,
+-};
+-
+-const u32 iq_lut_core0_rev3[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 iq_lut_core1_rev3[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 loft_lut_core0_rev3[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 loft_lut_core1_rev3[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-};
+-
+-const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
+-	0x00000000,
+-	0x00001fa0,
+-	0x00019f78,
+-	0x0001df7e,
+-	0x03fa9f86,
+-	0x03fd1f90,
+-	0x03fe5f8a,
+-	0x03fb1f94,
+-	0x03fd9fa0,
+-	0x00009f98,
+-	0x03fd1fac,
+-	0x03ff9fa2,
+-	0x03fe9fae,
+-	0x00001fae,
+-	0x03fddfb4,
+-	0x03ff1fb8,
+-	0x03ff9fbc,
+-	0x03ffdfbe,
+-	0x03fe9fc2,
+-	0x03fedfc6,
+-	0x03fedfc6,
+-	0x03ff9fc8,
+-	0x03ff5fc6,
+-	0x03fedfc2,
+-	0x03ff9fc0,
+-	0x03ff5fac,
+-	0x03ff5fac,
+-	0x03ff9fa2,
+-	0x03ff9fa6,
+-	0x03ff9faa,
+-	0x03ff5fb0,
+-	0x03ff5fb4,
+-	0x03ff1fca,
+-	0x03ff5fce,
+-	0x03fcdfdc,
+-	0x03fb4006,
+-	0x00000030,
+-	0x03ff808a,
+-	0x03ff80da,
+-	0x0000016c,
+-	0x03ff8318,
+-	0x03ff063a,
+-	0x03fd8bd6,
+-	0x00014ffe,
+-	0x00034ffe,
+-	0x00034ffe,
+-	0x0003cffe,
+-	0x00040ffe,
+-	0x00040ffe,
+-	0x0003cffe,
+-	0x0003cffe,
+-	0x00020ffe,
+-	0x03fe0ffe,
+-	0x03fdcffe,
+-	0x03f94ffe,
+-	0x03f54ffe,
+-	0x03f44ffe,
+-	0x03ef8ffe,
+-	0x03ee0ffe,
+-	0x03ebcffe,
+-	0x03e8cffe,
+-	0x03e74ffe,
+-	0x03e4cffe,
+-	0x03e38ffe,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core0_rev3[] = {
+-	0x05af005a,
+-	0x0571005e,
+-	0x05040066,
+-	0x04bd006c,
+-	0x047d0072,
+-	0x04430078,
+-	0x03f70081,
+-	0x03cb0087,
+-	0x03870091,
+-	0x035e0098,
+-	0x032e00a1,
+-	0x030300aa,
+-	0x02d800b4,
+-	0x02ae00bf,
+-	0x028900ca,
+-	0x026400d6,
+-	0x024100e3,
+-	0x022200f0,
+-	0x020200ff,
+-	0x01e5010e,
+-	0x01ca011e,
+-	0x01b0012f,
+-	0x01990140,
+-	0x01830153,
+-	0x016c0168,
+-	0x0158017d,
+-	0x01450193,
+-	0x013301ab,
+-	0x012101c5,
+-	0x011101e0,
+-	0x010201fc,
+-	0x00f4021a,
+-	0x00e6011d,
+-	0x00d9012e,
+-	0x00cd0140,
+-	0x00c20153,
+-	0x00b70167,
+-	0x00ac017c,
+-	0x00a30193,
+-	0x009a01ab,
+-	0x009101c4,
+-	0x008901df,
+-	0x008101fb,
+-	0x007a0219,
+-	0x00730239,
+-	0x006d025b,
+-	0x0067027e,
+-	0x006102a4,
+-	0x005c02cc,
+-	0x005602f6,
+-	0x00520323,
+-	0x004d0353,
+-	0x00490385,
+-	0x004503bb,
+-	0x004103f3,
+-	0x003d042f,
+-	0x003a046f,
+-	0x003704b2,
+-	0x003404f9,
+-	0x00310545,
+-	0x002e0596,
+-	0x002b05f5,
+-	0x00290640,
+-	0x002606a4,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
+-	0x00000000,
+-	0x00001fa0,
+-	0x00019f78,
+-	0x0001df7e,
+-	0x03fa9f86,
+-	0x03fd1f90,
+-	0x03fe5f8a,
+-	0x03fb1f94,
+-	0x03fd9fa0,
+-	0x00009f98,
+-	0x03fd1fac,
+-	0x03ff9fa2,
+-	0x03fe9fae,
+-	0x00001fae,
+-	0x03fddfb4,
+-	0x03ff1fb8,
+-	0x03ff9fbc,
+-	0x03ffdfbe,
+-	0x03fe9fc2,
+-	0x03fedfc6,
+-	0x03fedfc6,
+-	0x03ff9fc8,
+-	0x03ff5fc6,
+-	0x03fedfc2,
+-	0x03ff9fc0,
+-	0x03ff5fac,
+-	0x03ff5fac,
+-	0x03ff9fa2,
+-	0x03ff9fa6,
+-	0x03ff9faa,
+-	0x03ff5fb0,
+-	0x03ff5fb4,
+-	0x03ff1fca,
+-	0x03ff5fce,
+-	0x03fcdfdc,
+-	0x03fb4006,
+-	0x00000030,
+-	0x03ff808a,
+-	0x03ff80da,
+-	0x0000016c,
+-	0x03ff8318,
+-	0x03ff063a,
+-	0x03fd8bd6,
+-	0x00014ffe,
+-	0x00034ffe,
+-	0x00034ffe,
+-	0x0003cffe,
+-	0x00040ffe,
+-	0x00040ffe,
+-	0x0003cffe,
+-	0x0003cffe,
+-	0x00020ffe,
+-	0x03fe0ffe,
+-	0x03fdcffe,
+-	0x03f94ffe,
+-	0x03f54ffe,
+-	0x03f44ffe,
+-	0x03ef8ffe,
+-	0x03ee0ffe,
+-	0x03ebcffe,
+-	0x03e8cffe,
+-	0x03e74ffe,
+-	0x03e4cffe,
+-	0x03e38ffe,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core1_rev3[] = {
+-	0x05af005a,
+-	0x0571005e,
+-	0x05040066,
+-	0x04bd006c,
+-	0x047d0072,
+-	0x04430078,
+-	0x03f70081,
+-	0x03cb0087,
+-	0x03870091,
+-	0x035e0098,
+-	0x032e00a1,
+-	0x030300aa,
+-	0x02d800b4,
+-	0x02ae00bf,
+-	0x028900ca,
+-	0x026400d6,
+-	0x024100e3,
+-	0x022200f0,
+-	0x020200ff,
+-	0x01e5010e,
+-	0x01ca011e,
+-	0x01b0012f,
+-	0x01990140,
+-	0x01830153,
+-	0x016c0168,
+-	0x0158017d,
+-	0x01450193,
+-	0x013301ab,
+-	0x012101c5,
+-	0x011101e0,
+-	0x010201fc,
+-	0x00f4021a,
+-	0x00e6011d,
+-	0x00d9012e,
+-	0x00cd0140,
+-	0x00c20153,
+-	0x00b70167,
+-	0x00ac017c,
+-	0x00a30193,
+-	0x009a01ab,
+-	0x009101c4,
+-	0x008901df,
+-	0x008101fb,
+-	0x007a0219,
+-	0x00730239,
+-	0x006d025b,
+-	0x0067027e,
+-	0x006102a4,
+-	0x005c02cc,
+-	0x005602f6,
+-	0x00520323,
+-	0x004d0353,
+-	0x00490385,
+-	0x004503bb,
+-	0x004103f3,
+-	0x003d042f,
+-	0x003a046f,
+-	0x003704b2,
+-	0x003404f9,
+-	0x00310545,
+-	0x002e0596,
+-	0x002b05f5,
+-	0x00290640,
+-	0x002606a4,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile[] = {
+-	{&ant_swctrl_tbl_rev3,
+-	 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = {
+-	{&ant_swctrl_tbl_rev3_1,
+-	 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = {
+-	{&ant_swctrl_tbl_rev3_2,
+-	 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = {
+-	{&ant_swctrl_tbl_rev3_3,
+-	 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3[] = {
+-	{&frame_struct_rev3,
+-	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+-	,
+-	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+-	 11, 0, 16}
+-	,
+-	{&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
+-	 0, 32}
+-	,
+-	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+-	 13, 0, 32}
+-	,
+-	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+-	 14, 0, 32}
+-	,
+-	{&noise_var_tbl_rev3,
+-	 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
+-	,
+-	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+-	 16}
+-	,
+-	{&tdi_tbl20_ant0_rev3,
+-	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev3,
+-	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev3,
+-	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev3,
+-	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+-	 32}
+-	,
+-	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+-	 20, 0, 32}
+-	,
+-	{&chanest_tbl_rev3,
+-	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+-	,
+-	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+-	 24, 0, 8}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-};
+-
+-const u32 mimophytbl_info_sz_rev3 =
+-    sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile =
+-    sizeof(mimophytbl_info_rev3_volatile) /
+-    sizeof(mimophytbl_info_rev3_volatile[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile1 =
+-    sizeof(mimophytbl_info_rev3_volatile1) /
+-    sizeof(mimophytbl_info_rev3_volatile1[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile2 =
+-    sizeof(mimophytbl_info_rev3_volatile2) /
+-    sizeof(mimophytbl_info_rev3_volatile2[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile3 =
+-    sizeof(mimophytbl_info_rev3_volatile3) /
+-    sizeof(mimophytbl_info_rev3_volatile3[0]);
+-
+-const u32 tmap_tbl_rev7[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 noise_var_tbl_rev7[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00016023,
+-	0x00006028,
+-	0x00034036,
+-	0x0003402e,
+-	0x0007203c,
+-	0x0006e037,
+-	0x00070030,
+-	0x0009401f,
+-	0x0009a00f,
+-	0x000b600d,
+-	0x000c8007,
+-	0x000ce007,
+-	0x00101fff,
+-	0x00121ff9,
+-	0x0012e004,
+-	0x0014dffc,
+-	0x0016dff6,
+-	0x0018dfe9,
+-	0x001b3fe5,
+-	0x001c5fd0,
+-	0x001ddfc2,
+-	0x001f1fb6,
+-	0x00207fa4,
+-	0x00219f8f,
+-	0x0022ff7d,
+-	0x00247f6c,
+-	0x0024df5b,
+-	0x00267f4b,
+-	0x0027df3b,
+-	0x0029bf3b,
+-	0x002b5f2f,
+-	0x002d3f2e,
+-	0x002f5f2a,
+-	0x002fff15,
+-	0x00315f0b,
+-	0x0032defa,
+-	0x0033beeb,
+-	0x0034fed9,
+-	0x00353ec5,
+-	0x00361eb0,
+-	0x00363e9b,
+-	0x0036be87,
+-	0x0036be70,
+-	0x0038fe67,
+-	0x0044beb2,
+-	0x00513ef3,
+-	0x00595f11,
+-	0x00669f3d,
+-	0x0078dfdf,
+-	0x00a143aa,
+-	0x01642fff,
+-	0x0162afff,
+-	0x01620fff,
+-	0x0160cfff,
+-	0x015f0fff,
+-	0x015dafff,
+-	0x015bcfff,
+-	0x015bcfff,
+-	0x015b4fff,
+-	0x015acfff,
+-	0x01590fff,
+-	0x0156cfff,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core0_rev7[] = {
+-	0x0b5e002d,
+-	0x0ae2002f,
+-	0x0a3b0032,
+-	0x09a70035,
+-	0x09220038,
+-	0x08ab003b,
+-	0x081f003f,
+-	0x07a20043,
+-	0x07340047,
+-	0x06d2004b,
+-	0x067a004f,
+-	0x06170054,
+-	0x05bf0059,
+-	0x0571005e,
+-	0x051e0064,
+-	0x04d3006a,
+-	0x04910070,
+-	0x044c0077,
+-	0x040f007e,
+-	0x03d90085,
+-	0x03a1008d,
+-	0x036f0095,
+-	0x033d009e,
+-	0x030b00a8,
+-	0x02e000b2,
+-	0x02b900bc,
+-	0x029200c7,
+-	0x026d00d3,
+-	0x024900e0,
+-	0x022900ed,
+-	0x020a00fb,
+-	0x01ec010a,
+-	0x01d20119,
+-	0x01b7012a,
+-	0x019e013c,
+-	0x0188014e,
+-	0x01720162,
+-	0x015d0177,
+-	0x0149018e,
+-	0x013701a5,
+-	0x012601be,
+-	0x011501d8,
+-	0x010601f4,
+-	0x00f70212,
+-	0x00e90231,
+-	0x00dc0253,
+-	0x00d00276,
+-	0x00c4029b,
+-	0x00b902c3,
+-	0x00af02ed,
+-	0x00a50319,
+-	0x009c0348,
+-	0x0093037a,
+-	0x008b03af,
+-	0x008303e6,
+-	0x007c0422,
+-	0x00750460,
+-	0x006e04a3,
+-	0x006804e9,
+-	0x00620533,
+-	0x005d0582,
+-	0x005805d6,
+-	0x0053062e,
+-	0x004e068c,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00016023,
+-	0x00006028,
+-	0x00034036,
+-	0x0003402e,
+-	0x0007203c,
+-	0x0006e037,
+-	0x00070030,
+-	0x0009401f,
+-	0x0009a00f,
+-	0x000b600d,
+-	0x000c8007,
+-	0x000ce007,
+-	0x00101fff,
+-	0x00121ff9,
+-	0x0012e004,
+-	0x0014dffc,
+-	0x0016dff6,
+-	0x0018dfe9,
+-	0x001b3fe5,
+-	0x001c5fd0,
+-	0x001ddfc2,
+-	0x001f1fb6,
+-	0x00207fa4,
+-	0x00219f8f,
+-	0x0022ff7d,
+-	0x00247f6c,
+-	0x0024df5b,
+-	0x00267f4b,
+-	0x0027df3b,
+-	0x0029bf3b,
+-	0x002b5f2f,
+-	0x002d3f2e,
+-	0x002f5f2a,
+-	0x002fff15,
+-	0x00315f0b,
+-	0x0032defa,
+-	0x0033beeb,
+-	0x0034fed9,
+-	0x00353ec5,
+-	0x00361eb0,
+-	0x00363e9b,
+-	0x0036be87,
+-	0x0036be70,
+-	0x0038fe67,
+-	0x0044beb2,
+-	0x00513ef3,
+-	0x00595f11,
+-	0x00669f3d,
+-	0x0078dfdf,
+-	0x00a143aa,
+-	0x01642fff,
+-	0x0162afff,
+-	0x01620fff,
+-	0x0160cfff,
+-	0x015f0fff,
+-	0x015dafff,
+-	0x015bcfff,
+-	0x015bcfff,
+-	0x015b4fff,
+-	0x015acfff,
+-	0x01590fff,
+-	0x0156cfff,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core1_rev7[] = {
+-	0x0b5e002d,
+-	0x0ae2002f,
+-	0x0a3b0032,
+-	0x09a70035,
+-	0x09220038,
+-	0x08ab003b,
+-	0x081f003f,
+-	0x07a20043,
+-	0x07340047,
+-	0x06d2004b,
+-	0x067a004f,
+-	0x06170054,
+-	0x05bf0059,
+-	0x0571005e,
+-	0x051e0064,
+-	0x04d3006a,
+-	0x04910070,
+-	0x044c0077,
+-	0x040f007e,
+-	0x03d90085,
+-	0x03a1008d,
+-	0x036f0095,
+-	0x033d009e,
+-	0x030b00a8,
+-	0x02e000b2,
+-	0x02b900bc,
+-	0x029200c7,
+-	0x026d00d3,
+-	0x024900e0,
+-	0x022900ed,
+-	0x020a00fb,
+-	0x01ec010a,
+-	0x01d20119,
+-	0x01b7012a,
+-	0x019e013c,
+-	0x0188014e,
+-	0x01720162,
+-	0x015d0177,
+-	0x0149018e,
+-	0x013701a5,
+-	0x012601be,
+-	0x011501d8,
+-	0x010601f4,
+-	0x00f70212,
+-	0x00e90231,
+-	0x00dc0253,
+-	0x00d00276,
+-	0x00c4029b,
+-	0x00b902c3,
+-	0x00af02ed,
+-	0x00a50319,
+-	0x009c0348,
+-	0x0093037a,
+-	0x008b03af,
+-	0x008303e6,
+-	0x007c0422,
+-	0x00750460,
+-	0x006e04a3,
+-	0x006804e9,
+-	0x00620533,
+-	0x005d0582,
+-	0x005805d6,
+-	0x0053062e,
+-	0x004e068c,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev7[] = {
+-	{&frame_struct_rev3,
+-	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+-	,
+-	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+-	 11, 0, 16}
+-	,
+-	{&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
+-	 0, 32}
+-	,
+-	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+-	 13, 0, 32}
+-	,
+-	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+-	 14, 0, 32}
+-	,
+-	{&noise_var_tbl_rev7,
+-	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+-	,
+-	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+-	 16}
+-	,
+-	{&tdi_tbl20_ant0_rev3,
+-	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev3,
+-	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev3,
+-	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev3,
+-	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+-	 32}
+-	,
+-	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+-	 20, 0, 32}
+-	,
+-	{&chanest_tbl_rev3,
+-	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+-	,
+-	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+-	 24, 0, 8}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-	,
+-	{&papd_comp_rfpwr_tbl_core0_rev3,
+-	 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
+-	 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
+-	,
+-	{&papd_comp_rfpwr_tbl_core1_rev3,
+-	 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
+-	 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
+-	,
+-	{&papd_comp_epsilon_tbl_core0_rev7,
+-	 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
+-	 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
+-	,
+-	{&papd_cal_scalars_tbl_core0_rev7,
+-	 sizeof(papd_cal_scalars_tbl_core0_rev7) /
+-	 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
+-	,
+-	{&papd_comp_epsilon_tbl_core1_rev7,
+-	 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
+-	 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
+-	,
+-	{&papd_cal_scalars_tbl_core1_rev7,
+-	 sizeof(papd_cal_scalars_tbl_core1_rev7) /
+-	 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev7 =
+-    sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
+-
+-const mimophytbl_info_t mimophytbl_info_rev16[] = {
+-	{&noise_var_tbl_rev7,
+-	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev16 =
+-    sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
+deleted file mode 100644
+index 396122f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
++++ /dev/null
+@@ -1,39 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define ANT_SWCTRL_TBL_REV3_IDX (0)
+-
+-typedef phytbl_info_t mimophytbl_info_t;
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev0[],
+-    mimophytbl_info_rev0_volatile[];
+-extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile;
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev3[],
+-    mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[],
+-    mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[];
+-extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile,
+-    mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2,
+-    mimophytbl_info_sz_rev3_volatile3;
+-
+-extern const u32 noise_var_tbl_rev3[];
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev7[];
+-extern const u32 mimophytbl_info_sz_rev7;
+-extern const u32 noise_var_tbl_rev7[];
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev16[];
+-extern const u32 mimophytbl_info_sz_rev16;
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h
+deleted file mode 100644
+index 5582de3..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h
++++ /dev/null
+@@ -1,92 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_dbg_h_
+-#define _wl_dbg_h_
+-
+-#include <linux/device.h>			/* dev_err() */
+-
+-/* wl_msg_level is a bit vector with defs in wlioctl.h */
+-extern u32 wl_msg_level;
+-
+-#define BCMMSG(dev, fmt, args...)		\
+-do {						\
+-	if (wl_msg_level & WL_TRACE_VAL)	\
+-		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
+-} while (0)
+-
+-#ifdef BCMDBG
+-
+-
+-/* Extra message control for AMPDU debugging */
+-#define   WL_AMPDU_UPDN_VAL	0x00000001	/* Config up/down related  */
+-#define   WL_AMPDU_ERR_VAL	0x00000002	/* Calls to beaocn update  */
+-#define   WL_AMPDU_TX_VAL	0x00000004	/* Transmit data path */
+-#define   WL_AMPDU_RX_VAL	0x00000008	/* Receive data path  */
+-#define   WL_AMPDU_CTL_VAL	0x00000010	/* TSF-related items  */
+-#define   WL_AMPDU_HW_VAL       0x00000020	/* AMPDU_HW */
+-#define   WL_AMPDU_HWTXS_VAL    0x00000040	/* AMPDU_HWTXS */
+-#define   WL_AMPDU_HWDBG_VAL    0x00000080	/* AMPDU_DBG */
+-
+-extern u32 wl_ampdu_dbg;
+-
+-#define WL_AMPDU_PRINT(level, fmt, args...)	\
+-do {						\
+-	if (wl_ampdu_dbg & level) {		\
+-		WL_AMPDU(fmt, ##args);		\
+-	}					\
+-} while (0)
+-
+-#define WL_AMPDU_UPDN(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args)
+-#define WL_AMPDU_RX(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args)
+-#define WL_AMPDU_ERR(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args)
+-#define WL_AMPDU_TX(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args)
+-#define WL_AMPDU_CTL(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args)
+-#define WL_AMPDU_HW(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args)
+-#define WL_AMPDU_HWTXS(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args)
+-#define WL_AMPDU_HWDBG(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args)
+-#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL)
+-#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL)
+-#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL)
+-
+-#else				/* BCMDBG */
+-
+-
+-#define WL_AMPDU_UPDN(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_RX(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_ERR(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_TX(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_CTL(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HW(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HWTXS(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HWDBG(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_ERR_ON()       0
+-#define WL_AMPDU_HW_ON()        0
+-#define WL_AMPDU_HWTXS_ON()     0
+-
+-#endif				/* BCMDBG */
+-
+-#define WL_ERROR_ON()		(wl_msg_level & WL_ERROR_VAL)
+-
+-#endif				/* _wl_dbg_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h
+deleted file mode 100644
+index 0fe0b24..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_export.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_export_h_
+-#define _wl_export_h_
+-
+-/* misc callbacks */
+-struct wl_info;
+-struct wl_if;
+-struct wlc_if;
+-extern void wl_init(struct wl_info *wl);
+-extern uint wl_reset(struct wl_info *wl);
+-extern void wl_intrson(struct wl_info *wl);
+-extern u32 wl_intrsoff(struct wl_info *wl);
+-extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask);
+-extern int wl_up(struct wl_info *wl);
+-extern void wl_down(struct wl_info *wl);
+-extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+-			     int prio);
+-extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth);
+-extern bool wl_rfkill_set_hw_state(struct wl_info *wl);
+-
+-/* timer functions */
+-struct wl_timer;
+-extern struct wl_timer *wl_init_timer(struct wl_info *wl,
+-				      void (*fn) (void *arg), void *arg,
+-				      const char *name);
+-extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer);
+-extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
+-			 int periodic);
+-extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
+-extern void wl_msleep(struct wl_info *wl, uint ms);
+-
+-#endif				/* _wl_export_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+deleted file mode 100644
+index aa0d127..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
++++ /dev/null
+@@ -1,1942 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define __UNDEF_NO_VERSION__
+-
+-#include <linux/kernel.h>
+-#include <linux/etherdevice.h>
+-#include <linux/types.h>
+-#include <linux/pci_ids.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/sched.h>
+-#include <linux/firmware.h>
+-#include <net/mac80211.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmwifi.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <pcicfg.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "phy/wlc_phy_int.h"
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "phy/phy_version.h"
+-#include "wlc_key.h"
+-#include "wlc_channel.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wl_dbg.h"
+-#include "wl_export.h"
+-#include "wl_ucode.h"
+-#include "wl_mac80211.h"
+-
+-#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
+-
+-static void wl_timer(unsigned long data);
+-static void _wl_timer(struct wl_timer *t);
+-
+-
+-static int ieee_hw_init(struct ieee80211_hw *hw);
+-static int ieee_hw_rate_init(struct ieee80211_hw *hw);
+-
+-static int wl_linux_watchdog(void *ctx);
+-
+-/* Flags we support */
+-#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
+-	FIF_ALLMULTI | \
+-	FIF_FCSFAIL | \
+-	FIF_PLCPFAIL | \
+-	FIF_CONTROL | \
+-	FIF_OTHER_BSS | \
+-	FIF_BCN_PRBRESP_PROMISC)
+-
+-static int wl_found;
+-
+-#define WL_DEV_IF(dev)		((struct wl_if *)netdev_priv(dev))
+-#define	WL_INFO(dev)		((struct wl_info *)(WL_DEV_IF(dev)->wl))
+-static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev);
+-static void wl_release_fw(struct wl_info *wl);
+-
+-/* local prototypes */
+-static void wl_dpc(unsigned long data);
+-static irqreturn_t wl_isr(int irq, void *dev_id);
+-
+-static int __devinit wl_pci_probe(struct pci_dev *pdev,
+-				  const struct pci_device_id *ent);
+-static void wl_remove(struct pci_dev *pdev);
+-static void wl_free(struct wl_info *wl);
+-static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br);
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-/* recognized PCI IDs */
+-static struct pci_device_id wl_id_table[] = {
+-	{PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 43225 2G */
+-	{PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 43224 DUAL */
+-	{PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 4313 DUAL */
+-	{0}
+-};
+-
+-MODULE_DEVICE_TABLE(pci, wl_id_table);
+-
+-#ifdef BCMDBG
+-static int msglevel = 0xdeadbeef;
+-module_param(msglevel, int, 0);
+-static int phymsglevel = 0xdeadbeef;
+-module_param(phymsglevel, int, 0);
+-#endif				/* BCMDBG */
+-
+-#define HW_TO_WL(hw)	 (hw->priv)
+-#define WL_TO_HW(wl)	  (wl->pub->ieee_hw)
+-
+-/* MAC80211 callback functions */
+-static int wl_ops_start(struct ieee80211_hw *hw);
+-static void wl_ops_stop(struct ieee80211_hw *hw);
+-static int wl_ops_add_interface(struct ieee80211_hw *hw,
+-				struct ieee80211_vif *vif);
+-static void wl_ops_remove_interface(struct ieee80211_hw *hw,
+-				    struct ieee80211_vif *vif);
+-static int wl_ops_config(struct ieee80211_hw *hw, u32 changed);
+-static void wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+-				    struct ieee80211_vif *vif,
+-				    struct ieee80211_bss_conf *info,
+-				    u32 changed);
+-static void wl_ops_configure_filter(struct ieee80211_hw *hw,
+-				    unsigned int changed_flags,
+-				    unsigned int *total_flags, u64 multicast);
+-static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+-			  bool set);
+-static void wl_ops_sw_scan_start(struct ieee80211_hw *hw);
+-static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw);
+-static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
+-static int wl_ops_get_stats(struct ieee80211_hw *hw,
+-			    struct ieee80211_low_level_stats *stats);
+-static void wl_ops_sta_notify(struct ieee80211_hw *hw,
+-			      struct ieee80211_vif *vif,
+-			      enum sta_notify_cmd cmd,
+-			      struct ieee80211_sta *sta);
+-static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+-			  const struct ieee80211_tx_queue_params *params);
+-static u64 wl_ops_get_tsf(struct ieee80211_hw *hw);
+-static int wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		      struct ieee80211_sta *sta);
+-static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-			 struct ieee80211_sta *sta);
+-static int wl_ops_ampdu_action(struct ieee80211_hw *hw,
+-			       struct ieee80211_vif *vif,
+-			       enum ieee80211_ampdu_mlme_action action,
+-			       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-			       u8 buf_size);
+-static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
+-static void wl_ops_flush(struct ieee80211_hw *hw, bool drop);
+-
+-static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+-{
+-	struct wl_info *wl = hw->priv;
+-
+-	WL_LOCK(wl);
+-	if (!wl->pub->up) {
+-		wiphy_err(wl->wiphy, "ops->tx called while down\n");
+-		kfree_skb(skb);
+-		goto done;
+-	}
+-	wlc_sendpkt_mac80211(wl->wlc, skb, hw);
+- done:
+-	WL_UNLOCK(wl);
+-}
+-
+-static int wl_ops_start(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	bool blocked;
+-	/*
+-	  struct ieee80211_channel *curchan = hw->conf.channel;
+-	*/
+-
+-	ieee80211_wake_queues(hw);
+-	WL_LOCK(wl);
+-	blocked = wl_rfkill_set_hw_state(wl);
+-	WL_UNLOCK(wl);
+-	if (!blocked)
+-		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
+-
+-	return 0;
+-}
+-
+-static void wl_ops_stop(struct ieee80211_hw *hw)
+-{
+-	ieee80211_stop_queues(hw);
+-}
+-
+-static int
+-wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+-{
+-	struct wl_info *wl;
+-	int err;
+-
+-	/* Just STA for now */
+-	if (vif->type != NL80211_IFTYPE_AP &&
+-	    vif->type != NL80211_IFTYPE_MESH_POINT &&
+-	    vif->type != NL80211_IFTYPE_STATION &&
+-	    vif->type != NL80211_IFTYPE_WDS &&
+-	    vif->type != NL80211_IFTYPE_ADHOC) {
+-		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
+-			  " STA for now\n", __func__, vif->type);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	wl = HW_TO_WL(hw);
+-	WL_LOCK(wl);
+-	err = wl_up(wl);
+-	WL_UNLOCK(wl);
+-
+-	if (err != 0) {
+-		wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__,
+-			  err);
+-	}
+-	return err;
+-}
+-
+-static void
+-wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+-{
+-	struct wl_info *wl;
+-
+-	wl = HW_TO_WL(hw);
+-
+-	/* put driver in down state */
+-	WL_LOCK(wl);
+-	wl_down(wl);
+-	WL_UNLOCK(wl);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-static int
+-ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
+-		 enum nl80211_channel_type type)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int err = 0;
+-
+-	switch (type) {
+-	case NL80211_CHAN_HT20:
+-	case NL80211_CHAN_NO_HT:
+-		err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
+-		break;
+-	case NL80211_CHAN_HT40MINUS:
+-	case NL80211_CHAN_HT40PLUS:
+-		wiphy_err(hw->wiphy,
+-			  "%s: Need to implement 40 Mhz Channels!\n", __func__);
+-		err = 1;
+-		break;
+-	}
+-
+-	if (err)
+-		return -EIO;
+-	return err;
+-}
+-
+-static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
+-{
+-	struct ieee80211_conf *conf = &hw->conf;
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int err = 0;
+-	int new_int;
+-	struct wiphy *wiphy = hw->wiphy;
+-
+-	WL_LOCK(wl);
+-	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+-		if (wlc_iovar_setint
+-		    (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
+-			wiphy_err(wiphy, "%s: Error setting listen_interval\n",
+-				  __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
+-		wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
+-			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
+-			  "true" : "false");
+-	if (changed & IEEE80211_CONF_CHANGE_PS)
+-		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
+-			  __func__, conf->flags & IEEE80211_CONF_PS ?
+-			  "true" : "false");
+-
+-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+-		if (wlc_iovar_setint
+-		    (wl->wlc, "qtxpower", conf->power_level * 4)) {
+-			wiphy_err(wiphy, "%s: Error setting power_level\n",
+-				  __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
+-		if (new_int != (conf->power_level * 4))
+-			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
+-				  "\n", __func__, conf->power_level * 4,
+-				  new_int);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+-		err = ieee_set_channel(hw, conf->channel, conf->channel_type);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+-		if (wlc_set
+-		    (wl->wlc, WLC_SET_SRL,
+-		     conf->short_frame_max_tx_count) < 0) {
+-			wiphy_err(wiphy, "%s: Error setting srl\n", __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
+-		    < 0) {
+-			wiphy_err(wiphy, "%s: Error setting lrl\n", __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-	}
+-
+- config_out:
+-	WL_UNLOCK(wl);
+-	return err;
+-}
+-
+-static void
+-wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+-			struct ieee80211_vif *vif,
+-			struct ieee80211_bss_conf *info, u32 changed)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	struct wiphy *wiphy = hw->wiphy;
+-	int val;
+-
+-	if (changed & BSS_CHANGED_ASSOC) {
+-		/* association status changed (associated/disassociated)
+-		 * also implies a change in the AID.
+-		 */
+-		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
+-			  __func__, info->assoc ? "" : "dis");
+-		WL_LOCK(wl);
+-		wlc_associate_upd(wl->wlc, info->assoc);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_ERP_SLOT) {
+-		/* slot timing changed */
+-		if (info->use_short_slot)
+-			val = 1;
+-		else
+-			val = 0;
+-		WL_LOCK(wl);
+-		wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
+-		WL_UNLOCK(wl);
+-	}
+-
+-	if (changed & BSS_CHANGED_HT) {
+-		/* 802.11n parameters changed */
+-		u16 mode = info->ht_operation_mode;
+-
+-		WL_LOCK(wl);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG,
+-			mode & IEEE80211_HT_OP_MODE_PROTECTION);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF,
+-			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS,
+-			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BASIC_RATES) {
+-		struct ieee80211_supported_band *bi;
+-		u32 br_mask, i;
+-		u16 rate;
+-		struct wl_rateset rs;
+-		int error;
+-
+-		/* retrieve the current rates */
+-		WL_LOCK(wl);
+-		error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET,
+-				  &rs, sizeof(rs), NULL);
+-		WL_UNLOCK(wl);
+-		if (error) {
+-			wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n",
+-				  __func__, error);
+-			return;
+-		}
+-		br_mask = info->basic_rates;
+-		bi = hw->wiphy->bands[wlc_get_curband(wl->wlc)];
+-		for (i = 0; i < bi->n_bitrates; i++) {
+-			/* convert to internal rate value */
+-			rate = (bi->bitrates[i].bitrate << 1) / 10;
+-
+-			/* set/clear basic rate flag */
+-			wl_set_basic_rate(&rs, rate, br_mask & 1);
+-			br_mask >>= 1;
+-		}
+-
+-		/* update the rate set */
+-		WL_LOCK(wl);
+-		wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BEACON_INT) {
+-		/* Beacon interval changed */
+-		WL_LOCK(wl);
+-		wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BSSID) {
+-		/* BSSID changed, for whatever reason (IBSS and managed mode) */
+-		WL_LOCK(wl);
+-		wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
+-				  info->bssid);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BEACON) {
+-		/* Beacon data changed, retrieve new beacon (beaconing modes) */
+-		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
+-	}
+-	if (changed & BSS_CHANGED_BEACON_ENABLED) {
+-		/* Beaconing should be enabled/disabled (beaconing modes) */
+-		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
+-			  info->enable_beacon ? "true" : "false");
+-	}
+-	if (changed & BSS_CHANGED_CQM) {
+-		/* Connection quality monitor config changed */
+-		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
+-			  " (implement)\n", __func__, info->cqm_rssi_thold,
+-			  info->cqm_rssi_hyst);
+-	}
+-	if (changed & BSS_CHANGED_IBSS) {
+-		/* IBSS join status changed */
+-		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
+-			  info->ibss_joined ? "true" : "false");
+-	}
+-	if (changed & BSS_CHANGED_ARP_FILTER) {
+-		/* Hardware ARP filter address list or state changed */
+-		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
+-			  " (implement)\n", __func__, info->arp_filter_enabled ?
+-			  "true" : "false", info->arp_addr_cnt);
+-	}
+-	if (changed & BSS_CHANGED_QOS) {
+-		/*
+-		 * QoS for this association was enabled/disabled.
+-		 * Note that it is only ever disabled for station mode.
+-		 */
+-		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
+-			  info->qos ? "true" : "false");
+-	}
+-	return;
+-}
+-
+-static void
+-wl_ops_configure_filter(struct ieee80211_hw *hw,
+-			unsigned int changed_flags,
+-			unsigned int *total_flags, u64 multicast)
+-{
+-	struct wl_info *wl = hw->priv;
+-	struct wiphy *wiphy = hw->wiphy;
+-
+-	changed_flags &= MAC_FILTERS;
+-	*total_flags &= MAC_FILTERS;
+-	if (changed_flags & FIF_PROMISC_IN_BSS)
+-		wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
+-	if (changed_flags & FIF_ALLMULTI)
+-		wiphy_err(wiphy, "FIF_ALLMULTI\n");
+-	if (changed_flags & FIF_FCSFAIL)
+-		wiphy_err(wiphy, "FIF_FCSFAIL\n");
+-	if (changed_flags & FIF_PLCPFAIL)
+-		wiphy_err(wiphy, "FIF_PLCPFAIL\n");
+-	if (changed_flags & FIF_CONTROL)
+-		wiphy_err(wiphy, "FIF_CONTROL\n");
+-	if (changed_flags & FIF_OTHER_BSS)
+-		wiphy_err(wiphy, "FIF_OTHER_BSS\n");
+-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+-		WL_LOCK(wl);
+-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
+-			wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
+-			wlc_mac_bcn_promisc_change(wl->wlc, 1);
+-		} else {
+-			wlc_mac_bcn_promisc_change(wl->wlc, 0);
+-			wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
+-		}
+-		WL_UNLOCK(wl);
+-	}
+-	return;
+-}
+-
+-static int
+-wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+-{
+-	return 0;
+-}
+-
+-static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	WL_LOCK(wl);
+-	wlc_scan_start(wl->wlc);
+-	WL_UNLOCK(wl);
+-	return;
+-}
+-
+-static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	WL_LOCK(wl);
+-	wlc_scan_stop(wl->wlc);
+-	WL_UNLOCK(wl);
+-	return;
+-}
+-
+-static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+-{
+-	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
+-	return;
+-}
+-
+-static int
+-wl_ops_get_stats(struct ieee80211_hw *hw,
+-		 struct ieee80211_low_level_stats *stats)
+-{
+-	struct wl_info *wl = hw->priv;
+-	struct wl_cnt *cnt;
+-
+-	WL_LOCK(wl);
+-	cnt = wl->pub->_cnt;
+-	stats->dot11ACKFailureCount = 0;
+-	stats->dot11RTSFailureCount = 0;
+-	stats->dot11FCSErrorCount = 0;
+-	stats->dot11RTSSuccessCount = 0;
+-	WL_UNLOCK(wl);
+-	return 0;
+-}
+-
+-static void
+-wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		  enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
+-{
+-	switch (cmd) {
+-	default:
+-		wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__,
+-			  cmd);
+-		break;
+-	}
+-	return;
+-}
+-
+-static int
+-wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+-	       const struct ieee80211_tx_queue_params *params)
+-{
+-	struct wl_info *wl = hw->priv;
+-
+-	WL_LOCK(wl);
+-	wlc_wme_setparams(wl->wlc, queue, params, true);
+-	WL_UNLOCK(wl);
+-
+-	return 0;
+-}
+-
+-static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
+-{
+-	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
+-	return 0;
+-}
+-
+-static int
+-wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-	       struct ieee80211_sta *sta)
+-{
+-	struct scb *scb;
+-
+-	int i;
+-	struct wl_info *wl = hw->priv;
+-
+-	/* Init the scb */
+-	scb = (struct scb *)sta->drv_priv;
+-	memset(scb, 0, sizeof(struct scb));
+-	for (i = 0; i < NUMPRIO; i++)
+-		scb->seqctl[i] = 0xFFFF;
+-	scb->seqctl_nonqos = 0xFFFF;
+-	scb->magic = SCB_MAGIC;
+-
+-	wl->pub->global_scb = scb;
+-	wl->pub->global_ampdu = &(scb->scb_ampdu);
+-	wl->pub->global_ampdu->scb = scb;
+-	wl->pub->global_ampdu->max_pdu = 16;
+-	bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
+-		  AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
+-
+-	sta->ht_cap.ht_supported = true;
+-	sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+-	sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
+-	sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
+-	    IEEE80211_HT_CAP_SGI_20 |
+-	    IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+-
+-	/* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
+-	return 0;
+-}
+-
+-static int
+-wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		  struct ieee80211_sta *sta)
+-{
+-	return 0;
+-}
+-
+-static int
+-wl_ops_ampdu_action(struct ieee80211_hw *hw,
+-		    struct ieee80211_vif *vif,
+-		    enum ieee80211_ampdu_mlme_action action,
+-		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-		    u8 buf_size)
+-{
+-	struct scb *scb = (struct scb *)sta->drv_priv;
+-	struct wl_info *wl = hw->priv;
+-	int status;
+-
+-	if (WARN_ON(scb->magic != SCB_MAGIC))
+-		return -EIDRM;
+-	switch (action) {
+-	case IEEE80211_AMPDU_RX_START:
+-		break;
+-	case IEEE80211_AMPDU_RX_STOP:
+-		break;
+-	case IEEE80211_AMPDU_TX_START:
+-		WL_LOCK(wl);
+-		status = wlc_aggregatable(wl->wlc, tid);
+-		WL_UNLOCK(wl);
+-		if (!status) {
+-			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
+-				  tid);
+-			return -EINVAL;
+-		}
+-		/* XXX: Use the starting sequence number provided ... */
+-		*ssn = 0;
+-		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+-		break;
+-
+-	case IEEE80211_AMPDU_TX_STOP:
+-		WL_LOCK(wl);
+-		wlc_ampdu_flush(wl->wlc, sta, tid);
+-		WL_UNLOCK(wl);
+-		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+-		break;
+-	case IEEE80211_AMPDU_TX_OPERATIONAL:
+-		/* Not sure what to do here */
+-		/* Power save wakeup */
+-		break;
+-	default:
+-		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
+-			  __func__);
+-	}
+-
+-	return 0;
+-}
+-
+-static void wl_ops_rfkill_poll(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	bool blocked;
+-
+-	WL_LOCK(wl);
+-	blocked = wlc_check_radio_disabled(wl->wlc);
+-	WL_UNLOCK(wl);
+-
+-	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
+-}
+-
+-static void wl_ops_flush(struct ieee80211_hw *hw, bool drop)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-
+-	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
+-
+-	/* wait for packet queue and dma fifos to run empty */
+-	WL_LOCK(wl);
+-	wlc_wait_for_tx_completion(wl->wlc, drop);
+-	WL_UNLOCK(wl);
+-}
+-
+-static const struct ieee80211_ops wl_ops = {
+-	.tx = wl_ops_tx,
+-	.start = wl_ops_start,
+-	.stop = wl_ops_stop,
+-	.add_interface = wl_ops_add_interface,
+-	.remove_interface = wl_ops_remove_interface,
+-	.config = wl_ops_config,
+-	.bss_info_changed = wl_ops_bss_info_changed,
+-	.configure_filter = wl_ops_configure_filter,
+-	.set_tim = wl_ops_set_tim,
+-	.sw_scan_start = wl_ops_sw_scan_start,
+-	.sw_scan_complete = wl_ops_sw_scan_complete,
+-	.set_tsf = wl_ops_set_tsf,
+-	.get_stats = wl_ops_get_stats,
+-	.sta_notify = wl_ops_sta_notify,
+-	.conf_tx = wl_ops_conf_tx,
+-	.get_tsf = wl_ops_get_tsf,
+-	.sta_add = wl_ops_sta_add,
+-	.sta_remove = wl_ops_sta_remove,
+-	.ampdu_action = wl_ops_ampdu_action,
+-	.rfkill_poll = wl_ops_rfkill_poll,
+-	.flush = wl_ops_flush,
+-};
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int wl_set_hint(struct wl_info *wl, char *abbrev)
+-{
+-	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
+-}
+-
+-/**
+- * attach to the WL device.
+- *
+- * Attach to the WL device identified by vendor and device parameters.
+- * regs is a host accessible memory address pointing to WL device registers.
+- *
+- * wl_attach is not defined as static because in the case where no bus
+- * is defined, wl_attach will never be called, and thus, gcc will issue
+- * a warning that this function is defined but not used if we declare
+- * it as static.
+- *
+- *
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
+-			    uint bustype, void *btparam, uint irq)
+-{
+-	struct wl_info *wl = NULL;
+-	int unit, err;
+-
+-	unsigned long base_addr;
+-	struct ieee80211_hw *hw;
+-	u8 perm[ETH_ALEN];
+-
+-	unit = wl_found;
+-	err = 0;
+-
+-	if (unit < 0) {
+-		return NULL;
+-	}
+-
+-	/* allocate private info */
+-	hw = pci_get_drvdata(btparam);	/* btparam == pdev */
+-	if (hw != NULL)
+-		wl = hw->priv;
+-	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
+-		return NULL;
+-	wl->wiphy = hw->wiphy;
+-
+-	atomic_set(&wl->callbacks, 0);
+-
+-	/* setup the bottom half handler */
+-	tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);
+-
+-
+-
+-	base_addr = regs;
+-
+-	if (bustype == PCI_BUS) {
+-		wl->piomode = false;
+-	} else if (bustype == RPC_BUS) {
+-		/* Do nothing */
+-	} else {
+-		bustype = PCI_BUS;
+-		BCMMSG(wl->wiphy, "force to PCI\n");
+-	}
+-	wl->bcm_bustype = bustype;
+-
+-	wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
+-	if (wl->regsva == NULL) {
+-		wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
+-		goto fail;
+-	}
+-	spin_lock_init(&wl->lock);
+-	spin_lock_init(&wl->isr_lock);
+-
+-	/* prepare ucode */
+-	if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) {
+-		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
+-			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
+-		wl_release_fw(wl);
+-		wl_remove((struct pci_dev *)btparam);
+-		return NULL;
+-	}
+-
+-	/* common load-time initialization */
+-	wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode,
+-			     wl->regsva, wl->bcm_bustype, btparam, &err);
+-	wl_release_fw(wl);
+-	if (!wl->wlc) {
+-		wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n",
+-			  KBUILD_MODNAME, err);
+-		goto fail;
+-	}
+-	wl->pub = wlc_pub(wl->wlc);
+-
+-	wl->pub->ieee_hw = hw;
+-
+-	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+-		wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n",
+-			  unit);
+-	}
+-
+-	/* register our interrupt handler */
+-	if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
+-		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
+-		goto fail;
+-	}
+-	wl->irq = irq;
+-
+-	/* register module */
+-	wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
+-			    NULL);
+-
+-	if (ieee_hw_init(hw)) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
+-			  __func__);
+-		goto fail;
+-	}
+-
+-	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
+-	if (WARN_ON(!is_valid_ether_addr(perm)))
+-		goto fail;
+-	SET_IEEE80211_PERM_ADDR(hw, perm);
+-
+-	err = ieee80211_register_hw(hw);
+-	if (err) {
+-		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
+-			  "%d\n", __func__, err);
+-	}
+-
+-	if (wl->pub->srom_ccode[0])
+-		err = wl_set_hint(wl, wl->pub->srom_ccode);
+-	else
+-		err = wl_set_hint(wl, "US");
+-	if (err) {
+-		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
+-			  __func__, err);
+-	}
+-
+-	wl_found++;
+-	return wl;
+-
+-fail:
+-	wl_free(wl);
+-	return NULL;
+-}
+-
+-
+-
+-#define CHAN2GHZ(channel, freqency, chflags)  { \
+-	.band = IEEE80211_BAND_2GHZ, \
+-	.center_freq = (freqency), \
+-	.hw_value = (channel), \
+-	.flags = chflags, \
+-	.max_antenna_gain = 0, \
+-	.max_power = 19, \
+-}
+-
+-static struct ieee80211_channel wl_2ghz_chantable[] = {
+-	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(5, 2432, 0),
+-	CHAN2GHZ(6, 2437, 0),
+-	CHAN2GHZ(7, 2442, 0),
+-	CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(12, 2467,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(13, 2472,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(14, 2484,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+-};
+-
+-#define CHAN5GHZ(channel, chflags)  { \
+-	.band = IEEE80211_BAND_5GHZ, \
+-	.center_freq = 5000 + 5*(channel), \
+-	.hw_value = (channel), \
+-	.flags = chflags, \
+-	.max_antenna_gain = 0, \
+-	.max_power = 21, \
+-}
+-
+-static struct ieee80211_channel wl_5ghz_nphy_chantable[] = {
+-	/* UNII-1 */
+-	CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
+-	/* UNII-2 */
+-	CHAN5GHZ(52,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(56,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(60,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(64,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	/* MID */
+-	CHAN5GHZ(100,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(104,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(108,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(112,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(116,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(120,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(124,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(128,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(132,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(136,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(140,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
+-		 IEEE80211_CHAN_NO_HT40MINUS),
+-	/* UNII-3 */
+-	CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+-};
+-
+-#define RATE(rate100m, _flags) { \
+-	.bitrate = (rate100m), \
+-	.flags = (_flags), \
+-	.hw_value = (rate100m / 5), \
+-}
+-
+-static struct ieee80211_rate wl_legacy_ratetable[] = {
+-	RATE(10, 0),
+-	RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(60, 0),
+-	RATE(90, 0),
+-	RATE(120, 0),
+-	RATE(180, 0),
+-	RATE(240, 0),
+-	RATE(360, 0),
+-	RATE(480, 0),
+-	RATE(540, 0),
+-};
+-
+-static struct ieee80211_supported_band wl_band_2GHz_nphy = {
+-	.band = IEEE80211_BAND_2GHZ,
+-	.channels = wl_2ghz_chantable,
+-	.n_channels = ARRAY_SIZE(wl_2ghz_chantable),
+-	.bitrates = wl_legacy_ratetable,
+-	.n_bitrates = ARRAY_SIZE(wl_legacy_ratetable),
+-	.ht_cap = {
+-		   /* from include/linux/ieee80211.h */
+-		   .cap = IEEE80211_HT_CAP_GRN_FLD |
+-		   IEEE80211_HT_CAP_SGI_20 |
+-		   IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
+-		   .ht_supported = true,
+-		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+-		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+-		   .mcs = {
+-			   /* placeholders for now */
+-			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+-			   .rx_highest = 500,
+-			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+-		   }
+-};
+-
+-static struct ieee80211_supported_band wl_band_5GHz_nphy = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = wl_5ghz_nphy_chantable,
+-	.n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable),
+-	.bitrates = wl_legacy_ratetable + 4,
+-	.n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4,
+-	.ht_cap = {
+-		   /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
+-		   .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,	/* No 40 mhz yet */
+-		   .ht_supported = true,
+-		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+-		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+-		   .mcs = {
+-			   /* placeholders for now */
+-			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+-			   .rx_highest = 500,
+-			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+-		   }
+-};
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int ieee_hw_rate_init(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int has_5g;
+-	char phy_list[4];
+-
+-	has_5g = 0;
+-
+-	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+-	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+-
+-	if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
+-		wiphy_err(hw->wiphy, "Phy list failed\n");
+-	}
+-
+-	if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+-		if (phy_list[0] == 'c') {
+-			/* Single stream */
+-			wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
+-			wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
+-		}
+-		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
+-	} else {
+-		return -EPERM;
+-	}
+-
+-	/* Assume all bands use the same phy.  True for 11n devices. */
+-	if (NBANDS_PUB(wl->pub) > 1) {
+-		has_5g++;
+-		if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+-			hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+-			    &wl_band_5GHz_nphy;
+-		} else {
+-			return -EPERM;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int ieee_hw_init(struct ieee80211_hw *hw)
+-{
+-	hw->flags = IEEE80211_HW_SIGNAL_DBM
+-	    /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
+-	    | IEEE80211_HW_REPORTS_TX_ACK_STATUS
+-	    | IEEE80211_HW_AMPDU_AGGREGATION;
+-
+-	hw->extra_tx_headroom = wlc_get_header_len();
+-	hw->queues = N_TX_QUEUES;
+-	/* FIXME: this doesn't seem to be used properly in minstrel_ht.
+-	 * mac80211/status.c:ieee80211_tx_status() checks this value,
+-	 * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
+-	 * appears to always set 3 rates
+-	 */
+-	hw->max_rates = 2;	/* Primary rate and 1 fallback rate */
+-
+-	hw->channel_change_time = 7 * 1000;	/* channel change time is dependent on chip and band  */
+-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+-
+-	hw->rate_control_algorithm = "minstrel_ht";
+-
+-	hw->sta_data_size = sizeof(struct scb);
+-	return ieee_hw_rate_init(hw);
+-}
+-
+-/**
+- * determines if a device is a WL device, and if so, attaches it.
+- *
+- * This function determines if a device pointed to by pdev is a WL device,
+- * and if so, performs a wl_attach() on it.
+- *
+- * Perimeter lock is initialized in the course of this function.
+- */
+-static int __devinit
+-wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+-{
+-	int rc;
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	u32 val;
+-
+-	dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
+-	       pdev->bus->number, PCI_SLOT(pdev->devfn),
+-	       PCI_FUNC(pdev->devfn), pdev->irq);
+-
+-	if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
+-	    (((pdev->device & 0xff00) != 0x4300) &&
+-	     ((pdev->device & 0xff00) != 0x4700) &&
+-	     ((pdev->device < 43000) || (pdev->device > 43999))))
+-		return -ENODEV;
+-
+-	rc = pci_enable_device(pdev);
+-	if (rc) {
+-		pr_err("%s: Cannot enable device %d-%d_%d\n",
+-		       __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
+-		       PCI_FUNC(pdev->devfn));
+-		return -ENODEV;
+-	}
+-	pci_set_master(pdev);
+-
+-	pci_read_config_dword(pdev, 0x40, &val);
+-	if ((val & 0x0000ff00) != 0)
+-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+-
+-	hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops);
+-	if (!hw) {
+-		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
+-		return -ENOMEM;
+-	}
+-
+-	SET_IEEE80211_DEV(hw, &pdev->dev);
+-
+-	pci_set_drvdata(pdev, hw);
+-
+-	memset(hw->priv, 0, sizeof(*wl));
+-
+-	wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
+-		       PCI_BUS, pdev, pdev->irq);
+-
+-	if (!wl) {
+-		pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME,
+-		       __func__);
+-		return -ENODEV;
+-	}
+-	return 0;
+-}
+-
+-static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		wiphy_err(wl->wiphy,
+-			  "wl_suspend: pci_get_drvdata failed\n");
+-		return -ENODEV;
+-	}
+-
+-	/* only need to flag hw is down for proper resume */
+-	WL_LOCK(wl);
+-	wl->pub->hw_up = false;
+-	WL_UNLOCK(wl);
+-
+-	pci_save_state(pdev);
+-	pci_disable_device(pdev);
+-	return pci_set_power_state(pdev, PCI_D3hot);
+-}
+-
+-static int wl_resume(struct pci_dev *pdev)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	int err = 0;
+-	u32 val;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		wiphy_err(wl->wiphy,
+-			  "wl: wl_resume: pci_get_drvdata failed\n");
+-		return -ENODEV;
+-	}
+-
+-	err = pci_set_power_state(pdev, PCI_D0);
+-	if (err)
+-		return err;
+-
+-	pci_restore_state(pdev);
+-
+-	err = pci_enable_device(pdev);
+-	if (err)
+-		return err;
+-
+-	pci_set_master(pdev);
+-
+-	pci_read_config_dword(pdev, 0x40, &val);
+-	if ((val & 0x0000ff00) != 0)
+-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+-
+-	/*
+-	*  done. driver will be put in up state
+-	*  in wl_ops_add_interface() call.
+-	*/
+-	return err;
+-}
+-
+-/*
+-* called from both kernel as from wl_*()
+-* precondition: perimeter lock is not acquired.
+-*/
+-static void wl_remove(struct pci_dev *pdev)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	int status;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		pr_err("wl: wl_remove: pci_get_drvdata failed\n");
+-		return;
+-	}
+-
+-	WL_LOCK(wl);
+-	status = wlc_chipmatch(pdev->vendor, pdev->device);
+-	WL_UNLOCK(wl);
+-	if (!status) {
+-		wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n");
+-		return;
+-	}
+-	if (wl->wlc) {
+-		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
+-		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
+-		ieee80211_unregister_hw(hw);
+-		WL_LOCK(wl);
+-		wl_down(wl);
+-		WL_UNLOCK(wl);
+-	}
+-	pci_disable_device(pdev);
+-
+-	wl_free(wl);
+-
+-	pci_set_drvdata(pdev, NULL);
+-	ieee80211_free_hw(hw);
+-}
+-
+-static struct pci_driver wl_pci_driver = {
+-	.name     = KBUILD_MODNAME,
+-	.probe    = wl_pci_probe,
+-	.suspend  = wl_suspend,
+-	.resume   = wl_resume,
+-	.remove   = __devexit_p(wl_remove),
+-	.id_table = wl_id_table,
+-};
+-
+-/**
+- * This is the main entry point for the WL driver.
+- *
+- * This function determines if a device pointed to by pdev is a WL device,
+- * and if so, performs a wl_attach() on it.
+- *
+- */
+-static int __init wl_module_init(void)
+-{
+-	int error = -ENODEV;
+-
+-#ifdef BCMDBG
+-	if (msglevel != 0xdeadbeef)
+-		wl_msg_level = msglevel;
+-	else {
+-		char *var = getvar(NULL, "wl_msglevel");
+-		if (var) {
+-			unsigned long value;
+-
+-			(void)strict_strtoul(var, 0, &value);
+-			wl_msg_level = value;
+-		}
+-	}
+-	if (phymsglevel != 0xdeadbeef)
+-		phyhal_msg_level = phymsglevel;
+-	else {
+-		char *var = getvar(NULL, "phy_msglevel");
+-		if (var) {
+-			unsigned long value;
+-
+-			(void)strict_strtoul(var, 0, &value);
+-			phyhal_msg_level = value;
+-		}
+-	}
+-#endif				/* BCMDBG */
+-
+-	error = pci_register_driver(&wl_pci_driver);
+-	if (!error)
+-		return 0;
+-
+-
+-
+-	return error;
+-}
+-
+-/**
+- * This function unloads the WL driver from the system.
+- *
+- * This function unconditionally unloads the WL driver module from the
+- * system.
+- *
+- */
+-static void __exit wl_module_exit(void)
+-{
+-	pci_unregister_driver(&wl_pci_driver);
+-
+-}
+-
+-module_init(wl_module_init);
+-module_exit(wl_module_exit);
+-
+-/**
+- * This function frees the WL per-device resources.
+- *
+- * This function frees resources owned by the WL device pointed to
+- * by the wl parameter.
+- *
+- * precondition: can both be called locked and unlocked
+- *
+- */
+-static void wl_free(struct wl_info *wl)
+-{
+-	struct wl_timer *t, *next;
+-
+-	/* free ucode data */
+-	if (wl->fw.fw_cnt)
+-		wl_ucode_data_free();
+-	if (wl->irq)
+-		free_irq(wl->irq, wl);
+-
+-	/* kill dpc */
+-	tasklet_kill(&wl->tasklet);
+-
+-	if (wl->pub) {
+-		wlc_module_unregister(wl->pub, "linux", wl);
+-	}
+-
+-	/* free common resources */
+-	if (wl->wlc) {
+-		wlc_detach(wl->wlc);
+-		wl->wlc = NULL;
+-		wl->pub = NULL;
+-	}
+-
+-	/* virtual interface deletion is deferred so we cannot spinwait */
+-
+-	/* wait for all pending callbacks to complete */
+-	while (atomic_read(&wl->callbacks) > 0)
+-		schedule();
+-
+-	/* free timers */
+-	for (t = wl->timers; t; t = next) {
+-		next = t->next;
+-#ifdef BCMDBG
+-		kfree(t->name);
+-#endif
+-		kfree(t);
+-	}
+-
+-	/*
+-	 * unregister_netdev() calls get_stats() which may read chip registers
+-	 * so we cannot unmap the chip registers until after calling unregister_netdev() .
+-	 */
+-	if (wl->regsva && wl->bcm_bustype != SDIO_BUS &&
+-	    wl->bcm_bustype != JTAG_BUS) {
+-		iounmap((void *)wl->regsva);
+-	}
+-	wl->regsva = NULL;
+-}
+-
+-/* flags the given rate in rateset as requested */
+-static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br)
+-{
+-	u32 i;
+-
+-	for (i = 0; i < rs->count; i++) {
+-		if (rate != (rs->rates[i] & 0x7f))
+-			continue;
+-
+-		if (is_br)
+-			rs->rates[i] |= WLC_RATE_FLAG;
+-		else
+-			rs->rates[i] &= WLC_RATE_MASK;
+-		return;
+-	}
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+-		      int prio)
+-{
+-	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_init(struct wl_info *wl)
+-{
+-	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
+-	wl_reset(wl);
+-
+-	wlc_init(wl->wlc);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-uint wl_reset(struct wl_info *wl)
+-{
+-	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
+-	wlc_reset(wl->wlc);
+-
+-	/* dpc will not be rescheduled */
+-	wl->resched = 0;
+-
+-	return 0;
+-}
+-
+-/*
+- * These are interrupt on/off entry points. Disable interrupts
+- * during interrupt state transition.
+- */
+-void wl_intrson(struct wl_info *wl)
+-{
+-	unsigned long flags;
+-
+-	INT_LOCK(wl, flags);
+-	wlc_intrson(wl->wlc);
+-	INT_UNLOCK(wl, flags);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth)
+-{
+-	return true;
+-}
+-
+-u32 wl_intrsoff(struct wl_info *wl)
+-{
+-	unsigned long flags;
+-	u32 status;
+-
+-	INT_LOCK(wl, flags);
+-	status = wlc_intrsoff(wl->wlc);
+-	INT_UNLOCK(wl, flags);
+-	return status;
+-}
+-
+-void wl_intrsrestore(struct wl_info *wl, u32 macintmask)
+-{
+-	unsigned long flags;
+-
+-	INT_LOCK(wl, flags);
+-	wlc_intrsrestore(wl->wlc, macintmask);
+-	INT_UNLOCK(wl, flags);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-int wl_up(struct wl_info *wl)
+-{
+-	int error = 0;
+-
+-	if (wl->pub->up)
+-		return 0;
+-
+-	error = wlc_up(wl->wlc);
+-
+-	return error;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_down(struct wl_info *wl)
+-{
+-	uint callbacks, ret_val = 0;
+-
+-	/* call common down function */
+-	ret_val = wlc_down(wl->wlc);
+-	callbacks = atomic_read(&wl->callbacks) - ret_val;
+-
+-	/* wait for down callbacks to complete */
+-	WL_UNLOCK(wl);
+-
+-	/* For HIGH_only driver, it's important to actually schedule other work,
+-	 * not just spin wait since everything runs at schedule level
+-	 */
+-	SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
+-
+-	WL_LOCK(wl);
+-}
+-
+-static irqreturn_t wl_isr(int irq, void *dev_id)
+-{
+-	struct wl_info *wl;
+-	bool ours, wantdpc;
+-	unsigned long flags;
+-
+-	wl = (struct wl_info *) dev_id;
+-
+-	WL_ISRLOCK(wl, flags);
+-
+-	/* call common first level interrupt handler */
+-	ours = wlc_isr(wl->wlc, &wantdpc);
+-	if (ours) {
+-		/* if more to do... */
+-		if (wantdpc) {
+-
+-			/* ...and call the second level interrupt handler */
+-			/* schedule dpc */
+-			tasklet_schedule(&wl->tasklet);
+-		}
+-	}
+-
+-	WL_ISRUNLOCK(wl, flags);
+-
+-	return IRQ_RETVAL(ours);
+-}
+-
+-static void wl_dpc(unsigned long data)
+-{
+-	struct wl_info *wl;
+-
+-	wl = (struct wl_info *) data;
+-
+-	WL_LOCK(wl);
+-
+-	/* call the common second level interrupt handler */
+-	if (wl->pub->up) {
+-		if (wl->resched) {
+-			unsigned long flags;
+-
+-			INT_LOCK(wl, flags);
+-			wlc_intrsupd(wl->wlc);
+-			INT_UNLOCK(wl, flags);
+-		}
+-
+-		wl->resched = wlc_dpc(wl->wlc, true);
+-	}
+-
+-	/* wlc_dpc() may bring the driver down */
+-	if (!wl->pub->up)
+-		goto done;
+-
+-	/* re-schedule dpc */
+-	if (wl->resched)
+-		tasklet_schedule(&wl->tasklet);
+-	else {
+-		/* re-enable interrupts */
+-		wl_intrson(wl);
+-	}
+-
+- done:
+-	WL_UNLOCK(wl);
+-}
+-
+-/*
+- * is called by the kernel from software irq context
+- */
+-static void wl_timer(unsigned long data)
+-{
+-	_wl_timer((struct wl_timer *) data);
+-}
+-
+-/*
+-* precondition: perimeter lock is not acquired
+- */
+-static void _wl_timer(struct wl_timer *t)
+-{
+-	WL_LOCK(t->wl);
+-
+-	if (t->set) {
+-		if (t->periodic) {
+-			t->timer.expires = jiffies + t->ms * HZ / 1000;
+-			atomic_inc(&t->wl->callbacks);
+-			add_timer(&t->timer);
+-			t->set = true;
+-		} else
+-			t->set = false;
+-
+-		t->fn(t->arg);
+-	}
+-
+-	atomic_dec(&t->wl->callbacks);
+-
+-	WL_UNLOCK(t->wl);
+-}
+-
+-/*
+- * Adds a timer to the list. Caller supplies a timer function.
+- * Is called from wlc.
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg),
+-			       void *arg, const char *name)
+-{
+-	struct wl_timer *t;
+-
+-	t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC);
+-	if (!t) {
+-		wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n",
+-			  wl->pub->unit);
+-		return 0;
+-	}
+-
+-	init_timer(&t->timer);
+-	t->timer.data = (unsigned long) t;
+-	t->timer.function = wl_timer;
+-	t->wl = wl;
+-	t->fn = fn;
+-	t->arg = arg;
+-	t->next = wl->timers;
+-	wl->timers = t;
+-
+-#ifdef BCMDBG
+-	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
+-	if (t->name)
+-		strcpy(t->name, name);
+-#endif
+-
+-	return t;
+-}
+-
+-/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
+- * as well as it's easier to make it periodic
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic)
+-{
+-#ifdef BCMDBG
+-	if (t->set) {
+-		wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
+-			  __func__, t->name, periodic);
+-	}
+-#endif
+-	t->ms = ms;
+-	t->periodic = (bool) periodic;
+-	t->set = true;
+-	t->timer.expires = jiffies + ms * HZ / 1000;
+-
+-	atomic_inc(&wl->callbacks);
+-	add_timer(&t->timer);
+-}
+-
+-/*
+- * return true if timer successfully deleted, false if still pending
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_del_timer(struct wl_info *wl, struct wl_timer *t)
+-{
+-	if (t->set) {
+-		t->set = false;
+-		if (!del_timer(&t->timer)) {
+-			return false;
+-		}
+-		atomic_dec(&wl->callbacks);
+-	}
+-
+-	return true;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_free_timer(struct wl_info *wl, struct wl_timer *t)
+-{
+-	struct wl_timer *tmp;
+-
+-	/* delete the timer in case it is active */
+-	wl_del_timer(wl, t);
+-
+-	if (wl->timers == t) {
+-		wl->timers = wl->timers->next;
+-#ifdef BCMDBG
+-		kfree(t->name);
+-#endif
+-		kfree(t);
+-		return;
+-
+-	}
+-
+-	tmp = wl->timers;
+-	while (tmp) {
+-		if (tmp->next == t) {
+-			tmp->next = t->next;
+-#ifdef BCMDBG
+-			kfree(t->name);
+-#endif
+-			kfree(t);
+-			return;
+-		}
+-		tmp = tmp->next;
+-	}
+-
+-}
+-
+-/*
+- * runs in software irq context
+- *
+- * precondition: perimeter lock is not acquired
+- */
+-static int wl_linux_watchdog(void *ctx)
+-{
+-	return 0;
+-}
+-
+-struct wl_fw_hdr {
+-	u32 offset;
+-	u32 len;
+-	u32 idx;
+-};
+-
+-char *wl_firmwares[WL_MAX_FW] = {
+-	"brcm/bcm43xx",
+-	NULL
+-};
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx)
+-{
+-	int i, entry;
+-	const u8 *pdata;
+-	struct wl_fw_hdr *hdr;
+-	for (i = 0; i < wl->fw.fw_cnt; i++) {
+-		hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+-		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+-		     entry++, hdr++) {
+-			if (hdr->idx == idx) {
+-				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+-				*pbuf = kmalloc(hdr->len, GFP_ATOMIC);
+-				if (*pbuf == NULL) {
+-					wiphy_err(wl->wiphy, "fail to alloc %d"
+-						  " bytes\n", hdr->len);
+-					goto fail;
+-				}
+-				memcpy(*pbuf, pdata, hdr->len);
+-				return 0;
+-			}
+-		}
+-	}
+-	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
+-		  idx);
+-	*pbuf = NULL;
+-fail:
+-	return -ENODATA;
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
+-{
+-	int i, entry;
+-	const u8 *pdata;
+-	struct wl_fw_hdr *hdr;
+-	for (i = 0; i < wl->fw.fw_cnt; i++) {
+-		hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+-		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+-		     entry++, hdr++) {
+-			if (hdr->idx == idx) {
+-				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+-				if (hdr->len != 4) {
+-					wiphy_err(wl->wiphy,
+-						  "ERROR: fw hdr len\n");
+-					return -ENOMSG;
+-				}
+-				*data = *((u32 *) pdata);
+-				return 0;
+-			}
+-		}
+-	}
+-	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
+-	return -ENOMSG;
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev)
+-{
+-	int status;
+-	struct device *device = &pdev->dev;
+-	char fw_name[100];
+-	int i;
+-
+-	memset((void *)&wl->fw, 0, sizeof(struct wl_firmware));
+-	for (i = 0; i < WL_MAX_FW; i++) {
+-		if (wl_firmwares[i] == NULL)
+-			break;
+-		sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
+-			UCODE_LOADER_API_VER);
+-		status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
+-		if (status) {
+-			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+-				  KBUILD_MODNAME, fw_name);
+-			return status;
+-		}
+-		sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
+-			UCODE_LOADER_API_VER);
+-		status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
+-		if (status) {
+-			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+-				  KBUILD_MODNAME, fw_name);
+-			return status;
+-		}
+-		wl->fw.hdr_num_entries[i] =
+-		    wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
+-	}
+-	wl->fw.fw_cnt = i;
+-	return wl_ucode_data_init(wl);
+-}
+-
+-/*
+- * precondition: can both be called locked and unlocked
+- */
+-void wl_ucode_free_buf(void *p)
+-{
+-	kfree(p);
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-static void wl_release_fw(struct wl_info *wl)
+-{
+-	int i;
+-	for (i = 0; i < WL_MAX_FW; i++) {
+-		release_firmware(wl->fw.fw_bin[i]);
+-		release_firmware(wl->fw.fw_hdr[i]);
+-	}
+-}
+-
+-
+-/*
+- * checks validity of all firmware images loaded from user space
+- *
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-int wl_check_firmwares(struct wl_info *wl)
+-{
+-	int i;
+-	int entry;
+-	int rc = 0;
+-	const struct firmware *fw;
+-	const struct firmware *fw_hdr;
+-	struct wl_fw_hdr *ucode_hdr;
+-	for (i = 0; i < WL_MAX_FW && rc == 0; i++) {
+-		fw =  wl->fw.fw_bin[i];
+-		fw_hdr = wl->fw.fw_hdr[i];
+-		if (fw == NULL && fw_hdr == NULL) {
+-			break;
+-		} else if (fw == NULL || fw_hdr == NULL) {
+-			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
+-				  __func__);
+-			rc = -EBADF;
+-		} else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) {
+-			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
+-				"size %zu/%zu\n", __func__, fw_hdr->size,
+-				sizeof(struct wl_fw_hdr));
+-			rc = -EBADF;
+-		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
+-			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
+-				  "%zu\n", __func__, fw->size);
+-			rc = -EBADF;
+-		} else {
+-			/* check if ucode section overruns firmware image */
+-			ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data;
+-			for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
+-			     !rc; entry++, ucode_hdr++) {
+-				if (ucode_hdr->offset + ucode_hdr->len >
+-				    fw->size) {
+-					wiphy_err(wl->wiphy,
+-						  "%s: conflicting bin/hdr\n",
+-						  __func__);
+-					rc = -EBADF;
+-				}
+-			}
+-		}
+-	}
+-	if (rc == 0 && wl->fw.fw_cnt != i) {
+-		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
+-			wl->fw.fw_cnt);
+-		rc = -EBADF;
+-	}
+-	return rc;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_rfkill_set_hw_state(struct wl_info *wl)
+-{
+-	bool blocked = wlc_check_radio_disabled(wl->wlc);
+-
+-	WL_UNLOCK(wl);
+-	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
+-	if (blocked)
+-		wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
+-	WL_LOCK(wl);
+-	return blocked;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_msleep(struct wl_info *wl, uint ms)
+-{
+-	WL_UNLOCK(wl);
+-	msleep(ms);
+-	WL_LOCK(wl);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
+deleted file mode 100644
+index e703d8b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_mac80211_h_
+-#define _wl_mac80211_h_
+-
+-/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and
+- * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
+- * submitted to workqueue instead of being on kernel timer
+- */
+-struct wl_timer {
+-	struct timer_list timer;
+-	struct wl_info *wl;
+-	void (*fn) (void *);
+-	void *arg;		/* argument to fn */
+-	uint ms;
+-	bool periodic;
+-	bool set;
+-	struct wl_timer *next;
+-#ifdef BCMDBG
+-	char *name;		/* Description of the timer */
+-#endif
+-};
+-
+-struct wl_if {
+-	uint subunit;		/* WDS/BSS unit */
+-	struct pci_dev *pci_dev;
+-};
+-
+-#define WL_MAX_FW		4
+-struct wl_firmware {
+-	u32 fw_cnt;
+-	const struct firmware *fw_bin[WL_MAX_FW];
+-	const struct firmware *fw_hdr[WL_MAX_FW];
+-	u32 hdr_num_entries[WL_MAX_FW];
+-};
+-
+-struct wl_info {
+-	struct wlc_pub *pub;		/* pointer to public wlc state */
+-	void *wlc;		/* pointer to private common os-independent data */
+-	u32 magic;
+-
+-	int irq;
+-
+-	spinlock_t lock;	/* per-device perimeter lock */
+-	spinlock_t isr_lock;	/* per-device ISR synchronization lock */
+-	uint bcm_bustype;	/* bus type */
+-	bool piomode;		/* set from insmod argument */
+-	void *regsva;		/* opaque chip registers virtual address */
+-	atomic_t callbacks;	/* # outstanding callback functions */
+-	struct wl_timer *timers;	/* timer cleanup queue */
+-	struct tasklet_struct tasklet;	/* dpc tasklet */
+-	bool resched;		/* dpc needs to be and is rescheduled */
+-#ifdef LINUXSTA_PS
+-	u32 pci_psstate[16];	/* pci ps-state save/restore */
+-#endif
+-	struct wl_firmware fw;
+-	struct wiphy *wiphy;
+-};
+-
+-#define WL_LOCK(wl)	spin_lock_bh(&(wl)->lock)
+-#define WL_UNLOCK(wl)	spin_unlock_bh(&(wl)->lock)
+-
+-/* locking from inside wl_isr */
+-#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0)
+-#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0)
+-
+-/* locking under WL_LOCK() to synchronize with wl_isr */
+-#define INT_LOCK(wl, flags)	spin_lock_irqsave(&(wl)->isr_lock, flags)
+-#define INT_UNLOCK(wl, flags)	spin_unlock_irqrestore(&(wl)->isr_lock, flags)
+-
+-#endif				/* _wl_mac80211_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h
+deleted file mode 100644
+index 6933fda..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define MIN_FW_SIZE 40000	/* minimum firmware file size in bytes */
+-#define MAX_FW_SIZE 150000
+-
+-#define UCODE_LOADER_API_VER 0
+-
+-struct d11init {
+-	u16 addr;
+-	u16 size;
+-	u32 value;
+-};
+-
+-extern struct d11init *d11lcn0bsinitvals24;
+-extern struct d11init *d11lcn0initvals24;
+-extern struct d11init *d11lcn1bsinitvals24;
+-extern struct d11init *d11lcn1initvals24;
+-extern struct d11init *d11lcn2bsinitvals24;
+-extern struct d11init *d11lcn2initvals24;
+-extern struct d11init *d11n0absinitvals16;
+-extern struct d11init *d11n0bsinitvals16;
+-extern struct d11init *d11n0initvals16;
+-extern u32 *bcm43xx_16_mimo;
+-extern u32 bcm43xx_16_mimosz;
+-extern u32 *bcm43xx_24_lcn;
+-extern u32 bcm43xx_24_lcnsz;
+-
+-extern int wl_ucode_data_init(struct wl_info *wl);
+-extern void wl_ucode_data_free(void);
+-
+-extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx);
+-extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data,
+-			      unsigned int idx);
+-extern void wl_ucode_free_buf(void *);
+-extern int  wl_check_firmwares(struct wl_info *wl);
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
+deleted file mode 100644
+index cc00dd1..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
++++ /dev/null
+@@ -1,111 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <bcmdefs.h>
+-#include <wl_ucode.h>
+-
+-enum {
+-	D11UCODE_NAMETAG_START = 0,
+-	D11LCN0BSINITVALS24,
+-	D11LCN0INITVALS24,
+-	D11LCN1BSINITVALS24,
+-	D11LCN1INITVALS24,
+-	D11LCN2BSINITVALS24,
+-	D11LCN2INITVALS24,
+-	D11N0ABSINITVALS16,
+-	D11N0BSINITVALS16,
+-	D11N0INITVALS16,
+-	D11UCODE_OVERSIGHT16_MIMO,
+-	D11UCODE_OVERSIGHT16_MIMOSZ,
+-	D11UCODE_OVERSIGHT24_LCN,
+-	D11UCODE_OVERSIGHT24_LCNSZ,
+-	D11UCODE_OVERSIGHT_BOMMAJOR,
+-	D11UCODE_OVERSIGHT_BOMMINOR
+-};
+-
+-struct d11init *d11lcn0bsinitvals24;
+-struct d11init *d11lcn0initvals24;
+-struct d11init *d11lcn1bsinitvals24;
+-struct d11init *d11lcn1initvals24;
+-struct d11init *d11lcn2bsinitvals24;
+-struct d11init *d11lcn2initvals24;
+-struct d11init *d11n0absinitvals16;
+-struct d11init *d11n0bsinitvals16;
+-struct d11init *d11n0initvals16;
+-u32 *bcm43xx_16_mimo;
+-u32 bcm43xx_16_mimosz;
+-u32 *bcm43xx_24_lcn;
+-u32 bcm43xx_24_lcnsz;
+-u32 *bcm43xx_bommajor;
+-u32 *bcm43xx_bomminor;
+-
+-int wl_ucode_data_init(struct wl_info *wl)
+-{
+-	int rc;
+-	rc = wl_check_firmwares(wl);
+-
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
+-					     D11LCN0BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24,
+-					     D11LCN0INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
+-					     D11LCN1BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24,
+-					     D11LCN1INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
+-					     D11LCN2BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24,
+-					     D11LCN2INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16,
+-					     D11N0ABSINITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16,
+-					     D11N0BSINITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16,
+-					     D11N0INITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
+-					     D11UCODE_OVERSIGHT16_MIMO);
+-	rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz,
+-					      D11UCODE_OVERSIGHT16_MIMOSZ);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
+-					     D11UCODE_OVERSIGHT24_LCN);
+-	rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz,
+-					      D11UCODE_OVERSIGHT24_LCNSZ);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
+-					     D11UCODE_OVERSIGHT_BOMMAJOR);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
+-					     D11UCODE_OVERSIGHT_BOMMINOR);
+-	return rc;
+-}
+-
+-void wl_ucode_data_free(void)
+-{
+-	wl_ucode_free_buf((void *)d11lcn0bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn0initvals24);
+-	wl_ucode_free_buf((void *)d11lcn1bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn1initvals24);
+-	wl_ucode_free_buf((void *)d11lcn2bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn2initvals24);
+-	wl_ucode_free_buf((void *)d11n0absinitvals16);
+-	wl_ucode_free_buf((void *)d11n0bsinitvals16);
+-	wl_ucode_free_buf((void *)d11n0initvals16);
+-	wl_ucode_free_buf((void *)bcm43xx_16_mimo);
+-	wl_ucode_free_buf((void *)bcm43xx_24_lcn);
+-	wl_ucode_free_buf((void *)bcm43xx_bommajor);
+-	wl_ucode_free_buf((void *)bcm43xx_bomminor);
+-
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
+deleted file mode 100644
+index 82c64cd..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
++++ /dev/null
+@@ -1,300 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-#include "wlc_rate.h"
+-#include "wlc_bsscfg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-
+-static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit);
+-static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg);
+-static struct wlc_pub *wlc_pub_malloc(uint unit,
+-				      uint *err, uint devid);
+-static void wlc_pub_mfree(struct wlc_pub *pub);
+-static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid);
+-
+-static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
+-{
+-	tunables->ntxd = NTXD;
+-	tunables->nrxd = NRXD;
+-	tunables->rxbufsz = RXBUFSZ;
+-	tunables->nrxbufpost = NRXBUFPOST;
+-	tunables->maxscb = MAXSCB;
+-	tunables->ampdunummpdu = AMPDU_NUM_MPDU;
+-	tunables->maxpktcb = MAXPKTCB;
+-	tunables->maxucodebss = WLC_MAX_UCODE_BSS;
+-	tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4;
+-	tunables->maxbss = MAXBSS;
+-	tunables->datahiwat = WLC_DATAHIWAT;
+-	tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT;
+-	tunables->rxbnd = RXBND;
+-	tunables->txsbnd = TXSBND;
+-}
+-
+-static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid)
+-{
+-	struct wlc_pub *pub;
+-
+-	pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC);
+-	if (pub == NULL) {
+-		*err = 1001;
+-		goto fail;
+-	}
+-
+-	pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC);
+-	if (pub->tunables == NULL) {
+-		*err = 1028;
+-		goto fail;
+-	}
+-
+-	/* need to init the tunables now */
+-	wlc_tunables_init(pub->tunables, devid);
+-
+-	pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
+-	if (pub->multicast == NULL) {
+-		*err = 1003;
+-		goto fail;
+-	}
+-
+-	return pub;
+-
+- fail:
+-	wlc_pub_mfree(pub);
+-	return NULL;
+-}
+-
+-static void wlc_pub_mfree(struct wlc_pub *pub)
+-{
+-	if (pub == NULL)
+-		return;
+-
+-	kfree(pub->multicast);
+-	kfree(pub->tunables);
+-	kfree(pub);
+-}
+-
+-static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit)
+-{
+-	struct wlc_bsscfg *cfg;
+-
+-	cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC);
+-	if (cfg == NULL)
+-		goto fail;
+-
+-	cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
+-	if (cfg->current_bss == NULL)
+-		goto fail;
+-
+-	return cfg;
+-
+- fail:
+-	wlc_bsscfg_mfree(cfg);
+-	return NULL;
+-}
+-
+-static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg)
+-{
+-	if (cfg == NULL)
+-		return;
+-
+-	kfree(cfg->maclist);
+-	kfree(cfg->current_bss);
+-	kfree(cfg);
+-}
+-
+-static void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
+-				 struct wlc_bsscfg *bsscfg)
+-{
+-	bsscfg->ID = wlc->next_bsscfg_ID;
+-	wlc->next_bsscfg_ID++;
+-}
+-
+-/*
+- * The common driver entry routine. Error codes should be unique
+- */
+-struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
+-{
+-	struct wlc_info *wlc;
+-
+-	wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC);
+-	if (wlc == NULL) {
+-		*err = 1002;
+-		goto fail;
+-	}
+-
+-	wlc->hwrxoff = WL_HWRXOFF;
+-
+-	/* allocate struct wlc_pub state structure */
+-	wlc->pub = wlc_pub_malloc(unit, err, devid);
+-	if (wlc->pub == NULL) {
+-		*err = 1003;
+-		goto fail;
+-	}
+-	wlc->pub->wlc = wlc;
+-
+-	/* allocate struct wlc_hw_info state structure */
+-
+-	wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC);
+-	if (wlc->hw == NULL) {
+-		*err = 1005;
+-		goto fail;
+-	}
+-	wlc->hw->wlc = wlc;
+-
+-	wlc->hw->bandstate[0] =
+-		kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC);
+-	if (wlc->hw->bandstate[0] == NULL) {
+-		*err = 1006;
+-		goto fail;
+-	} else {
+-		int i;
+-
+-		for (i = 1; i < MAXBANDS; i++) {
+-			wlc->hw->bandstate[i] = (struct wlc_hwband *)
+-			    ((unsigned long)wlc->hw->bandstate[0] +
+-			     (sizeof(struct wlc_hwband) * i));
+-		}
+-	}
+-
+-	wlc->modulecb =
+-		kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC);
+-	if (wlc->modulecb == NULL) {
+-		*err = 1009;
+-		goto fail;
+-	}
+-
+-	wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
+-	if (wlc->default_bss == NULL) {
+-		*err = 1010;
+-		goto fail;
+-	}
+-
+-	wlc->cfg = wlc_bsscfg_malloc(unit);
+-	if (wlc->cfg == NULL) {
+-		*err = 1011;
+-		goto fail;
+-	}
+-	wlc_bsscfg_ID_assign(wlc, wlc->cfg);
+-
+-	wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) *
+-				    (wlc->pub->tunables->maxpktcb + 1),
+-				    GFP_ATOMIC);
+-	if (wlc->pkt_callback == NULL) {
+-		*err = 1013;
+-		goto fail;
+-	}
+-
+-	wlc->wsec_def_keys[0] =
+-		kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC);
+-	if (wlc->wsec_def_keys[0] == NULL) {
+-		*err = 1015;
+-		goto fail;
+-	} else {
+-		int i;
+-		for (i = 1; i < WLC_DEFAULT_KEYS; i++) {
+-			wlc->wsec_def_keys[i] = (wsec_key_t *)
+-			    ((unsigned long)wlc->wsec_def_keys[0] +
+-			     (sizeof(wsec_key_t) * i));
+-		}
+-	}
+-
+-	wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC);
+-	if (wlc->protection == NULL) {
+-		*err = 1016;
+-		goto fail;
+-	}
+-
+-	wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC);
+-	if (wlc->stf == NULL) {
+-		*err = 1017;
+-		goto fail;
+-	}
+-
+-	wlc->bandstate[0] =
+-		kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC);
+-	if (wlc->bandstate[0] == NULL) {
+-		*err = 1025;
+-		goto fail;
+-	} else {
+-		int i;
+-
+-		for (i = 1; i < MAXBANDS; i++) {
+-			wlc->bandstate[i] =
+-			    (struct wlcband *) ((unsigned long)wlc->bandstate[0]
+-			    + (sizeof(struct wlcband)*i));
+-		}
+-	}
+-
+-	wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC);
+-	if (wlc->corestate == NULL) {
+-		*err = 1026;
+-		goto fail;
+-	}
+-
+-	wlc->corestate->macstat_snapshot =
+-		kzalloc(sizeof(macstat_t), GFP_ATOMIC);
+-	if (wlc->corestate->macstat_snapshot == NULL) {
+-		*err = 1027;
+-		goto fail;
+-	}
+-
+-	return wlc;
+-
+- fail:
+-	wlc_detach_mfree(wlc);
+-	return NULL;
+-}
+-
+-void wlc_detach_mfree(struct wlc_info *wlc)
+-{
+-	if (wlc == NULL)
+-		return;
+-
+-	wlc_bsscfg_mfree(wlc->cfg);
+-	wlc_pub_mfree(wlc->pub);
+-	kfree(wlc->modulecb);
+-	kfree(wlc->default_bss);
+-	kfree(wlc->pkt_callback);
+-	kfree(wlc->wsec_def_keys[0]);
+-	kfree(wlc->protection);
+-	kfree(wlc->stf);
+-	kfree(wlc->bandstate[0]);
+-	kfree(wlc->corestate->macstat_snapshot);
+-	kfree(wlc->corestate);
+-	kfree(wlc->hw->bandstate[0]);
+-	kfree(wlc->hw);
+-
+-	/* free the wlc */
+-	kfree(wlc);
+-	wlc = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
+deleted file mode 100644
+index 95f951e..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
++++ /dev/null
+@@ -1,18 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid);
+-extern void wlc_detach_mfree(struct wlc_info *wlc);
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+deleted file mode 100644
+index 85ad700..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
++++ /dev/null
+@@ -1,1253 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <net/mac80211.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-#include <d11.h>
+-
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_antsel.h"
+-#include "wl_export.h"
+-#include "wl_dbg.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_ampdu.h"
+-
+-#define AMPDU_MAX_MPDU		32	/* max number of mpdus in an ampdu */
+-#define AMPDU_NUM_MPDU_LEGACY	16	/* max number of mpdus in an ampdu to a legacy */
+-#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
+-#define AMPDU_TX_BA_DEF_WSIZE	64	/* default Tx ba window size (in pdu) */
+-#define AMPDU_RX_BA_DEF_WSIZE   64	/* max Rx ba window size (in pdu) */
+-#define AMPDU_RX_BA_MAX_WSIZE   64	/* default Rx ba window size (in pdu) */
+-#define	AMPDU_MAX_DUR		5	/* max dur of tx ampdu (in msec) */
+-#define AMPDU_DEF_RETRY_LIMIT	5	/* default tx retry limit */
+-#define AMPDU_DEF_RR_RETRY_LIMIT	2	/* default tx retry limit at reg rate */
+-#define AMPDU_DEF_TXPKT_WEIGHT	2	/* default weight of ampdu in txfifo */
+-#define AMPDU_DEF_FFPLD_RSVD	2048	/* default ffpld reserved bytes */
+-#define AMPDU_INI_FREE		10	/* # of inis to be freed on detach */
+-#define	AMPDU_SCB_MAX_RELEASE	20	/* max # of mpdus released at a time */
+-
+-#define NUM_FFPLD_FIFO 4	/* number of fifo concerned by pre-loading */
+-#define FFPLD_TX_MAX_UNFL   200	/* default value of the average number of ampdu
+-				 * without underflows
+-				 */
+-#define FFPLD_MPDU_SIZE 1800	/* estimate of maximum mpdu size */
+-#define FFPLD_MAX_MCS 23	/* we don't deal with mcs 32 */
+-#define FFPLD_PLD_INCR 1000	/* increments in bytes */
+-#define FFPLD_MAX_AMPDU_CNT 5000	/* maximum number of ampdu we
+-					 * accumulate between resets.
+-					 */
+-
+-#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
+-
+-/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
+-#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
+-	AMPDU_DELIMITER_LEN + 3\
+-	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
+-
+-/* structure to hold tx fifo information and pre-loading state
+- * counters specific to tx underflows of ampdus
+- * some counters might be redundant with the ones in wlc or ampdu structures.
+- * This allows to maintain a specific state independently of
+- * how often and/or when the wlc counters are updated.
+- */
+-typedef struct wlc_fifo_info {
+-	u16 ampdu_pld_size;	/* number of bytes to be pre-loaded */
+-	u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];	/* per-mcs max # of mpdus in an ampdu */
+-	u16 prev_txfunfl;	/* num of underflows last read from the HW macstats counter */
+-	u32 accum_txfunfl;	/* num of underflows since we modified pld params */
+-	u32 accum_txampdu;	/* num of tx ampdu since we modified pld params  */
+-	u32 prev_txampdu;	/* previous reading of tx ampdu */
+-	u32 dmaxferrate;	/* estimated dma avg xfer rate in kbits/sec */
+-} wlc_fifo_info_t;
+-
+-/* AMPDU module specific state */
+-struct ampdu_info {
+-	struct wlc_info *wlc;	/* pointer to main wlc structure */
+-	int scb_handle;		/* scb cubby handle to retrieve data from scb */
+-	u8 ini_enable[AMPDU_MAX_SCB_TID];	/* per-tid initiator enable/disable of ampdu */
+-	u8 ba_tx_wsize;	/* Tx ba window size (in pdu) */
+-	u8 ba_rx_wsize;	/* Rx ba window size (in pdu) */
+-	u8 retry_limit;	/* mpdu transmit retry limit */
+-	u8 rr_retry_limit;	/* mpdu transmit retry limit at regular rate */
+-	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];	/* per-tid mpdu transmit retry limit */
+-	/* per-tid mpdu transmit retry limit at regular rate */
+-	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
+-	u8 mpdu_density;	/* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */
+-	s8 max_pdu;		/* max pdus allowed in ampdu */
+-	u8 dur;		/* max duration of an ampdu (in msec) */
+-	u8 txpkt_weight;	/* weight of ampdu in txfifo; reduces rate lag */
+-	u8 rx_factor;	/* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */
+-	u32 ffpld_rsvd;	/* number of bytes to reserve for preload */
+-	u32 max_txlen[MCS_TABLE_SIZE][2][2];	/* max size of ampdu per mcs, bw and sgi */
+-	void *ini_free[AMPDU_INI_FREE];	/* array of ini's to be freed on detach */
+-	bool mfbr;		/* enable multiple fallback rate */
+-	u32 tx_max_funl;	/* underflows should be kept such that
+-				 * (tx_max_funfl*underflows) < tx frames
+-				 */
+-	wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO];	/* table of fifo infos  */
+-
+-};
+-
+-/* used for flushing ampdu packets */
+-struct cb_del_ampdu_pars {
+-	struct ieee80211_sta *sta;
+-	u16 tid;
+-};
+-
+-#define AMPDU_CLEANUPFLAG_RX   (0x1)
+-#define AMPDU_CLEANUPFLAG_TX   (0x2)
+-
+-#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu))
+-#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid]))
+-
+-static void wlc_ffpld_init(struct ampdu_info *ampdu);
+-static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f);
+-static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
+-
+-static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
+-						   scb_ampdu_t *scb_ampdu,
+-						   u8 tid, bool override);
+-static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur);
+-static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb);
+-static void scb_ampdu_update_config_all(struct ampdu_info *ampdu);
+-
+-#define wlc_ampdu_txflowcontrol(a, b, c)	do {} while (0)
+-
+-static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu,
+-					  struct scb *scb,
+-					  struct sk_buff *p, tx_status_t *txs,
+-					  u32 frmtxstatus, u32 frmtxstatus2);
+-static bool wlc_ampdu_cap(struct ampdu_info *ampdu);
+-static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on);
+-
+-struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc)
+-{
+-	struct ampdu_info *ampdu;
+-	int i;
+-
+-	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
+-	if (!ampdu) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n",
+-			  wlc->pub->unit);
+-		return NULL;
+-	}
+-	ampdu->wlc = wlc;
+-
+-	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
+-		ampdu->ini_enable[i] = true;
+-	/* Disable ampdu for VO by default */
+-	ampdu->ini_enable[PRIO_8021D_VO] = false;
+-	ampdu->ini_enable[PRIO_8021D_NC] = false;
+-
+-	/* Disable ampdu for BK by default since not enough fifo space */
+-	ampdu->ini_enable[PRIO_8021D_NONE] = false;
+-	ampdu->ini_enable[PRIO_8021D_BK] = false;
+-
+-	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
+-	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
+-	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
+-	ampdu->max_pdu = AUTO;
+-	ampdu->dur = AMPDU_MAX_DUR;
+-	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
+-
+-	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
+-	/* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */
+-	if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
+-		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
+-	else
+-		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
+-	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
+-	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
+-
+-	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
+-		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
+-		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
+-	}
+-
+-	ampdu_update_max_txlen(ampdu, ampdu->dur);
+-	ampdu->mfbr = false;
+-	/* try to set ampdu to the default value */
+-	wlc_ampdu_set(ampdu, wlc->pub->_ampdu);
+-
+-	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
+-	wlc_ffpld_init(ampdu);
+-
+-	return ampdu;
+-}
+-
+-void wlc_ampdu_detach(struct ampdu_info *ampdu)
+-{
+-	int i;
+-
+-	if (!ampdu)
+-		return;
+-
+-	/* free all ini's which were to be freed on callbacks which were never called */
+-	for (i = 0; i < AMPDU_INI_FREE; i++) {
+-		kfree(ampdu->ini_free[i]);
+-	}
+-
+-	wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
+-	kfree(ampdu);
+-}
+-
+-static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb)
+-{
+-	scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	int i;
+-
+-	scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu;
+-
+-	/* go back to legacy size if some preloading is occurring */
+-	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
+-		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
+-			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
+-	}
+-
+-	/* apply user override */
+-	if (ampdu->max_pdu != AUTO)
+-		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
+-
+-	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE);
+-
+-	if (scb_ampdu->max_rxlen)
+-		scb_ampdu->release =
+-		    min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600);
+-
+-	scb_ampdu->release = min(scb_ampdu->release,
+-				 ampdu->fifo_tb[TX_AC_BE_FIFO].
+-				 mcs2ampdu_table[FFPLD_MAX_MCS]);
+-}
+-
+-static void scb_ampdu_update_config_all(struct ampdu_info *ampdu)
+-{
+-	scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
+-}
+-
+-static void wlc_ffpld_init(struct ampdu_info *ampdu)
+-{
+-	int i, j;
+-	wlc_fifo_info_t *fifo;
+-
+-	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
+-		fifo = (ampdu->fifo_tb + j);
+-		fifo->ampdu_pld_size = 0;
+-		for (i = 0; i <= FFPLD_MAX_MCS; i++)
+-			fifo->mcs2ampdu_table[i] = 255;
+-		fifo->dmaxferrate = 0;
+-		fifo->accum_txampdu = 0;
+-		fifo->prev_txfunfl = 0;
+-		fifo->accum_txfunfl = 0;
+-
+-	}
+-}
+-
+-/* evaluate the dma transfer rate using the tx underflows as feedback.
+- * If necessary, increase tx fifo preloading. If not enough,
+- * decrease maximum ampdu size for each mcs till underflows stop
+- * Return 1 if pre-loading not active, -1 if not an underflow event,
+- * 0 if pre-loading module took care of the event.
+- */
+-static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
+-{
+-	struct ampdu_info *ampdu = wlc->ampdu;
+-	u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
+-	u32 txunfl_ratio;
+-	u8 max_mpdu;
+-	u32 current_ampdu_cnt = 0;
+-	u16 max_pld_size;
+-	u32 new_txunfl;
+-	wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid);
+-	uint xmtfifo_sz;
+-	u16 cur_txunfl;
+-
+-	/* return if we got here for a different reason than underflows */
+-	cur_txunfl =
+-	    wlc_read_shm(wlc,
+-			 M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid]));
+-	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
+-	if (new_txunfl == 0) {
+-		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
+-		return -1;
+-	}
+-	fifo->prev_txfunfl = cur_txunfl;
+-
+-	if (!ampdu->tx_max_funl)
+-		return 1;
+-
+-	/* check if fifo is big enough */
+-	if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) {
+-		return -1;
+-	}
+-
+-	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
+-		return 1;
+-
+-	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
+-	fifo->accum_txfunfl += new_txunfl;
+-
+-	/* we need to wait for at least 10 underflows */
+-	if (fifo->accum_txfunfl < 10)
+-		return 0;
+-
+-	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
+-		current_ampdu_cnt, fifo->accum_txfunfl);
+-
+-	/*
+-	   compute the current ratio of tx unfl per ampdu.
+-	   When the current ampdu count becomes too
+-	   big while the ratio remains small, we reset
+-	   the current count in order to not
+-	   introduce too big of a latency in detecting a
+-	   large amount of tx underflows later.
+-	 */
+-
+-	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
+-
+-	if (txunfl_ratio > ampdu->tx_max_funl) {
+-		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) {
+-			fifo->accum_txfunfl = 0;
+-		}
+-		return 0;
+-	}
+-	max_mpdu =
+-	    min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+-
+-	/* In case max value max_pdu is already lower than
+-	   the fifo depth, there is nothing more we can do.
+-	 */
+-
+-	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
+-		fifo->accum_txfunfl = 0;
+-		return 0;
+-	}
+-
+-	if (fifo->ampdu_pld_size < max_pld_size) {
+-
+-		/* increment by TX_FIFO_PLD_INC bytes */
+-		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
+-		if (fifo->ampdu_pld_size > max_pld_size)
+-			fifo->ampdu_pld_size = max_pld_size;
+-
+-		/* update scb release size */
+-		scb_ampdu_update_config_all(ampdu);
+-
+-		/*
+-		   compute a new dma xfer rate for max_mpdu @ max mcs.
+-		   This is the minimum dma rate that
+-		   can achieve no underflow condition for the current mpdu size.
+-		 */
+-		/* note : we divide/multiply by 100 to avoid integer overflows */
+-		fifo->dmaxferrate =
+-		    (((phy_rate / 100) *
+-		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+-		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+-
+-		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
+-			"pre-load size %d\n",
+-			fifo->dmaxferrate, fifo->ampdu_pld_size);
+-	} else {
+-
+-		/* decrease ampdu size */
+-		if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
+-			if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
+-				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
+-				    AMPDU_NUM_MPDU_LEGACY - 1;
+-			else
+-				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
+-
+-			/* recompute the table */
+-			wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid);
+-
+-			/* update scb release size */
+-			scb_ampdu_update_config_all(ampdu);
+-		}
+-	}
+-	fifo->accum_txfunfl = 0;
+-	return 0;
+-}
+-
+-static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
+-{
+-	int i;
+-	u32 phy_rate, dma_rate, tmp;
+-	u8 max_mpdu;
+-	wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f);
+-
+-	/* recompute the dma rate */
+-	/* note : we divide/multiply by 100 to avoid integer overflows */
+-	max_mpdu =
+-	    min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+-	phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
+-	dma_rate =
+-	    (((phy_rate / 100) *
+-	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+-	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+-	fifo->dmaxferrate = dma_rate;
+-
+-	/* fill up the mcs2ampdu table; do not recalc the last mcs */
+-	dma_rate = dma_rate >> 7;
+-	for (i = 0; i < FFPLD_MAX_MCS; i++) {
+-		/* shifting to keep it within integer range */
+-		phy_rate = MCS_RATE(i, true, false) >> 7;
+-		if (phy_rate > dma_rate) {
+-			tmp = ((fifo->ampdu_pld_size * phy_rate) /
+-			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
+-			tmp = min_t(u32, tmp, 255);
+-			fifo->mcs2ampdu_table[i] = (u8) tmp;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
+-	      uint prec)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 tid = (u8) (p->priority);
+-
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-
+-	/* initialize initiator on first packet; sends addba req */
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	if (ini->magic != INI_MAGIC) {
+-		ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
+-	}
+-	return;
+-}
+-
+-int
+-wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
+-	      struct sk_buff **pdu, int prec)
+-{
+-	struct wlc_info *wlc;
+-	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
+-	u8 tid, ndelim;
+-	int err = 0;
+-	u8 preamble_type = WLC_GF_PREAMBLE;
+-	u8 fbr_preamble_type = WLC_GF_PREAMBLE;
+-	u8 rts_preamble_type = WLC_LONG_PREAMBLE;
+-	u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE;
+-
+-	bool rr = true, fbr = false;
+-	uint i, count = 0, fifo, seg_cnt = 0;
+-	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
+-	u32 ampdu_len, maxlen = 0;
+-	d11txh_t *txh = NULL;
+-	u8 *plcp;
+-	struct ieee80211_hdr *h;
+-	struct scb *scb;
+-	scb_ampdu_t *scb_ampdu;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 mcs = 0;
+-	bool use_rts = false, use_cts = false;
+-	ratespec_t rspec = 0, rspec_fallback = 0;
+-	ratespec_t rts_rspec = 0, rts_rspec_fallback = 0;
+-	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+-	struct ieee80211_rts *rts;
+-	u8 rr_retry_limit;
+-	wlc_fifo_info_t *f;
+-	bool fbr_iscck;
+-	struct ieee80211_tx_info *tx_info;
+-	u16 qlen;
+-	struct wiphy *wiphy;
+-
+-	wlc = ampdu->wlc;
+-	wiphy = wlc->wiphy;
+-	p = *pdu;
+-
+-	tid = (u8) (p->priority);
+-
+-	f = ampdu->fifo_tb + prio2fifo[tid];
+-
+-	scb = wlc->pub->global_scb;
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	ini = &scb_ampdu->ini[tid];
+-
+-	/* Let pressure continue to build ... */
+-	qlen = pktq_plen(&qi->q, prec);
+-	if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
+-		return -EBUSY;
+-	}
+-
+-	wlc_ampdu_agg(ampdu, scb, p, tid);
+-
+-	if (wlc->block_datafifo) {
+-		wiphy_err(wiphy, "%s: Fifo blocked\n", __func__);
+-		return -EBUSY;
+-	}
+-	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+-	ampdu_len = 0;
+-	dma_len = 0;
+-	while (p) {
+-		struct ieee80211_tx_rate *txrate;
+-
+-		tx_info = IEEE80211_SKB_CB(p);
+-		txrate = tx_info->status.rates;
+-
+-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-			err = wlc_prep_pdu(wlc, p, &fifo);
+-		} else {
+-			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
+-			*pdu = NULL;
+-			err = 0;
+-			break;
+-		}
+-
+-		if (err) {
+-			if (err == -EBUSY) {
+-				wiphy_err(wiphy, "wl%d: wlc_sendampdu: "
+-					  "prep_xdu retry; seq 0x%x\n",
+-					  wlc->pub->unit, seq);
+-				*pdu = p;
+-				break;
+-			}
+-
+-			/* error in the packet; reject it */
+-			wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu "
+-				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
+-			*pdu = NULL;
+-			break;
+-		}
+-
+-		/* pkt is good to be aggregated */
+-		txh = (d11txh_t *) p->data;
+-		plcp = (u8 *) (txh + 1);
+-		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
+-		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
+-		index = TX_SEQ_TO_INDEX(seq);
+-
+-		/* check mcl fields and test whether it can be agg'd */
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		mcl &= ~TXC_AMPDU_MASK;
+-		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
+-		txh->PreloadSize = 0;	/* always default to 0 */
+-
+-		/*  Handle retry limits */
+-		if (txrate[0].count <= rr_retry_limit) {
+-			txrate[0].count++;
+-			rr = true;
+-			fbr = false;
+-		} else {
+-			fbr = true;
+-			rr = false;
+-			txrate[1].count++;
+-		}
+-
+-		/* extract the length info */
+-		len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+-		    : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+-
+-		/* retrieve null delimiter count */
+-		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+-		seg_cnt += 1;
+-
+-		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
+-			wlc->pub->unit, count, len);
+-
+-		/*
+-		 * aggregateable mpdu. For ucode/hw agg,
+-		 * test whether need to break or change the epoch
+-		 */
+-		if (count == 0) {
+-			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
+-			/* refill the bits since might be a retx mpdu */
+-			mcl |= TXC_STARTMSDU;
+-			rts = (struct ieee80211_rts *)&txh->rts_frame;
+-
+-			if (ieee80211_is_rts(rts->frame_control)) {
+-				mcl |= TXC_SENDRTS;
+-				use_rts = true;
+-			}
+-			if (ieee80211_is_cts(rts->frame_control)) {
+-				mcl |= TXC_SENDCTS;
+-				use_cts = true;
+-			}
+-		} else {
+-			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
+-			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
+-		}
+-
+-		len = roundup(len, 4);
+-		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
+-
+-		dma_len += (u16) bcm_pkttotlen(p);
+-
+-		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
+-			" seg_cnt %d null delim %d\n",
+-			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
+-
+-		txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-		/* this packet is added */
+-		pkt[count++] = p;
+-
+-		/* patch the first MPDU */
+-		if (count == 1) {
+-			u8 plcp0, plcp3, is40, sgi;
+-			struct ieee80211_sta *sta;
+-
+-			sta = tx_info->control.sta;
+-
+-			if (rr) {
+-				plcp0 = plcp[0];
+-				plcp3 = plcp[3];
+-			} else {
+-				plcp0 = txh->FragPLCPFallback[0];
+-				plcp3 = txh->FragPLCPFallback[3];
+-
+-			}
+-			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
+-			sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
+-			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
+-			maxlen =
+-			    min(scb_ampdu->max_rxlen,
+-				ampdu->max_txlen[mcs][is40][sgi]);
+-
+-			/* XXX Fix me to honor real max_rxlen */
+-			/* can fix this as soon as ampdu_action() in mac80211.h
+-			 * gets extra u8buf_size par */
+-			maxlen = 64 * 1024;
+-
+-			if (is40)
+-				mimo_ctlchbw =
+-				    CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+-				    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+-
+-			/* rebuild the rspec and rspec_fallback */
+-			rspec = RSPEC_MIMORATE;
+-			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
+-			if (plcp[0] & MIMO_PLCP_40MHZ)
+-				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+-
+-			if (fbr_iscck)	/* CCK */
+-				rspec_fallback =
+-				    CCK_RSPEC(CCK_PHY2MAC_RATE
+-					      (txh->FragPLCPFallback[0]));
+-			else {	/* MIMO */
+-				rspec_fallback = RSPEC_MIMORATE;
+-				rspec_fallback |=
+-				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
+-				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
+-					rspec_fallback |=
+-					    (PHY_TXC1_BW_40MHZ <<
+-					     RSPEC_BW_SHIFT);
+-			}
+-
+-			if (use_rts || use_cts) {
+-				rts_rspec =
+-				    wlc_rspec_to_rts_rspec(wlc, rspec, false,
+-							   mimo_ctlchbw);
+-				rts_rspec_fallback =
+-				    wlc_rspec_to_rts_rspec(wlc, rspec_fallback,
+-							   false, mimo_ctlchbw);
+-			}
+-		}
+-
+-		/* if (first mpdu for host agg) */
+-		/* test whether to add more */
+-		if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) &&
+-		    (count == f->mcs2ampdu_table[mcs])) {
+-			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
+-				" ampdu at %d for mcs %d\n",
+-				wlc->pub->unit, count, mcs);
+-			break;
+-		}
+-
+-		if (count == scb_ampdu->max_pdu) {
+-			break;
+-		}
+-
+-		/* check to see if the next pkt is a candidate for aggregation */
+-		p = pktq_ppeek(&qi->q, prec);
+-		tx_info = IEEE80211_SKB_CB(p);	/* tx_info must be checked with current p */
+-
+-		if (p) {
+-			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
+-			    ((u8) (p->priority) == tid)) {
+-
+-				plen =
+-				    bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD;
+-				plen = max(scb_ampdu->min_len, plen);
+-
+-				if ((plen + ampdu_len) > maxlen) {
+-					p = NULL;
+-					wiphy_err(wiphy, "%s: Bogus plen #1\n",
+-						__func__);
+-					continue;
+-				}
+-
+-				/* check if there are enough descriptors available */
+-				if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) {
+-					wiphy_err(wiphy, "%s: No fifo space  "
+-						  "!!\n", __func__);
+-					p = NULL;
+-					continue;
+-				}
+-				p = bcm_pktq_pdeq(&qi->q, prec);
+-			} else {
+-				p = NULL;
+-			}
+-		}
+-	}			/* end while(p) */
+-
+-	ini->tx_in_transit += count;
+-
+-	if (count) {
+-		/* patch up the last txh */
+-		txh = (d11txh_t *) pkt[count - 1]->data;
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		mcl &= ~TXC_AMPDU_MASK;
+-		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
+-		txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-		/* remove the null delimiter after last mpdu */
+-		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+-		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
+-		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
+-
+-		/* remove the pad len from last mpdu */
+-		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
+-		len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+-		    : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+-		ampdu_len -= roundup(len, 4) - len;
+-
+-		/* patch up the first txh & plcp */
+-		txh = (d11txh_t *) pkt[0]->data;
+-		plcp = (u8 *) (txh + 1);
+-
+-		WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
+-		/* mark plcp to indicate ampdu */
+-		WLC_SET_MIMO_PLCP_AMPDU(plcp);
+-
+-		/* reset the mixed mode header durations */
+-		if (txh->MModeLen) {
+-			u16 mmodelen =
+-			    wlc_calc_lsig_len(wlc, rspec, ampdu_len);
+-			txh->MModeLen = cpu_to_le16(mmodelen);
+-			preamble_type = WLC_MM_PREAMBLE;
+-		}
+-		if (txh->MModeFbrLen) {
+-			u16 mmfbrlen =
+-			    wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len);
+-			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
+-			fbr_preamble_type = WLC_MM_PREAMBLE;
+-		}
+-
+-		/* set the preload length */
+-		if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) {
+-			dma_len = min(dma_len, f->ampdu_pld_size);
+-			txh->PreloadSize = cpu_to_le16(dma_len);
+-		} else
+-			txh->PreloadSize = 0;
+-
+-		mch = le16_to_cpu(txh->MacTxControlHigh);
+-
+-		/* update RTS dur fields */
+-		if (use_rts || use_cts) {
+-			u16 durid;
+-			rts = (struct ieee80211_rts *)&txh->rts_frame;
+-			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
+-			    TXC_PREAMBLE_RTS_MAIN_SHORT)
+-				rts_preamble_type = WLC_SHORT_PREAMBLE;
+-
+-			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
+-			    TXC_PREAMBLE_RTS_FB_SHORT)
+-				rts_fbr_preamble_type = WLC_SHORT_PREAMBLE;
+-
+-			durid =
+-			    wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec,
+-						   rspec, rts_preamble_type,
+-						   preamble_type, ampdu_len,
+-						   true);
+-			rts->duration = cpu_to_le16(durid);
+-			durid = wlc_compute_rtscts_dur(wlc, use_cts,
+-						       rts_rspec_fallback,
+-						       rspec_fallback,
+-						       rts_fbr_preamble_type,
+-						       fbr_preamble_type,
+-						       ampdu_len, true);
+-			txh->RTSDurFallback = cpu_to_le16(durid);
+-			/* set TxFesTimeNormal */
+-			txh->TxFesTimeNormal = rts->duration;
+-			/* set fallback rate version of TxFesTimeNormal */
+-			txh->TxFesTimeFallback = txh->RTSDurFallback;
+-		}
+-
+-		/* set flag and plcp for fallback rate */
+-		if (fbr) {
+-			mch |= TXC_AMPDU_FBR;
+-			txh->MacTxControlHigh = cpu_to_le16(mch);
+-			WLC_SET_MIMO_PLCP_AMPDU(plcp);
+-			WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
+-		}
+-
+-		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
+-			wlc->pub->unit, count, ampdu_len);
+-
+-		/* inform rate_sel if it this is a rate probe pkt */
+-		frameid = le16_to_cpu(txh->TxFrameID);
+-		if (frameid & TXFID_RATE_PROBE_MASK) {
+-			wiphy_err(wiphy, "%s: XXX what to do with "
+-				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
+-		}
+-		for (i = 0; i < count; i++)
+-			wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1),
+-				   ampdu->txpkt_weight);
+-
+-	}
+-	/* endif (count) */
+-	return err;
+-}
+-
+-void
+-wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
+-		     struct sk_buff *p, tx_status_t *txs)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	struct wlc_info *wlc = ampdu->wlc;
+-	scb_ampdu_tid_ini_t *ini;
+-	u32 s1 = 0, s2 = 0;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	tx_info = IEEE80211_SKB_CB(p);
+-
+-	/* BMAC_NOTE: For the split driver, second level txstatus comes later
+-	 * So if the ACK was received then wait for the second level else just
+-	 * call the first one
+-	 */
+-	if (txs->status & TX_STATUS_ACK_RCV) {
+-		u8 status_delay = 0;
+-
+-		/* wait till the next 8 bytes of txstatus is available */
+-		while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) {
+-			udelay(1);
+-			status_delay++;
+-			if (status_delay > 10) {
+-				return; /* error condition */
+-			}
+-		}
+-
+-		s2 = R_REG(&wlc->regs->frmtxstatus2);
+-	}
+-
+-	if (likely(scb)) {
+-		scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-		ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
+-		wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
+-	} else {
+-		/* loop through all pkts and free */
+-		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
+-		d11txh_t *txh;
+-		u16 mcl;
+-		while (p) {
+-			tx_info = IEEE80211_SKB_CB(p);
+-			txh = (d11txh_t *) p->data;
+-			mcl = le16_to_cpu(txh->MacTxControlLow);
+-			bcm_pkt_buf_free_skb(p);
+-			/* break out if last packet of ampdu */
+-			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
+-			    TXC_AMPDU_LAST)
+-				break;
+-			p = GETNEXTTXP(wlc, queue);
+-		}
+-		wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+-	}
+-	wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
+-}
+-
+-static void
+-rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info,
+-	    tx_status_t *txs, u8 mcs)
+-{
+-	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
+-	int i;
+-
+-	/* clear the rest of the rates */
+-	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+-		txrate[i].idx = -1;
+-		txrate[i].count = 0;
+-	}
+-}
+-
+-#define SHORTNAME "AMPDU status"
+-
+-static void
+-wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
+-			      struct sk_buff *p, tx_status_t *txs,
+-			      u32 s1, u32 s2)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	struct wlc_info *wlc = ampdu->wlc;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 bitmap[8], queue, tid;
+-	d11txh_t *txh;
+-	u8 *plcp;
+-	struct ieee80211_hdr *h;
+-	u16 seq, start_seq = 0, bindex, index, mcl;
+-	u8 mcs = 0;
+-	bool ba_recd = false, ack_recd = false;
+-	u8 suc_mpdu = 0, tot_mpdu = 0;
+-	uint supr_status;
+-	bool update_rate = true, retry = true, tx_error = false;
+-	u16 mimoantsel = 0;
+-	u8 antselid = 0;
+-	u8 retry_limit, rr_retry_limit;
+-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-#ifdef BCMDBG
+-	u8 hole[AMPDU_MAX_MPDU];
+-	memset(hole, 0, sizeof(hole));
+-#endif
+-
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	tid = (u8) (p->priority);
+-
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	retry_limit = ampdu->retry_limit_tid[tid];
+-	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+-	memset(bitmap, 0, sizeof(bitmap));
+-	queue = txs->frameid & TXFID_QUEUE_MASK;
+-	supr_status = txs->status & TX_STATUS_SUPR_MASK;
+-
+-	if (txs->status & TX_STATUS_ACK_RCV) {
+-		if (TX_STATUS_SUPR_UF == supr_status) {
+-			update_rate = false;
+-		}
+-
+-		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
+-		start_seq = txs->sequence >> SEQNUM_SHIFT;
+-		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
+-		    TX_STATUS_BA_BMAP03_SHIFT;
+-
+-		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
+-		WARN_ON(!(s1 & TX_STATUS_AMPDU));
+-
+-		bitmap[0] |=
+-		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
+-		    TX_STATUS_BA_BMAP47_SHIFT;
+-		bitmap[1] = (s1 >> 8) & 0xff;
+-		bitmap[2] = (s1 >> 16) & 0xff;
+-		bitmap[3] = (s1 >> 24) & 0xff;
+-
+-		bitmap[4] = s2 & 0xff;
+-		bitmap[5] = (s2 >> 8) & 0xff;
+-		bitmap[6] = (s2 >> 16) & 0xff;
+-		bitmap[7] = (s2 >> 24) & 0xff;
+-
+-		ba_recd = true;
+-	} else {
+-		if (supr_status) {
+-			update_rate = false;
+-			if (supr_status == TX_STATUS_SUPR_BADCH) {
+-				wiphy_err(wiphy, "%s: Pkt tx suppressed, "
+-					  "illegal channel possibly %d\n",
+-					  __func__, CHSPEC_CHANNEL(
+-					  wlc->default_bss->chanspec));
+-			} else {
+-				if (supr_status != TX_STATUS_SUPR_FRAG)
+-					wiphy_err(wiphy, "%s: wlc_ampdu_dotx"
+-						  "status:supr_status 0x%x\n",
+-						 __func__, supr_status);
+-			}
+-			/* no need to retry for badch; will fail again */
+-			if (supr_status == TX_STATUS_SUPR_BADCH ||
+-			    supr_status == TX_STATUS_SUPR_EXPTIME) {
+-				retry = false;
+-			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
+-				/* TX underflow : try tuning pre-loading or ampdu size */
+-			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
+-				/* if there were underflows, but pre-loading is not active,
+-				   notify rate adaptation.
+-				 */
+-				if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid])
+-				    > 0) {
+-					tx_error = true;
+-				}
+-			}
+-		} else if (txs->phyerr) {
+-			update_rate = false;
+-			wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy "
+-				  "error (0x%x)\n", wlc->pub->unit,
+-				  txs->phyerr);
+-
+-			if (WL_ERROR_ON()) {
+-				bcm_prpkt("txpkt (AMPDU)", p);
+-				wlc_print_txdesc((d11txh_t *) p->data);
+-			}
+-			wlc_print_txstatus(txs);
+-		}
+-	}
+-
+-	/* loop through all pkts and retry if not acked */
+-	while (p) {
+-		tx_info = IEEE80211_SKB_CB(p);
+-		txh = (d11txh_t *) p->data;
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		plcp = (u8 *) (txh + 1);
+-		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
+-		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
+-
+-		if (tot_mpdu == 0) {
+-			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
+-			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
+-		}
+-
+-		index = TX_SEQ_TO_INDEX(seq);
+-		ack_recd = false;
+-		if (ba_recd) {
+-			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
+-			BCMMSG(wlc->wiphy, "tid %d seq %d,"
+-				" start_seq %d, bindex %d set %d, index %d\n",
+-				tid, seq, start_seq, bindex,
+-				isset(bitmap, bindex), index);
+-			/* if acked then clear bit and free packet */
+-			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
+-			    && isset(bitmap, bindex)) {
+-				ini->tx_in_transit--;
+-				ini->txretry[index] = 0;
+-
+-				/* ampdu_ack_len: number of acked aggregated frames */
+-				/* ampdu_len: number of aggregated frames */
+-				rate_status(wlc, tx_info, txs, mcs);
+-				tx_info->flags |= IEEE80211_TX_STAT_ACK;
+-				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+-				tx_info->status.ampdu_ack_len =
+-					tx_info->status.ampdu_len = 1;
+-
+-				skb_pull(p, D11_PHY_HDR_LEN);
+-				skb_pull(p, D11_TXH_LEN);
+-
+-				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+-							    p);
+-				ack_recd = true;
+-				suc_mpdu++;
+-			}
+-		}
+-		/* either retransmit or send bar if ack not recd */
+-		if (!ack_recd) {
+-			struct ieee80211_tx_rate *txrate =
+-			    tx_info->status.rates;
+-			if (retry && (txrate[0].count < (int)retry_limit)) {
+-				ini->txretry[index]++;
+-				ini->tx_in_transit--;
+-				/* Use high prededence for retransmit to give some punch */
+-				/* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */
+-				wlc_txq_enq(wlc, scb, p,
+-					    WLC_PRIO_TO_HI_PREC(tid));
+-			} else {
+-				/* Retry timeout */
+-				ini->tx_in_transit--;
+-				ieee80211_tx_info_clear_status(tx_info);
+-				tx_info->status.ampdu_ack_len = 0;
+-				tx_info->status.ampdu_len = 1;
+-				tx_info->flags |=
+-				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
+-				skb_pull(p, D11_PHY_HDR_LEN);
+-				skb_pull(p, D11_TXH_LEN);
+-				wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
+-					"transit %d\n", SHORTNAME, seq,
+-					ini->tx_in_transit);
+-				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+-							    p);
+-			}
+-		}
+-		tot_mpdu++;
+-
+-		/* break out if last packet of ampdu */
+-		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
+-		    TXC_AMPDU_LAST)
+-			break;
+-
+-		p = GETNEXTTXP(wlc, queue);
+-	}
+-	wlc_send_q(wlc);
+-
+-	/* update rate state */
+-	antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
+-
+-	wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+-}
+-
+-/* initialize the initiator code for tid */
+-static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
+-						   scb_ampdu_t *scb_ampdu,
+-						   u8 tid, bool override)
+-{
+-	scb_ampdu_tid_ini_t *ini;
+-
+-	/* check for per-tid control of ampdu */
+-	if (!ampdu->ini_enable[tid]) {
+-		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
+-			  __func__, tid);
+-		return NULL;
+-	}
+-
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	ini->tid = tid;
+-	ini->scb = scb_ampdu->scb;
+-	ini->magic = INI_MAGIC;
+-	return ini;
+-}
+-
+-static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on)
+-{
+-	struct wlc_info *wlc = ampdu->wlc;
+-
+-	wlc->pub->_ampdu = false;
+-
+-	if (on) {
+-		if (!N_ENAB(wlc->pub)) {
+-			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
+-				"nmode enabled\n", wlc->pub->unit);
+-			return -ENOTSUPP;
+-		}
+-		if (!wlc_ampdu_cap(ampdu)) {
+-			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
+-				"ampdu capable\n", wlc->pub->unit);
+-			return -ENOTSUPP;
+-		}
+-		wlc->pub->_ampdu = on;
+-	}
+-
+-	return 0;
+-}
+-
+-static bool wlc_ampdu_cap(struct ampdu_info *ampdu)
+-{
+-	if (WLC_PHY_11N_CAP(ampdu->wlc->band))
+-		return true;
+-	else
+-		return false;
+-}
+-
+-static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
+-{
+-	u32 rate, mcs;
+-
+-	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
+-		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
+-		/* 20MHz, No SGI */
+-		rate = MCS_RATE(mcs, false, false);
+-		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
+-		/* 40 MHz, No SGI */
+-		rate = MCS_RATE(mcs, true, false);
+-		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
+-		/* 20MHz, SGI */
+-		rate = MCS_RATE(mcs, false, true);
+-		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
+-		/* 40 MHz, SGI */
+-		rate = MCS_RATE(mcs, true, true);
+-		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
+-	}
+-}
+-
+-void wlc_ampdu_macaddr_upd(struct wlc_info *wlc)
+-{
+-	char template[T_RAM_ACCESS_SZ * 2];
+-
+-	/* driver needs to write the ta in the template; ta is at offset 16 */
+-	memset(template, 0, sizeof(template));
+-	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
+-	wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2),
+-			       template);
+-}
+-
+-bool wlc_aggregatable(struct wlc_info *wlc, u8 tid)
+-{
+-	return wlc->ampdu->ini_enable[tid];
+-}
+-
+-void wlc_ampdu_shm_upd(struct ampdu_info *ampdu)
+-{
+-	struct wlc_info *wlc = ampdu->wlc;
+-
+-	/* Extend ucode internal watchdog timer to match larger received frames */
+-	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
+-	    IEEE80211_HT_MAX_AMPDU_64K) {
+-		wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
+-		wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
+-	} else {
+-		wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
+-		wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
+-	}
+-}
+-
+-/*
+- * callback function that helps flushing ampdu packets from a priority queue
+- */
+-static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
+-{
+-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
+-	struct cb_del_ampdu_pars *ampdu_pars =
+-				 (struct cb_del_ampdu_pars *)arg_a;
+-	bool rc;
+-
+-	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
+-	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
+-		    tx_info->control.sta == ampdu_pars->sta);
+-	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
+-	return rc;
+-}
+-
+-/*
+- * callback function that helps invalidating ampdu packets in a DMA queue
+- */
+-static void dma_cb_fn_ampdu(void *txi, void *arg_a)
+-{
+-	struct ieee80211_sta *sta = arg_a;
+-	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
+-
+-	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
+-	    (tx_info->control.sta == sta || sta == NULL))
+-		tx_info->control.sta = NULL;
+-}
+-
+-/*
+- * When a remote party is no longer available for ampdu communication, any
+- * pending tx ampdu packets in the driver have to be flushed.
+- */
+-void wlc_ampdu_flush(struct wlc_info *wlc,
+-		     struct ieee80211_sta *sta, u16 tid)
+-{
+-	struct wlc_txq_info *qi = wlc->pkt_queue;
+-	struct pktq *pq = &qi->q;
+-	int prec;
+-	struct cb_del_ampdu_pars ampdu_pars;
+-
+-	ampdu_pars.sta = sta;
+-	ampdu_pars.tid = tid;
+-	for (prec = 0; prec < pq->num_prec; prec++) {
+-		bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
+-			    (void *)&ampdu_pars);
+-	}
+-	wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
+deleted file mode 100644
+index 63d403b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_ampdu_h_
+-#define _wlc_ampdu_h_
+-
+-extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc);
+-extern void wlc_ampdu_detach(struct ampdu_info *ampdu);
+-extern int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
+-			 struct sk_buff **aggp, int prec);
+-extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
+-				 struct sk_buff *p, tx_status_t *txs);
+-extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc);
+-extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu);
+-
+-#endif				/* _wlc_ampdu_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
+deleted file mode 100644
+index 111ef32..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
++++ /dev/null
+@@ -1,320 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <wlc_cfg.h>
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-#include <wlioctl.h>
+-
+-#include "d11.h"
+-#include "wlc_rate.h"
+-#include "wlc_key.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wl_dbg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_bmac.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wlc_phy_shim.h"
+-#include "wlc_antsel.h"
+-
+-/* useful macros */
+-#define WLC_ANTSEL_11N_0(ant)	((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
+-#define WLC_ANTSEL_11N_1(ant)	(((ant) & ANT_SELCFG_MASK) & 0xf)
+-#define WLC_ANTIDX_11N(ant)	(((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant)))
+-#define WLC_ANT_ISAUTO_11N(ant)	(((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
+-#define WLC_ANTSEL_11N(ant)	((ant) & ANT_SELCFG_MASK)
+-
+-/* antenna switch */
+-/* defines for no boardlevel antenna diversity */
+-#define ANT_SELCFG_DEF_2x2	0x01	/* default antenna configuration */
+-
+-/* 2x3 antdiv defines and tables for GPIO communication */
+-#define ANT_SELCFG_NUM_2x3	3
+-#define ANT_SELCFG_DEF_2x3	0x01	/* default antenna configuration */
+-
+-/* 2x4 antdiv rev4 defines and tables for GPIO communication */
+-#define ANT_SELCFG_NUM_2x4	4
+-#define ANT_SELCFG_DEF_2x4	0x02	/* default antenna configuration */
+-
+-/* static functions */
+-static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel);
+-static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id);
+-static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
+-static void wlc_antsel_init_cfg(struct antsel_info *asi,
+-				wlc_antselcfg_t *antsel,
+-				bool auto_sel);
+-
+-const u16 mimo_2x4_div_antselpat_tbl[] = {
+-	0, 0, 0x9, 0xa,		/* ant0: 0 ant1: 2,3 */
+-	0, 0, 0x5, 0x6,		/* ant0: 1 ant1: 2,3 */
+-	0, 0, 0, 0,		/* n.a.              */
+-	0, 0, 0, 0		/* n.a.              */
+-};
+-
+-const u8 mimo_2x4_div_antselid_tbl[16] = {
+-	0, 0, 0, 0, 0, 2, 3, 0,
+-	0, 0, 1, 0, 0, 0, 0, 0	/* pat to antselid */
+-};
+-
+-const u16 mimo_2x3_div_antselpat_tbl[] = {
+-	16, 0, 1, 16,		/* ant0: 0 ant1: 1,2 */
+-	16, 16, 16, 16,		/* n.a.              */
+-	16, 2, 16, 16,		/* ant0: 2 ant1: 1   */
+-	16, 16, 16, 16		/* n.a.              */
+-};
+-
+-const u8 mimo_2x3_div_antselid_tbl[16] = {
+-	0, 1, 2, 0, 0, 0, 0, 0,
+-	0, 0, 0, 0, 0, 0, 0, 0	/* pat to antselid */
+-};
+-
+-struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc)
+-{
+-	struct antsel_info *asi;
+-
+-	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
+-	if (!asi) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n",
+-			  wlc->pub->unit);
+-		return NULL;
+-	}
+-
+-	asi->wlc = wlc;
+-	asi->pub = wlc->pub;
+-	asi->antsel_type = ANTSEL_NA;
+-	asi->antsel_avail = false;
+-	asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch");
+-
+-	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
+-		switch (asi->antsel_antswitch) {
+-		case ANTSWITCH_TYPE_1:
+-		case ANTSWITCH_TYPE_2:
+-		case ANTSWITCH_TYPE_3:
+-			/* 4321/2 board with 2x3 switch logic */
+-			asi->antsel_type = ANTSEL_2x3;
+-			/* Antenna selection availability */
+-			if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) ||
+-			    ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) {
+-				asi->antsel_avail = true;
+-			} else
+-			    if (((u16) getintvar(asi->pub->vars, "aa2g") ==
+-				 3)
+-				|| ((u16) getintvar(asi->pub->vars, "aa5g")
+-				    == 3)) {
+-				asi->antsel_avail = false;
+-			} else {
+-				asi->antsel_avail = false;
+-				wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 "
+-					  "board cfg invalid\n");
+-			}
+-			break;
+-		default:
+-			break;
+-		}
+-	} else if ((asi->pub->sromrev == 4) &&
+-		   ((u16) getintvar(asi->pub->vars, "aa2g") == 7) &&
+-		   ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) {
+-		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
+-		asi->antsel_type = ANTSEL_2x3;
+-		asi->antsel_avail = true;
+-	} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
+-		asi->antsel_type = ANTSEL_2x4;
+-		asi->antsel_avail = true;
+-	}
+-
+-	/* Set the antenna selection type for the low driver */
+-	wlc_bmac_antsel_type_set(wlc->hw, asi->antsel_type);
+-
+-	/* Init (auto/manual) antenna selection */
+-	wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true);
+-	wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true);
+-
+-	return asi;
+-}
+-
+-void wlc_antsel_detach(struct antsel_info *asi)
+-{
+-	kfree(asi);
+-}
+-
+-void wlc_antsel_init(struct antsel_info *asi)
+-{
+-	if ((asi->antsel_type == ANTSEL_2x3) ||
+-	    (asi->antsel_type == ANTSEL_2x4))
+-		wlc_antsel_cfgupd(asi, &asi->antcfg_11n);
+-}
+-
+-/* boardlevel antenna selection: init antenna selection structure */
+-static void
+-wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel,
+-		    bool auto_sel)
+-{
+-	if (asi->antsel_type == ANTSEL_2x3) {
+-		u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
+-		    ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
+-		antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x4) {
+-
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
+-		antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
+-
+-	} else {		/* no antenna selection available */
+-
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
+-		antsel->num_antcfg = 0;
+-	}
+-}
+-
+-void
+-wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
+-		      u8 antselid, u8 fbantselid, u8 *antcfg,
+-		      u8 *fbantcfg)
+-{
+-	u8 ant;
+-
+-	/* if use default, assign it and return */
+-	if (usedef) {
+-		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
+-		*fbantcfg = *antcfg;
+-		return;
+-	}
+-
+-	if (!sel) {
+-		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-		*fbantcfg = *antcfg;
+-
+-	} else {
+-		ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-		if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
+-			*antcfg = wlc_antsel_id2antcfg(asi, antselid);
+-			*fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid);
+-		} else {
+-			*antcfg =
+-			    asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-			*fbantcfg = *antcfg;
+-		}
+-	}
+-	return;
+-}
+-
+-/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
+-u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
+-{
+-	u8 antselid = 0;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
+-		return antselid;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
+-		return antselid;
+-	}
+-
+-	return antselid;
+-}
+-
+-/* boardlevel antenna selection: convert id to ant_cfg */
+-static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id)
+-{
+-	u8 antcfg = ANT_SELCFG_DEF_2x2;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
+-		return antcfg;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
+-		return antcfg;
+-	}
+-
+-	return antcfg;
+-}
+-
+-/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
+-static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
+-{
+-	u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg));
+-	u16 mimo_antsel = 0;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
+-		return mimo_antsel;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
+-		return mimo_antsel;
+-	}
+-
+-	return mimo_antsel;
+-}
+-
+-/* boardlevel antenna selection: ucode interface control */
+-static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel)
+-{
+-	struct wlc_info *wlc = asi->wlc;
+-	u8 ant_cfg;
+-	u16 mimo_antsel;
+-
+-	/* 1) Update TX antconfig for all frames that are not unicast data
+-	 *    (aka default TX)
+-	 */
+-	ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
+-	mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+-	wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
+-	/* Update driver stats for currently selected default tx/rx antenna config */
+-	asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
+-
+-	/* 2) Update RX antconfig for all frames that are not unicast data
+-	 *    (aka default RX)
+-	 */
+-	ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
+-	mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+-	wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
+-	/* Update driver stats for currently selected default tx/rx antenna config */
+-	asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
+-
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
+deleted file mode 100644
+index 2470c73..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_antsel_h_
+-#define _wlc_antsel_h_
+-
+-extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc);
+-extern void wlc_antsel_detach(struct antsel_info *asi);
+-extern void wlc_antsel_init(struct antsel_info *asi);
+-extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
+-				  bool sel,
+-				  u8 id, u8 fbid, u8 *antcfg,
+-				  u8 *fbantcfg);
+-extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
+-
+-#endif /* _wlc_antsel_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+deleted file mode 100644
+index 934e7f9..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
++++ /dev/null
+@@ -1,3602 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmwifi.h>
+-#include <aiutils.h>
+-#include <bcmsrom.h>
+-#include <bcmotp.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <wlioctl.h>
+-#include <sbconfig.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#include "wlc_types.h"
+-#include "wlc_pmu.h"
+-#include "d11.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_phy_shim.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wl_ucode.h"
+-#include "wlc_antsel.h"
+-#include "pcie_core.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-#include "wlc_bmac.h"
+-
+-#define	TIMER_INTERVAL_WATCHDOG_BMAC	1000	/* watchdog timer, in unit of ms */
+-
+-#define	SYNTHPU_DLY_APHY_US	3700	/* a phy synthpu_dly time in us */
+-#define	SYNTHPU_DLY_BPHY_US	1050	/* b/g phy synthpu_dly time in us, default */
+-#define	SYNTHPU_DLY_NPHY_US	2048	/* n phy REV3 synthpu_dly time in us, default */
+-#define	SYNTHPU_DLY_LPPHY_US	300	/* lpphy synthpu_dly time in us */
+-
+-#define	SYNTHPU_DLY_PHY_US_QT	100	/* QT synthpu_dly time in us */
+-
+-#ifndef BMAC_DUP_TO_REMOVE
+-#define WLC_RM_WAIT_TX_SUSPEND		4	/* Wait Tx Suspend */
+-
+-#define	ANTCNT			10	/* vanilla M_MAX_ANTCNT value */
+-
+-#endif				/* BMAC_DUP_TO_REMOVE */
+-
+-#define DMAREG(wlc_hw, direction, fifonum) \
+-	((direction == DMA_TX) ? \
+-		(void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \
+-		(void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv))
+-
+-/*
+- * The following table lists the buffer memory allocated to xmt fifos in HW.
+- * the size is in units of 256bytes(one block), total size is HW dependent
+- * ucode has default fifo partition, sw can overwrite if necessary
+- *
+- * This is documented in twiki under the topic UcodeTxFifo. Please ensure
+- * the twiki is updated before making changes.
+- */
+-
+-#define XMTFIFOTBL_STARTREV	20	/* Starting corerev for the fifo size table */
+-
+-static u16 xmtfifo_sz[][NFIFO] = {
+-	{20, 192, 192, 21, 17, 5},	/* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{9, 58, 22, 14, 14, 5},	/* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
+-	{20, 192, 192, 21, 17, 5},	/* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{20, 192, 192, 21, 17, 5},	/* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{9, 58, 22, 14, 14, 5},	/* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
+-};
+-
+-static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode);
+-static void wlc_coreinit(struct wlc_info *wlc);
+-
+-/* used by wlc_wakeucode_init() */
+-static void wlc_write_inits(struct wlc_hw_info *wlc_hw,
+-			    const struct d11init *inits);
+-static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[],
+-			    const uint nbytes);
+-static void wlc_ucode_download(struct wlc_hw_info *wlc);
+-static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw);
+-
+-/* used by wlc_dpc() */
+-static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs,
+-				u32 s2);
+-static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal);
+-static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound);
+-
+-/* used by wlc_down() */
+-static void wlc_flushqueues(struct wlc_info *wlc);
+-
+-static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs);
+-static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw);
+-static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw);
+-static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw,
+-				       uint tx_fifo);
+-static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo);
+-static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo);
+-
+-/* Low Level Prototypes */
+-static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw);
+-static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw);
+-static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want);
+-static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				   u32 sel);
+-static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				  u16 v, u32 sel);
+-static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk);
+-static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme);
+-static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw);
+-static bool wlc_validboardtype(struct wlc_hw_info *wlc);
+-static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw);
+-static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw);
+-static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw);
+-static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init);
+-static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw);
+-static u32 wlc_wlintrsoff(struct wlc_info *wlc);
+-static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask);
+-static void wlc_gpio_init(struct wlc_info *wlc);
+-static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn,
+-				      int len);
+-static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn,
+-				      int len);
+-static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec);
+-static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit);
+-static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit,
+-			     chanspec_t chanspec);
+-static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw,
+-					bool shortslot);
+-static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw);
+-static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw,
+-					     u8 rate);
+-
+-/* === Low Level functions === */
+-
+-void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot)
+-{
+-	wlc_hw->shortslot = shortslot;
+-
+-	if (BAND_2G(wlc_bmac_bandtype(wlc_hw)) && wlc_hw->up) {
+-		wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-		wlc_bmac_update_slot_timing(wlc_hw, shortslot);
+-		wlc_enable_mac(wlc_hw->wlc);
+-	}
+-}
+-
+-/*
+- * Update the slot timing for standard 11b/g (20us slots)
+- * or shortslot 11g (9us slots)
+- * The PSM needs to be suspended for this call.
+- */
+-static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw,
+-					bool shortslot)
+-{
+-	d11regs_t *regs;
+-
+-	regs = wlc_hw->regs;
+-
+-	if (shortslot) {
+-		/* 11g short slot: 11a timing */
+-		W_REG(&regs->ifs_slot, 0x0207);	/* APHY_SLOT_TIME */
+-		wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
+-	} else {
+-		/* 11g long slot: 11b timing */
+-		W_REG(&regs->ifs_slot, 0x0212);	/* BPHY_SLOT_TIME */
+-		wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw)
+-{
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	/* init microcode host flags */
+-	wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs);
+-
+-	/* do band-specific ucode IHR, SHM, and SCR inits */
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			wlc_write_inits(wlc_hw, d11n0bsinitvals16);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-		}
+-	} else {
+-		if (D11REV_IS(wlc_hw->corerev, 24)) {
+-			if (WLCISLCNPHY(wlc_hw->band)) {
+-				wlc_write_inits(wlc_hw, d11lcn0bsinitvals24);
+-			} else
+-				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
+-					  " core rev %d\n", __func__,
+-					  wlc_hw->unit, wlc_hw->corerev);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+-				__func__, wlc_hw->unit, wlc_hw->corerev);
+-		}
+-	}
+-}
+-
+-/* switch to new band but leave it inactive */
+-static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintmask;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
+-
+-	/* disable interrupts */
+-	macintmask = wl_intrsoff(wlc->wl);
+-
+-	/* radio off */
+-	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+-
+-	wlc_bmac_core_phy_clk(wlc_hw, OFF);
+-
+-	wlc_setxband(wlc_hw, bandunit);
+-
+-	return macintmask;
+-}
+-
+-/* Process received frames */
+-/*
+- * Return true if more frames need to be processed. false otherwise.
+- * Param 'bound' indicates max. # frames to process before break out.
+- */
+-static bool
+-wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
+-{
+-	struct sk_buff *p;
+-	struct sk_buff *head = NULL;
+-	struct sk_buff *tail = NULL;
+-	uint n = 0;
+-	uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
+-	wlc_d11rxhdr_t *wlc_rxhdr = NULL;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-	/* gather received frames */
+-	while ((p = dma_rx(wlc_hw->di[fifo]))) {
+-
+-		if (!tail)
+-			head = tail = p;
+-		else {
+-			tail->prev = p;
+-			tail = p;
+-		}
+-
+-		/* !give others some time to run! */
+-		if (++n >= bound_limit)
+-			break;
+-	}
+-
+-	/* post more rbufs */
+-	dma_rxfill(wlc_hw->di[fifo]);
+-
+-	/* process each frame */
+-	while ((p = head) != NULL) {
+-		head = head->prev;
+-		p->prev = NULL;
+-
+-		wlc_rxhdr = (wlc_d11rxhdr_t *) p->data;
+-
+-		/* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
+-		wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
+-
+-		wlc_recv(wlc_hw->wlc, p);
+-	}
+-
+-	return n >= bound_limit;
+-}
+-
+-/* second-level interrupt processing
+- *   Return true if another dpc needs to be re-scheduled. false otherwise.
+- *   Param 'bounded' indicates if applicable loops should be bounded.
+- */
+-bool wlc_dpc(struct wlc_info *wlc, bool bounded)
+-{
+-	u32 macintstatus;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	bool fatal = false;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return false;
+-	}
+-
+-	/* grab and clear the saved software intstatus bits */
+-	macintstatus = wlc->macintstatus;
+-	wlc->macintstatus = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
+-	       wlc_hw->unit, macintstatus);
+-
+-	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
+-
+-	/* BCN template is available */
+-	/* ZZZ: Use AP_ACTIVE ? */
+-	if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated)
+-	    && (macintstatus & MI_BCNTPL)) {
+-		wlc_update_beacon(wlc);
+-	}
+-
+-	/* PMQ entry addition */
+-	if (macintstatus & MI_PMQ) {
+-	}
+-
+-	/* tx status */
+-	if (macintstatus & MI_TFS) {
+-		if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal))
+-			wlc->macintstatus |= MI_TFS;
+-		if (fatal) {
+-			wiphy_err(wiphy, "MI_TFS: fatal\n");
+-			goto fatal;
+-		}
+-	}
+-
+-	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
+-		wlc_tbtt(wlc, regs);
+-
+-	/* ATIM window end */
+-	if (macintstatus & MI_ATIMWINEND) {
+-		BCMMSG(wlc->wiphy, "end of ATIM window\n");
+-		OR_REG(&regs->maccommand, wlc->qvalid);
+-		wlc->qvalid = 0;
+-	}
+-
+-	/* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
+-	if (macintstatus & MI_DMAINT) {
+-		if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) {
+-			wlc->macintstatus |= MI_DMAINT;
+-		}
+-	}
+-
+-	/* TX FIFO suspend/flush completion */
+-	if (macintstatus & MI_TXSTOP) {
+-		if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) {
+-			/* wiphy_err(wiphy, "dpc: fifo_suspend_comlete\n"); */
+-		}
+-	}
+-
+-	/* noise sample collected */
+-	if (macintstatus & MI_BG_NOISE) {
+-		wlc_phy_noise_sample_intr(wlc_hw->band->pi);
+-	}
+-
+-	if (macintstatus & MI_GP0) {
+-		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
+-			"(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
+-
+-		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
+-					__func__, wlc_hw->sih->chip,
+-					wlc_hw->sih->chiprev);
+-		/* big hammer */
+-		wl_init(wlc->wl);
+-	}
+-
+-	/* gptimer timeout */
+-	if (macintstatus & MI_TO) {
+-		W_REG(&regs->gptimer, 0);
+-	}
+-
+-	if (macintstatus & MI_RFDISABLE) {
+-		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
+-		       " RF Disable Input\n", wlc_hw->unit);
+-		wl_rfkill_set_hw_state(wlc->wl);
+-	}
+-
+-	/* send any enq'd tx packets. Just makes sure to jump start tx */
+-	if (!pktq_empty(&wlc->pkt_queue->q))
+-		wlc_send_q(wlc);
+-
+-	/* it isn't done and needs to be resched if macintstatus is non-zero */
+-	return wlc->macintstatus != 0;
+-
+- fatal:
+-	wl_init(wlc->wl);
+-	return wlc->macintstatus != 0;
+-}
+-
+-/* common low-level watchdog code */
+-void wlc_bmac_watchdog(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return;
+-
+-	/* increment second count */
+-	wlc_hw->now++;
+-
+-	/* Check for FIFO error interrupts */
+-	wlc_bmac_fifoerrors(wlc_hw);
+-
+-	/* make sure RX dma has buffers */
+-	dma_rxfill(wlc->hw->di[RX_FIFO]);
+-
+-	wlc_phy_watchdog(wlc_hw->band->pi);
+-}
+-
+-void
+-wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-		      bool mute, struct txpwr_limits *txpwr)
+-{
+-	uint bandunit;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
+-
+-	wlc_hw->chanspec = chanspec;
+-
+-	/* Switch bands if necessary */
+-	if (NBANDS_HW(wlc_hw) > 1) {
+-		bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+-		if (wlc_hw->band->bandunit != bandunit) {
+-			/* wlc_bmac_setband disables other bandunit,
+-			 *  use light band switch if not up yet
+-			 */
+-			if (wlc_hw->up) {
+-				wlc_phy_chanspec_radio_set(wlc_hw->
+-							   bandstate[bandunit]->
+-							   pi, chanspec);
+-				wlc_bmac_setband(wlc_hw, bandunit, chanspec);
+-			} else {
+-				wlc_setxband(wlc_hw, bandunit);
+-			}
+-		}
+-	}
+-
+-	wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
+-
+-	if (!wlc_hw->up) {
+-		if (wlc_hw->clk)
+-			wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
+-						  chanspec);
+-		wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+-	} else {
+-		wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
+-		wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
+-
+-		/* Update muting of the channel */
+-		wlc_bmac_mute(wlc_hw, mute, 0);
+-	}
+-}
+-
+-int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state)
+-{
+-	state->machwcap = wlc_hw->machwcap;
+-
+-	return 0;
+-}
+-
+-static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme)
+-{
+-	uint i;
+-	char name[8];
+-	/* ucode host flag 2 needed for pio mode, independent of band and fifo */
+-	u16 pio_mhf2 = 0;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	uint unit = wlc_hw->unit;
+-	wlc_tunables_t *tune = wlc->pub->tunables;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	/* name and offsets for dma_attach */
+-	snprintf(name, sizeof(name), "wl%d", unit);
+-
+-	if (wlc_hw->di[0] == 0) {	/* Init FIFOs */
+-		uint addrwidth;
+-		int dma_attach_err = 0;
+-		/* Find out the DMA addressing capability and let OS know
+-		 * All the channels within one DMA core have 'common-minimum' same
+-		 * capability
+-		 */
+-		addrwidth =
+-		    dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0));
+-
+-		if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) {
+-			wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_"
+-				  "resources failed\n", unit);
+-			return false;
+-		}
+-
+-		/*
+-		 * FIFO 0
+-		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
+-		 * RX: RX_FIFO (RX data packets)
+-		 */
+-		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
+-					   (wme ? DMAREG(wlc_hw, DMA_TX, 0) :
+-					    NULL), DMAREG(wlc_hw, DMA_RX, 0),
+-					   (wme ? tune->ntxd : 0), tune->nrxd,
+-					   tune->rxbufsz, -1, tune->nrxbufpost,
+-					   WL_HWRXOFF, &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[0]);
+-
+-		/*
+-		 * FIFO 1
+-		 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
+-		 *   (legacy) TX_DATA_FIFO (TX data packets)
+-		 * RX: UNUSED
+-		 */
+-		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 1), NULL,
+-					   tune->ntxd, 0, 0, -1, 0, 0,
+-					   &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[1]);
+-
+-		/*
+-		 * FIFO 2
+-		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
+-		 * RX: UNUSED
+-		 */
+-		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 2), NULL,
+-					   tune->ntxd, 0, 0, -1, 0, 0,
+-					   &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[2]);
+-		/*
+-		 * FIFO 3
+-		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
+-		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
+-		 */
+-		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 3),
+-					   NULL, tune->ntxd, 0, 0, -1,
+-					   0, 0, &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[3]);
+-/* Cleaner to leave this as if with AP defined */
+-
+-		if (dma_attach_err) {
+-			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
+-				  "\n", unit);
+-			return false;
+-		}
+-
+-		/* get pointer to dma engine tx flow control variable */
+-		for (i = 0; i < NFIFO; i++)
+-			if (wlc_hw->di[i])
+-				wlc_hw->txavail[i] =
+-				    (uint *) dma_getvar(wlc_hw->di[i],
+-							"&txavail");
+-	}
+-
+-	/* initial ucode host flags */
+-	wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
+-
+-	return true;
+-}
+-
+-static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw)
+-{
+-	uint j;
+-
+-	for (j = 0; j < NFIFO; j++) {
+-		if (wlc_hw->di[j]) {
+-			dma_detach(wlc_hw->di[j]);
+-			wlc_hw->di[j] = NULL;
+-		}
+-	}
+-}
+-
+-/* low level attach
+- *    run backplane attach, init nvram
+- *    run phy attach
+- *    initialize software state for each core and band
+- *    put the whole chip in reset(driver down state), no clock
+- */
+-int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit,
+-		    bool piomode, void *regsva, uint bustype, void *btparam)
+-{
+-	struct wlc_hw_info *wlc_hw;
+-	d11regs_t *regs;
+-	char *macaddr = NULL;
+-	char *vars;
+-	uint err = 0;
+-	uint j;
+-	bool wme = false;
+-	shared_phy_params_t sha_params;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
+-		device);
+-
+-	wme = true;
+-
+-	wlc_hw = wlc->hw;
+-	wlc_hw->wlc = wlc;
+-	wlc_hw->unit = unit;
+-	wlc_hw->band = wlc_hw->bandstate[0];
+-	wlc_hw->_piomode = piomode;
+-
+-	/* populate struct wlc_hw_info with default values  */
+-	wlc_bmac_info_init(wlc_hw);
+-
+-	/*
+-	 * Do the hardware portion of the attach.
+-	 * Also initialize software state that depends on the particular hardware
+-	 * we are running.
+-	 */
+-	wlc_hw->sih = ai_attach((uint) device, regsva, bustype, btparam,
+-				&wlc_hw->vars, &wlc_hw->vars_size);
+-	if (wlc_hw->sih == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: si_attach failed\n",
+-			  unit);
+-		err = 11;
+-		goto fail;
+-	}
+-	vars = wlc_hw->vars;
+-
+-	/*
+-	 * Get vendid/devid nvram overwrites, which could be different
+-	 * than those the BIOS recognizes for devices on PCMCIA_BUS,
+-	 * SDIO_BUS, and SROMless devices on PCI_BUS.
+-	 */
+-#ifdef BCMBUSTYPE
+-	bustype = BCMBUSTYPE;
+-#endif
+-	if (bustype != SI_BUS) {
+-		char *var;
+-
+-		var = getvar(vars, "vendid");
+-		if (var) {
+-			vendor = (u16) simple_strtoul(var, NULL, 0);
+-			wiphy_err(wiphy, "Overriding vendor id = 0x%x\n",
+-				  vendor);
+-		}
+-		var = getvar(vars, "devid");
+-		if (var) {
+-			u16 devid = (u16) simple_strtoul(var, NULL, 0);
+-			if (devid != 0xffff) {
+-				device = devid;
+-				wiphy_err(wiphy, "Overriding device id = 0x%x"
+-					  "\n", device);
+-			}
+-		}
+-
+-		/* verify again the device is supported */
+-		if (!wlc_chipmatch(vendor, device)) {
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported "
+-				"vendor/device (0x%x/0x%x)\n",
+-				 unit, vendor, device);
+-			err = 12;
+-			goto fail;
+-		}
+-	}
+-
+-	wlc_hw->vendorid = vendor;
+-	wlc_hw->deviceid = device;
+-
+-	/* set bar0 window to point at D11 core */
+-	wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
+-	wlc_hw->corerev = ai_corerev(wlc_hw->sih);
+-
+-	regs = wlc_hw->regs;
+-
+-	wlc->regs = wlc_hw->regs;
+-
+-	/* validate chip, chiprev and corerev */
+-	if (!wlc_isgoodchip(wlc_hw)) {
+-		err = 13;
+-		goto fail;
+-	}
+-
+-	/* initialize power control registers */
+-	ai_clkctl_init(wlc_hw->sih);
+-
+-	/* request fastclock and force fastclock for the rest of attach
+-	 * bring the d11 core out of reset.
+-	 *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false;
+-	 *   But it will be called again inside wlc_corereset, after d11 is out of reset.
+-	 */
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	if (!wlc_bmac_validate_chip_access(wlc_hw)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: validate_chip_access "
+-			"failed\n", unit);
+-		err = 14;
+-		goto fail;
+-	}
+-
+-	/* get the board rev, used just below */
+-	j = getintvar(vars, "boardrev");
+-	/* promote srom boardrev of 0xFF to 1 */
+-	if (j == BOARDREV_PROMOTABLE)
+-		j = BOARDREV_PROMOTED;
+-	wlc_hw->boardrev = (u16) j;
+-	if (!wlc_validboardtype(wlc_hw)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported Broadcom "
+-			"board type (0x%x)" " or revision level (0x%x)\n",
+-			 unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
+-		err = 15;
+-		goto fail;
+-	}
+-	wlc_hw->sromrev = (u8) getintvar(vars, "sromrev");
+-	wlc_hw->boardflags = (u32) getintvar(vars, "boardflags");
+-	wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2");
+-
+-	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
+-		wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED);
+-
+-	if ((wlc_hw->sih->bustype == PCI_BUS)
+-	    && (ai_pci_war16165(wlc_hw->sih)))
+-		wlc->war16165 = true;
+-
+-	/* check device id(srom, nvram etc.) to set bands */
+-	if (wlc_hw->deviceid == BCM43224_D11N_ID) {
+-		/* Dualband boards */
+-		wlc_hw->_nbands = 2;
+-	} else
+-		wlc_hw->_nbands = 1;
+-
+-	if ((wlc_hw->sih->chip == BCM43225_CHIP_ID))
+-		wlc_hw->_nbands = 1;
+-
+-	/* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the
+-	 * init of these values
+-	 */
+-	wlc->vendorid = wlc_hw->vendorid;
+-	wlc->deviceid = wlc_hw->deviceid;
+-	wlc->pub->sih = wlc_hw->sih;
+-	wlc->pub->corerev = wlc_hw->corerev;
+-	wlc->pub->sromrev = wlc_hw->sromrev;
+-	wlc->pub->boardrev = wlc_hw->boardrev;
+-	wlc->pub->boardflags = wlc_hw->boardflags;
+-	wlc->pub->boardflags2 = wlc_hw->boardflags2;
+-	wlc->pub->_nbands = wlc_hw->_nbands;
+-
+-	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
+-
+-	if (wlc_hw->physhim == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_shim_attach "
+-			"failed\n", unit);
+-		err = 25;
+-		goto fail;
+-	}
+-
+-	/* pass all the parameters to wlc_phy_shared_attach in one struct */
+-	sha_params.sih = wlc_hw->sih;
+-	sha_params.physhim = wlc_hw->physhim;
+-	sha_params.unit = unit;
+-	sha_params.corerev = wlc_hw->corerev;
+-	sha_params.vars = vars;
+-	sha_params.vid = wlc_hw->vendorid;
+-	sha_params.did = wlc_hw->deviceid;
+-	sha_params.chip = wlc_hw->sih->chip;
+-	sha_params.chiprev = wlc_hw->sih->chiprev;
+-	sha_params.chippkg = wlc_hw->sih->chippkg;
+-	sha_params.sromrev = wlc_hw->sromrev;
+-	sha_params.boardtype = wlc_hw->sih->boardtype;
+-	sha_params.boardrev = wlc_hw->boardrev;
+-	sha_params.boardvendor = wlc_hw->sih->boardvendor;
+-	sha_params.boardflags = wlc_hw->boardflags;
+-	sha_params.boardflags2 = wlc_hw->boardflags2;
+-	sha_params.bustype = wlc_hw->sih->bustype;
+-	sha_params.buscorerev = wlc_hw->sih->buscorerev;
+-
+-	/* alloc and save pointer to shared phy state area */
+-	wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
+-	if (!wlc_hw->phy_sh) {
+-		err = 16;
+-		goto fail;
+-	}
+-
+-	/* initialize software state for each core and band */
+-	for (j = 0; j < NBANDS_HW(wlc_hw); j++) {
+-		/*
+-		 * band0 is always 2.4Ghz
+-		 * band1, if present, is 5Ghz
+-		 */
+-
+-		/* So if this is a single band 11a card, use band 1 */
+-		if (IS_SINGLEBAND_5G(wlc_hw->deviceid))
+-			j = BAND_5G_INDEX;
+-
+-		wlc_setxband(wlc_hw, j);
+-
+-		wlc_hw->band->bandunit = j;
+-		wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+-		wlc->band->bandunit = j;
+-		wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+-		wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
+-
+-		wlc_hw->machwcap = R_REG(&regs->machwcap);
+-		wlc_hw->machwcap_backup = wlc_hw->machwcap;
+-
+-		/* init tx fifo size */
+-		wlc_hw->xmtfifo_sz =
+-		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
+-
+-		/* Get a phy for this band */
+-		wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh,
+-			(void *)regs, wlc_bmac_bandtype(wlc_hw), vars,
+-			wlc->wiphy);
+-		if (wlc_hw->band->pi == NULL) {
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_"
+-				  "attach failed\n", unit);
+-			err = 17;
+-			goto fail;
+-		}
+-
+-		wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
+-
+-		wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
+-				       &wlc_hw->band->phyrev,
+-				       &wlc_hw->band->radioid,
+-				       &wlc_hw->band->radiorev);
+-		wlc_hw->band->abgphy_encore =
+-		    wlc_phy_get_encore(wlc_hw->band->pi);
+-		wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
+-		wlc_hw->band->core_flags =
+-		    wlc_phy_get_coreflags(wlc_hw->band->pi);
+-
+-		/* verify good phy_type & supported phy revision */
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			if (NCONF_HAS(wlc_hw->band->phyrev))
+-				goto good_phy;
+-			else
+-				goto bad_phy;
+-		} else if (WLCISLCNPHY(wlc_hw->band)) {
+-			if (LCNCONF_HAS(wlc_hw->band->phyrev))
+-				goto good_phy;
+-			else
+-				goto bad_phy;
+-		} else {
+- bad_phy:
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: unsupported "
+-				  "phy type/rev (%d/%d)\n", unit,
+-				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
+-			err = 18;
+-			goto fail;
+-		}
+-
+- good_phy:
+-		/* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the
+-		 * high level attach. However we can not make that change until all low level access
+-		 * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping
+-		 * wlc_hw->band->pi as well for incremental update of low level fns, and cut over
+-		 * low only init when all fns updated.
+-		 */
+-		wlc->band->pi = wlc_hw->band->pi;
+-		wlc->band->phytype = wlc_hw->band->phytype;
+-		wlc->band->phyrev = wlc_hw->band->phyrev;
+-		wlc->band->radioid = wlc_hw->band->radioid;
+-		wlc->band->radiorev = wlc_hw->band->radiorev;
+-
+-		/* default contention windows size limits */
+-		wlc_hw->band->CWmin = APHY_CWMIN;
+-		wlc_hw->band->CWmax = PHY_CWMAX;
+-
+-		if (!wlc_bmac_attach_dmapio(wlc, j, wme)) {
+-			err = 19;
+-			goto fail;
+-		}
+-	}
+-
+-	/* disable core to match driver "down" state */
+-	wlc_coredisable(wlc_hw);
+-
+-	/* Match driver "down" state */
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_down(wlc_hw->sih);
+-
+-	/* register sb interrupt callback functions */
+-	ai_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff,
+-				  (void *)wlc_wlintrsrestore, NULL, wlc);
+-
+-	/* turn off pll and xtal to match driver "down" state */
+-	wlc_bmac_xtal(wlc_hw, OFF);
+-
+-	/* *********************************************************************
+-	 * The hardware is in the DOWN state at this point. D11 core
+-	 * or cores are in reset with clocks off, and the board PLLs
+-	 * are off if possible.
+-	 *
+-	 * Beyond this point, wlc->sbclk == false and chip registers
+-	 * should not be touched.
+-	 *********************************************************************
+-	 */
+-
+-	/* init etheraddr state variables */
+-	macaddr = wlc_get_macaddr(wlc_hw);
+-	if (macaddr == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: macaddr not found\n",
+-			  unit);
+-		err = 21;
+-		goto fail;
+-	}
+-	bcm_ether_atoe(macaddr, wlc_hw->etheraddr);
+-	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
+-	    is_zero_ether_addr(wlc_hw->etheraddr)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n",
+-			  unit, macaddr);
+-		err = 22;
+-		goto fail;
+-	}
+-
+-	BCMMSG(wlc->wiphy,
+-		 "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
+-		 wlc_hw->deviceid, wlc_hw->_nbands,
+-		 wlc_hw->sih->boardtype, macaddr);
+-
+-	return err;
+-
+- fail:
+-	wiphy_err(wiphy, "wl%d: wlc_bmac_attach: failed with err %d\n", unit,
+-		  err);
+-	return err;
+-}
+-
+-/*
+- * Initialize wlc_info default values ...
+- * may get overrides later in this function
+- *  BMAC_NOTES, move low out and resolve the dangling ones
+- */
+-static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw)
+-{
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-
+-	/* set default sw macintmask value */
+-	wlc->defmacintmask = DEF_MACINTMASK;
+-
+-	/* various 802.11g modes */
+-	wlc_hw->shortslot = false;
+-
+-	wlc_hw->SFBL = RETRY_SHORT_FB;
+-	wlc_hw->LFBL = RETRY_LONG_FB;
+-
+-	/* default mac retry limits */
+-	wlc_hw->SRL = RETRY_SHORT_DEF;
+-	wlc_hw->LRL = RETRY_LONG_DEF;
+-	wlc_hw->chanspec = CH20MHZ_CHSPEC(1);
+-}
+-
+-/*
+- * low level detach
+- */
+-int wlc_bmac_detach(struct wlc_info *wlc)
+-{
+-	uint i;
+-	struct wlc_hwband *band;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	int callbacks;
+-
+-	callbacks = 0;
+-
+-	if (wlc_hw->sih) {
+-		/* detach interrupt sync mechanism since interrupt is disabled and per-port
+-		 * interrupt object may has been freed. this must be done before sb core switch
+-		 */
+-		ai_deregister_intr_callback(wlc_hw->sih);
+-
+-		if (wlc_hw->sih->bustype == PCI_BUS)
+-			ai_pci_sleep(wlc_hw->sih);
+-	}
+-
+-	wlc_bmac_detach_dmapio(wlc_hw);
+-
+-	band = wlc_hw->band;
+-	for (i = 0; i < NBANDS_HW(wlc_hw); i++) {
+-		if (band->pi) {
+-			/* Detach this band's phy */
+-			wlc_phy_detach(band->pi);
+-			band->pi = NULL;
+-		}
+-		band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
+-	}
+-
+-	/* Free shared phy state */
+-	wlc_phy_shared_detach(wlc_hw->phy_sh);
+-
+-	wlc_phy_shim_detach(wlc_hw->physhim);
+-
+-	/* free vars */
+-	kfree(wlc_hw->vars);
+-	wlc_hw->vars = NULL;
+-
+-	if (wlc_hw->sih) {
+-		ai_detach(wlc_hw->sih);
+-		wlc_hw->sih = NULL;
+-	}
+-
+-	return callbacks;
+-
+-}
+-
+-void wlc_bmac_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* reset the core */
+-	if (!DEVICEREMOVED(wlc_hw->wlc))
+-		wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	/* purge the dma rings */
+-	wlc_flushqueues(wlc_hw->wlc);
+-
+-	wlc_reset_bmac_done(wlc_hw->wlc);
+-}
+-
+-void
+-wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-			  bool mute) {
+-	u32 macintmask;
+-	bool fastclk;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* request FAST clock if not on */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/* disable interrupts */
+-	macintmask = wl_intrsoff(wlc->wl);
+-
+-	/* set up the specified band and chanspec */
+-	wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec));
+-	wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+-
+-	/* do one-time phy inits and calibration */
+-	wlc_phy_cal_init(wlc_hw->band->pi);
+-
+-	/* core-specific initialization */
+-	wlc_coreinit(wlc);
+-
+-	/* suspend the tx fifos and mute the phy for preism cac time */
+-	if (mute)
+-		wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
+-
+-	/* band-specific inits */
+-	wlc_bmac_bsinit(wlc, chanspec);
+-
+-	/* restore macintmask */
+-	wl_intrsrestore(wlc->wl, macintmask);
+-
+-	/* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended
+-	 * and wlc_enable_mac() will clear this override bit.
+-	 */
+-	mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-
+-	/*
+-	 * initialize mac_suspend_depth to 1 to match ucode initial suspended state
+-	 */
+-	wlc_hw->mac_suspend_depth = 1;
+-
+-	/* restore the clk */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw)
+-{
+-	uint coremask;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/*
+-	 * Enable pll and xtal, initialize the power control registers,
+-	 * and force fastclock for the remainder of wlc_up().
+-	 */
+-	wlc_bmac_xtal(wlc_hw, ON);
+-	ai_clkctl_init(wlc_hw->sih);
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/*
+-	 * Configure pci/pcmcia here instead of in wlc_attach()
+-	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
+-	 */
+-	coremask = (1 << wlc_hw->wlc->core->coreidx);
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_setup(wlc_hw->sih, coremask);
+-
+-	/*
+-	 * Need to read the hwradio status here to cover the case where the system
+-	 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+-	 */
+-	if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) {
+-		/* put SB PCI in down state again */
+-		if (wlc_hw->sih->bustype == PCI_BUS)
+-			ai_pci_down(wlc_hw->sih);
+-		wlc_bmac_xtal(wlc_hw, OFF);
+-		return -ENOMEDIUM;
+-	}
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_up(wlc_hw->sih);
+-
+-	/* reset the d11 core */
+-	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	return 0;
+-}
+-
+-int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	wlc_hw->up = true;
+-	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
+-
+-	/* FULLY enable dynamic power control and d11 core interrupt */
+-	wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-	wl_intrson(wlc_hw->wlc->wl);
+-	return 0;
+-}
+-
+-int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw)
+-{
+-	bool dev_gone;
+-	uint callbacks = 0;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return callbacks;
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	/* disable interrupts */
+-	if (dev_gone)
+-		wlc_hw->wlc->macintmask = 0;
+-	else {
+-		/* now disable interrupts */
+-		wl_intrsoff(wlc_hw->wlc->wl);
+-
+-		/* ensure we're running on the pll clock again */
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-	}
+-	/* down phy at the last of this stage */
+-	callbacks += wlc_phy_down(wlc_hw->band->pi);
+-
+-	return callbacks;
+-}
+-
+-int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw)
+-{
+-	uint callbacks = 0;
+-	bool dev_gone;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return callbacks;
+-
+-	wlc_hw->up = false;
+-	wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	if (dev_gone) {
+-		wlc_hw->sbclk = false;
+-		wlc_hw->clk = false;
+-		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-
+-		/* reclaim any posted packets */
+-		wlc_flushqueues(wlc_hw->wlc);
+-	} else {
+-
+-		/* Reset and disable the core */
+-		if (ai_iscoreup(wlc_hw->sih)) {
+-			if (R_REG(&wlc_hw->regs->maccontrol) &
+-			    MCTL_EN_MAC)
+-				wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-			callbacks += wl_reset(wlc_hw->wlc->wl);
+-			wlc_coredisable(wlc_hw);
+-		}
+-
+-		/* turn off primary xtal and pll */
+-		if (!wlc_hw->noreset) {
+-			if (wlc_hw->sih->bustype == PCI_BUS)
+-				ai_pci_down(wlc_hw->sih);
+-			wlc_bmac_xtal(wlc_hw, OFF);
+-		}
+-	}
+-
+-	return callbacks;
+-}
+-
+-void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw)
+-{
+-	/* delay before first read of ucode state */
+-	udelay(40);
+-
+-	/* wait until ucode is no longer asleep */
+-	SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) ==
+-		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
+-}
+-
+-void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea)
+-{
+-	memcpy(ea, wlc_hw->etheraddr, ETH_ALEN);
+-}
+-
+-static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw)
+-{
+-	return wlc_hw->band->bandtype;
+-}
+-
+-/* control chip clock to save power, enable dynamic clock or force fast clock */
+-static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode)
+-{
+-	if (PMUCTL_ENAB(wlc_hw->sih)) {
+-		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane,
+-		 *  but mac core will still run on ALP(not HT) when it enters powersave mode,
+-		 *      which means the FCA bit may not be set.
+-		 *      should wakeup mac if driver wants it to run on HT.
+-		 */
+-
+-		if (wlc_hw->clk) {
+-			if (mode == CLK_FAST) {
+-				OR_REG(&wlc_hw->regs->clk_ctl_st,
+-				       CCS_FORCEHT);
+-
+-				udelay(64);
+-
+-				SPINWAIT(((R_REG
+-					   (&wlc_hw->regs->
+-					    clk_ctl_st) & CCS_HTAVAIL) == 0),
+-					 PMU_MAX_TRANSITION_DLY);
+-				WARN_ON(!(R_REG
+-					  (&wlc_hw->regs->
+-					   clk_ctl_st) & CCS_HTAVAIL));
+-			} else {
+-				if ((wlc_hw->sih->pmurev == 0) &&
+-				    (R_REG
+-				     (&wlc_hw->regs->
+-				      clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
+-					SPINWAIT(((R_REG
+-						   (&wlc_hw->regs->
+-						    clk_ctl_st) & CCS_HTAVAIL)
+-						  == 0),
+-						 PMU_MAX_TRANSITION_DLY);
+-				AND_REG(&wlc_hw->regs->clk_ctl_st,
+-					~CCS_FORCEHT);
+-			}
+-		}
+-		wlc_hw->forcefastclk = (mode == CLK_FAST);
+-	} else {
+-
+-		/* old chips w/o PMU, force HT through cc,
+-		 * then use FCA to verify mac is running fast clock
+-		 */
+-
+-		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
+-
+-		/* check fast clock is available (if core is not in reset) */
+-		if (wlc_hw->forcefastclk && wlc_hw->clk)
+-			WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
+-				  SISF_FCLKA));
+-
+-		/* keep the ucode wake bit on if forcefastclk is on
+-		 * since we do not want ucode to put us back to slow clock
+-		 * when it dozes for PM mode.
+-		 * Code below matches the wake override bit with current forcefastclk state
+-		 * Only setting bit in wake_override instead of waking ucode immediately
+-		 * since old code (wlc.c 1.4499) had this behavior. Older code set
+-		 * wlc->forcefastclk but only had the wake happen if the wakup_ucode work
+-		 * (protected by an up check) was executed just below.
+-		 */
+-		if (wlc_hw->forcefastclk)
+-			mboolset(wlc_hw->wake_override,
+-				 WLC_WAKE_OVERRIDE_FORCEFAST);
+-		else
+-			mboolclr(wlc_hw->wake_override,
+-				 WLC_WAKE_OVERRIDE_FORCEFAST);
+-	}
+-}
+-
+-/* set initial host flags value */
+-static void
+-wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	memset(mhfs, 0, MHFMAX * sizeof(u16));
+-
+-	mhfs[MHF2] |= mhf2_init;
+-
+-	/* prohibit use of slowclock on multifunction boards */
+-	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
+-		mhfs[MHF1] |= MHF1_FORCEFASTCLK;
+-
+-	if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
+-		mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
+-		mhfs[MHF1] |= MHF1_IQSWAP_WAR;
+-	}
+-}
+-
+-/* set or clear ucode host flag bits
+- * it has an optimization for no-change write
+- * it only writes through shared memory when the core has clock;
+- * pre-CLK changes should use wlc_write_mhf to get around the optimization
+- *
+- *
+- * bands values are: WLC_BAND_AUTO <--- Current band only
+- *                   WLC_BAND_5G   <--- 5G band only
+- *                   WLC_BAND_2G   <--- 2G band only
+- *                   WLC_BAND_ALL  <--- All bands
+- */
+-void
+-wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val,
+-	     int bands)
+-{
+-	u16 save;
+-	u16 addr[MHFMAX] = {
+-		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+-		M_HOST_FLAGS5
+-	};
+-	struct wlc_hwband *band;
+-
+-	if ((val & ~mask) || idx >= MHFMAX)
+-		return; /* error condition */
+-
+-	switch (bands) {
+-		/* Current band only or all bands,
+-		 * then set the band to current band
+-		 */
+-	case WLC_BAND_AUTO:
+-	case WLC_BAND_ALL:
+-		band = wlc_hw->band;
+-		break;
+-	case WLC_BAND_5G:
+-		band = wlc_hw->bandstate[BAND_5G_INDEX];
+-		break;
+-	case WLC_BAND_2G:
+-		band = wlc_hw->bandstate[BAND_2G_INDEX];
+-		break;
+-	default:
+-		band = NULL;	/* error condition */
+-	}
+-
+-	if (band) {
+-		save = band->mhfs[idx];
+-		band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
+-
+-		/* optimization: only write through if changed, and
+-		 * changed band is the current band
+-		 */
+-		if (wlc_hw->clk && (band->mhfs[idx] != save)
+-		    && (band == wlc_hw->band))
+-			wlc_bmac_write_shm(wlc_hw, addr[idx],
+-					   (u16) band->mhfs[idx]);
+-	}
+-
+-	if (bands == WLC_BAND_ALL) {
+-		wlc_hw->bandstate[0]->mhfs[idx] =
+-		    (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
+-		wlc_hw->bandstate[1]->mhfs[idx] =
+-		    (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
+-	}
+-}
+-
+-u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands)
+-{
+-	struct wlc_hwband *band;
+-
+-	if (idx >= MHFMAX)
+-		return 0; /* error condition */
+-	switch (bands) {
+-	case WLC_BAND_AUTO:
+-		band = wlc_hw->band;
+-		break;
+-	case WLC_BAND_5G:
+-		band = wlc_hw->bandstate[BAND_5G_INDEX];
+-		break;
+-	case WLC_BAND_2G:
+-		band = wlc_hw->bandstate[BAND_2G_INDEX];
+-		break;
+-	default:
+-		band = NULL;		/* error condition */
+-	}
+-
+-	if (!band)
+-		return 0;
+-
+-	return band->mhfs[idx];
+-}
+-
+-static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs)
+-{
+-	u8 idx;
+-	u16 addr[] = {
+-		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+-		M_HOST_FLAGS5
+-	};
+-
+-	for (idx = 0; idx < MHFMAX; idx++) {
+-		wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]);
+-	}
+-}
+-
+-/* set the maccontrol register to desired reset state and
+- * initialize the sw cache of the register
+- */
+-static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	/* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
+-	wlc_hw->maccontrol = 0;
+-	wlc_hw->suspended_fifos = 0;
+-	wlc_hw->wake_override = 0;
+-	wlc_hw->mute_override = 0;
+-	wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
+-}
+-
+-/* set or clear maccontrol bits */
+-void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val)
+-{
+-	u32 maccontrol;
+-	u32 new_maccontrol;
+-
+-	if (val & ~mask)
+-		return; /* error condition */
+-	maccontrol = wlc_hw->maccontrol;
+-	new_maccontrol = (maccontrol & ~mask) | val;
+-
+-	/* if the new maccontrol value is the same as the old, nothing to do */
+-	if (new_maccontrol == maccontrol)
+-		return;
+-
+-	/* something changed, cache the new value */
+-	wlc_hw->maccontrol = new_maccontrol;
+-
+-	/* write the new values with overrides applied */
+-	wlc_mctrl_write(wlc_hw);
+-}
+-
+-/* write the software state of maccontrol and overrides to the maccontrol register */
+-static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw)
+-{
+-	u32 maccontrol = wlc_hw->maccontrol;
+-
+-	/* OR in the wake bit if overridden */
+-	if (wlc_hw->wake_override)
+-		maccontrol |= MCTL_WAKE;
+-
+-	/* set AP and INFRA bits for mute if needed */
+-	if (wlc_hw->mute_override) {
+-		maccontrol &= ~(MCTL_AP);
+-		maccontrol |= MCTL_INFRA;
+-	}
+-
+-	W_REG(&wlc_hw->regs->maccontrol, maccontrol);
+-}
+-
+-void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit)
+-{
+-	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
+-		mboolset(wlc_hw->wake_override, override_bit);
+-		return;
+-	}
+-
+-	mboolset(wlc_hw->wake_override, override_bit);
+-
+-	wlc_mctrl_write(wlc_hw);
+-	wlc_bmac_wait_for_wake(wlc_hw);
+-
+-	return;
+-}
+-
+-void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit)
+-{
+-	mboolclr(wlc_hw->wake_override, override_bit);
+-
+-	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-
+-	return;
+-}
+-
+-/* When driver needs ucode to stop beaconing, it has to make sure that
+- * MCTL_AP is clear and MCTL_INFRA is set
+- * Mode           MCTL_AP        MCTL_INFRA
+- * AP                1              1
+- * STA               0              1 <--- This will ensure no beacons
+- * IBSS              0              0
+- */
+-static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw)
+-{
+-	wlc_hw->mute_override = 1;
+-
+-	/* if maccontrol already has AP == 0 and INFRA == 1 without this
+-	 * override, then there is no change to write
+-	 */
+-	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-
+-	return;
+-}
+-
+-/* Clear the override on AP and INFRA bits */
+-static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw)
+-{
+-	if (wlc_hw->mute_override == 0)
+-		return;
+-
+-	wlc_hw->mute_override = 0;
+-
+-	/* if maccontrol already has AP == 0 and INFRA == 1 without this
+-	 * override, then there is no change to write
+-	 */
+-	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-}
+-
+-/*
+- * Write a MAC address to the given match reg offset in the RXE match engine.
+- */
+-void
+-wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset,
+-		       const u8 *addr)
+-{
+-	d11regs_t *regs;
+-	u16 mac_l;
+-	u16 mac_m;
+-	u16 mac_h;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: wlc_bmac_set_addrmatch\n",
+-		 wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-	mac_l = addr[0] | (addr[1] << 8);
+-	mac_m = addr[2] | (addr[3] << 8);
+-	mac_h = addr[4] | (addr[5] << 8);
+-
+-	/* enter the MAC addr into the RXE match registers */
+-	W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
+-	W_REG(&regs->rcm_mat_data, mac_l);
+-	W_REG(&regs->rcm_mat_data, mac_m);
+-	W_REG(&regs->rcm_mat_data, mac_h);
+-
+-}
+-
+-void
+-wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len,
+-			    void *buf)
+-{
+-	d11regs_t *regs;
+-	u32 word;
+-	bool be_bit;
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-	W_REG(&regs->tplatewrptr, offset);
+-
+-	/* if MCTL_BIGEND bit set in mac control register,
+-	 * the chip swaps data in fifo, as well as data in
+-	 * template ram
+-	 */
+-	be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;
+-
+-	while (len > 0) {
+-		memcpy(&word, buf, sizeof(u32));
+-
+-		if (be_bit)
+-			word = cpu_to_be32(word);
+-		else
+-			word = cpu_to_le32(word);
+-
+-		W_REG(&regs->tplatewrdata, word);
+-
+-		buf = (u8 *) buf + sizeof(u32);
+-		len -= sizeof(u32);
+-	}
+-}
+-
+-void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin)
+-{
+-	wlc_hw->band->CWmin = newmin;
+-
+-	W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
+-	(void)R_REG(&wlc_hw->regs->objaddr);
+-	W_REG(&wlc_hw->regs->objdata, newmin);
+-}
+-
+-void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax)
+-{
+-	wlc_hw->band->CWmax = newmax;
+-
+-	W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
+-	(void)R_REG(&wlc_hw->regs->objaddr);
+-	W_REG(&wlc_hw->regs->objdata, newmax);
+-}
+-
+-void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw)
+-{
+-	bool fastclk;
+-
+-	/* request FAST clock if not on */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
+-
+-	wlc_bmac_phy_reset(wlc_hw);
+-	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
+-
+-	/* restore the clk */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-static void
+-wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
+-				    bcn);
+-	/* write beacon length to SCR */
+-	wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
+-	/* mark beacon0 valid */
+-	OR_REG(&regs->maccommand, MCMD_BCN0VLD);
+-}
+-
+-static void
+-wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
+-				    bcn);
+-	/* write beacon length to SCR */
+-	wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
+-	/* mark beacon1 valid */
+-	OR_REG(&regs->maccommand, MCMD_BCN1VLD);
+-}
+-
+-/* mac is assumed to be suspended at this point */
+-void
+-wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len,
+-			       bool both)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	if (both) {
+-		wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+-		wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+-	} else {
+-		/* bcn 0 */
+-		if (!(R_REG(&regs->maccommand) & MCMD_BCN0VLD))
+-			wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+-		/* bcn 1 */
+-		else if (!
+-			 (R_REG(&regs->maccommand) & MCMD_BCN1VLD))
+-			wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw)
+-{
+-	u16 v;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	/* update SYNTHPU_DLY */
+-
+-	if (WLCISLCNPHY(wlc->band)) {
+-		v = SYNTHPU_DLY_LPPHY_US;
+-	} else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) {
+-		v = SYNTHPU_DLY_NPHY_US;
+-	} else {
+-		v = SYNTHPU_DLY_BPHY_US;
+-	}
+-
+-	wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
+-}
+-
+-/* band-specific init */
+-static void
+-WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc_hw->band->bandunit);
+-
+-	wlc_ucode_bsinit(wlc_hw);
+-
+-	wlc_phy_init(wlc_hw->band->pi, chanspec);
+-
+-	wlc_ucode_txant_set(wlc_hw);
+-
+-	/* cwmin is band-specific, update hardware with value for current band */
+-	wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
+-	wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
+-
+-	wlc_bmac_update_slot_timing(wlc_hw,
+-				    BAND_5G(wlc_hw->band->
+-					    bandtype) ? true : wlc_hw->
+-				    shortslot);
+-
+-	/* write phytype and phyvers */
+-	wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
+-	wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
+-
+-	/* initialize the txphyctl1 rate table since shmem is shared between bands */
+-	wlc_upd_ofdm_pctl1_table(wlc_hw);
+-
+-	wlc_bmac_upd_synthpu(wlc_hw);
+-}
+-
+-static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
+-
+-	wlc_hw->phyclk = clk;
+-
+-	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
+-
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
+-			       (SICF_PRST | SICF_FGC));
+-		udelay(1);
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
+-		udelay(1);
+-
+-	} else {		/* take phy out of reset */
+-
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
+-		udelay(1);
+-		ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
+-		udelay(1);
+-
+-	}
+-}
+-
+-/* Perform a soft reset of the PHY PLL */
+-void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_addr), ~0, 0);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 4);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
+-	udelay(1);
+-}
+-
+-/* light way to turn on phy clock without reset for NPHY only
+- *  refer to wlc_bmac_core_phy_clk for full version
+- */
+-void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	/* support(necessary for NPHY and HYPHY) only */
+-	if (!WLCISNPHY(wlc_hw->band))
+-		return;
+-
+-	if (ON == clk)
+-		ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
+-	else
+-		ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
+-
+-}
+-
+-void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	if (ON == clk)
+-		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
+-	else
+-		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
+-}
+-
+-void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	wlc_phy_t *pih = wlc_hw->band->pi;
+-	u32 phy_bw_clkbits;
+-	bool phy_in_reset = false;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (pih == NULL)
+-		return;
+-
+-	phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
+-
+-	/* Specific reset sequence required for NPHY rev 3 and 4 */
+-	if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
+-	    NREV_LE(wlc_hw->band->phyrev, 4)) {
+-		/* Set the PHY bandwidth */
+-		ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
+-
+-		udelay(1);
+-
+-		/* Perform a soft reset of the PHY PLL */
+-		wlc_bmac_core_phypll_reset(wlc_hw);
+-
+-		/* reset the PHY */
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
+-			       (SICF_PRST | SICF_PCLKE));
+-		phy_in_reset = true;
+-	} else {
+-
+-		ai_core_cflags(wlc_hw->sih,
+-			       (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
+-			       (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
+-	}
+-
+-	udelay(2);
+-	wlc_bmac_core_phy_clk(wlc_hw, ON);
+-
+-	if (pih)
+-		wlc_phy_anacore(pih, ON);
+-}
+-
+-/* switch to and initialize new band */
+-static void
+-WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit,
+-				chanspec_t chanspec) {
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	u32 macintmask;
+-
+-	/* Enable the d11 core before accessing it */
+-	if (!ai_iscoreup(wlc_hw->sih)) {
+-		ai_core_reset(wlc_hw->sih, 0, 0);
+-		wlc_mctrl_reset(wlc_hw);
+-	}
+-
+-	macintmask = wlc_setband_inact(wlc, bandunit);
+-
+-	if (!wlc_hw->up)
+-		return;
+-
+-	wlc_bmac_core_phy_clk(wlc_hw, ON);
+-
+-	/* band-specific initializations */
+-	wlc_bmac_bsinit(wlc, chanspec);
+-
+-	/*
+-	 * If there are any pending software interrupt bits,
+-	 * then replace these with a harmless nonzero value
+-	 * so wlc_dpc() will re-enable interrupts when done.
+-	 */
+-	if (wlc->macintstatus)
+-		wlc->macintstatus = MI_DMAINT;
+-
+-	/* restore macintmask */
+-	wl_intrsrestore(wlc->wl, macintmask);
+-
+-	/* ucode should still be suspended.. */
+-	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
+-}
+-
+-/* low-level band switch utility routine */
+-void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		bandunit);
+-
+-	wlc_hw->band = wlc_hw->bandstate[bandunit];
+-
+-	/* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */
+-	wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
+-
+-	/* set gmode core flag */
+-	if (wlc_hw->sbclk && !wlc_hw->noreset) {
+-		ai_core_cflags(wlc_hw->sih, SICF_GMODE,
+-			       ((bandunit == 0) ? SICF_GMODE : 0));
+-	}
+-}
+-
+-static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw)
+-{
+-
+-	/* reject unsupported corerev */
+-	if (!VALID_COREREV(wlc_hw->corerev)) {
+-		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
+-			  wlc_hw->corerev);
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw)
+-{
+-	bool goodboard = true;
+-	uint boardrev = wlc_hw->boardrev;
+-
+-	if (boardrev == 0)
+-		goodboard = false;
+-	else if (boardrev > 0xff) {
+-		uint brt = (boardrev & 0xf000) >> 12;
+-		uint b0 = (boardrev & 0xf00) >> 8;
+-		uint b1 = (boardrev & 0xf0) >> 4;
+-		uint b2 = boardrev & 0xf;
+-
+-		if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
+-		    || (b2 > 9))
+-			goodboard = false;
+-	}
+-
+-	if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
+-		return goodboard;
+-
+-	return goodboard;
+-}
+-
+-static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw)
+-{
+-	const char *varname = "macaddr";
+-	char *macaddr;
+-
+-	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
+-	macaddr = getvar(wlc_hw->vars, varname);
+-	if (macaddr != NULL)
+-		return macaddr;
+-
+-	if (NBANDS_HW(wlc_hw) > 1)
+-		varname = "et1macaddr";
+-	else
+-		varname = "il0macaddr";
+-
+-	macaddr = getvar(wlc_hw->vars, varname);
+-	if (macaddr == NULL) {
+-		wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
+-			  "getvar(%s) not found\n", wlc_hw->unit, varname);
+-	}
+-
+-	return macaddr;
+-}
+-
+-/*
+- * Return true if radio is disabled, otherwise false.
+- * hw radio disable signal is an external pin, users activate it asynchronously
+- * this function could be called when driver is down and w/o clock
+- * it operates on different registers depending on corerev and boardflag.
+- */
+-bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw)
+-{
+-	bool v, clk, xtal;
+-	u32 resetbits = 0, flags = 0;
+-
+-	xtal = wlc_hw->sbclk;
+-	if (!xtal)
+-		wlc_bmac_xtal(wlc_hw, ON);
+-
+-	/* may need to take core out of reset first */
+-	clk = wlc_hw->clk;
+-	if (!clk) {
+-		/*
+-		 * mac no longer enables phyclk automatically when driver
+-		 * accesses phyreg throughput mac. This can be skipped since
+-		 * only mac reg is accessed below
+-		 */
+-		flags |= SICF_PCLKE;
+-
+-		/* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+-		if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
+-			wlc_hw->regs =
+-			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
+-						     0);
+-		ai_core_reset(wlc_hw->sih, flags, resetbits);
+-		wlc_mctrl_reset(wlc_hw);
+-	}
+-
+-	v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
+-
+-	/* put core back into reset */
+-	if (!clk)
+-		ai_core_disable(wlc_hw->sih, 0);
+-
+-	if (!xtal)
+-		wlc_bmac_xtal(wlc_hw, OFF);
+-
+-	return v;
+-}
+-
+-/* Initialize just the hardware when coming out of POR or S3/S5 system states */
+-void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw)
+-{
+-	if (wlc_hw->wlc->pub->hw_up)
+-		return;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/*
+-	 * Enable pll and xtal, initialize the power control registers,
+-	 * and force fastclock for the remainder of wlc_up().
+-	 */
+-	wlc_bmac_xtal(wlc_hw, ON);
+-	ai_clkctl_init(wlc_hw->sih);
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS) {
+-		ai_pci_fixcfg(wlc_hw->sih);
+-
+-		/* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+-		if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
+-			wlc_hw->regs =
+-			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
+-						     0);
+-	}
+-
+-	/* Inform phy that a POR reset has occurred so it does a complete phy init */
+-	wlc_phy_por_inform(wlc_hw->band->pi);
+-
+-	wlc_hw->ucode_loaded = false;
+-	wlc_hw->wlc->pub->hw_up = true;
+-
+-	if ((wlc_hw->boardflags & BFL_FEM)
+-	    && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
+-		if (!
+-		    (wlc_hw->boardrev >= 0x1250
+-		     && (wlc_hw->boardflags & BFL_FEM_BT)))
+-			ai_epa_4313war(wlc_hw->sih);
+-	}
+-}
+-
+-static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo)
+-{
+-	struct hnddma_pub *di = wlc_hw->di[fifo];
+-	return dma_rxreset(di);
+-}
+-
+-/* d11 core reset
+- *   ensure fask clock during reset
+- *   reset dma
+- *   reset d11(out of reset)
+- *   reset phy(out of reset)
+- *   clear software macintstatus for fresh new start
+- * one testing hack wlc_hw->noreset will bypass the d11/phy reset
+- */
+-void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags)
+-{
+-	d11regs_t *regs;
+-	uint i;
+-	bool fastclk;
+-	u32 resetbits = 0;
+-
+-	if (flags == WLC_USE_COREFLAGS)
+-		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-
+-	/* request FAST clock if not on  */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/* reset the dma engines except first time thru */
+-	if (ai_iscoreup(wlc_hw->sih)) {
+-		for (i = 0; i < NFIFO; i++)
+-			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
+-					  "dma_txreset[%d]: cannot stop dma\n",
+-					   wlc_hw->unit, __func__, i);
+-			}
+-
+-		if ((wlc_hw->di[RX_FIFO])
+-		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) {
+-			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
+-				  "[%d]: cannot stop dma\n",
+-				  wlc_hw->unit, __func__, RX_FIFO);
+-		}
+-	}
+-	/* if noreset, just stop the psm and return */
+-	if (wlc_hw->noreset) {
+-		wlc_hw->wlc->macintstatus = 0;	/* skip wl_dpc after down */
+-		wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
+-		return;
+-	}
+-
+-	/*
+-	 * mac no longer enables phyclk automatically when driver accesses
+-	 * phyreg throughput mac, AND phy_reset is skipped at early stage when
+-	 * band->pi is invalid. need to enable PHY CLK
+-	 */
+-	flags |= SICF_PCLKE;
+-
+-	/* reset the core
+-	 * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which
+-	 *  is cleared by the core_reset. have to re-request it.
+-	 *  This adds some delay and we can optimize it by also requesting fastclk through
+-	 *  chipcommon during this period if necessary. But that has to work coordinate
+-	 *  with other driver like mips/arm since they may touch chipcommon as well.
+-	 */
+-	wlc_hw->clk = false;
+-	ai_core_reset(wlc_hw->sih, flags, resetbits);
+-	wlc_hw->clk = true;
+-	if (wlc_hw->band && wlc_hw->band->pi)
+-		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
+-
+-	wlc_mctrl_reset(wlc_hw);
+-
+-	if (PMUCTL_ENAB(wlc_hw->sih))
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	wlc_bmac_phy_reset(wlc_hw);
+-
+-	/* turn on PHY_PLL */
+-	wlc_bmac_core_phypll_ctl(wlc_hw, true);
+-
+-	/* clear sw intstatus */
+-	wlc_hw->wlc->macintstatus = 0;
+-
+-	/* restore the clk setting */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-/* txfifo sizes needs to be modified(increased) since the newer cores
+- * have more memory.
+- */
+-static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	u16 fifo_nu;
+-	u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
+-	u16 txfifo_def, txfifo_def1;
+-	u16 txfifo_cmd;
+-
+-	/* tx fifos start at TXFIFO_START_BLK from the Base address */
+-	txfifo_startblk = TXFIFO_START_BLK;
+-
+-	/* sequence of operations:  reset fifo, set fifo size, reset fifo */
+-	for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
+-
+-		txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
+-		txfifo_def = (txfifo_startblk & 0xff) |
+-		    (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
+-		txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
+-		    ((((txfifo_endblk -
+-			1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
+-		txfifo_cmd =
+-		    TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
+-
+-		W_REG(&regs->xmtfifocmd, txfifo_cmd);
+-		W_REG(&regs->xmtfifodef, txfifo_def);
+-		W_REG(&regs->xmtfifodef1, txfifo_def1);
+-
+-		W_REG(&regs->xmtfifocmd, txfifo_cmd);
+-
+-		txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
+-	}
+-	/*
+-	 * need to propagate to shm location to be in sync since ucode/hw won't
+-	 * do this
+-	 */
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0,
+-			   wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1,
+-			   wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2,
+-			   ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
+-			    xmtfifo_sz[TX_AC_BK_FIFO]));
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3,
+-			   ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
+-			    xmtfifo_sz[TX_BCMC_FIFO]));
+-}
+-
+-/* d11 core init
+- *   reset PSM
+- *   download ucode/PCM
+- *   let ucode run to suspended
+- *   download ucode inits
+- *   config other core registers
+- *   init dma
+- */
+-static void wlc_coreinit(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs;
+-	u32 sflags;
+-	uint bcnint_us;
+-	uint i = 0;
+-	bool fifosz_fixup = false;
+-	int err = 0;
+-	u16 buf[NFIFO];
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	regs = wlc_hw->regs;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* reset PSM */
+-	wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
+-
+-	wlc_ucode_download(wlc_hw);
+-	/*
+-	 * FIFOSZ fixup. driver wants to controls the fifo allocation.
+-	 */
+-	fifosz_fixup = true;
+-
+-	/* let the PSM run to the suspended state, set mode to BSS STA */
+-	W_REG(&regs->macintstatus, -1);
+-	wlc_bmac_mctrl(wlc_hw, ~0,
+-		       (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
+-
+-	/* wait for ucode to self-suspend after auto-init */
+-	SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
+-		 1000 * 1000);
+-	if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
+-		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
+-			  "suspend!\n", wlc_hw->unit);
+-
+-	wlc_gpio_init(wlc);
+-
+-	sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
+-
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band))
+-			wlc_write_inits(wlc_hw, d11n0initvals16);
+-		else
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
+-		if (WLCISLCNPHY(wlc_hw->band)) {
+-			wlc_write_inits(wlc_hw, d11lcn0initvals24);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-		}
+-	} else {
+-		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+-			  __func__, wlc_hw->unit, wlc_hw->corerev);
+-	}
+-
+-	/* For old ucode, txfifo sizes needs to be modified(increased) */
+-	if (fifosz_fixup == true) {
+-		wlc_corerev_fifofixup(wlc_hw);
+-	}
+-
+-	/* check txfifo allocations match between ucode and driver */
+-	buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0);
+-	if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
+-		i = TX_AC_BE_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1);
+-	if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
+-		i = TX_AC_VI_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2);
+-	buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
+-	buf[TX_AC_BK_FIFO] &= 0xff;
+-	if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
+-		i = TX_AC_BK_FIFO;
+-		err = -1;
+-	}
+-	if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
+-		i = TX_AC_VO_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3);
+-	buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
+-	buf[TX_BCMC_FIFO] &= 0xff;
+-	if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
+-		i = TX_BCMC_FIFO;
+-		err = -1;
+-	}
+-	if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
+-		i = TX_ATIM_FIFO;
+-		err = -1;
+-	}
+-	if (err != 0) {
+-		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
+-			  " driver size %d index %d\n", buf[i],
+-			  wlc_hw->xmtfifo_sz[i], i);
+-	}
+-
+-	/* make sure we can still talk to the mac */
+-	WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
+-
+-	/* band-specific inits done by wlc_bsinit() */
+-
+-	/* Set up frame burst size and antenna swap threshold init values */
+-	wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
+-	wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
+-
+-	/* enable one rx interrupt per received frame */
+-	W_REG(&regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
+-
+-	/* set the station mode (BSS STA) */
+-	wlc_bmac_mctrl(wlc_hw,
+-		       (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
+-		       (MCTL_INFRA | MCTL_DISCARD_PMQ));
+-
+-	/* set up Beacon interval */
+-	bcnint_us = 0x8000 << 10;
+-	W_REG(&regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
+-	W_REG(&regs->tsf_cfpstart, bcnint_us);
+-	W_REG(&regs->macintstatus, MI_GP1);
+-
+-	/* write interrupt mask */
+-	W_REG(&regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
+-
+-	/* allow the MAC to control the PHY clock (dynamic on/off) */
+-	wlc_bmac_macphyclk_set(wlc_hw, ON);
+-
+-	/* program dynamic clock control fast powerup delay register */
+-	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
+-	W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
+-
+-	/* tell the ucode the corerev */
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
+-
+-	/* tell the ucode MAC capabilities */
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L,
+-			   (u16) (wlc_hw->machwcap & 0xffff));
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H,
+-			   (u16) ((wlc_hw->
+-				      machwcap >> 16) & 0xffff));
+-
+-	/* write retry limits to SCR, this done after PSM init */
+-	W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, wlc_hw->SRL);
+-	W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, wlc_hw->LRL);
+-
+-	/* write rate fallback retry limits */
+-	wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
+-	wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
+-
+-	AND_REG(&regs->ifs_ctl, 0x0FFF);
+-	W_REG(&regs->ifs_aifsn, EDCF_AIFSN_MIN);
+-
+-	/* dma initializations */
+-	wlc->txpend16165war = 0;
+-
+-	/* init the tx dma engines */
+-	for (i = 0; i < NFIFO; i++) {
+-		if (wlc_hw->di[i])
+-			dma_txinit(wlc_hw->di[i]);
+-	}
+-
+-	/* init the rx dma engine(s) and post receive buffers */
+-	dma_rxinit(wlc_hw->di[RX_FIFO]);
+-	dma_rxfill(wlc_hw->di[RX_FIFO]);
+-}
+-
+-/* This function is used for changing the tsf frac register
+- * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
+- * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
+- * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
+- * HTPHY Formula is 2^26/freq(MHz) e.g.
+- * For spuron2 - 126MHz -> 2^26/126 = 532610.0
+- *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
+- * For spuron: 123MHz -> 2^26/123    = 545600.5
+- *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
+- * For spur off: 120MHz -> 2^26/120    = 559240.5
+- *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
+- */
+-
+-void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode)
+-{
+-	d11regs_t *regs;
+-	regs = wlc_hw->regs;
+-
+-	if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-	    (wlc_hw->sih->chip == BCM43225_CHIP_ID)) {
+-		if (spurmode == WL_SPURAVOID_ON2) {	/* 126Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x2082);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		} else if (spurmode == WL_SPURAVOID_ON1) {	/* 123Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x5341);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		} else {	/* 120Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x8889);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		}
+-	} else if (WLCISLCNPHY(wlc_hw->band)) {
+-		if (spurmode == WL_SPURAVOID_ON1) {	/* 82Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x7CE0);
+-			W_REG(&regs->tsf_clk_frac_h, 0xC);
+-		} else {	/* 80Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0xCCCD);
+-			W_REG(&regs->tsf_clk_frac_h, 0xC);
+-		}
+-	}
+-}
+-
+-/* Initialize GPIOs that are controlled by D11 core */
+-static void wlc_gpio_init(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs;
+-	u32 gc, gm;
+-
+-	regs = wlc_hw->regs;
+-
+-	/* use GPIO select 0 to get all gpio signals from the gpio out reg */
+-	wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
+-
+-	/*
+-	 * Common GPIO setup:
+-	 *      G0 = LED 0 = WLAN Activity
+-	 *      G1 = LED 1 = WLAN 2.4 GHz Radio State
+-	 *      G2 = LED 2 = WLAN 5 GHz Radio State
+-	 *      G4 = radio disable input (HI enabled, LO disabled)
+-	 */
+-
+-	gc = gm = 0;
+-
+-	/* Allocate GPIOs for mimo antenna diversity feature */
+-	if (wlc_hw->antsel_type == ANTSEL_2x3) {
+-		/* Enable antenna diversity, use 2x3 mode */
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+-			     MHF3_ANTSEL_EN, WLC_BAND_ALL);
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
+-			     MHF3_ANTSEL_MODE, WLC_BAND_ALL);
+-
+-		/* init superswitch control */
+-		wlc_phy_antsel_init(wlc_hw->band->pi, false);
+-
+-	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
+-		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
+-		/*
+-		 * The board itself is powered by these GPIOs
+-		 * (when not sending pattern) so set them high
+-		 */
+-		OR_REG(&regs->psm_gpio_oe,
+-		       (BOARD_GPIO_12 | BOARD_GPIO_13));
+-		OR_REG(&regs->psm_gpio_out,
+-		       (BOARD_GPIO_12 | BOARD_GPIO_13));
+-
+-		/* Enable antenna diversity, use 2x4 mode */
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+-			     MHF3_ANTSEL_EN, WLC_BAND_ALL);
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
+-			     WLC_BAND_ALL);
+-
+-		/* Configure the desired clock to be 4Mhz */
+-		wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
+-				   ANTSEL_CLKDIV_4MHZ);
+-	}
+-
+-	/* gpio 9 controls the PA.  ucode is responsible for wiggling out and oe */
+-	if (wlc_hw->boardflags & BFL_PACTRL)
+-		gm |= gc |= BOARD_GPIO_PACTRL;
+-
+-	/* apply to gpiocontrol register */
+-	ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
+-}
+-
+-static void wlc_ucode_download(struct wlc_hw_info *wlc_hw)
+-{
+-	struct wlc_info *wlc;
+-	wlc = wlc_hw->wlc;
+-
+-	if (wlc_hw->ucode_loaded)
+-		return;
+-
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			wlc_ucode_write(wlc_hw, bcm43xx_16_mimo,
+-					bcm43xx_16_mimosz);
+-			wlc_hw->ucode_loaded = true;
+-		} else
+-			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+-				  "corerev %d\n",
+-				  __func__, wlc_hw->unit, wlc_hw->corerev);
+-	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
+-		if (WLCISLCNPHY(wlc_hw->band)) {
+-			wlc_ucode_write(wlc_hw, bcm43xx_24_lcn,
+-					bcm43xx_24_lcnsz);
+-			wlc_hw->ucode_loaded = true;
+-		} else {
+-			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+-				  "corerev %d\n",
+-				  __func__, wlc_hw->unit, wlc_hw->corerev);
+-		}
+-	}
+-}
+-
+-static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[],
+-			      const uint nbytes) {
+-	d11regs_t *regs = wlc_hw->regs;
+-	uint i;
+-	uint count;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	count = (nbytes / sizeof(u32));
+-
+-	W_REG(&regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
+-	(void)R_REG(&regs->objaddr);
+-	for (i = 0; i < count; i++)
+-		W_REG(&regs->objdata, ucode[i]);
+-}
+-
+-static void wlc_write_inits(struct wlc_hw_info *wlc_hw,
+-			    const struct d11init *inits)
+-{
+-	int i;
+-	volatile u8 *base;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	base = (volatile u8 *)wlc_hw->regs;
+-
+-	for (i = 0; inits[i].addr != 0xffff; i++) {
+-		if (inits[i].size == 2)
+-			W_REG((u16 *)(base + inits[i].addr),
+-			      inits[i].value);
+-		else if (inits[i].size == 4)
+-			W_REG((u32 *)(base + inits[i].addr),
+-			      inits[i].value);
+-	}
+-}
+-
+-static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw)
+-{
+-	u16 phyctl;
+-	u16 phytxant = wlc_hw->bmac_phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* set the Probe Response frame phy control word */
+-	phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
+-
+-	/* set the Response (ACK/CTS) frame phy control word */
+-	phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
+-}
+-
+-void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant)
+-{
+-	/* update sw state */
+-	wlc_hw->bmac_phytxant = phytxant;
+-
+-	/* push to ucode if up */
+-	if (!wlc_hw->up)
+-		return;
+-	wlc_ucode_txant_set(wlc_hw);
+-
+-}
+-
+-u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw)
+-{
+-	return (u16) wlc_hw->wlc->stf->txant;
+-}
+-
+-void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type)
+-{
+-	wlc_hw->antsel_type = antsel_type;
+-
+-	/* Update the antsel type for phy module to use */
+-	wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
+-}
+-
+-void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw)
+-{
+-	bool fatal = false;
+-	uint unit;
+-	uint intstatus, idx;
+-	d11regs_t *regs = wlc_hw->regs;
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	unit = wlc_hw->unit;
+-
+-	for (idx = 0; idx < NFIFO; idx++) {
+-		/* read intstatus register and ignore any non-error bits */
+-		intstatus =
+-		    R_REG(&regs->intctrlregs[idx].intstatus) & I_ERRORS;
+-		if (!intstatus)
+-			continue;
+-
+-		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
+-			unit, idx, intstatus);
+-
+-		if (intstatus & I_RO) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
+-				  "overflow\n", unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_PC) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
+-				 unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_PD) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
+-				  idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_DE) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
+-				  "error\n", unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_RU) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
+-				  "underflow\n", idx, unit);
+-		}
+-
+-		if (intstatus & I_XU) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
+-				  "underflow\n", idx, unit);
+-			fatal = true;
+-		}
+-
+-		if (fatal) {
+-			wlc_fatal_error(wlc_hw->wlc);	/* big hammer */
+-			break;
+-		} else
+-			W_REG(&regs->intctrlregs[idx].intstatus,
+-			      intstatus);
+-	}
+-}
+-
+-void wlc_intrson(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	wlc->macintmask = wlc->defmacintmask;
+-	W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
+-}
+-
+-/* callback for siutils.c, which has only wlc handler, no wl
+- * they both check up, not only because there is no need to off/restore d11 interrupt
+- *  but also because per-port code may require sync with valid interrupt.
+- */
+-
+-static u32 wlc_wlintrsoff(struct wlc_info *wlc)
+-{
+-	if (!wlc->hw->up)
+-		return 0;
+-
+-	return wl_intrsoff(wlc->wl);
+-}
+-
+-static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask)
+-{
+-	if (!wlc->hw->up)
+-		return;
+-
+-	wl_intrsrestore(wlc->wl, macintmask);
+-}
+-
+-u32 wlc_intrsoff(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintmask;
+-
+-	if (!wlc_hw->clk)
+-		return 0;
+-
+-	macintmask = wlc->macintmask;	/* isr can still happen */
+-
+-	W_REG(&wlc_hw->regs->macintmask, 0);
+-	(void)R_REG(&wlc_hw->regs->macintmask);	/* sync readback */
+-	udelay(1);		/* ensure int line is no longer driven */
+-	wlc->macintmask = 0;
+-
+-	/* return previous macintmask; resolve race between us and our isr */
+-	return wlc->macintstatus ? 0 : macintmask;
+-}
+-
+-void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	if (!wlc_hw->clk)
+-		return;
+-
+-	wlc->macintmask = macintmask;
+-	W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
+-}
+-
+-void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags)
+-{
+-	u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+-
+-	if (on) {
+-		/* suspend tx fifos */
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
+-
+-		/* zero the address match register so we do not send ACKs */
+-		wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+-				       null_ether_addr);
+-	} else {
+-		/* resume tx fifos */
+-		if (!wlc_hw->wlc->tx_suspended) {
+-			wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
+-		}
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
+-
+-		/* Restore address */
+-		wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+-				       wlc_hw->etheraddr);
+-	}
+-
+-	wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
+-
+-	if (on)
+-		wlc_ucode_mute_override_set(wlc_hw);
+-	else
+-		wlc_ucode_mute_override_clear(wlc_hw);
+-}
+-
+-int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks)
+-{
+-	if (fifo >= NFIFO)
+-		return -EINVAL;
+-
+-	*blocks = wlc_hw->xmtfifo_sz[fifo];
+-
+-	return 0;
+-}
+-
+-/* wlc_bmac_tx_fifo_suspended:
+- * Check the MAC's tx suspend status for a tx fifo.
+- *
+- * When the MAC acknowledges a tx suspend, it indicates that no more
+- * packets will be transmitted out the radio. This is independent of
+- * DMA channel suspension---the DMA may have finished suspending, or may still
+- * be pulling data into a tx fifo, by the time the MAC acks the suspend
+- * request.
+- */
+-static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	/* check that a suspend has been requested and is no longer pending */
+-
+-	/*
+-	 * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine,
+-	 * and the tx fifo suspend at the lower end of the MAC is acknowledged in the
+-	 * chnstatus register.
+-	 * The tx fifo suspend completion is independent of the DMA suspend completion and
+-	 *   may be acked before or after the DMA is suspended.
+-	 */
+-	if (dma_txsuspended(wlc_hw->di[tx_fifo]) &&
+-	    (R_REG(&wlc_hw->regs->chnstatus) &
+-	     (1 << tx_fifo)) == 0)
+-		return true;
+-
+-	return false;
+-}
+-
+-static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	u8 fifo = 1 << tx_fifo;
+-
+-	/* Two clients of this code, 11h Quiet period and scanning. */
+-
+-	/* only suspend if not already suspended */
+-	if ((wlc_hw->suspended_fifos & fifo) == fifo)
+-		return;
+-
+-	/* force the core awake only if not already */
+-	if (wlc_hw->suspended_fifos == 0)
+-		wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO);
+-
+-	wlc_hw->suspended_fifos |= fifo;
+-
+-	if (wlc_hw->di[tx_fifo]) {
+-		/* Suspending AMPDU transmissions in the middle can cause underflow
+-		 * which may result in mismatch between ucode and driver
+-		 * so suspend the mac before suspending the FIFO
+-		 */
+-		if (WLC_PHY_11N_CAP(wlc_hw->band))
+-			wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-
+-		dma_txsuspend(wlc_hw->di[tx_fifo]);
+-
+-		if (WLC_PHY_11N_CAP(wlc_hw->band))
+-			wlc_enable_mac(wlc_hw->wlc);
+-	}
+-}
+-
+-static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	/* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done
+-	 * here for PIO otherwise the watchdog will catch the inconsistency and fire
+-	 */
+-	/* Two clients of this code, 11h Quiet period and scanning. */
+-	if (wlc_hw->di[tx_fifo])
+-		dma_txresume(wlc_hw->di[tx_fifo]);
+-
+-	/* allow core to sleep again */
+-	if (wlc_hw->suspended_fifos == 0)
+-		return;
+-	else {
+-		wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
+-		if (wlc_hw->suspended_fifos == 0)
+-			wlc_ucode_wake_override_clear(wlc_hw,
+-						      WLC_WAKE_OVERRIDE_TXFIFO);
+-	}
+-}
+-
+-/*
+- * Read and clear macintmask and macintstatus and intstatus registers.
+- * This routine should be called with interrupts off
+- * Return:
+- *   -1 if DEVICEREMOVED(wlc) evaluates to true;
+- *   0 if the interrupt is not for us, or we are in some special cases;
+- *   device interrupt status bits otherwise.
+- */
+-static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 macintstatus;
+-
+-	/* macintstatus includes a DMA interrupt summary bit */
+-	macintstatus = R_REG(&regs->macintstatus);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
+-		 macintstatus);
+-
+-	/* detect cardbus removed, in power down(suspend) and in reset */
+-	if (DEVICEREMOVED(wlc))
+-		return -1;
+-
+-	/* DEVICEREMOVED succeeds even when the core is still resetting,
+-	 * handle that case here.
+-	 */
+-	if (macintstatus == 0xffffffff)
+-		return 0;
+-
+-	/* defer unsolicited interrupts */
+-	macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
+-
+-	/* if not for us */
+-	if (macintstatus == 0)
+-		return 0;
+-
+-	/* interrupts are already turned off for CFE build
+-	 * Caution: For CFE Turning off the interrupts again has some undesired
+-	 * consequences
+-	 */
+-	/* turn off the interrupts */
+-	W_REG(&regs->macintmask, 0);
+-	(void)R_REG(&regs->macintmask);	/* sync readback */
+-	wlc->macintmask = 0;
+-
+-	/* clear device interrupts */
+-	W_REG(&regs->macintstatus, macintstatus);
+-
+-	/* MI_DMAINT is indication of non-zero intstatus */
+-	if (macintstatus & MI_DMAINT) {
+-		/*
+-		 * only fifo interrupt enabled is I_RI in
+-		 * RX_FIFO. If MI_DMAINT is set, assume it
+-		 * is set and clear the interrupt.
+-		 */
+-		W_REG(&regs->intctrlregs[RX_FIFO].intstatus,
+-		      DEF_RXINTMASK);
+-	}
+-
+-	return macintstatus;
+-}
+-
+-/* Update wlc->macintstatus and wlc->intstatus[]. */
+-/* Return true if they are updated successfully. false otherwise */
+-bool wlc_intrsupd(struct wlc_info *wlc)
+-{
+-	u32 macintstatus;
+-
+-	/* read and clear macintstatus and intstatus registers */
+-	macintstatus = wlc_intstatus(wlc, false);
+-
+-	/* device is removed */
+-	if (macintstatus == 0xffffffff)
+-		return false;
+-
+-	/* update interrupt status in software */
+-	wlc->macintstatus |= macintstatus;
+-
+-	return true;
+-}
+-
+-/*
+- * First-level interrupt processing.
+- * Return true if this was our interrupt, false otherwise.
+- * *wantdpc will be set to true if further wlc_dpc() processing is required,
+- * false otherwise.
+- */
+-bool wlc_isr(struct wlc_info *wlc, bool *wantdpc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintstatus;
+-
+-	*wantdpc = false;
+-
+-	if (!wlc_hw->up || !wlc->macintmask)
+-		return false;
+-
+-	/* read and clear macintstatus and intstatus registers */
+-	macintstatus = wlc_intstatus(wlc, true);
+-
+-	if (macintstatus == 0xffffffff)
+-		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
+-			  " path\n");
+-
+-	/* it is not for us */
+-	if (macintstatus == 0)
+-		return false;
+-
+-	*wantdpc = true;
+-
+-	/* save interrupt status bits */
+-	wlc->macintstatus = macintstatus;
+-
+-	return true;
+-
+-}
+-
+-static bool
+-wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2)
+-{
+-	/* discard intermediate indications for ucode with one legitimate case:
+-	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+-	 *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+-	 *   transmission count)
+-	 */
+-	if (!(txs->status & TX_STATUS_AMPDU)
+-	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
+-		return false;
+-	}
+-
+-	return wlc_dotxstatus(wlc_hw->wlc, txs, s2);
+-}
+-
+-/* process tx completion events in BMAC
+- * Return true if more tx status need to be processed. false otherwise.
+- */
+-static bool
+-wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal)
+-{
+-	bool morepending = false;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	d11regs_t *regs;
+-	tx_status_t txstatus, *txs;
+-	u32 s1, s2;
+-	uint n = 0;
+-	/*
+-	 * Param 'max_tx_num' indicates max. # tx status to process before
+-	 * break out.
+-	 */
+-	uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	txs = &txstatus;
+-	regs = wlc_hw->regs;
+-	while (!(*fatal)
+-	       && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
+-
+-		if (s1 == 0xffffffff) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
+-				wlc_hw->unit, __func__);
+-			return morepending;
+-		}
+-
+-			s2 = R_REG(&regs->frmtxstatus2);
+-
+-		txs->status = s1 & TXS_STATUS_MASK;
+-		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
+-		txs->sequence = s2 & TXS_SEQ_MASK;
+-		txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
+-		txs->lasttxtime = 0;
+-
+-		*fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2);
+-
+-		/* !give others some time to run! */
+-		if (++n >= max_tx_num)
+-			break;
+-	}
+-
+-	if (*fatal)
+-		return 0;
+-
+-	if (n >= max_tx_num)
+-		morepending = true;
+-
+-	if (!pktq_empty(&wlc->pkt_queue->q))
+-		wlc_send_q(wlc);
+-
+-	return morepending;
+-}
+-
+-void wlc_suspend_mac_and_wait(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 mc, mi;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc_hw->band->bandunit);
+-
+-	/*
+-	 * Track overlapping suspend requests
+-	 */
+-	wlc_hw->mac_suspend_depth++;
+-	if (wlc_hw->mac_suspend_depth > 1)
+-		return;
+-
+-	/* force the core awake */
+-	wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-
+-	mc = R_REG(&regs->maccontrol);
+-
+-	if (mc == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-	WARN_ON(!(mc & MCTL_EN_MAC));
+-
+-	mi = R_REG(&regs->macintstatus);
+-	if (mi == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mi & MI_MACSSPNDD);
+-
+-	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0);
+-
+-	SPINWAIT(!(R_REG(&regs->macintstatus) & MI_MACSSPNDD),
+-		 WLC_MAX_MAC_SUSPEND);
+-
+-	if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
+-		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
+-			  " and MI_MACSSPNDD is still not on.\n",
+-			  wlc_hw->unit, WLC_MAX_MAC_SUSPEND);
+-		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
+-			  "psm_brc 0x%04x\n", wlc_hw->unit,
+-			  R_REG(&regs->psmdebug),
+-			  R_REG(&regs->phydebug),
+-			  R_REG(&regs->psm_brc));
+-	}
+-
+-	mc = R_REG(&regs->maccontrol);
+-	if (mc == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-	WARN_ON(mc & MCTL_EN_MAC);
+-}
+-
+-void wlc_enable_mac(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 mc, mi;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc->band->bandunit);
+-
+-	/*
+-	 * Track overlapping suspend requests
+-	 */
+-	wlc_hw->mac_suspend_depth--;
+-	if (wlc_hw->mac_suspend_depth > 0)
+-		return;
+-
+-	mc = R_REG(&regs->maccontrol);
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(mc & MCTL_EN_MAC);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-
+-	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
+-	W_REG(&regs->macintstatus, MI_MACSSPNDD);
+-
+-	mc = R_REG(&regs->maccontrol);
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_EN_MAC));
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-
+-	mi = R_REG(&regs->macintstatus);
+-	WARN_ON(mi & MI_MACSSPNDD);
+-
+-	wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-}
+-
+-static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw)
+-{
+-	u8 rate;
+-	u8 rates[8] = {
+-		WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M,
+-		WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M
+-	};
+-	u16 entry_ptr;
+-	u16 pctl1;
+-	uint i;
+-
+-	if (!WLC_PHY_11N_CAP(wlc_hw->band))
+-		return;
+-
+-	/* walk the phy rate table and update the entries */
+-	for (i = 0; i < ARRAY_SIZE(rates); i++) {
+-		rate = rates[i];
+-
+-		entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate);
+-
+-		/* read the SHM Rate Table entry OFDM PCTL1 values */
+-		pctl1 =
+-		    wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
+-
+-		/* modify the value */
+-		pctl1 &= ~PHY_TXC1_MODE_MASK;
+-		pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
+-
+-		/* Update the SHM Rate Table entry OFDM PCTL1 values */
+-		wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
+-				   pctl1);
+-	}
+-}
+-
+-static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate)
+-{
+-	uint i;
+-	u8 plcp_rate = 0;
+-	struct plcp_signal_rate_lookup {
+-		u8 rate;
+-		u8 signal_rate;
+-	};
+-	/* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
+-	const struct plcp_signal_rate_lookup rate_lookup[] = {
+-		{WLC_RATE_6M, 0xB},
+-		{WLC_RATE_9M, 0xF},
+-		{WLC_RATE_12M, 0xA},
+-		{WLC_RATE_18M, 0xE},
+-		{WLC_RATE_24M, 0x9},
+-		{WLC_RATE_36M, 0xD},
+-		{WLC_RATE_48M, 0x8},
+-		{WLC_RATE_54M, 0xC}
+-	};
+-
+-	for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
+-		if (rate == rate_lookup[i].rate) {
+-			plcp_rate = rate_lookup[i].signal_rate;
+-			break;
+-		}
+-	}
+-
+-	/* Find the SHM pointer to the rate table entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
+-}
+-
+-void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode)
+-{
+-	wlc_hw->hw_stf_ss_opmode = stf_mode;
+-
+-	if (wlc_hw->clk)
+-		wlc_upd_ofdm_pctl1_table(wlc_hw);
+-}
+-
+-void
+-wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr,
+-		  u32 *tsf_h_ptr)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	/* read the tsf timer low, then high to get an atomic read */
+-	*tsf_l_ptr = R_REG(&regs->tsf_timerlow);
+-	*tsf_h_ptr = R_REG(&regs->tsf_timerhigh);
+-
+-	return;
+-}
+-
+-static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw)
+-{
+-	d11regs_t *regs;
+-	u32 w, val;
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-
+-	/* Validate dchip register access */
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	w = R_REG(&regs->objdata);
+-
+-	/* Can we write and read back a 32bit register? */
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, (u32) 0xaa5555aa);
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	val = R_REG(&regs->objdata);
+-	if (val != (u32) 0xaa5555aa) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+-			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
+-		return false;
+-	}
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, (u32) 0x55aaaa55);
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	val = R_REG(&regs->objdata);
+-	if (val != (u32) 0x55aaaa55) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+-			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
+-		return false;
+-	}
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, w);
+-
+-	/* clear CFPStart */
+-	W_REG(&regs->tsf_cfpstart, 0);
+-
+-	w = R_REG(&regs->maccontrol);
+-	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
+-	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
+-			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
+-			  (MCTL_IHR_EN | MCTL_WAKE),
+-			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-#define PHYPLL_WAIT_US	100000
+-
+-void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on)
+-{
+-	d11regs_t *regs;
+-	u32 tmp;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	tmp = 0;
+-	regs = wlc_hw->regs;
+-
+-	if (on) {
+-		if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
+-			OR_REG(&regs->clk_ctl_st,
+-			       (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
+-				CCS_ERSRC_REQ_PHYPLL));
+-			SPINWAIT((R_REG(&regs->clk_ctl_st) &
+-				  (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
+-				 PHYPLL_WAIT_US);
+-
+-			tmp = R_REG(&regs->clk_ctl_st);
+-			if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
+-			    (CCS_ERSRC_AVAIL_HT)) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
+-					  " PLL failed\n", __func__);
+-			}
+-		} else {
+-			OR_REG(&regs->clk_ctl_st,
+-			       (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
+-			SPINWAIT((R_REG(&regs->clk_ctl_st) &
+-				  (CCS_ERSRC_AVAIL_D11PLL |
+-				   CCS_ERSRC_AVAIL_PHYPLL)) !=
+-				 (CCS_ERSRC_AVAIL_D11PLL |
+-				  CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
+-
+-			tmp = R_REG(&regs->clk_ctl_st);
+-			if ((tmp &
+-			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
+-			    !=
+-			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
+-					  "PHY PLL failed\n", __func__);
+-			}
+-		}
+-	} else {
+-		/* Since the PLL may be shared, other cores can still be requesting it;
+-		 * so we'll deassert the request but not wait for status to comply.
+-		 */
+-		AND_REG(&regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
+-		tmp = R_REG(&regs->clk_ctl_st);
+-	}
+-}
+-
+-void wlc_coredisable(struct wlc_hw_info *wlc_hw)
+-{
+-	bool dev_gone;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	if (dev_gone)
+-		return;
+-
+-	if (wlc_hw->noreset)
+-		return;
+-
+-	/* radio off */
+-	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+-
+-	/* turn off analog core */
+-	wlc_phy_anacore(wlc_hw->band->pi, OFF);
+-
+-	/* turn off PHYPLL to save power */
+-	wlc_bmac_core_phypll_ctl(wlc_hw, false);
+-
+-	/* No need to set wlc->pub->radio_active = OFF
+-	 * because this function needs down capability and
+-	 * radio_active is designed for BCMNODOWN.
+-	 */
+-
+-	/* remove gpio controls */
+-	if (wlc_hw->ucode_dbgsel)
+-		ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
+-
+-	wlc_hw->clk = false;
+-	ai_core_disable(wlc_hw->sih, 0);
+-	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-}
+-
+-/* power both the pll and external oscillator on/off */
+-static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
+-
+-	/* dont power down if plldown is false or we must poll hw radio disable */
+-	if (!want && wlc_hw->pllreq)
+-		return;
+-
+-	if (wlc_hw->sih)
+-		ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
+-
+-	wlc_hw->sbclk = want;
+-	if (!wlc_hw->sbclk) {
+-		wlc_hw->clk = false;
+-		if (wlc_hw->band && wlc_hw->band->pi)
+-			wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-	}
+-}
+-
+-static void wlc_flushqueues(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	uint i;
+-
+-	wlc->txpend16165war = 0;
+-
+-	/* free any posted tx packets */
+-	for (i = 0; i < NFIFO; i++)
+-		if (wlc_hw->di[i]) {
+-			dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL);
+-			TXPKTPENDCLR(wlc, i);
+-			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
+-		}
+-
+-	/* free any posted rx packets */
+-	dma_rxreclaim(wlc_hw->di[RX_FIFO]);
+-}
+-
+-u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset)
+-{
+-	return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
+-}
+-
+-void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v)
+-{
+-	wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
+-}
+-
+-static u16
+-wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
+-	volatile u16 *objdata_hi = objdata_lo + 1;
+-	u16 v;
+-
+-	W_REG(&regs->objaddr, sel | (offset >> 2));
+-	(void)R_REG(&regs->objaddr);
+-	if (offset & 2) {
+-		v = R_REG(objdata_hi);
+-	} else {
+-		v = R_REG(objdata_lo);
+-	}
+-
+-	return v;
+-}
+-
+-static void
+-wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
+-	volatile u16 *objdata_hi = objdata_lo + 1;
+-
+-	W_REG(&regs->objaddr, sel | (offset >> 2));
+-	(void)R_REG(&regs->objaddr);
+-	if (offset & 2) {
+-		W_REG(objdata_hi, v);
+-	} else {
+-		W_REG(objdata_lo, v);
+-	}
+-}
+-
+-/* Copy a buffer to shared memory of specified type .
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- * 'sel' selects the type of memory
+- */
+-void
+-wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf,
+-		       int len, u32 sel)
+-{
+-	u16 v;
+-	const u8 *p = (const u8 *)buf;
+-	int i;
+-
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	for (i = 0; i < len; i += 2) {
+-		v = p[i] | (p[i + 1] << 8);
+-		wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel);
+-	}
+-}
+-
+-/* Copy a piece of shared memory of specified type to a buffer .
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- * 'sel' selects the type of memory
+- */
+-void
+-wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf,
+-			 int len, u32 sel)
+-{
+-	u16 v;
+-	u8 *p = (u8 *) buf;
+-	int i;
+-
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	for (i = 0; i < len; i += 2) {
+-		v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel);
+-		p[i] = v & 0xFF;
+-		p[i + 1] = (v >> 8) & 0xFF;
+-	}
+-}
+-
+-void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n",
+-		wlc_hw->vars_size);
+-
+-	*buf = wlc_hw->vars;
+-	*len = wlc_hw->vars_size;
+-}
+-
+-void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL)
+-{
+-	wlc_hw->SRL = SRL;
+-	wlc_hw->LRL = LRL;
+-
+-	/* write retry limit to SCR, shouldn't need to suspend */
+-	if (wlc_hw->up) {
+-		W_REG(&wlc_hw->regs->objaddr,
+-		      OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+-		(void)R_REG(&wlc_hw->regs->objaddr);
+-		W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL);
+-		W_REG(&wlc_hw->regs->objaddr,
+-		      OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+-		(void)R_REG(&wlc_hw->regs->objaddr);
+-		W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL);
+-	}
+-}
+-
+-void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit)
+-{
+-	if (set) {
+-		if (mboolisset(wlc_hw->pllreq, req_bit))
+-			return;
+-
+-		mboolset(wlc_hw->pllreq, req_bit);
+-
+-		if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+-			if (!wlc_hw->sbclk) {
+-				wlc_bmac_xtal(wlc_hw, ON);
+-			}
+-		}
+-	} else {
+-		if (!mboolisset(wlc_hw->pllreq, req_bit))
+-			return;
+-
+-		mboolclr(wlc_hw->pllreq, req_bit);
+-
+-		if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+-			if (wlc_hw->sbclk) {
+-				wlc_bmac_xtal(wlc_hw, OFF);
+-			}
+-		}
+-	}
+-
+-	return;
+-}
+-
+-u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate)
+-{
+-	u16 table_ptr;
+-	u8 phy_rate, index;
+-
+-	/* get the phy specific rate encoding for the PLCP SIGNAL field */
+-	/* XXX4321 fixup needed ? */
+-	if (IS_OFDM(rate))
+-		table_ptr = M_RT_DIRMAP_A;
+-	else
+-		table_ptr = M_RT_DIRMAP_B;
+-
+-	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
+-	 * the index into the rate table.
+-	 */
+-	phy_rate = rate_info[rate] & WLC_RATE_MASK;
+-	index = phy_rate & 0xf;
+-
+-	/* Find the SHM pointer to the rate table entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2));
+-}
+-
+-void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail)
+-{
+-	wlc_hw->antsel_avail = antsel_avail;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
+deleted file mode 100644
+index a2a4e73..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
++++ /dev/null
+@@ -1,179 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#ifndef _wlc_bmac_h_
+-#define _wlc_bmac_h_
+-
+-/* XXXXX this interface is under wlc.c by design
+- * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign
+- *
+- *        high driver files(e.g. wlc_ampdu.c etc)
+- *             wlc.h/wlc.c
+- *         wlc_bmac.h/wlc_bmac.c
+- *
+- *  So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c
+- *  create wrappers in wlc.c if needed
+- */
+-
+-/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info)
+-   driver */
+-typedef struct wlc_bmac_state {
+-	u32 machwcap;	/* mac hw capibility */
+-	u32 preamble_ovr;	/* preamble override */
+-} wlc_bmac_state_t;
+-
+-enum {
+-	IOV_BMAC_DIAG,
+-	IOV_BMAC_SBGPIOTIMERVAL,
+-	IOV_BMAC_SBGPIOOUT,
+-	IOV_BMAC_CCGPIOCTRL,	/* CC GPIOCTRL REG */
+-	IOV_BMAC_CCGPIOOUT,	/* CC GPIOOUT REG */
+-	IOV_BMAC_CCGPIOOUTEN,	/* CC GPIOOUTEN REG */
+-	IOV_BMAC_CCGPIOIN,	/* CC GPIOIN REG */
+-	IOV_BMAC_WPSGPIO,	/* WPS push button GPIO pin */
+-	IOV_BMAC_OTPDUMP,
+-	IOV_BMAC_OTPSTAT,
+-	IOV_BMAC_PCIEASPM,	/* obfuscation clkreq/aspm control */
+-	IOV_BMAC_PCIEADVCORRMASK,	/* advanced correctable error mask */
+-	IOV_BMAC_PCIECLKREQ,	/* PCIE 1.1 clockreq enab support */
+-	IOV_BMAC_PCIELCREG,	/* PCIE LCREG */
+-	IOV_BMAC_SBGPIOTIMERMASK,
+-	IOV_BMAC_RFDISABLEDLY,
+-	IOV_BMAC_PCIEREG,	/* PCIE REG */
+-	IOV_BMAC_PCICFGREG,	/* PCI Config register */
+-	IOV_BMAC_PCIESERDESREG,	/* PCIE SERDES REG (dev, 0}offset) */
+-	IOV_BMAC_PCIEGPIOOUT,	/* PCIEOUT REG */
+-	IOV_BMAC_PCIEGPIOOUTEN,	/* PCIEOUTEN REG */
+-	IOV_BMAC_PCIECLKREQENCTRL,	/* clkreqenctrl REG (PCIE REV > 6.0 */
+-	IOV_BMAC_DMALPBK,
+-	IOV_BMAC_CCREG,
+-	IOV_BMAC_COREREG,
+-	IOV_BMAC_SDCIS,
+-	IOV_BMAC_SDIO_DRIVE,
+-	IOV_BMAC_OTPW,
+-	IOV_BMAC_NVOTPW,
+-	IOV_BMAC_SROM,
+-	IOV_BMAC_SRCRC,
+-	IOV_BMAC_CIS_SOURCE,
+-	IOV_BMAC_CISVAR,
+-	IOV_BMAC_OTPLOCK,
+-	IOV_BMAC_OTP_CHIPID,
+-	IOV_BMAC_CUSTOMVAR1,
+-	IOV_BMAC_BOARDFLAGS,
+-	IOV_BMAC_BOARDFLAGS2,
+-	IOV_BMAC_WPSLED,
+-	IOV_BMAC_NVRAM_SOURCE,
+-	IOV_BMAC_OTP_RAW_READ,
+-	IOV_BMAC_LAST
+-};
+-
+-extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device,
+-			   uint unit, bool piomode, void *regsva, uint bustype,
+-			   void *btparam);
+-extern int wlc_bmac_detach(struct wlc_info *wlc);
+-extern void wlc_bmac_watchdog(void *arg);
+-
+-/* up/down, reset, clk */
+-extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw,
+-				   uint offset, const void *buf, int len,
+-				   u32 sel);
+-extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				     void *buf, int len, u32 sel);
+-#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len)                 \
+-	wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+-#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len)                   \
+-	wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+-
+-extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on);
+-extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk);
+-extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk);
+-extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags);
+-extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags);
+-extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-			  bool mute);
+-extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode);
+-
+-/* chanspec, ucode interface */
+-extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw,
+-				  chanspec_t chanspec,
+-				  bool mute, struct txpwr_limits *txpwr);
+-
+-extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo,
+-				   uint *blocks);
+-extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask,
+-			 u16 val, int bands);
+-extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val);
+-extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands);
+-extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant);
+-extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw,
+-				     u8 antsel_type);
+-extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw,
+-			      wlc_bmac_state_t *state);
+-extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v);
+-extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset);
+-extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset,
+-					int len, void *buf);
+-extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf,
+-				   uint *len);
+-
+-extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw,
+-				  u8 *ea);
+-
+-extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot);
+-extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode);
+-
+-extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw);
+-
+-extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw,
+-					u32 override_bit);
+-extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw,
+-					  u32 override_bit);
+-
+-extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw,
+-				   int match_reg_offset,
+-				   const u8 *addr);
+-extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw,
+-					   void *bcn, int len, bool both);
+-
+-extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr,
+-			      u32 *tsf_h_ptr);
+-extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin);
+-extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax);
+-
+-extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL,
+-				    u16 LRL);
+-
+-extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw);
+-
+-
+-/* API for BMAC driver (e.g. wlc_phy.c etc) */
+-
+-extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw);
+-extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set,
+-			    mbool req_bit);
+-extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw);
+-extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate);
+-extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail);
+-
+-#endif /* _wlc_bmac_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
+deleted file mode 100644
+index 2572541..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
++++ /dev/null
+@@ -1,135 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_BSSCFG_H_
+-#define _WLC_BSSCFG_H_
+-
+-/* Check if a particular BSS config is AP or STA */
+-#define BSSCFG_AP(cfg)		(0)
+-#define BSSCFG_STA(cfg)		(1)
+-
+-#define BSSCFG_IBSS(cfg)	(!(cfg)->BSS)
+-
+-#define NTXRATE			64	/* # tx MPDUs rate is reported for */
+-#define MAXMACLIST		64	/* max # source MAC matches */
+-#define BCN_TEMPLATE_COUNT 	2
+-
+-/* Iterator for "associated" STA bss configs:
+-   (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */
+-#define FOREACH_AS_STA(wlc, idx, cfg) \
+-	for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+-		if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated)
+-
+-/* As above for all non-NULL BSS configs */
+-#define FOREACH_BSS(wlc, idx, cfg) \
+-	for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+-		if ((cfg = (wlc)->bsscfg[idx]))
+-
+-/* BSS configuration state */
+-struct wlc_bsscfg {
+-	struct wlc_info *wlc;	/* wlc to which this bsscfg belongs to. */
+-	bool up;		/* is this configuration up operational */
+-	bool enable;		/* is this configuration enabled */
+-	bool associated;	/* is BSS in ASSOCIATED state */
+-	bool BSS;		/* infraustructure or adhac */
+-	bool dtim_programmed;
+-
+-	u8 SSID_len;		/* the length of SSID */
+-	u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */
+-	struct scb *bcmc_scb[MAXBANDS];	/* one bcmc_scb per band */
+-	s8 _idx;		/* the index of this bsscfg,
+-				 * assigned at wlc_bsscfg_alloc()
+-				 */
+-	/* MAC filter */
+-	uint nmac;		/* # of entries on maclist array */
+-	int macmode;		/* allow/deny stations on maclist array */
+-	struct ether_addr *maclist;	/* list of source MAC addrs to match */
+-
+-	/* security */
+-	u32 wsec;		/* wireless security bitvec */
+-	s16 auth;		/* 802.11 authentication: Open, Shared Key, WPA */
+-	s16 openshared;	/* try Open auth first, then Shared Key */
+-	bool wsec_restrict;	/* drop unencrypted packets if wsec is enabled */
+-	bool eap_restrict;	/* restrict data until 802.1X auth succeeds */
+-	u16 WPA_auth;	/* WPA: authenticated key management */
+-	bool wpa2_preauth;	/* default is true, wpa_cap sets value */
+-	bool wsec_portopen;	/* indicates keys are plumbed */
+-	wsec_iv_t wpa_none_txiv;	/* global txiv for WPA_NONE, tkip and aes */
+-	int wsec_index;		/* 0-3: default tx key, -1: not set */
+-	wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS];	/* default key storage */
+-
+-	/* TKIP countermeasures */
+-	bool tkip_countermeasures;	/* flags TKIP no-assoc period */
+-	u32 tk_cm_dt;	/* detect timer */
+-	u32 tk_cm_bt;	/* blocking timer */
+-	u32 tk_cm_bt_tmstmp;	/* Timestamp when TKIP BT is activated */
+-	bool tk_cm_activate;	/* activate countermeasures after EAPOL-Key sent */
+-
+-	u8 BSSID[ETH_ALEN];	/* BSSID (associated) */
+-	u8 cur_etheraddr[ETH_ALEN];	/* h/w address */
+-	u16 bcmc_fid;	/* the last BCMC FID queued to TX_BCMC_FIFO */
+-	u16 bcmc_fid_shm;	/* the last BCMC FID written to shared mem */
+-
+-	u32 flags;		/* WLC_BSSCFG flags; see below */
+-
+-	u8 *bcn;		/* AP beacon */
+-	uint bcn_len;		/* AP beacon length */
+-	bool ar_disassoc;	/* disassociated in associated recreation */
+-
+-	int auth_atmptd;	/* auth type (open/shared) attempted */
+-
+-	pmkid_cand_t pmkid_cand[MAXPMKID];	/* PMKID candidate list */
+-	uint npmkid_cand;	/* num PMKID candidates */
+-	pmkid_t pmkid[MAXPMKID];	/* PMKID cache */
+-	uint npmkid;		/* num cached PMKIDs */
+-
+-	wlc_bss_info_t *current_bss;	/* BSS parms in ASSOCIATED state */
+-
+-	/* PM states */
+-	bool PMawakebcn;	/* bcn recvd during current waking state */
+-	bool PMpending;		/* waiting for tx status with PM indicated set */
+-	bool priorPMstate;	/* Detecting PM state transitions */
+-	bool PSpoll;		/* whether there is an outstanding PS-Poll frame */
+-
+-	/* BSSID entry in RCMTA, use the wsec key management infrastructure to
+-	 * manage the RCMTA entries.
+-	 */
+-	wsec_key_t *rcmta;
+-
+-	/* 'unique' ID of this bsscfg, assigned at bsscfg allocation */
+-	u16 ID;
+-
+-	uint txrspecidx;	/* index into tx rate circular buffer */
+-	ratespec_t txrspec[NTXRATE][2];	/* circular buffer of prev MPDUs tx rates */
+-};
+-
+-#define WLC_BSSCFG_11N_DISABLE	0x1000	/* Do not advertise .11n IEs for this BSS */
+-#define WLC_BSSCFG_HW_BCN	0x20	/* The BSS is generating beacons in HW */
+-
+-#define HWBCN_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0)
+-#define HWPRB_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0)
+-
+-/* Extend N_ENAB to per-BSS */
+-#define BSS_N_ENAB(wlc, cfg) \
+-	(N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE))
+-
+-#define MBSS_BCN_ENAB(cfg)       0
+-#define MBSS_PRB_ENAB(cfg)       0
+-#define SOFTBCN_ENAB(pub)    (0)
+-#define SOFTPRB_ENAB(pub)    (0)
+-#define wlc_bsscfg_tx_check(a) do { } while (0);
+-
+-#endif				/* _WLC_BSSCFG_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
+deleted file mode 100644
+index 85fbd06..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
++++ /dev/null
+@@ -1,280 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_cfg_h_
+-#define _wlc_cfg_h_
+-
+-#define NBANDS(wlc) ((wlc)->pub->_nbands)
+-#define NBANDS_PUB(pub) ((pub)->_nbands)
+-#define NBANDS_HW(hw) ((hw)->_nbands)
+-
+-#define IS_SINGLEBAND_5G(device)	0
+-
+-/* **** Core type/rev defaults **** */
+-#define D11_DEFAULT	0x0fffffb0	/* Supported  D11 revs: 4, 5, 7-27
+-					 * also need to update wlc.h MAXCOREREV
+-					 */
+-
+-#define NPHY_DEFAULT	0x000001ff	/* Supported nphy revs:
+-					 *      0       4321a0
+-					 *      1       4321a1
+-					 *      2       4321b0/b1/c0/c1
+-					 *      3       4322a0
+-					 *      4       4322a1
+-					 *      5       4716a0
+-					 *      6       43222a0, 43224a0
+-					 *      7       43226a0
+-					 *      8       5357a0, 43236a0
+-					 */
+-
+-#define LCNPHY_DEFAULT	0x00000007	/* Supported lcnphy revs:
+-					 *      0       4313a0, 4336a0, 4330a0
+-					 *      1
+-					 *      2       4330a0
+-					 */
+-
+-#define SSLPNPHY_DEFAULT 0x0000000f	/* Supported sslpnphy revs:
+-					 *      0       4329a0/k0
+-					 *      1       4329b0/4329C0
+-					 *      2       4319a0
+-					 *      3       5356a0
+-					 */
+-
+-
+-/* For undefined values, use defaults */
+-#ifndef D11CONF
+-#define D11CONF	D11_DEFAULT
+-#endif
+-#ifndef NCONF
+-#define NCONF	NPHY_DEFAULT
+-#endif
+-#ifndef LCNCONF
+-#define LCNCONF	LCNPHY_DEFAULT
+-#endif
+-
+-#ifndef SSLPNCONF
+-#define SSLPNCONF	SSLPNPHY_DEFAULT
+-#endif
+-
+-/********************************************************************
+- * Phy/Core Configuration.  Defines macros to to check core phy/rev *
+- * compile-time configuration.  Defines default core support.       *
+- * ******************************************************************
+- */
+-
+-/* Basic macros to check a configuration bitmask */
+-
+-#define CONF_HAS(config, val)	((config) & (1 << (val)))
+-#define CONF_MSK(config, mask)	((config) & (mask))
+-#define MSK_RANGE(low, hi)	((1 << ((hi)+1)) - (1 << (low)))
+-#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
+-
+-#define CONF_IS(config, val)	((config) == (1 << (val)))
+-#define CONF_GE(config, val)	((config) & (0-(1 << (val))))
+-#define CONF_GT(config, val)	((config) & (0-2*(1 << (val))))
+-#define CONF_LT(config, val)	((config) & ((1 << (val))-1))
+-#define CONF_LE(config, val)	((config) & (2*(1 << (val))-1))
+-
+-/* Wrappers for some of the above, specific to config constants */
+-
+-#define NCONF_HAS(val)	CONF_HAS(NCONF, val)
+-#define NCONF_MSK(mask)	CONF_MSK(NCONF, mask)
+-#define NCONF_IS(val)	CONF_IS(NCONF, val)
+-#define NCONF_GE(val)	CONF_GE(NCONF, val)
+-#define NCONF_GT(val)	CONF_GT(NCONF, val)
+-#define NCONF_LT(val)	CONF_LT(NCONF, val)
+-#define NCONF_LE(val)	CONF_LE(NCONF, val)
+-
+-#define LCNCONF_HAS(val)	CONF_HAS(LCNCONF, val)
+-#define LCNCONF_MSK(mask)	CONF_MSK(LCNCONF, mask)
+-#define LCNCONF_IS(val)		CONF_IS(LCNCONF, val)
+-#define LCNCONF_GE(val)		CONF_GE(LCNCONF, val)
+-#define LCNCONF_GT(val)		CONF_GT(LCNCONF, val)
+-#define LCNCONF_LT(val)		CONF_LT(LCNCONF, val)
+-#define LCNCONF_LE(val)		CONF_LE(LCNCONF, val)
+-
+-#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
+-#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
+-#define D11CONF_IS(val)	CONF_IS(D11CONF, val)
+-#define D11CONF_GE(val)	CONF_GE(D11CONF, val)
+-#define D11CONF_GT(val)	CONF_GT(D11CONF, val)
+-#define D11CONF_LT(val)	CONF_LT(D11CONF, val)
+-#define D11CONF_LE(val)	CONF_LE(D11CONF, val)
+-
+-#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
+-#define PHYCONF_IS(val)	CONF_IS(PHYTYPE, val)
+-
+-#define NREV_IS(var, val)	(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
+-#define NREV_GE(var, val)	(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
+-#define NREV_GT(var, val)	(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
+-#define NREV_LT(var, val)	(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
+-#define NREV_LE(var, val)	(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
+-
+-#define LCNREV_IS(var, val)	(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
+-#define LCNREV_GE(var, val)	(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
+-#define LCNREV_GT(var, val)	(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
+-#define LCNREV_LT(var, val)	(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
+-#define LCNREV_LE(var, val)	(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
+-
+-#define D11REV_IS(var, val)	(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
+-#define D11REV_GE(var, val)	(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
+-#define D11REV_GT(var, val)	(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
+-#define D11REV_LT(var, val)	(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
+-#define D11REV_LE(var, val)	(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
+-
+-#define PHYTYPE_IS(var, val)	(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
+-
+-/* Finally, early-exit from switch case if anyone wants it... */
+-
+-#define CASECHECK(config, val)	if (!(CONF_HAS(config, val))) break
+-#define CASEMSK(config, mask)	if (!(CONF_MSK(config, mask))) break
+-
+-#if (D11CONF ^ (D11CONF & D11_DEFAULT))
+-#error "Unsupported MAC revision configured"
+-#endif
+-#if (NCONF ^ (NCONF & NPHY_DEFAULT))
+-#error "Unsupported NPHY revision configured"
+-#endif
+-#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT))
+-#error "Unsupported LPPHY revision configured"
+-#endif
+-
+-/* *** Consistency checks *** */
+-#if !D11CONF
+-#error "No MAC revisions configured!"
+-#endif
+-
+-#if !NCONF && !LCNCONF && !SSLPNCONF
+-#error "No PHY configured!"
+-#endif
+-
+-/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
+-
+-#define _PHYCONF_N (1 << PHY_TYPE_N)
+-
+-#if LCNCONF
+-#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
+-#else
+-#define _PHYCONF_LCN 0
+-#endif				/* LCNCONF */
+-
+-#if SSLPNCONF
+-#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
+-#else
+-#define _PHYCONF_SSLPN 0
+-#endif				/* SSLPNCONF */
+-
+-#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
+-
+-/* Utility macro to identify 802.11n (HT) capable PHYs */
+-#define PHYTYPE_11N_CAP(phytype) \
+-	(PHYTYPE_IS(phytype, PHY_TYPE_N) ||	\
+-	 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
+-	 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
+-
+-/* Last but not least: shorter wlc-specific var checks */
+-#define WLCISNPHY(band)		PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
+-#define WLCISLCNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
+-#define WLCISSSLPNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
+-
+-#define WLC_PHY_11N_CAP(band)	PHYTYPE_11N_CAP((band)->phytype)
+-
+-/**********************************************************************
+- * ------------- End of Core phy/rev configuration. ----------------- *
+- * ********************************************************************
+- */
+-
+-/*************************************************
+- * Defaults for tunables (e.g. sizing constants)
+- *
+- * For each new tunable, add a member to the end
+- * of wlc_tunables_t in wlc_pub.h to enable
+- * runtime checks of tunable values. (Directly
+- * using the macros in code invalidates ROM code)
+- *
+- * ***********************************************
+- */
+-#ifndef NTXD
+-#define NTXD		256	/* Max # of entries in Tx FIFO based on 4kb page size */
+-#endif				/* NTXD */
+-#ifndef NRXD
+-#define NRXD		256	/* Max # of entries in Rx FIFO based on 4kb page size */
+-#endif				/* NRXD */
+-
+-#ifndef NRXBUFPOST
+-#define	NRXBUFPOST	32	/* try to keep this # rbufs posted to the chip */
+-#endif				/* NRXBUFPOST */
+-
+-#ifndef MAXSCB			/* station control blocks in cache */
+-#define MAXSCB		32	/* Maximum SCBs in cache for STA */
+-#endif				/* MAXSCB */
+-
+-#ifndef AMPDU_NUM_MPDU
+-#define AMPDU_NUM_MPDU		16	/* max allowed number of mpdus in an ampdu (2 streams) */
+-#endif				/* AMPDU_NUM_MPDU */
+-
+-#ifndef AMPDU_NUM_MPDU_3STREAMS
+-#define AMPDU_NUM_MPDU_3STREAMS	32	/* max allowed number of mpdus in an ampdu for 3+ streams */
+-#endif				/* AMPDU_NUM_MPDU_3STREAMS */
+-
+-/* Count of packet callback structures. either of following
+- * 1. Set to the number of SCBs since a STA
+- * can queue up a rate callback for each IBSS STA it knows about, and an AP can
+- * queue up an "are you there?" Null Data callback for each associated STA
+- * 2. controlled by tunable config file
+- */
+-#ifndef MAXPKTCB
+-#define MAXPKTCB	MAXSCB	/* Max number of packet callbacks */
+-#endif				/* MAXPKTCB */
+-
+-#ifndef CTFPOOLSZ
+-#define CTFPOOLSZ       128
+-#endif				/* CTFPOOLSZ */
+-
+-/* NetBSD also needs to keep track of this */
+-#define WLC_MAX_UCODE_BSS	(16)	/* Number of BSS handled in ucode bcn/prb */
+-#define WLC_MAX_UCODE_BSS4	(4)	/* Number of BSS handled in sw bcn/prb */
+-#ifndef WLC_MAXBSSCFG
+-#define WLC_MAXBSSCFG		(1)	/* max # BSS configs */
+-#endif				/* WLC_MAXBSSCFG */
+-
+-#ifndef MAXBSS
+-#define MAXBSS		64	/* max # available networks */
+-#endif				/* MAXBSS */
+-
+-#ifndef WLC_DATAHIWAT
+-#define WLC_DATAHIWAT		50	/* data msg txq hiwat mark */
+-#endif				/* WLC_DATAHIWAT */
+-
+-#ifndef WLC_AMPDUDATAHIWAT
+-#define WLC_AMPDUDATAHIWAT 255
+-#endif				/* WLC_AMPDUDATAHIWAT */
+-
+-/* bounded rx loops */
+-#ifndef RXBND
+-#define RXBND		8	/* max # frames to process in wlc_recv() */
+-#endif				/* RXBND */
+-#ifndef TXSBND
+-#define TXSBND		8	/* max # tx status to process in wlc_txstatus() */
+-#endif				/* TXSBND */
+-
+-#define BAND_5G(bt)	((bt) == WLC_BAND_5G)
+-#define BAND_2G(bt)	((bt) == WLC_BAND_2G)
+-
+-#define WLBANDINITDATA(_data)	_data
+-#define WLBANDINITFN(_fn)	_fn
+-
+-#endif				/* _wlc_cfg_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c
+deleted file mode 100644
+index a3a2bf9..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c
++++ /dev/null
+@@ -1,1557 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <sbhnddma.h>
+-#include <wlioctl.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_bmac.h"
+-#include "wlc_rate.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_stf.h"
+-#include "wl_dbg.h"
+-
+-#define	VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val)
+-#define	VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \
+-	wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val)
+-#define	VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val)
+-
+-typedef struct wlc_cm_band {
+-	u8 locale_flags;	/* locale_info_t flags */
+-	chanvec_t valid_channels;	/* List of valid channels in the country */
+-	const chanvec_t *restricted_channels;	/* List of restricted use channels */
+-	const chanvec_t *radar_channels;	/* List of radar sensitive channels */
+-	u8 PAD[8];
+-} wlc_cm_band_t;
+-
+-struct wlc_cm_info {
+-	struct wlc_pub *pub;
+-	struct wlc_info *wlc;
+-	char srom_ccode[WLC_CNTRY_BUF_SZ];	/* Country Code in SROM */
+-	uint srom_regrev;	/* Regulatory Rev for the SROM ccode */
+-	const country_info_t *country;	/* current country def */
+-	char ccode[WLC_CNTRY_BUF_SZ];	/* current internal Country Code */
+-	uint regrev;		/* current Regulatory Revision */
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];	/* current advertised ccode */
+-	wlc_cm_band_t bandstate[MAXBANDS];	/* per-band state (one per phy/radio) */
+-	/* quiet channels currently for radar sensitivity or 11h support */
+-	chanvec_t quiet_channels;	/* channels on which we cannot transmit */
+-};
+-
+-static int wlc_channels_init(wlc_cm_info_t *wlc_cm,
+-			     const country_info_t *country);
+-static void wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+-				   const char *country_abbrev,
+-				   const char *ccode, uint regrev,
+-				   const country_info_t *country);
+-static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode);
+-static int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+-				   const char *country_abbrev,
+-				   const char *ccode, int regrev);
+-static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+-				     char *mapped_ccode, uint *mapped_regrev);
+-static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+-						       uint regrev);
+-static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+-						 const char *ccode,
+-						 char *mapped_ccode,
+-						 uint *mapped_regrev);
+-static void wlc_channels_commit(wlc_cm_info_t *wlc_cm);
+-static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm);
+-static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+-static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val);
+-static bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit,
+-					uint val);
+-static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val);
+-static const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+-						const char *ccode);
+-static void wlc_locale_get_channels(const locale_info_t *locale,
+-				    chanvec_t *valid_channels);
+-static const locale_info_t *wlc_get_locale_2g(u8 locale_idx);
+-static const locale_info_t *wlc_get_locale_5g(u8 locale_idx);
+-static bool wlc_japan(struct wlc_info *wlc);
+-static bool wlc_japan_ccode(const char *ccode);
+-static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *
+-								 wlc_cm,
+-								 struct
+-								 txpwr_limits
+-								 *txpwr,
+-								 u8
+-								 local_constraint_qdbm);
+-static void wlc_locale_add_channels(chanvec_t *target,
+-				    const chanvec_t *channels);
+-static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx);
+-static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx);
+-
+-/* QDB() macro takes a dB value and converts to a quarter dB value */
+-#ifdef QDB
+-#undef QDB
+-#endif
+-#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR)
+-
+-/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
+-
+-/*
+- * Some common channel sets
+- */
+-
+-/* No channels */
+-static const chanvec_t chanvec_none = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* All 2.4 GHz HW channels */
+-const chanvec_t chanvec_all_2G = {
+-	{0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* All 5 GHz HW channels */
+-const chanvec_t chanvec_all_5G = {
+-	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
+-	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
+-	 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
+-	 0x11, 0x11, 0x11, 0x01}
+-};
+-
+-/*
+- * Radar channel sets
+- */
+-
+-/* No radar */
+-#define radar_set_none chanvec_none
+-
+-static const chanvec_t radar_set1 = {	/* Channels 52 - 64, 100 - 140 */
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,	/* 52 - 60 */
+-	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,	/* 64, 100 - 124 */
+-	 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 128 - 140 */
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/*
+- * Restricted channel sets
+- */
+-
+-#define restricted_set_none chanvec_none
+-
+-/* Channels 34, 38, 42, 46 */
+-static const chanvec_t restricted_set_japan_legacy = {
+-	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 12, 13 */
+-static const chanvec_t restricted_set_2g_short = {
+-	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channel 165 */
+-static const chanvec_t restricted_chan_165 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 36 - 48 & 149 - 165 */
+-static const chanvec_t restricted_low_hi = {
+-	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 12 - 14 */
+-static const chanvec_t restricted_set_12_13_14 = {
+-	{0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-#define  LOCALE_CHAN_01_11	 (1<<0)
+-#define  LOCALE_CHAN_12_13	 (1<<1)
+-#define  LOCALE_CHAN_14		 (1<<2)
+-#define  LOCALE_SET_5G_LOW_JP1   (1<<3)	/* 34-48, step 2 */
+-#define  LOCALE_SET_5G_LOW_JP2   (1<<4)	/* 34-46, step 4 */
+-#define  LOCALE_SET_5G_LOW1      (1<<5)	/* 36-48, step 4 */
+-#define  LOCALE_SET_5G_LOW2      (1<<6)	/* 52 */
+-#define  LOCALE_SET_5G_LOW3      (1<<7)	/* 56-64, step 4 */
+-#define  LOCALE_SET_5G_MID1      (1<<8)	/* 100-116, step 4 */
+-#define  LOCALE_SET_5G_MID2	 (1<<9)	/* 120-124, step 4 */
+-#define  LOCALE_SET_5G_MID3      (1<<10)	/* 128 */
+-#define  LOCALE_SET_5G_HIGH1     (1<<11)	/* 132-140, step 4 */
+-#define  LOCALE_SET_5G_HIGH2     (1<<12)	/* 149-161, step 4 */
+-#define  LOCALE_SET_5G_HIGH3     (1<<13)	/* 165 */
+-#define  LOCALE_CHAN_52_140_ALL  (1<<14)
+-#define  LOCALE_SET_5G_HIGH4     (1<<15)	/* 184-216 */
+-
+-#define  LOCALE_CHAN_36_64       (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+-#define  LOCALE_CHAN_52_64       (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+-#define  LOCALE_CHAN_100_124	 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
+-#define  LOCALE_CHAN_100_140     \
+-	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
+-#define  LOCALE_CHAN_149_165     (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
+-#define  LOCALE_CHAN_184_216     LOCALE_SET_5G_HIGH4
+-
+-#define  LOCALE_CHAN_01_14	(LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14)
+-
+-#define  LOCALE_RADAR_SET_NONE		  0
+-#define  LOCALE_RADAR_SET_1		  1
+-
+-#define  LOCALE_RESTRICTED_NONE		  0
+-#define  LOCALE_RESTRICTED_SET_2G_SHORT   1
+-#define  LOCALE_RESTRICTED_CHAN_165       2
+-#define  LOCALE_CHAN_ALL_5G		  3
+-#define  LOCALE_RESTRICTED_JAPAN_LEGACY   4
+-#define  LOCALE_RESTRICTED_11D_2G	  5
+-#define  LOCALE_RESTRICTED_11D_5G	  6
+-#define  LOCALE_RESTRICTED_LOW_HI	  7
+-#define  LOCALE_RESTRICTED_12_13_14	  8
+-
+-/* global memory to provide working buffer for expanded locale */
+-
+-static const chanvec_t *g_table_radar_set[] = {
+-	&chanvec_none,
+-	&radar_set1
+-};
+-
+-static const chanvec_t *g_table_restricted_chan[] = {
+-	&chanvec_none,		/* restricted_set_none */
+-	&restricted_set_2g_short,
+-	&restricted_chan_165,
+-	&chanvec_all_5G,
+-	&restricted_set_japan_legacy,
+-	&chanvec_all_2G,	/* restricted_set_11d_2G */
+-	&chanvec_all_5G,	/* restricted_set_11d_5G */
+-	&restricted_low_hi,
+-	&restricted_set_12_13_14
+-};
+-
+-static const chanvec_t locale_2g_01_11 = {
+-	{0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_2g_12_13 = {
+-	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_2g_14 = {
+-	{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW_JP1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW_JP2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_52_140_ALL = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
+-	 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+-	 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH4 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x11, 0x11, 0x11, 0x11}
+-};
+-
+-static const chanvec_t *g_table_locale_base[] = {
+-	&locale_2g_01_11,
+-	&locale_2g_12_13,
+-	&locale_2g_14,
+-	&locale_5g_LOW_JP1,
+-	&locale_5g_LOW_JP2,
+-	&locale_5g_LOW1,
+-	&locale_5g_LOW2,
+-	&locale_5g_LOW3,
+-	&locale_5g_MID1,
+-	&locale_5g_MID2,
+-	&locale_5g_MID3,
+-	&locale_5g_HIGH1,
+-	&locale_5g_HIGH2,
+-	&locale_5g_HIGH3,
+-	&locale_5g_52_140_ALL,
+-	&locale_5g_HIGH4
+-};
+-
+-static void wlc_locale_add_channels(chanvec_t *target,
+-				    const chanvec_t *channels)
+-{
+-	u8 i;
+-	for (i = 0; i < sizeof(chanvec_t); i++) {
+-		target->vec[i] |= channels->vec[i];
+-	}
+-}
+-
+-static void wlc_locale_get_channels(const locale_info_t *locale,
+-				    chanvec_t *channels)
+-{
+-	u8 i;
+-
+-	memset(channels, 0, sizeof(chanvec_t));
+-
+-	for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
+-		if (locale->valid_channels & (1 << i)) {
+-			wlc_locale_add_channels(channels,
+-						g_table_locale_base[i]);
+-		}
+-	}
+-}
+-
+-/*
+- * Locale Definitions - 2.4 GHz
+- */
+-static const locale_info_t locale_i = {	/* locale i. channel 1 - 13 */
+-	LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
+-	LOCALE_RADAR_SET_NONE,
+-	LOCALE_RESTRICTED_SET_2G_SHORT,
+-	{QDB(19), QDB(19), QDB(19),
+-	 QDB(19), QDB(19), QDB(19)},
+-	{20, 20, 20, 0},
+-	WLC_EIRP
+-};
+-
+-/*
+- * Locale Definitions - 5 GHz
+- */
+-static const locale_info_t locale_11 = {
+-	/* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
+-	LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
+-	LOCALE_RADAR_SET_1,
+-	LOCALE_RESTRICTED_NONE,
+-	{QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
+-	{23, 23, 23, 30, 30},
+-	WLC_EIRP | WLC_DFS_EU
+-};
+-
+-#define LOCALE_2G_IDX_i			0
+-static const locale_info_t *g_locale_2g_table[] = {
+-	&locale_i
+-};
+-
+-#define LOCALE_5G_IDX_11	0
+-static const locale_info_t *g_locale_5g_table[] = {
+-	&locale_11
+-};
+-
+-/*
+- * MIMO Locale Definitions - 2.4 GHz
+- */
+-static const locale_mimo_info_t locale_bn = {
+-	{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13)},
+-	{0, 0, QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), 0, 0},
+-	0
+-};
+-
+-/* locale mimo 2g indexes */
+-#define LOCALE_MIMO_IDX_bn			0
+-
+-static const locale_mimo_info_t *g_mimo_2g_table[] = {
+-	&locale_bn
+-};
+-
+-/*
+- * MIMO Locale Definitions - 5 GHz
+- */
+-static const locale_mimo_info_t locale_11n = {
+-	{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
+-	{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
+-	0
+-};
+-
+-#define LOCALE_MIMO_IDX_11n			0
+-static const locale_mimo_info_t *g_mimo_5g_table[] = {
+-	&locale_11n
+-};
+-
+-#ifdef LC
+-#undef LC
+-#endif
+-#define LC(id)	LOCALE_MIMO_IDX_ ## id
+-
+-#ifdef LC_2G
+-#undef LC_2G
+-#endif
+-#define LC_2G(id)	LOCALE_2G_IDX_ ## id
+-
+-#ifdef LC_5G
+-#undef LC_5G
+-#endif
+-#define LC_5G(id)	LOCALE_5G_IDX_ ## id
+-
+-#define LOCALES(band2, band5, mimo2, mimo5)     {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
+-
+-static const struct {
+-	char abbrev[WLC_CNTRY_BUF_SZ];	/* country abbreviation */
+-	country_info_t country;
+-} cntry_locales[] = {
+-	{
+-	"X2", LOCALES(i, 11, bn, 11n)},	/* Worldwide RoW 2 */
+-};
+-
+-#ifdef SUPPORT_40MHZ
+-/* 20MHz channel info for 40MHz pairing support */
+-struct chan20_info {
+-	u8 sb;
+-	u8 adj_sbs;
+-};
+-
+-/* indicates adjacent channels that are allowed for a 40 Mhz channel and
+- * those that permitted by the HT
+- */
+-struct chan20_info chan20_info[] = {
+-	/* 11b/11g */
+-/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 11 */ {12, (CH_LOWER_SB)},
+-/* 12 */ {13, (CH_LOWER_SB)},
+-/* 13 */ {14, (CH_LOWER_SB)},
+-
+-/* 11a japan high */
+-/* 14 */ {34, (CH_UPPER_SB)},
+-/* 15 */ {38, (CH_LOWER_SB)},
+-/* 16 */ {42, (CH_LOWER_SB)},
+-/* 17 */ {46, (CH_LOWER_SB)},
+-
+-/* 11a usa low */
+-/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
+-
+-/* 11a Europe */
+-/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 36 */ {140, (CH_LOWER_SB)},
+-
+-/* 11a usa high, ref5 only */
+-/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
+-/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 41 */ {165, (CH_LOWER_SB)},
+-
+-/* 11a japan */
+-/* 42 */ {184, (CH_UPPER_SB)},
+-/* 43 */ {188, (CH_LOWER_SB)},
+-/* 44 */ {192, (CH_UPPER_SB)},
+-/* 45 */ {196, (CH_LOWER_SB)},
+-/* 46 */ {200, (CH_UPPER_SB)},
+-/* 47 */ {204, (CH_LOWER_SB)},
+-/* 48 */ {208, (CH_UPPER_SB)},
+-/* 49 */ {212, (CH_LOWER_SB)},
+-/* 50 */ {216, (CH_LOWER_SB)}
+-};
+-#endif				/* SUPPORT_40MHZ */
+-
+-static const locale_info_t *wlc_get_locale_2g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) {
+-		return NULL; /* error condition */
+-	}
+-	return g_locale_2g_table[locale_idx];
+-}
+-
+-static const locale_info_t *wlc_get_locale_5g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) {
+-		return NULL; /* error condition */
+-	}
+-	return g_locale_5g_table[locale_idx];
+-}
+-
+-static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) {
+-		return NULL;
+-	}
+-	return g_mimo_2g_table[locale_idx];
+-}
+-
+-static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) {
+-		return NULL;
+-	}
+-	return g_mimo_5g_table[locale_idx];
+-}
+-
+-wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc)
+-{
+-	wlc_cm_info_t *wlc_cm;
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	const country_info_t *country;
+-	struct wlc_pub *pub = wlc->pub;
+-	char *ccode;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC);
+-	if (wlc_cm == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit,
+-			  __func__);
+-		return NULL;
+-	}
+-	wlc_cm->pub = pub;
+-	wlc_cm->wlc = wlc;
+-	wlc->cmi = wlc_cm;
+-
+-	/* store the country code for passing up as a regulatory hint */
+-	ccode = getvar(wlc->pub->vars, "ccode");
+-	if (ccode) {
+-		strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+-	}
+-
+-	/* internal country information which must match regulatory constraints in firmware */
+-	memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ);
+-	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
+-	country = wlc_country_lookup(wlc, country_abbrev);
+-
+-	/* save default country for exiting 11d regulatory mode */
+-	strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+-
+-	/* initialize autocountry_default to driver default */
+-	strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1);
+-
+-	wlc_set_countrycode(wlc_cm, country_abbrev);
+-
+-	return wlc_cm;
+-}
+-
+-void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm)
+-{
+-	kfree(wlc_cm);
+-}
+-
+-u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
+-{
+-	return wlc_cm->bandstate[bandunit].locale_flags;
+-}
+-
+-/* set the driver's current country and regulatory information using a country code
+- * as the source. Lookup built in country information found with the country code.
+- */
+-static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode)
+-{
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ);
+-	return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
+-}
+-
+-static int
+-wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+-			const char *country_abbrev,
+-			const char *ccode, int regrev)
+-{
+-	const country_info_t *country;
+-	char mapped_ccode[WLC_CNTRY_BUF_SZ];
+-	uint mapped_regrev;
+-
+-	/* if regrev is -1, lookup the mapped country code,
+-	 * otherwise use the ccode and regrev directly
+-	 */
+-	if (regrev == -1) {
+-		/* map the country code to a built-in country code, regrev, and country_info */
+-		country =
+-		    wlc_countrycode_map(wlc_cm, ccode, mapped_ccode,
+-					&mapped_regrev);
+-	} else {
+-		/* find the matching built-in country definition */
+-		country = wlc_country_lookup_direct(ccode, regrev);
+-		strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+-		mapped_regrev = regrev;
+-	}
+-
+-	if (country == NULL)
+-		return -EINVAL;
+-
+-	/* set the driver state for the country */
+-	wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
+-			       mapped_regrev, country);
+-
+-	return 0;
+-}
+-
+-/* set the driver's current country and regulatory information using a country code
+- * as the source. Look up built in country information found with the country code.
+- */
+-static void
+-wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+-		       const char *country_abbrev,
+-		       const char *ccode, uint regrev,
+-		       const country_info_t *country)
+-{
+-	const locale_mimo_info_t *li_mimo;
+-	const locale_info_t *locale;
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	char prev_country_abbrev[WLC_CNTRY_BUF_SZ];
+-
+-	/* save current country state */
+-	wlc_cm->country = country;
+-
+-	memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ);
+-	strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
+-		WLC_CNTRY_BUF_SZ - 1);
+-
+-	strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+-	strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+-	wlc_cm->regrev = regrev;
+-
+-	/* disable/restore nmode based on country regulations */
+-	li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G);
+-	if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) {
+-		wlc_set_nmode(wlc, OFF);
+-		wlc->stf->no_cddstbc = true;
+-	} else {
+-		wlc->stf->no_cddstbc = false;
+-		if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
+-			wlc_set_nmode(wlc, wlc->protection->nmode_user);
+-	}
+-
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-	/* set or restore gmode as required by regulatory */
+-	locale = wlc_get_locale_2g(country->locale_2G);
+-	if (locale && (locale->flags & WLC_NO_OFDM)) {
+-		wlc_set_gmode(wlc, GMODE_LEGACY_B, false);
+-	} else {
+-		wlc_set_gmode(wlc, wlc->protection->gmode_user, false);
+-	}
+-
+-	wlc_channels_init(wlc_cm, country);
+-
+-	return;
+-}
+-
+-/* Lookup a country info structure from a null terminated country code
+- * The lookup is case sensitive.
+- */
+-static const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+-					 const char *ccode)
+-{
+-	const country_info_t *country;
+-	char mapped_ccode[WLC_CNTRY_BUF_SZ];
+-	uint mapped_regrev;
+-
+-	/* map the country code to a built-in country code, regrev, and country_info struct */
+-	country =
+-	    wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev);
+-
+-	return country;
+-}
+-
+-static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+-						 const char *ccode,
+-						 char *mapped_ccode,
+-						 uint *mapped_regrev)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	const country_info_t *country;
+-	uint srom_regrev = wlc_cm->srom_regrev;
+-	const char *srom_ccode = wlc_cm->srom_ccode;
+-	int mapped;
+-
+-	/* check for currently supported ccode size */
+-	if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
+-			  "match\n", wlc->pub->unit, __func__, ccode);
+-		return NULL;
+-	}
+-
+-	/* default mapping is the given ccode and regrev 0 */
+-	strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+-	*mapped_regrev = 0;
+-
+-	/* If the desired country code matches the srom country code,
+-	 * then the mapped country is the srom regulatory rev.
+-	 * Otherwise look for an aggregate mapping.
+-	 */
+-	if (!strcmp(srom_ccode, ccode)) {
+-		*mapped_regrev = srom_regrev;
+-		mapped = 0;
+-		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
+-	} else {
+-		mapped =
+-		    wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
+-					      mapped_regrev);
+-	}
+-
+-	/* find the matching built-in country definition */
+-	country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+-
+-	/* if there is not an exact rev match, default to rev zero */
+-	if (country == NULL && *mapped_regrev != 0) {
+-		*mapped_regrev = 0;
+-		country =
+-		    wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+-	}
+-
+-	return country;
+-}
+-
+-static int
+-wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+-			  char *mapped_ccode, uint *mapped_regrev)
+-{
+-	return false;
+-}
+-
+-/* Lookup a country info structure from a null terminated country
+- * abbreviation and regrev directly with no translation.
+- */
+-static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+-						       uint regrev)
+-{
+-	uint size, i;
+-
+-	/* Should just return 0 for single locale driver. */
+-	/* Keep it this way in case we add more locales. (for now anyway) */
+-
+-	/* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
+-	if (regrev > 0)
+-		return NULL;
+-
+-	/* find matched table entry from country code */
+-	size = ARRAY_SIZE(cntry_locales);
+-	for (i = 0; i < size; i++) {
+-		if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
+-			return &cntry_locales[i].country;
+-		}
+-	}
+-	return NULL;
+-}
+-
+-static int
+-wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i, j;
+-	struct wlcband *band;
+-	const locale_info_t *li;
+-	chanvec_t sup_chan;
+-	const locale_mimo_info_t *li_mimo;
+-
+-	band = wlc->band;
+-	for (i = 0; i < NBANDS(wlc);
+-	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+-
+-		li = BAND_5G(band->bandtype) ?
+-		    wlc_get_locale_5g(country->locale_5G) :
+-		    wlc_get_locale_2g(country->locale_2G);
+-		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
+-		li_mimo = BAND_5G(band->bandtype) ?
+-		    wlc_get_mimo_5g(country->locale_mimo_5G) :
+-		    wlc_get_mimo_2g(country->locale_mimo_2G);
+-
+-		/* merge the mimo non-mimo locale flags */
+-		wlc_cm->bandstate[band->bandunit].locale_flags |=
+-		    li_mimo->flags;
+-
+-		wlc_cm->bandstate[band->bandunit].restricted_channels =
+-		    g_table_restricted_chan[li->restricted_channels];
+-		wlc_cm->bandstate[band->bandunit].radar_channels =
+-		    g_table_radar_set[li->radar_channels];
+-
+-		/* set the channel availability,
+-		 * masking out the channels that may not be supported on this phy
+-		 */
+-		wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
+-					      &sup_chan);
+-		wlc_locale_get_channels(li,
+-					&wlc_cm->bandstate[band->bandunit].
+-					valid_channels);
+-		for (j = 0; j < sizeof(chanvec_t); j++)
+-			wlc_cm->bandstate[band->bandunit].valid_channels.
+-			    vec[j] &= sup_chan.vec[j];
+-	}
+-
+-	wlc_quiet_channels_reset(wlc_cm);
+-	wlc_channels_commit(wlc_cm);
+-
+-	return 0;
+-}
+-
+-/* Update the radio state (enable/disable) and tx power targets
+- * based on a new set of channel/regulatory information
+- */
+-static void wlc_channels_commit(wlc_cm_info_t *wlc_cm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint chan;
+-	struct txpwr_limits txpwr;
+-
+-	/* search for the existence of any valid channel */
+-	for (chan = 0; chan < MAXCHANNEL; chan++) {
+-		if (VALID_CHANNEL20_DB(wlc, chan)) {
+-			break;
+-		}
+-	}
+-	if (chan == MAXCHANNEL)
+-		chan = INVCHANNEL;
+-
+-	/* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */
+-	if (chan == INVCHANNEL) {
+-		/* country/locale with no valid channels, set the radio disable bit */
+-		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+-		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
+-			  "nbands %d bandlocked %d\n", wlc->pub->unit,
+-			  __func__, wlc_cm->country_abbrev, NBANDS(wlc),
+-			  wlc->bandlocked);
+-	} else
+-	    if (mboolisset(wlc->pub->radio_disabled,
+-		WL_RADIO_COUNTRY_DISABLE)) {
+-		/* country/locale with valid channel, clear the radio disable bit */
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+-	}
+-
+-	/* Now that the country abbreviation is set, if the radio supports 2G, then
+-	 * set channel 14 restrictions based on the new locale.
+-	 */
+-	if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) {
+-		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
+-						     wlc_japan(wlc) ? true :
+-						     false);
+-	}
+-
+-	if (wlc->pub->up && chan != INVCHANNEL) {
+-		wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
+-		wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm,
+-								     &txpwr,
+-								     WLC_TXPWR_MAX);
+-		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
+-	}
+-}
+-
+-/* reset the quiet channels vector to the union of the restricted and radar channel sets */
+-static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i, j;
+-	struct wlcband *band;
+-	const chanvec_t *chanvec;
+-
+-	memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t));
+-
+-	band = wlc->band;
+-	for (i = 0; i < NBANDS(wlc);
+-	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+-
+-		/* initialize quiet channels for restricted channels */
+-		chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
+-		for (j = 0; j < sizeof(chanvec_t); j++)
+-			wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
+-
+-	}
+-}
+-
+-static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+-{
+-	return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
+-		(isset
+-		 (wlc_cm->quiet_channels.vec,
+-		  LOWER_20_SB(CHSPEC_CHANNEL(chspec)))
+-		 || isset(wlc_cm->quiet_channels.vec,
+-			  UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm->
+-									quiet_channels.
+-									vec,
+-									CHSPEC_CHANNEL
+-									(chspec));
+-}
+-
+-/* Is the channel valid for the current locale? (but don't consider channels not
+- *   available due to bandlocking)
+- */
+-static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-
+-	return VALID_CHANNEL20(wlc, val) ||
+-		(!wlc->bandlocked
+-		 && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
+-}
+-
+-/* Is the channel valid for the current locale and specified band? */
+-static bool
+-wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val)
+-{
+-	return ((val < MAXCHANNEL)
+-		&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
+-}
+-
+-/* Is the channel valid for the current locale and current band? */
+-static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-
+-	return ((val < MAXCHANNEL) &&
+-		isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
+-		      val));
+-}
+-
+-static void
+-wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm,
+-						     struct txpwr_limits *txpwr,
+-						     u8
+-						     local_constraint_qdbm)
+-{
+-	int j;
+-
+-	/* CCK Rates */
+-	for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) {
+-		txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20 MHz Legacy OFDM SISO */
+-	for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) {
+-		txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20 MHz Legacy OFDM CDD */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_cdd[j] =
+-		    min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40 MHz Legacy OFDM SISO */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_40_siso[j] =
+-		    min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40 MHz Legacy OFDM CDD */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_40_cdd[j] =
+-		    min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 SISO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_siso[j] =
+-		    min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 CDD */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_cdd[j] =
+-		    min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 STBC */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_stbc[j] =
+-		    min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 8-15 MIMO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+-		txpwr->mcs_20_mimo[j] =
+-		    min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
+-
+-	/* 40MHz MCS 0-7 SISO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_siso[j] =
+-		    min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 0-7 CDD */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_cdd[j] =
+-		    min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 0-7 STBC */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_stbc[j] =
+-		    min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 8-15 MIMO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+-		txpwr->mcs_40_mimo[j] =
+-		    min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
+-
+-	/* 40MHz MCS 32 */
+-	txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
+-
+-}
+-
+-void
+-wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+-			 u8 local_constraint_qdbm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	struct txpwr_limits txpwr;
+-
+-	wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr);
+-
+-	wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr,
+-							     local_constraint_qdbm);
+-
+-	wlc_bmac_set_chanspec(wlc->hw, chanspec,
+-			      (wlc_quiet_chanspec(wlc_cm, chanspec) != 0),
+-			      &txpwr);
+-}
+-
+-#ifdef POWER_DBG
+-static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr)
+-{
+-	int i;
+-	char buf[80];
+-	char fraction[4][4] = { "   ", ".25", ".5 ", ".75" };
+-
+-	sprintf(buf, "CCK                ");
+-	for (i = 0; i < WLC_NUM_RATES_CCK; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->cck[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz OFDM SISO   ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz OFDM CDD    ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz OFDM SISO   ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz OFDM CDD    ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 SISO ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 CDD  ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 STBC ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS8-15 SDM ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 SISO ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 CDD  ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 STBC ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS8-15 SDM ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	printk(KERN_DEBUG "MCS32               %2d%s\n",
+-	       txpwr->mcs32 / WLC_TXPWR_DB_FACTOR,
+-	       fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]);
+-}
+-#endif				/* POWER_DBG */
+-
+-void
+-wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+-		       txpwr_limits_t *txpwr)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i;
+-	uint chan;
+-	int maxpwr;
+-	int delta;
+-	const country_info_t *country;
+-	struct wlcband *band;
+-	const locale_info_t *li;
+-	int conducted_max;
+-	int conducted_ofdm_max;
+-	const locale_mimo_info_t *li_mimo;
+-	int maxpwr20, maxpwr40;
+-	int maxpwr_idx;
+-	uint j;
+-
+-	memset(txpwr, 0, sizeof(txpwr_limits_t));
+-
+-	if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) {
+-		country = wlc_country_lookup(wlc, wlc->autocountry_default);
+-		if (country == NULL)
+-			return;
+-	} else {
+-		country = wlc_cm->country;
+-	}
+-
+-	chan = CHSPEC_CHANNEL(chanspec);
+-	band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)];
+-	li = BAND_5G(band->bandtype) ?
+-	    wlc_get_locale_5g(country->locale_5G) :
+-	    wlc_get_locale_2g(country->locale_2G);
+-
+-	li_mimo = BAND_5G(band->bandtype) ?
+-	    wlc_get_mimo_5g(country->locale_mimo_5G) :
+-	    wlc_get_mimo_2g(country->locale_mimo_2G);
+-
+-	if (li->flags & WLC_EIRP) {
+-		delta = band->antgain;
+-	} else {
+-		delta = 0;
+-		if (band->antgain > QDB(6))
+-			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
+-	}
+-
+-	if (li == &locale_i) {
+-		conducted_max = QDB(22);
+-		conducted_ofdm_max = QDB(22);
+-	}
+-
+-	/* CCK txpwr limits for 2.4G band */
+-	if (BAND_2G(band->bandtype)) {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
+-
+-		maxpwr = maxpwr - delta;
+-		maxpwr = max(maxpwr, 0);
+-		maxpwr = min(maxpwr, conducted_max);
+-
+-		for (i = 0; i < WLC_NUM_RATES_CCK; i++)
+-			txpwr->cck[i] = (u8) maxpwr;
+-	}
+-
+-	/* OFDM txpwr limits for 2.4G or 5G bands */
+-	if (BAND_2G(band->bandtype)) {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
+-
+-	} else {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
+-	}
+-
+-	maxpwr = maxpwr - delta;
+-	maxpwr = max(maxpwr, 0);
+-	maxpwr = min(maxpwr, conducted_ofdm_max);
+-
+-	/* Keep OFDM lmit below CCK limit */
+-	if (BAND_2G(band->bandtype))
+-		maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
+-
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		txpwr->ofdm[i] = (u8) maxpwr;
+-	}
+-
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		/* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless
+-		 * overriden by the locale specific code. We set this value to 0 as a
+-		 * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
+-		 * to the 40 MHz value if it wasn't explicitly set.
+-		 */
+-		txpwr->ofdm_40_siso[i] = 0;
+-
+-		txpwr->ofdm_cdd[i] = (u8) maxpwr;
+-
+-		txpwr->ofdm_40_cdd[i] = 0;
+-	}
+-
+-	/* MIMO/HT specific limits */
+-	if (li_mimo->flags & WLC_EIRP) {
+-		delta = band->antgain;
+-	} else {
+-		delta = 0;
+-		if (band->antgain > QDB(6))
+-			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
+-	}
+-
+-	if (BAND_2G(band->bandtype))
+-		maxpwr_idx = (chan - 1);
+-	else
+-		maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
+-
+-	maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
+-	maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
+-
+-	maxpwr20 = maxpwr20 - delta;
+-	maxpwr20 = max(maxpwr20, 0);
+-	maxpwr40 = maxpwr40 - delta;
+-	maxpwr40 = max(maxpwr40, 0);
+-
+-	/* Fill in the MCS 0-7 (SISO) rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-
+-		/* 20 MHz has the same power as the corresponding OFDM rate unless
+-		 * overriden by the locale specific code.
+-		 */
+-		txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
+-		txpwr->mcs_40_siso[i] = 0;
+-	}
+-
+-	/* Fill in the MCS 0-7 CDD rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
+-		txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
+-	}
+-
+-	/* These locales have SISO expressed in the table and override CDD later */
+-	if (li_mimo == &locale_bn) {
+-		if (li_mimo == &locale_bn) {
+-			maxpwr20 = QDB(16);
+-			maxpwr40 = 0;
+-
+-			if (chan >= 3 && chan <= 11) {
+-				maxpwr40 = QDB(16);
+-			}
+-		}
+-
+-		for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-			txpwr->mcs_20_siso[i] = (u8) maxpwr20;
+-			txpwr->mcs_40_siso[i] = (u8) maxpwr40;
+-		}
+-	}
+-
+-	/* Fill in the MCS 0-7 STBC rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		txpwr->mcs_20_stbc[i] = 0;
+-		txpwr->mcs_40_stbc[i] = 0;
+-	}
+-
+-	/* Fill in the MCS 8-15 SDM rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
+-		txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
+-	}
+-
+-	/* Fill in MCS32 */
+-	txpwr->mcs32 = (u8) maxpwr40;
+-
+-	for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+-		if (txpwr->ofdm_40_cdd[i] == 0)
+-			txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+-		if (i == 0) {
+-			i = i + 1;
+-			if (txpwr->ofdm_40_cdd[i] == 0)
+-				txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+-		}
+-	}
+-
+-	/* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't
+-	 * provided explicitly.
+-	 */
+-
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		if (txpwr->mcs_40_siso[i] == 0)
+-			txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
+-	}
+-
+-	for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+-		if (txpwr->ofdm_40_siso[i] == 0)
+-			txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+-		if (i == 0) {
+-			i = i + 1;
+-			if (txpwr->ofdm_40_siso[i] == 0)
+-				txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+-		}
+-	}
+-
+-	/* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't
+-	 * provided explicitly.
+-	 */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		if (txpwr->mcs_20_stbc[i] == 0)
+-			txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
+-
+-		if (txpwr->mcs_40_stbc[i] == 0)
+-			txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
+-	}
+-
+-#ifdef POWER_DBG
+-	wlc_phy_txpower_limits_dump(txpwr);
+-#endif
+-	return;
+-}
+-
+-/* Returns true if currently set country is Japan or variant */
+-static bool wlc_japan(struct wlc_info *wlc)
+-{
+-	return wlc_japan_ccode(wlc->cmi->country_abbrev);
+-}
+-
+-/* JP, J1 - J10 are Japan ccodes */
+-static bool wlc_japan_ccode(const char *ccode)
+-{
+-	return (ccode[0] == 'J' &&
+-		(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
+-}
+-
+-/*
+- * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands
+- * are valid 20MZH channels in this locale and they are also a legal HT combination
+- */
+-static bool
+-wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	u8 channel = CHSPEC_CHANNEL(chspec);
+-
+-	/* check the chanspec */
+-	if (bcm_chspec_malformed(chspec)) {
+-		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
+-			wlc->pub->unit, chspec);
+-		return false;
+-	}
+-
+-	if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
+-	    CHSPEC_WLCBANDUNIT(chspec))
+-		return false;
+-
+-	/* Check a 20Mhz channel */
+-	if (CHSPEC_IS20(chspec)) {
+-		if (dualband)
+-			return VALID_CHANNEL20_DB(wlc_cm->wlc, channel);
+-		else
+-			return VALID_CHANNEL20(wlc_cm->wlc, channel);
+-	}
+-#ifdef SUPPORT_40MHZ
+-	/* We know we are now checking a 40MHZ channel, so we should only be here
+-	 * for NPHYS
+-	 */
+-	if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) {
+-		u8 upper_sideband = 0, idx;
+-		u8 num_ch20_entries =
+-		    sizeof(chan20_info) / sizeof(struct chan20_info);
+-
+-		if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec)))
+-			return false;
+-
+-		if (dualband) {
+-			if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) ||
+-			    !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel)))
+-				return false;
+-		} else {
+-			if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) ||
+-			    !VALID_CHANNEL20(wlc, UPPER_20_SB(channel)))
+-				return false;
+-		}
+-
+-		/* find the lower sideband info in the sideband array */
+-		for (idx = 0; idx < num_ch20_entries; idx++) {
+-			if (chan20_info[idx].sb == LOWER_20_SB(channel))
+-				upper_sideband = chan20_info[idx].adj_sbs;
+-		}
+-		/* check that the lower sideband allows an upper sideband */
+-		if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
+-		    (CH_UPPER_SB | CH_EWA_VALID))
+-			return true;
+-		return false;
+-	}
+-#endif				/* 40 MHZ */
+-
+-	return false;
+-}
+-
+-bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+-{
+-	return wlc_valid_chanspec_ext(wlc_cm, chspec, true);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h
+deleted file mode 100644
+index b8dec5b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h
++++ /dev/null
+@@ -1,120 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_CHANNEL_H_
+-#define _WLC_CHANNEL_H_
+-
+-#define WLC_TXPWR_DB_FACTOR 4	/* conversion for phy txpwr cacluations that use .25 dB units */
+-
+-struct wlc_info;
+-
+-/* maxpwr mapping to 5GHz band channels:
+- * maxpwr[0] - channels [34-48]
+- * maxpwr[1] - channels [52-60]
+- * maxpwr[2] - channels [62-64]
+- * maxpwr[3] - channels [100-140]
+- * maxpwr[4] - channels [149-165]
+- */
+-#define BAND_5G_PWR_LVLS	5	/* 5 power levels for 5G */
+-
+-/* power level in group of 2.4GHz band channels:
+- * maxpwr[0] - CCK  channels [1]
+- * maxpwr[1] - CCK  channels [2-10]
+- * maxpwr[2] - CCK  channels [11-14]
+- * maxpwr[3] - OFDM channels [1]
+- * maxpwr[4] - OFDM channels [2-10]
+- * maxpwr[5] - OFDM channels [11-14]
+- */
+-
+-/* macro to get 2.4 GHz channel group index for tx power */
+-#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))	/* cck index */
+-#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))	/* ofdm index */
+-
+-/* macro to get 5 GHz channel group index for tx power */
+-#define CHANNEL_POWER_IDX_5G(c) \
+-	(((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
+-
+-#define WLC_MAXPWR_TBL_SIZE		6	/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
+-#define WLC_MAXPWR_MIMO_TBL_SIZE	14	/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
+-
+-/* locale channel and power info. */
+-typedef struct {
+-	u32 valid_channels;
+-	u8 radar_channels;	/* List of radar sensitive channels */
+-	u8 restricted_channels;	/* List of channels used only if APs are detected */
+-	s8 maxpwr[WLC_MAXPWR_TBL_SIZE];	/* Max tx pwr in qdBm for each sub-band */
+-	s8 pub_maxpwr[BAND_5G_PWR_LVLS];	/* Country IE advertised max tx pwr in dBm
+-						 * per sub-band
+-						 */
+-	u8 flags;
+-} locale_info_t;
+-
+-/* bits for locale_info flags */
+-#define WLC_PEAK_CONDUCTED	0x00	/* Peak for locals */
+-#define WLC_EIRP		0x01	/* Flag for EIRP */
+-#define WLC_DFS_TPC		0x02	/* Flag for DFS TPC */
+-#define WLC_NO_OFDM		0x04	/* Flag for No OFDM */
+-#define WLC_NO_40MHZ		0x08	/* Flag for No MIMO 40MHz */
+-#define WLC_NO_MIMO		0x10	/* Flag for No MIMO, 20 or 40 MHz */
+-#define WLC_RADAR_TYPE_EU       0x20	/* Flag for EU */
+-#define WLC_DFS_FCC             WLC_DFS_TPC	/* Flag for DFS FCC */
+-#define WLC_DFS_EU              (WLC_DFS_TPC | WLC_RADAR_TYPE_EU)	/* Flag for DFS EU */
+-
+-#define ISDFS_EU(fl)		(((fl) & WLC_DFS_EU) == WLC_DFS_EU)
+-
+-/* locale per-channel tx power limits for MIMO frames
+- * maxpwr arrays are index by channel for 2.4 GHz limits, and
+- * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
+- */
+-typedef struct {
+-	s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE];	/* tx 20 MHz power limits, qdBm units */
+-	s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE];	/* tx 40 MHz power limits, qdBm units */
+-	u8 flags;
+-} locale_mimo_info_t;
+-
+-extern const chanvec_t chanvec_all_2G;
+-extern const chanvec_t chanvec_all_5G;
+-
+-/*
+- * Country names and abbreviations with locale defined from ISO 3166
+- */
+-struct country_info {
+-	const u8 locale_2G;	/* 2.4G band locale */
+-	const u8 locale_5G;	/* 5G band locale */
+-	const u8 locale_mimo_2G;	/* 2.4G mimo info */
+-	const u8 locale_mimo_5G;	/* 5G mimo info */
+-};
+-
+-typedef struct country_info country_info_t;
+-
+-typedef struct wlc_cm_info wlc_cm_info_t;
+-
+-extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc);
+-extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm);
+-
+-extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm,
+-					   uint bandunit);
+-
+-extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+-
+-extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm,
+-				   chanspec_t chanspec,
+-				   struct txpwr_limits *txpwr);
+-extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm,
+-				     chanspec_t chanspec,
+-				     u8 local_constraint_qdbm);
+-
+-#endif				/* _WLC_CHANNEL_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h
+deleted file mode 100644
+index cab10c7..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h
++++ /dev/null
+@@ -1,140 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_key_h_
+-#define _wlc_key_h_
+-
+-struct scb;
+-struct wlc_info;
+-struct wlc_bsscfg;
+-/* Maximum # of keys that wl driver supports in S/W.
+- * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS.
+- */
+-#define WSEC_MAX_KEYS		54	/* Max # of keys (50 + 4 default keys) */
+-#define WLC_DEFAULT_KEYS	4	/* Default # of keys */
+-
+-#define WSEC_MAX_WOWL_KEYS 5	/* Max keys in WOWL mode (1 + 4 default keys) */
+-
+-#define WPA2_GTK_MAX	3
+-
+-/*
+-* Max # of keys currently supported:
+-*
+-*     s/w keys if WSEC_SW(wlc->wsec).
+-*     h/w keys otherwise.
+-*/
+-#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS
+-
+-/* number of 802.11 default (non-paired, group keys) */
+-#define WSEC_MAX_DEFAULT_KEYS	4	/* # of default keys */
+-
+-/* Max # of hardware keys supported */
+-#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS
+-
+-/* Max # of hardware TKIP MIC keys supported */
+-#define WLC_MAX_TKMIC_HW_KEYS(wlc) (WSEC_MAX_TKMIC_ENGINE_KEYS)
+-
+-#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \
+-	((((wlc)->machwcap & MCAP_TKIPMIC)) && \
+-	 (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \
+-	 !WSEC_SOFTKEY(wlc, key, bsscfg) && \
+-	WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \
+-	(WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS))
+-
+-/* index of key in key table */
+-#define WSEC_KEY_INDEX(wlc, key)	((key)->idx)
+-
+-#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \
+-	WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc))
+-
+-/* get a key, non-NULL only if key allocated and not clear */
+-#define WSEC_KEY(wlc, i)	(((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \
+-	(wlc)->wsec_keys[i] : NULL)
+-
+-#define WSEC_SCB_KEY_VALID(scb)	(((scb)->key && (scb)->key->len) ? true : false)
+-
+-/* default key */
+-#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \
+-	(struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index])
+-
+-/* Macros for key management in IBSS mode */
+-#define WSEC_IBSS_MAX_PEERS	16	/* Max # of IBSS Peers */
+-#define WSEC_IBSS_RCMTA_INDEX(idx) \
+-	(((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS)
+-
+-/* contiguous # key slots for infrastructure mode STA */
+-#define WSEC_BSS_STA_KEY_GROUP_SIZE	5
+-
+-typedef struct wsec_iv {
+-	u32 hi;		/* upper 32 bits of IV */
+-	u16 lo;		/* lower 16 bits of IV */
+-} wsec_iv_t;
+-
+-#define WLC_NUMRXIVS	16	/* # rx IVs (one per 802.11e TID) */
+-
+-typedef struct wsec_key {
+-	u8 ea[ETH_ALEN];	/* per station */
+-	u8 idx;		/* key index in wsec_keys array */
+-	u8 id;		/* key ID [0-3] */
+-	u8 algo;		/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+-	u8 rcmta;		/* rcmta entry index, same as idx by default */
+-	u16 flags;		/* misc flags */
+-	u8 algo_hw;		/* cache for hw register */
+-	u8 aes_mode;		/* cache for hw register */
+-	s8 iv_len;		/* IV length */
+-	s8 icv_len;		/* ICV length */
+-	u32 len;		/* key length..don't move this var */
+-	/* data is 4byte aligned */
+-	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
+-	wsec_iv_t rxiv[WLC_NUMRXIVS];	/* Rx IV (one per TID) */
+-	wsec_iv_t txiv;		/* Tx IV */
+-
+-} wsec_key_t;
+-
+-#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+-
+-/* For use with wsec_key_t.flags */
+-
+-#define WSEC_BS_UPDATE		(1 << 0)	/* Indicates hw needs key update on BS switch */
+-#define WSEC_PRIMARY_KEY	(1 << 1)	/* Indicates this key is the primary (ie tx) key */
+-#define WSEC_TKIP_ERROR		(1 << 2)	/* Provoke deliberate MIC error */
+-#define WSEC_REPLAY_ERROR	(1 << 3)	/* Provoke deliberate replay */
+-#define WSEC_IBSS_PEER_GROUP_KEY	(1 << 7)	/* Flag: group key for a IBSS PEER */
+-#define WSEC_ICV_ERROR		(1 << 8)	/* Provoke deliberate ICV error */
+-
+-#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (-EBADE)
+-#define wlc_key_update(a, b, c) do {} while (0)
+-#define wlc_key_remove(a, b, c) do {} while (0)
+-#define wlc_key_remove_all(a, b) do {} while (0)
+-#define wlc_key_delete(a, b, c) do {} while (0)
+-#define wlc_scb_key_delete(a, b) do {} while (0)
+-#define wlc_key_lookup(a, b, c, d, e) (NULL)
+-#define wlc_key_hw_init_all(a) do {} while (0)
+-#define wlc_key_hw_init(a, b, c)  do {} while (0)
+-#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0)
+-#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0)
+-#define wlc_key_sw_wowl_create(a, b, c) (-EBADE)
+-#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0)
+-#define wlc_key_iv_init(a, b, c) do {} while (0)
+-#define wlc_key_set_error(a, b, c) (-EBADE)
+-#define wlc_key_dump_hw(a, b) (-EBADE)
+-#define wlc_key_dump_sw(a, b) (-EBADE)
+-#define wlc_key_defkeyflag(a) (0)
+-#define wlc_rcmta_add_bssid(a, b) do {} while (0)
+-#define wlc_rcmta_del_bssid(a, b) do {} while (0)
+-#define wlc_key_scb_delete(a, b) do {} while (0)
+-
+-#endif				/* _wlc_key_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+deleted file mode 100644
+index 99250e2..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
++++ /dev/null
+@@ -1,7537 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/ctype.h>
+-#include <linux/etherdevice.h>
+-#include <linux/pci_ids.h>
+-#include <net/mac80211.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <pcicfg.h>
+-#include <bcmsrom.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#include "wlc_pmu.h"
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_bsscfg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_bmac.h"
+-#include "wlc_phy_hal.h"
+-#include "wlc_phy_shim.h"
+-#include "wlc_antsel.h"
+-#include "wlc_stf.h"
+-#include "wlc_ampdu.h"
+-#include "wl_export.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-
+-#include "wl_mac80211.h"
+-
+-/*
+- * WPA(2) definitions
+- */
+-#define RSN_CAP_4_REPLAY_CNTRS		2
+-#define RSN_CAP_16_REPLAY_CNTRS		3
+-
+-#define WPA_CAP_4_REPLAY_CNTRS		RSN_CAP_4_REPLAY_CNTRS
+-#define WPA_CAP_16_REPLAY_CNTRS		RSN_CAP_16_REPLAY_CNTRS
+-
+-/*
+- * Indication for txflowcontrol that all priority bits in
+- * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
+- */
+-#define ALLPRIO		-1
+-
+-/*
+- * buffer length needed for wlc_format_ssid
+- * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+- */
+-#define SSID_FMT_BUF_LEN	((4 * IEEE80211_MAX_SSID_LEN) + 1)
+-
+-#define	TIMER_INTERVAL_WATCHDOG	1000	/* watchdog timer, in unit of ms */
+-#define	TIMER_INTERVAL_RADIOCHK	800	/* radio monitor timer, in unit of ms */
+-
+-#ifndef WLC_MPC_MAX_DELAYCNT
+-#define	WLC_MPC_MAX_DELAYCNT	10	/* Max MPC timeout, in unit of watchdog */
+-#endif
+-#define	WLC_MPC_MIN_DELAYCNT	1	/* Min MPC timeout, in unit of watchdog */
+-#define	WLC_MPC_THRESHOLD	3	/* MPC count threshold level */
+-
+-#define	BEACON_INTERVAL_DEFAULT	100	/* beacon interval, in unit of 1024TU */
+-#define	DTIM_INTERVAL_DEFAULT	3	/* DTIM interval, in unit of beacon interval */
+-
+-/* Scale down delays to accommodate QT slow speed */
+-#define	BEACON_INTERVAL_DEF_QT	20	/* beacon interval, in unit of 1024TU */
+-#define	DTIM_INTERVAL_DEF_QT	1	/* DTIM interval, in unit of beacon interval */
+-
+-#define	TBTT_ALIGN_LEEWAY_US	100	/* min leeway before first TBTT in us */
+-
+-/*
+- * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
+- * watchdog) it is not a wall clock and won't increment when driver is in "down" state
+- * this low resolution driver tick can be used for maintenance tasks such as phy
+- * calibration and scb update
+- */
+-
+-/* watchdog trigger mode: OSL timer or TBTT */
+-#define WLC_WATCHDOG_TBTT(wlc) \
+-	(wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt)
+-
+-/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
+-#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid))
+-
+-#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \
+-				(!AP_ENAB(wlc->pub)) && (wlc->war16165))
+-
+-/* debug/trace */
+-uint wl_msg_level =
+-#if defined(BCMDBG)
+-    WL_ERROR_VAL;
+-#else
+-    0;
+-#endif				/* BCMDBG */
+-
+-/* Find basic rate for a given rate */
+-#define WLC_BASIC_RATE(wlc, rspec)	(IS_MCS(rspec) ? \
+-			(wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
+-			(wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])
+-
+-#define FRAMETYPE(r, mimoframe)	(IS_MCS(r) ? mimoframe	: (IS_CCK(r) ? FT_CCK : FT_OFDM))
+-
+-#define RFDISABLE_DEFAULT	10000000	/* rfdisable delay timer 500 ms, runs of ALP clock */
+-
+-#define WLC_TEMPSENSE_PERIOD		10	/* 10 second timeout */
+-
+-#define SCAN_IN_PROGRESS(x)	0
+-
+-#define EPI_VERSION_NUM		0x054b0b00
+-
+-#ifdef BCMDBG
+-/* pointer to most recently allocated wl/wlc */
+-static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL);
+-#endif
+-
+-/* IOVar table */
+-
+-/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars
+- * table and by the wlc_doiovar() function.  No ordering is imposed:
+- * the table is keyed by name, and the function uses a switch.
+- */
+-enum {
+-	IOV_MPC = 1,
+-	IOV_RTSTHRESH,
+-	IOV_QTXPOWER,
+-	IOV_BCN_LI_BCN,		/* Beacon listen interval in # of beacons */
+-	IOV_LAST		/* In case of a need to check max ID number */
+-};
+-
+-const bcm_iovar_t wlc_iovars[] = {
+-	{"mpc", IOV_MPC, (0), IOVT_BOOL, 0},
+-	{"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0},
+-	{"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0},
+-	{"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0},
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-const u8 prio2fifo[NUMPRIO] = {
+-	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
+-	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
+-	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
+-	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
+-	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
+-	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
+-	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
+-	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
+-};
+-
+-/* precedences numbers for wlc queues. These are twice as may levels as
+- * 802.1D priorities.
+- * Odd numbers are used for HI priority traffic at same precedence levels
+- * These constants are used ONLY by wlc_prio2prec_map.  Do not use them elsewhere.
+- */
+-#define	_WLC_PREC_NONE		0	/* None = - */
+-#define	_WLC_PREC_BK		2	/* BK - Background */
+-#define	_WLC_PREC_BE		4	/* BE - Best-effort */
+-#define	_WLC_PREC_EE		6	/* EE - Excellent-effort */
+-#define	_WLC_PREC_CL		8	/* CL - Controlled Load */
+-#define	_WLC_PREC_VI		10	/* Vi - Video */
+-#define	_WLC_PREC_VO		12	/* Vo - Voice */
+-#define	_WLC_PREC_NC		14	/* NC - Network Control */
+-
+-/* 802.1D Priority to precedence queue mapping */
+-const u8 wlc_prio2prec_map[] = {
+-	_WLC_PREC_BE,		/* 0 BE - Best-effort */
+-	_WLC_PREC_BK,		/* 1 BK - Background */
+-	_WLC_PREC_NONE,		/* 2 None = - */
+-	_WLC_PREC_EE,		/* 3 EE - Excellent-effort */
+-	_WLC_PREC_CL,		/* 4 CL - Controlled Load */
+-	_WLC_PREC_VI,		/* 5 Vi - Video */
+-	_WLC_PREC_VO,		/* 6 Vo - Voice */
+-	_WLC_PREC_NC,		/* 7 NC - Network Control */
+-};
+-
+-/* Sanity check for tx_prec_map and fifo synchup
+- * Either there are some packets pending for the fifo, else if fifo is empty then
+- * all the corresponding precmap bits should be set
+- */
+-#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) ||	\
+-	(TXPKTPENDGET((wlc), (fifo)) == 0 && \
+-	((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \
+-	(wlc)->fifo2prec_map[(fifo)]))
+-
+-/* TX FIFO number to WME/802.1E Access Category */
+-const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
+-
+-/* WME/802.1E Access Category to TX FIFO number */
+-static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
+-
+-static bool in_send_q = false;
+-
+-/* Shared memory location index for various AC params */
+-#define wme_shmemacindex(ac)	wme_ac2fifo[ac]
+-
+-#ifdef BCMDBG
+-static const char *fifo_names[] = {
+-	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
+-#else
+-static const char fifo_names[6][0];
+-#endif
+-
+-static const u8 acbitmap2maxprio[] = {
+-	PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
+-	PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
+-	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
+-	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
+-};
+-
+-/* currently the best mechanism for determining SIFS is the band in use */
+-#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME);
+-
+-/* value for # replay counters currently supported */
+-#define WLC_REPLAY_CNTRS_VALUE	WPA_CAP_16_REPLAY_CNTRS
+-
+-/* local prototypes */
+-static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc,
+-					       struct ieee80211_hw *hw,
+-					       struct sk_buff *p,
+-					       struct scb *scb, uint frag,
+-					       uint nfrags, uint queue,
+-					       uint next_frag_len,
+-					       wsec_key_t *key,
+-					       ratespec_t rspec_override);
+-static void wlc_bss_default_init(struct wlc_info *wlc);
+-static void wlc_ucode_mac_upd(struct wlc_info *wlc);
+-static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc,
+-					 struct wlcband *cur_band, u32 int_val);
+-static void wlc_tx_prec_map_init(struct wlc_info *wlc);
+-static void wlc_watchdog(void *arg);
+-static void wlc_watchdog_by_timer(void *arg);
+-static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate);
+-static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg);
+-static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val,
+-				const bcm_iovar_t *vi);
+-static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc);
+-
+-/* send and receive */
+-static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc);
+-static void wlc_txq_free(struct wlc_info *wlc,
+-			 struct wlc_txq_info *qi);
+-static void wlc_txflowcontrol_signal(struct wlc_info *wlc,
+-				     struct wlc_txq_info *qi,
+-				     bool on, int prio);
+-static void wlc_txflowcontrol_reset(struct wlc_info *wlc);
+-static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rate,
+-				 uint length, u8 *plcp);
+-static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
+-static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
+-static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate,
+-				    u8 preamble_type, uint next_frag_len);
+-static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh);
+-static void wlc_recvctl(struct wlc_info *wlc,
+-			d11rxhdr_t *rxh, struct sk_buff *p);
+-static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate,
+-			       u8 preamble_type, uint dur);
+-static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate,
+-			      u8 preamble_type);
+-static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate,
+-			      u8 preamble_type);
+-/* interrupt, up/down, band */
+-static void wlc_setband(struct wlc_info *wlc, uint bandunit);
+-static chanspec_t wlc_init_chanspec(struct wlc_info *wlc);
+-static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec);
+-static void wlc_bsinit(struct wlc_info *wlc);
+-static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
+-			      bool writeToShm);
+-static void wlc_radio_hwdisable_upd(struct wlc_info *wlc);
+-static bool wlc_radio_monitor_start(struct wlc_info *wlc);
+-static void wlc_radio_timer(void *arg);
+-static void wlc_radio_enable(struct wlc_info *wlc);
+-static void wlc_radio_upd(struct wlc_info *wlc);
+-
+-/* scan, association, BSS */
+-static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate,
+-			     u8 preamble_type);
+-static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap);
+-static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val);
+-static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val);
+-static void wlc_war16165(struct wlc_info *wlc, bool tx);
+-
+-static void wlc_wme_retries_write(struct wlc_info *wlc);
+-static bool wlc_attach_stf_ant_init(struct wlc_info *wlc);
+-static uint wlc_attach_module(struct wlc_info *wlc);
+-static void wlc_detach_module(struct wlc_info *wlc);
+-static void wlc_timers_deinit(struct wlc_info *wlc);
+-static void wlc_down_led_upd(struct wlc_info *wlc);
+-static uint wlc_down_del_timer(struct wlc_info *wlc);
+-static void wlc_ofdm_rateset_war(struct wlc_info *wlc);
+-static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-		      struct wlc_if *wlcif);
+-
+-/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
+- */
+-bool wlc_ps_allowed(struct wlc_info *wlc)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	/* disallow PS when one of the following global conditions meets */
+-	if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override)
+-		return false;
+-
+-	/* disallow PS when one of these meets when not scanning */
+-	if (!wlc->PMblocked) {
+-		if (AP_ACTIVE(wlc) || wlc->monitor)
+-			return false;
+-	}
+-
+-	FOREACH_AS_STA(wlc, idx, cfg) {
+-		/* disallow PS when one of the following bsscfg specific conditions meets */
+-		if (!cfg->BSS || !WLC_PORTOPEN(cfg))
+-			return false;
+-
+-		if (!cfg->dtim_programmed)
+-			return false;
+-	}
+-
+-	return true;
+-}
+-
+-void wlc_reset(struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	wlc->check_for_unaligned_tbtt = false;
+-
+-	/* slurp up hw mac counters before core reset */
+-	wlc_statsupd(wlc);
+-
+-	/* reset our snapshot of macstat counters */
+-	memset((char *)wlc->core->macstat_snapshot, 0,
+-		sizeof(macstat_t));
+-
+-	wlc_bmac_reset(wlc->hw);
+-	wlc->txretried = 0;
+-
+-}
+-
+-void wlc_fatal_error(struct wlc_info *wlc)
+-{
+-	wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
+-		  wlc->pub->unit);
+-	wl_init(wlc->wl);
+-}
+-
+-/* Return the channel the driver should initialize during wlc_init.
+- * the channel may have to be changed from the currently configured channel
+- * if other configurations are in conflict (bandlocked, 11n mode disabled,
+- * invalid channel for current country, etc.)
+- */
+-static chanspec_t wlc_init_chanspec(struct wlc_info *wlc)
+-{
+-	chanspec_t chanspec =
+-	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
+-	    WL_CHANSPEC_BAND_2G;
+-
+-	return chanspec;
+-}
+-
+-struct scb global_scb;
+-
+-static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb)
+-{
+-	int i;
+-	scb->flags = SCB_WMECAP | SCB_HTCAP;
+-	for (i = 0; i < NUMPRIO; i++)
+-		scb->seqnum[i] = 0;
+-}
+-
+-void wlc_init(struct wlc_info *wlc)
+-{
+-	d11regs_t *regs;
+-	chanspec_t chanspec;
+-	int i;
+-	struct wlc_bsscfg *bsscfg;
+-	bool mute = false;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	regs = wlc->regs;
+-
+-	/* This will happen if a big-hammer was executed. In that case, we want to go back
+-	 * to the channel that we were on and not new channel
+-	 */
+-	if (wlc->pub->associated)
+-		chanspec = wlc->home_chanspec;
+-	else
+-		chanspec = wlc_init_chanspec(wlc);
+-
+-	wlc_bmac_init(wlc->hw, chanspec, mute);
+-
+-	wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2;
+-	if (wlc->machwcap & MCAP_TKIPMIC)
+-		wlc->tkmickeys =
+-		    wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2;
+-
+-	/* update beacon listen interval */
+-	wlc_bcn_li_upd(wlc);
+-	wlc->bcn_wait_prd =
+-	    (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10);
+-
+-	/* the world is new again, so is our reported rate */
+-	wlc_reprate_init(wlc);
+-
+-	/* write ethernet address to core */
+-	FOREACH_BSS(wlc, i, bsscfg) {
+-		wlc_set_mac(bsscfg);
+-		wlc_set_bssid(bsscfg);
+-	}
+-
+-	/* Update tsf_cfprep if associated and up */
+-	if (wlc->pub->associated) {
+-		FOREACH_BSS(wlc, i, bsscfg) {
+-			if (bsscfg->up) {
+-				u32 bi;
+-
+-				/* get beacon period and convert to uS */
+-				bi = bsscfg->current_bss->beacon_period << 10;
+-				/*
+-				 * update since init path would reset
+-				 * to default value
+-				 */
+-				W_REG(&regs->tsf_cfprep,
+-				      (bi << CFPREP_CBI_SHIFT));
+-
+-				/* Update maccontrol PM related bits */
+-				wlc_set_ps_ctrl(wlc);
+-
+-				break;
+-			}
+-		}
+-	}
+-
+-	wlc_key_hw_init_all(wlc);
+-
+-	wlc_bandinit_ordered(wlc, chanspec);
+-
+-	wlc_init_scb(wlc, &global_scb);
+-
+-	/* init probe response timeout */
+-	wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
+-
+-	/* init max burst txop (framebursting) */
+-	wlc_write_shm(wlc, M_MBURST_TXOP,
+-		      (wlc->
+-		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
+-
+-	/* initialize maximum allowed duty cycle */
+-	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
+-	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
+-
+-	/* Update some shared memory locations related to max AMPDU size allowed to received */
+-	wlc_ampdu_shm_upd(wlc->ampdu);
+-
+-	/* band-specific inits */
+-	wlc_bsinit(wlc);
+-
+-	/* Enable EDCF mode (while the MAC is suspended) */
+-	if (EDCF_ENAB(wlc->pub)) {
+-		OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
+-		wlc_edcf_setparams(wlc, false);
+-	}
+-
+-	/* Init precedence maps for empty FIFOs */
+-	wlc_tx_prec_map_init(wlc);
+-
+-	/* read the ucode version if we have not yet done so */
+-	if (wlc->ucode_rev == 0) {
+-		wlc->ucode_rev =
+-		    wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
+-		wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR);
+-	}
+-
+-	/* ..now really unleash hell (allow the MAC out of suspend) */
+-	wlc_enable_mac(wlc);
+-
+-	/* clear tx flow control */
+-	wlc_txflowcontrol_reset(wlc);
+-
+-	/* clear tx data fifo suspends */
+-	wlc->tx_suspended = false;
+-
+-	/* enable the RF Disable Delay timer */
+-	W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
+-
+-	/* initialize mpc delay */
+-	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-
+-	/*
+-	 * Initialize WME parameters; if they haven't been set by some other
+-	 * mechanism (IOVar, etc) then read them from the hardware.
+-	 */
+-	if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) {	/* Uninitialized; read from HW */
+-		int ac;
+-
+-		for (ac = 0; ac < AC_COUNT; ac++) {
+-			wlc->wme_retries[ac] =
+-			    wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
+-		}
+-	}
+-}
+-
+-void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc)
+-{
+-	wlc->bcnmisc_monitor = promisc;
+-	wlc_mac_bcn_promisc(wlc);
+-}
+-
+-void wlc_mac_bcn_promisc(struct wlc_info *wlc)
+-{
+-	if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
+-	    wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
+-		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
+-	else
+-		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
+-}
+-
+-/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
+-void wlc_mac_promisc(struct wlc_info *wlc)
+-{
+-	u32 promisc_bits = 0;
+-
+-	/* promiscuous mode just sets MCTL_PROMISC
+-	 * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
+-	 * since all BSS data traffic is directed at the AP
+-	 */
+-	if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet)
+-		promisc_bits |= MCTL_PROMISC;
+-
+-	/* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
+-	 * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
+-	 * handled in wlc_mac_bcn_promisc()
+-	 */
+-	if (MONITOR_ENAB(wlc))
+-		promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
+-
+-	wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
+-}
+-
+-/* push sw hps and wake state through hardware */
+-void wlc_set_ps_ctrl(struct wlc_info *wlc)
+-{
+-	u32 v1, v2;
+-	bool hps;
+-	bool awake_before;
+-
+-	hps = PS_ALLOWED(wlc);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
+-
+-	v1 = R_REG(&wlc->regs->maccontrol);
+-	v2 = MCTL_WAKE;
+-	if (hps)
+-		v2 |= MCTL_HPS;
+-
+-	wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
+-
+-	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
+-
+-	if (!awake_before)
+-		wlc_bmac_wait_for_wake(wlc->hw);
+-
+-}
+-
+-/*
+- * Write this BSS config's MAC address to core.
+- * Updates RXE match engine.
+- */
+-int wlc_set_mac(struct wlc_bsscfg *cfg)
+-{
+-	int err = 0;
+-	struct wlc_info *wlc = cfg->wlc;
+-
+-	if (cfg == wlc->cfg) {
+-		/* enter the MAC addr into the RXE match registers */
+-		wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr);
+-	}
+-
+-	wlc_ampdu_macaddr_upd(wlc);
+-
+-	return err;
+-}
+-
+-/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
+- * Updates RXE match engine.
+- */
+-void wlc_set_bssid(struct wlc_bsscfg *cfg)
+-{
+-	struct wlc_info *wlc = cfg->wlc;
+-
+-	/* if primary config, we need to update BSSID in RXE match registers */
+-	if (cfg == wlc->cfg) {
+-		wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID);
+-	}
+-#ifdef SUPPORT_HWKEYS
+-	else if (BSSCFG_STA(cfg) && cfg->BSS) {
+-		wlc_rcmta_add_bssid(wlc, cfg);
+-	}
+-#endif
+-}
+-
+-/*
+- * Suspend the the MAC and update the slot timing
+- * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
+- */
+-void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	/* use the override if it is set */
+-	if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO)
+-		shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON);
+-
+-	if (wlc->shortslot == shortslot)
+-		return;
+-
+-	wlc->shortslot = shortslot;
+-
+-	/* update the capability based on current shortslot mode */
+-	FOREACH_BSS(wlc, idx, cfg) {
+-		if (!cfg->associated)
+-			continue;
+-		cfg->current_bss->capability &=
+-					~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-		if (wlc->shortslot)
+-			cfg->current_bss->capability |=
+-					WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-	}
+-
+-	wlc_bmac_set_shortslot(wlc->hw, shortslot);
+-}
+-
+-static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc)
+-{
+-	u8 local;
+-	s16 local_max;
+-
+-	local = WLC_TXPWR_MAX;
+-	if (wlc->pub->associated &&
+-	    (bcm_chspec_ctlchan(wlc->chanspec) ==
+-	     bcm_chspec_ctlchan(wlc->home_chanspec))) {
+-
+-		/* get the local power constraint if we are on the AP's
+-		 * channel [802.11h, 7.3.2.13]
+-		 */
+-		/* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */
+-		local_max =
+-		    (wlc->txpwr_local_max -
+-		     wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR;
+-		if (local_max > 0 && local_max < WLC_TXPWR_MAX)
+-			return (u8) local_max;
+-		if (local_max < 0)
+-			return 0;
+-	}
+-
+-	return local;
+-}
+-
+-/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
+-void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	if (wlc->home_chanspec != chanspec) {
+-		int idx;
+-		struct wlc_bsscfg *cfg;
+-
+-		wlc->home_chanspec = chanspec;
+-
+-		FOREACH_BSS(wlc, idx, cfg) {
+-			if (!cfg->associated)
+-				continue;
+-
+-			cfg->current_bss->chanspec = chanspec;
+-		}
+-
+-	}
+-}
+-
+-static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	/* Save our copy of the chanspec */
+-	wlc->chanspec = chanspec;
+-
+-	/* Set the chanspec and power limits for this locale after computing
+-	 * any 11h local tx power constraints.
+-	 */
+-	wlc_channel_set_chanspec(wlc->cmi, chanspec,
+-				 wlc_local_constraint_qdbm(wlc));
+-
+-	if (wlc->stf->ss_algosel_auto)
+-		wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
+-					    chanspec);
+-
+-	wlc_stf_ss_update(wlc, wlc->band);
+-
+-}
+-
+-void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	uint bandunit;
+-	bool switchband = false;
+-	chanspec_t old_chanspec = wlc->chanspec;
+-
+-	if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
+-			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
+-		return;
+-	}
+-
+-	/* Switch bands if necessary */
+-	if (NBANDS(wlc) > 1) {
+-		bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+-		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
+-			switchband = true;
+-			if (wlc->bandlocked) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
+-					  "band is locked!\n",
+-					  wlc->pub->unit, __func__,
+-					  CHSPEC_CHANNEL(chanspec));
+-				return;
+-			}
+-			/* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ?
+-			 * if the setband updates (wlc_bsinit) use low level calls to inspect and
+-			 * set state, the state inspected may be from the wrong band, or the
+-			 * following wlc_bmac_set_chanspec() may undo the work.
+-			 */
+-			wlc_setband(wlc, bandunit);
+-		}
+-	}
+-
+-	/* sync up phy/radio chanspec */
+-	wlc_set_phy_chanspec(wlc, chanspec);
+-
+-	/* init antenna selection */
+-	if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
+-		wlc_antsel_init(wlc->asi);
+-
+-		/* Fix the hardware rateset based on bw.
+-		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
+-		 */
+-		wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
+-					  wlc->band->
+-					  mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
+-					  : 0);
+-	}
+-
+-	/* update some mac configuration since chanspec changed */
+-	wlc_ucode_mac_upd(wlc);
+-}
+-
+-#if defined(BCMDBG)
+-static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len)
+-{
+-	txpwr_limits_t txpwr;
+-	tx_power_t power;
+-	tx_power_legacy_t *old_power = NULL;
+-	int r, c;
+-	uint qdbm;
+-	bool override;
+-
+-	if (len == sizeof(tx_power_legacy_t))
+-		old_power = (tx_power_legacy_t *) pwr;
+-	else if (len < sizeof(tx_power_t))
+-		return -EOVERFLOW;
+-
+-	memset(&power, 0, sizeof(tx_power_t));
+-
+-	power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC;
+-	if (wlc->pub->associated)
+-		power.local_chanspec = wlc->home_chanspec;
+-
+-	/* Return the user target tx power limits for the various rates.  Note  wlc_phy.c's
+-	 * public interface only implements getting and setting a single value for all of
+-	 * rates, so we need to fill the array ourselves.
+-	 */
+-	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
+-	for (r = 0; r < WL_TX_POWER_RATES; r++) {
+-		power.user_limit[r] = (u8) qdbm;
+-	}
+-
+-	power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR;
+-	power.local_constraint =
+-	    wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR;
+-
+-	power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain;
+-	power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain;
+-
+-	wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr);
+-
+-#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK
+-#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK"
+-#endif
+-
+-	/* CCK tx power limits */
+-	for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM;
+-	     c++, r++)
+-		power.reg_limit[r] = txpwr.cck[c];
+-
+-#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM
+-#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM"
+-#endif
+-
+-	/* 20 MHz OFDM SISO tx power limits */
+-	for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM;
+-	     c++, r++)
+-		power.reg_limit[r] = txpwr.ofdm[c];
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-
+-		/* 20 MHz OFDM CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_cdd[c];
+-
+-		/* 40 MHz OFDM SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_40_siso[c];
+-
+-		/* 40 MHz OFDM CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_40_cdd[c];
+-
+-#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM
+-#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM"
+-#endif
+-
+-		/* 20MHz MCS0-7 SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_siso[c];
+-
+-		/* 20MHz MCS0-7 CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_cdd[c];
+-
+-		/* 20MHz MCS0-7 STBC tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_stbc[c];
+-
+-		/* 40MHz MCS0-7 SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_siso[c];
+-
+-		/* 40MHz MCS0-7 CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_cdd[c];
+-
+-		/* 40MHz MCS0-7 STBC tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_stbc[c];
+-
+-#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM
+-#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM"
+-#endif
+-
+-		/* 20MHz MCS8-15 SDM tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST;
+-		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_mimo[c];
+-
+-		/* 40MHz MCS8-15 SDM tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST;
+-		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_mimo[c];
+-
+-		/* MCS 32 */
+-		power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32;
+-	}
+-
+-	wlc_phy_txpower_get_current(wlc->band->pi, &power,
+-				    CHSPEC_CHANNEL(power.chanspec));
+-
+-	/* copy the tx_power_t struct to the return buffer,
+-	 * or convert to a tx_power_legacy_t struct
+-	 */
+-	if (!old_power) {
+-		memcpy(pwr, &power, sizeof(tx_power_t));
+-	} else {
+-		int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1;
+-
+-		memset(old_power, 0, sizeof(tx_power_legacy_t));
+-
+-		old_power->txpwr_local_max = power.local_max;
+-		old_power->txpwr_local_constraint = power.local_constraint;
+-		if (CHSPEC_IS2G(power.chanspec)) {
+-			old_power->txpwr_chan_reg_max = txpwr.cck[0];
+-			old_power->txpwr_est_Pout[band_idx] =
+-			    power.est_Pout_cck;
+-			old_power->txpwr_est_Pout_gofdm = power.est_Pout[0];
+-		} else {
+-			old_power->txpwr_chan_reg_max = txpwr.ofdm[0];
+-			old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0];
+-		}
+-		old_power->txpwr_antgain[0] = power.antgain[0];
+-		old_power->txpwr_antgain[1] = power.antgain[1];
+-
+-		for (r = 0; r < NUM_PWRCTRL_RATES; r++) {
+-			old_power->txpwr_band_max[r] = power.user_limit[r];
+-			old_power->txpwr_limit[r] = power.reg_limit[r];
+-			old_power->txpwr_target[band_idx][r] = power.target[r];
+-			if (CHSPEC_IS2G(power.chanspec))
+-				old_power->txpwr_bphy_cck_max[r] =
+-				    power.board_limit[r];
+-			else
+-				old_power->txpwr_aphy_max[r] =
+-				    power.board_limit[r];
+-		}
+-	}
+-
+-	return 0;
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc)
+-{
+-	u32 bi;
+-	bi = 2 * wlc->cfg->current_bss->dtim_period *
+-	    wlc->cfg->current_bss->beacon_period;
+-	if (wlc->bcn_li_dtim)
+-		bi *= wlc->bcn_li_dtim;
+-	else if (wlc->bcn_li_bcn)
+-		/* recalculate bi based on bcn_li_bcn */
+-		bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period;
+-
+-	if (bi < 2 * TIMER_INTERVAL_WATCHDOG)
+-		bi = 2 * TIMER_INTERVAL_WATCHDOG;
+-	return bi;
+-}
+-
+-/* Change to run the watchdog either from a periodic timer or from tbtt handler.
+- * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise.
+- */
+-void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt)
+-{
+-	/* make sure changing watchdog driver is allowed */
+-	if (!wlc->pub->up || !wlc->pub->align_wd_tbtt)
+-		return;
+-	if (!tbtt && wlc->WDarmed) {
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wlc->WDarmed = false;
+-	}
+-
+-	/* stop watchdog timer and use tbtt interrupt to drive watchdog */
+-	if (tbtt && wlc->WDarmed) {
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wlc->WDarmed = false;
+-		wlc->WDlast = OSL_SYSUPTIME();
+-	}
+-	/* arm watchdog timer and drive the watchdog there */
+-	else if (!tbtt && !wlc->WDarmed) {
+-		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+-			     true);
+-		wlc->WDarmed = true;
+-	}
+-	if (tbtt && !wlc->WDarmed) {
+-		wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc),
+-			     true);
+-		wlc->WDarmed = true;
+-	}
+-}
+-
+-ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs)
+-{
+-	ratespec_t lowest_basic_rspec;
+-	uint i;
+-
+-	/* Use the lowest basic rate */
+-	lowest_basic_rspec = rs->rates[0] & WLC_RATE_MASK;
+-	for (i = 0; i < rs->count; i++) {
+-		if (rs->rates[i] & WLC_RATE_FLAG) {
+-			lowest_basic_rspec = rs->rates[i] & WLC_RATE_MASK;
+-			break;
+-		}
+-	}
+-#if NCONF
+-	/* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
+-	if (IS_OFDM(lowest_basic_rspec)) {
+-		lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+-	}
+-#endif
+-
+-	return lowest_basic_rspec;
+-}
+-
+-/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
+- * setting as per this table:
+- *  ratespec     CCK		ant = wlc->stf->txant
+- *  		OFDM		ant = 3
+- */
+-void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec)
+-{
+-	u16 phyctl;
+-	u16 phytxant = wlc->stf->phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* for non-siso rates or default setting, use the available chains */
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec);
+-	}
+-
+-	phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl);
+-}
+-
+-/* centralized protection config change function to simplify debugging, no consistency checking
+- * this should be called only on changes to avoid overhead in periodic function
+-*/
+-void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val)
+-{
+-	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
+-
+-	switch (idx) {
+-	case WLC_PROT_G_SPEC:
+-		wlc->protection->_g = (bool) val;
+-		break;
+-	case WLC_PROT_G_OVR:
+-		wlc->protection->g_override = (s8) val;
+-		break;
+-	case WLC_PROT_G_USER:
+-		wlc->protection->gmode_user = (u8) val;
+-		break;
+-	case WLC_PROT_OVERLAP:
+-		wlc->protection->overlap = (s8) val;
+-		break;
+-	case WLC_PROT_N_USER:
+-		wlc->protection->nmode_user = (s8) val;
+-		break;
+-	case WLC_PROT_N_CFG:
+-		wlc->protection->n_cfg = (s8) val;
+-		break;
+-	case WLC_PROT_N_CFG_OVR:
+-		wlc->protection->n_cfg_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_NONGF:
+-		wlc->protection->nongf = (bool) val;
+-		break;
+-	case WLC_PROT_N_NONGF_OVR:
+-		wlc->protection->nongf_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_PAM_OVR:
+-		wlc->protection->n_pam_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_OBSS:
+-		wlc->protection->n_obss = (bool) val;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-}
+-
+-static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val)
+-{
+-	wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 |
+-					IEEE80211_HT_CAP_SGI_40);
+-	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ?
+-					IEEE80211_HT_CAP_SGI_20 : 0;
+-	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ?
+-					IEEE80211_HT_CAP_SGI_40 : 0;
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-	}
+-}
+-
+-static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val)
+-{
+-	wlc->stf->ldpc = val;
+-
+-	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING;
+-	if (wlc->stf->ldpc != OFF)
+-		wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
+-	}
+-}
+-
+-/*
+- * ucode, hwmac update
+- *    Channel dependent updates for ucode and hw
+- */
+-static void wlc_ucode_mac_upd(struct wlc_info *wlc)
+-{
+-	/* enable or disable any active IBSSs depending on whether or not
+-	 * we are on the home channel
+-	 */
+-	if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) {
+-		if (wlc->pub->associated) {
+-			/* BMAC_NOTE: This is something that should be fixed in ucode inits.
+-			 * I think that the ucode inits set up the bcn templates and shm values
+-			 * with a bogus beacon. This should not be done in the inits. If ucode needs
+-			 * to set up a beacon for testing, the test routines should write it down,
+-			 * not expect the inits to populate a bogus beacon.
+-			 */
+-			if (WLC_PHY_11N_CAP(wlc->band)) {
+-				wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET,
+-					      wlc->band->bcntsfoff);
+-			}
+-		}
+-	} else {
+-		/* disable an active IBSS if we are not on the home channel */
+-	}
+-
+-	/* update the various promisc bits */
+-	wlc_mac_bcn_promisc(wlc);
+-	wlc_mac_promisc(wlc);
+-}
+-
+-static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	wlc_rateset_t default_rateset;
+-	uint parkband;
+-	uint i, band_order[2];
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-	/*
+-	 * We might have been bandlocked during down and the chip power-cycled (hibernate).
+-	 * figure out the right band to park on
+-	 */
+-	if (wlc->bandlocked || NBANDS(wlc) == 1) {
+-		parkband = wlc->band->bandunit;	/* updated in wlc_bandlock() */
+-		band_order[0] = band_order[1] = parkband;
+-	} else {
+-		/* park on the band of the specified chanspec */
+-		parkband = CHSPEC_WLCBANDUNIT(chanspec);
+-
+-		/* order so that parkband initialize last */
+-		band_order[0] = parkband ^ 1;
+-		band_order[1] = parkband;
+-	}
+-
+-	/* make each band operational, software state init */
+-	for (i = 0; i < NBANDS(wlc); i++) {
+-		uint j = band_order[i];
+-
+-		wlc->band = wlc->bandstate[j];
+-
+-		wlc_default_rateset(wlc, &default_rateset);
+-
+-		/* fill in hw_rate */
+-		wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
+-				   false, WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-				   (bool) N_ENAB(wlc->pub));
+-
+-		/* init basic rate lookup */
+-		wlc_rate_lookup_init(wlc, &default_rateset);
+-	}
+-
+-	/* sync up phy/radio chanspec */
+-	wlc_set_phy_chanspec(wlc, chanspec);
+-}
+-
+-/* band-specific init */
+-static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
+-		 wlc->pub->unit, wlc->band->bandunit);
+-
+-	/* write ucode ACK/CTS rate table */
+-	wlc_set_ratetable(wlc);
+-
+-	/* update some band specific mac configuration */
+-	wlc_ucode_mac_upd(wlc);
+-
+-	/* init antenna selection */
+-	wlc_antsel_init(wlc->asi);
+-
+-}
+-
+-/* switch to and initialize new band */
+-static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	wlc->band = wlc->bandstate[bandunit];
+-
+-	if (!wlc->pub->up)
+-		return;
+-
+-	/* wait for at least one beacon before entering sleeping state */
+-	wlc->PMawakebcn = true;
+-	FOREACH_AS_STA(wlc, idx, cfg)
+-	    cfg->PMawakebcn = true;
+-	wlc_set_ps_ctrl(wlc);
+-
+-	/* band-specific initializations */
+-	wlc_bsinit(wlc);
+-}
+-
+-/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
+-void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe)
+-{
+-	static const wme_param_ie_t stadef = {
+-		WME_OUI,
+-		WME_TYPE,
+-		WME_SUBTYPE_PARAM_IE,
+-		WME_VER,
+-		0,
+-		0,
+-		{
+-		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_BE_TXOP_STA)},
+-		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_BK_TXOP_STA)},
+-		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_VI_TXOP_STA)},
+-		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
+-		 }
+-	};
+-	memcpy(pe, &stadef, sizeof(*pe));
+-}
+-
+-void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+-		       const struct ieee80211_tx_queue_params *params,
+-		       bool suspend)
+-{
+-	int i;
+-	shm_acparams_t acp_shm;
+-	u16 *shm_entry;
+-
+-	/* Only apply params if the core is out of reset and has clocks */
+-	if (!wlc->clk) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
+-			  __func__);
+-		return;
+-	}
+-
+-	wlc->wme_admctl = 0;
+-
+-	do {
+-		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
+-		/* fill in shm ac params struct */
+-		acp_shm.txop = le16_to_cpu(params->txop);
+-		/* convert from units of 32us to us for ucode */
+-		wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
+-		    EDCF_TXOP2USEC(acp_shm.txop);
+-		acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
+-
+-		if (aci == AC_VI && acp_shm.txop == 0
+-		    && acp_shm.aifs < EDCF_AIFSN_MAX)
+-			acp_shm.aifs++;
+-
+-		if (acp_shm.aifs < EDCF_AIFSN_MIN
+-		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_edcf_setparams: bad "
+-				  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
+-			continue;
+-		}
+-
+-		acp_shm.cwmin = params->cw_min;
+-		acp_shm.cwmax = params->cw_max;
+-		acp_shm.cwcur = acp_shm.cwmin;
+-		acp_shm.bslots =
+-		    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
+-		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
+-		/* Indicate the new params to the ucode */
+-		acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
+-						    wme_shmemacindex(aci) *
+-						    M_EDCF_QLEN +
+-						    M_EDCF_STATUS_OFF));
+-		acp_shm.status |= WME_STATUS_NEWAC;
+-
+-		/* Fill in shm acparam table */
+-		shm_entry = (u16 *) &acp_shm;
+-		for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2)
+-			wlc_write_shm(wlc,
+-				      M_EDCF_QINFO +
+-				      wme_shmemacindex(aci) * M_EDCF_QLEN + i,
+-				      *shm_entry++);
+-
+-	} while (0);
+-
+-	if (suspend)
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-	if (suspend)
+-		wlc_enable_mac(wlc);
+-
+-}
+-
+-void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend)
+-{
+-	u16 aci;
+-	int i_ac;
+-	edcf_acparam_t *edcf_acp;
+-
+-	struct ieee80211_tx_queue_params txq_pars;
+-	struct ieee80211_tx_queue_params *params = &txq_pars;
+-
+-	/*
+-	 * AP uses AC params from wme_param_ie_ap.
+-	 * AP advertises AC params from wme_param_ie.
+-	 * STA uses AC params from wme_param_ie.
+-	 */
+-
+-	edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0];
+-
+-	for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
+-		/* find out which ac this set of params applies to */
+-		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
+-		/* set the admission control policy for this AC */
+-		if (edcf_acp->ACI & EDCF_ACM_MASK) {
+-			wlc->wme_admctl |= 1 << aci;
+-		}
+-
+-		/* fill in shm ac params struct */
+-		params->txop = edcf_acp->TXOP;
+-		params->aifs = edcf_acp->ACI;
+-
+-		/* CWmin = 2^(ECWmin) - 1 */
+-		params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
+-		/* CWmax = 2^(ECWmax) - 1 */
+-		params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
+-					    >> EDCF_ECWMAX_SHIFT);
+-		wlc_wme_setparams(wlc, aci, params, suspend);
+-	}
+-
+-	if (suspend)
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-	if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, false);
+-	}
+-
+-	if (suspend)
+-		wlc_enable_mac(wlc);
+-
+-}
+-
+-bool wlc_timers_init(struct wlc_info *wlc, int unit)
+-{
+-	wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer,
+-		wlc, "watchdog");
+-	if (!wlc->wdtimer) {
+-		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
+-			  "failed\n", unit);
+-		goto fail;
+-	}
+-
+-	wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer,
+-		wlc, "radio");
+-	if (!wlc->radio_timer) {
+-		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
+-			  "failed\n", unit);
+-		goto fail;
+-	}
+-
+-	return true;
+-
+- fail:
+-	return false;
+-}
+-
+-/*
+- * Initialize wlc_info default values ...
+- * may get overrides later in this function
+- */
+-void wlc_info_init(struct wlc_info *wlc, int unit)
+-{
+-	int i;
+-	/* Assume the device is there until proven otherwise */
+-	wlc->device_present = true;
+-
+-	/* set default power output percentage to 100 percent */
+-	wlc->txpwr_percent = 100;
+-
+-	/* Save our copy of the chanspec */
+-	wlc->chanspec = CH20MHZ_CHSPEC(1);
+-
+-	/* initialize CCK preamble mode to unassociated state */
+-	wlc->shortpreamble = false;
+-
+-	wlc->legacy_probe = true;
+-
+-	/* various 802.11g modes */
+-	wlc->shortslot = false;
+-	wlc->shortslot_override = WLC_SHORTSLOT_AUTO;
+-
+-	wlc->barker_overlap_control = true;
+-	wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED;
+-	wlc->txburst_limit_override = AUTO;
+-
+-	wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false);
+-
+-	wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF);
+-	wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false);
+-	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO);
+-
+-	wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP);
+-
+-	/* 802.11g draft 4.0 NonERP elt advertisement */
+-	wlc->include_legacy_erp = true;
+-
+-	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
+-	wlc->stf->txant = ANT_TX_DEF;
+-
+-	wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT;
+-
+-	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
+-	for (i = 0; i < NFIFO; i++)
+-		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
+-	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
+-
+-	/* default rate fallback retry limits */
+-	wlc->SFBL = RETRY_SHORT_FB;
+-	wlc->LFBL = RETRY_LONG_FB;
+-
+-	/* default mac retry limits */
+-	wlc->SRL = RETRY_SHORT_DEF;
+-	wlc->LRL = RETRY_LONG_DEF;
+-
+-	/* init PM state */
+-	wlc->PM = PM_OFF;	/* User's setting of PM mode through IOCTL */
+-	wlc->PM_override = false;	/* Prevents from going to PM if our AP is 'ill' */
+-	wlc->PMenabled = false;	/* Current PM state */
+-	wlc->PMpending = false;	/* Tracks whether STA indicated PM in the last attempt */
+-	wlc->PMblocked = false;	/* To allow blocking going into PM during RM and scans */
+-
+-	/* In WMM Auto mode, PM is allowed if association is a UAPSD association */
+-	wlc->WME_PM_blocked = false;
+-
+-	/* Init wme queuing method */
+-	wlc->wme_prec_queuing = false;
+-
+-	/* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */
+-	wlc->wake = false;
+-	/* Are we waiting for a response to PS-Poll that we sent */
+-	wlc->PSpoll = false;
+-
+-	/* APSD defaults */
+-	wlc->wme_apsd = true;
+-	wlc->apsd_sta_usp = false;
+-	wlc->apsd_trigger_timeout = 0;	/* disable the trigger timer */
+-	wlc->apsd_trigger_ac = AC_BITMAP_ALL;
+-
+-	/* Set flag to indicate that hw keys should be used when available. */
+-	wlc->wsec_swkeys = false;
+-
+-	/* init the 4 static WEP default keys */
+-	for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+-		wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
+-		wlc->wsec_keys[i]->idx = (u8) i;
+-	}
+-
+-	wlc->_regulatory_domain = false;	/* 802.11d */
+-
+-	/* WME QoS mode is Auto by default */
+-	wlc->pub->_wme = AUTO;
+-
+-#ifdef BCMSDIODEV_ENABLED
+-	wlc->pub->_priofc = true;	/* enable priority flow control for sdio dongle */
+-#endif
+-
+-	wlc->pub->_ampdu = AMPDU_AGG_HOST;
+-	wlc->pub->bcmerror = 0;
+-	wlc->ibss_allowed = true;
+-	wlc->ibss_coalesce_allowed = true;
+-	wlc->pub->_coex = ON;
+-
+-	/* initialize mpc delay */
+-	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-
+-	wlc->pr80838_war = true;
+-}
+-
+-static bool wlc_state_bmac_sync(struct wlc_info *wlc)
+-{
+-	wlc_bmac_state_t state_bmac;
+-
+-	if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0)
+-		return false;
+-
+-	wlc->machwcap = state_bmac.machwcap;
+-	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR,
+-			   (s8) state_bmac.preamble_ovr);
+-
+-	return true;
+-}
+-
+-static uint wlc_attach_module(struct wlc_info *wlc)
+-{
+-	uint err = 0;
+-	uint unit;
+-	unit = wlc->pub->unit;
+-
+-	wlc->asi = wlc_antsel_attach(wlc);
+-	if (wlc->asi == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_antsel_attach "
+-			  "failed\n", unit);
+-		err = 44;
+-		goto fail;
+-	}
+-
+-	wlc->ampdu = wlc_ampdu_attach(wlc);
+-	if (wlc->ampdu == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_ampdu_attach "
+-			  "failed\n", unit);
+-		err = 50;
+-		goto fail;
+-	}
+-
+-	if ((wlc_stf_attach(wlc) != 0)) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_stf_attach "
+-			  "failed\n", unit);
+-		err = 68;
+-		goto fail;
+-	}
+- fail:
+-	return err;
+-}
+-
+-struct wlc_pub *wlc_pub(void *wlc)
+-{
+-	return ((struct wlc_info *) wlc)->pub;
+-}
+-
+-#define CHIP_SUPPORTS_11N(wlc) 	1
+-
+-/*
+- * The common driver entry routine. Error codes should be unique
+- */
+-void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
+-		 bool piomode, void *regsva, uint bustype, void *btparam,
+-		 uint *perr)
+-{
+-	struct wlc_info *wlc;
+-	uint err = 0;
+-	uint j;
+-	struct wlc_pub *pub;
+-	uint n_disabled;
+-
+-	/* allocate struct wlc_info state and its substructures */
+-	wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device);
+-	if (wlc == NULL)
+-		goto fail;
+-	wlc->wiphy = wl->wiphy;
+-	pub = wlc->pub;
+-
+-#if defined(BCMDBG)
+-	wlc_info_dbg = wlc;
+-#endif
+-
+-	wlc->band = wlc->bandstate[0];
+-	wlc->core = wlc->corestate;
+-	wlc->wl = wl;
+-	pub->unit = unit;
+-	wlc->btparam = btparam;
+-	pub->_piomode = piomode;
+-	wlc->bandinit_pending = false;
+-	/* By default restrict TKIP associations from 11n STA's */
+-	wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT;
+-
+-	/* populate struct wlc_info with default values  */
+-	wlc_info_init(wlc, unit);
+-
+-	/* update sta/ap related parameters */
+-	wlc_ap_upd(wlc);
+-
+-	/* 11n_disable nvram */
+-	n_disabled = getintvar(pub->vars, "11n_disable");
+-
+-	/* register a module (to handle iovars) */
+-	wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc,
+-			    wlc_doiovar, NULL, NULL);
+-
+-	/*
+-	 * low level attach steps(all hw accesses go
+-	 * inside, no more in rest of the attach)
+-	 */
+-	err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, regsva,
+-			      bustype, btparam);
+-	if (err)
+-		goto fail;
+-
+-	/* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
+-	 * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
+-	 */
+-	if (!wlc_state_bmac_sync(wlc)) {
+-		err = 20;
+-		goto fail;
+-	}
+-
+-	pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band);
+-
+-	/* propagate *vars* from BMAC driver to high driver */
+-	wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
+-
+-
+-	/* set maximum allowed duty cycle */
+-	wlc->tx_duty_cycle_ofdm =
+-	    (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
+-	wlc->tx_duty_cycle_cck =
+-	    (u16) getintvar(pub->vars, "tx_duty_cycle_cck");
+-
+-	wlc_stf_phy_chain_calc(wlc);
+-
+-	/* txchain 1: txant 0, txchain 2: txant 1 */
+-	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+-		wlc->stf->txant = wlc->stf->hw_txchain - 1;
+-
+-	/* push to BMAC driver */
+-	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
+-			       wlc->stf->hw_rxchain);
+-
+-	/* pull up some info resulting from the low attach */
+-	{
+-		int i;
+-		for (i = 0; i < NFIFO; i++)
+-			wlc->core->txavail[i] = wlc->hw->txavail[i];
+-	}
+-
+-	wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);
+-
+-	memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);
+-
+-	for (j = 0; j < NBANDS(wlc); j++) {
+-		/* Use band 1 for single band 11a */
+-		if (IS_SINGLEBAND_5G(wlc->deviceid))
+-			j = BAND_5G_INDEX;
+-
+-		wlc->band = wlc->bandstate[j];
+-
+-		if (!wlc_attach_stf_ant_init(wlc)) {
+-			err = 24;
+-			goto fail;
+-		}
+-
+-		/* default contention windows size limits */
+-		wlc->band->CWmin = APHY_CWMIN;
+-		wlc->band->CWmax = PHY_CWMAX;
+-
+-		/* init gmode value */
+-		if (BAND_2G(wlc->band->bandtype)) {
+-			wlc->band->gmode = GMODE_AUTO;
+-			wlc_protection_upd(wlc, WLC_PROT_G_USER,
+-					   wlc->band->gmode);
+-		}
+-
+-		/* init _n_enab supported mode */
+-		if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
+-			if (n_disabled & WLFEATURE_DISABLE_11N) {
+-				pub->_n_enab = OFF;
+-				wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF);
+-			} else {
+-				pub->_n_enab = SUPPORT_11N;
+-				wlc_protection_upd(wlc, WLC_PROT_N_USER,
+-						   ((pub->_n_enab ==
+-						     SUPPORT_11N) ? WL_11N_2x2 :
+-						    WL_11N_3x3));
+-			}
+-		}
+-
+-		/* init per-band default rateset, depend on band->gmode */
+-		wlc_default_rateset(wlc, &wlc->band->defrateset);
+-
+-		/* fill in hw_rateset (used early by WLC_SET_RATESET) */
+-		wlc_rateset_filter(&wlc->band->defrateset,
+-				   &wlc->band->hw_rateset, false,
+-				   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-				   (bool) N_ENAB(wlc->pub));
+-	}
+-
+-	/* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
+-	wlc_stf_phy_txant_upd(wlc);
+-
+-	/* attach each modules */
+-	err = wlc_attach_module(wlc);
+-	if (err != 0)
+-		goto fail;
+-
+-	if (!wlc_timers_init(wlc, unit)) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: wlc_init_timer failed\n", unit,
+-			  __func__);
+-		err = 32;
+-		goto fail;
+-	}
+-
+-	/* depend on rateset, gmode */
+-	wlc->cmi = wlc_channel_mgr_attach(wlc);
+-	if (!wlc->cmi) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: wlc_channel_mgr_attach failed"
+-			  "\n", unit, __func__);
+-		err = 33;
+-		goto fail;
+-	}
+-
+-	/* init default when all parameters are ready, i.e. ->rateset */
+-	wlc_bss_default_init(wlc);
+-
+-	/*
+-	 * Complete the wlc default state initializations..
+-	 */
+-
+-	/* allocate our initial queue */
+-	wlc->pkt_queue = wlc_txq_alloc(wlc);
+-	if (wlc->pkt_queue == NULL) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
+-			  unit, __func__);
+-		err = 100;
+-		goto fail;
+-	}
+-
+-	wlc->bsscfg[0] = wlc->cfg;
+-	wlc->cfg->_idx = 0;
+-	wlc->cfg->wlc = wlc;
+-	pub->txmaxpkts = MAXTXPKTS;
+-
+-	wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie);
+-
+-	wlc->mimoft = FT_HT;
+-	wlc->ht_cap.cap_info = HT_CAP;
+-	if (HT_ENAB(wlc->pub))
+-		wlc->stf->ldpc = AUTO;
+-
+-	wlc->mimo_40txbw = AUTO;
+-	wlc->ofdm_40txbw = AUTO;
+-	wlc->cck_40txbw = AUTO;
+-	wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G);
+-
+-	/* Enable setting the RIFS Mode bit by default in HT Info IE */
+-	wlc->rifs_advert = AUTO;
+-
+-	/* Set default values of SGI */
+-	if (WLC_SGI_CAP_PHY(wlc)) {
+-		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+-		wlc->sgi_tx = AUTO;
+-	} else if (WLCISSSLPNPHY(wlc->band)) {
+-		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+-		wlc->sgi_tx = AUTO;
+-	} else {
+-		wlc_ht_update_sgi_rx(wlc, 0);
+-		wlc->sgi_tx = OFF;
+-	}
+-
+-	/* *******nvram 11n config overrides Start ********* */
+-
+-	/* apply the sgi override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
+-		wlc->sgi_tx = OFF;
+-
+-	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
+-		wlc_ht_update_sgi_rx(wlc, 0);
+-
+-	/* apply the stbc override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
+-		wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+-		wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
+-	}
+-	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
+-		wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
+-
+-	/* apply the GF override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_GF)
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;
+-
+-	/* initialize radio_mpc_disable according to wlc->mpc */
+-	wlc_radio_mpc_upd(wlc);
+-
+-	if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) {
+-		if ((getintvar(wlc->pub->vars, "aa2g") == 7) ||
+-		    (getintvar(wlc->pub->vars, "aa5g") == 7)) {
+-			wlc_bmac_antsel_set(wlc->hw, 1);
+-		}
+-	} else {
+-		wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail);
+-	}
+-
+-	if (perr)
+-		*perr = 0;
+-
+-	return (void *)wlc;
+-
+- fail:
+-	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
+-		  unit, __func__, err);
+-	if (wlc)
+-		wlc_detach(wlc);
+-
+-	if (perr)
+-		*perr = err;
+-	return NULL;
+-}
+-
+-static void wlc_attach_antgain_init(struct wlc_info *wlc)
+-{
+-	uint unit;
+-	unit = wlc->pub->unit;
+-
+-	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
+-		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
+-		wlc->band->antgain = 8;
+-	} else if (wlc->band->antgain == -1) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+-			  " srom, using 2dB\n", unit, __func__);
+-		wlc->band->antgain = 8;
+-	} else {
+-		s8 gain, fract;
+-		/* Older sroms specified gain in whole dbm only.  In order
+-		 * be able to specify qdbm granularity and remain backward compatible
+-		 * the whole dbms are now encoded in only low 6 bits and remaining qdbms
+-		 * are encoded in the hi 2 bits. 6 bit signed number ranges from
+-		 * -32 - 31. Examples: 0x1 = 1 db,
+-		 * 0xc1 = 1.75 db (1 + 3 quarters),
+-		 * 0x3f = -1 (-1 + 0 quarters),
+-		 * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
+-		 * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
+-		 */
+-		gain = wlc->band->antgain & 0x3f;
+-		gain <<= 2;	/* Sign extend */
+-		gain >>= 2;
+-		fract = (wlc->band->antgain & 0xc0) >> 6;
+-		wlc->band->antgain = 4 * gain + fract;
+-	}
+-}
+-
+-static bool wlc_attach_stf_ant_init(struct wlc_info *wlc)
+-{
+-	int aa;
+-	uint unit;
+-	char *vars;
+-	int bandtype;
+-
+-	unit = wlc->pub->unit;
+-	vars = wlc->pub->vars;
+-	bandtype = wlc->band->bandtype;
+-
+-	/* get antennas available */
+-	aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
+-	if (aa == 0)
+-		aa = (s8) getintvar(vars,
+-				      (BAND_5G(bandtype) ? "aa1" : "aa0"));
+-	if ((aa < 1) || (aa > 15)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+-			  " srom (0x%x), using 3\n", unit, __func__, aa);
+-		aa = 3;
+-	}
+-
+-	/* reset the defaults if we have a single antenna */
+-	if (aa == 1) {
+-		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
+-		wlc->stf->txant = ANT_TX_FORCE_0;
+-	} else if (aa == 2) {
+-		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
+-		wlc->stf->txant = ANT_TX_FORCE_1;
+-	} else {
+-	}
+-
+-	/* Compute Antenna Gain */
+-	wlc->band->antgain =
+-	    (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
+-	wlc_attach_antgain_init(wlc);
+-
+-	return true;
+-}
+-
+-
+-static void wlc_timers_deinit(struct wlc_info *wlc)
+-{
+-	/* free timer state */
+-	if (wlc->wdtimer) {
+-		wl_free_timer(wlc->wl, wlc->wdtimer);
+-		wlc->wdtimer = NULL;
+-	}
+-	if (wlc->radio_timer) {
+-		wl_free_timer(wlc->wl, wlc->radio_timer);
+-		wlc->radio_timer = NULL;
+-	}
+-}
+-
+-static void wlc_detach_module(struct wlc_info *wlc)
+-{
+-	if (wlc->asi) {
+-		wlc_antsel_detach(wlc->asi);
+-		wlc->asi = NULL;
+-	}
+-
+-	if (wlc->ampdu) {
+-		wlc_ampdu_detach(wlc->ampdu);
+-		wlc->ampdu = NULL;
+-	}
+-
+-	wlc_stf_detach(wlc);
+-}
+-
+-/*
+- * Return a count of the number of driver callbacks still pending.
+- *
+- * General policy is that wlc_detach can only dealloc/free software states. It can NOT
+- *  touch hardware registers since the d11core may be in reset and clock may not be available.
+- *    One exception is sb register access, which is possible if crystal is turned on
+- * After "down" state, driver should avoid software timer with the exception of radio_monitor.
+- */
+-uint wlc_detach(struct wlc_info *wlc)
+-{
+-	uint callbacks = 0;
+-
+-	if (wlc == NULL)
+-		return 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	callbacks += wlc_bmac_detach(wlc);
+-
+-	/* delete software timers */
+-	if (!wlc_radio_monitor_stop(wlc))
+-		callbacks++;
+-
+-	wlc_channel_mgr_detach(wlc->cmi);
+-
+-	wlc_timers_deinit(wlc);
+-
+-	wlc_detach_module(wlc);
+-
+-	/* free other state */
+-
+-
+-#ifdef BCMDBG
+-	kfree(wlc->country_ie_override);
+-	wlc->country_ie_override = NULL;
+-#endif				/* BCMDBG */
+-
+-	{
+-		/* free dumpcb list */
+-		struct dumpcb_s *prev, *ptr;
+-		prev = ptr = wlc->dumpcb_head;
+-		while (ptr) {
+-			ptr = prev->next;
+-			kfree(prev);
+-			prev = ptr;
+-		}
+-		wlc->dumpcb_head = NULL;
+-	}
+-
+-	/* Detach from iovar manager */
+-	wlc_module_unregister(wlc->pub, "wlc_iovars", wlc);
+-
+-	while (wlc->tx_queues != NULL)
+-		wlc_txq_free(wlc, wlc->tx_queues);
+-
+-	wlc_detach_mfree(wlc);
+-	return callbacks;
+-}
+-
+-/* update state that depends on the current value of "ap" */
+-void wlc_ap_upd(struct wlc_info *wlc)
+-{
+-	if (AP_ENAB(wlc->pub))
+-		wlc->PLCPHdr_override = WLC_PLCP_AUTO;	/* AP: short not allowed, but not enforced */
+-	else
+-		wlc->PLCPHdr_override = WLC_PLCP_SHORT;	/* STA-BSS; short capable */
+-
+-	/* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */
+-	wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO;
+-
+-	/* fixup mpc */
+-	wlc->mpc = true;
+-}
+-
+-/* read hwdisable state and propagate to wlc flag */
+-static void wlc_radio_hwdisable_upd(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
+-		return;
+-
+-	if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) {
+-		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+-	} else {
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+-	}
+-}
+-
+-/* return true if Minimum Power Consumption should be entered, false otherwise */
+-bool wlc_is_non_delay_mpc(struct wlc_info *wlc)
+-{
+-	return false;
+-}
+-
+-bool wlc_ismpc(struct wlc_info *wlc)
+-{
+-	return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc));
+-}
+-
+-void wlc_radio_mpc_upd(struct wlc_info *wlc)
+-{
+-	bool mpc_radio, radio_state;
+-
+-	/*
+-	 * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
+-	 * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
+-	 * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
+-	 * the radio is going down.
+-	 */
+-	if (!wlc->mpc) {
+-		if (!wlc->pub->radio_disabled)
+-			return;
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+-		wlc_radio_upd(wlc);
+-		if (!wlc->pub->radio_disabled)
+-			wlc_radio_monitor_stop(wlc);
+-		return;
+-	}
+-
+-	/*
+-	 * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
+-	 * to go ON, always call radio_upd synchronously
+-	 * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
+-	 */
+-	radio_state =
+-	    (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
+-	     ON);
+-	mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON;
+-
+-	if (radio_state == ON && mpc_radio == OFF)
+-		wlc->mpc_delay_off = wlc->mpc_dlycnt;
+-	else if (radio_state == OFF && mpc_radio == ON) {
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+-		wlc_radio_upd(wlc);
+-		if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) {
+-			wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT;
+-		} else
+-			wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-		wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
+-	}
+-	/* Below logic is meant to capture the transition from mpc off to mpc on for reasons
+-	 * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
+-	 * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
+-	 */
+-	if ((wlc->prev_non_delay_mpc == false) &&
+-	    (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) {
+-		wlc->mpc_delay_off = wlc->mpc_dlycnt;
+-	}
+-	wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc);
+-}
+-
+-/*
+- * centralized radio disable/enable function,
+- * invoke radio enable/disable after updating hwradio status
+- */
+-static void wlc_radio_upd(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->radio_disabled) {
+-		wlc_radio_disable(wlc);
+-	} else {
+-		wlc_radio_enable(wlc);
+-	}
+-}
+-
+-/* maintain LED behavior in down state */
+-static void wlc_down_led_upd(struct wlc_info *wlc)
+-{
+-	/* maintain LEDs while in down state, turn on sbclk if not available yet */
+-	/* turn on sbclk if necessary */
+-	if (!AP_ENAB(wlc->pub)) {
+-		wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP);
+-
+-		wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP);
+-	}
+-}
+-
+-/* update hwradio status and return it */
+-bool wlc_check_radio_disabled(struct wlc_info *wlc)
+-{
+-	wlc_radio_hwdisable_upd(wlc);
+-
+-	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false;
+-}
+-
+-void wlc_radio_disable(struct wlc_info *wlc)
+-{
+-	if (!wlc->pub->up) {
+-		wlc_down_led_upd(wlc);
+-		return;
+-	}
+-
+-	wlc_radio_monitor_start(wlc);
+-	wl_down(wlc->wl);
+-}
+-
+-static void wlc_radio_enable(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->up)
+-		return;
+-
+-	if (DEVICEREMOVED(wlc))
+-		return;
+-
+-	if (!wlc->down_override) {	/* imposed by wl down/out ioctl */
+-		wl_up(wlc->wl);
+-	}
+-}
+-
+-/* periodical query hw radio button while driver is "down" */
+-static void wlc_radio_timer(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			__func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-
+-	/* cap mpc off count */
+-	if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT)
+-		wlc->mpc_offcnt++;
+-
+-	wlc_radio_hwdisable_upd(wlc);
+-	wlc_radio_upd(wlc);
+-}
+-
+-static bool wlc_radio_monitor_start(struct wlc_info *wlc)
+-{
+-	/* Don't start the timer if HWRADIO feature is disabled */
+-	if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
+-		return true;
+-
+-	wlc->radio_monitor = true;
+-	wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON);
+-	wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
+-	return true;
+-}
+-
+-bool wlc_radio_monitor_stop(struct wlc_info *wlc)
+-{
+-	if (!wlc->radio_monitor)
+-		return true;
+-
+-	wlc->radio_monitor = false;
+-	wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON);
+-	return wl_del_timer(wlc->wl, wlc->radio_timer);
+-}
+-
+-static void wlc_watchdog_by_timer(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	wlc_watchdog(arg);
+-	if (WLC_WATCHDOG_TBTT(wlc)) {
+-		/* set to normal osl watchdog period */
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+-			     true);
+-	}
+-}
+-
+-/* common watchdog code */
+-static void wlc_watchdog(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	int i;
+-	struct wlc_bsscfg *cfg;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	if (!wlc->pub->up)
+-		return;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-
+-	/* increment second count */
+-	wlc->pub->now++;
+-
+-	/* delay radio disable */
+-	if (wlc->mpc_delay_off) {
+-		if (--wlc->mpc_delay_off == 0) {
+-			mboolset(wlc->pub->radio_disabled,
+-				 WL_RADIO_MPC_DISABLE);
+-			if (wlc->mpc && wlc_ismpc(wlc))
+-				wlc->mpc_offcnt = 0;
+-			wlc->mpc_laston_ts = OSL_SYSUPTIME();
+-		}
+-	}
+-
+-	/* mpc sync */
+-	wlc_radio_mpc_upd(wlc);
+-	/* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
+-	wlc_radio_hwdisable_upd(wlc);
+-	wlc_radio_upd(wlc);
+-	/* if radio is disable, driver may be down, quit here */
+-	if (wlc->pub->radio_disabled)
+-		return;
+-
+-	wlc_bmac_watchdog(wlc);
+-
+-	/* occasionally sample mac stat counters to detect 16-bit counter wrap */
+-	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
+-		wlc_statsupd(wlc);
+-
+-	/* Manage TKIP countermeasures timers */
+-	FOREACH_BSS(wlc, i, cfg) {
+-		if (cfg->tk_cm_dt) {
+-			cfg->tk_cm_dt--;
+-		}
+-		if (cfg->tk_cm_bt) {
+-			cfg->tk_cm_bt--;
+-		}
+-	}
+-
+-	/* Call any registered watchdog handlers */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].watchdog_fn)
+-			wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
+-	}
+-
+-	if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
+-	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
+-	     WLC_TEMPSENSE_PERIOD)) {
+-		wlc->tempsense_lasttime = wlc->pub->now;
+-		wlc_tempsense_upd(wlc);
+-	}
+-}
+-
+-/* make interface operational */
+-int wlc_up(struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* HW is turned off so don't try to access it */
+-	if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
+-		return -ENOMEDIUM;
+-
+-	if (!wlc->pub->hw_up) {
+-		wlc_bmac_hw_up(wlc->hw);
+-		wlc->pub->hw_up = true;
+-	}
+-
+-	if ((wlc->pub->boardflags & BFL_FEM)
+-	    && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
+-		if (wlc->pub->boardrev >= 0x1250
+-		    && (wlc->pub->boardflags & BFL_FEM_BT)) {
+-			wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
+-				MHF5_4313_GPIOCTRL, WLC_BAND_ALL);
+-		} else {
+-			wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE,
+-				WLC_BAND_ALL);
+-		}
+-	}
+-
+-	/*
+-	 * Need to read the hwradio status here to cover the case where the system
+-	 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+-	 * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
+-	 * don't call radio_update to avoid looping wlc_up.
+-	 *
+-	 * wlc_bmac_up_prep() returns either 0 or -BCME_RADIOOFF only
+-	 */
+-	if (!wlc->pub->radio_disabled) {
+-		int status = wlc_bmac_up_prep(wlc->hw);
+-		if (status == -ENOMEDIUM) {
+-			if (!mboolisset
+-			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
+-				int idx;
+-				struct wlc_bsscfg *bsscfg;
+-				mboolset(wlc->pub->radio_disabled,
+-					 WL_RADIO_HW_DISABLE);
+-
+-				FOREACH_BSS(wlc, idx, bsscfg) {
+-					if (!BSSCFG_STA(bsscfg)
+-					    || !bsscfg->enable || !bsscfg->BSS)
+-						continue;
+-					wiphy_err(wlc->wiphy, "wl%d.%d: wlc_up"
+-						  ": rfdisable -> "
+-						  "wlc_bsscfg_disable()\n",
+-						   wlc->pub->unit, idx);
+-				}
+-			}
+-		}
+-	}
+-
+-	if (wlc->pub->radio_disabled) {
+-		wlc_radio_monitor_start(wlc);
+-		return 0;
+-	}
+-
+-	/* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */
+-	wlc->clk = true;
+-
+-	wlc_radio_monitor_stop(wlc);
+-
+-	/* Set EDCF hostflags */
+-	if (EDCF_ENAB(wlc->pub)) {
+-		wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL);
+-	} else {
+-		wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL);
+-	}
+-
+-	if (WLC_WAR16165(wlc))
+-		wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
+-			WLC_BAND_ALL);
+-
+-	wl_init(wlc->wl);
+-	wlc->pub->up = true;
+-
+-	if (wlc->bandinit_pending) {
+-		wlc_suspend_mac_and_wait(wlc);
+-		wlc_set_chanspec(wlc, wlc->default_bss->chanspec);
+-		wlc->bandinit_pending = false;
+-		wlc_enable_mac(wlc);
+-	}
+-
+-	wlc_bmac_up_finish(wlc->hw);
+-
+-	/* other software states up after ISR is running */
+-	/* start APs that were to be brought up but are not up  yet */
+-	/* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */
+-
+-	/* Program the TX wme params with the current settings */
+-	wlc_wme_retries_write(wlc);
+-
+-	/* start one second watchdog timer */
+-	wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
+-	wlc->WDarmed = true;
+-
+-	/* ensure antenna config is up to date */
+-	wlc_stf_phy_txant_upd(wlc);
+-	/* ensure LDPC config is in sync */
+-	wlc_ht_update_ldpc(wlc, wlc->stf->ldpc);
+-
+-	return 0;
+-}
+-
+-/* Initialize the base precedence map for dequeueing from txq based on WME settings */
+-static void wlc_tx_prec_map_init(struct wlc_info *wlc)
+-{
+-	wlc->tx_prec_map = WLC_PREC_BMP_ALL;
+-	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
+-
+-	/* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
+-	 * if either is full.
+-	 */
+-	if (!EDCF_ENAB(wlc->pub)) {
+-		wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL;
+-		wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL;
+-	} else {
+-		wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK;
+-		wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE;
+-		wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI;
+-		wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO;
+-	}
+-}
+-
+-static uint wlc_down_del_timer(struct wlc_info *wlc)
+-{
+-	uint callbacks = 0;
+-
+-	return callbacks;
+-}
+-
+-/*
+- * Mark the interface nonoperational, stop the software mechanisms,
+- * disable the hardware, free any transient buffer state.
+- * Return a count of the number of driver callbacks still pending.
+- */
+-uint wlc_down(struct wlc_info *wlc)
+-{
+-
+-	uint callbacks = 0;
+-	int i;
+-	bool dev_gone = false;
+-	struct wlc_txq_info *qi;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* check if we are already in the going down path */
+-	if (wlc->going_down) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
+-			  "\n", wlc->pub->unit, __func__);
+-		return 0;
+-	}
+-	if (!wlc->pub->up)
+-		return callbacks;
+-
+-	/* in between, mpc could try to bring down again.. */
+-	wlc->going_down = true;
+-
+-	callbacks += wlc_bmac_down_prep(wlc->hw);
+-
+-	dev_gone = DEVICEREMOVED(wlc);
+-
+-	/* Call any registered down handlers */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].down_fn)
+-			callbacks +=
+-			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
+-	}
+-
+-	/* cancel the watchdog timer */
+-	if (wlc->WDarmed) {
+-		if (!wl_del_timer(wlc->wl, wlc->wdtimer))
+-			callbacks++;
+-		wlc->WDarmed = false;
+-	}
+-	/* cancel all other timers */
+-	callbacks += wlc_down_del_timer(wlc);
+-
+-	wlc->pub->up = false;
+-
+-	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
+-
+-	/* clear txq flow control */
+-	wlc_txflowcontrol_reset(wlc);
+-
+-	/* flush tx queues */
+-	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+-		bcm_pktq_flush(&qi->q, true, NULL, NULL);
+-	}
+-
+-	callbacks += wlc_bmac_down_finish(wlc->hw);
+-
+-	/* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */
+-	wlc->clk = false;
+-
+-	wlc->going_down = false;
+-	return callbacks;
+-}
+-
+-/* Set the current gmode configuration */
+-int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config)
+-{
+-	int ret = 0;
+-	uint i;
+-	wlc_rateset_t rs;
+-	/* Default to 54g Auto */
+-	s8 shortslot = WLC_SHORTSLOT_AUTO;	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
+-	bool shortslot_restrict = false;	/* Restrict association to stations that support shortslot
+-						 */
+-	bool ignore_bcns = true;	/* Ignore legacy beacons on the same channel */
+-	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
+-	int preamble = WLC_PLCP_LONG;	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
+-	bool preamble_restrict = false;	/* Restrict association to stations that support short
+-					 * preambles
+-					 */
+-	struct wlcband *band;
+-
+-	/* if N-support is enabled, allow Gmode set as long as requested
+-	 * Gmode is not GMODE_LEGACY_B
+-	 */
+-	if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
+-		return -ENOTSUPP;
+-
+-	/* verify that we are dealing with 2G band and grab the band pointer */
+-	if (wlc->band->bandtype == WLC_BAND_2G)
+-		band = wlc->band;
+-	else if ((NBANDS(wlc) > 1) &&
+-		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G))
+-		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+-	else
+-		return -EINVAL;
+-
+-	/* Legacy or bust when no OFDM is supported by regulatory */
+-	if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
+-	     WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B))
+-		return -EINVAL;
+-
+-	/* update configuration value */
+-	if (config == true)
+-		wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode);
+-
+-	/* Clear supported rates filter */
+-	memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t));
+-
+-	/* Clear rateset override */
+-	memset(&rs, 0, sizeof(wlc_rateset_t));
+-
+-	switch (gmode) {
+-	case GMODE_LEGACY_B:
+-		shortslot = WLC_SHORTSLOT_OFF;
+-		wlc_rateset_copy(&gphy_legacy_rates, &rs);
+-
+-		break;
+-
+-	case GMODE_LRS:
+-		if (AP_ENAB(wlc->pub))
+-			wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override);
+-		break;
+-
+-	case GMODE_AUTO:
+-		/* Accept defaults */
+-		break;
+-
+-	case GMODE_ONLY:
+-		ofdm_basic = true;
+-		preamble = WLC_PLCP_SHORT;
+-		preamble_restrict = true;
+-		break;
+-
+-	case GMODE_PERFORMANCE:
+-		if (AP_ENAB(wlc->pub))	/* Put all rates into the Supported Rates element */
+-			wlc_rateset_copy(&cck_ofdm_rates,
+-					 &wlc->sup_rates_override);
+-
+-		shortslot = WLC_SHORTSLOT_ON;
+-		shortslot_restrict = true;
+-		ofdm_basic = true;
+-		preamble = WLC_PLCP_SHORT;
+-		preamble_restrict = true;
+-		break;
+-
+-	default:
+-		/* Error */
+-		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
+-			  wlc->pub->unit, __func__, gmode);
+-		return -ENOTSUPP;
+-	}
+-
+-	/*
+-	 * If we are switching to gmode == GMODE_LEGACY_B,
+-	 * clean up rate info that may refer to OFDM rates.
+-	 */
+-	if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
+-		band->gmode = gmode;
+-		if (band->rspec_override && !IS_CCK(band->rspec_override)) {
+-			band->rspec_override = 0;
+-			wlc_reprate_init(wlc);
+-		}
+-		if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
+-			band->mrspec_override = 0;
+-		}
+-	}
+-
+-	band->gmode = gmode;
+-
+-	wlc->ignore_bcns = ignore_bcns;
+-
+-	wlc->shortslot_override = shortslot;
+-
+-	if (AP_ENAB(wlc->pub)) {
+-		/* wlc->ap->shortslot_restrict = shortslot_restrict; */
+-		wlc->PLCPHdr_override =
+-		    (preamble !=
+-		     WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO;
+-	}
+-
+-	if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG)
+-	    || preamble == WLC_PLCP_SHORT)
+-		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+-	else
+-		wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE;
+-
+-	/* Update shortslot capability bit for AP and IBSS */
+-	if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) ||
+-	    shortslot == WLC_SHORTSLOT_ON)
+-		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-	else
+-		wlc->default_bss->capability &=
+-					~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-
+-	/* Use the default 11g rateset */
+-	if (!rs.count)
+-		wlc_rateset_copy(&cck_ofdm_rates, &rs);
+-
+-	if (ofdm_basic) {
+-		for (i = 0; i < rs.count; i++) {
+-			if (rs.rates[i] == WLC_RATE_6M
+-			    || rs.rates[i] == WLC_RATE_12M
+-			    || rs.rates[i] == WLC_RATE_24M)
+-				rs.rates[i] |= WLC_RATE_FLAG;
+-		}
+-	}
+-
+-	/* Set default bss rateset */
+-	wlc->default_bss->rateset.count = rs.count;
+-	memcpy(wlc->default_bss->rateset.rates, rs.rates, 
+-	       sizeof(wlc->default_bss->rateset.rates));
+-
+-	return ret;
+-}
+-
+-static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode)
+-{
+-	int err = 0;
+-
+-	switch (nmode) {
+-
+-	case OFF:
+-		break;
+-
+-	case AUTO:
+-	case WL_11N_2x2:
+-	case WL_11N_3x3:
+-		if (!(WLC_PHY_11N_CAP(wlc->band)))
+-			err = -EINVAL;
+-		break;
+-
+-	default:
+-		err = -EINVAL;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-int wlc_set_nmode(struct wlc_info *wlc, s32 nmode)
+-{
+-	uint i;
+-	int err;
+-
+-	err = wlc_nmode_validate(wlc, nmode);
+-	if (err)
+-		return err;
+-
+-	switch (nmode) {
+-	case OFF:
+-		wlc->pub->_n_enab = OFF;
+-		wlc->default_bss->flags &= ~WLC_BSS_HT;
+-		/* delete the mcs rates from the default and hw ratesets */
+-		wlc_rateset_mcs_clear(&wlc->default_bss->rateset);
+-		for (i = 0; i < NBANDS(wlc); i++) {
+-			memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
+-			       MCSSET_LEN);
+-			if (IS_MCS(wlc->band->rspec_override)) {
+-				wlc->bandstate[i]->rspec_override = 0;
+-				wlc_reprate_init(wlc);
+-			}
+-			if (IS_MCS(wlc->band->mrspec_override))
+-				wlc->bandstate[i]->mrspec_override = 0;
+-		}
+-		break;
+-
+-	case AUTO:
+-		if (wlc->stf->txstreams == WL_11N_3x3)
+-			nmode = WL_11N_3x3;
+-		else
+-			nmode = WL_11N_2x2;
+-	case WL_11N_2x2:
+-	case WL_11N_3x3:
+-		/* force GMODE_AUTO if NMODE is ON */
+-		wlc_set_gmode(wlc, GMODE_AUTO, true);
+-		if (nmode == WL_11N_3x3)
+-			wlc->pub->_n_enab = SUPPORT_HT;
+-		else
+-			wlc->pub->_n_enab = SUPPORT_11N;
+-		wlc->default_bss->flags |= WLC_BSS_HT;
+-		/* add the mcs rates to the default and hw ratesets */
+-		wlc_rateset_mcs_build(&wlc->default_bss->rateset,
+-				      wlc->stf->txstreams);
+-		for (i = 0; i < NBANDS(wlc); i++)
+-			memcpy(wlc->bandstate[i]->hw_rateset.mcs,
+-			       wlc->default_bss->rateset.mcs, MCSSET_LEN);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg)
+-{
+-	wlc_rateset_t rs, new;
+-	uint bandunit;
+-
+-	memcpy(&rs, rs_arg, sizeof(wlc_rateset_t));
+-
+-	/* check for bad count value */
+-	if ((rs.count == 0) || (rs.count > WLC_NUMRATES))
+-		return -EINVAL;
+-
+-	/* try the current band */
+-	bandunit = wlc->band->bandunit;
+-	memcpy(&new, &rs, sizeof(wlc_rateset_t));
+-	if (wlc_rate_hwrs_filter_sort_validate
+-	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
+-	     wlc->stf->txstreams))
+-		goto good;
+-
+-	/* try the other band */
+-	if (IS_MBAND_UNLOCKED(wlc)) {
+-		bandunit = OTHERBANDUNIT(wlc);
+-		memcpy(&new, &rs, sizeof(wlc_rateset_t));
+-		if (wlc_rate_hwrs_filter_sort_validate(&new,
+-						       &wlc->
+-						       bandstate[bandunit]->
+-						       hw_rateset, true,
+-						       wlc->stf->txstreams))
+-			goto good;
+-	}
+-
+-	return -EBADE;
+-
+- good:
+-	/* apply new rateset */
+-	memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t));
+-	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
+-	       sizeof(wlc_rateset_t));
+-	return 0;
+-}
+-
+-/* simplified integer set interface for common ioctl handler */
+-int wlc_set(struct wlc_info *wlc, int cmd, int arg)
+-{
+-	return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
+-}
+-
+-/* simplified integer get interface for common ioctl handler */
+-int wlc_get(struct wlc_info *wlc, int cmd, int *arg)
+-{
+-	return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL);
+-}
+-
+-static void wlc_ofdm_rateset_war(struct wlc_info *wlc)
+-{
+-	u8 r;
+-	bool war = false;
+-
+-	if (wlc->cfg->associated)
+-		r = wlc->cfg->current_bss->rateset.rates[0];
+-	else
+-		r = wlc->default_bss->rateset.rates[0];
+-
+-	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
+-
+-	return;
+-}
+-
+-int
+-wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-	  struct wlc_if *wlcif)
+-{
+-	return _wlc_ioctl(wlc, cmd, arg, len, wlcif);
+-}
+-
+-/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
+-static int
+-_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-	   struct wlc_if *wlcif)
+-{
+-	int val, *pval;
+-	bool bool_val;
+-	int bcmerror;
+-	d11regs_t *regs;
+-	uint i;
+-	struct scb *nextscb;
+-	bool ta_ok;
+-	uint band;
+-	rw_reg_t *r;
+-	struct wlc_bsscfg *bsscfg;
+-	wlc_bss_info_t *current_bss;
+-
+-	/* update bsscfg pointer */
+-	bsscfg = wlc->cfg;
+-	current_bss = bsscfg->current_bss;
+-
+-	/* initialize the following to get rid of compiler warning */
+-	nextscb = NULL;
+-	ta_ok = false;
+-	band = 0;
+-	r = NULL;
+-
+-	/* If the device is turned off, then it's not "removed" */
+-	if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return -EBADE;
+-	}
+-
+-	/* default argument is generic integer */
+-	pval = arg ? (int *)arg:NULL;
+-
+-	/* This will prevent the misaligned access */
+-	if (pval && (u32) len >= sizeof(val))
+-		memcpy(&val, pval, sizeof(val));
+-	else
+-		val = 0;
+-
+-	/* bool conversion to avoid duplication below */
+-	bool_val = val != 0;
+-	bcmerror = 0;
+-	regs = wlc->regs;
+-
+-	/* A few commands don't need any arguments; all the others do. */
+-	switch (cmd) {
+-	case WLC_UP:
+-	case WLC_OUT:
+-	case WLC_DOWN:
+-	case WLC_DISASSOC:
+-	case WLC_RESTART:
+-	case WLC_REBOOT:
+-	case WLC_START_CHANNEL_QA:
+-	case WLC_INIT:
+-		break;
+-
+-	default:
+-		if ((arg == NULL) || (len <= 0)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs "
+-				  "arguments\n",
+-				  wlc->pub->unit, __func__, cmd);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	}
+-
+-	switch (cmd) {
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_MSGLEVEL:
+-		*pval = wl_msg_level;
+-		break;
+-
+-	case WLC_SET_MSGLEVEL:
+-		wl_msg_level = val;
+-		break;
+-#endif
+-
+-	case WLC_GET_INSTANCE:
+-		*pval = wlc->pub->unit;
+-		break;
+-
+-	case WLC_GET_CHANNEL:{
+-			channel_info_t *ci = (channel_info_t *) arg;
+-
+-			if (len <= (int)sizeof(ci)) {
+-				bcmerror = EOVERFLOW;
+-				goto done;
+-			}
+-
+-			ci->hw_channel =
+-			    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC);
+-			ci->target_channel =
+-			    CHSPEC_CHANNEL(wlc->default_bss->chanspec);
+-			ci->scan_channel = 0;
+-
+-			break;
+-		}
+-
+-	case WLC_SET_CHANNEL:{
+-			chanspec_t chspec = CH20MHZ_CHSPEC(val);
+-
+-			if (val < 0 || val > MAXCHANNEL) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
+-				if (wlc->band->bandunit !=
+-				    CHSPEC_WLCBANDUNIT(chspec))
+-					wlc->bandinit_pending = true;
+-				else
+-					wlc->bandinit_pending = false;
+-			}
+-
+-			wlc->default_bss->chanspec = chspec;
+-			/* wlc_BSSinit() will sanitize the rateset before using it.. */
+-			if (wlc->pub->up &&
+-			    (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) {
+-				wlc_set_home_chanspec(wlc, chspec);
+-				wlc_suspend_mac_and_wait(wlc);
+-				wlc_set_chanspec(wlc, chspec);
+-				wlc_enable_mac(wlc);
+-			}
+-			break;
+-		}
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_UCFLAGS:
+-		if (!wlc->pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val >= MHFMAX) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		*pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO);
+-		break;
+-
+-	case WLC_SET_UCFLAGS:
+-		if (!wlc->pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		i = (u16) val;
+-		if (i >= MHFMAX) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)),
+-			WLC_BAND_AUTO);
+-		break;
+-
+-	case WLC_GET_SHMEM:
+-		ta_ok = true;
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val & 1) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		*pval = wlc_read_shm(wlc, (u16) val);
+-		break;
+-
+-	case WLC_SET_SHMEM:
+-		ta_ok = true;
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val & 1) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_write_shm(wlc, (u16) val,
+-			      (u16) (val >> NBITS(u16)));
+-		break;
+-
+-	case WLC_R_REG:	/* MAC registers */
+-		ta_ok = true;
+-		r = (rw_reg_t *) arg;
+-		band = WLC_BAND_AUTO;
+-
+-		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-
+-		if (len >= (int)sizeof(rw_reg_t))
+-			band = r->band;
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if ((r->byteoff + r->size) > sizeof(d11regs_t)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (r->size == sizeof(u32))
+-			r->val =
+-			    R_REG((u32 *)((unsigned char *)(unsigned long)regs +
+-					      r->byteoff));
+-		else if (r->size == sizeof(u16))
+-			r->val =
+-			    R_REG((u16 *)((unsigned char *)(unsigned long)regs +
+-					      r->byteoff));
+-		else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_W_REG:
+-		ta_ok = true;
+-		r = (rw_reg_t *) arg;
+-		band = WLC_BAND_AUTO;
+-
+-		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-
+-		if (len >= (int)sizeof(rw_reg_t))
+-			band = r->band;
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (r->byteoff + r->size > sizeof(d11regs_t)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (r->size == sizeof(u32))
+-			W_REG((u32 *)((unsigned char *)(unsigned long) regs +
+-					  r->byteoff), r->val);
+-		else if (r->size == sizeof(u16))
+-			W_REG((u16 *)((unsigned char *)(unsigned long) regs +
+-					  r->byteoff), r->val);
+-		else
+-			bcmerror = -EINVAL;
+-		break;
+-#endif				/* BCMDBG */
+-
+-	case WLC_GET_TXANT:
+-		*pval = wlc->stf->txant;
+-		break;
+-
+-	case WLC_SET_TXANT:
+-		bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val);
+-		if (bcmerror < 0)
+-			break;
+-
+-		wlc->stf->txant = (s8) val;
+-
+-		/* if down, we are done */
+-		if (!wlc->pub->up)
+-			break;
+-
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-		wlc_stf_phy_txant_upd(wlc);
+-		wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+-
+-		wlc_enable_mac(wlc);
+-
+-		break;
+-
+-	case WLC_GET_ANTDIV:{
+-			u8 phy_antdiv;
+-
+-			/* return configured value if core is down */
+-			if (!wlc->pub->up) {
+-				*pval = wlc->stf->ant_rx_ovr;
+-
+-			} else {
+-				if (wlc_phy_ant_rxdiv_get
+-				    (wlc->band->pi, &phy_antdiv))
+-					*pval = (int)phy_antdiv;
+-				else
+-					*pval = (int)wlc->stf->ant_rx_ovr;
+-			}
+-
+-			break;
+-		}
+-	case WLC_SET_ANTDIV:
+-		/* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */
+-		if ((val < -1) || (val > 3)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		if (val == -1)
+-			val = ANT_RX_DIV_DEF;
+-
+-		wlc->stf->ant_rx_ovr = (u8) val;
+-		wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val);
+-		break;
+-
+-	case WLC_GET_RX_ANT:{	/* get latest used rx antenna */
+-			u16 rxstatus;
+-
+-			if (!wlc->pub->up) {
+-				bcmerror = -ENOLINK;
+-				break;
+-			}
+-
+-			rxstatus = R_REG(&wlc->regs->phyrxstatus0);
+-			if (rxstatus == 0xdead || rxstatus == (u16) -1) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-			*pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
+-			break;
+-		}
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_UCANTDIV:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		*pval =
+-		    (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) &
+-		     MHF1_ANTDIV);
+-		break;
+-
+-	case WLC_SET_UCANTDIV:{
+-			if (!wlc->pub->up) {
+-				bcmerror = -ENOLINK;
+-				break;
+-			}
+-
+-			/* if multiband, band must be locked */
+-			if (IS_MBAND_UNLOCKED(wlc)) {
+-				bcmerror = -ENOMEDIUM;
+-				break;
+-			}
+-
+-			wlc_mhf(wlc, MHF1, MHF1_ANTDIV,
+-				(val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO);
+-			break;
+-		}
+-#endif				/* defined(BCMDBG) */
+-
+-	case WLC_GET_SRL:
+-		*pval = wlc->SRL;
+-		break;
+-
+-	case WLC_SET_SRL:
+-		if (val >= 1 && val <= RETRY_SHORT_MAX) {
+-			int ac;
+-			wlc->SRL = (u16) val;
+-
+-			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+-
+-			for (ac = 0; ac < AC_COUNT; ac++) {
+-				WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
+-			}
+-			wlc_wme_retries_write(wlc);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_LRL:
+-		*pval = wlc->LRL;
+-		break;
+-
+-	case WLC_SET_LRL:
+-		if (val >= 1 && val <= 255) {
+-			int ac;
+-			wlc->LRL = (u16) val;
+-
+-			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+-
+-			for (ac = 0; ac < AC_COUNT; ac++) {
+-				WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
+-			}
+-			wlc_wme_retries_write(wlc);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_CWMIN:
+-		*pval = wlc->band->CWmin;
+-		break;
+-
+-	case WLC_SET_CWMIN:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		if (val >= 1 && val <= 255) {
+-			wlc_set_cwmin(wlc, (u16) val);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_CWMAX:
+-		*pval = wlc->band->CWmax;
+-		break;
+-
+-	case WLC_SET_CWMAX:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		if (val >= 255 && val <= 2047) {
+-			wlc_set_cwmax(wlc, (u16) val);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_RADIO:	/* use mask if don't want to expose some internal bits */
+-		*pval = wlc->pub->radio_disabled;
+-		break;
+-
+-	case WLC_SET_RADIO:{	/* 32 bits input, higher 16 bits are mask, lower 16 bits are value to
+-				 * set
+-				 */
+-			u16 radiomask, radioval;
+-			uint validbits =
+-			    WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE;
+-			mbool new = 0;
+-
+-			radiomask = (val & 0xffff0000) >> 16;
+-			radioval = val & 0x0000ffff;
+-
+-			if ((radiomask == 0) || (radiomask & ~validbits)
+-			    || (radioval & ~validbits)
+-			    || ((radioval & ~radiomask) != 0)) {
+-				wiphy_err(wlc->wiphy, "SET_RADIO with wrong "
+-					  "bits 0x%x\n", val);
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			new =
+-			    (wlc->pub->radio_disabled & ~radiomask) | radioval;
+-			wlc->pub->radio_disabled = new;
+-
+-			wlc_radio_hwdisable_upd(wlc);
+-			wlc_radio_upd(wlc);
+-			break;
+-		}
+-
+-	case WLC_GET_PHYTYPE:
+-		*pval = WLC_PHYTYPE(wlc->band->phytype);
+-		break;
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_KEY:
+-		if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) {
+-			wl_wsec_key_t key;
+-
+-			wsec_key_t *src_key = wlc->wsec_keys[val];
+-
+-			if (len < (int)sizeof(key)) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			memset((char *)&key, 0, sizeof(key));
+-			if (src_key) {
+-				key.index = src_key->id;
+-				key.len = src_key->len;
+-				memcpy(key.data, src_key->data, key.len);
+-				key.algo = src_key->algo;
+-				if (WSEC_SOFTKEY(wlc, src_key, bsscfg))
+-					key.flags |= WL_SOFT_KEY;
+-				if (src_key->flags & WSEC_PRIMARY_KEY)
+-					key.flags |= WL_PRIMARY_KEY;
+-
+-				memcpy(key.ea, src_key->ea, ETH_ALEN);
+-			}
+-
+-			memcpy(arg, &key, sizeof(key));
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-#endif				/* defined(BCMDBG) */
+-
+-	case WLC_SET_KEY:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_GET_KEY_SEQ:{
+-			wsec_key_t *key;
+-
+-			if (len < DOT11_WPA_KEY_RSC_LEN) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Return the key's tx iv as an EAPOL sequence counter.
+-			 * This will be used to supply the RSC value to a supplicant.
+-			 * The format is 8 bytes, with least significant in seq[0].
+-			 */
+-
+-			key = WSEC_KEY(wlc, val);
+-			if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) &&
+-				(key != NULL)) {
+-				u8 seq[DOT11_WPA_KEY_RSC_LEN];
+-				u16 lo;
+-				u32 hi;
+-				/* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */
+-				if ((bsscfg->WPA_auth & WPA_AUTH_NONE) &&
+-				    is_zero_ether_addr(key->ea)) {
+-					lo = bsscfg->wpa_none_txiv.lo;
+-					hi = bsscfg->wpa_none_txiv.hi;
+-				} else {
+-					lo = key->txiv.lo;
+-					hi = key->txiv.hi;
+-				}
+-
+-				/* format the buffer, low to high */
+-				seq[0] = lo & 0xff;
+-				seq[1] = (lo >> 8) & 0xff;
+-				seq[2] = hi & 0xff;
+-				seq[3] = (hi >> 8) & 0xff;
+-				seq[4] = (hi >> 16) & 0xff;
+-				seq[5] = (hi >> 24) & 0xff;
+-				seq[6] = 0;
+-				seq[7] = 0;
+-
+-				memcpy(arg, seq, sizeof(seq));
+-			} else {
+-				bcmerror = -EINVAL;
+-			}
+-			break;
+-		}
+-
+-	case WLC_GET_CURR_RATESET:{
+-			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+-			wlc_rateset_t *rs;
+-
+-			if (wlc->pub->associated)
+-				rs = &current_bss->rateset;
+-			else
+-				rs = &wlc->default_bss->rateset;
+-
+-			if (len < (int)(rs->count + sizeof(rs->count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Copy only legacy rateset section */
+-			ret_rs->count = rs->count;
+-			memcpy(&ret_rs->rates, &rs->rates, rs->count);
+-			break;
+-		}
+-
+-	case WLC_GET_RATESET:{
+-			wlc_rateset_t rs;
+-			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+-
+-			memset(&rs, 0, sizeof(wlc_rateset_t));
+-			wlc_default_rateset(wlc, (wlc_rateset_t *) &rs);
+-
+-			if (len < (int)(rs.count + sizeof(rs.count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Copy only legacy rateset section */
+-			ret_rs->count = rs.count;
+-			memcpy(&ret_rs->rates, &rs.rates, rs.count);
+-			break;
+-		}
+-
+-	case WLC_SET_RATESET:{
+-			wlc_rateset_t rs;
+-			wl_rateset_t *in_rs = (wl_rateset_t *) arg;
+-
+-			if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			if (in_rs->count > WLC_NUMRATES) {
+-				bcmerror = -ENOBUFS;
+-				break;
+-			}
+-
+-			memset(&rs, 0, sizeof(wlc_rateset_t));
+-
+-			/* Copy only legacy rateset section */
+-			rs.count = in_rs->count;
+-			memcpy(&rs.rates, &in_rs->rates, rs.count);
+-
+-			/* merge rateset coming in with the current mcsset */
+-			if (N_ENAB(wlc->pub)) {
+-				if (bsscfg->associated)
+-					memcpy(rs.mcs,
+-					       &current_bss->rateset.mcs[0],
+-					       MCSSET_LEN);
+-				else
+-					memcpy(rs.mcs,
+-					       &wlc->default_bss->rateset.mcs[0],
+-					       MCSSET_LEN);
+-			}
+-
+-			bcmerror = wlc_set_rateset(wlc, &rs);
+-
+-			if (!bcmerror)
+-				wlc_ofdm_rateset_war(wlc);
+-
+-			break;
+-		}
+-
+-	case WLC_GET_BCNPRD:
+-		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+-			*pval = current_bss->beacon_period;
+-		else
+-			*pval = wlc->default_bss->beacon_period;
+-		break;
+-
+-	case WLC_SET_BCNPRD:
+-		/* range [1, 0xffff] */
+-		if (val >= DOT11_MIN_BEACON_PERIOD
+-		    && val <= DOT11_MAX_BEACON_PERIOD) {
+-			wlc->default_bss->beacon_period = (u16) val;
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_DTIMPRD:
+-		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+-			*pval = current_bss->dtim_period;
+-		else
+-			*pval = wlc->default_bss->dtim_period;
+-		break;
+-
+-	case WLC_SET_DTIMPRD:
+-		/* range [1, 0xff] */
+-		if (val >= DOT11_MIN_DTIM_PERIOD
+-		    && val <= DOT11_MAX_DTIM_PERIOD) {
+-			wlc->default_bss->dtim_period = (u8) val;
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-#ifdef SUPPORT_PS
+-	case WLC_GET_PM:
+-		*pval = wlc->PM;
+-		break;
+-
+-	case WLC_SET_PM:
+-		if ((val >= PM_OFF) && (val <= PM_MAX)) {
+-			wlc->PM = (u8) val;
+-			if (wlc->pub->up) {
+-			}
+-			/* Change watchdog driver to align watchdog with tbtt if possible */
+-			wlc_watchdog_upd(wlc, PS_ALLOWED(wlc));
+-		} else
+-			bcmerror = -EBADE;
+-		break;
+-#endif				/* SUPPORT_PS */
+-
+-#ifdef SUPPORT_PS
+-#ifdef BCMDBG
+-	case WLC_GET_WAKE:
+-		if (AP_ENAB(wlc->pub)) {
+-			bcmerror = -BCME_NOTSTA;
+-			break;
+-		}
+-		*pval = wlc->wake;
+-		break;
+-
+-	case WLC_SET_WAKE:
+-		if (AP_ENAB(wlc->pub)) {
+-			bcmerror = -BCME_NOTSTA;
+-			break;
+-		}
+-
+-		wlc->wake = val ? true : false;
+-
+-		/* if down, we're done */
+-		if (!wlc->pub->up)
+-			break;
+-
+-		/* apply to the mac */
+-		wlc_set_ps_ctrl(wlc);
+-		break;
+-#endif				/* BCMDBG */
+-#endif				/* SUPPORT_PS */
+-
+-	case WLC_GET_REVINFO:
+-		bcmerror = wlc_get_revision_info(wlc, arg, (uint) len);
+-		break;
+-
+-	case WLC_GET_AP:
+-		*pval = (int)AP_ENAB(wlc->pub);
+-		break;
+-
+-	case WLC_GET_ATIM:
+-		if (bsscfg->associated)
+-			*pval = (int)current_bss->atim_window;
+-		else
+-			*pval = (int)wlc->default_bss->atim_window;
+-		break;
+-
+-	case WLC_SET_ATIM:
+-		wlc->default_bss->atim_window = (u32) val;
+-		break;
+-
+-#ifdef SUPPORT_HWKEY
+-	case WLC_GET_WSEC:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_SET_WSEC:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_GET_WPA_AUTH:
+-		*pval = (int)bsscfg->WPA_auth;
+-		break;
+-
+-	case WLC_SET_WPA_AUTH:
+-		/* change of WPA_Auth modifies the PS_ALLOWED state */
+-		if (BSSCFG_STA(bsscfg)) {
+-			bsscfg->WPA_auth = (u16) val;
+-		} else
+-			bsscfg->WPA_auth = (u16) val;
+-		break;
+-#endif				/* SUPPORT_HWKEY */
+-
+-	case WLC_GET_BANDLIST:
+-		/* count of number of bands, followed by each band type */
+-		*pval++ = NBANDS(wlc);
+-		*pval++ = wlc->band->bandtype;
+-		if (NBANDS(wlc) > 1)
+-			*pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype;
+-		break;
+-
+-	case WLC_GET_BAND:
+-		*pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO;
+-		break;
+-
+-	case WLC_GET_PHYLIST:
+-		{
+-			unsigned char *cp = arg;
+-			if (len < 3) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			if (WLCISNPHY(wlc->band)) {
+-				*cp++ = 'n';
+-			} else if (WLCISLCNPHY(wlc->band)) {
+-				*cp++ = 'c';
+-			} else if (WLCISSSLPNPHY(wlc->band)) {
+-				*cp++ = 's';
+-			}
+-			*cp = '\0';
+-			break;
+-		}
+-
+-	case WLC_GET_SHORTSLOT:
+-		*pval = wlc->shortslot;
+-		break;
+-
+-	case WLC_GET_SHORTSLOT_OVERRIDE:
+-		*pval = wlc->shortslot_override;
+-		break;
+-
+-	case WLC_SET_SHORTSLOT_OVERRIDE:
+-		if ((val != WLC_SHORTSLOT_AUTO) &&
+-		    (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc->shortslot_override = (s8) val;
+-
+-		/* shortslot is an 11g feature, so no more work if we are
+-		 * currently on the 5G band
+-		 */
+-		if (BAND_5G(wlc->band->bandtype))
+-			break;
+-
+-		if (wlc->pub->up && wlc->pub->associated) {
+-			/* let watchdog or beacon processing update shortslot */
+-		} else if (wlc->pub->up) {
+-			/* unassociated shortslot is off */
+-			wlc_switch_shortslot(wlc, false);
+-		} else {
+-			/* driver is down, so just update the wlc_info value */
+-			if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) {
+-				wlc->shortslot = false;
+-			} else {
+-				wlc->shortslot =
+-				    (wlc->shortslot_override ==
+-				     WLC_SHORTSLOT_ON);
+-			}
+-		}
+-
+-		break;
+-
+-	case WLC_GET_LEGACY_ERP:
+-		*pval = wlc->include_legacy_erp;
+-		break;
+-
+-	case WLC_SET_LEGACY_ERP:
+-		if (wlc->include_legacy_erp == bool_val)
+-			break;
+-
+-		wlc->include_legacy_erp = bool_val;
+-
+-		if (AP_ENAB(wlc->pub) && wlc->clk) {
+-			wlc_update_beacon(wlc);
+-			wlc_update_probe_resp(wlc, true);
+-		}
+-		break;
+-
+-	case WLC_GET_GMODE:
+-		if (wlc->band->bandtype == WLC_BAND_2G)
+-			*pval = wlc->band->gmode;
+-		else if (NBANDS(wlc) > 1)
+-			*pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode;
+-		break;
+-
+-	case WLC_SET_GMODE:
+-		if (!wlc->pub->associated)
+-			bcmerror = wlc_set_gmode(wlc, (u8) val, true);
+-		else {
+-			bcmerror = -EISCONN;
+-			break;
+-		}
+-		break;
+-
+-	case WLC_GET_GMODE_PROTECTION:
+-		*pval = wlc->protection->_g;
+-		break;
+-
+-	case WLC_GET_PROTECTION_CONTROL:
+-		*pval = wlc->protection->overlap;
+-		break;
+-
+-	case WLC_SET_PROTECTION_CONTROL:
+-		if ((val != WLC_PROTECTION_CTL_OFF) &&
+-		    (val != WLC_PROTECTION_CTL_LOCAL) &&
+-		    (val != WLC_PROTECTION_CTL_OVERLAP)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val);
+-
+-		/* Current g_protection will sync up to the specified control alg in watchdog
+-		 * if the driver is up and associated.
+-		 * If the driver is down or not associated, the control setting has no effect.
+-		 */
+-		break;
+-
+-	case WLC_GET_GMODE_PROTECTION_OVERRIDE:
+-		*pval = wlc->protection->g_override;
+-		break;
+-
+-	case WLC_SET_GMODE_PROTECTION_OVERRIDE:
+-		if ((val != WLC_PROTECTION_AUTO) &&
+-		    (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val);
+-
+-		break;
+-
+-	case WLC_SET_SUP_RATESET_OVERRIDE:{
+-			wlc_rateset_t rs, new;
+-
+-			/* copyin */
+-			if (len < (int)sizeof(wlc_rateset_t)) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-			memcpy(&rs, arg, sizeof(wlc_rateset_t));
+-
+-			/* check for bad count value */
+-			if (rs.count > WLC_NUMRATES) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* this command is only appropriate for gmode operation */
+-			if (!(wlc->band->gmode ||
+-			      ((NBANDS(wlc) > 1)
+-			       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+-				/* gmode only command when not in gmode */
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* check for an empty rateset to clear the override */
+-			if (rs.count == 0) {
+-				memset(&wlc->sup_rates_override, 0,
+-				      sizeof(wlc_rateset_t));
+-				break;
+-			}
+-
+-			/*
+-			 * validate rateset by comparing pre and
+-			 * post sorted against 11g hw rates
+-			 */
+-			wlc_rateset_filter(&rs, &new, false,
+-					   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-					   BSS_N_ENAB(wlc, bsscfg));
+-			wlc_rate_hwrs_filter_sort_validate(&new,
+-							   &cck_ofdm_rates,
+-							   false,
+-							   wlc->stf->txstreams);
+-			if (rs.count != new.count) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* apply new rateset to the override */
+-			memcpy(&wlc->sup_rates_override, &new,
+-			      sizeof(wlc_rateset_t));
+-
+-			/* update bcn and probe resp if needed */
+-			if (wlc->pub->up && AP_ENAB(wlc->pub)
+-			    && wlc->pub->associated) {
+-				wlc_update_beacon(wlc);
+-				wlc_update_probe_resp(wlc, true);
+-			}
+-			break;
+-		}
+-
+-	case WLC_GET_SUP_RATESET_OVERRIDE:
+-		/* this command is only appropriate for gmode operation */
+-		if (!(wlc->band->gmode ||
+-		      ((NBANDS(wlc) > 1)
+-		       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+-			/* gmode only command when not in gmode */
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (len < (int)sizeof(wlc_rateset_t)) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-		memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t));
+-
+-		break;
+-
+-	case WLC_GET_PRB_RESP_TIMEOUT:
+-		*pval = wlc->prb_resp_timeout;
+-		break;
+-
+-	case WLC_SET_PRB_RESP_TIMEOUT:
+-		if (wlc->pub->up) {
+-			bcmerror = -EISCONN;
+-			break;
+-		}
+-		if (val < 0 || val >= 0xFFFF) {
+-			bcmerror = -EINVAL;	/* bad value */
+-			break;
+-		}
+-		wlc->prb_resp_timeout = (u16) val;
+-		break;
+-
+-	case WLC_GET_KEY_PRIMARY:{
+-			wsec_key_t *key;
+-
+-			/* treat the 'val' parm as the key id */
+-			key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+-			if (key != NULL) {
+-				*pval = key->id == val ? true : false;
+-			} else {
+-				bcmerror = -EINVAL;
+-			}
+-			break;
+-		}
+-
+-	case WLC_SET_KEY_PRIMARY:{
+-			wsec_key_t *key, *old_key;
+-
+-			bcmerror = -EINVAL;
+-
+-			/* treat the 'val' parm as the key id */
+-			for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+-				key = bsscfg->bss_def_keys[i];
+-				if (key != NULL && key->id == val) {
+-					old_key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+-					if (old_key != NULL)
+-						old_key->flags &=
+-						    ~WSEC_PRIMARY_KEY;
+-					key->flags |= WSEC_PRIMARY_KEY;
+-					bsscfg->wsec_index = i;
+-					bcmerror = 0;
+-				}
+-			}
+-			break;
+-		}
+-
+-#ifdef BCMDBG
+-	case WLC_INIT:
+-		wl_init(wlc->wl);
+-		break;
+-#endif
+-
+-	case WLC_SET_VAR:
+-	case WLC_GET_VAR:{
+-			char *name;
+-			/* validate the name value */
+-			name = (char *)arg;
+-			for (i = 0; i < (uint) len && *name != '\0';
+-			     i++, name++)
+-				;
+-
+-			if (i == (uint) len) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-			i++;	/* include the null in the string length */
+-
+-			if (cmd == WLC_GET_VAR) {
+-				bcmerror =
+-				    wlc_iovar_op(wlc, arg,
+-						 (void *)((s8 *) arg + i),
+-						 len - i, arg, len, IOV_GET,
+-						 wlcif);
+-			} else
+-				bcmerror =
+-				    wlc_iovar_op(wlc, arg, NULL, 0,
+-						 (void *)((s8 *) arg + i),
+-						 len - i, IOV_SET, wlcif);
+-
+-			break;
+-		}
+-
+-	case WLC_SET_WSEC_PMK:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-
+-#if defined(BCMDBG)
+-	case WLC_CURRENT_PWR:
+-		if (!wlc->pub->up)
+-			bcmerror = -ENOLINK;
+-		else
+-			bcmerror = wlc_get_current_txpwr(wlc, arg, len);
+-		break;
+-#endif
+-
+-	case WLC_LAST:
+-		wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__);
+-	}
+- done:
+-
+-	if (bcmerror)
+-		wlc->pub->bcmerror = bcmerror;
+-
+-	return bcmerror;
+-}
+-
+-#if defined(BCMDBG)
+-/* consolidated register access ioctl error checking */
+-int wlc_iocregchk(struct wlc_info *wlc, uint band)
+-{
+-	/* if band is specified, it must be the current band */
+-	if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype))
+-		return -EINVAL;
+-
+-	/* if multiband and band is not specified, band must be locked */
+-	if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc))
+-		return -ENOMEDIUM;
+-
+-	/* must have core clocks */
+-	if (!wlc->clk)
+-		return -EIO;
+-
+-	return 0;
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-/* Look up the given var name in the given table */
+-static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table,
+-					   const char *name)
+-{
+-	const bcm_iovar_t *vi;
+-	const char *lookup_name;
+-
+-	/* skip any ':' delimited option prefixes */
+-	lookup_name = strrchr(name, ':');
+-	if (lookup_name != NULL)
+-		lookup_name++;
+-	else
+-		lookup_name = name;
+-
+-	for (vi = table; vi->name; vi++) {
+-		if (!strcmp(vi->name, lookup_name))
+-			return vi;
+-	}
+-	/* ran to end of table */
+-
+-	return NULL;		/* var name not found */
+-}
+-
+-/* simplified integer get interface for common WLC_GET_VAR ioctl handler */
+-int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg)
+-{
+-	return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET,
+-			    NULL);
+-}
+-
+-/* simplified integer set interface for common WLC_SET_VAR ioctl handler */
+-int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg)
+-{
+-	return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg),
+-			    IOV_SET, NULL);
+-}
+-
+-/*
+- * register iovar table, watchdog and down handlers.
+- * calling function must keep 'iovars' until wlc_module_unregister is called.
+- * 'iovar' must have the last entry's name field being NULL as terminator.
+- */
+-int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars,
+-			const char *name, void *hdl, iovar_fn_t i_fn,
+-			watchdog_fn_t w_fn, down_fn_t d_fn)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int i;
+-
+-	/* find an empty entry and just add, no duplication check! */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].name[0] == '\0') {
+-			strncpy(wlc->modulecb[i].name, name,
+-				sizeof(wlc->modulecb[i].name) - 1);
+-			wlc->modulecb[i].iovars = iovars;
+-			wlc->modulecb[i].hdl = hdl;
+-			wlc->modulecb[i].iovar_fn = i_fn;
+-			wlc->modulecb[i].watchdog_fn = w_fn;
+-			wlc->modulecb[i].down_fn = d_fn;
+-			return 0;
+-		}
+-	}
+-
+-	return -ENOSR;
+-}
+-
+-/* unregister module callbacks */
+-int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int i;
+-
+-	if (wlc == NULL)
+-		return -ENODATA;
+-
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (!strcmp(wlc->modulecb[i].name, name) &&
+-		    (wlc->modulecb[i].hdl == hdl)) {
+-			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
+-			return 0;
+-		}
+-	}
+-
+-	/* table not found! */
+-	return -ENODATA;
+-}
+-
+-/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
+-static void wlc_wme_retries_write(struct wlc_info *wlc)
+-{
+-	int ac;
+-
+-	/* Need clock to do this */
+-	if (!wlc->clk)
+-		return;
+-
+-	for (ac = 0; ac < AC_COUNT; ac++) {
+-		wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]);
+-	}
+-}
+-
+-/* Get or set an iovar.  The params/p_len pair specifies any additional
+- * qualifying parameters (e.g. an "element index") for a get, while the
+- * arg/len pair is the buffer for the value to be set or retrieved.
+- * Operation (get/set) is specified by the last argument.
+- * interface context provided by wlcif
+- *
+- * All pointers may point into the same buffer.
+- */
+-int
+-wlc_iovar_op(struct wlc_info *wlc, const char *name,
+-	     void *params, int p_len, void *arg, int len,
+-	     bool set, struct wlc_if *wlcif)
+-{
+-	int err = 0;
+-	int val_size;
+-	const bcm_iovar_t *vi = NULL;
+-	u32 actionid;
+-	int i;
+-
+-	if (!set && (len == sizeof(int)) &&
+-	    !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s unaligned get ptr for %s\n",
+-			  wlc->pub->unit, __func__, name);
+-		return -ENOTSUPP;
+-	}
+-
+-	/* find the given iovar name */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (!wlc->modulecb[i].iovars)
+-			continue;
+-		vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name);
+-		if (vi)
+-			break;
+-	}
+-	/* iovar name not found */
+-	if (i >= WLC_MAXMODULES) {
+-		return -ENOTSUPP;
+-	}
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		p_len = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-
+-	/* Do the actual parameter implementation */
+-	err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid,
+-					name, params, p_len, arg, len, val_size,
+-					wlcif);
+-	return err;
+-}
+-
+-int
+-wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len,
+-		bool set)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int err = 0;
+-	s32 int_val = 0;
+-
+-	/* check generic condition flags */
+-	if (set) {
+-		if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) ||
+-		    ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) {
+-			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
+-		} else if ((vi->flags & IOVF_SET_BAND)
+-			   && IS_MBAND_UNLOCKED(wlc)) {
+-			err = -ENOMEDIUM;
+-		} else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) {
+-			err = -EIO;
+-		}
+-	} else {
+-		if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) ||
+-		    ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) {
+-			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
+-		} else if ((vi->flags & IOVF_GET_BAND)
+-			   && IS_MBAND_UNLOCKED(wlc)) {
+-			err = -ENOMEDIUM;
+-		} else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) {
+-			err = -EIO;
+-		}
+-	}
+-
+-	if (err)
+-		goto exit;
+-
+-	/* length check on io buf */
+-	err = bcm_iovar_lencheck(vi, arg, len, set);
+-	if (err)
+-		goto exit;
+-
+-	/* On set, check value ranges for integer types */
+-	if (set) {
+-		switch (vi->type) {
+-		case IOVT_BOOL:
+-		case IOVT_INT8:
+-		case IOVT_INT16:
+-		case IOVT_INT32:
+-		case IOVT_UINT8:
+-		case IOVT_UINT16:
+-		case IOVT_UINT32:
+-			memcpy(&int_val, arg, sizeof(int));
+-			err = wlc_iovar_rangecheck(wlc, int_val, vi);
+-			break;
+-		}
+-	}
+- exit:
+-	return err;
+-}
+-
+-/* handler for iovar table wlc_iovars */
+-/*
+- * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each
+- * iovar case, the switch statement maps the iovar id into separate get
+- * and set values.  If you add a new iovar to the switch you MUST use
+- * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with
+- * another case.
+- * Please use params for additional qualifying parameters.
+- */
+-int
+-wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid,
+-	    const char *name, void *params, uint p_len, void *arg, int len,
+-	    int val_size, struct wlc_if *wlcif)
+-{
+-	struct wlc_info *wlc = hdl;
+-	struct wlc_bsscfg *bsscfg;
+-	int err = 0;
+-	s32 int_val = 0;
+-	s32 int_val2 = 0;
+-	s32 *ret_int_ptr;
+-	bool bool_val;
+-	bool bool_val2;
+-	wlc_bss_info_t *current_bss;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	bsscfg = NULL;
+-	current_bss = NULL;
+-
+-	err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid));
+-	if (err != 0)
+-		return err;
+-
+-	/* convenience int and bool vals for first 8 bytes of buffer */
+-	if (p_len >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	if (p_len >= (int)sizeof(int_val) * 2)
+-		memcpy(&int_val2,
+-		       (void *)((unsigned long)params + sizeof(int_val)),
+-		       sizeof(int_val));
+-
+-	/* convenience int ptr for 4-byte gets (requires int aligned arg) */
+-	ret_int_ptr = (s32 *) arg;
+-
+-	bool_val = (int_val != 0) ? true : false;
+-	bool_val2 = (int_val2 != 0) ? true : false;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: id %d\n", wlc->pub->unit, IOV_ID(actionid));
+-	/* Do the actual parameter implementation */
+-	switch (actionid) {
+-	case IOV_SVAL(IOV_RTSTHRESH):
+-		wlc->RTSThresh = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_QTXPOWER):{
+-			uint qdbm;
+-			bool override;
+-
+-			err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
+-				&override);
+-			if (err != 0)
+-				return err;
+-
+-			/* Return qdbm units */
+-			*ret_int_ptr =
+-			    qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
+-			break;
+-		}
+-
+-		/* As long as override is false, this only sets the *user* targets.
+-		   User can twiddle this all he wants with no harm.
+-		   wlc_phy_txpower_set() explicitly sets override to false if
+-		   not internal or test.
+-		 */
+-	case IOV_SVAL(IOV_QTXPOWER):{
+-			u8 qdbm;
+-			bool override;
+-
+-			/* Remove override bit and clip to max qdbm value */
+-			qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff);
+-			/* Extract override setting */
+-			override = (int_val & WL_TXPWR_OVERRIDE) ? true : false;
+-			err =
+-			    wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_MPC):
+-		*ret_int_ptr = (s32) wlc->mpc;
+-		break;
+-
+-	case IOV_SVAL(IOV_MPC):
+-		wlc->mpc = bool_val;
+-		wlc_radio_mpc_upd(wlc);
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_BCN_LI_BCN):
+-		*ret_int_ptr = wlc->bcn_li_bcn;
+-		break;
+-
+-	case IOV_SVAL(IOV_BCN_LI_BCN):
+-		wlc->bcn_li_bcn = (u8) int_val;
+-		if (wlc->pub->up)
+-			wlc_bcn_li_upd(wlc);
+-		break;
+-
+-	default:
+-		wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n",
+-			  wlc->pub->unit, __func__);
+-		err = -ENOTSUPP;
+-		break;
+-	}
+-
+-	goto exit;		/* avoid unused label warning */
+-
+- exit:
+-	return err;
+-}
+-
+-static int
+-wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi)
+-{
+-	int err = 0;
+-	u32 min_val = 0;
+-	u32 max_val = 0;
+-
+-	/* Only ranged integers are checked */
+-	switch (vi->type) {
+-	case IOVT_INT32:
+-		max_val |= 0x7fffffff;
+-		/* fall through */
+-	case IOVT_INT16:
+-		max_val |= 0x00007fff;
+-		/* fall through */
+-	case IOVT_INT8:
+-		max_val |= 0x0000007f;
+-		min_val = ~max_val;
+-		if (vi->flags & IOVF_NTRL)
+-			min_val = 1;
+-		else if (vi->flags & IOVF_WHL)
+-			min_val = 0;
+-		/* Signed values are checked against max_val and min_val */
+-		if ((s32) val < (s32) min_val
+-		    || (s32) val > (s32) max_val)
+-			err = -EINVAL;
+-		break;
+-
+-	case IOVT_UINT32:
+-		max_val |= 0xffffffff;
+-		/* fall through */
+-	case IOVT_UINT16:
+-		max_val |= 0x0000ffff;
+-		/* fall through */
+-	case IOVT_UINT8:
+-		max_val |= 0x000000ff;
+-		if (vi->flags & IOVF_NTRL)
+-			min_val = 1;
+-		if ((val < min_val) || (val > max_val))
+-			err = -EINVAL;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-#ifdef BCMDBG
+-static const char *supr_reason[] = {
+-	"None", "PMQ Entry", "Flush request",
+-	"Previous frag failure", "Channel mismatch",
+-	"Lifetime Expiry", "Underflow"
+-};
+-
+-static void wlc_print_txs_status(u16 s)
+-{
+-	printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
+-	       (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
+-	printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
+-	       (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
+-	printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
+-	       ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
+-	printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
+-	       ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
+-	printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
+-	       (s & TX_STATUS_AMPDU) ? 1 : 0);
+-	printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
+-	       ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
+-	       supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
+-	printk(KERN_DEBUG "    [1]  %d  acked\n",
+-	       ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
+-}
+-#endif				/* BCMDBG */
+-
+-void wlc_print_txstatus(tx_status_t *txs)
+-{
+-#if defined(BCMDBG)
+-	u16 s = txs->status;
+-	u16 ackphyrxsh = txs->ackphyrxsh;
+-
+-	printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
+-
+-	printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
+-	printk(KERN_DEBUG "TxStatus: %04x", s);
+-	printk(KERN_DEBUG "\n");
+-
+-	wlc_print_txs_status(s);
+-
+-	printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
+-	printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
+-	printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
+-	printk(KERN_DEBUG "RxAckRSSI: %04x ",
+-	       (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
+-	printk(KERN_DEBUG "RxAckSQ: %04x",
+-	       (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
+-	printk(KERN_DEBUG "\n");
+-#endif				/* defined(BCMDBG) */
+-}
+-
+-void wlc_statsupd(struct wlc_info *wlc)
+-{
+-	int i;
+-	macstat_t macstats;
+-#ifdef BCMDBG
+-	u16 delta;
+-	u16 rxf0ovfl;
+-	u16 txfunfl[NFIFO];
+-#endif				/* BCMDBG */
+-
+-	/* if driver down, make no sense to update stats */
+-	if (!wlc->pub->up)
+-		return;
+-
+-#ifdef BCMDBG
+-	/* save last rx fifo 0 overflow count */
+-	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
+-
+-	/* save last tx fifo  underflow count */
+-	for (i = 0; i < NFIFO; i++)
+-		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
+-#endif				/* BCMDBG */
+-
+-	/* Read mac stats from contiguous shared memory */
+-	wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
+-			      &macstats, sizeof(macstat_t));
+-
+-#ifdef BCMDBG
+-	/* check for rx fifo 0 overflow */
+-	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
+-	if (delta)
+-		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
+-			  wlc->pub->unit, delta);
+-
+-	/* check for tx fifo underflows */
+-	for (i = 0; i < NFIFO; i++) {
+-		delta =
+-		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
+-			      txfunfl[i]);
+-		if (delta)
+-			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
+-				  "\n", wlc->pub->unit, delta, i);
+-	}
+-#endif				/* BCMDBG */
+-
+-	/* merge counters from dma module */
+-	for (i = 0; i < NFIFO; i++) {
+-		if (wlc->hw->di[i]) {
+-			dma_counterreset(wlc->hw->di[i]);
+-		}
+-	}
+-}
+-
+-bool wlc_chipmatch(u16 vendor, u16 device)
+-{
+-	if (vendor != PCI_VENDOR_ID_BROADCOM) {
+-		pr_err("wlc_chipmatch: unknown vendor id %04x\n", vendor);
+-		return false;
+-	}
+-
+-	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
+-		return true;
+-
+-	if (device == BCM4313_D11N2G_ID)
+-		return true;
+-	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
+-		return true;
+-
+-	pr_err("wlc_chipmatch: unknown device id %04x\n", device);
+-	return false;
+-}
+-
+-#if defined(BCMDBG)
+-void wlc_print_txdesc(d11txh_t *txh)
+-{
+-	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
+-	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
+-	u16 mfc = le16_to_cpu(txh->MacFrameControl);
+-	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
+-	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
+-	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
+-	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
+-	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
+-	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
+-	u16 mainrates = le16_to_cpu(txh->MainRates);
+-	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
+-	u8 *iv = txh->IV;
+-	u8 *ra = txh->TxFrameRA;
+-	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
+-	u8 *rtspfb = txh->RTSPLCPFallback;
+-	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
+-	u8 *fragpfb = txh->FragPLCPFallback;
+-	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
+-	u16 mmodelen = le16_to_cpu(txh->MModeLen);
+-	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
+-	u16 tfid = le16_to_cpu(txh->TxFrameID);
+-	u16 txs = le16_to_cpu(txh->TxStatus);
+-	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
+-	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
+-	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
+-	u16 mmbyte = le16_to_cpu(txh->MinMBytes);
+-
+-	u8 *rtsph = txh->RTSPhyHeader;
+-	struct ieee80211_rts rts = txh->rts_frame;
+-	char hexbuf[256];
+-
+-	/* add plcp header along with txh descriptor */
+-	printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
+-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-			     txh, sizeof(d11txh_t) + 48);
+-
+-	printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
+-	printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
+-	printk(KERN_DEBUG "FC: %04x ", mfc);
+-	printk(KERN_DEBUG "FES Time: %04x\n", tfest);
+-	printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
+-	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
+-	printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
+-	printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
+-	printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
+-	printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
+-	printk(KERN_DEBUG "MainRates: %04x ", mainrates);
+-	printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
+-	printk(KERN_DEBUG "\n");
+-
+-	bcm_format_hex(hexbuf, iv, sizeof(txh->IV));
+-	printk(KERN_DEBUG "SecIV:       %s\n", hexbuf);
+-	bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
+-	printk(KERN_DEBUG "RA:          %s\n", hexbuf);
+-
+-	printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
+-	bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
+-	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
+-	printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
+-	bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
+-	printk(KERN_DEBUG "PLCP: %s ", hexbuf);
+-	printk(KERN_DEBUG "DUR: %04x", fragdfb);
+-	printk(KERN_DEBUG "\n");
+-
+-	printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
+-	printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
+-
+-	printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
+-	printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
+-
+-	printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
+-	printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
+-	printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
+-	printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
+-
+-	bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
+-	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
+-	bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
+-	printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
+-	printk(KERN_DEBUG "\n");
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-#if defined(BCMDBG)
+-void wlc_print_rxh(d11rxhdr_t *rxh)
+-{
+-	u16 len = rxh->RxFrameSize;
+-	u16 phystatus_0 = rxh->PhyRxStatus_0;
+-	u16 phystatus_1 = rxh->PhyRxStatus_1;
+-	u16 phystatus_2 = rxh->PhyRxStatus_2;
+-	u16 phystatus_3 = rxh->PhyRxStatus_3;
+-	u16 macstatus1 = rxh->RxStatus1;
+-	u16 macstatus2 = rxh->RxStatus2;
+-	char flagstr[64];
+-	char lenbuf[20];
+-	static const bcm_bit_desc_t macstat_flags[] = {
+-		{RXS_FCSERR, "FCSErr"},
+-		{RXS_RESPFRAMETX, "Reply"},
+-		{RXS_PBPRES, "PADDING"},
+-		{RXS_DECATMPT, "DeCr"},
+-		{RXS_DECERR, "DeCrErr"},
+-		{RXS_BCNSENT, "Bcn"},
+-		{0, NULL}
+-	};
+-
+-	printk(KERN_DEBUG "Raw RxDesc:\n");
+-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(d11rxhdr_t));
+-
+-	bcm_format_flags(macstat_flags, macstatus1, flagstr, 64);
+-
+-	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
+-
+-	printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
+-	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
+-	printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
+-	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
+-	printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
+-	printk(KERN_DEBUG "RXMACaggtype:    %x\n",
+-	       (macstatus2 & RXS_AGGTYPE_MASK));
+-	printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-#if defined(BCMDBG)
+-int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len)
+-{
+-	uint i, c;
+-	char *p = buf;
+-	char *endp = buf + SSID_FMT_BUF_LEN;
+-
+-	if (ssid_len > IEEE80211_MAX_SSID_LEN)
+-		ssid_len = IEEE80211_MAX_SSID_LEN;
+-
+-	for (i = 0; i < ssid_len; i++) {
+-		c = (uint) ssid[i];
+-		if (c == '\\') {
+-			*p++ = '\\';
+-			*p++ = '\\';
+-		} else if (isprint((unsigned char) c)) {
+-			*p++ = (char)c;
+-		} else {
+-			p += snprintf(p, (endp - p), "\\x%02X", c);
+-		}
+-	}
+-	*p = '\0';
+-	return (int)(p - buf);
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate)
+-{
+-	return wlc_bmac_rate_shm_offset(wlc->hw, rate);
+-}
+-
+-/* Callback for device removed */
+-
+-/*
+- * Attempts to queue a packet onto a multiple-precedence queue,
+- * if necessary evicting a lower precedence packet from the queue.
+- *
+- * 'prec' is the precedence number that has already been mapped
+- * from the packet priority.
+- *
+- * Returns true if packet consumed (queued), false if not.
+- */
+-bool
+-wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec)
+-{
+-	return wlc_prec_enq_head(wlc, q, pkt, prec, false);
+-}
+-
+-bool
+-wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt,
+-		  int prec, bool head)
+-{
+-	struct sk_buff *p;
+-	int eprec = -1;		/* precedence to evict from */
+-
+-	/* Determine precedence from which to evict packet, if any */
+-	if (pktq_pfull(q, prec))
+-		eprec = prec;
+-	else if (pktq_full(q)) {
+-		p = bcm_pktq_peek_tail(q, &eprec);
+-		if (eprec > prec) {
+-			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
+-				  "\n", __func__, eprec, prec);
+-			return false;
+-		}
+-	}
+-
+-	/* Evict if needed */
+-	if (eprec >= 0) {
+-		bool discard_oldest;
+-
+-		discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
+-
+-		/* Refuse newer packet unless configured to discard oldest */
+-		if (eprec == prec && !discard_oldest) {
+-			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
+-				  "\n", __func__, prec);
+-			return false;
+-		}
+-
+-		/* Evict packet according to discard policy */
+-		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+-			bcm_pktq_pdeq_tail(q, eprec);
+-		bcm_pkt_buf_free_skb(p);
+-	}
+-
+-	/* Enqueue */
+-	if (head)
+-		p = bcm_pktq_penq_head(q, prec, pkt);
+-	else
+-		p = bcm_pktq_penq(q, prec, pkt);
+-
+-	return true;
+-}
+-
+-void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
+-			     uint prec)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) ctx;
+-	struct wlc_txq_info *qi = wlc->pkt_queue;	/* Check me */
+-	struct pktq *q = &qi->q;
+-	int prio;
+-
+-	prio = sdu->priority;
+-
+-	if (!wlc_prec_enq(wlc, q, sdu, prec)) {
+-		if (!EDCF_ENAB(wlc->pub)
+-		    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_txq_enq: txq overflow"
+-				  "\n", wlc->pub->unit);
+-
+-		/*
+-		 * XXX we might hit this condtion in case
+-		 * packet flooding from mac80211 stack
+-		 */
+-		bcm_pkt_buf_free_skb(sdu);
+-	}
+-
+-	/* Check if flow control needs to be turned on after enqueuing the packet
+-	 *   Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
+-	 *   to drop instead of relying on stack to make the right decision
+-	 */
+-	if (!EDCF_ENAB(wlc->pub)
+-	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+-		if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
+-			wlc_txflowcontrol(wlc, qi, ON, ALLPRIO);
+-		}
+-	} else if (wlc->pub->_priofc) {
+-		if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
+-		    wlc->pub->tunables->datahiwat) {
+-			wlc_txflowcontrol(wlc, qi, ON, prio);
+-		}
+-	}
+-}
+-
+-bool
+-wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
+-		     struct ieee80211_hw *hw)
+-{
+-	u8 prio;
+-	uint fifo;
+-	void *pkt;
+-	struct scb *scb = &global_scb;
+-	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
+-
+-	/* 802.11 standard requires management traffic to go at highest priority */
+-	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
+-		MAXPRIO;
+-	fifo = prio2fifo[prio];
+-	pkt = sdu;
+-	if (unlikely
+-	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
+-		return -EINVAL;
+-	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
+-	wlc_send_q(wlc);
+-	return 0;
+-}
+-
+-void wlc_send_q(struct wlc_info *wlc)
+-{
+-	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
+-	int prec;
+-	u16 prec_map;
+-	int err = 0, i, count;
+-	uint fifo;
+-	struct wlc_txq_info *qi = wlc->pkt_queue;
+-	struct pktq *q = &qi->q;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	if (in_send_q)
+-		return;
+-	else
+-		in_send_q = true;
+-
+-	prec_map = wlc->tx_prec_map;
+-
+-	/* Send all the enq'd pkts that we can.
+-	 * Dequeue packets with precedence with empty HW fifo only
+-	 */
+-	while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) {
+-		tx_info = IEEE80211_SKB_CB(pkt[0]);
+-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-			err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec);
+-		} else {
+-			count = 1;
+-			err = wlc_prep_pdu(wlc, pkt[0], &fifo);
+-			if (!err) {
+-				for (i = 0; i < count; i++) {
+-					wlc_txfifo(wlc, fifo, pkt[i], true, 1);
+-				}
+-			}
+-		}
+-
+-		if (err == -EBUSY) {
+-			bcm_pktq_penq_head(q, prec, pkt[0]);
+-			/* If send failed due to any other reason than a change in
+-			 * HW FIFO condition, quit. Otherwise, read the new prec_map!
+-			 */
+-			if (prec_map == wlc->tx_prec_map)
+-				break;
+-			prec_map = wlc->tx_prec_map;
+-		}
+-	}
+-
+-	/* Check if flow control needs to be turned off after sending the packet */
+-	if (!EDCF_ENAB(wlc->pub)
+-	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+-		if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
+-		    && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
+-			wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO);
+-		}
+-	} else if (wlc->pub->_priofc) {
+-		int prio;
+-		for (prio = MAXPRIO; prio >= 0; prio--) {
+-			if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) &&
+-			    (pktq_plen(q, wlc_prio2prec_map[prio]) <
+-			     wlc->pub->tunables->datahiwat / 2)) {
+-				wlc_txflowcontrol(wlc, qi, OFF, prio);
+-			}
+-		}
+-	}
+-	in_send_q = false;
+-}
+-
+-/*
+- * bcmc_fid_generate:
+- * Generate frame ID for a BCMC packet.  The frag field is not used
+- * for MC frames so is used as part of the sequence number.
+- */
+-static inline u16
+-bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg,
+-		  d11txh_t *txh)
+-{
+-	u16 frameid;
+-
+-	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
+-						  TXFID_QUEUE_MASK);
+-	frameid |=
+-	    (((wlc->
+-	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+-	    TX_BCMC_FIFO;
+-
+-	return frameid;
+-}
+-
+-void
+-wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit,
+-	   s8 txpktpend)
+-{
+-	u16 frameid = INVALIDFID;
+-	d11txh_t *txh;
+-
+-	txh = (d11txh_t *) (p->data);
+-
+-	/* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
+-	 * ucode or BSS info as appropriate.
+-	 */
+-	if (fifo == TX_BCMC_FIFO) {
+-		frameid = le16_to_cpu(txh->TxFrameID);
+-
+-	}
+-
+-	if (WLC_WAR16165(wlc))
+-		wlc_war16165(wlc, true);
+-
+-
+-	/* Bump up pending count for if not using rpc. If rpc is used, this will be handled
+-	 * in wlc_bmac_txfifo()
+-	 */
+-	if (commit) {
+-		TXPKTPENDINC(wlc, fifo, txpktpend);
+-		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
+-			 txpktpend, TXPKTPENDGET(wlc, fifo));
+-	}
+-
+-	/* Commit BCMC sequence number in the SHM frame ID location */
+-	if (frameid != INVALIDFID)
+-		BCMCFID(wlc, frameid);
+-
+-	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
+-		wiphy_err(wlc->wiphy, "wlc_txfifo: fatal, toss frames !!!\n");
+-	}
+-}
+-
+-void
+-wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp)
+-{
+-	if (IS_MCS(rspec)) {
+-		wlc_compute_mimo_plcp(rspec, length, plcp);
+-	} else if (IS_OFDM(rspec)) {
+-		wlc_compute_ofdm_plcp(rspec, length, plcp);
+-	} else {
+-		wlc_compute_cck_plcp(wlc, rspec, length, plcp);
+-	}
+-	return;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
+-{
+-	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
+-	plcp[0] = mcs;
+-	if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
+-		plcp[0] |= MIMO_PLCP_40MHZ;
+-	WLC_SET_MIMO_PLCP_LEN(plcp, length);
+-	plcp[3] = RSPEC_MIMOPLCP3(rspec);	/* rspec already holds this byte */
+-	plcp[3] |= 0x7;		/* set smoothing, not sounding ppdu & reserved */
+-	plcp[4] = 0;		/* number of extension spatial streams bit 0 & 1 */
+-	plcp[5] = 0;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void
+-wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
+-{
+-	u8 rate_signal;
+-	u32 tmp = 0;
+-	int rate = RSPEC2RATE(rspec);
+-
+-	/* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
+-	rate_signal = rate_info[rate] & WLC_RATE_MASK;
+-	memset(plcp, 0, D11_PHY_HDR_LEN);
+-	D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal);
+-
+-	tmp = (length & 0xfff) << 5;
+-	plcp[2] |= (tmp >> 16) & 0xff;
+-	plcp[1] |= (tmp >> 8) & 0xff;
+-	plcp[0] |= tmp & 0xff;
+-
+-	return;
+-}
+-
+-/*
+- * Compute PLCP, but only requires actual rate and length of pkt.
+- * Rate is given in the driver standard multiple of 500 kbps.
+- * le is set for 11 Mbps rate if necessary.
+- * Broken out for PRQ.
+- */
+-
+-static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length,
+-			     u8 *plcp)
+-{
+-	u16 usec = 0;
+-	u8 le = 0;
+-
+-	switch (rate_500) {
+-	case WLC_RATE_1M:
+-		usec = length << 3;
+-		break;
+-	case WLC_RATE_2M:
+-		usec = length << 2;
+-		break;
+-	case WLC_RATE_5M5:
+-		usec = (length << 4) / 11;
+-		if ((length << 4) - (usec * 11) > 0)
+-			usec++;
+-		break;
+-	case WLC_RATE_11M:
+-		usec = (length << 3) / 11;
+-		if ((length << 3) - (usec * 11) > 0) {
+-			usec++;
+-			if ((usec * 11) - (length << 3) >= 8)
+-				le = D11B_PLCP_SIGNAL_LE;
+-		}
+-		break;
+-
+-	default:
+-		wiphy_err(wlc->wiphy, "wlc_cck_plcp_set: unsupported rate %d"
+-			  "\n", rate_500);
+-		rate_500 = WLC_RATE_1M;
+-		usec = length << 3;
+-		break;
+-	}
+-	/* PLCP signal byte */
+-	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
+-	/* PLCP service byte */
+-	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
+-	/* PLCP length u16, little endian */
+-	plcp[2] = usec & 0xff;
+-	plcp[3] = (usec >> 8) & 0xff;
+-	/* PLCP CRC16 */
+-	plcp[4] = 0;
+-	plcp[5] = 0;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec,
+-				 uint length, u8 *plcp)
+-{
+-	int rate = RSPEC2RATE(rspec);
+-
+-	wlc_cck_plcp_set(wlc, rate, length, plcp);
+-}
+-
+-/* wlc_compute_frame_dur()
+- *
+- * Calculate the 802.11 MAC header DUR field for MPDU
+- * DUR for a single frame = 1 SIFS + 1 ACK
+- * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
+- *
+- * rate			MPDU rate in unit of 500kbps
+- * next_frag_len	next MPDU length in bytes
+- * preamble_type	use short/GF or long/MM PLCP header
+- */
+-static u16
+-wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type,
+-		      uint next_frag_len)
+-{
+-	u16 dur, sifs;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	dur = sifs;
+-	dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type);
+-
+-	if (next_frag_len) {
+-		/* Double the current DUR to get 2 SIFS + 2 ACKs */
+-		dur *= 2;
+-		/* add another SIFS and the frag time */
+-		dur += sifs;
+-		dur +=
+-		    (u16) wlc_calc_frame_time(wlc, rate, preamble_type,
+-						 next_frag_len);
+-	}
+-	return dur;
+-}
+-
+-/* wlc_compute_rtscts_dur()
+- *
+- * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
+- * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
+- * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
+- *
+- * cts			cts-to-self or rts/cts
+- * rts_rate		rts or cts rate in unit of 500kbps
+- * rate			next MPDU rate in unit of 500kbps
+- * frame_len		next MPDU frame length in bytes
+- */
+-u16
+-wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate,
+-		       ratespec_t frame_rate, u8 rts_preamble_type,
+-		       u8 frame_preamble_type, uint frame_len, bool ba)
+-{
+-	u16 dur, sifs;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	if (!cts_only) {	/* RTS/CTS */
+-		dur = 3 * sifs;
+-		dur +=
+-		    (u16) wlc_calc_cts_time(wlc, rts_rate,
+-					       rts_preamble_type);
+-	} else {		/* CTS-TO-SELF */
+-		dur = 2 * sifs;
+-	}
+-
+-	dur +=
+-	    (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type,
+-					 frame_len);
+-	if (ba)
+-		dur +=
+-		    (u16) wlc_calc_ba_time(wlc, frame_rate,
+-					      WLC_SHORT_PREAMBLE);
+-	else
+-		dur +=
+-		    (u16) wlc_calc_ack_time(wlc, frame_rate,
+-					       frame_preamble_type);
+-	return dur;
+-}
+-
+-u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phyctl1 = 0;
+-	u16 bw;
+-
+-	if (WLCISLCNPHY(wlc->band)) {
+-		bw = PHY_TXC1_BW_20MHZ;
+-	} else {
+-		bw = RSPEC_GET_BW(rspec);
+-		/* 10Mhz is not supported yet */
+-		if (bw < PHY_TXC1_BW_20MHZ) {
+-			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: bw %d is "
+-				  "not supported yet, set to 20L\n", bw);
+-			bw = PHY_TXC1_BW_20MHZ;
+-		}
+-	}
+-
+-	if (IS_MCS(rspec)) {
+-		uint mcs = rspec & RSPEC_RATE_MASK;
+-
+-		/* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
+-		phyctl1 = RSPEC_PHYTXBYTE2(rspec);
+-		/* set the upper byte of phyctl1 */
+-		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
+-	} else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band)
+-		   && !WLCISSSLPNPHY(wlc->band)) {
+-		/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+-		/* Eventually MIMOPHY would also be converted to this format */
+-		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+-		phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+-	} else {		/* legacy OFDM/CCK */
+-		s16 phycfg;
+-		/* get the phyctl byte from rate phycfg table */
+-		phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec));
+-		if (phycfg == -1) {
+-			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: wrong "
+-				  "legacy OFDM/CCK rate\n");
+-			phycfg = 0;
+-		}
+-		/* set the upper byte of phyctl1 */
+-		phyctl1 =
+-		    (bw | (phycfg << 8) |
+-		     (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+-	}
+-	return phyctl1;
+-}
+-
+-ratespec_t
+-wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec,
+-		       u16 mimo_ctlchbw)
+-{
+-	ratespec_t rts_rspec = 0;
+-
+-	if (use_rspec) {
+-		/* use frame rate as rts rate */
+-		rts_rspec = rspec;
+-
+-	} else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
+-		/* Use 11Mbps as the g protection RTS target rate and fallback.
+-		 * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the
+-		 * target in case 11 Mbps is not Basic.
+-		 * 6 and 9 Mbps are not usually selected by rate selection, but even
+-		 * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
+-		 */
+-		rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M);
+-	} else {
+-		/* calculate RTS rate and fallback rate based on the frame rate
+-		 * RTS must be sent at a basic rate since it is a
+-		 * control frame, sec 9.6 of 802.11 spec
+-		 */
+-		rts_rspec = WLC_BASIC_RATE(wlc, rspec);
+-	}
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		/* set rts txbw to correct side band */
+-		rts_rspec &= ~RSPEC_BW_MASK;
+-
+-		/* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
+-		 * (DUP), otherwise send RTS on control channel
+-		 */
+-		if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
+-			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
+-		else
+-			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+-
+-		/* pick siso/cdd as default for ofdm */
+-		if (IS_OFDM(rts_rspec)) {
+-			rts_rspec &= ~RSPEC_STF_MASK;
+-			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+-		}
+-	}
+-	return rts_rspec;
+-}
+-
+-/*
+- * Add d11txh_t, cck_phy_hdr_t.
+- *
+- * 'p' data must start with 802.11 MAC header
+- * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
+- *
+- * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
+- *
+- */
+-static u16
+-wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw,
+-		     struct sk_buff *p, struct scb *scb, uint frag,
+-		     uint nfrags, uint queue, uint next_frag_len,
+-		     wsec_key_t *key, ratespec_t rspec_override)
+-{
+-	struct ieee80211_hdr *h;
+-	d11txh_t *txh;
+-	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
+-	int len, phylen, rts_phylen;
+-	u16 mch, phyctl, xfts, mainrates;
+-	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
+-	ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = {
+-	WLC_RATE_1M, WLC_RATE_1M};
+-	bool use_rts = false;
+-	bool use_cts = false;
+-	bool use_rifs = false;
+-	bool short_preamble[2] = { false, false };
+-	u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+-	u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+-	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
+-	struct ieee80211_rts *rts = NULL;
+-	bool qos;
+-	uint ac;
+-	u32 rate_val[2];
+-	bool hwtkmic = false;
+-	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+-#define ANTCFG_NONE 0xFF
+-	u8 antcfg = ANTCFG_NONE;
+-	u8 fbantcfg = ANTCFG_NONE;
+-	uint phyctl1_stf = 0;
+-	u16 durid = 0;
+-	struct ieee80211_tx_rate *txrate[2];
+-	int k;
+-	struct ieee80211_tx_info *tx_info;
+-	bool is_mcs[2];
+-	u16 mimo_txbw;
+-	u8 mimo_preamble_type;
+-
+-	/* locate 802.11 MAC header */
+-	h = (struct ieee80211_hdr *)(p->data);
+-	qos = ieee80211_is_data_qos(h->frame_control);
+-
+-	/* compute length of frame in bytes for use in PLCP computations */
+-	len = bcm_pkttotlen(p);
+-	phylen = len + FCS_LEN;
+-
+-	/* If WEP enabled, add room in phylen for the additional bytes of
+-	 * ICV which MAC generates.  We do NOT add the additional bytes to
+-	 * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
+-	 * in this case
+-	 */
+-	if (key) {
+-		phylen += key->icv_len;
+-	}
+-
+-	/* Get tx_info */
+-	tx_info = IEEE80211_SKB_CB(p);
+-
+-	/* add PLCP */
+-	plcp = skb_push(p, D11_PHY_HDR_LEN);
+-
+-	/* add Broadcom tx descriptor header */
+-	txh = (d11txh_t *) skb_push(p, D11_TXH_LEN);
+-	memset(txh, 0, D11_TXH_LEN);
+-
+-	/* setup frameid */
+-	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+-		/* non-AP STA should never use BCMC queue */
+-		if (queue == TX_BCMC_FIFO) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
+-				  "TX_BCMC!\n", WLCWLUNIT(wlc), __func__);
+-			frameid = bcmc_fid_generate(wlc, NULL, txh);
+-		} else {
+-			/* Increment the counter for first fragment */
+-			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+-				SCB_SEQNUM(scb, p->priority)++;
+-			}
+-
+-			/* extract fragment number from frame first */
+-			seq = le16_to_cpu(seq) & FRAGNUM_MASK;
+-			seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT);
+-			h->seq_ctrl = cpu_to_le16(seq);
+-
+-			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+-			    (queue & TXFID_QUEUE_MASK);
+-		}
+-	}
+-	frameid |= queue & TXFID_QUEUE_MASK;
+-
+-	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
+-	if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
+-		mcl |= TXC_IGNOREPMQ;
+-
+-	txrate[0] = tx_info->control.rates;
+-	txrate[1] = txrate[0] + 1;
+-
+-	/* if rate control algorithm didn't give us a fallback rate, use the primary rate */
+-	if (txrate[1]->idx < 0) {
+-		txrate[1] = txrate[0];
+-	}
+-
+-	for (k = 0; k < hw->max_rates; k++) {
+-		is_mcs[k] =
+-		    txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
+-		if (!is_mcs[k]) {
+-			if ((txrate[k]->idx >= 0)
+-			    && (txrate[k]->idx <
+-				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
+-				rate_val[k] =
+-				    hw->wiphy->bands[tx_info->band]->
+-				    bitrates[txrate[k]->idx].hw_value;
+-				short_preamble[k] =
+-				    txrate[k]->
+-				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
+-				    true : false;
+-			} else {
+-				rate_val[k] = WLC_RATE_1M;
+-			}
+-		} else {
+-			rate_val[k] = txrate[k]->idx;
+-		}
+-		/* Currently only support same setting for primay and fallback rates.
+-		 * Unify flags for each rate into a single value for the frame
+-		 */
+-		use_rts |=
+-		    txrate[k]->
+-		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
+-		use_cts |=
+-		    txrate[k]->
+-		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
+-
+-		if (is_mcs[k])
+-			rate_val[k] |= NRATE_MCS_INUSE;
+-
+-		rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);
+-
+-		/* (1) RATE: determine and validate primary rate and fallback rates */
+-		if (!RSPEC_ACTIVE(rspec[k])) {
+-			rspec[k] = WLC_RATE_1M;
+-		} else {
+-			if (!is_multicast_ether_addr(h->addr1)) {
+-				/* set tx antenna config */
+-				wlc_antsel_antcfg_get(wlc->asi, false, false, 0,
+-						      0, &antcfg, &fbantcfg);
+-			}
+-		}
+-	}
+-
+-	phyctl1_stf = wlc->stf->ss_opmode;
+-
+-	if (N_ENAB(wlc->pub)) {
+-		for (k = 0; k < hw->max_rates; k++) {
+-			/* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
+-			if (((IS_MCS(rspec[k]) &&
+-			      IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
+-			     IS_OFDM(rspec[k]))
+-			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
+-				|| !(rspec[k] & RSPEC_OVERRIDE))) {
+-				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
+-
+-				/* For SISO MCS use STBC if possible */
+-				if (IS_MCS(rspec[k])
+-				    && WLC_STF_SS_STBC_TX(wlc, scb)) {
+-					u8 stc;
+-
+-					stc = 1;	/* Nss for single stream is always 1 */
+-					rspec[k] |=
+-					    (PHY_TXC1_MODE_STBC <<
+-					     RSPEC_STF_SHIFT) | (stc <<
+-								 RSPEC_STC_SHIFT);
+-				} else
+-					rspec[k] |=
+-					    (phyctl1_stf << RSPEC_STF_SHIFT);
+-			}
+-
+-			/* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
+-			if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) {
+-				/* default txbw is 20in40 SB */
+-				mimo_ctlchbw = mimo_txbw =
+-				    CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+-				    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+-
+-				if (IS_MCS(rspec[k])) {
+-					/* mcs 32 must be 40b/w DUP */
+-					if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+-						mimo_txbw =
+-						    PHY_TXC1_BW_40MHZ_DUP;
+-						/* use override */
+-					} else if (wlc->mimo_40txbw != AUTO)
+-						mimo_txbw = wlc->mimo_40txbw;
+-					/* else check if dst is using 40 Mhz */
+-					else if (scb->flags & SCB_IS40)
+-						mimo_txbw = PHY_TXC1_BW_40MHZ;
+-				} else if (IS_OFDM(rspec[k])) {
+-					if (wlc->ofdm_40txbw != AUTO)
+-						mimo_txbw = wlc->ofdm_40txbw;
+-				} else {
+-					if (wlc->cck_40txbw != AUTO)
+-						mimo_txbw = wlc->cck_40txbw;
+-				}
+-			} else {
+-				/* mcs32 is 40 b/w only.
+-				 * This is possible for probe packets on a STA during SCAN
+-				 */
+-				if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+-					/* mcs 0 */
+-					rspec[k] = RSPEC_MIMORATE;
+-				}
+-				mimo_txbw = PHY_TXC1_BW_20MHZ;
+-			}
+-
+-			/* Set channel width */
+-			rspec[k] &= ~RSPEC_BW_MASK;
+-			if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
+-				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
+-			else
+-				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+-
+-			/* Set Short GI */
+-#ifdef NOSGIYET
+-			if (IS_MCS(rspec[k])
+-			    && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+-				rspec[k] |= RSPEC_SHORT_GI;
+-			else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+-				rspec[k] &= ~RSPEC_SHORT_GI;
+-#else
+-			rspec[k] &= ~RSPEC_SHORT_GI;
+-#endif
+-
+-			mimo_preamble_type = WLC_MM_PREAMBLE;
+-			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
+-				mimo_preamble_type = WLC_GF_PREAMBLE;
+-
+-			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
+-			    && (!IS_MCS(rspec[k]))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
+-					  "RC_MCS != IS_MCS(rspec)\n",
+-					  WLCWLUNIT(wlc), __func__);
+-			}
+-
+-			if (IS_MCS(rspec[k])) {
+-				preamble_type[k] = mimo_preamble_type;
+-
+-				/* if SGI is selected, then forced mm for single stream */
+-				if ((rspec[k] & RSPEC_SHORT_GI)
+-				    && IS_SINGLE_STREAM(rspec[k] &
+-							RSPEC_RATE_MASK)) {
+-					preamble_type[k] = WLC_MM_PREAMBLE;
+-				}
+-			}
+-
+-			/* should be better conditionalized */
+-			if (!IS_MCS(rspec[0])
+-			    && (tx_info->control.rates[0].
+-				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
+-				preamble_type[k] = WLC_SHORT_PREAMBLE;
+-		}
+-	} else {
+-		for (k = 0; k < hw->max_rates; k++) {
+-			/* Set ctrlchbw as 20Mhz */
+-			rspec[k] &= ~RSPEC_BW_MASK;
+-			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
+-
+-			/* for nphy, stf of ofdm frames must follow policies */
+-			if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
+-				rspec[k] &= ~RSPEC_STF_MASK;
+-				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
+-			}
+-		}
+-	}
+-
+-	/* Reset these for use with AMPDU's */
+-	txrate[0]->count = 0;
+-	txrate[1]->count = 0;
+-
+-	/* (2) PROTECTION, may change rspec */
+-	if ((ieee80211_is_data(h->frame_control) ||
+-	    ieee80211_is_mgmt(h->frame_control)) &&
+-	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
+-		use_rts = true;
+-
+-	/* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */
+-	wlc_compute_plcp(wlc, rspec[0], phylen, plcp);
+-	wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
+-	memcpy(&txh->FragPLCPFallback,
+-	       plcp_fallback, sizeof(txh->FragPLCPFallback));
+-
+-	/* Length field now put in CCK FBR CRC field */
+-	if (IS_CCK(rspec[1])) {
+-		txh->FragPLCPFallback[4] = phylen & 0xff;
+-		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
+-	}
+-
+-	/* MIMO-RATE: need validation ?? */
+-	mainrates =
+-	    IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) :
+-	    plcp[0];
+-
+-	/* DUR field for main rate */
+-	if (!ieee80211_is_pspoll(h->frame_control) &&
+-	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
+-		durid =
+-		    wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0],
+-					  next_frag_len);
+-		h->duration_id = cpu_to_le16(durid);
+-	} else if (use_rifs) {
+-		/* NAV protect to end of next max packet size */
+-		durid =
+-		    (u16) wlc_calc_frame_time(wlc, rspec[0],
+-						 preamble_type[0],
+-						 DOT11_MAX_FRAG_LEN);
+-		durid += RIFS_11N_TIME;
+-		h->duration_id = cpu_to_le16(durid);
+-	}
+-
+-	/* DUR field for fallback rate */
+-	if (ieee80211_is_pspoll(h->frame_control))
+-		txh->FragDurFallback = h->duration_id;
+-	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
+-		txh->FragDurFallback = 0;
+-	else {
+-		durid = wlc_compute_frame_dur(wlc, rspec[1],
+-					      preamble_type[1], next_frag_len);
+-		txh->FragDurFallback = cpu_to_le16(durid);
+-	}
+-
+-	/* (4) MAC-HDR: MacTxControlLow */
+-	if (frag == 0)
+-		mcl |= TXC_STARTMSDU;
+-
+-	if (!is_multicast_ether_addr(h->addr1))
+-		mcl |= TXC_IMMEDACK;
+-
+-	if (BAND_5G(wlc->band->bandtype))
+-		mcl |= TXC_FREQBAND_5G;
+-
+-	if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC))
+-		mcl |= TXC_BW_40;
+-
+-	/* set AMIC bit if using hardware TKIP MIC */
+-	if (hwtkmic)
+-		mcl |= TXC_AMIC;
+-
+-	txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-	/* MacTxControlHigh */
+-	mch = 0;
+-
+-	/* Set fallback rate preamble type */
+-	if ((preamble_type[1] == WLC_SHORT_PREAMBLE) ||
+-	    (preamble_type[1] == WLC_GF_PREAMBLE)) {
+-		if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M)
+-			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
+-	}
+-
+-	/* MacFrameControl */
+-	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
+-	txh->TxFesTimeNormal = cpu_to_le16(0);
+-
+-	txh->TxFesTimeFallback = cpu_to_le16(0);
+-
+-	/* TxFrameRA */
+-	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
+-
+-	/* TxFrameID */
+-	txh->TxFrameID = cpu_to_le16(frameid);
+-
+-	/* TxStatus, Note the case of recreating the first frag of a suppressed frame
+-	 * then we may need to reset the retry cnt's via the status reg
+-	 */
+-	txh->TxStatus = cpu_to_le16(status);
+-
+-	/* extra fields for ucode AMPDU aggregation, the new fields are added to
+-	 * the END of previous structure so that it's compatible in driver.
+-	 */
+-	txh->MaxNMpdus = cpu_to_le16(0);
+-	txh->MaxABytes_MRT = cpu_to_le16(0);
+-	txh->MaxABytes_FBR = cpu_to_le16(0);
+-	txh->MinMBytes = cpu_to_le16(0);
+-
+-	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */
+-	/* RTS PLCP header and RTS frame */
+-	if (use_rts || use_cts) {
+-		if (use_rts && use_cts)
+-			use_cts = false;
+-
+-		for (k = 0; k < 2; k++) {
+-			rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k],
+-							      false,
+-							      mimo_ctlchbw);
+-		}
+-
+-		if (!IS_OFDM(rts_rspec[0]) &&
+-		    !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) ||
+-		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+-			rts_preamble_type[0] = WLC_SHORT_PREAMBLE;
+-			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
+-		}
+-
+-		if (!IS_OFDM(rts_rspec[1]) &&
+-		    !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) ||
+-		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+-			rts_preamble_type[1] = WLC_SHORT_PREAMBLE;
+-			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
+-		}
+-
+-		/* RTS/CTS additions to MacTxControlLow */
+-		if (use_cts) {
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
+-		} else {
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
+-		}
+-
+-		/* RTS PLCP header */
+-		rts_plcp = txh->RTSPhyHeader;
+-		if (use_cts)
+-			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
+-		else
+-			rts_phylen = DOT11_RTS_LEN + FCS_LEN;
+-
+-		wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
+-
+-		/* fallback rate version of RTS PLCP header */
+-		wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen,
+-				 rts_plcp_fallback);
+-		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
+-		       sizeof(txh->RTSPLCPFallback));
+-
+-		/* RTS frame fields... */
+-		rts = (struct ieee80211_rts *)&txh->rts_frame;
+-
+-		durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
+-					       rspec[0], rts_preamble_type[0],
+-					       preamble_type[0], phylen, false);
+-		rts->duration = cpu_to_le16(durid);
+-		/* fallback rate version of RTS DUR field */
+-		durid = wlc_compute_rtscts_dur(wlc, use_cts,
+-					       rts_rspec[1], rspec[1],
+-					       rts_preamble_type[1],
+-					       preamble_type[1], phylen, false);
+-		txh->RTSDurFallback = cpu_to_le16(durid);
+-
+-		if (use_cts) {
+-			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+-							 IEEE80211_STYPE_CTS);
+-
+-			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
+-		} else {
+-			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+-							 IEEE80211_STYPE_RTS);
+-
+-			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
+-		}
+-
+-		/* mainrate
+-		 *    low 8 bits: main frag rate/mcs,
+-		 *    high 8 bits: rts/cts rate/mcs
+-		 */
+-		mainrates |= (IS_OFDM(rts_rspec[0]) ?
+-			      D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) :
+-			      rts_plcp[0]) << 8;
+-	} else {
+-		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
+-		memset((char *)&txh->rts_frame, 0,
+-			sizeof(struct ieee80211_rts));
+-		memset((char *)txh->RTSPLCPFallback, 0,
+-		      sizeof(txh->RTSPLCPFallback));
+-		txh->RTSDurFallback = 0;
+-	}
+-
+-#ifdef SUPPORT_40MHZ
+-	/* add null delimiter count */
+-	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
+-		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
+-		    wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
+-	}
+-#endif
+-
+-	/* Now that RTS/RTS FB preamble types are updated, write the final value */
+-	txh->MacTxControlHigh = cpu_to_le16(mch);
+-
+-	/* MainRates (both the rts and frag plcp rates have been calculated now) */
+-	txh->MainRates = cpu_to_le16(mainrates);
+-
+-	/* XtraFrameTypes */
+-	xfts = FRAMETYPE(rspec[1], wlc->mimoft);
+-	xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
+-	xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
+-	xfts |=
+-	    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
+-	txh->XtraFrameTypes = cpu_to_le16(xfts);
+-
+-	/* PhyTxControlWord */
+-	phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
+-	if ((preamble_type[0] == WLC_SHORT_PREAMBLE) ||
+-	    (preamble_type[0] == WLC_GF_PREAMBLE)) {
+-		if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
+-			phyctl |= PHY_TXC_SHORT_HDR;
+-	}
+-
+-	/* phytxant is properly bit shifted */
+-	phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
+-	txh->PhyTxControlWord = cpu_to_le16(phyctl);
+-
+-	/* PhyTxControlWord_1 */
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		u16 phyctl1 = 0;
+-
+-		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]);
+-		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
+-		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]);
+-		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
+-
+-		if (use_rts || use_cts) {
+-			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]);
+-			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
+-			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]);
+-			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
+-		}
+-
+-		/*
+-		 * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
+-		 * fill in non-zero MModeLen and/or MModeFbrLen
+-		 *  it will be unnecessary if they are separated
+-		 */
+-		if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) {
+-			u16 mmodelen =
+-			    wlc_calc_lsig_len(wlc, rspec[0], phylen);
+-			txh->MModeLen = cpu_to_le16(mmodelen);
+-		}
+-
+-		if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) {
+-			u16 mmodefbrlen =
+-			    wlc_calc_lsig_len(wlc, rspec[1], phylen);
+-			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
+-		}
+-	}
+-
+-	ac = skb_get_queue_mapping(p);
+-	if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
+-		uint frag_dur, dur, dur_fallback;
+-
+-		/* WME: Update TXOP threshold */
+-		if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
+-			frag_dur =
+-			    wlc_calc_frame_time(wlc, rspec[0], preamble_type[0],
+-						phylen);
+-
+-			if (rts) {
+-				/* 1 RTS or CTS-to-self frame */
+-				dur =
+-				    wlc_calc_cts_time(wlc, rts_rspec[0],
+-						      rts_preamble_type[0]);
+-				dur_fallback =
+-				    wlc_calc_cts_time(wlc, rts_rspec[1],
+-						      rts_preamble_type[1]);
+-				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
+-				dur += le16_to_cpu(rts->duration);
+-				dur_fallback +=
+-					le16_to_cpu(txh->RTSDurFallback);
+-			} else if (use_rifs) {
+-				dur = frag_dur;
+-				dur_fallback = 0;
+-			} else {
+-				/* frame + SIFS + ACK */
+-				dur = frag_dur;
+-				dur +=
+-				    wlc_compute_frame_dur(wlc, rspec[0],
+-							  preamble_type[0], 0);
+-
+-				dur_fallback =
+-				    wlc_calc_frame_time(wlc, rspec[1],
+-							preamble_type[1],
+-							phylen);
+-				dur_fallback +=
+-				    wlc_compute_frame_dur(wlc, rspec[1],
+-							  preamble_type[1], 0);
+-			}
+-			/* NEED to set TxFesTimeNormal (hard) */
+-			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
+-			/* NEED to set fallback rate version of TxFesTimeNormal (hard) */
+-			txh->TxFesTimeFallback =
+-				cpu_to_le16((u16) dur_fallback);
+-
+-			/* update txop byte threshold (txop minus intraframe overhead) */
+-			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
+-				{
+-					uint newfragthresh;
+-
+-					newfragthresh =
+-					    wlc_calc_frame_len(wlc, rspec[0],
+-							       preamble_type[0],
+-							       (wlc->
+-								edcf_txop[ac] -
+-								(dur -
+-								 frag_dur)));
+-					/* range bound the fragthreshold */
+-					if (newfragthresh < DOT11_MIN_FRAG_LEN)
+-						newfragthresh =
+-						    DOT11_MIN_FRAG_LEN;
+-					else if (newfragthresh >
+-						 wlc->usr_fragthresh)
+-						newfragthresh =
+-						    wlc->usr_fragthresh;
+-					/* update the fragthresh and do txc update */
+-					if (wlc->fragthresh[queue] !=
+-					    (u16) newfragthresh) {
+-						wlc->fragthresh[queue] =
+-						    (u16) newfragthresh;
+-					}
+-				}
+-			} else
+-				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
+-					  "for rate %d\n",
+-					  wlc->pub->unit, fifo_names[queue],
+-					  RSPEC2RATE(rspec[0]));
+-
+-			if (dur > wlc->edcf_txop[ac])
+-				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
+-					  "exceeded phylen %d/%d dur %d/%d\n",
+-					  wlc->pub->unit, __func__,
+-					  fifo_names[queue],
+-					  phylen, wlc->fragthresh[queue],
+-					  dur, wlc->edcf_txop[ac]);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs)
+-{
+-	struct wlc_bsscfg *cfg = wlc->cfg;
+-
+-	if (BSSCFG_STA(cfg)) {
+-		/* run watchdog here if the watchdog timer is not armed */
+-		if (WLC_WATCHDOG_TBTT(wlc)) {
+-			u32 cur, delta;
+-			if (wlc->WDarmed) {
+-				wl_del_timer(wlc->wl, wlc->wdtimer);
+-				wlc->WDarmed = false;
+-			}
+-
+-			cur = OSL_SYSUPTIME();
+-			delta = cur > wlc->WDlast ? cur - wlc->WDlast :
+-			    (u32) ~0 - wlc->WDlast + cur + 1;
+-			if (delta >= TIMER_INTERVAL_WATCHDOG) {
+-				wlc_watchdog((void *)wlc);
+-				wlc->WDlast = cur;
+-			}
+-
+-			wl_add_timer(wlc->wl, wlc->wdtimer,
+-				     wlc_watchdog_backup_bi(wlc), true);
+-			wlc->WDarmed = true;
+-		}
+-	}
+-
+-	if (!cfg->BSS) {
+-		/* DirFrmQ is now valid...defer setting until end of ATIM window */
+-		wlc->qvalid |= MCMD_DIRFRMQVAL;
+-	}
+-}
+-
+-static void wlc_war16165(struct wlc_info *wlc, bool tx)
+-{
+-	if (tx) {
+-		/* the post-increment is used in STAY_AWAKE macro */
+-		if (wlc->txpend16165war++ == 0)
+-			wlc_set_ps_ctrl(wlc);
+-	} else {
+-		wlc->txpend16165war--;
+-		if (wlc->txpend16165war == 0)
+-			wlc_set_ps_ctrl(wlc);
+-	}
+-}
+-
+-/* process an individual tx_status_t */
+-/* WLC_HIGH_API */
+-bool
+-wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
+-{
+-	struct sk_buff *p;
+-	uint queue;
+-	d11txh_t *txh;
+-	struct scb *scb = NULL;
+-	bool free_pdu;
+-	int tx_rts, tx_frame_count, tx_rts_count;
+-	uint totlen, supr_status;
+-	bool lastframe;
+-	struct ieee80211_hdr *h;
+-	u16 mcl;
+-	struct ieee80211_tx_info *tx_info;
+-	struct ieee80211_tx_rate *txrate;
+-	int i;
+-
+-	(void)(frm_tx2);	/* Compiler reference to avoid unused variable warning */
+-
+-	/* discard intermediate indications for ucode with one legitimate case:
+-	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+-	 *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+-	 *   transmission count)
+-	 */
+-	if (!(txs->status & TX_STATUS_AMPDU)
+-	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
+-		wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
+-			  __func__);
+-		return false;
+-	}
+-
+-	queue = txs->frameid & TXFID_QUEUE_MASK;
+-	if (queue >= NFIFO) {
+-		p = NULL;
+-		goto fatal;
+-	}
+-
+-	p = GETNEXTTXP(wlc, queue);
+-	if (WLC_WAR16165(wlc))
+-		wlc_war16165(wlc, false);
+-	if (p == NULL)
+-		goto fatal;
+-
+-	txh = (d11txh_t *) (p->data);
+-	mcl = le16_to_cpu(txh->MacTxControlLow);
+-
+-	if (txs->phyerr) {
+-		if (WL_ERROR_ON()) {
+-			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
+-				  txs->phyerr, txh->MainRates);
+-			wlc_print_txdesc(txh);
+-		}
+-		wlc_print_txstatus(txs);
+-	}
+-
+-	if (txs->frameid != cpu_to_le16(txh->TxFrameID))
+-		goto fatal;
+-	tx_info = IEEE80211_SKB_CB(p);
+-	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
+-
+-	if (tx_info->control.sta)
+-		scb = (struct scb *)tx_info->control.sta->drv_priv;
+-
+-	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-		wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
+-		return false;
+-	}
+-
+-	supr_status = txs->status & TX_STATUS_SUPR_MASK;
+-	if (supr_status == TX_STATUS_SUPR_BADCH)
+-		BCMMSG(wlc->wiphy,
+-		       "%s: Pkt tx suppressed, possibly channel %d\n",
+-		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+-
+-	tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
+-	tx_frame_count =
+-	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
+-	tx_rts_count =
+-	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
+-
+-	lastframe = !ieee80211_has_morefrags(h->frame_control);
+-
+-	if (!lastframe) {
+-		wiphy_err(wlc->wiphy, "Not last frame!\n");
+-	} else {
+-		u16 sfbl, lfbl;
+-		ieee80211_tx_info_clear_status(tx_info);
+-		if (queue < AC_COUNT) {
+-			sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
+-			lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
+-		} else {
+-			sfbl = wlc->SFBL;
+-			lfbl = wlc->LFBL;
+-		}
+-
+-		txrate = tx_info->status.rates;
+-		/* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */
+-		if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) {
+-			/* rate selection requested a fallback rate and we used it */
+-			txrate->count = lfbl;
+-			txrate[1].count = tx_frame_count - lfbl;
+-		} else {
+-			/* rate selection did not request fallback rate, or we didn't need it */
+-			txrate->count = tx_frame_count;
+-			/* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
+-			txrate[1].idx = -1;
+-			txrate[1].count = 0;
+-		}
+-
+-		/* clear the rest of the rates */
+-		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+-			txrate[i].idx = -1;
+-			txrate[i].count = 0;
+-		}
+-
+-		if (txs->status & TX_STATUS_ACK_RCV)
+-			tx_info->flags |= IEEE80211_TX_STAT_ACK;
+-	}
+-
+-	totlen = bcm_pkttotlen(p);
+-	free_pdu = true;
+-
+-	wlc_txfifo_complete(wlc, queue, 1);
+-
+-	if (lastframe) {
+-		p->next = NULL;
+-		p->prev = NULL;
+-		wlc->txretried = 0;
+-		/* remove PLCP & Broadcom tx descriptor header */
+-		skb_pull(p, D11_PHY_HDR_LEN);
+-		skb_pull(p, D11_TXH_LEN);
+-		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
+-	} else {
+-		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
+-			  "tx_status\n", __func__);
+-	}
+-
+-	return false;
+-
+- fatal:
+-	if (p)
+-		bcm_pkt_buf_free_skb(p);
+-
+-	return true;
+-
+-}
+-
+-void
+-wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend)
+-{
+-	TXPKTPENDDEC(wlc, fifo, txpktpend);
+-	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
+-		TXPKTPENDGET(wlc, fifo));
+-
+-	/* There is more room; mark precedences related to this FIFO sendable */
+-	WLC_TX_FIFO_ENAB(wlc, fifo);
+-
+-	if (!TXPKTPENDTOT(wlc)) {
+-		if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR)
+-			wlc_bsscfg_tx_check(wlc);
+-	}
+-
+-	/* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
+-	if (AP_ENAB(wlc->pub) &&
+-	    wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
+-		wlc->bcmcfifo_drain = false;
+-		wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO);
+-	}
+-
+-	/* figure out which bsscfg is being worked on... */
+-}
+-
+-/* Update beacon listen interval in shared memory */
+-void wlc_bcn_li_upd(struct wlc_info *wlc)
+-{
+-	if (AP_ENAB(wlc->pub))
+-		return;
+-
+-	/* wake up every DTIM is the default */
+-	if (wlc->bcn_li_dtim == 1)
+-		wlc_write_shm(wlc, M_BCN_LI, 0);
+-	else
+-		wlc_write_shm(wlc, M_BCN_LI,
+-			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
+-}
+-
+-/*
+- * recover 64bit TSF value from the 16bit TSF value in the rx header
+- * given the assumption that the TSF passed in header is within 65ms
+- * of the current tsf.
+- *
+- * 6       5       4       4       3       2       1
+- * 3.......6.......8.......0.......2.......4.......6.......8......0
+- * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
+- *
+- * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
+- * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the
+- * receive call sequence after rx interrupt. Only the higher 16 bits
+- * are used. Finally, the tsf_h is read from the tsf register.
+- */
+-static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh)
+-{
+-	u32 tsf_h, tsf_l;
+-	u16 rx_tsf_0_15, rx_tsf_16_31;
+-
+-	wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h);
+-
+-	rx_tsf_16_31 = (u16)(tsf_l >> 16);
+-	rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
+-
+-	/*
+-	 * a greater tsf time indicates the low 16 bits of
+-	 * tsf_l wrapped, so decrement the high 16 bits.
+-	 */
+-	if ((u16)tsf_l < rx_tsf_0_15) {
+-		rx_tsf_16_31 -= 1;
+-		if (rx_tsf_16_31 == 0xffff)
+-			tsf_h -= 1;
+-	}
+-
+-	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
+-}
+-
+-static void
+-prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p,
+-		     struct ieee80211_rx_status *rx_status)
+-{
+-	wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
+-	int preamble;
+-	int channel;
+-	ratespec_t rspec;
+-	unsigned char *plcp;
+-
+-	/* fill in TSF and flag its presence */
+-	rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh);
+-	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+-
+-	channel = WLC_CHAN_CHANNEL(rxh->RxChan);
+-
+-	if (channel > 14) {
+-		rx_status->band = IEEE80211_BAND_5GHZ;
+-		rx_status->freq = ieee80211_ofdm_chan_to_freq(
+-					WF_CHAN_FACTOR_5_G/2, channel);
+-
+-	} else {
+-		rx_status->band = IEEE80211_BAND_2GHZ;
+-		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
+-	}
+-
+-	rx_status->signal = wlc_rxh->rssi;	/* signal */
+-
+-	/* noise */
+-	/* qual */
+-	rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;	/* ant */
+-
+-	plcp = p->data;
+-
+-	rspec = wlc_compute_rspec(rxh, plcp);
+-	if (IS_MCS(rspec)) {
+-		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
+-		rx_status->flag |= RX_FLAG_HT;
+-		if (RSPEC_IS40MHZ(rspec))
+-			rx_status->flag |= RX_FLAG_40MHZ;
+-	} else {
+-		switch (RSPEC2RATE(rspec)) {
+-		case WLC_RATE_1M:
+-			rx_status->rate_idx = 0;
+-			break;
+-		case WLC_RATE_2M:
+-			rx_status->rate_idx = 1;
+-			break;
+-		case WLC_RATE_5M5:
+-			rx_status->rate_idx = 2;
+-			break;
+-		case WLC_RATE_11M:
+-			rx_status->rate_idx = 3;
+-			break;
+-		case WLC_RATE_6M:
+-			rx_status->rate_idx = 4;
+-			break;
+-		case WLC_RATE_9M:
+-			rx_status->rate_idx = 5;
+-			break;
+-		case WLC_RATE_12M:
+-			rx_status->rate_idx = 6;
+-			break;
+-		case WLC_RATE_18M:
+-			rx_status->rate_idx = 7;
+-			break;
+-		case WLC_RATE_24M:
+-			rx_status->rate_idx = 8;
+-			break;
+-		case WLC_RATE_36M:
+-			rx_status->rate_idx = 9;
+-			break;
+-		case WLC_RATE_48M:
+-			rx_status->rate_idx = 10;
+-			break;
+-		case WLC_RATE_54M:
+-			rx_status->rate_idx = 11;
+-			break;
+-		default:
+-			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
+-		}
+-
+-		/* Determine short preamble and rate_idx */
+-		preamble = 0;
+-		if (IS_CCK(rspec)) {
+-			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
+-				rx_status->flag |= RX_FLAG_SHORTPRE;
+-		} else if (IS_OFDM(rspec)) {
+-			rx_status->flag |= RX_FLAG_SHORTPRE;
+-		} else {
+-			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
+-				  __func__);
+-		}
+-	}
+-
+-	if (PLCP3_ISSGI(plcp[3]))
+-		rx_status->flag |= RX_FLAG_SHORT_GI;
+-
+-	if (rxh->RxStatus1 & RXS_DECERR) {
+-		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+-		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
+-			  __func__);
+-	}
+-	if (rxh->RxStatus1 & RXS_FCSERR) {
+-		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+-		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
+-			  __func__);
+-	}
+-}
+-
+-static void
+-wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p)
+-{
+-	int len_mpdu;
+-	struct ieee80211_rx_status rx_status;
+-	struct ieee80211_hdr *hdr;
+-
+-	memset(&rx_status, 0, sizeof(rx_status));
+-	prep_mac80211_status(wlc, rxh, p, &rx_status);
+-
+-	/* mac header+body length, exclude CRC and plcp header */
+-	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
+-	skb_pull(p, D11_PHY_HDR_LEN);
+-	__skb_trim(p, len_mpdu);
+-
+-	/* unmute transmit */
+-	if (wlc->hw->suspended_fifos) {
+-		hdr = (struct ieee80211_hdr *)p->data;
+-		if (ieee80211_is_beacon(hdr->frame_control))
+-			wlc_bmac_mute(wlc->hw, false, 0);
+-	}
+-
+-	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
+-	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
+-	return;
+-}
+-
+-/* Process received frames */
+-/*
+- * Return true if more frames need to be processed. false otherwise.
+- * Param 'bound' indicates max. # frames to process before break out.
+- */
+-/* WLC_HIGH_API */
+-void wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
+-{
+-	d11rxhdr_t *rxh;
+-	struct ieee80211_hdr *h;
+-	uint len;
+-	bool is_amsdu;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* frame starts with rxhdr */
+-	rxh = (d11rxhdr_t *) (p->data);
+-
+-	/* strip off rxhdr */
+-	skb_pull(p, wlc->hwrxoff);
+-
+-	/* fixup rx header endianness */
+-	rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize);
+-	rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0);
+-	rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1);
+-	rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2);
+-	rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3);
+-	rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4);
+-	rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5);
+-	rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1);
+-	rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2);
+-	rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime);
+-	rxh->RxChan = le16_to_cpu(rxh->RxChan);
+-
+-	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
+-	if (rxh->RxStatus1 & RXS_PBPRES) {
+-		if (p->len < 2) {
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_recv: rcvd runt of "
+-				  "len %d\n", wlc->pub->unit, p->len);
+-			goto toss;
+-		}
+-		skb_pull(p, 2);
+-	}
+-
+-	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
+-	len = p->len;
+-
+-	if (rxh->RxStatus1 & RXS_FCSERR) {
+-		if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
+-			wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
+-				  " tossing\n");
+-			goto toss;
+-		} else {
+-			wiphy_err(wlc->wiphy, "RCSERR!!!\n");
+-			goto toss;
+-		}
+-	}
+-
+-	/* check received pkt has at least frame control field */
+-	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
+-		goto toss;
+-	}
+-
+-	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
+-
+-	/* explicitly test bad src address to avoid sending bad deauth */
+-	if (!is_amsdu) {
+-		/* CTS and ACK CTL frames are w/o a2 */
+-
+-		if (ieee80211_is_data(h->frame_control) ||
+-		    ieee80211_is_mgmt(h->frame_control)) {
+-			if ((is_zero_ether_addr(h->addr2) ||
+-			     is_multicast_ether_addr(h->addr2))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
+-					  "frame with invalid src mac address,"
+-					  " a2: %pM\n",
+-					 wlc->pub->unit, __func__, h->addr2);
+-				goto toss;
+-			}
+-		}
+-	}
+-
+-	/* due to sheer numbers, toss out probe reqs for now */
+-	if (ieee80211_is_probe_req(h->frame_control))
+-		goto toss;
+-
+-	if (is_amsdu)
+-		goto toss;
+-
+-	wlc_recvctl(wlc, rxh, p);
+-	return;
+-
+- toss:
+-	bcm_pkt_buf_free_skb(p);
+-}
+-
+-/* calculate frame duration for Mixed-mode L-SIG spoofing, return
+- * number of bytes goes in the length field
+- *
+- * Formula given by HT PHY Spec v 1.13
+- *   len = 3(nsyms + nstream + 3) - 3
+- */
+-u16
+-wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len)
+-{
+-	uint nsyms, len = 0, kNdps;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
+-		 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		/* MCS_TXS(mcs) returns num tx streams - 1 */
+-		int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
+-
+-		/* the payload duration calculation matches that of regular ofdm */
+-		/* 1000Ndbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-
+-		if (RSPEC_STC(ratespec) == 0)
+-			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-			nsyms =
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, kNdps);
+-		else
+-			/* STBC needs to have even number of symbols */
+-			nsyms =
+-			    2 *
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+-
+-		nsyms += (tot_streams + 3);	/* (+3) account for HT-SIG(2) and HT-STF(1) */
+-		/* 3 bytes/symbol @ legacy 6Mbps rate */
+-		len = (3 * nsyms) - 3;	/* (-3) excluding service bits and tail bits */
+-	}
+-
+-	return (u16) len;
+-}
+-
+-/* calculate frame duration of a given rate and length, return time in usec unit */
+-uint
+-wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
+-		    uint mac_len)
+-{
+-	uint nsyms, dur = 0, Ndps, kNdps;
+-	uint rate = RSPEC2RATE(ratespec);
+-
+-	if (rate == 0) {
+-		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
+-			  wlc->pub->unit);
+-		rate = WLC_RATE_1M;
+-	}
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
+-		 wlc->pub->unit, ratespec, preamble_type, mac_len);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+-
+-		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+-		if (preamble_type == WLC_MM_PREAMBLE)
+-			dur += PREN_MM_EXT;
+-		/* 1000Ndbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-
+-		if (RSPEC_STC(ratespec) == 0)
+-			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-			nsyms =
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, kNdps);
+-		else
+-			/* STBC needs to have even number of symbols */
+-			nsyms =
+-			    2 *
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+-
+-		dur += APHY_SYMBOL_TIME * nsyms;
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur += DOT11_OFDM_SIGNAL_EXTENSION;
+-	} else if (IS_OFDM(rate)) {
+-		dur = APHY_PREAMBLE_TIME;
+-		dur += APHY_SIGNAL_TIME;
+-		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+-		Ndps = rate * 2;
+-		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-		nsyms =
+-		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
+-			 Ndps);
+-		dur += APHY_SYMBOL_TIME * nsyms;
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur += DOT11_OFDM_SIGNAL_EXTENSION;
+-	} else {
+-		/* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
+-		mac_len = mac_len * 8 * 2;
+-		/* calc ceiling of bits/rate = microseconds of air time */
+-		dur = (mac_len + rate - 1) / rate;
+-		if (preamble_type & WLC_SHORT_PREAMBLE)
+-			dur += BPHY_PLCP_SHORT_TIME;
+-		else
+-			dur += BPHY_PLCP_TIME;
+-	}
+-	return dur;
+-}
+-
+-/* The opposite of wlc_calc_frame_time */
+-static uint
+-wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
+-		   uint dur)
+-{
+-	uint nsyms, mac_len, Ndps, kNdps;
+-	uint rate = RSPEC2RATE(ratespec);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
+-		 wlc->pub->unit, ratespec, preamble_type, dur);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+-		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+-		/* payload calculation matches that of regular ofdm */
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
+-		/* kNdbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-		nsyms = dur / APHY_SYMBOL_TIME;
+-		mac_len =
+-		    ((nsyms * kNdps) -
+-		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
+-	} else if (IS_OFDM(ratespec)) {
+-		dur -= APHY_PREAMBLE_TIME;
+-		dur -= APHY_SIGNAL_TIME;
+-		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+-		Ndps = rate * 2;
+-		nsyms = dur / APHY_SYMBOL_TIME;
+-		mac_len =
+-		    ((nsyms * Ndps) -
+-		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
+-	} else {
+-		if (preamble_type & WLC_SHORT_PREAMBLE)
+-			dur -= BPHY_PLCP_SHORT_TIME;
+-		else
+-			dur -= BPHY_PLCP_TIME;
+-		mac_len = dur * rate;
+-		/* divide out factor of 2 in rate (1/2 mbps) */
+-		mac_len = mac_len / 8 / 2;
+-	}
+-	return mac_len;
+-}
+-
+-static uint
+-wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
+-		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
+-	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+-	 * or equal to the rate of the immediately previous frame in the FES
+-	 */
+-	rspec = WLC_BASIC_RATE(wlc, rspec);
+-	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
+-	return wlc_calc_frame_time(wlc, rspec, preamble_type,
+-				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
+-				    FCS_LEN));
+-}
+-
+-static uint
+-wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	uint dur = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
+-		wlc->pub->unit, rspec, preamble_type);
+-	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+-	 * or equal to the rate of the immediately previous frame in the FES
+-	 */
+-	rspec = WLC_BASIC_RATE(wlc, rspec);
+-	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
+-	dur =
+-	    wlc_calc_frame_time(wlc, rspec, preamble_type,
+-				(DOT11_ACK_LEN + FCS_LEN));
+-	return dur;
+-}
+-
+-static uint
+-wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
+-		wlc->pub->unit, rspec, preamble_type);
+-	return wlc_calc_ack_time(wlc, rspec, preamble_type);
+-}
+-
+-/* derive wlc->band->basic_rate[] table from 'rateset' */
+-void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset)
+-{
+-	u8 rate;
+-	u8 mandatory;
+-	u8 cck_basic = 0;
+-	u8 ofdm_basic = 0;
+-	u8 *br = wlc->band->basic_rate;
+-	uint i;
+-
+-	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
+-	memset(br, 0, WLC_MAXRATE + 1);
+-
+-	/* For each basic rate in the rates list, make an entry in the
+-	 * best basic lookup.
+-	 */
+-	for (i = 0; i < rateset->count; i++) {
+-		/* only make an entry for a basic rate */
+-		if (!(rateset->rates[i] & WLC_RATE_FLAG))
+-			continue;
+-
+-		/* mask off basic bit */
+-		rate = (rateset->rates[i] & WLC_RATE_MASK);
+-
+-		if (rate > WLC_MAXRATE) {
+-			wiphy_err(wlc->wiphy, "wlc_rate_lookup_init: invalid "
+-				  "rate 0x%X in rate set\n",
+-				  rateset->rates[i]);
+-			continue;
+-		}
+-
+-		br[rate] = rate;
+-	}
+-
+-	/* The rate lookup table now has non-zero entries for each
+-	 * basic rate, equal to the basic rate: br[basicN] = basicN
+-	 *
+-	 * To look up the best basic rate corresponding to any
+-	 * particular rate, code can use the basic_rate table
+-	 * like this
+-	 *
+-	 * basic_rate = wlc->band->basic_rate[tx_rate]
+-	 *
+-	 * Make sure there is a best basic rate entry for
+-	 * every rate by walking up the table from low rates
+-	 * to high, filling in holes in the lookup table
+-	 */
+-
+-	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
+-		rate = wlc->band->hw_rateset.rates[i];
+-
+-		if (br[rate] != 0) {
+-			/* This rate is a basic rate.
+-			 * Keep track of the best basic rate so far by
+-			 * modulation type.
+-			 */
+-			if (IS_OFDM(rate))
+-				ofdm_basic = rate;
+-			else
+-				cck_basic = rate;
+-
+-			continue;
+-		}
+-
+-		/* This rate is not a basic rate so figure out the
+-		 * best basic rate less than this rate and fill in
+-		 * the hole in the table
+-		 */
+-
+-		br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;
+-
+-		if (br[rate] != 0)
+-			continue;
+-
+-		if (IS_OFDM(rate)) {
+-			/* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
+-			if (rate >= WLC_RATE_24M)
+-				mandatory = WLC_RATE_24M;
+-			else if (rate >= WLC_RATE_12M)
+-				mandatory = WLC_RATE_12M;
+-			else
+-				mandatory = WLC_RATE_6M;
+-		} else {
+-			/* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
+-			mandatory = rate;
+-		}
+-
+-		br[rate] = mandatory;
+-	}
+-}
+-
+-static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate)
+-{
+-	u8 phy_rate, index;
+-	u8 basic_phy_rate, basic_index;
+-	u16 dir_table, basic_table;
+-	u16 basic_ptr;
+-
+-	/* Shared memory address for the table we are reading */
+-	dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
+-
+-	/* Shared memory address for the table we are writing */
+-	basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
+-
+-	/*
+-	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
+-	 * the index into the rate table.
+-	 */
+-	phy_rate = rate_info[rate] & WLC_RATE_MASK;
+-	basic_phy_rate = rate_info[basic_rate] & WLC_RATE_MASK;
+-	index = phy_rate & 0xf;
+-	basic_index = basic_phy_rate & 0xf;
+-
+-	/* Find the SHM pointer to the ACK rate entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2));
+-
+-	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
+-	 * to the correct basic rate for the given incoming rate
+-	 */
+-	wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr);
+-}
+-
+-static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		if (BAND_5G(wlc->band->bandtype))
+-			rs_dflt = &ofdm_mimo_rates;
+-		else
+-			rs_dflt = &cck_ofdm_mimo_rates;
+-	} else if (wlc->band->gmode)
+-		rs_dflt = &cck_ofdm_rates;
+-	else
+-		rs_dflt = &cck_rates;
+-
+-	return rs_dflt;
+-}
+-
+-void wlc_set_ratetable(struct wlc_info *wlc)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs;
+-	u8 rate, basic_rate;
+-	uint i;
+-
+-	rs_dflt = wlc_rateset_get_hwrs(wlc);
+-
+-	wlc_rateset_copy(rs_dflt, &rs);
+-	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+-
+-	/* walk the phy rate table and update SHM basic rate lookup table */
+-	for (i = 0; i < rs.count; i++) {
+-		rate = rs.rates[i] & WLC_RATE_MASK;
+-
+-		/* for a given rate WLC_BASIC_RATE returns the rate at
+-		 * which a response ACK/CTS should be sent.
+-		 */
+-		basic_rate = WLC_BASIC_RATE(wlc, rate);
+-		if (basic_rate == 0) {
+-			/* This should only happen if we are using a
+-			 * restricted rateset.
+-			 */
+-			basic_rate = rs.rates[0] & WLC_RATE_MASK;
+-		}
+-
+-		wlc_write_rate_shm(wlc, rate, basic_rate);
+-	}
+-}
+-
+-/*
+- * Return true if the specified rate is supported by the specified band.
+- * WLC_BAND_AUTO indicates the current band.
+- */
+-bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band,
+-		    bool verbose)
+-{
+-	wlc_rateset_t *hw_rateset;
+-	uint i;
+-
+-	if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) {
+-		hw_rateset = &wlc->band->hw_rateset;
+-	} else if (NBANDS(wlc) > 1) {
+-		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
+-	} else {
+-		/* other band specified and we are a single band device */
+-		return false;
+-	}
+-
+-	/* check if this is a mimo rate */
+-	if (IS_MCS(rspec)) {
+-		if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
+-			goto error;
+-
+-		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
+-	}
+-
+-	for (i = 0; i < hw_rateset->count; i++)
+-		if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
+-			return true;
+- error:
+-	if (verbose) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_valid_rate: rate spec 0x%x "
+-			  "not in hw_rateset\n", wlc->pub->unit, rspec);
+-	}
+-
+-	return false;
+-}
+-
+-static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap)
+-{
+-	uint i;
+-	struct wlcband *band;
+-
+-	for (i = 0; i < NBANDS(wlc); i++) {
+-		if (IS_SINGLEBAND_5G(wlc->deviceid))
+-			i = BAND_5G_INDEX;
+-		band = wlc->bandstate[i];
+-		if (band->bandtype == WLC_BAND_5G) {
+-			if ((bwcap == WLC_N_BW_40ALL)
+-			    || (bwcap == WLC_N_BW_20IN2G_40IN5G))
+-				band->mimo_cap_40 = true;
+-			else
+-				band->mimo_cap_40 = false;
+-		} else {
+-			if (bwcap == WLC_N_BW_40ALL)
+-				band->mimo_cap_40 = true;
+-			else
+-				band->mimo_cap_40 = false;
+-		}
+-	}
+-
+-	wlc->mimo_band_bwcap = bwcap;
+-}
+-
+-void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs;
+-	u8 rate;
+-	u16 entry_ptr;
+-	u8 plcp[D11_PHY_HDR_LEN];
+-	u16 dur, sifs;
+-	uint i;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	rs_dflt = wlc_rateset_get_hwrs(wlc);
+-
+-	wlc_rateset_copy(rs_dflt, &rs);
+-	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+-
+-	/* walk the phy rate table and update MAC core SHM basic rate table entries */
+-	for (i = 0; i < rs.count; i++) {
+-		rate = rs.rates[i] & WLC_RATE_MASK;
+-
+-		entry_ptr = wlc_rate_shm_offset(wlc, rate);
+-
+-		/* Calculate the Probe Response PLCP for the given rate */
+-		wlc_compute_plcp(wlc, rate, frame_len, plcp);
+-
+-		/* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
+-		dur =
+-		    (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE,
+-						 frame_len);
+-		dur += sifs;
+-
+-		/* Update the SHM Rate Table entry Probe Response values */
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
+-			      (u16) (plcp[0] + (plcp[1] << 8)));
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
+-			      (u16) (plcp[2] + (plcp[3] << 8)));
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
+-	}
+-}
+-
+-/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
+- *
+- *	PLCP header is 6 bytes.
+- *	802.11 A3 header is 24 bytes.
+- *	Max beacon frame body template length is 112 bytes.
+- *	Max probe resp frame body template length is 110 bytes.
+- *
+- *      *len on input contains the max length of the packet available.
+- *
+- *	The *len value is set to the number of bytes in buf used, and starts with the PLCP
+- *	and included up to, but not including, the 4 byte FCS.
+- */
+-static void
+-wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec,
+-		     struct wlc_bsscfg *cfg, u16 *buf, int *len)
+-{
+-	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-	cck_phy_hdr_t *plcp;
+-	struct ieee80211_mgmt *h;
+-	int hdr_len, body_len;
+-
+-	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
+-		hdr_len = DOT11_MAC_HDR_LEN;
+-	else
+-		hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
+-	body_len = *len - hdr_len;	/* calc buffer size provided for frame body */
+-
+-	*len = hdr_len + body_len;	/* return actual size */
+-
+-	/* format PHY and MAC headers */
+-	memset((char *)buf, 0, hdr_len);
+-
+-	plcp = (cck_phy_hdr_t *) buf;
+-
+-	/* PLCP for Probe Response frames are filled in from core's rate table */
+-	if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) {
+-		/* fill in PLCP */
+-		wlc_compute_plcp(wlc, bcn_rspec,
+-				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
+-				 (u8 *) plcp);
+-
+-	}
+-	/* "Regular" and 16 MBSS but not for 4 MBSS */
+-	/* Update the phytxctl for the beacon based on the rspec */
+-	if (!SOFTBCN_ENAB(cfg))
+-		wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
+-
+-	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
+-		h = (struct ieee80211_mgmt *)&plcp[0];
+-	else
+-		h = (struct ieee80211_mgmt *)&plcp[1];
+-
+-	/* fill in 802.11 header */
+-	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
+-
+-	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
+-	/* A1 filled in by MAC for prb resp, broadcast for bcn */
+-	if (type == IEEE80211_STYPE_BEACON)
+-		memcpy(&h->da, &ether_bcast, ETH_ALEN);
+-	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
+-	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
+-
+-	/* SEQ filled in by MAC */
+-
+-	return;
+-}
+-
+-int wlc_get_header_len()
+-{
+-	return TXOFF;
+-}
+-
+-/* Update a beacon for a particular BSS
+- * For MBSS, this updates the software template and sets "latest" to the index of the
+- * template updated.
+- * Otherwise, it updates the hardware template.
+- */
+-void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
+-{
+-	int len = BCN_TMPL_LEN;
+-
+-	/* Clear the soft intmask */
+-	wlc->defmacintmask &= ~MI_BCNTPL;
+-
+-	if (!cfg->up) {		/* Only allow updates on an UP bss */
+-		return;
+-	}
+-
+-	/* Optimize:  Some of if/else could be combined */
+-	if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) {
+-		/* Hardware beaconing for this config */
+-		u16 bcn[BCN_TMPL_LEN / 2];
+-		u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
+-		d11regs_t *regs = wlc->regs;
+-
+-		/* Check if both templates are in use, if so sched. an interrupt
+-		 *      that will call back into this routine
+-		 */
+-		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
+-			/* clear any previous status */
+-			W_REG(&regs->macintstatus, MI_BCNTPL);
+-		}
+-		/* Check that after scheduling the interrupt both of the
+-		 *      templates are still busy. if not clear the int. & remask
+-		 */
+-		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
+-			wlc->defmacintmask |= MI_BCNTPL;
+-			return;
+-		}
+-
+-		wlc->bcn_rspec =
+-		    wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
+-		/* update the template and ucode shm */
+-		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
+-				     wlc->bcn_rspec, cfg, bcn, &len);
+-		wlc_write_hw_bcntemplates(wlc, bcn, len, false);
+-	}
+-}
+-
+-/*
+- * Update all beacons for the system.
+- */
+-void wlc_update_beacon(struct wlc_info *wlc)
+-{
+-	int idx;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	/* update AP or IBSS beacons */
+-	FOREACH_BSS(wlc, idx, bsscfg) {
+-		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+-			wlc_bss_update_beacon(wlc, bsscfg);
+-	}
+-}
+-
+-/* Write ssid into shared memory */
+-void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
+-{
+-	u8 *ssidptr = cfg->SSID;
+-	u16 base = M_SSID;
+-	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
+-
+-	/* padding the ssid with zero and copy it into shm */
+-	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
+-	memcpy(ssidbuf, ssidptr, cfg->SSID_len);
+-
+-	wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
+-
+-	if (!MBSS_BCN_ENAB(cfg))
+-		wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
+-}
+-
+-void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend)
+-{
+-	int idx;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	/* update AP or IBSS probe responses */
+-	FOREACH_BSS(wlc, idx, bsscfg) {
+-		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+-			wlc_bss_update_probe_resp(wlc, bsscfg, suspend);
+-	}
+-}
+-
+-void
+-wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg,
+-			  bool suspend)
+-{
+-	u16 prb_resp[BCN_TMPL_LEN / 2];
+-	int len = BCN_TMPL_LEN;
+-
+-	/* write the probe response to hardware, or save in the config structure */
+-	if (!MBSS_PRB_ENAB(cfg)) {
+-
+-		/* create the probe response template */
+-		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg,
+-				     prb_resp, &len);
+-
+-		if (suspend)
+-			wlc_suspend_mac_and_wait(wlc);
+-
+-		/* write the probe response into the template region */
+-		wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
+-					    (len + 3) & ~3, prb_resp);
+-
+-		/* write the length of the probe response frame (+PLCP/-FCS) */
+-		wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);
+-
+-		/* write the SSID and SSID length */
+-		wlc_shm_ssid_upd(wlc, cfg);
+-
+-		/*
+-		 * Write PLCP headers and durations for probe response frames at all rates.
+-		 * Use the actual frame length covered by the PLCP header for the call to
+-		 * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS.
+-		 */
+-		len += (-D11_PHY_HDR_LEN + FCS_LEN);
+-		wlc_mod_prb_rsp_rate_table(wlc, (u16) len);
+-
+-		if (suspend)
+-			wlc_enable_mac(wlc);
+-	} else {		/* Generating probe resp in sw; update local template */
+-		/* error: No software probe response support without MBSS */
+-	}
+-}
+-
+-/* prepares pdu for transmission. returns BCM error codes */
+-int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop)
+-{
+-	uint fifo;
+-	d11txh_t *txh;
+-	struct ieee80211_hdr *h;
+-	struct scb *scb;
+-
+-	txh = (d11txh_t *) (pdu->data);
+-	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
+-
+-	/* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */
+-	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
+-
+-	scb = NULL;
+-
+-	*fifop = fifo;
+-
+-	/* return if insufficient dma resources */
+-	if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
+-		/* Mark precedences related to this FIFO, unsendable */
+-		WLC_TX_FIFO_CLEAR(wlc, fifo);
+-		return -EBUSY;
+-	}
+-	return 0;
+-}
+-
+-/* init tx reported rate mechanism */
+-void wlc_reprate_init(struct wlc_info *wlc)
+-{
+-	int i;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	FOREACH_BSS(wlc, i, bsscfg) {
+-		wlc_bsscfg_reprate_init(bsscfg);
+-	}
+-}
+-
+-/* per bsscfg init tx reported rate mechanism */
+-void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg)
+-{
+-	bsscfg->txrspecidx = 0;
+-	memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
+-}
+-
+-/* Retrieve a consolidated set of revision information,
+- * typically for the WLC_GET_REVINFO ioctl
+- */
+-int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len)
+-{
+-	wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf;
+-
+-	if (len < WL_REV_INFO_LEGACY_LENGTH)
+-		return -EOVERFLOW;
+-
+-	rinfo->vendorid = wlc->vendorid;
+-	rinfo->deviceid = wlc->deviceid;
+-	rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) |
+-	    (wlc->band->radioid << IDCODE_ID_SHIFT);
+-	rinfo->chiprev = wlc->pub->sih->chiprev;
+-	rinfo->corerev = wlc->pub->corerev;
+-	rinfo->boardid = wlc->pub->sih->boardtype;
+-	rinfo->boardvendor = wlc->pub->sih->boardvendor;
+-	rinfo->boardrev = wlc->pub->boardrev;
+-	rinfo->ucoderev = wlc->ucode_rev;
+-	rinfo->driverrev = EPI_VERSION_NUM;
+-	rinfo->bus = wlc->pub->sih->bustype;
+-	rinfo->chipnum = wlc->pub->sih->chip;
+-
+-	if (len >= (offsetof(wlc_rev_info_t, chippkg))) {
+-		rinfo->phytype = wlc->band->phytype;
+-		rinfo->phyrev = wlc->band->phyrev;
+-		rinfo->anarev = 0;	/* obsolete stuff, suppress */
+-	}
+-
+-	if (len >= sizeof(*rinfo)) {
+-		rinfo->chippkg = wlc->pub->sih->chippkg;
+-	}
+-
+-	return 0;
+-}
+-
+-void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs)
+-{
+-	wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype,
+-			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+-			    CHSPEC_WLC_BW(wlc->default_bss->chanspec),
+-			    wlc->stf->txstreams);
+-}
+-
+-static void wlc_bss_default_init(struct wlc_info *wlc)
+-{
+-	chanspec_t chanspec;
+-	struct wlcband *band;
+-	wlc_bss_info_t *bi = wlc->default_bss;
+-
+-	/* init default and target BSS with some sane initial values */
+-	memset((char *)(bi), 0, sizeof(wlc_bss_info_t));
+-	bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT :
+-	    BEACON_INTERVAL_DEFAULT;
+-	bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT :
+-	    DTIM_INTERVAL_DEFAULT;
+-
+-	/* fill the default channel as the first valid channel
+-	 * starting from the 2G channels
+-	 */
+-	chanspec = CH20MHZ_CHSPEC(1);
+-	wlc->home_chanspec = bi->chanspec = chanspec;
+-
+-	/* find the band of our default channel */
+-	band = wlc->band;
+-	if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec))
+-		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+-
+-	/* init bss rates to the band specific default rate set */
+-	wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype,
+-			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+-			    CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams);
+-
+-	if (N_ENAB(wlc->pub))
+-		bi->flags |= WLC_BSS_HT;
+-}
+-
+-static ratespec_t
+-mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band,
+-		       u32 int_val)
+-{
+-	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
+-	u8 rate = int_val & NRATE_RATE_MASK;
+-	ratespec_t rspec;
+-	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
+-	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
+-	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
+-				  == NRATE_OVERRIDE_MCS_ONLY);
+-	int bcmerror = 0;
+-
+-	if (!ismcs) {
+-		return (ratespec_t) rate;
+-	}
+-
+-	/* validate the combination of rate/mcs/stf is allowed */
+-	if (N_ENAB(wlc->pub) && ismcs) {
+-		/* mcs only allowed when nmode */
+-		if (stf > PHY_TXC1_MODE_SDM) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
+-				 WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-
+-		/* mcs 32 is a special case, DUP mode 40 only */
+-		if (rate == 32) {
+-			if (!CHSPEC_IS40(wlc->home_chanspec) ||
+-			    ((stf != PHY_TXC1_MODE_SISO)
+-			     && (stf != PHY_TXC1_MODE_CDD))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
+-					  "32\n", WLCWLUNIT(wlc), __func__);
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-			/* mcs > 7 must use stf SDM */
+-		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
+-			/* mcs > 7 must use stf SDM */
+-			if (stf != PHY_TXC1_MODE_SDM) {
+-				BCMMSG(wlc->wiphy, "wl%d: enabling "
+-					 "SDM mode for mcs %d\n",
+-					 WLCWLUNIT(wlc), rate);
+-				stf = PHY_TXC1_MODE_SDM;
+-			}
+-		} else {
+-			/* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
+-			if ((stf > PHY_TXC1_MODE_STBC) ||
+-			    (!WLC_STBC_CAP_PHY(wlc)
+-			     && (stf == PHY_TXC1_MODE_STBC))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
+-					  "\n", WLCWLUNIT(wlc), __func__);
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-		}
+-	} else if (IS_OFDM(rate)) {
+-		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
+-				  WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	} else if (IS_CCK(rate)) {
+-		if ((cur_band->bandtype != WLC_BAND_2G)
+-		    || (stf != PHY_TXC1_MODE_SISO)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
+-				  WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	} else {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
+-			  WLCWLUNIT(wlc), __func__);
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-	/* make sure multiple antennae are available for non-siso rates */
+-	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
+-			  "request\n", WLCWLUNIT(wlc), __func__);
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	rspec = rate;
+-	if (ismcs) {
+-		rspec |= RSPEC_MIMORATE;
+-		/* For STBC populate the STC field of the ratespec */
+-		if (stf == PHY_TXC1_MODE_STBC) {
+-			u8 stc;
+-			stc = 1;	/* Nss for single stream is always 1 */
+-			rspec |= (stc << RSPEC_STC_SHIFT);
+-		}
+-	}
+-
+-	rspec |= (stf << RSPEC_STF_SHIFT);
+-
+-	if (override_mcs_only)
+-		rspec |= RSPEC_OVERRIDE_MCS_ONLY;
+-
+-	if (issgi)
+-		rspec |= RSPEC_SHORT_GI;
+-
+-	if ((rate != 0)
+-	    && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) {
+-		return rate;
+-	}
+-
+-	return rspec;
+-done:
+-	return rate;
+-}
+-
+-/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
+-static int
+-wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
+-		   bool writeToShm)
+-{
+-	int idle_busy_ratio_x_16 = 0;
+-	uint offset =
+-	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
+-	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
+-	if (duty_cycle > 100 || duty_cycle < 0) {
+-		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
+-			  wlc->pub->unit);
+-		return -EINVAL;
+-	}
+-	if (duty_cycle)
+-		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
+-	/* Only write to shared memory  when wl is up */
+-	if (writeToShm)
+-		wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);
+-
+-	if (isOFDM)
+-		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
+-	else
+-		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
+-
+-	return 0;
+-}
+-
+-/* Read a single u16 from shared memory.
+- * SHM 'offset' needs to be an even address
+- */
+-u16 wlc_read_shm(struct wlc_info *wlc, uint offset)
+-{
+-	return wlc_bmac_read_shm(wlc->hw, offset);
+-}
+-
+-/* Write a single u16 to shared memory.
+- * SHM 'offset' needs to be an even address
+- */
+-void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v)
+-{
+-	wlc_bmac_write_shm(wlc->hw, offset, v);
+-}
+-
+-/* Copy a buffer to shared memory.
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- */
+-void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len)
+-{
+-	/* offset and len need to be even */
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+-
+-}
+-
+-/* wrapper BMAC functions to for HIGH driver access */
+-void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val)
+-{
+-	wlc_bmac_mctrl(wlc->hw, mask, val);
+-}
+-
+-void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands)
+-{
+-	wlc_bmac_mhf(wlc->hw, idx, mask, val, bands);
+-}
+-
+-int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks)
+-{
+-	return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks);
+-}
+-
+-void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len,
+-			    void *buf)
+-{
+-	wlc_bmac_write_template_ram(wlc->hw, offset, len, buf);
+-}
+-
+-void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
+-			       bool both)
+-{
+-	wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both);
+-}
+-
+-void
+-wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
+-		  const u8 *addr)
+-{
+-	wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr);
+-	if (match_reg_offset == RCM_BSSID_OFFSET)
+-		memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
+-}
+-
+-void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin)
+-{
+-	wlc->band->CWmin = newmin;
+-	wlc_bmac_set_cwmin(wlc->hw, newmin);
+-}
+-
+-void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax)
+-{
+-	wlc->band->CWmax = newmax;
+-	wlc_bmac_set_cwmax(wlc->hw, newmax);
+-}
+-
+-/* Search mem rw utilities */
+-
+-void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit)
+-{
+-	wlc_bmac_pllreq(wlc->hw, set, req_bit);
+-}
+-
+-void wlc_reset_bmac_done(struct wlc_info *wlc)
+-{
+-}
+-
+-/* check for the particular priority flow control bit being set */
+-bool
+-wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q,
+-			     int prio)
+-{
+-	uint prio_mask;
+-
+-	if (prio == ALLPRIO) {
+-		prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
+-	} else {
+-		prio_mask = NBITVAL(prio);
+-	}
+-
+-	return (q->stopped & prio_mask) == prio_mask;
+-}
+-
+-/* propagate the flow control to all interfaces using the given tx queue */
+-void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-		       bool on, int prio)
+-{
+-	uint prio_bits;
+-	uint cur_bits;
+-
+-	BCMMSG(wlc->wiphy, "flow control kicks in\n");
+-
+-	if (prio == ALLPRIO) {
+-		prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
+-	} else {
+-		prio_bits = NBITVAL(prio);
+-	}
+-
+-	cur_bits = qi->stopped & prio_bits;
+-
+-	/* Check for the case of no change and return early
+-	 * Otherwise update the bit and continue
+-	 */
+-	if (on) {
+-		if (cur_bits == prio_bits) {
+-			return;
+-		}
+-		mboolset(qi->stopped, prio_bits);
+-	} else {
+-		if (cur_bits == 0) {
+-			return;
+-		}
+-		mboolclr(qi->stopped, prio_bits);
+-	}
+-
+-	/* If there is a flow control override we will not change the external
+-	 * flow control state.
+-	 */
+-	if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
+-		return;
+-	}
+-
+-	wlc_txflowcontrol_signal(wlc, qi, on, prio);
+-}
+-
+-void
+-wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-			   bool on, uint override)
+-{
+-	uint prev_override;
+-
+-	prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
+-
+-	/* Update the flow control bits and do an early return if there is
+-	 * no change in the external flow control state.
+-	 */
+-	if (on) {
+-		mboolset(qi->stopped, override);
+-		/* if there was a previous override bit on, then setting this
+-		 * makes no difference.
+-		 */
+-		if (prev_override) {
+-			return;
+-		}
+-
+-		wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
+-	} else {
+-		mboolclr(qi->stopped, override);
+-		/* clearing an override bit will only make a difference for
+-		 * flow control if it was the only bit set. For any other
+-		 * override setting, just return
+-		 */
+-		if (prev_override != override) {
+-			return;
+-		}
+-
+-		if (qi->stopped == 0) {
+-			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+-		} else {
+-			int prio;
+-
+-			for (prio = MAXPRIO; prio >= 0; prio--) {
+-				if (!mboolisset(qi->stopped, NBITVAL(prio)))
+-					wlc_txflowcontrol_signal(wlc, qi, OFF,
+-								 prio);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_txflowcontrol_reset(struct wlc_info *wlc)
+-{
+-	struct wlc_txq_info *qi;
+-
+-	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+-		if (qi->stopped) {
+-			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+-			qi->stopped = 0;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on,
+-			 int prio)
+-{
+-	struct wlc_if *wlcif;
+-
+-	for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
+-		if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED)
+-			wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
+-	}
+-}
+-
+-static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc)
+-{
+-	struct wlc_txq_info *qi, *p;
+-
+-	qi = kzalloc(sizeof(struct wlc_txq_info), GFP_ATOMIC);
+-	if (qi != NULL) {
+-		/*
+-		 * Have enough room for control packets along with HI watermark
+-		 * Also, add room to txq for total psq packets if all the SCBs
+-		 * leave PS mode. The watermark for flowcontrol to OS packets
+-		 * will remain the same
+-		 */
+-		bcm_pktq_init(&qi->q, WLC_PREC_COUNT,
+-			  (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
+-			  + wlc->pub->psq_pkts_total);
+-
+-		/* add this queue to the the global list */
+-		p = wlc->tx_queues;
+-		if (p == NULL) {
+-			wlc->tx_queues = qi;
+-		} else {
+-			while (p->next != NULL)
+-				p = p->next;
+-			p->next = qi;
+-		}
+-	}
+-	return qi;
+-}
+-
+-static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi)
+-{
+-	struct wlc_txq_info *p;
+-
+-	if (qi == NULL)
+-		return;
+-
+-	/* remove the queue from the linked list */
+-	p = wlc->tx_queues;
+-	if (p == qi)
+-		wlc->tx_queues = p->next;
+-	else {
+-		while (p != NULL && p->next != qi)
+-			p = p->next;
+-		if (p != NULL)
+-			p->next = p->next->next;
+-	}
+-
+-	kfree(qi);
+-}
+-
+-/*
+- * Flag 'scan in progress' to withhold dynamic phy calibration
+- */
+-void wlc_scan_start(struct wlc_info *wlc)
+-{
+-	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
+-}
+-
+-void wlc_scan_stop(struct wlc_info *wlc)
+-{
+-	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
+-}
+-
+-void wlc_associate_upd(struct wlc_info *wlc, bool state)
+-{
+-	wlc->pub->associated = state;
+-	wlc->cfg->associated = state;
+-}
+-
+-/*
+- * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
+- * AMPDU traffic, packets pending in hardware have to be invalidated so that
+- * when later on hardware releases them, they can be handled appropriately.
+- */
+-void wlc_inval_dma_pkts(struct wlc_hw_info *hw,
+-			       struct ieee80211_sta *sta,
+-			       void (*dma_callback_fn))
+-{
+-	struct hnddma_pub *dmah;
+-	int i;
+-	for (i = 0; i < NFIFO; i++) {
+-		dmah = hw->di[i];
+-		if (dmah != NULL)
+-			dma_walk_packets(dmah, dma_callback_fn, sta);
+-	}
+-}
+-
+-int wlc_get_curband(struct wlc_info *wlc)
+-{
+-	return wlc->band->bandunit;
+-}
+-
+-void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
+-{
+-	/* flush packet queue when requested */
+-	if (drop)
+-		bcm_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+-
+-	/* wait for queue and DMA fifos to run dry */
+-	while (!pktq_empty(&wlc->pkt_queue->q) ||
+-	       TXPKTPENDTOT(wlc) > 0) {
+-		wl_msleep(wlc->wl, 1);
+-	}
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
+deleted file mode 100644
+index fb48dfc..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h
++++ /dev/null
+@@ -1,939 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_h_
+-#define _wlc_h_
+-
+-#define MA_WINDOW_SZ		8	/* moving average window size */
+-#define	WL_HWRXOFF		38	/* chip rx buffer offset */
+-#define	INVCHANNEL		255	/* invalid channel */
+-#define	MAXCOREREV		28	/* max # supported core revisions (0 .. MAXCOREREV - 1) */
+-#define WLC_MAXMODULES		22	/* max #  wlc_module_register() calls */
+-
+-#define WLC_BITSCNT(x)	bcm_bitcount((u8 *)&(x), sizeof(u8))
+-
+-/* Maximum wait time for a MAC suspend */
+-#define	WLC_MAX_MAC_SUSPEND	83000	/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
+-
+-/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable
+- */
+-#define WLC_PRB_RESP_TIMEOUT	0	/* Disable probe response timeout */
+-
+-/* transmit buffer max headroom for protocol headers */
+-#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
+-
+-/* For managing scan result lists */
+-struct wlc_bss_list {
+-	uint count;
+-	bool beacon;		/* set for beacon, cleared for probe response */
+-	wlc_bss_info_t *ptrs[MAXBSS];
+-};
+-
+-#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */
+-
+-/* Double check that unsupported cores are not enabled */
+-#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
+-#error "Configuration for D11CONF includes unsupported versions."
+-#endif				/* Bad versions */
+-
+-#define	VALID_COREREV(corerev)	CONF_HAS(D11CONF, corerev)
+-
+-/* values for shortslot_override */
+-#define WLC_SHORTSLOT_AUTO	-1	/* Driver will manage Shortslot setting */
+-#define WLC_SHORTSLOT_OFF	0	/* Turn off short slot */
+-#define WLC_SHORTSLOT_ON	1	/* Turn on short slot */
+-
+-/* value for short/long and mixmode/greenfield preamble */
+-
+-#define WLC_LONG_PREAMBLE	(0)
+-#define WLC_SHORT_PREAMBLE	(1 << 0)
+-#define WLC_GF_PREAMBLE		(1 << 1)
+-#define WLC_MM_PREAMBLE		(1 << 2)
+-#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE))
+-
+-/* values for barker_preamble */
+-#define WLC_BARKER_SHORT_ALLOWED	0	/* Short pre-amble allowed */
+-
+-/* A fifo is full. Clear precedences related to that FIFO */
+-#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo])
+-
+-/* Fifo is NOT full. Enable precedences for that FIFO */
+-#define WLC_TX_FIFO_ENAB(wlc, fifo)  ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo])
+-
+-/* TxFrameID */
+-/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
+-/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
+-#define TXFID_QUEUE_MASK	0x0007	/* Bits 0-2 */
+-#define TXFID_SEQ_MASK		0x7FE0	/* Bits 5-15 */
+-#define TXFID_SEQ_SHIFT		5	/* Number of bit shifts */
+-#define	TXFID_RATE_PROBE_MASK	0x8000	/* Bit 15 for rate probe */
+-#define TXFID_RATE_MASK		0x0018	/* Mask for bits 3 and 4 */
+-#define TXFID_RATE_SHIFT	3	/* Shift 3 bits for rate mask */
+-
+-/* promote boardrev */
+-#define BOARDREV_PROMOTABLE	0xFF	/* from */
+-#define BOARDREV_PROMOTED	1	/* to */
+-
+-/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true
+- */
+-#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+-#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \
+-	((bsscfg)->wsec & WSEC_SWFLAG)))
+-
+-#define WLC_PORTOPEN(cfg) \
+-	(((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \
+-	(cfg)->wsec_portopen : true)
+-
+-#define PS_ALLOWED(wlc)	wlc_ps_allowed(wlc)
+-
+-#define DATA_BLOCK_TX_SUPR	(1 << 4)
+-
+-/* 802.1D Priority to TX FIFO number for wme */
+-extern const u8 prio2fifo[];
+-
+-/* Ucode MCTL_WAKE override bits */
+-#define WLC_WAKE_OVERRIDE_CLKCTL	0x01
+-#define WLC_WAKE_OVERRIDE_PHYREG	0x02
+-#define WLC_WAKE_OVERRIDE_MACSUSPEND	0x04
+-#define WLC_WAKE_OVERRIDE_TXFIFO	0x08
+-#define WLC_WAKE_OVERRIDE_FORCEFAST	0x10
+-
+-/* stuff pulled in from wlc.c */
+-
+-/* Interrupt bit error summary.  Don't include I_RU: we refill DMA at other
+- * times; and if we run out, constant I_RU interrupts may cause lockup.  We
+- * will still get error counts from rx0ovfl.
+- */
+-#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RO | I_XU)
+-/* default software intmasks */
+-#define	DEF_RXINTMASK	(I_RI)	/* enable rx int on rxfifo only */
+-#define	DEF_MACINTMASK	(MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
+-			 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
+-			 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
+-
+-#define	RETRY_SHORT_DEF			7	/* Default Short retry Limit */
+-#define	RETRY_SHORT_MAX			255	/* Maximum Short retry Limit */
+-#define	RETRY_LONG_DEF			4	/* Default Long retry count */
+-#define	RETRY_SHORT_FB			3	/* Short retry count for fallback rate */
+-#define	RETRY_LONG_FB			2	/* Long retry count for fallback rate */
+-
+-#define	MAXTXPKTS		6	/* max # pkts pending */
+-
+-/* frameburst */
+-#define	MAXTXFRAMEBURST		8	/* vanilla xpress mode: max frames/burst */
+-#define	MAXFRAMEBURST_TXOP	10000	/* Frameburst TXOP in usec */
+-
+-/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */
+-#define EDCF_SHORT_S            0
+-#define EDCF_SFB_S              4
+-#define EDCF_LONG_S             8
+-#define EDCF_LFB_S              12
+-#define EDCF_SHORT_M            BITFIELD_MASK(4)
+-#define EDCF_SFB_M              BITFIELD_MASK(4)
+-#define EDCF_LONG_M             BITFIELD_MASK(4)
+-#define EDCF_LFB_M              BITFIELD_MASK(4)
+-
+-#define WLC_WME_RETRY_SHORT_GET(wlc, ac)    GFIELD(wlc->wme_retries[ac], EDCF_SHORT)
+-#define WLC_WME_RETRY_SFB_GET(wlc, ac)      GFIELD(wlc->wme_retries[ac], EDCF_SFB)
+-#define WLC_WME_RETRY_LONG_GET(wlc, ac)     GFIELD(wlc->wme_retries[ac], EDCF_LONG)
+-#define WLC_WME_RETRY_LFB_GET(wlc, ac)      GFIELD(wlc->wme_retries[ac], EDCF_LFB)
+-
+-#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val))
+-#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val))
+-#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val))
+-#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val))
+-
+-/* PLL requests */
+-#define WLC_PLLREQ_SHARED	0x1	/* pll is shared on old chips */
+-#define WLC_PLLREQ_RADIO_MON	0x2	/* hold pll for radio monitor register checking */
+-#define WLC_PLLREQ_FLIP		0x4	/* hold/release pll for some short operation */
+-
+-/*
+- * Macros to check if AP or STA is active.
+- * AP Active means more than just configured: driver and BSS are "up";
+- * that is, we are beaconing/responding as an AP (aps_associated).
+- * STA Active similarly means the driver is up and a configured STA BSS
+- * is up: either associated (stas_associated) or trying.
+- *
+- * Macro definitions vary as per AP/STA ifdefs, allowing references to
+- * ifdef'd structure fields and constant values (0) for optimization.
+- * Make sure to enclose blocks of code such that any routines they
+- * reference can also be unused and optimized out by the linker.
+- */
+-/* NOTE: References structure fields defined in wlc.h */
+-#define AP_ACTIVE(wlc)	(0)
+-
+-/*
+- * Detect Card removed.
+- * Even checking an sbconfig register read will not false trigger when the core is in reset.
+- * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy
+- * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern
+- * (some platforms return all 0).
+- * If clocks are present, call the sb routine which will figure out if the device is removed.
+- */
+-#define DEVICEREMOVED(wlc)      \
+-	((wlc->hw->clk) ?   \
+-	((R_REG(&wlc->hw->regs->maccontrol) & \
+-	(MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \
+-	(ai_deviceremoved(wlc->hw->sih)))
+-
+-#define WLCWLUNIT(wlc)		((wlc)->pub->unit)
+-
+-struct wlc_protection {
+-	bool _g;		/* use g spec protection, driver internal */
+-	s8 g_override;	/* override for use of g spec protection */
+-	u8 gmode_user;	/* user config gmode, operating band->gmode is different */
+-	s8 overlap;		/* Overlap BSS/IBSS protection for both 11g and 11n */
+-	s8 nmode_user;	/* user config nmode, operating pub->nmode is different */
+-	s8 n_cfg;		/* use OFDM protection on MIMO frames */
+-	s8 n_cfg_override;	/* override for use of N protection */
+-	bool nongf;		/* non-GF present protection */
+-	s8 nongf_override;	/* override for use of GF protection */
+-	s8 n_pam_override;	/* override for preamble: MM or GF */
+-	bool n_obss;		/* indicated OBSS Non-HT STA present */
+-
+-	uint longpre_detect_timeout;	/* #sec until long preamble bcns gone */
+-	uint barker_detect_timeout;	/* #sec until bcns signaling Barker long preamble */
+-	/* only is gone */
+-	uint ofdm_ibss_timeout;	/* #sec until ofdm IBSS beacons gone */
+-	uint ofdm_ovlp_timeout;	/* #sec until ofdm overlapping BSS bcns gone */
+-	uint nonerp_ibss_timeout;	/* #sec until nonerp IBSS beacons gone */
+-	uint nonerp_ovlp_timeout;	/* #sec until nonerp overlapping BSS bcns gone */
+-	uint g_ibss_timeout;	/* #sec until bcns signaling Use_Protection gone */
+-	uint n_ibss_timeout;	/* #sec until bcns signaling Use_OFDM_Protection gone */
+-	uint ht20in40_ovlp_timeout;	/* #sec until 20MHz overlapping OPMODE gone */
+-	uint ht20in40_ibss_timeout;	/* #sec until 20MHz-only HT station bcns gone */
+-	uint non_gf_ibss_timeout;	/* #sec until non-GF bcns gone */
+-};
+-
+-/* anything affects the single/dual streams/antenna operation */
+-struct wlc_stf {
+-	u8 hw_txchain;	/* HW txchain bitmap cfg */
+-	u8 txchain;		/* txchain bitmap being used */
+-	u8 txstreams;	/* number of txchains being used */
+-
+-	u8 hw_rxchain;	/* HW rxchain bitmap cfg */
+-	u8 rxchain;		/* rxchain bitmap being used */
+-	u8 rxstreams;	/* number of rxchains being used */
+-
+-	u8 ant_rx_ovr;	/* rx antenna override */
+-	s8 txant;		/* userTx antenna setting */
+-	u16 phytxant;	/* phyTx antenna setting in txheader */
+-
+-	u8 ss_opmode;	/* singlestream Operational mode, 0:siso; 1:cdd */
+-	bool ss_algosel_auto;	/* if true, use wlc->stf->ss_algo_channel; */
+-	/* else use wlc->band->stf->ss_mode_band; */
+-	u16 ss_algo_channel;	/* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */
+-	u8 no_cddstbc;	/* stf override, 1: no CDD (or STBC) allowed */
+-
+-	u8 rxchain_restore_delay;	/* delay time to restore default rxchain */
+-
+-	s8 ldpc;		/* AUTO/ON/OFF ldpc cap supported */
+-	u8 txcore[MAX_STREAMS_SUPPORTED + 1];	/* bitmap of selected core for each Nsts */
+-	s8 spatial_policy;
+-};
+-
+-#define WLC_STF_SS_STBC_TX(wlc, scb) \
+-	(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \
+-	 (SCB_STBC_CAP((scb)) &&					\
+-	  (wlc)->band->band_stf_stbc_tx == AUTO &&			\
+-	  isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
+-
+-#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3))
+-
+-#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \
+-	WLCISLCNPHY(wlc->band))
+-
+-#define WLC_CHAN_PHYTYPE(x)     (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT)
+-#define WLC_CHAN_CHANNEL(x)     (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT)
+-#define WLC_RX_CHANNEL(rxh)	(WLC_CHAN_CHANNEL((rxh)->RxChan))
+-
+-/* wlc_bss_info flag bit values */
+-#define WLC_BSS_HT		0x0020	/* BSS is HT (MIMO) capable */
+-
+-/* Flags used in wlc_txq_info.stopped */
+-#define TXQ_STOP_FOR_PRIOFC_MASK	0x000000FF	/* per prio flow control bits */
+-#define TXQ_STOP_FOR_PKT_DRAIN		0x00000100	/* stop txq enqueue for packet drain */
+-#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL	0x00000200	/* stop txq enqueue for ampdu flow control */
+-
+-#define WLC_HT_WEP_RESTRICT	0x01	/* restrict HT with WEP */
+-#define WLC_HT_TKIP_RESTRICT	0x02	/* restrict HT with TKIP */
+-
+-/*
+- * core state (mac)
+- */
+-struct wlccore {
+-	uint coreidx;		/* # sb enumerated core */
+-
+-	/* fifo */
+-	uint *txavail[NFIFO];	/* # tx descriptors available */
+-	s16 txpktpend[NFIFO];	/* tx admission control */
+-
+-	macstat_t *macstat_snapshot;	/* mac hw prev read values */
+-};
+-
+-/*
+- * band state (phy+ana+radio)
+- */
+-struct wlcband {
+-	int bandtype;		/* WLC_BAND_2G, WLC_BAND_5G */
+-	uint bandunit;		/* bandstate[] index */
+-
+-	u16 phytype;		/* phytype */
+-	u16 phyrev;
+-	u16 radioid;
+-	u16 radiorev;
+-	wlc_phy_t *pi;		/* pointer to phy specific information */
+-	bool abgphy_encore;
+-
+-	u8 gmode;		/* currently active gmode (see wlioctl.h) */
+-
+-	struct scb *hwrs_scb;	/* permanent scb for hw rateset */
+-
+-	wlc_rateset_t defrateset;	/* band-specific copy of default_bss.rateset */
+-
+-	ratespec_t rspec_override;	/* 802.11 rate override */
+-	ratespec_t mrspec_override;	/* multicast rate override */
+-	u8 band_stf_ss_mode;	/* Configured STF type, 0:siso; 1:cdd */
+-	s8 band_stf_stbc_tx;	/* STBC TX 0:off; 1:force on; -1:auto */
+-	wlc_rateset_t hw_rateset;	/* rates supported by chip (phy-specific) */
+-	u8 basic_rate[WLC_MAXRATE + 1];	/* basic rates indexed by rate */
+-	bool mimo_cap_40;	/* 40 MHz cap enabled on this band */
+-	s8 antgain;		/* antenna gain from srom */
+-
+-	u16 CWmin;		/* The minimum size of contention window, in unit of aSlotTime */
+-	u16 CWmax;		/* The maximum size of contention window, in unit of aSlotTime */
+-	u16 bcntsfoff;	/* beacon tsf offset */
+-};
+-
+-/* tx completion callback takes 3 args */
+-typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg);
+-
+-struct pkt_cb {
+-	pkcb_fn_t fn;		/* function to call when tx frame completes */
+-	void *arg;		/* void arg for fn */
+-	u8 nextidx;		/* index of next call back if threading */
+-	bool entered;		/* recursion check */
+-};
+-
+-/* module control blocks */
+-struct modulecb {
+-	char name[32];		/* module name : NULL indicates empty array member */
+-	const bcm_iovar_t *iovars;	/* iovar table */
+-	void *hdl;		/* handle passed when handler 'doiovar' is called */
+-	watchdog_fn_t watchdog_fn;	/* watchdog handler */
+-	iovar_fn_t iovar_fn;	/* iovar handler */
+-	down_fn_t down_fn;	/* down handler. Note: the int returned
+-				 * by the down function is a count of the
+-				 * number of timers that could not be
+-				 * freed.
+-				 */
+-};
+-
+-/* dump control blocks */
+-struct dumpcb_s {
+-	const char *name;	/* dump name */
+-	dump_fn_t dump_fn;	/* 'wl dump' handler */
+-	void *dump_fn_arg;
+-	struct dumpcb_s *next;
+-};
+-
+-/* virtual interface */
+-struct wlc_if {
+-	struct wlc_if *next;
+-	u8 type;		/* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */
+-	u8 index;		/* assigned in wl_add_if(), index of the wlif if any,
+-				 * not necessarily corresponding to bsscfg._idx or
+-				 * AID2PVBMAP(scb).
+-				 */
+-	u8 flags;		/* flags for the interface */
+-	struct wl_if *wlif;		/* pointer to wlif */
+-	struct wlc_txq_info *qi;	/* pointer to associated tx queue */
+-	union {
+-		struct scb *scb;	/* pointer to scb if WLC_IFTYPE_WDS */
+-		struct wlc_bsscfg *bsscfg;	/* pointer to bsscfg if WLC_IFTYPE_BSS */
+-	} u;
+-};
+-
+-/* flags for the interface */
+-#define WLC_IF_LINKED		0x02	/* this interface is linked to a wl_if */
+-
+-struct wlc_hwband {
+-	int bandtype;		/* WLC_BAND_2G, WLC_BAND_5G */
+-	uint bandunit;		/* bandstate[] index */
+-	u16 mhfs[MHFMAX];	/* MHF array shadow */
+-	u8 bandhw_stf_ss_mode;	/* HW configured STF type, 0:siso; 1:cdd */
+-	u16 CWmin;
+-	u16 CWmax;
+-	u32 core_flags;
+-
+-	u16 phytype;		/* phytype */
+-	u16 phyrev;
+-	u16 radioid;
+-	u16 radiorev;
+-	wlc_phy_t *pi;		/* pointer to phy specific information */
+-	bool abgphy_encore;
+-};
+-
+-struct wlc_hw_info {
+-	bool _piomode;		/* true if pio mode */
+-	struct wlc_info *wlc;
+-
+-	/* fifo */
+-	struct hnddma_pub *di[NFIFO];	/* hnddma handles, per fifo */
+-
+-	uint unit;		/* device instance number */
+-
+-	/* version info */
+-	u16 vendorid;	/* PCI vendor id */
+-	u16 deviceid;	/* PCI device id */
+-	uint corerev;		/* core revision */
+-	u8 sromrev;		/* version # of the srom */
+-	u16 boardrev;	/* version # of particular board */
+-	u32 boardflags;	/* Board specific flags from srom */
+-	u32 boardflags2;	/* More board flags if sromrev >= 4 */
+-	u32 machwcap;	/* MAC capabilities */
+-	u32 machwcap_backup;	/* backup of machwcap */
+-	u16 ucode_dbgsel;	/* dbgsel for ucode debug(config gpio) */
+-
+-	si_t *sih;		/* SB handle (cookie for siutils calls) */
+-	char *vars;		/* "environment" name=value */
+-	uint vars_size;		/* size of vars, free vars on detach */
+-	d11regs_t *regs;	/* pointer to device registers */
+-	void *physhim;		/* phy shim layer handler */
+-	void *phy_sh;		/* pointer to shared phy state */
+-	struct wlc_hwband *band;/* pointer to active per-band state */
+-	struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */
+-	u16 bmac_phytxant;	/* cache of high phytxant state */
+-	bool shortslot;		/* currently using 11g ShortSlot timing */
+-	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
+-	u16 LRL;		/* 802.11 dot11LongRetryLimit */
+-	u16 SFBL;		/* Short Frame Rate Fallback Limit */
+-	u16 LFBL;		/* Long Frame Rate Fallback Limit */
+-
+-	bool up;		/* d11 hardware up and running */
+-	uint now;		/* # elapsed seconds */
+-	uint _nbands;		/* # bands supported */
+-	chanspec_t chanspec;	/* bmac chanspec shadow */
+-
+-	uint *txavail[NFIFO];	/* # tx descriptors available */
+-	u16 *xmtfifo_sz;	/* fifo size in 256B for each xmt fifo */
+-
+-	mbool pllreq;		/* pll requests to keep PLL on */
+-
+-	u8 suspended_fifos;	/* Which TX fifo to remain awake for */
+-	u32 maccontrol;	/* Cached value of maccontrol */
+-	uint mac_suspend_depth;	/* current depth of mac_suspend levels */
+-	u32 wake_override;	/* Various conditions to force MAC to WAKE mode */
+-	u32 mute_override;	/* Prevent ucode from sending beacons */
+-	u8 etheraddr[ETH_ALEN];	/* currently configured ethernet address */
+-	u32 led_gpio_mask;	/* LED GPIO Mask */
+-	bool noreset;		/* true= do not reset hw, used by WLC_OUT */
+-	bool forcefastclk;	/* true if the h/w is forcing the use of fast clk */
+-	bool clk;		/* core is out of reset and has clock */
+-	bool sbclk;		/* sb has clock */
+-	struct bmac_pmq *bmac_pmq; /*  bmac PM states derived from ucode PMQ */
+-	bool phyclk;		/* phy is out of reset and has clock */
+-	bool dma_lpbk;		/* core is in DMA loopback */
+-
+-	bool ucode_loaded;	/* true after ucode downloaded */
+-
+-
+-	u8 hw_stf_ss_opmode;	/* STF single stream operation mode */
+-	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
+-				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+-				 */
+-	u32 antsel_avail;	/*
+-				 * put struct antsel_info here if more info is
+-				 * needed
+-				 */
+-};
+-
+-/* TX Queue information
+- *
+- * Each flow of traffic out of the device has a TX Queue with independent
+- * flow control. Several interfaces may be associated with a single TX Queue
+- * if they belong to the same flow of traffic from the device. For multi-channel
+- * operation there are independent TX Queues for each channel.
+- */
+-struct wlc_txq_info {
+-	struct wlc_txq_info *next;
+-	struct pktq q;
+-	uint stopped;		/* tx flow control bits */
+-};
+-
+-/*
+- * Principal common (os-independent) software data structure.
+- */
+-struct wlc_info {
+-	struct wlc_pub *pub;		/* pointer to wlc public state */
+-	struct wl_info *wl;	/* pointer to os-specific private state */
+-	d11regs_t *regs;	/* pointer to device registers */
+-
+-	struct wlc_hw_info *hw;	/* HW related state used primarily by BMAC */
+-
+-	/* clock */
+-	int clkreq_override;	/* setting for clkreq for PCIE : Auto, 0, 1 */
+-	u16 fastpwrup_dly;	/* time in us needed to bring up d11 fast clock */
+-
+-	/* interrupt */
+-	u32 macintstatus;	/* bit channel between isr and dpc */
+-	u32 macintmask;	/* sw runtime master macintmask value */
+-	u32 defmacintmask;	/* default "on" macintmask value */
+-
+-	/* up and down */
+-	bool device_present;	/* (removable) device is present */
+-
+-	bool clk;		/* core is out of reset and has clock */
+-
+-	/* multiband */
+-	struct wlccore *core;	/* pointer to active io core */
+-	struct wlcband *band;	/* pointer to active per-band state */
+-	struct wlccore *corestate;	/* per-core state (one per hw core) */
+-	/* per-band state (one per phy/radio): */
+-	struct wlcband *bandstate[MAXBANDS];
+-
+-	bool war16165;		/* PCI slow clock 16165 war flag */
+-
+-	bool tx_suspended;	/* data fifos need to remain suspended */
+-
+-	uint txpend16165war;
+-
+-	/* packet queue */
+-	uint qvalid;		/* DirFrmQValid and BcMcFrmQValid */
+-
+-	/* Regulatory power limits */
+-	s8 txpwr_local_max;	/* regulatory local txpwr max */
+-	u8 txpwr_local_constraint;	/* local power contraint in dB */
+-
+-
+-	struct ampdu_info *ampdu;	/* ampdu module handler */
+-	struct antsel_info *asi;	/* antsel module handler */
+-	wlc_cm_info_t *cmi;	/* channel manager module handler */
+-
+-	void *btparam;		/* bus type specific cookie */
+-
+-	uint vars_size;		/* size of vars, free vars on detach */
+-
+-	u16 vendorid;	/* PCI vendor id */
+-	u16 deviceid;	/* PCI device id */
+-	uint ucode_rev;		/* microcode revision */
+-
+-	u32 machwcap;	/* MAC capabilities, BMAC shadow */
+-
+-	u8 perm_etheraddr[ETH_ALEN];	/* original sprom local ethernet address */
+-
+-	bool bandlocked;	/* disable auto multi-band switching */
+-	bool bandinit_pending;	/* track band init in auto band */
+-
+-	bool radio_monitor;	/* radio timer is running */
+-	bool down_override;	/* true=down */
+-	bool going_down;	/* down path intermediate variable */
+-
+-	bool mpc;		/* enable minimum power consumption */
+-	u8 mpc_dlycnt;	/* # of watchdog cnt before turn disable radio */
+-	u8 mpc_offcnt;	/* # of watchdog cnt that radio is disabled */
+-	u8 mpc_delay_off;	/* delay radio disable by # of watchdog cnt */
+-	u8 prev_non_delay_mpc;	/* prev state wlc_is_non_delay_mpc */
+-
+-	/* timer */
+-	struct wl_timer *wdtimer;	/* timer for watchdog routine */
+-	uint fast_timer;	/* Periodic timeout for 'fast' timer */
+-	uint slow_timer;	/* Periodic timeout for 'slow' timer */
+-	uint glacial_timer;	/* Periodic timeout for 'glacial' timer */
+-	uint phycal_mlo;	/* last time measurelow calibration was done */
+-	uint phycal_txpower;	/* last time txpower calibration was done */
+-
+-	struct wl_timer *radio_timer;	/* timer for hw radio button monitor routine */
+-	struct wl_timer *pspoll_timer;	/* periodic pspoll timer */
+-
+-	/* promiscuous */
+-	bool monitor;		/* monitor (MPDU sniffing) mode */
+-	bool bcnmisc_ibss;	/* bcns promisc mode override for IBSS */
+-	bool bcnmisc_scan;	/* bcns promisc mode override for scan */
+-	bool bcnmisc_monitor;	/* bcns promisc mode override for monitor */
+-
+-	u8 bcn_wait_prd;	/* max waiting period (for beacon) in 1024TU */
+-
+-	/* driver feature */
+-	bool _rifs;		/* enable per-packet rifs */
+-	s32 rifs_advert;	/* RIFS mode advertisement */
+-	s8 sgi_tx;		/* sgi tx */
+-	bool wet;		/* true if wireless ethernet bridging mode */
+-
+-	/* AP-STA synchronization, power save */
+-	bool check_for_unaligned_tbtt;	/* check unaligned tbtt flag */
+-	bool PM_override;	/* no power-save flag, override PM(user input) */
+-	bool PMenabled;		/* current power-management state (CAM or PS) */
+-	bool PMpending;		/* waiting for tx status with PM indicated set */
+-	bool PMblocked;		/* block any PSPolling in PS mode, used to buffer
+-				 * AP traffic, also used to indicate in progress
+-				 * of scan, rm, etc. off home channel activity.
+-				 */
+-	bool PSpoll;		/* whether there is an outstanding PS-Poll frame */
+-	u8 PM;		/* power-management mode (CAM, PS or FASTPS) */
+-	bool PMawakebcn;	/* bcn recvd during current waking state */
+-
+-	bool WME_PM_blocked;	/* Can STA go to PM when in WME Auto mode */
+-	bool wake;		/* host-specified PS-mode sleep state */
+-	u8 pspoll_prd;	/* pspoll interval in milliseconds */
+-	u8 bcn_li_bcn;	/* beacon listen interval in # beacons */
+-	u8 bcn_li_dtim;	/* beacon listen interval in # dtims */
+-
+-	bool WDarmed;		/* watchdog timer is armed */
+-	u32 WDlast;		/* last time wlc_watchdog() was called */
+-
+-	/* WME */
+-	ac_bitmap_t wme_dp;	/* Discard (oldest first) policy per AC */
+-	bool wme_apsd;		/* enable Advanced Power Save Delivery */
+-	ac_bitmap_t wme_admctl;	/* bit i set if AC i under admission control */
+-	u16 edcf_txop[AC_COUNT];	/* current txop for each ac */
+-	wme_param_ie_t wme_param_ie;	/* WME parameter info element, which on STA
+-					 * contains parameters in use locally, and on
+-					 * AP contains parameters advertised to STA
+-					 * in beacons and assoc responses.
+-					 */
+-	bool wme_prec_queuing;	/* enable/disable non-wme STA prec queuing */
+-	u16 wme_retries[AC_COUNT];	/* per-AC retry limits */
+-
+-	int vlan_mode;		/* OK to use 802.1Q Tags (ON, OFF, AUTO) */
+-	u16 tx_prec_map;	/* Precedence map based on HW FIFO space */
+-	u16 fifo2prec_map[NFIFO];	/* pointer to fifo2_prec map based on WME */
+-
+-	/*
+-	 * BSS Configurations set of BSS configurations, idx 0 is default and
+-	 * always valid
+-	 */
+-	struct wlc_bsscfg *bsscfg[WLC_MAXBSSCFG];
+-	struct wlc_bsscfg *cfg;	/* the primary bsscfg (can be AP or STA) */
+-	u8 stas_associated;	/* count of ASSOCIATED STA bsscfgs */
+-	u8 aps_associated;	/* count of UP AP bsscfgs */
+-	u8 block_datafifo;	/* prohibit posting frames to data fifos */
+-	bool bcmcfifo_drain;	/* TX_BCMC_FIFO is set to drain */
+-
+-	/* tx queue */
+-	struct wlc_txq_info *tx_queues;	/* common TX Queue list */
+-
+-	/* security */
+-	wsec_key_t *wsec_keys[WSEC_MAX_KEYS];	/* dynamic key storage */
+-	wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS];	/* default key storage */
+-	bool wsec_swkeys;	/* indicates that all keys should be
+-				 * treated as sw keys (used for debugging)
+-				 */
+-	struct modulecb *modulecb;
+-	struct dumpcb_s *dumpcb_head;
+-
+-	u8 mimoft;		/* SIGN or 11N */
+-	u8 mimo_band_bwcap;	/* bw cap per band type */
+-	s8 txburst_limit_override;	/* tx burst limit override */
+-	u16 txburst_limit;	/* tx burst limit value */
+-	s8 cck_40txbw;	/* 11N, cck tx b/w override when in 40MHZ mode */
+-	s8 ofdm_40txbw;	/* 11N, ofdm tx b/w override when in 40MHZ mode */
+-	s8 mimo_40txbw;	/* 11N, mimo tx b/w override when in 40MHZ mode */
+-	/* HT CAP IE being advertised by this node: */
+-	struct ieee80211_ht_cap ht_cap;
+-
+-	uint seckeys;		/* 54 key table shm address */
+-	uint tkmickeys;		/* 12 TKIP MIC key table shm address */
+-
+-	wlc_bss_info_t *default_bss;	/* configured BSS parameters */
+-
+-	u16 AID;		/* association ID */
+-	u16 counter;		/* per-sdu monotonically increasing counter */
+-	u16 mc_fid_counter;	/* BC/MC FIFO frame ID counter */
+-
+-	bool ibss_allowed;	/* false, all IBSS will be ignored during a scan
+-				 * and the driver will not allow the creation of
+-				 * an IBSS network
+-				 */
+-	bool ibss_coalesce_allowed;
+-
+-	char country_default[WLC_CNTRY_BUF_SZ];	/* saved country for leaving 802.11d
+-						 * auto-country mode
+-						 */
+-	char autocountry_default[WLC_CNTRY_BUF_SZ];	/* initial country for 802.11d
+-							 * auto-country mode
+-							 */
+-#ifdef BCMDBG
+-	bcm_tlv_t *country_ie_override;	/* debug override of announced Country IE */
+-#endif
+-
+-	u16 prb_resp_timeout;	/* do not send prb resp if request older than this,
+-					 * 0 = disable
+-					 */
+-
+-	wlc_rateset_t sup_rates_override;	/* use only these rates in 11g supported rates if
+-						 * specifed
+-						 */
+-
+-	chanspec_t home_chanspec;	/* shared home chanspec */
+-
+-	/* PHY parameters */
+-	chanspec_t chanspec;	/* target operational channel */
+-	u16 usr_fragthresh;	/* user configured fragmentation threshold */
+-	u16 fragthresh[NFIFO];	/* per-fifo fragmentation thresholds */
+-	u16 RTSThresh;	/* 802.11 dot11RTSThreshold */
+-	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
+-	u16 LRL;		/* 802.11 dot11LongRetryLimit */
+-	u16 SFBL;		/* Short Frame Rate Fallback Limit */
+-	u16 LFBL;		/* Long Frame Rate Fallback Limit */
+-
+-	/* network config */
+-	bool shortpreamble;	/* currently operating with CCK ShortPreambles */
+-	bool shortslot;		/* currently using 11g ShortSlot timing */
+-	s8 barker_preamble;	/* current Barker Preamble Mode */
+-	s8 shortslot_override;	/* 11g ShortSlot override */
+-	bool include_legacy_erp;	/* include Legacy ERP info elt ID 47 as well as g ID 42 */
+-	bool barker_overlap_control;	/* true: be aware of overlapping BSSs for barker */
+-	bool ignore_bcns;	/* override: ignore non shortslot bcns in a 11g network */
+-	bool legacy_probe;	/* restricts probe requests to CCK rates */
+-
+-	struct wlc_protection *protection;
+-	s8 PLCPHdr_override;	/* 802.11b Preamble Type override */
+-
+-	struct wlc_stf *stf;
+-
+-	struct pkt_cb *pkt_callback;	/* tx completion callback handlers */
+-
+-	u32 txretried;	/* tx retried number in one msdu */
+-
+-	ratespec_t bcn_rspec;	/* save bcn ratespec purpose */
+-
+-	bool apsd_sta_usp;	/* Unscheduled Service Period in progress on STA */
+-	struct wl_timer *apsd_trigger_timer;	/* timer for wme apsd trigger frames */
+-	u32 apsd_trigger_timeout;	/* timeout value for apsd_trigger_timer (in ms)
+-					 * 0 == disable
+-					 */
+-	ac_bitmap_t apsd_trigger_ac;	/* Permissible Access Category in which APSD Null
+-					 * Trigger frames can be send
+-					 */
+-	u8 htphy_membership;	/* HT PHY membership */
+-
+-	bool _regulatory_domain;	/* 802.11d enabled? */
+-
+-	u8 mimops_PM;
+-
+-	u8 txpwr_percent;	/* power output percentage */
+-
+-	u8 ht_wsec_restriction;	/* the restriction of HT with TKIP or WEP */
+-
+-	uint tempsense_lasttime;
+-
+-	u16 tx_duty_cycle_ofdm;	/* maximum allowed duty cycle for OFDM */
+-	u16 tx_duty_cycle_cck;	/* maximum allowed duty cycle for CCK */
+-
+-	u16 next_bsscfg_ID;
+-
+-	struct wlc_if *wlcif_list;	/* linked list of wlc_if structs */
+-	struct wlc_txq_info *pkt_queue; /* txq for transmit packets */
+-	u32 mpc_dur;		/* total time (ms) in mpc mode except for the
+-				 * portion since radio is turned off last time
+-				 */
+-	u32 mpc_laston_ts;	/* timestamp (ms) when radio is turned off last
+-				 * time
+-				 */
+-	bool pr80838_war;
+-	uint hwrxoff;
+-	struct wiphy *wiphy;
+-};
+-
+-/* antsel module specific state */
+-struct antsel_info {
+-	struct wlc_info *wlc;	/* pointer to main wlc structure */
+-	struct wlc_pub *pub;		/* pointer to public fn */
+-	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
+-				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+-				 */
+-	u8 antsel_antswitch;	/* board level antenna switch type */
+-	bool antsel_avail;	/* Ant selection availability (SROM based) */
+-	wlc_antselcfg_t antcfg_11n;	/* antenna configuration */
+-	wlc_antselcfg_t antcfg_cur;	/* current antenna config (auto) */
+-};
+-
+-#define	CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
+-#define	OTHERBANDUNIT(wlc)	((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
+-
+-#define IS_MBAND_UNLOCKED(wlc) \
+-	((NBANDS(wlc) > 1) && !(wlc)->bandlocked)
+-
+-#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi)
+-
+-/* sum the individual fifo tx pending packet counts */
+-#define	TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \
+-	(wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3])
+-#define TXPKTPENDGET(wlc, fifo)		((wlc)->core->txpktpend[(fifo)])
+-#define TXPKTPENDINC(wlc, fifo, val)	((wlc)->core->txpktpend[(fifo)] += (val))
+-#define TXPKTPENDDEC(wlc, fifo, val)	((wlc)->core->txpktpend[(fifo)] -= (val))
+-#define TXPKTPENDCLR(wlc, fifo)		((wlc)->core->txpktpend[(fifo)] = 0)
+-#define TXAVAIL(wlc, fifo)		(*(wlc)->core->txavail[(fifo)])
+-#define GETNEXTTXP(wlc, _queue)								\
+-		dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED)
+-
+-#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \
+-	((len1 == len2) && !memcmp(ssid1, ssid2, len1))
+-
+-extern void wlc_fatal_error(struct wlc_info *wlc);
+-extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc);
+-extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p);
+-extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2);
+-extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p,
+-		       bool commit, s8 txpktpend);
+-extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend);
+-extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
+-			uint prec);
+-extern void wlc_info_init(struct wlc_info *wlc, int unit);
+-extern void wlc_print_txstatus(tx_status_t *txs);
+-extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks);
+-extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len,
+-				   void *buf);
+-extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
+-				      bool both);
+-extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin);
+-extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax);
+-extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit);
+-extern void wlc_reset_bmac_done(struct wlc_info *wlc);
+-
+-#if defined(BCMDBG)
+-extern void wlc_print_rxh(d11rxhdr_t *rxh);
+-extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame,
+-			   d11txh_t *txh, d11rxhdr_t *rxh, uint len);
+-extern void wlc_print_txdesc(d11txh_t *txh);
+-#else
+-#define wlc_print_txdesc(a)
+-#endif
+-#if defined(BCMDBG)
+-extern void wlc_print_dot11_mac_hdr(u8 *buf, int len);
+-#endif
+-
+-extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit);
+-extern void wlc_coredisable(struct wlc_hw_info *wlc_hw);
+-
+-extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band,
+-			   bool verbose);
+-extern void wlc_ap_upd(struct wlc_info *wlc);
+-
+-/* helper functions */
+-extern void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg);
+-extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config);
+-
+-extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc);
+-extern void wlc_mac_bcn_promisc(struct wlc_info *wlc);
+-extern void wlc_mac_promisc(struct wlc_info *wlc);
+-extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-			      bool on, int prio);
+-extern void wlc_txflowcontrol_override(struct wlc_info *wlc,
+-				       struct wlc_txq_info *qi,
+-				       bool on, uint override);
+-extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc,
+-					 struct wlc_txq_info *qi, int prio);
+-extern void wlc_send_q(struct wlc_info *wlc);
+-extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo);
+-
+-extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec,
+-				uint mac_len);
+-extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec,
+-					 bool use_rspec, u16 mimo_ctlchbw);
+-extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only,
+-				     ratespec_t rts_rate, ratespec_t frame_rate,
+-				     u8 rts_preamble_type,
+-				     u8 frame_preamble_type, uint frame_len,
+-				     bool ba);
+-
+-extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs);
+-extern void wlc_inval_dma_pkts(struct wlc_hw_info *hw,
+-			       struct ieee80211_sta *sta,
+-			       void (*dma_callback_fn));
+-
+-#if defined(BCMDBG)
+-extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie,
+-			struct bcmstrbuf *b);
+-#endif
+-
+-extern void wlc_reprate_init(struct wlc_info *wlc);
+-extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg);
+-
+-/* Shared memory access */
+-extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v);
+-extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset);
+-extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf,
+-			   int len);
+-
+-extern void wlc_update_beacon(struct wlc_info *wlc);
+-extern void wlc_bss_update_beacon(struct wlc_info *wlc,
+-				  struct wlc_bsscfg *bsscfg);
+-
+-extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend);
+-extern void wlc_bss_update_probe_resp(struct wlc_info *wlc,
+-				      struct wlc_bsscfg *cfg, bool suspend);
+-
+-extern bool wlc_ismpc(struct wlc_info *wlc);
+-extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc);
+-extern void wlc_radio_mpc_upd(struct wlc_info *wlc);
+-extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt,
+-			 int prec);
+-extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q,
+-			      struct sk_buff *pkt, int prec, bool head);
+-extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec);
+-extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length,
+-			     u8 *plcp);
+-extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec,
+-				u8 preamble_type, uint mac_len);
+-
+-extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec);
+-
+-extern bool wlc_timers_init(struct wlc_info *wlc, int unit);
+-
+-extern const bcm_iovar_t wlc_iovars[];
+-
+-extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid,
+-		       const char *name, void *params, uint p_len, void *arg,
+-		       int len, int val_size, struct wlc_if *wlcif);
+-
+-#if defined(BCMDBG)
+-extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len);
+-#endif
+-
+-extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode);
+-extern void wlc_mimops_action_ht_send(struct wlc_info *wlc,
+-				      struct wlc_bsscfg *bsscfg,
+-				      u8 mimops_mode);
+-
+-extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot);
+-extern void wlc_set_bssid(struct wlc_bsscfg *cfg);
+-extern void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend);
+-
+-extern void wlc_set_ratetable(struct wlc_info *wlc);
+-extern int wlc_set_mac(struct wlc_bsscfg *cfg);
+-extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc,
+-					  ratespec_t bcn_rate);
+-extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len);
+-extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc,
+-					 wlc_rateset_t *rs);
+-extern void wlc_radio_disable(struct wlc_info *wlc);
+-extern void wlc_bcn_li_upd(struct wlc_info *wlc);
+-
+-extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len);
+-extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec);
+-extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt);
+-extern bool wlc_ps_allowed(struct wlc_info *wlc);
+-extern bool wlc_stay_awake(struct wlc_info *wlc);
+-extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe);
+-
+-#endif				/* _wlc_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
+deleted file mode 100644
+index 16fea02..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
++++ /dev/null
+@@ -1,243 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/*
+- * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer.
+- *   WL driver can optinally call this translation layer to do some preprocessing, then reach PHY.
+- *   On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the
+- *   access to wlc_hw pointer.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbconfig.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-#include <wlc_pmu.h>
+-
+-#include "wlc_types.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "d11.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "bcmsrom.h"
+-#include "wlc_key.h"
+-#include "wlc_bmac.h"
+-#include "wlc_phy_hal.h"
+-#include "wl_export.h"
+-#include "wlc_main.h"
+-#include "wlc_phy_shim.h"
+-
+-/* PHY SHIM module specific state */
+-struct wlc_phy_shim_info {
+-	struct wlc_hw_info *wlc_hw;	/* pointer to main wlc_hw structure */
+-	void *wlc;		/* pointer to main wlc structure */
+-	void *wl;		/* pointer to os-specific private state */
+-};
+-
+-wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw,
+-						       void *wl, void *wlc) {
+-	wlc_phy_shim_info_t *physhim = NULL;
+-
+-	physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC);
+-	if (!physhim) {
+-		wiphy_err(wlc_hw->wlc->wiphy,
+-			  "wl%d: wlc_phy_shim_attach: out of mem\n",
+-			  wlc_hw->unit);
+-		return NULL;
+-	}
+-	physhim->wlc_hw = wlc_hw;
+-	physhim->wlc = wlc;
+-	physhim->wl = wl;
+-
+-	return physhim;
+-}
+-
+-void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim)
+-{
+-	kfree(physhim);
+-}
+-
+-struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+-				     void (*fn) (void *arg), void *arg,
+-				     const char *name)
+-{
+-	return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name);
+-}
+-
+-void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+-{
+-	wl_free_timer(physhim->wl, (struct wl_timer *)t);
+-}
+-
+-void
+-wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms,
+-		int periodic)
+-{
+-	wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic);
+-}
+-
+-bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+-{
+-	return wl_del_timer(physhim->wl, (struct wl_timer *)t);
+-}
+-
+-void wlapi_intrson(wlc_phy_shim_info_t *physhim)
+-{
+-	wl_intrson(physhim->wl);
+-}
+-
+-u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim)
+-{
+-	return wl_intrsoff(physhim->wl);
+-}
+-
+-void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask)
+-{
+-	wl_intrsrestore(physhim->wl, macintmask);
+-}
+-
+-void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v)
+-{
+-	wlc_bmac_write_shm(physhim->wlc_hw, offset, v);
+-}
+-
+-u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset)
+-{
+-	return wlc_bmac_read_shm(physhim->wlc_hw, offset);
+-}
+-
+-void
+-wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask,
+-	       u16 val, int bands)
+-{
+-	wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands);
+-}
+-
+-void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags)
+-{
+-	wlc_bmac_corereset(physhim->wlc_hw, flags);
+-}
+-
+-void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_suspend_mac_and_wait(physhim->wlc);
+-}
+-
+-void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode)
+-{
+-	wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode);
+-}
+-
+-void wlapi_enable_mac(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_enable_mac(physhim->wlc);
+-}
+-
+-void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val)
+-{
+-	wlc_bmac_mctrl(physhim->wlc_hw, mask, val);
+-}
+-
+-void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_bmac_phy_reset(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw)
+-{
+-	wlc_bmac_bw_set(physhim->wlc_hw, bw);
+-}
+-
+-u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim)
+-{
+-	return wlc_bmac_get_txant(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk)
+-{
+-	wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk);
+-}
+-
+-void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk)
+-{
+-	wlc_bmac_macphyclk_set(physhim->wlc_hw, clk);
+-}
+-
+-void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on)
+-{
+-	wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on);
+-}
+-
+-void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_bmac_core_phypll_reset(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG);
+-}
+-
+-void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_ucode_wake_override_clear(physhim->wlc_hw,
+-				      WLC_WAKE_OVERRIDE_PHYREG);
+-}
+-
+-void
+-wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset,
+-			      int len, void *buf)
+-{
+-	wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf);
+-}
+-
+-u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate)
+-{
+-	return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate);
+-}
+-
+-void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim)
+-{
+-}
+-
+-void
+-wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf,
+-		      int len, u32 sel)
+-{
+-	wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
+-}
+-
+-void
+-wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf,
+-		    int l, u32 sel)
+-{
+-	wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
+deleted file mode 100644
+index c151a5d..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
++++ /dev/null
+@@ -1,112 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_shim_h_
+-#define _wlc_phy_shim_h_
+-
+-#define RADAR_TYPE_NONE		0	/* Radar type None */
+-#define RADAR_TYPE_ETSI_1	1	/* ETSI 1 Radar type */
+-#define RADAR_TYPE_ETSI_2	2	/* ETSI 2 Radar type */
+-#define RADAR_TYPE_ETSI_3	3	/* ETSI 3 Radar type */
+-#define RADAR_TYPE_ITU_E	4	/* ITU E Radar type */
+-#define RADAR_TYPE_ITU_K	5	/* ITU K Radar type */
+-#define RADAR_TYPE_UNCLASSIFIED	6	/* Unclassified Radar type  */
+-#define RADAR_TYPE_BIN5		7	/* long pulse radar type */
+-#define RADAR_TYPE_STG2 	8	/* staggered-2 radar */
+-#define RADAR_TYPE_STG3 	9	/* staggered-3 radar */
+-#define RADAR_TYPE_FRA		10	/* French radar */
+-
+-/* French radar pulse widths */
+-#define FRA_T1_20MHZ	52770
+-#define FRA_T2_20MHZ	61538
+-#define FRA_T3_20MHZ	66002
+-#define FRA_T1_40MHZ	105541
+-#define FRA_T2_40MHZ	123077
+-#define FRA_T3_40MHZ	132004
+-#define FRA_ERR_20MHZ	60
+-#define FRA_ERR_40MHZ	120
+-
+-#define ANTSEL_NA		0	/* No boardlevel selection available */
+-#define ANTSEL_2x4		1	/* 2x4 boardlevel selection available */
+-#define ANTSEL_2x3		2	/* 2x3 CB2 boardlevel selection available */
+-
+-/* Rx Antenna diversity control values */
+-#define	ANT_RX_DIV_FORCE_0		0	/* Use antenna 0 */
+-#define	ANT_RX_DIV_FORCE_1		1	/* Use antenna 1 */
+-#define	ANT_RX_DIV_START_1		2	/* Choose starting with 1 */
+-#define	ANT_RX_DIV_START_0		3	/* Choose starting with 0 */
+-#define	ANT_RX_DIV_ENABLE		3	/* APHY bbConfig Enable RX Diversity */
+-#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0	/* default antdiv setting */
+-
+-/* Forward declarations */
+-struct wlc_hw_info;
+-typedef struct wlc_phy_shim_info wlc_phy_shim_info_t;
+-
+-extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw,
+-						void *wl, void *wlc);
+-extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim);
+-
+-/* PHY to WL utility functions */
+-struct wlapi_timer;
+-extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+-					    void (*fn) (void *arg), void *arg,
+-					    const char *name);
+-extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim,
+-			     struct wlapi_timer *t);
+-extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim,
+-			    struct wlapi_timer *t, uint ms, int periodic);
+-extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim,
+-			    struct wlapi_timer *t);
+-extern void wlapi_intrson(wlc_phy_shim_info_t *physhim);
+-extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim,
+-			       u32 macintmask);
+-
+-extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset,
+-				 u16 v);
+-extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset);
+-extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx,
+-			   u16 mask, u16 val, int bands);
+-extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags);
+-extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode);
+-extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask,
+-			     u32 val);
+-extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw);
+-extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk);
+-extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk);
+-extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on);
+-extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *
+-						      physhim);
+-extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *
+-							physhim);
+-extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o,
+-					  int len, void *buf);
+-extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim,
+-					 u8 rate);
+-extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint,
+-				  void *buf, int, u32 sel);
+-extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint,
+-				const void *buf, int, u32);
+-
+-extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim,
+-				       u32 phy_mode);
+-extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim);
+-#endif				/* _wlc_phy_shim_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
+deleted file mode 100644
+index 82986bd..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
++++ /dev/null
+@@ -1,1929 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/delay.h>
+-#include <linux/io.h>
+-
+-#include <bcmdevs.h>
+-#include <sbchipc.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include "wlc_pmu.h"
+-
+-/*
+- * d11 slow to fast clock transition time in slow clock cycles
+- */
+-#define D11SCC_SLOW2FAST_TRANSITION	2
+-
+-/*
+- * external LPO crystal frequency
+- */
+-#define EXT_ILP_HZ 32768
+-
+-/*
+- * Duration for ILP clock frequency measurment in milliseconds
+- *
+- * remark: 1000 must be an integer multiple of this duration
+- */
+-#define ILP_CALC_DUR	10
+-
+-/*
+- * FVCO frequency
+- */
+-#define FVCO_880	880000	/* 880MHz */
+-#define FVCO_1760	1760000	/* 1760MHz */
+-#define FVCO_1440	1440000	/* 1440MHz */
+-#define FVCO_960	960000	/* 960MHz */
+-
+-/*
+- * PMU crystal table indices for 1440MHz fvco
+- */
+-#define PMU1_XTALTAB0_1440_12000K	0
+-#define PMU1_XTALTAB0_1440_13000K	1
+-#define PMU1_XTALTAB0_1440_14400K	2
+-#define PMU1_XTALTAB0_1440_15360K	3
+-#define PMU1_XTALTAB0_1440_16200K	4
+-#define PMU1_XTALTAB0_1440_16800K	5
+-#define PMU1_XTALTAB0_1440_19200K	6
+-#define PMU1_XTALTAB0_1440_19800K	7
+-#define PMU1_XTALTAB0_1440_20000K	8
+-#define PMU1_XTALTAB0_1440_25000K	9
+-#define PMU1_XTALTAB0_1440_26000K	10
+-#define PMU1_XTALTAB0_1440_30000K	11
+-#define PMU1_XTALTAB0_1440_37400K	12
+-#define PMU1_XTALTAB0_1440_38400K	13
+-#define PMU1_XTALTAB0_1440_40000K	14
+-#define PMU1_XTALTAB0_1440_48000K	15
+-
+-/*
+- * PMU crystal table indices for 960MHz fvco
+- */
+-#define PMU1_XTALTAB0_960_12000K	0
+-#define PMU1_XTALTAB0_960_13000K	1
+-#define PMU1_XTALTAB0_960_14400K	2
+-#define PMU1_XTALTAB0_960_15360K	3
+-#define PMU1_XTALTAB0_960_16200K	4
+-#define PMU1_XTALTAB0_960_16800K	5
+-#define PMU1_XTALTAB0_960_19200K	6
+-#define PMU1_XTALTAB0_960_19800K	7
+-#define PMU1_XTALTAB0_960_20000K	8
+-#define PMU1_XTALTAB0_960_25000K	9
+-#define PMU1_XTALTAB0_960_26000K	10
+-#define PMU1_XTALTAB0_960_30000K	11
+-#define PMU1_XTALTAB0_960_37400K	12
+-#define PMU1_XTALTAB0_960_38400K	13
+-#define PMU1_XTALTAB0_960_40000K	14
+-#define PMU1_XTALTAB0_960_48000K	15
+-
+-/*
+- * PMU crystal table indices for 880MHz fvco
+- */
+-#define PMU1_XTALTAB0_880_12000K	0
+-#define PMU1_XTALTAB0_880_13000K	1
+-#define PMU1_XTALTAB0_880_14400K	2
+-#define PMU1_XTALTAB0_880_15360K	3
+-#define PMU1_XTALTAB0_880_16200K	4
+-#define PMU1_XTALTAB0_880_16800K	5
+-#define PMU1_XTALTAB0_880_19200K	6
+-#define PMU1_XTALTAB0_880_19800K	7
+-#define PMU1_XTALTAB0_880_20000K	8
+-#define PMU1_XTALTAB0_880_24000K	9
+-#define PMU1_XTALTAB0_880_25000K	10
+-#define PMU1_XTALTAB0_880_26000K	11
+-#define PMU1_XTALTAB0_880_30000K	12
+-#define PMU1_XTALTAB0_880_37400K	13
+-#define PMU1_XTALTAB0_880_38400K	14
+-#define PMU1_XTALTAB0_880_40000K	15
+-
+-/*
+- * crystal frequency values
+- */
+-#define XTAL_FREQ_24000MHZ		24000
+-#define XTAL_FREQ_30000MHZ		30000
+-#define XTAL_FREQ_37400MHZ		37400
+-#define XTAL_FREQ_48000MHZ		48000
+-
+-/*
+- * Resource dependancies mask change action
+- *
+- * @RES_DEPEND_SET: Override the dependancies mask
+- * @RES_DEPEND_ADD: Add to the  dependancies mask
+- * @RES_DEPEND_REMOVE: Remove from the dependancies mask
+- */
+-#define RES_DEPEND_SET		0
+-#define RES_DEPEND_ADD		1
+-#define RES_DEPEND_REMOVE	-1
+-
+-/* d11 slow to fast clock transition time in slow clock cycles */
+-#define D11SCC_SLOW2FAST_TRANSITION	2
+-
+-/* Setup resource up/down timers */
+-typedef struct {
+-	u8 resnum;
+-	u16 updown;
+-} pmu_res_updown_t;
+-
+-/* Change resource dependancies masks */
+-typedef struct {
+-	u32 res_mask;	/* resources (chip specific) */
+-	s8 action;		/* action */
+-	u32 depend_mask;	/* changes to the dependancies mask */
+-	 bool(*filter) (si_t *sih);	/* action is taken when filter is NULL or return true */
+-} pmu_res_depend_t;
+-
+-/* setup pll and query clock speed */
+-typedef struct {
+-	u16 fref;
+-	u8 xf;
+-	u8 p1div;
+-	u8 p2div;
+-	u8 ndiv_int;
+-	u32 ndiv_frac;
+-} pmu1_xtaltab0_t;
+-
+-/*
+- * prototypes used in resource tables
+- */
+-static bool si_pmu_res_depfltr_bb(si_t *sih);
+-static bool si_pmu_res_depfltr_ncb(si_t *sih);
+-static bool si_pmu_res_depfltr_paldo(si_t *sih);
+-static bool si_pmu_res_depfltr_npaldo(si_t *sih);
+-
+-static const pmu_res_updown_t bcm4328a0_res_updown[] = {
+-	{
+-	RES4328_EXT_SWITCHER_PWM, 0x0101}, {
+-	RES4328_BB_SWITCHER_PWM, 0x1f01}, {
+-	RES4328_BB_SWITCHER_BURST, 0x010f}, {
+-	RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
+-	RES4328_ILP_REQUEST, 0x0202}, {
+-	RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
+-	RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
+-	RES4328_ROM_SWITCH, 0x0101}, {
+-	RES4328_PA_REF_LDO, 0x0f01}, {
+-	RES4328_RADIO_LDO, 0x0f01}, {
+-	RES4328_AFE_LDO, 0x0f01}, {
+-	RES4328_PLL_LDO, 0x0f01}, {
+-	RES4328_BG_FILTBYP, 0x0101}, {
+-	RES4328_TX_FILTBYP, 0x0101}, {
+-	RES4328_RX_FILTBYP, 0x0101}, {
+-	RES4328_XTAL_PU, 0x0101}, {
+-	RES4328_XTAL_EN, 0xa001}, {
+-	RES4328_BB_PLL_FILTBYP, 0x0101}, {
+-	RES4328_RF_PLL_FILTBYP, 0x0101}, {
+-	RES4328_BB_PLL_PU, 0x0701}
+-};
+-
+-static const pmu_res_depend_t bcm4328a0_res_depend[] = {
+-	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
+-	{
+-	PMURES_BIT(RES4328_ILP_REQUEST),
+-		    RES_DEPEND_SET,
+-		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
+-		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
+-	{
+-	RES4325_HT_AVAIL, 0x0300}, {
+-	RES4325_BBPLL_PWRSW_PU, 0x0101}, {
+-	RES4325_RFPLL_PWRSW_PU, 0x0101}, {
+-	RES4325_ALP_AVAIL, 0x0100}, {
+-	RES4325_XTAL_PU, 0x1000}, {
+-	RES4325_LNLDO1_PU, 0x0800}, {
+-	RES4325_CLDO_CBUCK_PWM, 0x0101}, {
+-	RES4325_CBUCK_PWM, 0x0803}
+-};
+-
+-static const pmu_res_updown_t bcm4325a0_res_updown[] = {
+-	{
+-	RES4325_XTAL_PU, 0x1501}
+-};
+-
+-static const pmu_res_depend_t bcm4325a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - remove BB BURST */
+-	{
+-	PMURES_BIT(RES4325_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
+-	    /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
+-	{
+-	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
+-		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4325_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
+-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+-	{
+-	PMURES_BIT(RES4325_ILP_REQUEST) |
+-		    PMURES_BIT(RES4325_ABUCK_BURST) |
+-		    PMURES_BIT(RES4325_ABUCK_PWM) |
+-		    PMURES_BIT(RES4325_LNLDO1_PU) |
+-		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
+-		    PMURES_BIT(RES4325_XTAL_PU) |
+-		    PMURES_BIT(RES4325_ALP_AVAIL) |
+-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
+-		    PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+-};
+-
+-static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
+-	{
+-	RES4315_HT_AVAIL, 0x0101}, {
+-	RES4315_XTAL_PU, 0x0100}, {
+-	RES4315_LNLDO1_PU, 0x0100}, {
+-	RES4315_PALDO_PU, 0x0100}, {
+-	RES4315_CLDO_PU, 0x0100}, {
+-	RES4315_CBUCK_PWM, 0x0100}, {
+-	RES4315_CBUCK_BURST, 0x0100}, {
+-	RES4315_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4315a0_res_updown[] = {
+-	{
+-	RES4315_XTAL_PU, 0x2501}
+-};
+-
+-static const pmu_res_depend_t bcm4315a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+-	{
+-	PMURES_BIT(RES4315_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
+-	    /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
+-	{
+-	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4315_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
+-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+-	{
+-	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
+-		    PMURES_BIT(RES4315_LNLDO1_PU) |
+-		    PMURES_BIT(RES4315_OTP_PU) |
+-		    PMURES_BIT(RES4315_LNLDO2_PU) |
+-		    PMURES_BIT(RES4315_XTAL_PU) |
+-		    PMURES_BIT(RES4315_ALP_AVAIL) |
+-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4315_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4315_CBUCK_BURST) |
+-		    PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+-};
+-
+-	/* 4329 specific. needs to come back this issue later */
+-static const pmu_res_updown_t bcm4329_res_updown[] = {
+-	{
+-	RES4329_XTAL_PU, 0x1501}
+-};
+-
+-static const pmu_res_depend_t bcm4329_res_depend[] = {
+-	/* Adjust HT Avail resource dependencies */
+-	{
+-	PMURES_BIT(RES4329_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4329_CBUCK_BURST) |
+-		    PMURES_BIT(RES4329_CBUCK_PWM) |
+-		    PMURES_BIT(RES4329_CLDO_PU) |
+-		    PMURES_BIT(RES4329_PALDO_PU) |
+-		    PMURES_BIT(RES4329_LNLDO1_PU) |
+-		    PMURES_BIT(RES4329_XTAL_PU) |
+-		    PMURES_BIT(RES4329_ALP_AVAIL) |
+-		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
+-	{
+-	RES4319_HT_AVAIL, 0x0101}, {
+-	RES4319_XTAL_PU, 0x0100}, {
+-	RES4319_LNLDO1_PU, 0x0100}, {
+-	RES4319_PALDO_PU, 0x0100}, {
+-	RES4319_CLDO_PU, 0x0100}, {
+-	RES4319_CBUCK_PWM, 0x0100}, {
+-	RES4319_CBUCK_BURST, 0x0100}, {
+-	RES4319_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4319a0_res_updown[] = {
+-	{
+-	RES4319_XTAL_PU, 0x3f01}
+-};
+-
+-static const pmu_res_depend_t bcm4319a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+-	{
+-	PMURES_BIT(RES4319_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
+-	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
+-	{
+-	PMURES_BIT(RES4319_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4319_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
+-	{
+-	RES4336_HT_AVAIL, 0x0101}, {
+-	RES4336_XTAL_PU, 0x0100}, {
+-	RES4336_CLDO_PU, 0x0100}, {
+-	RES4336_CBUCK_PWM, 0x0100}, {
+-	RES4336_CBUCK_BURST, 0x0100}, {
+-	RES4336_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4336a0_res_updown[] = {
+-	{
+-	RES4336_HT_AVAIL, 0x0D01}
+-};
+-
+-static const pmu_res_depend_t bcm4336a0_res_depend[] = {
+-	/* Just a dummy entry for now */
+-	{
+-	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
+-	{
+-	RES4330_HT_AVAIL, 0x0101}, {
+-	RES4330_XTAL_PU, 0x0100}, {
+-	RES4330_CLDO_PU, 0x0100}, {
+-	RES4330_CBUCK_PWM, 0x0100}, {
+-	RES4330_CBUCK_BURST, 0x0100}, {
+-	RES4330_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4330a0_res_updown[] = {
+-	{
+-	RES4330_HT_AVAIL, 0x0e02}
+-};
+-
+-static const pmu_res_depend_t bcm4330a0_res_depend[] = {
+-	/* Just a dummy entry for now */
+-	{
+-	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
+-};
+-
+-/* the following table is based on 1440Mhz fvco */
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
+-	{
+-	12000, 1, 1, 1, 0x78, 0x0}, {
+-	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
+-	14400, 3, 1, 1, 0x64, 0x0}, {
+-	15360, 4, 1, 1, 0x5D, 0xC00000}, {
+-	16200, 5, 1, 1, 0x58, 0xE38E38}, {
+-	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
+-	19200, 7, 1, 1, 0x4B, 0}, {
+-	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
+-	20000, 9, 1, 1, 0x48, 0x0}, {
+-	25000, 10, 1, 1, 0x39, 0x999999}, {
+-	26000, 11, 1, 1, 0x37, 0x627627}, {
+-	30000, 12, 1, 1, 0x30, 0x0}, {
+-	37400, 13, 2, 1, 0x4D, 0x15E76}, {
+-	38400, 13, 2, 1, 0x4B, 0x0}, {
+-	40000, 14, 2, 1, 0x48, 0x0}, {
+-	48000, 15, 2, 1, 0x3c, 0x0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
+-	{
+-	12000, 1, 1, 1, 0x50, 0x0}, {
+-	13000, 2, 1, 1, 0x49, 0xD89D89}, {
+-	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
+-	15360, 4, 1, 1, 0x3E, 0x800000}, {
+-	16200, 5, 1, 1, 0x39, 0x425ED0}, {
+-	16800, 6, 1, 1, 0x39, 0x249249}, {
+-	19200, 7, 1, 1, 0x32, 0x0}, {
+-	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
+-	20000, 9, 1, 1, 0x30, 0x0}, {
+-	25000, 10, 1, 1, 0x26, 0x666666}, {
+-	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
+-	30000, 12, 1, 1, 0x20, 0x0}, {
+-	37400, 13, 2, 1, 0x33, 0x563EF9}, {
+-	38400, 14, 2, 1, 0x32, 0x0}, {
+-	40000, 15, 2, 1, 0x30, 0x0}, {
+-	48000, 16, 2, 1, 0x28, 0x0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
+-	{
+-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+-	13000, 2, 1, 6, 0xb, 0x483483}, {
+-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+-	15360, 4, 1, 5, 0xb, 0x755555}, {
+-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+-	19200, 7, 1, 4, 0xb, 0x755555}, {
+-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+-	20000, 9, 1, 11, 0x4, 0x0}, {
+-	24000, 10, 3, 11, 0xa, 0x0}, {
+-	25000, 11, 5, 16, 0xb, 0x0}, {
+-	26000, 12, 1, 1, 0x21, 0xD89D89}, {
+-	30000, 13, 3, 8, 0xb, 0x0}, {
+-	37400, 14, 3, 1, 0x46, 0x969696}, {
+-	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
+-	40000, 16, 1, 2, 0xb, 0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-/* the following table is based on 880Mhz fvco */
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
+-	{
+-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+-	13000, 2, 1, 6, 0xb, 0x483483}, {
+-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+-	15360, 4, 1, 5, 0xb, 0x755555}, {
+-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+-	19200, 7, 1, 4, 0xb, 0x755555}, {
+-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+-	20000, 9, 1, 11, 0x4, 0x0}, {
+-	24000, 10, 3, 11, 0xa, 0x0}, {
+-	25000, 11, 5, 16, 0xb, 0x0}, {
+-	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
+-	30000, 13, 3, 8, 0xb, 0x0}, {
+-	33600, 14, 1, 2, 0xd, 0x186186}, {
+-	38400, 15, 1, 2, 0xb, 0x755555}, {
+-	40000, 16, 1, 2, 0xb, 0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-/* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
+-static bool si_pmu_res_depfltr_bb(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_BUCKBOOST) != 0;
+-}
+-
+-/* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
+-static bool si_pmu_res_depfltr_ncb(si_t *sih)
+-{
+-
+-	return (sih->boardflags & BFL_NOCBUCK) != 0;
+-}
+-
+-/* true if the power topology uses the PALDO */
+-static bool si_pmu_res_depfltr_paldo(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_PALDO) != 0;
+-}
+-
+-/* true if the power topology doesn't use the PALDO */
+-static bool si_pmu_res_depfltr_npaldo(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_PALDO) == 0;
+-}
+-
+-/* Return dependancies (direct or all/indirect) for the given resources */
+-static u32
+-si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
+-		bool all)
+-{
+-	u32 deps = 0;
+-	u32 i;
+-
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(rsrcs & PMURES_BIT(i)))
+-			continue;
+-		W_REG(&cc->res_table_sel, i);
+-		deps |= R_REG(&cc->res_dep_mask);
+-	}
+-
+-	return !all ? deps : (deps
+-			      ? (deps |
+-				 si_pmu_res_deps(sih, cc, deps,
+-						 true)) : 0);
+-}
+-
+-/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
+-static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
+-{
+-	u32 min_mask = 0, max_mask = 0;
+-	uint rsrcs;
+-	char *val;
+-
+-	/* # resources */
+-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+-
+-	/* determine min/max rsrc masks */
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		/* ??? */
+-		break;
+-
+-	case BCM4329_CHIP_ID:
+-		/* 4329 spedific issue. Needs to come back this issue later */
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4329_CLDO_PU);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0x3ff63e;
+-		break;
+-	case BCM4319_CHIP_ID:
+-		/* We only need a few resources to be kept on all the time */
+-		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4319_CLDO_PU);
+-
+-		/* Allow everything else to be turned on upon requests */
+-		max_mask = ~(~0 << rsrcs);
+-		break;
+-	case BCM4336_CHIP_ID:
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
+-		    | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
+-		    | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0x1ffffff;
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
+-		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
+-		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0xfffffff;
+-		break;
+-
+-	case BCM4313_CHIP_ID:
+-		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
+-		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
+-		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
+-		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
+-		max_mask = 0xffff;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Apply nvram override to min mask */
+-	val = getvar(NULL, "rmin");
+-	if (val != NULL) {
+-		min_mask = (u32) simple_strtoul(val, NULL, 0);
+-	}
+-	/* Apply nvram override to max mask */
+-	val = getvar(NULL, "rmax");
+-	if (val != NULL) {
+-		max_mask = (u32) simple_strtoul(val, NULL, 0);
+-	}
+-
+-	*pmin = min_mask;
+-	*pmax = max_mask;
+-}
+-
+-/* Return up time in ILP cycles for the given resource. */
+-static uint
+-si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
+-	u32 deps;
+-	uint up, i, dup, dmax;
+-	u32 min_mask = 0, max_mask = 0;
+-
+-	/* uptime of resource 'rsrc' */
+-	W_REG(&cc->res_table_sel, rsrc);
+-	up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
+-
+-	/* direct dependancies of resource 'rsrc' */
+-	deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(deps & PMURES_BIT(i)))
+-			continue;
+-		deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
+-	}
+-	si_pmu_res_masks(sih, &min_mask, &max_mask);
+-	deps &= ~min_mask;
+-
+-	/* max uptime of direct dependancies */
+-	dmax = 0;
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(deps & PMURES_BIT(i)))
+-			continue;
+-		dup = si_pmu_res_uptime(sih, cc, (u8) i);
+-		if (dmax < dup)
+-			dmax = dup;
+-	}
+-
+-	return up + dmax + PMURES_UP_TRANSITION;
+-}
+-
+-static void
+-si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
+-{
+-	u32 tmp = 0;
+-	u8 phypll_offset = 0;
+-	u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
+-	u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
+-
+-	switch (sih->chip) {
+-	case BCM5357_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-
+-		/*
+-		 * BCM5357 needs to touch PLL1_PLLCTL[02],
+-		 * so offset PLL0_PLLCTL[02] by 6
+-		 */
+-		phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
+-
+-		/* RMW only the P1 divider */
+-		W_REG(&cc->pllcontrol_addr,
+-		      PMU1_PLL0_PLLCTL0 + phypll_offset);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
+-		tmp |=
+-		    (bcm5357_bcm43236_p1div[spuravoid] <<
+-		     PMU1_PLL0_PC0_P1DIV_SHIFT);
+-		W_REG(&cc->pllcontrol_data, tmp);
+-
+-		/* RMW only the int feedback divider */
+-		W_REG(&cc->pllcontrol_addr,
+-		      PMU1_PLL0_PLLCTL2 + phypll_offset);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
+-		tmp |=
+-		    (bcm5357_bcm43236_ndiv[spuravoid]) <<
+-		    PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM4331_CHIP_ID:
+-		if (spuravoid == 2) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0FC00a08);
+-		} else if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000a08);
+-		}
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500010);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x000C0C06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x2001E920);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100010);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x000c0c06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000a08);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x200005c0);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		}
+-		tmp = 1 << 10;
+-		break;
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x11100008);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x0c000c06);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-		W_REG(&cc->pllcontrol_data, 0x03000a08);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-		W_REG(&cc->pllcontrol_data, 0x00000000);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		W_REG(&cc->pllcontrol_data, 0x200005c0);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888855);
+-
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM4716_CHIP_ID:
+-	case BCM4748_CHIP_ID:
+-	case BCM47162_CHIP_ID:
+-		if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500060);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x080C0C06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x2001E924);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100060);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x080c0c06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x200005c0);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		}
+-
+-		tmp = 3 << 9;
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x11100070);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x1014140a);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888854);
+-
+-		if (spuravoid == 1) {
+-			/* spur_avoid ON, so enable 41/82/164Mhz clock mode */
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x05201828);
+-		} else {
+-			/* enable 40/80/160Mhz clock mode */
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x05001828);
+-		}
+-		break;
+-	case BCM4336_CHIP_ID:
+-		/* Looks like these are only for default xtal freq 26MHz */
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x02100020);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-		W_REG(&cc->pllcontrol_data, 0x01240C0C);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		W_REG(&cc->pllcontrol_data, 0x202C2820);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888825);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-		if (spuravoid == 1)
+-			W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
+-		else
+-			W_REG(&cc->pllcontrol_data, 0x00762762);
+-
+-		tmp = PCTL_PLL_PLLCTL_UPD;
+-		break;
+-
+-	default:
+-		/* bail out */
+-		return;
+-	}
+-
+-	tmp |= R_REG(&cc->pmucontrol);
+-	W_REG(&cc->pmucontrol, tmp);
+-}
+-
+-/* select default xtal frequency for each chip */
+-static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Default to 38400Khz */
+-		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
+-	case BCM4319_CHIP_ID:
+-		/* Default to 30000Khz */
+-		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
+-	case BCM4336_CHIP_ID:
+-		/* Default to 26000Khz */
+-		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
+-	case BCM4330_CHIP_ID:
+-		/* Default to 37400Khz */
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
+-		else
+-			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
+-	default:
+-		break;
+-	}
+-	return NULL;
+-}
+-
+-/* select xtal table for each chip */
+-static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return pmu1_xtaltab0_880_4329;
+-	case BCM4319_CHIP_ID:
+-		return pmu1_xtaltab0_1440;
+-	case BCM4336_CHIP_ID:
+-		return pmu1_xtaltab0_960;
+-	case BCM4330_CHIP_ID:
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return pmu1_xtaltab0_960;
+-		else
+-			return pmu1_xtaltab0_1440;
+-	default:
+-		break;
+-	}
+-	return NULL;
+-}
+-
+-/* query alp/xtal clock frequency */
+-static u32
+-si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
+-{
+-	const pmu1_xtaltab0_t *xt;
+-	u32 xf;
+-
+-	/* Find the frequency in the table */
+-	xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+-	    PCTL_XTALFREQ_SHIFT;
+-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+-		if (xt->xf == xf)
+-			break;
+-	/* Could not find it so assign a default value */
+-	if (xt == NULL || xt->fref == 0)
+-		xt = si_pmu1_xtaldef0(sih);
+-	return xt->fref * 1000;
+-}
+-
+-/* select default pll fvco for each chip */
+-static u32 si_pmu1_pllfvco0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return FVCO_880;
+-	case BCM4319_CHIP_ID:
+-		return FVCO_1440;
+-	case BCM4336_CHIP_ID:
+-		return FVCO_960;
+-	case BCM4330_CHIP_ID:
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return FVCO_960;
+-		else
+-			return FVCO_1440;
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-static void si_pmu_set_4330_plldivs(si_t *sih)
+-{
+-	u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
+-	u32 m1div, m2div, m3div, m4div, m5div, m6div;
+-	u32 pllc1, pllc2;
+-
+-	m2div = m3div = m4div = m6div = FVCO / 80;
+-	m5div = FVCO / 160;
+-
+-	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-		m1div = FVCO / 80;
+-	else
+-		m1div = FVCO / 90;
+-	pllc1 =
+-	    (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
+-						    PMU1_PLL0_PC1_M2DIV_SHIFT) |
+-	    (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
+-						    PMU1_PLL0_PC1_M4DIV_SHIFT);
+-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
+-
+-	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
+-	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
+-	pllc2 |=
+-	    ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
+-	     (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
+-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
+-}
+-
+-/* Set up PLL registers in the PMU as per the crystal speed.
+- * XtalFreq field in pmucontrol register being 0 indicates the PLL
+- * is not programmed and the h/w default is assumed to work, in which
+- * case the xtal frequency is unknown to the s/w so we need to call
+- * si_pmu1_xtaldef0() wherever it is needed to return a default value.
+- */
+-static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
+-{
+-	const pmu1_xtaltab0_t *xt;
+-	u32 tmp;
+-	u32 buf_strength = 0;
+-	u8 ndiv_mode = 1;
+-
+-	/* Use h/w default PLL config */
+-	if (xtal == 0) {
+-		return;
+-	}
+-
+-	/* Find the frequency in the table */
+-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+-		if (xt->fref == xtal)
+-			break;
+-
+-	/* Check current PLL state, bail out if it has been programmed or
+-	 * we don't know how to program it.
+-	 */
+-	if (xt == NULL || xt->fref == 0) {
+-		return;
+-	}
+-	/* for 4319 bootloader already programs the PLL but bootloader does not
+-	 * program the PLL4 and PLL5. So Skip this check for 4319
+-	 */
+-	if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+-	      PCTL_XTALFREQ_SHIFT) == xt->xf) &&
+-	    !((sih->chip == BCM4319_CHIP_ID)
+-	      || (sih->chip == BCM4330_CHIP_ID)))
+-		return;
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Change the BBPLL drive strength to 8 for all channels */
+-		buf_strength = 0x888888;
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+-			  PMURES_BIT(RES4329_HT_AVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+-			  PMURES_BIT(RES4329_HT_AVAIL)));
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		if (xt->fref == 38400)
+-			tmp = 0x200024C0;
+-		else if (xt->fref == 37400)
+-			tmp = 0x20004500;
+-		else if (xt->fref == 26000)
+-			tmp = 0x200024C0;
+-		else
+-			tmp = 0x200005C0;	/* Chip Dflt Settings */
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		tmp =
+-		    R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
+-		if ((xt->fref == 38400) || (xt->fref == 37400)
+-		    || (xt->fref == 26000))
+-			tmp |= 0x15;
+-		else
+-			tmp |= 0x25;	/* Chip Dflt Settings */
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		/* Change the BBPLL drive strength to 2 for all channels */
+-		buf_strength = 0x222222;
+-
+-		/* Make sure the PLL is off */
+-		/* WAR65104: Disable the HT_AVAIL resource first and then
+-		 * after a delay (more than downtime for HT_AVAIL) remove the
+-		 * BBPLL resource; backplane clock moves to ALP from HT.
+-		 */
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4319_HT_AVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4319_HT_AVAIL)));
+-
+-		udelay(100);
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+-
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		tmp = 0x200005c0;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		break;
+-
+-	case BCM4336_CHIP_ID:
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4336_HT_AVAIL) |
+-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4336_HT_AVAIL) |
+-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4330_HT_AVAIL) |
+-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4330_HT_AVAIL) |
+-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	/* Write p1div and p2div to pllcontrol[0] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-	tmp = R_REG(&cc->pllcontrol_data) &
+-	    ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
+-	tmp |=
+-	    ((xt->
+-	      p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
+-	    ((xt->
+-	      p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	if ((sih->chip == BCM4330_CHIP_ID))
+-		si_pmu_set_4330_plldivs(sih);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID)
+-	    && (sih->chiprev == 0)) {
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
+-		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-	}
+-	if ((sih->chip == BCM4319_CHIP_ID) ||
+-	    (sih->chip == BCM4336_CHIP_ID) ||
+-	    (sih->chip == BCM4330_CHIP_ID))
+-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
+-	else
+-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
+-
+-	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-	tmp = R_REG(&cc->pllcontrol_data) &
+-	    ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
+-	tmp |=
+-	    ((xt->
+-	      ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
+-	     PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
+-					      PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
+-					     PMU1_PLL0_PC2_NDIV_MODE_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	/* Write ndiv_frac to pllcontrol[3] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-	tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
+-	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
+-		PMU1_PLL0_PC3_NDIV_FRAC_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	/* Write clock driving strength to pllcontrol[5] */
+-	if (buf_strength) {
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		tmp =
+-		    R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
+-		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
+-		W_REG(&cc->pllcontrol_data, tmp);
+-	}
+-
+-	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
+-	 * to be updated.
+-	 */
+-	if ((sih->chip == BCM4319_CHIP_ID)
+-	    && (xt->fref != XTAL_FREQ_30000MHZ)) {
+-		W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
+-		tmp =
+-		    R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
+-		if (xt->fref == XTAL_FREQ_24000MHZ) {
+-			tmp |=
+-			    (CCTL_4319USB_24MHZ_PLL_SEL <<
+-			     CCTL_4319USB_XTAL_SEL_SHIFT);
+-		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
+-			tmp |=
+-			    (CCTL_4319USB_48MHZ_PLL_SEL <<
+-			     CCTL_4319USB_XTAL_SEL_SHIFT);
+-		}
+-		W_REG(&cc->chipcontrol_data, tmp);
+-	}
+-
+-	/* Flush deferred pll control registers writes */
+-	if (sih->pmurev >= 2)
+-		OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
+-
+-	/* Write XtalFreq. Set the divisor also. */
+-	tmp = R_REG(&cc->pmucontrol) &
+-	    ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
+-	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+-		PCTL_ILP_DIV_MASK) |
+-	    ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID)
+-	    && sih->chiprev == 0) {
+-		/* clear the htstretch before clearing HTReqEn */
+-		AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
+-		tmp &= ~PCTL_HT_REQ_EN;
+-	}
+-
+-	W_REG(&cc->pmucontrol, tmp);
+-}
+-
+-u32 si_pmu_ilp_clock(si_t *sih)
+-{
+-	static u32 ilpcycles_per_sec;
+-
+-	if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
+-		return ILP_CLOCK;
+-
+-	if (ilpcycles_per_sec == 0) {
+-		u32 start, end, delta;
+-		u32 origidx = ai_coreidx(sih);
+-		chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
+-		start = R_REG(&cc->pmutimer);
+-		mdelay(ILP_CALC_DUR);
+-		end = R_REG(&cc->pmutimer);
+-		delta = end - start;
+-		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
+-		ai_setcoreidx(sih, origidx);
+-	}
+-
+-	return ilpcycles_per_sec;
+-}
+-
+-void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
+-{
+-	u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
+-	u8 addr = 0;
+-
+-	switch (sih->chip) {
+-	case BCM4336_CHIP_ID:
+-		switch (ldo) {
+-		case SET_LDO_VOLTAGE_CLDO_PWM:
+-			addr = 4;
+-			rc_shift = 1;
+-			mask = 0xf;
+-			break;
+-		case SET_LDO_VOLTAGE_CLDO_BURST:
+-			addr = 4;
+-			rc_shift = 5;
+-			mask = 0xf;
+-			break;
+-		case SET_LDO_VOLTAGE_LNLDO1:
+-			addr = 4;
+-			rc_shift = 17;
+-			mask = 0xf;
+-			break;
+-		default:
+-			return;
+-		}
+-		break;
+-	case BCM4330_CHIP_ID:
+-		switch (ldo) {
+-		case SET_LDO_VOLTAGE_CBUCK_PWM:
+-			addr = 3;
+-			rc_shift = 0;
+-			mask = 0x1f;
+-			break;
+-		default:
+-			return;
+-		}
+-		break;
+-	default:
+-		return;
+-	}
+-
+-	shift = sr_cntl_shift + rc_shift;
+-
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
+-		   ~0, addr);
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
+-		   mask << shift, (voltage & mask) << shift);
+-}
+-
+-u16 si_pmu_fast_pwrup_delay(si_t *sih)
+-{
+-	uint delay = PMU_MAX_TRANSITION_DLY;
+-	chipcregs_t *cc;
+-	uint origidx;
+-#ifdef BCMDBG
+-	char chn[8];
+-	chn[0] = 0;		/* to suppress compile error */
+-#endif
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-	case BCM4313_CHIP_ID:
+-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+-		break;
+-	case BCM4329_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	case BCM4319_CHIP_ID:
+-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+-		break;
+-	case BCM4336_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	case BCM4330_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-
+-	return (u16) delay;
+-}
+-
+-void si_pmu_sprom_enable(si_t *sih, bool enable)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* Read/write a chipcontrol reg */
+-u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, chipcontrol_data), mask, val);
+-}
+-
+-/* Read/write a regcontrol reg */
+-u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, regcontrol_data), mask, val);
+-}
+-
+-/* Read/write a pllcontrol reg */
+-u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, pllcontrol_data), mask, val);
+-}
+-
+-/* PMU PLL update */
+-void si_pmu_pllupd(si_t *sih)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
+-		   PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
+-}
+-
+-/* query alp/xtal clock frequency */
+-u32 si_pmu_alp_clock(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 clock = ALP_CLOCK;
+-
+-	/* bail out with default */
+-	if (!PMUCTL_ENAB(sih))
+-		return clock;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-	case BCM4716_CHIP_ID:
+-	case BCM4748_CHIP_ID:
+-	case BCM47162_CHIP_ID:
+-	case BCM4313_CHIP_ID:
+-	case BCM5357_CHIP_ID:
+-		/* always 20Mhz */
+-		clock = 20000 * 1000;
+-		break;
+-	case BCM4329_CHIP_ID:
+-	case BCM4319_CHIP_ID:
+-	case BCM4336_CHIP_ID:
+-	case BCM4330_CHIP_ID:
+-
+-		clock = si_pmu1_alpclk0(sih, cc);
+-		break;
+-	case BCM5356_CHIP_ID:
+-		/* always 25Mhz */
+-		clock = 25000 * 1000;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-	return clock;
+-}
+-
+-void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
+-{
+-	chipcregs_t *cc;
+-	uint origidx, intr_val;
+-	u32 tmp = 0;
+-
+-	/* Remember original core before switch to chipc */
+-	cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
+-					    &intr_val);
+-
+-	/* force the HT off  */
+-	if (sih->chip == BCM4336_CHIP_ID) {
+-		tmp = R_REG(&cc->max_res_mask);
+-		tmp &= ~RES4336_HT_AVAIL;
+-		W_REG(&cc->max_res_mask, tmp);
+-		/* wait for the ht to really go away */
+-		SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
+-			 10000);
+-	}
+-
+-	/* update the pll changes */
+-	si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
+-
+-	/* enable HT back on  */
+-	if (sih->chip == BCM4336_CHIP_ID) {
+-		tmp = R_REG(&cc->max_res_mask);
+-		tmp |= RES4336_HT_AVAIL;
+-		W_REG(&cc->max_res_mask, tmp);
+-	}
+-
+-	/* Return to original core */
+-	ai_restore_core(sih, origidx, intr_val);
+-}
+-
+-/* initialize PMU */
+-void si_pmu_init(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	if (sih->pmurev == 1)
+-		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
+-	else if (sih->pmurev >= 2)
+-		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
+-		/* Fix for 4329b0 bad LPOM state. */
+-		W_REG(&cc->regcontrol_addr, 2);
+-		OR_REG(&cc->regcontrol_data, 0x100);
+-
+-		W_REG(&cc->regcontrol_addr, 3);
+-		OR_REG(&cc->regcontrol_data, 0x4);
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU chip controls and other chip level stuff */
+-void si_pmu_chip_init(si_t *sih)
+-{
+-	uint origidx;
+-
+-	/* Gate off SPROM clock and chip select signals */
+-	si_pmu_sprom_enable(sih, false);
+-
+-	/* Remember original core */
+-	origidx = ai_coreidx(sih);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU switch/regulators */
+-void si_pmu_swreg_init(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4336_CHIP_ID:
+-		/* Reduce CLDO PWM output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
+-		/* Reduce CLDO BURST output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
+-				       0xe);
+-		/* Reduce LNLDO1 output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
+-		if (sih->chiprev == 0)
+-			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-/* initialize PLL */
+-void si_pmu_pll_init(si_t *sih, uint xtalfreq)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		if (xtalfreq == 0)
+-			xtalfreq = 38400;
+-		si_pmu1_pllinit0(sih, cc, xtalfreq);
+-		break;
+-	case BCM4313_CHIP_ID:
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		/* ??? */
+-		break;
+-	case BCM4319_CHIP_ID:
+-	case BCM4336_CHIP_ID:
+-	case BCM4330_CHIP_ID:
+-		si_pmu1_pllinit0(sih, cc, xtalfreq);
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU resources */
+-void si_pmu_res_init(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	const pmu_res_updown_t *pmu_res_updown_table = NULL;
+-	uint pmu_res_updown_table_sz = 0;
+-	const pmu_res_depend_t *pmu_res_depend_table = NULL;
+-	uint pmu_res_depend_table_sz = 0;
+-	u32 min_mask = 0, max_mask = 0;
+-	char name[8], *val;
+-	uint i, rsrcs;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = NULL;
+-			pmu_res_updown_table_sz = 0;
+-		} else {
+-			pmu_res_updown_table = bcm4329_res_updown;
+-			pmu_res_updown_table_sz =
+-				ARRAY_SIZE(bcm4329_res_updown);
+-		}
+-		/* Optimize resources dependencies */
+-		pmu_res_depend_table = bcm4329_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4319a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4319a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4319a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4319a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4319a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
+-		break;
+-
+-	case BCM4336_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4336a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4336a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4336a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4336a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4336a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4330a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4330a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4330a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4330a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4330a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	/* # resources */
+-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+-
+-	/* Program up/down timers */
+-	while (pmu_res_updown_table_sz--) {
+-		W_REG(&cc->res_table_sel,
+-		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
+-		W_REG(&cc->res_updn_timer,
+-		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
+-	}
+-	/* Apply nvram overrides to up/down timers */
+-	for (i = 0; i < rsrcs; i++) {
+-		snprintf(name, sizeof(name), "r%dt", i);
+-		val = getvar(NULL, name);
+-		if (val == NULL)
+-			continue;
+-		W_REG(&cc->res_table_sel, (u32) i);
+-		W_REG(&cc->res_updn_timer,
+-		      (u32) simple_strtoul(val, NULL, 0));
+-	}
+-
+-	/* Program resource dependencies table */
+-	while (pmu_res_depend_table_sz--) {
+-		if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
+-		    && !(pmu_res_depend_table[pmu_res_depend_table_sz].
+-			 filter) (sih))
+-			continue;
+-		for (i = 0; i < rsrcs; i++) {
+-			if ((pmu_res_depend_table[pmu_res_depend_table_sz].
+-			     res_mask & PMURES_BIT(i)) == 0)
+-				continue;
+-			W_REG(&cc->res_table_sel, i);
+-			switch (pmu_res_depend_table[pmu_res_depend_table_sz].
+-				action) {
+-			case RES_DEPEND_SET:
+-				W_REG(&cc->res_dep_mask,
+-				      pmu_res_depend_table
+-				      [pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			case RES_DEPEND_ADD:
+-				OR_REG(&cc->res_dep_mask,
+-				       pmu_res_depend_table
+-				       [pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			case RES_DEPEND_REMOVE:
+-				AND_REG(&cc->res_dep_mask,
+-					~pmu_res_depend_table
+-					[pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			default:
+-				break;
+-			}
+-		}
+-	}
+-	/* Apply nvram overrides to dependancies masks */
+-	for (i = 0; i < rsrcs; i++) {
+-		snprintf(name, sizeof(name), "r%dd", i);
+-		val = getvar(NULL, name);
+-		if (val == NULL)
+-			continue;
+-		W_REG(&cc->res_table_sel, (u32) i);
+-		W_REG(&cc->res_dep_mask,
+-		      (u32) simple_strtoul(val, NULL, 0));
+-	}
+-
+-	/* Determine min/max rsrc masks */
+-	si_pmu_res_masks(sih, &min_mask, &max_mask);
+-
+-	/* It is required to program max_mask first and then min_mask */
+-
+-	/* Program max resource mask */
+-
+-	if (max_mask)
+-		W_REG(&cc->max_res_mask, max_mask);
+-
+-	/* Program min resource mask */
+-
+-	if (min_mask)
+-		W_REG(&cc->min_res_mask, min_mask);
+-
+-	/* Add some delay; allow resources to come up and settle. */
+-	mdelay(2);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-u32 si_pmu_measure_alpclk(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 alp_khz;
+-
+-	if (sih->pmurev < 10)
+-		return 0;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
+-		u32 ilp_ctr, alp_hz;
+-
+-		/*
+-		 * Enable the reg to measure the freq,
+-		 * in case it was disabled before
+-		 */
+-		W_REG(&cc->pmu_xtalfreq,
+-		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
+-
+-		/* Delay for well over 4 ILP clocks */
+-		udelay(1000);
+-
+-		/* Read the latched number of ALP ticks per 4 ILP ticks */
+-		ilp_ctr =
+-		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
+-
+-		/*
+-		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
+-		 * bit to save power
+-		 */
+-		W_REG(&cc->pmu_xtalfreq, 0);
+-
+-		/* Calculate ALP frequency */
+-		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
+-
+-		/*
+-		 * Round to nearest 100KHz, and at
+-		 * the same time convert to KHz
+-		 */
+-		alp_khz = (alp_hz + 50000) / 100000 * 100;
+-	} else
+-		alp_khz = 0;
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-
+-	return alp_khz;
+-}
+-
+-bool si_pmu_is_otp_powered(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	bool st;
+-
+-	/* Remember original core before switch to chipc */
+-	idx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4319_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4336_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4330_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
+-		    != 0;
+-		break;
+-
+-		/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
+-		 * Use OTP_INIT command to reset/refresh state.
+-		 */
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-		st = true;
+-		break;
+-	default:
+-		st = true;
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, idx);
+-	return st;
+-}
+-
+-/* power up/down OTP through PMU resources */
+-void si_pmu_otp_power(si_t *sih, bool on)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
+-
+-	/* Don't do anything if OTP is disabled */
+-	if (ai_is_otp_disabled(sih))
+-		return;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4329_OTP_PU);
+-		break;
+-	case BCM4319_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4319_OTP_PU);
+-		break;
+-	case BCM4336_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4336_OTP_PU);
+-		break;
+-	case BCM4330_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4330_OTP_PU);
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	if (rsrcs != 0) {
+-		u32 otps;
+-
+-		/* Figure out the dependancies (exclude min_res_mask) */
+-		u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
+-		u32 min_mask = 0, max_mask = 0;
+-		si_pmu_res_masks(sih, &min_mask, &max_mask);
+-		deps &= ~min_mask;
+-		/* Turn on/off the power */
+-		if (on) {
+-			OR_REG(&cc->min_res_mask, (rsrcs | deps));
+-			SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
+-				 PMU_MAX_TRANSITION_DLY);
+-		} else {
+-			AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
+-		}
+-
+-		SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
+-			  (on ? OTPS_READY : 0)), 100);
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
+deleted file mode 100644
+index bd5b809b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
++++ /dev/null
+@@ -1,58 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-
+-#ifndef WLC_PMU_H_
+-#define WLC_PMU_H_
+-
+-#include <linux/types.h>
+-
+-#include <aiutils.h>
+-
+-/*
+- * LDO selections used in si_pmu_set_ldo_voltage
+- */
+-#define SET_LDO_VOLTAGE_LDO1	1
+-#define SET_LDO_VOLTAGE_LDO2	2
+-#define SET_LDO_VOLTAGE_LDO3	3
+-#define SET_LDO_VOLTAGE_PAREF	4
+-#define SET_LDO_VOLTAGE_CLDO_PWM	5
+-#define SET_LDO_VOLTAGE_CLDO_BURST	6
+-#define SET_LDO_VOLTAGE_CBUCK_PWM	7
+-#define SET_LDO_VOLTAGE_CBUCK_BURST	8
+-#define SET_LDO_VOLTAGE_LNLDO1	9
+-#define SET_LDO_VOLTAGE_LNLDO2_SEL	10
+-
+-extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage);
+-extern u16 si_pmu_fast_pwrup_delay(si_t *sih);
+-extern void si_pmu_sprom_enable(si_t *sih, bool enable);
+-extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern u32 si_pmu_ilp_clock(si_t *sih);
+-extern u32 si_pmu_alp_clock(si_t *sih);
+-extern void si_pmu_pllupd(si_t *sih);
+-extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid);
+-extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern void si_pmu_init(si_t *sih);
+-extern void si_pmu_chip_init(si_t *sih);
+-extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq);
+-extern void si_pmu_res_init(si_t *sih);
+-extern void si_pmu_swreg_init(si_t *sih);
+-extern u32 si_pmu_measure_alpclk(si_t *sih);
+-extern bool si_pmu_is_otp_powered(si_t *sih);
+-extern void si_pmu_otp_power(si_t *sih, bool on);
+-
+-#endif /* WLC_PMU_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
+deleted file mode 100644
+index 9334dea..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
++++ /dev/null
+@@ -1,584 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_pub_h_
+-#define _wlc_pub_h_
+-
+-#define	WLC_NUMRATES	16	/* max # of rates in a rateset */
+-#define	MAXMULTILIST	32	/* max # multicast addresses */
+-#define	D11_PHY_HDR_LEN	6	/* Phy header length - 6 bytes */
+-
+-/* phy types */
+-#define	PHY_TYPE_A	0	/* Phy type A */
+-#define	PHY_TYPE_G	2	/* Phy type G */
+-#define	PHY_TYPE_N	4	/* Phy type N */
+-#define	PHY_TYPE_LP	5	/* Phy type Low Power A/B/G */
+-#define	PHY_TYPE_SSN	6	/* Phy type Single Stream N */
+-#define	PHY_TYPE_LCN	8	/* Phy type Single Stream N */
+-#define	PHY_TYPE_LCNXN	9	/* Phy type 2-stream N */
+-#define	PHY_TYPE_HT	7	/* Phy type 3-Stream N */
+-
+-/* bw */
+-#define WLC_10_MHZ	10	/* 10Mhz nphy channel bandwidth */
+-#define WLC_20_MHZ	20	/* 20Mhz nphy channel bandwidth */
+-#define WLC_40_MHZ	40	/* 40Mhz nphy channel bandwidth */
+-
+-#define CHSPEC_WLC_BW(chanspec)	(CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \
+-				 CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \
+-							 WLC_10_MHZ)
+-
+-#define	WLC_RSSI_MINVAL		-200	/* Low value, e.g. for forcing roam */
+-#define	WLC_RSSI_NO_SIGNAL	-91	/* NDIS RSSI link quality cutoffs */
+-#define	WLC_RSSI_VERY_LOW	-80	/* Very low quality cutoffs */
+-#define	WLC_RSSI_LOW		-70	/* Low quality cutoffs */
+-#define	WLC_RSSI_GOOD		-68	/* Good quality cutoffs */
+-#define	WLC_RSSI_VERY_GOOD	-58	/* Very good quality cutoffs */
+-#define	WLC_RSSI_EXCELLENT	-57	/* Excellent quality cutoffs */
+-
+-#define WLC_PHYTYPE(_x) (_x)	/* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */
+-
+-#define MA_WINDOW_SZ		8	/* moving average window size */
+-
+-#define WLC_SNR_INVALID		0	/* invalid SNR value */
+-
+-/* a large TX Power as an init value to factor out of min() calculations,
+- * keep low enough to fit in an s8, units are .25 dBm
+- */
+-#define WLC_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
+-
+-/* rate related definitions */
+-#define	WLC_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
+-#define	WLC_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
+-
+-/* legacy rx Antenna diversity for SISO rates */
+-#define	ANT_RX_DIV_FORCE_0		0	/* Use antenna 0 */
+-#define	ANT_RX_DIV_FORCE_1		1	/* Use antenna 1 */
+-#define	ANT_RX_DIV_START_1		2	/* Choose starting with 1 */
+-#define	ANT_RX_DIV_START_0		3	/* Choose starting with 0 */
+-#define	ANT_RX_DIV_ENABLE		3	/* APHY bbConfig Enable RX Diversity */
+-#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0	/* default antdiv setting */
+-
+-/* legacy rx Antenna diversity for SISO rates */
+-#define ANT_TX_FORCE_0		0	/* Tx on antenna 0, "legacy term Main" */
+-#define ANT_TX_FORCE_1		1	/* Tx on antenna 1, "legacy term Aux" */
+-#define ANT_TX_LAST_RX		3	/* Tx on phy's last good Rx antenna */
+-#define ANT_TX_DEF			3	/* driver's default tx antenna setting */
+-
+-#define TXCORE_POLICY_ALL	0x1	/* use all available core for transmit */
+-
+-/* Tx Chain values */
+-#define TXCHAIN_DEF		0x1	/* def bitmap of txchain */
+-#define TXCHAIN_DEF_NPHY	0x3	/* default bitmap of tx chains for nphy */
+-#define TXCHAIN_DEF_HTPHY	0x7	/* default bitmap of tx chains for nphy */
+-#define RXCHAIN_DEF		0x1	/* def bitmap of rxchain */
+-#define RXCHAIN_DEF_NPHY	0x3	/* default bitmap of rx chains for nphy */
+-#define RXCHAIN_DEF_HTPHY	0x7	/* default bitmap of rx chains for nphy */
+-#define ANTSWITCH_NONE		0	/* no antenna switch */
+-#define ANTSWITCH_TYPE_1	1	/* antenna switch on 4321CB2, 2of3 */
+-#define ANTSWITCH_TYPE_2	2	/* antenna switch on 4321MPCI, 2of3 */
+-#define ANTSWITCH_TYPE_3	3	/* antenna switch on 4322, 2of3 */
+-
+-#define RXBUFSZ		PKTBUFSZ
+-#ifndef AIDMAPSZ
+-#define AIDMAPSZ	(roundup(MAXSCB, NBBY)/NBBY)	/* aid bitmap size in bytes */
+-#endif				/* AIDMAPSZ */
+-
+-struct ieee80211_tx_queue_params;
+-
+-typedef struct wlc_tunables {
+-	int ntxd;		/* size of tx descriptor table */
+-	int nrxd;		/* size of rx descriptor table */
+-	int rxbufsz;		/* size of rx buffers to post */
+-	int nrxbufpost;		/* # of rx buffers to post */
+-	int maxscb;		/* # of SCBs supported */
+-	int ampdunummpdu;	/* max number of mpdu in an ampdu */
+-	int maxpktcb;		/* max # of packet callbacks */
+-	int maxucodebss;	/* max # of BSS handled in ucode bcn/prb */
+-	int maxucodebss4;	/* max # of BSS handled in sw bcn/prb */
+-	int maxbss;		/* max # of bss info elements in scan list */
+-	int datahiwat;		/* data msg txq hiwat mark */
+-	int ampdudatahiwat;	/* AMPDU msg txq hiwat mark */
+-	int rxbnd;		/* max # of rx bufs to process before deferring to dpc */
+-	int txsbnd;		/* max # tx status to process in wlc_txstatus() */
+-	int memreserved;	/* memory reserved for BMAC's USB dma rx */
+-} wlc_tunables_t;
+-
+-typedef struct wlc_rateset {
+-	uint count;		/* number of rates in rates[] */
+-	u8 rates[WLC_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-	u8 htphy_membership;	/* HT PHY Membership */
+-	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
+-} wlc_rateset_t;
+-
+-struct rsn_parms {
+-	u8 flags;		/* misc booleans (e.g., supported) */
+-	u8 multicast;	/* multicast cipher */
+-	u8 ucount;		/* count of unicast ciphers */
+-	u8 unicast[4];	/* unicast ciphers */
+-	u8 acount;		/* count of auth modes */
+-	u8 auth[4];		/* Authentication modes */
+-	u8 PAD[4];		/* padding for future growth */
+-};
+-
+-/*
+- * buffer length needed for wlc_format_ssid
+- * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+- */
+-#define SSID_FMT_BUF_LEN	((4 * IEEE80211_MAX_SSID_LEN) + 1)
+-
+-#define RSN_FLAGS_SUPPORTED		0x1	/* Flag for rsn_params */
+-#define RSN_FLAGS_PREAUTH		0x2	/* Flag for WPA2 rsn_params */
+-
+-/* All the HT-specific default advertised capabilities (including AMPDU)
+- * should be grouped here at one place
+- */
+-#define AMPDU_DEF_MPDU_DENSITY	6	/* default mpdu density (110 ==> 4us) */
+-
+-/* defaults for the HT (MIMO) bss */
+-#define HT_CAP	(IEEE80211_HT_CAP_SM_PS |\
+-	IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\
+-	IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40)
+-
+-/* wlc internal bss_info, wl external one is in wlioctl.h */
+-typedef struct wlc_bss_info {
+-	u8 BSSID[ETH_ALEN];	/* network BSSID */
+-	u16 flags;		/* flags for internal attributes */
+-	u8 SSID_len;		/* the length of SSID */
+-	u8 SSID[32];		/* SSID string */
+-	s16 RSSI;		/* receive signal strength (in dBm) */
+-	s16 SNR;		/* receive signal SNR in dB */
+-	u16 beacon_period;	/* units are Kusec */
+-	u16 atim_window;	/* units are Kusec */
+-	chanspec_t chanspec;	/* Channel num, bw, ctrl_sb and band */
+-	s8 infra;		/* 0=IBSS, 1=infrastructure, 2=unknown */
+-	wlc_rateset_t rateset;	/* supported rates */
+-	u8 dtim_period;	/* DTIM period */
+-	s8 phy_noise;		/* noise right after tx (in dBm) */
+-	u16 capability;	/* Capability information */
+-	u8 wme_qosinfo;	/* QoS Info from WME IE; valid if WLC_BSS_WME flag set */
+-	struct rsn_parms wpa;
+-	struct rsn_parms wpa2;
+-	u16 qbss_load_aac;	/* qbss load available admission capacity */
+-	/* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */
+-	u8 qbss_load_chan_free;	/* indicates how free the channel is */
+-	u8 mcipher;		/* multicast cipher */
+-	u8 wpacfg;		/* wpa config index */
+-} wlc_bss_info_t;
+-
+-/* forward declarations */
+-struct wlc_if;
+-
+-/* wlc_ioctl error codes */
+-#define WLC_ENOIOCTL	1	/* No such Ioctl */
+-#define WLC_EINVAL	2	/* Invalid value */
+-#define WLC_ETOOSMALL	3	/* Value too small */
+-#define WLC_ETOOBIG	4	/* Value too big */
+-#define WLC_ERANGE	5	/* Out of range */
+-#define WLC_EDOWN	6	/* Down */
+-#define WLC_EUP		7	/* Up */
+-#define WLC_ENOMEM	8	/* No Memory */
+-#define WLC_EBUSY	9	/* Busy */
+-
+-/* IOVar flags for common error checks */
+-#define IOVF_MFG	(1<<3)	/* flag for mfgtest iovars */
+-#define IOVF_WHL	(1<<4)	/* value must be whole (0-max) */
+-#define IOVF_NTRL	(1<<5)	/* value must be natural (1-max) */
+-
+-#define IOVF_SET_UP	(1<<6)	/* set requires driver be up */
+-#define IOVF_SET_DOWN	(1<<7)	/* set requires driver be down */
+-#define IOVF_SET_CLK	(1<<8)	/* set requires core clock */
+-#define IOVF_SET_BAND	(1<<9)	/* set requires fixed band */
+-
+-#define IOVF_GET_UP	(1<<10)	/* get requires driver be up */
+-#define IOVF_GET_DOWN	(1<<11)	/* get requires driver be down */
+-#define IOVF_GET_CLK	(1<<12)	/* get requires core clock */
+-#define IOVF_GET_BAND	(1<<13)	/* get requires fixed band */
+-#define IOVF_OPEN_ALLOW	(1<<14)	/* set allowed iovar for opensrc */
+-
+-/* watchdog down and dump callback function proto's */
+-typedef int (*watchdog_fn_t) (void *handle);
+-typedef int (*down_fn_t) (void *handle);
+-typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b);
+-
+-/* IOVar handler
+- *
+- * handle - a pointer value registered with the function
+- * vi - iovar_info that was looked up
+- * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid.
+- * name - the actual iovar name
+- * params/plen - parameters and length for a get, input only.
+- * arg/len - buffer and length for value to be set or retrieved, input or output.
+- * vsize - value size, valid for integer type only.
+- * wlcif - interface context (wlc_if pointer)
+- *
+- * All pointers may point into the same buffer.
+- */
+-typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi,
+-			   u32 actionid, const char *name, void *params,
+-			   uint plen, void *arg, int alen, int vsize,
+-			   struct wlc_if *wlcif);
+-
+-#define MAC80211_PROMISC_BCNS	(1 << 0)
+-#define MAC80211_SCAN		(1 << 1)
+-
+-/*
+- * Public portion of "common" os-independent state structure.
+- * The wlc handle points at this.
+- */
+-struct wlc_pub {
+-	void *wlc;
+-
+-	struct ieee80211_hw *ieee_hw;
+-	struct scb *global_scb;
+-	scb_ampdu_t *global_ampdu;
+-	uint mac80211_state;
+-	uint unit;		/* device instance number */
+-	uint corerev;		/* core revision */
+-	si_t *sih;		/* SB handle (cookie for siutils calls) */
+-	char *vars;		/* "environment" name=value */
+-	bool up;		/* interface up and running */
+-	bool hw_off;		/* HW is off */
+-	wlc_tunables_t *tunables;	/* tunables: ntxd, nrxd, maxscb, etc. */
+-	bool hw_up;		/* one time hw up/down(from boot or hibernation) */
+-	bool _piomode;		/* true if pio mode *//* BMAC_NOTE: NEED In both */
+-	uint _nbands;		/* # bands supported */
+-	uint now;		/* # elapsed seconds */
+-
+-	bool promisc;		/* promiscuous destination address */
+-	bool delayed_down;	/* down delayed */
+-	bool _ap;		/* AP mode enabled */
+-	bool _apsta;		/* simultaneous AP/STA mode enabled */
+-	bool _assoc_recreate;	/* association recreation on up transitions */
+-	int _wme;		/* WME QoS mode */
+-	u8 _mbss;		/* MBSS mode on */
+-	bool allmulti;		/* enable all multicasts */
+-	bool associated;	/* true:part of [I]BSS, false: not */
+-	/* (union of stas_associated, aps_associated) */
+-	bool phytest_on;	/* whether a PHY test is running */
+-	bool bf_preempt_4306;	/* True to enable 'darwin' mode */
+-	bool _ampdu;		/* ampdu enabled or not */
+-	bool _cac;		/* 802.11e CAC enabled */
+-	u8 _n_enab;		/* bitmap of 11N + HT support */
+-	bool _n_reqd;		/* N support required for clients */
+-
+-	s8 _coex;		/* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */
+-	bool _priofc;		/* Priority-based flowcontrol */
+-
+-	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
+-
+-	u8 *multicast;	/* ptr to list of multicast addresses */
+-	uint nmulticast;	/* # enabled multicast addresses */
+-
+-	u32 wlfeatureflag;	/* Flags to control sw features from registry */
+-	int psq_pkts_total;	/* total num of ps pkts */
+-
+-	u16 txmaxpkts;	/* max number of large pkts allowed to be pending */
+-
+-	/* s/w decryption counters */
+-	u32 swdecrypt;	/* s/w decrypt attempts */
+-
+-	int bcmerror;		/* last bcm error */
+-
+-	mbool radio_disabled;	/* bit vector for radio disabled reasons */
+-	bool radio_active;	/* radio on/off state */
+-	u16 roam_time_thresh;	/* Max. # secs. of not hearing beacons
+-					 * before roaming.
+-					 */
+-	bool align_wd_tbtt;	/* Align watchdog with tbtt indication
+-				 * handling. This flag is cleared by default
+-				 * and is set by per port code explicitly and
+-				 * you need to make sure the OSL_SYSUPTIME()
+-				 * is implemented properly in osl of that port
+-				 * when it enables this Power Save feature.
+-				 */
+-
+-	u16 boardrev;	/* version # of particular board */
+-	u8 sromrev;		/* version # of the srom */
+-	char srom_ccode[WLC_CNTRY_BUF_SZ];	/* Country Code in SROM */
+-	u32 boardflags;	/* Board specific flags from srom */
+-	u32 boardflags2;	/* More board flags if sromrev >= 4 */
+-	bool tempsense_disable;	/* disable periodic tempsense check */
+-
+-	bool _lmac;		/* lmac module included and enabled */
+-	bool _lmacproto;	/* lmac protocol module included and enabled */
+-	bool phy_11ncapable;	/* the PHY/HW is capable of 802.11N */
+-	bool _ampdumac;		/* mac assist ampdu enabled or not */
+-
+-	struct wl_cnt *_cnt;	/* low-level counters in driver */
+-};
+-
+-/* wl_monitor rx status per packet */
+-typedef struct wl_rxsts {
+-	uint pkterror;		/* error flags per pkt */
+-	uint phytype;		/* 802.11 A/B/G ... */
+-	uint channel;		/* channel */
+-	uint datarate;		/* rate in 500kbps */
+-	uint antenna;		/* antenna pkts received on */
+-	uint pktlength;		/* pkt length minus bcm phy hdr */
+-	u32 mactime;		/* time stamp from mac, count per 1us */
+-	uint sq;		/* signal quality */
+-	s32 signal;		/* in dbm */
+-	s32 noise;		/* in dbm */
+-	uint preamble;		/* Unknown, short, long */
+-	uint encoding;		/* Unknown, CCK, PBCC, OFDM */
+-	uint nfrmtype;		/* special 802.11n frames(AMPDU, AMSDU) */
+-	struct wl_if *wlif;	/* wl interface */
+-} wl_rxsts_t;
+-
+-/* status per error RX pkt */
+-#define WL_RXS_CRC_ERROR		0x00000001	/* CRC Error in packet */
+-#define WL_RXS_RUNT_ERROR		0x00000002	/* Runt packet */
+-#define WL_RXS_ALIGN_ERROR		0x00000004	/* Misaligned packet */
+-#define WL_RXS_OVERSIZE_ERROR		0x00000008	/* packet bigger than RX_LENGTH (usually 1518) */
+-#define WL_RXS_WEP_ICV_ERROR		0x00000010	/* Integrity Check Value error */
+-#define WL_RXS_WEP_ENCRYPTED		0x00000020	/* Encrypted with WEP */
+-#define WL_RXS_PLCP_SHORT		0x00000040	/* Short PLCP error */
+-#define WL_RXS_DECRYPT_ERR		0x00000080	/* Decryption error */
+-#define WL_RXS_OTHER_ERR		0x80000000	/* Other errors */
+-
+-/* phy type */
+-#define WL_RXS_PHY_A			0x00000000	/* A phy type */
+-#define WL_RXS_PHY_B			0x00000001	/* B phy type */
+-#define WL_RXS_PHY_G			0x00000002	/* G phy type */
+-#define WL_RXS_PHY_N			0x00000004	/* N phy type */
+-
+-/* encoding */
+-#define WL_RXS_ENCODING_CCK		0x00000000	/* CCK encoding */
+-#define WL_RXS_ENCODING_OFDM		0x00000001	/* OFDM encoding */
+-
+-/* preamble */
+-#define WL_RXS_UNUSED_STUB		0x0	/* stub to match with wlc_ethereal.h */
+-#define WL_RXS_PREAMBLE_SHORT		0x00000001	/* Short preamble */
+-#define WL_RXS_PREAMBLE_LONG		0x00000002	/* Long preamble */
+-#define WL_RXS_PREAMBLE_MIMO_MM		0x00000003	/* MIMO mixed mode preamble */
+-#define WL_RXS_PREAMBLE_MIMO_GF		0x00000004	/* MIMO green field preamble */
+-
+-#define WL_RXS_NFRM_AMPDU_FIRST		0x00000001	/* first MPDU in A-MPDU */
+-#define WL_RXS_NFRM_AMPDU_SUB		0x00000002	/* subsequent MPDU(s) in A-MPDU */
+-#define WL_RXS_NFRM_AMSDU_FIRST		0x00000004	/* first MSDU in A-MSDU */
+-#define WL_RXS_NFRM_AMSDU_SUB		0x00000008	/* subsequent MSDU(s) in A-MSDU */
+-
+-/* forward declare and use the struct notation so we don't have to
+- * have it defined if not necessary.
+- */
+-struct wlc_info;
+-struct wlc_hw_info;
+-struct wlc_bsscfg;
+-struct wlc_if;
+-
+-/***********************************************
+- * Feature-related macros to optimize out code *
+- * *********************************************
+- */
+-
+-/* AP Support (versus STA) */
+-#define	AP_ENAB(pub)	(0)
+-
+-/* Macro to check if APSTA mode enabled */
+-#define APSTA_ENAB(pub)	(0)
+-
+-/* Some useful combinations */
+-#define STA_ONLY(pub)	(!AP_ENAB(pub))
+-#define AP_ONLY(pub)	(AP_ENAB(pub) && !APSTA_ENAB(pub))
+-
+-#define ENAB_1x1	0x01
+-#define ENAB_2x2	0x02
+-#define ENAB_3x3	0x04
+-#define ENAB_4x4	0x08
+-#define SUPPORT_11N	(ENAB_1x1|ENAB_2x2)
+-#define SUPPORT_HT	(ENAB_1x1|ENAB_2x2|ENAB_3x3)
+-/* WL11N Support */
+-#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \
+-	(defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0)))
+-#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N)
+-#define N_REQD(pub) ((pub)->_n_reqd)
+-#else
+-#define N_ENAB(pub)	0
+-#define N_REQD(pub)	0
+-#endif
+-
+-#if (defined(HTCONF) && (HTCONF != 0))
+-#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT)
+-#else
+-#define HT_ENAB(pub) 0
+-#endif
+-
+-#define AMPDU_AGG_HOST	1
+-#define AMPDU_ENAB(pub) ((pub)->_ampdu)
+-
+-#define EDCF_ENAB(pub) (WME_ENAB(pub))
+-#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
+-
+-#define MONITOR_ENAB(wlc)	((wlc)->monitor)
+-
+-#define PROMISC_ENAB(wlc)	((wlc)->promisc)
+-
+-#define	WLC_PREC_COUNT		16	/* Max precedence level implemented */
+-
+-/* pri is priority encoded in the packet. This maps the Packet priority to
+- * enqueue precedence as defined in wlc_prec_map
+- */
+-extern const u8 wlc_prio2prec_map[];
+-#define WLC_PRIO_TO_PREC(pri)	wlc_prio2prec_map[(pri) & 7]
+-
+-/* This maps priority to one precedence higher - Used by PS-Poll response packets to
+- * simulate enqueue-at-head operation, but still maintain the order on the queue
+- */
+-#define WLC_PRIO_TO_HI_PREC(pri)	min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1)
+-
+-extern const u8 wme_fifo2ac[];
+-#define WME_PRIO2AC(prio)	wme_fifo2ac[prio2fifo[(prio)]]
+-
+-/* Mask to describe all precedence levels */
+-#define WLC_PREC_BMP_ALL		MAXBITVAL(WLC_PREC_COUNT)
+-
+-/* Define a bitmap of precedences comprised by each AC */
+-#define WLC_PREC_BMP_AC_BE	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
+-#define WLC_PREC_BMP_AC_BK	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
+-#define WLC_PREC_BMP_AC_VI	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
+-#define WLC_PREC_BMP_AC_VO	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
+-
+-/* WME Support */
+-#define WME_ENAB(pub) ((pub)->_wme != OFF)
+-#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
+-
+-#define WLC_USE_COREFLAGS	0xffffffff	/* invalid core flags, use the saved coreflags */
+-
+-
+-/* network protection config */
+-#define	WLC_PROT_G_SPEC		1	/* SPEC g protection */
+-#define	WLC_PROT_G_OVR		2	/* SPEC g prot override */
+-#define	WLC_PROT_G_USER		3	/* gmode specified by user */
+-#define	WLC_PROT_OVERLAP	4	/* overlap */
+-#define	WLC_PROT_N_USER		10	/* nmode specified by user */
+-#define	WLC_PROT_N_CFG		11	/* n protection */
+-#define	WLC_PROT_N_CFG_OVR	12	/* n protection override */
+-#define	WLC_PROT_N_NONGF	13	/* non-GF protection */
+-#define	WLC_PROT_N_NONGF_OVR	14	/* non-GF protection override */
+-#define	WLC_PROT_N_PAM_OVR	15	/* n preamble override */
+-#define	WLC_PROT_N_OBSS		16	/* non-HT OBSS present */
+-
+-/* common functions for every port */
+-extern void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
+-			bool piomode, void *regsva, uint bustype, void *btparam,
+-			uint *perr);
+-extern uint wlc_detach(struct wlc_info *wlc);
+-extern int wlc_up(struct wlc_info *wlc);
+-extern uint wlc_down(struct wlc_info *wlc);
+-
+-extern int wlc_set(struct wlc_info *wlc, int cmd, int arg);
+-extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg);
+-extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg);
+-extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg);
+-extern bool wlc_chipmatch(u16 vendor, u16 device);
+-extern void wlc_init(struct wlc_info *wlc);
+-extern void wlc_reset(struct wlc_info *wlc);
+-
+-extern void wlc_intrson(struct wlc_info *wlc);
+-extern u32 wlc_intrsoff(struct wlc_info *wlc);
+-extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask);
+-extern bool wlc_intrsupd(struct wlc_info *wlc);
+-extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc);
+-extern bool wlc_dpc(struct wlc_info *wlc, bool bounded);
+-extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
+-				 struct ieee80211_hw *hw);
+-extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params,
+-			int p_len, void *arg, int len, bool set,
+-			struct wlc_if *wlcif);
+-extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-		     struct wlc_if *wlcif);
+-extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid);
+-
+-/* helper functions */
+-extern void wlc_statsupd(struct wlc_info *wlc);
+-extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val);
+-extern int wlc_get_header_len(void);
+-extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc);
+-extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
+-			      const u8 *addr);
+-extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+-			      const struct ieee80211_tx_queue_params *arg,
+-			      bool suspend);
+-extern struct wlc_pub *wlc_pub(void *wlc);
+-
+-/* common functions for every port */
+-extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val,
+-		    int bands);
+-extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset);
+-extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs);
+-
+-struct ieee80211_sta;
+-extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta,
+-			    u16 tid);
+-
+-/* wlc_phy.c helper functions */
+-extern void wlc_set_ps_ctrl(struct wlc_info *wlc);
+-extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val);
+-
+-/* ioctl */
+-extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi,
+-			   void *arg,
+-			   int len, bool set);
+-
+-extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars,
+-			       const char *name, void *hdl, iovar_fn_t iovar_fn,
+-			       watchdog_fn_t watchdog_fn, down_fn_t down_fn);
+-extern int wlc_module_unregister(struct wlc_pub *pub, const char *name,
+-				 void *hdl);
+-extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc);
+-extern void wlc_enable_mac(struct wlc_info *wlc);
+-extern void wlc_associate_upd(struct wlc_info *wlc, bool state);
+-extern void wlc_scan_start(struct wlc_info *wlc);
+-extern void wlc_scan_stop(struct wlc_info *wlc);
+-extern int wlc_get_curband(struct wlc_info *wlc);
+-extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop);
+-
+-#if defined(BCMDBG)
+-extern int wlc_iocregchk(struct wlc_info *wlc, uint band);
+-#endif
+-
+-/* helper functions */
+-extern bool wlc_check_radio_disabled(struct wlc_info *wlc);
+-extern bool wlc_radio_monitor_stop(struct wlc_info *wlc);
+-
+-#if defined(BCMDBG)
+-extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len);
+-#endif
+-
+-#define	MAXBANDS		2	/* Maximum #of bands */
+-/* bandstate array indices */
+-#define BAND_2G_INDEX		0	/* wlc->bandstate[x] index */
+-#define BAND_5G_INDEX		1	/* wlc->bandstate[x] index */
+-
+-#define BAND_2G_NAME		"2.4G"
+-#define BAND_5G_NAME		"5G"
+-
+-/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */
+-#define WLC_RPCTX_PARAMS		32
+-
+-#endif				/* _wlc_pub_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c
+deleted file mode 100644
+index 87b252d..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c
++++ /dev/null
+@@ -1,499 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_rate.h"
+-
+-/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */
+-const u8 rate_info[WLC_MAXRATE + 1] = {
+-	/*  0     1     2     3     4     5     6     7     8     9 */
+-/*   0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
+-/*  20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
+-/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
+-/*  50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
+-/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
+-};
+-
+-/* rates are in units of Kbps */
+-const mcs_info_t mcs_table[MCS_TABLE_SIZE] = {
+-	/* MCS  0: SS 1, MOD: BPSK,  CR 1/2 */
+-	{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
+-	 WLC_RATE_6M},
+-	/* MCS  1: SS 1, MOD: QPSK,  CR 1/2 */
+-	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
+-	 WLC_RATE_12M},
+-	/* MCS  2: SS 1, MOD: QPSK,  CR 3/4 */
+-	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
+-	 WLC_RATE_18M},
+-	/* MCS  3: SS 1, MOD: 16QAM, CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
+-	 WLC_RATE_24M},
+-	/* MCS  4: SS 1, MOD: 16QAM, CR 3/4 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
+-	 WLC_RATE_36M},
+-	/* MCS  5: SS 1, MOD: 64QAM, CR 2/3 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
+-	 WLC_RATE_48M},
+-	/* MCS  6: SS 1, MOD: 64QAM, CR 3/4 */
+-	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
+-	 WLC_RATE_54M},
+-	/* MCS  7: SS 1, MOD: 64QAM, CR 5/6 */
+-	{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
+-	 WLC_RATE_54M},
+-	/* MCS  8: SS 2, MOD: BPSK,  CR 1/2 */
+-	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
+-	 WLC_RATE_6M},
+-	/* MCS  9: SS 2, MOD: QPSK,  CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
+-	 WLC_RATE_12M},
+-	/* MCS 10: SS 2, MOD: QPSK,  CR 3/4 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
+-	 WLC_RATE_18M},
+-	/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
+-	 WLC_RATE_24M},
+-	/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
+-	 WLC_RATE_36M},
+-	/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
+-	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
+-	 WLC_RATE_48M},
+-	/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
+-	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
+-	 WLC_RATE_54M},
+-	/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
+-	{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
+-	 WLC_RATE_54M},
+-	/* MCS 16: SS 3, MOD: BPSK,  CR 1/2 */
+-	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
+-	 WLC_RATE_6M},
+-	/* MCS 17: SS 3, MOD: QPSK,  CR 1/2 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
+-	 WLC_RATE_12M},
+-	/* MCS 18: SS 3, MOD: QPSK,  CR 3/4 */
+-	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
+-	 WLC_RATE_18M},
+-	/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
+-	 WLC_RATE_24M},
+-	/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
+-	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
+-	 WLC_RATE_36M},
+-	/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
+-	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
+-	 WLC_RATE_48M},
+-	/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
+-	{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
+-	 WLC_RATE_54M},
+-	/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
+-	{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
+-	 WLC_RATE_54M},
+-	/* MCS 24: SS 4, MOD: BPSK,  CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
+-	 WLC_RATE_6M},
+-	/* MCS 25: SS 4, MOD: QPSK,  CR 1/2 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
+-	 WLC_RATE_12M},
+-	/* MCS 26: SS 4, MOD: QPSK,  CR 3/4 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
+-	 WLC_RATE_18M},
+-	/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
+-	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
+-	 WLC_RATE_24M},
+-	/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
+-	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
+-	 WLC_RATE_36M},
+-	/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
+-	{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
+-	 WLC_RATE_48M},
+-	/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
+-	{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
+-	 WLC_RATE_54M},
+-	/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
+-	{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
+-	 WLC_RATE_54M},
+-	/* MCS 32: SS 1, MOD: BPSK,  CR 1/2 */
+-	{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M},
+-};
+-
+-/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
+- *   Number of spatial streams: always 1
+- *   other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard
+- */
+-typedef struct legacy_phycfg {
+-	u32 rate_ofdm;	/* ofdm mac rate */
+-	u8 tx_phy_ctl3;	/* phy ctl byte 3, code rate, modulation type, # of streams */
+-} legacy_phycfg_t;
+-
+-#define LEGACY_PHYCFG_TABLE_SIZE	12	/* Number of legacy_rate_cfg entries in the table */
+-
+-/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+-/* Eventually MIMOPHY would also be converted to this format */
+-/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+-static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
+-	{WLC_RATE_1M, 0x00},	/* CCK  1Mbps,  data rate  0 */
+-	{WLC_RATE_2M, 0x08},	/* CCK  2Mbps,  data rate  1 */
+-	{WLC_RATE_5M5, 0x10},	/* CCK  5.5Mbps,  data rate  2 */
+-	{WLC_RATE_11M, 0x18},	/* CCK  11Mbps,  data rate   3 */
+-	{WLC_RATE_6M, 0x00},	/* OFDM  6Mbps,  code rate 1/2, BPSK,   1 spatial stream */
+-	{WLC_RATE_9M, 0x02},	/* OFDM  9Mbps,  code rate 3/4, BPSK,   1 spatial stream */
+-	{WLC_RATE_12M, 0x08},	/* OFDM  12Mbps, code rate 1/2, QPSK,   1 spatial stream */
+-	{WLC_RATE_18M, 0x0A},	/* OFDM  18Mbps, code rate 3/4, QPSK,   1 spatial stream */
+-	{WLC_RATE_24M, 0x10},	/* OFDM  24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
+-	{WLC_RATE_36M, 0x12},	/* OFDM  36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
+-	{WLC_RATE_48M, 0x19},	/* OFDM  48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
+-	{WLC_RATE_54M, 0x1A},	/* OFDM  54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
+-};
+-
+-/* Hardware rates (also encodes default basic rates) */
+-
+-const wlc_rateset_t cck_ofdm_mimo_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_mimo_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Default ratesets that include MCS32 for 40BW channels */
+-const wlc_rateset_t cck_ofdm_40bw_mimo_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_40bw_mimo_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t cck_ofdm_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t gphy_legacy_rates = {
+-	4,
+-	{			/*    1b,   2b,   5.5b,  11b Mbps */
+-	 0x82, 0x84, 0x8b, 0x96},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t cck_rates = {
+-	4,
+-	{			/*    1b,   2b,   5.5,  11 Mbps */
+-	 0x82, 0x84, 0x0b, 0x16},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate);
+-
+-/* check if rateset is valid.
+- * if check_brate is true, rateset without a basic rate is considered NOT valid.
+- */
+-static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate)
+-{
+-	uint idx;
+-
+-	if (!rs->count)
+-		return false;
+-
+-	if (!check_brate)
+-		return true;
+-
+-	/* error if no basic rates */
+-	for (idx = 0; idx < rs->count; idx++) {
+-		if (rs->rates[idx] & WLC_RATE_FLAG)
+-			return true;
+-	}
+-	return false;
+-}
+-
+-void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams)
+-{
+-	int i;
+-	for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
+-		rs->mcs[i] = 0;
+-}
+-
+-/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved,
+- * and check if resulting rateset is valid.
+-*/
+-bool
+-wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs,
+-				   const wlc_rateset_t *hw_rs,
+-				   bool check_brate, u8 txstreams)
+-{
+-	u8 rateset[WLC_MAXRATE + 1];
+-	u8 r;
+-	uint count;
+-	uint i;
+-
+-	memset(rateset, 0, sizeof(rateset));
+-	count = rs->count;
+-
+-	for (i = 0; i < count; i++) {
+-		/* mask off "basic rate" bit, WLC_RATE_FLAG */
+-		r = (int)rs->rates[i] & WLC_RATE_MASK;
+-		if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) {
+-			continue;
+-		}
+-		rateset[r] = rs->rates[i];	/* preserve basic bit! */
+-	}
+-
+-	/* fill out the rates in order, looking at only supported rates */
+-	count = 0;
+-	for (i = 0; i < hw_rs->count; i++) {
+-		r = hw_rs->rates[i] & WLC_RATE_MASK;
+-		if (rateset[r])
+-			rs->rates[count++] = rateset[r];
+-	}
+-
+-	rs->count = count;
+-
+-	/* only set the mcs rate bit if the equivalent hw mcs bit is set */
+-	for (i = 0; i < MCSSET_LEN; i++)
+-		rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
+-
+-	if (wlc_rateset_valid(rs, check_brate))
+-		return true;
+-	else
+-		return false;
+-}
+-
+-/* calculate the rate of a rx'd frame and return it as a ratespec */
+-ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp)
+-{
+-	int phy_type;
+-	ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
+-
+-	phy_type =
+-	    ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
+-
+-	if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
+-	    (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
+-		switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
+-		case PRXS0_CCK:
+-			rspec =
+-			    CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+-			break;
+-		case PRXS0_OFDM:
+-			rspec =
+-			    OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->
+-					      rlpt[0]);
+-			break;
+-		case PRXS0_PREN:
+-			rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
+-			if (plcp[0] & MIMO_PLCP_40MHZ) {
+-				/* indicate rspec is for 40 MHz mode */
+-				rspec &= ~RSPEC_BW_MASK;
+-				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+-			}
+-			break;
+-		case PRXS0_STDN:
+-			/* fallthru */
+-		default:
+-			/* not supported, error condition */
+-			break;
+-		}
+-		if (PLCP3_ISSGI(plcp[3]))
+-			rspec |= RSPEC_SHORT_GI;
+-	} else
+-	    if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
+-		rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]);
+-	else
+-		rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+-
+-	return rspec;
+-}
+-
+-/* copy rateset src to dst as-is (no masking or sorting) */
+-void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst)
+-{
+-	memcpy(dst, src, sizeof(wlc_rateset_t));
+-}
+-
+-/*
+- * Copy and selectively filter one rateset to another.
+- * 'basic_only' means only copy basic rates.
+- * 'rates' indicates cck (11b) and ofdm rates combinations.
+- *    - 0: cck and ofdm
+- *    - 1: cck only
+- *    - 2: ofdm only
+- * 'xmask' is the copy mask (typically 0x7f or 0xff).
+- */
+-void
+-wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only,
+-		   u8 rates, uint xmask, bool mcsallow)
+-{
+-	uint i;
+-	uint r;
+-	uint count;
+-
+-	count = 0;
+-	for (i = 0; i < src->count; i++) {
+-		r = src->rates[i];
+-		if (basic_only && !(r & WLC_RATE_FLAG))
+-			continue;
+-		if ((rates == WLC_RATES_CCK) && IS_OFDM((r & WLC_RATE_MASK)))
+-			continue;
+-		if ((rates == WLC_RATES_OFDM) && IS_CCK((r & WLC_RATE_MASK)))
+-			continue;
+-		dst->rates[count++] = r & xmask;
+-	}
+-	dst->count = count;
+-	dst->htphy_membership = src->htphy_membership;
+-
+-	if (mcsallow && rates != WLC_RATES_CCK)
+-		memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
+-	else
+-		wlc_rateset_mcs_clear(dst);
+-}
+-
+-/* select rateset for a given phy_type and bandtype and filter it, sort it
+- * and fill rs_tgt with result
+- */
+-void
+-wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw,
+-		    uint phy_type, int bandtype, bool cck_only, uint rate_mask,
+-		    bool mcsallow, u8 bw, u8 txstreams)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs_sel;
+-	if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
+-		if (BAND_5G(bandtype)) {
+-			rs_dflt = (bw == WLC_20_MHZ ?
+-				   &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
+-		} else {
+-			rs_dflt = (bw == WLC_20_MHZ ?
+-				   &cck_ofdm_mimo_rates :
+-				   &cck_ofdm_40bw_mimo_rates);
+-		}
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
+-		rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates;
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
+-		rs_dflt = &ofdm_rates;
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
+-		rs_dflt = &cck_ofdm_rates;
+-	} else {
+-		/* should not happen, error condition */
+-		rs_dflt = &cck_rates;	/* force cck */
+-	}
+-
+-	/* if hw rateset is not supplied, assign selected rateset to it */
+-	if (!rs_hw)
+-		rs_hw = rs_dflt;
+-
+-	wlc_rateset_copy(rs_dflt, &rs_sel);
+-	wlc_rateset_mcs_upd(&rs_sel, txstreams);
+-	wlc_rateset_filter(&rs_sel, rs_tgt, false,
+-			   cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM,
+-			   rate_mask, mcsallow);
+-	wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
+-					   mcsallow ? txstreams : 1);
+-}
+-
+-s16 wlc_rate_legacy_phyctl(uint rate)
+-{
+-	uint i;
+-	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
+-		if (rate == legacy_phycfg_table[i].rate_ofdm)
+-			return legacy_phycfg_table[i].tx_phy_ctl3;
+-
+-	return -1;
+-}
+-
+-void wlc_rateset_mcs_clear(wlc_rateset_t *rateset)
+-{
+-	uint i;
+-	for (i = 0; i < MCSSET_LEN; i++)
+-		rateset->mcs[i] = 0;
+-}
+-
+-void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams)
+-{
+-	memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
+-	wlc_rateset_mcs_upd(rateset, txstreams);
+-}
+-
+-/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
+-void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw)
+-{
+-	if (bw == WLC_40_MHZ)
+-		setbit(rateset->mcs, 32);
+-	else
+-		clrbit(rateset->mcs, 32);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h
+deleted file mode 100644
+index 5575e83..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h
++++ /dev/null
+@@ -1,169 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_RATE_H_
+-#define _WLC_RATE_H_
+-
+-extern const u8 rate_info[];
+-extern const struct wlc_rateset cck_ofdm_mimo_rates;
+-extern const struct wlc_rateset ofdm_mimo_rates;
+-extern const struct wlc_rateset cck_ofdm_rates;
+-extern const struct wlc_rateset ofdm_rates;
+-extern const struct wlc_rateset cck_rates;
+-extern const struct wlc_rateset gphy_legacy_rates;
+-extern const struct wlc_rateset wlc_lrs_rates;
+-extern const struct wlc_rateset rate_limit_1_2;
+-
+-typedef struct mcs_info {
+-	u32 phy_rate_20;	/* phy rate in kbps [20Mhz] */
+-	u32 phy_rate_40;	/* phy rate in kbps [40Mhz] */
+-	u32 phy_rate_20_sgi;	/* phy rate in kbps [20Mhz] with SGI */
+-	u32 phy_rate_40_sgi;	/* phy rate in kbps [40Mhz] with SGI */
+-	u8 tx_phy_ctl3;	/* phy ctl byte 3, code rate, modulation type, # of streams */
+-	u8 leg_ofdm;		/* matching legacy ofdm rate in 500bkps */
+-} mcs_info_t;
+-
+-#define WLC_MAXMCS	32	/* max valid mcs index */
+-#define MCS_TABLE_SIZE	33	/* Number of mcs entries in the table */
+-extern const mcs_info_t mcs_table[];
+-
+-#define MCS_INVALID	0xFF
+-#define MCS_CR_MASK	0x07	/* Code Rate bit mask */
+-#define MCS_MOD_MASK	0x38	/* Modulation bit shift */
+-#define MCS_MOD_SHIFT	3	/* MOdulation bit shift */
+-#define MCS_TXS_MASK	0xc0	/* num tx streams - 1 bit mask */
+-#define MCS_TXS_SHIFT	6	/* num tx streams - 1 bit shift */
+-#define MCS_CR(_mcs)	(mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK)
+-#define MCS_MOD(_mcs)	((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT)
+-#define MCS_TXS(_mcs)	((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT)
+-#define MCS_RATE(_mcs, _is40, _sgi)	(_sgi ? \
+-	(_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \
+-	(_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
+-#define VALID_MCS(_mcs)	((_mcs < MCS_TABLE_SIZE))
+-
+-/* Macro to use the rate_info table */
+-#define	WLC_RATE_MASK_FULL 0xff	/* Rate value mask with basic rate flag */
+-
+-#define WLC_RATE_500K_TO_BPS(rate)	((rate) * 500000)	/* convert 500kbps to bps */
+-
+-/* rate spec : holds rate and mode specific information required to generate a tx frame. */
+-/* Legacy CCK and OFDM information is held in the same manner as was done in the past    */
+-/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information        */
+-typedef u32 ratespec_t;
+-
+-/* rate spec bit fields */
+-#define RSPEC_RATE_MASK		0x0000007F	/* Either 500Kbps units or MIMO MCS idx */
+-#define RSPEC_MIMORATE		0x08000000	/* mimo MCS is stored in RSPEC_RATE_MASK */
+-#define RSPEC_BW_MASK		0x00000700	/* mimo bw mask */
+-#define RSPEC_BW_SHIFT		8	/* mimo bw shift */
+-#define RSPEC_STF_MASK		0x00003800	/* mimo Space/Time/Frequency mode mask */
+-#define RSPEC_STF_SHIFT		11	/* mimo Space/Time/Frequency mode shift */
+-#define RSPEC_CT_MASK		0x0000C000	/* mimo coding type mask */
+-#define RSPEC_CT_SHIFT		14	/* mimo coding type shift */
+-#define RSPEC_STC_MASK		0x00300000	/* mimo num STC streams per PLCP defn. */
+-#define RSPEC_STC_SHIFT		20	/* mimo num STC streams per PLCP defn. */
+-#define RSPEC_LDPC_CODING	0x00400000	/* mimo bit indicates adv coding in use */
+-#define RSPEC_SHORT_GI		0x00800000	/* mimo bit indicates short GI in use */
+-#define RSPEC_OVERRIDE		0x80000000	/* bit indicates override both rate & mode */
+-#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000	/* bit indicates override rate only */
+-
+-#define WLC_HTPHY		127	/* HT PHY Membership */
+-
+-#define RSPEC_ACTIVE(rspec)	(rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE))
+-#define RSPEC2RATE(rspec)      	((rspec & RSPEC_MIMORATE) ? \
+-	MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \
+-	(rspec & RSPEC_RATE_MASK))
+-/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
+-#define RSPEC2RATE500K(rspec)	((rspec & RSPEC_MIMORATE) ? \
+-		MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \
+-		(rspec & RSPEC_RATE_MASK))
+-#define CRSPEC2RATE500K(rspec)	((rspec & RSPEC_MIMORATE) ? \
+-		MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\
+-		(rspec & RSPEC_RATE_MASK))
+-
+-#define RSPEC2KBPS(rspec)	(IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500)
+-#define RSPEC_PHYTXBYTE2(rspec)	((rspec & 0xff00) >> 8)
+-#define RSPEC_GET_BW(rspec)	((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT)
+-#define RSPEC_IS40MHZ(rspec)	((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \
+-				PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \
+-				RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP))
+-#define RSPEC_ISSGI(rspec)	((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI)
+-#define RSPEC_MIMOPLCP3(rspec)	((rspec & 0xf00000) >> 16)
+-#define PLCP3_ISSGI(plcp)	(plcp & (RSPEC_SHORT_GI >> 16))
+-#define RSPEC_STC(rspec)	((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT)
+-#define RSPEC_STF(rspec)	((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT)
+-#define PLCP3_ISSTBC(plcp)	((plcp & (RSPEC_STC_MASK) >> 16) == 0x10)
+-#define PLCP3_STC_MASK          0x30
+-#define PLCP3_STC_SHIFT         4
+-
+-/* Rate info table; takes a legacy rate or ratespec_t */
+-#define	IS_MCS(r)     	(r & RSPEC_MIMORATE)
+-#define	IS_OFDM(r)     	(!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG))
+-#define	IS_CCK(r)	(!IS_MCS(r) && ( \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_1M || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_2M || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_5M5 || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_11M))
+-#define IS_SINGLE_STREAM(mcs)	(((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
+-#define CCK_RSPEC(cck)		((cck) & RSPEC_RATE_MASK)
+-#define OFDM_RSPEC(ofdm)	(((ofdm) & RSPEC_RATE_MASK) |\
+-	(PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT))
+-#define LEGACY_RSPEC(rate)	(IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate))
+-
+-#define MCS_RSPEC(mcs)		(((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \
+-	(IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \
+-	(PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT)))
+-
+-/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
+-extern const u8 ofdm_rate_lookup[];
+-#define OFDM_PHY2MAC_RATE(rlpt)		(ofdm_rate_lookup[rlpt & 0x7])
+-#define CCK_PHY2MAC_RATE(signal)	(signal/5)
+-
+-/* Rates specified in wlc_rateset_filter() */
+-#define WLC_RATES_CCK_OFDM	0
+-#define WLC_RATES_CCK		1
+-#define WLC_RATES_OFDM		2
+-
+-/* use the stuct form instead of typedef to fix dependency problems */
+-struct wlc_rateset;
+-
+-/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */
+-extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs,
+-					       const struct wlc_rateset *hw_rs,
+-					       bool check_brate,
+-					       u8 txstreams);
+-/* copy rateset src to dst as-is (no masking or sorting) */
+-extern void wlc_rateset_copy(const struct wlc_rateset *src,
+-			     struct wlc_rateset *dst);
+-
+-/* would be nice to have these documented ... */
+-extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp);
+-
+-extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst,
+-			       bool basic_only, u8 rates, uint xmask,
+-			       bool mcsallow);
+-extern void wlc_rateset_default(struct wlc_rateset *rs_tgt,
+-				const struct wlc_rateset *rs_hw, uint phy_type,
+-				int bandtype, bool cck_only, uint rate_mask,
+-				bool mcsallow, u8 bw, u8 txstreams);
+-extern s16 wlc_rate_legacy_phyctl(uint rate);
+-
+-extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams);
+-extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset);
+-extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams);
+-extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw);
+-
+-#endif				/* _WLC_RATE_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h
+deleted file mode 100644
+index f07a891..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h
++++ /dev/null
+@@ -1,80 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_scb_h_
+-#define _wlc_scb_h_
+-
+-#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
+-/* structure to store per-tid state for the ampdu initiator */
+-typedef struct scb_ampdu_tid_ini {
+-	u32 magic;
+-	u8 tx_in_transit;	/* number of pending mpdus in transit in driver */
+-	u8 tid;		/* initiator tid for easy lookup */
+-	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];	/* tx retry count; indexed by seq modulo */
+-	struct scb *scb;	/* backptr for easy lookup */
+-} scb_ampdu_tid_ini_t;
+-
+-#define AMPDU_MAX_SCB_TID	NUMPRIO
+-
+-typedef struct scb_ampdu {
+-	struct scb *scb;	/* back pointer for easy reference */
+-	u8 mpdu_density;	/* mpdu density */
+-	u8 max_pdu;		/* max pdus allowed in ampdu */
+-	u8 release;		/* # of mpdus released at a time */
+-	u16 min_len;		/* min mpdu len to support the density */
+-	u32 max_rxlen;	/* max ampdu rcv length; 8k, 16k, 32k, 64k */
+-	struct pktq txq;	/* sdu transmit queue pending aggregation */
+-
+-	/* This could easily be a ini[] pointer and we keep this info in wl itself instead
+-	 * of having mac80211 hold it for us.  Also could be made dynamic per tid instead of
+-	 * static.
+-	 */
+-	scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID];	/* initiator info - per tid (NUMPRIO) */
+-} scb_ampdu_t;
+-
+-#define SCB_MAGIC 	0xbeefcafe
+-#define INI_MAGIC 	0xabcd1234
+-
+-/* station control block - one per remote MAC address */
+-struct scb {
+-	u32 magic;
+-	u32 flags;		/* various bit flags as defined below */
+-	u32 flags2;		/* various bit flags2 as defined below */
+-	u8 state;		/* current state bitfield of auth/assoc process */
+-	u8 ea[ETH_ALEN];	/* station address */
+-	void *fragbuf[NUMPRIO];	/* defragmentation buffer per prio */
+-	uint fragresid[NUMPRIO];	/* #bytes unused in frag buffer per prio */
+-
+-	u16 seqctl[NUMPRIO];	/* seqctl of last received frame (for dups) */
+-	u16 seqctl_nonqos;	/* seqctl of last received frame (for dups) for
+-				 * non-QoS data and management
+-				 */
+-	u16 seqnum[NUMPRIO];	/* WME: driver maintained sw seqnum per priority */
+-
+-	scb_ampdu_t scb_ampdu;	/* AMPDU state including per tid info */
+-};
+-
+-/* scb flags */
+-#define SCB_WMECAP		0x0040	/* may ONLY be set if WME_ENAB(wlc) */
+-#define SCB_HTCAP		0x10000	/* HT (MIMO) capable device */
+-#define SCB_IS40		0x80000	/* 40MHz capable */
+-#define SCB_STBCCAP		0x40000000	/* STBC Capable */
+-#define SCB_WME(a)		((a)->flags & SCB_WMECAP)/* implies WME_ENAB */
+-#define SCB_SEQNUM(scb, prio)	((scb)->seqnum[(prio)])
+-#define SCB_PS(a)		NULL
+-#define SCB_STBC_CAP(a)		((a)->flags & SCB_STBCCAP)
+-#define SCB_AMPDU(a)		true
+-#endif				/* _wlc_scb_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c
+deleted file mode 100644
+index c4f5817..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c
++++ /dev/null
+@@ -1,523 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-
+-#include <proto/802.11.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <bcmwifi.h>
+-#include <bcmnvram.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wlc_bmac.h"
+-#include "wlc_stf.h"
+-
+-#define MIN_SPATIAL_EXPANSION	0
+-#define MAX_SPATIAL_EXPANSION	1
+-
+-#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \
+-	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
+-
+-static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val);
+-static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val);
+-static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val);
+-static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val);
+-
+-static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec);
+-
+-#define NSTS_1	1
+-#define NSTS_2	2
+-#define NSTS_3	3
+-#define NSTS_4	4
+-const u8 txcore_default[5] = {
+-	(0),			/* bitmap of the core enabled */
+-	(0x01),			/* For Nsts = 1, enable core 1 */
+-	(0x03),			/* For Nsts = 2, enable core 1 & 2 */
+-	(0x07),			/* For Nsts = 3, enable core 1, 2 & 3 */
+-	(0x0f)			/* For Nsts = 4, enable all cores */
+-};
+-
+-static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val)
+-{
+-	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
+-	if (WLC_STF_SS_STBC_RX(wlc)) {
+-		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
+-			return;
+-	}
+-
+-	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_RX_STBC;
+-	wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-	}
+-}
+-
+-/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */
+-void wlc_tempsense_upd(struct wlc_info *wlc)
+-{
+-	wlc_phy_t *pi = wlc->band->pi;
+-	uint active_chains, txchain;
+-
+-	/* Check if the chip is too hot. Disable one Tx chain, if it is */
+-	/* high 4 bits are for Rx chain, low 4 bits are  for Tx chain */
+-	active_chains = wlc_phy_stf_chain_active_get(pi);
+-	txchain = active_chains & 0xf;
+-
+-	if (wlc->stf->txchain == wlc->stf->hw_txchain) {
+-		if (txchain && (txchain < wlc->stf->hw_txchain)) {
+-			/* turn off 1 tx chain */
+-			wlc_stf_txchain_set(wlc, txchain, true);
+-		}
+-	} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
+-		if (txchain == wlc->stf->hw_txchain) {
+-			/* turn back on txchain */
+-			wlc_stf_txchain_set(wlc, txchain, true);
+-		}
+-	}
+-}
+-
+-void
+-wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel,
+-			    chanspec_t chanspec)
+-{
+-	tx_power_t power;
+-	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
+-
+-	/* Clear previous settings */
+-	*ss_algo_channel = 0;
+-
+-	if (!wlc->pub->up) {
+-		*ss_algo_channel = (u16) -1;
+-		return;
+-	}
+-
+-	wlc_phy_txpower_get_current(wlc->band->pi, &power,
+-				    CHSPEC_CHANNEL(chanspec));
+-
+-	siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
+-	cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
+-	stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
+-
+-	/* criteria to choose stf mode */
+-
+-	/* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs
+-	 * on both chains
+-	 */
+-	if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
+-	else
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
+-
+-	/* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check
+-	 * so cannot be default mode of operation. One of SISO, CDD have to be set
+-	 */
+-	if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
+-}
+-
+-static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val)
+-{
+-	if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) {
+-		return false;
+-	}
+-
+-	if ((int_val == ON) && (wlc->stf->txstreams == 1))
+-		return false;
+-
+-	if ((int_val == OFF) || (wlc->stf->txstreams == 1)
+-	    || !WLC_STBC_CAP_PHY(wlc))
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
+-	else
+-		wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC;
+-
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
+-
+-	return true;
+-}
+-
+-bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val)
+-{
+-	if ((int_val != HT_CAP_RX_STBC_NO)
+-	    && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) {
+-		return false;
+-	}
+-
+-	if (WLC_STF_SS_STBC_RX(wlc)) {
+-		if ((int_val != HT_CAP_RX_STBC_NO)
+-		    && (wlc->stf->rxstreams == 1))
+-			return false;
+-	}
+-
+-	wlc_stf_stbc_rx_ht_update(wlc, int_val);
+-	return true;
+-}
+-
+-static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
+-		 wlc->pub->unit, Nsts, core_mask);
+-
+-	if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) {
+-		core_mask = 0;
+-	}
+-
+-	if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) &&
+-	    ((core_mask & ~wlc->stf->txchain)
+-	     || !(core_mask & wlc->stf->txchain))) {
+-		core_mask = wlc->stf->txchain;
+-	}
+-
+-	wlc->stf->txcore[Nsts] = core_mask;
+-	/* Nsts = 1..4, txcore index = 1..4 */
+-	if (Nsts == 1) {
+-		/* Needs to update beacon and ucode generated response
+-		 * frames when 1 stream core map changed
+-		 */
+-		wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
+-		wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+-		if (wlc->clk) {
+-			wlc_suspend_mac_and_wait(wlc);
+-			wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+-			wlc_enable_mac(wlc);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val)
+-{
+-	int i;
+-	u8 core_mask = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
+-
+-	wlc->stf->spatial_policy = (s8) val;
+-	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
+-		core_mask = (val == MAX_SPATIAL_EXPANSION) ?
+-		    wlc->stf->txchain : txcore_default[i];
+-		wlc_stf_txcore_set(wlc, (u8) i, core_mask);
+-	}
+-	return 0;
+-}
+-
+-int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force)
+-{
+-	u8 txchain = (u8) int_val;
+-	u8 txstreams;
+-	uint i;
+-
+-	if (wlc->stf->txchain == txchain)
+-		return 0;
+-
+-	if ((txchain & ~wlc->stf->hw_txchain)
+-	    || !(txchain & wlc->stf->hw_txchain))
+-		return -EINVAL;
+-
+-	/* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
+-	txstreams = (u8) WLC_BITSCNT(txchain);
+-	if (txstreams > MAX_STREAMS_SUPPORTED)
+-		return -EINVAL;
+-
+-	if (txstreams == 1) {
+-		for (i = 0; i < NBANDS(wlc); i++)
+-			if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
+-			     PHY_TXC1_MODE_SISO)
+-			    || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
+-				PHY_TXC1_MODE_SISO)) {
+-				if (!force)
+-					return -EBADE;
+-
+-				/* over-write the override rspec */
+-				if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
+-				    != PHY_TXC1_MODE_SISO) {
+-					wlc->bandstate[i]->rspec_override = 0;
+-					wiphy_err(wlc->wiphy, "%s(): temp "
+-						  "sense override non-SISO "
+-						  "rspec_override\n",
+-						  __func__);
+-				}
+-				if (RSPEC_STF
+-				    (wlc->bandstate[i]->mrspec_override) !=
+-				    PHY_TXC1_MODE_SISO) {
+-					wlc->bandstate[i]->mrspec_override = 0;
+-					wiphy_err(wlc->wiphy, "%s(): temp "
+-						  "sense override non-SISO "
+-						  "mrspec_override\n",
+-						  __func__);
+-				}
+-			}
+-	}
+-
+-	wlc->stf->txchain = txchain;
+-	wlc->stf->txstreams = txstreams;
+-	wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-	wlc->stf->txant =
+-	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
+-	_wlc_stf_phy_txant_upd(wlc);
+-
+-	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+-			      wlc->stf->rxchain);
+-
+-	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
+-		wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
+-
+-	return 0;
+-}
+-
+-/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
+-int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band)
+-{
+-	int ret_code = 0;
+-	u8 prev_stf_ss;
+-	u8 upd_stf_ss;
+-
+-	prev_stf_ss = wlc->stf->ss_opmode;
+-
+-	/* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */
+-	if (WLC_STBC_CAP_PHY(wlc) &&
+-	    wlc->stf->ss_algosel_auto
+-	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
+-		upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
+-			      || isset(&wlc->stf->ss_algo_channel,
+-				       PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
+-		    : PHY_TXC1_MODE_CDD;
+-	} else {
+-		if (wlc->band != band)
+-			return ret_code;
+-		upd_stf_ss = (wlc->stf->no_cddstbc
+-			      || (wlc->stf->txstreams ==
+-				  1)) ? PHY_TXC1_MODE_SISO : band->
+-		    band_stf_ss_mode;
+-	}
+-	if (prev_stf_ss != upd_stf_ss) {
+-		wlc->stf->ss_opmode = upd_stf_ss;
+-		wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss);
+-	}
+-
+-	return ret_code;
+-}
+-
+-int wlc_stf_attach(struct wlc_info *wlc)
+-{
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
+-
+-	if (WLCISNPHY(wlc->band) &&
+-	    (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
+-		wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
+-		    PHY_TXC1_MODE_CDD;
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-
+-	wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+-
+-	if (WLC_STBC_CAP_PHY(wlc)) {
+-		wlc->stf->ss_algosel_auto = true;
+-		wlc->stf->ss_algo_channel = (u16) -1;	/* Init the default value */
+-	}
+-	return 0;
+-}
+-
+-void wlc_stf_detach(struct wlc_info *wlc)
+-{
+-}
+-
+-int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val)
+-{
+-	int bcmerror = 0;
+-
+-	/* when there is only 1 tx_streams, don't allow to change the txant */
+-	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+-		return ((val == wlc->stf->txant) ? bcmerror : -EINVAL);
+-
+-	switch (val) {
+-	case -1:
+-		val = ANT_TX_DEF;
+-		break;
+-	case 0:
+-		val = ANT_TX_FORCE_0;
+-		break;
+-	case 1:
+-		val = ANT_TX_FORCE_1;
+-		break;
+-	case 3:
+-		val = ANT_TX_LAST_RX;
+-		break;
+-	default:
+-		bcmerror = -EINVAL;
+-		break;
+-	}
+-
+-	if (bcmerror == 0)
+-		wlc->stf->txant = (s8) val;
+-
+-	return bcmerror;
+-
+-}
+-
+-/*
+- * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain
+- *  change
+- *
+- * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
+- *   achieve various tx/rx antenna selection schemes
+- *
+- * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx)
+- * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+- *    do tx-antenna selection for SISO transmissions
+- * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+- *    do tx-antenna selection for SISO transmissions
+- * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active
+-*/
+-static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc)
+-{
+-	s8 txant;
+-
+-	txant = (s8) wlc->stf->txant;
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		if (txant == ANT_TX_FORCE_0) {
+-			wlc->stf->phytxant = PHY_TXC_ANT_0;
+-		} else if (txant == ANT_TX_FORCE_1) {
+-			wlc->stf->phytxant = PHY_TXC_ANT_1;
+-
+-			if (WLCISNPHY(wlc->band) &&
+-			    NREV_GE(wlc->band->phyrev, 3)
+-			    && NREV_LT(wlc->band->phyrev, 7)) {
+-				wlc->stf->phytxant = PHY_TXC_ANT_2;
+-			}
+-		} else {
+-			if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band))
+-				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
+-			else {
+-				/* catch out of sync wlc->stf->txcore */
+-				WARN_ON(wlc->stf->txchain <= 0);
+-				wlc->stf->phytxant =
+-				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-			}
+-		}
+-	} else {
+-		if (txant == ANT_TX_FORCE_0)
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
+-		else if (txant == ANT_TX_FORCE_1)
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
+-		else
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
+-	}
+-
+-	wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+-}
+-
+-void wlc_stf_phy_txant_upd(struct wlc_info *wlc)
+-{
+-	_wlc_stf_phy_txant_upd(wlc);
+-}
+-
+-void wlc_stf_phy_chain_calc(struct wlc_info *wlc)
+-{
+-	/* get available rx/tx chains */
+-	wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain");
+-	wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain");
+-
+-	/* these parameter are intended to be used for all PHY types */
+-	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
+-		if (WLCISNPHY(wlc->band)) {
+-			wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
+-		} else {
+-			wlc->stf->hw_txchain = TXCHAIN_DEF;
+-		}
+-	}
+-
+-	wlc->stf->txchain = wlc->stf->hw_txchain;
+-	wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain);
+-
+-	if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
+-		if (WLCISNPHY(wlc->band)) {
+-			wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
+-		} else {
+-			wlc->stf->hw_rxchain = RXCHAIN_DEF;
+-		}
+-	}
+-
+-	wlc->stf->rxchain = wlc->stf->hw_rxchain;
+-	wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain);
+-
+-	/* initialize the txcore table */
+-	memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
+-
+-	/* default spatial_policy */
+-	wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
+-	wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
+-}
+-
+-static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phytxant = wlc->stf->phytxant;
+-
+-	if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
+-		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-	} else if (wlc->stf->txant == ANT_TX_DEF)
+-		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-	phytxant &= PHY_TXC_ANT_MASK;
+-	return phytxant;
+-}
+-
+-u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	return _wlc_stf_phytxchain_sel(wlc, rspec);
+-}
+-
+-u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phytxant = wlc->stf->phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* for non-siso rates or default setting, use the available chains */
+-	if (WLCISNPHY(wlc->band)) {
+-		phytxant = _wlc_stf_phytxchain_sel(wlc, rspec);
+-		mask = PHY_TXC_HTANT_MASK;
+-	}
+-	phytxant |= phytxant & mask;
+-	return phytxant;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h
+deleted file mode 100644
+index 2b1180b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_stf_h_
+-#define _wlc_stf_h_
+-
+-extern int wlc_stf_attach(struct wlc_info *wlc);
+-extern void wlc_stf_detach(struct wlc_info *wlc);
+-
+-extern void wlc_tempsense_upd(struct wlc_info *wlc);
+-extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc,
+-					u16 *ss_algo_channel,
+-					chanspec_t chanspec);
+-extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band);
+-extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force);
+-extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val);
+-
+-extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val);
+-extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc);
+-extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec);
+-extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec);
+-
+-#endif				/* _wlc_stf_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/wlc_types.h
+deleted file mode 100644
+index df6e04c..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_types.h
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_types_h_
+-#define _wlc_types_h_
+-
+-/* forward declarations */
+-
+-struct wlc_info;
+-struct wlc_hw_info;
+-struct wlc_if;
+-struct wl_if;
+-struct ampdu_info;
+-struct antsel_info;
+-struct bmac_pmq;
+-
+-struct d11init;
+-
+-#ifndef _hnddma_pub_
+-#define _hnddma_pub_
+-struct hnddma_pub;
+-#endif				/* _hnddma_pub_ */
+-
+-#endif				/* _wlc_types_h_ */
+diff --git a/drivers/staging/brcm80211/include/aidmp.h b/drivers/staging/brcm80211/include/aidmp.h
+deleted file mode 100644
+index 7e0ce8f..0000000
+--- a/drivers/staging/brcm80211/include/aidmp.h
++++ /dev/null
+@@ -1,374 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_AIDMP_H
+-#define	_AIDMP_H
+-
+-/* Manufacturer Ids */
+-#define	MFGID_ARM		0x43b
+-#define	MFGID_BRCM		0x4bf
+-#define	MFGID_MIPS		0x4a7
+-
+-/* Component Classes */
+-#define	CC_SIM			0
+-#define	CC_EROM			1
+-#define	CC_CORESIGHT		9
+-#define	CC_VERIF		0xb
+-#define	CC_OPTIMO		0xd
+-#define	CC_GEN			0xe
+-#define	CC_PRIMECELL		0xf
+-
+-/* Enumeration ROM registers */
+-#define	ER_EROMENTRY		0x000
+-#define	ER_REMAPCONTROL		0xe00
+-#define	ER_REMAPSELECT		0xe04
+-#define	ER_MASTERSELECT		0xe10
+-#define	ER_ITCR			0xf00
+-#define	ER_ITIP			0xf04
+-
+-/* Erom entries */
+-#define	ER_TAG			0xe
+-#define	ER_TAG1			0x6
+-#define	ER_VALID		1
+-#define	ER_CI			0
+-#define	ER_MP			2
+-#define	ER_ADD			4
+-#define	ER_END			0xe
+-#define	ER_BAD			0xffffffff
+-
+-/* EROM CompIdentA */
+-#define	CIA_MFG_MASK		0xfff00000
+-#define	CIA_MFG_SHIFT		20
+-#define	CIA_CID_MASK		0x000fff00
+-#define	CIA_CID_SHIFT		8
+-#define	CIA_CCL_MASK		0x000000f0
+-#define	CIA_CCL_SHIFT		4
+-
+-/* EROM CompIdentB */
+-#define	CIB_REV_MASK		0xff000000
+-#define	CIB_REV_SHIFT		24
+-#define	CIB_NSW_MASK		0x00f80000
+-#define	CIB_NSW_SHIFT		19
+-#define	CIB_NMW_MASK		0x0007c000
+-#define	CIB_NMW_SHIFT		14
+-#define	CIB_NSP_MASK		0x00003e00
+-#define	CIB_NSP_SHIFT		9
+-#define	CIB_NMP_MASK		0x000001f0
+-#define	CIB_NMP_SHIFT		4
+-
+-/* EROM MasterPortDesc */
+-#define	MPD_MUI_MASK		0x0000ff00
+-#define	MPD_MUI_SHIFT		8
+-#define	MPD_MP_MASK		0x000000f0
+-#define	MPD_MP_SHIFT		4
+-
+-/* EROM AddrDesc */
+-#define	AD_ADDR_MASK		0xfffff000
+-#define	AD_SP_MASK		0x00000f00
+-#define	AD_SP_SHIFT		8
+-#define	AD_ST_MASK		0x000000c0
+-#define	AD_ST_SHIFT		6
+-#define	AD_ST_SLAVE		0x00000000
+-#define	AD_ST_BRIDGE		0x00000040
+-#define	AD_ST_SWRAP		0x00000080
+-#define	AD_ST_MWRAP		0x000000c0
+-#define	AD_SZ_MASK		0x00000030
+-#define	AD_SZ_SHIFT		4
+-#define	AD_SZ_4K		0x00000000
+-#define	AD_SZ_8K		0x00000010
+-#define	AD_SZ_16K		0x00000020
+-#define	AD_SZ_SZD		0x00000030
+-#define	AD_AG32			0x00000008
+-#define	AD_ADDR_ALIGN		0x00000fff
+-#define	AD_SZ_BASE		0x00001000	/* 4KB */
+-
+-/* EROM SizeDesc */
+-#define	SD_SZ_MASK		0xfffff000
+-#define	SD_SG32			0x00000008
+-#define	SD_SZ_ALIGN		0x00000fff
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-typedef volatile struct _aidmp {
+-	u32 oobselina30;	/* 0x000 */
+-	u32 oobselina74;	/* 0x004 */
+-	u32 PAD[6];
+-	u32 oobselinb30;	/* 0x020 */
+-	u32 oobselinb74;	/* 0x024 */
+-	u32 PAD[6];
+-	u32 oobselinc30;	/* 0x040 */
+-	u32 oobselinc74;	/* 0x044 */
+-	u32 PAD[6];
+-	u32 oobselind30;	/* 0x060 */
+-	u32 oobselind74;	/* 0x064 */
+-	u32 PAD[38];
+-	u32 oobselouta30;	/* 0x100 */
+-	u32 oobselouta74;	/* 0x104 */
+-	u32 PAD[6];
+-	u32 oobseloutb30;	/* 0x120 */
+-	u32 oobseloutb74;	/* 0x124 */
+-	u32 PAD[6];
+-	u32 oobseloutc30;	/* 0x140 */
+-	u32 oobseloutc74;	/* 0x144 */
+-	u32 PAD[6];
+-	u32 oobseloutd30;	/* 0x160 */
+-	u32 oobseloutd74;	/* 0x164 */
+-	u32 PAD[38];
+-	u32 oobsynca;	/* 0x200 */
+-	u32 oobseloutaen;	/* 0x204 */
+-	u32 PAD[6];
+-	u32 oobsyncb;	/* 0x220 */
+-	u32 oobseloutben;	/* 0x224 */
+-	u32 PAD[6];
+-	u32 oobsyncc;	/* 0x240 */
+-	u32 oobseloutcen;	/* 0x244 */
+-	u32 PAD[6];
+-	u32 oobsyncd;	/* 0x260 */
+-	u32 oobseloutden;	/* 0x264 */
+-	u32 PAD[38];
+-	u32 oobaextwidth;	/* 0x300 */
+-	u32 oobainwidth;	/* 0x304 */
+-	u32 oobaoutwidth;	/* 0x308 */
+-	u32 PAD[5];
+-	u32 oobbextwidth;	/* 0x320 */
+-	u32 oobbinwidth;	/* 0x324 */
+-	u32 oobboutwidth;	/* 0x328 */
+-	u32 PAD[5];
+-	u32 oobcextwidth;	/* 0x340 */
+-	u32 oobcinwidth;	/* 0x344 */
+-	u32 oobcoutwidth;	/* 0x348 */
+-	u32 PAD[5];
+-	u32 oobdextwidth;	/* 0x360 */
+-	u32 oobdinwidth;	/* 0x364 */
+-	u32 oobdoutwidth;	/* 0x368 */
+-	u32 PAD[37];
+-	u32 ioctrlset;	/* 0x400 */
+-	u32 ioctrlclear;	/* 0x404 */
+-	u32 ioctrl;		/* 0x408 */
+-	u32 PAD[61];
+-	u32 iostatus;	/* 0x500 */
+-	u32 PAD[127];
+-	u32 ioctrlwidth;	/* 0x700 */
+-	u32 iostatuswidth;	/* 0x704 */
+-	u32 PAD[62];
+-	u32 resetctrl;	/* 0x800 */
+-	u32 resetstatus;	/* 0x804 */
+-	u32 resetreadid;	/* 0x808 */
+-	u32 resetwriteid;	/* 0x80c */
+-	u32 PAD[60];
+-	u32 errlogctrl;	/* 0x900 */
+-	u32 errlogdone;	/* 0x904 */
+-	u32 errlogstatus;	/* 0x908 */
+-	u32 errlogaddrlo;	/* 0x90c */
+-	u32 errlogaddrhi;	/* 0x910 */
+-	u32 errlogid;	/* 0x914 */
+-	u32 errloguser;	/* 0x918 */
+-	u32 errlogflags;	/* 0x91c */
+-	u32 PAD[56];
+-	u32 intstatus;	/* 0xa00 */
+-	u32 PAD[127];
+-	u32 config;		/* 0xe00 */
+-	u32 PAD[63];
+-	u32 itcr;		/* 0xf00 */
+-	u32 PAD[3];
+-	u32 itipooba;	/* 0xf10 */
+-	u32 itipoobb;	/* 0xf14 */
+-	u32 itipoobc;	/* 0xf18 */
+-	u32 itipoobd;	/* 0xf1c */
+-	u32 PAD[4];
+-	u32 itipoobaout;	/* 0xf30 */
+-	u32 itipoobbout;	/* 0xf34 */
+-	u32 itipoobcout;	/* 0xf38 */
+-	u32 itipoobdout;	/* 0xf3c */
+-	u32 PAD[4];
+-	u32 itopooba;	/* 0xf50 */
+-	u32 itopoobb;	/* 0xf54 */
+-	u32 itopoobc;	/* 0xf58 */
+-	u32 itopoobd;	/* 0xf5c */
+-	u32 PAD[4];
+-	u32 itopoobain;	/* 0xf70 */
+-	u32 itopoobbin;	/* 0xf74 */
+-	u32 itopoobcin;	/* 0xf78 */
+-	u32 itopoobdin;	/* 0xf7c */
+-	u32 PAD[4];
+-	u32 itopreset;	/* 0xf90 */
+-	u32 PAD[15];
+-	u32 peripherialid4;	/* 0xfd0 */
+-	u32 peripherialid5;	/* 0xfd4 */
+-	u32 peripherialid6;	/* 0xfd8 */
+-	u32 peripherialid7;	/* 0xfdc */
+-	u32 peripherialid0;	/* 0xfe0 */
+-	u32 peripherialid1;	/* 0xfe4 */
+-	u32 peripherialid2;	/* 0xfe8 */
+-	u32 peripherialid3;	/* 0xfec */
+-	u32 componentid0;	/* 0xff0 */
+-	u32 componentid1;	/* 0xff4 */
+-	u32 componentid2;	/* 0xff8 */
+-	u32 componentid3;	/* 0xffc */
+-} aidmp_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* Out-of-band Router registers */
+-#define	OOB_BUSCONFIG		0x020
+-#define	OOB_STATUSA		0x100
+-#define	OOB_STATUSB		0x104
+-#define	OOB_STATUSC		0x108
+-#define	OOB_STATUSD		0x10c
+-#define	OOB_ENABLEA0		0x200
+-#define	OOB_ENABLEA1		0x204
+-#define	OOB_ENABLEA2		0x208
+-#define	OOB_ENABLEA3		0x20c
+-#define	OOB_ENABLEB0		0x280
+-#define	OOB_ENABLEB1		0x284
+-#define	OOB_ENABLEB2		0x288
+-#define	OOB_ENABLEB3		0x28c
+-#define	OOB_ENABLEC0		0x300
+-#define	OOB_ENABLEC1		0x304
+-#define	OOB_ENABLEC2		0x308
+-#define	OOB_ENABLEC3		0x30c
+-#define	OOB_ENABLED0		0x380
+-#define	OOB_ENABLED1		0x384
+-#define	OOB_ENABLED2		0x388
+-#define	OOB_ENABLED3		0x38c
+-#define	OOB_ITCR		0xf00
+-#define	OOB_ITIPOOBA		0xf10
+-#define	OOB_ITIPOOBB		0xf14
+-#define	OOB_ITIPOOBC		0xf18
+-#define	OOB_ITIPOOBD		0xf1c
+-#define	OOB_ITOPOOBA		0xf30
+-#define	OOB_ITOPOOBB		0xf34
+-#define	OOB_ITOPOOBC		0xf38
+-#define	OOB_ITOPOOBD		0xf3c
+-
+-/* DMP wrapper registers */
+-#define	AI_OOBSELINA30		0x000
+-#define	AI_OOBSELINA74		0x004
+-#define	AI_OOBSELINB30		0x020
+-#define	AI_OOBSELINB74		0x024
+-#define	AI_OOBSELINC30		0x040
+-#define	AI_OOBSELINC74		0x044
+-#define	AI_OOBSELIND30		0x060
+-#define	AI_OOBSELIND74		0x064
+-#define	AI_OOBSELOUTA30		0x100
+-#define	AI_OOBSELOUTA74		0x104
+-#define	AI_OOBSELOUTB30		0x120
+-#define	AI_OOBSELOUTB74		0x124
+-#define	AI_OOBSELOUTC30		0x140
+-#define	AI_OOBSELOUTC74		0x144
+-#define	AI_OOBSELOUTD30		0x160
+-#define	AI_OOBSELOUTD74		0x164
+-#define	AI_OOBSYNCA		0x200
+-#define	AI_OOBSELOUTAEN		0x204
+-#define	AI_OOBSYNCB		0x220
+-#define	AI_OOBSELOUTBEN		0x224
+-#define	AI_OOBSYNCC		0x240
+-#define	AI_OOBSELOUTCEN		0x244
+-#define	AI_OOBSYNCD		0x260
+-#define	AI_OOBSELOUTDEN		0x264
+-#define	AI_OOBAEXTWIDTH		0x300
+-#define	AI_OOBAINWIDTH		0x304
+-#define	AI_OOBAOUTWIDTH		0x308
+-#define	AI_OOBBEXTWIDTH		0x320
+-#define	AI_OOBBINWIDTH		0x324
+-#define	AI_OOBBOUTWIDTH		0x328
+-#define	AI_OOBCEXTWIDTH		0x340
+-#define	AI_OOBCINWIDTH		0x344
+-#define	AI_OOBCOUTWIDTH		0x348
+-#define	AI_OOBDEXTWIDTH		0x360
+-#define	AI_OOBDINWIDTH		0x364
+-#define	AI_OOBDOUTWIDTH		0x368
+-
+-#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
+-/* Selective swapped defines for those registers we need in
+- * big-endian code.
+- */
+-#define	AI_IOCTRLSET		0x404
+-#define	AI_IOCTRLCLEAR		0x400
+-#define	AI_IOCTRL		0x40c
+-#define	AI_IOSTATUS		0x504
+-#define	AI_RESETCTRL		0x804
+-#define	AI_RESETSTATUS		0x800
+-
+-#else				/* !__BIG_ENDIAN || !BCMHND74K */
+-
+-#define	AI_IOCTRLSET		0x400
+-#define	AI_IOCTRLCLEAR		0x404
+-#define	AI_IOCTRL		0x408
+-#define	AI_IOSTATUS		0x500
+-#define	AI_RESETCTRL		0x800
+-#define	AI_RESETSTATUS		0x804
+-
+-#endif				/* __BIG_ENDIAN && BCMHND74K */
+-
+-#define	AI_IOCTRLWIDTH		0x700
+-#define	AI_IOSTATUSWIDTH	0x704
+-
+-#define	AI_RESETREADID		0x808
+-#define	AI_RESETWRITEID		0x80c
+-#define	AI_ERRLOGCTRL		0xa00
+-#define	AI_ERRLOGDONE		0xa04
+-#define	AI_ERRLOGSTATUS		0xa08
+-#define	AI_ERRLOGADDRLO		0xa0c
+-#define	AI_ERRLOGADDRHI		0xa10
+-#define	AI_ERRLOGID		0xa14
+-#define	AI_ERRLOGUSER		0xa18
+-#define	AI_ERRLOGFLAGS		0xa1c
+-#define	AI_INTSTATUS		0xa00
+-#define	AI_CONFIG		0xe00
+-#define	AI_ITCR			0xf00
+-#define	AI_ITIPOOBA		0xf10
+-#define	AI_ITIPOOBB		0xf14
+-#define	AI_ITIPOOBC		0xf18
+-#define	AI_ITIPOOBD		0xf1c
+-#define	AI_ITIPOOBAOUT		0xf30
+-#define	AI_ITIPOOBBOUT		0xf34
+-#define	AI_ITIPOOBCOUT		0xf38
+-#define	AI_ITIPOOBDOUT		0xf3c
+-#define	AI_ITOPOOBA		0xf50
+-#define	AI_ITOPOOBB		0xf54
+-#define	AI_ITOPOOBC		0xf58
+-#define	AI_ITOPOOBD		0xf5c
+-#define	AI_ITOPOOBAIN		0xf70
+-#define	AI_ITOPOOBBIN		0xf74
+-#define	AI_ITOPOOBCIN		0xf78
+-#define	AI_ITOPOOBDIN		0xf7c
+-#define	AI_ITOPRESET		0xf90
+-#define	AI_PERIPHERIALID4	0xfd0
+-#define	AI_PERIPHERIALID5	0xfd4
+-#define	AI_PERIPHERIALID6	0xfd8
+-#define	AI_PERIPHERIALID7	0xfdc
+-#define	AI_PERIPHERIALID0	0xfe0
+-#define	AI_PERIPHERIALID1	0xfe4
+-#define	AI_PERIPHERIALID2	0xfe8
+-#define	AI_PERIPHERIALID3	0xfec
+-#define	AI_COMPONENTID0		0xff0
+-#define	AI_COMPONENTID1		0xff4
+-#define	AI_COMPONENTID2		0xff8
+-#define	AI_COMPONENTID3		0xffc
+-
+-/* resetctrl */
+-#define	AIRC_RESET		1
+-
+-/* config */
+-#define	AICFG_OOB		0x00000020
+-#define	AICFG_IOS		0x00000010
+-#define	AICFG_IOC		0x00000008
+-#define	AICFG_TO		0x00000004
+-#define	AICFG_ERRL		0x00000002
+-#define	AICFG_RST		0x00000001
+-
+-#endif				/* _AIDMP_H */
+diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h
+deleted file mode 100644
+index 55631f3..0000000
+--- a/drivers/staging/brcm80211/include/bcmdefs.h
++++ /dev/null
+@@ -1,150 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmdefs_h_
+-#define	_bcmdefs_h_
+-
+-#define	SI_BUS			0
+-#define	PCI_BUS			1
+-#define	PCMCIA_BUS		2
+-#define SDIO_BUS		3
+-#define JTAG_BUS		4
+-#define USB_BUS			5
+-#define SPI_BUS			6
+-
+-
+-#ifndef OFF
+-#define	OFF	0
+-#endif
+-
+-#ifndef ON
+-#define	ON	1		/* ON = 1 */
+-#endif
+-
+-#define	AUTO	(-1)		/* Auto = -1 */
+-
+-/* Bus types */
+-#define	SI_BUS			0	/* SOC Interconnect */
+-#define	PCI_BUS			1	/* PCI target */
+-#define SDIO_BUS		3	/* SDIO target */
+-#define JTAG_BUS		4	/* JTAG */
+-#define USB_BUS			5	/* USB (does not support R/W REG) */
+-#define SPI_BUS			6	/* gSPI target */
+-#define RPC_BUS			7	/* RPC target */
+-
+-
+-/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
+-#define DMADDR_MASK_32 0x0	/* Address mask for 32-bits */
+-#define DMADDR_MASK_30 0xc0000000	/* Address mask for 30-bits */
+-#define DMADDR_MASK_0  0xffffffff	/* Address mask for 0-bits (hi-part) */
+-
+-#define	DMADDRWIDTH_30  30	/* 30-bit addressing capability */
+-#define	DMADDRWIDTH_32  32	/* 32-bit addressing capability */
+-#define	DMADDRWIDTH_63  63	/* 64-bit addressing capability */
+-#define	DMADDRWIDTH_64  64	/* 64-bit addressing capability */
+-
+-#ifdef BCMDMA64OSL
+-typedef struct {
+-	u32 loaddr;
+-	u32 hiaddr;
+-} dma64addr_t;
+-
+-typedef dma64addr_t dmaaddr_t;
+-#define PHYSADDRHI(_pa) ((_pa).hiaddr)
+-#define PHYSADDRHISET(_pa, _val) \
+-	do { \
+-		(_pa).hiaddr = (_val);		\
+-	} while (0)
+-#define PHYSADDRLO(_pa) ((_pa).loaddr)
+-#define PHYSADDRLOSET(_pa, _val) \
+-	do { \
+-		(_pa).loaddr = (_val);		\
+-	} while (0)
+-
+-#else
+-typedef unsigned long dmaaddr_t;
+-#define PHYSADDRHI(_pa) (0)
+-#define PHYSADDRHISET(_pa, _val)
+-#define PHYSADDRLO(_pa) ((_pa))
+-#define PHYSADDRLOSET(_pa, _val) \
+-	do { \
+-		(_pa) = (_val);			\
+-	} while (0)
+-#endif				/* BCMDMA64OSL */
+-
+-/* One physical DMA segment */
+-typedef struct {
+-	dmaaddr_t addr;
+-	u32 length;
+-} hnddma_seg_t;
+-
+-#define MAX_DMA_SEGS 4
+-
+-typedef struct {
+-	void *oshdmah;		/* Opaque handle for OSL to store its information */
+-	uint origsize;		/* Size of the virtual packet */
+-	uint nsegs;
+-	hnddma_seg_t segs[MAX_DMA_SEGS];
+-} hnddma_seg_map_t;
+-
+-/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
+- * By doing, we avoid the need  to allocate an extra buffer for the header when bridging to WL.
+- * There is a compile time check in wlc.c which ensure that this value is at least as big
+- * as TXOFF. This value is used in dma_rxfill (hnddma.c).
+- */
+-
+-#define BCMEXTRAHDROOM 172
+-
+-/* Macros for doing definition and get/set of bitfields
+- * Usage example, e.g. a three-bit field (bits 4-6):
+- *    #define <NAME>_M	BITFIELD_MASK(3)
+- *    #define <NAME>_S	4
+- * ...
+- *    regval = R_REG(osh, &regs->regfoo);
+- *    field = GFIELD(regval, <NAME>);
+- *    regval = SFIELD(regval, <NAME>, 1);
+- *    W_REG(osh, &regs->regfoo, regval);
+- */
+-#define BITFIELD_MASK(width) \
+-		(((unsigned)1 << (width)) - 1)
+-#define GFIELD(val, field) \
+-		(((val) >> field ## _S) & field ## _M)
+-#define SFIELD(val, field, bits) \
+-		(((val) & (~(field ## _M << field ## _S))) | \
+-		 ((unsigned)(bits) << field ## _S))
+-
+-/*
+- * Priority definitions according 802.1D
+- */
+-#define	PRIO_8021D_NONE		2
+-#define	PRIO_8021D_BK		1
+-#define	PRIO_8021D_BE		0
+-#define	PRIO_8021D_EE		3
+-#define	PRIO_8021D_CL		4
+-#define	PRIO_8021D_VI		5
+-#define	PRIO_8021D_VO		6
+-#define	PRIO_8021D_NC		7
+-#define	MAXPRIO			7
+-#define NUMPRIO			(MAXPRIO + 1)
+-
+-/* Max. nvram variable table size */
+-#define	MAXSZ_NVRAM_VARS	4096
+-
+-/* handle forward declaration */
+-struct wl_info;
+-struct wlc_bsscfg;
+-
+-#endif				/* _bcmdefs_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h
+deleted file mode 100644
+index 26947ef..0000000
+--- a/drivers/staging/brcm80211/include/bcmdevs.h
++++ /dev/null
+@@ -1,124 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_BCMDEVS_H
+-#define	_BCMDEVS_H
+-
+-#define	BCM4325_D11DUAL_ID	0x431b
+-#define	BCM4325_D11G_ID		0x431c
+-#define	BCM4325_D11A_ID		0x431d
+-
+-#define BCM4329_D11N2G_ID	0x432f	/* 4329 802.11n 2.4G device */
+-#define BCM4329_D11N5G_ID	0x4330	/* 4329 802.11n 5G device */
+-#define BCM4329_D11NDUAL_ID	0x432e
+-
+-#define BCM4319_D11N_ID		0x4337	/* 4319 802.11n dualband device */
+-#define BCM4319_D11N2G_ID	0x4338	/* 4319 802.11n 2.4G device */
+-#define BCM4319_D11N5G_ID	0x4339	/* 4319 802.11n 5G device */
+-
+-#define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
+-
+-#define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
+-
+-#define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
+-#define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
+-
+-#define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
+-
+-/* Chip IDs */
+-#define BCM4313_CHIP_ID		0x4313	/* 4313 chip id */
+-#define	BCM4319_CHIP_ID		0x4319	/* 4319 chip id */
+-
+-#define	BCM43224_CHIP_ID	43224	/* 43224 chipcommon chipid */
+-#define	BCM43225_CHIP_ID	43225	/* 43225 chipcommon chipid */
+-#define	BCM43421_CHIP_ID	43421	/* 43421 chipcommon chipid */
+-#define	BCM43235_CHIP_ID	43235	/* 43235 chipcommon chipid */
+-#define	BCM43236_CHIP_ID	43236	/* 43236 chipcommon chipid */
+-#define	BCM43238_CHIP_ID	43238	/* 43238 chipcommon chipid */
+-#define	BCM4329_CHIP_ID		0x4329	/* 4329 chipcommon chipid */
+-#define	BCM4325_CHIP_ID		0x4325	/* 4325 chipcommon chipid */
+-#define	BCM4331_CHIP_ID		0x4331	/* 4331 chipcommon chipid */
+-#define BCM4336_CHIP_ID		0x4336	/* 4336 chipcommon chipid */
+-#define BCM4330_CHIP_ID		0x4330	/* 4330 chipcommon chipid */
+-#define BCM6362_CHIP_ID		0x6362	/* 6362 chipcommon chipid */
+-
+-/* these are router chips */
+-#define	BCM4716_CHIP_ID		0x4716	/* 4716 chipcommon chipid */
+-#define	BCM47162_CHIP_ID	47162	/* 47162 chipcommon chipid */
+-#define	BCM4748_CHIP_ID		0x4748	/* 4716 chipcommon chipid (OTP, RBBU) */
+-#define	BCM5356_CHIP_ID		0x5356	/* 5356 chipcommon chipid */
+-#define	BCM5357_CHIP_ID		0x5357	/* 5357 chipcommon chipid */
+-
+-/* Package IDs */
+-#define BCM4329_289PIN_PKG_ID	0	/* 4329 289-pin package id */
+-#define BCM4329_182PIN_PKG_ID	1	/* 4329N 182-pin package id */
+-#define	BCM4717_PKG_ID		9	/* 4717 package id */
+-#define	BCM4718_PKG_ID		10	/* 4718 package id */
+-#define HDLSIM_PKG_ID		14	/* HDL simulator package id */
+-#define HWSIM_PKG_ID		15	/* Hardware simulator package id */
+-#define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
+-
+-/* boardflags */
+-#define	BFL_PACTRL		0x00000002	/* Board has gpio 9 controlling the PA */
+-#define	BFL_NOPLLDOWN		0x00000020	/* Not ok to power down the chip pll and oscillator */
+-#define BFL_FEM			0x00000800	/* Board supports the Front End Module */
+-#define BFL_EXTLNA		0x00001000	/* Board has an external LNA in 2.4GHz band */
+-#define BFL_NOPA		0x00010000	/* Board has no PA */
+-#define BFL_BUCKBOOST		0x00200000	/* Power topology uses BUCKBOOST */
+-#define BFL_FEM_BT		0x00400000	/* Board has FEM and switch to share antenna w/ BT */
+-#define BFL_NOCBUCK		0x00800000	/* Power topology doesn't use CBUCK */
+-#define BFL_PALDO		0x02000000	/* Power topology uses PALDO */
+-#define BFL_EXTLNA_5GHz		0x10000000	/* Board has an external LNA in 5GHz band */
+-
+-/* boardflags2 */
+-#define BFL2_RXBB_INT_REG_DIS	0x00000001	/* Board has an external rxbb regulator */
+-#define BFL2_APLL_WAR		0x00000002	/* Flag to implement alternative A-band PLL settings */
+-#define BFL2_TXPWRCTRL_EN	0x00000004	/* Board permits enabling TX Power Control */
+-#define BFL2_2X4_DIV		0x00000008	/* Board supports the 2X4 diversity switch */
+-#define BFL2_5G_PWRGAIN		0x00000010	/* Board supports 5G band power gain */
+-#define BFL2_PCIEWAR_OVR	0x00000020	/* Board overrides ASPM and Clkreq settings */
+-#define BFL2_LEGACY		0x00000080
+-#define BFL2_SKWRKFEM_BRD	0x00000100	/* 4321mcm93 board uses Skyworks FEM */
+-#define BFL2_SPUR_WAR		0x00000200	/* Board has a WAR for clock-harmonic spurs */
+-#define BFL2_GPLL_WAR		0x00000400	/* Flag to narrow G-band PLL loop b/w */
+-#define BFL2_SINGLEANT_CCK	0x00001000	/* Tx CCK pkts on Ant 0 only */
+-#define BFL2_2G_SPUR_WAR	0x00002000	/* WAR to reduce and avoid clock-harmonic spurs in 2G */
+-#define BFL2_GPLL_WAR2	        0x00010000	/* Flag to widen G-band PLL loop b/w */
+-#define BFL2_IPALVLSHIFT_3P3    0x00020000
+-#define BFL2_INTERNDET_TXIQCAL  0x00040000	/* Use internal envelope detector for TX IQCAL */
+-#define BFL2_XTALBUFOUTEN       0x00080000	/* Keep the buffered Xtal output from radio "ON"
+-						 * Most drivers will turn it off without this flag
+-						 * to save power.
+-						 */
+-
+-/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
+-#define	BOARD_GPIO_PACTRL	0x200	/* bit 9 controls the PA on new 4306 boards */
+-#define BOARD_GPIO_12		0x1000	/* gpio 12 */
+-#define BOARD_GPIO_13		0x2000	/* gpio 13 */
+-
+-#define	PCI_CFG_GPIO_SCS	0x10	/* PCI config space bit 4 for 4306c0 slow clock source */
+-#define PCI_CFG_GPIO_XTAL	0x40	/* PCI config space GPIO 14 for Xtal power-up */
+-#define PCI_CFG_GPIO_PLL	0x80	/* PCI config space GPIO 15 for PLL power-down */
+-
+-/* power control defines */
+-#define PLL_DELAY		150	/* us pll on delay */
+-#define FREF_DELAY		200	/* us fref change delay */
+-#define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
+-
+-/* Reference board types */
+-#define	SPI_BOARD		0x0402
+-
+-#endif				/* _BCMDEVS_H */
+diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h
+deleted file mode 100644
+index 12645dd..0000000
+--- a/drivers/staging/brcm80211/include/bcmnvram.h
++++ /dev/null
+@@ -1,153 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _bcmnvram_h_
+-#define _bcmnvram_h_
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-#include <bcmdefs.h>
+-
+-struct nvram_header {
+-	u32 magic;
+-	u32 len;
+-	u32 crc_ver_init;	/* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+-	u32 config_refresh;	/* 0:15 sdram_config, 16:31 sdram_refresh */
+-	u32 config_ncdl;	/* ncdl values for memc */
+-};
+-
+-/*
+- * Initialize NVRAM access. May be unnecessary or undefined on certain
+- * platforms.
+- */
+-extern int nvram_init(void);
+-
+-/*
+- * Append a chunk of nvram variables to the global list
+- */
+-extern int nvram_append(char *vars, uint varsz);
+-
+-/*
+- * Check for reset button press for restoring factory defaults.
+- */
+-extern int nvram_reset(void);
+-
+-/*
+- * Disable NVRAM access. May be unnecessary or undefined on certain
+- * platforms.
+- */
+-extern void nvram_exit(void);
+-
+-/*
+- * Get the value of an NVRAM variable. The pointer returned may be
+- * invalid after a set.
+- * @param	name	name of variable to get
+- * @return	value of variable or NULL if undefined
+- */
+-extern char *nvram_get(const char *name);
+-
+-/*
+- * Get the value of an NVRAM variable.
+- * @param	name	name of variable to get
+- * @return	value of variable or NUL if undefined
+- */
+-#define nvram_safe_get(name) (nvram_get(name) ? : "")
+-
+-/*
+- * Match an NVRAM variable.
+- * @param	name	name of variable to match
+- * @param	match	value to compare against value of variable
+- * @return	true if variable is defined and its value is string equal
+- *		to match or false otherwise
+- */
+-static inline int nvram_match(char *name, char *match)
+-{
+-	const char *value = nvram_get(name);
+-	return value && !strcmp(value, match);
+-}
+-
+-/*
+- * Inversely match an NVRAM variable.
+- * @param	name	name of variable to match
+- * @param	match	value to compare against value of variable
+- * @return	true if variable is defined and its value is not string
+- *		equal to invmatch or false otherwise
+- */
+-static inline int nvram_invmatch(char *name, char *invmatch)
+-{
+-	const char *value = nvram_get(name);
+-	return value && strcmp(value, invmatch);
+-}
+-
+-/*
+- * Set the value of an NVRAM variable. The name and value strings are
+- * copied into private storage. Pointers to previously set values
+- * may become invalid. The new value may be immediately
+- * retrieved but will not be permanently stored until a commit.
+- * @param	name	name of variable to set
+- * @param	value	value of variable
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_set(const char *name, const char *value);
+-
+-/*
+- * Unset an NVRAM variable. Pointers to previously set values
+- * remain valid until a set.
+- * @param	name	name of variable to unset
+- * @return	0 on success and errno on failure
+- * NOTE: use nvram_commit to commit this change to flash.
+- */
+-extern int nvram_unset(const char *name);
+-
+-/*
+- * Commit NVRAM variables to permanent storage. All pointers to values
+- * may be invalid after a commit.
+- * NVRAM values are undefined after a commit.
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_commit(void);
+-
+-/*
+- * Get all NVRAM variables (format name=value\0 ... \0\0).
+- * @param	buf	buffer to store variables
+- * @param	count	size of buffer in bytes
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_getall(char *nvram_buf, int count);
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* variable access */
+-extern char *getvar(char *vars, const char *name);
+-extern int getintvar(char *vars, const char *name);
+-
+-/* The NVRAM version number stored as an NVRAM variable */
+-#define NVRAM_SOFTWARE_VERSION	"1"
+-
+-#define NVRAM_MAGIC		0x48534C46	/* 'FLSH' */
+-#define NVRAM_CLEAR_MAGIC	0x0
+-#define NVRAM_INVALID_MAGIC	0xFFFFFFFF
+-#define NVRAM_VERSION		1
+-#define NVRAM_HEADER_SIZE	20
+-#define NVRAM_SPACE		0x8000
+-
+-#define NVRAM_MAX_VALUE_LEN 255
+-#define NVRAM_MAX_PARAM_LEN 64
+-
+-#define NVRAM_CRC_START_POSITION	9	/* magic, len, crc8 to be skipped */
+-#define NVRAM_CRC_VER_MASK	0xffffff00	/* for crc_ver_init */
+-
+-#endif				/* _bcmnvram_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmotp.h b/drivers/staging/brcm80211/include/bcmotp.h
+deleted file mode 100644
+index 5803acc..0000000
+--- a/drivers/staging/brcm80211/include/bcmotp.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmotp_h_
+-#define	_bcmotp_h_
+-
+-/* OTP regions */
+-#define OTP_HW_RGN	1
+-#define OTP_SW_RGN	2
+-#define OTP_CI_RGN	4
+-#define OTP_FUSE_RGN	8
+-#define OTP_ALL_RGN	0xf	/* From h/w region to end of OTP including checksum */
+-
+-/* OTP Size */
+-#define OTP_SZ_MAX		(6144/8)	/* maximum bytes in one CIS */
+-
+-/* Fixed size subregions sizes in words */
+-#define OTPGU_CI_SZ		2
+-
+-/* OTP usage */
+-#define OTP4325_FM_DISABLED_OFFSET	188
+-
+-/* Exported functions */
+-extern int otp_status(void *oh);
+-extern int otp_size(void *oh);
+-extern u16 otp_read_bit(void *oh, uint offset);
+-extern void *otp_init(si_t *sih);
+-extern int otp_read_region(si_t *sih, int region, u16 *data, uint *wlen);
+-extern int otp_nvread(void *oh, char *data, uint *len);
+-
+-#endif				/* _bcmotp_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h
+deleted file mode 100644
+index 3b57dc1..0000000
+--- a/drivers/staging/brcm80211/include/bcmsdh.h
++++ /dev/null
+@@ -1,205 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsdh_h_
+-#define	_bcmsdh_h_
+-
+-#include <linux/skbuff.h>
+-#define BCMSDH_ERROR_VAL	0x0001	/* Error */
+-#define BCMSDH_INFO_VAL		0x0002	/* Info */
+-extern const uint bcmsdh_msglevel;
+-
+-#ifdef BCMDBG
+-#define BCMSDH_ERROR(x) \
+-	do { \
+-		if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define BCMSDH_INFO(x)	\
+-	do { \
+-		if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#else				/* BCMDBG */
+-#define BCMSDH_ERROR(x)
+-#define BCMSDH_INFO(x)
+-#endif				/* BCMDBG */
+-
+-/* forward declarations */
+-typedef struct bcmsdh_info bcmsdh_info_t;
+-typedef void (*bcmsdh_cb_fn_t) (void *);
+-
+-/* Attach and build an interface to the underlying SD host driver.
+- *  - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh.
+- *  - Returns the bcmsdh handle and virtual address base for register access.
+- *    The returned handle should be used in all subsequent calls, but the bcmsh
+- *    implementation may maintain a single "default" handle (e.g. the first or
+- *    most recent one) to enable single-instance implementations to pass NULL.
+- */
+-extern bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq);
+-
+-/* Detach - freeup resources allocated in attach */
+-extern int bcmsdh_detach(void *sdh);
+-
+-/* Query if SD device interrupts are enabled */
+-extern bool bcmsdh_intr_query(void *sdh);
+-
+-/* Enable/disable SD interrupt */
+-extern int bcmsdh_intr_enable(void *sdh);
+-extern int bcmsdh_intr_disable(void *sdh);
+-
+-/* Register/deregister device interrupt handler. */
+-extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+-extern int bcmsdh_intr_dereg(void *sdh);
+-
+-#if defined(DHD_DEBUG)
+-/* Query pending interrupt status from the host controller */
+-extern bool bcmsdh_intr_pending(void *sdh);
+-#endif
+-extern int bcmsdh_claim_host_and_lock(void *sdh);
+-extern int bcmsdh_release_host_and_unlock(void *sdh);
+-
+-/* Register a callback to be called if and when bcmsdh detects
+- * device removal. No-op in the case of non-removable/hardwired devices.
+- */
+-extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+-
+-/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
+- *   fn:   function number
+- *   addr: unmodified SDIO-space address
+- *   data: data byte to write
+- *   err:  pointer to error code (or NULL)
+- */
+-extern u8 bcmsdh_cfg_read(void *sdh, uint func, u32 addr, int *err);
+-extern void bcmsdh_cfg_write(void *sdh, uint func, u32 addr, u8 data,
+-			     int *err);
+-
+-/* Read/Write 4bytes from/to cfg space */
+-extern u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr,
+-				   int *err);
+-extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr,
+-				  u32 data, int *err);
+-
+-/* Read CIS content for specified function.
+- *   fn:     function whose CIS is being requested (0 is common CIS)
+- *   cis:    pointer to memory location to place results
+- *   length: number of bytes to read
+- * Internally, this routine uses the values from the cis base regs (0x9-0xB)
+- * to form an SDIO-space address to read the data from.
+- */
+-extern int bcmsdh_cis_read(void *sdh, uint func, u8 *cis, uint length);
+-
+-/* Synchronous access to device (client) core registers via CMD53 to F1.
+- *   addr: backplane address (i.e. >= regsva from attach)
+- *   size: register width in bytes (2 or 4)
+- *   data: data for register write
+- */
+-extern u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size);
+-extern u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data);
+-
+-/* Indicate if last reg read/write failed */
+-extern bool bcmsdh_regfail(void *sdh);
+-
+-/* Buffer transfer to/from device (client) core via cmd53.
+- *   fn:       function number
+- *   addr:     backplane address (i.e. >= regsva from attach)
+- *   flags:    backplane width, address increment, sync/async
+- *   buf:      pointer to memory data buffer
+- *   nbytes:   number of bytes to transfer to/from buf
+- *   pkt:      pointer to packet associated with buf (if any)
+- *   complete: callback function for command completion (async only)
+- *   handle:   handle for completion callback (first arg in callback)
+- * Returns 0 or error code.
+- * NOTE: Async operation is not currently supported.
+- */
+-typedef void (*bcmsdh_cmplt_fn_t) (void *handle, int status, bool sync_waiting);
+-extern int bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
+-			   u8 *buf, uint nbytes, void *pkt,
+-			   bcmsdh_cmplt_fn_t complete, void *handle);
+-extern int bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
+-			   u8 *buf, uint nbytes, struct sk_buff *pkt,
+-			   bcmsdh_cmplt_fn_t complete, void *handle);
+-
+-/* Flags bits */
+-#define SDIO_REQ_4BYTE	0x1	/* Four-byte target (backplane) width (vs. two-byte) */
+-#define SDIO_REQ_FIXED	0x2	/* Fixed address (FIFO) (vs. incrementing address) */
+-#define SDIO_REQ_ASYNC	0x4	/* Async request (vs. sync request) */
+-
+-/* Pending (non-error) return code */
+-#define BCME_PENDING	1
+-
+-/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
+- *   rw:       read or write (0/1)
+- *   addr:     direct SDIO address
+- *   buf:      pointer to memory data buffer
+- *   nbytes:   number of bytes to transfer to/from buf
+- * Returns 0 or error code.
+- */
+-extern int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf,
+-			 uint nbytes);
+-
+-/* Issue an abort to the specified function */
+-extern int bcmsdh_abort(void *sdh, uint fn);
+-
+-/* Start SDIO Host Controller communication */
+-extern int bcmsdh_start(void *sdh, int stage);
+-
+-/* Stop SDIO Host Controller communication */
+-extern int bcmsdh_stop(void *sdh);
+-
+-/* Returns the "Device ID" of target device on the SDIO bus. */
+-extern int bcmsdh_query_device(void *sdh);
+-
+-/* Returns the number of IO functions reported by the device */
+-extern uint bcmsdh_query_iofnum(void *sdh);
+-
+-/* Miscellaneous knob tweaker. */
+-extern int bcmsdh_iovar_op(void *sdh, const char *name,
+-			   void *params, int plen, void *arg, int len,
+-			   bool set);
+-
+-/* Reset and reinitialize the device */
+-extern int bcmsdh_reset(bcmsdh_info_t *sdh);
+-
+-/* helper functions */
+-
+-extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+-
+-/* callback functions */
+-typedef struct {
+-	/* attach to device */
+-	void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot,
+-			 u16 func, uint bustype, void *regsva, void *param);
+-	/* detach from device */
+-	void (*detach) (void *ch);
+-} bcmsdh_driver_t;
+-
+-/* platform specific/high level functions */
+-extern int bcmsdh_register(bcmsdh_driver_t *driver);
+-extern void bcmsdh_unregister(void);
+-extern bool bcmsdh_chipmatch(u16 vendor, u16 device);
+-extern void bcmsdh_device_remove(void *sdh);
+-
+-/* Function to pass device-status bits to DHD. */
+-extern u32 bcmsdh_get_dstatus(void *sdh);
+-
+-/* Function to return current window addr */
+-extern u32 bcmsdh_cur_sbwad(void *sdh);
+-
+-/* Function to pass chipid and rev to lower layers for controlling pr's */
+-extern void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev);
+-
+-#endif				/* _bcmsdh_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsdpcm.h b/drivers/staging/brcm80211/include/bcmsdpcm.h
+deleted file mode 100644
+index 5175e67..0000000
+--- a/drivers/staging/brcm80211/include/bcmsdpcm.h
++++ /dev/null
+@@ -1,208 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsdpcm_h_
+-#define	_bcmsdpcm_h_
+-
+-/*
+- * Software allocation of To SB Mailbox resources
+- */
+-
+-/* intstatus bits */
+-#define I_SMB_NAK	I_SMB_SW0	/* To SB Mailbox Frame NAK */
+-#define I_SMB_INT_ACK	I_SMB_SW1	/* To SB Mailbox Host Interrupt ACK */
+-#define I_SMB_USE_OOB	I_SMB_SW2	/* To SB Mailbox Use OOB Wakeup */
+-#define I_SMB_DEV_INT	I_SMB_SW3	/* To SB Mailbox Miscellaneous Interrupt */
+-
+-#define I_TOSBMAIL      (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT)
+-
+-/* tosbmailbox bits corresponding to intstatus bits */
+-#define SMB_NAK		(1 << 0)	/* To SB Mailbox Frame NAK */
+-#define SMB_INT_ACK	(1 << 1)	/* To SB Mailbox Host Interrupt ACK */
+-#define SMB_USE_OOB	(1 << 2)	/* To SB Mailbox Use OOB Wakeup */
+-#define SMB_DEV_INT	(1 << 3)	/* To SB Mailbox Miscellaneous Interrupt */
+-#define SMB_MASK	0x0000000f	/* To SB Mailbox Mask */
+-
+-/* tosbmailboxdata */
+-#define SMB_DATA_VERSION_MASK	0x00ff0000	/* host protocol version (sent with F2 enable) */
+-#define SMB_DATA_VERSION_SHIFT	16	/* host protocol version (sent with F2 enable) */
+-
+-/*
+- * Software allocation of To Host Mailbox resources
+- */
+-
+-/* intstatus bits */
+-#define I_HMB_FC_STATE	I_HMB_SW0	/* To Host Mailbox Flow Control State */
+-#define I_HMB_FC_CHANGE	I_HMB_SW1	/* To Host Mailbox Flow Control State Changed */
+-#define I_HMB_FRAME_IND	I_HMB_SW2	/* To Host Mailbox Frame Indication */
+-#define I_HMB_HOST_INT	I_HMB_SW3	/* To Host Mailbox Miscellaneous Interrupt */
+-
+-#define I_TOHOSTMAIL    (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT)
+-
+-/* tohostmailbox bits corresponding to intstatus bits */
+-#define HMB_FC_ON	(1 << 0)	/* To Host Mailbox Flow Control State */
+-#define HMB_FC_CHANGE	(1 << 1)	/* To Host Mailbox Flow Control State Changed */
+-#define HMB_FRAME_IND	(1 << 2)	/* To Host Mailbox Frame Indication */
+-#define HMB_HOST_INT	(1 << 3)	/* To Host Mailbox Miscellaneous Interrupt */
+-#define HMB_MASK	0x0000000f	/* To Host Mailbox Mask */
+-
+-/* tohostmailboxdata */
+-#define HMB_DATA_NAKHANDLED	1	/* we're ready to retransmit NAK'd frame to host */
+-#define HMB_DATA_DEVREADY	2	/* we're ready to to talk to host after enable */
+-#define HMB_DATA_FC		4	/* per prio flowcontrol update flag to host */
+-#define HMB_DATA_FWREADY	8	/* firmware is ready for protocol activity */
+-
+-#define HMB_DATA_FCDATA_MASK	0xff000000	/* per prio flowcontrol data */
+-#define HMB_DATA_FCDATA_SHIFT	24	/* per prio flowcontrol data */
+-
+-#define HMB_DATA_VERSION_MASK	0x00ff0000	/* device protocol version (with devready) */
+-#define HMB_DATA_VERSION_SHIFT	16	/* device protocol version (with devready) */
+-
+-/*
+- * Software-defined protocol header
+- */
+-
+-/* Current protocol version */
+-#define SDPCM_PROT_VERSION	4
+-
+-/* SW frame header */
+-#define SDPCM_SEQUENCE_MASK		0x000000ff	/* Sequence Number Mask */
+-#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)	/* p starts w/SW Header */
+-
+-#define SDPCM_CHANNEL_MASK		0x00000f00	/* Channel Number Mask */
+-#define SDPCM_CHANNEL_SHIFT		8	/* Channel Number Shift */
+-#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)	/* p starts w/SW Header */
+-
+-#define SDPCM_FLAGS_MASK		0x0000f000	/* Mask of flag bits */
+-#define SDPCM_FLAGS_SHIFT		12	/* Flag bits shift */
+-#define SDPCM_PACKET_FLAGS(p) ((((u8 *)p)[1] & 0xf0) >> 4)	/* p starts w/SW Header */
+-
+-/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */
+-#define SDPCM_NEXTLEN_MASK		0x00ff0000	/* Next Read Len Mask */
+-#define SDPCM_NEXTLEN_SHIFT		16	/* Next Read Len Shift */
+-#define SDPCM_NEXTLEN_VALUE(p) ((((u8 *)p)[2] & 0xff) << 4)	/* p starts w/SW Header */
+-#define SDPCM_NEXTLEN_OFFSET		2
+-
+-/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
+-#define SDPCM_DOFFSET_OFFSET		3	/* Data Offset */
+-#define SDPCM_DOFFSET_VALUE(p) 		(((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
+-#define SDPCM_DOFFSET_MASK		0xff000000
+-#define SDPCM_DOFFSET_SHIFT		24
+-
+-#define SDPCM_FCMASK_OFFSET		4	/* Flow control */
+-#define SDPCM_FCMASK_VALUE(p)		(((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
+-#define SDPCM_WINDOW_OFFSET		5	/* Credit based fc */
+-#define SDPCM_WINDOW_VALUE(p)		(((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
+-#define SDPCM_VERSION_OFFSET		6	/* Version # */
+-#define SDPCM_VERSION_VALUE(p)		(((u8 *)p)[SDPCM_VERSION_OFFSET] & 0xff)
+-#define SDPCM_UNUSED_OFFSET		7	/* Spare */
+-#define SDPCM_UNUSED_VALUE(p)		(((u8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff)
+-
+-#define SDPCM_SWHEADER_LEN	8	/* SW header is 64 bits */
+-
+-/* logical channel numbers */
+-#define SDPCM_CONTROL_CHANNEL	0	/* Control Request/Response Channel Id */
+-#define SDPCM_EVENT_CHANNEL	1	/* Asyc Event Indication Channel Id */
+-#define SDPCM_DATA_CHANNEL	2	/* Data Xmit/Recv Channel Id */
+-#define SDPCM_GLOM_CHANNEL	3	/* For coalesced packets (superframes) */
+-#define SDPCM_TEST_CHANNEL	15	/* Reserved for test/debug packets */
+-#define SDPCM_MAX_CHANNEL	15
+-
+-#define SDPCM_SEQUENCE_WRAP	256	/* wrap-around val for eight-bit frame seq number */
+-
+-#define SDPCM_FLAG_RESVD0	0x01
+-#define SDPCM_FLAG_RESVD1	0x02
+-#define SDPCM_FLAG_GSPI_TXENAB	0x04
+-#define SDPCM_FLAG_GLOMDESC	0x08	/* Superframe descriptor mask */
+-
+-/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */
+-#define SDPCM_GLOMDESC_FLAG	(SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT)
+-
+-#define SDPCM_GLOMDESC(p)	(((u8 *)p)[1] & 0x80)
+-
+-/* For TEST_CHANNEL packets, define another 4-byte header */
+-#define SDPCM_TEST_HDRLEN	4	/* Generally: Cmd(1), Ext(1), Len(2);
+-					 * Semantics of Ext byte depend on command.
+-					 * Len is current or requested frame length, not
+-					 * including test header; sent little-endian.
+-					 */
+-#define SDPCM_TEST_DISCARD	0x01	/* Receiver discards. Ext is a pattern id. */
+-#define SDPCM_TEST_ECHOREQ	0x02	/* Echo request. Ext is a pattern id. */
+-#define SDPCM_TEST_ECHORSP	0x03	/* Echo response. Ext is a pattern id. */
+-#define SDPCM_TEST_BURST	0x04	/* Receiver to send a burst. Ext is a frame count */
+-#define SDPCM_TEST_SEND		0x05	/* Receiver sets send mode. Ext is boolean on/off */
+-
+-/* Handy macro for filling in datagen packets with a pattern */
+-#define SDPCM_TEST_FILL(byteno, id)	((u8)(id + byteno))
+-
+-/*
+- * Software counters (first part matches hardware counters)
+- */
+-
+-typedef volatile struct {
+-	u32 cmd52rd;		/* Cmd52RdCount, SDIO: cmd52 reads */
+-	u32 cmd52wr;		/* Cmd52WrCount, SDIO: cmd52 writes */
+-	u32 cmd53rd;		/* Cmd53RdCount, SDIO: cmd53 reads */
+-	u32 cmd53wr;		/* Cmd53WrCount, SDIO: cmd53 writes */
+-	u32 abort;		/* AbortCount, SDIO: aborts */
+-	u32 datacrcerror;	/* DataCrcErrorCount, SDIO: frames w/CRC error */
+-	u32 rdoutofsync;	/* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */
+-	u32 wroutofsync;	/* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */
+-	u32 writebusy;	/* WriteBusyCount, SDIO: device asserted "busy" */
+-	u32 readwait;	/* ReadWaitCount, SDIO: no data ready for a read cmd */
+-	u32 readterm;	/* ReadTermCount, SDIO: read frame termination cmds */
+-	u32 writeterm;	/* WriteTermCount, SDIO: write frames termination cmds */
+-	u32 rxdescuflo;	/* receive descriptor underflows */
+-	u32 rxfifooflo;	/* receive fifo overflows */
+-	u32 txfifouflo;	/* transmit fifo underflows */
+-	u32 runt;		/* runt (too short) frames recv'd from bus */
+-	u32 badlen;		/* frame's rxh len does not match its hw tag len */
+-	u32 badcksum;	/* frame's hw tag chksum doesn't agree with len value */
+-	u32 seqbreak;	/* break in sequence # space from one rx frame to the next */
+-	u32 rxfcrc;		/* frame rx header indicates crc error */
+-	u32 rxfwoos;		/* frame rx header indicates write out of sync */
+-	u32 rxfwft;		/* frame rx header indicates write frame termination */
+-	u32 rxfabort;	/* frame rx header indicates frame aborted */
+-	u32 woosint;		/* write out of sync interrupt */
+-	u32 roosint;		/* read out of sync interrupt */
+-	u32 rftermint;	/* read frame terminate interrupt */
+-	u32 wftermint;	/* write frame terminate interrupt */
+-} sdpcmd_cnt_t;
+-
+-/*
+- * Shared structure between dongle and the host.
+- * The structure contains pointers to trap or assert information.
+- */
+-#define SDPCM_SHARED_VERSION       0x0002
+-#define SDPCM_SHARED_VERSION_MASK  0x00FF
+-#define SDPCM_SHARED_ASSERT_BUILT  0x0100
+-#define SDPCM_SHARED_ASSERT        0x0200
+-#define SDPCM_SHARED_TRAP          0x0400
+-
+-typedef struct {
+-	u32 flags;
+-	u32 trap_addr;
+-	u32 assert_exp_addr;
+-	u32 assert_file_addr;
+-	u32 assert_line;
+-	u32 console_addr;	/* Address of hndrte_cons_t */
+-	u32 msgtrace_addr;
+-	u8 tag[32];
+-} sdpcm_shared_t;
+-
+-extern sdpcm_shared_t sdpcm_shared;
+-
+-#endif				/* _bcmsdpcm_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/include/bcmsrom.h
+deleted file mode 100644
+index b2dc895..0000000
+--- a/drivers/staging/brcm80211/include/bcmsrom.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_h_
+-#define	_bcmsrom_h_
+-
+-#include <bcmsrom_fmt.h>
+-
+-/* Prototypes */
+-extern int srom_var_init(si_t *sih, uint bus, void *curmap,
+-			 char **vars, uint *count);
+-
+-extern int srom_read(si_t *sih, uint bus, void *curmap,
+-		     uint byteoff, uint nbytes, u16 *buf, bool check_crc);
+-
+-/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
+- *   and extract from it into name=value pairs
+- */
+-extern int srom_parsecis(u8 **pcis, uint ciscnt,
+-			 char **vars, uint *count);
+-#endif				/* _bcmsrom_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h
+deleted file mode 100644
+index 4666afd..0000000
+--- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h
++++ /dev/null
+@@ -1,367 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_fmt_h_
+-#define	_bcmsrom_fmt_h_
+-
+-/* Maximum srom: 6 Kilobits == 768 bytes */
+-#define	SROM_MAX		768
+-#define SROM_MAXW		384
+-#define VARS_MAX		4096
+-
+-/* PCI fields */
+-#define PCI_F0DEVID		48
+-
+-#define	SROM_WORDS		64
+-
+-#define SROM3_SWRGN_OFF		28	/* s/w region offset in words */
+-
+-#define	SROM_SSID		2
+-
+-#define	SROM_WL1LHMAXP		29
+-
+-#define	SROM_WL1LPAB0		30
+-#define	SROM_WL1LPAB1		31
+-#define	SROM_WL1LPAB2		32
+-
+-#define	SROM_WL1HPAB0		33
+-#define	SROM_WL1HPAB1		34
+-#define	SROM_WL1HPAB2		35
+-
+-#define	SROM_MACHI_IL0		36
+-#define	SROM_MACMID_IL0		37
+-#define	SROM_MACLO_IL0		38
+-#define	SROM_MACHI_ET0		39
+-#define	SROM_MACMID_ET0		40
+-#define	SROM_MACLO_ET0		41
+-#define	SROM_MACHI_ET1		42
+-#define	SROM_MACMID_ET1		43
+-#define	SROM_MACLO_ET1		44
+-#define	SROM3_MACHI		37
+-#define	SROM3_MACMID		38
+-#define	SROM3_MACLO		39
+-
+-#define	SROM_BXARSSI2G		40
+-#define	SROM_BXARSSI5G		41
+-
+-#define	SROM_TRI52G		42
+-#define	SROM_TRI5GHL		43
+-
+-#define	SROM_RXPO52G		45
+-
+-#define	SROM2_ENETPHY		45
+-
+-#define	SROM_AABREV		46
+-/* Fields in AABREV */
+-#define	SROM_BR_MASK		0x00ff
+-#define	SROM_CC_MASK		0x0f00
+-#define	SROM_CC_SHIFT		8
+-#define	SROM_AA0_MASK		0x3000
+-#define	SROM_AA0_SHIFT		12
+-#define	SROM_AA1_MASK		0xc000
+-#define	SROM_AA1_SHIFT		14
+-
+-#define	SROM_WL0PAB0		47
+-#define	SROM_WL0PAB1		48
+-#define	SROM_WL0PAB2		49
+-
+-#define	SROM_LEDBH10		50
+-#define	SROM_LEDBH32		51
+-
+-#define	SROM_WL10MAXP		52
+-
+-#define	SROM_WL1PAB0		53
+-#define	SROM_WL1PAB1		54
+-#define	SROM_WL1PAB2		55
+-
+-#define	SROM_ITT		56
+-
+-#define	SROM_BFL		57
+-#define	SROM_BFL2		28
+-#define	SROM3_BFL2		61
+-
+-#define	SROM_AG10		58
+-
+-#define	SROM_CCODE		59
+-
+-#define	SROM_OPO		60
+-
+-#define	SROM3_LEDDC		62
+-
+-#define	SROM_CRCREV		63
+-
+-/* SROM Rev 4: Reallocate the software part of the srom to accommodate
+- * MIMO features. It assumes up to two PCIE functions and 440 bytes
+- * of usable srom i.e. the usable storage in chips with OTP that
+- * implements hardware redundancy.
+- */
+-
+-#define	SROM4_WORDS		220
+-
+-#define	SROM4_SIGN		32
+-#define	SROM4_SIGNATURE		0x5372
+-
+-#define	SROM4_BREV		33
+-
+-#define	SROM4_BFL0		34
+-#define	SROM4_BFL1		35
+-#define	SROM4_BFL2		36
+-#define	SROM4_BFL3		37
+-#define	SROM5_BFL0		37
+-#define	SROM5_BFL1		38
+-#define	SROM5_BFL2		39
+-#define	SROM5_BFL3		40
+-
+-#define	SROM4_MACHI		38
+-#define	SROM4_MACMID		39
+-#define	SROM4_MACLO		40
+-#define	SROM5_MACHI		41
+-#define	SROM5_MACMID		42
+-#define	SROM5_MACLO		43
+-
+-#define	SROM4_CCODE		41
+-#define	SROM4_REGREV		42
+-#define	SROM5_CCODE		34
+-#define	SROM5_REGREV		35
+-
+-#define	SROM4_LEDBH10		43
+-#define	SROM4_LEDBH32		44
+-#define	SROM5_LEDBH10		59
+-#define	SROM5_LEDBH32		60
+-
+-#define	SROM4_LEDDC		45
+-#define	SROM5_LEDDC		45
+-
+-#define	SROM4_AA		46
+-#define	SROM4_AA2G_MASK		0x00ff
+-#define	SROM4_AA2G_SHIFT	0
+-#define	SROM4_AA5G_MASK		0xff00
+-#define	SROM4_AA5G_SHIFT	8
+-
+-#define	SROM4_AG10		47
+-#define	SROM4_AG32		48
+-
+-#define	SROM4_TXPID2G		49
+-#define	SROM4_TXPID5G		51
+-#define	SROM4_TXPID5GL		53
+-#define	SROM4_TXPID5GH		55
+-
+-#define SROM4_TXRXC		61
+-#define SROM4_TXCHAIN_MASK	0x000f
+-#define SROM4_TXCHAIN_SHIFT	0
+-#define SROM4_RXCHAIN_MASK	0x00f0
+-#define SROM4_RXCHAIN_SHIFT	4
+-#define SROM4_SWITCH_MASK	0xff00
+-#define SROM4_SWITCH_SHIFT	8
+-
+-/* Per-path fields */
+-#define	MAX_PATH_SROM		4
+-#define	SROM4_PATH0		64
+-#define	SROM4_PATH1		87
+-#define	SROM4_PATH2		110
+-#define	SROM4_PATH3		133
+-
+-#define	SROM4_2G_ITT_MAXP	0
+-#define	SROM4_2G_PA		1
+-#define	SROM4_5G_ITT_MAXP	5
+-#define	SROM4_5GLH_MAXP		6
+-#define	SROM4_5G_PA		7
+-#define	SROM4_5GL_PA		11
+-#define	SROM4_5GH_PA		15
+-
+-/* Fields in the ITT_MAXP and 5GLH_MAXP words */
+-#define	B2G_MAXP_MASK		0xff
+-#define	B2G_ITT_SHIFT		8
+-#define	B5G_MAXP_MASK		0xff
+-#define	B5G_ITT_SHIFT		8
+-#define	B5GH_MAXP_MASK		0xff
+-#define	B5GL_MAXP_SHIFT		8
+-
+-/* All the miriad power offsets */
+-#define	SROM4_2G_CCKPO		156
+-#define	SROM4_2G_OFDMPO		157
+-#define	SROM4_5G_OFDMPO		159
+-#define	SROM4_5GL_OFDMPO	161
+-#define	SROM4_5GH_OFDMPO	163
+-#define	SROM4_2G_MCSPO		165
+-#define	SROM4_5G_MCSPO		173
+-#define	SROM4_5GL_MCSPO		181
+-#define	SROM4_5GH_MCSPO		189
+-#define	SROM4_CDDPO		197
+-#define	SROM4_STBCPO		198
+-#define	SROM4_BW40PO		199
+-#define	SROM4_BWDUPPO		200
+-
+-#define	SROM4_CRCREV		219
+-
+-/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
+- * This is acombined srom for both MIMO and SISO boards, usable in
+- * the .130 4Kilobit OTP with hardware redundancy.
+- */
+-
+-#define	SROM8_SIGN		64
+-
+-#define	SROM8_BREV		65
+-
+-#define	SROM8_BFL0		66
+-#define	SROM8_BFL1		67
+-#define	SROM8_BFL2		68
+-#define	SROM8_BFL3		69
+-
+-#define	SROM8_MACHI		70
+-#define	SROM8_MACMID		71
+-#define	SROM8_MACLO		72
+-
+-#define	SROM8_CCODE		73
+-#define	SROM8_REGREV		74
+-
+-#define	SROM8_LEDBH10		75
+-#define	SROM8_LEDBH32		76
+-
+-#define	SROM8_LEDDC		77
+-
+-#define	SROM8_AA		78
+-
+-#define	SROM8_AG10		79
+-#define	SROM8_AG32		80
+-
+-#define	SROM8_TXRXC		81
+-
+-#define	SROM8_BXARSSI2G		82
+-#define	SROM8_BXARSSI5G		83
+-#define	SROM8_TRI52G		84
+-#define	SROM8_TRI5GHL		85
+-#define	SROM8_RXPO52G		86
+-
+-#define SROM8_FEM2G		87
+-#define SROM8_FEM5G		88
+-#define SROM8_FEM_ANTSWLUT_MASK		0xf800
+-#define SROM8_FEM_ANTSWLUT_SHIFT	11
+-#define SROM8_FEM_TR_ISO_MASK		0x0700
+-#define SROM8_FEM_TR_ISO_SHIFT		8
+-#define SROM8_FEM_PDET_RANGE_MASK	0x00f8
+-#define SROM8_FEM_PDET_RANGE_SHIFT	3
+-#define SROM8_FEM_EXTPA_GAIN_MASK	0x0006
+-#define SROM8_FEM_EXTPA_GAIN_SHIFT	1
+-#define SROM8_FEM_TSSIPOS_MASK		0x0001
+-#define SROM8_FEM_TSSIPOS_SHIFT		0
+-
+-#define SROM8_THERMAL		89
+-
+-/* Temp sense related entries */
+-#define SROM8_MPWR_RAWTS		90
+-#define SROM8_TS_SLP_OPT_CORRX	91
+-/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
+-#define SROM8_FOC_HWIQ_IQSWP	92
+-
+-/* Temperature delta for PHY calibration */
+-#define SROM8_PHYCAL_TEMPDELTA	93
+-
+-/* Per-path offsets & fields */
+-#define	SROM8_PATH0		96
+-#define	SROM8_PATH1		112
+-#define	SROM8_PATH2		128
+-#define	SROM8_PATH3		144
+-
+-#define	SROM8_2G_ITT_MAXP	0
+-#define	SROM8_2G_PA		1
+-#define	SROM8_5G_ITT_MAXP	4
+-#define	SROM8_5GLH_MAXP		5
+-#define	SROM8_5G_PA		6
+-#define	SROM8_5GL_PA		9
+-#define	SROM8_5GH_PA		12
+-
+-/* All the miriad power offsets */
+-#define	SROM8_2G_CCKPO		160
+-
+-#define	SROM8_2G_OFDMPO		161
+-#define	SROM8_5G_OFDMPO		163
+-#define	SROM8_5GL_OFDMPO	165
+-#define	SROM8_5GH_OFDMPO	167
+-
+-#define	SROM8_2G_MCSPO		169
+-#define	SROM8_5G_MCSPO		177
+-#define	SROM8_5GL_MCSPO		185
+-#define	SROM8_5GH_MCSPO		193
+-
+-#define	SROM8_CDDPO		201
+-#define	SROM8_STBCPO		202
+-#define	SROM8_BW40PO		203
+-#define	SROM8_BWDUPPO		204
+-
+-/* SISO PA parameters are in the path0 spaces */
+-#define	SROM8_SISO		96
+-
+-/* Legacy names for SISO PA paramters */
+-#define	SROM8_W0_ITTMAXP	(SROM8_SISO + SROM8_2G_ITT_MAXP)
+-#define	SROM8_W0_PAB0		(SROM8_SISO + SROM8_2G_PA)
+-#define	SROM8_W0_PAB1		(SROM8_SISO + SROM8_2G_PA + 1)
+-#define	SROM8_W0_PAB2		(SROM8_SISO + SROM8_2G_PA + 2)
+-#define	SROM8_W1_ITTMAXP	(SROM8_SISO + SROM8_5G_ITT_MAXP)
+-#define	SROM8_W1_MAXP_LCHC	(SROM8_SISO + SROM8_5GLH_MAXP)
+-#define	SROM8_W1_PAB0		(SROM8_SISO + SROM8_5G_PA)
+-#define	SROM8_W1_PAB1		(SROM8_SISO + SROM8_5G_PA + 1)
+-#define	SROM8_W1_PAB2		(SROM8_SISO + SROM8_5G_PA + 2)
+-#define	SROM8_W1_PAB0_LC	(SROM8_SISO + SROM8_5GL_PA)
+-#define	SROM8_W1_PAB1_LC	(SROM8_SISO + SROM8_5GL_PA + 1)
+-#define	SROM8_W1_PAB2_LC	(SROM8_SISO + SROM8_5GL_PA + 2)
+-#define	SROM8_W1_PAB0_HC	(SROM8_SISO + SROM8_5GH_PA)
+-#define	SROM8_W1_PAB1_HC	(SROM8_SISO + SROM8_5GH_PA + 1)
+-#define	SROM8_W1_PAB2_HC	(SROM8_SISO + SROM8_5GH_PA + 2)
+-
+-#define	SROM8_CRCREV		219
+-
+-/* SROM REV 9 */
+-#define SROM9_2GPO_CCKBW20	160
+-#define SROM9_2GPO_CCKBW20UL	161
+-#define SROM9_2GPO_LOFDMBW20	162
+-#define SROM9_2GPO_LOFDMBW20UL	164
+-
+-#define SROM9_5GLPO_LOFDMBW20	166
+-#define SROM9_5GLPO_LOFDMBW20UL	168
+-#define SROM9_5GMPO_LOFDMBW20	170
+-#define SROM9_5GMPO_LOFDMBW20UL	172
+-#define SROM9_5GHPO_LOFDMBW20	174
+-#define SROM9_5GHPO_LOFDMBW20UL	176
+-
+-#define SROM9_2GPO_MCSBW20	178
+-#define SROM9_2GPO_MCSBW20UL	180
+-#define SROM9_2GPO_MCSBW40	182
+-
+-#define SROM9_5GLPO_MCSBW20	184
+-#define SROM9_5GLPO_MCSBW20UL	186
+-#define SROM9_5GLPO_MCSBW40	188
+-#define SROM9_5GMPO_MCSBW20	190
+-#define SROM9_5GMPO_MCSBW20UL	192
+-#define SROM9_5GMPO_MCSBW40	194
+-#define SROM9_5GHPO_MCSBW20	196
+-#define SROM9_5GHPO_MCSBW20UL	198
+-#define SROM9_5GHPO_MCSBW40	200
+-
+-#define SROM9_PO_MCS32		202
+-#define SROM9_PO_LOFDM40DUP	203
+-
+-#define SROM9_REV_CRC		219
+-
+-typedef struct {
+-	u8 tssipos;		/* TSSI positive slope, 1: positive, 0: negative */
+-	u8 extpagain;	/* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
+-	u8 pdetrange;	/* support 32 combinations of different Pdet dynamic ranges */
+-	u8 triso;		/* TR switch isolation */
+-	u8 antswctrllut;	/* antswctrl lookup table configuration: 32 possible choices */
+-} srom_fem_t;
+-
+-#endif				/* _bcmsrom_fmt_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h
+deleted file mode 100644
+index 17683f2..0000000
+--- a/drivers/staging/brcm80211/include/bcmutils.h
++++ /dev/null
+@@ -1,500 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmutils_h_
+-#define	_bcmutils_h_
+-
+-/* Buffer structure for collecting string-formatted data
+-* using bcm_bprintf() API.
+-* Use bcm_binit() to initialize before use
+-*/
+-
+-	struct bcmstrbuf {
+-		char *buf;	/* pointer to current position in origbuf */
+-		unsigned int size;	/* current (residual) size in bytes */
+-		char *origbuf;	/* unmodified pointer to orignal buffer */
+-		unsigned int origsize;	/* unmodified orignal buffer size in bytes */
+-	};
+-
+-/* ** driver-only section ** */
+-
+-#define GPIO_PIN_NOTDEFINED 	0x20	/* Pin not defined */
+-
+-/*
+- * Spin at most 'us' microseconds while 'exp' is true.
+- * Caller should explicitly test 'exp' when this completes
+- * and take appropriate error action if 'exp' is still true.
+- */
+-#define SPINWAIT(exp, us) { \
+-	uint countdown = (us) + 9; \
+-	while ((exp) && (countdown >= 10)) {\
+-		udelay(10); \
+-		countdown -= 10; \
+-	} \
+-}
+-
+-/* osl multi-precedence packet queue */
+-#ifndef PKTQ_LEN_DEFAULT
+-#define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
+-#endif
+-#ifndef PKTQ_MAX_PREC
+-#define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
+-#endif
+-
+-	struct pktq_prec {
+-		struct sk_buff *head;	/* first packet to dequeue */
+-		struct sk_buff *tail;	/* last packet to dequeue */
+-		u16 len;		/* number of queued packets */
+-		u16 max;		/* maximum number of queued packets */
+-	};
+-
+-/* multi-priority pkt queue */
+-	struct pktq {
+-		u16 num_prec;	/* number of precedences in use */
+-		u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
+-		u16 max;	/* total max packets */
+-		u16 len;	/* total number of packets */
+-		/* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+-		struct pktq_prec q[PKTQ_MAX_PREC];
+-	};
+-
+-#define PKTQ_PREC_ITER(pq, prec)        for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
+-
+-/* fn(pkt, arg).  return true if pkt belongs to if */
+-typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *);
+-
+-/* operations on a specific precedence in packet queue */
+-
+-#define pktq_psetmax(pq, prec, _max)    ((pq)->q[prec].max = (_max))
+-#define pktq_plen(pq, prec)             ((pq)->q[prec].len)
+-#define pktq_pavail(pq, prec)           ((pq)->q[prec].max - (pq)->q[prec].len)
+-#define pktq_pfull(pq, prec)            ((pq)->q[prec].len >= (pq)->q[prec].max)
+-#define pktq_pempty(pq, prec)           ((pq)->q[prec].len == 0)
+-
+-#define pktq_ppeek(pq, prec)            ((pq)->q[prec].head)
+-#define pktq_ppeek_tail(pq, prec)       ((pq)->q[prec].tail)
+-
+-extern struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
+-				 struct sk_buff *p);
+-extern struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
+-				      struct sk_buff *p);
+-extern struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec);
+-extern struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec);
+-
+-/* packet primitives */
+-extern struct sk_buff *bcm_pkt_buf_get_skb(uint len);
+-extern void bcm_pkt_buf_free_skb(struct sk_buff *skb);
+-
+-/* Empty the queue at particular precedence level */
+-extern void bcm_pktq_pflush(struct pktq *pq, int prec,
+-	bool dir, ifpkt_cb_t fn, void *arg);
+-
+-/* operations on a set of precedences in packet queue */
+-
+-extern int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp);
+-extern struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
+-	int *prec_out);
+-
+-/* operations on packet queue as a whole */
+-
+-#define pktq_len(pq)                    ((int)(pq)->len)
+-#define pktq_max(pq)                    ((int)(pq)->max)
+-#define pktq_avail(pq)                  ((int)((pq)->max - (pq)->len))
+-#define pktq_full(pq)                   ((pq)->len >= (pq)->max)
+-#define pktq_empty(pq)                  ((pq)->len == 0)
+-
+-/* operations for single precedence queues */
+-#define pktenq(pq, p)		bcm_pktq_penq(((struct pktq *)pq), 0, (p))
+-#define pktenq_head(pq, p)	bcm_pktq_penq_head(((struct pktq *)pq), 0, (p))
+-#define pktdeq(pq)		bcm_pktq_pdeq(((struct pktq *)pq), 0)
+-#define pktdeq_tail(pq)		bcm_pktq_pdeq_tail(((struct pktq *)pq), 0)
+-#define pktqinit(pq, len)	bcm_pktq_init(((struct pktq *)pq), 1, len)
+-
+-extern void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len);
+-/* prec_out may be NULL if caller is not interested in return value */
+-extern struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out);
+-extern void bcm_pktq_flush(struct pktq *pq, bool dir,
+-	ifpkt_cb_t fn, void *arg);
+-
+-/* externs */
+-/* packet */
+-extern uint bcm_pktfrombuf(struct sk_buff *p,
+-	uint offset, int len, unsigned char *buf);
+-extern uint bcm_pkttotlen(struct sk_buff *p);
+-
+-/* ethernet address */
+-extern int bcm_ether_atoe(char *p, u8 *ea);
+-
+-/* ip address */
+-	struct ipv4_addr;
+-	extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
+-
+-#ifdef BCMDBG
+-extern void bcm_prpkt(const char *msg, struct sk_buff *p0);
+-#else
+-#define bcm_prpkt(a, b)
+-#endif				/* BCMDBG */
+-
+-#define bcm_perf_enable()
+-#define	bcmlog(fmt, a1, a2)
+-#define	bcmdumplog(buf, size)	(*buf = '\0')
+-#define	bcmdumplogent(buf, idx)	-1
+-
+-#define bcmtslog(tstamp, fmt, a1, a2)
+-#define bcmprinttslogs()
+-#define bcmprinttstamp(us)
+-
+-/* Support for sharing code across in-driver iovar implementations.
+- * The intent is that a driver use this structure to map iovar names
+- * to its (private) iovar identifiers, and the lookup function to
+- * find the entry.  Macros are provided to map ids and get/set actions
+- * into a single number space for a switch statement.
+- */
+-
+-/* iovar structure */
+-	typedef struct bcm_iovar {
+-		const char *name;	/* name for lookup and display */
+-		u16 varid;	/* id for switch */
+-		u16 flags;	/* driver-specific flag bits */
+-		u16 type;	/* base type of argument */
+-		u16 minlen;	/* min length for buffer vars */
+-	} bcm_iovar_t;
+-
+-/* varid definitions are per-driver, may use these get/set bits */
+-
+-/* IOVar action bits for id mapping */
+-#define IOV_GET 0		/* Get an iovar */
+-#define IOV_SET 1		/* Set an iovar */
+-
+-/* Varid to actionid mapping */
+-#define IOV_GVAL(id)		((id)*2)
+-#define IOV_SVAL(id)		(((id)*2)+IOV_SET)
+-#define IOV_ISSET(actionid)	((actionid & IOV_SET) == IOV_SET)
+-#define IOV_ID(actionid)	(actionid >> 1)
+-
+-/* flags are per-driver based on driver attributes */
+-
+-	extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table,
+-						   const char *name);
+-	extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg,
+-				      int len, bool set);
+-
+-/* Base type definitions */
+-#define IOVT_VOID	0	/* no value (implictly set only) */
+-#define IOVT_BOOL	1	/* any value ok (zero/nonzero) */
+-#define IOVT_INT8	2	/* integer values are range-checked */
+-#define IOVT_UINT8	3	/* unsigned int 8 bits */
+-#define IOVT_INT16	4	/* int 16 bits */
+-#define IOVT_UINT16	5	/* unsigned int 16 bits */
+-#define IOVT_INT32	6	/* int 32 bits */
+-#define IOVT_UINT32	7	/* unsigned int 32 bits */
+-#define IOVT_BUFFER	8	/* buffer is size-checked as per minlen */
+-#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
+-
+-/* Initializer for IOV type strings */
+-#define BCM_IOV_TYPE_INIT { \
+-	"void", \
+-	"bool", \
+-	"s8", \
+-	"u8", \
+-	"s16", \
+-	"u16", \
+-	"s32", \
+-	"u32", \
+-	"buffer", \
+-	"" }
+-
+-#define BCM_IOVT_IS_INT(type) (\
+-	(type == IOVT_BOOL) || \
+-	(type == IOVT_INT8) || \
+-	(type == IOVT_UINT8) || \
+-	(type == IOVT_INT16) || \
+-	(type == IOVT_UINT16) || \
+-	(type == IOVT_INT32) || \
+-	(type == IOVT_UINT32))
+-
+-/* ** driver/apps-shared section ** */
+-
+-#define BCME_STRLEN 		64	/* Max string length for BCM errors */
+-
+-#ifndef ABS
+-#define	ABS(a)			(((a) < 0) ? -(a) : (a))
+-#endif				/* ABS */
+-
+-#define CEIL(x, y)		(((x) + ((y)-1)) / (y))
+-#define	ISPOWEROF2(x)		((((x)-1)&(x)) == 0)
+-
+-/* map physical to virtual I/O */
+-#if !defined(CONFIG_MMC_MSM7X00A)
+-#define REG_MAP(pa, size)       ioremap_nocache((unsigned long)(pa), \
+-					(unsigned long)(size))
+-#else
+-#define REG_MAP(pa, size)       (void *)(0)
+-#endif
+-
+-/* register access macros */
+-#if defined(BCMSDIO)
+-#ifdef BRCM_FULLMAC
+-#include <bcmsdh.h>
+-#endif
+-#define OSL_WRITE_REG(r, v) \
+-		(bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v)))
+-#define OSL_READ_REG(r) \
+-		(bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r))))
+-#endif
+-
+-#if defined(BCMSDIO)
+-#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op
+-#define SELECT_BUS_READ(mmap_op, bus_op) bus_op
+-#else
+-#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op
+-#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op
+-#endif
+-
+-/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
+-#define	PKTBUFSZ	2048
+-
+-#define OSL_SYSUPTIME()		((u32)jiffies * (1000 / HZ))
+-#ifdef BRCM_FULLMAC
+-#include <linux/kernel.h>	/* for vsn/printf's */
+-#include <linux/string.h>	/* for mem*, str* */
+-#endif
+-/* bcopy's: Linux kernel doesn't provide these (anymore) */
+-#define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
+-
+-/* register access macros */
+-#ifndef __BIG_ENDIAN
+-#ifndef __mips__
+-#define R_REG(r) (\
+-	SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \
+-	readb((volatile u8*)(r)) : \
+-	sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \
+-	readl((volatile u32*)(r)), OSL_READ_REG(r)) \
+-)
+-#else				/* __mips__ */
+-#define R_REG(r) (\
+-	SELECT_BUS_READ( \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			__asm__ __volatile__("sync"); \
+-			switch (sizeof(*(r))) { \
+-			case sizeof(u8): \
+-				__osl_v = readb((volatile u8*)(r)); \
+-				break; \
+-			case sizeof(u16): \
+-				__osl_v = readw((volatile u16*)(r)); \
+-				break; \
+-			case sizeof(u32): \
+-				__osl_v = \
+-				readl((volatile u32*)(r)); \
+-				break; \
+-			} \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v; \
+-		}), \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v = OSL_READ_REG(r); \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v; \
+-		})) \
+-)
+-#endif				/* __mips__ */
+-
+-#define W_REG(r, v) do { \
+-	SELECT_BUS_WRITE( \
+-		switch (sizeof(*(r))) { \
+-		case sizeof(u8): \
+-			writeb((u8)(v), (volatile u8*)(r)); break; \
+-		case sizeof(u16): \
+-			writew((u16)(v), (volatile u16*)(r)); break; \
+-		case sizeof(u32): \
+-			writel((u32)(v), (volatile u32*)(r)); break; \
+-		}, \
+-		(OSL_WRITE_REG(r, v))); \
+-	} while (0)
+-#else				/* __BIG_ENDIAN */
+-#define R_REG(r) (\
+-	SELECT_BUS_READ( \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			switch (sizeof(*(r))) { \
+-			case sizeof(u8): \
+-				__osl_v = \
+-				readb((volatile u8*)((r)^3)); \
+-				break; \
+-			case sizeof(u16): \
+-				__osl_v = \
+-				readw((volatile u16*)((r)^2)); \
+-				break; \
+-			case sizeof(u32): \
+-				__osl_v = readl((volatile u32*)(r)); \
+-				break; \
+-			} \
+-			__osl_v; \
+-		}), \
+-		OSL_READ_REG(r)) \
+-)
+-#define W_REG(r, v) do { \
+-	SELECT_BUS_WRITE( \
+-		switch (sizeof(*(r))) { \
+-		case sizeof(u8):	\
+-			writeb((u8)(v), \
+-			(volatile u8*)((r)^3)); break; \
+-		case sizeof(u16):	\
+-			writew((u16)(v), \
+-			(volatile u16*)((r)^2)); break; \
+-		case sizeof(u32):	\
+-			writel((u32)(v), \
+-			(volatile u32*)(r)); break; \
+-		}, \
+-		(OSL_WRITE_REG(r, v))); \
+-	} while (0)
+-#endif				/* __BIG_ENDIAN */
+-
+-#define AND_REG(r, v)	W_REG((r), R_REG(r) & (v))
+-#define OR_REG(r, v)	W_REG((r), R_REG(r) | (v))
+-
+-#define SET_REG(r, mask, val) \
+-		W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
+-
+-#ifndef setbit
+-#ifndef NBBY			/* the BSD family defines NBBY */
+-#define	NBBY	8		/* 8 bits per byte */
+-#endif				/* #ifndef NBBY */
+-#define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
+-#define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+-#define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
+-#define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+-#endif				/* setbit */
+-
+-#define	NBITS(type)	(sizeof(type) * 8)
+-#define NBITVAL(nbits)	(1 << (nbits))
+-#define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
+-#define	NBITMASK(nbits)	MAXBITVAL(nbits)
+-#define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
+-
+-/* basic mux operation - can be optimized on several architectures */
+-#define MUX(pred, true, false) ((pred) ? (true) : (false))
+-
+-/* modulo inc/dec - assumes x E [0, bound - 1] */
+-#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
+-#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
+-
+-/* modulo inc/dec, bound = 2^k */
+-#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
+-#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
+-
+-/* modulo add/sub - assumes x, y E [0, bound - 1] */
+-#define MODADD(x, y, bound) \
+-    MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
+-#define MODSUB(x, y, bound) \
+-    MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
+-
+-/* module add/sub, bound = 2^k */
+-#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
+-#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
+-
+-/* crc defines */
+-#define CRC8_INIT_VALUE  0xff	/* Initial CRC8 checksum value */
+-#define CRC8_GOOD_VALUE  0x9f	/* Good final CRC8 checksum value */
+-#define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
+-#define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
+-
+-/* bcm_format_flags() bit description structure */
+-	typedef struct bcm_bit_desc {
+-		u32 bit;
+-		const char *name;
+-	} bcm_bit_desc_t;
+-
+-/* tag_ID/length/value_buffer tuple */
+-	typedef struct bcm_tlv {
+-		u8 id;
+-		u8 len;
+-		u8 data[1];
+-	} bcm_tlv_t;
+-
+-/* Check that bcm_tlv_t fits into the given buflen */
+-#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
+-
+-#define ETHER_ADDR_STR_LEN	18	/* 18-bytes of Ethernet address buffer length */
+-
+-/* crypto utility function */
+-/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */
+-	static inline void
+-	 xor_128bit_block(const u8 *src1, const u8 *src2, u8 *dst) {
+-		if (
+-#ifdef __i386__
+-			   1 ||
+-#endif
+-			   (((unsigned long) src1 | (unsigned long) src2 | (unsigned long) dst) &
+-			    3) == 0) {
+-			/* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */
+-			/* x86 supports unaligned.  This version runs 6x-9x faster on x86. */
+-			((u32 *) dst)[0] =
+-			    ((const u32 *)src1)[0] ^ ((const u32 *)
+-							 src2)[0];
+-			((u32 *) dst)[1] =
+-			    ((const u32 *)src1)[1] ^ ((const u32 *)
+-							 src2)[1];
+-			((u32 *) dst)[2] =
+-			    ((const u32 *)src1)[2] ^ ((const u32 *)
+-							 src2)[2];
+-			((u32 *) dst)[3] =
+-			    ((const u32 *)src1)[3] ^ ((const u32 *)
+-							 src2)[3];
+-		} else {
+-			/* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */
+-			int k;
+-			for (k = 0; k < 16; k++)
+-				dst[k] = src1[k] ^ src2[k];
+-		}
+-	}
+-
+-/* externs */
+-/* crc */
+-extern u8 bcm_crc8(u8 *p, uint nbytes, u8 crc);
+-/* format/print */
+-#if defined(BCMDBG)
+-	extern int bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags,
+-				    char *buf, int len);
+-	extern int bcm_format_hex(char *str, const void *bytes, int len);
+-#endif
+-	extern char *bcm_chipname(uint chipid, char *buf, uint len);
+-
+-	extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen,
+-						    uint key);
+-
+-/* multi-bool data type: set of bools, mbool is true if any is set */
+-	typedef u32 mbool;
+-#define mboolset(mb, bit)		((mb) |= (bit))	/* set one bool */
+-#define mboolclr(mb, bit)		((mb) &= ~(bit))	/* clear one bool */
+-#define mboolisset(mb, bit)		(((mb) & (bit)) != 0)	/* true if one bool is set */
+-#define	mboolmaskset(mb, mask, val)	((mb) = (((mb) & ~(mask)) | (val)))
+-
+-/* power conversion */
+-	extern u16 bcm_qdbm_to_mw(u8 qdbm);
+-	extern u8 bcm_mw_to_qdbm(u16 mw);
+-
+-	extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
+-	extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
+-
+-	extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf,
+-				uint len);
+-	extern uint bcm_bitcount(u8 *bitmap, uint bytelength);
+-
+-#endif				/* _bcmutils_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h
+deleted file mode 100644
+index a573ebf..0000000
+--- a/drivers/staging/brcm80211/include/bcmwifi.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmwifi_h_
+-#define	_bcmwifi_h_
+-
+-/* A chanspec holds the channel number, band, bandwidth and control sideband */
+-typedef u16 chanspec_t;
+-
+-/* channel defines */
+-#define CH_UPPER_SB			0x01
+-#define CH_LOWER_SB			0x02
+-#define CH_EWA_VALID			0x04
+-#define CH_20MHZ_APART			4
+-#define CH_10MHZ_APART			2
+-#define CH_5MHZ_APART			1	/* 2G band channels are 5 Mhz apart */
+-#define CH_MAX_2G_CHANNEL		14	/* Max channel in 2G band */
+-#define WLC_MAX_2G_CHANNEL		CH_MAX_2G_CHANNEL	/* legacy define */
+-#define	MAXCHANNEL		224	/* max # supported channels. The max channel no is 216,
+-					 * this is that + 1 rounded up to a multiple of NBBY (8).
+-					 * DO NOT MAKE it > 255: channels are u8's all over
+-					 */
+-
+-#define WL_CHANSPEC_CHAN_MASK		0x00ff
+-#define WL_CHANSPEC_CHAN_SHIFT		0
+-
+-#define WL_CHANSPEC_CTL_SB_MASK		0x0300
+-#define WL_CHANSPEC_CTL_SB_SHIFT	     8
+-#define WL_CHANSPEC_CTL_SB_LOWER	0x0100
+-#define WL_CHANSPEC_CTL_SB_UPPER	0x0200
+-#define WL_CHANSPEC_CTL_SB_NONE		0x0300
+-
+-#define WL_CHANSPEC_BW_MASK		0x0C00
+-#define WL_CHANSPEC_BW_SHIFT		    10
+-#define WL_CHANSPEC_BW_10		0x0400
+-#define WL_CHANSPEC_BW_20		0x0800
+-#define WL_CHANSPEC_BW_40		0x0C00
+-
+-#define WL_CHANSPEC_BAND_MASK		0xf000
+-#define WL_CHANSPEC_BAND_SHIFT		12
+-#define WL_CHANSPEC_BAND_5G		0x1000
+-#define WL_CHANSPEC_BAND_2G		0x2000
+-#define INVCHANSPEC			255
+-
+-/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
+-#define WF_CHAN_FACTOR_2_4_G		4814	/* 2.4 GHz band, 2407 MHz */
+-#define WF_CHAN_FACTOR_5_G		10000	/* 5   GHz band, 5000 MHz */
+-#define WF_CHAN_FACTOR_4_G		8000	/* 4.9 GHz band for Japan */
+-
+-/* channel defines */
+-#define LOWER_20_SB(channel)	(((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
+-#define UPPER_20_SB(channel)	(((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
+-				((channel) + CH_10MHZ_APART) : 0)
+-#define CHSPEC_WLCBANDUNIT(chspec)	(CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
+-#define CH20MHZ_CHSPEC(channel)	(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
+-				WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
+-				WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
+-#define NEXT_20MHZ_CHAN(channel)	(((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
+-					((channel) + CH_20MHZ_APART) : 0)
+-#define CH40MHZ_CHSPEC(channel, ctlsb)	(chanspec_t) \
+-					((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
+-					((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
+-					WL_CHANSPEC_BAND_5G))
+-#define CHSPEC_CHANNEL(chspec)	((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
+-#define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
+-
+-#ifdef WL11N_20MHZONLY
+-
+-#define CHSPEC_CTL_SB(chspec)	WL_CHANSPEC_CTL_SB_NONE
+-#define CHSPEC_BW(chspec)	WL_CHANSPEC_BW_20
+-#define CHSPEC_IS10(chspec)	0
+-#define CHSPEC_IS20(chspec)	1
+-#ifndef CHSPEC_IS40
+-#define CHSPEC_IS40(chspec)	0
+-#endif
+-
+-#else				/* !WL11N_20MHZONLY */
+-
+-#define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
+-#define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
+-#define CHSPEC_IS10(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
+-#define CHSPEC_IS20(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
+-#ifndef CHSPEC_IS40
+-#define CHSPEC_IS40(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
+-#endif
+-
+-#endif				/* !WL11N_20MHZONLY */
+-
+-#define CHSPEC_IS5G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
+-#define CHSPEC_IS2G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
+-#define CHSPEC_SB_NONE(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
+-#define CHSPEC_SB_UPPER(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
+-#define CHSPEC_SB_LOWER(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
+-#define CHSPEC_CTL_CHAN(chspec)  ((CHSPEC_SB_LOWER(chspec)) ? \
+-				  (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
+-				  (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
+-#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
+-
+-#define CHANSPEC_STR_LEN    8
+-
+-/* defined rate in 500kbps */
+-#define WLC_MAXRATE	108	/* in 500kbps units */
+-#define WLC_RATE_1M	2	/* in 500kbps units */
+-#define WLC_RATE_2M	4	/* in 500kbps units */
+-#define WLC_RATE_5M5	11	/* in 500kbps units */
+-#define WLC_RATE_11M	22	/* in 500kbps units */
+-#define WLC_RATE_6M	12	/* in 500kbps units */
+-#define WLC_RATE_9M	18	/* in 500kbps units */
+-#define WLC_RATE_12M	24	/* in 500kbps units */
+-#define WLC_RATE_18M	36	/* in 500kbps units */
+-#define WLC_RATE_24M	48	/* in 500kbps units */
+-#define WLC_RATE_36M	72	/* in 500kbps units */
+-#define WLC_RATE_48M	96	/* in 500kbps units */
+-#define WLC_RATE_54M	108	/* in 500kbps units */
+-
+-#define WLC_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
+-
+-/*
+- * Verify the chanspec is using a legal set of parameters, i.e. that the
+- * chanspec specified a band, bw, ctl_sb and channel and that the
+- * combination could be legal given any set of circumstances.
+- * RETURNS: true is the chanspec is malformed, false if it looks good.
+- */
+-extern bool bcm_chspec_malformed(chanspec_t chanspec);
+-
+-/*
+- * This function returns the channel number that control traffic is being sent on, for legacy
+- * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+- * sideband depending on the chanspec selected
+- */
+-extern u8 bcm_chspec_ctlchan(chanspec_t chspec);
+-
+-/*
+- * Return the channel number for a given frequency and base frequency.
+- * The returned channel number is relative to the given base frequency.
+- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+- *
+- * Frequency is specified in MHz.
+- * The base frequency is specified as (start_factor * 500 kHz).
+- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+- * 2.4 GHz and 5 GHz bands.
+- *
+- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+- * and [0, 200] otherwise.
+- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+- *
+- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+- */
+-extern int bcm_mhz2channel(uint freq, uint start_factor);
+-
+-#endif				/* _bcmwifi_h_ */
+diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h
+deleted file mode 100644
+index fbbcb9b..0000000
+--- a/drivers/staging/brcm80211/include/hnddma.h
++++ /dev/null
+@@ -1,226 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_hnddma_h_
+-#define	_hnddma_h_
+-
+-#ifndef _hnddma_pub_
+-#define _hnddma_pub_
+-struct hnddma_pub;
+-#endif				/* _hnddma_pub_ */
+-
+-/* map/unmap direction */
+-#define	DMA_TX	1		/* TX direction for DMA */
+-#define	DMA_RX	2		/* RX direction for DMA */
+-#define BUS_SWAP32(v)		(v)
+-
+-/* range param for dma_getnexttxp() and dma_txreclaim */
+-typedef enum txd_range {
+-	HNDDMA_RANGE_ALL = 1,
+-	HNDDMA_RANGE_TRANSMITTED,
+-	HNDDMA_RANGE_TRANSFERED
+-} txd_range_t;
+-
+-/* dma function type */
+-typedef void (*di_detach_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txreset_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxreset_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxidle_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txinit_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txenabled_t) (struct hnddma_pub *dmah);
+-typedef void (*di_rxinit_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txsuspend_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txresume_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txsuspended_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txsuspendedidle_t) (struct hnddma_pub *dmah);
+-typedef int (*di_txfast_t) (struct hnddma_pub *dmah, struct sk_buff *p,
+-			    bool commit);
+-typedef int (*di_txunframed_t) (struct hnddma_pub *dmah, void *p, uint len,
+-				bool commit);
+-typedef void *(*di_getpos_t) (struct hnddma_pub *di, bool direction);
+-typedef void (*di_fifoloopbackenable_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txstopped_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxstopped_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxenable_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxenabled_t) (struct hnddma_pub *dmah);
+-typedef void *(*di_rx_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxfill_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txreclaim_t) (struct hnddma_pub *dmah, txd_range_t range);
+-typedef void (*di_rxreclaim_t) (struct hnddma_pub *dmah);
+-typedef unsigned long (*di_getvar_t) (struct hnddma_pub *dmah,
+-				      const char *name);
+-typedef void *(*di_getnexttxp_t) (struct hnddma_pub *dmah, txd_range_t range);
+-typedef void *(*di_getnextrxp_t) (struct hnddma_pub *dmah, bool forceall);
+-typedef void *(*di_peeknexttxp_t) (struct hnddma_pub *dmah);
+-typedef void *(*di_peeknextrxp_t) (struct hnddma_pub *dmah);
+-typedef void (*di_rxparam_get_t) (struct hnddma_pub *dmah, u16 *rxoffset,
+-				  u16 *rxbufsize);
+-typedef void (*di_txblock_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txunblock_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txactive_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txrotate_t) (struct hnddma_pub *dmah);
+-typedef void (*di_counterreset_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_ctrlflags_t) (struct hnddma_pub *dmah, uint mask, uint flags);
+-typedef char *(*di_dump_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			    bool dumpring);
+-typedef char *(*di_dumptx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			      bool dumpring);
+-typedef char *(*di_dumprx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			      bool dumpring);
+-typedef uint(*di_rxactive_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txpending_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txcommitted_t) (struct hnddma_pub *dmah);
+-
+-/* dma opsvec */
+-typedef struct di_fcn_s {
+-	di_detach_t detach;
+-	di_txinit_t txinit;
+-	di_txreset_t txreset;
+-	di_txenabled_t txenabled;
+-	di_txsuspend_t txsuspend;
+-	di_txresume_t txresume;
+-	di_txsuspended_t txsuspended;
+-	di_txsuspendedidle_t txsuspendedidle;
+-	di_txfast_t txfast;
+-	di_txunframed_t txunframed;
+-	di_getpos_t getpos;
+-	di_txstopped_t txstopped;
+-	di_txreclaim_t txreclaim;
+-	di_getnexttxp_t getnexttxp;
+-	di_peeknexttxp_t peeknexttxp;
+-	di_txblock_t txblock;
+-	di_txunblock_t txunblock;
+-	di_txactive_t txactive;
+-	di_txrotate_t txrotate;
+-
+-	di_rxinit_t rxinit;
+-	di_rxreset_t rxreset;
+-	di_rxidle_t rxidle;
+-	di_rxstopped_t rxstopped;
+-	di_rxenable_t rxenable;
+-	di_rxenabled_t rxenabled;
+-	di_rx_t rx;
+-	di_rxfill_t rxfill;
+-	di_rxreclaim_t rxreclaim;
+-	di_getnextrxp_t getnextrxp;
+-	di_peeknextrxp_t peeknextrxp;
+-	di_rxparam_get_t rxparam_get;
+-
+-	di_fifoloopbackenable_t fifoloopbackenable;
+-	di_getvar_t d_getvar;
+-	di_counterreset_t counterreset;
+-	di_ctrlflags_t ctrlflags;
+-	di_dump_t dump;
+-	di_dumptx_t dumptx;
+-	di_dumprx_t dumprx;
+-	di_rxactive_t rxactive;
+-	di_txpending_t txpending;
+-	di_txcommitted_t txcommitted;
+-	uint endnum;
+-} di_fcn_t;
+-
+-/*
+- * Exported data structure (read-only)
+- */
+-/* export structure */
+-struct hnddma_pub {
+-	const di_fcn_t *di_fn;	/* DMA function pointers */
+-	uint txavail;		/* # free tx descriptors */
+-	uint dmactrlflags;	/* dma control flags */
+-
+-	/* rx error counters */
+-	uint rxgiants;		/* rx giant frames */
+-	uint rxnobuf;		/* rx out of dma descriptors */
+-	/* tx error counters */
+-	uint txnobuf;		/* tx out of dma descriptors */
+-};
+-
+-extern struct hnddma_pub *dma_attach(char *name, si_t *sih,
+-			    void *dmaregstx, void *dmaregsrx, uint ntxd,
+-			    uint nrxd, uint rxbufsize, int rxextheadroom,
+-			    uint nrxpost, uint rxoffset, uint *msg_level);
+-
+-extern const di_fcn_t dma64proc;
+-
+-#define dma_detach(di)			(dma64proc.detach(di))
+-#define dma_txreset(di)			(dma64proc.txreset(di))
+-#define dma_rxreset(di)			(dma64proc.rxreset(di))
+-#define dma_rxidle(di)			(dma64proc.rxidle(di))
+-#define dma_txinit(di)                  (dma64proc.txinit(di))
+-#define dma_txenabled(di)               (dma64proc.txenabled(di))
+-#define dma_rxinit(di)                  (dma64proc.rxinit(di))
+-#define dma_txsuspend(di)               (dma64proc.txsuspend(di))
+-#define dma_txresume(di)                (dma64proc.txresume(di))
+-#define dma_txsuspended(di)             (dma64proc.txsuspended(di))
+-#define dma_txsuspendedidle(di)         (dma64proc.txsuspendedidle(di))
+-#define dma_txfast(di, p, commit)	(dma64proc.txfast(di, p, commit))
+-#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
+-#define dma_getpos(di, dir)		(dma64proc.getpos(di, dir))
+-#define dma_fifoloopbackenable(di)      (dma64proc.fifoloopbackenable(di))
+-#define dma_txstopped(di)               (dma64proc.txstopped(di))
+-#define dma_rxstopped(di)               (dma64proc.rxstopped(di))
+-#define dma_rxenable(di)                (dma64proc.rxenable(di))
+-#define dma_rxenabled(di)               (dma64proc.rxenabled(di))
+-#define dma_rx(di)                      (dma64proc.rx(di))
+-#define dma_rxfill(di)                  (dma64proc.rxfill(di))
+-#define dma_txreclaim(di, range)	(dma64proc.txreclaim(di, range))
+-#define dma_rxreclaim(di)               (dma64proc.rxreclaim(di))
+-#define dma_getvar(di, name)		(dma64proc.d_getvar(di, name))
+-#define dma_getnexttxp(di, range)	(dma64proc.getnexttxp(di, range))
+-#define dma_getnextrxp(di, forceall)    (dma64proc.getnextrxp(di, forceall))
+-#define dma_peeknexttxp(di)             (dma64proc.peeknexttxp(di))
+-#define dma_peeknextrxp(di)             (dma64proc.peeknextrxp(di))
+-#define dma_rxparam_get(di, off, bufs)	(dma64proc.rxparam_get(di, off, bufs))
+-
+-#define dma_txblock(di)                 (dma64proc.txblock(di))
+-#define dma_txunblock(di)               (dma64proc.txunblock(di))
+-#define dma_txactive(di)                (dma64proc.txactive(di))
+-#define dma_rxactive(di)                (dma64proc.rxactive(di))
+-#define dma_txrotate(di)                (dma64proc.txrotate(di))
+-#define dma_counterreset(di)            (dma64proc.counterreset(di))
+-#define dma_ctrlflags(di, mask, flags)  (dma64proc.ctrlflags((di), (mask), (flags)))
+-#define dma_txpending(di)		(dma64proc.txpending(di))
+-#define dma_txcommitted(di)		(dma64proc.txcommitted(di))
+-
+-
+-/* return addresswidth allowed
+- * This needs to be done after SB attach but before dma attach.
+- * SB attach provides ability to probe backplane and dma core capabilities
+- * This info is needed by DMA_ALLOC_CONSISTENT in dma attach
+- */
+-extern uint dma_addrwidth(si_t *sih, void *dmaregs);
+-void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
+-		      (void *pkt, void *arg_a), void *arg_a);
+-
+-/*
+- * DMA(Bug) on some chips seems to declare that the packet is ready, but the
+- * packet length is not updated yet (by DMA) on the expected time.
+- * Workaround is to hold processor till DMA updates the length, and stay off
+- * the bus to allow DMA update the length in buffer
+- */
+-static inline void dma_spin_for_len(uint len, struct sk_buff *head)
+-{
+-#if defined(__mips__)
+-	if (!len) {
+-		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
+-			udelay(1);
+-
+-		*(u16 *) (head->data) = cpu_to_le16((u16) len);
+-	}
+-#endif				/* defined(__mips__) */
+-}
+-
+-#endif				/* _hnddma_h_ */
+diff --git a/drivers/staging/brcm80211/include/hndsoc.h b/drivers/staging/brcm80211/include/hndsoc.h
+deleted file mode 100644
+index 6435686..0000000
+--- a/drivers/staging/brcm80211/include/hndsoc.h
++++ /dev/null
+@@ -1,199 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_HNDSOC_H
+-#define	_HNDSOC_H
+-
+-/* Include the soci specific files */
+-#include <sbconfig.h>
+-#include <aidmp.h>
+-
+-/*
+- * SOC Interconnect Address Map.
+- * All regions may not exist on all chips.
+- */
+-#define SI_SDRAM_BASE		0x00000000	/* Physical SDRAM */
+-#define SI_PCI_MEM		0x08000000	/* Host Mode sb2pcitranslation0 (64 MB) */
+-#define SI_PCI_MEM_SZ		(64 * 1024 * 1024)
+-#define SI_PCI_CFG		0x0c000000	/* Host Mode sb2pcitranslation1 (64 MB) */
+-#define	SI_SDRAM_SWAPPED	0x10000000	/* Byteswapped Physical SDRAM */
+-#define SI_SDRAM_R2		0x80000000	/* Region 2 for sdram (512 MB) */
+-
+-#ifdef SI_ENUM_BASE_VARIABLE
+-#define SI_ENUM_BASE		(sii->pub.si_enum_base)
+-#else
+-#define SI_ENUM_BASE    	0x18000000	/* Enumeration space base */
+-#endif				/* SI_ENUM_BASE_VARIABLE */
+-
+-#define SI_WRAP_BASE    	0x18100000	/* Wrapper space base */
+-#define SI_CORE_SIZE    	0x1000	/* each core gets 4Kbytes for registers */
+-#define	SI_MAXCORES		16	/* Max cores (this is arbitrary, for software
+-					 * convenience and could be changed if we
+-					 * make any larger chips
+-					 */
+-
+-#define	SI_FASTRAM		0x19000000	/* On-chip RAM on chips that also have DDR */
+-#define	SI_FASTRAM_SWAPPED	0x19800000
+-
+-#define	SI_FLASH2		0x1c000000	/* Flash Region 2 (region 1 shadowed here) */
+-#define	SI_FLASH2_SZ		0x02000000	/* Size of Flash Region 2 */
+-#define	SI_ARMCM3_ROM		0x1e000000	/* ARM Cortex-M3 ROM */
+-#define	SI_FLASH1		0x1fc00000	/* MIPS Flash Region 1 */
+-#define	SI_FLASH1_SZ		0x00400000	/* MIPS Size of Flash Region 1 */
+-#define	SI_ARM7S_ROM		0x20000000	/* ARM7TDMI-S ROM */
+-#define	SI_ARMCM3_SRAM2		0x60000000	/* ARM Cortex-M3 SRAM Region 2 */
+-#define	SI_ARM7S_SRAM2		0x80000000	/* ARM7TDMI-S SRAM Region 2 */
+-#define	SI_ARM_FLASH1		0xffff0000	/* ARM Flash Region 1 */
+-#define	SI_ARM_FLASH1_SZ	0x00010000	/* ARM Size of Flash Region 1 */
+-
+-#define SI_PCI_DMA		0x40000000	/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA2		0x80000000	/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA_SZ		0x40000000	/* Client Mode sb2pcitranslation2 size in bytes */
+-#define SI_PCIE_DMA_L32		0x00000000	/* PCIE Client Mode sb2pcitranslation2
+-						 * (2 ZettaBytes), low 32 bits
+-						 */
+-#define SI_PCIE_DMA_H32		0x80000000	/* PCIE Client Mode sb2pcitranslation2
+-						 * (2 ZettaBytes), high 32 bits
+-						 */
+-
+-/* core codes */
+-#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
+-#define	CC_CORE_ID		0x800	/* chipcommon core */
+-#define	ILINE20_CORE_ID		0x801	/* iline20 core */
+-#define	SRAM_CORE_ID		0x802	/* sram core */
+-#define	SDRAM_CORE_ID		0x803	/* sdram core */
+-#define	PCI_CORE_ID		0x804	/* pci core */
+-#define	MIPS_CORE_ID		0x805	/* mips core */
+-#define	ENET_CORE_ID		0x806	/* enet mac core */
+-#define	CODEC_CORE_ID		0x807	/* v90 codec core */
+-#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
+-#define	ADSL_CORE_ID		0x809	/* ADSL core */
+-#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
+-#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
+-#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
+-#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
+-#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
+-#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
+-#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
+-#define	EXTIF_CORE_ID		0x811	/* external interface core */
+-#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
+-#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
+-#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
+-#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
+-#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
+-#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
+-#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
+-#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
+-#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
+-#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
+-#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
+-#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
+-#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
+-#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
+-#define	PCIE_CORE_ID		0x820	/* pci express core */
+-#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
+-#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
+-#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
+-#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
+-#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
+-#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
+-#define	PMU_CORE_ID		0x827	/* PMU core */
+-#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
+-#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
+-#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
+-#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
+-#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
+-#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
+-#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
+-#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
+-#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
+-#define	SC_CORE_ID		0x831	/* shared common core */
+-#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
+-#define	SPIH_CORE_ID		0x833	/* SPI host core */
+-#define	I2S_CORE_ID		0x834	/* I2S core */
+-#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
+-#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
+-#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
+-#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it maps all
+-					 * unused address ranges
+-					 */
+-
+-/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+- * and chipcommon being the first core:
+- */
+-#define	SI_CC_IDX		0
+-
+-/* SOC Interconnect types (aka chip types) */
+-#define	SOCI_AI			1
+-
+-/* Common core control flags */
+-#define	SICF_BIST_EN		0x8000
+-#define	SICF_PME_EN		0x4000
+-#define	SICF_CORE_BITS		0x3ffc
+-#define	SICF_FGC		0x0002
+-#define	SICF_CLOCK_EN		0x0001
+-
+-/* Common core status flags */
+-#define	SISF_BIST_DONE		0x8000
+-#define	SISF_BIST_ERROR		0x4000
+-#define	SISF_GATED_CLK		0x2000
+-#define	SISF_DMA64		0x1000
+-#define	SISF_CORE_BITS		0x0fff
+-
+-/* A register that is common to all cores to
+- * communicate w/PMU regarding clock control.
+- */
+-#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
+-
+-/* clk_ctl_st register */
+-#define	CCS_FORCEALP		0x00000001	/* force ALP request */
+-#define	CCS_FORCEHT		0x00000002	/* force HT request */
+-#define	CCS_FORCEILP		0x00000004	/* force ILP request */
+-#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
+-#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
+-#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
+-#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
+-#define CCS_ERSRC_REQ_SHIFT	8
+-#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
+-#define	CCS_HTAVAIL		0x00020000	/* HT is available */
+-#define CCS_BP_ON_APL		0x00040000	/* RO: Backplane is running on ALP clock */
+-#define CCS_BP_ON_HT		0x00080000	/* RO: Backplane is running on HT clock */
+-#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
+-#define CCS_ERSRC_STS_SHIFT	24
+-
+-#define	CCS0_HTAVAIL		0x00010000	/* HT avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_ALPAVAIL		0x00020000	/* ALP avail in chipc and pcmcia on 4328a0 */
+-
+-/* Not really related to SOC Interconnect, but a couple of software
+- * conventions for the use the flash space:
+- */
+-
+-/* Minimum amount of flash we support */
+-#define FLASH_MIN		0x00020000	/* Minimum flash size */
+-
+-/* A boot/binary may have an embedded block that describes its size  */
+-#define	BISZ_OFFSET		0x3e0	/* At this offset into the binary */
+-#define	BISZ_MAGIC		0x4249535a	/* Marked with this value: 'BISZ' */
+-#define	BISZ_MAGIC_IDX		0	/* Word 0: magic */
+-#define	BISZ_TXTST_IDX		1	/*      1: text start */
+-#define	BISZ_TXTEND_IDX		2	/*      2: text end */
+-#define	BISZ_DATAST_IDX		3	/*      3: data start */
+-#define	BISZ_DATAEND_IDX	4	/*      4: data end */
+-#define	BISZ_BSSST_IDX		5	/*      5: bss start */
+-#define	BISZ_BSSEND_IDX		6	/*      6: bss end */
+-#define BISZ_SIZE		7	/* descriptor size in 32-bit integers */
+-
+-#endif				/* _HNDSOC_H */
+diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h
+deleted file mode 100644
+index 30321eb..0000000
+--- a/drivers/staging/brcm80211/include/nicpci.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_NICPCI_H
+-#define	_NICPCI_H
+-
+-#if defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS))
+-#define pcicore_find_pci_capability(a, b, c, d) (0)
+-#define pcie_readreg(a, b, c, d) (0)
+-#define pcie_writereg(a, b, c, d, e) (0)
+-
+-#define pcie_clkreq(a, b, c)	(0)
+-#define pcie_lcreg(a, b, c)	(0)
+-
+-#define pcicore_init(a, b, c) (0x0dadbeef)
+-#define pcicore_deinit(a)	do { } while (0)
+-#define pcicore_attach(a, b, c)	do { } while (0)
+-#define pcicore_hwup(a)		do { } while (0)
+-#define pcicore_up(a, b)	do { } while (0)
+-#define pcicore_sleep(a)	do { } while (0)
+-#define pcicore_down(a, b)	do { } while (0)
+-
+-#define pcie_war_ovr_aspm_update(a, b)	do { } while (0)
+-
+-#define pcicore_pcieserdesreg(a, b, c, d, e) (0)
+-#define pcicore_pciereg(a, b, c, d, e) (0)
+-
+-#define pcicore_pmecap_fast(a)	(false)
+-#define pcicore_pmeen(a)	do { } while (0)
+-#define pcicore_pmeclr(a)	do { } while (0)
+-#define pcicore_pmestat(a)	(false)
+-#else
+-struct sbpcieregs;
+-
+-extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id,
+-					 unsigned char *buf, u32 *buflen);
+-extern uint pcie_readreg(struct sbpcieregs *pcieregs,
+-			 uint addrtype, uint offset);
+-extern uint pcie_writereg(struct sbpcieregs *pcieregs,
+-			  uint addrtype, uint offset, uint val);
+-
+-extern u8 pcie_clkreq(void *pch, u32 mask, u32 val);
+-extern u32 pcie_lcreg(void *pch, u32 mask, u32 val);
+-
+-extern void *pcicore_init(si_t *sih, void *pdev, void *regs);
+-extern void pcicore_deinit(void *pch);
+-extern void pcicore_attach(void *pch, char *pvars, int state);
+-extern void pcicore_hwup(void *pch);
+-extern void pcicore_up(void *pch, int state);
+-extern void pcicore_sleep(void *pch);
+-extern void pcicore_down(void *pch, int state);
+-
+-extern void pcie_war_ovr_aspm_update(void *pch, u8 aspm);
+-extern u32 pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset,
+-				    u32 mask, u32 val);
+-
+-extern u32 pcicore_pciereg(void *pch, u32 offset, u32 mask,
+-			      u32 val, uint type);
+-
+-extern bool pcicore_pmecap_fast(void *pch);
+-extern void pcicore_pmeen(void *pch);
+-extern void pcicore_pmeclr(void *pch);
+-extern bool pcicore_pmestat(void *pch);
+-#endif /* defined(BCMSDIO)||(defined(BCMBUSTYPE) && (BCMBUSTYPE==SI_BUS)) */
+-
+-#endif				/* _NICPCI_H */
+diff --git a/drivers/staging/brcm80211/include/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h
+deleted file mode 100644
+index 9153dcb..0000000
+--- a/drivers/staging/brcm80211/include/pci_core.h
++++ /dev/null
+@@ -1,122 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_PCI_CORE_H_
+-#define	_PCI_CORE_H_
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* Sonics side: PCI core and host control registers */
+-struct sbpciregs {
+-	u32 control;		/* PCI control */
+-	u32 PAD[3];
+-	u32 arbcontrol;	/* PCI arbiter control */
+-	u32 clkrun;		/* Clkrun Control (>=rev11) */
+-	u32 PAD[2];
+-	u32 intstatus;	/* Interrupt status */
+-	u32 intmask;		/* Interrupt mask */
+-	u32 sbtopcimailbox;	/* Sonics to PCI mailbox */
+-	u32 PAD[9];
+-	u32 bcastaddr;	/* Sonics broadcast address */
+-	u32 bcastdata;	/* Sonics broadcast data */
+-	u32 PAD[2];
+-	u32 gpioin;		/* ro: gpio input (>=rev2) */
+-	u32 gpioout;		/* rw: gpio output (>=rev2) */
+-	u32 gpioouten;	/* rw: gpio output enable (>= rev2) */
+-	u32 gpiocontrol;	/* rw: gpio control (>= rev2) */
+-	u32 PAD[36];
+-	u32 sbtopci0;	/* Sonics to PCI translation 0 */
+-	u32 sbtopci1;	/* Sonics to PCI translation 1 */
+-	u32 sbtopci2;	/* Sonics to PCI translation 2 */
+-	u32 PAD[189];
+-	u32 pcicfg[4][64];	/* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
+-	u16 sprom[36];	/* SPROM shadow Area */
+-	u32 PAD[46];
+-};
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* PCI control */
+-#define PCI_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
+-#define PCI_RST		0x02	/* Value driven out to pin */
+-#define PCI_CLK_OE	0x04	/* When set, drives clock as gated by PCI_CLK out to pin */
+-#define PCI_CLK		0x08	/* Gate for clock driven out to pin */
+-
+-/* PCI arbiter control */
+-#define PCI_INT_ARB	0x01	/* When set, use an internal arbiter */
+-#define PCI_EXT_ARB	0x02	/* When set, use an external arbiter */
+-/* ParkID - for PCI corerev >= 8 */
+-#define PCI_PARKID_MASK		0x1c	/* Selects which agent is parked on an idle bus */
+-#define PCI_PARKID_SHIFT	2
+-#define PCI_PARKID_EXT0		0	/* External master 0 */
+-#define PCI_PARKID_EXT1		1	/* External master 1 */
+-#define PCI_PARKID_EXT2		2	/* External master 2 */
+-#define PCI_PARKID_EXT3		3	/* External master 3 (rev >= 11) */
+-#define PCI_PARKID_INT		3	/* Internal master (rev < 11) */
+-#define PCI11_PARKID_INT	4	/* Internal master (rev >= 11) */
+-#define PCI_PARKID_LAST		4	/* Last active master (rev < 11) */
+-#define PCI11_PARKID_LAST	5	/* Last active master (rev >= 11) */
+-
+-#define PCI_CLKRUN_DSBL	0x8000	/* Bit 15 forceClkrun */
+-
+-/* Interrupt status/mask */
+-#define PCI_INTA	0x01	/* PCI INTA# is asserted */
+-#define PCI_INTB	0x02	/* PCI INTB# is asserted */
+-#define PCI_SERR	0x04	/* PCI SERR# has been asserted (write one to clear) */
+-#define PCI_PERR	0x08	/* PCI PERR# has been asserted (write one to clear) */
+-#define PCI_PME		0x10	/* PCI PME# is asserted */
+-
+-/* (General) PCI/SB mailbox interrupts, two bits per pci function */
+-#define	MAILBOX_F0_0	0x100	/* function 0, int 0 */
+-#define	MAILBOX_F0_1	0x200	/* function 0, int 1 */
+-#define	MAILBOX_F1_0	0x400	/* function 1, int 0 */
+-#define	MAILBOX_F1_1	0x800	/* function 1, int 1 */
+-#define	MAILBOX_F2_0	0x1000	/* function 2, int 0 */
+-#define	MAILBOX_F2_1	0x2000	/* function 2, int 1 */
+-#define	MAILBOX_F3_0	0x4000	/* function 3, int 0 */
+-#define	MAILBOX_F3_1	0x8000	/* function 3, int 1 */
+-
+-/* Sonics broadcast address */
+-#define BCAST_ADDR_MASK	0xff	/* Broadcast register address */
+-
+-/* Sonics to PCI translation types */
+-#define SBTOPCI0_MASK	0xfc000000
+-#define SBTOPCI1_MASK	0xfc000000
+-#define SBTOPCI2_MASK	0xc0000000
+-#define SBTOPCI_MEM	0
+-#define SBTOPCI_IO	1
+-#define SBTOPCI_CFG0	2
+-#define SBTOPCI_CFG1	3
+-#define	SBTOPCI_PREF	0x4	/* prefetch enable */
+-#define	SBTOPCI_BURST	0x8	/* burst enable */
+-#define	SBTOPCI_RC_MASK		0x30	/* read command (>= rev11) */
+-#define	SBTOPCI_RC_READ		0x00	/* memory read */
+-#define	SBTOPCI_RC_READLINE	0x10	/* memory read line */
+-#define	SBTOPCI_RC_READMULTI	0x20	/* memory read multiple */
+-
+-/* PCI core index in SROM shadow area */
+-#define SRSH_PI_OFFSET	0	/* first word */
+-#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
+-#define SRSH_PI_SHIFT	12	/* bit 15:12 */
+-
+-#endif				/* _PCI_CORE_H_ */
+diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h
+deleted file mode 100644
+index d0c617a..0000000
+--- a/drivers/staging/brcm80211/include/pcicfg.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_h_pcicfg_
+-#define	_h_pcicfg_
+-
+-#include <linux/pci_regs.h>
+-
+-/* PCI configuration address space size */
+-#define PCI_SZPCR		256
+-
+-/* Everything below is BRCM HND proprietary */
+-
+-/* Brcm PCI configuration registers */
+-#define PCI_BAR0_WIN		0x80	/* backplane address space accessed by BAR0 */
+-#define PCI_SPROM_CONTROL	0x88	/* sprom property control */
+-#define PCI_INT_MASK		0x94	/* mask of PCI and other cores interrupts */
+-#define  PCI_SBIM_SHIFT		8	/* backplane core interrupt mask bits offset */
+-#define PCI_BAR0_WIN2		0xac	/* backplane address space accessed by second 4KB of BAR0 */
+-#define PCI_GPIO_IN		0xb0	/* pci config space gpio input (>=rev3) */
+-#define PCI_GPIO_OUT		0xb4	/* pci config space gpio output (>=rev3) */
+-#define PCI_GPIO_OUTEN		0xb8	/* pci config space gpio output enable (>=rev3) */
+-
+-#define PCI_BAR0_SPROM_OFFSET	(4 * 1024)	/* bar0 + 4K accesses external sprom */
+-#define PCI_BAR0_PCIREGS_OFFSET	(6 * 1024)	/* bar0 + 6K accesses pci core registers */
+-#define PCI_BAR0_PCISBR_OFFSET	(4 * 1024)	/* pci core SB registers are at the end of the
+-						 * 8KB window, so their address is the "regular"
+-						 * address plus 4K
+-						 */
+-#define PCI_BAR0_WINSZ		(16 * 1024)	/* bar0 window size Match with corerev 13 */
+-/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
+-#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)	/* bar0 + 8K accesses pci/pcie core registers */
+-#define PCI_16KB0_CCREGS_OFFSET	(12 * 1024)	/* bar0 + 12K accesses chipc core registers */
+-
+-#define PCI_SBIM_STATUS_SERR	0x4	/* backplane SBErr interrupt status */
+-
+-#endif				/* _h_pcicfg_ */
+diff --git a/drivers/staging/brcm80211/include/pcie_core.h b/drivers/staging/brcm80211/include/pcie_core.h
+deleted file mode 100644
+index cd54ddc..0000000
+--- a/drivers/staging/brcm80211/include/pcie_core.h
++++ /dev/null
+@@ -1,299 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_PCIE_CORE_H
+-#define	_PCIE_CORE_H
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* PCIE Enumeration space offsets */
+-#define  PCIE_CORE_CONFIG_OFFSET	0x0
+-#define  PCIE_FUNC0_CONFIG_OFFSET	0x400
+-#define  PCIE_FUNC1_CONFIG_OFFSET	0x500
+-#define  PCIE_FUNC2_CONFIG_OFFSET	0x600
+-#define  PCIE_FUNC3_CONFIG_OFFSET	0x700
+-#define  PCIE_SPROM_SHADOW_OFFSET	0x800
+-#define  PCIE_SBCONFIG_OFFSET		0xE00
+-
+-/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */
+-#define PCIE_DEV_BAR0_SIZE		0x4000
+-#define PCIE_BAR0_WINMAPCORE_OFFSET	0x0
+-#define PCIE_BAR0_EXTSPROM_OFFSET	0x1000
+-#define PCIE_BAR0_PCIECORE_OFFSET	0x2000
+-#define PCIE_BAR0_CCCOREREG_OFFSET	0x3000
+-
+-/* different register spaces to access thr'u pcie indirect access */
+-#define PCIE_CONFIGREGS 	1	/* Access to config space */
+-#define PCIE_PCIEREGS 		2	/* Access to pcie registers */
+-
+-/* SB side: PCIE core and host control registers */
+-typedef struct sbpcieregs {
+-	u32 control;		/* host mode only */
+-	u32 PAD[2];
+-	u32 biststatus;	/* bist Status: 0x00C */
+-	u32 gpiosel;		/* PCIE gpio sel: 0x010 */
+-	u32 gpioouten;	/* PCIE gpio outen: 0x14 */
+-	u32 PAD[2];
+-	u32 intstatus;	/* Interrupt status: 0x20 */
+-	u32 intmask;		/* Interrupt mask: 0x24 */
+-	u32 sbtopcimailbox;	/* sb to pcie mailbox: 0x028 */
+-	u32 PAD[53];
+-	u32 sbtopcie0;	/* sb to pcie translation 0: 0x100 */
+-	u32 sbtopcie1;	/* sb to pcie translation 1: 0x104 */
+-	u32 sbtopcie2;	/* sb to pcie translation 2: 0x108 */
+-	u32 PAD[5];
+-
+-	/* pcie core supports in direct access to config space */
+-	u32 configaddr;	/* pcie config space access: Address field: 0x120 */
+-	u32 configdata;	/* pcie config space access: Data field: 0x124 */
+-
+-	/* mdio access to serdes */
+-	u32 mdiocontrol;	/* controls the mdio access: 0x128 */
+-	u32 mdiodata;	/* Data to the mdio access: 0x12c */
+-
+-	/* pcie protocol phy/dllp/tlp register indirect access mechanism */
+-	u32 pcieindaddr;	/* indirect access to the internal register: 0x130 */
+-	u32 pcieinddata;	/* Data to/from the internal regsiter: 0x134 */
+-
+-	u32 clkreqenctrl;	/* >= rev 6, Clkreq rdma control : 0x138 */
+-	u32 PAD[177];
+-	u32 pciecfg[4][64];	/* 0x400 - 0x7FF, PCIE Cfg Space */
+-	u16 sprom[64];	/* SPROM shadow Area */
+-} sbpcieregs_t;
+-
+-/* PCI control */
+-#define PCIE_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
+-#define PCIE_RST	0x02	/* Value driven out to pin */
+-
+-#define	PCIE_CFGADDR	0x120	/* offsetof(configaddr) */
+-#define	PCIE_CFGDATA	0x124	/* offsetof(configdata) */
+-
+-/* Interrupt status/mask */
+-#define PCIE_INTA	0x01	/* PCIE INTA message is received */
+-#define PCIE_INTB	0x02	/* PCIE INTB message is received */
+-#define PCIE_INTFATAL	0x04	/* PCIE INTFATAL message is received */
+-#define PCIE_INTNFATAL	0x08	/* PCIE INTNONFATAL message is received */
+-#define PCIE_INTCORR	0x10	/* PCIE INTCORR message is received */
+-#define PCIE_INTPME	0x20	/* PCIE INTPME message is received */
+-
+-/* SB to PCIE translation masks */
+-#define SBTOPCIE0_MASK	0xfc000000
+-#define SBTOPCIE1_MASK	0xfc000000
+-#define SBTOPCIE2_MASK	0xc0000000
+-
+-/* Access type bits (0:1) */
+-#define SBTOPCIE_MEM	0
+-#define SBTOPCIE_IO	1
+-#define SBTOPCIE_CFG0	2
+-#define SBTOPCIE_CFG1	3
+-
+-/* Prefetch enable bit 2 */
+-#define SBTOPCIE_PF		4
+-
+-/* Write Burst enable for memory write bit 3 */
+-#define SBTOPCIE_WR_BURST	8
+-
+-/* config access */
+-#define CONFIGADDR_FUNC_MASK	0x7000
+-#define CONFIGADDR_FUNC_SHF	12
+-#define CONFIGADDR_REG_MASK	0x0FFF
+-#define CONFIGADDR_REG_SHF	0
+-
+-#define PCIE_CONFIG_INDADDR(f, r)	\
+-	((((f) & CONFIGADDR_FUNC_MASK) << CONFIGADDR_FUNC_SHF) | \
+-	(((r) & CONFIGADDR_REG_MASK) << CONFIGADDR_REG_SHF))
+-
+-/* PCIE protocol regs Indirect Address */
+-#define PCIEADDR_PROT_MASK	0x300
+-#define PCIEADDR_PROT_SHF	8
+-#define PCIEADDR_PL_TLP		0
+-#define PCIEADDR_PL_DLLP	1
+-#define PCIEADDR_PL_PLP		2
+-
+-/* PCIE protocol PHY diagnostic registers */
+-#define	PCIE_PLP_MODEREG		0x200	/* Mode */
+-#define	PCIE_PLP_STATUSREG		0x204	/* Status */
+-#define PCIE_PLP_LTSSMCTRLREG		0x208	/* LTSSM control */
+-#define PCIE_PLP_LTLINKNUMREG		0x20c	/* Link Training Link number */
+-#define PCIE_PLP_LTLANENUMREG		0x210	/* Link Training Lane number */
+-#define PCIE_PLP_LTNFTSREG		0x214	/* Link Training N_FTS */
+-#define PCIE_PLP_ATTNREG		0x218	/* Attention */
+-#define PCIE_PLP_ATTNMASKREG		0x21C	/* Attention Mask */
+-#define PCIE_PLP_RXERRCTR		0x220	/* Rx Error */
+-#define PCIE_PLP_RXFRMERRCTR		0x224	/* Rx Framing Error */
+-#define PCIE_PLP_RXERRTHRESHREG		0x228	/* Rx Error threshold */
+-#define PCIE_PLP_TESTCTRLREG		0x22C	/* Test Control reg */
+-#define PCIE_PLP_SERDESCTRLOVRDREG	0x230	/* SERDES Control Override */
+-#define PCIE_PLP_TIMINGOVRDREG		0x234	/* Timing param override */
+-#define PCIE_PLP_RXTXSMDIAGREG		0x238	/* RXTX State Machine Diag */
+-#define PCIE_PLP_LTSSMDIAGREG		0x23C	/* LTSSM State Machine Diag */
+-
+-/* PCIE protocol DLLP diagnostic registers */
+-#define PCIE_DLLP_LCREG			0x100	/* Link Control */
+-#define PCIE_DLLP_LSREG			0x104	/* Link Status */
+-#define PCIE_DLLP_LAREG			0x108	/* Link Attention */
+-#define PCIE_DLLP_LAMASKREG		0x10C	/* Link Attention Mask */
+-#define PCIE_DLLP_NEXTTXSEQNUMREG	0x110	/* Next Tx Seq Num */
+-#define PCIE_DLLP_ACKEDTXSEQNUMREG	0x114	/* Acked Tx Seq Num */
+-#define PCIE_DLLP_PURGEDTXSEQNUMREG	0x118	/* Purged Tx Seq Num */
+-#define PCIE_DLLP_RXSEQNUMREG		0x11C	/* Rx Sequence Number */
+-#define PCIE_DLLP_LRREG			0x120	/* Link Replay */
+-#define PCIE_DLLP_LACKTOREG		0x124	/* Link Ack Timeout */
+-#define PCIE_DLLP_PMTHRESHREG		0x128	/* Power Management Threshold */
+-#define PCIE_DLLP_RTRYWPREG		0x12C	/* Retry buffer write ptr */
+-#define PCIE_DLLP_RTRYRPREG		0x130	/* Retry buffer Read ptr */
+-#define PCIE_DLLP_RTRYPPREG		0x134	/* Retry buffer Purged ptr */
+-#define PCIE_DLLP_RTRRWREG		0x138	/* Retry buffer Read/Write */
+-#define PCIE_DLLP_ECTHRESHREG		0x13C	/* Error Count Threshold */
+-#define PCIE_DLLP_TLPERRCTRREG		0x140	/* TLP Error Counter */
+-#define PCIE_DLLP_ERRCTRREG		0x144	/* Error Counter */
+-#define PCIE_DLLP_NAKRXCTRREG		0x148	/* NAK Received Counter */
+-#define PCIE_DLLP_TESTREG		0x14C	/* Test */
+-#define PCIE_DLLP_PKTBIST		0x150	/* Packet BIST */
+-#define PCIE_DLLP_PCIE11		0x154	/* DLLP PCIE 1.1 reg */
+-
+-#define PCIE_DLLP_LSREG_LINKUP		(1 << 16)
+-
+-/* PCIE protocol TLP diagnostic registers */
+-#define PCIE_TLP_CONFIGREG		0x000	/* Configuration */
+-#define PCIE_TLP_WORKAROUNDSREG		0x004	/* TLP Workarounds */
+-#define PCIE_TLP_WRDMAUPPER		0x010	/* Write DMA Upper Address */
+-#define PCIE_TLP_WRDMALOWER		0x014	/* Write DMA Lower Address */
+-#define PCIE_TLP_WRDMAREQ_LBEREG	0x018	/* Write DMA Len/ByteEn Req */
+-#define PCIE_TLP_RDDMAUPPER		0x01C	/* Read DMA Upper Address */
+-#define PCIE_TLP_RDDMALOWER		0x020	/* Read DMA Lower Address */
+-#define PCIE_TLP_RDDMALENREG		0x024	/* Read DMA Len Req */
+-#define PCIE_TLP_MSIDMAUPPER		0x028	/* MSI DMA Upper Address */
+-#define PCIE_TLP_MSIDMALOWER		0x02C	/* MSI DMA Lower Address */
+-#define PCIE_TLP_MSIDMALENREG		0x030	/* MSI DMA Len Req */
+-#define PCIE_TLP_SLVREQLENREG		0x034	/* Slave Request Len */
+-#define PCIE_TLP_FCINPUTSREQ		0x038	/* Flow Control Inputs */
+-#define PCIE_TLP_TXSMGRSREQ		0x03C	/* Tx StateMachine and Gated Req */
+-#define PCIE_TLP_ADRACKCNTARBLEN	0x040	/* Address Ack XferCnt and ARB Len */
+-#define PCIE_TLP_DMACPLHDR0		0x044	/* DMA Completion Hdr 0 */
+-#define PCIE_TLP_DMACPLHDR1		0x048	/* DMA Completion Hdr 1 */
+-#define PCIE_TLP_DMACPLHDR2		0x04C	/* DMA Completion Hdr 2 */
+-#define PCIE_TLP_DMACPLMISC0		0x050	/* DMA Completion Misc0 */
+-#define PCIE_TLP_DMACPLMISC1		0x054	/* DMA Completion Misc1 */
+-#define PCIE_TLP_DMACPLMISC2		0x058	/* DMA Completion Misc2 */
+-#define PCIE_TLP_SPTCTRLLEN		0x05C	/* Split Controller Req len */
+-#define PCIE_TLP_SPTCTRLMSIC0		0x060	/* Split Controller Misc 0 */
+-#define PCIE_TLP_SPTCTRLMSIC1		0x064	/* Split Controller Misc 1 */
+-#define PCIE_TLP_BUSDEVFUNC		0x068	/* Bus/Device/Func */
+-#define PCIE_TLP_RESETCTR		0x06C	/* Reset Counter */
+-#define PCIE_TLP_RTRYBUF		0x070	/* Retry Buffer value */
+-#define PCIE_TLP_TGTDEBUG1		0x074	/* Target Debug Reg1 */
+-#define PCIE_TLP_TGTDEBUG2		0x078	/* Target Debug Reg2 */
+-#define PCIE_TLP_TGTDEBUG3		0x07C	/* Target Debug Reg3 */
+-#define PCIE_TLP_TGTDEBUG4		0x080	/* Target Debug Reg4 */
+-
+-/* MDIO control */
+-#define MDIOCTL_DIVISOR_MASK		0x7f	/* clock to be used on MDIO */
+-#define MDIOCTL_DIVISOR_VAL		0x2
+-#define MDIOCTL_PREAM_EN		0x80	/* Enable preamble sequnce */
+-#define MDIOCTL_ACCESS_DONE		0x100	/* Tranaction complete */
+-
+-/* MDIO Data */
+-#define MDIODATA_MASK			0x0000ffff	/* data 2 bytes */
+-#define MDIODATA_TA			0x00020000	/* Turnaround */
+-#define MDIODATA_REGADDR_SHF_OLD	18	/* Regaddr shift (rev < 10) */
+-#define MDIODATA_REGADDR_MASK_OLD	0x003c0000	/* Regaddr Mask (rev < 10) */
+-#define MDIODATA_DEVADDR_SHF_OLD	22	/* Physmedia devaddr shift (rev < 10) */
+-#define MDIODATA_DEVADDR_MASK_OLD	0x0fc00000	/* Physmedia devaddr Mask (rev < 10) */
+-#define MDIODATA_REGADDR_SHF		18	/* Regaddr shift */
+-#define MDIODATA_REGADDR_MASK		0x007c0000	/* Regaddr Mask */
+-#define MDIODATA_DEVADDR_SHF		23	/* Physmedia devaddr shift */
+-#define MDIODATA_DEVADDR_MASK		0x0f800000	/* Physmedia devaddr Mask */
+-#define MDIODATA_WRITE			0x10000000	/* write Transaction */
+-#define MDIODATA_READ			0x20000000	/* Read Transaction */
+-#define MDIODATA_START			0x40000000	/* start of Transaction */
+-
+-#define MDIODATA_DEV_ADDR		0x0	/* dev address for serdes */
+-#define	MDIODATA_BLK_ADDR		0x1F	/* blk address for serdes */
+-
+-/* MDIO devices (SERDES modules)
+- *  unlike old pcie cores (rev < 10), rev10 pcie serde organizes registers into a few blocks.
+- *  two layers mapping (blockidx, register offset) is required
+- */
+-#define MDIO_DEV_IEEE0		0x000
+-#define MDIO_DEV_IEEE1		0x001
+-#define MDIO_DEV_BLK0		0x800
+-#define MDIO_DEV_BLK1		0x801
+-#define MDIO_DEV_BLK2		0x802
+-#define MDIO_DEV_BLK3		0x803
+-#define MDIO_DEV_BLK4		0x804
+-#define MDIO_DEV_TXPLL		0x808	/* TXPLL register block idx */
+-#define MDIO_DEV_TXCTRL0	0x820
+-#define MDIO_DEV_SERDESID	0x831
+-#define MDIO_DEV_RXCTRL0	0x840
+-
+-/* serdes regs (rev < 10) */
+-#define MDIODATA_DEV_PLL       		0x1d	/* SERDES PLL Dev */
+-#define MDIODATA_DEV_TX        		0x1e	/* SERDES TX Dev */
+-#define MDIODATA_DEV_RX        		0x1f	/* SERDES RX Dev */
+-	/* SERDES RX registers */
+-#define SERDES_RX_CTRL			1	/* Rx cntrl */
+-#define SERDES_RX_TIMER1		2	/* Rx Timer1 */
+-#define SERDES_RX_CDR			6	/* CDR */
+-#define SERDES_RX_CDRBW			7	/* CDR BW */
+-
+-	/* SERDES RX control register */
+-#define SERDES_RX_CTRL_FORCE		0x80	/* rxpolarity_force */
+-#define SERDES_RX_CTRL_POLARITY		0x40	/* rxpolarity_value */
+-
+-	/* SERDES PLL registers */
+-#define SERDES_PLL_CTRL                 1	/* PLL control reg */
+-#define PLL_CTRL_FREQDET_EN             0x4000	/* bit 14 is FREQDET on */
+-
+-/* Power management threshold */
+-#define PCIE_L0THRESHOLDTIME_MASK       0xFF00	/* bits 0 - 7 */
+-#define PCIE_L1THRESHOLDTIME_MASK       0xFF00	/* bits 8 - 15 */
+-#define PCIE_L1THRESHOLDTIME_SHIFT      8	/* PCIE_L1THRESHOLDTIME_SHIFT */
+-#define PCIE_L1THRESHOLD_WARVAL         0x72	/* WAR value */
+-#define PCIE_ASPMTIMER_EXTEND		0x01000000	/* > rev7: enable extend ASPM timer */
+-
+-/* SPROM offsets */
+-#define SRSH_ASPM_OFFSET		4	/* word 4 */
+-#define SRSH_ASPM_ENB			0x18	/* bit 3, 4 */
+-#define SRSH_ASPM_L1_ENB		0x10	/* bit 4 */
+-#define SRSH_ASPM_L0s_ENB		0x8	/* bit 3 */
+-#define SRSH_PCIE_MISC_CONFIG		5	/* word 5 */
+-#define SRSH_L23READY_EXIT_NOPERST	0x8000	/* bit 15 */
+-#define SRSH_CLKREQ_OFFSET_REV5		20	/* word 20 for srom rev <= 5 */
+-#define SRSH_CLKREQ_OFFSET_REV8		52	/* word 52 for srom rev 8 */
+-#define SRSH_CLKREQ_ENB			0x0800	/* bit 11 */
+-#define SRSH_BD_OFFSET                  6	/* word 6 */
+-#define SRSH_AUTOINIT_OFFSET            18	/* auto initialization enable */
+-
+-/* Linkcontrol reg offset in PCIE Cap */
+-#define PCIE_CAP_LINKCTRL_OFFSET	16	/* linkctrl offset in pcie cap */
+-#define PCIE_CAP_LCREG_ASPML0s		0x01	/* ASPM L0s in linkctrl */
+-#define PCIE_CAP_LCREG_ASPML1		0x02	/* ASPM L1 in linkctrl */
+-#define PCIE_CLKREQ_ENAB		0x100	/* CLKREQ Enab in linkctrl */
+-
+-#define PCIE_ASPM_ENAB			3	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_L1_ENAB		2	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_L0s_ENAB		1	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_DISAB			0	/* ASPM L0s & L1 in linkctrl */
+-
+-/* Status reg PCIE_PLP_STATUSREG */
+-#define PCIE_PLP_POLARITYINV_STAT	0x10
+-#endif				/* _PCIE_CORE_H */
+diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h
+deleted file mode 100644
+index 374125d..0000000
+--- a/drivers/staging/brcm80211/include/proto/802.11.h
++++ /dev/null
+@@ -1,200 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _802_11_H_
+-#define _802_11_H_
+-
+-#include <linux/if_ether.h>
+-
+-#define DOT11_A3_HDR_LEN		24
+-#define DOT11_A4_HDR_LEN		30
+-#define DOT11_MAC_HDR_LEN		DOT11_A3_HDR_LEN
+-#define DOT11_ICV_AES_LEN		8
+-#define DOT11_QOS_LEN			2
+-
+-#define DOT11_IV_MAX_LEN		8
+-
+-#define DOT11_DEFAULT_RTS_LEN		2347
+-
+-#define DOT11_MIN_FRAG_LEN		256
+-#define DOT11_MAX_FRAG_LEN		2346
+-#define DOT11_DEFAULT_FRAG_LEN		2346
+-
+-#define DOT11_MIN_BEACON_PERIOD		1
+-#define DOT11_MAX_BEACON_PERIOD		0xFFFF
+-
+-#define DOT11_MIN_DTIM_PERIOD		1
+-#define DOT11_MAX_DTIM_PERIOD		0xFF
+-
+-#define DOT11_OUI_LEN			3
+-
+-#define	DOT11_RTS_LEN		16
+-#define	DOT11_CTS_LEN		10
+-#define	DOT11_ACK_LEN		10
+-
+-#define DOT11_BA_BITMAP_LEN		128
+-#define DOT11_BA_LEN		4
+-
+-#define WME_OUI			"\x00\x50\xf2"
+-#define WME_VER			1
+-#define WME_TYPE		2
+-#define WME_SUBTYPE_PARAM_IE	1
+-
+-#define AC_BE			0
+-#define AC_BK			1
+-#define AC_VI			2
+-#define AC_VO			3
+-#define AC_COUNT		4
+-
+-typedef u8 ac_bitmap_t;
+-
+-#define AC_BITMAP_ALL		0xf
+-#define AC_BITMAP_TST(ab, ac)	(((ab) & (1 << (ac))) != 0)
+-
+-struct edcf_acparam {
+-	u8 ACI;
+-	u8 ECW;
+-	u16 TXOP;
+-} __attribute__((packed));
+-typedef struct edcf_acparam edcf_acparam_t;
+-
+-struct wme_param_ie {
+-	u8 oui[3];
+-	u8 type;
+-	u8 subtype;
+-	u8 version;
+-	u8 qosinfo;
+-	u8 rsvd;
+-	edcf_acparam_t acparam[AC_COUNT];
+-} __attribute__((packed));
+-typedef struct wme_param_ie wme_param_ie_t;
+-#define WME_PARAM_IE_LEN            24
+-
+-#define EDCF_AIFSN_MIN               1
+-#define EDCF_AIFSN_MAX               15
+-#define EDCF_AIFSN_MASK              0x0f
+-#define EDCF_ACM_MASK                0x10
+-#define EDCF_ACI_MASK                0x60
+-#define EDCF_ACI_SHIFT               5
+-
+-#define EDCF_ECW2CW(exp)             ((1 << (exp)) - 1)
+-#define EDCF_ECWMIN_MASK             0x0f
+-#define EDCF_ECWMAX_MASK             0xf0
+-#define EDCF_ECWMAX_SHIFT            4
+-
+-#define EDCF_TXOP2USEC(txop)         ((txop) << 5)
+-
+-#define EDCF_AC_BE_ACI_STA           0x03
+-#define EDCF_AC_BE_ECW_STA           0xA4
+-#define EDCF_AC_BE_TXOP_STA          0x0000
+-#define EDCF_AC_BK_ACI_STA           0x27
+-#define EDCF_AC_BK_ECW_STA           0xA4
+-#define EDCF_AC_BK_TXOP_STA          0x0000
+-#define EDCF_AC_VI_ACI_STA           0x42
+-#define EDCF_AC_VI_ECW_STA           0x43
+-#define EDCF_AC_VI_TXOP_STA          0x005e
+-#define EDCF_AC_VO_ACI_STA           0x62
+-#define EDCF_AC_VO_ECW_STA           0x32
+-#define EDCF_AC_VO_TXOP_STA          0x002f
+-
+-#define EDCF_AC_VO_TXOP_AP           0x002f
+-
+-#define SEQNUM_SHIFT		4
+-#define SEQNUM_MAX		0x1000
+-#define FRAGNUM_MASK		0xF
+-
+-#define DOT11_MNG_RSN_ID			48
+-#define DOT11_MNG_WPA_ID			221
+-#define DOT11_MNG_VS_ID				221
+-
+-#define DOT11_BSSTYPE_INFRASTRUCTURE		0
+-#define DOT11_BSSTYPE_ANY			2
+-#define DOT11_SCANTYPE_ACTIVE			0
+-
+-#define PREN_PREAMBLE		24
+-#define PREN_MM_EXT		12
+-#define PREN_PREAMBLE_EXT	4
+-
+-#define RIFS_11N_TIME		2
+-
+-#define APHY_SLOT_TIME		9
+-#define APHY_SIFS_TIME		16
+-#define APHY_PREAMBLE_TIME	16
+-#define APHY_SIGNAL_TIME	4
+-#define APHY_SYMBOL_TIME	4
+-#define APHY_SERVICE_NBITS	16
+-#define APHY_TAIL_NBITS		6
+-#define	APHY_CWMIN		15
+-
+-#define BPHY_SLOT_TIME		20
+-#define BPHY_SIFS_TIME		10
+-#define BPHY_PLCP_TIME		192
+-#define BPHY_PLCP_SHORT_TIME	96
+-
+-#define DOT11_OFDM_SIGNAL_EXTENSION	6
+-
+-#define PHY_CWMAX		1023
+-
+-#define	DOT11_MAXNUMFRAGS	16
+-
+-typedef struct d11cnt {
+-	u32 txfrag;
+-	u32 txmulti;
+-	u32 txfail;
+-	u32 txretry;
+-	u32 txretrie;
+-	u32 rxdup;
+-	u32 txrts;
+-	u32 txnocts;
+-	u32 txnoack;
+-	u32 rxfrag;
+-	u32 rxmulti;
+-	u32 rxcrc;
+-	u32 txfrmsnt;
+-	u32 rxundec;
+-} d11cnt_t;
+-
+-#define MCSSET_LEN	16
+-
+-#define HT_CAP_IE_LEN		26
+-
+-#define HT_CAP_RX_STBC_NO		0x0
+-#define HT_CAP_RX_STBC_ONE_STREAM	0x1
+-
+-#define AMPDU_MAX_MPDU_DENSITY	IEEE80211_HT_MPDU_DENSITY_16
+-
+-#define AMPDU_DELIMITER_LEN	4
+-
+-#define DOT11N_TXBURST		0x0008
+-
+-#define WPA_VERSION		1
+-#define WPA_OUI			"\x00\x50\xF2"
+-
+-#define WFA_OUI			"\x00\x50\xF2"
+-#define WFA_OUI_LEN	3
+-
+-#define WFA_OUI_TYPE_WPA	1
+-
+-#define RSN_AKM_NONE		0
+-#define RSN_AKM_UNSPECIFIED	1
+-#define RSN_AKM_PSK		2
+-
+-#define DOT11_MAX_DEFAULT_KEYS	4
+-#define DOT11_WPA_KEY_RSC_LEN   8
+-
+-#define BRCM_OUI		"\x00\x10\x18"
+-
+-#endif				/* _802_11_H_ */
+diff --git a/drivers/staging/brcm80211/include/proto/bcmeth.h b/drivers/staging/brcm80211/include/proto/bcmeth.h
+deleted file mode 100644
+index e98ee65..0000000
+--- a/drivers/staging/brcm80211/include/proto/bcmeth.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _BCMETH_H_
+-#define _BCMETH_H_
+-
+-#define	BCMILCP_SUBTYPE_RATE		1
+-#define	BCMILCP_SUBTYPE_LINK		2
+-#define	BCMILCP_SUBTYPE_CSA		3
+-#define	BCMILCP_SUBTYPE_LARQ		4
+-#define BCMILCP_SUBTYPE_VENDOR		5
+-#define	BCMILCP_SUBTYPE_FLH		17
+-#define BCMILCP_SUBTYPE_VENDOR_LONG	32769
+-#define BCMILCP_SUBTYPE_CERT		32770
+-#define BCMILCP_SUBTYPE_SES		32771
+-#define BCMILCP_BCM_SUBTYPE_RESERVED		0
+-#define BCMILCP_BCM_SUBTYPE_EVENT		1
+-#define BCMILCP_BCM_SUBTYPE_SES			2
+-#define BCMILCP_BCM_SUBTYPE_DPT			4
+-#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH	8
+-#define BCMILCP_BCM_SUBTYPEHDR_VERSION		0
+-
+-typedef  struct bcmeth_hdr {
+-	u16 subtype;
+-	u16 length;
+-	u8 version;
+-	u8 oui[3];
+-	u16 usr_subtype;
+-} __attribute__((packed)) bcmeth_hdr_t;
+-
+-#endif				/* _BCMETH_H_ */
+diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h
+deleted file mode 100644
+index 1b60789..0000000
+--- a/drivers/staging/brcm80211/include/proto/bcmevent.h
++++ /dev/null
+@@ -1,207 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _BCMEVENT_H_
+-#define _BCMEVENT_H_
+-
+-#include <linux/if_ether.h>
+-
+-#define BCM_EVENT_MSG_VERSION		1
+-#define BCM_MSG_IFNAME_MAX		16
+-
+-#define WLC_EVENT_MSG_LINK		0x01
+-#define WLC_EVENT_MSG_FLUSHTXQ		0x02
+-#define WLC_EVENT_MSG_GROUP		0x04
+-
+-typedef struct {
+-	u16 version;
+-	u16 flags;
+-	u32 event_type;
+-	u32 status;
+-	u32 reason;
+-	u32 auth_type;
+-	u32 datalen;
+-	u8 addr[ETH_ALEN];
+-	char ifname[BCM_MSG_IFNAME_MAX];
+-} __attribute__((packed)) wl_event_msg_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct bcm_event {
+-	struct ethhdr eth;
+-	bcmeth_hdr_t		bcm_hdr;
+-	wl_event_msg_t		event;
+-} __attribute__((packed)) bcm_event_t;
+-#endif
+-#define BCM_MSG_LEN	(sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - \
+-	sizeof(struct ether_header))
+-
+-#define WLC_E_SET_SSID		0
+-#define WLC_E_JOIN		1
+-#define WLC_E_START		2
+-#define WLC_E_AUTH		3
+-#define WLC_E_AUTH_IND		4
+-#define WLC_E_DEAUTH		5
+-#define WLC_E_DEAUTH_IND	6
+-#define WLC_E_ASSOC		7
+-#define WLC_E_ASSOC_IND		8
+-#define WLC_E_REASSOC		9
+-#define WLC_E_REASSOC_IND	10
+-#define WLC_E_DISASSOC		11
+-#define WLC_E_DISASSOC_IND	12
+-#define WLC_E_QUIET_START	13
+-#define WLC_E_QUIET_END		14
+-#define WLC_E_BEACON_RX		15
+-#define WLC_E_LINK		16
+-#define WLC_E_MIC_ERROR		17
+-#define WLC_E_NDIS_LINK		18
+-#define WLC_E_ROAM		19
+-#define WLC_E_TXFAIL		20
+-#define WLC_E_PMKID_CACHE	21
+-#define WLC_E_RETROGRADE_TSF	22
+-#define WLC_E_PRUNE		23
+-#define WLC_E_AUTOAUTH		24
+-#define WLC_E_EAPOL_MSG		25
+-#define WLC_E_SCAN_COMPLETE	26
+-#define WLC_E_ADDTS_IND		27
+-#define WLC_E_DELTS_IND		28
+-#define WLC_E_BCNSENT_IND	29
+-#define WLC_E_BCNRX_MSG		30
+-#define WLC_E_BCNLOST_MSG	31
+-#define WLC_E_ROAM_PREP		32
+-#define WLC_E_PFN_NET_FOUND	33
+-#define WLC_E_PFN_NET_LOST	34
+-#define WLC_E_RESET_COMPLETE	35
+-#define WLC_E_JOIN_START	36
+-#define WLC_E_ROAM_START	37
+-#define WLC_E_ASSOC_START	38
+-#define WLC_E_IBSS_ASSOC	39
+-#define WLC_E_RADIO		40
+-#define WLC_E_PSM_WATCHDOG	41
+-#define WLC_E_PROBREQ_MSG       44
+-#define WLC_E_SCAN_CONFIRM_IND  45
+-#define WLC_E_PSK_SUP		46
+-#define WLC_E_COUNTRY_CODE_CHANGED 47
+-#define	WLC_E_EXCEEDED_MEDIUM_TIME 48
+-#define WLC_E_ICV_ERROR		49
+-#define WLC_E_UNICAST_DECODE_ERROR 50
+-#define WLC_E_MULTICAST_DECODE_ERROR 51
+-#define WLC_E_TRACE		52
+-#define WLC_E_IF		54
+-#define WLC_E_RSSI		56
+-#define WLC_E_PFN_SCAN_COMPLETE	57
+-#define WLC_E_EXTLOG_MSG	58
+-#define WLC_E_ACTION_FRAME      59
+-#define WLC_E_ACTION_FRAME_COMPLETE 60
+-#define WLC_E_PRE_ASSOC_IND	61
+-#define WLC_E_PRE_REASSOC_IND	62
+-#define WLC_E_CHANNEL_ADOPTED	63
+-#define WLC_E_AP_STARTED	64
+-#define WLC_E_DFS_AP_STOP	65
+-#define WLC_E_DFS_AP_RESUME	66
+-#define WLC_E_RESERVED1		67
+-#define WLC_E_RESERVED2		68
+-#define WLC_E_ESCAN_RESULT 	69
+-#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 	70
+-#define WLC_E_DCS_REQUEST 73
+-
+-#define WLC_E_FIFO_CREDIT_MAP	74
+-
+-#define WLC_E_LAST		75
+-
+-typedef struct {
+-	uint event;
+-	const char *name;
+-} bcmevent_name_t;
+-
+-extern const bcmevent_name_t bcmevent_names[];
+-extern const int bcmevent_names_size;
+-
+-#define WLC_E_STATUS_SUCCESS		0
+-#define WLC_E_STATUS_FAIL		1
+-#define WLC_E_STATUS_TIMEOUT		2
+-#define WLC_E_STATUS_NO_NETWORKS	3
+-#define WLC_E_STATUS_ABORT		4
+-#define WLC_E_STATUS_NO_ACK		5
+-#define WLC_E_STATUS_UNSOLICITED	6
+-#define WLC_E_STATUS_ATTEMPT		7
+-#define WLC_E_STATUS_PARTIAL		8
+-#define WLC_E_STATUS_NEWSCAN		9
+-#define WLC_E_STATUS_NEWASSOC		10
+-#define WLC_E_STATUS_11HQUIET		11
+-#define WLC_E_STATUS_SUPPRESS		12
+-#define WLC_E_STATUS_NOCHANS		13
+-#define WLC_E_STATUS_CS_ABORT		15
+-#define WLC_E_STATUS_ERROR		16
+-
+-#define WLC_E_REASON_INITIAL_ASSOC	0
+-#define WLC_E_REASON_LOW_RSSI		1
+-#define WLC_E_REASON_DEAUTH		2
+-#define WLC_E_REASON_DISASSOC		3
+-#define WLC_E_REASON_BCNS_LOST		4
+-#define WLC_E_REASON_MINTXRATE		9
+-#define WLC_E_REASON_TXFAIL		10
+-
+-#define WLC_E_REASON_FAST_ROAM_FAILED	5
+-#define WLC_E_REASON_DIRECTED_ROAM	6
+-#define WLC_E_REASON_TSPEC_REJECTED	7
+-#define WLC_E_REASON_BETTER_AP		8
+-
+-#define WLC_E_PRUNE_ENCR_MISMATCH	1
+-#define WLC_E_PRUNE_BCAST_BSSID		2
+-#define WLC_E_PRUNE_MAC_DENY		3
+-#define WLC_E_PRUNE_MAC_NA		4
+-#define WLC_E_PRUNE_REG_PASSV		5
+-#define WLC_E_PRUNE_SPCT_MGMT		6
+-#define WLC_E_PRUNE_RADAR		7
+-#define WLC_E_RSN_MISMATCH		8
+-#define WLC_E_PRUNE_NO_COMMON_RATES	9
+-#define WLC_E_PRUNE_BASIC_RATES		10
+-#define WLC_E_PRUNE_CIPHER_NA		12
+-#define WLC_E_PRUNE_KNOWN_STA		13
+-#define WLC_E_PRUNE_WDS_PEER		15
+-#define WLC_E_PRUNE_QBSS_LOAD		16
+-#define WLC_E_PRUNE_HOME_AP		17
+-
+-#define WLC_E_SUP_OTHER			0
+-#define WLC_E_SUP_DECRYPT_KEY_DATA	1
+-#define WLC_E_SUP_BAD_UCAST_WEP128	2
+-#define WLC_E_SUP_BAD_UCAST_WEP40	3
+-#define WLC_E_SUP_UNSUP_KEY_LEN		4
+-#define WLC_E_SUP_PW_KEY_CIPHER		5
+-#define WLC_E_SUP_MSG3_TOO_MANY_IE	6
+-#define WLC_E_SUP_MSG3_IE_MISMATCH	7
+-#define WLC_E_SUP_NO_INSTALL_FLAG	8
+-#define WLC_E_SUP_MSG3_NO_GTK		9
+-#define WLC_E_SUP_GRP_KEY_CIPHER	10
+-#define WLC_E_SUP_GRP_MSG1_NO_GTK	11
+-#define WLC_E_SUP_GTK_DECRYPT_FAIL	12
+-#define WLC_E_SUP_SEND_FAIL		13
+-#define WLC_E_SUP_DEAUTH		14
+-
+-#define WLC_E_IF_ADD		1
+-#define WLC_E_IF_DEL		2
+-#define WLC_E_IF_CHANGE		3
+-
+-#define WLC_E_IF_ROLE_STA		0
+-#define WLC_E_IF_ROLE_AP		1
+-#define WLC_E_IF_ROLE_WDS		2
+-
+-#define WLC_E_LINK_BCN_LOSS	1
+-#define WLC_E_LINK_DISASSOC	2
+-#define WLC_E_LINK_ASSOC_REC	3
+-#define WLC_E_LINK_BSSCFG_DIS	4
+-
+-#endif				/* _BCMEVENT_H_ */
+diff --git a/drivers/staging/brcm80211/include/sbchipc.h b/drivers/staging/brcm80211/include/sbchipc.h
+deleted file mode 100644
+index 8c01c63..0000000
+--- a/drivers/staging/brcm80211/include/sbchipc.h
++++ /dev/null
+@@ -1,1588 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBCHIPC_H
+-#define	_SBCHIPC_H
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif				/* PAD */
+-
+-typedef volatile struct {
+-	u32 chipid;		/* 0x0 */
+-	u32 capabilities;
+-	u32 corecontrol;	/* corerev >= 1 */
+-	u32 bist;
+-
+-	/* OTP */
+-	u32 otpstatus;	/* 0x10, corerev >= 10 */
+-	u32 otpcontrol;
+-	u32 otpprog;
+-	u32 otplayout;	/* corerev >= 23 */
+-
+-	/* Interrupt control */
+-	u32 intstatus;	/* 0x20 */
+-	u32 intmask;
+-
+-	/* Chip specific regs */
+-	u32 chipcontrol;	/* 0x28, rev >= 11 */
+-	u32 chipstatus;	/* 0x2c, rev >= 11 */
+-
+-	/* Jtag Master */
+-	u32 jtagcmd;		/* 0x30, rev >= 10 */
+-	u32 jtagir;
+-	u32 jtagdr;
+-	u32 jtagctrl;
+-
+-	/* serial flash interface registers */
+-	u32 flashcontrol;	/* 0x40 */
+-	u32 flashaddress;
+-	u32 flashdata;
+-	u32 PAD[1];
+-
+-	/* Silicon backplane configuration broadcast control */
+-	u32 broadcastaddress;	/* 0x50 */
+-	u32 broadcastdata;
+-
+-	/* gpio - cleared only by power-on-reset */
+-	u32 gpiopullup;	/* 0x58, corerev >= 20 */
+-	u32 gpiopulldown;	/* 0x5c, corerev >= 20 */
+-	u32 gpioin;		/* 0x60 */
+-	u32 gpioout;		/* 0x64 */
+-	u32 gpioouten;	/* 0x68 */
+-	u32 gpiocontrol;	/* 0x6C */
+-	u32 gpiointpolarity;	/* 0x70 */
+-	u32 gpiointmask;	/* 0x74 */
+-
+-	/* GPIO events corerev >= 11 */
+-	u32 gpioevent;
+-	u32 gpioeventintmask;
+-
+-	/* Watchdog timer */
+-	u32 watchdog;	/* 0x80 */
+-
+-	/* GPIO events corerev >= 11 */
+-	u32 gpioeventintpolarity;
+-
+-	/* GPIO based LED powersave registers corerev >= 16 */
+-	u32 gpiotimerval;	/* 0x88 */
+-	u32 gpiotimeroutmask;
+-
+-	/* clock control */
+-	u32 clockcontrol_n;	/* 0x90 */
+-	u32 clockcontrol_sb;	/* aka m0 */
+-	u32 clockcontrol_pci;	/* aka m1 */
+-	u32 clockcontrol_m2;	/* mii/uart/mipsref */
+-	u32 clockcontrol_m3;	/* cpu */
+-	u32 clkdiv;		/* corerev >= 3 */
+-	u32 gpiodebugsel;	/* corerev >= 28 */
+-	u32 capabilities_ext;	/* 0xac  */
+-
+-	/* pll delay registers (corerev >= 4) */
+-	u32 pll_on_delay;	/* 0xb0 */
+-	u32 fref_sel_delay;
+-	u32 slow_clk_ctl;	/* 5 < corerev < 10 */
+-	u32 PAD;
+-
+-	/* Instaclock registers (corerev >= 10) */
+-	u32 system_clk_ctl;	/* 0xc0 */
+-	u32 clkstatestretch;
+-	u32 PAD[2];
+-
+-	/* Indirect backplane access (corerev >= 22) */
+-	u32 bp_addrlow;	/* 0xd0 */
+-	u32 bp_addrhigh;
+-	u32 bp_data;
+-	u32 PAD;
+-	u32 bp_indaccess;
+-	u32 PAD[3];
+-
+-	/* More clock dividers (corerev >= 32) */
+-	u32 clkdiv2;
+-	u32 PAD[2];
+-
+-	/* In AI chips, pointer to erom */
+-	u32 eromptr;		/* 0xfc */
+-
+-	/* ExtBus control registers (corerev >= 3) */
+-	u32 pcmcia_config;	/* 0x100 */
+-	u32 pcmcia_memwait;
+-	u32 pcmcia_attrwait;
+-	u32 pcmcia_iowait;
+-	u32 ide_config;
+-	u32 ide_memwait;
+-	u32 ide_attrwait;
+-	u32 ide_iowait;
+-	u32 prog_config;
+-	u32 prog_waitcount;
+-	u32 flash_config;
+-	u32 flash_waitcount;
+-	u32 SECI_config;	/* 0x130 SECI configuration */
+-	u32 PAD[3];
+-
+-	/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
+-	u32 eci_output;	/* 0x140 */
+-	u32 eci_control;
+-	u32 eci_inputlo;
+-	u32 eci_inputmi;
+-	u32 eci_inputhi;
+-	u32 eci_inputintpolaritylo;
+-	u32 eci_inputintpolaritymi;
+-	u32 eci_inputintpolarityhi;
+-	u32 eci_intmasklo;
+-	u32 eci_intmaskmi;
+-	u32 eci_intmaskhi;
+-	u32 eci_eventlo;
+-	u32 eci_eventmi;
+-	u32 eci_eventhi;
+-	u32 eci_eventmasklo;
+-	u32 eci_eventmaskmi;
+-	u32 eci_eventmaskhi;
+-	u32 PAD[3];
+-
+-	/* SROM interface (corerev >= 32) */
+-	u32 sromcontrol;	/* 0x190 */
+-	u32 sromaddress;
+-	u32 sromdata;
+-	u32 PAD[17];
+-
+-	/* Clock control and hardware workarounds (corerev >= 20) */
+-	u32 clk_ctl_st;	/* 0x1e0 */
+-	u32 hw_war;
+-	u32 PAD[70];
+-
+-	/* UARTs */
+-	u8 uart0data;	/* 0x300 */
+-	u8 uart0imr;
+-	u8 uart0fcr;
+-	u8 uart0lcr;
+-	u8 uart0mcr;
+-	u8 uart0lsr;
+-	u8 uart0msr;
+-	u8 uart0scratch;
+-	u8 PAD[248];		/* corerev >= 1 */
+-
+-	u8 uart1data;	/* 0x400 */
+-	u8 uart1imr;
+-	u8 uart1fcr;
+-	u8 uart1lcr;
+-	u8 uart1mcr;
+-	u8 uart1lsr;
+-	u8 uart1msr;
+-	u8 uart1scratch;
+-	u32 PAD[126];
+-
+-	/* PMU registers (corerev >= 20) */
+-	u32 pmucontrol;	/* 0x600 */
+-	u32 pmucapabilities;
+-	u32 pmustatus;
+-	u32 res_state;
+-	u32 res_pending;
+-	u32 pmutimer;
+-	u32 min_res_mask;
+-	u32 max_res_mask;
+-	u32 res_table_sel;
+-	u32 res_dep_mask;
+-	u32 res_updn_timer;
+-	u32 res_timer;
+-	u32 clkstretch;
+-	u32 pmuwatchdog;
+-	u32 gpiosel;		/* 0x638, rev >= 1 */
+-	u32 gpioenable;	/* 0x63c, rev >= 1 */
+-	u32 res_req_timer_sel;
+-	u32 res_req_timer;
+-	u32 res_req_mask;
+-	u32 PAD;
+-	u32 chipcontrol_addr;	/* 0x650 */
+-	u32 chipcontrol_data;	/* 0x654 */
+-	u32 regcontrol_addr;
+-	u32 regcontrol_data;
+-	u32 pllcontrol_addr;
+-	u32 pllcontrol_data;
+-	u32 pmustrapopt;	/* 0x668, corerev >= 28 */
+-	u32 pmu_xtalfreq;	/* 0x66C, pmurev >= 10 */
+-	u32 PAD[100];
+-	u16 sromotp[768];
+-} chipcregs_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
+-/* Selective swapped defines for those registers we need in
+- * big-endian code.
+- */
+-#define	CC_CHIPID		4
+-#define	CC_CAPABILITIES		0
+-#define	CC_CHIPST		0x28
+-#define	CC_EROMPTR		0xf8
+-
+-#else				/* !__BIG_ENDIAN || !BCMHND74K */
+-
+-#define	CC_CHIPID		0
+-#define	CC_CAPABILITIES		4
+-#define	CC_CHIPST		0x2c
+-#define	CC_EROMPTR		0xfc
+-
+-#endif				/* __BIG_ENDIAN && BCMHND74K */
+-
+-#define CC_OTPST		0x10
+-#define	CC_JTAGCMD		0x30
+-#define	CC_JTAGIR		0x34
+-#define	CC_JTAGDR		0x38
+-#define	CC_JTAGCTRL		0x3c
+-#define	CC_GPIOPU		0x58
+-#define	CC_GPIOPD		0x5c
+-#define	CC_GPIOIN		0x60
+-#define	CC_GPIOOUT		0x64
+-#define	CC_GPIOOUTEN		0x68
+-#define	CC_GPIOCTRL		0x6c
+-#define	CC_GPIOPOL		0x70
+-#define	CC_GPIOINTM		0x74
+-#define	CC_WATCHDOG		0x80
+-#define	CC_CLKC_N		0x90
+-#define	CC_CLKC_M0		0x94
+-#define	CC_CLKC_M1		0x98
+-#define	CC_CLKC_M2		0x9c
+-#define	CC_CLKC_M3		0xa0
+-#define	CC_CLKDIV		0xa4
+-#define	CC_SYS_CLK_CTL		0xc0
+-#define	CC_CLK_CTL_ST		SI_CLK_CTL_ST
+-#define	PMU_CTL			0x600
+-#define	PMU_CAP			0x604
+-#define	PMU_ST			0x608
+-#define PMU_RES_STATE		0x60c
+-#define PMU_TIMER		0x614
+-#define	PMU_MIN_RES_MASK	0x618
+-#define	PMU_MAX_RES_MASK	0x61c
+-#define CC_CHIPCTL_ADDR         0x650
+-#define CC_CHIPCTL_DATA         0x654
+-#define PMU_REG_CONTROL_ADDR	0x658
+-#define PMU_REG_CONTROL_DATA	0x65C
+-#define PMU_PLL_CONTROL_ADDR 	0x660
+-#define PMU_PLL_CONTROL_DATA 	0x664
+-#define	CC_SROM_OTP		0x800	/* SROM/OTP address space */
+-
+-/* chipid */
+-#define	CID_ID_MASK		0x0000ffff	/* Chip Id mask */
+-#define	CID_REV_MASK		0x000f0000	/* Chip Revision mask */
+-#define	CID_REV_SHIFT		16	/* Chip Revision shift */
+-#define	CID_PKG_MASK		0x00f00000	/* Package Option mask */
+-#define	CID_PKG_SHIFT		20	/* Package Option shift */
+-#define	CID_CC_MASK		0x0f000000	/* CoreCount (corerev >= 4) */
+-#define CID_CC_SHIFT		24
+-#define	CID_TYPE_MASK		0xf0000000	/* Chip Type */
+-#define CID_TYPE_SHIFT		28
+-
+-/* capabilities */
+-#define	CC_CAP_UARTS_MASK	0x00000003	/* Number of UARTs */
+-#define CC_CAP_MIPSEB		0x00000004	/* MIPS is in big-endian mode */
+-#define CC_CAP_UCLKSEL		0x00000018	/* UARTs clock select */
+-#define CC_CAP_UINTCLK		0x00000008	/* UARTs are driven by internal divided clock */
+-#define CC_CAP_UARTGPIO		0x00000020	/* UARTs own GPIOs 15:12 */
+-#define CC_CAP_EXTBUS_MASK	0x000000c0	/* External bus mask */
+-#define CC_CAP_EXTBUS_NONE	0x00000000	/* No ExtBus present */
+-#define CC_CAP_EXTBUS_FULL	0x00000040	/* ExtBus: PCMCIA, IDE & Prog */
+-#define CC_CAP_EXTBUS_PROG	0x00000080	/* ExtBus: ProgIf only */
+-#define	CC_CAP_FLASH_MASK	0x00000700	/* Type of flash */
+-#define	CC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
+-#define CC_CAP_PWR_CTL		0x00040000	/* Power control */
+-#define CC_CAP_OTPSIZE		0x00380000	/* OTP Size (0 = none) */
+-#define CC_CAP_OTPSIZE_SHIFT	19	/* OTP Size shift */
+-#define CC_CAP_OTPSIZE_BASE	5	/* OTP Size base */
+-#define CC_CAP_JTAGP		0x00400000	/* JTAG Master Present */
+-#define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
+-#define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
+-#define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
+-#define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
+-#define	CC_CAP_NFLASH		0x80000000	/* Nand flash present, rev >= 35 */
+-
+-#define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
+-#define	CC_CAP2_GSIO		0x00000002	/* GSIO (spi/i2c) present, rev >= 37 */
+-
+-/* PLL type */
+-#define PLL_NONE		0x00000000
+-#define PLL_TYPE1		0x00010000	/* 48MHz base, 3 dividers */
+-#define PLL_TYPE2		0x00020000	/* 48MHz, 4 dividers */
+-#define PLL_TYPE3		0x00030000	/* 25MHz, 2 dividers */
+-#define PLL_TYPE4		0x00008000	/* 48MHz, 4 dividers */
+-#define PLL_TYPE5		0x00018000	/* 25MHz, 4 dividers */
+-#define PLL_TYPE6		0x00028000	/* 100/200 or 120/240 only */
+-#define PLL_TYPE7		0x00038000	/* 25MHz, 4 dividers */
+-
+-/* ILP clock */
+-#define	ILP_CLOCK		32000
+-
+-/* ALP clock on pre-PMU chips */
+-#define	ALP_CLOCK		20000000
+-
+-/* HT clock */
+-#define	HT_CLOCK		80000000
+-
+-/* corecontrol */
+-#define CC_UARTCLKO		0x00000001	/* Drive UART with internal clock */
+-#define	CC_SE			0x00000002	/* sync clk out enable (corerev >= 3) */
+-#define CC_UARTCLKEN		0x00000008	/* enable UART Clock (corerev > = 21 */
+-
+-/* chipcontrol */
+-#define CHIPCTRL_4321A0_DEFAULT	0x3a4
+-#define CHIPCTRL_4321A1_DEFAULT	0x0a4
+-#define CHIPCTRL_4321_PLL_DOWN	0x800000	/* serdes PLL down override */
+-
+-/* Fields in the otpstatus register in rev >= 21 */
+-#define OTPS_OL_MASK		0x000000ff
+-#define OTPS_OL_MFG		0x00000001	/* manuf row is locked */
+-#define OTPS_OL_OR1		0x00000002	/* otp redundancy row 1 is locked */
+-#define OTPS_OL_OR2		0x00000004	/* otp redundancy row 2 is locked */
+-#define OTPS_OL_GU		0x00000008	/* general use region is locked */
+-#define OTPS_GUP_MASK		0x00000f00
+-#define OTPS_GUP_SHIFT		8
+-#define OTPS_GUP_HW		0x00000100	/* h/w subregion is programmed */
+-#define OTPS_GUP_SW		0x00000200	/* s/w subregion is programmed */
+-#define OTPS_GUP_CI		0x00000400	/* chipid/pkgopt subregion is programmed */
+-#define OTPS_GUP_FUSE		0x00000800	/* fuse subregion is programmed */
+-#define OTPS_READY		0x00001000
+-#define OTPS_RV(x)		(1 << (16 + (x)))	/* redundancy entry valid */
+-#define OTPS_RV_MASK		0x0fff0000
+-
+-/* Fields in the otpcontrol register in rev >= 21 */
+-#define OTPC_PROGSEL		0x00000001
+-#define OTPC_PCOUNT_MASK	0x0000000e
+-#define OTPC_PCOUNT_SHIFT	1
+-#define OTPC_VSEL_MASK		0x000000f0
+-#define OTPC_VSEL_SHIFT		4
+-#define OTPC_TMM_MASK		0x00000700
+-#define OTPC_TMM_SHIFT		8
+-#define OTPC_ODM		0x00000800
+-#define OTPC_PROGEN		0x80000000
+-
+-/* Fields in otpprog in rev >= 21 and HND OTP */
+-#define OTPP_COL_MASK		0x000000ff
+-#define OTPP_COL_SHIFT		0
+-#define OTPP_ROW_MASK		0x0000ff00
+-#define OTPP_ROW_SHIFT		8
+-#define OTPP_OC_MASK		0x0f000000
+-#define OTPP_OC_SHIFT		24
+-#define OTPP_READERR		0x10000000
+-#define OTPP_VALUE_MASK		0x20000000
+-#define OTPP_VALUE_SHIFT	29
+-#define OTPP_START_BUSY		0x80000000
+-#define	OTPP_READ		0x40000000	/* HND OTP */
+-
+-/* otplayout reg corerev >= 36 */
+-#define OTP_CISFORMAT_NEW	0x80000000
+-
+-/* Opcodes for OTPP_OC field */
+-#define OTPPOC_READ		0
+-#define OTPPOC_BIT_PROG		1
+-#define OTPPOC_VERIFY		3
+-#define OTPPOC_INIT		4
+-#define OTPPOC_SET		5
+-#define OTPPOC_RESET		6
+-#define OTPPOC_OCST		7
+-#define OTPPOC_ROW_LOCK		8
+-#define OTPPOC_PRESCN_TEST	9
+-
+-/* Jtagm characteristics that appeared at a given corerev */
+-#define	JTAGM_CREV_OLD		10	/* Old command set, 16bit max IR */
+-#define	JTAGM_CREV_IRP		22	/* Able to do pause-ir */
+-#define	JTAGM_CREV_RTI		28	/* Able to do return-to-idle */
+-
+-/* jtagcmd */
+-#define JCMD_START		0x80000000
+-#define JCMD_BUSY		0x80000000
+-#define JCMD_STATE_MASK		0x60000000
+-#define JCMD_STATE_TLR		0x00000000	/* Test-logic-reset */
+-#define JCMD_STATE_PIR		0x20000000	/* Pause IR */
+-#define JCMD_STATE_PDR		0x40000000	/* Pause DR */
+-#define JCMD_STATE_RTI		0x60000000	/* Run-test-idle */
+-#define JCMD0_ACC_MASK		0x0000f000
+-#define JCMD0_ACC_IRDR		0x00000000
+-#define JCMD0_ACC_DR		0x00001000
+-#define JCMD0_ACC_IR		0x00002000
+-#define JCMD0_ACC_RESET		0x00003000
+-#define JCMD0_ACC_IRPDR		0x00004000
+-#define JCMD0_ACC_PDR		0x00005000
+-#define JCMD0_IRW_MASK		0x00000f00
+-#define JCMD_ACC_MASK		0x000f0000	/* Changes for corerev 11 */
+-#define JCMD_ACC_IRDR		0x00000000
+-#define JCMD_ACC_DR		0x00010000
+-#define JCMD_ACC_IR		0x00020000
+-#define JCMD_ACC_RESET		0x00030000
+-#define JCMD_ACC_IRPDR		0x00040000
+-#define JCMD_ACC_PDR		0x00050000
+-#define JCMD_ACC_PIR		0x00060000
+-#define JCMD_ACC_IRDR_I		0x00070000	/* rev 28: return to run-test-idle */
+-#define JCMD_ACC_DR_I		0x00080000	/* rev 28: return to run-test-idle */
+-#define JCMD_IRW_MASK		0x00001f00
+-#define JCMD_IRW_SHIFT		8
+-#define JCMD_DRW_MASK		0x0000003f
+-
+-/* jtagctrl */
+-#define JCTRL_FORCE_CLK		4	/* Force clock */
+-#define JCTRL_EXT_EN		2	/* Enable external targets */
+-#define JCTRL_EN		1	/* Enable Jtag master */
+-
+-/* Fields in clkdiv */
+-#define	CLKD_SFLASH		0x0f000000
+-#define	CLKD_SFLASH_SHIFT	24
+-#define	CLKD_OTP		0x000f0000
+-#define	CLKD_OTP_SHIFT		16
+-#define	CLKD_JTAG		0x00000f00
+-#define	CLKD_JTAG_SHIFT		8
+-#define	CLKD_UART		0x000000ff
+-
+-#define	CLKD2_SROM		0x00000003
+-
+-/* intstatus/intmask */
+-#define	CI_GPIO			0x00000001	/* gpio intr */
+-#define	CI_EI			0x00000002	/* extif intr (corerev >= 3) */
+-#define	CI_TEMP			0x00000004	/* temp. ctrl intr (corerev >= 15) */
+-#define	CI_SIRQ			0x00000008	/* serial IRQ intr (corerev >= 15) */
+-#define	CI_PMU			0x00000020	/* pmu intr (corerev >= 21) */
+-#define	CI_UART			0x00000040	/* uart intr (corerev >= 21) */
+-#define	CI_WDRESET		0x80000000	/* watchdog reset occurred */
+-
+-/* slow_clk_ctl */
+-#define SCC_SS_MASK		0x00000007	/* slow clock source mask */
+-#define	SCC_SS_LPO		0x00000000	/* source of slow clock is LPO */
+-#define	SCC_SS_XTAL		0x00000001	/* source of slow clock is crystal */
+-#define	SCC_SS_PCI		0x00000002	/* source of slow clock is PCI */
+-#define SCC_LF			0x00000200	/* LPOFreqSel, 1: 160Khz, 0: 32KHz */
+-#define SCC_LP			0x00000400	/* LPOPowerDown, 1: LPO is disabled,
+-						 * 0: LPO is enabled
+-						 */
+-#define SCC_FS			0x00000800	/* ForceSlowClk, 1: sb/cores running on slow clock,
+-						 * 0: power logic control
+-						 */
+-#define SCC_IP			0x00001000	/* IgnorePllOffReq, 1/0: power logic ignores/honors
+-						 * PLL clock disable requests from core
+-						 */
+-#define SCC_XC			0x00002000	/* XtalControlEn, 1/0: power logic does/doesn't
+-						 * disable crystal when appropriate
+-						 */
+-#define SCC_XP			0x00004000	/* XtalPU (RO), 1/0: crystal running/disabled */
+-#define SCC_CD_MASK		0xffff0000	/* ClockDivider (SlowClk = 1/(4+divisor)) */
+-#define SCC_CD_SHIFT		16
+-
+-/* system_clk_ctl */
+-#define	SYCC_IE			0x00000001	/* ILPen: Enable Idle Low Power */
+-#define	SYCC_AE			0x00000002	/* ALPen: Enable Active Low Power */
+-#define	SYCC_FP			0x00000004	/* ForcePLLOn */
+-#define	SYCC_AR			0x00000008	/* Force ALP (or HT if ALPen is not set */
+-#define	SYCC_HR			0x00000010	/* Force HT */
+-#define SYCC_CD_MASK		0xffff0000	/* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
+-#define SYCC_CD_SHIFT		16
+-
+-/* Indirect backplane access */
+-#define	BPIA_BYTEEN		0x0000000f
+-#define	BPIA_SZ1		0x00000001
+-#define	BPIA_SZ2		0x00000003
+-#define	BPIA_SZ4		0x00000007
+-#define	BPIA_SZ8		0x0000000f
+-#define	BPIA_WRITE		0x00000100
+-#define	BPIA_START		0x00000200
+-#define	BPIA_BUSY		0x00000200
+-#define	BPIA_ERROR		0x00000400
+-
+-/* pcmcia/prog/flash_config */
+-#define	CF_EN			0x00000001	/* enable */
+-#define	CF_EM_MASK		0x0000000e	/* mode */
+-#define	CF_EM_SHIFT		1
+-#define	CF_EM_FLASH		0	/* flash/asynchronous mode */
+-#define	CF_EM_SYNC		2	/* synchronous mode */
+-#define	CF_EM_PCMCIA		4	/* pcmcia mode */
+-#define	CF_DS			0x00000010	/* destsize:  0=8bit, 1=16bit */
+-#define	CF_BS			0x00000020	/* byteswap */
+-#define	CF_CD_MASK		0x000000c0	/* clock divider */
+-#define	CF_CD_SHIFT		6
+-#define	CF_CD_DIV2		0x00000000	/* backplane/2 */
+-#define	CF_CD_DIV3		0x00000040	/* backplane/3 */
+-#define	CF_CD_DIV4		0x00000080	/* backplane/4 */
+-#define	CF_CE			0x00000100	/* clock enable */
+-#define	CF_SB			0x00000200	/* size/bytestrobe (synch only) */
+-
+-/* pcmcia_memwait */
+-#define	PM_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PM_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PM_W1_SHIFT		8
+-#define	PM_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PM_W2_SHIFT		16
+-#define	PM_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PM_W3_SHIFT		24
+-
+-/* pcmcia_attrwait */
+-#define	PA_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PA_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PA_W1_SHIFT		8
+-#define	PA_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PA_W2_SHIFT		16
+-#define	PA_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PA_W3_SHIFT		24
+-
+-/* pcmcia_iowait */
+-#define	PI_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PI_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PI_W1_SHIFT		8
+-#define	PI_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PI_W2_SHIFT		16
+-#define	PI_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PI_W3_SHIFT		24
+-
+-/* prog_waitcount */
+-#define	PW_W0_MASK		0x0000001f	/* waitcount0 */
+-#define	PW_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PW_W1_SHIFT		8
+-#define	PW_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PW_W2_SHIFT		16
+-#define	PW_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PW_W3_SHIFT		24
+-
+-#define PW_W0       		0x0000000c
+-#define PW_W1       		0x00000a00
+-#define PW_W2       		0x00020000
+-#define PW_W3       		0x01000000
+-
+-/* flash_waitcount */
+-#define	FW_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	FW_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	FW_W1_SHIFT		8
+-#define	FW_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	FW_W2_SHIFT		16
+-#define	FW_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	FW_W3_SHIFT		24
+-
+-/* When Srom support present, fields in sromcontrol */
+-#define	SRC_START		0x80000000
+-#define	SRC_BUSY		0x80000000
+-#define	SRC_OPCODE		0x60000000
+-#define	SRC_OP_READ		0x00000000
+-#define	SRC_OP_WRITE		0x20000000
+-#define	SRC_OP_WRDIS		0x40000000
+-#define	SRC_OP_WREN		0x60000000
+-#define	SRC_OTPSEL		0x00000010
+-#define	SRC_LOCK		0x00000008
+-#define	SRC_SIZE_MASK		0x00000006
+-#define	SRC_SIZE_1K		0x00000000
+-#define	SRC_SIZE_4K		0x00000002
+-#define	SRC_SIZE_16K		0x00000004
+-#define	SRC_SIZE_SHIFT		1
+-#define	SRC_PRESENT		0x00000001
+-
+-/* Fields in pmucontrol */
+-#define	PCTL_ILP_DIV_MASK	0xffff0000
+-#define	PCTL_ILP_DIV_SHIFT	16
+-#define PCTL_PLL_PLLCTL_UPD	0x00000400	/* rev 2 */
+-#define PCTL_NOILP_ON_WAIT	0x00000200	/* rev 1 */
+-#define	PCTL_HT_REQ_EN		0x00000100
+-#define	PCTL_ALP_REQ_EN		0x00000080
+-#define	PCTL_XTALFREQ_MASK	0x0000007c
+-#define	PCTL_XTALFREQ_SHIFT	2
+-#define	PCTL_ILP_DIV_EN		0x00000002
+-#define	PCTL_LPO_SEL		0x00000001
+-
+-/* Fields in clkstretch */
+-#define CSTRETCH_HT		0xffff0000
+-#define CSTRETCH_ALP		0x0000ffff
+-
+-/* gpiotimerval */
+-#define GPIO_ONTIME_SHIFT	16
+-
+-/* clockcontrol_n */
+-#define	CN_N1_MASK		0x3f	/* n1 control */
+-#define	CN_N2_MASK		0x3f00	/* n2 control */
+-#define	CN_N2_SHIFT		8
+-#define	CN_PLLC_MASK		0xf0000	/* pll control */
+-#define	CN_PLLC_SHIFT		16
+-
+-/* clockcontrol_sb/pci/uart */
+-#define	CC_M1_MASK		0x3f	/* m1 control */
+-#define	CC_M2_MASK		0x3f00	/* m2 control */
+-#define	CC_M2_SHIFT		8
+-#define	CC_M3_MASK		0x3f0000	/* m3 control */
+-#define	CC_M3_SHIFT		16
+-#define	CC_MC_MASK		0x1f000000	/* mux control */
+-#define	CC_MC_SHIFT		24
+-
+-/* N3M Clock control magic field values */
+-#define	CC_F6_2			0x02	/* A factor of 2 in */
+-#define	CC_F6_3			0x03	/* 6-bit fields like */
+-#define	CC_F6_4			0x05	/* N1, M1 or M3 */
+-#define	CC_F6_5			0x09
+-#define	CC_F6_6			0x11
+-#define	CC_F6_7			0x21
+-
+-#define	CC_F5_BIAS		5	/* 5-bit fields get this added */
+-
+-#define	CC_MC_BYPASS		0x08
+-#define	CC_MC_M1		0x04
+-#define	CC_MC_M1M2		0x02
+-#define	CC_MC_M1M2M3		0x01
+-#define	CC_MC_M1M3		0x11
+-
+-/* Type 2 Clock control magic field values */
+-#define	CC_T2_BIAS		2	/* n1, n2, m1 & m3 bias */
+-#define	CC_T2M2_BIAS		3	/* m2 bias */
+-
+-#define	CC_T2MC_M1BYP		1
+-#define	CC_T2MC_M2BYP		2
+-#define	CC_T2MC_M3BYP		4
+-
+-/* Type 6 Clock control magic field values */
+-#define	CC_T6_MMASK		1	/* bits of interest in m */
+-#define	CC_T6_M0		120000000	/* sb clock for m = 0 */
+-#define	CC_T6_M1		100000000	/* sb clock for m = 1 */
+-#define	SB2MIPS_T6(sb)		(2 * (sb))
+-
+-/* Common clock base */
+-#define	CC_CLOCK_BASE1		24000000	/* Half the clock freq */
+-#define CC_CLOCK_BASE2		12500000	/* Alternate crystal on some PLLs */
+-
+-/* Clock control values for 200MHz in 5350 */
+-#define	CLKC_5350_N		0x0311
+-#define	CLKC_5350_M		0x04020009
+-
+-/* Flash types in the chipcommon capabilities register */
+-#define FLASH_NONE		0x000	/* No flash */
+-#define SFLASH_ST		0x100	/* ST serial flash */
+-#define SFLASH_AT		0x200	/* Atmel serial flash */
+-#define	PFLASH			0x700	/* Parallel flash */
+-
+-/* Bits in the ExtBus config registers */
+-#define	CC_CFG_EN		0x0001	/* Enable */
+-#define	CC_CFG_EM_MASK		0x000e	/* Extif Mode */
+-#define	CC_CFG_EM_ASYNC		0x0000	/*   Async/Parallel flash */
+-#define	CC_CFG_EM_SYNC		0x0002	/*   Synchronous */
+-#define	CC_CFG_EM_PCMCIA	0x0004	/*   PCMCIA */
+-#define	CC_CFG_EM_IDE		0x0006	/*   IDE */
+-#define	CC_CFG_DS		0x0010	/* Data size, 0=8bit, 1=16bit */
+-#define	CC_CFG_CD_MASK		0x00e0	/* Sync: Clock divisor, rev >= 20 */
+-#define	CC_CFG_CE		0x0100	/* Sync: Clock enable, rev >= 20 */
+-#define	CC_CFG_SB		0x0200	/* Sync: Size/Bytestrobe, rev >= 20 */
+-#define	CC_CFG_IS		0x0400	/* Extif Sync Clk Select, rev >= 20 */
+-
+-/* ExtBus address space */
+-#define	CC_EB_BASE		0x1a000000	/* Chipc ExtBus base address */
+-#define	CC_EB_PCMCIA_MEM	0x1a000000	/* PCMCIA 0 memory base address */
+-#define	CC_EB_PCMCIA_IO		0x1a200000	/* PCMCIA 0 I/O base address */
+-#define	CC_EB_PCMCIA_CFG	0x1a400000	/* PCMCIA 0 config base address */
+-#define	CC_EB_IDE		0x1a800000	/* IDE memory base */
+-#define	CC_EB_PCMCIA1_MEM	0x1a800000	/* PCMCIA 1 memory base address */
+-#define	CC_EB_PCMCIA1_IO	0x1aa00000	/* PCMCIA 1 I/O base address */
+-#define	CC_EB_PCMCIA1_CFG	0x1ac00000	/* PCMCIA 1 config base address */
+-#define	CC_EB_PROGIF		0x1b000000	/* ProgIF Async/Sync base address */
+-
+-/* Start/busy bit in flashcontrol */
+-#define SFLASH_OPCODE		0x000000ff
+-#define SFLASH_ACTION		0x00000700
+-#define	SFLASH_CS_ACTIVE	0x00001000	/* Chip Select Active, rev >= 20 */
+-#define SFLASH_START		0x80000000
+-#define SFLASH_BUSY		SFLASH_START
+-
+-/* flashcontrol action codes */
+-#define	SFLASH_ACT_OPONLY	0x0000	/* Issue opcode only */
+-#define	SFLASH_ACT_OP1D		0x0100	/* opcode + 1 data byte */
+-#define	SFLASH_ACT_OP3A		0x0200	/* opcode + 3 addr bytes */
+-#define	SFLASH_ACT_OP3A1D	0x0300	/* opcode + 3 addr & 1 data bytes */
+-#define	SFLASH_ACT_OP3A4D	0x0400	/* opcode + 3 addr & 4 data bytes */
+-#define	SFLASH_ACT_OP3A4X4D	0x0500	/* opcode + 3 addr, 4 don't care & 4 data bytes */
+-#define	SFLASH_ACT_OP3A1X4D	0x0700	/* opcode + 3 addr, 1 don't care & 4 data bytes */
+-
+-/* flashcontrol action+opcodes for ST flashes */
+-#define SFLASH_ST_WREN		0x0006	/* Write Enable */
+-#define SFLASH_ST_WRDIS		0x0004	/* Write Disable */
+-#define SFLASH_ST_RDSR		0x0105	/* Read Status Register */
+-#define SFLASH_ST_WRSR		0x0101	/* Write Status Register */
+-#define SFLASH_ST_READ		0x0303	/* Read Data Bytes */
+-#define SFLASH_ST_PP		0x0302	/* Page Program */
+-#define SFLASH_ST_SE		0x02d8	/* Sector Erase */
+-#define SFLASH_ST_BE		0x00c7	/* Bulk Erase */
+-#define SFLASH_ST_DP		0x00b9	/* Deep Power-down */
+-#define SFLASH_ST_RES		0x03ab	/* Read Electronic Signature */
+-#define SFLASH_ST_CSA		0x1000	/* Keep chip select asserted */
+-#define SFLASH_ST_SSE		0x0220	/* Sub-sector Erase */
+-
+-/* Status register bits for ST flashes */
+-#define SFLASH_ST_WIP		0x01	/* Write In Progress */
+-#define SFLASH_ST_WEL		0x02	/* Write Enable Latch */
+-#define SFLASH_ST_BP_MASK	0x1c	/* Block Protect */
+-#define SFLASH_ST_BP_SHIFT	2
+-#define SFLASH_ST_SRWD		0x80	/* Status Register Write Disable */
+-
+-/* flashcontrol action+opcodes for Atmel flashes */
+-#define SFLASH_AT_READ				0x07e8
+-#define SFLASH_AT_PAGE_READ			0x07d2
+-#define SFLASH_AT_BUF1_READ
+-#define SFLASH_AT_BUF2_READ
+-#define SFLASH_AT_STATUS			0x01d7
+-#define SFLASH_AT_BUF1_WRITE			0x0384
+-#define SFLASH_AT_BUF2_WRITE			0x0387
+-#define SFLASH_AT_BUF1_ERASE_PROGRAM		0x0283
+-#define SFLASH_AT_BUF2_ERASE_PROGRAM		0x0286
+-#define SFLASH_AT_BUF1_PROGRAM			0x0288
+-#define SFLASH_AT_BUF2_PROGRAM			0x0289
+-#define SFLASH_AT_PAGE_ERASE			0x0281
+-#define SFLASH_AT_BLOCK_ERASE			0x0250
+-#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM	0x0382
+-#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM	0x0385
+-#define SFLASH_AT_BUF1_LOAD			0x0253
+-#define SFLASH_AT_BUF2_LOAD			0x0255
+-#define SFLASH_AT_BUF1_COMPARE			0x0260
+-#define SFLASH_AT_BUF2_COMPARE			0x0261
+-#define SFLASH_AT_BUF1_REPROGRAM		0x0258
+-#define SFLASH_AT_BUF2_REPROGRAM		0x0259
+-
+-/* Status register bits for Atmel flashes */
+-#define SFLASH_AT_READY				0x80
+-#define SFLASH_AT_MISMATCH			0x40
+-#define SFLASH_AT_ID_MASK			0x38
+-#define SFLASH_AT_ID_SHIFT			3
+-
+-/*
+- * These are the UART port assignments, expressed as offsets from the base
+- * register.  These assignments should hold for any serial port based on
+- * a 8250, 16450, or 16550(A).
+- */
+-
+-#define UART_RX		0	/* In:  Receive buffer (DLAB=0) */
+-#define UART_TX		0	/* Out: Transmit buffer (DLAB=0) */
+-#define UART_DLL	0	/* Out: Divisor Latch Low (DLAB=1) */
+-#define UART_IER	1	/* In/Out: Interrupt Enable Register (DLAB=0) */
+-#define UART_DLM	1	/* Out: Divisor Latch High (DLAB=1) */
+-#define UART_IIR	2	/* In: Interrupt Identity Register  */
+-#define UART_FCR	2	/* Out: FIFO Control Register */
+-#define UART_LCR	3	/* Out: Line Control Register */
+-#define UART_MCR	4	/* Out: Modem Control Register */
+-#define UART_LSR	5	/* In:  Line Status Register */
+-#define UART_MSR	6	/* In:  Modem Status Register */
+-#define UART_SCR	7	/* I/O: Scratch Register */
+-#define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
+-#define UART_LCR_WLEN8	0x03	/* Word length: 8 bits */
+-#define UART_MCR_OUT2	0x08	/* MCR GPIO out 2 */
+-#define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
+-#define UART_LSR_RX_FIFO 	0x80	/* Receive FIFO error */
+-#define UART_LSR_TDHR		0x40	/* Data-hold-register empty */
+-#define UART_LSR_THRE		0x20	/* Transmit-hold-register empty */
+-#define UART_LSR_BREAK		0x10	/* Break interrupt */
+-#define UART_LSR_FRAMING	0x08	/* Framing error */
+-#define UART_LSR_PARITY		0x04	/* Parity error */
+-#define UART_LSR_OVERRUN	0x02	/* Overrun error */
+-#define UART_LSR_RXRDY		0x01	/* Receiver ready */
+-#define UART_FCR_FIFO_ENABLE 1	/* FIFO control register bit controlling FIFO enable/disable */
+-
+-/* Interrupt Identity Register (IIR) bits */
+-#define UART_IIR_FIFO_MASK	0xc0	/* IIR FIFO disable/enabled mask */
+-#define UART_IIR_INT_MASK	0xf	/* IIR interrupt ID source */
+-#define UART_IIR_MDM_CHG	0x0	/* Modem status changed */
+-#define UART_IIR_NOINT		0x1	/* No interrupt pending */
+-#define UART_IIR_THRE		0x2	/* THR empty */
+-#define UART_IIR_RCVD_DATA	0x4	/* Received data available */
+-#define UART_IIR_RCVR_STATUS 	0x6	/* Receiver status */
+-#define UART_IIR_CHAR_TIME 	0xc	/* Character time */
+-
+-/* Interrupt Enable Register (IER) bits */
+-#define UART_IER_EDSSI	8	/* enable modem status interrupt */
+-#define UART_IER_ELSI	4	/* enable receiver line status interrupt */
+-#define UART_IER_ETBEI  2	/* enable transmitter holding register empty interrupt */
+-#define UART_IER_ERBFI	1	/* enable data available interrupt */
+-
+-/* pmustatus */
+-#define PST_EXTLPOAVAIL	0x0100
+-#define PST_WDRESET	0x0080
+-#define	PST_INTPEND	0x0040
+-#define	PST_SBCLKST	0x0030
+-#define	PST_SBCLKST_ILP	0x0010
+-#define	PST_SBCLKST_ALP	0x0020
+-#define	PST_SBCLKST_HT	0x0030
+-#define	PST_ALPAVAIL	0x0008
+-#define	PST_HTAVAIL	0x0004
+-#define	PST_RESINIT	0x0003
+-
+-/* pmucapabilities */
+-#define PCAP_REV_MASK	0x000000ff
+-#define PCAP_RC_MASK	0x00001f00
+-#define PCAP_RC_SHIFT	8
+-#define PCAP_TC_MASK	0x0001e000
+-#define PCAP_TC_SHIFT	13
+-#define PCAP_PC_MASK	0x001e0000
+-#define PCAP_PC_SHIFT	17
+-#define PCAP_VC_MASK	0x01e00000
+-#define PCAP_VC_SHIFT	21
+-#define PCAP_CC_MASK	0x1e000000
+-#define PCAP_CC_SHIFT	25
+-#define PCAP5_PC_MASK	0x003e0000	/* PMU corerev >= 5 */
+-#define PCAP5_PC_SHIFT	17
+-#define PCAP5_VC_MASK	0x07c00000
+-#define PCAP5_VC_SHIFT	22
+-#define PCAP5_CC_MASK	0xf8000000
+-#define PCAP5_CC_SHIFT	27
+-
+-/* PMU Resource Request Timer registers */
+-/* This is based on PmuRev0 */
+-#define	PRRT_TIME_MASK	0x03ff
+-#define	PRRT_INTEN	0x0400
+-#define	PRRT_REQ_ACTIVE	0x0800
+-#define	PRRT_ALP_REQ	0x1000
+-#define	PRRT_HT_REQ	0x2000
+-
+-/* PMU resource bit position */
+-#define PMURES_BIT(bit)	(1 << (bit))
+-
+-/* PMU resource number limit */
+-#define PMURES_MAX_RESNUM	30
+-
+-/* PMU chip control0 register */
+-#define	PMU_CHIPCTL0		0
+-
+-/* PMU chip control1 register */
+-#define	PMU_CHIPCTL1			1
+-#define	PMU_CC1_RXC_DLL_BYPASS		0x00010000
+-
+-#define PMU_CC1_IF_TYPE_MASK   		0x00000030
+-#define PMU_CC1_IF_TYPE_RMII    	0x00000000
+-#define PMU_CC1_IF_TYPE_MII     	0x00000010
+-#define PMU_CC1_IF_TYPE_RGMII   	0x00000020
+-
+-#define PMU_CC1_SW_TYPE_MASK    	0x000000c0
+-#define PMU_CC1_SW_TYPE_EPHY    	0x00000000
+-#define PMU_CC1_SW_TYPE_EPHYMII 	0x00000040
+-#define PMU_CC1_SW_TYPE_EPHYRMII	0x00000080
+-#define PMU_CC1_SW_TYPE_RGMII   	0x000000c0
+-
+-/* PMU corerev and chip specific PLL controls.
+- * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
+- * to differentiate different PLLs controlled by the same PMU rev.
+- */
+-/* pllcontrol registers */
+-/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
+-#define	PMU0_PLL0_PLLCTL0		0
+-#define	PMU0_PLL0_PC0_PDIV_MASK		1
+-#define	PMU0_PLL0_PC0_PDIV_FREQ		25000
+-#define PMU0_PLL0_PC0_DIV_ARM_MASK	0x00000038
+-#define PMU0_PLL0_PC0_DIV_ARM_SHIFT	3
+-#define PMU0_PLL0_PC0_DIV_ARM_BASE	8
+-
+-/* PC0_DIV_ARM for PLLOUT_ARM */
+-#define PMU0_PLL0_PC0_DIV_ARM_110MHZ	0
+-#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ	1
+-#define PMU0_PLL0_PC0_DIV_ARM_88MHZ	2
+-#define PMU0_PLL0_PC0_DIV_ARM_80MHZ	3	/* Default */
+-#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ	4
+-#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ	5
+-#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ	6
+-#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ	7
+-
+-/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
+-#define	PMU0_PLL0_PLLCTL1		1
+-#define	PMU0_PLL0_PC1_WILD_INT_MASK	0xf0000000
+-#define	PMU0_PLL0_PC1_WILD_INT_SHIFT	28
+-#define	PMU0_PLL0_PC1_WILD_FRAC_MASK	0x0fffff00
+-#define	PMU0_PLL0_PC1_WILD_FRAC_SHIFT	8
+-#define	PMU0_PLL0_PC1_STOP_MOD		0x00000040
+-
+-/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
+-#define	PMU0_PLL0_PLLCTL2		2
+-#define	PMU0_PLL0_PC2_WILD_INT_MASK	0xf
+-#define	PMU0_PLL0_PC2_WILD_INT_SHIFT	4
+-
+-/* pllcontrol registers */
+-/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+-#define PMU1_PLL0_PLLCTL0		0
+-#define PMU1_PLL0_PC0_P1DIV_MASK	0x00f00000
+-#define PMU1_PLL0_PC0_P1DIV_SHIFT	20
+-#define PMU1_PLL0_PC0_P2DIV_MASK	0x0f000000
+-#define PMU1_PLL0_PC0_P2DIV_SHIFT	24
+-
+-/* m<x>div */
+-#define PMU1_PLL0_PLLCTL1		1
+-#define PMU1_PLL0_PC1_M1DIV_MASK	0x000000ff
+-#define PMU1_PLL0_PC1_M1DIV_SHIFT	0
+-#define PMU1_PLL0_PC1_M2DIV_MASK	0x0000ff00
+-#define PMU1_PLL0_PC1_M2DIV_SHIFT	8
+-#define PMU1_PLL0_PC1_M3DIV_MASK	0x00ff0000
+-#define PMU1_PLL0_PC1_M3DIV_SHIFT	16
+-#define PMU1_PLL0_PC1_M4DIV_MASK	0xff000000
+-#define PMU1_PLL0_PC1_M4DIV_SHIFT	24
+-
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL  (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+-
+-/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+-#define PMU1_PLL0_PLLCTL2		2
+-#define PMU1_PLL0_PC2_M5DIV_MASK	0x000000ff
+-#define PMU1_PLL0_PC2_M5DIV_SHIFT	0
+-#define PMU1_PLL0_PC2_M6DIV_MASK	0x0000ff00
+-#define PMU1_PLL0_PC2_M6DIV_SHIFT	8
+-#define PMU1_PLL0_PC2_NDIV_MODE_MASK	0x000e0000
+-#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT	17
+-#define PMU1_PLL0_PC2_NDIV_MODE_MASH	1
+-#define PMU1_PLL0_PC2_NDIV_MODE_MFB	2	/* recommended for 4319 */
+-#define PMU1_PLL0_PC2_NDIV_INT_MASK	0x1ff00000
+-#define PMU1_PLL0_PC2_NDIV_INT_SHIFT	20
+-
+-/* ndiv_frac */
+-#define PMU1_PLL0_PLLCTL3		3
+-#define PMU1_PLL0_PC3_NDIV_FRAC_MASK	0x00ffffff
+-#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT	0
+-
+-/* pll_ctrl */
+-#define PMU1_PLL0_PLLCTL4		4
+-
+-/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+-#define PMU1_PLL0_PLLCTL5		5
+-#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
+-#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
+-
+-/* PMU rev 2 control words */
+-#define PMU2_PHY_PLL_PLLCTL		4
+-#define PMU2_SI_PLL_PLLCTL		10
+-
+-/* PMU rev 2 */
+-/* pllcontrol registers */
+-/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+-#define PMU2_PLL_PLLCTL0		0
+-#define PMU2_PLL_PC0_P1DIV_MASK 	0x00f00000
+-#define PMU2_PLL_PC0_P1DIV_SHIFT	20
+-#define PMU2_PLL_PC0_P2DIV_MASK 	0x0f000000
+-#define PMU2_PLL_PC0_P2DIV_SHIFT	24
+-
+-/* m<x>div */
+-#define PMU2_PLL_PLLCTL1		1
+-#define PMU2_PLL_PC1_M1DIV_MASK 	0x000000ff
+-#define PMU2_PLL_PC1_M1DIV_SHIFT	0
+-#define PMU2_PLL_PC1_M2DIV_MASK 	0x0000ff00
+-#define PMU2_PLL_PC1_M2DIV_SHIFT	8
+-#define PMU2_PLL_PC1_M3DIV_MASK 	0x00ff0000
+-#define PMU2_PLL_PC1_M3DIV_SHIFT	16
+-#define PMU2_PLL_PC1_M4DIV_MASK 	0xff000000
+-#define PMU2_PLL_PC1_M4DIV_SHIFT	24
+-
+-/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+-#define PMU2_PLL_PLLCTL2		2
+-#define PMU2_PLL_PC2_M5DIV_MASK 	0x000000ff
+-#define PMU2_PLL_PC2_M5DIV_SHIFT	0
+-#define PMU2_PLL_PC2_M6DIV_MASK 	0x0000ff00
+-#define PMU2_PLL_PC2_M6DIV_SHIFT	8
+-#define PMU2_PLL_PC2_NDIV_MODE_MASK	0x000e0000
+-#define PMU2_PLL_PC2_NDIV_MODE_SHIFT	17
+-#define PMU2_PLL_PC2_NDIV_INT_MASK	0x1ff00000
+-#define PMU2_PLL_PC2_NDIV_INT_SHIFT	20
+-
+-/* ndiv_frac */
+-#define PMU2_PLL_PLLCTL3		3
+-#define PMU2_PLL_PC3_NDIV_FRAC_MASK	0x00ffffff
+-#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT	0
+-
+-/* pll_ctrl */
+-#define PMU2_PLL_PLLCTL4		4
+-
+-/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+-#define PMU2_PLL_PLLCTL5		5
+-#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK	0x00000f00
+-#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT	8
+-#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK	0x0000f000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT	12
+-#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK	0x000f0000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT	16
+-#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK	0x00f00000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT	20
+-#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK	0x0f000000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT	24
+-#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK	0xf0000000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT	28
+-
+-/* PMU rev 5 (& 6) */
+-#define	PMU5_PLL_P1P2_OFF		0
+-#define	PMU5_PLL_P1_MASK		0x0f000000
+-#define	PMU5_PLL_P1_SHIFT		24
+-#define	PMU5_PLL_P2_MASK		0x00f00000
+-#define	PMU5_PLL_P2_SHIFT		20
+-#define	PMU5_PLL_M14_OFF		1
+-#define	PMU5_PLL_MDIV_MASK		0x000000ff
+-#define	PMU5_PLL_MDIV_WIDTH		8
+-#define	PMU5_PLL_NM5_OFF		2
+-#define	PMU5_PLL_NDIV_MASK		0xfff00000
+-#define	PMU5_PLL_NDIV_SHIFT		20
+-#define	PMU5_PLL_NDIV_MODE_MASK		0x000e0000
+-#define	PMU5_PLL_NDIV_MODE_SHIFT	17
+-#define	PMU5_PLL_FMAB_OFF		3
+-#define	PMU5_PLL_MRAT_MASK		0xf0000000
+-#define	PMU5_PLL_MRAT_SHIFT		28
+-#define	PMU5_PLL_ABRAT_MASK		0x08000000
+-#define	PMU5_PLL_ABRAT_SHIFT		27
+-#define	PMU5_PLL_FDIV_MASK		0x07ffffff
+-#define	PMU5_PLL_PLLCTL_OFF		4
+-#define	PMU5_PLL_PCHI_OFF		5
+-#define	PMU5_PLL_PCHI_MASK		0x0000003f
+-
+-/* pmu XtalFreqRatio */
+-#define	PMU_XTALFREQ_REG_ILPCTR_MASK	0x00001FFF
+-#define	PMU_XTALFREQ_REG_MEASURE_MASK	0x80000000
+-#define	PMU_XTALFREQ_REG_MEASURE_SHIFT	31
+-
+-/* Divider allocation in 4716/47162/5356/5357 */
+-#define	PMU5_MAINPLL_CPU		1
+-#define	PMU5_MAINPLL_MEM		2
+-#define	PMU5_MAINPLL_SI			3
+-
+-#define PMU7_PLL_PLLCTL7                7
+-#define PMU7_PLL_PLLCTL8                8
+-#define PMU7_PLL_PLLCTL11		11
+-
+-/* PLL usage in 4716/47162 */
+-#define	PMU4716_MAINPLL_PLL0		12
+-
+-/* PLL usage in 5356/5357 */
+-#define	PMU5356_MAINPLL_PLL0		0
+-#define	PMU5357_MAINPLL_PLL0		0
+-
+-/* 4716/47162 resources */
+-#define RES4716_PROC_PLL_ON		0x00000040
+-#define RES4716_PROC_HT_AVAIL		0x00000080
+-
+-/* 4716/4717/4718 Chip specific ChipControl register bits */
+-#define CCTRL471X_I2S_PINS_ENABLE          0x0080	/* I2S pins off by default, shared with pflash */
+-
+-/* 5354 resources */
+-#define RES5354_EXT_SWITCHER_PWM	0	/* 0x00001 */
+-#define RES5354_BB_SWITCHER_PWM		1	/* 0x00002 */
+-#define RES5354_BB_SWITCHER_BURST	2	/* 0x00004 */
+-#define RES5354_BB_EXT_SWITCHER_BURST	3	/* 0x00008 */
+-#define RES5354_ILP_REQUEST		4	/* 0x00010 */
+-#define RES5354_RADIO_SWITCHER_PWM	5	/* 0x00020 */
+-#define RES5354_RADIO_SWITCHER_BURST	6	/* 0x00040 */
+-#define RES5354_ROM_SWITCH		7	/* 0x00080 */
+-#define RES5354_PA_REF_LDO		8	/* 0x00100 */
+-#define RES5354_RADIO_LDO		9	/* 0x00200 */
+-#define RES5354_AFE_LDO			10	/* 0x00400 */
+-#define RES5354_PLL_LDO			11	/* 0x00800 */
+-#define RES5354_BG_FILTBYP		12	/* 0x01000 */
+-#define RES5354_TX_FILTBYP		13	/* 0x02000 */
+-#define RES5354_RX_FILTBYP		14	/* 0x04000 */
+-#define RES5354_XTAL_PU			15	/* 0x08000 */
+-#define RES5354_XTAL_EN			16	/* 0x10000 */
+-#define RES5354_BB_PLL_FILTBYP		17	/* 0x20000 */
+-#define RES5354_RF_PLL_FILTBYP		18	/* 0x40000 */
+-#define RES5354_BB_PLL_PU		19	/* 0x80000 */
+-
+-/* 5357 Chip specific ChipControl register bits */
+-#define CCTRL5357_EXTPA                 (1<<14)	/* extPA in ChipControl 1, bit 14 */
+-#define CCTRL5357_ANT_MUX_2o3		(1<<15)	/* 2o3 in ChipControl 1, bit 15 */
+-
+-/* 4328 resources */
+-#define RES4328_EXT_SWITCHER_PWM	0	/* 0x00001 */
+-#define RES4328_BB_SWITCHER_PWM		1	/* 0x00002 */
+-#define RES4328_BB_SWITCHER_BURST	2	/* 0x00004 */
+-#define RES4328_BB_EXT_SWITCHER_BURST	3	/* 0x00008 */
+-#define RES4328_ILP_REQUEST		4	/* 0x00010 */
+-#define RES4328_RADIO_SWITCHER_PWM	5	/* 0x00020 */
+-#define RES4328_RADIO_SWITCHER_BURST	6	/* 0x00040 */
+-#define RES4328_ROM_SWITCH		7	/* 0x00080 */
+-#define RES4328_PA_REF_LDO		8	/* 0x00100 */
+-#define RES4328_RADIO_LDO		9	/* 0x00200 */
+-#define RES4328_AFE_LDO			10	/* 0x00400 */
+-#define RES4328_PLL_LDO			11	/* 0x00800 */
+-#define RES4328_BG_FILTBYP		12	/* 0x01000 */
+-#define RES4328_TX_FILTBYP		13	/* 0x02000 */
+-#define RES4328_RX_FILTBYP		14	/* 0x04000 */
+-#define RES4328_XTAL_PU			15	/* 0x08000 */
+-#define RES4328_XTAL_EN			16	/* 0x10000 */
+-#define RES4328_BB_PLL_FILTBYP		17	/* 0x20000 */
+-#define RES4328_RF_PLL_FILTBYP		18	/* 0x40000 */
+-#define RES4328_BB_PLL_PU		19	/* 0x80000 */
+-
+-/* 4325 A0/A1 resources */
+-#define RES4325_BUCK_BOOST_BURST	0	/* 0x00000001 */
+-#define RES4325_CBUCK_BURST		1	/* 0x00000002 */
+-#define RES4325_CBUCK_PWM		2	/* 0x00000004 */
+-#define RES4325_CLDO_CBUCK_BURST	3	/* 0x00000008 */
+-#define RES4325_CLDO_CBUCK_PWM		4	/* 0x00000010 */
+-#define RES4325_BUCK_BOOST_PWM		5	/* 0x00000020 */
+-#define RES4325_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4325_ABUCK_BURST		7	/* 0x00000080 */
+-#define RES4325_ABUCK_PWM		8	/* 0x00000100 */
+-#define RES4325_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4325_OTP_PU			10	/* 0x00000400 */
+-#define RES4325_LNLDO3_PU		11	/* 0x00000800 */
+-#define RES4325_LNLDO4_PU		12	/* 0x00001000 */
+-#define RES4325_XTAL_PU			13	/* 0x00002000 */
+-#define RES4325_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4325_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4325_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4325_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4325_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4325_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4325_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4325_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4325 B0/C0 resources */
+-#define RES4325B0_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4325B0_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4325B0_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4325B0_CLDO_PU		4	/* 0x00000010 */
+-
+-/* 4325 C1 resources */
+-#define RES4325C1_LNLDO2_PU		12	/* 0x00001000 */
+-
+-/* 4325 chip-specific ChipStatus register bits */
+-#define CST4325_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4325_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4325_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4325_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4325_OTP_PWRDN		3	/* OTP is powered down, SPROM is present */
+-#define CST4325_SDIO_USB_MODE_MASK	0x00000004
+-#define CST4325_SDIO_USB_MODE_SHIFT	2
+-#define CST4325_RCAL_VALID_MASK		0x00000008
+-#define CST4325_RCAL_VALID_SHIFT	3
+-#define CST4325_RCAL_VALUE_MASK		0x000001f0
+-#define CST4325_RCAL_VALUE_SHIFT	4
+-#define CST4325_PMUTOP_2B_MASK 		0x00000200	/* 1 for 2b, 0 for to 2a */
+-#define CST4325_PMUTOP_2B_SHIFT   	9
+-
+-#define RES4329_RESERVED0		0	/* 0x00000001 */
+-#define RES4329_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4329_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4329_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4329_CLDO_PU			4	/* 0x00000010 */
+-#define RES4329_PALDO_PU		5	/* 0x00000020 */
+-#define RES4329_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4329_RESERVED7		7	/* 0x00000080 */
+-#define RES4329_RESERVED8		8	/* 0x00000100 */
+-#define RES4329_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4329_OTP_PU			10	/* 0x00000400 */
+-#define RES4329_RESERVED11		11	/* 0x00000800 */
+-#define RES4329_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4329_XTAL_PU			13	/* 0x00002000 */
+-#define RES4329_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4329_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4329_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4329_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4329_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4329_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4329_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4329_HT_AVAIL		21	/* 0x00200000 */
+-
+-#define CST4329_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4329_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4329_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4329_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4329_OTP_PWRDN		3	/* OTP is powered down, SPROM is present */
+-#define CST4329_SPI_SDIO_MODE_MASK	0x00000004
+-#define CST4329_SPI_SDIO_MODE_SHIFT	2
+-
+-/* 4312 chip-specific ChipStatus register bits */
+-#define CST4312_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4312_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4312_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4312_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4312_OTP_BAD			3	/* OTP is broken, SPROM is present */
+-
+-/* 4312 resources (all PMU chips with little memory constraint) */
+-#define RES4312_SWITCHER_BURST		0	/* 0x00000001 */
+-#define RES4312_SWITCHER_PWM    	1	/* 0x00000002 */
+-#define RES4312_PA_REF_LDO		2	/* 0x00000004 */
+-#define RES4312_CORE_LDO_BURST		3	/* 0x00000008 */
+-#define RES4312_CORE_LDO_PWM		4	/* 0x00000010 */
+-#define RES4312_RADIO_LDO		5	/* 0x00000020 */
+-#define RES4312_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4312_BG_FILTBYP		7	/* 0x00000080 */
+-#define RES4312_TX_FILTBYP		8	/* 0x00000100 */
+-#define RES4312_RX_FILTBYP		9	/* 0x00000200 */
+-#define RES4312_XTAL_PU			10	/* 0x00000400 */
+-#define RES4312_ALP_AVAIL		11	/* 0x00000800 */
+-#define RES4312_BB_PLL_FILTBYP		12	/* 0x00001000 */
+-#define RES4312_RF_PLL_FILTBYP		13	/* 0x00002000 */
+-#define RES4312_HT_AVAIL		14	/* 0x00004000 */
+-
+-/* 4322 resources */
+-#define RES4322_RF_LDO			0
+-#define RES4322_ILP_REQUEST		1
+-#define RES4322_XTAL_PU			2
+-#define RES4322_ALP_AVAIL		3
+-#define RES4322_SI_PLL_ON		4
+-#define RES4322_HT_SI_AVAIL		5
+-#define RES4322_PHY_PLL_ON		6
+-#define RES4322_HT_PHY_AVAIL		7
+-#define RES4322_OTP_PU			8
+-
+-/* 4322 chip-specific ChipStatus register bits */
+-#define CST4322_XTAL_FREQ_20_40MHZ	0x00000020
+-#define CST4322_SPROM_OTP_SEL_MASK	0x000000c0
+-#define CST4322_SPROM_OTP_SEL_SHIFT	6
+-#define CST4322_NO_SPROM_OTP		0	/* no OTP, no SPROM */
+-#define CST4322_SPROM_PRESENT		1	/* SPROM is present */
+-#define CST4322_OTP_PRESENT		2	/* OTP is present */
+-#define CST4322_PCI_OR_USB		0x00000100
+-#define CST4322_BOOT_MASK		0x00000600
+-#define CST4322_BOOT_SHIFT		9
+-#define CST4322_BOOT_FROM_SRAM		0	/* boot from SRAM, ARM in reset */
+-#define CST4322_BOOT_FROM_ROM		1	/* boot from ROM */
+-#define CST4322_BOOT_FROM_FLASH		2	/* boot from FLASH */
+-#define CST4322_BOOT_FROM_INVALID	3
+-#define CST4322_ILP_DIV_EN		0x00000800
+-#define CST4322_FLASH_TYPE_MASK		0x00001000
+-#define CST4322_FLASH_TYPE_SHIFT	12
+-#define CST4322_FLASH_TYPE_SHIFT_ST	0	/* ST serial FLASH */
+-#define CST4322_FLASH_TYPE_SHIFT_ATMEL	1	/* ATMEL flash */
+-#define CST4322_ARM_TAP_SEL		0x00002000
+-#define CST4322_RES_INIT_MODE_MASK	0x0000c000
+-#define CST4322_RES_INIT_MODE_SHIFT	14
+-#define CST4322_RES_INIT_MODE_ILPAVAIL	0	/* resinitmode: ILP available */
+-#define CST4322_RES_INIT_MODE_ILPREQ	1	/* resinitmode: ILP request */
+-#define CST4322_RES_INIT_MODE_ALPAVAIL	2	/* resinitmode: ALP available */
+-#define CST4322_RES_INIT_MODE_HTAVAIL	3	/* resinitmode: HT available */
+-#define CST4322_PCIPLLCLK_GATING	0x00010000
+-#define CST4322_CLK_SWITCH_PCI_TO_ALP	0x00020000
+-#define CST4322_PCI_CARDBUS_MODE	0x00040000
+-
+-/* 43224 chip-specific ChipControl register bits */
+-#define CCTRL43224_GPIO_TOGGLE          0x8000
+-#define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0	/* 12 mA drive strength */
+-#define CCTRL_43224B0_12MA_LED_DRIVE    0xF0	/* 12 mA drive strength for later 43224s */
+-
+-/* 43236 resources */
+-#define RES43236_REGULATOR		0
+-#define RES43236_ILP_REQUEST		1
+-#define RES43236_XTAL_PU		2
+-#define RES43236_ALP_AVAIL		3
+-#define RES43236_SI_PLL_ON		4
+-#define RES43236_HT_SI_AVAIL		5
+-
+-/* 43236 chip-specific ChipControl register bits */
+-#define CCTRL43236_BT_COEXIST		(1<<0)	/* 0 disable */
+-#define CCTRL43236_SECI			(1<<1)	/* 0 SECI is disabled (JATG functional) */
+-#define CCTRL43236_EXT_LNA		(1<<2)	/* 0 disable */
+-#define CCTRL43236_ANT_MUX_2o3          (1<<3)	/* 2o3 mux, chipcontrol bit 3 */
+-#define CCTRL43236_GSIO			(1<<4)	/* 0 disable */
+-
+-/* 43236 Chip specific ChipStatus register bits */
+-#define CST43236_SFLASH_MASK		0x00000040
+-#define CST43236_OTP_MASK		0x00000080
+-#define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
+-#define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
+-#define CST43236_BOOT_MASK		0x00001800
+-#define CST43236_BOOT_SHIFT		11
+-#define CST43236_BOOT_FROM_SRAM		0	/* boot from SRAM, ARM in reset */
+-#define CST43236_BOOT_FROM_ROM		1	/* boot from ROM */
+-#define CST43236_BOOT_FROM_FLASH	2	/* boot from FLASH */
+-#define CST43236_BOOT_FROM_INVALID	3
+-
+-/* 4331 resources */
+-#define RES4331_REGULATOR		0
+-#define RES4331_ILP_REQUEST		1
+-#define RES4331_XTAL_PU			2
+-#define RES4331_ALP_AVAIL		3
+-#define RES4331_SI_PLL_ON		4
+-#define RES4331_HT_SI_AVAIL		5
+-
+-/* 4331 chip-specific ChipControl register bits */
+-#define CCTRL4331_BT_COEXIST		(1<<0)	/* 0 disable */
+-#define CCTRL4331_SECI			(1<<1)	/* 0 SECI is disabled (JATG functional) */
+-#define CCTRL4331_EXT_LNA		(1<<2)	/* 0 disable */
+-#define CCTRL4331_SPROM_GPIO13_15       (1<<3)	/* sprom/gpio13-15 mux */
+-#define CCTRL4331_EXTPA_EN		(1<<4)	/* 0 ext pa disable, 1 ext pa enabled */
+-#define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)	/* set drive out GPIO_CLK on sprom_cs pin */
+-#define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)	/* use sprom_cs pin as PCIE mdio interface */
+-#define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)	/* aband extpa will be at gpio2/5 and sprom_dout */
+-#define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)	/* override core control on pipe_AuxClkEnable */
+-#define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)	/* override core control on pipe_AuxPowerDown */
+-#define CCTRL4331_PCIE_AUXCLKEN		(1<<10)	/* pcie_auxclkenable */
+-#define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)	/* pcie_pipe_pllpowerdown */
+-#define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)	/* enable bt_shd0 at gpio4 */
+-#define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)	/* enable bt_shd1 at gpio5 */
+-
+-/* 4331 Chip specific ChipStatus register bits */
+-#define	CST4331_XTAL_FREQ		0x00000001	/* crystal frequency 20/40Mhz */
+-#define	CST4331_SPROM_PRESENT		0x00000002
+-#define	CST4331_OTP_PRESENT		0x00000004
+-#define	CST4331_LDO_RF			0x00000008
+-#define	CST4331_LDO_PAR			0x00000010
+-
+-/* 4315 resources */
+-#define RES4315_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4315_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4315_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4315_CLDO_PU			4	/* 0x00000010 */
+-#define RES4315_PALDO_PU		5	/* 0x00000020 */
+-#define RES4315_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4315_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4315_OTP_PU			10	/* 0x00000400 */
+-#define RES4315_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4315_XTAL_PU			13	/* 0x00002000 */
+-#define RES4315_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4315_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4315_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4315_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4315_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4315_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4315_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4315_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4315 chip-specific ChipStatus register bits */
+-#define CST4315_SPROM_OTP_SEL_MASK	0x00000003	/* gpio [7:6], SDIO CIS selection */
+-#define CST4315_DEFCIS_SEL		0x00000000	/* use default CIS, OTP is powered up */
+-#define CST4315_SPROM_SEL		0x00000001	/* use SPROM, OTP is powered up */
+-#define CST4315_OTP_SEL			0x00000002	/* use OTP, OTP is powered up */
+-#define CST4315_OTP_PWRDN		0x00000003	/* use SPROM, OTP is powered down */
+-#define CST4315_SDIO_MODE		0x00000004	/* gpio [8], sdio/usb mode */
+-#define CST4315_RCAL_VALID		0x00000008
+-#define CST4315_RCAL_VALUE_MASK		0x000001f0
+-#define CST4315_RCAL_VALUE_SHIFT	4
+-#define CST4315_PALDO_EXTPNP		0x00000200	/* PALDO is configured with external PNP */
+-#define CST4315_CBUCK_MODE_MASK		0x00000c00
+-#define CST4315_CBUCK_MODE_BURST	0x00000400
+-#define CST4315_CBUCK_MODE_LPBURST	0x00000c00
+-
+-/* 4319 resources */
+-#define RES4319_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4319_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4319_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4319_CLDO_PU			4	/* 0x00000010 */
+-#define RES4319_PALDO_PU		5	/* 0x00000020 */
+-#define RES4319_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4319_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4319_OTP_PU			10	/* 0x00000400 */
+-#define RES4319_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4319_XTAL_PU			13	/* 0x00002000 */
+-#define RES4319_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4319_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4319_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4319_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4319_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4319_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4319_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4319_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4319 chip-specific ChipStatus register bits */
+-#define	CST4319_SPI_CPULESSUSB		0x00000001
+-#define	CST4319_SPI_CLK_POL		0x00000002
+-#define	CST4319_SPI_CLK_PH		0x00000008
+-#define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0	/* gpio [7:6], SDIO CIS selection */
+-#define	CST4319_SPROM_OTP_SEL_SHIFT	6
+-#define	CST4319_DEFCIS_SEL		0x00000000	/* use default CIS, OTP is powered up */
+-#define	CST4319_SPROM_SEL		0x00000040	/* use SPROM, OTP is powered up */
+-#define	CST4319_OTP_SEL			0x00000080	/* use OTP, OTP is powered up */
+-#define	CST4319_OTP_PWRDN		0x000000c0	/* use SPROM, OTP is powered down */
+-#define	CST4319_SDIO_USB_MODE		0x00000100	/* gpio [8], sdio/usb mode */
+-#define	CST4319_REMAP_SEL_MASK		0x00000600
+-#define	CST4319_ILPDIV_EN		0x00000800
+-#define	CST4319_XTAL_PD_POL		0x00001000
+-#define	CST4319_LPO_SEL			0x00002000
+-#define	CST4319_RES_INIT_MODE		0x0000c000
+-#define	CST4319_PALDO_EXTPNP		0x00010000	/* PALDO is configured with external PNP */
+-#define	CST4319_CBUCK_MODE_MASK		0x00060000
+-#define CST4319_CBUCK_MODE_BURST	0x00020000
+-#define CST4319_CBUCK_MODE_LPBURST	0x00060000
+-#define	CST4319_RCAL_VALID		0x01000000
+-#define	CST4319_RCAL_VALUE_MASK		0x3e000000
+-#define	CST4319_RCAL_VALUE_SHIFT	25
+-
+-#define PMU1_PLL0_CHIPCTL0		0
+-#define PMU1_PLL0_CHIPCTL1		1
+-#define PMU1_PLL0_CHIPCTL2		2
+-#define CCTL_4319USB_XTAL_SEL_MASK	0x00180000
+-#define CCTL_4319USB_XTAL_SEL_SHIFT	19
+-#define CCTL_4319USB_48MHZ_PLL_SEL	1
+-#define CCTL_4319USB_24MHZ_PLL_SEL	2
+-
+-/* PMU resources for 4336 */
+-#define	RES4336_CBUCK_LPOM		0
+-#define	RES4336_CBUCK_BURST		1
+-#define	RES4336_CBUCK_LP_PWM		2
+-#define	RES4336_CBUCK_PWM		3
+-#define	RES4336_CLDO_PU			4
+-#define	RES4336_DIS_INT_RESET_PD	5
+-#define	RES4336_ILP_REQUEST		6
+-#define	RES4336_LNLDO_PU		7
+-#define	RES4336_LDO3P3_PU		8
+-#define	RES4336_OTP_PU			9
+-#define	RES4336_XTAL_PU			10
+-#define	RES4336_ALP_AVAIL		11
+-#define	RES4336_RADIO_PU		12
+-#define	RES4336_BG_PU			13
+-#define	RES4336_VREG1p4_PU_PU		14
+-#define	RES4336_AFE_PWRSW_PU		15
+-#define	RES4336_RX_PWRSW_PU		16
+-#define	RES4336_TX_PWRSW_PU		17
+-#define	RES4336_BB_PWRSW_PU		18
+-#define	RES4336_SYNTH_PWRSW_PU		19
+-#define	RES4336_MISC_PWRSW_PU		20
+-#define	RES4336_LOGEN_PWRSW_PU		21
+-#define	RES4336_BBPLL_PWRSW_PU		22
+-#define	RES4336_MACPHY_CLKAVAIL		23
+-#define	RES4336_HT_AVAIL		24
+-#define	RES4336_RSVD			25
+-
+-/* 4336 chip-specific ChipStatus register bits */
+-#define	CST4336_SPI_MODE_MASK		0x00000001
+-#define	CST4336_SPROM_PRESENT		0x00000002
+-#define	CST4336_OTP_PRESENT		0x00000004
+-#define	CST4336_ARMREMAP_0		0x00000008
+-#define	CST4336_ILPDIV_EN_MASK		0x00000010
+-#define	CST4336_ILPDIV_EN_SHIFT		4
+-#define	CST4336_XTAL_PD_POL_MASK	0x00000020
+-#define	CST4336_XTAL_PD_POL_SHIFT	5
+-#define	CST4336_LPO_SEL_MASK		0x00000040
+-#define	CST4336_LPO_SEL_SHIFT		6
+-#define	CST4336_RES_INIT_MODE_MASK	0x00000180
+-#define	CST4336_RES_INIT_MODE_SHIFT	7
+-#define	CST4336_CBUCK_MODE_MASK		0x00000600
+-#define	CST4336_CBUCK_MODE_SHIFT	9
+-
+-/* 4330 resources */
+-#define	RES4330_CBUCK_LPOM		0
+-#define	RES4330_CBUCK_BURST		1
+-#define	RES4330_CBUCK_LP_PWM		2
+-#define	RES4330_CBUCK_PWM		3
+-#define	RES4330_CLDO_PU			4
+-#define	RES4330_DIS_INT_RESET_PD	5
+-#define	RES4330_ILP_REQUEST		6
+-#define	RES4330_LNLDO_PU		7
+-#define	RES4330_LDO3P3_PU		8
+-#define	RES4330_OTP_PU			9
+-#define	RES4330_XTAL_PU			10
+-#define	RES4330_ALP_AVAIL		11
+-#define	RES4330_RADIO_PU		12
+-#define	RES4330_BG_PU			13
+-#define	RES4330_VREG1p4_PU_PU		14
+-#define	RES4330_AFE_PWRSW_PU		15
+-#define	RES4330_RX_PWRSW_PU		16
+-#define	RES4330_TX_PWRSW_PU		17
+-#define	RES4330_BB_PWRSW_PU		18
+-#define	RES4330_SYNTH_PWRSW_PU		19
+-#define	RES4330_MISC_PWRSW_PU		20
+-#define	RES4330_LOGEN_PWRSW_PU		21
+-#define	RES4330_BBPLL_PWRSW_PU		22
+-#define	RES4330_MACPHY_CLKAVAIL		23
+-#define	RES4330_HT_AVAIL		24
+-#define	RES4330_5gRX_PWRSW_PU		25
+-#define	RES4330_5gTX_PWRSW_PU		26
+-#define	RES4330_5g_LOGEN_PWRSW_PU	27
+-
+-/* 4330 chip-specific ChipStatus register bits */
+-#define CST4330_CHIPMODE_SDIOD(cs)	(((cs) & 0x7) < 6)	/* SDIO || gSPI */
+-#define CST4330_CHIPMODE_USB20D(cs)	(((cs) & 0x7) >= 6)	/* USB || USBDA */
+-#define CST4330_CHIPMODE_SDIO(cs)	(((cs) & 0x4) == 0)	/* SDIO */
+-#define CST4330_CHIPMODE_GSPI(cs)	(((cs) & 0x6) == 4)	/* gSPI */
+-#define CST4330_CHIPMODE_USB(cs)	(((cs) & 0x7) == 6)	/* USB packet-oriented */
+-#define CST4330_CHIPMODE_USBDA(cs)	(((cs) & 0x7) == 7)	/* USB Direct Access */
+-#define	CST4330_OTP_PRESENT		0x00000010
+-#define	CST4330_LPO_AUTODET_EN		0x00000020
+-#define	CST4330_ARMREMAP_0		0x00000040
+-#define	CST4330_SPROM_PRESENT		0x00000080	/* takes priority over OTP if both set */
+-#define	CST4330_ILPDIV_EN		0x00000100
+-#define	CST4330_LPO_SEL			0x00000200
+-#define	CST4330_RES_INIT_MODE_SHIFT	10
+-#define	CST4330_RES_INIT_MODE_MASK	0x00000c00
+-#define CST4330_CBUCK_MODE_SHIFT	12
+-#define CST4330_CBUCK_MODE_MASK		0x00003000
+-#define	CST4330_CBUCK_POWER_OK		0x00004000
+-#define	CST4330_BB_PLL_LOCKED		0x00008000
+-#define SOCDEVRAM_4330_BP_ADDR		0x1E000000
+-#define SOCDEVRAM_4330_ARM_ADDR		0x00800000
+-
+-/* 4313 resources */
+-#define	RES4313_BB_PU_RSRC		0
+-#define	RES4313_ILP_REQ_RSRC		1
+-#define	RES4313_XTAL_PU_RSRC		2
+-#define	RES4313_ALP_AVAIL_RSRC		3
+-#define	RES4313_RADIO_PU_RSRC		4
+-#define	RES4313_BG_PU_RSRC		5
+-#define	RES4313_VREG1P4_PU_RSRC		6
+-#define	RES4313_AFE_PWRSW_RSRC		7
+-#define	RES4313_RX_PWRSW_RSRC		8
+-#define	RES4313_TX_PWRSW_RSRC		9
+-#define	RES4313_BB_PWRSW_RSRC		10
+-#define	RES4313_SYNTH_PWRSW_RSRC	11
+-#define	RES4313_MISC_PWRSW_RSRC		12
+-#define	RES4313_BB_PLL_PWRSW_RSRC	13
+-#define	RES4313_HT_AVAIL_RSRC		14
+-#define	RES4313_MACPHY_CLK_AVAIL_RSRC	15
+-
+-/* 4313 chip-specific ChipStatus register bits */
+-#define	CST4313_SPROM_PRESENT			1
+-#define	CST4313_OTP_PRESENT			2
+-#define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
+-#define	CST4313_SPROM_OTP_SEL_SHIFT		0
+-
+-/* 4313 Chip specific ChipControl register bits */
+-#define CCTRL_4313_12MA_LED_DRIVE    0x00000007	/* 12 mA drive strengh for later 4313 */
+-
+-/* 43228 resources */
+-#define RES43228_NOT_USED		0
+-#define RES43228_ILP_REQUEST		1
+-#define RES43228_XTAL_PU		2
+-#define RES43228_ALP_AVAIL		3
+-#define RES43228_PLL_EN			4
+-#define RES43228_HT_PHY_AVAIL		5
+-
+-/* 43228 chipstatus  reg bits */
+-#define CST43228_ILP_DIV_EN		0x1
+-#define	CST43228_OTP_PRESENT		0x2
+-#define	CST43228_SERDES_REFCLK_PADSEL	0x4
+-#define	CST43228_SDIO_MODE		0x8
+-
+-#define	CST43228_SDIO_OTP_PRESENT	0x10
+-#define	CST43228_SDIO_RESET		0x20
+-
+-/*
+-* Maximum delay for the PMU state transition in us.
+-* This is an upper bound intended for spinwaits etc.
+-*/
+-#define PMU_MAX_TRANSITION_DLY	15000
+-
+-/* PMU resource up transition time in ILP cycles */
+-#define PMURES_UP_TRANSITION	2
+-
+-/*
+-* Register eci_inputlo bitfield values.
+-* - BT packet type information bits [7:0]
+-*/
+-/*  [3:0] - Task (link) type */
+-#define BT_ACL				0x00
+-#define BT_SCO				0x01
+-#define BT_eSCO				0x02
+-#define BT_A2DP				0x03
+-#define BT_SNIFF			0x04
+-#define BT_PAGE_SCAN			0x05
+-#define BT_INQUIRY_SCAN			0x06
+-#define BT_PAGE				0x07
+-#define BT_INQUIRY			0x08
+-#define BT_MSS				0x09
+-#define BT_PARK				0x0a
+-#define BT_RSSISCAN			0x0b
+-#define BT_MD_ACL			0x0c
+-#define BT_MD_eSCO			0x0d
+-#define BT_SCAN_WITH_SCO_LINK		0x0e
+-#define BT_SCAN_WITHOUT_SCO_LINK	0x0f
+-/* [7:4] = packet duration code */
+-/* [8] - Master / Slave */
+-#define BT_MASTER			0
+-#define BT_SLAVE			1
+-/* [11:9] - multi-level priority */
+-#define BT_LOWEST_PRIO			0x0
+-#define BT_HIGHEST_PRIO			0x3
+-
+-/* WLAN - number of antenna */
+-#define WLAN_NUM_ANT1 TXANT_0
+-#define WLAN_NUM_ANT2 TXANT_1
+-
+-#endif				/* _SBCHIPC_H */
+diff --git a/drivers/staging/brcm80211/include/sbconfig.h b/drivers/staging/brcm80211/include/sbconfig.h
+deleted file mode 100644
+index 5247f01..0000000
+--- a/drivers/staging/brcm80211/include/sbconfig.h
++++ /dev/null
+@@ -1,272 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBCONFIG_H
+-#define	_SBCONFIG_H
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* enumeration in SB is based on the premise that cores are contiguos in the
+- * enumeration space.
+- */
+-#define SB_BUS_SIZE		0x10000	/* Each bus gets 64Kbytes for cores */
+-#define SB_BUS_BASE(b)		(SI_ENUM_BASE + (b) * SB_BUS_SIZE)
+-#define	SB_BUS_MAXCORES		(SB_BUS_SIZE / SI_CORE_SIZE)	/* Max cores per bus */
+-
+-/*
+- * Sonics Configuration Space Registers.
+- */
+-#define	SBCONFIGOFF		0xf00	/* core sbconfig regs are top 256bytes of regs */
+-#define	SBCONFIGSIZE		256	/* sizeof (sbconfig_t) */
+-
+-#define SBIPSFLAG		0x08
+-#define SBTPSFLAG		0x18
+-#define	SBTMERRLOGA		0x48	/* sonics >= 2.3 */
+-#define	SBTMERRLOG		0x50	/* sonics >= 2.3 */
+-#define SBADMATCH3		0x60
+-#define SBADMATCH2		0x68
+-#define SBADMATCH1		0x70
+-#define SBIMSTATE		0x90
+-#define SBINTVEC		0x94
+-#define SBTMSTATELOW		0x98
+-#define SBTMSTATEHIGH		0x9c
+-#define SBBWA0			0xa0
+-#define SBIMCONFIGLOW		0xa8
+-#define SBIMCONFIGHIGH		0xac
+-#define SBADMATCH0		0xb0
+-#define SBTMCONFIGLOW		0xb8
+-#define SBTMCONFIGHIGH		0xbc
+-#define SBBCONFIG		0xc0
+-#define SBBSTATE		0xc8
+-#define SBACTCNFG		0xd8
+-#define	SBFLAGST		0xe8
+-#define SBIDLOW			0xf8
+-#define SBIDHIGH		0xfc
+-
+-/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have
+- * a few registers *below* that line. I think it would be very confusing to try
+- * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here,
+- */
+-
+-#define SBIMERRLOGA		0xea8
+-#define SBIMERRLOG		0xeb0
+-#define SBTMPORTCONNID0		0xed8
+-#define SBTMPORTLOCK0		0xef8
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-typedef volatile struct _sbconfig {
+-	u32 PAD[2];
+-	u32 sbipsflag;	/* initiator port ocp slave flag */
+-	u32 PAD[3];
+-	u32 sbtpsflag;	/* target port ocp slave flag */
+-	u32 PAD[11];
+-	u32 sbtmerrloga;	/* (sonics >= 2.3) */
+-	u32 PAD;
+-	u32 sbtmerrlog;	/* (sonics >= 2.3) */
+-	u32 PAD[3];
+-	u32 sbadmatch3;	/* address match3 */
+-	u32 PAD;
+-	u32 sbadmatch2;	/* address match2 */
+-	u32 PAD;
+-	u32 sbadmatch1;	/* address match1 */
+-	u32 PAD[7];
+-	u32 sbimstate;	/* initiator agent state */
+-	u32 sbintvec;	/* interrupt mask */
+-	u32 sbtmstatelow;	/* target state */
+-	u32 sbtmstatehigh;	/* target state */
+-	u32 sbbwa0;		/* bandwidth allocation table0 */
+-	u32 PAD;
+-	u32 sbimconfiglow;	/* initiator configuration */
+-	u32 sbimconfighigh;	/* initiator configuration */
+-	u32 sbadmatch0;	/* address match0 */
+-	u32 PAD;
+-	u32 sbtmconfiglow;	/* target configuration */
+-	u32 sbtmconfighigh;	/* target configuration */
+-	u32 sbbconfig;	/* broadcast configuration */
+-	u32 PAD;
+-	u32 sbbstate;	/* broadcast state */
+-	u32 PAD[3];
+-	u32 sbactcnfg;	/* activate configuration */
+-	u32 PAD[3];
+-	u32 sbflagst;	/* current sbflags */
+-	u32 PAD[3];
+-	u32 sbidlow;		/* identification */
+-	u32 sbidhigh;	/* identification */
+-} sbconfig_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* sbipsflag */
+-#define	SBIPS_INT1_MASK		0x3f	/* which sbflags get routed to mips interrupt 1 */
+-#define	SBIPS_INT1_SHIFT	0
+-#define	SBIPS_INT2_MASK		0x3f00	/* which sbflags get routed to mips interrupt 2 */
+-#define	SBIPS_INT2_SHIFT	8
+-#define	SBIPS_INT3_MASK		0x3f0000	/* which sbflags get routed to mips interrupt 3 */
+-#define	SBIPS_INT3_SHIFT	16
+-#define	SBIPS_INT4_MASK		0x3f000000	/* which sbflags get routed to mips interrupt 4 */
+-#define	SBIPS_INT4_SHIFT	24
+-
+-/* sbtpsflag */
+-#define	SBTPS_NUM0_MASK		0x3f	/* interrupt sbFlag # generated by this core */
+-#define	SBTPS_F0EN0		0x40	/* interrupt is always sent on the backplane */
+-
+-/* sbtmerrlog */
+-#define	SBTMEL_CM		0x00000007	/* command */
+-#define	SBTMEL_CI		0x0000ff00	/* connection id */
+-#define	SBTMEL_EC		0x0f000000	/* error code */
+-#define	SBTMEL_ME		0x80000000	/* multiple error */
+-
+-/* sbimstate */
+-#define	SBIM_PC			0xf	/* pipecount */
+-#define	SBIM_AP_MASK		0x30	/* arbitration policy */
+-#define	SBIM_AP_BOTH		0x00	/* use both timeslaces and token */
+-#define	SBIM_AP_TS		0x10	/* use timesliaces only */
+-#define	SBIM_AP_TK		0x20	/* use token only */
+-#define	SBIM_AP_RSV		0x30	/* reserved */
+-#define	SBIM_IBE		0x20000	/* inbanderror */
+-#define	SBIM_TO			0x40000	/* timeout */
+-#define	SBIM_BY			0x01800000	/* busy (sonics >= 2.3) */
+-#define	SBIM_RJ			0x02000000	/* reject (sonics >= 2.3) */
+-
+-/* sbtmstatelow */
+-#define	SBTML_RESET		0x0001	/* reset */
+-#define	SBTML_REJ_MASK		0x0006	/* reject field */
+-#define	SBTML_REJ		0x0002	/* reject */
+-#define	SBTML_TMPREJ		0x0004	/* temporary reject, for error recovery */
+-
+-#define	SBTML_SICF_SHIFT	16	/* Shift to locate the SI control flags in sbtml */
+-
+-/* sbtmstatehigh */
+-#define	SBTMH_SERR		0x0001	/* serror */
+-#define	SBTMH_INT		0x0002	/* interrupt */
+-#define	SBTMH_BUSY		0x0004	/* busy */
+-#define	SBTMH_TO		0x0020	/* timeout (sonics >= 2.3) */
+-
+-#define	SBTMH_SISF_SHIFT	16	/* Shift to locate the SI status flags in sbtmh */
+-
+-/* sbbwa0 */
+-#define	SBBWA_TAB0_MASK		0xffff	/* lookup table 0 */
+-#define	SBBWA_TAB1_MASK		0xffff	/* lookup table 1 */
+-#define	SBBWA_TAB1_SHIFT	16
+-
+-/* sbimconfiglow */
+-#define	SBIMCL_STO_MASK		0x7	/* service timeout */
+-#define	SBIMCL_RTO_MASK		0x70	/* request timeout */
+-#define	SBIMCL_RTO_SHIFT	4
+-#define	SBIMCL_CID_MASK		0xff0000	/* connection id */
+-#define	SBIMCL_CID_SHIFT	16
+-
+-/* sbimconfighigh */
+-#define	SBIMCH_IEM_MASK		0xc	/* inband error mode */
+-#define	SBIMCH_TEM_MASK		0x30	/* timeout error mode */
+-#define	SBIMCH_TEM_SHIFT	4
+-#define	SBIMCH_BEM_MASK		0xc0	/* bus error mode */
+-#define	SBIMCH_BEM_SHIFT	6
+-
+-/* sbadmatch0 */
+-#define	SBAM_TYPE_MASK		0x3	/* address type */
+-#define	SBAM_AD64		0x4	/* reserved */
+-#define	SBAM_ADINT0_MASK	0xf8	/* type0 size */
+-#define	SBAM_ADINT0_SHIFT	3
+-#define	SBAM_ADINT1_MASK	0x1f8	/* type1 size */
+-#define	SBAM_ADINT1_SHIFT	3
+-#define	SBAM_ADINT2_MASK	0x1f8	/* type2 size */
+-#define	SBAM_ADINT2_SHIFT	3
+-#define	SBAM_ADEN		0x400	/* enable */
+-#define	SBAM_ADNEG		0x800	/* negative decode */
+-#define	SBAM_BASE0_MASK		0xffffff00	/* type0 base address */
+-#define	SBAM_BASE0_SHIFT	8
+-#define	SBAM_BASE1_MASK		0xfffff000	/* type1 base address for the core */
+-#define	SBAM_BASE1_SHIFT	12
+-#define	SBAM_BASE2_MASK		0xffff0000	/* type2 base address for the core */
+-#define	SBAM_BASE2_SHIFT	16
+-
+-/* sbtmconfiglow */
+-#define	SBTMCL_CD_MASK		0xff	/* clock divide */
+-#define	SBTMCL_CO_MASK		0xf800	/* clock offset */
+-#define	SBTMCL_CO_SHIFT		11
+-#define	SBTMCL_IF_MASK		0xfc0000	/* interrupt flags */
+-#define	SBTMCL_IF_SHIFT		18
+-#define	SBTMCL_IM_MASK		0x3000000	/* interrupt mode */
+-#define	SBTMCL_IM_SHIFT		24
+-
+-/* sbtmconfighigh */
+-#define	SBTMCH_BM_MASK		0x3	/* busy mode */
+-#define	SBTMCH_RM_MASK		0x3	/* retry mode */
+-#define	SBTMCH_RM_SHIFT		2
+-#define	SBTMCH_SM_MASK		0x30	/* stop mode */
+-#define	SBTMCH_SM_SHIFT		4
+-#define	SBTMCH_EM_MASK		0x300	/* sb error mode */
+-#define	SBTMCH_EM_SHIFT		8
+-#define	SBTMCH_IM_MASK		0xc00	/* int mode */
+-#define	SBTMCH_IM_SHIFT		10
+-
+-/* sbbconfig */
+-#define	SBBC_LAT_MASK		0x3	/* sb latency */
+-#define	SBBC_MAX0_MASK		0xf0000	/* maxccntr0 */
+-#define	SBBC_MAX0_SHIFT		16
+-#define	SBBC_MAX1_MASK		0xf00000	/* maxccntr1 */
+-#define	SBBC_MAX1_SHIFT		20
+-
+-/* sbbstate */
+-#define	SBBS_SRD		0x1	/* st reg disable */
+-#define	SBBS_HRD		0x2	/* hold reg disable */
+-
+-/* sbidlow */
+-#define	SBIDL_CS_MASK		0x3	/* config space */
+-#define	SBIDL_AR_MASK		0x38	/* # address ranges supported */
+-#define	SBIDL_AR_SHIFT		3
+-#define	SBIDL_SYNCH		0x40	/* sync */
+-#define	SBIDL_INIT		0x80	/* initiator */
+-#define	SBIDL_MINLAT_MASK	0xf00	/* minimum backplane latency */
+-#define	SBIDL_MINLAT_SHIFT	8
+-#define	SBIDL_MAXLAT		0xf000	/* maximum backplane latency */
+-#define	SBIDL_MAXLAT_SHIFT	12
+-#define	SBIDL_FIRST		0x10000	/* this initiator is first */
+-#define	SBIDL_CW_MASK		0xc0000	/* cycle counter width */
+-#define	SBIDL_CW_SHIFT		18
+-#define	SBIDL_TP_MASK		0xf00000	/* target ports */
+-#define	SBIDL_TP_SHIFT		20
+-#define	SBIDL_IP_MASK		0xf000000	/* initiator ports */
+-#define	SBIDL_IP_SHIFT		24
+-#define	SBIDL_RV_MASK		0xf0000000	/* sonics backplane revision code */
+-#define	SBIDL_RV_SHIFT		28
+-#define	SBIDL_RV_2_2		0x00000000	/* version 2.2 or earlier */
+-#define	SBIDL_RV_2_3		0x10000000	/* version 2.3 */
+-
+-/* sbidhigh */
+-#define	SBIDH_RC_MASK		0x000f	/* revision code */
+-#define	SBIDH_RCE_MASK		0x7000	/* revision code extension field */
+-#define	SBIDH_RCE_SHIFT		8
+-#define	SBCOREREV(sbidh) \
+-	((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
+-#define	SBIDH_CC_MASK		0x8ff0	/* core code */
+-#define	SBIDH_CC_SHIFT		4
+-#define	SBIDH_VC_MASK		0xffff0000	/* vendor code */
+-#define	SBIDH_VC_SHIFT		16
+-
+-#define	SB_COMMIT		0xfd8	/* update buffered registers value */
+-
+-/* vendor codes */
+-#define	SB_VEND_BCM		0x4243	/* Broadcom's SB vendor code */
+-
+-#endif				/* _SBCONFIG_H */
+diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h
+deleted file mode 100644
+index 08cb7f6..0000000
+--- a/drivers/staging/brcm80211/include/sbhnddma.h
++++ /dev/null
+@@ -1,315 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sbhnddma_h_
+-#define	_sbhnddma_h_
+-
+-/* DMA structure:
+- *  support two DMA engines: 32 bits address or 64 bit addressing
+- *  basic DMA register set is per channel(transmit or receive)
+- *  a pair of channels is defined for convenience
+- */
+-
+-/* 32 bits addressing */
+-
+-/* dma registers per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 control;		/* enable, et al */
+-	u32 addr;		/* descriptor ring base address (4K aligned) */
+-	u32 ptr;		/* last descriptor posted to chip */
+-	u32 status;		/* current active descriptor, et al */
+-} dma32regs_t;
+-
+-typedef volatile struct {
+-	dma32regs_t xmt;	/* dma tx channel */
+-	dma32regs_t rcv;	/* dma rx channel */
+-} dma32regp_t;
+-
+-typedef volatile struct {	/* diag access */
+-	u32 fifoaddr;	/* diag address */
+-	u32 fifodatalow;	/* low 32bits of data */
+-	u32 fifodatahigh;	/* high 32bits of data */
+-	u32 pad;		/* reserved */
+-} dma32diag_t;
+-
+-/*
+- * DMA Descriptor
+- * Descriptors are only read by the hardware, never written back.
+- */
+-typedef volatile struct {
+-	u32 ctrl;		/* misc control bits & bufcount */
+-	u32 addr;		/* data buffer address */
+-} dma32dd_t;
+-
+-/*
+- * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
+- */
+-#define	D32RINGALIGN_BITS	12
+-#define	D32MAXRINGSZ		(1 << D32RINGALIGN_BITS)
+-#define	D32RINGALIGN		(1 << D32RINGALIGN_BITS)
+-
+-#define	D32MAXDD	(D32MAXRINGSZ / sizeof (dma32dd_t))
+-
+-/* transmit channel control */
+-#define	XC_XE		((u32)1 << 0)	/* transmit enable */
+-#define	XC_SE		((u32)1 << 1)	/* transmit suspend request */
+-#define	XC_LE		((u32)1 << 2)	/* loopback enable */
+-#define	XC_FL		((u32)1 << 4)	/* flush request */
+-#define	XC_PD		((u32)1 << 11)	/* parity check disable */
+-#define	XC_AE		((u32)3 << 16)	/* address extension bits */
+-#define	XC_AE_SHIFT	16
+-
+-/* transmit descriptor table pointer */
+-#define	XP_LD_MASK	0xfff	/* last valid descriptor */
+-
+-/* transmit channel status */
+-#define	XS_CD_MASK	0x0fff	/* current descriptor pointer */
+-#define	XS_XS_MASK	0xf000	/* transmit state */
+-#define	XS_XS_SHIFT	12
+-#define	XS_XS_DISABLED	0x0000	/* disabled */
+-#define	XS_XS_ACTIVE	0x1000	/* active */
+-#define	XS_XS_IDLE	0x2000	/* idle wait */
+-#define	XS_XS_STOPPED	0x3000	/* stopped */
+-#define	XS_XS_SUSP	0x4000	/* suspend pending */
+-#define	XS_XE_MASK	0xf0000	/* transmit errors */
+-#define	XS_XE_SHIFT	16
+-#define	XS_XE_NOERR	0x00000	/* no error */
+-#define	XS_XE_DPE	0x10000	/* descriptor protocol error */
+-#define	XS_XE_DFU	0x20000	/* data fifo underrun */
+-#define	XS_XE_BEBR	0x30000	/* bus error on buffer read */
+-#define	XS_XE_BEDA	0x40000	/* bus error on descriptor access */
+-#define	XS_AD_MASK	0xfff00000	/* active descriptor */
+-#define	XS_AD_SHIFT	20
+-
+-/* receive channel control */
+-#define	RC_RE		((u32)1 << 0)	/* receive enable */
+-#define	RC_RO_MASK	0xfe	/* receive frame offset */
+-#define	RC_RO_SHIFT	1
+-#define	RC_FM		((u32)1 << 8)	/* direct fifo receive (pio) mode */
+-#define	RC_SH		((u32)1 << 9)	/* separate rx header descriptor enable */
+-#define	RC_OC		((u32)1 << 10)	/* overflow continue */
+-#define	RC_PD		((u32)1 << 11)	/* parity check disable */
+-#define	RC_AE		((u32)3 << 16)	/* address extension bits */
+-#define	RC_AE_SHIFT	16
+-
+-/* receive descriptor table pointer */
+-#define	RP_LD_MASK	0xfff	/* last valid descriptor */
+-
+-/* receive channel status */
+-#define	RS_CD_MASK	0x0fff	/* current descriptor pointer */
+-#define	RS_RS_MASK	0xf000	/* receive state */
+-#define	RS_RS_SHIFT	12
+-#define	RS_RS_DISABLED	0x0000	/* disabled */
+-#define	RS_RS_ACTIVE	0x1000	/* active */
+-#define	RS_RS_IDLE	0x2000	/* idle wait */
+-#define	RS_RS_STOPPED	0x3000	/* reserved */
+-#define	RS_RE_MASK	0xf0000	/* receive errors */
+-#define	RS_RE_SHIFT	16
+-#define	RS_RE_NOERR	0x00000	/* no error */
+-#define	RS_RE_DPE	0x10000	/* descriptor protocol error */
+-#define	RS_RE_DFO	0x20000	/* data fifo overflow */
+-#define	RS_RE_BEBW	0x30000	/* bus error on buffer write */
+-#define	RS_RE_BEDA	0x40000	/* bus error on descriptor access */
+-#define	RS_AD_MASK	0xfff00000	/* active descriptor */
+-#define	RS_AD_SHIFT	20
+-
+-/* fifoaddr */
+-#define	FA_OFF_MASK	0xffff	/* offset */
+-#define	FA_SEL_MASK	0xf0000	/* select */
+-#define	FA_SEL_SHIFT	16
+-#define	FA_SEL_XDD	0x00000	/* transmit dma data */
+-#define	FA_SEL_XDP	0x10000	/* transmit dma pointers */
+-#define	FA_SEL_RDD	0x40000	/* receive dma data */
+-#define	FA_SEL_RDP	0x50000	/* receive dma pointers */
+-#define	FA_SEL_XFD	0x80000	/* transmit fifo data */
+-#define	FA_SEL_XFP	0x90000	/* transmit fifo pointers */
+-#define	FA_SEL_RFD	0xc0000	/* receive fifo data */
+-#define	FA_SEL_RFP	0xd0000	/* receive fifo pointers */
+-#define	FA_SEL_RSD	0xe0000	/* receive frame status data */
+-#define	FA_SEL_RSP	0xf0000	/* receive frame status pointers */
+-
+-/* descriptor control flags */
+-#define	CTRL_BC_MASK	0x00001fff	/* buffer byte count, real data len must <= 4KB */
+-#define	CTRL_AE		((u32)3 << 16)	/* address extension bits */
+-#define	CTRL_AE_SHIFT	16
+-#define	CTRL_PARITY	((u32)3 << 18)	/* parity bit */
+-#define	CTRL_EOT	((u32)1 << 28)	/* end of descriptor table */
+-#define	CTRL_IOC	((u32)1 << 29)	/* interrupt on completion */
+-#define	CTRL_EOF	((u32)1 << 30)	/* end of frame */
+-#define	CTRL_SOF	((u32)1 << 31)	/* start of frame */
+-
+-/* control flags in the range [27:20] are core-specific and not defined here */
+-#define	CTRL_CORE_MASK	0x0ff00000
+-
+-/* 64 bits addressing */
+-
+-/* dma registers per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 control;		/* enable, et al */
+-	u32 ptr;		/* last descriptor posted to chip */
+-	u32 addrlow;		/* descriptor ring base address low 32-bits (8K aligned) */
+-	u32 addrhigh;	/* descriptor ring base address bits 63:32 (8K aligned) */
+-	u32 status0;		/* current descriptor, xmt state */
+-	u32 status1;		/* active descriptor, xmt error */
+-} dma64regs_t;
+-
+-typedef volatile struct {
+-	dma64regs_t tx;		/* dma64 tx channel */
+-	dma64regs_t rx;		/* dma64 rx channel */
+-} dma64regp_t;
+-
+-typedef volatile struct {	/* diag access */
+-	u32 fifoaddr;	/* diag address */
+-	u32 fifodatalow;	/* low 32bits of data */
+-	u32 fifodatahigh;	/* high 32bits of data */
+-	u32 pad;		/* reserved */
+-} dma64diag_t;
+-
+-/*
+- * DMA Descriptor
+- * Descriptors are only read by the hardware, never written back.
+- */
+-typedef volatile struct {
+-	u32 ctrl1;		/* misc control bits & bufcount */
+-	u32 ctrl2;		/* buffer count and address extension */
+-	u32 addrlow;		/* memory address of the date buffer, bits 31:0 */
+-	u32 addrhigh;	/* memory address of the date buffer, bits 63:32 */
+-} dma64dd_t;
+-
+-/*
+- * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address.
+- */
+-#define D64RINGALIGN_BITS	13
+-#define	D64MAXRINGSZ		(1 << D64RINGALIGN_BITS)
+-#define	D64RINGALIGN		(1 << D64RINGALIGN_BITS)
+-
+-#define	D64MAXDD	(D64MAXRINGSZ / sizeof (dma64dd_t))
+-
+-/* transmit channel control */
+-#define	D64_XC_XE		0x00000001	/* transmit enable */
+-#define	D64_XC_SE		0x00000002	/* transmit suspend request */
+-#define	D64_XC_LE		0x00000004	/* loopback enable */
+-#define	D64_XC_FL		0x00000010	/* flush request */
+-#define	D64_XC_PD		0x00000800	/* parity check disable */
+-#define	D64_XC_AE		0x00030000	/* address extension bits */
+-#define	D64_XC_AE_SHIFT		16
+-
+-/* transmit descriptor table pointer */
+-#define	D64_XP_LD_MASK		0x00000fff	/* last valid descriptor */
+-
+-/* transmit channel status */
+-#define	D64_XS0_CD_MASK		0x00001fff	/* current descriptor pointer */
+-#define	D64_XS0_XS_MASK		0xf0000000	/* transmit state */
+-#define	D64_XS0_XS_SHIFT		28
+-#define	D64_XS0_XS_DISABLED	0x00000000	/* disabled */
+-#define	D64_XS0_XS_ACTIVE	0x10000000	/* active */
+-#define	D64_XS0_XS_IDLE		0x20000000	/* idle wait */
+-#define	D64_XS0_XS_STOPPED	0x30000000	/* stopped */
+-#define	D64_XS0_XS_SUSP		0x40000000	/* suspend pending */
+-
+-#define	D64_XS1_AD_MASK		0x00001fff	/* active descriptor */
+-#define	D64_XS1_XE_MASK		0xf0000000	/* transmit errors */
+-#define	D64_XS1_XE_SHIFT		28
+-#define	D64_XS1_XE_NOERR	0x00000000	/* no error */
+-#define	D64_XS1_XE_DPE		0x10000000	/* descriptor protocol error */
+-#define	D64_XS1_XE_DFU		0x20000000	/* data fifo underrun */
+-#define	D64_XS1_XE_DTE		0x30000000	/* data transfer error */
+-#define	D64_XS1_XE_DESRE	0x40000000	/* descriptor read error */
+-#define	D64_XS1_XE_COREE	0x50000000	/* core error */
+-
+-/* receive channel control */
+-#define	D64_RC_RE		0x00000001	/* receive enable */
+-#define	D64_RC_RO_MASK		0x000000fe	/* receive frame offset */
+-#define	D64_RC_RO_SHIFT		1
+-#define	D64_RC_FM		0x00000100	/* direct fifo receive (pio) mode */
+-#define	D64_RC_SH		0x00000200	/* separate rx header descriptor enable */
+-#define	D64_RC_OC		0x00000400	/* overflow continue */
+-#define	D64_RC_PD		0x00000800	/* parity check disable */
+-#define	D64_RC_AE		0x00030000	/* address extension bits */
+-#define	D64_RC_AE_SHIFT		16
+-
+-/* flags for dma controller */
+-#define DMA_CTRL_PEN		(1 << 0)	/* partity enable */
+-#define DMA_CTRL_ROC		(1 << 1)	/* rx overflow continue */
+-#define DMA_CTRL_RXMULTI	(1 << 2)	/* allow rx scatter to multiple descriptors */
+-#define DMA_CTRL_UNFRAMED	(1 << 3)	/* Unframed Rx/Tx data */
+-
+-/* receive descriptor table pointer */
+-#define	D64_RP_LD_MASK		0x00000fff	/* last valid descriptor */
+-
+-/* receive channel status */
+-#define	D64_RS0_CD_MASK		0x00001fff	/* current descriptor pointer */
+-#define	D64_RS0_RS_MASK		0xf0000000	/* receive state */
+-#define	D64_RS0_RS_SHIFT		28
+-#define	D64_RS0_RS_DISABLED	0x00000000	/* disabled */
+-#define	D64_RS0_RS_ACTIVE	0x10000000	/* active */
+-#define	D64_RS0_RS_IDLE		0x20000000	/* idle wait */
+-#define	D64_RS0_RS_STOPPED	0x30000000	/* stopped */
+-#define	D64_RS0_RS_SUSP		0x40000000	/* suspend pending */
+-
+-#define	D64_RS1_AD_MASK		0x0001ffff	/* active descriptor */
+-#define	D64_RS1_RE_MASK		0xf0000000	/* receive errors */
+-#define	D64_RS1_RE_SHIFT		28
+-#define	D64_RS1_RE_NOERR	0x00000000	/* no error */
+-#define	D64_RS1_RE_DPO		0x10000000	/* descriptor protocol error */
+-#define	D64_RS1_RE_DFU		0x20000000	/* data fifo overflow */
+-#define	D64_RS1_RE_DTE		0x30000000	/* data transfer error */
+-#define	D64_RS1_RE_DESRE	0x40000000	/* descriptor read error */
+-#define	D64_RS1_RE_COREE	0x50000000	/* core error */
+-
+-/* fifoaddr */
+-#define	D64_FA_OFF_MASK		0xffff	/* offset */
+-#define	D64_FA_SEL_MASK		0xf0000	/* select */
+-#define	D64_FA_SEL_SHIFT	16
+-#define	D64_FA_SEL_XDD		0x00000	/* transmit dma data */
+-#define	D64_FA_SEL_XDP		0x10000	/* transmit dma pointers */
+-#define	D64_FA_SEL_RDD		0x40000	/* receive dma data */
+-#define	D64_FA_SEL_RDP		0x50000	/* receive dma pointers */
+-#define	D64_FA_SEL_XFD		0x80000	/* transmit fifo data */
+-#define	D64_FA_SEL_XFP		0x90000	/* transmit fifo pointers */
+-#define	D64_FA_SEL_RFD		0xc0000	/* receive fifo data */
+-#define	D64_FA_SEL_RFP		0xd0000	/* receive fifo pointers */
+-#define	D64_FA_SEL_RSD		0xe0000	/* receive frame status data */
+-#define	D64_FA_SEL_RSP		0xf0000	/* receive frame status pointers */
+-
+-/* descriptor control flags 1 */
+-#define D64_CTRL_COREFLAGS	0x0ff00000	/* core specific flags */
+-#define	D64_CTRL1_EOT		((u32)1 << 28)	/* end of descriptor table */
+-#define	D64_CTRL1_IOC		((u32)1 << 29)	/* interrupt on completion */
+-#define	D64_CTRL1_EOF		((u32)1 << 30)	/* end of frame */
+-#define	D64_CTRL1_SOF		((u32)1 << 31)	/* start of frame */
+-
+-/* descriptor control flags 2 */
+-#define	D64_CTRL2_BC_MASK	0x00007fff	/* buffer byte count. real data len must <= 16KB */
+-#define	D64_CTRL2_AE		0x00030000	/* address extension bits */
+-#define	D64_CTRL2_AE_SHIFT	16
+-#define D64_CTRL2_PARITY	0x00040000	/* parity bit */
+-
+-/* control flags in the range [27:20] are core-specific and not defined here */
+-#define	D64_CTRL_CORE_MASK	0x0ff00000
+-
+-#define D64_RX_FRM_STS_LEN	0x0000ffff	/* frame length mask */
+-#define D64_RX_FRM_STS_OVFL	0x00800000	/* RxOverFlow */
+-#define D64_RX_FRM_STS_DSCRCNT	0x0f000000  /* no. of descriptors used - 1 */
+-#define D64_RX_FRM_STS_DATATYPE	0xf0000000	/* core-dependent data type */
+-
+-/* receive frame status */
+-typedef volatile struct {
+-	u16 len;
+-	u16 flags;
+-} dma_rxh_t;
+-
+-#endif				/* _sbhnddma_h_ */
+diff --git a/drivers/staging/brcm80211/include/sbsdio.h b/drivers/staging/brcm80211/include/sbsdio.h
+deleted file mode 100644
+index c7facd3..0000000
+--- a/drivers/staging/brcm80211/include/sbsdio.h
++++ /dev/null
+@@ -1,152 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBSDIO_H
+-#define	_SBSDIO_H
+-
+-#define SBSDIO_NUM_FUNCTION		3	/* as of sdiod rev 0, supports 3 functions */
+-
+-/* function 1 miscellaneous registers */
+-#define SBSDIO_SPROM_CS			0x10000	/* sprom command and status */
+-#define SBSDIO_SPROM_INFO		0x10001	/* sprom info register */
+-#define SBSDIO_SPROM_DATA_LOW		0x10002	/* sprom indirect access data byte 0 */
+-#define SBSDIO_SPROM_DATA_HIGH		0x10003	/* sprom indirect access data byte 1 */
+-#define SBSDIO_SPROM_ADDR_LOW		0x10004	/* sprom indirect access addr byte 0 */
+-#define SBSDIO_SPROM_ADDR_HIGH		0x10005	/* sprom indirect access addr byte 0 */
+-#define SBSDIO_CHIP_CTRL_DATA		0x10006	/* xtal_pu (gpio) output */
+-#define SBSDIO_CHIP_CTRL_EN		0x10007	/* xtal_pu (gpio) enable */
+-#define SBSDIO_WATERMARK		0x10008	/* rev < 7, watermark for sdio device */
+-#define SBSDIO_DEVICE_CTL		0x10009	/* control busy signal generation */
+-
+-/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
+-#define SBSDIO_FUNC1_SBADDRLOW		0x1000A	/* SB Address Window Low (b15) */
+-#define SBSDIO_FUNC1_SBADDRMID		0x1000B	/* SB Address Window Mid (b23:b16) */
+-#define SBSDIO_FUNC1_SBADDRHIGH		0x1000C	/* SB Address Window High (b31:b24)    */
+-#define SBSDIO_FUNC1_FRAMECTRL		0x1000D	/* Frame Control (frame term/abort) */
+-#define SBSDIO_FUNC1_CHIPCLKCSR		0x1000E	/* ChipClockCSR (ALP/HT ctl/status) */
+-#define SBSDIO_FUNC1_SDIOPULLUP 	0x1000F	/* SdioPullUp (on cmd, d0-d2) */
+-#define SBSDIO_FUNC1_WFRAMEBCLO		0x10019	/* Write Frame Byte Count Low */
+-#define SBSDIO_FUNC1_WFRAMEBCHI		0x1001A	/* Write Frame Byte Count High */
+-#define SBSDIO_FUNC1_RFRAMEBCLO		0x1001B	/* Read Frame Byte Count Low */
+-#define SBSDIO_FUNC1_RFRAMEBCHI		0x1001C	/* Read Frame Byte Count High */
+-
+-#define SBSDIO_FUNC1_MISC_REG_START	0x10000	/* f1 misc register start */
+-#define SBSDIO_FUNC1_MISC_REG_LIMIT	0x1001C	/* f1 misc register end */
+-
+-/* SBSDIO_SPROM_CS */
+-#define SBSDIO_SPROM_IDLE		0
+-#define SBSDIO_SPROM_WRITE		1
+-#define SBSDIO_SPROM_READ		2
+-#define SBSDIO_SPROM_WEN		4
+-#define SBSDIO_SPROM_WDS		7
+-#define SBSDIO_SPROM_DONE		8
+-
+-/* SBSDIO_SPROM_INFO */
+-#define SROM_SZ_MASK			0x03	/* SROM size, 1: 4k, 2: 16k */
+-#define SROM_BLANK			0x04	/* depreciated in corerev 6 */
+-#define	SROM_OTP			0x80	/* OTP present */
+-
+-/* SBSDIO_CHIP_CTRL */
+-#define SBSDIO_CHIP_CTRL_XTAL		0x01	/* or'd with onchip xtal_pu,
+-						 * 1: power on oscillator
+-						 * (for 4318 only)
+-						 */
+-/* SBSDIO_WATERMARK */
+-#define SBSDIO_WATERMARK_MASK		0x7f	/* number of words - 1 for sd device
+-						 * to wait before sending data to host
+-						 */
+-
+-/* SBSDIO_DEVICE_CTL */
+-#define SBSDIO_DEVCTL_SETBUSY		0x01	/* 1: device will assert busy signal when
+-						 * receiving CMD53
+-						 */
+-#define SBSDIO_DEVCTL_SPI_INTR_SYNC	0x02	/* 1: assertion of sdio interrupt is
+-						 * synchronous to the sdio clock
+-						 */
+-#define SBSDIO_DEVCTL_CA_INT_ONLY	0x04	/* 1: mask all interrupts to host
+-						 * except the chipActive (rev 8)
+-						 */
+-#define SBSDIO_DEVCTL_PADS_ISO		0x08	/* 1: isolate internal sdio signals, put
+-						 * external pads in tri-state; requires
+-						 * sdio bus power cycle to clear (rev 9)
+-						 */
+-#define SBSDIO_DEVCTL_SB_RST_CTL	0x30	/* Force SD->SB reset mapping (rev 11) */
+-#define SBSDIO_DEVCTL_RST_CORECTL	0x00	/*   Determined by CoreControl bit */
+-#define SBSDIO_DEVCTL_RST_BPRESET	0x10	/*   Force backplane reset */
+-#define SBSDIO_DEVCTL_RST_NOBPRESET	0x20	/*   Force no backplane reset */
+-
+-/* SBSDIO_FUNC1_CHIPCLKCSR */
+-#define SBSDIO_FORCE_ALP		0x01	/* Force ALP request to backplane */
+-#define SBSDIO_FORCE_HT			0x02	/* Force HT request to backplane */
+-#define SBSDIO_FORCE_ILP		0x04	/* Force ILP request to backplane */
+-#define SBSDIO_ALP_AVAIL_REQ		0x08	/* Make ALP ready (power up xtal) */
+-#define SBSDIO_HT_AVAIL_REQ		0x10	/* Make HT ready (power up PLL) */
+-#define SBSDIO_FORCE_HW_CLKREQ_OFF	0x20	/* Squelch clock requests from HW */
+-#define SBSDIO_ALP_AVAIL		0x40	/* Status: ALP is ready */
+-#define SBSDIO_HT_AVAIL			0x80	/* Status: HT is ready */
+-/* In rev8, actual avail bits followed original docs */
+-#define SBSDIO_Rev8_HT_AVAIL		0x40
+-#define SBSDIO_Rev8_ALP_AVAIL		0x80
+-
+-#define SBSDIO_AVBITS			(SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
+-#define SBSDIO_ALPAV(regval)		((regval) & SBSDIO_AVBITS)
+-#define SBSDIO_HTAV(regval)		(((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
+-#define SBSDIO_ALPONLY(regval)		(SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
+-#define SBSDIO_CLKAV(regval, alponly)	(SBSDIO_ALPAV(regval) && \
+-					(alponly ? 1 : SBSDIO_HTAV(regval)))
+-
+-/* SBSDIO_FUNC1_SDIOPULLUP */
+-#define SBSDIO_PULLUP_D0		0x01	/* Enable D0/MISO pullup */
+-#define SBSDIO_PULLUP_D1		0x02	/* Enable D1/INT# pullup */
+-#define SBSDIO_PULLUP_D2		0x04	/* Enable D2 pullup */
+-#define SBSDIO_PULLUP_CMD		0x08	/* Enable CMD/MOSI pullup */
+-#define SBSDIO_PULLUP_ALL		0x0f	/* All valid bits */
+-
+-/* function 1 OCP space */
+-#define SBSDIO_SB_OFT_ADDR_MASK		0x07FFF	/* sb offset addr is <= 15 bits, 32k */
+-#define SBSDIO_SB_OFT_ADDR_LIMIT	0x08000
+-#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000	/* with b15, maps to 32-bit SB access */
+-
+-/* some duplication with sbsdpcmdev.h here */
+-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+-#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */
+-#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */
+-#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */
+-#define SBSDIO_SBWINDOW_MASK		0xffff8000	/* Address bits from SBADDR regs */
+-
+-/* direct(mapped) cis space */
+-#define SBSDIO_CIS_BASE_COMMON		0x1000	/* MAPPED common CIS address */
+-#define SBSDIO_CIS_SIZE_LIMIT		0x200	/* maximum bytes in one CIS */
+-#define SBSDIO_OTP_CIS_SIZE_LIMIT       0x078	/* maximum bytes OTP CIS */
+-
+-#define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF	/* cis offset addr is < 17 bits */
+-
+-#define SBSDIO_CIS_MANFID_TUPLE_LEN	6	/* manfid tuple length, include tuple,
+-						 * link bytes
+-						 */
+-
+-/* indirect cis access (in sprom) */
+-#define SBSDIO_SPROM_CIS_OFFSET		0x8	/* 8 control bytes first, CIS starts from
+-						 * 8th byte
+-						 */
+-
+-#define SBSDIO_BYTEMODE_DATALEN_MAX	64	/* sdio byte mode: maximum length of one
+-						 * data command
+-						 */
+-
+-#define SBSDIO_CORE_ADDR_MASK		0x1FFFF	/* sdio core function one address mask */
+-
+-#endif				/* _SBSDIO_H */
+diff --git a/drivers/staging/brcm80211/include/sbsdpcmdev.h b/drivers/staging/brcm80211/include/sbsdpcmdev.h
+deleted file mode 100644
+index afd3581..0000000
+--- a/drivers/staging/brcm80211/include/sbsdpcmdev.h
++++ /dev/null
+@@ -1,281 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sbsdpcmdev_h_
+-#define	_sbsdpcmdev_h_
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif				/* PAD */
+-
+-typedef volatile struct {
+-	dma64regs_t xmt;	/* dma tx */
+-	u32 PAD[2];
+-	dma64regs_t rcv;	/* dma rx */
+-	u32 PAD[2];
+-} dma64p_t;
+-
+-/* dma64 sdiod corerev >= 1 */
+-typedef volatile struct {
+-	dma64p_t dma64regs[2];
+-	dma64diag_t dmafifo;	/* DMA Diagnostic Regs, 0x280-0x28c */
+-	u32 PAD[92];
+-} sdiodma64_t;
+-
+-/* dma32 sdiod corerev == 0 */
+-typedef volatile struct {
+-	dma32regp_t dma32regs[2];	/* dma tx & rx, 0x200-0x23c */
+-	dma32diag_t dmafifo;	/* DMA Diagnostic Regs, 0x240-0x24c */
+-	u32 PAD[108];
+-} sdiodma32_t;
+-
+-/* dma32 regs for pcmcia core */
+-typedef volatile struct {
+-	dma32regp_t dmaregs;	/* DMA Regs, 0x200-0x21c, rev8 */
+-	dma32diag_t dmafifo;	/* DMA Diagnostic Regs, 0x220-0x22c */
+-	u32 PAD[116];
+-} pcmdma32_t;
+-
+-/* core registers */
+-typedef volatile struct {
+-	u32 corecontrol;	/* CoreControl, 0x000, rev8 */
+-	u32 corestatus;	/* CoreStatus, 0x004, rev8  */
+-	u32 PAD[1];
+-	u32 biststatus;	/* BistStatus, 0x00c, rev8  */
+-
+-	/* PCMCIA access */
+-	u16 pcmciamesportaladdr;	/* PcmciaMesPortalAddr, 0x010, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciamesportalmask;	/* PcmciaMesPortalMask, 0x014, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciawrframebc;	/* PcmciaWrFrameBC, 0x018, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciaunderflowtimer;	/* PcmciaUnderflowTimer, 0x01c, rev8   */
+-	u16 PAD[1];
+-
+-	/* interrupt */
+-	u32 intstatus;	/* IntStatus, 0x020, rev8   */
+-	u32 hostintmask;	/* IntHostMask, 0x024, rev8   */
+-	u32 intmask;		/* IntSbMask, 0x028, rev8   */
+-	u32 sbintstatus;	/* SBIntStatus, 0x02c, rev8   */
+-	u32 sbintmask;	/* SBIntMask, 0x030, rev8   */
+-	u32 funcintmask;	/* SDIO Function Interrupt Mask, SDIO rev4 */
+-	u32 PAD[2];
+-	u32 tosbmailbox;	/* ToSBMailbox, 0x040, rev8   */
+-	u32 tohostmailbox;	/* ToHostMailbox, 0x044, rev8   */
+-	u32 tosbmailboxdata;	/* ToSbMailboxData, 0x048, rev8   */
+-	u32 tohostmailboxdata;	/* ToHostMailboxData, 0x04c, rev8   */
+-
+-	/* synchronized access to registers in SDIO clock domain */
+-	u32 sdioaccess;	/* SdioAccess, 0x050, rev8   */
+-	u32 PAD[3];
+-
+-	/* PCMCIA frame control */
+-	u8 pcmciaframectrl;	/* pcmciaFrameCtrl, 0x060, rev8   */
+-	u8 PAD[3];
+-	u8 pcmciawatermark;	/* pcmciaWaterMark, 0x064, rev8   */
+-	u8 PAD[155];
+-
+-	/* interrupt batching control */
+-	u32 intrcvlazy;	/* IntRcvLazy, 0x100, rev8 */
+-	u32 PAD[3];
+-
+-	/* counters */
+-	u32 cmd52rd;		/* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */
+-	u32 cmd52wr;		/* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */
+-	u32 cmd53rd;		/* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */
+-	u32 cmd53wr;		/* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */
+-	u32 abort;		/* AbortCount, 0x120, rev8, SDIO: aborts */
+-	u32 datacrcerror;	/* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */
+-	u32 rdoutofsync;	/* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */
+-	u32 wroutofsync;	/* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */
+-	u32 writebusy;	/* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */
+-	u32 readwait;	/* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */
+-	u32 readterm;	/* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */
+-	u32 writeterm;	/* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */
+-	u32 PAD[40];
+-	u32 clockctlstatus;	/* ClockCtlStatus, 0x1e0, rev8 */
+-	u32 PAD[7];
+-
+-	/* DMA engines */
+-	volatile union {
+-		pcmdma32_t pcm32;
+-		sdiodma32_t sdiod32;
+-		sdiodma64_t sdiod64;
+-	} dma;
+-
+-	/* SDIO/PCMCIA CIS region */
+-	char cis[512];		/* 512 byte CIS, 0x400-0x5ff, rev6 */
+-
+-	/* PCMCIA function control registers */
+-	char pcmciafcr[256];	/* PCMCIA FCR, 0x600-6ff, rev6 */
+-	u16 PAD[55];
+-
+-	/* PCMCIA backplane access */
+-	u16 backplanecsr;	/* BackplaneCSR, 0x76E, rev6 */
+-	u16 backplaneaddr0;	/* BackplaneAddr0, 0x770, rev6 */
+-	u16 backplaneaddr1;	/* BackplaneAddr1, 0x772, rev6 */
+-	u16 backplaneaddr2;	/* BackplaneAddr2, 0x774, rev6 */
+-	u16 backplaneaddr3;	/* BackplaneAddr3, 0x776, rev6 */
+-	u16 backplanedata0;	/* BackplaneData0, 0x778, rev6 */
+-	u16 backplanedata1;	/* BackplaneData1, 0x77a, rev6 */
+-	u16 backplanedata2;	/* BackplaneData2, 0x77c, rev6 */
+-	u16 backplanedata3;	/* BackplaneData3, 0x77e, rev6 */
+-	u16 PAD[31];
+-
+-	/* sprom "size" & "blank" info */
+-	u16 spromstatus;	/* SPROMStatus, 0x7BE, rev2 */
+-	u32 PAD[464];
+-
+-	/* Sonics SiliconBackplane registers */
+-	sbconfig_t sbconfig;	/* SbConfig Regs, 0xf00-0xfff, rev8 */
+-} sdpcmd_regs_t;
+-
+-/* corecontrol */
+-#define CC_CISRDY		(1 << 0)	/* CIS Ready */
+-#define CC_BPRESEN		(1 << 1)	/* CCCR RES signal causes backplane reset */
+-#define CC_F2RDY		(1 << 2)	/* set CCCR IOR2 bit */
+-#define CC_CLRPADSISO		(1 << 3)	/* clear SDIO pads isolation bit (rev 11) */
+-#define CC_XMTDATAAVAIL_MODE	(1 << 4)	/* data avail generates an interrupt */
+-#define CC_XMTDATAAVAIL_CTRL	(1 << 5)	/* data avail interrupt ctrl */
+-
+-/* corestatus */
+-#define CS_PCMCIAMODE	(1 << 0)	/* Device Mode; 0=SDIO, 1=PCMCIA */
+-#define CS_SMARTDEV	(1 << 1)	/* 1=smartDev enabled */
+-#define CS_F2ENABLED	(1 << 2)	/* 1=host has enabled the device */
+-
+-#define PCMCIA_MES_PA_MASK	0x7fff	/* PCMCIA Message Portal Address Mask */
+-#define PCMCIA_MES_PM_MASK	0x7fff	/* PCMCIA Message Portal Mask Mask */
+-#define PCMCIA_WFBC_MASK	0xffff	/* PCMCIA Write Frame Byte Count Mask */
+-#define PCMCIA_UT_MASK		0x07ff	/* PCMCIA Underflow Timer Mask */
+-
+-/* intstatus */
+-#define I_SMB_SW0	(1 << 0)	/* To SB Mail S/W interrupt 0 */
+-#define I_SMB_SW1	(1 << 1)	/* To SB Mail S/W interrupt 1 */
+-#define I_SMB_SW2	(1 << 2)	/* To SB Mail S/W interrupt 2 */
+-#define I_SMB_SW3	(1 << 3)	/* To SB Mail S/W interrupt 3 */
+-#define I_SMB_SW_MASK	0x0000000f	/* To SB Mail S/W interrupts mask */
+-#define I_SMB_SW_SHIFT	0	/* To SB Mail S/W interrupts shift */
+-#define I_HMB_SW0	(1 << 4)	/* To Host Mail S/W interrupt 0 */
+-#define I_HMB_SW1	(1 << 5)	/* To Host Mail S/W interrupt 1 */
+-#define I_HMB_SW2	(1 << 6)	/* To Host Mail S/W interrupt 2 */
+-#define I_HMB_SW3	(1 << 7)	/* To Host Mail S/W interrupt 3 */
+-#define I_HMB_SW_MASK	0x000000f0	/* To Host Mail S/W interrupts mask */
+-#define I_HMB_SW_SHIFT	4	/* To Host Mail S/W interrupts shift */
+-#define I_WR_OOSYNC	(1 << 8)	/* Write Frame Out Of Sync */
+-#define I_RD_OOSYNC	(1 << 9)	/* Read Frame Out Of Sync */
+-#define	I_PC		(1 << 10)	/* descriptor error */
+-#define	I_PD		(1 << 11)	/* data error */
+-#define	I_DE		(1 << 12)	/* Descriptor protocol Error */
+-#define	I_RU		(1 << 13)	/* Receive descriptor Underflow */
+-#define	I_RO		(1 << 14)	/* Receive fifo Overflow */
+-#define	I_XU		(1 << 15)	/* Transmit fifo Underflow */
+-#define	I_RI		(1 << 16)	/* Receive Interrupt */
+-#define I_BUSPWR	(1 << 17)	/* SDIO Bus Power Change (rev 9) */
+-#define I_XMTDATA_AVAIL (1 << 23)	/* bits in fifo */
+-#define	I_XI		(1 << 24)	/* Transmit Interrupt */
+-#define I_RF_TERM	(1 << 25)	/* Read Frame Terminate */
+-#define I_WF_TERM	(1 << 26)	/* Write Frame Terminate */
+-#define I_PCMCIA_XU	(1 << 27)	/* PCMCIA Transmit FIFO Underflow */
+-#define I_SBINT		(1 << 28)	/* sbintstatus Interrupt */
+-#define I_CHIPACTIVE	(1 << 29)	/* chip transitioned from doze to active state */
+-#define I_SRESET	(1 << 30)	/* CCCR RES interrupt */
+-#define I_IOE2		(1U << 31)	/* CCCR IOE2 Bit Changed */
+-#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)	/* DMA Errors */
+-#define I_DMA		(I_RI | I_XI | I_ERRORS)
+-
+-/* sbintstatus */
+-#define I_SB_SERR	(1 << 8)	/* Backplane SError (write) */
+-#define I_SB_RESPERR	(1 << 9)	/* Backplane Response Error (read) */
+-#define I_SB_SPROMERR	(1 << 10)	/* Error accessing the sprom */
+-
+-/* sdioaccess */
+-#define SDA_DATA_MASK	0x000000ff	/* Read/Write Data Mask */
+-#define SDA_ADDR_MASK	0x000fff00	/* Read/Write Address Mask */
+-#define SDA_ADDR_SHIFT	8	/* Read/Write Address Shift */
+-#define SDA_WRITE	0x01000000	/* Write bit  */
+-#define SDA_READ	0x00000000	/* Write bit cleared for Read */
+-#define SDA_BUSY	0x80000000	/* Busy bit */
+-
+-/* sdioaccess-accessible register address spaces */
+-#define SDA_CCCR_SPACE		0x000	/* sdioAccess CCCR register space */
+-#define SDA_F1_FBR_SPACE	0x100	/* sdioAccess F1 FBR register space */
+-#define SDA_F2_FBR_SPACE	0x200	/* sdioAccess F2 FBR register space */
+-#define SDA_F1_REG_SPACE	0x300	/* sdioAccess F1 core-specific register space */
+-
+-/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */
+-#define SDA_CHIPCONTROLDATA	0x006	/* ChipControlData */
+-#define SDA_CHIPCONTROLENAB	0x007	/* ChipControlEnable */
+-#define SDA_F2WATERMARK		0x008	/* Function 2 Watermark */
+-#define SDA_DEVICECONTROL	0x009	/* DeviceControl */
+-#define SDA_SBADDRLOW		0x00a	/* SbAddrLow */
+-#define SDA_SBADDRMID		0x00b	/* SbAddrMid */
+-#define SDA_SBADDRHIGH		0x00c	/* SbAddrHigh */
+-#define SDA_FRAMECTRL		0x00d	/* FrameCtrl */
+-#define SDA_CHIPCLOCKCSR	0x00e	/* ChipClockCSR */
+-#define SDA_SDIOPULLUP		0x00f	/* SdioPullUp */
+-#define SDA_SDIOWRFRAMEBCLOW	0x019	/* SdioWrFrameBCLow */
+-#define SDA_SDIOWRFRAMEBCHIGH	0x01a	/* SdioWrFrameBCHigh */
+-#define SDA_SDIORDFRAMEBCLOW	0x01b	/* SdioRdFrameBCLow */
+-#define SDA_SDIORDFRAMEBCHIGH	0x01c	/* SdioRdFrameBCHigh */
+-
+-/* SDA_F2WATERMARK */
+-#define SDA_F2WATERMARK_MASK	0x7f	/* F2Watermark Mask */
+-
+-/* SDA_SBADDRLOW */
+-#define SDA_SBADDRLOW_MASK	0x80	/* SbAddrLow Mask */
+-
+-/* SDA_SBADDRMID */
+-#define SDA_SBADDRMID_MASK	0xff	/* SbAddrMid Mask */
+-
+-/* SDA_SBADDRHIGH */
+-#define SDA_SBADDRHIGH_MASK	0xff	/* SbAddrHigh Mask */
+-
+-/* SDA_FRAMECTRL */
+-#define SFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
+-#define SFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
+-#define SFC_CRC4WOOS	(1 << 2)	/* HW reports CRC error for write out of sync */
+-#define SFC_ABORTALL	(1 << 3)	/* Abort cancels all in-progress frames */
+-
+-/* pcmciaframectrl */
+-#define PFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
+-#define PFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
+-
+-/* intrcvlazy */
+-#define	IRL_TO_MASK	0x00ffffff	/* timeout */
+-#define	IRL_FC_MASK	0xff000000	/* frame count */
+-#define	IRL_FC_SHIFT	24	/* frame count */
+-
+-/* rx header */
+-typedef volatile struct {
+-	u16 len;
+-	u16 flags;
+-} sdpcmd_rxh_t;
+-
+-/* rx header flags */
+-#define RXF_CRC		0x0001	/* CRC error detected */
+-#define RXF_WOOS	0x0002	/* write frame out of sync */
+-#define RXF_WF_TERM	0x0004	/* write frame terminated */
+-#define RXF_ABORT	0x0008	/* write frame aborted */
+-#define RXF_DISCARD	(RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT)	/* bad frame */
+-
+-/* HW frame tag */
+-#define SDPCM_FRAMETAG_LEN	4	/* HW frametag: 2 bytes len, 2 bytes check val */
+-
+-#endif				/* _sbsdpcmdev_h_ */
+diff --git a/drivers/staging/brcm80211/include/sdio.h b/drivers/staging/brcm80211/include/sdio.h
+deleted file mode 100644
+index 670e379..0000000
+--- a/drivers/staging/brcm80211/include/sdio.h
++++ /dev/null
+@@ -1,552 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SDIO_H
+-#define	_SDIO_H
+-
+-#ifdef BCMSDIO
+-
+-/* CCCR structure for function 0 */
+-typedef volatile struct {
+-	u8 cccr_sdio_rev;	/* RO, cccr and sdio revision */
+-	u8 sd_rev;		/* RO, sd spec revision */
+-	u8 io_en;		/* I/O enable */
+-	u8 io_rdy;		/* I/O ready reg */
+-	u8 intr_ctl;		/* Master and per function interrupt enable control */
+-	u8 intr_status;	/* RO, interrupt pending status */
+-	u8 io_abort;		/* read/write abort or reset all functions */
+-	u8 bus_inter;	/* bus interface control */
+-	u8 capability;	/* RO, card capability */
+-
+-	u8 cis_base_low;	/* 0x9 RO, common CIS base address, LSB */
+-	u8 cis_base_mid;
+-	u8 cis_base_high;	/* 0xB RO, common CIS base address, MSB */
+-
+-	/* suspend/resume registers */
+-	u8 bus_suspend;	/* 0xC */
+-	u8 func_select;	/* 0xD */
+-	u8 exec_flag;	/* 0xE */
+-	u8 ready_flag;	/* 0xF */
+-
+-	u8 fn0_blk_size[2];	/* 0x10(LSB), 0x11(MSB) */
+-
+-	u8 power_control;	/* 0x12 (SDIO version 1.10) */
+-
+-	u8 speed_control;	/* 0x13 */
+-} sdio_regs_t;
+-
+-/* SDIO Device CCCR offsets */
+-#define SDIOD_CCCR_REV			0x00
+-#define SDIOD_CCCR_SDREV		0x01
+-#define SDIOD_CCCR_IOEN			0x02
+-#define SDIOD_CCCR_IORDY		0x03
+-#define SDIOD_CCCR_INTEN		0x04
+-#define SDIOD_CCCR_INTPEND		0x05
+-#define SDIOD_CCCR_IOABORT		0x06
+-#define SDIOD_CCCR_BICTRL		0x07
+-#define SDIOD_CCCR_CAPABLITIES		0x08
+-#define SDIOD_CCCR_CISPTR_0		0x09
+-#define SDIOD_CCCR_CISPTR_1		0x0A
+-#define SDIOD_CCCR_CISPTR_2		0x0B
+-#define SDIOD_CCCR_BUSSUSP		0x0C
+-#define SDIOD_CCCR_FUNCSEL		0x0D
+-#define SDIOD_CCCR_EXECFLAGS		0x0E
+-#define SDIOD_CCCR_RDYFLAGS		0x0F
+-#define SDIOD_CCCR_BLKSIZE_0		0x10
+-#define SDIOD_CCCR_BLKSIZE_1		0x11
+-#define SDIOD_CCCR_POWER_CONTROL	0x12
+-#define SDIOD_CCCR_SPEED_CONTROL	0x13
+-
+-/* Broadcom extensions (corerev >= 1) */
+-#define SDIOD_CCCR_BRCM_SEPINT		0xf2
+-
+-/* cccr_sdio_rev */
+-#define SDIO_REV_SDIOID_MASK	0xf0	/* SDIO spec revision number */
+-#define SDIO_REV_CCCRID_MASK	0x0f	/* CCCR format version number */
+-
+-/* sd_rev */
+-#define SD_REV_PHY_MASK		0x0f	/* SD format version number */
+-
+-/* io_en */
+-#define SDIO_FUNC_ENABLE_1	0x02	/* function 1 I/O enable */
+-#define SDIO_FUNC_ENABLE_2	0x04	/* function 2 I/O enable */
+-
+-/* io_rdys */
+-#define SDIO_FUNC_READY_1	0x02	/* function 1 I/O ready */
+-#define SDIO_FUNC_READY_2	0x04	/* function 2 I/O ready */
+-
+-/* intr_ctl */
+-#define INTR_CTL_MASTER_EN	0x1	/* interrupt enable master */
+-#define INTR_CTL_FUNC1_EN	0x2	/* interrupt enable for function 1 */
+-#define INTR_CTL_FUNC2_EN	0x4	/* interrupt enable for function 2 */
+-
+-/* intr_status */
+-#define INTR_STATUS_FUNC1	0x2	/* interrupt pending for function 1 */
+-#define INTR_STATUS_FUNC2	0x4	/* interrupt pending for function 2 */
+-
+-/* io_abort */
+-#define IO_ABORT_RESET_ALL	0x08	/* I/O card reset */
+-#define IO_ABORT_FUNC_MASK	0x07	/* abort selction: function x */
+-
+-/* bus_inter */
+-#define BUS_CARD_DETECT_DIS	0x80	/* Card Detect disable */
+-#define BUS_SPI_CONT_INTR_CAP	0x40	/* support continuous SPI interrupt */
+-#define BUS_SPI_CONT_INTR_EN	0x20	/* continuous SPI interrupt enable */
+-#define BUS_SD_DATA_WIDTH_MASK	0x03	/* bus width mask */
+-#define BUS_SD_DATA_WIDTH_4BIT	0x02	/* bus width 4-bit mode */
+-#define BUS_SD_DATA_WIDTH_1BIT	0x00	/* bus width 1-bit mode */
+-
+-/* capability */
+-#define SDIO_CAP_4BLS		0x80	/* 4-bit support for low speed card */
+-#define SDIO_CAP_LSC		0x40	/* low speed card */
+-#define SDIO_CAP_E4MI		0x20	/* enable interrupt between block of data in 4-bit mode */
+-#define SDIO_CAP_S4MI		0x10	/* support interrupt between block of data in 4-bit mode */
+-#define SDIO_CAP_SBS		0x08	/* support suspend/resume */
+-#define SDIO_CAP_SRW		0x04	/* support read wait */
+-#define SDIO_CAP_SMB		0x02	/* support multi-block transfer */
+-#define SDIO_CAP_SDC		0x01	/* Support Direct commands during multi-byte transfer */
+-
+-/* power_control */
+-#define SDIO_POWER_SMPC		0x01	/* supports master power control (RO) */
+-#define SDIO_POWER_EMPC		0x02	/* enable master power control (allow > 200mA) (RW) */
+-
+-/* speed_control (control device entry into high-speed clocking mode) */
+-#define SDIO_SPEED_SHS		0x01	/* supports high-speed [clocking] mode (RO) */
+-#define SDIO_SPEED_EHS		0x02	/* enable high-speed [clocking] mode (RW) */
+-
+-/* brcm sepint */
+-#define SDIO_SEPINT_MASK	0x01	/* route sdpcmdev intr onto separate pad (chip-specific) */
+-#define SDIO_SEPINT_OE		0x02	/* 1 asserts output enable for above pad */
+-#define SDIO_SEPINT_ACT_HI	0x04	/* use active high interrupt level instead of active low */
+-
+-/* FBR structure for function 1-7, FBR addresses and register offsets */
+-typedef volatile struct {
+-	u8 devctr;		/* device interface, CSA control */
+-	u8 ext_dev;		/* extended standard I/O device type code */
+-	u8 pwr_sel;		/* power selection support */
+-	u8 PAD[6];		/* reserved */
+-
+-	u8 cis_low;		/* CIS LSB */
+-	u8 cis_mid;
+-	u8 cis_high;		/* CIS MSB */
+-	u8 csa_low;		/* code storage area, LSB */
+-	u8 csa_mid;
+-	u8 csa_high;		/* code storage area, MSB */
+-	u8 csa_dat_win;	/* data access window to function */
+-
+-	u8 fnx_blk_size[2];	/* block size, little endian */
+-} sdio_fbr_t;
+-
+-/* Maximum number of I/O funcs */
+-#define SDIOD_MAX_IOFUNCS		7
+-
+-/* SDIO Device FBR Start Address  */
+-#define SDIOD_FBR_STARTADDR		0x100
+-
+-/* SDIO Device FBR Size */
+-#define SDIOD_FBR_SIZE			0x100
+-
+-/* Macro to calculate FBR register base */
+-#define SDIOD_FBR_BASE(n)		((n) * 0x100)
+-
+-/* Function register offsets */
+-#define SDIOD_FBR_DEVCTR		0x00	/* basic info for function */
+-#define SDIOD_FBR_EXT_DEV		0x01	/* extended I/O device code */
+-#define SDIOD_FBR_PWR_SEL		0x02	/* power selection bits */
+-
+-/* SDIO Function CIS ptr offset */
+-#define SDIOD_FBR_CISPTR_0		0x09
+-#define SDIOD_FBR_CISPTR_1		0x0A
+-#define SDIOD_FBR_CISPTR_2		0x0B
+-
+-/* Code Storage Area pointer */
+-#define SDIOD_FBR_CSA_ADDR_0		0x0C
+-#define SDIOD_FBR_CSA_ADDR_1		0x0D
+-#define SDIOD_FBR_CSA_ADDR_2		0x0E
+-#define SDIOD_FBR_CSA_DATA		0x0F
+-
+-/* SDIO Function I/O Block Size */
+-#define SDIOD_FBR_BLKSIZE_0		0x10
+-#define SDIOD_FBR_BLKSIZE_1		0x11
+-
+-/* devctr */
+-#define SDIOD_FBR_DEVCTR_DIC	0x0f	/* device interface code */
+-#define SDIOD_FBR_DECVTR_CSA	0x40	/* CSA support flag */
+-#define SDIOD_FBR_DEVCTR_CSA_EN	0x80	/* CSA enabled */
+-/* interface codes */
+-#define SDIOD_DIC_NONE		0	/* SDIO standard interface is not supported */
+-#define SDIOD_DIC_UART		1
+-#define SDIOD_DIC_BLUETOOTH_A	2
+-#define SDIOD_DIC_BLUETOOTH_B	3
+-#define SDIOD_DIC_GPS		4
+-#define SDIOD_DIC_CAMERA	5
+-#define SDIOD_DIC_PHS		6
+-#define SDIOD_DIC_WLAN		7
+-#define SDIOD_DIC_EXT		0xf	/* extended device interface, read ext_dev register */
+-
+-/* pwr_sel */
+-#define SDIOD_PWR_SEL_SPS	0x01	/* supports power selection */
+-#define SDIOD_PWR_SEL_EPS	0x02	/* enable power selection (low-current mode) */
+-
+-/* misc defines */
+-#define SDIO_FUNC_0		0
+-#define SDIO_FUNC_1		1
+-#define SDIO_FUNC_2		2
+-#define SDIO_FUNC_3		3
+-#define SDIO_FUNC_4		4
+-#define SDIO_FUNC_5		5
+-#define SDIO_FUNC_6		6
+-#define SDIO_FUNC_7		7
+-
+-#define SD_CARD_TYPE_UNKNOWN	0	/* bad type or unrecognized */
+-#define SD_CARD_TYPE_IO		1	/* IO only card */
+-#define SD_CARD_TYPE_MEMORY	2	/* memory only card */
+-#define SD_CARD_TYPE_COMBO	3	/* IO and memory combo card */
+-
+-#define SDIO_MAX_BLOCK_SIZE	2048	/* maximum block size for block mode operation */
+-#define SDIO_MIN_BLOCK_SIZE	1	/* minimum block size for block mode operation */
+-
+-/* Card registers: status bit position */
+-#define CARDREG_STATUS_BIT_OUTOFRANGE		31
+-#define CARDREG_STATUS_BIT_COMCRCERROR		23
+-#define CARDREG_STATUS_BIT_ILLEGALCOMMAND	22
+-#define CARDREG_STATUS_BIT_ERROR		19
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE3	12
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE2	11
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE1	10
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE0	9
+-#define CARDREG_STATUS_BIT_FUN_NUM_ERROR	4
+-
+-#define SD_CMD_GO_IDLE_STATE		0	/* mandatory for SDIO */
+-#define SD_CMD_SEND_OPCOND		1
+-#define SD_CMD_MMC_SET_RCA		3
+-#define SD_CMD_IO_SEND_OP_COND		5	/* mandatory for SDIO */
+-#define SD_CMD_SELECT_DESELECT_CARD	7
+-#define SD_CMD_SEND_CSD			9
+-#define SD_CMD_SEND_CID			10
+-#define SD_CMD_STOP_TRANSMISSION	12
+-#define SD_CMD_SEND_STATUS		13
+-#define SD_CMD_GO_INACTIVE_STATE	15
+-#define SD_CMD_SET_BLOCKLEN		16
+-#define SD_CMD_READ_SINGLE_BLOCK	17
+-#define SD_CMD_READ_MULTIPLE_BLOCK	18
+-#define SD_CMD_WRITE_BLOCK		24
+-#define SD_CMD_WRITE_MULTIPLE_BLOCK	25
+-#define SD_CMD_PROGRAM_CSD		27
+-#define SD_CMD_SET_WRITE_PROT		28
+-#define SD_CMD_CLR_WRITE_PROT		29
+-#define SD_CMD_SEND_WRITE_PROT		30
+-#define SD_CMD_ERASE_WR_BLK_START	32
+-#define SD_CMD_ERASE_WR_BLK_END		33
+-#define SD_CMD_ERASE			38
+-#define SD_CMD_LOCK_UNLOCK		42
+-#define SD_CMD_IO_RW_DIRECT		52	/* mandatory for SDIO */
+-#define SD_CMD_IO_RW_EXTENDED		53	/* mandatory for SDIO */
+-#define SD_CMD_APP_CMD			55
+-#define SD_CMD_GEN_CMD			56
+-#define SD_CMD_READ_OCR			58
+-#define SD_CMD_CRC_ON_OFF		59	/* mandatory for SDIO */
+-#define SD_ACMD_SD_STATUS		13
+-#define SD_ACMD_SEND_NUM_WR_BLOCKS	22
+-#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT	23
+-#define SD_ACMD_SD_SEND_OP_COND		41
+-#define SD_ACMD_SET_CLR_CARD_DETECT	42
+-#define SD_ACMD_SEND_SCR		51
+-
+-/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */
+-#define SD_IO_OP_READ		0	/* Read_Write: Read */
+-#define SD_IO_OP_WRITE		1	/* Read_Write: Write */
+-#define SD_IO_RW_NORMAL		0	/* no RAW */
+-#define SD_IO_RW_RAW		1	/* RAW */
+-#define SD_IO_BYTE_MODE		0	/* Byte Mode */
+-#define SD_IO_BLOCK_MODE	1	/* BlockMode */
+-#define SD_IO_FIXED_ADDRESS	0	/* fix Address */
+-#define SD_IO_INCREMENT_ADDRESS	1	/* IncrementAddress */
+-
+-/* build SD_CMD_IO_RW_DIRECT Argument */
+-#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \
+-	((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \
+-	 (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF))
+-
+-/* build SD_CMD_IO_RW_EXTENDED Argument */
+-#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \
+-	((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \
+-	 (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF))
+-
+-/* SDIO response parameters */
+-#define SD_RSP_NO_NONE			0
+-#define SD_RSP_NO_1			1
+-#define SD_RSP_NO_2			2
+-#define SD_RSP_NO_3			3
+-#define SD_RSP_NO_4			4
+-#define SD_RSP_NO_5			5
+-#define SD_RSP_NO_6			6
+-
+-	/* Modified R6 response (to CMD3) */
+-#define SD_RSP_MR6_COM_CRC_ERROR	0x8000
+-#define SD_RSP_MR6_ILLEGAL_COMMAND	0x4000
+-#define SD_RSP_MR6_ERROR		0x2000
+-
+-	/* Modified R1 in R4 Response (to CMD5) */
+-#define SD_RSP_MR1_SBIT			0x80
+-#define SD_RSP_MR1_PARAMETER_ERROR	0x40
+-#define SD_RSP_MR1_RFU5			0x20
+-#define SD_RSP_MR1_FUNC_NUM_ERROR	0x10
+-#define SD_RSP_MR1_COM_CRC_ERROR	0x08
+-#define SD_RSP_MR1_ILLEGAL_COMMAND	0x04
+-#define SD_RSP_MR1_RFU1			0x02
+-#define SD_RSP_MR1_IDLE_STATE		0x01
+-
+-	/* R5 response (to CMD52 and CMD53) */
+-#define SD_RSP_R5_COM_CRC_ERROR		0x80
+-#define SD_RSP_R5_ILLEGAL_COMMAND	0x40
+-#define SD_RSP_R5_IO_CURRENTSTATE1	0x20
+-#define SD_RSP_R5_IO_CURRENTSTATE0	0x10
+-#define SD_RSP_R5_ERROR			0x08
+-#define SD_RSP_R5_RFU			0x04
+-#define SD_RSP_R5_FUNC_NUM_ERROR	0x02
+-#define SD_RSP_R5_OUT_OF_RANGE		0x01
+-
+-#define SD_RSP_R5_ERRBITS		0xCB
+-
+-/* ------------------------------------------------
+- *  SDIO Commands and responses
+- *
+- *  I/O only commands are:
+- *      CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+- * ------------------------------------------------
+- */
+-
+-/* SDIO Commands */
+-#define SDIOH_CMD_0		0
+-#define SDIOH_CMD_3		3
+-#define SDIOH_CMD_5		5
+-#define SDIOH_CMD_7		7
+-#define SDIOH_CMD_15		15
+-#define SDIOH_CMD_52		52
+-#define SDIOH_CMD_53		53
+-#define SDIOH_CMD_59		59
+-
+-/* SDIO Command Responses */
+-#define SDIOH_RSP_NONE		0
+-#define SDIOH_RSP_R1		1
+-#define SDIOH_RSP_R2		2
+-#define SDIOH_RSP_R3		3
+-#define SDIOH_RSP_R4		4
+-#define SDIOH_RSP_R5		5
+-#define SDIOH_RSP_R6		6
+-
+-/*
+- *  SDIO Response Error flags
+- */
+-#define SDIOH_RSP5_ERROR_FLAGS	0xCB
+-
+-/* ------------------------------------------------
+- * SDIO Command structures. I/O only commands are:
+- *
+- * 	CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+- * ------------------------------------------------
+- */
+-
+-#define CMD5_OCR_M		BITFIELD_MASK(24)
+-#define CMD5_OCR_S		0
+-
+-#define CMD7_RCA_M		BITFIELD_MASK(16)
+-#define CMD7_RCA_S		16
+-
+-#define CMD_15_RCA_M		BITFIELD_MASK(16)
+-#define CMD_15_RCA_S		16
+-
+-#define CMD52_DATA_M		BITFIELD_MASK(8)	/* Bits [7:0]    - Write Data/Stuff bits of CMD52
+-							 */
+-#define CMD52_DATA_S		0
+-#define CMD52_REG_ADDR_M	BITFIELD_MASK(17)	/* Bits [25:9]   - register address */
+-#define CMD52_REG_ADDR_S	9
+-#define CMD52_RAW_M		BITFIELD_MASK(1)	/* Bit  27       - Read after Write flag */
+-#define CMD52_RAW_S		27
+-#define CMD52_FUNCTION_M	BITFIELD_MASK(3)	/* Bits [30:28]  - Function number */
+-#define CMD52_FUNCTION_S	28
+-#define CMD52_RW_FLAG_M		BITFIELD_MASK(1)	/* Bit  31       - R/W flag */
+-#define CMD52_RW_FLAG_S		31
+-
+-#define CMD53_BYTE_BLK_CNT_M	BITFIELD_MASK(9)	/* Bits [8:0]     - Byte/Block Count of CMD53 */
+-#define CMD53_BYTE_BLK_CNT_S	0
+-#define CMD53_REG_ADDR_M	BITFIELD_MASK(17)	/* Bits [25:9]   - register address */
+-#define CMD53_REG_ADDR_S	9
+-#define CMD53_OP_CODE_M		BITFIELD_MASK(1)	/* Bit  26       - R/W Operation Code */
+-#define CMD53_OP_CODE_S		26
+-#define CMD53_BLK_MODE_M	BITFIELD_MASK(1)	/* Bit  27       - Block Mode */
+-#define CMD53_BLK_MODE_S	27
+-#define CMD53_FUNCTION_M	BITFIELD_MASK(3)	/* Bits [30:28]  - Function number */
+-#define CMD53_FUNCTION_S	28
+-#define CMD53_RW_FLAG_M		BITFIELD_MASK(1)	/* Bit  31       - R/W flag */
+-#define CMD53_RW_FLAG_S		31
+-
+-/* ------------------------------------------------------
+- * SDIO Command Response structures for SD1 and SD4 modes
+- *  -----------------------------------------------------
+- */
+-#define RSP4_IO_OCR_M		BITFIELD_MASK(24)	/* Bits [23:0]  - Card's OCR Bits [23:0] */
+-#define RSP4_IO_OCR_S		0
+-#define RSP4_STUFF_M		BITFIELD_MASK(3)	/* Bits [26:24] - Stuff bits */
+-#define RSP4_STUFF_S		24
+-#define RSP4_MEM_PRESENT_M	BITFIELD_MASK(1)	/* Bit  27      - Memory present */
+-#define RSP4_MEM_PRESENT_S	27
+-#define RSP4_NUM_FUNCS_M	BITFIELD_MASK(3)	/* Bits [30:28] - Number of I/O funcs */
+-#define RSP4_NUM_FUNCS_S	28
+-#define RSP4_CARD_READY_M	BITFIELD_MASK(1)	/* Bit  31      - SDIO card ready */
+-#define RSP4_CARD_READY_S	31
+-
+-#define RSP6_STATUS_M		BITFIELD_MASK(16)	/* Bits [15:0]  - Card status bits [19,22,23,12:0]
+-							 */
+-#define RSP6_STATUS_S		0
+-#define RSP6_IO_RCA_M		BITFIELD_MASK(16)	/* Bits [31:16] - RCA bits[31-16] */
+-#define RSP6_IO_RCA_S		16
+-
+-#define RSP1_AKE_SEQ_ERROR_M	BITFIELD_MASK(1)	/* Bit 3       - Authentication seq error */
+-#define RSP1_AKE_SEQ_ERROR_S	3
+-#define RSP1_APP_CMD_M		BITFIELD_MASK(1)	/* Bit 5       - Card expects ACMD */
+-#define RSP1_APP_CMD_S		5
+-#define RSP1_READY_FOR_DATA_M	BITFIELD_MASK(1)	/* Bit 8       - Ready for data (buff empty) */
+-#define RSP1_READY_FOR_DATA_S	8
+-#define RSP1_CURR_STATE_M	BITFIELD_MASK(4)	/* Bits [12:9] - State of card
+-							 * when Cmd was received
+-							 */
+-#define RSP1_CURR_STATE_S	9
+-#define RSP1_EARSE_RESET_M	BITFIELD_MASK(1)	/* Bit 13   - Erase seq cleared */
+-#define RSP1_EARSE_RESET_S	13
+-#define RSP1_CARD_ECC_DISABLE_M	BITFIELD_MASK(1)	/* Bit 14   - Card ECC disabled */
+-#define RSP1_CARD_ECC_DISABLE_S	14
+-#define RSP1_WP_ERASE_SKIP_M	BITFIELD_MASK(1)	/* Bit 15   - Partial blocks erased due to W/P */
+-#define RSP1_WP_ERASE_SKIP_S	15
+-#define RSP1_CID_CSD_OVERW_M	BITFIELD_MASK(1)	/* Bit 16   - Illegal write to CID or R/O bits
+-							 * of CSD
+-							 */
+-#define RSP1_CID_CSD_OVERW_S	16
+-#define RSP1_ERROR_M		BITFIELD_MASK(1)	/* Bit 19   - General/Unknown error */
+-#define RSP1_ERROR_S		19
+-#define RSP1_CC_ERROR_M		BITFIELD_MASK(1)	/* Bit 20   - Internal Card Control error */
+-#define RSP1_CC_ERROR_S		20
+-#define RSP1_CARD_ECC_FAILED_M	BITFIELD_MASK(1)	/* Bit 21   - Card internal ECC failed
+-							 * to correct data
+-							 */
+-#define RSP1_CARD_ECC_FAILED_S	21
+-#define RSP1_ILLEGAL_CMD_M	BITFIELD_MASK(1)	/* Bit 22   - Cmd not legal for the card state */
+-#define RSP1_ILLEGAL_CMD_S	22
+-#define RSP1_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit 23   - CRC check of previous command failed
+-							 */
+-#define RSP1_COM_CRC_ERROR_S	23
+-#define RSP1_LOCK_UNLOCK_FAIL_M	BITFIELD_MASK(1)	/* Bit 24   - Card lock-unlock Cmd Seq error */
+-#define RSP1_LOCK_UNLOCK_FAIL_S	24
+-#define RSP1_CARD_LOCKED_M	BITFIELD_MASK(1)	/* Bit 25   - Card locked by the host */
+-#define RSP1_CARD_LOCKED_S	25
+-#define RSP1_WP_VIOLATION_M	BITFIELD_MASK(1)	/* Bit 26   - Attempt to program
+-							 * write-protected blocks
+-							 */
+-#define RSP1_WP_VIOLATION_S	26
+-#define RSP1_ERASE_PARAM_M	BITFIELD_MASK(1)	/* Bit 27   - Invalid erase blocks */
+-#define RSP1_ERASE_PARAM_S	27
+-#define RSP1_ERASE_SEQ_ERR_M	BITFIELD_MASK(1)	/* Bit 28   - Erase Cmd seq error */
+-#define RSP1_ERASE_SEQ_ERR_S	28
+-#define RSP1_BLK_LEN_ERR_M	BITFIELD_MASK(1)	/* Bit 29   - Block length error */
+-#define RSP1_BLK_LEN_ERR_S	29
+-#define RSP1_ADDR_ERR_M		BITFIELD_MASK(1)	/* Bit 30   - Misaligned address */
+-#define RSP1_ADDR_ERR_S		30
+-#define RSP1_OUT_OF_RANGE_M	BITFIELD_MASK(1)	/* Bit 31   - Cmd arg was out of range */
+-#define RSP1_OUT_OF_RANGE_S	31
+-
+-#define RSP5_DATA_M		BITFIELD_MASK(8)	/* Bits [0:7]   - data */
+-#define RSP5_DATA_S		0
+-#define RSP5_FLAGS_M		BITFIELD_MASK(8)	/* Bit  [15:8]  - Rsp flags */
+-#define RSP5_FLAGS_S		8
+-#define RSP5_STUFF_M		BITFIELD_MASK(16)	/* Bits [31:16] - Stuff bits */
+-#define RSP5_STUFF_S		16
+-
+-/* ----------------------------------------------
+- * SDIO Command Response structures for SPI mode
+- * ----------------------------------------------
+- */
+-#define SPIRSP4_IO_OCR_M	BITFIELD_MASK(16)	/* Bits [15:0]    - Card's OCR Bits [23:8] */
+-#define SPIRSP4_IO_OCR_S	0
+-#define SPIRSP4_STUFF_M		BITFIELD_MASK(3)	/* Bits [18:16]   - Stuff bits */
+-#define SPIRSP4_STUFF_S		16
+-#define SPIRSP4_MEM_PRESENT_M	BITFIELD_MASK(1)	/* Bit  19        - Memory present */
+-#define SPIRSP4_MEM_PRESENT_S	19
+-#define SPIRSP4_NUM_FUNCS_M	BITFIELD_MASK(3)	/* Bits [22:20]   - Number of I/O funcs */
+-#define SPIRSP4_NUM_FUNCS_S	20
+-#define SPIRSP4_CARD_READY_M	BITFIELD_MASK(1)	/* Bit  23        - SDIO card ready */
+-#define SPIRSP4_CARD_READY_S	23
+-#define SPIRSP4_IDLE_STATE_M	BITFIELD_MASK(1)	/* Bit  24        - idle state */
+-#define SPIRSP4_IDLE_STATE_S	24
+-#define SPIRSP4_ILLEGAL_CMD_M	BITFIELD_MASK(1)	/* Bit  26        - Illegal Cmd error */
+-#define SPIRSP4_ILLEGAL_CMD_S	26
+-#define SPIRSP4_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit  27        - COM CRC error */
+-#define SPIRSP4_COM_CRC_ERROR_S	27
+-#define SPIRSP4_FUNC_NUM_ERROR_M	BITFIELD_MASK(1)	/* Bit  28        - Function number error
+-								 */
+-#define SPIRSP4_FUNC_NUM_ERROR_S	28
+-#define SPIRSP4_PARAM_ERROR_M	BITFIELD_MASK(1)	/* Bit  30        - Parameter Error Bit */
+-#define SPIRSP4_PARAM_ERROR_S	30
+-#define SPIRSP4_START_BIT_M	BITFIELD_MASK(1)	/* Bit  31        - Start Bit */
+-#define SPIRSP4_START_BIT_S	31
+-
+-#define SPIRSP5_DATA_M			BITFIELD_MASK(8)	/* Bits [23:16]   - R/W Data */
+-#define SPIRSP5_DATA_S			16
+-#define SPIRSP5_IDLE_STATE_M		BITFIELD_MASK(1)	/* Bit  24        - Idle state */
+-#define SPIRSP5_IDLE_STATE_S		24
+-#define SPIRSP5_ILLEGAL_CMD_M		BITFIELD_MASK(1)	/* Bit  26        - Illegal Cmd error */
+-#define SPIRSP5_ILLEGAL_CMD_S		26
+-#define SPIRSP5_COM_CRC_ERROR_M		BITFIELD_MASK(1)	/* Bit  27        - COM CRC error */
+-#define SPIRSP5_COM_CRC_ERROR_S		27
+-#define SPIRSP5_FUNC_NUM_ERROR_M	BITFIELD_MASK(1)	/* Bit  28        - Function number error
+-								 */
+-#define SPIRSP5_FUNC_NUM_ERROR_S	28
+-#define SPIRSP5_PARAM_ERROR_M		BITFIELD_MASK(1)	/* Bit  30        - Parameter Error Bit */
+-#define SPIRSP5_PARAM_ERROR_S		30
+-#define SPIRSP5_START_BIT_M		BITFIELD_MASK(1)	/* Bit  31        - Start Bit */
+-#define SPIRSP5_START_BIT_S		31
+-
+-/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */
+-#define RSP6STAT_AKE_SEQ_ERROR_M	BITFIELD_MASK(1)	/* Bit 3      - Authentication seq error
+-								 */
+-#define RSP6STAT_AKE_SEQ_ERROR_S	3
+-#define RSP6STAT_APP_CMD_M		BITFIELD_MASK(1)	/* Bit 5      - Card expects ACMD */
+-#define RSP6STAT_APP_CMD_S		5
+-#define RSP6STAT_READY_FOR_DATA_M	BITFIELD_MASK(1)	/* Bit 8      - Ready for data
+-								 * (buff empty)
+-								 */
+-#define RSP6STAT_READY_FOR_DATA_S	8
+-#define RSP6STAT_CURR_STATE_M		BITFIELD_MASK(4)	/* Bits [12:9] - Card state at
+-								 * Cmd reception
+-								 */
+-#define RSP6STAT_CURR_STATE_S		9
+-#define RSP6STAT_ERROR_M		BITFIELD_MASK(1)	/* Bit 13  - General/Unknown error Bit 19
+-								 */
+-#define RSP6STAT_ERROR_S		13
+-#define RSP6STAT_ILLEGAL_CMD_M		BITFIELD_MASK(1)	/* Bit 14  - Illegal cmd for
+-								 * card state Bit 22
+-								 */
+-#define RSP6STAT_ILLEGAL_CMD_S		14
+-#define RSP6STAT_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit 15  - CRC previous command
+-								 * failed Bit 23
+-								 */
+-#define RSP6STAT_COM_CRC_ERROR_S	15
+-
+-#define SDIOH_XFER_TYPE_READ    SD_IO_OP_READ
+-#define SDIOH_XFER_TYPE_WRITE   SD_IO_OP_WRITE
+-
+-#endif				/* def BCMSDIO */
+-#endif				/* _SDIO_H */
+diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h
+deleted file mode 100644
+index 2876bd9..0000000
+--- a/drivers/staging/brcm80211/include/wlioctl.h
++++ /dev/null
+@@ -1,1365 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlioctl_h_
+-#define	_wlioctl_h_
+-
+-#include <linux/ieee80211.h>
+-#ifdef BRCM_FULLMAC
+-#include <proto/bcmeth.h>
+-#endif
+-#include <proto/bcmevent.h>
+-#include <proto/802.11.h>
+-#include <bcmwifi.h>
+-
+-#ifndef INTF_NAME_SIZ
+-#define INTF_NAME_SIZ	16
+-#endif
+-
+-#ifdef BRCM_FULLMAC
+-
+-#define	WL_BSS_INFO_VERSION	108	/* current ver of wl_bss_info struct */
+-
+-/* BSS info structure
+- * Applications MUST CHECK ie_offset field and length field to access IEs and
+- * next bss_info structure in a vector (in wl_scan_results_t)
+- */
+-typedef struct wl_bss_info {
+-	u32 version;		/* version field */
+-	u32 length;		/* byte length of data in this record,
+-				 * starting at version and including IEs
+-				 */
+-	u8 BSSID[ETH_ALEN];
+-	u16 beacon_period;	/* units are Kusec */
+-	u16 capability;	/* Capability information */
+-	u8 SSID_len;
+-	u8 SSID[32];
+-	struct {
+-		uint count;	/* # rates in this set */
+-		u8 rates[16];	/* rates in 500kbps units w/hi bit set if basic */
+-	} rateset;		/* supported rates */
+-	chanspec_t chanspec;	/* chanspec for bss */
+-	u16 atim_window;	/* units are Kusec */
+-	u8 dtim_period;	/* DTIM period */
+-	s16 RSSI;		/* receive signal strength (in dBm) */
+-	s8 phy_noise;		/* noise (in dBm) */
+-
+-	u8 n_cap;		/* BSS is 802.11N Capable */
+-	u32 nbss_cap;	/* 802.11N BSS Capabilities (based on HT_CAP_*) */
+-	u8 ctl_ch;		/* 802.11N BSS control channel number */
+-	u32 reserved32[1];	/* Reserved for expansion of BSS properties */
+-	u8 flags;		/* flags */
+-	u8 reserved[3];	/* Reserved for expansion of BSS properties */
+-	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
+-
+-	u16 ie_offset;	/* offset at which IEs start, from beginning */
+-	u32 ie_length;	/* byte length of Information Elements */
+-	s16 SNR;		/* average SNR of during frame reception */
+-	/* Add new fields here */
+-	/* variable length Information Elements */
+-} wl_bss_info_t;
+-#endif /* BRCM_FULLMAC */
+-
+-typedef struct wlc_ssid {
+-	u32 SSID_len;
+-	unsigned char SSID[32];
+-} wlc_ssid_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct chan_scandata {
+-	u8 txpower;
+-	u8 pad;
+-	chanspec_t channel;	/* Channel num, bw, ctrl_sb and band */
+-	u32 channel_mintime;
+-	u32 channel_maxtime;
+-} chan_scandata_t;
+-
+-typedef enum wl_scan_type {
+-	EXTDSCAN_FOREGROUND_SCAN,
+-	EXTDSCAN_BACKGROUND_SCAN,
+-	EXTDSCAN_FORCEDBACKGROUND_SCAN
+-} wl_scan_type_t;
+-
+-#define WLC_EXTDSCAN_MAX_SSID		5
+-
+-#define WL_BSS_FLAGS_FROM_BEACON	0x01	/* bss_info derived from beacon */
+-#define WL_BSS_FLAGS_FROM_CACHE		0x02	/* bss_info collected from cache */
+-#define WL_BSS_FLAGS_RSSI_ONCHANNEL     0x04	/* rssi info was received on channel (vs offchannel) */
+-
+-typedef struct wl_extdscan_params {
+-	s8 nprobes;		/* 0, passive, otherwise active */
+-	s8 split_scan;	/* split scan */
+-	s8 band;		/* band */
+-	s8 pad;
+-	wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID];	/* ssid list */
+-	u32 tx_rate;		/* in 500ksec units */
+-	wl_scan_type_t scan_type;	/* enum */
+-	s32 channel_num;
+-	chan_scandata_t channel_list[1];	/* list of chandata structs */
+-} wl_extdscan_params_t;
+-
+-#define WL_EXTDSCAN_PARAMS_FIXED_SIZE 	(sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t))
+-
+-#define WL_BSSTYPE_INFRA 1
+-#define WL_BSSTYPE_INDEP 0
+-#define WL_BSSTYPE_ANY   2
+-
+-/* Bitmask for scan_type */
+-#define WL_SCANFLAGS_PASSIVE 0x01	/* force passive scan */
+-#define WL_SCANFLAGS_RESERVED 0x02	/* Reserved */
+-#define WL_SCANFLAGS_PROHIBITED 0x04	/* allow scanning prohibited channels */
+-
+-typedef struct wl_scan_params {
+-	wlc_ssid_t ssid;	/* default: {0, ""} */
+-	u8 bssid[ETH_ALEN];	/* default: bcast */
+-	s8 bss_type;		/* default: any,
+-				 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
+-				 */
+-	u8 scan_type;	/* flags, 0 use default */
+-	s32 nprobes;		/* -1 use default, number of probes per channel */
+-	s32 active_time;	/* -1 use default, dwell time per channel for
+-				 * active scanning
+-				 */
+-	s32 passive_time;	/* -1 use default, dwell time per channel
+-				 * for passive scanning
+-				 */
+-	s32 home_time;	/* -1 use default, dwell time for the home channel
+-				 * between channel scans
+-				 */
+-	s32 channel_num;	/* count of channels and ssids that follow
+-				 *
+-				 * low half is count of channels in channel_list, 0
+-				 * means default (use all available channels)
+-				 *
+-				 * high half is entries in wlc_ssid_t array that
+-				 * follows channel_list, aligned for s32 (4 bytes)
+-				 * meaning an odd channel count implies a 2-byte pad
+-				 * between end of channel_list and first ssid
+-				 *
+-				 * if ssid count is zero, single ssid in the fixed
+-				 * parameter portion is assumed, otherwise ssid in
+-				 * the fixed portion is ignored
+-				 */
+-	u16 channel_list[1];	/* list of chanspecs */
+-} wl_scan_params_t;
+-
+-/* size of wl_scan_params not including variable length array */
+-#define WL_SCAN_PARAMS_FIXED_SIZE 64
+-
+-/* masks for channel and ssid count */
+-#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff
+-#define WL_SCAN_PARAMS_NSSID_SHIFT 16
+-
+-#define WL_SCAN_ACTION_START      1
+-#define WL_SCAN_ACTION_CONTINUE   2
+-#define WL_SCAN_ACTION_ABORT      3
+-
+-#define ISCAN_REQ_VERSION 1
+-
+-/* incremental scan struct */
+-typedef struct wl_iscan_params {
+-	u32 version;
+-	u16 action;
+-	u16 scan_duration;
+-	wl_scan_params_t params;
+-} wl_iscan_params_t;
+-
+-/* 3 fields + size of wl_scan_params, not including variable length array */
+-#define WL_ISCAN_PARAMS_FIXED_SIZE (offsetof(wl_iscan_params_t, params) + sizeof(wlc_ssid_t))
+-
+-typedef struct wl_scan_results {
+-	u32 buflen;
+-	u32 version;
+-	u32 count;
+-	wl_bss_info_t bss_info[1];
+-} wl_scan_results_t;
+-
+-/* size of wl_scan_results not including variable length array */
+-#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t))
+-
+-/* wl_iscan_results status values */
+-#define WL_SCAN_RESULTS_SUCCESS	0
+-#define WL_SCAN_RESULTS_PARTIAL	1
+-#define WL_SCAN_RESULTS_PENDING	2
+-#define WL_SCAN_RESULTS_ABORTED	3
+-#define WL_SCAN_RESULTS_NO_MEM	4
+-
+-#define ESCAN_REQ_VERSION 1
+-
+-typedef struct wl_escan_params {
+-	u32 version;
+-	u16 action;
+-	u16 sync_id;
+-	wl_scan_params_t params;
+-} wl_escan_params_t;
+-
+-#define WL_ESCAN_PARAMS_FIXED_SIZE (offsetof(wl_escan_params_t, params) + sizeof(wlc_ssid_t))
+-
+-typedef struct wl_escan_result {
+-	u32 buflen;
+-	u32 version;
+-	u16 sync_id;
+-	u16 bss_count;
+-	wl_bss_info_t bss_info[1];
+-} wl_escan_result_t;
+-
+-#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t))
+-
+-/* incremental scan results struct */
+-typedef struct wl_iscan_results {
+-	u32 status;
+-	wl_scan_results_t results;
+-} wl_iscan_results_t;
+-
+-/* size of wl_iscan_results not including variable length array */
+-#define WL_ISCAN_RESULTS_FIXED_SIZE \
+-	(WL_SCAN_RESULTS_FIXED_SIZE + offsetof(wl_iscan_results_t, results))
+-
+-typedef struct wl_probe_params {
+-	wlc_ssid_t ssid;
+-	u8 bssid[ETH_ALEN];
+-	u8 mac[ETH_ALEN];
+-} wl_probe_params_t;
+-#endif /* BRCM_FULLMAC */
+-
+-#define WL_NUMRATES		16	/* max # of rates in a rateset */
+-typedef struct wl_rateset {
+-	u32 count;		/* # rates in this set */
+-	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-} wl_rateset_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct wl_rateset_args {
+-	u32 count;		/* # rates in this set */
+-	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
+-} wl_rateset_args_t;
+-
+-/* u32 list */
+-typedef struct wl_u32_list {
+-	/* in - # of elements, out - # of entries */
+-	u32 count;
+-	/* variable length u32 list */
+-	u32 element[1];
+-} wl_u32_list_t;
+-
+-/* used for association with a specific BSSID and chanspec list */
+-typedef struct wl_assoc_params {
+-	u8 bssid[ETH_ALEN];	/* 00:00:00:00:00:00: broadcast scan */
+-	u16 bssid_cnt;
+-	s32 chanspec_num;	/* 0: all available channels,
+-				 * otherwise count of chanspecs in chanspec_list
+-				 */
+-	chanspec_t chanspec_list[1];	/* list of chanspecs */
+-} wl_assoc_params_t;
+-#define WL_ASSOC_PARAMS_FIXED_SIZE 	(sizeof(wl_assoc_params_t) - sizeof(chanspec_t))
+-
+-/* used for reassociation/roam to a specific BSSID and channel */
+-typedef wl_assoc_params_t wl_reassoc_params_t;
+-#define WL_REASSOC_PARAMS_FIXED_SIZE	WL_ASSOC_PARAMS_FIXED_SIZE
+-
+-/* used for join with or without a specific bssid and channel list */
+-typedef struct wl_join_params {
+-	wlc_ssid_t ssid;
+-	wl_assoc_params_t params;	/* optional field, but it must include the fixed portion
+-					 * of the wl_assoc_params_t struct when it does present.
+-					 */
+-} wl_join_params_t;
+-#define WL_JOIN_PARAMS_FIXED_SIZE 	(sizeof(wl_join_params_t) - sizeof(chanspec_t))
+-
+-#endif /* BRCM_FULLMAC */
+-
+-/* defines used by the nrate iovar */
+-#define NRATE_MCS_INUSE	0x00000080	/* MSC in use,indicates b0-6 holds an mcs */
+-#define NRATE_RATE_MASK 0x0000007f	/* rate/mcs value */
+-#define NRATE_STF_MASK	0x0000ff00	/* stf mode mask: siso, cdd, stbc, sdm */
+-#define NRATE_STF_SHIFT	8	/* stf mode shift */
+-#define NRATE_OVERRIDE	0x80000000	/* bit indicates override both rate & mode */
+-#define NRATE_OVERRIDE_MCS_ONLY 0x40000000	/* bit indicate to override mcs only */
+-#define NRATE_SGI_MASK  0x00800000	/* sgi mode */
+-#define NRATE_SGI_SHIFT 23	/* sgi mode */
+-#define NRATE_LDPC_CODING 0x00400000	/* bit indicates adv coding in use */
+-#define NRATE_LDPC_SHIFT 22	/* ldpc shift */
+-
+-#define NRATE_STF_SISO	0	/* stf mode SISO */
+-#define NRATE_STF_CDD	1	/* stf mode CDD */
+-#define NRATE_STF_STBC	2	/* stf mode STBC */
+-#define NRATE_STF_SDM	3	/* stf mode SDM */
+-
+-#define ANTENNA_NUM_1	1	/* total number of antennas to be used */
+-#define ANTENNA_NUM_2	2
+-#define ANTENNA_NUM_3	3
+-#define ANTENNA_NUM_4	4
+-
+-#define ANT_SELCFG_AUTO		0x80	/* bit indicates antenna sel AUTO */
+-#define ANT_SELCFG_MASK		0x33	/* antenna configuration mask */
+-#define ANT_SELCFG_MAX		4	/* max number of antenna configurations */
+-#define ANT_SELCFG_TX_UNICAST	0	/* unicast tx antenna configuration */
+-#define ANT_SELCFG_RX_UNICAST	1	/* unicast rx antenna configuration */
+-#define ANT_SELCFG_TX_DEF	2	/* default tx antenna configuration */
+-#define ANT_SELCFG_RX_DEF	3	/* default rx antenna configuration */
+-
+-#define MAX_STREAMS_SUPPORTED	4	/* max number of streams supported */
+-
+-typedef struct {
+-	u8 ant_config[ANT_SELCFG_MAX];	/* antenna configuration */
+-	u8 num_antcfg;	/* number of available antenna configurations */
+-} wlc_antselcfg_t;
+-
+-#define HIGHEST_SINGLE_STREAM_MCS	7	/* MCS values greater than this enable multiple streams */
+-
+-#ifdef BRCM_FULLMAC
+-#define MAX_CCA_CHANNELS 38	/* Max number of 20 Mhz wide channels */
+-#define MAX_CCA_SECS     60	/* CCA keeps this many seconds history */
+-
+-#define IBSS_MED        15	/* Mediom in-bss congestion percentage */
+-#define IBSS_HI         25	/* Hi in-bss congestion percentage */
+-#define OBSS_MED        12
+-#define OBSS_HI         25
+-#define INTERFER_MED    5
+-#define INTERFER_HI     10
+-
+-#define  CCA_FLAG_2G_ONLY		0x01	/* Return a channel from 2.4 Ghz band */
+-#define  CCA_FLAG_5G_ONLY		0x02	/* Return a channel from 2.4 Ghz band */
+-#define  CCA_FLAG_IGNORE_DURATION	0x04	/* Ignore dwell time for each channel */
+-#define  CCA_FLAGS_PREFER_1_6_11	0x10
+-#define  CCA_FLAG_IGNORE_INTERFER 	0x20	/* do not exlude channel based on interfer level */
+-
+-#define CCA_ERRNO_BAND 		1	/* After filtering for band pref, no choices left */
+-#define CCA_ERRNO_DURATION	2	/* After filtering for duration, no choices left */
+-#define CCA_ERRNO_PREF_CHAN	3	/* After filtering for chan pref, no choices left */
+-#define CCA_ERRNO_INTERFER	4	/* After filtering for interference, no choices left */
+-#define CCA_ERRNO_TOO_FEW	5	/* Only 1 channel was input */
+-
+-typedef struct {
+-	u32 duration;	/* millisecs spent sampling this channel */
+-	u32 congest_ibss;	/* millisecs in our bss (presumably this traffic will */
+-	/*  move if cur bss moves channels) */
+-	u32 congest_obss;	/* traffic not in our bss */
+-	u32 interference;	/* millisecs detecting a non 802.11 interferer. */
+-	u32 timestamp;	/* second timestamp */
+-} cca_congest_t;
+-
+-typedef struct {
+-	chanspec_t chanspec;	/* Which channel? */
+-	u8 num_secs;		/* How many secs worth of data */
+-	cca_congest_t secs[1];	/* Data */
+-} cca_congest_channel_req_t;
+-
+-#endif /* BRCM_FULLMAC */
+-
+-#define WLC_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct wl_country {
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];	/* nul-terminated country code used in
+-						 * the Country IE
+-						 */
+-	s32 rev;		/* revision specifier for ccode
+-				 * on set, -1 indicates unspecified.
+-				 * on get, rev >= 0
+-				 */
+-	char ccode[WLC_CNTRY_BUF_SZ];	/* nul-terminated built-in country code.
+-					 * variable length, but fixed size in
+-					 * struct allows simple allocation for
+-					 * expected country strings <= 3 chars.
+-					 */
+-} wl_country_t;
+-
+-typedef struct wl_channels_in_country {
+-	u32 buflen;
+-	u32 band;
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	u32 count;
+-	u32 channel[1];
+-} wl_channels_in_country_t;
+-
+-typedef struct wl_country_list {
+-	u32 buflen;
+-	u32 band_set;
+-	u32 band;
+-	u32 count;
+-	char country_abbrev[1];
+-} wl_country_list_t;
+-
+-#define WL_NUM_RPI_BINS		8
+-#define WL_RM_TYPE_BASIC	1
+-#define WL_RM_TYPE_CCA		2
+-#define WL_RM_TYPE_RPI		3
+-
+-#define WL_RM_FLAG_PARALLEL	(1<<0)
+-
+-#define WL_RM_FLAG_LATE		(1<<1)
+-#define WL_RM_FLAG_INCAPABLE	(1<<2)
+-#define WL_RM_FLAG_REFUSED	(1<<3)
+-
+-typedef struct wl_rm_req_elt {
+-	s8 type;
+-	s8 flags;
+-	chanspec_t chanspec;
+-	u32 token;		/* token for this measurement */
+-	u32 tsf_h;		/* TSF high 32-bits of Measurement start time */
+-	u32 tsf_l;		/* TSF low 32-bits */
+-	u32 dur;		/* TUs */
+-} wl_rm_req_elt_t;
+-
+-typedef struct wl_rm_req {
+-	u32 token;		/* overall measurement set token */
+-	u32 count;		/* number of measurement requests */
+-	void *cb;		/* completion callback function: may be NULL */
+-	void *cb_arg;		/* arg to completion callback function */
+-	wl_rm_req_elt_t req[1];	/* variable length block of requests */
+-} wl_rm_req_t;
+-#define WL_RM_REQ_FIXED_LEN	offsetof(wl_rm_req_t, req)
+-
+-typedef struct wl_rm_rep_elt {
+-	s8 type;
+-	s8 flags;
+-	chanspec_t chanspec;
+-	u32 token;		/* token for this measurement */
+-	u32 tsf_h;		/* TSF high 32-bits of Measurement start time */
+-	u32 tsf_l;		/* TSF low 32-bits */
+-	u32 dur;		/* TUs */
+-	u32 len;		/* byte length of data block */
+-	u8 data[1];		/* variable length data block */
+-} wl_rm_rep_elt_t;
+-#define WL_RM_REP_ELT_FIXED_LEN	24	/* length excluding data block */
+-
+-#define WL_RPI_REP_BIN_NUM 8
+-typedef struct wl_rm_rpi_rep {
+-	u8 rpi[WL_RPI_REP_BIN_NUM];
+-	s8 rpi_max[WL_RPI_REP_BIN_NUM];
+-} wl_rm_rpi_rep_t;
+-
+-typedef struct wl_rm_rep {
+-	u32 token;		/* overall measurement set token */
+-	u32 len;		/* length of measurement report block */
+-	wl_rm_rep_elt_t rep[1];	/* variable length block of reports */
+-} wl_rm_rep_t;
+-#define WL_RM_REP_FIXED_LEN	8
+-#endif /* BRCM_FULLMAC */
+-
+-/* Enumerate crypto algorithms */
+-#define	CRYPTO_ALGO_OFF			0
+-#define	CRYPTO_ALGO_WEP1		1
+-#define	CRYPTO_ALGO_TKIP		2
+-#define	CRYPTO_ALGO_WEP128		3
+-#define CRYPTO_ALGO_AES_CCM		4
+-#define CRYPTO_ALGO_AES_RESERVED1	5
+-#define CRYPTO_ALGO_AES_RESERVED2	6
+-#define CRYPTO_ALGO_NALG		7
+-
+-#define WSEC_GEN_MIC_ERROR	0x0001
+-#define WSEC_GEN_REPLAY		0x0002
+-#define WSEC_GEN_ICV_ERROR	0x0004
+-
+-#define WL_SOFT_KEY	(1 << 0)	/* Indicates this key is using soft encrypt */
+-#define WL_PRIMARY_KEY	(1 << 1)	/* Indicates this key is the primary (ie tx) key */
+-#define WL_KF_RES_4	(1 << 4)	/* Reserved for backward compat */
+-#define WL_KF_RES_5	(1 << 5)	/* Reserved for backward compat */
+-#define WL_IBSS_PEER_GROUP_KEY	(1 << 6)	/* Indicates a group key for a IBSS PEER */
+-
+-typedef struct wl_wsec_key {
+-	u32 index;		/* key index */
+-	u32 len;		/* key length */
+-	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
+-	u32 pad_1[18];
+-	u32 algo;		/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+-	u32 flags;		/* misc flags */
+-	u32 pad_2[2];
+-	int pad_3;
+-	int iv_initialized;	/* has IV been initialized already? */
+-	int pad_4;
+-	/* Rx IV */
+-	struct {
+-		u32 hi;	/* upper 32 bits of IV */
+-		u16 lo;	/* lower 16 bits of IV */
+-	} rxiv;
+-	u32 pad_5[2];
+-	u8 ea[ETH_ALEN];	/* per station */
+-} wl_wsec_key_t;
+-
+-#define WSEC_MIN_PSK_LEN	8
+-#define WSEC_MAX_PSK_LEN	64
+-
+-/* Flag for key material needing passhash'ing */
+-#define WSEC_PASSPHRASE		(1<<0)
+-
+-/* receptacle for WLC_SET_WSEC_PMK parameter */
+-typedef struct {
+-	unsigned short key_len;		/* octets in key material */
+-	unsigned short flags;		/* key handling qualification */
+-	u8 key[WSEC_MAX_PSK_LEN];	/* PMK material */
+-} wsec_pmk_t;
+-
+-/* wireless security bitvec */
+-#define WEP_ENABLED		0x0001
+-#define TKIP_ENABLED		0x0002
+-#define AES_ENABLED		0x0004
+-#define WSEC_SWFLAG		0x0008
+-#define SES_OW_ENABLED		0x0040	/* to go into transition mode without setting wep */
+-
+-/* WPA authentication mode bitvec */
+-#define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
+-#define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
+-#define WPA_AUTH_UNSPECIFIED	0x0002	/* over 802.1x */
+-#define WPA_AUTH_PSK		0x0004	/* Pre-shared key */
+-#define WPA_AUTH_RESERVED1	0x0008
+-#define WPA_AUTH_RESERVED2	0x0010
+-					/* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */
+-#define WPA2_AUTH_RESERVED1	0x0020
+-#define WPA2_AUTH_UNSPECIFIED	0x0040	/* over 802.1x */
+-#define WPA2_AUTH_PSK		0x0080	/* Pre-shared key */
+-#define WPA2_AUTH_RESERVED3	0x0200
+-#define WPA2_AUTH_RESERVED4	0x0400
+-#define WPA2_AUTH_RESERVED5	0x0800
+-
+-/* pmkid */
+-#define	MAXPMKID		16
+-
+-typedef struct _pmkid {
+-	u8 BSSID[ETH_ALEN];
+-	u8 PMKID[WLAN_PMKID_LEN];
+-} pmkid_t;
+-
+-typedef struct _pmkid_list {
+-	u32 npmkid;
+-	pmkid_t pmkid[1];
+-} pmkid_list_t;
+-
+-typedef struct _pmkid_cand {
+-	u8 BSSID[ETH_ALEN];
+-	u8 preauth;
+-} pmkid_cand_t;
+-
+-typedef struct _pmkid_cand_list {
+-	u32 npmkid_cand;
+-	pmkid_cand_t pmkid_cand[1];
+-} pmkid_cand_list_t;
+-
+-typedef struct wl_led_info {
+-	u32 index;		/* led index */
+-	u32 behavior;
+-	u8 activehi;
+-} wl_led_info_t;
+-
+-/* R_REG and W_REG struct passed through ioctl */
+-typedef struct {
+-	u32 byteoff;		/* byte offset of the field in d11regs_t */
+-	u32 val;		/* read/write value of the field */
+-	u32 size;		/* sizeof the field */
+-	uint band;		/* band (optional) */
+-} rw_reg_t;
+-
+-
+-#ifdef BRCM_FULLMAC
+-/* Used to get specific STA parameters */
+-typedef struct {
+-	u32 val;
+-	u8 ea[ETH_ALEN];
+-} scb_val_t;
+-#endif /* BRCM_FULLMAC */
+-
+-/* channel encoding */
+-typedef struct channel_info {
+-	int hw_channel;
+-	int target_channel;
+-	int scan_channel;
+-} channel_info_t;
+-
+-/* For ioctls that take a list of MAC addresses */
+-struct maclist {
+-	uint count;		/* number of MAC addresses */
+-	u8 ea[1][ETH_ALEN];	/* variable length array of MAC addresses */
+-};
+-
+-#ifdef BRCM_FULLMAC
+-/* Linux network driver ioctl encoding */
+-typedef struct wl_ioctl {
+-	uint cmd;		/* common ioctl definition */
+-	void *buf;		/* pointer to user buffer */
+-	uint len;		/* length of user buffer */
+-	u8 set;		/* get or set request (optional) */
+-	uint used;		/* bytes read or written (optional) */
+-	uint needed;		/* bytes needed (optional) */
+-} wl_ioctl_t;
+-#endif /* BRCM_FULLMAC */
+-
+-
+-/*
+- * Structure for passing hardware and software
+- * revision info up from the driver.
+- */
+-typedef struct wlc_rev_info {
+-	uint vendorid;		/* PCI vendor id */
+-	uint deviceid;		/* device id of chip */
+-	uint radiorev;		/* radio revision */
+-	uint chiprev;		/* chip revision */
+-	uint corerev;		/* core revision */
+-	uint boardid;		/* board identifier (usu. PCI sub-device id) */
+-	uint boardvendor;	/* board vendor (usu. PCI sub-vendor id) */
+-	uint boardrev;		/* board revision */
+-	uint driverrev;		/* driver version */
+-	uint ucoderev;		/* microcode version */
+-	uint bus;		/* bus type */
+-	uint chipnum;		/* chip number */
+-	uint phytype;		/* phy type */
+-	uint phyrev;		/* phy revision */
+-	uint anarev;		/* anacore rev */
+-	uint chippkg;		/* chip package info */
+-} wlc_rev_info_t;
+-
+-#define WL_REV_INFO_LEGACY_LENGTH	48
+-
+-#ifdef BRCM_FULLMAC
+-#define	WLC_IOCTL_SMLEN			256	/* "small" length ioctl buffer required */
+-#define WLC_IOCTL_MEDLEN		1536	/* "med" length ioctl buffer required */
+-#define	WLC_IOCTL_MAXLEN	8192
+-#endif
+-
+-/* common ioctl definitions */
+-#define WLC_GET_MAGIC				0
+-#define WLC_GET_VERSION				1
+-#define WLC_UP					2
+-#define WLC_DOWN				3
+-#define WLC_GET_LOOP				4
+-#define WLC_SET_LOOP				5
+-#define WLC_DUMP				6
+-#define WLC_GET_MSGLEVEL			7
+-#define WLC_SET_MSGLEVEL			8
+-#define WLC_GET_PROMISC				9
+-#define WLC_SET_PROMISC				10
+-#define WLC_OVERLAY_IOCTL			11
+-#define WLC_GET_RATE				12
+-						      /* #define WLC_SET_RATE				13 *//* no longer supported */
+-#define WLC_GET_INSTANCE			14
+-						      /* #define WLC_GET_FRAG				15 *//* no longer supported */
+-						      /* #define WLC_SET_FRAG				16 *//* no longer supported */
+-						      /* #define WLC_GET_RTS				17 *//* no longer supported */
+-						      /* #define WLC_SET_RTS				18 *//* no longer supported */
+-#define WLC_GET_INFRA				19
+-#define WLC_SET_INFRA				20
+-#define WLC_GET_AUTH				21
+-#define WLC_SET_AUTH				22
+-#define WLC_GET_BSSID				23
+-#define WLC_SET_BSSID				24
+-#define WLC_GET_SSID				25
+-#define WLC_SET_SSID				26
+-#define WLC_RESTART				27
+-						      /* #define WLC_DUMP_SCB				28 *//* no longer supported */
+-#define WLC_GET_CHANNEL				29
+-#define WLC_SET_CHANNEL				30
+-#define WLC_GET_SRL				31
+-#define WLC_SET_SRL				32
+-#define WLC_GET_LRL				33
+-#define WLC_SET_LRL				34
+-#define WLC_GET_PLCPHDR				35
+-#define WLC_SET_PLCPHDR				36
+-#define WLC_GET_RADIO				37
+-#define WLC_SET_RADIO				38
+-#define WLC_GET_PHYTYPE				39
+-#define WLC_DUMP_RATE				40
+-#define WLC_SET_RATE_PARAMS			41
+-#define WLC_GET_FIXRATE				42
+-#define WLC_SET_FIXRATE				43
+-						      /* #define WLC_GET_WEP				42 *//* no longer supported */
+-						      /* #define WLC_SET_WEP				43 *//* no longer supported */
+-#define WLC_GET_KEY				44
+-#define WLC_SET_KEY				45
+-#define WLC_GET_REGULATORY			46
+-#define WLC_SET_REGULATORY			47
+-#define WLC_GET_PASSIVE_SCAN			48
+-#define WLC_SET_PASSIVE_SCAN			49
+-#define WLC_SCAN				50
+-#define WLC_SCAN_RESULTS			51
+-#define WLC_DISASSOC				52
+-#define WLC_REASSOC				53
+-#define WLC_GET_ROAM_TRIGGER			54
+-#define WLC_SET_ROAM_TRIGGER			55
+-#define WLC_GET_ROAM_DELTA			56
+-#define WLC_SET_ROAM_DELTA			57
+-#define WLC_GET_ROAM_SCAN_PERIOD		58
+-#define WLC_SET_ROAM_SCAN_PERIOD		59
+-#define WLC_EVM					60	/* diag */
+-#define WLC_GET_TXANT				61
+-#define WLC_SET_TXANT				62
+-#define WLC_GET_ANTDIV				63
+-#define WLC_SET_ANTDIV				64
+-						      /* #define WLC_GET_TXPWR			65 *//* no longer supported */
+-						      /* #define WLC_SET_TXPWR			66 *//* no longer supported */
+-#define WLC_GET_CLOSED				67
+-#define WLC_SET_CLOSED				68
+-#define WLC_GET_MACLIST				69
+-#define WLC_SET_MACLIST				70
+-#define WLC_GET_RATESET				71
+-#define WLC_SET_RATESET				72
+-						      /* #define WLC_GET_LOCALE			73 *//* no longer supported */
+-#define WLC_LONGTRAIN				74
+-#define WLC_GET_BCNPRD				75
+-#define WLC_SET_BCNPRD				76
+-#define WLC_GET_DTIMPRD				77
+-#define WLC_SET_DTIMPRD				78
+-#define WLC_GET_SROM				79
+-#define WLC_SET_SROM				80
+-#define WLC_GET_WEP_RESTRICT			81
+-#define WLC_SET_WEP_RESTRICT			82
+-#define WLC_GET_COUNTRY				83
+-#define WLC_SET_COUNTRY				84
+-#define WLC_GET_PM				85
+-#define WLC_SET_PM				86
+-#define WLC_GET_WAKE				87
+-#define WLC_SET_WAKE				88
+-						      /* #define WLC_GET_D11CNTS			89 *//* -> "counters" iovar */
+-#define WLC_GET_FORCELINK			90	/* ndis only */
+-#define WLC_SET_FORCELINK			91	/* ndis only */
+-#define WLC_FREQ_ACCURACY			92	/* diag */
+-#define WLC_CARRIER_SUPPRESS			93	/* diag */
+-#define WLC_GET_PHYREG				94
+-#define WLC_SET_PHYREG				95
+-#define WLC_GET_RADIOREG			96
+-#define WLC_SET_RADIOREG			97
+-#define WLC_GET_REVINFO				98
+-#define WLC_GET_UCANTDIV			99
+-#define WLC_SET_UCANTDIV			100
+-#define WLC_R_REG				101
+-#define WLC_W_REG				102
+-/* #define WLC_DIAG_LOOPBACK			103	old tray diag */
+-						       /* #define WLC_RESET_D11CNTS			104 *//* -> "reset_d11cnts" iovar */
+-#define WLC_GET_MACMODE				105
+-#define WLC_SET_MACMODE				106
+-#define WLC_GET_MONITOR				107
+-#define WLC_SET_MONITOR				108
+-#define WLC_GET_GMODE				109
+-#define WLC_SET_GMODE				110
+-#define WLC_GET_LEGACY_ERP			111
+-#define WLC_SET_LEGACY_ERP			112
+-#define WLC_GET_RX_ANT				113
+-#define WLC_GET_CURR_RATESET			114	/* current rateset */
+-#define WLC_GET_SCANSUPPRESS			115
+-#define WLC_SET_SCANSUPPRESS			116
+-#define WLC_GET_AP				117
+-#define WLC_SET_AP				118
+-#define WLC_GET_EAP_RESTRICT			119
+-#define WLC_SET_EAP_RESTRICT			120
+-#define WLC_SCB_AUTHORIZE			121
+-#define WLC_SCB_DEAUTHORIZE			122
+-#define WLC_GET_WDSLIST				123
+-#define WLC_SET_WDSLIST				124
+-#define WLC_GET_ATIM				125
+-#define WLC_SET_ATIM				126
+-#define WLC_GET_RSSI				127
+-#define WLC_GET_PHYANTDIV			128
+-#define WLC_SET_PHYANTDIV			129
+-#define WLC_AP_RX_ONLY				130
+-#define WLC_GET_TX_PATH_PWR			131
+-#define WLC_SET_TX_PATH_PWR			132
+-#define WLC_GET_WSEC				133
+-#define WLC_SET_WSEC				134
+-#define WLC_GET_PHY_NOISE			135
+-#define WLC_GET_BSS_INFO			136
+-#define WLC_GET_PKTCNTS				137
+-#define WLC_GET_LAZYWDS				138
+-#define WLC_SET_LAZYWDS				139
+-#define WLC_GET_BANDLIST			140
+-#define WLC_GET_BAND				141
+-#define WLC_SET_BAND				142
+-#define WLC_SCB_DEAUTHENTICATE			143
+-#define WLC_GET_SHORTSLOT			144
+-#define WLC_GET_SHORTSLOT_OVERRIDE		145
+-#define WLC_SET_SHORTSLOT_OVERRIDE		146
+-#define WLC_GET_SHORTSLOT_RESTRICT		147
+-#define WLC_SET_SHORTSLOT_RESTRICT		148
+-#define WLC_GET_GMODE_PROTECTION		149
+-#define WLC_GET_GMODE_PROTECTION_OVERRIDE	150
+-#define WLC_SET_GMODE_PROTECTION_OVERRIDE	151
+-#define WLC_UPGRADE				152
+-						       /* #define WLC_GET_MRATE			153 *//* no longer supported */
+-						       /* #define WLC_SET_MRATE			154 *//* no longer supported */
+-#define WLC_GET_IGNORE_BCNS			155
+-#define WLC_SET_IGNORE_BCNS			156
+-#define WLC_GET_SCB_TIMEOUT			157
+-#define WLC_SET_SCB_TIMEOUT			158
+-#define WLC_GET_ASSOCLIST			159
+-#define WLC_GET_CLK				160
+-#define WLC_SET_CLK				161
+-#define WLC_GET_UP				162
+-#define WLC_OUT					163
+-#define WLC_GET_WPA_AUTH			164
+-#define WLC_SET_WPA_AUTH			165
+-#define WLC_GET_UCFLAGS				166
+-#define WLC_SET_UCFLAGS				167
+-#define WLC_GET_PWRIDX				168
+-#define WLC_SET_PWRIDX				169
+-#define WLC_GET_TSSI				170
+-#define WLC_GET_SUP_RATESET_OVERRIDE		171
+-#define WLC_SET_SUP_RATESET_OVERRIDE		172
+-						       /* #define WLC_SET_FAST_TIMER			173 *//* no longer supported */
+-						       /* #define WLC_GET_FAST_TIMER			174 *//* no longer supported */
+-						       /* #define WLC_SET_SLOW_TIMER			175 *//* no longer supported */
+-						       /* #define WLC_GET_SLOW_TIMER			176 *//* no longer supported */
+-						       /* #define WLC_DUMP_PHYREGS			177 *//* no longer supported */
+-#define WLC_GET_PROTECTION_CONTROL		178
+-#define WLC_SET_PROTECTION_CONTROL		179
+-#define WLC_GET_PHYLIST				180
+-#define WLC_ENCRYPT_STRENGTH			181	/* ndis only */
+-#define WLC_DECRYPT_STATUS			182	/* ndis only */
+-#define WLC_GET_KEY_SEQ				183
+-#define WLC_GET_SCAN_CHANNEL_TIME		184
+-#define WLC_SET_SCAN_CHANNEL_TIME		185
+-#define WLC_GET_SCAN_UNASSOC_TIME		186
+-#define WLC_SET_SCAN_UNASSOC_TIME		187
+-#define WLC_GET_SCAN_HOME_TIME			188
+-#define WLC_SET_SCAN_HOME_TIME			189
+-#define WLC_GET_SCAN_NPROBES			190
+-#define WLC_SET_SCAN_NPROBES			191
+-#define WLC_GET_PRB_RESP_TIMEOUT		192
+-#define WLC_SET_PRB_RESP_TIMEOUT		193
+-#define WLC_GET_ATTEN				194
+-#define WLC_SET_ATTEN				195
+-#define WLC_GET_SHMEM				196	/* diag */
+-#define WLC_SET_SHMEM				197	/* diag */
+-						       /* #define WLC_GET_GMODE_PROTECTION_CTS		198 *//* no longer supported */
+-						       /* #define WLC_SET_GMODE_PROTECTION_CTS		199 *//* no longer supported */
+-#define WLC_SET_WSEC_TEST			200
+-#define WLC_SCB_DEAUTHENTICATE_FOR_REASON	201
+-#define WLC_TKIP_COUNTERMEASURES		202
+-#define WLC_GET_PIOMODE				203
+-#define WLC_SET_PIOMODE				204
+-#define WLC_SET_ASSOC_PREFER			205
+-#define WLC_GET_ASSOC_PREFER			206
+-#define WLC_SET_ROAM_PREFER			207
+-#define WLC_GET_ROAM_PREFER			208
+-#define WLC_SET_LED				209
+-#define WLC_GET_LED				210
+-#define WLC_RESERVED6				211
+-#define WLC_RESERVED7				212
+-#define WLC_GET_CHANNEL_QA			213
+-#define WLC_START_CHANNEL_QA			214
+-#define WLC_GET_CHANNEL_SEL			215
+-#define WLC_START_CHANNEL_SEL			216
+-#define WLC_GET_VALID_CHANNELS			217
+-#define WLC_GET_FAKEFRAG			218
+-#define WLC_SET_FAKEFRAG			219
+-#define WLC_GET_PWROUT_PERCENTAGE		220
+-#define WLC_SET_PWROUT_PERCENTAGE		221
+-#define WLC_SET_BAD_FRAME_PREEMPT		222
+-#define WLC_GET_BAD_FRAME_PREEMPT		223
+-#define WLC_SET_LEAP_LIST			224
+-#define WLC_GET_LEAP_LIST			225
+-#define WLC_GET_CWMIN				226
+-#define WLC_SET_CWMIN				227
+-#define WLC_GET_CWMAX				228
+-#define WLC_SET_CWMAX				229
+-#define WLC_GET_WET				230
+-#define WLC_SET_WET				231
+-#define WLC_GET_PUB				232
+-						       /* #define WLC_SET_GLACIAL_TIMER		233 *//* no longer supported */
+-						       /* #define WLC_GET_GLACIAL_TIMER		234 *//* no longer supported */
+-#define WLC_GET_KEY_PRIMARY			235
+-#define WLC_SET_KEY_PRIMARY			236
+-						       /* #define WLC_DUMP_RADIOREGS			237 *//* no longer supported */
+-#define WLC_RESERVED4				238
+-#define WLC_RESERVED5				239
+-#define WLC_UNSET_CALLBACK			240
+-#define WLC_SET_CALLBACK			241
+-#define WLC_GET_RADAR				242
+-#define WLC_SET_RADAR				243
+-#define WLC_SET_SPECT_MANAGMENT			244
+-#define WLC_GET_SPECT_MANAGMENT			245
+-#define WLC_WDS_GET_REMOTE_HWADDR		246	/* handled in wl_linux.c/wl_vx.c */
+-#define WLC_WDS_GET_WPA_SUP			247
+-#define WLC_SET_CS_SCAN_TIMER			248
+-#define WLC_GET_CS_SCAN_TIMER			249
+-#define WLC_MEASURE_REQUEST			250
+-#define WLC_INIT				251
+-#define WLC_SEND_QUIET				252
+-#define WLC_KEEPALIVE			253
+-#define WLC_SEND_PWR_CONSTRAINT			254
+-#define WLC_UPGRADE_STATUS			255
+-#define WLC_CURRENT_PWR				256
+-#define WLC_GET_SCAN_PASSIVE_TIME		257
+-#define WLC_SET_SCAN_PASSIVE_TIME		258
+-#define WLC_LEGACY_LINK_BEHAVIOR		259
+-#define WLC_GET_CHANNELS_IN_COUNTRY		260
+-#define WLC_GET_COUNTRY_LIST			261
+-#define WLC_GET_VAR				262	/* get value of named variable */
+-#define WLC_SET_VAR				263	/* set named variable to value */
+-#define WLC_NVRAM_GET				264	/* deprecated */
+-#define WLC_NVRAM_SET				265
+-#define WLC_NVRAM_DUMP				266
+-#define WLC_REBOOT				267
+-#define WLC_SET_WSEC_PMK			268
+-#define WLC_GET_AUTH_MODE			269
+-#define WLC_SET_AUTH_MODE			270
+-#define WLC_GET_WAKEENTRY			271
+-#define WLC_SET_WAKEENTRY			272
+-#define WLC_NDCONFIG_ITEM			273	/* currently handled in wl_oid.c */
+-#define WLC_NVOTPW				274
+-#define WLC_OTPW				275
+-#define WLC_IOV_BLOCK_GET			276
+-#define WLC_IOV_MODULES_GET			277
+-#define WLC_SOFT_RESET				278
+-#define WLC_GET_ALLOW_MODE			279
+-#define WLC_SET_ALLOW_MODE			280
+-#define WLC_GET_DESIRED_BSSID			281
+-#define WLC_SET_DESIRED_BSSID			282
+-#define	WLC_DISASSOC_MYAP			283
+-#define WLC_GET_RESERVED10			284
+-#define WLC_GET_RESERVED11			285
+-#define WLC_GET_RESERVED12			286
+-#define WLC_GET_RESERVED13			287
+-#define WLC_GET_RESERVED14			288
+-#define WLC_SET_RESERVED15			289
+-#define WLC_SET_RESERVED16			290
+-#define WLC_GET_RESERVED17			291
+-#define WLC_GET_RESERVED18			292
+-#define WLC_GET_RESERVED19			293
+-#define WLC_SET_RESERVED1A			294
+-#define WLC_GET_RESERVED1B			295
+-#define WLC_GET_RESERVED1C			296
+-#define WLC_GET_RESERVED1D			297
+-#define WLC_SET_RESERVED1E			298
+-#define WLC_GET_RESERVED1F			299
+-#define WLC_GET_RESERVED20			300
+-#define WLC_GET_RESERVED21			301
+-#define WLC_GET_RESERVED22			302
+-#define WLC_GET_RESERVED23			303
+-#define WLC_GET_RESERVED24			304
+-#define WLC_SET_RESERVED25			305
+-#define WLC_GET_RESERVED26			306
+-#define WLC_NPHY_SAMPLE_COLLECT			307	/* Nphy sample collect mode */
+-#define WLC_UM_PRIV				308	/* for usermode driver private ioctl */
+-#define WLC_GET_CMD				309
+-							/* #define WLC_LAST				310 *//* Never used - can be reused */
+-#define WLC_RESERVED8				311
+-#define WLC_RESERVED9				312
+-#define WLC_RESERVED1				313
+-#define WLC_RESERVED2				314
+-#define WLC_RESERVED3				315
+-#define WLC_LAST				316
+-
+-#ifndef EPICTRL_COOKIE
+-#define EPICTRL_COOKIE		0xABADCEDE
+-#endif
+-
+-#define WL_DECRYPT_STATUS_SUCCESS	1
+-#define WL_DECRYPT_STATUS_FAILURE	2
+-#define WL_DECRYPT_STATUS_UNKNOWN	3
+-
+-/* allows user-mode app to poll the status of USB image upgrade */
+-#define WLC_UPGRADE_SUCCESS			0
+-#define WLC_UPGRADE_PENDING			1
+-
+-/* WLC_GET_AUTH, WLC_SET_AUTH values */
+-#define WL_AUTH_OPEN_SYSTEM		0	/* d11 open authentication */
+-#define WL_AUTH_SHARED_KEY		1	/* d11 shared authentication */
+-#define WL_AUTH_OPEN_SHARED		2	/* try open, then shared if open failed w/rc 13 */
+-
+-/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
+-#define WL_RADIO_SW_DISABLE		(1<<0)
+-#define WL_RADIO_HW_DISABLE		(1<<1)
+-#define WL_RADIO_MPC_DISABLE		(1<<2)
+-#define WL_RADIO_COUNTRY_DISABLE	(1<<3)	/* some countries don't support any channel */
+-
+-#define	WL_SPURAVOID_OFF	0
+-#define	WL_SPURAVOID_ON1	1
+-#define	WL_SPURAVOID_ON2	2
+-
+-/* Override bit for WLC_SET_TXPWR.  if set, ignore other level limits */
+-#define WL_TXPWR_OVERRIDE	(1U<<31)
+-
+-#define WL_PHY_PAVARS_LEN	6	/* Phy type, Band range, chain, a1, b0, b1 */
+-
+-typedef struct wl_po {
+-	u16 phy_type;	/* Phy type */
+-	u16 band;
+-	u16 cckpo;
+-	u32 ofdmpo;
+-	u16 mcspo[8];
+-} wl_po_t;
+-
+-/* a large TX Power as an init value to factor out of min() calculations,
+- * keep low enough to fit in an s8, units are .25 dBm
+- */
+-#define WLC_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
+-
+-/* "diag" iovar argument and error code */
+-#define WL_DIAG_INTERRUPT			1	/* d11 loopback interrupt test */
+-#define WL_DIAG_LOOPBACK			2	/* d11 loopback data test */
+-#define WL_DIAG_MEMORY				3	/* d11 memory test */
+-#define WL_DIAG_LED				4	/* LED test */
+-#define WL_DIAG_REG				5	/* d11/phy register test */
+-#define WL_DIAG_SROM				6	/* srom read/crc test */
+-#define WL_DIAG_DMA				7	/* DMA test */
+-
+-#define WL_DIAGERR_SUCCESS			0
+-#define WL_DIAGERR_FAIL_TO_RUN			1	/* unable to run requested diag */
+-#define WL_DIAGERR_NOT_SUPPORTED		2	/* diag requested is not supported */
+-#define WL_DIAGERR_INTERRUPT_FAIL		3	/* loopback interrupt test failed */
+-#define WL_DIAGERR_LOOPBACK_FAIL		4	/* loopback data test failed */
+-#define WL_DIAGERR_SROM_FAIL			5	/* srom read failed */
+-#define WL_DIAGERR_SROM_BADCRC			6	/* srom crc failed */
+-#define WL_DIAGERR_REG_FAIL			7	/* d11/phy register test failed */
+-#define WL_DIAGERR_MEMORY_FAIL			8	/* d11 memory test failed */
+-#define WL_DIAGERR_NOMEM			9	/* diag test failed due to no memory */
+-#define WL_DIAGERR_DMA_FAIL			10	/* DMA test failed */
+-
+-#define WL_DIAGERR_MEMORY_TIMEOUT		11	/* d11 memory test didn't finish in time */
+-#define WL_DIAGERR_MEMORY_BADPATTERN		12	/* d11 memory test result in bad pattern */
+-
+-/* band types */
+-#define	WLC_BAND_AUTO		0	/* auto-select */
+-#define	WLC_BAND_5G		1	/* 5 Ghz */
+-#define	WLC_BAND_2G		2	/* 2.4 Ghz */
+-#define	WLC_BAND_ALL		3	/* all bands */
+-
+-/* band range returned by band_range iovar */
+-#define WL_CHAN_FREQ_RANGE_2G      0
+-#define WL_CHAN_FREQ_RANGE_5GL     1
+-#define WL_CHAN_FREQ_RANGE_5GM     2
+-#define WL_CHAN_FREQ_RANGE_5GH     3
+-
+-/* phy types (returned by WLC_GET_PHYTPE) */
+-#define	WLC_PHY_TYPE_A		0
+-#define	WLC_PHY_TYPE_B		1
+-#define	WLC_PHY_TYPE_G		2
+-#define	WLC_PHY_TYPE_N		4
+-#define	WLC_PHY_TYPE_LP		5
+-#define	WLC_PHY_TYPE_SSN	6
+-#define	WLC_PHY_TYPE_HT		7
+-#define	WLC_PHY_TYPE_LCN	8
+-#define	WLC_PHY_TYPE_NULL	0xf
+-
+-/* MAC list modes */
+-#define WLC_MACMODE_DISABLED	0	/* MAC list disabled */
+-#define WLC_MACMODE_DENY	1	/* Deny specified (i.e. allow unspecified) */
+-#define WLC_MACMODE_ALLOW	2	/* Allow specified (i.e. deny unspecified) */
+-
+-/*
+- * 54g modes (basic bits may still be overridden)
+- *
+- * GMODE_LEGACY_B			Rateset: 1b, 2b, 5.5, 11
+- *					Preamble: Long
+- *					Shortslot: Off
+- * GMODE_AUTO				Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+- *					Extended Rateset: 6, 9, 12, 48
+- *					Preamble: Long
+- *					Shortslot: Auto
+- * GMODE_ONLY				Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
+- *					Extended Rateset: 6b, 9, 12b, 48
+- *					Preamble: Short required
+- *					Shortslot: Auto
+- * GMODE_B_DEFERRED			Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+- *					Extended Rateset: 6, 9, 12, 48
+- *					Preamble: Long
+- *					Shortslot: On
+- * GMODE_PERFORMANCE			Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
+- *					Preamble: Short required
+- *					Shortslot: On and required
+- * GMODE_LRS				Rateset: 1b, 2b, 5.5b, 11b
+- *					Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
+- *					Preamble: Long
+- *					Shortslot: Auto
+- */
+-#define GMODE_LEGACY_B		0
+-#define GMODE_AUTO		1
+-#define GMODE_ONLY		2
+-#define GMODE_B_DEFERRED	3
+-#define GMODE_PERFORMANCE	4
+-#define GMODE_LRS		5
+-#define GMODE_MAX		6
+-
+-/* values for PLCPHdr_override */
+-#define WLC_PLCP_AUTO	-1
+-#define WLC_PLCP_SHORT	0
+-#define WLC_PLCP_LONG	1
+-
+-/* values for g_protection_override and n_protection_override */
+-#define WLC_PROTECTION_AUTO		-1
+-#define WLC_PROTECTION_OFF		0
+-#define WLC_PROTECTION_ON		1
+-#define WLC_PROTECTION_MMHDR_ONLY	2
+-#define WLC_PROTECTION_CTS_ONLY		3
+-
+-/* values for g_protection_control and n_protection_control */
+-#define WLC_PROTECTION_CTL_OFF		0
+-#define WLC_PROTECTION_CTL_LOCAL	1
+-#define WLC_PROTECTION_CTL_OVERLAP	2
+-
+-/* values for n_protection */
+-#define WLC_N_PROTECTION_OFF		0
+-#define WLC_N_PROTECTION_OPTIONAL	1
+-#define WLC_N_PROTECTION_20IN40		2
+-#define WLC_N_PROTECTION_MIXEDMODE	3
+-
+-/* values for n_preamble_type */
+-#define WLC_N_PREAMBLE_MIXEDMODE	0
+-#define WLC_N_PREAMBLE_GF		1
+-#define WLC_N_PREAMBLE_GF_BRCM          2
+-
+-/* values for band specific 40MHz capabilities */
+-#define WLC_N_BW_20ALL			0
+-#define WLC_N_BW_40ALL			1
+-#define WLC_N_BW_20IN2G_40IN5G		2
+-
+-/* values to force tx/rx chain */
+-#define WLC_N_TXRX_CHAIN0		0
+-#define WLC_N_TXRX_CHAIN1		1
+-
+-/* bitflags for SGI support (sgi_rx iovar) */
+-#define WLC_N_SGI_20			0x01
+-#define WLC_N_SGI_40			0x02
+-
+-/* Values for PM */
+-#define PM_OFF	0
+-#define PM_MAX	1
+-
+-/* interference mitigation options */
+-#define	INTERFERE_OVRRIDE_OFF	-1	/* interference override off */
+-#define	INTERFERE_NONE	0	/* off */
+-#define	NON_WLAN	1	/* foreign/non 802.11 interference, no auto detect */
+-#define	WLAN_MANUAL	2	/* ACI: no auto detection */
+-#define	WLAN_AUTO	3	/* ACI: auto detect */
+-#define	WLAN_AUTO_W_NOISE	4	/* ACI: auto - detect and non 802.11 interference */
+-#define	AUTO_ACTIVE	(1 << 7)	/* Auto is currently active */
+-
+-#define WL_RSSI_ANT_VERSION	1	/* current version of wl_rssi_ant_t */
+-#define WL_ANT_RX_MAX		2	/* max 2 receive antennas */
+-#define WL_ANT_HT_RX_MAX	3	/* max 3 receive antennas/cores */
+-#define WL_ANT_IDX_1		0	/* antenna index 1 */
+-#define WL_ANT_IDX_2		1	/* antenna index 2 */
+-
+-#ifndef WL_RSSI_ANT_MAX
+-#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
+-#elif WL_RSSI_ANT_MAX != 4
+-#error "WL_RSSI_ANT_MAX does not match"
+-#endif
+-
+-/* RSSI per antenna */
+-typedef struct {
+-	u32 version;		/* version field */
+-	u32 count;		/* number of valid antenna rssi */
+-	s8 rssi_ant[WL_RSSI_ANT_MAX];	/* rssi per antenna */
+-} wl_rssi_ant_t;
+-
+-#define NUM_PWRCTRL_RATES 12
+-
+-typedef struct {
+-	u8 txpwr_band_max[NUM_PWRCTRL_RATES];	/* User set target */
+-	u8 txpwr_limit[NUM_PWRCTRL_RATES];	/* reg and local power limit */
+-	u8 txpwr_local_max;	/* local max according to the AP */
+-	u8 txpwr_local_constraint;	/* local constraint according to the AP */
+-	u8 txpwr_chan_reg_max;	/* Regulatory max for this channel */
+-	u8 txpwr_target[2][NUM_PWRCTRL_RATES];	/* Latest target for 2.4 and 5 Ghz */
+-	u8 txpwr_est_Pout[2];	/* Latest estimate for 2.4 and 5 Ghz */
+-	u8 txpwr_opo[NUM_PWRCTRL_RATES];	/* On G phy, OFDM power offset */
+-	u8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES];	/* Max CCK power for this band (SROM) */
+-	u8 txpwr_bphy_ofdm_max;	/* Max OFDM power for this band (SROM) */
+-	u8 txpwr_aphy_max[NUM_PWRCTRL_RATES];	/* Max power for A band (SROM) */
+-	s8 txpwr_antgain[2];	/* Ant gain for each band - from SROM */
+-	u8 txpwr_est_Pout_gofdm;	/* Pwr estimate for 2.4 OFDM */
+-} tx_power_legacy_t;
+-
+-#define WL_TX_POWER_RATES_LEGACY	45
+-#define WL_TX_POWER_MCS20_FIRST	        12
+-#define WL_TX_POWER_MCS20_NUM	        16
+-#define WL_TX_POWER_MCS40_FIRST	        28
+-#define WL_TX_POWER_MCS40_NUM	        17
+-
+-
+-#define WL_TX_POWER_RATES	       101
+-#define WL_TX_POWER_CCK_FIRST	       0
+-#define WL_TX_POWER_CCK_NUM	       4
+-#define WL_TX_POWER_OFDM_FIRST	       4	/* Index for first 20MHz OFDM SISO rate */
+-#define WL_TX_POWER_OFDM20_CDD_FIRST   12	/* Index for first 20MHz OFDM CDD rate */
+-#define WL_TX_POWER_OFDM40_SISO_FIRST  52	/* Index for first 40MHz OFDM SISO rate */
+-#define WL_TX_POWER_OFDM40_CDD_FIRST   60	/* Index for first 40MHz OFDM CDD rate */
+-#define WL_TX_POWER_OFDM_NUM	       8
+-#define WL_TX_POWER_MCS20_SISO_FIRST   20	/* Index for first 20MHz MCS SISO rate */
+-#define WL_TX_POWER_MCS20_CDD_FIRST    28	/* Index for first 20MHz MCS CDD rate */
+-#define WL_TX_POWER_MCS20_STBC_FIRST   36	/* Index for first 20MHz MCS STBC rate */
+-#define WL_TX_POWER_MCS20_SDM_FIRST    44	/* Index for first 20MHz MCS SDM rate */
+-#define WL_TX_POWER_MCS40_SISO_FIRST   68	/* Index for first 40MHz MCS SISO rate */
+-#define WL_TX_POWER_MCS40_CDD_FIRST    76	/* Index for first 40MHz MCS CDD rate */
+-#define WL_TX_POWER_MCS40_STBC_FIRST   84	/* Index for first 40MHz MCS STBC rate */
+-#define WL_TX_POWER_MCS40_SDM_FIRST    92	/* Index for first 40MHz MCS SDM rate */
+-#define WL_TX_POWER_MCS_1_STREAM_NUM   8
+-#define WL_TX_POWER_MCS_2_STREAM_NUM   8
+-#define WL_TX_POWER_MCS_32	       100	/* Index for 40MHz rate MCS 32 */
+-#define WL_TX_POWER_MCS_32_NUM	       1
+-
+-/* sslpnphy specifics */
+-#define WL_TX_POWER_MCS20_SISO_FIRST_SSN   12	/* Index for first 20MHz MCS SISO rate */
+-
+-/* tx_power_t.flags bits */
+-#define WL_TX_POWER_F_ENABLED	1
+-#define WL_TX_POWER_F_HW	2
+-#define WL_TX_POWER_F_MIMO	4
+-#define WL_TX_POWER_F_SISO	8
+-
+-typedef struct {
+-	u32 flags;
+-	chanspec_t chanspec;	/* txpwr report for this channel */
+-	chanspec_t local_chanspec;	/* channel on which we are associated */
+-	u8 local_max;	/* local max according to the AP */
+-	u8 local_constraint;	/* local constraint according to the AP */
+-	s8 antgain[2];	/* Ant gain for each band - from SROM */
+-	u8 rf_cores;		/* count of RF Cores being reported */
+-	u8 est_Pout[4];	/* Latest tx power out estimate per RF chain */
+-	u8 est_Pout_act[4];	/* Latest tx power out estimate per RF chain
+-				 * without adjustment
+-				 */
+-	u8 est_Pout_cck;	/* Latest CCK tx power out estimate */
+-	u8 tx_power_max[4];	/* Maximum target power among all rates */
+-	u8 tx_power_max_rate_ind[4];	/* Index of the rate with the max target power */
+-	u8 user_limit[WL_TX_POWER_RATES];	/* User limit */
+-	u8 reg_limit[WL_TX_POWER_RATES];	/* Regulatory power limit */
+-	u8 board_limit[WL_TX_POWER_RATES];	/* Max power board can support (SROM) */
+-	u8 target[WL_TX_POWER_RATES];	/* Latest target power */
+-} tx_power_t;
+-
+-typedef struct tx_inst_power {
+-	u8 txpwr_est_Pout[2];	/* Latest estimate for 2.4 and 5 Ghz */
+-	u8 txpwr_est_Pout_gofdm;	/* Pwr estimate for 2.4 OFDM */
+-} tx_inst_power_t;
+-
+-/* Message levels */
+-#define WL_ERROR_VAL		0x00000001
+-#define WL_TRACE_VAL		0x00000002
+-
+-/* maximum channels returned by the get valid channels iovar */
+-#define WL_NUMCHANNELS		64
+-#define WL_NUMCHANSPECS		100
+-
+-struct tsinfo_arg {
+-	u8 octets[3];
+-};
+-
+-#define	NFIFO			6	/* # tx/rx fifopairs */
+-
+-struct wl_msglevel2 {
+-	u32 low;
+-	u32 high;
+-};
+-
+-/* structure for per-tid ampdu control */
+-struct ampdu_tid_control {
+-	u8 tid;		/* tid */
+-	u8 enable;		/* enable/disable */
+-};
+-
+-/* structure for identifying ea/tid for sending addba/delba */
+-struct ampdu_ea_tid {
+-	u8 ea[ETH_ALEN];	/* Station address */
+-	u8 tid;		/* tid */
+-};
+-/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */
+-struct ampdu_retry_tid {
+-	u8 tid;		/* tid */
+-	u8 retry;		/* retry value */
+-};
+-
+-
+-/* Software feature flag defines used by wlfeatureflag */
+-#define WL_SWFL_NOHWRADIO	0x0004
+-#define WL_SWFL_FLOWCONTROL     0x0008	/* Enable backpressure to OS stack */
+-#define WL_SWFL_WLBSSSORT	0x0010	/* Per-port supports sorting of BSS */
+-
+-#define WL_LIFETIME_MAX 0xFFFF	/* Max value in ms */
+-
+-
+-/* Pattern matching filter. Specifies an offset within received packets to
+- * start matching, the pattern to match, the size of the pattern, and a bitmask
+- * that indicates which bits within the pattern should be matched.
+- */
+-typedef struct wl_pkt_filter_pattern {
+-	u32 offset;		/* Offset within received packet to start pattern matching.
+-				 * Offset '0' is the first byte of the ethernet header.
+-				 */
+-	u32 size_bytes;	/* Size of the pattern.  Bitmask must be the same size. */
+-	u8 mask_and_pattern[1];	/* Variable length mask and pattern data.  mask starts
+-					 * at offset 0.  Pattern immediately follows mask.
+-					 */
+-} wl_pkt_filter_pattern_t;
+-
+-/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
+-typedef struct wl_pkt_filter {
+-	u32 id;		/* Unique filter id, specified by app. */
+-	u32 type;		/* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+-	u32 negate_match;	/* Negate the result of filter matches */
+-	union {			/* Filter definitions */
+-		wl_pkt_filter_pattern_t pattern;	/* Pattern matching filter */
+-	} u;
+-} wl_pkt_filter_t;
+-
+-#define WL_PKT_FILTER_FIXED_LEN		  offsetof(wl_pkt_filter_t, u)
+-#define WL_PKT_FILTER_PATTERN_FIXED_LEN	  offsetof(wl_pkt_filter_pattern_t, mask_and_pattern)
+-
+-/* IOVAR "pkt_filter_enable" parameter. */
+-typedef struct wl_pkt_filter_enable {
+-	u32 id;		/* Unique filter id */
+-	u32 enable;		/* Enable/disable bool */
+-} wl_pkt_filter_enable_t;
+-
+-
+-#define	WLC_RSSI_INVALID	 0	/* invalid RSSI value */
+-
+-/* n-mode support capability */
+-/* 2x2 includes both 1x1 & 2x2 devices
+- * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
+- * control it independently
+- */
+-#define WL_11N_2x2			1
+-#define WL_11N_3x3			3
+-#define WL_11N_4x4			4
+-
+-/* define 11n feature disable flags */
+-#define WLFEATURE_DISABLE_11N		0x00000001
+-#define WLFEATURE_DISABLE_11N_STBC_TX	0x00000002
+-#define WLFEATURE_DISABLE_11N_STBC_RX	0x00000004
+-#define WLFEATURE_DISABLE_11N_SGI_TX	0x00000008
+-#define WLFEATURE_DISABLE_11N_SGI_RX	0x00000010
+-#define WLFEATURE_DISABLE_11N_AMPDU_TX	0x00000020
+-#define WLFEATURE_DISABLE_11N_AMPDU_RX	0x00000040
+-#define WLFEATURE_DISABLE_11N_GF	0x00000080
+-
+-#define WL_EVENTING_MASK_LEN	16
+-
+-#define TOE_TX_CSUM_OL		0x00000001
+-#define TOE_RX_CSUM_OL		0x00000002
+-
+-#define PM_OFF	0
+-#define PM_MAX	1
+-#define PM_FAST 2
+-
+-typedef enum sup_auth_status {
+-	WLC_SUP_DISCONNECTED = 0,
+-	WLC_SUP_CONNECTING,
+-	WLC_SUP_IDREQUIRED,
+-	WLC_SUP_AUTHENTICATING,
+-	WLC_SUP_AUTHENTICATED,
+-	WLC_SUP_KEYXCHANGE,
+-	WLC_SUP_KEYED,
+-	WLC_SUP_TIMEOUT,
+-	WLC_SUP_LAST_BASIC_STATE,
+-	WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED,
+-	WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE,
+-	WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE,
+-	WLC_SUP_KEYXCHANGE_PREP_M4,
+-	WLC_SUP_KEYXCHANGE_WAIT_G1,
+-	WLC_SUP_KEYXCHANGE_PREP_G2
+-} sup_auth_status_t;
+-#endif				/* _wlioctl_h_ */
+diff --git a/drivers/staging/brcm80211/util/Makefile b/drivers/staging/brcm80211/util/Makefile
+deleted file mode 100644
+index f9b36ca..0000000
+--- a/drivers/staging/brcm80211/util/Makefile
++++ /dev/null
+@@ -1,29 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
+-#
+-# Copyright (c) 2011 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=				\
+-	-Idrivers/staging/brcm80211/util \
+-	-Idrivers/staging/brcm80211/include
+-
+-BRCMUTIL_OFILES := \
+-	bcmutils.o \
+-	bcmwifi.o
+-
+-MODULEPFX := brcmutil
+-
+-obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
+-$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
+diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c
+deleted file mode 100644
+index 43e5bb3..0000000
+--- a/drivers/staging/brcm80211/util/bcmutils.c
++++ /dev/null
+@@ -1,796 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/ctype.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/netdevice.h>
+-#include <linux/sched.h>
+-#include <linux/printk.h>
+-#include <bcmdefs.h>
+-#include <stdarg.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <bcmdevs.h>
+-#include <proto/802.11.h>
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-struct sk_buff *bcm_pkt_buf_get_skb(uint len)
+-{
+-	struct sk_buff *skb;
+-
+-	skb = dev_alloc_skb(len);
+-	if (skb) {
+-		skb_put(skb, len);
+-		skb->priority = 0;
+-	}
+-
+-	return skb;
+-}
+-EXPORT_SYMBOL(bcm_pkt_buf_get_skb);
+-
+-/* Free the driver packet. Free the tag if present */
+-void bcm_pkt_buf_free_skb(struct sk_buff *skb)
+-{
+-	struct sk_buff *nskb;
+-	int nest = 0;
+-
+-	/* perversion: we use skb->next to chain multi-skb packets */
+-	while (skb) {
+-		nskb = skb->next;
+-		skb->next = NULL;
+-
+-		if (skb->destructor)
+-			/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
+-			 * destructor exists
+-			 */
+-			dev_kfree_skb_any(skb);
+-		else
+-			/* can free immediately (even in_irq()) if destructor
+-			 * does not exist
+-			 */
+-			dev_kfree_skb(skb);
+-
+-		nest++;
+-		skb = nskb;
+-	}
+-}
+-EXPORT_SYMBOL(bcm_pkt_buf_free_skb);
+-
+-
+-/* copy a buffer into a pkt buffer chain */
+-uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len,
+-		unsigned char *buf)
+-{
+-	uint n, ret = 0;
+-
+-	/* skip 'offset' bytes */
+-	for (; p && offset; p = p->next) {
+-		if (offset < (uint) (p->len))
+-			break;
+-		offset -= p->len;
+-	}
+-
+-	if (!p)
+-		return 0;
+-
+-	/* copy the data */
+-	for (; p && len; p = p->next) {
+-		n = min((uint) (p->len) - offset, (uint) len);
+-		memcpy(p->data + offset, buf, n);
+-		buf += n;
+-		len -= n;
+-		ret += n;
+-		offset = 0;
+-	}
+-
+-	return ret;
+-}
+-EXPORT_SYMBOL(bcm_pktfrombuf);
+-
+-/* return total length of buffer chain */
+-uint bcm_pkttotlen(struct sk_buff *p)
+-{
+-	uint total;
+-
+-	total = 0;
+-	for (; p; p = p->next)
+-		total += p->len;
+-	return total;
+-}
+-EXPORT_SYMBOL(bcm_pkttotlen);
+-
+-/*
+- * osl multiple-precedence packet queue
+- * hi_prec is always >= the number of the highest non-empty precedence
+- */
+-struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
+-				      struct sk_buff *p)
+-{
+-	struct pktq_prec *q;
+-
+-	if (pktq_full(pq) || pktq_pfull(pq, prec))
+-		return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	if (q->head)
+-		q->tail->prev = p;
+-	else
+-		q->head = p;
+-
+-	q->tail = p;
+-	q->len++;
+-
+-	pq->len++;
+-
+-	if (pq->hi_prec < prec)
+-		pq->hi_prec = (u8) prec;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_penq);
+-
+-struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
+-					   struct sk_buff *p)
+-{
+-	struct pktq_prec *q;
+-
+-	if (pktq_full(pq) || pktq_pfull(pq, prec))
+-		return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	if (q->head == NULL)
+-		q->tail = p;
+-
+-	p->prev = q->head;
+-	q->head = p;
+-	q->len++;
+-
+-	pq->len++;
+-
+-	if (pq->hi_prec < prec)
+-		pq->hi_prec = (u8) prec;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_penq_head);
+-
+-struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	q->head = p->prev;
+-	if (q->head == NULL)
+-		q->tail = NULL;
+-
+-	q->len--;
+-
+-	pq->len--;
+-
+-	p->prev = NULL;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_pdeq);
+-
+-struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p, *prev;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	for (prev = NULL; p != q->tail; p = p->prev)
+-		prev = p;
+-
+-	if (prev)
+-		prev->prev = NULL;
+-	else
+-		q->head = NULL;
+-
+-	q->tail = prev;
+-	q->len--;
+-
+-	pq->len--;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_pdeq_tail);
+-
+-void
+-bcm_pktq_pflush(struct pktq *pq, int prec, bool dir,
+-	    ifpkt_cb_t fn, void *arg)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p, *prev = NULL;
+-
+-	q = &pq->q[prec];
+-	p = q->head;
+-	while (p) {
+-		if (fn == NULL || (*fn) (p, arg)) {
+-			bool head = (p == q->head);
+-			if (head)
+-				q->head = p->prev;
+-			else
+-				prev->prev = p->prev;
+-			p->prev = NULL;
+-			bcm_pkt_buf_free_skb(p);
+-			q->len--;
+-			pq->len--;
+-			p = (head ? q->head : prev->prev);
+-		} else {
+-			prev = p;
+-			p = p->prev;
+-		}
+-	}
+-
+-	if (q->head == NULL) {
+-		q->tail = NULL;
+-	}
+-}
+-EXPORT_SYMBOL(bcm_pktq_pflush);
+-
+-void bcm_pktq_flush(struct pktq *pq, bool dir,
+-		ifpkt_cb_t fn, void *arg)
+-{
+-	int prec;
+-	for (prec = 0; prec < pq->num_prec; prec++)
+-		bcm_pktq_pflush(pq, prec, dir, fn, arg);
+-}
+-EXPORT_SYMBOL(bcm_pktq_flush);
+-
+-void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len)
+-{
+-	int prec;
+-
+-	/* pq is variable size; only zero out what's requested */
+-	memset(pq, 0,
+-	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
+-
+-	pq->num_prec = (u16) num_prec;
+-
+-	pq->max = (u16) max_len;
+-
+-	for (prec = 0; prec < num_prec; prec++)
+-		pq->q[prec].max = pq->max;
+-}
+-EXPORT_SYMBOL(bcm_pktq_init);
+-
+-struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out)
+-{
+-	int prec;
+-
+-	if (pq->len == 0)
+-		return NULL;
+-
+-	for (prec = 0; prec < pq->hi_prec; prec++)
+-		if (pq->q[prec].head)
+-			break;
+-
+-	if (prec_out)
+-		*prec_out = prec;
+-
+-	return pq->q[prec].tail;
+-}
+-EXPORT_SYMBOL(bcm_pktq_peek_tail);
+-
+-/* Return sum of lengths of a specific set of precedences */
+-int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp)
+-{
+-	int prec, len;
+-
+-	len = 0;
+-
+-	for (prec = 0; prec <= pq->hi_prec; prec++)
+-		if (prec_bmp & (1 << prec))
+-			len += pq->q[prec].len;
+-
+-	return len;
+-}
+-EXPORT_SYMBOL(bcm_pktq_mlen);
+-
+-/* Priority dequeue from a specific set of precedences */
+-struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
+-				      int *prec_out)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p;
+-	int prec;
+-
+-	if (pq->len == 0)
+-		return NULL;
+-
+-	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+-		pq->hi_prec--;
+-
+-	while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+-		if (prec-- == 0)
+-			return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	q->head = p->prev;
+-	if (q->head == NULL)
+-		q->tail = NULL;
+-
+-	q->len--;
+-
+-	if (prec_out)
+-		*prec_out = prec;
+-
+-	pq->len--;
+-
+-	p->prev = NULL;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_mdeq);
+-
+-/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+-int bcm_ether_atoe(char *p, u8 *ea)
+-{
+-	int i = 0;
+-
+-	for (;;) {
+-		ea[i++] = (char)simple_strtoul(p, &p, 16);
+-		if (!*p++ || i == 6)
+-			break;
+-	}
+-
+-	return i == 6;
+-}
+-EXPORT_SYMBOL(bcm_ether_atoe);
+-
+-#if defined(BCMDBG)
+-/* pretty hex print a pkt buffer chain */
+-void bcm_prpkt(const char *msg, struct sk_buff *p0)
+-{
+-	struct sk_buff *p;
+-
+-	if (msg && (msg[0] != '\0'))
+-		printk(KERN_DEBUG "%s:\n", msg);
+-
+-	for (p = p0; p; p = p->next)
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
+-}
+-EXPORT_SYMBOL(bcm_prpkt);
+-#endif				/* defined(BCMDBG) */
+-
+-/* iovar table lookup */
+-const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
+-{
+-	const bcm_iovar_t *vi;
+-	const char *lookup_name;
+-
+-	/* skip any ':' delimited option prefixes */
+-	lookup_name = strrchr(name, ':');
+-	if (lookup_name != NULL)
+-		lookup_name++;
+-	else
+-		lookup_name = name;
+-
+-	for (vi = table; vi->name; vi++) {
+-		if (!strcmp(vi->name, lookup_name))
+-			return vi;
+-	}
+-	/* ran to end of table */
+-
+-	return NULL;		/* var name not found */
+-}
+-EXPORT_SYMBOL(bcm_iovar_lookup);
+-
+-int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
+-{
+-	int bcmerror = 0;
+-
+-	/* length check on io buf */
+-	switch (vi->type) {
+-	case IOVT_BOOL:
+-	case IOVT_INT8:
+-	case IOVT_INT16:
+-	case IOVT_INT32:
+-	case IOVT_UINT8:
+-	case IOVT_UINT16:
+-	case IOVT_UINT32:
+-		/* all integers are s32 sized args at the ioctl interface */
+-		if (len < (int)sizeof(int)) {
+-			bcmerror = -EOVERFLOW;
+-		}
+-		break;
+-
+-	case IOVT_BUFFER:
+-		/* buffer must meet minimum length requirement */
+-		if (len < vi->minlen) {
+-			bcmerror = -EOVERFLOW;
+-		}
+-		break;
+-
+-	case IOVT_VOID:
+-		if (!set) {
+-			/* Cannot return nil... */
+-			bcmerror = -ENOTSUPP;
+-		} else if (len) {
+-			/* Set is an action w/o parameters */
+-			bcmerror = -ENOBUFS;
+-		}
+-		break;
+-
+-	default:
+-		/* unknown type for length check in iovar info */
+-		bcmerror = -ENOTSUPP;
+-	}
+-
+-	return bcmerror;
+-}
+-EXPORT_SYMBOL(bcm_iovar_lencheck);
+-
+-/*******************************************************************************
+- * crc8
+- *
+- * Computes a crc8 over the input data using the polynomial:
+- *
+- *       x^8 + x^7 +x^6 + x^4 + x^2 + 1
+- *
+- * The caller provides the initial value (either CRC8_INIT_VALUE
+- * or the previous returned value) to allow for processing of
+- * discontiguous blocks of data.  When generating the CRC the
+- * caller is responsible for complementing the final return value
+- * and inserting it into the byte stream.  When checking, a final
+- * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+- *
+- * Reference: Dallas Semiconductor Application Note 27
+- *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+- *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+- *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+- *
+- * ****************************************************************************
+- */
+-
+-static const u8 crc8_table[256] = {
+-	0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+-	0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+-	0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+-	0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+-	0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+-	0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+-	0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+-	0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+-	0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+-	0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+-	0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+-	0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+-	0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+-	0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+-	0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+-	0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+-	0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+-	0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+-	0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+-	0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+-	0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+-	0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+-	0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+-	0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+-	0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+-	0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+-	0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+-	0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+-	0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+-	0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+-	0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+-	0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+-};
+-
+-u8 bcm_crc8(u8 *pdata,	/* pointer to array of data to process */
+-			 uint nbytes,	/* number of input data bytes to process */
+-			 u8 crc	/* either CRC8_INIT_VALUE or previous return value */
+-    ) {
+-	/* loop over the buffer data */
+-	while (nbytes-- > 0)
+-		crc = crc8_table[(crc ^ *pdata++) & 0xff];
+-
+-	return crc;
+-}
+-EXPORT_SYMBOL(bcm_crc8);
+-
+-/*
+- * Traverse a string of 1-byte tag/1-byte length/variable-length value
+- * triples, returning a pointer to the substring whose first element
+- * matches tag
+- */
+-bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key)
+-{
+-	bcm_tlv_t *elt;
+-	int totlen;
+-
+-	elt = (bcm_tlv_t *) buf;
+-	totlen = buflen;
+-
+-	/* find tagged parameter */
+-	while (totlen >= 2) {
+-		int len = elt->len;
+-
+-		/* validate remaining totlen */
+-		if ((elt->id == key) && (totlen >= (len + 2)))
+-			return elt;
+-
+-		elt = (bcm_tlv_t *) ((u8 *) elt + (len + 2));
+-		totlen -= (len + 2);
+-	}
+-
+-	return NULL;
+-}
+-EXPORT_SYMBOL(bcm_parse_tlvs);
+-
+-
+-#if defined(BCMDBG)
+-int
+-bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, char *buf, int len)
+-{
+-	int i;
+-	char *p = buf;
+-	char hexstr[16];
+-	int slen = 0, nlen = 0;
+-	u32 bit;
+-	const char *name;
+-
+-	if (len < 2 || !buf)
+-		return 0;
+-
+-	buf[0] = '\0';
+-
+-	for (i = 0; flags != 0; i++) {
+-		bit = bd[i].bit;
+-		name = bd[i].name;
+-		if (bit == 0 && flags != 0) {
+-			/* print any unnamed bits */
+-			snprintf(hexstr, 16, "0x%X", flags);
+-			name = hexstr;
+-			flags = 0;	/* exit loop */
+-		} else if ((flags & bit) == 0)
+-			continue;
+-		flags &= ~bit;
+-		nlen = strlen(name);
+-		slen += nlen;
+-		/* count btwn flag space */
+-		if (flags != 0)
+-			slen += 1;
+-		/* need NULL char as well */
+-		if (len <= slen)
+-			break;
+-		/* copy NULL char but don't count it */
+-		strncpy(p, name, nlen + 1);
+-		p += nlen;
+-		/* copy btwn flag space and NULL char */
+-		if (flags != 0)
+-			p += snprintf(p, 2, " ");
+-		len -= slen;
+-	}
+-
+-	/* indicate the str was too short */
+-	if (flags != 0) {
+-		if (len < 2)
+-			p -= 2 - len;	/* overwrite last char */
+-		p += snprintf(p, 2, ">");
+-	}
+-
+-	return (int)(p - buf);
+-}
+-EXPORT_SYMBOL(bcm_format_flags);
+-
+-/* print bytes formatted as hex to a string. return the resulting string length */
+-int bcm_format_hex(char *str, const void *bytes, int len)
+-{
+-	int i;
+-	char *p = str;
+-	const u8 *src = (const u8 *)bytes;
+-
+-	for (i = 0; i < len; i++) {
+-		p += snprintf(p, 3, "%02X", *src);
+-		src++;
+-	}
+-	return (int)(p - str);
+-}
+-EXPORT_SYMBOL(bcm_format_hex);
+-#endif				/* defined(BCMDBG) */
+-
+-char *bcm_chipname(uint chipid, char *buf, uint len)
+-{
+-	const char *fmt;
+-
+-	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+-	snprintf(buf, len, fmt, chipid);
+-	return buf;
+-}
+-EXPORT_SYMBOL(bcm_chipname);
+-
+-uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+-{
+-	uint len;
+-
+-	len = strlen(name) + 1;
+-
+-	if ((len + datalen) > buflen)
+-		return 0;
+-
+-	strncpy(buf, name, buflen);
+-
+-	/* append data onto the end of the name string */
+-	memcpy(&buf[len], data, datalen);
+-	len += datalen;
+-
+-	return len;
+-}
+-EXPORT_SYMBOL(bcm_mkiovar);
+-
+-/* Quarter dBm units to mW
+- * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+- * Table is offset so the last entry is largest mW value that fits in
+- * a u16.
+- */
+-
+-#define QDBM_OFFSET 153		/* Offset for first entry */
+-#define QDBM_TABLE_LEN 40	/* Table size */
+-
+-/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+- * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+- */
+-#define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
+-
+-/* Largest mW value that will round down to the last table entry,
+- * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+- * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
+- * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+- */
+-#define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
+-
+-static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+-/* qdBm: 	+0 	+1 	+2 	+3 	+4 	+5 	+6 	+7 */
+-/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+-/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+-/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+-/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+-/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+-};
+-
+-u16 bcm_qdbm_to_mw(u8 qdbm)
+-{
+-	uint factor = 1;
+-	int idx = qdbm - QDBM_OFFSET;
+-
+-	if (idx >= QDBM_TABLE_LEN) {
+-		/* clamp to max u16 mW value */
+-		return 0xFFFF;
+-	}
+-
+-	/* scale the qdBm index up to the range of the table 0-40
+-	 * where an offset of 40 qdBm equals a factor of 10 mW.
+-	 */
+-	while (idx < 0) {
+-		idx += 40;
+-		factor *= 10;
+-	}
+-
+-	/* return the mW value scaled down to the correct factor of 10,
+-	 * adding in factor/2 to get proper rounding.
+-	 */
+-	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+-}
+-EXPORT_SYMBOL(bcm_qdbm_to_mw);
+-
+-u8 bcm_mw_to_qdbm(u16 mw)
+-{
+-	u8 qdbm;
+-	int offset;
+-	uint mw_uint = mw;
+-	uint boundary;
+-
+-	/* handle boundary case */
+-	if (mw_uint <= 1)
+-		return 0;
+-
+-	offset = QDBM_OFFSET;
+-
+-	/* move mw into the range of the table */
+-	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+-		mw_uint *= 10;
+-		offset -= 40;
+-	}
+-
+-	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+-		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+-						    nqdBm_to_mW_map[qdbm]) / 2;
+-		if (mw_uint < boundary)
+-			break;
+-	}
+-
+-	qdbm += (u8) offset;
+-
+-	return qdbm;
+-}
+-EXPORT_SYMBOL(bcm_mw_to_qdbm);
+-
+-uint bcm_bitcount(u8 *bitmap, uint length)
+-{
+-	uint bitcount = 0, i;
+-	u8 tmp;
+-	for (i = 0; i < length; i++) {
+-		tmp = bitmap[i];
+-		while (tmp) {
+-			bitcount++;
+-			tmp &= (tmp - 1);
+-		}
+-	}
+-	return bitcount;
+-}
+-EXPORT_SYMBOL(bcm_bitcount);
+-
+-/* Initialization of bcmstrbuf structure */
+-void bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
+-{
+-	b->origsize = b->size = size;
+-	b->origbuf = b->buf = buf;
+-}
+-EXPORT_SYMBOL(bcm_binit);
+-
+-/* Buffer sprintf wrapper to guard against buffer overflow */
+-int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
+-{
+-	va_list ap;
+-	int r;
+-
+-	va_start(ap, fmt);
+-	r = vsnprintf(b->buf, b->size, fmt, ap);
+-
+-	/* Non Ansi C99 compliant returns -1,
+-	 * Ansi compliant return r >= b->size,
+-	 * bcmstdlib returns 0, handle all
+-	 */
+-	if ((r == -1) || (r >= (int)b->size) || (r == 0)) {
+-		b->size = 0;
+-	} else {
+-		b->size -= r;
+-		b->buf += r;
+-	}
+-
+-	va_end(ap);
+-
+-	return r;
+-}
+-EXPORT_SYMBOL(bcm_bprintf);
+diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c
+deleted file mode 100644
+index 955a3ab..0000000
+--- a/drivers/staging/brcm80211/util/bcmwifi.c
++++ /dev/null
+@@ -1,137 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/ctype.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-
+-/*
+- * Verify the chanspec is using a legal set of parameters, i.e. that the
+- * chanspec specified a band, bw, ctl_sb and channel and that the
+- * combination could be legal given any set of circumstances.
+- * RETURNS: true is the chanspec is malformed, false if it looks good.
+- */
+-bool bcm_chspec_malformed(chanspec_t chanspec)
+-{
+-	/* must be 2G or 5G band */
+-	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
+-		return true;
+-	/* must be 20 or 40 bandwidth */
+-	if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
+-		return true;
+-
+-	/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
+-	if (CHSPEC_IS20(chanspec)) {
+-		if (!CHSPEC_SB_NONE(chanspec))
+-			return true;
+-	} else {
+-		if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
+-			return true;
+-	}
+-
+-	return false;
+-}
+-EXPORT_SYMBOL(bcm_chspec_malformed);
+-
+-/*
+- * This function returns the channel number that control traffic is being sent on, for legacy
+- * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+- * sideband depending on the chanspec selected
+- */
+-u8 bcm_chspec_ctlchan(chanspec_t chspec)
+-{
+-	u8 ctl_chan;
+-
+-	/* Is there a sideband ? */
+-	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+-		return CHSPEC_CHANNEL(chspec);
+-	} else {
+-		/* we only support 40MHZ with sidebands */
+-		/* chanspec channel holds the centre frequency, use that and the
+-		 * side band information to reconstruct the control channel number
+-		 */
+-		if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+-			/* control chan is the upper 20 MHZ SB of the 40MHZ channel */
+-			ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+-		} else {
+-			/* control chan is the lower 20 MHZ SB of the 40MHZ channel */
+-			ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+-		}
+-	}
+-
+-	return ctl_chan;
+-}
+-EXPORT_SYMBOL(bcm_chspec_ctlchan);
+-
+-/*
+- * Return the channel number for a given frequency and base frequency.
+- * The returned channel number is relative to the given base frequency.
+- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+- *
+- * Frequency is specified in MHz.
+- * The base frequency is specified as (start_factor * 500 kHz).
+- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+- * 2.4 GHz and 5 GHz bands.
+- *
+- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+- * and [0, 200] otherwise.
+- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+- *
+- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+- */
+-int bcm_mhz2channel(uint freq, uint start_factor)
+-{
+-	int ch = -1;
+-	uint base;
+-	int offset;
+-
+-	/* take the default channel start frequency */
+-	if (start_factor == 0) {
+-		if (freq >= 2400 && freq <= 2500)
+-			start_factor = WF_CHAN_FACTOR_2_4_G;
+-		else if (freq >= 5000 && freq <= 6000)
+-			start_factor = WF_CHAN_FACTOR_5_G;
+-	}
+-
+-	if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
+-		return 14;
+-
+-	base = start_factor / 2;
+-
+-	/* check that the frequency is in 1GHz range of the base */
+-	if ((freq < base) || (freq > base + 1000))
+-		return -1;
+-
+-	offset = freq - base;
+-	ch = offset / 5;
+-
+-	/* check that frequency is a 5MHz multiple from the base */
+-	if (offset != (ch * 5))
+-		return -1;
+-
+-	/* restricted channel range check for 2.4G */
+-	if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
+-		return -1;
+-
+-	return ch;
+-}
+-EXPORT_SYMBOL(bcm_mhz2channel);
+-
+-- 
+1.7.9.5
+
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): add brcm80211 driver backported from v3.5
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig John Weber
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Adds a backported driver from kernel v3.5 for brcm80211.  Used with
bcm4329 and other Broadcom Wifi devices.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ....0.35-Add-brcm80211-driver-backported-fro.patch |94038 ++++++++++++++++++++
 1 files changed, 94039 insertions(+)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
new file mode 100644
index 0000000..1ed5f50
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
@@ -0,0 +1,94038 @@
+From 99044f426f004207f6256add552e64a509c205fd Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Sat, 9 Mar 2013 09:25:52 -0600
+Subject: [meta-fsl-arm-extra][PATCH 2/2] linux-imx (3.0.35): Add brcm80211
+ driver backported from 3.5
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ drivers/net/wireless/Kconfig                       |    2 +
+ drivers/net/wireless/Makefile                      |    4 +
+ drivers/net/wireless/brcm80211/Kconfig             |   62 +
+ drivers/net/wireless/brcm80211/Makefile            |   23 +
+ drivers/net/wireless/brcm80211/brcmfmac/Makefile   |   36 +
+ drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  550 +
+ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  703 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |  669 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |  118 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |  495 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |  882 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |   79 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    | 1232 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_proto.h    |   53 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4014 +++
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |  622 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.h    |  136 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |  272 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb.c      | 1617 ++
+ drivers/net/wireless/brcm80211/brcmfmac/usb.h      |   61 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h  |   75 +
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  | 3881 +++
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |  366 +
+ drivers/net/wireless/brcm80211/brcmsmac/Makefile   |   48 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.c  |  841 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.h  |  248 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.c    | 1236 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.h    |   30 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.c   |  307 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.h   |   29 +
+ .../brcm80211/brcmsmac/brcms_trace_events.c        |   23 +
+ .../brcm80211/brcmsmac/brcms_trace_events.h        |   92 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.c  | 1506 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.h  |   53 +
+ drivers/net/wireless/brcm80211/brcmsmac/d11.h      | 1901 ++
+ drivers/net/wireless/brcm80211/brcmsmac/dma.c      | 1444 +
+ drivers/net/wireless/brcm80211/brcmsmac/dma.h      |  122 +
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  | 1609 ++
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.h  |  108 +
+ drivers/net/wireless/brcm80211/brcmsmac/main.c     | 8495 ++++++
+ drivers/net/wireless/brcm80211/brcmsmac/main.h     |  720 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c  | 2961 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_hal.h  |  299 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_int.h  | 1162 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  | 5137 ++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h  |  121 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c    |28685 ++++++++++++++++++++
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.c    |  308 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.h    |   42 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_radio.h    | 1533 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h |  167 +
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   | 3250 +++
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h   |   54 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c |10630 ++++++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h |   50 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c |  216 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h |  179 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.c      |  375 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.h      |   35 +
+ drivers/net/wireless/brcm80211/brcmsmac/pub.h      |  372 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.c     |  514 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.h     |  249 +
+ drivers/net/wireless/brcm80211/brcmsmac/scb.h      |   82 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.c      |  438 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.h      |   42 +
+ drivers/net/wireless/brcm80211/brcmsmac/types.h    |  304 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.c |  109 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.h |   58 +
+ drivers/net/wireless/brcm80211/brcmutil/Makefile   |   28 +
+ drivers/net/wireless/brcm80211/brcmutil/utils.c    |  278 +
+ .../net/wireless/brcm80211/include/brcm_hw_ids.h   |   41 +
+ .../net/wireless/brcm80211/include/brcmu_utils.h   |  196 +
+ .../net/wireless/brcm80211/include/brcmu_wifi.h    |  239 +
+ .../net/wireless/brcm80211/include/chipcommon.h    |  286 +
+ drivers/net/wireless/brcm80211/include/defs.h      |  103 +
+ drivers/net/wireless/brcm80211/include/soc.h       |   98 +
+ 76 files changed, 93405 insertions(+)
+ create mode 100644 drivers/net/wireless/brcm80211/Kconfig
+ create mode 100644 drivers/net/wireless/brcm80211/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/d11.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pub.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/scb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/types.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/utils.c
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_utils.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/chipcommon.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/defs.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/soc.h
+
+diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
+index fbcf861..d7da434 100644
+--- a/drivers/net/wireless/Kconfig
++++ b/drivers/net/wireless/Kconfig
+@@ -271,6 +271,7 @@ config MWL8K
+ source "drivers/net/wireless/ath/Kconfig"
+ source "drivers/net/wireless/b43/Kconfig"
+ source "drivers/net/wireless/b43legacy/Kconfig"
++source "drivers/net/wireless/brcm80211/Kconfig"
+ source "drivers/net/wireless/hostap/Kconfig"
+ source "drivers/net/wireless/ipw2x00/Kconfig"
+ source "drivers/net/wireless/iwlwifi/Kconfig"
+@@ -288,4 +289,5 @@ source "drivers/net/wireless/mwifiex/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ 
++
+ endif # WLAN
+diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
+index 60a0a41..69a03f4 100644
+--- a/drivers/net/wireless/Makefile
++++ b/drivers/net/wireless/Makefile
+@@ -59,3 +59,7 @@ obj-$(CONFIG_IWM)	+= iwmc3200wifi/
+ 
+ obj-$(CONFIG_MWIFIEX)	+= mwifiex/
+ #obj-$(CONFIG_ATH6K_LEGACY)	+= ath6kl/
++
++obj-$(CONFIG_BRCMFMAC) += brcm80211/
++obj-$(CONFIG_BRCMUMAC) += brcm80211/
++obj-$(CONFIG_BRCMSMAC) += brcm80211/
+diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
+new file mode 100644
+index 0000000..b480088
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Kconfig
+@@ -0,0 +1,62 @@
++config BRCMUTIL
++	tristate
++
++config BRCMSMAC
++	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
++	depends on MAC80211
++	depends on BCMA
++	select BRCMUTIL
++	select FW_LOADER
++	select CRC_CCITT
++	select CRC8
++	select CORDIC
++	---help---
++	  This module adds support for PCIe wireless adapters based on Broadcom
++	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
++	  be called brcmsmac.ko.
++
++config BRCMFMAC
++	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
++	depends on CFG80211
++	select BRCMUTIL
++	---help---
++	  This module adds support for embedded wireless adapters based on
++	  Broadcom IEEE802.11n FullMAC chipsets. It has to work with at least
++	  one of the bus interface support. If you choose to build a module,
++	  it'll be called brcmfmac.ko.
++
++config BRCMFMAC_SDIO
++	bool "SDIO bus interface support for FullMAC driver"
++	depends on MMC
++	depends on BRCMFMAC
++	select FW_LOADER
++	default y
++	---help---
++	  This option enables the SDIO bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for a SDIO wireless card.
++
++config BRCMFMAC_SDIO_OOB
++	bool "Out of band interrupt support for SDIO interface chipset"
++	depends on BRCMFMAC_SDIO
++	---help---
++	  This option enables out-of-band interrupt support for Broadcom
++	  SDIO Wifi chipset using fullmac in order to gain better
++	  performance and deep sleep wake up capability on certain
++	  platforms. Say N if you are unsure.
++
++config BRCMFMAC_USB
++	bool "USB bus interface support for FullMAC driver"
++	depends on USB
++	depends on BRCMFMAC
++	select FW_LOADER
++	---help---
++	  This option enables the USB bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for an USB wireless card.
++
++config BRCMDBG
++	bool "Broadcom driver debug functions"
++	depends on BRCMSMAC || BRCMFMAC
++	---help---
++	  Selecting this enables additional code for debug purposes.
+diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile
+new file mode 100644
+index 0000000..b987920
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Makefile
+@@ -0,0 +1,23 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++# common flags
++subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DDEBUG
++
++obj-$(CONFIG_BRCMUTIL)	+= brcmutil/
++obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
++obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+new file mode 100644
+index 0000000..a4c4d1c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+@@ -0,0 +1,36 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y += \
++	-I$(obj)		\
++	-I$(obj)/../include
++
++ccflags-y += -D__CHECK_ENDIAN__
++
++obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
++brcmfmac-objs += \
++		wl_cfg80211.o \
++		dhd_cdc.o \
++		dhd_common.o \
++		dhd_linux.o
++brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
++		dhd_sdio.o \
++		bcmsdh.o \
++		bcmsdh_sdmmc.o \
++		sdio_chip.o
++brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
++		usb.o
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+new file mode 100644
+index 0000000..a87f141
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -0,0 +1,550 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ****************** SDIO CARD Interface Functions **************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++#include <linux/pci.h>
++#include <linux/pci_ids.h>
++#include <linux/sched.h>
++#include <linux/completion.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <soc.h>
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++
++#define SDIOH_API_ACCESS_RETRY_LIMIT	2
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id);
++
++	brcmf_dbg(INTR, "oob intr triggered\n");
++
++	/*
++	 * out-of-band interrupt is level-triggered which won't
++	 * be cleared until dpc
++	 */
++	if (sdiodev->irq_en) {
++		disable_irq_nosync(irq);
++		sdiodev->irq_en = false;
++	}
++
++	brcmf_sdbrcm_isr(sdiodev->bus);
++
++	return IRQ_HANDLED;
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	int ret = 0;
++	u8 data;
++	unsigned long flags;
++
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
++	ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
++			  sdiodev->irq_flags, "brcmf_oob_intr",
++			  &sdiodev->func[1]->card->dev);
++	if (ret != 0)
++		return ret;
++	spin_lock_init(&sdiodev->irq_en_lock);
++	spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
++	sdiodev->irq_en = true;
++	spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
++
++	ret = enable_irq_wake(sdiodev->irq);
++	if (ret != 0)
++		return ret;
++	sdiodev->irq_wake = true;
++
++	/* must configure SDIO_CCCR_IENx to enable irq */
++	data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
++	data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
++
++	/* redirect, configure and enable io for interrupt signal */
++	data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
++	if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
++		data |= SDIO_SEPINT_ACT_HI;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
++
++	if (sdiodev->irq_wake) {
++		disable_irq_wake(sdiodev->irq);
++		sdiodev->irq_wake = false;
++	}
++	free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev);
++	sdiodev->irq_en = false;
++
++	return 0;
++}
++#else		/* CONFIG_BRCMFMAC_SDIO_OOB */
++static void brcmf_sdio_irqhandler(struct sdio_func *func)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_dbg(INTR, "ib intr triggered\n");
++
++	sdio_release_host(sdiodev->func[1]);
++	brcmf_sdbrcm_isr(sdiodev->bus);
++	sdio_claim_host(sdiodev->func[1]);
++}
++
++/* dummy handler for SDIO function 2 interrupt */
++static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
++{
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler);
++	sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_release_irq(sdiodev->func[2]);
++	sdio_release_irq(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++int
++brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
++{
++	int err = 0, i;
++	u8 addr[3];
++	s32 retry;
++
++	addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
++	addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
++	addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
++
++	for (i = 0; i < 3; i++) {
++		retry = 0;
++		do {
++			if (retry)
++				usleep_range(1000, 2000);
++			err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
++					SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
++					&addr[i]);
++		} while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++		if (err) {
++			brcmf_dbg(ERROR, "failed at addr:0x%0x\n",
++				  SBSDIO_FUNC1_SBADDRLOW + i);
++			break;
++		}
++	}
++
++	return err;
++}
++
++static int
++brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			void *data, bool write)
++{
++	u8 func_num, reg_size;
++	u32 bar;
++	s32 retry = 0;
++	int ret;
++
++	/*
++	 * figure out how to read the register based on address range
++	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
++	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
++	 * The rest: function 1 silicon backplane core registers
++	 */
++	if ((addr & ~REG_F0_REG_MASK) == 0) {
++		func_num = SDIO_FUNC_0;
++		reg_size = 1;
++	} else if ((addr & ~REG_F1_MISC_MASK) == 0) {
++		func_num = SDIO_FUNC_1;
++		reg_size = 1;
++	} else {
++		func_num = SDIO_FUNC_1;
++		reg_size = 4;
++
++		/* Set the window for SB core register */
++		bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++		if (bar != sdiodev->sbwad) {
++			ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
++			if (ret != 0) {
++				memset(data, 0xFF, reg_size);
++				return ret;
++			}
++			sdiodev->sbwad = bar;
++		}
++		addr &= SBSDIO_SB_OFT_ADDR_MASK;
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++	}
++
++	do {
++		if (!write)
++			memset(data, 0, reg_size);
++		if (retry)	/* wait for 1 ms till bus get settled down */
++			usleep_range(1000, 2000);
++		if (reg_size == 1)
++			ret = brcmf_sdioh_request_byte(sdiodev, write,
++						       func_num, addr, data);
++		else
++			ret = brcmf_sdioh_request_word(sdiodev, write,
++						       func_num, addr, data, 4);
++	} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++	if (ret != 0)
++		brcmf_dbg(ERROR, "failed with %d\n", ret);
++
++	return ret;
++}
++
++u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u8 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%02x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u32 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%08x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u8 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u32 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
++				     uint flags, uint width, u32 *addr)
++{
++	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	if (width == 4)
++		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return 0;
++}
++
++int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt);
++	if (!err)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
++					 fn, addr, pkt);
++
++	return err;
++}
++
++int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			    uint flags, struct sk_buff_head *pktq)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pktq->qlen);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
++					pktq);
++
++	return err;
++}
++
++int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	memcpy(mypkt->data, buf, nbytes);
++	err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, mypkt);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++
++}
++
++int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	if (width == 4)
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
++					  addr, pkt);
++}
++
++int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
++			u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	bool write = rw ? SDIOH_WRITE : SDIOH_READ;
++	int err;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	/* For a write, copy the buffer data into the packet. */
++	if (write)
++		memcpy(mypkt->data, buf, nbytes);
++
++	err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write,
++					 SDIO_FUNC_1, addr, mypkt);
++
++	/* For a read, copy the packet data back to the buffer. */
++	if (!err && !write)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
++{
++	char t_func = (char)fn;
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* issue abort cmd52 command through F0 */
++	brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
++				 SDIO_CCCR_ABORT, &t_func);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return 0;
++}
++
++int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
++{
++	u32 regs = 0;
++	int ret = 0;
++
++	ret = brcmf_sdioh_attach(sdiodev);
++	if (ret)
++		goto out;
++
++	regs = SI_ENUM_BASE;
++
++	/* Report the BAR, to fix if needed */
++	sdiodev->sbwad = SI_ENUM_BASE;
++
++	/* try to attach to the target device */
++	sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev);
++	if (!sdiodev->bus) {
++		brcmf_dbg(ERROR, "device attach failed\n");
++		ret = -ENODEV;
++		goto out;
++	}
++
++out:
++	if (ret)
++		brcmf_sdio_remove(sdiodev);
++
++	return ret;
++}
++EXPORT_SYMBOL(brcmf_sdio_probe);
++
++int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
++{
++	if (sdiodev->bus) {
++		brcmf_sdbrcm_disconnect(sdiodev->bus);
++		sdiodev->bus = NULL;
++	}
++
++	brcmf_sdioh_detach(sdiodev);
++
++	sdiodev->sbwad = 0;
++
++	return 0;
++}
++EXPORT_SYMBOL(brcmf_sdio_remove);
++
++void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
++{
++	if (enable)
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
++	else
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+new file mode 100644
+index 0000000..391a721
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+@@ -0,0 +1,703 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/core.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/sdio_ids.h>
++#include <linux/mmc/card.h>
++#include <linux/suspend.h>
++#include <linux/errno.h>
++#include <linux/sched.h>	/* request_irq() */
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include "sdio_host.h"
++#include "dhd_dbg.h"
++#include "dhd_bus.h"
++
++#define SDIO_VENDOR_ID_BROADCOM		0x02d0
++
++#define DMA_ALIGN_MASK	0x03
++
++#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
++#define SDIO_DEVICE_ID_BROADCOM_4330	0x4330
++
++#define SDIO_FUNC1_BLOCKSIZE		64
++#define SDIO_FUNC2_BLOCKSIZE		512
++
++/* devices we support, null terminated */
++static const struct sdio_device_id brcmf_sdmmc_ids[] = {
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
++	{ /* end: all zeroes */ },
++};
++MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static struct list_head oobirq_lh;
++struct brcmf_sdio_oobirq {
++	unsigned int irq;
++	unsigned long flags;
++	struct list_head list;
++};
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool
++brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
++{
++	bool is_err = false;
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	is_err = atomic_read(&sdiodev->suspend);
++#endif
++	return is_err;
++}
++
++static void
++brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
++{
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	int retry = 0;
++	while (atomic_read(&sdiodev->suspend) && retry++ != 30)
++		wait_event_timeout(*wq, false, HZ/100);
++#endif
++}
++
++static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
++					    uint regaddr, u8 *byte)
++{
++	struct sdio_func *sdfunc = sdiodev->func[0];
++	int err_ret;
++
++	/*
++	 * Can only directly write to some F0 registers.
++	 * Handle F2 enable/disable and Abort command
++	 * as a special case.
++	 */
++	if (regaddr == SDIO_CCCR_IOEx) {
++		sdfunc = sdiodev->func[2];
++		if (sdfunc) {
++			sdio_claim_host(sdfunc);
++			if (*byte & SDIO_FUNC_ENABLE_2) {
++				/* Enable Function 2 */
++				err_ret = sdio_enable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "enable F2 failed:%d\n",
++						  err_ret);
++			} else {
++				/* Disable Function 2 */
++				err_ret = sdio_disable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "Disable F2 failed:%d\n",
++						  err_ret);
++			}
++			sdio_release_host(sdfunc);
++		}
++	} else if ((regaddr == SDIO_CCCR_ABORT) ||
++		   (regaddr == SDIO_CCCR_IENx)) {
++		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
++				 GFP_KERNEL);
++		if (!sdfunc)
++			return -ENOMEM;
++		sdfunc->num = 0;
++		sdio_claim_host(sdfunc);
++		sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++		kfree(sdfunc);
++	} else if (regaddr < 0xF0) {
++		brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
++		err_ret = -EPERM;
++	} else {
++		sdio_claim_host(sdfunc);
++		sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++	}
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
++			     uint regaddr, u8 *byte)
++{
++	int err_ret;
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	if (rw && func == 0) {
++		/* handle F0 separately */
++		err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
++	} else {
++		sdio_claim_host(sdiodev->func[func]);
++		if (rw) /* CMD52 Write */
++			sdio_writeb(sdiodev->func[func], *byte, regaddr,
++				    &err_ret);
++		else if (func == 0) {
++			*byte = sdio_f0_readb(sdiodev->func[func], regaddr,
++					      &err_ret);
++		} else {
++			*byte = sdio_readb(sdiodev->func[func], regaddr,
++					   &err_ret);
++		}
++		sdio_release_host(sdiodev->func[func]);
++	}
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
++			  rw ? "write" : "read", func, regaddr, *byte, err_ret);
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			     uint rw, uint func, uint addr, u32 *word,
++			     uint nbytes)
++{
++	int err_ret = -EIO;
++
++	if (func == 0) {
++		brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
++		return -EINVAL;
++	}
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
++		  rw, func, addr, nbytes);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	if (rw) {		/* CMD52 Write */
++		if (nbytes == 4)
++			sdio_writel(sdiodev->func[func], *word, addr,
++				    &err_ret);
++		else if (nbytes == 2)
++			sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
++				    addr, &err_ret);
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	} else {		/* CMD52 Read */
++		if (nbytes == 4)
++			*word = sdio_readl(sdiodev->func[func], addr, &err_ret);
++		else if (nbytes == 2)
++			*word = sdio_readw(sdiodev->func[func], addr,
++					   &err_ret) & 0xFFFF;
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
++			  rw ? "write" : "read", err_ret);
++
++	return err_ret;
++}
++
++/* precondition: host controller is claimed */
++static int
++brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
++			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
++{
++	int err_ret = 0;
++
++	if ((write) && (!fifo)) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (write) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (fifo) {
++		err_ret = sdio_readsb(sdiodev->func[func],
++				      ((u8 *) (pkt->data)), addr, pktlen);
++	} else {
++		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
++					     ((u8 *) (pkt->data)),
++					     addr, pktlen);
++	}
++
++	return err_ret;
++}
++
++/*
++ * This function takes a queue of packets. The packets on the queue
++ * are assumed to be properly aligned by the caller.
++ */
++int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq)
++{
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++	u32 SGCount = 0;
++	int err_ret = 0;
++
++	struct sk_buff *pkt;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	skb_queue_walk(pktq, pkt) {
++		uint pkt_len = pkt->len;
++		pkt_len += 3;
++		pkt_len &= 0xFFFFFFFC;
++
++		err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++						   addr, pkt, pkt_len);
++		if (err_ret) {
++			brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len, err_ret);
++		} else {
++			brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len);
++		}
++		if (!fifo)
++			addr += pkt_len;
++
++		SGCount++;
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return err_ret;
++}
++
++/*
++ * This function takes a single DMA-able packet.
++ */
++int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			       uint fix_inc, uint write, uint func, uint addr,
++			       struct sk_buff *pkt)
++{
++	int status;
++	uint pkt_len;
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (pkt == NULL)
++		return -EINVAL;
++	pkt_len = pkt->len;
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	pkt_len += 3;
++	pkt_len &= (uint)~3;
++
++	status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++					   addr, pkt, pkt_len);
++	if (status) {
++		brcmf_dbg(ERROR, "%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len, status);
++	} else {
++		brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	return status;
++}
++
++static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
++{
++	/* read 24 bits and return valid 17 bit addr */
++	int i, ret;
++	u32 scratch, regdata;
++	__le32 scratch_le;
++	u8 *ptr = (u8 *)&scratch_le;
++
++	for (i = 0; i < 3; i++) {
++		regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "Can't read!\n");
++
++		*ptr++ = (u8) regdata;
++		regaddr++;
++	}
++
++	/* Only the lower 17-bits are valid */
++	scratch = le32_to_cpu(scratch_le);
++	scratch &= 0x0001FFFF;
++	return scratch;
++}
++
++static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret;
++	u32 fbraddr;
++	u8 func;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Get the Card's common CIS address */
++	sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
++							   SDIO_CCCR_CIS);
++	brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
++		  sdiodev->func_cis_ptr[0]);
++
++	/* Get the Card's function CIS (for each function) */
++	for (fbraddr = SDIO_FBR_BASE(1), func = 1;
++	     func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
++		sdiodev->func_cis_ptr[func] =
++		    brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
++		brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
++			  func, sdiodev->func_cis_ptr[func]);
++	}
++
++	/* Enable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_enable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
++
++	return false;
++}
++
++/*
++ *	Public entry points & extern's
++ */
++int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	sdiodev->num_funcs = 2;
++
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
++		goto out;
++	}
++
++	sdio_claim_host(sdiodev->func[2]);
++	err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[2]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
++		goto out;
++	}
++
++	brcmf_sdioh_enablefuncs(sdiodev);
++
++out:
++	brcmf_dbg(TRACE, "Done\n");
++	return err_ret;
++}
++
++void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "\n");
++
++	/* Disable Function 2 */
++	sdio_claim_host(sdiodev->func[2]);
++	sdio_disable_func(sdiodev->func[2]);
++	sdio_release_host(sdiodev->func[2]);
++
++	/* Disable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_disable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	struct brcmf_sdio_oobirq *oobirq_entry;
++
++	if (list_empty(&oobirq_lh)) {
++		brcmf_dbg(ERROR, "no valid oob irq resource\n");
++		return -ENXIO;
++	}
++
++	oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq,
++					list);
++
++	sdiodev->irq = oobirq_entry->irq;
++	sdiodev->irq_flags = oobirq_entry->flags;
++	list_del(&oobirq_entry->list);
++	kfree(oobirq_entry);
++
++	return 0;
++}
++#else
++static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static int brcmf_ops_sdio_probe(struct sdio_func *func,
++			      const struct sdio_device_id *id)
++{
++	int ret = 0;
++	struct brcmf_sdio_dev *sdiodev;
++	struct brcmf_bus *bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(TRACE, "func->class=%x\n", func->class);
++	brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 1) {
++		if (dev_get_drvdata(&func->card->dev)) {
++			brcmf_dbg(ERROR, "card private drvdata occupied\n");
++			return -ENXIO;
++		}
++		bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
++		if (!bus_if)
++			return -ENOMEM;
++		sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
++		if (!sdiodev) {
++			kfree(bus_if);
++			return -ENOMEM;
++		}
++		sdiodev->func[0] = func;
++		sdiodev->func[1] = func;
++		sdiodev->bus_if = bus_if;
++		bus_if->bus_priv.sdio = sdiodev;
++		bus_if->type = SDIO_BUS;
++		bus_if->align = BRCMF_SDALIGN;
++		dev_set_drvdata(&func->card->dev, sdiodev);
++
++		atomic_set(&sdiodev->suspend, false);
++		init_waitqueue_head(&sdiodev->request_byte_wait);
++		init_waitqueue_head(&sdiodev->request_word_wait);
++		init_waitqueue_head(&sdiodev->request_chain_wait);
++		init_waitqueue_head(&sdiodev->request_buffer_wait);
++	}
++
++	if (func->num == 2) {
++		sdiodev = dev_get_drvdata(&func->card->dev);
++		if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
++			return -ENODEV;
++
++		ret = brcmf_sdio_getintrcfg(sdiodev);
++		if (ret)
++			return ret;
++		sdiodev->func[2] = func;
++
++		bus_if = sdiodev->bus_if;
++		sdiodev->dev = &func->dev;
++		dev_set_drvdata(&func->dev, bus_if);
++
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
++		ret = brcmf_sdio_probe(sdiodev);
++	}
++
++	return ret;
++}
++
++static void brcmf_ops_sdio_remove(struct sdio_func *func)
++{
++	struct brcmf_bus *bus_if;
++	struct brcmf_sdio_dev *sdiodev;
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(INFO, "func->class=%x\n", func->class);
++	brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 2) {
++		bus_if = dev_get_drvdata(&func->dev);
++		sdiodev = bus_if->bus_priv.sdio;
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
++		brcmf_sdio_remove(sdiodev);
++		dev_set_drvdata(&func->card->dev, NULL);
++		dev_set_drvdata(&func->dev, NULL);
++		kfree(bus_if);
++		kfree(sdiodev);
++	}
++}
++
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++static int brcmf_sdio_suspend(struct device *dev)
++{
++	mmc_pm_flag_t sdio_flags;
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	atomic_set(&sdiodev->suspend, true);
++
++	sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
++	if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
++		brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
++		return -EINVAL;
++	}
++
++	ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
++	if (ret) {
++		brcmf_dbg(ERROR, "Failed to set pm_flags\n");
++		return ret;
++	}
++
++	brcmf_sdio_wdtmr_enable(sdiodev, false);
++
++	return ret;
++}
++
++static int brcmf_sdio_resume(struct device *dev)
++{
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_sdio_wdtmr_enable(sdiodev, true);
++	atomic_set(&sdiodev->suspend, false);
++	return 0;
++}
++
++static const struct dev_pm_ops brcmf_sdio_pm_ops = {
++	.suspend	= brcmf_sdio_suspend,
++	.resume		= brcmf_sdio_resume,
++};
++#endif	/* CONFIG_PM_SLEEP */
++
++static struct sdio_driver brcmf_sdmmc_driver = {
++	.probe = brcmf_ops_sdio_probe,
++	.remove = brcmf_ops_sdio_remove,
++	.name = "brcmfmac",
++	.id_table = brcmf_sdmmc_ids,
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	.drv = {
++		.pm = &brcmf_sdio_pm_ops,
++	},
++#endif	/* CONFIG_PM_SLEEP */
++};
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_pd_probe(struct platform_device *pdev)
++{
++	struct resource *res;
++	struct brcmf_sdio_oobirq *oobirq_entry;
++	int i, ret;
++
++	INIT_LIST_HEAD(&oobirq_lh);
++
++	for (i = 0; ; i++) {
++		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
++		if (!res)
++			break;
++
++		oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
++				       GFP_KERNEL);
++		oobirq_entry->irq = res->start;
++		oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
++		list_add_tail(&oobirq_entry->list, &oobirq_lh);
++	}
++	if (i == 0)
++		return -ENXIO;
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++
++	return ret;
++}
++
++static struct platform_driver brcmf_sdio_pd = {
++	.probe		= brcmf_sdio_pd_probe,
++	.driver		= {
++		.name	= "brcmf_sdio_pd"
++	}
++};
++
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++
++	platform_driver_unregister(&brcmf_sdio_pd);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = platform_driver_register(&brcmf_sdio_pd);
++
++	if (ret)
++		brcmf_dbg(ERROR, "platform_driver_register failed: %d\n", ret);
++}
++#else
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+new file mode 100644
+index 0000000..9f63701
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+@@ -0,0 +1,669 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/****************
++ * Common types *
++ */
++
++#ifndef _BRCMF_H_
++#define _BRCMF_H_
++
++#define BRCMF_VERSION_STR		"4.218.248.5"
++
++/*******************************************************************************
++ * IO codes that are interpreted by dongle firmware
++ ******************************************************************************/
++#define BRCMF_C_UP				2
++#define BRCMF_C_SET_PROMISC			10
++#define BRCMF_C_GET_RATE			12
++#define BRCMF_C_GET_INFRA			19
++#define BRCMF_C_SET_INFRA			20
++#define BRCMF_C_GET_AUTH			21
++#define BRCMF_C_SET_AUTH			22
++#define BRCMF_C_GET_BSSID			23
++#define BRCMF_C_GET_SSID			25
++#define BRCMF_C_SET_SSID			26
++#define BRCMF_C_GET_CHANNEL			29
++#define BRCMF_C_GET_SRL				31
++#define BRCMF_C_GET_LRL				33
++#define BRCMF_C_GET_RADIO			37
++#define BRCMF_C_SET_RADIO			38
++#define BRCMF_C_GET_PHYTYPE			39
++#define BRCMF_C_SET_KEY				45
++#define BRCMF_C_SET_PASSIVE_SCAN		49
++#define BRCMF_C_SCAN				50
++#define BRCMF_C_SCAN_RESULTS			51
++#define BRCMF_C_DISASSOC			52
++#define BRCMF_C_REASSOC				53
++#define BRCMF_C_SET_ROAM_TRIGGER		55
++#define BRCMF_C_SET_ROAM_DELTA			57
++#define BRCMF_C_GET_DTIMPRD			77
++#define BRCMF_C_SET_COUNTRY			84
++#define BRCMF_C_GET_PM				85
++#define BRCMF_C_SET_PM				86
++#define BRCMF_C_GET_AP				117
++#define BRCMF_C_SET_AP				118
++#define BRCMF_C_GET_RSSI			127
++#define BRCMF_C_GET_WSEC			133
++#define BRCMF_C_SET_WSEC			134
++#define BRCMF_C_GET_PHY_NOISE			135
++#define BRCMF_C_GET_BSS_INFO			136
++#define BRCMF_C_SET_SCAN_CHANNEL_TIME		185
++#define BRCMF_C_SET_SCAN_UNASSOC_TIME		187
++#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON	201
++#define BRCMF_C_GET_VALID_CHANNELS		217
++#define BRCMF_C_GET_KEY_PRIMARY			235
++#define BRCMF_C_SET_KEY_PRIMARY			236
++#define BRCMF_C_SET_SCAN_PASSIVE_TIME		258
++#define BRCMF_C_GET_VAR				262
++#define BRCMF_C_SET_VAR				263
++
++/* phy types (returned by WLC_GET_PHYTPE) */
++#define	WLC_PHY_TYPE_A		0
++#define	WLC_PHY_TYPE_B		1
++#define	WLC_PHY_TYPE_G		2
++#define	WLC_PHY_TYPE_N		4
++#define	WLC_PHY_TYPE_LP		5
++#define	WLC_PHY_TYPE_SSN	6
++#define	WLC_PHY_TYPE_HT		7
++#define	WLC_PHY_TYPE_LCN	8
++#define	WLC_PHY_TYPE_NULL	0xf
++
++#define BRCMF_EVENTING_MASK_LEN	16
++
++#define TOE_TX_CSUM_OL		0x00000001
++#define TOE_RX_CSUM_OL		0x00000002
++
++#define	BRCMF_BSS_INFO_VERSION	109 /* curr ver of brcmf_bss_info_le struct */
++
++/* size of brcmf_scan_params not including variable length array */
++#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
++
++/* masks for channel and ssid count */
++#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
++#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
++
++#define BRCMF_SCAN_ACTION_START      1
++#define BRCMF_SCAN_ACTION_CONTINUE   2
++#define WL_SCAN_ACTION_ABORT      3
++
++#define BRCMF_ISCAN_REQ_VERSION 1
++
++/* brcmf_iscan_results status values */
++#define BRCMF_SCAN_RESULTS_SUCCESS	0
++#define BRCMF_SCAN_RESULTS_PARTIAL	1
++#define BRCMF_SCAN_RESULTS_PENDING	2
++#define BRCMF_SCAN_RESULTS_ABORTED	3
++#define BRCMF_SCAN_RESULTS_NO_MEM	4
++
++/* Indicates this key is using soft encrypt */
++#define WL_SOFT_KEY	(1 << 0)
++/* primary (ie tx) key */
++#define BRCMF_PRIMARY_KEY	(1 << 1)
++/* Reserved for backward compat */
++#define WL_KF_RES_4	(1 << 4)
++/* Reserved for backward compat */
++#define WL_KF_RES_5	(1 << 5)
++/* Indicates a group key for a IBSS PEER */
++#define WL_IBSS_PEER_GROUP_KEY	(1 << 6)
++
++/* For supporting multiple interfaces */
++#define BRCMF_MAX_IFS	16
++
++#define DOT11_BSSTYPE_ANY			2
++#define DOT11_MAX_DEFAULT_KEYS	4
++
++#define BRCMF_EVENT_MSG_LINK		0x01
++#define BRCMF_EVENT_MSG_FLUSHTXQ	0x02
++#define BRCMF_EVENT_MSG_GROUP		0x04
++
++struct brcmf_event_msg {
++	__be16 version;
++	__be16 flags;
++	__be32 event_type;
++	__be32 status;
++	__be32 reason;
++	__be32 auth_type;
++	__be32 datalen;
++	u8 addr[ETH_ALEN];
++	char ifname[IFNAMSIZ];
++} __packed;
++
++struct brcm_ethhdr {
++	u16 subtype;
++	u16 length;
++	u8 version;
++	u8 oui[3];
++	u16 usr_subtype;
++} __packed;
++
++struct brcmf_event {
++	struct ethhdr eth;
++	struct brcm_ethhdr hdr;
++	struct brcmf_event_msg msg;
++} __packed;
++
++/* event codes sent by the dongle to this driver */
++#define BRCMF_E_SET_SSID			0
++#define BRCMF_E_JOIN				1
++#define BRCMF_E_START				2
++#define BRCMF_E_AUTH				3
++#define BRCMF_E_AUTH_IND			4
++#define BRCMF_E_DEAUTH				5
++#define BRCMF_E_DEAUTH_IND			6
++#define BRCMF_E_ASSOC				7
++#define BRCMF_E_ASSOC_IND			8
++#define BRCMF_E_REASSOC				9
++#define BRCMF_E_REASSOC_IND			10
++#define BRCMF_E_DISASSOC			11
++#define BRCMF_E_DISASSOC_IND			12
++#define BRCMF_E_QUIET_START			13
++#define BRCMF_E_QUIET_END			14
++#define BRCMF_E_BEACON_RX			15
++#define BRCMF_E_LINK				16
++#define BRCMF_E_MIC_ERROR			17
++#define BRCMF_E_NDIS_LINK			18
++#define BRCMF_E_ROAM				19
++#define BRCMF_E_TXFAIL				20
++#define BRCMF_E_PMKID_CACHE			21
++#define BRCMF_E_RETROGRADE_TSF			22
++#define BRCMF_E_PRUNE				23
++#define BRCMF_E_AUTOAUTH			24
++#define BRCMF_E_EAPOL_MSG			25
++#define BRCMF_E_SCAN_COMPLETE			26
++#define BRCMF_E_ADDTS_IND			27
++#define BRCMF_E_DELTS_IND			28
++#define BRCMF_E_BCNSENT_IND			29
++#define BRCMF_E_BCNRX_MSG			30
++#define BRCMF_E_BCNLOST_MSG			31
++#define BRCMF_E_ROAM_PREP			32
++#define BRCMF_E_PFN_NET_FOUND			33
++#define BRCMF_E_PFN_NET_LOST			34
++#define BRCMF_E_RESET_COMPLETE			35
++#define BRCMF_E_JOIN_START			36
++#define BRCMF_E_ROAM_START			37
++#define BRCMF_E_ASSOC_START			38
++#define BRCMF_E_IBSS_ASSOC			39
++#define BRCMF_E_RADIO				40
++#define BRCMF_E_PSM_WATCHDOG			41
++#define BRCMF_E_PROBREQ_MSG			44
++#define BRCMF_E_SCAN_CONFIRM_IND		45
++#define BRCMF_E_PSK_SUP				46
++#define BRCMF_E_COUNTRY_CODE_CHANGED		47
++#define	BRCMF_E_EXCEEDED_MEDIUM_TIME		48
++#define BRCMF_E_ICV_ERROR			49
++#define BRCMF_E_UNICAST_DECODE_ERROR		50
++#define BRCMF_E_MULTICAST_DECODE_ERROR		51
++#define BRCMF_E_TRACE				52
++#define BRCMF_E_IF				54
++#define BRCMF_E_RSSI				56
++#define BRCMF_E_PFN_SCAN_COMPLETE		57
++#define BRCMF_E_EXTLOG_MSG			58
++#define BRCMF_E_ACTION_FRAME			59
++#define BRCMF_E_ACTION_FRAME_COMPLETE		60
++#define BRCMF_E_PRE_ASSOC_IND			61
++#define BRCMF_E_PRE_REASSOC_IND			62
++#define BRCMF_E_CHANNEL_ADOPTED			63
++#define BRCMF_E_AP_STARTED			64
++#define BRCMF_E_DFS_AP_STOP			65
++#define BRCMF_E_DFS_AP_RESUME			66
++#define BRCMF_E_RESERVED1			67
++#define BRCMF_E_RESERVED2			68
++#define BRCMF_E_ESCAN_RESULT			69
++#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE	70
++#define BRCMF_E_DCS_REQUEST			73
++
++#define BRCMF_E_FIFO_CREDIT_MAP			74
++
++#define BRCMF_E_LAST				75
++
++#define BRCMF_E_STATUS_SUCCESS			0
++#define BRCMF_E_STATUS_FAIL			1
++#define BRCMF_E_STATUS_TIMEOUT			2
++#define BRCMF_E_STATUS_NO_NETWORKS		3
++#define BRCMF_E_STATUS_ABORT			4
++#define BRCMF_E_STATUS_NO_ACK			5
++#define BRCMF_E_STATUS_UNSOLICITED		6
++#define BRCMF_E_STATUS_ATTEMPT			7
++#define BRCMF_E_STATUS_PARTIAL			8
++#define BRCMF_E_STATUS_NEWSCAN			9
++#define BRCMF_E_STATUS_NEWASSOC			10
++#define BRCMF_E_STATUS_11HQUIET			11
++#define BRCMF_E_STATUS_SUPPRESS			12
++#define BRCMF_E_STATUS_NOCHANS			13
++#define BRCMF_E_STATUS_CS_ABORT			15
++#define BRCMF_E_STATUS_ERROR			16
++
++#define BRCMF_E_REASON_INITIAL_ASSOC		0
++#define BRCMF_E_REASON_LOW_RSSI			1
++#define BRCMF_E_REASON_DEAUTH			2
++#define BRCMF_E_REASON_DISASSOC			3
++#define BRCMF_E_REASON_BCNS_LOST		4
++#define BRCMF_E_REASON_MINTXRATE		9
++#define BRCMF_E_REASON_TXFAIL			10
++
++#define BRCMF_E_REASON_FAST_ROAM_FAILED		5
++#define BRCMF_E_REASON_DIRECTED_ROAM		6
++#define BRCMF_E_REASON_TSPEC_REJECTED		7
++#define BRCMF_E_REASON_BETTER_AP		8
++
++#define BRCMF_E_PRUNE_ENCR_MISMATCH		1
++#define BRCMF_E_PRUNE_BCAST_BSSID		2
++#define BRCMF_E_PRUNE_MAC_DENY			3
++#define BRCMF_E_PRUNE_MAC_NA			4
++#define BRCMF_E_PRUNE_REG_PASSV			5
++#define BRCMF_E_PRUNE_SPCT_MGMT			6
++#define BRCMF_E_PRUNE_RADAR			7
++#define BRCMF_E_RSN_MISMATCH			8
++#define BRCMF_E_PRUNE_NO_COMMON_RATES		9
++#define BRCMF_E_PRUNE_BASIC_RATES		10
++#define BRCMF_E_PRUNE_CIPHER_NA			12
++#define BRCMF_E_PRUNE_KNOWN_STA			13
++#define BRCMF_E_PRUNE_WDS_PEER			15
++#define BRCMF_E_PRUNE_QBSS_LOAD			16
++#define BRCMF_E_PRUNE_HOME_AP			17
++
++#define BRCMF_E_SUP_OTHER			0
++#define BRCMF_E_SUP_DECRYPT_KEY_DATA		1
++#define BRCMF_E_SUP_BAD_UCAST_WEP128		2
++#define BRCMF_E_SUP_BAD_UCAST_WEP40		3
++#define BRCMF_E_SUP_UNSUP_KEY_LEN		4
++#define BRCMF_E_SUP_PW_KEY_CIPHER		5
++#define BRCMF_E_SUP_MSG3_TOO_MANY_IE		6
++#define BRCMF_E_SUP_MSG3_IE_MISMATCH		7
++#define BRCMF_E_SUP_NO_INSTALL_FLAG		8
++#define BRCMF_E_SUP_MSG3_NO_GTK			9
++#define BRCMF_E_SUP_GRP_KEY_CIPHER		10
++#define BRCMF_E_SUP_GRP_MSG1_NO_GTK		11
++#define BRCMF_E_SUP_GTK_DECRYPT_FAIL		12
++#define BRCMF_E_SUP_SEND_FAIL			13
++#define BRCMF_E_SUP_DEAUTH			14
++
++#define BRCMF_E_IF_ADD				1
++#define BRCMF_E_IF_DEL				2
++#define BRCMF_E_IF_CHANGE			3
++
++#define BRCMF_E_IF_ROLE_STA			0
++#define BRCMF_E_IF_ROLE_AP			1
++#define BRCMF_E_IF_ROLE_WDS			2
++
++#define BRCMF_E_LINK_BCN_LOSS			1
++#define BRCMF_E_LINK_DISASSOC			2
++#define BRCMF_E_LINK_ASSOC_REC			3
++#define BRCMF_E_LINK_BSSCFG_DIS			4
++
++/* Pattern matching filter. Specifies an offset within received packets to
++ * start matching, the pattern to match, the size of the pattern, and a bitmask
++ * that indicates which bits within the pattern should be matched.
++ */
++struct brcmf_pkt_filter_pattern_le {
++	/*
++	 * Offset within received packet to start pattern matching.
++	 * Offset '0' is the first byte of the ethernet header.
++	 */
++	__le32 offset;
++	/* Size of the pattern.  Bitmask must be the same size.*/
++	__le32 size_bytes;
++	/*
++	 * Variable length mask and pattern data. mask starts at offset 0.
++	 * Pattern immediately follows mask.
++	 */
++	u8 mask_and_pattern[1];
++};
++
++/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
++struct brcmf_pkt_filter_le {
++	__le32 id;		/* Unique filter id, specified by app. */
++	__le32 type;		/* Filter type (WL_PKT_FILTER_TYPE_xxx). */
++	__le32 negate_match;	/* Negate the result of filter matches */
++	union {			/* Filter definitions */
++		struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
++	} u;
++};
++
++/* IOVAR "pkt_filter_enable" parameter. */
++struct brcmf_pkt_filter_enable_le {
++	__le32 id;		/* Unique filter id */
++	__le32 enable;		/* Enable/disable bool */
++};
++
++/* BSS info structure
++ * Applications MUST CHECK ie_offset field and length field to access IEs and
++ * next bss_info structure in a vector (in struct brcmf_scan_results)
++ */
++struct brcmf_bss_info_le {
++	__le32 version;		/* version field */
++	__le32 length;		/* byte length of data in this record,
++				 * starting at version and including IEs
++				 */
++	u8 BSSID[ETH_ALEN];
++	__le16 beacon_period;	/* units are Kusec */
++	__le16 capability;	/* Capability information */
++	u8 SSID_len;
++	u8 SSID[32];
++	struct {
++		__le32 count;   /* # rates in this set */
++		u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
++	} rateset;		/* supported rates */
++	__le16 chanspec;	/* chanspec for bss */
++	__le16 atim_window;	/* units are Kusec */
++	u8 dtim_period;	/* DTIM period */
++	__le16 RSSI;		/* receive signal strength (in dBm) */
++	s8 phy_noise;		/* noise (in dBm) */
++
++	u8 n_cap;		/* BSS is 802.11N Capable */
++	/* 802.11N BSS Capabilities (based on HT_CAP_*): */
++	__le32 nbss_cap;
++	u8 ctl_ch;		/* 802.11N BSS control channel number */
++	__le32 reserved32[1];	/* Reserved for expansion of BSS properties */
++	u8 flags;		/* flags */
++	u8 reserved[3];	/* Reserved for expansion of BSS properties */
++	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
++
++	__le16 ie_offset;	/* offset at which IEs start, from beginning */
++	__le32 ie_length;	/* byte length of Information Elements */
++	__le16 SNR;		/* average SNR of during frame reception */
++	/* Add new fields here */
++	/* variable length Information Elements */
++};
++
++struct brcm_rateset_le {
++	/* # rates in this set */
++	__le32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcmf_ssid {
++	u32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_ssid_le {
++	__le32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_scan_params_le {
++	struct brcmf_ssid_le ssid_le;	/* default: {0, ""} */
++	u8 bssid[ETH_ALEN];	/* default: bcast */
++	s8 bss_type;		/* default: any,
++				 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
++				 */
++	u8 scan_type;	/* flags, 0 use default */
++	__le32 nprobes;	  /* -1 use default, number of probes per channel */
++	__le32 active_time;	/* -1 use default, dwell time per channel for
++				 * active scanning
++				 */
++	__le32 passive_time;	/* -1 use default, dwell time per channel
++				 * for passive scanning
++				 */
++	__le32 home_time;	/* -1 use default, dwell time for the
++				 * home channel between channel scans
++				 */
++	__le32 channel_num;	/* count of channels and ssids that follow
++				 *
++				 * low half is count of channels in
++				 * channel_list, 0 means default (use all
++				 * available channels)
++				 *
++				 * high half is entries in struct brcmf_ssid
++				 * array that follows channel_list, aligned for
++				 * s32 (4 bytes) meaning an odd channel count
++				 * implies a 2-byte pad between end of
++				 * channel_list and first ssid
++				 *
++				 * if ssid count is zero, single ssid in the
++				 * fixed parameter portion is assumed, otherwise
++				 * ssid in the fixed portion is ignored
++				 */
++	__le16 channel_list[1];	/* list of chanspecs */
++};
++
++/* incremental scan struct */
++struct brcmf_iscan_params_le {
++	__le32 version;
++	__le16 action;
++	__le16 scan_duration;
++	struct brcmf_scan_params_le params_le;
++};
++
++struct brcmf_scan_results {
++	u32 buflen;
++	u32 version;
++	u32 count;
++	struct brcmf_bss_info_le bss_info_le[];
++};
++
++struct brcmf_scan_results_le {
++	__le32 buflen;
++	__le32 version;
++	__le32 count;
++};
++
++/* used for association with a specific BSSID and chanspec list */
++struct brcmf_assoc_params_le {
++	/* 00:00:00:00:00:00: broadcast scan */
++	u8 bssid[ETH_ALEN];
++	/* 0: all available channels, otherwise count of chanspecs in
++	 * chanspec_list */
++	__le32 chanspec_num;
++	/* list of chanspecs */
++	__le16 chanspec_list[1];
++};
++
++/* used for join with or without a specific bssid and channel list */
++struct brcmf_join_params {
++	struct brcmf_ssid_le ssid_le;
++	struct brcmf_assoc_params_le params_le;
++};
++
++/* incremental scan results struct */
++struct brcmf_iscan_results {
++	union {
++		u32 status;
++		__le32 status_le;
++	};
++	union {
++		struct brcmf_scan_results results;
++		struct brcmf_scan_results_le results_le;
++	};
++};
++
++/* size of brcmf_iscan_results not including variable length array */
++#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
++	(sizeof(struct brcmf_scan_results) + \
++	 offsetof(struct brcmf_iscan_results, results))
++
++struct brcmf_wsec_key {
++	u32 index;		/* key index */
++	u32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	u32 pad_1[18];
++	u32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	u32 flags;	/* misc flags */
++	u32 pad_2[3];
++	u32 iv_initialized;	/* has IV been initialized already? */
++	u32 pad_3;
++	/* Rx IV */
++	struct {
++		u32 hi;	/* upper 32 bits of IV */
++		u16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	u32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/*
++ * dongle requires same struct as above but with fields in little endian order
++ */
++struct brcmf_wsec_key_le {
++	__le32 index;		/* key index */
++	__le32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	__le32 pad_1[18];
++	__le32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	__le32 flags;	/* misc flags */
++	__le32 pad_2[3];
++	__le32 iv_initialized;	/* has IV been initialized already? */
++	__le32 pad_3;
++	/* Rx IV */
++	struct {
++		__le32 hi;	/* upper 32 bits of IV */
++		__le16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	__le32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/* Used to get specific STA parameters */
++struct brcmf_scb_val_le {
++	__le32 val;
++	u8 ea[ETH_ALEN];
++};
++
++/* channel encoding */
++struct brcmf_channel_info_le {
++	__le32 hw_channel;
++	__le32 target_channel;
++	__le32 scan_channel;
++};
++
++/* Bus independent dongle command */
++struct brcmf_dcmd {
++	uint cmd;		/* common dongle cmd definition */
++	void *buf;		/* pointer to user buffer */
++	uint len;		/* length of user buffer */
++	u8 set;			/* get or set request (optional) */
++	uint used;		/* bytes read or written (optional) */
++	uint needed;		/* bytes needed (optional) */
++};
++
++/* Forward decls for struct brcmf_pub (see below) */
++struct brcmf_proto;	/* device communication protocol info */
++struct brcmf_cfg80211_dev; /* cfg80211 device info */
++
++/* Common structure for module and instance linkage */
++struct brcmf_pub {
++	/* Linkage ponters */
++	struct brcmf_bus *bus_if;
++	struct brcmf_proto *prot;
++	struct brcmf_cfg80211_dev *config;
++	struct device *dev;		/* fullmac dongle device pointer */
++
++	/* Internal brcmf items */
++	uint hdrlen;		/* Total BRCMF header length (proto + bus) */
++	uint rxsz;		/* Rx buffer size bus module should use */
++	u8 wme_dp;		/* wme discard priority */
++
++	/* Dongle media info */
++	bool iswl;		/* Dongle-resident driver is wl */
++	unsigned long drv_version;	/* Version of dongle-resident driver */
++	u8 mac[ETH_ALEN];		/* MAC address obtained from dongle */
++
++	/* Additional stats for the bus level */
++
++	/* Multicast data packets sent to dongle */
++	unsigned long tx_multicast;
++	/* Packets flushed due to unscheduled sendup thread */
++	unsigned long rx_flushed;
++	/* Number of times dpc scheduled by watchdog timer */
++	unsigned long wd_dpc_sched;
++
++	/* Number of flow control pkts recvd */
++	unsigned long fc_packets;
++
++	/* Last error return */
++	int bcmerror;
++
++	/* Last error from dongle */
++	int dongle_error;
++
++	/* Suspend disable flag  flag */
++	int suspend_disable_flag;	/* "1" to disable all extra powersaving
++					 during suspend */
++	int in_suspend;		/* flag set to 1 when early suspend called */
++	int dtim_skip;		/* dtim skip , default 0 means wake each dtim */
++
++	/* Pkt filter defination */
++	char *pktfilter[100];
++	int pktfilter_count;
++
++	u8 country_code[BRCM_CNTRY_BUF_SZ];
++	char eventmask[BRCMF_EVENTING_MASK_LEN];
++
++	struct brcmf_if *iflist[BRCMF_MAX_IFS];
++
++	struct mutex proto_block;
++
++	struct work_struct setmacaddr_work;
++	struct work_struct multicast_work;
++	u8 macvalue[ETH_ALEN];
++	atomic_t pend_8021x_cnt;
++};
++
++struct brcmf_if_event {
++	u8 ifidx;
++	u8 action;
++	u8 flags;
++	u8 bssidx;
++};
++
++struct bcmevent_name {
++	uint event;
++	const char *name;
++};
++
++extern const struct bcmevent_name bcmevent_names[];
++
++extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
++			  char *buf, uint len);
++
++extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
++
++extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
++
++/* Return pointer to interface name */
++extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
++
++/* Query dongle */
++extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
++				       uint cmd, void *buf, uint len);
++
++#ifdef DEBUG
++extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
++#endif				/* DEBUG */
++
++extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
++extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
++			      void *pktdata, struct brcmf_event_msg *,
++			      void **data_ptr);
++
++extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
++
++/* Send packet to dongle via data channel */
++extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
++			 struct sk_buff *pkt);
++
++extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
++extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
++					     int enable, int master_mode);
++
++#define	BRCMF_DCMD_SMLEN	256	/* "small" cmd buffer required */
++#define BRCMF_DCMD_MEDLEN	1536	/* "med" cmd buffer required */
++#define	BRCMF_DCMD_MAXLEN	8192	/* max length cmd buffer required */
++
++#endif				/* _BRCMF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+new file mode 100644
+index 0000000..3669164
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_BUS_H_
++#define _BRCMF_BUS_H_
++
++/* The level of bus communication with the dongle */
++enum brcmf_bus_state {
++	BRCMF_BUS_DOWN,		/* Not ready for frame transfers */
++	BRCMF_BUS_LOAD,		/* Download access only (CPU reset) */
++	BRCMF_BUS_DATA		/* Ready for frame transfers */
++};
++
++struct dngl_stats {
++	unsigned long rx_packets;	/* total packets received */
++	unsigned long tx_packets;	/* total packets transmitted */
++	unsigned long rx_bytes;	/* total bytes received */
++	unsigned long tx_bytes;	/* total bytes transmitted */
++	unsigned long rx_errors;	/* bad packets received */
++	unsigned long tx_errors;	/* packet transmit problems */
++	unsigned long rx_dropped;	/* packets dropped by dongle */
++	unsigned long tx_dropped;	/* packets dropped by dongle */
++	unsigned long multicast;	/* multicast packets received */
++};
++
++/* interface structure between common and bus layer */
++struct brcmf_bus {
++	u8 type;		/* bus type */
++	union {
++		struct brcmf_sdio_dev *sdio;
++		struct brcmf_usbdev *usb;
++	} bus_priv;
++	struct brcmf_pub *drvr;	/* pointer to driver pub structure brcmf_pub */
++	enum brcmf_bus_state state;
++	uint maxctl;		/* Max size rxctl request from proto to bus */
++	bool drvr_up;		/* Status flag of driver up/down */
++	unsigned long tx_realloc;	/* Tx packets realloced for headroom */
++	struct dngl_stats dstats;	/* Stats for dongle-based data */
++	u8 align;		/* bus alignment requirement */
++
++	/* interface functions pointers */
++	/* Stop bus module: clear pending frames, disable data flow */
++	void (*brcmf_bus_stop)(struct device *);
++	/* Initialize bus module: prepare for communication w/dongle */
++	int (*brcmf_bus_init)(struct device *);
++	/* Send a data frame to the dongle.  Callee disposes of txp. */
++	int (*brcmf_bus_txdata)(struct device *, struct sk_buff *);
++	/* Send/receive a control message to/from the dongle.
++	 * Expects caller to enforce a single outstanding transaction.
++	 */
++	int (*brcmf_bus_txctl)(struct device *, unsigned char *, uint);
++	int (*brcmf_bus_rxctl)(struct device *, unsigned char *, uint);
++};
++
++/*
++ * interface functions from common layer
++ */
++
++/* Remove any protocol-specific data header. */
++extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			       struct sk_buff *rxp);
++
++extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++			 struct sk_buff *pkt, int prec);
++
++/* Receive frame for delivery to OS.  Callee disposes of rxp. */
++extern void brcmf_rx_frame(struct device *dev, int ifidx,
++			   struct sk_buff_head *rxlist);
++static inline void brcmf_rx_packet(struct device *dev, int ifidx,
++				   struct sk_buff *pkt)
++{
++	struct sk_buff_head q;
++
++	skb_queue_head_init(&q);
++	skb_queue_tail(&q, pkt);
++	brcmf_rx_frame(dev, ifidx, &q);
++}
++
++/* Indication from bus module regarding presence/insertion of dongle. */
++extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
++/* Indication from bus module regarding removal/absence of dongle */
++extern void brcmf_detach(struct device *dev);
++
++/* Indication from bus module to change flow-control state */
++extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on);
++
++/* Notify tx completion */
++extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
++			     bool success);
++
++extern int brcmf_bus_start(struct device *dev);
++
++extern int brcmf_add_if(struct device *dev, int ifidx,
++			char *name, u8 *mac_addr);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++extern void brcmf_sdio_exit(void);
++extern void brcmf_sdio_init(void);
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++extern void brcmf_usb_exit(void);
++extern void brcmf_usb_init(void);
++#endif
++
++#endif				/* _BRCMF_BUS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+new file mode 100644
+index 0000000..ca28295
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+@@ -0,0 +1,495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*******************************************************************************
++ * Communicates with the dongle by using dcmd codes.
++ * For certain dcmd codes, the dongle interprets string data from the host.
++ ******************************************************************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <defs.h>
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_proto.h"
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++struct brcmf_proto_cdc_dcmd {
++	__le32 cmd;	/* dongle command value */
++	__le32 len;	/* lower 16: output buflen;
++			 * upper 16: input buflen (excludes header) */
++	__le32 flags;	/* flag defns given below */
++	__le32 status;	/* status code returned from the device */
++};
++
++/* Max valid buffer size that can be sent to the dongle */
++#define CDC_MAX_MSG_SIZE	(ETH_FRAME_LEN+ETH_FCS_LEN)
++
++/* CDC flag definitions */
++#define CDC_DCMD_ERROR		0x01	/* 1=cmd failed */
++#define CDC_DCMD_SET		0x02	/* 0=get, 1=set cmd */
++#define CDC_DCMD_IF_MASK	0xF000		/* I/F index */
++#define CDC_DCMD_IF_SHIFT	12
++#define CDC_DCMD_ID_MASK	0xFFFF0000	/* id an cmd pairing */
++#define CDC_DCMD_ID_SHIFT	16		/* ID Mask shift bits */
++#define CDC_DCMD_ID(flags)	\
++	(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
++
++/*
++ * BDC header - Broadcom specific extension of CDC.
++ * Used on data packets to convey priority across USB.
++ */
++#define	BDC_HEADER_LEN		4
++#define BDC_PROTO_VER		2	/* Protocol version */
++#define BDC_FLAG_VER_MASK	0xf0	/* Protocol version mask */
++#define BDC_FLAG_VER_SHIFT	4	/* Protocol version shift */
++#define BDC_FLAG_SUM_GOOD	0x04	/* Good RX checksums */
++#define BDC_FLAG_SUM_NEEDED	0x08	/* Dongle needs to do TX checksums */
++#define BDC_PRIORITY_MASK	0x7
++#define BDC_FLAG2_IF_MASK	0x0f	/* packet rx interface in APSTA */
++#define BDC_FLAG2_IF_SHIFT	0
++
++#define BDC_GET_IF_IDX(hdr) \
++	((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
++#define BDC_SET_IF_IDX(hdr, idx) \
++	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
++	((idx) << BDC_FLAG2_IF_SHIFT)))
++
++struct brcmf_proto_bdc_header {
++	u8 flags;
++	u8 priority;	/* 802.1d Priority, 4:7 flow control info for usb */
++	u8 flags2;
++	u8 data_offset;
++};
++
++
++#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
++#define BUS_HEADER_LEN	(16+64)		/* Must be atleast SDPCM_RESERVE
++					 * (amount of header tha might be added)
++					 * plus any space that might be needed
++					 * for bus alignment padding.
++					 */
++#define ROUND_UP_MARGIN	2048	/* Biggest bus block size possible for
++				 * round off at the end of buffer
++				 * Currently is SDIO
++				 */
++
++struct brcmf_proto {
++	u16 reqid;
++	u8 pending;
++	u32 lastcmd;
++	u8 bus_header[BUS_HEADER_LEN];
++	struct brcmf_proto_cdc_dcmd msg;
++	unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
++};
++
++static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int len = le32_to_cpu(prot->msg.len) +
++			sizeof(struct brcmf_proto_cdc_dcmd);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
++	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
++	 *        is actually sent to the dongle
++	 */
++	if (len > CDC_MAX_MSG_SIZE)
++		len = CDC_MAX_MSG_SIZE;
++
++	/* Send request */
++	return drvr->bus_if->brcmf_bus_txctl(drvr->dev,
++					     (unsigned char *)&prot->msg,
++					     len);
++}
++
++static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
++{
++	int ret;
++	struct brcmf_proto *prot = drvr->prot;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	do {
++		ret = drvr->bus_if->brcmf_bus_rxctl(drvr->dev,
++				(unsigned char *)&prot->msg,
++				len + sizeof(struct brcmf_proto_cdc_dcmd));
++		if (ret < 0)
++			break;
++	} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
++
++	return ret;
++}
++
++int
++brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++			       void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	void *info;
++	int ret = 0, retries = 0;
++	u32 id, flags;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
++	if (cmd == BRCMF_C_GET_VAR && buf) {
++		if (!strcmp((char *)buf, "bcmerrorstr")) {
++			strncpy((char *)buf, "bcm_error",
++				BCME_STRLEN);
++			goto done;
++		} else if (!strcmp((char *)buf, "bcmerror")) {
++			*(int *)buf = drvr->dongle_error;
++			goto done;
++		}
++	}
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
++			  ret);
++		goto done;
++	}
++
++retry:
++	/* wait for interrupt and get first fragment */
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if ((id < prot->reqid) && (++retries < RETRIES))
++		goto retry;
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check info buffer */
++	info = (void *)&msg[1];
++
++	/* Copy info buffer */
++	if (buf) {
++		if (ret < (int)len)
++			len = ret;
++		memcpy(buf, info, len);
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++				 void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	int ret = 0;
++	u32 flags, id;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0)
++		goto done;
++
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int
++brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
++		  int len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int ret = -1;
++
++	if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
++		return ret;
++	}
++	mutex_lock(&drvr->proto_block);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (len > BRCMF_DCMD_MAXLEN)
++		goto done;
++
++	if (prot->pending == true) {
++		brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
++			  dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
++			  (unsigned long)prot->lastcmd);
++		if (dcmd->cmd == BRCMF_C_SET_VAR ||
++		    dcmd->cmd == BRCMF_C_GET_VAR)
++			brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
++
++		goto done;
++	}
++
++	prot->pending = true;
++	prot->lastcmd = dcmd->cmd;
++	if (dcmd->set)
++		ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
++						   dcmd->buf, len);
++	else {
++		ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
++						     dcmd->buf, len);
++		if (ret > 0)
++			dcmd->used = ret -
++					sizeof(struct brcmf_proto_cdc_dcmd);
++	}
++
++	if (ret >= 0)
++		ret = 0;
++	else {
++		struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++		/* len == needed when set/query fails from dongle */
++		dcmd->needed = le32_to_cpu(msg->len);
++	}
++
++	/* Intercept the wme_dp dongle cmd here */
++	if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
++	    !strcmp(dcmd->buf, "wme_dp")) {
++		int slen;
++		__le32 val = 0;
++
++		slen = strlen("wme_dp") + 1;
++		if (len >= (int)(slen + sizeof(int)))
++			memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
++		drvr->wme_dp = (u8) le32_to_cpu(val);
++	}
++
++	prot->pending = false;
++
++done:
++	mutex_unlock(&drvr->proto_block);
++
++	return ret;
++}
++
++static bool pkt_sum_needed(struct sk_buff *skb)
++{
++	return skb->ip_summed == CHECKSUM_PARTIAL;
++}
++
++static void pkt_set_sum_good(struct sk_buff *skb, bool x)
++{
++	skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
++}
++
++void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
++			 struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Push BDC header used to convey priority for buses that don't */
++
++	skb_push(pktbuf, BDC_HEADER_LEN);
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
++	if (pkt_sum_needed(pktbuf))
++		h->flags |= BDC_FLAG_SUM_NEEDED;
++
++	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
++	h->flags2 = 0;
++	h->data_offset = 0;
++	BDC_SET_IF_IDX(h, ifidx);
++}
++
++int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Pop BDC header used to convey priority for buses that don't */
++
++	if (pktbuf->len < BDC_HEADER_LEN) {
++		brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
++			  pktbuf->len, BDC_HEADER_LEN);
++		return -EBADE;
++	}
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	*ifidx = BDC_GET_IF_IDX(h);
++	if (*ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
++		return -EBADE;
++	}
++
++	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
++	    BDC_PROTO_VER) {
++		brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		return -EBADE;
++	}
++
++	if (h->flags & BDC_FLAG_SUM_GOOD) {
++		brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		pkt_set_sum_good(pktbuf, true);
++	}
++
++	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
++
++	skb_pull(pktbuf, BDC_HEADER_LEN);
++	skb_pull(pktbuf, h->data_offset << 2);
++
++	return 0;
++}
++
++int brcmf_proto_attach(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *cdc;
++
++	cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
++	if (!cdc)
++		goto fail;
++
++	/* ensure that the msg buf directly follows the cdc msg struct */
++	if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
++		brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
++		goto fail;
++	}
++
++	drvr->prot = cdc;
++	drvr->hdrlen += BDC_HEADER_LEN;
++	drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
++			sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
++	return 0;
++
++fail:
++	kfree(cdc);
++	return -ENOMEM;
++}
++
++/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
++void brcmf_proto_detach(struct brcmf_pub *drvr)
++{
++	kfree(drvr->prot);
++	drvr->prot = NULL;
++}
++
++int brcmf_proto_init(struct brcmf_pub *drvr)
++{
++	int ret = 0;
++	char buf[128];
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Get the device MAC address */
++	strcpy(buf, "cur_etheraddr");
++	ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
++					  buf, sizeof(buf));
++	if (ret < 0) {
++		mutex_unlock(&drvr->proto_block);
++		return ret;
++	}
++	memcpy(drvr->mac, buf, ETH_ALEN);
++
++	mutex_unlock(&drvr->proto_block);
++
++	ret = brcmf_c_preinit_dcmds(drvr);
++
++	/* Always assumes wl for now */
++	drvr->iswl = true;
++
++	return ret;
++}
++
++void brcmf_proto_stop(struct brcmf_pub *drvr)
++{
++	/* Nothing to do for CDC */
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+new file mode 100644
+index 0000000..2962900
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+@@ -0,0 +1,882 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/netdevice.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++
++#define BRCM_OUI			"\x00\x10\x18"
++#define DOT11_OUI_LEN			3
++#define BCMILCP_BCM_SUBTYPE_EVENT	1
++#define PKTFILTER_BUF_SIZE		2048
++#define BRCMF_ARPOL_MODE		0xb	/* agent|snoop|peer_autoreply */
++
++#define MSGTRACE_VERSION	1
++
++#define BRCMF_PKT_FILTER_FIXED_LEN	offsetof(struct brcmf_pkt_filter_le, u)
++#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN	\
++	offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
++
++#ifdef DEBUG
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
++	__DATE__ " at " __TIME__;
++#else
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR;
++#endif
++
++/* Message trace header */
++struct msgtrace_hdr {
++	u8 version;
++	u8 spare;
++	__be16 len;		/* Len of the trace */
++	__be32 seqnum;		/* Sequence number of message. Useful
++				 * if the messsage has been lost
++				 * because of DMA error or a bus reset
++				 * (ex: SDIO Func2)
++				 */
++	__be32 discarded_bytes;	/* Number of discarded bytes because of
++				 trace overflow  */
++	__be32 discarded_printf;	/* Number of discarded printf
++				 because of trace overflow */
++} __packed;
++
++
++uint
++brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
++{
++	uint len;
++
++	len = strlen(name) + 1;
++
++	if ((len + datalen) > buflen)
++		return 0;
++
++	strncpy(buf, name, buflen);
++
++	/* append data onto the end of the name string */
++	memcpy(&buf[len], data, datalen);
++	len += datalen;
++
++	return len;
++}
++
++bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++	bool discard_oldest;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	/* Fast case, precedence queue is not full and we are also not
++	 * exceeding total queue length
++	 */
++	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
++		brcmu_pktq_penq(q, prec, pkt);
++		return true;
++	}
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec)
++			return false;
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		/* Detect queueing to unconfigured precedence */
++		discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
++		if (eprec == prec && !discard_oldest)
++			return false;	/* refuse newer (incoming) packet */
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		if (p == NULL)
++			brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
++				  discard_oldest);
++
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	p = brcmu_pktq_penq(q, prec, pkt);
++	if (p == NULL)
++		brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
++
++	return p != NULL;
++}
++
++#ifdef DEBUG
++static void
++brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
++{
++	uint i, status, reason;
++	bool group = false, flush_txq = false, link = false;
++	char *auth_str, *event_name;
++	unsigned char *buf;
++	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
++	static struct {
++		uint event;
++		char *event_name;
++	} event_names[] = {
++		{
++		BRCMF_E_SET_SSID, "SET_SSID"}, {
++		BRCMF_E_JOIN, "JOIN"}, {
++		BRCMF_E_START, "START"}, {
++		BRCMF_E_AUTH, "AUTH"}, {
++		BRCMF_E_AUTH_IND, "AUTH_IND"}, {
++		BRCMF_E_DEAUTH, "DEAUTH"}, {
++		BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
++		BRCMF_E_ASSOC, "ASSOC"}, {
++		BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
++		BRCMF_E_REASSOC, "REASSOC"}, {
++		BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
++		BRCMF_E_DISASSOC, "DISASSOC"}, {
++		BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
++		BRCMF_E_QUIET_START, "START_QUIET"}, {
++		BRCMF_E_QUIET_END, "END_QUIET"}, {
++		BRCMF_E_BEACON_RX, "BEACON_RX"}, {
++		BRCMF_E_LINK, "LINK"}, {
++		BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
++		BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
++		BRCMF_E_ROAM, "ROAM"}, {
++		BRCMF_E_TXFAIL, "TXFAIL"}, {
++		BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
++		BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
++		BRCMF_E_PRUNE, "PRUNE"}, {
++		BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
++		BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
++		BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
++		BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
++		BRCMF_E_DELTS_IND, "DELTS_IND"}, {
++		BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
++		BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
++		BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
++		BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
++		BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
++		BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
++		BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
++		BRCMF_E_JOIN_START, "JOIN_START"}, {
++		BRCMF_E_ROAM_START, "ROAM_START"}, {
++		BRCMF_E_ASSOC_START, "ASSOC_START"}, {
++		BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
++		BRCMF_E_RADIO, "RADIO"}, {
++		BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
++		BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
++		BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
++		BRCMF_E_PSK_SUP, "PSK_SUP"}, {
++		BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
++		BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
++		BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
++		BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
++		BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
++		BRCMF_E_TRACE, "TRACE"}, {
++		BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
++		BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
++		BRCMF_E_IF, "IF"}, {
++		BRCMF_E_RSSI, "RSSI"}, {
++		BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
++	};
++	uint event_type, flags, auth_type, datalen;
++	static u32 seqnum_prev;
++	struct msgtrace_hdr hdr;
++	u32 nblost;
++	char *s, *p;
++
++	event_type = be32_to_cpu(event->event_type);
++	flags = be16_to_cpu(event->flags);
++	status = be32_to_cpu(event->status);
++	reason = be32_to_cpu(event->reason);
++	auth_type = be32_to_cpu(event->auth_type);
++	datalen = be32_to_cpu(event->datalen);
++	/* debug dump of event messages */
++	sprintf(eabuf, "%pM", event->addr);
++
++	event_name = "UNKNOWN";
++	for (i = 0; i < ARRAY_SIZE(event_names); i++) {
++		if (event_names[i].event == event_type)
++			event_name = event_names[i].event_name;
++	}
++
++	brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
++	brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
++		  flags, status, reason, auth_type, eabuf);
++
++	if (flags & BRCMF_EVENT_MSG_LINK)
++		link = true;
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		group = true;
++	if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
++		flush_txq = true;
++
++	switch (event_type) {
++	case BRCMF_E_START:
++	case BRCMF_E_DEAUTH:
++	case BRCMF_E_DISASSOC:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC:
++	case BRCMF_E_REASSOC:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
++				  event_name, eabuf, (int)reason);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
++				  event_name, eabuf, (int)status);
++		break;
++
++	case BRCMF_E_DEAUTH_IND:
++	case BRCMF_E_DISASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
++			  event_name, eabuf, (int)reason);
++		break;
++
++	case BRCMF_E_AUTH:
++	case BRCMF_E_AUTH_IND:
++		if (auth_type == WLAN_AUTH_OPEN)
++			auth_str = "Open System";
++		else if (auth_type == WLAN_AUTH_SHARED_KEY)
++			auth_str = "Shared Key";
++		else {
++			sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
++			auth_str = err_msg;
++		}
++		if (event_type == BRCMF_E_AUTH_IND)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_FAIL) {
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
++				  event_name, eabuf, auth_str, (int)reason);
++		}
++
++		break;
++
++	case BRCMF_E_JOIN:
++	case BRCMF_E_ROAM:
++	case BRCMF_E_SET_SSID:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
++		else if (status == BRCMF_E_STATUS_NO_NETWORKS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
++				  event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
++				  event_name, (int)status);
++		break;
++
++	case BRCMF_E_BEACON_RX:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
++				  event_name, status);
++		break;
++
++	case BRCMF_E_LINK:
++		brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
++			  event_name, link ? "UP" : "DOWN");
++		break;
++
++	case BRCMF_E_MIC_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
++			  event_name, eabuf, group, flush_txq);
++		break;
++
++	case BRCMF_E_ICV_ERROR:
++	case BRCMF_E_UNICAST_DECODE_ERROR:
++	case BRCMF_E_MULTICAST_DECODE_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_TXFAIL:
++		brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_SCAN_COMPLETE:
++	case BRCMF_E_PMKID_CACHE:
++		brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PFN_NET_FOUND:
++	case BRCMF_E_PFN_NET_LOST:
++	case BRCMF_E_PFN_SCAN_COMPLETE:
++		brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PSK_SUP:
++	case BRCMF_E_PRUNE:
++		brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
++			  event_name, (int)status, (int)reason);
++		break;
++
++	case BRCMF_E_TRACE:
++		buf = (unsigned char *) event_data;
++		memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
++
++		if (hdr.version != MSGTRACE_VERSION) {
++			brcmf_dbg(ERROR,
++				  "MACEVENT: %s [unsupported version --> brcmf"
++				  " version:%d dongle version:%d]\n",
++				  event_name, MSGTRACE_VERSION, hdr.version);
++			/* Reset datalen to avoid display below */
++			datalen = 0;
++			break;
++		}
++
++		/* There are 2 bytes available at the end of data */
++		*(buf + sizeof(struct msgtrace_hdr)
++			 + be16_to_cpu(hdr.len)) = '\0';
++
++		if (be32_to_cpu(hdr.discarded_bytes)
++		    || be32_to_cpu(hdr.discarded_printf))
++			brcmf_dbg(ERROR,
++				  "WLC_E_TRACE: [Discarded traces in dongle -->"
++				  " discarded_bytes %d discarded_printf %d]\n",
++				  be32_to_cpu(hdr.discarded_bytes),
++				  be32_to_cpu(hdr.discarded_printf));
++
++		nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
++		if (nblost > 0)
++			brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
++				  " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
++				  nblost);
++		seqnum_prev = be32_to_cpu(hdr.seqnum);
++
++		/* Display the trace buffer. Advance from \n to \n to
++		 * avoid display big
++		 * printf (issue with Linux printk )
++		 */
++		p = (char *)&buf[sizeof(struct msgtrace_hdr)];
++		while ((s = strstr(p, "\n")) != NULL) {
++			*s = '\0';
++			pr_debug("%s\n", p);
++			p = s + 1;
++		}
++		pr_debug("%s\n", p);
++
++		/* Reset datalen to avoid display below */
++		datalen = 0;
++		break;
++
++	case BRCMF_E_RSSI:
++		brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
++			  event_name, be32_to_cpu(*((__be32 *)event_data)));
++		break;
++
++	default:
++		brcmf_dbg(EVENT,
++			  "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
++			  "auth %d\n", event_name, event_type, eabuf,
++			  (int)status, (int)reason, (int)auth_type);
++		break;
++	}
++
++	/* show any appended data */
++	if (datalen) {
++		buf = (unsigned char *) event_data;
++		brcmf_dbg(EVENT, " data (%d) : ", datalen);
++		for (i = 0; i < datalen; i++)
++			brcmf_dbg(EVENT, " 0x%02x ", *buf++);
++		brcmf_dbg(EVENT, "\n");
++	}
++}
++#endif				/* DEBUG */
++
++int
++brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
++		   struct brcmf_event_msg *event, void **data_ptr)
++{
++	/* check whether packet is a BRCM event pkt */
++	struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
++	struct brcmf_if_event *ifevent;
++	char *event_data;
++	u32 type, status;
++	u16 flags;
++	int evlen;
++
++	if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
++		brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
++		return -EBADE;
++	}
++
++	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
++	if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
++	    BCMILCP_BCM_SUBTYPE_EVENT) {
++		brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
++		return -EBADE;
++	}
++
++	*data_ptr = &pvt_data[1];
++	event_data = *data_ptr;
++
++	/* memcpy since BRCM event pkt may be unaligned. */
++	memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
++
++	type = get_unaligned_be32(&event->event_type);
++	flags = get_unaligned_be16(&event->flags);
++	status = get_unaligned_be32(&event->status);
++	evlen = get_unaligned_be32(&event->datalen) +
++		sizeof(struct brcmf_event);
++
++	switch (type) {
++	case BRCMF_E_IF:
++		ifevent = (struct brcmf_if_event *) event_data;
++		brcmf_dbg(TRACE, "if event\n");
++
++		if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
++			if (ifevent->action == BRCMF_E_IF_ADD)
++				brcmf_add_if(drvr->dev, ifevent->ifidx,
++					     event->ifname,
++					     pvt_data->eth.h_dest);
++			else
++				brcmf_del_if(drvr, ifevent->ifidx);
++		} else {
++			brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
++				  ifevent->ifidx, event->ifname);
++		}
++
++		/* send up the if event: btamp user needs it */
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		break;
++
++		/* These are what external supplicant/authenticator wants */
++	case BRCMF_E_LINK:
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++	case BRCMF_E_DISASSOC_IND:
++	case BRCMF_E_MIC_ERROR:
++	default:
++		/* Fall through: this should get _everything_  */
++
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
++			  type, flags, status);
++
++		/* put it back to BRCMF_E_NDIS_LINK */
++		if (type == BRCMF_E_NDIS_LINK) {
++			u32 temp1;
++			__be32 temp2;
++
++			temp1 = get_unaligned_be32(&event->event_type);
++			brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
++				  temp1);
++
++			temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
++			memcpy((void *)(&pvt_data->msg.event_type), &temp2,
++			       sizeof(pvt_data->msg.event_type));
++		}
++		break;
++	}
++
++#ifdef DEBUG
++	brcmf_c_show_host_event(event, event_data);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++/* Convert user's input in hex pattern to byte-size mask */
++static int brcmf_c_pattern_atoh(char *src, char *dst)
++{
++	int i;
++	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
++		return -EINVAL;
++	}
++	src = src + 2;		/* Skip past 0x */
++	if (strlen(src) % 2 != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
++		return -EINVAL;
++	}
++	for (i = 0; *src != '\0'; i++) {
++		unsigned long res;
++		char num[3];
++		strncpy(num, src, 2);
++		num[2] = '\0';
++		if (kstrtoul(num, 16, &res))
++			return -EINVAL;
++		dst[i] = (u8)res;
++		src += 2;
++	}
++	return i;
++}
++
++void
++brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
++			     int master_mode)
++{
++	unsigned long res;
++	char *argv[8];
++	int i = 0;
++	const char *str;
++	int buf_len;
++	int str_len;
++	char *arg_save = NULL, *arg_org = NULL;
++	int rc;
++	char buf[128];
++	struct brcmf_pkt_filter_enable_le enable_parm;
++	struct brcmf_pkt_filter_enable_le *pkt_filterp;
++	__le32 mmode_le;
++
++	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++	memcpy(arg_save, arg, strlen(arg) + 1);
++
++	argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_enable";
++	str_len = strlen(str);
++	strncpy(buf, str, str_len);
++	buf[str_len] = '\0';
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	enable_parm.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		enable_parm.id = cpu_to_le32((u32)res);
++
++	/* Parse enable/disable value. */
++	enable_parm.enable = cpu_to_le32(enable);
++
++	buf_len += sizeof(enable_parm);
++	memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
++
++	/* Enable/disable the specified filter. */
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++	/* Contorl the master mode */
++	mmode_le = cpu_to_le32(master_mode);
++	brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
++		    sizeof(buf));
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
++				       sizeof(buf));
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++
++fail:
++	kfree(arg_org);
++}
++
++void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
++{
++	const char *str;
++	struct brcmf_pkt_filter_le pkt_filter;
++	struct brcmf_pkt_filter_le *pkt_filterp;
++	unsigned long res;
++	int buf_len;
++	int str_len;
++	int rc;
++	u32 mask_size;
++	u32 pattern_size;
++	char *argv[8], *buf = NULL;
++	int i = 0;
++	char *arg_save = NULL, *arg_org = NULL;
++
++	arg_save = kstrdup(arg, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++
++	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
++	if (!buf)
++		goto fail;
++
++	argv[i] = strsep(&arg_save, " ");
++	while (argv[i++])
++		argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_add";
++	strcpy(buf, str);
++	str_len = strlen(str);
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	pkt_filter.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.id = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Polarity not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter polarity. */
++	pkt_filter.negate_match = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.negate_match = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Filter type not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter type. */
++	pkt_filter.type = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.type = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Offset not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter offset. */
++	pkt_filter.u.pattern.offset = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Bitmask not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter mask. */
++	mask_size =
++	    brcmf_c_pattern_atoh
++		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Pattern not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter pattern. */
++	pattern_size =
++	    brcmf_c_pattern_atoh(argv[i],
++				   (char *)&pkt_filterp->u.pattern.
++				   mask_and_pattern[mask_size]);
++
++	if (mask_size != pattern_size) {
++		brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
++		goto fail;
++	}
++
++	pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
++	buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
++	buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
++
++	/* Keep-alive attributes are set in local
++	 * variable (keep_alive_pkt), and
++	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
++	 ** guarantee that the buffer is properly aligned.
++	 */
++	memcpy((char *)pkt_filterp,
++	       &pkt_filter,
++	       BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
++
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++fail:
++	kfree(arg_org);
++
++	kfree(buf);
++}
++
++static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
++			  arp_mode, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
++			  arp_mode);
++}
++
++static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
++			iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
++			  arp_enable, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
++			  arp_enable);
++}
++
++int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
++{
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];	/*  Room for
++				 "event_msgs" + '\0' + bitvec  */
++	char buf[128], *ptr;
++	u32 dongle_align = drvr->bus_if->align;
++	u32 glom = 0;
++	u32 roaming = 1;
++	uint bcn_timeout = 3;
++	int scan_assoc_time = 40;
++	int scan_unassoc_time = 40;
++	int i;
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Set Country code */
++	if (drvr->country_code[0] != 0) {
++		if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
++					      drvr->country_code,
++					      sizeof(drvr->country_code)) < 0)
++			brcmf_dbg(ERROR, "country code setting failed\n");
++	}
++
++	/* query for 'ver' to get version info from firmware */
++	memset(buf, 0, sizeof(buf));
++	ptr = buf;
++	brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
++	strsep(&ptr, "\n");
++	/* Print fw version info */
++	brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
++
++	/* Match Host and Dongle rx alignment */
++	brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* disable glom option per default */
++	brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup timeout if Beacons are lost and roam is off to report
++		 link down */
++	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Enable/Disable build-in roaming to allowed ext supplicant to take
++		 of romaing */
++	brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
++
++	/* Set and enable ARP offload feature */
++	brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
++	brcmf_c_arp_offload_enable(drvr, true);
++
++	/* Set up pkt filter */
++	for (i = 0; i < drvr->pktfilter_count; i++) {
++		brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
++		brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
++						 0, true);
++	}
++
++	mutex_unlock(&drvr->proto_block);
++
++	return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+new file mode 100644
+index 0000000..a2c4576
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_DBG_H_
++#define _BRCMF_DBG_H_
++
++/* message levels */
++#define BRCMF_ERROR_VAL	0x0001
++#define BRCMF_TRACE_VAL	0x0002
++#define BRCMF_INFO_VAL	0x0004
++#define BRCMF_DATA_VAL	0x0008
++#define BRCMF_CTL_VAL	0x0010
++#define BRCMF_TIMER_VAL	0x0020
++#define BRCMF_HDRS_VAL	0x0040
++#define BRCMF_BYTES_VAL	0x0080
++#define BRCMF_INTR_VAL	0x0100
++#define BRCMF_GLOM_VAL	0x0400
++#define BRCMF_EVENT_VAL	0x0800
++#define BRCMF_BTA_VAL	0x1000
++#define BRCMF_ISCAN_VAL 0x2000
++
++#if defined(DEBUG)
++
++#define brcmf_dbg(level, fmt, ...)					\
++do {									\
++	if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) {			\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			if (net_ratelimit())				\
++				pr_debug("%s: " fmt,			\
++					 __func__, ##__VA_ARGS__);	\
++		}							\
++	} else {							\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			pr_debug("%s: " fmt,				\
++				 __func__, ##__VA_ARGS__);		\
++		}							\
++	}								\
++} while (0)
++
++#define BRCMF_DATA_ON()		(brcmf_msg_level & BRCMF_DATA_VAL)
++#define BRCMF_CTL_ON()		(brcmf_msg_level & BRCMF_CTL_VAL)
++#define BRCMF_HDRS_ON()		(brcmf_msg_level & BRCMF_HDRS_VAL)
++#define BRCMF_BYTES_ON()	(brcmf_msg_level & BRCMF_BYTES_VAL)
++#define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
++
++#else	/* (defined DEBUG) || (defined DEBUG) */
++
++#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
++
++#define BRCMF_DATA_ON()		0
++#define BRCMF_CTL_ON()		0
++#define BRCMF_HDRS_ON()		0
++#define BRCMF_BYTES_ON()	0
++#define BRCMF_GLOM_ON()		0
++
++#endif				/* defined(DEBUG) */
++
++#define brcmf_dbg_hex_dump(test, data, len, fmt, ...)			\
++do {									\
++	if (test)							\
++		brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__);	\
++} while (0)
++
++extern int brcmf_msg_level;
++
++#endif				/* _BRCMF_DBG_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+new file mode 100644
+index 0000000..7c42840
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+@@ -0,0 +1,1232 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/random.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/hardirq.h>
++#include <linux/mutex.h>
++#include <linux/wait.h>
++#include <linux/module.h>
++#include <net/cfg80211.h>
++#include <net/rtnetlink.h>
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++#include "wl_cfg80211.h"
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* Interface control information */
++struct brcmf_if {
++	struct brcmf_pub *drvr;	/* back pointer to brcmf_pub */
++	/* OS/stack specifics */
++	struct net_device *ndev;
++	struct net_device_stats stats;
++	int idx;		/* iface idx in dongle */
++	u8 mac_addr[ETH_ALEN];	/* assigned MAC address */
++};
++
++/* Error bits */
++int brcmf_msg_level = BRCMF_ERROR_VAL;
++module_param(brcmf_msg_level, int, 0);
++
++int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name)
++{
++	int i = BRCMF_MAX_IFS;
++	struct brcmf_if *ifp;
++
++	if (name == NULL || *name == '\0')
++		return 0;
++
++	while (--i > 0) {
++		ifp = drvr->iflist[i];
++		if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
++			break;
++	}
++
++	brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
++
++	return i;		/* default - the primary interface */
++}
++
++char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
++{
++	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
++		return "<if_bad>";
++	}
++
++	if (drvr->iflist[ifidx] == NULL) {
++		brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
++		return "<if_null>";
++	}
++
++	if (drvr->iflist[ifidx]->ndev)
++		return drvr->iflist[ifidx]->ndev->name;
++
++	return "<if_none>";
++}
++
++static void _brcmf_set_multicast_list(struct work_struct *work)
++{
++	struct net_device *ndev;
++	struct netdev_hw_addr *ha;
++	u32 dcmd_value, cnt;
++	__le32 cnt_le;
++	__le32 dcmd_le_value;
++
++	struct brcmf_dcmd dcmd;
++	char *buf, *bufp;
++	uint buflen;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    multicast_work);
++
++	ndev = drvr->iflist[0]->ndev;
++	cnt = netdev_mc_count(ndev);
++
++	/* Determine initial value of allmulti flag */
++	dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
++
++	/* Send down the multicast list first. */
++
++	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
++	bufp = buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!bufp)
++		return;
++
++	strcpy(bufp, "mcast_list");
++	bufp += strlen("mcast_list") + 1;
++
++	cnt_le = cpu_to_le32(cnt);
++	memcpy(bufp, &cnt_le, sizeof(cnt));
++	bufp += sizeof(cnt_le);
++
++	netdev_for_each_mc_addr(ha, ndev) {
++		if (!cnt)
++			break;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
++		memcpy(bufp, ha->addr, ETH_ALEN);
++#else
++		memcpy(bufp, ha->dmi_addr, ETH_ALEN);
++#endif
++		bufp += ETH_ALEN;
++		cnt--;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
++			  brcmf_ifname(drvr, 0), cnt);
++		dcmd_value = cnt ? true : dcmd_value;
++	}
++
++	kfree(buf);
++
++	/* Now send the allmulti setting.  This is based on the setting in the
++	 * net_device flags, but might be modified above to be turned on if we
++	 * were trying to set some addresses and dongle rejected it...
++	 */
++
++	buflen = sizeof("allmulti") + sizeof(dcmd_value);
++	buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!buf)
++		return;
++
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	if (!brcmf_c_mkiovar
++	    ("allmulti", (void *)&dcmd_le_value,
++	    sizeof(dcmd_le_value), buf, buflen)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
++			  brcmf_ifname(drvr, 0),
++			  (int)sizeof(dcmd_value), buflen);
++		kfree(buf);
++		return;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++
++	kfree(buf);
++
++	/* Finally, pick up the PROMISC flag as well, like the NIC
++		 driver does */
++
++	dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_PROMISC;
++	dcmd.buf = &dcmd_le_value;
++	dcmd.len = sizeof(dcmd_le_value);
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++}
++
++static void
++_brcmf_set_mac_address(struct work_struct *work)
++{
++	char buf[32];
++	struct brcmf_dcmd dcmd;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    setmacaddr_work);
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
++			   ETH_ALEN, buf, 32)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
++			  brcmf_ifname(drvr, 0));
++		return;
++	}
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = 32;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
++			  brcmf_ifname(drvr, 0));
++	else
++		memcpy(drvr->iflist[0]->ndev->dev_addr,
++		       drvr->macvalue, ETH_ALEN);
++
++	return;
++}
++
++static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct sockaddr *sa = (struct sockaddr *)addr;
++
++	memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN);
++	schedule_work(&drvr->setmacaddr_work);
++	return 0;
++}
++
++static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	schedule_work(&drvr->multicast_work);
++}
++
++int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
++{
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN))
++		return -ENODEV;
++
++	/* Update multicast statistic */
++	if (pktbuf->len >= ETH_ALEN) {
++		u8 *pktdata = (u8 *) (pktbuf->data);
++		struct ethhdr *eh = (struct ethhdr *)pktdata;
++
++		if (is_multicast_ether_addr(eh->h_dest))
++			drvr->tx_multicast++;
++		if (ntohs(eh->h_proto) == ETH_P_PAE)
++			atomic_inc(&drvr->pend_8021x_cnt);
++	}
++
++	/* If the protocol uses a data header, apply it */
++	brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
++
++	/* Use bus module to send data frame */
++	return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf);
++}
++
++static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	int ret;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up ||
++	    (drvr->bus_if->state == BRCMF_BUS_DOWN)) {
++		brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
++			  drvr->bus_if->drvr_up,
++			  drvr->bus_if->state);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	if (!drvr->iflist[ifp->idx]) {
++		brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	/* Make sure there's enough room for any header */
++	if (skb_headroom(skb) < drvr->hdrlen) {
++		struct sk_buff *skb2;
++
++		brcmf_dbg(INFO, "%s: insufficient headroom\n",
++			  brcmf_ifname(drvr, ifp->idx));
++		drvr->bus_if->tx_realloc++;
++		skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
++		dev_kfree_skb(skb);
++		skb = skb2;
++		if (skb == NULL) {
++			brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
++				  brcmf_ifname(drvr, ifp->idx));
++			ret = -ENOMEM;
++			goto done;
++		}
++	}
++
++	ret = brcmf_sendpkt(drvr, ifp->idx, skb);
++
++done:
++	if (ret)
++		drvr->bus_if->dstats.tx_dropped++;
++	else
++		drvr->bus_if->dstats.tx_packets++;
++
++	/* Return ok: we always eat the packet */
++	return 0;
++}
++
++void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
++{
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ndev = drvr->iflist[ifidx]->ndev;
++	if (state == ON)
++		netif_stop_queue(ndev);
++	else
++		netif_wake_queue(ndev);
++}
++
++static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
++			    void *pktdata, struct brcmf_event_msg *event,
++			    void **data)
++{
++	int bcmerror = 0;
++
++	bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data);
++	if (bcmerror != 0)
++		return bcmerror;
++
++	if (drvr->iflist[*ifidx]->ndev)
++		brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
++				     event, *data);
++
++	return bcmerror;
++}
++
++void brcmf_rx_frame(struct device *dev, int ifidx,
++		    struct sk_buff_head *skb_list)
++{
++	unsigned char *eth;
++	uint len;
++	void *data;
++	struct sk_buff *skb, *pnext;
++	struct brcmf_if *ifp;
++	struct brcmf_event_msg event;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	skb_queue_walk_safe(skb_list, skb, pnext) {
++		skb_unlink(skb, skb_list);
++
++		/* Get the protocol, maintain skb around eth_type_trans()
++		 * The main reason for this hack is for the limitation of
++		 * Linux 2.4 where 'eth_type_trans' uses the
++		 * 'net->hard_header_len'
++		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
++		 * coping of the packet coming from the network stack to add
++		 * BDC, Hardware header etc, during network interface
++		 * registration
++		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
++		 * required
++		 * for BDC, Hardware header etc. and not just the ETH_HLEN
++		 */
++		eth = skb->data;
++		len = skb->len;
++
++		ifp = drvr->iflist[ifidx];
++		if (ifp == NULL)
++			ifp = drvr->iflist[0];
++
++		if (!ifp || !ifp->ndev ||
++		    ifp->ndev->reg_state != NETREG_REGISTERED) {
++			brcmu_pkt_buf_free_skb(skb);
++			continue;
++		}
++
++		skb->dev = ifp->ndev;
++		skb->protocol = eth_type_trans(skb, skb->dev);
++
++		if (skb->pkt_type == PACKET_MULTICAST)
++			bus_if->dstats.multicast++;
++
++		skb->data = eth;
++		skb->len = len;
++
++		/* Strip header, count, deliver upward */
++		skb_pull(skb, ETH_HLEN);
++
++		/* Process special event packets and then discard them */
++		if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
++			brcmf_host_event(drvr, &ifidx,
++					  skb_mac_header(skb),
++					  &event, &data);
++
++		if (drvr->iflist[ifidx]) {
++			ifp = drvr->iflist[ifidx];
++			ifp->ndev->last_rx = jiffies;
++		}
++
++		bus_if->dstats.rx_bytes += skb->len;
++		bus_if->dstats.rx_packets++;	/* Local count */
++
++		if (in_interrupt())
++			netif_rx(skb);
++		else
++			/* If the receive is not processed inside an ISR,
++			 * the softirqd must be woken explicitly to service
++			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
++			 * by netif_rx_ni(), but in earlier kernels, we need
++			 * to do it manually.
++			 */
++			netif_rx_ni(skb);
++	}
++}
++
++void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
++{
++	uint ifidx;
++	struct ethhdr *eh;
++	u16 type;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_proto_hdrpull(dev, &ifidx, txp);
++
++	eh = (struct ethhdr *)(txp->data);
++	type = ntohs(eh->h_proto);
++
++	if (type == ETH_P_PAE)
++		atomic_dec(&drvr->pend_8021x_cnt);
++
++}
++
++static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_bus *bus_if = ifp->drvr->bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Copy dongle stats to net device stats */
++	ifp->stats.rx_packets = bus_if->dstats.rx_packets;
++	ifp->stats.tx_packets = bus_if->dstats.tx_packets;
++	ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
++	ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
++	ifp->stats.rx_errors = bus_if->dstats.rx_errors;
++	ifp->stats.tx_errors = bus_if->dstats.tx_errors;
++	ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
++	ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
++	ifp->stats.multicast = bus_if->dstats.multicast;
++
++	return &ifp->stats;
++}
++
++/* Retrieve current toe component enables, which are kept
++	 as a bitmap in toe_ol iovar */
++static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	__le32 toe_le;
++	char buf[32];
++	int ret;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_GET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = false;
++
++	strcpy(buf, "toe_ol");
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		/* Check for older dongle image that doesn't support toe_ol */
++		if (ret == -EIO) {
++			brcmf_dbg(ERROR, "%s: toe not supported by device\n",
++				  brcmf_ifname(drvr, ifidx));
++			return -EOPNOTSUPP;
++		}
++
++		brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	memcpy(&toe_le, buf, sizeof(u32));
++	*toe_ol = le32_to_cpu(toe_le);
++	return 0;
++}
++
++/* Set current toe component enables in toe_ol iovar,
++	 and set toe global enable iovar */
++static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	char buf[32];
++	int ret;
++	__le32 toe_le = cpu_to_le32(toe_ol);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = true;
++
++	/* Set toe_ol as requested */
++	strcpy(buf, "toe_ol");
++	memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	/* Enable toe globally only if any components are enabled. */
++	toe_le = cpu_to_le32(toe_ol != 0);
++
++	strcpy(buf, "toe");
++	memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	return 0;
++}
++
++static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
++				    struct ethtool_drvinfo *info)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	sprintf(info->driver, KBUILD_MODNAME);
++	sprintf(info->version, "%lu", drvr->drv_version);
++	sprintf(info->bus_info, "%s", dev_name(drvr->dev));
++}
++
++static const struct ethtool_ops brcmf_ethtool_ops = {
++	.get_drvinfo = brcmf_ethtool_get_drvinfo,
++};
++
++static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
++{
++	struct ethtool_drvinfo info;
++	char drvname[sizeof(info.driver)];
++	u32 cmd;
++	struct ethtool_value edata;
++	u32 toe_cmpnt, csum_dir;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* all ethtool calls start with a cmd word */
++	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
++		return -EFAULT;
++
++	switch (cmd) {
++	case ETHTOOL_GDRVINFO:
++		/* Copy out any request driver name */
++		if (copy_from_user(&info, uaddr, sizeof(info)))
++			return -EFAULT;
++		strncpy(drvname, info.driver, sizeof(info.driver));
++		drvname[sizeof(info.driver) - 1] = '\0';
++
++		/* clear struct for return */
++		memset(&info, 0, sizeof(info));
++		info.cmd = cmd;
++
++		/* if requested, identify ourselves */
++		if (strcmp(drvname, "?dhd") == 0) {
++			sprintf(info.driver, "dhd");
++			strcpy(info.version, BRCMF_VERSION_STR);
++		}
++
++		/* otherwise, require dongle to be up */
++		else if (!drvr->bus_if->drvr_up) {
++			brcmf_dbg(ERROR, "dongle is not up\n");
++			return -ENODEV;
++		}
++
++		/* finally, report dongle driver type */
++		else if (drvr->iswl)
++			sprintf(info.driver, "wl");
++		else
++			sprintf(info.driver, "xx");
++
++		sprintf(info.version, "%lu", drvr->drv_version);
++		if (copy_to_user(uaddr, &info, sizeof(info)))
++			return -EFAULT;
++		brcmf_dbg(CTL, "given %*s, returning %s\n",
++			  (int)sizeof(drvname), drvname, info.driver);
++		break;
++
++		/* Get toe offload components from dongle */
++	case ETHTOOL_GRXCSUM:
++	case ETHTOOL_GTXCSUM:
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		edata.cmd = cmd;
++		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
++
++		if (copy_to_user(uaddr, &edata, sizeof(edata)))
++			return -EFAULT;
++		break;
++
++		/* Set toe offload components in dongle */
++	case ETHTOOL_SRXCSUM:
++	case ETHTOOL_STXCSUM:
++		if (copy_from_user(&edata, uaddr, sizeof(edata)))
++			return -EFAULT;
++
++		/* Read the current settings, update and write back */
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		if (edata.data != 0)
++			toe_cmpnt |= csum_dir;
++		else
++			toe_cmpnt &= ~csum_dir;
++
++		ret = brcmf_toe_set(drvr, 0, toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		/* If setting TX checksum mode, tell Linux the new mode */
++		if (cmd == ETHTOOL_STXCSUM) {
++			if (edata.data)
++				drvr->iflist[0]->ndev->features |=
++				    NETIF_F_IP_CSUM;
++			else
++				drvr->iflist[0]->ndev->features &=
++				    ~NETIF_F_IP_CSUM;
++		}
++
++		break;
++
++	default:
++		return -EOPNOTSUPP;
++	}
++
++	return 0;
++}
++
++static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
++				    int cmd)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
++
++	if (!drvr->iflist[ifp->idx])
++		return -1;
++
++	if (cmd == SIOCETHTOOL)
++		return brcmf_ethtool(drvr, ifr->ifr_data);
++
++	return -EOPNOTSUPP;
++}
++
++/* called only from within this driver. Sends a command to the dongle. */
++s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
++{
++	struct brcmf_dcmd dcmd;
++	s32 err = 0;
++	int buflen = 0;
++	bool is_set_key_cmd;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = cmd;
++	dcmd.buf = arg;
++	dcmd.len = len;
++
++	if (dcmd.buf != NULL)
++		buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
++
++	/* send to dongle (must be up, and wl) */
++	if ((drvr->bus_if->state != BRCMF_BUS_DATA)) {
++		brcmf_dbg(ERROR, "DONGLE_DOWN\n");
++		err = -EIO;
++		goto done;
++	}
++
++	if (!drvr->iswl) {
++		err = -EIO;
++		goto done;
++	}
++
++	/*
++	 * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
++	 * set key CMD to prevent M4 encryption.
++	 */
++	is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("wsec_key", dcmd.buf, 9))) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
++	if (is_set_key_cmd)
++		brcmf_netdev_wait_pend8021x(ndev);
++
++	err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen);
++
++done:
++	if (err > 0)
++		err = 0;
++
++	return err;
++}
++
++static int brcmf_netdev_stop(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_cfg80211_down(drvr->config);
++	if (drvr->bus_if->drvr_up == 0)
++		return 0;
++
++	/* Set state and stop OS transmissions */
++	drvr->bus_if->drvr_up = false;
++	netif_stop_queue(ndev);
++
++	return 0;
++}
++
++static int brcmf_netdev_open(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct brcmf_bus *bus_if = drvr->bus_if;
++	u32 toe_ol;
++	s32 ret = 0;
++	uint up = 0;
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	if (ifp->idx == 0) {	/* do it only for primary eth0 */
++		/* If bus is not ready, can't continue */
++		if (bus_if->state != BRCMF_BUS_DATA) {
++			brcmf_dbg(ERROR, "failed bus is not ready\n");
++			return -EAGAIN;
++		}
++
++		atomic_set(&drvr->pend_8021x_cnt, 0);
++
++		memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
++
++		/* Get current TOE mode from dongle */
++		if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0
++		    && (toe_ol & TOE_TX_CSUM_OL) != 0)
++			drvr->iflist[ifp->idx]->ndev->features |=
++				NETIF_F_IP_CSUM;
++		else
++			drvr->iflist[ifp->idx]->ndev->features &=
++				~NETIF_F_IP_CSUM;
++	}
++
++	/* make sure RF is ready for work */
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
++
++	/* Allow transmit calls */
++	netif_start_queue(ndev);
++	drvr->bus_if->drvr_up = true;
++	if (brcmf_cfg80211_up(drvr->config)) {
++		brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
++		return -1;
++	}
++
++	return ret;
++}
++
++static const struct net_device_ops brcmf_netdev_ops_pri = {
++	.ndo_open = brcmf_netdev_open,
++	.ndo_stop = brcmf_netdev_stop,
++	.ndo_get_stats = brcmf_netdev_get_stats,
++	.ndo_do_ioctl = brcmf_netdev_ioctl_entry,
++	.ndo_start_xmit = brcmf_netdev_start_xmit,
++	.ndo_set_mac_address = brcmf_netdev_set_mac_address,
++	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
++};
++
++static int brcmf_net_attach(struct brcmf_if *ifp)
++{
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct net_device *ndev;
++	u8 temp_addr[ETH_ALEN];
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	ndev = drvr->iflist[ifp->idx]->ndev;
++	ndev->netdev_ops = &brcmf_netdev_ops_pri;
++
++	/*
++	 * determine mac address to use
++	 */
++	if (is_valid_ether_addr(ifp->mac_addr))
++		memcpy(temp_addr, ifp->mac_addr, ETH_ALEN);
++	else
++		memcpy(temp_addr, drvr->mac, ETH_ALEN);
++
++	if (ifp->idx == 1) {
++		brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
++		/*  ACCESSPOINT INTERFACE CASE */
++		temp_addr[0] |= 0X02;	/* set bit 2 ,
++			 - Locally Administered address  */
++
++	}
++	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
++	ndev->ethtool_ops = &brcmf_ethtool_ops;
++
++	drvr->rxsz = ndev->mtu + ndev->hard_header_len +
++			      drvr->hdrlen;
++
++	memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
++
++	/* attach to cfg80211 for primary interface */
++	if (!ifp->idx) {
++		drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
++		if (drvr->config == NULL) {
++			brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
++			goto fail;
++		}
++	}
++
++	if (register_netdev(ndev) != 0) {
++		brcmf_dbg(ERROR, "couldn't register the net device\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
++
++	return 0;
++
++fail:
++	ndev->netdev_ops = NULL;
++	return -EBADE;
++}
++
++int
++brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
++{
++	struct brcmf_if *ifp;
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	/*
++	 * Delete the existing interface before overwriting it
++	 * in case we missed the BRCMF_E_IF_DEL event.
++	 */
++	if (ifp) {
++		brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
++			  ifp->ndev->name);
++		netif_stop_queue(ifp->ndev);
++		unregister_netdev(ifp->ndev);
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++	}
++
++	/* Allocate netdev, including space for private structure */
++	ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
++	if (!ndev) {
++		brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
++		return -ENOMEM;
++	}
++
++	ifp = netdev_priv(ndev);
++	ifp->ndev = ndev;
++	ifp->drvr = drvr;
++	drvr->iflist[ifidx] = ifp;
++	ifp->idx = ifidx;
++	if (mac_addr != NULL)
++		memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
++
++	if (brcmf_net_attach(ifp)) {
++		brcmf_dbg(ERROR, "brcmf_net_attach failed");
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		return -EOPNOTSUPP;
++	}
++
++	brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
++		  current->pid, ifp->ndev->name);
++
++	return 0;
++}
++
++void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
++{
++	struct brcmf_if *ifp;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	if (!ifp) {
++		brcmf_dbg(ERROR, "Null interface\n");
++		return;
++	}
++	if (ifp->ndev) {
++		if (ifidx == 0) {
++			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
++				rtnl_lock();
++				brcmf_netdev_stop(ifp->ndev);
++				rtnl_unlock();
++			}
++		} else {
++			netif_stop_queue(ifp->ndev);
++		}
++
++		unregister_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		if (ifidx == 0)
++			brcmf_cfg80211_detach(drvr->config);
++		free_netdev(ifp->ndev);
++	}
++}
++
++int brcmf_attach(uint bus_hdrlen, struct device *dev)
++{
++	struct brcmf_pub *drvr = NULL;
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Allocate primary brcmf_info */
++	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
++	if (!drvr)
++		return -ENOMEM;
++
++	mutex_init(&drvr->proto_block);
++
++	/* Link to bus module */
++	drvr->hdrlen = bus_hdrlen;
++	drvr->bus_if = dev_get_drvdata(dev);
++	drvr->bus_if->drvr = drvr;
++	drvr->dev = dev;
++
++	/* Attach and link in the protocol */
++	ret = brcmf_proto_attach(drvr);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
++		goto fail;
++	}
++
++	INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address);
++	INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list);
++
++	return ret;
++
++fail:
++	brcmf_detach(dev);
++
++	return ret;
++}
++
++int brcmf_bus_start(struct device *dev)
++{
++	int ret = -1;
++	/* Room for "event_msgs" + '\0' + bitvec */
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Bring up the bus */
++	ret = bus_if->brcmf_bus_init(dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
++		return ret;
++	}
++
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
++				    sizeof(iovbuf));
++	memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(drvr->eventmask, BRCMF_E_SET_SSID);
++	setbit(drvr->eventmask, BRCMF_E_PRUNE);
++	setbit(drvr->eventmask, BRCMF_E_AUTH);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC);
++	setbit(drvr->eventmask, BRCMF_E_JOIN);
++	setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
++	setbit(drvr->eventmask, BRCMF_E_LINK);
++	setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
++	setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
++	setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(drvr->eventmask, BRCMF_E_TXFAIL);
++	setbit(drvr->eventmask, BRCMF_E_JOIN_START);
++	setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
++
++/* enable dongle roaming event */
++
++	drvr->pktfilter_count = 1;
++	/* Setup filter to allow only unicast */
++	drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
++
++	/* Bus is ready, do any protocol initialization */
++	ret = brcmf_proto_init(drvr);
++	if (ret < 0)
++		return ret;
++
++	/* add primary networking interface */
++	ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac);
++	if (ret < 0)
++		return ret;
++
++	/* signal bus ready */
++	bus_if->state = BRCMF_BUS_DATA;
++	return 0;
++}
++
++static void brcmf_bus_detach(struct brcmf_pub *drvr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (drvr) {
++		/* Stop the protocol module */
++		brcmf_proto_stop(drvr);
++
++		/* Stop the bus module */
++		drvr->bus_if->brcmf_bus_stop(drvr->dev);
++	}
++}
++
++void brcmf_detach(struct device *dev)
++{
++	int i;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++
++	/* make sure primary interface removed last */
++	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
++		if (drvr->iflist[i])
++			brcmf_del_if(drvr, i);
++
++	brcmf_bus_detach(drvr);
++
++	if (drvr->prot) {
++		cancel_work_sync(&drvr->setmacaddr_work);
++		cancel_work_sync(&drvr->multicast_work);
++		brcmf_proto_detach(drvr);
++	}
++
++	bus_if->drvr = NULL;
++	kfree(drvr);
++}
++
++static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
++{
++	return atomic_read(&drvr->pend_8021x_cnt);
++}
++
++#define MAX_WAIT_FOR_8021X_TX	10
++
++int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	int timeout = 10 * HZ / 1000;
++	int ntimes = MAX_WAIT_FOR_8021X_TX;
++	int pend = brcmf_get_pend_8021x_cnt(drvr);
++
++	while (ntimes && pend) {
++		if (pend) {
++			set_current_state(TASK_INTERRUPTIBLE);
++			schedule_timeout(timeout);
++			set_current_state(TASK_RUNNING);
++			ntimes--;
++		}
++		pend = brcmf_get_pend_8021x_cnt(drvr);
++	}
++	return pend;
++}
++
++#ifdef DEBUG
++int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
++{
++	int ret = 0;
++	struct file *fp;
++	mm_segment_t old_fs;
++	loff_t pos = 0;
++
++	/* change to KERNEL_DS address limit */
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	/* open file to write */
++	fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
++	if (!fp) {
++		brcmf_dbg(ERROR, "open file error\n");
++		ret = -1;
++		goto exit;
++	}
++
++	/* Write buf to file */
++	fp->f_op->write(fp, (char __user *)buf, size, &pos);
++
++exit:
++	/* free buf before return */
++	kfree(buf);
++	/* close file before return */
++	if (fp)
++		filp_close(fp, current->files);
++	/* restore previous address limit */
++	set_fs(old_fs);
++
++	return ret;
++}
++#endif				/* DEBUG */
++
++static void brcmf_driver_init(struct work_struct *work)
++{
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_init();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_init();
++#endif
++}
++static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
++
++static int __init brcmfmac_module_init(void)
++{
++	if (!schedule_work(&brcmf_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++static void __exit brcmfmac_module_exit(void)
++{
++	cancel_work_sync(&brcmf_driver_work);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_exit();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_exit();
++#endif
++}
++
++module_init(brcmfmac_module_init);
++module_exit(brcmfmac_module_exit);
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+new file mode 100644
+index 0000000..6bc4425
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_PROTO_H_
++#define _BRCMF_PROTO_H_
++
++/*
++ * Exported from the brcmf protocol module (brcmf_cdc)
++ */
++
++/* Linkage, sets prot link and updates hdrlen in pub */
++extern int brcmf_proto_attach(struct brcmf_pub *drvr);
++
++/* Unlink, frees allocated protocol memory (including brcmf_proto) */
++extern void brcmf_proto_detach(struct brcmf_pub *drvr);
++
++/* Initialize protocol: sync w/dongle state.
++ * Sets dongle media info (iswl, drv_version, mac address).
++ */
++extern int brcmf_proto_init(struct brcmf_pub *drvr);
++
++/* Stop protocol: sync w/dongle state. */
++extern void brcmf_proto_stop(struct brcmf_pub *drvr);
++
++/* Add any protocol-specific data header.
++ * Caller must reserve prot_hdrlen prepend space.
++ */
++extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
++				struct sk_buff *txp);
++
++/* Use protocol to issue command to dongle */
++extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
++				struct brcmf_dcmd *dcmd, int len);
++
++extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
++
++extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
++				     uint cmd, void *buf, uint len);
++
++#endif				/* _BRCMF_PROTO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+new file mode 100644
+index 0000000..0d23b8d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+@@ -0,0 +1,4014 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/netdevice.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++#include <linux/semaphore.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++#define DCMD_RESP_TIMEOUT  2000	/* In milli second */
++
++#ifdef DEBUG
++
++#define BRCMF_TRAP_INFO_SIZE	80
++
++#define CBUF_LEN	(128)
++
++struct rte_log_le {
++	__le32 buf;		/* Can't be pointer on (64-bit) hosts */
++	__le32 buf_size;
++	__le32 idx;
++	char *_buf_compat;	/* Redundant pointer for backward compat. */
++};
++
++struct rte_console {
++	/* Virtual UART
++	 * When there is no UART (e.g. Quickturn),
++	 * the host should write a complete
++	 * input line directly into cbuf and then write
++	 * the length into vcons_in.
++	 * This may also be used when there is a real UART
++	 * (at risk of conflicting with
++	 * the real UART).  vcons_out is currently unused.
++	 */
++	uint vcons_in;
++	uint vcons_out;
++
++	/* Output (logging) buffer
++	 * Console output is written to a ring buffer log_buf at index log_idx.
++	 * The host may read the output when it sees log_idx advance.
++	 * Output will be lost if the output wraps around faster than the host
++	 * polls.
++	 */
++	struct rte_log_le log_le;
++
++	/* Console input line buffer
++	 * Characters are read one at a time into cbuf
++	 * until <CR> is received, then
++	 * the buffer is processed as a command line.
++	 * Also used for virtual UART.
++	 */
++	uint cbuf_idx;
++	char cbuf[CBUF_LEN];
++};
++
++#endif				/* DEBUG */
++#include <chipcommon.h>
++
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++#define TXQLEN		2048	/* bulk tx queue length */
++#define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
++#define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
++#define PRIOMASK	7
++
++#define TXRETRIES	2	/* # of retries for tx frames */
++
++#define BRCMF_RXBOUND	50	/* Default for max rx frames in
++				 one scheduling */
++
++#define BRCMF_TXBOUND	20	/* Default for max tx frames in
++				 one scheduling */
++
++#define BRCMF_TXMINMAX	1	/* Max tx frames if rx still pending */
++
++#define MEMBLOCK	2048	/* Block size used for downloading
++				 of dongle image */
++#define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
++				 biggest possible glom */
++
++#define BRCMF_FIRSTREAD	(1 << 6)
++
++
++/* SBSDIO_DEVICE_CTL */
++
++/* 1: device will assert busy signal when receiving CMD53 */
++#define SBSDIO_DEVCTL_SETBUSY		0x01
++/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
++#define SBSDIO_DEVCTL_SPI_INTR_SYNC	0x02
++/* 1: mask all interrupts to host except the chipActive (rev 8) */
++#define SBSDIO_DEVCTL_CA_INT_ONLY	0x04
++/* 1: isolate internal sdio signals, put external pads in tri-state; requires
++ * sdio bus power cycle to clear (rev 9) */
++#define SBSDIO_DEVCTL_PADS_ISO		0x08
++/* Force SD->SB reset mapping (rev 11) */
++#define SBSDIO_DEVCTL_SB_RST_CTL	0x30
++/*   Determined by CoreControl bit */
++#define SBSDIO_DEVCTL_RST_CORECTL	0x00
++/*   Force backplane reset */
++#define SBSDIO_DEVCTL_RST_BPRESET	0x10
++/*   Force no backplane reset */
++#define SBSDIO_DEVCTL_RST_NOBPRESET	0x20
++
++/* direct(mapped) cis space */
++
++/* MAPPED common CIS address */
++#define SBSDIO_CIS_BASE_COMMON		0x1000
++/* maximum bytes in one CIS */
++#define SBSDIO_CIS_SIZE_LIMIT		0x200
++/* cis offset addr is < 17 bits */
++#define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF
++
++/* manfid tuple length, include tuple, link bytes */
++#define SBSDIO_CIS_MANFID_TUPLE_LEN	6
++
++/* intstatus */
++#define I_SMB_SW0	(1 << 0)	/* To SB Mail S/W interrupt 0 */
++#define I_SMB_SW1	(1 << 1)	/* To SB Mail S/W interrupt 1 */
++#define I_SMB_SW2	(1 << 2)	/* To SB Mail S/W interrupt 2 */
++#define I_SMB_SW3	(1 << 3)	/* To SB Mail S/W interrupt 3 */
++#define I_SMB_SW_MASK	0x0000000f	/* To SB Mail S/W interrupts mask */
++#define I_SMB_SW_SHIFT	0	/* To SB Mail S/W interrupts shift */
++#define I_HMB_SW0	(1 << 4)	/* To Host Mail S/W interrupt 0 */
++#define I_HMB_SW1	(1 << 5)	/* To Host Mail S/W interrupt 1 */
++#define I_HMB_SW2	(1 << 6)	/* To Host Mail S/W interrupt 2 */
++#define I_HMB_SW3	(1 << 7)	/* To Host Mail S/W interrupt 3 */
++#define I_HMB_SW_MASK	0x000000f0	/* To Host Mail S/W interrupts mask */
++#define I_HMB_SW_SHIFT	4	/* To Host Mail S/W interrupts shift */
++#define I_WR_OOSYNC	(1 << 8)	/* Write Frame Out Of Sync */
++#define I_RD_OOSYNC	(1 << 9)	/* Read Frame Out Of Sync */
++#define	I_PC		(1 << 10)	/* descriptor error */
++#define	I_PD		(1 << 11)	/* data error */
++#define	I_DE		(1 << 12)	/* Descriptor protocol Error */
++#define	I_RU		(1 << 13)	/* Receive descriptor Underflow */
++#define	I_RO		(1 << 14)	/* Receive fifo Overflow */
++#define	I_XU		(1 << 15)	/* Transmit fifo Underflow */
++#define	I_RI		(1 << 16)	/* Receive Interrupt */
++#define I_BUSPWR	(1 << 17)	/* SDIO Bus Power Change (rev 9) */
++#define I_XMTDATA_AVAIL (1 << 23)	/* bits in fifo */
++#define	I_XI		(1 << 24)	/* Transmit Interrupt */
++#define I_RF_TERM	(1 << 25)	/* Read Frame Terminate */
++#define I_WF_TERM	(1 << 26)	/* Write Frame Terminate */
++#define I_PCMCIA_XU	(1 << 27)	/* PCMCIA Transmit FIFO Underflow */
++#define I_SBINT		(1 << 28)	/* sbintstatus Interrupt */
++#define I_CHIPACTIVE	(1 << 29)	/* chip from doze to active state */
++#define I_SRESET	(1 << 30)	/* CCCR RES interrupt */
++#define I_IOE2		(1U << 31)	/* CCCR IOE2 Bit Changed */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
++#define I_DMA		(I_RI | I_XI | I_ERRORS)
++
++/* corecontrol */
++#define CC_CISRDY		(1 << 0)	/* CIS Ready */
++#define CC_BPRESEN		(1 << 1)	/* CCCR RES signal */
++#define CC_F2RDY		(1 << 2)	/* set CCCR IOR2 bit */
++#define CC_CLRPADSISO		(1 << 3)	/* clear SDIO pads isolation */
++#define CC_XMTDATAAVAIL_MODE	(1 << 4)
++#define CC_XMTDATAAVAIL_CTRL	(1 << 5)
++
++/* SDA_FRAMECTRL */
++#define SFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
++#define SFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
++#define SFC_CRC4WOOS	(1 << 2)	/* CRC error for write out of sync */
++#define SFC_ABORTALL	(1 << 3)	/* Abort all in-progress frames */
++
++/* HW frame tag */
++#define SDPCM_FRAMETAG_LEN	4	/* 2 bytes len, 2 bytes check val */
++
++/* Total length of frame header for dongle protocol */
++#define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
++#define SDPCM_RESERVE	(SDPCM_HDRLEN + BRCMF_SDALIGN)
++
++/*
++ * Software allocation of To SB Mailbox resources
++ */
++
++/* tosbmailbox bits corresponding to intstatus bits */
++#define SMB_NAK		(1 << 0)	/* Frame NAK */
++#define SMB_INT_ACK	(1 << 1)	/* Host Interrupt ACK */
++#define SMB_USE_OOB	(1 << 2)	/* Use OOB Wakeup */
++#define SMB_DEV_INT	(1 << 3)	/* Miscellaneous Interrupt */
++
++/* tosbmailboxdata */
++#define SMB_DATA_VERSION_SHIFT	16	/* host protocol version */
++
++/*
++ * Software allocation of To Host Mailbox resources
++ */
++
++/* intstatus bits */
++#define I_HMB_FC_STATE	I_HMB_SW0	/* Flow Control State */
++#define I_HMB_FC_CHANGE	I_HMB_SW1	/* Flow Control State Changed */
++#define I_HMB_FRAME_IND	I_HMB_SW2	/* Frame Indication */
++#define I_HMB_HOST_INT	I_HMB_SW3	/* Miscellaneous Interrupt */
++
++/* tohostmailboxdata */
++#define HMB_DATA_NAKHANDLED	1	/* retransmit NAK'd frame */
++#define HMB_DATA_DEVREADY	2	/* talk to host after enable */
++#define HMB_DATA_FC		4	/* per prio flowcontrol update flag */
++#define HMB_DATA_FWREADY	8	/* fw ready for protocol activity */
++
++#define HMB_DATA_FCDATA_MASK	0xff000000
++#define HMB_DATA_FCDATA_SHIFT	24
++
++#define HMB_DATA_VERSION_MASK	0x00ff0000
++#define HMB_DATA_VERSION_SHIFT	16
++
++/*
++ * Software-defined protocol header
++ */
++
++/* Current protocol version */
++#define SDPCM_PROT_VERSION	4
++
++/* SW frame header */
++#define SDPCM_PACKET_SEQUENCE(p)	(((u8 *)p)[0] & 0xff)
++
++#define SDPCM_CHANNEL_MASK		0x00000f00
++#define SDPCM_CHANNEL_SHIFT		8
++#define SDPCM_PACKET_CHANNEL(p)		(((u8 *)p)[1] & 0x0f)
++
++#define SDPCM_NEXTLEN_OFFSET		2
++
++/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
++#define SDPCM_DOFFSET_OFFSET		3	/* Data Offset */
++#define SDPCM_DOFFSET_VALUE(p)		(((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
++#define SDPCM_DOFFSET_MASK		0xff000000
++#define SDPCM_DOFFSET_SHIFT		24
++#define SDPCM_FCMASK_OFFSET		4	/* Flow control */
++#define SDPCM_FCMASK_VALUE(p)		(((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
++#define SDPCM_WINDOW_OFFSET		5	/* Credit based fc */
++#define SDPCM_WINDOW_VALUE(p)		(((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
++
++#define SDPCM_SWHEADER_LEN	8	/* SW header is 64 bits */
++
++/* logical channel numbers */
++#define SDPCM_CONTROL_CHANNEL	0	/* Control channel Id */
++#define SDPCM_EVENT_CHANNEL	1	/* Asyc Event Indication Channel Id */
++#define SDPCM_DATA_CHANNEL	2	/* Data Xmit/Recv Channel Id */
++#define SDPCM_GLOM_CHANNEL	3	/* For coalesced packets */
++#define SDPCM_TEST_CHANNEL	15	/* Reserved for test/debug packets */
++
++#define SDPCM_SEQUENCE_WRAP	256	/* wrap-around val for 8bit frame seq */
++
++#define SDPCM_GLOMDESC(p)	(((u8 *)p)[1] & 0x80)
++
++/*
++ * Shared structure between dongle and the host.
++ * The structure contains pointers to trap or assert information.
++ */
++#define SDPCM_SHARED_VERSION       0x0002
++#define SDPCM_SHARED_VERSION_MASK  0x00FF
++#define SDPCM_SHARED_ASSERT_BUILT  0x0100
++#define SDPCM_SHARED_ASSERT        0x0200
++#define SDPCM_SHARED_TRAP          0x0400
++
++/* Space for header read, limit for data packets */
++#define MAX_HDR_READ	(1 << 6)
++#define MAX_RX_DATASZ	2048
++
++/* Maximum milliseconds to wait for F2 to come up */
++#define BRCMF_WAIT_F2RDY	3000
++
++/* Bump up limit on waiting for HT to account for first startup;
++ * if the image is doing a CRC calculation before programming the PMU
++ * for HT availability, it could take a couple hundred ms more, so
++ * max out at a 1 second (1000000us).
++ */
++#undef PMU_MAX_TRANSITION_DLY
++#define PMU_MAX_TRANSITION_DLY 1000000
++
++/* Value for ChipClockCSR during initial setup */
++#define BRCMF_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
++					SBSDIO_ALP_AVAIL_REQ)
++
++/* Flags for SDH calls */
++#define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
++
++#define BRCMF_SDIO_FW_NAME	"brcm/brcmfmac-sdio.bin"
++#define BRCMF_SDIO_NV_NAME	"brcm/brcmfmac-sdio.txt"
++MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
++MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
++
++#define BRCMF_IDLE_IMMEDIATE	(-1)	/* Enter idle immediately */
++#define BRCMF_IDLE_ACTIVE	0	/* Do not request any SD clock change
++					 * when idle
++					 */
++#define BRCMF_IDLE_INTERVAL	1
++
++/*
++ * Conversion of 802.1D priority to precedence level
++ */
++static uint prio2prec(u32 prio)
++{
++	return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
++	       (prio^2) : prio;
++}
++
++/* core registers */
++struct sdpcmd_regs {
++	u32 corecontrol;		/* 0x00, rev8 */
++	u32 corestatus;			/* rev8 */
++	u32 PAD[1];
++	u32 biststatus;			/* rev8 */
++
++	/* PCMCIA access */
++	u16 pcmciamesportaladdr;	/* 0x010, rev8 */
++	u16 PAD[1];
++	u16 pcmciamesportalmask;	/* rev8 */
++	u16 PAD[1];
++	u16 pcmciawrframebc;		/* rev8 */
++	u16 PAD[1];
++	u16 pcmciaunderflowtimer;	/* rev8 */
++	u16 PAD[1];
++
++	/* interrupt */
++	u32 intstatus;			/* 0x020, rev8 */
++	u32 hostintmask;		/* rev8 */
++	u32 intmask;			/* rev8 */
++	u32 sbintstatus;		/* rev8 */
++	u32 sbintmask;			/* rev8 */
++	u32 funcintmask;		/* rev4 */
++	u32 PAD[2];
++	u32 tosbmailbox;		/* 0x040, rev8 */
++	u32 tohostmailbox;		/* rev8 */
++	u32 tosbmailboxdata;		/* rev8 */
++	u32 tohostmailboxdata;		/* rev8 */
++
++	/* synchronized access to registers in SDIO clock domain */
++	u32 sdioaccess;			/* 0x050, rev8 */
++	u32 PAD[3];
++
++	/* PCMCIA frame control */
++	u8 pcmciaframectrl;		/* 0x060, rev8 */
++	u8 PAD[3];
++	u8 pcmciawatermark;		/* rev8 */
++	u8 PAD[155];
++
++	/* interrupt batching control */
++	u32 intrcvlazy;			/* 0x100, rev8 */
++	u32 PAD[3];
++
++	/* counters */
++	u32 cmd52rd;			/* 0x110, rev8 */
++	u32 cmd52wr;			/* rev8 */
++	u32 cmd53rd;			/* rev8 */
++	u32 cmd53wr;			/* rev8 */
++	u32 abort;			/* rev8 */
++	u32 datacrcerror;		/* rev8 */
++	u32 rdoutofsync;		/* rev8 */
++	u32 wroutofsync;		/* rev8 */
++	u32 writebusy;			/* rev8 */
++	u32 readwait;			/* rev8 */
++	u32 readterm;			/* rev8 */
++	u32 writeterm;			/* rev8 */
++	u32 PAD[40];
++	u32 clockctlstatus;		/* rev8 */
++	u32 PAD[7];
++
++	u32 PAD[128];			/* DMA engines */
++
++	/* SDIO/PCMCIA CIS region */
++	char cis[512];			/* 0x400-0x5ff, rev6 */
++
++	/* PCMCIA function control registers */
++	char pcmciafcr[256];		/* 0x600-6ff, rev6 */
++	u16 PAD[55];
++
++	/* PCMCIA backplane access */
++	u16 backplanecsr;		/* 0x76E, rev6 */
++	u16 backplaneaddr0;		/* rev6 */
++	u16 backplaneaddr1;		/* rev6 */
++	u16 backplaneaddr2;		/* rev6 */
++	u16 backplaneaddr3;		/* rev6 */
++	u16 backplanedata0;		/* rev6 */
++	u16 backplanedata1;		/* rev6 */
++	u16 backplanedata2;		/* rev6 */
++	u16 backplanedata3;		/* rev6 */
++	u16 PAD[31];
++
++	/* sprom "size" & "blank" info */
++	u16 spromstatus;		/* 0x7BE, rev2 */
++	u32 PAD[464];
++
++	u16 PAD[0x80];
++};
++
++#ifdef DEBUG
++/* Device console log buffer state */
++struct brcmf_console {
++	uint count;		/* Poll interval msec counter */
++	uint log_addr;		/* Log struct address (fixed) */
++	struct rte_log_le log_le;	/* Log struct (host copy) */
++	uint bufsize;		/* Size of log buffer */
++	u8 *buf;		/* Log buffer (host copy) */
++	uint last;		/* Last buffer read index */
++};
++#endif				/* DEBUG */
++
++struct sdpcm_shared {
++	u32 flags;
++	u32 trap_addr;
++	u32 assert_exp_addr;
++	u32 assert_file_addr;
++	u32 assert_line;
++	u32 console_addr;	/* Address of struct rte_console */
++	u32 msgtrace_addr;
++	u8 tag[32];
++};
++
++struct sdpcm_shared_le {
++	__le32 flags;
++	__le32 trap_addr;
++	__le32 assert_exp_addr;
++	__le32 assert_file_addr;
++	__le32 assert_line;
++	__le32 console_addr;	/* Address of struct rte_console */
++	__le32 msgtrace_addr;
++	u8 tag[32];
++};
++
++
++/* misc chip info needed by some of the routines */
++/* Private data for SDIO bus interaction */
++struct brcmf_sdio {
++	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */
++	struct chip_info *ci;	/* Chip info struct */
++	char *vars;		/* Variables (from CIS and/or other) */
++	uint varsz;		/* Size of variables buffer */
++
++	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
++
++	u32 hostintmask;	/* Copy of Host Interrupt Mask */
++	u32 intstatus;	/* Intstatus bits (events) pending */
++	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
++	bool fcstate;		/* State of dongle flow-control */
++
++	uint blocksize;		/* Block size of SDIO transfers */
++	uint roundup;		/* Max roundup limit */
++
++	struct pktq txq;	/* Queue length used for flow-control */
++	u8 flowcontrol;	/* per prio flow control bitmask */
++	u8 tx_seq;		/* Transmit sequence number (next) */
++	u8 tx_max;		/* Maximum transmit sequence allowed */
++
++	u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
++	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
++	u16 nextlen;		/* Next Read Len from last header */
++	u8 rx_seq;		/* Receive sequence number (expected) */
++	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
++
++	uint rxbound;		/* Rx frames to read before resched */
++	uint txbound;		/* Tx frames to send before resched */
++	uint txminmax;
++
++	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
++	struct sk_buff_head glom; /* Packet list for glommed superframe */
++	uint glomerr;		/* Glom packet read errors */
++
++	u8 *rxbuf;		/* Buffer for receiving control packets */
++	uint rxblen;		/* Allocated length of rxbuf */
++	u8 *rxctl;		/* Aligned pointer into rxbuf */
++	u8 *databuf;		/* Buffer for receiving big glom packet */
++	u8 *dataptr;		/* Aligned pointer into databuf */
++	uint rxlen;		/* Length of valid data in buffer */
++
++	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
++
++	bool intr;		/* Use interrupts */
++	bool poll;		/* Use polling */
++	bool ipend;		/* Device interrupt is pending */
++	uint intrcount;		/* Count of device interrupt callbacks */
++	uint lastintrs;		/* Count as of last watchdog timer */
++	uint spurious;		/* Count of spurious interrupts */
++	uint pollrate;		/* Ticks between device polls */
++	uint polltick;		/* Tick counter */
++	uint pollcnt;		/* Count of active polls */
++
++#ifdef DEBUG
++	uint console_interval;
++	struct brcmf_console console;	/* Console output polling support */
++	uint console_addr;	/* Console address from shared struct */
++#endif				/* DEBUG */
++
++	uint regfails;		/* Count of R_REG failures */
++
++	uint clkstate;		/* State of sd and backplane clock(s) */
++	bool activity;		/* Activity flag for clock down */
++	s32 idletime;		/* Control for activity timeout */
++	s32 idlecount;	/* Activity timeout counter */
++	s32 idleclock;	/* How to set bus driver when idle */
++	s32 sd_rxchain;
++	bool use_rxchain;	/* If brcmf should use PKT chains */
++	bool sleeping;		/* Is SDIO bus sleeping? */
++	bool rxflow_mode;	/* Rx flow control mode */
++	bool rxflow;		/* Is rx flow control on */
++	bool alp_only;		/* Don't use HT clock (ALP only) */
++/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
++	bool usebufpool;
++
++	/* Some additional counters */
++	uint tx_sderrs;		/* Count of tx attempts with sd errors */
++	uint fcqueued;		/* Tx packets that got queued */
++	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
++	uint rx_toolong;	/* Receive frames too long to receive */
++	uint rxc_errors;	/* SDIO errors when reading control frames */
++	uint rx_hdrfail;	/* SDIO errors on header reads */
++	uint rx_badhdr;		/* Bad received headers (roosync?) */
++	uint rx_badseq;		/* Mismatched rx sequence number */
++	uint fc_rcvd;		/* Number of flow-control events received */
++	uint fc_xoff;		/* Number which turned on flow-control */
++	uint fc_xon;		/* Number which turned off flow-control */
++	uint rxglomfail;	/* Failed deglom attempts */
++	uint rxglomframes;	/* Number of glom frames (superframes) */
++	uint rxglompkts;	/* Number of packets from glom frames */
++	uint f2rxhdrs;		/* Number of header reads */
++	uint f2rxdata;		/* Number of frame data reads */
++	uint f2txdata;		/* Number of f2 frame writes */
++	uint f1regdata;		/* Number of f1 register accesses */
++	uint tickcnt;		/* Number of watchdog been schedule */
++	unsigned long tx_ctlerrs;	/* Err of sending ctrl frames */
++	unsigned long tx_ctlpkts;	/* Ctrl frames sent to dongle */
++	unsigned long rx_ctlerrs;	/* Err of processing rx ctrl frames */
++	unsigned long rx_ctlpkts;	/* Ctrl frames processed from dongle */
++	unsigned long rx_readahead_cnt;	/* Number of packets where header
++					 * read-ahead was used. */
++
++	u8 *ctrl_frame_buf;
++	u32 ctrl_frame_len;
++	bool ctrl_frame_stat;
++
++	spinlock_t txqlock;
++	wait_queue_head_t ctrl_wait;
++	wait_queue_head_t dcmd_resp_wait;
++
++	struct timer_list timer;
++	struct completion watchdog_wait;
++	struct task_struct *watchdog_tsk;
++	bool wd_timer_valid;
++	uint save_ms;
++
++	struct task_struct *dpc_tsk;
++	struct completion dpc_wait;
++	struct list_head dpc_tsklst;
++	spinlock_t dpc_tl_lock;
++
++	struct semaphore sdsem;
++
++	const struct firmware *firmware;
++	u32 fw_ptr;
++
++	bool txoff;		/* Transmit flow-controlled */
++};
++
++/* clkstate */
++#define CLK_NONE	0
++#define CLK_SDONLY	1
++#define CLK_PENDING	2	/* Not used yet */
++#define CLK_AVAIL	3
++
++#ifdef DEBUG
++static int qcount[NUMPRIO];
++static int tx_packets[NUMPRIO];
++#endif				/* DEBUG */
++
++#define SDIO_DRIVE_STRENGTH	6	/* in milliamps */
++
++#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
++
++/* Retry count for register access failures */
++static const uint retry_limit = 2;
++
++/* Limit on rounding up frames */
++static const uint max_roundup = 512;
++
++#define ALIGNMENT  4
++
++static void pkt_align(struct sk_buff *p, int len, int align)
++{
++	uint datalign;
++	datalign = (unsigned long)(p->data);
++	datalign = roundup(datalign, (align)) - datalign;
++	if (datalign)
++		skb_pull(p, datalign);
++	__skb_trim(p, len);
++}
++
++/* To check if there's window offered */
++static bool data_ok(struct brcmf_sdio *bus)
++{
++	return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
++	       ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
++}
++
++/*
++ * Reads a register in the SDIO hardware block. This block occupies a series of
++ * adresses on the 32 bit backplane bus.
++ */
++static int
++r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	*regvar = brcmf_sdio_regrl(bus->sdiodev,
++				   bus->ci->c_inf[idx].base + offset, &ret);
++
++	return ret;
++}
++
++static int
++w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	brcmf_sdio_regwl(bus->sdiodev,
++			 bus->ci->c_inf[idx].base + reg_offset,
++			 regval, &ret);
++
++	return ret;
++}
++
++#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
++
++#define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
++
++/* Packet free applicable unconditionally for sdio and sdspi.
++ * Conditional if bufpool was present for gspi bus.
++ */
++static void brcmf_sdbrcm_pktfree2(struct brcmf_sdio *bus, struct sk_buff *pkt)
++{
++	if (bus->usebufpool)
++		brcmu_pkt_buf_free_skb(pkt);
++}
++
++/* Turn backplane clock on or off */
++static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
++{
++	int err;
++	u8 clkctl, clkreq, devctl;
++	unsigned long timeout;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	clkctl = 0;
++
++	if (on) {
++		/* Request HT Avail */
++		clkreq =
++		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Check current status */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Go to pending and await interrupt if appropriate */
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
++			/* Allow only clock-available interrupt */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
++					  err);
++				return -EBADE;
++			}
++
++			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
++			bus->clkstate = CLK_PENDING;
++
++			return 0;
++		} else if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		/* Otherwise, wait here (polling) for HT Avail */
++		timeout = jiffies +
++			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
++		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			clkctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_FUNC1_CHIPCLKCSR,
++						  &err);
++			if (time_after(jiffies, timeout))
++				break;
++			else
++				usleep_range(5000, 10000);
++		}
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n",
++				  PMU_MAX_TRANSITION_DLY, clkctl);
++			return -EBADE;
++		}
++
++		/* Mark clock available */
++		bus->clkstate = CLK_AVAIL;
++		brcmf_dbg(INFO, "CLKCTL: turned ON\n");
++
++#if defined(DEBUG)
++		if (!bus->alp_only) {
++			if (SBSDIO_ALPONLY(clkctl))
++				brcmf_dbg(ERROR, "HT Clock should be on\n");
++		}
++#endif				/* defined (DEBUG) */
++
++		bus->activity = true;
++	} else {
++		clkreq = 0;
++
++		if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		bus->clkstate = CLK_SDONLY;
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
++		if (err) {
++			brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
++				  err);
++			return -EBADE;
++		}
++	}
++	return 0;
++}
++
++/* Change idle/active SD state */
++static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (on)
++		bus->clkstate = CLK_SDONLY;
++	else
++		bus->clkstate = CLK_NONE;
++
++	return 0;
++}
++
++/* Transition SD and backplane clock readiness */
++static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
++{
++#ifdef DEBUG
++	uint oldstate = bus->clkstate;
++#endif				/* DEBUG */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Early exit if we're already there */
++	if (bus->clkstate == target) {
++		if (target == CLK_AVAIL) {
++			brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			bus->activity = true;
++		}
++		return 0;
++	}
++
++	switch (target) {
++	case CLK_AVAIL:
++		/* Make sure SD clock is available */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		/* Now request HT Avail on the backplane */
++		brcmf_sdbrcm_htclk(bus, true, pendok);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		bus->activity = true;
++		break;
++
++	case CLK_SDONLY:
++		/* Remove HT request, or bring up SD clock */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		else if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		else
++			brcmf_dbg(ERROR, "request for %d -> %d\n",
++				  bus->clkstate, target);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		break;
++
++	case CLK_NONE:
++		/* Make sure to remove HT request */
++		if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		/* Now remove the SD clock */
++		brcmf_sdbrcm_sdclk(bus, false);
++		brcmf_sdbrcm_wd_timer(bus, 0);
++		break;
++	}
++#ifdef DEBUG
++	brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
++{
++	int ret;
++
++	brcmf_dbg(INFO, "request %s (currently %s)\n",
++		  sleep ? "SLEEP" : "WAKE",
++		  bus->sleeping ? "SLEEP" : "WAKE");
++
++	/* Done if we're already in the requested state */
++	if (sleep == bus->sleeping)
++		return 0;
++
++	/* Going to sleep: set the alarm and turn off the lights... */
++	if (sleep) {
++		/* Don't sleep if something is pending */
++		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
++			return -EBUSY;
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Tell device to start using OOB wakeup */
++		ret = w_sdreg32(bus, SMB_USE_OOB,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
++
++		/* Turn off our contribution to the HT clock request */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
++
++		/* Isolate the bus */
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++				 SBSDIO_DEVCTL_PADS_ISO, NULL);
++
++		/* Change state */
++		bus->sleeping = true;
++
++	} else {
++		/* Waking up: bus power up is ok, set local state */
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 0, NULL);
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Send misc interrupt to indicate OOB not needed */
++		ret = w_sdreg32(bus, 0,
++				offsetof(struct sdpcmd_regs, tosbmailboxdata));
++		if (ret == 0)
++			ret = w_sdreg32(bus, SMB_DEV_INT,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
++
++		/* Make sure we have SD bus access */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		/* Change state */
++		bus->sleeping = false;
++	}
++
++	return 0;
++}
++
++static void bus_wake(struct brcmf_sdio *bus)
++{
++	if (bus->sleeping)
++		brcmf_sdbrcm_bussleep(bus, false);
++}
++
++static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
++{
++	u32 intstatus = 0;
++	u32 hmb_data;
++	u8 fcbits;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Read mailbox data and ack that we did so */
++	ret = r_sdreg32(bus, &hmb_data,
++			offsetof(struct sdpcmd_regs, tohostmailboxdata));
++
++	if (ret == 0)
++		w_sdreg32(bus, SMB_INT_ACK,
++			  offsetof(struct sdpcmd_regs, tosbmailbox));
++	bus->f1regdata += 2;
++
++	/* Dongle recomposed rx frames, accept them again */
++	if (hmb_data & HMB_DATA_NAKHANDLED) {
++		brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n",
++			  bus->rx_seq);
++		if (!bus->rxskip)
++			brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n");
++
++		bus->rxskip = false;
++		intstatus |= I_HMB_FRAME_IND;
++	}
++
++	/*
++	 * DEVREADY does not occur with gSPI.
++	 */
++	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
++		bus->sdpcm_ver =
++		    (hmb_data & HMB_DATA_VERSION_MASK) >>
++		    HMB_DATA_VERSION_SHIFT;
++		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
++			brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, "
++				  "expecting %d\n",
++				  bus->sdpcm_ver, SDPCM_PROT_VERSION);
++		else
++			brcmf_dbg(INFO, "Dongle ready, protocol version %d\n",
++				  bus->sdpcm_ver);
++	}
++
++	/*
++	 * Flow Control has been moved into the RX headers and this out of band
++	 * method isn't used any more.
++	 * remaining backward compatible with older dongles.
++	 */
++	if (hmb_data & HMB_DATA_FC) {
++		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
++							HMB_DATA_FCDATA_SHIFT;
++
++		if (fcbits & ~bus->flowcontrol)
++			bus->fc_xoff++;
++
++		if (bus->flowcontrol & ~fcbits)
++			bus->fc_xon++;
++
++		bus->fc_rcvd++;
++		bus->flowcontrol = fcbits;
++	}
++
++	/* Shouldn't be any others */
++	if (hmb_data & ~(HMB_DATA_DEVREADY |
++			 HMB_DATA_NAKHANDLED |
++			 HMB_DATA_FC |
++			 HMB_DATA_FWREADY |
++			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
++		brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n",
++			  hmb_data);
++
++	return intstatus;
++}
++
++static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
++{
++	uint retries = 0;
++	u16 lastrbc;
++	u8 hi, lo;
++	int err;
++
++	brcmf_dbg(ERROR, "%sterminate frame%s\n",
++		  abort ? "abort command, " : "",
++		  rtx ? ", send NAK" : "");
++
++	if (abort)
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++			 SFC_RF_TERM, &err);
++	bus->f1regdata++;
++
++	/* Wait until the packet has been flushed (device/FIFO stable) */
++	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
++		hi = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCHI, &err);
++		lo = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCLO, &err);
++		bus->f1regdata += 2;
++
++		if ((hi == 0) && (lo == 0))
++			break;
++
++		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
++			brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n",
++				  lastrbc, (hi << 8) + lo);
++		}
++		lastrbc = (hi << 8) + lo;
++	}
++
++	if (!retries)
++		brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc);
++	else
++		brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
++
++	if (rtx) {
++		bus->rxrtx++;
++		err = w_sdreg32(bus, SMB_NAK,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		bus->f1regdata++;
++		if (err == 0)
++			bus->rxskip = true;
++	}
++
++	/* Clear partial in any case */
++	bus->nextlen = 0;
++
++	/* If we can't reach the device, signal failure */
++	if (err)
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++}
++
++/* copy a buffer into a pkt buffer chain */
++static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len)
++{
++	uint n, ret = 0;
++	struct sk_buff *p;
++	u8 *buf;
++
++	buf = bus->dataptr;
++
++	/* copy the data */
++	skb_queue_walk(&bus->glom, p) {
++		n = min_t(uint, p->len, len);
++		memcpy(p->data, buf, n);
++		buf += n;
++		len -= n;
++		ret += n;
++		if (!len)
++			break;
++	}
++
++	return ret;
++}
++
++/* return total length of buffer chain */
++static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
++{
++	struct sk_buff *p;
++	uint total;
++
++	total = 0;
++	skb_queue_walk(&bus->glom, p)
++		total += p->len;
++	return total;
++}
++
++static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
++{
++	struct sk_buff *cur, *next;
++
++	skb_queue_walk_safe(&bus->glom, cur, next) {
++		skb_unlink(cur, &bus->glom);
++		brcmu_pkt_buf_free_skb(cur);
++	}
++}
++
++static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
++{
++	u16 dlen, totlen;
++	u8 *dptr, num = 0;
++
++	u16 sublen, check;
++	struct sk_buff *pfirst, *pnext;
++
++	int errcode;
++	u8 chan, seq, doff, sfdoff;
++	u8 txmax;
++
++	int ifidx = 0;
++	bool usechain = bus->use_rxchain;
++
++	/* If packets, issue read(s) and send up packet chain */
++	/* Return sequence numbers consumed? */
++
++	brcmf_dbg(TRACE, "start: glomd %p glom %p\n",
++		  bus->glomd, skb_peek(&bus->glom));
++
++	/* If there's a descriptor, generate the packet chain */
++	if (bus->glomd) {
++		pfirst = pnext = NULL;
++		dlen = (u16) (bus->glomd->len);
++		dptr = bus->glomd->data;
++		if (!dlen || (dlen & 1)) {
++			brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n",
++				  dlen);
++			dlen = 0;
++		}
++
++		for (totlen = num = 0; dlen; num++) {
++			/* Get (and move past) next length */
++			sublen = get_unaligned_le16(dptr);
++			dlen -= sizeof(u16);
++			dptr += sizeof(u16);
++			if ((sublen < SDPCM_HDRLEN) ||
++			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
++				brcmf_dbg(ERROR, "descriptor len %d bad: %d\n",
++					  num, sublen);
++				pnext = NULL;
++				break;
++			}
++			if (sublen % BRCMF_SDALIGN) {
++				brcmf_dbg(ERROR, "sublen %d not multiple of %d\n",
++					  sublen, BRCMF_SDALIGN);
++				usechain = false;
++			}
++			totlen += sublen;
++
++			/* For last frame, adjust read len so total
++				 is a block multiple */
++			if (!dlen) {
++				sublen +=
++				    (roundup(totlen, bus->blocksize) - totlen);
++				totlen = roundup(totlen, bus->blocksize);
++			}
++
++			/* Allocate/chain packet for next subframe */
++			pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
++			if (pnext == NULL) {
++				brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n",
++					  num, sublen);
++				break;
++			}
++			skb_queue_tail(&bus->glom, pnext);
++
++			/* Adhere to start alignment requirements */
++			pkt_align(pnext, sublen, BRCMF_SDALIGN);
++		}
++
++		/* If all allocations succeeded, save packet chain
++			 in bus structure */
++		if (pnext) {
++			brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
++				  totlen, num);
++			if (BRCMF_GLOM_ON() && bus->nextlen &&
++			    totlen != bus->nextlen) {
++				brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
++					  bus->nextlen, totlen, rxseq);
++			}
++			pfirst = pnext = NULL;
++		} else {
++			brcmf_sdbrcm_free_glom(bus);
++			num = 0;
++		}
++
++		/* Done with descriptor packet */
++		brcmu_pkt_buf_free_skb(bus->glomd);
++		bus->glomd = NULL;
++		bus->nextlen = 0;
++	}
++
++	/* Ok -- either we just generated a packet chain,
++		 or had one from before */
++	if (!skb_queue_empty(&bus->glom)) {
++		if (BRCMF_GLOM_ON()) {
++			brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
++			skb_queue_walk(&bus->glom, pnext) {
++				brcmf_dbg(GLOM, "    %p: %p len 0x%04x (%d)\n",
++					  pnext, (u8 *) (pnext->data),
++					  pnext->len, pnext->len);
++			}
++		}
++
++		pfirst = skb_peek(&bus->glom);
++		dlen = (u16) brcmf_sdbrcm_glom_len(bus);
++
++		/* Do an SDIO read for the superframe.  Configurable iovar to
++		 * read directly into the chained packet, or allocate a large
++		 * packet and and copy into the chain.
++		 */
++		if (usechain) {
++			errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC, &bus->glom);
++		} else if (bus->dataptr) {
++			errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC,
++					bus->dataptr, dlen);
++			sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
++			if (sublen != dlen) {
++				brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n",
++					  dlen, sublen);
++				errcode = -1;
++			}
++			pnext = NULL;
++		} else {
++			brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
++				  dlen);
++			errcode = -1;
++		}
++		bus->f2rxdata++;
++
++		/* On failure, kill the superframe, allow a couple retries */
++		if (errcode < 0) {
++			brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n",
++				  dlen, errcode);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++
++			if (bus->glomerr++ < 3) {
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			return 0;
++		}
++
++		brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++				   pfirst->data, min_t(int, pfirst->len, 48),
++				   "SUPERFRAME:\n");
++
++		/* Validate the superframe header */
++		dptr = (u8 *) (pfirst->data);
++		sublen = get_unaligned_le16(dptr);
++		check = get_unaligned_le16(dptr + sizeof(u16));
++
++		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++		errcode = 0;
++		if ((u16)~(sublen ^ check)) {
++			brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
++				  sublen, check);
++			errcode = -1;
++		} else if (roundup(sublen, bus->blocksize) != dlen) {
++			brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
++				  sublen, roundup(sublen, bus->blocksize),
++				  dlen);
++			errcode = -1;
++		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
++			   SDPCM_GLOM_CHANNEL) {
++			brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
++				  SDPCM_PACKET_CHANNEL(
++					  &dptr[SDPCM_FRAMETAG_LEN]));
++			errcode = -1;
++		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
++			brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
++			errcode = -1;
++		} else if ((doff < SDPCM_HDRLEN) ||
++			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
++			brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
++				  doff, sublen, pfirst->len, SDPCM_HDRLEN);
++			errcode = -1;
++		}
++
++		/* Check sequence number of superframe SW header */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
++				  seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Remove superframe header, remember offset */
++		skb_pull(pfirst, doff);
++		sfdoff = doff;
++		num = 0;
++
++		/* Validate all the subframe headers */
++		skb_queue_walk(&bus->glom, pnext) {
++			/* leave when invalid subframe is found */
++			if (errcode)
++				break;
++
++			dptr = (u8 *) (pnext->data);
++			dlen = (u16) (pnext->len);
++			sublen = get_unaligned_le16(dptr);
++			check = get_unaligned_le16(dptr + sizeof(u16));
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   dptr, 32, "subframe:\n");
++
++			if ((u16)~(sublen ^ check)) {
++				brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
++					  num, sublen, check);
++				errcode = -1;
++			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
++				brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
++					  num, sublen, dlen);
++				errcode = -1;
++			} else if ((chan != SDPCM_DATA_CHANNEL) &&
++				   (chan != SDPCM_EVENT_CHANNEL)) {
++				brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
++					  num, chan);
++				errcode = -1;
++			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
++				brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
++					  num, doff, sublen, SDPCM_HDRLEN);
++				errcode = -1;
++			}
++			/* increase the subframe count */
++			num++;
++		}
++
++		if (errcode) {
++			/* Terminate frame on error, request
++				 a couple retries */
++			if (bus->glomerr++ < 3) {
++				/* Restore superframe header space */
++				skb_push(pfirst, sfdoff);
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			bus->nextlen = 0;
++			return 0;
++		}
++
++		/* Basic SD framing looks ok - process each packet (header) */
++
++		skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
++			dptr = (u8 *) (pfirst->data);
++			sublen = get_unaligned_le16(dptr);
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++			brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
++				  num, pfirst, pfirst->data,
++				  pfirst->len, sublen, chan, seq);
++
++			/* precondition: chan == SDPCM_DATA_CHANNEL ||
++					 chan == SDPCM_EVENT_CHANNEL */
++
++			if (rxseq != seq) {
++				brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++			rxseq++;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   dptr, dlen, "Rx Subframe Data:\n");
++
++			__skb_trim(pfirst, sublen);
++			skb_pull(pfirst, doff);
++
++			if (pfirst->len == 0) {
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			} else if (brcmf_proto_hdrpull(bus->sdiodev->dev,
++						       &ifidx, pfirst) != 0) {
++				brcmf_dbg(ERROR, "rx protocol error\n");
++				bus->sdiodev->bus_if->dstats.rx_errors++;
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			}
++
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   pfirst->data,
++					   min_t(int, pfirst->len, 32),
++					   "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
++					   bus->glom.qlen, pfirst, pfirst->data,
++					   pfirst->len, pfirst->next,
++					   pfirst->prev);
++		}
++		/* sent any remaining packets up */
++		if (bus->glom.qlen) {
++			up(&bus->sdsem);
++			brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
++			down(&bus->sdsem);
++		}
++
++		bus->rxglomframes++;
++		bus->rxglompkts += bus->glom.qlen;
++	}
++	return num;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
++					bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
++
++	/* Wait until control frame is available */
++	add_wait_queue(&bus->dcmd_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	while (!(*condition) && (!signal_pending(current) && timeout))
++		timeout = schedule_timeout(timeout);
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&bus->dcmd_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->dcmd_resp_wait))
++		wake_up_interruptible(&bus->dcmd_resp_wait);
++
++	return 0;
++}
++static void
++brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
++{
++	uint rdlen, pad;
++
++	int sdret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Set rxctl for frame (w/optional alignment) */
++	bus->rxctl = bus->rxbuf;
++	bus->rxctl += BRCMF_FIRSTREAD;
++	pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
++	if (pad)
++		bus->rxctl += (BRCMF_SDALIGN - pad);
++	bus->rxctl -= BRCMF_FIRSTREAD;
++
++	/* Copy the already-read portion over */
++	memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
++	if (len <= BRCMF_FIRSTREAD)
++		goto gotpkt;
++
++	/* Raise rdlen to next SDIO block to avoid tail command */
++	rdlen = len - BRCMF_FIRSTREAD;
++	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
++		pad = bus->blocksize - (rdlen % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++		    ((len + pad) < bus->sdiodev->bus_if->maxctl))
++			rdlen += pad;
++	} else if (rdlen % BRCMF_SDALIGN) {
++		rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (rdlen & (ALIGNMENT - 1))
++		rdlen = roundup(rdlen, ALIGNMENT);
++
++	/* Drop if the read is too big or it exceeds our maximum */
++	if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n",
++			  rdlen, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
++			  len, len - doff, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		bus->rx_toolong++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	/* Read remainder of frame body into the rxctl buffer */
++	sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
++				bus->sdiodev->sbwad,
++				SDIO_FUNC_2,
++				F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen);
++	bus->f2rxdata++;
++
++	/* Control frame failures need retransmission */
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
++			  rdlen, sdret);
++		bus->rxc_errors++;
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto done;
++	}
++
++gotpkt:
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++			   bus->rxctl, len, "RxCtrl:\n");
++
++	/* Point to valid data and indicate its length */
++	bus->rxctl += doff;
++	bus->rxlen = len - doff;
++
++done:
++	/* Awake any waiters */
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++}
++
++/* Pad read to blocksize for efficiency */
++static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
++{
++	if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
++		*pad = bus->blocksize - (*rdlen % bus->blocksize);
++		if (*pad <= bus->roundup && *pad < bus->blocksize &&
++		    *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
++			*rdlen += *pad;
++	} else if (*rdlen % BRCMF_SDALIGN) {
++		*rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
++	}
++}
++
++static void
++brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen,
++			 struct sk_buff **pkt, u8 **rxbuf)
++{
++	int sdret;		/* Return code from calls */
++
++	*pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
++	if (*pkt == NULL)
++		return;
++
++	pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
++	*rxbuf = (u8 *) ((*pkt)->data);
++	/* Read the entire frame */
++	sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				      SDIO_FUNC_2, F2SYNC, *pkt);
++	bus->f2rxdata++;
++
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
++			  rdlen, sdret);
++		brcmu_pkt_buf_free_skb(*pkt);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		/* Force retry w/normal header read.
++		 * Don't attempt NAK for
++		 * gSPI
++		 */
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		*pkt = NULL;
++	}
++}
++
++/* Checks the header */
++static int
++brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf,
++		  u8 rxseq, u16 nextlen, u16 *len)
++{
++	u16 check;
++	bool len_consistent;	/* Result of comparing readahead len and
++				   len from hw-hdr */
++
++	memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
++
++	/* Extract hardware header fields */
++	*len = get_unaligned_le16(bus->rxhdr);
++	check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++	/* All zeros means readahead info was bad */
++	if (!(*len | check)) {
++		brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
++		goto fail;
++	}
++
++	/* Validate check bytes */
++	if ((u16)~(*len ^ check)) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
++			  nextlen, *len, check);
++		bus->rx_badhdr++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto fail;
++	}
++
++	/* Validate frame length */
++	if (*len < SDPCM_HDRLEN) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
++			  *len);
++		goto fail;
++	}
++
++	/* Check for consistency with readahead info */
++	len_consistent = (nextlen != (roundup(*len, 16) >> 4));
++	if (len_consistent) {
++		/* Mismatch, force retry w/normal
++			header (may be >4K) */
++		brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
++			  nextlen, *len, roundup(*len, 16),
++			  rxseq);
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto fail;
++	}
++
++	return 0;
++
++fail:
++	brcmf_sdbrcm_pktfree2(bus, pkt);
++	return -EINVAL;
++}
++
++/* Return true if there may be more frames to read */
++static uint
++brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
++{
++	u16 len, check;	/* Extracted hardware header fields */
++	u8 chan, seq, doff;	/* Extracted software header fields */
++	u8 fcbits;		/* Extracted fcbits from software header */
++
++	struct sk_buff *pkt;		/* Packet for event or data frames */
++	u16 pad;		/* Number of pad bytes to read */
++	u16 rdlen;		/* Total number of bytes to read */
++	u8 rxseq;		/* Next sequence number to expect */
++	uint rxleft = 0;	/* Remaining number of frames allowed */
++	int sdret;		/* Return code from calls */
++	u8 txmax;		/* Maximum tx sequence offered */
++	u8 *rxbuf;
++	int ifidx = 0;
++	uint rxcount = 0;	/* Total frames read */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Not finished unless we encounter no more frames indication */
++	*finished = false;
++
++	for (rxseq = bus->rx_seq, rxleft = maxframes;
++	     !bus->rxskip && rxleft &&
++	     bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
++	     rxseq++, rxleft--) {
++
++		/* Handle glomming separately */
++		if (bus->glomd || !skb_queue_empty(&bus->glom)) {
++			u8 cnt;
++			brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
++				  bus->glomd, skb_peek(&bus->glom));
++			cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
++			brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
++			rxseq += cnt - 1;
++			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
++			continue;
++		}
++
++		/* Try doing single read if we can */
++		if (bus->nextlen) {
++			u16 nextlen = bus->nextlen;
++			bus->nextlen = 0;
++
++			rdlen = len = nextlen << 4;
++			brcmf_pad(bus, &pad, &rdlen);
++
++			/*
++			 * After the frame is received we have to
++			 * distinguish whether it is data
++			 * or non-data frame.
++			 */
++			brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf);
++			if (pkt == NULL) {
++				/* Give up on data, request rtx of events */
++				brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
++					  len, rdlen, rxseq);
++				continue;
++			}
++
++			if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
++					      &len) < 0)
++				continue;
++
++			/* Extract software header fields */
++			chan = SDPCM_PACKET_CHANNEL(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			txmax = SDPCM_WINDOW_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			bus->nextlen =
++			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
++				       SDPCM_NEXTLEN_OFFSET];
++			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++				brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++					  bus->nextlen, seq);
++				bus->nextlen = 0;
++			}
++
++			bus->rx_readahead_cnt++;
++
++			/* Handle Flow Control */
++			fcbits = SDPCM_FCMASK_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			if (bus->flowcontrol != fcbits) {
++				if (~bus->flowcontrol & fcbits)
++					bus->fc_xoff++;
++
++				if (bus->flowcontrol & ~fcbits)
++					bus->fc_xon++;
++
++				bus->fc_rcvd++;
++				bus->flowcontrol = fcbits;
++			}
++
++			/* Check and update sequence number */
++			if (rxseq != seq) {
++				brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++
++			/* Check window for sanity */
++			if ((u8) (txmax - bus->tx_seq) > 0x40) {
++				brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
++					  txmax, bus->tx_seq);
++				txmax = bus->tx_seq + 2;
++			}
++			bus->tx_max = txmax;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   rxbuf, len, "Rx Data:\n");
++			brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++					     BRCMF_DATA_ON()) &&
++					   BRCMF_HDRS_ON(),
++					   bus->rxhdr, SDPCM_HDRLEN,
++					   "RxHdr:\n");
++
++			if (chan == SDPCM_CONTROL_CHANNEL) {
++				brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
++					  seq);
++				/* Force retry w/normal header read */
++				bus->nextlen = 0;
++				brcmf_sdbrcm_rxfail(bus, false, true);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* Validate data offset */
++			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++				brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n",
++					  doff, len, SDPCM_HDRLEN);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* All done with this one -- now deliver the packet */
++			goto deliver;
++		}
++
++		/* Read frame header (hardware and software) */
++		sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, bus->rxhdr,
++					      BRCMF_FIRSTREAD);
++		bus->f2rxhdrs++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
++			bus->rx_hdrfail++;
++			brcmf_sdbrcm_rxfail(bus, true, true);
++			continue;
++		}
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
++				   bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
++
++
++		/* Extract hardware header fields */
++		len = get_unaligned_le16(bus->rxhdr);
++		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++		/* All zeros means no more frames */
++		if (!(len | check)) {
++			*finished = true;
++			break;
++		}
++
++		/* Validate check bytes */
++		if ((u16) ~(len ^ check)) {
++			brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
++				  len, check);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Validate frame length */
++		if (len < SDPCM_HDRLEN) {
++			brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
++			continue;
++		}
++
++		/* Extract software header fields */
++		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		/* Validate data offset */
++		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++			brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
++				  doff, len, SDPCM_HDRLEN, seq);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Save the readahead length if there is one */
++		bus->nextlen =
++		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++
++		/* Handle Flow Control */
++		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		if (bus->flowcontrol != fcbits) {
++			if (~bus->flowcontrol & fcbits)
++				bus->fc_xoff++;
++
++			if (bus->flowcontrol & ~fcbits)
++				bus->fc_xon++;
++
++			bus->fc_rcvd++;
++			bus->flowcontrol = fcbits;
++		}
++
++		/* Check and update sequence number */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Call a separate function for control frames */
++		if (chan == SDPCM_CONTROL_CHANNEL) {
++			brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
++			continue;
++		}
++
++		/* precondition: chan is either SDPCM_DATA_CHANNEL,
++		   SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
++		   SDPCM_GLOM_CHANNEL */
++
++		/* Length to read */
++		rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
++
++		/* May pad read to blocksize for efficiency */
++		if (bus->roundup && bus->blocksize &&
++			(rdlen > bus->blocksize)) {
++			pad = bus->blocksize - (rdlen % bus->blocksize);
++			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++			    ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
++				rdlen += pad;
++		} else if (rdlen % BRCMF_SDALIGN) {
++			rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++		}
++
++		/* Satisfy length-alignment requirements */
++		if (rdlen & (ALIGNMENT - 1))
++			rdlen = roundup(rdlen, ALIGNMENT);
++
++		if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
++			/* Too long -- skip this frame */
++			brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
++				  len, rdlen);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			bus->rx_toolong++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		pkt = brcmu_pkt_buf_get_skb(rdlen +
++					    BRCMF_FIRSTREAD + BRCMF_SDALIGN);
++		if (!pkt) {
++			/* Give up on data, request rtx of events */
++			brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n",
++				  rdlen, chan);
++			bus->sdiodev->bus_if->dstats.rx_dropped++;
++			brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Leave room for what we already read, and align remainder */
++		skb_pull(pkt, BRCMF_FIRSTREAD);
++		pkt_align(pkt, rdlen, BRCMF_SDALIGN);
++
++		/* Read the remaining frame data */
++		sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, pkt);
++		bus->f2rxdata++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
++				  ((chan == SDPCM_EVENT_CHANNEL) ? "event"
++				   : ((chan == SDPCM_DATA_CHANNEL) ? "data"
++				      : "test")), sdret);
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Copy the already-read portion */
++		skb_push(pkt, BRCMF_FIRSTREAD);
++		memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
++
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++				   pkt->data, len, "Rx Data:\n");
++
++deliver:
++		/* Save superframe descriptor and allocate packet frame */
++		if (chan == SDPCM_GLOM_CHANNEL) {
++			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
++				brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
++					  len);
++				brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++						   pkt->data, len,
++						   "Glom Data:\n");
++				__skb_trim(pkt, len);
++				skb_pull(pkt, SDPCM_HDRLEN);
++				bus->glomd = pkt;
++			} else {
++				brcmf_dbg(ERROR, "%s: glom superframe w/o "
++					  "descriptor!\n", __func__);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++			}
++			continue;
++		}
++
++		/* Fill in packet len and prio, deliver upward */
++		__skb_trim(pkt, len);
++		skb_pull(pkt, doff);
++
++		if (pkt->len == 0) {
++			brcmu_pkt_buf_free_skb(pkt);
++			continue;
++		} else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx,
++			   pkt) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			continue;
++		}
++
++		/* Unlock during rx call */
++		up(&bus->sdsem);
++		brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
++		down(&bus->sdsem);
++	}
++	rxcount = maxframes - rxleft;
++	/* Message if we hit the limit */
++	if (!rxleft)
++		brcmf_dbg(DATA, "hit rx limit of %d frames\n",
++			  maxframes);
++	else
++		brcmf_dbg(DATA, "processed %d frames\n", rxcount);
++	/* Back off rxseq if awaiting rtx, update rx_seq */
++	if (bus->rxskip)
++		rxseq--;
++	bus->rx_seq = rxseq;
++
++	return rxcount;
++}
++
++static void
++brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
++{
++	up(&bus->sdsem);
++	wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
++	down(&bus->sdsem);
++	return;
++}
++
++static void
++brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->ctrl_wait))
++		wake_up_interruptible(&bus->ctrl_wait);
++	return;
++}
++
++/* Writes a HW/SW header into the packet and sends it. */
++/* Assumes: (a) header space already there, (b) caller holds lock */
++static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
++			      uint chan, bool free_pkt)
++{
++	int ret;
++	u8 *frame;
++	u16 len, pad = 0;
++	u32 swheader;
++	struct sk_buff *new;
++	int i;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	frame = (u8 *) (pkt->data);
++
++	/* Add alignment padding, allocate new packet if needed */
++	pad = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (pad) {
++		if (skb_headroom(pkt) < pad) {
++			brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
++				  skb_headroom(pkt), pad);
++			bus->sdiodev->bus_if->tx_realloc++;
++			new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
++			if (!new) {
++				brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n",
++					  pkt->len + BRCMF_SDALIGN);
++				ret = -ENOMEM;
++				goto done;
++			}
++
++			pkt_align(new, pkt->len, BRCMF_SDALIGN);
++			memcpy(new->data, pkt->data, pkt->len);
++			if (free_pkt)
++				brcmu_pkt_buf_free_skb(pkt);
++			/* free the pkt if canned one is not used */
++			free_pkt = true;
++			pkt = new;
++			frame = (u8 *) (pkt->data);
++			/* precondition: (frame % BRCMF_SDALIGN) == 0) */
++			pad = 0;
++		} else {
++			skb_push(pkt, pad);
++			frame = (u8 *) (pkt->data);
++			/* precondition: pad + SDPCM_HDRLEN <= pkt->len */
++			memset(frame, 0, pad + SDPCM_HDRLEN);
++		}
++	}
++	/* precondition: pad < BRCMF_SDALIGN */
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	len = (u16) (pkt->len);
++	*(__le16 *) frame = cpu_to_le16(len);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~len);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
++	    (((pad +
++	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
++
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++#ifdef DEBUG
++	tx_packets[pkt->priority]++;
++#endif
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() &&
++			   ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
++			    (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)),
++			   frame, len, "Tx Frame:\n");
++	brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++			     ((BRCMF_CTL_ON() &&
++			       chan == SDPCM_CONTROL_CHANNEL) ||
++			      (BRCMF_DATA_ON() &&
++			       chan != SDPCM_CONTROL_CHANNEL))) &&
++			   BRCMF_HDRS_ON(),
++			   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++	/* Raise len to next SDIO block to eliminate tail command */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++				len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Some controllers have trouble with odd bytes -- round to even */
++	if (len & (ALIGNMENT - 1))
++			len = roundup(len, ALIGNMENT);
++
++	ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, pkt);
++	bus->f2txdata++;
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if ((hi == 0) && (lo == 0))
++				break;
++		}
++
++	}
++	if (ret == 0)
++		bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++done:
++	/* restore pkt buffer pointer before calling tx complete routine */
++	skb_pull(pkt, SDPCM_HDRLEN + pad);
++	up(&bus->sdsem);
++	brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
++	down(&bus->sdsem);
++
++	if (free_pkt)
++		brcmu_pkt_buf_free_skb(pkt);
++
++	return ret;
++}
++
++static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
++{
++	struct sk_buff *pkt;
++	u32 intstatus = 0;
++	int ret = 0, prec_out;
++	uint cnt = 0;
++	uint datalen;
++	u8 tx_prec_map;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	tx_prec_map = ~bus->flowcontrol;
++
++	/* Send frames until the limit or some other event */
++	for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
++		spin_lock_bh(&bus->txqlock);
++		pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
++		if (pkt == NULL) {
++			spin_unlock_bh(&bus->txqlock);
++			break;
++		}
++		spin_unlock_bh(&bus->txqlock);
++		datalen = pkt->len - SDPCM_HDRLEN;
++
++		ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
++		if (ret)
++			bus->sdiodev->bus_if->dstats.tx_errors++;
++		else
++			bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
++
++		/* In poll mode, need to check for other events */
++		if (!bus->intr && cnt) {
++			/* Check device status, signal pending interrupt */
++			ret = r_sdreg32(bus, &intstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f2txdata++;
++			if (ret != 0)
++				break;
++			if (intstatus & bus->hostintmask)
++				bus->ipend = true;
++		}
++	}
++
++	/* Deflow-control stack if needed */
++	if (bus->sdiodev->bus_if->drvr_up &&
++	    (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
++	    bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
++		bus->txoff = OFF;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF);
++	}
++
++	return cnt;
++}
++
++static void brcmf_sdbrcm_bus_stop(struct device *dev)
++{
++	u32 local_hostintmask;
++	u8 saveclk;
++	int err;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->watchdog_tsk) {
++		send_sig(SIGTERM, bus->watchdog_tsk, 1);
++		kthread_stop(bus->watchdog_tsk);
++		bus->watchdog_tsk = NULL;
++	}
++
++	if (bus->dpc_tsk && bus->dpc_tsk != current) {
++		send_sig(SIGTERM, bus->dpc_tsk, 1);
++		kthread_stop(bus->dpc_tsk);
++		bus->dpc_tsk = NULL;
++	}
++
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Enable clock for device interrupts */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Disable and clear interrupts at the chip level also */
++	w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
++	local_hostintmask = bus->hostintmask;
++	bus->hostintmask = 0;
++
++	/* Change our idea of bus state */
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err)
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++
++	/* Turn off the bus (F2), free any pending packets */
++	brcmf_dbg(INTR, "disable SDIO interrupts\n");
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
++			 NULL);
++
++	/* Clear any pending interrupts now that F2 is disabled */
++	w_sdreg32(bus, local_hostintmask,
++		  offsetof(struct sdpcmd_regs, intstatus));
++
++	/* Turn off the backplane clock (only) */
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	/* Clear the data packet queues */
++	brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
++
++	/* Clear any held glomming stuff */
++	if (bus->glomd)
++		brcmu_pkt_buf_free_skb(bus->glomd);
++	brcmf_sdbrcm_free_glom(bus);
++
++	/* Clear rx control and wake any waiters */
++	bus->rxlen = 0;
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++
++	/* Reset some F2 state stuff */
++	bus->rxskip = false;
++	bus->tx_seq = bus->rx_seq = 0;
++
++	up(&bus->sdsem);
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
++	if (!bus->sdiodev->irq_en && !bus->ipend) {
++		enable_irq(bus->sdiodev->irq);
++		bus->sdiodev->irq_en = true;
++	}
++	spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags);
++}
++#else
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
++{
++	u32 intstatus, newstatus = 0;
++	uint rxlimit = bus->rxbound;	/* Rx frames to read before resched */
++	uint txlimit = bus->txbound;	/* Tx frames to send before resched */
++	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
++	bool rxdone = true;	/* Flag for no more read data */
++	bool resched = false;	/* Flag indicating resched wanted */
++	int err = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Start with leftover status bits */
++	intstatus = bus->intstatus;
++
++	down(&bus->sdsem);
++
++	/* If waiting for HTAVAIL, check status */
++	if (bus->clkstate == CLK_PENDING) {
++		u8 clkctl, devctl = 0;
++
++#ifdef DEBUG
++		/* Check for inconsistent device control */
++		devctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_DEVICE_CTL, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++#endif				/* DEBUG */
++
++		/* Read CSR, if clock on switch to AVAIL, else ignore */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading CSR: %d\n",
++				  err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++
++		brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
++			  devctl, clkctl);
++
++		if (SBSDIO_HTAV(clkctl)) {
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			bus->clkstate = CLK_AVAIL;
++		} else {
++			goto clkwait;
++		}
++	}
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
++	if (bus->clkstate == CLK_PENDING)
++		goto clkwait;
++
++	/* Pending interrupt indicates new device status */
++	if (bus->ipend) {
++		bus->ipend = false;
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata++;
++		if (err != 0)
++			newstatus = 0;
++		newstatus &= bus->hostintmask;
++		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
++		if (newstatus) {
++			err = w_sdreg32(bus, newstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f1regdata++;
++		}
++	}
++
++	/* Merge new bits with previous */
++	intstatus |= newstatus;
++	bus->intstatus = 0;
++
++	/* Handle flow-control change: read new state in case our ack
++	 * crossed another change interrupt.  If change still set, assume
++	 * FC ON for safety, let next loop through do the debounce.
++	 */
++	if (intstatus & I_HMB_FC_CHANGE) {
++		intstatus &= ~I_HMB_FC_CHANGE;
++		err = w_sdreg32(bus, I_HMB_FC_CHANGE,
++				offsetof(struct sdpcmd_regs, intstatus));
++
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata += 2;
++		bus->fcstate =
++		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
++		intstatus |= (newstatus & bus->hostintmask);
++	}
++
++	/* Handle host mailbox indication */
++	if (intstatus & I_HMB_HOST_INT) {
++		intstatus &= ~I_HMB_HOST_INT;
++		intstatus |= brcmf_sdbrcm_hostmail(bus);
++	}
++
++	/* Generally don't ask for these, can get CRC errors... */
++	if (intstatus & I_WR_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
++		intstatus &= ~I_WR_OOSYNC;
++	}
++
++	if (intstatus & I_RD_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n");
++		intstatus &= ~I_RD_OOSYNC;
++	}
++
++	if (intstatus & I_SBINT) {
++		brcmf_dbg(ERROR, "Dongle reports SBINT\n");
++		intstatus &= ~I_SBINT;
++	}
++
++	/* Would be active due to wake-wlan in gSPI */
++	if (intstatus & I_CHIPACTIVE) {
++		brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n");
++		intstatus &= ~I_CHIPACTIVE;
++	}
++
++	/* Ignore frame indications if rxskip is set */
++	if (bus->rxskip)
++		intstatus &= ~I_HMB_FRAME_IND;
++
++	/* On frame indication, read available frames */
++	if (PKT_AVAILABLE()) {
++		framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
++		if (rxdone || bus->rxskip)
++			intstatus &= ~I_HMB_FRAME_IND;
++		rxlimit -= min(framecnt, rxlimit);
++	}
++
++	/* Keep still-pending events for next scheduling */
++	bus->intstatus = intstatus;
++
++clkwait:
++	brcmf_sdbrcm_clrintr(bus);
++
++	if (data_ok(bus) && bus->ctrl_frame_stat &&
++		(bus->clkstate == CLK_AVAIL)) {
++		int ret, i;
++
++		ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++			SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
++			(u32) bus->ctrl_frame_len);
++
++		if (ret < 0) {
++			/* On failure, abort the command and
++				terminate the frame */
++			brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++				  ret);
++			bus->tx_sderrs++;
++
++			brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++					 SFC_WF_TERM, &err);
++			bus->f1regdata++;
++
++			for (i = 0; i < 3; i++) {
++				u8 hi, lo;
++				hi = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCHI,
++						      &err);
++				lo = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCLO,
++						      &err);
++				bus->f1regdata += 2;
++				if ((hi == 0) && (lo == 0))
++					break;
++			}
++
++		}
++		if (ret == 0)
++			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++		brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
++		bus->ctrl_frame_stat = false;
++		brcmf_sdbrcm_wait_event_wakeup(bus);
++	}
++	/* Send queued frames (limit 1 if rx may still be pending) */
++	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
++		 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
++		 && data_ok(bus)) {
++		framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax);
++		framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
++		txlimit -= framecnt;
++	}
++
++	/* Resched if events or tx frames are pending,
++		 else await next interrupt */
++	/* On failed register access, all bets are off:
++		 no resched or interrupts */
++	if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
++		brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		bus->intstatus = 0;
++	} else if (bus->clkstate == CLK_PENDING) {
++		brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n");
++		resched = true;
++	} else if (bus->intstatus || bus->ipend ||
++		(!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
++		 && data_ok(bus)) || PKT_AVAILABLE()) {
++		resched = true;
++	}
++
++	bus->dpc_sched = resched;
++
++	/* If we're done for now, turn off clock request. */
++	if ((bus->clkstate != CLK_PENDING)
++	    && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++	}
++
++	up(&bus->sdsem);
++
++	return resched;
++}
++
++static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
++{
++	struct list_head *new_hd;
++	unsigned long flags;
++
++	if (in_interrupt())
++		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
++	else
++		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
++	if (new_hd == NULL)
++		return;
++
++	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++	list_add_tail(new_hd, &bus->dpc_tsklst);
++	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++}
++
++static int brcmf_sdbrcm_dpc_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
++	struct list_head *cur_hd, *tmp_hd;
++	unsigned long flags;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++
++		if (list_empty(&bus->dpc_tsklst))
++			if (wait_for_completion_interruptible(&bus->dpc_wait))
++				break;
++
++		spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++		list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
++			spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++
++			if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++				/* after stopping the bus, exit thread */
++				brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
++				bus->dpc_tsk = NULL;
++				spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++				break;
++			}
++
++			if (brcmf_sdbrcm_dpc(bus))
++				brcmf_sdbrcm_adddpctsk(bus);
++
++			spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++			list_del(cur_hd);
++			kfree(cur_hd);
++		}
++		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++	}
++	return 0;
++}
++
++static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
++{
++	int ret = -EBADE;
++	uint datalen, prec;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	datalen = pkt->len;
++
++	/* Add space for the header */
++	skb_push(pkt, SDPCM_HDRLEN);
++	/* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
++
++	prec = prio2prec((pkt->priority & PRIOMASK));
++
++	/* Check for existing queue, current flow-control,
++			 pending event, or pending clock */
++	brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
++	bus->fcqueued++;
++
++	/* Priority based enq */
++	spin_lock_bh(&bus->txqlock);
++	if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
++		skb_pull(pkt, SDPCM_HDRLEN);
++		brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
++		brcmu_pkt_buf_free_skb(pkt);
++		brcmf_dbg(ERROR, "out of bus->txq !!!\n");
++		ret = -ENOSR;
++	} else {
++		ret = 0;
++	}
++	spin_unlock_bh(&bus->txqlock);
++
++	if (pktq_len(&bus->txq) >= TXHI) {
++		bus->txoff = ON;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
++	}
++
++#ifdef DEBUG
++	if (pktq_plen(&bus->txq, prec) > qcount[prec])
++		qcount[prec] = pktq_plen(&bus->txq, prec);
++#endif
++	/* Schedule DPC if needed to send queued packet(s) */
++	if (!bus->dpc_sched) {
++		bus->dpc_sched = true;
++		if (bus->dpc_tsk) {
++			brcmf_sdbrcm_adddpctsk(bus);
++			complete(&bus->dpc_wait);
++		}
++	}
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
++		 uint size)
++{
++	int bcmerror = 0;
++	u32 sdaddr;
++	uint dsize;
++
++	/* Determine initial transfer parameters */
++	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
++	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
++		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
++	else
++		dsize = size;
++
++	/* Set the backplane window to include the start address */
++	bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
++	if (bcmerror) {
++		brcmf_dbg(ERROR, "window change failed\n");
++		goto xfer_done;
++	}
++
++	/* Do the transfer(s) */
++	while (size) {
++		brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
++			  write ? "write" : "read", dsize,
++			  sdaddr, address & SBSDIO_SBWINDOW_MASK);
++		bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
++					       sdaddr, data, dsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "membytes transfer failed\n");
++			break;
++		}
++
++		/* Adjust for next transfer (if any) */
++		size -= dsize;
++		if (size) {
++			data += dsize;
++			address += dsize;
++			bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
++								  address);
++			if (bcmerror) {
++				brcmf_dbg(ERROR, "window change failed\n");
++				break;
++			}
++			sdaddr = 0;
++			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
++		}
++	}
++
++xfer_done:
++	/* Return the window to backplane enumeration space for core access */
++	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
++		brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
++			  bus->sdiodev->sbwad);
++
++	return bcmerror;
++}
++
++#ifdef DEBUG
++#define CONSOLE_LINE_MAX	192
++
++static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
++{
++	struct brcmf_console *c = &bus->console;
++	u8 line[CONSOLE_LINE_MAX], ch;
++	u32 n, idx, addr;
++	int rv;
++
++	/* Don't do anything until FWREADY updates console address */
++	if (bus->console_addr == 0)
++		return 0;
++
++	/* Read console log struct */
++	addr = bus->console_addr + offsetof(struct rte_console, log_le);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
++				   sizeof(c->log_le));
++	if (rv < 0)
++		return rv;
++
++	/* Allocate console buffer (one time only) */
++	if (c->buf == NULL) {
++		c->bufsize = le32_to_cpu(c->log_le.buf_size);
++		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
++		if (c->buf == NULL)
++			return -ENOMEM;
++	}
++
++	idx = le32_to_cpu(c->log_le.idx);
++
++	/* Protect against corrupt value */
++	if (idx > c->bufsize)
++		return -EBADE;
++
++	/* Skip reading the console buffer if the index pointer
++	 has not moved */
++	if (idx == c->last)
++		return 0;
++
++	/* Read the console buffer */
++	addr = le32_to_cpu(c->log_le.buf);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
++	if (rv < 0)
++		return rv;
++
++	while (c->last != idx) {
++		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
++			if (c->last == idx) {
++				/* This would output a partial line.
++				 * Instead, back up
++				 * the buffer pointer and output this
++				 * line next time around.
++				 */
++				if (c->last >= n)
++					c->last -= n;
++				else
++					c->last = c->bufsize - n;
++				goto break2;
++			}
++			ch = c->buf[c->last];
++			c->last = (c->last + 1) % c->bufsize;
++			if (ch == '\n')
++				break;
++			line[n] = ch;
++		}
++
++		if (n > 0) {
++			if (line[n - 1] == '\r')
++				n--;
++			line[n] = 0;
++			pr_debug("CONSOLE: %s\n", line);
++		}
++	}
++break2:
++
++	return 0;
++}
++#endif				/* DEBUG */
++
++static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
++{
++	int i;
++	int ret;
++
++	bus->ctrl_frame_stat = false;
++	ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, frame, len);
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if (hi == 0 && lo == 0)
++				break;
++		}
++		return ret;
++	}
++
++	bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	u8 *frame;
++	u16 len;
++	u32 swheader;
++	uint retries = 0;
++	u8 doff = 0;
++	int ret = -1;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Back the pointer to make a room for bus header */
++	frame = msg - SDPCM_HDRLEN;
++	len = (msglen += SDPCM_HDRLEN);
++
++	/* Add alignment padding (optional for ctl frames) */
++	doff = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (doff) {
++		frame -= doff;
++		len += doff;
++		msglen += doff;
++		memset(frame, 0, doff + SDPCM_HDRLEN);
++	}
++	/* precondition: doff < BRCMF_SDALIGN */
++	doff += SDPCM_HDRLEN;
++
++	/* Round send length to next SDIO block */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++			len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (len & (ALIGNMENT - 1))
++		len = roundup(len, ALIGNMENT);
++
++	/* precondition: IS_ALIGNED((unsigned long)frame, 2) */
++
++	/* Need to lock here to protect txseq and SDIO tx calls */
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	*(__le16 *) frame = cpu_to_le16((u16) msglen);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~msglen);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
++	     SDPCM_CHANNEL_MASK)
++	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
++			     SDPCM_DOFFSET_MASK);
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++	if (!data_ok(bus)) {
++		brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
++			  bus->tx_max, bus->tx_seq);
++		bus->ctrl_frame_stat = true;
++		/* Send from dpc */
++		bus->ctrl_frame_buf = frame;
++		bus->ctrl_frame_len = len;
++
++		brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
++
++		if (!bus->ctrl_frame_stat) {
++			brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
++			ret = 0;
++		} else {
++			brcmf_dbg(INFO, "ctrl_frame_stat == true\n");
++			ret = -1;
++		}
++	}
++
++	if (ret == -1) {
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++				   frame, len, "Tx Frame:\n");
++		brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
++				   BRCMF_HDRS_ON(),
++				   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++		do {
++			ret = brcmf_tx_frame(bus, frame, len);
++		} while (ret < 0 && retries++ < TXRETRIES);
++	}
++
++	if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
++	}
++
++	up(&bus->sdsem);
++
++	if (ret)
++		bus->tx_ctlerrs++;
++	else
++		bus->tx_ctlpkts++;
++
++	return ret ? -EIO : 0;
++}
++
++static int
++brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	int timeleft;
++	uint rxlen = 0;
++	bool pending;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Wait until control frame is available */
++	timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
++
++	down(&bus->sdsem);
++	rxlen = bus->rxlen;
++	memcpy(msg, bus->rxctl, min(msglen, rxlen));
++	bus->rxlen = 0;
++	up(&bus->sdsem);
++
++	if (rxlen) {
++		brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
++			  rxlen, msglen);
++	} else if (timeleft == 0) {
++		brcmf_dbg(ERROR, "resumed on timeout\n");
++	} else if (pending) {
++		brcmf_dbg(CTL, "cancelled\n");
++		return -ERESTARTSYS;
++	} else {
++		brcmf_dbg(CTL, "resumed for unknown reason?\n");
++	}
++
++	if (rxlen)
++		bus->rx_ctlpkts++;
++	else
++		bus->rx_ctlerrs++;
++
++	return rxlen ? (int)rxlen : -ETIMEDOUT;
++}
++
++static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
++{
++	int bcmerror = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Basic sanity checks */
++	if (bus->sdiodev->bus_if->drvr_up) {
++		bcmerror = -EISCONN;
++		goto err;
++	}
++	if (!len) {
++		bcmerror = -EOVERFLOW;
++		goto err;
++	}
++
++	/* Free the old ones and replace with passed variables */
++	kfree(bus->vars);
++
++	bus->vars = kmalloc(len, GFP_ATOMIC);
++	bus->varsz = bus->vars ? len : 0;
++	if (bus->vars == NULL) {
++		bcmerror = -ENOMEM;
++		goto err;
++	}
++
++	/* Copy the passed variables, which should include the
++		 terminating double-null */
++	memcpy(bus->vars, arg, bus->varsz);
++err:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
++{
++	int bcmerror = 0;
++	u32 varsize;
++	u32 varaddr;
++	u8 *vbuffer;
++	u32 varsizew;
++	__le32 varsizew_le;
++#ifdef DEBUG
++	char *nvram_ularray;
++#endif				/* DEBUG */
++
++	/* Even if there are no vars are to be written, we still
++		 need to set the ramsize. */
++	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
++	varaddr = (bus->ramsize - 4) - varsize;
++
++	if (bus->vars) {
++		vbuffer = kzalloc(varsize, GFP_ATOMIC);
++		if (!vbuffer)
++			return -ENOMEM;
++
++		memcpy(vbuffer, bus->vars, bus->varsz);
++
++		/* Write the vars list */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
++#ifdef DEBUG
++		/* Verify NVRAM bytes */
++		brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
++		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
++		if (!nvram_ularray) {
++			kfree(vbuffer);
++			return -ENOMEM;
++		}
++
++		/* Upload image to verify downloaded contents. */
++		memset(nvram_ularray, 0xaa, varsize);
++
++		/* Read the vars list to temp buffer for comparison */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
++				     varsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
++				  bcmerror, varsize, varaddr);
++		}
++		/* Compare the org NVRAM with the one read from RAM */
++		if (memcmp(vbuffer, nvram_ularray, varsize))
++			brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
++		else
++			brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
++
++		kfree(nvram_ularray);
++#endif				/* DEBUG */
++
++		kfree(vbuffer);
++	}
++
++	/* adjust to the user specified RAM */
++	brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
++	brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
++		  varaddr, varsize);
++	varsize = ((bus->ramsize - 4) - varaddr);
++
++	/*
++	 * Determine the length token:
++	 * Varsize, converted to words, in lower 16-bits, checksum
++	 * in upper 16-bits.
++	 */
++	if (bcmerror) {
++		varsizew = 0;
++		varsizew_le = cpu_to_le32(0);
++	} else {
++		varsizew = varsize / 4;
++		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
++		varsizew_le = cpu_to_le32(varsizew);
++	}
++
++	brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
++		  varsize, varsizew);
++
++	/* Write the length token to the last word */
++	bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
++					 (u8 *)&varsizew_le, 4);
++
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
++{
++	int bcmerror = 0;
++	struct chip_info *ci = bus->ci;
++
++	/* To enter download state, disable ARM and reset SOCRAM.
++	 * To exit download state, simply reset ARM (default is RAM boot).
++	 */
++	if (enter) {
++		bus->alp_only = true;
++
++		ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM);
++
++		/* Clear the top bit of memory */
++		if (bus->ramsize) {
++			u32 zeros = 0;
++			brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
++					 (u8 *)&zeros, 4);
++		}
++	} else {
++		if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
++			brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
++			bcmerror = -EBADE;
++			goto fail;
++		}
++
++		bcmerror = brcmf_sdbrcm_write_vars(bus);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "no vars written to RAM\n");
++			bcmerror = 0;
++		}
++
++		w_sdreg32(bus, 0xFFFFFFFF,
++			  offsetof(struct sdpcmd_regs, intstatus));
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		/* Allow HT Clock now that the ARM is running. */
++		bus->alp_only = false;
++
++		bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD;
++	}
++fail:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus)
++{
++	if (bus->firmware->size < bus->fw_ptr + len)
++		len = bus->firmware->size - bus->fw_ptr;
++
++	memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
++	bus->fw_ptr += len;
++	return len;
++}
++
++static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
++{
++	int offset = 0;
++	uint len;
++	u8 *memblock = NULL, *memptr;
++	int ret;
++
++	brcmf_dbg(INFO, "Enter\n");
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++	if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
++		memptr += (BRCMF_SDALIGN -
++			   ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
++
++	/* Download image */
++	while ((len =
++		brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
++		ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
++		if (ret) {
++			brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n",
++				  ret, MEMBLOCK, offset);
++			goto err;
++		}
++
++		offset += MEMBLOCK;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++/*
++ * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
++ * and ending in a NUL.
++ * Removes carriage returns, empty lines, comment lines, and converts
++ * newlines to NULs.
++ * Shortens buffer as needed and pads with NULs.  End of buffer is marked
++ * by two NULs.
++*/
++
++static uint brcmf_process_nvram_vars(char *varbuf, uint len)
++{
++	char *dp;
++	bool findNewline;
++	int column;
++	uint buf_len, n;
++
++	dp = varbuf;
++
++	findNewline = false;
++	column = 0;
++
++	for (n = 0; n < len; n++) {
++		if (varbuf[n] == 0)
++			break;
++		if (varbuf[n] == '\r')
++			continue;
++		if (findNewline && varbuf[n] != '\n')
++			continue;
++		findNewline = false;
++		if (varbuf[n] == '#') {
++			findNewline = true;
++			continue;
++		}
++		if (varbuf[n] == '\n') {
++			if (column == 0)
++				continue;
++			*dp++ = 0;
++			column = 0;
++			continue;
++		}
++		*dp++ = varbuf[n];
++		column++;
++	}
++	buf_len = dp - varbuf;
++
++	while (dp < varbuf + n)
++		*dp++ = 0;
++
++	return buf_len;
++}
++
++static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
++{
++	uint len;
++	char *memblock = NULL;
++	char *bufp;
++	int ret;
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++
++	len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
++
++	if (len > 0 && len < MEMBLOCK) {
++		bufp = (char *)memblock;
++		bufp[len] = 0;
++		len = brcmf_process_nvram_vars(bufp, len);
++		bufp += len;
++		*bufp++ = 0;
++		if (len)
++			ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
++		if (ret)
++			brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
++	} else {
++		brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
++		ret = -EIO;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	int bcmerror = -1;
++
++	/* Keep arm in reset */
++	if (brcmf_sdbrcm_download_state(bus, true)) {
++		brcmf_dbg(ERROR, "error placing ARM core in reset\n");
++		goto err;
++	}
++
++	/* External image takes precedence if specified */
++	if (brcmf_sdbrcm_download_code_file(bus)) {
++		brcmf_dbg(ERROR, "dongle image file download failed\n");
++		goto err;
++	}
++
++	/* External nvram takes precedence if specified */
++	if (brcmf_sdbrcm_download_nvram(bus))
++		brcmf_dbg(ERROR, "dongle nvram file download failed\n");
++
++	/* Take arm out of reset */
++	if (brcmf_sdbrcm_download_state(bus, false)) {
++		brcmf_dbg(ERROR, "error getting out of ARM core reset\n");
++		goto err;
++	}
++
++	bcmerror = 0;
++
++err:
++	return bcmerror;
++}
++
++static bool
++brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	bool ret;
++
++	/* Download the firmware */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
++
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	return ret;
++}
++
++static int brcmf_sdbrcm_bus_init(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++	unsigned long timeout;
++	u8 ready, enable;
++	int err, ret = 0;
++	u8 saveclk;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* try to download image and nvram to the dongle */
++	if (bus_if->state == BRCMF_BUS_DOWN) {
++		if (!(brcmf_sdbrcm_download_firmware(bus)))
++			return -1;
++	}
++
++	if (!bus->sdiodev->bus_if->drvr)
++		return 0;
++
++	/* Start the watchdog timer */
++	bus->tickcnt = 0;
++	brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++
++	down(&bus->sdsem);
++
++	/* Make sure backplane clock is on, needed to generate F2 interrupt */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++	if (bus->clkstate != CLK_AVAIL)
++		goto exit;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err) {
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++		goto exit;
++	}
++
++	/* Enable function 2 (frame transfers) */
++	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
++		  offsetof(struct sdpcmd_regs, tosbmailboxdata));
++	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++
++	timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
++	ready = 0;
++	while (enable != ready) {
++		ready = brcmf_sdio_regrb(bus->sdiodev,
++					 SDIO_CCCR_IORx, NULL);
++		if (time_after(jiffies, timeout))
++			break;
++		else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
++			/* prevent busy waiting if it takes too long */
++			msleep_interruptible(20);
++	}
++
++	brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
++
++	/* If F2 successfully enabled, set core and enable interrupts */
++	if (ready == enable) {
++		/* Set up the interrupt mask and enable interrupts */
++		bus->hostintmask = HOSTINTMASK;
++		w_sdreg32(bus, bus->hostintmask,
++			  offsetof(struct sdpcmd_regs, hostintmask));
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
++	} else {
++		/* Disable F2 again */
++		enable = SDIO_FUNC_ENABLE_1;
++		brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++		ret = -ENODEV;
++	}
++
++	/* Restore previous clock setting */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
++
++	if (ret == 0) {
++		ret = brcmf_sdio_intr_register(bus->sdiodev);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "intr register failed:%d\n", ret);
++	}
++
++	/* If we didn't come up, turn off backplane clock */
++	if (bus_if->state != BRCMF_BUS_DATA)
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++
++exit:
++	up(&bus->sdsem);
++
++	return ret;
++}
++
++void brcmf_sdbrcm_isr(void *arg)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) arg;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (!bus) {
++		brcmf_dbg(ERROR, "bus is null pointer, exiting\n");
++		return;
++	}
++
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do\n");
++		return;
++	}
++	/* Count the interrupt call */
++	bus->intrcount++;
++	bus->ipend = true;
++
++	/* Shouldn't get this interrupt if we're sleeping? */
++	if (bus->sleeping) {
++		brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n");
++		return;
++	}
++
++	/* Disable additional interrupts (is this needed now)? */
++	if (!bus->intr)
++		brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
++
++#ifndef CONFIG_BRCMFMAC_SDIO_OOB
++	while (brcmf_sdbrcm_dpc(bus))
++		;
++#else
++	bus->dpc_sched = true;
++	if (bus->dpc_tsk) {
++		brcmf_sdbrcm_adddpctsk(bus);
++		complete(&bus->dpc_wait);
++	}
++#endif
++}
++
++static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
++{
++#ifdef DEBUG
++	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
++#endif	/* DEBUG */
++
++	brcmf_dbg(TIMER, "Enter\n");
++
++	/* Ignore the timer if simulating bus down */
++	if (bus->sleeping)
++		return false;
++
++	down(&bus->sdsem);
++
++	/* Poll period: check device if appropriate. */
++	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
++		u32 intstatus = 0;
++
++		/* Reset poll tick */
++		bus->polltick = 0;
++
++		/* Check device if no interrupts */
++		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
++
++			if (!bus->dpc_sched) {
++				u8 devpend;
++				devpend = brcmf_sdio_regrb(bus->sdiodev,
++							   SDIO_CCCR_INTx,
++							   NULL);
++				intstatus =
++				    devpend & (INTR_STATUS_FUNC1 |
++					       INTR_STATUS_FUNC2);
++			}
++
++			/* If there is something, make like the ISR and
++				 schedule the DPC */
++			if (intstatus) {
++				bus->pollcnt++;
++				bus->ipend = true;
++
++				bus->dpc_sched = true;
++				if (bus->dpc_tsk) {
++					brcmf_sdbrcm_adddpctsk(bus);
++					complete(&bus->dpc_wait);
++				}
++			}
++		}
++
++		/* Update interrupt tracking */
++		bus->lastintrs = bus->intrcount;
++	}
++#ifdef DEBUG
++	/* Poll for console output periodically */
++	if (bus_if->state == BRCMF_BUS_DATA &&
++	    bus->console_interval != 0) {
++		bus->console.count += BRCMF_WD_POLL_MS;
++		if (bus->console.count >= bus->console_interval) {
++			bus->console.count -= bus->console_interval;
++			/* Make sure backplane clock is on */
++			brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++			if (brcmf_sdbrcm_readconsole(bus) < 0)
++				/* stop on error */
++				bus->console_interval = 0;
++		}
++	}
++#endif				/* DEBUG */
++
++	/* On idle timeout clear activity flag and/or turn off clock */
++	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
++		if (++bus->idlecount >= bus->idletime) {
++			bus->idlecount = 0;
++			if (bus->activity) {
++				bus->activity = false;
++				brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			} else {
++				brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++			}
++		}
++	}
++
++	up(&bus->sdsem);
++
++	return bus->ipend;
++}
++
++static bool brcmf_sdbrcm_chipmatch(u16 chipid)
++{
++	if (chipid == BCM4329_CHIP_ID)
++		return true;
++	if (chipid == BCM4330_CHIP_ID)
++		return true;
++	return false;
++}
++
++static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(bus->rxbuf);
++	bus->rxctl = bus->rxbuf = NULL;
++	bus->rxlen = 0;
++
++	kfree(bus->databuf);
++	bus->databuf = NULL;
++}
++
++static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->sdiodev->bus_if->maxctl) {
++		bus->rxblen =
++		    roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
++			    ALIGNMENT) + BRCMF_SDALIGN;
++		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
++		if (!(bus->rxbuf))
++			goto fail;
++	}
++
++	/* Allocate buffer to receive glomed packet */
++	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
++	if (!(bus->databuf)) {
++		/* release rxbuf which was already located as above */
++		if (!bus->rxblen)
++			kfree(bus->rxbuf);
++		goto fail;
++	}
++
++	/* Align the buffer */
++	if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
++		bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
++			       ((unsigned long)bus->databuf % BRCMF_SDALIGN));
++	else
++		bus->dataptr = bus->databuf;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool
++brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
++{
++	u8 clkctl = 0;
++	int err = 0;
++	int reg_addr;
++	u32 reg_val;
++	u8 idx;
++
++	bus->alp_only = true;
++
++	pr_debug("F1 signature read @0x18000000=0x%4x\n",
++		 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
++
++	/*
++	 * Force PLL off until brcmf_sdio_chip_attach()
++	 * programs PLL control regs
++	 */
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++			 BRCMF_INIT_CLKCTL1, &err);
++	if (!err)
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++
++	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
++			  err, BRCMF_INIT_CLKCTL1, clkctl);
++		goto fail;
++	}
++
++	if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) {
++		brcmf_dbg(ERROR, "brcmf_sdio_chip_attach failed!\n");
++		goto fail;
++	}
++
++	if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
++		brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip);
++		goto fail;
++	}
++
++	brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci,
++					  SDIO_DRIVE_STRENGTH);
++
++	/* Get info on the SOCRAM cores... */
++	bus->ramsize = bus->ci->ramsize;
++	if (!(bus->ramsize)) {
++		brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n");
++		goto fail;
++	}
++
++	/* Set core control so an SDIO reset does a backplane reset */
++	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	reg_addr = bus->ci->c_inf[idx].base +
++		   offsetof(struct sdpcmd_regs, corecontrol);
++	reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
++	brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
++
++	brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
++
++	/* Locate an appropriately-aligned portion of hdrbuf */
++	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
++				    BRCMF_SDALIGN);
++
++	/* Set the poll and/or interrupt flags */
++	bus->intr = true;
++	bus->poll = false;
++	if (bus->poll)
++		bus->pollrate = 1;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Disable F2 to clear any intermediate frame state on the dongle */
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
++			 SDIO_FUNC_ENABLE_1, NULL);
++
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++	bus->sleeping = false;
++	bus->rxflow = false;
++
++	/* Done with backplane-dependent accesses, can drop clock... */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
++
++	/* ...and initialize clock/power states */
++	bus->clkstate = CLK_SDONLY;
++	bus->idletime = BRCMF_IDLE_INTERVAL;
++	bus->idleclock = BRCMF_IDLE_ACTIVE;
++
++	/* Query the F2 block size, set roundup accordingly */
++	bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
++	bus->roundup = min(max_roundup, bus->blocksize);
++
++	/* bus module does not support packet chaining */
++	bus->use_rxchain = false;
++	bus->sd_rxchain = false;
++
++	return true;
++}
++
++static int
++brcmf_sdbrcm_watchdog_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++		if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
++			brcmf_sdbrcm_bus_watchdog(bus);
++			/* Count the tick for reference */
++			bus->tickcnt++;
++		} else
++			break;
++	}
++	return 0;
++}
++
++static void
++brcmf_sdbrcm_watchdog(unsigned long data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	if (bus->watchdog_tsk) {
++		complete(&bus->watchdog_wait);
++		/* Reschedule the watchdog */
++		if (bus->wd_timer_valid)
++			mod_timer(&bus->timer,
++				  jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++	}
++}
++
++static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->ci) {
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++		brcmf_sdio_chip_detach(&bus->ci);
++		if (bus->vars && bus->varsz)
++			kfree(bus->vars);
++		bus->vars = NULL;
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++/* Detach and free everything */
++static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus) {
++		/* De-register interrupt handler */
++		brcmf_sdio_intr_unregister(bus->sdiodev);
++
++		if (bus->sdiodev->bus_if->drvr) {
++			brcmf_detach(bus->sdiodev->dev);
++			brcmf_sdbrcm_release_dongle(bus);
++		}
++
++		brcmf_sdbrcm_release_malloc(bus);
++
++		kfree(bus);
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
++{
++	int ret;
++	struct brcmf_sdio *bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* We make an assumption about address window mappings:
++	 * regsva == SI_ENUM_BASE*/
++
++	/* Allocate private bus interface state */
++	bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
++	if (!bus)
++		goto fail;
++
++	bus->sdiodev = sdiodev;
++	sdiodev->bus = bus;
++	skb_queue_head_init(&bus->glom);
++	bus->txbound = BRCMF_TXBOUND;
++	bus->rxbound = BRCMF_RXBOUND;
++	bus->txminmax = BRCMF_TXMINMAX;
++	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
++	bus->usebufpool = false;	/* Use bufpool if allocated,
++					 else use locally malloced rxbuf */
++
++	/* attempt to attach to the dongle */
++	if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
++		goto fail;
++	}
++
++	spin_lock_init(&bus->txqlock);
++	init_waitqueue_head(&bus->ctrl_wait);
++	init_waitqueue_head(&bus->dcmd_resp_wait);
++
++	/* Set up the watchdog timer */
++	init_timer(&bus->timer);
++	bus->timer.data = (unsigned long)bus;
++	bus->timer.function = brcmf_sdbrcm_watchdog;
++
++	/* Initialize thread based operation and lock */
++	sema_init(&bus->sdsem, 1);
++
++	/* Initialize watchdog thread */
++	init_completion(&bus->watchdog_wait);
++	bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
++					bus, "brcmf_watchdog");
++	if (IS_ERR(bus->watchdog_tsk)) {
++		pr_warn("brcmf_watchdog thread failed to start\n");
++		bus->watchdog_tsk = NULL;
++	}
++	/* Initialize DPC thread */
++	init_completion(&bus->dpc_wait);
++	INIT_LIST_HEAD(&bus->dpc_tsklst);
++	spin_lock_init(&bus->dpc_tl_lock);
++	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
++				   bus, "brcmf_dpc");
++	if (IS_ERR(bus->dpc_tsk)) {
++		pr_warn("brcmf_dpc thread failed to start\n");
++		bus->dpc_tsk = NULL;
++	}
++
++	/* Assign bus interface call back */
++	bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
++	bus->sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init;
++	bus->sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata;
++	bus->sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl;
++	bus->sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl;
++	/* Attach to the brcmf/OS/network interface */
++	ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_attach failed\n");
++		goto fail;
++	}
++
++	/* Allocate buffers */
++	if (!(brcmf_sdbrcm_probe_malloc(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n");
++		goto fail;
++	}
++
++	if (!(brcmf_sdbrcm_probe_init(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "completed!!\n");
++
++	/* if firmware path present try to download and bring up bus */
++	ret = brcmf_bus_start(bus->sdiodev->dev);
++	if (ret != 0) {
++		if (ret == -ENOLINK) {
++			brcmf_dbg(ERROR, "dongle is not responding\n");
++			goto fail;
++		}
++	}
++
++	return bus;
++
++fail:
++	brcmf_sdbrcm_release(bus);
++	return NULL;
++}
++
++void brcmf_sdbrcm_disconnect(void *ptr)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)ptr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus)
++		brcmf_sdbrcm_release(bus);
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void
++brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
++{
++	/* Totally stop the timer */
++	if (!wdtick && bus->wd_timer_valid) {
++		del_timer_sync(&bus->timer);
++		bus->wd_timer_valid = false;
++		bus->save_ms = wdtick;
++		return;
++	}
++
++	/* don't start the wd until fw is loaded */
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN)
++		return;
++
++	if (wdtick) {
++		if (bus->save_ms != BRCMF_WD_POLL_MS) {
++			if (bus->wd_timer_valid)
++				/* Stop timer and restart at new value */
++				del_timer_sync(&bus->timer);
++
++			/* Create timer again when watchdog period is
++			   dynamically changed or in the first instance
++			 */
++			bus->timer.expires =
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000;
++			add_timer(&bus->timer);
++
++		} else {
++			/* Re arm the timer, at last watchdog period */
++			mod_timer(&bus->timer,
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++		}
++
++		bus->wd_timer_valid = true;
++		bus->save_ms = wdtick;
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+new file mode 100644
+index 0000000..13f630c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+@@ -0,0 +1,622 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ***** SDIO interface chip backplane handle functions ***** */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/card.h>
++#include <linux/ssb/ssb_regs.h>
++#include <linux/bcma/bcma.h>
++
++#include <chipcommon.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <soc.h>
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++/* chip core base & ramsize */
++/* bcm4329 */
++/* SDIO device core, ID 0x829 */
++#define BCM4329_CORE_BUS_BASE		0x18011000
++/* internal memory core, ID 0x80e */
++#define BCM4329_CORE_SOCRAM_BASE	0x18003000
++/* ARM Cortex M3 core, ID 0x82a */
++#define BCM4329_CORE_ARM_BASE		0x18002000
++#define BCM4329_RAMSIZE			0x48000
++
++#define	SBCOREREV(sbidh) \
++	((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
++	  ((sbidh) & SSB_IDHIGH_RCLO))
++
++/* SOC Interconnect types (aka chip types) */
++#define SOCI_SB		0
++#define SOCI_AI		1
++
++/* EROM CompIdentB */
++#define CIB_REV_MASK		0xff000000
++#define CIB_REV_SHIFT		24
++
++#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
++/* SDIO Pad drive strength to select value mappings */
++struct sdiod_drive_str {
++	u8 strength;	/* Pad Drive Strength in mA */
++	u8 sel;		/* Chip-specific select value */
++};
++/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
++static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
++	{32, 0x6},
++	{26, 0x7},
++	{22, 0x4},
++	{16, 0x5},
++	{12, 0x2},
++	{8, 0x3},
++	{4, 0x0},
++	{0, 0x1}
++};
++
++u8
++brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
++		if (coreid == ci->c_inf[idx].id)
++			return idx;
++
++	return BRCMF_MAX_CORENUM;
++}
++
++static u32
++brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbidhigh),
++				   NULL);
++	return SBCOREREV(regdata);
++}
++
++static u32
++brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
++}
++
++static bool
++brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
++		    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
++	return (SSB_TMSLOW_CLOCK == regdata);
++}
++
++static bool
++brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++	bool ret;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
++
++	return ret;
++}
++
++static void
++brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u32 regdata, base;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++	base = ci->c_inf[idx].base;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if (regdata & SSB_TMSLOW_RESET)
++		return;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
++		/*
++		 * set target reject and spin until busy is clear
++		 * (preserve core-specific bits)
++		 */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata | SSB_TMSLOW_REJECT, NULL);
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(1);
++		SPINWAIT((brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL) &
++			SSB_TMSHIGH_BUSY), 100000);
++
++		regdata = brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL);
++		if (regdata & SSB_TMSHIGH_BUSY)
++			brcmf_dbg(ERROR, "core state still busy\n");
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata |= SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			udelay(1);
++			SPINWAIT((brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL) &
++				SSB_IMSTATE_BUSY), 100000);
++		}
++
++		/* set reset and reject while enabling the clocks */
++		regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
++			  SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata, NULL);
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(10);
++
++		/* clear the initiator reject bit */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata &= ~SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++		}
++	}
++
++	/* leave reset and reject asserted */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++			 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* if core is already in reset, just return */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	if ((regdata & BCMA_RESET_CTL_RESET) != 0)
++		return;
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(10);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 BCMA_RESET_CTL_RESET, NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/*
++	 * Must do the disable sequence first to work for
++	 * arbitrary current core state.
++	 */
++	brcmf_sdio_sb_coredisable(sdiodev, ci, coreid);
++
++	/*
++	 * Now do the initialization sequence.
++	 * set reset while enabling the clock and
++	 * forcing them on throughout the core
++	 */
++	brcmf_sdio_regwl(sdiodev,
++			 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
++			 NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* clear any serror */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				   NULL);
++	if (regdata & SSB_TMSHIGH_SERR)
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				 0, NULL);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbimstate),
++				   NULL);
++	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbimstate),
++				 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
++				 NULL);
++
++	/* clear reset and allow it to propagate throughout the core */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* leave clock enabled */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* must disable first to work for arbitrary current core state */
++	brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
++
++	/* now do initialization sequence */
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 0, NULL);
++	udelay(1);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(1);
++}
++
++static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
++				       struct chip_info *ci, u32 regs)
++{
++	u32 regdata;
++
++	/*
++	 * Get CC core rev
++	 * Chipid is assume to be at offset 0 from regs arg
++	 * For different chiptypes or old sdio hosts w/o chipcommon,
++	 * other ways of recognition should be added here.
++	 */
++	ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
++	ci->c_inf[0].base = regs;
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_CC_REG(ci->c_inf[0].base, chipid),
++				   NULL);
++	ci->chip = regdata & CID_ID_MASK;
++	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
++	ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
++
++	brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
++
++	/* Address of cores for new chips should be added here */
++	switch (ci->chip) {
++	case BCM4329_CHIP_ID:
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
++		ci->ramsize = BCM4329_RAMSIZE;
++		break;
++	case BCM4330_CHIP_ID:
++		ci->c_inf[0].wrapbase = 0x18100000;
++		ci->c_inf[0].cib = 0x27004211;
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = 0x18002000;
++		ci->c_inf[1].wrapbase = 0x18102000;
++		ci->c_inf[1].cib = 0x07004211;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = 0x18004000;
++		ci->c_inf[2].wrapbase = 0x18104000;
++		ci->c_inf[2].cib = 0x0d080401;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = 0x18003000;
++		ci->c_inf[3].wrapbase = 0x18103000;
++		ci->c_inf[3].cib = 0x03004211;
++		ci->ramsize = 0x48000;
++		break;
++	default:
++		brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
++		return -ENODEV;
++	}
++
++	switch (ci->socitype) {
++	case SOCI_SB:
++		ci->iscoreup = brcmf_sdio_sb_iscoreup;
++		ci->corerev = brcmf_sdio_sb_corerev;
++		ci->coredisable = brcmf_sdio_sb_coredisable;
++		ci->resetcore = brcmf_sdio_sb_resetcore;
++		break;
++	case SOCI_AI:
++		ci->iscoreup = brcmf_sdio_ai_iscoreup;
++		ci->corerev = brcmf_sdio_ai_corerev;
++		ci->coredisable = brcmf_sdio_ai_coredisable;
++		ci->resetcore = brcmf_sdio_ai_resetcore;
++		break;
++	default:
++		brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype);
++		return -ENODEV;
++	}
++
++	return 0;
++}
++
++static int
++brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
++{
++	int err = 0;
++	u8 clkval, clkset;
++
++	/* Try forcing SDIO core to do ALPAvail request only */
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	if (err) {
++		brcmf_dbg(ERROR, "error writing for HT off\n");
++		return err;
++	}
++
++	/* If register supported, wait for ALPAvail and then force ALP */
++	/* This may take up to 15 milliseconds */
++	clkval = brcmf_sdio_regrb(sdiodev,
++				  SBSDIO_FUNC1_CHIPCLKCSR, NULL);
++
++	if ((clkval & ~SBSDIO_AVBITS) != clkset) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
++			  clkset, clkval);
++		return -EACCES;
++	}
++
++	SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
++					     SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
++			!SBSDIO_ALPAV(clkval)),
++			PMU_MAX_TRANSITION_DLY);
++	if (!SBSDIO_ALPAV(clkval)) {
++		brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
++			  clkval);
++		return -EBUSY;
++	}
++
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	udelay(65);
++
++	/* Also, disable the extra SDIO pull-ups */
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
++
++	return 0;
++}
++
++static void
++brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
++			     struct chip_info *ci)
++{
++	u32 base = ci->c_inf[0].base;
++
++	/* get chipcommon rev */
++	ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
++
++	/* get chipcommon capabilites */
++	ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
++					     CORE_CC_REG(base, capabilities),
++					     NULL);
++
++	/* get pmu caps & rev */
++	if (ci->c_inf[0].caps & CC_CAP_PMU) {
++		ci->pmucaps =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, pmucapabilities),
++					 NULL);
++		ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
++	}
++
++	ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
++
++	brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
++		  ci->c_inf[0].rev, ci->pmurev,
++		  ci->c_inf[1].rev, ci->c_inf[1].id);
++
++	/*
++	 * Make sure any on-chip ARM is off (in case strapping is wrong),
++	 * or downloaded code was already running.
++	 */
++	ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3);
++}
++
++int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++			   struct chip_info **ci_ptr, u32 regs)
++{
++	int ret;
++	struct chip_info *ci;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* alloc chip_info_t */
++	ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
++	if (!ci)
++		return -ENOMEM;
++
++	ret = brcmf_sdio_chip_buscoreprep(sdiodev);
++	if (ret != 0)
++		goto err;
++
++	ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
++	if (ret != 0)
++		goto err;
++
++	brcmf_sdio_chip_buscoresetup(sdiodev, ci);
++
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
++			 0, NULL);
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
++			 0, NULL);
++
++	*ci_ptr = ci;
++	return 0;
++
++err:
++	kfree(ci);
++	return ret;
++}
++
++void
++brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(*ci_ptr);
++	*ci_ptr = NULL;
++}
++
++static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
++{
++	const char *fmt;
++
++	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
++	snprintf(buf, len, fmt, chipid);
++	return buf;
++}
++
++void
++brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info *ci, u32 drivestrength)
++{
++	struct sdiod_drive_str *str_tab = NULL;
++	u32 str_mask = 0;
++	u32 str_shift = 0;
++	char chn[8];
++	u32 base = ci->c_inf[0].base;
++
++	if (!(ci->c_inf[0].caps & CC_CAP_PMU))
++		return;
++
++	switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
++	case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
++		str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8;
++		str_mask = 0x00003800;
++		str_shift = 11;
++		break;
++	default:
++		brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
++			  brcmf_sdio_chip_name(ci->chip, chn, 8),
++			  ci->chiprev, ci->pmurev);
++		break;
++	}
++
++	if (str_tab != NULL) {
++		u32 drivestrength_sel = 0;
++		u32 cc_data_temp;
++		int i;
++
++		for (i = 0; str_tab[i].strength != 0; i++) {
++			if (drivestrength >= str_tab[i].strength) {
++				drivestrength_sel = str_tab[i].sel;
++				break;
++			}
++		}
++
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 1, NULL);
++		cc_data_temp =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, chipcontrol_addr),
++					 NULL);
++		cc_data_temp &= ~str_mask;
++		drivestrength_sel <<= str_shift;
++		cc_data_temp |= drivestrength_sel;
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 cc_data_temp, NULL);
++
++		brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
++			  drivestrength, cc_data_temp);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+new file mode 100644
+index 0000000..ce974d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+@@ -0,0 +1,136 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMFMAC_SDIO_CHIP_H_
++#define _BRCMFMAC_SDIO_CHIP_H_
++
++/*
++ * Core reg address translation.
++ * Both macro's returns a 32 bits byte address on the backplane bus.
++ */
++#define CORE_CC_REG(base, field) \
++		(base + offsetof(struct chipcregs, field))
++#define CORE_BUS_REG(base, field) \
++		(base + offsetof(struct sdpcmd_regs, field))
++#define CORE_SB(base, field) \
++		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
++
++/* SDIO function 1 register CHIPCLKCSR */
++/* Force ALP request to backplane */
++#define SBSDIO_FORCE_ALP		0x01
++/* Force HT request to backplane */
++#define SBSDIO_FORCE_HT			0x02
++/* Force ILP request to backplane */
++#define SBSDIO_FORCE_ILP		0x04
++/* Make ALP ready (power up xtal) */
++#define SBSDIO_ALP_AVAIL_REQ		0x08
++/* Make HT ready (power up PLL) */
++#define SBSDIO_HT_AVAIL_REQ		0x10
++/* Squelch clock requests from HW */
++#define SBSDIO_FORCE_HW_CLKREQ_OFF	0x20
++/* Status: ALP is ready */
++#define SBSDIO_ALP_AVAIL		0x40
++/* Status: HT is ready */
++#define SBSDIO_HT_AVAIL			0x80
++#define SBSDIO_AVBITS		(SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
++#define SBSDIO_ALPAV(regval)	((regval) & SBSDIO_AVBITS)
++#define SBSDIO_HTAV(regval)	(((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
++#define SBSDIO_ALPONLY(regval)	(SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
++#define SBSDIO_CLKAV(regval, alponly) \
++	(SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
++
++#define BRCMF_MAX_CORENUM	6
++
++struct chip_core_info {
++	u16 id;
++	u16 rev;
++	u32 base;
++	u32 wrapbase;
++	u32 caps;
++	u32 cib;
++};
++
++struct chip_info {
++	u32 chip;
++	u32 chiprev;
++	u32 socitype;
++	/* core info */
++	/* always put chipcommon core at 0, bus core at 1 */
++	struct chip_core_info c_inf[BRCMF_MAX_CORENUM];
++	u32 pmurev;
++	u32 pmucaps;
++	u32 ramsize;
++
++	bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++	void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++};
++
++struct sbconfig {
++	u32 PAD[2];
++	u32 sbipsflag;	/* initiator port ocp slave flag */
++	u32 PAD[3];
++	u32 sbtpsflag;	/* target port ocp slave flag */
++	u32 PAD[11];
++	u32 sbtmerrloga;	/* (sonics >= 2.3) */
++	u32 PAD;
++	u32 sbtmerrlog;	/* (sonics >= 2.3) */
++	u32 PAD[3];
++	u32 sbadmatch3;	/* address match3 */
++	u32 PAD;
++	u32 sbadmatch2;	/* address match2 */
++	u32 PAD;
++	u32 sbadmatch1;	/* address match1 */
++	u32 PAD[7];
++	u32 sbimstate;	/* initiator agent state */
++	u32 sbintvec;	/* interrupt mask */
++	u32 sbtmstatelow;	/* target state */
++	u32 sbtmstatehigh;	/* target state */
++	u32 sbbwa0;		/* bandwidth allocation table0 */
++	u32 PAD;
++	u32 sbimconfiglow;	/* initiator configuration */
++	u32 sbimconfighigh;	/* initiator configuration */
++	u32 sbadmatch0;	/* address match0 */
++	u32 PAD;
++	u32 sbtmconfiglow;	/* target configuration */
++	u32 sbtmconfighigh;	/* target configuration */
++	u32 sbbconfig;	/* broadcast configuration */
++	u32 PAD;
++	u32 sbbstate;	/* broadcast state */
++	u32 PAD[3];
++	u32 sbactcnfg;	/* activate configuration */
++	u32 PAD[3];
++	u32 sbflagst;	/* current sbflags */
++	u32 PAD[3];
++	u32 sbidlow;		/* identification */
++	u32 sbidhigh;	/* identification */
++};
++
++extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info **ci_ptr, u32 regs);
++extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr);
++extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++					      struct chip_info *ci,
++					      u32 drivestrength);
++extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid);
++
++
++#endif		/* _BRCMFMAC_SDIO_CHIP_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+new file mode 100644
+index 0000000..29bf78d2
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+@@ -0,0 +1,272 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SDH_H_
++#define	_BRCM_SDH_H_
++
++#include <linux/skbuff.h>
++
++#define SDIO_FUNC_0		0
++#define SDIO_FUNC_1		1
++#define SDIO_FUNC_2		2
++
++#define SDIOD_FBR_SIZE		0x100
++
++/* io_en */
++#define SDIO_FUNC_ENABLE_1	0x02
++#define SDIO_FUNC_ENABLE_2	0x04
++
++/* io_rdys */
++#define SDIO_FUNC_READY_1	0x02
++#define SDIO_FUNC_READY_2	0x04
++
++/* intr_status */
++#define INTR_STATUS_FUNC1	0x2
++#define INTR_STATUS_FUNC2	0x4
++
++/* Maximum number of I/O funcs */
++#define SDIOD_MAX_IOFUNCS	7
++
++/* mask of register map */
++#define REG_F0_REG_MASK		0x7FF
++#define REG_F1_MISC_MASK	0x1FFFF
++
++/* as of sdiod rev 0, supports 3 functions */
++#define SBSDIO_NUM_FUNCTION		3
++
++/* function 0 vendor specific CCCR registers */
++#define SDIO_CCCR_BRCM_SEPINT		0xf2
++
++#define  SDIO_SEPINT_MASK		0x01
++#define  SDIO_SEPINT_OE			0x02
++#define  SDIO_SEPINT_ACT_HI		0x04
++
++/* function 1 miscellaneous registers */
++
++/* sprom command and status */
++#define SBSDIO_SPROM_CS			0x10000
++/* sprom info register */
++#define SBSDIO_SPROM_INFO		0x10001
++/* sprom indirect access data byte 0 */
++#define SBSDIO_SPROM_DATA_LOW		0x10002
++/* sprom indirect access data byte 1 */
++#define SBSDIO_SPROM_DATA_HIGH		0x10003
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_LOW		0x10004
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_HIGH		0x10005
++/* xtal_pu (gpio) output */
++#define SBSDIO_CHIP_CTRL_DATA		0x10006
++/* xtal_pu (gpio) enable */
++#define SBSDIO_CHIP_CTRL_EN		0x10007
++/* rev < 7, watermark for sdio device */
++#define SBSDIO_WATERMARK		0x10008
++/* control busy signal generation */
++#define SBSDIO_DEVICE_CTL		0x10009
++
++/* SB Address Window Low (b15) */
++#define SBSDIO_FUNC1_SBADDRLOW		0x1000A
++/* SB Address Window Mid (b23:b16) */
++#define SBSDIO_FUNC1_SBADDRMID		0x1000B
++/* SB Address Window High (b31:b24)    */
++#define SBSDIO_FUNC1_SBADDRHIGH		0x1000C
++/* Frame Control (frame term/abort) */
++#define SBSDIO_FUNC1_FRAMECTRL		0x1000D
++/* ChipClockCSR (ALP/HT ctl/status) */
++#define SBSDIO_FUNC1_CHIPCLKCSR		0x1000E
++/* SdioPullUp (on cmd, d0-d2) */
++#define SBSDIO_FUNC1_SDIOPULLUP		0x1000F
++/* Write Frame Byte Count Low */
++#define SBSDIO_FUNC1_WFRAMEBCLO		0x10019
++/* Write Frame Byte Count High */
++#define SBSDIO_FUNC1_WFRAMEBCHI		0x1001A
++/* Read Frame Byte Count Low */
++#define SBSDIO_FUNC1_RFRAMEBCLO		0x1001B
++/* Read Frame Byte Count High */
++#define SBSDIO_FUNC1_RFRAMEBCHI		0x1001C
++
++#define SBSDIO_FUNC1_MISC_REG_START	0x10000	/* f1 misc register start */
++#define SBSDIO_FUNC1_MISC_REG_LIMIT	0x1001C	/* f1 misc register end */
++
++/* function 1 OCP space */
++
++/* sb offset addr is <= 15 bits, 32k */
++#define SBSDIO_SB_OFT_ADDR_MASK		0x07FFF
++#define SBSDIO_SB_OFT_ADDR_LIMIT	0x08000
++/* with b15, maps to 32-bit SB access */
++#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000
++
++/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
++
++#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */
++#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */
++#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */
++/* Address bits from SBADDR regs */
++#define SBSDIO_SBWINDOW_MASK		0xffff8000
++
++#define SDIOH_READ              0	/* Read request */
++#define SDIOH_WRITE             1	/* Write request */
++
++#define SDIOH_DATA_FIX          0	/* Fixed addressing */
++#define SDIOH_DATA_INC          1	/* Incremental addressing */
++
++/* internal return code */
++#define SUCCESS	0
++#define ERROR	1
++
++/* Packet alignment for most efficient SDIO (can change based on platform) */
++#define BRCMF_SDALIGN	(1 << 6)
++
++/* watchdog polling interval in ms */
++#define BRCMF_WD_POLL_MS	10
++
++struct brcmf_sdreg {
++	int func;
++	int offset;
++	int value;
++};
++
++struct brcmf_sdio;
++
++struct brcmf_sdio_dev {
++	struct sdio_func *func[SDIO_MAX_FUNCS];
++	u8 num_funcs;			/* Supported funcs on client */
++	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
++	u32 sbwad;			/* Save backplane window address */
++	void *bus;
++	atomic_t suspend;		/* suspend flag */
++	wait_queue_head_t request_byte_wait;
++	wait_queue_head_t request_word_wait;
++	wait_queue_head_t request_chain_wait;
++	wait_queue_head_t request_buffer_wait;
++	struct device *dev;
++	struct brcmf_bus *bus_if;
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++	unsigned int irq;		/* oob interrupt number */
++	unsigned long irq_flags;	/* board specific oob flags */
++	bool irq_en;			/* irq enable flags */
++	spinlock_t irq_en_lock;
++	bool irq_wake;			/* irq wake enable flags */
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++};
++
++/* Register/deregister interrupt handler. */
++extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
++
++/* sdio device register access interface */
++extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u8 data, int *ret);
++extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u32 data, int *ret);
++
++/* Buffer transfer to/from device (client) core via cmd53.
++ *   fn:       function number
++ *   addr:     backplane address (i.e. >= regsva from attach)
++ *   flags:    backplane width, address increment, sync/async
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ *   pkt:      pointer to packet associated with buf (if any)
++ *   complete: callback function for command completion (async only)
++ *   handle:   handle for completion callback (first arg in callback)
++ * Returns 0 or error code.
++ * NOTE: Async operation is not currently supported.
++ */
++extern int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++
++extern int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++extern int
++brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			uint flags, struct sk_buff_head *pktq);
++
++/* Flags bits */
++
++/* Four-byte target (backplane) width (vs. two-byte) */
++#define SDIO_REQ_4BYTE	0x1
++/* Fixed address (FIFO) (vs. incrementing address) */
++#define SDIO_REQ_FIXED	0x2
++/* Async request (vs. sync request) */
++#define SDIO_REQ_ASYNC	0x4
++
++/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
++ *   rw:       read or write (0/1)
++ *   addr:     direct SDIO address
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ * Returns 0 or error code.
++ */
++extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
++			       u32 addr, u8 *buf, uint nbytes);
++
++/* Issue an abort to the specified function */
++extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
++
++/* platform specific/high level functions */
++extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
++
++extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
++					  u32 address);
++
++/* attach, return handler on success, NULL if failed.
++ *  The handler shall be provided by all subsequent calls. No local cache
++ *  cfghdl points to the starting address of pci device mapped memory
++ */
++extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
++
++/* read or write one byte using cmd52 */
++extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
++				    uint fnc, uint addr, u8 *byte);
++
++/* read or write 2/4 bytes using cmd53 */
++extern int
++brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			 uint rw, uint fnc, uint addr,
++			 u32 *word, uint nbyte);
++
++/* read or write any buffer using cmd53 */
++extern int
++brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			   uint fix_inc, uint rw, uint fnc_num, u32 addr,
++			   struct sk_buff *pkt);
++extern int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq);
++
++/* Watchdog timer interface for pm ops */
++extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
++				    bool enable);
++
++extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdbrcm_disconnect(void *ptr);
++extern void brcmf_sdbrcm_isr(void *arg);
++
++extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
++#endif				/* _BRCM_SDH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+new file mode 100644
+index 0000000..be1edc8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+@@ -0,0 +1,1617 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/firmware.h>
++#include <linux/usb.h>
++#include <linux/vmalloc.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <dhd_bus.h>
++#include <dhd_dbg.h>
++
++#include "usb_rdl.h"
++#include "usb.h"
++
++#define IOCTL_RESP_TIMEOUT  2000
++
++#define BRCMF_USB_SYNC_TIMEOUT		300	/* ms */
++#define BRCMF_USB_DLIMAGE_SPINWAIT	100	/* in unit of ms */
++#define BRCMF_USB_DLIMAGE_LIMIT		500	/* spinwait limit (ms) */
++
++#define BRCMF_POSTBOOT_ID		0xA123  /* ID to detect if dongle
++						   has boot up */
++#define BRCMF_USB_RESETCFG_SPINWAIT	1	/* wait after resetcfg (ms) */
++
++#define BRCMF_USB_NRXQ	50
++#define BRCMF_USB_NTXQ	50
++
++#define CONFIGDESC(usb)         (&((usb)->actconfig)->desc)
++#define IFPTR(usb, idx)         ((usb)->actconfig->interface[(idx)])
++#define IFALTS(usb, idx)        (IFPTR((usb), (idx))->altsetting[0])
++#define IFDESC(usb, idx)        IFALTS((usb), (idx)).desc
++#define IFEPDESC(usb, idx, ep)  (IFALTS((usb), (idx)).endpoint[(ep)]).desc
++
++#define CONTROL_IF              0
++#define BULK_IF                 0
++
++#define BRCMF_USB_CBCTL_WRITE	0
++#define BRCMF_USB_CBCTL_READ	1
++#define BRCMF_USB_MAX_PKT_SIZE	1600
++
++#define BRCMF_USB_43236_FW_NAME	"brcm/brcmfmac43236b.bin"
++
++enum usbdev_suspend_state {
++	USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
++						  suspend */
++	USBOS_SUSPEND_STATE_SUSPEND_PENDING,	/* Device is idle, can be
++						 * suspended. Wating PM to
++						 * suspend the device
++						 */
++	USBOS_SUSPEND_STATE_SUSPENDED	/* Device suspended */
++};
++
++struct brcmf_usb_probe_info {
++	void *usbdev_info;
++	struct usb_device *usb; /* USB device pointer from OS */
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++	int intr_size; /* Size of interrupt message */
++	int interval;  /* Interrupt polling interval */
++	int vid;
++	int pid;
++	enum usb_device_speed device_speed;
++	enum usbdev_suspend_state suspend_state;
++	struct usb_interface *intf;
++};
++static struct brcmf_usb_probe_info usbdev_probe_info;
++
++struct brcmf_usb_image {
++	void *data;
++	u32 len;
++};
++static struct brcmf_usb_image g_image = { NULL, 0 };
++
++struct intr_transfer_buf {
++	u32 notification;
++	u32 reserved;
++};
++
++struct brcmf_usbdev_info {
++	struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
++	spinlock_t qlock;
++	struct list_head rx_freeq;
++	struct list_head rx_postq;
++	struct list_head tx_freeq;
++	struct list_head tx_postq;
++	enum usbdev_suspend_state suspend_state;
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++
++	bool activity;
++	int rx_low_watermark;
++	int tx_low_watermark;
++	int tx_high_watermark;
++	bool txoff;
++	bool rxoff;
++	bool txoverride;
++
++	struct brcmf_usbreq *tx_reqs;
++	struct brcmf_usbreq *rx_reqs;
++
++	u8 *image;	/* buffer for combine fw and nvram */
++	int image_len;
++
++	wait_queue_head_t wait;
++	bool waitdone;
++	int sync_urb_status;
++
++	struct usb_device *usbdev;
++	struct device *dev;
++	enum usb_device_speed  device_speed;
++
++	int ctl_in_pipe, ctl_out_pipe;
++	struct urb *ctl_urb; /* URB for control endpoint */
++	struct usb_ctrlrequest ctl_write;
++	struct usb_ctrlrequest ctl_read;
++	u32 ctl_urb_actual_length;
++	int ctl_urb_status;
++	int ctl_completed;
++	wait_queue_head_t ioctl_resp_wait;
++	wait_queue_head_t ctrl_wait;
++	ulong ctl_op;
++
++	bool rxctl_deferrespok;
++
++	struct urb *bulk_urb; /* used for FW download */
++	struct urb *intr_urb; /* URB for interrupt endpoint */
++	int intr_size;          /* Size of interrupt message */
++	int interval;           /* Interrupt polling interval */
++	struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
++
++	struct brcmf_usb_probe_info probe_info;
++
++};
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req);
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	return bus_if->bus_priv.usb;
++}
++
++static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
++{
++	return brcmf_usb_get_buspub(dev)->devinfo;
++}
++
++#if 0
++static void
++brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
++{
++	dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
++}
++#endif
++
++static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
++	 uint *condition, bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = IOCTL_RESP_TIMEOUT;
++
++	/* Convert timeout in millsecond to jiffies */
++	timeout = msecs_to_jiffies(timeout);
++	/* Wait until control frame is available */
++	add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	smp_mb();
++	while (!(*condition) && (!signal_pending(current) && timeout)) {
++		timeout = schedule_timeout(timeout);
++		/* Wait until control frame is available */
++		smp_mb();
++	}
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
++{
++	if (waitqueue_active(&devinfo->ioctl_resp_wait))
++		wake_up_interruptible(&devinfo->ioctl_resp_wait);
++
++	return 0;
++}
++
++static void
++brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
++{
++
++	if (unlikely(devinfo == NULL))
++		return;
++
++	if (type == BRCMF_USB_CBCTL_READ) {
++		if (status == 0)
++			devinfo->bus_pub.stats.rx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.rx_ctlerrs++;
++	} else if (type == BRCMF_USB_CBCTL_WRITE) {
++		if (status == 0)
++			devinfo->bus_pub.stats.tx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.tx_ctlerrs++;
++	}
++
++	devinfo->ctl_urb_status = status;
++	devinfo->ctl_completed = true;
++	brcmf_usb_ioctl_resp_wake(devinfo);
++}
++
++static void
++brcmf_usb_ctlread_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->ctl_urb_actual_length = urb->actual_length;
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
++		urb->status);
++}
++
++static void
++brcmf_usb_ctlwrite_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
++		urb->status);
++}
++
++static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
++{
++	return 0;
++}
++
++static int
++brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if (devinfo == NULL || buf == NULL ||
++	    len == 0 || devinfo->ctl_urb == NULL)
++		return -EINVAL;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED)
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++
++	devinfo->activity = true;
++	size = len;
++	devinfo->ctl_write.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++	devinfo->ctl_urb_status = 0;
++	devinfo->ctl_urb_actual_length = 0;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_out_pipe,
++		(unsigned char *) &devinfo->ctl_write,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlwrite_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int
++brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if ((devinfo == NULL) || (buf == NULL) || (len == 0)
++		|| (devinfo->ctl_urb == NULL))
++		return -EINVAL;
++
++	size = len;
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	if (devinfo->rxctl_deferrespok) {
++		/* BMAC model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK;
++	} else {
++		/* full dongle model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++	}
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_in_pipe,
++		(unsigned char *) &devinfo->ctl_read,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlread_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_send_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "Txctl wait timed out\n");
++		err = -EIO;
++	}
++	return err;
++}
++
++static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_recv_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	err = devinfo->ctl_urb_status;
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "rxctl wait timed out\n");
++		err = -EIO;
++	}
++	if (!err)
++		return devinfo->ctl_urb_actual_length;
++	else
++		return err;
++}
++
++static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
++					  struct list_head *q)
++{
++	unsigned long flags;
++	struct brcmf_usbreq  *req;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	if (list_empty(q)) {
++		spin_unlock_irqrestore(&devinfo->qlock, flags);
++		return NULL;
++	}
++	req = list_entry(q->next, struct brcmf_usbreq, list);
++	list_del_init(q->next);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++	return req;
++
++}
++
++static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
++			  struct list_head *q, struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_add_tail(&req->list, q);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++static struct brcmf_usbreq *
++brcmf_usbdev_qinit(struct list_head *q, int qsize)
++{
++	int i;
++	struct brcmf_usbreq *req, *reqs;
++
++	reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC);
++	if (reqs == NULL) {
++		brcmf_dbg(ERROR, "fail to allocate memory!\n");
++		return NULL;
++	}
++	req = reqs;
++
++	for (i = 0; i < qsize; i++) {
++		req->urb = usb_alloc_urb(0, GFP_ATOMIC);
++		if (!req->urb)
++			goto fail;
++
++		INIT_LIST_HEAD(&req->list);
++		list_add_tail(&req->list, q);
++		req++;
++	}
++	return reqs;
++fail:
++	brcmf_dbg(ERROR, "fail!\n");
++	while (!list_empty(q)) {
++		req = list_entry(q->next, struct brcmf_usbreq, list);
++		if (req && req->urb)
++			usb_free_urb(req->urb);
++		list_del(q->next);
++	}
++	return NULL;
++
++}
++
++static void brcmf_usb_free_q(struct list_head *q, bool pending)
++{
++	struct brcmf_usbreq *req, *next;
++	int i = 0;
++	list_for_each_entry_safe(req, next, q, list) {
++		if (!req->urb) {
++			brcmf_dbg(ERROR, "bad req\n");
++			break;
++		}
++		i++;
++		if (pending) {
++			usb_kill_urb(req->urb);
++		} else {
++			usb_free_urb(req->urb);
++			list_del_init(&req->list);
++		}
++	}
++}
++
++static void brcmf_usb_del_fromq(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_del_init(&req->list);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++
++static void brcmf_usb_tx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	if (urb->status == 0)
++		devinfo->bus_pub.bus->dstats.tx_packets++;
++	else
++		devinfo->bus_pub.bus->dstats.tx_errors++;
++
++	dev_kfree_skb(req->skb);
++	req->skb = NULL;
++	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++
++}
++
++static void brcmf_usb_rx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq  *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++	struct sk_buff *skb;
++	int ifidx = 0;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	skb = req->skb;
++	req->skb = NULL;
++
++	if (urb->status == 0) {
++		devinfo->bus_pub.bus->dstats.rx_packets++;
++	} else {
++		devinfo->bus_pub.bus->dstats.rx_errors++;
++		dev_kfree_skb(skb);
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) {
++		skb_put(skb, urb->actual_length);
++		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(skb);
++			devinfo->bus_pub.bus->dstats.rx_errors++;
++		} else {
++			brcmf_rx_packet(devinfo->dev, ifidx, skb);
++			brcmf_usb_rx_refill(devinfo, req);
++		}
++	} else {
++		dev_kfree_skb(skb);
++	}
++	return;
++
++}
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req)
++{
++	struct sk_buff *skb;
++	int ret;
++
++	if (!req || !devinfo)
++		return;
++
++	skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
++	if (!skb) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++	req->skb = skb;
++
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
++			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
++			  req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	req->devinfo = devinfo;
++
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (ret == 0) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
++	} else {
++		dev_kfree_skb(req->skb);
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++	}
++	return;
++}
++
++static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
++{
++	struct brcmf_usbreq *req;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		brcmf_dbg(ERROR, "bus is not up\n");
++		return;
++	}
++	while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
++		brcmf_usb_rx_refill(devinfo, req);
++}
++
++static void
++brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
++{
++	struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
++	int old_state;
++
++
++	if (devinfo->bus_pub.state == state)
++		return;
++
++	old_state = devinfo->bus_pub.state;
++	brcmf_dbg(TRACE, "dbus state change from %d to to %d\n",
++		  old_state, state);
++
++	/* Don't update state if it's PnP firmware re-download */
++	if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
++		devinfo->bus_pub.state = state;
++
++	if ((old_state  == BCMFMAC_USB_STATE_SLEEP)
++		&& (state == BCMFMAC_USB_STATE_UP)) {
++		brcmf_usb_rx_fill_all(devinfo);
++	}
++
++	/* update state of upper layer */
++	if (state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(INFO, "DBUS is down\n");
++		bcmf_bus->state = BRCMF_BUS_DOWN;
++	} else {
++		brcmf_dbg(INFO, "DBUS current state=%d\n", state);
++	}
++}
++
++static void
++brcmf_usb_intr_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++	bool killed;
++
++	if (devinfo == NULL)
++		return;
++
++	if (unlikely(urb->status)) {
++		if (devinfo->suspend_state ==
++			USBOS_SUSPEND_STATE_SUSPEND_PENDING)
++			killed = true;
++
++		if ((urb->status == -ENOENT && (!killed))
++			|| urb->status == -ESHUTDOWN ||
++			urb->status == -ENODEV) {
++			brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++		}
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n");
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++}
++
++static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	struct brcmf_usbreq  *req;
++	int ret;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
++	if (!req) {
++		brcmf_dbg(ERROR, "no req to send\n");
++		return -ENOMEM;
++	}
++	if (!req->urb) {
++		brcmf_dbg(ERROR, "no urb for req %p\n", req);
++		return -ENOBUFS;
++	}
++
++	req->skb = skb;
++	req->devinfo = devinfo;
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
++			  skb->data, skb->len, brcmf_usb_tx_complete, req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (!ret) {
++		brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
++	} else {
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++	}
++
++	return ret;
++}
++
++
++static int brcmf_usb_up(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	u16 ifnum;
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		return 0;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++	}
++	devinfo->activity = true;
++
++	/* Success, indicate devinfo is fully up */
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP);
++
++	if (devinfo->intr_urb) {
++		int ret;
++
++		usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
++			devinfo->intr_pipe,
++			&devinfo->intr,
++			devinfo->intr_size,
++			(usb_complete_t)brcmf_usb_intr_complete,
++			devinfo,
++			devinfo->interval);
++
++		ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++		if (ret) {
++			brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n",
++				  ret);
++			return -EINVAL;
++		}
++	}
++
++	if (devinfo->ctl_urb) {
++		devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
++		devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
++
++		ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
++
++		/* CTL Write */
++		devinfo->ctl_write.bRequestType =
++			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_write.bRequest = 0;
++		devinfo->ctl_write.wValue = cpu_to_le16(0);
++		devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);
++
++		/* CTL Read */
++		devinfo->ctl_read.bRequestType =
++			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++		devinfo->ctl_read.wValue = cpu_to_le16(0);
++		devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
++	}
++	brcmf_usb_rx_fill_all(devinfo);
++	return 0;
++}
++
++static void brcmf_usb_down(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo == NULL)
++		return;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
++		return;
++
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++	if (devinfo->intr_urb)
++		usb_kill_urb(devinfo->intr_urb);
++
++	if (devinfo->ctl_urb)
++		usb_kill_urb(devinfo->ctl_urb);
++
++	if (devinfo->bulk_urb)
++		usb_kill_urb(devinfo->bulk_urb);
++	brcmf_usb_free_q(&devinfo->tx_postq, true);
++
++	brcmf_usb_free_q(&devinfo->rx_postq, true);
++}
++
++static int
++brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time)
++{
++	int ret;
++	int err = 0;
++	int ms = time;
++
++	ret = wait_event_interruptible_timeout(devinfo->wait,
++		devinfo->waitdone == true, (ms * HZ / 1000));
++
++	if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) {
++		brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n",
++			  ret, devinfo->sync_urb_status);
++		err = -EINVAL;
++	}
++	devinfo->waitdone = false;
++	return err;
++}
++
++static void
++brcmf_usb_sync_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->waitdone = true;
++	wake_up_interruptible(&devinfo->wait);
++	devinfo->sync_urb_status = urb->status;
++}
++
++static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
++			     void *buffer, int buflen)
++{
++	int ret = 0;
++	char *tmpbuf;
++	u16 size;
++
++	if ((!devinfo) || (devinfo->ctl_urb == NULL))
++		return false;
++
++	tmpbuf = kmalloc(buflen, GFP_ATOMIC);
++	if (!tmpbuf)
++		return false;
++
++	size = buflen;
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
++		USB_RECIP_INTERFACE;
++	devinfo->ctl_read.bRequest = cmd;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		usb_rcvctrlpipe(devinfo->usbdev, 0),
++		(unsigned char *) &devinfo->ctl_read,
++		(void *) tmpbuf, size,
++		(usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		kfree(tmpbuf);
++		return false;
++	}
++
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	memcpy(buffer, tmpbuf, buflen);
++	kfree(tmpbuf);
++
++	return (ret == 0);
++}
++
++static bool
++brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u32 chipid, chiprev;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return false;
++
++	/* Check if firmware downloaded already by querying runtime ID */
++	id.chip = cpu_to_le32(0xDEAD);
++	brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++		sizeof(struct bootrom_id_le));
++
++	chipid = le32_to_cpu(id.chip);
++	chiprev = le32_to_cpu(id.chiprev);
++
++	if ((chipid & 0x4300) == 0x4300)
++		brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev);
++	else
++		brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev);
++	if (chipid == BRCMF_POSTBOOT_ID) {
++		brcmf_dbg(INFO, "firmware already downloaded\n");
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++		return false;
++	} else {
++		devinfo->bus_pub.devid = chipid;
++		devinfo->bus_pub.chiprev = chiprev;
++	}
++	return true;
++}
++
++static int
++brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u16 wait = 0, wait_time;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	/* Give dongle chance to boot */
++	wait_time = BRCMF_USB_DLIMAGE_SPINWAIT;
++	while (wait < BRCMF_USB_DLIMAGE_LIMIT) {
++		mdelay(wait_time);
++		wait += wait_time;
++		id.chip = cpu_to_le32(0xDEAD);       /* Get the ID */
++		brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++			sizeof(struct bootrom_id_le));
++		if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
++			break;
++	}
++
++	if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
++		brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
++			  wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));
++
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++
++		/* XXX this wait may not be necessary */
++		mdelay(BRCMF_USB_RESETCFG_SPINWAIT);
++		return 0;
++	} else {
++		brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n",
++			  wait);
++		return -EINVAL;
++	}
++}
++
++
++static int
++brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len)
++{
++	int ret;
++
++	if ((devinfo == NULL) || (devinfo->bulk_urb == NULL))
++		return -EINVAL;
++
++	/* Prepare the URB */
++	usb_fill_bulk_urb(devinfo->bulk_urb, devinfo->usbdev,
++			  devinfo->tx_pipe, buffer, len,
++			  (usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET;
++
++	ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC);
++	if (ret) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		return ret;
++	}
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	return ret;
++}
++
++static int
++brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
++{
++	unsigned int sendlen, sent, dllen;
++	char *bulkchunk = NULL, *dlpos;
++	struct rdl_state_le state;
++	u32 rdlstate, rdlbytes;
++	int err = 0;
++	brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen);
++
++	bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
++	if (bulkchunk == NULL) {
++		err = -ENOMEM;
++		goto fail;
++	}
++
++	/* 1) Prepare USB boot loader for runtime image */
++	brcmf_usb_dl_cmd(devinfo, DL_START, &state,
++			 sizeof(struct rdl_state_le));
++
++	rdlstate = le32_to_cpu(state.state);
++	rdlbytes = le32_to_cpu(state.bytes);
++
++	/* 2) Check we are in the Waiting state */
++	if (rdlstate != DL_WAITING) {
++		brcmf_dbg(ERROR, "Failed to DL_START\n");
++		err = -EINVAL;
++		goto fail;
++	}
++	sent = 0;
++	dlpos = fw;
++	dllen = fwlen;
++
++	/* Get chip id and rev */
++	while (rdlbytes != dllen) {
++		/* Wait until the usb device reports it received all
++		 * the bytes we sent */
++		if ((rdlbytes == sent) && (rdlbytes != dllen)) {
++			if ((dllen-sent) < RDL_CHUNK)
++				sendlen = dllen-sent;
++			else
++				sendlen = RDL_CHUNK;
++
++			/* simply avoid having to send a ZLP by ensuring we
++			 * never have an even
++			 * multiple of 64
++			 */
++			if (!(sendlen % 64))
++				sendlen -= 4;
++
++			/* send data */
++			memcpy(bulkchunk, dlpos, sendlen);
++			if (brcmf_usb_dl_send_bulk(devinfo, bulkchunk,
++						   sendlen)) {
++				brcmf_dbg(ERROR, "send_bulk failed\n");
++				err = -EINVAL;
++				goto fail;
++			}
++
++			dlpos += sendlen;
++			sent += sendlen;
++		}
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++				      sizeof(struct rdl_state_le))) {
++			brcmf_dbg(ERROR, "DL_GETSTATE Failed xxxx\n");
++			err = -EINVAL;
++			goto fail;
++		}
++
++		rdlstate = le32_to_cpu(state.state);
++		rdlbytes = le32_to_cpu(state.bytes);
++
++		/* restart if an error is reported */
++		if (rdlstate == DL_BAD_HDR || rdlstate == DL_BAD_CRC) {
++			brcmf_dbg(ERROR, "Bad Hdr or Bad CRC state %d\n",
++				  rdlstate);
++			err = -EINVAL;
++			goto fail;
++		}
++	}
++
++fail:
++	kfree(bulkchunk);
++	brcmf_dbg(TRACE, "err=%d\n", err);
++	return err;
++}
++
++static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
++{
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	err = brcmf_usb_dl_writeimage(devinfo, fw, len);
++	if (err == 0)
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE;
++	else
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING;
++	brcmf_dbg(TRACE, "exit: err=%d\n", err);
++
++	return err;
++}
++
++static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
++{
++	struct rdl_state_le state;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!devinfo)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	/* Check we are runnable */
++	brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++		sizeof(struct rdl_state_le));
++
++	/* Start the image */
++	if (state.state == cpu_to_le32(DL_RUNNABLE)) {
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state,
++			sizeof(struct rdl_state_le)))
++			return -ENODEV;
++		if (brcmf_usb_resetcfg(devinfo))
++			return -ENODEV;
++		/* The Dongle may go for re-enumeration. */
++	} else {
++		brcmf_dbg(ERROR, "Dongle not runnable\n");
++		return -EINVAL;
++	}
++	brcmf_dbg(TRACE, "exit\n");
++	return 0;
++}
++
++static bool brcmf_usb_chip_support(int chipid, int chiprev)
++{
++	switch(chipid) {
++	case 43235:
++	case 43236:
++	case 43238:
++		return (chiprev == 3);
++	default:
++		break;
++	}
++	return false;
++}
++
++static int
++brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
++{
++	int devid, chiprev;
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo == NULL)
++		return -ENODEV;
++
++	devid = devinfo->bus_pub.devid;
++	chiprev = devinfo->bus_pub.chiprev;
++
++	if (!brcmf_usb_chip_support(devid, chiprev)) {
++		brcmf_dbg(ERROR, "unsupported chip %d rev %d\n",
++			  devid, chiprev);
++		return -EINVAL;
++	}
++
++	if (!devinfo->image) {
++		brcmf_dbg(ERROR, "No firmware!\n");
++		return -ENOENT;
++	}
++
++	err = brcmf_usb_dlstart(devinfo,
++		devinfo->image, devinfo->image_len);
++	if (err == 0)
++		err = brcmf_usb_dlrun(devinfo);
++	return err;
++}
++
++
++static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)bus_pub;
++
++	brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
++
++	/* store the image globally */
++	g_image.data = devinfo->image;
++	g_image.len = devinfo->image_len;
++
++	/* free the URBS */
++	brcmf_usb_free_q(&devinfo->rx_freeq, false);
++	brcmf_usb_free_q(&devinfo->tx_freeq, false);
++
++	usb_free_urb(devinfo->intr_urb);
++	usb_free_urb(devinfo->ctl_urb);
++	usb_free_urb(devinfo->bulk_urb);
++
++	kfree(devinfo->tx_reqs);
++	kfree(devinfo->rx_reqs);
++	kfree(devinfo);
++}
++
++#define TRX_MAGIC       0x30524448      /* "HDR0" */
++#define TRX_VERSION     1               /* Version 1 */
++#define TRX_MAX_LEN     0x3B0000        /* Max length */
++#define TRX_NO_HEADER   1               /* Do not write TRX header */
++#define TRX_MAX_OFFSET  3               /* Max number of individual files */
++#define TRX_UNCOMP_IMAGE        0x20    /* Trx contains uncompressed image */
++
++struct trx_header_le {
++	__le32 magic;		/* "HDR0" */
++	__le32 len;		/* Length of file including header */
++	__le32 crc32;		/* CRC from flag_version to end of file */
++	__le32 flag_version;	/* 0:15 flags, 16:31 version */
++	__le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
++					 * header */
++};
++
++static int check_file(const u8 *headers)
++{
++	struct trx_header_le *trx;
++	int actual_len = -1;
++
++	/* Extract trx header */
++	trx = (struct trx_header_le *) headers;
++	if (trx->magic != cpu_to_le32(TRX_MAGIC))
++		return -1;
++
++	headers += sizeof(struct trx_header_le);
++
++	if (le32_to_cpu(trx->flag_version) & TRX_UNCOMP_IMAGE) {
++		actual_len = le32_to_cpu(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]);
++		return actual_len + sizeof(struct trx_header_le);
++	}
++	return -1;
++}
++
++static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
++{
++	s8 *fwname;
++	const struct firmware *fw;
++	int err;
++
++	devinfo->image = g_image.data;
++	devinfo->image_len = g_image.len;
++
++	/*
++	 * if we have an image we can leave here.
++	 */
++	if (devinfo->image)
++		return 0;
++
++	fwname = BRCMF_USB_43236_FW_NAME;
++
++	err = request_firmware(&fw, fwname, devinfo->dev);
++	if (!fw) {
++		brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname);
++		return err;
++	}
++	if (check_file(fw->data) < 0) {
++		brcmf_dbg(ERROR, "invalid firmware %s\n", fwname);
++		return -EINVAL;
++	}
++
++	devinfo->image = vmalloc(fw->size); /* plus nvram */
++	if (!devinfo->image)
++		return -ENOMEM;
++
++	memcpy(devinfo->image, fw->data, fw->size);
++	devinfo->image_len = fw->size;
++
++	release_firmware(fw);
++	return 0;
++}
++
++
++static
++struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo;
++
++	devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
++	if (devinfo == NULL)
++		return NULL;
++
++	devinfo->bus_pub.nrxq = nrxq;
++	devinfo->rx_low_watermark = nrxq / 2;
++	devinfo->bus_pub.devinfo = devinfo;
++	devinfo->bus_pub.ntxq = ntxq;
++
++	/* flow control when too many tx urbs posted */
++	devinfo->tx_low_watermark = ntxq / 4;
++	devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
++	devinfo->dev = dev;
++	devinfo->usbdev = usbdev_probe_info.usb;
++	devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
++	devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
++	devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
++	devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
++
++	devinfo->interval = usbdev_probe_info.interval;
++	devinfo->intr_size = usbdev_probe_info.intr_size;
++
++	memcpy(&devinfo->probe_info, &usbdev_probe_info,
++		sizeof(struct brcmf_usb_probe_info));
++	devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
++
++	/* Initialize other structure content */
++	init_waitqueue_head(&devinfo->ioctl_resp_wait);
++
++	/* Initialize the spinlocks */
++	spin_lock_init(&devinfo->qlock);
++
++	INIT_LIST_HEAD(&devinfo->rx_freeq);
++	INIT_LIST_HEAD(&devinfo->rx_postq);
++
++	INIT_LIST_HEAD(&devinfo->tx_freeq);
++	INIT_LIST_HEAD(&devinfo->tx_postq);
++
++	devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
++	if (!devinfo->rx_reqs)
++		goto error;
++
++	devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
++	if (!devinfo->tx_reqs)
++		goto error;
++
++	devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->intr_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n");
++		goto error;
++	}
++	devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->ctl_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
++		goto error;
++	}
++	devinfo->rxctl_deferrespok = 0;
++
++	devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->bulk_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
++		goto error;
++	}
++
++	init_waitqueue_head(&devinfo->wait);
++	if (!brcmf_usb_dlneeded(devinfo))
++		return &devinfo->bus_pub;
++
++	brcmf_dbg(TRACE, "start fw downloading\n");
++	if (brcmf_usb_get_fw(devinfo))
++		goto error;
++
++	if (brcmf_usb_fw_download(devinfo))
++		goto error;
++
++	return &devinfo->bus_pub;
++
++error:
++	brcmf_dbg(ERROR, "failed!\n");
++	brcmf_usb_detach(&devinfo->bus_pub);
++	return NULL;
++}
++
++static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
++				u32 bustype, u32 hdrlen)
++{
++	struct brcmf_bus *bus = NULL;
++	struct brcmf_usbdev *bus_pub = NULL;
++	int ret;
++
++
++	bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
++	if (!bus_pub) {
++		ret = -ENODEV;
++		goto fail;
++	}
++
++	bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
++	if (!bus) {
++		ret = -ENOMEM;
++		goto fail;
++	}
++
++	bus_pub->bus = bus;
++	bus->brcmf_bus_txdata = brcmf_usb_tx;
++	bus->brcmf_bus_init = brcmf_usb_up;
++	bus->brcmf_bus_stop = brcmf_usb_down;
++	bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
++	bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
++	bus->type = bustype;
++	bus->bus_priv.usb = bus_pub;
++	dev_set_drvdata(dev, bus);
++
++	/* Attach to the common driver interface */
++	ret = brcmf_attach(hdrlen, dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "dhd_attach failed\n");
++		goto fail;
++	}
++
++	ret = brcmf_bus_start(dev);
++	if (ret == -ENOLINK) {
++		brcmf_dbg(ERROR, "dongle is not responding\n");
++		brcmf_detach(dev);
++		goto fail;
++	}
++
++	return 0;
++fail:
++	/* Release resources in reverse order */
++	if (bus_pub)
++		brcmf_usb_detach(bus_pub);
++	kfree(bus);
++	return ret;
++}
++
++static void
++brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
++{
++	if (!bus_pub)
++		return;
++	brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
++
++	brcmf_detach(bus_pub->devinfo->dev);
++	kfree(bus_pub->bus);
++	brcmf_usb_detach(bus_pub);
++
++}
++
++static int
++brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++	int ep;
++	struct usb_endpoint_descriptor *endpoint;
++	int ret = 0;
++	struct usb_device *usb = interface_to_usbdev(intf);
++	int num_of_eps;
++	u8 endpoint_num;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	usbdev_probe_info.usb = usb;
++	usbdev_probe_info.intf = intf;
++
++	if (id != NULL) {
++		usbdev_probe_info.vid = id->idVendor;
++		usbdev_probe_info.pid = id->idProduct;
++	}
++
++	usb_set_intfdata(intf, &usbdev_probe_info);
++
++	/* Check that the device supports only one configuration */
++	if (usb->descriptor.bNumConfigurations != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
++		ret = -1;
++		goto fail;
++	}
++
++	/*
++	 * Only the BDC interface configuration is supported:
++	 *	Device class: USB_CLASS_VENDOR_SPEC
++	 *	if0 class: USB_CLASS_VENDOR_SPEC
++	 *	if0/ep0: control
++	 *	if0/ep1: bulk in
++	 *	if0/ep2: bulk out (ok if swapped with bulk in)
++	 */
++	if (CONFIGDESC(usb)->bNumInterfaces != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check interface */
++	if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
++		brcmf_dbg(ERROR, "invalid control interface: class %d, subclass %d, proto %d\n",
++			  IFDESC(usb, CONTROL_IF).bInterfaceClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceProtocol);
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check control endpoint */
++	endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
++		!= USB_ENDPOINT_XFER_INT) {
++		brcmf_dbg(ERROR, "invalid control endpoint %d\n",
++			  endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
++		ret = -1;
++		goto fail;
++	}
++
++	endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
++	usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
++
++	usbdev_probe_info.rx_pipe = 0;
++	usbdev_probe_info.rx_pipe2 = 0;
++	usbdev_probe_info.tx_pipe = 0;
++	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
++
++	/* Check data endpoints and get pipes */
++	for (ep = 1; ep <= num_of_eps; ep++) {
++		endpoint = &IFEPDESC(usb, BULK_IF, ep);
++		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
++		    USB_ENDPOINT_XFER_BULK) {
++			brcmf_dbg(ERROR, "invalid data endpoint %d\n", ep);
++			ret = -1;
++			goto fail;
++		}
++
++		endpoint_num = endpoint->bEndpointAddress &
++			       USB_ENDPOINT_NUMBER_MASK;
++		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
++			== USB_DIR_IN) {
++			if (!usbdev_probe_info.rx_pipe) {
++				usbdev_probe_info.rx_pipe =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			} else {
++				usbdev_probe_info.rx_pipe2 =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			}
++		} else {
++			usbdev_probe_info.tx_pipe =
++					usb_sndbulkpipe(usb, endpoint_num);
++		}
++	}
++
++	/* Allocate interrupt URB and data buffer */
++	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
++	if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
++		usbdev_probe_info.intr_size = 8;
++	else
++		usbdev_probe_info.intr_size = 4;
++
++	usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
++
++	usbdev_probe_info.device_speed = usb->speed;
++	if (usb->speed == USB_SPEED_HIGH)
++		brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
++	else
++		brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
++
++	ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
++	if (ret)
++		goto fail;
++
++	/* Success */
++	return 0;
++
++fail:
++	brcmf_dbg(ERROR, "failed with errno %d\n", ret);
++	usb_set_intfdata(intf, NULL);
++	return ret;
++
++}
++
++static void
++brcmf_usb_disconnect(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++
++	brcmf_dbg(TRACE, "enter\n");
++	brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
++	usb_set_intfdata(intf, NULL);
++}
++
++/*
++ *	only need to signal the bus being down and update the suspend state.
++ */
++static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
++	return 0;
++}
++
++/*
++ *	mark suspend state active and crank up the bus.
++ */
++static int brcmf_usb_resume(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
++	brcmf_bus_start(&usb->dev);
++	return 0;
++}
++
++#define BRCMF_USB_VENDOR_ID_BROADCOM	0x0a5c
++#define BRCMF_USB_DEVICE_ID_43236	0xbd17
++#define BRCMF_USB_DEVICE_ID_BCMFW	0x0bdc
++
++static struct usb_device_id brcmf_usb_devid_table[] = {
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
++	/* special entry for device with firmware loaded and running */
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
++	{ }
++};
++MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
++MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
++
++/* TODO: suspend and resume entries */
++static struct usb_driver brcmf_usbdrvr = {
++	.name = KBUILD_MODNAME,
++	.probe = brcmf_usb_probe,
++	.disconnect = brcmf_usb_disconnect,
++	.id_table = brcmf_usb_devid_table,
++	.suspend = brcmf_usb_suspend,
++	.resume = brcmf_usb_resume,
++	.supports_autosuspend = 1,
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
++	.disable_hub_initiated_lpm = 1,
++#endif
++};
++
++void brcmf_usb_exit(void)
++{
++	usb_deregister(&brcmf_usbdrvr);
++	vfree(g_image.data);
++	g_image.data = NULL;
++	g_image.len = 0;
++}
++
++void brcmf_usb_init(void)
++{
++	usb_register(&brcmf_usbdrvr);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+new file mode 100644
+index 0000000..acfa5e8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef BRCMFMAC_USB_H
++#define BRCMFMAC_USB_H
++
++enum brcmf_usb_state {
++	BCMFMAC_USB_STATE_DL_PENDING,
++	BCMFMAC_USB_STATE_DL_DONE,
++	BCMFMAC_USB_STATE_UP,
++	BCMFMAC_USB_STATE_DOWN,
++	BCMFMAC_USB_STATE_PNP_FWDL,
++	BCMFMAC_USB_STATE_DISCONNECT,
++	BCMFMAC_USB_STATE_SLEEP
++};
++
++enum brcmf_usb_pnp_state {
++	BCMFMAC_USB_PNP_DISCONNECT,
++	BCMFMAC_USB_PNP_SLEEP,
++	BCMFMAC_USB_PNP_RESUME,
++};
++
++struct brcmf_stats {
++	u32 tx_ctlpkts;
++	u32 tx_ctlerrs;
++	u32 rx_ctlpkts;
++	u32 rx_ctlerrs;
++};
++
++struct brcmf_usbdev {
++	struct brcmf_bus *bus;
++	struct brcmf_usbdev_info *devinfo;
++	enum brcmf_usb_state state;
++	struct brcmf_stats stats;
++	int ntxq, nrxq, rxsize;
++	u32 bus_mtu;
++	int devid;
++	int chiprev; /* chip revsion number */
++};
++
++/* IO Request Block (IRB) */
++struct brcmf_usbreq {
++	struct list_head list;
++	struct brcmf_usbdev_info *devinfo;
++	struct urb *urb;
++	struct sk_buff  *skb;
++};
++
++#endif /* BRCMFMAC_USB_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+new file mode 100644
+index 0000000..0a35c51
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _USB_RDL_H
++#define _USB_RDL_H
++
++/* Control messages: bRequest values */
++#define DL_GETSTATE	0	/* returns the rdl_state_t struct */
++#define DL_CHECK_CRC	1	/* currently unused */
++#define DL_GO		2	/* execute downloaded image */
++#define DL_START	3	/* initialize dl state */
++#define DL_REBOOT	4	/* reboot the device in 2 seconds */
++#define DL_GETVER	5	/* returns the bootrom_id_t struct */
++#define DL_GO_PROTECTED	6	/* execute the downloaded code and set reset
++				 * event to occur in 2 seconds.  It is the
++				 * responsibility of the downloaded code to
++				 * clear this event
++				 */
++#define DL_EXEC		7	/* jump to a supplied address */
++#define DL_RESETCFG	8	/* To support single enum on dongle
++				 * - Not used by bootloader
++				 */
++#define DL_DEFER_RESP_OK 9	/* Potentially defer the response to setup
++				 * if resp unavailable
++				 */
++
++/* states */
++#define DL_WAITING	0	/* waiting to rx first pkt */
++#define DL_READY	1	/* hdr was good, waiting for more of the
++				 * compressed image */
++#define DL_BAD_HDR	2	/* hdr was corrupted */
++#define DL_BAD_CRC	3	/* compressed image was corrupted */
++#define DL_RUNNABLE	4	/* download was successful,waiting for go cmd */
++#define DL_START_FAIL	5	/* failed to initialize correctly */
++#define DL_NVRAM_TOOBIG	6	/* host specified nvram data exceeds DL_NVRAM
++				 * value */
++#define DL_IMAGE_TOOBIG	7	/* download image too big (exceeds DATA_START
++				 *  for rdl) */
++
++struct rdl_state_le {
++	__le32 state;
++	__le32 bytes;
++};
++
++struct bootrom_id_le {
++	__le32 chip;	/* Chip id */
++	__le32 chiprev;	/* Chip rev */
++	__le32 ramsize;	/* Size of  RAM */
++	__le32 remapbase;	/* Current remap base address */
++	__le32 boardtype;	/* Type of board */
++	__le32 boardrev;	/* Board revision */
++};
++
++#define RDL_CHUNK	1500  /* size of each dl transfer */
++
++#define TRX_OFFSETS_DLFWLEN_IDX	0
++#define TRX_OFFSETS_JUMPTO_IDX	1
++#define TRX_OFFSETS_NVM_LEN_IDX	2
++
++#define TRX_OFFSETS_DLBASE_IDX  0
++
++#endif  /* _USB_RDL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+new file mode 100644
+index 0000000..65e48d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+@@ -0,0 +1,3881 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/if_arp.h>
++#include <linux/sched.h>
++#include <linux/kthread.h>
++#include <linux/netdevice.h>
++#include <linux/bitops.h>
++#include <linux/etherdevice.h>
++#include <linux/ieee80211.h>
++#include <linux/uaccess.h>
++#include <net/cfg80211.h>
++
++#include <brcmu_utils.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include "dhd.h"
++#include "wl_cfg80211.h"
++
++#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
++	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
++
++static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++
++static u32 brcmf_dbg_level = WL_DBG_ERR;
++
++static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
++{
++	dev->driver_data = data;
++}
++
++static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
++{
++	void *data = NULL;
++
++	if (dev)
++		data = dev->driver_data;
++	return data;
++}
++
++static
++struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
++	return ci->cfg_priv;
++}
++
++static bool check_sys_up(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("device is not ready : status (%d)\n",
++			(int)cfg_priv->status);
++		return false;
++	}
++	return true;
++}
++
++#define CHAN2G(_channel, _freq, _flags) {			\
++	.band			= IEEE80211_BAND_2GHZ,		\
++	.center_freq		= (_freq),			\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define CHAN5G(_channel, _flags) {				\
++	.band			= IEEE80211_BAND_5GHZ,		\
++	.center_freq		= 5000 + (5 * (_channel)),	\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
++#define RATETAB_ENT(_rateid, _flags) \
++	{                                                               \
++		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
++		.hw_value       = (_rateid),                            \
++		.flags          = (_flags),                             \
++	}
++
++static struct ieee80211_rate __wl_rates[] = {
++	RATETAB_ENT(BRCM_RATE_1M, 0),
++	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_6M, 0),
++	RATETAB_ENT(BRCM_RATE_9M, 0),
++	RATETAB_ENT(BRCM_RATE_12M, 0),
++	RATETAB_ENT(BRCM_RATE_18M, 0),
++	RATETAB_ENT(BRCM_RATE_24M, 0),
++	RATETAB_ENT(BRCM_RATE_36M, 0),
++	RATETAB_ENT(BRCM_RATE_48M, 0),
++	RATETAB_ENT(BRCM_RATE_54M, 0),
++};
++
++#define wl_a_rates		(__wl_rates + 4)
++#define wl_a_rates_size	8
++#define wl_g_rates		(__wl_rates + 0)
++#define wl_g_rates_size	12
++
++static struct ieee80211_channel __wl_2ghz_channels[] = {
++	CHAN2G(1, 2412, 0),
++	CHAN2G(2, 2417, 0),
++	CHAN2G(3, 2422, 0),
++	CHAN2G(4, 2427, 0),
++	CHAN2G(5, 2432, 0),
++	CHAN2G(6, 2437, 0),
++	CHAN2G(7, 2442, 0),
++	CHAN2G(8, 2447, 0),
++	CHAN2G(9, 2452, 0),
++	CHAN2G(10, 2457, 0),
++	CHAN2G(11, 2462, 0),
++	CHAN2G(12, 2467, 0),
++	CHAN2G(13, 2472, 0),
++	CHAN2G(14, 2484, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_a_channels[] = {
++	CHAN5G(34, 0), CHAN5G(36, 0),
++	CHAN5G(38, 0), CHAN5G(40, 0),
++	CHAN5G(42, 0), CHAN5G(44, 0),
++	CHAN5G(46, 0), CHAN5G(48, 0),
++	CHAN5G(52, 0), CHAN5G(56, 0),
++	CHAN5G(60, 0), CHAN5G(64, 0),
++	CHAN5G(100, 0), CHAN5G(104, 0),
++	CHAN5G(108, 0), CHAN5G(112, 0),
++	CHAN5G(116, 0), CHAN5G(120, 0),
++	CHAN5G(124, 0), CHAN5G(128, 0),
++	CHAN5G(132, 0), CHAN5G(136, 0),
++	CHAN5G(140, 0), CHAN5G(149, 0),
++	CHAN5G(153, 0), CHAN5G(157, 0),
++	CHAN5G(161, 0), CHAN5G(165, 0),
++	CHAN5G(184, 0), CHAN5G(188, 0),
++	CHAN5G(192, 0), CHAN5G(196, 0),
++	CHAN5G(200, 0), CHAN5G(204, 0),
++	CHAN5G(208, 0), CHAN5G(212, 0),
++	CHAN5G(216, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_n_channels[] = {
++	CHAN5G(32, 0), CHAN5G(34, 0),
++	CHAN5G(36, 0), CHAN5G(38, 0),
++	CHAN5G(40, 0), CHAN5G(42, 0),
++	CHAN5G(44, 0), CHAN5G(46, 0),
++	CHAN5G(48, 0), CHAN5G(50, 0),
++	CHAN5G(52, 0), CHAN5G(54, 0),
++	CHAN5G(56, 0), CHAN5G(58, 0),
++	CHAN5G(60, 0), CHAN5G(62, 0),
++	CHAN5G(64, 0), CHAN5G(66, 0),
++	CHAN5G(68, 0), CHAN5G(70, 0),
++	CHAN5G(72, 0), CHAN5G(74, 0),
++	CHAN5G(76, 0), CHAN5G(78, 0),
++	CHAN5G(80, 0), CHAN5G(82, 0),
++	CHAN5G(84, 0), CHAN5G(86, 0),
++	CHAN5G(88, 0), CHAN5G(90, 0),
++	CHAN5G(92, 0), CHAN5G(94, 0),
++	CHAN5G(96, 0), CHAN5G(98, 0),
++	CHAN5G(100, 0), CHAN5G(102, 0),
++	CHAN5G(104, 0), CHAN5G(106, 0),
++	CHAN5G(108, 0), CHAN5G(110, 0),
++	CHAN5G(112, 0), CHAN5G(114, 0),
++	CHAN5G(116, 0), CHAN5G(118, 0),
++	CHAN5G(120, 0), CHAN5G(122, 0),
++	CHAN5G(124, 0), CHAN5G(126, 0),
++	CHAN5G(128, 0), CHAN5G(130, 0),
++	CHAN5G(132, 0), CHAN5G(134, 0),
++	CHAN5G(136, 0), CHAN5G(138, 0),
++	CHAN5G(140, 0), CHAN5G(142, 0),
++	CHAN5G(144, 0), CHAN5G(145, 0),
++	CHAN5G(146, 0), CHAN5G(147, 0),
++	CHAN5G(148, 0), CHAN5G(149, 0),
++	CHAN5G(150, 0), CHAN5G(151, 0),
++	CHAN5G(152, 0), CHAN5G(153, 0),
++	CHAN5G(154, 0), CHAN5G(155, 0),
++	CHAN5G(156, 0), CHAN5G(157, 0),
++	CHAN5G(158, 0), CHAN5G(159, 0),
++	CHAN5G(160, 0), CHAN5G(161, 0),
++	CHAN5G(162, 0), CHAN5G(163, 0),
++	CHAN5G(164, 0), CHAN5G(165, 0),
++	CHAN5G(166, 0), CHAN5G(168, 0),
++	CHAN5G(170, 0), CHAN5G(172, 0),
++	CHAN5G(174, 0), CHAN5G(176, 0),
++	CHAN5G(178, 0), CHAN5G(180, 0),
++	CHAN5G(182, 0), CHAN5G(184, 0),
++	CHAN5G(186, 0), CHAN5G(188, 0),
++	CHAN5G(190, 0), CHAN5G(192, 0),
++	CHAN5G(194, 0), CHAN5G(196, 0),
++	CHAN5G(198, 0), CHAN5G(200, 0),
++	CHAN5G(202, 0), CHAN5G(204, 0),
++	CHAN5G(206, 0), CHAN5G(208, 0),
++	CHAN5G(210, 0), CHAN5G(212, 0),
++	CHAN5G(214, 0), CHAN5G(216, 0),
++	CHAN5G(218, 0), CHAN5G(220, 0),
++	CHAN5G(222, 0), CHAN5G(224, 0),
++	CHAN5G(226, 0), CHAN5G(228, 0),
++};
++
++static struct ieee80211_supported_band __wl_band_2ghz = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = __wl_2ghz_channels,
++	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
++	.bitrates = wl_g_rates,
++	.n_bitrates = wl_g_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_a = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_a_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_n = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_n_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static const u32 __wl_cipher_suites[] = {
++	WLAN_CIPHER_SUITE_WEP40,
++	WLAN_CIPHER_SUITE_WEP104,
++	WLAN_CIPHER_SUITE_TKIP,
++	WLAN_CIPHER_SUITE_CCMP,
++	WLAN_CIPHER_SUITE_AES_CMAC,
++};
++
++/* tag_ID/length/value_buffer tuple */
++struct brcmf_tlv {
++	u8 id;
++	u8 len;
++	u8 data[1];
++};
++
++/* Quarter dBm units to mW
++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
++ * Table is offset so the last entry is largest mW value that fits in
++ * a u16.
++ */
++
++#define QDBM_OFFSET 153		/* Offset for first entry */
++#define QDBM_TABLE_LEN 40	/* Table size */
++
++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
++ */
++#define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
++
++/* Largest mW value that will round down to the last table entry,
++ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
++ * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
++ */
++#define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
++
++static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
++/* qdBm:	+0	+1	+2	+3	+4	+5	+6	+7 */
++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
++};
++
++static u16 brcmf_qdbm_to_mw(u8 qdbm)
++{
++	uint factor = 1;
++	int idx = qdbm - QDBM_OFFSET;
++
++	if (idx >= QDBM_TABLE_LEN)
++		/* clamp to max u16 mW value */
++		return 0xFFFF;
++
++	/* scale the qdBm index up to the range of the table 0-40
++	 * where an offset of 40 qdBm equals a factor of 10 mW.
++	 */
++	while (idx < 0) {
++		idx += 40;
++		factor *= 10;
++	}
++
++	/* return the mW value scaled down to the correct factor of 10,
++	 * adding in factor/2 to get proper rounding.
++	 */
++	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
++}
++
++static u8 brcmf_mw_to_qdbm(u16 mw)
++{
++	u8 qdbm;
++	int offset;
++	uint mw_uint = mw;
++	uint boundary;
++
++	/* handle boundary case */
++	if (mw_uint <= 1)
++		return 0;
++
++	offset = QDBM_OFFSET;
++
++	/* move mw into the range of the table */
++	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
++		mw_uint *= 10;
++		offset -= 40;
++	}
++
++	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
++		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
++						    nqdBm_to_mW_map[qdbm]) / 2;
++		if (mw_uint < boundary)
++			break;
++	}
++
++	qdbm += (u8) offset;
++
++	return qdbm;
++}
++
++/* function for reading/writing a single u32 from/to the dongle */
++static int
++brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
++{
++	int err;
++	__le32 par_le = cpu_to_le32(*par);
++
++	err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
++	*par = le32_to_cpu(par_le);
++
++	return err;
++}
++
++static void convert_key_from_CPU(struct brcmf_wsec_key *key,
++				 struct brcmf_wsec_key_le *key_le)
++{
++	key_le->index = cpu_to_le32(key->index);
++	key_le->len = cpu_to_le32(key->len);
++	key_le->algo = cpu_to_le32(key->algo);
++	key_le->flags = cpu_to_le32(key->flags);
++	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
++	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
++	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
++	memcpy(key_le->data, key->data, sizeof(key->data));
++	memcpy(key_le->ea, key->ea, sizeof(key->ea));
++}
++
++static int send_key_to_dongle(struct net_device *ndev,
++			      struct brcmf_wsec_key *key)
++{
++	int err;
++	struct brcmf_wsec_key_le key_le;
++
++	convert_key_from_CPU(key, &key_le);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
++	if (err)
++		WL_ERR("WLC_SET_KEY error (%d)\n", err);
++	return err;
++}
++
++static s32
++brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
++			 enum nl80211_iftype type, u32 *flags,
++			 struct vif_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct wireless_dev *wdev;
++	s32 infra = 0;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this type\n",
++		       type);
++		return -EOPNOTSUPP;
++	case NL80211_IFTYPE_ADHOC:
++		cfg_priv->conf->mode = WL_MODE_IBSS;
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		cfg_priv->conf->mode = WL_MODE_BSS;
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		err = -EAGAIN;
++	} else {
++		wdev = ndev->ieee80211_ptr;
++		wdev->iftype = type;
++	}
++
++	WL_INFO("IF Type = %s\n",
++		(cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
++
++done:
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
++{
++	s8 buf[BRCMF_DCMD_SMLEN];
++	u32 len;
++	s32 err = 0;
++	__le32 val_le;
++
++	val_le = cpu_to_le32(val);
++	len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
++			    sizeof(buf));
++	BUG_ON(!len);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	return err;
++}
++
++static s32
++brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
++{
++	union {
++		s8 buf[BRCMF_DCMD_SMLEN];
++		__le32 val;
++	} var;
++	u32 len;
++	u32 data_null;
++	s32 err = 0;
++
++	len =
++	    brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
++			sizeof(var.buf));
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	*retval = le32_to_cpu(var.val);
++
++	return err;
++}
++
++static void brcmf_set_mpc(struct net_device *ndev, int mpc)
++{
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
++		if (err) {
++			WL_ERR("fail to set mpc\n");
++			return;
++		}
++		WL_INFO("MPC : %d\n", mpc);
++	}
++}
++
++static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
++			  struct brcmf_ssid *ssid)
++{
++	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
++	params_le->bss_type = DOT11_BSSTYPE_ANY;
++	params_le->scan_type = 0;
++	params_le->channel_num = 0;
++	params_le->nprobes = cpu_to_le32(-1);
++	params_le->active_time = cpu_to_le32(-1);
++	params_le->passive_time = cpu_to_le32(-1);
++	params_le->home_time = cpu_to_le32(-1);
++	if (ssid && ssid->SSID_len)
++		memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
++}
++
++static s32
++brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
++}
++
++static s32
++brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
++}
++
++static s32
++brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
++		struct brcmf_ssid *ssid, u16 action)
++{
++	s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
++			  offsetof(struct brcmf_iscan_params_le, params_le);
++	struct brcmf_iscan_params_le *params;
++	s32 err = 0;
++
++	if (ssid && ssid->SSID_len)
++		params_size += sizeof(struct brcmf_ssid);
++	params = kzalloc(params_size, GFP_KERNEL);
++	if (!params)
++		return -ENOMEM;
++	BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
++
++	wl_iscan_prep(&params->params_le, ssid);
++
++	params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
++	params->action = cpu_to_le16(action);
++	params->scan_duration = cpu_to_le16(0);
++
++	err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
++				     iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
++	if (err) {
++		if (err == -EBUSY)
++			WL_INFO("system busy : iscan canceled\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++
++	kfree(params);
++	return err;
++}
++
++static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_ssid ssid;
++	__le32 passive_scan;
++	s32 err = 0;
++
++	/* Broadcast scan by default */
++	memset(&ssid, 0, sizeof(ssid));
++
++	iscan->state = WL_ISCAN_STATE_SCANING;
++
++	passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
++			&passive_scan, sizeof(passive_scan));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	brcmf_set_mpc(ndev, 0);
++	cfg_priv->iscan_kickstart = true;
++	err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
++	if (err) {
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->iscan_kickstart = false;
++		return err;
++	}
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++	return err;
++}
++
++static s32
++__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		   struct cfg80211_scan_request *request,
++		   struct cfg80211_ssid *this_ssid)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct cfg80211_ssid *ssids;
++	struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
++	__le32 passive_scan;
++	bool iscan_req;
++	bool spec_scan;
++	s32 err = 0;
++	u32 SSID_len;
++
++	if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
++		WL_ERR("Scanning being aborted : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		WL_ERR("Connecting : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++
++	iscan_req = false;
++	spec_scan = false;
++	if (request) {
++		/* scan bss */
++		ssids = request->ssids;
++		if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
++			iscan_req = true;
++	} else {
++		/* scan in ibss */
++		/* we don't do iscan in ibss */
++		ssids = this_ssid;
++	}
++
++	cfg_priv->scan_request = request;
++	set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	if (iscan_req) {
++		err = brcmf_do_iscan(cfg_priv);
++		if (!err)
++			return err;
++		else
++			goto scan_out;
++	} else {
++		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
++		       ssids->ssid, ssids->ssid_len);
++		memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
++		SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
++		sr->ssid_le.SSID_len = cpu_to_le32(0);
++		if (SSID_len) {
++			memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
++			sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
++			spec_scan = true;
++		} else {
++			WL_SCAN("Broadcast scan\n");
++		}
++
++		passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
++				&passive_scan, sizeof(passive_scan));
++		if (err) {
++			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
++			goto scan_out;
++		}
++		brcmf_set_mpc(ndev, 0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
++				      sizeof(sr->ssid_le));
++		if (err) {
++			if (err == -EBUSY)
++				WL_INFO("system busy : scan for \"%s\" "
++					"canceled\n", sr->ssid_le.SSID);
++			else
++				WL_ERR("WLC_SCAN error (%d)\n", err);
++
++			brcmf_set_mpc(ndev, 1);
++			goto scan_out;
++		}
++	}
++
++	return 0;
++
++scan_out:
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	cfg_priv->scan_request = NULL;
++	return err;
++}
++
++static s32
++brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		 struct cfg80211_scan_request *request)
++{
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
++	if (err)
++		WL_ERR("scan error (%d)\n", err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
++{
++	s32 err = 0;
++	u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
++
++	err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
++	if (err) {
++		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
++		return err;
++	}
++	return err;
++}
++
++static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
++	    (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
++		cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
++		err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
++	    (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
++		cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
++		err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_LONG
++	    && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
++		cfg_priv->conf->retry_long = wiphy->retry_long;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_SHORT
++	    && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
++		cfg_priv->conf->retry_short = wiphy->retry_short;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
++		if (!err)
++			goto done;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
++{
++	switch (item) {
++	case WL_PROF_SEC:
++		return &cfg_priv->profile->sec;
++	case WL_PROF_BSSID:
++		return &cfg_priv->profile->bssid;
++	case WL_PROF_SSID:
++		return &cfg_priv->profile->ssid;
++	}
++	WL_ERR("invalid item (%d)\n", item);
++	return NULL;
++}
++
++static s32
++brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
++		  const struct brcmf_event_msg *e, void *data, s32 item)
++{
++	s32 err = 0;
++	struct brcmf_ssid *ssid;
++
++	switch (item) {
++	case WL_PROF_SSID:
++		ssid = (struct brcmf_ssid *) data;
++		memset(cfg_priv->profile->ssid.SSID, 0,
++		       sizeof(cfg_priv->profile->ssid.SSID));
++		memcpy(cfg_priv->profile->ssid.SSID,
++		       ssid->SSID, ssid->SSID_len);
++		cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
++		break;
++	case WL_PROF_BSSID:
++		if (data)
++			memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
++		else
++			memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
++		break;
++	case WL_PROF_SEC:
++		memcpy(&cfg_priv->profile->sec, data,
++		       sizeof(cfg_priv->profile->sec));
++		break;
++	case WL_PROF_BEACONINT:
++		cfg_priv->profile->beacon_interval = *(u16 *)data;
++		break;
++	case WL_PROF_DTIMPERIOD:
++		cfg_priv->profile->dtim_period = *(u8 *)data;
++		break;
++	default:
++		WL_ERR("unsupported item (%d)\n", item);
++		err = -EOPNOTSUPP;
++		break;
++	}
++
++	return err;
++}
++
++static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
++{
++	memset(prof, 0, sizeof(*prof));
++}
++
++static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
++	size_t *join_params_size)
++{
++	u16 chanspec = 0;
++
++	if (ch != 0) {
++		if (ch <= CH_MAX_2G_CHANNEL)
++			chanspec |= WL_CHANSPEC_BAND_2G;
++		else
++			chanspec |= WL_CHANSPEC_BAND_5G;
++
++		chanspec |= WL_CHANSPEC_BW_20;
++		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
++
++		*join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
++				     sizeof(u16);
++
++		chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
++		join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
++		join_params->params_le.chanspec_num = cpu_to_le32(1);
++
++		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
++			"channel %d, chanspec %#X\n",
++			chanspec, ch, chanspec);
++	}
++}
++
++static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = NULL;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->link_up) {
++		ndev = cfg_to_ndev(cfg_priv);
++		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
++		if (err)
++			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
++		cfg_priv->link_up = false;
++	}
++	WL_TRACE("Exit\n");
++}
++
++static s32
++brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_ibss_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_join_params join_params;
++	size_t join_params_size = 0;
++	s32 err = 0;
++	s32 wsec = 0;
++	s32 bcnprd;
++	struct brcmf_ssid ssid;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (params->ssid)
++		WL_CONN("SSID: %s\n", params->ssid);
++	else {
++		WL_CONN("SSID: NULL, Not supported\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (params->bssid)
++		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
++		params->bssid[0], params->bssid[1], params->bssid[2],
++		params->bssid[3], params->bssid[4], params->bssid[5]);
++	else
++		WL_CONN("No BSSID specified\n");
++
++	if (params->channel)
++		WL_CONN("channel: %d\n", params->channel->center_freq);
++	else
++		WL_CONN("no channel specified\n");
++
++	if (params->channel_fixed)
++		WL_CONN("fixed channel required\n");
++	else
++		WL_CONN("no fixed channel required\n");
++
++	if (params->ie && params->ie_len)
++		WL_CONN("ie len: %d\n", params->ie_len);
++	else
++		WL_CONN("no ie specified\n");
++
++	if (params->beacon_interval)
++		WL_CONN("beacon interval: %d\n", params->beacon_interval);
++	else
++		WL_CONN("no beacon interval specified\n");
++
++	if (params->basic_rates)
++		WL_CONN("basic rates: %08X\n", params->basic_rates);
++	else
++		WL_CONN("no basic rates specified\n");
++
++	if (params->privacy)
++		WL_CONN("privacy required\n");
++	else
++		WL_CONN("no privacy required\n");
++
++	/* Configure Privacy for starter */
++	if (params->privacy)
++		wsec |= WEP_ENABLED;
++
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("wsec failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure Beacon Interval for starter */
++	if (params->beacon_interval)
++		bcnprd = params->beacon_interval;
++	else
++		bcnprd = 100;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
++	if (err) {
++		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure required join parameter */
++	memset(&join_params, 0, sizeof(struct brcmf_join_params));
++
++	/* SSID */
++	ssid.SSID_len = min_t(u32, params->ssid_len, 32);
++	memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
++	memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	join_params_size = sizeof(join_params.ssid_le);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	/* BSSID */
++	if (params->bssid) {
++		memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
++		join_params_size = sizeof(join_params.ssid_le) +
++				   BRCMF_ASSOC_PARAMS_FIXED_SIZE;
++	} else {
++		memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++	}
++
++	brcmf_update_prof(cfg_priv, NULL,
++			  &join_params.params_le.bssid, WL_PROF_BSSID);
++
++	/* Channel */
++	if (params->channel) {
++		u32 target_channel;
++
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(
++				params->channel->center_freq);
++		if (params->channel_fixed) {
++			/* adding chanspec */
++			brcmf_ch_to_chanspec(cfg_priv->channel,
++				&join_params, &join_params_size);
++		}
++
++		/* set channel for starter */
++		target_channel = cfg_priv->channel;
++		err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
++					  &target_channel);
++		if (err) {
++			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
++			goto done;
++		}
++	} else
++		cfg_priv->channel = 0;
++
++	cfg_priv->ibss_starter = false;
++
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err) {
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++		goto done;
++	}
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	brcmf_link_down(cfg_priv);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_set_wpa_version(struct net_device *ndev,
++				 struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
++		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
++	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
++		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
++	else
++		val = WPA_AUTH_DISABLED;
++	WL_CONN("setting wpa_auth to 0x%0x\n", val);
++	err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++	if (err) {
++		WL_ERR("set wpa_auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_versions = sme->crypto.wpa_versions;
++	return err;
++}
++
++static s32 brcmf_set_auth_type(struct net_device *ndev,
++			       struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	switch (sme->auth_type) {
++	case NL80211_AUTHTYPE_OPEN_SYSTEM:
++		val = 0;
++		WL_CONN("open system\n");
++		break;
++	case NL80211_AUTHTYPE_SHARED_KEY:
++		val = 1;
++		WL_CONN("shared key\n");
++		break;
++	case NL80211_AUTHTYPE_AUTOMATIC:
++		val = 2;
++		WL_CONN("automatic\n");
++		break;
++	case NL80211_AUTHTYPE_NETWORK_EAP:
++		WL_CONN("network eap\n");
++	default:
++		val = 2;
++		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
++		break;
++	}
++
++	err = brcmf_dev_intvar_set(ndev, "auth", val);
++	if (err) {
++		WL_ERR("set auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->auth_type = sme->auth_type;
++	return err;
++}
++
++static s32
++brcmf_set_set_cipher(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 pval = 0;
++	s32 gval = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_ciphers_pairwise) {
++		switch (sme->crypto.ciphers_pairwise[0]) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			pval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			pval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			pval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			pval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher pairwise (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++	}
++	if (sme->crypto.cipher_group) {
++		switch (sme->crypto.cipher_group) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			gval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			gval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			gval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			gval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher group (%d)\n",
++			       sme->crypto.cipher_group);
++			return -EINVAL;
++		}
++	}
++
++	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
++	err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
++	sec->cipher_group = sme->crypto.cipher_group;
++
++	return err;
++}
++
++static s32
++brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_akm_suites) {
++		err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
++		if (err) {
++			WL_ERR("could not get wpa_auth (%d)\n", err);
++			return err;
++		}
++		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA2_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA2_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		}
++
++		WL_CONN("setting wpa_auth to %d\n", val);
++		err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++		if (err) {
++			WL_ERR("could not set wpa_auth (%d)\n", err);
++			return err;
++		}
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_auth = sme->crypto.akm_suites[0];
++
++	return err;
++}
++
++static s32
++brcmf_set_wep_sharedkey(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 err = 0;
++
++	WL_CONN("key len (%d)\n", sme->key_len);
++
++	if (sme->key_len == 0)
++		return 0;
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
++		sec->wpa_versions, sec->cipher_pairwise);
++
++	if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
++		return 0;
++
++	if (sec->cipher_pairwise &
++	    (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
++		memset(&key, 0, sizeof(key));
++		key.len = (u32) sme->key_len;
++		key.index = (u32) sme->key_idx;
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Too long key length (%u)\n", key.len);
++			return -EINVAL;
++		}
++		memcpy(key.data, sme->key, key.len);
++		key.flags = BRCMF_PRIMARY_KEY;
++		switch (sec->cipher_pairwise) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			break;
++		default:
++			WL_ERR("Invalid algorithm (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++		/* Set the new key/index */
++		WL_CONN("key length (%d) key index (%d) algo (%d)\n",
++			key.len, key.index, key.algo);
++		WL_CONN("key \"%s\"\n", key.data);
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++
++		if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
++			WL_CONN("set auth_type to shared key\n");
++			val = 1;	/* shared key */
++			err = brcmf_dev_intvar_set(ndev, "auth", val);
++			if (err) {
++				WL_ERR("set auth failed (%d)\n", err);
++				return err;
++			}
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
++		    struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct ieee80211_channel *chan = sme->channel;
++	struct brcmf_join_params join_params;
++	size_t join_params_size;
++	struct brcmf_ssid ssid;
++
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (!sme->ssid) {
++		WL_ERR("Invalid ssid\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (chan) {
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(chan->center_freq);
++		WL_CONN("channel (%d), center_req (%d)\n",
++				cfg_priv->channel, chan->center_freq);
++	} else
++		cfg_priv->channel = 0;
++
++	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
++
++	err = brcmf_set_wpa_version(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_wpa_version failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_auth_type(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_auth_type failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_set_cipher(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_set_cipher failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_key_mgmt(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_wep_sharedkey(ndev, sme);
++	if (err) {
++		WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
++		goto done;
++	}
++
++	memset(&join_params, 0, sizeof(join_params));
++	join_params_size = sizeof(join_params.ssid_le);
++
++	ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
++	memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
++	memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++
++	if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
++		WL_CONN("ssid \"%s\", len (%d)\n",
++		       ssid.SSID, ssid.SSID_len);
++
++	brcmf_ch_to_chanspec(cfg_priv->channel,
++			     &join_params, &join_params_size);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err)
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
++		       u16 reason_code)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scbval;
++	s32 err = 0;
++
++	WL_TRACE("Enter. Reason code = %d\n", reason_code);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++
++	memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
++	scbval.val = cpu_to_le32(reason_code);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
++			      sizeof(struct brcmf_scb_val_le));
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	cfg_priv->link_up = false;
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
++			    enum nl80211_tx_power_setting type, s32 mbm)
++{
++
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	u16 txpwrmw;
++	s32 err = 0;
++	s32 disable = 0;
++	s32 dbm = MBM_TO_DBM(mbm);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_TX_POWER_AUTOMATIC:
++		break;
++	case NL80211_TX_POWER_LIMITED:
++	case NL80211_TX_POWER_FIXED:
++		if (dbm < 0) {
++			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
++			err = -EINVAL;
++			goto done;
++		}
++		break;
++	}
++	/* Make sure radio is off or on as far as software is concerned */
++	disable = WL_RADIO_SW_DISABLE << 16;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
++	if (err)
++		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
++
++	if (dbm > 0xffff)
++		txpwrmw = 0xffff;
++	else
++		txpwrmw = (u16) dbm;
++	err = brcmf_dev_intvar_set(ndev, "qtxpower",
++			(s32) (brcmf_mw_to_qdbm(txpwrmw)));
++	if (err)
++		WL_ERR("qtxpower error (%d)\n", err);
++	cfg_priv->conf->tx_power = dbm;
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 txpwrdbm;
++	u8 result;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		goto done;
++	}
++
++	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
++	*dbm = (s32) brcmf_qdbm_to_mw(result);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
++			       u8 key_idx, bool unicast, bool multicast)
++{
++	u32 index;
++	u32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		goto done;
++	}
++
++	if (wsec & WEP_ENABLED) {
++		/* Just select a new current key */
++		index = key_idx;
++		err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
++					  &index);
++		if (err)
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
++	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	struct brcmf_wsec_key_le key_le;
++	s32 err = 0;
++
++	memset(&key, 0, sizeof(key));
++	key.index = (u32) key_idx;
++	/* Instead of bcast for ea address for default wep keys,
++		 driver needs it to be Null */
++	if (!is_multicast_ether_addr(mac_addr))
++		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
++	key.len = (u32) params->key_len;
++	/* check for key index change */
++	if (key.len == 0) {
++		/* key delete */
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++	} else {
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Invalid key length (%d)\n", key.len);
++			return -EINVAL;
++		}
++
++		WL_CONN("Setting the key index %d\n", key.index);
++		memcpy(key.data, params->key, key.len);
++
++		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
++			u8 keybuf[8];
++			memcpy(keybuf, &key.data[24], sizeof(keybuf));
++			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++			memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		}
++
++		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
++		if (params->seq && params->seq_len == 6) {
++			/* rx iv */
++			u8 *ivptr;
++			ivptr = (u8 *) params->seq;
++			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
++			    (ivptr[3] << 8) | ivptr[2];
++			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
++			key.iv_initialized = true;
++		}
++
++		switch (params->cipher) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			key.algo = CRYPTO_ALGO_TKIP;
++			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++			break;
++		default:
++			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++			return -EINVAL;
++		}
++		convert_key_from_CPU(&key, &key_le);
++
++		brcmf_netdev_wait_pend8021x(ndev);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
++				      sizeof(key_le));
++		if (err) {
++			WL_ERR("WLC_SET_KEY error (%d)\n", err);
++			return err;
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr,
++		    struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 wsec;
++	s32 err = 0;
++	u8 keybuf[8];
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (mac_addr) {
++		WL_TRACE("Exit");
++		return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
++	}
++	memset(&key, 0, sizeof(key));
++
++	key.len = (u32) params->key_len;
++	key.index = (u32) key_idx;
++
++	if (key.len > sizeof(key.data)) {
++		WL_ERR("Too long key length (%u)\n", key.len);
++		err = -EINVAL;
++		goto done;
++	}
++	memcpy(key.data, params->key, key.len);
++
++	key.flags = BRCMF_PRIMARY_KEY;
++	switch (params->cipher) {
++	case WLAN_CIPHER_SUITE_WEP40:
++		key.algo = CRYPTO_ALGO_WEP1;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		break;
++	case WLAN_CIPHER_SUITE_WEP104:
++		key.algo = CRYPTO_ALGO_WEP128;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		break;
++	case WLAN_CIPHER_SUITE_TKIP:
++		memcpy(keybuf, &key.data[24], sizeof(keybuf));
++		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++		memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		key.algo = CRYPTO_ALGO_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case WLAN_CIPHER_SUITE_AES_CMAC:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	case WLAN_CIPHER_SUITE_CCMP:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++		break;
++	default:
++		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
++	if (err)
++		goto done;
++
++	val = WEP_ENABLED;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		goto done;
++	}
++
++	val = 1;		/* assume shared key. otherwise 0 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err)
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr)
++{
++	struct brcmf_wsec_key key;
++	s32 err = 0;
++	s32 val;
++	s32 wsec;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&key, 0, sizeof(key));
++
++	key.index = (u32) key_idx;
++	key.flags = BRCMF_PRIMARY_KEY;
++	key.algo = CRYPTO_ALGO_OFF;
++
++	WL_CONN("key index (%d)\n", key_idx);
++
++	/* Set the new key/index */
++	err = send_key_to_dongle(ndev, &key);
++	if (err) {
++		if (err == -EINVAL) {
++			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
++				/* we ignore this key index in this case */
++				WL_ERR("invalid key index (%d)\n", key_idx);
++		}
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;		/* assume open key. otherwise 1 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err) {
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
++		    void (*callback) (void *cookie, struct key_params * params))
++{
++	struct key_params params;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_cfg80211_security *sec;
++	s32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&params, 0, sizeof(params));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	switch (wsec) {
++	case WEP_ENABLED:
++		sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP40;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP104;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		}
++		break;
++	case TKIP_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case AES_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	default:
++		WL_ERR("Invalid algo (0x%x)\n", wsec);
++		err = -EINVAL;
++		goto done;
++	}
++	callback(cookie, &params);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
++				    struct net_device *ndev, u8 key_idx)
++{
++	WL_INFO("Not supported\n");
++
++	return -EOPNOTSUPP;
++}
++
++static s32
++brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
++			u8 *mac, struct station_info *sinfo)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scb_val;
++	int rssi;
++	s32 rate;
++	s32 err = 0;
++	u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (memcmp(mac, bssid, ETH_ALEN)) {
++		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
++			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
++			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
++			bssid[0], bssid[1], bssid[2], bssid[3],
++			bssid[4], bssid[5]);
++		err = -ENOENT;
++		goto done;
++	}
++
++	/* Report the current tx rate */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
++	if (err) {
++		WL_ERR("Could not get rate (%d)\n", err);
++	} else {
++		sinfo->filled |= STATION_INFO_TX_BITRATE;
++		sinfo->txrate.legacy = rate * 5;
++		WL_CONN("Rate %d Mbps\n", rate / 2);
++	}
++
++	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
++		scb_val.val = cpu_to_le32(0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
++				      sizeof(struct brcmf_scb_val_le));
++		if (err)
++			WL_ERR("Could not get rssi (%d)\n", err);
++
++		rssi = le32_to_cpu(scb_val.val);
++		sinfo->filled |= STATION_INFO_SIGNAL;
++		sinfo->signal = rssi;
++		WL_CONN("RSSI %d dBm\n", rssi);
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
++			   bool enabled, s32 timeout)
++{
++	s32 pm;
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Powersave enable/disable request is coming from the
++	 * cfg80211 even before the interface is up. In that
++	 * scenario, driver will be storing the power save
++	 * preference in cfg_priv struct to apply this to
++	 * FW later while initializing the dongle
++	 */
++	cfg_priv->pwr_save = enabled;
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++
++		WL_INFO("Device is not ready,"
++			"storing the value in cfg_priv struct\n");
++		goto done;
++	}
++
++	pm = enabled ? PM_FAST : PM_OFF;
++	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
++	if (err) {
++		if (err == -ENODEV)
++			WL_ERR("net_device is not ready yet\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
++			     const u8 *addr,
++			     const struct cfg80211_bitrate_mask *mask)
++{
++	struct brcm_rateset_le rateset_le;
++	s32 rate;
++	s32 val;
++	s32 err_bg;
++	s32 err_a;
++	u32 legacy;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	/* addr param is always NULL. ignore it */
++	/* Get current rateset */
++	err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
++			      sizeof(rateset_le));
++	if (err) {
++		WL_ERR("could not get current rateset (%d)\n", err);
++		goto done;
++	}
++
++	legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
++	if (!legacy)
++		legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
++			     0xFFFF);
++
++	val = wl_g_rates[legacy - 1].bitrate * 100000;
++
++	if (val < le32_to_cpu(rateset_le.count))
++		/* Select rate by rateset index */
++		rate = rateset_le.rates[val] & 0x7f;
++	else
++		/* Specified rate in bps */
++		rate = val / 500000;
++
++	WL_CONN("rate %d mbps\n", rate / 2);
++
++	/*
++	 *
++	 *      Set rate override,
++	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
++	 */
++	err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
++	err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
++	if (err_bg && err_a) {
++		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
++		err = err_bg | err_a;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
++				   struct brcmf_bss_info_le *bi)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct cfg80211_bss *bss;
++	struct ieee80211_supported_band *band;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
++		WL_ERR("Bss info is larger than buffer. Discarding\n");
++		return 0;
++	}
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
++			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
++			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
++	WL_CONN("Channel: %d(%d)\n", channel, freq);
++	WL_CONN("Capability: %X\n", notify_capability);
++	WL_CONN("Beacon interval: %d\n", notify_interval);
++	WL_CONN("Signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
++		0, notify_capability, notify_interval, notify_ie,
++		notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss)
++		return -ENOMEM;
++
++	cfg80211_put_bss(bss);
++
++	return err;
++}
++
++static struct brcmf_bss_info_le *
++next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
++{
++	if (bss == NULL)
++		return list->bss_info_le;
++	return (struct brcmf_bss_info_le *)((unsigned long)bss +
++					    le32_to_cpu(bss->length));
++}
++
++static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_scan_results *bss_list;
++	struct brcmf_bss_info_le *bi = NULL;	/* must be initialized */
++	s32 err = 0;
++	int i;
++
++	bss_list = cfg_priv->bss_list;
++	if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
++		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
++		       bss_list->version);
++		return -EOPNOTSUPP;
++	}
++	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
++	for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
++		bi = next_bss_le(bss_list, bi);
++		err = brcmf_inform_single_bss(cfg_priv, bi);
++		if (err)
++			break;
++	}
++	return err;
++}
++
++static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
++			  struct net_device *ndev, const u8 *bssid)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct brcmf_bss_info_le *bi = NULL;
++	struct ieee80211_supported_band *band;
++	struct cfg80211_bss *bss;
++	u8 *buf = NULL;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	WL_TRACE("Enter\n");
++
++	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (buf == NULL) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
++	if (err) {
++		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
++		goto CleanUp;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(buf + 4);
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("channel: %d(%d)\n", channel, freq);
++	WL_CONN("capability: %X\n", notify_capability);
++	WL_CONN("beacon interval: %d\n", notify_interval);
++	WL_CONN("signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
++		0, notify_capability, notify_interval,
++		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	cfg80211_put_bss(bss);
++
++CleanUp:
++
++	kfree(buf);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return cfg_priv->conf->mode == WL_MODE_IBSS;
++}
++
++/*
++ * Traverse a string of 1-byte tag/1-byte length/variable-length value
++ * triples, returning a pointer to the substring whose first element
++ * matches tag
++ */
++static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
++{
++	struct brcmf_tlv *elt;
++	int totlen;
++
++	elt = (struct brcmf_tlv *) buf;
++	totlen = buflen;
++
++	/* find tagged parameter */
++	while (totlen >= 2) {
++		int len = elt->len;
++
++		/* validate remaining totlen */
++		if ((elt->id == key) && (totlen >= (len + 2)))
++			return elt;
++
++		elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
++		totlen -= (len + 2);
++	}
++
++	return NULL;
++}
++
++static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_bss_info_le *bi;
++	struct brcmf_ssid *ssid;
++	struct brcmf_tlv *tim;
++	u16 beacon_interval;
++	u8 dtim_period;
++	size_t ie_len;
++	u8 *ie;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (brcmf_is_ibssmode(cfg_priv))
++		return err;
++
++	ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
++
++	*(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
++			cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
++	if (err) {
++		WL_ERR("Could not get bss info %d\n", err);
++		goto update_bss_info_out;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
++	err = brcmf_inform_single_bss(cfg_priv, bi);
++	if (err)
++		goto update_bss_info_out;
++
++	ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
++	ie_len = le32_to_cpu(bi->ie_length);
++	beacon_interval = le16_to_cpu(bi->beacon_period);
++
++	tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
++	if (tim)
++		dtim_period = tim->data[1];
++	else {
++		/*
++		* active scan was done so we could not get dtim
++		* information out of probe response.
++		* so we speficially query dtim information to dongle.
++		*/
++		u32 var;
++		err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
++					   "dtim_assoc", &var);
++		if (err) {
++			WL_ERR("wl dtim_assoc failed (%d)\n", err);
++			goto update_bss_info_out;
++		}
++		dtim_period = (u8)var;
++	}
++
++	brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
++	brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
++
++update_bss_info_out:
++	WL_TRACE("Exit");
++	return err;
++}
++
++static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct brcmf_ssid ssid;
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++
++		if (iscan->timer_on) {
++			del_timer_sync(&iscan->timer);
++			iscan->timer_on = 0;
++		}
++
++		cancel_work_sync(&iscan->work);
++
++		/* Abort iscan running in FW */
++		memset(&ssid, 0, sizeof(ssid));
++		brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
++	}
++}
++
++static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
++					bool aborted)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		return;
++	}
++	if (cfg_priv->scan_request) {
++		WL_SCAN("ISCAN Completed scan: %s\n",
++				aborted ? "Aborted" : "Done");
++		cfg80211_scan_done(cfg_priv->scan_request, aborted);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++	cfg_priv->iscan_kickstart = false;
++}
++
++static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
++{
++	if (iscan->state != WL_ISCAN_STATE_IDLE) {
++		WL_SCAN("wake up iscan\n");
++		schedule_work(&iscan->work);
++		return 0;
++	}
++
++	return -EIO;
++}
++
++static s32
++brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
++		     struct brcmf_scan_results **bss_list)
++{
++	struct brcmf_iscan_results list;
++	struct brcmf_scan_results *results;
++	struct brcmf_scan_results_le *results_le;
++	struct brcmf_iscan_results *list_buf;
++	s32 err = 0;
++
++	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
++	list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
++	results = &list_buf->results;
++	results_le = &list_buf->results_le;
++	results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
++	results->version = 0;
++	results->count = 0;
++
++	memset(&list, 0, sizeof(list));
++	list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
++	err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
++				     BRCMF_ISCAN_RESULTS_FIXED_SIZE,
++				     iscan->scan_buf, WL_ISCAN_BUF_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	results->buflen = le32_to_cpu(results_le->buflen);
++	results->version = le32_to_cpu(results_le->version);
++	results->count = le32_to_cpu(results_le->count);
++	WL_SCAN("results->count = %d\n", results_le->count);
++	WL_SCAN("results->buflen = %d\n", results_le->buflen);
++	*status = le32_to_cpu(list_buf->status_le);
++	WL_SCAN("status = %d\n", *status);
++	*bss_list = results;
++
++	return err;
++}
++
++static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_inform_bss(cfg_priv);
++	brcmf_notify_iscan_complete(iscan, false);
++
++	return err;
++}
++
++static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	brcmf_inform_bss(cfg_priv);
++	brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_notify_iscan_complete(iscan, true);
++
++	return err;
++}
++
++static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			container_of(work, struct brcmf_cfg80211_iscan_ctrl,
++				     work);
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
++	u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
++
++	if (iscan->timer_on) {
++		del_timer_sync(&iscan->timer);
++		iscan->timer_on = 0;
++	}
++
++	if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
++		status = BRCMF_SCAN_RESULTS_ABORTED;
++		WL_ERR("Abort iscan\n");
++	}
++
++	el->handler[status](cfg_priv);
++}
++
++static void brcmf_iscan_timer(unsigned long data)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			(struct brcmf_cfg80211_iscan_ctrl *)data;
++
++	if (iscan) {
++		iscan->timer_on = 0;
++		WL_SCAN("timer expired\n");
++		brcmf_wakeup_iscan(iscan);
++	}
++}
++
++static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++		INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
++	}
++
++	return 0;
++}
++
++static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
++	el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
++	el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
++	el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
++	el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
++}
++
++static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	int err = 0;
++
++	if (cfg_priv->iscan_on) {
++		iscan->ndev = cfg_to_ndev(cfg_priv);
++		brcmf_init_iscan_eloop(&iscan->el);
++		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
++		init_timer(&iscan->timer);
++		iscan->timer.data = (unsigned long) iscan;
++		iscan->timer.function = brcmf_iscan_timer;
++		err = brcmf_invoke_iscan(cfg_priv);
++		if (!err)
++			iscan->data = cfg_priv;
++	}
++
++	return err;
++}
++
++static __always_inline void brcmf_delay(u32 ms)
++{
++	if (ms < 1000 / HZ) {
++		cond_resched();
++		mdelay(ms);
++	} else {
++		msleep(ms);
++	}
++}
++
++static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the resume for
++	 * any driver error conditions
++	 */
++	WL_TRACE("Enter\n");
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
++
++	WL_TRACE("Exit\n");
++	return 0;
++}
++
++static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
++				  struct cfg80211_wowlan *wow)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the suspend for
++	 * any driver error conditions
++	 */
++
++	/*
++	 * While going to suspend if associated with AP disassociate
++	 * from AP to save power while system is in suspended state
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP"
++			" while entering suspend state\n");
++		brcmf_link_down(cfg_priv);
++
++		/*
++		 * Make sure WPA_Supplicant receives all the event
++		 * generated due to DISASSOC call to the fw to keep
++		 * the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_term_iscan(cfg_priv);
++
++	if (cfg_priv->scan_request) {
++		/* Indidate scan abort to cfg80211 layer */
++		WL_INFO("Terminating scan in progress\n");
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	/* Turn off watchdog timer */
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Enable MPC\n");
++		brcmf_set_mpc(ndev, 1);
++	}
++
++	WL_TRACE("Exit\n");
++
++	return 0;
++}
++
++static __used s32
++brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 buflen;
++
++	buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
++			       WL_DCMD_LEN_MAX);
++	BUG_ON(!buflen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
++			       buflen);
++}
++
++static s32
++brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
++		  s32 buf_len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 len;
++	s32 err = 0;
++
++	len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
++			    WL_DCMD_LEN_MAX);
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
++			      WL_DCMD_LEN_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	memcpy(buf, cfg_priv->dcmd_buf, buf_len);
++
++	return err;
++}
++
++static __used s32
++brcmf_update_pmklist(struct net_device *ndev,
++		     struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
++{
++	int i, j;
++	int pmkid_len;
++
++	pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
++
++	WL_CONN("No of elements %d\n", pmkid_len);
++	for (i = 0; i < pmkid_len; i++) {
++		WL_CONN("PMKID[%d]: %pM =\n", i,
++			&pmk_list->pmkids.pmkid[i].BSSID);
++		for (j = 0; j < WLAN_PMKID_LEN; j++)
++			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
++	}
++
++	if (!err)
++		brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
++					sizeof(*pmk_list));
++
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++			 struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
++	s32 err = 0;
++	int i;
++	int pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	pmkid_len = le32_to_cpu(pmkids->npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
++			break;
++	if (i < WL_NUM_PMKIDS_MAX) {
++		memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
++		memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++		if (i == pmkid_len) {
++			pmkid_len++;
++			pmkids->npmkid = cpu_to_le32(pmkid_len);
++		}
++	} else
++		err = -EINVAL;
++
++	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
++		pmkids->pmkid[pmkid_len].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list pmkid;
++	s32 err = 0;
++	int i, pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
++	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++
++	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
++	       &pmkid.pmkid[0].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
++
++	pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp
++		    (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++		     ETH_ALEN))
++			break;
++
++	if ((pmkid_len > 0)
++	    && (i < pmkid_len)) {
++		memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
++		       sizeof(struct pmkid));
++		for (; i < (pmkid_len - 1); i++) {
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
++			       ETH_ALEN);
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
++			       WLAN_PMKID_LEN);
++		}
++		cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
++	} else
++		err = -EINVAL;
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static s32
++brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static struct cfg80211_ops wl_cfg80211_ops = {
++	.change_virtual_intf = brcmf_cfg80211_change_iface,
++	.scan = brcmf_cfg80211_scan,
++	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
++	.join_ibss = brcmf_cfg80211_join_ibss,
++	.leave_ibss = brcmf_cfg80211_leave_ibss,
++	.get_station = brcmf_cfg80211_get_station,
++	.set_tx_power = brcmf_cfg80211_set_tx_power,
++	.get_tx_power = brcmf_cfg80211_get_tx_power,
++	.add_key = brcmf_cfg80211_add_key,
++	.del_key = brcmf_cfg80211_del_key,
++	.get_key = brcmf_cfg80211_get_key,
++	.set_default_key = brcmf_cfg80211_config_default_key,
++	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
++	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
++	.set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
++	.connect = brcmf_cfg80211_connect,
++	.disconnect = brcmf_cfg80211_disconnect,
++	.suspend = brcmf_cfg80211_suspend,
++	.resume = brcmf_cfg80211_resume,
++	.set_pmksa = brcmf_cfg80211_set_pmksa,
++	.del_pmksa = brcmf_cfg80211_del_pmksa,
++	.flush_pmksa = brcmf_cfg80211_flush_pmksa
++};
++
++static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
++{
++	s32 err = 0;
++
++	switch (mode) {
++	case WL_MODE_BSS:
++		return NL80211_IFTYPE_STATION;
++	case WL_MODE_IBSS:
++		return NL80211_IFTYPE_ADHOC;
++	default:
++		return NL80211_IFTYPE_UNSPECIFIED;
++	}
++
++	return err;
++}
++
++static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
++					  struct device *ndev)
++{
++	struct wireless_dev *wdev;
++	s32 err = 0;
++
++	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
++	if (!wdev)
++		return ERR_PTR(-ENOMEM);
++
++	wdev->wiphy =
++	    wiphy_new(&wl_cfg80211_ops,
++		      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
++	if (!wdev->wiphy) {
++		WL_ERR("Could not allocate wiphy device\n");
++		err = -ENOMEM;
++		goto wiphy_new_out;
++	}
++	set_wiphy_dev(wdev->wiphy, ndev);
++	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
++	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
++	wdev->wiphy->interface_modes =
++	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
++	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
++	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
++						* it as 11a by default.
++						* This will be updated with
++						* 11n phy tables in
++						* "ifconfig up"
++						* if phy has 11n capability
++						*/
++	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
++	wdev->wiphy->cipher_suites = __wl_cipher_suites;
++	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
++	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
++								 * save mode
++								 * by default
++								 */
++	err = wiphy_register(wdev->wiphy);
++	if (err < 0) {
++		WL_ERR("Could not register wiphy device (%d)\n", err);
++		goto wiphy_register_out;
++	}
++	return wdev;
++
++wiphy_register_out:
++	wiphy_free(wdev->wiphy);
++
++wiphy_new_out:
++	kfree(wdev);
++
++	return ERR_PTR(err);
++}
++
++static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wireless_dev *wdev = cfg_priv->wdev;
++
++	if (!wdev) {
++		WL_ERR("wdev is invalid\n");
++		return;
++	}
++	wiphy_unregister(wdev->wiphy);
++	wiphy_free(wdev->wiphy);
++	kfree(wdev);
++	cfg_priv->wdev = NULL;
++}
++
++static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
++			    const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing set ssid\n");
++		cfg_priv->link_up = true;
++		return true;
++	}
++
++	return false;
++}
++
++static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
++			      const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u16 flags = be16_to_cpu(e->flags);
++
++	if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
++		WL_CONN("Processing link down\n");
++		return true;
++	}
++	return false;
++}
++
++static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
++			       const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
++		WL_CONN("Processing Link %s & no network found\n",
++				be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
++				"up" : "down");
++		return true;
++	}
++
++	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing connecting & no network found\n");
++		return true;
++	}
++
++	return false;
++}
++
++static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++
++	kfree(conn_info->req_ie);
++	conn_info->req_ie = NULL;
++	conn_info->req_ie_len = 0;
++	kfree(conn_info->resp_ie);
++	conn_info->resp_ie = NULL;
++	conn_info->resp_ie_len = 0;
++}
++
++static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	u32 req_len;
++	u32 resp_len;
++	s32 err = 0;
++
++	brcmf_clear_assoc_ies(cfg_priv);
++
++	err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
++				WL_ASSOC_INFO_MAX);
++	if (err) {
++		WL_ERR("could not get assoc info (%d)\n", err);
++		return err;
++	}
++	assoc_info =
++		(struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
++	req_len = le32_to_cpu(assoc_info->req_len);
++	resp_len = le32_to_cpu(assoc_info->resp_len);
++	if (req_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc req (%d)\n", err);
++			return err;
++		}
++		conn_info->req_ie_len = req_len;
++		conn_info->req_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->req_ie_len = 0;
++		conn_info->req_ie = NULL;
++	}
++	if (resp_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc resp (%d)\n", err);
++			return err;
++		}
++		conn_info->resp_ie_len = resp_len;
++		conn_info->resp_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->resp_ie_len = 0;
++		conn_info->resp_ie = NULL;
++	}
++	WL_CONN("req len (%d) resp len (%d)\n",
++	       conn_info->req_ie_len, conn_info->resp_ie_len);
++
++	return err;
++}
++
++static s32
++brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev,
++		       const struct brcmf_event_msg *e)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct brcmf_channel_info_le channel_le;
++	struct ieee80211_channel *notify_channel;
++	struct ieee80211_supported_band *band;
++	u32 freq;
++	s32 err = 0;
++	u32 target_channel;
++
++	WL_TRACE("Enter\n");
++
++	brcmf_get_assoc_ies(cfg_priv);
++	brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
++	brcmf_update_bss_info(cfg_priv);
++
++	brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
++			sizeof(channel_le));
++
++	target_channel = le32_to_cpu(channel_le.target_channel);
++	WL_CONN("Roamed to channel %d\n", target_channel);
++
++	if (target_channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(target_channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	cfg80211_roamed(ndev, notify_channel,
++			(u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
++			conn_info->req_ie, conn_info->req_ie_len,
++			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
++	WL_CONN("Report roaming result\n");
++
++	set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev, const struct brcmf_event_msg *e,
++		       bool completed)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		if (completed) {
++			brcmf_get_assoc_ies(cfg_priv);
++			brcmf_update_prof(cfg_priv, NULL, &e->addr,
++					  WL_PROF_BSSID);
++			brcmf_update_bss_info(cfg_priv);
++		}
++		cfg80211_connect_result(ndev,
++					(u8 *)brcmf_read_prof(cfg_priv,
++							      WL_PROF_BSSID),
++					conn_info->req_ie,
++					conn_info->req_ie_len,
++					conn_info->resp_ie,
++					conn_info->resp_ie_len,
++					completed ? WLAN_STATUS_SUCCESS :
++						    WLAN_STATUS_AUTH_TIMEOUT,
++					GFP_KERNEL);
++		if (completed)
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		WL_CONN("Report connect result - connection %s\n",
++				completed ? "succeeded" : "failed");
++	}
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++
++	if (brcmf_is_linkup(cfg_priv, e)) {
++		WL_CONN("Linkup\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
++				WL_PROF_BSSID);
++			wl_inform_ibss(cfg_priv, ndev, e->addr);
++			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		} else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	} else if (brcmf_is_linkdown(cfg_priv, e)) {
++		WL_CONN("Linkdown\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status))
++				brcmf_link_down(cfg_priv);
++		} else {
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status)) {
++				cfg80211_disconnected(ndev, 0, NULL, 0,
++					GFP_KERNEL);
++				brcmf_link_down(cfg_priv);
++			}
++		}
++		brcmf_init_prof(cfg_priv->profile);
++	} else if (brcmf_is_nonetwork(cfg_priv, e)) {
++		if (brcmf_is_ibssmode(cfg_priv))
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
++		if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
++			brcmf_bss_roaming_done(cfg_priv, ndev, e);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
++			struct net_device *ndev,
++			const struct brcmf_event_msg *e, void *data)
++{
++	u16 flags = be16_to_cpu(e->flags);
++	enum nl80211_key_type key_type;
++
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		key_type = NL80211_KEYTYPE_GROUP;
++	else
++		key_type = NL80211_KEYTYPE_PAIRWISE;
++
++	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
++				     NULL, GFP_KERNEL);
++
++	return 0;
++}
++
++static s32
++brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
++			 struct net_device *ndev,
++			 const struct brcmf_event_msg *e, void *data)
++{
++	struct brcmf_channel_info_le channel_inform_le;
++	struct brcmf_scan_results_le *bss_list_le;
++	u32 len = WL_SCAN_BUF_MAX;
++	s32 err = 0;
++	bool scan_abort = false;
++	u32 scan_channel;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
++		WL_TRACE("Exit\n");
++		return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
++	}
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		scan_abort = true;
++		err = -EINVAL;
++		goto scan_done_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
++			      sizeof(channel_inform_le));
++	if (err) {
++		WL_ERR("scan busy (%d)\n", err);
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
++	if (scan_channel)
++		WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
++	cfg_priv->bss_list = cfg_priv->scan_results;
++	bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
++
++	memset(cfg_priv->scan_results, 0, len);
++	bss_list_le->buflen = cpu_to_le32(len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
++			      cfg_priv->scan_results, len);
++	if (err) {
++		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
++		err = -EINVAL;
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
++	cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
++	cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
++
++	err = brcmf_inform_bss(cfg_priv);
++	if (err) {
++		scan_abort = true;
++		goto scan_done_out;
++	}
++
++scan_done_out:
++	if (cfg_priv->scan_request) {
++		WL_SCAN("calling cfg80211_scan_done\n");
++		cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
++{
++	conf->mode = (u32)-1;
++	conf->frag_threshold = (u32)-1;
++	conf->rts_threshold = (u32)-1;
++	conf->retry_short = (u32)-1;
++	conf->retry_long = (u32)-1;
++	conf->tx_power = -1;
++}
++
++static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
++	el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
++	el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
++	el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
++	el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
++}
++
++static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	kfree(cfg_priv->scan_results);
++	cfg_priv->scan_results = NULL;
++	kfree(cfg_priv->bss_info);
++	cfg_priv->bss_info = NULL;
++	kfree(cfg_priv->conf);
++	cfg_priv->conf = NULL;
++	kfree(cfg_priv->profile);
++	cfg_priv->profile = NULL;
++	kfree(cfg_priv->scan_req_int);
++	cfg_priv->scan_req_int = NULL;
++	kfree(cfg_priv->dcmd_buf);
++	cfg_priv->dcmd_buf = NULL;
++	kfree(cfg_priv->extra_buf);
++	cfg_priv->extra_buf = NULL;
++	kfree(cfg_priv->iscan);
++	cfg_priv->iscan = NULL;
++	kfree(cfg_priv->pmk_list);
++	cfg_priv->pmk_list = NULL;
++}
++
++static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->scan_results)
++		goto init_priv_mem_out;
++	cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
++	if (!cfg_priv->conf)
++		goto init_priv_mem_out;
++	cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
++	if (!cfg_priv->profile)
++		goto init_priv_mem_out;
++	cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (!cfg_priv->bss_info)
++		goto init_priv_mem_out;
++	cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
++					 GFP_KERNEL);
++	if (!cfg_priv->scan_req_int)
++		goto init_priv_mem_out;
++	cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
++	if (!cfg_priv->dcmd_buf)
++		goto init_priv_mem_out;
++	cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->extra_buf)
++		goto init_priv_mem_out;
++	cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
++	if (!cfg_priv->iscan)
++		goto init_priv_mem_out;
++	cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
++	if (!cfg_priv->pmk_list)
++		goto init_priv_mem_out;
++
++	return 0;
++
++init_priv_mem_out:
++	brcmf_deinit_priv_mem(cfg_priv);
++
++	return -ENOMEM;
++}
++
++/*
++* retrieve first queued event from head
++*/
++
++static struct brcmf_cfg80211_event_q *brcmf_deq_event(
++	struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e = NULL;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	if (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++
++	return e;
++}
++
++/*
++*	push event to tail of the queue
++*
++*	remark: this function may not sleep as it is called in atomic context.
++*/
++
++static s32
++brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
++		const struct brcmf_event_msg *msg)
++{
++	struct brcmf_cfg80211_event_q *e;
++	s32 err = 0;
++	ulong flags;
++
++	e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
++	if (!e)
++		return -ENOMEM;
++
++	e->etype = event;
++	memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
++
++	spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
++	list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
++	spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
++
++	return err;
++}
++
++static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
++{
++	kfree(e);
++}
++
++static void brcmf_cfg80211_event_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_priv *cfg_priv =
++			container_of(work, struct brcmf_cfg80211_priv,
++				     event_work);
++	struct brcmf_cfg80211_event_q *e;
++
++	e = brcmf_deq_event(cfg_priv);
++	if (unlikely(!e)) {
++		WL_ERR("event queue empty...\n");
++		return;
++	}
++
++	do {
++		WL_INFO("event type (%d)\n", e->etype);
++		if (cfg_priv->el.handler[e->etype])
++			cfg_priv->el.handler[e->etype](cfg_priv,
++						       cfg_to_ndev(cfg_priv),
++						       &e->emsg, e->edata);
++		else
++			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
++		brcmf_put_event(e);
++	} while ((e = brcmf_deq_event(cfg_priv)));
++
++}
++
++static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	spin_lock_init(&cfg_priv->evt_q_lock);
++	INIT_LIST_HEAD(&cfg_priv->evt_q_list);
++}
++
++static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	while (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++		kfree(e);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++}
++
++static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	cfg_priv->scan_request = NULL;
++	cfg_priv->pwr_save = true;
++	cfg_priv->iscan_on = true;	/* iscan on & off switch.
++				 we enable iscan per default */
++	cfg_priv->roam_on = true;	/* roam on & off switch.
++				 we enable roam per default */
++
++	cfg_priv->iscan_kickstart = false;
++	cfg_priv->active_scan = true;	/* we do active scan for
++				 specific scan per default */
++	cfg_priv->dongle_up = false;	/* dongle is not up yet */
++	brcmf_init_eq(cfg_priv);
++	err = brcmf_init_priv_mem(cfg_priv);
++	if (err)
++		return err;
++	INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
++	brcmf_init_eloop_handler(&cfg_priv->el);
++	mutex_init(&cfg_priv->usr_sync);
++	err = brcmf_init_iscan(cfg_priv);
++	if (err)
++		return err;
++	brcmf_init_conf(cfg_priv->conf);
++	brcmf_init_prof(cfg_priv->profile);
++	brcmf_link_down(cfg_priv);
++
++	return err;
++}
++
++static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cancel_work_sync(&cfg_priv->event_work);
++	cfg_priv->dongle_up = false;	/* dongle down */
++	brcmf_flush_eq(cfg_priv);
++	brcmf_link_down(cfg_priv);
++	brcmf_term_iscan(cfg_priv);
++	brcmf_deinit_priv_mem(cfg_priv);
++}
++
++struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++						 struct device *busdev,
++						 void *data)
++{
++	struct wireless_dev *wdev;
++	struct brcmf_cfg80211_priv *cfg_priv;
++	struct brcmf_cfg80211_iface *ci;
++	struct brcmf_cfg80211_dev *cfg_dev;
++	s32 err = 0;
++
++	if (!ndev) {
++		WL_ERR("ndev is invalid\n");
++		return NULL;
++	}
++	cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
++	if (!cfg_dev)
++		return NULL;
++
++	wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
++	if (IS_ERR(wdev)) {
++		kfree(cfg_dev);
++		return NULL;
++	}
++
++	wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
++	cfg_priv = wdev_to_cfg(wdev);
++	cfg_priv->wdev = wdev;
++	cfg_priv->pub = data;
++	ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
++	ci->cfg_priv = cfg_priv;
++	ndev->ieee80211_ptr = wdev;
++	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
++	wdev->netdev = ndev;
++	err = wl_init_priv(cfg_priv);
++	if (err) {
++		WL_ERR("Failed to init iwm_priv (%d)\n", err);
++		goto cfg80211_attach_out;
++	}
++	brcmf_set_drvdata(cfg_dev, ci);
++
++	return cfg_dev;
++
++cfg80211_attach_out:
++	brcmf_free_wdev(cfg_priv);
++	kfree(cfg_dev);
++	return NULL;
++}
++
++void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++
++	wl_deinit_priv(cfg_priv);
++	brcmf_free_wdev(cfg_priv);
++	brcmf_set_drvdata(cfg_dev, NULL);
++	kfree(cfg_dev);
++}
++
++void
++brcmf_cfg80211_event(struct net_device *ndev,
++		  const struct brcmf_event_msg *e, void *data)
++{
++	u32 event_type = be32_to_cpu(e->event_type);
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (!brcmf_enq_event(cfg_priv, event_type, e))
++		schedule_work(&cfg_priv->event_work);
++}
++
++static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
++{
++	s32 infra = 0;
++	s32 err = 0;
++
++	switch (iftype) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this mode\n",
++		       iftype);
++		err = -EINVAL;
++		return err;
++	case NL80211_IFTYPE_ADHOC:
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		WL_ERR("invalid type (%d)\n", iftype);
++		return err;
++	}
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		return err;
++	}
++
++	return 0;
++}
++
++static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
++{
++	/* Room for "event_msgs" + '\0' + bitvec */
++	s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Get event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++	memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(eventmask, BRCMF_E_SET_SSID);
++	setbit(eventmask, BRCMF_E_ROAM);
++	setbit(eventmask, BRCMF_E_PRUNE);
++	setbit(eventmask, BRCMF_E_AUTH);
++	setbit(eventmask, BRCMF_E_REASSOC);
++	setbit(eventmask, BRCMF_E_REASSOC_IND);
++	setbit(eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC);
++	setbit(eventmask, BRCMF_E_JOIN);
++	setbit(eventmask, BRCMF_E_ASSOC_IND);
++	setbit(eventmask, BRCMF_E_PSK_SUP);
++	setbit(eventmask, BRCMF_E_LINK);
++	setbit(eventmask, BRCMF_E_NDIS_LINK);
++	setbit(eventmask, BRCMF_E_MIC_ERROR);
++	setbit(eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(eventmask, BRCMF_E_TXFAIL);
++	setbit(eventmask, BRCMF_E_JOIN_START);
++	setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
++
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Set event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++
++dongle_eventmsg_out:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
++{
++	s8 iovbuf[32];
++	s32 err = 0;
++	__le32 roamtrigger[2];
++	__le32 roam_delta[2];
++	__le32 bcn_to_le;
++	__le32 roamvar_le;
++
++	/*
++	 * Setup timeout if Beacons are lost and roam is
++	 * off to report link down
++	 */
++	if (roamvar) {
++		bcn_to_le = cpu_to_le32(bcn_timeout);
++		brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
++			sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++		if (err) {
++			WL_ERR("bcn_timeout error (%d)\n", err);
++			goto dongle_rom_out;
++		}
++	}
++
++	/*
++	 * Enable/Disable built-in roaming to allow supplicant
++	 * to take care of roaming
++	 */
++	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
++	roamvar_le = cpu_to_le32(roamvar);
++	brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
++				sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("roam_off error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
++	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
++			(void *)roamtrigger, sizeof(roamtrigger));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
++	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
++				(void *)roam_delta, sizeof(roam_delta));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++dongle_rom_out:
++	return err;
++}
++
++static s32
++brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
++		      s32 scan_unassoc_time, s32 scan_passive_time)
++{
++	s32 err = 0;
++	__le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
++	__le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
++	__le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			   &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan assoc time is not supported\n");
++		else
++			WL_ERR("Scan assoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			   &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan unassoc time is not supported\n");
++		else
++			WL_ERR("Scan unassoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
++			   &scan_passive_tm_le, sizeof(scan_passive_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan passive time is not supported\n");
++		else
++			WL_ERR("Scan passive time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++dongle_scantime_out:
++	return err;
++}
++
++static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wiphy *wiphy;
++	s32 phy_list;
++	s8 phy;
++	s32 err = 0;
++
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
++			      &phy_list, sizeof(phy_list));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	phy = ((char *)&phy_list)[1];
++	WL_INFO("%c phy\n", phy);
++	if (phy == 'n' || phy == 'a') {
++		wiphy = cfg_to_wiphy(cfg_priv);
++		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
++	}
++
++	return err;
++}
++
++static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return wl_update_wiphybands(cfg_priv);
++}
++
++static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev;
++	struct wireless_dev *wdev;
++	s32 power_mode;
++	s32 err = 0;
++
++	if (cfg_priv->dongle_up)
++		return err;
++
++	ndev = cfg_to_ndev(cfg_priv);
++	wdev = ndev->ieee80211_ptr;
++
++	brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
++			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
++
++	err = brcmf_dongle_eventmsg(ndev);
++	if (err)
++		goto default_conf_out;
++
++	power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
++	if (err)
++		goto default_conf_out;
++	WL_INFO("power save set to %s\n",
++		(power_mode ? "enabled" : "disabled"));
++
++	err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
++				WL_BEACON_TIMEOUT);
++	if (err)
++		goto default_conf_out;
++	err = brcmf_dongle_mode(ndev, wdev->iftype);
++	if (err && err != -EINPROGRESS)
++		goto default_conf_out;
++	err = brcmf_dongle_probecap(cfg_priv);
++	if (err)
++		goto default_conf_out;
++
++	/* -EINPROGRESS: Call commit handler */
++
++default_conf_out:
++
++	cfg_priv->dongle_up = true;
++
++	return err;
++
++}
++
++static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	char buf[10+IFNAMSIZ];
++	struct dentry *fd;
++	s32 err = 0;
++
++	sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
++	cfg_priv->debugfsdir = debugfs_create_dir(buf,
++					cfg_to_wiphy(cfg_priv)->debugfsdir);
++
++	fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
++		(u16 *)&cfg_priv->profile->beacon_interval);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
++		(u8 *)&cfg_priv->profile->dtim_period);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++err_out:
++	return err;
++}
++
++static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	debugfs_remove_recursive(cfg_priv->debugfsdir);
++	cfg_priv->debugfsdir = NULL;
++}
++
++static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	set_bit(WL_STATUS_READY, &cfg_priv->status);
++
++	brcmf_debugfs_add_netdev_params(cfg_priv);
++
++	err = brcmf_config_dongle(cfg_priv);
++	if (err)
++		return err;
++
++	brcmf_invoke_iscan(cfg_priv);
++
++	return err;
++}
++
++static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	/*
++	 * While going down, if associated with AP disassociate
++	 * from AP to save power
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP");
++		brcmf_link_down(cfg_priv);
++
++		/* Make sure WPA_Supplicant receives all the event
++		   generated due to DISASSOC call to the fw to keep
++		   the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	brcmf_term_iscan(cfg_priv);
++	if (cfg_priv->scan_request) {
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		/* May need to perform this to cover rmmod */
++		/* wl_set_mpc(cfg_to_ndev(wl), 1); */
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_READY, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	brcmf_debugfs_remove_netdev(cfg_priv);
++
++	return 0;
++}
++
++s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_up(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_down(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
++			       u8 t, u8 l, u8 *v)
++{
++	struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
++	s32 err = 0;
++
++	if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
++		WL_ERR("ei crosses buffer boundary\n");
++		return -ENOSPC;
++	}
++	ie->buf[ie->offset] = t;
++	ie->buf[ie->offset + 1] = l;
++	memcpy(&ie->buf[ie->offset + 2], v, l);
++	ie->offset += l + 2;
++
++	return err;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+new file mode 100644
+index 0000000..b5d9b36
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+@@ -0,0 +1,366 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _wl_cfg80211_h_
++#define _wl_cfg80211_h_
++
++struct brcmf_cfg80211_conf;
++struct brcmf_cfg80211_iface;
++struct brcmf_cfg80211_priv;
++struct brcmf_cfg80211_security;
++struct brcmf_cfg80211_ibss;
++
++#define WL_DBG_NONE		0
++#define WL_DBG_CONN		(1 << 5)
++#define WL_DBG_SCAN		(1 << 4)
++#define WL_DBG_TRACE		(1 << 3)
++#define WL_DBG_INFO		(1 << 1)
++#define WL_DBG_ERR		(1 << 0)
++#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
++				(WL_DBG_SCAN) | (WL_DBG_CONN))
++
++#define	WL_ERR(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_ERR) {			\
++		if (net_ratelimit()) {				\
++			pr_err("ERROR @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#if (defined DEBUG)
++#define	WL_INFO(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_INFO) {			\
++		if (net_ratelimit()) {				\
++			pr_err("INFO @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_TRACE(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_TRACE) {			\
++		if (net_ratelimit()) {				\
++			pr_err("TRACE @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_SCAN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_SCAN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("SCAN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_CONN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_CONN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("CONN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#else /* (defined DEBUG) */
++#define	WL_INFO(fmt, args...)
++#define	WL_TRACE(fmt, args...)
++#define	WL_SCAN(fmt, args...)
++#define	WL_CONN(fmt, args...)
++#endif /* (defined DEBUG) */
++
++#define WL_NUM_SCAN_MAX		1
++#define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
++						 * for 2.6.33 kernel
++						 * or later
++						 */
++#define WL_SCAN_BUF_MAX			(1024 * 8)
++#define WL_TLV_INFO_MAX			1024
++#define WL_BSS_INFO_MAX			2048
++#define WL_ASSOC_INFO_MAX	512	/*
++				 * needs to grab assoc info from dongle to
++				 * report it to cfg80211 through "connect"
++				 * event
++				 */
++#define WL_DCMD_LEN_MAX	1024
++#define WL_EXTRA_BUF_MAX	2048
++#define WL_ISCAN_BUF_MAX	2048	/*
++				 * the buf length can be BRCMF_DCMD_MAXLEN
++				 * to reduce iteration
++				 */
++#define WL_ISCAN_TIMER_INTERVAL_MS	3000
++#define WL_SCAN_ERSULTS_LAST	(BRCMF_SCAN_RESULTS_NO_MEM+1)
++#define WL_AP_MAX	256	/* virtually unlimitted as long
++				 * as kernel memory allows
++				 */
++
++#define WL_ROAM_TRIGGER_LEVEL		-75
++#define WL_ROAM_DELTA			20
++#define WL_BEACON_TIMEOUT		3
++
++#define WL_SCAN_CHANNEL_TIME		40
++#define WL_SCAN_UNASSOC_TIME		40
++#define WL_SCAN_PASSIVE_TIME		120
++
++/* dongle status */
++enum wl_status {
++	WL_STATUS_READY,
++	WL_STATUS_SCANNING,
++	WL_STATUS_SCAN_ABORTING,
++	WL_STATUS_CONNECTING,
++	WL_STATUS_CONNECTED
++};
++
++/* wi-fi mode */
++enum wl_mode {
++	WL_MODE_BSS,
++	WL_MODE_IBSS,
++	WL_MODE_AP
++};
++
++/* dongle profile list */
++enum wl_prof_list {
++	WL_PROF_MODE,
++	WL_PROF_SSID,
++	WL_PROF_SEC,
++	WL_PROF_IBSS,
++	WL_PROF_BAND,
++	WL_PROF_BSSID,
++	WL_PROF_ACT,
++	WL_PROF_BEACONINT,
++	WL_PROF_DTIMPERIOD
++};
++
++/* dongle iscan state */
++enum wl_iscan_state {
++	WL_ISCAN_STATE_IDLE,
++	WL_ISCAN_STATE_SCANING
++};
++
++/* dongle configuration */
++struct brcmf_cfg80211_conf {
++	u32 mode;		/* adhoc , infrastructure or ap */
++	u32 frag_threshold;
++	u32 rts_threshold;
++	u32 retry_short;
++	u32 retry_long;
++	s32 tx_power;
++	struct ieee80211_channel channel;
++};
++
++/* cfg80211 main event loop */
++struct brcmf_cfg80211_event_loop {
++	s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
++				     struct net_device *ndev,
++				     const struct brcmf_event_msg *e,
++				     void *data);
++};
++
++/* representing interface of cfg80211 plane */
++struct brcmf_cfg80211_iface {
++	struct brcmf_cfg80211_priv *cfg_priv;
++};
++
++struct brcmf_cfg80211_dev {
++	void *driver_data;	/* to store cfg80211 object information */
++};
++
++/* basic structure of scan request */
++struct brcmf_cfg80211_scan_req {
++	struct brcmf_ssid_le ssid_le;
++};
++
++/* basic structure of information element */
++struct brcmf_cfg80211_ie {
++	u16 offset;
++	u8 buf[WL_TLV_INFO_MAX];
++};
++
++/* event queue for cfg80211 main event */
++struct brcmf_cfg80211_event_q {
++	struct list_head evt_q_list;
++	u32 etype;
++	struct brcmf_event_msg emsg;
++	s8 edata[1];
++};
++
++/* security information with currently associated ap */
++struct brcmf_cfg80211_security {
++	u32 wpa_versions;
++	u32 auth_type;
++	u32 cipher_pairwise;
++	u32 cipher_group;
++	u32 wpa_auth;
++};
++
++/* ibss information for currently joined ibss network */
++struct brcmf_cfg80211_ibss {
++	u8 beacon_interval;	/* in millisecond */
++	u8 atim;		/* in millisecond */
++	s8 join_only;
++	u8 band;
++	u8 channel;
++};
++
++/* dongle profile */
++struct brcmf_cfg80211_profile {
++	u32 mode;
++	struct brcmf_ssid ssid;
++	u8 bssid[ETH_ALEN];
++	u16 beacon_interval;
++	u8 dtim_period;
++	struct brcmf_cfg80211_security sec;
++	struct brcmf_cfg80211_ibss ibss;
++	s32 band;
++};
++
++/* dongle iscan event loop */
++struct brcmf_cfg80211_iscan_eloop {
++	s32 (*handler[WL_SCAN_ERSULTS_LAST])
++		(struct brcmf_cfg80211_priv *cfg_priv);
++};
++
++/* dongle iscan controller */
++struct brcmf_cfg80211_iscan_ctrl {
++	struct net_device *ndev;
++	struct timer_list timer;
++	u32 timer_ms;
++	u32 timer_on;
++	s32 state;
++	struct work_struct work;
++	struct brcmf_cfg80211_iscan_eloop el;
++	void *data;
++	s8 dcmd_buf[BRCMF_DCMD_SMLEN];
++	s8 scan_buf[WL_ISCAN_BUF_MAX];
++};
++
++/* association inform */
++struct brcmf_cfg80211_connect_info {
++	u8 *req_ie;
++	s32 req_ie_len;
++	u8 *resp_ie;
++	s32 resp_ie_len;
++};
++
++/* assoc ie length */
++struct brcmf_cfg80211_assoc_ielen_le {
++	__le32 req_len;
++	__le32 resp_len;
++};
++
++/* wpa2 pmk list */
++struct brcmf_cfg80211_pmk_list {
++	struct pmkid_list pmkids;
++	struct pmkid foo[MAXPMKID - 1];
++};
++
++/* dongle private data of cfg80211 interface */
++struct brcmf_cfg80211_priv {
++	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
++	struct brcmf_cfg80211_conf *conf;	/* dongle configuration */
++	struct cfg80211_scan_request *scan_request;	/* scan request
++							 object */
++	struct brcmf_cfg80211_event_loop el;	/* main event loop */
++	struct list_head evt_q_list;	/* used for event queue */
++	spinlock_t	 evt_q_lock;	/* for event queue synchronization */
++	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
++	struct brcmf_scan_results *bss_list;	/* bss_list holding scanned
++						 ap information */
++	struct brcmf_scan_results *scan_results;
++	struct brcmf_cfg80211_scan_req *scan_req_int;	/* scan request object
++						 for internal purpose */
++	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
++						 cfg80211 layer */
++	struct brcmf_cfg80211_ie ie;	/* information element object for
++					 internal purpose */
++	struct brcmf_cfg80211_profile *profile;	/* holding dongle profile */
++	struct brcmf_cfg80211_iscan_ctrl *iscan;	/* iscan controller */
++	struct brcmf_cfg80211_connect_info conn_info; /* association info */
++	struct brcmf_cfg80211_pmk_list *pmk_list;	/* wpa2 pmk list */
++	struct work_struct event_work;	/* event handler work struct */
++	unsigned long status;		/* current dongle status */
++	void *pub;
++	u32 channel;		/* current channel */
++	bool iscan_on;		/* iscan on/off switch */
++	bool iscan_kickstart;	/* indicate iscan already started */
++	bool active_scan;	/* current scan mode */
++	bool ibss_starter;	/* indicates this sta is ibss starter */
++	bool link_up;		/* link/connection up flag */
++	bool pwr_save;		/* indicate whether dongle to support
++					 power save mode */
++	bool dongle_up;		/* indicate whether dongle up or not */
++	bool roam_on;		/* on/off switch for dongle self-roaming */
++	bool scan_tried;	/* indicates if first scan attempted */
++	u8 *dcmd_buf;		/* dcmd buffer */
++	u8 *extra_buf;		/* maily to grab assoc information */
++	struct dentry *debugfsdir;
++	u8 ci[0] __aligned(NETDEV_ALIGN);
++};
++
++static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
++{
++	return w->wdev->wiphy;
++}
++
++static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
++{
++	return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
++}
++
++static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
++{
++	return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
++}
++
++static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
++{
++	return cfg->wdev->netdev;
++}
++
++static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
++{
++	return wdev_to_cfg(ndev->ieee80211_ptr);
++}
++
++#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
++#define cfg_to_iscan(w) (w->iscan)
++
++static inline struct
++brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
++{
++	return &cfg->conn_info;
++}
++
++extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++							struct device *busdev,
++							void *data);
++extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
++
++/* event handler from dongle */
++extern void brcmf_cfg80211_event(struct net_device *ndev,
++				 const struct brcmf_event_msg *e, void *data);
++extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
++extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
++
++#endif				/* _wl_cfg80211_h_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+new file mode 100644
+index 0000000..3c1f39d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+@@ -0,0 +1,48 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y := \
++	-D__CHECK_ENDIAN__ \
++	-I$(obj)				\
++	-I$(obj)/phy				\
++	-I$(obj)/../include
++
++BRCMSMAC_OFILES := \
++	mac80211_if.o \
++	ucode_loader.o \
++	ampdu.o \
++	antsel.o \
++	channel.o \
++	main.o \
++	phy_shim.o \
++	pmu.o \
++	rate.o \
++	stf.o \
++	aiutils.o \
++	phy/phy_cmn.o \
++	phy/phy_lcn.o \
++	phy/phy_n.o \
++	phy/phytbl_lcn.o \
++	phy/phytbl_n.o \
++	phy/phy_qmath.o \
++	dma.o \
++	brcms_trace_events.o
++
++MODULEPFX := brcmsmac
++
++obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+new file mode 100644
+index 0000000..94e040a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+@@ -0,0 +1,841 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * File contents: support functions for PCI/PCIe
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/delay.h>
++
++#include <defs.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "types.h"
++#include "pub.h"
++#include "pmu.h"
++#include "aiutils.h"
++
++/* slow_clk_ctl */
++ /* slow clock source mask */
++#define SCC_SS_MASK		0x00000007
++ /* source of slow clock is LPO */
++#define	SCC_SS_LPO		0x00000000
++ /* source of slow clock is crystal */
++#define	SCC_SS_XTAL		0x00000001
++ /* source of slow clock is PCI */
++#define	SCC_SS_PCI		0x00000002
++ /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
++#define SCC_LF			0x00000200
++ /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
++#define SCC_LP			0x00000400
++ /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
++#define SCC_FS			0x00000800
++ /* IgnorePllOffReq, 1/0:
++  *  power logic ignores/honors PLL clock disable requests from core
++  */
++#define SCC_IP			0x00001000
++ /* XtalControlEn, 1/0:
++  *  power logic does/doesn't disable crystal when appropriate
++  */
++#define SCC_XC			0x00002000
++ /* XtalPU (RO), 1/0: crystal running/disabled */
++#define SCC_XP			0x00004000
++ /* ClockDivider (SlowClk = 1/(4+divisor)) */
++#define SCC_CD_MASK		0xffff0000
++#define SCC_CD_SHIFT		16
++
++/* system_clk_ctl */
++ /* ILPen: Enable Idle Low Power */
++#define	SYCC_IE			0x00000001
++ /* ALPen: Enable Active Low Power */
++#define	SYCC_AE			0x00000002
++ /* ForcePLLOn */
++#define	SYCC_FP			0x00000004
++ /* Force ALP (or HT if ALPen is not set */
++#define	SYCC_AR			0x00000008
++ /* Force HT */
++#define	SYCC_HR			0x00000010
++ /* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
++#define SYCC_CD_MASK		0xffff0000
++#define SYCC_CD_SHIFT		16
++
++#define CST4329_SPROM_OTP_SEL_MASK	0x00000003
++ /* OTP is powered up, use def. CIS, no SPROM */
++#define CST4329_DEFCIS_SEL		0
++ /* OTP is powered up, SPROM is present */
++#define CST4329_SPROM_SEL		1
++ /* OTP is powered up, no SPROM */
++#define CST4329_OTP_SEL			2
++ /* OTP is powered down, SPROM is present */
++#define CST4329_OTP_PWRDN		3
++
++#define CST4329_SPI_SDIO_MODE_MASK	0x00000004
++#define CST4329_SPI_SDIO_MODE_SHIFT	2
++
++/* 43224 chip-specific ChipControl register bits */
++#define CCTRL43224_GPIO_TOGGLE          0x8000
++ /* 12 mA drive strength */
++#define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0
++ /* 12 mA drive strength for later 43224s */
++#define CCTRL_43224B0_12MA_LED_DRIVE    0xF0
++
++/* 43236 Chip specific ChipStatus register bits */
++#define CST43236_SFLASH_MASK		0x00000040
++#define CST43236_OTP_MASK		0x00000080
++#define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
++#define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
++#define CST43236_BOOT_MASK		0x00001800
++#define CST43236_BOOT_SHIFT		11
++#define CST43236_BOOT_FROM_SRAM		0 /* boot from SRAM, ARM in reset */
++#define CST43236_BOOT_FROM_ROM		1 /* boot from ROM */
++#define CST43236_BOOT_FROM_FLASH	2 /* boot from FLASH */
++#define CST43236_BOOT_FROM_INVALID	3
++
++/* 4331 chip-specific ChipControl register bits */
++ /* 0 disable */
++#define CCTRL4331_BT_COEXIST		(1<<0)
++ /* 0 SECI is disabled (JTAG functional) */
++#define CCTRL4331_SECI			(1<<1)
++ /* 0 disable */
++#define CCTRL4331_EXT_LNA		(1<<2)
++ /* sprom/gpio13-15 mux */
++#define CCTRL4331_SPROM_GPIO13_15       (1<<3)
++ /* 0 ext pa disable, 1 ext pa enabled */
++#define CCTRL4331_EXTPA_EN		(1<<4)
++ /* set drive out GPIO_CLK on sprom_cs pin */
++#define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)
++ /* use sprom_cs pin as PCIE mdio interface */
++#define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)
++ /* aband extpa will be at gpio2/5 and sprom_dout */
++#define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)
++ /* override core control on pipe_AuxClkEnable */
++#define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)
++ /* override core control on pipe_AuxPowerDown */
++#define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)
++ /* pcie_auxclkenable */
++#define CCTRL4331_PCIE_AUXCLKEN		(1<<10)
++ /* pcie_pipe_pllpowerdown */
++#define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)
++ /* enable bt_shd0 at gpio4 */
++#define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)
++ /* enable bt_shd1 at gpio5 */
++#define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)
++
++/* 4331 Chip specific ChipStatus register bits */
++ /* crystal frequency 20/40Mhz */
++#define	CST4331_XTAL_FREQ		0x00000001
++#define	CST4331_SPROM_PRESENT		0x00000002
++#define	CST4331_OTP_PRESENT		0x00000004
++#define	CST4331_LDO_RF			0x00000008
++#define	CST4331_LDO_PAR			0x00000010
++
++/* 4319 chip-specific ChipStatus register bits */
++#define	CST4319_SPI_CPULESSUSB		0x00000001
++#define	CST4319_SPI_CLK_POL		0x00000002
++#define	CST4319_SPI_CLK_PH		0x00000008
++ /* gpio [7:6], SDIO CIS selection */
++#define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0
++#define	CST4319_SPROM_OTP_SEL_SHIFT	6
++ /* use default CIS, OTP is powered up */
++#define	CST4319_DEFCIS_SEL		0x00000000
++ /* use SPROM, OTP is powered up */
++#define	CST4319_SPROM_SEL		0x00000040
++ /* use OTP, OTP is powered up */
++#define	CST4319_OTP_SEL			0x00000080
++ /* use SPROM, OTP is powered down */
++#define	CST4319_OTP_PWRDN		0x000000c0
++ /* gpio [8], sdio/usb mode */
++#define	CST4319_SDIO_USB_MODE		0x00000100
++#define	CST4319_REMAP_SEL_MASK		0x00000600
++#define	CST4319_ILPDIV_EN		0x00000800
++#define	CST4319_XTAL_PD_POL		0x00001000
++#define	CST4319_LPO_SEL			0x00002000
++#define	CST4319_RES_INIT_MODE		0x0000c000
++ /* PALDO is configured with external PNP */
++#define	CST4319_PALDO_EXTPNP		0x00010000
++#define	CST4319_CBUCK_MODE_MASK		0x00060000
++#define CST4319_CBUCK_MODE_BURST	0x00020000
++#define CST4319_CBUCK_MODE_LPBURST	0x00060000
++#define	CST4319_RCAL_VALID		0x01000000
++#define	CST4319_RCAL_VALUE_MASK		0x3e000000
++#define	CST4319_RCAL_VALUE_SHIFT	25
++
++/* 4336 chip-specific ChipStatus register bits */
++#define	CST4336_SPI_MODE_MASK		0x00000001
++#define	CST4336_SPROM_PRESENT		0x00000002
++#define	CST4336_OTP_PRESENT		0x00000004
++#define	CST4336_ARMREMAP_0		0x00000008
++#define	CST4336_ILPDIV_EN_MASK		0x00000010
++#define	CST4336_ILPDIV_EN_SHIFT		4
++#define	CST4336_XTAL_PD_POL_MASK	0x00000020
++#define	CST4336_XTAL_PD_POL_SHIFT	5
++#define	CST4336_LPO_SEL_MASK		0x00000040
++#define	CST4336_LPO_SEL_SHIFT		6
++#define	CST4336_RES_INIT_MODE_MASK	0x00000180
++#define	CST4336_RES_INIT_MODE_SHIFT	7
++#define	CST4336_CBUCK_MODE_MASK		0x00000600
++#define	CST4336_CBUCK_MODE_SHIFT	9
++
++/* 4313 chip-specific ChipStatus register bits */
++#define	CST4313_SPROM_PRESENT			1
++#define	CST4313_OTP_PRESENT			2
++#define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
++#define	CST4313_SPROM_OTP_SEL_SHIFT		0
++
++/* 4313 Chip specific ChipControl register bits */
++ /* 12 mA drive strengh for later 4313 */
++#define CCTRL_4313_12MA_LED_DRIVE    0x00000007
++
++/* Manufacturer Ids */
++#define	MFGID_ARM		0x43b
++#define	MFGID_BRCM		0x4bf
++#define	MFGID_MIPS		0x4a7
++
++/* Enumeration ROM registers */
++#define	ER_EROMENTRY		0x000
++#define	ER_REMAPCONTROL		0xe00
++#define	ER_REMAPSELECT		0xe04
++#define	ER_MASTERSELECT		0xe10
++#define	ER_ITCR			0xf00
++#define	ER_ITIP			0xf04
++
++/* Erom entries */
++#define	ER_TAG			0xe
++#define	ER_TAG1			0x6
++#define	ER_VALID		1
++#define	ER_CI			0
++#define	ER_MP			2
++#define	ER_ADD			4
++#define	ER_END			0xe
++#define	ER_BAD			0xffffffff
++
++/* EROM CompIdentA */
++#define	CIA_MFG_MASK		0xfff00000
++#define	CIA_MFG_SHIFT		20
++#define	CIA_CID_MASK		0x000fff00
++#define	CIA_CID_SHIFT		8
++#define	CIA_CCL_MASK		0x000000f0
++#define	CIA_CCL_SHIFT		4
++
++/* EROM CompIdentB */
++#define	CIB_REV_MASK		0xff000000
++#define	CIB_REV_SHIFT		24
++#define	CIB_NSW_MASK		0x00f80000
++#define	CIB_NSW_SHIFT		19
++#define	CIB_NMW_MASK		0x0007c000
++#define	CIB_NMW_SHIFT		14
++#define	CIB_NSP_MASK		0x00003e00
++#define	CIB_NSP_SHIFT		9
++#define	CIB_NMP_MASK		0x000001f0
++#define	CIB_NMP_SHIFT		4
++
++/* EROM AddrDesc */
++#define	AD_ADDR_MASK		0xfffff000
++#define	AD_SP_MASK		0x00000f00
++#define	AD_SP_SHIFT		8
++#define	AD_ST_MASK		0x000000c0
++#define	AD_ST_SHIFT		6
++#define	AD_ST_SLAVE		0x00000000
++#define	AD_ST_BRIDGE		0x00000040
++#define	AD_ST_SWRAP		0x00000080
++#define	AD_ST_MWRAP		0x000000c0
++#define	AD_SZ_MASK		0x00000030
++#define	AD_SZ_SHIFT		4
++#define	AD_SZ_4K		0x00000000
++#define	AD_SZ_8K		0x00000010
++#define	AD_SZ_16K		0x00000020
++#define	AD_SZ_SZD		0x00000030
++#define	AD_AG32			0x00000008
++#define	AD_ADDR_ALIGN		0x00000fff
++#define	AD_SZ_BASE		0x00001000	/* 4KB */
++
++/* EROM SizeDesc */
++#define	SD_SZ_MASK		0xfffff000
++#define	SD_SG32			0x00000008
++#define	SD_SZ_ALIGN		0x00000fff
++
++/* PCI config space bit 4 for 4306c0 slow clock source */
++#define	PCI_CFG_GPIO_SCS	0x10
++/* PCI config space GPIO 14 for Xtal power-up */
++#define PCI_CFG_GPIO_XTAL	0x40
++/* PCI config space GPIO 15 for PLL power-down */
++#define PCI_CFG_GPIO_PLL	0x80
++
++/* power control defines */
++#define PLL_DELAY		150	/* us pll on delay */
++#define FREF_DELAY		200	/* us fref change delay */
++#define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
++
++/* resetctrl */
++#define	AIRC_RESET		1
++
++#define	NOREV		-1	/* Invalid rev */
++
++/* GPIO Based LED powersave defines */
++#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
++#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
++
++/* When Srom support present, fields in sromcontrol */
++#define	SRC_START		0x80000000
++#define	SRC_BUSY		0x80000000
++#define	SRC_OPCODE		0x60000000
++#define	SRC_OP_READ		0x00000000
++#define	SRC_OP_WRITE		0x20000000
++#define	SRC_OP_WRDIS		0x40000000
++#define	SRC_OP_WREN		0x60000000
++#define	SRC_OTPSEL		0x00000010
++#define	SRC_LOCK		0x00000008
++#define	SRC_SIZE_MASK		0x00000006
++#define	SRC_SIZE_1K		0x00000000
++#define	SRC_SIZE_4K		0x00000002
++#define	SRC_SIZE_16K		0x00000004
++#define	SRC_SIZE_SHIFT		1
++#define	SRC_PRESENT		0x00000001
++
++/* External PA enable mask */
++#define GPIO_CTRL_EPA_EN_MASK 0x40
++
++#define DEFAULT_GPIOTIMERVAL \
++	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
++
++#define	BADIDX		(SI_MAXCORES + 1)
++
++#define	IS_SIM(chippkg)	\
++	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
++
++#define PCIE(sih)	(ai_get_buscoretype(sih) == PCIE_CORE_ID)
++
++#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
++
++#ifdef DEBUG
++#define	SI_MSG(fmt, ...)	pr_debug(fmt, ##__VA_ARGS__)
++#else
++#define	SI_MSG(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	GOODCOREADDR(x, b) \
++	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
++		IS_ALIGNED((x), SI_CORE_SIZE))
++
++struct aidmp {
++	u32 oobselina30;	/* 0x000 */
++	u32 oobselina74;	/* 0x004 */
++	u32 PAD[6];
++	u32 oobselinb30;	/* 0x020 */
++	u32 oobselinb74;	/* 0x024 */
++	u32 PAD[6];
++	u32 oobselinc30;	/* 0x040 */
++	u32 oobselinc74;	/* 0x044 */
++	u32 PAD[6];
++	u32 oobselind30;	/* 0x060 */
++	u32 oobselind74;	/* 0x064 */
++	u32 PAD[38];
++	u32 oobselouta30;	/* 0x100 */
++	u32 oobselouta74;	/* 0x104 */
++	u32 PAD[6];
++	u32 oobseloutb30;	/* 0x120 */
++	u32 oobseloutb74;	/* 0x124 */
++	u32 PAD[6];
++	u32 oobseloutc30;	/* 0x140 */
++	u32 oobseloutc74;	/* 0x144 */
++	u32 PAD[6];
++	u32 oobseloutd30;	/* 0x160 */
++	u32 oobseloutd74;	/* 0x164 */
++	u32 PAD[38];
++	u32 oobsynca;	/* 0x200 */
++	u32 oobseloutaen;	/* 0x204 */
++	u32 PAD[6];
++	u32 oobsyncb;	/* 0x220 */
++	u32 oobseloutben;	/* 0x224 */
++	u32 PAD[6];
++	u32 oobsyncc;	/* 0x240 */
++	u32 oobseloutcen;	/* 0x244 */
++	u32 PAD[6];
++	u32 oobsyncd;	/* 0x260 */
++	u32 oobseloutden;	/* 0x264 */
++	u32 PAD[38];
++	u32 oobaextwidth;	/* 0x300 */
++	u32 oobainwidth;	/* 0x304 */
++	u32 oobaoutwidth;	/* 0x308 */
++	u32 PAD[5];
++	u32 oobbextwidth;	/* 0x320 */
++	u32 oobbinwidth;	/* 0x324 */
++	u32 oobboutwidth;	/* 0x328 */
++	u32 PAD[5];
++	u32 oobcextwidth;	/* 0x340 */
++	u32 oobcinwidth;	/* 0x344 */
++	u32 oobcoutwidth;	/* 0x348 */
++	u32 PAD[5];
++	u32 oobdextwidth;	/* 0x360 */
++	u32 oobdinwidth;	/* 0x364 */
++	u32 oobdoutwidth;	/* 0x368 */
++	u32 PAD[37];
++	u32 ioctrlset;	/* 0x400 */
++	u32 ioctrlclear;	/* 0x404 */
++	u32 ioctrl;		/* 0x408 */
++	u32 PAD[61];
++	u32 iostatus;	/* 0x500 */
++	u32 PAD[127];
++	u32 ioctrlwidth;	/* 0x700 */
++	u32 iostatuswidth;	/* 0x704 */
++	u32 PAD[62];
++	u32 resetctrl;	/* 0x800 */
++	u32 resetstatus;	/* 0x804 */
++	u32 resetreadid;	/* 0x808 */
++	u32 resetwriteid;	/* 0x80c */
++	u32 PAD[60];
++	u32 errlogctrl;	/* 0x900 */
++	u32 errlogdone;	/* 0x904 */
++	u32 errlogstatus;	/* 0x908 */
++	u32 errlogaddrlo;	/* 0x90c */
++	u32 errlogaddrhi;	/* 0x910 */
++	u32 errlogid;	/* 0x914 */
++	u32 errloguser;	/* 0x918 */
++	u32 errlogflags;	/* 0x91c */
++	u32 PAD[56];
++	u32 intstatus;	/* 0xa00 */
++	u32 PAD[127];
++	u32 config;		/* 0xe00 */
++	u32 PAD[63];
++	u32 itcr;		/* 0xf00 */
++	u32 PAD[3];
++	u32 itipooba;	/* 0xf10 */
++	u32 itipoobb;	/* 0xf14 */
++	u32 itipoobc;	/* 0xf18 */
++	u32 itipoobd;	/* 0xf1c */
++	u32 PAD[4];
++	u32 itipoobaout;	/* 0xf30 */
++	u32 itipoobbout;	/* 0xf34 */
++	u32 itipoobcout;	/* 0xf38 */
++	u32 itipoobdout;	/* 0xf3c */
++	u32 PAD[4];
++	u32 itopooba;	/* 0xf50 */
++	u32 itopoobb;	/* 0xf54 */
++	u32 itopoobc;	/* 0xf58 */
++	u32 itopoobd;	/* 0xf5c */
++	u32 PAD[4];
++	u32 itopoobain;	/* 0xf70 */
++	u32 itopoobbin;	/* 0xf74 */
++	u32 itopoobcin;	/* 0xf78 */
++	u32 itopoobdin;	/* 0xf7c */
++	u32 PAD[4];
++	u32 itopreset;	/* 0xf90 */
++	u32 PAD[15];
++	u32 peripherialid4;	/* 0xfd0 */
++	u32 peripherialid5;	/* 0xfd4 */
++	u32 peripherialid6;	/* 0xfd8 */
++	u32 peripherialid7;	/* 0xfdc */
++	u32 peripherialid0;	/* 0xfe0 */
++	u32 peripherialid1;	/* 0xfe4 */
++	u32 peripherialid2;	/* 0xfe8 */
++	u32 peripherialid3;	/* 0xfec */
++	u32 componentid0;	/* 0xff0 */
++	u32 componentid1;	/* 0xff4 */
++	u32 componentid2;	/* 0xff8 */
++	u32 componentid3;	/* 0xffc */
++};
++
++static bool
++ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
++{
++	/* no cores found, bail out */
++	if (cc->bus->nr_cores == 0)
++		return false;
++
++	/* get chipcommon rev */
++	sii->pub.ccrev = cc->id.rev;
++
++	/* get chipcommon chipstatus */
++	sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
++
++	/* get chipcommon capabilites */
++	sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
++
++	/* get pmu rev and caps */
++	if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
++		sii->pub.pmucaps = bcma_read32(cc,
++					       CHIPCREGOFFS(pmucapabilities));
++		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
++	}
++
++	/* figure out buscore */
++	sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0);
++
++	return true;
++}
++
++static struct si_info *ai_doattach(struct si_info *sii,
++				   struct bcma_bus *pbus)
++{
++	struct si_pub *sih = &sii->pub;
++	u32 w, savewin;
++	struct bcma_device *cc;
++	struct ssb_sprom *sprom = &pbus->sprom;
++
++	savewin = 0;
++
++	sii->icbus = pbus;
++	sii->pcibus = pbus->host_pci;
++
++	/* switch to Chipcommon core */
++	cc = pbus->drv_cc.core;
++
++	sih->chip = pbus->chipinfo.id;
++	sih->chiprev = pbus->chipinfo.rev;
++	sih->chippkg = pbus->chipinfo.pkg;
++	sih->boardvendor = pbus->boardinfo.vendor;
++	sih->boardtype = pbus->boardinfo.type;
++
++	if (!ai_buscore_setup(sii, cc))
++		goto exit;
++
++	/* === NVRAM, clock is ready === */
++	bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
++	bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
++
++	/* PMU specific initializations */
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		si_pmu_init(sih);
++		(void)si_pmu_measure_alpclk(sih);
++		si_pmu_res_init(sih);
++	}
++
++	/* setup the GPIO based LED powersave register */
++	w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
++		 (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT);
++	if (w == 0)
++		w = DEFAULT_GPIOTIMERVAL;
++	ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
++		  ~0, w);
++
++	if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 43224 and
++		 * set chipControl register bit 15
++		 */
++		if (ai_get_chiprev(sih) == 0) {
++			SI_MSG("Applying 43224A0 WARs\n");
++			ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol),
++				  CCTRL43224_GPIO_TOGGLE,
++				  CCTRL43224_GPIO_TOGGLE);
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
++					   CCTRL_43224A0_12MA_LED_DRIVE);
++		}
++		if (ai_get_chiprev(sih) >= 1) {
++			SI_MSG("Applying 43224B0+ WARs\n");
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
++					   CCTRL_43224B0_12MA_LED_DRIVE);
++		}
++	}
++
++	if (ai_get_chip_id(sih) == BCM4313_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 4313 and
++		 * set chipControl register bit 1
++		 */
++		SI_MSG("Applying 4313 WARs\n");
++		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
++				   CCTRL_4313_12MA_LED_DRIVE);
++	}
++
++	return sii;
++
++ exit:
++
++	return NULL;
++}
++
++/*
++ * Allocate a si handle and do the attach.
++ */
++struct si_pub *
++ai_attach(struct bcma_bus *pbus)
++{
++	struct si_info *sii;
++
++	/* alloc struct si_info */
++	sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC);
++	if (sii == NULL)
++		return NULL;
++
++	if (ai_doattach(sii, pbus) == NULL) {
++		kfree(sii);
++		return NULL;
++	}
++
++	return (struct si_pub *) sii;
++}
++
++/* may be called with core in reset */
++void ai_detach(struct si_pub *sih)
++{
++	struct si_info *sii;
++
++	struct si_pub *si_local = NULL;
++	memcpy(&si_local, &sih, sizeof(struct si_pub **));
++
++	sii = (struct si_info *)sih;
++
++	if (sii == NULL)
++		return;
++
++	kfree(sii);
++}
++
++/* return index of coreid or BADIDX if not found */
++struct bcma_device *ai_findcore(struct si_pub *sih, u16 coreid, u16 coreunit)
++{
++	struct bcma_device *core;
++	struct si_info *sii;
++	uint found;
++
++	sii = (struct si_info *)sih;
++
++	found = 0;
++
++	list_for_each_entry(core, &sii->icbus->cores, list)
++		if (core->id.id == coreid) {
++			if (found == coreunit)
++				return core;
++			found++;
++		}
++
++	return NULL;
++}
++
++/*
++ * read/modify chipcommon core register.
++ */
++uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
++{
++	struct bcma_device *cc;
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++	cc = sii->icbus->drv_cc.core;
++
++	/* mask and set */
++	if (mask || val) {
++		bcma_maskset32(cc, regoff, ~mask, val);
++	}
++
++	/* readback */
++	w = bcma_read32(cc, regoff);
++
++	return w;
++}
++
++/* return the slow clock source - LPO, XTAL, or PCI */
++static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
++{
++	return SCC_SS_XTAL;
++}
++
++/*
++* return the ILP (slowclock) min or max frequency
++* precondition: we've established the chip has dynamic clk control
++*/
++static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
++			    struct bcma_device *cc)
++{
++	uint div;
++
++	/* Chipc rev 10 is InstaClock */
++	div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
++	div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
++	return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
++}
++
++static void
++ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
++{
++	uint slowmaxfreq, pll_delay, slowclk;
++	uint pll_on_delay, fref_sel_delay;
++
++	pll_delay = PLL_DELAY;
++
++	/*
++	 * If the slow clock is not sourced by the xtal then
++	 * add the xtal_on_delay since the xtal will also be
++	 * powered down by dynamic clk control logic.
++	 */
++
++	slowclk = ai_slowclk_src(sih, cc);
++	if (slowclk != SCC_SS_XTAL)
++		pll_delay += XTAL_ON_DELAY;
++
++	/* Starting with 4318 it is ILP that is used for the delays */
++	slowmaxfreq =
++	    ai_slowclk_freq(sih, false, cc);
++
++	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
++	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
++
++	bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay);
++	bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay);
++}
++
++/* initialize power control delay registers */
++void ai_clkctl_init(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return;
++
++	cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++	if (cc == NULL)
++		return;
++
++	/* set all Instaclk chip ILP to 1 MHz */
++	bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
++		       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
++
++	ai_clkctl_setdelay(sih, cc);
++}
++
++/*
++ * return the value suitable for writing to the
++ * dot11 core FAST_PWRUP_DELAY register
++ */
++u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++	uint slowminfreq;
++	u16 fpdelay;
++
++	sii = (struct si_info *)sih;
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		fpdelay = si_pmu_fast_pwrup_delay(sih);
++		return fpdelay;
++	}
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return 0;
++
++	fpdelay = 0;
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++	if (cc) {
++		slowminfreq = ai_slowclk_freq(sih, false, cc);
++		fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2)
++			    * 1000000) + (slowminfreq - 1)) / slowminfreq;
++	}
++	return fpdelay;
++}
++
++/*
++ *  clock control policy function throught chipcommon
++ *
++ *    set dynamic clk control mode (forceslow, forcefast, dynamic)
++ *    returns true if we are forcing fast clock
++ *    this is a wrapper over the next internal function
++ *      to allow flexible policy settings for outside caller
++ */
++bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih))
++		return mode == BCMA_CLKMODE_FAST;
++
++	cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++	bcma_core_set_clockmode(cc, mode);
++	return mode == BCMA_CLKMODE_FAST;
++}
++
++void ai_pci_up(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
++}
++
++/* Unconfigure and/or apply various WARs when going down */
++void ai_pci_down(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	/* release FORCEHT since chip is going to "down" state */
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
++}
++
++/* Enable BT-COEX & Ex-PA for 4313 */
++void ai_epa_4313war(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++
++	/* EPA Fix */
++	bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK);
++}
++
++/* check if the device is removed */
++bool ai_deviceremoved(struct si_pub *sih)
++{
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++
++	if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
++		return false;
++
++	pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
++	if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	return false;
++}
++
++uint ai_get_buscoretype(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.id;
++}
++
++uint ai_get_buscorerev(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.rev;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+new file mode 100644
+index 0000000..d9f04a6
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_AIUTILS_H_
++#define	_BRCM_AIUTILS_H_
++
++#include <linux/bcma/bcma.h>
++
++#include "types.h"
++
++/*
++ * SOC Interconnect Address Map.
++ * All regions may not exist on all chips.
++ */
++/* each core gets 4Kbytes for registers */
++#define SI_CORE_SIZE		0x1000
++/*
++ * Max cores (this is arbitrary, for software
++ * convenience and could be changed if we
++ * make any larger chips
++ */
++#define	SI_MAXCORES		16
++
++/* Client Mode sb2pcitranslation2 size in bytes */
++#define SI_PCI_DMA_SZ		0x40000000
++
++/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
++#define SI_PCIE_DMA_H32		0x80000000
++
++/* chipcommon being the first core: */
++#define	SI_CC_IDX		0
++
++/* SOC Interconnect types (aka chip types) */
++#define	SOCI_AI			1
++
++/* A register that is common to all cores to
++ * communicate w/PMU regarding clock control.
++ */
++#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
++
++/* clk_ctl_st register */
++#define	CCS_FORCEALP		0x00000001	/* force ALP request */
++#define	CCS_FORCEHT		0x00000002	/* force HT request */
++#define	CCS_FORCEILP		0x00000004	/* force ILP request */
++#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
++#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
++#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
++#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
++#define CCS_ERSRC_REQ_SHIFT	8
++#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
++#define	CCS_HTAVAIL		0x00020000	/* HT is available */
++#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
++#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
++#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
++#define CCS_ERSRC_STS_SHIFT	24
++
++/* HT avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_HTAVAIL		0x00010000
++/* ALP avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_ALPAVAIL		0x00020000
++
++/* Not really related to SOC Interconnect, but a couple of software
++ * conventions for the use the flash space:
++ */
++
++/* Minumum amount of flash we support */
++#define FLASH_MIN		0x00020000	/* Minimum flash size */
++
++#define	CC_SROM_OTP		0x800	/* SROM/OTP address space */
++
++/* gpiotimerval */
++#define GPIO_ONTIME_SHIFT	16
++
++/* Fields in clkdiv */
++#define	CLKD_OTP		0x000f0000
++#define	CLKD_OTP_SHIFT		16
++
++/* Package IDs */
++#define	BCM4717_PKG_ID		9	/* 4717 package id */
++#define	BCM4718_PKG_ID		10	/* 4718 package id */
++#define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
++
++/* these are router chips */
++#define	BCM4716_CHIP_ID		0x4716	/* 4716 chipcommon chipid */
++#define	BCM47162_CHIP_ID	47162	/* 47162 chipcommon chipid */
++#define	BCM4748_CHIP_ID		0x4748	/* 4716 chipcommon chipid (OTP, RBBU) */
++
++/* dynamic clock control defines */
++#define	LPOMINFREQ		25000	/* low power oscillator min */
++#define	LPOMAXFREQ		43000	/* low power oscillator max */
++#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
++#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
++#define	PCIMINFREQ		25000000	/* 25 MHz */
++#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
++
++#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
++#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
++
++/* clkctl xtal what flags */
++#define	XTAL			0x1	/* primary crystal oscillator (2050) */
++#define	PLL			0x2	/* main chip pll */
++
++/* GPIO usage priorities */
++#define GPIO_DRV_PRIORITY	0	/* Driver */
++#define GPIO_APP_PRIORITY	1	/* Application */
++#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
++					 * reservation
++					 */
++
++/* GPIO pull up/down */
++#define GPIO_PULLUP		0
++#define GPIO_PULLDN		1
++
++/* GPIO event regtype */
++#define GPIO_REGEVT		0	/* GPIO register event */
++#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
++#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
++
++/* device path */
++#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
++
++/* SI routine enumeration: to be used by update function with multiple hooks */
++#define	SI_DOATTACH	1
++#define SI_PCIDOWN	2
++#define SI_PCIUP	3
++
++/*
++ * Data structure to export all chip specific common variables
++ *   public (read-only) portion of aiutils handle returned by si_attach()
++ */
++struct si_pub {
++	int ccrev;		/* chip common core rev */
++	u32 cccaps;		/* chip common capabilities */
++	int pmurev;		/* pmu core rev */
++	u32 pmucaps;		/* pmu capabilities */
++	uint boardtype;		/* board type */
++	uint boardvendor;	/* board vendor */
++	uint chip;		/* chip number */
++	uint chiprev;		/* chip revision */
++	uint chippkg;		/* chip package option */
++};
++
++struct pci_dev;
++
++struct gpioh_item {
++	void *arg;
++	bool level;
++	void (*handler) (u32 stat, void *arg);
++	u32 event;
++	struct gpioh_item *next;
++};
++
++/* misc si info needed by some of the routines */
++struct si_info {
++	struct si_pub pub;	/* back plane public state (must be first) */
++	struct bcma_bus *icbus;	/* handle to soc interconnect bus */
++	struct pci_dev *pcibus;	/* handle to pci bus */
++	struct bcma_device *buscore;
++
++	u32 chipst;		/* chip status */
++};
++
++/*
++ * Many of the routines below take an 'sih' handle as their first arg.
++ * Allocate this by calling si_attach().  Free it by calling si_detach().
++ * At any one time, the sih is logically focused on one particular si core
++ * (the "current core").
++ * Use si_setcore() or si_setcoreidx() to change the association to another core
++ */
++
++
++/* AMBA Interconnect exported externs */
++extern struct bcma_device *ai_findcore(struct si_pub *sih,
++				       u16 coreid, u16 coreunit);
++extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
++
++/* === exported functions === */
++extern struct si_pub *ai_attach(struct bcma_bus *pbus);
++extern void ai_detach(struct si_pub *sih);
++extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
++extern void ai_clkctl_init(struct si_pub *sih);
++extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
++extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
++extern bool ai_deviceremoved(struct si_pub *sih);
++
++extern void ai_pci_down(struct si_pub *sih);
++extern void ai_pci_up(struct si_pub *sih);
++
++/* Enable Ex-PA for 4313 */
++extern void ai_epa_4313war(struct si_pub *sih);
++
++extern uint ai_get_buscoretype(struct si_pub *sih);
++extern uint ai_get_buscorerev(struct si_pub *sih);
++
++static inline u32 ai_get_cccaps(struct si_pub *sih)
++{
++	return sih->cccaps;
++}
++
++static inline int ai_get_pmurev(struct si_pub *sih)
++{
++	return sih->pmurev;
++}
++
++static inline u32 ai_get_pmucaps(struct si_pub *sih)
++{
++	return sih->pmucaps;
++}
++
++static inline uint ai_get_boardtype(struct si_pub *sih)
++{
++	return sih->boardtype;
++}
++
++static inline uint ai_get_boardvendor(struct si_pub *sih)
++{
++	return sih->boardvendor;
++}
++
++static inline uint ai_get_chip_id(struct si_pub *sih)
++{
++	return sih->chip;
++}
++
++static inline uint ai_get_chiprev(struct si_pub *sih)
++{
++	return sih->chiprev;
++}
++
++static inline uint ai_get_chippkg(struct si_pub *sih)
++{
++	return sih->chippkg;
++}
++
++#endif				/* _BRCM_AIUTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+new file mode 100644
+index 0000000..95b5902
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+@@ -0,0 +1,1236 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <net/mac80211.h>
++
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "antsel.h"
++#include "main.h"
++#include "ampdu.h"
++
++/* max number of mpdus in an ampdu */
++#define AMPDU_MAX_MPDU			32
++/* max number of mpdus in an ampdu to a legacy */
++#define AMPDU_NUM_MPDU_LEGACY		16
++/* max Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_MAX_WSIZE		64
++/* default Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_DEF_WSIZE		64
++/* default Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_DEF_WSIZE		64
++/* max Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_MAX_WSIZE		64
++/* max dur of tx ampdu (in msec) */
++#define	AMPDU_MAX_DUR			5
++/* default tx retry limit */
++#define AMPDU_DEF_RETRY_LIMIT		5
++/* default tx retry limit at reg rate */
++#define AMPDU_DEF_RR_RETRY_LIMIT	2
++/* default weight of ampdu in txfifo */
++#define AMPDU_DEF_TXPKT_WEIGHT		2
++/* default ffpld reserved bytes */
++#define AMPDU_DEF_FFPLD_RSVD		2048
++/* # of inis to be freed on detach */
++#define AMPDU_INI_FREE			10
++/* max # of mpdus released at a time */
++#define	AMPDU_SCB_MAX_RELEASE		20
++
++#define NUM_FFPLD_FIFO 4	/* number of fifo concerned by pre-loading */
++#define FFPLD_TX_MAX_UNFL   200	/* default value of the average number of ampdu
++				 * without underflows
++				 */
++#define FFPLD_MPDU_SIZE 1800	/* estimate of maximum mpdu size */
++#define FFPLD_MAX_MCS 23	/* we don't deal with mcs 32 */
++#define FFPLD_PLD_INCR 1000	/* increments in bytes */
++#define FFPLD_MAX_AMPDU_CNT 5000	/* maximum number of ampdu we
++					 * accumulate between resets.
++					 */
++
++#define AMPDU_DELIMITER_LEN	4
++
++/* max allowed number of mpdus in an ampdu (2 streams) */
++#define AMPDU_NUM_MPDU		16
++
++#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
++
++/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
++#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
++	AMPDU_DELIMITER_LEN + 3\
++	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
++
++/* modulo add/sub, bound = 2^k */
++#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
++#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
++
++/* structure to hold tx fifo information and pre-loading state
++ * counters specific to tx underflows of ampdus
++ * some counters might be redundant with the ones in wlc or ampdu structures.
++ * This allows to maintain a specific state independently of
++ * how often and/or when the wlc counters are updated.
++ *
++ * ampdu_pld_size: number of bytes to be pre-loaded
++ * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
++ * prev_txfunfl: num of underflows last read from the HW macstats counter
++ * accum_txfunfl: num of underflows since we modified pld params
++ * accum_txampdu: num of tx ampdu since we modified pld params
++ * prev_txampdu: previous reading of tx ampdu
++ * dmaxferrate: estimated dma avg xfer rate in kbits/sec
++ */
++struct brcms_fifo_info {
++	u16 ampdu_pld_size;
++	u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
++	u16 prev_txfunfl;
++	u32 accum_txfunfl;
++	u32 accum_txampdu;
++	u32 prev_txampdu;
++	u32 dmaxferrate;
++};
++
++/* AMPDU module specific state
++ *
++ * wlc: pointer to main wlc structure
++ * scb_handle: scb cubby handle to retrieve data from scb
++ * ini_enable: per-tid initiator enable/disable of ampdu
++ * ba_tx_wsize: Tx ba window size (in pdu)
++ * ba_rx_wsize: Rx ba window size (in pdu)
++ * retry_limit: mpdu transmit retry limit
++ * rr_retry_limit: mpdu transmit retry limit at regular rate
++ * retry_limit_tid: per-tid mpdu transmit retry limit
++ * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
++ * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
++ * max_pdu: max pdus allowed in ampdu
++ * dur: max duration of an ampdu (in msec)
++ * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
++ * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
++ * ffpld_rsvd: number of bytes to reserve for preload
++ * max_txlen: max size of ampdu per mcs, bw and sgi
++ * mfbr: enable multiple fallback rate
++ * tx_max_funl: underflows should be kept such that
++ *		(tx_max_funfl*underflows) < tx frames
++ * fifo_tb: table of fifo infos
++ */
++struct ampdu_info {
++	struct brcms_c_info *wlc;
++	int scb_handle;
++	u8 ini_enable[AMPDU_MAX_SCB_TID];
++	u8 ba_tx_wsize;
++	u8 ba_rx_wsize;
++	u8 retry_limit;
++	u8 rr_retry_limit;
++	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 mpdu_density;
++	s8 max_pdu;
++	u8 dur;
++	u8 txpkt_weight;
++	u8 rx_factor;
++	u32 ffpld_rsvd;
++	u32 max_txlen[MCS_TABLE_SIZE][2][2];
++	bool mfbr;
++	u32 tx_max_funl;
++	struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
++};
++
++/* used for flushing ampdu packets */
++struct cb_del_ampdu_pars {
++	struct ieee80211_sta *sta;
++	u16 tid;
++};
++
++static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
++{
++	u32 rate, mcs;
++
++	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
++		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
++		/* 20MHz, No SGI */
++		rate = mcs_2_rate(mcs, false, false);
++		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
++		/* 40 MHz, No SGI */
++		rate = mcs_2_rate(mcs, true, false);
++		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
++		/* 20MHz, SGI */
++		rate = mcs_2_rate(mcs, false, true);
++		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
++		/* 40 MHz, SGI */
++		rate = mcs_2_rate(mcs, true, true);
++		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
++	}
++}
++
++static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
++{
++	if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
++		return true;
++	else
++		return false;
++}
++
++static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	wlc->pub->_ampdu = false;
++
++	if (on) {
++		if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
++				"nmode enabled\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		if (!brcms_c_ampdu_cap(ampdu)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
++				"ampdu capable\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		wlc->pub->_ampdu = on;
++	}
++
++	return 0;
++}
++
++static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
++{
++	int i, j;
++	struct brcms_fifo_info *fifo;
++
++	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
++		fifo = (ampdu->fifo_tb + j);
++		fifo->ampdu_pld_size = 0;
++		for (i = 0; i <= FFPLD_MAX_MCS; i++)
++			fifo->mcs2ampdu_table[i] = 255;
++		fifo->dmaxferrate = 0;
++		fifo->accum_txampdu = 0;
++		fifo->prev_txfunfl = 0;
++		fifo->accum_txfunfl = 0;
++
++	}
++}
++
++struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
++{
++	struct ampdu_info *ampdu;
++	int i;
++
++	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
++	if (!ampdu)
++		return NULL;
++
++	ampdu->wlc = wlc;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
++		ampdu->ini_enable[i] = true;
++	/* Disable ampdu for VO by default */
++	ampdu->ini_enable[PRIO_8021D_VO] = false;
++	ampdu->ini_enable[PRIO_8021D_NC] = false;
++
++	/* Disable ampdu for BK by default since not enough fifo space */
++	ampdu->ini_enable[PRIO_8021D_NONE] = false;
++	ampdu->ini_enable[PRIO_8021D_BK] = false;
++
++	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
++	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
++	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
++	ampdu->max_pdu = AUTO;
++	ampdu->dur = AMPDU_MAX_DUR;
++	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
++
++	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
++	/*
++	 * bump max ampdu rcv size to 64k for all 11n
++	 * devices except 4321A0 and 4321A1
++	 */
++	if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
++	else
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
++	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
++	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
++		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
++		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
++	}
++
++	brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
++	ampdu->mfbr = false;
++	/* try to set ampdu to the default value */
++	brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
++
++	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
++	brcms_c_ffpld_init(ampdu);
++
++	return ampdu;
++}
++
++void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
++{
++	kfree(ampdu);
++}
++
++static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
++					    struct scb *scb)
++{
++	struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
++	int i;
++
++	scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
++
++	/* go back to legacy size if some preloading is occurring */
++	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
++		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
++			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
++	}
++
++	/* apply user override */
++	if (ampdu->max_pdu != AUTO)
++		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
++
++	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
++				   AMPDU_SCB_MAX_RELEASE);
++
++	if (scb_ampdu->max_rx_ampdu_bytes)
++		scb_ampdu->release = min_t(u8, scb_ampdu->release,
++			scb_ampdu->max_rx_ampdu_bytes / 1600);
++
++	scb_ampdu->release = min(scb_ampdu->release,
++				 ampdu->fifo_tb[TX_AC_BE_FIFO].
++				 mcs2ampdu_table[FFPLD_MAX_MCS]);
++}
++
++static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
++{
++	brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
++}
++
++static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
++{
++	int i;
++	u32 phy_rate, dma_rate, tmp;
++	u8 max_mpdu;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
++
++	/* recompute the dma rate */
++	/* note : we divide/multiply by 100 to avoid integer overflows */
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++	phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	dma_rate =
++	    (((phy_rate / 100) *
++	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++	fifo->dmaxferrate = dma_rate;
++
++	/* fill up the mcs2ampdu table; do not recalc the last mcs */
++	dma_rate = dma_rate >> 7;
++	for (i = 0; i < FFPLD_MAX_MCS; i++) {
++		/* shifting to keep it within integer range */
++		phy_rate = mcs_2_rate(i, true, false) >> 7;
++		if (phy_rate > dma_rate) {
++			tmp = ((fifo->ampdu_pld_size * phy_rate) /
++			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
++			tmp = min_t(u32, tmp, 255);
++			fifo->mcs2ampdu_table[i] = (u8) tmp;
++		}
++	}
++}
++
++/* evaluate the dma transfer rate using the tx underflows as feedback.
++ * If necessary, increase tx fifo preloading. If not enough,
++ * decrease maximum ampdu size for each mcs till underflows stop
++ * Return 1 if pre-loading not active, -1 if not an underflow event,
++ * 0 if pre-loading module took care of the event.
++ */
++static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
++{
++	struct ampdu_info *ampdu = wlc->ampdu;
++	u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	u32 txunfl_ratio;
++	u8 max_mpdu;
++	u32 current_ampdu_cnt = 0;
++	u16 max_pld_size;
++	u32 new_txunfl;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
++	uint xmtfifo_sz;
++	u16 cur_txunfl;
++
++	/* return if we got here for a different reason than underflows */
++	cur_txunfl = brcms_b_read_shm(wlc->hw,
++				      M_UCODE_MACSTAT +
++				      offsetof(struct macstat, txfunfl[fid]));
++	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
++	if (new_txunfl == 0) {
++		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
++		return -1;
++	}
++	fifo->prev_txfunfl = cur_txunfl;
++
++	if (!ampdu->tx_max_funl)
++		return 1;
++
++	/* check if fifo is big enough */
++	if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
++		return -1;
++
++	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
++		return 1;
++
++	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
++	fifo->accum_txfunfl += new_txunfl;
++
++	/* we need to wait for at least 10 underflows */
++	if (fifo->accum_txfunfl < 10)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
++		current_ampdu_cnt, fifo->accum_txfunfl);
++
++	/*
++	   compute the current ratio of tx unfl per ampdu.
++	   When the current ampdu count becomes too
++	   big while the ratio remains small, we reset
++	   the current count in order to not
++	   introduce too big of a latency in detecting a
++	   large amount of tx underflows later.
++	 */
++
++	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
++
++	if (txunfl_ratio > ampdu->tx_max_funl) {
++		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
++			fifo->accum_txfunfl = 0;
++
++		return 0;
++	}
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++
++	/* In case max value max_pdu is already lower than
++	   the fifo depth, there is nothing more we can do.
++	 */
++
++	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
++		fifo->accum_txfunfl = 0;
++		return 0;
++	}
++
++	if (fifo->ampdu_pld_size < max_pld_size) {
++
++		/* increment by TX_FIFO_PLD_INC bytes */
++		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
++		if (fifo->ampdu_pld_size > max_pld_size)
++			fifo->ampdu_pld_size = max_pld_size;
++
++		/* update scb release size */
++		brcms_c_scb_ampdu_update_config_all(ampdu);
++
++		/*
++		 * compute a new dma xfer rate for max_mpdu @ max mcs.
++		 * This is the minimum dma rate that can achieve no
++		 * underflow condition for the current mpdu size.
++		 *
++		 * note : we divide/multiply by 100 to avoid integer overflows
++		 */
++		fifo->dmaxferrate =
++		    (((phy_rate / 100) *
++		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++
++		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
++			"pre-load size %d\n",
++			fifo->dmaxferrate, fifo->ampdu_pld_size);
++	} else {
++
++		/* decrease ampdu size */
++		if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
++			if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
++				    AMPDU_NUM_MPDU_LEGACY - 1;
++			else
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
++
++			/* recompute the table */
++			brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
++
++			/* update scb release size */
++			brcms_c_scb_ampdu_update_config_all(ampdu);
++		}
++	}
++	fifo->accum_txfunfl = 0;
++	return 0;
++}
++
++void
++brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++	u8 ba_wsize,		/* negotiated ba window size (in pdu) */
++	uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
++{
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	struct ampdu_info *ampdu = wlc->ampdu;
++	struct scb *scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++
++	if (!ampdu->ini_enable[tid]) {
++		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
++			  __func__, tid);
++		return;
++	}
++
++	ini = &scb_ampdu->ini[tid];
++	ini->tid = tid;
++	ini->scb = scb_ampdu->scb;
++	ini->ba_wsize = ba_wsize;
++	scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
++}
++
++int
++brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
++	      struct sk_buff **pdu, int prec)
++{
++	struct brcms_c_info *wlc;
++	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
++	u8 tid, ndelim;
++	int err = 0;
++	u8 preamble_type = BRCMS_GF_PREAMBLE;
++	u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
++	u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
++	u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
++
++	bool rr = true, fbr = false;
++	uint i, count = 0, fifo, seg_cnt = 0;
++	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
++	u32 ampdu_len, max_ampdu_bytes = 0;
++	struct d11txh *txh = NULL;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	u8 mcs = 0;
++	bool use_rts = false, use_cts = false;
++	u32 rspec = 0, rspec_fallback = 0;
++	u32 rts_rspec = 0, rts_rspec_fallback = 0;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++	struct ieee80211_rts *rts;
++	u8 rr_retry_limit;
++	struct brcms_fifo_info *f;
++	bool fbr_iscck;
++	struct ieee80211_tx_info *tx_info;
++	u16 qlen;
++	struct wiphy *wiphy;
++
++	wlc = ampdu->wlc;
++	wiphy = wlc->wiphy;
++	p = *pdu;
++
++	tid = (u8) (p->priority);
++
++	f = ampdu->fifo_tb + prio2fifo[tid];
++
++	scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++	ini = &scb_ampdu->ini[tid];
++
++	/* Let pressure continue to build ... */
++	qlen = pktq_plen(&qi->q, prec);
++	if (ini->tx_in_transit > 0 &&
++	    qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
++		/* Collect multiple MPDU's to be sent in the next AMPDU */
++		return -EBUSY;
++
++	/* at this point we intend to transmit an AMPDU */
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	ampdu_len = 0;
++	dma_len = 0;
++	while (p) {
++		struct ieee80211_tx_rate *txrate;
++
++		tx_info = IEEE80211_SKB_CB(p);
++		txrate = tx_info->status.rates;
++
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_prep_pdu(wlc, p, &fifo);
++		} else {
++			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
++			*pdu = NULL;
++			err = 0;
++			break;
++		}
++
++		if (err) {
++			if (err == -EBUSY) {
++				wiphy_err(wiphy, "wl%d: sendampdu: "
++					  "prep_xdu retry; seq 0x%x\n",
++					  wlc->pub->unit, seq);
++				*pdu = p;
++				break;
++			}
++
++			/* error in the packet; reject it */
++			wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
++				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
++			*pdu = NULL;
++			break;
++		}
++
++		/* pkt is good to be aggregated */
++		txh = (struct d11txh *) p->data;
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++		index = TX_SEQ_TO_INDEX(seq);
++
++		/* check mcl fields and test whether it can be agg'd */
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
++		txh->PreloadSize = 0;	/* always default to 0 */
++
++		/*  Handle retry limits */
++		if (txrate[0].count <= rr_retry_limit) {
++			txrate[0].count++;
++			rr = true;
++			fbr = false;
++		} else {
++			fbr = true;
++			rr = false;
++			txrate[1].count++;
++		}
++
++		/* extract the length info */
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++
++		/* retrieve null delimiter count */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		seg_cnt += 1;
++
++		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
++			wlc->pub->unit, count, len);
++
++		/*
++		 * aggregateable mpdu. For ucode/hw agg,
++		 * test whether need to break or change the epoch
++		 */
++		if (count == 0) {
++			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
++			/* refill the bits since might be a retx mpdu */
++			mcl |= TXC_STARTMSDU;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++			if (ieee80211_is_rts(rts->frame_control)) {
++				mcl |= TXC_SENDRTS;
++				use_rts = true;
++			}
++			if (ieee80211_is_cts(rts->frame_control)) {
++				mcl |= TXC_SENDCTS;
++				use_cts = true;
++			}
++		} else {
++			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
++			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
++		}
++
++		len = roundup(len, 4);
++		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
++
++		dma_len += (u16) p->len;
++
++		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
++			" seg_cnt %d null delim %d\n",
++			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
++
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* this packet is added */
++		pkt[count++] = p;
++
++		/* patch the first MPDU */
++		if (count == 1) {
++			u8 plcp0, plcp3, is40, sgi;
++			struct ieee80211_sta *sta;
++
++			sta = tx_info->control.sta;
++
++			if (rr) {
++				plcp0 = plcp[0];
++				plcp3 = plcp[3];
++			} else {
++				plcp0 = txh->FragPLCPFallback[0];
++				plcp3 = txh->FragPLCPFallback[3];
++
++			}
++			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
++			sgi = plcp3_issgi(plcp3) ? 1 : 0;
++			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
++			max_ampdu_bytes =
++			    min(scb_ampdu->max_rx_ampdu_bytes,
++				ampdu->max_txlen[mcs][is40][sgi]);
++
++			if (is40)
++				mimo_ctlchbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++			/* rebuild the rspec and rspec_fallback */
++			rspec = RSPEC_MIMORATE;
++			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
++			if (plcp[0] & MIMO_PLCP_40MHZ)
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++
++			if (fbr_iscck)	/* CCK */
++				rspec_fallback = cck_rspec(cck_phy2mac_rate
++						    (txh->FragPLCPFallback[0]));
++			else {	/* MIMO */
++				rspec_fallback = RSPEC_MIMORATE;
++				rspec_fallback |=
++				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
++				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
++					rspec_fallback |=
++					    (PHY_TXC1_BW_40MHZ <<
++					     RSPEC_BW_SHIFT);
++			}
++
++			if (use_rts || use_cts) {
++				rts_rspec =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec, false, mimo_ctlchbw);
++				rts_rspec_fallback =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec_fallback, false, mimo_ctlchbw);
++			}
++		}
++
++		/* if (first mpdu for host agg) */
++		/* test whether to add more */
++		if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
++		    (count == f->mcs2ampdu_table[mcs])) {
++			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
++				" ampdu at %d for mcs %d\n",
++				wlc->pub->unit, count, mcs);
++			break;
++		}
++
++		if (count == scb_ampdu->max_pdu)
++			break;
++
++		/*
++		 * check to see if the next pkt is
++		 * a candidate for aggregation
++		 */
++		p = pktq_ppeek(&qi->q, prec);
++		/* tx_info must be checked with current p */
++		tx_info = IEEE80211_SKB_CB(p);
++
++		if (p) {
++			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++			    ((u8) (p->priority) == tid)) {
++				plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
++				plen = max(scb_ampdu->min_len, plen);
++
++				if ((plen + ampdu_len) > max_ampdu_bytes) {
++					p = NULL;
++					continue;
++				}
++
++				/*
++				 * check if there are enough
++				 * descriptors available
++				 */
++				if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
++					wiphy_err(wiphy, "%s: No fifo space  "
++						  "!!\n", __func__);
++					p = NULL;
++					continue;
++				}
++				p = brcmu_pktq_pdeq(&qi->q, prec);
++			} else {
++				p = NULL;
++			}
++		}
++	}			/* end while(p) */
++
++	ini->tx_in_transit += count;
++
++	if (count) {
++		/* patch up the last txh */
++		txh = (struct d11txh *) pkt[count - 1]->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* remove the null delimiter after last mpdu */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
++		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
++
++		/* remove the pad len from last mpdu */
++		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++		ampdu_len -= roundup(len, 4) - len;
++
++		/* patch up the first txh & plcp */
++		txh = (struct d11txh *) pkt[0]->data;
++		plcp = (u8 *) (txh + 1);
++
++		BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
++		/* mark plcp to indicate ampdu */
++		BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++
++		/* reset the mixed mode header durations */
++		if (txh->MModeLen) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++			preamble_type = BRCMS_MM_PREAMBLE;
++		}
++		if (txh->MModeFbrLen) {
++			u16 mmfbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec_fallback,
++						  ampdu_len);
++			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
++			fbr_preamble_type = BRCMS_MM_PREAMBLE;
++		}
++
++		/* set the preload length */
++		if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
++			dma_len = min(dma_len, f->ampdu_pld_size);
++			txh->PreloadSize = cpu_to_le16(dma_len);
++		} else
++			txh->PreloadSize = 0;
++
++		mch = le16_to_cpu(txh->MacTxControlHigh);
++
++		/* update RTS dur fields */
++		if (use_rts || use_cts) {
++			u16 durid;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
++			    TXC_PREAMBLE_RTS_MAIN_SHORT)
++				rts_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
++			    TXC_PREAMBLE_RTS_FB_SHORT)
++				rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			durid =
++			    brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
++						   rspec, rts_preamble_type,
++						   preamble_type, ampdu_len,
++						   true);
++			rts->duration = cpu_to_le16(durid);
++			durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++						       rts_rspec_fallback,
++						       rspec_fallback,
++						       rts_fbr_preamble_type,
++						       fbr_preamble_type,
++						       ampdu_len, true);
++			txh->RTSDurFallback = cpu_to_le16(durid);
++			/* set TxFesTimeNormal */
++			txh->TxFesTimeNormal = rts->duration;
++			/* set fallback rate version of TxFesTimeNormal */
++			txh->TxFesTimeFallback = txh->RTSDurFallback;
++		}
++
++		/* set flag and plcp for fallback rate */
++		if (fbr) {
++			mch |= TXC_AMPDU_FBR;
++			txh->MacTxControlHigh = cpu_to_le16(mch);
++			BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++			BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
++		}
++
++		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
++			wlc->pub->unit, count, ampdu_len);
++
++		/* inform rate_sel if it this is a rate probe pkt */
++		frameid = le16_to_cpu(txh->TxFrameID);
++		if (frameid & TXFID_RATE_PROBE_MASK)
++			wiphy_err(wiphy, "%s: XXX what to do with "
++				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
++
++		for (i = 0; i < count; i++)
++			brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
++				   ampdu->txpkt_weight);
++
++	}
++	/* endif (count) */
++	return err;
++}
++
++static void
++brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
++			  struct ieee80211_tx_info *tx_info,
++			  struct tx_status *txs, u8 mcs)
++{
++	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
++	int i;
++
++	/* clear the rest of the rates */
++	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++		txrate[i].idx = -1;
++		txrate[i].count = 0;
++	}
++}
++
++static void
++brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
++			      struct sk_buff *p, struct tx_status *txs,
++			      u32 s1, u32 s2)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u8 bitmap[8], queue, tid;
++	struct d11txh *txh;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	u16 seq, start_seq = 0, bindex, index, mcl;
++	u8 mcs = 0;
++	bool ba_recd = false, ack_recd = false;
++	u8 suc_mpdu = 0, tot_mpdu = 0;
++	uint supr_status;
++	bool update_rate = true, retry = true, tx_error = false;
++	u16 mimoantsel = 0;
++	u8 antselid = 0;
++	u8 retry_limit, rr_retry_limit;
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
++	struct wiphy *wiphy = wlc->wiphy;
++
++#ifdef DEBUG
++	u8 hole[AMPDU_MAX_MPDU];
++	memset(hole, 0, sizeof(hole));
++#endif
++
++	scb_ampdu = &scb->scb_ampdu;
++	tid = (u8) (p->priority);
++
++	ini = &scb_ampdu->ini[tid];
++	retry_limit = ampdu->retry_limit_tid[tid];
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	memset(bitmap, 0, sizeof(bitmap));
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		if (TX_STATUS_SUPR_UF == supr_status)
++			update_rate = false;
++
++		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
++		start_seq = txs->sequence >> SEQNUM_SHIFT;
++		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
++		    TX_STATUS_BA_BMAP03_SHIFT;
++
++		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
++		WARN_ON(!(s1 & TX_STATUS_AMPDU));
++
++		bitmap[0] |=
++		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
++		    TX_STATUS_BA_BMAP47_SHIFT;
++		bitmap[1] = (s1 >> 8) & 0xff;
++		bitmap[2] = (s1 >> 16) & 0xff;
++		bitmap[3] = (s1 >> 24) & 0xff;
++
++		bitmap[4] = s2 & 0xff;
++		bitmap[5] = (s2 >> 8) & 0xff;
++		bitmap[6] = (s2 >> 16) & 0xff;
++		bitmap[7] = (s2 >> 24) & 0xff;
++
++		ba_recd = true;
++	} else {
++		if (supr_status) {
++			update_rate = false;
++			if (supr_status == TX_STATUS_SUPR_BADCH) {
++				wiphy_err(wiphy,
++					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
++					  __func__, CHSPEC_CHANNEL(
++					  wlc->default_bss->chanspec));
++			} else {
++				if (supr_status != TX_STATUS_SUPR_FRAG)
++					wiphy_err(wiphy, "%s: supr_status 0x%x\n",
++						  __func__, supr_status);
++			}
++			/* no need to retry for badch; will fail again */
++			if (supr_status == TX_STATUS_SUPR_BADCH ||
++			    supr_status == TX_STATUS_SUPR_EXPTIME) {
++				retry = false;
++			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
++				/* TX underflow:
++				 *   try tuning pre-loading or ampdu size
++				 */
++			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
++				/*
++				 * if there were underflows, but pre-loading
++				 * is not active, notify rate adaptation.
++				 */
++				if (brcms_c_ffpld_check_txfunfl(wlc,
++					prio2fifo[tid]) > 0)
++					tx_error = true;
++			}
++		} else if (txs->phyerr) {
++			update_rate = false;
++			wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
++				  __func__, txs->phyerr);
++
++			if (brcm_msg_level & LOG_ERROR_VAL) {
++				brcmu_prpkt("txpkt (AMPDU)", p);
++				brcms_c_print_txdesc((struct d11txh *) p->data);
++			}
++			brcms_c_print_txstatus(txs);
++		}
++	}
++
++	/* loop through all pkts and retry if not acked */
++	while (p) {
++		tx_info = IEEE80211_SKB_CB(p);
++		txh = (struct d11txh *) p->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++
++		if (tot_mpdu == 0) {
++			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
++			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
++		}
++
++		index = TX_SEQ_TO_INDEX(seq);
++		ack_recd = false;
++		if (ba_recd) {
++			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
++			BCMMSG(wiphy,
++			       "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
++			       tid, seq, start_seq, bindex,
++			       isset(bitmap, bindex), index);
++			/* if acked then clear bit and free packet */
++			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
++			    && isset(bitmap, bindex)) {
++				ini->tx_in_transit--;
++				ini->txretry[index] = 0;
++
++				/*
++				 * ampdu_ack_len:
++				 *   number of acked aggregated frames
++				 */
++				/* ampdu_len: number of aggregated frames */
++				brcms_c_ampdu_rate_status(wlc, tx_info, txs,
++							  mcs);
++				tx_info->flags |= IEEE80211_TX_STAT_ACK;
++				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
++				tx_info->status.ampdu_ack_len =
++					tx_info->status.ampdu_len = 1;
++
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++				ack_recd = true;
++				suc_mpdu++;
++			}
++		}
++		/* either retransmit or send bar if ack not recd */
++		if (!ack_recd) {
++			if (retry && (ini->txretry[index] < (int)retry_limit)) {
++				ini->txretry[index]++;
++				ini->tx_in_transit--;
++				/*
++				 * Use high prededence for retransmit to
++				 * give some punch
++				 */
++				brcms_c_txq_enq(wlc, scb, p,
++						BRCMS_PRIO_TO_HI_PREC(tid));
++			} else {
++				/* Retry timeout */
++				ini->tx_in_transit--;
++				ieee80211_tx_info_clear_status(tx_info);
++				tx_info->status.ampdu_ack_len = 0;
++				tx_info->status.ampdu_len = 1;
++				tx_info->flags |=
++				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++				BCMMSG(wiphy,
++				       "BA Timeout, seq %d, in_transit %d\n",
++				       seq, ini->tx_in_transit);
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++			}
++		}
++		tot_mpdu++;
++
++		/* break out if last packet of ampdu */
++		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++		    TXC_AMPDU_LAST)
++			break;
++
++		p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	}
++	brcms_c_send_q(wlc);
++
++	/* update rate state */
++	antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
++
++	brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++}
++
++void
++brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++		     struct sk_buff *p, struct tx_status *txs)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u32 s1 = 0, s2 = 0;
++	struct ieee80211_tx_info *tx_info;
++
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* BMAC_NOTE: For the split driver, second level txstatus comes later
++	 * So if the ACK was received then wait for the second level else just
++	 * call the first one
++	 */
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		u8 status_delay = 0;
++
++		/* wait till the next 8 bytes of txstatus is available */
++		s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
++		while ((s1 & TXS_V) == 0) {
++			udelay(1);
++			status_delay++;
++			if (status_delay > 10)
++				return; /* error condition */
++			s1 = bcma_read32(wlc->hw->d11core,
++					 D11REGOFFS(frmtxstatus));
++		}
++
++		s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
++	}
++
++	if (scb) {
++		scb_ampdu = &scb->scb_ampdu;
++		ini = &scb_ampdu->ini[p->priority];
++		brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
++	} else {
++		/* loop through all pkts and free */
++		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
++		struct d11txh *txh;
++		u16 mcl;
++		while (p) {
++			tx_info = IEEE80211_SKB_CB(p);
++			txh = (struct d11txh *) p->data;
++			mcl = le16_to_cpu(txh->MacTxControlLow);
++			brcmu_pkt_buf_free_skb(p);
++			/* break out if last packet of ampdu */
++			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++			    TXC_AMPDU_LAST)
++				break;
++			p = dma_getnexttxp(wlc->hw->di[queue],
++					   DMA_RANGE_TRANSMITTED);
++		}
++		brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++	}
++}
++
++void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
++{
++	char template[T_RAM_ACCESS_SZ * 2];
++
++	/* driver needs to write the ta in the template; ta is at offset 16 */
++	memset(template, 0, sizeof(template));
++	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
++	brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
++				  (T_RAM_ACCESS_SZ * 2),
++				  template);
++}
++
++bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
++{
++	return wlc->ampdu->ini_enable[tid];
++}
++
++void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	/*
++	 * Extend ucode internal watchdog timer to
++	 * match larger received frames
++	 */
++	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
++	    IEEE80211_HT_MAX_AMPDU_64K) {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
++	} else {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
++	}
++}
++
++/*
++ * callback function that helps flushing ampdu packets from a priority queue
++ */
++static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
++{
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
++	struct cb_del_ampdu_pars *ampdu_pars =
++				 (struct cb_del_ampdu_pars *)arg_a;
++	bool rc;
++
++	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
++	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
++		    tx_info->control.sta == ampdu_pars->sta);
++	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
++	return rc;
++}
++
++/*
++ * callback function that helps invalidating ampdu packets in a DMA queue
++ */
++static void dma_cb_fn_ampdu(void *txi, void *arg_a)
++{
++	struct ieee80211_sta *sta = arg_a;
++	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
++
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++	    (tx_info->control.sta == sta || sta == NULL))
++		tx_info->control.sta = NULL;
++}
++
++/*
++ * When a remote party is no longer available for ampdu communication, any
++ * pending tx ampdu packets in the driver have to be flushed.
++ */
++void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++		     struct ieee80211_sta *sta, u16 tid)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *pq = &qi->q;
++	int prec;
++	struct cb_del_ampdu_pars ampdu_pars;
++
++	ampdu_pars.sta = sta;
++	ampdu_pars.tid = tid;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
++			    (void *)&ampdu_pars);
++	brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+new file mode 100644
+index 0000000..421f4ba
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_AMPDU_H_
++#define _BRCM_AMPDU_H_
++
++extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
++extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
++			     struct brcms_txq_info *qi,
++			     struct sk_buff **aggp, int prec);
++extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++				 struct sk_buff *p, struct tx_status *txs);
++extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
++
++#endif				/* _BRCM_AMPDU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+new file mode 100644
+index 0000000..55e12c3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+@@ -0,0 +1,307 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "main.h"
++#include "phy_shim.h"
++#include "antsel.h"
++
++#define ANT_SELCFG_AUTO		0x80	/* bit indicates antenna sel AUTO */
++#define ANT_SELCFG_MASK		0x33	/* antenna configuration mask */
++#define ANT_SELCFG_TX_UNICAST	0	/* unicast tx antenna configuration */
++#define ANT_SELCFG_RX_UNICAST	1	/* unicast rx antenna configuration */
++#define ANT_SELCFG_TX_DEF	2	/* default tx antenna configuration */
++#define ANT_SELCFG_RX_DEF	3	/* default rx antenna configuration */
++
++/* useful macros */
++#define BRCMS_ANTSEL_11N_0(ant)	((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
++#define BRCMS_ANTSEL_11N_1(ant)	(((ant) & ANT_SELCFG_MASK) & 0xf)
++#define BRCMS_ANTIDX_11N(ant)	(((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
++				(BRCMS_ANTSEL_11N_1(ant)))
++#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
++#define BRCMS_ANTSEL_11N(ant)	((ant) & ANT_SELCFG_MASK)
++
++/* antenna switch */
++/* defines for no boardlevel antenna diversity */
++#define ANT_SELCFG_DEF_2x2	0x01	/* default antenna configuration */
++
++/* 2x3 antdiv defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x3	3
++#define ANT_SELCFG_DEF_2x3	0x01	/* default antenna configuration */
++
++/* 2x4 antdiv rev4 defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x4	4
++#define ANT_SELCFG_DEF_2x4	0x02	/* default antenna configuration */
++
++static const u16 mimo_2x4_div_antselpat_tbl[] = {
++	0, 0, 0x9, 0xa,		/* ant0: 0 ant1: 2,3 */
++	0, 0, 0x5, 0x6,		/* ant0: 1 ant1: 2,3 */
++	0, 0, 0, 0,		/* n.a.              */
++	0, 0, 0, 0		/* n.a.              */
++};
++
++static const u8 mimo_2x4_div_antselid_tbl[16] = {
++	0, 0, 0, 0, 0, 2, 3, 0,
++	0, 0, 1, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++static const u16 mimo_2x3_div_antselpat_tbl[] = {
++	16, 0, 1, 16,		/* ant0: 0 ant1: 1,2 */
++	16, 16, 16, 16,		/* n.a.              */
++	16, 2, 16, 16,		/* ant0: 2 ant1: 1   */
++	16, 16, 16, 16		/* n.a.              */
++};
++
++static const u8 mimo_2x3_div_antselid_tbl[16] = {
++	0, 1, 2, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++/* boardlevel antenna selection: init antenna selection structure */
++static void
++brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
++		    bool auto_sel)
++{
++	if (asi->antsel_type == ANTSEL_2x3) {
++		u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
++		    ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
++
++	} else if (asi->antsel_type == ANTSEL_2x4) {
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
++
++	} else {		/* no antenna selection available */
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->num_antcfg = 0;
++	}
++}
++
++struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
++{
++	struct antsel_info *asi;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
++	if (!asi)
++		return NULL;
++
++	asi->wlc = wlc;
++	asi->pub = wlc->pub;
++	asi->antsel_type = ANTSEL_NA;
++	asi->antsel_avail = false;
++	asi->antsel_antswitch = sprom->antswitch;
++
++	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
++		switch (asi->antsel_antswitch) {
++		case ANTSWITCH_TYPE_1:
++		case ANTSWITCH_TYPE_2:
++		case ANTSWITCH_TYPE_3:
++			/* 4321/2 board with 2x3 switch logic */
++			asi->antsel_type = ANTSEL_2x3;
++			/* Antenna selection availability */
++			if ((sprom->ant_available_bg == 7) ||
++			    (sprom->ant_available_a == 7)) {
++				asi->antsel_avail = true;
++			} else if (
++				sprom->ant_available_bg == 3 ||
++				sprom->ant_available_a == 3) {
++				asi->antsel_avail = false;
++			} else {
++				asi->antsel_avail = false;
++				wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
++					  "board cfg invalid\n");
++			}
++
++			break;
++		default:
++			break;
++		}
++	} else if ((asi->pub->sromrev == 4) &&
++		   (sprom->ant_available_bg == 7) &&
++		   (sprom->ant_available_a == 0)) {
++		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
++		asi->antsel_type = ANTSEL_2x3;
++		asi->antsel_avail = true;
++	} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
++		asi->antsel_type = ANTSEL_2x4;
++		asi->antsel_avail = true;
++	}
++
++	/* Set the antenna selection type for the low driver */
++	brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
++
++	/* Init (auto/manual) antenna selection */
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
++
++	return asi;
++}
++
++void brcms_c_antsel_detach(struct antsel_info *asi)
++{
++	kfree(asi);
++}
++
++/*
++ * boardlevel antenna selection:
++ *   convert ant_cfg to mimo_antsel (ucode interface)
++ */
++static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
++{
++	u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
++	u16 mimo_antsel = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++	}
++
++	return mimo_antsel;
++}
++
++/* boardlevel antenna selection: ucode interface control */
++static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
++				 struct brcms_antselcfg *antsel)
++{
++	struct brcms_c_info *wlc = asi->wlc;
++	u8 ant_cfg;
++	u16 mimo_antsel;
++
++	/* 1) Update TX antconfig for all frames that are not unicast data
++	 *    (aka default TX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
++
++	/* 2) Update RX antconfig for all frames that are not unicast data
++	 *    (aka default RX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
++
++	return 0;
++}
++
++void brcms_c_antsel_init(struct antsel_info *asi)
++{
++	if ((asi->antsel_type == ANTSEL_2x3) ||
++	    (asi->antsel_type == ANTSEL_2x4))
++		brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
++}
++
++/* boardlevel antenna selection: convert id to ant_cfg */
++static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
++{
++	u8 antcfg = ANT_SELCFG_DEF_2x2;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
++		return antcfg;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
++		return antcfg;
++	}
++
++	return antcfg;
++}
++
++void
++brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
++		      u8 antselid, u8 fbantselid, u8 *antcfg,
++		      u8 *fbantcfg)
++{
++	u8 ant;
++
++	/* if use default, assign it and return */
++	if (usedef) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
++		*fbantcfg = *antcfg;
++		return;
++	}
++
++	if (!sel) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		*fbantcfg = *antcfg;
++
++	} else {
++		ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
++			*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
++			*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
++		} else {
++			*antcfg =
++			    asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++			*fbantcfg = *antcfg;
++		}
++	}
++	return;
++}
++
++/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
++u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
++{
++	u8 antselid = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++	}
++
++	return antselid;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+new file mode 100644
+index 0000000..97ea388
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_ANTSEL_H_
++#define _BRCM_ANTSEL_H_
++
++extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
++extern void brcms_c_antsel_detach(struct antsel_info *asi);
++extern void brcms_c_antsel_init(struct antsel_info *asi);
++extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
++				  bool sel,
++				  u8 id, u8 fbid, u8 *antcfg,
++				  u8 *fbantcfg);
++extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
++
++#endif /* _BRCM_ANTSEL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+new file mode 100644
+index 0000000..52fc9ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/module.h> /* bug in tracepoint.h, it should include this */
++
++#ifndef __CHECKER__
++#include "mac80211_if.h"
++#define CREATE_TRACE_POINTS
++#include "brcms_trace_events.h"
++#endif
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+new file mode 100644
+index 0000000..27dd73e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM brcmsmac
++
++#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
++
++#define __TRACE_BRCMSMAC_H
++
++#include <linux/tracepoint.h>
++#include "mac80211_if.h"
++
++#ifndef CONFIG_BRCMDBG
++#undef TRACE_EVENT
++#define TRACE_EVENT(name, proto, ...) \
++static inline void trace_ ## name(proto) {}
++#endif
++
++/*
++ * We define a tracepoint, its arguments, its printk format and its
++ * 'fast binary record' layout.
++ */
++TRACE_EVENT(brcms_timer,
++	/* TPPROTO is the prototype of the function called by this tracepoint */
++	TP_PROTO(struct brcms_timer *t),
++	/*
++	 * TPARGS(firstarg, p) are the parameters names, same as found in the
++	 * prototype.
++	 */
++	TP_ARGS(t),
++	/*
++	 * Fast binary tracing: define the trace record via TP_STRUCT__entry().
++	 * You can think about it like a regular C structure local variable
++	 * definition.
++	 */
++	TP_STRUCT__entry(
++		__field(uint, ms)
++		__field(uint, set)
++		__field(uint, periodic)
++	),
++	TP_fast_assign(
++		__entry->ms = t->ms;
++		__entry->set = t->set;
++		__entry->periodic = t->periodic;
++	),
++	TP_printk(
++		"ms=%u set=%u periodic=%u",
++		__entry->ms, __entry->set, __entry->periodic
++	)
++);
++
++TRACE_EVENT(brcms_dpc,
++	TP_PROTO(unsigned long data),
++	TP_ARGS(data),
++	TP_STRUCT__entry(
++		__field(unsigned long, data)
++	),
++	TP_fast_assign(
++		__entry->data = data;
++	),
++	TP_printk(
++		"data=%p",
++		(void *)__entry->data
++	)
++);
++
++#endif /* __TRACE_BRCMSMAC_H */
++
++#ifdef CONFIG_BRCMDBG
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE brcms_trace_events
++
++#include <trace/define_trace.h>
++
++#endif /* CONFIG_BRCMDBG */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+new file mode 100644
+index 0000000..eb77ac3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -0,0 +1,1506 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/types.h>
++#include <net/mac80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "phy/phy_hal.h"
++#include "main.h"
++#include "stf.h"
++#include "channel.h"
++
++/* QDB() macro takes a dB value and converts to a quarter dB value */
++#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
++
++#define  LOCALE_CHAN_01_11	 (1<<0)
++#define  LOCALE_CHAN_12_13	 (1<<1)
++#define  LOCALE_CHAN_14		 (1<<2)
++#define  LOCALE_SET_5G_LOW_JP1   (1<<3)	/* 34-48, step 2 */
++#define  LOCALE_SET_5G_LOW_JP2   (1<<4)	/* 34-46, step 4 */
++#define  LOCALE_SET_5G_LOW1      (1<<5)	/* 36-48, step 4 */
++#define  LOCALE_SET_5G_LOW2      (1<<6)	/* 52 */
++#define  LOCALE_SET_5G_LOW3      (1<<7)	/* 56-64, step 4 */
++#define  LOCALE_SET_5G_MID1      (1<<8)	/* 100-116, step 4 */
++#define  LOCALE_SET_5G_MID2	 (1<<9)	/* 120-124, step 4 */
++#define  LOCALE_SET_5G_MID3      (1<<10)	/* 128 */
++#define  LOCALE_SET_5G_HIGH1     (1<<11)	/* 132-140, step 4 */
++#define  LOCALE_SET_5G_HIGH2     (1<<12)	/* 149-161, step 4 */
++#define  LOCALE_SET_5G_HIGH3     (1<<13)	/* 165 */
++#define  LOCALE_CHAN_52_140_ALL  (1<<14)
++#define  LOCALE_SET_5G_HIGH4     (1<<15)	/* 184-216 */
++
++#define  LOCALE_CHAN_36_64	(LOCALE_SET_5G_LOW1 | \
++				 LOCALE_SET_5G_LOW2 | \
++				 LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_52_64	(LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_100_124	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
++#define  LOCALE_CHAN_100_140	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
++				  LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
++#define  LOCALE_CHAN_149_165	(LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
++#define  LOCALE_CHAN_184_216	LOCALE_SET_5G_HIGH4
++
++#define  LOCALE_CHAN_01_14	(LOCALE_CHAN_01_11 | \
++				 LOCALE_CHAN_12_13 | \
++				 LOCALE_CHAN_14)
++
++#define  LOCALE_RADAR_SET_NONE		  0
++#define  LOCALE_RADAR_SET_1		  1
++
++#define  LOCALE_RESTRICTED_NONE		  0
++#define  LOCALE_RESTRICTED_SET_2G_SHORT   1
++#define  LOCALE_RESTRICTED_CHAN_165       2
++#define  LOCALE_CHAN_ALL_5G		  3
++#define  LOCALE_RESTRICTED_JAPAN_LEGACY   4
++#define  LOCALE_RESTRICTED_11D_2G	  5
++#define  LOCALE_RESTRICTED_11D_5G	  6
++#define  LOCALE_RESTRICTED_LOW_HI	  7
++#define  LOCALE_RESTRICTED_12_13_14	  8
++
++#define LOCALE_2G_IDX_i			0
++#define LOCALE_5G_IDX_11		0
++#define LOCALE_MIMO_IDX_bn		0
++#define LOCALE_MIMO_IDX_11n		0
++
++/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
++#define BRCMS_MAXPWR_TBL_SIZE		6
++/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
++#define BRCMS_MAXPWR_MIMO_TBL_SIZE	14
++
++/* power level in group of 2.4GHz band channels:
++ * maxpwr[0] - CCK  channels [1]
++ * maxpwr[1] - CCK  channels [2-10]
++ * maxpwr[2] - CCK  channels [11-14]
++ * maxpwr[3] - OFDM channels [1]
++ * maxpwr[4] - OFDM channels [2-10]
++ * maxpwr[5] - OFDM channels [11-14]
++ */
++
++/* maxpwr mapping to 5GHz band channels:
++ * maxpwr[0] - channels [34-48]
++ * maxpwr[1] - channels [52-60]
++ * maxpwr[2] - channels [62-64]
++ * maxpwr[3] - channels [100-140]
++ * maxpwr[4] - channels [149-165]
++ */
++#define BAND_5G_PWR_LVLS	5	/* 5 power levels for 5G */
++
++#define LC(id)	LOCALE_MIMO_IDX_ ## id
++
++#define LC_2G(id)	LOCALE_2G_IDX_ ## id
++
++#define LC_5G(id)	LOCALE_5G_IDX_ ## id
++
++#define LOCALES(band2, band5, mimo2, mimo5) \
++		{LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
++
++/* macro to get 2.4 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))
++#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))
++
++/* macro to get 5 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
++				 (((c) < 62) ? 1 : \
++				 (((c) < 100) ? 2 : \
++				 (((c) < 149) ? 3 : 4))))
++
++#define ISDFS_EU(fl)		(((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
++
++struct brcms_cm_band {
++	/* struct locale_info flags */
++	u8 locale_flags;
++	/* List of valid channels in the country */
++	struct brcms_chanvec valid_channels;
++	/* List of restricted use channels */
++	const struct brcms_chanvec *restricted_channels;
++	/* List of radar sensitive channels */
++	const struct brcms_chanvec *radar_channels;
++	u8 PAD[8];
++};
++
++ /* locale per-channel tx power limits for MIMO frames
++  * maxpwr arrays are index by channel for 2.4 GHz limits, and
++  * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
++  */
++struct locale_mimo_info {
++	/* tx 20 MHz power limits, qdBm units */
++	s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	/* tx 40 MHz power limits, qdBm units */
++	s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	u8 flags;
++};
++
++/* Country names and abbreviations with locale defined from ISO 3166 */
++struct country_info {
++	const u8 locale_2G;	/* 2.4G band locale */
++	const u8 locale_5G;	/* 5G band locale */
++	const u8 locale_mimo_2G;	/* 2.4G mimo info */
++	const u8 locale_mimo_5G;	/* 5G mimo info */
++};
++
++struct brcms_cm_info {
++	struct brcms_pub *pub;
++	struct brcms_c_info *wlc;
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	uint srom_regrev;	/* Regulatory Rev for the SROM ccode */
++	const struct country_info *country;	/* current country def */
++	char ccode[BRCM_CNTRY_BUF_SZ];	/* current internal Country Code */
++	uint regrev;		/* current Regulatory Revision */
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];	/* current advertised ccode */
++	/* per-band state (one per phy/radio) */
++	struct brcms_cm_band bandstate[MAXBANDS];
++	/* quiet channels currently for radar sensitivity or 11h support */
++	/* channels on which we cannot transmit */
++	struct brcms_chanvec quiet_channels;
++};
++
++/* locale channel and power info. */
++struct locale_info {
++	u32 valid_channels;
++	/* List of radar sensitive channels */
++	u8 radar_channels;
++	/* List of channels used only if APs are detected */
++	u8 restricted_channels;
++	/* Max tx pwr in qdBm for each sub-band */
++	s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
++	/* Country IE advertised max tx pwr in dBm per sub-band */
++	s8 pub_maxpwr[BAND_5G_PWR_LVLS];
++	u8 flags;
++};
++
++/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
++
++/*
++ * Some common channel sets
++ */
++
++/* No channels */
++static const struct brcms_chanvec chanvec_none = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 2.4 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_2G = {
++	{0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 5 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_5G = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x01}
++};
++
++/*
++ * Radar channel sets
++ */
++
++/* Channels 52 - 64, 100 - 140 */
++static const struct brcms_chanvec radar_set1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,  /* 52 - 60 */
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,  /* 64, 100 - 124 */
++	 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 128 - 140 */
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/*
++ * Restricted channel sets
++ */
++
++/* Channels 34, 38, 42, 46 */
++static const struct brcms_chanvec restricted_set_japan_legacy = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12, 13 */
++static const struct brcms_chanvec restricted_set_2g_short = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channel 165 */
++static const struct brcms_chanvec restricted_chan_165 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 36 - 48 & 149 - 165 */
++static const struct brcms_chanvec restricted_low_hi = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12 - 14 */
++static const struct brcms_chanvec restricted_set_12_13_14 = {
++	{0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* global memory to provide working buffer for expanded locale */
++
++static const struct brcms_chanvec *g_table_radar_set[] = {
++	&chanvec_none,
++	&radar_set1
++};
++
++static const struct brcms_chanvec *g_table_restricted_chan[] = {
++	&chanvec_none,		/* restricted_set_none */
++	&restricted_set_2g_short,
++	&restricted_chan_165,
++	&chanvec_all_5G,
++	&restricted_set_japan_legacy,
++	&chanvec_all_2G,	/* restricted_set_11d_2G */
++	&chanvec_all_5G,	/* restricted_set_11d_5G */
++	&restricted_low_hi,
++	&restricted_set_12_13_14
++};
++
++static const struct brcms_chanvec locale_2g_01_11 = {
++	{0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_12_13 = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_14 = {
++	{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_52_140_ALL = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
++	 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH4 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x11}
++};
++
++static const struct brcms_chanvec *g_table_locale_base[] = {
++	&locale_2g_01_11,
++	&locale_2g_12_13,
++	&locale_2g_14,
++	&locale_5g_LOW_JP1,
++	&locale_5g_LOW_JP2,
++	&locale_5g_LOW1,
++	&locale_5g_LOW2,
++	&locale_5g_LOW3,
++	&locale_5g_MID1,
++	&locale_5g_MID2,
++	&locale_5g_MID3,
++	&locale_5g_HIGH1,
++	&locale_5g_HIGH2,
++	&locale_5g_HIGH3,
++	&locale_5g_52_140_ALL,
++	&locale_5g_HIGH4
++};
++
++static void brcms_c_locale_add_channels(struct brcms_chanvec *target,
++				    const struct brcms_chanvec *channels)
++{
++	u8 i;
++	for (i = 0; i < sizeof(struct brcms_chanvec); i++)
++		target->vec[i] |= channels->vec[i];
++}
++
++static void brcms_c_locale_get_channels(const struct locale_info *locale,
++				    struct brcms_chanvec *channels)
++{
++	u8 i;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
++		if (locale->valid_channels & (1 << i))
++			brcms_c_locale_add_channels(channels,
++						g_table_locale_base[i]);
++	}
++}
++
++/*
++ * Locale Definitions - 2.4 GHz
++ */
++static const struct locale_info locale_i = {	/* locale i. channel 1 - 13 */
++	LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
++	LOCALE_RADAR_SET_NONE,
++	LOCALE_RESTRICTED_SET_2G_SHORT,
++	{QDB(19), QDB(19), QDB(19),
++	 QDB(19), QDB(19), QDB(19)},
++	{20, 20, 20, 0},
++	BRCMS_EIRP
++};
++
++/*
++ * Locale Definitions - 5 GHz
++ */
++static const struct locale_info locale_11 = {
++	/* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
++	LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
++	LOCALE_RADAR_SET_1,
++	LOCALE_RESTRICTED_NONE,
++	{QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
++	{23, 23, 23, 30, 30},
++	BRCMS_EIRP | BRCMS_DFS_EU
++};
++
++static const struct locale_info *g_locale_2g_table[] = {
++	&locale_i
++};
++
++static const struct locale_info *g_locale_5g_table[] = {
++	&locale_11
++};
++
++/*
++ * MIMO Locale Definitions - 2.4 GHz
++ */
++static const struct locale_mimo_info locale_bn = {
++	{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13)},
++	{0, 0, QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), 0, 0},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_2g_table[] = {
++	&locale_bn
++};
++
++/*
++ * MIMO Locale Definitions - 5 GHz
++ */
++static const struct locale_mimo_info locale_11n = {
++	{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
++	{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_5g_table[] = {
++	&locale_11n
++};
++
++static const struct {
++	char abbrev[BRCM_CNTRY_BUF_SZ];	/* country abbreviation */
++	struct country_info country;
++} cntry_locales[] = {
++	{
++	"X2", LOCALES(i, 11, bn, 11n)},	/* Worldwide RoW 2 */
++};
++
++#ifdef SUPPORT_40MHZ
++/* 20MHz channel info for 40MHz pairing support */
++struct chan20_info {
++	u8 sb;
++	u8 adj_sbs;
++};
++
++/* indicates adjacent channels that are allowed for a 40 Mhz channel and
++ * those that permitted by the HT
++ */
++struct chan20_info chan20_info[] = {
++	/* 11b/11g */
++/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 11 */ {12, (CH_LOWER_SB)},
++/* 12 */ {13, (CH_LOWER_SB)},
++/* 13 */ {14, (CH_LOWER_SB)},
++
++/* 11a japan high */
++/* 14 */ {34, (CH_UPPER_SB)},
++/* 15 */ {38, (CH_LOWER_SB)},
++/* 16 */ {42, (CH_LOWER_SB)},
++/* 17 */ {46, (CH_LOWER_SB)},
++
++/* 11a usa low */
++/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
++
++/* 11a Europe */
++/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 36 */ {140, (CH_LOWER_SB)},
++
++/* 11a usa high, ref5 only */
++/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
++/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 41 */ {165, (CH_LOWER_SB)},
++
++/* 11a japan */
++/* 42 */ {184, (CH_UPPER_SB)},
++/* 43 */ {188, (CH_LOWER_SB)},
++/* 44 */ {192, (CH_UPPER_SB)},
++/* 45 */ {196, (CH_LOWER_SB)},
++/* 46 */ {200, (CH_UPPER_SB)},
++/* 47 */ {204, (CH_LOWER_SB)},
++/* 48 */ {208, (CH_UPPER_SB)},
++/* 49 */ {212, (CH_LOWER_SB)},
++/* 50 */ {216, (CH_LOWER_SB)}
++};
++#endif				/* SUPPORT_40MHZ */
++
++static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table))
++		return NULL; /* error condition */
++
++	return g_locale_2g_table[locale_idx];
++}
++
++static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table))
++		return NULL; /* error condition */
++
++	return g_locale_5g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
++		return NULL;
++
++	return g_mimo_2g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
++		return NULL;
++
++	return g_mimo_5g_table[locale_idx];
++}
++
++static int
++brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			  char *mapped_ccode, uint *mapped_regrev)
++{
++	return false;
++}
++
++/*
++ * Indicates whether the country provided is valid to pass
++ * to cfg80211 or not.
++ *
++ * returns true if valid; false if not.
++ */
++static bool brcms_c_country_valid(const char *ccode)
++{
++	/*
++	 * only allow ascii alpha uppercase for the first 2
++	 * chars.
++	 */
++	if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
++	      (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
++	      ccode[2] == '\0'))
++		return false;
++
++	/*
++	 * do not match ISO 3166-1 user assigned country codes
++	 * that may be in the driver table
++	 */
++	if (!strcmp("AA", ccode) ||        /* AA */
++	    !strcmp("ZZ", ccode) ||        /* ZZ */
++	    ccode[0] == 'X' ||             /* XA - XZ */
++	    (ccode[0] == 'Q' &&            /* QM - QZ */
++	     (ccode[1] >= 'M' && ccode[1] <= 'Z')))
++		return false;
++
++	if (!strcmp("NA", ccode))
++		return false;
++
++	return true;
++}
++
++/* Lookup a country info structure from a null terminated country
++ * abbreviation and regrev directly with no translation.
++ */
++static const struct country_info *
++brcms_c_country_lookup_direct(const char *ccode, uint regrev)
++{
++	uint size, i;
++
++	/* Should just return 0 for single locale driver. */
++	/* Keep it this way in case we add more locales. (for now anyway) */
++
++	/*
++	 * all other country def arrays are for regrev == 0, so if
++	 * regrev is non-zero, fail
++	 */
++	if (regrev > 0)
++		return NULL;
++
++	/* find matched table entry from country code */
++	size = ARRAY_SIZE(cntry_locales);
++	for (i = 0; i < size; i++) {
++		if (strcmp(ccode, cntry_locales[i].abbrev) == 0)
++			return &cntry_locales[i].country;
++	}
++	return NULL;
++}
++
++static const struct country_info *
++brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			char *mapped_ccode, uint *mapped_regrev)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	const struct country_info *country;
++	uint srom_regrev = wlc_cm->srom_regrev;
++	const char *srom_ccode = wlc_cm->srom_ccode;
++	int mapped;
++
++	/* check for currently supported ccode size */
++	if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
++			  "match\n", wlc->pub->unit, __func__, ccode);
++		return NULL;
++	}
++
++	/* default mapping is the given ccode and regrev 0 */
++	strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++	*mapped_regrev = 0;
++
++	/* If the desired country code matches the srom country code,
++	 * then the mapped country is the srom regulatory rev.
++	 * Otherwise look for an aggregate mapping.
++	 */
++	if (!strcmp(srom_ccode, ccode)) {
++		*mapped_regrev = srom_regrev;
++		mapped = 0;
++		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
++	} else {
++		mapped =
++		    brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
++					      mapped_regrev);
++	}
++
++	/* find the matching built-in country definition */
++	country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++
++	/* if there is not an exact rev match, default to rev zero */
++	if (country == NULL && *mapped_regrev != 0) {
++		*mapped_regrev = 0;
++		country =
++		    brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++	}
++
++	return country;
++}
++
++/* Lookup a country info structure from a null terminated country code
++ * The lookup is case sensitive.
++ */
++static const struct country_info *
++brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/*
++	 * map the country code to a built-in country code, regrev, and
++	 * country_info struct
++	 */
++	country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
++					  &mapped_regrev);
++
++	return country;
++}
++
++/*
++ * reset the quiet channels vector to the union
++ * of the restricted and radar channel sets
++ */
++static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct brcms_chanvec *chanvec;
++
++	memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec));
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		/* initialize quiet channels for restricted channels */
++		chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
++
++	}
++}
++
++/* Is the channel valid for the current locale and current band? */
++static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return ((val < MAXCHANNEL) &&
++		isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
++		      val));
++}
++
++/* Is the channel valid for the current locale and specified band? */
++static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
++					    uint bandunit, uint val)
++{
++	return ((val < MAXCHANNEL)
++		&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
++}
++
++/* Is the channel valid for the current locale? (but don't consider channels not
++ *   available due to bandlocking)
++ */
++static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return brcms_c_valid_channel20(wlc->cmi, val) ||
++		(!wlc->bandlocked
++		 && brcms_c_valid_channel20_in_band(wlc->cmi,
++						    OTHERBANDUNIT(wlc), val));
++}
++
++/* JP, J1 - J10 are Japan ccodes */
++static bool brcms_c_japan_ccode(const char *ccode)
++{
++	return (ccode[0] == 'J' &&
++		(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
++}
++
++/* Returns true if currently set country is Japan or variant */
++static bool brcms_c_japan(struct brcms_c_info *wlc)
++{
++	return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
++}
++
++static void
++brcms_c_channel_min_txpower_limits_with_local_constraint(
++		struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
++		u8 local_constraint_qdbm)
++{
++	int j;
++
++	/* CCK Rates */
++	for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
++		txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM SISO */
++	for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
++		txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_cdd[j] =
++		    min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_siso[j] =
++		    min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_cdd[j] =
++		    min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_siso[j] =
++		    min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_cdd[j] =
++		    min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_stbc[j] =
++		    min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_20_mimo[j] =
++		    min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_siso[j] =
++		    min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_cdd[j] =
++		    min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_stbc[j] =
++		    min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_40_mimo[j] =
++		    min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 32 */
++	txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
++
++}
++
++/* Update the radio state (enable/disable) and tx power targets
++ * based on a new set of channel/regulatory information
++ */
++static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint chan;
++	struct txpwr_limits txpwr;
++
++	/* search for the existence of any valid channel */
++	for (chan = 0; chan < MAXCHANNEL; chan++) {
++		if (brcms_c_valid_channel20_db(wlc->cmi, chan))
++			break;
++	}
++	if (chan == MAXCHANNEL)
++		chan = INVCHANNEL;
++
++	/*
++	 * based on the channel search above, set or
++	 * clear WL_RADIO_COUNTRY_DISABLE.
++	 */
++	if (chan == INVCHANNEL) {
++		/*
++		 * country/locale with no valid channels, set
++		 * the radio disable bit
++		 */
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
++			  "nbands %d bandlocked %d\n", wlc->pub->unit,
++			  __func__, wlc_cm->country_abbrev, wlc->pub->_nbands,
++			  wlc->bandlocked);
++	} else if (mboolisset(wlc->pub->radio_disabled,
++			      WL_RADIO_COUNTRY_DISABLE)) {
++		/*
++		 * country/locale with valid channel, clear
++		 * the radio disable bit
++		 */
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++	}
++
++	/*
++	 * Now that the country abbreviation is set, if the radio supports 2G,
++	 * then set channel 14 restrictions based on the new locale.
++	 */
++	if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
++		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
++						     brcms_c_japan(wlc) ? true :
++						     false);
++
++	if (wlc->pub->up && chan != INVCHANNEL) {
++		brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
++		brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
++			&txpwr, BRCMS_TXPWR_MAX);
++		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
++	}
++}
++
++static int
++brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
++		      const struct country_info *country)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	struct brcms_chanvec sup_chan;
++	const struct locale_mimo_info *li_mimo;
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		li = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_locale_5g(country->locale_5G) :
++		    brcms_c_get_locale_2g(country->locale_2G);
++		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
++		li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++		    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++		/* merge the mimo non-mimo locale flags */
++		wlc_cm->bandstate[band->bandunit].locale_flags |=
++		    li_mimo->flags;
++
++		wlc_cm->bandstate[band->bandunit].restricted_channels =
++		    g_table_restricted_chan[li->restricted_channels];
++		wlc_cm->bandstate[band->bandunit].radar_channels =
++		    g_table_radar_set[li->radar_channels];
++
++		/*
++		 * set the channel availability, masking out the channels
++		 * that may not be supported on this phy.
++		 */
++		wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
++					      &sup_chan);
++		brcms_c_locale_get_channels(li,
++					&wlc_cm->bandstate[band->bandunit].
++					valid_channels);
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->bandstate[band->bandunit].valid_channels.
++			    vec[j] &= sup_chan.vec[j];
++	}
++
++	brcms_c_quiet_channels_reset(wlc_cm);
++	brcms_c_channels_commit(wlc_cm);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information
++ * using a country code as the source. Look up built in country
++ * information found with the country code.
++ */
++static void
++brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
++		       const char *country_abbrev,
++		       const char *ccode, uint regrev,
++		       const struct country_info *country)
++{
++	const struct locale_info *locale;
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
++
++	/* save current country state */
++	wlc_cm->country = country;
++
++	memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
++		BRCM_CNTRY_BUF_SZ - 1);
++
++	strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++	strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
++	wlc_cm->regrev = regrev;
++
++	if ((wlc->pub->_n_enab & SUPPORT_11N) !=
++	    wlc->protection->nmode_user)
++		brcms_c_set_nmode(wlc);
++
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	/* set or restore gmode as required by regulatory */
++	locale = brcms_c_get_locale_2g(country->locale_2G);
++	if (locale && (locale->flags & BRCMS_NO_OFDM))
++		brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
++	else
++		brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
++
++	brcms_c_channels_init(wlc_cm, country);
++
++	return;
++}
++
++static int
++brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
++			const char *country_abbrev,
++			const char *ccode, int regrev)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/* if regrev is -1, lookup the mapped country code,
++	 * otherwise use the ccode and regrev directly
++	 */
++	if (regrev == -1) {
++		/*
++		 * map the country code to a built-in country
++		 * code, regrev, and country_info
++		 */
++		country =
++		    brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
++					&mapped_regrev);
++	} else {
++		/* find the matching built-in country definition */
++		country = brcms_c_country_lookup_direct(ccode, regrev);
++		strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++		mapped_regrev = regrev;
++	}
++
++	if (country == NULL)
++		return -EINVAL;
++
++	/* set the driver state for the country */
++	brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
++			       mapped_regrev, country);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information using
++ * a country code as the source. Lookup built in country information
++ * found with the country code.
++ */
++static int
++brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
++{
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
++	return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
++}
++
++struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
++{
++	struct brcms_cm_info *wlc_cm;
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	const struct country_info *country;
++	struct brcms_pub *pub = wlc->pub;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
++	if (wlc_cm == NULL)
++		return NULL;
++	wlc_cm->pub = pub;
++	wlc_cm->wlc = wlc;
++	wlc->cmi = wlc_cm;
++
++	/* store the country code for passing up as a regulatory hint */
++	if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2))
++		strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2));
++
++	/*
++	 * internal country information which must match
++	 * regulatory constraints in firmware
++	 */
++	memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
++	country = brcms_c_country_lookup(wlc, country_abbrev);
++
++	/* save default country for exiting 11d regulatory mode */
++	strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++
++	/* initialize autocountry_default to driver default */
++	strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
++
++	brcms_c_set_countrycode(wlc_cm, country_abbrev);
++
++	return wlc_cm;
++}
++
++void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
++{
++	kfree(wlc_cm);
++}
++
++u8
++brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++				     uint bandunit)
++{
++	return wlc_cm->bandstate[bandunit].locale_flags;
++}
++
++static bool
++brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) &&
++		CHSPEC_IS40(chspec) ?
++		(isset(wlc_cm->quiet_channels.vec,
++		       lower_20_sb(CHSPEC_CHANNEL(chspec))) ||
++		 isset(wlc_cm->quiet_channels.vec,
++		       upper_20_sb(CHSPEC_CHANNEL(chspec)))) :
++		isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
++}
++
++void
++brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
++			 u8 local_constraint_qdbm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	struct txpwr_limits txpwr;
++
++	brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
++
++	brcms_c_channel_min_txpower_limits_with_local_constraint(
++		wlc_cm, &txpwr, local_constraint_qdbm
++	);
++
++	brcms_b_set_chanspec(wlc->hw, chanspec,
++			      (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0),
++			      &txpwr);
++}
++
++void
++brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
++		       struct txpwr_limits *txpwr)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i;
++	uint chan;
++	int maxpwr;
++	int delta;
++	const struct country_info *country;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	int conducted_max = BRCMS_TXPWR_MAX;
++	int conducted_ofdm_max = BRCMS_TXPWR_MAX;
++	const struct locale_mimo_info *li_mimo;
++	int maxpwr20, maxpwr40;
++	int maxpwr_idx;
++	uint j;
++
++	memset(txpwr, 0, sizeof(struct txpwr_limits));
++
++	if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) {
++		country = brcms_c_country_lookup(wlc, wlc->autocountry_default);
++		if (country == NULL)
++			return;
++	} else {
++		country = wlc_cm->country;
++	}
++
++	chan = CHSPEC_CHANNEL(chanspec);
++	band = wlc->bandstate[chspec_bandunit(chanspec)];
++	li = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_locale_5g(country->locale_5G) :
++	    brcms_c_get_locale_2g(country->locale_2G);
++
++	li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++	    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++	if (li->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (li == &locale_i) {
++		conducted_max = QDB(22);
++		conducted_ofdm_max = QDB(22);
++	}
++
++	/* CCK txpwr limits for 2.4G band */
++	if (band->bandtype == BRCM_BAND_2G) {
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
++
++		maxpwr = maxpwr - delta;
++		maxpwr = max(maxpwr, 0);
++		maxpwr = min(maxpwr, conducted_max);
++
++		for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
++			txpwr->cck[i] = (u8) maxpwr;
++	}
++
++	/* OFDM txpwr limits for 2.4G or 5G bands */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
++	else
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
++
++	maxpwr = maxpwr - delta;
++	maxpwr = max(maxpwr, 0);
++	maxpwr = min(maxpwr, conducted_ofdm_max);
++
++	/* Keep OFDM lmit below CCK limit */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
++		txpwr->ofdm[i] = (u8) maxpwr;
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
++		/*
++		 * OFDM 40 MHz SISO has the same power as the corresponding
++		 * MCS0-7 rate unless overriden by the locale specific code.
++		 * We set this value to 0 as a flag (presumably 0 dBm isn't
++		 * a possibility) and then copy the MCS0-7 value to the 40 MHz
++		 * value if it wasn't explicitly set.
++		 */
++		txpwr->ofdm_40_siso[i] = 0;
++
++		txpwr->ofdm_cdd[i] = (u8) maxpwr;
++
++		txpwr->ofdm_40_cdd[i] = 0;
++	}
++
++	/* MIMO/HT specific limits */
++	if (li_mimo->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr_idx = (chan - 1);
++	else
++		maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
++
++	maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
++	maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
++
++	maxpwr20 = maxpwr20 - delta;
++	maxpwr20 = max(maxpwr20, 0);
++	maxpwr40 = maxpwr40 - delta;
++	maxpwr40 = max(maxpwr40, 0);
++
++	/* Fill in the MCS 0-7 (SISO) rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++
++		/*
++		 * 20 MHz has the same power as the corresponding OFDM rate
++		 * unless overriden by the locale specific code.
++		 */
++		txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
++		txpwr->mcs_40_siso[i] = 0;
++	}
++
++	/* Fill in the MCS 0-7 CDD rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
++		txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
++	}
++
++	/*
++	 * These locales have SISO expressed in the
++	 * table and override CDD later
++	 */
++	if (li_mimo == &locale_bn) {
++		if (li_mimo == &locale_bn) {
++			maxpwr20 = QDB(16);
++			maxpwr40 = 0;
++
++			if (chan >= 3 && chan <= 11)
++				maxpwr40 = QDB(16);
++		}
++
++		for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++			txpwr->mcs_20_siso[i] = (u8) maxpwr20;
++			txpwr->mcs_40_siso[i] = (u8) maxpwr40;
++		}
++	}
++
++	/* Fill in the MCS 0-7 STBC rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_stbc[i] = 0;
++		txpwr->mcs_40_stbc[i] = 0;
++	}
++
++	/* Fill in the MCS 8-15 SDM rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
++		txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
++		txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
++	}
++
++	/* Fill in MCS32 */
++	txpwr->mcs32 = (u8) maxpwr40;
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_cdd[i] == 0)
++			txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_cdd[i] == 0)
++				txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		}
++	}
++
++	/*
++	 * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
++	 * value if it wasn't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_40_siso[i] == 0)
++			txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_siso[i] == 0)
++			txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_siso[i] == 0)
++				txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		}
++	}
++
++	/*
++	 * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
++	 * STBC values if they weren't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_20_stbc[i] == 0)
++			txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
++
++		if (txpwr->mcs_40_stbc[i] == 0)
++			txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	return;
++}
++
++/*
++ * Verify the chanspec is using a legal set of parameters, i.e. that the
++ * chanspec specified a band, bw, ctl_sb and channel and that the
++ * combination could be legal given any set of circumstances.
++ * RETURNS: true is the chanspec is malformed, false if it looks good.
++ */
++static bool brcms_c_chspec_malformed(u16 chanspec)
++{
++	/* must be 2G or 5G band */
++	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
++		return true;
++	/* must be 20 or 40 bandwidth */
++	if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
++		return true;
++
++	/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
++	if (CHSPEC_IS20(chanspec)) {
++		if (!CHSPEC_SB_NONE(chanspec))
++			return true;
++	} else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
++		return true;
++	}
++
++	return false;
++}
++
++/*
++ * Validate the chanspec for this locale, for 40MHZ we need to also
++ * check that the sidebands are valid 20MZH channels in this locale
++ * and they are also a legal HT combination
++ */
++static bool
++brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec,
++			   bool dualband)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	u8 channel = CHSPEC_CHANNEL(chspec);
++
++	/* check the chanspec */
++	if (brcms_c_chspec_malformed(chspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
++			wlc->pub->unit, chspec);
++		return false;
++	}
++
++	if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
++	    chspec_bandunit(chspec))
++		return false;
++
++	/* Check a 20Mhz channel */
++	if (CHSPEC_IS20(chspec)) {
++		if (dualband)
++			return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi,
++							  channel);
++		else
++			return brcms_c_valid_channel20(wlc_cm->wlc->cmi,
++						       channel);
++	}
++#ifdef SUPPORT_40MHZ
++	/*
++	 * We know we are now checking a 40MHZ channel, so we should
++	 * only be here for NPHYS
++	 */
++	if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) {
++		u8 upper_sideband = 0, idx;
++		u8 num_ch20_entries =
++		    sizeof(chan20_info) / sizeof(struct chan20_info);
++
++		if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec)))
++			return false;
++
++		if (dualband) {
++			if (!brcms_c_valid_channel20_db(wlc->cmi,
++							lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20_db(wlc->cmi,
++							upper_20_sb(channel)))
++				return false;
++		} else {
++			if (!brcms_c_valid_channel20(wlc->cmi,
++						     lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20(wlc->cmi,
++						     upper_20_sb(channel)))
++				return false;
++		}
++
++		/* find the lower sideband info in the sideband array */
++		for (idx = 0; idx < num_ch20_entries; idx++) {
++			if (chan20_info[idx].sb == lower_20_sb(channel))
++				upper_sideband = chan20_info[idx].adj_sbs;
++		}
++		/* check that the lower sideband allows an upper sideband */
++		if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
++		    (CH_UPPER_SB | CH_EWA_VALID))
++			return true;
++		return false;
++	}
++#endif				/* 40 MHZ */
++
++	return false;
++}
++
++bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+new file mode 100644
+index 0000000..808cb4f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_CHANNEL_H_
++#define _BRCM_CHANNEL_H_
++
++/* conversion for phy txpwr calculations that use .25 dB units */
++#define BRCMS_TXPWR_DB_FACTOR 4
++
++/* bits for locale_info flags */
++#define BRCMS_PEAK_CONDUCTED	0x00	/* Peak for locals */
++#define BRCMS_EIRP		0x01	/* Flag for EIRP */
++#define BRCMS_DFS_TPC		0x02	/* Flag for DFS TPC */
++#define BRCMS_NO_OFDM		0x04	/* Flag for No OFDM */
++#define BRCMS_NO_40MHZ		0x08	/* Flag for No MIMO 40MHz */
++#define BRCMS_NO_MIMO		0x10	/* Flag for No MIMO, 20 or 40 MHz */
++#define BRCMS_RADAR_TYPE_EU       0x20	/* Flag for EU */
++#define BRCMS_DFS_FCC             BRCMS_DFS_TPC	/* Flag for DFS FCC */
++
++#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
++
++extern struct brcms_cm_info *
++brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
++
++extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
++
++extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++					   uint bandunit);
++
++extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
++				      u16 chspec);
++
++extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
++				   u16 chanspec,
++				   struct txpwr_limits *txpwr);
++extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
++				     u16 chanspec,
++				     u8 local_constraint_qdbm);
++
++#endif				/* _WLC_CHANNEL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/d11.h b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+new file mode 100644
+index 0000000..3f659e0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+@@ -0,0 +1,1901 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_D11_H_
++#define	_BRCM_D11_H_
++
++#include <linux/ieee80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "dma.h"
++
++/* RX FIFO numbers */
++#define	RX_FIFO			0	/* data and ctl frames */
++#define	RX_TXSTATUS_FIFO	3	/* RX fifo for tx status packages */
++
++/* TX FIFO numbers using WME Access Category */
++#define	TX_AC_BK_FIFO		0	/* Background TX FIFO */
++#define	TX_AC_BE_FIFO		1	/* Best-Effort TX FIFO */
++#define	TX_AC_VI_FIFO		2	/* Video TX FIFO */
++#define	TX_AC_VO_FIFO		3	/* Voice TX FIFO */
++#define	TX_BCMC_FIFO		4	/* Broadcast/Multicast TX FIFO */
++#define	TX_ATIM_FIFO		5	/* TX fifo for ATIM window info */
++
++/* Addr is byte address used by SW; offset is word offset used by uCode */
++
++/* Per AC TX limit settings */
++#define M_AC_TXLMT_BASE_ADDR         (0x180 * 2)
++#define M_AC_TXLMT_ADDR(_ac)         (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
++
++/* Legacy TX FIFO numbers */
++#define	TX_DATA_FIFO		TX_AC_BE_FIFO
++#define	TX_CTL_FIFO		TX_AC_VO_FIFO
++
++#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
++
++struct intctrlregs {
++	u32 intstatus;
++	u32 intmask;
++};
++
++/* PIO structure,
++ *  support two PIO format: 2 bytes access and 4 bytes access
++ *  basic FIFO register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++/* 2byte-wide pio register set per channel(xmt or rcv) */
++struct pio2regs {
++	u16 fifocontrol;
++	u16 fifodata;
++	u16 fifofree;	/* only valid in xmt channel, not in rcv channel */
++	u16 PAD;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio2regp {
++	struct pio2regs tx;
++	struct pio2regs rx;
++};
++
++/* 4byte-wide pio register set per channel(xmt or rcv) */
++struct pio4regs {
++	u32 fifocontrol;
++	u32 fifodata;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio4regp {
++	struct pio4regs tx;
++	struct pio4regs rx;
++};
++
++/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
++ * write: only low 16b-it half can be written
++ */
++union pmqreg {
++	u32 pmqhostdata;	/* read only! */
++	struct {
++		u16 pmqctrlstatus;	/* read/write */
++		u16 PAD;
++	} w;
++};
++
++struct fifo64 {
++	struct dma64regs dmaxmt;	/* dma tx */
++	struct pio4regs piotx;	/* pio tx */
++	struct dma64regs dmarcv;	/* dma rx */
++	struct pio4regs piorx;	/* pio rx */
++};
++
++/*
++ * Host Interface Registers
++ */
++struct d11regs {
++	/* Device Control ("semi-standard host registers") */
++	u32 PAD[3];		/* 0x0 - 0x8 */
++	u32 biststatus;	/* 0xC */
++	u32 biststatus2;	/* 0x10 */
++	u32 PAD;		/* 0x14 */
++	u32 gptimer;		/* 0x18 */
++	u32 usectimer;	/* 0x1c *//* for corerev >= 26 */
++
++	/* Interrupt Control *//* 0x20 */
++	struct intctrlregs intctrlregs[8];
++
++	u32 PAD[40];		/* 0x60 - 0xFC */
++
++	u32 intrcvlazy[4];	/* 0x100 - 0x10C */
++
++	u32 PAD[4];		/* 0x110 - 0x11c */
++
++	u32 maccontrol;	/* 0x120 */
++	u32 maccommand;	/* 0x124 */
++	u32 macintstatus;	/* 0x128 */
++	u32 macintmask;	/* 0x12C */
++
++	/* Transmit Template Access */
++	u32 tplatewrptr;	/* 0x130 */
++	u32 tplatewrdata;	/* 0x134 */
++	u32 PAD[2];		/* 0x138 - 0x13C */
++
++	/* PMQ registers */
++	union pmqreg pmqreg;	/* 0x140 */
++	u32 pmqpatl;		/* 0x144 */
++	u32 pmqpath;		/* 0x148 */
++	u32 PAD;		/* 0x14C */
++
++	u32 chnstatus;	/* 0x150 */
++	u32 psmdebug;	/* 0x154 */
++	u32 phydebug;	/* 0x158 */
++	u32 machwcap;	/* 0x15C */
++
++	/* Extended Internal Objects */
++	u32 objaddr;		/* 0x160 */
++	u32 objdata;		/* 0x164 */
++	u32 PAD[2];		/* 0x168 - 0x16c */
++
++	u32 frmtxstatus;	/* 0x170 */
++	u32 frmtxstatus2;	/* 0x174 */
++	u32 PAD[2];		/* 0x178 - 0x17c */
++
++	/* TSF host access */
++	u32 tsf_timerlow;	/* 0x180 */
++	u32 tsf_timerhigh;	/* 0x184 */
++	u32 tsf_cfprep;	/* 0x188 */
++	u32 tsf_cfpstart;	/* 0x18c */
++	u32 tsf_cfpmaxdur32;	/* 0x190 */
++	u32 PAD[3];		/* 0x194 - 0x19c */
++
++	u32 maccontrol1;	/* 0x1a0 */
++	u32 machwcap1;	/* 0x1a4 */
++	u32 PAD[14];		/* 0x1a8 - 0x1dc */
++
++	/* Clock control and hardware workarounds*/
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 d11_phypllctl;	/* the phypll request/avail bits are
++				 * moved to clk_ctl_st
++				 */
++	u32 PAD[5];		/* 0x1ec - 0x1fc */
++
++	/* 0x200-0x37F dma/pio registers */
++	struct fifo64 fifo64regs[6];
++
++	/* FIFO diagnostic port access */
++	struct dma32diag dmafifo;	/* 0x380 - 0x38C */
++
++	u32 aggfifocnt;	/* 0x390 */
++	u32 aggfifodata;	/* 0x394 */
++	u32 PAD[16];		/* 0x398 - 0x3d4 */
++	u16 radioregaddr;	/* 0x3d8 */
++	u16 radioregdata;	/* 0x3da */
++
++	/*
++	 * time delay between the change on rf disable input and
++	 * radio shutdown
++	 */
++	u32 rfdisabledly;	/* 0x3DC */
++
++	/* PHY register access */
++	u16 phyversion;	/* 0x3e0 - 0x0 */
++	u16 phybbconfig;	/* 0x3e2 - 0x1 */
++	u16 phyadcbias;	/* 0x3e4 - 0x2  Bphy only */
++	u16 phyanacore;	/* 0x3e6 - 0x3  pwwrdwn on aphy */
++	u16 phyrxstatus0;	/* 0x3e8 - 0x4 */
++	u16 phyrxstatus1;	/* 0x3ea - 0x5 */
++	u16 phycrsth;	/* 0x3ec - 0x6 */
++	u16 phytxerror;	/* 0x3ee - 0x7 */
++	u16 phychannel;	/* 0x3f0 - 0x8 */
++	u16 PAD[1];		/* 0x3f2 - 0x9 */
++	u16 phytest;		/* 0x3f4 - 0xa */
++	u16 phy4waddr;	/* 0x3f6 - 0xb */
++	u16 phy4wdatahi;	/* 0x3f8 - 0xc */
++	u16 phy4wdatalo;	/* 0x3fa - 0xd */
++	u16 phyregaddr;	/* 0x3fc - 0xe */
++	u16 phyregdata;	/* 0x3fe - 0xf */
++
++	/* IHR *//* 0x400 - 0x7FE */
++
++	/* RXE Block */
++	u16 PAD[3];		/* 0x400 - 0x406 */
++	u16 rcv_fifo_ctl;	/* 0x406 */
++	u16 PAD;		/* 0x408 - 0x40a */
++	u16 rcv_frm_cnt;	/* 0x40a */
++	u16 PAD[4];		/* 0x40a - 0x414 */
++	u16 rssi;		/* 0x414 */
++	u16 PAD[5];		/* 0x414 - 0x420 */
++	u16 rcm_ctl;		/* 0x420 */
++	u16 rcm_mat_data;	/* 0x422 */
++	u16 rcm_mat_mask;	/* 0x424 */
++	u16 rcm_mat_dly;	/* 0x426 */
++	u16 rcm_cond_mask_l;	/* 0x428 */
++	u16 rcm_cond_mask_h;	/* 0x42A */
++	u16 rcm_cond_dly;	/* 0x42C */
++	u16 PAD[1];		/* 0x42E */
++	u16 ext_ihr_addr;	/* 0x430 */
++	u16 ext_ihr_data;	/* 0x432 */
++	u16 rxe_phyrs_2;	/* 0x434 */
++	u16 rxe_phyrs_3;	/* 0x436 */
++	u16 phy_mode;	/* 0x438 */
++	u16 rcmta_ctl;	/* 0x43a */
++	u16 rcmta_size;	/* 0x43c */
++	u16 rcmta_addr0;	/* 0x43e */
++	u16 rcmta_addr1;	/* 0x440 */
++	u16 rcmta_addr2;	/* 0x442 */
++	u16 PAD[30];		/* 0x444 - 0x480 */
++
++	/* PSM Block *//* 0x480 - 0x500 */
++
++	u16 PAD;		/* 0x480 */
++	u16 psm_maccontrol_h;	/* 0x482 */
++	u16 psm_macintstatus_l;	/* 0x484 */
++	u16 psm_macintstatus_h;	/* 0x486 */
++	u16 psm_macintmask_l;	/* 0x488 */
++	u16 psm_macintmask_h;	/* 0x48A */
++	u16 PAD;		/* 0x48C */
++	u16 psm_maccommand;	/* 0x48E */
++	u16 psm_brc;		/* 0x490 */
++	u16 psm_phy_hdr_param;	/* 0x492 */
++	u16 psm_postcard;	/* 0x494 */
++	u16 psm_pcard_loc_l;	/* 0x496 */
++	u16 psm_pcard_loc_h;	/* 0x498 */
++	u16 psm_gpio_in;	/* 0x49A */
++	u16 psm_gpio_out;	/* 0x49C */
++	u16 psm_gpio_oe;	/* 0x49E */
++
++	u16 psm_bred_0;	/* 0x4A0 */
++	u16 psm_bred_1;	/* 0x4A2 */
++	u16 psm_bred_2;	/* 0x4A4 */
++	u16 psm_bred_3;	/* 0x4A6 */
++	u16 psm_brcl_0;	/* 0x4A8 */
++	u16 psm_brcl_1;	/* 0x4AA */
++	u16 psm_brcl_2;	/* 0x4AC */
++	u16 psm_brcl_3;	/* 0x4AE */
++	u16 psm_brpo_0;	/* 0x4B0 */
++	u16 psm_brpo_1;	/* 0x4B2 */
++	u16 psm_brpo_2;	/* 0x4B4 */
++	u16 psm_brpo_3;	/* 0x4B6 */
++	u16 psm_brwk_0;	/* 0x4B8 */
++	u16 psm_brwk_1;	/* 0x4BA */
++	u16 psm_brwk_2;	/* 0x4BC */
++	u16 psm_brwk_3;	/* 0x4BE */
++
++	u16 psm_base_0;	/* 0x4C0 */
++	u16 psm_base_1;	/* 0x4C2 */
++	u16 psm_base_2;	/* 0x4C4 */
++	u16 psm_base_3;	/* 0x4C6 */
++	u16 psm_base_4;	/* 0x4C8 */
++	u16 psm_base_5;	/* 0x4CA */
++	u16 psm_base_6;	/* 0x4CC */
++	u16 psm_pc_reg_0;	/* 0x4CE */
++	u16 psm_pc_reg_1;	/* 0x4D0 */
++	u16 psm_pc_reg_2;	/* 0x4D2 */
++	u16 psm_pc_reg_3;	/* 0x4D4 */
++	u16 PAD[0xD];	/* 0x4D6 - 0x4DE */
++	u16 psm_corectlsts;	/* 0x4f0 *//* Corerev >= 13 */
++	u16 PAD[0x7];	/* 0x4f2 - 0x4fE */
++
++	/* TXE0 Block *//* 0x500 - 0x580 */
++	u16 txe_ctl;		/* 0x500 */
++	u16 txe_aux;		/* 0x502 */
++	u16 txe_ts_loc;	/* 0x504 */
++	u16 txe_time_out;	/* 0x506 */
++	u16 txe_wm_0;	/* 0x508 */
++	u16 txe_wm_1;	/* 0x50A */
++	u16 txe_phyctl;	/* 0x50C */
++	u16 txe_status;	/* 0x50E */
++	u16 txe_mmplcp0;	/* 0x510 */
++	u16 txe_mmplcp1;	/* 0x512 */
++	u16 txe_phyctl1;	/* 0x514 */
++
++	u16 PAD[0x05];	/* 0x510 - 0x51E */
++
++	/* Transmit control */
++	u16 xmtfifodef;	/* 0x520 */
++	u16 xmtfifo_frame_cnt;	/* 0x522 *//* Corerev >= 16 */
++	u16 xmtfifo_byte_cnt;	/* 0x524 *//* Corerev >= 16 */
++	u16 xmtfifo_head;	/* 0x526 *//* Corerev >= 16 */
++	u16 xmtfifo_rd_ptr;	/* 0x528 *//* Corerev >= 16 */
++	u16 xmtfifo_wr_ptr;	/* 0x52A *//* Corerev >= 16 */
++	u16 xmtfifodef1;	/* 0x52C *//* Corerev >= 16 */
++
++	u16 PAD[0x09];	/* 0x52E - 0x53E */
++
++	u16 xmtfifocmd;	/* 0x540 */
++	u16 xmtfifoflush;	/* 0x542 */
++	u16 xmtfifothresh;	/* 0x544 */
++	u16 xmtfifordy;	/* 0x546 */
++	u16 xmtfifoprirdy;	/* 0x548 */
++	u16 xmtfiforqpri;	/* 0x54A */
++	u16 xmttplatetxptr;	/* 0x54C */
++	u16 PAD;		/* 0x54E */
++	u16 xmttplateptr;	/* 0x550 */
++	u16 smpl_clct_strptr;	/* 0x552 *//* Corerev >= 22 */
++	u16 smpl_clct_stpptr;	/* 0x554 *//* Corerev >= 22 */
++	u16 smpl_clct_curptr;	/* 0x556 *//* Corerev >= 22 */
++	u16 PAD[0x04];	/* 0x558 - 0x55E */
++	u16 xmttplatedatalo;	/* 0x560 */
++	u16 xmttplatedatahi;	/* 0x562 */
++
++	u16 PAD[2];		/* 0x564 - 0x566 */
++
++	u16 xmtsel;		/* 0x568 */
++	u16 xmttxcnt;	/* 0x56A */
++	u16 xmttxshmaddr;	/* 0x56C */
++
++	u16 PAD[0x09];	/* 0x56E - 0x57E */
++
++	/* TXE1 Block */
++	u16 PAD[0x40];	/* 0x580 - 0x5FE */
++
++	/* TSF Block */
++	u16 PAD[0X02];	/* 0x600 - 0x602 */
++	u16 tsf_cfpstrt_l;	/* 0x604 */
++	u16 tsf_cfpstrt_h;	/* 0x606 */
++	u16 PAD[0X05];	/* 0x608 - 0x610 */
++	u16 tsf_cfppretbtt;	/* 0x612 */
++	u16 PAD[0XD];	/* 0x614 - 0x62C */
++	u16 tsf_clk_frac_l;	/* 0x62E */
++	u16 tsf_clk_frac_h;	/* 0x630 */
++	u16 PAD[0X14];	/* 0x632 - 0x658 */
++	u16 tsf_random;	/* 0x65A */
++	u16 PAD[0x05];	/* 0x65C - 0x664 */
++	/* GPTimer 2 registers */
++	u16 tsf_gpt2_stat;	/* 0x666 */
++	u16 tsf_gpt2_ctr_l;	/* 0x668 */
++	u16 tsf_gpt2_ctr_h;	/* 0x66A */
++	u16 tsf_gpt2_val_l;	/* 0x66C */
++	u16 tsf_gpt2_val_h;	/* 0x66E */
++	u16 tsf_gptall_stat;	/* 0x670 */
++	u16 PAD[0x07];	/* 0x672 - 0x67E */
++
++	/* IFS Block */
++	u16 ifs_sifs_rx_tx_tx;	/* 0x680 */
++	u16 ifs_sifs_nav_tx;	/* 0x682 */
++	u16 ifs_slot;	/* 0x684 */
++	u16 PAD;		/* 0x686 */
++	u16 ifs_ctl;		/* 0x688 */
++	u16 PAD[0x3];	/* 0x68a - 0x68F */
++	u16 ifsstat;		/* 0x690 */
++	u16 ifsmedbusyctl;	/* 0x692 */
++	u16 iftxdur;		/* 0x694 */
++	u16 PAD[0x3];	/* 0x696 - 0x69b */
++	/* EDCF support in dot11macs */
++	u16 ifs_aifsn;	/* 0x69c */
++	u16 ifs_ctl1;	/* 0x69e */
++
++	/* slow clock registers */
++	u16 scc_ctl;		/* 0x6a0 */
++	u16 scc_timer_l;	/* 0x6a2 */
++	u16 scc_timer_h;	/* 0x6a4 */
++	u16 scc_frac;	/* 0x6a6 */
++	u16 scc_fastpwrup_dly;	/* 0x6a8 */
++	u16 scc_per;		/* 0x6aa */
++	u16 scc_per_frac;	/* 0x6ac */
++	u16 scc_cal_timer_l;	/* 0x6ae */
++	u16 scc_cal_timer_h;	/* 0x6b0 */
++	u16 PAD;		/* 0x6b2 */
++
++	u16 PAD[0x26];
++
++	/* NAV Block */
++	u16 nav_ctl;		/* 0x700 */
++	u16 navstat;		/* 0x702 */
++	u16 PAD[0x3e];	/* 0x702 - 0x77E */
++
++	/* WEP/PMQ Block *//* 0x780 - 0x7FE */
++	u16 PAD[0x20];	/* 0x780 - 0x7BE */
++
++	u16 wepctl;		/* 0x7C0 */
++	u16 wepivloc;	/* 0x7C2 */
++	u16 wepivkey;	/* 0x7C4 */
++	u16 wepwkey;		/* 0x7C6 */
++
++	u16 PAD[4];		/* 0x7C8 - 0x7CE */
++	u16 pcmctl;		/* 0X7D0 */
++	u16 pcmstat;		/* 0X7D2 */
++	u16 PAD[6];		/* 0x7D4 - 0x7DE */
++
++	u16 pmqctl;		/* 0x7E0 */
++	u16 pmqstatus;	/* 0x7E2 */
++	u16 pmqpat0;		/* 0x7E4 */
++	u16 pmqpat1;		/* 0x7E6 */
++	u16 pmqpat2;		/* 0x7E8 */
++
++	u16 pmqdat;		/* 0x7EA */
++	u16 pmqdator;	/* 0x7EC */
++	u16 pmqhst;		/* 0x7EE */
++	u16 pmqpath0;	/* 0x7F0 */
++	u16 pmqpath1;	/* 0x7F2 */
++	u16 pmqpath2;	/* 0x7F4 */
++	u16 pmqdath;		/* 0x7F6 */
++
++	u16 PAD[0x04];	/* 0x7F8 - 0x7FE */
++
++	/* SHM *//* 0x800 - 0xEFE */
++	u16 PAD[0x380];	/* 0x800 - 0xEFE */
++};
++
++/* d11 register field offset */
++#define D11REGOFFS(field)	offsetof(struct d11regs, field)
++
++#define	PIHR_BASE	0x0400	/* byte address of packed IHR region */
++
++/* biststatus */
++#define	BT_DONE		(1U << 31)	/* bist done */
++#define	BT_B2S		(1 << 30)	/* bist2 ram summary bit */
++
++/* intstatus and intmask */
++#define	I_PC		(1 << 10)	/* pci descriptor error */
++#define	I_PD		(1 << 11)	/* pci data error */
++#define	I_DE		(1 << 12)	/* descriptor protocol error */
++#define	I_RU		(1 << 13)	/* receive descriptor underflow */
++#define	I_RO		(1 << 14)	/* receive fifo overflow */
++#define	I_XU		(1 << 15)	/* transmit fifo underflow */
++#define	I_RI		(1 << 16)	/* receive interrupt */
++#define	I_XI		(1 << 24)	/* transmit interrupt */
++
++/* interrupt receive lazy */
++#define	IRL_TO_MASK		0x00ffffff	/* timeout */
++#define	IRL_FC_MASK		0xff000000	/* frame count */
++#define	IRL_FC_SHIFT		24	/* frame count */
++
++/*== maccontrol register ==*/
++#define	MCTL_GMODE		(1U << 31)
++#define	MCTL_DISCARD_PMQ	(1 << 30)
++#define	MCTL_WAKE		(1 << 26)
++#define	MCTL_HPS		(1 << 25)
++#define	MCTL_PROMISC		(1 << 24)
++#define	MCTL_KEEPBADFCS		(1 << 23)
++#define	MCTL_KEEPCONTROL	(1 << 22)
++#define	MCTL_PHYLOCK		(1 << 21)
++#define	MCTL_BCNS_PROMISC	(1 << 20)
++#define	MCTL_LOCK_RADIO		(1 << 19)
++#define	MCTL_AP			(1 << 18)
++#define	MCTL_INFRA		(1 << 17)
++#define	MCTL_BIGEND		(1 << 16)
++#define	MCTL_GPOUT_SEL_MASK	(3 << 14)
++#define	MCTL_GPOUT_SEL_SHIFT	14
++#define	MCTL_EN_PSMDBG		(1 << 13)
++#define	MCTL_IHR_EN		(1 << 10)
++#define	MCTL_SHM_UPPER		(1 <<  9)
++#define	MCTL_SHM_EN		(1 <<  8)
++#define	MCTL_PSM_JMP_0		(1 <<  2)
++#define	MCTL_PSM_RUN		(1 <<  1)
++#define	MCTL_EN_MAC		(1 <<  0)
++
++/*== maccommand register ==*/
++#define	MCMD_BCN0VLD		(1 <<  0)
++#define	MCMD_BCN1VLD		(1 <<  1)
++#define	MCMD_DIRFRMQVAL		(1 <<  2)
++#define	MCMD_CCA		(1 <<  3)
++#define	MCMD_BG_NOISE		(1 <<  4)
++#define	MCMD_SKIP_SHMINIT	(1 <<  5)	/* only used for simulation */
++#define MCMD_SAMPLECOLL		MCMD_SKIP_SHMINIT /* reuse for sample collect */
++
++/*== macintstatus/macintmask ==*/
++/* gracefully suspended */
++#define	MI_MACSSPNDD		(1 <<  0)
++/* beacon template available */
++#define	MI_BCNTPL		(1 <<  1)
++/* TBTT indication */
++#define	MI_TBTT			(1 <<  2)
++/* beacon successfully tx'd */
++#define	MI_BCNSUCCESS		(1 <<  3)
++/* beacon canceled (IBSS) */
++#define	MI_BCNCANCLD		(1 <<  4)
++/* end of ATIM-window (IBSS) */
++#define	MI_ATIMWINEND		(1 <<  5)
++/* PMQ entries available */
++#define	MI_PMQ			(1 <<  6)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_0		(1 <<  7)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_1		(1 <<  8)
++/* MAC level Tx error */
++#define	MI_MACTXERR		(1 <<  9)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_3		(1 << 10)
++/* PHY Tx error */
++#define	MI_PHYTXERR		(1 << 11)
++/* Power Management Event */
++#define	MI_PME			(1 << 12)
++/* General-purpose timer0 */
++#define	MI_GP0			(1 << 13)
++/* General-purpose timer1 */
++#define	MI_GP1			(1 << 14)
++/* (ORed) DMA-interrupts */
++#define	MI_DMAINT		(1 << 15)
++/* MAC has completed a TX FIFO Suspend/Flush */
++#define	MI_TXSTOP		(1 << 16)
++/* MAC has completed a CCA measurement */
++#define	MI_CCA			(1 << 17)
++/* MAC has collected background noise samples */
++#define	MI_BG_NOISE		(1 << 18)
++/* MBSS DTIM TBTT indication */
++#define	MI_DTIM_TBTT		(1 << 19)
++/* Probe response queue needs attention */
++#define MI_PRQ			(1 << 20)
++/* Radio/PHY has been powered back up. */
++#define	MI_PWRUP		(1 << 21)
++#define	MI_RESERVED3		(1 << 22)
++#define	MI_RESERVED2		(1 << 23)
++#define MI_RESERVED1		(1 << 25)
++/* MAC detected change on RF Disable input*/
++#define MI_RFDISABLE		(1 << 28)
++/* MAC has completed a TX */
++#define	MI_TFS			(1 << 29)
++/* A phy status change wrt G mode */
++#define	MI_PHYCHANGED		(1 << 30)
++/* general purpose timeout */
++#define	MI_TO			(1U << 31)
++
++/* Mac capabilities registers */
++/*== machwcap ==*/
++#define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
++
++/*== pmqhost data ==*/
++/* data entry of head pmq entry */
++#define	PMQH_DATA_MASK		0xffff0000
++/* PM entry for BSS config */
++#define	PMQH_BSSCFG		0x00100000
++/* PM Mode OFF: power save off */
++#define	PMQH_PMOFF		0x00010000
++/* PM Mode ON: power save on */
++#define	PMQH_PMON		0x00020000
++/* Dis-associated or De-authenticated */
++#define	PMQH_DASAT		0x00040000
++/* ATIM not acknowledged */
++#define	PMQH_ATIMFAIL		0x00080000
++/* delete head entry */
++#define	PMQH_DEL_ENTRY		0x00000001
++/* delete head entry to cur read pointer -1 */
++#define	PMQH_DEL_MULT		0x00000002
++/* pmq overflow indication */
++#define	PMQH_OFLO		0x00000004
++/* entries are present in pmq */
++#define	PMQH_NOT_EMPTY		0x00000008
++
++/*== phydebug ==*/
++/* phy is asserting carrier sense */
++#define	PDBG_CRS		(1 << 0)
++/* phy is taking xmit byte from mac this cycle */
++#define	PDBG_TXA		(1 << 1)
++/* mac is instructing the phy to transmit a frame */
++#define	PDBG_TXF		(1 << 2)
++/* phy is signalling a transmit Error to the mac */
++#define	PDBG_TXE		(1 << 3)
++/* phy detected the end of a valid frame preamble */
++#define	PDBG_RXF		(1 << 4)
++/* phy detected the end of a valid PLCP header */
++#define	PDBG_RXS		(1 << 5)
++/* rx start not asserted */
++#define	PDBG_RXFRG		(1 << 6)
++/* mac is taking receive byte from phy this cycle */
++#define	PDBG_RXV		(1 << 7)
++/* RF portion of the radio is disabled */
++#define	PDBG_RFD		(1 << 16)
++
++/*== objaddr register ==*/
++#define	OBJADDR_SEL_MASK	0x000F0000
++#define	OBJADDR_UCM_SEL		0x00000000
++#define	OBJADDR_SHM_SEL		0x00010000
++#define	OBJADDR_SCR_SEL		0x00020000
++#define	OBJADDR_IHR_SEL		0x00030000
++#define	OBJADDR_RCMTA_SEL	0x00040000
++#define	OBJADDR_SRCHM_SEL	0x00060000
++#define	OBJADDR_WINC		0x01000000
++#define	OBJADDR_RINC		0x02000000
++#define	OBJADDR_AUTO_INC	0x03000000
++
++#define	WEP_PCMADDR		0x07d4
++#define	WEP_PCMDATA		0x07d6
++
++/*== frmtxstatus ==*/
++#define	TXS_V			(1 << 0)	/* valid bit */
++#define	TXS_STATUS_MASK		0xffff
++#define	TXS_FID_MASK		0xffff0000
++#define	TXS_FID_SHIFT		16
++
++/*== frmtxstatus2 ==*/
++#define	TXS_SEQ_MASK		0xffff
++#define	TXS_PTX_MASK		0xff0000
++#define	TXS_PTX_SHIFT		16
++#define	TXS_MU_MASK		0x01000000
++#define	TXS_MU_SHIFT		24
++
++/*== clk_ctl_st ==*/
++#define CCS_ERSRC_REQ_D11PLL	0x00000100	/* d11 core pll request */
++#define CCS_ERSRC_REQ_PHYPLL	0x00000200	/* PHY pll request */
++#define CCS_ERSRC_AVAIL_D11PLL	0x01000000	/* d11 core pll available */
++#define CCS_ERSRC_AVAIL_PHYPLL	0x02000000	/* PHY pll available */
++
++/* HT Cloclk Ctrl and Clock Avail for 4313 */
++#define CCS_ERSRC_REQ_HT    0x00000010	/* HT avail request */
++#define CCS_ERSRC_AVAIL_HT  0x00020000	/* HT clock available */
++
++/* tsf_cfprep register */
++#define	CFPREP_CBI_MASK		0xffffffc0
++#define	CFPREP_CBI_SHIFT	6
++#define	CFPREP_CFPP		0x00000001
++
++/* tx fifo sizes values are in terms of 256 byte blocks */
++#define TXFIFOCMD_RESET_MASK	(1 << 15)	/* reset */
++#define TXFIFOCMD_FIFOSEL_SHIFT	8	/* fifo */
++#define TXFIFO_FIFOTOP_SHIFT	8	/* fifo start */
++
++#define TXFIFO_START_BLK16	 65	/* Base address + 32 * 512 B/P */
++#define TXFIFO_START_BLK	 6	/* Base address + 6 * 256 B */
++#define TXFIFO_SIZE_UNIT	256	/* one unit corresponds to 256 bytes */
++#define MBSS16_TEMPLMEM_MINBLKS	65	/* one unit corresponds to 256 bytes */
++
++/*== phy versions (PhyVersion:Revision field) ==*/
++/* analog block version */
++#define	PV_AV_MASK		0xf000
++/* analog block version bitfield offset */
++#define	PV_AV_SHIFT		12
++/* phy type */
++#define	PV_PT_MASK		0x0f00
++/* phy type bitfield offset */
++#define	PV_PT_SHIFT		8
++/* phy version */
++#define	PV_PV_MASK		0x000f
++#define	PHY_TYPE(v)		((v & PV_PT_MASK) >> PV_PT_SHIFT)
++
++/*== phy types (PhyVersion:PhyType field) ==*/
++#define	PHY_TYPE_N		4	/* N-Phy value */
++#define	PHY_TYPE_SSN		6	/* SSLPN-Phy value */
++#define	PHY_TYPE_LCN		8	/* LCN-Phy value */
++#define	PHY_TYPE_LCNXN		9	/* LCNXN-Phy value */
++#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
++
++/*== analog types (PhyVersion:AnalogType field) ==*/
++#define	ANA_11N_013		5
++
++/* 802.11a PLCP header def */
++struct ofdm_phy_hdr {
++	u8 rlpt[3];		/* rate, length, parity, tail */
++	u16 service;
++	u8 pad;
++} __packed;
++
++#define	D11A_PHY_HDR_GRATE(phdr)	((phdr)->rlpt[0] & 0x0f)
++#define	D11A_PHY_HDR_GRES(phdr)		(((phdr)->rlpt[0] >> 4) & 0x01)
++#define	D11A_PHY_HDR_GLENGTH(phdr)	(((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
++#define	D11A_PHY_HDR_GPARITY(phdr)	(((phdr)->rlpt[3] >> 1) & 0x01)
++#define	D11A_PHY_HDR_GTAIL(phdr)	(((phdr)->rlpt[3] >> 2) & 0x3f)
++
++/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
++#define	D11A_PHY_HDR_SRATE(phdr, rate)		\
++	((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
++/* set reserved field to zero */
++#define	D11A_PHY_HDR_SRES(phdr)		((phdr)->rlpt[0] &= 0xef)
++/* length is number of octets in PSDU */
++#define	D11A_PHY_HDR_SLENGTH(phdr, length)	\
++	(*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
++	(((length) & 0x0fff) << 5))
++/* set the tail to all zeros */
++#define	D11A_PHY_HDR_STAIL(phdr)	((phdr)->rlpt[3] &= 0x03)
++
++#define	D11A_PHY_HDR_LEN_L	3	/* low-rate part of PLCP header */
++#define	D11A_PHY_HDR_LEN_R	2	/* high-rate part of PLCP header */
++
++#define	D11A_PHY_TX_DELAY	(2)	/* 2.1 usec */
++
++#define	D11A_PHY_HDR_TIME	(4)	/* low-rate part of PLCP header */
++#define	D11A_PHY_PRE_TIME	(16)
++#define	D11A_PHY_PREHDR_TIME	(D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
++
++/* 802.11b PLCP header def */
++struct cck_phy_hdr {
++	u8 signal;
++	u8 service;
++	u16 length;
++	u16 crc;
++} __packed;
++
++#define	D11B_PHY_HDR_LEN	6
++
++#define	D11B_PHY_TX_DELAY	(3)	/* 3.4 usec */
++
++#define	D11B_PHY_LHDR_TIME	(D11B_PHY_HDR_LEN << 3)
++#define	D11B_PHY_LPRE_TIME	(144)
++#define	D11B_PHY_LPREHDR_TIME	(D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
++
++#define	D11B_PHY_SHDR_TIME	(D11B_PHY_LHDR_TIME >> 1)
++#define	D11B_PHY_SPRE_TIME	(D11B_PHY_LPRE_TIME >> 1)
++#define	D11B_PHY_SPREHDR_TIME	(D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
++
++#define	D11B_PLCP_SIGNAL_LOCKED	(1 << 2)
++#define	D11B_PLCP_SIGNAL_LE	(1 << 7)
++
++#define MIMO_PLCP_MCS_MASK	0x7f	/* mcs index */
++#define MIMO_PLCP_40MHZ		0x80	/* 40 Hz frame */
++#define MIMO_PLCP_AMPDU		0x08	/* ampdu */
++
++#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
++#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
++#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
++	do { \
++		plcp[1] = len & 0xff; \
++		plcp[2] = ((len >> 8) & 0xff); \
++	} while (0)
++
++#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
++#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
++#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
++
++/*
++ * The dot11a PLCP header is 5 bytes.  To simplify the software (so that we
++ * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header
++ * has padding added in the ucode.
++ */
++#define	D11_PHY_HDR_LEN	6
++
++/* TX DMA buffer header */
++struct d11txh {
++	__le16 MacTxControlLow;	/* 0x0 */
++	__le16 MacTxControlHigh;	/* 0x1 */
++	__le16 MacFrameControl;	/* 0x2 */
++	__le16 TxFesTimeNormal;	/* 0x3 */
++	__le16 PhyTxControlWord;	/* 0x4 */
++	__le16 PhyTxControlWord_1;	/* 0x5 */
++	__le16 PhyTxControlWord_1_Fbr;	/* 0x6 */
++	__le16 PhyTxControlWord_1_Rts;	/* 0x7 */
++	__le16 PhyTxControlWord_1_FbrRts;	/* 0x8 */
++	__le16 MainRates;	/* 0x9 */
++	__le16 XtraFrameTypes;	/* 0xa */
++	u8 IV[16];		/* 0x0b - 0x12 */
++	u8 TxFrameRA[6];	/* 0x13 - 0x15 */
++	__le16 TxFesTimeFallback;	/* 0x16 */
++	u8 RTSPLCPFallback[6];	/* 0x17 - 0x19 */
++	__le16 RTSDurFallback;	/* 0x1a */
++	u8 FragPLCPFallback[6];	/* 0x1b - 1d */
++	__le16 FragDurFallback;	/* 0x1e */
++	__le16 MModeLen;	/* 0x1f */
++	__le16 MModeFbrLen;	/* 0x20 */
++	__le16 TstampLow;	/* 0x21 */
++	__le16 TstampHigh;	/* 0x22 */
++	__le16 ABI_MimoAntSel;	/* 0x23 */
++	__le16 PreloadSize;	/* 0x24 */
++	__le16 AmpduSeqCtl;	/* 0x25 */
++	__le16 TxFrameID;	/* 0x26 */
++	__le16 TxStatus;	/* 0x27 */
++	__le16 MaxNMpdus;	/* 0x28 */
++	__le16 MaxABytes_MRT;	/* 0x29 */
++	__le16 MaxABytes_FBR;	/* 0x2a */
++	__le16 MinMBytes;	/* 0x2b */
++	u8 RTSPhyHeader[D11_PHY_HDR_LEN];	/* 0x2c - 0x2e */
++	struct ieee80211_rts rts_frame;	/* 0x2f - 0x36 */
++	u16 PAD;		/* 0x37 */
++} __packed;
++
++#define	D11_TXH_LEN		112	/* bytes */
++
++/* Frame Types */
++#define FT_CCK	0
++#define FT_OFDM	1
++#define FT_HT	2
++#define FT_N	3
++
++/*
++ * Position of MPDU inside A-MPDU; indicated with bits 10:9
++ * of MacTxControlLow
++ */
++#define TXC_AMPDU_SHIFT		9	/* shift for ampdu settings */
++#define TXC_AMPDU_NONE		0	/* Regular MPDU, not an A-MPDU */
++#define TXC_AMPDU_FIRST		1	/* first MPDU of an A-MPDU */
++#define TXC_AMPDU_MIDDLE	2	/* intermediate MPDU of an A-MPDU */
++#define TXC_AMPDU_LAST		3	/* last (or single) MPDU of an A-MPDU */
++
++/*== MacTxControlLow ==*/
++#define TXC_AMIC		0x8000
++#define	TXC_SENDCTS		0x0800
++#define TXC_AMPDU_MASK		0x0600
++#define TXC_BW_40		0x0100
++#define TXC_FREQBAND_5G		0x0080
++#define	TXC_DFCS		0x0040
++#define	TXC_IGNOREPMQ		0x0020
++#define	TXC_HWSEQ		0x0010
++#define	TXC_STARTMSDU		0x0008
++#define	TXC_SENDRTS		0x0004
++#define	TXC_LONGFRAME		0x0002
++#define	TXC_IMMEDACK		0x0001
++
++/*== MacTxControlHigh ==*/
++/* RTS fallback preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_FB_SHORT	0x8000
++/* RTS main rate preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_MAIN_SHORT	0x4000
++/*
++ * Main fallback rate preamble type
++ *   1 = SHORT for OFDM/GF for MIMO
++ *   0 = LONG for CCK/MM for MIMO
++ */
++#define TXC_PREAMBLE_DATA_FB_SHORT	0x2000
++
++/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
++/* use fallback rate for this AMPDU */
++#define	TXC_AMPDU_FBR		0x1000
++#define	TXC_SECKEY_MASK		0x0FF0
++#define	TXC_SECKEY_SHIFT	4
++/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
++#define	TXC_ALT_TXPWR		0x0008
++#define	TXC_SECTYPE_MASK	0x0007
++#define	TXC_SECTYPE_SHIFT	0
++
++/* Null delimiter for Fallback rate */
++#define AMPDU_FBR_NULL_DELIM  5	/* Location of Null delimiter count for AMPDU */
++
++/* PhyTxControl for Mimophy */
++#define	PHY_TXC_PWR_MASK	0xFC00
++#define	PHY_TXC_PWR_SHIFT	10
++#define	PHY_TXC_ANT_MASK	0x03C0	/* bit 6, 7, 8, 9 */
++#define	PHY_TXC_ANT_SHIFT	6
++#define	PHY_TXC_ANT_0_1		0x00C0	/* auto, last rx */
++#define	PHY_TXC_LCNPHY_ANT_LAST	0x0000
++#define	PHY_TXC_ANT_3		0x0200	/* virtual antenna 3 */
++#define	PHY_TXC_ANT_2		0x0100	/* virtual antenna 2 */
++#define	PHY_TXC_ANT_1		0x0080	/* virtual antenna 1 */
++#define	PHY_TXC_ANT_0		0x0040	/* virtual antenna 0 */
++#define	PHY_TXC_SHORT_HDR	0x0010
++
++#define	PHY_TXC_OLD_ANT_0	0x0000
++#define	PHY_TXC_OLD_ANT_1	0x0100
++#define	PHY_TXC_OLD_ANT_LAST	0x0300
++
++/* PhyTxControl_1 for Mimophy */
++#define PHY_TXC1_BW_MASK		0x0007
++#define PHY_TXC1_BW_10MHZ		0
++#define PHY_TXC1_BW_10MHZ_UP		1
++#define PHY_TXC1_BW_20MHZ		2
++#define PHY_TXC1_BW_20MHZ_UP		3
++#define PHY_TXC1_BW_40MHZ		4
++#define PHY_TXC1_BW_40MHZ_DUP		5
++#define PHY_TXC1_MODE_SHIFT		3
++#define PHY_TXC1_MODE_MASK		0x0038
++#define PHY_TXC1_MODE_SISO		0
++#define PHY_TXC1_MODE_CDD		1
++#define PHY_TXC1_MODE_STBC		2
++#define PHY_TXC1_MODE_SDM		3
++
++/* PhyTxControl for HTphy that are different from Mimophy */
++#define	PHY_TXC_HTANT_MASK		0x3fC0	/* bits 6-13 */
++
++/* XtraFrameTypes */
++#define XFTS_RTS_FT_SHIFT	2
++#define XFTS_FBRRTS_FT_SHIFT	4
++#define XFTS_CHANNEL_SHIFT	8
++
++/* Antenna diversity bit in ant_wr_settle */
++#define	PHY_AWS_ANTDIV		0x2000
++
++/* IFS ctl */
++#define IFS_USEEDCF	(1 << 2)
++
++/* IFS ctl1 */
++#define IFS_CTL1_EDCRS	(1 << 3)
++#define IFS_CTL1_EDCRS_20L (1 << 4)
++#define IFS_CTL1_EDCRS_40 (1 << 5)
++
++/* ABI_MimoAntSel */
++#define ABI_MAS_ADDR_BMP_IDX_MASK	0x0f00
++#define ABI_MAS_ADDR_BMP_IDX_SHIFT	8
++#define ABI_MAS_FBR_ANT_PTN_MASK	0x00f0
++#define ABI_MAS_FBR_ANT_PTN_SHIFT	4
++#define ABI_MAS_MRT_ANT_PTN_MASK	0x000f
++
++/* tx status packet */
++struct tx_status {
++	u16 framelen;
++	u16 PAD;
++	u16 frameid;
++	u16 status;
++	u16 lasttxtime;
++	u16 sequence;
++	u16 phyerr;
++	u16 ackphyrxsh;
++} __packed;
++
++#define	TXSTATUS_LEN	16
++
++/* status field bit definitions */
++#define	TX_STATUS_FRM_RTX_MASK	0xF000
++#define	TX_STATUS_FRM_RTX_SHIFT	12
++#define	TX_STATUS_RTS_RTX_MASK	0x0F00
++#define	TX_STATUS_RTS_RTX_SHIFT	8
++#define TX_STATUS_MASK		0x00FE
++#define	TX_STATUS_PMINDCTD	(1 << 7) /* PM mode indicated to AP */
++#define	TX_STATUS_INTERMEDIATE	(1 << 6) /* intermediate or 1st ampdu pkg */
++#define	TX_STATUS_AMPDU		(1 << 5) /* AMPDU status */
++#define TX_STATUS_SUPR_MASK	0x1C	 /* suppress status bits (4:2) */
++#define TX_STATUS_SUPR_SHIFT	2
++#define	TX_STATUS_ACK_RCV	(1 << 1) /* ACK received */
++#define	TX_STATUS_VALID		(1 << 0) /* Tx status valid */
++#define	TX_STATUS_NO_ACK	0
++
++/* suppress status reason codes */
++#define	TX_STATUS_SUPR_PMQ	(1 << 2) /* PMQ entry */
++#define	TX_STATUS_SUPR_FLUSH	(2 << 2) /* flush request */
++#define	TX_STATUS_SUPR_FRAG	(3 << 2) /* previous frag failure */
++#define	TX_STATUS_SUPR_TBTT	(3 << 2) /* SHARED: Probe resp supr for TBTT */
++#define	TX_STATUS_SUPR_BADCH	(4 << 2) /* channel mismatch */
++#define	TX_STATUS_SUPR_EXPTIME	(5 << 2) /* lifetime expiry */
++#define	TX_STATUS_SUPR_UF	(6 << 2) /* underflow */
++
++/* Unexpected tx status for rate update */
++#define TX_STATUS_UNEXP(status) \
++	((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
++	 TX_STATUS_UNEXP_AMPDU(status))
++
++/* Unexpected tx status for A-MPDU rate update */
++#define TX_STATUS_UNEXP_AMPDU(status) \
++	((((status) & TX_STATUS_SUPR_MASK) != 0) && \
++	 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
++
++#define TX_STATUS_BA_BMAP03_MASK	0xF000	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP03_SHIFT	12	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP47_MASK	0x001E	/* ba bitmap 4:7 in 2nd pkg */
++#define TX_STATUS_BA_BMAP47_SHIFT	3	/* ba bitmap 4:7 in 2nd pkg */
++
++/* RXE (Receive Engine) */
++
++/* RCM_CTL */
++#define	RCM_INC_MASK_H		0x0080
++#define	RCM_INC_MASK_L		0x0040
++#define	RCM_INC_DATA		0x0020
++#define	RCM_INDEX_MASK		0x001F
++#define	RCM_SIZE		15
++
++#define	RCM_MAC_OFFSET		0	/* current MAC address */
++#define	RCM_BSSID_OFFSET	3	/* current BSSID address */
++#define	RCM_F_BSSID_0_OFFSET	6	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_1_OFFSET	9	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_2_OFFSET	12	/* foreign BSS CFP tracking */
++
++#define RCM_WEP_TA0_OFFSET	16
++#define RCM_WEP_TA1_OFFSET	19
++#define RCM_WEP_TA2_OFFSET	22
++#define RCM_WEP_TA3_OFFSET	25
++
++/* PSM Block */
++
++/* psm_phy_hdr_param bits */
++#define MAC_PHY_RESET		1
++#define MAC_PHY_CLOCK_EN	2
++#define MAC_PHY_FORCE_CLK	4
++
++/* WEP Block */
++
++/* WEP_WKEY */
++#define	WKEY_START		(1 << 8)
++#define	WKEY_SEL_MASK		0x1F
++
++/* WEP data formats */
++
++/* the number of RCMTA entries */
++#define RCMTA_SIZE 50
++
++#define M_ADDR_BMP_BLK		(0x37e * 2)
++#define M_ADDR_BMP_BLK_SZ	12
++
++#define ADDR_BMP_RA		(1 << 0)	/* Receiver Address (RA) */
++#define ADDR_BMP_TA		(1 << 1)	/* Transmitter Address (TA) */
++#define ADDR_BMP_BSSID		(1 << 2)	/* BSSID */
++#define ADDR_BMP_AP		(1 << 3)	/* Infra-BSS Access Point */
++#define ADDR_BMP_STA		(1 << 4)	/* Infra-BSS Station */
++#define ADDR_BMP_RESERVED1	(1 << 5)
++#define ADDR_BMP_RESERVED2	(1 << 6)
++#define ADDR_BMP_RESERVED3	(1 << 7)
++#define ADDR_BMP_BSS_IDX_MASK	(3 << 8)	/* BSS control block index */
++#define ADDR_BMP_BSS_IDX_SHIFT	8
++
++#define	WSEC_MAX_RCMTA_KEYS	54
++
++/* max keys in M_TKMICKEYS_BLK */
++#define	WSEC_MAX_TKMIC_ENGINE_KEYS		12	/* 8 + 4 default */
++
++/* max RXE match registers */
++#define WSEC_MAX_RXE_KEYS	4
++
++/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
++/* SKL (Security Key Lookup) */
++#define	SKL_ALGO_MASK		0x0007
++#define	SKL_ALGO_SHIFT		0
++#define	SKL_KEYID_MASK		0x0008
++#define	SKL_KEYID_SHIFT		3
++#define	SKL_INDEX_MASK		0x03F0
++#define	SKL_INDEX_SHIFT		4
++#define	SKL_GRP_ALGO_MASK	0x1c00
++#define	SKL_GRP_ALGO_SHIFT	10
++
++/* additional bits defined for IBSS group key support */
++#define	SKL_IBSS_INDEX_MASK	0x01F0
++#define	SKL_IBSS_INDEX_SHIFT	4
++#define	SKL_IBSS_KEYID1_MASK	0x0600
++#define	SKL_IBSS_KEYID1_SHIFT	9
++#define	SKL_IBSS_KEYID2_MASK	0x1800
++#define	SKL_IBSS_KEYID2_SHIFT	11
++#define	SKL_IBSS_KEYALGO_MASK	0xE000
++#define	SKL_IBSS_KEYALGO_SHIFT	13
++
++#define	WSEC_MODE_OFF		0
++#define	WSEC_MODE_HW		1
++#define	WSEC_MODE_SW		2
++
++#define	WSEC_ALGO_OFF		0
++#define	WSEC_ALGO_WEP1		1
++#define	WSEC_ALGO_TKIP		2
++#define	WSEC_ALGO_AES		3
++#define	WSEC_ALGO_WEP128	4
++#define	WSEC_ALGO_AES_LEGACY	5
++#define	WSEC_ALGO_NALG		6
++
++#define	AES_MODE_NONE		0
++#define	AES_MODE_CCM		1
++
++/* WEP_CTL (Rev 0) */
++#define	WECR0_KEYREG_SHIFT	0
++#define	WECR0_KEYREG_MASK	0x7
++#define	WECR0_DECRYPT		(1 << 3)
++#define	WECR0_IVINLINE		(1 << 4)
++#define	WECR0_WEPALG_SHIFT	5
++#define	WECR0_WEPALG_MASK	(0x7 << 5)
++#define	WECR0_WKEYSEL_SHIFT	8
++#define	WECR0_WKEYSEL_MASK	(0x7 << 8)
++#define	WECR0_WKEYSTART		(1 << 11)
++#define	WECR0_WEPINIT		(1 << 14)
++#define	WECR0_ICVERR		(1 << 15)
++
++/* Frame template map byte offsets */
++#define	T_ACTS_TPL_BASE		(0)
++#define	T_NULL_TPL_BASE		(0xc * 2)
++#define	T_QNULL_TPL_BASE	(0x1c * 2)
++#define	T_RR_TPL_BASE		(0x2c * 2)
++#define	T_BCN0_TPL_BASE		(0x34 * 2)
++#define	T_PRS_TPL_BASE		(0x134 * 2)
++#define	T_BCN1_TPL_BASE		(0x234 * 2)
++#define T_TX_FIFO_TXRAM_BASE	(T_ACTS_TPL_BASE + \
++				 (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
++
++#define T_BA_TPL_BASE		T_QNULL_TPL_BASE /* template area for BA */
++
++#define T_RAM_ACCESS_SZ		4	/* template ram is 4 byte access only */
++
++/* Shared Mem byte offsets */
++
++/* Location where the ucode expects the corerev */
++#define	M_MACHW_VER		(0x00b * 2)
++
++/* Location where the ucode expects the MAC capabilities */
++#define	M_MACHW_CAP_L		(0x060 * 2)
++#define	M_MACHW_CAP_H	(0x061 * 2)
++
++/* WME shared memory */
++#define M_EDCF_STATUS_OFF	(0x007 * 2)
++#define M_TXF_CUR_INDEX		(0x018 * 2)
++#define M_EDCF_QINFO		(0x120 * 2)
++
++/* PS-mode related parameters */
++#define	M_DOT11_SLOT		(0x008 * 2)
++#define	M_DOT11_DTIMPERIOD	(0x009 * 2)
++#define	M_NOSLPZNATDTIM		(0x026 * 2)
++
++/* Beacon-related parameters */
++#define	M_BCN0_FRM_BYTESZ	(0x00c * 2)	/* Bcn 0 template length */
++#define	M_BCN1_FRM_BYTESZ	(0x00d * 2)	/* Bcn 1 template length */
++#define	M_BCN_TXTSF_OFFSET	(0x00e * 2)
++#define	M_TIMBPOS_INBEACON	(0x00f * 2)
++#define	M_SFRMTXCNTFBRTHSD	(0x022 * 2)
++#define	M_LFRMTXCNTFBRTHSD	(0x023 * 2)
++#define	M_BCN_PCTLWD		(0x02a * 2)
++#define M_BCN_LI		(0x05b * 2)	/* beacon listen interval */
++
++/* MAX Rx Frame len */
++#define M_MAXRXFRM_LEN		(0x010 * 2)
++
++/* ACK/CTS related params */
++#define	M_RSP_PCTLWD		(0x011 * 2)
++
++/* Hardware Power Control */
++#define M_TXPWR_N		(0x012 * 2)
++#define M_TXPWR_TARGET		(0x013 * 2)
++#define M_TXPWR_MAX		(0x014 * 2)
++#define M_TXPWR_CUR		(0x019 * 2)
++
++/* Rx-related parameters */
++#define	M_RX_PAD_DATA_OFFSET	(0x01a * 2)
++
++/* WEP Shared mem data */
++#define	M_SEC_DEFIVLOC		(0x01e * 2)
++#define	M_SEC_VALNUMSOFTMCHTA	(0x01f * 2)
++#define	M_PHYVER		(0x028 * 2)
++#define	M_PHYTYPE		(0x029 * 2)
++#define	M_SECRXKEYS_PTR		(0x02b * 2)
++#define	M_TKMICKEYS_PTR		(0x059 * 2)
++#define	M_SECKINDXALGO_BLK	(0x2ea * 2)
++#define M_SECKINDXALGO_BLK_SZ	54
++#define	M_SECPSMRXTAMCH_BLK	(0x2fa * 2)
++#define	M_TKIP_TSC_TTAK		(0x18c * 2)
++#define	D11_MAX_KEY_SIZE	16
++
++#define	M_MAX_ANTCNT		(0x02e * 2)	/* antenna swap threshold */
++
++/* Probe response related parameters */
++#define	M_SSIDLEN		(0x024 * 2)
++#define	M_PRB_RESP_FRM_LEN	(0x025 * 2)
++#define	M_PRS_MAXTIME		(0x03a * 2)
++#define	M_SSID			(0xb0 * 2)
++#define	M_CTXPRS_BLK		(0xc0 * 2)
++#define	C_CTX_PCTLWD_POS	(0x4 * 2)
++
++/* Delta between OFDM and CCK power in CCK power boost mode */
++#define M_OFDM_OFFSET		(0x027 * 2)
++
++/* TSSI for last 4 11b/g CCK packets transmitted */
++#define	M_B_TSSI_0		(0x02c * 2)
++#define	M_B_TSSI_1		(0x02d * 2)
++
++/* Host flags to turn on ucode options */
++#define	M_HOST_FLAGS1		(0x02f * 2)
++#define	M_HOST_FLAGS2		(0x030 * 2)
++#define	M_HOST_FLAGS3		(0x031 * 2)
++#define	M_HOST_FLAGS4		(0x03c * 2)
++#define	M_HOST_FLAGS5		(0x06a * 2)
++#define	M_HOST_FLAGS_SZ		16
++
++#define M_RADAR_REG		(0x033 * 2)
++
++/* TSSI for last 4 11a OFDM packets transmitted */
++#define	M_A_TSSI_0		(0x034 * 2)
++#define	M_A_TSSI_1		(0x035 * 2)
++
++/* noise interference measurement */
++#define M_NOISE_IF_COUNT	(0x034 * 2)
++#define M_NOISE_IF_TIMEOUT	(0x035 * 2)
++
++#define	M_RF_RX_SP_REG1		(0x036 * 2)
++
++/* TSSI for last 4 11g OFDM packets transmitted */
++#define	M_G_TSSI_0		(0x038 * 2)
++#define	M_G_TSSI_1		(0x039 * 2)
++
++/* Background noise measure */
++#define	M_JSSI_0		(0x44 * 2)
++#define	M_JSSI_1		(0x45 * 2)
++#define	M_JSSI_AUX		(0x46 * 2)
++
++#define	M_CUR_2050_RADIOCODE	(0x47 * 2)
++
++/* TX fifo sizes */
++#define M_FIFOSIZE0		(0x4c * 2)
++#define M_FIFOSIZE1		(0x4d * 2)
++#define M_FIFOSIZE2		(0x4e * 2)
++#define M_FIFOSIZE3		(0x4f * 2)
++#define D11_MAX_TX_FRMS		32	/* max frames allowed in tx fifo */
++
++/* Current channel number plus upper bits */
++#define M_CURCHANNEL		(0x50 * 2)
++#define D11_CURCHANNEL_5G	0x0100;
++#define D11_CURCHANNEL_40	0x0200;
++#define D11_CURCHANNEL_MAX	0x00FF;
++
++/* last posted frameid on the bcmc fifo */
++#define M_BCMC_FID		(0x54 * 2)
++#define INVALIDFID		0xffff
++
++/* extended beacon phyctl bytes for 11N */
++#define	M_BCN_PCTL1WD		(0x058 * 2)
++
++/* idle busy ratio to duty_cycle requirement  */
++#define M_TX_IDLE_BUSY_RATIO_X_16_CCK  (0x52 * 2)
++#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
++
++/* CW RSSI for LCNPHY */
++#define M_LCN_RSSI_0		0x1332
++#define M_LCN_RSSI_1		0x1338
++#define M_LCN_RSSI_2		0x133e
++#define M_LCN_RSSI_3		0x1344
++
++/* SNR for LCNPHY */
++#define M_LCN_SNR_A_0	0x1334
++#define M_LCN_SNR_B_0	0x1336
++
++#define M_LCN_SNR_A_1	0x133a
++#define M_LCN_SNR_B_1	0x133c
++
++#define M_LCN_SNR_A_2	0x1340
++#define M_LCN_SNR_B_2	0x1342
++
++#define M_LCN_SNR_A_3	0x1346
++#define M_LCN_SNR_B_3	0x1348
++
++#define M_LCN_LAST_RESET	(81*2)
++#define M_LCN_LAST_LOC	(63*2)
++#define M_LCNPHY_RESET_STATUS (4902)
++#define M_LCNPHY_DSC_TIME	(0x98d*2)
++#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
++#define M_LCNPHY_RESET_CNT	(0x98c*2)
++
++/* Rate table offsets */
++#define	M_RT_DIRMAP_A		(0xe0 * 2)
++#define	M_RT_BBRSMAP_A		(0xf0 * 2)
++#define	M_RT_DIRMAP_B		(0x100 * 2)
++#define	M_RT_BBRSMAP_B		(0x110 * 2)
++
++/* Rate table entry offsets */
++#define	M_RT_PRS_PLCP_POS	10
++#define	M_RT_PRS_DUR_POS	16
++#define	M_RT_OFDM_PCTL1_POS	18
++
++#define M_20IN40_IQ			(0x380 * 2)
++
++/* SHM locations where ucode stores the current power index */
++#define M_CURR_IDX1		(0x384 * 2)
++#define M_CURR_IDX2		(0x387 * 2)
++
++#define M_BSCALE_ANT0	(0x5e * 2)
++#define M_BSCALE_ANT1	(0x5f * 2)
++
++/* Antenna Diversity Testing */
++#define M_MIMO_ANTSEL_RXDFLT	(0x63 * 2)
++#define M_ANTSEL_CLKDIV	(0x61 * 2)
++#define M_MIMO_ANTSEL_TXDFLT	(0x64 * 2)
++
++#define M_MIMO_MAXSYM	(0x5d * 2)
++#define MIMO_MAXSYM_DEF		0x8000	/* 32k */
++#define MIMO_MAXSYM_MAX		0xffff	/* 64k */
++
++#define M_WATCHDOG_8TU		(0x1e * 2)
++#define WATCHDOG_8TU_DEF	5
++#define WATCHDOG_8TU_MAX	10
++
++/* Manufacturing Test Variables */
++/* PER test mode */
++#define M_PKTENG_CTRL		(0x6c * 2)
++/* IFS for TX mode */
++#define M_PKTENG_IFS		(0x6d * 2)
++/* Lower word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_LO	(0x6e * 2)
++/* Upper word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_HI	(0x6f * 2)
++
++/* Index variation in vbat ripple */
++#define M_LCN_PWR_IDX_MAX	(0x67 * 2) /* highest index read by ucode */
++#define M_LCN_PWR_IDX_MIN	(0x66 * 2) /* lowest index read by ucode */
++
++/* M_PKTENG_CTRL bit definitions */
++#define M_PKTENG_MODE_TX		0x0001
++#define M_PKTENG_MODE_TX_RIFS	        0x0004
++#define M_PKTENG_MODE_TX_CTS            0x0008
++#define M_PKTENG_MODE_RX		0x0002
++#define M_PKTENG_MODE_RX_WITH_ACK	0x0402
++#define M_PKTENG_MODE_MASK		0x0003
++/* TX frames indicated in the frmcnt reg */
++#define M_PKTENG_FRMCNT_VLD		0x0100
++
++/* Sample Collect parameters (bitmap and type) */
++/* Trigger bitmap for sample collect */
++#define M_SMPL_COL_BMP		(0x37d * 2)
++/* Sample collect type */
++#define M_SMPL_COL_CTL		(0x3b2 * 2)
++
++#define ANTSEL_CLKDIV_4MHZ	6
++#define MIMO_ANTSEL_BUSY	0x4000	/* bit 14 (busy) */
++#define MIMO_ANTSEL_SEL		0x8000	/* bit 15 write the value */
++#define MIMO_ANTSEL_WAIT	50	/* 50us wait */
++#define MIMO_ANTSEL_OVERRIDE	0x8000	/* flag */
++
++struct shm_acparams {
++	u16 txop;
++	u16 cwmin;
++	u16 cwmax;
++	u16 cwcur;
++	u16 aifs;
++	u16 bslots;
++	u16 reggap;
++	u16 status;
++	u16 rsvd[8];
++} __packed;
++#define M_EDCF_QLEN	(16 * 2)
++
++#define WME_STATUS_NEWAC	(1 << 8)
++
++/* M_HOST_FLAGS */
++#define MHFMAX		5	/* Number of valid hostflag half-word (u16) */
++#define MHF1		0	/* Hostflag 1 index */
++#define MHF2		1	/* Hostflag 2 index */
++#define MHF3		2	/* Hostflag 3 index */
++#define MHF4		3	/* Hostflag 4 index */
++#define MHF5		4	/* Hostflag 5 index */
++
++/* Flags in M_HOST_FLAGS */
++/* Enable ucode antenna diversity help */
++#define	MHF1_ANTDIV		0x0001
++/* Enable EDCF access control */
++#define	MHF1_EDCF		0x0100
++#define MHF1_IQSWAP_WAR		0x0200
++/* Disable Slow clock request, for corerev < 11 */
++#define	MHF1_FORCEFASTCLK	0x0400
++
++/* Flags in M_HOST_FLAGS2 */
++
++/* Flush BCMC FIFO immediately */
++#define MHF2_TXBCMC_NOW		0x0040
++/* Enable ucode/hw power control */
++#define MHF2_HWPWRCTL		0x0080
++#define MHF2_NPHY40MHZ_WAR	0x0800
++
++/* Flags in M_HOST_FLAGS3 */
++/* enabled mimo antenna selection */
++#define MHF3_ANTSEL_EN		0x0001
++/* antenna selection mode: 0: 2x3, 1: 2x4 */
++#define MHF3_ANTSEL_MODE	0x0002
++#define MHF3_RESERVED1		0x0004
++#define MHF3_RESERVED2		0x0008
++#define MHF3_NPHY_MLADV_WAR	0x0010
++
++/* Flags in M_HOST_FLAGS4 */
++/* force bphy Tx on core 0 (board level WAR) */
++#define MHF4_BPHY_TXCORE0	0x0080
++/* for 4313A0 FEM boards */
++#define MHF4_EXTPA_ENABLE	0x4000
++
++/* Flags in M_HOST_FLAGS5 */
++#define MHF5_4313_GPIOCTRL	0x0001
++#define MHF5_RESERVED1		0x0002
++#define MHF5_RESERVED2		0x0004
++/* Radio power setting for ucode */
++#define	M_RADIO_PWR		(0x32 * 2)
++
++/* phy noise recorded by ucode right after tx */
++#define	M_PHY_NOISE		(0x037 * 2)
++#define	PHY_NOISE_MASK		0x00ff
++
++/*
++ * Receive Frame Data Header for 802.11b DCF-only frames
++ *
++ * RxFrameSize: Actual byte length of the frame data received
++ * PAD: padding (not used)
++ * PhyRxStatus_0: PhyRxStatus 15:0
++ * PhyRxStatus_1: PhyRxStatus 31:16
++ * PhyRxStatus_2: PhyRxStatus 47:32
++ * PhyRxStatus_3: PhyRxStatus 63:48
++ * PhyRxStatus_4: PhyRxStatus 79:64
++ * PhyRxStatus_5: PhyRxStatus 95:80
++ * RxStatus1: MAC Rx Status
++ * RxStatus2: extended MAC Rx status
++ * RxTSFTime: RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY
++ * RxChan: gain code, channel radio code, and phy type
++ */
++struct d11rxhdr_le {
++	__le16 RxFrameSize;
++	u16 PAD;
++	__le16 PhyRxStatus_0;
++	__le16 PhyRxStatus_1;
++	__le16 PhyRxStatus_2;
++	__le16 PhyRxStatus_3;
++	__le16 PhyRxStatus_4;
++	__le16 PhyRxStatus_5;
++	__le16 RxStatus1;
++	__le16 RxStatus2;
++	__le16 RxTSFTime;
++	__le16 RxChan;
++} __packed;
++
++struct d11rxhdr {
++	u16 RxFrameSize;
++	u16 PAD;
++	u16 PhyRxStatus_0;
++	u16 PhyRxStatus_1;
++	u16 PhyRxStatus_2;
++	u16 PhyRxStatus_3;
++	u16 PhyRxStatus_4;
++	u16 PhyRxStatus_5;
++	u16 RxStatus1;
++	u16 RxStatus2;
++	u16 RxTSFTime;
++	u16 RxChan;
++} __packed;
++
++/* PhyRxStatus_0: */
++/* NPHY only: CCK, OFDM, preN, N */
++#define	PRXS0_FT_MASK		0x0003
++/* NPHY only: clip count adjustment steps by AGC */
++#define	PRXS0_CLIP_MASK		0x000C
++#define	PRXS0_CLIP_SHIFT	2
++/* PHY received a frame with unsupported rate */
++#define	PRXS0_UNSRATE		0x0010
++/* GPHY: rx ant, NPHY: upper sideband */
++#define	PRXS0_RXANT_UPSUBBAND	0x0020
++/* CCK frame only: lost crs during cck frame reception */
++#define	PRXS0_LCRS		0x0040
++/* Short Preamble */
++#define	PRXS0_SHORTH		0x0080
++/* PLCP violation */
++#define	PRXS0_PLCPFV		0x0100
++/* PLCP header integrity check failed */
++#define	PRXS0_PLCPHCF		0x0200
++/* legacy PHY gain control */
++#define	PRXS0_GAIN_CTL		0x4000
++/* NPHY: Antennas used for received frame, bitmask */
++#define PRXS0_ANTSEL_MASK	0xF000
++#define PRXS0_ANTSEL_SHIFT	0x12
++
++/* subfield PRXS0_FT_MASK */
++#define	PRXS0_CCK		0x0000
++/* valid only for G phy, use rxh->RxChan for A phy */
++#define	PRXS0_OFDM		0x0001
++#define	PRXS0_PREN		0x0002
++#define	PRXS0_STDN		0x0003
++
++/* subfield PRXS0_ANTSEL_MASK */
++#define PRXS0_ANTSEL_0		0x0	/* antenna 0 is used */
++#define PRXS0_ANTSEL_1		0x2	/* antenna 1 is used */
++#define PRXS0_ANTSEL_2		0x4	/* antenna 2 is used */
++#define PRXS0_ANTSEL_3		0x8	/* antenna 3 is used */
++
++/* PhyRxStatus_1: */
++#define	PRXS1_JSSI_MASK		0x00FF
++#define	PRXS1_JSSI_SHIFT	0
++#define	PRXS1_SQ_MASK		0xFF00
++#define	PRXS1_SQ_SHIFT		8
++
++/* nphy PhyRxStatus_1: */
++#define PRXS1_nphy_PWR0_MASK	0x00FF
++#define PRXS1_nphy_PWR1_MASK	0xFF00
++
++/* HTPHY Rx Status defines */
++/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
++#define PRXS0_BAND	        0x0400	/* 0 = 2.4G, 1 = 5G */
++#define PRXS0_RSVD	        0x0800	/* reserved; set to 0 */
++#define PRXS0_UNUSED	        0xF000	/* unused and not defined; set to 0 */
++
++/* htphy PhyRxStatus_1: */
++/* core enables for {3..0}, 0=disabled, 1=enabled */
++#define PRXS1_HTPHY_CORE_MASK	0x000F
++/* antenna configation */
++#define PRXS1_HTPHY_ANTCFG_MASK	0x00F0
++/* Mixmode PLCP Length low byte mask */
++#define PRXS1_HTPHY_MMPLCPLenL_MASK	0xFF00
++
++/* htphy PhyRxStatus_2: */
++/* Mixmode PLCP Length high byte maskw */
++#define PRXS2_HTPHY_MMPLCPLenH_MASK	0x000F
++/* Mixmode PLCP rate mask */
++#define PRXS2_HTPHY_MMPLCH_RATE_MASK	0x00F0
++/* Rx power on core 0 */
++#define PRXS2_HTPHY_RXPWR_ANT0	0xFF00
++
++/* htphy PhyRxStatus_3: */
++/* Rx power on core 1 */
++#define PRXS3_HTPHY_RXPWR_ANT1	0x00FF
++/* Rx power on core 2 */
++#define PRXS3_HTPHY_RXPWR_ANT2	0xFF00
++
++/* htphy PhyRxStatus_4: */
++/* Rx power on core 3 */
++#define PRXS4_HTPHY_RXPWR_ANT3	0x00FF
++/* Coarse frequency offset */
++#define PRXS4_HTPHY_CFO		0xFF00
++
++/* htphy PhyRxStatus_5: */
++/* Fine frequency offset */
++#define PRXS5_HTPHY_FFO	        0x00FF
++/* Advance Retard */
++#define PRXS5_HTPHY_AR	        0xFF00
++
++#define HTPHY_MMPLCPLen(rxs) \
++	((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
++	(((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
++/* Get Rx power on core 0 */
++#define HTPHY_RXPWR_ANT0(rxs) \
++	((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
++/* Get Rx power on core 1 */
++#define HTPHY_RXPWR_ANT1(rxs) \
++	(((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
++/* Get Rx power on core 2 */
++#define HTPHY_RXPWR_ANT2(rxs) \
++	((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
++
++/* ucode RxStatus1: */
++#define	RXS_BCNSENT		0x8000
++#define	RXS_SECKINDX_MASK	0x07e0
++#define	RXS_SECKINDX_SHIFT	5
++#define	RXS_DECERR		(1 << 4)
++#define	RXS_DECATMPT		(1 << 3)
++/* PAD bytes to make IP data 4 bytes aligned */
++#define	RXS_PBPRES		(1 << 2)
++#define	RXS_RESPFRAMETX		(1 << 1)
++#define	RXS_FCSERR		(1 << 0)
++
++/* ucode RxStatus2: */
++#define RXS_AMSDU_MASK		1
++#define	RXS_AGGTYPE_MASK	0x6
++#define	RXS_AGGTYPE_SHIFT	1
++#define	RXS_PHYRXST_VALID	(1 << 8)
++#define RXS_RXANT_MASK		0x3
++#define RXS_RXANT_SHIFT		12
++
++/* RxChan */
++#define RXS_CHAN_40		0x1000
++#define RXS_CHAN_5G		0x0800
++#define	RXS_CHAN_ID_MASK	0x07f8
++#define	RXS_CHAN_ID_SHIFT	3
++#define	RXS_CHAN_PHYTYPE_MASK	0x0007
++#define	RXS_CHAN_PHYTYPE_SHIFT	0
++
++/* Index of attenuations used during ucode power control. */
++#define M_PWRIND_BLKS	(0x184 * 2)
++#define M_PWRIND_MAP0	(M_PWRIND_BLKS + 0x0)
++#define M_PWRIND_MAP1	(M_PWRIND_BLKS + 0x2)
++#define M_PWRIND_MAP2	(M_PWRIND_BLKS + 0x4)
++#define M_PWRIND_MAP3	(M_PWRIND_BLKS + 0x6)
++/* M_PWRIND_MAP(core) macro */
++#define M_PWRIND_MAP(core)  (M_PWRIND_BLKS + ((core)<<1))
++
++/* PSM SHM variable offsets */
++#define	M_PSM_SOFT_REGS	0x0
++#define	M_BOM_REV_MAJOR	(M_PSM_SOFT_REGS + 0x0)
++#define	M_BOM_REV_MINOR	(M_PSM_SOFT_REGS + 0x2)
++#define	M_UCODE_DBGST	(M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
++#define	M_UCODE_MACSTAT	(M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
++
++#define M_AGING_THRSH	(0x3e * 2) /* max time waiting for medium before tx */
++#define	M_MBURST_SIZE	(0x40 * 2) /* max frames in a frameburst */
++#define	M_MBURST_TXOP	(0x41 * 2) /* max frameburst TXOP in unit of us */
++#define M_SYNTHPU_DLY	(0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
++#define	M_PRETBTT	(0x4b * 2)
++
++/* offset to the target txpwr */
++#define M_ALT_TXPWR_IDX		(M_PSM_SOFT_REGS + (0x3b * 2))
++#define M_PHY_TX_FLT_PTR	(M_PSM_SOFT_REGS + (0x3d * 2))
++#define M_CTS_DURATION		(M_PSM_SOFT_REGS + (0x5c * 2))
++#define M_LP_RCCAL_OVR		(M_PSM_SOFT_REGS + (0x6b * 2))
++
++/* PKTENG Rx Stats Block */
++#define M_RXSTATS_BLK_PTR	(M_PSM_SOFT_REGS + (0x65 * 2))
++
++/* ucode debug status codes */
++/* not valid really */
++#define	DBGST_INACTIVE		0
++/* after zeroing SHM, before suspending at init */
++#define	DBGST_INIT		1
++/* "normal" state */
++#define	DBGST_ACTIVE		2
++/* suspended */
++#define	DBGST_SUSPENDED		3
++/* asleep (PS mode) */
++#define	DBGST_ASLEEP		4
++
++/* Scratch Reg defs */
++enum _ePsmScratchPadRegDefinitions {
++	S_RSV0 = 0,
++	S_RSV1,
++	S_RSV2,
++
++	/* offset 0x03: scratch registers for Dot11-contants */
++	S_DOT11_CWMIN,		/* CW-minimum */
++	S_DOT11_CWMAX,		/* CW-maximum */
++	S_DOT11_CWCUR,		/* CW-current */
++	S_DOT11_SRC_LMT,	/* short retry count limit */
++	S_DOT11_LRC_LMT,	/* long retry count limit */
++	S_DOT11_DTIMCOUNT,	/* DTIM-count */
++
++	/* offset 0x09: Tx-side scratch registers */
++	S_SEQ_NUM,		/* hardware sequence number reg */
++	S_SEQ_NUM_FRAG,		/* seq num for frags (at the start of MSDU) */
++	S_FRMRETX_CNT,		/* frame retx count */
++	S_SSRC,			/* Station short retry count */
++	S_SLRC,			/* Station long retry count */
++	S_EXP_RSP,		/* Expected response frame */
++	S_OLD_BREM,		/* Remaining backoff ctr */
++	S_OLD_CWWIN,		/* saved-off CW-cur */
++	S_TXECTL,		/* TXE-Ctl word constructed in scr-pad */
++	S_CTXTST,		/* frm type-subtype as read from Tx-descr */
++
++	/* offset 0x13: Rx-side scratch registers */
++	S_RXTST,		/* Type and subtype in Rxframe */
++
++	/* Global state register */
++	S_STREG,		/* state storage actual bit maps below */
++
++	S_TXPWR_SUM,		/* Tx power control: accumulator */
++	S_TXPWR_ITER,		/* Tx power control: iteration */
++	S_RX_FRMTYPE,		/* Rate and PHY type for frames */
++	S_THIS_AGG,		/* Size of this AGG (A-MSDU) */
++
++	S_KEYINDX,
++	S_RXFRMLEN,		/* Receive MPDU length in bytes */
++
++	/* offset 0x1B: Receive TSF time stored in SCR */
++	S_RXTSFTMRVAL_WD3,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD2,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD1,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD0,	/* TSF value at the start of rx */
++	S_RXSSN,		/* Received start seq number for A-MPDU BA */
++	S_RXQOSFLD,		/* Rx-QoS field (if present) */
++
++	/* offset 0x21: Scratch pad regs used in microcode as temp storage */
++	S_TMP0,			/* stmp0 */
++	S_TMP1,			/* stmp1 */
++	S_TMP2,			/* stmp2 */
++	S_TMP3,			/* stmp3 */
++	S_TMP4,			/* stmp4 */
++	S_TMP5,			/* stmp5 */
++	S_PRQPENALTY_CTR,	/* Probe response queue penalty counter */
++	S_ANTCNT,		/* unsuccessful attempts on current ant. */
++	S_SYMBOL,		/* flag for possible symbol ctl frames */
++	S_RXTP,			/* rx frame type */
++	S_STREG2,		/* extra state storage */
++	S_STREG3,		/* even more extra state storage */
++	S_STREG4,		/* ... */
++	S_STREG5,		/* remember to initialize it to zero */
++
++	S_ADJPWR_IDX,
++	S_CUR_PTR,		/* Temp pointer for A-MPDU re-Tx SHM table */
++	S_REVID4,		/* 0x33 */
++	S_INDX,			/* 0x34 */
++	S_ADDR0,		/* 0x35 */
++	S_ADDR1,		/* 0x36 */
++	S_ADDR2,		/* 0x37 */
++	S_ADDR3,		/* 0x38 */
++	S_ADDR4,		/* 0x39 */
++	S_ADDR5,		/* 0x3A */
++	S_TMP6,			/* 0x3B */
++	S_KEYINDX_BU,		/* Backup for Key index */
++	S_MFGTEST_TMP0,		/* Temp regs used for RX test calculations */
++	S_RXESN,		/* Received end sequence number for A-MPDU BA */
++	S_STREG6,		/* 0x3F */
++};
++
++#define S_BEACON_INDX	S_OLD_BREM
++#define S_PRS_INDX	S_OLD_CWWIN
++#define S_PHYTYPE	S_SSRC
++#define S_PHYVER	S_SLRC
++
++/* IHR SLOW_CTRL values */
++#define SLOW_CTRL_PDE		(1 << 0)
++#define SLOW_CTRL_FD		(1 << 8)
++
++/* ucode mac statistic counters in shared memory */
++struct macstat {
++	u16 txallfrm;	/* 0x80 */
++	u16 txrtsfrm;	/* 0x82 */
++	u16 txctsfrm;	/* 0x84 */
++	u16 txackfrm;	/* 0x86 */
++	u16 txdnlfrm;	/* 0x88 */
++	u16 txbcnfrm;	/* 0x8a */
++	u16 txfunfl[8];	/* 0x8c - 0x9b */
++	u16 txtplunfl;	/* 0x9c */
++	u16 txphyerr;	/* 0x9e */
++	u16 pktengrxducast;	/* 0xa0 */
++	u16 pktengrxdmcast;	/* 0xa2 */
++	u16 rxfrmtoolong;	/* 0xa4 */
++	u16 rxfrmtooshrt;	/* 0xa6 */
++	u16 rxinvmachdr;	/* 0xa8 */
++	u16 rxbadfcs;	/* 0xaa */
++	u16 rxbadplcp;	/* 0xac */
++	u16 rxcrsglitch;	/* 0xae */
++	u16 rxstrt;		/* 0xb0 */
++	u16 rxdfrmucastmbss;	/* 0xb2 */
++	u16 rxmfrmucastmbss;	/* 0xb4 */
++	u16 rxcfrmucast;	/* 0xb6 */
++	u16 rxrtsucast;	/* 0xb8 */
++	u16 rxctsucast;	/* 0xba */
++	u16 rxackucast;	/* 0xbc */
++	u16 rxdfrmocast;	/* 0xbe */
++	u16 rxmfrmocast;	/* 0xc0 */
++	u16 rxcfrmocast;	/* 0xc2 */
++	u16 rxrtsocast;	/* 0xc4 */
++	u16 rxctsocast;	/* 0xc6 */
++	u16 rxdfrmmcast;	/* 0xc8 */
++	u16 rxmfrmmcast;	/* 0xca */
++	u16 rxcfrmmcast;	/* 0xcc */
++	u16 rxbeaconmbss;	/* 0xce */
++	u16 rxdfrmucastobss;	/* 0xd0 */
++	u16 rxbeaconobss;	/* 0xd2 */
++	u16 rxrsptmout;	/* 0xd4 */
++	u16 bcntxcancl;	/* 0xd6 */
++	u16 PAD;
++	u16 rxf0ovfl;	/* 0xda */
++	u16 rxf1ovfl;	/* 0xdc */
++	u16 rxf2ovfl;	/* 0xde */
++	u16 txsfovfl;	/* 0xe0 */
++	u16 pmqovfl;		/* 0xe2 */
++	u16 rxcgprqfrm;	/* 0xe4 */
++	u16 rxcgprsqovfl;	/* 0xe6 */
++	u16 txcgprsfail;	/* 0xe8 */
++	u16 txcgprssuc;	/* 0xea */
++	u16 prs_timeout;	/* 0xec */
++	u16 rxnack;
++	u16 frmscons;
++	u16 txnack;
++	u16 txglitch_nack;
++	u16 txburst;		/* 0xf6 # tx bursts */
++	u16 bphy_rxcrsglitch;	/* bphy rx crs glitch */
++	u16 phywatchdog;	/* 0xfa # of phy watchdog events */
++	u16 PAD;
++	u16 bphy_badplcp;	/* bphy bad plcp */
++};
++
++/* dot11 core-specific control flags */
++#define	SICF_PCLKE		0x0004	/* PHY clock enable */
++#define	SICF_PRST		0x0008	/* PHY reset */
++#define	SICF_MPCLKE		0x0010	/* MAC PHY clockcontrol enable */
++#define	SICF_FREF		0x0020	/* PLL FreqRefSelect */
++/* NOTE: the following bw bits only apply when the core is attached
++ * to a NPHY
++ */
++#define	SICF_BWMASK		0x00c0	/* phy clock mask (b6 & b7) */
++#define	SICF_BW40		0x0080	/* 40MHz BW (160MHz phyclk) */
++#define	SICF_BW20		0x0040	/* 20MHz BW (80MHz phyclk) */
++#define	SICF_BW10		0x0000	/* 10MHz BW (40MHz phyclk) */
++#define	SICF_GMODE		0x2000	/* gmode enable */
++
++/* dot11 core-specific status flags */
++#define	SISF_2G_PHY		0x0001	/* 2.4G capable phy */
++#define	SISF_5G_PHY		0x0002	/* 5G capable phy */
++#define	SISF_FCLKA		0x0004	/* FastClkAvailable */
++#define	SISF_DB_PHY		0x0008	/* Dualband phy */
++
++/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg === */
++/* radio and LPPHY regs are separated */
++
++#define	BPHY_REG_OFT_BASE	0x0
++/* offsets for indirect access to bphy registers */
++#define	BPHY_BB_CONFIG		0x01
++#define	BPHY_ADCBIAS		0x02
++#define	BPHY_ANACORE		0x03
++#define	BPHY_PHYCRSTH		0x06
++#define	BPHY_TEST		0x0a
++#define	BPHY_PA_TX_TO		0x10
++#define	BPHY_SYNTH_DC_TO	0x11
++#define	BPHY_PA_TX_TIME_UP	0x12
++#define	BPHY_RX_FLTR_TIME_UP	0x13
++#define	BPHY_TX_POWER_OVERRIDE	0x14
++#define	BPHY_RF_OVERRIDE	0x15
++#define	BPHY_RF_TR_LOOKUP1	0x16
++#define	BPHY_RF_TR_LOOKUP2	0x17
++#define	BPHY_COEFFS		0x18
++#define	BPHY_PLL_OUT		0x19
++#define	BPHY_REFRESH_MAIN	0x1a
++#define	BPHY_REFRESH_TO0	0x1b
++#define	BPHY_REFRESH_TO1	0x1c
++#define	BPHY_RSSI_TRESH		0x20
++#define	BPHY_IQ_TRESH_HH	0x21
++#define	BPHY_IQ_TRESH_H		0x22
++#define	BPHY_IQ_TRESH_L		0x23
++#define	BPHY_IQ_TRESH_LL	0x24
++#define	BPHY_GAIN		0x25
++#define	BPHY_LNA_GAIN_RANGE	0x26
++#define	BPHY_JSSI		0x27
++#define	BPHY_TSSI_CTL		0x28
++#define	BPHY_TSSI		0x29
++#define	BPHY_TR_LOSS_CTL	0x2a
++#define	BPHY_LO_LEAKAGE		0x2b
++#define	BPHY_LO_RSSI_ACC	0x2c
++#define	BPHY_LO_IQMAG_ACC	0x2d
++#define	BPHY_TX_DC_OFF1		0x2e
++#define	BPHY_TX_DC_OFF2		0x2f
++#define	BPHY_PEAK_CNT_THRESH	0x30
++#define	BPHY_FREQ_OFFSET	0x31
++#define	BPHY_DIVERSITY_CTL	0x32
++#define	BPHY_PEAK_ENERGY_LO	0x33
++#define	BPHY_PEAK_ENERGY_HI	0x34
++#define	BPHY_SYNC_CTL		0x35
++#define	BPHY_TX_PWR_CTRL	0x36
++#define BPHY_TX_EST_PWR		0x37
++#define	BPHY_STEP		0x38
++#define	BPHY_WARMUP		0x39
++#define	BPHY_LMS_CFF_READ	0x3a
++#define	BPHY_LMS_COEFF_I	0x3b
++#define	BPHY_LMS_COEFF_Q	0x3c
++#define	BPHY_SIG_POW		0x3d
++#define	BPHY_RFDC_CANCEL_CTL	0x3e
++#define	BPHY_HDR_TYPE		0x40
++#define	BPHY_SFD_TO		0x41
++#define	BPHY_SFD_CTL		0x42
++#define	BPHY_DEBUG		0x43
++#define	BPHY_RX_DELAY_COMP	0x44
++#define	BPHY_CRS_DROP_TO	0x45
++#define	BPHY_SHORT_SFD_NZEROS	0x46
++#define	BPHY_DSSS_COEFF1	0x48
++#define	BPHY_DSSS_COEFF2	0x49
++#define	BPHY_CCK_COEFF1		0x4a
++#define	BPHY_CCK_COEFF2		0x4b
++#define	BPHY_TR_CORR		0x4c
++#define	BPHY_ANGLE_SCALE	0x4d
++#define	BPHY_TX_PWR_BASE_IDX	0x4e
++#define	BPHY_OPTIONAL_MODES2	0x4f
++#define	BPHY_CCK_LMS_STEP	0x50
++#define	BPHY_BYPASS		0x51
++#define	BPHY_CCK_DELAY_LONG	0x52
++#define	BPHY_CCK_DELAY_SHORT	0x53
++#define	BPHY_PPROC_CHAN_DELAY	0x54
++#define	BPHY_DDFS_ENABLE	0x58
++#define	BPHY_PHASE_SCALE	0x59
++#define	BPHY_FREQ_CONTROL	0x5a
++#define	BPHY_LNA_GAIN_RANGE_10	0x5b
++#define	BPHY_LNA_GAIN_RANGE_32	0x5c
++#define	BPHY_OPTIONAL_MODES	0x5d
++#define	BPHY_RX_STATUS2		0x5e
++#define	BPHY_RX_STATUS3		0x5f
++#define	BPHY_DAC_CONTROL	0x60
++#define	BPHY_ANA11G_FILT_CTRL	0x62
++#define	BPHY_REFRESH_CTRL	0x64
++#define	BPHY_RF_OVERRIDE2	0x65
++#define	BPHY_SPUR_CANCEL_CTRL	0x66
++#define	BPHY_FINE_DIGIGAIN_CTRL	0x67
++#define	BPHY_RSSI_LUT		0x88
++#define	BPHY_RSSI_LUT_END	0xa7
++#define	BPHY_TSSI_LUT		0xa8
++#define	BPHY_TSSI_LUT_END	0xc7
++#define	BPHY_TSSI2PWR_LUT	0x380
++#define	BPHY_TSSI2PWR_LUT_END	0x39f
++#define	BPHY_LOCOMP_LUT		0x3a0
++#define	BPHY_LOCOMP_LUT_END	0x3bf
++#define	BPHY_TXGAIN_LUT		0x3c0
++#define	BPHY_TXGAIN_LUT_END	0x3ff
++
++/* Bits in BB_CONFIG: */
++#define	PHY_BBC_ANT_MASK	0x0180
++#define	PHY_BBC_ANT_SHIFT	7
++#define	BB_DARWIN		0x1000
++#define BBCFG_RESETCCA		0x4000
++#define BBCFG_RESETRX		0x8000
++
++/* Bits in phytest(0x0a): */
++#define	TST_DDFS		0x2000
++#define	TST_TXFILT1		0x0800
++#define	TST_UNSCRAM		0x0400
++#define	TST_CARR_SUPP		0x0200
++#define	TST_DC_COMP_LOOP	0x0100
++#define	TST_LOOPBACK		0x0080
++#define	TST_TXFILT0		0x0040
++#define	TST_TXTEST_ENABLE	0x0020
++#define	TST_TXTEST_RATE		0x0018
++#define	TST_TXTEST_PHASE	0x0007
++
++/* phytest txTestRate values */
++#define	TST_TXTEST_RATE_1MBPS	0
++#define	TST_TXTEST_RATE_2MBPS	1
++#define	TST_TXTEST_RATE_5_5MBPS	2
++#define	TST_TXTEST_RATE_11MBPS	3
++#define	TST_TXTEST_RATE_SHIFT	3
++
++#define SHM_BYT_CNT	0x2	/* IHR location */
++#define MAX_BYT_CNT	0x600	/* Maximum frame len */
++
++struct d11cnt {
++	u32 txfrag;
++	u32 txmulti;
++	u32 txfail;
++	u32 txretry;
++	u32 txretrie;
++	u32 rxdup;
++	u32 txrts;
++	u32 txnocts;
++	u32 txnoack;
++	u32 rxfrag;
++	u32 rxmulti;
++	u32 rxcrc;
++	u32 txfrmsnt;
++	u32 rxundec;
++};
++
++#endif				/* _BRCM_D11_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+new file mode 100644
+index 0000000..e898266
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+@@ -0,0 +1,1444 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pci.h>
++
++#include <brcmu_utils.h>
++#include <aiutils.h>
++#include "types.h"
++#include "dma.h"
++#include "soc.h"
++
++/*
++ * dma register field offset calculation
++ */
++#define DMA64REGOFFS(field)		offsetof(struct dma64regs, field)
++#define DMA64TXREGOFFS(di, field)	(di->d64txregbase + DMA64REGOFFS(field))
++#define DMA64RXREGOFFS(di, field)	(di->d64rxregbase + DMA64REGOFFS(field))
++
++/*
++ * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
++ * a contiguous 8kB physical address.
++ */
++#define D64RINGALIGN_BITS	13
++#define	D64MAXRINGSZ		(1 << D64RINGALIGN_BITS)
++#define	D64RINGALIGN		(1 << D64RINGALIGN_BITS)
++
++#define	D64MAXDD	(D64MAXRINGSZ / sizeof(struct dma64desc))
++
++/* transmit channel control */
++#define	D64_XC_XE		0x00000001	/* transmit enable */
++#define	D64_XC_SE		0x00000002	/* transmit suspend request */
++#define	D64_XC_LE		0x00000004	/* loopback enable */
++#define	D64_XC_FL		0x00000010	/* flush request */
++#define	D64_XC_PD		0x00000800	/* parity check disable */
++#define	D64_XC_AE		0x00030000	/* address extension bits */
++#define	D64_XC_AE_SHIFT		16
++
++/* transmit descriptor table pointer */
++#define	D64_XP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* transmit channel status */
++#define	D64_XS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_XS0_XS_MASK		0xf0000000	/* transmit state */
++#define	D64_XS0_XS_SHIFT		28
++#define	D64_XS0_XS_DISABLED	0x00000000	/* disabled */
++#define	D64_XS0_XS_ACTIVE	0x10000000	/* active */
++#define	D64_XS0_XS_IDLE		0x20000000	/* idle wait */
++#define	D64_XS0_XS_STOPPED	0x30000000	/* stopped */
++#define	D64_XS0_XS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_XS1_AD_MASK		0x00001fff	/* active descriptor */
++#define	D64_XS1_XE_MASK		0xf0000000	/* transmit errors */
++#define	D64_XS1_XE_SHIFT		28
++#define	D64_XS1_XE_NOERR	0x00000000	/* no error */
++#define	D64_XS1_XE_DPE		0x10000000	/* descriptor protocol error */
++#define	D64_XS1_XE_DFU		0x20000000	/* data fifo underrun */
++#define	D64_XS1_XE_DTE		0x30000000	/* data transfer error */
++#define	D64_XS1_XE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_XS1_XE_COREE	0x50000000	/* core error */
++
++/* receive channel control */
++/* receive enable */
++#define	D64_RC_RE		0x00000001
++/* receive frame offset */
++#define	D64_RC_RO_MASK		0x000000fe
++#define	D64_RC_RO_SHIFT		1
++/* direct fifo receive (pio) mode */
++#define	D64_RC_FM		0x00000100
++/* separate rx header descriptor enable */
++#define	D64_RC_SH		0x00000200
++/* overflow continue */
++#define	D64_RC_OC		0x00000400
++/* parity check disable */
++#define	D64_RC_PD		0x00000800
++/* address extension bits */
++#define	D64_RC_AE		0x00030000
++#define	D64_RC_AE_SHIFT		16
++
++/* flags for dma controller */
++/* partity enable */
++#define DMA_CTRL_PEN		(1 << 0)
++/* rx overflow continue */
++#define DMA_CTRL_ROC		(1 << 1)
++/* allow rx scatter to multiple descriptors */
++#define DMA_CTRL_RXMULTI	(1 << 2)
++/* Unframed Rx/Tx data */
++#define DMA_CTRL_UNFRAMED	(1 << 3)
++
++/* receive descriptor table pointer */
++#define	D64_RP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* receive channel status */
++#define	D64_RS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_RS0_RS_MASK		0xf0000000	/* receive state */
++#define	D64_RS0_RS_SHIFT		28
++#define	D64_RS0_RS_DISABLED	0x00000000	/* disabled */
++#define	D64_RS0_RS_ACTIVE	0x10000000	/* active */
++#define	D64_RS0_RS_IDLE		0x20000000	/* idle wait */
++#define	D64_RS0_RS_STOPPED	0x30000000	/* stopped */
++#define	D64_RS0_RS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_RS1_AD_MASK		0x0001ffff	/* active descriptor */
++#define	D64_RS1_RE_MASK		0xf0000000	/* receive errors */
++#define	D64_RS1_RE_SHIFT		28
++#define	D64_RS1_RE_NOERR	0x00000000	/* no error */
++#define	D64_RS1_RE_DPO		0x10000000	/* descriptor protocol error */
++#define	D64_RS1_RE_DFU		0x20000000	/* data fifo overflow */
++#define	D64_RS1_RE_DTE		0x30000000	/* data transfer error */
++#define	D64_RS1_RE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_RS1_RE_COREE	0x50000000	/* core error */
++
++/* fifoaddr */
++#define	D64_FA_OFF_MASK		0xffff	/* offset */
++#define	D64_FA_SEL_MASK		0xf0000	/* select */
++#define	D64_FA_SEL_SHIFT	16
++#define	D64_FA_SEL_XDD		0x00000	/* transmit dma data */
++#define	D64_FA_SEL_XDP		0x10000	/* transmit dma pointers */
++#define	D64_FA_SEL_RDD		0x40000	/* receive dma data */
++#define	D64_FA_SEL_RDP		0x50000	/* receive dma pointers */
++#define	D64_FA_SEL_XFD		0x80000	/* transmit fifo data */
++#define	D64_FA_SEL_XFP		0x90000	/* transmit fifo pointers */
++#define	D64_FA_SEL_RFD		0xc0000	/* receive fifo data */
++#define	D64_FA_SEL_RFP		0xd0000	/* receive fifo pointers */
++#define	D64_FA_SEL_RSD		0xe0000	/* receive frame status data */
++#define	D64_FA_SEL_RSP		0xf0000	/* receive frame status pointers */
++
++/* descriptor control flags 1 */
++#define D64_CTRL_COREFLAGS	0x0ff00000	/* core specific flags */
++#define	D64_CTRL1_EOT		((u32)1 << 28)	/* end of descriptor table */
++#define	D64_CTRL1_IOC		((u32)1 << 29)	/* interrupt on completion */
++#define	D64_CTRL1_EOF		((u32)1 << 30)	/* end of frame */
++#define	D64_CTRL1_SOF		((u32)1 << 31)	/* start of frame */
++
++/* descriptor control flags 2 */
++/* buffer byte count. real data len must <= 16KB */
++#define	D64_CTRL2_BC_MASK	0x00007fff
++/* address extension bits */
++#define	D64_CTRL2_AE		0x00030000
++#define	D64_CTRL2_AE_SHIFT	16
++/* parity bit */
++#define D64_CTRL2_PARITY	0x00040000
++
++/* control flags in the range [27:20] are core-specific and not defined here */
++#define	D64_CTRL_CORE_MASK	0x0ff00000
++
++#define D64_RX_FRM_STS_LEN	0x0000ffff	/* frame length mask */
++#define D64_RX_FRM_STS_OVFL	0x00800000	/* RxOverFlow */
++#define D64_RX_FRM_STS_DSCRCNT	0x0f000000  /* no. of descriptors used - 1 */
++#define D64_RX_FRM_STS_DATATYPE	0xf0000000	/* core-dependent data type */
++
++/*
++ * packet headroom necessary to accommodate the largest header
++ * in the system, (i.e TXOFF). By doing, we avoid the need to
++ * allocate an extra buffer for the header when bridging to WL.
++ * There is a compile time check in wlc.c which ensure that this
++ * value is at least as big as TXOFF. This value is used in
++ * dma_rxfill().
++ */
++
++#define BCMEXTRAHDROOM 172
++
++/* debug/trace */
++#ifdef DEBUG
++#define	DMA_ERROR(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 1)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#define	DMA_TRACE(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 2)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#else
++#define	DMA_ERROR(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#define	DMA_TRACE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	DMA_NONE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++
++#define	MAXNAMEL	8	/* 8 char names */
++
++/* macros to convert between byte offsets and indexes */
++#define	B2I(bytes, type)	((bytes) / sizeof(type))
++#define	I2B(index, type)	((index) * sizeof(type))
++
++#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
++#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
++
++#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
++#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
++
++/*
++ * DMA Descriptor
++ * Descriptors are only read by the hardware, never written back.
++ */
++struct dma64desc {
++	__le32 ctrl1;	/* misc control bits & bufcount */
++	__le32 ctrl2;	/* buffer count and address extension */
++	__le32 addrlow;	/* memory address of the date buffer, bits 31:0 */
++	__le32 addrhigh; /* memory address of the date buffer, bits 63:32 */
++};
++
++/* dma engine software state */
++struct dma_info {
++	struct dma_pub dma; /* exported structure */
++	uint *msg_level;	/* message level pointer */
++	char name[MAXNAMEL];	/* callers name for diag msgs */
++
++	struct bcma_device *core;
++	struct device *dmadev;
++
++	bool dma64;	/* this dma engine is operating in 64-bit mode */
++	bool addrext;	/* this dma engine supports DmaExtendedAddrChanges */
++
++	/* 64-bit dma tx engine registers */
++	uint d64txregbase;
++	/* 64-bit dma rx engine registers */
++	uint d64rxregbase;
++	/* pointer to dma64 tx descriptor ring */
++	struct dma64desc *txd64;
++	/* pointer to dma64 rx descriptor ring */
++	struct dma64desc *rxd64;
++
++	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
++
++	u16 ntxd;		/* # tx descriptors tunable */
++	u16 txin;		/* index of next descriptor to reclaim */
++	u16 txout;		/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **txp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t txdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t txdpaorig;
++	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
++	u32 txdalloc;	/* #bytes allocated for the ring */
++	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
++			 * is not just an index, it needs all 13 bits to be
++			 * an offset from the addr register.
++			 */
++
++	u16 nrxd;	/* # rx descriptors tunable */
++	u16 rxin;	/* index of next descriptor to reclaim */
++	u16 rxout;	/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **rxp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t rxdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t rxdpaorig;
++	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
++	u32 rxdalloc;	/* #bytes allocated for the ring */
++	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
++
++	/* tunables */
++	unsigned int rxbufsize;	/* rx buffer size in bytes, not including
++				 * the extra headroom
++				 */
++	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper
++				 * stack, e.g. some rx pkt buffers will be
++				 * bridged to tx side without byte copying.
++				 * The extra headroom needs to be large enough
++				 * to fit txheader needs. Some dongle driver may
++				 * not need it.
++				 */
++	uint nrxpost;		/* # rx buffers to keep posted */
++	unsigned int rxoffset;	/* rxcontrol offset */
++	/* add to get dma address of descriptor ring, low 32 bits */
++	uint ddoffsetlow;
++	/*   high 32 bits */
++	uint ddoffsethigh;
++	/* add to get dma address of data buffer, low 32 bits */
++	uint dataoffsetlow;
++	/*   high 32 bits */
++	uint dataoffsethigh;
++	/* descriptor base need to be aligned or not */
++	bool aligndesc_4k;
++};
++
++/*
++ * default dma message level (if input msg_level
++ * pointer is null in dma_attach())
++ */
++static uint dma_msg_level;
++
++/* Check for odd number of 1's */
++static u32 parity32(__le32 data)
++{
++	/* no swap needed for counting 1's */
++	u32 par_data = *(u32 *)&data;
++
++	par_data ^= par_data >> 16;
++	par_data ^= par_data >> 8;
++	par_data ^= par_data >> 4;
++	par_data ^= par_data >> 2;
++	par_data ^= par_data >> 1;
++
++	return par_data & 1;
++}
++
++static bool dma64_dd_parity(struct dma64desc *dd)
++{
++	return parity32(dd->addrlow ^ dd->addrhigh ^ dd->ctrl1 ^ dd->ctrl2);
++}
++
++/* descriptor bumping functions */
++
++static uint xxd(uint x, uint n)
++{
++	return x & (n - 1); /* faster than %, but n must be power of 2 */
++}
++
++static uint txd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->ntxd);
++}
++
++static uint rxd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->nrxd);
++}
++
++static uint nexttxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint prevtxd(struct dma_info *di, uint i)
++{
++	return txd(di, i - 1);
++}
++
++static uint nextrxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint ntxdactive(struct dma_info *di, uint h, uint t)
++{
++	return txd(di, t-h);
++}
++
++static uint nrxdactive(struct dma_info *di, uint h, uint t)
++{
++	return rxd(di, t-h);
++}
++
++static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
++{
++	uint dmactrlflags;
++
++	if (di == NULL) {
++		DMA_ERROR("NULL dma handle\n");
++		return 0;
++	}
++
++	dmactrlflags = di->dma.dmactrlflags;
++	dmactrlflags &= ~mask;
++	dmactrlflags |= flags;
++
++	/* If trying to enable parity, check if parity is actually supported */
++	if (dmactrlflags & DMA_CTRL_PEN) {
++		u32 control;
++
++		control = bcma_read32(di->core, DMA64TXREGOFFS(di, control));
++		bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++		      control | D64_XC_PD);
++		if (bcma_read32(di->core, DMA64TXREGOFFS(di, control)) &
++		    D64_XC_PD)
++			/* We *can* disable it so it is supported,
++			 * restore control register
++			 */
++			bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++				     control);
++		else
++			/* Not supported, don't allow it to be enabled */
++			dmactrlflags &= ~DMA_CTRL_PEN;
++	}
++
++	di->dma.dmactrlflags = dmactrlflags;
++
++	return dmactrlflags;
++}
++
++static bool _dma64_addrext(struct dma_info *di, uint ctrl_offset)
++{
++	u32 w;
++	bcma_set32(di->core, ctrl_offset, D64_XC_AE);
++	w = bcma_read32(di->core, ctrl_offset);
++	bcma_mask32(di->core, ctrl_offset, ~D64_XC_AE);
++	return (w & D64_XC_AE) == D64_XC_AE;
++}
++
++/*
++ * return true if this dma engine supports DmaExtendedAddrChanges,
++ * otherwise false
++ */
++static bool _dma_isaddrext(struct dma_info *di)
++{
++	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
++
++	/* not all tx or rx channel are available */
++	if (di->d64txregbase != 0) {
++		if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
++				  di->name);
++		return true;
++	} else if (di->d64rxregbase != 0) {
++		if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
++				  di->name);
++		return true;
++	}
++
++	return false;
++}
++
++static bool _dma_descriptor_align(struct dma_info *di)
++{
++	u32 addrl;
++
++	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
++	if (di->d64txregbase != 0) {
++		bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64TXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	} else if (di->d64rxregbase != 0) {
++		bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64RXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	}
++	return true;
++}
++
++/*
++ * Descriptor table must start at the DMA hardware dictated alignment, so
++ * allocated memory must be large enough to support this requirement.
++ */
++static void *dma_alloc_consistent(struct dma_info *di, uint size,
++				  u16 align_bits, uint *alloced,
++				  dma_addr_t *pap)
++{
++	if (align_bits) {
++		u16 align = (1 << align_bits);
++		if (!IS_ALIGNED(PAGE_SIZE, align))
++			size += align;
++		*alloced = size;
++	}
++	return dma_alloc_coherent(di->dmadev, size, pap, GFP_ATOMIC);
++}
++
++static
++u8 dma_align_sizetobits(uint size)
++{
++	u8 bitpos = 0;
++	while (size >>= 1)
++		bitpos++;
++	return bitpos;
++}
++
++/* This function ensures that the DMA descriptor ring will not get allocated
++ * across Page boundary. If the allocation is done across the page boundary
++ * at the first time, then it is freed and the allocation is done at
++ * descriptor ring size aligned location. This will ensure that the ring will
++ * not cross page boundary
++ */
++static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
++			   u16 *alignbits, uint *alloced,
++			   dma_addr_t *descpa)
++{
++	void *va;
++	u32 desc_strtaddr;
++	u32 alignbytes = 1 << *alignbits;
++
++	va = dma_alloc_consistent(di, size, *alignbits, alloced, descpa);
++
++	if (NULL == va)
++		return NULL;
++
++	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
++	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
++							& boundary)) {
++		*alignbits = dma_align_sizetobits(size);
++		dma_free_coherent(di->dmadev, size, va, *descpa);
++		va = dma_alloc_consistent(di, size, *alignbits,
++			alloced, descpa);
++	}
++	return va;
++}
++
++static bool dma64_alloc(struct dma_info *di, uint direction)
++{
++	u16 size;
++	uint ddlen;
++	void *va;
++	uint alloced = 0;
++	u16 align;
++	u16 align_bits;
++
++	ddlen = sizeof(struct dma64desc);
++
++	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++	align_bits = di->dmadesc_align;
++	align = (1 << align_bits);
++
++	if (direction == DMA_TX) {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->txdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->txd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
++		di->txdpa = di->txdpaorig + di->txdalign;
++		di->txdalloc = alloced;
++	} else {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->rxdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->rxd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
++		di->rxdpa = di->rxdpaorig + di->rxdalign;
++		di->rxdalloc = alloced;
++	}
++
++	return true;
++}
++
++static bool _dma_alloc(struct dma_info *di, uint direction)
++{
++	return dma64_alloc(di, direction);
++}
++
++struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++			   struct bcma_device *core,
++			   uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
++			   uint rxbufsize, int rxextheadroom,
++			   uint nrxpost, uint rxoffset, uint *msg_level)
++{
++	struct dma_info *di;
++	u8 rev = core->id.rev;
++	uint size;
++
++	/* allocate private info structure */
++	di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC);
++	if (di == NULL)
++		return NULL;
++
++	di->msg_level = msg_level ? msg_level : &dma_msg_level;
++
++
++	di->dma64 =
++		((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);
++
++	/* init dma reg info */
++	di->core = core;
++	di->d64txregbase = txregbase;
++	di->d64rxregbase = rxregbase;
++
++	/*
++	 * Default flags (which can be changed by the driver calling
++	 * dma_ctrlflags before enable): For backwards compatibility
++	 * both Rx Overflow Continue and Parity are DISABLED.
++	 */
++	_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
++
++	DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
++		  "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
++		  "txregbase %u rxregbase %u\n", name, "DMA64",
++		  di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
++		  rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
++
++	/* make a private copy of our callers name */
++	strncpy(di->name, name, MAXNAMEL);
++	di->name[MAXNAMEL - 1] = '\0';
++
++	di->dmadev = core->dma_dev;
++
++	/* save tunables */
++	di->ntxd = (u16) ntxd;
++	di->nrxd = (u16) nrxd;
++
++	/* the actual dma size doesn't include the extra headroom */
++	di->rxextrahdrroom =
++	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
++	if (rxbufsize > BCMEXTRAHDROOM)
++		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
++	else
++		di->rxbufsize = (u16) rxbufsize;
++
++	di->nrxpost = (u16) nrxpost;
++	di->rxoffset = (u8) rxoffset;
++
++	/*
++	 * figure out the DMA physical address offset for dd and data
++	 *     PCI/PCIE: they map silicon backplace address to zero
++	 *     based memory, need offset
++	 *     Other bus: use zero SI_BUS BIGENDIAN kludge: use sdram
++	 *     swapped region for data buffer, not descriptor
++	 */
++	di->ddoffsetlow = 0;
++	di->dataoffsetlow = 0;
++	/* add offset for pcie with DMA64 bus */
++	di->ddoffsetlow = 0;
++	di->ddoffsethigh = SI_PCIE_DMA_H32;
++	di->dataoffsetlow = di->ddoffsetlow;
++	di->dataoffsethigh = di->ddoffsethigh;
++	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
++	if ((core->id.id == SDIOD_CORE_ID)
++	    && ((rev > 0) && (rev <= 2)))
++		di->addrext = false;
++	else if ((core->id.id == I2S_CORE_ID) &&
++		 ((rev == 0) || (rev == 1)))
++		di->addrext = false;
++	else
++		di->addrext = _dma_isaddrext(di);
++
++	/* does the descriptor need to be aligned and if yes, on 4K/8K or not */
++	di->aligndesc_4k = _dma_descriptor_align(di);
++	if (di->aligndesc_4k) {
++		di->dmadesc_align = D64RINGALIGN_BITS;
++		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
++			/* for smaller dd table, HW relax alignment reqmnt */
++			di->dmadesc_align = D64RINGALIGN_BITS - 1;
++	} else {
++		di->dmadesc_align = 4;	/* 16 byte alignment */
++	}
++
++	DMA_NONE("DMA descriptor align_needed %d, align %d\n",
++		 di->aligndesc_4k, di->dmadesc_align);
++
++	/* allocate tx packet pointer vector */
++	if (ntxd) {
++		size = ntxd * sizeof(void *);
++		di->txp = kzalloc(size, GFP_ATOMIC);
++		if (di->txp == NULL)
++			goto fail;
++	}
++
++	/* allocate rx packet pointer vector */
++	if (nrxd) {
++		size = nrxd * sizeof(void *);
++		di->rxp = kzalloc(size, GFP_ATOMIC);
++		if (di->rxp == NULL)
++			goto fail;
++	}
++
++	/*
++	 * allocate transmit descriptor ring, only need ntxd descriptors
++	 * but it must be aligned
++	 */
++	if (ntxd) {
++		if (!_dma_alloc(di, DMA_TX))
++			goto fail;
++	}
++
++	/*
++	 * allocate receive descriptor ring, only need nrxd descriptors
++	 * but it must be aligned
++	 */
++	if (nrxd) {
++		if (!_dma_alloc(di, DMA_RX))
++			goto fail;
++	}
++
++	if ((di->ddoffsetlow != 0) && !di->addrext) {
++		if (di->txdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->txdpa);
++			goto fail;
++		}
++		if (di->rxdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->rxdpa);
++			goto fail;
++		}
++	}
++
++	DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
++		  di->ddoffsetlow, di->ddoffsethigh,
++		  di->dataoffsetlow, di->dataoffsethigh,
++		  di->addrext);
++
++	return (struct dma_pub *) di;
++
++ fail:
++	dma_detach((struct dma_pub *)di);
++	return NULL;
++}
++
++static inline void
++dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
++	     dma_addr_t pa, uint outidx, u32 *flags, u32 bufcount)
++{
++	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
++
++	/* PCI bus with big(>1G) physical address, use address extension */
++	if ((di->dataoffsetlow == 0) || !(pa & PCI32ADDR_HIGH)) {
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	} else {
++		/* address extension for 32-bit PCI */
++		u32 ae;
++
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	}
++	if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
++		if (dma64_dd_parity(&ddring[outidx]))
++			ddring[outidx].ctrl2 =
++			     cpu_to_le32(ctrl2 | D64_CTRL2_PARITY);
++	}
++}
++
++/* !! may be called with core in reset */
++void dma_detach(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	/* free dma descriptor rings */
++	if (di->txd64)
++		dma_free_coherent(di->dmadev, di->txdalloc,
++				  ((s8 *)di->txd64 - di->txdalign),
++				  (di->txdpaorig));
++	if (di->rxd64)
++		dma_free_coherent(di->dmadev, di->rxdalloc,
++				  ((s8 *)di->rxd64 - di->rxdalign),
++				  (di->rxdpaorig));
++
++	/* free packet pointer vectors */
++	kfree(di->txp);
++	kfree(di->rxp);
++
++	/* free our private info structure */
++	kfree(di);
++
++}
++
++/* initialize descriptor table base address */
++static void
++_dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
++{
++	if (!di->aligndesc_4k) {
++		if (direction == DMA_TX)
++			di->xmtptrbase = pa;
++		else
++			di->rcvptrbase = pa;
++	}
++
++	if ((di->ddoffsetlow == 0)
++	    || !(pa & PCI32ADDR_HIGH)) {
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		}
++	} else {
++		/* DMA64 32bits address extension */
++		u32 ae;
++
++		/* shift the high bit(s) from pa to ae */
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64TXREGOFFS(di, control),
++				       D64_XC_AE, (ae << D64_XC_AE_SHIFT));
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64RXREGOFFS(di, control),
++				       D64_RC_AE, (ae << D64_RC_AE_SHIFT));
++		}
++	}
++}
++
++static void _dma_rxenable(struct dma_info *di)
++{
++	uint dmactrlflags = di->dma.dmactrlflags;
++	u32 control;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	control = D64_RC_RE | (bcma_read32(di->core,
++					   DMA64RXREGOFFS(di, control)) &
++			       D64_RC_AE);
++
++	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_RC_PD;
++
++	if (dmactrlflags & DMA_CTRL_ROC)
++		control |= D64_RC_OC;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control),
++		((di->rxoffset << D64_RC_RO_SHIFT) | control));
++}
++
++void dma_rxinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return;
++
++	di->rxin = di->rxout = 0;
++
++	/* clear rx descriptor ring */
++	memset(di->rxd64, '\0', di->nrxd * sizeof(struct dma64desc));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++
++	_dma_rxenable(di);
++
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++}
++
++static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
++{
++	uint i, curr;
++	struct sk_buff *rxp;
++	dma_addr_t pa;
++
++	i = di->rxin;
++
++	/* return if no packets posted */
++	if (i == di->rxout)
++		return NULL;
++
++	curr =
++	    B2I(((bcma_read32(di->core,
++			      DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) -
++		 di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
++
++	/* ignore curr if forceall */
++	if (!forceall && (i == curr))
++		return NULL;
++
++	/* get the packet pointer that corresponds to the rx descriptor */
++	rxp = di->rxp[i];
++	di->rxp[i] = NULL;
++
++	pa = le32_to_cpu(di->rxd64[i].addrlow) - di->dataoffsetlow;
++
++	/* clear this packet from the descriptor ring */
++	dma_unmap_single(di->dmadev, pa, di->rxbufsize, DMA_FROM_DEVICE);
++
++	di->rxd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++	di->rxd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++	di->rxin = nextrxd(di, i);
++
++	return rxp;
++}
++
++static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall)
++{
++	if (di->nrxd == 0)
++		return NULL;
++
++	return dma64_getnextrxp(di, forceall);
++}
++
++/*
++ * !! rx entry routine
++ * returns the number packages in the next frame, or 0 if there are no more
++ *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is
++ *   supported with pkts chain
++ *   otherwise, it's treated as giant pkt and will be tossed.
++ *   The DMA scattering starts with normal DMA header, followed by first
++ *   buffer data. After it reaches the max size of buffer, the data continues
++ *   in next DMA descriptor buffer WITHOUT DMA header
++ */
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff_head dma_frames;
++	struct sk_buff *p, *next;
++	uint len;
++	uint pkt_len;
++	int resid = 0;
++	int pktcnt = 1;
++
++	skb_queue_head_init(&dma_frames);
++ next_frame:
++	p = _dma_getnextrxp(di, false);
++	if (p == NULL)
++		return 0;
++
++	len = le16_to_cpu(*(__le16 *) (p->data));
++	DMA_TRACE("%s: dma_rx len %d\n", di->name, len);
++	dma_spin_for_len(len, p);
++
++	/* set actual length */
++	pkt_len = min((di->rxoffset + len), di->rxbufsize);
++	__skb_trim(p, pkt_len);
++	skb_queue_tail(&dma_frames, p);
++	resid = len - (di->rxbufsize - di->rxoffset);
++
++	/* check for single or multi-buffer rx */
++	if (resid > 0) {
++		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
++			pkt_len = min_t(uint, resid, di->rxbufsize);
++			__skb_trim(p, pkt_len);
++			skb_queue_tail(&dma_frames, p);
++			resid -= di->rxbufsize;
++			pktcnt++;
++		}
++
++#ifdef DEBUG
++		if (resid > 0) {
++			uint cur;
++			cur =
++			    B2I(((bcma_read32(di->core,
++					      DMA64RXREGOFFS(di, status0)) &
++				  D64_RS0_CD_MASK) - di->rcvptrbase) &
++				D64_RS0_CD_MASK, struct dma64desc);
++			DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
++				   di->rxin, di->rxout, cur);
++		}
++#endif				/* DEBUG */
++
++		if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
++			DMA_ERROR("%s: bad frame length (%d)\n",
++				  di->name, len);
++			skb_queue_walk_safe(&dma_frames, p, next) {
++				skb_unlink(p, &dma_frames);
++				brcmu_pkt_buf_free_skb(p);
++			}
++			di->dma.rxgiants++;
++			pktcnt = 1;
++			goto next_frame;
++		}
++	}
++
++	skb_queue_splice_tail(&dma_frames, skb_list);
++	return pktcnt;
++}
++
++static bool dma64_rxidle(struct dma_info *di)
++{
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return true;
++
++	return ((bcma_read32(di->core,
++			     DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) ==
++		(bcma_read32(di->core, DMA64RXREGOFFS(di, ptr)) &
++		 D64_RS0_CD_MASK));
++}
++
++/*
++ * post receive buffers
++ *  return false is refill failed completely and ring is empty this will stall
++ *  the rx dma and user might want to call rxfill again asap. This unlikely
++ *  happens on memory-rich NIC, but often on memory-constrained dongle
++ */
++bool dma_rxfill(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++	u16 rxin, rxout;
++	u32 flags = 0;
++	uint n;
++	uint i;
++	dma_addr_t pa;
++	uint extra_offset = 0;
++	bool ring_empty;
++
++	ring_empty = false;
++
++	/*
++	 * Determine how many receive buffers we're lacking
++	 * from the full complement, allocate, initialize,
++	 * and post them, then update the chip rx lastdscr.
++	 */
++
++	rxin = di->rxin;
++	rxout = di->rxout;
++
++	n = di->nrxpost - nrxdactive(di, rxin, rxout);
++
++	DMA_TRACE("%s: post %d\n", di->name, n);
++
++	if (di->rxbufsize > BCMEXTRAHDROOM)
++		extra_offset = di->rxextrahdrroom;
++
++	for (i = 0; i < n; i++) {
++		/*
++		 * the di->rxbufsize doesn't include the extra headroom,
++		 * we need to add it to the size to be allocated
++		 */
++		p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
++
++		if (p == NULL) {
++			DMA_ERROR("%s: out of rxbufs\n", di->name);
++			if (i == 0 && dma64_rxidle(di)) {
++				DMA_ERROR("%s: ring is empty !\n", di->name);
++				ring_empty = true;
++			}
++			di->dma.rxnobuf++;
++			break;
++		}
++		/* reserve an extra headroom, if applicable */
++		if (extra_offset)
++			skb_pull(p, extra_offset);
++
++		/* Do a cached write instead of uncached write since DMA_MAP
++		 * will flush the cache.
++		 */
++		*(u32 *) (p->data) = 0;
++
++		pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
++				    DMA_FROM_DEVICE);
++
++		/* save the free packet pointer */
++		di->rxp[rxout] = p;
++
++		/* reset flags for each descriptor */
++		flags = 0;
++		if (rxout == (di->nrxd - 1))
++			flags = D64_CTRL1_EOT;
++
++		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
++			     di->rxbufsize);
++		rxout = nextrxd(di, rxout);
++	}
++
++	di->rxout = rxout;
++
++	/* update the chip lastdscr pointer */
++	bcma_write32(di->core, DMA64RXREGOFFS(di, ptr),
++	      di->rcvptrbase + I2B(rxout, struct dma64desc));
++
++	return ring_empty;
++}
++
++void dma_rxreclaim(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	while ((p = _dma_getnextrxp(di, true)))
++		brcmu_pkt_buf_free_skb(p);
++}
++
++void dma_counterreset(struct dma_pub *pub)
++{
++	/* reset all software counters */
++	pub->rxgiants = 0;
++	pub->rxnobuf = 0;
++	pub->txnobuf = 0;
++}
++
++/* get the address of the var in order to change later */
++unsigned long dma_getvar(struct dma_pub *pub, const char *name)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	if (!strcmp(name, "&txavail"))
++		return (unsigned long)&(di->dma.txavail);
++	return 0;
++}
++
++/* 64-bit DMA functions */
++
++void dma_txinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 control = D64_XC_XE;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	di->txin = di->txout = 0;
++	di->dma.txavail = di->ntxd - 1;
++
++	/* clear tx descriptor ring */
++	memset(di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc)));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++
++	if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_XC_PD;
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), control);
++
++	/* DMA engine with alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++}
++
++void dma_txsuspend(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++}
++
++void dma_txresume(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_mask32(di->core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
++}
++
++bool dma_txsuspended(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	return (di->ntxd == 0) ||
++	       ((bcma_read32(di->core,
++			     DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
++		D64_XC_SE);
++}
++
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->txin == di->txout)
++		return;
++
++	while ((p = dma_getnexttxp(pub, range))) {
++		/* For unframed data, we don't have any packets to free */
++		if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
++			brcmu_pkt_buf_free_skb(p);
++	}
++}
++
++bool dma_txreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->ntxd == 0)
++		return true;
++
++	/* suspend tx DMA first */
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) &&
++		  (status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED),
++		 10000);
++
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000);
++
++	/* wait for the last transaction to complete */
++	udelay(300);
++
++	return status == D64_XS0_XS_DISABLED;
++}
++
++bool dma_rxreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->nrxd == 0)
++		return true;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64RXREGOFFS(di, status0)) &
++		    D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000);
++
++	return status == D64_RS0_RS_DISABLED;
++}
++
++/*
++ * !! tx entry routine
++ * WARNING: call must check the return value for error.
++ *   the error(toss frames) could be fatal and cause many subsequent hard
++ *   to debug problems
++ */
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	unsigned char *data;
++	uint len;
++	u16 txout;
++	u32 flags = 0;
++	dma_addr_t pa;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	txout = di->txout;
++
++	/*
++	 * obtain and initialize transmit descriptor entry.
++	 */
++	data = p->data;
++	len = p->len;
++
++	/* no use to transmit a zero length packet */
++	if (len == 0)
++		return 0;
++
++	/* return nonzero if out of tx descriptors */
++	if (nexttxd(di, txout) == di->txin)
++		goto outoftxd;
++
++	/* get physical address of buffer start */
++	pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
++
++	/* With a DMA segment list, Descriptor table is filled
++	 * using the segment list instead of looping over
++	 * buffers in multi-chain DMA. Therefore, EOF for SGLIST
++	 * is when end of segment list is reached.
++	 */
++	flags = D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF;
++	if (txout == (di->ntxd - 1))
++		flags |= D64_CTRL1_EOT;
++
++	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
++
++	txout = nexttxd(di, txout);
++
++	/* save the packet */
++	di->txp[prevtxd(di, txout)] = p;
++
++	/* bump the tx descriptor index */
++	di->txout = txout;
++
++	/* kick the chip */
++	if (commit)
++		bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
++		      di->xmtptrbase + I2B(txout, struct dma64desc));
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return 0;
++
++ outoftxd:
++	DMA_ERROR("%s: out of txds !!!\n", di->name);
++	brcmu_pkt_buf_free_skb(p);
++	di->dma.txavail = 0;
++	di->dma.txnobuf++;
++	return -1;
++}
++
++/*
++ * Reclaim next completed txd (txds if using chained buffers) in the range
++ * specified and return associated packet.
++ * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be
++ * transmitted as noted by the hardware "CurrDescr" pointer.
++ * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be
++ * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
++ * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
++ * return associated packet regardless of the value of hardware pointers.
++ */
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u16 start, end, i;
++	u16 active_desc;
++	struct sk_buff *txp;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->ntxd == 0)
++		return NULL;
++
++	txp = NULL;
++
++	start = di->txin;
++	if (range == DMA_RANGE_ALL)
++		end = di->txout;
++	else {
++		end = (u16) (B2I(((bcma_read32(di->core,
++					       DMA64TXREGOFFS(di, status0)) &
++				   D64_XS0_CD_MASK) - di->xmtptrbase) &
++				 D64_XS0_CD_MASK, struct dma64desc));
++
++		if (range == DMA_RANGE_TRANSFERED) {
++			active_desc =
++				(u16)(bcma_read32(di->core,
++						  DMA64TXREGOFFS(di, status1)) &
++				      D64_XS1_AD_MASK);
++			active_desc =
++			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
++			active_desc = B2I(active_desc, struct dma64desc);
++			if (end != active_desc)
++				end = prevtxd(di, active_desc);
++		}
++	}
++
++	if ((start == 0) && (end > di->txout))
++		goto bogus;
++
++	for (i = start; i != end && !txp; i = nexttxd(di, i)) {
++		dma_addr_t pa;
++		uint size;
++
++		pa = le32_to_cpu(di->txd64[i].addrlow) - di->dataoffsetlow;
++
++		size =
++		    (le32_to_cpu(di->txd64[i].ctrl2) &
++		     D64_CTRL2_BC_MASK);
++
++		di->txd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++		di->txd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++		txp = di->txp[i];
++		di->txp[i] = NULL;
++
++		dma_unmap_single(di->dmadev, pa, size, DMA_TO_DEVICE);
++	}
++
++	di->txin = i;
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return txp;
++
++ bogus:
++	DMA_NONE("bogus curr: start %d end %d txout %d\n",
++		 start, end, di->txout);
++	return NULL;
++}
++
++/*
++ * Mac80211 initiated actions sometimes require packets in the DMA queue to be
++ * modified. The modified portion of the packet is not under control of the DMA
++ * engine. This function calls a caller-supplied function for each packet in
++ * the caller specified dma chain.
++ */
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a)
++{
++	struct dma_info *di = (struct dma_info *) dmah;
++	uint i =   di->txin;
++	uint end = di->txout;
++	struct sk_buff *skb;
++	struct ieee80211_tx_info *tx_info;
++
++	while (i != end) {
++		skb = (struct sk_buff *)di->txp[i];
++		if (skb != NULL) {
++			tx_info = (struct ieee80211_tx_info *)skb->cb;
++			(callback_fnc)(tx_info, arg_a);
++		}
++		i = nexttxd(di, i);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+new file mode 100644
+index 0000000..cc269ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+@@ -0,0 +1,122 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DMA_H_
++#define	_BRCM_DMA_H_
++
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include "types.h"		/* forward structure declarations */
++
++/* map/unmap direction */
++#define	DMA_TX	1		/* TX direction for DMA */
++#define	DMA_RX	2		/* RX direction for DMA */
++
++/* DMA structure:
++ *  support two DMA engines: 32 bits address or 64 bit addressing
++ *  basic DMA register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++
++/* 32 bits addressing */
++
++struct dma32diag {	/* diag access */
++	u32 fifoaddr;	/* diag address */
++	u32 fifodatalow;	/* low 32bits of data */
++	u32 fifodatahigh;	/* high 32bits of data */
++	u32 pad;		/* reserved */
++};
++
++/* 64 bits addressing */
++
++/* dma registers per channel(xmt or rcv) */
++struct dma64regs {
++	u32 control;	/* enable, et al */
++	u32 ptr;	/* last descriptor posted to chip */
++	u32 addrlow;	/* desc ring base address low 32-bits (8K aligned) */
++	u32 addrhigh;	/* desc ring base address bits 63:32 (8K aligned) */
++	u32 status0;	/* current descriptor, xmt state */
++	u32 status1;	/* active descriptor, xmt error */
++};
++
++/* range param for dma_getnexttxp() and dma_txreclaim */
++enum txd_range {
++	DMA_RANGE_ALL = 1,
++	DMA_RANGE_TRANSMITTED,
++	DMA_RANGE_TRANSFERED
++};
++
++/*
++ * Exported data structure (read-only)
++ */
++/* export structure */
++struct dma_pub {
++	uint txavail;		/* # free tx descriptors */
++	uint dmactrlflags;	/* dma control flags */
++
++	/* rx error counters */
++	uint rxgiants;		/* rx giant frames */
++	uint rxnobuf;		/* rx out of dma descriptors */
++	/* tx error counters */
++	uint txnobuf;		/* tx out of dma descriptors */
++};
++
++extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++				  struct bcma_device *d11core,
++				  uint txregbase, uint rxregbase,
++				  uint ntxd, uint nrxd,
++				  uint rxbufsize, int rxextheadroom,
++				  uint nrxpost, uint rxoffset, uint *msg_level);
++
++void dma_rxinit(struct dma_pub *pub);
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
++bool dma_rxfill(struct dma_pub *pub);
++bool dma_rxreset(struct dma_pub *pub);
++bool dma_txreset(struct dma_pub *pub);
++void dma_txinit(struct dma_pub *pub);
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
++void dma_txsuspend(struct dma_pub *pub);
++bool dma_txsuspended(struct dma_pub *pub);
++void dma_txresume(struct dma_pub *pub);
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
++void dma_rxreclaim(struct dma_pub *pub);
++void dma_detach(struct dma_pub *pub);
++unsigned long dma_getvar(struct dma_pub *pub, const char *name);
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
++void dma_counterreset(struct dma_pub *pub);
++
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a);
++
++/*
++ * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
++ * the packet length is not updated yet (by DMA) on the expected time.
++ * Workaround is to hold processor till DMA updates the length, and stay off
++ * the bus to allow DMA update the length in buffer
++ */
++static inline void dma_spin_for_len(uint len, struct sk_buff *head)
++{
++#if defined(CONFIG_BCM47XX)
++	if (!len) {
++		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
++			udelay(1);
++
++		*(u16 *) (head->data) = cpu_to_le16((u16) len);
++	}
++#endif				/* defined(CONFIG_BCM47XX) */
++}
++
++#endif				/* _BRCM_DMA_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+new file mode 100644
+index 0000000..21f7939
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -0,0 +1,1609 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define __UNDEF_NO_VERSION__
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/etherdevice.h>
++#include <linux/sched.h>
++#include <linux/firmware.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <net/mac80211.h>
++#include <defs.h>
++#include "phy/phy_int.h"
++#include "d11.h"
++#include "channel.h"
++#include "scb.h"
++#include "pub.h"
++#include "ucode_loader.h"
++#include "mac80211_if.h"
++#include "main.h"
++
++#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
++
++/* Flags we support */
++#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
++	FIF_ALLMULTI | \
++	FIF_FCSFAIL | \
++	FIF_CONTROL | \
++	FIF_OTHER_BSS | \
++	FIF_BCN_PRBRESP_PROMISC | \
++	FIF_PSPOLL)
++
++#define CHAN2GHZ(channel, freqency, chflags)  { \
++	.band = IEEE80211_BAND_2GHZ, \
++	.center_freq = (freqency), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 19, \
++}
++
++#define CHAN5GHZ(channel, chflags)  { \
++	.band = IEEE80211_BAND_5GHZ, \
++	.center_freq = 5000 + 5*(channel), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 21, \
++}
++
++#define RATE(rate100m, _flags) { \
++	.bitrate = (rate100m), \
++	.flags = (_flags), \
++	.hw_value = (rate100m / 5), \
++}
++
++struct firmware_hdr {
++	__le32 offset;
++	__le32 len;
++	__le32 idx;
++};
++
++static const char * const brcms_firmwares[MAX_FW_IMAGES] = {
++	"brcm/bcm43xx",
++	NULL
++};
++
++static int n_adapters_found;
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* recognized BCMA Core IDs */
++static struct bcma_device_id brcms_coreid_table[] = {
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
++	BCMA_CORETABLE_END
++};
++MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
++
++#ifdef DEBUG
++static int msglevel = 0xdeadbeef;
++module_param(msglevel, int, 0);
++#endif				/* DEBUG */
++
++static struct ieee80211_channel brcms_2ghz_chantable[] = {
++	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(5, 2432, 0),
++	CHAN2GHZ(6, 2437, 0),
++	CHAN2GHZ(7, 2442, 0),
++	CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(12, 2467,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(13, 2472,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(14, 2484,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
++	/* UNII-1 */
++	CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
++	/* UNII-2 */
++	CHAN5GHZ(52,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(56,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(60,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(64,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	/* MID */
++	CHAN5GHZ(100,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(104,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(108,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(112,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(116,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(120,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(124,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(128,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(132,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(136,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(140,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
++		 IEEE80211_CHAN_NO_HT40MINUS),
++	/* UNII-3 */
++	CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++/*
++ * The rate table is used for both 2.4G and 5G rates. The
++ * latter being a subset as it does not support CCK rates.
++ */
++static struct ieee80211_rate legacy_ratetable[] = {
++	RATE(10, 0),
++	RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(60, 0),
++	RATE(90, 0),
++	RATE(120, 0),
++	RATE(180, 0),
++	RATE(240, 0),
++	RATE(360, 0),
++	RATE(480, 0),
++	RATE(540, 0),
++};
++
++static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = brcms_2ghz_chantable,
++	.n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
++	.bitrates = legacy_ratetable,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable),
++	.ht_cap = {
++		   /* from include/linux/ieee80211.h */
++		   .cap = IEEE80211_HT_CAP_GRN_FLD |
++			  IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = brcms_5ghz_nphy_chantable,
++	.n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
++	.bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable) -
++			BRCMS_LEGACY_5G_RATE_OFFSET,
++	.ht_cap = {
++		   .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
++			  IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++/* flags the given rate in rateset as requested */
++static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
++{
++	u32 i;
++
++	for (i = 0; i < rs->count; i++) {
++		if (rate != (rs->rates[i] & 0x7f))
++			continue;
++
++		if (is_br)
++			rs->rates[i] |= BRCMS_RATE_FLAG;
++		else
++			rs->rates[i] &= BRCMS_RATE_MASK;
++		return;
++	}
++}
++
++static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	if (!wl->pub->up) {
++		wiphy_err(wl->wiphy, "ops->tx called while down\n");
++		kfree_skb(skb);
++		goto done;
++	}
++	brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++static int brcms_ops_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++	int err;
++
++	ieee80211_wake_queues(hw);
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_rfkill_set_hw_state(wl);
++	spin_unlock_bh(&wl->lock);
++	if (!blocked)
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++
++	spin_lock_bh(&wl->lock);
++	/* avoid acknowledging frames before a non-monitor device is added */
++	wl->mute_tx = true;
++
++	if (!wl->pub->up)
++		err = brcms_up(wl);
++	else
++		err = -ENODEV;
++	spin_unlock_bh(&wl->lock);
++
++	if (err != 0)
++		wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
++			  err);
++	return err;
++}
++
++static void brcms_ops_stop(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	int status;
++
++	ieee80211_stop_queues(hw);
++
++	if (wl->wlc == NULL)
++		return;
++
++	spin_lock_bh(&wl->lock);
++	status = brcms_c_chipmatch(wl->wlc->hw->vendorid,
++				   wl->wlc->hw->deviceid);
++	spin_unlock_bh(&wl->lock);
++	if (!status) {
++		wiphy_err(wl->wiphy,
++			  "wl: brcms_ops_stop: chipmatch failed\n");
++		return;
++	}
++
++	/* put driver in down state */
++	spin_lock_bh(&wl->lock);
++	brcms_down(wl);
++	spin_unlock_bh(&wl->lock);
++}
++
++static int
++brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++	struct brcms_info *wl = hw->priv;
++
++	/* Just STA for now */
++	if (vif->type != NL80211_IFTYPE_STATION) {
++		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
++			  " STA for now\n", __func__, vif->type);
++		return -EOPNOTSUPP;
++	}
++
++	wl->mute_tx = false;
++	brcms_c_mute(wl->wlc, false);
++
++	return 0;
++}
++
++static void
++brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++}
++
++static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
++{
++	struct ieee80211_conf *conf = &hw->conf;
++	struct brcms_info *wl = hw->priv;
++	int err = 0;
++	int new_int;
++	struct wiphy *wiphy = hw->wiphy;
++
++	spin_lock_bh(&wl->lock);
++	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
++		brcms_c_set_beacon_listen_interval(wl->wlc,
++						   conf->listen_interval);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
++		wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
++			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
++			  "true" : "false");
++	if (changed & IEEE80211_CONF_CHANGE_PS)
++		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
++			  __func__, conf->flags & IEEE80211_CONF_PS ?
++			  "true" : "false");
++
++	if (changed & IEEE80211_CONF_CHANGE_POWER) {
++		err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
++		if (err < 0) {
++			wiphy_err(wiphy, "%s: Error setting power_level\n",
++				  __func__);
++			goto config_out;
++		}
++		new_int = brcms_c_get_tx_power(wl->wlc);
++		if (new_int != conf->power_level)
++			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
++				  "\n", __func__, conf->power_level,
++				  new_int);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
++		if (conf->channel_type == NL80211_CHAN_HT20 ||
++		    conf->channel_type == NL80211_CHAN_NO_HT)
++			err = brcms_c_set_channel(wl->wlc,
++						  conf->channel->hw_value);
++		else
++			err = -ENOTSUPP;
++	}
++	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
++		err = brcms_c_set_rate_limit(wl->wlc,
++					     conf->short_frame_max_tx_count,
++					     conf->long_frame_max_tx_count);
++
++ config_out:
++	spin_unlock_bh(&wl->lock);
++	return err;
++}
++
++static void
++brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
++			struct ieee80211_vif *vif,
++			struct ieee80211_bss_conf *info, u32 changed)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	if (changed & BSS_CHANGED_ASSOC) {
++		/* association status changed (associated/disassociated)
++		 * also implies a change in the AID.
++		 */
++		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
++			  __func__, info->assoc ? "" : "dis");
++		spin_lock_bh(&wl->lock);
++		brcms_c_associate_upd(wl->wlc, info->assoc);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_ERP_SLOT) {
++		s8 val;
++
++		/* slot timing changed */
++		if (info->use_short_slot)
++			val = 1;
++		else
++			val = 0;
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_shortslot_override(wl->wlc, val);
++		spin_unlock_bh(&wl->lock);
++	}
++
++	if (changed & BSS_CHANGED_HT) {
++		/* 802.11n parameters changed */
++		u16 mode = info->ht_operation_mode;
++
++		spin_lock_bh(&wl->lock);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
++			mode & IEEE80211_HT_OP_MODE_PROTECTION);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
++			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
++			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BASIC_RATES) {
++		struct ieee80211_supported_band *bi;
++		u32 br_mask, i;
++		u16 rate;
++		struct brcm_rateset rs;
++		int error;
++
++		/* retrieve the current rates */
++		spin_lock_bh(&wl->lock);
++		brcms_c_get_current_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++
++		br_mask = info->basic_rates;
++		bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
++		for (i = 0; i < bi->n_bitrates; i++) {
++			/* convert to internal rate value */
++			rate = (bi->bitrates[i].bitrate << 1) / 10;
++
++			/* set/clear basic rate flag */
++			brcms_set_basic_rate(&rs, rate, br_mask & 1);
++			br_mask >>= 1;
++		}
++
++		/* update the rate set */
++		spin_lock_bh(&wl->lock);
++		error = brcms_c_set_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++		if (error)
++			wiphy_err(wiphy, "changing basic rates failed: %d\n",
++				  error);
++	}
++	if (changed & BSS_CHANGED_BEACON_INT) {
++		/* Beacon interval changed */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BSSID) {
++		/* BSSID changed, for whatever reason (IBSS and managed mode) */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BEACON)
++		/* Beacon data changed, retrieve new beacon (beaconing modes) */
++		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
++
++	if (changed & BSS_CHANGED_BEACON_ENABLED) {
++		/* Beaconing should be enabled/disabled (beaconing modes) */
++		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
++			  info->enable_beacon ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_CQM) {
++		/* Connection quality monitor config changed */
++		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
++			  " (implement)\n", __func__, info->cqm_rssi_thold,
++			  info->cqm_rssi_hyst);
++	}
++
++	if (changed & BSS_CHANGED_IBSS) {
++		/* IBSS join status changed */
++		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
++			  info->ibss_joined ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_ARP_FILTER) {
++		/* Hardware ARP filter address list or state changed */
++		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
++			  " (implement)\n", __func__, info->arp_filter_enabled ?
++			  "true" : "false", info->arp_addr_cnt);
++	}
++
++	if (changed & BSS_CHANGED_QOS) {
++		/*
++		 * QoS for this association was enabled/disabled.
++		 * Note that it is only ever disabled for station mode.
++		 */
++		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
++			  info->qos ? "true" : "false");
++	}
++	return;
++}
++
++static void
++brcms_ops_configure_filter(struct ieee80211_hw *hw,
++			unsigned int changed_flags,
++			unsigned int *total_flags, u64 multicast)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	changed_flags &= MAC_FILTERS;
++	*total_flags &= MAC_FILTERS;
++
++	if (changed_flags & FIF_PROMISC_IN_BSS)
++		wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
++	if (changed_flags & FIF_ALLMULTI)
++		wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
++	if (changed_flags & FIF_FCSFAIL)
++		wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
++	if (changed_flags & FIF_CONTROL)
++		wiphy_dbg(wiphy, "FIF_CONTROL\n");
++	if (changed_flags & FIF_OTHER_BSS)
++		wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
++	if (changed_flags & FIF_PSPOLL)
++		wiphy_dbg(wiphy, "FIF_PSPOLL\n");
++	if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
++		wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_mac_promisc(wl->wlc, *total_flags);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_start(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_stop(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static int
++brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
++		  const struct ieee80211_tx_queue_params *params)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_wme_setparams(wl->wlc, queue, params, true);
++	spin_unlock_bh(&wl->lock);
++
++	return 0;
++}
++
++static int
++brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++	       struct ieee80211_sta *sta)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++
++	brcms_c_init_scb(scb);
++
++	wl->pub->global_ampdu = &(scb->scb_ampdu);
++	wl->pub->global_ampdu->scb = scb;
++	wl->pub->global_ampdu->max_pdu = 16;
++
++	/*
++	 * minstrel_ht initiates addBA on our behalf by calling
++	 * ieee80211_start_tx_ba_session()
++	 */
++	return 0;
++}
++
++static int
++brcms_ops_ampdu_action(struct ieee80211_hw *hw,
++		    struct ieee80211_vif *vif,
++		    enum ieee80211_ampdu_mlme_action action,
++		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
++		    u8 buf_size)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++	int status;
++
++	if (WARN_ON(scb->magic != SCB_MAGIC))
++		return -EIDRM;
++	switch (action) {
++	case IEEE80211_AMPDU_RX_START:
++		break;
++	case IEEE80211_AMPDU_RX_STOP:
++		break;
++	case IEEE80211_AMPDU_TX_START:
++		spin_lock_bh(&wl->lock);
++		status = brcms_c_aggregatable(wl->wlc, tid);
++		spin_unlock_bh(&wl->lock);
++		if (!status) {
++			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
++				  tid);
++			return -EINVAL;
++		}
++		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++
++	case IEEE80211_AMPDU_TX_STOP:
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_flush(wl->wlc, sta, tid);
++		spin_unlock_bh(&wl->lock);
++		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++	case IEEE80211_AMPDU_TX_OPERATIONAL:
++		/*
++		 * BA window size from ADDBA response ('buf_size') defines how
++		 * many outstanding MPDUs are allowed for the BA stream by
++		 * recipient and traffic class. 'ampdu_factor' gives maximum
++		 * AMPDU size.
++		 */
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
++			(1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
++			 sta->ht_cap.ampdu_factor)) - 1);
++		spin_unlock_bh(&wl->lock);
++		/* Power save wakeup */
++		break;
++	default:
++		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
++			  __func__);
++	}
++
++	return 0;
++}
++
++static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_c_check_radio_disabled(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++}
++
++static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
++{
++	struct brcms_info *wl = hw->priv;
++
++	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
++
++	/* wait for packet queue and dma fifos to run empty */
++	spin_lock_bh(&wl->lock);
++	brcms_c_wait_for_tx_completion(wl->wlc, drop);
++	spin_unlock_bh(&wl->lock);
++}
++
++static const struct ieee80211_ops brcms_ops = {
++	.tx = brcms_ops_tx,
++	.start = brcms_ops_start,
++	.stop = brcms_ops_stop,
++	.add_interface = brcms_ops_add_interface,
++	.remove_interface = brcms_ops_remove_interface,
++	.config = brcms_ops_config,
++	.bss_info_changed = brcms_ops_bss_info_changed,
++	.configure_filter = brcms_ops_configure_filter,
++	.sw_scan_start = brcms_ops_sw_scan_start,
++	.sw_scan_complete = brcms_ops_sw_scan_complete,
++	.conf_tx = brcms_ops_conf_tx,
++	.sta_add = brcms_ops_sta_add,
++	.ampdu_action = brcms_ops_ampdu_action,
++	.rfkill_poll = brcms_ops_rfkill_poll,
++	.flush = brcms_ops_flush,
++};
++
++/*
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
++{
++	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
++}
++
++void brcms_dpc(unsigned long data)
++{
++	struct brcms_info *wl;
++
++	wl = (struct brcms_info *) data;
++
++	spin_lock_bh(&wl->lock);
++
++	/* call the common second level interrupt handler */
++	if (wl->pub->up) {
++		if (wl->resched) {
++			unsigned long flags;
++
++			spin_lock_irqsave(&wl->isr_lock, flags);
++			brcms_c_intrsupd(wl->wlc);
++			spin_unlock_irqrestore(&wl->isr_lock, flags);
++		}
++
++		wl->resched = brcms_c_dpc(wl->wlc, true);
++	}
++
++	/* brcms_c_dpc() may bring the driver down */
++	if (!wl->pub->up)
++		goto done;
++
++	/* re-schedule dpc */
++	if (wl->resched)
++		tasklet_schedule(&wl->tasklet);
++	else
++		/* re-enable interrupts */
++		brcms_intrson(wl);
++
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
++{
++	int status;
++	struct device *device = &pdev->dev;
++	char fw_name[100];
++	int i;
++
++	memset(&wl->fw, 0, sizeof(struct brcms_firmware));
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		if (brcms_firmwares[i] == NULL)
++			break;
++		sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		wl->fw.hdr_num_entries[i] =
++		    wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
++	}
++	wl->fw.fw_cnt = i;
++	return brcms_ucode_data_init(wl, &wl->ucode);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static void brcms_release_fw(struct brcms_info *wl)
++{
++	int i;
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		release_firmware(wl->fw.fw_bin[i]);
++		release_firmware(wl->fw.fw_hdr[i]);
++	}
++}
++
++/**
++ * This function frees the WL per-device resources.
++ *
++ * This function frees resources owned by the WL device pointed to
++ * by the wl parameter.
++ *
++ * precondition: can both be called locked and unlocked
++ *
++ */
++static void brcms_free(struct brcms_info *wl)
++{
++	struct brcms_timer *t, *next;
++
++	/* free ucode data */
++	if (wl->fw.fw_cnt)
++		brcms_ucode_data_free(&wl->ucode);
++	if (wl->irq)
++		free_irq(wl->irq, wl);
++
++	/* kill dpc */
++	tasklet_kill(&wl->tasklet);
++
++	if (wl->pub)
++		brcms_c_module_unregister(wl->pub, "linux", wl);
++
++	/* free common resources */
++	if (wl->wlc) {
++		brcms_c_detach(wl->wlc);
++		wl->wlc = NULL;
++		wl->pub = NULL;
++	}
++
++	/* virtual interface deletion is deferred so we cannot spinwait */
++
++	/* wait for all pending callbacks to complete */
++	while (atomic_read(&wl->callbacks) > 0)
++		schedule();
++
++	/* free timers */
++	for (t = wl->timers; t; t = next) {
++		next = t->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++	}
++}
++
++/*
++* called from both kernel as from this kernel module (error flow on attach)
++* precondition: perimeter lock is not acquired.
++*/
++static void brcms_remove(struct bcma_device *pdev)
++{
++	struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
++	struct brcms_info *wl = hw->priv;
++
++	if (wl->wlc) {
++		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++		ieee80211_unregister_hw(hw);
++	}
++
++	brcms_free(wl);
++
++	bcma_set_drvdata(pdev, NULL);
++	ieee80211_free_hw(hw);
++}
++
++static irqreturn_t brcms_isr(int irq, void *dev_id)
++{
++	struct brcms_info *wl;
++	bool ours, wantdpc;
++
++	wl = (struct brcms_info *) dev_id;
++
++	spin_lock(&wl->isr_lock);
++
++	/* call common first level interrupt handler */
++	ours = brcms_c_isr(wl->wlc, &wantdpc);
++	if (ours) {
++		/* if more to do... */
++		if (wantdpc) {
++
++			/* ...and call the second level interrupt handler */
++			/* schedule dpc */
++			tasklet_schedule(&wl->tasklet);
++		}
++	}
++
++	spin_unlock(&wl->isr_lock);
++
++	return IRQ_RETVAL(ours);
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_rate_init(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	struct brcms_c_info *wlc = wl->wlc;
++	struct ieee80211_supported_band *band;
++	int has_5g = 0;
++	u16 phy_type;
++
++	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
++	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
++
++	phy_type = brcms_c_get_phy_type(wl->wlc, 0);
++	if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++		band = &wlc->bandstate[BAND_2G_INDEX]->band;
++		*band = brcms_band_2GHz_nphy_template;
++		if (phy_type == PHY_TYPE_LCN) {
++			/* Single stream */
++			band->ht_cap.mcs.rx_mask[1] = 0;
++			band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
++		}
++		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
++	} else {
++		return -EPERM;
++	}
++
++	/* Assume all bands use the same phy.  True for 11n devices. */
++	if (wl->pub->_nbands > 1) {
++		has_5g++;
++		if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++			band = &wlc->bandstate[BAND_5G_INDEX]->band;
++			*band = brcms_band_5GHz_nphy_template;
++			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
++		} else {
++			return -EPERM;
++		}
++	}
++	return 0;
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_init(struct ieee80211_hw *hw)
++{
++	hw->flags = IEEE80211_HW_SIGNAL_DBM
++	    /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
++	    | IEEE80211_HW_REPORTS_TX_ACK_STATUS
++	    | IEEE80211_HW_AMPDU_AGGREGATION;
++
++	hw->extra_tx_headroom = brcms_c_get_header_len();
++	hw->queues = N_TX_QUEUES;
++	hw->max_rates = 2;	/* Primary rate and 1 fallback rate */
++
++	/* channel change time is dependent on chip and band  */
++	hw->channel_change_time = 7 * 1000;
++	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
++
++	hw->rate_control_algorithm = "minstrel_ht";
++
++	hw->sta_data_size = 0;
++	return ieee_hw_rate_init(hw);
++}
++
++/**
++ * attach to the WL device.
++ *
++ * Attach to the WL device identified by vendor and device parameters.
++ * regs is a host accessible memory address pointing to WL device registers.
++ *
++ * brcms_attach is not defined as static because in the case where no bus
++ * is defined, wl_attach will never be called, and thus, gcc will issue
++ * a warning that this function is defined but not used if we declare
++ * it as static.
++ *
++ *
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static struct brcms_info *brcms_attach(struct bcma_device *pdev)
++{
++	struct brcms_info *wl = NULL;
++	int unit, err;
++	struct ieee80211_hw *hw;
++	u8 perm[ETH_ALEN];
++
++	unit = n_adapters_found;
++	err = 0;
++
++	if (unit < 0)
++		return NULL;
++
++	/* allocate private info */
++	hw = bcma_get_drvdata(pdev);
++	if (hw != NULL)
++		wl = hw->priv;
++	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
++		return NULL;
++	wl->wiphy = hw->wiphy;
++
++	atomic_set(&wl->callbacks, 0);
++
++	/* setup the bottom half handler */
++	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
++
++	spin_lock_init(&wl->lock);
++	spin_lock_init(&wl->isr_lock);
++
++	/* prepare ucode */
++	if (brcms_request_fw(wl, pdev) < 0) {
++		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
++			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
++		brcms_release_fw(wl);
++		brcms_remove(pdev);
++		return NULL;
++	}
++
++	/* common load-time initialization */
++	wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
++	brcms_release_fw(wl);
++	if (!wl->wlc) {
++		wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
++			  KBUILD_MODNAME, err);
++		goto fail;
++	}
++	wl->pub = brcms_c_pub(wl->wlc);
++
++	wl->pub->ieee_hw = hw;
++
++	/* register our interrupt handler */
++	if (request_irq(pdev->irq, brcms_isr,
++			IRQF_SHARED, KBUILD_MODNAME, wl)) {
++		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
++		goto fail;
++	}
++	wl->irq = pdev->irq;
++
++	/* register module */
++	brcms_c_module_register(wl->pub, "linux", wl, NULL);
++
++	if (ieee_hw_init(hw)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
++			  __func__);
++		goto fail;
++	}
++
++	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
++	if (WARN_ON(!is_valid_ether_addr(perm)))
++		goto fail;
++	SET_IEEE80211_PERM_ADDR(hw, perm);
++
++	err = ieee80211_register_hw(hw);
++	if (err)
++		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
++			  "%d\n", __func__, err);
++
++	if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode))
++		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
++			  __func__, err);
++
++	n_adapters_found++;
++	return wl;
++
++fail:
++	brcms_free(wl);
++	return NULL;
++}
++
++
++
++/**
++ * determines if a device is a WL device, and if so, attaches it.
++ *
++ * This function determines if a device pointed to by pdev is a WL device,
++ * and if so, performs a brcms_attach() on it.
++ *
++ * Perimeter lock is initialized in the course of this function.
++ */
++static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
++		 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
++		 pdev->irq);
++
++	if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
++	    (pdev->id.id != BCMA_CORE_80211))
++		return -ENODEV;
++
++	hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
++	if (!hw) {
++		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
++		return -ENOMEM;
++	}
++
++	SET_IEEE80211_DEV(hw, &pdev->dev);
++
++	bcma_set_drvdata(pdev, hw);
++
++	memset(hw->priv, 0, sizeof(*wl));
++
++	wl = brcms_attach(pdev);
++	if (!wl) {
++		pr_err("%s: brcms_attach failed!\n", __func__);
++		return -ENODEV;
++	}
++	return 0;
++}
++
++static int brcms_suspend(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	hw = bcma_get_drvdata(pdev);
++	wl = hw->priv;
++	if (!wl) {
++		pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
++		       __func__);
++		return -ENODEV;
++	}
++
++	/* only need to flag hw is down for proper resume */
++	spin_lock_bh(&wl->lock);
++	wl->pub->hw_up = false;
++	spin_unlock_bh(&wl->lock);
++
++	pr_debug("brcms_suspend ok\n");
++
++	return 0;
++}
++
++static int brcms_resume(struct bcma_device *pdev)
++{
++	pr_debug("brcms_resume ok\n");
++	return 0;
++}
++
++static struct bcma_driver brcms_bcma_driver = {
++	.name     = KBUILD_MODNAME,
++	.probe    = brcms_bcma_probe,
++	.suspend  = brcms_suspend,
++	.resume   = brcms_resume,
++	.remove   = __devexit_p(brcms_remove),
++	.id_table = brcms_coreid_table,
++};
++
++/**
++ * This is the main entry point for the brcmsmac driver.
++ *
++ * This function is scheduled upon module initialization and
++ * does the driver registration, which result in brcms_bcma_probe()
++ * call resulting in the driver bringup.
++ */
++static void brcms_driver_init(struct work_struct *work)
++{
++	int error;
++
++	error = bcma_driver_register(&brcms_bcma_driver);
++	if (error)
++		pr_err("%s: register returned %d\n", __func__, error);
++}
++
++static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
++
++static int __init brcms_module_init(void)
++{
++#ifdef DEBUG
++	if (msglevel != 0xdeadbeef)
++		brcm_msg_level = msglevel;
++#endif
++	if (!schedule_work(&brcms_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++/**
++ * This function unloads the brcmsmac driver from the system.
++ *
++ * This function unconditionally unloads the brcmsmac driver module from the
++ * system.
++ *
++ */
++static void __exit brcms_module_exit(void)
++{
++	cancel_work_sync(&brcms_driver_work);
++	bcma_driver_unregister(&brcms_bcma_driver);
++}
++
++module_init(brcms_module_init);
++module_exit(brcms_module_exit);
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++			 bool state, int prio)
++{
++	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_init(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_reset(wl);
++	brcms_c_init(wl->wlc, wl->mute_tx);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++uint brcms_reset(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_c_reset(wl->wlc);
++
++	/* dpc will not be rescheduled */
++	wl->resched = false;
++
++	return 0;
++}
++
++void brcms_fatal_error(struct brcms_info *wl)
++{
++	wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n",
++		  wl->wlc->pub->unit);
++	brcms_reset(wl);
++	ieee80211_restart_hw(wl->pub->ieee_hw);
++}
++
++/*
++ * These are interrupt on/off entry points. Disable interrupts
++ * during interrupt state transition.
++ */
++void brcms_intrson(struct brcms_info *wl)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrson(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++u32 brcms_intrsoff(struct brcms_info *wl)
++{
++	unsigned long flags;
++	u32 status;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	status = brcms_c_intrsoff(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++	return status;
++}
++
++void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrsrestore(wl->wlc, macintmask);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_up(struct brcms_info *wl)
++{
++	int error = 0;
++
++	if (wl->pub->up)
++		return 0;
++
++	error = brcms_c_up(wl->wlc);
++
++	return error;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_down(struct brcms_info *wl)
++{
++	uint callbacks, ret_val = 0;
++
++	/* call common down function */
++	ret_val = brcms_c_down(wl->wlc);
++	callbacks = atomic_read(&wl->callbacks) - ret_val;
++
++	/* wait for down callbacks to complete */
++	spin_unlock_bh(&wl->lock);
++
++	/* For HIGH_only driver, it's important to actually schedule other work,
++	 * not just spin wait since everything runs at schedule level
++	 */
++	SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
++
++	spin_lock_bh(&wl->lock);
++}
++
++/*
++* precondition: perimeter lock is not acquired
++ */
++static void _brcms_timer(struct work_struct *work)
++{
++	struct brcms_timer *t = container_of(work, struct brcms_timer,
++					     dly_wrk.work);
++
++	spin_lock_bh(&t->wl->lock);
++
++	if (t->set) {
++		if (t->periodic) {
++			atomic_inc(&t->wl->callbacks);
++			ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
++						     &t->dly_wrk,
++						     msecs_to_jiffies(t->ms));
++		} else {
++			t->set = false;
++		}
++
++		t->fn(t->arg);
++	}
++
++	atomic_dec(&t->wl->callbacks);
++
++	spin_unlock_bh(&t->wl->lock);
++}
++
++/*
++ * Adds a timer to the list. Caller supplies a timer function.
++ * Is called from wlc.
++ *
++ * precondition: perimeter lock has been acquired
++ */
++struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				     void (*fn) (void *arg),
++				     void *arg, const char *name)
++{
++	struct brcms_timer *t;
++
++	t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
++	if (!t)
++		return NULL;
++
++	INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
++	t->wl = wl;
++	t->fn = fn;
++	t->arg = arg;
++	t->next = wl->timers;
++	wl->timers = t;
++
++#ifdef DEBUG
++	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
++	if (t->name)
++		strcpy(t->name, name);
++#endif
++
++	return t;
++}
++
++/*
++ * adds only the kernel timer since it's going to be more accurate
++ * as well as it's easier to make it periodic
++ *
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
++{
++	struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
++
++#ifdef DEBUG
++	if (t->set)
++		wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
++			  __func__, t->name, periodic);
++#endif
++	t->ms = ms;
++	t->periodic = (bool) periodic;
++	t->set = true;
++
++	atomic_inc(&t->wl->callbacks);
++
++	ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
++}
++
++/*
++ * return true if timer successfully deleted, false if still pending
++ *
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_del_timer(struct brcms_timer *t)
++{
++	if (t->set) {
++		t->set = false;
++		if (!cancel_delayed_work(&t->dly_wrk))
++			return false;
++
++		atomic_dec(&t->wl->callbacks);
++	}
++
++	return true;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_free_timer(struct brcms_timer *t)
++{
++	struct brcms_info *wl = t->wl;
++	struct brcms_timer *tmp;
++
++	/* delete the timer in case it is active */
++	brcms_del_timer(t);
++
++	if (wl->timers == t) {
++		wl->timers = wl->timers->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++		return;
++
++	}
++
++	tmp = wl->timers;
++	while (tmp) {
++		if (tmp->next == t) {
++			tmp->next = t->next;
++#ifdef DEBUG
++			kfree(t->name);
++#endif
++			kfree(t);
++			return;
++		}
++		tmp = tmp->next;
++	}
++
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			u32 len = le32_to_cpu(hdr->len);
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				*pbuf = kmemdup(pdata, len, GFP_ATOMIC);
++				if (*pbuf == NULL)
++					goto fail;
++
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
++		  idx);
++	*pbuf = NULL;
++fail:
++	return -ENODATA;
++}
++
++/*
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				if (le32_to_cpu(hdr->len) != 4) {
++					wiphy_err(wl->wiphy,
++						  "ERROR: fw hdr len\n");
++					return -ENOMSG;
++				}
++				*n_bytes = le32_to_cpu(*((__le32 *) pdata));
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
++	return -ENOMSG;
++}
++
++/*
++ * precondition: can both be called locked and unlocked
++ */
++void brcms_ucode_free_buf(void *p)
++{
++	kfree(p);
++}
++
++/*
++ * checks validity of all firmware images loaded from user space
++ *
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_check_firmwares(struct brcms_info *wl)
++{
++	int i;
++	int entry;
++	int rc = 0;
++	const struct firmware *fw;
++	const struct firmware *fw_hdr;
++	struct firmware_hdr *ucode_hdr;
++	for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
++		fw =  wl->fw.fw_bin[i];
++		fw_hdr = wl->fw.fw_hdr[i];
++		if (fw == NULL && fw_hdr == NULL) {
++			break;
++		} else if (fw == NULL || fw_hdr == NULL) {
++			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
++				  __func__);
++			rc = -EBADF;
++		} else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
++			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
++				"size %zu/%zu\n", __func__, fw_hdr->size,
++				sizeof(struct firmware_hdr));
++			rc = -EBADF;
++		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
++			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
++				  "%zu\n", __func__, fw->size);
++			rc = -EBADF;
++		} else {
++			/* check if ucode section overruns firmware image */
++			ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
++			for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
++			     !rc; entry++, ucode_hdr++) {
++				if (le32_to_cpu(ucode_hdr->offset) +
++				    le32_to_cpu(ucode_hdr->len) >
++				    fw->size) {
++					wiphy_err(wl->wiphy,
++						  "%s: conflicting bin/hdr\n",
++						  __func__);
++					rc = -EBADF;
++				}
++			}
++		}
++	}
++	if (rc == 0 && wl->fw.fw_cnt != i) {
++		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
++			wl->fw.fw_cnt);
++		rc = -EBADF;
++	}
++	return rc;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
++{
++	bool blocked = brcms_c_check_radio_disabled(wl->wlc);
++
++	spin_unlock_bh(&wl->lock);
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++	if (blocked)
++		wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
++	spin_lock_bh(&wl->lock);
++	return blocked;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_msleep(struct brcms_info *wl, uint ms)
++{
++	spin_unlock_bh(&wl->lock);
++	msleep(ms);
++	spin_lock_bh(&wl->lock);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+new file mode 100644
+index 0000000..9358bd5
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAC80211_IF_H_
++#define _BRCM_MAC80211_IF_H_
++
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++
++#include "ucode_loader.h"
++/*
++ * Starting index for 5G rates in the
++ * legacy rate table.
++ */
++#define BRCMS_LEGACY_5G_RATE_OFFSET	4
++
++/* softmac ioctl definitions */
++#define BRCMS_SET_SHORTSLOT_OVERRIDE		146
++
++struct brcms_timer {
++	struct delayed_work dly_wrk;
++	struct brcms_info *wl;
++	void (*fn) (void *);	/* function called upon expiration */
++	void *arg;		/* fixed argument provided to called function */
++	uint ms;
++	bool periodic;
++	bool set;		/* indicates if timer is active */
++	struct brcms_timer *next;	/* for freeing on unload */
++#ifdef DEBUG
++	char *name;		/* Description of the timer */
++#endif
++};
++
++struct brcms_if {
++	uint subunit;		/* WDS/BSS unit */
++	struct pci_dev *pci_dev;
++};
++
++#define MAX_FW_IMAGES		4
++struct brcms_firmware {
++	u32 fw_cnt;
++	const struct firmware *fw_bin[MAX_FW_IMAGES];
++	const struct firmware *fw_hdr[MAX_FW_IMAGES];
++	u32 hdr_num_entries[MAX_FW_IMAGES];
++};
++
++struct brcms_info {
++	struct brcms_pub *pub;		/* pointer to public wlc state */
++	struct brcms_c_info *wlc;	/* pointer to private common data */
++	u32 magic;
++
++	int irq;
++
++	spinlock_t lock;	/* per-device perimeter lock */
++	spinlock_t isr_lock;	/* per-device ISR synchronization lock */
++
++
++	/* timer related fields */
++	atomic_t callbacks;	/* # outstanding callback functions */
++	struct brcms_timer *timers;	/* timer cleanup queue */
++
++	struct tasklet_struct tasklet;	/* dpc tasklet */
++	bool resched;		/* dpc needs to be and is rescheduled */
++	struct brcms_firmware fw;
++	struct wiphy *wiphy;
++	struct brcms_ucode ucode;
++	bool mute_tx;
++};
++
++/* misc callbacks */
++extern void brcms_init(struct brcms_info *wl);
++extern uint brcms_reset(struct brcms_info *wl);
++extern void brcms_intrson(struct brcms_info *wl);
++extern u32 brcms_intrsoff(struct brcms_info *wl);
++extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
++extern int brcms_up(struct brcms_info *wl);
++extern void brcms_down(struct brcms_info *wl);
++extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++				bool state, int prio);
++extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
++
++/* timer functions */
++extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				      void (*fn) (void *arg), void *arg,
++				      const char *name);
++extern void brcms_free_timer(struct brcms_timer *timer);
++extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
++extern bool brcms_del_timer(struct brcms_timer *timer);
++extern void brcms_msleep(struct brcms_info *wl, uint ms);
++extern void brcms_dpc(unsigned long data);
++extern void brcms_timer(struct brcms_timer *t);
++extern void brcms_fatal_error(struct brcms_info *wl);
++
++#endif				/* _BRCM_MAC80211_IF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+new file mode 100644
+index 0000000..d7d4a33
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -0,0 +1,8495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/if_ether.h>
++#include <net/mac80211.h>
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "antsel.h"
++#include "stf.h"
++#include "ampdu.h"
++#include "mac80211_if.h"
++#include "ucode_loader.h"
++#include "main.h"
++#include "soc.h"
++
++/*
++ * Indication for txflowcontrol that all priority bits in
++ * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
++ */
++#define ALLPRIO				-1
++
++/* watchdog timer, in unit of ms */
++#define TIMER_INTERVAL_WATCHDOG		1000
++/* radio monitor timer, in unit of ms */
++#define TIMER_INTERVAL_RADIOCHK		800
++
++/* beacon interval, in unit of 1024TU */
++#define BEACON_INTERVAL_DEFAULT		100
++
++/* n-mode support capability */
++/* 2x2 includes both 1x1 & 2x2 devices
++ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
++ * control it independently
++ */
++#define WL_11N_2x2			1
++#define WL_11N_3x3			3
++#define WL_11N_4x4			4
++
++#define EDCF_ACI_MASK			0x60
++#define EDCF_ACI_SHIFT			5
++#define EDCF_ECWMIN_MASK		0x0f
++#define EDCF_ECWMAX_SHIFT		4
++#define EDCF_AIFSN_MASK			0x0f
++#define EDCF_AIFSN_MAX			15
++#define EDCF_ECWMAX_MASK		0xf0
++
++#define EDCF_AC_BE_TXOP_STA		0x0000
++#define EDCF_AC_BK_TXOP_STA		0x0000
++#define EDCF_AC_VO_ACI_STA		0x62
++#define EDCF_AC_VO_ECW_STA		0x32
++#define EDCF_AC_VI_ACI_STA		0x42
++#define EDCF_AC_VI_ECW_STA		0x43
++#define EDCF_AC_BK_ECW_STA		0xA4
++#define EDCF_AC_VI_TXOP_STA		0x005e
++#define EDCF_AC_VO_TXOP_STA		0x002f
++#define EDCF_AC_BE_ACI_STA		0x03
++#define EDCF_AC_BE_ECW_STA		0xA4
++#define EDCF_AC_BK_ACI_STA		0x27
++#define EDCF_AC_VO_TXOP_AP		0x002f
++
++#define EDCF_TXOP2USEC(txop)		((txop) << 5)
++#define EDCF_ECW2CW(exp)		((1 << (exp)) - 1)
++
++#define APHY_SYMBOL_TIME		4
++#define APHY_PREAMBLE_TIME		16
++#define APHY_SIGNAL_TIME		4
++#define APHY_SIFS_TIME			16
++#define APHY_SERVICE_NBITS		16
++#define APHY_TAIL_NBITS			6
++#define BPHY_SIFS_TIME			10
++#define BPHY_PLCP_SHORT_TIME		96
++
++#define PREN_PREAMBLE			24
++#define PREN_MM_EXT			12
++#define PREN_PREAMBLE_EXT		4
++
++#define DOT11_MAC_HDR_LEN		24
++#define DOT11_ACK_LEN			10
++#define DOT11_BA_LEN			4
++#define DOT11_OFDM_SIGNAL_EXTENSION	6
++#define DOT11_MIN_FRAG_LEN		256
++#define DOT11_RTS_LEN			16
++#define DOT11_CTS_LEN			10
++#define DOT11_BA_BITMAP_LEN		128
++#define DOT11_MIN_BEACON_PERIOD		1
++#define DOT11_MAX_BEACON_PERIOD		0xFFFF
++#define DOT11_MAXNUMFRAGS		16
++#define DOT11_MAX_FRAG_LEN		2346
++
++#define BPHY_PLCP_TIME			192
++#define RIFS_11N_TIME			2
++
++/* length of the BCN template area */
++#define BCN_TMPL_LEN			512
++
++/* brcms_bss_info flag bit values */
++#define BRCMS_BSS_HT			0x0020	/* BSS is HT (MIMO) capable */
++
++/* chip rx buffer offset */
++#define BRCMS_HWRXOFF			38
++
++/* rfdisable delay timer 500 ms, runs of ALP clock */
++#define RFDISABLE_DEFAULT		10000000
++
++#define BRCMS_TEMPSENSE_PERIOD		10	/* 10 second timeout */
++
++/* precedences numbers for wlc queues. These are twice as may levels as
++ * 802.1D priorities.
++ * Odd numbers are used for HI priority traffic at same precedence levels
++ * These constants are used ONLY by wlc_prio2prec_map.  Do not use them
++ * elsewhere.
++ */
++#define _BRCMS_PREC_NONE		0	/* None = - */
++#define _BRCMS_PREC_BK			2	/* BK - Background */
++#define _BRCMS_PREC_BE			4	/* BE - Best-effort */
++#define _BRCMS_PREC_EE			6	/* EE - Excellent-effort */
++#define _BRCMS_PREC_CL			8	/* CL - Controlled Load */
++#define _BRCMS_PREC_VI			10	/* Vi - Video */
++#define _BRCMS_PREC_VO			12	/* Vo - Voice */
++#define _BRCMS_PREC_NC			14	/* NC - Network Control */
++
++/* synthpu_dly times in us */
++#define SYNTHPU_DLY_APHY_US		3700
++#define SYNTHPU_DLY_BPHY_US		1050
++#define SYNTHPU_DLY_NPHY_US		2048
++#define SYNTHPU_DLY_LPPHY_US		300
++
++#define ANTCNT				10	/* vanilla M_MAX_ANTCNT val */
++
++/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
++#define EDCF_SHORT_S			0
++#define EDCF_SFB_S			4
++#define EDCF_LONG_S			8
++#define EDCF_LFB_S			12
++#define EDCF_SHORT_M			BITFIELD_MASK(4)
++#define EDCF_SFB_M			BITFIELD_MASK(4)
++#define EDCF_LONG_M			BITFIELD_MASK(4)
++#define EDCF_LFB_M			BITFIELD_MASK(4)
++
++#define RETRY_SHORT_DEF			7	/* Default Short retry Limit */
++#define RETRY_SHORT_MAX			255	/* Maximum Short retry Limit */
++#define RETRY_LONG_DEF			4	/* Default Long retry count */
++#define RETRY_SHORT_FB			3	/* Short count for fb rate */
++#define RETRY_LONG_FB			2	/* Long count for fb rate */
++
++#define APHY_CWMIN			15
++#define PHY_CWMAX			1023
++
++#define EDCF_AIFSN_MIN			1
++
++#define FRAGNUM_MASK			0xF
++
++#define APHY_SLOT_TIME			9
++#define BPHY_SLOT_TIME			20
++
++#define WL_SPURAVOID_OFF		0
++#define WL_SPURAVOID_ON1		1
++#define WL_SPURAVOID_ON2		2
++
++/* invalid core flags, use the saved coreflags */
++#define BRCMS_USE_COREFLAGS		0xffffffff
++
++/* values for PLCPHdr_override */
++#define BRCMS_PLCP_AUTO			-1
++#define BRCMS_PLCP_SHORT		0
++#define BRCMS_PLCP_LONG			1
++
++/* values for g_protection_override and n_protection_override */
++#define BRCMS_PROTECTION_AUTO		-1
++#define BRCMS_PROTECTION_OFF		0
++#define BRCMS_PROTECTION_ON		1
++#define BRCMS_PROTECTION_MMHDR_ONLY	2
++#define BRCMS_PROTECTION_CTS_ONLY	3
++
++/* values for g_protection_control and n_protection_control */
++#define BRCMS_PROTECTION_CTL_OFF	0
++#define BRCMS_PROTECTION_CTL_LOCAL	1
++#define BRCMS_PROTECTION_CTL_OVERLAP	2
++
++/* values for n_protection */
++#define BRCMS_N_PROTECTION_OFF		0
++#define BRCMS_N_PROTECTION_OPTIONAL	1
++#define BRCMS_N_PROTECTION_20IN40	2
++#define BRCMS_N_PROTECTION_MIXEDMODE	3
++
++/* values for band specific 40MHz capabilities */
++#define BRCMS_N_BW_20ALL		0
++#define BRCMS_N_BW_40ALL		1
++#define BRCMS_N_BW_20IN2G_40IN5G	2
++
++/* bitflags for SGI support (sgi_rx iovar) */
++#define BRCMS_N_SGI_20			0x01
++#define BRCMS_N_SGI_40			0x02
++
++/* defines used by the nrate iovar */
++/* MSC in use,indicates b0-6 holds an mcs */
++#define NRATE_MCS_INUSE			0x00000080
++/* rate/mcs value */
++#define NRATE_RATE_MASK			0x0000007f
++/* stf mode mask: siso, cdd, stbc, sdm */
++#define NRATE_STF_MASK			0x0000ff00
++/* stf mode shift */
++#define NRATE_STF_SHIFT			8
++/* bit indicate to override mcs only */
++#define NRATE_OVERRIDE_MCS_ONLY		0x40000000
++#define NRATE_SGI_MASK			0x00800000	/* sgi mode */
++#define NRATE_SGI_SHIFT			23		/* sgi mode */
++#define NRATE_LDPC_CODING		0x00400000	/* adv coding in use */
++#define NRATE_LDPC_SHIFT		22		/* ldpc shift */
++
++#define NRATE_STF_SISO			0		/* stf mode SISO */
++#define NRATE_STF_CDD			1		/* stf mode CDD */
++#define NRATE_STF_STBC			2		/* stf mode STBC */
++#define NRATE_STF_SDM			3		/* stf mode SDM */
++
++#define MAX_DMA_SEGS			4
++
++/* Max # of entries in Tx FIFO based on 4kb page size */
++#define NTXD				256
++/* Max # of entries in Rx FIFO based on 4kb page size */
++#define NRXD				256
++
++/* try to keep this # rbufs posted to the chip */
++#define NRXBUFPOST			32
++
++/* data msg txq hiwat mark */
++#define BRCMS_DATAHIWAT			50
++
++/* max # frames to process in brcms_c_recv() */
++#define RXBND				8
++/* max # tx status to process in wlc_txstatus() */
++#define TXSBND				8
++
++/* brcmu_format_flags() bit description structure */
++struct brcms_c_bit_desc {
++	u32 bit;
++	const char *name;
++};
++
++/*
++ * The following table lists the buffer memory allocated to xmt fifos in HW.
++ * the size is in units of 256bytes(one block), total size is HW dependent
++ * ucode has default fifo partition, sw can overwrite if necessary
++ *
++ * This is documented in twiki under the topic UcodeTxFifo. Please ensure
++ * the twiki is updated before making changes.
++ */
++
++/* Starting corerev for the fifo size table */
++#define XMTFIFOTBL_STARTREV	20
++
++struct d11init {
++	__le16 addr;
++	__le16 size;
++	__le32 value;
++};
++
++struct edcf_acparam {
++	u8 ACI;
++	u8 ECW;
++	u16 TXOP;
++} __packed;
++
++const u8 prio2fifo[NUMPRIO] = {
++	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
++	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
++	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
++	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
++	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
++	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
++	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
++	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
++};
++
++/* debug/trace */
++uint brcm_msg_level =
++#if defined(DEBUG)
++	LOG_ERROR_VAL;
++#else
++	0;
++#endif				/* DEBUG */
++
++/* TX FIFO number to WME/802.1E Access Category */
++static const u8 wme_fifo2ac[] = {
++	IEEE80211_AC_BK,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_VI,
++	IEEE80211_AC_VO,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_BE
++};
++
++/* ieee80211 Access Category to TX FIFO number */
++static const u8 wme_ac2fifo[] = {
++	TX_AC_VO_FIFO,
++	TX_AC_VI_FIFO,
++	TX_AC_BE_FIFO,
++	TX_AC_BK_FIFO
++};
++
++/* 802.1D Priority to precedence queue mapping */
++const u8 wlc_prio2prec_map[] = {
++	_BRCMS_PREC_BE,		/* 0 BE - Best-effort */
++	_BRCMS_PREC_BK,		/* 1 BK - Background */
++	_BRCMS_PREC_NONE,		/* 2 None = - */
++	_BRCMS_PREC_EE,		/* 3 EE - Excellent-effort */
++	_BRCMS_PREC_CL,		/* 4 CL - Controlled Load */
++	_BRCMS_PREC_VI,		/* 5 Vi - Video */
++	_BRCMS_PREC_VO,		/* 6 Vo - Voice */
++	_BRCMS_PREC_NC,		/* 7 NC - Network Control */
++};
++
++static const u16 xmtfifo_sz[][NFIFO] = {
++	/* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++	/* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++};
++
++#ifdef DEBUG
++static const char * const fifo_names[] = {
++	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
++#else
++static const char fifo_names[6][0];
++#endif
++
++#ifdef DEBUG
++/* pointer to most recently allocated wl/wlc */
++static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
++#endif
++
++/* Find basic rate for a given rate */
++static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
++{
++	if (is_mcs_rate(rspec))
++		return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
++		       .leg_ofdm];
++	return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
++}
++
++static u16 frametype(u32 rspec, u8 mimoframe)
++{
++	if (is_mcs_rate(rspec))
++		return mimoframe;
++	return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
++}
++
++/* currently the best mechanism for determining SIFS is the band in use */
++static u16 get_sifs(struct brcms_band *band)
++{
++	return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
++				 BPHY_SIFS_TIME;
++}
++
++/*
++ * Detect Card removed.
++ * Even checking an sbconfig register read will not false trigger when the core
++ * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
++ * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
++ * reg with fixed 0/1 pattern (some platforms return all 0).
++ * If clocks are present, call the sb routine which will figure out if the
++ * device is removed.
++ */
++static bool brcms_deviceremoved(struct brcms_c_info *wlc)
++{
++	u32 macctrl;
++
++	if (!wlc->hw->clk)
++		return ai_deviceremoved(wlc->hw->sih);
++	macctrl = bcma_read32(wlc->hw->d11core,
++			      D11REGOFFS(maccontrol));
++	return (macctrl & (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
++}
++
++/* sum the individual fifo tx pending packet counts */
++static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
++{
++	return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
++	       wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
++}
++
++static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
++{
++	return wlc->pub->_nbands > 1 && !wlc->bandlocked;
++}
++
++static int brcms_chspec_bw(u16 chanspec)
++{
++	if (CHSPEC_IS40(chanspec))
++		return BRCMS_40_MHZ;
++	if (CHSPEC_IS20(chanspec))
++		return BRCMS_20_MHZ;
++
++	return BRCMS_10_MHZ;
++}
++
++static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
++{
++	if (cfg == NULL)
++		return;
++
++	kfree(cfg->current_bss);
++	kfree(cfg);
++}
++
++static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
++{
++	if (wlc == NULL)
++		return;
++
++	brcms_c_bsscfg_mfree(wlc->bsscfg);
++	kfree(wlc->pub);
++	kfree(wlc->modulecb);
++	kfree(wlc->default_bss);
++	kfree(wlc->protection);
++	kfree(wlc->stf);
++	kfree(wlc->bandstate[0]);
++	kfree(wlc->corestate->macstat_snapshot);
++	kfree(wlc->corestate);
++	kfree(wlc->hw->bandstate[0]);
++	kfree(wlc->hw);
++
++	/* free the wlc */
++	kfree(wlc);
++	wlc = NULL;
++}
++
++static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
++{
++	struct brcms_bss_cfg *cfg;
++
++	cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
++	if (cfg == NULL)
++		goto fail;
++
++	cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (cfg->current_bss == NULL)
++		goto fail;
++
++	return cfg;
++
++ fail:
++	brcms_c_bsscfg_mfree(cfg);
++	return NULL;
++}
++
++static struct brcms_c_info *
++brcms_c_attach_malloc(uint unit, uint *err, uint devid)
++{
++	struct brcms_c_info *wlc;
++
++	wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
++	if (wlc == NULL) {
++		*err = 1002;
++		goto fail;
++	}
++
++	/* allocate struct brcms_c_pub state structure */
++	wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
++	if (wlc->pub == NULL) {
++		*err = 1003;
++		goto fail;
++	}
++	wlc->pub->wlc = wlc;
++
++	/* allocate struct brcms_hardware state structure */
++
++	wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
++	if (wlc->hw == NULL) {
++		*err = 1005;
++		goto fail;
++	}
++	wlc->hw->wlc = wlc;
++
++	wlc->hw->bandstate[0] =
++		kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
++	if (wlc->hw->bandstate[0] == NULL) {
++		*err = 1006;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->hw->bandstate[i] = (struct brcms_hw_band *)
++			    ((unsigned long)wlc->hw->bandstate[0] +
++			     (sizeof(struct brcms_hw_band) * i));
++	}
++
++	wlc->modulecb =
++		kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
++	if (wlc->modulecb == NULL) {
++		*err = 1009;
++		goto fail;
++	}
++
++	wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (wlc->default_bss == NULL) {
++		*err = 1010;
++		goto fail;
++	}
++
++	wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
++	if (wlc->bsscfg == NULL) {
++		*err = 1011;
++		goto fail;
++	}
++
++	wlc->protection = kzalloc(sizeof(struct brcms_protection),
++				  GFP_ATOMIC);
++	if (wlc->protection == NULL) {
++		*err = 1016;
++		goto fail;
++	}
++
++	wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
++	if (wlc->stf == NULL) {
++		*err = 1017;
++		goto fail;
++	}
++
++	wlc->bandstate[0] =
++		kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
++	if (wlc->bandstate[0] == NULL) {
++		*err = 1025;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->bandstate[i] = (struct brcms_band *)
++				((unsigned long)wlc->bandstate[0]
++				+ (sizeof(struct brcms_band)*i));
++	}
++
++	wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
++	if (wlc->corestate == NULL) {
++		*err = 1026;
++		goto fail;
++	}
++
++	wlc->corestate->macstat_snapshot =
++		kzalloc(sizeof(struct macstat), GFP_ATOMIC);
++	if (wlc->corestate->macstat_snapshot == NULL) {
++		*err = 1027;
++		goto fail;
++	}
++
++	return wlc;
++
++ fail:
++	brcms_c_detach_mfree(wlc);
++	return NULL;
++}
++
++/*
++ * Update the slot timing for standard 11b/g (20us slots)
++ * or shortslot 11g (9us slots)
++ * The PSM needs to be suspended for this call.
++ */
++static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
++					bool shortslot)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if (shortslot) {
++		/* 11g short slot: 11a timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0207);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
++	} else {
++		/* 11g long slot: 11b timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0212);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
++	}
++}
++
++/*
++ * calculate frame duration of a given rate and length, return
++ * time in usec unit
++ */
++static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
++				    u8 preamble_type, uint mac_len)
++{
++	uint nsyms, dur = 0, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	if (rate == 0) {
++		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
++			  wlc->pub->unit);
++		rate = BRCM_RATE_1M;
++	}
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
++		 wlc->pub->unit, ratespec, preamble_type, mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++
++		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		if (preamble_type == BRCMS_MM_PREAMBLE)
++			dur += PREN_MM_EXT;
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else if (is_ofdm_rate(rate)) {
++		dur = APHY_PREAMBLE_TIME;
++		dur += APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
++		nsyms =
++		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
++			 Ndps);
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else {
++		/*
++		 * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
++		 * will divide out
++		 */
++		mac_len = mac_len * 8 * 2;
++		/* calc ceiling of bits/rate = microseconds of air time */
++		dur = (mac_len + rate - 1) / rate;
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur += BPHY_PLCP_SHORT_TIME;
++		else
++			dur += BPHY_PLCP_TIME;
++	}
++	return dur;
++}
++
++static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
++				const struct d11init *inits)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	int i;
++	uint offset;
++	u16 size;
++	u32 value;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
++		size = le16_to_cpu(inits[i].size);
++		offset = le16_to_cpu(inits[i].addr);
++		value = le32_to_cpu(inits[i].value);
++		if (size == 2)
++			bcma_write16(core, offset, value);
++		else if (size == 4)
++			bcma_write32(core, offset, value);
++		else
++			break;
++	}
++}
++
++static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
++{
++	u8 idx;
++	u16 addr[] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++
++	for (idx = 0; idx < MHFMAX; idx++)
++		brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
++}
++
++static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
++{
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	/* init microcode host flags */
++	brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
++
++	/* do band-specific ucode IHR, SHM, and SCR inits */
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		if (D11REV_IS(wlc_hw->corerev, 24)) {
++			if (BRCMS_ISLCNPHY(wlc_hw->band))
++				brcms_c_write_inits(wlc_hw,
++						    ucode->d11lcn0bsinitvals24);
++			else
++				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
++					  " core rev %d\n", __func__,
++					  wlc_hw->unit, wlc_hw->corerev);
++		} else {
++			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++				__func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 ioctl = bcma_aread32(core, BCMA_IOCTL) & ~m;
++
++	bcma_awrite32(core, BCMA_IOCTL, ioctl | v);
++}
++
++static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
++
++	wlc_hw->phyclk = clk;
++
++	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC | SICF_GMODE),
++				   (SICF_PRST | SICF_FGC));
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_PRST);
++		udelay(1);
++
++	} else {		/* take phy out of reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_FGC);
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++		udelay(1);
++
++	}
++}
++
++/* low-level band switch utility routine */
++static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		bandunit);
++
++	wlc_hw->band = wlc_hw->bandstate[bandunit];
++
++	/*
++	 * BMAC_NOTE:
++	 *   until we eliminate need for wlc->band refs in low level code
++	 */
++	wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
++
++	/* set gmode core flag */
++	if (wlc_hw->sbclk && !wlc_hw->noreset) {
++		u32 gmode = 0;
++
++		if (bandunit == 0)
++			gmode = SICF_GMODE;
++
++		brcms_b_core_ioctl(wlc_hw, SICF_GMODE, gmode);
++	}
++}
++
++/* switch to new band but leave it inactive */
++static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++	u32 macctrl;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	macctrl = bcma_read32(wlc_hw->d11core,
++			      D11REGOFFS(maccontrol));
++	WARN_ON((macctrl & MCTL_EN_MAC) != 0);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	brcms_b_core_phy_clk(wlc_hw, OFF);
++
++	brcms_c_setxband(wlc_hw, bandunit);
++
++	return macintmask;
++}
++
++/* process an individual struct tx_status */
++static bool
++brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
++{
++	struct sk_buff *p;
++	uint queue;
++	struct d11txh *txh;
++	struct scb *scb = NULL;
++	bool free_pdu;
++	int tx_rts, tx_frame_count, tx_rts_count;
++	uint totlen, supr_status;
++	bool lastframe;
++	struct ieee80211_hdr *h;
++	u16 mcl;
++	struct ieee80211_tx_info *tx_info;
++	struct ieee80211_tx_rate *txrate;
++	int i;
++
++	/* discard intermediate indications for ucode with one legitimate case:
++	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
++	 *   but the subsequent tx of DATA failed. so it will start rts/cts
++	 *   from the beginning (resetting the rts transmission count)
++	 */
++	if (!(txs->status & TX_STATUS_AMPDU)
++	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
++		BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
++		return false;
++	}
++
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	if (queue >= NFIFO) {
++		p = NULL;
++		goto fatal;
++	}
++
++	p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	if (p == NULL)
++		goto fatal;
++
++	txh = (struct d11txh *) (p->data);
++	mcl = le16_to_cpu(txh->MacTxControlLow);
++
++	if (txs->phyerr) {
++		if (brcm_msg_level & LOG_ERROR_VAL) {
++			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
++				  txs->phyerr, txh->MainRates);
++			brcms_c_print_txdesc(txh);
++		}
++		brcms_c_print_txstatus(txs);
++	}
++
++	if (txs->frameid != le16_to_cpu(txh->TxFrameID))
++		goto fatal;
++	tx_info = IEEE80211_SKB_CB(p);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	if (tx_info->control.sta)
++		scb = &wlc->pri_scb;
++
++	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++		brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
++		return false;
++	}
++
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++	if (supr_status == TX_STATUS_SUPR_BADCH)
++		BCMMSG(wlc->wiphy,
++		       "%s: Pkt tx suppressed, possibly channel %d\n",
++		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
++
++	tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
++	tx_frame_count =
++	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
++	tx_rts_count =
++	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
++
++	lastframe = !ieee80211_has_morefrags(h->frame_control);
++
++	if (!lastframe) {
++		wiphy_err(wlc->wiphy, "Not last frame!\n");
++	} else {
++		/*
++		 * Set information to be consumed by Minstrel ht.
++		 *
++		 * The "fallback limit" is the number of tx attempts a given
++		 * MPDU is sent at the "primary" rate. Tx attempts beyond that
++		 * limit are sent at the "secondary" rate.
++		 * A 'short frame' does not exceed RTS treshold.
++		 */
++		u16 sfbl,	/* Short Frame Rate Fallback Limit */
++		    lfbl,	/* Long Frame Rate Fallback Limit */
++		    fbl;
++
++		if (queue < IEEE80211_NUM_ACS) {
++			sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_SFB);
++			lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_LFB);
++		} else {
++			sfbl = wlc->SFBL;
++			lfbl = wlc->LFBL;
++		}
++
++		txrate = tx_info->status.rates;
++		if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
++			fbl = lfbl;
++		else
++			fbl = sfbl;
++
++		ieee80211_tx_info_clear_status(tx_info);
++
++		if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
++			/*
++			 * rate selection requested a fallback rate
++			 * and we used it
++			 */
++			txrate[0].count = fbl;
++			txrate[1].count = tx_frame_count - fbl;
++		} else {
++			/*
++			 * rate selection did not request fallback rate, or
++			 * we didn't need it
++			 */
++			txrate[0].count = tx_frame_count;
++			/*
++			 * rc80211_minstrel.c:minstrel_tx_status() expects
++			 * unused rates to be marked with idx = -1
++			 */
++			txrate[1].idx = -1;
++			txrate[1].count = 0;
++		}
++
++		/* clear the rest of the rates */
++		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++			txrate[i].idx = -1;
++			txrate[i].count = 0;
++		}
++
++		if (txs->status & TX_STATUS_ACK_RCV)
++			tx_info->flags |= IEEE80211_TX_STAT_ACK;
++	}
++
++	totlen = p->len;
++	free_pdu = true;
++
++	brcms_c_txfifo_complete(wlc, queue, 1);
++
++	if (lastframe) {
++		/* remove PLCP & Broadcom tx descriptor header */
++		skb_pull(p, D11_PHY_HDR_LEN);
++		skb_pull(p, D11_TXH_LEN);
++		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
++	} else {
++		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
++			  "tx_status\n", __func__);
++	}
++
++	return false;
++
++ fatal:
++	if (p)
++		brcmu_pkt_buf_free_skb(p);
++
++	return true;
++
++}
++
++/* process tx completion events in BMAC
++ * Return true if more tx status need to be processed. false otherwise.
++ */
++static bool
++brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
++{
++	bool morepending = false;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	struct bcma_device *core;
++	struct tx_status txstatus, *txs;
++	u32 s1, s2;
++	uint n = 0;
++	/*
++	 * Param 'max_tx_num' indicates max. # tx status to process before
++	 * break out.
++	 */
++	uint max_tx_num = bound ? TXSBND : -1;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	txs = &txstatus;
++	core = wlc_hw->d11core;
++	*fatal = false;
++	s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	while (!(*fatal)
++	       && (s1 & TXS_V)) {
++
++		if (s1 == 0xffffffff) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
++				wlc_hw->unit, __func__);
++			return morepending;
++		}
++		s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
++
++		txs->status = s1 & TXS_STATUS_MASK;
++		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
++		txs->sequence = s2 & TXS_SEQ_MASK;
++		txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
++		txs->lasttxtime = 0;
++
++		*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
++
++		/* !give others some time to run! */
++		if (++n >= max_tx_num)
++			break;
++		s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	}
++
++	if (*fatal)
++		return 0;
++
++	if (n >= max_tx_num)
++		morepending = true;
++
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	return morepending;
++}
++
++static void brcms_c_tbtt(struct brcms_c_info *wlc)
++{
++	if (!wlc->bsscfg->BSS)
++		/*
++		 * DirFrmQ is now valid...defer setting until end
++		 * of ATIM window
++		 */
++		wlc->qvalid |= MCMD_DIRFRMQVAL;
++}
++
++/* set initial host flags value */
++static void
++brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	memset(mhfs, 0, MHFMAX * sizeof(u16));
++
++	mhfs[MHF2] |= mhf2_init;
++
++	/* prohibit use of slowclock on multifunction boards */
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		mhfs[MHF1] |= MHF1_FORCEFASTCLK;
++
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
++		mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
++		mhfs[MHF1] |= MHF1_IQSWAP_WAR;
++	}
++}
++
++static uint
++dmareg(uint direction, uint fifonum)
++{
++	if (direction == DMA_TX)
++		return offsetof(struct d11regs, fifo64regs[fifonum].dmaxmt);
++	return offsetof(struct d11regs, fifo64regs[fifonum].dmarcv);
++}
++
++static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
++{
++	uint i;
++	char name[8];
++	/*
++	 * ucode host flag 2 needed for pio mode, independent of band and fifo
++	 */
++	u16 pio_mhf2 = 0;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint unit = wlc_hw->unit;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	/* name and offsets for dma_attach */
++	snprintf(name, sizeof(name), "wl%d", unit);
++
++	if (wlc_hw->di[0] == NULL) {	/* Init FIFOs */
++		int dma_attach_err = 0;
++
++		/*
++		 * FIFO 0
++		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
++		 * RX: RX_FIFO (RX data packets)
++		 */
++		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   (wme ? dmareg(DMA_TX, 0) : 0),
++					   dmareg(DMA_RX, 0),
++					   (wme ? NTXD : 0), NRXD,
++					   RXBUFSZ, -1, NRXBUFPOST,
++					   BRCMS_HWRXOFF, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[0]);
++
++		/*
++		 * FIFO 1
++		 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
++		 *   (legacy) TX_DATA_FIFO (TX data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 1), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[1]);
++
++		/*
++		 * FIFO 2
++		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 2), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[2]);
++		/*
++		 * FIFO 3
++		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
++		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
++		 */
++		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 3),
++					   0, NTXD, 0, 0, -1,
++					   0, 0, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[3]);
++/* Cleaner to leave this as if with AP defined */
++
++		if (dma_attach_err) {
++			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
++				  "\n", unit);
++			return false;
++		}
++
++		/* get pointer to dma engine tx flow control variable */
++		for (i = 0; i < NFIFO; i++)
++			if (wlc_hw->di[i])
++				wlc_hw->txavail[i] =
++				    (uint *) dma_getvar(wlc_hw->di[i],
++							"&txavail");
++	}
++
++	/* initial ucode host flags */
++	brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
++
++	return true;
++}
++
++static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
++{
++	uint j;
++
++	for (j = 0; j < NFIFO; j++) {
++		if (wlc_hw->di[j]) {
++			dma_detach(wlc_hw->di[j]);
++			wlc_hw->di[j] = NULL;
++		}
++	}
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ *  BMAC_NOTES, move low out and resolve the dangling ones
++ */
++static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	/* set default sw macintmask value */
++	wlc->defmacintmask = DEF_MACINTMASK;
++
++	/* various 802.11g modes */
++	wlc_hw->shortslot = false;
++
++	wlc_hw->SFBL = RETRY_SHORT_FB;
++	wlc_hw->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc_hw->SRL = RETRY_SHORT_DEF;
++	wlc_hw->LRL = RETRY_LONG_DEF;
++	wlc_hw->chanspec = ch20mhz_chspec(1);
++}
++
++static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
++{
++	/* delay before first read of ucode state */
++	udelay(40);
++
++	/* wait until ucode is no longer asleep */
++	SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
++		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
++}
++
++/* control chip clock to save power, enable dynamic clock or force fast clock */
++static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
++{
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
++		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock
++		 * on backplane, but mac core will still run on ALP(not HT) when
++		 * it enters powersave mode, which means the FCA bit may not be
++		 * set. Should wakeup mac if driver wants it to run on HT.
++		 */
++
++		if (wlc_hw->clk) {
++			if (mode == BCMA_CLKMODE_FAST) {
++				bcma_set32(wlc_hw->d11core,
++					   D11REGOFFS(clk_ctl_st),
++					   CCS_FORCEHT);
++
++				udelay(64);
++
++				SPINWAIT(
++				    ((bcma_read32(wlc_hw->d11core,
++				      D11REGOFFS(clk_ctl_st)) &
++				      CCS_HTAVAIL) == 0),
++				      PMU_MAX_TRANSITION_DLY);
++				WARN_ON(!(bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					CCS_HTAVAIL));
++			} else {
++				if ((ai_get_pmurev(wlc_hw->sih) == 0) &&
++				    (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					(CCS_FORCEHT | CCS_HTAREQ)))
++					SPINWAIT(
++					    ((bcma_read32(wlc_hw->d11core,
++					      offsetof(struct d11regs,
++						       clk_ctl_st)) &
++					      CCS_HTAVAIL) == 0),
++					      PMU_MAX_TRANSITION_DLY);
++				bcma_mask32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st),
++					~CCS_FORCEHT);
++			}
++		}
++		wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
++	} else {
++
++		/* old chips w/o PMU, force HT through cc,
++		 * then use FCA to verify mac is running fast clock
++		 */
++
++		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
++
++		/* check fast clock is available (if core is not in reset) */
++		if (wlc_hw->forcefastclk && wlc_hw->clk)
++			WARN_ON(!(bcma_aread32(wlc_hw->d11core, BCMA_IOST) &
++				  SISF_FCLKA));
++
++		/*
++		 * keep the ucode wake bit on if forcefastclk is on since we
++		 * do not want ucode to put us back to slow clock when it dozes
++		 * for PM mode. Code below matches the wake override bit with
++		 * current forcefastclk state. Only setting bit in wake_override
++		 * instead of waking ucode immediately since old code had this
++		 * behavior. Older code set wlc->forcefastclk but only had the
++		 * wake happen if the wakup_ucode work (protected by an up
++		 * check) was executed just below.
++		 */
++		if (wlc_hw->forcefastclk)
++			mboolset(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++		else
++			mboolclr(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++	}
++}
++
++/* set or clear ucode host flag bits
++ * it has an optimization for no-change write
++ * it only writes through shared memory when the core has clock;
++ * pre-CLK changes should use wlc_write_mhf to get around the optimization
++ *
++ *
++ * bands values are: BRCM_BAND_AUTO <--- Current band only
++ *                   BRCM_BAND_5G   <--- 5G band only
++ *                   BRCM_BAND_2G   <--- 2G band only
++ *                   BRCM_BAND_ALL  <--- All bands
++ */
++void
++brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
++	     int bands)
++{
++	u16 save;
++	u16 addr[MHFMAX] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++	struct brcms_hw_band *band;
++
++	if ((val & ~mask) || idx >= MHFMAX)
++		return; /* error condition */
++
++	switch (bands) {
++		/* Current band only or all bands,
++		 * then set the band to current band
++		 */
++	case BRCM_BAND_AUTO:
++	case BRCM_BAND_ALL:
++		band = wlc_hw->band;
++		break;
++	case BRCM_BAND_5G:
++		band = wlc_hw->bandstate[BAND_5G_INDEX];
++		break;
++	case BRCM_BAND_2G:
++		band = wlc_hw->bandstate[BAND_2G_INDEX];
++		break;
++	default:
++		band = NULL;	/* error condition */
++	}
++
++	if (band) {
++		save = band->mhfs[idx];
++		band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
++
++		/* optimization: only write through if changed, and
++		 * changed band is the current band
++		 */
++		if (wlc_hw->clk && (band->mhfs[idx] != save)
++		    && (band == wlc_hw->band))
++			brcms_b_write_shm(wlc_hw, addr[idx],
++					   (u16) band->mhfs[idx]);
++	}
++
++	if (bands == BRCM_BAND_ALL) {
++		wlc_hw->bandstate[0]->mhfs[idx] =
++		    (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
++		wlc_hw->bandstate[1]->mhfs[idx] =
++		    (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
++	}
++}
++
++/* set the maccontrol register to desired reset state and
++ * initialize the sw cache of the register
++ */
++static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
++{
++	/* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
++	wlc_hw->maccontrol = 0;
++	wlc_hw->suspended_fifos = 0;
++	wlc_hw->wake_override = 0;
++	wlc_hw->mute_override = 0;
++	brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
++}
++
++/*
++ * write the software state of maccontrol and
++ * overrides to the maccontrol register
++ */
++static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
++{
++	u32 maccontrol = wlc_hw->maccontrol;
++
++	/* OR in the wake bit if overridden */
++	if (wlc_hw->wake_override)
++		maccontrol |= MCTL_WAKE;
++
++	/* set AP and INFRA bits for mute if needed */
++	if (wlc_hw->mute_override) {
++		maccontrol &= ~(MCTL_AP);
++		maccontrol |= MCTL_INFRA;
++	}
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(maccontrol),
++		     maccontrol);
++}
++
++/* set or clear maccontrol bits */
++void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
++{
++	u32 maccontrol;
++	u32 new_maccontrol;
++
++	if (val & ~mask)
++		return; /* error condition */
++	maccontrol = wlc_hw->maccontrol;
++	new_maccontrol = (maccontrol & ~mask) | val;
++
++	/* if the new maccontrol value is the same as the old, nothing to do */
++	if (new_maccontrol == maccontrol)
++		return;
++
++	/* something changed, cache the new value */
++	wlc_hw->maccontrol = new_maccontrol;
++
++	/* write the new values with overrides applied */
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++				 u32 override_bit)
++{
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
++		mboolset(wlc_hw->wake_override, override_bit);
++		return;
++	}
++
++	mboolset(wlc_hw->wake_override, override_bit);
++
++	brcms_c_mctrl_write(wlc_hw);
++	brcms_b_wait_for_wake(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++				   u32 override_bit)
++{
++	mboolclr(wlc_hw->wake_override, override_bit);
++
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* When driver needs ucode to stop beaconing, it has to make sure that
++ * MCTL_AP is clear and MCTL_INFRA is set
++ * Mode           MCTL_AP        MCTL_INFRA
++ * AP                1              1
++ * STA               0              1 <--- This will ensure no beacons
++ * IBSS              0              0
++ */
++static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
++{
++	wlc_hw->mute_override = 1;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* Clear the override on AP and INFRA bits */
++static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->mute_override == 0)
++		return;
++
++	wlc_hw->mute_override = 0;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/*
++ * Write a MAC address to the given match reg offset in the RXE match engine.
++ */
++static void
++brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
++		       const u8 *addr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 mac_l;
++	u16 mac_m;
++	u16 mac_h;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
++		 wlc_hw->unit);
++
++	mac_l = addr[0] | (addr[1] << 8);
++	mac_m = addr[2] | (addr[3] << 8);
++	mac_h = addr[4] | (addr[5] << 8);
++
++	/* enter the MAC addr into the RXE match registers */
++	bcma_write16(core, D11REGOFFS(rcm_ctl),
++		     RCM_INC_DATA | match_reg_offset);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_l);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_m);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_h);
++}
++
++void
++brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
++			    void *buf)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 word;
++	__le32 word_le;
++	__be32 word_be;
++	bool be_bit;
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	bcma_write32(core, D11REGOFFS(tplatewrptr), offset);
++
++	/* if MCTL_BIGEND bit set in mac control register,
++	 * the chip swaps data in fifo, as well as data in
++	 * template ram
++	 */
++	be_bit = (bcma_read32(core, D11REGOFFS(maccontrol)) & MCTL_BIGEND) != 0;
++
++	while (len > 0) {
++		memcpy(&word, buf, sizeof(u32));
++
++		if (be_bit) {
++			word_be = cpu_to_be32(word);
++			word = *(u32 *)&word_be;
++		} else {
++			word_le = cpu_to_le32(word);
++			word = *(u32 *)&word_le;
++		}
++
++		bcma_write32(core, D11REGOFFS(tplatewrdata), word);
++
++		buf = (u8 *) buf + sizeof(u32);
++		len -= sizeof(u32);
++	}
++}
++
++static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
++{
++	wlc_hw->band->CWmin = newmin;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMIN);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmin);
++}
++
++static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
++{
++	wlc_hw->band->CWmax = newmax;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMAX);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmax);
++}
++
++void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
++{
++	bool fastclk;
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
++
++	brcms_b_phy_reset(wlc_hw);
++	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
++{
++	u16 v;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	/* update SYNTHPU_DLY */
++
++	if (BRCMS_ISLCNPHY(wlc->band))
++		v = SYNTHPU_DLY_LPPHY_US;
++	else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
++		v = SYNTHPU_DLY_NPHY_US;
++	else
++		v = SYNTHPU_DLY_BPHY_US;
++
++	brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
++}
++
++static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
++{
++	u16 phyctl;
++	u16 phytxant = wlc_hw->bmac_phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* set the Probe Response frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
++
++	/* set the Response (ACK/CTS) frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
++}
++
++static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
++					 u8 rate)
++{
++	uint i;
++	u8 plcp_rate = 0;
++	struct plcp_signal_rate_lookup {
++		u8 rate;
++		u8 signal_rate;
++	};
++	/* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
++	const struct plcp_signal_rate_lookup rate_lookup[] = {
++		{BRCM_RATE_6M, 0xB},
++		{BRCM_RATE_9M, 0xF},
++		{BRCM_RATE_12M, 0xA},
++		{BRCM_RATE_18M, 0xE},
++		{BRCM_RATE_24M, 0x9},
++		{BRCM_RATE_36M, 0xD},
++		{BRCM_RATE_48M, 0x8},
++		{BRCM_RATE_54M, 0xC}
++	};
++
++	for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
++		if (rate == rate_lookup[i].rate) {
++			plcp_rate = rate_lookup[i].signal_rate;
++			break;
++		}
++	}
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
++}
++
++static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
++{
++	u8 rate;
++	u8 rates[8] = {
++		BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
++		BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
++	};
++	u16 entry_ptr;
++	u16 pctl1;
++	uint i;
++
++	if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
++		return;
++
++	/* walk the phy rate table and update the entries */
++	for (i = 0; i < ARRAY_SIZE(rates); i++) {
++		rate = rates[i];
++
++		entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
++
++		/* read the SHM Rate Table entry OFDM PCTL1 values */
++		pctl1 =
++		    brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
++
++		/* modify the value */
++		pctl1 &= ~PHY_TXC1_MODE_MASK;
++		pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
++
++		/* Update the SHM Rate Table entry OFDM PCTL1 values */
++		brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
++				   pctl1);
++	}
++}
++
++/* band-specific init */
++static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	brcms_c_ucode_bsinit(wlc_hw);
++
++	wlc_phy_init(wlc_hw->band->pi, chanspec);
++
++	brcms_c_ucode_txant_set(wlc_hw);
++
++	/*
++	 * cwmin is band-specific, update hardware
++	 * with value for current band
++	 */
++	brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
++	brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
++
++	brcms_b_update_slot_timing(wlc_hw,
++				   wlc_hw->band->bandtype == BRCM_BAND_5G ?
++				   true : wlc_hw->shortslot);
++
++	/* write phytype and phyvers */
++	brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
++	brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
++
++	/*
++	 * initialize the txphyctl1 rate table since
++	 * shmem is shared between bands
++	 */
++	brcms_upd_ofdm_pctl1_table(wlc_hw);
++
++	brcms_b_upd_synthpu(wlc_hw);
++}
++
++/* Perform a soft reset of the PHY PLL */
++void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
++		  ~0, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 4);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++}
++
++/* light way to turn on phy clock without reset for NPHY only
++ *  refer to brcms_b_core_phy_clk for full version
++ */
++void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
++{
++	/* support(necessary for NPHY and HYPHY) only */
++	if (!BRCMS_ISNPHY(wlc_hw->band))
++		return;
++
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, SICF_FGC);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++
++}
++
++void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
++{
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, SICF_MPCLKE);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, 0);
++}
++
++void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_phy_pub *pih = wlc_hw->band->pi;
++	u32 phy_bw_clkbits;
++	bool phy_in_reset = false;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (pih == NULL)
++		return;
++
++	phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
++
++	/* Specific reset sequence required for NPHY rev 3 and 4 */
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
++	    NREV_LE(wlc_hw->band->phyrev, 4)) {
++		/* Set the PHY bandwidth */
++		brcms_b_core_ioctl(wlc_hw, SICF_BWMASK, phy_bw_clkbits);
++
++		udelay(1);
++
++		/* Perform a soft reset of the PHY PLL */
++		brcms_b_core_phypll_reset(wlc_hw);
++
++		/* reset the PHY */
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_PCLKE),
++				   (SICF_PRST | SICF_PCLKE));
++		phy_in_reset = true;
++	} else {
++		brcms_b_core_ioctl(wlc_hw,
++				   (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
++				   (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
++	}
++
++	udelay(2);
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	if (pih)
++		wlc_phy_anacore(pih, ON);
++}
++
++/* switch to and initialize new band */
++static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
++			    u16 chanspec) {
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	u32 macintmask;
++
++	/* Enable the d11 core before accessing it */
++	if (!bcma_core_is_enabled(wlc_hw->d11core)) {
++		bcma_core_enable(wlc_hw->d11core, 0);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	macintmask = brcms_c_setband_inact(wlc, bandunit);
++
++	if (!wlc_hw->up)
++		return;
++
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	/* band-specific initializations */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/*
++	 * If there are any pending software interrupt bits,
++	 * then replace these with a harmless nonzero value
++	 * so brcms_c_dpc() will re-enable interrupts when done.
++	 */
++	if (wlc->macintstatus)
++		wlc->macintstatus = MI_DMAINT;
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* ucode should still be suspended.. */
++	WARN_ON((bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)) &
++		 MCTL_EN_MAC) != 0);
++}
++
++static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
++{
++
++	/* reject unsupported corerev */
++	if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
++		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
++			  wlc_hw->corerev);
++		return false;
++	}
++
++	return true;
++}
++
++/* Validate some board info parameters */
++static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
++{
++	uint boardrev = wlc_hw->boardrev;
++
++	/* 4 bits each for board type, major, minor, and tiny version */
++	uint brt = (boardrev & 0xf000) >> 12;
++	uint b0 = (boardrev & 0xf00) >> 8;
++	uint b1 = (boardrev & 0xf0) >> 4;
++	uint b2 = boardrev & 0xf;
++
++	/* voards from other vendors are always considered valid */
++	if (ai_get_boardvendor(wlc_hw->sih) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	/* do some boardrev sanity checks when boardvendor is Broadcom */
++	if (boardrev == 0)
++		return false;
++
++	if (boardrev <= 0xff)
++		return true;
++
++	if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
++		|| (b2 > 9))
++		return false;
++
++	return true;
++}
++
++static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
++{
++	struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
++
++	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
++	if (!is_zero_ether_addr(sprom->il0mac)) {
++		memcpy(etheraddr, sprom->il0mac, 6);
++		return;
++	}
++
++	if (wlc_hw->_nbands > 1)
++		memcpy(etheraddr, sprom->et1mac, 6);
++	else
++		memcpy(etheraddr, sprom->il0mac, 6);
++}
++
++/* power both the pll and external oscillator on/off */
++static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
++
++	/*
++	 * dont power down if plldown is false or
++	 * we must poll hw radio disable
++	 */
++	if (!want && wlc_hw->pllreq)
++		return;
++
++	wlc_hw->sbclk = want;
++	if (!wlc_hw->sbclk) {
++		wlc_hw->clk = false;
++		if (wlc_hw->band && wlc_hw->band->pi)
++			wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++	}
++}
++
++/*
++ * Return true if radio is disabled, otherwise false.
++ * hw radio disable signal is an external pin, users activate it asynchronously
++ * this function could be called when driver is down and w/o clock
++ * it operates on different registers depending on corerev and boardflag.
++ */
++static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
++{
++	bool v, clk, xtal;
++	u32 flags = 0;
++
++	xtal = wlc_hw->sbclk;
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, ON);
++
++	/* may need to take core out of reset first */
++	clk = wlc_hw->clk;
++	if (!clk) {
++		/*
++		 * mac no longer enables phyclk automatically when driver
++		 * accesses phyreg throughput mac. This can be skipped since
++		 * only mac reg is accessed below
++		 */
++		flags |= SICF_PCLKE;
++
++		/*
++		 * TODO: test suspend/resume
++		 *
++		 * AI chip doesn't restore bar0win2 on
++		 * hibernation/resume, need sw fixup
++		 */
++
++		bcma_core_enable(wlc_hw->d11core, flags);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	v = ((bcma_read32(wlc_hw->d11core,
++			  D11REGOFFS(phydebug)) & PDBG_RFD) != 0);
++
++	/* put core back into reset */
++	if (!clk)
++		bcma_core_disable(wlc_hw->d11core, 0);
++
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, OFF);
++
++	return v;
++}
++
++static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
++{
++	struct dma_pub *di = wlc_hw->di[fifo];
++	return dma_rxreset(di);
++}
++
++/* d11 core reset
++ *   ensure fask clock during reset
++ *   reset dma
++ *   reset d11(out of reset)
++ *   reset phy(out of reset)
++ *   clear software macintstatus for fresh new start
++ * one testing hack wlc_hw->noreset will bypass the d11/phy reset
++ */
++void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
++{
++	uint i;
++	bool fastclk;
++
++	if (flags == BRCMS_USE_COREFLAGS)
++		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on  */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* reset the dma engines except first time thru */
++	if (bcma_core_is_enabled(wlc_hw->d11core)) {
++		for (i = 0; i < NFIFO; i++)
++			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
++				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
++					  "dma_txreset[%d]: cannot stop dma\n",
++					   wlc_hw->unit, __func__, i);
++
++		if ((wlc_hw->di[RX_FIFO])
++		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
++			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
++				  "[%d]: cannot stop dma\n",
++				  wlc_hw->unit, __func__, RX_FIFO);
++	}
++	/* if noreset, just stop the psm and return */
++	if (wlc_hw->noreset) {
++		wlc_hw->wlc->macintstatus = 0;	/* skip wl_dpc after down */
++		brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
++		return;
++	}
++
++	/*
++	 * mac no longer enables phyclk automatically when driver accesses
++	 * phyreg throughput mac, AND phy_reset is skipped at early stage when
++	 * band->pi is invalid. need to enable PHY CLK
++	 */
++	flags |= SICF_PCLKE;
++
++	/*
++	 * reset the core
++	 * In chips with PMU, the fastclk request goes through d11 core
++	 * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
++	 *
++	 * This adds some delay and we can optimize it by also requesting
++	 * fastclk through chipcommon during this period if necessary. But
++	 * that has to work coordinate with other driver like mips/arm since
++	 * they may touch chipcommon as well.
++	 */
++	wlc_hw->clk = false;
++	bcma_core_enable(wlc_hw->d11core, flags);
++	wlc_hw->clk = true;
++	if (wlc_hw->band && wlc_hw->band->pi)
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
++
++	brcms_c_mctrl_reset(wlc_hw);
++
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	brcms_b_phy_reset(wlc_hw);
++
++	/* turn on PHY_PLL */
++	brcms_b_core_phypll_ctl(wlc_hw, true);
++
++	/* clear sw intstatus */
++	wlc_hw->wlc->macintstatus = 0;
++
++	/* restore the clk setting */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++/* txfifo sizes needs to be modified(increased) since the newer cores
++ * have more memory.
++ */
++static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 fifo_nu;
++	u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
++	u16 txfifo_def, txfifo_def1;
++	u16 txfifo_cmd;
++
++	/* tx fifos start at TXFIFO_START_BLK from the Base address */
++	txfifo_startblk = TXFIFO_START_BLK;
++
++	/* sequence of operations:  reset fifo, set fifo size, reset fifo */
++	for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
++
++		txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
++		txfifo_def = (txfifo_startblk & 0xff) |
++		    (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
++		    ((((txfifo_endblk -
++			1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_cmd =
++		    TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++		bcma_write16(core, D11REGOFFS(xmtfifodef), txfifo_def);
++		bcma_write16(core, D11REGOFFS(xmtfifodef1), txfifo_def1);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++
++		txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
++	}
++	/*
++	 * need to propagate to shm location to be in sync since ucode/hw won't
++	 * do this
++	 */
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
++			   wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
++			   wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
++			   ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_AC_BK_FIFO]));
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
++			   ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_BCMC_FIFO]));
++}
++
++/* This function is used for changing the tsf frac register
++ * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
++ * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
++ * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
++ * HTPHY Formula is 2^26/freq(MHz) e.g.
++ * For spuron2 - 126MHz -> 2^26/126 = 532610.0
++ *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
++ * For spuron: 123MHz -> 2^26/123    = 545600.5
++ *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
++ * For spur off: 120MHz -> 2^26/120    = 559240.5
++ *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
++ */
++
++void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43224_CHIP_ID) ||
++	    (ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID)) {
++		if (spurmode == WL_SPURAVOID_ON2) {	/* 126Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x2082);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else if (spurmode == WL_SPURAVOID_ON1) {	/* 123Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x5341);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else {	/* 120Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x8889);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		}
++	} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++		if (spurmode == WL_SPURAVOID_ON1) {	/* 82Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x7CE0);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		} else {	/* 80Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0xCCCD);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		}
++	}
++}
++
++/* Initialize GPIOs that are controlled by D11 core */
++static void brcms_c_gpio_init(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 gc, gm;
++
++	/* use GPIO select 0 to get all gpio signals from the gpio out reg */
++	brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
++
++	/*
++	 * Common GPIO setup:
++	 *      G0 = LED 0 = WLAN Activity
++	 *      G1 = LED 1 = WLAN 2.4 GHz Radio State
++	 *      G2 = LED 2 = WLAN 5 GHz Radio State
++	 *      G4 = radio disable input (HI enabled, LO disabled)
++	 */
++
++	gc = gm = 0;
++
++	/* Allocate GPIOs for mimo antenna diversity feature */
++	if (wlc_hw->antsel_type == ANTSEL_2x3) {
++		/* Enable antenna diversity, use 2x3 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
++			     MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
++
++		/* init superswitch control */
++		wlc_phy_antsel_init(wlc_hw->band->pi, false);
++
++	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
++		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
++		/*
++		 * The board itself is powered by these GPIOs
++		 * (when not sending pattern) so set them high
++		 */
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_oe),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_out),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++
++		/* Enable antenna diversity, use 2x4 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
++			     BRCM_BAND_ALL);
++
++		/* Configure the desired clock to be 4Mhz */
++		brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
++				   ANTSEL_CLKDIV_4MHZ);
++	}
++
++	/*
++	 * gpio 9 controls the PA. ucode is responsible
++	 * for wiggling out and oe
++	 */
++	if (wlc_hw->boardflags & BFL_PACTRL)
++		gm |= gc |= BOARD_GPIO_PACTRL;
++
++	/* apply to gpiocontrol register */
++	bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
++}
++
++static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
++			      const __le32 ucode[], const size_t nbytes)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	uint i;
++	uint count;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	count = (nbytes / sizeof(u32));
++
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_AUTO_INC | OBJADDR_UCM_SEL);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	for (i = 0; i < count; i++)
++		bcma_write32(core, D11REGOFFS(objdata), le32_to_cpu(ucode[i]));
++
++}
++
++static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	wlc = wlc_hw->wlc;
++
++	if (wlc_hw->ucode_loaded)
++		return;
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
++					  ucode->bcm43xx_16_mimosz);
++			wlc_hw->ucode_loaded = true;
++		} else
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
++					  ucode->bcm43xx_24_lcnsz);
++			wlc_hw->ucode_loaded = true;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
++{
++	/* update sw state */
++	wlc_hw->bmac_phytxant = phytxant;
++
++	/* push to ucode if up */
++	if (!wlc_hw->up)
++		return;
++	brcms_c_ucode_txant_set(wlc_hw);
++
++}
++
++u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
++{
++	return (u16) wlc_hw->wlc->stf->txant;
++}
++
++void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
++{
++	wlc_hw->antsel_type = antsel_type;
++
++	/* Update the antsel type for phy module to use */
++	wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
++}
++
++static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
++{
++	bool fatal = false;
++	uint unit;
++	uint intstatus, idx;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	unit = wlc_hw->unit;
++
++	for (idx = 0; idx < NFIFO; idx++) {
++		/* read intstatus register and ignore any non-error bits */
++		intstatus =
++			bcma_read32(core,
++				    D11REGOFFS(intctrlregs[idx].intstatus)) &
++			I_ERRORS;
++		if (!intstatus)
++			continue;
++
++		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
++			unit, idx, intstatus);
++
++		if (intstatus & I_RO) {
++			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
++				  "overflow\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PC) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
++				 unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PD) {
++			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
++				  idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_DE) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
++				  "error\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_RU)
++			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
++				  "underflow\n", idx, unit);
++
++		if (intstatus & I_XU) {
++			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
++				  "underflow\n", idx, unit);
++			fatal = true;
++		}
++
++		if (fatal) {
++			brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */
++			break;
++		} else
++			bcma_write32(core,
++				     D11REGOFFS(intctrlregs[idx].intstatus),
++				     intstatus);
++	}
++}
++
++void brcms_c_intrson(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	wlc->macintmask = wlc->defmacintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++
++	if (!wlc_hw->clk)
++		return 0;
++
++	macintmask = wlc->macintmask;	/* isr can still happen */
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(macintmask));
++	udelay(1);		/* ensure int line is no longer driven */
++	wlc->macintmask = 0;
++
++	/* return previous macintmask; resolve race between us and our isr */
++	return wlc->macintstatus ? 0 : macintmask;
++}
++
++void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	if (!wlc_hw->clk)
++		return;
++
++	wlc->macintmask = macintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++/* assumes that the d11 MAC is enabled */
++static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
++				    uint tx_fifo)
++{
++	u8 fifo = 1 << tx_fifo;
++
++	/* Two clients of this code, 11h Quiet period and scanning. */
++
++	/* only suspend if not already suspended */
++	if ((wlc_hw->suspended_fifos & fifo) == fifo)
++		return;
++
++	/* force the core awake only if not already */
++	if (wlc_hw->suspended_fifos == 0)
++		brcms_c_ucode_wake_override_set(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++
++	wlc_hw->suspended_fifos |= fifo;
++
++	if (wlc_hw->di[tx_fifo]) {
++		/*
++		 * Suspending AMPDU transmissions in the middle can cause
++		 * underflow which may result in mismatch between ucode and
++		 * driver so suspend the mac before suspending the FIFO
++		 */
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++
++		dma_txsuspend(wlc_hw->di[tx_fifo]);
++
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
++				   uint tx_fifo)
++{
++	/* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
++	 * but need to be done here for PIO otherwise the watchdog will catch
++	 * the inconsistency and fire
++	 */
++	/* Two clients of this code, 11h Quiet period and scanning. */
++	if (wlc_hw->di[tx_fifo])
++		dma_txresume(wlc_hw->di[tx_fifo]);
++
++	/* allow core to sleep again */
++	if (wlc_hw->suspended_fifos == 0)
++		return;
++	else {
++		wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
++		if (wlc_hw->suspended_fifos == 0)
++			brcms_c_ucode_wake_override_clear(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++	}
++}
++
++/* precondition: requires the mac core to be enabled */
++static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
++{
++	static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
++
++	if (mute_tx) {
++		/* suspend tx fifos */
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
++
++		/* zero the address match register so we do not send ACKs */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       null_ether_addr);
++	} else {
++		/* resume tx fifos */
++		brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
++
++		/* Restore address */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       wlc_hw->etheraddr);
++	}
++
++	wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
++
++	if (mute_tx)
++		brcms_c_ucode_mute_override_set(wlc_hw);
++	else
++		brcms_c_ucode_mute_override_clear(wlc_hw);
++}
++
++void
++brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
++{
++	brcms_b_mute(wlc->hw, mute_tx);
++}
++
++/*
++ * Read and clear macintmask and macintstatus and intstatus registers.
++ * This routine should be called with interrupts off
++ * Return:
++ *   -1 if brcms_deviceremoved(wlc) evaluates to true;
++ *   0 if the interrupt is not for us, or we are in some special cases;
++ *   device interrupt status bits otherwise.
++ */
++static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 macintstatus;
++
++	/* macintstatus includes a DMA interrupt summary bit */
++	macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
++		 macintstatus);
++
++	/* detect cardbus removed, in power down(suspend) and in reset */
++	if (brcms_deviceremoved(wlc))
++		return -1;
++
++	/* brcms_deviceremoved() succeeds even when the core is still resetting,
++	 * handle that case here.
++	 */
++	if (macintstatus == 0xffffffff)
++		return 0;
++
++	/* defer unsolicited interrupts */
++	macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
++
++	/* if not for us */
++	if (macintstatus == 0)
++		return 0;
++
++	/* interrupts are already turned off for CFE build
++	 * Caution: For CFE Turning off the interrupts again has some undesired
++	 * consequences
++	 */
++	/* turn off the interrupts */
++	bcma_write32(core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(core, D11REGOFFS(macintmask));
++	wlc->macintmask = 0;
++
++	/* clear device interrupts */
++	bcma_write32(core, D11REGOFFS(macintstatus), macintstatus);
++
++	/* MI_DMAINT is indication of non-zero intstatus */
++	if (macintstatus & MI_DMAINT)
++		/*
++		 * only fifo interrupt enabled is I_RI in
++		 * RX_FIFO. If MI_DMAINT is set, assume it
++		 * is set and clear the interrupt.
++		 */
++		bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intstatus),
++			     DEF_RXINTMASK);
++
++	return macintstatus;
++}
++
++/* Update wlc->macintstatus and wlc->intstatus[]. */
++/* Return true if they are updated successfully. false otherwise */
++bool brcms_c_intrsupd(struct brcms_c_info *wlc)
++{
++	u32 macintstatus;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, false);
++
++	/* device is removed */
++	if (macintstatus == 0xffffffff)
++		return false;
++
++	/* update interrupt status in software */
++	wlc->macintstatus |= macintstatus;
++
++	return true;
++}
++
++/*
++ * First-level interrupt processing.
++ * Return true if this was our interrupt, false otherwise.
++ * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
++ * false otherwise.
++ */
++bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintstatus;
++
++	*wantdpc = false;
++
++	if (!wlc_hw->up || !wlc->macintmask)
++		return false;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, true);
++
++	if (macintstatus == 0xffffffff)
++		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
++			  " path\n");
++
++	/* it is not for us */
++	if (macintstatus == 0)
++		return false;
++
++	*wantdpc = true;
++
++	/* save interrupt status bits */
++	wlc->macintstatus = macintstatus;
++
++	return true;
++
++}
++
++void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth++;
++	if (wlc_hw->mac_suspend_depth > 1)
++		return;
++
++	/* force the core awake */
++	brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(!(mc & MCTL_EN_MAC));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	if (mi == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
++
++	SPINWAIT(!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD),
++		 BRCMS_MAX_MAC_SUSPEND);
++
++	if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
++		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
++			  " and MI_MACSSPNDD is still not on.\n",
++			  wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
++		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
++			  "psm_brc 0x%04x\n", wlc_hw->unit,
++			  bcma_read32(core, D11REGOFFS(psmdebug)),
++			  bcma_read32(core, D11REGOFFS(phydebug)),
++			  bcma_read16(core, D11REGOFFS(psm_brc)));
++	}
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(mc & MCTL_EN_MAC);
++}
++
++void brcms_c_enable_mac(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth--;
++	if (wlc_hw->mac_suspend_depth > 0)
++		return;
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(mc & MCTL_EN_MAC);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_MACSSPNDD);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_EN_MAC));
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_c_ucode_wake_override_clear(wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++}
++
++void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
++{
++	wlc_hw->hw_stf_ss_opmode = stf_mode;
++
++	if (wlc_hw->clk)
++		brcms_upd_ofdm_pctl1_table(wlc_hw);
++}
++
++static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 w, val;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* Validate dchip register access */
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	w = bcma_read32(core, D11REGOFFS(objdata));
++
++	/* Can we write and read back a 32bit register? */
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0xaa5555aa);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0xaa5555aa) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0x55aaaa55);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0x55aaaa55) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), w);
++
++	/* clear CFPStart */
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), 0);
++
++	w = bcma_read32(core, D11REGOFFS(maccontrol));
++	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
++	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
++			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
++			  (MCTL_IHR_EN | MCTL_WAKE),
++			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
++		return false;
++	}
++
++	return true;
++}
++
++#define PHYPLL_WAIT_US	100000
++
++void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 tmp;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	tmp = 0;
++
++	if (on) {
++		if ((ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   CCS_ERSRC_REQ_HT |
++				   CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT,
++				 PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
++					  " PLL failed\n", __func__);
++		} else {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   tmp | CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  (CCS_ERSRC_AVAIL_D11PLL |
++				   CCS_ERSRC_AVAIL_PHYPLL)) !=
++				 (CCS_ERSRC_AVAIL_D11PLL |
++				  CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp &
++			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++			    !=
++			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
++					  "PHY PLL failed\n", __func__);
++		}
++	} else {
++		/*
++		 * Since the PLL may be shared, other cores can still
++		 * be requesting it; so we'll deassert the request but
++		 * not wait for status to comply.
++		 */
++		bcma_mask32(core, D11REGOFFS(clk_ctl_st),
++			    ~CCS_ERSRC_REQ_PHYPLL);
++		(void)bcma_read32(core, D11REGOFFS(clk_ctl_st));
++	}
++}
++
++static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone)
++		return;
++
++	if (wlc_hw->noreset)
++		return;
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	/* turn off analog core */
++	wlc_phy_anacore(wlc_hw->band->pi, OFF);
++
++	/* turn off PHYPLL to save power */
++	brcms_b_core_phypll_ctl(wlc_hw, false);
++
++	wlc_hw->clk = false;
++	bcma_core_disable(wlc_hw->d11core, 0);
++	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++}
++
++static void brcms_c_flushqueues(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint i;
++
++	/* free any posted tx packets */
++	for (i = 0; i < NFIFO; i++)
++		if (wlc_hw->di[i]) {
++			dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
++			wlc->core->txpktpend[i] = 0;
++			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
++		}
++
++	/* free any posted rx packets */
++	dma_rxreclaim(wlc_hw->di[RX_FIFO]);
++}
++
++static u16
++brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	return bcma_read16(core, objoff);
++}
++
++static void
++brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
++		     u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	bcma_write16(core, objoff, v);
++}
++
++/*
++ * Read a single u16 from shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
++{
++	return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Write a single u16 to shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
++{
++	brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Copy a buffer to shared memory of specified type .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
++		      const void *buf, int len, u32 sel)
++{
++	u16 v;
++	const u8 *p = (const u8 *)buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = p[i] | (p[i + 1] << 8);
++		brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
++	}
++}
++
++/*
++ * Copy a piece of shared memory of specified type to a buffer .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
++			 int len, u32 sel)
++{
++	u16 v;
++	u8 *p = (u8 *) buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
++		p[i] = v & 0xFF;
++		p[i + 1] = (v >> 8) & 0xFF;
++	}
++}
++
++/* Copy a buffer to shared memory.
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ */
++static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
++			const void *buf, int len)
++{
++	brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
++}
++
++static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
++				   u16 SRL, u16 LRL)
++{
++	wlc_hw->SRL = SRL;
++	wlc_hw->LRL = LRL;
++
++	/* write retry limit to SCR, shouldn't need to suspend */
++	if (wlc_hw->up) {
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->SRL);
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->LRL);
++	}
++}
++
++static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
++{
++	if (set) {
++		if (mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolset(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (!wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, ON);
++		}
++	} else {
++		if (!mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolclr(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++}
++
++static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
++{
++	wlc_hw->antsel_avail = antsel_avail;
++}
++
++/*
++ * conditions under which the PM bit should be set in outgoing frames
++ * and STAY_AWAKE is meaningful
++ */
++static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *cfg = wlc->bsscfg;
++
++	/* disallow PS when one of the following global conditions meets */
++	if (!wlc->pub->associated)
++		return false;
++
++	/* disallow PS when one of these meets when not scanning */
++	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
++		return false;
++
++	if (cfg->associated) {
++		/*
++		 * disallow PS when one of the following
++		 * bsscfg specific conditions meets
++		 */
++		if (!cfg->BSS)
++			return false;
++
++		return false;
++	}
++
++	return true;
++}
++
++static void brcms_c_statsupd(struct brcms_c_info *wlc)
++{
++	int i;
++	struct macstat macstats;
++#ifdef DEBUG
++	u16 delta;
++	u16 rxf0ovfl;
++	u16 txfunfl[NFIFO];
++#endif				/* DEBUG */
++
++	/* if driver down, make no sense to update stats */
++	if (!wlc->pub->up)
++		return;
++
++#ifdef DEBUG
++	/* save last rx fifo 0 overflow count */
++	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
++
++	/* save last tx fifo  underflow count */
++	for (i = 0; i < NFIFO; i++)
++		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
++#endif				/* DEBUG */
++
++	/* Read mac stats from contiguous shared memory */
++	brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
++				sizeof(struct macstat), OBJADDR_SHM_SEL);
++
++#ifdef DEBUG
++	/* check for rx fifo 0 overflow */
++	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
++	if (delta)
++		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
++			  wlc->pub->unit, delta);
++
++	/* check for tx fifo underflows */
++	for (i = 0; i < NFIFO; i++) {
++		delta =
++		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
++			      txfunfl[i]);
++		if (delta)
++			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
++				  "\n", wlc->pub->unit, delta, i);
++	}
++#endif				/* DEBUG */
++
++	/* merge counters from dma module */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc->hw->di[i])
++			dma_counterreset(wlc->hw->di[i]);
++	}
++}
++
++static void brcms_b_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset the core */
++	if (!brcms_deviceremoved(wlc_hw->wlc))
++		brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	/* purge the dma rings */
++	brcms_c_flushqueues(wlc_hw->wlc);
++}
++
++void brcms_c_reset(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* slurp up hw mac counters before core reset */
++	brcms_c_statsupd(wlc);
++
++	/* reset our snapshot of macstat counters */
++	memset((char *)wlc->core->macstat_snapshot, 0,
++		sizeof(struct macstat));
++
++	brcms_b_reset(wlc->hw);
++}
++
++/* Return the channel the driver should initialize during brcms_c_init.
++ * the channel may have to be changed from the currently configured channel
++ * if other configurations are in conflict (bandlocked, 11n mode disabled,
++ * invalid channel for current country, etc.)
++ */
++static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
++{
++	u16 chanspec =
++	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
++	    WL_CHANSPEC_BAND_2G;
++
++	return chanspec;
++}
++
++void brcms_c_init_scb(struct scb *scb)
++{
++	int i;
++
++	memset(scb, 0, sizeof(struct scb));
++	scb->flags = SCB_WMECAP | SCB_HTCAP;
++	for (i = 0; i < NUMPRIO; i++) {
++		scb->seqnum[i] = 0;
++		scb->seqctl[i] = 0xFFFF;
++	}
++
++	scb->seqctl_nonqos = 0xFFFF;
++	scb->magic = SCB_MAGIC;
++}
++
++/* d11 core init
++ *   reset PSM
++ *   download ucode/PCM
++ *   let ucode run to suspended
++ *   download ucode inits
++ *   config other core registers
++ *   init dma
++ */
++static void brcms_b_coreinit(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 sflags;
++	u32 bcnint_us;
++	uint i = 0;
++	bool fifosz_fixup = false;
++	int err = 0;
++	u16 buf[NFIFO];
++	struct wiphy *wiphy = wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset PSM */
++	brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
++
++	brcms_ucode_download(wlc_hw);
++	/*
++	 * FIFOSZ fixup. driver wants to controls the fifo allocation.
++	 */
++	fifosz_fixup = true;
++
++	/* let the PSM run to the suspended state, set mode to BSS STA */
++	bcma_write32(core, D11REGOFFS(macintstatus), -1);
++	brcms_b_mctrl(wlc_hw, ~0,
++		       (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
++
++	/* wait for ucode to self-suspend after auto-init */
++	SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
++		   MI_MACSSPNDD) == 0), 1000 * 1000);
++	if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
++		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
++			  "suspend!\n", wlc_hw->unit);
++
++	brcms_c_gpio_init(wlc);
++
++	sflags = bcma_aread32(core, BCMA_IOST);
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++			  __func__, wlc_hw->unit, wlc_hw->corerev);
++	}
++
++	/* For old ucode, txfifo sizes needs to be modified(increased) */
++	if (fifosz_fixup)
++		brcms_b_corerev_fifofixup(wlc_hw);
++
++	/* check txfifo allocations match between ucode and driver */
++	buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
++	if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
++		i = TX_AC_BE_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
++	if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
++		i = TX_AC_VI_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
++	buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
++	buf[TX_AC_BK_FIFO] &= 0xff;
++	if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
++		i = TX_AC_BK_FIFO;
++		err = -1;
++	}
++	if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
++		i = TX_AC_VO_FIFO;
++		err = -1;
++	}
++	buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
++	buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
++	buf[TX_BCMC_FIFO] &= 0xff;
++	if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
++		i = TX_BCMC_FIFO;
++		err = -1;
++	}
++	if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
++		i = TX_ATIM_FIFO;
++		err = -1;
++	}
++	if (err != 0)
++		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
++			  " driver size %d index %d\n", buf[i],
++			  wlc_hw->xmtfifo_sz[i], i);
++
++	/* make sure we can still talk to the mac */
++	WARN_ON(bcma_read32(core, D11REGOFFS(maccontrol)) == 0xffffffff);
++
++	/* band-specific inits done by wlc_bsinit() */
++
++	/* Set up frame burst size and antenna swap threshold init values */
++	brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
++	brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
++
++	/* enable one rx interrupt per received frame */
++	bcma_write32(core, D11REGOFFS(intrcvlazy[0]), (1 << IRL_FC_SHIFT));
++
++	/* set the station mode (BSS STA) */
++	brcms_b_mctrl(wlc_hw,
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ));
++
++	/* set up Beacon interval */
++	bcnint_us = 0x8000 << 10;
++	bcma_write32(core, D11REGOFFS(tsf_cfprep),
++		     (bcnint_us << CFPREP_CBI_SHIFT));
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), bcnint_us);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_GP1);
++
++	/* write interrupt mask */
++	bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intmask),
++		     DEF_RXINTMASK);
++
++	/* allow the MAC to control the PHY clock (dynamic on/off) */
++	brcms_b_macphyclk_set(wlc_hw, ON);
++
++	/* program dynamic clock control fast powerup delay register */
++	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
++	bcma_write16(core, D11REGOFFS(scc_fastpwrup_dly), wlc->fastpwrup_dly);
++
++	/* tell the ucode the corerev */
++	brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
++
++	/* tell the ucode MAC capabilities */
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
++			   (u16) (wlc_hw->machwcap & 0xffff));
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
++			   (u16) ((wlc_hw->
++				      machwcap >> 16) & 0xffff));
++
++	/* write retry limits to SCR, this done after PSM init */
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->SRL);
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->LRL);
++
++	/* write rate fallback retry limits */
++	brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
++	brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
++
++	bcma_mask16(core, D11REGOFFS(ifs_ctl), 0x0FFF);
++	bcma_write16(core, D11REGOFFS(ifs_aifsn), EDCF_AIFSN_MIN);
++
++	/* init the tx dma engines */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc_hw->di[i])
++			dma_txinit(wlc_hw->di[i]);
++	}
++
++	/* init the rx dma engine(s) and post receive buffers */
++	dma_rxinit(wlc_hw->di[RX_FIFO]);
++	dma_rxfill(wlc_hw->di[RX_FIFO]);
++}
++
++void
++static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
++	u32 macintmask;
++	bool fastclk;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* set up the specified band and chanspec */
++	brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
++	wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++
++	/* do one-time phy inits and calibration */
++	wlc_phy_cal_init(wlc_hw->band->pi);
++
++	/* core-specific initialization */
++	brcms_b_coreinit(wlc);
++
++	/* band-specific inits */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
++	 * is suspended and brcms_c_enable_mac() will clear this override bit.
++	 */
++	mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	/*
++	 * initialize mac_suspend_depth to 1 to match ucode
++	 * initial suspended state
++	 */
++	wlc_hw->mac_suspend_depth = 1;
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	/* Save our copy of the chanspec */
++	wlc->chanspec = chanspec;
++
++	/* Set the chanspec and power limits for this locale */
++	brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
++
++	if (wlc->stf->ss_algosel_auto)
++		brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
++					    chanspec);
++
++	brcms_c_stf_ss_update(wlc, wlc->band);
++}
++
++static void
++brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
++{
++	brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
++		wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(wlc->default_bss->chanspec),
++		wlc->stf->txstreams);
++}
++
++/* derive wlc->band->basic_rate[] table from 'rateset' */
++static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
++			      struct brcms_c_rateset *rateset)
++{
++	u8 rate;
++	u8 mandatory;
++	u8 cck_basic = 0;
++	u8 ofdm_basic = 0;
++	u8 *br = wlc->band->basic_rate;
++	uint i;
++
++	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
++	memset(br, 0, BRCM_MAXRATE + 1);
++
++	/* For each basic rate in the rates list, make an entry in the
++	 * best basic lookup.
++	 */
++	for (i = 0; i < rateset->count; i++) {
++		/* only make an entry for a basic rate */
++		if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
++			continue;
++
++		/* mask off basic bit */
++		rate = (rateset->rates[i] & BRCMS_RATE_MASK);
++
++		if (rate > BRCM_MAXRATE) {
++			wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
++				  "invalid rate 0x%X in rate set\n",
++				  rateset->rates[i]);
++			continue;
++		}
++
++		br[rate] = rate;
++	}
++
++	/* The rate lookup table now has non-zero entries for each
++	 * basic rate, equal to the basic rate: br[basicN] = basicN
++	 *
++	 * To look up the best basic rate corresponding to any
++	 * particular rate, code can use the basic_rate table
++	 * like this
++	 *
++	 * basic_rate = wlc->band->basic_rate[tx_rate]
++	 *
++	 * Make sure there is a best basic rate entry for
++	 * every rate by walking up the table from low rates
++	 * to high, filling in holes in the lookup table
++	 */
++
++	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
++		rate = wlc->band->hw_rateset.rates[i];
++
++		if (br[rate] != 0) {
++			/* This rate is a basic rate.
++			 * Keep track of the best basic rate so far by
++			 * modulation type.
++			 */
++			if (is_ofdm_rate(rate))
++				ofdm_basic = rate;
++			else
++				cck_basic = rate;
++
++			continue;
++		}
++
++		/* This rate is not a basic rate so figure out the
++		 * best basic rate less than this rate and fill in
++		 * the hole in the table
++		 */
++
++		br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
++
++		if (br[rate] != 0)
++			continue;
++
++		if (is_ofdm_rate(rate)) {
++			/*
++			 * In 11g and 11a, the OFDM mandatory rates
++			 * are 6, 12, and 24 Mbps
++			 */
++			if (rate >= BRCM_RATE_24M)
++				mandatory = BRCM_RATE_24M;
++			else if (rate >= BRCM_RATE_12M)
++				mandatory = BRCM_RATE_12M;
++			else
++				mandatory = BRCM_RATE_6M;
++		} else {
++			/* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
++			mandatory = rate;
++		}
++
++		br[rate] = mandatory;
++	}
++}
++
++static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	struct brcms_c_rateset default_rateset;
++	uint parkband;
++	uint i, band_order[2];
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++	/*
++	 * We might have been bandlocked during down and the chip
++	 * power-cycled (hibernate). Figure out the right band to park on
++	 */
++	if (wlc->bandlocked || wlc->pub->_nbands == 1) {
++		/* updated in brcms_c_bandlock() */
++		parkband = wlc->band->bandunit;
++		band_order[0] = band_order[1] = parkband;
++	} else {
++		/* park on the band of the specified chanspec */
++		parkband = chspec_bandunit(chanspec);
++
++		/* order so that parkband initialize last */
++		band_order[0] = parkband ^ 1;
++		band_order[1] = parkband;
++	}
++
++	/* make each band operational, software state init */
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		uint j = band_order[i];
++
++		wlc->band = wlc->bandstate[j];
++
++		brcms_default_rateset(wlc, &default_rateset);
++
++		/* fill in hw_rate */
++		brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
++				   false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++
++		/* init basic rate lookup */
++		brcms_c_rate_lookup_init(wlc, &default_rateset);
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++}
++
++/*
++ * Set or clear filtering related maccontrol bits based on
++ * specified filter flags
++ */
++void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
++{
++	u32 promisc_bits = 0;
++
++	wlc->filter_flags = filter_flags;
++
++	if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
++		promisc_bits |= MCTL_PROMISC;
++
++	if (filter_flags & FIF_BCN_PRBRESP_PROMISC)
++		promisc_bits |= MCTL_BCNS_PROMISC;
++
++	if (filter_flags & FIF_FCSFAIL)
++		promisc_bits |= MCTL_KEEPBADFCS;
++
++	if (filter_flags & (FIF_CONTROL | FIF_PSPOLL))
++		promisc_bits |= MCTL_KEEPCONTROL;
++
++	brcms_b_mctrl(wlc->hw,
++		MCTL_PROMISC | MCTL_BCNS_PROMISC |
++		MCTL_KEEPCONTROL | MCTL_KEEPBADFCS,
++		promisc_bits);
++}
++
++/*
++ * ucode, hwmac update
++ *    Channel dependent updates for ucode and hw
++ */
++static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
++{
++	/* enable or disable any active IBSSs depending on whether or not
++	 * we are on the home channel
++	 */
++	if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
++		if (wlc->pub->associated) {
++			/*
++			 * BMAC_NOTE: This is something that should be fixed
++			 * in ucode inits. I think that the ucode inits set
++			 * up the bcn templates and shm values with a bogus
++			 * beacon. This should not be done in the inits. If
++			 * ucode needs to set up a beacon for testing, the
++			 * test routines should write it down, not expect the
++			 * inits to populate a bogus beacon.
++			 */
++			if (BRCMS_PHY_11N_CAP(wlc->band))
++				brcms_b_write_shm(wlc->hw,
++						M_BCN_TXTSF_OFFSET, 0);
++		}
++	} else {
++		/* disable an active IBSS if we are not on the home channel */
++	}
++}
++
++static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
++				   u8 basic_rate)
++{
++	u8 phy_rate, index;
++	u8 basic_phy_rate, basic_index;
++	u16 dir_table, basic_table;
++	u16 basic_ptr;
++
++	/* Shared memory address for the table we are reading */
++	dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
++
++	/* Shared memory address for the table we are writing */
++	basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
++
++	/*
++	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++	basic_index = basic_phy_rate & 0xf;
++
++	/* Find the SHM pointer to the ACK rate entry by looking in the
++	 * Direct-map Table
++	 */
++	basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
++
++	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
++	 * to the correct basic rate for the given incoming rate
++	 */
++	brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
++}
++
++static const struct brcms_c_rateset *
++brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (wlc->band->bandtype == BRCM_BAND_5G)
++			rs_dflt = &ofdm_mimo_rates;
++		else
++			rs_dflt = &cck_ofdm_mimo_rates;
++	} else if (wlc->band->gmode)
++		rs_dflt = &cck_ofdm_rates;
++	else
++		rs_dflt = &cck_rates;
++
++	return rs_dflt;
++}
++
++static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate, basic_rate;
++	uint i;
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/* walk the phy rate table and update SHM basic rate lookup table */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		/* for a given rate brcms_basic_rate returns the rate at
++		 * which a response ACK/CTS should be sent.
++		 */
++		basic_rate = brcms_basic_rate(wlc, rate);
++		if (basic_rate == 0)
++			/* This should only happen if we are using a
++			 * restricted rateset.
++			 */
++			basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
++
++		brcms_c_write_rate_shm(wlc, rate, basic_rate);
++	}
++}
++
++/* band-specific init */
++static void brcms_c_bsinit(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
++		 wlc->pub->unit, wlc->band->bandunit);
++
++	/* write ucode ACK/CTS rate table */
++	brcms_c_set_ratetable(wlc);
++
++	/* update some band specific mac configuration */
++	brcms_c_ucode_mac_upd(wlc);
++
++	/* init antenna selection */
++	brcms_c_antsel_init(wlc->asi);
++
++}
++
++/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
++static int
++brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
++		   bool writeToShm)
++{
++	int idle_busy_ratio_x_16 = 0;
++	uint offset =
++	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
++	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
++	if (duty_cycle > 100 || duty_cycle < 0) {
++		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
++			  wlc->pub->unit);
++		return -EINVAL;
++	}
++	if (duty_cycle)
++		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
++	/* Only write to shared memory  when wl is up */
++	if (writeToShm)
++		brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16);
++
++	if (isOFDM)
++		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
++	else
++		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
++
++	return 0;
++}
++
++/*
++ * Initialize the base precedence map for dequeueing
++ * from txq based on WME settings
++ */
++static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
++{
++	wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
++	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
++
++	wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
++	wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
++	wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
++	wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
++}
++
++static void
++brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi, bool on, int prio)
++{
++	/* transmit flowcontrol is not yet implemented */
++}
++
++static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi;
++
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
++		if (qi->stopped) {
++			brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
++			qi->stopped = 0;
++		}
++	}
++}
++
++/* push sw hps and wake state through hardware */
++static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
++{
++	u32 v1, v2;
++	bool hps;
++	bool awake_before;
++
++	hps = brcms_c_ps_allowed(wlc);
++
++	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
++
++	v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
++	v2 = MCTL_WAKE;
++	if (hps)
++		v2 |= MCTL_HPS;
++
++	brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
++
++	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
++
++	if (!awake_before)
++		brcms_b_wait_for_wake(wlc->hw);
++}
++
++/*
++ * Write this BSS config's MAC address to core.
++ * Updates RXE match engine.
++ */
++static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
++{
++	int err = 0;
++	struct brcms_c_info *wlc = bsscfg->wlc;
++
++	/* enter the MAC addr into the RXE match registers */
++	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
++
++	brcms_c_ampdu_macaddr_upd(wlc);
++
++	return err;
++}
++
++/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
++ * Updates RXE match engine.
++ */
++static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
++{
++	/* we need to update BSSID in RXE match registers */
++	brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
++}
++
++static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
++{
++	wlc_hw->shortslot = shortslot;
++
++	if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) {
++		brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++		brcms_b_update_slot_timing(wlc_hw, shortslot);
++		brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++/*
++ * Suspend the the MAC and update the slot timing
++ * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
++ */
++static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
++{
++	/* use the override if it is set */
++	if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
++		shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
++
++	if (wlc->shortslot == shortslot)
++		return;
++
++	wlc->shortslot = shortslot;
++
++	brcms_b_set_shortslot(wlc->hw, shortslot);
++}
++
++static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	if (wlc->home_chanspec != chanspec) {
++		wlc->home_chanspec = chanspec;
++
++		if (wlc->bsscfg->associated)
++			wlc->bsscfg->current_bss->chanspec = chanspec;
++	}
++}
++
++void
++brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
++		      bool mute_tx, struct txpwr_limits *txpwr)
++{
++	uint bandunit;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
++
++	wlc_hw->chanspec = chanspec;
++
++	/* Switch bands if necessary */
++	if (wlc_hw->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc_hw->band->bandunit != bandunit) {
++			/* brcms_b_setband disables other bandunit,
++			 *  use light band switch if not up yet
++			 */
++			if (wlc_hw->up) {
++				wlc_phy_chanspec_radio_set(wlc_hw->
++							   bandstate[bandunit]->
++							   pi, chanspec);
++				brcms_b_setband(wlc_hw, bandunit, chanspec);
++			} else {
++				brcms_c_setxband(wlc_hw, bandunit);
++			}
++		}
++	}
++
++	wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx);
++
++	if (!wlc_hw->up) {
++		if (wlc_hw->clk)
++			wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
++						  chanspec);
++		wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++	} else {
++		wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
++		wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
++
++		/* Update muting of the channel */
++		brcms_b_mute(wlc_hw, mute_tx);
++	}
++}
++
++/* switch to and initialize new band */
++static void brcms_c_setband(struct brcms_c_info *wlc,
++					   uint bandunit)
++{
++	wlc->band = wlc->bandstate[bandunit];
++
++	if (!wlc->pub->up)
++		return;
++
++	/* wait for at least one beacon before entering sleeping state */
++	brcms_c_set_ps_ctrl(wlc);
++
++	/* band-specific initializations */
++	brcms_c_bsinit(wlc);
++}
++
++static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	uint bandunit;
++	bool switchband = false;
++	u16 old_chanspec = wlc->chanspec;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
++			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
++		return;
++	}
++
++	/* Switch bands if necessary */
++	if (wlc->pub->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
++			switchband = true;
++			if (wlc->bandlocked) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
++					  "band is locked!\n",
++					  wlc->pub->unit, __func__,
++					  CHSPEC_CHANNEL(chanspec));
++				return;
++			}
++			/*
++			 * should the setband call come after the
++			 * brcms_b_chanspec() ? if the setband updates
++			 * (brcms_c_bsinit) use low level calls to inspect and
++			 * set state, the state inspected may be from the wrong
++			 * band, or the following brcms_b_set_chanspec() may
++			 * undo the work.
++			 */
++			brcms_c_setband(wlc, bandunit);
++		}
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++
++	/* init antenna selection */
++	if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
++		brcms_c_antsel_init(wlc->asi);
++
++		/* Fix the hardware rateset based on bw.
++		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
++		 */
++		brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
++			wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
++	}
++
++	/* update some mac configuration since chanspec changed */
++	brcms_c_ucode_mac_upd(wlc);
++}
++
++/*
++ * This function changes the phytxctl for beacon based on current
++ * beacon ratespec AND txant setting as per this table:
++ *  ratespec     CCK		ant = wlc->stf->txant
++ *		OFDM		ant = 3
++ */
++void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++				       u32 bcn_rspec)
++{
++	u16 phyctl;
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_PHY_11N_CAP(wlc->band))
++		phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
++
++	phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl);
++}
++
++/*
++ * centralized protection config change function to simplify debugging, no
++ * consistency checking this should be called only on changes to avoid overhead
++ * in periodic function
++ */
++void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
++{
++	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
++
++	switch (idx) {
++	case BRCMS_PROT_G_SPEC:
++		wlc->protection->_g = (bool) val;
++		break;
++	case BRCMS_PROT_G_OVR:
++		wlc->protection->g_override = (s8) val;
++		break;
++	case BRCMS_PROT_G_USER:
++		wlc->protection->gmode_user = (u8) val;
++		break;
++	case BRCMS_PROT_OVERLAP:
++		wlc->protection->overlap = (s8) val;
++		break;
++	case BRCMS_PROT_N_USER:
++		wlc->protection->nmode_user = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG:
++		wlc->protection->n_cfg = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG_OVR:
++		wlc->protection->n_cfg_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_NONGF:
++		wlc->protection->nongf = (bool) val;
++		break;
++	case BRCMS_PROT_N_NONGF_OVR:
++		wlc->protection->nongf_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_PAM_OVR:
++		wlc->protection->n_pam_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_OBSS:
++		wlc->protection->n_obss = (bool) val;
++		break;
++
++	default:
++		break;
++	}
++
++}
++
++static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
++{
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
++{
++	wlc->stf->ldpc = val;
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
++	}
++}
++
++void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++		       const struct ieee80211_tx_queue_params *params,
++		       bool suspend)
++{
++	int i;
++	struct shm_acparams acp_shm;
++	u16 *shm_entry;
++
++	/* Only apply params if the core is out of reset and has clocks */
++	if (!wlc->clk) {
++		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
++			  __func__);
++		return;
++	}
++
++	memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
++	/* fill in shm ac params struct */
++	acp_shm.txop = params->txop;
++	/* convert from units of 32us to us for ucode */
++	wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
++	    EDCF_TXOP2USEC(acp_shm.txop);
++	acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
++
++	if (aci == IEEE80211_AC_VI && acp_shm.txop == 0
++	    && acp_shm.aifs < EDCF_AIFSN_MAX)
++		acp_shm.aifs++;
++
++	if (acp_shm.aifs < EDCF_AIFSN_MIN
++	    || acp_shm.aifs > EDCF_AIFSN_MAX) {
++		wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
++			  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
++	} else {
++		acp_shm.cwmin = params->cw_min;
++		acp_shm.cwmax = params->cw_max;
++		acp_shm.cwcur = acp_shm.cwmin;
++		acp_shm.bslots =
++			bcma_read16(wlc->hw->d11core, D11REGOFFS(tsf_random)) &
++			acp_shm.cwcur;
++		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
++		/* Indicate the new params to the ucode */
++		acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO +
++						  wme_ac2fifo[aci] *
++						  M_EDCF_QLEN +
++						  M_EDCF_STATUS_OFF));
++		acp_shm.status |= WME_STATUS_NEWAC;
++
++		/* Fill in shm acparam table */
++		shm_entry = (u16 *) &acp_shm;
++		for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
++			brcms_b_write_shm(wlc->hw,
++					  M_EDCF_QINFO +
++					  wme_ac2fifo[aci] * M_EDCF_QLEN + i,
++					  *shm_entry++);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
++{
++	u16 aci;
++	int i_ac;
++	struct ieee80211_tx_queue_params txq_pars;
++	static const struct edcf_acparam default_edcf_acparams[] = {
++		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
++		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
++		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
++		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
++	}; /* ucode needs these parameters during its initialization */
++	const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
++
++	for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) {
++		/* find out which ac this set of params applies to */
++		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
++
++		/* fill in shm ac params struct */
++		txq_pars.txop = edcf_acp->TXOP;
++		txq_pars.aifs = edcf_acp->ACI;
++
++		/* CWmin = 2^(ECWmin) - 1 */
++		txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
++		/* CWmax = 2^(ECWmax) - 1 */
++		txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
++					    >> EDCF_ECWMAX_SHIFT);
++		brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
++{
++	/* Don't start the timer if HWRADIO feature is disabled */
++	if (wlc->radio_monitor)
++		return;
++
++	wlc->radio_monitor = true;
++	brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
++	brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
++}
++
++static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
++{
++	if (!wlc->radio_monitor)
++		return true;
++
++	wlc->radio_monitor = false;
++	brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
++	return brcms_del_timer(wlc->radio_timer);
++}
++
++/* read hwdisable state and propagate to wlc flag */
++static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
++{
++	if (wlc->pub->hw_off)
++		return;
++
++	if (brcms_b_radio_read_hwdisabled(wlc->hw))
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++	else
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++}
++
++/* update hwradio status and return it */
++bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
++{
++	brcms_c_radio_hwdisable_upd(wlc);
++
++	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
++			true : false;
++}
++
++/* periodical query hw radio button while driver is "down" */
++static void brcms_c_radio_timer(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			__func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	brcms_c_radio_hwdisable_upd(wlc);
++}
++
++/* common low-level watchdog code */
++static void brcms_b_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return;
++
++	/* increment second count */
++	wlc_hw->now++;
++
++	/* Check for FIFO error interrupts */
++	brcms_b_fifoerrors(wlc_hw);
++
++	/* make sure RX dma has buffers */
++	dma_rxfill(wlc->hw->di[RX_FIFO]);
++
++	wlc_phy_watchdog(wlc_hw->band->pi);
++}
++
++/* common watchdog code */
++static void brcms_c_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	if (!wlc->pub->up)
++		return;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	/* increment second count */
++	wlc->pub->now++;
++
++	brcms_c_radio_hwdisable_upd(wlc);
++	/* if radio is disable, driver may be down, quit here */
++	if (wlc->pub->radio_disabled)
++		return;
++
++	brcms_b_watchdog(wlc);
++
++	/*
++	 * occasionally sample mac stat counters to
++	 * detect 16-bit counter wrap
++	 */
++	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
++		brcms_c_statsupd(wlc);
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
++	     BRCMS_TEMPSENSE_PERIOD)) {
++		wlc->tempsense_lasttime = wlc->pub->now;
++		brcms_c_tempsense_upd(wlc);
++	}
++}
++
++static void brcms_c_watchdog_by_timer(void *arg)
++{
++	brcms_c_watchdog(arg);
++}
++
++static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
++{
++	wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
++		wlc, "watchdog");
++	if (!wlc->wdtimer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
++		wlc, "radio");
++	if (!wlc->radio_timer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	return true;
++
++ fail:
++	return false;
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ */
++static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
++{
++	int i;
++
++	/* Save our copy of the chanspec */
++	wlc->chanspec = ch20mhz_chspec(1);
++
++	/* various 802.11g modes */
++	wlc->shortslot = false;
++	wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
++			       BRCMS_PROTECTION_CTL_OVERLAP);
++
++	/* 802.11g draft 4.0 NonERP elt advertisement */
++	wlc->include_legacy_erp = true;
++
++	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
++	wlc->stf->txant = ANT_TX_DEF;
++
++	wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
++
++	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
++	for (i = 0; i < NFIFO; i++)
++		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
++	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
++
++	/* default rate fallback retry limits */
++	wlc->SFBL = RETRY_SHORT_FB;
++	wlc->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc->SRL = RETRY_SHORT_DEF;
++	wlc->LRL = RETRY_LONG_DEF;
++
++	/* WME QoS mode is Auto by default */
++	wlc->pub->_ampdu = AMPDU_AGG_HOST;
++	wlc->pub->bcmerror = 0;
++}
++
++static uint brcms_c_attach_module(struct brcms_c_info *wlc)
++{
++	uint err = 0;
++	uint unit;
++	unit = wlc->pub->unit;
++
++	wlc->asi = brcms_c_antsel_attach(wlc);
++	if (wlc->asi == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
++			  "failed\n", unit);
++		err = 44;
++		goto fail;
++	}
++
++	wlc->ampdu = brcms_c_ampdu_attach(wlc);
++	if (wlc->ampdu == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
++			  "failed\n", unit);
++		err = 50;
++		goto fail;
++	}
++
++	if ((brcms_c_stf_attach(wlc) != 0)) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
++			  "failed\n", unit);
++		err = 68;
++		goto fail;
++	}
++ fail:
++	return err;
++}
++
++struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
++{
++	return wlc->pub;
++}
++
++/* low level attach
++ *    run backplane attach, init nvram
++ *    run phy attach
++ *    initialize software state for each core and band
++ *    put the whole chip in reset(driver down state), no clock
++ */
++static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
++			  uint unit, bool piomode)
++{
++	struct brcms_hardware *wlc_hw;
++	uint err = 0;
++	uint j;
++	bool wme = false;
++	struct shared_phy_params sha_params;
++	struct wiphy *wiphy = wlc->wiphy;
++	struct pci_dev *pcidev = core->bus->host_pci;
++	struct ssb_sprom *sprom = &core->bus->sprom;
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       pcidev->vendor,
++		       pcidev->device);
++	else
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       core->bus->boardinfo.vendor,
++		       core->bus->boardinfo.type);
++
++	wme = true;
++
++	wlc_hw = wlc->hw;
++	wlc_hw->wlc = wlc;
++	wlc_hw->unit = unit;
++	wlc_hw->band = wlc_hw->bandstate[0];
++	wlc_hw->_piomode = piomode;
++
++	/* populate struct brcms_hardware with default values  */
++	brcms_b_info_init(wlc_hw);
++
++	/*
++	 * Do the hardware portion of the attach. Also initialize software
++	 * state that depends on the particular hardware we are running.
++	 */
++	wlc_hw->sih = ai_attach(core->bus);
++	if (wlc_hw->sih == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
++			  unit);
++		err = 11;
++		goto fail;
++	}
++
++	/* verify again the device is supported */
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI &&
++	    !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
++			"vendor/device (0x%x/0x%x)\n",
++			 unit, pcidev->vendor, pcidev->device);
++		err = 12;
++		goto fail;
++	}
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
++		wlc_hw->vendorid = pcidev->vendor;
++		wlc_hw->deviceid = pcidev->device;
++	} else {
++		wlc_hw->vendorid = core->bus->boardinfo.vendor;
++		wlc_hw->deviceid = core->bus->boardinfo.type;
++	}
++
++	wlc_hw->d11core = core;
++	wlc_hw->corerev = core->id.rev;
++
++	/* validate chip, chiprev and corerev */
++	if (!brcms_c_isgoodchip(wlc_hw)) {
++		err = 13;
++		goto fail;
++	}
++
++	/* initialize power control registers */
++	ai_clkctl_init(wlc_hw->sih);
++
++	/* request fastclock and force fastclock for the rest of attach
++	 * bring the d11 core out of reset.
++	 *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
++	 *   is still false; But it will be called again inside wlc_corereset,
++	 *   after d11 is out of reset.
++	 */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	if (!brcms_b_validate_chip_access(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
++			"failed\n", unit);
++		err = 14;
++		goto fail;
++	}
++
++	/* get the board rev, used just below */
++	j = sprom->board_rev;
++	/* promote srom boardrev of 0xFF to 1 */
++	if (j == BOARDREV_PROMOTABLE)
++		j = BOARDREV_PROMOTED;
++	wlc_hw->boardrev = (u16) j;
++	if (!brcms_c_validboardtype(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
++			  "board type (0x%x)" " or revision level (0x%x)\n",
++			  unit, ai_get_boardtype(wlc_hw->sih),
++			  wlc_hw->boardrev);
++		err = 15;
++		goto fail;
++	}
++	wlc_hw->sromrev = sprom->revision;
++	wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
++	wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
++
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
++
++	/* check device id(srom, nvram etc.) to set bands */
++	if (wlc_hw->deviceid == BCM43224_D11N_ID ||
++	    wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
++		/* Dualband boards */
++		wlc_hw->_nbands = 2;
++	else
++		wlc_hw->_nbands = 1;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID))
++		wlc_hw->_nbands = 1;
++
++	/* BMAC_NOTE: remove init of pub values when brcms_c_attach()
++	 * unconditionally does the init of these values
++	 */
++	wlc->vendorid = wlc_hw->vendorid;
++	wlc->deviceid = wlc_hw->deviceid;
++	wlc->pub->sih = wlc_hw->sih;
++	wlc->pub->corerev = wlc_hw->corerev;
++	wlc->pub->sromrev = wlc_hw->sromrev;
++	wlc->pub->boardrev = wlc_hw->boardrev;
++	wlc->pub->boardflags = wlc_hw->boardflags;
++	wlc->pub->boardflags2 = wlc_hw->boardflags2;
++	wlc->pub->_nbands = wlc_hw->_nbands;
++
++	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
++
++	if (wlc_hw->physhim == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
++			"failed\n", unit);
++		err = 25;
++		goto fail;
++	}
++
++	/* pass all the parameters to wlc_phy_shared_attach in one struct */
++	sha_params.sih = wlc_hw->sih;
++	sha_params.physhim = wlc_hw->physhim;
++	sha_params.unit = unit;
++	sha_params.corerev = wlc_hw->corerev;
++	sha_params.vid = wlc_hw->vendorid;
++	sha_params.did = wlc_hw->deviceid;
++	sha_params.chip = ai_get_chip_id(wlc_hw->sih);
++	sha_params.chiprev = ai_get_chiprev(wlc_hw->sih);
++	sha_params.chippkg = ai_get_chippkg(wlc_hw->sih);
++	sha_params.sromrev = wlc_hw->sromrev;
++	sha_params.boardtype = ai_get_boardtype(wlc_hw->sih);
++	sha_params.boardrev = wlc_hw->boardrev;
++	sha_params.boardflags = wlc_hw->boardflags;
++	sha_params.boardflags2 = wlc_hw->boardflags2;
++
++	/* alloc and save pointer to shared phy state area */
++	wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
++	if (!wlc_hw->phy_sh) {
++		err = 16;
++		goto fail;
++	}
++
++	/* initialize software state for each core and band */
++	for (j = 0; j < wlc_hw->_nbands; j++) {
++		/*
++		 * band0 is always 2.4Ghz
++		 * band1, if present, is 5Ghz
++		 */
++
++		brcms_c_setxband(wlc_hw, j);
++
++		wlc_hw->band->bandunit = j;
++		wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->band->bandunit = j;
++		wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->core->coreidx = core->core_index;
++
++		wlc_hw->machwcap = bcma_read32(core, D11REGOFFS(machwcap));
++		wlc_hw->machwcap_backup = wlc_hw->machwcap;
++
++		/* init tx fifo size */
++		wlc_hw->xmtfifo_sz =
++		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
++
++		/* Get a phy for this band */
++		wlc_hw->band->pi =
++			wlc_phy_attach(wlc_hw->phy_sh, core,
++				       wlc_hw->band->bandtype,
++				       wlc->wiphy);
++		if (wlc_hw->band->pi == NULL) {
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
++				  "attach failed\n", unit);
++			err = 17;
++			goto fail;
++		}
++
++		wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
++
++		wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
++				       &wlc_hw->band->phyrev,
++				       &wlc_hw->band->radioid,
++				       &wlc_hw->band->radiorev);
++		wlc_hw->band->abgphy_encore =
++		    wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc_hw->band->core_flags =
++		    wlc_phy_get_coreflags(wlc_hw->band->pi);
++
++		/* verify good phy_type & supported phy revision */
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			if (NCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			if (LCNCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else {
++ bad_phy:
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
++				  "phy type/rev (%d/%d)\n", unit,
++				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
++			err = 18;
++			goto fail;
++		}
++
++ good_phy:
++		/*
++		 * BMAC_NOTE: wlc->band->pi should not be set below and should
++		 * be done in the high level attach. However we can not make
++		 * that change until all low level access is changed to
++		 * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
++		 * keeping wlc_hw->band->pi as well for incremental update of
++		 * low level fns, and cut over low only init when all fns
++		 * updated.
++		 */
++		wlc->band->pi = wlc_hw->band->pi;
++		wlc->band->phytype = wlc_hw->band->phytype;
++		wlc->band->phyrev = wlc_hw->band->phyrev;
++		wlc->band->radioid = wlc_hw->band->radioid;
++		wlc->band->radiorev = wlc_hw->band->radiorev;
++
++		/* default contention windows size limits */
++		wlc_hw->band->CWmin = APHY_CWMIN;
++		wlc_hw->band->CWmax = PHY_CWMAX;
++
++		if (!brcms_b_attach_dmapio(wlc, j, wme)) {
++			err = 19;
++			goto fail;
++		}
++	}
++
++	/* disable core to match driver "down" state */
++	brcms_c_coredisable(wlc_hw);
++
++	/* Match driver "down" state */
++	ai_pci_down(wlc_hw->sih);
++
++	/* turn off pll and xtal to match driver "down" state */
++	brcms_b_xtal(wlc_hw, OFF);
++
++	/* *******************************************************************
++	 * The hardware is in the DOWN state at this point. D11 core
++	 * or cores are in reset with clocks off, and the board PLLs
++	 * are off if possible.
++	 *
++	 * Beyond this point, wlc->sbclk == false and chip registers
++	 * should not be touched.
++	 *********************************************************************
++	 */
++
++	/* init etheraddr state variables */
++	brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
++
++	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
++	    is_zero_ether_addr(wlc_hw->etheraddr)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
++			  unit);
++		err = 22;
++		goto fail;
++	}
++
++	BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
++	       wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
++
++	return err;
++
++ fail:
++	wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
++		  err);
++	return err;
++}
++
++static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
++{
++	uint unit;
++	unit = wlc->pub->unit;
++
++	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
++		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
++		wlc->band->antgain = 8;
++	} else if (wlc->band->antgain == -1) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom, using 2dB\n", unit, __func__);
++		wlc->band->antgain = 8;
++	} else {
++		s8 gain, fract;
++		/* Older sroms specified gain in whole dbm only.  In order
++		 * be able to specify qdbm granularity and remain backward
++		 * compatible the whole dbms are now encoded in only
++		 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
++		 * 6 bit signed number ranges from -32 - 31.
++		 *
++		 * Examples:
++		 * 0x1 = 1 db,
++		 * 0xc1 = 1.75 db (1 + 3 quarters),
++		 * 0x3f = -1 (-1 + 0 quarters),
++		 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
++		 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
++		 */
++		gain = wlc->band->antgain & 0x3f;
++		gain <<= 2;	/* Sign extend */
++		gain >>= 2;
++		fract = (wlc->band->antgain & 0xc0) >> 6;
++		wlc->band->antgain = 4 * gain + fract;
++	}
++}
++
++static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
++{
++	int aa;
++	uint unit;
++	int bandtype;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	unit = wlc->pub->unit;
++	bandtype = wlc->band->bandtype;
++
++	/* get antennas available */
++	if (bandtype == BRCM_BAND_5G)
++		aa = sprom->ant_available_a;
++	else
++		aa = sprom->ant_available_bg;
++
++	if ((aa < 1) || (aa > 15)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom (0x%x), using 3\n", unit, __func__, aa);
++		aa = 3;
++	}
++
++	/* reset the defaults if we have a single antenna */
++	if (aa == 1) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
++		wlc->stf->txant = ANT_TX_FORCE_0;
++	} else if (aa == 2) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
++		wlc->stf->txant = ANT_TX_FORCE_1;
++	} else {
++	}
++
++	/* Compute Antenna Gain */
++	if (bandtype == BRCM_BAND_5G)
++		wlc->band->antgain = sprom->antenna_gain.a1;
++	else
++		wlc->band->antgain = sprom->antenna_gain.a0;
++
++	brcms_c_attach_antgain_init(wlc);
++
++	return true;
++}
++
++static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
++{
++	u16 chanspec;
++	struct brcms_band *band;
++	struct brcms_bss_info *bi = wlc->default_bss;
++
++	/* init default and target BSS with some sane initial values */
++	memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
++	bi->beacon_period = BEACON_INTERVAL_DEFAULT;
++
++	/* fill the default channel as the first valid channel
++	 * starting from the 2G channels
++	 */
++	chanspec = ch20mhz_chspec(1);
++	wlc->home_chanspec = bi->chanspec = chanspec;
++
++	/* find the band of our default channel */
++	band = wlc->band;
++	if (wlc->pub->_nbands > 1 &&
++	    band->bandunit != chspec_bandunit(chanspec))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++
++	/* init bss rates to the band specific default rate set */
++	brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
++		band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(chanspec), wlc->stf->txstreams);
++
++	if (wlc->pub->_n_enab & SUPPORT_11N)
++		bi->flags |= BRCMS_BSS_HT;
++}
++
++static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi, *p;
++
++	qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
++	if (qi != NULL) {
++		/*
++		 * Have enough room for control packets along with HI watermark
++		 * Also, add room to txq for total psq packets if all the SCBs
++		 * leave PS mode. The watermark for flowcontrol to OS packets
++		 * will remain the same
++		 */
++		brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
++			  2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
++
++		/* add this queue to the the global list */
++		p = wlc->tx_queues;
++		if (p == NULL) {
++			wlc->tx_queues = qi;
++		} else {
++			while (p->next != NULL)
++				p = p->next;
++			p->next = qi;
++		}
++	}
++	return qi;
++}
++
++static void brcms_c_txq_free(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi)
++{
++	struct brcms_txq_info *p;
++
++	if (qi == NULL)
++		return;
++
++	/* remove the queue from the linked list */
++	p = wlc->tx_queues;
++	if (p == qi)
++		wlc->tx_queues = p->next;
++	else {
++		while (p != NULL && p->next != qi)
++			p = p->next;
++		if (p != NULL)
++			p->next = p->next->next;
++	}
++
++	kfree(qi);
++}
++
++static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
++{
++	uint i;
++	struct brcms_band *band;
++
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		band = wlc->bandstate[i];
++		if (band->bandtype == BRCM_BAND_5G) {
++			if ((bwcap == BRCMS_N_BW_40ALL)
++			    || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		} else {
++			if (bwcap == BRCMS_N_BW_40ALL)
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		}
++	}
++}
++
++static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
++{
++	/* free timer state */
++	if (wlc->wdtimer) {
++		brcms_free_timer(wlc->wdtimer);
++		wlc->wdtimer = NULL;
++	}
++	if (wlc->radio_timer) {
++		brcms_free_timer(wlc->radio_timer);
++		wlc->radio_timer = NULL;
++	}
++}
++
++static void brcms_c_detach_module(struct brcms_c_info *wlc)
++{
++	if (wlc->asi) {
++		brcms_c_antsel_detach(wlc->asi);
++		wlc->asi = NULL;
++	}
++
++	if (wlc->ampdu) {
++		brcms_c_ampdu_detach(wlc->ampdu);
++		wlc->ampdu = NULL;
++	}
++
++	brcms_c_stf_detach(wlc);
++}
++
++/*
++ * low level detach
++ */
++static int brcms_b_detach(struct brcms_c_info *wlc)
++{
++	uint i;
++	struct brcms_hw_band *band;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	int callbacks;
++
++	callbacks = 0;
++
++	brcms_b_detach_dmapio(wlc_hw);
++
++	band = wlc_hw->band;
++	for (i = 0; i < wlc_hw->_nbands; i++) {
++		if (band->pi) {
++			/* Detach this band's phy */
++			wlc_phy_detach(band->pi);
++			band->pi = NULL;
++		}
++		band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
++	}
++
++	/* Free shared phy state */
++	kfree(wlc_hw->phy_sh);
++
++	wlc_phy_shim_detach(wlc_hw->physhim);
++
++	if (wlc_hw->sih) {
++		ai_detach(wlc_hw->sih);
++		wlc_hw->sih = NULL;
++	}
++
++	return callbacks;
++
++}
++
++/*
++ * Return a count of the number of driver callbacks still pending.
++ *
++ * General policy is that brcms_c_detach can only dealloc/free software states.
++ * It can NOT touch hardware registers since the d11core may be in reset and
++ * clock may not be available.
++ * One exception is sb register access, which is possible if crystal is turned
++ * on after "down" state, driver should avoid software timer with the exception
++ * of radio_monitor.
++ */
++uint brcms_c_detach(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	if (wlc == NULL)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	callbacks += brcms_b_detach(wlc);
++
++	/* delete software timers */
++	if (!brcms_c_radio_monitor_stop(wlc))
++		callbacks++;
++
++	brcms_c_channel_mgr_detach(wlc->cmi);
++
++	brcms_c_timers_deinit(wlc);
++
++	brcms_c_detach_module(wlc);
++
++
++	while (wlc->tx_queues != NULL)
++		brcms_c_txq_free(wlc, wlc->tx_queues);
++
++	brcms_c_detach_mfree(wlc);
++	return callbacks;
++}
++
++/* update state that depends on the current value of "ap" */
++static void brcms_c_ap_upd(struct brcms_c_info *wlc)
++{
++	/* STA-BSS; short capable */
++	wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
++}
++
++/* Initialize just the hardware when coming out of POR or S3/S5 system states */
++static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->wlc->pub->hw_up)
++		return;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * TODO: test suspend/resume
++	 *
++	 * AI chip doesn't restore bar0win2 on
++	 * hibernation/resume, need sw fixup
++	 */
++
++	/*
++	 * Inform phy that a POR reset has occurred so
++	 * it does a complete phy init
++	 */
++	wlc_phy_por_inform(wlc_hw->band->pi);
++
++	wlc_hw->ucode_loaded = false;
++	wlc_hw->wlc->pub->hw_up = true;
++
++	if ((wlc_hw->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++		if (!
++		    (wlc_hw->boardrev >= 0x1250
++		     && (wlc_hw->boardflags & BFL_FEM_BT)))
++			ai_epa_4313war(wlc_hw->sih);
++	}
++}
++
++static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * Configure pci/pcmcia here instead of in brcms_c_attach()
++	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
++	 */
++	bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
++			      true);
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to
++	 * bring the driver up in this case.
++	 */
++	if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
++		/* put SB PCI in down state again */
++		ai_pci_down(wlc_hw->sih);
++		brcms_b_xtal(wlc_hw, OFF);
++		return -ENOMEDIUM;
++	}
++
++	ai_pci_up(wlc_hw->sih);
++
++	/* reset the d11 core */
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	return 0;
++}
++
++static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	wlc_hw->up = true;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
++
++	/* FULLY enable dynamic power control and d11 core interrupt */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++	brcms_intrson(wlc_hw->wlc->wl);
++	return 0;
++}
++
++/*
++ * Write WME tunable parameters for retransmit/max rate
++ * from wlc struct to ucode
++ */
++static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
++{
++	int ac;
++
++	/* Need clock to do this */
++	if (!wlc->clk)
++		return;
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++		brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),
++				  wlc->wme_retries[ac]);
++}
++
++/* make interface operational */
++int brcms_c_up(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* HW is turned off so don't try to access it */
++	if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
++		return -ENOMEDIUM;
++
++	if (!wlc->pub->hw_up) {
++		brcms_b_hw_up(wlc->hw);
++		wlc->pub->hw_up = true;
++	}
++
++	if ((wlc->pub->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc->hw->sih) == BCM4313_CHIP_ID)) {
++		if (wlc->pub->boardrev >= 0x1250
++		    && (wlc->pub->boardflags & BFL_FEM_BT))
++			brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL,
++				MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
++		else
++			brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE,
++				    MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
++	}
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to bring
++	 * the driver up in this case. If radio is disabled, abort up, lower
++	 * power, start radio timer and return 0(for NDIS) don't call
++	 * radio_update to avoid looping brcms_c_up.
++	 *
++	 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
++	 */
++	if (!wlc->pub->radio_disabled) {
++		int status = brcms_b_up_prep(wlc->hw);
++		if (status == -ENOMEDIUM) {
++			if (!mboolisset
++			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
++				struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++				mboolset(wlc->pub->radio_disabled,
++					 WL_RADIO_HW_DISABLE);
++
++				if (bsscfg->enable && bsscfg->BSS)
++					wiphy_err(wlc->wiphy, "wl%d: up"
++						  ": rfdisable -> "
++						  "bsscfg_disable()\n",
++						   wlc->pub->unit);
++			}
++		}
++	}
++
++	if (wlc->pub->radio_disabled) {
++		brcms_c_radio_monitor_start(wlc);
++		return 0;
++	}
++
++	/* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
++	wlc->clk = true;
++
++	brcms_c_radio_monitor_stop(wlc);
++
++	/* Set EDCF hostflags */
++	brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
++
++	brcms_init(wlc->wl);
++	wlc->pub->up = true;
++
++	if (wlc->bandinit_pending) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
++		wlc->bandinit_pending = false;
++		brcms_c_enable_mac(wlc);
++	}
++
++	brcms_b_up_finish(wlc->hw);
++
++	/* Program the TX wme params with the current settings */
++	brcms_c_wme_retries_write(wlc);
++
++	/* start one second watchdog timer */
++	brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
++	wlc->WDarmed = true;
++
++	/* ensure antenna config is up to date */
++	brcms_c_stf_phy_txant_upd(wlc);
++	/* ensure LDPC config is in sync */
++	brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
++
++	return 0;
++}
++
++static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	return callbacks;
++}
++
++static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++	uint callbacks = 0;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	/* disable interrupts */
++	if (dev_gone)
++		wlc_hw->wlc->macintmask = 0;
++	else {
++		/* now disable interrupts */
++		brcms_intrsoff(wlc_hw->wlc->wl);
++
++		/* ensure we're running on the pll clock again */
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	}
++	/* down phy at the last of this stage */
++	callbacks += wlc_phy_down(wlc_hw->band->pi);
++
++	return callbacks;
++}
++
++static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
++{
++	uint callbacks = 0;
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	wlc_hw->up = false;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone) {
++		wlc_hw->sbclk = false;
++		wlc_hw->clk = false;
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++
++		/* reclaim any posted packets */
++		brcms_c_flushqueues(wlc_hw->wlc);
++	} else {
++
++		/* Reset and disable the core */
++		if (bcma_core_is_enabled(wlc_hw->d11core)) {
++			if (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++				brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++			callbacks += brcms_reset(wlc_hw->wlc->wl);
++			brcms_c_coredisable(wlc_hw);
++		}
++
++		/* turn off primary xtal and pll */
++		if (!wlc_hw->noreset) {
++			ai_pci_down(wlc_hw->sih);
++			brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++
++	return callbacks;
++}
++
++/*
++ * Mark the interface nonoperational, stop the software mechanisms,
++ * disable the hardware, free any transient buffer state.
++ * Return a count of the number of driver callbacks still pending.
++ */
++uint brcms_c_down(struct brcms_c_info *wlc)
++{
++
++	uint callbacks = 0;
++	int i;
++	bool dev_gone = false;
++	struct brcms_txq_info *qi;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* check if we are already in the going down path */
++	if (wlc->going_down) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
++			  "\n", wlc->pub->unit, __func__);
++		return 0;
++	}
++	if (!wlc->pub->up)
++		return callbacks;
++
++	wlc->going_down = true;
++
++	callbacks += brcms_b_bmac_down_prep(wlc->hw);
++
++	dev_gone = brcms_deviceremoved(wlc);
++
++	/* Call any registered down handlers */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].down_fn)
++			callbacks +=
++			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
++	}
++
++	/* cancel the watchdog timer */
++	if (wlc->WDarmed) {
++		if (!brcms_del_timer(wlc->wdtimer))
++			callbacks++;
++		wlc->WDarmed = false;
++	}
++	/* cancel all other timers */
++	callbacks += brcms_c_down_del_timer(wlc);
++
++	wlc->pub->up = false;
++
++	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
++
++	/* clear txq flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* flush tx queues */
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
++		brcmu_pktq_flush(&qi->q, true, NULL, NULL);
++
++	callbacks += brcms_b_down_finish(wlc->hw);
++
++	/* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
++	wlc->clk = false;
++
++	wlc->going_down = false;
++	return callbacks;
++}
++
++/* Set the current gmode configuration */
++int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
++{
++	int ret = 0;
++	uint i;
++	struct brcms_c_rateset rs;
++	/* Default to 54g Auto */
++	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
++	s8 shortslot = BRCMS_SHORTSLOT_AUTO;
++	bool shortslot_restrict = false; /* Restrict association to stations
++					  * that support shortslot
++					  */
++	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
++	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
++	int preamble = BRCMS_PLCP_LONG;
++	bool preamble_restrict = false;	/* Restrict association to stations
++					 * that support short preambles
++					 */
++	struct brcms_band *band;
++
++	/* if N-support is enabled, allow Gmode set as long as requested
++	 * Gmode is not GMODE_LEGACY_B
++	 */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
++		return -ENOTSUPP;
++
++	/* verify that we are dealing with 2G band and grab the band pointer */
++	if (wlc->band->bandtype == BRCM_BAND_2G)
++		band = wlc->band;
++	else if ((wlc->pub->_nbands > 1) &&
++		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++	else
++		return -EINVAL;
++
++	/* Legacy or bust when no OFDM is supported by regulatory */
++	if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
++	     BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
++		return -EINVAL;
++
++	/* update configuration value */
++	if (config)
++		brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
++
++	/* Clear rateset override */
++	memset(&rs, 0, sizeof(struct brcms_c_rateset));
++
++	switch (gmode) {
++	case GMODE_LEGACY_B:
++		shortslot = BRCMS_SHORTSLOT_OFF;
++		brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
++
++		break;
++
++	case GMODE_LRS:
++		break;
++
++	case GMODE_AUTO:
++		/* Accept defaults */
++		break;
++
++	case GMODE_ONLY:
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	case GMODE_PERFORMANCE:
++		shortslot = BRCMS_SHORTSLOT_ON;
++		shortslot_restrict = true;
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	default:
++		/* Error */
++		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
++			  wlc->pub->unit, __func__, gmode);
++		return -ENOTSUPP;
++	}
++
++	band->gmode = gmode;
++
++	wlc->shortslot_override = shortslot;
++
++	/* Use the default 11g rateset */
++	if (!rs.count)
++		brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
++
++	if (ofdm_basic) {
++		for (i = 0; i < rs.count; i++) {
++			if (rs.rates[i] == BRCM_RATE_6M
++			    || rs.rates[i] == BRCM_RATE_12M
++			    || rs.rates[i] == BRCM_RATE_24M)
++				rs.rates[i] |= BRCMS_RATE_FLAG;
++		}
++	}
++
++	/* Set default bss rateset */
++	wlc->default_bss->rateset.count = rs.count;
++	memcpy(wlc->default_bss->rateset.rates, rs.rates,
++	       sizeof(wlc->default_bss->rateset.rates));
++
++	return ret;
++}
++
++int brcms_c_set_nmode(struct brcms_c_info *wlc)
++{
++	uint i;
++	s32 nmode = AUTO;
++
++	if (wlc->stf->txstreams == WL_11N_3x3)
++		nmode = WL_11N_3x3;
++	else
++		nmode = WL_11N_2x2;
++
++	/* force GMODE_AUTO if NMODE is ON */
++	brcms_c_set_gmode(wlc, GMODE_AUTO, true);
++	if (nmode == WL_11N_3x3)
++		wlc->pub->_n_enab = SUPPORT_HT;
++	else
++		wlc->pub->_n_enab = SUPPORT_11N;
++	wlc->default_bss->flags |= BRCMS_BSS_HT;
++	/* add the mcs rates to the default and hw ratesets */
++	brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
++			      wlc->stf->txstreams);
++	for (i = 0; i < wlc->pub->_nbands; i++)
++		memcpy(wlc->bandstate[i]->hw_rateset.mcs,
++		       wlc->default_bss->rateset.mcs, MCSSET_LEN);
++
++	return 0;
++}
++
++static int
++brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
++			     struct brcms_c_rateset *rs_arg)
++{
++	struct brcms_c_rateset rs, new;
++	uint bandunit;
++
++	memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
++
++	/* check for bad count value */
++	if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
++		return -EINVAL;
++
++	/* try the current band */
++	bandunit = wlc->band->bandunit;
++	memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++	if (brcms_c_rate_hwrs_filter_sort_validate
++	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
++	     wlc->stf->txstreams))
++		goto good;
++
++	/* try the other band */
++	if (brcms_is_mband_unlocked(wlc)) {
++		bandunit = OTHERBANDUNIT(wlc);
++		memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++		if (brcms_c_rate_hwrs_filter_sort_validate(&new,
++						       &wlc->
++						       bandstate[bandunit]->
++						       hw_rateset, true,
++						       wlc->stf->txstreams))
++			goto good;
++	}
++
++	return -EBADE;
++
++ good:
++	/* apply new rateset */
++	memcpy(&wlc->default_bss->rateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	return 0;
++}
++
++static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
++{
++	u8 r;
++	bool war = false;
++
++	if (wlc->bsscfg->associated)
++		r = wlc->bsscfg->current_bss->rateset.rates[0];
++	else
++		r = wlc->default_bss->rateset.rates[0];
++
++	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
++}
++
++int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
++{
++	u16 chspec = ch20mhz_chspec(channel);
++
++	if (channel < 0 || channel > MAXCHANNEL)
++		return -EINVAL;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
++		return -EINVAL;
++
++
++	if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
++		if (wlc->band->bandunit != chspec_bandunit(chspec))
++			wlc->bandinit_pending = true;
++		else
++			wlc->bandinit_pending = false;
++	}
++
++	wlc->default_bss->chanspec = chspec;
++	/* brcms_c_BSSinit() will sanitize the rateset before
++	 * using it.. */
++	if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
++		brcms_c_set_home_chanspec(wlc, chspec);
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, chspec);
++		brcms_c_enable_mac(wlc);
++	}
++	return 0;
++}
++
++int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
++{
++	int ac;
++
++	if (srl < 1 || srl > RETRY_SHORT_MAX ||
++	    lrl < 1 || lrl > RETRY_SHORT_MAX)
++		return -EINVAL;
++
++	wlc->SRL = srl;
++	wlc->LRL = lrl;
++
++	brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_SHORT,  wlc->SRL);
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_LONG, wlc->LRL);
++	}
++	brcms_c_wme_retries_write(wlc);
++
++	return 0;
++}
++
++void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs)
++{
++	struct brcms_c_rateset *rs;
++
++	if (wlc->pub->associated)
++		rs = &wlc->bsscfg->current_bss->rateset;
++	else
++		rs = &wlc->default_bss->rateset;
++
++	/* Copy only legacy rateset section */
++	currs->count = rs->count;
++	memcpy(&currs->rates, &rs->rates, rs->count);
++}
++
++int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
++{
++	struct brcms_c_rateset internal_rs;
++	int bcmerror;
++
++	if (rs->count > BRCMS_NUMRATES)
++		return -ENOBUFS;
++
++	memset(&internal_rs, 0, sizeof(struct brcms_c_rateset));
++
++	/* Copy only legacy rateset section */
++	internal_rs.count = rs->count;
++	memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
++
++	/* merge rateset coming in with the current mcsset */
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		struct brcms_bss_info *mcsset_bss;
++		if (wlc->bsscfg->associated)
++			mcsset_bss = wlc->bsscfg->current_bss;
++		else
++			mcsset_bss = wlc->default_bss;
++		memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
++		       MCSSET_LEN);
++	}
++
++	bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
++	if (!bcmerror)
++		brcms_c_ofdm_rateset_war(wlc);
++
++	return bcmerror;
++}
++
++int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
++{
++	if (period < DOT11_MIN_BEACON_PERIOD ||
++	    period > DOT11_MAX_BEACON_PERIOD)
++		return -EINVAL;
++
++	wlc->default_bss->beacon_period = period;
++	return 0;
++}
++
++u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
++{
++	return wlc->band->phytype;
++}
++
++void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
++{
++	wlc->shortslot_override = sslot_override;
++
++	/*
++	 * shortslot is an 11g feature, so no more work if we are
++	 * currently on the 5G band
++	 */
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		return;
++
++	if (wlc->pub->up && wlc->pub->associated) {
++		/* let watchdog or beacon processing update shortslot */
++	} else if (wlc->pub->up) {
++		/* unassociated shortslot is off */
++		brcms_c_switch_shortslot(wlc, false);
++	} else {
++		/* driver is down, so just update the brcms_c_info
++		 * value */
++		if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
++			wlc->shortslot = false;
++		else
++			wlc->shortslot =
++			    (wlc->shortslot_override ==
++			     BRCMS_SHORTSLOT_ON);
++	}
++}
++
++/*
++ * register watchdog and down handlers.
++ */
++int brcms_c_module_register(struct brcms_pub *pub,
++			    const char *name, struct brcms_info *hdl,
++			    int (*d_fn)(void *handle))
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	/* find an empty entry and just add, no duplication check! */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].name[0] == '\0') {
++			strncpy(wlc->modulecb[i].name, name,
++				sizeof(wlc->modulecb[i].name) - 1);
++			wlc->modulecb[i].hdl = hdl;
++			wlc->modulecb[i].down_fn = d_fn;
++			return 0;
++		}
++	}
++
++	return -ENOSR;
++}
++
++/* unregister module callbacks */
++int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++			      struct brcms_info *hdl)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	if (wlc == NULL)
++		return -ENODATA;
++
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (!strcmp(wlc->modulecb[i].name, name) &&
++		    (wlc->modulecb[i].hdl == hdl)) {
++			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
++			return 0;
++		}
++	}
++
++	/* table not found! */
++	return -ENODATA;
++}
++
++void brcms_c_print_txstatus(struct tx_status *txs)
++{
++	pr_debug("\ntxpkt (MPDU) Complete\n");
++
++	pr_debug("FrameID: %04x   TxStatus: %04x\n", txs->frameid, txs->status);
++
++	pr_debug("[15:12]  %d  frame attempts\n",
++		  (txs->status & TX_STATUS_FRM_RTX_MASK) >>
++		 TX_STATUS_FRM_RTX_SHIFT);
++	pr_debug(" [11:8]  %d  rts attempts\n",
++		 (txs->status & TX_STATUS_RTS_RTX_MASK) >>
++		 TX_STATUS_RTS_RTX_SHIFT);
++	pr_debug("    [7]  %d  PM mode indicated\n",
++		 txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
++	pr_debug("    [6]  %d  intermediate status\n",
++		 txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
++	pr_debug("    [5]  %d  AMPDU\n",
++		 txs->status & TX_STATUS_AMPDU ? 1 : 0);
++	pr_debug("  [4:2]  %d  Frame Suppressed Reason (%s)\n",
++		 (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
++		 (const char *[]) {
++			"None",
++			"PMQ Entry",
++			"Flush request",
++			"Previous frag failure",
++			"Channel mismatch",
++			"Lifetime Expiry",
++			"Underflow"
++		 } [(txs->status & TX_STATUS_SUPR_MASK) >>
++		    TX_STATUS_SUPR_SHIFT]);
++	pr_debug("    [1]  %d  acked\n",
++		 txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
++
++	pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
++		 txs->lasttxtime, txs->sequence, txs->phyerr,
++		 (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
++		 (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
++}
++
++bool brcms_c_chipmatch(u16 vendor, u16 device)
++{
++	if (vendor != PCI_VENDOR_ID_BROADCOM) {
++		pr_err("unknown vendor id %04x\n", vendor);
++		return false;
++	}
++
++	if (device == BCM43224_D11N_ID_VEN1)
++		return true;
++	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
++		return true;
++	if (device == BCM4313_D11N2G_ID)
++		return true;
++	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
++		return true;
++
++	pr_err("unknown device id %04x\n", device);
++	return false;
++}
++
++#if defined(DEBUG)
++void brcms_c_print_txdesc(struct d11txh *txh)
++{
++	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
++	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
++	u16 mfc = le16_to_cpu(txh->MacFrameControl);
++	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
++	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
++	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
++	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
++	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
++	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
++	u16 mainrates = le16_to_cpu(txh->MainRates);
++	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
++	u8 *iv = txh->IV;
++	u8 *ra = txh->TxFrameRA;
++	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
++	u8 *rtspfb = txh->RTSPLCPFallback;
++	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
++	u8 *fragpfb = txh->FragPLCPFallback;
++	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
++	u16 mmodelen = le16_to_cpu(txh->MModeLen);
++	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
++	u16 tfid = le16_to_cpu(txh->TxFrameID);
++	u16 txs = le16_to_cpu(txh->TxStatus);
++	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
++	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
++	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
++	u16 mmbyte = le16_to_cpu(txh->MinMBytes);
++
++	u8 *rtsph = txh->RTSPhyHeader;
++	struct ieee80211_rts rts = txh->rts_frame;
++
++	/* add plcp header along with txh descriptor */
++	brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
++			   "Raw TxDesc + plcp header:\n");
++
++	pr_debug("TxCtlLow: %04x ", mtcl);
++	pr_debug("TxCtlHigh: %04x ", mtch);
++	pr_debug("FC: %04x ", mfc);
++	pr_debug("FES Time: %04x\n", tfest);
++	pr_debug("PhyCtl: %04x%s ", ptcw,
++	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
++	pr_debug("PhyCtl_1: %04x ", ptcw_1);
++	pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
++	pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
++	pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
++	pr_debug("MainRates: %04x ", mainrates);
++	pr_debug("XtraFrameTypes: %04x ", xtraft);
++	pr_debug("\n");
++
++	print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
++	print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
++			     ra, sizeof(txh->TxFrameRA));
++
++	pr_debug("Fb FES Time: %04x ", tfestfb);
++	print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtspfb, sizeof(txh->RTSPLCPFallback));
++	pr_debug("RTS DUR: %04x ", rtsdfb);
++	print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
++			     fragpfb, sizeof(txh->FragPLCPFallback));
++	pr_debug("DUR: %04x", fragdfb);
++	pr_debug("\n");
++
++	pr_debug("MModeLen: %04x ", mmodelen);
++	pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
++
++	pr_debug("FrameID:     %04x\n", tfid);
++	pr_debug("TxStatus:    %04x\n", txs);
++
++	pr_debug("MaxNumMpdu:  %04x\n", mnmpdu);
++	pr_debug("MaxAggbyte:  %04x\n", mabyte);
++	pr_debug("MaxAggbyte_fb:  %04x\n", mabyte_f);
++	pr_debug("MinByte:     %04x\n", mmbyte);
++
++	print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtsph, sizeof(txh->RTSPhyHeader));
++	print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
++			     (u8 *)&rts, sizeof(txh->rts_frame));
++	pr_debug("\n");
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++static int
++brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
++		     int len)
++{
++	int i;
++	char *p = buf;
++	char hexstr[16];
++	int slen = 0, nlen = 0;
++	u32 bit;
++	const char *name;
++
++	if (len < 2 || !buf)
++		return 0;
++
++	buf[0] = '\0';
++
++	for (i = 0; flags != 0; i++) {
++		bit = bd[i].bit;
++		name = bd[i].name;
++		if (bit == 0 && flags != 0) {
++			/* print any unnamed bits */
++			snprintf(hexstr, 16, "0x%X", flags);
++			name = hexstr;
++			flags = 0;	/* exit loop */
++		} else if ((flags & bit) == 0)
++			continue;
++		flags &= ~bit;
++		nlen = strlen(name);
++		slen += nlen;
++		/* count btwn flag space */
++		if (flags != 0)
++			slen += 1;
++		/* need NULL char as well */
++		if (len <= slen)
++			break;
++		/* copy NULL char but don't count it */
++		strncpy(p, name, nlen + 1);
++		p += nlen;
++		/* copy btwn flag space and NULL char */
++		if (flags != 0)
++			p += snprintf(p, 2, " ");
++		len -= slen;
++	}
++
++	/* indicate the str was too short */
++	if (flags != 0) {
++		if (len < 2)
++			p -= 2 - len;	/* overwrite last char */
++		p += snprintf(p, 2, ">");
++	}
++
++	return (int)(p - buf);
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++void brcms_c_print_rxh(struct d11rxhdr *rxh)
++{
++	u16 len = rxh->RxFrameSize;
++	u16 phystatus_0 = rxh->PhyRxStatus_0;
++	u16 phystatus_1 = rxh->PhyRxStatus_1;
++	u16 phystatus_2 = rxh->PhyRxStatus_2;
++	u16 phystatus_3 = rxh->PhyRxStatus_3;
++	u16 macstatus1 = rxh->RxStatus1;
++	u16 macstatus2 = rxh->RxStatus2;
++	char flagstr[64];
++	char lenbuf[20];
++	static const struct brcms_c_bit_desc macstat_flags[] = {
++		{RXS_FCSERR, "FCSErr"},
++		{RXS_RESPFRAMETX, "Reply"},
++		{RXS_PBPRES, "PADDING"},
++		{RXS_DECATMPT, "DeCr"},
++		{RXS_DECERR, "DeCrErr"},
++		{RXS_BCNSENT, "Bcn"},
++		{0, NULL}
++	};
++
++	brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
++
++	brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
++
++	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
++
++	pr_debug("RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
++	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
++	pr_debug("RxPHYStatus:     %04x %04x %04x %04x\n",
++	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
++	pr_debug("RxMACStatus:     %x %s\n", macstatus1, flagstr);
++	pr_debug("RXMACaggtype:    %x\n",
++	       (macstatus2 & RXS_AGGTYPE_MASK));
++	pr_debug("RxTSFTime:       %04x\n", rxh->RxTSFTime);
++}
++#endif				/* defined(DEBUG) */
++
++u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
++{
++	u16 table_ptr;
++	u8 phy_rate, index;
++
++	/* get the phy specific rate encoding for the PLCP SIGNAL field */
++	if (is_ofdm_rate(rate))
++		table_ptr = M_RT_DIRMAP_A;
++	else
++		table_ptr = M_RT_DIRMAP_B;
++
++	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
++}
++
++static bool
++brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec, bool head)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec) {
++			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
++				  "\n", __func__, eprec, prec);
++			return false;
++		}
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		bool discard_oldest;
++
++		discard_oldest = ac_bitmap_tst(0, eprec);
++
++		/* Refuse newer packet unless configured to discard oldest */
++		if (eprec == prec && !discard_oldest) {
++			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
++				  "\n", __func__, prec);
++			return false;
++		}
++
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	if (head)
++		p = brcmu_pktq_penq_head(q, prec, pkt);
++	else
++		p = brcmu_pktq_penq(q, prec, pkt);
++
++	return true;
++}
++
++/*
++ * Attempts to queue a packet onto a multiple-precedence queue,
++ * if necessary evicting a lower precedence packet from the queue.
++ *
++ * 'prec' is the precedence number that has already been mapped
++ * from the packet priority.
++ *
++ * Returns true if packet consumed (queued), false if not.
++ */
++static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
++}
++
++void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++		     struct sk_buff *sdu, uint prec)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;	/* Check me */
++	struct pktq *q = &qi->q;
++	int prio;
++
++	prio = sdu->priority;
++
++	if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
++		/*
++		 * we might hit this condtion in case
++		 * packet flooding from mac80211 stack
++		 */
++		brcmu_pkt_buf_free_skb(sdu);
++	}
++}
++
++/*
++ * bcmc_fid_generate:
++ * Generate frame ID for a BCMC packet.  The frag field is not used
++ * for MC frames so is used as part of the sequence number.
++ */
++static inline u16
++bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
++		  struct d11txh *txh)
++{
++	u16 frameid;
++
++	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
++						  TXFID_QUEUE_MASK);
++	frameid |=
++	    (((wlc->
++	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++	    TX_BCMC_FIFO;
++
++	return frameid;
++}
++
++static uint
++brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	uint dur = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
++	dur =
++	    brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				(DOT11_ACK_LEN + FCS_LEN));
++	return dur;
++}
++
++static uint
++brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
++}
++
++static uint
++brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
++		     u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
++		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
++	return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
++				    FCS_LEN));
++}
++
++/* brcms_c_compute_frame_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for MPDU
++ * DUR for a single frame = 1 SIFS + 1 ACK
++ * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
++ *
++ * rate			MPDU rate in unit of 500kbps
++ * next_frag_len	next MPDU length in bytes
++ * preamble_type	use short/GF or long/MM PLCP header
++ */
++static u16
++brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
++		      u8 preamble_type, uint next_frag_len)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	dur = sifs;
++	dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
++
++	if (next_frag_len) {
++		/* Double the current DUR to get 2 SIFS + 2 ACKs */
++		dur *= 2;
++		/* add another SIFS and the frag time */
++		dur += sifs;
++		dur +=
++		    (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
++						 next_frag_len);
++	}
++	return dur;
++}
++
++/* The opposite of brcms_c_calc_frame_time */
++static uint
++brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
++		   u8 preamble_type, uint dur)
++{
++	uint nsyms, mac_len, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
++		 wlc->pub->unit, ratespec, preamble_type, dur);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		/* payload calculation matches that of regular ofdm */
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
++		/* kNdbps = kbps * 4 */
++		kNdps =	mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * kNdps) -
++		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
++	} else if (is_ofdm_rate(ratespec)) {
++		dur -= APHY_PREAMBLE_TIME;
++		dur -= APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * Ndps) -
++		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
++	} else {
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur -= BPHY_PLCP_SHORT_TIME;
++		else
++			dur -= BPHY_PLCP_TIME;
++		mac_len = dur * rate;
++		/* divide out factor of 2 in rate (1/2 mbps) */
++		mac_len = mac_len / 8 / 2;
++	}
++	return mac_len;
++}
++
++/*
++ * Return true if the specified rate is supported by the specified band.
++ * BRCM_BAND_AUTO indicates the current band.
++ */
++static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
++		    bool verbose)
++{
++	struct brcms_c_rateset *hw_rateset;
++	uint i;
++
++	if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
++		hw_rateset = &wlc->band->hw_rateset;
++	else if (wlc->pub->_nbands > 1)
++		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
++	else
++		/* other band specified and we are a single band device */
++		return false;
++
++	/* check if this is a mimo rate */
++	if (is_mcs_rate(rspec)) {
++		if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
++			goto error;
++
++		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
++	}
++
++	for (i = 0; i < hw_rateset->count; i++)
++		if (hw_rateset->rates[i] == rspec2rate(rspec))
++			return true;
++ error:
++	if (verbose)
++		wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
++			  "not in hw_rateset\n", wlc->pub->unit, rspec);
++
++	return false;
++}
++
++static u32
++mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
++		       u32 int_val)
++{
++	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
++	u8 rate = int_val & NRATE_RATE_MASK;
++	u32 rspec;
++	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
++	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
++	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
++				  == NRATE_OVERRIDE_MCS_ONLY);
++	int bcmerror = 0;
++
++	if (!ismcs)
++		return (u32) rate;
++
++	/* validate the combination of rate/mcs/stf is allowed */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
++		/* mcs only allowed when nmode */
++		if (stf > PHY_TXC1_MODE_SDM) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++
++		/* mcs 32 is a special case, DUP mode 40 only */
++		if (rate == 32) {
++			if (!CHSPEC_IS40(wlc->home_chanspec) ||
++			    ((stf != PHY_TXC1_MODE_SISO)
++			     && (stf != PHY_TXC1_MODE_CDD))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
++					  "32\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++			/* mcs > 7 must use stf SDM */
++		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
++			/* mcs > 7 must use stf SDM */
++			if (stf != PHY_TXC1_MODE_SDM) {
++				BCMMSG(wlc->wiphy, "wl%d: enabling "
++				       "SDM mode for mcs %d\n",
++				       wlc->pub->unit, rate);
++				stf = PHY_TXC1_MODE_SDM;
++			}
++		} else {
++			/*
++			 * MCS 0-7 may use SISO, CDD, and for
++			 * phy_rev >= 3 STBC
++			 */
++			if ((stf > PHY_TXC1_MODE_STBC) ||
++			    (!BRCMS_STBC_CAP_PHY(wlc)
++			     && (stf == PHY_TXC1_MODE_STBC))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
++					  "\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++		}
++	} else if (is_ofdm_rate(rate)) {
++		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else if (is_cck_rate(rate)) {
++		if ((cur_band->bandtype != BRCM_BAND_2G)
++		    || (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
++			  wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++	/* make sure multiple antennae are available for non-siso rates */
++	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
++			  "request\n", wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++
++	rspec = rate;
++	if (ismcs) {
++		rspec |= RSPEC_MIMORATE;
++		/* For STBC populate the STC field of the ratespec */
++		if (stf == PHY_TXC1_MODE_STBC) {
++			u8 stc;
++			stc = 1;	/* Nss for single stream is always 1 */
++			rspec |= (stc << RSPEC_STC_SHIFT);
++		}
++	}
++
++	rspec |= (stf << RSPEC_STF_SHIFT);
++
++	if (override_mcs_only)
++		rspec |= RSPEC_OVERRIDE_MCS_ONLY;
++
++	if (issgi)
++		rspec |= RSPEC_SHORT_GI;
++
++	if ((rate != 0)
++	    && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
++		return rate;
++
++	return rspec;
++done:
++	return rate;
++}
++
++/*
++ * Compute PLCP, but only requires actual rate and length of pkt.
++ * Rate is given in the driver standard multiple of 500 kbps.
++ * le is set for 11 Mbps rate if necessary.
++ * Broken out for PRQ.
++ */
++
++static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
++			     uint length, u8 *plcp)
++{
++	u16 usec = 0;
++	u8 le = 0;
++
++	switch (rate_500) {
++	case BRCM_RATE_1M:
++		usec = length << 3;
++		break;
++	case BRCM_RATE_2M:
++		usec = length << 2;
++		break;
++	case BRCM_RATE_5M5:
++		usec = (length << 4) / 11;
++		if ((length << 4) - (usec * 11) > 0)
++			usec++;
++		break;
++	case BRCM_RATE_11M:
++		usec = (length << 3) / 11;
++		if ((length << 3) - (usec * 11) > 0) {
++			usec++;
++			if ((usec * 11) - (length << 3) >= 8)
++				le = D11B_PLCP_SIGNAL_LE;
++		}
++		break;
++
++	default:
++		wiphy_err(wlc->wiphy,
++			  "brcms_c_cck_plcp_set: unsupported rate %d\n",
++			  rate_500);
++		rate_500 = BRCM_RATE_1M;
++		usec = length << 3;
++		break;
++	}
++	/* PLCP signal byte */
++	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
++	/* PLCP service byte */
++	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
++	/* PLCP length u16, little endian */
++	plcp[2] = usec & 0xff;
++	plcp[3] = (usec >> 8) & 0xff;
++	/* PLCP CRC16 */
++	plcp[4] = 0;
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
++{
++	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
++	plcp[0] = mcs;
++	if (rspec_is40mhz(rspec) || (mcs == 32))
++		plcp[0] |= MIMO_PLCP_40MHZ;
++	BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
++	plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
++	plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
++	plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void
++brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
++{
++	u8 rate_signal;
++	u32 tmp = 0;
++	int rate = rspec2rate(rspec);
++
++	/*
++	 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
++	 * transmitted first
++	 */
++	rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
++	memset(plcp, 0, D11_PHY_HDR_LEN);
++	D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
++
++	tmp = (length & 0xfff) << 5;
++	plcp[2] |= (tmp >> 16) & 0xff;
++	plcp[1] |= (tmp >> 8) & 0xff;
++	plcp[0] |= tmp & 0xff;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
++				 uint length, u8 *plcp)
++{
++	int rate = rspec2rate(rspec);
++
++	brcms_c_cck_plcp_set(wlc, rate, length, plcp);
++}
++
++static void
++brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
++		     uint length, u8 *plcp)
++{
++	if (is_mcs_rate(rspec))
++		brcms_c_compute_mimo_plcp(rspec, length, plcp);
++	else if (is_ofdm_rate(rspec))
++		brcms_c_compute_ofdm_plcp(rspec, length, plcp);
++	else
++		brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
++}
++
++/* brcms_c_compute_rtscts_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
++ * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
++ * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
++ *
++ * cts			cts-to-self or rts/cts
++ * rts_rate		rts or cts rate in unit of 500kbps
++ * rate			next MPDU rate in unit of 500kbps
++ * frame_len		next MPDU frame length in bytes
++ */
++u16
++brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++			   u32 rts_rate,
++			   u32 frame_rate, u8 rts_preamble_type,
++			   u8 frame_preamble_type, uint frame_len, bool ba)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	if (!cts_only) {
++		/* RTS/CTS */
++		dur = 3 * sifs;
++		dur +=
++		    (u16) brcms_c_calc_cts_time(wlc, rts_rate,
++					       rts_preamble_type);
++	} else {
++		/* CTS-TO-SELF */
++		dur = 2 * sifs;
++	}
++
++	dur +=
++	    (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
++					 frame_len);
++	if (ba)
++		dur +=
++		    (u16) brcms_c_calc_ba_time(wlc, frame_rate,
++					      BRCMS_SHORT_PREAMBLE);
++	else
++		dur +=
++		    (u16) brcms_c_calc_ack_time(wlc, frame_rate,
++					       frame_preamble_type);
++	return dur;
++}
++
++static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phyctl1 = 0;
++	u16 bw;
++
++	if (BRCMS_ISLCNPHY(wlc->band)) {
++		bw = PHY_TXC1_BW_20MHZ;
++	} else {
++		bw = rspec_get_bw(rspec);
++		/* 10Mhz is not supported yet */
++		if (bw < PHY_TXC1_BW_20MHZ) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
++				  "not supported yet, set to 20L\n", bw);
++			bw = PHY_TXC1_BW_20MHZ;
++		}
++	}
++
++	if (is_mcs_rate(rspec)) {
++		uint mcs = rspec & RSPEC_RATE_MASK;
++
++		/* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
++		phyctl1 = rspec_phytxbyte2(rspec);
++		/* set the upper byte of phyctl1 */
++		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
++	} else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
++		   && !BRCMS_ISSSLPNPHY(wlc->band)) {
++		/*
++		 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
++		 * Data Rate. Eventually MIMOPHY would also be converted to
++		 * this format
++		 */
++		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
++		phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	} else {		/* legacy OFDM/CCK */
++		s16 phycfg;
++		/* get the phyctl byte from rate phycfg table */
++		phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
++		if (phycfg == -1) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
++				  "legacy OFDM/CCK rate\n");
++			phycfg = 0;
++		}
++		/* set the upper byte of phyctl1 */
++		phyctl1 =
++		    (bw | (phycfg << 8) |
++		     (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	}
++	return phyctl1;
++}
++
++/*
++ * Add struct d11txh, struct cck_phy_hdr.
++ *
++ * 'p' data must start with 802.11 MAC header
++ * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
++ *
++ * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
++ *
++ */
++static u16
++brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
++		     struct sk_buff *p, struct scb *scb, uint frag,
++		     uint nfrags, uint queue, uint next_frag_len)
++{
++	struct ieee80211_hdr *h;
++	struct d11txh *txh;
++	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
++	int len, phylen, rts_phylen;
++	u16 mch, phyctl, xfts, mainrates;
++	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
++	u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	bool use_rts = false;
++	bool use_cts = false;
++	bool use_rifs = false;
++	bool short_preamble[2] = { false, false };
++	u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
++	struct ieee80211_rts *rts = NULL;
++	bool qos;
++	uint ac;
++	bool hwtkmic = false;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++#define ANTCFG_NONE 0xFF
++	u8 antcfg = ANTCFG_NONE;
++	u8 fbantcfg = ANTCFG_NONE;
++	uint phyctl1_stf = 0;
++	u16 durid = 0;
++	struct ieee80211_tx_rate *txrate[2];
++	int k;
++	struct ieee80211_tx_info *tx_info;
++	bool is_mcs;
++	u16 mimo_txbw;
++	u8 mimo_preamble_type;
++
++	/* locate 802.11 MAC header */
++	h = (struct ieee80211_hdr *)(p->data);
++	qos = ieee80211_is_data_qos(h->frame_control);
++
++	/* compute length of frame in bytes for use in PLCP computations */
++	len = p->len;
++	phylen = len + FCS_LEN;
++
++	/* Get tx_info */
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* add PLCP */
++	plcp = skb_push(p, D11_PHY_HDR_LEN);
++
++	/* add Broadcom tx descriptor header */
++	txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
++	memset(txh, 0, D11_TXH_LEN);
++
++	/* setup frameid */
++	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
++		/* non-AP STA should never use BCMC queue */
++		if (queue == TX_BCMC_FIFO) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
++				  "TX_BCMC!\n", wlc->pub->unit, __func__);
++			frameid = bcmc_fid_generate(wlc, NULL, txh);
++		} else {
++			/* Increment the counter for first fragment */
++			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
++				scb->seqnum[p->priority]++;
++
++			/* extract fragment number from frame first */
++			seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
++			seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
++			h->seq_ctrl = cpu_to_le16(seq);
++
++			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++			    (queue & TXFID_QUEUE_MASK);
++		}
++	}
++	frameid |= queue & TXFID_QUEUE_MASK;
++
++	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
++	if (ieee80211_is_beacon(h->frame_control))
++		mcl |= TXC_IGNOREPMQ;
++
++	txrate[0] = tx_info->control.rates;
++	txrate[1] = txrate[0] + 1;
++
++	/*
++	 * if rate control algorithm didn't give us a fallback
++	 * rate, use the primary rate
++	 */
++	if (txrate[1]->idx < 0)
++		txrate[1] = txrate[0];
++
++	for (k = 0; k < hw->max_rates; k++) {
++		is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
++		if (!is_mcs) {
++			if ((txrate[k]->idx >= 0)
++			    && (txrate[k]->idx <
++				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
++				rspec[k] =
++				    hw->wiphy->bands[tx_info->band]->
++				    bitrates[txrate[k]->idx].hw_value;
++				short_preamble[k] =
++				    txrate[k]->
++				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
++				    true : false;
++			} else {
++				rspec[k] = BRCM_RATE_1M;
++			}
++		} else {
++			rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
++					NRATE_MCS_INUSE | txrate[k]->idx);
++		}
++
++		/*
++		 * Currently only support same setting for primay and
++		 * fallback rates. Unify flags for each rate into a
++		 * single value for the frame
++		 */
++		use_rts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
++		use_cts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
++
++
++		/*
++		 * (1) RATE:
++		 *   determine and validate primary rate
++		 *   and fallback rates
++		 */
++		if (!rspec_active(rspec[k])) {
++			rspec[k] = BRCM_RATE_1M;
++		} else {
++			if (!is_multicast_ether_addr(h->addr1)) {
++				/* set tx antenna config */
++				brcms_c_antsel_antcfg_get(wlc->asi, false,
++					false, 0, 0, &antcfg, &fbantcfg);
++			}
++		}
++	}
++
++	phyctl1_stf = wlc->stf->ss_opmode;
++
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		for (k = 0; k < hw->max_rates; k++) {
++			/*
++			 * apply siso/cdd to single stream mcs's or ofdm
++			 * if rspec is auto selected
++			 */
++			if (((is_mcs_rate(rspec[k]) &&
++			      is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
++			     is_ofdm_rate(rspec[k]))
++			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
++				|| !(rspec[k] & RSPEC_OVERRIDE))) {
++				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
++
++				/* For SISO MCS use STBC if possible */
++				if (is_mcs_rate(rspec[k])
++				    && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
++					u8 stc;
++
++					/* Nss for single stream is always 1 */
++					stc = 1;
++					rspec[k] |= (PHY_TXC1_MODE_STBC <<
++							RSPEC_STF_SHIFT) |
++						    (stc << RSPEC_STC_SHIFT);
++				} else
++					rspec[k] |=
++					    (phyctl1_stf << RSPEC_STF_SHIFT);
++			}
++
++			/*
++			 * Is the phy configured to use 40MHZ frames? If
++			 * so then pick the desired txbw
++			 */
++			if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
++				/* default txbw is 20in40 SB */
++				mimo_ctlchbw = mimo_txbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++				if (is_mcs_rate(rspec[k])) {
++					/* mcs 32 must be 40b/w DUP */
++					if ((rspec[k] & RSPEC_RATE_MASK)
++					    == 32) {
++						mimo_txbw =
++						    PHY_TXC1_BW_40MHZ_DUP;
++						/* use override */
++					} else if (wlc->mimo_40txbw != AUTO)
++						mimo_txbw = wlc->mimo_40txbw;
++					/* else check if dst is using 40 Mhz */
++					else if (scb->flags & SCB_IS40)
++						mimo_txbw = PHY_TXC1_BW_40MHZ;
++				} else if (is_ofdm_rate(rspec[k])) {
++					if (wlc->ofdm_40txbw != AUTO)
++						mimo_txbw = wlc->ofdm_40txbw;
++				} else if (wlc->cck_40txbw != AUTO) {
++					mimo_txbw = wlc->cck_40txbw;
++				}
++			} else {
++				/*
++				 * mcs32 is 40 b/w only.
++				 * This is possible for probe packets on
++				 * a STA during SCAN
++				 */
++				if ((rspec[k] & RSPEC_RATE_MASK) == 32)
++					/* mcs 0 */
++					rspec[k] = RSPEC_MIMORATE;
++
++				mimo_txbw = PHY_TXC1_BW_20MHZ;
++			}
++
++			/* Set channel width */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
++				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
++			else
++				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++			/* Disable short GI, not supported yet */
++			rspec[k] &= ~RSPEC_SHORT_GI;
++
++			mimo_preamble_type = BRCMS_MM_PREAMBLE;
++			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
++				mimo_preamble_type = BRCMS_GF_PREAMBLE;
++
++			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
++			    && (!is_mcs_rate(rspec[k]))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
++					  "RC_MCS != is_mcs_rate(rspec)\n",
++					  wlc->pub->unit, __func__);
++			}
++
++			if (is_mcs_rate(rspec[k])) {
++				preamble_type[k] = mimo_preamble_type;
++
++				/*
++				 * if SGI is selected, then forced mm
++				 * for single stream
++				 */
++				if ((rspec[k] & RSPEC_SHORT_GI)
++				    && is_single_stream(rspec[k] &
++							RSPEC_RATE_MASK))
++					preamble_type[k] = BRCMS_MM_PREAMBLE;
++			}
++
++			/* should be better conditionalized */
++			if (!is_mcs_rate(rspec[0])
++			    && (tx_info->control.rates[0].
++				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
++				preamble_type[k] = BRCMS_SHORT_PREAMBLE;
++		}
++	} else {
++		for (k = 0; k < hw->max_rates; k++) {
++			/* Set ctrlchbw as 20Mhz */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
++
++			/* for nphy, stf of ofdm frames must follow policies */
++			if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
++				rspec[k] &= ~RSPEC_STF_MASK;
++				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
++			}
++		}
++	}
++
++	/* Reset these for use with AMPDU's */
++	txrate[0]->count = 0;
++	txrate[1]->count = 0;
++
++	/* (2) PROTECTION, may change rspec */
++	if ((ieee80211_is_data(h->frame_control) ||
++	    ieee80211_is_mgmt(h->frame_control)) &&
++	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
++		use_rts = true;
++
++	/* (3) PLCP: determine PLCP header and MAC duration,
++	 * fill struct d11txh */
++	brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
++	brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
++	memcpy(&txh->FragPLCPFallback,
++	       plcp_fallback, sizeof(txh->FragPLCPFallback));
++
++	/* Length field now put in CCK FBR CRC field */
++	if (is_cck_rate(rspec[1])) {
++		txh->FragPLCPFallback[4] = phylen & 0xff;
++		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
++	}
++
++	/* MIMO-RATE: need validation ?? */
++	mainrates = is_ofdm_rate(rspec[0]) ?
++			D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
++			plcp[0];
++
++	/* DUR field for main rate */
++	if (!ieee80211_is_pspoll(h->frame_control) &&
++	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
++		durid =
++		    brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
++					  next_frag_len);
++		h->duration_id = cpu_to_le16(durid);
++	} else if (use_rifs) {
++		/* NAV protect to end of next max packet size */
++		durid =
++		    (u16) brcms_c_calc_frame_time(wlc, rspec[0],
++						 preamble_type[0],
++						 DOT11_MAX_FRAG_LEN);
++		durid += RIFS_11N_TIME;
++		h->duration_id = cpu_to_le16(durid);
++	}
++
++	/* DUR field for fallback rate */
++	if (ieee80211_is_pspoll(h->frame_control))
++		txh->FragDurFallback = h->duration_id;
++	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
++		txh->FragDurFallback = 0;
++	else {
++		durid = brcms_c_compute_frame_dur(wlc, rspec[1],
++					      preamble_type[1], next_frag_len);
++		txh->FragDurFallback = cpu_to_le16(durid);
++	}
++
++	/* (4) MAC-HDR: MacTxControlLow */
++	if (frag == 0)
++		mcl |= TXC_STARTMSDU;
++
++	if (!is_multicast_ether_addr(h->addr1))
++		mcl |= TXC_IMMEDACK;
++
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		mcl |= TXC_FREQBAND_5G;
++
++	if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
++		mcl |= TXC_BW_40;
++
++	/* set AMIC bit if using hardware TKIP MIC */
++	if (hwtkmic)
++		mcl |= TXC_AMIC;
++
++	txh->MacTxControlLow = cpu_to_le16(mcl);
++
++	/* MacTxControlHigh */
++	mch = 0;
++
++	/* Set fallback rate preamble type */
++	if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
++			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
++	}
++
++	/* MacFrameControl */
++	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
++	txh->TxFesTimeNormal = cpu_to_le16(0);
++
++	txh->TxFesTimeFallback = cpu_to_le16(0);
++
++	/* TxFrameRA */
++	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
++
++	/* TxFrameID */
++	txh->TxFrameID = cpu_to_le16(frameid);
++
++	/*
++	 * TxStatus, Note the case of recreating the first frag of a suppressed
++	 * frame then we may need to reset the retry cnt's via the status reg
++	 */
++	txh->TxStatus = cpu_to_le16(status);
++
++	/*
++	 * extra fields for ucode AMPDU aggregation, the new fields are added to
++	 * the END of previous structure so that it's compatible in driver.
++	 */
++	txh->MaxNMpdus = cpu_to_le16(0);
++	txh->MaxABytes_MRT = cpu_to_le16(0);
++	txh->MaxABytes_FBR = cpu_to_le16(0);
++	txh->MinMBytes = cpu_to_le16(0);
++
++	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
++	 * furnish struct d11txh */
++	/* RTS PLCP header and RTS frame */
++	if (use_rts || use_cts) {
++		if (use_rts && use_cts)
++			use_cts = false;
++
++		for (k = 0; k < 2; k++) {
++			rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
++							      false,
++							      mimo_ctlchbw);
++		}
++
++		if (!is_ofdm_rate(rts_rspec[0]) &&
++		    !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
++		}
++
++		if (!is_ofdm_rate(rts_rspec[1]) &&
++		    !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
++		}
++
++		/* RTS/CTS additions to MacTxControlLow */
++		if (use_cts) {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
++		} else {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
++			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
++		}
++
++		/* RTS PLCP header */
++		rts_plcp = txh->RTSPhyHeader;
++		if (use_cts)
++			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
++		else
++			rts_phylen = DOT11_RTS_LEN + FCS_LEN;
++
++		brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
++
++		/* fallback rate version of RTS PLCP header */
++		brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
++				 rts_plcp_fallback);
++		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
++		       sizeof(txh->RTSPLCPFallback));
++
++		/* RTS frame fields... */
++		rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
++					       rspec[0], rts_preamble_type[0],
++					       preamble_type[0], phylen, false);
++		rts->duration = cpu_to_le16(durid);
++		/* fallback rate version of RTS DUR field */
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++					       rts_rspec[1], rspec[1],
++					       rts_preamble_type[1],
++					       preamble_type[1], phylen, false);
++		txh->RTSDurFallback = cpu_to_le16(durid);
++
++		if (use_cts) {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_CTS);
++
++			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
++		} else {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_RTS);
++
++			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
++		}
++
++		/* mainrate
++		 *    low 8 bits: main frag rate/mcs,
++		 *    high 8 bits: rts/cts rate/mcs
++		 */
++		mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
++				D11A_PHY_HDR_GRATE(
++					(struct ofdm_phy_hdr *) rts_plcp) :
++				rts_plcp[0]) << 8;
++	} else {
++		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
++		memset((char *)&txh->rts_frame, 0,
++			sizeof(struct ieee80211_rts));
++		memset((char *)txh->RTSPLCPFallback, 0,
++		      sizeof(txh->RTSPLCPFallback));
++		txh->RTSDurFallback = 0;
++	}
++
++#ifdef SUPPORT_40MHZ
++	/* add null delimiter count */
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
++		   brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
++
++#endif
++
++	/*
++	 * Now that RTS/RTS FB preamble types are updated, write
++	 * the final value
++	 */
++	txh->MacTxControlHigh = cpu_to_le16(mch);
++
++	/*
++	 * MainRates (both the rts and frag plcp rates have
++	 * been calculated now)
++	 */
++	txh->MainRates = cpu_to_le16(mainrates);
++
++	/* XtraFrameTypes */
++	xfts = frametype(rspec[1], wlc->mimoft);
++	xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
++	xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
++	xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
++							     XFTS_CHANNEL_SHIFT;
++	txh->XtraFrameTypes = cpu_to_le16(xfts);
++
++	/* PhyTxControlWord */
++	phyctl = frametype(rspec[0], wlc->mimoft);
++	if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
++			phyctl |= PHY_TXC_SHORT_HDR;
++	}
++
++	/* phytxant is properly bit shifted */
++	phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
++	txh->PhyTxControlWord = cpu_to_le16(phyctl);
++
++	/* PhyTxControlWord_1 */
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		u16 phyctl1 = 0;
++
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
++		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
++		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
++
++		if (use_rts || use_cts) {
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
++			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
++			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
++		}
++
++		/*
++		 * For mcs frames, if mixedmode(overloaded with long preamble)
++		 * is going to be set, fill in non-zero MModeLen and/or
++		 * MModeFbrLen it will be unnecessary if they are separated
++		 */
++		if (is_mcs_rate(rspec[0]) &&
++		    (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++		}
++
++		if (is_mcs_rate(rspec[1]) &&
++		    (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodefbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
++			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
++		}
++	}
++
++	ac = skb_get_queue_mapping(p);
++	if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
++		uint frag_dur, dur, dur_fallback;
++
++		/* WME: Update TXOP threshold */
++		if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
++			frag_dur =
++			    brcms_c_calc_frame_time(wlc, rspec[0],
++					preamble_type[0], phylen);
++
++			if (rts) {
++				/* 1 RTS or CTS-to-self frame */
++				dur =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[0],
++						      rts_preamble_type[0]);
++				dur_fallback =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[1],
++						      rts_preamble_type[1]);
++				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
++				dur += le16_to_cpu(rts->duration);
++				dur_fallback +=
++					le16_to_cpu(txh->RTSDurFallback);
++			} else if (use_rifs) {
++				dur = frag_dur;
++				dur_fallback = 0;
++			} else {
++				/* frame + SIFS + ACK */
++				dur = frag_dur;
++				dur +=
++				    brcms_c_compute_frame_dur(wlc, rspec[0],
++							  preamble_type[0], 0);
++
++				dur_fallback =
++				    brcms_c_calc_frame_time(wlc, rspec[1],
++							preamble_type[1],
++							phylen);
++				dur_fallback +=
++				    brcms_c_compute_frame_dur(wlc, rspec[1],
++							  preamble_type[1], 0);
++			}
++			/* NEED to set TxFesTimeNormal (hard) */
++			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
++			/*
++			 * NEED to set fallback rate version of
++			 * TxFesTimeNormal (hard)
++			 */
++			txh->TxFesTimeFallback =
++				cpu_to_le16((u16) dur_fallback);
++
++			/*
++			 * update txop byte threshold (txop minus intraframe
++			 * overhead)
++			 */
++			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
++				uint newfragthresh;
++
++				newfragthresh =
++				    brcms_c_calc_frame_len(wlc,
++					rspec[0], preamble_type[0],
++					(wlc->edcf_txop[ac] -
++						(dur - frag_dur)));
++				/* range bound the fragthreshold */
++				if (newfragthresh < DOT11_MIN_FRAG_LEN)
++					newfragthresh =
++					    DOT11_MIN_FRAG_LEN;
++				else if (newfragthresh >
++					 wlc->usr_fragthresh)
++					newfragthresh =
++					    wlc->usr_fragthresh;
++				/* update the fragthresh and do txc update */
++				if (wlc->fragthresh[queue] !=
++				    (u16) newfragthresh)
++					wlc->fragthresh[queue] =
++					    (u16) newfragthresh;
++			} else {
++				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
++					  "for rate %d\n",
++					  wlc->pub->unit, fifo_names[queue],
++					  rspec2rate(rspec[0]));
++			}
++
++			if (dur > wlc->edcf_txop[ac])
++				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
++					  "exceeded phylen %d/%d dur %d/%d\n",
++					  wlc->pub->unit, __func__,
++					  fifo_names[queue],
++					  phylen, wlc->fragthresh[queue],
++					  dur, wlc->edcf_txop[ac]);
++		}
++	}
++
++	return 0;
++}
++
++void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
++			      struct ieee80211_hw *hw)
++{
++	u8 prio;
++	uint fifo;
++	struct scb *scb = &wlc->pri_scb;
++	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
++
++	/*
++	 * 802.11 standard requires management traffic
++	 * to go at highest priority
++	 */
++	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
++		MAXPRIO;
++	fifo = prio2fifo[prio];
++	if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
++		return;
++	brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
++	brcms_c_send_q(wlc);
++}
++
++void brcms_c_send_q(struct brcms_c_info *wlc)
++{
++	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
++	int prec;
++	u16 prec_map;
++	int err = 0, i, count;
++	uint fifo;
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *q = &qi->q;
++	struct ieee80211_tx_info *tx_info;
++
++	prec_map = wlc->tx_prec_map;
++
++	/* Send all the enq'd pkts that we can.
++	 * Dequeue packets with precedence with empty HW fifo only
++	 */
++	while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
++		tx_info = IEEE80211_SKB_CB(pkt[0]);
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
++		} else {
++			count = 1;
++			err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
++			if (!err) {
++				for (i = 0; i < count; i++)
++					brcms_c_txfifo(wlc, fifo, pkt[i], true,
++						       1);
++			}
++		}
++
++		if (err == -EBUSY) {
++			brcmu_pktq_penq_head(q, prec, pkt[0]);
++			/*
++			 * If send failed due to any other reason than a
++			 * change in HW FIFO condition, quit. Otherwise,
++			 * read the new prec_map!
++			 */
++			if (prec_map == wlc->tx_prec_map)
++				break;
++			prec_map = wlc->tx_prec_map;
++		}
++	}
++}
++
++void
++brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
++	       bool commit, s8 txpktpend)
++{
++	u16 frameid = INVALIDFID;
++	struct d11txh *txh;
++
++	txh = (struct d11txh *) (p->data);
++
++	/* When a BC/MC frame is being committed to the BCMC fifo
++	 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
++	 */
++	if (fifo == TX_BCMC_FIFO)
++		frameid = le16_to_cpu(txh->TxFrameID);
++
++	/*
++	 * Bump up pending count for if not using rpc. If rpc is
++	 * used, this will be handled in brcms_b_txfifo()
++	 */
++	if (commit) {
++		wlc->core->txpktpend[fifo] += txpktpend;
++		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
++			 txpktpend, wlc->core->txpktpend[fifo]);
++	}
++
++	/* Commit BCMC sequence number in the SHM frame ID location */
++	if (frameid != INVALIDFID) {
++		/*
++		 * To inform the ucode of the last mcast frame posted
++		 * so that it can clear moredata bit
++		 */
++		brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
++	}
++
++	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
++		wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
++}
++
++u32
++brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
++			   bool use_rspec, u16 mimo_ctlchbw)
++{
++	u32 rts_rspec = 0;
++
++	if (use_rspec)
++		/* use frame rate as rts rate */
++		rts_rspec = rspec;
++	else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
++		/* Use 11Mbps as the g protection RTS target rate and fallback.
++		 * Use the brcms_basic_rate() lookup to find the best basic rate
++		 * under the target in case 11 Mbps is not Basic.
++		 * 6 and 9 Mbps are not usually selected by rate selection, but
++		 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
++		 * is more robust.
++		 */
++		rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
++	else
++		/* calculate RTS rate and fallback rate based on the frame rate
++		 * RTS must be sent at a basic rate since it is a
++		 * control frame, sec 9.6 of 802.11 spec
++		 */
++		rts_rspec = brcms_basic_rate(wlc, rspec);
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		/* set rts txbw to correct side band */
++		rts_rspec &= ~RSPEC_BW_MASK;
++
++		/*
++		 * if rspec/rspec_fallback is 40MHz, then send RTS on both
++		 * 20MHz channel (DUP), otherwise send RTS on control channel
++		 */
++		if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
++			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
++		else
++			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++		/* pick siso/cdd as default for ofdm */
++		if (is_ofdm_rate(rts_rspec)) {
++			rts_rspec &= ~RSPEC_STF_MASK;
++			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
++		}
++	}
++	return rts_rspec;
++}
++
++void
++brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
++{
++	wlc->core->txpktpend[fifo] -= txpktpend;
++	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
++	       wlc->core->txpktpend[fifo]);
++
++	/* There is more room; mark precedences related to this FIFO sendable */
++	wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
++
++	/* figure out which bsscfg is being worked on... */
++}
++
++/* Update beacon listen interval in shared memory */
++static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
++{
++	/* wake up every DTIM is the default */
++	if (wlc->bcn_li_dtim == 1)
++		brcms_b_write_shm(wlc->hw, M_BCN_LI, 0);
++	else
++		brcms_b_write_shm(wlc->hw, M_BCN_LI,
++			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
++}
++
++static void
++brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
++		  u32 *tsf_h_ptr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	/* read the tsf timer low, then high to get an atomic read */
++	*tsf_l_ptr = bcma_read32(core, D11REGOFFS(tsf_timerlow));
++	*tsf_h_ptr = bcma_read32(core, D11REGOFFS(tsf_timerhigh));
++}
++
++/*
++ * recover 64bit TSF value from the 16bit TSF value in the rx header
++ * given the assumption that the TSF passed in header is within 65ms
++ * of the current tsf.
++ *
++ * 6       5       4       4       3       2       1
++ * 3.......6.......8.......0.......2.......4.......6.......8......0
++ * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
++ *
++ * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
++ * tsf_l is filled in by brcms_b_recv, which is done earlier in the
++ * receive call sequence after rx interrupt. Only the higher 16 bits
++ * are used. Finally, the tsf_h is read from the tsf register.
++ */
++static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
++				 struct d11rxhdr *rxh)
++{
++	u32 tsf_h, tsf_l;
++	u16 rx_tsf_0_15, rx_tsf_16_31;
++
++	brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
++
++	rx_tsf_16_31 = (u16)(tsf_l >> 16);
++	rx_tsf_0_15 = rxh->RxTSFTime;
++
++	/*
++	 * a greater tsf time indicates the low 16 bits of
++	 * tsf_l wrapped, so decrement the high 16 bits.
++	 */
++	if ((u16)tsf_l < rx_tsf_0_15) {
++		rx_tsf_16_31 -= 1;
++		if (rx_tsf_16_31 == 0xffff)
++			tsf_h -= 1;
++	}
++
++	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
++}
++
++static void
++prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		     struct sk_buff *p,
++		     struct ieee80211_rx_status *rx_status)
++{
++	int preamble;
++	int channel;
++	u32 rspec;
++	unsigned char *plcp;
++
++	/* fill in TSF and flag its presence */
++	rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
++	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
++
++	channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
++
++	if (channel > 14) {
++		rx_status->band = IEEE80211_BAND_5GHZ;
++		rx_status->freq = ieee80211_ofdm_chan_to_freq(
++					WF_CHAN_FACTOR_5_G/2, channel);
++
++	} else {
++		rx_status->band = IEEE80211_BAND_2GHZ;
++		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
++	}
++
++	rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
++
++	/* noise */
++	/* qual */
++	rx_status->antenna =
++		(rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
++
++	plcp = p->data;
++
++	rspec = brcms_c_compute_rspec(rxh, plcp);
++	if (is_mcs_rate(rspec)) {
++		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
++		rx_status->flag |= RX_FLAG_HT;
++		if (rspec_is40mhz(rspec))
++			rx_status->flag |= RX_FLAG_40MHZ;
++	} else {
++		switch (rspec2rate(rspec)) {
++		case BRCM_RATE_1M:
++			rx_status->rate_idx = 0;
++			break;
++		case BRCM_RATE_2M:
++			rx_status->rate_idx = 1;
++			break;
++		case BRCM_RATE_5M5:
++			rx_status->rate_idx = 2;
++			break;
++		case BRCM_RATE_11M:
++			rx_status->rate_idx = 3;
++			break;
++		case BRCM_RATE_6M:
++			rx_status->rate_idx = 4;
++			break;
++		case BRCM_RATE_9M:
++			rx_status->rate_idx = 5;
++			break;
++		case BRCM_RATE_12M:
++			rx_status->rate_idx = 6;
++			break;
++		case BRCM_RATE_18M:
++			rx_status->rate_idx = 7;
++			break;
++		case BRCM_RATE_24M:
++			rx_status->rate_idx = 8;
++			break;
++		case BRCM_RATE_36M:
++			rx_status->rate_idx = 9;
++			break;
++		case BRCM_RATE_48M:
++			rx_status->rate_idx = 10;
++			break;
++		case BRCM_RATE_54M:
++			rx_status->rate_idx = 11;
++			break;
++		default:
++			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
++		}
++
++		/*
++		 * For 5GHz, we should decrease the index as it is
++		 * a subset of the 2.4G rates. See bitrates field
++		 * of brcms_band_5GHz_nphy (in mac80211_if.c).
++		 */
++		if (rx_status->band == IEEE80211_BAND_5GHZ)
++			rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
++
++		/* Determine short preamble and rate_idx */
++		preamble = 0;
++		if (is_cck_rate(rspec)) {
++			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
++				rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else if (is_ofdm_rate(rspec)) {
++			rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
++				  __func__);
++		}
++	}
++
++	if (plcp3_issgi(plcp[3]))
++		rx_status->flag |= RX_FLAG_SHORT_GI;
++
++	if (rxh->RxStatus1 & RXS_DECERR) {
++		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
++			  __func__);
++	}
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
++			  __func__);
++	}
++}
++
++static void
++brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		struct sk_buff *p)
++{
++	int len_mpdu;
++	struct ieee80211_rx_status rx_status;
++	struct ieee80211_hdr *hdr;
++
++	memset(&rx_status, 0, sizeof(rx_status));
++	prep_mac80211_status(wlc, rxh, p, &rx_status);
++
++	/* mac header+body length, exclude CRC and plcp header */
++	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
++	skb_pull(p, D11_PHY_HDR_LEN);
++	__skb_trim(p, len_mpdu);
++
++	/* unmute transmit */
++	if (wlc->hw->suspended_fifos) {
++		hdr = (struct ieee80211_hdr *)p->data;
++		if (ieee80211_is_beacon(hdr->frame_control))
++			brcms_b_mute(wlc->hw, false);
++	}
++
++	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
++	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
++}
++
++/* calculate frame duration for Mixed-mode L-SIG spoofing, return
++ * number of bytes goes in the length field
++ *
++ * Formula given by HT PHY Spec v 1.13
++ *   len = 3(nsyms + nstream + 3) - 3
++ */
++u16
++brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++		      uint mac_len)
++{
++	uint nsyms, len = 0, kNdps;
++
++	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
++		 wlc->pub->unit, rspec2rate(ratespec), mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = (mcs_2_txstreams(mcs) + 1) +
++				  rspec_stc(ratespec);
++
++		/*
++		 * the payload duration calculation matches that
++		 * of regular ofdm
++		 */
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		/* (+3) account for HT-SIG(2) and HT-STF(1) */
++		nsyms += (tot_streams + 3);
++		/*
++		 * 3 bytes/symbol @ legacy 6Mbps rate
++		 * (-3) excluding service bits and tail bits
++		 */
++		len = (3 * nsyms) - 3;
++	}
++
++	return (u16) len;
++}
++
++static void
++brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate;
++	u16 entry_ptr;
++	u8 plcp[D11_PHY_HDR_LEN];
++	u16 dur, sifs;
++	uint i;
++
++	sifs = get_sifs(wlc->band);
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/*
++	 * walk the phy rate table and update MAC core SHM
++	 * basic rate table entries
++	 */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
++
++		/* Calculate the Probe Response PLCP for the given rate */
++		brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
++
++		/*
++		 * Calculate the duration of the Probe Response
++		 * frame plus SIFS for the MAC
++		 */
++		dur = (u16) brcms_c_calc_frame_time(wlc, rate,
++						BRCMS_LONG_PREAMBLE, frame_len);
++		dur += sifs;
++
++		/* Update the SHM Rate Table entry Probe Response values */
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
++			      (u16) (plcp[0] + (plcp[1] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
++			      (u16) (plcp[2] + (plcp[3] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
++	}
++}
++
++/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
++ *
++ *	PLCP header is 6 bytes.
++ *	802.11 A3 header is 24 bytes.
++ *	Max beacon frame body template length is 112 bytes.
++ *	Max probe resp frame body template length is 110 bytes.
++ *
++ *      *len on input contains the max length of the packet available.
++ *
++ *	The *len value is set to the number of bytes in buf used, and starts
++ *	with the PLCP and included up to, but not including, the 4 byte FCS.
++ */
++static void
++brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
++			 u32 bcn_rspec,
++			 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
++{
++	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++	struct cck_phy_hdr *plcp;
++	struct ieee80211_mgmt *h;
++	int hdr_len, body_len;
++
++	hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
++
++	/* calc buffer size provided for frame body */
++	body_len = *len - hdr_len;
++	/* return actual size */
++	*len = hdr_len + body_len;
++
++	/* format PHY and MAC headers */
++	memset((char *)buf, 0, hdr_len);
++
++	plcp = (struct cck_phy_hdr *) buf;
++
++	/*
++	 * PLCP for Probe Response frames are filled in from
++	 * core's rate table
++	 */
++	if (type == IEEE80211_STYPE_BEACON)
++		/* fill in PLCP */
++		brcms_c_compute_plcp(wlc, bcn_rspec,
++				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
++				 (u8 *) plcp);
++
++	/* "Regular" and 16 MBSS but not for 4 MBSS */
++	/* Update the phytxctl for the beacon based on the rspec */
++	brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
++
++	h = (struct ieee80211_mgmt *)&plcp[1];
++
++	/* fill in 802.11 header */
++	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
++
++	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
++	/* A1 filled in by MAC for prb resp, broadcast for bcn */
++	if (type == IEEE80211_STYPE_BEACON)
++		memcpy(&h->da, &ether_bcast, ETH_ALEN);
++	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
++	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
++
++	/* SEQ filled in by MAC */
++}
++
++int brcms_c_get_header_len(void)
++{
++	return TXOFF;
++}
++
++/*
++ * Update all beacons for the system.
++ */
++void brcms_c_update_beacon(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	if (bsscfg->up && !bsscfg->BSS)
++		/* Clear the soft intmask */
++		wlc->defmacintmask &= ~MI_BCNTPL;
++}
++
++/* Write ssid into shared memory */
++static void
++brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
++{
++	u8 *ssidptr = cfg->SSID;
++	u16 base = M_SSID;
++	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
++
++	/* padding the ssid with zero and copy it into shm */
++	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
++	memcpy(ssidbuf, ssidptr, cfg->SSID_len);
++
++	brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
++	brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
++}
++
++static void
++brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
++			      struct brcms_bss_cfg *cfg,
++			      bool suspend)
++{
++	u16 prb_resp[BCN_TMPL_LEN / 2];
++	int len = BCN_TMPL_LEN;
++
++	/*
++	 * write the probe response to hardware, or save in
++	 * the config structure
++	 */
++
++	/* create the probe response template */
++	brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
++				 cfg, prb_resp, &len);
++
++	if (suspend)
++		brcms_c_suspend_mac_and_wait(wlc);
++
++	/* write the probe response into the template region */
++	brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
++				    (len + 3) & ~3, prb_resp);
++
++	/* write the length of the probe response frame (+PLCP/-FCS) */
++	brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
++
++	/* write the SSID and SSID length */
++	brcms_c_shm_ssid_upd(wlc, cfg);
++
++	/*
++	 * Write PLCP headers and durations for probe response frames
++	 * at all rates. Use the actual frame length covered by the
++	 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
++	 * by subtracting the PLCP len and adding the FCS.
++	 */
++	len += (-D11_PHY_HDR_LEN + FCS_LEN);
++	brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
++
++	if (suspend)
++		brcms_c_enable_mac(wlc);
++}
++
++void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	/* update AP or IBSS probe responses */
++	if (bsscfg->up && !bsscfg->BSS)
++		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
++}
++
++/* prepares pdu for transmission. returns BCM error codes */
++int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
++{
++	uint fifo;
++	struct d11txh *txh;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++
++	txh = (struct d11txh *) (pdu->data);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	/* get the pkt queue info. This was put at brcms_c_sendctl or
++	 * brcms_c_send for PDU */
++	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
++
++	scb = NULL;
++
++	*fifop = fifo;
++
++	/* return if insufficient dma resources */
++	if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
++		/* Mark precedences related to this FIFO, unsendable */
++		/* A fifo is full. Clear precedences related to that FIFO */
++		wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
++		return -EBUSY;
++	}
++	return 0;
++}
++
++int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++			   uint *blocks)
++{
++	if (fifo >= NFIFO)
++		return -EINVAL;
++
++	*blocks = wlc_hw->xmtfifo_sz[fifo];
++
++	return 0;
++}
++
++void
++brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
++		  const u8 *addr)
++{
++	brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
++	if (match_reg_offset == RCM_BSSID_OFFSET)
++		memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
++}
++
++/*
++ * Flag 'scan in progress' to withhold dynamic phy calibration
++ */
++void brcms_c_scan_start(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
++}
++
++void brcms_c_scan_stop(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
++}
++
++void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
++{
++	wlc->pub->associated = state;
++	wlc->bsscfg->associated = state;
++}
++
++/*
++ * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
++ * AMPDU traffic, packets pending in hardware have to be invalidated so that
++ * when later on hardware releases them, they can be handled appropriately.
++ */
++void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn))
++{
++	struct dma_pub *dmah;
++	int i;
++	for (i = 0; i < NFIFO; i++) {
++		dmah = hw->di[i];
++		if (dmah != NULL)
++			dma_walk_packets(dmah, dma_callback_fn, sta);
++	}
++}
++
++int brcms_c_get_curband(struct brcms_c_info *wlc)
++{
++	return wlc->band->bandunit;
++}
++
++void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
++{
++	int timeout = 20;
++
++	/* flush packet queue when requested */
++	if (drop)
++		brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
++
++	/* wait for queue and DMA fifos to run dry */
++	while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
++		brcms_msleep(wlc->wl, 1);
++
++		if (--timeout == 0)
++			break;
++	}
++
++	WARN_ON_ONCE(timeout == 0);
++}
++
++void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
++{
++	wlc->bcn_li_bcn = interval;
++	if (wlc->pub->up)
++		brcms_c_bcn_li_upd(wlc);
++}
++
++int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
++{
++	uint qdbm;
++
++	/* Remove override bit and clip to max qdbm value */
++	qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
++	return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
++}
++
++int brcms_c_get_tx_power(struct brcms_c_info *wlc)
++{
++	uint qdbm;
++	bool override;
++
++	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
++
++	/* Return qdbm units */
++	return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
++{
++	struct d11rxhdr *rxh;
++	struct ieee80211_hdr *h;
++	uint len;
++	bool is_amsdu;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* frame starts with rxhdr */
++	rxh = (struct d11rxhdr *) (p->data);
++
++	/* strip off rxhdr */
++	skb_pull(p, BRCMS_HWRXOFF);
++
++	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
++	if (rxh->RxStatus1 & RXS_PBPRES) {
++		if (p->len < 2) {
++			wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
++				  "len %d\n", wlc->pub->unit, p->len);
++			goto toss;
++		}
++		skb_pull(p, 2);
++	}
++
++	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
++	len = p->len;
++
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		if (!(wlc->filter_flags & FIF_FCSFAIL))
++			goto toss;
++	}
++
++	/* check received pkt has at least frame control field */
++	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
++		goto toss;
++
++	/* not supporting A-MSDU */
++	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
++	if (is_amsdu)
++		goto toss;
++
++	brcms_c_recvctl(wlc, rxh, p);
++	return;
++
++ toss:
++	brcmu_pkt_buf_free_skb(p);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static bool
++brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
++{
++	struct sk_buff *p;
++	struct sk_buff *next = NULL;
++	struct sk_buff_head recv_frames;
++
++	uint n = 0;
++	uint bound_limit = bound ? RXBND : -1;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	skb_queue_head_init(&recv_frames);
++
++	/* gather received frames */
++	while (dma_rx(wlc_hw->di[fifo], &recv_frames)) {
++
++		/* !give others some time to run! */
++		if (++n >= bound_limit)
++			break;
++	}
++
++	/* post more rbufs */
++	dma_rxfill(wlc_hw->di[fifo]);
++
++	/* process each frame */
++	skb_queue_walk_safe(&recv_frames, p, next) {
++		struct d11rxhdr_le *rxh_le;
++		struct d11rxhdr *rxh;
++
++		skb_unlink(p, &recv_frames);
++		rxh_le = (struct d11rxhdr_le *)p->data;
++		rxh = (struct d11rxhdr *)p->data;
++
++		/* fixup rx header endianness */
++		rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
++		rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
++		rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
++		rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
++		rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
++		rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
++		rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
++		rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
++		rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
++		rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
++		rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
++
++		brcms_c_recv(wlc_hw->wlc, p);
++	}
++
++	return n >= bound_limit;
++}
++
++/* second-level interrupt processing
++ *   Return true if another dpc needs to be re-scheduled. false otherwise.
++ *   Param 'bounded' indicates if applicable loops should be bounded.
++ */
++bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
++{
++	u32 macintstatus;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return false;
++	}
++
++	/* grab and clear the saved software intstatus bits */
++	macintstatus = wlc->macintstatus;
++	wlc->macintstatus = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
++	       wlc_hw->unit, macintstatus);
++
++	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
++
++	/* tx status */
++	if (macintstatus & MI_TFS) {
++		bool fatal;
++		if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
++			wlc->macintstatus |= MI_TFS;
++		if (fatal) {
++			wiphy_err(wiphy, "MI_TFS: fatal\n");
++			goto fatal;
++		}
++	}
++
++	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
++		brcms_c_tbtt(wlc);
++
++	/* ATIM window end */
++	if (macintstatus & MI_ATIMWINEND) {
++		BCMMSG(wlc->wiphy, "end of ATIM window\n");
++		bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
++		wlc->qvalid = 0;
++	}
++
++	/*
++	 * received data or control frame, MI_DMAINT is
++	 * indication of RX_FIFO interrupt
++	 */
++	if (macintstatus & MI_DMAINT)
++		if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
++			wlc->macintstatus |= MI_DMAINT;
++
++	/* noise sample collected */
++	if (macintstatus & MI_BG_NOISE)
++		wlc_phy_noise_sample_intr(wlc_hw->band->pi);
++
++	if (macintstatus & MI_GP0) {
++		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
++			  "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
++
++		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
++			    __func__, ai_get_chip_id(wlc_hw->sih),
++			    ai_get_chiprev(wlc_hw->sih));
++		brcms_fatal_error(wlc_hw->wlc->wl);
++	}
++
++	/* gptimer timeout */
++	if (macintstatus & MI_TO)
++		bcma_write32(core, D11REGOFFS(gptimer), 0);
++
++	if (macintstatus & MI_RFDISABLE) {
++		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
++		       " RF Disable Input\n", wlc_hw->unit);
++		brcms_rfkill_set_hw_state(wlc->wl);
++	}
++
++	/* send any enq'd tx packets. Just makes sure to jump start tx */
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	/* it isn't done and needs to be resched if macintstatus is non-zero */
++	return wlc->macintstatus != 0;
++
++ fatal:
++	brcms_fatal_error(wlc_hw->wlc->wl);
++	return wlc->macintstatus != 0;
++}
++
++void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
++{
++	struct bcma_device *core = wlc->hw->d11core;
++	u16 chanspec;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/*
++	 * This will happen if a big-hammer was executed. In
++	 * that case, we want to go back to the channel that
++	 * we were on and not new channel
++	 */
++	if (wlc->pub->associated)
++		chanspec = wlc->home_chanspec;
++	else
++		chanspec = brcms_c_init_chanspec(wlc);
++
++	brcms_b_init(wlc->hw, chanspec);
++
++	/* update beacon listen interval */
++	brcms_c_bcn_li_upd(wlc);
++
++	/* write ethernet address to core */
++	brcms_c_set_mac(wlc->bsscfg);
++	brcms_c_set_bssid(wlc->bsscfg);
++
++	/* Update tsf_cfprep if associated and up */
++	if (wlc->pub->associated && wlc->bsscfg->up) {
++		u32 bi;
++
++		/* get beacon period and convert to uS */
++		bi = wlc->bsscfg->current_bss->beacon_period << 10;
++		/*
++		 * update since init path would reset
++		 * to default value
++		 */
++		bcma_write32(core, D11REGOFFS(tsf_cfprep),
++			     bi << CFPREP_CBI_SHIFT);
++
++		/* Update maccontrol PM related bits */
++		brcms_c_set_ps_ctrl(wlc);
++	}
++
++	brcms_c_bandinit_ordered(wlc, chanspec);
++
++	/* init probe response timeout */
++	brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
++
++	/* init max burst txop (framebursting) */
++	brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
++		      (wlc->
++		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
++
++	/* initialize maximum allowed duty cycle */
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
++
++	/*
++	 * Update some shared memory locations related to
++	 * max AMPDU size allowed to received
++	 */
++	brcms_c_ampdu_shm_upd(wlc->ampdu);
++
++	/* band-specific inits */
++	brcms_c_bsinit(wlc);
++
++	/* Enable EDCF mode (while the MAC is suspended) */
++	bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
++	brcms_c_edcf_setparams(wlc, false);
++
++	/* Init precedence maps for empty FIFOs */
++	brcms_c_tx_prec_map_init(wlc);
++
++	/* read the ucode version if we have not yet done so */
++	if (wlc->ucode_rev == 0) {
++		wlc->ucode_rev =
++		    brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
++		wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
++	}
++
++	/* ..now really unleash hell (allow the MAC out of suspend) */
++	brcms_c_enable_mac(wlc);
++
++	/* suspend the tx fifos and mute the phy for preism cac time */
++	if (mute_tx)
++		brcms_b_mute(wlc->hw, true);
++
++	/* clear tx flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* enable the RF Disable Delay timer */
++	bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);
++
++	/*
++	 * Initialize WME parameters; if they haven't been set by some other
++	 * mechanism (IOVar, etc) then read them from the hardware.
++	 */
++	if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
++		/* Uninitialized; read from HW */
++		int ac;
++
++		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++			wlc->wme_retries[ac] =
++			    brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
++	}
++}
++
++/*
++ * The common driver entry routine. Error codes should be unique
++ */
++struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr)
++{
++	struct brcms_c_info *wlc;
++	uint err = 0;
++	uint i, j;
++	struct brcms_pub *pub;
++
++	/* allocate struct brcms_c_info state and its substructures */
++	wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0);
++	if (wlc == NULL)
++		goto fail;
++	wlc->wiphy = wl->wiphy;
++	pub = wlc->pub;
++
++#if defined(DEBUG)
++	wlc_info_dbg = wlc;
++#endif
++
++	wlc->band = wlc->bandstate[0];
++	wlc->core = wlc->corestate;
++	wlc->wl = wl;
++	pub->unit = unit;
++	pub->_piomode = piomode;
++	wlc->bandinit_pending = false;
++
++	/* populate struct brcms_c_info with default values  */
++	brcms_c_info_init(wlc, unit);
++
++	/* update sta/ap related parameters */
++	brcms_c_ap_upd(wlc);
++
++	/*
++	 * low level attach steps(all hw accesses go
++	 * inside, no more in rest of the attach)
++	 */
++	err = brcms_b_attach(wlc, core, unit, piomode);
++	if (err)
++		goto fail;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
++
++	pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
++
++	/* disable allowed duty cycle */
++	wlc->tx_duty_cycle_ofdm = 0;
++	wlc->tx_duty_cycle_cck = 0;
++
++	brcms_c_stf_phy_chain_calc(wlc);
++
++	/* txchain 1: txant 0, txchain 2: txant 1 */
++	if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
++		wlc->stf->txant = wlc->stf->hw_txchain - 1;
++
++	/* push to BMAC driver */
++	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
++			       wlc->stf->hw_rxchain);
++
++	/* pull up some info resulting from the low attach */
++	for (i = 0; i < NFIFO; i++)
++		wlc->core->txavail[i] = wlc->hw->txavail[i];
++
++	memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++	memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++
++	for (j = 0; j < wlc->pub->_nbands; j++) {
++		wlc->band = wlc->bandstate[j];
++
++		if (!brcms_c_attach_stf_ant_init(wlc)) {
++			err = 24;
++			goto fail;
++		}
++
++		/* default contention windows size limits */
++		wlc->band->CWmin = APHY_CWMIN;
++		wlc->band->CWmax = PHY_CWMAX;
++
++		/* init gmode value */
++		if (wlc->band->bandtype == BRCM_BAND_2G) {
++			wlc->band->gmode = GMODE_AUTO;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
++					   wlc->band->gmode);
++		}
++
++		/* init _n_enab supported mode */
++		if (BRCMS_PHY_11N_CAP(wlc->band)) {
++			pub->_n_enab = SUPPORT_11N;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
++						   ((pub->_n_enab ==
++						     SUPPORT_11N) ? WL_11N_2x2 :
++						    WL_11N_3x3));
++		}
++
++		/* init per-band default rateset, depend on band->gmode */
++		brcms_default_rateset(wlc, &wlc->band->defrateset);
++
++		/* fill in hw_rateset */
++		brcms_c_rateset_filter(&wlc->band->defrateset,
++				   &wlc->band->hw_rateset, false,
++				   BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++	}
++
++	/*
++	 * update antenna config due to
++	 * wlc->stf->txant/txchain/ant_rx_ovr change
++	 */
++	brcms_c_stf_phy_txant_upd(wlc);
++
++	/* attach each modules */
++	err = brcms_c_attach_module(wlc);
++	if (err != 0)
++		goto fail;
++
++	if (!brcms_c_timers_init(wlc, unit)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
++			  __func__);
++		err = 32;
++		goto fail;
++	}
++
++	/* depend on rateset, gmode */
++	wlc->cmi = brcms_c_channel_mgr_attach(wlc);
++	if (!wlc->cmi) {
++		wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
++			  "\n", unit, __func__);
++		err = 33;
++		goto fail;
++	}
++
++	/* init default when all parameters are ready, i.e. ->rateset */
++	brcms_c_bss_default_init(wlc);
++
++	/*
++	 * Complete the wlc default state initializations..
++	 */
++
++	/* allocate our initial queue */
++	wlc->pkt_queue = brcms_c_txq_alloc(wlc);
++	if (wlc->pkt_queue == NULL) {
++		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
++			  unit, __func__);
++		err = 100;
++		goto fail;
++	}
++
++	wlc->bsscfg->wlc = wlc;
++
++	wlc->mimoft = FT_HT;
++	wlc->mimo_40txbw = AUTO;
++	wlc->ofdm_40txbw = AUTO;
++	wlc->cck_40txbw = AUTO;
++	brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
++
++	/* Set default values of SGI */
++	if (BRCMS_SGI_CAP_PHY(wlc)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else if (BRCMS_ISSSLPNPHY(wlc->band)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else {
++		brcms_c_ht_update_sgi_rx(wlc, 0);
++	}
++
++	brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
++
++	if (perr)
++		*perr = 0;
++
++	return wlc;
++
++ fail:
++	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
++		  unit, __func__, err);
++	if (wlc)
++		brcms_c_detach(wlc);
++
++	if (perr)
++		*perr = err;
++	return NULL;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+new file mode 100644
+index 0000000..8debc74
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -0,0 +1,720 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAIN_H_
++#define _BRCM_MAIN_H_
++
++#include <linux/etherdevice.h>
++
++#include <brcmu_utils.h>
++#include "types.h"
++#include "d11.h"
++#include "scb.h"
++
++#define	INVCHANNEL		255	/* invalid channel */
++
++/* max # brcms_c_module_register() calls */
++#define BRCMS_MAXMODULES	22
++
++#define SEQNUM_SHIFT		4
++#define SEQNUM_MAX		0x1000
++
++#define NTXRATE			64	/* # tx MPDUs rate is reported for */
++
++/* Maximum wait time for a MAC suspend */
++/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
++#define	BRCMS_MAX_MAC_SUSPEND	83000
++
++/* responses for probe requests older that this are tossed, zero to disable */
++#define BRCMS_PRB_RESP_TIMEOUT	0	/* Disable probe response timeout */
++
++/* transmit buffer max headroom for protocol headers */
++#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
++
++/* Macros for doing definition and get/set of bitfields
++ * Usage example, e.g. a three-bit field (bits 4-6):
++ *    #define <NAME>_M	BITFIELD_MASK(3)
++ *    #define <NAME>_S	4
++ * ...
++ *    regval = R_REG(osh, &regs->regfoo);
++ *    field = GFIELD(regval, <NAME>);
++ *    regval = SFIELD(regval, <NAME>, 1);
++ *    W_REG(osh, &regs->regfoo, regval);
++ */
++#define BITFIELD_MASK(width) \
++		(((unsigned)1 << (width)) - 1)
++#define GFIELD(val, field) \
++		(((val) >> field ## _S) & field ## _M)
++#define SFIELD(val, field, bits) \
++		(((val) & (~(field ## _M << field ## _S))) | \
++		 ((unsigned)(bits) << field ## _S))
++
++#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */
++
++/* max # supported core revisions (0 .. MAXCOREREV - 1) */
++#define	MAXCOREREV		28
++
++/* Double check that unsupported cores are not enabled */
++#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
++#error "Configuration for D11CONF includes unsupported versions."
++#endif				/* Bad versions */
++
++/* values for shortslot_override */
++#define BRCMS_SHORTSLOT_AUTO	-1 /* Driver will manage Shortslot setting */
++#define BRCMS_SHORTSLOT_OFF	0  /* Turn off short slot */
++#define BRCMS_SHORTSLOT_ON	1  /* Turn on short slot */
++
++/* value for short/long and mixmode/greenfield preamble */
++#define BRCMS_LONG_PREAMBLE	(0)
++#define BRCMS_SHORT_PREAMBLE	(1 << 0)
++#define BRCMS_GF_PREAMBLE		(1 << 1)
++#define BRCMS_MM_PREAMBLE		(1 << 2)
++#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
++				      ((_pre) == BRCMS_MM_PREAMBLE))
++
++/* TxFrameID */
++/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
++/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
++#define TXFID_QUEUE_MASK	0x0007	/* Bits 0-2 */
++#define TXFID_SEQ_MASK		0x7FE0	/* Bits 5-15 */
++#define TXFID_SEQ_SHIFT		5	/* Number of bit shifts */
++#define	TXFID_RATE_PROBE_MASK	0x8000	/* Bit 15 for rate probe */
++#define TXFID_RATE_MASK		0x0018	/* Mask for bits 3 and 4 */
++#define TXFID_RATE_SHIFT	3	/* Shift 3 bits for rate mask */
++
++/* promote boardrev */
++#define BOARDREV_PROMOTABLE	0xFF	/* from */
++#define BOARDREV_PROMOTED	1	/* to */
++
++#define DATA_BLOCK_TX_SUPR	(1 << 4)
++
++/* 802.1D Priority to TX FIFO number for wme */
++extern const u8 prio2fifo[];
++
++/* Ucode MCTL_WAKE override bits */
++#define BRCMS_WAKE_OVERRIDE_CLKCTL	0x01
++#define BRCMS_WAKE_OVERRIDE_PHYREG	0x02
++#define BRCMS_WAKE_OVERRIDE_MACSUSPEND	0x04
++#define BRCMS_WAKE_OVERRIDE_TXFIFO	0x08
++#define BRCMS_WAKE_OVERRIDE_FORCEFAST	0x10
++
++/* stuff pulled in from wlc.c */
++
++/* Interrupt bit error summary.  Don't include I_RU: we refill DMA at other
++ * times; and if we run out, constant I_RU interrupts may cause lockup.  We
++ * will still get error counts from rx0ovfl.
++ */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RO | I_XU)
++/* default software intmasks */
++#define	DEF_RXINTMASK	(I_RI)	/* enable rx int on rxfifo only */
++#define	DEF_MACINTMASK	(MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
++			 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
++			 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
++
++#define	MAXTXPKTS		6	/* max # pkts pending */
++
++/* frameburst */
++#define	MAXTXFRAMEBURST		8 /* vanilla xpress mode: max frames/burst */
++#define	MAXFRAMEBURST_TXOP	10000	/* Frameburst TXOP in usec */
++
++#define	NFIFO			6	/* # tx/rx fifopairs */
++
++/* PLL requests */
++
++/* pll is shared on old chips */
++#define BRCMS_PLLREQ_SHARED	0x1
++/* hold pll for radio monitor register checking */
++#define BRCMS_PLLREQ_RADIO_MON	0x2
++/* hold/release pll for some short operation */
++#define BRCMS_PLLREQ_FLIP		0x4
++
++#define	CHANNEL_BANDUNIT(wlc, ch) \
++	(((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
++
++#define	OTHERBANDUNIT(wlc) \
++	((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
++
++/*
++ * 802.11 protection information
++ *
++ * _g: use g spec protection, driver internal.
++ * g_override: override for use of g spec protection.
++ * gmode_user: user config gmode, operating band->gmode is different.
++ * overlap: Overlap BSS/IBSS protection for both 11g and 11n.
++ * nmode_user: user config nmode, operating pub->nmode is different.
++ * n_cfg: use OFDM protection on MIMO frames.
++ * n_cfg_override: override for use of N protection.
++ * nongf: non-GF present protection.
++ * nongf_override: override for use of GF protection.
++ * n_pam_override: override for preamble: MM or GF.
++ * n_obss: indicated OBSS Non-HT STA present.
++*/
++struct brcms_protection {
++	bool _g;
++	s8 g_override;
++	u8 gmode_user;
++	s8 overlap;
++	s8 nmode_user;
++	s8 n_cfg;
++	s8 n_cfg_override;
++	bool nongf;
++	s8 nongf_override;
++	s8 n_pam_override;
++	bool n_obss;
++};
++
++/*
++ * anything affecting the single/dual streams/antenna operation
++ *
++ * hw_txchain: HW txchain bitmap cfg.
++ * txchain: txchain bitmap being used.
++ * txstreams: number of txchains being used.
++ * hw_rxchain: HW rxchain bitmap cfg.
++ * rxchain: rxchain bitmap being used.
++ * rxstreams: number of rxchains being used.
++ * ant_rx_ovr: rx antenna override.
++ * txant: userTx antenna setting.
++ * phytxant: phyTx antenna setting in txheader.
++ * ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
++ * ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
++ *			else use wlc->band->stf->ss_mode_band.
++ * ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
++ * rxchain_restore_delay: delay time to restore default rxchain.
++ * ldpc: AUTO/ON/OFF ldpc cap supported.
++ * txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
++ * spatial_policy:
++ */
++struct brcms_stf {
++	u8 hw_txchain;
++	u8 txchain;
++	u8 txstreams;
++	u8 hw_rxchain;
++	u8 rxchain;
++	u8 rxstreams;
++	u8 ant_rx_ovr;
++	s8 txant;
++	u16 phytxant;
++	u8 ss_opmode;
++	bool ss_algosel_auto;
++	u16 ss_algo_channel;
++	u8 rxchain_restore_delay;
++	s8 ldpc;
++	u8 txcore[MAX_STREAMS_SUPPORTED + 1];
++	s8 spatial_policy;
++};
++
++#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
++	(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
++	 || (((scb)->flags & SCB_STBCCAP) && \
++	     (wlc)->band->band_stf_stbc_tx == AUTO && \
++	     isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
++
++#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3))
++
++#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3)) || \
++				BRCMS_ISLCNPHY(wlc->band))
++
++#define BRCMS_CHAN_PHYTYPE(x)     (((x) & RXS_CHAN_PHYTYPE_MASK) \
++				   >> RXS_CHAN_PHYTYPE_SHIFT)
++#define BRCMS_CHAN_CHANNEL(x)     (((x) & RXS_CHAN_ID_MASK) \
++				   >> RXS_CHAN_ID_SHIFT)
++
++/*
++ * core state (mac)
++ */
++struct brcms_core {
++	uint coreidx;		/* # sb enumerated core */
++
++	/* fifo */
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	s16 txpktpend[NFIFO];	/* tx admission control */
++
++	struct macstat *macstat_snapshot;	/* mac hw prev read values */
++};
++
++/*
++ * band state (phy+ana+radio)
++ */
++struct brcms_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++
++	u8 gmode;		/* currently active gmode */
++
++	struct scb *hwrs_scb;	/* permanent scb for hw rateset */
++
++	/* band-specific copy of default_bss.rateset */
++	struct brcms_c_rateset defrateset;
++
++	u8 band_stf_ss_mode;	/* Configured STF type, 0:siso; 1:cdd */
++	s8 band_stf_stbc_tx;	/* STBC TX 0:off; 1:force on; -1:auto */
++	/* rates supported by chip (phy-specific) */
++	struct brcms_c_rateset hw_rateset;
++	u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
++	bool mimo_cap_40;	/* 40 MHz cap enabled on this band */
++	s8 antgain;		/* antenna gain from srom */
++
++	u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
++	u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
++	struct ieee80211_supported_band band;
++};
++
++/* module control blocks */
++struct modulecb {
++	/* module name : NULL indicates empty array member */
++	char name[32];
++	/* handle passed when handler 'doiovar' is called */
++	struct brcms_info *hdl;
++
++	int (*down_fn)(void *handle); /* down handler. Note: the int returned
++				       * by the down function is a count of the
++				       * number of timers that could not be
++				       * freed.
++				       */
++
++};
++
++struct brcms_hw_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++	u16 mhfs[MHFMAX];	/* MHF array shadow */
++	u8 bandhw_stf_ss_mode;	/* HW configured STF type, 0:siso; 1:cdd */
++	u16 CWmin;
++	u16 CWmax;
++	u32 core_flags;
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++};
++
++struct brcms_hardware {
++	bool _piomode;		/* true if pio mode */
++	struct brcms_c_info *wlc;
++
++	/* fifo */
++	struct dma_pub *di[NFIFO];	/* dma handles, per fifo */
++
++	uint unit;		/* device instance number */
++
++	/* version info */
++	u16 vendorid;	/* PCI vendor id */
++	u16 deviceid;	/* PCI device id */
++	uint corerev;		/* core revision */
++	u8 sromrev;		/* version # of the srom */
++	u16 boardrev;	/* version # of particular board */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	u32 machwcap;	/* MAC capabilities */
++	u32 machwcap_backup;	/* backup of machwcap */
++
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	struct bcma_device *d11core;	/* pointer to 802.11 core */
++	struct phy_shim_info *physhim; /* phy shim layer handler */
++	struct shared_phy *phy_sh;	/* pointer to shared phy state */
++	struct brcms_hw_band *band;/* pointer to active per-band state */
++	/* band state per phy/radio */
++	struct brcms_hw_band *bandstate[MAXBANDS];
++	u16 bmac_phytxant;	/* cache of high phytxant state */
++	bool shortslot;		/* currently using 11g ShortSlot timing */
++	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
++	u16 LRL;		/* 802.11 dot11LongRetryLimit */
++	u16 SFBL;		/* Short Frame Rate Fallback Limit */
++	u16 LFBL;		/* Long Frame Rate Fallback Limit */
++
++	bool up;		/* d11 hardware up and running */
++	uint now;		/* # elapsed seconds */
++	uint _nbands;		/* # bands supported */
++	u16 chanspec;	/* bmac chanspec shadow */
++
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	const u16 *xmtfifo_sz;	/* fifo size in 256B for each xmt fifo */
++
++	u32 pllreq;		/* pll requests to keep PLL on */
++
++	u8 suspended_fifos;	/* Which TX fifo to remain awake for */
++	u32 maccontrol;	/* Cached value of maccontrol */
++	uint mac_suspend_depth;	/* current depth of mac_suspend levels */
++	u32 wake_override;	/* bit flags to force MAC to WAKE mode */
++	u32 mute_override;	/* Prevent ucode from sending beacons */
++	u8 etheraddr[ETH_ALEN];	/* currently configured ethernet address */
++	bool noreset;		/* true= do not reset hw, used by WLC_OUT */
++	bool forcefastclk;	/* true if h/w is forcing to use fast clk */
++	bool clk;		/* core is out of reset and has clock */
++	bool sbclk;		/* sb has clock */
++	bool phyclk;		/* phy is out of reset and has clock */
++
++	bool ucode_loaded;	/* true after ucode downloaded */
++
++
++	u8 hw_stf_ss_opmode;	/* STF single stream operation mode */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u32 antsel_avail;	/*
++				 * put struct antsel_info here if more info is
++				 * needed
++				 */
++};
++
++/* TX Queue information
++ *
++ * Each flow of traffic out of the device has a TX Queue with independent
++ * flow control. Several interfaces may be associated with a single TX Queue
++ * if they belong to the same flow of traffic from the device. For multi-channel
++ * operation there are independent TX Queues for each channel.
++ */
++struct brcms_txq_info {
++	struct brcms_txq_info *next;
++	struct pktq q;
++	uint stopped;		/* tx flow control bits */
++};
++
++/*
++ * Principal common driver data structure.
++ *
++ * pub: pointer to driver public state.
++ * wl: pointer to specific private state.
++ * hw: HW related state.
++ * clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
++ * fastpwrup_dly: time in us needed to bring up d11 fast clock.
++ * macintstatus: bit channel between isr and dpc.
++ * macintmask: sw runtime master macintmask value.
++ * defmacintmask: default "on" macintmask value.
++ * clk: core is out of reset and has clock.
++ * core: pointer to active io core.
++ * band: pointer to active per-band state.
++ * corestate: per-core state (one per hw core).
++ * bandstate: per-band state (one per phy/radio).
++ * qvalid: DirFrmQValid and BcMcFrmQValid.
++ * ampdu: ampdu module handler.
++ * asi: antsel module handler.
++ * cmi: channel manager module handler.
++ * vendorid: PCI vendor id.
++ * deviceid: PCI device id.
++ * ucode_rev: microcode revision.
++ * machwcap: MAC capabilities, BMAC shadow.
++ * perm_etheraddr: original sprom local ethernet address.
++ * bandlocked: disable auto multi-band switching.
++ * bandinit_pending: track band init in auto band.
++ * radio_monitor: radio timer is running.
++ * going_down: down path intermediate variable.
++ * wdtimer: timer for watchdog routine.
++ * radio_timer: timer for hw radio button monitor routine.
++ * monitor: monitor (MPDU sniffing) mode.
++ * bcnmisc_monitor: bcns promisc mode override for monitor.
++ * _rifs: enable per-packet rifs.
++ * bcn_li_bcn: beacon listen interval in # beacons.
++ * bcn_li_dtim: beacon listen interval in # dtims.
++ * WDarmed: watchdog timer is armed.
++ * WDlast: last time wlc_watchdog() was called.
++ * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
++ * wme_retries: per-AC retry limits.
++ * tx_prec_map: Precedence map based on HW FIFO space.
++ * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
++ * bsscfg: set of BSS configurations, idx 0 is default and always valid.
++ * cfg: the primary bsscfg (can be AP or STA).
++ * tx_queues: common TX Queue list.
++ * modulecb:
++ * mimoft: SIGN or 11N.
++ * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
++ * ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
++ * mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
++ * default_bss: configured BSS parameters.
++ * mc_fid_counter: BC/MC FIFO frame ID counter.
++ * country_default: saved country for leaving 802.11d auto-country mode.
++ * autocountry_default: initial country for 802.11d auto-country mode.
++ * prb_resp_timeout: do not send prb resp if request older
++ *		     than this, 0 = disable.
++ * home_chanspec: shared home chanspec.
++ * chanspec: target operational channel.
++ * usr_fragthresh: user configured fragmentation threshold.
++ * fragthresh[NFIFO]: per-fifo fragmentation thresholds.
++ * RTSThresh: 802.11 dot11RTSThreshold.
++ * SRL: 802.11 dot11ShortRetryLimit.
++ * LRL: 802.11 dot11LongRetryLimit.
++ * SFBL: Short Frame Rate Fallback Limit.
++ * LFBL: Long Frame Rate Fallback Limit.
++ * shortslot: currently using 11g ShortSlot timing.
++ * shortslot_override: 11g ShortSlot override.
++ * include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
++ * PLCPHdr_override: 802.11b Preamble Type override.
++ * stf:
++ * bcn_rspec: save bcn ratespec purpose.
++ * tempsense_lasttime;
++ * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
++ * tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
++ * pkt_queue: txq for transmit packets.
++ * wiphy:
++ * pri_scb: primary Station Control Block
++ */
++struct brcms_c_info {
++	struct brcms_pub *pub;
++	struct brcms_info *wl;
++	struct brcms_hardware *hw;
++
++	/* clock */
++	u16 fastpwrup_dly;
++
++	/* interrupt */
++	u32 macintstatus;
++	u32 macintmask;
++	u32 defmacintmask;
++
++	bool clk;
++
++	/* multiband */
++	struct brcms_core *core;
++	struct brcms_band *band;
++	struct brcms_core *corestate;
++	struct brcms_band *bandstate[MAXBANDS];
++
++	/* packet queue */
++	uint qvalid;
++
++	struct ampdu_info *ampdu;
++	struct antsel_info *asi;
++	struct brcms_cm_info *cmi;
++
++	u16 vendorid;
++	u16 deviceid;
++	uint ucode_rev;
++
++	u8 perm_etheraddr[ETH_ALEN];
++
++	bool bandlocked;
++	bool bandinit_pending;
++
++	bool radio_monitor;
++	bool going_down;
++
++	struct brcms_timer *wdtimer;
++	struct brcms_timer *radio_timer;
++
++	/* promiscuous */
++	uint filter_flags;
++
++	/* driver feature */
++	bool _rifs;
++
++	/* AP-STA synchronization, power save */
++	u8 bcn_li_bcn;
++	u8 bcn_li_dtim;
++
++	bool WDarmed;
++	u32 WDlast;
++
++	/* WME */
++	u16 edcf_txop[IEEE80211_NUM_ACS];
++
++	u16 wme_retries[IEEE80211_NUM_ACS];
++	u16 tx_prec_map;
++	u16 fifo2prec_map[NFIFO];
++
++	struct brcms_bss_cfg *bsscfg;
++
++	/* tx queue */
++	struct brcms_txq_info *tx_queues;
++
++	struct modulecb *modulecb;
++
++	u8 mimoft;
++	s8 cck_40txbw;
++	s8 ofdm_40txbw;
++	s8 mimo_40txbw;
++
++	struct brcms_bss_info *default_bss;
++
++	u16 mc_fid_counter;
++
++	char country_default[BRCM_CNTRY_BUF_SZ];
++	char autocountry_default[BRCM_CNTRY_BUF_SZ];
++	u16 prb_resp_timeout;
++
++	u16 home_chanspec;
++
++	/* PHY parameters */
++	u16 chanspec;
++	u16 usr_fragthresh;
++	u16 fragthresh[NFIFO];
++	u16 RTSThresh;
++	u16 SRL;
++	u16 LRL;
++	u16 SFBL;
++	u16 LFBL;
++
++	/* network config */
++	bool shortslot;
++	s8 shortslot_override;
++	bool include_legacy_erp;
++
++	struct brcms_protection *protection;
++	s8 PLCPHdr_override;
++
++	struct brcms_stf *stf;
++
++	u32 bcn_rspec;
++
++	uint tempsense_lasttime;
++
++	u16 tx_duty_cycle_ofdm;
++	u16 tx_duty_cycle_cck;
++
++	struct brcms_txq_info *pkt_queue;
++	struct wiphy *wiphy;
++	struct scb pri_scb;
++};
++
++/* antsel module specific state */
++struct antsel_info {
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_pub *pub;		/* pointer to public fn */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u8 antsel_antswitch;	/* board level antenna switch type */
++	bool antsel_avail;	/* Ant selection availability (SROM based) */
++	struct brcms_antselcfg antcfg_11n; /* antenna configuration */
++	struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
++};
++
++/*
++ * BSS configuration state
++ *
++ * wlc: wlc to which this bsscfg belongs to.
++ * up: is this configuration up operational
++ * enable: is this configuration enabled
++ * associated: is BSS in ASSOCIATED state
++ * BSS: infraustructure or adhoc
++ * SSID_len: the length of SSID
++ * SSID: SSID string
++ *
++ *
++ * BSSID: BSSID (associated)
++ * cur_etheraddr: h/w address
++ * flags: BSSCFG flags; see below
++ *
++ * current_bss: BSS parms in ASSOCIATED state
++ *
++ *
++ * ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
++ */
++struct brcms_bss_cfg {
++	struct brcms_c_info *wlc;
++	bool up;
++	bool enable;
++	bool associated;
++	bool BSS;
++	u8 SSID_len;
++	u8 SSID[IEEE80211_MAX_SSID_LEN];
++	u8 BSSID[ETH_ALEN];
++	u8 cur_etheraddr[ETH_ALEN];
++	struct brcms_bss_info *current_bss;
++};
++
++extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
++			   struct sk_buff *p,
++			   bool commit, s8 txpktpend);
++extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
++				    s8 txpktpend);
++extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++			    struct sk_buff *sdu, uint prec);
++extern void brcms_c_print_txstatus(struct tx_status *txs);
++extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++		   uint *blocks);
++
++#if defined(DEBUG)
++extern void brcms_c_print_txdesc(struct d11txh *txh);
++#else
++static inline void brcms_c_print_txdesc(struct d11txh *txh)
++{
++}
++#endif
++
++extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
++extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
++extern void brcms_c_send_q(struct brcms_c_info *wlc);
++extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
++			    uint *fifo);
++extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++				uint mac_len);
++extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
++					     u32 rspec,
++					     bool use_rspec, u16 mimo_ctlchbw);
++extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++				      u32 rts_rate,
++				      u32 frame_rate,
++				      u8 rts_preamble_type,
++				      u8 frame_preamble_type, uint frame_len,
++				      bool ba);
++extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn));
++extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
++extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
++extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
++extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++					  u32 bcn_rate);
++extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
++				     u8 antsel_type);
++extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
++				  u16 chanspec,
++				  bool mute, struct txpwr_limits *txpwr);
++extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
++			      u16 v);
++extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
++extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
++			u16 val, int bands);
++extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
++extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
++extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
++extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++					u32 override_bit);
++extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++					  u32 override_bit);
++extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
++				       int offset, int len, void *buf);
++extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
++extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
++				   uint offset, const void *buf, int len,
++				   u32 sel);
++extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
++				     void *buf, int len, u32 sel);
++extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
++extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
++extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
++extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
++extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
++				    u8 stf_mode);
++extern void brcms_c_init_scb(struct scb *scb);
++
++#endif				/* _BRCM_MAIN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+new file mode 100644
+index 0000000..264f8c4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+@@ -0,0 +1,2961 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <aiutils.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_hal.h"
++#include "phy_int.h"
++#include "phy_radio.h"
++#include "phy_lcn.h"
++#include "phyreg_n.h"
++
++#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \
++				 (radioid == BCM2056_ID) || \
++				 (radioid == BCM2057_ID))
++
++#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
++
++#define VALID_RADIO(pi, radioid)        ( \
++		(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
++		(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
++
++/* basic mux operation - can be optimized on several architectures */
++#define MUX(pred, true, false) ((pred) ? (true) : (false))
++
++/* modulo inc/dec - assumes x E [0, bound - 1] */
++#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
++
++/* modulo inc/dec, bound = 2^k */
++#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
++#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
++
++struct chan_info_basic {
++	u16 chan;
++	u16 freq;
++};
++
++static const struct chan_info_basic chan_info_all[] = {
++	{1, 2412},
++	{2, 2417},
++	{3, 2422},
++	{4, 2427},
++	{5, 2432},
++	{6, 2437},
++	{7, 2442},
++	{8, 2447},
++	{9, 2452},
++	{10, 2457},
++	{11, 2462},
++	{12, 2467},
++	{13, 2472},
++	{14, 2484},
++
++	{34, 5170},
++	{38, 5190},
++	{42, 5210},
++	{46, 5230},
++
++	{36, 5180},
++	{40, 5200},
++	{44, 5220},
++	{48, 5240},
++	{52, 5260},
++	{56, 5280},
++	{60, 5300},
++	{64, 5320},
++
++	{100, 5500},
++	{104, 5520},
++	{108, 5540},
++	{112, 5560},
++	{116, 5580},
++	{120, 5600},
++	{124, 5620},
++	{128, 5640},
++	{132, 5660},
++	{136, 5680},
++	{140, 5700},
++
++	{149, 5745},
++	{153, 5765},
++	{157, 5785},
++	{161, 5805},
++	{165, 5825},
++
++	{184, 4920},
++	{188, 4940},
++	{192, 4960},
++	{196, 4980},
++	{200, 5000},
++	{204, 5020},
++	{208, 5040},
++	{212, 5060},
++	{216, 5080}
++};
++
++static const u8 ofdm_rate_lookup[] = {
++
++	BRCM_RATE_48M,
++	BRCM_RATE_24M,
++	BRCM_RATE_12M,
++	BRCM_RATE_6M,
++	BRCM_RATE_54M,
++	BRCM_RATE_36M,
++	BRCM_RATE_18M,
++	BRCM_RATE_9M
++};
++
++#define PHY_WREG_LIMIT  24
++
++void wlc_phyreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
++}
++
++void wlc_phyreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
++}
++
++void wlc_radioreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
++
++	udelay(10);
++}
++
++void wlc_radioreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	pi->phy_wreg = 0;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
++}
++
++u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
++{
++	u16 data;
++
++	if ((addr == RADIO_IDCODE))
++		return 0xffff;
++
++	switch (pi->pubpi.phy_type) {
++	case PHY_TYPE_N:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_N))
++			break;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			addr |= RADIO_2057_READ_OFF;
++		else
++			addr |= RADIO_2055_READ_OFF;
++		break;
++
++	case PHY_TYPE_LCN:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_LCN))
++			break;
++		addr |= RADIO_2064_READ_OFF;
++		break;
++
++	default:
++		break;
++	}
++
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++	}
++	pi->phy_wreg = 0;
++
++	return data;
++}
++
++void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(radioregdata), val);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
++	}
++
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		pi->phy_wreg = 0;
++	}
++}
++
++static u32 read_radio_id(struct brcms_phy *pi)
++{
++	u32 id;
++
++	if (D11REV_GE(pi->sh->corerev, 24)) {
++		u32 b0, b1, b2;
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 0);
++		b0 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 1);
++		b1 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 2);
++		b2 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++
++		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
++								      & 0xf);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), RADIO_IDCODE);
++		id = (u32) bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++		id |= (u32) bcma_read16(pi->d11core,
++					D11REGOFFS(phy4wdatahi)) << 16;
++	}
++	pi->phy_wreg = 0;
++	return id;
++}
++
++void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & val));
++}
++
++void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval | val));
++}
++
++void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval ^ mask));
++}
++
++void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
++}
++
++void write_phy_channel_reg(struct brcms_phy *pi, uint val)
++{
++	bcma_write16(pi->d11core, D11REGOFFS(phychannel), val);
++}
++
++u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++
++	pi->phy_wreg = 0;
++	return bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
++}
++
++void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++#ifdef CONFIG_BCM47XX
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_write16(pi->d11core, D11REGOFFS(phyregdata), val);
++	if (addr == 0x72)
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++#else
++	bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		pi->phy_wreg = 0;
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	}
++#endif
++}
++
++void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_mask16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_set16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	val &= mask;
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_maskset16(pi->d11core, D11REGOFFS(phyregdata), ~mask, val);
++	pi->phy_wreg = 0;
++}
++
++static void wlc_set_phy_uninitted(struct brcms_phy *pi)
++{
++	int i, j;
++
++	pi->initialized = false;
++
++	pi->tx_vos = 0xffff;
++	pi->nrssi_table_delta = 0x7fffffff;
++	pi->rc_cal = 0xffff;
++	pi->mintxbias = 0xffff;
++	pi->txpwridx = -1;
++	if (ISNPHY(pi)) {
++		pi->phy_spuravoid = SPURAVOID_DISABLE;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7))
++			pi->phy_spuravoid = SPURAVOID_AUTO;
++
++		pi->nphy_papd_skip = 0;
++		pi->nphy_papd_epsilon_offset[0] = 0xf588;
++		pi->nphy_papd_epsilon_offset[1] = 0xf588;
++		pi->nphy_txpwr_idx[0] = 128;
++		pi->nphy_txpwr_idx[1] = 128;
++		pi->nphy_txpwrindex[0].index_internal = 40;
++		pi->nphy_txpwrindex[1].index_internal = 40;
++		pi->phy_pabias = 0;
++	} else {
++		pi->phy_spuravoid = SPURAVOID_AUTO;
++	}
++	pi->radiopwr = 0xffff;
++	for (i = 0; i < STATIC_NUM_RF; i++) {
++		for (j = 0; j < STATIC_NUM_BB; j++)
++			pi->stats_11b_txpower[i][j] = -1;
++	}
++}
++
++struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
++{
++	struct shared_phy *sh;
++
++	sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
++	if (sh == NULL)
++		return NULL;
++
++	sh->sih = shp->sih;
++	sh->physhim = shp->physhim;
++	sh->unit = shp->unit;
++	sh->corerev = shp->corerev;
++
++	sh->vid = shp->vid;
++	sh->did = shp->did;
++	sh->chip = shp->chip;
++	sh->chiprev = shp->chiprev;
++	sh->chippkg = shp->chippkg;
++	sh->sromrev = shp->sromrev;
++	sh->boardtype = shp->boardtype;
++	sh->boardrev = shp->boardrev;
++	sh->boardflags = shp->boardflags;
++	sh->boardflags2 = shp->boardflags2;
++
++	sh->fast_timer = PHY_SW_TIMER_FAST;
++	sh->slow_timer = PHY_SW_TIMER_SLOW;
++	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
++
++	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
++
++	return sh;
++}
++
++static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
++{
++	uint delay = 5;
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
++		if (!pi->sh->up) {
++			wlc_phy_cal_perical_mphase_reset(pi);
++			return;
++		}
++
++		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
++
++			delay = 1000;
++			wlc_phy_cal_perical_mphase_restart(pi);
++		} else
++			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
++		wlapi_add_timer(pi->phycal_timer, delay, 0);
++		return;
++	}
++
++}
++
++static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
++{
++	u32 ver;
++
++	ver = read_radio_id(pi);
++
++	return ver;
++}
++
++struct brcms_phy_pub *
++wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core,
++	       int bandtype, struct wiphy *wiphy)
++{
++	struct brcms_phy *pi;
++	u32 sflags = 0;
++	uint phyversion;
++	u32 idcode;
++	int i;
++
++	if (D11REV_IS(sh->corerev, 4))
++		sflags = SISF_2G_PHY | SISF_5G_PHY;
++	else
++		sflags = bcma_aread32(d11core, BCMA_IOST);
++
++	if (bandtype == BRCM_BAND_5G) {
++		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
++			return NULL;
++	}
++
++	pi = sh->phy_head;
++	if ((sflags & SISF_DB_PHY) && pi) {
++		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++		pi->refcnt++;
++		return &pi->pubpi_ro;
++	}
++
++	pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
++	if (pi == NULL)
++		return NULL;
++	pi->wiphy = wiphy;
++	pi->d11core = d11core;
++	pi->sh = sh;
++	pi->phy_init_por = true;
++	pi->phy_wreg_limit = PHY_WREG_LIMIT;
++
++	pi->txpwr_percent = 100;
++
++	pi->do_initcal = true;
++
++	pi->phycal_tempdelta = 0;
++
++	if (bandtype == BRCM_BAND_2G && (sflags & SISF_2G_PHY))
++		pi->pubpi.coreflags = SICF_GMODE;
++
++	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++	phyversion = bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++
++	pi->pubpi.phy_type = PHY_TYPE(phyversion);
++	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
++
++	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
++		pi->pubpi.phy_type = PHY_TYPE_N;
++		pi->pubpi.phy_rev += LCNXN_BASEREV;
++	}
++	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
++	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
++
++	if (pi->pubpi.phy_type != PHY_TYPE_N &&
++	    pi->pubpi.phy_type != PHY_TYPE_LCN)
++		goto err;
++
++	if (bandtype == BRCM_BAND_5G) {
++		if (!ISNPHY(pi))
++			goto err;
++	} else if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
++		goto err;
++	}
++
++	wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
++
++	idcode = wlc_phy_get_radio_ver(pi);
++	pi->pubpi.radioid =
++		(idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
++	pi->pubpi.radiorev =
++		(idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
++	pi->pubpi.radiover =
++		(idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
++	if (!VALID_RADIO(pi, pi->pubpi.radioid))
++		goto err;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
++
++	wlc_set_phy_uninitted(pi);
++
++	pi->bw = WL_CHANSPEC_BW_20;
++	pi->radio_chanspec = (bandtype == BRCM_BAND_2G) ?
++			     ch20mhz_chspec(1) : ch20mhz_chspec(36);
++
++	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++	pi->rxiq_antsel = ANT_RX_DIV_DEF;
++
++	pi->watchdog_override = true;
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++
++	pi->nphy_saved_noisevars.bufcount = 0;
++
++	if (ISNPHY(pi))
++		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
++	else
++		pi->min_txpower = PHY_TXPWR_MIN;
++
++	pi->sh->phyrxchain = 0x3;
++
++	pi->rx2tx_biasentry = -1;
++
++	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++	pi->phy_txcore_enable_temp =
++		PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
++	pi->phy_tempsense_offset = 0;
++	pi->phy_txcore_heatedup = false;
++
++	pi->nphy_lastcal_temp = -50;
++
++	pi->phynoise_polling = true;
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		pi->phynoise_polling = false;
++
++	for (i = 0; i < TXP_NUM_RATES; i++) {
++		pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++		pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
++	}
++
++	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
++
++	pi->user_txpwr_at_rfport = false;
++
++	if (ISNPHY(pi)) {
++
++		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
++						    wlc_phy_timercb_phycal,
++						    pi, "phycal");
++		if (!pi->phycal_timer)
++			goto err;
++
++		if (!wlc_phy_attach_nphy(pi))
++			goto err;
++
++	} else if (ISLCNPHY(pi)) {
++		if (!wlc_phy_attach_lcnphy(pi))
++			goto err;
++
++	}
++
++	pi->refcnt++;
++	pi->next = pi->sh->phy_head;
++	sh->phy_head = pi;
++
++	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
++
++	return &pi->pubpi_ro;
++
++err:
++	kfree(pi);
++	return NULL;
++}
++
++void wlc_phy_detach(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pih) {
++		if (--pi->refcnt)
++			return;
++
++		if (pi->phycal_timer) {
++			wlapi_free_timer(pi->phycal_timer);
++			pi->phycal_timer = NULL;
++		}
++
++		if (pi->sh->phy_head == pi)
++			pi->sh->phy_head = pi->next;
++		else if (pi->sh->phy_head->next == pi)
++			pi->sh->phy_head->next = NULL;
++
++		if (pi->pi_fptr.detach)
++			(pi->pi_fptr.detach)(pi);
++
++		kfree(pi);
++	}
++}
++
++bool
++wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
++		       u16 *radioid, u16 *radiover)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	*phytype = (u16) pi->pubpi.phy_type;
++	*phyrev = (u16) pi->pubpi.phy_rev;
++	*radioid = pi->pubpi.radioid;
++	*radiover = pi->pubpi.radiorev;
++
++	return true;
++}
++
++bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.abgphy_encore;
++}
++
++u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.coreflags;
++}
++
++void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		if (on) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0xa6, 0x0d);
++				write_phy_reg(pi, 0x8f, 0x0);
++				write_phy_reg(pi, 0xa7, 0x0d);
++				write_phy_reg(pi, 0xa5, 0x0);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x0);
++			}
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0x8f, 0x07ff);
++				write_phy_reg(pi, 0xa6, 0x0fd);
++				write_phy_reg(pi, 0xa5, 0x07ff);
++				write_phy_reg(pi, 0xa7, 0x0fd);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x7fff);
++			}
++		}
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x43b,
++				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++		} else {
++			or_phy_reg(pi, 0x43c,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++			or_phy_reg(pi, 0x43b,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++		}
++	}
++}
++
++u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	u32 phy_bw_clkbits = 0;
++
++	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
++		switch (pi->bw) {
++		case WL_CHANSPEC_BW_10:
++			phy_bw_clkbits = SICF_BW10;
++			break;
++		case WL_CHANSPEC_BW_20:
++			phy_bw_clkbits = SICF_BW20;
++			break;
++		case WL_CHANSPEC_BW_40:
++			phy_bw_clkbits = SICF_BW40;
++			break;
++		default:
++			break;
++		}
++	}
++
++	return phy_bw_clkbits;
++}
++
++void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->phy_init_por = true;
++}
++
++void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->edcrs_threshold_lock = lock;
++
++	write_phy_reg(pi, 0x22c, 0x46b);
++	write_phy_reg(pi, 0x22d, 0x46b);
++	write_phy_reg(pi, 0x22e, 0x3c0);
++	write_phy_reg(pi, 0x22f, 0x3c0);
++}
++
++void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->do_initcal = initcal;
++}
++
++void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->clk = newstate;
++}
++
++void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->up = newstate;
++}
++
++void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	u32 mc;
++	void (*phy_init)(struct brcms_phy *) = NULL;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pi->init_in_progress)
++		return;
++
++	pi->init_in_progress = true;
++
++	pi->radio_chanspec = chanspec;
++
++	mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
++		return;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if (WARN(!(bcma_aread32(pi->d11core, BCMA_IOST) & SISF_FCLKA),
++		 "HW error SISF_FCLKA\n"))
++		return;
++
++	phy_init = pi->pi_fptr.init;
++
++	if (phy_init == NULL)
++		return;
++
++	wlc_phy_anacore(pih, ON);
++
++	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim,
++				  CHSPEC_BW(pi->radio_chanspec));
++
++	pi->nphy_gain_boost = true;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
++
++	(*phy_init)(pi);
++
++	pi->phy_init_por = false;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlc_phy_do_dummy_tx(pi, true, OFF);
++
++	if (!(ISNPHY(pi)))
++		wlc_phy_txpower_update_shm(pi);
++
++	wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
++
++	pi->init_in_progress = false;
++}
++
++void wlc_phy_cal_init(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	void (*cal_init)(struct brcms_phy *) = NULL;
++
++	if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++		  MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n"))
++		return;
++
++	if (!pi->initialized) {
++		cal_init = pi->pi_fptr.calinit;
++		if (cal_init)
++			(*cal_init)(pi);
++
++		pi->initialized = true;
++	}
++}
++
++int wlc_phy_down(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	int callbacks = 0;
++
++	if (pi->phycal_timer
++	    && !wlapi_del_timer(pi->phycal_timer))
++		callbacks++;
++
++	pi->nphy_iqcal_chanspec_2G = 0;
++	pi->nphy_iqcal_chanspec_5G = 0;
++
++	return callbacks;
++}
++
++void
++wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	pi->tbl_data_hi = tblDataHi;
++	pi->tbl_data_lo = tblDataLo;
++
++	if (pi->sh->chip == BCM43224_CHIP_ID &&
++	    pi->sh->chiprev == 1) {
++		pi->tbl_addr = tblAddr;
++		pi->tbl_save_id = tbl_id;
++		pi->tbl_save_offset = tbl_offset;
++	}
++}
++
++void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
++{
++	if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++	    (pi->sh->chiprev == 1) &&
++	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++		read_phy_reg(pi, pi->tbl_data_lo);
++
++		write_phy_reg(pi, pi->tbl_addr,
++			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
++		pi->tbl_save_offset++;
++	}
++
++	if (width == 32) {
++		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	} else {
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	}
++}
++
++void
++wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
++	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
++	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1) &&
++		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++			read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			write_phy_reg(pi, tblDataHi,
++				      (u16) (ptbl_32b[idx] >> 16));
++			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
++		} else if (tbl_width == 16) {
++			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
++		} else {
++			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
++		}
++	}
++}
++
++void
++wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
++	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
++	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1)) {
++			(void)read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
++			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
++		} else if (tbl_width == 16) {
++			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
++		} else {
++			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
++		}
++	}
++}
++
++uint
++wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++				 struct radio_20xx_regs *radioregs)
++{
++	uint i = 0;
++
++	do {
++		if (radioregs[i].do_init)
++			write_radio_reg(pi, radioregs[i].address,
++					(u16) radioregs[i].init);
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++uint
++wlc_phy_init_radio_regs(struct brcms_phy *pi,
++			const struct radio_regs *radioregs,
++			u16 core_offset)
++{
++	uint i = 0;
++	uint count = 0;
++
++	do {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (radioregs[i].do_init_a) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_a);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		} else {
++			if (radioregs[i].do_init_g) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_g);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		}
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
++{
++#define DUMMY_PKT_LEN   20
++	struct bcma_device *core = pi->d11core;
++	int i, count;
++	u8 ofdmpkt[DUMMY_PKT_LEN] = {
++		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u8 cckpkt[DUMMY_PKT_LEN] = {
++		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u32 *dummypkt;
++
++	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
++	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
++				      dummypkt);
++
++	bcma_write16(core, D11REGOFFS(xmtsel), 0);
++
++	if (D11REV_GE(pi->sh->corerev, 11))
++		bcma_write16(core, D11REGOFFS(wepctl), 0x100);
++	else
++		bcma_write16(core, D11REGOFFS(wepctl), 0);
++
++	bcma_write16(core, D11REGOFFS(txe_phyctl),
++		     (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_phyctl1), 0x1A02);
++
++	bcma_write16(core, D11REGOFFS(txe_wm_0), 0);
++	bcma_write16(core, D11REGOFFS(txe_wm_1), 0);
++
++	bcma_write16(core, D11REGOFFS(xmttplatetxptr), 0);
++	bcma_write16(core, D11REGOFFS(xmttxcnt), DUMMY_PKT_LEN);
++
++	bcma_write16(core, D11REGOFFS(xmtsel),
++		     ((8 << 8) | (1 << 5) | (1 << 2) | 2));
++
++	bcma_write16(core, D11REGOFFS(txe_ctl), 0);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, OFF);
++	}
++
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_aux), 0xD0);
++	else
++		bcma_write16(core, D11REGOFFS(txe_aux), ((1 << 5) | (1 << 4)));
++
++	(void)bcma_read16(core, D11REGOFFS(txe_aux));
++
++	i = 0;
++	count = ofdm ? 30 : 250;
++	while ((i++ < count)
++	       && (bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 7)))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 10)) == 0))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(ifsstat)) & (1 << 8))))
++		udelay(10);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, ON);
++	}
++}
++
++void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (set)
++		mboolset(pi->measure_hold, id);
++	else
++		mboolclr(pi->measure_hold, id);
++
++	return;
++}
++
++void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (mute)
++		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++	else
++		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++
++	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
++		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
++	return;
++}
++
++void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		return;
++	} else {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
++	}
++}
++
++static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
++{
++	return false;
++}
++
++void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++
++	if (ISNPHY(pi)) {
++		wlc_phy_switch_radio_nphy(pi, on);
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x44c,
++				    ~((0x1 << 8) |
++				      (0x1 << 9) |
++				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
++			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
++			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
++		} else {
++			and_phy_reg(pi, 0x44d,
++				    ~((0x1 << 10) |
++				      (0x1 << 11) |
++				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
++			or_phy_reg(pi, 0x44c,
++				   (0x1 << 8) |
++				   (0x1 << 9) |
++				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
++
++			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
++			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
++			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
++			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
++			or_phy_reg(pi, 0x4f9, (0x1 << 3));
++		}
++	}
++}
++
++u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->bw;
++}
++
++void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->bw = bw;
++}
++
++void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	pi->radio_chanspec = newch;
++
++}
++
++u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->radio_chanspec;
++}
++
++void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 m_cur_channel;
++	void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
++	m_cur_channel = CHSPEC_CHANNEL(chanspec);
++	if (CHSPEC_IS5G(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_5G;
++	if (CHSPEC_IS40(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_40;
++	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
++
++	chanspec_set = pi->pi_fptr.chanset;
++	if (chanspec_set)
++		(*chanspec_set)(pi, chanspec);
++
++}
++
++int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
++{
++	int range = -1;
++
++	if (freq < 2500)
++		range = WL_CHAN_FREQ_RANGE_2G;
++	else if (freq <= 5320)
++		range = WL_CHAN_FREQ_RANGE_5GL;
++	else if (freq <= 5700)
++		range = WL_CHAN_FREQ_RANGE_5GM;
++	else
++		range = WL_CHAN_FREQ_RANGE_5GH;
++
++	return range;
++}
++
++int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
++{
++	int range = -1;
++	uint channel = CHSPEC_CHANNEL(chanspec);
++	uint freq = wlc_phy_channel2freq(channel);
++
++	if (ISNPHY(pi))
++		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
++	else if (ISLCNPHY(pi))
++		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
++
++	return range;
++}
++
++void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++					  bool wide_filter)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->channel_14_wide_filter = wide_filter;
++
++}
++
++int wlc_phy_channel2freq(uint channel)
++{
++	uint i;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
++		if (chan_info_all[i].chan == channel)
++			return chan_info_all[i].freq;
++	return 0;
++}
++
++void
++wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++			      struct brcms_chanvec *channels)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			setbit(channels->vec, channel);
++	}
++}
++
++u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++	u16 chspec;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if (ISNPHY(pi) && pi->bw == WL_CHANSPEC_BW_40) {
++			uint j;
++
++			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
++				if (chan_info_all[j].chan ==
++				    channel + CH_10MHZ_APART)
++					break;
++			}
++
++			if (j == ARRAY_SIZE(chan_info_all))
++				continue;
++
++			channel = upper_20_sb(channel);
++			chspec =  channel | WL_CHANSPEC_BW_40 |
++				  WL_CHANSPEC_CTL_SB_LOWER;
++			if (band == BRCM_BAND_2G)
++				chspec |= WL_CHANSPEC_BAND_2G;
++			else
++				chspec |= WL_CHANSPEC_BAND_5G;
++		} else
++			chspec = ch20mhz_chspec(channel);
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			return chspec;
++	}
++
++	return (u16) INVCHANSPEC;
++}
++
++int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	*qdbm = pi->tx_user_target[0];
++	if (override != NULL)
++		*override = pi->txpwroverride;
++	return 0;
++}
++
++void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				struct txpwr_limits *txpwr)
++{
++	bool mac_enabled = false;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
++	       &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
++	       &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
++	       &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
++	       &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
++	       &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
++	       &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
++	       &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
++	       &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
++	       &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
++	       &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
++	       &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
++	       &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
++	       &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	if (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++		mac_enabled = true;
++
++	if (mac_enabled)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++
++	if (mac_enabled)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	int i;
++
++	if (qdbm > 127)
++		return -EINVAL;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->tx_user_target[i] = (u8) qdbm;
++
++	pi->txpwroverride = false;
++
++	if (pi->sh->up) {
++		if (!SCAN_INPROG_PHY(pi)) {
++			bool suspend;
++
++			suspend = (0 == (bcma_read32(pi->d11core,
++						     D11REGOFFS(maccontrol)) &
++					 MCTL_EN_MAC));
++
++			if (!suspend)
++				wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++			wlc_phy_txpower_recalc_target(pi);
++			wlc_phy_cal_txpower_recalc_sw(pi);
++
++			if (!suspend)
++				wlapi_enable_mac(pi->sh->physhim);
++		}
++	}
++	return 0;
++}
++
++void
++wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
++			  u8 *max_pwr, int txp_rate_idx)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++
++	*min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
++
++	if (ISNPHY(pi)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
++						   (u8) txp_rate_idx);
++
++	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++	} else {
++
++		*max_pwr = BRCMS_TXPWR_MAX;
++
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_OFDM;
++
++		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++			if (channel == chan_info_all[i].chan)
++				break;
++		}
++
++		if (pi->hwtxpwr) {
++			*max_pwr = pi->hwtxpwr[i];
++		} else {
++
++			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++			if ((i >= FIRST_HIGH_5G_CHAN)
++			    && (i <= LAST_HIGH_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		}
++	}
++}
++
++void
++wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
++				  u8 *max_txpwr, u8 *min_txpwr)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 max_num_rate;
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++
++	pactrl = 0;
++
++	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
++		       ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 +
++				       1) : (TXP_LAST_OFDM + 1);
++
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
++					  rate);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
++		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
++	}
++	*max_txpwr = tx_pwr_max;
++	*min_txpwr = tx_pwr_min;
++}
++
++void
++wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
++				s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
++{
++	return;
++}
++
++u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_min;
++}
++
++u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_max;
++}
++
++static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_vbatsense(pi, 0);
++	else
++		return 0;
++}
++
++static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_tempsense_degree(pi, 0);
++	else
++		return 0;
++}
++
++static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
++{
++	u8 i;
++	s8 temp, vbat;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++
++	vbat = wlc_phy_env_measure_vbat(pi);
++	temp = wlc_phy_env_measure_temperature(pi);
++
++}
++
++static s8
++wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
++				 u8 rate)
++{
++	s8 offset = 0;
++
++	if (!pi->user_txpwr_at_rfport)
++		return offset;
++	return offset;
++}
++
++void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++	uint target_chan;
++	u8 tx_pwr_target[TXP_NUM_RATES];
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 tx_pwr_max_rate_ind = 0;
++	u8 max_num_rate;
++	u8 start_rate = 0;
++	u16 chspec;
++	u32 band = CHSPEC2BAND(pi->radio_chanspec);
++	void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL;
++
++	chspec = pi->radio_chanspec;
++	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
++		target_chan = CHSPEC_CHANNEL(chspec);
++	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
++		target_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
++	else
++		target_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
++
++	pactrl = 0;
++	if (ISLCNPHY(pi)) {
++		u32 offset_mcs, i;
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			offset_mcs = pi->mcs40_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		} else {
++			offset_mcs = pi->mcs20_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++	}
++
++	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++			((ISLCNPHY(pi)) ?
++			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
++
++	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
++
++	for (rate = start_rate; rate < max_num_rate; rate++) {
++
++		tx_pwr_target[rate] = pi->tx_user_target[rate];
++
++		if (pi->user_txpwr_at_rfport)
++			tx_pwr_target[rate] +=
++				wlc_user_txpwr_antport_to_rfport(pi,
++								 target_chan,
++								 band,
++								 rate);
++
++		wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
++					  target_chan,
++					  &mintxpwr, &maxtxpwr, rate);
++
++		maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
++
++		if (pi->txpwr_percent <= 100)
++			maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
++
++		tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
++
++		tx_pwr_target[rate] =
++			min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
++
++		if (tx_pwr_target[rate] > tx_pwr_max)
++			tx_pwr_max_rate_ind = rate;
++
++		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
++		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
++	}
++
++	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
++	pi->tx_power_max = tx_pwr_max;
++	pi->tx_power_min = tx_pwr_min;
++	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		pi->tx_power_target[rate] = tx_pwr_target[rate];
++
++		if (!pi->hwpwrctrl || ISNPHY(pi))
++			pi->tx_power_offset[rate] =
++				pi->tx_power_max - pi->tx_power_target[rate];
++		else
++			pi->tx_power_offset[rate] =
++				pi->tx_power_target[rate] - pi->tx_power_min;
++	}
++
++	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
++	if (txpwr_recalc_fn)
++		(*txpwr_recalc_fn)(pi);
++}
++
++static void
++wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
++			       u16 chanspec)
++{
++	u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
++	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
++	int rate_start_index = 0, rate1, rate2, k;
++
++	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
++
++	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
++
++	if (ISNPHY(pi)) {
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->mcs_20_siso;
++				txpwr_ptr2 = txpwr->ofdm;
++				rate_start_index = WL_TX_POWER_OFDM_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->mcs_20_cdd;
++				txpwr_ptr2 = txpwr->ofdm_cdd;
++				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->mcs_40_siso;
++				txpwr_ptr2 = txpwr->ofdm_40_siso;
++				rate_start_index =
++					WL_TX_POWER_OFDM40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->mcs_40_cdd;
++				txpwr_ptr2 = txpwr->ofdm_40_cdd;
++				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
++				break;
++			}
++
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_mcs_to_ofdm_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->ofdm;
++				txpwr_ptr2 = txpwr->mcs_20_siso;
++				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->ofdm_cdd;
++				txpwr_ptr2 = txpwr->mcs_20_cdd;
++				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->ofdm_40_siso;
++				txpwr_ptr2 = txpwr->mcs_40_siso;
++				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->ofdm_40_cdd;
++				txpwr_ptr2 = txpwr->mcs_40_cdd;
++				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
++				break;
++			}
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_ofdm_to_mcs_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_stbc;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_stbc;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_mimo;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_mimo;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
++
++		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
++			min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
++			    pi->txpwr_limit[WL_TX_POWER_MCS_32]);
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
++			pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
++	}
++}
++
++void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->txpwr_percent = txpwr_percent;
++}
++
++void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->sh->machwcap = machwcap;
++}
++
++void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 rxc;
++	rxc = 0;
++
++	if (start_end == ON) {
++		if (!ISNPHY(pi))
++			return;
++
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_set16(pi->d11core, D11REGOFFS(phyregdata),
++				   0x1 << 15);
++		}
++	} else {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_write16(pi->d11core, D11REGOFFS(phyregdata), rxc);
++		}
++
++		wlc_phy_por_inform(ppi);
++	}
++}
++
++void
++wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
++			  u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
++
++	if (ISLCNPHY(pi)) {
++		int i, j;
++		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
++		     j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
++			if (txpwr->mcs_20_siso[j])
++				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
++			else
++				pi->txpwr_limit[i] = txpwr->ofdm[j];
++		}
++	}
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->ofdm_rateset_war = war;
++}
++
++void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->bf_preempt_4306 = bf_preempt;
++}
++
++void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
++{
++	int j;
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	if (pi->hwpwrctrl) {
++		u16 offset;
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
++				     1 << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
++				     pi->tx_power_min << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
++				     pi->hwpwr_txcur);
++
++		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
++			const u8 ucode_ofdm_rates[] = {
++				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
++			};
++			offset = wlapi_bmac_rate_shm_offset(
++				pi->sh->physhim,
++				ucode_ofdm_rates[j - TXP_FIRST_OFDM]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
++					     pi->tx_power_offset[j]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
++					     -(pi->tx_power_offset[j] / 2));
++		}
++
++		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
++			       MHF2_HWPWRCTL, BRCM_BAND_ALL);
++	} else {
++		int i;
++
++		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
++			pi->tx_power_offset[i] =
++				(u8) roundup(pi->tx_power_offset[i], 8);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
++				     (u16)
++				     ((pi->tx_power_offset[TXP_FIRST_OFDM]
++				       + 7) >> 3));
++	}
++}
++
++bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return pi->nphy_txpwrctrl;
++	else
++		return pi->hwpwrctrl;
++}
++
++void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	if (!pi->hwpwrctrl_capable)
++		return;
++
++	pi->hwpwrctrl = hwpwrctrl;
++	pi->nphy_txpwrctrl = hwpwrctrl;
++	pi->txpwrctrl = hwpwrctrl;
++
++	if (ISNPHY(pi)) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++			wlc_phy_txpwr_fixpower_nphy(pi);
++		else
++			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++				    pi->saved_txpwr_idx);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++}
++
++void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
++		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
++	} else {
++		pi->ipa2g_on = false;
++		pi->ipa5g_on = false;
++	}
++}
++
++static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
++{
++	s16 tx0_status, tx1_status;
++	u16 estPower1, estPower2;
++	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
++	u32 est_pwr;
++
++	estPower1 = read_phy_reg(pi, 0x118);
++	estPower2 = read_phy_reg(pi, 0x119);
++
++	if ((estPower1 & (0x1 << 8)) == (0x1 << 8))
++		pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0;
++	else
++		pwr0 = 0x80;
++
++	if ((estPower2 & (0x1 << 8)) == (0x1 << 8))
++		pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0;
++	else
++		pwr1 = 0x80;
++
++	tx0_status = read_phy_reg(pi, 0x1ed);
++	tx1_status = read_phy_reg(pi, 0x1ee);
++
++	if ((tx0_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr0 = 0x80;
++	if ((tx1_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr1 = 0x80;
++
++	est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) |
++			 adj_pwr1);
++
++	return est_pwr;
++}
++
++void
++wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
++			    uint channel)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint rate, num_rates;
++	u8 min_pwr, max_pwr;
++
++#if WL_TX_POWER_RATES != TXP_NUM_RATES
++#error "struct tx_power out of sync with this fn"
++#endif
++
++	if (ISNPHY(pi)) {
++		power->rf_cores = 2;
++		power->flags |= (WL_TX_POWER_F_MIMO);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++			power->flags |=
++				(WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
++	} else if (ISLCNPHY(pi)) {
++		power->rf_cores = 1;
++		power->flags |= (WL_TX_POWER_F_SISO);
++		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
++			power->flags |= WL_TX_POWER_F_ENABLED;
++		if (pi->hwpwrctrl)
++			power->flags |= WL_TX_POWER_F_HW;
++	}
++
++	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++		     ((ISLCNPHY(pi)) ?
++		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
++
++	for (rate = 0; rate < num_rates; rate++) {
++		power->user_limit[rate] = pi->tx_user_target[rate];
++		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
++					  rate);
++		power->board_limit[rate] = (u8) max_pwr;
++		power->target[rate] = pi->tx_power_target[rate];
++	}
++
++	if (ISNPHY(pi)) {
++		u32 est_pout;
++
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++		est_pout = wlc_phy_txpower_est_power_nphy(pi);
++		wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		power->est_Pout[0] = (est_pout >> 8) & 0xff;
++		power->est_Pout[1] = est_pout & 0xff;
++
++		power->est_Pout_act[0] = est_pout >> 24;
++		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
++
++		if (power->est_Pout[0] == 0x80)
++			power->est_Pout[0] = 0;
++		if (power->est_Pout[1] == 0x80)
++			power->est_Pout[1] = 0;
++
++		if (power->est_Pout_act[0] == 0x80)
++			power->est_Pout_act[0] = 0;
++		if (power->est_Pout_act[1] == 0x80)
++			power->est_Pout_act[1] = 0;
++
++		power->est_Pout_cck = 0;
++
++		power->tx_power_max[0] = pi->tx_power_max;
++		power->tx_power_max[1] = pi->tx_power_max;
++
++		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
++		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
++	} else if (pi->hwpwrctrl && pi->sh->up) {
++
++		wlc_phyreg_enter(ppi);
++		if (ISLCNPHY(pi)) {
++
++			power->tx_power_max[0] = pi->tx_power_max;
++			power->tx_power_max[1] = pi->tx_power_max;
++
++			power->tx_power_max_rate_ind[0] =
++				pi->tx_power_max_rate_ind;
++			power->tx_power_max_rate_ind[1] =
++				pi->tx_power_max_rate_ind;
++
++			if (wlc_phy_tpc_isenabled_lcnphy(pi))
++				power->flags |=
++					(WL_TX_POWER_F_HW |
++					 WL_TX_POWER_F_ENABLED);
++			else
++				power->flags &=
++					~(WL_TX_POWER_F_HW |
++					  WL_TX_POWER_F_ENABLED);
++
++			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
++					    (s8 *) &power->est_Pout_cck);
++		}
++		wlc_phyreg_exit(ppi);
++	}
++}
++
++void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->antsel_type = antsel_type;
++}
++
++bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->phytest_on;
++}
++
++void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	pi->sh->rx_antdiv = val;
++
++	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
++		if (val > ANT_RX_DIV_FORCE_1)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
++				       MHF1_ANTDIV, BRCM_BAND_ALL);
++		else
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
++				       BRCM_BAND_ALL);
++	}
++
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (ISLCNPHY(pi)) {
++		if (val > ANT_RX_DIV_FORCE_1) {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
++			mod_phy_reg(pi, 0x410,
++				    (0x1 << 0),
++				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
++		} else {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
++			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
++		}
++	}
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return;
++}
++
++static bool
++wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
++{
++	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
++	u8 i;
++
++	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
++	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
++		else
++
++			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
++	}
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
++		pwr_ant[i] = cmplx_pwr_dbm[i];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++	return true;
++}
++
++static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
++{
++	if (!pi->phynoise_state)
++		return;
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
++		if (pi->phynoise_chan_watchdog == channel) {
++			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
++				noise_dbm;
++			pi->sh->phy_noise_index =
++				MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
++		}
++		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
++	}
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL)
++		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
++
++}
++
++static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
++{
++	u32 cmplx_pwr[PHY_CORE_MAX];
++	s8 noise_dbm_ant[PHY_CORE_MAX];
++	u16 lo, hi;
++	u32 cmplx_pwr_tot = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	u8 idx, core;
++
++	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2,
++	     core++) {
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
++		hi = wlapi_bmac_read_shm(pi->sh->physhim,
++					 M_PWRIND_MAP(idx + 1));
++		cmplx_pwr[core] = (hi << 16) + lo;
++		cmplx_pwr_tot += cmplx_pwr[core];
++		if (cmplx_pwr[core] == 0)
++			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
++		else
++			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
++	}
++
++	if (cmplx_pwr_tot != 0)
++		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		pi->nphy_noise_win[core][pi->nphy_noise_index] =
++			noise_dbm_ant[core];
++
++		if (noise_dbm_ant[core] > noise_dbm)
++			noise_dbm = noise_dbm_ant[core];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++
++	return noise_dbm;
++
++}
++
++void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 jssi_aux;
++	u8 channel = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++
++	if (ISLCNPHY(pi)) {
++		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
++		u16 lo, hi;
++		s32 pwr_offset_dB, gain_dB;
++		u16 status_0, status_1;
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
++		cmplx_pwr0 = (hi << 16) + lo;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
++		cmplx_pwr1 = (hi << 16) + lo;
++		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
++
++		status_0 = 0x44;
++		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
++		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
++		    && ((status_1 & 0xc000) == 0x4000)) {
++
++			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
++					   pi->pubpi.phy_corenum);
++			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
++			if (pwr_offset_dB > 127)
++				pwr_offset_dB -= 256;
++
++			noise_dbm += (s8) (pwr_offset_dB - 30);
++
++			gain_dB = (status_0 & 0x1ff);
++			noise_dbm -= (s8) (gain_dB);
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
++		}
++	} else if (ISNPHY(pi)) {
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		noise_dbm = wlc_phy_noise_read_shmem(pi);
++	}
++
++	wlc_phy_noise_cb(pi, channel, noise_dbm);
++
++}
++
++static void
++wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	bool sampling_in_progress = (pi->phynoise_state != 0);
++	bool wait_for_intr = true;
++
++	switch (reason) {
++	case PHY_NOISE_SAMPLE_MON:
++		pi->phynoise_chan_watchdog = ch;
++		pi->phynoise_state |= PHY_NOISE_STATE_MON;
++		break;
++
++	case PHY_NOISE_SAMPLE_EXTERNAL:
++		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
++		break;
++
++	default:
++		break;
++	}
++
++	if (sampling_in_progress)
++		return;
++
++	pi->phynoise_now = pi->sh->now;
++
++	if (pi->phy_fixed_noise) {
++		if (ISNPHY(pi)) {
++			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL;
++		}
++
++		wait_for_intr = false;
++		goto done;
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_lcnphy_deaf_mode(pi, (bool) 0);
++			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
++			wlc_lcnphy_deaf_mode(pi, (bool) 1);
++			wlapi_enable_mac(pi->sh->physhim);
++			wait_for_intr = false;
++		}
++	} else if (ISNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			struct phy_iq_est est[PHY_CORE_MAX];
++			u32 cmplx_pwr[PHY_CORE_MAX];
++			s8 noise_dbm_ant[PHY_CORE_MAX];
++			u16 log_num_samps, num_samps, classif_state = 0;
++			u8 wait_time = 32;
++			u8 wait_crs = 0;
++			u8 i;
++
++			memset((u8 *) est, 0, sizeof(est));
++			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++			num_samps = 1 << log_num_samps;
++
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, 3, 0);
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
++					       wait_crs);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++			wlapi_enable_mac(pi->sh->physhim);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++)
++				cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >>
++					       log_num_samps;
++
++			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++				pi->nphy_noise_win[i][pi->nphy_noise_index] =
++					noise_dbm_ant[i];
++
++				if (noise_dbm_ant[i] > noise_dbm)
++					noise_dbm = noise_dbm_ant[i];
++			}
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++
++			wait_for_intr = false;
++		}
++	}
++
++done:
++
++	if (!wait_for_intr)
++		wlc_phy_noise_cb(pi, ch, noise_dbm);
++
++}
++
++void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
++{
++	u8 channel;
++
++	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
++
++	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
++}
++
++static const s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	9,
++	10,
++	8,
++	8,
++	7,
++	7,
++	1,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	1,
++	1,
++	0,
++	0,
++	0,
++	0
++};
++
++void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
++{
++	u8 msb, secondmsb, i;
++	u32 tmp;
++
++	for (i = 0; i < core; i++) {
++		secondmsb = 0;
++		tmp = cmplx_pwr[i];
++		msb = fls(tmp);
++		if (msb)
++			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
++		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
++	}
++}
++
++int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++			 struct d11rxhdr *rxh)
++{
++	int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
++	uint radioid = pih->radioid;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if ((pi->sh->corerev >= 11)
++	    && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
++		rssi = BRCMS_RSSI_INVALID;
++		goto end;
++	}
++
++	if (ISLCNPHY(pi)) {
++		u8 gidx = (rxh->PhyRxStatus_2 & 0xFC00) >> 10;
++		struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++		if (rssi > 127)
++			rssi -= 256;
++
++		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
++		if ((rssi > -46) && (gidx > 18))
++			rssi = rssi + 7;
++
++		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
++
++		rssi = rssi + 2;
++
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (rssi > 127)
++			rssi -= 256;
++	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
++		   || radioid == BCM2057_ID) {
++		rssi = wlc_phy_rssi_compute_nphy(pi, rxh);
++	}
++
++end:
++	return rssi;
++}
++
++void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
++{
++	struct brcms_phy *pi;
++	pi = (struct brcms_phy *) ppi;
++
++	if (ISLCNPHY(pi))
++		wlc_lcnphy_deaf_mode(pi, true);
++	else if (ISNPHY(pi))
++		wlc_nphy_deaf_mode(pi, true);
++}
++
++void wlc_phy_watchdog(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	bool delay_phy_cal = false;
++	pi->sh->now++;
++
++	if (!pi->watchdog_override)
++		return;
++
++	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)))
++		wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
++					     PHY_NOISE_SAMPLE_MON,
++					     CHSPEC_CHANNEL(pi->
++							    radio_chanspec));
++
++	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5)
++		pi->phynoise_state = 0;
++
++	if ((!pi->phycal_txpower) ||
++	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
++
++		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi))
++			pi->phycal_txpower = pi->sh->now;
++	}
++
++	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++	     || ASSOC_INPROG_PHY(pi)))
++		return;
++
++	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
++
++		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
++		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
++		    ((pi->sh->now - pi->nphy_perical_last) >=
++		     pi->sh->glacial_timer))
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_WATCHDOG);
++
++		wlc_phy_txpwr_papd_cal_nphy(pi);
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (pi->phy_forcecal ||
++		    ((pi->sh->now - pi->phy_lastcal) >=
++		     pi->sh->glacial_timer)) {
++			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
++				wlc_lcnphy_calib_modes(
++					pi,
++					LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++			if (!
++			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++			     || ASSOC_INPROG_PHY(pi)
++			     || pi->carrier_suppr_disable
++			     || pi->disable_percal))
++				wlc_lcnphy_calib_modes(pi,
++						       PHY_PERICAL_WATCHDOG);
++		}
++	}
++}
++
++void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	uint i;
++	uint k;
++
++	for (i = 0; i < MA_WINDOW_SZ; i++)
++		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
++	if (ISLCNPHY(pi)) {
++		for (i = 0; i < MA_WINDOW_SZ; i++)
++			pi->sh->phy_noise_window[i] =
++				PHY_NOISE_FIXED_VAL_LCNPHY;
++	}
++	pi->sh->phy_noise_index = 0;
++
++	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
++		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
++			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
++	}
++	pi->nphy_noise_index = 0;
++}
++
++void
++wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
++{
++	*eps_imag = (epsilon >> 13);
++	if (*eps_imag > 0xfff)
++		*eps_imag -= 0x2000;
++
++	*eps_real = (epsilon & 0x1fff);
++	if (*eps_real > 0xfff)
++		*eps_real -= 0x2000;
++}
++
++void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
++{
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++static void
++wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
++{
++
++	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
++	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
++		return;
++
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	wlapi_add_timer(pi->phycal_timer, delay, 0);
++}
++
++void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
++{
++	s16 nphy_currtemp = 0;
++	s16 delta_temp = 0;
++	bool do_periodic_cal = true;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!ISNPHY(pi))
++		return;
++
++	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
++	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
++		return;
++
++	switch (reason) {
++	case PHY_PERICAL_DRIVERUP:
++		break;
++
++	case PHY_PERICAL_PHYINIT:
++		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++			if (PHY_PERICAL_MPHASE_PENDING(pi))
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			wlc_phy_cal_perical_mphase_schedule(
++				pi,
++				PHY_PERICAL_INIT_DELAY);
++		}
++		break;
++
++	case PHY_PERICAL_JOIN_BSS:
++	case PHY_PERICAL_START_IBSS:
++	case PHY_PERICAL_UP_BSS:
++		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
++		    PHY_PERICAL_MPHASE_PENDING(pi))
++			wlc_phy_cal_perical_mphase_reset(pi);
++
++		pi->first_cal_after_assoc = true;
++
++		pi->cal_type_override = PHY_PERICAL_FULL;
++
++		if (pi->phycal_tempdelta)
++			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
++
++		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
++		break;
++
++	case PHY_PERICAL_WATCHDOG:
++		if (pi->phycal_tempdelta) {
++			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++			delta_temp =
++				(nphy_currtemp > pi->nphy_lastcal_temp) ?
++				nphy_currtemp - pi->nphy_lastcal_temp :
++				pi->nphy_lastcal_temp - nphy_currtemp;
++
++			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
++			    (pi->nphy_txiqlocal_chanspec ==
++			     pi->radio_chanspec))
++				do_periodic_cal = false;
++			else
++				pi->nphy_lastcal_temp = nphy_currtemp;
++		}
++
++		if (do_periodic_cal) {
++			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++				if (!PHY_PERICAL_MPHASE_PENDING(pi))
++					wlc_phy_cal_perical_mphase_schedule(
++						pi,
++						PHY_PERICAL_WDOG_DELAY);
++			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
++				wlc_phy_cal_perical_nphy_run(pi,
++							     PHY_PERICAL_AUTO);
++		}
++		break;
++	default:
++		break;
++	}
++}
++
++void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
++{
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++u8 wlc_phy_nbits(s32 value)
++{
++	s32 abs_val;
++	u8 nbits = 0;
++
++	abs_val = abs(value);
++	while ((abs_val >> nbits) > 0)
++		nbits++;
++
++	return nbits;
++}
++
++void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->hw_phytxchain = txchain;
++	pi->sh->hw_phyrxchain = rxchain;
++	pi->sh->phytxchain = txchain;
++	pi->sh->phyrxchain = rxchain;
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->phytxchain = txchain;
++
++	if (ISNPHY(pi))
++		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
++
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	*txchain = pi->sh->phytxchain;
++	*rxchain = pi->sh->phyrxchain;
++}
++
++u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
++{
++	s16 nphy_currtemp;
++	u8 active_bitmap;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
++
++	if (!pi->watchdog_override)
++		return active_bitmap;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		if (!pi->phy_txcore_heatedup) {
++			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
++				active_bitmap &= 0xFD;
++				pi->phy_txcore_heatedup = true;
++			}
++		} else {
++			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
++				active_bitmap |= 0x2;
++				pi->phy_txcore_heatedup = false;
++			}
++		}
++	}
++
++	return active_bitmap;
++}
++
++s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u8 siso_mcs_id, cdd_mcs_id;
++
++	siso_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
++		TXP_FIRST_MCS_20_SISO;
++	cdd_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
++		TXP_FIRST_MCS_20_CDD;
++
++	if (pi->tx_power_target[siso_mcs_id] >
++	    (pi->tx_power_target[cdd_mcs_id] + 12))
++		return PHY_TXC1_MODE_SISO;
++	else
++		return PHY_TXC1_MODE_CDD;
++}
++
++const u8 *wlc_phy_get_ofdm_rate_lookup(void)
++{
++	return ofdm_rate_lookup;
++}
++
++void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
++{
++	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
++	    (pi->sh->boardflags & BFL_FEM)) {
++		if (mode) {
++			u16 txant = 0;
++			txant = wlapi_bmac_get_txant(pi->sh->physhim);
++			if (txant == 1) {
++				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
++
++			}
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x40);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x40);
++		} else {
++			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
++
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x00);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x40);
++		}
++	}
++}
++
++void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
++{
++	return;
++}
++
++void
++wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
++{
++	*cckoffset = 0;
++	*ofdmoffset = 0;
++}
++
++s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
++{
++
++	return rssi;
++}
++
++bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return wlc_phy_n_txpower_ipa_ison(pi);
++	else
++		return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+new file mode 100644
+index 0000000..e34a71e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+@@ -0,0 +1,299 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_hal.h:  functionality exported from the phy to higher layers
++ */
++
++#ifndef _BRCM_PHY_HAL_H_
++#define _BRCM_PHY_HAL_H_
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <phy_shim.h>
++
++#define	IDCODE_VER_MASK		0x0000000f
++#define	IDCODE_VER_SHIFT	0
++#define	IDCODE_MFG_MASK		0x00000fff
++#define	IDCODE_MFG_SHIFT	0
++#define	IDCODE_ID_MASK		0x0ffff000
++#define	IDCODE_ID_SHIFT		12
++#define	IDCODE_REV_MASK		0xf0000000
++#define	IDCODE_REV_SHIFT	28
++
++#define	NORADIO_ID		0xe4f5
++#define	NORADIO_IDCODE		0x4e4f5246
++
++#define BCM2055_ID		0x2055
++#define BCM2055_IDCODE		0x02055000
++#define BCM2055A0_IDCODE	0x1205517f
++
++#define BCM2056_ID		0x2056
++#define BCM2056_IDCODE		0x02056000
++#define BCM2056A0_IDCODE	0x1205617f
++
++#define BCM2057_ID		0x2057
++#define BCM2057_IDCODE		0x02057000
++#define BCM2057A0_IDCODE	0x1205717f
++
++#define BCM2064_ID		0x2064
++#define BCM2064_IDCODE		0x02064000
++#define BCM2064A0_IDCODE	0x0206417f
++
++#define PHY_TPC_HW_OFF		false
++#define PHY_TPC_HW_ON		true
++
++#define PHY_PERICAL_DRIVERUP	1
++#define PHY_PERICAL_WATCHDOG	2
++#define PHY_PERICAL_PHYINIT	3
++#define PHY_PERICAL_JOIN_BSS	4
++#define PHY_PERICAL_START_IBSS	5
++#define PHY_PERICAL_UP_BSS	6
++#define PHY_PERICAL_CHAN	7
++#define PHY_FULLCAL	8
++
++#define PHY_PERICAL_DISABLE	0
++#define PHY_PERICAL_SPHASE	1
++#define PHY_PERICAL_MPHASE	2
++#define PHY_PERICAL_MANUAL	3
++
++#define PHY_HOLD_FOR_ASSOC	1
++#define PHY_HOLD_FOR_SCAN	2
++#define PHY_HOLD_FOR_RM		4
++#define PHY_HOLD_FOR_PLT	8
++#define PHY_HOLD_FOR_MUTE	16
++#define PHY_HOLD_FOR_NOT_ASSOC 0x20
++
++#define PHY_MUTE_FOR_PREISM	1
++#define PHY_MUTE_ALL		0xffffffff
++
++#define PHY_NOISE_FIXED_VAL		(-95)
++#define PHY_NOISE_FIXED_VAL_NPHY	(-92)
++#define PHY_NOISE_FIXED_VAL_LCNPHY	(-92)
++
++#define PHY_MODE_CAL		0x0002
++#define PHY_MODE_NOISEM		0x0004
++
++#define BRCMS_TXPWR_DB_FACTOR	4
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++#define BRCMS_NUM_RATES_CCK           4
++#define BRCMS_NUM_RATES_OFDM          8
++#define BRCMS_NUM_RATES_MCS_1_STREAM  8
++#define BRCMS_NUM_RATES_MCS_2_STREAM  8
++#define BRCMS_NUM_RATES_MCS_3_STREAM  8
++#define BRCMS_NUM_RATES_MCS_4_STREAM  8
++
++#define	BRCMS_RSSI_INVALID	 0	/* invalid RSSI value */
++
++struct d11regs;
++struct phy_shim_info;
++
++struct txpwr_limits {
++	u8 cck[BRCMS_NUM_RATES_CCK];
++	u8 ofdm[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
++	u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++
++	u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++	u8 mcs32;
++};
++
++struct tx_power {
++	u32 flags;
++	u16 chanspec;   /* txpwr report for this channel */
++	u16 local_chanspec;     /* channel on which we are associated */
++	u8 local_max;   /* local max according to the AP */
++	u8 local_constraint;    /* local constraint according to the AP */
++	s8 antgain[2];  /* Ant gain for each band - from SROM */
++	u8 rf_cores;            /* count of RF Cores being reported */
++	u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
++	u8 est_Pout_act[4];     /* Latest tx power out estimate per RF chain
++				 * without adjustment */
++	u8 est_Pout_cck;        /* Latest CCK tx power out estimate */
++	u8 tx_power_max[4];     /* Maximum target power among all rates */
++	/* Index of the rate with the max target power */
++	u8 tx_power_max_rate_ind[4];
++	/* User limit */
++	u8 user_limit[WL_TX_POWER_RATES];
++	/* Regulatory power limit */
++	u8 reg_limit[WL_TX_POWER_RATES];
++	/* Max power board can support (SROM) */
++	u8 board_limit[WL_TX_POWER_RATES];
++	/* Latest target power */
++	u8 target[WL_TX_POWER_RATES];
++};
++
++struct tx_inst_power {
++	u8 txpwr_est_Pout[2];   /* Latest estimate for 2.4 and 5 Ghz */
++	u8 txpwr_est_Pout_gofdm;        /* Pwr estimate for 2.4 OFDM */
++};
++
++struct brcms_chanvec {
++	u8 vec[MAXCHANNEL / NBBY];
++};
++
++struct shared_phy_params {
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint unit;
++	uint corerev;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++};
++
++
++extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
++extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
++					    struct bcma_device *d11core,
++					    int bandtype, struct wiphy *wiphy);
++extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
++
++extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
++				   u16 *phyrev, u16 *radioid,
++				   u16 *radiover);
++extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
++extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
++extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
++extern int wlc_phy_down(struct brcms_phy_pub *ppi);
++extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
++extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
++extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
++
++extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
++				 u16 chanspec);
++extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
++				       u16 newch);
++extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
++
++extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++				struct d11rxhdr *rxh);
++extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
++extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
++
++extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
++extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
++
++
++extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
++
++extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++						 bool wide_filter);
++extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++					  struct brcms_chanvec *channels);
++extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
++					 uint band);
++
++extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
++				      u8 *_min_, u8 *_max_, int rate);
++extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
++					      uint chan, u8 *_max_, u8 *_min_);
++extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
++					    uint band, s32 *, s32 *, u32 *);
++extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
++				      struct txpwr_limits *,
++				      u16 chanspec);
++extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
++			       bool *override);
++extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
++			       bool override);
++extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				       struct txpwr_limits *);
++extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
++					bool hwpwrctrl);
++extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
++extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
++				   u8 rxchain);
++extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
++				  u8 rxchain);
++extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
++				  u8 *rxchain);
++extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
++extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
++				 u16 chanspec);
++extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
++
++extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
++extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
++extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
++extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
++extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
++extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
++extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
++
++extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
++
++extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
++					struct tx_power *power, uint channel);
++
++extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
++extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
++				      u8 txpwr_percent);
++extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
++extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
++				      bool bf_preempt);
++extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
++
++extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
++
++extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
++extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
++
++extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
++
++extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
++					     u8 mcs_offset);
++extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
++#endif                          /* _BRCM_PHY_HAL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+new file mode 100644
+index 0000000..af00e2c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+@@ -0,0 +1,1162 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_INT_H_
++#define _BRCM_PHY_INT_H_
++
++#include <types.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#define	PHY_VERSION			{ 1, 82, 8, 0 }
++
++#define LCNXN_BASEREV		16
++
++struct phy_shim_info;
++
++struct brcms_phy_srom_fem {
++	/* TSSI positive slope, 1: positive, 0: negative */
++	u8 tssipos;
++	/* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
++	u8 extpagain;
++	/* support 32 combinations of different Pdet dynamic ranges */
++	u8 pdetrange;
++	/* TR switch isolation */
++	u8 triso;
++	/* antswctrl lookup table configuration: 32 possible choices */
++	u8 antswctrllut;
++};
++
++#define ISNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
++#define ISLCNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
++
++#define PHY_GET_RFATTN(rfgain)	((rfgain) & 0x0f)
++#define PHY_GET_PADMIX(rfgain)	(((rfgain) & 0x10) >> 4)
++#define PHY_GET_RFGAINID(rfattn, padmix, width)	((rfattn) + ((padmix)*(width)))
++#define PHY_SAT(x, n)		((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
++				((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
++#define PHY_SHIFT_ROUND(x, n)	((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
++#define PHY_HW_ROUND(x, s)		((x >> s) + ((x >> (s-1)) & (s != 0)))
++
++#define CH_5G_GROUP	3
++#define A_LOW_CHANS	0
++#define A_MID_CHANS	1
++#define A_HIGH_CHANS	2
++#define CH_2G_GROUP	1
++#define G_ALL_CHANS	0
++
++#define FIRST_REF5_CHANNUM	149
++#define LAST_REF5_CHANNUM	165
++#define	FIRST_5G_CHAN		14
++#define	LAST_5G_CHAN		50
++#define	FIRST_MID_5G_CHAN	14
++#define	LAST_MID_5G_CHAN	35
++#define	FIRST_HIGH_5G_CHAN	36
++#define	LAST_HIGH_5G_CHAN	41
++#define	FIRST_LOW_5G_CHAN	42
++#define	LAST_LOW_5G_CHAN	50
++
++#define BASE_LOW_5G_CHAN	4900
++#define BASE_MID_5G_CHAN	5100
++#define BASE_HIGH_5G_CHAN	5500
++
++#define CHAN5G_FREQ(chan)  (5000 + chan*5)
++#define CHAN2G_FREQ(chan)  (2407 + chan*5)
++
++#define TXP_FIRST_CCK		0
++#define TXP_LAST_CCK		3
++#define TXP_FIRST_OFDM		4
++#define TXP_LAST_OFDM		11
++#define TXP_FIRST_OFDM_20_CDD	12
++#define TXP_LAST_OFDM_20_CDD	19
++#define TXP_FIRST_MCS_20_SISO	20
++#define TXP_LAST_MCS_20_SISO	27
++#define TXP_FIRST_MCS_20_CDD	28
++#define TXP_LAST_MCS_20_CDD	35
++#define TXP_FIRST_MCS_20_STBC	36
++#define TXP_LAST_MCS_20_STBC	43
++#define TXP_FIRST_MCS_20_SDM	44
++#define TXP_LAST_MCS_20_SDM	51
++#define TXP_FIRST_OFDM_40_SISO	52
++#define TXP_LAST_OFDM_40_SISO	59
++#define TXP_FIRST_OFDM_40_CDD	60
++#define TXP_LAST_OFDM_40_CDD	67
++#define TXP_FIRST_MCS_40_SISO	68
++#define TXP_LAST_MCS_40_SISO	75
++#define TXP_FIRST_MCS_40_CDD	76
++#define TXP_LAST_MCS_40_CDD	83
++#define TXP_FIRST_MCS_40_STBC	84
++#define TXP_LAST_MCS_40_STBC	91
++#define TXP_FIRST_MCS_40_SDM	92
++#define TXP_LAST_MCS_40_SDM	99
++#define TXP_MCS_32	        100
++#define TXP_NUM_RATES		101
++#define ADJ_PWR_TBL_LEN		84
++
++#define TXP_FIRST_SISO_MCS_20	20
++#define TXP_LAST_SISO_MCS_20	27
++
++#define PHY_CORE_NUM_1	1
++#define PHY_CORE_NUM_2	2
++#define PHY_CORE_NUM_3	3
++#define PHY_CORE_NUM_4	4
++#define PHY_CORE_MAX	PHY_CORE_NUM_4
++#define PHY_CORE_0	0
++#define PHY_CORE_1	1
++#define PHY_CORE_2	2
++#define PHY_CORE_3	3
++
++#define MA_WINDOW_SZ		8
++
++#define PHY_NOISE_SAMPLE_MON		1
++#define PHY_NOISE_SAMPLE_EXTERNAL	2
++#define PHY_NOISE_WINDOW_SZ	16
++#define PHY_NOISE_GLITCH_INIT_MA 10
++#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
++#define PHY_NOISE_STATE_MON		0x1
++#define PHY_NOISE_STATE_EXTERNAL	0x2
++#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY	10
++#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE	9
++
++#define PHY_NOISE_OFFSETFACT_4322  (-103)
++#define PHY_NOISE_MA_WINDOW_SZ	2
++
++#define	PHY_RSSI_TABLE_SIZE	64
++#define RSSI_ANT_MERGE_MAX	0
++#define RSSI_ANT_MERGE_MIN	1
++#define RSSI_ANT_MERGE_AVG	2
++
++#define	PHY_TSSI_TABLE_SIZE	64
++#define	APHY_TSSI_TABLE_SIZE	256
++#define	TX_GAIN_TABLE_LENGTH	64
++#define	DEFAULT_11A_TXP_IDX	24
++#define NUM_TSSI_FRAMES        4
++#define	NULL_TSSI		0x7f
++#define	NULL_TSSI_W		0x7f7f
++
++#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
++
++#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
++
++#define PHY_TXPWR_MIN		10
++#define PHY_TXPWR_MIN_NPHY	8
++#define RADIOPWR_OVERRIDE_DEF	(-1)
++
++#define PWRTBL_NUM_COEFF	3
++
++#define SPURAVOID_DISABLE	0
++#define SPURAVOID_AUTO		1
++#define SPURAVOID_FORCEON	2
++#define SPURAVOID_FORCEON2	3
++
++#define PHY_SW_TIMER_FAST		15
++#define PHY_SW_TIMER_SLOW		60
++#define PHY_SW_TIMER_GLACIAL	120
++
++#define PHY_PERICAL_AUTO	0
++#define PHY_PERICAL_FULL	1
++#define PHY_PERICAL_PARTIAL	2
++
++#define PHY_PERICAL_NODELAY	0
++#define PHY_PERICAL_INIT_DELAY	5
++#define PHY_PERICAL_ASSOC_DELAY	5
++#define PHY_PERICAL_WDOG_DELAY	5
++
++#define MPHASE_TXCAL_NUMCMDS	2
++
++#define PHY_PERICAL_MPHASE_PENDING(pi) \
++	(pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
++
++enum {
++	MPHASE_CAL_STATE_IDLE = 0,
++	MPHASE_CAL_STATE_INIT = 1,
++	MPHASE_CAL_STATE_TXPHASE0,
++	MPHASE_CAL_STATE_TXPHASE1,
++	MPHASE_CAL_STATE_TXPHASE2,
++	MPHASE_CAL_STATE_TXPHASE3,
++	MPHASE_CAL_STATE_TXPHASE4,
++	MPHASE_CAL_STATE_TXPHASE5,
++	MPHASE_CAL_STATE_PAPDCAL,
++	MPHASE_CAL_STATE_RXCAL,
++	MPHASE_CAL_STATE_RSSICAL,
++	MPHASE_CAL_STATE_IDLETSSI
++};
++
++enum phy_cal_mode {
++	CAL_FULL,
++	CAL_RECAL,
++	CAL_CURRECAL,
++	CAL_DIGCAL,
++	CAL_GCTRL,
++	CAL_SOFT,
++	CAL_DIGLO
++};
++
++#define RDR_NTIERS  1
++#define RDR_TIER_SIZE 64
++#define RDR_LIST_SIZE (512/3)
++#define RDR_EPOCH_SIZE 40
++#define RDR_NANTENNAS 2
++#define RDR_NTIER_SIZE  RDR_LIST_SIZE
++#define RDR_LP_BUFFER_SIZE 64
++#define LP_LEN_HIS_SIZE 10
++
++#define STATIC_NUM_RF 32
++#define STATIC_NUM_BB 9
++
++#define BB_MULT_MASK		0x0000ffff
++#define BB_MULT_VALID_MASK	0x80000000
++
++#define CORDIC_AG	39797
++#define	CORDIC_NI	18
++#define	FIXED(X)	((s32)((X) << 16))
++
++#define	FLOAT(X) \
++	(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
++
++#define PHY_CHAIN_TX_DISABLE_TEMP	115
++#define PHY_HYSTERESIS_DELTATEMP	5
++
++#define SCAN_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
++
++#define PLT_INPROG_PHY(pi)      (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
++
++#define ASSOC_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
++
++#define SCAN_RM_IN_PROGRESS(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
++
++#define PHY_MUTED(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
++
++#define PUB_NOT_ASSOC(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
++
++struct phy_table_info {
++	uint table;
++	int q;
++	uint max;
++};
++
++struct phytbl_info {
++	const void *tbl_ptr;
++	u32 tbl_len;
++	u32 tbl_id;
++	u32 tbl_offset;
++	u32 tbl_width;
++};
++
++struct interference_info {
++	u8 curr_home_channel;
++	u16 crsminpwrthld_40_stored;
++	u16 crsminpwrthld_20L_stored;
++	u16 crsminpwrthld_20U_stored;
++	u16 init_gain_code_core1_stored;
++	u16 init_gain_code_core2_stored;
++	u16 init_gain_codeb_core1_stored;
++	u16 init_gain_codeb_core2_stored;
++	u16 init_gain_table_stored[4];
++
++	u16 clip1_hi_gain_code_core1_stored;
++	u16 clip1_hi_gain_code_core2_stored;
++	u16 clip1_hi_gain_codeb_core1_stored;
++	u16 clip1_hi_gain_codeb_core2_stored;
++	u16 nb_clip_thresh_core1_stored;
++	u16 nb_clip_thresh_core2_stored;
++	u16 init_ofdmlna2gainchange_stored[4];
++	u16 init_ccklna2gainchange_stored[4];
++	u16 clip1_lo_gain_code_core1_stored;
++	u16 clip1_lo_gain_code_core2_stored;
++	u16 clip1_lo_gain_codeb_core1_stored;
++	u16 clip1_lo_gain_codeb_core2_stored;
++	u16 w1_clip_thresh_core1_stored;
++	u16 w1_clip_thresh_core2_stored;
++	u16 radio_2056_core1_rssi_gain_stored;
++	u16 radio_2056_core2_rssi_gain_stored;
++	u16 energy_drop_timeout_len_stored;
++
++	u16 ed_crs40_assertthld0_stored;
++	u16 ed_crs40_assertthld1_stored;
++	u16 ed_crs40_deassertthld0_stored;
++	u16 ed_crs40_deassertthld1_stored;
++	u16 ed_crs20L_assertthld0_stored;
++	u16 ed_crs20L_assertthld1_stored;
++	u16 ed_crs20L_deassertthld0_stored;
++	u16 ed_crs20L_deassertthld1_stored;
++	u16 ed_crs20U_assertthld0_stored;
++	u16 ed_crs20U_assertthld1_stored;
++	u16 ed_crs20U_deassertthld0_stored;
++	u16 ed_crs20U_deassertthld1_stored;
++
++	u16 badplcp_ma;
++	u16 badplcp_ma_previous;
++	u16 badplcp_ma_total;
++	u16 badplcp_ma_list[MA_WINDOW_SZ];
++	int badplcp_ma_index;
++	s16 pre_badplcp_cnt;
++	s16 bphy_pre_badplcp_cnt;
++
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u16 init_gain_rfseq[4];
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++
++	s16 crsminpwr_index;
++
++	u16 radio_2057_core1_rssi_wb1a_gc_stored;
++	u16 radio_2057_core2_rssi_wb1a_gc_stored;
++	u16 radio_2057_core1_rssi_wb1g_gc_stored;
++	u16 radio_2057_core2_rssi_wb1g_gc_stored;
++	u16 radio_2057_core1_rssi_wb2_gc_stored;
++	u16 radio_2057_core2_rssi_wb2_gc_stored;
++	u16 radio_2057_core1_rssi_nb_gc_stored;
++	u16 radio_2057_core2_rssi_nb_gc_stored;
++};
++
++struct aci_save_gphy {
++	u16 rc_cal_ovr;
++	u16 phycrsth1;
++	u16 phycrsth2;
++	u16 init_n1p1_gain;
++	u16 p1_p2_gain;
++	u16 n1_n2_gain;
++	u16 n1_p1_gain;
++	u16 div_search_gain;
++	u16 div_p1_p2_gain;
++	u16 div_search_gn_change;
++	u16 table_7_2;
++	u16 table_7_3;
++	u16 cckshbits_gnref;
++	u16 clip_thresh;
++	u16 clip2_thresh;
++	u16 clip3_thresh;
++	u16 clip_p2_thresh;
++	u16 clip_pwdn_thresh;
++	u16 clip_n1p1_thresh;
++	u16 clip_n1_pwdn_thresh;
++	u16 bbconfig;
++	u16 cthr_sthr_shdin;
++	u16 energy;
++	u16 clip_p1_p2_thresh;
++	u16 threshold;
++	u16 reg15;
++	u16 reg16;
++	u16 reg17;
++	u16 div_srch_idx;
++	u16 div_srch_p1_p2;
++	u16 div_srch_gn_back;
++	u16 ant_dwell;
++	u16 ant_wr_settle;
++};
++
++struct lo_complex_abgphy_info {
++	s8 i;
++	s8 q;
++};
++
++struct nphy_iq_comp {
++	s16 a0;
++	s16 b0;
++	s16 a1;
++	s16 b1;
++};
++
++struct nphy_txpwrindex {
++	s8 index;
++	s8 index_internal;
++	s8 index_internal_save;
++	u16 AfectrlOverride;
++	u16 AfeCtrlDacGain;
++	u16 rad_gain;
++	u8 bbmult;
++	u16 iqcomp_a;
++	u16 iqcomp_b;
++	u16 locomp;
++};
++
++struct txiqcal_cache {
++
++	u16 txcal_coeffs_2G[8];
++	u16 txcal_radio_regs_2G[8];
++	struct nphy_iq_comp rxcal_coeffs_2G;
++
++	u16 txcal_coeffs_5G[8];
++	u16 txcal_radio_regs_5G[8];
++	struct nphy_iq_comp rxcal_coeffs_5G;
++};
++
++struct nphy_pwrctrl {
++	s8 max_pwr_2g;
++	s8 idle_targ_2g;
++	s16 pwrdet_2g_a1;
++	s16 pwrdet_2g_b0;
++	s16 pwrdet_2g_b1;
++	s8 max_pwr_5gm;
++	s8 idle_targ_5gm;
++	s8 max_pwr_5gh;
++	s8 max_pwr_5gl;
++	s16 pwrdet_5gm_a1;
++	s16 pwrdet_5gm_b0;
++	s16 pwrdet_5gm_b1;
++	s16 pwrdet_5gl_a1;
++	s16 pwrdet_5gl_b0;
++	s16 pwrdet_5gl_b1;
++	s16 pwrdet_5gh_a1;
++	s16 pwrdet_5gh_b0;
++	s16 pwrdet_5gh_b1;
++	s8 idle_targ_5gl;
++	s8 idle_targ_5gh;
++	s8 idle_tssi_2g;
++	s8 idle_tssi_5g;
++	s8 idle_tssi;
++	s16 a1;
++	s16 b0;
++	s16 b1;
++};
++
++struct nphy_txgains {
++	u16 txlpf[2];
++	u16 txgm[2];
++	u16 pga[2];
++	u16 pad[2];
++	u16 ipa[2];
++};
++
++#define PHY_NOISEVAR_BUFSIZE 10
++
++struct nphy_noisevar_buf {
++	int bufcount;
++	int tone_id[PHY_NOISEVAR_BUFSIZE];
++	u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
++	u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
++};
++
++struct rssical_cache {
++	u16 rssical_radio_regs_2G[2];
++	u16 rssical_phyregs_2G[12];
++
++	u16 rssical_radio_regs_5G[2];
++	u16 rssical_phyregs_5G[12];
++};
++
++struct lcnphy_cal_results {
++
++	u16 txiqlocal_a;
++	u16 txiqlocal_b;
++	u16 txiqlocal_didq;
++	u8 txiqlocal_ei0;
++	u8 txiqlocal_eq0;
++	u8 txiqlocal_fi0;
++	u8 txiqlocal_fq0;
++
++	u16 txiqlocal_bestcoeffs[11];
++	u16 txiqlocal_bestcoeffs_valid;
++
++	u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
++	u16 analog_gain_ref;
++	u16 lut_begin;
++	u16 lut_end;
++	u16 lut_step;
++	u16 rxcompdbm;
++	u16 papdctrl;
++	u16 sslpnCalibClkEnCtrl;
++
++	u16 rxiqcal_coeff_a0;
++	u16 rxiqcal_coeff_b0;
++};
++
++struct shared_phy {
++	struct brcms_phy *phy_head;
++	uint unit;
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint corerev;
++	u32 machwcap;
++	bool up;
++	bool clk;
++	uint now;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++	uint fast_timer;
++	uint slow_timer;
++	uint glacial_timer;
++	u8 rx_antdiv;
++	s8 phy_noise_window[MA_WINDOW_SZ];
++	uint phy_noise_index;
++	u8 hw_phytxchain;
++	u8 hw_phyrxchain;
++	u8 phytxchain;
++	u8 phyrxchain;
++	u8 rssi_mode;
++	bool _rifs_phy;
++};
++
++struct brcms_phy_pub {
++	uint phy_type;
++	uint phy_rev;
++	u8 phy_corenum;
++	u16 radioid;
++	u8 radiorev;
++	u8 radiover;
++
++	uint coreflags;
++	uint ana_rev;
++	bool abgphy_encore;
++};
++
++struct phy_func_ptr {
++	void (*init)(struct brcms_phy *);
++	void (*calinit)(struct brcms_phy *);
++	void (*chanset)(struct brcms_phy *, u16 chanspec);
++	void (*txpwrrecalc)(struct brcms_phy *);
++	int (*longtrn)(struct brcms_phy *, int);
++	void (*txiqccget)(struct brcms_phy *, u16 *, u16 *);
++	void (*txiqccset)(struct brcms_phy *, u16, u16);
++	u16 (*txloccget)(struct brcms_phy *);
++	void (*radioloftget)(struct brcms_phy *, u8 *, u8 *, u8 *, u8 *);
++	void (*carrsuppr)(struct brcms_phy *);
++	s32 (*rxsigpwr)(struct brcms_phy *, s32);
++	void (*detach)(struct brcms_phy *);
++};
++
++struct brcms_phy {
++	struct brcms_phy_pub pubpi_ro;
++	struct shared_phy *sh;
++	struct phy_func_ptr pi_fptr;
++
++	union {
++		struct brcms_phy_lcnphy *pi_lcnphy;
++	} u;
++	bool user_txpwr_at_rfport;
++
++	struct bcma_device *d11core;
++	struct brcms_phy *next;
++	struct brcms_phy_pub pubpi;
++
++	bool do_initcal;
++	bool phytest_on;
++	bool ofdm_rateset_war;
++	bool bf_preempt_4306;
++	u16 radio_chanspec;
++	u8 antsel_type;
++	u16 bw;
++	u8 txpwr_percent;
++	bool phy_init_por;
++
++	bool init_in_progress;
++	bool initialized;
++	bool sbtml_gm;
++	uint refcnt;
++	bool watchdog_override;
++	u8 phynoise_state;
++	uint phynoise_now;
++	int phynoise_chan_watchdog;
++	bool phynoise_polling;
++	bool disable_percal;
++	u32 measure_hold;
++
++	s16 txpa_2g[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_low[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
++
++	u8 tx_srom_max_2g;
++	u8 tx_srom_max_5g_low;
++	u8 tx_srom_max_5g_mid;
++	u8 tx_srom_max_5g_hi;
++	u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
++	u8 tx_user_target[TXP_NUM_RATES];
++	s8 tx_power_offset[TXP_NUM_RATES];
++	u8 tx_power_target[TXP_NUM_RATES];
++
++	struct brcms_phy_srom_fem srom_fem2g;
++	struct brcms_phy_srom_fem srom_fem5g;
++
++	u8 tx_power_max;
++	u8 tx_power_max_rate_ind;
++	bool hwpwrctrl;
++	u8 nphy_txpwrctrl;
++	s8 nphy_txrx_chain;
++	bool phy_5g_pwrgain;
++
++	u16 phy_wreg;
++	u16 phy_wreg_limit;
++
++	s8 n_preamble_override;
++	u8 antswitch;
++	u8 aa2g, aa5g;
++
++	s8 idle_tssi[CH_5G_GROUP];
++	s8 target_idle_tssi;
++	s8 txpwr_est_Pout;
++	u8 tx_power_min;
++	u8 txpwr_limit[TXP_NUM_RATES];
++	u8 txpwr_env_limit[TXP_NUM_RATES];
++	u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
++
++	bool channel_14_wide_filter;
++
++	bool txpwroverride;
++	bool txpwridx_override_aphy;
++	s16 radiopwr_override;
++	u16 hwpwr_txcur;
++	u8 saved_txpwr_idx;
++
++	bool edcrs_threshold_lock;
++
++	u32 tr_R_gain_val;
++	u32 tr_T_gain_val;
++
++	s16 ofdm_analog_filt_bw_override;
++	s16 cck_analog_filt_bw_override;
++	s16 ofdm_rccal_override;
++	s16 cck_rccal_override;
++	u16 extlna_type;
++
++	uint interference_mode_crs_time;
++	u16 crsglitch_prev;
++	bool interference_mode_crs;
++
++	u32 phy_tx_tone_freq;
++	uint phy_lastcal;
++	bool phy_forcecal;
++	bool phy_fixed_noise;
++	u32 xtalfreq;
++	u8 pdiv;
++	s8 carrier_suppr_disable;
++
++	bool phy_bphy_evm;
++	bool phy_bphy_rfcs;
++	s8 phy_scraminit;
++	u8 phy_gpiosel;
++
++	s16 phy_txcore_disable_temp;
++	s16 phy_txcore_enable_temp;
++	s8 phy_tempsense_offset;
++	bool phy_txcore_heatedup;
++
++	u16 radiopwr;
++	u16 bb_atten;
++	u16 txctl1;
++
++	u16 mintxbias;
++	u16 mintxmag;
++	struct lo_complex_abgphy_info gphy_locomp_iq
++			[STATIC_NUM_RF][STATIC_NUM_BB];
++	s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
++	u16 gain_table[TX_GAIN_TABLE_LENGTH];
++	bool loopback_gain;
++	s16 max_lpback_gain_hdB;
++	s16 trsw_rx_gain_hdB;
++	u8 power_vec[8];
++
++	u16 rc_cal;
++	int nrssi_table_delta;
++	int nrssi_slope_scale;
++	int nrssi_slope_offset;
++	int min_rssi;
++	int max_rssi;
++
++	s8 txpwridx;
++	u8 min_txpower;
++
++	u8 a_band_high_disable;
++
++	u16 tx_vos;
++	u16 global_tx_bb_dc_bias_loft;
++
++	int rf_max;
++	int bb_max;
++	int rf_list_size;
++	int bb_list_size;
++	u16 *rf_attn_list;
++	u16 *bb_attn_list;
++	u16 padmix_mask;
++	u16 padmix_reg;
++	u16 *txmag_list;
++	uint txmag_len;
++	bool txmag_enable;
++
++	s8 *a_tssi_to_dbm;
++	s8 *m_tssi_to_dbm;
++	s8 *l_tssi_to_dbm;
++	s8 *h_tssi_to_dbm;
++	u8 *hwtxpwr;
++
++	u16 freqtrack_saved_regs[2];
++	int cur_interference_mode;
++	bool hwpwrctrl_capable;
++	bool temppwrctrl_capable;
++
++	uint phycal_nslope;
++	uint phycal_noffset;
++	uint phycal_mlo;
++	uint phycal_txpower;
++
++	u8 phy_aa2g;
++
++	bool nphy_tableloaded;
++	s8 nphy_rssisel;
++	u32 nphy_bb_mult_save;
++	u16 nphy_txiqlocal_bestc[11];
++	bool nphy_txiqlocal_coeffsvalid;
++	struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
++	struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
++	u16 cck2gpo;
++	u32 ofdm2gpo;
++	u32 ofdm5gpo;
++	u32 ofdm5glpo;
++	u32 ofdm5ghpo;
++	u8 bw402gpo;
++	u8 bw405gpo;
++	u8 bw405glpo;
++	u8 bw405ghpo;
++	u8 cdd2gpo;
++	u8 cdd5gpo;
++	u8 cdd5glpo;
++	u8 cdd5ghpo;
++	u8 stbc2gpo;
++	u8 stbc5gpo;
++	u8 stbc5glpo;
++	u8 stbc5ghpo;
++	u8 bwdup2gpo;
++	u8 bwdup5gpo;
++	u8 bwdup5glpo;
++	u8 bwdup5ghpo;
++	u16 mcs2gpo[8];
++	u16 mcs5gpo[8];
++	u16 mcs5glpo[8];
++	u16 mcs5ghpo[8];
++	u32 nphy_rxcalparams;
++
++	u8 phy_spuravoid;
++	bool phy_isspuravoid;
++
++	u8 phy_pabias;
++	u8 nphy_papd_skip;
++	u8 nphy_tssi_slope;
++
++	s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
++	u8 nphy_noise_index;
++
++	bool nphy_gain_boost;
++	bool nphy_elna_gain_config;
++	u16 old_bphy_test;
++	u16 old_bphy_testcontrol;
++
++	bool phyhang_avoid;
++
++	bool rssical_nphy;
++	u8 nphy_perical;
++	uint nphy_perical_last;
++	u8 cal_type_override;
++	u8 mphase_cal_phase_id;
++	u8 mphase_txcal_cmdidx;
++	u8 mphase_txcal_numcmds;
++	u16 mphase_txcal_bestcoeffs[11];
++	u16 nphy_txiqlocal_chanspec;
++	u16 nphy_iqcal_chanspec_2G;
++	u16 nphy_iqcal_chanspec_5G;
++	u16 nphy_rssical_chanspec_2G;
++	u16 nphy_rssical_chanspec_5G;
++	struct wlapi_timer *phycal_timer;
++	bool use_int_tx_iqlo_cal_nphy;
++	bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
++	s16 nphy_lastcal_temp;
++
++	struct txiqcal_cache calibration_cache;
++	struct rssical_cache rssical_cache;
++
++	u8 nphy_txpwr_idx[2];
++	u8 nphy_papd_cal_type;
++	uint nphy_papd_last_cal;
++	u16 nphy_papd_tx_gain_at_last_cal[2];
++	u8 nphy_papd_cal_gain_index[2];
++	s16 nphy_papd_epsilon_offset[2];
++	bool nphy_papd_recal_enable;
++	u32 nphy_papd_recal_counter;
++	bool nphy_force_papd_cal;
++	bool nphy_papdcomp;
++	bool ipa2g_on;
++	bool ipa5g_on;
++
++	u16 classifier_state;
++	u16 clip_state[2];
++	uint nphy_deaf_count;
++	u8 rxiq_samps;
++	u8 rxiq_antsel;
++
++	u16 rfctrlIntc1_save;
++	u16 rfctrlIntc2_save;
++	bool first_cal_after_assoc;
++	u16 tx_rx_cal_radio_saveregs[22];
++	u16 tx_rx_cal_phy_saveregs[15];
++
++	u8 nphy_cal_orig_pwr_idx[2];
++	u8 nphy_txcal_pwr_idx[2];
++	u8 nphy_rxcal_pwr_idx[2];
++	u16 nphy_cal_orig_tx_gain[2];
++	struct nphy_txgains nphy_cal_target_gain;
++	u16 nphy_txcal_bbmult;
++	u16 nphy_gmval;
++
++	u16 nphy_saved_bbconf;
++
++	bool nphy_gband_spurwar_en;
++	bool nphy_gband_spurwar2_en;
++	bool nphy_aband_spurwar_en;
++	u16 nphy_rccal_value;
++	u16 nphy_crsminpwr[3];
++	struct nphy_noisevar_buf nphy_saved_noisevars;
++	bool nphy_anarxlpf_adjusted;
++	bool nphy_crsminpwr_adjusted;
++	bool nphy_noisevars_adjusted;
++
++	bool nphy_rxcal_active;
++	u16 radar_percal_mask;
++	bool dfs_lp_buffer_nphy;
++
++	u16 nphy_fineclockgatecontrol;
++
++	s8 rx2tx_biasentry;
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++	s16 noise_crsminpwr_index;
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u8 aci_noise_curr_channel;
++	u16 init_gain_rfseq[4];
++
++	bool radio_is_on;
++
++	bool nphy_sample_play_lpf_bw_ctl_ovr;
++
++	u16 tbl_data_hi;
++	u16 tbl_data_lo;
++	u16 tbl_addr;
++
++	uint tbl_save_id;
++	uint tbl_save_offset;
++
++	u8 txpwrctrl;
++	s8 txpwrindex[PHY_CORE_MAX];
++
++	u8 phycal_tempdelta;
++	u32 mcs20_po;
++	u32 mcs40_po;
++	struct wiphy *wiphy;
++};
++
++struct cs32 {
++	s32 q;
++	s32 i;
++};
++
++struct radio_regs {
++	u16 address;
++	u32 init_a;
++	u32 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++struct radio_20xx_regs {
++	u16 address;
++	u8 init;
++	u8 do_init;
++};
++
++struct lcnphy_radio_regs {
++	u16 address;
++	u8 init_a;
++	u8 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
++extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
++
++extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
++extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
++			  u16 val);
++extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
++
++extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++
++extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_read_table(struct brcms_phy *pi,
++			       const struct phytbl_info *ptbl_info,
++			       u16 tblAddr, u16 tblDataHi,
++			       u16 tblDatalo);
++extern void wlc_phy_write_table(struct brcms_phy *pi,
++				const struct phytbl_info *ptbl_info,
++				u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
++extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
++			       uint tbl_offset, u16 tblAddr, u16 tblDataHi,
++			       u16 tblDataLo);
++extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
++
++extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
++extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
++
++extern u8 wlc_phy_nbits(s32 value);
++extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
++
++extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++					     struct radio_20xx_regs *radioregs);
++extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
++				    const struct radio_regs *radioregs,
++				    u16 core_offset);
++
++extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
++
++extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
++extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
++					s32 *eps_imag);
++
++extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
++extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
++
++extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
++extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
++				      u16 chanspec);
++extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
++					u16 chanspec);
++extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
++					      u16 chanspec);
++extern int wlc_phy_channel2freq(uint channel);
++extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
++extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec);
++
++extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
++extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
++extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
++extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
++extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
++extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
++				     u16 max_val, bool iqcalmode);
++
++extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
++					       u8 *max_pwr, u8 rate_id);
++extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++					    u8 rate_mcs_end,
++					    u8 rate_ofdm_start);
++extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
++					    u8 rate_ofdm_start,
++					    u8 rate_ofdm_end,
++					    u8 rate_mcs_start);
++
++extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
++extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
++extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
++extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
++extern void wlc_2064_vco_cal(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
++
++#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
++#define LCNPHY_TX_POWER_TABLE_SIZE	128
++#define LCNPHY_MAX_TX_POWER_INDEX	(LCNPHY_TX_POWER_TABLE_SIZE - 1)
++#define LCNPHY_TBL_ID_TXPWRCTL	0x07
++#define LCNPHY_TX_PWR_CTRL_OFF	0
++#define LCNPHY_TX_PWR_CTRL_SW		(0x1 << 15)
++#define LCNPHY_TX_PWR_CTRL_HW         ((0x1 << 15) | \
++					(0x1 << 14) | \
++					(0x1 << 13))
++
++#define LCNPHY_TX_PWR_CTRL_TEMPBASED	0xE001
++
++extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
++				   const struct phytbl_info *pti);
++extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
++				  struct phytbl_info *pti);
++extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
++extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
++extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
++extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
++extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
++				      u8 *eq0, u8 *fi0, u8 *fq0);
++extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
++extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
++extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
++extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
++extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
++				s8 *cck_pwr);
++extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
++
++extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
++
++#define NPHY_MAX_HPVGA1_INDEX		10
++#define NPHY_DEF_HPVGA1_INDEXLIMIT	7
++
++struct phy_iq_est {
++	s32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
++					       bool enable);
++extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
++
++#define wlc_phy_write_table_nphy(pi, pti) \
++	wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_phy_read_table_nphy(pi, pti) \
++	wlc_phy_read_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_addr(pi, id, off) \
++	wlc_phy_table_addr((pi), (id), (off), 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_data_write(pi, w, v) \
++	wlc_phy_table_data_write((pi), (w), (v))
++
++extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
++				    u32 w, void *d);
++extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
++				     u32, const void *);
++
++#define	PHY_IPA(pi) \
++	((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
++	 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
++
++#define BRCMS_PHY_WAR_PR51571(pi) \
++	if (NREV_LT((pi)->pubpi.phy_rev, 3)) \
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol))
++
++extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
++extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
++extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
++
++extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
++extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
++
++extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
++extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
++
++extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
++
++extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++				   u16 num_samps, u8 wait_time,
++				   u8 wait_for_crs);
++
++extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++				      struct nphy_iq_comp *comp);
++extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
++					 u8 rxcore_bitmask);
++extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
++extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
++extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
++
++extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
++extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
++				   struct nphy_txgains target_gain,
++				   bool full, bool m);
++extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
++				 struct nphy_txgains target_gain,
++				 u8 type, bool d);
++extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
++				     s8 txpwrindex, bool res);
++extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
++extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
++				  s32 *rssi_buf, u8 nsamps);
++extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
++extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
++					s32 dBm_targetpower, bool debug);
++extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++				u8 mode, u8, bool);
++extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
++extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
++				     u8 num_samps);
++extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
++
++extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
++				     struct d11rxhdr *rxh);
++
++#define NPHY_TESTPATTERN_BPHY_EVM   0
++#define NPHY_TESTPATTERN_BPHY_RFCS  1
++
++extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
++
++void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
++				s8 *ofdmoffset);
++extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
++				  u16 chanspec);
++
++extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
++#endif				/* _BRCM_PHY_INT_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+new file mode 100644
+index 0000000..abfd788
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+@@ -0,0 +1,5137 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_qmath.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phytbl_lcn.h"
++#include "phy_lcn.h"
++
++#define PLL_2064_NDIV		90
++#define PLL_2064_LOW_END_VCO	3000
++#define PLL_2064_LOW_END_KVCO	27
++#define PLL_2064_HIGH_END_VCO	4200
++#define PLL_2064_HIGH_END_KVCO	68
++#define PLL_2064_LOOP_BW_DOUBLER	200
++#define PLL_2064_D30_DOUBLER		10500
++#define PLL_2064_LOOP_BW	260
++#define PLL_2064_D30		8000
++#define PLL_2064_CAL_REF_TO	8
++#define PLL_2064_MHZ		1000000
++#define PLL_2064_OPEN_LOOP_DELAY	5
++
++#define TEMPSENSE			1
++#define VBATSENSE           2
++
++#define NOISE_IF_UPD_CHK_INTERVAL	1
++#define NOISE_IF_UPD_RST_INTERVAL	60
++#define NOISE_IF_UPD_THRESHOLD_CNT	1
++#define NOISE_IF_UPD_TRHRESHOLD	50
++#define NOISE_IF_UPD_TIMEOUT		1000
++#define NOISE_IF_OFF			0
++#define NOISE_IF_CHK			1
++#define NOISE_IF_ON			2
++
++#define PAPD_BLANKING_PROFILE		3
++#define PAPD2LUT			0
++#define PAPD_CORR_NORM			0
++#define PAPD_BLANKING_THRESHOLD		0
++#define PAPD_STOP_AFTER_LAST_UPDATE	0
++
++#define LCN_TARGET_PWR  60
++
++#define LCN_VBAT_OFFSET_433X 34649679
++#define LCN_VBAT_SLOPE_433X  8258032
++
++#define LCN_VBAT_SCALE_NOM  53
++#define LCN_VBAT_SCALE_DEN  432
++
++#define LCN_TEMPSENSE_OFFSET  80812
++#define LCN_TEMPSENSE_DEN  2647
++
++#define LCN_BW_LMT	200
++#define LCN_CUR_LMT	1250
++#define LCN_MULT	1
++#define LCN_VCO_DIV	30
++#define LCN_OFFSET	680
++#define LCN_FACT	490
++#define LCN_CUR_DIV	2640
++
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define wlc_lcnphy_enable_tx_gain_override(pi) \
++	wlc_lcnphy_set_tx_gain_override(pi, true)
++#define wlc_lcnphy_disable_tx_gain_override(pi)	\
++	wlc_lcnphy_set_tx_gain_override(pi, false)
++
++#define wlc_lcnphy_iqcal_active(pi)	\
++	(read_phy_reg((pi), 0x451) & \
++	 ((0x1 << 15) | (0x1 << 14)))
++
++#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
++#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)	\
++	(pi->temppwrctrl_capable)
++#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
++	(pi->hwpwrctrl_capable)
++
++#define SWCTRL_BT_TX		0x18
++#define SWCTRL_OVR_DISABLE	0x40
++
++#define	AFE_CLK_INIT_MODE_TXRX2X	1
++#define	AFE_CLK_INIT_MODE_PAPD		0
++
++#define LCNPHY_TBL_ID_IQLOCAL			0x00
++
++#define LCNPHY_TBL_ID_RFSEQ         0x08
++#define LCNPHY_TBL_ID_GAIN_IDX		0x0d
++#define LCNPHY_TBL_ID_SW_CTRL			0x0f
++#define LCNPHY_TBL_ID_GAIN_TBL		0x12
++#define LCNPHY_TBL_ID_SPUR			0x14
++#define LCNPHY_TBL_ID_SAMPLEPLAY		0x15
++#define LCNPHY_TBL_ID_SAMPLEPLAY1		0x16
++
++#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET	832
++#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET	128
++#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET	192
++#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET		320
++#define LCNPHY_TX_PWR_CTRL_LO_OFFSET		448
++#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET		576
++
++#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313	140
++
++#define LCNPHY_TX_PWR_CTRL_START_NPT		1
++#define LCNPHY_TX_PWR_CTRL_MAX_NPT			7
++
++#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
++
++#define LCNPHY_ACI_DETECT_START      1
++#define LCNPHY_ACI_DETECT_PROGRESS   2
++#define LCNPHY_ACI_DETECT_STOP       3
++
++#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
++#define LCNPHY_ACI_GLITCH_TRSH 2000
++#define	LCNPHY_ACI_TMOUT 250
++#define LCNPHY_ACI_DETECT_TIMEOUT  2
++#define LCNPHY_ACI_START_DELAY 0
++
++#define wlc_lcnphy_tx_gain_override_enabled(pi)	\
++	(0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
++
++#define wlc_lcnphy_total_tx_frames(pi) \
++	wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + \
++			    offsetof(struct macstat, txallfrm))
++
++struct lcnphy_txgains {
++	u16 gm_gain;
++	u16 pga_gain;
++	u16 pad_gain;
++	u16 dac_gain;
++};
++
++enum lcnphy_cal_mode {
++	LCNPHY_CAL_FULL,
++	LCNPHY_CAL_RECAL,
++	LCNPHY_CAL_CURRECAL,
++	LCNPHY_CAL_DIGCAL,
++	LCNPHY_CAL_GCTRL
++};
++
++struct lcnphy_rx_iqcomp {
++	u8 chan;
++	s16 a;
++	s16 b;
++};
++
++struct lcnphy_spb_tone {
++	s16 re;
++	s16 im;
++};
++
++struct lcnphy_unsign16_struct {
++	u16 re;
++	u16 im;
++};
++
++struct lcnphy_iq_est {
++	u32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++struct lcnphy_sfo_cfg {
++	u16 ptcentreTs20;
++	u16 ptcentreFactor;
++};
++
++enum lcnphy_papd_cal_type {
++	LCNPHY_PAPD_CAL_CW,
++	LCNPHY_PAPD_CAL_OFDM
++};
++
++typedef u16 iqcal_gain_params_lcnphy[9];
++
++static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
++	{0, 0, 0, 0, 0, 0, 0, 0, 0},
++};
++
++static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
++	tbl_iqcal_gainparams_lcnphy_2G,
++};
++
++static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
++	ARRAY_SIZE(tbl_iqcal_gainparams_lcnphy_2G),
++};
++
++static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
++	{965, 1087},
++	{967, 1085},
++	{969, 1082},
++	{971, 1080},
++	{973, 1078},
++	{975, 1076},
++	{977, 1073},
++	{979, 1071},
++	{981, 1069},
++	{983, 1067},
++	{985, 1065},
++	{987, 1063},
++	{989, 1060},
++	{994, 1055}
++};
++
++static const
++u16 lcnphy_iqcal_loft_gainladder[] = {
++	((2 << 8) | 0),
++	((3 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((16 << 8) | 1),
++	((16 << 8) | 2),
++	((16 << 8) | 3),
++	((16 << 8) | 4),
++	((16 << 8) | 5),
++	((16 << 8) | 6),
++	((16 << 8) | 7),
++	((23 << 8) | 7),
++	((32 << 8) | 7),
++	((45 << 8) | 7),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++u16 lcnphy_iqcal_ir_gainladder[] = {
++	((1 << 8) | 0),
++	((2 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((23 << 8) | 0),
++	((32 << 8) | 0),
++	((45 << 8) | 0),
++	((64 << 8) | 0),
++	((64 << 8) | 1),
++	((64 << 8) | 2),
++	((64 << 8) | 3),
++	((64 << 8) | 4),
++	((64 << 8) | 5),
++	((64 << 8) | 6),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = {
++	{88, 0},
++	{73, 49},
++	{34, 81},
++	{-17, 86},
++	{-62, 62},
++	{-86, 17},
++	{-81, -34},
++	{-49, -73},
++	{0, -88},
++	{49, -73},
++	{81, -34},
++	{86, 17},
++	{62, 62},
++	{17, 86},
++	{-34, 81},
++	{-73, 49},
++	{-88, 0},
++	{-73, -49},
++	{-34, -81},
++	{17, -86},
++	{62, -62},
++	{86, -17},
++	{81, 34},
++	{49, 73},
++	{0, 88},
++	{-49, 73},
++	{-81, 34},
++	{-86, -17},
++	{-62, -62},
++	{-17, -86},
++	{34, -81},
++	{73, -49},
++};
++
++static const
++u16 iqlo_loopback_rf_regs[20] = {
++	RADIO_2064_REG036,
++	RADIO_2064_REG11A,
++	RADIO_2064_REG03A,
++	RADIO_2064_REG025,
++	RADIO_2064_REG028,
++	RADIO_2064_REG005,
++	RADIO_2064_REG112,
++	RADIO_2064_REG0FF,
++	RADIO_2064_REG11F,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG007,
++	RADIO_2064_REG0FC,
++	RADIO_2064_REG0FD,
++	RADIO_2064_REG012,
++	RADIO_2064_REG057,
++	RADIO_2064_REG059,
++	RADIO_2064_REG05C,
++	RADIO_2064_REG078,
++	RADIO_2064_REG092,
++};
++
++static const
++u16 tempsense_phy_regs[14] = {
++	0x503,
++	0x4a4,
++	0x4d0,
++	0x4d9,
++	0x4da,
++	0x4a6,
++	0x938,
++	0x939,
++	0x4d8,
++	0x4d0,
++	0x4d7,
++	0x4a5,
++	0x40d,
++	0x4a2,
++};
++
++static const
++u16 rxiq_cal_rf_reg[11] = {
++	RADIO_2064_REG098,
++	RADIO_2064_REG116,
++	RADIO_2064_REG12C,
++	RADIO_2064_REG06A,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG01B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG01D,
++	RADIO_2064_REG114,
++	RADIO_2064_REG02E,
++	RADIO_2064_REG12A,
++};
++
++static const
++struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = {
++	{1, 0, 0},
++	{2, 0, 0},
++	{3, 0, 0},
++	{4, 0, 0},
++	{5, 0, 0},
++	{6, 0, 0},
++	{7, 0, 0},
++	{8, 0, 0},
++	{9, 0, 0},
++	{10, 0, 0},
++	{11, 0, 0},
++	{12, 0, 0},
++	{13, 0, 0},
++	{14, 0, 0},
++	{34, 0, 0},
++	{38, 0, 0},
++	{42, 0, 0},
++	{46, 0, 0},
++	{36, 0, 0},
++	{40, 0, 0},
++	{44, 0, 0},
++	{48, 0, 0},
++	{52, 0, 0},
++	{56, 0, 0},
++	{60, 0, 0},
++	{64, 0, 0},
++	{100, 0, 0},
++	{104, 0, 0},
++	{108, 0, 0},
++	{112, 0, 0},
++	{116, 0, 0},
++	{120, 0, 0},
++	{124, 0, 0},
++	{128, 0, 0},
++	{132, 0, 0},
++	{136, 0, 0},
++	{140, 0, 0},
++	{149, 0, 0},
++	{153, 0, 0},
++	{157, 0, 0},
++	{161, 0, 0},
++	{165, 0, 0},
++	{184, 0, 0},
++	{188, 0, 0},
++	{192, 0, 0},
++	{196, 0, 0},
++	{200, 0, 0},
++	{204, 0, 0},
++	{208, 0, 0},
++	{212, 0, 0},
++	{216, 0, 0},
++};
++
++static const u32 lcnphy_23bitgaincode_table[] = {
++	0x200100,
++	0x200200,
++	0x200004,
++	0x200014,
++	0x200024,
++	0x200034,
++	0x200134,
++	0x200234,
++	0x200334,
++	0x200434,
++	0x200037,
++	0x200137,
++	0x200237,
++	0x200337,
++	0x200437,
++	0x000035,
++	0x000135,
++	0x000235,
++	0x000037,
++	0x000137,
++	0x000237,
++	0x000337,
++	0x00013f,
++	0x00023f,
++	0x00033f,
++	0x00034f,
++	0x00044f,
++	0x00144f,
++	0x00244f,
++	0x00254f,
++	0x00354f,
++	0x00454f,
++	0x00464f,
++	0x01464f,
++	0x02464f,
++	0x03464f,
++	0x04464f,
++};
++
++static const s8 lcnphy_gain_table[] = {
++	-16,
++	-13,
++	10,
++	7,
++	4,
++	0,
++	3,
++	6,
++	9,
++	12,
++	15,
++	18,
++	21,
++	24,
++	27,
++	30,
++	33,
++	36,
++	39,
++	42,
++	45,
++	48,
++	50,
++	53,
++	56,
++	59,
++	62,
++	65,
++	68,
++	71,
++	74,
++	77,
++	80,
++	83,
++	86,
++	89,
++	92,
++};
++
++static const s8 lcnphy_gain_index_offset_for_rssi[] = {
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	8,
++	7,
++	7,
++	6,
++	7,
++	7,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	4,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	-1,
++	-2,
++	-2,
++	-2
++};
++
++struct chan_info_2064_lcnphy {
++	uint chan;
++	uint freq;
++	u8 logen_buftune;
++	u8 logen_rccr_tx;
++	u8 txrf_mix_tune_ctrl;
++	u8 pa_input_tune_g;
++	u8 logen_rccr_rx;
++	u8 pa_rxrf_lna1_freq_tune;
++	u8 pa_rxrf_lna2_freq_tune;
++	u8 rxrf_rxrf_spare1;
++};
++
++static const struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = {
++	{1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++};
++
++static const struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = {
++	{0x00, 0, 0, 0, 0},
++	{0x01, 0x64, 0x64, 0, 0},
++	{0x02, 0x20, 0x20, 0, 0},
++	{0x03, 0x66, 0x66, 0, 0},
++	{0x04, 0xf8, 0xf8, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x10, 0x10, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0x37, 0x37, 0, 0},
++	{0x0B, 0x6, 0x6, 0, 0},
++	{0x0C, 0x55, 0x55, 0, 0},
++	{0x0D, 0x8b, 0x8b, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0x5, 0x5, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0xe, 0xe, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0xb, 0xb, 0, 0},
++	{0x14, 0x2, 0x2, 0, 0},
++	{0x15, 0x12, 0x12, 0, 0},
++	{0x16, 0x12, 0x12, 0, 0},
++	{0x17, 0xc, 0xc, 0, 0},
++	{0x18, 0xc, 0xc, 0, 0},
++	{0x19, 0xc, 0xc, 0, 0},
++	{0x1A, 0x8, 0x8, 0, 0},
++	{0x1B, 0x2, 0x2, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0x1, 0x1, 0, 0},
++	{0x1E, 0x12, 0x12, 0, 0},
++	{0x1F, 0x6e, 0x6e, 0, 0},
++	{0x20, 0x2, 0x2, 0, 0},
++	{0x21, 0x23, 0x23, 0, 0},
++	{0x22, 0x8, 0x8, 0, 0},
++	{0x23, 0, 0, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0x33, 0x33, 0, 0},
++	{0x27, 0x55, 0x55, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x30, 0x30, 0, 0},
++	{0x2A, 0xb, 0xb, 0, 0},
++	{0x2B, 0x1b, 0x1b, 0, 0},
++	{0x2C, 0x3, 0x3, 0, 0},
++	{0x2D, 0x1b, 0x1b, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x20, 0x20, 0, 0},
++	{0x30, 0xa, 0xa, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0x62, 0x62, 0, 0},
++	{0x33, 0x19, 0x19, 0, 0},
++	{0x34, 0x33, 0x33, 0, 0},
++	{0x35, 0x77, 0x77, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x70, 0x70, 0, 0},
++	{0x38, 0x3, 0x3, 0, 0},
++	{0x39, 0xf, 0xf, 0, 0},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0xcf, 0xcf, 0, 0},
++	{0x3C, 0x1a, 0x1a, 0, 0},
++	{0x3D, 0x6, 0x6, 0, 0},
++	{0x3E, 0x42, 0x42, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0xfb, 0xfb, 0, 0},
++	{0x41, 0x9a, 0x9a, 0, 0},
++	{0x42, 0x7a, 0x7a, 0, 0},
++	{0x43, 0x29, 0x29, 0, 0},
++	{0x44, 0, 0, 0, 0},
++	{0x45, 0x8, 0x8, 0, 0},
++	{0x46, 0xce, 0xce, 0, 0},
++	{0x47, 0x27, 0x27, 0, 0},
++	{0x48, 0x62, 0x62, 0, 0},
++	{0x49, 0x6, 0x6, 0, 0},
++	{0x4A, 0x58, 0x58, 0, 0},
++	{0x4B, 0xf7, 0xf7, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0xb3, 0xb3, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0, 0, 0, 0},
++	{0x51, 0x9, 0x9, 0, 0},
++	{0x52, 0x5, 0x5, 0, 0},
++	{0x53, 0x17, 0x17, 0, 0},
++	{0x54, 0x38, 0x38, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0xb, 0xb, 0, 0},
++	{0x58, 0, 0, 0, 0},
++	{0x59, 0, 0, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0, 0, 0, 0},
++	{0x5C, 0, 0, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x88, 0x88, 0, 0},
++	{0x5F, 0xcc, 0xcc, 0, 0},
++	{0x60, 0x74, 0x74, 0, 0},
++	{0x61, 0x74, 0x74, 0, 0},
++	{0x62, 0x74, 0x74, 0, 0},
++	{0x63, 0x44, 0x44, 0, 0},
++	{0x64, 0x77, 0x77, 0, 0},
++	{0x65, 0x44, 0x44, 0, 0},
++	{0x66, 0x77, 0x77, 0, 0},
++	{0x67, 0x55, 0x55, 0, 0},
++	{0x68, 0x77, 0x77, 0, 0},
++	{0x69, 0x77, 0x77, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0x7f, 0x7f, 0, 0},
++	{0x6C, 0x8, 0x8, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0x88, 0x88, 0, 0},
++	{0x6F, 0x66, 0x66, 0, 0},
++	{0x70, 0x66, 0x66, 0, 0},
++	{0x71, 0x28, 0x28, 0, 0},
++	{0x72, 0x55, 0x55, 0, 0},
++	{0x73, 0x4, 0x4, 0, 0},
++	{0x74, 0, 0, 0, 0},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0, 0, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0xd6, 0xd6, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0xb4, 0xb4, 0, 0},
++	{0x84, 0x1, 0x1, 0, 0},
++	{0x85, 0x20, 0x20, 0, 0},
++	{0x86, 0x5, 0x5, 0, 0},
++	{0x87, 0xff, 0xff, 0, 0},
++	{0x88, 0x7, 0x7, 0, 0},
++	{0x89, 0x77, 0x77, 0, 0},
++	{0x8A, 0x77, 0x77, 0, 0},
++	{0x8B, 0x77, 0x77, 0, 0},
++	{0x8C, 0x77, 0x77, 0, 0},
++	{0x8D, 0x8, 0x8, 0, 0},
++	{0x8E, 0xa, 0xa, 0, 0},
++	{0x8F, 0x8, 0x8, 0, 0},
++	{0x90, 0x18, 0x18, 0, 0},
++	{0x91, 0x5, 0x5, 0, 0},
++	{0x92, 0x1f, 0x1f, 0, 0},
++	{0x93, 0x10, 0x10, 0, 0},
++	{0x94, 0x3, 0x3, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0xaa, 0xaa, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0x23, 0x23, 0, 0},
++	{0x9A, 0x7, 0x7, 0, 0},
++	{0x9B, 0xf, 0xf, 0, 0},
++	{0x9C, 0x10, 0x10, 0, 0},
++	{0x9D, 0x3, 0x3, 0, 0},
++	{0x9E, 0x4, 0x4, 0, 0},
++	{0x9F, 0x20, 0x20, 0, 0},
++	{0xA0, 0, 0, 0, 0},
++	{0xA1, 0, 0, 0, 0},
++	{0xA2, 0, 0, 0, 0},
++	{0xA3, 0, 0, 0, 0},
++	{0xA4, 0x1, 0x1, 0, 0},
++	{0xA5, 0x77, 0x77, 0, 0},
++	{0xA6, 0x77, 0x77, 0, 0},
++	{0xA7, 0x77, 0x77, 0, 0},
++	{0xA8, 0x77, 0x77, 0, 0},
++	{0xA9, 0x8c, 0x8c, 0, 0},
++	{0xAA, 0x88, 0x88, 0, 0},
++	{0xAB, 0x78, 0x78, 0, 0},
++	{0xAC, 0x57, 0x57, 0, 0},
++	{0xAD, 0x88, 0x88, 0, 0},
++	{0xAE, 0, 0, 0, 0},
++	{0xAF, 0x8, 0x8, 0, 0},
++	{0xB0, 0x88, 0x88, 0, 0},
++	{0xB1, 0, 0, 0, 0},
++	{0xB2, 0x1b, 0x1b, 0, 0},
++	{0xB3, 0x3, 0x3, 0, 0},
++	{0xB4, 0x24, 0x24, 0, 0},
++	{0xB5, 0x3, 0x3, 0, 0},
++	{0xB6, 0x1b, 0x1b, 0, 0},
++	{0xB7, 0x24, 0x24, 0, 0},
++	{0xB8, 0x3, 0x3, 0, 0},
++	{0xB9, 0, 0, 0, 0},
++	{0xBA, 0xaa, 0xaa, 0, 0},
++	{0xBB, 0, 0, 0, 0},
++	{0xBC, 0x4, 0x4, 0, 0},
++	{0xBD, 0, 0, 0, 0},
++	{0xBE, 0x8, 0x8, 0, 0},
++	{0xBF, 0x11, 0x11, 0, 0},
++	{0xC0, 0, 0, 0, 0},
++	{0xC1, 0, 0, 0, 0},
++	{0xC2, 0x62, 0x62, 0, 0},
++	{0xC3, 0x1e, 0x1e, 0, 0},
++	{0xC4, 0x33, 0x33, 0, 0},
++	{0xC5, 0x37, 0x37, 0, 0},
++	{0xC6, 0, 0, 0, 0},
++	{0xC7, 0x70, 0x70, 0, 0},
++	{0xC8, 0x1e, 0x1e, 0, 0},
++	{0xC9, 0x6, 0x6, 0, 0},
++	{0xCA, 0x4, 0x4, 0, 0},
++	{0xCB, 0x2f, 0x2f, 0, 0},
++	{0xCC, 0xf, 0xf, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0xff, 0xff, 0, 0},
++	{0xCF, 0x8, 0x8, 0, 0},
++	{0xD0, 0x3f, 0x3f, 0, 0},
++	{0xD1, 0x3f, 0x3f, 0, 0},
++	{0xD2, 0x3f, 0x3f, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0xcc, 0xcc, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0x8, 0x8, 0, 0},
++	{0xD9, 0x8, 0x8, 0, 0},
++	{0xDA, 0x8, 0x8, 0, 0},
++	{0xDB, 0x11, 0x11, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x87, 0x87, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0x8, 0x8, 0, 0},
++	{0xE0, 0x8, 0x8, 0, 0},
++	{0xE1, 0x8, 0x8, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xE3, 0, 0, 0, 0},
++	{0xE4, 0, 0, 0, 0},
++	{0xE5, 0xf5, 0xf5, 0, 0},
++	{0xE6, 0x30, 0x30, 0, 0},
++	{0xE7, 0x1, 0x1, 0, 0},
++	{0xE8, 0, 0, 0, 0},
++	{0xE9, 0xff, 0xff, 0, 0},
++	{0xEA, 0, 0, 0, 0},
++	{0xEB, 0, 0, 0, 0},
++	{0xEC, 0x22, 0x22, 0, 0},
++	{0xED, 0, 0, 0, 0},
++	{0xEE, 0, 0, 0, 0},
++	{0xEF, 0, 0, 0, 0},
++	{0xF0, 0x3, 0x3, 0, 0},
++	{0xF1, 0x1, 0x1, 0, 0},
++	{0xF2, 0, 0, 0, 0},
++	{0xF3, 0, 0, 0, 0},
++	{0xF4, 0, 0, 0, 0},
++	{0xF5, 0, 0, 0, 0},
++	{0xF6, 0, 0, 0, 0},
++	{0xF7, 0x6, 0x6, 0, 0},
++	{0xF8, 0, 0, 0, 0},
++	{0xF9, 0, 0, 0, 0},
++	{0xFA, 0x40, 0x40, 0, 0},
++	{0xFB, 0, 0, 0, 0},
++	{0xFC, 0x1, 0x1, 0, 0},
++	{0xFD, 0x80, 0x80, 0, 0},
++	{0xFE, 0x2, 0x2, 0, 0},
++	{0xFF, 0x10, 0x10, 0, 0},
++	{0x100, 0x2, 0x2, 0, 0},
++	{0x101, 0x1e, 0x1e, 0, 0},
++	{0x102, 0x1e, 0x1e, 0, 0},
++	{0x103, 0, 0, 0, 0},
++	{0x104, 0x1f, 0x1f, 0, 0},
++	{0x105, 0, 0x8, 0, 1},
++	{0x106, 0x2a, 0x2a, 0, 0},
++	{0x107, 0xf, 0xf, 0, 0},
++	{0x108, 0, 0, 0, 0},
++	{0x109, 0, 0, 0, 0},
++	{0x10A, 0, 0, 0, 0},
++	{0x10B, 0, 0, 0, 0},
++	{0x10C, 0, 0, 0, 0},
++	{0x10D, 0, 0, 0, 0},
++	{0x10E, 0, 0, 0, 0},
++	{0x10F, 0, 0, 0, 0},
++	{0x110, 0, 0, 0, 0},
++	{0x111, 0, 0, 0, 0},
++	{0x112, 0, 0, 0, 0},
++	{0x113, 0, 0, 0, 0},
++	{0x114, 0, 0, 0, 0},
++	{0x115, 0, 0, 0, 0},
++	{0x116, 0, 0, 0, 0},
++	{0x117, 0, 0, 0, 0},
++	{0x118, 0, 0, 0, 0},
++	{0x119, 0, 0, 0, 0},
++	{0x11A, 0, 0, 0, 0},
++	{0x11B, 0, 0, 0, 0},
++	{0x11C, 0x1, 0x1, 0, 0},
++	{0x11D, 0, 0, 0, 0},
++	{0x11E, 0, 0, 0, 0},
++	{0x11F, 0, 0, 0, 0},
++	{0x120, 0, 0, 0, 0},
++	{0x121, 0, 0, 0, 0},
++	{0x122, 0x80, 0x80, 0, 0},
++	{0x123, 0, 0, 0, 0},
++	{0x124, 0xf8, 0xf8, 0, 0},
++	{0x125, 0, 0, 0, 0},
++	{0x126, 0, 0, 0, 0},
++	{0x127, 0, 0, 0, 0},
++	{0x128, 0, 0, 0, 0},
++	{0x129, 0, 0, 0, 0},
++	{0x12A, 0, 0, 0, 0},
++	{0x12B, 0, 0, 0, 0},
++	{0x12C, 0, 0, 0, 0},
++	{0x12D, 0, 0, 0, 0},
++	{0x12E, 0, 0, 0, 0},
++	{0x12F, 0, 0, 0, 0},
++	{0x130, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++#define LCNPHY_NUM_DIG_FILT_COEFFS 16
++#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
++
++static const u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
++	 128, 64,},
++	{1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
++	 167, 93,},
++	{2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
++	 128, 64,},
++	{3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++	{20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
++	 256, 185, 256,},
++	{21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
++	 256, 273, 256,},
++	{22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
++	 256, 352, 256,},
++	{23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
++	 128, 233, 128,},
++	{24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
++	 1881, 256,},
++	{25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
++	 1881, 256,},
++	{26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
++	 384, 288,},
++	{27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
++	 128, 384, 288,},
++	{30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++};
++
++#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
++static const u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
++	 0x278, 0xfea0, 0x80, 0x100, 0x80,},
++	{1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
++	 750, 0xFE2B, 212, 0xFFCE, 212,},
++	{2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
++	 0xFEF2, 128, 0xFFE2, 128}
++};
++
++#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
++	mod_phy_reg(pi, 0x4a4, \
++		    (0x1ff << 0), \
++		    (u16)(idx) << 0)
++
++#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
++	mod_phy_reg(pi, 0x4a5, \
++		    (0x7 << 8),	\
++		    (u16)(npt) << 8)
++
++#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
++	(read_phy_reg((pi), 0x4a4) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++#define wlc_lcnphy_get_tx_pwr_npt(pi) \
++	((read_phy_reg(pi, 0x4a5) & \
++	  (0x7 << 8)) >> \
++	 8)
++
++#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
++	(read_phy_reg(pi, 0x473) & 0x1ff)
++
++#define wlc_lcnphy_get_target_tx_pwr(pi) \
++	((read_phy_reg(pi, 0x4a7) & \
++	  (0xff << 0)) >> \
++	 0)
++
++#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
++	mod_phy_reg(pi, 0x4a7, \
++		    (0xff << 0), \
++		    (u16)(target) << 0)
++
++#define wlc_radio_2064_rcal_done(pi) \
++	(0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
++
++#define tempsense_done(pi) \
++	(0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
++
++#define LCNPHY_IQLOCC_READ(val) \
++	((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
++
++#define FIXED_TXPWR 78
++#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
++
++void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti)
++{
++	wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti)
++{
++	wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++static void
++wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id,
++			     const u16 *tbl_ptr, u32 tbl_len,
++			     u32 tbl_width, u32 tbl_offset)
++{
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_read_table(pi, &tab);
++}
++
++static void
++wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id,
++			      const u16 *tbl_ptr, u32 tbl_len,
++			      u32 tbl_width, u32 tbl_offset)
++{
++
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static u32
++wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
++{
++	u32 quotient, remainder, roundup, rbit;
++
++	quotient = dividend / divisor;
++	remainder = dividend % divisor;
++	rbit = divisor & 1;
++	roundup = (divisor >> 1) + rbit;
++
++	while (precision--) {
++		quotient <<= 1;
++		if (remainder >= roundup) {
++			quotient++;
++			remainder = ((remainder - roundup) << 1) + rbit;
++		} else {
++			remainder <<= 1;
++		}
++	}
++
++	if (remainder >= roundup)
++		quotient++;
++
++	return quotient;
++}
++
++static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
++{
++	int k;
++	k = 0;
++	if (type == 0) {
++		if (coeff_x < 0)
++			k = (coeff_x - 1) / 2;
++		else
++			k = coeff_x / 2;
++	}
++
++	if (type == 1) {
++		if ((coeff_x + 1) < 0)
++			k = (coeff_x) / 2;
++		else
++			k = (coeff_x + 1) / 2;
++	}
++	return k;
++}
++
++static void
++wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains)
++{
++	u16 dac_gain, rfgain0, rfgain1;
++
++	dac_gain = read_phy_reg(pi, 0x439) >> 0;
++	gains->dac_gain = (dac_gain & 0x380) >> 7;
++
++	rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
++	rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
++
++	gains->gm_gain = rfgain0 & 0xff;
++	gains->pga_gain = (rfgain0 >> 8) & 0xff;
++	gains->pad_gain = rfgain1 & 0xff;
++}
++
++
++static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain)
++{
++	u16 dac_ctrl;
++
++	dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
++	dac_ctrl = dac_ctrl & 0xc7f;
++	dac_ctrl = dac_ctrl | (dac_gain << 7);
++	mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
++
++}
++
++static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable)
++{
++	u16 bit = bEnable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
++}
++
++static void
++wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable)
++{
++	u16 ebit = enable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
++		mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
++		mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
++	}
++}
++
++static void
++wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
++				       u16 trsw,
++				       u16 ext_lna,
++				       u16 biq2,
++				       u16 biq1,
++				       u16 tia, u16 lna2, u16 lna1)
++{
++	u16 gain0_15, gain16_19;
++
++	gain16_19 = biq2 & 0xf;
++	gain0_15 = ((biq1 & 0xf) << 12) |
++		   ((tia & 0xf) << 8) |
++		   ((lna2 & 0x3) << 6) |
++		   ((lna2 &
++		     0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
++
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	} else {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	}
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
++
++}
++
++static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx)
++{
++
++	mod_phy_reg(pi, 0x44d,
++		    (0x1 << 1) |
++		    (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
++
++	or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
++}
++
++static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
++}
++
++static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b)
++{
++	mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
++
++}
++
++static bool
++wlc_lcnphy_rx_iq_est(struct brcms_phy *pi,
++		     u16 num_samps,
++		     u8 wait_time, struct lcnphy_iq_est *iq_est)
++{
++	int wait_count = 0;
++	bool result = true;
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
++
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
++
++	mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
++
++	while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
++
++		if (wait_count > (10 * 500)) {
++			result = false;
++			goto cleanup;
++		}
++		udelay(100);
++		wait_count++;
++	}
++
++	iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
++			  (u32) read_phy_reg(pi, 0x484);
++	iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
++			(u32) read_phy_reg(pi, 0x486);
++	iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
++			(u32) read_phy_reg(pi, 0x488);
++
++cleanup:
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
++
++	return result;
++}
++
++static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps)
++{
++#define LCNPHY_MIN_RXIQ_PWR 2
++	bool result;
++	u16 a0_new, b0_new;
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++	s32 a, b, temp;
++	s16 iq_nbits, qq_nbits, arsh, brsh;
++	s32 iq;
++	u32 ii, qq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
++	b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
++	mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
++
++	wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
++
++	result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
++	if (!result)
++		goto cleanup;
++
++	iq = (s32) iq_est.iq_prod;
++	ii = iq_est.i_pwr;
++	qq = iq_est.q_pwr;
++
++	if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
++		result = false;
++		goto cleanup;
++	}
++
++	iq_nbits = wlc_phy_nbits(iq);
++	qq_nbits = wlc_phy_nbits(qq);
++
++	arsh = 10 - (30 - iq_nbits);
++	if (arsh >= 0) {
++		a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++		temp = (s32) (ii >> arsh);
++		if (temp == 0)
++			return false;
++	} else {
++		a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++		temp = (s32) (ii << -arsh);
++		if (temp == 0)
++			return false;
++	}
++	a /= temp;
++	brsh = qq_nbits - 31 + 20;
++	if (brsh >= 0) {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii >> brsh);
++		if (temp == 0)
++			return false;
++	} else {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii << -brsh);
++		if (temp == 0)
++			return false;
++	}
++	b /= temp;
++	b -= a * a;
++	b = (s32) int_sqrt((unsigned long) b);
++	b -= (1 << 10);
++	a0_new = (u16) (a & 0x3ff);
++	b0_new = (u16) (b & 0x3ff);
++cleanup:
++
++	wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
++
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
++
++	return result;
++}
++
++static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
++{
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++
++	if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
++		return 0;
++	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
++}
++
++static bool
++wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
++		     const struct lcnphy_rx_iqcomp *iqcomp,
++		     int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
++		     int tx_gain_idx)
++{
++	struct lcnphy_txgains old_gains;
++	u16 tx_pwr_ctrl;
++	u8 tx_gain_index_old = 0;
++	bool result = false, tx_gain_override_old = false;
++	u16 i, Core1TxControl_old, RFOverride0_old,
++	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
++	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
++	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
++	int tia_gain;
++	u32 received_power, rx_pwr_threshold;
++	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
++	u16 values_to_save[11];
++	s16 *ptr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return false;
++	if (module == 2) {
++		while (iqcomp_sz--) {
++			if (iqcomp[iqcomp_sz].chan ==
++			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
++				wlc_lcnphy_set_rx_iq_comp(pi,
++							  (u16)
++							  iqcomp[iqcomp_sz].a,
++							  (u16)
++							  iqcomp[iqcomp_sz].b);
++				result = true;
++				break;
++			}
++		}
++		goto cal_done;
++	}
++
++	if (module == 1) {
++
++		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++		for (i = 0; i < 11; i++)
++			values_to_save[i] =
++				read_radio_reg(pi, rxiq_cal_rf_reg[i]);
++		Core1TxControl_old = read_phy_reg(pi, 0x631);
++
++		or_phy_reg(pi, 0x631, 0x0015);
++
++		RFOverride0_old = read_phy_reg(pi, 0x44c);
++		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
++		rfoverride2_old = read_phy_reg(pi, 0x4b0);
++		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
++		rfoverride3_old = read_phy_reg(pi, 0x4f9);
++		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
++		rfoverride4_old = read_phy_reg(pi, 0x938);
++		rfoverride4val_old = read_phy_reg(pi, 0x939);
++		afectrlovr_old = read_phy_reg(pi, 0x43b);
++		afectrlovrval_old = read_phy_reg(pi, 0x43c);
++		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++
++		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++		if (tx_gain_override_old) {
++			wlc_lcnphy_get_tx_gain(pi, &old_gains);
++			tx_gain_index_old = pi_lcn->lcnphy_current_index;
++		}
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
++
++		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
++		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
++		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
++		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
++		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
++		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
++		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
++
++		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
++		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
++		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
++		write_phy_reg(pi, 0x6da, 0xffff);
++		or_phy_reg(pi, 0x6db, 0x3);
++		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
++		wlc_lcnphy_rx_gain_override_enable(pi, true);
++
++		tia_gain = 8;
++		rx_pwr_threshold = 950;
++		while (tia_gain > 0) {
++			tia_gain -= 1;
++			wlc_lcnphy_set_rx_gain_by_distribution(pi,
++							       0, 0, 2, 2,
++							       (u16)
++							       tia_gain, 1, 0);
++			udelay(500);
++
++			received_power =
++				wlc_lcnphy_measure_digital_power(pi, 2000);
++			if (received_power < rx_pwr_threshold)
++				break;
++		}
++		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
++
++		wlc_lcnphy_stop_tx_tone(pi);
++
++		write_phy_reg(pi, 0x631, Core1TxControl_old);
++
++		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x4b0, rfoverride2_old);
++		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
++		write_phy_reg(pi, 0x4f9, rfoverride3_old);
++		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
++		write_phy_reg(pi, 0x938, rfoverride4_old);
++		write_phy_reg(pi, 0x939, rfoverride4val_old);
++		write_phy_reg(pi, 0x43b, afectrlovr_old);
++		write_phy_reg(pi, 0x43c, afectrlovrval_old);
++		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
++
++		wlc_lcnphy_clear_trsw_override(pi);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
++
++		for (i = 0; i < 11; i++)
++			write_radio_reg(pi, rxiq_cal_rf_reg[i],
++					values_to_save[i]);
++
++		if (tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
++		else
++			wlc_lcnphy_disable_tx_gain_override(pi);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
++		wlc_lcnphy_rx_gain_override_enable(pi, false);
++	}
++
++cal_done:
++	kfree(ptr);
++	return result;
++}
++
++s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi)
++{
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (txpwrctrl_off(pi))
++		index = pi_lcn->lcnphy_current_index;
++	else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		index =	(s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(
++			      pi) / 2);
++	else
++		index = pi_lcn->lcnphy_current_index;
++	return index;
++}
++
++void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel)
++{
++	u16 afectrlovr, afectrlovrval;
++	afectrlovr = read_phy_reg(pi, 0x43b);
++	afectrlovrval = read_phy_reg(pi, 0x43c);
++	if (channel != 0) {
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
++
++		write_phy_reg(pi, 0x44b, 0xffff);
++		wlc_lcnphy_tx_pu(pi, 1);
++
++		mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
++
++		or_phy_reg(pi, 0x6da, 0x0080);
++
++		or_phy_reg(pi, 0x00a, 0x228);
++	} else {
++		and_phy_reg(pi, 0x00a, ~(0x228));
++
++		and_phy_reg(pi, 0x6da, 0xFF7F);
++		write_phy_reg(pi, 0x43b, afectrlovr);
++		write_phy_reg(pi, 0x43c, afectrlovrval);
++	}
++}
++
++static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi)
++{
++	u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
++
++	save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
++	save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
++}
++
++static void
++wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable)
++{
++	if (enable) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
++
++		write_phy_reg(pi, 0x44a, 0x084);
++		write_phy_reg(pi, 0x44a, 0x080);
++		write_phy_reg(pi, 0x6d3, 0x2222);
++		write_phy_reg(pi, 0x6d3, 0x2220);
++	} else {
++		write_phy_reg(pi, 0x942, 0x0);
++		write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
++	}
++	wlapi_switch_macfreq(pi->sh->physhim, enable);
++}
++
++static void
++wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (channel == 14)
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++	else
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++	pi_lcn->lcnphy_bandedge_corr = 2;
++	if (channel == 1)
++		pi_lcn->lcnphy_bandedge_corr = 4;
++
++	if (channel == 1 || channel == 2 || channel == 3 ||
++	    channel == 4 || channel == 9 ||
++	    channel == 10 || channel == 11 || channel == 12) {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
++
++		write_phy_reg(pi, 0x425, 0x5907);
++	} else {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
++
++		write_phy_reg(pi, 0x425, 0x590a);
++	}
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++}
++
++static void
++wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
++{
++	uint i;
++	const struct chan_info_2064_lcnphy *ci;
++	u8 rfpll_doubler = 0;
++	u8 pll_pwrup, pll_pwrup_ovr;
++	s32 qFxtal, qFref, qFvco, qFcal;
++	u8 d15, d16, f16, e44, e45;
++	u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
++	u16 loop_bw, d30, setCount;
++
++	u8 h29, h28_ten, e30, h30_ten, cp_current;
++	u16 g30, d28;
++
++	ci = &chan_info_2064_lcnphy[0];
++	rfpll_doubler = 1;
++
++	mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
++
++	write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
++	if (!rfpll_doubler) {
++		loop_bw = PLL_2064_LOOP_BW;
++		d30 = PLL_2064_D30;
++	} else {
++		loop_bw = PLL_2064_LOOP_BW_DOUBLER;
++		d30 = PLL_2064_D30_DOUBLER;
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
++			if (chan_info_2064_lcnphy[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_2064_lcnphy))
++			return;
++
++		ci = &chan_info_2064_lcnphy[i];
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
++
++	mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
++
++	mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
++		      (ci->logen_rccr_rx) << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
++		      (ci->pa_rxrf_lna2_freq_tune) << 4);
++
++	write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
++
++	pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
++	pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
++
++	or_radio_reg(pi, RADIO_2064_REG044, 0x07);
++
++	or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
++	e44 = 0;
++	e45 = 0;
++
++	fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
++	if (pi->xtalfreq > 26000000)
++		e44 = 1;
++	if (pi->xtalfreq > 52000000)
++		e45 = 1;
++	if (e44 == 0)
++		fcal_div = 1;
++	else if (e45 == 0)
++		fcal_div = 2;
++	else
++		fcal_div = 4;
++	fvco3 = (ci->freq * 3);
++	fref3 = 2 * fpfd;
++
++	qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
++	qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
++	qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
++	qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
++
++	write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
++
++	d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
++	write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
++	write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
++
++	d16 = (qFcal * 8 / (d15 + 1)) - 1;
++	write_radio_reg(pi, RADIO_2064_REG051, d16);
++
++	f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
++	setCount = f16 * 3 * (ci->freq) / 32 - 1;
++	mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
++		      (u8) (setCount >> 8));
++
++	or_radio_reg(pi, RADIO_2064_REG053, 0x10);
++	write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
++
++	div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
++
++	div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
++	while (div_frac >= fref3) {
++		div_int++;
++		div_frac -= fref3;
++	}
++	div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
++
++	mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
++		      (u8) (div_int >> 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
++		      (u8) (div_int << 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
++		      (u8) (div_frac >> 16));
++	write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
++	write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
++
++	write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
++
++	write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
++	write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
++	write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
++
++	h29 = LCN_BW_LMT / loop_bw;
++	d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
++		(fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
++	       (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
++	      + PLL_2064_LOW_END_KVCO;
++	h28_ten = (d28 * 10) / LCN_VCO_DIV;
++	e30 = (d30 - LCN_OFFSET) / LCN_FACT;
++	g30 = LCN_OFFSET + (e30 * LCN_FACT);
++	h30_ten = (g30 * 10) / LCN_CUR_DIV;
++	cp_current = ((LCN_CUR_LMT * h29 * LCN_MULT * 100) / h28_ten) / h30_ten;
++	mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
++
++	if (channel >= 1 && channel <= 5)
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
++	else
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
++	write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
++
++	mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
++	udelay(1);
++
++	wlc_2064_vco_cal(pi);
++
++	write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
++	write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		write_radio_reg(pi, RADIO_2064_REG038, 3);
++		write_radio_reg(pi, RADIO_2064_REG091, 7);
++	}
++}
++
++static int
++wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
++{
++	s16 filt_index = -1;
++	int j;
++
++	u16 addr[] = {
++		0x910,
++		0x91e,
++		0x91f,
++		0x924,
++		0x925,
++		0x926,
++		0x920,
++		0x921,
++		0x927,
++		0x928,
++		0x929,
++		0x922,
++		0x923,
++		0x930,
++		0x931,
++		0x932
++	};
++
++	u16 addr_ofdm[] = {
++		0x90f,
++		0x900,
++		0x901,
++		0x906,
++		0x907,
++		0x908,
++		0x902,
++		0x903,
++		0x909,
++		0x90a,
++		0x90b,
++		0x904,
++		0x905,
++		0x90c,
++		0x90d,
++		0x90e
++	};
++
++	if (!is_ofdm) {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr[j],
++					      LCNPHY_txdigfiltcoeffs_cck
++					      [filt_index][j + 1]);
++		}
++	} else {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr_ofdm[j],
++					      LCNPHY_txdigfiltcoeffs_ofdm
++					      [filt_index][j + 1]);
++		}
++	}
++
++	return (filt_index != -1) ? 0 : -1;
++}
++
++void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
++	udelay(1000);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++
++	write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
++	write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
++	} else {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
++	}
++
++	wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
++
++}
++
++static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
++{
++	u16 pa_gain;
++
++	pa_gain = (read_phy_reg(pi, 0x4fb) &
++		   LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
++		  LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
++
++	return pa_gain;
++}
++
++static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
++				   struct lcnphy_txgains *target_gains)
++{
++	u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	mod_phy_reg(
++		pi, 0x4b5,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fb,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	mod_phy_reg(
++		pi, 0x4fc,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fd,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++}
++
++static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
++{
++	u16 m0m1 = (u16) m0 << 8;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi)
++{
++	u32 data_buf[64];
++	struct phytbl_info tab;
++
++	memset(data_buf, 0, sizeof(data_buf));
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = data_buf;
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		tab.tbl_len = 30;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_len = 64;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++enum lcnphy_tssi_mode {
++	LCNPHY_TSSI_PRE_PA,
++	LCNPHY_TSSI_POST_PA,
++	LCNPHY_TSSI_EXT
++};
++
++static void
++wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
++{
++	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
++
++	if (LCNPHY_TSSI_POST_PA == pos) {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	} else {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	}
++	mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
++
++	if (LCNPHY_TSSI_EXT == pos) {
++		write_radio_reg(pi, RADIO_2064_REG07F, 1);
++		mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
++		mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
++	}
++}
++
++static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi)
++{
++	u16 N1, N2, N3, N4, N5, N6, N;
++	N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
++	      >> 0);
++	N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
++		   >> 12);
++	N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
++	      >> 0);
++	N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
++		   >> 8);
++	N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
++	      >> 0);
++	N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
++		   >> 8);
++	N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
++	if (N < 1600)
++		N = 1600;
++	return N;
++}
++
++static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
++{
++	u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	auxpga_vmid = (2 << 8) |
++		      (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
++	auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
++	auxpga_gain_temp = 2;
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x4db,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x4dc,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40a,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40b,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_phy_reg(pi, 0x40c,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
++}
++
++static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rfseq, ind;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &ind;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 0;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	tab.tbl_offset = 704;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
++
++	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
++
++	wlc_lcnphy_clear_tx_power_offsets(pi);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
++
++	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
++		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++	} else {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xc);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++	} else {
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++	else
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		mod_phy_reg(pi, 0x4d7,
++			    (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
++
++	rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &rfseq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
++
++	wlc_lcnphy_pwrctrl_rssiparams(pi);
++}
++
++void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi)
++{
++	u16 tx_cnt, tx_total, npt;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	tx_total = wlc_lcnphy_total_tx_frames(pi);
++	tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
++	npt = wlc_lcnphy_get_tx_pwr_npt(pi);
++
++	if (tx_cnt > (1 << npt)) {
++
++		pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
++
++		pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++		pi_lcn->lcnphy_tssi_npt = npt;
++
++	}
++}
++
++s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
++{
++	s32 a, b, p;
++
++	a = 32768 + (a1 * tssi);
++	b = (1024 * b0) + (64 * b1 * tssi);
++	p = ((2 * b) + a) / (2 * a);
++
++	return p;
++}
++
++static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
++	pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
++}
++
++void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM +
++		       BRCMS_NUM_RATES_MCS_1_STREAM];
++	uint i, j;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
++
++		if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM)
++			j = TXP_FIRST_MCS_20_SISO;
++
++		rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = ARRAY_SIZE(rate_table);
++	tab.tbl_ptr = rate_table;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
++		wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
++
++		wlc_lcnphy_txpower_reset_npt(pi);
++	}
++}
++
++static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index)
++{
++	u32 cck_offset[4] = { 22, 22, 22, 22 };
++	u32 ofdm_offset, reg_offset_cck;
++	int i;
++	u16 index2;
++	struct phytbl_info tab;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return;
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
++
++	or_phy_reg(pi, 0x6da, 0x0040);
++
++	reg_offset_cck = 0;
++	for (i = 0; i < 4; i++)
++		cck_offset[i] -= reg_offset_cck;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 4;
++	tab.tbl_ptr = cck_offset;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++	ofdm_offset = 0;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &ofdm_offset;
++	for (i = 836; i < 862; i++) {
++		tab.tbl_offset = i;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
++
++	index2 = (u16) (index * 2);
++	mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
++
++}
++
++static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi)
++{
++	s8 index, delta_brd, delta_temp, new_index, tempcorrx;
++	s16 manp, meas_temp, temp_diff;
++	bool neg = false;
++	u16 temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return pi_lcn->lcnphy_current_index;
++
++	index = FIXED_TXPWR;
++
++	if (pi_lcn->lcnphy_tempsense_slope == 0)
++		return index;
++
++	temp = (u16) wlc_lcnphy_tempsense(pi, 0);
++	meas_temp = LCNPHY_TEMPSENSE(temp);
++
++	if (pi->tx_power_min != 0)
++		delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
++	else
++		delta_brd = 0;
++
++	manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
++	temp_diff = manp - meas_temp;
++	if (temp_diff < 0) {
++		neg = true;
++		temp_diff = -temp_diff;
++	}
++
++	delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
++						  (u32) (pi_lcn->
++							 lcnphy_tempsense_slope
++							 * 10), 0);
++	if (neg)
++		delta_temp = -delta_temp;
++
++	if (pi_lcn->lcnphy_tempsense_option == 3
++	    && LCNREV_IS(pi->pubpi.phy_rev, 0))
++		delta_temp = 0;
++	if (pi_lcn->lcnphy_tempcorrx > 31)
++		tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
++	else
++		tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		tempcorrx = 4;
++	new_index =
++		index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
++	new_index += tempcorrx;
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		index = 127;
++
++	if (new_index < 0 || new_index > 126)
++		return index;
++
++	return new_index;
++}
++
++static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode)
++{
++
++	u16 current_mode = mode;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_HW)
++		current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
++		current_mode = LCNPHY_TX_PWR_CTRL_HW;
++	return current_mode;
++}
++
++void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode)
++{
++	u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
++	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 6),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
++
++	if (old_mode != mode) {
++		if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
++
++			wlc_lcnphy_tx_pwr_update_npt(pi);
++
++			wlc_lcnphy_clear_tx_power_offsets(pi);
++		}
++		if (LCNPHY_TX_PWR_CTRL_HW == mode) {
++
++			wlc_lcnphy_txpower_recalc_target(pi);
++
++			wlc_lcnphy_set_start_tx_pwr_idx(pi,
++							pi_lcn->
++							lcnphy_tssi_idx);
++			wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
++			mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
++
++			pi_lcn->lcnphy_tssi_tx_cnt =
++				wlc_lcnphy_total_tx_frames(pi);
++
++			wlc_lcnphy_disable_tx_gain_override(pi);
++			pi_lcn->lcnphy_tx_power_idx_override = -1;
++		} else
++			wlc_lcnphy_enable_tx_gain_override(pi);
++
++		mod_phy_reg(pi, 0x4a4,
++			    ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
++		if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
++			index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++			wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
++			pi_lcn->lcnphy_current_index = (s8)
++						       ((read_phy_reg(pi,
++								      0x4a9) &
++							 0xFF) / 2);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save)
++{
++	u16 vmid;
++	int i;
++	for (i = 0; i < 20; i++)
++		values_to_save[i] =
++			read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++	mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
++	mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
++	else
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
++
++	or_radio_reg(pi, RADIO_2064_REG036, 0x01);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
++	udelay(20);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 1);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xF);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG005, 0x8);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x80);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++	or_radio_reg(pi, RADIO_2064_REG113, 0x10);
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG007, 0x1);
++	udelay(20);
++
++	vmid = 0x2A6;
++	mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
++	write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	udelay(20);
++	write_radio_reg(pi, RADIO_2064_REG012, 0x02);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x06);
++	write_radio_reg(pi, RADIO_2064_REG036, 0x11);
++	write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
++	write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
++	write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
++	write_radio_reg(pi, RADIO_2064_REG092, 0x15);
++}
++
++static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi)
++{
++	uint delay_count = 0;
++
++	while (wlc_lcnphy_iqcal_active(pi)) {
++		udelay(100);
++		delay_count++;
++
++		if (delay_count > (10 * 500))
++			break;
++	}
++
++	return (0 == wlc_lcnphy_iqcal_active(pi));
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save)
++{
++	int i;
++
++	and_phy_reg(pi, 0x44c, 0x0 >> 11);
++
++	and_phy_reg(pi, 0x43b, 0xC);
++
++	for (i = 0; i < 20; i++)
++		write_radio_reg(pi, iqlo_loopback_rf_regs[i],
++				values_to_save[i]);
++}
++
++static void
++wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi,
++		       struct lcnphy_txgains *target_gains,
++		       enum lcnphy_cal_mode cal_mode, bool keep_tone)
++{
++
++	struct lcnphy_txgains cal_gains, temp_gains;
++	u16 hash;
++	u8 band_idx;
++	int j;
++	u16 ncorr_override[5];
++	u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++			      0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
++
++	u16 commands_fullcal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 commands_recal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 command_nums_fullcal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++
++	u16 command_nums_recal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++	u16 *command_nums = command_nums_fullcal;
++
++	u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
++	u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
++	u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
++	bool tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	uint i, n_cal_cmds = 0, n_cal_start = 0;
++	u16 *values_to_save;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == values_to_save)
++		return;
++
++	save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++	save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	or_phy_reg(pi, 0x6da, 0x40);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	switch (cal_mode) {
++	case LCNPHY_CAL_FULL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_fullcal;
++		n_cal_cmds = ARRAY_SIZE(commands_fullcal);
++		break;
++
++	case LCNPHY_CAL_RECAL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_recal;
++		n_cal_cmds = ARRAY_SIZE(commands_recal);
++		command_nums = command_nums_recal;
++		break;
++
++	default:
++		break;
++	}
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      start_coeffs, 11, 16, 64);
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++	mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
++
++	tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
++
++	mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
++
++	mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	if (tx_gain_override_old)
++		wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	if (!target_gains) {
++		if (!tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi,
++						       pi_lcn->lcnphy_tssi_idx);
++		wlc_lcnphy_get_tx_gain(pi, &temp_gains);
++		target_gains = &temp_gains;
++	}
++
++	hash = (target_gains->gm_gain << 8) |
++	       (target_gains->pga_gain << 4) | (target_gains->pad_gain);
++
++	band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	cal_gains = *target_gains;
++	memset(ncorr_override, 0, sizeof(ncorr_override));
++	for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
++		if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
++			cal_gains.gm_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
++			cal_gains.pga_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
++			cal_gains.pad_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
++			memcpy(ncorr_override,
++			       &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
++			       sizeof(ncorr_override));
++			break;
++		}
++	}
++
++	wlc_lcnphy_set_tx_gain(pi, &cal_gains);
++
++	write_phy_reg(pi, 0x453, 0xaa9);
++	write_phy_reg(pi, 0x93d, 0xc0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_loft_gainladder,
++				      ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
++				      16, 0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_ir_gainladder,
++				      ARRAY_SIZE(
++					      lcnphy_iqcal_ir_gainladder), 16,
++				      32);
++
++	if (pi->phy_tx_tone_freq) {
++
++		wlc_lcnphy_stop_tx_tone(pi);
++		udelay(5);
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	} else {
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	}
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++
++	for (i = n_cal_start; i < n_cal_cmds; i++) {
++		u16 zero_diq = 0;
++		u16 best_coeffs[11];
++		u16 command_num;
++
++		cal_type = (cal_cmds[i] & 0x0f00) >> 8;
++
++		command_num = command_nums[i];
++		if (ncorr_override[cal_type])
++			command_num =
++				ncorr_override[cal_type] << 8 | (command_num &
++								 0xff);
++
++		write_phy_reg(pi, 0x452, command_num);
++
++		if ((cal_type == 3) || (cal_type == 4)) {
++			wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						     &diq_start, 1, 16, 69);
++
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &zero_diq, 1, 16, 69);
++		}
++
++		write_phy_reg(pi, 0x451, cal_cmds[i]);
++
++		if (!wlc_lcnphy_iqcal_wait(pi))
++			goto cleanup;
++
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     best_coeffs,
++					     ARRAY_SIZE(best_coeffs), 16, 96);
++		wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					      best_coeffs,
++					      ARRAY_SIZE(best_coeffs), 16, 64);
++
++		if ((cal_type == 3) || (cal_type == 4))
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &diq_start, 1, 16, 69);
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     pi_lcn->lcnphy_cal_results.
++					     txiqlocal_bestcoeffs,
++					     ARRAY_SIZE(pi_lcn->
++							lcnphy_cal_results.
++							txiqlocal_bestcoeffs),
++					     16, 96);
++	}
++
++	wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				     pi_lcn->lcnphy_cal_results.
++				     txiqlocal_bestcoeffs,
++				     ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
++						txiqlocal_bestcoeffs), 16, 96);
++	pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[0], 4, 16, 80);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[5], 2, 16, 85);
++
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
++	kfree(values_to_save);
++
++	if (!keep_tone)
++		wlc_lcnphy_stop_tx_tone(pi);
++
++	write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
++
++	write_phy_reg(pi, 0x453, 0);
++
++	if (tx_gain_override_old)
++		wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
++
++	write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
++	write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
++
++}
++
++static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
++{
++	bool suspend, tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
++	    idleTssi0_regvalue_2C;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
++	u16 SAVE_jtag_bb_afe_switch =
++		read_radio_reg(pi, RADIO_2064_REG007) & 1;
++	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
++	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
++	idleTssi = read_phy_reg(pi, 0x4ab);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
++	wlc_lcnphy_tssi_setup(pi);
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++		    >> 0);
++
++	idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
++			>> 0);
++
++	if (idleTssi0_2C >= 256)
++		idleTssi0_OB = idleTssi0_2C - 256;
++	else
++		idleTssi0_OB = idleTssi0_2C + 256;
++
++	idleTssi0_regvalue_OB = idleTssi0_OB;
++	if (idleTssi0_regvalue_OB >= 256)
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
++	else
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
++
++	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
++	mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
++{
++	bool suspend;
++	u16 save_txpwrCtrlEn;
++	u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
++	u16 auxpga_vmid;
++	struct phytbl_info tab;
++	u32 val;
++	u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
++	   save_reg112;
++	u16 values_to_save[14];
++	s8 index;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	udelay(999);
++
++	save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
++	save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
++	save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
++	save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
++	save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
++	save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
++
++	for (i = 0; i < 14; i++)
++		values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++	index = pi_lcn->lcnphy_current_index;
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xC);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++	if (mode == TEMPSENSE) {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
++
++		auxpga_vmidcourse = 8;
++		auxpga_vmidfine = 0x4;
++		auxpga_gain = 2;
++		mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
++	} else {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
++
++		auxpga_vmidcourse = 7;
++		auxpga_vmidfine = 0xa;
++		auxpga_gain = 2;
++	}
++	auxpga_vmid =
++		(u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
++
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
++
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	if (!tempsense_done(pi))
++		udelay(10);
++
++	write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
++	write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
++	write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
++	write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
++	write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
++	write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
++	for (i = 0; i < 14; i++)
++		write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
++
++	write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++	udelay(999);
++}
++
++static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
++{
++	struct lcnphy_txgains tx_gains;
++	u8 bbmult;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	bool suspend;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (!pi->hwpwrctrl_capable) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			tx_gains.gm_gain = 4;
++			tx_gains.pga_gain = 12;
++			tx_gains.pad_gain = 12;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		} else {
++			tx_gains.gm_gain = 7;
++			tx_gains.pga_gain = 15;
++			tx_gains.pad_gain = 14;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		}
++		wlc_lcnphy_set_tx_gain(pi, &tx_gains);
++		wlc_lcnphy_set_bbmult(pi, bbmult);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	} else {
++
++		wlc_lcnphy_idle_tssi_est(ppi);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
++
++		write_phy_reg(pi, 0x4a8, 10);
++
++		wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	}
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
++{
++	u16 m0m1;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return (u8) ((m0m1 & 0xff00) >> 8);
++}
++
++static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
++{
++	mod_phy_reg(pi, 0x4fb,
++		    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
++	mod_phy_reg(pi, 0x4fd,
++		    LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
++}
++
++void
++wlc_lcnphy_get_radio_loft(struct brcms_phy *pi,
++			  u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
++{
++	*ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
++	*eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
++	*fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
++	*fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
++}
++
++void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b)
++{
++	struct phytbl_info tab;
++	u16 iqcc[2];
++
++	iqcc[0] = a;
++	iqcc[1] = b;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_offset = 80;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq)
++{
++	struct phytbl_info tab;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index)
++{
++	struct phytbl_info tab;
++	u16 a, b;
++	u8 bb_mult;
++	u32 bbmultiqcomp, txgain, locoeffs, rfpower;
++	struct lcnphy_txgains gains;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
++	pi_lcn->lcnphy_current_index = (u8) index;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++	tab.tbl_ptr = &bbmultiqcomp;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &txgain;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	gains.gm_gain = (u16) (txgain & 0xff);
++	gains.pga_gain = (u16) (txgain >> 8) & 0xff;
++	gains.pad_gain = (u16) (txgain >> 16) & 0xff;
++	gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
++	wlc_lcnphy_set_tx_gain(pi, &gains);
++	wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
++
++	bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
++	wlc_lcnphy_set_bbmult(pi, bb_mult);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
++		b = (u16) (bbmultiqcomp & 0x3ff);
++		wlc_lcnphy_set_tx_iqcc(pi, a, b);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
++		tab.tbl_ptr = &locoeffs;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		tab.tbl_ptr = &rfpower;
++		wlc_lcnphy_read_table(pi, &tab);
++		mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
++
++	}
++}
++
++static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 temp_offset[128];
++	tab.tbl_ptr = temp_offset;
++	tab.tbl_len = 128;
++	tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
++	tab.tbl_width = 32;
++	tab.tbl_offset = 0;
++
++	memset(temp_offset, 0, sizeof(temp_offset));
++	for (j = 1; j < 128; j += 2)
++		temp_offset[j] = 0x80000;
++
++	wlc_lcnphy_write_table(pi, &tab);
++	return;
++}
++
++void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable)
++{
++	if (!bEnable) {
++
++		and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
++
++		and_phy_reg(pi, 0x44c,
++			    ~(u16) ((0x1 << 3) |
++				    (0x1 << 5) |
++				    (0x1 << 12) |
++				    (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x44d,
++			    ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
++
++		and_phy_reg(pi, 0x4f9,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x4fa,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++	} else {
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++		mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++		wlc_lcnphy_set_trsw_override(pi, true, false);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
++		} else {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_run_samples(struct brcms_phy *pi,
++		       u16 num_samps,
++		       u16 num_loops, u16 wait, bool iqcalmode)
++{
++
++	or_phy_reg(pi, 0x6da, 0x8080);
++
++	mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
++	if (num_loops != 0xffff)
++		num_loops--;
++	mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
++
++	mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
++
++	if (iqcalmode) {
++
++		and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
++		or_phy_reg(pi, 0x453, (0x1 << 15));
++	} else {
++		write_phy_reg(pi, 0x63f, 1);
++		wlc_lcnphy_tx_pu(pi, 1);
++	}
++
++	or_radio_reg(pi, RADIO_2064_REG112, 0x6);
++}
++
++void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	}
++
++	if (phybw40 == 0) {
++		mod_phy_reg((pi), 0x410,
++			    (0x1 << 6) |
++			    (0x1 << 5),
++			    ((CHSPEC_IS2G(
++				      pi->radio_chanspec)) ? (!mode) : 0) <<
++			    6 | (!mode) << 5);
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
++	}
++}
++
++void
++wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
++			 bool iqcalmode)
++{
++	u8 phy_bw;
++	u16 num_samps, t, k;
++	u32 bw;
++	s32 theta = 0, rot = 0;
++	struct cordic_iq tone_samp;
++	u32 data_buf[64];
++	u16 i_samp, q_samp;
++	struct phytbl_info tab;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = f_kHz;
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	phy_bw = 40;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x2);
++		write_phy_reg(pi, 0x93b, 0x0);
++		write_phy_reg(pi, 0x93c, 0x0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++	}
++
++	if (f_kHz) {
++		k = 1;
++		do {
++			bw = phy_bw * 1000 * k;
++			num_samps = bw / abs(f_kHz);
++			k++;
++		} while ((num_samps * (u32) (abs(f_kHz))) != bw);
++	} else
++		num_samps = 2;
++
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_samp = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
++		q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
++		data_buf[t] = (i_samp << 10) | q_samp;
++	}
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
++
++	tab.tbl_ptr = data_buf;
++	tab.tbl_len = num_samps;
++	tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
++	tab.tbl_offset = 0;
++	tab.tbl_width = 32;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
++}
++
++void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi)
++{
++	s16 playback_status;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = 0;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, 0x2017);
++		write_phy_reg(pi, 0x93c, 0x27c5);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++	}
++
++	playback_status = read_phy_reg(pi, 0x644);
++	if (playback_status & (0x1 << 0)) {
++		wlc_lcnphy_tx_pu(pi, 0);
++		mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
++	} else if (playback_status & (0x1 << 1))
++		mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
++
++	and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
++
++	wlc_lcnphy_deaf_mode(pi, false);
++}
++
++static void
++wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y)
++{
++	u16 di0dq0;
++	u16 x, y, data_rf;
++	int k;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
++		break;
++	case 2:
++		di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
++		wlc_lcnphy_set_tx_locc(pi, di0dq0);
++		break;
++	case 3:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG089, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
++		break;
++	case 4:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
++		break;
++	}
++}
++
++static struct lcnphy_unsign16_struct
++wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type)
++{
++	u16 a, b, didq;
++	u8 di0, dq0, ei, eq, fi, fq;
++	struct lcnphy_unsign16_struct cc;
++	cc.re = 0;
++	cc.im = 0;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++		cc.re = a;
++		cc.im = b;
++		break;
++	case 2:
++		didq = wlc_lcnphy_get_tx_locc(pi);
++		di0 = (((didq & 0xff00) << 16) >> 24);
++		dq0 = (((didq & 0x00ff) << 24) >> 24);
++		cc.re = (u16) di0;
++		cc.im = (u16) dq0;
++		break;
++	case 3:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) ei;
++		cc.im = (u16) eq;
++		break;
++	case 4:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) fi;
++		cc.im = (u16) fq;
++		break;
++	}
++	return cc;
++}
++
++static void
++wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
++		    s16 *ptr, int mode)
++{
++	u32 curval1, curval2, stpptr, curptr, strptr, val;
++	u16 sslpnCalibClkEnCtrl, timer;
++	u16 old_sslpnCalibClkEnCtrl;
++	s16 imag, real;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	timer = 0;
++	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	curval1 = bcma_read16(pi->d11core, D11REGOFFS(psm_corectlsts));
++	ptr[130] = 0;
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts),
++		     ((1 << 6) | curval1));
++
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_strptr), 0x7E00);
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_stpptr), 0x8000);
++	udelay(20);
++	curval2 = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		     curval2 | 0x30);
++
++	write_phy_reg(pi, 0x555, 0x0);
++	write_phy_reg(pi, 0x5a6, 0x5);
++
++	write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
++	write_phy_reg(pi, 0x5cf, 3);
++	write_phy_reg(pi, 0x5a5, 0x3);
++	write_phy_reg(pi, 0x583, 0x0);
++	write_phy_reg(pi, 0x584, 0x0);
++	write_phy_reg(pi, 0x585, 0x0fff);
++	write_phy_reg(pi, 0x586, 0x0000);
++
++	write_phy_reg(pi, 0x580, 0x4501);
++
++	sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++	write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
++	stpptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_stpptr));
++	curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++	do {
++		udelay(10);
++		curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++		timer++;
++	} while ((curptr != stpptr) && (timer < 500));
++
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), 0x2);
++	strptr = 0x7E00;
++	bcma_write32(pi->d11core, D11REGOFFS(tplatewrptr), strptr);
++	while (strptr < 0x8000) {
++		val = bcma_read32(pi->d11core, D11REGOFFS(tplatewrdata));
++		imag = ((val >> 16) & 0x3ff);
++		real = ((val) & 0x3ff);
++		if (imag > 511)
++			imag -= 1024;
++
++		if (real > 511)
++			real -= 1024;
++
++		if (pi_lcn->lcnphy_iqcal_swp_dis)
++			ptr[(strptr - 0x7E00) / 4] = real;
++		else
++			ptr[(strptr - 0x7E00) / 4] = imag;
++
++		if (clip_detect_algo) {
++			if (imag > thresh || imag < -thresh) {
++				strptr = 0x8000;
++				ptr[130] = 1;
++			}
++		}
++
++		strptr += 4;
++	}
++
++	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), curval2);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts), curval1);
++}
++
++static void
++wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels,
++	      int step_size_lg2)
++{
++	const struct lcnphy_spb_tone *phy_c1;
++	struct lcnphy_spb_tone phy_c2;
++	struct lcnphy_unsign16_struct phy_c3;
++	int phy_c4, phy_c5, k, l, j, phy_c6;
++	u16 phy_c7, phy_c8, phy_c9;
++	s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
++	s16 *ptr, phy_c17;
++	s32 phy_c18, phy_c19;
++	u32 phy_c20, phy_c21;
++	bool phy_c22, phy_c23, phy_c24, phy_c25;
++	u16 phy_c26, phy_c27;
++	u16 phy_c28, phy_c29, phy_c30;
++	u16 phy_c31;
++	u16 *phy_c32;
++	phy_c21 = 0;
++	phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return;
++
++	phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == phy_c32) {
++		kfree(ptr);
++		return;
++	}
++	phy_c26 = read_phy_reg(pi, 0x6da);
++	phy_c27 = read_phy_reg(pi, 0x6db);
++	phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
++	write_phy_reg(pi, 0x93d, 0xC0);
++
++	wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
++	write_phy_reg(pi, 0x6da, 0xffff);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
++	udelay(500);
++	phy_c28 = read_phy_reg(pi, 0x938);
++	phy_c29 = read_phy_reg(pi, 0x4d7);
++	phy_c30 = read_phy_reg(pi, 0x4d8);
++	or_phy_reg(pi, 0x938, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 3);
++	mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
++	or_phy_reg(pi, 0x4d8, 1 << 0);
++	or_phy_reg(pi, 0x4d8, 1 << 1);
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
++	phy_c1 = &lcnphy_spb_tone_3750[0];
++	phy_c4 = 32;
++
++	if (num_levels == 0) {
++		if (cal_type != 0)
++			num_levels = 4;
++		else
++			num_levels = 9;
++	}
++	if (step_size_lg2 == 0) {
++		if (cal_type != 0)
++			step_size_lg2 = 3;
++		else
++			step_size_lg2 = 8;
++	}
++
++	phy_c7 = (1 << step_size_lg2);
++	phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
++	phy_c15 = (s16) phy_c3.re;
++	phy_c16 = (s16) phy_c3.im;
++	if (cal_type == 2) {
++		if (phy_c3.re > 127)
++			phy_c15 = phy_c3.re - 256;
++		if (phy_c3.im > 127)
++			phy_c16 = phy_c3.im - 256;
++	}
++	wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++	udelay(20);
++	for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
++		phy_c23 = true;
++		phy_c22 = false;
++		switch (cal_type) {
++		case 0:
++			phy_c10 = 511;
++			break;
++		case 2:
++			phy_c10 = 127;
++			break;
++		case 3:
++			phy_c10 = 15;
++			break;
++		case 4:
++			phy_c10 = 15;
++			break;
++		}
++
++		phy_c9 = read_phy_reg(pi, 0x93d);
++		phy_c9 = 2 * phy_c9;
++		phy_c24 = false;
++		phy_c5 = 7;
++		phy_c25 = true;
++		while (1) {
++			write_radio_reg(pi, RADIO_2064_REG026,
++					(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
++			udelay(50);
++			phy_c22 = false;
++			ptr[130] = 0;
++			wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
++			if (ptr[130] == 1)
++				phy_c22 = true;
++			if (phy_c22)
++				phy_c5 -= 1;
++			if ((phy_c22 != phy_c24) && (!phy_c25))
++				break;
++			if (!phy_c22)
++				phy_c5 += 1;
++			if (phy_c5 <= 0 || phy_c5 >= 7)
++				break;
++			phy_c24 = phy_c22;
++			phy_c25 = false;
++		}
++
++		if (phy_c5 < 0)
++			phy_c5 = 0;
++		else if (phy_c5 > 7)
++			phy_c5 = 7;
++
++		for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
++			for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
++				phy_c11 = phy_c15 + k;
++				phy_c12 = phy_c16 + l;
++
++				if (phy_c11 < -phy_c10)
++					phy_c11 = -phy_c10;
++				else if (phy_c11 > phy_c10)
++					phy_c11 = phy_c10;
++				if (phy_c12 < -phy_c10)
++					phy_c12 = -phy_c10;
++				else if (phy_c12 > phy_c10)
++					phy_c12 = phy_c10;
++				wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
++						  phy_c12);
++				udelay(20);
++				wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
++
++				phy_c18 = 0;
++				phy_c19 = 0;
++				for (j = 0; j < 128; j++) {
++					if (cal_type != 0)
++						phy_c6 = j % phy_c4;
++					else
++						phy_c6 = (2 * j) % phy_c4;
++
++					phy_c2.re = phy_c1[phy_c6].re;
++					phy_c2.im = phy_c1[phy_c6].im;
++					phy_c17 = ptr[j];
++					phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
++					phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
++				}
++
++				phy_c18 = phy_c18 >> 10;
++				phy_c19 = phy_c19 >> 10;
++				phy_c20 = ((phy_c18 * phy_c18) +
++					   (phy_c19 * phy_c19));
++
++				if (phy_c23 || phy_c20 < phy_c21) {
++					phy_c21 = phy_c20;
++					phy_c13 = phy_c11;
++					phy_c14 = phy_c12;
++				}
++				phy_c23 = false;
++			}
++		}
++		phy_c23 = true;
++		phy_c15 = phy_c13;
++		phy_c16 = phy_c14;
++		phy_c7 = phy_c7 >> 1;
++		wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++		udelay(20);
++	}
++	goto cleanup;
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
++	wlc_lcnphy_stop_tx_tone(pi);
++	write_phy_reg(pi, 0x6da, phy_c26);
++	write_phy_reg(pi, 0x6db, phy_c27);
++	write_phy_reg(pi, 0x938, phy_c28);
++	write_phy_reg(pi, 0x4d7, phy_c29);
++	write_phy_reg(pi, 0x4d8, phy_c30);
++	write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
++
++	kfree(phy_c32);
++	kfree(ptr);
++}
++
++void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b)
++{
++	u16 iqcc[2];
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_id = 0;
++	tab.tbl_offset = 80;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	*a = iqcc[0];
++	*b = iqcc[1];
++}
++
++static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi)
++{
++	struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
++
++	wlc_lcnphy_set_cc(pi, 0, 0, 0);
++	wlc_lcnphy_set_cc(pi, 2, 0, 0);
++	wlc_lcnphy_set_cc(pi, 3, 0, 0);
++	wlc_lcnphy_set_cc(pi, 4, 0, 0);
++
++	wlc_lcnphy_a1(pi, 4, 0, 0);
++	wlc_lcnphy_a1(pi, 3, 0, 0);
++	wlc_lcnphy_a1(pi, 2, 3, 2);
++	wlc_lcnphy_a1(pi, 0, 5, 8);
++	wlc_lcnphy_a1(pi, 2, 2, 1);
++	wlc_lcnphy_a1(pi, 0, 4, 3);
++
++	iqcc0 = wlc_lcnphy_get_cc(pi, 0);
++	locc2 = wlc_lcnphy_get_cc(pi, 2);
++	locc3 = wlc_lcnphy_get_cc(pi, 3);
++	locc4 = wlc_lcnphy_get_cc(pi, 4);
++}
++
++u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u16 didq;
++
++	tab.tbl_id = 0;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return didq;
++}
++
++static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
++{
++
++	struct lcnphy_txgains target_gains, old_gains;
++	u8 save_bb_mult;
++	u16 a, b, didq, save_pa_gain = 0;
++	uint idx, SAVE_txpwrindex = 0xFF;
++	u32 val;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct phytbl_info tab;
++	u8 ei0, eq0, fi0, fq0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++	save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	save_bb_mult = wlc_lcnphy_get_bbmult(pi);
++
++	if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
++		SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	target_gains.gm_gain = 7;
++	target_gains.pga_gain = 0;
++	target_gains.pad_gain = 21;
++	target_gains.dac_gain = 0;
++	wlc_lcnphy_set_tx_gain(pi, &target_gains);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
++
++		wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++				       (pi_lcn->
++					lcnphy_recal ? LCNPHY_CAL_RECAL :
++					LCNPHY_CAL_FULL), false);
++	} else {
++		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++	}
++
++	wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
++	if ((abs((s8) fi0) == 15) && (abs((s8) fq0) == 15)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			target_gains.gm_gain = 255;
++			target_gains.pga_gain = 255;
++			target_gains.pad_gain = 0xf0;
++			target_gains.dac_gain = 0;
++		} else {
++			target_gains.gm_gain = 7;
++			target_gains.pga_gain = 45;
++			target_gains.pad_gain = 186;
++			target_gains.dac_gain = 0;
++		}
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 1)
++		    || pi_lcn->lcnphy_hw_iqcal_en) {
++
++			target_gains.pga_gain = 0;
++			target_gains.pad_gain = 30;
++			wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++			wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++					       LCNPHY_CAL_FULL, false);
++		} else {
++			wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++		}
++	}
++
++	wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++
++	didq = wlc_lcnphy_get_tx_locc(pi);
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &val;
++
++	tab.tbl_len = 1;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++
++	for (idx = 0; idx < 128; idx++) {
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
++
++		wlc_lcnphy_read_table(pi, &tab);
++		val = (val & 0xfff00000) |
++		      ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = didq;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
++	pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
++	pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
++	pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
++
++	wlc_lcnphy_set_bbmult(pi, save_bb_mult);
++	wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++
++	if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++	else
++		wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
++}
++
++s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s16 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (s16) (tempsenseval1 - 512);
++	else
++		avg = (s16) tempsenseval1;
++
++	if (tempsenseval2 > 255)
++		avg += (s16) (tempsenseval2 - 512);
++	else
++		avg += (s16) tempsenseval2;
++
++	avg /= 2;
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return avg;
++}
++
++u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s32 avg = 0;
++	bool suspend = false;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (int)(tempsenseval1 - 512);
++	else
++		avg = (int)tempsenseval1;
++
++	if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg - tempsenseval2 + 512);
++		else
++			avg = (int)(avg - tempsenseval2);
++	} else {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg + tempsenseval2 - 512);
++		else
++			avg = (int)(avg + tempsenseval2);
++		avg = avg / 2;
++	}
++	if (avg < 0)
++		avg = avg + 512;
++
++	if (pi_lcn->lcnphy_tempsense_option == 2)
++		avg = tempsenseval1;
++
++	if (mode)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (u16) avg;
++}
++
++s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode)
++{
++	s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
++	degree =
++		((degree <<
++		  10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
++		/ LCN_TEMPSENSE_DEN;
++	return (s8) degree;
++}
++
++s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
++{
++	u16 vbatsenseval;
++	s32 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
++	}
++
++	vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
++
++	if (vbatsenseval > 255)
++		avg = (s32) (vbatsenseval - 512);
++	else
++		avg = (s32) vbatsenseval;
++
++	avg =	(avg * LCN_VBAT_SCALE_NOM +
++		 (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
++
++	if (mode == 1) {
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (s8) avg;
++}
++
++static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode)
++{
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
++
++	if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
++	    (mode == AFE_CLK_INIT_MODE_TXRX2X))
++		write_phy_reg(pi, 0x6d0, 0x7);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++}
++
++static void wlc_lcnphy_temp_adj(struct brcms_phy *pi)
++{
++}
++
++static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
++{
++	bool suspend;
++	s8 index;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_deaf_mode(pi, true);
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	index = pi_lcn->lcnphy_current_index;
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++}
++
++static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
++{
++	bool suspend, full_cal;
++	const struct lcnphy_rx_iqcomp *rx_iqcomp;
++	int rx_iqcomp_sz;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	full_cal =
++		(pi_lcn->lcnphy_full_cal_channel !=
++		 CHSPEC_CHANNEL(pi->radio_chanspec));
++	pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++	index = pi_lcn->lcnphy_current_index;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend) {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
++	rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
++	else
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++
++		wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++	}
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode)
++{
++	u16 temp_new;
++	int temp1, temp2, temp_diff;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	switch (mode) {
++	case PHY_PERICAL_CHAN:
++		break;
++	case PHY_FULLCAL:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_PHYINIT:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_WATCHDOG:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++			temp_new = wlc_lcnphy_tempsense(pi, 0);
++			temp1 = LCNPHY_TEMPSENSE(temp_new);
++			temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
++			temp_diff = temp1 - temp2;
++			if ((pi_lcn->lcnphy_cal_counter > 90) ||
++			    (temp_diff > 60) || (temp_diff < -60)) {
++				wlc_lcnphy_glacial_timer_based_cal(pi);
++				wlc_2064_vco_cal(pi);
++				pi_lcn->lcnphy_cal_temper = temp_new;
++				pi_lcn->lcnphy_cal_counter = 0;
++			} else
++				pi_lcn->lcnphy_cal_counter++;
++		}
++		break;
++	case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++			wlc_lcnphy_tx_power_adjustment(
++				(struct brcms_phy_pub *) pi);
++		break;
++	}
++}
++
++void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr)
++{
++	s8 cck_offset;
++	u16 status;
++	status = (read_phy_reg(pi, 0x4ab));
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    (status  & (0x1 << 15))) {
++		*ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++				   >> 0) >> 1);
++
++		if (wlc_phy_tpc_isenabled_lcnphy(pi))
++			cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
++		else
++			cck_offset = 0;
++
++		*cck_pwr = *ofdm_pwr + cck_offset;
++	} else {
++		*cck_pwr = 0;
++		*ofdm_pwr = 0;
++	}
++}
++
++void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi)
++{
++	return;
++
++}
++
++void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
++{
++	s8 index;
++	u16 index2;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    SAVE_txpwrctrl) {
++		index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++		index2 = (u16) (index * 2);
++		mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++		pi_lcn->lcnphy_current_index =
++			(s8)((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
++	}
++}
++
++static void
++wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
++			      const struct lcnphy_tx_gain_tbl_entry *gain_table)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 val;
++	u16 pa_gain;
++	u16 gm_gain;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		pa_gain = 0x70;
++	else
++		pa_gain = 0x70;
++
++	if (pi->sh->boardflags & BFL_FEM)
++		pa_gain = 0x10;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++
++	for (j = 0; j < 128; j++) {
++		gm_gain = gain_table[j].gm;
++		val = (((u32) pa_gain << 24) |
++		       (gain_table[j].pad << 16) |
++		       (gain_table[j].pga << 8) | gm_gain);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 val, bbmult, rfgain;
++	u8 index;
++	u8 scale_factor = 1;
++	s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	for (index = 0; index < 128; index++) {
++		tab.tbl_ptr = &bbmult;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++		bbmult = bbmult >> 20;
++
++		tab.tbl_ptr = &rfgain;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
++		qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
++
++		if (qQ1 < qQ2) {
++			temp2 = qm_shr16(temp2, qQ2 - qQ1);
++			qQ = qQ1;
++		} else {
++			temp1 = qm_shr16(temp1, qQ1 - qQ2);
++			qQ = qQ2;
++		}
++		temp = qm_sub16(temp1, temp2);
++
++		if (qQ >= 4)
++			shift = qQ - 4;
++		else
++			shift = 4 - qQ;
++
++		val = (((index << shift) + (5 * temp) +
++			(1 << (scale_factor + shift - 3))) >> (scale_factor +
++							       shift - 2));
++
++		tab.tbl_ptr = &val;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi)
++{
++	or_phy_reg(pi, 0x805, 0x1);
++
++	mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
++
++	mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
++
++	write_phy_reg(pi, 0x414, 0x1e10);
++	write_phy_reg(pi, 0x415, 0x0640);
++
++	mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++	mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
++
++	mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
++
++	if (!(pi->sh->boardrev < 0x1204))
++		mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
++
++	write_phy_reg(pi, 0x7d6, 0x0902);
++	mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
++
++	mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
++
++		mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
++
++		mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
++
++		mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++		mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
++		mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
++		mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
++
++		mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++		mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
++
++	}
++}
++
++static void wlc_lcnphy_rcal(struct brcms_phy *pi)
++{
++	u8 rcal_value;
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	or_radio_reg(pi, RADIO_2064_REG004, 0x40);
++	or_radio_reg(pi, RADIO_2064_REG120, 0x10);
++
++	or_radio_reg(pi, RADIO_2064_REG078, 0x80);
++	or_radio_reg(pi, RADIO_2064_REG129, 0x02);
++
++	or_radio_reg(pi, RADIO_2064_REG057, 0x01);
++
++	or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
++	mdelay(5);
++	SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
++
++	if (wlc_radio_2064_rcal_done(pi)) {
++		rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
++		rcal_value = rcal_value & 0x1f;
++	}
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
++}
++
++static void wlc_lcnphy_rc_cal(struct brcms_phy *pi)
++{
++	u8 dflt_rc_cal_val;
++	u16 flt_val;
++
++	dflt_rc_cal_val = 7;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		dflt_rc_cal_val = 11;
++	flt_val =
++		(dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
++		(dflt_rc_cal_val);
++	write_phy_reg(pi, 0x933, flt_val);
++	write_phy_reg(pi, 0x934, flt_val);
++	write_phy_reg(pi, 0x935, flt_val);
++	write_phy_reg(pi, 0x936, flt_val);
++	write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
++
++	return;
++}
++
++static void wlc_radio_2064_init(struct brcms_phy *pi)
++{
++	u32 i;
++	const struct lcnphy_radio_regs *lcnphyregs = NULL;
++
++	lcnphyregs = lcnphy_radio_regs_2064;
++
++	for (i = 0; lcnphyregs[i].address != 0xffff; i++)
++		if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_a);
++		else if (lcnphyregs[i].do_init_g)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_g);
++
++	write_radio_reg(pi, RADIO_2064_REG032, 0x62);
++	write_radio_reg(pi, RADIO_2064_REG033, 0x19);
++
++	write_radio_reg(pi, RADIO_2064_REG090, 0x10);
++
++	write_radio_reg(pi, RADIO_2064_REG010, 0x00);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++
++		write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
++		write_radio_reg(pi, RADIO_2064_REG061, 0x72);
++		write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
++	write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
++
++	write_phy_reg(pi, 0x4ea, 0x4688);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
++
++	mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
++
++	wlc_lcnphy_set_tx_locc(pi, 0);
++
++	wlc_lcnphy_rcal(pi);
++
++	wlc_lcnphy_rc_cal(pi);
++}
++
++static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
++{
++	wlc_radio_2064_init(pi);
++}
++
++static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
++{
++	uint idx;
++	u8 phybw40;
++	struct phytbl_info tab;
++	u32 val;
++
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++)
++		wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
++
++	if (pi->sh->boardflags & BFL_FEM_BT) {
++		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++		tab.tbl_width = 16;
++		tab.tbl_ptr = &val;
++		tab.tbl_len = 1;
++		val = 100;
++		tab.tbl_offset = 4;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &val;
++	tab.tbl_len = 1;
++
++	val = 114;
++	tab.tbl_offset = 0;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 130;
++	tab.tbl_offset = 1;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 6;
++	tab.tbl_offset = 8;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->sh->boardflags & BFL_FEM)
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_extPA_gaintable_rev0);
++		else
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_gaintable_rev0);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		const struct phytbl_info *tb;
++		int l;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			l = dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_2G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_2G_rev2;
++		} else {
++			l = dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_5G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_5G_rev2;
++		}
++
++		for (idx = 0; idx < l; idx++)
++			wlc_lcnphy_write_table(pi, &tb[idx]);
++	}
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && !(pi->sh->boardflags & BFL_FEM_BT))
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
++	else if (pi->sh->boardflags & BFL_FEM_BT) {
++		if (pi->sh->boardrev < 0x1250)
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
++		else
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
++	} else
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
++
++	wlc_lcnphy_load_rfpower(pi);
++
++	wlc_lcnphy_clear_papd_comptable(pi);
++}
++
++static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi)
++{
++	u16 afectrl1;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
++
++	write_phy_reg(pi, 0x43b, 0x0);
++	write_phy_reg(pi, 0x43c, 0x0);
++	write_phy_reg(pi, 0x44c, 0x0);
++	write_phy_reg(pi, 0x4e6, 0x0);
++	write_phy_reg(pi, 0x4f9, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x938, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x44e, 0);
++
++	or_phy_reg(pi, 0x567, 0x03);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	if (!(pi->sh->boardflags & BFL_FEM))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
++
++	if (0) {
++		afectrl1 = 0;
++		afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
++				  (pi_lcn->lcnphy_rssi_vc << 4) |
++				  (pi_lcn->lcnphy_rssi_gs << 10));
++		write_phy_reg(pi, 0x43e, afectrl1);
++	}
++
++	mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
++	if (pi->sh->boardflags & BFL_FEM) {
++		mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
++
++		write_phy_reg(pi, 0x910, 0x1);
++	}
++
++	mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
++	mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
++	mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
++
++}
++
++static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
++		mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
++	}
++}
++
++static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi)
++{
++	s16 temp;
++	struct phytbl_info tab;
++	u32 tableBuffer[2];
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	temp = (s16) read_phy_reg(pi, 0x4df);
++	pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
++
++	if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
++		pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
++
++	pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
++
++	if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
++		pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = 17;
++	tab.tbl_offset = 59;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	if (tableBuffer[0] > 63)
++		tableBuffer[0] -= 128;
++	pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
++
++	if (tableBuffer[1] > 63)
++		tableBuffer[1] -= 128;
++	pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
++
++	temp = (s16) (read_phy_reg(pi, 0x434) & (0xff << 0));
++	if (temp > 127)
++		temp -= 256;
++	pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
++
++	pi_lcn->lcnphy_Med_Low_Gain_db =
++		(read_phy_reg(pi, 0x424) & (0xff << 8)) >> 8;
++	pi_lcn->lcnphy_Very_Low_Gain_db =
++		(read_phy_reg(pi, 0x425) & (0xff << 0)) >> 0;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
++	tab.tbl_offset = 28;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
++	pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
++
++}
++
++static void wlc_lcnphy_baseband_init(struct brcms_phy *pi)
++{
++
++	wlc_lcnphy_tbl_init(pi);
++	wlc_lcnphy_rev0_baseband_init(pi);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		wlc_lcnphy_rev2_baseband_init(pi);
++	wlc_lcnphy_bu_tweaks(pi);
++}
++
++void wlc_phy_init_lcnphy(struct brcms_phy *pi)
++{
++	u8 phybw40;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	pi_lcn->lcnphy_cal_counter = 0;
++	pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
++
++	or_phy_reg(pi, 0x44a, 0x80);
++	and_phy_reg(pi, 0x44a, 0x7f);
++
++	wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
++
++	write_phy_reg(pi, 0x60a, 160);
++
++	write_phy_reg(pi, 0x46a, 25);
++
++	wlc_lcnphy_baseband_init(pi);
++
++	wlc_lcnphy_radio_init(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi);
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
++
++	si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
++
++	wlc_lcnphy_agc_temp_init(pi);
++
++	wlc_lcnphy_temp_adj(pi);
++
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++	udelay(100);
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
++	wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
++}
++
++static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
++{
++	s8 txpwr = 0;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 cckpo = 0;
++		u32 offset_ofdm, offset_mcs;
++
++		pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso;
++
++		pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g;
++
++		pi->txpa_2g[0] = sprom->pa0b0;
++		pi->txpa_2g[1] = sprom->pa0b1;
++		pi->txpa_2g[2] = sprom->pa0b2;
++
++		pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g;
++		pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g;
++		pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g;
++
++		pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
++
++		pi_lcn->lcnphy_rssi_vf_hightemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
++
++		txpwr = sprom->core_pwr_info[0].maxpwr_2g;
++		pi->tx_srom_max_2g = txpwr;
++
++		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
++			pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
++			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
++		}
++
++		cckpo = sprom->cck2gpo;
++		offset_ofdm = sprom->ofdm2gpo;
++		if (cckpo) {
++			uint max_pwr_chan = txpwr;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan - ((cckpo & 0xf) * 2);
++				cckpo >>= 4;
++			}
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan -
++					((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++		} else {
++			u8 opo = 0;
++
++			opo = sprom->opo;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
++				pi->tx_srom_max_rate_2g[i] = txpwr;
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] = txpwr -
++						((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++			offset_mcs = sprom->mcs2gpo[1] << 16;
++			offset_mcs |= sprom->mcs2gpo[0];
++			pi_lcn->lcnphy_mcs20_po = offset_mcs;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					txpwr - ((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++
++		pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense;
++		pi_lcn->lcnphy_measPower = sprom->measpower;
++		pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope;
++		pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en;
++		pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis;
++		pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx;
++		pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option;
++		pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr;
++		if (sprom->ant_available_bg > 1)
++			wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
++				sprom->ant_available_bg);
++	}
++	pi_lcn->lcnphy_cck_dig_filt_type = -1;
++
++	return true;
++}
++
++void wlc_2064_vco_cal(struct brcms_phy *pi)
++{
++	u8 calnrst;
++
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
++	calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
++	udelay(300);
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
++}
++
++bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi)
++{
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return 0;
++	else
++		return (LCNPHY_TX_PWR_CTRL_HW ==
++			wlc_lcnphy_get_tx_pwr_ctrl((pi)));
++}
++
++void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
++{
++	u16 pwr_ctrl;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++		wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++	} else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++		pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++		wlc_lcnphy_txpower_recalc_target(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
++	}
++}
++
++void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
++{
++	kfree(pi->u.pi_lcnphy);
++}
++
++bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn;
++
++	pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC);
++	if (pi->u.pi_lcnphy == NULL)
++		return false;
++
++	pi_lcn = pi->u.pi_lcnphy;
++
++	if (0 == (pi->sh->boardflags & BFL_NOPA)) {
++		pi->hwpwrctrl = true;
++		pi->hwpwrctrl_capable = true;
++	}
++
++	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
++	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
++
++	pi->pi_fptr.init = wlc_phy_init_lcnphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
++	pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
++	pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
++	pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
++	pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
++	pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
++
++	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
++		return false;
++
++	if ((pi->sh->boardflags & BFL_FEM) &&
++	    (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
++		if (pi_lcn->lcnphy_tempsense_option == 3) {
++			pi->hwpwrctrl = true;
++			pi->hwpwrctrl_capable = true;
++			pi->temppwrctrl_capable = false;
++		} else {
++			pi->hwpwrctrl = false;
++			pi->hwpwrctrl_capable = false;
++			pi->temppwrctrl_capable = true;
++		}
++	}
++
++	return true;
++}
++
++static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain)
++{
++	u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
++
++	trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
++	ext_lna = (u16) (gain >> 29) & 0x01;
++	lna1 = (u16) (gain >> 0) & 0x0f;
++	lna2 = (u16) (gain >> 4) & 0x0f;
++	tia = (u16) (gain >> 8) & 0xf;
++	biq0 = (u16) (gain >> 12) & 0xf;
++	biq1 = (u16) (gain >> 16) & 0xf;
++
++	gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
++			  ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
++			  ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
++	gain16_19 = biq1;
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++		mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
++	}
++	wlc_lcnphy_rx_gain_override_enable(pi, true);
++}
++
++static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index)
++{
++	u32 received_power = 0;
++	s32 max_index = 0;
++	u32 gain_code = 0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	max_index = 36;
++	if (*gain_index >= 0)
++		gain_code = lcnphy_23bitgaincode_table[*gain_index];
++
++	if (-1 == *gain_index) {
++		*gain_index = 0;
++		while ((*gain_index <= (s32) max_index)
++		       && (received_power < 700)) {
++			wlc_lcnphy_set_rx_gain(pi,
++					       lcnphy_23bitgaincode_table
++					       [*gain_index]);
++			received_power =
++				wlc_lcnphy_measure_digital_power(
++					pi,
++					pi_lcn->
++					lcnphy_noise_samples);
++			(*gain_index)++;
++		}
++		(*gain_index)--;
++	} else {
++		wlc_lcnphy_set_rx_gain(pi, gain_code);
++		received_power =
++			wlc_lcnphy_measure_digital_power(pi,
++							 pi_lcn->
++							 lcnphy_noise_samples);
++	}
++
++	return received_power;
++}
++
++s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index)
++{
++	s32 gain = 0;
++	s32 nominal_power_db;
++	s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
++	    input_power_db;
++	s32 received_power, temperature;
++	u32 power;
++	u32 msb1, msb2, val1, val2, diff1, diff2;
++	uint freq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
++
++	gain = lcnphy_gain_table[gain_index];
++
++	nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
++
++	power = (received_power * 16);
++	msb1 = ffs(power) - 1;
++	msb2 = msb1 + 1;
++	val1 = 1 << msb1;
++	val2 = 1 << msb2;
++	diff1 = (power - val1);
++	diff2 = (val2 - power);
++	if (diff1 < diff2)
++		log_val = msb1;
++	else
++		log_val = msb2;
++
++	log_val = log_val * 3;
++
++	gain_mismatch = (nominal_power_db / 2) - (log_val);
++
++	desired_gain = gain + gain_mismatch;
++
++	input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
++
++	if (input_power_offset_db > 127)
++		input_power_offset_db -= 256;
++
++	input_power_db = input_power_offset_db - desired_gain;
++
++	input_power_db =
++		input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
++
++	freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
++	if ((freq > 2427) && (freq <= 2467))
++		input_power_db = input_power_db - 1;
++
++	temperature = pi_lcn->lcnphy_lastsensed_temperature;
++
++	if ((temperature - 15) < -30)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			7;
++	else if ((temperature - 15) < 4)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			3;
++	else
++		input_power_db = input_power_db +
++					(((temperature - 10 - 25) * 286) >> 12);
++
++	wlc_lcnphy_rx_gain_override_enable(pi, 0);
++
++	return input_power_db;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+new file mode 100644
+index 0000000..f4a8ab0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_LCN_H_
++#define _BRCM_PHY_LCN_H_
++
++#include <types.h>
++
++struct brcms_phy_lcnphy {
++	int lcnphy_txrf_sp_9_override;
++	u8 lcnphy_full_cal_channel;
++	u8 lcnphy_cal_counter;
++	u16 lcnphy_cal_temper;
++	bool lcnphy_recal;
++
++	u8 lcnphy_rc_cap;
++	u32 lcnphy_mcs20_po;
++
++	u8 lcnphy_tr_isolation_mid;
++	u8 lcnphy_tr_isolation_low;
++	u8 lcnphy_tr_isolation_hi;
++
++	u8 lcnphy_bx_arch;
++	u8 lcnphy_rx_power_offset;
++	u8 lcnphy_rssi_vf;
++	u8 lcnphy_rssi_vc;
++	u8 lcnphy_rssi_gs;
++	u8 lcnphy_tssi_val;
++	u8 lcnphy_rssi_vf_lowtemp;
++	u8 lcnphy_rssi_vc_lowtemp;
++	u8 lcnphy_rssi_gs_lowtemp;
++
++	u8 lcnphy_rssi_vf_hightemp;
++	u8 lcnphy_rssi_vc_hightemp;
++	u8 lcnphy_rssi_gs_hightemp;
++
++	s16 lcnphy_pa0b0;
++	s16 lcnphy_pa0b1;
++	s16 lcnphy_pa0b2;
++
++	u16 lcnphy_rawtempsense;
++	u8 lcnphy_measPower;
++	u8 lcnphy_tempsense_slope;
++	u8 lcnphy_freqoffset_corr;
++	u8 lcnphy_tempsense_option;
++	u8 lcnphy_tempcorrx;
++	bool lcnphy_iqcal_swp_dis;
++	bool lcnphy_hw_iqcal_en;
++	uint lcnphy_bandedge_corr;
++	bool lcnphy_spurmod;
++	u16 lcnphy_tssi_tx_cnt;
++	u16 lcnphy_tssi_idx;
++	u16 lcnphy_tssi_npt;
++
++	u16 lcnphy_target_tx_freq;
++	s8 lcnphy_tx_power_idx_override;
++	u16 lcnphy_noise_samples;
++
++	u32 lcnphy_papdRxGnIdx;
++	u32 lcnphy_papd_rxGnCtrl_init;
++
++	u32 lcnphy_gain_idx_14_lowword;
++	u32 lcnphy_gain_idx_14_hiword;
++	u32 lcnphy_gain_idx_27_lowword;
++	u32 lcnphy_gain_idx_27_hiword;
++	s16 lcnphy_ofdmgainidxtableoffset;
++	s16 lcnphy_dsssgainidxtableoffset;
++	u32 lcnphy_tr_R_gain_val;
++	u32 lcnphy_tr_T_gain_val;
++	s8 lcnphy_input_pwr_offset_db;
++	u16 lcnphy_Med_Low_Gain_db;
++	u16 lcnphy_Very_Low_Gain_db;
++	s8 lcnphy_lastsensed_temperature;
++	s8 lcnphy_pkteng_rssi_slope;
++	u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
++	u8 lcnphy_volt_winner;
++	u8 lcnphy_volt_low;
++	u8 lcnphy_54_48_36_24mbps_backoff;
++	u8 lcnphy_11n_backoff;
++	u8 lcnphy_lowerofdm;
++	u8 lcnphy_cck;
++	u8 lcnphy_psat_2pt3_detected;
++	s32 lcnphy_lowest_Re_div_Im;
++	s8 lcnphy_final_papd_cal_idx;
++	u16 lcnphy_extstxctrl4;
++	u16 lcnphy_extstxctrl0;
++	u16 lcnphy_extstxctrl1;
++	s16 lcnphy_cck_dig_filt_type;
++	s16 lcnphy_ofdm_dig_filt_type;
++	struct lcnphy_cal_results lcnphy_cal_results;
++
++	u8 lcnphy_psat_pwr;
++	u8 lcnphy_psat_indx;
++	s32 lcnphy_min_phase;
++	u8 lcnphy_final_idx;
++	u8 lcnphy_start_idx;
++	u8 lcnphy_current_index;
++	u16 lcnphy_logen_buf_1;
++	u16 lcnphy_local_ovr_2;
++	u16 lcnphy_local_oval_6;
++	u16 lcnphy_local_oval_5;
++	u16 lcnphy_logen_mixer_1;
++
++	u8 lcnphy_aci_stat;
++	uint lcnphy_aci_start_time;
++	s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
++};
++#endif				/* _BRCM_PHY_LCN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+new file mode 100644
+index 0000000..06975af
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+@@ -0,0 +1,28685 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_int.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phyreg_n.h"
++#include "phytbl_n.h"
++#include "soc.h"
++
++#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, radio_type##_##jspace##_##reg_name |	\
++		       ((core == PHY_CORE_0) ? \
++			radio_type##_##jspace##0 : \
++			radio_type##_##jspace##1))
++
++#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
++			((core ==  PHY_CORE_0) ? \
++			 radio_type##_##jspace##0 : \
++			 radio_type##_##jspace##1), value)
++
++#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
++	write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value)
++
++#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			    radio_type##_##jspace##0##_##reg_name : \
++			    radio_type##_##jspace##1##_##reg_name))
++
++#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core ==  PHY_CORE_0) ? \
++			     radio_type##_##jspace##0##_##reg_name : \
++			     radio_type##_##jspace##1##_##reg_name), \
++			value)
++
++#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			     radio_type##_##reg_name##_##jspace##0 : \
++			     radio_type##_##reg_name##_##jspace##1))
++
++#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			radio_type##_##reg_name##_##jspace##0 : \
++			radio_type##_##reg_name##_##jspace##1), \
++			value)
++
++#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
++#define NPHY_ACI_CHANNEL_DELTA 5
++#define NPHY_ACI_CHANNEL_SKIP 4
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
++#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
++#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_NOASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH  400
++
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
++
++#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
++
++#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
++
++#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
++
++#define NPHY_RSSICAL_MAXREAD 31
++
++#define NPHY_RSSICAL_NPOLL 8
++#define NPHY_RSSICAL_MAXD  (1<<20)
++#define NPHY_MIN_RXIQ_PWR 2
++
++#define NPHY_RSSICAL_W1_TARGET 25
++#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
++#define NPHY_RSSICAL_NB_TARGET 0
++
++#define NPHY_RSSICAL_W1_TARGET_REV3 29
++#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
++
++#define NPHY_CALSANITY_RSSI_NB_MAX_POS  9
++#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
++#define NPHY_CALSANITY_RSSI_W1_MAX_POS  12
++#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_CALSANITY_RSSI_W2_MAX_POS  NPHY_CALSANITY_RSSI_W1_MAX_POS
++#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
++#define NPHY_RSSI_NB_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
++#define NPHY_RSSI_W1_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
++#define NPHY_RSSI_W2_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
++
++#define NPHY_IQCAL_NUMGAINS 9
++#define NPHY_N_GCTL 0x66
++
++#define NPHY_PAPD_EPS_TBL_SIZE 64
++#define NPHY_PAPD_SCL_TBL_SIZE 64
++#define NPHY_NUM_DIG_FILT_COEFFS 15
++
++#define NPHY_PAPD_COMP_OFF 0
++#define NPHY_PAPD_COMP_ON  1
++
++#define NPHY_SROM_TEMPSHIFT             32
++#define NPHY_SROM_MAXTEMPOFFSET         16
++#define NPHY_SROM_MINTEMPOFFSET         -16
++
++#define NPHY_CAL_MAXTEMPDELTA           64
++
++#define NPHY_NOISEVAR_TBLLEN40 256
++#define NPHY_NOISEVAR_TBLLEN20 128
++
++#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
++
++#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
++
++/* 5357 Chip specific ChipControl register bits */
++#define CCTRL5357_EXTPA            (1<<14) /* extPA in ChipControl 1, bit 14 */
++#define CCTRL5357_ANT_MUX_2o3      (1<<15) /* 2o3 in ChipControl 1, bit 15 */
++
++#define NPHY_CAL_TSSISAMPS      64
++#define NPHY_TEST_TONE_FREQ_40MHz 4000
++#define NPHY_TEST_TONE_FREQ_20MHz 2500
++
++#define MAX_205x_RCAL_WAITLOOPS 10000
++
++#define NPHY_RXCAL_TONEAMP 181
++#define NPHY_RXCAL_TONEFREQ_40MHz 4000
++#define NPHY_RXCAL_TONEFREQ_20MHz 2000
++
++#define TXFILT_SHAPING_OFDM20   0
++#define TXFILT_SHAPING_OFDM40   1
++#define TXFILT_SHAPING_CCK      2
++#define TXFILT_DEFAULT_OFDM20   3
++#define TXFILT_DEFAULT_OFDM40   4
++
++struct nphy_iqcal_params {
++	u16 txlpf;
++	u16 txgm;
++	u16 pga;
++	u16 pad;
++	u16 ipa;
++	u16 cal_gain;
++	u16 ncorr[5];
++};
++
++struct nphy_txiqcal_ladder {
++	u8 percent;
++	u8 g_env;
++};
++
++struct nphy_ipa_txcalgains {
++	struct nphy_txgains gains;
++	bool useindex;
++	u8 index;
++};
++
++struct nphy_papd_restore_state {
++	u16 fbmix[2];
++	u16 vga_master[2];
++	u16 intpa_master[2];
++	u16 afectrl[2];
++	u16 afeoverride[2];
++	u16 pwrup[2];
++	u16 atten[2];
++	u16 mm;
++};
++
++struct nphy_ipa_txrxgain {
++	u16 hpvga;
++	u16 lpf_biq1;
++	u16 lpf_biq0;
++	u16 lna2;
++	u16 lna1;
++	s8 txpwrindex;
++};
++
++#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 2, 3, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = {
++	{0, 0, 0, 0, 0, 128},
++	{0, 0, 0, 0, 0, 70},
++	{0, 0, 0, 0, 0, 20},
++	{0, 0, 0, 3, 0, 20},
++	{0, 0, 3, 3, 0, 20},
++	{0, 2, 3, 3, 0, 20}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 0, 5, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 10},
++	{0, 0, 0, 1, 0, 10},
++	{0, 0, 1, 2, 0, 10},
++	{0, 0, 1, 3, 0, 10},
++	{0, 0, 4, 3, 0, 10},
++	{0, 0, 6, 3, 0, 10}
++};
++
++enum {
++	NPHY_RXCAL_GAIN_INIT = 0,
++	NPHY_RXCAL_GAIN_UP,
++	NPHY_RXCAL_GAIN_DOWN
++};
++
++#define wlc_phy_get_papd_nphy(pi) \
++	(read_phy_reg((pi), 0x1e7) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++static const u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
++	{-377, 137, -407, 208, -1527, 956, 93, 186, 93,
++	 230, -44, 230, 201, -191, 201},
++	{-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
++	 26, 34, -32, 34},
++	{-360, 164, -376, 164, -1533, 576, 308, -314, 308,
++	 121, -73, 121, 91, 124, 91},
++	{-295, 200, -363, 142, -1391, 826, 151, 301, 151,
++	 151, 301, 151, 602, -752, 602},
++	{-92, 58, -96, 49, -104, 44, 17, 35, 17,
++	 12, 25, 12, 13, 27, 13},
++	{-375, 136, -399, 209, -1479, 949, 130, 260, 130,
++	 230, -44, 230, 201, -191, 201},
++	{0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
++	 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
++};
++
++struct chan_info_nphy_2055 {
++	u16 chan;
++	u16 freq;
++	uint unknown;
++	u8 RF_pll_ref;
++	u8 RF_rf_pll_mod1;
++	u8 RF_rf_pll_mod0;
++	u8 RF_vco_cap_tail;
++	u8 RF_vco_cal1;
++	u8 RF_vco_cal2;
++	u8 RF_pll_lf_c1;
++	u8 RF_pll_lf_r1;
++	u8 RF_pll_lf_c2;
++	u8 RF_lgbuf_cen_buf;
++	u8 RF_lgen_tune1;
++	u8 RF_lgen_tune2;
++	u8 RF_core1_lgbuf_a_tune;
++	u8 RF_core1_lgbuf_g_tune;
++	u8 RF_core1_rxrf_reg1;
++	u8 RF_core1_tx_pga_pad_tn;
++	u8 RF_core1_tx_mx_bgtrim;
++	u8 RF_core2_lgbuf_a_tune;
++	u8 RF_core2_lgbuf_g_tune;
++	u8 RF_core2_rxrf_reg1;
++	u8 RF_core2_tx_pga_pad_tn;
++	u8 RF_core2_tx_mx_bgtrim;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio205x {
++	u16 chan;
++	u16 freq;
++	u8 RF_SYN_pll_vcocal1;
++	u8 RF_SYN_pll_vcocal2;
++	u8 RF_SYN_pll_refdiv;
++	u8 RF_SYN_pll_mmd2;
++	u8 RF_SYN_pll_mmd1;
++	u8 RF_SYN_pll_loopfilter1;
++	u8 RF_SYN_pll_loopfilter2;
++	u8 RF_SYN_pll_loopfilter3;
++	u8 RF_SYN_pll_loopfilter4;
++	u8 RF_SYN_pll_loopfilter5;
++	u8 RF_SYN_reserved_addr27;
++	u8 RF_SYN_reserved_addr28;
++	u8 RF_SYN_reserved_addr29;
++	u8 RF_SYN_logen_VCOBUF1;
++	u8 RF_SYN_logen_MIXER2;
++	u8 RF_SYN_logen_BUF3;
++	u8 RF_SYN_logen_BUF4;
++	u8 RF_RX0_lnaa_tune;
++	u8 RF_RX0_lnag_tune;
++	u8 RF_TX0_intpaa_boost_tune;
++	u8 RF_TX0_intpag_boost_tune;
++	u8 RF_TX0_pada_boost_tune;
++	u8 RF_TX0_padg_boost_tune;
++	u8 RF_TX0_pgaa_boost_tune;
++	u8 RF_TX0_pgag_boost_tune;
++	u8 RF_TX0_mixa_boost_tune;
++	u8 RF_TX0_mixg_boost_tune;
++	u8 RF_RX1_lnaa_tune;
++	u8 RF_RX1_lnag_tune;
++	u8 RF_TX1_intpaa_boost_tune;
++	u8 RF_TX1_intpag_boost_tune;
++	u8 RF_TX1_pada_boost_tune;
++	u8 RF_TX1_padg_boost_tune;
++	u8 RF_TX1_pgaa_boost_tune;
++	u8 RF_TX1_pgag_boost_tune;
++	u8 RF_TX1_mixa_boost_tune;
++	u8 RF_TX1_mixg_boost_tune;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_mx5g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_logen_indbuf5g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_pga_boost_tune_core0;
++	u8 RF_txmix5g_boost_tune_core0;
++	u8 RF_pad5g_tune_misc_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_lna5g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_pga_boost_tune_core1;
++	u8 RF_txmix5g_boost_tune_core1;
++	u8 RF_pad5g_tune_misc_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u8 RF_lna5g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057_rev5 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct nphy_sfo_cfg {
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++static const struct chan_info_nphy_2055 chan_info_nphy_2055[] = {
++	{
++	 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
++	{
++	 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
++	{
++	 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
++	{
++	 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
++	{
++	 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
++	{
++	 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
++	{
++	 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
++	{
++	 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
++	{
++	 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
++	{
++	 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
++	{
++	 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
++	{
++	 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
++	{
++	 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
++	{
++	 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
++	{
++	 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
++	{
++	 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
++	{
++	 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
++	{
++	 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
++	{
++	 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
++	{
++	 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
++	{
++	 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
++	{
++	 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
++	{
++	 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
++	 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
++	{
++	 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
++	{
++	 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
++	{
++	 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
++	{
++	 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
++	{
++	 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
++	{
++	 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
++	{
++	 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
++	{
++	 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
++	{
++	 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
++	{
++	 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
++	{
++	 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
++	{
++	 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
++	{
++	 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
++	{
++	 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
++	{
++	 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
++	{
++	 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
++	{
++	 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
++	{
++	 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
++	{
++	 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
++	{
++	 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
++	{
++	 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
++	{
++	 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
++	{
++	 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
++	{
++	 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
++	{
++	 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
++	{
++	 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
++	{
++	 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
++	{
++	 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
++	{
++	 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
++	{
++	 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
++	{
++	 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
++	{
++	 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
++	{
++	 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
++	{
++	 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
++	{
++	 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
++	{
++	 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
++	{
++	 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
++	{
++	 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
++	{
++	 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
++	{
++	 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
++	{
++	 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
++	{
++	 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
++	{
++	 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
++	{
++	 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
++	{
++	 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
++	{
++	 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
++	{
++	 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
++	{
++	 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
++	{
++	 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
++	{
++	 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
++	{
++	 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
++	{
++	 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
++	{
++	 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
++	{
++	 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
++	{
++	 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
++	{
++	 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
++	{
++	 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
++	{
++	 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
++	{
++	 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
++	{
++	 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
++	{
++	 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
++	{
++	 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
++	{
++	 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
++	{
++	 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
++	{
++	 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
++	{
++	 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
++	{
++	 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
++	{
++	 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
++	{
++	 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
++	{
++	 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
++	{
++	 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
++	{
++	 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
++	{
++	 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
++	{
++	 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
++	{
++	 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
++	{
++	 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
++	{
++	 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
++	{
++	 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
++	{
++	 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
++	{
++	 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
++	 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
++	{
++	 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
++	{
++	 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
++	{
++	 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
++	{
++	 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
++	 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
++	{
++	 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
++	 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
++	{
++	 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
++	 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
++	{
++	 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
++	 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
++	{
++	 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
++	 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
++	{
++	 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
++	 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
++	{
++	 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
++	 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
++	{
++	 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
++	 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
++	{
++	 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
++	 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
++	{
++	 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
++	 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216,
++	 },
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215,
++	 },
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214,
++	 },
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213,
++	 },
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212,
++	 },
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211,
++	 },
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f,
++	 },
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e,
++	 },
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d,
++	 },
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c,
++	 },
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b,
++	 },
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a,
++	 },
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209,
++	 },
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208,
++	 },
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207,
++	 },
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206,
++	 },
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205,
++	 },
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204,
++	 },
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203,
++	 },
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202,
++	 },
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201,
++	 },
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200,
++	 },
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff,
++	 },
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd,
++	 },
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc,
++	 },
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb,
++	 },
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa,
++	 },
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9,
++	 },
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8,
++	 },
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7,
++	 },
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6,
++	 },
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5,
++	 },
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4,
++	 },
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3,
++	 },
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2,
++	 },
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1,
++	 },
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0,
++	 },
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0,
++	 },
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef,
++	 },
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee,
++	 },
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed,
++	 },
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec,
++	 },
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb,
++	 },
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea,
++	 },
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9,
++	 },
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8,
++	 },
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7,
++	 },
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6,
++	 },
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5,
++	 },
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5,
++	 },
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4,
++	 },
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3,
++	 },
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2,
++	 },
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1,
++	 },
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0,
++	 },
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df,
++	 },
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de,
++	 },
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd,
++	 },
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd,
++	 },
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc,
++	 },
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db,
++	 },
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da,
++	 },
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9,
++	 },
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8,
++	 },
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7,
++	 },
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7,
++	 },
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6,
++	 },
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5,
++	 },
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4,
++	 },
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3,
++	 },
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2,
++	 },
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2,
++	 },
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1,
++	 },
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0,
++	 },
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf,
++	 },
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce,
++	 },
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce,
++	 },
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd,
++	 },
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc,
++	 },
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9,
++	 },
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8,
++	 },
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6,
++	 },
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4,
++	 },
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2,
++	 },
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2,
++	 },
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1,
++	 },
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0,
++	 },
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf,
++	 },
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf,
++	 },
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be,
++	 },
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd,
++	 },
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443,
++	 },
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441,
++	 },
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f,
++	 },
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d,
++	 },
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a,
++	 },
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438,
++	 },
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436,
++	 },
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434,
++	 },
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431,
++	 },
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f,
++	 },
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d,
++	 },
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b,
++	 },
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429,
++	 },
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
++	 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev8_2057_rev5[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev9_2057_rev5v1[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216},
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = {
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static struct radio_regs regs_2055[] = {
++	{0x02, 0x80, 0x80, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0x27, 0x27, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x27, 0x27, 0, 0},
++	{0x07, 0x7f, 0x7f, 1, 1},
++	{0x08, 0x7, 0x7, 1, 1},
++	{0x09, 0x7f, 0x7f, 1, 1},
++	{0x0A, 0x7, 0x7, 1, 1},
++	{0x0B, 0x15, 0x15, 0, 0},
++	{0x0C, 0x15, 0x15, 0, 0},
++	{0x0D, 0x4f, 0x4f, 1, 1},
++	{0x0E, 0x5, 0x5, 1, 1},
++	{0x0F, 0x4f, 0x4f, 1, 1},
++	{0x10, 0x5, 0x5, 1, 1},
++	{0x11, 0xd0, 0xd0, 0, 0},
++	{0x12, 0x2, 0x2, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0x40, 0x40, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0xc0, 0xc0, 0, 0},
++	{0x1E, 0xff, 0xff, 0, 0},
++	{0x1F, 0xc0, 0xc0, 0, 0},
++	{0x20, 0xff, 0xff, 0, 0},
++	{0x21, 0xc0, 0xc0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x2c, 0x2c, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0xa4, 0xa4, 0, 0},
++	{0x2E, 0x38, 0x38, 0, 0},
++	{0x2F, 0, 0, 0, 0},
++	{0x30, 0x4, 0x4, 1, 1},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0xa, 0xa, 0, 0},
++	{0x33, 0x87, 0x87, 0, 0},
++	{0x34, 0x9, 0x9, 0, 0},
++	{0x35, 0x70, 0x70, 0, 0},
++	{0x36, 0x11, 0x11, 0, 0},
++	{0x37, 0x18, 0x18, 1, 1},
++	{0x38, 0x6, 0x6, 0, 0},
++	{0x39, 0x4, 0x4, 1, 1},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0x9e, 0x9e, 0, 0},
++	{0x3C, 0x9, 0x9, 0, 0},
++	{0x3D, 0xc8, 0xc8, 1, 1},
++	{0x3E, 0x88, 0x88, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0, 0, 0, 0},
++	{0x42, 0x1, 0x1, 0, 0},
++	{0x43, 0x2, 0x2, 0, 0},
++	{0x44, 0x96, 0x96, 0, 0},
++	{0x45, 0x3e, 0x3e, 0, 0},
++	{0x46, 0x3e, 0x3e, 0, 0},
++	{0x47, 0x13, 0x13, 0, 0},
++	{0x48, 0x2, 0x2, 0, 0},
++	{0x49, 0x15, 0x15, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0, 0, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0, 0, 0, 0},
++	{0x50, 0x8, 0x8, 0, 0},
++	{0x51, 0x8, 0x8, 0, 0},
++	{0x52, 0x6, 0x6, 0, 0},
++	{0x53, 0x84, 0x84, 1, 1},
++	{0x54, 0xc3, 0xc3, 0, 0},
++	{0x55, 0x8f, 0x8f, 0, 0},
++	{0x56, 0xff, 0xff, 0, 0},
++	{0x57, 0xff, 0xff, 0, 0},
++	{0x58, 0x88, 0x88, 0, 0},
++	{0x59, 0x88, 0x88, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0xcc, 0xcc, 0, 0},
++	{0x5C, 0x6, 0x6, 0, 0},
++	{0x5D, 0x80, 0x80, 0, 0},
++	{0x5E, 0x80, 0x80, 0, 0},
++	{0x5F, 0xf8, 0xf8, 0, 0},
++	{0x60, 0x88, 0x88, 0, 0},
++	{0x61, 0x88, 0x88, 0, 0},
++	{0x62, 0x88, 0x8, 1, 1},
++	{0x63, 0x88, 0x88, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0x1, 0x1, 1, 1},
++	{0x66, 0x8a, 0x8a, 0, 0},
++	{0x67, 0x8, 0x8, 0, 0},
++	{0x68, 0x83, 0x83, 0, 0},
++	{0x69, 0x6, 0x6, 0, 0},
++	{0x6A, 0xa0, 0xa0, 0, 0},
++	{0x6B, 0xa, 0xa, 0, 0},
++	{0x6C, 0x87, 0x87, 1, 1},
++	{0x6D, 0x2a, 0x2a, 0, 0},
++	{0x6E, 0x2a, 0x2a, 0, 0},
++	{0x6F, 0x2a, 0x2a, 0, 0},
++	{0x70, 0x2a, 0x2a, 0, 0},
++	{0x71, 0x18, 0x18, 0, 0},
++	{0x72, 0x6a, 0x6a, 1, 1},
++	{0x73, 0xab, 0xab, 1, 1},
++	{0x74, 0x13, 0x13, 1, 1},
++	{0x75, 0xc1, 0xc1, 1, 1},
++	{0x76, 0xaa, 0xaa, 1, 1},
++	{0x77, 0x87, 0x87, 1, 1},
++	{0x78, 0, 0, 0, 0},
++	{0x79, 0x6, 0x6, 0, 0},
++	{0x7A, 0x7, 0x7, 0, 0},
++	{0x7B, 0x7, 0x7, 0, 0},
++	{0x7C, 0x15, 0x15, 0, 0},
++	{0x7D, 0x55, 0x55, 0, 0},
++	{0x7E, 0x97, 0x97, 1, 1},
++	{0x7F, 0x8, 0x8, 0, 0},
++	{0x80, 0x14, 0x14, 1, 1},
++	{0x81, 0x33, 0x33, 0, 0},
++	{0x82, 0x88, 0x88, 0, 0},
++	{0x83, 0x6, 0x6, 0, 0},
++	{0x84, 0x3, 0x3, 1, 1},
++	{0x85, 0xa, 0xa, 0, 0},
++	{0x86, 0x3, 0x3, 1, 1},
++	{0x87, 0x2a, 0x2a, 0, 0},
++	{0x88, 0xa4, 0xa4, 0, 0},
++	{0x89, 0x18, 0x18, 0, 0},
++	{0x8A, 0x28, 0x28, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0x4a, 0x4a, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0xf8, 0xf8, 0, 0},
++	{0x8F, 0x88, 0x88, 0, 0},
++	{0x90, 0x88, 0x88, 0, 0},
++	{0x91, 0x88, 0x8, 1, 1},
++	{0x92, 0x88, 0x88, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0x1, 0x1, 1, 1},
++	{0x95, 0x8a, 0x8a, 0, 0},
++	{0x96, 0x8, 0x8, 0, 0},
++	{0x97, 0x83, 0x83, 0, 0},
++	{0x98, 0x6, 0x6, 0, 0},
++	{0x99, 0xa0, 0xa0, 0, 0},
++	{0x9A, 0xa, 0xa, 0, 0},
++	{0x9B, 0x87, 0x87, 1, 1},
++	{0x9C, 0x2a, 0x2a, 0, 0},
++	{0x9D, 0x2a, 0x2a, 0, 0},
++	{0x9E, 0x2a, 0x2a, 0, 0},
++	{0x9F, 0x2a, 0x2a, 0, 0},
++	{0xA0, 0x18, 0x18, 0, 0},
++	{0xA1, 0x6a, 0x6a, 1, 1},
++	{0xA2, 0xab, 0xab, 1, 1},
++	{0xA3, 0x13, 0x13, 1, 1},
++	{0xA4, 0xc1, 0xc1, 1, 1},
++	{0xA5, 0xaa, 0xaa, 1, 1},
++	{0xA6, 0x87, 0x87, 1, 1},
++	{0xA7, 0, 0, 0, 0},
++	{0xA8, 0x6, 0x6, 0, 0},
++	{0xA9, 0x7, 0x7, 0, 0},
++	{0xAA, 0x7, 0x7, 0, 0},
++	{0xAB, 0x15, 0x15, 0, 0},
++	{0xAC, 0x55, 0x55, 0, 0},
++	{0xAD, 0x97, 0x97, 1, 1},
++	{0xAE, 0x8, 0x8, 0, 0},
++	{0xAF, 0x14, 0x14, 1, 1},
++	{0xB0, 0x33, 0x33, 0, 0},
++	{0xB1, 0x88, 0x88, 0, 0},
++	{0xB2, 0x6, 0x6, 0, 0},
++	{0xB3, 0x3, 0x3, 1, 1},
++	{0xB4, 0xa, 0xa, 0, 0},
++	{0xB5, 0x3, 0x3, 1, 1},
++	{0xB6, 0x2a, 0x2a, 0, 0},
++	{0xB7, 0xa4, 0xa4, 0, 0},
++	{0xB8, 0x18, 0x18, 0, 0},
++	{0xB9, 0x28, 0x28, 0, 0},
++	{0xBA, 0, 0, 0, 0},
++	{0xBB, 0x4a, 0x4a, 0, 0},
++	{0xBC, 0, 0, 0, 0},
++	{0xBD, 0x71, 0x71, 0, 0},
++	{0xBE, 0x72, 0x72, 0, 0},
++	{0xBF, 0x73, 0x73, 0, 0},
++	{0xC0, 0x74, 0x74, 0, 0},
++	{0xC1, 0x75, 0x75, 0, 0},
++	{0xC2, 0x76, 0x76, 0, 0},
++	{0xC3, 0x77, 0x77, 0, 0},
++	{0xC4, 0x78, 0x78, 0, 0},
++	{0xC5, 0x79, 0x79, 0, 0},
++	{0xC6, 0x7a, 0x7a, 0, 0},
++	{0xC7, 0, 0, 0, 0},
++	{0xC8, 0, 0, 0, 0},
++	{0xC9, 0, 0, 0, 0},
++	{0xCA, 0, 0, 0, 0},
++	{0xCB, 0, 0, 0, 0},
++	{0xCC, 0, 0, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0x6, 0x6, 0, 0},
++	{0xCF, 0, 0, 0, 0},
++	{0xD0, 0, 0, 0, 0},
++	{0xD1, 0x18, 0x18, 0, 0},
++	{0xD2, 0x88, 0x88, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0, 0, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0, 0, 0, 0},
++	{0xD9, 0, 0, 0, 0},
++	{0xDA, 0x6, 0x6, 0, 0},
++	{0xDB, 0, 0, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x18, 0x18, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0, 0, 0, 0},
++	{0xE0, 0, 0, 0, 0},
++	{0xE1, 0, 0, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x74, 0x74, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x99, 0x99, 0, 0},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x99, 0x99, 0, 0},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x66, 0x66, 0, 0},
++	{0x50, 0x66, 0x66, 0, 0},
++	{0x51, 0x57, 0x57, 0, 0},
++	{0x52, 0x57, 0x57, 0, 0},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x23, 0x23, 0, 0},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0x2, 0x2, 0, 0},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x72, 0x72, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x2f, 0x2f, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_SYN_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x6, 0x6, 1, 1},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x3f, 0x3f, 1, 1},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0x6, 0x6, 1, 1},
++	{0x4C, 0x6, 0x6, 1, 1},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x2b, 0x2b, 1, 1},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_TX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_RX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev4[] = {
++	{0x00, 0x84, 0},
++	{0x01, 0, 0},
++	{0x02, 0x60, 0},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 1},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0xf7, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x4, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x26, 1},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 1},
++	{0x3D, 0xff, 1},
++	{0x3E, 0xff, 1},
++	{0x3F, 0xff, 1},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x75, 0},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0xa8, 0},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x30, 0},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0x19, 0},
++	{0x64, 0x62, 0},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0xc8, 0},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x1e, 0},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x1e, 0},
++	{0x7C, 0x62, 0},
++	{0x7D, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x9c, 0},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 1},
++	{0x8B, 0x10, 1},
++	{0x8C, 0xf0, 1},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0xe1, 0},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 1},
++	{0xA5, 0x6d, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 1},
++	{0xA9, 0xc, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 1},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x75, 0},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0xa8, 0},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x30, 0},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0x19, 0},
++	{0xE9, 0x62, 0},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0xc8, 0},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x1e, 0},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x1e, 0},
++	{0x101, 0x62, 0},
++	{0x102, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x9c, 0},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 1},
++	{0x110, 0x10, 1},
++	{0x111, 0xf0, 1},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0xe1, 0},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 1},
++	{0x12A, 0x6d, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 1},
++	{0x12E, 0xc, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 1},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x152, 0, 0},
++	{0x153, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0x2, 1},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0xFFFF, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev5[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev5v1[] = {
++	{0x00, 0x15, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev7[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0x13, 1},
++	{0x65, 0, 0},
++	{0x66, 0xee, 1},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0x14, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0x13, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0xee, 1},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0x14, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev8[] = {
++	{0x00, 0x8, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0xf, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0xf, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
++
++static s32 nphy_lnagain_est0[] = { -315, 40370 };
++static s32 nphy_lnagain_est1[] = { -224, 23242 };
++
++static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
++	{
++		{0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
++		{0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
++		{0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
++		{0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
++		{0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
++		{0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
++		{0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
++		{0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
++		{0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
++	},
++	{
++		{0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
++		{0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
++		{0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
++	}
++};
++
++static const u32 nphy_tpc_txgain[] = {
++	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
++	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
++	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
++	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
++	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
++	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
++	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
++	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
++	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
++	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
++	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
++	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
++	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
++	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
++	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
++	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
++	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
++	0x03902942, 0x03902844, 0x03902842, 0x03902744,
++	0x03902742, 0x03902644, 0x03902642, 0x03902544,
++	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
++	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
++	0x03802842, 0x03802744, 0x03802742, 0x03802644,
++	0x03802642, 0x03802544, 0x03802542, 0x03802444,
++	0x03802442, 0x03802344, 0x03802342, 0x03802244,
++	0x03802242, 0x03802144, 0x03802142, 0x03802044,
++	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
++	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
++	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
++	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
++	0x03801842, 0x03801744, 0x03801742, 0x03801644,
++	0x03801642, 0x03801544, 0x03801542, 0x03801444,
++	0x03801442, 0x03801344, 0x03801342, 0x00002b00
++};
++
++static const u16 nphy_tpc_loscale[] = {
++	256, 256, 271, 271, 287, 256, 256, 271,
++	271, 287, 287, 304, 304, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 406, 406, 430,
++	430, 455, 455, 482, 482, 511, 511, 541,
++	541, 573, 573, 607, 607, 643, 643, 681,
++	681, 722, 722, 764, 764, 810, 810, 858,
++	858, 908, 908, 962, 962, 1019, 1019, 256
++};
++
++static u32 nphy_tpc_txgain_ipa[] = {
++	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
++	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
++	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
++	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
++	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
++	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
++	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
++	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
++	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
++	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
++	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
++	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
++	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
++	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
++	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
++	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
++	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
++	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
++	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
++	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
++	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
++	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
++	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
++	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
++	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
++	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
++	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
++	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
++	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
++	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
++	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
++	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev5[] = {
++	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
++	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
++	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
++	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
++	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
++	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
++	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
++	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
++	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
++	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
++	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
++	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
++	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
++	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
++	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
++	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
++	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
++	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
++	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
++	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
++	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
++	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
++	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
++	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
++	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
++	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
++	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
++	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
++	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
++	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
++	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
++	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev6[] = {
++	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
++	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
++	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
++	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
++	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
++	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
++	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
++	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
++	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
++	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
++	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
++	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
++	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
++	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
++	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
++	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
++	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
++	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
++	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
++	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
++	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
++	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
++	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
++	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
++	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
++	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
++	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
++	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
++	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
++	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
++	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
++	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
++	0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
++	0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
++	0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
++	0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
++	0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
++	0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
++	0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
++	0x70470028, 0x70470026, 0x70470024, 0x70470022,
++	0x7047001f, 0x70370027, 0x70370024, 0x70370022,
++	0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
++	0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
++	0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
++	0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
++	0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
++	0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
++	0x70170019, 0x70170018, 0x70170016, 0x70170015,
++	0x70170014, 0x70170013, 0x70170012, 0x70170010,
++	0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
++	0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
++	0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
++	0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
++	0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
++	0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
++	0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
++	0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
++	0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
++	0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
++	0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
++	0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
++	0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
++	0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
++	0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
++	0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
++	0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
++	0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
++	0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
++	0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
++	0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
++	0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
++	0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
++	0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
++	0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
++	0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
++	0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
++	0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
++	0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
++	0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
++	0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
++	0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
++	0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
++	0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
++	0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
++	0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
++	0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
++	0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
++	0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
++	0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
++	0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
++	0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
++	0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_5g[] = {
++	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
++	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
++	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
++	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
++	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
++	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
++	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
++	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
++	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
++	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
++	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
++	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
++	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
++	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
++	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
++	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
++	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
++	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
++	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
++	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
++	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
++	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
++	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
++	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
++	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
++	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
++	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
++	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
++	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
++	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
++	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
++	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
++	0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
++	0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
++	0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
++	0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
++	0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
++	0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
++	0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
++	0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
++	0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
++	0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
++	0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
++	0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
++	0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
++	0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
++	0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
++	0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
++	0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
++	0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
++	0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
++	0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
++	0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
++	0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
++	0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
++	0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
++	0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
++	0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
++	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
++	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
++	0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
++	0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
++	0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
++	0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
++	0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
++	0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
++	0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
++	0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
++	0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
++	0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
++	0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
++	0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
++	0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
++	0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
++	0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
++	0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
++	0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
++	0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
++	0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
++	0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
++	0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
++	0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
++	0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
++	0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
++	0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
++	0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
++	0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
++	0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
++	-114, -108, -98, -91, -84, -78, -70, -62,
++	-54, -46, -39, -31, -23, -15, -8, 0
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
++	-100, -95, -89, -83, -77, -70, -63, -56,
++	-48, -41, -33, -25, -19, -12, -6, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
++	-159, -113, -86, -72, -62, -54, -48, -43,
++	-39, -35, -31, -28, -25, -23, -20, -18,
++	-17, -15, -13, -11, -10, -8, -7, -6,
++	-5, -4, -3, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
++	-109, -109, -82, -68, -58, -50, -44, -39,
++	-35, -31, -28, -26, -23, -21, -19, -17,
++	-16, -14, -13, -11, -10, -9, -8, -7,
++	-5, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
++	-122, -122, -95, -80, -69, -61, -54, -49,
++	-43, -39, -35, -32, -28, -26, -23, -21,
++	-18, -16, -15, -13, -11, -10, -8, -7,
++	-6, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
++	-107, -101, -92, -85, -78, -71, -62, -55,
++	-47, -39, -32, -24, -19, -12, -6, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
++	-110, -104, -95, -88, -81, -74, -66, -58,
++	-50, -44, -36, -28, -23, -15, -8, 0
++};
++
++static u8 pad_gain_codes_used_2057rev5[] = {
++	20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
++	10, 9, 8, 7, 6, 5, 4, 3, 2, 1
++};
++
++static u8 pad_gain_codes_used_2057rev7[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
++	5, 4, 3, 2, 1
++};
++
++static u8 pad_all_gain_codes_2057[] = {
++	31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
++	21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
++	11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
++	1, 0
++};
++
++static u8 pga_all_gain_codes_2057[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
++};
++
++static u32 nphy_papd_scaltbl[] = {
++	0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
++	0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
++	0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
++	0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
++	0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
++	0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
++	0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
++	0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
++	0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
++	0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
++	0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
++	0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
++	0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
++	0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
++	0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
++	0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
++};
++
++static u32 nphy_tpc_txgain_rev3[] = {
++	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
++	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
++	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
++	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
++	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
++	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
++	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
++	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
++	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
++	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
++	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
++	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
++	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
++	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
++	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
++	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
++	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
++	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
++	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
++	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
++	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
++	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
++	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
++	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
++	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
++	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
++	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
++	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
++	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
++	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
++	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
++	0x1041003c, 0x1041003b, 0x10410039, 0x10410037
++};
++
++static u32 nphy_tpc_txgain_HiPwrEPA[] = {
++	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
++	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
++	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
++	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
++	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
++	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
++	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
++	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
++	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
++	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
++	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
++	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
++	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
++	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
++	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
++	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
++	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
++	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
++	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
++	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
++	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
++	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
++	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
++	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
++	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
++	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
++	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
++	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
++	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
++	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
++	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
++	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev3[] = {
++	0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
++	0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
++	0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
++	0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
++	0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
++	0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
++	0x80390038, 0x80390035, 0x8031003a, 0x80310036,
++	0x80310033, 0x8029003a, 0x80290037, 0x80290034,
++	0x80290031, 0x80210039, 0x80210036, 0x80210033,
++	0x80210030, 0x8019003c, 0x80190039, 0x80190036,
++	0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
++	0x80190028, 0x8011003a, 0x80110036, 0x80110033,
++	0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
++	0x80110027, 0x80110024, 0x80110022, 0x80110020,
++	0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
++	0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
++	0x80090029, 0x80090027, 0x80090025, 0x80090023,
++	0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
++	0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
++	0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev5[] = {
++	0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
++	0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
++	0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
++	0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
++	0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
++	0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
++	0x10390038, 0x10390035, 0x1031003a, 0x10310036,
++	0x10310033, 0x1029003a, 0x10290037, 0x10290034,
++	0x10290031, 0x10210039, 0x10210036, 0x10210033,
++	0x10210030, 0x1019003c, 0x10190039, 0x10190036,
++	0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
++	0x10190028, 0x1011003a, 0x10110036, 0x10110033,
++	0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
++	0x10110027, 0x10110024, 0x10110022, 0x10110020,
++	0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
++	0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
++	0x10090029, 0x10090027, 0x10090025, 0x10090023,
++	0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
++	0x1009001a, 0x10090018, 0x10090017, 0x10090016,
++	0x10090015, 0x10090013, 0x10090012, 0x10090011,
++	0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
++	0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
++	0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
++	0x10090008, 0x10090008, 0x10090007, 0x10090007,
++	0x10090007, 0x10090006, 0x10090006, 0x10090005,
++	0x10090005, 0x10090005, 0x10090005, 0x10090004,
++	0x10090004, 0x10090004, 0x10090004, 0x10090003,
++	0x10090003, 0x10090003, 0x10090003, 0x10090003,
++	0x10090003, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090001, 0x10090001,
++	0x10090001, 0x10090001, 0x10090001, 0x10090001
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev3[] = {
++	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
++	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
++	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
++	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
++	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
++	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
++	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
++	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
++	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
++	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
++	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
++	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
++	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
++	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
++	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
++	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
++	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
++	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
++	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
++	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
++	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
++	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
++	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
++	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
++	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
++	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
++	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
++	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
++	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
++	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
++	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
++	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev4[] = {
++	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
++	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
++	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
++	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
++	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
++	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
++	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
++	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
++	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
++	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
++	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
++	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
++	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
++	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
++	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
++	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
++	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
++	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
++	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
++	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
++	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
++	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
++	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
++	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
++	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
++	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
++	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
++	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
++	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
++	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
++	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
++	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev5[] = {
++	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
++	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
++	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
++	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
++	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
++	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
++	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
++	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
++	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
++	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
++	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
++	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
++	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
++	0x09620039, 0x09620037, 0x09620035, 0x09620033,
++	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
++	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
++	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
++	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
++	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
++	0x06620039, 0x06620037, 0x06620035, 0x06620033,
++	0x05620046, 0x05620044, 0x05620042, 0x05620040,
++	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
++	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
++	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
++	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
++	0x03620038, 0x03620037, 0x03620035, 0x03620033,
++	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
++	0x02620046, 0x02620044, 0x02620043, 0x02620042,
++	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
++	0x01620043, 0x01620042, 0x01620041, 0x01620040,
++	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
++	0x0062003b, 0x00620039, 0x00620037, 0x00620035
++};
++
++static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
++	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
++	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
++	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
++	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
++	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
++	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
++	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
++	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
++	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
++	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
++	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
++	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
++	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
++	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
++	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
++	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
++	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
++	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
++	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
++	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
++	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
++	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
++	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
++	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
++	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
++	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
++	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
++	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
++	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
++	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
++	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
++	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
++};
++
++static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
++static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
++	0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a
++};
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
++	0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16
++};
++
++bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u32 phybist0, phybist1, phybist2, phybist3, phybist4;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16))
++		return true;
++
++	phybist0 = read_phy_reg(pi, 0x0e);
++	phybist1 = read_phy_reg(pi, 0x0f);
++	phybist2 = read_phy_reg(pi, 0xea);
++	phybist3 = read_phy_reg(pi, 0xeb);
++	phybist4 = read_phy_reg(pi, 0x156);
++
++	if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
++	    (phybist3 == 0) && (phybist4 == 0))
++		return true;
++
++	return false;
++}
++
++static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
++{
++	u16 addr, val;
++
++	val = 0x1e1f;
++	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
++	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
++		write_phy_reg(pi, addr, val);
++		if (addr == (NPHY_TO_BPHY_OFF + 0x97))
++			val = 0x3e3f;
++		else
++			val -= 0x0202;
++	}
++
++	write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
++}
++
++void
++wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			 u32 width, const void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_write_table_nphy(pi, &tbl);
++}
++
++void
++wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			u32 width, void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_read_table_nphy(pi, &tbl);
++}
++
++static void
++wlc_phy_static_table_download_nphy(struct brcms_phy *pi)
++{
++	uint idx;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev16[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev7[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev3[idx]);
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0[idx]);
++	}
++}
++
++static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi)
++{
++	uint idx = 0;
++	u8 antswctrllut;
++
++	if (pi->phy_init_por)
++		wlc_phy_static_table_download_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
++			       pi->srom_fem2g.antswctrllut : pi->srom_fem5g.
++			       antswctrllut;
++
++		switch (antswctrllut) {
++		case 0:
++
++			break;
++
++		case 1:
++
++			if (pi->aa2g == 7)
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8_2o3[0]);
++			else
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8
++					[0]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x25, 8,
++						 &ant_sw_ctrl_tbl_rev8[2]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x29, 8,
++						 &ant_sw_ctrl_tbl_rev8[4]);
++			break;
++
++		case 2:
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x1, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x5, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x9, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[4]);
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x21, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x25, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x29, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[4]);
++			break;
++
++		default:
++			break;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
++
++			if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
++				antswctrllut =
++					CHSPEC_IS2G(pi->radio_chanspec) ?
++					pi->srom_fem2g.antswctrllut :
++					pi->srom_fem5g.antswctrllut;
++				switch (antswctrllut) {
++				case 0:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile
++						[idx]);
++					break;
++				case 1:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile1
++						[idx]);
++					break;
++				case 2:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile2
++						[idx]);
++					break;
++				case 3:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile3
++						[idx]);
++					break;
++				default:
++					break;
++				}
++			} else {
++				wlc_phy_write_table_nphy(
++					pi,
++					&mimophytbl_info_rev3_volatile[idx]);
++			}
++		}
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0_volatile
++						 [idx]);
++	}
++}
++
++static void
++wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay)
++{
++	write_phy_reg(pi, 0x77, holdoff);
++	write_phy_reg(pi, 0xb4, delay);
++}
++
++void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs)
++{
++	u16 holdoff, delay;
++
++	if (rifs) {
++
++		holdoff = 0x10;
++		delay = 0x258;
++	} else {
++
++		holdoff = 0x15;
++		delay = 0x320;
++	}
++
++	wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
++
++	if (pi && pi->sh && (pi->sh->_rifs_phy != rifs))
++		pi->sh->_rifs_phy = rifs;
++}
++
++static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++		pi->phy_5g_pwrgain = true;
++		return;
++	}
++
++	pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
++	pi->phy_5g_pwrgain = false;
++
++	if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
++	    NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++	else if ((pi->sh->sromrev >= 4)
++		 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
++		pi->phy_5g_pwrgain = true;
++}
++
++static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
++{
++	u16 bw40po, cddpo, stbcpo, bwduppo;
++	uint band_num;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (pi->sh->sromrev >= 9)
++		return;
++
++	bw40po = sprom->bw40po;
++	pi->bw402gpo = bw40po & 0xf;
++	pi->bw405gpo = (bw40po & 0xf0) >> 4;
++	pi->bw405glpo = (bw40po & 0xf00) >> 8;
++	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
++
++	cddpo = sprom->cddpo;
++	pi->cdd2gpo = cddpo & 0xf;
++	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
++	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
++	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
++
++	stbcpo = sprom->stbcpo;
++	pi->stbc2gpo = stbcpo & 0xf;
++	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
++	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
++	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
++
++	bwduppo = sprom->bwduppo;
++	pi->bwdup2gpo = bwduppo & 0xf;
++	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
++	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
++	pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
++				sprom->core_pwr_info[0].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
++				sprom->core_pwr_info[1].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
++				sprom->core_pwr_info[0].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
++				sprom->core_pwr_info[1].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
++				sprom->core_pwr_info[0].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
++				sprom->core_pwr_info[1].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
++				sprom->core_pwr_info[0].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
++				sprom->core_pwr_info[1].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
++				sprom->core_pwr_info[0].itssi_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
++				sprom->core_pwr_info[1].itssi_2g;
++
++			pi->cck2gpo = sprom->cck2gpo;
++
++			pi->ofdm2gpo = sprom->ofdm2gpo;
++
++			pi->mcs2gpo[0] = sprom->mcs2gpo[0];
++			pi->mcs2gpo[1] = sprom->mcs2gpo[1];
++			pi->mcs2gpo[2] = sprom->mcs2gpo[2];
++			pi->mcs2gpo[3] = sprom->mcs2gpo[3];
++			pi->mcs2gpo[4] = sprom->mcs2gpo[4];
++			pi->mcs2gpo[5] = sprom->mcs2gpo[5];
++			pi->mcs2gpo[6] = sprom->mcs2gpo[6];
++			pi->mcs2gpo[7] = sprom->mcs2gpo[7];
++			break;
++		case 1:
++
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
++				sprom->core_pwr_info[0].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
++				sprom->core_pwr_info[1].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[0].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[1].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[0].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[1].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[0].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[1].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
++				sprom->core_pwr_info[0].itssi_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
++				sprom->core_pwr_info[1].itssi_5g;
++
++			pi->ofdm5gpo = sprom->ofdm5gpo;
++
++			pi->mcs5gpo[0] = sprom->mcs5gpo[0];
++			pi->mcs5gpo[1] = sprom->mcs5gpo[1];
++			pi->mcs5gpo[2] = sprom->mcs5gpo[2];
++			pi->mcs5gpo[3] = sprom->mcs5gpo[3];
++			pi->mcs5gpo[4] = sprom->mcs5gpo[4];
++			pi->mcs5gpo[5] = sprom->mcs5gpo[5];
++			pi->mcs5gpo[6] = sprom->mcs5gpo[6];
++			pi->mcs5gpo[7] = sprom->mcs5gpo[7];
++			break;
++		case 2:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
++				sprom->core_pwr_info[0].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
++				sprom->core_pwr_info[1].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[0].pa_5gl[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[1].pa_5gl[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[0].pa_5gl[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[1].pa_5gl[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[0].pa_5gl[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[1].pa_5gl[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
++
++			pi->ofdm5glpo = sprom->ofdm5glpo;
++
++			pi->mcs5glpo[0] = sprom->mcs5glpo[0];
++			pi->mcs5glpo[1] = sprom->mcs5glpo[1];
++			pi->mcs5glpo[2] = sprom->mcs5glpo[2];
++			pi->mcs5glpo[3] = sprom->mcs5glpo[3];
++			pi->mcs5glpo[4] = sprom->mcs5glpo[4];
++			pi->mcs5glpo[5] = sprom->mcs5glpo[5];
++			pi->mcs5glpo[6] = sprom->mcs5glpo[6];
++			pi->mcs5glpo[7] = sprom->mcs5glpo[7];
++			break;
++		case 3:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
++				sprom->core_pwr_info[0].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
++				sprom->core_pwr_info[1].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[0].pa_5gh[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[1].pa_5gh[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[0].pa_5gh[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[1].pa_5gh[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[0].pa_5gh[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[1].pa_5gh[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
++
++			pi->ofdm5ghpo = sprom->ofdm5ghpo;
++
++			pi->mcs5ghpo[0] = sprom->mcs5ghpo[0];
++			pi->mcs5ghpo[1] = sprom->mcs5ghpo[1];
++			pi->mcs5ghpo[2] = sprom->mcs5ghpo[2];
++			pi->mcs5ghpo[3] = sprom->mcs5ghpo[3];
++			pi->mcs5ghpo[4] = sprom->mcs5ghpo[4];
++			pi->mcs5ghpo[5] = sprom->mcs5ghpo[5];
++			pi->mcs5ghpo[6] = sprom->mcs5ghpo[6];
++			pi->mcs5ghpo[7] = sprom->mcs5ghpo[7];
++			break;
++		}
++	}
++
++	wlc_phy_txpwr_apply_nphy(pi);
++}
++
++static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
++{
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	pi->antswitch = sprom->antswitch;
++	pi->aa2g = sprom->ant_available_bg;
++	pi->aa5g = sprom->ant_available_a;
++
++	pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos;
++	pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain;
++	pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range;
++	pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso;
++	pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos;
++	pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain;
++	pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range;
++	pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso;
++	if (sprom->fem.ghz5.antswlut)
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut;
++	else
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	wlc_phy_txpower_ipa_upd(pi);
++
++	pi->phy_txcore_disable_temp = sprom->tempthresh;
++	if (pi->phy_txcore_disable_temp == 0)
++		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++
++	pi->phy_tempsense_offset = sprom->tempoffset;
++	if (pi->phy_tempsense_offset != 0) {
++		if (pi->phy_tempsense_offset >
++		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
++		else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
++						     NPHY_SROM_MINTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
++		else
++			pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
++	}
++
++	pi->phy_txcore_enable_temp =
++		pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
++
++	pi->phycal_tempdelta = sprom->phycal_tempdelta;
++	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
++		pi->phycal_tempdelta = 0;
++
++	wlc_phy_txpwr_srom_read_ppr_nphy(pi);
++
++	return true;
++}
++
++bool wlc_phy_attach_nphy(struct brcms_phy *pi)
++{
++	uint i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6))
++		pi->phyhang_avoid = true;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		pi->nphy_gband_spurwar_en = true;
++		if (pi->sh->boardflags2 & BFL2_SPUR_WAR)
++			pi->nphy_aband_spurwar_en = true;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR)
++			pi->nphy_gband_spurwar2_en = true;
++	}
++
++	pi->n_preamble_override = AUTO;
++	if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
++		pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE;
++
++	pi->nphy_txrx_chain = AUTO;
++	pi->phy_scraminit = AUTO;
++
++	pi->nphy_rxcalparams = 0x010100B5;
++
++	pi->nphy_perical = PHY_PERICAL_MPHASE;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
++
++	pi->nphy_gain_boost = true;
++	pi->nphy_elna_gain_config = false;
++	pi->radio_is_on = false;
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++)
++		pi->nphy_txpwrindex[i].index = AUTO;
++
++	wlc_phy_txpwrctrl_config_nphy(pi);
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++		pi->hwpwrctrl_capable = true;
++
++	pi->pi_fptr.init = wlc_phy_init_nphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
++
++	if (!wlc_phy_txpwr_srom_read_nphy(pi))
++		return false;
++
++	return true;
++}
++
++static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn)
++{
++	s32 rfpwr_offset = 0;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev3n4
++				       [pad_gn];
++		else if (pi->pubpi.radiorev == 5)
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev5
++				       [pad_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev7
++				       [pad_gn];
++	} else {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057
++				       [pga_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057rev7
++				       [pga_gn];
++	}
++	return rfpwr_offset;
++}
++
++static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble)
++{
++	bool gf_preamble = false;
++	u16 val;
++
++	if (preamble == BRCMS_N_PREAMBLE_GF)
++		gf_preamble = true;
++
++	val = read_phy_reg(pi, 0xed);
++
++	val |= RX_GF_MM_AUTO;
++	val &= ~RX_GF_OR_MM;
++	if (gf_preamble)
++		val |= RX_GF_OR_MM;
++
++	write_phy_reg(pi, 0xed, val);
++}
++
++static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type;
++	u16 addr_offset[] = { 0x186, 0x195, 0x2c5};
++
++	for (type = 0; type < 3; type++) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, addr_offset[type] + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++	}
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x186 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[5][j]);
++		}
++
++		if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x2c5 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[6][j]);
++		}
++	}
++}
++
++static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j;
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x195 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
++	} else {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	}
++}
++
++static void
++wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
++		       u8 len)
++{
++	u32 t1_offset, t2_offset;
++	u8 ctr;
++	u8 end_event =
++		NREV_GE(pi->pubpi.phy_rev,
++			3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
++	u8 end_dly = 1;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	t1_offset = cmd << 4;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
++				 events);
++	t2_offset = t1_offset + 0x080;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
++				 dlys);
++
++	for (ctr = len; ctr < 16; ctr++) {
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t1_offset + ctr, 8, &end_event);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t2_offset + ctr, 8, &end_dly);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset)
++{
++	u16 lpf_bw_ctl_val = 0;
++	u16 rx2tx_lpf_rc_lut_offset = 0;
++
++	if (offset == 0) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			rx2tx_lpf_rc_lut_offset = 0x159;
++		else
++			rx2tx_lpf_rc_lut_offset = 0x154;
++	} else {
++		rx2tx_lpf_rc_lut_offset = offset;
++	}
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++				(u32) rx2tx_lpf_rc_lut_offset, 16,
++				&lpf_bw_ctl_val);
++
++	lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
++
++	return lpf_bw_ctl_val;
++}
++
++static void
++wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
++				  u8 core_mask, u8 off, u8 override_id)
++{
++	u8 core_num;
++	u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
++	u8 val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++			if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
++
++				switch (field) {
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 7):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 7);
++					val_shift = 7;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0xf8 :
++						   0xfa;
++					val_mask = (0x7 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7b :
++						   0x7e;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 12):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7c :
++						   0x7f;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x3 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xf << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID1) {
++
++				switch (field) {
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 2):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 7):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x7 << 8);
++					val_shift = 8;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 14);
++					val_shift = 14;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 13);
++					val_shift = 13;
++					break;
++				case (0x1 << 9):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 12);
++					val_shift = 12;
++					break;
++				case (0x1 << 8):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 11);
++					val_shift = 11;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID2) {
++
++				switch (field) {
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	}
++}
++
++static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	int ctr;
++	s16 gain_delta[2];
++	u8 curr_channel;
++	u16 minmax_gain[2];
++	u16 regval[4];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->nphy_gain_boost) {
++		if ((CHSPEC_IS2G(pi->radio_chanspec))) {
++
++			gain_delta[0] = 6;
++			gain_delta[1] = 6;
++		} else {
++
++			curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++			gain_delta[0] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est0[0] *
++					       curr_channel) +
++					      nphy_lnagain_est0[1]), 13);
++			gain_delta[1] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est1[0] *
++					       curr_channel) +
++					      nphy_lnagain_est1[1]), 13);
++		}
++	} else {
++
++		gain_delta[0] = 0;
++		gain_delta[1] = 0;
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (pi->nphy_elna_gain_config) {
++
++			regval[0] = nphy_def_lnagains[2] + gain_delta[core];
++			regval[1] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[2] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[3] = nphy_def_lnagains[3] + gain_delta[core];
++		} else {
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] =
++					nphy_def_lnagains[ctr] +
++					gain_delta[core];
++		}
++		wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
++
++		minmax_gain[core] =
++			(u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
++	}
++
++	mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
++	mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core)
++{
++	if (core == PHY_CORE_0) {
++		write_phy_reg(pi, 0x38, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x37, 0x0060);
++		else
++			write_phy_reg(pi, 0x37, 0x1080);
++	} else if (core == PHY_CORE_1) {
++		write_phy_reg(pi, 0x2ae, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x2ad, 0x0060);
++		else
++			write_phy_reg(pi, 0x2ad, 0x1080);
++	}
++}
++
++static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain)
++{
++	u8 txchain0, txchain1;
++
++	txchain0 = txchain & 0x1;
++	txchain1 = (txchain & 0x2) >> 1;
++	if (!txchain0)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++
++	if (!txchain1)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
++{
++	s8 lna1_gain_db[] = { 8, 13, 17, 22 };
++	s8 lna2_gain_db[] = { -2, 7, 11, 15 };
++	s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
++	s8 tia_gainbits[] = {
++		0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++	mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
++	mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
++				 lna1_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
++				 lna1_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
++				 lna2_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
++				 lna2_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++				 tia_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++				 tia_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++				 tia_gainbits);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++				 tia_gainbits);
++
++	write_phy_reg(pi, 0x37, 0x74);
++	write_phy_reg(pi, 0x2ad, 0x74);
++	write_phy_reg(pi, 0x38, 0x18);
++	write_phy_reg(pi, 0x2ae, 0x18);
++
++	write_phy_reg(pi, 0x2b, 0xe8);
++	write_phy_reg(pi, 0x41, 0xe8);
++
++	if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
++	} else {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
++{
++	u16 currband;
++	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
++	s8 *lna1_gain_db = NULL;
++	s8 *lna1_gain_db_2 = NULL;
++	s8 *lna2_gain_db = NULL;
++	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
++	s8 *tia_gain_db;
++	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
++	s8 *tia_gainbits;
++	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
++	u16 *rfseq_init_gain;
++	u16 init_gaincode;
++	u16 clip1hi_gaincode;
++	u16 clip1md_gaincode = 0;
++	u16 clip1md_gaincode_B;
++	u16 clip1lo_gaincode;
++	u16 clip1lo_gaincode_B;
++	u8 crsminl_th = 0;
++	u8 crsminu_th;
++	u16 nbclip_th = 0;
++	u8 w1clip_th;
++	u16 freq;
++	s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
++	u8 chg_nbclip_th = 0;
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (currband == 0) {
++
++		lna1_gain_db = lna1G_gain_db_rev7;
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++					 lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++					 lna1_gain_db);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
++		}
++
++		mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
++			mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
++		}
++	} else {
++
++		init_gaincode = 0x9e;
++		clip1hi_gaincode = 0x9e;
++		clip1md_gaincode_B = 0x24;
++		clip1lo_gaincode = 0x8a;
++		clip1lo_gaincode_B = 8;
++		rfseq_init_gain = rfseqA_init_gain_rev7;
++
++		tia_gain_db = tiaA_gain_db_rev7;
++		tia_gainbits = tiaA_gainbits_rev7;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			w1clip_th = 25;
++			clip1md_gaincode = 0x82;
++
++			if ((freq <= 5080) || (freq == 5825)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					11, 17, 22, 25};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x3e;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else if ((freq >= 5500) && (freq <= 5700)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
++
++				crsminu_th = 0x45;
++				clip1md_gaincode_B = 0x14;
++				nbclip_th = 0xff;
++				chg_nbclip_th = 1;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else {
++
++				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x41;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			}
++
++			if (freq <= 4920) {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5700)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 0;
++			}
++		} else {
++
++			crsminu_th = 0x3a;
++			crsminl_th = 0x3a;
++			w1clip_th = 20;
++
++			if ((freq >= 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5550)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 3;
++			}
++		}
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x36, clip1md_gaincode_B);
++		write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++		write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
++		write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++					 tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++					 tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++					 tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++					 tia_gainbits);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		if (chg_nbclip_th == 1) {
++			write_phy_reg(pi, 0x2b, nbclip_th);
++			write_phy_reg(pi, 0x41, nbclip_th);
++		}
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 0), (nvar_baseline_offset0 << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 6), (nvar_baseline_offset1 << 6));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++						 lna1_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++						 lna1_gain_db_2);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++						 8, lna2_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++						 8, lna2_gain_db);
++
++			write_phy_reg(pi, 0x24, clip1md_gaincode);
++			write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++		} else {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		}
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
++{
++	u16 w1th, hpf_code, currband;
++	int ctr;
++	u8 rfseq_updategainu_events[] = {
++		NPHY_RFSEQ_CMD_RX_GAIN,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_SET_HPF_BW
++	};
++	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
++	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
++	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
++	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
++	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
++	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
++	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
++	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
++	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
++	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
++	s8 *lna1_gain_db = NULL;
++	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
++	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
++	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
++	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
++	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
++	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
++	s8 *lna2_gain_db = NULL;
++	s8 tiaG_gain_db[] = {
++		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
++	s8 tiaA_gain_db[] = {
++		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
++	s8 tiaA_gain_db_rev4[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev5[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev6[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 *tia_gain_db;
++	s8 tiaG_gainbits[] = {
++		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++	s8 tiaA_gainbits[] = {
++		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
++	s8 tiaA_gainbits_rev4[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev5[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev6[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 *tia_gainbits;
++	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
++	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
++	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
++	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev5_elna[] = {
++		0x013f, 0x013f, 0x013f, 0x013f };
++	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
++	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
++	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
++	u16 rfseqA_init_gain_rev4_elna[] = {
++		0x314f, 0x314f, 0x314f, 0x314f };
++	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
++	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
++	u16 *rfseq_init_gain;
++	u16 initG_gaincode = 0x627e;
++	u16 initG_gaincode_rev4 = 0x527e;
++	u16 initG_gaincode_rev5 = 0x427e;
++	u16 initG_gaincode_rev5_elna = 0x027e;
++	u16 initG_gaincode_rev6 = 0x527e;
++	u16 initG_gaincode_rev6_224B0 = 0x427e;
++	u16 initG_gaincode_rev6_elna = 0x127e;
++	u16 initA_gaincode = 0x52de;
++	u16 initA_gaincode_rev4 = 0x629e;
++	u16 initA_gaincode_rev4_elna = 0x329e;
++	u16 initA_gaincode_rev5 = 0x729e;
++	u16 initA_gaincode_rev6 = 0x729e;
++	u16 init_gaincode;
++	u16 clip1hiG_gaincode = 0x107e;
++	u16 clip1hiG_gaincode_rev4 = 0x007e;
++	u16 clip1hiG_gaincode_rev5 = 0x1076;
++	u16 clip1hiG_gaincode_rev6 = 0x007e;
++	u16 clip1hiA_gaincode = 0x00de;
++	u16 clip1hiA_gaincode_rev4 = 0x029e;
++	u16 clip1hiA_gaincode_rev5 = 0x029e;
++	u16 clip1hiA_gaincode_rev6 = 0x029e;
++	u16 clip1hi_gaincode;
++	u16 clip1mdG_gaincode = 0x0066;
++	u16 clip1mdA_gaincode = 0x00ca;
++	u16 clip1mdA_gaincode_rev4 = 0x1084;
++	u16 clip1mdA_gaincode_rev5 = 0x2084;
++	u16 clip1mdA_gaincode_rev6 = 0x2084;
++	u16 clip1md_gaincode = 0;
++	u16 clip1loG_gaincode = 0x0074;
++	u16 clip1loG_gaincode_rev5[] = {
++		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
++	};
++	u16 clip1loG_gaincode_rev6[] = {
++		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
++	};
++	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
++	u16 clip1loA_gaincode = 0x00cc;
++	u16 clip1loA_gaincode_rev4 = 0x0086;
++	u16 clip1loA_gaincode_rev5 = 0x2086;
++	u16 clip1loA_gaincode_rev6 = 0x2086;
++	u16 clip1lo_gaincode;
++	u8 crsminG_th = 0x18;
++	u8 crsminG_th_rev5 = 0x18;
++	u8 crsminG_th_rev6 = 0x18;
++	u8 crsminA_th = 0x1e;
++	u8 crsminA_th_rev4 = 0x24;
++	u8 crsminA_th_rev5 = 0x24;
++	u8 crsminA_th_rev6 = 0x24;
++	u8 crsmin_th;
++	u8 crsminlG_th = 0x18;
++	u8 crsminlG_th_rev5 = 0x18;
++	u8 crsminlG_th_rev6 = 0x18;
++	u8 crsminlA_th = 0x1e;
++	u8 crsminlA_th_rev4 = 0x24;
++	u8 crsminlA_th_rev5 = 0x24;
++	u8 crsminlA_th_rev6 = 0x24;
++	u8 crsminl_th = 0;
++	u8 crsminuG_th = 0x18;
++	u8 crsminuG_th_rev5 = 0x18;
++	u8 crsminuG_th_rev6 = 0x18;
++	u8 crsminuA_th = 0x1e;
++	u8 crsminuA_th_rev4 = 0x24;
++	u8 crsminuA_th_rev5 = 0x24;
++	u8 crsminuA_th_rev6 = 0x24;
++	u8 crsminuA_th_rev6_224B0 = 0x2d;
++	u8 crsminu_th;
++	u16 nbclipG_th = 0x20d;
++	u16 nbclipG_th_rev4 = 0x1a1;
++	u16 nbclipG_th_rev5 = 0x1d0;
++	u16 nbclipG_th_rev6 = 0x1d0;
++	u16 nbclipA_th = 0x1a1;
++	u16 nbclipA_th_rev4 = 0x107;
++	u16 nbclipA_th_rev5 = 0x0a9;
++	u16 nbclipA_th_rev6 = 0x0f0;
++	u16 nbclip_th = 0;
++	u8 w1clipG_th = 5;
++	u8 w1clipG_th_rev5 = 9;
++	u8 w1clipG_th_rev6 = 5;
++	u8 w1clipA_th = 25, w1clip_th;
++	u8 rssi_gain_default = 0x50;
++	u8 rssiG_gain_rev6_224B0 = 0x50;
++	u8 rssiA_gain_rev5 = 0x90;
++	u8 rssiA_gain_rev6 = 0x90;
++	u8 rssi_gain;
++	u16 regval[21];
++	u8 triso;
++
++	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
++		pi->srom_fem2g.triso;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (pi->pubpi.radiorev == 5) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
++		} else if (pi->pubpi.radiorev == 7) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
++
++		} else if ((pi->pubpi.radiorev == 3)
++			   || (pi->pubpi.radiorev == 8)) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			if (pi->pubpi.radiorev == 8) {
++				mod_phy_reg(pi, 0x283,
++					    (0xff << 0), (0x44 << 0));
++				mod_phy_reg(pi, 0x280,
++					    (0xff << 0), (0x44 << 0));
++			}
++		} else {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		currband =
++			read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++		if (currband == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				if (pi->pubpi.radiorev == 11) {
++					lna1_gain_db = lna1G_gain_db_rev6_224B0;
++					lna2_gain_db = lna2G_gain_db_rev6_224B0;
++					rfseq_init_gain =
++						rfseqG_init_gain_rev6_224B0;
++					init_gaincode =
++						initG_gaincode_rev6_224B0;
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev6_224B0;
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssiG_gain_rev6_224B0;
++				} else {
++					lna1_gain_db = lna1G_gain_db_rev6;
++					lna2_gain_db = lna2G_gain_db_rev6;
++					if (pi->sh->boardflags & BFL_EXTLNA) {
++
++						rfseq_init_gain =
++						     rfseqG_init_gain_rev6_elna;
++						init_gaincode =
++						       initG_gaincode_rev6_elna;
++					} else {
++						rfseq_init_gain =
++							rfseqG_init_gain_rev6;
++						init_gaincode =
++							initG_gaincode_rev6;
++					}
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					switch (triso) {
++					case 0:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[0];
++						break;
++					case 1:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[1];
++						break;
++					case 2:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[2];
++						break;
++					case 3:
++					default:
++
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[3];
++						break;
++					case 4:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[4];
++						break;
++					case 5:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[5];
++						break;
++					case 6:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[6];
++						break;
++					case 7:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[7];
++						break;
++					}
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssi_gain_default;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1G_gain_db_rev5;
++				lna2_gain_db = lna2G_gain_db_rev5;
++				if (pi->sh->boardflags & BFL_EXTLNA) {
++
++					rfseq_init_gain =
++						rfseqG_init_gain_rev5_elna;
++					init_gaincode =
++						initG_gaincode_rev5_elna;
++				} else {
++					rfseq_init_gain = rfseqG_init_gain_rev5;
++					init_gaincode = initG_gaincode_rev5;
++				}
++				clip1hi_gaincode = clip1hiG_gaincode_rev5;
++				switch (triso) {
++				case 0:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[0];
++					break;
++				case 1:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[1];
++					break;
++				case 2:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[2];
++					break;
++				case 3:
++
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				case 4:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[4];
++					break;
++				case 5:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[5];
++					break;
++				case 6:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[6];
++					break;
++				case 7:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[7];
++					break;
++				default:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				}
++				nbclip_th = nbclipG_th_rev5;
++				w1clip_th = w1clipG_th_rev5;
++				crsmin_th = crsminG_th_rev5;
++				crsminl_th = crsminlG_th_rev5;
++				crsminu_th = crsminuG_th_rev5;
++				rssi_gain = rssi_gain_default;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1G_gain_db_rev4;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain_rev4;
++				init_gaincode = initG_gaincode_rev4;
++				clip1hi_gaincode = clip1hiG_gaincode_rev4;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th_rev4;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1G_gain_db;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain;
++				init_gaincode = initG_gaincode;
++				clip1hi_gaincode = clip1hiG_gaincode;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			}
++			tia_gain_db = tiaG_gain_db;
++			tia_gainbits = tiaG_gainbits;
++			clip1md_gaincode = clip1mdG_gaincode;
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				lna1_gain_db = lna1A_gain_db_rev6;
++				lna2_gain_db = lna2A_gain_db_rev6;
++				tia_gain_db = tiaA_gain_db_rev6;
++				tia_gainbits = tiaA_gainbits_rev6;
++				rfseq_init_gain = rfseqA_init_gain_rev6;
++				init_gaincode = initA_gaincode_rev6;
++				clip1hi_gaincode = clip1hiA_gaincode_rev6;
++				clip1md_gaincode = clip1mdA_gaincode_rev6;
++				clip1lo_gaincode = clip1loA_gaincode_rev6;
++				crsmin_th = crsminA_th_rev6;
++				crsminl_th = crsminlA_th_rev6;
++				if ((pi->pubpi.radiorev == 11) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 0))
++					crsminu_th = crsminuA_th_rev6_224B0;
++				else
++					crsminu_th = crsminuA_th_rev6;
++
++				nbclip_th = nbclipA_th_rev6;
++				rssi_gain = rssiA_gain_rev6;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1A_gain_db_rev5;
++				lna2_gain_db = lna2A_gain_db_rev5;
++				tia_gain_db = tiaA_gain_db_rev5;
++				tia_gainbits = tiaA_gainbits_rev5;
++				rfseq_init_gain = rfseqA_init_gain_rev5;
++				init_gaincode = initA_gaincode_rev5;
++				clip1hi_gaincode = clip1hiA_gaincode_rev5;
++				clip1md_gaincode = clip1mdA_gaincode_rev5;
++				clip1lo_gaincode = clip1loA_gaincode_rev5;
++				crsmin_th = crsminA_th_rev5;
++				crsminl_th = crsminlA_th_rev5;
++				crsminu_th = crsminuA_th_rev5;
++				nbclip_th = nbclipA_th_rev5;
++				rssi_gain = rssiA_gain_rev5;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1A_gain_db_rev4;
++				lna2_gain_db = lna2A_gain_db_rev4;
++				tia_gain_db = tiaA_gain_db_rev4;
++				tia_gainbits = tiaA_gainbits_rev4;
++				if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
++
++					rfseq_init_gain =
++						rfseqA_init_gain_rev4_elna;
++					init_gaincode =
++						initA_gaincode_rev4_elna;
++				} else {
++					rfseq_init_gain = rfseqA_init_gain_rev4;
++					init_gaincode = initA_gaincode_rev4;
++				}
++				clip1hi_gaincode = clip1hiA_gaincode_rev4;
++				clip1md_gaincode = clip1mdA_gaincode_rev4;
++				clip1lo_gaincode = clip1loA_gaincode_rev4;
++				crsmin_th = crsminA_th_rev4;
++				crsminl_th = crsminlA_th_rev4;
++				crsminu_th = crsminuA_th_rev4;
++				nbclip_th = nbclipA_th_rev4;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1A_gain_db;
++				lna2_gain_db = lna2A_gain_db;
++				tia_gain_db = tiaA_gain_db;
++				tia_gainbits = tiaA_gainbits;
++				rfseq_init_gain = rfseqA_init_gain;
++				init_gaincode = initA_gaincode;
++				clip1hi_gaincode = clip1hiA_gaincode;
++				clip1md_gaincode = clip1mdA_gaincode;
++				clip1lo_gaincode = clip1loA_gaincode;
++				crsmin_th = crsminA_th;
++				crsminl_th = crsminlA_th;
++				crsminu_th = crsminuA_th;
++				nbclip_th = nbclipA_th;
++				rssi_gain = rssi_gain_default;
++			}
++			w1clip_th = w1clipA_th;
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
++				0xf0);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
++				0xf0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
++				rssi_gain);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
++				rssi_gain);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
++				0xFF);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
++				0xFF);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
++					 8, lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
++					 8, lna1_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++					 8, lna2_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++					 8, lna2_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
++					 8, tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
++					 8, tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
++					 8, tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
++					 8, tia_gainbits);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
++					 8, &lpf_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
++					 8, &lpf_gainbits);
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x24, clip1md_gaincode);
++		write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++
++		mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
++		mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		write_phy_reg(pi, 0x2b, nbclip_th);
++		write_phy_reg(pi, 0x41, nbclip_th);
++
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++	} else {
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		write_phy_reg(pi, 0x2b, 0x84);
++		write_phy_reg(pi, 0x41, 0x84);
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			write_phy_reg(pi, 0x6b, 0x2b);
++			write_phy_reg(pi, 0x6c, 0x2b);
++			write_phy_reg(pi, 0x6d, 0x9);
++			write_phy_reg(pi, 0x6e, 0x9);
++		}
++
++		w1th = NPHY_RSSICAL_W1_TARGET - 4;
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
++
++			mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
++		}
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++		if (pi->nphy_gain_boost)
++			if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
++			    (CHSPEC_IS40(pi->radio_chanspec)))
++				hpf_code = 4;
++			else
++				hpf_code = 5;
++		else if (CHSPEC_IS40(pi->radio_chanspec))
++			hpf_code = 6;
++		else
++			hpf_code = 7;
++
++		mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
++		mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
++
++		for (ctr = 0; ctr < 4; ctr++)
++			regval[ctr] = (hpf_code << 8) | 0x7c;
++		wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++		if (pi->nphy_elna_gain_config) {
++			regval[0] = 0;
++			regval[1] = 1;
++			regval[2] = 1;
++			regval[3] = 1;
++			wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
++
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] = (hpf_code << 8) | 0x74;
++			wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = 3 * ctr;
++			wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
++
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = (u16) ctr;
++			wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
++		}
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
++				       rfseq_updategainu_events,
++				       rfseq_updategainu_dlys,
++				       sizeof(rfseq_updategainu_events) /
++				       sizeof(rfseq_updategainu_events[0]));
++
++		mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_phy_reg(pi,
++				    (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
++				    0x7f, 0x4);
++	}
++}
++
++static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
++{
++	u8 rfseq_rx2tx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_EXT_PA
++	};
++	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
++	u8 rfseq_tx2rx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_EXT_PA,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
++	};
++	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
++	u8 rfseq_tx2rx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
++	u8 rfseq_rx2tx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
++
++	u8 rfseq_rx2tx_events_rev3_ipa[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
++	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
++
++	s16 alpha0, alpha1, alpha2;
++	s16 beta0, beta1, beta2;
++	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
++	    stbc_data_weights;
++	u8 chan_freq_range = 0;
++	u16 dac_control = 0x0002;
++	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
++	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
++	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 *aux_adc_vmid;
++	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
++	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 *aux_adc_gain;
++	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
++	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
++	s32 min_nvar_val = 0x18d;
++	s32 min_nvar_offset_6mbps = 20;
++	u8 pdetrange;
++	u8 triso;
++	u16 regval;
++	u16 afectrl_adc_ctrl1_rev7 = 0x20;
++	u16 afectrl_adc_ctrl2_rev7 = 0x0;
++	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
++	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 ipalvlshift_3p3_war_en = 0;
++	u16 rccal_bcap_val, rccal_scap_val;
++	u16 rccal_tx20_11b_bcap = 0;
++	u16 rccal_tx20_11b_scap = 0;
++	u16 rccal_tx20_11n_bcap = 0;
++	u16 rccal_tx20_11n_scap = 0;
++	u16 rccal_tx40_11n_bcap = 0;
++	u16 rccal_tx40_11n_scap = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
++	u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
++	u16 tx_lpf_bw_ofdm_20mhz = 0;
++	u16 tx_lpf_bw_ofdm_40mhz = 0;
++	u16 tx_lpf_bw_11b = 0;
++	u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
++	u16 txgm_idac_bleed = 0;
++	bool rccal_ovrd = false;
++	u16 freq;
++	int coreNum;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
++	else
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
++
++			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
++			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
++			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
++			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
++			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
++			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
++			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
++			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
++			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
++			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
++			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
++			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
++		}
++
++		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
++			write_phy_reg(pi, 0x23f, 0x1b0);
++			write_phy_reg(pi, 0x240, 0x1b0);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8))
++			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 2, 0x15e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
++		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
++
++		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
++		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
++		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
++
++		if (PHY_IPA(pi)) {
++
++			if (((pi->pubpi.radiorev == 5)
++			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				if ((pi->pubpi.radiorev == 5) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
++
++					rccal_tx20_11n_bcap = rccal_bcap_val;
++					rccal_tx20_11n_scap = rccal_scap_val;
++					rccal_tx40_11n_bcap = 0xc;
++					rccal_tx40_11n_scap = 0xc;
++
++					rccal_ovrd = true;
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					tx_lpf_bw_ofdm_20mhz = 4;
++					tx_lpf_bw_11b = 1;
++
++					if (CHSPEC_IS2G(pi->radio_chanspec)) {
++						rccal_tx20_11n_bcap = 0xc;
++						rccal_tx20_11n_scap = 0xc;
++						rccal_tx40_11n_bcap = 0xa;
++						rccal_tx40_11n_scap = 0xa;
++					} else {
++						rccal_tx20_11n_bcap = 0x14;
++						rccal_tx20_11n_scap = 0x14;
++						rccal_tx40_11n_bcap = 0xf;
++						rccal_tx40_11n_scap = 0xf;
++					}
++
++					rccal_ovrd = true;
++				}
++			}
++
++		} else {
++
++			if (pi->pubpi.radiorev == 5) {
++
++				tx_lpf_bw_ofdm_20mhz = 1;
++				tx_lpf_bw_ofdm_40mhz = 3;
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				rccal_tx20_11n_bcap = 0x13;
++				rccal_tx20_11n_scap = 0x11;
++				rccal_tx40_11n_bcap = 0x13;
++				rccal_tx40_11n_scap = 0x11;
++
++				rccal_ovrd = true;
++			}
++		}
++
++		if (rccal_ovrd) {
++
++			rx2tx_lpf_rc_lut_tx20_11b =
++				(rccal_tx20_11b_bcap << 8) |
++				(rccal_tx20_11b_scap << 3) |
++				tx_lpf_bw_11b;
++			rx2tx_lpf_rc_lut_tx20_11n =
++				(rccal_tx20_11n_bcap << 8) |
++				(rccal_tx20_11n_scap << 3) |
++				tx_lpf_bw_ofdm_20mhz;
++			rx2tx_lpf_rc_lut_tx40_11n =
++				(rccal_tx40_11n_bcap << 8) |
++				(rccal_tx40_11n_scap << 3) |
++				tx_lpf_bw_ofdm_40mhz;
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x152 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11b);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x153 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x154 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x155 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x156 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x157 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x158 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x159 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++			}
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		}
++
++		write_phy_reg(pi, 0x32f, 0x3);
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6)) {
++			if ((pi->sh->sromrev >= 8)
++			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
++				ipalvlshift_3p3_war_en = 1;
++
++			if (ipalvlshift_3p3_war_en) {
++				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
++						0x5);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
++						0x30);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
++					     0x1);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
++					     0x1);
++
++				ipa2g_mainbias = 0x1f;
++
++				ipa2g_casconv = 0x6f;
++
++				ipa2g_biasfilt = 0xaa;
++			} else {
++
++				ipa2g_mainbias = 0x2b;
++
++				ipa2g_casconv = 0x7f;
++
++				ipa2g_biasfilt = 0xee;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_IMAIN,
++							 ipa2g_mainbias);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_CASCONV,
++							 ipa2g_casconv);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 IPA2G_BIAS_FILTER,
++							 ipa2g_biasfilt);
++				}
++			}
++		}
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6))
++					txgm_idac_bleed = 0x7f;
++
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					if (txgm_idac_bleed != 0)
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							TXGM_IDAC_BLEED,
++							txgm_idac_bleed);
++				}
++
++				if (pi->pubpi.radiorev == 5) {
++
++					for (coreNum = 0; coreNum <= 1;
++					     coreNum++) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_CASCONV,
++								 0x13);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_IMAIN,
++								 0x1f);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							IPA2G_BIAS_FILTER,
++							0xee);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 PAD2G_IDACS,
++								 0x8a);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							PAD_BIAS_FILTER_BWS,
++							0x3e);
++					}
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					if (CHSPEC_IS40(pi->radio_chanspec) ==
++					    0) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x14);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x12);
++					} else {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x16);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x16);
++					}
++				}
++
++			} else {
++				freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
++							pi->radio_chanspec));
++				if (((freq >= 5180) && (freq <= 5230))
++				    || ((freq >= 5745) && (freq <= 5805))) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 0, IPA5G_BIAS_FILTER,
++							 0xff);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 1, IPA5G_BIAS_FILTER,
++							 0xff);
++				}
++			}
++		} else {
++
++			if (pi->pubpi.radiorev != 5) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXMIX2G_TUNE_BOOST_PU,
++							 0x61);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXGM_IDAC_BLEED, 0x70);
++				}
++			}
++		}
++
++		if (pi->pubpi.radiorev == 4) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl1_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl1_rev7);
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_VCM_CAL_MASTER, 0x0);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_I, 0x3f);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_Q, 0x3f);
++			}
++		} else {
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl2_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl2_rev7);
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
++		}
++
++		write_phy_reg(pi, 0x6a, 0x2);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
++					 &min_nvar_offset_6mbps);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
++					 &rfseq_pktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
++					 &rfseq_pktgn_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
++					 &rfseq_htpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
++					 &rfseq_cckpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
++					 &rfseq_tx2rx_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
++					 &rfseq_rx2tx_lpf_h_hpc_rev7);
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev7[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev7[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			}
++		} else if (pdetrange == 1) {
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x7c;
++				aux_adc_vmid_rev7_core1[3] = 0x7c;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x8c;
++				aux_adc_vmid_rev7_core1[3] = 0x8c;
++				aux_adc_gain_rev7[3] = 1;
++			}
++		} else if (pdetrange == 2) {
++			if (pi->pubpi.radioid == BCM2057_ID) {
++				if ((pi->pubpi.radiorev == 5)
++				    || (pi->pubpi.radiorev == 7)
++				    || (pi->pubpi.radiorev == 8)) {
++					if (chan_freq_range ==
++					    WL_CHAN_FREQ_RANGE_2G) {
++						aux_adc_vmid_rev7_core0[3] =
++							0x8c;
++						aux_adc_vmid_rev7_core1[3] =
++							0x8c;
++						aux_adc_gain_rev7[3] = 0;
++					} else {
++						aux_adc_vmid_rev7_core0[3] =
++							0x96;
++						aux_adc_vmid_rev7_core1[3] =
++							0x96;
++						aux_adc_gain_rev7[3] = 0;
++					}
++				}
++			}
++
++		} else if (pdetrange == 3) {
++			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x89;
++				aux_adc_vmid_rev7_core1[3] = 0x89;
++				aux_adc_gain_rev7[3] = 0;
++			}
++
++		} else if (pdetrange == 5) {
++
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
++					 &aux_adc_vmid_rev7_core0);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
++					 &aux_adc_vmid_rev7_core1);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
++					 &aux_adc_gain_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
++					 &aux_adc_gain_rev7);
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		write_phy_reg(pi, 0x23f, 0x1f8);
++		write_phy_reg(pi, 0x240, 0x1f8);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		write_phy_reg(pi, 0x38, 0xC);
++		write_phy_reg(pi, 0x2ae, 0xC);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
++				       rfseq_tx2rx_events_rev3,
++				       rfseq_tx2rx_dlys_rev3,
++				       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		if ((pi->sh->hw_phyrxchain != 0x3) &&
++		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
++
++			if (PHY_IPA(pi)) {
++				rfseq_rx2tx_dlys_rev3[5] = 59;
++				rfseq_rx2tx_dlys_rev3[6] = 1;
++				rfseq_rx2tx_events_rev3[7] =
++					NPHY_REV3_RFSEQ_CMD_END;
++			}
++
++			wlc_phy_set_rfseq_nphy(
++				pi, NPHY_RFSEQ_RX2TX,
++				rfseq_rx2tx_events_rev3,
++				rfseq_rx2tx_dlys_rev3,
++				ARRAY_SIZE(rfseq_rx2tx_events_rev3));
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x6a, 0x2);
++		else
++			write_phy_reg(pi, 0x6a, 0x9c40);
++
++		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev3[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev3[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++				aux_adc_vmid = aux_adc_vmid_rev4;
++				aux_adc_gain = aux_adc_gain_rev4;
++			} else {
++				aux_adc_vmid = aux_adc_vmid_rev3;
++				aux_adc_gain = aux_adc_gain_rev3;
++			}
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				switch (chan_freq_range) {
++				case WL_CHAN_FREQ_RANGE_5GL:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GM:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GH:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				default:
++					break;
++				}
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, aux_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, aux_adc_gain);
++		} else if (pdetrange == 1) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, sk_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, sk_adc_gain);
++		} else if (pdetrange == 2) {
++
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				chan_freq_range =
++					wlc_phy_get_chan_freq_range_nphy(pi, 0);
++				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++					bcm_adc_vmid[3] = 0x8e;
++					bcm_adc_gain[3] = 0x03;
++				} else {
++					bcm_adc_vmid[3] = 0x94;
++					bcm_adc_gain[3] = 0x03;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				bcm_adc_vmid[3] = 0x84;
++				bcm_adc_gain[3] = 0x02;
++			}
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		} else if (pdetrange == 3) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if ((NREV_GE(pi->pubpi.phy_rev, 4))
++			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
++
++				u16 auxadc_vmid[] = {
++					0xa2, 0xb4, 0xb4, 0x270
++				};
++				u16 auxadc_gain[] = {
++					0x02, 0x02, 0x02, 0x00
++				};
++
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x08, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x18, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x0c, 16, auxadc_gain);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x1c, 16, auxadc_gain);
++			}
++		} else if ((pdetrange == 4) || (pdetrange == 5)) {
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
++			u16 Vmid[2], Av[2];
++
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
++				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			} else {
++				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
++				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			}
++
++			bcm_adc_vmid[3] = Vmid[0];
++			bcm_adc_gain[3] = Av[0];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++
++			bcm_adc_vmid[3] = Vmid[1];
++			bcm_adc_gain[3] = Av[1];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
++				0x6);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
++				0x6);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
++				0x7);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
++				0x7);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
++				0x88);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
++				0x88);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		triso =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			triso : pi->srom_fem2g.triso;
++		if (triso == 7) {
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++		}
++
++		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
++
++		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
++		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
++		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
++		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
++		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
++			nss1_data_weights = 0x00088888;
++			ht_data_weights = 0x00088888;
++			stbc_data_weights = 0x00088888;
++		} else {
++			nss1_data_weights = 0x88888888;
++			ht_data_weights = 0x88888888;
++			stbc_data_weights = 0x88888888;
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 1, 32, &nss1_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 2, 32, &ht_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 3, 32, &stbc_data_weights);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX0, 0x70);
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX1, 0x70);
++			}
++		}
++
++		if (!pi->edcrs_threshold_lock) {
++			write_phy_reg(pi, 0x224, 0x3eb);
++			write_phy_reg(pi, 0x225, 0x3eb);
++			write_phy_reg(pi, 0x226, 0x341);
++			write_phy_reg(pi, 0x227, 0x341);
++			write_phy_reg(pi, 0x228, 0x42b);
++			write_phy_reg(pi, 0x229, 0x42b);
++			write_phy_reg(pi, 0x22a, 0x381);
++			write_phy_reg(pi, 0x22b, 0x381);
++			write_phy_reg(pi, 0x22c, 0x42b);
++			write_phy_reg(pi, 0x22d, 0x42b);
++			write_phy_reg(pi, 0x22e, 0x381);
++			write_phy_reg(pi, 0x22f, 0x381);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++
++			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
++					      MHF4_BPHY_TXCORE0,
++					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
++		}
++	} else {
++
++		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
++		    (pi->sh->boardtype == 0x8b)) {
++			uint i;
++			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
++			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
++				rfseq_rx2tx_dlys[i] = war_dlys[i];
++		}
++
++		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
++		} else {
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
++		}
++
++		regval = 0x000a;
++		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
++		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			regval = 0xcdaa;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			regval = 0x0000;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
++
++			regval = 0x7aab;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
++
++			regval = 0x0800;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
++		}
++
++		write_phy_reg(pi, 0xf8, 0x02d8);
++		write_phy_reg(pi, 0xf9, 0x0301);
++		write_phy_reg(pi, 0xfa, 0x02d8);
++		write_phy_reg(pi, 0xfb, 0x0301);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
++				       rfseq_rx2tx_dlys,
++				       ARRAY_SIZE(rfseq_rx2tx_events));
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
++				       rfseq_tx2rx_dlys,
++				       ARRAY_SIZE(rfseq_tx2rx_events));
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
++					       MHF3_NPHY_MLADV_WAR,
++					       MHF3_NPHY_MLADV_WAR,
++					       BRCM_BAND_ALL);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			write_phy_reg(pi, 0x1e3, 0x0);
++			write_phy_reg(pi, 0x1e4, 0x0);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
++
++			write_phy_reg(pi, 0x192, 0xb5);
++			write_phy_reg(pi, 0x193, 0xa4);
++			write_phy_reg(pi, 0x194, 0x0);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x221,
++				    NPHY_FORCESIG_DECODEGATEDCLKS,
++				    NPHY_FORCESIG_DECODEGATEDCLKS);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type = 2;
++	u16 addr_offset = 0x2c5;
++
++	for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++		write_phy_reg(pi, addr_offset + j,
++			      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++}
++
++static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals)
++{
++
++	if (write == 0) {
++		vals[0] = read_phy_reg(pi, 0x2c);
++		vals[1] = read_phy_reg(pi, 0x42);
++	} else {
++		write_phy_reg(pi, 0x2c, vals[0]);
++		write_phy_reg(pi, 0x42, vals[1]);
++	}
++}
++
++static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi)
++{
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x5);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xe);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0);
++
++				if (!NREV_IS(pi->pubpi.phy_rev, 7))
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x1);
++				else
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x31);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xc);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0);
++
++				if (pi->pubpi.radiorev != 5) {
++					if (!NREV_IS(pi->pubpi.phy_rev, 7))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x1);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++				}
++			}
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 0x0);
++		}
++	} else {
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
++				(CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
++				0x80);
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
++		WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
++					 0x8);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
++					 0x0);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x5);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIA, 0x0);
++				if (NREV_GE(pi->pubpi.phy_rev, 5))
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x31);
++				else
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x11);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xe);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIA, 0x31);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIG, 0x0);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xc);
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value,
++			     u8 core_mask, u8 off)
++{
++	u8 core_num;
++	u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
++		0, val_mask = 0;
++	u8 shift = 0, val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 2):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 1);
++				val_shift = 1;
++				break;
++			case (0x1 << 3):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 2);
++				val_shift = 2;
++				break;
++			case (0x1 << 4):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 4);
++				val_shift = 4;
++				break;
++			case (0x1 << 5):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 5);
++				val_shift = 5;
++				break;
++			case (0x1 << 6):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 7):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 7);
++				val_shift = 7;
++				break;
++			case (0x1 << 8):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 8);
++				val_shift = 8;
++				break;
++			case (0x1 << 11):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 13);
++				val_shift = 13;
++				break;
++
++			case (0x1 << 9):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 0);
++				val_shift = 0;
++				break;
++
++			case (0x1 << 10):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 4);
++				val_shift = 4;
++				break;
++
++			case (0x1 << 12):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7b : 0x7e;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 13):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7c : 0x7f;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 14):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x3 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 0):
++				en_addr = (core_num == 0) ? 0xe5 : 0xe6;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x1 << 15);
++				val_shift = 15;
++				break;
++			default:
++				addr = 0xffff;
++				break;
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	} else {
++
++		if (off) {
++			and_phy_reg(pi, 0xec, ~field);
++			value = 0x0;
++		} else {
++			or_phy_reg(pi, 0xec, field);
++		}
++
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++			case (0x1 << 9):
++			case (0x1 << 12):
++			case (0x1 << 13):
++			case (0x1 << 14):
++				addr = 0x78;
++
++				core_mask = 0x1;
++				break;
++			case (0x1 << 2):
++			case (0x1 << 3):
++			case (0x1 << 4):
++			case (0x1 << 5):
++			case (0x1 << 6):
++			case (0x1 << 7):
++			case (0x1 << 8):
++				addr = (core_num == 0) ? 0x7a : 0x7d;
++				break;
++			case (0x1 << 10):
++				addr = (core_num == 0) ? 0x7b : 0x7e;
++				break;
++			case (0x1 << 11):
++				addr = (core_num == 0) ? 0x7c : 0x7f;
++				break;
++			default:
++				addr = 0xffff;
++			}
++
++			switch (field) {
++			case (0x1 << 1):
++				mask = (0x7 << 3);
++				shift = 3;
++				break;
++			case (0x1 << 9):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 12):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 13):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 14):
++				mask = (0xf << 12);
++				shift = 12;
++				break;
++			case (0x1 << 2):
++				mask = (0x1 << 0);
++				shift = 0;
++				break;
++			case (0x1 << 3):
++				mask = (0x1 << 1);
++				shift = 1;
++				break;
++			case (0x1 << 4):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 5):
++				mask = (0x3 << 4);
++				shift = 4;
++				break;
++			case (0x1 << 6):
++				mask = (0x3 << 6);
++				shift = 6;
++				break;
++			case (0x1 << 7):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 8):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 10):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			case (0x1 << 11):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			default:
++				mask = 0x0;
++				shift = 0x0;
++				break;
++			}
++
++			if ((addr != 0xffff) && (core_mask & (1 << core_num)))
++				mod_phy_reg(pi, addr, mask, (value << shift));
++		}
++
++		or_phy_reg(pi, 0xec, (0x1 << 0));
++		or_phy_reg(pi, 0x78, (0x1 << 0));
++		udelay(1);
++		and_phy_reg(pi, 0xec, ~(0x1 << 0));
++	}
++}
++
++static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi)
++{
++	s32 rssi_buf[4];
++	s32 int_val;
++
++	if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
++
++		return;
++
++	if (PHY_IPA(pi))
++		wlc_phy_ipa_internal_tssi_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
++
++	udelay(20);
++	int_val =
++		wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
++				       1);
++	wlc_phy_stopplayback_nphy(pi);
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val >> 8) & 0xff);
++	} else {
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 16) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val) & 0xff);
++	}
++
++}
++
++static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi)
++{
++	u8 idx, idx2, i, delta_ind;
++
++	for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++)
++		pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
++
++	for (i = 0; i < 4; i++) {
++		idx2 = 0;
++
++		delta_ind = 0;
++
++		switch (i) {
++		case 0:
++
++			if (CHSPEC_IS40(pi->radio_chanspec)
++			    && NPHY_IS_SROM_REINTERPRET) {
++				idx = TXP_FIRST_MCS_40_SISO;
++			} else {
++				idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++				      TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
++				delta_ind = 1;
++			}
++			break;
++
++		case 1:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
++			break;
++
++		case 2:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
++			break;
++
++		case 3:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
++			break;
++		}
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + 1 - delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++	}
++}
++
++static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	s16 a1[2], b0[2], b1[2];
++	s8 target_pwr_qtrdbm[2];
++	s32 num, den, pwr_est;
++	u8 chan_freq_range;
++	u8 idle_tssi[2];
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[64];
++	u8 core;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0x122, (0x1 << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
++	else
++		or_phy_reg(pi, 0x1e7, (0x1 << 15));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	if (pi->sh->sromrev < 4) {
++		idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++		idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++		a1[0] = -424;
++		a1[1] = -424;
++		b0[0] = 5612;
++		b0[1] = 5612;
++		b1[1] = -1393;
++		b1[0] = -1393;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GL:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GM:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GH:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
++			break;
++		default:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = -424;
++			a1[1] = -424;
++			b0[0] = 5612;
++			b0[1] = 5612;
++			b1[1] = -1393;
++			b1[0] = -1393;
++			break;
++		}
++	}
++
++	/* use the provided transmit power */
++	target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
++	target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->srom_fem2g.tssipos)
++			or_phy_reg(pi, 0x1e9, (0x1 << 14));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			for (core = 0; core <= 1; core++) {
++				if (PHY_IPA(pi)) {
++					if (CHSPEC_IS2G(pi->radio_chanspec))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xe);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xc);
++				}
++			}
++		} else {
++			if (PHY_IPA(pi)) {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++			} else {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0, 0x11);
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1, 0x11);
++			}
++		}
++	}
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
++
++	write_phy_reg(pi, 0x1e9,
++		      (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
++
++	write_phy_reg(pi, 0x1ea,
++		      (target_pwr_qtrdbm[0] << 0) |
++		      (target_pwr_qtrdbm[1] << 8));
++
++	tbl_len = 64;
++	tbl_offset = 0;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		for (idx = 0; idx < tbl_len; idx++) {
++			num = 8 *
++			      (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
++			den = 32768 + a1[tbl_id - 26] * idx;
++			pwr_est = max(((4 * num + den / 2) / den), -8);
++			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++				if (idx <=
++				    (uint) (31 - idle_tssi[tbl_id - 26] + 1))
++					pwr_est =
++						max(pwr_est,
++						    target_pwr_qtrdbm
++						    [tbl_id - 26] + 1);
++			}
++			regval[idx] = (u32) pwr_est;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev4n6;
++			else if (pi->pubpi.radiorev == 3)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev3;
++			else if (pi->pubpi.radiorev == 5)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev5;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev7;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
++		}
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_5g_2057rev7;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
++		}
++	}
++
++	return tx_pwrctrl_tbl;
++}
++
++static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_rssical_chanspec_2G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_2G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_2G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_2G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_2G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_2G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_2G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_2G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_2G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_2G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_2G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_2G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_2G[11]);
++
++	} else {
++		if (pi->nphy_rssical_chanspec_5G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_5G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_5G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_5G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_5G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_5G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_5G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_5G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_5G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_5G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_5G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_5G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_5G[11]);
++	}
++}
++
++static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi)
++{
++	u16 txcal_gain[2];
++
++	pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
++	pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				txcal_gain);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
++	} else {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 txcal_gain);
++}
++
++static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi)
++{
++	bool save_bbmult = false;
++	u8 txcal_index_2057_rev5n7 = 0;
++	u8 txcal_index_2057_rev3n4n6 = 10;
++
++	if (pi->use_int_tx_iqlo_cal_nphy) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6)) {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev3n4n6;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev3n4n6;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev3n4n6,
++					false);
++			} else {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev5n7;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev5n7;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev5n7,
++					false);
++			}
++			save_bbmult = true;
++
++		} else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
++			wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
++			if (pi->sh->hw_phytxchain != 3) {
++				pi->nphy_txcal_pwr_idx[1] =
++					pi->nphy_txcal_pwr_idx[0];
++				wlc_phy_txpwr_index_nphy(pi, 3,
++							 pi->
++							 nphy_txcal_pwr_idx[0],
++							 true);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				} else {
++					pi->nphy_txcal_pwr_idx[0] = 80;
++					pi->nphy_txcal_pwr_idx[1] = 80;
++					wlc_phy_txpwr_index_nphy(pi, 3, 80,
++								 false);
++					save_bbmult = true;
++				}
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				else
++					wlc_phy_cal_txgainctrl_nphy(pi, 14,
++								    false);
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++		}
++
++	} else {
++		wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
++	}
++
++	if (save_bbmult)
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++					&pi->nphy_txcal_bbmult);
++}
++
++static void
++wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value,
++				 u8 core_code)
++{
++	u16 mask;
++	u16 val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (core_code == RADIO_MIMO_CORESEL_CORE1
++			    && core == PHY_CORE_1)
++				continue;
++			else if (core_code == RADIO_MIMO_CORESEL_CORE2
++				 && core == PHY_CORE_0)
++				continue;
++
++			if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++				mask = (0x1 << 10);
++				val = 1 << 10;
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					    0x92, mask, val);
++			}
++
++			if (field == NPHY_RfctrlIntc_override_OFF) {
++
++				write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					      0x92, 0);
++
++				wlc_phy_force_rfseq_nphy(pi,
++							 NPHY_RFSEQ_RESET2RX);
++			} else if (field == NPHY_RfctrlIntc_override_TRSW) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 6) | (0x1 << 7);
++
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 10));
++
++					and_phy_reg(pi, 0x2ff, (u16)
++						    ~(0x3 << 14));
++					or_phy_reg(pi, 0x2ff, (0x1 << 13));
++					or_phy_reg(pi, 0x2ff, (0x1 << 0));
++				} else {
++
++					mask = (0x1 << 6) |
++					       (0x1 << 7) |
++					       (0x1 << 8) | (0x1 << 9);
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					mask = (0x1 << 0);
++					val = 1 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++
++					mask = (core == PHY_CORE_0) ?
++					       (0x1 << 0) : (0x1 << 1);
++					val = 1 << ((core == PHY_CORE_0) ?
++						    0 : 1);
++					mod_phy_reg(pi, 0x78, mask, val);
++
++					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
++						  != 0), 10000);
++					if (WARN(read_phy_reg(pi, 0x78) & val,
++						 "HW error: override failed"))
++						return;
++
++					mask = (0x1 << 0);
++					val = 0 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++				}
++			} else if (field == NPHY_RfctrlIntc_override_PA) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 4) | (0x1 << 5);
++
++					if (CHSPEC_IS5G(pi->radio_chanspec))
++						val = value << 5;
++					else
++						val = value << 4;
++
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 12));
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 5);
++						val = value << 5;
++					} else {
++						mask = (0x1 << 4);
++						val = value << 4;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_PU) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 0);
++						val = value << 0;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 2);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 2);
++						val = value << 2;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 0);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 0);
++						val = value << 0;
++					} else {
++						mask = (0x1 << 2);
++						val = value << 2;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 1);
++						val = value << 1;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 3);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 3);
++						val = value << 3;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 1);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 1);
++						val = value << 1;
++					} else {
++						mask = (0x1 << 3);
++						val = value << 3;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			}
++		}
++	}
++}
++
++void
++wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower,
++			    bool debug)
++{
++	int gainctrl_loopidx;
++	uint core;
++	u16 m0m1, curr_m0m1;
++	s32 delta_power;
++	s32 txpwrindex;
++	s32 qdBm_power[2];
++	u16 orig_BBConfig;
++	u16 phy_saveregs[4];
++	u32 freq_test;
++	u16 ampl_test = 250;
++	uint stepsize;
++	bool phyhang_avoid_state = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		stepsize = 2;
++	else
++		stepsize = 1;
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		freq_test = 5000;
++	else
++		freq_test = 2500;
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phyhang_avoid_state = pi->phyhang_avoid;
++	pi->phyhang_avoid = false;
++
++	phy_saveregs[0] = read_phy_reg(pi, 0x91);
++	phy_saveregs[1] = read_phy_reg(pi, 0x92);
++	phy_saveregs[2] = read_phy_reg(pi, 0xe7);
++	phy_saveregs[3] = read_phy_reg(pi, 0xec);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (!debug) {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++	} else {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x7, RADIO_MIMO_CORESEL_CORE2);
++	}
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
++
++		for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
++		     gainctrl_loopidx++) {
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			if (core == PHY_CORE_0)
++				curr_m0m1 = m0m1 & 0xff00;
++			else
++				curr_m0m1 = m0m1 & 0x00ff;
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
++
++			udelay(50);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++
++			delta_power = (dBm_targetpower * 4) - qdBm_power[core];
++
++			txpwrindex -= stepsize * delta_power;
++			if (txpwrindex < 0)
++				txpwrindex = 0;
++			else if (txpwrindex > 127)
++				txpwrindex = 127;
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 4) &&
++				    (pi->srom_fem5g.extpagain == 3)) {
++					if (txpwrindex < 30)
++						txpwrindex = 30;
++				}
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++				    (pi->srom_fem2g.extpagain == 3)) {
++					if (txpwrindex < 50)
++						txpwrindex = 50;
++				}
++			}
++
++			wlc_phy_txpwr_index_nphy(pi, (1 << core),
++						 (u8) txpwrindex, true);
++		}
++
++		pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
++
++		if (debug) {
++			u16 radio_gain;
++			u16 dbg_m0m1;
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
++
++			udelay(100);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
++						&radio_gain);
++
++			mdelay(4000);
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++		}
++	}
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	write_phy_reg(pi, 0x91, phy_saveregs[0]);
++	write_phy_reg(pi, 0x92, phy_saveregs[1]);
++	write_phy_reg(pi, 0xe7, phy_saveregs[2]);
++	write_phy_reg(pi, 0xec, phy_saveregs[3]);
++
++	pi->phyhang_avoid = phyhang_avoid_state;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_savecal_nphy(struct brcms_phy *pi)
++{
++	void *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_2G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++	} else {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_5G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			txcal_radio_regs[2 * coreNum] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_I);
++			txcal_radio_regs[2 * coreNum + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_Q);
++
++			txcal_radio_regs[2 * coreNum + 4] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_I);
++			txcal_radio_regs[2 * coreNum + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_Q);
++		}
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi)
++{
++	struct nphy_iq_comp tx_comp;
++
++	wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, &tx_comp);
++
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
++}
++
++static void wlc_phy_restorecal_nphy(struct brcms_phy *pi)
++{
++	u16 *loft_comp;
++	u16 txcal_coeffs_bphy[4];
++	u16 *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_iqcal_chanspec_2G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
++	} else {
++		if (pi->nphy_iqcal_chanspec_5G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, tbl_ptr);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		txcal_coeffs_bphy[0] = tbl_ptr[0];
++		txcal_coeffs_bphy[1] = tbl_ptr[1];
++		txcal_coeffs_bphy[2] = tbl_ptr[2];
++		txcal_coeffs_bphy[3] = tbl_ptr[3];
++	} else {
++		txcal_coeffs_bphy[0] = 0;
++		txcal_coeffs_bphy[1] = 0;
++		txcal_coeffs_bphy[2] = 0;
++		txcal_coeffs_bphy[3] = 0;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
++				 txcal_coeffs_bphy);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_tx_iq_war_nphy(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_I,
++					 txcal_radio_regs[2 * coreNum]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_Q,
++					 txcal_radio_regs[2 * coreNum + 1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_I,
++					 txcal_radio_regs[2 * coreNum + 4]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_Q,
++					 txcal_radio_regs[2 * coreNum + 5]);
++		}
++	}
++}
++
++static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	u16 iqloCalbuf[7];
++	u32 iqcomp, locomp, curr_locomp;
++	s8 locomp_i, locomp_q;
++	s8 curr_locomp_i, curr_locomp_q;
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[128];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
++
++	tbl_len = 128;
++	tbl_offset = 320;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++		iqcomp =
++			(tbl_id ==
++			 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
++			(iqloCalbuf[1] & 0x3ff)
++			: (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
++			(iqloCalbuf[3] & 0x3ff);
++
++		for (idx = 0; idx < tbl_len; idx++)
++			regval[idx] = iqcomp;
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	tbl_offset = 448;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		locomp =
++			(u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
++		locomp_i = (s8) ((locomp >> 8) & 0xff);
++		locomp_q = (s8) ((locomp) & 0xff);
++		for (idx = 0; idx < tbl_len; idx++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				curr_locomp_i = locomp_i;
++				curr_locomp_q = locomp_q;
++			} else {
++				curr_locomp_i = (s8) ((locomp_i *
++						       nphy_tpc_loscale[idx] +
++						       128) >> 8);
++				curr_locomp_q =
++					(s8) ((locomp_q *
++					       nphy_tpc_loscale[idx] +
++					       128) >> 8);
++			}
++			curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
++			curr_locomp |= (u32) (curr_locomp_q & 0xff);
++			regval[idx] = curr_locomp;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi)
++{
++	u8 tx_lpf_bw = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			tx_lpf_bw = 3;
++		else
++			tx_lpf_bw = 1;
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 5;
++			else
++				tx_lpf_bw = 4;
++		}
++
++		write_phy_reg(pi, 0xe8,
++			      (tx_lpf_bw << 0) |
++			      (tx_lpf_bw << 3) |
++			      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++
++		if (PHY_IPA(pi)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 4;
++			else
++				tx_lpf_bw = 1;
++
++			write_phy_reg(pi, 0xe9,
++				      (tx_lpf_bw << 0) |
++				      (tx_lpf_bw << 3) |
++				      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						((pi->nphy_rccal_value +
++						  reduction_factr) | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						(pi->nphy_rccal_value | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = false;
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones,
++				 int *tone_id_buf, u32 *noise_var_buf)
++{
++	int i;
++	u32 offset;
++	int tone_id;
++	int tbllen =
++		CHSPEC_IS40(pi->radio_chanspec) ?
++		NPHY_NOISEVAR_TBLLEN40 : NPHY_NOISEVAR_TBLLEN20;
++
++	if (pi->nphy_noisevars_adjusted) {
++		for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
++			tone_id = pi->nphy_saved_noisevars.tone_id[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id *
++				   2) + 1) : (tbllen + (tone_id * 2) + 1);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_NOISEVAR, 1,
++				offset, 32,
++				&pi->nphy_saved_noisevars.min_noise_vars[i]);
++		}
++
++		pi->nphy_saved_noisevars.bufcount = 0;
++		pi->nphy_noisevars_adjusted = false;
++	}
++
++	if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
++		pi->nphy_saved_noisevars.bufcount = 0;
++
++		for (i = 0; i < ntones; i++) {
++			tone_id = tone_id_buf[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id * 2) + 1) :
++				 (tbllen + (tone_id * 2) + 1);
++			pi->nphy_saved_noisevars.tone_id[i] = tone_id;
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						offset, 32,
++						&pi->nphy_saved_noisevars.
++						min_noise_vars[i]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 offset, 32, &noise_var_buf[i]);
++			pi->nphy_saved_noisevars.bufcount++;
++		}
++
++		pi->nphy_noisevars_adjusted = true;
++	}
++}
++
++static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr)
++{
++	u16 regval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				pi->nphy_crsminpwr[0] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				pi->nphy_crsminpwr[1] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				pi->nphy_crsminpwr[2] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[0];
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[1];
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[2];
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = false;
++			}
++		}
++	}
++}
++
++static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
++{
++	u16 cur_channel = 0;
++	int nphy_adj_tone_id_buf[] = { 57, 58 };
++	u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
++	bool isAdjustNoiseVar = false;
++	uint numTonesAdjust = 0;
++	u32 tempval = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++		if (pi->nphy_gband_spurwar_en) {
++
++			wlc_phy_adjust_rx_analpfbw_nphy(
++				pi,
++				NPHY_ANARXLPFBW_REDUCTIONFACT);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((cur_channel == 11)
++				    && CHSPEC_IS40(pi->radio_chanspec))
++					wlc_phy_adjust_min_noisevar_nphy(
++						pi, 2,
++						nphy_adj_tone_id_buf,
++						nphy_adj_noise_var_buf);
++				else
++					wlc_phy_adjust_min_noisevar_nphy(pi, 0,
++									 NULL,
++									 NULL);
++			}
++
++			wlc_phy_adjust_crsminpwr_nphy(pi,
++						     NPHY_ADJUSTED_MINCRSPOWER);
++		}
++
++		if ((pi->nphy_gband_spurwar2_en)
++		    && CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				switch (cur_channel) {
++				case 3:
++					nphy_adj_tone_id_buf[0] = 57;
++					nphy_adj_tone_id_buf[1] = 58;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 4:
++					nphy_adj_tone_id_buf[0] = 41;
++					nphy_adj_tone_id_buf[1] = 42;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 5:
++					nphy_adj_tone_id_buf[0] = 25;
++					nphy_adj_tone_id_buf[1] = 26;
++					nphy_adj_noise_var_buf[0] = 0x24f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 6:
++					nphy_adj_tone_id_buf[0] = 9;
++					nphy_adj_tone_id_buf[1] = 10;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 7:
++					nphy_adj_tone_id_buf[0] = 121;
++					nphy_adj_tone_id_buf[1] = 122;
++					nphy_adj_noise_var_buf[0] = 0x18f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 8:
++					nphy_adj_tone_id_buf[0] = 105;
++					nphy_adj_tone_id_buf[1] = 106;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 9:
++					nphy_adj_tone_id_buf[0] = 89;
++					nphy_adj_tone_id_buf[1] = 90;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 10:
++					nphy_adj_tone_id_buf[0] = 73;
++					nphy_adj_tone_id_buf[1] = 74;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				default:
++					isAdjustNoiseVar = false;
++					break;
++				}
++			}
++
++			if (isAdjustNoiseVar) {
++				numTonesAdjust = ARRAY_SIZE(nphy_adj_tone_id_buf);
++
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi,
++					numTonesAdjust,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++
++				tempval = 0;
++
++			} else {
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++			}
++		}
++
++		if ((pi->nphy_aband_spurwar_en) &&
++		    (CHSPEC_IS5G(pi->radio_chanspec))) {
++			switch (cur_channel) {
++			case 54:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x25f;
++				break;
++			case 38:
++			case 102:
++			case 118:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			case 134:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x21f;
++				break;
++			case 151:
++				nphy_adj_tone_id_buf[0] = 16;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			case 153:
++			case 161:
++				nphy_adj_tone_id_buf[0] = 48;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			default:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			}
++
++			if (nphy_adj_tone_id_buf[0]
++			    && nphy_adj_noise_var_buf[0])
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi, 1,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++			else
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++		}
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++}
++
++void wlc_phy_init_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++	u16 clip1_ths[2];
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool do_nphy_cal = false;
++	uint core;
++	u32 d11_clk_ctl_st;
++	bool do_rssi_cal = false;
++
++	core = 0;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
++	    ((pi->sh->chippkg == BCM4717_PKG_ID) ||
++	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
++		if ((pi->sh->boardflags & BFL_EXTLNA) &&
++		    (CHSPEC_IS2G(pi->radio_chanspec)))
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, chipcontrol),
++				  0x40, 0x40);
++	}
++
++	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
++	    CHSPEC_IS40(pi->radio_chanspec)) {
++
++		d11_clk_ctl_st = bcma_read32(pi->d11core,
++					     D11REGOFFS(clk_ctl_st));
++		bcma_mask32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			    ~(CCS_FORCEHT | CCS_HTAREQ));
++
++		bcma_write32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			     d11_clk_ctl_st);
++	}
++
++	pi->use_int_tx_iqlo_cal_nphy =
++		(PHY_IPA(pi) ||
++		 (NREV_GE(pi->pubpi.phy_rev, 7) ||
++		  (NREV_GE(pi->pubpi.phy_rev, 5)
++		   && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
++
++	pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
++
++	pi->nphy_deaf_count = 0;
++
++	wlc_phy_tbl_init_nphy(pi);
++
++	pi->nphy_crsminpwr_adjusted = false;
++	pi->nphy_noisevars_adjusted = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xe7, 0);
++		write_phy_reg(pi, 0xec, 0);
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_phy_reg(pi, 0x342, 0);
++			write_phy_reg(pi, 0x343, 0);
++			write_phy_reg(pi, 0x346, 0);
++			write_phy_reg(pi, 0x347, 0);
++		}
++		write_phy_reg(pi, 0xe5, 0);
++		write_phy_reg(pi, 0xe6, 0);
++	} else {
++		write_phy_reg(pi, 0xec, 0);
++	}
++
++	write_phy_reg(pi, 0x91, 0);
++	write_phy_reg(pi, 0x92, 0);
++	if (NREV_LT(pi->pubpi.phy_rev, 6)) {
++		write_phy_reg(pi, 0x93, 0);
++		write_phy_reg(pi, 0x94, 0);
++	}
++
++	and_phy_reg(pi, 0xa1, ~3);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0x8f, 0);
++		write_phy_reg(pi, 0xa5, 0);
++	} else {
++		write_phy_reg(pi, 0xa5, 0);
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++	else if (NREV_LT(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++	write_phy_reg(pi, 0x203, 32);
++	write_phy_reg(pi, 0x201, 32);
++
++	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
++		write_phy_reg(pi, 0x20d, 160);
++	else
++		write_phy_reg(pi, 0x20d, 184);
++
++	write_phy_reg(pi, 0x13a, 200);
++
++	write_phy_reg(pi, 0x70, 80);
++
++	write_phy_reg(pi, 0x1ff, 48);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 8))
++		wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
++
++	wlc_phy_stf_chain_upd_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		write_phy_reg(pi, 0x180, 0xaa8);
++		write_phy_reg(pi, 0x181, 0x9a4);
++	}
++
++	if (PHY_IPA(pi)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 0), (1) << 0);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7),
++				    (pi->nphy_papd_epsilon_offset[core]) << 7);
++
++		}
++
++		wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++		wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
++	}
++
++	wlc_phy_workarounds_nphy(pi);
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
++
++	wlc_phy_pa_override_nphy(pi, OFF);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	wlc_phy_pa_override_nphy(pi, ON);
++
++	wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_phy_bphy_init_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_txpwr_fixpower_nphy(pi);
++
++	wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u32 *tx_pwrctrl_tbl = NULL;
++		u16 idx;
++		s16 pga_gn = 0;
++		s16 pad_gn = 0;
++		s32 rfpwr_offset;
++
++		if (PHY_IPA(pi)) {
++			tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev3;
++				else if (NREV_IS(pi->pubpi.phy_rev, 4))
++					tx_pwrctrl_tbl =
++						(pi->srom_fem5g.extpagain ==
++						 3) ?
++						nphy_tpc_5GHz_txgain_HiPwrEPA :
++						nphy_tpc_5GHz_txgain_rev4;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev5;
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (pi->pubpi.radiorev == 5)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev5;
++					else if (pi->pubpi.radiorev == 3)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev3;
++				} else {
++					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3))
++						tx_pwrctrl_tbl =
++						       nphy_tpc_txgain_HiPwrEPA;
++					else
++						tx_pwrctrl_tbl =
++							nphy_tpc_txgain_rev3;
++				}
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++
++		pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
++				rfpwr_offset = get_rf_pwr_offset(pi, pga_gn,
++								 pad_gn);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++		} else {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_2g
++								       [pga_gn];
++				else
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_5g
++								       [pga_gn];
++
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++
++		}
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++	}
++
++	if (pi->sh->phyrxchain != 0x3)
++		wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi,
++					     pi->sh->phyrxchain);
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi))
++		wlc_phy_cal_perical_mphase_restart(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_rssical_chanspec_2G == 0) :
++			      (pi->nphy_rssical_chanspec_5G == 0);
++
++		if (do_rssi_cal)
++			wlc_phy_rssi_cal_nphy(pi);
++		else
++			wlc_phy_restore_rssical_nphy(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy(pi);
++	}
++
++	if (!SCAN_RM_IN_PROGRESS(pi))
++		do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_iqcal_chanspec_2G == 0) :
++			      (pi->nphy_iqcal_chanspec_5G == 0);
++
++	if (!pi->do_initcal)
++		do_nphy_cal = false;
++
++	if (do_nphy_cal) {
++
++		target_gain = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (pi->antsel_type == ANTSEL_2x3)
++			wlc_phy_antsel_init((struct brcms_phy_pub *) pi,
++					    true);
++
++		if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				pi->nphy_cal_orig_pwr_idx[0] =
++					pi->nphy_txpwrindex[PHY_CORE_0]
++					.
++					index_internal;
++				pi->nphy_cal_orig_pwr_idx[1] =
++					pi->nphy_txpwrindex[PHY_CORE_1]
++					.
++					index_internal;
++
++				wlc_phy_precal_txgain_nphy(pi);
++				target_gain =
++					wlc_phy_get_tx_gain_nphy(pi);
++			}
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, target_gain, true,
++				    false) == 0) {
++				if (wlc_phy_cal_rxiq_nphy
++					    (pi, target_gain, 2,
++					    false) == 0)
++					wlc_phy_savecal_nphy(pi);
++
++			}
++		} else if (pi->mphase_cal_phase_id ==
++			   MPHASE_CAL_STATE_IDLE) {
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_PHYINIT);
++		}
++	} else {
++		wlc_phy_restorecal_nphy(pi);
++	}
++
++	wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
++
++		write_phy_reg(pi, 0x70, 50);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	wlc_phy_spurwar_nphy(pi);
++
++}
++
++static void wlc_phy_resetcca_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	udelay(1);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++}
++
++void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en)
++{
++	u16 rfctrlintc_override_val;
++
++	if (!en) {
++
++		pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
++		pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			rfctrlintc_override_val = 0x1480;
++		else if (NREV_GE(pi->pubpi.phy_rev, 3))
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
++		else
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++
++		write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++		write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	} else {
++		write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
++		write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
++	}
++
++}
++
++void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi)
++{
++
++	u16 txrx_chain =
++		(NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
++	bool CoreActv_override = false;
++
++	if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			and_phy_reg(pi, 0xa0, ~0x20);
++	} else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			or_phy_reg(pi, 0xa0, 0x20);
++	}
++
++	mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
++
++	if (CoreActv_override) {
++		pi->nphy_perical = PHY_PERICAL_DISABLE;
++		or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	} else {
++		pi->nphy_perical = PHY_PERICAL_MPHASE;
++		and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
++	}
++}
++
++void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
++{
++	u16 regval;
++	u16 tbl_buf[16];
++	uint i;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 tbl_opcode;
++	bool suspend;
++
++	pi->sh->phyrxchain = rxcore_bitmask;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	regval = read_phy_reg(pi, 0xa2);
++	regval &= ~(0xf << 4);
++	regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
++	write_phy_reg(pi, 0xa2, regval);
++
++	if ((rxcore_bitmask & 0x3) != 0x3) {
++
++		write_phy_reg(pi, 0x20e, 1);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry == -1) {
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							ARRAY_SIZE(tbl_buf), 80,
++							16, tbl_buf);
++
++				for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
++					if (tbl_buf[i] ==
++					    NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
++						pi->rx2tx_biasentry = (u8) i;
++						tbl_opcode =
++							NPHY_REV3_RFSEQ_CMD_NOP;
++						wlc_phy_table_write_nphy(
++							pi,
++							NPHY_TBL_ID_RFSEQ,
++							1, i,
++							16,
++							&tbl_opcode);
++						break;
++					} else if (tbl_buf[i] ==
++						   NPHY_REV3_RFSEQ_CMD_END)
++						break;
++				}
++			}
++		}
++	} else {
++
++		write_phy_reg(pi, 0x20e, 30);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry != -1) {
++				tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
++				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							 1, pi->rx2tx_biasentry,
++							 16, &tbl_opcode);
++				pi->rx2tx_biasentry = -1;
++			}
++		}
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
++{
++	u16 regval, rxen_bits;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	regval = read_phy_reg(pi, 0xa2);
++	rxen_bits = (regval >> 4) & 0xf;
++
++	return (u8) rxen_bits;
++}
++
++bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi)
++{
++	return PHY_IPA(pi);
++}
++
++void wlc_phy_cal_init_nphy(struct brcms_phy *pi)
++{
++}
++
++static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++	and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
++
++}
++
++static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
++{
++	struct radio_20xx_regs *regs_2057_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++		regs_2057_ptr = regs_2057_rev4;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++		   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++
++			if (NREV_IS(pi->pubpi.phy_rev, 8))
++				regs_2057_ptr = regs_2057_rev5;
++			else if (NREV_IS(pi->pubpi.phy_rev, 9))
++				regs_2057_ptr = regs_2057_rev5v1;
++			break;
++
++		case 7:
++
++			regs_2057_ptr = regs_2057_rev7;
++			break;
++
++		case 8:
++
++			regs_2057_ptr = regs_2057_rev8;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
++}
++
++static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi)
++{
++	u16 rcal_reg = 0;
++	int i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (pi->pubpi.radiorev == 5) {
++
++			and_phy_reg(pi, 0x342, ~(0x1 << 1));
++
++			udelay(10);
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x1);
++		}
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
++
++		udelay(10);
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
++			if (rcal_reg & 0x1)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib2"))
++			return 0;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
++
++		rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
++		if (pi->pubpi.radiorev == 5) {
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x0);
++		}
++
++		if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++			mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
++				      rcal_reg);
++			mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
++				      rcal_reg << 2);
++		}
++
++	} else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		u16 savereg;
++
++		savereg =
++			read_radio_reg(
++				pi,
++				RADIO_2056_SYN_PLL_MAST2 |
++				RADIO_2056_SYN);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg | 0x7);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x9);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(
++				pi,
++				RADIO_2056_SYN_RCAL_CODE_OUT |
++				RADIO_2056_SYN);
++			if (rcal_reg & 0x80)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib3"))
++			return 0;
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++
++		rcal_reg =
++			read_radio_reg(pi,
++				       RADIO_2056_SYN_RCAL_CODE_OUT |
++				       RADIO_2056_SYN);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x0);
++
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg);
++
++		return rcal_reg & 0x1f;
++	}
++	return rcal_reg & 0x3e;
++}
++
++static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi)
++{
++	u16 rccal_valid;
++	int i;
++	bool chip43226_6362A0;
++
++	chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
++			    || (pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6));
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
++		return 0;
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	return rccal_valid;
++}
++
++static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi)
++{
++
++	mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
++	mdelay(2);
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
++
++	if (pi->phy_init_por) {
++		wlc_phy_radio205x_rcal(pi);
++		wlc_phy_radio2057_rccal(pi);
++	}
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
++}
++
++static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++	const struct radio_regs *regs_TX_2056_ptr = NULL;
++	const struct radio_regs *regs_RX_2056_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		regs_SYN_2056_ptr = regs_SYN_2056;
++		regs_TX_2056_ptr = regs_TX_2056;
++		regs_RX_2056_ptr = regs_RX_2056;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++		regs_TX_2056_ptr = regs_TX_2056_A1;
++		regs_RX_2056_ptr = regs_RX_2056_A1;
++	} else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			regs_TX_2056_ptr = regs_TX_2056_rev5;
++			regs_RX_2056_ptr = regs_RX_2056_rev5;
++			break;
++
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			regs_TX_2056_ptr = regs_TX_2056_rev6;
++			regs_RX_2056_ptr = regs_RX_2056_rev6;
++			break;
++
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			regs_TX_2056_ptr = regs_TX_2056_rev7;
++			regs_RX_2056_ptr = regs_RX_2056_rev7;
++			break;
++
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			regs_TX_2056_ptr = regs_TX_2056_rev8;
++			regs_RX_2056_ptr = regs_RX_2056_rev8;
++			break;
++
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			regs_TX_2056_ptr = regs_TX_2056_rev11;
++			regs_RX_2056_ptr = regs_RX_2056_rev11;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
++}
++
++static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi)
++{
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
++	udelay(1000);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
++
++	if ((pi->sh->boardflags2 & BFL2_LEGACY)
++	    || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN))
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
++	else
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
++
++	if (pi->phy_init_por)
++		wlc_phy_radio205x_rcal(pi);
++}
++
++static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
++}
++
++static void wlc_phy_radio_init_2055(struct brcms_phy *pi)
++{
++	wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
++}
++
++static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi)
++{
++
++	and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
++		      ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
++
++	if (((pi->sh->sromrev >= 4)
++	     && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
++	    || ((pi->sh->sromrev < 4))) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
++		and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
++	write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
++
++	and_radio_reg(pi, RADIO_2055_CAL_MISC,
++		      ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
++
++	or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
++
++	udelay(1000);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
++
++	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
++
++	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		  RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
++		 "HW error: radio calibration1\n"))
++		return;
++
++	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
++		      ~(RADIO_2055_CAL_LPO_ENABLE));
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
++
++	mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	if (pi->nphy_gain_boost) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++		and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++	} else {
++		or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++		or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++	}
++
++	udelay(2);
++}
++
++void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on)
++{
++	if (on) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (!pi->radio_is_on) {
++				wlc_phy_radio_preinit_205x(pi);
++				wlc_phy_radio_init_2057(pi);
++				wlc_phy_radio_postinit_2057(pi);
++			}
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_radio_preinit_205x(pi);
++			wlc_phy_radio_init_2056(pi);
++			wlc_phy_radio_postinit_2056(pi);
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else {
++			wlc_phy_radio_preinit_2055(pi);
++			wlc_phy_radio_init_2055(pi);
++			wlc_phy_radio_postinit_2055(pi);
++		}
++
++		pi->radio_is_on = true;
++
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX0, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX1, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++
++			pi->radio_is_on = false;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			pi->radio_is_on = false;
++		}
++
++	}
++}
++
++static bool
++wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
++		       const struct chan_info_nphy_radio2057 **t0,
++		       const struct chan_info_nphy_radio205x **t1,
++		       const struct chan_info_nphy_radio2057_rev5 **t2,
++		       const struct chan_info_nphy_2055 **t3)
++{
++	uint i;
++	const struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL;
++	const struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL;
++	u32 tbl_len = 0;
++
++	int freq = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++			   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++			switch (pi->pubpi.radiorev) {
++
++			case 5:
++
++				if (pi->pubpi.radiover == 0x0) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev8_2057_rev5;
++					tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev5);
++
++				} else if (pi->pubpi.radiover == 0x1) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev9_2057_rev5v1;
++					tbl_len = ARRAY_SIZE(
++						chan_info_nphyrev9_2057_rev5v1);
++
++				}
++				break;
++
++			case 7:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev7;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev7);
++				break;
++
++			case 8:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev8;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev8);
++				break;
++
++			default:
++				break;
++			}
++		} else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
++		} else {
++			goto fail;
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (pi->pubpi.radiorev == 5) {
++
++				if (chan_info_tbl_p_2[i].chan == channel)
++					break;
++			} else {
++
++				if (chan_info_tbl_p_0[i].chan == channel)
++					break;
++			}
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		if (pi->pubpi.radiorev == 5) {
++			*t2 = &chan_info_tbl_p_2[i];
++			freq = chan_info_tbl_p_2[i].freq;
++		} else {
++			*t0 = &chan_info_tbl_p_0[i];
++			freq = chan_info_tbl_p_0[i].freq;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)
++			   || NREV_IS(pi->pubpi.phy_rev, 6)) {
++			switch (pi->pubpi.radiorev) {
++			case 5:
++				chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
++				break;
++			case 6:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
++				break;
++			case 7:
++			case 9:
++				chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
++				tbl_len =
++					ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
++				break;
++			case 8:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
++				break;
++			case 11:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
++				tbl_len = ARRAY_SIZE(
++						    chan_info_nphyrev6_2056v11);
++				break;
++			default:
++				break;
++			}
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (chan_info_tbl_p_1[i].chan == channel)
++				break;
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		*t1 = &chan_info_tbl_p_1[i];
++		freq = chan_info_tbl_p_1[i].freq;
++
++	} else {
++		for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
++			if (chan_info_nphy_2055[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_nphy_2055))
++			goto fail;
++
++		*t3 = &chan_info_nphy_2055[i];
++		freq = chan_info_nphy_2055[i].freq;
++	}
++
++	*f = freq;
++	return true;
++
++fail:
++	*f = WL_CHAN_FREQ_RANGE_2G;
++	return false;
++}
++
++u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (channel == 0)
++		channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++	wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		return WL_CHAN_FREQ_RANGE_2G;
++
++	if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GL;
++	else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GM;
++	else
++		return WL_CHAN_FREQ_RANGE_5GH;
++}
++
++static void
++wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_2055 *ci)
++{
++
++	write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
++	write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
++			ci->RF_core1_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
++			ci->RF_core1_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
++			ci->RF_core1_tx_pga_pad_tn);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
++			ci->RF_core1_tx_mx_bgtrim);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
++			ci->RF_core2_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
++			ci->RF_core2_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
++			ci->RF_core2_tx_pga_pad_tn);
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
++			ci->RF_core2_tx_mx_bgtrim);
++
++	udelay(50);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_radio205x *ci)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++
++	write_radio_reg(pi,
++			RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
++			ci->RF_SYN_pll_refdiv);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter3);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter4);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter5);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr27);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr28);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr29);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_VCOBUF1);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_MIXER2);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF3);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF4);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixg_boost_tune);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixg_boost_tune);
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3))
++		regs_SYN_2056_ptr = regs_SYN_2056;
++	else if (NREV_IS(pi->pubpi.phy_rev, 4))
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++	else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			break;
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			break;
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			break;
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			break;
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			break;
++		}
++	}
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
++	else
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
++
++	if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0xb);
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0x14);
++		}
++	}
++
++	if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
++	    (CHSPEC_IS2G(pi->radio_chanspec))) {
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++				0xb);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
++				0x20);
++	}
++
++	if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0x5);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0xc);
++		}
++	}
++
++	if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 pag_boost_tune;
++		u16 padg_boost_tune;
++		u16 pgag_boost_tune;
++		u16 mixg_boost_tune;
++		u16 bias, cascbias;
++		uint core;
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_IDAC, 0xcc);
++
++				bias = 0x25;
++				cascbias = 0x20;
++
++				if ((pi->sh->chip ==
++				     BCM43224_CHIP_ID)
++				    || (pi->sh->chip ==
++					BCM43225_CHIP_ID)) {
++					if (pi->sh->chippkg ==
++					    BCM43224_FAB_SMIC) {
++						bias = 0x2a;
++						cascbias = 0x38;
++					}
++				}
++
++				pag_boost_tune = 0x4;
++				pgag_boost_tune = 0x03;
++				padg_boost_tune = 0x77;
++				mixg_boost_tune = 0x65;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, cascbias);
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_BOOST_TUNE,
++						 pag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PGAG_BOOST_TUNE,
++						 pgag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_BOOST_TUNE,
++						 padg_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 MIXG_BOOST_TUNE,
++						 mixg_boost_tune);
++			} else {
++
++				bias = (pi->bw == WL_CHANSPEC_BW_40) ?
++				       0x40 : 0x20;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, 0x30);
++			}
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
++					 0xee);
++		}
++	}
++
++	if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
++	    && CHSPEC_IS5G(pi->radio_chanspec)) {
++		u16 paa_boost_tune;
++		u16 pada_boost_tune;
++		u16 pgaa_boost_tune;
++		u16 mixa_boost_tune;
++		u16 freq, pabias, cascbias;
++		uint core;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++
++		if (freq < 5150) {
++
++			paa_boost_tune = 0xa;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xf;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5340) {
++
++			paa_boost_tune = 0x8;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xfb;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5650) {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xb;
++			mixa_boost_tune = 0xf;
++		} else {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			if (freq != 5825)
++				pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
++			else
++				pgaa_boost_tune = 6;
++
++			mixa_boost_tune = 0xf;
++		}
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_BOOST_TUNE, paa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_BOOST_TUNE, pada_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PGAA_BOOST_TUNE, pgaa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 MIXA_BOOST_TUNE, mixa_boost_tune);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 TXSPARE1, 0x30);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PA_SPARE2, 0xee);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_CASCBIAS, 0x3);
++
++			cascbias = 0x30;
++
++			if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++			    (pi->sh->chip == BCM43225_CHIP_ID)) {
++				if (pi->sh->chippkg == BCM43224_FAB_SMIC)
++					cascbias = 0x35;
++			}
++
++			pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IAUX_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IMAIN_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_CASCBIAS, cascbias);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
++			      (1 << 2));
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
++	}
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2057_setup(
++	struct brcms_phy *pi,
++	const struct chan_info_nphy_radio2057 *ci,
++	const struct chan_info_nphy_radio2057_rev5 *
++	ci2)
++{
++	int coreNum;
++	u16 txmix2g_tune_boost_pu = 0;
++	u16 pad2g_tune_pus = 0;
++
++	if (pi->pubpi.radiorev == 5) {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci2->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci2->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci2->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci2->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci2->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci2->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
++				ci2->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
++		write_radio_reg(pi,
++				RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci2->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci2->RF_logen_indbuf2g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci2->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci2->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci2->RF_lna2g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci2->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci2->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci2->RF_lna2g_tune_core1);
++
++	} else {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
++		write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
++				ci->RF_logen_mx5g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci->RF_logen_indbuf2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
++				ci->RF_logen_indbuf5g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
++				ci->RF_pga_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
++				ci->RF_txmix5g_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
++				ci->RF_pad5g_tune_misc_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci->RF_lna2g_tune_core0);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
++				ci->RF_lna5g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
++				ci->RF_pga_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
++				ci->RF_txmix5g_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
++				ci->RF_pad5g_tune_misc_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci->RF_lna2g_tune_core1);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
++				ci->RF_lna5g_tune_core1);
++	}
++
++	if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x3f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++	} else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
++		   (pi->pubpi.radiorev == 8)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1b);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0xa);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0xa);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (PHY_IPA(pi)) {
++			if (pi->pubpi.radiorev == 3)
++				txmix2g_tune_boost_pu = 0x6b;
++
++			if (pi->pubpi.radiorev == 5)
++				pad2g_tune_pus = 0x73;
++
++		} else {
++			if (pi->pubpi.radiorev != 5) {
++				pad2g_tune_pus = 0x3;
++
++				txmix2g_tune_boost_pu = 0x61;
++			}
++		}
++
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			if (txmix2g_tune_boost_pu != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 TXMIX2G_TUNE_BOOST_PU,
++						 txmix2g_tune_boost_pu);
++
++			if (pad2g_tune_pus != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 PAD2G_TUNE_PUS,
++						 pad2g_tune_pus);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++static void
++wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
++			    const struct nphy_sfo_cfg *ci)
++{
++	u16 val;
++
++	val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (CHSPEC_IS5G(chanspec) && !val) {
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			   (BBCFG_RESETCCA | BBCFG_RESETRX));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++
++		or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
++	} else if (!CHSPEC_IS5G(chanspec) && val) {
++
++		and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			    (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++	}
++
++	write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
++	write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
++	write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
++
++	write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
++	write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
++	write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
++
++		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
++	} else {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
++					NPHY_ClassifierCtrl_ofdm_en);
++
++		if (CHSPEC_IS2G(chanspec))
++			and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
++	}
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++		wlc_phy_txpwr_fixpower_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)
++	    && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
++		u8 spuravoid = 0;
++
++		val = CHSPEC_CHANNEL(chanspec);
++		if (!CHSPEC_IS40(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				if ((val == 13) || (val == 14) || (val == 153))
++					spuravoid = 1;
++			} else if (((val >= 5) && (val <= 8)) || (val == 13)
++				   || (val == 14)) {
++				spuravoid = 1;
++			}
++		} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (val == 54)
++				spuravoid = 1;
++		} else {
++			if (pi->nphy_aband_spurwar_en &&
++			    ((val == 38) || (val == 102)
++			     || (val == 118)))
++				spuravoid = 1;
++		}
++
++		if (pi->phy_spuravoid == SPURAVOID_FORCEON)
++			spuravoid = 1;
++
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
++		si_pmu_spuravoid_pllupdate(pi->sh->sih, spuravoid);
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++		    (pi->sh->chip == BCM43225_CHIP_ID)) {
++			if (spuravoid == 1) {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x5341);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			} else {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x8889);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			}
++		}
++
++		wlapi_bmac_core_phypll_reset(pi->sh->physhim);
++
++		mod_phy_reg(pi, 0x01, (0x1 << 15),
++			    ((spuravoid > 0) ? (0x1 << 15) : 0));
++
++		wlc_phy_resetcca_nphy(pi);
++
++		pi->phy_isspuravoid = (spuravoid > 0);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0x17e, 0x3830);
++
++	wlc_phy_spurwar_nphy(pi);
++}
++
++void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (!wlc_phy_chan2freq_nphy
++		    (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
++		return;
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	if (CHSPEC_BW(chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
++
++	if (CHSPEC_IS40(chanspec)) {
++		if (CHSPEC_SB_UPPER(chanspec)) {
++			or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
++		} else {
++			and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				and_phy_reg(pi, 0x310,
++					    (~PRIM_SEL_UP20 & 0xffff));
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++			}
++
++			wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(pi->pubpi.radiorev == 5) ?
++				(const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) :
++				(const struct nphy_sfo_cfg *)&(t0->PHY_BW1a));
++
++		} else {
++
++			mod_radio_reg(pi,
++				      RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
++				      0x4,
++				      (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
++			wlc_phy_chanspec_radio2056_setup(pi, t1);
++
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(const struct nphy_sfo_cfg *) &(t1->PHY_BW1a));
++		}
++
++	} else {
++
++		mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
++			      (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
++			       : (0x05 << 4)));
++
++		wlc_phy_chanspec_radio2055_setup(pi, t3);
++		wlc_phy_chanspec_nphy_setup(pi, chanspec,
++					    (const struct nphy_sfo_cfg *)
++					     &(t3->PHY_BW1a));
++	}
++
++}
++
++void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 mask = 0xfc00;
++	u32 mc = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
++
++		if (!lut_init)
++			return;
++
++		if (pi->srom_fem2g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x02, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x03, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x08, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x0C, 16, &v3);
++		}
++
++		if (pi->srom_fem5g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x12, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x13, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x18, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x1C, 16, &v3);
++		}
++	} else {
++
++		write_phy_reg(pi, 0xc8, 0x0);
++		write_phy_reg(pi, 0xc9, 0x0);
++
++		bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask);
++
++		mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		mc &= ~MCTL_GPOUT_SEL_MASK;
++		bcma_write32(pi->d11core, D11REGOFFS(maccontrol), mc);
++
++		bcma_set16(pi->d11core, D11REGOFFS(psm_gpio_oe), mask);
++
++		bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), ~mask);
++
++		if (lut_init) {
++			write_phy_reg(pi, 0xf8, 0x02d8);
++			write_phy_reg(pi, 0xf9, 0x0301);
++			write_phy_reg(pi, 0xfa, 0x02d8);
++			write_phy_reg(pi, 0xfb, 0x0301);
++		}
++	}
++}
++
++u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
++{
++	u16 curr_ctl, new_ctl;
++	bool suspended = false;
++
++	if (D11REV_IS(pi->sh->corerev, 16)) {
++		suspended = (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			     MCTL_EN_MAC) ? false : true;
++		if (!suspended)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
++
++	new_ctl = (curr_ctl & (~mask)) | (val & mask);
++
++	mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
++
++	if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return new_ctl;
++}
++
++void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd)
++{
++	u16 trigger_mask, status_mask;
++	u16 orig_RfseqCoreActv;
++
++	switch (cmd) {
++	case NPHY_RFSEQ_RX2TX:
++		trigger_mask = NPHY_RfseqTrigger_rx2tx;
++		status_mask = NPHY_RfseqStatus_rx2tx;
++		break;
++	case NPHY_RFSEQ_TX2RX:
++		trigger_mask = NPHY_RfseqTrigger_tx2rx;
++		status_mask = NPHY_RfseqStatus_tx2rx;
++		break;
++	case NPHY_RFSEQ_RESET2RX:
++		trigger_mask = NPHY_RfseqTrigger_reset2rx;
++		status_mask = NPHY_RfseqStatus_reset2rx;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINH:
++		trigger_mask = NPHY_RfseqTrigger_updategainh;
++		status_mask = NPHY_RfseqStatus_updategainh;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINL:
++		trigger_mask = NPHY_RfseqTrigger_updategainl;
++		status_mask = NPHY_RfseqStatus_updategainl;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINU:
++		trigger_mask = NPHY_RfseqTrigger_updategainu;
++		status_mask = NPHY_RfseqStatus_updategainu;
++		break;
++	default:
++		return;
++	}
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1,
++		   (NPHY_RfseqMode_CoreActv_override |
++		    NPHY_RfseqMode_Trigger_override));
++	or_phy_reg(pi, 0xa3, trigger_mask);
++	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
++}
++
++static void
++wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value,
++				     u8 core_mask, u8 off)
++{
++	u16 rfmxgain = 0, lpfgain = 0;
++	u16 tgain = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		switch (cmd) {
++		case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 3), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 0,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 1,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rxgain:
++			rfmxgain = value & 0x000ff;
++			lpfgain = value & 0x0ff00;
++			lpfgain = lpfgain >> 8;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11),
++				rfmxgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x3 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_txgain:
++			tgain = value & 0x7fff;
++			lpfgain = value & 0x8000;
++			lpfgain = lpfgain >> 14;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 12),
++				tgain, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		}
++	}
++}
++
++static void
++wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset,
++			       u8 coresel, u8 rail, u8 rssi_type)
++{
++	u16 valuetostuff;
++
++	offset = (offset > NPHY_RSSICAL_MAXREAD) ?
++		 NPHY_RSSICAL_MAXREAD : offset;
++	offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
++		 -NPHY_RSSICAL_MAXREAD - 1 : offset;
++
++	valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1a6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1ac, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b2, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1a4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1aa, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b0, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1a5, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1ab, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b1, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b7, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1a7, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1ad, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b3, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b9, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1a8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ae, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1b4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ba, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1a9, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1b5, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1af, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1bb, valuetostuff);
++}
++
++static void brcms_phy_wr_tx_mux(struct brcms_phy *pi, u8 core)
++{
++	if (PHY_IPA(pi)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++		else
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					0x11);
++
++			if (pi->pubpi.radioid == BCM2057_ID)
++				write_radio_reg(pi,
++						RADIO_2057_IQTEST_SEL_PU, 0x1);
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					0x11);
++		}
++	}
++}
++
++void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type)
++{
++	u16 mask, val;
++	u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
++	    startseq;
++	u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
++	    rfctrlovr_trigger_val;
++	u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
++	u16 rfctrlcmd_val, rfctrlovr_val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
++
++			mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
++			mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
++
++			mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
++			mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
++
++			mask = (0x1 << 2) |
++			       (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
++			mod_phy_reg(pi, 0xf9, mask, 0);
++			mod_phy_reg(pi, 0xfb, mask, 0);
++
++		} else {
++			for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++				if (core_code == RADIO_MIMO_CORESEL_CORE1
++				    && core == PHY_CORE_1)
++					continue;
++				else if (core_code == RADIO_MIMO_CORESEL_CORE2
++					 && core == PHY_CORE_0)
++					continue;
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ?
++					    0x8f : 0xa5, (0x1 << 9), 1 << 9);
++
++				if (rssi_type == NPHY_RSSI_SEL_W1 ||
++				    rssi_type == NPHY_RSSI_SEL_W2 ||
++				    rssi_type == NPHY_RSSI_SEL_NB) {
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xa6 : 0xa7,
++						    (0x3 << 8), 0);
++
++					mask = (0x1 << 2) |
++					       (0x1 << 3) |
++					       (0x1 << 4) | (0x1 << 5);
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, 0);
++
++					if (rssi_type == NPHY_RSSI_SEL_W1) {
++						if (CHSPEC_IS5G(
++							  pi->radio_chanspec)) {
++							mask = (0x1 << 2);
++							val = 1 << 2;
++						} else {
++							mask = (0x1 << 3);
++							val = 1 << 3;
++						}
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_W2) {
++						mask = (0x1 << 4);
++						val = 1 << 4;
++					} else {
++						mask = (0x1 << 5);
++						val = 1 << 5;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, val);
++
++					mask = (0x1 << 5);
++					val = 1 << 5;
++					mod_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xe5 : 0xe6, mask, val);
++				} else {
++					if (rssi_type == NPHY_RSSI_SEL_TBD) {
++						mask = (0x3 << 8);
++						val = 1 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 1 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_IQ) {
++						mask = (0x3 << 8);
++						val = 2 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 2 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else {
++						mask = (0x3 << 8);
++						val = 3 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 3 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						brcms_phy_wr_tx_mux(pi, core);
++						afectrlovr_rssi_val = 1 << 9;
++						mod_phy_reg(pi,
++							   (core ==
++							    PHY_CORE_0) ? 0x8f
++							   : 0xa5, (0x1 << 9),
++							   afectrlovr_rssi_val);
++					}
++				}
++			}
++		}
++	} else {
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB))
++			val = 0x0;
++		else if (rssi_type == NPHY_RSSI_SEL_TBD)
++			val = 0x1;
++		else if (rssi_type == NPHY_RSSI_SEL_IQ)
++			val = 0x2;
++		else
++			val = 0x3;
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (val << 12) | (val << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			if (rssi_type == NPHY_RSSI_SEL_W1)
++				val = 0x1;
++			if (rssi_type == NPHY_RSSI_SEL_W2)
++				val = 0x2;
++			if (rssi_type == NPHY_RSSI_SEL_NB)
++				val = 0x3;
++
++			mask = (0x3 << 4);
++			val = (val << 4);
++			mod_phy_reg(pi, 0x7a, mask, val);
++			mod_phy_reg(pi, 0x7d, mask, val);
++		}
++
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			afectrlovr_rssi_val = 0;
++			rfctrlcmd_rxen_val = 0;
++			rfctrlcmd_coresel_val = 0;
++			rfctrlovr_rssi_val = 0;
++			rfctrlovr_rxen_val = 0;
++			rfctrlovr_coresel_val = 0;
++			rfctrlovr_trigger_val = 0;
++			startseq = 0;
++		} else {
++			afectrlovr_rssi_val = 1;
++			rfctrlcmd_rxen_val = 1;
++			rfctrlcmd_coresel_val = core_code;
++			rfctrlovr_rssi_val = 1;
++			rfctrlovr_rxen_val = 1;
++			rfctrlovr_coresel_val = 1;
++			rfctrlovr_trigger_val = 1;
++			startseq = 1;
++		}
++
++		afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
++		afectrlovr_rssi_val = (afectrlovr_rssi_val <<
++				       12) | (afectrlovr_rssi_val << 13);
++		mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
++			    afectrlovr_rssi_val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
++			rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
++					(rfctrlcmd_coresel_val << 3);
++
++			rfctrlovr_mask = ((0x1 << 5) |
++					  (0x1 << 12) |
++					  (0x1 << 1) | (0x1 << 0));
++			rfctrlovr_val = (rfctrlovr_rssi_val <<
++					 5) |
++					(rfctrlovr_rxen_val << 12) |
++					(rfctrlovr_coresel_val << 1) |
++					(rfctrlovr_trigger_val << 0);
++
++			mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
++			mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
++
++			mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
++			udelay(20);
++
++			mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++		}
++	}
++}
++
++int
++wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf,
++		       u8 nsamps)
++{
++	s16 rssi0, rssi1;
++	u16 afectrlCore1_save = 0;
++	u16 afectrlCore2_save = 0;
++	u16 afectrlOverride1_save = 0;
++	u16 afectrlOverride2_save = 0;
++	u16 rfctrlOverrideAux0_save = 0;
++	u16 rfctrlOverrideAux1_save = 0;
++	u16 rfctrlMiscReg1_save = 0;
++	u16 rfctrlMiscReg2_save = 0;
++	u16 rfctrlcmd_save = 0;
++	u16 rfctrloverride_save = 0;
++	u16 rfctrlrssiothers1_save = 0;
++	u16 rfctrlrssiothers2_save = 0;
++	s8 tmp_buf[4];
++	u8 ctr = 0, samp = 0;
++	s32 rssi_out_val;
++	u16 gpiosel_orig;
++
++	afectrlCore1_save = read_phy_reg(pi, 0xa6);
++	afectrlCore2_save = read_phy_reg(pi, 0xa7);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++		rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++		afectrlOverride1_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++		rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	} else {
++		afectrlOverride1_save = read_phy_reg(pi, 0xa5);
++		rfctrlcmd_save = read_phy_reg(pi, 0x78);
++		rfctrloverride_save = read_phy_reg(pi, 0xec);
++		rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
++		rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
++	}
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	gpiosel_orig = read_phy_reg(pi, 0xca);
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, 5);
++
++	for (ctr = 0; ctr < 4; ctr++)
++		rssi_buf[ctr] = 0;
++
++	for (samp = 0; samp < nsamps; samp++) {
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			rssi0 = read_phy_reg(pi, 0x1c9);
++			rssi1 = read_phy_reg(pi, 0x1ca);
++		} else {
++			rssi0 = read_phy_reg(pi, 0x219);
++			rssi1 = read_phy_reg(pi, 0x21a);
++		}
++
++		ctr = 0;
++		tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
++
++		for (ctr = 0; ctr < 4; ctr++)
++			rssi_buf[ctr] += tmp_buf[ctr];
++
++	}
++
++	rssi_out_val = rssi_buf[3] & 0xff;
++	rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
++	rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
++	rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, gpiosel_orig);
++
++	write_phy_reg(pi, 0xa6, afectrlCore1_save);
++	write_phy_reg(pi, 0xa7, afectrlCore2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
++		write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride1_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
++		write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
++	} else {
++		write_phy_reg(pi, 0xa5, afectrlOverride1_save);
++		write_phy_reg(pi, 0x78, rfctrlcmd_save);
++		write_phy_reg(pi, 0xec, rfctrloverride_save);
++		write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
++		write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
++	}
++
++	return rssi_out_val;
++}
++
++s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi)
++{
++	u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
++	u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
++	u16 pwrdet_rxtx_core1_save;
++	u16 pwrdet_rxtx_core2_save;
++	u16 afectrlCore1_save;
++	u16 afectrlCore2_save;
++	u16 afectrlOverride_save;
++	u16 afectrlOverride2_save;
++	u16 pd_pll_ts_save;
++	u16 gpioSel_save;
++	s32 radio_temp[4];
++	s32 radio_temp2[4];
++	u16 syn_tempprocsense_save;
++	s16 offset = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
++		u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
++		u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
++		s32 auxADC_Vl;
++		u16 RfctrlOverride5_save, RfctrlOverride6_save;
++		u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
++		u16 RSSIMultCoef0QPowerDet_save;
++		u16 tempsense_Rcal;
++
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
++		RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++		RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					&auxADC_Vmid_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					&auxADC_Av_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					&auxADC_rssi_ctrlL_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					&auxADC_rssi_ctrlH_save);
++
++		write_phy_reg(pi, 0x1ae, 0x0);
++
++		auxADC_rssi_ctrlL = 0x0;
++		auxADC_rssi_ctrlH = 0x20;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH);
++
++		tempsense_Rcal = syn_tempprocsense_save & 0x1c;
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
++		mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
++
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++		udelay(5);
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
++		mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
++
++		auxADC_Vmid = 0xA3;
++		auxADC_Av = 0x0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x03);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++
++		auxADC_Av = 0x7;
++		if (radio_temp[1] + radio_temp2[1] < -30) {
++			auxADC_Vmid = 0x45;
++			auxADC_Vl = 263;
++		} else if (radio_temp[1] + radio_temp2[1] < -9) {
++			auxADC_Vmid = 0x200;
++			auxADC_Vl = 467;
++		} else if (radio_temp[1] + radio_temp2[1] < 11) {
++			auxADC_Vmid = 0x266;
++			auxADC_Vl = 634;
++		} else {
++			auxADC_Vmid = 0x2D5;
++			auxADC_Vl = 816;
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
++		write_phy_reg(pi, 0x346, RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, RfctrlOverride6_save);
++		write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH_save);
++
++		radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
++				 + 82 * (auxADC_Vl) - 28861 +
++				 128) / 256;
++
++		offset = (s16) pi->phy_tempsense_offset;
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		if (NREV_LT(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
++		else
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		radio_temp[0] =
++			(126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++
++		offset = (s16) pi->phy_tempsense_offset;
++	} else {
++
++		pwrdet_rxtx_core1_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pwrdet_rxtx_core2_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++		core1_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		core1_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		core2_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		core2_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
++		radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
++		radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
++		radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] + radio_temp[1] + radio_temp[2] +
++			 radio_temp[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] +
++			 (8 * 32)) * (950 - 350) / 63 + (350 * 8);
++
++		radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
++
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pwrdet_rxtx_core1_save);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pwrdet_rxtx_core2_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				core1_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				core2_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				core1_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				core2_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride_save);
++	}
++
++	return (s16) radio_temp[0] + offset;
++}
++
++static void
++wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf)
++{
++	u8 core;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (rssi_type == NPHY_RSSI_SEL_NB) {
++			if (core == PHY_CORE_0) {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			} else {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			}
++		} else {
++			if (core == PHY_CORE_0)
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++			else
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++		}
++	}
++}
++
++static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi)
++{
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 clip_off[] = { 0xffff, 0xffff };
++	s32 target_code;
++	u8 vcm, min_vcm;
++	u8 vcm_final = 0;
++	u8 result_idx;
++	s32 poll_results[8][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_result_core[4] = { 0, 0, 0, 0 };
++	s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++	u8 vcm_level_max;
++	u8 core;
++	u8 wb_cnt;
++	u8 rssi_type;
++	u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
++	u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
++	u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
++	u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
++	u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
++	u16 NPHY_RfctrlCmd_save;
++	u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
++	u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
++	u8 rxcore_state;
++	u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
++	u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
++	u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
++	u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
++
++	NPHY_REV7_RfctrlOverride3_save =
++		NPHY_REV7_RfctrlOverride4_save =
++		NPHY_REV7_RfctrlOverride5_save =
++		NPHY_REV7_RfctrlOverride6_save =
++		NPHY_REV7_RfctrlMiscReg3_save =
++		NPHY_REV7_RfctrlMiscReg4_save =
++		NPHY_REV7_RfctrlMiscReg5_save =
++		NPHY_REV7_RfctrlMiscReg6_save = 0;
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
++	NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
++	NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
++	NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
++	NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
++	NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
++	NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
++	NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
++		NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
++		NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++	}
++	NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++	NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
++	NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++	NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
++		NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
++		NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++	}
++	NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
++	NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
++			0, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rx_pu,
++			1, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
++	}
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
++		}
++
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
++		}
++	}
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	vcm_level_max = 8;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
++
++		for (vcm = 0; vcm < vcm_level_max; vcm++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				mod_radio_reg(pi, (core == PHY_CORE_0) ?
++					      RADIO_2057_NB_MASTER_CORE0 :
++					      RADIO_2057_NB_MASTER_CORE1,
++					      RADIO_2057_VCM_MASK, vcm);
++			else
++				mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++					      ((core ==
++						PHY_CORE_0) ? RADIO_2056_RX0 :
++					       RADIO_2056_RX1),
++					      RADIO_2056_VCM_MASK,
++					      vcm << RADIO_2056_RSSI_VCM_SHIFT);
++
++			wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
++					       &poll_results[vcm][0],
++					       NPHY_RSSICAL_NPOLL);
++		}
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if ((core == result_idx / 2) &&
++			    (result_idx % 2 == 0)) {
++
++				min_d = NPHY_RSSICAL_MAXD;
++				min_vcm = 0;
++				min_poll =
++					NPHY_RSSICAL_MAXREAD *
++					NPHY_RSSICAL_NPOLL + 1;
++				for (vcm = 0; vcm < vcm_level_max; vcm++) {
++					curr_d =
++						poll_results[vcm][result_idx] *
++						poll_results[vcm][result_idx] +
++						poll_results[vcm][result_idx +
++								  1] *
++						poll_results[vcm][result_idx +
++								  1];
++					if (curr_d < min_d) {
++						min_d = curr_d;
++						min_vcm = vcm;
++					}
++					if (poll_results[vcm][result_idx] <
++					    min_poll)
++						min_poll =
++							poll_results[vcm]
++							[result_idx];
++				}
++				vcm_final = min_vcm;
++				poll_results_min[result_idx] = min_poll;
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mod_radio_reg(pi, (core == PHY_CORE_0) ?
++				      RADIO_2057_NB_MASTER_CORE0 :
++				      RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK, vcm_final);
++		else
++			mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++				      ((core ==
++					PHY_CORE_0) ? RADIO_2056_RX0 :
++				       RADIO_2056_RX1), RADIO_2056_VCM_MASK,
++				      vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if (core == result_idx / 2) {
++				fine_digital_offset[result_idx] =
++					(NPHY_RSSICAL_NB_TARGET *
++					 NPHY_RSSICAL_NPOLL) -
++					poll_results[vcm_final][result_idx];
++				if (fine_digital_offset[result_idx] < 0) {
++					fine_digital_offset[result_idx] =
++						abs(fine_digital_offset
++						    [result_idx]);
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++					fine_digital_offset[result_idx] =
++						-fine_digital_offset[
++								    result_idx];
++				} else {
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++				}
++
++				if (poll_results_min[result_idx] ==
++				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++					fine_digital_offset[result_idx] =
++						(NPHY_RSSICAL_NB_TARGET -
++						 NPHY_RSSICAL_MAXREAD - 1);
++
++				wlc_phy_scale_offset_rssi_nphy(
++					pi, 0x0,
++					(s8)
++					fine_digital_offset
++					[result_idx],
++					(result_idx / 2 == 0) ?
++					RADIO_MIMO_CORESEL_CORE1 :
++					RADIO_MIMO_CORESEL_CORE2,
++					(result_idx % 2 == 0) ?
++					NPHY_RAIL_I : NPHY_RAIL_Q,
++					NPHY_RSSI_SEL_NB);
++			}
++		}
++
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
++			if (wb_cnt == 0) {
++				rssi_type = NPHY_RSSI_SEL_W1;
++				target_code = NPHY_RSSICAL_W1_TARGET_REV3;
++			} else {
++				rssi_type = NPHY_RSSI_SEL_W2;
++				target_code = NPHY_RSSICAL_W2_TARGET_REV3;
++			}
++
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_I, rssi_type);
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_Q, rssi_type);
++
++			wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
++					       NPHY_RSSICAL_NPOLL);
++
++			for (result_idx = 0; result_idx < 4; result_idx++) {
++				if (core == result_idx / 2) {
++					fine_digital_offset[result_idx] =
++						(target_code *
++						 NPHY_RSSICAL_NPOLL) -
++						poll_result_core[result_idx];
++					if (fine_digital_offset[result_idx] <
++					    0) {
++						fine_digital_offset[result_idx]
++							= abs(
++							    fine_digital_offset
++							    [result_idx]);
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++						fine_digital_offset[result_idx]
++							= -fine_digital_offset
++								[result_idx];
++					} else {
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++					}
++
++					wlc_phy_scale_offset_rssi_nphy(
++						pi, 0x0,
++						(s8)
++						fine_digital_offset
++						[core *
++						 2],
++						(core == PHY_CORE_0) ?
++						RADIO_MIMO_CORESEL_CORE1 :
++						RADIO_MIMO_CORESEL_CORE2,
++						(result_idx % 2 == 0) ?
++						NPHY_RAIL_I :
++						NPHY_RAIL_Q,
++						rssi_type);
++				}
++			}
++
++		}
++	}
++
++	write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
++	write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
++
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++
++	write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
++	write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
++	write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
++	write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
++	write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
++	write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
++		write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
++		write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
++	}
++	write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
++	write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
++	write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
++	write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
++	write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
++		write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
++		write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
++	}
++	write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
++	write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_2G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_2G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_2G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_2G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_2G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_2G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_2G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_2G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_2G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_2G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_2G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_2G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_5G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_5G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_5G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_5G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_5G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_5G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_5G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_5G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_5G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_5G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_5G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_5G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
++	}
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++}
++
++static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
++{
++	s32 target_code;
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 rssi_ctrl_state[2], pd_state[2];
++	u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
++	u16 rfctrlintc_override_val;
++	u16 clip_off[] = { 0xffff, 0xffff };
++	u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
++	u8 vcm, min_vcm, vcm_tmp[4];
++	u8 vcm_final[4] = { 0, 0, 0, 0 };
++	u8 result_idx, ctr;
++	s32 poll_results[4][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_miniq[4][2] = {
++		{0, 0},
++		{0, 0},
++		{0, 0},
++		{0, 0}
++	};
++	s32 min_d, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++
++	switch (rssi_type) {
++	case NPHY_RSSI_SEL_NB:
++		target_code = NPHY_RSSICAL_NB_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W1:
++		target_code = NPHY_RSSICAL_W1_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W2:
++		target_code = NPHY_RSSICAL_W2_TARGET;
++		break;
++	default:
++		return;
++		break;
++	}
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
++	rfctrlintc_override_val =
++		CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
++
++	rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
++	rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
++	write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
++
++	rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
++	rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
++	write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
++
++	pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
++		  RADIO_2055_WBRSSI_G2_PD;
++	pd_state[0] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
++	pd_state[1] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
++	rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
++			 RADIO_2055_WBRSSI_G2_SEL;
++	rssi_ctrl_state[0] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
++	rssi_ctrl_state[1] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_I, rssi_type);
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_Q, rssi_type);
++
++	for (vcm = 0; vcm < 4; vcm++) {
++
++		vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
++		if (rssi_type != NPHY_RSSI_SEL_W2)
++			wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
++
++		wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
++				       NPHY_RSSICAL_NPOLL);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1)
++		    || (rssi_type == NPHY_RSSI_SEL_W2)) {
++			for (ctr = 0; ctr < 2; ctr++)
++				poll_miniq[vcm][ctr] =
++					min(poll_results[vcm][ctr * 2 + 0],
++					    poll_results[vcm][ctr * 2 + 1]);
++		}
++	}
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		min_d = NPHY_RSSICAL_MAXD;
++		min_vcm = 0;
++		min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
++		for (vcm = 0; vcm < 4; vcm++) {
++			curr_d = abs(((rssi_type == NPHY_RSSI_SEL_NB) ?
++				      poll_results[vcm][result_idx] :
++				      poll_miniq[vcm][result_idx / 2]) -
++				     (target_code * NPHY_RSSICAL_NPOLL));
++			if (curr_d < min_d) {
++				min_d = curr_d;
++				min_vcm = vcm;
++			}
++			if (poll_results[vcm][result_idx] < min_poll)
++				min_poll = poll_results[vcm][result_idx];
++		}
++		vcm_final[result_idx] = min_vcm;
++		poll_results_min[result_idx] = min_poll;
++	}
++
++	if (rssi_type != NPHY_RSSI_SEL_W2)
++		wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		fine_digital_offset[result_idx] =
++			(target_code * NPHY_RSSICAL_NPOLL) -
++			poll_results[vcm_final[result_idx]][result_idx];
++		if (fine_digital_offset[result_idx] < 0) {
++			fine_digital_offset[result_idx] =
++				abs(fine_digital_offset[result_idx]);
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++			fine_digital_offset[result_idx] =
++				-fine_digital_offset[result_idx];
++		} else {
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++		}
++
++		if (poll_results_min[result_idx] ==
++		    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++			fine_digital_offset[result_idx] =
++				(target_code - NPHY_RSSICAL_MAXREAD - 1);
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
++					       (s8)
++					       fine_digital_offset[result_idx],
++					       (result_idx / 2 ==
++						0) ? RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       (result_idx % 2 ==
++						0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
++					       rssi_type);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
++	if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
++
++	write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
++	write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++
++	wlc_phy_resetcca_nphy(pi);
++}
++
++void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		wlc_phy_rssi_cal_nphy_rev3(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
++	}
++}
++
++int
++wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh)
++{
++	s16 rxpwr, rxpwr0, rxpwr1;
++	s16 phyRx0_l, phyRx2_l;
++
++	rxpwr = 0;
++	rxpwr0 = rxh->PhyRxStatus_1 & PRXS1_nphy_PWR0_MASK;
++	rxpwr1 = (rxh->PhyRxStatus_1 & PRXS1_nphy_PWR1_MASK) >> 8;
++
++	if (rxpwr0 > 127)
++		rxpwr0 -= 256;
++	if (rxpwr1 > 127)
++		rxpwr1 -= 256;
++
++	phyRx0_l = rxh->PhyRxStatus_0 & 0x00ff;
++	phyRx2_l = rxh->PhyRxStatus_2 & 0x00ff;
++	if (phyRx2_l > 127)
++		phyRx2_l -= 256;
++
++	if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
++		rxpwr0 = rxpwr1;
++		rxpwr1 = phyRx2_l;
++	}
++
++	if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
++		rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
++		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
++		rxpwr = (rxpwr0 + rxpwr1) >> 1;
++
++	return rxpwr;
++}
++
++static void
++wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf,
++			     u16 num_samps)
++{
++	u16 t;
++	u32 *data_buf = NULL;
++
++	data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
++	if (data_buf == NULL)
++		return;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	for (t = 0; t < num_samps; t++)
++		data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
++			      (((unsigned int)tone_buf[t].q) & 0x3ff);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
++				 data_buf);
++
++	kfree(data_buf);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16
++wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++			      u8 dac_test_mode)
++{
++	u8 phy_bw, is_phybw40;
++	u16 num_samps, t, spur;
++	s32 theta = 0, rot = 0;
++	u32 tbl_len;
++	struct cordic_iq *tone_buf = NULL;
++
++	is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++	phy_bw = (is_phybw40 == 1) ? 40 : 20;
++	tbl_len = (phy_bw << 3);
++
++	if (dac_test_mode == 1) {
++		spur = read_phy_reg(pi, 0x01);
++		spur = (spur >> 15) & 1;
++		phy_bw = (spur == 1) ? 82 : 80;
++		phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
++
++		tbl_len = (phy_bw << 1);
++	}
++
++	tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC);
++	if (tone_buf == NULL)
++		return 0;
++
++	num_samps = (u16) tbl_len;
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_buf[t] = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
++		tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
++	}
++
++	wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
++
++	kfree(tone_buf);
++
++	return num_samps;
++}
++
++static void
++wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops,
++			u16 wait, u8 iqmode, u8 dac_test_mode,
++			bool modify_bbmult)
++{
++	u16 bb_mult;
++	u8 phy_bw, sample_cmd;
++	u16 orig_RfseqCoreActv;
++	u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
++	    lpf_bw_ctl_miscreg4;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phy_bw = 20;
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
++		lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
++		if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		} else {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
++
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		}
++	}
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					&bb_mult);
++		pi->nphy_bb_mult_save =
++			BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
++	}
++
++	if (modify_bbmult) {
++		bb_mult = (phy_bw == 20) ? 100 : 71;
++		bb_mult = (bb_mult << 8) + bb_mult;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	write_phy_reg(pi, 0xc6, num_samps - 1);
++
++	if (loops != 0xffff)
++		write_phy_reg(pi, 0xc4, loops - 1);
++	else
++		write_phy_reg(pi, 0xc4, loops);
++
++	write_phy_reg(pi, 0xc5, wait);
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	if (iqmode) {
++
++		and_phy_reg(pi, 0xc2, 0x7FFF);
++
++		or_phy_reg(pi, 0xc2, 0x8000);
++	} else {
++
++		sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
++		write_phy_reg(pi, 0xc3, sample_cmd);
++	}
++
++	SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
++
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++}
++
++int
++wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++		     u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
++{
++	u16 num_samps;
++	u16 loops = 0xffff;
++	u16 wait = 0;
++
++	num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val,
++						  dac_test_mode);
++	if (num_samps == 0)
++		return -EBADE;
++
++	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
++				dac_test_mode, modify_bbmult);
++
++	return 0;
++}
++
++void wlc_phy_stopplayback_nphy(struct brcms_phy *pi)
++{
++	u16 playback_status;
++	u16 bb_mult;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	playback_status = read_phy_reg(pi, 0xc7);
++	if (playback_status & 0x1)
++		or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
++	else if (playback_status & 0x2)
++		and_phy_reg(pi, 0xc2,
++			    (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
++
++	and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
++
++		bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++
++		pi->nphy_bb_mult_save = 0;
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
++		if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
++		}
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *brcms_phy_get_tx_pwrctrl_tbl(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++	uint phyrev = pi->pubpi.phy_rev;
++
++	if (PHY_IPA(pi)) {
++		tx_pwrctrl_tbl =
++			wlc_phy_get_ipa_gaintbl_nphy(pi);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_IS(phyrev, 3))
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3;
++			else if (NREV_IS(phyrev, 4))
++				tx_pwrctrl_tbl =
++					(pi->srom_fem5g.extpagain == 3) ?
++					nphy_tpc_5GHz_txgain_HiPwrEPA :
++					nphy_tpc_5GHz_txgain_rev4;
++			else
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev5;
++		} else {
++			if (NREV_GE(phyrev, 7)) {
++				if (pi->pubpi.radiorev == 3)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev3;
++				else if (pi->pubpi.radiorev == 5)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev5;
++			} else {
++				if (NREV_GE(phyrev, 5) &&
++				   (pi->srom_fem2g.extpagain ==	3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_HiPwrEPA;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_rev3;
++			}
++		}
++	}
++	return tx_pwrctrl_tbl;
++}
++
++struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi)
++{
++	u16 base_idx[2], curr_gain[2];
++	u8 core_no;
++	struct nphy_txgains target_gain;
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++					curr_gain);
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0007;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F8) >> 3);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++				target_gain.txlpf[core_no] =
++					((curr_gain[core_no] & 0x8000) >> 15);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x000F;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F0) >> 4);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++			} else {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0003;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x000C) >> 2);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0070) >> 4);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x0380) >> 7);
++			}
++		}
++	} else {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
++		base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(phyrev, 3)) {
++				tx_pwrctrl_tbl =
++					brcms_phy_get_tx_pwrctrl_tbl(pi);
++				if (NREV_GE(phyrev, 7)) {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0x7;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 19) & 0x1f;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 28) & 0x7;
++					target_gain.txlpf[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 31) & 0x1;
++				} else {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0xf;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 20) & 0xf;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						[base_idx[core_no]]
++						 >> 28) & 0x7;
++				}
++			} else {
++				target_gain.ipa[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 16) & 0x3;
++				target_gain.pad[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 18) & 0x3;
++				target_gain.pga[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 20) & 0x7;
++				target_gain.txgm[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 23) & 0x7;
++			}
++		}
++	}
++
++	return target_gain;
++}
++
++static void
++wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no,
++			      struct nphy_txgains target_gain,
++			      struct nphy_iqcal_params *params)
++{
++	u8 k;
++	int idx;
++	u16 gain_index;
++	u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->txlpf = target_gain.txlpf[core_no];
++
++		params->txgm = target_gain.txgm[core_no];
++		params->pga = target_gain.pga[core_no];
++		params->pad = target_gain.pad[core_no];
++		params->ipa = target_gain.ipa[core_no];
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->cal_gain =
++				((params->txlpf << 15) | (params->txgm << 12) |
++				 (params->pga << 8) |
++				 (params->pad << 3) | (params->ipa));
++		else
++			params->cal_gain =
++				((params->txgm << 12) | (params->pga << 8) |
++				 (params->pad << 4) | (params->ipa));
++
++		params->ncorr[0] = 0x79;
++		params->ncorr[1] = 0x79;
++		params->ncorr[2] = 0x79;
++		params->ncorr[3] = 0x79;
++		params->ncorr[4] = 0x79;
++	} else {
++
++		gain_index = ((target_gain.pad[core_no] << 0) |
++			      (target_gain.pga[core_no] << 4) |
++			      (target_gain.txgm[core_no] << 8));
++
++		idx = -1;
++		for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
++			if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
++			    gain_index) {
++				idx = k;
++				break;
++			}
++		}
++
++		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
++		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
++		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
++		params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
++				    (params->pad << 2));
++		params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
++		params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
++		params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
++		params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
++	}
++}
++
++static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core <= 1; core++) {
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MASTER);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_VCM_HG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_IDAC);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_VCM);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MUX);
++
++			if (pi->pubpi.radiorev != 5)
++				pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++					READ_RADIO_REG3(pi, RADIO_2057, TX,
++							core,
++							TSSIA);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++			       READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_MISC1);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x0a);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX, 0x4);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x06);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX,
++							 0x06);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			}
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		for (core = 0; core <= 1; core++) {
++			jtag_core =
++				(core ==
++				 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MASTER |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_VCM_HG |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_IDAC |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				read_radio_reg(
++					pi,
++					RADIO_2056_TX_TSSI_VCM |
++					jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_AMP_DET |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MUX |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIA | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIG | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC1 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC2 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC3 |
++					       jtag_core);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x0a);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++
++				if (PHY_IPA(pi)) {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x4);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x2f);
++				}
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIG | jtag_core,
++						0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			} else {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x06);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIA | jtag_core,
++						0x00);
++
++				if (PHY_IPA(pi)) {
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x06);
++					if (NREV_LT(pi->pubpi.phy_rev, 5))
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x11);
++					else
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIG |
++							jtag_core, 0x20);
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			}
++		}
++	} else {
++
++		pi->tx_rx_cal_radio_saveregs[0] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[1] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[2] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[3] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[4] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pi->tx_rx_cal_radio_saveregs[5] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++
++		if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
++		    0) {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		} else {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
++		} else {
++
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
++		}
++	}
++}
++
++static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core <= 1; core++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TX_SSI_MASTER,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  0]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  2]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  3]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  5]);
++
++			if (pi->pubpi.radiorev != 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIA,
++						 pi->tx_rx_cal_radio_saveregs
++							     [(core * 11) + 6]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  7]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  8]);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core <= 1; core++) {
++			jtag_core = (core == PHY_CORE_0) ?
++				     RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 1]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_IDAC | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 2]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_AMP_DET | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 4]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 5]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 6]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 7]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC1 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 8]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC2 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 9]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC3 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 10]);
++		}
++	} else {
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[0]);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[1]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[2]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[3]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pi->tx_rx_cal_radio_saveregs[4]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pi->tx_rx_cal_radio_saveregs[5]);
++	}
++}
++
++static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi)
++{
++	u16 val, mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 8) | (0x3 << 10));
++		val = (0x2 << 8);
++		val |= (0x2 << 10);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0x8f);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0x8f, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0xa5, val);
++
++		pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
++		mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[5] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[6] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
++
++		if (!(pi->use_int_tx_iqlo_cal_nphy))
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				1,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++		else
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				0,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++
++		pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++		pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      1 << 4);
++
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 0);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 0);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 0);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 0);
++				}
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 0,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (0x2 << 12);
++		val |= (0x2 << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 12) | (0x1 << 13));
++		write_phy_reg(pi, 0xa5, val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[4] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
++		val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++		write_phy_reg(pi, 0x91, val);
++		write_phy_reg(pi, 0x92, val);
++	}
++}
++
++static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi)
++{
++	u16 mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
++		write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
++		write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &pi->tx_rx_cal_phy_saveregs[5]);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &pi->tx_rx_cal_phy_saveregs[6]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
++
++		write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++		write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_resetcca_nphy(pi);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 1);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 1);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 1);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 1);
++				}
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      0);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 1,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		mask = ((0x3 << 12) | (0x3 << 14));
++		mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
++		mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &pi->tx_rx_cal_phy_saveregs[3]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &pi->tx_rx_cal_phy_saveregs[4]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
++	}
++}
++
++void
++wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps)
++{
++	u16 tssi_reg;
++	s32 temp, pwrindex[2];
++	s32 idle_tssi[2];
++	s32 rssi_buf[4];
++	s32 tssival[2];
++	u8 tssi_type;
++
++	tssi_reg = read_phy_reg(pi, 0x1e9);
++
++	temp = (s32) (tssi_reg & 0x3f);
++	idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
++
++	temp = (s32) ((tssi_reg >> 8) & 0x3f);
++	idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
++
++	tssi_type =
++		CHSPEC_IS5G(pi->radio_chanspec) ?
++		(u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G;
++
++	wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
++
++	tssival[0] = rssi_buf[0] / ((s32) num_samps);
++	tssival[1] = rssi_buf[2] / ((s32) num_samps);
++
++	pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
++	pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
++
++	if (pwrindex[0] < 0)
++		pwrindex[0] = 0;
++	else if (pwrindex[0] > 63)
++		pwrindex[0] = 63;
++
++	if (pwrindex[1] < 0)
++		pwrindex[1] = 0;
++	else if (pwrindex[1] > 63)
++		pwrindex[1] = 63;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
++				(u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
++				(u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
++}
++
++static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
++{
++	int index;
++	u32 bbmult_scale;
++	u16 bbmult;
++	u16 tblentry;
++
++	struct nphy_txiqcal_ladder ladder_lo[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
++		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
++	};
++
++	struct nphy_txiqcal_ladder ladder_iq[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
++		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
++	};
++
++	bbmult = (core == PHY_CORE_0) ?
++		 ((pi->nphy_txcal_bbmult >> 8) & 0xff) :
++		 (pi->nphy_txcal_bbmult & 0xff);
++
++	for (index = 0; index < 18; index++) {
++		bbmult_scale = ladder_lo[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
++					 &tblentry);
++
++		bbmult_scale = ladder_iq[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
++					 16, &tblentry);
++	}
++}
++
++static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core)
++{
++	u16 tmp;
++	tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
++
++	tmp = (tmp & (0x7f << 8)) >> 8;
++	return (u8) tmp;
++}
++
++static void
++wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1)
++{
++	mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
++
++	if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
++}
++
++static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi)
++{
++	u16 m0m1;
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	return m0m1;
++}
++
++static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1)
++{
++	u16 m0m1 = (u16) ((m0 << 8) | m1);
++
++	wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
++	wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
++}
++
++static void
++wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
++			    struct nphy_papd_restore_state *state, u8 core)
++{
++	s32 tone_freq;
++	u8 off_core;
++	u16 mixgain = 0;
++
++	off_core = core ^ 0x1;
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5)
++				mixgain = (core == 0) ? 0x20 : 0x00;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x00;
++			else if ((pi->pubpi.radiorev <= 4)
++				 || (pi->pubpi.radiorev == 6))
++				mixgain = 0x00;
++		} else {
++			if ((pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				mixgain = 0x50;
++			else if ((pi->pubpi.radiorev == 3)
++				 || (pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x0;
++		}
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
++						  mixgain, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			1, (1 << core), 0);
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			0, (1 << off_core), 0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
++						  0, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++		state->afectrl[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
++		state->afeoverride[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5), (0x1 << 2), (0x1 << 2));
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
++			    (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
++				 0x8f), (0x1 << 2), (0x1 << 2));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_2G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++			else if (pi->pubpi.radiorev == 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 (core == 0) ? 0xf7 : 0xf2);
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_ATTEN, 0xff);
++		} else {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_5G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf4);
++
++			else
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_ATTEN, 0xff);
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5),
++			    (0x1 << 0) |
++			    (0x1 << 1) |
++			    (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++
++		state->vga_master[core] =
++			READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
++		WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_G);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAG_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAG_MASTER, 0x04);
++		} else {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_A);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAA_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_MASTER, 0x04);
++
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++	}
++}
++
++static void
++wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
++			      struct nphy_papd_restore_state *state)
++{
++	u8 core;
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 state->atten[core]);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN,
++						 state->atten[core]);
++			}
++		}
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				0, 0x3, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
++					 state->vga_master[core]);
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_G, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_MASTER,
++						 state->intpa_master[core]);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_A, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAA_MASTER,
++						 state->intpa_master[core]);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
++	}
++}
++
++static void
++wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start,
++		u32 end)
++{
++	u32 *buf, *src, *dst, sz;
++
++	sz = end - start + 1;
++
++	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
++	if (NULL == buf)
++		return;
++
++	src = buf;
++	dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
++
++	wlc_phy_table_read_nphy(pi,
++				(core ==
++				 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1),
++				NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
++
++	do {
++		u32 phy_a1, phy_a2;
++		s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
++
++		phy_a1 = end - min(end, (winsz >> 1));
++		phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1,
++			       end + (winsz >> 1));
++		phy_a3 = phy_a2 - phy_a1 + 1;
++		phy_a6 = 0;
++		phy_a7 = 0;
++
++		do {
++			wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
++						    &phy_a5);
++			phy_a6 += phy_a4;
++			phy_a7 += phy_a5;
++		} while (phy_a2-- != phy_a1);
++
++		phy_a6 /= phy_a3;
++		phy_a7 /= phy_a3;
++		dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
++	} while (end-- != start);
++
++	wlc_phy_table_write_nphy(pi,
++				 (core ==
++				  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
++
++	kfree(buf);
++}
++
++static void
++wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains,
++		enum phy_cal_mode cal_mode, u8 core)
++{
++	u16 phy_a1, phy_a2, phy_a3;
++	u16 phy_a4, phy_a5;
++	bool phy_a6;
++	u8 phy_a7, m[2];
++	u32 phy_a8 = 0;
++	struct nphy_txgains phy_a9;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		return;
++
++	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
++
++	phy_a6 = ((cal_mode == CAL_GCTRL)
++		  || (cal_mode == CAL_SOFT)) ? true : false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (phy_a9.pga[core] << 8) |
++				  (txgains->gains.pad[core] << 3) |
++				  (phy_a9.ipa[core]));
++		else
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (txgains->gains.pga[core] << 8) |
++				  (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 0);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6))
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  60 : 79;
++			else
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  45 : 64;
++		} else {
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++		}
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				phy_a1 = 30;
++				phy_a3 = 30;
++			} else {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			}
++		} else {
++			if ((pi->pubpi.radiorev == 5)
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			} else {
++				phy_a1 = 35;
++				phy_a3 = 35;
++			}
++		}
++
++		if (cal_mode == CAL_GCTRL) {
++			if ((pi->pubpi.radiorev == 5)
++			    && (CHSPEC_IS2G(pi->radio_chanspec)))
++				phy_a1 = 55;
++			else if (((pi->pubpi.radiorev == 7) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))) ||
++				 ((pi->pubpi.radiorev == 8) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))))
++				phy_a1 = 60;
++			else
++				phy_a1 = 63;
++
++		} else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
++
++			phy_a1 = 35;
++			phy_a3 = 35;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		write_phy_reg(pi, 0x2a1, 0x80);
++		write_phy_reg(pi, 0x2a2, 0x100);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 4), (11) << 4);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 8), (11) << 8);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 0), (0x3) << 0);
++
++		write_phy_reg(pi, 0x2e5, 0x20);
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  1, ((core == 0) ? 1 : 2), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, ((core == 0) ? 2 : 1), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL) {
++			if (CHSPEC_IS5G(pi->radio_chanspec))
++				wlc_phy_a1_nphy(pi, core, 5, 0, 35);
++		}
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 1);
++
++	} else {
++
++		if (txgains) {
++			if (txgains->useindex) {
++				phy_a4 = 15 - ((txgains->index) >> 3);
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					if (NREV_GE(pi->pubpi.phy_rev, 6))
++						phy_a5 = 0x00f7 | (phy_a4 << 8);
++
++					else
++					if (NREV_IS(pi->pubpi.phy_rev, 5))
++						phy_a5 = 0x10f7 | (phy_a4 << 8);
++					else
++						phy_a5 = 0x50f7 | (phy_a4 << 8);
++				} else {
++					phy_a5 = 0x70f7 | (phy_a4 << 8);
++				}
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     phy_a5,
++							     (1 << core), 0);
++			} else {
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     0x5bf7,
++							     (1 << core), 0);
++			}
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 45 : 64;
++		else
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (cal_mode == CAL_FULL) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_SOFT) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_GCTRL) {
++			phy_a1 = 63;
++			phy_a3 = 25;
++		} else {
++
++			phy_a1 = 25;
++			phy_a3 = 25;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (1) << 13);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (0) << 13);
++
++			write_phy_reg(pi, 0x2a1, 0x20);
++			write_phy_reg(pi, 0x2a2, 0x60);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 4), (9) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 8), (9) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 0), (0x2) << 0);
++
++			write_phy_reg(pi, 0x2e5, 0x20);
++		} else {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (1) << 11);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (0) << 11);
++
++			write_phy_reg(pi, 0x2a1, 0x80);
++			write_phy_reg(pi, 0x2a2, 0x600);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 4), (0) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 8), (0) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 0), (0x3) << 0);
++
++			mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
++
++		}
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL)
++			wlc_phy_a1_nphy(pi, core, 5, 0, 40);
++	}
++}
++
++static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
++{
++	int phy_a1;
++	int phy_a2;
++	bool phy_a3;
++	struct nphy_ipa_txcalgains phy_a4;
++	bool phy_a5 = false;
++	bool phy_a6 = true;
++	s32 phy_a7, phy_a8;
++	u32 phy_a9;
++	int phy_a10;
++	bool phy_a11 = false;
++	int phy_a12;
++	u8 phy_a13 = 0;
++	u8 phy_a14;
++	u8 *phy_a15 = NULL;
++
++	phy_a4.useindex = true;
++	phy_a12 = start_gain;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a2 = 20;
++		phy_a1 = 1;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5) {
++
++				phy_a15 = pad_gain_codes_used_2057rev5;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev5) - 1;
++
++			} else if ((pi->pubpi.radiorev == 7)
++				   || (pi->pubpi.radiorev == 8)) {
++
++				phy_a15 = pad_gain_codes_used_2057rev7;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev7) - 1;
++
++			} else {
++
++				phy_a15 = pad_all_gain_codes_2057;
++				phy_a13 = ARRAY_SIZE(pad_all_gain_codes_2057) -
++					  1;
++			}
++
++		} else {
++
++			phy_a15 = pga_all_gain_codes_2057;
++			phy_a13 = ARRAY_SIZE(pga_all_gain_codes_2057) - 1;
++		}
++
++		phy_a14 = 0;
++
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_a4.gains.pad[core] =
++					(u16) phy_a15[phy_a12];
++			else
++				phy_a4.gains.pga[core] =
++					(u16) phy_a15[phy_a12];
++
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
++				if (phy_a12 < phy_a14)
++					phy_a12 = phy_a14;
++				else
++					phy_a12 = phy_a13;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	} else {
++		phy_a2 = 10;
++		phy_a1 = 8;
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			phy_a4.index = (u8) phy_a12;
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < 0) || (phy_a12 > 127)) {
++				if (phy_a12 < 0)
++					phy_a12 = 0;
++				else
++					phy_a12 = 127;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return (u8) phy_a15[phy_a12];
++	else
++		return (u8) phy_a12;
++
++}
++
++static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
++{
++	struct nphy_ipa_txcalgains phy_b1[2];
++	struct nphy_papd_restore_state phy_b2;
++	bool phy_b3;
++	u8 phy_b4;
++	u8 phy_b5;
++	s16 phy_b6, phy_b7, phy_b8;
++	u16 phy_b9;
++	s16 phy_b10, phy_b11, phy_b12;
++
++	phy_b11 = 0;
++	phy_b12 = 0;
++	phy_b7 = 0;
++	phy_b8 = 0;
++	phy_b6 = 0;
++
++	if (pi->nphy_papd_skip == 1)
++		return;
++
++	phy_b3 = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			MCTL_EN_MAC));
++	if (!phy_b3)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	pi->nphy_force_papd_cal = false;
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
++		pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
++			wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
++
++	pi->nphy_papd_last_cal = pi->sh->now;
++	pi->nphy_papd_recal_counter++;
++
++	phy_b4 = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
++				 nphy_papd_scaltbl);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
++				 nphy_papd_scaltbl);
++
++	phy_b9 = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		s32 i, val = 0;
++		for (i = 0; i < 64; i++)
++			wlc_phy_table_write_nphy(pi,
++						 ((phy_b5 ==
++						   PHY_CORE_0) ?
++						  NPHY_TBL_ID_EPSILONTBL0 :
++						  NPHY_TBL_ID_EPSILONTBL1), 1,
++						 i, 32, &val);
++	}
++
++	wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
++
++	phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6)) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						23;
++				} else if (pi->pubpi.radiorev == 5) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				}
++
++				phy_b1[phy_b5].gains.pad[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++
++			} else {
++				pi->nphy_papd_cal_gain_index[phy_b5] = 0;
++				pi->nphy_papd_cal_gain_index[phy_b5] =
++					wlc_phy_a3_nphy(
++						pi,
++						pi->
++						nphy_papd_cal_gain_index
++						[phy_b5], phy_b5);
++				phy_b1[phy_b5].gains.pga[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++			}
++		} else {
++			phy_b1[phy_b5].useindex = true;
++			phy_b1[phy_b5].index = 16;
++			phy_b1[phy_b5].index =
++				wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index,
++						phy_b5);
++
++			pi->nphy_papd_cal_gain_index[phy_b5] =
++				15 - ((phy_b1[phy_b5].index) >> 3);
++		}
++
++		switch (pi->nphy_papd_cal_type) {
++		case 0:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
++			break;
++		case 1:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
++			break;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		int eps_offset = 0;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev == 3)
++					eps_offset = -2;
++				else if (pi->pubpi.radiorev == 5)
++					eps_offset = 3;
++				else
++					eps_offset = -1;
++			} else {
++				eps_offset = 2;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
++				phy_b10 = 0;
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev3n4
++							     [phy_b8] + 1) / 2;
++					phy_b10 = -1;
++				} else if (pi->pubpi.radiorev == 5) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev5
++							     [phy_b8] + 1) / 2;
++				} else if ((pi->pubpi.radiorev == 7) ||
++					   (pi->pubpi.radiorev == 8)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev7
++							     [phy_b8] + 1) / 2;
++				}
++			} else {
++				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6))
++					phy_b11 =
++						-(nphy_papd_pgagain_dlt_5g_2057
++						  [phy_b7]
++						  + 1) / 2;
++				else if ((pi->pubpi.radiorev == 7)
++					 || (pi->pubpi.radiorev == 8))
++					phy_b11 = -(
++					      nphy_papd_pgagain_dlt_5g_2057rev7
++							     [phy_b7] + 1) / 2;
++
++				phy_b10 = -9;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b12 +
++					phy_b10;
++			else
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b11 +
++					phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		} else {
++			if (NREV_LT(pi->pubpi.phy_rev, 5))
++				eps_offset = 4;
++			else
++				eps_offset = 2;
++
++			phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_2g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = 0;
++			} else {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_5g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = -9;
++			}
++
++			phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		}
++	}
++
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++	}
++	pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
++
++	write_phy_reg(pi, 0x01, phy_b9);
++
++	wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
++	if (phy_b4 == PHY_TPC_HW_OFF) {
++		wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++					 (s8) (pi->nphy_txpwrindex[0].
++					       index_internal), false);
++		wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++					 (s8) (pi->nphy_txpwrindex[1].
++					       index_internal), false);
++	}
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!phy_b3)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype)
++{
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool fullcal = true;
++	bool restore_tx_gain = false;
++	bool mphase;
++
++	if (PHY_MUTED(pi))
++		return;
++
++	if (caltype == PHY_PERICAL_AUTO)
++		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
++	else if (caltype == PHY_PERICAL_PARTIAL)
++		fullcal = false;
++
++	if (pi->cal_type_override != PHY_PERICAL_AUTO)
++		fullcal =
++			(pi->cal_type_override ==
++			 PHY_PERICAL_FULL) ? true : false;
++
++	if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
++		if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
++			wlc_phy_cal_perical_mphase_restart(pi);
++	}
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL))
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
++	    (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
++		pi->nphy_cal_orig_pwr_idx[0] =
++			(u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
++		pi->nphy_cal_orig_pwr_idx[1] =
++			(u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
++
++		if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
++						0x110, 16,
++						pi->nphy_cal_orig_tx_gain);
++		} else {
++			pi->nphy_cal_orig_tx_gain[0] = 0;
++			pi->nphy_cal_orig_tx_gain[1] = 0;
++		}
++	}
++	target_gain = wlc_phy_get_tx_gain_nphy(pi);
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	if (pi->antsel_type == ANTSEL_2x3)
++		wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true);
++
++	mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
++	if (!mphase) {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_precal_txgain_nphy(pi);
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			restore_tx_gain = true;
++
++			target_gain = pi->nphy_cal_target_gain;
++		}
++		if (0 ==
++		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal,
++					    mphase)) {
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++			wlapi_enable_mac(pi->sh->physhim);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
++					     10000);
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
++					(pi->first_cal_after_assoc ||
++					(pi->cal_type_override ==
++					 PHY_PERICAL_FULL)) ? 2 : 0, false)) {
++				wlc_phy_savecal_nphy(pi);
++
++				wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++				pi->nphy_perical_last = pi->sh->now;
++			}
++		}
++		if (caltype != PHY_PERICAL_AUTO)
++			wlc_phy_rssi_cal_nphy(pi);
++
++		if (pi->first_cal_after_assoc
++		    || (pi->cal_type_override == PHY_PERICAL_FULL)) {
++			pi->first_cal_after_assoc = false;
++			wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++			wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_radio205x_vcocal_nphy(pi);
++	} else {
++		switch (pi->mphase_cal_phase_id) {
++		case MPHASE_CAL_STATE_INIT:
++			pi->nphy_perical_last = pi->sh->now;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_precal_txgain_nphy(pi);
++
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_TXPHASE0:
++		case MPHASE_CAL_STATE_TXPHASE1:
++		case MPHASE_CAL_STATE_TXPHASE2:
++		case MPHASE_CAL_STATE_TXPHASE3:
++		case MPHASE_CAL_STATE_TXPHASE4:
++		case MPHASE_CAL_STATE_TXPHASE5:
++			if ((pi->radar_percal_mask & 0x10) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, pi->nphy_cal_target_gain, fullcal,
++				    true) != 0) {
++
++				wlc_phy_cal_perical_mphase_reset(pi);
++				break;
++			}
++
++			if (NREV_LE(pi->pubpi.phy_rev, 2) &&
++			    (pi->mphase_cal_phase_id ==
++			     MPHASE_CAL_STATE_TXPHASE4))
++				pi->mphase_cal_phase_id += 2;
++			else
++				pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_PAPDCAL:
++			if ((pi->radar_percal_mask & 0x2) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RXCAL:
++			if ((pi->radar_percal_mask & 0x1) != 0)
++				pi->nphy_rxcal_active = true;
++			if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
++						  (pi->first_cal_after_assoc ||
++						   (pi->cal_type_override ==
++						    PHY_PERICAL_FULL)) ? 2 : 0,
++						  false) == 0)
++				wlc_phy_savecal_nphy(pi);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RSSICAL:
++			if ((pi->radar_percal_mask & 0x4) != 0)
++				pi->nphy_rxcal_active = true;
++			wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_radio205x_vcocal_nphy(pi);
++
++			restore_tx_gain = true;
++
++			if (pi->first_cal_after_assoc)
++				pi->mphase_cal_phase_id++;
++			else
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			break;
++
++		case MPHASE_CAL_STATE_IDLETSSI:
++			if ((pi->radar_percal_mask & 0x8) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (pi->first_cal_after_assoc) {
++				pi->first_cal_after_assoc = false;
++				wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++				wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++			}
++
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++
++		default:
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (restore_tx_gain) {
++			if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
++
++				wlc_phy_txpwr_index_nphy(pi, 1,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [0], false);
++				wlc_phy_txpwr_index_nphy(pi, 2,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [1], false);
++
++				pi->nphy_txpwrindex[0].index = -1;
++				pi->nphy_txpwrindex[1].index = -1;
++			} else {
++				wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [0].
++							       index_internal),
++							 false);
++				wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [1].
++							       index_internal),
++							 false);
++			}
++		}
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++	wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++int
++wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++			bool fullcal, bool mphase)
++{
++	u16 val;
++	u16 tbl_buf[11];
++	u8 cal_cnt;
++	u16 cal_cmd;
++	u8 num_cals, max_cal_cmds;
++	u16 core_no, cal_type;
++	u16 diq_start = 0;
++	u8 phy_bw;
++	u16 max_val;
++	u16 tone_freq;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u32 tbl_len;
++	void *tbl_ptr;
++	bool ladder_updated[2];
++	u8 mphase_cal_lastphase = 0;
++	int bcmerror = 0;
++	bool phyhang_avoid_state = false;
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
++		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
++		0x1902,
++		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
++		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
++		0x3200,
++		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
++		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
++		0x1202,
++		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
++		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
++		0x2300,
++		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
++		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
++		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
++		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
++		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
++		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
++		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
++		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
++	};
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++	else
++		phy_bw = 20;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	wlc_phy_txcal_radio_setup_nphy(pi);
++
++	wlc_phy_txcal_physetup_nphy(pi);
++
++	ladder_updated[0] = ladder_updated[1] = false;
++	if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
++	      (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
++	       && (CHSPEC_IS2G(pi->radio_chanspec))))) {
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
++					 16, tbl_ptr);
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
++					 16, tbl_ptr);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0xc2, 0x8ad9);
++	else
++		write_phy_reg(pi, 0xc2, 0x8aa9);
++
++	max_val = 250;
++	tone_freq = (phy_bw == 20) ? 2500 : 5000;
++
++	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
++		bcmerror = 0;
++	} else {
++		bcmerror =
++			wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0,
++					     false);
++	}
++
++	if (bcmerror == 0) {
++
++		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++			tbl_ptr = pi->mphase_txcal_bestcoeffs;
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++		} else {
++			if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
++
++				tbl_ptr = pi->nphy_txiqlocal_bestc;
++				tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++				if (NREV_LT(pi->pubpi.phy_rev, 3))
++					tbl_len -= 2;
++			} else {
++
++				fullcal = true;
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					tbl_ptr =
++					    tbl_tx_iqlo_cal_startcoefs_nphyrev3;
++					tbl_len = ARRAY_SIZE(
++					   tbl_tx_iqlo_cal_startcoefs_nphyrev3);
++				} else {
++					tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
++					tbl_len = ARRAY_SIZE(
++						    tbl_tx_iqlo_cal_startcoefs);
++				}
++			}
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
++					 16, tbl_ptr);
++
++		if (fullcal) {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
++		} else {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
++		}
++
++		if (mphase) {
++			cal_cnt = pi->mphase_txcal_cmdidx;
++			if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds)
++				num_cals = cal_cnt + pi->mphase_txcal_numcmds;
++			else
++				num_cals = max_cal_cmds;
++		} else {
++			cal_cnt = 0;
++			num_cals = max_cal_cmds;
++		}
++
++		for (; cal_cnt < num_cals; cal_cnt++) {
++
++			if (fullcal) {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
++					  [cal_cnt] :
++					  tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
++			} else {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_recal_nphyrev3[
++					cal_cnt]
++					  : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
++			}
++
++			core_no = ((cal_cmd & 0x3000) >> 12);
++			cal_type = ((cal_cmd & 0x0F00) >> 8);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6) ||
++			    (NREV_IS(pi->pubpi.phy_rev, 5) &&
++			     PHY_IPA(pi)
++			     && (CHSPEC_IS2G(pi->radio_chanspec)))) {
++				if (!ladder_updated[core_no]) {
++					wlc_phy_update_txcal_ladder_nphy(
++						pi,
++						core_no);
++					ladder_updated[core_no] = true;
++				}
++			}
++
++			val =
++				(cal_params[core_no].
++				 ncorr[cal_type] << 8) | NPHY_N_GCTL;
++			write_phy_reg(pi, 0xc1, val);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++							1, 69 + core_no, 16,
++							tbl_buf);
++
++				diq_start = tbl_buf[0];
++
++				tbl_buf[0] = 0;
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_IQLOCAL, 1,
++							 69 + core_no, 16,
++							 tbl_buf);
++			}
++
++			write_phy_reg(pi, 0xc0, cal_cmd);
++
++			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
++				 20000);
++			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
++				 "HW error: txiq calib"))
++				return -EIO;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						 tbl_len, 64, 16, tbl_buf);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				tbl_buf[0] = diq_start;
++
++			}
++
++		}
++
++		if (mphase) {
++			pi->mphase_txcal_cmdidx = num_cals;
++			if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
++				pi->mphase_txcal_cmdidx = 0;
++		}
++
++		mphase_cal_lastphase =
++			(NREV_LE(pi->pubpi.phy_rev, 2)) ?
++			MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
++
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, tbl_buf);
++
++			if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++				tbl_buf[0] = 0;
++				tbl_buf[1] = 0;
++				tbl_buf[2] = 0;
++				tbl_buf[3] = 0;
++
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16, tbl_buf);
++
++			tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->nphy_txiqlocal_bestc);
++
++			pi->nphy_txiqlocal_coeffsvalid = true;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++		} else {
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->mphase_txcal_bestcoeffs);
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++
++		write_phy_reg(pi, 0xc2, 0x0000);
++
++	}
++
++	wlc_phy_txcal_phycleanup_nphy(pi);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_txcal_radio_cleanup_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
++			wlc_phy_tx_iq_war_nphy(pi);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi)
++{
++	u16 tbl_buf[7];
++
++	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
++	    (pi->nphy_txiqlocal_coeffsvalid)) {
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++					ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
++
++		if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
++		    (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
++		    (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
++		    (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, pi->nphy_txiqlocal_bestc);
++
++			tbl_buf[0] = 0;
++			tbl_buf[1] = 0;
++			tbl_buf[2] = 0;
++			tbl_buf[3] = 0;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++		}
++	}
++}
++
++void
++wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++			  struct nphy_iq_comp *pcomp)
++{
++	if (write) {
++		write_phy_reg(pi, 0x9a, pcomp->a0);
++		write_phy_reg(pi, 0x9b, pcomp->b0);
++		write_phy_reg(pi, 0x9c, pcomp->a1);
++		write_phy_reg(pi, 0x9d, pcomp->b1);
++	} else {
++		pcomp->a0 = read_phy_reg(pi, 0x9a);
++		pcomp->b0 = read_phy_reg(pi, 0x9b);
++		pcomp->a1 = read_phy_reg(pi, 0x9c);
++		pcomp->b1 = read_phy_reg(pi, 0x9d);
++	}
++}
++
++void
++wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++		       u16 num_samps, u8 wait_time, u8 wait_for_crs)
++{
++	u8 core;
++
++	write_phy_reg(pi, 0x12b, num_samps);
++	mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
++		    (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
++
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
++
++	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
++		 10000);
++	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
++		 "HW error: rxiq est"))
++		return;
++
++	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			est[core].i_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestipwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
++			est[core].q_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestqpwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
++			est[core].iq_prod =
++				(read_phy_reg(pi,
++					      NPHY_IqestIqAccHi(core)) << 16) |
++				read_phy_reg(pi, NPHY_IqestIqAccLo(core));
++		}
++	}
++}
++
++#define CAL_RETRY_CNT 2
++static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask)
++{
++	u8 curr_core;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	struct nphy_iq_comp old_comp, new_comp;
++	s32 iq = 0;
++	u32 ii = 0, qq = 0;
++	s16 iq_nbits, qq_nbits, brsh, arsh;
++	s32 a, b, temp;
++	int bcmerror = 0;
++	uint cal_retry = 0;
++
++	if (core_mask == 0x0)
++		return;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
++	new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++
++cal_try:
++	wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
++
++	new_comp = old_comp;
++
++	for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else {
++			continue;
++		}
++
++		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
++			bcmerror = -EBADE;
++			break;
++		}
++
++		iq_nbits = wlc_phy_nbits(iq);
++		qq_nbits = wlc_phy_nbits(qq);
++
++		arsh = 10 - (30 - iq_nbits);
++		if (arsh >= 0) {
++			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++			temp = (s32) (ii >> arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++			temp = (s32) (ii << -arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++
++		a /= temp;
++
++		brsh = qq_nbits - 31 + 20;
++		if (brsh >= 0) {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii >> brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii << -brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++		b /= temp;
++		b -= a * a;
++		b = (s32) int_sqrt((unsigned long) b);
++		b -= (1 << 10);
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a0 = (s16) a & 0x3ff;
++				new_comp.b0 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a0 = (s16) b & 0x3ff;
++				new_comp.b0 = (s16) a & 0x3ff;
++			}
++		}
++		if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a1 = (s16) a & 0x3ff;
++				new_comp.b1 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a1 = (s16) b & 0x3ff;
++				new_comp.b1 = (s16) a & 0x3ff;
++			}
++		}
++	}
++
++	if (bcmerror != 0) {
++		pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry);
++
++		if (cal_retry < CAL_RETRY_CNT) {
++			cal_retry++;
++			goto cal_try;
++		}
++
++		new_comp = old_comp;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++}
++
++static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u16 offtune_val;
++	u16 bias_g = 0;
++	u16 bias_a = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX1);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX0);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX0);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX1);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_MASTER
++						      | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1, bias_a);
++
++					write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->tx_rx_cal_radio_saveregs
++						 [2] & 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX1, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX0, bias_g);
++
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x6);
++			}
++
++		} else {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX0);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX1);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX1);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX0);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						       pi,
++						       RADIO_2056_RX_LNAA_MASTER
++						       | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER |
++						RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_a);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_g);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x6);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX1,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX0,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX0,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX1,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX0,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u8 tx_core;
++	u16 rx_antval, tx_antval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
++
++	pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
++	pi->tx_rx_cal_phy_saveregs[1] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
++	pi->tx_rx_cal_phy_saveregs[2] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
++	pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
++	pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
++	pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
++	pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
++	pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
++	pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
++		pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
++		pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
++		pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
++	}
++
++	pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++	pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
++
++	} else {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++		mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
++		mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
++	}
++
++	mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
++	mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		    (0x1 << 2), (0x1 << 2));
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++		mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1), 0);
++		mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++			    0x8f : 0xa5,
++			    (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
++	}
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				2, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, rx_core + 1);
++	} else {
++
++		if (rx_core == PHY_CORE_0) {
++			rx_antval = 0x1;
++			tx_antval = 0x8;
++		} else {
++			rx_antval = 0x4;
++			tx_antval = 0x2;
++		}
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 rx_antval, rx_core + 1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 tx_antval, tx_core + 1);
++	}
++}
++
++static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++
++	write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
++		      pi->tx_rx_cal_phy_saveregs[1]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		      pi->tx_rx_cal_phy_saveregs[2]);
++	write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
++	write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
++
++	write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
++	write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
++	write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
++	write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
++		write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
++		write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
++		write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
++	}
++
++	write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++	write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
++				 u16 *rxgain, u8 cal_type)
++{
++
++	u16 num_samps;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 tx_core;
++	struct nphy_iq_comp save_comp, zero_comp;
++	u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0,
++	    thresh_pwr = 10000;
++	s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
++	bool gainctrl_done = false;
++	u8 mix_tia_gain = 3;
++	s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
++	s8 curr_gaintbl_index = 3;
++	u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
++	const struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl;
++	u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
++	int fine_gain_idx;
++	s8 txpwrindex;
++	u16 nphy_rxcal_txgain[2];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = 1 - rx_core;
++
++	num_samps = 1024;
++	desired_log2_pwr = (cal_type == 0) ? 13 : 13;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
++	zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mix_tia_gain = 3;
++		else if (NREV_GE(pi->pubpi.phy_rev, 4))
++			mix_tia_gain = 4;
++		else
++			mix_tia_gain = 6;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
++	}
++
++	do {
++
++		hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
++			0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
++		lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
++		lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
++		lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
++		lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
++		txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_rfctrl_override_1tomany_nphy(
++				pi,
++				NPHY_REV7_RfctrlOverride_cmd_rxgain,
++				((lpf_biq1 << 12) |
++				 (lpf_biq0 << 8) |
++				 (mix_tia_gain << 4) | (lna2 << 2)
++				 | lna1), 0x3, 0);
++		else
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++						     ((hpvga << 12) |
++						      (lpf_biq1 << 10) |
++						      (lpf_biq0 << 8) |
++						      (mix_tia_gain << 4) |
++						      (lna2 << 2) | lna1), 0x3,
++						     0);
++
++		pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
++
++		if (txpwrindex == -1) {
++			nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
++			nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++						 2, 0x110, 16,
++						 nphy_rxcal_txgain);
++		} else {
++			wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
++						 false);
++		}
++
++		wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
++				     NPHY_RXCAL_TONEFREQ_40MHz :
++				     NPHY_RXCAL_TONEFREQ_20MHz,
++				     NPHY_RXCAL_TONEAMP, 0, cal_type, false);
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++		i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
++		q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
++		curr_pwr = i_pwr + q_pwr;
++
++		switch (gainctrl_dirn) {
++		case NPHY_RXCAL_GAIN_INIT:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_UP:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_done = true;
++				optim_pwr = prev_pwr;
++				optim_gaintbl_index = prev_gaintbl_index;
++			} else {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_DOWN:
++			if (curr_pwr > thresh_pwr) {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_done = true;
++				optim_pwr = curr_pwr;
++				optim_gaintbl_index = curr_gaintbl_index;
++			}
++			break;
++
++		default:
++			break;
++		}
++
++		if ((curr_gaintbl_index < 0) ||
++		    (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
++			gainctrl_done = true;
++			optim_pwr = curr_pwr;
++			optim_gaintbl_index = prev_gaintbl_index;
++		} else {
++			prev_pwr = curr_pwr;
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++	} while (!gainctrl_done);
++
++	hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
++	lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
++	lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
++	lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
++	lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
++	txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
++
++	actual_log2_pwr = wlc_phy_nbits(optim_pwr);
++	delta_pwr = desired_log2_pwr - actual_log2_pwr;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		fine_gain_idx = (int)lpf_biq1 + delta_pwr;
++
++		if (fine_gain_idx + (int)lpf_biq0 > 10)
++			lpf_biq1 = 10 - lpf_biq0;
++		else
++			lpf_biq1 = (u16) max(fine_gain_idx, 0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			((lpf_biq1 << 12) |
++			 (lpf_biq0 << 8) |
++			 (mix_tia_gain << 4) |
++			 (lna2 << 2) | lna1), 0x3,
++			0);
++	} else {
++		hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++					     ((hpvga << 12) |
++					      (lpf_biq1 << 10) |
++					      (lpf_biq0 << 8) |
++					      (mix_tia_gain << 4) |
++					      (lna2 << 2) |
++					      lna1), 0x3, 0);
++	}
++
++	if (rxgain != NULL) {
++		*rxgain++ = lna1;
++		*rxgain++ = lna2;
++		*rxgain++ = mix_tia_gain;
++		*rxgain++ = lpf_biq0;
++		*rxgain++ = lpf_biq1;
++		*rxgain = hpvga;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain,
++			    u8 cal_type)
++{
++	wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
++}
++
++static u8
++wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type)
++{
++	u32 target_bws[2] = { 9500, 21000 };
++	u32 ref_tones[2] = { 3000, 6000 };
++	u32 target_bw, ref_tone;
++
++	u32 target_pwr_ratios[2] = { 28606, 18468 };
++	u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
++
++	u16 start_rccal_ovr_val = 128;
++	u16 txlpf_rccal_lpc_ovr_val = 128;
++	u16 rxlpf_rccal_hpc_ovr_val = 159;
++
++	u16 orig_txlpf_rccal_lpc_ovr_val;
++	u16 orig_rxlpf_rccal_hpc_ovr_val;
++	u16 radio_addr_offset_rx;
++	u16 radio_addr_offset_tx;
++	u16 orig_dcBypass;
++	u16 orig_RxStrnFilt40Num[6];
++	u16 orig_RxStrnFilt40Den[4];
++	u16 orig_rfctrloverride[2];
++	u16 orig_rfctrlauxreg[2];
++	u16 orig_rfctrlrssiothers;
++	u16 tx_lpf_bw = 4;
++
++	u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
++	u16 lpf_hpc = 7, hpvga_hpc = 7;
++
++	s8 rccal_stepsize;
++	u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
++	u32 ref_iq_vals = 0, target_iq_vals = 0;
++	u16 num_samps, log_num_samps = 10;
++	struct phy_iq_est est[PHY_CORE_MAX];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return 0;
++
++	num_samps = (1 << log_num_samps);
++
++	if (CHSPEC_IS40(pi->radio_chanspec)) {
++		target_bw = target_bws[1];
++		target_pwr_ratio = target_pwr_ratios[1];
++		ref_tone = ref_tones[1];
++		rx_lpf_bw = rx_lpf_bws[1];
++	} else {
++		target_bw = target_bws[0];
++		target_pwr_ratio = target_pwr_ratios[0];
++		ref_tone = ref_tones[0];
++		rx_lpf_bw = rx_lpf_bws[0];
++	}
++
++	if (core_idx == 0) {
++		radio_addr_offset_rx = RADIO_2056_RX0;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++	} else {
++		radio_addr_offset_rx = RADIO_2056_RX1;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
++	}
++
++	orig_txlpf_rccal_lpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_TX_TXLPF_RCCAL |
++				radio_addr_offset_tx));
++	orig_rxlpf_rccal_hpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++				radio_addr_offset_rx));
++
++	orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
++
++	orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
++	orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
++	orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
++	orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
++	orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
++	orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
++	orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
++	orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
++	orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
++	orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
++
++	orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
++	orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
++	orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
++	orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
++	orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			txlpf_rccal_lpc_ovr_val);
++
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
++
++	write_phy_reg(pi, 0x267, 0x02d4);
++	write_phy_reg(pi, 0x268, 0x0000);
++	write_phy_reg(pi, 0x269, 0x0000);
++	write_phy_reg(pi, 0x26a, 0x0000);
++	write_phy_reg(pi, 0x26b, 0x0000);
++	write_phy_reg(pi, 0x26c, 0x02d4);
++	write_phy_reg(pi, 0x26d, 0x0000);
++	write_phy_reg(pi, 0x26e, 0x0000);
++	write_phy_reg(pi, 0x26f, 0x0000);
++	write_phy_reg(pi, 0x270, 0x0000);
++
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
++	or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
++
++	mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
++		    (0x7 << 10), (tx_lpf_bw << 10));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 0), (hpvga_hpc << 0));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 4), (lpf_hpc << 4));
++	mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
++		    (0x7 << 8), (rx_lpf_bw << 8));
++
++	rccal_stepsize = 16;
++	rccal_val = start_rccal_ovr_val + rccal_stepsize;
++
++	while (rccal_stepsize >= 0) {
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 radio_addr_offset_rx), rccal_val);
++
++		if (rccal_stepsize == 16) {
++
++			wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++			if (core_idx == 0)
++				ref_iq_vals =
++					max_t(u32, (est[0].i_pwr +
++						    est[0].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++			else
++				ref_iq_vals =
++					max_t(u32, (est[1].i_pwr +
++						    est[1].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++
++			wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++		}
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++		if (core_idx == 0)
++			target_iq_vals = (est[0].i_pwr + est[0].q_pwr) >>
++					 (log_num_samps + 1);
++		else
++			target_iq_vals =
++				(est[1].i_pwr +
++				 est[1].q_pwr) >> (log_num_samps + 1);
++
++		pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
++
++		if (rccal_stepsize == 0)
++			rccal_stepsize--;
++		else if (rccal_stepsize == 1) {
++			last_rccal_val = rccal_val;
++			rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
++			last_pwr_ratio = pwr_ratio;
++			rccal_stepsize--;
++		} else {
++			rccal_stepsize = (rccal_stepsize >> 1);
++			rccal_val += ((pwr_ratio > target_pwr_ratio) ?
++				      rccal_stepsize : (-rccal_stepsize));
++		}
++
++		if (rccal_stepsize == -1) {
++			best_rccal_val =
++				(abs((int)last_pwr_ratio -
++				     (int)target_pwr_ratio) <
++				 abs((int)pwr_ratio -
++				     (int)target_pwr_ratio)) ? last_rccal_val :
++				rccal_val;
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				if ((best_rccal_val > 140)
++				    || (best_rccal_val < 135))
++					best_rccal_val = 138;
++			} else {
++				if ((best_rccal_val > 142)
++				    || (best_rccal_val < 137))
++					best_rccal_val = 140;
++			}
++
++			write_radio_reg(pi,
++					(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++					 radio_addr_offset_rx), best_rccal_val);
++		}
++	}
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			orig_txlpf_rccal_lpc_ovr_val);
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			orig_rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
++
++	write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
++	write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
++	write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
++	write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
++	write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
++	write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
++	write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
++	write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
++	write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
++	write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
++
++	write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
++	write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
++	write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
++	write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
++	write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
++
++	pi->nphy_anarxlpf_adjusted = false;
++
++	return best_rccal_val - 0x80;
++}
++
++#define WAIT_FOR_SCOPE  4000
++static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
++				      struct nphy_txgains target_gain,
++				      u8 cal_type, bool debug)
++{
++	u16 orig_BBConfig;
++	u8 core_no, rx_core;
++	u8 best_rccal[2];
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 rxcore_state;
++	s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
++	s8 txlpf_idac;
++	bool phyhang_avoid_state = false;
++	bool skip_rxiqcal = false;
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++
++		skip_rxiqcal =
++			((rxcore_state & (1 << rx_core)) == 0) ? true : false;
++
++		wlc_phy_rxcal_physetup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
++
++		if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
++
++			wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
++
++			wlc_phy_tx_tone_nphy(pi,
++					     (CHSPEC_IS40(
++						      pi->radio_chanspec)) ?
++					     NPHY_RXCAL_TONEFREQ_40MHz :
++					     NPHY_RXCAL_TONEFREQ_20MHz,
++					     NPHY_RXCAL_TONEAMP, 0, cal_type,
++					     false);
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
++			wlc_phy_stopplayback_nphy(pi);
++		}
++
++		if (((cal_type == 1) || (cal_type == 2))
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++			if (rx_core == PHY_CORE_1) {
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi, 3);
++
++				wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
++							    1);
++
++				best_rccal[rx_core] =
++					wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
++				pi->nphy_rccal_value = best_rccal[rx_core];
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi,
++						rxcore_state);
++			}
++		}
++
++		wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
++		wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	}
++
++	if ((cal_type == 1) || (cal_type == 2)) {
++
++		best_rccal[0] = best_rccal[1];
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 RADIO_2056_RX0), (best_rccal[0] | 0x80));
++
++		for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++			rxlpf_rccal_hpc =
++				(((int)best_rccal[rx_core] - 12) >> 1) + 10;
++			txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
++
++			if (PHY_IPA(pi)) {
++				txlpf_rccal_lpc +=
++					(pi->bw == WL_CHANSPEC_BW_40) ? 24 : 12;
++				txlpf_idac = (pi->bw == WL_CHANSPEC_BW_40) ?
++					     0x0e : 0x13;
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
++						 TXLPF_IDAC_4, txlpf_idac);
++			}
++
++			rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31),
++					      0);
++			txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31),
++					      0);
++
++			write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_RX0 :
++					      RADIO_2056_RX1)),
++					(rxlpf_rccal_hpc | 0x80));
++
++			write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_TX0 :
++					      RADIO_2056_TX1)),
++					(txlpf_rccal_lpc | 0x80));
++		}
++	}
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	wlc_phy_resetcca_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			0, 0x3, 1);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return 0;
++}
++
++static int
++wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
++			   struct nphy_txgains target_gain, bool debug)
++{
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 core_num, rx_core, tx_core;
++	u16 lna_vals[] = { 0x3, 0x3, 0x1 };
++	u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
++	u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
++	s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
++	s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
++	u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
++	u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
++	u16 num_samps;
++	u32 i_pwr, q_pwr, tot_pwr[3];
++	u8 gain_pass, use_hpf_num;
++	u16 mask, val1, val2;
++	u16 core_no;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 phy_bw;
++	int bcmerror = 0;
++	bool first_playtone = true;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_reapply_txcal_coeffs_nphy(pi);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	num_samps = 1024;
++	desired_log2_pwr = 13;
++
++	for (core_num = 0; core_num < 2; core_num++) {
++
++		rx_core = core_num;
++		tx_core = 1 - core_num;
++
++		orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
++		orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						0xa6 : 0xa7);
++		orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
++		orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++		orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			   ((0x1 << 1) | (0x1 << 2)));
++		or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
++
++		if (((pi->nphy_rxcalparams) & 0xff000000))
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++					0x140 : 0x110));
++		else
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++				       0x180 : 0x120));
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
++			      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
++			       0x114));
++
++		mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
++		if (rx_core == PHY_CORE_0) {
++			val1 = RADIO_2055_COUPLE_RX_MASK;
++			val2 = RADIO_2055_COUPLE_TX_MASK;
++		} else {
++			val1 = RADIO_2055_COUPLE_TX_MASK;
++			val2 = RADIO_2055_COUPLE_RX_MASK;
++		}
++
++		if ((pi->nphy_rxcalparams & 0x10000)) {
++			mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
++				      val1);
++			mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
++				      val2);
++		}
++
++		for (gain_pass = 0; gain_pass < 4; gain_pass++) {
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			if (gain_pass < 3) {
++				curr_lna = lna_vals[gain_pass];
++				curr_hpf1 = hpf1_vals[gain_pass];
++				curr_hpf2 = hpf2_vals[gain_pass];
++			} else {
++
++				if (tot_pwr[1] > 10000) {
++					curr_lna = lna_vals[2];
++					curr_hpf1 = hpf1_vals[2];
++					curr_hpf2 = hpf2_vals[2];
++					use_hpf_num = 1;
++					curr_hpf = curr_hpf1;
++					actual_log2_pwr =
++						wlc_phy_nbits(tot_pwr[2]);
++				} else {
++					if (tot_pwr[0] > 10000) {
++						curr_lna = lna_vals[1];
++						curr_hpf1 = hpf1_vals[1];
++						curr_hpf2 = hpf2_vals[1];
++						use_hpf_num = 1;
++						curr_hpf = curr_hpf1;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[1]);
++					} else {
++						curr_lna = lna_vals[0];
++						curr_hpf1 = hpf1_vals[0];
++						curr_hpf2 = hpf2_vals[0];
++						use_hpf_num = 2;
++						curr_hpf = curr_hpf2;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[0]);
++					}
++				}
++
++				hpf_change = desired_log2_pwr - actual_log2_pwr;
++				curr_hpf += hpf_change;
++				curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
++				if (use_hpf_num == 1)
++					curr_hpf1 = curr_hpf;
++				else
++					curr_hpf2 = curr_hpf;
++			}
++
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
++						     ((curr_hpf2 << 8) |
++						      (curr_hpf1 << 4) |
++						      (curr_lna << 2)), 0x3, 0);
++			wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++			wlc_phy_stopplayback_nphy(pi);
++
++			if (first_playtone) {
++				bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
++						(u16) (pi->nphy_rxcalparams &
++						       0xffff), 0, 0, true);
++				first_playtone = false;
++			} else {
++				phy_bw = (CHSPEC_IS40(pi->radio_chanspec)) ?
++					  40 : 20;
++				wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
++							0, 0, 0, true);
++			}
++
++			if (bcmerror == 0) {
++				if (gain_pass < 3) {
++
++					wlc_phy_rx_iq_est_nphy(pi, est,
++							       num_samps, 32,
++							       0);
++					i_pwr =	(est[rx_core].i_pwr +
++						 num_samps / 2) / num_samps;
++					q_pwr =	(est[rx_core].q_pwr +
++						 num_samps / 2) / num_samps;
++					tot_pwr[gain_pass] = i_pwr + q_pwr;
++				} else {
++
++					wlc_phy_calc_rx_iq_comp_nphy(pi,
++								     (1 <<
++								      rx_core));
++				}
++
++				wlc_phy_stopplayback_nphy(pi);
++			}
++
++			if (bcmerror != 0)
++				break;
++		}
++
++		and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
++		and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcTx);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcRx);
++		write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
++			      0xa7, orig_AfectrlCore);
++		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
++
++		if (bcmerror != 0)
++			break;
++	}
++
++	wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++int
++wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++		      u8 cal_type, bool debug)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		cal_type = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
++						  debug);
++	else
++		return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
++}
++
++void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	u32 txgain;
++	u16 rad_gain, dac_gain, bbmult, m1m2;
++	u8 txpi[2], chan_freq_range;
++	s32 rfpwr_offset;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->sh->sromrev < 4) {
++		txpi[0] = txpi[1] = 72;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++		case WL_CHAN_FREQ_RANGE_5GL:
++		case WL_CHAN_FREQ_RANGE_5GM:
++		case WL_CHAN_FREQ_RANGE_5GH:
++			txpi[0] = 0;
++			txpi[1] = 0;
++			break;
++		default:
++			txpi[0] = txpi[1] = 91;
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		txpi[0] = txpi[1] = 30;
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		txpi[0] = txpi[1] = 40;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		if ((txpi[0] < 40) || (txpi[0] > 100) ||
++		    (txpi[1] < 40) || (txpi[1] > 100))
++			txpi[0] = txpi[1] = 91;
++	}
++
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		if (NREV_GE(phyrev, 3)) {
++			if (PHY_IPA(pi)) {
++				u32 *tx_gaintbl =
++					wlc_phy_get_ipa_gaintbl_nphy(pi);
++				txgain = tx_gaintbl[txpi[core]];
++			} else {
++				if (CHSPEC_IS5G(pi->radio_chanspec)) {
++					if (NREV_IS(phyrev, 3)) {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev3
++								   [txpi[core]];
++					} else if (NREV_IS(phyrev, 4)) {
++						txgain = (
++						  pi->srom_fem5g.extpagain ==
++						  3) ?
++						  nphy_tpc_5GHz_txgain_HiPwrEPA
++						 [txpi[core]] :
++						 nphy_tpc_5GHz_txgain_rev4
++						 [txpi[core]];
++					} else {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev5
++								   [txpi[core]];
++					}
++				} else {
++					if (NREV_GE(phyrev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3)) {
++						txgain =
++							nphy_tpc_txgain_HiPwrEPA
++							[txpi[core]];
++					} else {
++						txgain = nphy_tpc_txgain_rev3
++							 [txpi[core]];
++					}
++				}
++			}
++		} else {
++			txgain = nphy_tpc_txgain[txpi[core]];
++		}
++
++		if (NREV_GE(phyrev, 3))
++			rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
++		else
++			rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 7))
++			dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
++		else
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++
++		bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 3))
++			mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++					 0xa5), (0x1 << 8), (0x1 << 8));
++		else
++			mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++		write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
++
++		wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++					 &rad_gain);
++
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++		m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++		m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
++		wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++		if (PHY_IPA(pi)) {
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
++						576 + txpi[core], 32,
++						&rfpwr_offset);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1ff << 4),
++				    ((s16) rfpwr_offset) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (1) << 2);
++
++		}
++	}
++
++	and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
++				u8 tmp_max_pwr, u8 rate_start,
++				u8 rate_end)
++{
++	u8 rate;
++	u8 word_num, nibble_num;
++	u8 tmp_nibble;
++
++	for (rate = rate_start; rate <= rate_end; rate++) {
++		word_num = (rate - rate_start) >> 2;
++		nibble_num = (rate - rate_start) & 0x3;
++		tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
++
++		srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
++	}
++}
++
++static void
++wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
++			    u8 rate_start, u8 rate_end)
++{
++	u8 rate;
++
++	for (rate = rate_start; rate <= rate_end; rate++)
++		srom_max[rate] -= 2 * pwr_offset;
++}
++
++void
++wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++				u8 rate_mcs_end, u8 rate_ofdm_start)
++{
++	u8 rate1, rate2;
++
++	rate2 = rate_ofdm_start;
++	for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
++		power[rate1] = power[rate2];
++		rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
++	}
++	power[rate_mcs_end] = power[rate_mcs_end - 1];
++}
++
++void
++wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
++				u8 rate_ofdm_end, u8 rate_mcs_start)
++{
++	u8 rate1, rate2;
++
++	for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
++	     rate1 <= rate_ofdm_end; rate1++, rate2++) {
++		power[rate1] = power[rate2];
++		if (rate1 == rate_ofdm_start)
++			power[++rate1] = power[rate2];
++	}
++}
++
++void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi)
++{
++	uint rate1, rate2, band_num;
++	u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
++	u8 tmp_max_pwr = 0;
++	u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
++	u8 *tx_srom_max_rate = NULL;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
++					  pi->nphy_pwrctrl_info[1].max_pwr_2g);
++
++			pwr_offsets1[0] = pi->cck2gpo;
++			wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
++							pwr_offsets1,
++							tmp_max_pwr,
++							TXP_FIRST_CCK,
++							TXP_LAST_CCK);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm2gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs2gpo;
++
++			tmp_cddpo = pi->cdd2gpo;
++			tmp_stbcpo = pi->stbc2gpo;
++			tmp_bw40po = pi->bw402gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_2g;
++			break;
++		case 1:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gm);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5gpo;
++
++			tmp_cddpo = pi->cdd5gpo;
++			tmp_stbcpo = pi->stbc5gpo;
++			tmp_bw40po = pi->bw405gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
++			break;
++		case 2:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gl);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5glpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5glpo;
++
++			tmp_cddpo = pi->cdd5glpo;
++			tmp_stbcpo = pi->stbc5glpo;
++			tmp_bw40po = pi->bw405glpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
++			break;
++		case 3:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gh);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5ghpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5ghpo;
++
++			tmp_cddpo = pi->cdd5ghpo;
++			tmp_stbcpo = pi->stbc5ghpo;
++			tmp_bw40po = pi->bw405ghpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
++			break;
++		}
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
++						tmp_max_pwr, TXP_FIRST_OFDM,
++						TXP_LAST_OFDM);
++
++		wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_MCS_20_SISO,
++						TXP_LAST_MCS_20_SISO,
++						TXP_FIRST_OFDM);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_CDD,
++						TXP_LAST_MCS_20_CDD);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_20_CDD,
++						    TXP_LAST_MCS_20_CDD);
++
++		wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_OFDM_20_CDD,
++						TXP_LAST_OFDM_20_CDD,
++						TXP_FIRST_MCS_20_CDD);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_STBC,
++						TXP_LAST_MCS_20_STBC);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_20_STBC,
++						    TXP_LAST_MCS_20_STBC);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++						&pwr_offsets2[2], tmp_max_pwr,
++						TXP_FIRST_MCS_20_SDM,
++						TXP_LAST_MCS_20_SDM);
++
++		if (NPHY_IS_SROM_REINTERPRET) {
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SISO,
++							TXP_LAST_MCS_40_SISO);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_SISO,
++							TXP_LAST_OFDM_40_SISO,
++							TXP_FIRST_MCS_40_SISO);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_CDD,
++							TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_40_CDD,
++						    TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_CDD,
++							TXP_LAST_OFDM_40_CDD,
++							TXP_FIRST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_STBC,
++							TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_40_STBC,
++						    TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[6],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SDM,
++							TXP_LAST_MCS_40_SDM);
++		} else {
++
++			for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
++				     TXP_FIRST_OFDM;
++			     rate1 <= TXP_LAST_MCS_40_SDM;
++			     rate1++, rate2++)
++				tx_srom_max_rate[rate1] =
++					tx_srom_max_rate[rate2];
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_bw40po,
++						    TXP_FIRST_OFDM_40_SISO,
++						    TXP_LAST_MCS_40_SDM);
++
++		tx_srom_max_rate[TXP_MCS_32] =
++			tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
++	}
++
++	return;
++}
++
++void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
++{
++	u8 tx_pwr_ctrl_state;
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++}
++
++static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi)
++{
++	return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
++					    (0x1 << 14) | (0x1 << 13));
++}
++
++u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi)
++{
++	u16 tmp;
++	u16 pwr_idx[2];
++
++	if (wlc_phy_txpwr_ison_nphy(pi)) {
++		pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
++		pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
++
++		tmp = (pwr_idx[0] << 8) | pwr_idx[1];
++	} else {
++		tmp = ((pi->nphy_txpwrindex[PHY_CORE_0].index_internal & 0xff)
++			<< 8) |
++			(pi->nphy_txpwrindex[PHY_CORE_1].index_internal & 0xff);
++	}
++
++	return tmp;
++}
++
++void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi)
++{
++	if (PHY_IPA(pi)
++	    && (pi->nphy_force_papd_cal
++		|| (wlc_phy_txpwr_ison_nphy(pi)
++		    &&
++		    (((u32)
++		      abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
++			  pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
++		     || ((u32)
++			 abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
++			     pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4)))))
++		wlc_phy_a4(pi, true);
++}
++
++void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type)
++{
++	u16 mask = 0, val = 0, ishw = 0;
++	u8 ctr;
++	uint core;
++	u32 tbl_offset;
++	u32 tbl_len;
++	u16 regval[84];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	switch (ctrl_type) {
++	case PHY_TPC_HW_OFF:
++	case PHY_TPC_HW_ON:
++		pi->nphy_txpwrctrl = ctrl_type;
++		break;
++	default:
++		break;
++	}
++
++	if (ctrl_type == PHY_TPC_HW_OFF) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			if (wlc_phy_txpwr_ison_nphy(pi)) {
++				for (core = 0; core < pi->pubpi.phy_corenum;
++				     core++)
++					pi->nphy_txpwr_idx[core] =
++						wlc_phy_txpwr_idx_cur_get_nphy(
++							pi,
++							(u8) core);
++			}
++
++		}
++
++		tbl_len = 84;
++		tbl_offset = 64;
++		for (ctr = 0; ctr < tbl_len; ctr++)
++			regval[ctr] = 0;
++		wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
++					 regval);
++		wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
++					 regval);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 15) |
++					     (0x1 << 14) | (0x1 << 13))));
++		else
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 14) | (0x1 << 13))));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			or_phy_reg(pi, 0x8f, (0x1 << 8));
++			or_phy_reg(pi, 0xa5, (0x1 << 8));
++		} else {
++			or_phy_reg(pi, 0xa5, (0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       MHF1_IQSWAP_WAR, BRCM_BAND_ALL);
++
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++
++		ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
++		mask = (0x1 << 14) | (0x1 << 13);
++		val = (ishw << 14) | (ishw << 13);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			mask |= (0x1 << 15);
++			val |= (ishw << 15);
++		}
++
++		mod_phy_reg(pi, 0x1e7, mask, val);
++
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
++				mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
++			} else {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
++				if (NREV_GT(pi->pubpi.phy_rev, 1))
++					mod_phy_reg(pi, 0x222,
++						    (0xff << 0), 0x64);
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if ((pi->nphy_txpwr_idx[0] != 128)
++			    && (pi->nphy_txpwr_idx[1] != 128))
++				wlc_phy_txpwr_idx_cur_set_nphy(pi,
++							       pi->
++							       nphy_txpwr_idx
++							       [0],
++							       pi->
++							       nphy_txpwr_idx
++							       [1]);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			and_phy_reg(pi, 0x8f, ~(0x1 << 8));
++			and_phy_reg(pi, 0xa5, ~(0x1 << 8));
++		} else {
++			and_phy_reg(pi, 0xa5, ~(0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       0x0, BRCM_BAND_ALL);
++
++		if (PHY_IPA(pi)) {
++			mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++		}
++
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex,
++			 bool restore_cals)
++{
++	u8 core, txpwrctl_tbl;
++	u16 tx_ind0, iq_ind0, lo_ind0;
++	u16 m1m2;
++	u32 txgain;
++	u16 rad_gain, dac_gain;
++	u8 bbmult;
++	u32 iqcomp;
++	u16 iqcomp_a, iqcomp_b;
++	u32 locomp;
++	u16 tmpval;
++	u8 tx_pwr_ctrl_state;
++	s32 rfpwr_offset;
++	u16 regval[2];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	tx_ind0 = 192;
++	iq_ind0 = 320;
++	lo_ind0 = 448;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((core_mask & (1 << core)) == 0)
++			continue;
++
++		txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
++
++		if (txpwrindex < 0) {
++			if (pi->nphy_txpwrindex[core].index < 0)
++				continue;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				mod_phy_reg(pi, 0x8f,
++					    (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++				mod_phy_reg(pi, 0xa5, (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			} else {
++				mod_phy_reg(pi, 0xa5,
++					    (0x1 << 14),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab,
++				      pi->nphy_txpwrindex[core].AfeCtrlDacGain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &pi->nphy_txpwrindex[core].
++						 rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				 (pi->nphy_txpwrindex[core].bbmult << 8) :
++				 (pi->nphy_txpwrindex[core].bbmult << 0));
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			if (restore_cals) {
++				wlc_phy_table_write_nphy(
++					pi, 15, 2, (80 + 2 * core), 16,
++					&pi->nphy_txpwrindex[core].iqcomp_a);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (85 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (93 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++
++			pi->nphy_txpwrindex[core].index_internal =
++				pi->nphy_txpwrindex[core].index_internal_save;
++		} else {
++
++			if (pi->nphy_txpwrindex[core].index < 0) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					mod_phy_reg(pi, 0x8f,
++						    (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++					mod_phy_reg(pi, 0xa5, (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++				} else {
++					pi->nphy_txpwrindex[core].
++					AfectrlOverride =
++						read_phy_reg(pi, 0xa5);
++				}
++
++				pi->nphy_txpwrindex[core].AfeCtrlDacGain =
++					read_phy_reg(pi, (core == PHY_CORE_0) ?
++							 0xaa : 0xab);
++
++				wlc_phy_table_read_nphy(pi, 7, 1,
++							(0x110 + core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							rad_gain);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++							&tmpval);
++				tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
++				tmpval &= 0xff;
++				pi->nphy_txpwrindex[core].bbmult = (u8) tmpval;
++
++				wlc_phy_table_read_nphy(pi, 15, 2,
++							(80 + 2 * core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							iqcomp_a);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
++							16,
++							&pi->
++							nphy_txpwrindex[core].
++							locomp);
++
++				pi->nphy_txpwrindex[core].index_internal_save =
++					pi->nphy_txpwrindex[core].
++					index_internal;
++			}
++
++			tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++			wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(tx_ind0 + txpwrindex), 32,
++						&txgain);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				rad_gain = (txgain >> 16) &
++					   ((1 << (32 - 16 + 1)) - 1);
++			else
++				rad_gain = (txgain >> 16) &
++					   ((1 << (28 - 16 + 1)) - 1);
++
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++			bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++						 0xa5), (0x1 << 8), (0x1 << 8));
++			else
++				mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab, dac_gain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				(bbmult << 8) : (bbmult << 0));
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(iq_ind0 + txpwrindex), 32,
++						&iqcomp);
++			iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
++			iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
++
++			if (restore_cals) {
++				regval[0] = (u16) iqcomp_a;
++				regval[1] = (u16) iqcomp_b;
++				wlc_phy_table_write_nphy(pi, 15, 2,
++							 (80 + 2 * core), 16,
++							 regval);
++			}
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(lo_ind0 + txpwrindex), 32,
++						&locomp);
++			if (restore_cals)
++				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
++							 16, &locomp);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++			if (PHY_IPA(pi)) {
++				wlc_phy_table_read_nphy(pi,
++						(core == PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL),
++						1, 576 + txpwrindex, 32,
++						&rfpwr_offset);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1ff << 4),
++					    ((s16) rfpwr_offset) << 4);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1 << 2), (1) << 2);
++
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++		}
++
++		pi->nphy_txpwrindex[core].index = txpwrindex;
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr,
++				   u8 txp_rate_idx)
++{
++	u8 chan_freq_range;
++
++	chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
++	switch (chan_freq_range) {
++	case WL_CHAN_FREQ_RANGE_2G:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GM:
++		*max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GL:
++		*max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GH:
++		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++		break;
++	default:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	}
++
++	return;
++}
++
++void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable)
++{
++	u16 clip_off[] = { 0xffff, 0xffff };
++
++	if (enable) {
++		if (pi->nphy_deaf_count == 0) {
++			pi->classifier_state =
++				wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++			wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
++			wlc_phy_clip_det_nphy(pi, 1, clip_off);
++		}
++
++		pi->nphy_deaf_count++;
++
++		wlc_phy_resetcca_nphy(pi);
++
++	} else {
++		pi->nphy_deaf_count--;
++
++		if (pi->nphy_deaf_count == 0) {
++			wlc_phy_classifier_nphy(pi, (0x7 << 0),
++						pi->classifier_state);
++			wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
++		}
++	}
++}
++
++void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (mode) {
++		if (pi->nphy_deaf_count == 0)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++	} else if (pi->nphy_deaf_count > 0) {
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++
++	wlapi_enable_mac(pi->sh->physhim);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+new file mode 100644
+index 0000000..faf1ebe
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+@@ -0,0 +1,308 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include "phy_qmath.h"
++
++/*
++ * Description: This function make 16 bit unsigned multiplication.
++ * To fit the output into 16 bits the 32 bit multiplication result is right
++ * shifted by 16 bits.
++ */
++u16 qm_mulu16(u16 op1, u16 op2)
++{
++	return (u16) (((u32) op1 * (u32) op2) >> 16);
++}
++
++/*
++ * Description: This function make 16 bit multiplication and return the result
++ * in 16 bits. To fit the multiplication result into 16 bits the multiplication
++ * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
++ * is done to remove the extra sign bit formed due to the multiplication.
++ * When both the 16bit inputs are 0x8000 then the output is saturated to
++ * 0x7fffffff.
++ */
++s16 qm_muls16(s16 op1, s16 op2)
++{
++	s32 result;
++	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
++		result = 0x7fffffff;
++	else
++		result = ((s32) (op1) * (s32) (op2));
++
++	return (s16) (result >> 15);
++}
++
++/*
++ * Description: This function add two 32 bit numbers and return the 32bit
++ * result. If the result overflow 32 bits, the output will be saturated to
++ * 32bits.
++ */
++s32 qm_add32(s32 op1, s32 op2)
++{
++	s32 result;
++	result = op1 + op2;
++	if (op1 < 0 && op2 < 0 && result > 0)
++		result = 0x80000000;
++	else if (op1 > 0 && op2 > 0 && result < 0)
++		result = 0x7fffffff;
++
++	return result;
++}
++
++/*
++ * Description: This function add two 16 bit numbers and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_add16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 + (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make 16 bit subtraction and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_sub16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 - (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make a 32 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 32 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s32 qm_shl32(s32 op, int shift)
++{
++	int i;
++	s32 result;
++	result = op;
++	if (shift > 31)
++		shift = 31;
++	else if (shift < -31)
++		shift = -31;
++	if (shift >= 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add32(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 16 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s16 qm_shl16(s16 op, int shift)
++{
++	int i;
++	s16 result;
++	result = op;
++	if (shift > 15)
++		shift = 15;
++	else if (shift < -15)
++		shift = -15;
++	if (shift > 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add16(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit right shift when shift is +ve.
++ * This function make a 16 bit saturated left shift when shift is -ve. This
++ * function return the result of the shift operation.
++ */
++s16 qm_shr16(s16 op, int shift)
++{
++	return qm_shl16(op, -shift);
++}
++
++/*
++ * Description: This function return the number of redundant sign bits in a
++ * 32 bit number. Example: qm_norm32(0x00000080) = 23
++ */
++s16 qm_norm32(s32 op)
++{
++	u16 u16extraSignBits;
++	if (op == 0) {
++		return 31;
++	} else {
++		u16extraSignBits = 0;
++		while ((op >> 31) == (op >> 30)) {
++			u16extraSignBits++;
++			op = op << 1;
++		}
++	}
++	return u16extraSignBits;
++}
++
++/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
++static const s16 log_table[] = {
++	0,
++	1455,
++	2866,
++	4236,
++	5568,
++	6863,
++	8124,
++	9352,
++	10549,
++	11716,
++	12855,
++	13968,
++	15055,
++	16117,
++	17156,
++	18173,
++	19168,
++	20143,
++	21098,
++	22034,
++	22952,
++	23852,
++	24736,
++	25604,
++	26455,
++	27292,
++	28114,
++	28922,
++	29717,
++	30498,
++	31267,
++	32024
++};
++
++#define LOG_TABLE_SIZE 32       /* log_table size */
++#define LOG2_LOG_TABLE_SIZE 5   /* log2(log_table size) */
++#define Q_LOG_TABLE 15          /* qformat of log_table */
++#define LOG10_2         19728   /* log10(2) in q.16 */
++
++/*
++ * Description:
++ * This routine takes the input number N and its q format qN and compute
++ * the log10(N). This routine first normalizes the input no N.	Then N is in
++ * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
++ * Then log2(mag * 2^x) = log2(mag) + x is computed. From that
++ * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
++ * This routine looks the log2 value in the table considering
++ * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
++ * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
++ * for interpolation.
++ * Inputs:
++ * N - number to which log10 has to be found.
++ * qN - q format of N
++ * log10N - address where log10(N) will be written.
++ * qLog10N - address where log10N qformat will be written.
++ * Note/Problem:
++ * For accurate results input should be in normalized or near normalized form.
++ */
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
++{
++	s16 s16norm, s16tableIndex, s16errorApproximation;
++	u16 u16offset;
++	s32 s32log;
++
++	/* normalize the N. */
++	s16norm = qm_norm32(N);
++	N = N << s16norm;
++
++	/* The qformat of N after normalization.
++	 * -30 is added to treat the no as between 1.0 to 2.0
++	 * i.e. after adding the -30 to the qformat the decimal point will be
++	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
++	 * at the right side of 30th bit.
++	 */
++	qN = qN + s16norm - 30;
++
++	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
++	 * MSB */
++	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
++
++	/* remove the MSB. the MSB is always 1 after normalization. */
++	s16tableIndex =
++		s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
++
++	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
++	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
++
++	/* take the offset as the 16 MSBS after table index.
++	 */
++	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
++
++	/* look the log value in the table. */
++	s32log = log_table[s16tableIndex];      /* q.15 format */
++
++	/* interpolate using the offset. q.15 format. */
++	s16errorApproximation = (s16) qm_mulu16(u16offset,
++				(u16) (log_table[s16tableIndex + 1] -
++				       log_table[s16tableIndex]));
++
++	 /* q.15 format */
++	s32log = qm_add16((s16) s32log, s16errorApproximation);
++
++	/* adjust for the qformat of the N as
++	 * log2(mag * 2^x) = log2(mag) + x
++	 */
++	s32log = qm_add32(s32log, ((s32) -qN) << 15);   /* q.15 format */
++
++	/* normalize the result. */
++	s16norm = qm_norm32(s32log);
++
++	/* bring all the important bits into lower 16 bits */
++	/* q.15+s16norm-16 format */
++	s32log = qm_shl32(s32log, s16norm - 16);
++
++	/* compute the log10(N) by multiplying log2(N) with log10(2).
++	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
++	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
++	 */
++	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
++
++	/* write the q format of the result. */
++	*qLog10N = 15 + s16norm - 16 + 1;
++
++	return;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+new file mode 100644
+index 0000000..20e3783
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_QMATH_H_
++#define _BRCM_QMATH_H_
++
++#include <types.h>
++
++u16 qm_mulu16(u16 op1, u16 op2);
++
++s16 qm_muls16(s16 op1, s16 op2);
++
++s32 qm_add32(s32 op1, s32 op2);
++
++s16 qm_add16(s16 op1, s16 op2);
++
++s16 qm_sub16(s16 op1, s16 op2);
++
++s32 qm_shl32(s32 op, int shift);
++
++s16 qm_shl16(s16 op, int shift);
++
++s16 qm_shr16(s16 op, int shift);
++
++s16 qm_norm32(s32 op);
++
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
++
++#endif				/* #ifndef _BRCM_QMATH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+new file mode 100644
+index 0000000..c3a6754
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+@@ -0,0 +1,1533 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_PHY_RADIO_H_
++#define	_BRCM_PHY_RADIO_H_
++
++#define	RADIO_IDCODE			0x01
++
++#define RADIO_DEFAULT_CORE		0
++
++#define	RXC0_RSSI_RST			0x80
++#define	RXC0_MODE_RSSI			0x40
++#define	RXC0_MODE_OFF			0x20
++#define	RXC0_MODE_CM			0x10
++#define	RXC0_LAN_LOAD			0x08
++#define	RXC0_OFF_ADJ_MASK		0x07
++
++#define	TXC0_MODE_TXLPF			0x04
++#define	TXC0_PA_TSSI_EN			0x02
++#define	TXC0_TSSI_EN			0x01
++
++#define	TXC1_PA_GAIN_MASK		0x60
++#define	TXC1_PA_GAIN_3DB		0x40
++#define	TXC1_PA_GAIN_2DB		0x20
++#define	TXC1_TX_MIX_GAIN		0x10
++#define	TXC1_OFF_I_MASK			0x0c
++#define	TXC1_OFF_Q_MASK			0x03
++
++#define	RADIO_2055_READ_OFF		0x100
++#define	RADIO_2057_READ_OFF		0x200
++
++#define RADIO_2055_GEN_SPARE		0x00
++#define RADIO_2055_SP_PIN_PD		0x02
++#define RADIO_2055_SP_RSSI_CORE1	0x03
++#define RADIO_2055_SP_PD_MISC_CORE1	0x04
++#define RADIO_2055_SP_RSSI_CORE2	0x05
++#define RADIO_2055_SP_PD_MISC_CORE2	0x06
++#define RADIO_2055_SP_RX_GC1_CORE1	0x07
++#define RADIO_2055_SP_RX_GC2_CORE1	0x08
++#define RADIO_2055_SP_RX_GC1_CORE2	0x09
++#define RADIO_2055_SP_RX_GC2_CORE2	0x0a
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
++#define RADIO_2055_SP_TX_GC1_CORE1	0x0d
++#define RADIO_2055_SP_TX_GC2_CORE1	0x0e
++#define RADIO_2055_SP_TX_GC1_CORE2	0x0f
++#define RADIO_2055_SP_TX_GC2_CORE2	0x10
++#define RADIO_2055_MASTER_CNTRL1	0x11
++#define RADIO_2055_MASTER_CNTRL2	0x12
++#define RADIO_2055_PD_LGEN		0x13
++#define RADIO_2055_PD_PLL_TS		0x14
++#define RADIO_2055_PD_CORE1_LGBUF	0x15
++#define RADIO_2055_PD_CORE1_TX		0x16
++#define RADIO_2055_PD_CORE1_RXTX	0x17
++#define RADIO_2055_PD_CORE1_RSSI_MISC	0x18
++#define RADIO_2055_PD_CORE2_LGBUF	0x19
++#define RADIO_2055_PD_CORE2_TX		0x1a
++#define RADIO_2055_PD_CORE2_RXTX	0x1b
++#define RADIO_2055_PD_CORE2_RSSI_MISC	0x1c
++#define RADIO_2055_PWRDET_LGEN		0x1d
++#define RADIO_2055_PWRDET_LGBUF_CORE1	0x1e
++#define RADIO_2055_PWRDET_RXTX_CORE1	0x1f
++#define RADIO_2055_PWRDET_LGBUF_CORE2	0x20
++#define RADIO_2055_PWRDET_RXTX_CORE2	0x21
++#define RADIO_2055_RRCCAL_CNTRL_SPARE	0x22
++#define RADIO_2055_RRCCAL_N_OPT_SEL	0x23
++#define RADIO_2055_CAL_MISC		0x24
++#define RADIO_2055_CAL_COUNTER_OUT	0x25
++#define RADIO_2055_CAL_COUNTER_OUT2	0x26
++#define RADIO_2055_CAL_CVAR_CNTRL	0x27
++#define RADIO_2055_CAL_RVAR_CNTRL	0x28
++#define RADIO_2055_CAL_LPO_CNTRL	0x29
++#define RADIO_2055_CAL_TS		0x2a
++#define RADIO_2055_CAL_RCCAL_READ_TS	0x2b
++#define RADIO_2055_CAL_RCAL_READ_TS	0x2c
++#define RADIO_2055_PAD_DRIVER		0x2d
++#define RADIO_2055_XO_CNTRL1		0x2e
++#define RADIO_2055_XO_CNTRL2		0x2f
++#define RADIO_2055_XO_REGULATOR		0x30
++#define RADIO_2055_XO_MISC		0x31
++#define RADIO_2055_PLL_LF_C1		0x32
++#define RADIO_2055_PLL_CAL_VTH		0x33
++#define RADIO_2055_PLL_LF_C2		0x34
++#define RADIO_2055_PLL_REF		0x35
++#define RADIO_2055_PLL_LF_R1		0x36
++#define RADIO_2055_PLL_PFD_CP		0x37
++#define RADIO_2055_PLL_IDAC_CPOPAMP	0x38
++#define RADIO_2055_PLL_CP_REGULATOR	0x39
++#define RADIO_2055_PLL_RCAL		0x3a
++#define RADIO_2055_RF_PLL_MOD0		0x3b
++#define RADIO_2055_RF_PLL_MOD1		0x3c
++#define RADIO_2055_RF_MMD_IDAC1		0x3d
++#define RADIO_2055_RF_MMD_IDAC0		0x3e
++#define RADIO_2055_RF_MMD_SPARE		0x3f
++#define RADIO_2055_VCO_CAL1		0x40
++#define RADIO_2055_VCO_CAL2		0x41
++#define RADIO_2055_VCO_CAL3		0x42
++#define RADIO_2055_VCO_CAL4		0x43
++#define RADIO_2055_VCO_CAL5		0x44
++#define RADIO_2055_VCO_CAL6		0x45
++#define RADIO_2055_VCO_CAL7		0x46
++#define RADIO_2055_VCO_CAL8		0x47
++#define RADIO_2055_VCO_CAL9		0x48
++#define RADIO_2055_VCO_CAL10		0x49
++#define RADIO_2055_VCO_CAL11		0x4a
++#define RADIO_2055_VCO_CAL12		0x4b
++#define RADIO_2055_VCO_CAL13		0x4c
++#define RADIO_2055_VCO_CAL14		0x4d
++#define RADIO_2055_VCO_CAL15		0x4e
++#define RADIO_2055_VCO_CAL16		0x4f
++#define RADIO_2055_VCO_KVCO		0x50
++#define RADIO_2055_VCO_CAP_TAIL		0x51
++#define RADIO_2055_VCO_IDAC_VCO		0x52
++#define RADIO_2055_VCO_REGULATOR	0x53
++#define RADIO_2055_PLL_RF_VTH		0x54
++#define RADIO_2055_LGBUF_CEN_BUF	0x55
++#define RADIO_2055_LGEN_TUNE1		0x56
++#define RADIO_2055_LGEN_TUNE2		0x57
++#define RADIO_2055_LGEN_IDAC1		0x58
++#define RADIO_2055_LGEN_IDAC2		0x59
++#define RADIO_2055_LGEN_BIAS_CNT	0x5a
++#define RADIO_2055_LGEN_BIAS_IDAC	0x5b
++#define RADIO_2055_LGEN_RCAL		0x5c
++#define RADIO_2055_LGEN_DIV		0x5d
++#define RADIO_2055_LGEN_SPARE2		0x5e
++#define RADIO_2055_CORE1_LGBUF_A_TUNE	0x5f
++#define RADIO_2055_CORE1_LGBUF_G_TUNE	0x60
++#define RADIO_2055_CORE1_LGBUF_DIV	0x61
++#define RADIO_2055_CORE1_LGBUF_A_IDAC	0x62
++#define RADIO_2055_CORE1_LGBUF_G_IDAC	0x63
++#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
++#define RADIO_2055_CORE1_LGBUF_SPARE	0x65
++#define RADIO_2055_CORE1_RXRF_SPC1	0x66
++#define RADIO_2055_CORE1_RXRF_REG1	0x67
++#define RADIO_2055_CORE1_RXRF_REG2	0x68
++#define RADIO_2055_CORE1_RXRF_RCAL	0x69
++#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
++#define RADIO_2055_CORE1_RXBB_LPF	0x6b
++#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
++#define RADIO_2055_CORE1_RXBB_VGA1_IDAC	0x6d
++#define RADIO_2055_CORE1_RXBB_VGA2_IDAC	0x6e
++#define RADIO_2055_CORE1_RXBB_VGA3_IDAC	0x6f
++#define RADIO_2055_CORE1_RXBB_BUFO_CTRL	0x70
++#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
++#define RADIO_2055_CORE1_RXBB_REGULATOR	0x77
++#define RADIO_2055_CORE1_RXBB_SPARE1	0x78
++#define RADIO_2055_CORE1_RXTXBB_RCAL	0x79
++#define RADIO_2055_CORE1_TXRF_SGM_PGA	0x7a
++#define RADIO_2055_CORE1_TXRF_SGM_PAD	0x7b
++#define RADIO_2055_CORE1_TXRF_CNTR_PGA1	0x7c
++#define RADIO_2055_CORE1_TXRF_CNTR_PAD1	0x7d
++#define RADIO_2055_CORE1_TX_RFPGA_IDAC	0x7e
++#define RADIO_2055_CORE1_TX_PGA_PAD_TN	0x7f
++#define RADIO_2055_CORE1_TX_PAD_IDAC1	0x80
++#define RADIO_2055_CORE1_TX_PAD_IDAC2	0x81
++#define RADIO_2055_CORE1_TX_MX_BGTRIM	0x82
++#define RADIO_2055_CORE1_TXRF_RCAL	0x83
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI1	0x84
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI2	0x85
++#define RADIO_2055_CORE1_TX_RF_SPARE	0x86
++#define RADIO_2055_CORE1_TXRF_IQCAL1	0x87
++#define RADIO_2055_CORE1_TXRF_IQCAL2	0x88
++#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
++#define RADIO_2055_CORE1_TXBB_LPF1	0x8a
++#define RADIO_2055_CORE1_TX_VOS_CNCL	0x8b
++#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
++#define RADIO_2055_CORE1_TX_BB_MXGM	0x8d
++#define RADIO_2055_CORE2_LGBUF_A_TUNE	0x8e
++#define RADIO_2055_CORE2_LGBUF_G_TUNE	0x8f
++#define RADIO_2055_CORE2_LGBUF_DIV	0x90
++#define RADIO_2055_CORE2_LGBUF_A_IDAC	0x91
++#define RADIO_2055_CORE2_LGBUF_G_IDAC	0x92
++#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
++#define RADIO_2055_CORE2_LGBUF_SPARE	0x94
++#define RADIO_2055_CORE2_RXRF_SPC1	0x95
++#define RADIO_2055_CORE2_RXRF_REG1	0x96
++#define RADIO_2055_CORE2_RXRF_REG2	0x97
++#define RADIO_2055_CORE2_RXRF_RCAL	0x98
++#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
++#define RADIO_2055_CORE2_RXBB_LPF	0x9a
++#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
++#define RADIO_2055_CORE2_RXBB_VGA1_IDAC	0x9c
++#define RADIO_2055_CORE2_RXBB_VGA2_IDAC	0x9d
++#define RADIO_2055_CORE2_RXBB_VGA3_IDAC	0x9e
++#define RADIO_2055_CORE2_RXBB_BUFO_CTRL	0x9f
++#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
++#define RADIO_2055_CORE2_RXBB_REGULATOR	0xa6
++#define RADIO_2055_CORE2_RXBB_SPARE1	0xa7
++#define RADIO_2055_CORE2_RXTXBB_RCAL	0xa8
++#define RADIO_2055_CORE2_TXRF_SGM_PGA	0xa9
++#define RADIO_2055_CORE2_TXRF_SGM_PAD	0xaa
++#define RADIO_2055_CORE2_TXRF_CNTR_PGA1	0xab
++#define RADIO_2055_CORE2_TXRF_CNTR_PAD1	0xac
++#define RADIO_2055_CORE2_TX_RFPGA_IDAC	0xad
++#define RADIO_2055_CORE2_TX_PGA_PAD_TN	0xae
++#define RADIO_2055_CORE2_TX_PAD_IDAC1	0xaf
++#define RADIO_2055_CORE2_TX_PAD_IDAC2	0xb0
++#define RADIO_2055_CORE2_TX_MX_BGTRIM	0xb1
++#define RADIO_2055_CORE2_TXRF_RCAL	0xb2
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI1	0xb3
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI2	0xb4
++#define RADIO_2055_CORE2_TX_RF_SPARE	0xb5
++#define RADIO_2055_CORE2_TXRF_IQCAL1	0xb6
++#define RADIO_2055_CORE2_TXRF_IQCAL2	0xb7
++#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
++#define RADIO_2055_CORE2_TXBB_LPF1	0xb9
++#define RADIO_2055_CORE2_TX_VOS_CNCL	0xba
++#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
++#define RADIO_2055_CORE2_TX_BB_MXGM	0xbc
++#define RADIO_2055_PRG_GC_HPVGA23_21	0xbd
++#define RADIO_2055_PRG_GC_HPVGA23_22	0xbe
++#define RADIO_2055_PRG_GC_HPVGA23_23	0xbf
++#define RADIO_2055_PRG_GC_HPVGA23_24	0xc0
++#define RADIO_2055_PRG_GC_HPVGA23_25	0xc1
++#define RADIO_2055_PRG_GC_HPVGA23_26	0xc2
++#define RADIO_2055_PRG_GC_HPVGA23_27	0xc3
++#define RADIO_2055_PRG_GC_HPVGA23_28	0xc4
++#define RADIO_2055_PRG_GC_HPVGA23_29	0xc5
++#define RADIO_2055_PRG_GC_HPVGA23_30	0xc6
++#define RADIO_2055_CORE1_LNA_GAINBST	0xcd
++#define RADIO_2055_CORE1_B0_NBRSSI_VCM	0xd2
++#define RADIO_2055_CORE1_GEN_SPARE2		0xd6
++#define RADIO_2055_CORE2_LNA_GAINBST	0xd9
++#define RADIO_2055_CORE2_B0_NBRSSI_VCM	0xde
++#define RADIO_2055_CORE2_GEN_SPARE2		0xe2
++
++#define RADIO_2055_GAINBST_GAIN_DB	6
++#define RADIO_2055_GAINBST_CODE		0x6
++
++#define RADIO_2055_JTAGCTRL_MASK	0x04
++#define RADIO_2055_JTAGSYNC_MASK	0x08
++#define RADIO_2055_RRCAL_START		0x40
++#define RADIO_2055_RRCAL_RST_N		0x01
++#define RADIO_2055_CAL_LPO_ENABLE	0x80
++#define RADIO_2055_RCAL_DONE		0x80
++#define RADIO_2055_NBRSSI_VCM_I_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_I_SHIFT	0x00
++#define RADIO_2055_NBRSSI_VCM_Q_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_Q_SHIFT	0x00
++#define RADIO_2055_WBRSSI_VCM_IQ_MASK	0x0c
++#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT	0x02
++#define RADIO_2055_NBRSSI_PD		0x01
++#define RADIO_2055_WBRSSI_G1_PD		0x04
++#define RADIO_2055_WBRSSI_G2_PD		0x02
++#define RADIO_2055_NBRSSI_SEL		0x01
++#define RADIO_2055_WBRSSI_G1_SEL	0x04
++#define RADIO_2055_WBRSSI_G2_SEL	0x02
++#define RADIO_2055_COUPLE_RX_MASK	0x01
++#define RADIO_2055_COUPLE_TX_MASK	0x02
++#define RADIO_2055_GAINBST_DISABLE	0x02
++#define RADIO_2055_GAINBST_VAL_MASK	0x07
++#define RADIO_2055_RXMX_GC_MASK		0x0c
++
++#define RADIO_MIMO_CORESEL_OFF		0x0
++#define RADIO_MIMO_CORESEL_CORE1	0x1
++#define RADIO_MIMO_CORESEL_CORE2	0x2
++#define RADIO_MIMO_CORESEL_CORE3	0x3
++#define RADIO_MIMO_CORESEL_CORE4	0x4
++#define RADIO_MIMO_CORESEL_ALLRX	0x5
++#define RADIO_MIMO_CORESEL_ALLTX	0x6
++#define RADIO_MIMO_CORESEL_ALLRXTX	0x7
++
++#define	RADIO_2064_READ_OFF		0x200
++
++#define RADIO_2064_REG000               0x0
++#define RADIO_2064_REG001               0x1
++#define RADIO_2064_REG002               0x2
++#define RADIO_2064_REG003               0x3
++#define RADIO_2064_REG004               0x4
++#define RADIO_2064_REG005               0x5
++#define RADIO_2064_REG006               0x6
++#define RADIO_2064_REG007               0x7
++#define RADIO_2064_REG008               0x8
++#define RADIO_2064_REG009               0x9
++#define RADIO_2064_REG00A               0xa
++#define RADIO_2064_REG00B               0xb
++#define RADIO_2064_REG00C               0xc
++#define RADIO_2064_REG00D               0xd
++#define RADIO_2064_REG00E               0xe
++#define RADIO_2064_REG00F               0xf
++#define RADIO_2064_REG010               0x10
++#define RADIO_2064_REG011               0x11
++#define RADIO_2064_REG012               0x12
++#define RADIO_2064_REG013               0x13
++#define RADIO_2064_REG014               0x14
++#define RADIO_2064_REG015               0x15
++#define RADIO_2064_REG016               0x16
++#define RADIO_2064_REG017               0x17
++#define RADIO_2064_REG018               0x18
++#define RADIO_2064_REG019               0x19
++#define RADIO_2064_REG01A               0x1a
++#define RADIO_2064_REG01B               0x1b
++#define RADIO_2064_REG01C               0x1c
++#define RADIO_2064_REG01D               0x1d
++#define RADIO_2064_REG01E               0x1e
++#define RADIO_2064_REG01F               0x1f
++#define RADIO_2064_REG020               0x20
++#define RADIO_2064_REG021               0x21
++#define RADIO_2064_REG022               0x22
++#define RADIO_2064_REG023               0x23
++#define RADIO_2064_REG024               0x24
++#define RADIO_2064_REG025               0x25
++#define RADIO_2064_REG026               0x26
++#define RADIO_2064_REG027               0x27
++#define RADIO_2064_REG028               0x28
++#define RADIO_2064_REG029               0x29
++#define RADIO_2064_REG02A               0x2a
++#define RADIO_2064_REG02B               0x2b
++#define RADIO_2064_REG02C               0x2c
++#define RADIO_2064_REG02D               0x2d
++#define RADIO_2064_REG02E               0x2e
++#define RADIO_2064_REG02F               0x2f
++#define RADIO_2064_REG030               0x30
++#define RADIO_2064_REG031               0x31
++#define RADIO_2064_REG032               0x32
++#define RADIO_2064_REG033               0x33
++#define RADIO_2064_REG034               0x34
++#define RADIO_2064_REG035               0x35
++#define RADIO_2064_REG036               0x36
++#define RADIO_2064_REG037               0x37
++#define RADIO_2064_REG038               0x38
++#define RADIO_2064_REG039               0x39
++#define RADIO_2064_REG03A               0x3a
++#define RADIO_2064_REG03B               0x3b
++#define RADIO_2064_REG03C               0x3c
++#define RADIO_2064_REG03D               0x3d
++#define RADIO_2064_REG03E               0x3e
++#define RADIO_2064_REG03F               0x3f
++#define RADIO_2064_REG040               0x40
++#define RADIO_2064_REG041               0x41
++#define RADIO_2064_REG042               0x42
++#define RADIO_2064_REG043               0x43
++#define RADIO_2064_REG044               0x44
++#define RADIO_2064_REG045               0x45
++#define RADIO_2064_REG046               0x46
++#define RADIO_2064_REG047               0x47
++#define RADIO_2064_REG048               0x48
++#define RADIO_2064_REG049               0x49
++#define RADIO_2064_REG04A               0x4a
++#define RADIO_2064_REG04B               0x4b
++#define RADIO_2064_REG04C               0x4c
++#define RADIO_2064_REG04D               0x4d
++#define RADIO_2064_REG04E               0x4e
++#define RADIO_2064_REG04F               0x4f
++#define RADIO_2064_REG050               0x50
++#define RADIO_2064_REG051               0x51
++#define RADIO_2064_REG052               0x52
++#define RADIO_2064_REG053               0x53
++#define RADIO_2064_REG054               0x54
++#define RADIO_2064_REG055               0x55
++#define RADIO_2064_REG056               0x56
++#define RADIO_2064_REG057               0x57
++#define RADIO_2064_REG058               0x58
++#define RADIO_2064_REG059               0x59
++#define RADIO_2064_REG05A               0x5a
++#define RADIO_2064_REG05B               0x5b
++#define RADIO_2064_REG05C               0x5c
++#define RADIO_2064_REG05D               0x5d
++#define RADIO_2064_REG05E               0x5e
++#define RADIO_2064_REG05F               0x5f
++#define RADIO_2064_REG060               0x60
++#define RADIO_2064_REG061               0x61
++#define RADIO_2064_REG062               0x62
++#define RADIO_2064_REG063               0x63
++#define RADIO_2064_REG064               0x64
++#define RADIO_2064_REG065               0x65
++#define RADIO_2064_REG066               0x66
++#define RADIO_2064_REG067               0x67
++#define RADIO_2064_REG068               0x68
++#define RADIO_2064_REG069               0x69
++#define RADIO_2064_REG06A               0x6a
++#define RADIO_2064_REG06B               0x6b
++#define RADIO_2064_REG06C               0x6c
++#define RADIO_2064_REG06D               0x6d
++#define RADIO_2064_REG06E               0x6e
++#define RADIO_2064_REG06F               0x6f
++#define RADIO_2064_REG070               0x70
++#define RADIO_2064_REG071               0x71
++#define RADIO_2064_REG072               0x72
++#define RADIO_2064_REG073               0x73
++#define RADIO_2064_REG074               0x74
++#define RADIO_2064_REG075               0x75
++#define RADIO_2064_REG076               0x76
++#define RADIO_2064_REG077               0x77
++#define RADIO_2064_REG078               0x78
++#define RADIO_2064_REG079               0x79
++#define RADIO_2064_REG07A               0x7a
++#define RADIO_2064_REG07B               0x7b
++#define RADIO_2064_REG07C               0x7c
++#define RADIO_2064_REG07D               0x7d
++#define RADIO_2064_REG07E               0x7e
++#define RADIO_2064_REG07F               0x7f
++#define RADIO_2064_REG080               0x80
++#define RADIO_2064_REG081               0x81
++#define RADIO_2064_REG082               0x82
++#define RADIO_2064_REG083               0x83
++#define RADIO_2064_REG084               0x84
++#define RADIO_2064_REG085               0x85
++#define RADIO_2064_REG086               0x86
++#define RADIO_2064_REG087               0x87
++#define RADIO_2064_REG088               0x88
++#define RADIO_2064_REG089               0x89
++#define RADIO_2064_REG08A               0x8a
++#define RADIO_2064_REG08B               0x8b
++#define RADIO_2064_REG08C               0x8c
++#define RADIO_2064_REG08D               0x8d
++#define RADIO_2064_REG08E               0x8e
++#define RADIO_2064_REG08F               0x8f
++#define RADIO_2064_REG090               0x90
++#define RADIO_2064_REG091               0x91
++#define RADIO_2064_REG092               0x92
++#define RADIO_2064_REG093               0x93
++#define RADIO_2064_REG094               0x94
++#define RADIO_2064_REG095               0x95
++#define RADIO_2064_REG096               0x96
++#define RADIO_2064_REG097               0x97
++#define RADIO_2064_REG098               0x98
++#define RADIO_2064_REG099               0x99
++#define RADIO_2064_REG09A               0x9a
++#define RADIO_2064_REG09B               0x9b
++#define RADIO_2064_REG09C               0x9c
++#define RADIO_2064_REG09D               0x9d
++#define RADIO_2064_REG09E               0x9e
++#define RADIO_2064_REG09F               0x9f
++#define RADIO_2064_REG0A0               0xa0
++#define RADIO_2064_REG0A1               0xa1
++#define RADIO_2064_REG0A2               0xa2
++#define RADIO_2064_REG0A3               0xa3
++#define RADIO_2064_REG0A4               0xa4
++#define RADIO_2064_REG0A5               0xa5
++#define RADIO_2064_REG0A6               0xa6
++#define RADIO_2064_REG0A7               0xa7
++#define RADIO_2064_REG0A8               0xa8
++#define RADIO_2064_REG0A9               0xa9
++#define RADIO_2064_REG0AA               0xaa
++#define RADIO_2064_REG0AB               0xab
++#define RADIO_2064_REG0AC               0xac
++#define RADIO_2064_REG0AD               0xad
++#define RADIO_2064_REG0AE               0xae
++#define RADIO_2064_REG0AF               0xaf
++#define RADIO_2064_REG0B0               0xb0
++#define RADIO_2064_REG0B1               0xb1
++#define RADIO_2064_REG0B2               0xb2
++#define RADIO_2064_REG0B3               0xb3
++#define RADIO_2064_REG0B4               0xb4
++#define RADIO_2064_REG0B5               0xb5
++#define RADIO_2064_REG0B6               0xb6
++#define RADIO_2064_REG0B7               0xb7
++#define RADIO_2064_REG0B8               0xb8
++#define RADIO_2064_REG0B9               0xb9
++#define RADIO_2064_REG0BA               0xba
++#define RADIO_2064_REG0BB               0xbb
++#define RADIO_2064_REG0BC               0xbc
++#define RADIO_2064_REG0BD               0xbd
++#define RADIO_2064_REG0BE               0xbe
++#define RADIO_2064_REG0BF               0xbf
++#define RADIO_2064_REG0C0               0xc0
++#define RADIO_2064_REG0C1               0xc1
++#define RADIO_2064_REG0C2               0xc2
++#define RADIO_2064_REG0C3               0xc3
++#define RADIO_2064_REG0C4               0xc4
++#define RADIO_2064_REG0C5               0xc5
++#define RADIO_2064_REG0C6               0xc6
++#define RADIO_2064_REG0C7               0xc7
++#define RADIO_2064_REG0C8               0xc8
++#define RADIO_2064_REG0C9               0xc9
++#define RADIO_2064_REG0CA               0xca
++#define RADIO_2064_REG0CB               0xcb
++#define RADIO_2064_REG0CC               0xcc
++#define RADIO_2064_REG0CD               0xcd
++#define RADIO_2064_REG0CE               0xce
++#define RADIO_2064_REG0CF               0xcf
++#define RADIO_2064_REG0D0               0xd0
++#define RADIO_2064_REG0D1               0xd1
++#define RADIO_2064_REG0D2               0xd2
++#define RADIO_2064_REG0D3               0xd3
++#define RADIO_2064_REG0D4               0xd4
++#define RADIO_2064_REG0D5               0xd5
++#define RADIO_2064_REG0D6               0xd6
++#define RADIO_2064_REG0D7               0xd7
++#define RADIO_2064_REG0D8               0xd8
++#define RADIO_2064_REG0D9               0xd9
++#define RADIO_2064_REG0DA               0xda
++#define RADIO_2064_REG0DB               0xdb
++#define RADIO_2064_REG0DC               0xdc
++#define RADIO_2064_REG0DD               0xdd
++#define RADIO_2064_REG0DE               0xde
++#define RADIO_2064_REG0DF               0xdf
++#define RADIO_2064_REG0E0               0xe0
++#define RADIO_2064_REG0E1               0xe1
++#define RADIO_2064_REG0E2               0xe2
++#define RADIO_2064_REG0E3               0xe3
++#define RADIO_2064_REG0E4               0xe4
++#define RADIO_2064_REG0E5               0xe5
++#define RADIO_2064_REG0E6               0xe6
++#define RADIO_2064_REG0E7               0xe7
++#define RADIO_2064_REG0E8               0xe8
++#define RADIO_2064_REG0E9               0xe9
++#define RADIO_2064_REG0EA               0xea
++#define RADIO_2064_REG0EB               0xeb
++#define RADIO_2064_REG0EC               0xec
++#define RADIO_2064_REG0ED               0xed
++#define RADIO_2064_REG0EE               0xee
++#define RADIO_2064_REG0EF               0xef
++#define RADIO_2064_REG0F0               0xf0
++#define RADIO_2064_REG0F1               0xf1
++#define RADIO_2064_REG0F2               0xf2
++#define RADIO_2064_REG0F3               0xf3
++#define RADIO_2064_REG0F4               0xf4
++#define RADIO_2064_REG0F5               0xf5
++#define RADIO_2064_REG0F6               0xf6
++#define RADIO_2064_REG0F7               0xf7
++#define RADIO_2064_REG0F8               0xf8
++#define RADIO_2064_REG0F9               0xf9
++#define RADIO_2064_REG0FA               0xfa
++#define RADIO_2064_REG0FB               0xfb
++#define RADIO_2064_REG0FC               0xfc
++#define RADIO_2064_REG0FD               0xfd
++#define RADIO_2064_REG0FE               0xfe
++#define RADIO_2064_REG0FF               0xff
++#define RADIO_2064_REG100               0x100
++#define RADIO_2064_REG101               0x101
++#define RADIO_2064_REG102               0x102
++#define RADIO_2064_REG103               0x103
++#define RADIO_2064_REG104               0x104
++#define RADIO_2064_REG105               0x105
++#define RADIO_2064_REG106               0x106
++#define RADIO_2064_REG107               0x107
++#define RADIO_2064_REG108               0x108
++#define RADIO_2064_REG109               0x109
++#define RADIO_2064_REG10A               0x10a
++#define RADIO_2064_REG10B               0x10b
++#define RADIO_2064_REG10C               0x10c
++#define RADIO_2064_REG10D               0x10d
++#define RADIO_2064_REG10E               0x10e
++#define RADIO_2064_REG10F               0x10f
++#define RADIO_2064_REG110               0x110
++#define RADIO_2064_REG111               0x111
++#define RADIO_2064_REG112               0x112
++#define RADIO_2064_REG113               0x113
++#define RADIO_2064_REG114               0x114
++#define RADIO_2064_REG115               0x115
++#define RADIO_2064_REG116               0x116
++#define RADIO_2064_REG117               0x117
++#define RADIO_2064_REG118               0x118
++#define RADIO_2064_REG119               0x119
++#define RADIO_2064_REG11A               0x11a
++#define RADIO_2064_REG11B               0x11b
++#define RADIO_2064_REG11C               0x11c
++#define RADIO_2064_REG11D               0x11d
++#define RADIO_2064_REG11E               0x11e
++#define RADIO_2064_REG11F               0x11f
++#define RADIO_2064_REG120               0x120
++#define RADIO_2064_REG121               0x121
++#define RADIO_2064_REG122               0x122
++#define RADIO_2064_REG123               0x123
++#define RADIO_2064_REG124               0x124
++#define RADIO_2064_REG125               0x125
++#define RADIO_2064_REG126               0x126
++#define RADIO_2064_REG127               0x127
++#define RADIO_2064_REG128               0x128
++#define RADIO_2064_REG129               0x129
++#define RADIO_2064_REG12A               0x12a
++#define RADIO_2064_REG12B               0x12b
++#define RADIO_2064_REG12C               0x12c
++#define RADIO_2064_REG12D               0x12d
++#define RADIO_2064_REG12E               0x12e
++#define RADIO_2064_REG12F               0x12f
++#define RADIO_2064_REG130               0x130
++
++#define RADIO_2056_SYN                           (0x0 << 12)
++#define RADIO_2056_TX0                           (0x2 << 12)
++#define RADIO_2056_TX1                           (0x3 << 12)
++#define RADIO_2056_RX0                           (0x6 << 12)
++#define RADIO_2056_RX1                           (0x7 << 12)
++#define RADIO_2056_ALLTX                         (0xe << 12)
++#define RADIO_2056_ALLRX                         (0xf << 12)
++
++#define RADIO_2056_SYN_RESERVED_ADDR0            0x0
++#define RADIO_2056_SYN_IDCODE                    0x1
++#define RADIO_2056_SYN_RESERVED_ADDR2            0x2
++#define RADIO_2056_SYN_RESERVED_ADDR3            0x3
++#define RADIO_2056_SYN_RESERVED_ADDR4            0x4
++#define RADIO_2056_SYN_RESERVED_ADDR5            0x5
++#define RADIO_2056_SYN_RESERVED_ADDR6            0x6
++#define RADIO_2056_SYN_RESERVED_ADDR7            0x7
++#define RADIO_2056_SYN_COM_CTRL                  0x8
++#define RADIO_2056_SYN_COM_PU                    0x9
++#define RADIO_2056_SYN_COM_OVR                   0xa
++#define RADIO_2056_SYN_COM_RESET                 0xb
++#define RADIO_2056_SYN_COM_RCAL                  0xc
++#define RADIO_2056_SYN_COM_RC_RXLPF              0xd
++#define RADIO_2056_SYN_COM_RC_TXLPF              0xe
++#define RADIO_2056_SYN_COM_RC_RXHPF              0xf
++#define RADIO_2056_SYN_RESERVED_ADDR16           0x10
++#define RADIO_2056_SYN_RESERVED_ADDR17           0x11
++#define RADIO_2056_SYN_RESERVED_ADDR18           0x12
++#define RADIO_2056_SYN_RESERVED_ADDR19           0x13
++#define RADIO_2056_SYN_RESERVED_ADDR20           0x14
++#define RADIO_2056_SYN_RESERVED_ADDR21           0x15
++#define RADIO_2056_SYN_RESERVED_ADDR22           0x16
++#define RADIO_2056_SYN_RESERVED_ADDR23           0x17
++#define RADIO_2056_SYN_RESERVED_ADDR24           0x18
++#define RADIO_2056_SYN_RESERVED_ADDR25           0x19
++#define RADIO_2056_SYN_RESERVED_ADDR26           0x1a
++#define RADIO_2056_SYN_RESERVED_ADDR27           0x1b
++#define RADIO_2056_SYN_RESERVED_ADDR28           0x1c
++#define RADIO_2056_SYN_RESERVED_ADDR29           0x1d
++#define RADIO_2056_SYN_RESERVED_ADDR30           0x1e
++#define RADIO_2056_SYN_RESERVED_ADDR31           0x1f
++#define RADIO_2056_SYN_GPIO_MASTER1              0x20
++#define RADIO_2056_SYN_GPIO_MASTER2              0x21
++#define RADIO_2056_SYN_TOPBIAS_MASTER            0x22
++#define RADIO_2056_SYN_TOPBIAS_RCAL              0x23
++#define RADIO_2056_SYN_AFEREG                    0x24
++#define RADIO_2056_SYN_TEMPPROCSENSE             0x25
++#define RADIO_2056_SYN_TEMPPROCSENSEIDAC         0x26
++#define RADIO_2056_SYN_TEMPPROCSENSERCAL         0x27
++#define RADIO_2056_SYN_LPO                       0x28
++#define RADIO_2056_SYN_VDDCAL_MASTER             0x29
++#define RADIO_2056_SYN_VDDCAL_IDAC               0x2a
++#define RADIO_2056_SYN_VDDCAL_STATUS             0x2b
++#define RADIO_2056_SYN_RCAL_MASTER               0x2c
++#define RADIO_2056_SYN_RCAL_CODE_OUT             0x2d
++#define RADIO_2056_SYN_RCCAL_CTRL0               0x2e
++#define RADIO_2056_SYN_RCCAL_CTRL1               0x2f
++#define RADIO_2056_SYN_RCCAL_CTRL2               0x30
++#define RADIO_2056_SYN_RCCAL_CTRL3               0x31
++#define RADIO_2056_SYN_RCCAL_CTRL4               0x32
++#define RADIO_2056_SYN_RCCAL_CTRL5               0x33
++#define RADIO_2056_SYN_RCCAL_CTRL6               0x34
++#define RADIO_2056_SYN_RCCAL_CTRL7               0x35
++#define RADIO_2056_SYN_RCCAL_CTRL8               0x36
++#define RADIO_2056_SYN_RCCAL_CTRL9               0x37
++#define RADIO_2056_SYN_RCCAL_CTRL10              0x38
++#define RADIO_2056_SYN_RCCAL_CTRL11              0x39
++#define RADIO_2056_SYN_ZCAL_SPARE1               0x3a
++#define RADIO_2056_SYN_ZCAL_SPARE2               0x3b
++#define RADIO_2056_SYN_PLL_MAST1                 0x3c
++#define RADIO_2056_SYN_PLL_MAST2                 0x3d
++#define RADIO_2056_SYN_PLL_MAST3                 0x3e
++#define RADIO_2056_SYN_PLL_BIAS_RESET            0x3f
++#define RADIO_2056_SYN_PLL_XTAL0                 0x40
++#define RADIO_2056_SYN_PLL_XTAL1                 0x41
++#define RADIO_2056_SYN_PLL_XTAL3                 0x42
++#define RADIO_2056_SYN_PLL_XTAL4                 0x43
++#define RADIO_2056_SYN_PLL_XTAL5                 0x44
++#define RADIO_2056_SYN_PLL_XTAL6                 0x45
++#define RADIO_2056_SYN_PLL_REFDIV                0x46
++#define RADIO_2056_SYN_PLL_PFD                   0x47
++#define RADIO_2056_SYN_PLL_CP1                   0x48
++#define RADIO_2056_SYN_PLL_CP2                   0x49
++#define RADIO_2056_SYN_PLL_CP3                   0x4a
++#define RADIO_2056_SYN_PLL_LOOPFILTER1           0x4b
++#define RADIO_2056_SYN_PLL_LOOPFILTER2           0x4c
++#define RADIO_2056_SYN_PLL_LOOPFILTER3           0x4d
++#define RADIO_2056_SYN_PLL_LOOPFILTER4           0x4e
++#define RADIO_2056_SYN_PLL_LOOPFILTER5           0x4f
++#define RADIO_2056_SYN_PLL_MMD1                  0x50
++#define RADIO_2056_SYN_PLL_MMD2                  0x51
++#define RADIO_2056_SYN_PLL_VCO1                  0x52
++#define RADIO_2056_SYN_PLL_VCO2                  0x53
++#define RADIO_2056_SYN_PLL_MONITOR1              0x54
++#define RADIO_2056_SYN_PLL_MONITOR2              0x55
++#define RADIO_2056_SYN_PLL_VCOCAL1               0x56
++#define RADIO_2056_SYN_PLL_VCOCAL2               0x57
++#define RADIO_2056_SYN_PLL_VCOCAL4               0x58
++#define RADIO_2056_SYN_PLL_VCOCAL5               0x59
++#define RADIO_2056_SYN_PLL_VCOCAL6               0x5a
++#define RADIO_2056_SYN_PLL_VCOCAL7               0x5b
++#define RADIO_2056_SYN_PLL_VCOCAL8               0x5c
++#define RADIO_2056_SYN_PLL_VCOCAL9               0x5d
++#define RADIO_2056_SYN_PLL_VCOCAL10              0x5e
++#define RADIO_2056_SYN_PLL_VCOCAL11              0x5f
++#define RADIO_2056_SYN_PLL_VCOCAL12              0x60
++#define RADIO_2056_SYN_PLL_VCOCAL13              0x61
++#define RADIO_2056_SYN_PLL_VREG                  0x62
++#define RADIO_2056_SYN_PLL_STATUS1               0x63
++#define RADIO_2056_SYN_PLL_STATUS2               0x64
++#define RADIO_2056_SYN_PLL_STATUS3               0x65
++#define RADIO_2056_SYN_LOGEN_PU0                 0x66
++#define RADIO_2056_SYN_LOGEN_PU1                 0x67
++#define RADIO_2056_SYN_LOGEN_PU2                 0x68
++#define RADIO_2056_SYN_LOGEN_PU3                 0x69
++#define RADIO_2056_SYN_LOGEN_PU5                 0x6a
++#define RADIO_2056_SYN_LOGEN_PU6                 0x6b
++#define RADIO_2056_SYN_LOGEN_PU7                 0x6c
++#define RADIO_2056_SYN_LOGEN_PU8                 0x6d
++#define RADIO_2056_SYN_LOGEN_BIAS_RESET          0x6e
++#define RADIO_2056_SYN_LOGEN_RCCR1               0x6f
++#define RADIO_2056_SYN_LOGEN_VCOBUF1             0x70
++#define RADIO_2056_SYN_LOGEN_MIXER1              0x71
++#define RADIO_2056_SYN_LOGEN_MIXER2              0x72
++#define RADIO_2056_SYN_LOGEN_BUF1                0x73
++#define RADIO_2056_SYN_LOGENBUF2                 0x74
++#define RADIO_2056_SYN_LOGEN_BUF3                0x75
++#define RADIO_2056_SYN_LOGEN_BUF4                0x76
++#define RADIO_2056_SYN_LOGEN_DIV1                0x77
++#define RADIO_2056_SYN_LOGEN_DIV2                0x78
++#define RADIO_2056_SYN_LOGEN_DIV3                0x79
++#define RADIO_2056_SYN_LOGEN_ACL1                0x7a
++#define RADIO_2056_SYN_LOGEN_ACL2                0x7b
++#define RADIO_2056_SYN_LOGEN_ACL3                0x7c
++#define RADIO_2056_SYN_LOGEN_ACL4                0x7d
++#define RADIO_2056_SYN_LOGEN_ACL5                0x7e
++#define RADIO_2056_SYN_LOGEN_ACL6                0x7f
++#define RADIO_2056_SYN_LOGEN_ACLOUT              0x80
++#define RADIO_2056_SYN_LOGEN_ACLCAL1             0x81
++#define RADIO_2056_SYN_LOGEN_ACLCAL2             0x82
++#define RADIO_2056_SYN_LOGEN_ACLCAL3             0x83
++#define RADIO_2056_SYN_CALEN                     0x84
++#define RADIO_2056_SYN_LOGEN_PEAKDET1            0x85
++#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR        0x86
++#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR     0x87
++#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR     0x88
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR     0x89
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR     0x8a
++#define RADIO_2056_SYN_LOGEN_VCOBUF2             0x8b
++#define RADIO_2056_SYN_LOGEN_MIXER3              0x8c
++#define RADIO_2056_SYN_LOGEN_BUF5                0x8d
++#define RADIO_2056_SYN_LOGEN_BUF6                0x8e
++#define RADIO_2056_SYN_LOGEN_CBUFRX1             0x8f
++#define RADIO_2056_SYN_LOGEN_CBUFRX2             0x90
++#define RADIO_2056_SYN_LOGEN_CBUFRX3             0x91
++#define RADIO_2056_SYN_LOGEN_CBUFRX4             0x92
++#define RADIO_2056_SYN_LOGEN_CBUFTX1             0x93
++#define RADIO_2056_SYN_LOGEN_CBUFTX2             0x94
++#define RADIO_2056_SYN_LOGEN_CBUFTX3             0x95
++#define RADIO_2056_SYN_LOGEN_CBUFTX4             0x96
++#define RADIO_2056_SYN_LOGEN_CMOSRX1             0x97
++#define RADIO_2056_SYN_LOGEN_CMOSRX2             0x98
++#define RADIO_2056_SYN_LOGEN_CMOSRX3             0x99
++#define RADIO_2056_SYN_LOGEN_CMOSRX4             0x9a
++#define RADIO_2056_SYN_LOGEN_CMOSTX1             0x9b
++#define RADIO_2056_SYN_LOGEN_CMOSTX2             0x9c
++#define RADIO_2056_SYN_LOGEN_CMOSTX3             0x9d
++#define RADIO_2056_SYN_LOGEN_CMOSTX4             0x9e
++#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL      0x9f
++#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL       0xa0
++#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL         0xa1
++#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL         0xa2
++#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL      0xa3
++#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL      0xa4
++#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL      0xa5
++#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL      0xa6
++#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL      0xa7
++#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL      0xa8
++#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL      0xa9
++#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL      0xaa
++#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL      0xab
++#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL      0xac
++#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL      0xad
++#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL      0xae
++#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL      0xaf
++#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL      0xb0
++#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL      0xb1
++#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL      0xb2
++#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT         0xb3
++#define RADIO_2056_SYN_LOGEN_CORE_CALVALID       0xb4
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID    0xb5
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID       0xb6
++
++#define RADIO_2056_TX_RESERVED_ADDR0             0x0
++#define RADIO_2056_TX_IDCODE                     0x1
++#define RADIO_2056_TX_RESERVED_ADDR2             0x2
++#define RADIO_2056_TX_RESERVED_ADDR3             0x3
++#define RADIO_2056_TX_RESERVED_ADDR4             0x4
++#define RADIO_2056_TX_RESERVED_ADDR5             0x5
++#define RADIO_2056_TX_RESERVED_ADDR6             0x6
++#define RADIO_2056_TX_RESERVED_ADDR7             0x7
++#define RADIO_2056_TX_COM_CTRL                   0x8
++#define RADIO_2056_TX_COM_PU                     0x9
++#define RADIO_2056_TX_COM_OVR                    0xa
++#define RADIO_2056_TX_COM_RESET                  0xb
++#define RADIO_2056_TX_COM_RCAL                   0xc
++#define RADIO_2056_TX_COM_RC_RXLPF               0xd
++#define RADIO_2056_TX_COM_RC_TXLPF               0xe
++#define RADIO_2056_TX_COM_RC_RXHPF               0xf
++#define RADIO_2056_TX_RESERVED_ADDR16            0x10
++#define RADIO_2056_TX_RESERVED_ADDR17            0x11
++#define RADIO_2056_TX_RESERVED_ADDR18            0x12
++#define RADIO_2056_TX_RESERVED_ADDR19            0x13
++#define RADIO_2056_TX_RESERVED_ADDR20            0x14
++#define RADIO_2056_TX_RESERVED_ADDR21            0x15
++#define RADIO_2056_TX_RESERVED_ADDR22            0x16
++#define RADIO_2056_TX_RESERVED_ADDR23            0x17
++#define RADIO_2056_TX_RESERVED_ADDR24            0x18
++#define RADIO_2056_TX_RESERVED_ADDR25            0x19
++#define RADIO_2056_TX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_TX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_TX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_TX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_TX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_TX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_TX_IQCAL_GAIN_BW              0x20
++#define RADIO_2056_TX_LOFT_FINE_I                0x21
++#define RADIO_2056_TX_LOFT_FINE_Q                0x22
++#define RADIO_2056_TX_LOFT_COARSE_I              0x23
++#define RADIO_2056_TX_LOFT_COARSE_Q              0x24
++#define RADIO_2056_TX_TX_COM_MASTER1             0x25
++#define RADIO_2056_TX_TX_COM_MASTER2             0x26
++#define RADIO_2056_TX_RXIQCAL_TXMUX              0x27
++#define RADIO_2056_TX_TX_SSI_MASTER              0x28
++#define RADIO_2056_TX_IQCAL_VCM_HG               0x29
++#define RADIO_2056_TX_IQCAL_IDAC                 0x2a
++#define RADIO_2056_TX_TSSI_VCM                   0x2b
++#define RADIO_2056_TX_TX_AMP_DET                 0x2c
++#define RADIO_2056_TX_TX_SSI_MUX                 0x2d
++#define RADIO_2056_TX_TSSIA                      0x2e
++#define RADIO_2056_TX_TSSIG                      0x2f
++#define RADIO_2056_TX_TSSI_MISC1                 0x30
++#define RADIO_2056_TX_TSSI_MISC2                 0x31
++#define RADIO_2056_TX_TSSI_MISC3                 0x32
++#define RADIO_2056_TX_PA_SPARE1                  0x33
++#define RADIO_2056_TX_PA_SPARE2                  0x34
++#define RADIO_2056_TX_INTPAA_MASTER              0x35
++#define RADIO_2056_TX_INTPAA_GAIN                0x36
++#define RADIO_2056_TX_INTPAA_BOOST_TUNE          0x37
++#define RADIO_2056_TX_INTPAA_IAUX_STAT           0x38
++#define RADIO_2056_TX_INTPAA_IAUX_DYN            0x39
++#define RADIO_2056_TX_INTPAA_IMAIN_STAT          0x3a
++#define RADIO_2056_TX_INTPAA_IMAIN_DYN           0x3b
++#define RADIO_2056_TX_INTPAA_CASCBIAS            0x3c
++#define RADIO_2056_TX_INTPAA_PASLOPE             0x3d
++#define RADIO_2056_TX_INTPAA_PA_MISC             0x3e
++#define RADIO_2056_TX_INTPAG_MASTER              0x3f
++#define RADIO_2056_TX_INTPAG_GAIN                0x40
++#define RADIO_2056_TX_INTPAG_BOOST_TUNE          0x41
++#define RADIO_2056_TX_INTPAG_IAUX_STAT           0x42
++#define RADIO_2056_TX_INTPAG_IAUX_DYN            0x43
++#define RADIO_2056_TX_INTPAG_IMAIN_STAT          0x44
++#define RADIO_2056_TX_INTPAG_IMAIN_DYN           0x45
++#define RADIO_2056_TX_INTPAG_CASCBIAS            0x46
++#define RADIO_2056_TX_INTPAG_PASLOPE             0x47
++#define RADIO_2056_TX_INTPAG_PA_MISC             0x48
++#define RADIO_2056_TX_PADA_MASTER                0x49
++#define RADIO_2056_TX_PADA_IDAC                  0x4a
++#define RADIO_2056_TX_PADA_CASCBIAS              0x4b
++#define RADIO_2056_TX_PADA_GAIN                  0x4c
++#define RADIO_2056_TX_PADA_BOOST_TUNE            0x4d
++#define RADIO_2056_TX_PADA_SLOPE                 0x4e
++#define RADIO_2056_TX_PADG_MASTER                0x4f
++#define RADIO_2056_TX_PADG_IDAC                  0x50
++#define RADIO_2056_TX_PADG_CASCBIAS              0x51
++#define RADIO_2056_TX_PADG_GAIN                  0x52
++#define RADIO_2056_TX_PADG_BOOST_TUNE            0x53
++#define RADIO_2056_TX_PADG_SLOPE                 0x54
++#define RADIO_2056_TX_PGAA_MASTER                0x55
++#define RADIO_2056_TX_PGAA_IDAC                  0x56
++#define RADIO_2056_TX_PGAA_GAIN                  0x57
++#define RADIO_2056_TX_PGAA_BOOST_TUNE            0x58
++#define RADIO_2056_TX_PGAA_SLOPE                 0x59
++#define RADIO_2056_TX_PGAA_MISC                  0x5a
++#define RADIO_2056_TX_PGAG_MASTER                0x5b
++#define RADIO_2056_TX_PGAG_IDAC                  0x5c
++#define RADIO_2056_TX_PGAG_GAIN                  0x5d
++#define RADIO_2056_TX_PGAG_BOOST_TUNE            0x5e
++#define RADIO_2056_TX_PGAG_SLOPE                 0x5f
++#define RADIO_2056_TX_PGAG_MISC                  0x60
++#define RADIO_2056_TX_MIXA_MASTER                0x61
++#define RADIO_2056_TX_MIXA_BOOST_TUNE            0x62
++#define RADIO_2056_TX_MIXG                       0x63
++#define RADIO_2056_TX_MIXG_BOOST_TUNE            0x64
++#define RADIO_2056_TX_BB_GM_MASTER               0x65
++#define RADIO_2056_TX_GMBB_GM                    0x66
++#define RADIO_2056_TX_GMBB_IDAC                  0x67
++#define RADIO_2056_TX_TXLPF_MASTER               0x68
++#define RADIO_2056_TX_TXLPF_RCCAL                0x69
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF0           0x6a
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF1           0x6b
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF2           0x6c
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF3           0x6d
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF4           0x6e
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF5           0x6f
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF6           0x70
++#define RADIO_2056_TX_TXLPF_BW                   0x71
++#define RADIO_2056_TX_TXLPF_GAIN                 0x72
++#define RADIO_2056_TX_TXLPF_IDAC                 0x73
++#define RADIO_2056_TX_TXLPF_IDAC_0               0x74
++#define RADIO_2056_TX_TXLPF_IDAC_1               0x75
++#define RADIO_2056_TX_TXLPF_IDAC_2               0x76
++#define RADIO_2056_TX_TXLPF_IDAC_3               0x77
++#define RADIO_2056_TX_TXLPF_IDAC_4               0x78
++#define RADIO_2056_TX_TXLPF_IDAC_5               0x79
++#define RADIO_2056_TX_TXLPF_IDAC_6               0x7a
++#define RADIO_2056_TX_TXLPF_OPAMP_IDAC           0x7b
++#define RADIO_2056_TX_TXLPF_MISC                 0x7c
++#define RADIO_2056_TX_TXSPARE1                   0x7d
++#define RADIO_2056_TX_TXSPARE2                   0x7e
++#define RADIO_2056_TX_TXSPARE3                   0x7f
++#define RADIO_2056_TX_TXSPARE4                   0x80
++#define RADIO_2056_TX_TXSPARE5                   0x81
++#define RADIO_2056_TX_TXSPARE6                   0x82
++#define RADIO_2056_TX_TXSPARE7                   0x83
++#define RADIO_2056_TX_TXSPARE8                   0x84
++#define RADIO_2056_TX_TXSPARE9                   0x85
++#define RADIO_2056_TX_TXSPARE10                  0x86
++#define RADIO_2056_TX_TXSPARE11                  0x87
++#define RADIO_2056_TX_TXSPARE12                  0x88
++#define RADIO_2056_TX_TXSPARE13                  0x89
++#define RADIO_2056_TX_TXSPARE14                  0x8a
++#define RADIO_2056_TX_TXSPARE15                  0x8b
++#define RADIO_2056_TX_TXSPARE16                  0x8c
++#define RADIO_2056_TX_STATUS_INTPA_GAIN          0x8d
++#define RADIO_2056_TX_STATUS_PAD_GAIN            0x8e
++#define RADIO_2056_TX_STATUS_PGA_GAIN            0x8f
++#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN       0x90
++#define RADIO_2056_TX_STATUS_TXLPF_BW            0x91
++#define RADIO_2056_TX_STATUS_TXLPF_RC            0x92
++#define RADIO_2056_TX_GMBB_IDAC0                 0x93
++#define RADIO_2056_TX_GMBB_IDAC1                 0x94
++#define RADIO_2056_TX_GMBB_IDAC2                 0x95
++#define RADIO_2056_TX_GMBB_IDAC3                 0x96
++#define RADIO_2056_TX_GMBB_IDAC4                 0x97
++#define RADIO_2056_TX_GMBB_IDAC5                 0x98
++#define RADIO_2056_TX_GMBB_IDAC6                 0x99
++#define RADIO_2056_TX_GMBB_IDAC7                 0x9a
++
++#define RADIO_2056_RX_RESERVED_ADDR0             0x0
++#define RADIO_2056_RX_IDCODE                     0x1
++#define RADIO_2056_RX_RESERVED_ADDR2             0x2
++#define RADIO_2056_RX_RESERVED_ADDR3             0x3
++#define RADIO_2056_RX_RESERVED_ADDR4             0x4
++#define RADIO_2056_RX_RESERVED_ADDR5             0x5
++#define RADIO_2056_RX_RESERVED_ADDR6             0x6
++#define RADIO_2056_RX_RESERVED_ADDR7             0x7
++#define RADIO_2056_RX_COM_CTRL                   0x8
++#define RADIO_2056_RX_COM_PU                     0x9
++#define RADIO_2056_RX_COM_OVR                    0xa
++#define RADIO_2056_RX_COM_RESET                  0xb
++#define RADIO_2056_RX_COM_RCAL                   0xc
++#define RADIO_2056_RX_COM_RC_RXLPF               0xd
++#define RADIO_2056_RX_COM_RC_TXLPF               0xe
++#define RADIO_2056_RX_COM_RC_RXHPF               0xf
++#define RADIO_2056_RX_RESERVED_ADDR16            0x10
++#define RADIO_2056_RX_RESERVED_ADDR17            0x11
++#define RADIO_2056_RX_RESERVED_ADDR18            0x12
++#define RADIO_2056_RX_RESERVED_ADDR19            0x13
++#define RADIO_2056_RX_RESERVED_ADDR20            0x14
++#define RADIO_2056_RX_RESERVED_ADDR21            0x15
++#define RADIO_2056_RX_RESERVED_ADDR22            0x16
++#define RADIO_2056_RX_RESERVED_ADDR23            0x17
++#define RADIO_2056_RX_RESERVED_ADDR24            0x18
++#define RADIO_2056_RX_RESERVED_ADDR25            0x19
++#define RADIO_2056_RX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_RX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_RX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_RX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_RX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_RX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_RX_RXIQCAL_RXMUX              0x20
++#define RADIO_2056_RX_RSSI_PU                    0x21
++#define RADIO_2056_RX_RSSI_SEL                   0x22
++#define RADIO_2056_RX_RSSI_GAIN                  0x23
++#define RADIO_2056_RX_RSSI_NB_IDAC               0x24
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_1           0x25
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_2           0x26
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1           0x27
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2           0x28
++#define RADIO_2056_RX_RSSI_POLE                  0x29
++#define RADIO_2056_RX_RSSI_WB1_IDAC              0x2a
++#define RADIO_2056_RX_RSSI_MISC                  0x2b
++#define RADIO_2056_RX_LNAA_MASTER                0x2c
++#define RADIO_2056_RX_LNAA_TUNE                  0x2d
++#define RADIO_2056_RX_LNAA_GAIN                  0x2e
++#define RADIO_2056_RX_LNA_A_SLOPE                0x2f
++#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC        0x30
++#define RADIO_2056_RX_LNAA2_IDAC                 0x31
++#define RADIO_2056_RX_LNA1A_MISC                 0x32
++#define RADIO_2056_RX_LNAG_MASTER                0x33
++#define RADIO_2056_RX_LNAG_TUNE                  0x34
++#define RADIO_2056_RX_LNAG_GAIN                  0x35
++#define RADIO_2056_RX_LNA_G_SLOPE                0x36
++#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC        0x37
++#define RADIO_2056_RX_LNAG2_IDAC                 0x38
++#define RADIO_2056_RX_LNA1G_MISC                 0x39
++#define RADIO_2056_RX_MIXA_MASTER                0x3a
++#define RADIO_2056_RX_MIXA_VCM                   0x3b
++#define RADIO_2056_RX_MIXA_CTRLPTAT              0x3c
++#define RADIO_2056_RX_MIXA_LOB_BIAS              0x3d
++#define RADIO_2056_RX_MIXA_CORE_IDAC             0x3e
++#define RADIO_2056_RX_MIXA_CMFB_IDAC             0x3f
++#define RADIO_2056_RX_MIXA_BIAS_AUX              0x40
++#define RADIO_2056_RX_MIXA_BIAS_MAIN             0x41
++#define RADIO_2056_RX_MIXA_BIAS_MISC             0x42
++#define RADIO_2056_RX_MIXA_MAST_BIAS             0x43
++#define RADIO_2056_RX_MIXG_MASTER                0x44
++#define RADIO_2056_RX_MIXG_VCM                   0x45
++#define RADIO_2056_RX_MIXG_CTRLPTAT              0x46
++#define RADIO_2056_RX_MIXG_LOB_BIAS              0x47
++#define RADIO_2056_RX_MIXG_CORE_IDAC             0x48
++#define RADIO_2056_RX_MIXG_CMFB_IDAC             0x49
++#define RADIO_2056_RX_MIXG_BIAS_AUX              0x4a
++#define RADIO_2056_RX_MIXG_BIAS_MAIN             0x4b
++#define RADIO_2056_RX_MIXG_BIAS_MISC             0x4c
++#define RADIO_2056_RX_MIXG_MAST_BIAS             0x4d
++#define RADIO_2056_RX_TIA_MASTER                 0x4e
++#define RADIO_2056_RX_TIA_IOPAMP                 0x4f
++#define RADIO_2056_RX_TIA_QOPAMP                 0x50
++#define RADIO_2056_RX_TIA_IMISC                  0x51
++#define RADIO_2056_RX_TIA_QMISC                  0x52
++#define RADIO_2056_RX_TIA_GAIN                   0x53
++#define RADIO_2056_RX_TIA_SPARE1                 0x54
++#define RADIO_2056_RX_TIA_SPARE2                 0x55
++#define RADIO_2056_RX_BB_LPF_MASTER              0x56
++#define RADIO_2056_RX_AACI_MASTER                0x57
++#define RADIO_2056_RX_RXLPF_IDAC                 0x58
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ       0x59
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ      0x5a
++#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL        0x5b
++#define RADIO_2056_RX_RXLPF_OUTVCM               0x5c
++#define RADIO_2056_RX_RXLPF_INVCM_BODY           0x5d
++#define RADIO_2056_RX_RXLPF_CC_OP                0x5e
++#define RADIO_2056_RX_RXLPF_GAIN                 0x5f
++#define RADIO_2056_RX_RXLPF_Q_BW                 0x60
++#define RADIO_2056_RX_RXLPF_HP_CORNER_BW         0x61
++#define RADIO_2056_RX_RXLPF_RCCAL_HPC            0x62
++#define RADIO_2056_RX_RXHPF_OFF0                 0x63
++#define RADIO_2056_RX_RXHPF_OFF1                 0x64
++#define RADIO_2056_RX_RXHPF_OFF2                 0x65
++#define RADIO_2056_RX_RXHPF_OFF3                 0x66
++#define RADIO_2056_RX_RXHPF_OFF4                 0x67
++#define RADIO_2056_RX_RXHPF_OFF5                 0x68
++#define RADIO_2056_RX_RXHPF_OFF6                 0x69
++#define RADIO_2056_RX_RXHPF_OFF7                 0x6a
++#define RADIO_2056_RX_RXLPF_RCCAL_LPC            0x6b
++#define RADIO_2056_RX_RXLPF_OFF_0                0x6c
++#define RADIO_2056_RX_RXLPF_OFF_1                0x6d
++#define RADIO_2056_RX_RXLPF_OFF_2                0x6e
++#define RADIO_2056_RX_RXLPF_OFF_3                0x6f
++#define RADIO_2056_RX_RXLPF_OFF_4                0x70
++#define RADIO_2056_RX_UNUSED                     0x71
++#define RADIO_2056_RX_VGA_MASTER                 0x72
++#define RADIO_2056_RX_VGA_BIAS                   0x73
++#define RADIO_2056_RX_VGA_BIAS_DCCANCEL          0x74
++#define RADIO_2056_RX_VGA_GAIN                   0x75
++#define RADIO_2056_RX_VGA_HP_CORNER_BW           0x76
++#define RADIO_2056_RX_VGABUF_BIAS                0x77
++#define RADIO_2056_RX_VGABUF_GAIN_BW             0x78
++#define RADIO_2056_RX_TXFBMIX_A                  0x79
++#define RADIO_2056_RX_TXFBMIX_G                  0x7a
++#define RADIO_2056_RX_RXSPARE1                   0x7b
++#define RADIO_2056_RX_RXSPARE2                   0x7c
++#define RADIO_2056_RX_RXSPARE3                   0x7d
++#define RADIO_2056_RX_RXSPARE4                   0x7e
++#define RADIO_2056_RX_RXSPARE5                   0x7f
++#define RADIO_2056_RX_RXSPARE6                   0x80
++#define RADIO_2056_RX_RXSPARE7                   0x81
++#define RADIO_2056_RX_RXSPARE8                   0x82
++#define RADIO_2056_RX_RXSPARE9                   0x83
++#define RADIO_2056_RX_RXSPARE10                  0x84
++#define RADIO_2056_RX_RXSPARE11                  0x85
++#define RADIO_2056_RX_RXSPARE12                  0x86
++#define RADIO_2056_RX_RXSPARE13                  0x87
++#define RADIO_2056_RX_RXSPARE14                  0x88
++#define RADIO_2056_RX_RXSPARE15                  0x89
++#define RADIO_2056_RX_RXSPARE16                  0x8a
++#define RADIO_2056_RX_STATUS_LNAA_GAIN           0x8b
++#define RADIO_2056_RX_STATUS_LNAG_GAIN           0x8c
++#define RADIO_2056_RX_STATUS_MIXTIA_GAIN         0x8d
++#define RADIO_2056_RX_STATUS_RXLPF_GAIN          0x8e
++#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN        0x8f
++#define RADIO_2056_RX_STATUS_RXLPF_Q             0x90
++#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW        0x91
++#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC       0x92
++#define RADIO_2056_RX_STATUS_RXLPF_RC            0x93
++#define RADIO_2056_RX_STATUS_HPC_RC              0x94
++
++#define RADIO_2056_LNA1_A_PU		0x01
++#define RADIO_2056_LNA2_A_PU		0x02
++#define RADIO_2056_LNA1_G_PU		0x01
++#define RADIO_2056_LNA2_G_PU		0x02
++#define RADIO_2056_MIXA_PU_I		0x01
++#define RADIO_2056_MIXA_PU_Q		0x02
++#define RADIO_2056_MIXA_PU_GM		0x10
++#define RADIO_2056_MIXG_PU_I		0x01
++#define RADIO_2056_MIXG_PU_Q		0x02
++#define RADIO_2056_MIXG_PU_GM		0x10
++#define RADIO_2056_TIA_PU			0x01
++#define RADIO_2056_BB_LPF_PU		0x20
++#define RADIO_2056_W1_PU			0x02
++#define RADIO_2056_W2_PU			0x04
++#define RADIO_2056_NB_PU			0x08
++#define RADIO_2056_RSSI_W1_SEL		0x02
++#define RADIO_2056_RSSI_W2_SEL		0x04
++#define RADIO_2056_RSSI_NB_SEL		0x08
++#define RADIO_2056_VCM_MASK			0x1c
++#define RADIO_2056_RSSI_VCM_SHIFT	0x02
++
++#define RADIO_2057_DACBUF_VINCM_CORE0            0x0
++#define RADIO_2057_IDCODE                        0x1
++#define RADIO_2057_RCCAL_MASTER                  0x2
++#define RADIO_2057_RCCAL_CAP_SIZE                0x3
++#define RADIO_2057_RCAL_CONFIG                   0x4
++#define RADIO_2057_GPAIO_CONFIG                  0x5
++#define RADIO_2057_GPAIO_SEL1                    0x6
++#define RADIO_2057_GPAIO_SEL0                    0x7
++#define RADIO_2057_CLPO_CONFIG                   0x8
++#define RADIO_2057_BANDGAP_CONFIG                0x9
++#define RADIO_2057_BANDGAP_RCAL_TRIM             0xa
++#define RADIO_2057_AFEREG_CONFIG                 0xb
++#define RADIO_2057_TEMPSENSE_CONFIG              0xc
++#define RADIO_2057_XTAL_CONFIG1                  0xd
++#define RADIO_2057_XTAL_ICORE_SIZE               0xe
++#define RADIO_2057_XTAL_BUF_SIZE                 0xf
++#define RADIO_2057_XTAL_PULLCAP_SIZE             0x10
++#define RADIO_2057_RFPLL_MASTER                  0x11
++#define RADIO_2057_VCOMONITOR_VTH_L              0x12
++#define RADIO_2057_VCOMONITOR_VTH_H              0x13
++#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
++#define RADIO_2057_VCO_VARCSIZE_IDAC             0x15
++#define RADIO_2057_VCOCAL_COUNTVAL0              0x16
++#define RADIO_2057_VCOCAL_COUNTVAL1              0x17
++#define RADIO_2057_VCOCAL_INTCLK_COUNT           0x18
++#define RADIO_2057_VCOCAL_MASTER                 0x19
++#define RADIO_2057_VCOCAL_NUMCAPCHANGE           0x1a
++#define RADIO_2057_VCOCAL_WINSIZE                0x1b
++#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH    0x1c
++#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP  0x1d
++#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP   0x1e
++#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP  0x1f
++#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1      0x20
++#define RADIO_2057_VCO_FORCECAP0                 0x21
++#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
++#define RADIO_2057_RFPLL_PFD_RESET_PW            0x23
++#define RADIO_2057_RFPLL_LOOPFILTER_R2           0x24
++#define RADIO_2057_RFPLL_LOOPFILTER_R1           0x25
++#define RADIO_2057_RFPLL_LOOPFILTER_C3           0x26
++#define RADIO_2057_RFPLL_LOOPFILTER_C2           0x27
++#define RADIO_2057_RFPLL_LOOPFILTER_C1           0x28
++#define RADIO_2057_CP_KPD_IDAC                   0x29
++#define RADIO_2057_RFPLL_IDACS                   0x2a
++#define RADIO_2057_RFPLL_MISC_EN                 0x2b
++#define RADIO_2057_RFPLL_MMD0                    0x2c
++#define RADIO_2057_RFPLL_MMD1                    0x2d
++#define RADIO_2057_RFPLL_MISC_CAL_RESETN         0x2e
++#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES  0x2f
++#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE     0x30
++#define RADIO_2057_VCOCAL_READCAP0               0x31
++#define RADIO_2057_VCOCAL_READCAP1               0x32
++#define RADIO_2057_VCOCAL_STATUS                 0x33
++#define RADIO_2057_LOGEN_PUS                     0x34
++#define RADIO_2057_LOGEN_PTAT_RESETS             0x35
++#define RADIO_2057_VCOBUF_IDACS                  0x36
++#define RADIO_2057_VCOBUF_TUNE                   0x37
++#define RADIO_2057_CMOSBUF_TX2GQ_IDACS           0x38
++#define RADIO_2057_CMOSBUF_TX2GI_IDACS           0x39
++#define RADIO_2057_CMOSBUF_TX5GQ_IDACS           0x3a
++#define RADIO_2057_CMOSBUF_TX5GI_IDACS           0x3b
++#define RADIO_2057_CMOSBUF_RX2GQ_IDACS           0x3c
++#define RADIO_2057_CMOSBUF_RX2GI_IDACS           0x3d
++#define RADIO_2057_CMOSBUF_RX5GQ_IDACS           0x3e
++#define RADIO_2057_CMOSBUF_RX5GI_IDACS           0x3f
++#define RADIO_2057_LOGEN_MX2G_IDACS              0x40
++#define RADIO_2057_LOGEN_MX2G_TUNE               0x41
++#define RADIO_2057_LOGEN_MX5G_IDACS              0x42
++#define RADIO_2057_LOGEN_MX5G_TUNE               0x43
++#define RADIO_2057_LOGEN_MX5G_RCCR               0x44
++#define RADIO_2057_LOGEN_INDBUF2G_IDAC           0x45
++#define RADIO_2057_LOGEN_INDBUF2G_IBOOST         0x46
++#define RADIO_2057_LOGEN_INDBUF2G_TUNE           0x47
++#define RADIO_2057_LOGEN_INDBUF5G_IDAC           0x48
++#define RADIO_2057_LOGEN_INDBUF5G_IBOOST         0x49
++#define RADIO_2057_LOGEN_INDBUF5G_TUNE           0x4a
++#define RADIO_2057_CMOSBUF_TX_RCCR               0x4b
++#define RADIO_2057_CMOSBUF_RX_RCCR               0x4c
++#define RADIO_2057_LOGEN_SEL_PKDET               0x4d
++#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT          0x4e
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE0         0x4f
++#define RADIO_2057_TXGM_TXRF_PUS_CORE0           0x50
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE0         0x51
++#define RADIO_2057_TXGM_GAIN_CORE0               0x56
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0        0x57
++#define RADIO_2057_PAD2G_PTATS_CORE0             0x58
++#define RADIO_2057_PAD2G_IDACS_CORE0             0x59
++#define RADIO_2057_PAD2G_BOOST_PU_CORE0          0x5a
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0        0x5b
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0   0x5c
++#define RADIO_2057_TXMIX2G_LODC_CORE0            0x5d
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE0          0x5e
++#define RADIO_2057_IPA2G_GAIN_CORE0              0x5f
++#define RADIO_2057_TSSI2G_SPARE1_CORE0           0x60
++#define RADIO_2057_TSSI2G_SPARE2_CORE0           0x61
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0  0x62
++#define RADIO_2057_IPA2G_IMAIN_CORE0             0x63
++#define RADIO_2057_IPA2G_CASCONV_CORE0           0x64
++#define RADIO_2057_IPA2G_CASCOFFV_CORE0          0x65
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0       0x66
++#define RADIO_2057_TX5G_PKDET_CORE0              0x69
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0      0x6a
++#define RADIO_2057_PAD5G_PTATS1_CORE0            0x6b
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0      0x6c
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0     0x6d
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0       0x6e
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
++#define RADIO_2057_PGA_BOOST_TUNE_CORE0          0x70
++#define RADIO_2057_PGA_GAIN_CORE0                0x71
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0      0x73
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0     0x74
++#define RADIO_2057_IPA5G_IAUX_CORE0              0x75
++#define RADIO_2057_IPA5G_GAIN_CORE0              0x76
++#define RADIO_2057_TSSI5G_SPARE1_CORE0           0x77
++#define RADIO_2057_TSSI5G_SPARE2_CORE0           0x78
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0       0x79
++#define RADIO_2057_IPA5G_PTAT_CORE0              0x7a
++#define RADIO_2057_IPA5G_IMAIN_CORE0             0x7b
++#define RADIO_2057_IPA5G_CASCONV_CORE0           0x7c
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0       0x7d
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0     0x80
++#define RADIO_2057_TR2G_CONFIG1_CORE0_NU         0x81
++#define RADIO_2057_TR2G_CONFIG2_CORE0_NU         0x82
++#define RADIO_2057_LNA5G_RFEN_CORE0              0x83
++#define RADIO_2057_TR5G_CONFIG2_CORE0_NU         0x84
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0      0x85
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0  0x87
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0   0x88
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0      0x89
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0      0x8a
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE0          0x8b
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0      0x8c
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0        0x8e
++#define RADIO_2057_TIA_CONFIG_CORE0              0x8f
++#define RADIO_2057_TIA_IQGAIN_CORE0              0x90
++#define RADIO_2057_TIA_IBIAS2_CORE0              0x91
++#define RADIO_2057_TIA_IBIAS1_CORE0              0x92
++#define RADIO_2057_TIA_SPARE_Q_CORE0             0x93
++#define RADIO_2057_TIA_SPARE_I_CORE0             0x94
++#define RADIO_2057_RXMIX2G_PUS_CORE0             0x95
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE0         0x96
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE0         0x97
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0       0x98
++#define RADIO_2057_LNA2G_GAIN_CORE0              0x99
++#define RADIO_2057_LNA2G_TUNE_CORE0              0x9a
++#define RADIO_2057_RXMIX5G_PUS_CORE0             0x9b
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE0         0x9c
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE0         0x9d
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0       0x9e
++#define RADIO_2057_LNA5G_GAIN_CORE0              0x9f
++#define RADIO_2057_LNA5G_TUNE_CORE0              0xa0
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0    0xa1
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE0        0xa2
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0       0xa3
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
++#define RADIO_2057_TXBUF_VINCM_CORE0             0xa5
++#define RADIO_2057_TXBUF_IDACS_CORE0             0xa6
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0       0xa7
++#define RADIO_2057_RXBB_CC_CORE0                 0xa8
++#define RADIO_2057_RXBB_SPARE3_CORE0             0xa9
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE0          0xaa
++#define RADIO_2057_LPF_IDACS_CORE0               0xab
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0  0xac
++#define RADIO_2057_TXBUF_GAIN_CORE0              0xad
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0   0xae
++#define RADIO_2057_RXBUF_DEGEN_CORE0             0xaf
++#define RADIO_2057_RXBB_SPARE2_CORE0             0xb0
++#define RADIO_2057_RXBB_SPARE1_CORE0             0xb1
++#define RADIO_2057_RSSI_MASTER_CORE0             0xb2
++#define RADIO_2057_W2_MASTER_CORE0               0xb3
++#define RADIO_2057_NB_MASTER_CORE0               0xb4
++#define RADIO_2057_W2_IDACS0_Q_CORE0             0xb5
++#define RADIO_2057_W2_IDACS1_Q_CORE0             0xb6
++#define RADIO_2057_W2_IDACS0_I_CORE0             0xb7
++#define RADIO_2057_W2_IDACS1_I_CORE0             0xb8
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0  0xb9
++#define RADIO_2057_NB_IDACS_Q_CORE0              0xba
++#define RADIO_2057_NB_IDACS_I_CORE0              0xbb
++#define RADIO_2057_BACKUP4_CORE0                 0xc1
++#define RADIO_2057_BACKUP3_CORE0                 0xc2
++#define RADIO_2057_BACKUP2_CORE0                 0xc3
++#define RADIO_2057_BACKUP1_CORE0                 0xc4
++#define RADIO_2057_SPARE16_CORE0                 0xc5
++#define RADIO_2057_SPARE15_CORE0                 0xc6
++#define RADIO_2057_SPARE14_CORE0                 0xc7
++#define RADIO_2057_SPARE13_CORE0                 0xc8
++#define RADIO_2057_SPARE12_CORE0                 0xc9
++#define RADIO_2057_SPARE11_CORE0                 0xca
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE0        0xcb
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE0        0xcc
++#define RADIO_2057_IQTEST_SEL_PU                 0xcd
++#define RADIO_2057_XTAL_CONFIG2                  0xce
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE0         0xcf
++#define RADIO_2057_TXLPF_RCCAL_CORE0             0xd0
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
++#define RADIO_2057_LPF_GAIN_CORE0                0xd2
++#define RADIO_2057_DACBUF_IDACS_BW_CORE0         0xd3
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE1         0xd4
++#define RADIO_2057_TXGM_TXRF_PUS_CORE1           0xd5
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE1         0xd6
++#define RADIO_2057_TXGM_GAIN_CORE1               0xdb
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1        0xdc
++#define RADIO_2057_PAD2G_PTATS_CORE1             0xdd
++#define RADIO_2057_PAD2G_IDACS_CORE1             0xde
++#define RADIO_2057_PAD2G_BOOST_PU_CORE1          0xdf
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1        0xe0
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1   0xe1
++#define RADIO_2057_TXMIX2G_LODC_CORE1            0xe2
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE1          0xe3
++#define RADIO_2057_IPA2G_GAIN_CORE1              0xe4
++#define RADIO_2057_TSSI2G_SPARE1_CORE1           0xe5
++#define RADIO_2057_TSSI2G_SPARE2_CORE1           0xe6
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1  0xe7
++#define RADIO_2057_IPA2G_IMAIN_CORE1             0xe8
++#define RADIO_2057_IPA2G_CASCONV_CORE1           0xe9
++#define RADIO_2057_IPA2G_CASCOFFV_CORE1          0xea
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1       0xeb
++#define RADIO_2057_TX5G_PKDET_CORE1              0xee
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1      0xef
++#define RADIO_2057_PAD5G_PTATS1_CORE1            0xf0
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1      0xf1
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1     0xf2
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1       0xf3
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
++#define RADIO_2057_PGA_BOOST_TUNE_CORE1          0xf5
++#define RADIO_2057_PGA_GAIN_CORE1                0xf6
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1      0xf8
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1     0xf9
++#define RADIO_2057_IPA5G_IAUX_CORE1              0xfa
++#define RADIO_2057_IPA5G_GAIN_CORE1              0xfb
++#define RADIO_2057_TSSI5G_SPARE1_CORE1           0xfc
++#define RADIO_2057_TSSI5G_SPARE2_CORE1           0xfd
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1       0xfe
++#define RADIO_2057_IPA5G_PTAT_CORE1              0xff
++#define RADIO_2057_IPA5G_IMAIN_CORE1             0x100
++#define RADIO_2057_IPA5G_CASCONV_CORE1           0x101
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1       0x102
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1     0x105
++#define RADIO_2057_TR2G_CONFIG1_CORE1_NU         0x106
++#define RADIO_2057_TR2G_CONFIG2_CORE1_NU         0x107
++#define RADIO_2057_LNA5G_RFEN_CORE1              0x108
++#define RADIO_2057_TR5G_CONFIG2_CORE1_NU         0x109
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1      0x10a
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1  0x10c
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1   0x10d
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1      0x10e
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1      0x10f
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE1          0x110
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1      0x111
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1        0x113
++#define RADIO_2057_TIA_CONFIG_CORE1              0x114
++#define RADIO_2057_TIA_IQGAIN_CORE1              0x115
++#define RADIO_2057_TIA_IBIAS2_CORE1              0x116
++#define RADIO_2057_TIA_IBIAS1_CORE1              0x117
++#define RADIO_2057_TIA_SPARE_Q_CORE1             0x118
++#define RADIO_2057_TIA_SPARE_I_CORE1             0x119
++#define RADIO_2057_RXMIX2G_PUS_CORE1             0x11a
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE1         0x11b
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE1         0x11c
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1       0x11d
++#define RADIO_2057_LNA2G_GAIN_CORE1              0x11e
++#define RADIO_2057_LNA2G_TUNE_CORE1              0x11f
++#define RADIO_2057_RXMIX5G_PUS_CORE1             0x120
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE1         0x121
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE1         0x122
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1       0x123
++#define RADIO_2057_LNA5G_GAIN_CORE1              0x124
++#define RADIO_2057_LNA5G_TUNE_CORE1              0x125
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1    0x126
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE1        0x127
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1       0x128
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
++#define RADIO_2057_TXBUF_VINCM_CORE1             0x12a
++#define RADIO_2057_TXBUF_IDACS_CORE1             0x12b
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1       0x12c
++#define RADIO_2057_RXBB_CC_CORE1                 0x12d
++#define RADIO_2057_RXBB_SPARE3_CORE1             0x12e
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE1          0x12f
++#define RADIO_2057_LPF_IDACS_CORE1               0x130
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1  0x131
++#define RADIO_2057_TXBUF_GAIN_CORE1              0x132
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1   0x133
++#define RADIO_2057_RXBUF_DEGEN_CORE1             0x134
++#define RADIO_2057_RXBB_SPARE2_CORE1             0x135
++#define RADIO_2057_RXBB_SPARE1_CORE1             0x136
++#define RADIO_2057_RSSI_MASTER_CORE1             0x137
++#define RADIO_2057_W2_MASTER_CORE1               0x138
++#define RADIO_2057_NB_MASTER_CORE1               0x139
++#define RADIO_2057_W2_IDACS0_Q_CORE1             0x13a
++#define RADIO_2057_W2_IDACS1_Q_CORE1             0x13b
++#define RADIO_2057_W2_IDACS0_I_CORE1             0x13c
++#define RADIO_2057_W2_IDACS1_I_CORE1             0x13d
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1  0x13e
++#define RADIO_2057_NB_IDACS_Q_CORE1              0x13f
++#define RADIO_2057_NB_IDACS_I_CORE1              0x140
++#define RADIO_2057_BACKUP4_CORE1                 0x146
++#define RADIO_2057_BACKUP3_CORE1                 0x147
++#define RADIO_2057_BACKUP2_CORE1                 0x148
++#define RADIO_2057_BACKUP1_CORE1                 0x149
++#define RADIO_2057_SPARE16_CORE1                 0x14a
++#define RADIO_2057_SPARE15_CORE1                 0x14b
++#define RADIO_2057_SPARE14_CORE1                 0x14c
++#define RADIO_2057_SPARE13_CORE1                 0x14d
++#define RADIO_2057_SPARE12_CORE1                 0x14e
++#define RADIO_2057_SPARE11_CORE1                 0x14f
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE1        0x150
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE1        0x151
++#define RADIO_2057_SPARE8_CORE1                  0x152
++#define RADIO_2057_SPARE7_CORE1                  0x153
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE1         0x154
++#define RADIO_2057_TXLPF_RCCAL_CORE1             0x155
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
++#define RADIO_2057_LPF_GAIN_CORE1                0x157
++#define RADIO_2057_DACBUF_IDACS_BW_CORE1         0x158
++#define RADIO_2057_DACBUF_VINCM_CORE1            0x159
++#define RADIO_2057_RCCAL_START_R1_Q1_P1          0x15a
++#define RADIO_2057_RCCAL_X1                      0x15b
++#define RADIO_2057_RCCAL_TRC0                    0x15c
++#define RADIO_2057_RCCAL_TRC1                    0x15d
++#define RADIO_2057_RCCAL_DONE_OSCCAP             0x15e
++#define RADIO_2057_RCCAL_N0_0                    0x15f
++#define RADIO_2057_RCCAL_N0_1                    0x160
++#define RADIO_2057_RCCAL_N1_0                    0x161
++#define RADIO_2057_RCCAL_N1_1                    0x162
++#define RADIO_2057_RCAL_STATUS                   0x163
++#define RADIO_2057_XTALPUOVR_PINCTRL             0x164
++#define RADIO_2057_OVR_REG0                      0x165
++#define RADIO_2057_OVR_REG1                      0x166
++#define RADIO_2057_OVR_REG2                      0x167
++#define RADIO_2057_OVR_REG3                      0x168
++#define RADIO_2057_OVR_REG4                      0x169
++#define RADIO_2057_RCCAL_SCAP_VAL                0x16a
++#define RADIO_2057_RCCAL_BCAP_VAL                0x16b
++#define RADIO_2057_RCCAL_HPC_VAL                 0x16c
++#define RADIO_2057_RCCAL_OVERRIDES               0x16d
++#define RADIO_2057_TX0_IQCAL_GAIN_BW             0x170
++#define RADIO_2057_TX0_LOFT_FINE_I               0x171
++#define RADIO_2057_TX0_LOFT_FINE_Q               0x172
++#define RADIO_2057_TX0_LOFT_COARSE_I             0x173
++#define RADIO_2057_TX0_LOFT_COARSE_Q             0x174
++#define RADIO_2057_TX0_TX_SSI_MASTER             0x175
++#define RADIO_2057_TX0_IQCAL_VCM_HG              0x176
++#define RADIO_2057_TX0_IQCAL_IDAC                0x177
++#define RADIO_2057_TX0_TSSI_VCM                  0x178
++#define RADIO_2057_TX0_TX_SSI_MUX                0x179
++#define RADIO_2057_TX0_TSSIA                     0x17a
++#define RADIO_2057_TX0_TSSIG                     0x17b
++#define RADIO_2057_TX0_TSSI_MISC1                0x17c
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN       0x17d
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP       0x17e
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN       0x17f
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP       0x180
++#define RADIO_2057_TX1_IQCAL_GAIN_BW             0x190
++#define RADIO_2057_TX1_LOFT_FINE_I               0x191
++#define RADIO_2057_TX1_LOFT_FINE_Q               0x192
++#define RADIO_2057_TX1_LOFT_COARSE_I             0x193
++#define RADIO_2057_TX1_LOFT_COARSE_Q             0x194
++#define RADIO_2057_TX1_TX_SSI_MASTER             0x195
++#define RADIO_2057_TX1_IQCAL_VCM_HG              0x196
++#define RADIO_2057_TX1_IQCAL_IDAC                0x197
++#define RADIO_2057_TX1_TSSI_VCM                  0x198
++#define RADIO_2057_TX1_TX_SSI_MUX                0x199
++#define RADIO_2057_TX1_TSSIA                     0x19a
++#define RADIO_2057_TX1_TSSIG                     0x19b
++#define RADIO_2057_TX1_TSSI_MISC1                0x19c
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN       0x19d
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP       0x19e
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN       0x19f
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP       0x1a0
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0      0x1a1
++#define RADIO_2057_AFE_SET_VCM_I_CORE0           0x1a2
++#define RADIO_2057_AFE_SET_VCM_Q_CORE0           0x1a3
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0    0x1a4
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE0        0x1a5
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0        0x1a6
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1      0x1a7
++#define RADIO_2057_AFE_SET_VCM_I_CORE1           0x1a8
++#define RADIO_2057_AFE_SET_VCM_Q_CORE1           0x1a9
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1    0x1aa
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE1        0x1ab
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1        0x1ac
++
++#define RADIO_2057v7_DACBUF_VINCM_CORE0          0x1ad
++#define RADIO_2057v7_RCCAL_MASTER                0x1ae
++#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU       0x1af
++#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU       0x1b0
++#define RADIO_2057v7_LOGEN_PUS1                  0x1b1
++#define RADIO_2057v7_OVR_REG5                    0x1b2
++#define RADIO_2057v7_OVR_REG6                    0x1b3
++#define RADIO_2057v7_OVR_REG7                    0x1b4
++#define RADIO_2057v7_OVR_REG8                    0x1b5
++#define RADIO_2057v7_OVR_REG9                    0x1b6
++#define RADIO_2057v7_OVR_REG10                   0x1b7
++#define RADIO_2057v7_OVR_REG11                   0x1b8
++#define RADIO_2057v7_OVR_REG12                   0x1b9
++#define RADIO_2057v7_OVR_REG13                   0x1ba
++#define RADIO_2057v7_OVR_REG14                   0x1bb
++#define RADIO_2057v7_OVR_REG15                   0x1bc
++#define RADIO_2057v7_OVR_REG16                   0x1bd
++#define RADIO_2057v7_OVR_REG1                    0x1be
++#define RADIO_2057v7_OVR_REG18                   0x1bf
++#define RADIO_2057v7_OVR_REG19                   0x1c0
++#define RADIO_2057v7_OVR_REG20                   0x1c1
++#define RADIO_2057v7_OVR_REG21                   0x1c2
++#define RADIO_2057v7_OVR_REG2                    0x1c3
++#define RADIO_2057v7_OVR_REG23                   0x1c4
++#define RADIO_2057v7_OVR_REG24                   0x1c5
++#define RADIO_2057v7_OVR_REG25                   0x1c6
++#define RADIO_2057v7_OVR_REG26                   0x1c7
++#define RADIO_2057v7_OVR_REG27                   0x1c8
++#define RADIO_2057v7_OVR_REG28                   0x1c9
++#define RADIO_2057v7_IQTEST_SEL_PU2              0x1ca
++
++#define RADIO_2057_VCM_MASK			 0x7
++
++#endif				/* _BRCM_PHY_RADIO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+new file mode 100644
+index 0000000..a97c3a7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define NPHY_TBL_ID_GAIN1		0
++#define NPHY_TBL_ID_GAIN2		1
++#define NPHY_TBL_ID_GAINBITS1		2
++#define NPHY_TBL_ID_GAINBITS2		3
++#define NPHY_TBL_ID_GAINLIMIT		4
++#define NPHY_TBL_ID_WRSSIGainLimit	5
++#define NPHY_TBL_ID_RFSEQ		7
++#define NPHY_TBL_ID_AFECTRL		8
++#define NPHY_TBL_ID_ANTSWCTRLLUT	9
++#define NPHY_TBL_ID_IQLOCAL		15
++#define NPHY_TBL_ID_NOISEVAR		16
++#define NPHY_TBL_ID_SAMPLEPLAY		17
++#define NPHY_TBL_ID_CORE1TXPWRCTL	26
++#define NPHY_TBL_ID_CORE2TXPWRCTL	27
++#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL	30
++
++#define NPHY_TBL_ID_EPSILONTBL0   31
++#define NPHY_TBL_ID_SCALARTBL0    32
++#define NPHY_TBL_ID_EPSILONTBL1   33
++#define NPHY_TBL_ID_SCALARTBL1    34
++
++#define	NPHY_TO_BPHY_OFF	0xc00
++
++#define NPHY_BandControl_currentBand			0x0001
++#define RFCC_CHIP0_PU			0x0400
++#define RFCC_POR_FORCE			0x0040
++#define RFCC_OE_POR_FORCE		0x0080
++#define NPHY_RfctrlIntc_override_OFF			0
++#define NPHY_RfctrlIntc_override_TRSW			1
++#define NPHY_RfctrlIntc_override_PA				2
++#define NPHY_RfctrlIntc_override_EXT_LNA_PU		3
++#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN	4
++#define RIFS_ENABLE			0x80
++#define BPHY_BAND_SEL_UP20		0x10
++#define NPHY_MLenable			0x02
++
++#define NPHY_RfseqMode_CoreActv_override 0x0001
++#define NPHY_RfseqMode_Trigger_override	0x0002
++#define NPHY_RfseqCoreActv_TxRxChain0	(0x11)
++#define NPHY_RfseqCoreActv_TxRxChain1	(0x22)
++
++#define NPHY_RfseqTrigger_rx2tx		0x0001
++#define NPHY_RfseqTrigger_tx2rx		0x0002
++#define NPHY_RfseqTrigger_updategainh	0x0004
++#define NPHY_RfseqTrigger_updategainl	0x0008
++#define NPHY_RfseqTrigger_updategainu	0x0010
++#define NPHY_RfseqTrigger_reset2rx	0x0020
++#define NPHY_RfseqStatus_rx2tx		0x0001
++#define NPHY_RfseqStatus_tx2rx		0x0002
++#define NPHY_RfseqStatus_updategainh	0x0004
++#define NPHY_RfseqStatus_updategainl	0x0008
++#define NPHY_RfseqStatus_updategainu	0x0010
++#define NPHY_RfseqStatus_reset2rx	0x0020
++#define NPHY_ClassifierCtrl_cck_en	0x1
++#define NPHY_ClassifierCtrl_ofdm_en	0x2
++#define NPHY_ClassifierCtrl_waited_en	0x4
++#define NPHY_IQFlip_ADC1		0x0001
++#define NPHY_IQFlip_ADC2		0x0010
++#define NPHY_sampleCmd_STOP		0x0002
++
++#define RX_GF_OR_MM			0x0004
++#define RX_GF_MM_AUTO			0x0100
++
++#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN	0x8000
++
++#define NPHY_IqestCmd_iqstart		0x1
++#define NPHY_IqestCmd_iqMode		0x2
++
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init		0x40
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7	0x19
++
++#define PRIM_SEL_UP20		0x8000
++
++#define NPHY_RFSEQ_RX2TX		0x0
++#define NPHY_RFSEQ_TX2RX		0x1
++#define NPHY_RFSEQ_RESET2RX		0x2
++#define NPHY_RFSEQ_UPDATEGAINH		0x3
++#define NPHY_RFSEQ_UPDATEGAINL		0x4
++#define NPHY_RFSEQ_UPDATEGAINU		0x5
++
++#define NPHY_RFSEQ_CMD_NOP		0x0
++#define NPHY_RFSEQ_CMD_RXG_FBW		0x1
++#define NPHY_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_RFSEQ_CMD_EXT_PA		0x3
++#define NPHY_RFSEQ_CMD_RXPD_TXPD	0x4
++#define NPHY_RFSEQ_CMD_TX_GAIN		0x5
++#define NPHY_RFSEQ_CMD_RX_GAIN		0x6
++#define NPHY_RFSEQ_CMD_SET_HPF_BW	0x7
++#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_RFSEQ_CMD_END		0xf
++
++#define NPHY_REV3_RFSEQ_CMD_NOP		0x0
++#define NPHY_REV3_RFSEQ_CMD_RXG_FBW	0x1
++#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU	0x3
++#define NPHY_REV3_RFSEQ_CMD_EXT_PA	0x4
++#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD	0x5
++#define NPHY_REV3_RFSEQ_CMD_TX_GAIN	0x6
++#define NPHY_REV3_RFSEQ_CMD_RX_GAIN	0x7
++#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC	0x9
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC	0xa
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC	0xb
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC	0xc
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC	0xd
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC	0xe
++#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS	0xf
++#define NPHY_REV3_RFSEQ_CMD_END		0x1f
++
++#define NPHY_RSSI_SEL_W1		0x0
++#define NPHY_RSSI_SEL_W2		0x1
++#define NPHY_RSSI_SEL_NB		0x2
++#define NPHY_RSSI_SEL_IQ		0x3
++#define NPHY_RSSI_SEL_TSSI_2G		0x4
++#define NPHY_RSSI_SEL_TSSI_5G		0x5
++#define NPHY_RSSI_SEL_TBD		0x6
++
++#define NPHY_RAIL_I			0x0
++#define NPHY_RAIL_Q			0x1
++
++#define NPHY_FORCESIG_DECODEGATEDCLKS	0x8
++
++#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
++#define NPHY_REV7_RfctrlOverride_cmd_rx_pu   0x1
++#define NPHY_REV7_RfctrlOverride_cmd_tx_pu   0x2
++#define NPHY_REV7_RfctrlOverride_cmd_rxgain  0x3
++#define NPHY_REV7_RfctrlOverride_cmd_txgain  0x4
++
++#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
++#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK  0x0ff00
++#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
++
++#define NPHY_REV7_TXGAINCODE_TGAIN_MASK     0x7fff
++#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK   0x8000
++#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
++
++#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
++#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
++#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
++
++#define NPHY_IqestIqAccLo(core)  ((core == 0) ? 0x12c : 0x134)
++
++#define NPHY_IqestIqAccHi(core)  ((core == 0) ? 0x12d : 0x135)
++
++#define NPHY_IqestipwrAccLo(core)  ((core == 0) ? 0x12e : 0x136)
++
++#define NPHY_IqestipwrAccHi(core)  ((core == 0) ? 0x12f : 0x137)
++
++#define NPHY_IqestqpwrAccLo(core)  ((core == 0) ? 0x130 : 0x138)
++
++#define NPHY_IqestqpwrAccHi(core)  ((core == 0) ? 0x131 : 0x139)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+new file mode 100644
+index 0000000..622c01c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+@@ -0,0 +1,3250 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_lcn.h"
++
++static const u32 dot11lcn_gain_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00001193,
++	0x00005193,
++	0x00009193,
++	0x0000d193,
++	0x00011193,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00005153,
++	0x00009153,
++	0x0000d153,
++	0x00011153,
++	0x00015153,
++	0x00019153,
++	0x0001d153,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 dot11lcn_gain_tbl_rev1[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00001197,
++	0x00005197,
++	0x00009197,
++	0x0000d197,
++	0x00011197,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00005157,
++	0x00009157,
++	0x0000d157,
++	0x00011157,
++	0x00015157,
++	0x00019157,
++	0x0001d157,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0405,
++	0x0406,
++	0x0407,
++	0x0408,
++	0x0409,
++	0x040a,
++	0x058b,
++	0x058c,
++	0x058d,
++	0x058e,
++	0x058f,
++	0x0090,
++	0x0091,
++	0x0092,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x019e,
++	0x019f,
++	0x01a0,
++	0x01a1,
++	0x01a2,
++	0x01a3,
++	0x01a4,
++	0x01a5,
++	0x0000,
++};
++
++static const u32 dot11lcn_gain_idx_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x50000000,
++	0x00000000,
++	0x60000000,
++	0x00000000,
++	0x70000000,
++	0x00000000,
++	0x80000000,
++	0x00000000,
++	0x90000000,
++	0x00000008,
++	0xa0000000,
++	0x00000008,
++	0xb0000000,
++	0x00000008,
++	0xc0000000,
++	0x00000008,
++	0xd0000000,
++	0x00000008,
++	0xe0000000,
++	0x00000008,
++	0xf0000000,
++	0x00000008,
++	0x00000000,
++	0x00000009,
++	0x10000000,
++	0x00000009,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0xe0000000,
++	0x00000019,
++	0xf0000000,
++	0x00000019,
++	0x00000000,
++	0x0000001a,
++	0x10000000,
++	0x0000001a,
++	0x20000000,
++	0x0000001a,
++	0x30000000,
++	0x0000001a,
++	0x40000000,
++	0x0000001a,
++	0x50000000,
++	0x00000002,
++	0x60000000,
++	0x00000002,
++	0x70000000,
++	0x00000002,
++	0x80000000,
++	0x00000002,
++	0x90000000,
++	0x00000002,
++	0xa0000000,
++	0x00000002,
++	0xb0000000,
++	0x00000002,
++	0xc0000000,
++	0x0000000a,
++	0xd0000000,
++	0x0000000a,
++	0xe0000000,
++	0x0000000a,
++	0xf0000000,
++	0x0000000a,
++	0x00000000,
++	0x0000000b,
++	0x10000000,
++	0x0000000b,
++	0x20000000,
++	0x0000000b,
++	0x30000000,
++	0x0000000b,
++	0x40000000,
++	0x0000000b,
++	0x50000000,
++	0x0000001b,
++	0x60000000,
++	0x0000001b,
++	0x70000000,
++	0x0000001b,
++	0x80000000,
++	0x0000001b,
++	0x90000000,
++	0x0000001b,
++	0xa0000000,
++	0x0000001b,
++	0xb0000000,
++	0x0000001b,
++	0xc0000000,
++	0x0000001b,
++	0xd0000000,
++	0x0000001b,
++	0xe0000000,
++	0x0000001b,
++	0xf0000000,
++	0x0000001b,
++	0x00000000,
++	0x0000001c,
++	0x10000000,
++	0x0000001c,
++	0x20000000,
++	0x0000001c,
++	0x30000000,
++	0x0000001c,
++	0x40000000,
++	0x0000001c,
++	0x50000000,
++	0x0000001c,
++	0x60000000,
++	0x0000001c,
++	0x70000000,
++	0x0000001c,
++	0x80000000,
++	0x0000001c,
++	0x90000000,
++	0x0000001c,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0080,
++	0x0081,
++	0x0100,
++	0x0101,
++	0x0180,
++	0x0181,
++	0x0182,
++	0x0183,
++	0x0184,
++	0x0185,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0285,
++	0x0289,
++	0x028a,
++	0x028b,
++	0x028c,
++	0x028d,
++	0x028e,
++	0x028f,
++	0x0290,
++	0x0291,
++	0x0292,
++	0x0293,
++	0x0294,
++	0x0295,
++	0x0296,
++	0x0297,
++	0x0298,
++	0x0299,
++	0x029a,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_2G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0xb0000000,
++	0x00000029,
++	0xc0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x00000049,
++	0x00000089,
++	0x000000c9,
++	0x0000004b,
++	0x0000008b,
++	0x000000cb,
++	0x000000cf,
++	0x0000010f,
++	0x0000050f,
++	0x0000090f,
++	0x0000094f,
++	0x00000d4f,
++	0x0000114f,
++	0x0000118f,
++	0x0000518f,
++	0x0000918f,
++	0x0000d18f,
++	0x0001118f,
++	0x0001518f,
++	0x0001918f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000003,
++	0x00000007,
++	0x0000000b,
++	0x0000000f,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x0000010f,
++	0x0000014f,
++	0x0000018f,
++	0x0000058f,
++	0x0000098f,
++	0x00000d8f,
++	0x00008000,
++	0x00008004,
++	0x00008008,
++	0x00008001,
++	0x00008005,
++	0x00008009,
++	0x0000800d,
++	0x00008003,
++	0x00008007,
++	0x0000800b,
++	0x0000800f,
++	0x0000804f,
++	0x0000808f,
++	0x000080cf,
++	0x0000810f,
++	0x0000814f,
++	0x0000818f,
++	0x0000858f,
++	0x0000898f,
++	0x00008d8f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0483,
++	0x0484,
++	0x0485,
++	0x0486,
++	0x0583,
++	0x0584,
++	0x0585,
++	0x0587,
++	0x0588,
++	0x0589,
++	0x058a,
++	0x0687,
++	0x0688,
++	0x0689,
++	0x068a,
++	0x068b,
++	0x068c,
++	0x068d,
++	0x068e,
++	0x068f,
++	0x0690,
++	0x0691,
++	0x0692,
++	0x0693,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0f,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x10000000,
++	0x00000040,
++	0x20000000,
++	0x00000040,
++	0x30000000,
++	0x00000040,
++	0x40000000,
++	0x00000040,
++	0x30000000,
++	0x00000048,
++	0x40000000,
++	0x00000048,
++	0x50000000,
++	0x00000048,
++	0x60000000,
++	0x00000048,
++	0x30000000,
++	0x00000058,
++	0x40000000,
++	0x00000058,
++	0x50000000,
++	0x00000058,
++	0x70000000,
++	0x00000058,
++	0x80000000,
++	0x00000058,
++	0x90000000,
++	0x00000058,
++	0xa0000000,
++	0x00000058,
++	0x70000000,
++	0x00000068,
++	0x80000000,
++	0x00000068,
++	0x90000000,
++	0x00000068,
++	0xa0000000,
++	0x00000068,
++	0xb0000000,
++	0x00000068,
++	0xc0000000,
++	0x00000068,
++	0xd0000000,
++	0x00000068,
++	0xe0000000,
++	0x00000068,
++	0xf0000000,
++	0x00000068,
++	0x00000000,
++	0x00000069,
++	0x10000000,
++	0x00000069,
++	0x20000000,
++	0x00000069,
++	0x30000000,
++	0x00000069,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x50000000,
++	0x00000041,
++	0x60000000,
++	0x00000041,
++	0x70000000,
++	0x00000041,
++	0x80000000,
++	0x00000041,
++	0x70000000,
++	0x00000049,
++	0x80000000,
++	0x00000049,
++	0x90000000,
++	0x00000049,
++	0xa0000000,
++	0x00000049,
++	0x70000000,
++	0x00000059,
++	0x80000000,
++	0x00000059,
++	0x90000000,
++	0x00000059,
++	0xb0000000,
++	0x00000059,
++	0xc0000000,
++	0x00000059,
++	0xd0000000,
++	0x00000059,
++	0xe0000000,
++	0x00000059,
++	0xb0000000,
++	0x00000069,
++	0xc0000000,
++	0x00000069,
++	0xd0000000,
++	0x00000069,
++	0xe0000000,
++	0x00000069,
++	0xf0000000,
++	0x00000069,
++	0x00000000,
++	0x0000006a,
++	0x10000000,
++	0x0000006a,
++	0x20000000,
++	0x0000006a,
++	0x30000000,
++	0x0000006a,
++	0x40000000,
++	0x0000006a,
++	0x50000000,
++	0x0000006a,
++	0x60000000,
++	0x0000006a,
++	0x70000000,
++	0x0000006a,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0002,
++	0x0003,
++	0x0004,
++	0x0083,
++	0x0084,
++	0x0085,
++	0x0086,
++	0x0087,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0189,
++	0x018a,
++	0x018b,
++	0x018c,
++	0x018d,
++	0x018e,
++	0x018f,
++	0x0190,
++	0x0191,
++	0x0192,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x0000
++};
++
++static const u32 dot11lcn_gain_val_tbl_5G[] = {
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf6,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x06,
++	0x0a,
++	0x10,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_5G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x30000000,
++	0x00000008,
++	0x40000000,
++	0x00000008,
++	0x50000000,
++	0x00000008,
++	0x60000000,
++	0x00000008,
++	0x70000000,
++	0x00000008,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x90000000,
++	0x00000018,
++	0xa0000000,
++	0x00000018,
++	0xb0000000,
++	0x00000018,
++	0xc0000000,
++	0x00000018,
++	0xd0000000,
++	0x00000018,
++	0xe0000000,
++	0x00000018,
++	0xf0000000,
++	0x00000018,
++	0x00000000,
++	0x00000019,
++	0x10000000,
++	0x00000019,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_5G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000080,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000011,
++	0x00000015,
++	0x00000055,
++	0x00000095,
++	0x00000017,
++	0x0000001b,
++	0x0000005b,
++	0x0000009b,
++	0x000000db,
++	0x0000011b,
++	0x0000015b,
++	0x0000019b,
++	0x0000059b,
++	0x0000099b,
++	0x00000d9b,
++	0x0000119b,
++	0x0000519b,
++	0x0000919b,
++	0x0000d19b,
++	0x0001119b,
++	0x0001519b,
++	0x0001919b,
++	0x0001d19b,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++static const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
++	{&dot11lcn_gain_tbl_rev1,
++	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_2G,
++	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_2G,
++	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
++
++static const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++};
++
++static const u16 dot11lcn_noise_scale_tbl_rev0[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
++	0x000141f8,
++	0x000021f8,
++	0x000021fb,
++	0x000041fb,
++	0x0001fe4b,
++	0x0000217b,
++	0x00002133,
++	0x000040eb,
++	0x0001fea3,
++	0x0000024b,
++};
++
++static const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
++	0x00100001,
++	0x00200010,
++	0x00300001,
++	0x00400010,
++	0x00500022,
++	0x00600122,
++	0x00700222,
++	0x00800322,
++	0x00900422,
++	0x00a00522,
++	0x00b00622,
++	0x00c00722,
++	0x00d00822,
++	0x00f00922,
++	0x00100a22,
++	0x00200b22,
++	0x00300c22,
++	0x00400d22,
++	0x00500e22,
++	0x00600f22,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++};
++
++static const u8 dot11lcn_nf_table_rev0[] = {
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++};
++
++static const u8 dot11lcn_gain_val_tbl_rev0[] = {
++	0x09,
++	0x0f,
++	0x14,
++	0x18,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0xeb,
++	0x00,
++	0x00,
++};
++
++static const u8 dot11lcn_spur_tbl_rev0[] = {
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++};
++
++static const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
++	0x001a,
++	0x0034,
++	0x004e,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x00ea,
++	0x0104,
++	0x0034,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x004e,
++	0x009c,
++	0x00ea,
++	0x0138,
++	0x01d4,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x0068,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x0270,
++	0x0340,
++	0x03a8,
++	0x0410,
++	0x0018,
++	0x009c,
++	0x00d0,
++	0x0104,
++	0x00ea,
++	0x0138,
++	0x0186,
++	0x00d0,
++	0x0104,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x016c,
++	0x01a0,
++	0x0138,
++	0x0186,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x0222,
++	0x0270,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x0138,
++	0x016c,
++	0x01a0,
++	0x01d4,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x0208,
++	0x023c,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x01d4,
++	0x0222,
++	0x0270,
++	0x02be,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x030c,
++	0x035a,
++	0x0036,
++	0x006c,
++	0x00a2,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x01e6,
++	0x021c,
++	0x006c,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x00a2,
++	0x0144,
++	0x01e6,
++	0x0288,
++	0x03cc,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x00d8,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x0510,
++	0x06c0,
++	0x0798,
++	0x0870,
++	0x0018,
++	0x0144,
++	0x01b0,
++	0x021c,
++	0x01e6,
++	0x0288,
++	0x032a,
++	0x01b0,
++	0x021c,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x02f4,
++	0x0360,
++	0x0288,
++	0x032a,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x046e,
++	0x0510,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x0288,
++	0x02f4,
++	0x0360,
++	0x03cc,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x0438,
++	0x04a4,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x03cc,
++	0x046e,
++	0x0510,
++	0x05b2,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x0654,
++	0x06f6,
++};
++
++static const u16 dot11lcn_iq_local_tbl_rev0[] = {
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x4000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++};
++
++const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
++	{&dot11lcn_min_sig_sq_tbl_rev0,
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
++	,
++	{&dot11lcn_noise_scale_tbl_rev0,
++	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
++	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
++	,
++	{&dot11lcn_fltr_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
++	,
++	{&dot11lcn_ps_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_sw_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
++	,
++	{&dot11lcn_nf_table_rev0,
++	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
++	 0, 8}
++	,
++	{&dot11lcn_gain_val_tbl_rev0,
++	 sizeof(dot11lcn_gain_val_tbl_rev0) /
++	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
++	,
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_spur_tbl_rev0,
++	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
++	 0, 8}
++	,
++	{&dot11lcn_unsup_mcs_tbl_rev0,
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
++	,
++	{&dot11lcn_iq_local_tbl_rev0,
++	 sizeof(dot11lcn_iq_local_tbl_rev0) /
++	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
++	,
++	{&dot11lcn_papd_compdelta_tbl_rev0,
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
++	&dot11lcn_sw_ctrl_tbl_4313_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
++	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
++};
++
++const u32 dot11lcnphytbl_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
++
++const struct lcnphy_tx_gain_tbl_entry
++dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
++	{3, 0, 31, 0, 72},
++	{3, 0, 31, 0, 70},
++	{3, 0, 31, 0, 68},
++	{3, 0, 30, 0, 67},
++	{3, 0, 29, 0, 68},
++	{3, 0, 28, 0, 68},
++	{3, 0, 27, 0, 69},
++	{3, 0, 26, 0, 70},
++	{3, 0, 25, 0, 70},
++	{3, 0, 24, 0, 71},
++	{3, 0, 23, 0, 72},
++	{3, 0, 23, 0, 70},
++	{3, 0, 22, 0, 71},
++	{3, 0, 21, 0, 72},
++	{3, 0, 21, 0, 70},
++	{3, 0, 21, 0, 68},
++	{3, 0, 21, 0, 66},
++	{3, 0, 21, 0, 64},
++	{3, 0, 21, 0, 63},
++	{3, 0, 20, 0, 64},
++	{3, 0, 19, 0, 65},
++	{3, 0, 19, 0, 64},
++	{3, 0, 18, 0, 65},
++	{3, 0, 18, 0, 64},
++	{3, 0, 17, 0, 65},
++	{3, 0, 17, 0, 64},
++	{3, 0, 16, 0, 65},
++	{3, 0, 16, 0, 64},
++	{3, 0, 16, 0, 62},
++	{3, 0, 16, 0, 60},
++	{3, 0, 16, 0, 58},
++	{3, 0, 15, 0, 61},
++	{3, 0, 15, 0, 59},
++	{3, 0, 14, 0, 61},
++	{3, 0, 14, 0, 60},
++	{3, 0, 14, 0, 58},
++	{3, 0, 13, 0, 60},
++	{3, 0, 13, 0, 59},
++	{3, 0, 12, 0, 62},
++	{3, 0, 12, 0, 60},
++	{3, 0, 12, 0, 58},
++	{3, 0, 11, 0, 62},
++	{3, 0, 11, 0, 60},
++	{3, 0, 11, 0, 59},
++	{3, 0, 11, 0, 57},
++	{3, 0, 10, 0, 61},
++	{3, 0, 10, 0, 59},
++	{3, 0, 10, 0, 57},
++	{3, 0, 9, 0, 62},
++	{3, 0, 9, 0, 60},
++	{3, 0, 9, 0, 58},
++	{3, 0, 9, 0, 57},
++	{3, 0, 8, 0, 62},
++	{3, 0, 8, 0, 60},
++	{3, 0, 8, 0, 58},
++	{3, 0, 8, 0, 57},
++	{3, 0, 8, 0, 55},
++	{3, 0, 7, 0, 61},
++	{3, 0, 7, 0, 60},
++	{3, 0, 7, 0, 58},
++	{3, 0, 7, 0, 56},
++	{3, 0, 7, 0, 55},
++	{3, 0, 6, 0, 62},
++	{3, 0, 6, 0, 60},
++	{3, 0, 6, 0, 58},
++	{3, 0, 6, 0, 57},
++	{3, 0, 6, 0, 55},
++	{3, 0, 6, 0, 54},
++	{3, 0, 6, 0, 52},
++	{3, 0, 5, 0, 61},
++	{3, 0, 5, 0, 59},
++	{3, 0, 5, 0, 57},
++	{3, 0, 5, 0, 56},
++	{3, 0, 5, 0, 54},
++	{3, 0, 5, 0, 53},
++	{3, 0, 5, 0, 51},
++	{3, 0, 4, 0, 62},
++	{3, 0, 4, 0, 60},
++	{3, 0, 4, 0, 58},
++	{3, 0, 4, 0, 57},
++	{3, 0, 4, 0, 55},
++	{3, 0, 4, 0, 54},
++	{3, 0, 4, 0, 52},
++	{3, 0, 4, 0, 51},
++	{3, 0, 4, 0, 49},
++	{3, 0, 4, 0, 48},
++	{3, 0, 4, 0, 46},
++	{3, 0, 3, 0, 60},
++	{3, 0, 3, 0, 58},
++	{3, 0, 3, 0, 57},
++	{3, 0, 3, 0, 55},
++	{3, 0, 3, 0, 54},
++	{3, 0, 3, 0, 52},
++	{3, 0, 3, 0, 51},
++	{3, 0, 3, 0, 49},
++	{3, 0, 3, 0, 48},
++	{3, 0, 3, 0, 46},
++	{3, 0, 3, 0, 45},
++	{3, 0, 3, 0, 44},
++	{3, 0, 3, 0, 43},
++	{3, 0, 3, 0, 41},
++	{3, 0, 2, 0, 61},
++	{3, 0, 2, 0, 59},
++	{3, 0, 2, 0, 57},
++	{3, 0, 2, 0, 56},
++	{3, 0, 2, 0, 54},
++	{3, 0, 2, 0, 53},
++	{3, 0, 2, 0, 51},
++	{3, 0, 2, 0, 50},
++	{3, 0, 2, 0, 48},
++	{3, 0, 2, 0, 47},
++	{3, 0, 2, 0, 46},
++	{3, 0, 2, 0, 44},
++	{3, 0, 2, 0, 43},
++	{3, 0, 2, 0, 42},
++	{3, 0, 2, 0, 41},
++	{3, 0, 2, 0, 39},
++	{3, 0, 2, 0, 38},
++	{3, 0, 2, 0, 37},
++	{3, 0, 2, 0, 36},
++	{3, 0, 2, 0, 35},
++	{3, 0, 2, 0, 34},
++	{3, 0, 2, 0, 33},
++	{3, 0, 2, 0, 32},
++	{3, 0, 1, 0, 63},
++	{3, 0, 1, 0, 61},
++	{3, 0, 1, 0, 59},
++	{3, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
++	{7, 0, 31, 0, 72},
++	{7, 0, 31, 0, 70},
++	{7, 0, 31, 0, 68},
++	{7, 0, 30, 0, 67},
++	{7, 0, 29, 0, 68},
++	{7, 0, 28, 0, 68},
++	{7, 0, 27, 0, 69},
++	{7, 0, 26, 0, 70},
++	{7, 0, 25, 0, 70},
++	{7, 0, 24, 0, 71},
++	{7, 0, 23, 0, 72},
++	{7, 0, 23, 0, 70},
++	{7, 0, 22, 0, 71},
++	{7, 0, 21, 0, 72},
++	{7, 0, 21, 0, 70},
++	{7, 0, 21, 0, 68},
++	{7, 0, 21, 0, 66},
++	{7, 0, 21, 0, 64},
++	{7, 0, 21, 0, 63},
++	{7, 0, 20, 0, 64},
++	{7, 0, 19, 0, 65},
++	{7, 0, 19, 0, 64},
++	{7, 0, 18, 0, 65},
++	{7, 0, 18, 0, 64},
++	{7, 0, 17, 0, 65},
++	{7, 0, 17, 0, 64},
++	{7, 0, 16, 0, 65},
++	{7, 0, 16, 0, 64},
++	{7, 0, 16, 0, 62},
++	{7, 0, 16, 0, 60},
++	{7, 0, 16, 0, 58},
++	{7, 0, 15, 0, 61},
++	{7, 0, 15, 0, 59},
++	{7, 0, 14, 0, 61},
++	{7, 0, 14, 0, 60},
++	{7, 0, 14, 0, 58},
++	{7, 0, 13, 0, 60},
++	{7, 0, 13, 0, 59},
++	{7, 0, 12, 0, 62},
++	{7, 0, 12, 0, 60},
++	{7, 0, 12, 0, 58},
++	{7, 0, 11, 0, 62},
++	{7, 0, 11, 0, 60},
++	{7, 0, 11, 0, 59},
++	{7, 0, 11, 0, 57},
++	{7, 0, 10, 0, 61},
++	{7, 0, 10, 0, 59},
++	{7, 0, 10, 0, 57},
++	{7, 0, 9, 0, 62},
++	{7, 0, 9, 0, 60},
++	{7, 0, 9, 0, 58},
++	{7, 0, 9, 0, 57},
++	{7, 0, 8, 0, 62},
++	{7, 0, 8, 0, 60},
++	{7, 0, 8, 0, 58},
++	{7, 0, 8, 0, 57},
++	{7, 0, 8, 0, 55},
++	{7, 0, 7, 0, 61},
++	{7, 0, 7, 0, 60},
++	{7, 0, 7, 0, 58},
++	{7, 0, 7, 0, 56},
++	{7, 0, 7, 0, 55},
++	{7, 0, 6, 0, 62},
++	{7, 0, 6, 0, 60},
++	{7, 0, 6, 0, 58},
++	{7, 0, 6, 0, 57},
++	{7, 0, 6, 0, 55},
++	{7, 0, 6, 0, 54},
++	{7, 0, 6, 0, 52},
++	{7, 0, 5, 0, 61},
++	{7, 0, 5, 0, 59},
++	{7, 0, 5, 0, 57},
++	{7, 0, 5, 0, 56},
++	{7, 0, 5, 0, 54},
++	{7, 0, 5, 0, 53},
++	{7, 0, 5, 0, 51},
++	{7, 0, 4, 0, 62},
++	{7, 0, 4, 0, 60},
++	{7, 0, 4, 0, 58},
++	{7, 0, 4, 0, 57},
++	{7, 0, 4, 0, 55},
++	{7, 0, 4, 0, 54},
++	{7, 0, 4, 0, 52},
++	{7, 0, 4, 0, 51},
++	{7, 0, 4, 0, 49},
++	{7, 0, 4, 0, 48},
++	{7, 0, 4, 0, 46},
++	{7, 0, 3, 0, 60},
++	{7, 0, 3, 0, 58},
++	{7, 0, 3, 0, 57},
++	{7, 0, 3, 0, 55},
++	{7, 0, 3, 0, 54},
++	{7, 0, 3, 0, 52},
++	{7, 0, 3, 0, 51},
++	{7, 0, 3, 0, 49},
++	{7, 0, 3, 0, 48},
++	{7, 0, 3, 0, 46},
++	{7, 0, 3, 0, 45},
++	{7, 0, 3, 0, 44},
++	{7, 0, 3, 0, 43},
++	{7, 0, 3, 0, 41},
++	{7, 0, 2, 0, 61},
++	{7, 0, 2, 0, 59},
++	{7, 0, 2, 0, 57},
++	{7, 0, 2, 0, 56},
++	{7, 0, 2, 0, 54},
++	{7, 0, 2, 0, 53},
++	{7, 0, 2, 0, 51},
++	{7, 0, 2, 0, 50},
++	{7, 0, 2, 0, 48},
++	{7, 0, 2, 0, 47},
++	{7, 0, 2, 0, 46},
++	{7, 0, 2, 0, 44},
++	{7, 0, 2, 0, 43},
++	{7, 0, 2, 0, 42},
++	{7, 0, 2, 0, 41},
++	{7, 0, 2, 0, 39},
++	{7, 0, 2, 0, 38},
++	{7, 0, 2, 0, 37},
++	{7, 0, 2, 0, 36},
++	{7, 0, 2, 0, 35},
++	{7, 0, 2, 0, 34},
++	{7, 0, 2, 0, 33},
++	{7, 0, 2, 0, 32},
++	{7, 0, 1, 0, 63},
++	{7, 0, 1, 0, 61},
++	{7, 0, 1, 0, 59},
++	{7, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
++	{255, 255, 0xf0, 0, 152},
++	{255, 255, 0xf0, 0, 147},
++	{255, 255, 0xf0, 0, 143},
++	{255, 255, 0xf0, 0, 139},
++	{255, 255, 0xf0, 0, 135},
++	{255, 255, 0xf0, 0, 131},
++	{255, 255, 0xf0, 0, 128},
++	{255, 255, 0xf0, 0, 124},
++	{255, 255, 0xf0, 0, 121},
++	{255, 255, 0xf0, 0, 117},
++	{255, 255, 0xf0, 0, 114},
++	{255, 255, 0xf0, 0, 111},
++	{255, 255, 0xf0, 0, 107},
++	{255, 255, 0xf0, 0, 104},
++	{255, 255, 0xf0, 0, 101},
++	{255, 255, 0xf0, 0, 99},
++	{255, 255, 0xf0, 0, 96},
++	{255, 255, 0xf0, 0, 93},
++	{255, 255, 0xf0, 0, 90},
++	{255, 255, 0xf0, 0, 88},
++	{255, 255, 0xf0, 0, 85},
++	{255, 255, 0xf0, 0, 83},
++	{255, 255, 0xf0, 0, 81},
++	{255, 255, 0xf0, 0, 78},
++	{255, 255, 0xf0, 0, 76},
++	{255, 255, 0xf0, 0, 74},
++	{255, 255, 0xf0, 0, 72},
++	{255, 255, 0xf0, 0, 70},
++	{255, 255, 0xf0, 0, 68},
++	{255, 255, 0xf0, 0, 66},
++	{255, 255, 0xf0, 0, 64},
++	{255, 248, 0xf0, 0, 64},
++	{255, 241, 0xf0, 0, 64},
++	{255, 251, 0xe0, 0, 64},
++	{255, 244, 0xe0, 0, 64},
++	{255, 254, 0xd0, 0, 64},
++	{255, 246, 0xd0, 0, 64},
++	{255, 239, 0xd0, 0, 64},
++	{255, 249, 0xc0, 0, 64},
++	{255, 242, 0xc0, 0, 64},
++	{255, 255, 0xb0, 0, 64},
++	{255, 248, 0xb0, 0, 64},
++	{255, 241, 0xb0, 0, 64},
++	{255, 254, 0xa0, 0, 64},
++	{255, 246, 0xa0, 0, 64},
++	{255, 239, 0xa0, 0, 64},
++	{255, 255, 0x90, 0, 64},
++	{255, 248, 0x90, 0, 64},
++	{255, 241, 0x90, 0, 64},
++	{255, 234, 0x90, 0, 64},
++	{255, 255, 0x80, 0, 64},
++	{255, 248, 0x80, 0, 64},
++	{255, 241, 0x80, 0, 64},
++	{255, 234, 0x80, 0, 64},
++	{255, 255, 0x70, 0, 64},
++	{255, 248, 0x70, 0, 64},
++	{255, 241, 0x70, 0, 64},
++	{255, 234, 0x70, 0, 64},
++	{255, 227, 0x70, 0, 64},
++	{255, 221, 0x70, 0, 64},
++	{255, 215, 0x70, 0, 64},
++	{255, 208, 0x70, 0, 64},
++	{255, 203, 0x70, 0, 64},
++	{255, 197, 0x70, 0, 64},
++	{255, 255, 0x60, 0, 64},
++	{255, 248, 0x60, 0, 64},
++	{255, 241, 0x60, 0, 64},
++	{255, 234, 0x60, 0, 64},
++	{255, 227, 0x60, 0, 64},
++	{255, 221, 0x60, 0, 64},
++	{255, 255, 0x50, 0, 64},
++	{255, 248, 0x50, 0, 64},
++	{255, 241, 0x50, 0, 64},
++	{255, 234, 0x50, 0, 64},
++	{255, 227, 0x50, 0, 64},
++	{255, 221, 0x50, 0, 64},
++	{255, 215, 0x50, 0, 64},
++	{255, 208, 0x50, 0, 64},
++	{255, 255, 0x40, 0, 64},
++	{255, 248, 0x40, 0, 64},
++	{255, 241, 0x40, 0, 64},
++	{255, 234, 0x40, 0, 64},
++	{255, 227, 0x40, 0, 64},
++	{255, 221, 0x40, 0, 64},
++	{255, 215, 0x40, 0, 64},
++	{255, 208, 0x40, 0, 64},
++	{255, 203, 0x40, 0, 64},
++	{255, 197, 0x40, 0, 64},
++	{255, 255, 0x30, 0, 64},
++	{255, 248, 0x30, 0, 64},
++	{255, 241, 0x30, 0, 64},
++	{255, 234, 0x30, 0, 64},
++	{255, 227, 0x30, 0, 64},
++	{255, 221, 0x30, 0, 64},
++	{255, 215, 0x30, 0, 64},
++	{255, 208, 0x30, 0, 64},
++	{255, 203, 0x30, 0, 64},
++	{255, 197, 0x30, 0, 64},
++	{255, 191, 0x30, 0, 64},
++	{255, 186, 0x30, 0, 64},
++	{255, 181, 0x30, 0, 64},
++	{255, 175, 0x30, 0, 64},
++	{255, 255, 0x20, 0, 64},
++	{255, 248, 0x20, 0, 64},
++	{255, 241, 0x20, 0, 64},
++	{255, 234, 0x20, 0, 64},
++	{255, 227, 0x20, 0, 64},
++	{255, 221, 0x20, 0, 64},
++	{255, 215, 0x20, 0, 64},
++	{255, 208, 0x20, 0, 64},
++	{255, 203, 0x20, 0, 64},
++	{255, 197, 0x20, 0, 64},
++	{255, 191, 0x20, 0, 64},
++	{255, 186, 0x20, 0, 64},
++	{255, 181, 0x20, 0, 64},
++	{255, 175, 0x20, 0, 64},
++	{255, 170, 0x20, 0, 64},
++	{255, 166, 0x20, 0, 64},
++	{255, 161, 0x20, 0, 64},
++	{255, 156, 0x20, 0, 64},
++	{255, 152, 0x20, 0, 64},
++	{255, 148, 0x20, 0, 64},
++	{255, 143, 0x20, 0, 64},
++	{255, 139, 0x20, 0, 64},
++	{255, 135, 0x20, 0, 64},
++	{255, 132, 0x20, 0, 64},
++	{255, 255, 0x10, 0, 64},
++	{255, 248, 0x10, 0, 64},
++};
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+new file mode 100644
+index 0000000..5f75e16
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
++extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
++
++extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
++extern const u32 dot11lcnphytbl_info_sz_rev0;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
++
++struct lcnphy_tx_gain_tbl_entry {
++	unsigned char gm;
++	unsigned char pga;
++	unsigned char pad;
++	unsigned char dac;
++	unsigned char bb_mult;
++};
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
++
++extern const struct
++lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+new file mode 100644
+index 0000000..dbf50ef
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+@@ -0,0 +1,10630 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_n.h"
++
++static const u32 frame_struct_rev0[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u8 frame_lut_rev0[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u32 tmap_tbl_rev0[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdtrn_tbl_rev0[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++static const u32 intlv_tbl_rev0[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u16 pilot_tbl_rev0[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 pltlut_tbl_rev0[] = {
++	0x76540123,
++	0x62407351,
++	0x76543201,
++	0x76540213,
++	0x76540123,
++	0x76430521,
++};
++
++static const u32 tdi_tbl20_ant0_rev0[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev0[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev0[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev0[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 bdi_tbl_rev0[] = {
++	0x0070,
++	0x0126,
++	0x012c,
++	0x0246,
++	0x048d,
++	0x04d2,
++};
++
++static const u32 chanest_tbl_rev0[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 mcs_tbl_rev0[] = {
++	0x00,
++	0x08,
++	0x0a,
++	0x10,
++	0x12,
++	0x19,
++	0x1a,
++	0x1c,
++	0x40,
++	0x48,
++	0x4a,
++	0x50,
++	0x52,
++	0x59,
++	0x5a,
++	0x5c,
++	0x80,
++	0x88,
++	0x8a,
++	0x90,
++	0x92,
++	0x99,
++	0x9a,
++	0x9c,
++	0xc0,
++	0xc8,
++	0xca,
++	0xd0,
++	0xd2,
++	0xd9,
++	0xda,
++	0xdc,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x01,
++	0x02,
++	0x04,
++	0x08,
++	0x09,
++	0x0a,
++	0x0c,
++	0x10,
++	0x11,
++	0x12,
++	0x14,
++	0x18,
++	0x19,
++	0x1a,
++	0x1c,
++	0x20,
++	0x21,
++	0x22,
++	0x24,
++	0x40,
++	0x41,
++	0x42,
++	0x44,
++	0x48,
++	0x49,
++	0x4a,
++	0x4c,
++	0x50,
++	0x51,
++	0x52,
++	0x54,
++	0x58,
++	0x59,
++	0x5a,
++	0x5c,
++	0x60,
++	0x61,
++	0x62,
++	0x64,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 noise_var_tbl0_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 noise_var_tbl1_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u8 est_pwr_lut_core0_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 est_pwr_lut_core1_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 adj_pwr_lut_core0_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 gainctrl_lut_core1_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 iq_lut_core0_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u32 iq_lut_core1_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u16 loft_lut_core0_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++static const u16 loft_lut_core1_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++const struct phytbl_info mimophytbl_info_rev0_volatile[] = {
++	{&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
++	 16}
++	,
++	{&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
++	 20, 0, 32}
++	,
++	{&gainctrl_lut_core0_rev0,
++	 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev0,
++	 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
++	 27, 192, 32}
++	,
++
++	{&est_pwr_lut_core0_rev0,
++	 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev0,
++	 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev0,
++	 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev0,
++	 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
++	 64, 8}
++	,
++	{&iq_lut_core0_rev0,
++	 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev0,
++	 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev0,
++	 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev0,
++	 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev0[] = {
++	{&frame_struct_rev0,
++	 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
++	,
++	{&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
++	 24, 0, 8}
++	,
++	{&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
++	 0, 32}
++	,
++	{&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
++	 14, 0, 32}
++	,
++	{&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
++	 13, 0, 32}
++	,
++	{&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
++	 11, 0, 16}
++	,
++	{&tdi_tbl20_ant0_rev0,
++	 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev0,
++	 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev0,
++	 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev0,
++	 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
++	 32}
++	,
++	{&chanest_tbl_rev0,
++	 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
++	,
++	{&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0,
++	 8}
++	,
++	{&noise_var_tbl0_rev0,
++	 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
++	 32}
++	,
++	{&noise_var_tbl1_rev0,
++	 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
++	 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev0 =
++	sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
++const u32 mimophytbl_info_sz_rev0_volatile =
++	sizeof(mimophytbl_info_rev0_volatile) /
++	sizeof(mimophytbl_info_rev0_volatile[0]);
++
++static const u16 ant_swctrl_tbl_rev3[] = {
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_1[] = {
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_2[] = {
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_3[] = {
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc,
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc
++};
++
++static const u32 frame_struct_rev3[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 pilot_tbl_rev3[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 tmap_tbl_rev3[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 intlv_tbl_rev3[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u32 tdtrn_tbl_rev3[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++const u32 noise_var_tbl_rev3[] = {
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++};
++
++static const u16 mcs_tbl_rev3[] = {
++	0x0000,
++	0x0008,
++	0x000a,
++	0x0010,
++	0x0012,
++	0x0019,
++	0x001a,
++	0x001c,
++	0x0080,
++	0x0088,
++	0x008a,
++	0x0090,
++	0x0092,
++	0x0099,
++	0x009a,
++	0x009c,
++	0x0100,
++	0x0108,
++	0x010a,
++	0x0110,
++	0x0112,
++	0x0119,
++	0x011a,
++	0x011c,
++	0x0180,
++	0x0188,
++	0x018a,
++	0x0190,
++	0x0192,
++	0x0199,
++	0x019a,
++	0x019c,
++	0x0000,
++	0x0098,
++	0x00a0,
++	0x00a8,
++	0x009a,
++	0x00a2,
++	0x00aa,
++	0x0120,
++	0x0128,
++	0x0128,
++	0x0130,
++	0x0138,
++	0x0138,
++	0x0140,
++	0x0122,
++	0x012a,
++	0x012a,
++	0x0132,
++	0x013a,
++	0x013a,
++	0x0142,
++	0x01a8,
++	0x01b0,
++	0x01b8,
++	0x01b0,
++	0x01b8,
++	0x01c0,
++	0x01c8,
++	0x01c0,
++	0x01c8,
++	0x01d0,
++	0x01d0,
++	0x01d8,
++	0x01aa,
++	0x01b2,
++	0x01ba,
++	0x01b2,
++	0x01ba,
++	0x01c2,
++	0x01ca,
++	0x01c2,
++	0x01ca,
++	0x01d2,
++	0x01d2,
++	0x01da,
++	0x0001,
++	0x0002,
++	0x0004,
++	0x0009,
++	0x000c,
++	0x0011,
++	0x0014,
++	0x0018,
++	0x0020,
++	0x0021,
++	0x0022,
++	0x0024,
++	0x0081,
++	0x0082,
++	0x0084,
++	0x0089,
++	0x008c,
++	0x0091,
++	0x0094,
++	0x0098,
++	0x00a0,
++	0x00a1,
++	0x00a2,
++	0x00a4,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++};
++
++static const u32 tdi_tbl20_ant0_rev3[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev3[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev3[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev3[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 pltlut_tbl_rev3[] = {
++	0x76540213,
++	0x62407351,
++	0x76543210,
++	0x76540213,
++	0x76540213,
++	0x76430521,
++};
++
++static const u32 chanest_tbl_rev3[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 frame_lut_rev3[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u8 est_pwr_lut_core0_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 est_pwr_lut_core1_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 adj_pwr_lut_core0_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 gainctrl_lut_core1_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 iq_lut_core0_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 iq_lut_core1_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 loft_lut_core0_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 loft_lut_core1_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile[] = {
++	{&ant_swctrl_tbl_rev3,
++	 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile1[] = {
++	{&ant_swctrl_tbl_rev3_1,
++	 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile2[] = {
++	{&ant_swctrl_tbl_rev3_2,
++	 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile3[] = {
++	{&ant_swctrl_tbl_rev3_3,
++	 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev3,
++	 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++};
++
++const u32 mimophytbl_info_sz_rev3 =
++	sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
++const u32 mimophytbl_info_sz_rev3_volatile =
++	sizeof(mimophytbl_info_rev3_volatile) /
++	sizeof(mimophytbl_info_rev3_volatile[0]);
++const u32 mimophytbl_info_sz_rev3_volatile1 =
++	sizeof(mimophytbl_info_rev3_volatile1) /
++	sizeof(mimophytbl_info_rev3_volatile1[0]);
++const u32 mimophytbl_info_sz_rev3_volatile2 =
++	sizeof(mimophytbl_info_rev3_volatile2) /
++	sizeof(mimophytbl_info_rev3_volatile2[0]);
++const u32 mimophytbl_info_sz_rev3_volatile3 =
++	sizeof(mimophytbl_info_rev3_volatile3) /
++	sizeof(mimophytbl_info_rev3_volatile3[0]);
++
++static const u32 tmap_tbl_rev7[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++const u32 noise_var_tbl_rev7[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++const struct phytbl_info mimophytbl_info_rev7[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++	{&papd_comp_rfpwr_tbl_core0_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
++	,
++	{&papd_comp_rfpwr_tbl_core1_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
++	,
++	{&papd_comp_epsilon_tbl_core0_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core0_rev7,
++	 sizeof(papd_cal_scalars_tbl_core0_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
++	,
++	{&papd_comp_epsilon_tbl_core1_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core1_rev7,
++	 sizeof(papd_cal_scalars_tbl_core1_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev7 =
++	sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
++
++const struct phytbl_info mimophytbl_info_rev16[] = {
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev16 =
++	sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+new file mode 100644
+index 0000000..dc8a84e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define ANT_SWCTRL_TBL_REV3_IDX (0)
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info mimophytbl_info_rev0[],
++				mimophytbl_info_rev0_volatile[];
++
++extern const u32 mimophytbl_info_sz_rev0,
++		 mimophytbl_info_sz_rev0_volatile;
++
++extern const struct phytbl_info mimophytbl_info_rev3[],
++				mimophytbl_info_rev3_volatile[],
++				mimophytbl_info_rev3_volatile1[],
++				mimophytbl_info_rev3_volatile2[],
++				mimophytbl_info_rev3_volatile3[];
++
++extern const u32 mimophytbl_info_sz_rev3,
++		 mimophytbl_info_sz_rev3_volatile,
++		 mimophytbl_info_sz_rev3_volatile1,
++		 mimophytbl_info_sz_rev3_volatile2,
++		 mimophytbl_info_sz_rev3_volatile3;
++
++extern const u32 noise_var_tbl_rev3[];
++
++extern const struct phytbl_info mimophytbl_info_rev7[];
++
++extern const u32 mimophytbl_info_sz_rev7;
++
++extern const u32 noise_var_tbl_rev7[];
++
++extern const struct phytbl_info mimophytbl_info_rev16[];
++
++extern const u32 mimophytbl_info_sz_rev16;
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+new file mode 100644
+index 0000000..a0de5db
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * This is "two-way" interface, acting as the SHIM layer between driver
++ * and PHY layer. The driver can optionally call this translation layer
++ * to do some preprocessing, then reach PHY. On the PHY->driver direction,
++ * all calls go through this layer since PHY doesn't have access to the
++ * driver's brcms_hardware pointer.
++ */
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "main.h"
++#include "mac80211_if.h"
++#include "phy_shim.h"
++
++/* PHY SHIM module specific state */
++struct phy_shim_info {
++	struct brcms_hardware *wlc_hw;	/* pointer to main wlc_hw structure */
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_info *wl; /* pointer to os-specific private state */
++};
++
++struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++					  struct brcms_info *wl,
++					  struct brcms_c_info *wlc) {
++	struct phy_shim_info *physhim = NULL;
++
++	physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
++	if (!physhim)
++		return NULL;
++
++	physhim->wlc_hw = wlc_hw;
++	physhim->wlc = wlc;
++	physhim->wl = wl;
++
++	return physhim;
++}
++
++void wlc_phy_shim_detach(struct phy_shim_info *physhim)
++{
++	kfree(physhim);
++}
++
++struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++				     void (*fn)(struct brcms_phy *pi),
++				     void *arg, const char *name)
++{
++	return (struct wlapi_timer *)
++			brcms_init_timer(physhim->wl, (void (*)(void *))fn,
++					 arg, name);
++}
++
++void wlapi_free_timer(struct wlapi_timer *t)
++{
++	brcms_free_timer((struct brcms_timer *)t);
++}
++
++void
++wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
++{
++	brcms_add_timer((struct brcms_timer *)t, ms, periodic);
++}
++
++bool wlapi_del_timer(struct wlapi_timer *t)
++{
++	return brcms_del_timer((struct brcms_timer *)t);
++}
++
++void wlapi_intrson(struct phy_shim_info *physhim)
++{
++	brcms_intrson(physhim->wl);
++}
++
++u32 wlapi_intrsoff(struct phy_shim_info *physhim)
++{
++	return brcms_intrsoff(physhim->wl);
++}
++
++void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
++{
++	brcms_intrsrestore(physhim->wl, macintmask);
++}
++
++void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
++{
++	brcms_b_write_shm(physhim->wlc_hw, offset, v);
++}
++
++u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
++{
++	return brcms_b_read_shm(physhim->wlc_hw, offset);
++}
++
++void
++wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
++	       u16 val, int bands)
++{
++	brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
++}
++
++void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
++{
++	brcms_b_corereset(physhim->wlc_hw, flags);
++}
++
++void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
++{
++	brcms_c_suspend_mac_and_wait(physhim->wlc);
++}
++
++void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
++{
++	brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
++}
++
++void wlapi_enable_mac(struct phy_shim_info *physhim)
++{
++	brcms_c_enable_mac(physhim->wlc);
++}
++
++void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
++{
++	brcms_b_mctrl(physhim->wlc_hw, mask, val);
++}
++
++void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_phy_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
++{
++	brcms_b_bw_set(physhim->wlc_hw, bw);
++}
++
++u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
++{
++	return brcms_b_get_txant(physhim->wlc_hw);
++}
++
++void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_macphyclk_set(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
++{
++	brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
++}
++
++void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_core_phypll_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_set(physhim->wlc_hw,
++					BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void
++wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
++			      int len, void *buf)
++{
++	brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
++}
++
++u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
++{
++	return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
++}
++
++void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
++{
++}
++
++void
++wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
++		      int len, u32 sel)
++{
++	brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
++}
++
++void
++wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
++		    int l, u32 sel)
++{
++	brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+new file mode 100644
+index 0000000..2c5b66b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_shim.h: stuff defined in phy_shim.c and included only by the phy
++ */
++
++#ifndef _BRCM_PHY_SHIM_H_
++#define _BRCM_PHY_SHIM_H_
++
++#include "types.h"
++
++#define RADAR_TYPE_NONE		0	/* Radar type None */
++#define RADAR_TYPE_ETSI_1	1	/* ETSI 1 Radar type */
++#define RADAR_TYPE_ETSI_2	2	/* ETSI 2 Radar type */
++#define RADAR_TYPE_ETSI_3	3	/* ETSI 3 Radar type */
++#define RADAR_TYPE_ITU_E	4	/* ITU E Radar type */
++#define RADAR_TYPE_ITU_K	5	/* ITU K Radar type */
++#define RADAR_TYPE_UNCLASSIFIED	6	/* Unclassified Radar type  */
++#define RADAR_TYPE_BIN5		7	/* long pulse radar type */
++#define RADAR_TYPE_STG2		8	/* staggered-2 radar */
++#define RADAR_TYPE_STG3		9	/* staggered-3 radar */
++#define RADAR_TYPE_FRA		10	/* French radar */
++
++/* French radar pulse widths */
++#define FRA_T1_20MHZ	52770
++#define FRA_T2_20MHZ	61538
++#define FRA_T3_20MHZ	66002
++#define FRA_T1_40MHZ	105541
++#define FRA_T2_40MHZ	123077
++#define FRA_T3_40MHZ	132004
++#define FRA_ERR_20MHZ	60
++#define FRA_ERR_40MHZ	120
++
++#define ANTSEL_NA		0 /* No boardlevel selection available */
++#define ANTSEL_2x4		1 /* 2x4 boardlevel selection available */
++#define ANTSEL_2x3		2 /* 2x3 CB2 boardlevel selection available */
++
++/* Rx Antenna diversity control values */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0 /* default antdiv setting */
++
++#define WL_ANT_RX_MAX		2	/* max 2 receive antennas */
++#define WL_ANT_HT_RX_MAX	3	/* max 3 receive antennas/cores */
++#define WL_ANT_IDX_1		0	/* antenna index 1 */
++#define WL_ANT_IDX_2		1	/* antenna index 2 */
++
++/* values for n_preamble_type */
++#define BRCMS_N_PREAMBLE_MIXEDMODE	0
++#define BRCMS_N_PREAMBLE_GF		1
++#define BRCMS_N_PREAMBLE_GF_BRCM          2
++
++#define WL_TX_POWER_RATES_LEGACY	45
++#define WL_TX_POWER_MCS20_FIRST	        12
++#define WL_TX_POWER_MCS20_NUM	        16
++#define WL_TX_POWER_MCS40_FIRST	        28
++#define WL_TX_POWER_MCS40_NUM	        17
++
++
++#define WL_TX_POWER_RATES	       101
++#define WL_TX_POWER_CCK_FIRST	       0
++#define WL_TX_POWER_CCK_NUM	       4
++/* Index for first 20MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM_FIRST	       4
++/* Index for first 20MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM20_CDD_FIRST   12
++/* Index for first 40MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM40_SISO_FIRST  52
++/* Index for first 40MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM40_CDD_FIRST   60
++#define WL_TX_POWER_OFDM_NUM	       8
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST   20
++/* Index for first 20MHz MCS CDD rate */
++#define WL_TX_POWER_MCS20_CDD_FIRST    28
++/* Index for first 20MHz MCS STBC rate */
++#define WL_TX_POWER_MCS20_STBC_FIRST   36
++/* Index for first 20MHz MCS SDM rate */
++#define WL_TX_POWER_MCS20_SDM_FIRST    44
++/* Index for first 40MHz MCS SISO rate */
++#define WL_TX_POWER_MCS40_SISO_FIRST   68
++/* Index for first 40MHz MCS CDD rate */
++#define WL_TX_POWER_MCS40_CDD_FIRST    76
++/* Index for first 40MHz MCS STBC rate */
++#define WL_TX_POWER_MCS40_STBC_FIRST   84
++/* Index for first 40MHz MCS SDM rate */
++#define WL_TX_POWER_MCS40_SDM_FIRST    92
++#define WL_TX_POWER_MCS_1_STREAM_NUM   8
++#define WL_TX_POWER_MCS_2_STREAM_NUM   8
++/* Index for 40MHz rate MCS 32 */
++#define WL_TX_POWER_MCS_32	       100
++#define WL_TX_POWER_MCS_32_NUM	       1
++
++/* sslpnphy specifics */
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST_SSN   12
++
++/* struct tx_power::flags bits */
++#define WL_TX_POWER_F_ENABLED	1
++#define WL_TX_POWER_F_HW	2
++#define WL_TX_POWER_F_MIMO	4
++#define WL_TX_POWER_F_SISO	8
++
++/* values to force tx/rx chain */
++#define BRCMS_N_TXRX_CHAIN0		0
++#define BRCMS_N_TXRX_CHAIN1		1
++
++struct brcms_phy;
++
++extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++						 struct brcms_info *wl,
++						 struct brcms_c_info *wlc);
++extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
++
++/* PHY to WL utility functions */
++extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++					    void (*fn) (struct brcms_phy *pi),
++					    void *arg, const char *name);
++extern void wlapi_free_timer(struct wlapi_timer *t);
++extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
++extern bool wlapi_del_timer(struct wlapi_timer *t);
++extern void wlapi_intrson(struct phy_shim_info *physhim);
++extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
++extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
++			       u32 macintmask);
++
++extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
++				 u16 v);
++extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
++extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
++			   u16 mask, u16 val, int bands);
++extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
++extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
++extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
++extern void wlapi_enable_mac(struct phy_shim_info *physhim);
++extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
++			     u32 val);
++extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
++extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
++extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
++						      physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
++							physhim);
++extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
++					  int len, void *buf);
++extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
++					 u8 rate);
++extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
++extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
++				  void *buf, int, u32 sel);
++extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
++				const void *buf, int, u32);
++
++extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
++				       u32 phy_mode);
++extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
++
++#endif				/* _BRCM_PHY_SHIM_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+new file mode 100644
+index 0000000..4931d29
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+@@ -0,0 +1,375 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include "pub.h"
++#include "aiutils.h"
++#include "pmu.h"
++#include "soc.h"
++
++/*
++ * external LPO crystal frequency
++ */
++#define EXT_ILP_HZ 32768
++
++/*
++ * Duration for ILP clock frequency measurment in milliseconds
++ *
++ * remark: 1000 must be an integer multiple of this duration
++ */
++#define ILP_CALC_DUR	10
++
++/* Fields in pmucontrol */
++#define	PCTL_ILP_DIV_MASK	0xffff0000
++#define	PCTL_ILP_DIV_SHIFT	16
++#define PCTL_PLL_PLLCTL_UPD	0x00000400	/* rev 2 */
++#define PCTL_NOILP_ON_WAIT	0x00000200	/* rev 1 */
++#define	PCTL_HT_REQ_EN		0x00000100
++#define	PCTL_ALP_REQ_EN		0x00000080
++#define	PCTL_XTALFREQ_MASK	0x0000007c
++#define	PCTL_XTALFREQ_SHIFT	2
++#define	PCTL_ILP_DIV_EN		0x00000002
++#define	PCTL_LPO_SEL		0x00000001
++
++/* ILP clock */
++#define	ILP_CLOCK		32000
++
++/* ALP clock on pre-PMU chips */
++#define	ALP_CLOCK		20000000
++
++/* pmustatus */
++#define PST_EXTLPOAVAIL	0x0100
++#define PST_WDRESET	0x0080
++#define	PST_INTPEND	0x0040
++#define	PST_SBCLKST	0x0030
++#define	PST_SBCLKST_ILP	0x0010
++#define	PST_SBCLKST_ALP	0x0020
++#define	PST_SBCLKST_HT	0x0030
++#define	PST_ALPAVAIL	0x0008
++#define	PST_HTAVAIL	0x0004
++#define	PST_RESINIT	0x0003
++
++/* PMU resource bit position */
++#define PMURES_BIT(bit)	(1 << (bit))
++
++/* PMU corerev and chip specific PLL controls.
++ * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
++ * number to differentiate different PLLs controlled by the same PMU rev.
++ */
++/* pllcontrol registers:
++ * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
++ * p1div, p2div, _bypass_sdmod
++ */
++#define PMU1_PLL0_PLLCTL0		0
++#define PMU1_PLL0_PLLCTL1		1
++#define PMU1_PLL0_PLLCTL2		2
++#define PMU1_PLL0_PLLCTL3		3
++#define PMU1_PLL0_PLLCTL4		4
++#define PMU1_PLL0_PLLCTL5		5
++
++/* pmu XtalFreqRatio */
++#define	PMU_XTALFREQ_REG_ILPCTR_MASK	0x00001FFF
++#define	PMU_XTALFREQ_REG_MEASURE_MASK	0x80000000
++#define	PMU_XTALFREQ_REG_MEASURE_SHIFT	31
++
++/* 4313 resources */
++#define	RES4313_BB_PU_RSRC		0
++#define	RES4313_ILP_REQ_RSRC		1
++#define	RES4313_XTAL_PU_RSRC		2
++#define	RES4313_ALP_AVAIL_RSRC		3
++#define	RES4313_RADIO_PU_RSRC		4
++#define	RES4313_BG_PU_RSRC		5
++#define	RES4313_VREG1P4_PU_RSRC		6
++#define	RES4313_AFE_PWRSW_RSRC		7
++#define	RES4313_RX_PWRSW_RSRC		8
++#define	RES4313_TX_PWRSW_RSRC		9
++#define	RES4313_BB_PWRSW_RSRC		10
++#define	RES4313_SYNTH_PWRSW_RSRC	11
++#define	RES4313_MISC_PWRSW_RSRC		12
++#define	RES4313_BB_PLL_PWRSW_RSRC	13
++#define	RES4313_HT_AVAIL_RSRC		14
++#define	RES4313_MACPHY_CLK_AVAIL_RSRC	15
++
++/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
++static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
++{
++	u32 min_mask = 0, max_mask = 0;
++	uint rsrcs;
++
++	/* # resources */
++	rsrcs = (ai_get_pmucaps(sih) & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
++
++	/* determine min/max rsrc masks */
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		/* ??? */
++		break;
++
++	case BCM4313_CHIP_ID:
++		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
++		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
++		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
++		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
++		max_mask = 0xffff;
++		break;
++	default:
++		break;
++	}
++
++	*pmin = min_mask;
++	*pmax = max_mask;
++}
++
++void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid)
++{
++	u32 tmp = 0;
++	struct bcma_device *core;
++
++	/* switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		if (spuravoid == 1) {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11500010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000C0C06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x0F600a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x2001E920);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		} else {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11100010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000c0c06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x03000a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x200005c0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		}
++		tmp = 1 << 10;
++		break;
++
++	default:
++		/* bail out */
++		return;
++	}
++
++	bcma_set32(core, CHIPCREGOFFS(pmucontrol), tmp);
++}
++
++u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
++{
++	uint delay = PMU_MAX_TRANSITION_DLY;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		delay = 3700;
++		break;
++	default:
++		break;
++	}
++
++	return (u16) delay;
++}
++
++/* Read/write a chipcontrol reg */
++u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a regcontrol reg */
++u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a pllcontrol reg */
++u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_data),
++			 mask, val);
++}
++
++/* PMU PLL update */
++void si_pmu_pllupd(struct si_pub *sih)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pmucontrol),
++		  PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
++}
++
++/* query alp/xtal clock frequency */
++u32 si_pmu_alp_clock(struct si_pub *sih)
++{
++	u32 clock = ALP_CLOCK;
++
++	/* bail out with default */
++	if (!(ai_get_cccaps(sih) & CC_CAP_PMU))
++		return clock;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		/* always 20Mhz */
++		clock = 20000 * 1000;
++		break;
++	default:
++		break;
++	}
++
++	return clock;
++}
++
++/* initialize PMU */
++void si_pmu_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++
++	/* select chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (ai_get_pmurev(sih) == 1)
++		bcma_mask32(core, CHIPCREGOFFS(pmucontrol),
++			    ~PCTL_NOILP_ON_WAIT);
++	else if (ai_get_pmurev(sih) >= 2)
++		bcma_set32(core, CHIPCREGOFFS(pmucontrol), PCTL_NOILP_ON_WAIT);
++}
++
++/* initialize PMU resources */
++void si_pmu_res_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 min_mask = 0, max_mask = 0;
++
++	/* select to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	/* Determine min/max rsrc masks */
++	si_pmu_res_masks(sih, &min_mask, &max_mask);
++
++	/* It is required to program max_mask first and then min_mask */
++
++	/* Program max resource mask */
++
++	if (max_mask)
++		bcma_write32(core, CHIPCREGOFFS(max_res_mask), max_mask);
++
++	/* Program min resource mask */
++
++	if (min_mask)
++		bcma_write32(core, CHIPCREGOFFS(min_res_mask), min_mask);
++
++	/* Add some delay; allow resources to come up and settle. */
++	mdelay(2);
++}
++
++u32 si_pmu_measure_alpclk(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 alp_khz;
++
++	if (ai_get_pmurev(sih) < 10)
++		return 0;
++
++	/* Remember original core before switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
++		u32 ilp_ctr, alp_hz;
++
++		/*
++		 * Enable the reg to measure the freq,
++		 * in case it was disabled before
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
++			    1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
++
++		/* Delay for well over 4 ILP clocks */
++		udelay(1000);
++
++		/* Read the latched number of ALP ticks per 4 ILP ticks */
++		ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
++			  PMU_XTALFREQ_REG_ILPCTR_MASK;
++
++		/*
++		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
++		 * bit to save power
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
++
++		/* Calculate ALP frequency */
++		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
++
++		/*
++		 * Round to nearest 100KHz, and at
++		 * the same time convert to KHz
++		 */
++		alp_khz = (alp_hz + 50000) / 100000 * 100;
++	} else
++		alp_khz = 0;
++
++	return alp_khz;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+new file mode 100644
+index 0000000..3e39c5e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _BRCM_PMU_H_
++#define _BRCM_PMU_H_
++
++#include "types.h"
++
++extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
++extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
++extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_alp_clock(struct si_pub *sih);
++extern void si_pmu_pllupd(struct si_pub *sih);
++extern void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid);
++extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern void si_pmu_init(struct si_pub *sih);
++extern void si_pmu_res_init(struct si_pub *sih);
++extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
++
++#endif /* _BRCM_PMU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+new file mode 100644
+index 0000000..aa5d67f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -0,0 +1,372 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PUB_H_
++#define _BRCM_PUB_H_
++
++#include <linux/bcma/bcma.h>
++#include <brcmu_wifi.h>
++#include "types.h"
++#include "defs.h"
++
++#define	BRCMS_NUMRATES	16	/* max # of rates in a rateset */
++
++/* phy types */
++#define	PHY_TYPE_A	0	/* Phy type A */
++#define	PHY_TYPE_G	2	/* Phy type G */
++#define	PHY_TYPE_N	4	/* Phy type N */
++#define	PHY_TYPE_LP	5	/* Phy type Low Power A/B/G */
++#define	PHY_TYPE_SSN	6	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCN	8	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCNXN	9	/* Phy type 2-stream N */
++#define	PHY_TYPE_HT	7	/* Phy type 3-Stream N */
++
++/* bw */
++#define BRCMS_10_MHZ	10	/* 10Mhz nphy channel bandwidth */
++#define BRCMS_20_MHZ	20	/* 20Mhz nphy channel bandwidth */
++#define BRCMS_40_MHZ	40	/* 40Mhz nphy channel bandwidth */
++
++#define	BRCMS_RSSI_MINVAL	-200	/* Low value, e.g. for forcing roam */
++#define	BRCMS_RSSI_NO_SIGNAL	-91	/* NDIS RSSI link quality cutoffs */
++#define	BRCMS_RSSI_VERY_LOW	-80	/* Very low quality cutoffs */
++#define	BRCMS_RSSI_LOW		-70	/* Low quality cutoffs */
++#define	BRCMS_RSSI_GOOD		-68	/* Good quality cutoffs */
++#define	BRCMS_RSSI_VERY_GOOD	-58	/* Very good quality cutoffs */
++#define	BRCMS_RSSI_EXCELLENT	-57	/* Excellent quality cutoffs */
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++/* rate related definitions */
++#define	BRCMS_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
++#define	BRCMS_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
++
++/* legacy rx Antenna diversity for SISO rates */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++/* default antdiv setting */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0
++
++/* legacy rx Antenna diversity for SISO rates */
++/* Tx on antenna 0, "legacy term Main" */
++#define ANT_TX_FORCE_0		0
++/* Tx on antenna 1, "legacy term Aux" */
++#define ANT_TX_FORCE_1		1
++/* Tx on phy's last good Rx antenna */
++#define ANT_TX_LAST_RX		3
++/* driver's default tx antenna setting */
++#define ANT_TX_DEF		3
++
++/* Tx Chain values */
++/* def bitmap of txchain */
++#define TXCHAIN_DEF		0x1
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_NPHY	0x3
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_HTPHY	0x7
++/* def bitmap of rxchain */
++#define RXCHAIN_DEF		0x1
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_NPHY	0x3
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_HTPHY	0x7
++/* no antenna switch */
++#define ANTSWITCH_NONE		0
++/* antenna switch on 4321CB2, 2of3 */
++#define ANTSWITCH_TYPE_1	1
++/* antenna switch on 4321MPCI, 2of3 */
++#define ANTSWITCH_TYPE_2	2
++/* antenna switch on 4322, 2of3 */
++#define ANTSWITCH_TYPE_3	3
++
++#define RXBUFSZ		PKTBUFSZ
++
++#define MAX_STREAMS_SUPPORTED	4	/* max number of streams supported */
++
++struct brcm_rateset {
++	/* # rates in this set */
++	u32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcms_c_rateset {
++	uint count;		/* number of rates in rates[] */
++	 /* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[BRCMS_NUMRATES];
++	u8 htphy_membership;	/* HT PHY Membership */
++	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
++};
++
++/* All the HT-specific default advertised capabilities (including AMPDU)
++ * should be grouped here at one place
++ */
++#define AMPDU_DEF_MPDU_DENSITY	6	/* default mpdu density (110 ==> 4us) */
++
++/* wlc internal bss_info */
++struct brcms_bss_info {
++	u8 BSSID[ETH_ALEN];	/* network BSSID */
++	u16 flags;		/* flags for internal attributes */
++	u8 SSID_len;		/* the length of SSID */
++	u8 SSID[32];		/* SSID string */
++	s16 RSSI;		/* receive signal strength (in dBm) */
++	s16 SNR;		/* receive signal SNR in dB */
++	u16 beacon_period;	/* units are Kusec */
++	u16 chanspec;	/* Channel num, bw, ctrl_sb and band */
++	struct brcms_c_rateset rateset;	/* supported rates */
++};
++
++#define MAC80211_PROMISC_BCNS	(1 << 0)
++#define MAC80211_SCAN		(1 << 1)
++
++/*
++ * Public portion of common driver state structure.
++ * The wlc handle points at this.
++ */
++struct brcms_pub {
++	struct brcms_c_info *wlc;
++	struct ieee80211_hw *ieee_hw;
++	struct scb_ampdu *global_ampdu;
++	uint mac80211_state;
++	uint unit;		/* device instance number */
++	uint corerev;		/* core revision */
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	bool up;		/* interface up and running */
++	bool hw_off;		/* HW is off */
++	bool hw_up;		/* one time hw up/down */
++	bool _piomode;		/* true if pio mode */
++	uint _nbands;		/* # bands supported */
++	uint now;		/* # elapsed seconds */
++
++	bool delayed_down;	/* down delayed */
++	bool associated;	/* true:part of [I]BSS, false: not */
++	/* (union of stas_associated, aps_associated) */
++	bool _ampdu;		/* ampdu enabled or not */
++	u8 _n_enab;		/* bitmap of 11N + HT support */
++
++	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
++
++	int bcmerror;		/* last bcm error */
++
++	u32 radio_disabled;	/* bit vector for radio disabled reasons */
++
++	u16 boardrev;	/* version # of particular board */
++	u8 sromrev;		/* version # of the srom */
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	bool phy_11ncapable;	/* the PHY/HW is capable of 802.11N */
++
++	struct wl_cnt *_cnt;	/* low-level counters in driver */
++};
++
++enum wlc_par_id {
++	IOV_MPC = 1,
++	IOV_RTSTHRESH,
++	IOV_QTXPOWER,
++	IOV_BCN_LI_BCN		/* Beacon listen interval in # of beacons */
++};
++
++/***********************************************
++ * Feature-related macros to optimize out code *
++ * *********************************************
++ */
++
++#define ENAB_1x1	0x01
++#define ENAB_2x2	0x02
++#define ENAB_3x3	0x04
++#define ENAB_4x4	0x08
++#define SUPPORT_11N	(ENAB_1x1|ENAB_2x2)
++#define SUPPORT_HT	(ENAB_1x1|ENAB_2x2|ENAB_3x3)
++
++/* WL11N Support */
++#define AMPDU_AGG_HOST	1
++
++/* pri is priority encoded in the packet. This maps the Packet priority to
++ * enqueue precedence as defined in wlc_prec_map
++ */
++extern const u8 wlc_prio2prec_map[];
++#define BRCMS_PRIO_TO_PREC(pri)	wlc_prio2prec_map[(pri) & 7]
++
++#define	BRCMS_PREC_COUNT	16	/* Max precedence level implemented */
++
++/* Mask to describe all precedence levels */
++#define BRCMS_PREC_BMP_ALL		MAXBITVAL(BRCMS_PREC_COUNT)
++
++/*
++ * This maps priority to one precedence higher - Used by PS-Poll response
++ * packets to simulate enqueue-at-head operation, but still maintain the
++ * order on the queue
++ */
++#define BRCMS_PRIO_TO_HI_PREC(pri)	min(BRCMS_PRIO_TO_PREC(pri) + 1,\
++					    BRCMS_PREC_COUNT - 1)
++
++/* Define a bitmap of precedences comprised by each AC */
++#define BRCMS_PREC_BMP_AC_BE	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
++#define BRCMS_PREC_BMP_AC_BK	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
++#define BRCMS_PREC_BMP_AC_VI	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
++#define BRCMS_PREC_BMP_AC_VO	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
++
++/* network protection config */
++#define	BRCMS_PROT_G_SPEC		1	/* SPEC g protection */
++#define	BRCMS_PROT_G_OVR		2	/* SPEC g prot override */
++#define	BRCMS_PROT_G_USER		3	/* gmode specified by user */
++#define	BRCMS_PROT_OVERLAP	4	/* overlap */
++#define	BRCMS_PROT_N_USER		10	/* nmode specified by user */
++#define	BRCMS_PROT_N_CFG		11	/* n protection */
++#define	BRCMS_PROT_N_CFG_OVR	12	/* n protection override */
++#define	BRCMS_PROT_N_NONGF	13	/* non-GF protection */
++#define	BRCMS_PROT_N_NONGF_OVR	14	/* non-GF protection override */
++#define	BRCMS_PROT_N_PAM_OVR	15	/* n preamble override */
++#define	BRCMS_PROT_N_OBSS		16	/* non-HT OBSS present */
++
++/*
++ * 54g modes (basic bits may still be overridden)
++ *
++ * GMODE_LEGACY_B
++ *	Rateset: 1b, 2b, 5.5, 11
++ *	Preamble: Long
++ *	Shortslot: Off
++ * GMODE_AUTO
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: Auto
++ * GMODE_ONLY
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
++ *	Extended Rateset: 6b, 9, 12b, 48
++ *	Preamble: Short required
++ *	Shortslot: Auto
++ * GMODE_B_DEFERRED
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: On
++ * GMODE_PERFORMANCE
++ *	Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
++ *	Preamble: Short required
++ *	Shortslot: On and required
++ * GMODE_LRS
++ *	Rateset: 1b, 2b, 5.5b, 11b
++ *	Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
++ *	Preamble: Long
++ *	Shortslot: Auto
++ */
++#define GMODE_LEGACY_B		0
++#define GMODE_AUTO		1
++#define GMODE_ONLY		2
++#define GMODE_B_DEFERRED	3
++#define GMODE_PERFORMANCE	4
++#define GMODE_LRS		5
++#define GMODE_MAX		6
++
++/* MCS values greater than this enable multiple streams */
++#define HIGHEST_SINGLE_STREAM_MCS	7
++
++#define	MAXBANDS		2	/* Maximum #of bands */
++
++/* max number of antenna configurations */
++#define ANT_SELCFG_MAX		4
++
++struct brcms_antselcfg {
++	u8 ant_config[ANT_SELCFG_MAX];	/* antenna configuration */
++	u8 num_antcfg;	/* number of available antenna configurations */
++};
++
++/* common functions for every port */
++extern struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr);
++extern uint brcms_c_detach(struct brcms_c_info *wlc);
++extern int brcms_c_up(struct brcms_c_info *wlc);
++extern uint brcms_c_down(struct brcms_c_info *wlc);
++
++extern bool brcms_c_chipmatch(u16 vendor, u16 device);
++extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx);
++extern void brcms_c_reset(struct brcms_c_info *wlc);
++
++extern void brcms_c_intrson(struct brcms_c_info *wlc);
++extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
++extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
++extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
++extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
++extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
++extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
++				     struct sk_buff *sdu,
++				     struct ieee80211_hw *hw);
++extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
++extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
++				   int val);
++extern int brcms_c_get_header_len(void);
++extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
++				  int match_reg_offset,
++				  const u8 *addr);
++extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++			      const struct ieee80211_tx_queue_params *arg,
++			      bool suspend);
++extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++			    struct ieee80211_sta *sta, u16 tid);
++extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++					 u8 ba_wsize, uint max_rx_ampdu_bytes);
++extern int brcms_c_module_register(struct brcms_pub *pub,
++				   const char *name, struct brcms_info *hdl,
++				   int (*down_fn)(void *handle));
++extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++				     struct brcms_info *hdl);
++extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
++extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
++extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
++extern void brcms_c_scan_start(struct brcms_c_info *wlc);
++extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
++extern int brcms_c_get_curband(struct brcms_c_info *wlc);
++extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
++					   bool drop);
++extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
++extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
++extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs);
++extern int brcms_c_set_rateset(struct brcms_c_info *wlc,
++					struct brcm_rateset *rs);
++extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
++extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
++extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
++				    s8 sslot_override);
++extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
++					u8 interval);
++extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
++extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
++extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
++extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
++
++#endif				/* _BRCM_PUB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.c b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+new file mode 100644
+index 0000000..0a0c0ad
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+@@ -0,0 +1,514 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++
++#include "d11.h"
++#include "pub.h"
++#include "rate.h"
++
++/*
++ * Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate
++ * value
++ */
++const u8 rate_info[BRCM_MAXRATE + 1] = {
++	/*  0     1     2     3     4     5     6     7     8     9 */
++/*   0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
++/*  20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
++/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
++/*  50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
++/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
++};
++
++/* rates are in units of Kbps */
++const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
++	/* MCS  0: SS 1, MOD: BPSK,  CR 1/2 */
++	{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
++	 BRCM_RATE_6M},
++	/* MCS  1: SS 1, MOD: QPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
++	 BRCM_RATE_12M},
++	/* MCS  2: SS 1, MOD: QPSK,  CR 3/4 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
++	 BRCM_RATE_18M},
++	/* MCS  3: SS 1, MOD: 16QAM, CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
++	 BRCM_RATE_24M},
++	/* MCS  4: SS 1, MOD: 16QAM, CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
++	 BRCM_RATE_36M},
++	/* MCS  5: SS 1, MOD: 64QAM, CR 2/3 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
++	 BRCM_RATE_48M},
++	/* MCS  6: SS 1, MOD: 64QAM, CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
++	 BRCM_RATE_54M},
++	/* MCS  7: SS 1, MOD: 64QAM, CR 5/6 */
++	{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
++	 BRCM_RATE_54M},
++	/* MCS  8: SS 2, MOD: BPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
++	 BRCM_RATE_6M},
++	/* MCS  9: SS 2, MOD: QPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
++	 BRCM_RATE_12M},
++	/* MCS 10: SS 2, MOD: QPSK,  CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
++	 BRCM_RATE_18M},
++	/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
++	 BRCM_RATE_24M},
++	/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
++	 BRCM_RATE_36M},
++	/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
++	 BRCM_RATE_48M},
++	/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
++	 BRCM_RATE_54M},
++	/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
++	{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
++	 BRCM_RATE_54M},
++	/* MCS 16: SS 3, MOD: BPSK,  CR 1/2 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
++	 BRCM_RATE_6M},
++	/* MCS 17: SS 3, MOD: QPSK,  CR 1/2 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
++	 BRCM_RATE_12M},
++	/* MCS 18: SS 3, MOD: QPSK,  CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
++	 BRCM_RATE_18M},
++	/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
++	 BRCM_RATE_24M},
++	/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
++	 BRCM_RATE_36M},
++	/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
++	 BRCM_RATE_48M},
++	/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
++	{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
++	 BRCM_RATE_54M},
++	/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
++	{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
++	 BRCM_RATE_54M},
++	/* MCS 24: SS 4, MOD: BPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
++	 BRCM_RATE_6M},
++	/* MCS 25: SS 4, MOD: QPSK,  CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
++	 BRCM_RATE_12M},
++	/* MCS 26: SS 4, MOD: QPSK,  CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
++	 BRCM_RATE_18M},
++	/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
++	 BRCM_RATE_24M},
++	/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
++	 BRCM_RATE_36M},
++	/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
++	{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
++	 BRCM_RATE_48M},
++	/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
++	{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
++	 BRCM_RATE_54M},
++	/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
++	{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
++	 BRCM_RATE_54M},
++	/* MCS 32: SS 1, MOD: BPSK,  CR 1/2 */
++	{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
++};
++
++/*
++ * phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
++ * Number of spatial streams: always 1 other fields: refer to table 78 of
++ * section 17.3.2.2 of the original .11a standard
++ */
++struct legacy_phycfg {
++	u32 rate_ofdm;	/* ofdm mac rate */
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++};
++
++/* Number of legacy_rate_cfg entries in the table */
++#define LEGACY_PHYCFG_TABLE_SIZE	12
++
++/*
++ * In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
++ * Eventually MIMOPHY would also be converted to this format
++ * 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
++ */
++static const struct
++legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
++	{BRCM_RATE_1M, 0x00},	/* CCK  1Mbps,  data rate  0 */
++	{BRCM_RATE_2M, 0x08},	/* CCK  2Mbps,  data rate  1 */
++	{BRCM_RATE_5M5, 0x10},	/* CCK  5.5Mbps,  data rate  2 */
++	{BRCM_RATE_11M, 0x18},	/* CCK  11Mbps,  data rate   3 */
++	/* OFDM  6Mbps,  code rate 1/2, BPSK,   1 spatial stream */
++	{BRCM_RATE_6M, 0x00},
++	/* OFDM  9Mbps,  code rate 3/4, BPSK,   1 spatial stream */
++	{BRCM_RATE_9M, 0x02},
++	/* OFDM  12Mbps, code rate 1/2, QPSK,   1 spatial stream */
++	{BRCM_RATE_12M, 0x08},
++	/* OFDM  18Mbps, code rate 3/4, QPSK,   1 spatial stream */
++	{BRCM_RATE_18M, 0x0A},
++	/* OFDM  24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_24M, 0x10},
++	/* OFDM  36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_36M, 0x12},
++	/* OFDM  48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_48M, 0x19},
++	/* OFDM  54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_54M, 0x1A},
++};
++
++/* Hardware rates (also encodes default basic rates) */
++
++const struct brcms_c_rateset cck_ofdm_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48, */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Default ratesets that include MCS32 for 40BW channels */
++static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48 */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_ofdm_rates = {
++	12,
++	/*  1b,   2b, 5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,*/
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/*54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset gphy_legacy_rates = {
++	4,
++	/*  1b,   2b,   5.5b, 11b Mbps */
++	{ 0x82, 0x84, 0x8b, 0x96},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_rates = {
++	4,
++	/*  1b,   2b,   5.5,  11 Mbps */
++	{ 0x82, 0x84, 0x0b, 0x16},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* check if rateset is valid.
++ * if check_brate is true, rateset without a basic rate is considered NOT valid.
++ */
++static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
++{
++	uint idx;
++
++	if (!rs->count)
++		return false;
++
++	if (!check_brate)
++		return true;
++
++	/* error if no basic rates */
++	for (idx = 0; idx < rs->count; idx++) {
++		if (rs->rates[idx] & BRCMS_RATE_FLAG)
++			return true;
++	}
++	return false;
++}
++
++void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
++{
++	int i;
++	for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
++		rs->mcs[i] = 0;
++}
++
++/*
++ * filter based on hardware rateset, and sort filtered rateset with basic
++ * bit(s) preserved, and check if resulting rateset is valid.
++*/
++bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				   const struct brcms_c_rateset *hw_rs,
++				   bool check_brate, u8 txstreams)
++{
++	u8 rateset[BRCM_MAXRATE + 1];
++	u8 r;
++	uint count;
++	uint i;
++
++	memset(rateset, 0, sizeof(rateset));
++	count = rs->count;
++
++	for (i = 0; i < count; i++) {
++		/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
++		r = (int)rs->rates[i] & BRCMS_RATE_MASK;
++		if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
++			continue;
++		rateset[r] = rs->rates[i];	/* preserve basic bit! */
++	}
++
++	/* fill out the rates in order, looking at only supported rates */
++	count = 0;
++	for (i = 0; i < hw_rs->count; i++) {
++		r = hw_rs->rates[i] & BRCMS_RATE_MASK;
++		if (rateset[r])
++			rs->rates[count++] = rateset[r];
++	}
++
++	rs->count = count;
++
++	/* only set the mcs rate bit if the equivalent hw mcs bit is set */
++	for (i = 0; i < MCSSET_LEN; i++)
++		rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
++
++	if (brcms_c_rateset_valid(rs, check_brate))
++		return true;
++	else
++		return false;
++}
++
++/* calculate the rate of a rx'd frame and return it as a ratespec */
++u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
++{
++	int phy_type;
++	u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
++
++	phy_type =
++	    ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
++
++	if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
++	    (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
++		switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
++		case PRXS0_CCK:
++			rspec =
++				cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++			break;
++		case PRXS0_OFDM:
++			rspec =
++			    ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++			break;
++		case PRXS0_PREN:
++			rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
++			if (plcp[0] & MIMO_PLCP_40MHZ) {
++				/* indicate rspec is for 40 MHz mode */
++				rspec &= ~RSPEC_BW_MASK;
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++			}
++			break;
++		case PRXS0_STDN:
++			/* fallthru */
++		default:
++			/* not supported, error condition */
++			break;
++		}
++		if (plcp3_issgi(plcp[3]))
++			rspec |= RSPEC_SHORT_GI;
++	} else
++	    if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
++		rspec = ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++	else
++		rspec = cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++
++	return rspec;
++}
++
++/* copy rateset src to dst as-is (no masking or sorting) */
++void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			  struct brcms_c_rateset *dst)
++{
++	memcpy(dst, src, sizeof(struct brcms_c_rateset));
++}
++
++/*
++ * Copy and selectively filter one rateset to another.
++ * 'basic_only' means only copy basic rates.
++ * 'rates' indicates cck (11b) and ofdm rates combinations.
++ *    - 0: cck and ofdm
++ *    - 1: cck only
++ *    - 2: ofdm only
++ * 'xmask' is the copy mask (typically 0x7f or 0xff).
++ */
++void
++brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
++		       bool basic_only, u8 rates, uint xmask, bool mcsallow)
++{
++	uint i;
++	uint r;
++	uint count;
++
++	count = 0;
++	for (i = 0; i < src->count; i++) {
++		r = src->rates[i];
++		if (basic_only && !(r & BRCMS_RATE_FLAG))
++			continue;
++		if (rates == BRCMS_RATES_CCK &&
++		    is_ofdm_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		if (rates == BRCMS_RATES_OFDM &&
++		    is_cck_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		dst->rates[count++] = r & xmask;
++	}
++	dst->count = count;
++	dst->htphy_membership = src->htphy_membership;
++
++	if (mcsallow && rates != BRCMS_RATES_CCK)
++		memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
++	else
++		brcms_c_rateset_mcs_clear(dst);
++}
++
++/* select rateset for a given phy_type and bandtype and filter it, sort it
++ * and fill rs_tgt with result
++ */
++void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw,
++			uint phy_type, int bandtype, bool cck_only,
++			uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs_sel;
++	if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
++		if (bandtype == BRCM_BAND_5G)
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
++		else
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &cck_ofdm_mimo_rates :
++				   &cck_ofdm_40bw_mimo_rates);
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
++		rs_dflt = (bandtype == BRCM_BAND_5G) ?
++			  &ofdm_rates : &cck_ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
++		rs_dflt = &ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
++		rs_dflt = &cck_ofdm_rates;
++	} else {
++		/* should not happen, error condition */
++		rs_dflt = &cck_rates;	/* force cck */
++	}
++
++	/* if hw rateset is not supplied, assign selected rateset to it */
++	if (!rs_hw)
++		rs_hw = rs_dflt;
++
++	brcms_c_rateset_copy(rs_dflt, &rs_sel);
++	brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
++	brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
++			   cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
++			   rate_mask, mcsallow);
++	brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
++					   mcsallow ? txstreams : 1);
++}
++
++s16 brcms_c_rate_legacy_phyctl(uint rate)
++{
++	uint i;
++	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
++		if (rate == legacy_phycfg_table[i].rate_ofdm)
++			return legacy_phycfg_table[i].tx_phy_ctl3;
++
++	return -1;
++}
++
++void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
++{
++	uint i;
++	for (i = 0; i < MCSSET_LEN; i++)
++		rateset->mcs[i] = 0;
++}
++
++void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
++{
++	memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
++	brcms_c_rateset_mcs_upd(rateset, txstreams);
++}
++
++/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
++void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
++{
++	if (bw == BRCMS_40_MHZ)
++		setbit(rateset->mcs, 32);
++	else
++		clrbit(rateset->mcs, 32);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+new file mode 100644
+index 0000000..980d578
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+@@ -0,0 +1,249 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_RATE_H_
++#define _BRCM_RATE_H_
++
++#include "types.h"
++#include "d11.h"
++#include "phy_hal.h"
++
++extern const u8 rate_info[];
++extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
++extern const struct brcms_c_rateset ofdm_mimo_rates;
++extern const struct brcms_c_rateset cck_ofdm_rates;
++extern const struct brcms_c_rateset ofdm_rates;
++extern const struct brcms_c_rateset cck_rates;
++extern const struct brcms_c_rateset gphy_legacy_rates;
++extern const struct brcms_c_rateset rate_limit_1_2;
++
++struct brcms_mcs_info {
++	/* phy rate in kbps [20Mhz] */
++	u32 phy_rate_20;
++	/* phy rate in kbps [40Mhz] */
++	u32 phy_rate_40;
++	/* phy rate in kbps [20Mhz] with SGI */
++	u32 phy_rate_20_sgi;
++	/* phy rate in kbps [40Mhz] with SGI */
++	u32 phy_rate_40_sgi;
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++	/* matching legacy ofdm rate in 500bkps */
++	u8 leg_ofdm;
++};
++
++#define BRCMS_MAXMCS	32	/* max valid mcs index */
++#define MCS_TABLE_SIZE	33	/* Number of mcs entries in the table */
++extern const struct brcms_mcs_info mcs_table[];
++
++#define MCS_TXS_MASK	0xc0	/* num tx streams - 1 bit mask */
++#define MCS_TXS_SHIFT	6	/* num tx streams - 1 bit shift */
++
++/* returns num tx streams - 1 */
++static inline u8 mcs_2_txstreams(u8 mcs)
++{
++	return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
++}
++
++static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
++{
++	if (sgi) {
++		if (is40)
++			return mcs_table[mcs].phy_rate_40_sgi;
++		return mcs_table[mcs].phy_rate_20_sgi;
++	}
++	if (is40)
++		return mcs_table[mcs].phy_rate_40;
++
++	return mcs_table[mcs].phy_rate_20;
++}
++
++/* Macro to use the rate_info table */
++#define	BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
++
++/*
++ * rate spec : holds rate and mode specific information required to generate a
++ * tx frame. Legacy CCK and OFDM information is held in the same manner as was
++ * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
++ * specific information
++ */
++
++/* rate spec bit fields */
++
++/* Either 500Kbps units or MIMO MCS idx */
++#define RSPEC_RATE_MASK		0x0000007F
++/* mimo MCS is stored in RSPEC_RATE_MASK */
++#define RSPEC_MIMORATE		0x08000000
++/* mimo bw mask */
++#define RSPEC_BW_MASK		0x00000700
++/* mimo bw shift */
++#define RSPEC_BW_SHIFT		8
++/* mimo Space/Time/Frequency mode mask */
++#define RSPEC_STF_MASK		0x00003800
++/* mimo Space/Time/Frequency mode shift */
++#define RSPEC_STF_SHIFT		11
++/* mimo coding type mask */
++#define RSPEC_CT_MASK		0x0000C000
++/* mimo coding type shift */
++#define RSPEC_CT_SHIFT		14
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_MASK		0x00300000
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_SHIFT		20
++/* mimo bit indicates adv coding in use */
++#define RSPEC_LDPC_CODING	0x00400000
++/* mimo bit indicates short GI in use */
++#define RSPEC_SHORT_GI		0x00800000
++/* bit indicates override both rate & mode */
++#define RSPEC_OVERRIDE		0x80000000
++/* bit indicates override rate only */
++#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
++
++static inline bool rspec_active(u32 rspec)
++{
++	return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
++}
++
++static inline u8 rspec_phytxbyte2(u32 rspec)
++{
++	return (rspec & 0xff00) >> 8;
++}
++
++static inline u32 rspec_get_bw(u32 rspec)
++{
++	return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
++}
++
++static inline bool rspec_issgi(u32 rspec)
++{
++	return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
++}
++
++static inline bool rspec_is40mhz(u32 rspec)
++{
++	u32 bw = rspec_get_bw(rspec);
++
++	return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
++}
++
++static inline uint rspec2rate(u32 rspec)
++{
++	if (rspec & RSPEC_MIMORATE)
++		return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
++				  rspec_issgi(rspec));
++	return rspec & RSPEC_RATE_MASK;
++}
++
++static inline u8 rspec_mimoplcp3(u32 rspec)
++{
++	return (rspec & 0xf00000) >> 16;
++}
++
++static inline bool plcp3_issgi(u8 plcp)
++{
++	return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
++}
++
++static inline uint rspec_stc(u32 rspec)
++{
++	return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
++}
++
++static inline uint rspec_stf(u32 rspec)
++{
++	return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
++}
++
++static inline bool is_mcs_rate(u32 ratespec)
++{
++	return (ratespec & RSPEC_MIMORATE) != 0;
++}
++
++static inline bool is_ofdm_rate(u32 ratespec)
++{
++	return !is_mcs_rate(ratespec) &&
++	       (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
++}
++
++static inline bool is_cck_rate(u32 ratespec)
++{
++	u32 rate = (ratespec & BRCMS_RATE_MASK);
++
++	return !is_mcs_rate(ratespec) && (
++			rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
++			rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
++}
++
++static inline bool is_single_stream(u8 mcs)
++{
++	return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
++}
++
++static inline u8 cck_rspec(u8 cck)
++{
++	return cck & RSPEC_RATE_MASK;
++}
++
++/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
++ * increments */
++static inline u8 ofdm_phy2mac_rate(u8 rlpt)
++{
++	return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7];
++}
++
++static inline u8 cck_phy2mac_rate(u8 signal)
++{
++	return signal/5;
++}
++
++/* Rates specified in brcms_c_rateset_filter() */
++#define BRCMS_RATES_CCK_OFDM	0
++#define BRCMS_RATES_CCK		1
++#define BRCMS_RATES_OFDM		2
++
++/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
++ * rateset */
++extern bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				       const struct brcms_c_rateset *hw_rs,
++				       bool check_brate, u8 txstreams);
++/* copy rateset src to dst as-is (no masking or sorting) */
++extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			     struct brcms_c_rateset *dst);
++
++/* would be nice to have these documented ... */
++extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
++
++extern void brcms_c_rateset_filter(struct brcms_c_rateset *src,
++	struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask,
++	bool mcsallow);
++
++extern void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw, uint phy_type,
++			int bandtype, bool cck_only, uint rate_mask,
++			bool mcsallow, u8 bw, u8 txstreams);
++
++extern s16 brcms_c_rate_legacy_phyctl(uint rate);
++
++extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
++extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
++extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset,
++				      u8 txstreams);
++extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset,
++					  u8 bw);
++
++#endif				/* _BRCM_RATE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/scb.h b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+new file mode 100644
+index 0000000..51c79c7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+@@ -0,0 +1,82 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_SCB_H_
++#define _BRCM_SCB_H_
++
++#include <linux/if_ether.h>
++#include <brcmu_utils.h>
++#include <defs.h>
++#include "types.h"
++
++#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
++
++#define AMPDU_MAX_SCB_TID	NUMPRIO
++
++/* scb flags */
++#define SCB_WMECAP		0x0040
++#define SCB_HTCAP		0x10000	/* HT (MIMO) capable device */
++#define SCB_IS40		0x80000	/* 40MHz capable */
++#define SCB_STBCCAP		0x40000000	/* STBC Capable */
++
++#define SCB_MAGIC	0xbeefcafe
++
++/* structure to store per-tid state for the ampdu initiator */
++struct scb_ampdu_tid_ini {
++	u8 tx_in_transit; /* number of pending mpdus in transit in driver */
++	u8 tid;		  /* initiator tid for easy lookup */
++	/* tx retry count; indexed by seq modulo */
++	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
++	struct scb *scb;  /* backptr for easy lookup */
++	u8 ba_wsize;	  /* negotiated ba window size (in pdu) */
++};
++
++struct scb_ampdu {
++	struct scb *scb;	/* back pointer for easy reference */
++	u8 mpdu_density;	/* mpdu density */
++	u8 max_pdu;		/* max pdus allowed in ampdu */
++	u8 release;		/* # of mpdus released at a time */
++	u16 min_len;		/* min mpdu len to support the density */
++	u32 max_rx_ampdu_bytes;	/* max ampdu rcv length; 8k, 16k, 32k, 64k */
++
++	/*
++	 * This could easily be a ini[] pointer and we keep this info in wl
++	 * itself instead of having mac80211 hold it for us. Also could be made
++	 * dynamic per tid instead of static.
++	 */
++	/* initiator info - per tid (NUMPRIO): */
++	struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
++};
++
++/* station control block - one per remote MAC address */
++struct scb {
++	u32 magic;
++	u32 flags;	/* various bit flags as defined below */
++	u32 flags2;	/* various bit flags2 as defined below */
++	u8 state;	/* current state bitfield of auth/assoc process */
++	u8 ea[ETH_ALEN];	/* station address */
++	uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
++
++	u16 seqctl[NUMPRIO];	/* seqctl of last received frame (for dups) */
++	/* seqctl of last received frame (for dups) for non-QoS data and
++	 * management */
++	u16 seqctl_nonqos;
++	u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
++
++	struct scb_ampdu scb_ampdu;	/* AMPDU state including per tid info */
++};
++
++#endif				/* _BRCM_SCB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+new file mode 100644
+index 0000000..ed1d1aa
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+@@ -0,0 +1,438 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "d11.h"
++#include "rate.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "main.h"
++#include "stf.h"
++
++#define MIN_SPATIAL_EXPANSION	0
++#define MAX_SPATIAL_EXPANSION	1
++
++#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
++	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
++
++#define NSTS_1	1
++#define NSTS_2	2
++#define NSTS_3	3
++#define NSTS_4	4
++
++static const u8 txcore_default[5] = {
++	(0),			/* bitmap of the core enabled */
++	(0x01),			/* For Nsts = 1, enable core 1 */
++	(0x03),			/* For Nsts = 2, enable core 1 & 2 */
++	(0x07),			/* For Nsts = 3, enable core 1, 2 & 3 */
++	(0x0f)			/* For Nsts = 4, enable all cores */
++};
++
++static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
++{
++	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
++			return;
++	}
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++/*
++ * every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
++ * turn on/off txchain.
++ */
++void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
++{
++	struct brcms_phy_pub *pi = wlc->band->pi;
++	uint active_chains, txchain;
++
++	/* Check if the chip is too hot. Disable one Tx chain, if it is */
++	/* high 4 bits are for Rx chain, low 4 bits are  for Tx chain */
++	active_chains = wlc_phy_stf_chain_active_get(pi);
++	txchain = active_chains & 0xf;
++
++	if (wlc->stf->txchain == wlc->stf->hw_txchain) {
++		if (txchain && (txchain < wlc->stf->hw_txchain))
++			/* turn off 1 tx chain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
++		if (txchain == wlc->stf->hw_txchain)
++			/* turn back on txchain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	}
++}
++
++void
++brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
++			    u16 chanspec)
++{
++	struct tx_power power;
++	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
++
++	/* Clear previous settings */
++	*ss_algo_channel = 0;
++
++	if (!wlc->pub->up) {
++		*ss_algo_channel = (u16) -1;
++		return;
++	}
++
++	wlc_phy_txpower_get_current(wlc->band->pi, &power,
++				    CHSPEC_CHANNEL(chanspec));
++
++	siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
++	cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
++	stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
++
++	/* criteria to choose stf mode */
++
++	/*
++	 * the "+3dbm (12 0.25db units)" is to account for the fact that with
++	 * CDD, tx occurs on both chains
++	 */
++	if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
++	else
++		setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
++
++	/*
++	 * STBC is ORed into to algo channel as STBC requires per-packet SCB
++	 * capability check so cannot be default mode of operation. One of
++	 * SISO, CDD have to be set
++	 */
++	if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
++}
++
++static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
++		return false;
++
++	if ((int_val == ON) && (wlc->stf->txstreams == 1))
++		return false;
++
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++
++	return true;
++}
++
++bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != HT_CAP_RX_STBC_NO)
++	    && (int_val != HT_CAP_RX_STBC_ONE_STREAM))
++		return false;
++
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((int_val != HT_CAP_RX_STBC_NO)
++		    && (wlc->stf->rxstreams == 1))
++			return false;
++	}
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
++	return true;
++}
++
++static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
++				  u8 core_mask)
++{
++	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
++		 wlc->pub->unit, Nsts, core_mask);
++
++	if (hweight8(core_mask) > wlc->stf->txstreams)
++		core_mask = 0;
++
++	if ((hweight8(core_mask) == wlc->stf->txstreams) &&
++	    ((core_mask & ~wlc->stf->txchain)
++	     || !(core_mask & wlc->stf->txchain)))
++		core_mask = wlc->stf->txchain;
++
++	wlc->stf->txcore[Nsts] = core_mask;
++	/* Nsts = 1..4, txcore index = 1..4 */
++	if (Nsts == 1) {
++		/* Needs to update beacon and ucode generated response
++		 * frames when 1 stream core map changed
++		 */
++		wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
++		brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++		if (wlc->clk) {
++			brcms_c_suspend_mac_and_wait(wlc);
++			brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
++			brcms_c_enable_mac(wlc);
++		}
++	}
++
++	return 0;
++}
++
++static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
++{
++	int i;
++	u8 core_mask = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
++
++	wlc->stf->spatial_policy = (s8) val;
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
++		core_mask = (val == MAX_SPATIAL_EXPANSION) ?
++		    wlc->stf->txchain : txcore_default[i];
++		brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
++	}
++	return 0;
++}
++
++/*
++ * Centralized txant update function. call it whenever wlc->stf->txant and/or
++ * wlc->stf->txchain change.
++ *
++ * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
++ * achieve various tx/rx antenna selection schemes
++ *
++ * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means auto(last rx).
++ * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
++ * means both cores active
++*/
++static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	s8 txant;
++
++	txant = (s8) wlc->stf->txant;
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (txant == ANT_TX_FORCE_0) {
++			wlc->stf->phytxant = PHY_TXC_ANT_0;
++		} else if (txant == ANT_TX_FORCE_1) {
++			wlc->stf->phytxant = PHY_TXC_ANT_1;
++
++			if (BRCMS_ISNPHY(wlc->band) &&
++			    NREV_GE(wlc->band->phyrev, 3)
++			    && NREV_LT(wlc->band->phyrev, 7))
++				wlc->stf->phytxant = PHY_TXC_ANT_2;
++		} else {
++			if (BRCMS_ISLCNPHY(wlc->band) ||
++			    BRCMS_ISSSLPNPHY(wlc->band))
++				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
++			else {
++				/* catch out of sync wlc->stf->txcore */
++				WARN_ON(wlc->stf->txchain <= 0);
++				wlc->stf->phytxant =
++				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++			}
++		}
++	} else {
++		if (txant == ANT_TX_FORCE_0)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
++		else if (txant == ANT_TX_FORCE_1)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
++		else
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
++	}
++
++	brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++}
++
++int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
++{
++	u8 txchain = (u8) int_val;
++	u8 txstreams;
++	uint i;
++
++	if (wlc->stf->txchain == txchain)
++		return 0;
++
++	if ((txchain & ~wlc->stf->hw_txchain)
++	    || !(txchain & wlc->stf->hw_txchain))
++		return -EINVAL;
++
++	/*
++	 * if nrate override is configured to be non-SISO STF mode, reject
++	 * reducing txchain to 1
++	 */
++	txstreams = (u8) hweight8(txchain);
++	if (txstreams > MAX_STREAMS_SUPPORTED)
++		return -EINVAL;
++
++	wlc->stf->txchain = txchain;
++	wlc->stf->txstreams = txstreams;
++	brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	wlc->stf->txant =
++	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
++	_brcms_c_stf_phy_txant_upd(wlc);
++
++	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
++			      wlc->stf->rxchain);
++
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
++		brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
++
++	return 0;
++}
++
++/*
++ * update wlc->stf->ss_opmode which represents the operational stf_ss mode
++ * we're using
++ */
++int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
++{
++	int ret_code = 0;
++	u8 prev_stf_ss;
++	u8 upd_stf_ss;
++
++	prev_stf_ss = wlc->stf->ss_opmode;
++
++	/*
++	 * NOTE: opmode can only be SISO or CDD as STBC is decided on a
++	 * per-packet basis
++	 */
++	if (BRCMS_STBC_CAP_PHY(wlc) &&
++	    wlc->stf->ss_algosel_auto
++	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
++		upd_stf_ss = (wlc->stf->txstreams == 1 ||
++			      isset(&wlc->stf->ss_algo_channel,
++				    PHY_TXC1_MODE_SISO)) ?
++				    PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
++	} else {
++		if (wlc->band != band)
++			return ret_code;
++		upd_stf_ss = (wlc->stf->txstreams == 1) ?
++				PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
++	}
++	if (prev_stf_ss != upd_stf_ss) {
++		wlc->stf->ss_opmode = upd_stf_ss;
++		brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
++	}
++
++	return ret_code;
++}
++
++int brcms_c_stf_attach(struct brcms_c_info *wlc)
++{
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
++		wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
++		    PHY_TXC1_MODE_CDD;
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
++
++	if (BRCMS_STBC_CAP_PHY(wlc)) {
++		wlc->stf->ss_algosel_auto = true;
++		/* Init the default value */
++		wlc->stf->ss_algo_channel = (u16) -1;
++	}
++	return 0;
++}
++
++void brcms_c_stf_detach(struct brcms_c_info *wlc)
++{
++}
++
++void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	_brcms_c_stf_phy_txant_upd(wlc);
++}
++
++void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
++{
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	/* get available rx/tx chains */
++	wlc->stf->hw_txchain = sprom->txchain;
++	wlc->stf->hw_rxchain = sprom->rxchain;
++
++	/* these parameter are intended to be used for all PHY types */
++	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_txchain = TXCHAIN_DEF;
++	}
++
++	wlc->stf->txchain = wlc->stf->hw_txchain;
++	wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
++
++	if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_rxchain = RXCHAIN_DEF;
++	}
++
++	wlc->stf->rxchain = wlc->stf->hw_rxchain;
++	wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
++
++	/* initialize the txcore table */
++	memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
++
++	/* default spatial_policy */
++	wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
++	brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
++}
++
++static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				       u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++
++	if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	else if (wlc->stf->txant == ANT_TX_DEF)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	phytxant &= PHY_TXC_ANT_MASK;
++	return phytxant;
++}
++
++u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
++{
++	return _brcms_c_stf_phytxchain_sel(wlc, rspec);
++}
++
++u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_ISNPHY(wlc->band)) {
++		phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
++		mask = PHY_TXC_HTANT_MASK;
++	}
++	phytxant |= phytxant & mask;
++	return phytxant;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+new file mode 100644
+index 0000000..19f6580
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_STF_H_
++#define _BRCM_STF_H_
++
++#include "types.h"
++
++extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
++extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
++
++extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
++					u16 *ss_algo_channel,
++					u16 chanspec);
++extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
++			     struct brcms_band *band);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
++			       bool force);
++extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
++extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				      u32 rspec);
++extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
++					u32 rspec);
++
++#endif				/* _BRCM_STF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+new file mode 100644
+index 0000000..e11ae83
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+@@ -0,0 +1,304 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_TYPES_H_
++#define _BRCM_TYPES_H_
++
++#include <linux/types.h>
++#include <linux/io.h>
++
++#define WL_CHAN_FREQ_RANGE_2G      0
++#define WL_CHAN_FREQ_RANGE_5GL     1
++#define WL_CHAN_FREQ_RANGE_5GM     2
++#define WL_CHAN_FREQ_RANGE_5GH     3
++
++/* boardflags */
++
++/* Board has gpio 9 controlling the PA */
++#define	BFL_PACTRL		0x00000002
++/* Not ok to power down the chip pll and oscillator */
++#define	BFL_NOPLLDOWN		0x00000020
++/* Board supports the Front End Module */
++#define BFL_FEM			0x00000800
++/* Board has an external LNA in 2.4GHz band */
++#define BFL_EXTLNA		0x00001000
++/* Board has no PA */
++#define BFL_NOPA		0x00010000
++/* Power topology uses BUCKBOOST */
++#define BFL_BUCKBOOST		0x00200000
++/* Board has FEM and switch to share antenna w/ BT */
++#define BFL_FEM_BT		0x00400000
++/* Power topology doesn't use CBUCK */
++#define BFL_NOCBUCK		0x00800000
++/* Power topology uses PALDO */
++#define BFL_PALDO		0x02000000
++/* Board has an external LNA in 5GHz band */
++#define BFL_EXTLNA_5GHz		0x10000000
++
++/* boardflags2 */
++
++/* Board has an external rxbb regulator */
++#define BFL2_RXBB_INT_REG_DIS	0x00000001
++/* Flag to implement alternative A-band PLL settings */
++#define BFL2_APLL_WAR		0x00000002
++/* Board permits enabling TX Power Control */
++#define BFL2_TXPWRCTRL_EN	0x00000004
++/* Board supports the 2X4 diversity switch */
++#define BFL2_2X4_DIV		0x00000008
++/* Board supports 5G band power gain */
++#define BFL2_5G_PWRGAIN		0x00000010
++/* Board overrides ASPM and Clkreq settings */
++#define BFL2_PCIEWAR_OVR	0x00000020
++#define BFL2_LEGACY		0x00000080
++/* 4321mcm93 board uses Skyworks FEM */
++#define BFL2_SKWRKFEM_BRD	0x00000100
++/* Board has a WAR for clock-harmonic spurs */
++#define BFL2_SPUR_WAR		0x00000200
++/* Flag to narrow G-band PLL loop b/w */
++#define BFL2_GPLL_WAR		0x00000400
++/* Tx CCK pkts on Ant 0 only */
++#define BFL2_SINGLEANT_CCK	0x00001000
++/* WAR to reduce and avoid clock-harmonic spurs in 2G */
++#define BFL2_2G_SPUR_WAR	0x00002000
++/* Flag to widen G-band PLL loop b/w */
++#define BFL2_GPLL_WAR2	        0x00010000
++#define BFL2_IPALVLSHIFT_3P3    0x00020000
++/* Use internal envelope detector for TX IQCAL */
++#define BFL2_INTERNDET_TXIQCAL  0x00040000
++/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
++ * off without this flag to save power. */
++#define BFL2_XTALBUFOUTEN       0x00080000
++
++/*
++ * board specific GPIO assignment, gpio 0-3 are also customer-configurable
++ * led
++ */
++
++/* bit 9 controls the PA on new 4306 boards */
++#define	BOARD_GPIO_PACTRL	0x200
++#define BOARD_GPIO_12		0x1000
++#define BOARD_GPIO_13		0x2000
++
++/* **** Core type/rev defaults **** */
++#define D11CONF		0x0fffffb0	/* Supported  D11 revs: 4, 5, 7-27
++					 * also need to update wlc.h MAXCOREREV
++					 */
++
++#define NCONF		0x000001ff	/* Supported nphy revs:
++					 *      0       4321a0
++					 *      1       4321a1
++					 *      2       4321b0/b1/c0/c1
++					 *      3       4322a0
++					 *      4       4322a1
++					 *      5       4716a0
++					 *      6       43222a0, 43224a0
++					 *      7       43226a0
++					 *      8       5357a0, 43236a0
++					 */
++
++#define LCNCONF		0x00000007	/* Supported lcnphy revs:
++					 *      0       4313a0, 4336a0, 4330a0
++					 *      1
++					 *      2       4330a0
++					 */
++
++#define SSLPNCONF	0x0000000f	/* Supported sslpnphy revs:
++					 *      0       4329a0/k0
++					 *      1       4329b0/4329C0
++					 *      2       4319a0
++					 *      3       5356a0
++					 */
++
++/********************************************************************
++ * Phy/Core Configuration.  Defines macros to to check core phy/rev *
++ * compile-time configuration.  Defines default core support.       *
++ * ******************************************************************
++ */
++
++/* Basic macros to check a configuration bitmask */
++
++#define CONF_HAS(config, val)	((config) & (1 << (val)))
++#define CONF_MSK(config, mask)	((config) & (mask))
++#define MSK_RANGE(low, hi)	((1 << ((hi)+1)) - (1 << (low)))
++#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
++
++#define CONF_IS(config, val)	((config) == (1 << (val)))
++#define CONF_GE(config, val)	((config) & (0-(1 << (val))))
++#define CONF_GT(config, val)	((config) & (0-2*(1 << (val))))
++#define CONF_LT(config, val)	((config) & ((1 << (val))-1))
++#define CONF_LE(config, val)	((config) & (2*(1 << (val))-1))
++
++/* Wrappers for some of the above, specific to config constants */
++
++#define NCONF_HAS(val)	CONF_HAS(NCONF, val)
++#define NCONF_MSK(mask)	CONF_MSK(NCONF, mask)
++#define NCONF_IS(val)	CONF_IS(NCONF, val)
++#define NCONF_GE(val)	CONF_GE(NCONF, val)
++#define NCONF_GT(val)	CONF_GT(NCONF, val)
++#define NCONF_LT(val)	CONF_LT(NCONF, val)
++#define NCONF_LE(val)	CONF_LE(NCONF, val)
++
++#define LCNCONF_HAS(val)	CONF_HAS(LCNCONF, val)
++#define LCNCONF_MSK(mask)	CONF_MSK(LCNCONF, mask)
++#define LCNCONF_IS(val)		CONF_IS(LCNCONF, val)
++#define LCNCONF_GE(val)		CONF_GE(LCNCONF, val)
++#define LCNCONF_GT(val)		CONF_GT(LCNCONF, val)
++#define LCNCONF_LT(val)		CONF_LT(LCNCONF, val)
++#define LCNCONF_LE(val)		CONF_LE(LCNCONF, val)
++
++#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
++#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
++#define D11CONF_IS(val)	CONF_IS(D11CONF, val)
++#define D11CONF_GE(val)	CONF_GE(D11CONF, val)
++#define D11CONF_GT(val)	CONF_GT(D11CONF, val)
++#define D11CONF_LT(val)	CONF_LT(D11CONF, val)
++#define D11CONF_LE(val)	CONF_LE(D11CONF, val)
++
++#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
++#define PHYCONF_IS(val)	CONF_IS(PHYTYPE, val)
++
++#define NREV_IS(var, val) \
++	(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
++
++#define NREV_GE(var, val) \
++	(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
++
++#define NREV_GT(var, val) \
++	(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
++
++#define NREV_LT(var, val) \
++	(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
++
++#define NREV_LE(var, val) \
++	(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
++
++#define LCNREV_IS(var, val) \
++	(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
++
++#define LCNREV_GE(var, val) \
++	(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
++
++#define LCNREV_GT(var, val) \
++	(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
++
++#define LCNREV_LT(var, val) \
++	(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
++
++#define LCNREV_LE(var, val) \
++	(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
++
++#define D11REV_IS(var, val) \
++	(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
++
++#define D11REV_GE(var, val) \
++	(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
++
++#define D11REV_GT(var, val) \
++	(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
++
++#define D11REV_LT(var, val) \
++	(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
++
++#define D11REV_LE(var, val) \
++	(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
++
++#define PHYTYPE_IS(var, val)\
++	(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
++
++/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
++
++#define _PHYCONF_N (1 << PHY_TYPE_N)
++#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
++#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
++
++#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
++
++/* Utility macro to identify 802.11n (HT) capable PHYs */
++#define PHYTYPE_11N_CAP(phytype) \
++	(PHYTYPE_IS(phytype, PHY_TYPE_N) ||	\
++	 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
++	 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
++
++/* Last but not least: shorter wlc-specific var checks */
++#define BRCMS_ISNPHY(band)		PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
++#define BRCMS_ISLCNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
++#define BRCMS_ISSSLPNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
++
++#define BRCMS_PHY_11N_CAP(band)	PHYTYPE_11N_CAP((band)->phytype)
++
++/**********************************************************************
++ * ------------- End of Core phy/rev configuration. ----------------- *
++ * ********************************************************************
++ */
++
++#define BCMMSG(dev, fmt, args...)		\
++do {						\
++	if (brcm_msg_level & LOG_TRACE_VAL)	\
++		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
++} while (0)
++
++#ifdef CONFIG_BCM47XX
++/*
++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
++ * transactions. As a fix, a read after write is performed on certain places
++ * in the code. Older chips and the newer 5357 family don't require this fix.
++ */
++#define bcma_wflush16(c, o, v) \
++	({ bcma_write16(c, o, v); (void)bcma_read16(c, o); })
++#else
++#define bcma_wflush16(c, o, v)	bcma_write16(c, o, v)
++#endif				/* CONFIG_BCM47XX */
++
++/* multi-bool data type: set of bools, mbool is true if any is set */
++
++/* set one bool */
++#define mboolset(mb, bit)		((mb) |= (bit))
++/* clear one bool */
++#define mboolclr(mb, bit)		((mb) &= ~(bit))
++/* true if one bool is set */
++#define mboolisset(mb, bit)		(((mb) & (bit)) != 0)
++#define	mboolmaskset(mb, mask, val)	((mb) = (((mb) & ~(mask)) | (val)))
++
++#define CEIL(x, y)		(((x) + ((y)-1)) / (y))
++
++/* forward declarations */
++struct wiphy;
++struct ieee80211_sta;
++struct ieee80211_tx_queue_params;
++struct brcms_info;
++struct brcms_c_info;
++struct brcms_hardware;
++struct brcms_txq_info;
++struct brcms_band;
++struct dma_pub;
++struct si_pub;
++struct tx_status;
++struct d11rxhdr;
++struct txpwr_limits;
++
++/* iovar structure */
++struct brcmu_iovar {
++	const char *name;	/* name for lookup and display */
++	u16 varid;	/* id for switch */
++	u16 flags;	/* driver-specific flag bits */
++	u16 type;	/* base type of argument */
++	u16 minlen;	/* min length for buffer vars */
++};
++
++/* brcm_msg_level is a bit vector with defs in defs.h */
++extern u32 brcm_msg_level;
++
++#endif				/* _BRCM_TYPES_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+new file mode 100644
+index 0000000..80e3ccf
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <defs.h>
++#include "types.h"
++#include <ucode_loader.h>
++
++enum {
++	D11UCODE_NAMETAG_START = 0,
++	D11LCN0BSINITVALS24,
++	D11LCN0INITVALS24,
++	D11LCN1BSINITVALS24,
++	D11LCN1INITVALS24,
++	D11LCN2BSINITVALS24,
++	D11LCN2INITVALS24,
++	D11N0ABSINITVALS16,
++	D11N0BSINITVALS16,
++	D11N0INITVALS16,
++	D11UCODE_OVERSIGHT16_MIMO,
++	D11UCODE_OVERSIGHT16_MIMOSZ,
++	D11UCODE_OVERSIGHT24_LCN,
++	D11UCODE_OVERSIGHT24_LCNSZ,
++	D11UCODE_OVERSIGHT_BOMMAJOR,
++	D11UCODE_OVERSIGHT_BOMMINOR
++};
++
++int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
++{
++	int rc;
++
++	rc = brcms_check_firmwares(wl);
++
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
++				     D11LCN0BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
++				       D11LCN0INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
++				       D11LCN1BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
++				       D11LCN1INITVALS24);
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
++				     D11LCN2BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
++				       D11LCN2INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
++				       D11N0ABSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
++				       D11N0BSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
++				       D11N0INITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
++				       D11UCODE_OVERSIGHT16_MIMO);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
++					D11UCODE_OVERSIGHT16_MIMOSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
++				       D11UCODE_OVERSIGHT24_LCN);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
++					D11UCODE_OVERSIGHT24_LCNSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
++				       D11UCODE_OVERSIGHT_BOMMAJOR);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
++				       D11UCODE_OVERSIGHT_BOMMINOR);
++	return rc;
++}
++
++void brcms_ucode_data_free(struct brcms_ucode *ucode)
++{
++	brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+new file mode 100644
+index 0000000..18750a8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef	_BRCM_UCODE_H_
++#define	_BRCM_UCODE_H_
++
++#include "types.h"		/* forward structure declarations */
++
++#define MIN_FW_SIZE 40000	/* minimum firmware file size in bytes */
++#define MAX_FW_SIZE 150000
++
++#define UCODE_LOADER_API_VER 0
++
++struct d11init;
++
++struct brcms_ucode {
++	struct d11init *d11lcn0bsinitvals24;
++	struct d11init *d11lcn0initvals24;
++	struct d11init *d11lcn1bsinitvals24;
++	struct d11init *d11lcn1initvals24;
++	struct d11init *d11lcn2bsinitvals24;
++	struct d11init *d11lcn2initvals24;
++	struct d11init *d11n0absinitvals16;
++	struct d11init *d11n0bsinitvals16;
++	struct d11init *d11n0initvals16;
++	__le32 *bcm43xx_16_mimo;
++	size_t bcm43xx_16_mimosz;
++	__le32 *bcm43xx_24_lcn;
++	size_t bcm43xx_24_lcnsz;
++	u32 *bcm43xx_bommajor;
++	u32 *bcm43xx_bomminor;
++};
++
++extern int
++brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
++
++extern void brcms_ucode_data_free(struct brcms_ucode *ucode);
++
++extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
++				unsigned int idx);
++extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
++				 unsigned int idx);
++extern void brcms_ucode_free_buf(void *);
++extern int  brcms_check_firmwares(struct brcms_info *wl);
++
++#endif	/* _BRCM_UCODE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/Makefile b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+new file mode 100644
+index 0000000..5529801
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+@@ -0,0 +1,28 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
++#
++# Copyright (c) 2011 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y :=				\
++	-I$(obj)			\
++	-I$(obj)/../include
++
++BRCMUTIL_OFILES := \
++	utils.o
++
++MODULEPFX := brcmutil
++
++obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+new file mode 100644
+index 0000000..161851b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+@@ -0,0 +1,278 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++
++#include <brcmu_utils.h>
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(len);
++	if (skb) {
++		skb_put(skb, len);
++		skb->priority = 0;
++	}
++
++	return skb;
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
++
++/* Free the driver packet. Free the tag if present */
++void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
++{
++	WARN_ON(skb->next);
++	if (skb->destructor)
++		/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
++		 * destructor exists
++		 */
++		dev_kfree_skb_any(skb);
++	else
++		/* can free immediately (even in_irq()) if destructor
++		 * does not exist
++		 */
++		dev_kfree_skb(skb);
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
++
++/*
++ * osl multiple-precedence packet queue
++ * hi_prec is always >= the number of the highest non-empty precedence
++ */
++struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				      struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_tail(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq);
++
++struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++					   struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_head(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq_head);
++
++struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq);
++
++struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue_tail(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
++
++void
++brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
++		  bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p, *next;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_walk_safe(q, p, next) {
++		if (fn == NULL || (*fn) (p, arg)) {
++			skb_unlink(p, q);
++			brcmu_pkt_buf_free_skb(p);
++			pq->len--;
++		}
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_pflush);
++
++void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		      bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	int prec;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, dir, fn, arg);
++}
++EXPORT_SYMBOL(brcmu_pktq_flush);
++
++void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
++{
++	int prec;
++
++	/* pq is variable size; only zero out what's requested */
++	memset(pq, 0,
++	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
++
++	pq->num_prec = (u16) num_prec;
++
++	pq->max = (u16) max_len;
++
++	for (prec = 0; prec < num_prec; prec++) {
++		pq->q[prec].max = pq->max;
++		skb_queue_head_init(&pq->q[prec].skblist);
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_init);
++
++struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
++{
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	for (prec = 0; prec < pq->hi_prec; prec++)
++		if (!skb_queue_empty(&pq->q[prec].skblist))
++			break;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++EXPORT_SYMBOL(brcmu_pktq_peek_tail);
++
++/* Return sum of lengths of a specific set of precedences */
++int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
++{
++	int prec, len;
++
++	len = 0;
++
++	for (prec = 0; prec <= pq->hi_prec; prec++)
++		if (prec_bmp & (1 << prec))
++			len += pq->q[prec].skblist.qlen;
++
++	return len;
++}
++EXPORT_SYMBOL(brcmu_pktq_mlen);
++
++/* Priority dequeue from a specific set of precedences */
++struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++				      int *prec_out)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	while ((prec = pq->hi_prec) > 0 &&
++	       skb_queue_empty(&pq->q[prec].skblist))
++		pq->hi_prec--;
++
++	while ((prec_bmp & (1 << prec)) == 0 ||
++	       skb_queue_empty(&pq->q[prec].skblist))
++		if (prec-- == 0)
++			return NULL;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_mdeq);
++
++#if defined(DEBUG)
++/* pretty hex print a pkt buffer chain */
++void brcmu_prpkt(const char *msg, struct sk_buff *p0)
++{
++	struct sk_buff *p;
++
++	if (msg && (msg[0] != '\0'))
++		pr_debug("%s:\n", msg);
++
++	for (p = p0; p; p = p->next)
++		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
++}
++EXPORT_SYMBOL(brcmu_prpkt);
++
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++	struct va_format vaf;
++	va_list args;
++
++	va_start(args, fmt);
++
++	vaf.fmt = fmt;
++	vaf.va = &args;
++
++	pr_debug("%pV", &vaf);
++
++	va_end(args);
++
++	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size);
++}
++EXPORT_SYMBOL(brcmu_dbg_hex_dump);
++#endif				/* defined(DEBUG) */
+diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+new file mode 100644
+index 0000000..333193f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_HW_IDS_H_
++#define	_BRCM_HW_IDS_H_
++
++#define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
++
++#define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
++#define BCM43224_D11N_ID_VEN1	0x0576	/* Vendor specific 43224 802.11n db */
++
++#define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
++
++#define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
++#define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
++
++/* Chipcommon Core Chip IDs */
++#define BCM4313_CHIP_ID		0x4313
++#define BCM43224_CHIP_ID	43224
++#define BCM43225_CHIP_ID	43225
++#define BCM43235_CHIP_ID	43235
++#define BCM43236_CHIP_ID	43236
++#define BCM43238_CHIP_ID	43238
++#define BCM4329_CHIP_ID		0x4329
++#define BCM4330_CHIP_ID		0x4330
++#define BCM4331_CHIP_ID		0x4331
++
++#endif				/* _BRCM_HW_IDS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+new file mode 100644
+index 0000000..477b92a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+@@ -0,0 +1,196 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_UTILS_H_
++#define	_BRCMU_UTILS_H_
++
++#include <linux/skbuff.h>
++
++/*
++ * Spin at most 'us' microseconds while 'exp' is true.
++ * Caller should explicitly test 'exp' when this completes
++ * and take appropriate error action if 'exp' is still true.
++ */
++#define SPINWAIT(exp, us) { \
++	uint countdown = (us) + 9; \
++	while ((exp) && (countdown >= 10)) {\
++		udelay(10); \
++		countdown -= 10; \
++	} \
++}
++
++/* osl multi-precedence packet queue */
++#define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
++#define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
++
++#define BCME_STRLEN		64	/* Max string length for BCM errors */
++
++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
++#define	PKTBUFSZ	2048
++
++#ifndef setbit
++#ifndef NBBY			/* the BSD family defines NBBY */
++#define	NBBY	8		/* 8 bits per byte */
++#endif				/* #ifndef NBBY */
++#define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
++#define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
++#define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
++#define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
++#endif				/* setbit */
++
++#define	NBITS(type)	(sizeof(type) * 8)
++#define NBITVAL(nbits)	(1 << (nbits))
++#define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
++#define	NBITMASK(nbits)	MAXBITVAL(nbits)
++#define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
++
++/* crc defines */
++#define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
++#define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
++
++/* 18-bytes of Ethernet address buffer length */
++#define ETHER_ADDR_STR_LEN	18
++
++struct pktq_prec {
++	struct sk_buff_head skblist;
++	u16 max;		/* maximum number of queued packets */
++};
++
++/* multi-priority pkt queue */
++struct pktq {
++	u16 num_prec;	/* number of precedences in use */
++	u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
++	u16 max;	/* total max packets */
++	u16 len;	/* total number of packets */
++	/*
++	 * q array must be last since # of elements can be either
++	 * PKTQ_MAX_PREC or 1
++	 */
++	struct pktq_prec q[PKTQ_MAX_PREC];
++};
++
++/* operations on a specific precedence in packet queue */
++
++static inline int pktq_plen(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen;
++}
++
++static inline int pktq_pavail(struct pktq *pq, int prec)
++{
++	return pq->q[prec].max - pq->q[prec].skblist.qlen;
++}
++
++static inline bool pktq_pfull(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen >= pq->q[prec].max;
++}
++
++static inline bool pktq_pempty(struct pktq *pq, int prec)
++{
++	return skb_queue_empty(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
++{
++	return skb_peek(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
++{
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++
++extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				 struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++				      struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
++extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
++
++/* packet primitives */
++extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
++extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
++
++/* Empty the queue at particular precedence level */
++/* callback function fn(pkt, arg) returns true if pkt belongs to if */
++extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
++	bool dir, bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* operations on a set of precedences in packet queue */
++
++extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
++extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++	int *prec_out);
++
++/* operations on packet queue as a whole */
++
++static inline int pktq_len(struct pktq *pq)
++{
++	return (int)pq->len;
++}
++
++static inline int pktq_max(struct pktq *pq)
++{
++	return (int)pq->max;
++}
++
++static inline int pktq_avail(struct pktq *pq)
++{
++	return (int)(pq->max - pq->len);
++}
++
++static inline bool pktq_full(struct pktq *pq)
++{
++	return pq->len >= pq->max;
++}
++
++static inline bool pktq_empty(struct pktq *pq)
++{
++	return pq->len == 0;
++}
++
++extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
++/* prec_out may be NULL if caller is not interested in return value */
++extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
++extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* externs */
++/* ip address */
++struct ipv4_addr;
++
++
++/* externs */
++/* format/print */
++#ifdef DEBUG
++extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
++#else
++#define brcmu_prpkt(a, b)
++#endif				/* DEBUG */
++
++#ifdef DEBUG
++extern __printf(3, 4)
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
++#else
++__printf(3, 4)
++static inline
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++}
++#endif
++
++#endif				/* _BRCMU_UTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+new file mode 100644
+index 0000000..f10d302
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+@@ -0,0 +1,239 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_WIFI_H_
++#define	_BRCMU_WIFI_H_
++
++#include <linux/if_ether.h>		/* for ETH_ALEN */
++#include <linux/ieee80211.h>		/* for WLAN_PMKID_LEN */
++
++/*
++ * A chanspec (u16) holds the channel number, band, bandwidth and control
++ * sideband
++ */
++
++/* channel defines */
++#define CH_UPPER_SB			0x01
++#define CH_LOWER_SB			0x02
++#define CH_EWA_VALID			0x04
++#define CH_20MHZ_APART			4
++#define CH_10MHZ_APART			2
++#define CH_5MHZ_APART			1 /* 2G band channels are 5 Mhz apart */
++#define CH_MAX_2G_CHANNEL		14	/* Max channel in 2G band */
++#define BRCM_MAX_2G_CHANNEL	CH_MAX_2G_CHANNEL	/* legacy define */
++
++/* bandstate array indices */
++#define BAND_2G_INDEX		0	/* wlc->bandstate[x] index */
++#define BAND_5G_INDEX		1	/* wlc->bandstate[x] index */
++
++/*
++ * max # supported channels. The max channel no is 216, this is that + 1
++ * rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
++ * u8's all over
++*/
++#define	MAXCHANNEL		224
++
++#define WL_CHANSPEC_CHAN_MASK		0x00ff
++#define WL_CHANSPEC_CHAN_SHIFT		0
++
++#define WL_CHANSPEC_CTL_SB_MASK		0x0300
++#define WL_CHANSPEC_CTL_SB_SHIFT	     8
++#define WL_CHANSPEC_CTL_SB_LOWER	0x0100
++#define WL_CHANSPEC_CTL_SB_UPPER	0x0200
++#define WL_CHANSPEC_CTL_SB_NONE		0x0300
++
++#define WL_CHANSPEC_BW_MASK		0x0C00
++#define WL_CHANSPEC_BW_SHIFT		    10
++#define WL_CHANSPEC_BW_10		0x0400
++#define WL_CHANSPEC_BW_20		0x0800
++#define WL_CHANSPEC_BW_40		0x0C00
++
++#define WL_CHANSPEC_BAND_MASK		0xf000
++#define WL_CHANSPEC_BAND_SHIFT		12
++#define WL_CHANSPEC_BAND_5G		0x1000
++#define WL_CHANSPEC_BAND_2G		0x2000
++#define INVCHANSPEC			255
++
++/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
++#define WF_CHAN_FACTOR_2_4_G		4814	/* 2.4 GHz band, 2407 MHz */
++#define WF_CHAN_FACTOR_5_G		10000	/* 5   GHz band, 5000 MHz */
++#define WF_CHAN_FACTOR_4_G		8000	/* 4.9 GHz band for Japan */
++
++#define CHSPEC_CHANNEL(chspec)	((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
++#define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
++
++#define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
++#define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
++
++#define CHSPEC_IS10(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
++
++#define CHSPEC_IS20(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
++
++#ifndef CHSPEC_IS40
++#define CHSPEC_IS40(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
++#endif
++
++#define CHSPEC_IS5G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
++
++#define CHSPEC_IS2G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
++
++#define CHSPEC_SB_NONE(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
++
++#define CHSPEC_SB_UPPER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
++
++#define CHSPEC_SB_LOWER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
++
++#define CHSPEC_CTL_CHAN(chspec) \
++	((CHSPEC_SB_LOWER(chspec)) ? \
++	(lower_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
++	(upper_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))))
++
++#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
++
++#define CHANSPEC_STR_LEN    8
++
++static inline int lower_20_sb(int channel)
++{
++	return channel > CH_10MHZ_APART ? (channel - CH_10MHZ_APART) : 0;
++}
++
++static inline int upper_20_sb(int channel)
++{
++	return (channel < (MAXCHANNEL - CH_10MHZ_APART)) ?
++	       channel + CH_10MHZ_APART : 0;
++}
++
++static inline int chspec_bandunit(u16 chspec)
++{
++	return CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX;
++}
++
++static inline u16 ch20mhz_chspec(int channel)
++{
++	u16 rc = channel <= CH_MAX_2G_CHANNEL ?
++		 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G;
++
++	return	(u16)((u16)channel | WL_CHANSPEC_BW_20 |
++		      WL_CHANSPEC_CTL_SB_NONE | rc);
++}
++
++static inline int next_20mhz_chan(int channel)
++{
++	return channel < (MAXCHANNEL - CH_20MHZ_APART) ?
++	       channel + CH_20MHZ_APART : 0;
++}
++
++/* defined rate in 500kbps */
++#define BRCM_MAXRATE	108	/* in 500kbps units */
++#define BRCM_RATE_1M	2	/* in 500kbps units */
++#define BRCM_RATE_2M	4	/* in 500kbps units */
++#define BRCM_RATE_5M5	11	/* in 500kbps units */
++#define BRCM_RATE_11M	22	/* in 500kbps units */
++#define BRCM_RATE_6M	12	/* in 500kbps units */
++#define BRCM_RATE_9M	18	/* in 500kbps units */
++#define BRCM_RATE_12M	24	/* in 500kbps units */
++#define BRCM_RATE_18M	36	/* in 500kbps units */
++#define BRCM_RATE_24M	48	/* in 500kbps units */
++#define BRCM_RATE_36M	72	/* in 500kbps units */
++#define BRCM_RATE_48M	96	/* in 500kbps units */
++#define BRCM_RATE_54M	108	/* in 500kbps units */
++
++#define BRCM_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
++
++#define MCSSET_LEN	16
++
++static inline bool ac_bitmap_tst(u8 bitmap, int prec)
++{
++	return (bitmap & (1 << (prec))) != 0;
++}
++
++/* Enumerate crypto algorithms */
++#define	CRYPTO_ALGO_OFF			0
++#define	CRYPTO_ALGO_WEP1		1
++#define	CRYPTO_ALGO_TKIP		2
++#define	CRYPTO_ALGO_WEP128		3
++#define CRYPTO_ALGO_AES_CCM		4
++#define CRYPTO_ALGO_AES_RESERVED1	5
++#define CRYPTO_ALGO_AES_RESERVED2	6
++#define CRYPTO_ALGO_NALG		7
++
++/* wireless security bitvec */
++
++#define WEP_ENABLED		0x0001
++#define TKIP_ENABLED		0x0002
++#define AES_ENABLED		0x0004
++#define WSEC_SWFLAG		0x0008
++/* to go into transition mode without setting wep */
++#define SES_OW_ENABLED		0x0040
++
++/* WPA authentication mode bitvec */
++#define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
++#define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
++#define WPA_AUTH_UNSPECIFIED	0x0002	/* over 802.1x */
++#define WPA_AUTH_PSK		0x0004	/* Pre-shared key */
++#define WPA_AUTH_RESERVED1	0x0008
++#define WPA_AUTH_RESERVED2	0x0010
++
++#define WPA2_AUTH_RESERVED1	0x0020
++#define WPA2_AUTH_UNSPECIFIED	0x0040	/* over 802.1x */
++#define WPA2_AUTH_PSK		0x0080	/* Pre-shared key */
++#define WPA2_AUTH_RESERVED3	0x0200
++#define WPA2_AUTH_RESERVED4	0x0400
++#define WPA2_AUTH_RESERVED5	0x0800
++
++/* pmkid */
++#define	MAXPMKID		16
++
++#define DOT11_DEFAULT_RTS_LEN		2347
++#define DOT11_DEFAULT_FRAG_LEN		2346
++
++#define DOT11_ICV_AES_LEN		8
++#define DOT11_QOS_LEN			2
++#define DOT11_IV_MAX_LEN		8
++#define DOT11_A4_HDR_LEN		30
++
++#define HT_CAP_RX_STBC_NO		0x0
++#define HT_CAP_RX_STBC_ONE_STREAM	0x1
++
++struct pmkid {
++	u8 BSSID[ETH_ALEN];
++	u8 PMKID[WLAN_PMKID_LEN];
++};
++
++struct pmkid_list {
++	__le32 npmkid;
++	struct pmkid pmkid[1];
++};
++
++struct pmkid_cand {
++	u8 BSSID[ETH_ALEN];
++	u8 preauth;
++};
++
++struct pmkid_cand_list {
++	u32 npmkid_cand;
++	struct pmkid_cand pmkid_cand[1];
++};
++
++#endif				/* _BRCMU_WIFI_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h
+new file mode 100644
+index 0000000..f96834a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
+@@ -0,0 +1,286 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_SBCHIPC_H
++#define	_SBCHIPC_H
++
++#include "defs.h"		/* for PAD macro */
++
++#define CHIPCREGOFFS(field)	offsetof(struct chipcregs, field)
++
++struct chipcregs {
++	u32 chipid;		/* 0x0 */
++	u32 capabilities;
++	u32 corecontrol;	/* corerev >= 1 */
++	u32 bist;
++
++	/* OTP */
++	u32 otpstatus;	/* 0x10, corerev >= 10 */
++	u32 otpcontrol;
++	u32 otpprog;
++	u32 otplayout;	/* corerev >= 23 */
++
++	/* Interrupt control */
++	u32 intstatus;	/* 0x20 */
++	u32 intmask;
++
++	/* Chip specific regs */
++	u32 chipcontrol;	/* 0x28, rev >= 11 */
++	u32 chipstatus;	/* 0x2c, rev >= 11 */
++
++	/* Jtag Master */
++	u32 jtagcmd;		/* 0x30, rev >= 10 */
++	u32 jtagir;
++	u32 jtagdr;
++	u32 jtagctrl;
++
++	/* serial flash interface registers */
++	u32 flashcontrol;	/* 0x40 */
++	u32 flashaddress;
++	u32 flashdata;
++	u32 PAD[1];
++
++	/* Silicon backplane configuration broadcast control */
++	u32 broadcastaddress;	/* 0x50 */
++	u32 broadcastdata;
++
++	/* gpio - cleared only by power-on-reset */
++	u32 gpiopullup;	/* 0x58, corerev >= 20 */
++	u32 gpiopulldown;	/* 0x5c, corerev >= 20 */
++	u32 gpioin;		/* 0x60 */
++	u32 gpioout;		/* 0x64 */
++	u32 gpioouten;	/* 0x68 */
++	u32 gpiocontrol;	/* 0x6C */
++	u32 gpiointpolarity;	/* 0x70 */
++	u32 gpiointmask;	/* 0x74 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioevent;
++	u32 gpioeventintmask;
++
++	/* Watchdog timer */
++	u32 watchdog;	/* 0x80 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioeventintpolarity;
++
++	/* GPIO based LED powersave registers corerev >= 16 */
++	u32 gpiotimerval;	/* 0x88 */
++	u32 gpiotimeroutmask;
++
++	/* clock control */
++	u32 clockcontrol_n;	/* 0x90 */
++	u32 clockcontrol_sb;	/* aka m0 */
++	u32 clockcontrol_pci;	/* aka m1 */
++	u32 clockcontrol_m2;	/* mii/uart/mipsref */
++	u32 clockcontrol_m3;	/* cpu */
++	u32 clkdiv;		/* corerev >= 3 */
++	u32 gpiodebugsel;	/* corerev >= 28 */
++	u32 capabilities_ext;	/* 0xac  */
++
++	/* pll delay registers (corerev >= 4) */
++	u32 pll_on_delay;	/* 0xb0 */
++	u32 fref_sel_delay;
++	u32 slow_clk_ctl;	/* 5 < corerev < 10 */
++	u32 PAD;
++
++	/* Instaclock registers (corerev >= 10) */
++	u32 system_clk_ctl;	/* 0xc0 */
++	u32 clkstatestretch;
++	u32 PAD[2];
++
++	/* Indirect backplane access (corerev >= 22) */
++	u32 bp_addrlow;	/* 0xd0 */
++	u32 bp_addrhigh;
++	u32 bp_data;
++	u32 PAD;
++	u32 bp_indaccess;
++	u32 PAD[3];
++
++	/* More clock dividers (corerev >= 32) */
++	u32 clkdiv2;
++	u32 PAD[2];
++
++	/* In AI chips, pointer to erom */
++	u32 eromptr;		/* 0xfc */
++
++	/* ExtBus control registers (corerev >= 3) */
++	u32 pcmcia_config;	/* 0x100 */
++	u32 pcmcia_memwait;
++	u32 pcmcia_attrwait;
++	u32 pcmcia_iowait;
++	u32 ide_config;
++	u32 ide_memwait;
++	u32 ide_attrwait;
++	u32 ide_iowait;
++	u32 prog_config;
++	u32 prog_waitcount;
++	u32 flash_config;
++	u32 flash_waitcount;
++	u32 SECI_config;	/* 0x130 SECI configuration */
++	u32 PAD[3];
++
++	/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
++	u32 eci_output;	/* 0x140 */
++	u32 eci_control;
++	u32 eci_inputlo;
++	u32 eci_inputmi;
++	u32 eci_inputhi;
++	u32 eci_inputintpolaritylo;
++	u32 eci_inputintpolaritymi;
++	u32 eci_inputintpolarityhi;
++	u32 eci_intmasklo;
++	u32 eci_intmaskmi;
++	u32 eci_intmaskhi;
++	u32 eci_eventlo;
++	u32 eci_eventmi;
++	u32 eci_eventhi;
++	u32 eci_eventmasklo;
++	u32 eci_eventmaskmi;
++	u32 eci_eventmaskhi;
++	u32 PAD[3];
++
++	/* SROM interface (corerev >= 32) */
++	u32 sromcontrol;	/* 0x190 */
++	u32 sromaddress;
++	u32 sromdata;
++	u32 PAD[17];
++
++	/* Clock control and hardware workarounds (corerev >= 20) */
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 PAD[70];
++
++	/* UARTs */
++	u8 uart0data;	/* 0x300 */
++	u8 uart0imr;
++	u8 uart0fcr;
++	u8 uart0lcr;
++	u8 uart0mcr;
++	u8 uart0lsr;
++	u8 uart0msr;
++	u8 uart0scratch;
++	u8 PAD[248];		/* corerev >= 1 */
++
++	u8 uart1data;	/* 0x400 */
++	u8 uart1imr;
++	u8 uart1fcr;
++	u8 uart1lcr;
++	u8 uart1mcr;
++	u8 uart1lsr;
++	u8 uart1msr;
++	u8 uart1scratch;
++	u32 PAD[126];
++
++	/* PMU registers (corerev >= 20) */
++	u32 pmucontrol;	/* 0x600 */
++	u32 pmucapabilities;
++	u32 pmustatus;
++	u32 res_state;
++	u32 res_pending;
++	u32 pmutimer;
++	u32 min_res_mask;
++	u32 max_res_mask;
++	u32 res_table_sel;
++	u32 res_dep_mask;
++	u32 res_updn_timer;
++	u32 res_timer;
++	u32 clkstretch;
++	u32 pmuwatchdog;
++	u32 gpiosel;		/* 0x638, rev >= 1 */
++	u32 gpioenable;	/* 0x63c, rev >= 1 */
++	u32 res_req_timer_sel;
++	u32 res_req_timer;
++	u32 res_req_mask;
++	u32 PAD;
++	u32 chipcontrol_addr;	/* 0x650 */
++	u32 chipcontrol_data;	/* 0x654 */
++	u32 regcontrol_addr;
++	u32 regcontrol_data;
++	u32 pllcontrol_addr;
++	u32 pllcontrol_data;
++	u32 pmustrapopt;	/* 0x668, corerev >= 28 */
++	u32 pmu_xtalfreq;	/* 0x66C, pmurev >= 10 */
++	u32 PAD[100];
++	u16 sromotp[768];
++};
++
++/* chipid */
++#define	CID_ID_MASK		0x0000ffff	/* Chip Id mask */
++#define	CID_REV_MASK		0x000f0000	/* Chip Revision mask */
++#define	CID_REV_SHIFT		16	/* Chip Revision shift */
++#define	CID_PKG_MASK		0x00f00000	/* Package Option mask */
++#define	CID_PKG_SHIFT		20	/* Package Option shift */
++#define	CID_CC_MASK		0x0f000000	/* CoreCount (corerev >= 4) */
++#define CID_CC_SHIFT		24
++#define	CID_TYPE_MASK		0xf0000000	/* Chip Type */
++#define CID_TYPE_SHIFT		28
++
++/* capabilities */
++#define	CC_CAP_UARTS_MASK	0x00000003	/* Number of UARTs */
++#define CC_CAP_MIPSEB		0x00000004	/* MIPS is in big-endian mode */
++#define CC_CAP_UCLKSEL		0x00000018	/* UARTs clock select */
++/* UARTs are driven by internal divided clock */
++#define CC_CAP_UINTCLK		0x00000008
++#define CC_CAP_UARTGPIO		0x00000020	/* UARTs own GPIOs 15:12 */
++#define CC_CAP_EXTBUS_MASK	0x000000c0	/* External bus mask */
++#define CC_CAP_EXTBUS_NONE	0x00000000	/* No ExtBus present */
++#define CC_CAP_EXTBUS_FULL	0x00000040	/* ExtBus: PCMCIA, IDE & Prog */
++#define CC_CAP_EXTBUS_PROG	0x00000080	/* ExtBus: ProgIf only */
++#define	CC_CAP_FLASH_MASK	0x00000700	/* Type of flash */
++#define	CC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
++#define CC_CAP_PWR_CTL		0x00040000	/* Power control */
++#define CC_CAP_OTPSIZE		0x00380000	/* OTP Size (0 = none) */
++#define CC_CAP_OTPSIZE_SHIFT	19	/* OTP Size shift */
++#define CC_CAP_OTPSIZE_BASE	5	/* OTP Size base */
++#define CC_CAP_JTAGP		0x00400000	/* JTAG Master Present */
++#define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
++#define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
++#define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
++#define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
++/* Nand flash present, rev >= 35 */
++#define	CC_CAP_NFLASH		0x80000000
++
++#define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
++/* GSIO (spi/i2c) present, rev >= 37 */
++#define	CC_CAP2_GSIO		0x00000002
++
++/* pmucapabilities */
++#define PCAP_REV_MASK	0x000000ff
++#define PCAP_RC_MASK	0x00001f00
++#define PCAP_RC_SHIFT	8
++#define PCAP_TC_MASK	0x0001e000
++#define PCAP_TC_SHIFT	13
++#define PCAP_PC_MASK	0x001e0000
++#define PCAP_PC_SHIFT	17
++#define PCAP_VC_MASK	0x01e00000
++#define PCAP_VC_SHIFT	21
++#define PCAP_CC_MASK	0x1e000000
++#define PCAP_CC_SHIFT	25
++#define PCAP5_PC_MASK	0x003e0000	/* PMU corerev >= 5 */
++#define PCAP5_PC_SHIFT	17
++#define PCAP5_VC_MASK	0x07c00000
++#define PCAP5_VC_SHIFT	22
++#define PCAP5_CC_MASK	0xf8000000
++#define PCAP5_CC_SHIFT	27
++
++/*
++* Maximum delay for the PMU state transition in us.
++* This is an upper bound intended for spinwaits etc.
++*/
++#define PMU_MAX_TRANSITION_DLY	15000
++
++#endif				/* _SBCHIPC_H */
+diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
+new file mode 100644
+index 0000000..f0d8c04
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/defs.h
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DEFS_H_
++#define	_BRCM_DEFS_H_
++
++#include <linux/types.h>
++
++#define	SI_BUS			0
++#define	PCI_BUS			1
++#define	PCMCIA_BUS		2
++#define SDIO_BUS		3
++#define JTAG_BUS		4
++#define USB_BUS			5
++#define SPI_BUS			6
++
++#define	OFF	0
++#define	ON	1		/* ON = 1 */
++#define	AUTO	(-1)		/* Auto = -1 */
++
++/*
++ * Priority definitions according 802.1D
++ */
++#define	PRIO_8021D_NONE		2
++#define	PRIO_8021D_BK		1
++#define	PRIO_8021D_BE		0
++#define	PRIO_8021D_EE		3
++#define	PRIO_8021D_CL		4
++#define	PRIO_8021D_VI		5
++#define	PRIO_8021D_VO		6
++#define	PRIO_8021D_NC		7
++
++#define	MAXPRIO			7
++#define NUMPRIO			(MAXPRIO + 1)
++
++#define WL_NUMRATES		16	/* max # of rates in a rateset */
++
++#define BRCM_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
++
++#define BRCM_SET_CHANNEL	30
++#define BRCM_SET_SRL		32
++#define BRCM_SET_LRL		34
++#define BRCM_SET_BCNPRD		76
++
++#define BRCM_GET_CURR_RATESET	114	/* current rateset */
++#define BRCM_GET_PHYLIST	180
++
++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
++
++#define WL_RADIO_SW_DISABLE		(1<<0)
++#define WL_RADIO_HW_DISABLE		(1<<1)
++/* some countries don't support any channel */
++#define WL_RADIO_COUNTRY_DISABLE	(1<<3)
++
++/* Override bit for SET_TXPWR.  if set, ignore other level limits */
++#define WL_TXPWR_OVERRIDE	(1U<<31)
++
++/* band types */
++#define	BRCM_BAND_AUTO		0	/* auto-select */
++#define	BRCM_BAND_5G		1	/* 5 Ghz */
++#define	BRCM_BAND_2G		2	/* 2.4 Ghz */
++#define	BRCM_BAND_ALL		3	/* all bands */
++
++/* Values for PM */
++#define PM_OFF	0
++#define PM_MAX	1
++
++/* Message levels */
++#define LOG_ERROR_VAL		0x00000001
++#define LOG_TRACE_VAL		0x00000002
++
++#define PM_OFF	0
++#define PM_MAX	1
++#define PM_FAST 2
++
++/*
++ * Sonics Configuration Space Registers.
++ */
++
++/* core sbconfig regs are top 256bytes of regs */
++#define	SBCONFIGOFF		0xf00
++
++/* cpp contortions to concatenate w/arg prescan */
++#ifndef	PAD
++#define	_PADLINE(line)	pad ## line
++#define	_XSTR(line)	_PADLINE(line)
++#define	PAD		_XSTR(__LINE__)
++#endif
++
++#endif				/* _BRCM_DEFS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h
+new file mode 100644
+index 0000000..4e9b7e4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/soc.h
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SOC_H
++#define	_BRCM_SOC_H
++
++#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
++
++/* core codes */
++#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
++#define	CC_CORE_ID		0x800	/* chipcommon core */
++#define	ILINE20_CORE_ID		0x801	/* iline20 core */
++#define	SRAM_CORE_ID		0x802	/* sram core */
++#define	SDRAM_CORE_ID		0x803	/* sdram core */
++#define	PCI_CORE_ID		0x804	/* pci core */
++#define	MIPS_CORE_ID		0x805	/* mips core */
++#define	ENET_CORE_ID		0x806	/* enet mac core */
++#define	CODEC_CORE_ID		0x807	/* v90 codec core */
++#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
++#define	ADSL_CORE_ID		0x809	/* ADSL core */
++#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
++#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
++#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
++#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
++#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
++#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
++#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
++#define	EXTIF_CORE_ID		0x811	/* external interface core */
++#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
++#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
++#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
++#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
++#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
++#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
++#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
++#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
++#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
++#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
++#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
++#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
++#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
++#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
++#define	PCIE_CORE_ID		0x820	/* pci express core */
++#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
++#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
++#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
++#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
++#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
++#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
++#define	PMU_CORE_ID		0x827	/* PMU core */
++#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
++#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
++#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
++#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
++#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
++#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
++#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
++#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
++#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
++#define	SC_CORE_ID		0x831	/* shared common core */
++#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
++#define	SPIH_CORE_ID		0x833	/* SPI host core */
++#define	I2S_CORE_ID		0x834	/* I2S core */
++#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
++#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
++#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
++#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
++					 * maps all unused address ranges
++					 */
++
++/* Common core control flags */
++#define	SICF_BIST_EN		0x8000
++#define	SICF_PME_EN		0x4000
++#define	SICF_CORE_BITS		0x3ffc
++#define	SICF_FGC		0x0002
++#define	SICF_CLOCK_EN		0x0001
++
++/* Common core status flags */
++#define	SISF_BIST_DONE		0x8000
++#define	SISF_BIST_ERROR		0x4000
++#define	SISF_GATED_CLK		0x2000
++#define	SISF_DMA64		0x1000
++#define	SISF_CORE_BITS		0x0fff
++
++#endif				/* _BRCM_SOC_H */
+-- 
+1.7.9.5
+
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): add brcm80211 driver backported from v3.5 John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 14:32     ` Otavio Salvador
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend John Weber
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Enables Broadcom FullMAC driver in kernel defconfig for Wandboard Dual.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 .../linux-imx-3.0.35/wandboard-dual/defconfig      |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
index cbc3c34..1657ea1 100644
--- a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
@@ -1024,6 +1024,12 @@ CONFIG_ATH_COMMON=m
 # CONFIG_ATH_DEBUG is not set
 CONFIG_ATH6KL=m
 # CONFIG_ATH6KL_DEBUG is not set
+CONFIG_BRCMUTIL=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_SDIO=y
+# CONFIG_BRCMFMAC_SDIO_OOB is not set
+# CONFIG_BRCMFMAC_USB is not set
+CONFIG_BRCMDBG=y
 CONFIG_HOSTAP=y
 # CONFIG_HOSTAP_FIRMWARE is not set
 # CONFIG_IWM is not set
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
                     ` (2 preceding siblings ...)
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 14:31     ` Otavio Salvador
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329 John Weber
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Modifies bbappend to utilize the new brcm80211 patches and fixes.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 recipes-kernel/linux/linux-imx_3.0.35.bbappend |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/recipes-kernel/linux/linux-imx_3.0.35.bbappend b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
index f1abbf9..7317478 100644
--- a/recipes-kernel/linux/linux-imx_3.0.35.bbappend
+++ b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
@@ -1,10 +1,13 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
 
-PRINC := "${@int(PRINC) + 1}"
+PRINC := "${@int(PRINC) + 2}"
 
 # Wandboard-specific patches
 SRC_URI_append_wandboard-dual = " \
    file://wandboard-dual/0001-Linux-3.0.35-Add-wandboard-dual-support.patch \
+   file://wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch \
+   file://wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch \
+   file://wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch \
 "
 # Add support for the Congatec qmx6 board
 SRC_URI_append_cgtqmx6 = " file://cgtqmx6/cgtqmx6.patch"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
                     ` (3 preceding siblings ...)
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 14:31     ` Otavio Salvador
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] conf/machine: add firmware rrecomends to wandboard-dual John Weber
  2013-03-16 14:23   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data Otavio Salvador
  6 siblings, 1 reply; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Adds linux-firmware bbappend recipe to provide support for the Broadcom
BCM4329 Wifi device.  Also adds a .txt file for nvram support.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 .../linux-firmware/brcmfmac-sdio.txt               |   70 ++++++++++++++++++++
 .../linux-firmware/linux-firmware_git.bbappend     |   28 ++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 recipes-kernel/linux-firmware/linux-firmware/brcmfmac-sdio.txt
 create mode 100644 recipes-kernel/linux-firmware/linux-firmware_git.bbappend

diff --git a/recipes-kernel/linux-firmware/linux-firmware/brcmfmac-sdio.txt b/recipes-kernel/linux-firmware/linux-firmware/brcmfmac-sdio.txt
new file mode 100644
index 0000000..53e4bba
--- /dev/null
+++ b/recipes-kernel/linux-firmware/linux-firmware/brcmfmac-sdio.txt
@@ -0,0 +1,70 @@
+# bcm4329 NVRAM file for Wandboard Dual
+# $Copyright (C) 2008 Broadcom Corporation$
+# $id$
+
+sromrev=3
+vendid=0x14e4
+devid=0x432f
+boardtype=0x53e
+
+boardrev=0x41
+
+#boardflags=0x1200
+boardflags=0x200
+
+# Specify the xtalfreq if it is otherthan 38.4MHz
+xtalfreq=37400
+
+aa2g=3
+aa5g=0
+
+ag0=255
+#tri2g=0x64
+
+# 11g paparams
+pa0b0=5542,5542,5542
+pa0b1=64244,64244,64244
+pa0b2=65202,65202,65202
+
+pa0itssit=62
+pa0maxpwr=74
+opo=0
+mcs2gpo0=0x6666
+mcs2gpo1=0x6666
+
+# 11g rssi params
+rssismf2g=0xa,0xa,0xa
+rssismc2g=0xb,0xb,0xb
+rssisav2g=0x3,0x3,0x3
+bxa2g=0
+
+# country code
+ccode=ALL
+cctl=0x0
+cckdigfilttype=0
+ofdmdigfilttype=1
+
+rxpo2g=0
+
+boardnum=1
+macaddr=00:90:4c:c5:00:34
+
+# xtal pu and pd time control variable
+# pu time is driver default (0x1501)
+#r13t=0x1501
+
+#######
+nocrc=1
+
+#for mfgc
+otpimagesize=182
+
+# sdio extra configs
+hwhdr=0x05ffff031030031003100000
+
+#This generates empty F1, F2 and F3 tuple chains, and may be used if the host SDIO stack does not require the standard tuples.
+#RAW1=80 02 fe ff
+
+#This includes the standard FUNCID and FUNCE tuples in the F1, F2, F3 and common CIS.
+RAW1=80 32 fe 21 02 0c 00 22 2a 01 01 00 00 c5 0 e6 00 00 00 00 00 40 00 00 ff ff 80 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 20 04 D0 2 29 43 21 02 0c 00 22 04 00 20 00 5A
+nvramver=4.218.214.0
diff --git a/recipes-kernel/linux-firmware/linux-firmware_git.bbappend b/recipes-kernel/linux-firmware/linux-firmware_git.bbappend
new file mode 100644
index 0000000..47cf682
--- /dev/null
+++ b/recipes-kernel/linux-firmware/linux-firmware_git.bbappend
@@ -0,0 +1,28 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}"
+
+PRINC := "${@int(PRINC) + 1}"
+
+SRC_URI_append = " \
+   file://brcmfmac-sdio.txt \
+"
+LIC_FILES_CHKSUM += "file://LICENCE.broadcom_bcm43xx;md5=3160c14df7228891b868060e1951dfbc\
+"
+
+do_install_append() {
+	# Broadcom BCM4329 SDIO
+	cp -r ${D}/lib/firmware/brcm/brcmfmac4329.bin \
+              ${D}/lib/firmware/brcm/brcmfmac-sdio.bin
+	cp -r ${WORKDIR}/brcmfmac-sdio.txt \ 
+              ${D}/lib/firmware/brcm
+	cp -r ${D}/lib/firmware/LICENCE.broadcom_bcm43xx \ 
+              ${D}/lib/firmware/brcm
+}
+
+PACKAGES =+ "${PN}-bcm4329"
+
+LICENSE_${PN}-bcm4329 = "Firmware-bcm4329"
+FILES_${PN}-bcm4329 = " \
+  /lib/firmware/brcm/brcmfmac-sdio.bin \
+  /lib/firmware/brcm/brcmfmac-sdio.txt \
+  /lib/firmware/brcm/LICENCE.broadcom_bcm43xx \
+"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH] conf/machine: add firmware rrecomends to wandboard-dual
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
                     ` (4 preceding siblings ...)
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329 John Weber
@ 2013-03-16 13:45   ` John Weber
  2013-03-16 14:23   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data Otavio Salvador
  6 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-16 13:45 UTC (permalink / raw)
  To: meta-freescale

Adds a MACHINE_EXTRA_RRECOMMENDS line to wandboard-dual conf file to add 
firmware for BCM4329 wifi device to the rootfs image.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 conf/machine/wandboard-dual.conf |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/conf/machine/wandboard-dual.conf b/conf/machine/wandboard-dual.conf
index f827be7..f8980cc 100644
--- a/conf/machine/wandboard-dual.conf
+++ b/conf/machine/wandboard-dual.conf
@@ -18,3 +18,5 @@ UBOOT_PADDING = "2"
 SERIAL_CONSOLE = "115200 ttymxc0"
 
 MACHINE_FEATURES += " pci wifi bluetooth"
+
+MACHINE_EXTRA_RRECOMMENDS += "linux-firmware-bcm4329"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
                     ` (5 preceding siblings ...)
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] conf/machine: add firmware rrecomends to wandboard-dual John Weber
@ 2013-03-16 14:23   ` Otavio Salvador
  6 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-16 14:23 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
> Fixes esdhc platform data for wandboard dual.  Without this fix,
> wandboard-dual is unable to load firmware from the filesystem into
> the kernel.
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>
> ---
>  ...002-wandboard-dual-fix-sdhc-platform-data.patch |   53 ++++++++++++++++++++
>  1 files changed, 56 insertions(+), 2 deletions(-)
>  create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
>
> diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
> new file mode 100644
> index 0000000..3aefebe
> --- /dev/null
> +++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
> @@ -0,0 +1,53 @@
> +From ea530483ad42e5b9a89934fbdfd57df81b3a90ab Mon Sep 17 00:00:00 2001
> +From: John Weber <rjohnweber@gmail.com>
> +Date: Fri, 15 Mar 2013 08:43:15 -0500
> +Subject: [PATCH] wandboard: fix sdhc platform data
> +
> +Fixes sdhc platfrom data structure to solve a problem when loading
> +the firmware files for the on-board Wifi module on Wandboard-dual.
> +This problem only occured when udev is tasked with loading firmware
> +from the filesystem.
> +
> +Upstream-Status: Pending
> +
> +Signed-off-by: John Weber <rjohnweber@gmail.com>
> +---
> + arch/arm/mach-mx6/board-wand.c |   11 ++++++++---
> + 1 file changed, 8 insertions(+), 3 deletions(-)
> +
> +diff --git a/arch/arm/mach-mx6/board-wand.c b/arch/arm/mach-mx6/board-wand.c
> +index 7f972eb..7be6726 100644
> +--- a/arch/arm/mach-mx6/board-wand.c
> ++++ b/arch/arm/mach-mx6/board-wand.c
> +@@ -184,13 +184,17 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
> +               .cd_gpio                = WAND_SD1_CD,
> +               .wp_gpio                =-EINVAL,
> +               .keep_power_at_suspend  = 1,
> +-              .support_8bit           = 0,
> ++        .support_8bit         = 0,
> ++        .delay_line = 0,

It seems you changed spaces here without need.

> +               .platform_pad_change    = plt_sd_pad_change,
> ++              .cd_type = ESDHC_CD_CONTROLLER,
> +       }, {
> +-              .cd_gpio                =-EINVAL,
> +-              .wp_gpio                =-EINVAL,
> +               .keep_power_at_suspend  = 1,
> +               .platform_pad_change    = plt_sd_pad_change,
> ++              .always_present = 1,
> ++              .support_8bit = 0,
> ++              .delay_line = 0,
> ++              .cd_type = ESDHC_CD_PERMANENT,
> +       }, {
> +               .cd_gpio                = WAND_SD3_CD,
> +               .wp_gpio                = WAND_SD3_WP,
> +@@ -198,6 +202,7 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
> +               .support_8bit           = 0,
> +               .delay_line             = 0,
> +               .platform_pad_change    = plt_sd_pad_change,
> ++              .cd_type = ESDHC_CD_CONTROLLER,
> +       }
> + };
> +
> +--
> +1.7.9.5
> +
> --
> 1.7.9.5
>
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-freescale



-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329 John Weber
@ 2013-03-16 14:31     ` Otavio Salvador
  2013-03-17  0:40       ` John Weber
  0 siblings, 1 reply; 716+ messages in thread
From: Otavio Salvador @ 2013-03-16 14:31 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
> Adds linux-firmware bbappend recipe to provide support for the Broadcom
> BCM4329 Wifi device.  Also adds a .txt file for nvram support.
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

Thinking about how it was done, I'd say you could do it:

 * Make this to split the binaries but without renaming it

 * Add a new recipe (let's say wandboard-wifi-support) which rdepends
on the binary package and installs the .txt file for nvram as well.

So we avoid to make linux-firmware machine specific. We cannot have
more than one package with same contents in filesystem (without being
different recipe name) so we'd need to complicate it a lot, using the
extra recipe makes it easy.


-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend John Weber
@ 2013-03-16 14:31     ` Otavio Salvador
  0 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-16 14:31 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
> Modifies bbappend to utilize the new brcm80211 patches and fixes.
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

Please change the bbappend when adding the patch.

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig John Weber
@ 2013-03-16 14:32     ` Otavio Salvador
  0 siblings, 0 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-16 14:32 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
> Enables Broadcom FullMAC driver in kernel defconfig for Wandboard Dual.
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

I'd prefer you to enable it with the patch which adds the backport.

-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211
  2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
@ 2013-03-16 14:39     ` Otavio Salvador
  2013-03-17  1:08       ` John Weber
  0 siblings, 1 reply; 716+ messages in thread
From: Otavio Salvador @ 2013-03-16 14:39 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
> Removes brcm80211 driver in drivers/staging.  This is meant to be
> applied with a patch to add a backported driver from kernel v3.5
> which is loaded into drivers/net/wireless.
>
> Signed-off-by: John Weber <rjohnweber@gmail.com>

Personally I think the removal and addition of new driver could do in
a single shot in meta-fsl-arm-extra (so you'd still keep two patches
to apply but both here).

> ---
>  ...mx-3.0.35-remove-brcm80211-staging-driver.patch |123141 ++++++++++++++++++++
>  1 files changed, 123142 insertions(+)
>  create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
>
> diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
> new file mode 100644
> index 0000000..96d3ce1
> --- /dev/null
> +++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
> @@ -0,0 +1,123141 @@
> +From 748eb185cad62c456dcd316c941f9835520a946d Mon Sep 17 00:00:00 2001
> +From: John Weber <rjohnweber@gmail.com>
> +Date: Sat, 9 Mar 2013 09:23:58 -0600
> +Subject: [meta-fsl-arm-extra][PATCH 1/2] linux-imx (3.0.35): remove brcm80211
> + staging driver

The subject of internal patch is confusing as it is not for
meta-fsl-arm-extra ;-)

One thing I noticed in this serie is that you didn't export the
patches with the order (PATCH X/Y) which is important so we know the
order to apply them.


-- 
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329
  2013-03-16 14:31     ` Otavio Salvador
@ 2013-03-17  0:40       ` John Weber
  0 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-17  0:40 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

Otavio -

I assume you mean this rename?

+do_install_append() {
+	# Broadcom BCM4329 SDIO
+	cp -r ${D}/lib/firmware/brcm/brcmfmac4329.bin \
+              ${D}/lib/firmware/brcm/brcmfmac-sdio.bin
+	cp -r ${WORKDIR}/brcmfmac-sdio.txt \
+              ${D}/lib/firmware/brcm
+	cp -r ${D}/lib/firmware/LICENCE.broadcom_bcm43xx \
+              ${D}/lib/firmware/brcm
+}

If I do not rename them, then the default kernel module for brcmfmac will not 
find the firmware files because it expects them to be named as above.

 From the driver in the mainline kernel (and also the backported driver, so it 
hasn't changed):

drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c, line 317-320

#define BRCMF_SDIO_FW_NAME      "brcm/brcmfmac-sdio.bin"
#define BRCMF_SDIO_NV_NAME      "brcm/brcmfmac-sdio.txt"
MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);

I'll create a recipe to populate the nvram file separately from the kernel 
firmware.  I can also do the rename there - is that what you are suggesting?  If 
that is the case, then everyone that wants to use the brcmfmac driver will need 
to create their own recipe to do the copy (or a patch to the kernel to rename 
the files that the driver expects).

In the end, I'll submit 2 patches instead of this 1 patch:
- linux-firmware_git.bbappend - which will split the binaries only.
- wandboard-wifi-support.bb - which will add the nvram file (.txt) and rename 
the binaries as the driver expects.

Then the image/machine/conf should only have to include the 
wandboard-wifi-support recipe.  I really don't think that renaming the .bin file 
makes the linux-firmware recipe machine-specific, but I think it should be done 
in the packages-split step when it is filtering out the bcm4329-specific files 
for inclusion into the image.  That way, the user through the selection of 
linux-firmware-bcm4329 definitely gets the bcm4329 firmware file.

John


On 3/16/13 9:31 AM, Otavio Salvador wrote:
> On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
>> Adds linux-firmware bbappend recipe to provide support for the Broadcom
>> BCM4329 Wifi device.  Also adds a .txt file for nvram support.
>>
>> Signed-off-by: John Weber <rjohnweber@gmail.com>
>
> Thinking about how it was done, I'd say you could do it:
>
>   * Make this to split the binaries but without renaming it
>
>   * Add a new recipe (let's say wandboard-wifi-support) which rdepends
> on the binary package and installs the .txt file for nvram as well.
>
> So we avoid to make linux-firmware machine specific. We cannot have
> more than one package with same contents in filesystem (without being
> different recipe name) so we'd need to complicate it a lot, using the
> extra recipe makes it easy.
>
>


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211
  2013-03-16 14:39     ` Otavio Salvador
@ 2013-03-17  1:08       ` John Weber
  0 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-17  1:08 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

Sounds good.  I'll do that in v2.

On 3/16/13 9:39 AM, Otavio Salvador wrote:
> On Sat, Mar 16, 2013 at 10:45 AM, John Weber <rjohnweber@gmail.com> wrote:
>> Removes brcm80211 driver in drivers/staging.  This is meant to be
>> applied with a patch to add a backported driver from kernel v3.5
>> which is loaded into drivers/net/wireless.
>>
>> Signed-off-by: John Weber <rjohnweber@gmail.com>
>
> Personally I think the removal and addition of new driver could do in
> a single shot in meta-fsl-arm-extra (so you'd still keep two patches
> to apply but both here).
>
>> ---
>>   ...mx-3.0.35-remove-brcm80211-staging-driver.patch |123141 ++++++++++++++++++++
>>   1 files changed, 123142 insertions(+)
>>   create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
>>
>> diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
>> new file mode 100644
>> index 0000000..96d3ce1
>> --- /dev/null
>> +++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
>> @@ -0,0 +1,123141 @@
>> +From 748eb185cad62c456dcd316c941f9835520a946d Mon Sep 17 00:00:00 2001
>> +From: John Weber <rjohnweber@gmail.com>
>> +Date: Sat, 9 Mar 2013 09:23:58 -0600
>> +Subject: [meta-fsl-arm-extra][PATCH 1/2] linux-imx (3.0.35): remove brcm80211
>> + staging driver
>
> The subject of internal patch is confusing as it is not for
> meta-fsl-arm-extra ;-)
>
> One thing I noticed in this serie is that you didn't export the
> patches with the order (PATCH X/Y) which is important so we know the
> order to apply them.
>
>


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
       [not found] <yes>
                   ` (69 preceding siblings ...)
  2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
@ 2013-03-18 20:25 ` John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data John Weber
                     ` (5 more replies)
  2013-06-10  9:17   ` Srinivas KANDAGATLA
                   ` (20 subsequent siblings)
  91 siblings, 6 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

This patchset provides fixes and wifi support for Wandboard-Dual.

  Fixes ESDHC platform data in kernel board init

  Replaces old wifi driver in drivers/staging with a backported driver from
  kernel v3.5 

  Adds a recipe to install wifi chip firmware (linux-firmware bbappend)

  Adds a recipe (wandboard-wifi-support) to provide the nvram file for 
  the chip and to create appropriate symlinks for the firmware files.

  Adds a dependency in the wandboard-dual machine conf to integrate
  the wandboard-wifi-support recipe.

Changes since v1:
  
  Removed an unneeded formatting change to the ESDHC platform data patch.
  
  Combined the remove and add patches for the wifi device driver, as 
  well as integrated the changes to the kernel recipe.
  
  Separated out the machine-specific code from the linux-firmware.bbappend
  and removed the PRINC in linux-firmware_git.bbappend in anticipation that
  we will be upstreaming this into oe-core.
  
  Created a machine-specific wifi support recipe for wandboard.
  
  Added patch numbers to the shortlog

John Weber (5):
  linux-imx (3.0.35): wandboard: fix sdhc platform data
  linux-imx (3.0.35): wandboard: replace brcm80211 driver
  linux-firmware: Add bbappend to include Broadcom wifi drivers
  wandboard-wifi-support: add nvram file and create firmware links
  wandboard-dual: Add wandboard-wifi-support to machine

 conf/machine/wandboard-dual.conf                   |    3 +
 .../files/LICENCE.broadcom_bcm43xx                 |   65 +
 .../files/wandboard-brcmfmac-nvram.txt             |   70 +
 .../wandboard-wifi-support.bb                      |   41 +
 .../linux-firmware/linux-firmware_git.bbappend     |   24 +
 ...002-wandboard-dual-fix-sdhc-platform-data.patch |   52 +
 ....0.35-Add-brcm80211-driver-backported-fro.patch |94038 +++++++++++++++
 ...mx-3.0.35-remove-brcm80211-staging-driver.patch |123141 ++++++++++++++++++++
 .../linux-imx-3.0.35/wandboard-dual/defconfig      |    6 +
 recipes-kernel/linux/linux-imx_3.0.35.bbappend     |    5 +-
 10 files changed, 217444 insertions(+), 1 deletion(-)
 create mode 100644 recipes-bsp/wandboard-wifi-support/files/LICENCE.broadcom_bcm43xx
 create mode 100644 recipes-bsp/wandboard-wifi-support/files/wandboard-brcmfmac-nvram.txt
 create mode 100644 recipes-bsp/wandboard-wifi-support/wandboard-wifi-support.bb
 create mode 100644 recipes-kernel/linux-firmware/linux-firmware_git.bbappend
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch

-- 
1.7.9.5



^ permalink raw reply	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
@ 2013-03-18 20:25   ` John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 2/5] linux-imx (3.0.35): wandboard: replace brcm80211 driver John Weber
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

Fixes the esdhc_platform_data structure defined in board-wand.c.  Before
this change there were problems with loading firmware for the BCM4329
wifi module on board Wandboard-Dual.  In addition, this squashes some
kernel warning messages concerning the MMC bus not having WP and CD for 
mmc1.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ...002-wandboard-dual-fix-sdhc-platform-data.patch |   52 ++++++++++++++++++++
 recipes-kernel/linux/linux-imx_3.0.35.bbappend     |    3 +-
 2 files changed, 54 insertions(+), 1 deletion(-)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
new file mode 100644
index 0000000..b5c9422
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch
@@ -0,0 +1,52 @@
+From ea530483ad42e5b9a89934fbdfd57df81b3a90ab Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Fri, 15 Mar 2013 08:43:15 -0500
+Subject: [PATCH] wandboard: fix sdhc platform data
+
+Fixes sdhc platfrom data structure to solve a problem when loading
+the firmware files for the on-board Wifi module on Wandboard-dual.
+This problem only occured when udev is tasked with loading firmware
+from the filesystem.
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ arch/arm/mach-mx6/board-wand.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-mx6/board-wand.c b/arch/arm/mach-mx6/board-wand.c
+index 7f972eb..7be6726 100644
+--- a/arch/arm/mach-mx6/board-wand.c
++++ b/arch/arm/mach-mx6/board-wand.c
+@@ -184,13 +184,17 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
+ 		.cd_gpio		= WAND_SD1_CD,
+ 		.wp_gpio		=-EINVAL,
+ 		.keep_power_at_suspend	= 1,
+	        .support_8bit		= 0,
++	  .delay_line = 0,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.cd_type = ESDHC_CD_CONTROLLER,
+ 	}, {
+-		.cd_gpio		=-EINVAL,
+-		.wp_gpio		=-EINVAL,
+ 		.keep_power_at_suspend	= 1,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.always_present = 1,
++		.support_8bit = 0,
++		.delay_line = 0,
++		.cd_type = ESDHC_CD_PERMANENT,
+ 	}, {
+ 		.cd_gpio		= WAND_SD3_CD,
+ 		.wp_gpio		= WAND_SD3_WP,
+@@ -198,6 +202,7 @@ static const struct esdhc_platform_data wand_sd_data[3] = {
+ 		.support_8bit		= 0,
+ 		.delay_line		= 0,
+ 		.platform_pad_change	= plt_sd_pad_change,
++		.cd_type = ESDHC_CD_CONTROLLER,
+ 	}
+ };
+ 
+-- 
+1.7.9.5
+
diff --git a/recipes-kernel/linux/linux-imx_3.0.35.bbappend b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
index f1abbf9..0466e67 100644
--- a/recipes-kernel/linux/linux-imx_3.0.35.bbappend
+++ b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
@@ -1,10 +1,11 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
 
-PRINC := "${@int(PRINC) + 1}"
+PRINC := "${@int(PRINC) + 2}"
 
 # Wandboard-specific patches
 SRC_URI_append_wandboard-dual = " \
    file://wandboard-dual/0001-Linux-3.0.35-Add-wandboard-dual-support.patch \
+   file://wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch \
 "
 # Add support for the Congatec qmx6 board
 SRC_URI_append_cgtqmx6 = " file://cgtqmx6/cgtqmx6.patch"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 2/5] linux-imx (3.0.35): wandboard: replace brcm80211 driver
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data John Weber
@ 2013-03-18 20:25   ` John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 3/5] linux-firmware: Add bbappend to include Broadcom wifi drivers John Weber
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

Replaces brcm80211 driver what was in drivers/staging with a backport
from kernel v3.5 which is located in drivers/net/wireless. 

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 ....0.35-Add-brcm80211-driver-backported-fro.patch |94038 +++++++++++++++
 ...mx-3.0.35-remove-brcm80211-staging-driver.patch |123141 ++++++++++++++++++++
 .../linux-imx-3.0.35/wandboard-dual/defconfig      |    6 +
 recipes-kernel/linux/linux-imx_3.0.35.bbappend     |    4 +-
 4 files changed, 217188 insertions(+), 1 deletion(-)
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
 create mode 100644 recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch

diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
new file mode 100644
index 0000000..1ed5f50
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch
@@ -0,0 +1,94038 @@
+From 99044f426f004207f6256add552e64a509c205fd Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Sat, 9 Mar 2013 09:25:52 -0600
+Subject: [meta-fsl-arm-extra][PATCH 2/2] linux-imx (3.0.35): Add brcm80211
+ driver backported from 3.5
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ drivers/net/wireless/Kconfig                       |    2 +
+ drivers/net/wireless/Makefile                      |    4 +
+ drivers/net/wireless/brcm80211/Kconfig             |   62 +
+ drivers/net/wireless/brcm80211/Makefile            |   23 +
+ drivers/net/wireless/brcm80211/brcmfmac/Makefile   |   36 +
+ drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  550 +
+ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  703 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |  669 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |  118 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |  495 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |  882 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |   79 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    | 1232 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_proto.h    |   53 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4014 +++
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |  622 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.h    |  136 +
+ .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |  272 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb.c      | 1617 ++
+ drivers/net/wireless/brcm80211/brcmfmac/usb.h      |   61 +
+ drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h  |   75 +
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  | 3881 +++
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |  366 +
+ drivers/net/wireless/brcm80211/brcmsmac/Makefile   |   48 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.c  |  841 +
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.h  |  248 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.c    | 1236 +
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.h    |   30 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.c   |  307 +
+ drivers/net/wireless/brcm80211/brcmsmac/antsel.h   |   29 +
+ .../brcm80211/brcmsmac/brcms_trace_events.c        |   23 +
+ .../brcm80211/brcmsmac/brcms_trace_events.h        |   92 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.c  | 1506 +
+ drivers/net/wireless/brcm80211/brcmsmac/channel.h  |   53 +
+ drivers/net/wireless/brcm80211/brcmsmac/d11.h      | 1901 ++
+ drivers/net/wireless/brcm80211/brcmsmac/dma.c      | 1444 +
+ drivers/net/wireless/brcm80211/brcmsmac/dma.h      |  122 +
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  | 1609 ++
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.h  |  108 +
+ drivers/net/wireless/brcm80211/brcmsmac/main.c     | 8495 ++++++
+ drivers/net/wireless/brcm80211/brcmsmac/main.h     |  720 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c  | 2961 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_hal.h  |  299 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_int.h  | 1162 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c  | 5137 ++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h  |  121 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c    |28685 ++++++++++++++++++++
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.c    |  308 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_qmath.h    |   42 +
+ .../wireless/brcm80211/brcmsmac/phy/phy_radio.h    | 1533 ++
+ .../net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h |  167 +
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c   | 3250 +++
+ .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h   |   54 +
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c |10630 ++++++++
+ .../net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h |   50 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c |  216 +
+ drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h |  179 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.c      |  375 +
+ drivers/net/wireless/brcm80211/brcmsmac/pmu.h      |   35 +
+ drivers/net/wireless/brcm80211/brcmsmac/pub.h      |  372 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.c     |  514 +
+ drivers/net/wireless/brcm80211/brcmsmac/rate.h     |  249 +
+ drivers/net/wireless/brcm80211/brcmsmac/scb.h      |   82 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.c      |  438 +
+ drivers/net/wireless/brcm80211/brcmsmac/stf.h      |   42 +
+ drivers/net/wireless/brcm80211/brcmsmac/types.h    |  304 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.c |  109 +
+ .../net/wireless/brcm80211/brcmsmac/ucode_loader.h |   58 +
+ drivers/net/wireless/brcm80211/brcmutil/Makefile   |   28 +
+ drivers/net/wireless/brcm80211/brcmutil/utils.c    |  278 +
+ .../net/wireless/brcm80211/include/brcm_hw_ids.h   |   41 +
+ .../net/wireless/brcm80211/include/brcmu_utils.h   |  196 +
+ .../net/wireless/brcm80211/include/brcmu_wifi.h    |  239 +
+ .../net/wireless/brcm80211/include/chipcommon.h    |  286 +
+ drivers/net/wireless/brcm80211/include/defs.h      |  103 +
+ drivers/net/wireless/brcm80211/include/soc.h       |   98 +
+ 76 files changed, 93405 insertions(+)
+ create mode 100644 drivers/net/wireless/brcm80211/Kconfig
+ create mode 100644 drivers/net/wireless/brcm80211/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/channel.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/d11.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/dma.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/main.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/pub.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/rate.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/scb.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/stf.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/types.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+ create mode 100644 drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/Makefile
+ create mode 100644 drivers/net/wireless/brcm80211/brcmutil/utils.c
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_utils.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/chipcommon.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/defs.h
+ create mode 100644 drivers/net/wireless/brcm80211/include/soc.h
+
+diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
+index fbcf861..d7da434 100644
+--- a/drivers/net/wireless/Kconfig
++++ b/drivers/net/wireless/Kconfig
+@@ -271,6 +271,7 @@ config MWL8K
+ source "drivers/net/wireless/ath/Kconfig"
+ source "drivers/net/wireless/b43/Kconfig"
+ source "drivers/net/wireless/b43legacy/Kconfig"
++source "drivers/net/wireless/brcm80211/Kconfig"
+ source "drivers/net/wireless/hostap/Kconfig"
+ source "drivers/net/wireless/ipw2x00/Kconfig"
+ source "drivers/net/wireless/iwlwifi/Kconfig"
+@@ -288,4 +289,5 @@ source "drivers/net/wireless/mwifiex/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ #source "drivers/net/wireless/ath6kl/Kconfig"
+ 
++
+ endif # WLAN
+diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
+index 60a0a41..69a03f4 100644
+--- a/drivers/net/wireless/Makefile
++++ b/drivers/net/wireless/Makefile
+@@ -59,3 +59,7 @@ obj-$(CONFIG_IWM)	+= iwmc3200wifi/
+ 
+ obj-$(CONFIG_MWIFIEX)	+= mwifiex/
+ #obj-$(CONFIG_ATH6K_LEGACY)	+= ath6kl/
++
++obj-$(CONFIG_BRCMFMAC) += brcm80211/
++obj-$(CONFIG_BRCMUMAC) += brcm80211/
++obj-$(CONFIG_BRCMSMAC) += brcm80211/
+diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
+new file mode 100644
+index 0000000..b480088
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Kconfig
+@@ -0,0 +1,62 @@
++config BRCMUTIL
++	tristate
++
++config BRCMSMAC
++	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
++	depends on MAC80211
++	depends on BCMA
++	select BRCMUTIL
++	select FW_LOADER
++	select CRC_CCITT
++	select CRC8
++	select CORDIC
++	---help---
++	  This module adds support for PCIe wireless adapters based on Broadcom
++	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
++	  be called brcmsmac.ko.
++
++config BRCMFMAC
++	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
++	depends on CFG80211
++	select BRCMUTIL
++	---help---
++	  This module adds support for embedded wireless adapters based on
++	  Broadcom IEEE802.11n FullMAC chipsets. It has to work with at least
++	  one of the bus interface support. If you choose to build a module,
++	  it'll be called brcmfmac.ko.
++
++config BRCMFMAC_SDIO
++	bool "SDIO bus interface support for FullMAC driver"
++	depends on MMC
++	depends on BRCMFMAC
++	select FW_LOADER
++	default y
++	---help---
++	  This option enables the SDIO bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for a SDIO wireless card.
++
++config BRCMFMAC_SDIO_OOB
++	bool "Out of band interrupt support for SDIO interface chipset"
++	depends on BRCMFMAC_SDIO
++	---help---
++	  This option enables out-of-band interrupt support for Broadcom
++	  SDIO Wifi chipset using fullmac in order to gain better
++	  performance and deep sleep wake up capability on certain
++	  platforms. Say N if you are unsure.
++
++config BRCMFMAC_USB
++	bool "USB bus interface support for FullMAC driver"
++	depends on USB
++	depends on BRCMFMAC
++	select FW_LOADER
++	---help---
++	  This option enables the USB bus interface support for Broadcom
++	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
++	  use the driver for an USB wireless card.
++
++config BRCMDBG
++	bool "Broadcom driver debug functions"
++	depends on BRCMSMAC || BRCMFMAC
++	---help---
++	  Selecting this enables additional code for debug purposes.
+diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile
+new file mode 100644
+index 0000000..b987920
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/Makefile
+@@ -0,0 +1,23 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++# common flags
++subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DDEBUG
++
++obj-$(CONFIG_BRCMUTIL)	+= brcmutil/
++obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
++obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+new file mode 100644
+index 0000000..a4c4d1c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+@@ -0,0 +1,36 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y += \
++	-I$(obj)		\
++	-I$(obj)/../include
++
++ccflags-y += -D__CHECK_ENDIAN__
++
++obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
++brcmfmac-objs += \
++		wl_cfg80211.o \
++		dhd_cdc.o \
++		dhd_common.o \
++		dhd_linux.o
++brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
++		dhd_sdio.o \
++		bcmsdh.o \
++		bcmsdh_sdmmc.o \
++		sdio_chip.o
++brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
++		usb.o
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+new file mode 100644
+index 0000000..a87f141
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -0,0 +1,550 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ****************** SDIO CARD Interface Functions **************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++#include <linux/pci.h>
++#include <linux/pci_ids.h>
++#include <linux/sched.h>
++#include <linux/completion.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <soc.h>
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++
++#define SDIOH_API_ACCESS_RETRY_LIMIT	2
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id);
++
++	brcmf_dbg(INTR, "oob intr triggered\n");
++
++	/*
++	 * out-of-band interrupt is level-triggered which won't
++	 * be cleared until dpc
++	 */
++	if (sdiodev->irq_en) {
++		disable_irq_nosync(irq);
++		sdiodev->irq_en = false;
++	}
++
++	brcmf_sdbrcm_isr(sdiodev->bus);
++
++	return IRQ_HANDLED;
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	int ret = 0;
++	u8 data;
++	unsigned long flags;
++
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
++	ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
++			  sdiodev->irq_flags, "brcmf_oob_intr",
++			  &sdiodev->func[1]->card->dev);
++	if (ret != 0)
++		return ret;
++	spin_lock_init(&sdiodev->irq_en_lock);
++	spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
++	sdiodev->irq_en = true;
++	spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
++
++	ret = enable_irq_wake(sdiodev->irq);
++	if (ret != 0)
++		return ret;
++	sdiodev->irq_wake = true;
++
++	/* must configure SDIO_CCCR_IENx to enable irq */
++	data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
++	data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
++
++	/* redirect, configure and enable io for interrupt signal */
++	data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
++	if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
++		data |= SDIO_SEPINT_ACT_HI;
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
++	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
++
++	if (sdiodev->irq_wake) {
++		disable_irq_wake(sdiodev->irq);
++		sdiodev->irq_wake = false;
++	}
++	free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev);
++	sdiodev->irq_en = false;
++
++	return 0;
++}
++#else		/* CONFIG_BRCMFMAC_SDIO_OOB */
++static void brcmf_sdio_irqhandler(struct sdio_func *func)
++{
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_dbg(INTR, "ib intr triggered\n");
++
++	sdio_release_host(sdiodev->func[1]);
++	brcmf_sdbrcm_isr(sdiodev->bus);
++	sdio_claim_host(sdiodev->func[1]);
++}
++
++/* dummy handler for SDIO function 2 interrupt */
++static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
++{
++}
++
++int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler);
++	sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++
++int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "Entering\n");
++
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_release_irq(sdiodev->func[2]);
++	sdio_release_irq(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++int
++brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
++{
++	int err = 0, i;
++	u8 addr[3];
++	s32 retry;
++
++	addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
++	addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK;
++	addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK;
++
++	for (i = 0; i < 3; i++) {
++		retry = 0;
++		do {
++			if (retry)
++				usleep_range(1000, 2000);
++			err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE,
++					SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i,
++					&addr[i]);
++		} while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++		if (err) {
++			brcmf_dbg(ERROR, "failed at addr:0x%0x\n",
++				  SBSDIO_FUNC1_SBADDRLOW + i);
++			break;
++		}
++	}
++
++	return err;
++}
++
++static int
++brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			void *data, bool write)
++{
++	u8 func_num, reg_size;
++	u32 bar;
++	s32 retry = 0;
++	int ret;
++
++	/*
++	 * figure out how to read the register based on address range
++	 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
++	 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
++	 * The rest: function 1 silicon backplane core registers
++	 */
++	if ((addr & ~REG_F0_REG_MASK) == 0) {
++		func_num = SDIO_FUNC_0;
++		reg_size = 1;
++	} else if ((addr & ~REG_F1_MISC_MASK) == 0) {
++		func_num = SDIO_FUNC_1;
++		reg_size = 1;
++	} else {
++		func_num = SDIO_FUNC_1;
++		reg_size = 4;
++
++		/* Set the window for SB core register */
++		bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++		if (bar != sdiodev->sbwad) {
++			ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
++			if (ret != 0) {
++				memset(data, 0xFF, reg_size);
++				return ret;
++			}
++			sdiodev->sbwad = bar;
++		}
++		addr &= SBSDIO_SB_OFT_ADDR_MASK;
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++	}
++
++	do {
++		if (!write)
++			memset(data, 0, reg_size);
++		if (retry)	/* wait for 1 ms till bus get settled down */
++			usleep_range(1000, 2000);
++		if (reg_size == 1)
++			ret = brcmf_sdioh_request_byte(sdiodev, write,
++						       func_num, addr, data);
++		else
++			ret = brcmf_sdioh_request_word(sdiodev, write,
++						       func_num, addr, data, 4);
++	} while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
++
++	if (ret != 0)
++		brcmf_dbg(ERROR, "failed with %d\n", ret);
++
++	return ret;
++}
++
++u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u8 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%02x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
++{
++	u32 data;
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x\n", addr);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
++	brcmf_dbg(INFO, "data:0x%08x\n", data);
++
++	if (ret)
++		*ret = retval;
++
++	return data;
++}
++
++void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u8 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++		      u32 data, int *ret)
++{
++	int retval;
++
++	brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
++	retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
++
++	if (ret)
++		*ret = retval;
++}
++
++static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
++				     uint flags, uint width, u32 *addr)
++{
++	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	if (width == 4)
++		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return 0;
++}
++
++int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt);
++	if (!err)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
++					 fn, addr, pkt);
++
++	return err;
++}
++
++int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			    uint flags, struct sk_buff_head *pktq)
++{
++	uint incr_fix;
++	uint width;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pktq->qlen);
++
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
++	if (err)
++		return err;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
++					pktq);
++
++	return err;
++}
++
++int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	int err;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	memcpy(mypkt->data, buf, nbytes);
++	err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, mypkt);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++
++}
++
++int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt)
++{
++	uint incr_fix;
++	uint width;
++	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
++	int err = 0;
++
++	brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
++		  fn, addr, pkt->len);
++
++	/* Async not implemented yet */
++	if (flags & SDIO_REQ_ASYNC)
++		return -ENOTSUPP;
++
++	if (bar0 != sdiodev->sbwad) {
++		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
++		if (err)
++			return err;
++
++		sdiodev->sbwad = bar0;
++	}
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++
++	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
++	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
++	if (width == 4)
++		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
++					  addr, pkt);
++}
++
++int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
++			u8 *buf, uint nbytes)
++{
++	struct sk_buff *mypkt;
++	bool write = rw ? SDIOH_WRITE : SDIOH_READ;
++	int err;
++
++	addr &= SBSDIO_SB_OFT_ADDR_MASK;
++	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
++
++	mypkt = brcmu_pkt_buf_get_skb(nbytes);
++	if (!mypkt) {
++		brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
++			  nbytes);
++		return -EIO;
++	}
++
++	/* For a write, copy the buffer data into the packet. */
++	if (write)
++		memcpy(mypkt->data, buf, nbytes);
++
++	err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write,
++					 SDIO_FUNC_1, addr, mypkt);
++
++	/* For a read, copy the packet data back to the buffer. */
++	if (!err && !write)
++		memcpy(buf, mypkt->data, nbytes);
++
++	brcmu_pkt_buf_free_skb(mypkt);
++	return err;
++}
++
++int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
++{
++	char t_func = (char)fn;
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* issue abort cmd52 command through F0 */
++	brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
++				 SDIO_CCCR_ABORT, &t_func);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return 0;
++}
++
++int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
++{
++	u32 regs = 0;
++	int ret = 0;
++
++	ret = brcmf_sdioh_attach(sdiodev);
++	if (ret)
++		goto out;
++
++	regs = SI_ENUM_BASE;
++
++	/* Report the BAR, to fix if needed */
++	sdiodev->sbwad = SI_ENUM_BASE;
++
++	/* try to attach to the target device */
++	sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev);
++	if (!sdiodev->bus) {
++		brcmf_dbg(ERROR, "device attach failed\n");
++		ret = -ENODEV;
++		goto out;
++	}
++
++out:
++	if (ret)
++		brcmf_sdio_remove(sdiodev);
++
++	return ret;
++}
++EXPORT_SYMBOL(brcmf_sdio_probe);
++
++int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
++{
++	if (sdiodev->bus) {
++		brcmf_sdbrcm_disconnect(sdiodev->bus);
++		sdiodev->bus = NULL;
++	}
++
++	brcmf_sdioh_detach(sdiodev);
++
++	sdiodev->sbwad = 0;
++
++	return 0;
++}
++EXPORT_SYMBOL(brcmf_sdio_remove);
++
++void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
++{
++	if (enable)
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
++	else
++		brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+new file mode 100644
+index 0000000..391a721
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+@@ -0,0 +1,703 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/core.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/sdio_ids.h>
++#include <linux/mmc/card.h>
++#include <linux/suspend.h>
++#include <linux/errno.h>
++#include <linux/sched.h>	/* request_irq() */
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include "sdio_host.h"
++#include "dhd_dbg.h"
++#include "dhd_bus.h"
++
++#define SDIO_VENDOR_ID_BROADCOM		0x02d0
++
++#define DMA_ALIGN_MASK	0x03
++
++#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
++#define SDIO_DEVICE_ID_BROADCOM_4330	0x4330
++
++#define SDIO_FUNC1_BLOCKSIZE		64
++#define SDIO_FUNC2_BLOCKSIZE		512
++
++/* devices we support, null terminated */
++static const struct sdio_device_id brcmf_sdmmc_ids[] = {
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
++	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
++	{ /* end: all zeroes */ },
++};
++MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static struct list_head oobirq_lh;
++struct brcmf_sdio_oobirq {
++	unsigned int irq;
++	unsigned long flags;
++	struct list_head list;
++};
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool
++brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
++{
++	bool is_err = false;
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	is_err = atomic_read(&sdiodev->suspend);
++#endif
++	return is_err;
++}
++
++static void
++brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
++{
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	int retry = 0;
++	while (atomic_read(&sdiodev->suspend) && retry++ != 30)
++		wait_event_timeout(*wq, false, HZ/100);
++#endif
++}
++
++static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
++					    uint regaddr, u8 *byte)
++{
++	struct sdio_func *sdfunc = sdiodev->func[0];
++	int err_ret;
++
++	/*
++	 * Can only directly write to some F0 registers.
++	 * Handle F2 enable/disable and Abort command
++	 * as a special case.
++	 */
++	if (regaddr == SDIO_CCCR_IOEx) {
++		sdfunc = sdiodev->func[2];
++		if (sdfunc) {
++			sdio_claim_host(sdfunc);
++			if (*byte & SDIO_FUNC_ENABLE_2) {
++				/* Enable Function 2 */
++				err_ret = sdio_enable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "enable F2 failed:%d\n",
++						  err_ret);
++			} else {
++				/* Disable Function 2 */
++				err_ret = sdio_disable_func(sdfunc);
++				if (err_ret)
++					brcmf_dbg(ERROR,
++						  "Disable F2 failed:%d\n",
++						  err_ret);
++			}
++			sdio_release_host(sdfunc);
++		}
++	} else if ((regaddr == SDIO_CCCR_ABORT) ||
++		   (regaddr == SDIO_CCCR_IENx)) {
++		sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
++				 GFP_KERNEL);
++		if (!sdfunc)
++			return -ENOMEM;
++		sdfunc->num = 0;
++		sdio_claim_host(sdfunc);
++		sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++		kfree(sdfunc);
++	} else if (regaddr < 0xF0) {
++		brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
++		err_ret = -EPERM;
++	} else {
++		sdio_claim_host(sdfunc);
++		sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
++		sdio_release_host(sdfunc);
++	}
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
++			     uint regaddr, u8 *byte)
++{
++	int err_ret;
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	if (rw && func == 0) {
++		/* handle F0 separately */
++		err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
++	} else {
++		sdio_claim_host(sdiodev->func[func]);
++		if (rw) /* CMD52 Write */
++			sdio_writeb(sdiodev->func[func], *byte, regaddr,
++				    &err_ret);
++		else if (func == 0) {
++			*byte = sdio_f0_readb(sdiodev->func[func], regaddr,
++					      &err_ret);
++		} else {
++			*byte = sdio_readb(sdiodev->func[func], regaddr,
++					   &err_ret);
++		}
++		sdio_release_host(sdiodev->func[func]);
++	}
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
++			  rw ? "write" : "read", func, regaddr, *byte, err_ret);
++
++	return err_ret;
++}
++
++int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			     uint rw, uint func, uint addr, u32 *word,
++			     uint nbytes)
++{
++	int err_ret = -EIO;
++
++	if (func == 0) {
++		brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
++		return -EINVAL;
++	}
++
++	brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
++		  rw, func, addr, nbytes);
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	if (rw) {		/* CMD52 Write */
++		if (nbytes == 4)
++			sdio_writel(sdiodev->func[func], *word, addr,
++				    &err_ret);
++		else if (nbytes == 2)
++			sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
++				    addr, &err_ret);
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	} else {		/* CMD52 Read */
++		if (nbytes == 4)
++			*word = sdio_readl(sdiodev->func[func], addr, &err_ret);
++		else if (nbytes == 2)
++			*word = sdio_readw(sdiodev->func[func], addr,
++					   &err_ret) & 0xFFFF;
++		else
++			brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
++			  rw ? "write" : "read", err_ret);
++
++	return err_ret;
++}
++
++/* precondition: host controller is claimed */
++static int
++brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
++			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
++{
++	int err_ret = 0;
++
++	if ((write) && (!fifo)) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (write) {
++		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
++					   ((u8 *) (pkt->data)), pktlen);
++	} else if (fifo) {
++		err_ret = sdio_readsb(sdiodev->func[func],
++				      ((u8 *) (pkt->data)), addr, pktlen);
++	} else {
++		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
++					     ((u8 *) (pkt->data)),
++					     addr, pktlen);
++	}
++
++	return err_ret;
++}
++
++/*
++ * This function takes a queue of packets. The packets on the queue
++ * are assumed to be properly aligned by the caller.
++ */
++int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq)
++{
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++	u32 SGCount = 0;
++	int err_ret = 0;
++
++	struct sk_buff *pkt;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	skb_queue_walk(pktq, pkt) {
++		uint pkt_len = pkt->len;
++		pkt_len += 3;
++		pkt_len &= 0xFFFFFFFC;
++
++		err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++						   addr, pkt, pkt_len);
++		if (err_ret) {
++			brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len, err_ret);
++		} else {
++			brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
++				  write ? "TX" : "RX", pkt, SGCount, addr,
++				  pkt_len);
++		}
++		if (!fifo)
++			addr += pkt_len;
++
++		SGCount++;
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	brcmf_dbg(TRACE, "Exit\n");
++	return err_ret;
++}
++
++/*
++ * This function takes a single DMA-able packet.
++ */
++int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			       uint fix_inc, uint write, uint func, uint addr,
++			       struct sk_buff *pkt)
++{
++	int status;
++	uint pkt_len;
++	bool fifo = (fix_inc == SDIOH_DATA_FIX);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (pkt == NULL)
++		return -EINVAL;
++	pkt_len = pkt->len;
++
++	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
++	if (brcmf_pm_resume_error(sdiodev))
++		return -EIO;
++
++	/* Claim host controller */
++	sdio_claim_host(sdiodev->func[func]);
++
++	pkt_len += 3;
++	pkt_len &= (uint)~3;
++
++	status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
++					   addr, pkt, pkt_len);
++	if (status) {
++		brcmf_dbg(ERROR, "%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len, status);
++	} else {
++		brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n",
++			  write ? "TX" : "RX", pkt, addr, pkt_len);
++	}
++
++	/* Release host controller */
++	sdio_release_host(sdiodev->func[func]);
++
++	return status;
++}
++
++static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
++{
++	/* read 24 bits and return valid 17 bit addr */
++	int i, ret;
++	u32 scratch, regdata;
++	__le32 scratch_le;
++	u8 *ptr = (u8 *)&scratch_le;
++
++	for (i = 0; i < 3; i++) {
++		regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "Can't read!\n");
++
++		*ptr++ = (u8) regdata;
++		regaddr++;
++	}
++
++	/* Only the lower 17-bits are valid */
++	scratch = le32_to_cpu(scratch_le);
++	scratch &= 0x0001FFFF;
++	return scratch;
++}
++
++static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret;
++	u32 fbraddr;
++	u8 func;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Get the Card's common CIS address */
++	sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
++							   SDIO_CCCR_CIS);
++	brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
++		  sdiodev->func_cis_ptr[0]);
++
++	/* Get the Card's function CIS (for each function) */
++	for (fbraddr = SDIO_FBR_BASE(1), func = 1;
++	     func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
++		sdiodev->func_cis_ptr[func] =
++		    brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
++		brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
++			  func, sdiodev->func_cis_ptr[func]);
++	}
++
++	/* Enable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_enable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret)
++		brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
++
++	return false;
++}
++
++/*
++ *	Public entry points & extern's
++ */
++int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
++{
++	int err_ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	sdiodev->num_funcs = 2;
++
++	sdio_claim_host(sdiodev->func[1]);
++	err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[1]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
++		goto out;
++	}
++
++	sdio_claim_host(sdiodev->func[2]);
++	err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
++	sdio_release_host(sdiodev->func[2]);
++	if (err_ret) {
++		brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
++		goto out;
++	}
++
++	brcmf_sdioh_enablefuncs(sdiodev);
++
++out:
++	brcmf_dbg(TRACE, "Done\n");
++	return err_ret;
++}
++
++void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
++{
++	brcmf_dbg(TRACE, "\n");
++
++	/* Disable Function 2 */
++	sdio_claim_host(sdiodev->func[2]);
++	sdio_disable_func(sdiodev->func[2]);
++	sdio_release_host(sdiodev->func[2]);
++
++	/* Disable Function 1 */
++	sdio_claim_host(sdiodev->func[1]);
++	sdio_disable_func(sdiodev->func[1]);
++	sdio_release_host(sdiodev->func[1]);
++
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	struct brcmf_sdio_oobirq *oobirq_entry;
++
++	if (list_empty(&oobirq_lh)) {
++		brcmf_dbg(ERROR, "no valid oob irq resource\n");
++		return -ENXIO;
++	}
++
++	oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq,
++					list);
++
++	sdiodev->irq = oobirq_entry->irq;
++	sdiodev->irq_flags = oobirq_entry->flags;
++	list_del(&oobirq_entry->list);
++	kfree(oobirq_entry);
++
++	return 0;
++}
++#else
++static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
++{
++	return 0;
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static int brcmf_ops_sdio_probe(struct sdio_func *func,
++			      const struct sdio_device_id *id)
++{
++	int ret = 0;
++	struct brcmf_sdio_dev *sdiodev;
++	struct brcmf_bus *bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(TRACE, "func->class=%x\n", func->class);
++	brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 1) {
++		if (dev_get_drvdata(&func->card->dev)) {
++			brcmf_dbg(ERROR, "card private drvdata occupied\n");
++			return -ENXIO;
++		}
++		bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL);
++		if (!bus_if)
++			return -ENOMEM;
++		sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
++		if (!sdiodev) {
++			kfree(bus_if);
++			return -ENOMEM;
++		}
++		sdiodev->func[0] = func;
++		sdiodev->func[1] = func;
++		sdiodev->bus_if = bus_if;
++		bus_if->bus_priv.sdio = sdiodev;
++		bus_if->type = SDIO_BUS;
++		bus_if->align = BRCMF_SDALIGN;
++		dev_set_drvdata(&func->card->dev, sdiodev);
++
++		atomic_set(&sdiodev->suspend, false);
++		init_waitqueue_head(&sdiodev->request_byte_wait);
++		init_waitqueue_head(&sdiodev->request_word_wait);
++		init_waitqueue_head(&sdiodev->request_chain_wait);
++		init_waitqueue_head(&sdiodev->request_buffer_wait);
++	}
++
++	if (func->num == 2) {
++		sdiodev = dev_get_drvdata(&func->card->dev);
++		if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
++			return -ENODEV;
++
++		ret = brcmf_sdio_getintrcfg(sdiodev);
++		if (ret)
++			return ret;
++		sdiodev->func[2] = func;
++
++		bus_if = sdiodev->bus_if;
++		sdiodev->dev = &func->dev;
++		dev_set_drvdata(&func->dev, bus_if);
++
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
++		ret = brcmf_sdio_probe(sdiodev);
++	}
++
++	return ret;
++}
++
++static void brcmf_ops_sdio_remove(struct sdio_func *func)
++{
++	struct brcmf_bus *bus_if;
++	struct brcmf_sdio_dev *sdiodev;
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(INFO, "func->class=%x\n", func->class);
++	brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
++	brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
++	brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
++
++	if (func->num == 2) {
++		bus_if = dev_get_drvdata(&func->dev);
++		sdiodev = bus_if->bus_priv.sdio;
++		brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
++		brcmf_sdio_remove(sdiodev);
++		dev_set_drvdata(&func->card->dev, NULL);
++		dev_set_drvdata(&func->dev, NULL);
++		kfree(bus_if);
++		kfree(sdiodev);
++	}
++}
++
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++static int brcmf_sdio_suspend(struct device *dev)
++{
++	mmc_pm_flag_t sdio_flags;
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "\n");
++
++	atomic_set(&sdiodev->suspend, true);
++
++	sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
++	if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
++		brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
++		return -EINVAL;
++	}
++
++	ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
++	if (ret) {
++		brcmf_dbg(ERROR, "Failed to set pm_flags\n");
++		return ret;
++	}
++
++	brcmf_sdio_wdtmr_enable(sdiodev, false);
++
++	return ret;
++}
++
++static int brcmf_sdio_resume(struct device *dev)
++{
++	struct sdio_func *func = dev_to_sdio_func(dev);
++	struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
++
++	brcmf_sdio_wdtmr_enable(sdiodev, true);
++	atomic_set(&sdiodev->suspend, false);
++	return 0;
++}
++
++static const struct dev_pm_ops brcmf_sdio_pm_ops = {
++	.suspend	= brcmf_sdio_suspend,
++	.resume		= brcmf_sdio_resume,
++};
++#endif	/* CONFIG_PM_SLEEP */
++
++static struct sdio_driver brcmf_sdmmc_driver = {
++	.probe = brcmf_ops_sdio_probe,
++	.remove = brcmf_ops_sdio_remove,
++	.name = "brcmfmac",
++	.id_table = brcmf_sdmmc_ids,
++#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	.drv = {
++		.pm = &brcmf_sdio_pm_ops,
++	},
++#endif	/* CONFIG_PM_SLEEP */
++};
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static int brcmf_sdio_pd_probe(struct platform_device *pdev)
++{
++	struct resource *res;
++	struct brcmf_sdio_oobirq *oobirq_entry;
++	int i, ret;
++
++	INIT_LIST_HEAD(&oobirq_lh);
++
++	for (i = 0; ; i++) {
++		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
++		if (!res)
++			break;
++
++		oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
++				       GFP_KERNEL);
++		oobirq_entry->irq = res->start;
++		oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
++		list_add_tail(&oobirq_entry->list, &oobirq_lh);
++	}
++	if (i == 0)
++		return -ENXIO;
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++
++	return ret;
++}
++
++static struct platform_driver brcmf_sdio_pd = {
++	.probe		= brcmf_sdio_pd_probe,
++	.driver		= {
++		.name	= "brcmf_sdio_pd"
++	}
++};
++
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++
++	platform_driver_unregister(&brcmf_sdio_pd);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = platform_driver_register(&brcmf_sdio_pd);
++
++	if (ret)
++		brcmf_dbg(ERROR, "platform_driver_register failed: %d\n", ret);
++}
++#else
++void brcmf_sdio_exit(void)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	sdio_unregister_driver(&brcmf_sdmmc_driver);
++}
++
++void brcmf_sdio_init(void)
++{
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ret = sdio_register_driver(&brcmf_sdmmc_driver);
++
++	if (ret)
++		brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+new file mode 100644
+index 0000000..9f63701
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+@@ -0,0 +1,669 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/****************
++ * Common types *
++ */
++
++#ifndef _BRCMF_H_
++#define _BRCMF_H_
++
++#define BRCMF_VERSION_STR		"4.218.248.5"
++
++/*******************************************************************************
++ * IO codes that are interpreted by dongle firmware
++ ******************************************************************************/
++#define BRCMF_C_UP				2
++#define BRCMF_C_SET_PROMISC			10
++#define BRCMF_C_GET_RATE			12
++#define BRCMF_C_GET_INFRA			19
++#define BRCMF_C_SET_INFRA			20
++#define BRCMF_C_GET_AUTH			21
++#define BRCMF_C_SET_AUTH			22
++#define BRCMF_C_GET_BSSID			23
++#define BRCMF_C_GET_SSID			25
++#define BRCMF_C_SET_SSID			26
++#define BRCMF_C_GET_CHANNEL			29
++#define BRCMF_C_GET_SRL				31
++#define BRCMF_C_GET_LRL				33
++#define BRCMF_C_GET_RADIO			37
++#define BRCMF_C_SET_RADIO			38
++#define BRCMF_C_GET_PHYTYPE			39
++#define BRCMF_C_SET_KEY				45
++#define BRCMF_C_SET_PASSIVE_SCAN		49
++#define BRCMF_C_SCAN				50
++#define BRCMF_C_SCAN_RESULTS			51
++#define BRCMF_C_DISASSOC			52
++#define BRCMF_C_REASSOC				53
++#define BRCMF_C_SET_ROAM_TRIGGER		55
++#define BRCMF_C_SET_ROAM_DELTA			57
++#define BRCMF_C_GET_DTIMPRD			77
++#define BRCMF_C_SET_COUNTRY			84
++#define BRCMF_C_GET_PM				85
++#define BRCMF_C_SET_PM				86
++#define BRCMF_C_GET_AP				117
++#define BRCMF_C_SET_AP				118
++#define BRCMF_C_GET_RSSI			127
++#define BRCMF_C_GET_WSEC			133
++#define BRCMF_C_SET_WSEC			134
++#define BRCMF_C_GET_PHY_NOISE			135
++#define BRCMF_C_GET_BSS_INFO			136
++#define BRCMF_C_SET_SCAN_CHANNEL_TIME		185
++#define BRCMF_C_SET_SCAN_UNASSOC_TIME		187
++#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON	201
++#define BRCMF_C_GET_VALID_CHANNELS		217
++#define BRCMF_C_GET_KEY_PRIMARY			235
++#define BRCMF_C_SET_KEY_PRIMARY			236
++#define BRCMF_C_SET_SCAN_PASSIVE_TIME		258
++#define BRCMF_C_GET_VAR				262
++#define BRCMF_C_SET_VAR				263
++
++/* phy types (returned by WLC_GET_PHYTPE) */
++#define	WLC_PHY_TYPE_A		0
++#define	WLC_PHY_TYPE_B		1
++#define	WLC_PHY_TYPE_G		2
++#define	WLC_PHY_TYPE_N		4
++#define	WLC_PHY_TYPE_LP		5
++#define	WLC_PHY_TYPE_SSN	6
++#define	WLC_PHY_TYPE_HT		7
++#define	WLC_PHY_TYPE_LCN	8
++#define	WLC_PHY_TYPE_NULL	0xf
++
++#define BRCMF_EVENTING_MASK_LEN	16
++
++#define TOE_TX_CSUM_OL		0x00000001
++#define TOE_RX_CSUM_OL		0x00000002
++
++#define	BRCMF_BSS_INFO_VERSION	109 /* curr ver of brcmf_bss_info_le struct */
++
++/* size of brcmf_scan_params not including variable length array */
++#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
++
++/* masks for channel and ssid count */
++#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
++#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
++
++#define BRCMF_SCAN_ACTION_START      1
++#define BRCMF_SCAN_ACTION_CONTINUE   2
++#define WL_SCAN_ACTION_ABORT      3
++
++#define BRCMF_ISCAN_REQ_VERSION 1
++
++/* brcmf_iscan_results status values */
++#define BRCMF_SCAN_RESULTS_SUCCESS	0
++#define BRCMF_SCAN_RESULTS_PARTIAL	1
++#define BRCMF_SCAN_RESULTS_PENDING	2
++#define BRCMF_SCAN_RESULTS_ABORTED	3
++#define BRCMF_SCAN_RESULTS_NO_MEM	4
++
++/* Indicates this key is using soft encrypt */
++#define WL_SOFT_KEY	(1 << 0)
++/* primary (ie tx) key */
++#define BRCMF_PRIMARY_KEY	(1 << 1)
++/* Reserved for backward compat */
++#define WL_KF_RES_4	(1 << 4)
++/* Reserved for backward compat */
++#define WL_KF_RES_5	(1 << 5)
++/* Indicates a group key for a IBSS PEER */
++#define WL_IBSS_PEER_GROUP_KEY	(1 << 6)
++
++/* For supporting multiple interfaces */
++#define BRCMF_MAX_IFS	16
++
++#define DOT11_BSSTYPE_ANY			2
++#define DOT11_MAX_DEFAULT_KEYS	4
++
++#define BRCMF_EVENT_MSG_LINK		0x01
++#define BRCMF_EVENT_MSG_FLUSHTXQ	0x02
++#define BRCMF_EVENT_MSG_GROUP		0x04
++
++struct brcmf_event_msg {
++	__be16 version;
++	__be16 flags;
++	__be32 event_type;
++	__be32 status;
++	__be32 reason;
++	__be32 auth_type;
++	__be32 datalen;
++	u8 addr[ETH_ALEN];
++	char ifname[IFNAMSIZ];
++} __packed;
++
++struct brcm_ethhdr {
++	u16 subtype;
++	u16 length;
++	u8 version;
++	u8 oui[3];
++	u16 usr_subtype;
++} __packed;
++
++struct brcmf_event {
++	struct ethhdr eth;
++	struct brcm_ethhdr hdr;
++	struct brcmf_event_msg msg;
++} __packed;
++
++/* event codes sent by the dongle to this driver */
++#define BRCMF_E_SET_SSID			0
++#define BRCMF_E_JOIN				1
++#define BRCMF_E_START				2
++#define BRCMF_E_AUTH				3
++#define BRCMF_E_AUTH_IND			4
++#define BRCMF_E_DEAUTH				5
++#define BRCMF_E_DEAUTH_IND			6
++#define BRCMF_E_ASSOC				7
++#define BRCMF_E_ASSOC_IND			8
++#define BRCMF_E_REASSOC				9
++#define BRCMF_E_REASSOC_IND			10
++#define BRCMF_E_DISASSOC			11
++#define BRCMF_E_DISASSOC_IND			12
++#define BRCMF_E_QUIET_START			13
++#define BRCMF_E_QUIET_END			14
++#define BRCMF_E_BEACON_RX			15
++#define BRCMF_E_LINK				16
++#define BRCMF_E_MIC_ERROR			17
++#define BRCMF_E_NDIS_LINK			18
++#define BRCMF_E_ROAM				19
++#define BRCMF_E_TXFAIL				20
++#define BRCMF_E_PMKID_CACHE			21
++#define BRCMF_E_RETROGRADE_TSF			22
++#define BRCMF_E_PRUNE				23
++#define BRCMF_E_AUTOAUTH			24
++#define BRCMF_E_EAPOL_MSG			25
++#define BRCMF_E_SCAN_COMPLETE			26
++#define BRCMF_E_ADDTS_IND			27
++#define BRCMF_E_DELTS_IND			28
++#define BRCMF_E_BCNSENT_IND			29
++#define BRCMF_E_BCNRX_MSG			30
++#define BRCMF_E_BCNLOST_MSG			31
++#define BRCMF_E_ROAM_PREP			32
++#define BRCMF_E_PFN_NET_FOUND			33
++#define BRCMF_E_PFN_NET_LOST			34
++#define BRCMF_E_RESET_COMPLETE			35
++#define BRCMF_E_JOIN_START			36
++#define BRCMF_E_ROAM_START			37
++#define BRCMF_E_ASSOC_START			38
++#define BRCMF_E_IBSS_ASSOC			39
++#define BRCMF_E_RADIO				40
++#define BRCMF_E_PSM_WATCHDOG			41
++#define BRCMF_E_PROBREQ_MSG			44
++#define BRCMF_E_SCAN_CONFIRM_IND		45
++#define BRCMF_E_PSK_SUP				46
++#define BRCMF_E_COUNTRY_CODE_CHANGED		47
++#define	BRCMF_E_EXCEEDED_MEDIUM_TIME		48
++#define BRCMF_E_ICV_ERROR			49
++#define BRCMF_E_UNICAST_DECODE_ERROR		50
++#define BRCMF_E_MULTICAST_DECODE_ERROR		51
++#define BRCMF_E_TRACE				52
++#define BRCMF_E_IF				54
++#define BRCMF_E_RSSI				56
++#define BRCMF_E_PFN_SCAN_COMPLETE		57
++#define BRCMF_E_EXTLOG_MSG			58
++#define BRCMF_E_ACTION_FRAME			59
++#define BRCMF_E_ACTION_FRAME_COMPLETE		60
++#define BRCMF_E_PRE_ASSOC_IND			61
++#define BRCMF_E_PRE_REASSOC_IND			62
++#define BRCMF_E_CHANNEL_ADOPTED			63
++#define BRCMF_E_AP_STARTED			64
++#define BRCMF_E_DFS_AP_STOP			65
++#define BRCMF_E_DFS_AP_RESUME			66
++#define BRCMF_E_RESERVED1			67
++#define BRCMF_E_RESERVED2			68
++#define BRCMF_E_ESCAN_RESULT			69
++#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE	70
++#define BRCMF_E_DCS_REQUEST			73
++
++#define BRCMF_E_FIFO_CREDIT_MAP			74
++
++#define BRCMF_E_LAST				75
++
++#define BRCMF_E_STATUS_SUCCESS			0
++#define BRCMF_E_STATUS_FAIL			1
++#define BRCMF_E_STATUS_TIMEOUT			2
++#define BRCMF_E_STATUS_NO_NETWORKS		3
++#define BRCMF_E_STATUS_ABORT			4
++#define BRCMF_E_STATUS_NO_ACK			5
++#define BRCMF_E_STATUS_UNSOLICITED		6
++#define BRCMF_E_STATUS_ATTEMPT			7
++#define BRCMF_E_STATUS_PARTIAL			8
++#define BRCMF_E_STATUS_NEWSCAN			9
++#define BRCMF_E_STATUS_NEWASSOC			10
++#define BRCMF_E_STATUS_11HQUIET			11
++#define BRCMF_E_STATUS_SUPPRESS			12
++#define BRCMF_E_STATUS_NOCHANS			13
++#define BRCMF_E_STATUS_CS_ABORT			15
++#define BRCMF_E_STATUS_ERROR			16
++
++#define BRCMF_E_REASON_INITIAL_ASSOC		0
++#define BRCMF_E_REASON_LOW_RSSI			1
++#define BRCMF_E_REASON_DEAUTH			2
++#define BRCMF_E_REASON_DISASSOC			3
++#define BRCMF_E_REASON_BCNS_LOST		4
++#define BRCMF_E_REASON_MINTXRATE		9
++#define BRCMF_E_REASON_TXFAIL			10
++
++#define BRCMF_E_REASON_FAST_ROAM_FAILED		5
++#define BRCMF_E_REASON_DIRECTED_ROAM		6
++#define BRCMF_E_REASON_TSPEC_REJECTED		7
++#define BRCMF_E_REASON_BETTER_AP		8
++
++#define BRCMF_E_PRUNE_ENCR_MISMATCH		1
++#define BRCMF_E_PRUNE_BCAST_BSSID		2
++#define BRCMF_E_PRUNE_MAC_DENY			3
++#define BRCMF_E_PRUNE_MAC_NA			4
++#define BRCMF_E_PRUNE_REG_PASSV			5
++#define BRCMF_E_PRUNE_SPCT_MGMT			6
++#define BRCMF_E_PRUNE_RADAR			7
++#define BRCMF_E_RSN_MISMATCH			8
++#define BRCMF_E_PRUNE_NO_COMMON_RATES		9
++#define BRCMF_E_PRUNE_BASIC_RATES		10
++#define BRCMF_E_PRUNE_CIPHER_NA			12
++#define BRCMF_E_PRUNE_KNOWN_STA			13
++#define BRCMF_E_PRUNE_WDS_PEER			15
++#define BRCMF_E_PRUNE_QBSS_LOAD			16
++#define BRCMF_E_PRUNE_HOME_AP			17
++
++#define BRCMF_E_SUP_OTHER			0
++#define BRCMF_E_SUP_DECRYPT_KEY_DATA		1
++#define BRCMF_E_SUP_BAD_UCAST_WEP128		2
++#define BRCMF_E_SUP_BAD_UCAST_WEP40		3
++#define BRCMF_E_SUP_UNSUP_KEY_LEN		4
++#define BRCMF_E_SUP_PW_KEY_CIPHER		5
++#define BRCMF_E_SUP_MSG3_TOO_MANY_IE		6
++#define BRCMF_E_SUP_MSG3_IE_MISMATCH		7
++#define BRCMF_E_SUP_NO_INSTALL_FLAG		8
++#define BRCMF_E_SUP_MSG3_NO_GTK			9
++#define BRCMF_E_SUP_GRP_KEY_CIPHER		10
++#define BRCMF_E_SUP_GRP_MSG1_NO_GTK		11
++#define BRCMF_E_SUP_GTK_DECRYPT_FAIL		12
++#define BRCMF_E_SUP_SEND_FAIL			13
++#define BRCMF_E_SUP_DEAUTH			14
++
++#define BRCMF_E_IF_ADD				1
++#define BRCMF_E_IF_DEL				2
++#define BRCMF_E_IF_CHANGE			3
++
++#define BRCMF_E_IF_ROLE_STA			0
++#define BRCMF_E_IF_ROLE_AP			1
++#define BRCMF_E_IF_ROLE_WDS			2
++
++#define BRCMF_E_LINK_BCN_LOSS			1
++#define BRCMF_E_LINK_DISASSOC			2
++#define BRCMF_E_LINK_ASSOC_REC			3
++#define BRCMF_E_LINK_BSSCFG_DIS			4
++
++/* Pattern matching filter. Specifies an offset within received packets to
++ * start matching, the pattern to match, the size of the pattern, and a bitmask
++ * that indicates which bits within the pattern should be matched.
++ */
++struct brcmf_pkt_filter_pattern_le {
++	/*
++	 * Offset within received packet to start pattern matching.
++	 * Offset '0' is the first byte of the ethernet header.
++	 */
++	__le32 offset;
++	/* Size of the pattern.  Bitmask must be the same size.*/
++	__le32 size_bytes;
++	/*
++	 * Variable length mask and pattern data. mask starts at offset 0.
++	 * Pattern immediately follows mask.
++	 */
++	u8 mask_and_pattern[1];
++};
++
++/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
++struct brcmf_pkt_filter_le {
++	__le32 id;		/* Unique filter id, specified by app. */
++	__le32 type;		/* Filter type (WL_PKT_FILTER_TYPE_xxx). */
++	__le32 negate_match;	/* Negate the result of filter matches */
++	union {			/* Filter definitions */
++		struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
++	} u;
++};
++
++/* IOVAR "pkt_filter_enable" parameter. */
++struct brcmf_pkt_filter_enable_le {
++	__le32 id;		/* Unique filter id */
++	__le32 enable;		/* Enable/disable bool */
++};
++
++/* BSS info structure
++ * Applications MUST CHECK ie_offset field and length field to access IEs and
++ * next bss_info structure in a vector (in struct brcmf_scan_results)
++ */
++struct brcmf_bss_info_le {
++	__le32 version;		/* version field */
++	__le32 length;		/* byte length of data in this record,
++				 * starting at version and including IEs
++				 */
++	u8 BSSID[ETH_ALEN];
++	__le16 beacon_period;	/* units are Kusec */
++	__le16 capability;	/* Capability information */
++	u8 SSID_len;
++	u8 SSID[32];
++	struct {
++		__le32 count;   /* # rates in this set */
++		u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
++	} rateset;		/* supported rates */
++	__le16 chanspec;	/* chanspec for bss */
++	__le16 atim_window;	/* units are Kusec */
++	u8 dtim_period;	/* DTIM period */
++	__le16 RSSI;		/* receive signal strength (in dBm) */
++	s8 phy_noise;		/* noise (in dBm) */
++
++	u8 n_cap;		/* BSS is 802.11N Capable */
++	/* 802.11N BSS Capabilities (based on HT_CAP_*): */
++	__le32 nbss_cap;
++	u8 ctl_ch;		/* 802.11N BSS control channel number */
++	__le32 reserved32[1];	/* Reserved for expansion of BSS properties */
++	u8 flags;		/* flags */
++	u8 reserved[3];	/* Reserved for expansion of BSS properties */
++	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
++
++	__le16 ie_offset;	/* offset at which IEs start, from beginning */
++	__le32 ie_length;	/* byte length of Information Elements */
++	__le16 SNR;		/* average SNR of during frame reception */
++	/* Add new fields here */
++	/* variable length Information Elements */
++};
++
++struct brcm_rateset_le {
++	/* # rates in this set */
++	__le32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcmf_ssid {
++	u32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_ssid_le {
++	__le32 SSID_len;
++	unsigned char SSID[32];
++};
++
++struct brcmf_scan_params_le {
++	struct brcmf_ssid_le ssid_le;	/* default: {0, ""} */
++	u8 bssid[ETH_ALEN];	/* default: bcast */
++	s8 bss_type;		/* default: any,
++				 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
++				 */
++	u8 scan_type;	/* flags, 0 use default */
++	__le32 nprobes;	  /* -1 use default, number of probes per channel */
++	__le32 active_time;	/* -1 use default, dwell time per channel for
++				 * active scanning
++				 */
++	__le32 passive_time;	/* -1 use default, dwell time per channel
++				 * for passive scanning
++				 */
++	__le32 home_time;	/* -1 use default, dwell time for the
++				 * home channel between channel scans
++				 */
++	__le32 channel_num;	/* count of channels and ssids that follow
++				 *
++				 * low half is count of channels in
++				 * channel_list, 0 means default (use all
++				 * available channels)
++				 *
++				 * high half is entries in struct brcmf_ssid
++				 * array that follows channel_list, aligned for
++				 * s32 (4 bytes) meaning an odd channel count
++				 * implies a 2-byte pad between end of
++				 * channel_list and first ssid
++				 *
++				 * if ssid count is zero, single ssid in the
++				 * fixed parameter portion is assumed, otherwise
++				 * ssid in the fixed portion is ignored
++				 */
++	__le16 channel_list[1];	/* list of chanspecs */
++};
++
++/* incremental scan struct */
++struct brcmf_iscan_params_le {
++	__le32 version;
++	__le16 action;
++	__le16 scan_duration;
++	struct brcmf_scan_params_le params_le;
++};
++
++struct brcmf_scan_results {
++	u32 buflen;
++	u32 version;
++	u32 count;
++	struct brcmf_bss_info_le bss_info_le[];
++};
++
++struct brcmf_scan_results_le {
++	__le32 buflen;
++	__le32 version;
++	__le32 count;
++};
++
++/* used for association with a specific BSSID and chanspec list */
++struct brcmf_assoc_params_le {
++	/* 00:00:00:00:00:00: broadcast scan */
++	u8 bssid[ETH_ALEN];
++	/* 0: all available channels, otherwise count of chanspecs in
++	 * chanspec_list */
++	__le32 chanspec_num;
++	/* list of chanspecs */
++	__le16 chanspec_list[1];
++};
++
++/* used for join with or without a specific bssid and channel list */
++struct brcmf_join_params {
++	struct brcmf_ssid_le ssid_le;
++	struct brcmf_assoc_params_le params_le;
++};
++
++/* incremental scan results struct */
++struct brcmf_iscan_results {
++	union {
++		u32 status;
++		__le32 status_le;
++	};
++	union {
++		struct brcmf_scan_results results;
++		struct brcmf_scan_results_le results_le;
++	};
++};
++
++/* size of brcmf_iscan_results not including variable length array */
++#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
++	(sizeof(struct brcmf_scan_results) + \
++	 offsetof(struct brcmf_iscan_results, results))
++
++struct brcmf_wsec_key {
++	u32 index;		/* key index */
++	u32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	u32 pad_1[18];
++	u32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	u32 flags;	/* misc flags */
++	u32 pad_2[3];
++	u32 iv_initialized;	/* has IV been initialized already? */
++	u32 pad_3;
++	/* Rx IV */
++	struct {
++		u32 hi;	/* upper 32 bits of IV */
++		u16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	u32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/*
++ * dongle requires same struct as above but with fields in little endian order
++ */
++struct brcmf_wsec_key_le {
++	__le32 index;		/* key index */
++	__le32 len;		/* key length */
++	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
++	__le32 pad_1[18];
++	__le32 algo;	/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
++	__le32 flags;	/* misc flags */
++	__le32 pad_2[3];
++	__le32 iv_initialized;	/* has IV been initialized already? */
++	__le32 pad_3;
++	/* Rx IV */
++	struct {
++		__le32 hi;	/* upper 32 bits of IV */
++		__le16 lo;	/* lower 16 bits of IV */
++	} rxiv;
++	__le32 pad_4[2];
++	u8 ea[ETH_ALEN];	/* per station */
++};
++
++/* Used to get specific STA parameters */
++struct brcmf_scb_val_le {
++	__le32 val;
++	u8 ea[ETH_ALEN];
++};
++
++/* channel encoding */
++struct brcmf_channel_info_le {
++	__le32 hw_channel;
++	__le32 target_channel;
++	__le32 scan_channel;
++};
++
++/* Bus independent dongle command */
++struct brcmf_dcmd {
++	uint cmd;		/* common dongle cmd definition */
++	void *buf;		/* pointer to user buffer */
++	uint len;		/* length of user buffer */
++	u8 set;			/* get or set request (optional) */
++	uint used;		/* bytes read or written (optional) */
++	uint needed;		/* bytes needed (optional) */
++};
++
++/* Forward decls for struct brcmf_pub (see below) */
++struct brcmf_proto;	/* device communication protocol info */
++struct brcmf_cfg80211_dev; /* cfg80211 device info */
++
++/* Common structure for module and instance linkage */
++struct brcmf_pub {
++	/* Linkage ponters */
++	struct brcmf_bus *bus_if;
++	struct brcmf_proto *prot;
++	struct brcmf_cfg80211_dev *config;
++	struct device *dev;		/* fullmac dongle device pointer */
++
++	/* Internal brcmf items */
++	uint hdrlen;		/* Total BRCMF header length (proto + bus) */
++	uint rxsz;		/* Rx buffer size bus module should use */
++	u8 wme_dp;		/* wme discard priority */
++
++	/* Dongle media info */
++	bool iswl;		/* Dongle-resident driver is wl */
++	unsigned long drv_version;	/* Version of dongle-resident driver */
++	u8 mac[ETH_ALEN];		/* MAC address obtained from dongle */
++
++	/* Additional stats for the bus level */
++
++	/* Multicast data packets sent to dongle */
++	unsigned long tx_multicast;
++	/* Packets flushed due to unscheduled sendup thread */
++	unsigned long rx_flushed;
++	/* Number of times dpc scheduled by watchdog timer */
++	unsigned long wd_dpc_sched;
++
++	/* Number of flow control pkts recvd */
++	unsigned long fc_packets;
++
++	/* Last error return */
++	int bcmerror;
++
++	/* Last error from dongle */
++	int dongle_error;
++
++	/* Suspend disable flag  flag */
++	int suspend_disable_flag;	/* "1" to disable all extra powersaving
++					 during suspend */
++	int in_suspend;		/* flag set to 1 when early suspend called */
++	int dtim_skip;		/* dtim skip , default 0 means wake each dtim */
++
++	/* Pkt filter defination */
++	char *pktfilter[100];
++	int pktfilter_count;
++
++	u8 country_code[BRCM_CNTRY_BUF_SZ];
++	char eventmask[BRCMF_EVENTING_MASK_LEN];
++
++	struct brcmf_if *iflist[BRCMF_MAX_IFS];
++
++	struct mutex proto_block;
++
++	struct work_struct setmacaddr_work;
++	struct work_struct multicast_work;
++	u8 macvalue[ETH_ALEN];
++	atomic_t pend_8021x_cnt;
++};
++
++struct brcmf_if_event {
++	u8 ifidx;
++	u8 action;
++	u8 flags;
++	u8 bssidx;
++};
++
++struct bcmevent_name {
++	uint event;
++	const char *name;
++};
++
++extern const struct bcmevent_name bcmevent_names[];
++
++extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
++			  char *buf, uint len);
++
++extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
++
++extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
++
++/* Return pointer to interface name */
++extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
++
++/* Query dongle */
++extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
++				       uint cmd, void *buf, uint len);
++
++#ifdef DEBUG
++extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
++#endif				/* DEBUG */
++
++extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
++extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
++			      void *pktdata, struct brcmf_event_msg *,
++			      void **data_ptr);
++
++extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
++
++/* Send packet to dongle via data channel */
++extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
++			 struct sk_buff *pkt);
++
++extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
++extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
++					     int enable, int master_mode);
++
++#define	BRCMF_DCMD_SMLEN	256	/* "small" cmd buffer required */
++#define BRCMF_DCMD_MEDLEN	1536	/* "med" cmd buffer required */
++#define	BRCMF_DCMD_MAXLEN	8192	/* max length cmd buffer required */
++
++#endif				/* _BRCMF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+new file mode 100644
+index 0000000..3669164
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+@@ -0,0 +1,118 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_BUS_H_
++#define _BRCMF_BUS_H_
++
++/* The level of bus communication with the dongle */
++enum brcmf_bus_state {
++	BRCMF_BUS_DOWN,		/* Not ready for frame transfers */
++	BRCMF_BUS_LOAD,		/* Download access only (CPU reset) */
++	BRCMF_BUS_DATA		/* Ready for frame transfers */
++};
++
++struct dngl_stats {
++	unsigned long rx_packets;	/* total packets received */
++	unsigned long tx_packets;	/* total packets transmitted */
++	unsigned long rx_bytes;	/* total bytes received */
++	unsigned long tx_bytes;	/* total bytes transmitted */
++	unsigned long rx_errors;	/* bad packets received */
++	unsigned long tx_errors;	/* packet transmit problems */
++	unsigned long rx_dropped;	/* packets dropped by dongle */
++	unsigned long tx_dropped;	/* packets dropped by dongle */
++	unsigned long multicast;	/* multicast packets received */
++};
++
++/* interface structure between common and bus layer */
++struct brcmf_bus {
++	u8 type;		/* bus type */
++	union {
++		struct brcmf_sdio_dev *sdio;
++		struct brcmf_usbdev *usb;
++	} bus_priv;
++	struct brcmf_pub *drvr;	/* pointer to driver pub structure brcmf_pub */
++	enum brcmf_bus_state state;
++	uint maxctl;		/* Max size rxctl request from proto to bus */
++	bool drvr_up;		/* Status flag of driver up/down */
++	unsigned long tx_realloc;	/* Tx packets realloced for headroom */
++	struct dngl_stats dstats;	/* Stats for dongle-based data */
++	u8 align;		/* bus alignment requirement */
++
++	/* interface functions pointers */
++	/* Stop bus module: clear pending frames, disable data flow */
++	void (*brcmf_bus_stop)(struct device *);
++	/* Initialize bus module: prepare for communication w/dongle */
++	int (*brcmf_bus_init)(struct device *);
++	/* Send a data frame to the dongle.  Callee disposes of txp. */
++	int (*brcmf_bus_txdata)(struct device *, struct sk_buff *);
++	/* Send/receive a control message to/from the dongle.
++	 * Expects caller to enforce a single outstanding transaction.
++	 */
++	int (*brcmf_bus_txctl)(struct device *, unsigned char *, uint);
++	int (*brcmf_bus_rxctl)(struct device *, unsigned char *, uint);
++};
++
++/*
++ * interface functions from common layer
++ */
++
++/* Remove any protocol-specific data header. */
++extern int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			       struct sk_buff *rxp);
++
++extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++			 struct sk_buff *pkt, int prec);
++
++/* Receive frame for delivery to OS.  Callee disposes of rxp. */
++extern void brcmf_rx_frame(struct device *dev, int ifidx,
++			   struct sk_buff_head *rxlist);
++static inline void brcmf_rx_packet(struct device *dev, int ifidx,
++				   struct sk_buff *pkt)
++{
++	struct sk_buff_head q;
++
++	skb_queue_head_init(&q);
++	skb_queue_tail(&q, pkt);
++	brcmf_rx_frame(dev, ifidx, &q);
++}
++
++/* Indication from bus module regarding presence/insertion of dongle. */
++extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
++/* Indication from bus module regarding removal/absence of dongle */
++extern void brcmf_detach(struct device *dev);
++
++/* Indication from bus module to change flow-control state */
++extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on);
++
++/* Notify tx completion */
++extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
++			     bool success);
++
++extern int brcmf_bus_start(struct device *dev);
++
++extern int brcmf_add_if(struct device *dev, int ifidx,
++			char *name, u8 *mac_addr);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++extern void brcmf_sdio_exit(void);
++extern void brcmf_sdio_init(void);
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++extern void brcmf_usb_exit(void);
++extern void brcmf_usb_init(void);
++#endif
++
++#endif				/* _BRCMF_BUS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+new file mode 100644
+index 0000000..ca28295
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+@@ -0,0 +1,495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*******************************************************************************
++ * Communicates with the dongle by using dcmd codes.
++ * For certain dcmd codes, the dongle interprets string data from the host.
++ ******************************************************************************/
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <defs.h>
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_proto.h"
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++struct brcmf_proto_cdc_dcmd {
++	__le32 cmd;	/* dongle command value */
++	__le32 len;	/* lower 16: output buflen;
++			 * upper 16: input buflen (excludes header) */
++	__le32 flags;	/* flag defns given below */
++	__le32 status;	/* status code returned from the device */
++};
++
++/* Max valid buffer size that can be sent to the dongle */
++#define CDC_MAX_MSG_SIZE	(ETH_FRAME_LEN+ETH_FCS_LEN)
++
++/* CDC flag definitions */
++#define CDC_DCMD_ERROR		0x01	/* 1=cmd failed */
++#define CDC_DCMD_SET		0x02	/* 0=get, 1=set cmd */
++#define CDC_DCMD_IF_MASK	0xF000		/* I/F index */
++#define CDC_DCMD_IF_SHIFT	12
++#define CDC_DCMD_ID_MASK	0xFFFF0000	/* id an cmd pairing */
++#define CDC_DCMD_ID_SHIFT	16		/* ID Mask shift bits */
++#define CDC_DCMD_ID(flags)	\
++	(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
++
++/*
++ * BDC header - Broadcom specific extension of CDC.
++ * Used on data packets to convey priority across USB.
++ */
++#define	BDC_HEADER_LEN		4
++#define BDC_PROTO_VER		2	/* Protocol version */
++#define BDC_FLAG_VER_MASK	0xf0	/* Protocol version mask */
++#define BDC_FLAG_VER_SHIFT	4	/* Protocol version shift */
++#define BDC_FLAG_SUM_GOOD	0x04	/* Good RX checksums */
++#define BDC_FLAG_SUM_NEEDED	0x08	/* Dongle needs to do TX checksums */
++#define BDC_PRIORITY_MASK	0x7
++#define BDC_FLAG2_IF_MASK	0x0f	/* packet rx interface in APSTA */
++#define BDC_FLAG2_IF_SHIFT	0
++
++#define BDC_GET_IF_IDX(hdr) \
++	((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
++#define BDC_SET_IF_IDX(hdr, idx) \
++	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
++	((idx) << BDC_FLAG2_IF_SHIFT)))
++
++struct brcmf_proto_bdc_header {
++	u8 flags;
++	u8 priority;	/* 802.1d Priority, 4:7 flow control info for usb */
++	u8 flags2;
++	u8 data_offset;
++};
++
++
++#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
++#define BUS_HEADER_LEN	(16+64)		/* Must be atleast SDPCM_RESERVE
++					 * (amount of header tha might be added)
++					 * plus any space that might be needed
++					 * for bus alignment padding.
++					 */
++#define ROUND_UP_MARGIN	2048	/* Biggest bus block size possible for
++				 * round off at the end of buffer
++				 * Currently is SDIO
++				 */
++
++struct brcmf_proto {
++	u16 reqid;
++	u8 pending;
++	u32 lastcmd;
++	u8 bus_header[BUS_HEADER_LEN];
++	struct brcmf_proto_cdc_dcmd msg;
++	unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
++};
++
++static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int len = le32_to_cpu(prot->msg.len) +
++			sizeof(struct brcmf_proto_cdc_dcmd);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
++	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
++	 *        is actually sent to the dongle
++	 */
++	if (len > CDC_MAX_MSG_SIZE)
++		len = CDC_MAX_MSG_SIZE;
++
++	/* Send request */
++	return drvr->bus_if->brcmf_bus_txctl(drvr->dev,
++					     (unsigned char *)&prot->msg,
++					     len);
++}
++
++static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
++{
++	int ret;
++	struct brcmf_proto *prot = drvr->prot;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	do {
++		ret = drvr->bus_if->brcmf_bus_rxctl(drvr->dev,
++				(unsigned char *)&prot->msg,
++				len + sizeof(struct brcmf_proto_cdc_dcmd));
++		if (ret < 0)
++			break;
++	} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
++
++	return ret;
++}
++
++int
++brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++			       void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	void *info;
++	int ret = 0, retries = 0;
++	u32 id, flags;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
++	if (cmd == BRCMF_C_GET_VAR && buf) {
++		if (!strcmp((char *)buf, "bcmerrorstr")) {
++			strncpy((char *)buf, "bcm_error",
++				BCME_STRLEN);
++			goto done;
++		} else if (!strcmp((char *)buf, "bcmerror")) {
++			*(int *)buf = drvr->dongle_error;
++			goto done;
++		}
++	}
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
++			  ret);
++		goto done;
++	}
++
++retry:
++	/* wait for interrupt and get first fragment */
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if ((id < prot->reqid) && (++retries < RETRIES))
++		goto retry;
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check info buffer */
++	info = (void *)&msg[1];
++
++	/* Copy info buffer */
++	if (buf) {
++		if (ret < (int)len)
++			len = ret;
++		memcpy(buf, info, len);
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
++				 void *buf, uint len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++	int ret = 0;
++	u32 flags, id;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
++
++	memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
++
++	msg->cmd = cpu_to_le32(cmd);
++	msg->len = cpu_to_le32(len);
++	flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
++	flags = (flags & ~CDC_DCMD_IF_MASK) |
++		(ifidx << CDC_DCMD_IF_SHIFT);
++	msg->flags = cpu_to_le32(flags);
++
++	if (buf)
++		memcpy(prot->buf, buf, len);
++
++	ret = brcmf_proto_cdc_msg(drvr);
++	if (ret < 0)
++		goto done;
++
++	ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
++	if (ret < 0)
++		goto done;
++
++	flags = le32_to_cpu(msg->flags);
++	id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
++
++	if (id != prot->reqid) {
++		brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
++			  brcmf_ifname(drvr, ifidx), id, prot->reqid);
++		ret = -EINVAL;
++		goto done;
++	}
++
++	/* Check the ERROR flag */
++	if (flags & CDC_DCMD_ERROR) {
++		ret = le32_to_cpu(msg->status);
++		/* Cache error from dongle */
++		drvr->dongle_error = ret;
++	}
++
++done:
++	return ret;
++}
++
++int
++brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
++		  int len)
++{
++	struct brcmf_proto *prot = drvr->prot;
++	int ret = -1;
++
++	if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
++		return ret;
++	}
++	mutex_lock(&drvr->proto_block);
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (len > BRCMF_DCMD_MAXLEN)
++		goto done;
++
++	if (prot->pending == true) {
++		brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
++			  dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
++			  (unsigned long)prot->lastcmd);
++		if (dcmd->cmd == BRCMF_C_SET_VAR ||
++		    dcmd->cmd == BRCMF_C_GET_VAR)
++			brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
++
++		goto done;
++	}
++
++	prot->pending = true;
++	prot->lastcmd = dcmd->cmd;
++	if (dcmd->set)
++		ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
++						   dcmd->buf, len);
++	else {
++		ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
++						     dcmd->buf, len);
++		if (ret > 0)
++			dcmd->used = ret -
++					sizeof(struct brcmf_proto_cdc_dcmd);
++	}
++
++	if (ret >= 0)
++		ret = 0;
++	else {
++		struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
++		/* len == needed when set/query fails from dongle */
++		dcmd->needed = le32_to_cpu(msg->len);
++	}
++
++	/* Intercept the wme_dp dongle cmd here */
++	if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
++	    !strcmp(dcmd->buf, "wme_dp")) {
++		int slen;
++		__le32 val = 0;
++
++		slen = strlen("wme_dp") + 1;
++		if (len >= (int)(slen + sizeof(int)))
++			memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
++		drvr->wme_dp = (u8) le32_to_cpu(val);
++	}
++
++	prot->pending = false;
++
++done:
++	mutex_unlock(&drvr->proto_block);
++
++	return ret;
++}
++
++static bool pkt_sum_needed(struct sk_buff *skb)
++{
++	return skb->ip_summed == CHECKSUM_PARTIAL;
++}
++
++static void pkt_set_sum_good(struct sk_buff *skb, bool x)
++{
++	skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
++}
++
++void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
++			 struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Push BDC header used to convey priority for buses that don't */
++
++	skb_push(pktbuf, BDC_HEADER_LEN);
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
++	if (pkt_sum_needed(pktbuf))
++		h->flags |= BDC_FLAG_SUM_NEEDED;
++
++	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
++	h->flags2 = 0;
++	h->data_offset = 0;
++	BDC_SET_IF_IDX(h, ifidx);
++}
++
++int brcmf_proto_hdrpull(struct device *dev, int *ifidx,
++			struct sk_buff *pktbuf)
++{
++	struct brcmf_proto_bdc_header *h;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Pop BDC header used to convey priority for buses that don't */
++
++	if (pktbuf->len < BDC_HEADER_LEN) {
++		brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
++			  pktbuf->len, BDC_HEADER_LEN);
++		return -EBADE;
++	}
++
++	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
++
++	*ifidx = BDC_GET_IF_IDX(h);
++	if (*ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
++		return -EBADE;
++	}
++
++	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
++	    BDC_PROTO_VER) {
++		brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		return -EBADE;
++	}
++
++	if (h->flags & BDC_FLAG_SUM_GOOD) {
++		brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
++			  brcmf_ifname(drvr, *ifidx), h->flags);
++		pkt_set_sum_good(pktbuf, true);
++	}
++
++	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
++
++	skb_pull(pktbuf, BDC_HEADER_LEN);
++	skb_pull(pktbuf, h->data_offset << 2);
++
++	return 0;
++}
++
++int brcmf_proto_attach(struct brcmf_pub *drvr)
++{
++	struct brcmf_proto *cdc;
++
++	cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
++	if (!cdc)
++		goto fail;
++
++	/* ensure that the msg buf directly follows the cdc msg struct */
++	if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
++		brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
++		goto fail;
++	}
++
++	drvr->prot = cdc;
++	drvr->hdrlen += BDC_HEADER_LEN;
++	drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
++			sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
++	return 0;
++
++fail:
++	kfree(cdc);
++	return -ENOMEM;
++}
++
++/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
++void brcmf_proto_detach(struct brcmf_pub *drvr)
++{
++	kfree(drvr->prot);
++	drvr->prot = NULL;
++}
++
++int brcmf_proto_init(struct brcmf_pub *drvr)
++{
++	int ret = 0;
++	char buf[128];
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Get the device MAC address */
++	strcpy(buf, "cur_etheraddr");
++	ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
++					  buf, sizeof(buf));
++	if (ret < 0) {
++		mutex_unlock(&drvr->proto_block);
++		return ret;
++	}
++	memcpy(drvr->mac, buf, ETH_ALEN);
++
++	mutex_unlock(&drvr->proto_block);
++
++	ret = brcmf_c_preinit_dcmds(drvr);
++
++	/* Always assumes wl for now */
++	drvr->iswl = true;
++
++	return ret;
++}
++
++void brcmf_proto_stop(struct brcmf_pub *drvr)
++{
++	/* Nothing to do for CDC */
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+new file mode 100644
+index 0000000..2962900
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+@@ -0,0 +1,882 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/string.h>
++#include <linux/sched.h>
++#include <linux/netdevice.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++
++#define BRCM_OUI			"\x00\x10\x18"
++#define DOT11_OUI_LEN			3
++#define BCMILCP_BCM_SUBTYPE_EVENT	1
++#define PKTFILTER_BUF_SIZE		2048
++#define BRCMF_ARPOL_MODE		0xb	/* agent|snoop|peer_autoreply */
++
++#define MSGTRACE_VERSION	1
++
++#define BRCMF_PKT_FILTER_FIXED_LEN	offsetof(struct brcmf_pkt_filter_le, u)
++#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN	\
++	offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
++
++#ifdef DEBUG
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
++	__DATE__ " at " __TIME__;
++#else
++static const char brcmf_version[] =
++	"Dongle Host Driver, version " BRCMF_VERSION_STR;
++#endif
++
++/* Message trace header */
++struct msgtrace_hdr {
++	u8 version;
++	u8 spare;
++	__be16 len;		/* Len of the trace */
++	__be32 seqnum;		/* Sequence number of message. Useful
++				 * if the messsage has been lost
++				 * because of DMA error or a bus reset
++				 * (ex: SDIO Func2)
++				 */
++	__be32 discarded_bytes;	/* Number of discarded bytes because of
++				 trace overflow  */
++	__be32 discarded_printf;	/* Number of discarded printf
++				 because of trace overflow */
++} __packed;
++
++
++uint
++brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
++{
++	uint len;
++
++	len = strlen(name) + 1;
++
++	if ((len + datalen) > buflen)
++		return 0;
++
++	strncpy(buf, name, buflen);
++
++	/* append data onto the end of the name string */
++	memcpy(&buf[len], data, datalen);
++	len += datalen;
++
++	return len;
++}
++
++bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++	bool discard_oldest;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	/* Fast case, precedence queue is not full and we are also not
++	 * exceeding total queue length
++	 */
++	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
++		brcmu_pktq_penq(q, prec, pkt);
++		return true;
++	}
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec)
++			return false;
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		/* Detect queueing to unconfigured precedence */
++		discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
++		if (eprec == prec && !discard_oldest)
++			return false;	/* refuse newer (incoming) packet */
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		if (p == NULL)
++			brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
++				  discard_oldest);
++
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	p = brcmu_pktq_penq(q, prec, pkt);
++	if (p == NULL)
++		brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
++
++	return p != NULL;
++}
++
++#ifdef DEBUG
++static void
++brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
++{
++	uint i, status, reason;
++	bool group = false, flush_txq = false, link = false;
++	char *auth_str, *event_name;
++	unsigned char *buf;
++	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
++	static struct {
++		uint event;
++		char *event_name;
++	} event_names[] = {
++		{
++		BRCMF_E_SET_SSID, "SET_SSID"}, {
++		BRCMF_E_JOIN, "JOIN"}, {
++		BRCMF_E_START, "START"}, {
++		BRCMF_E_AUTH, "AUTH"}, {
++		BRCMF_E_AUTH_IND, "AUTH_IND"}, {
++		BRCMF_E_DEAUTH, "DEAUTH"}, {
++		BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
++		BRCMF_E_ASSOC, "ASSOC"}, {
++		BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
++		BRCMF_E_REASSOC, "REASSOC"}, {
++		BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
++		BRCMF_E_DISASSOC, "DISASSOC"}, {
++		BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
++		BRCMF_E_QUIET_START, "START_QUIET"}, {
++		BRCMF_E_QUIET_END, "END_QUIET"}, {
++		BRCMF_E_BEACON_RX, "BEACON_RX"}, {
++		BRCMF_E_LINK, "LINK"}, {
++		BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
++		BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
++		BRCMF_E_ROAM, "ROAM"}, {
++		BRCMF_E_TXFAIL, "TXFAIL"}, {
++		BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
++		BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
++		BRCMF_E_PRUNE, "PRUNE"}, {
++		BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
++		BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
++		BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
++		BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
++		BRCMF_E_DELTS_IND, "DELTS_IND"}, {
++		BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
++		BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
++		BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
++		BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
++		BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
++		BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
++		BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
++		BRCMF_E_JOIN_START, "JOIN_START"}, {
++		BRCMF_E_ROAM_START, "ROAM_START"}, {
++		BRCMF_E_ASSOC_START, "ASSOC_START"}, {
++		BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
++		BRCMF_E_RADIO, "RADIO"}, {
++		BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
++		BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
++		BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
++		BRCMF_E_PSK_SUP, "PSK_SUP"}, {
++		BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
++		BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
++		BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
++		BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
++		BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
++		BRCMF_E_TRACE, "TRACE"}, {
++		BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
++		BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
++		BRCMF_E_IF, "IF"}, {
++		BRCMF_E_RSSI, "RSSI"}, {
++		BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
++	};
++	uint event_type, flags, auth_type, datalen;
++	static u32 seqnum_prev;
++	struct msgtrace_hdr hdr;
++	u32 nblost;
++	char *s, *p;
++
++	event_type = be32_to_cpu(event->event_type);
++	flags = be16_to_cpu(event->flags);
++	status = be32_to_cpu(event->status);
++	reason = be32_to_cpu(event->reason);
++	auth_type = be32_to_cpu(event->auth_type);
++	datalen = be32_to_cpu(event->datalen);
++	/* debug dump of event messages */
++	sprintf(eabuf, "%pM", event->addr);
++
++	event_name = "UNKNOWN";
++	for (i = 0; i < ARRAY_SIZE(event_names); i++) {
++		if (event_names[i].event == event_type)
++			event_name = event_names[i].event_name;
++	}
++
++	brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
++	brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
++		  flags, status, reason, auth_type, eabuf);
++
++	if (flags & BRCMF_EVENT_MSG_LINK)
++		link = true;
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		group = true;
++	if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
++		flush_txq = true;
++
++	switch (event_type) {
++	case BRCMF_E_START:
++	case BRCMF_E_DEAUTH:
++	case BRCMF_E_DISASSOC:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_ASSOC:
++	case BRCMF_E_REASSOC:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
++				  event_name, eabuf, (int)reason);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
++				  event_name, eabuf, (int)status);
++		break;
++
++	case BRCMF_E_DEAUTH_IND:
++	case BRCMF_E_DISASSOC_IND:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
++			  event_name, eabuf, (int)reason);
++		break;
++
++	case BRCMF_E_AUTH:
++	case BRCMF_E_AUTH_IND:
++		if (auth_type == WLAN_AUTH_OPEN)
++			auth_str = "Open System";
++		else if (auth_type == WLAN_AUTH_SHARED_KEY)
++			auth_str = "Shared Key";
++		else {
++			sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
++			auth_str = err_msg;
++		}
++		if (event_type == BRCMF_E_AUTH_IND)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_TIMEOUT)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
++				  event_name, eabuf, auth_str);
++		else if (status == BRCMF_E_STATUS_FAIL) {
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
++				  event_name, eabuf, auth_str, (int)reason);
++		}
++
++		break;
++
++	case BRCMF_E_JOIN:
++	case BRCMF_E_ROAM:
++	case BRCMF_E_SET_SSID:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
++				  event_name, eabuf);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
++		else if (status == BRCMF_E_STATUS_NO_NETWORKS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
++				  event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
++				  event_name, (int)status);
++		break;
++
++	case BRCMF_E_BEACON_RX:
++		if (status == BRCMF_E_STATUS_SUCCESS)
++			brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
++		else if (status == BRCMF_E_STATUS_FAIL)
++			brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
++		else
++			brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
++				  event_name, status);
++		break;
++
++	case BRCMF_E_LINK:
++		brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
++			  event_name, link ? "UP" : "DOWN");
++		break;
++
++	case BRCMF_E_MIC_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
++			  event_name, eabuf, group, flush_txq);
++		break;
++
++	case BRCMF_E_ICV_ERROR:
++	case BRCMF_E_UNICAST_DECODE_ERROR:
++	case BRCMF_E_MULTICAST_DECODE_ERROR:
++		brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_TXFAIL:
++		brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
++		break;
++
++	case BRCMF_E_SCAN_COMPLETE:
++	case BRCMF_E_PMKID_CACHE:
++		brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PFN_NET_FOUND:
++	case BRCMF_E_PFN_NET_LOST:
++	case BRCMF_E_PFN_SCAN_COMPLETE:
++		brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
++		break;
++
++	case BRCMF_E_PSK_SUP:
++	case BRCMF_E_PRUNE:
++		brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
++			  event_name, (int)status, (int)reason);
++		break;
++
++	case BRCMF_E_TRACE:
++		buf = (unsigned char *) event_data;
++		memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
++
++		if (hdr.version != MSGTRACE_VERSION) {
++			brcmf_dbg(ERROR,
++				  "MACEVENT: %s [unsupported version --> brcmf"
++				  " version:%d dongle version:%d]\n",
++				  event_name, MSGTRACE_VERSION, hdr.version);
++			/* Reset datalen to avoid display below */
++			datalen = 0;
++			break;
++		}
++
++		/* There are 2 bytes available at the end of data */
++		*(buf + sizeof(struct msgtrace_hdr)
++			 + be16_to_cpu(hdr.len)) = '\0';
++
++		if (be32_to_cpu(hdr.discarded_bytes)
++		    || be32_to_cpu(hdr.discarded_printf))
++			brcmf_dbg(ERROR,
++				  "WLC_E_TRACE: [Discarded traces in dongle -->"
++				  " discarded_bytes %d discarded_printf %d]\n",
++				  be32_to_cpu(hdr.discarded_bytes),
++				  be32_to_cpu(hdr.discarded_printf));
++
++		nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
++		if (nblost > 0)
++			brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
++				  " %d nblost %d\n", be32_to_cpu(hdr.seqnum),
++				  nblost);
++		seqnum_prev = be32_to_cpu(hdr.seqnum);
++
++		/* Display the trace buffer. Advance from \n to \n to
++		 * avoid display big
++		 * printf (issue with Linux printk )
++		 */
++		p = (char *)&buf[sizeof(struct msgtrace_hdr)];
++		while ((s = strstr(p, "\n")) != NULL) {
++			*s = '\0';
++			pr_debug("%s\n", p);
++			p = s + 1;
++		}
++		pr_debug("%s\n", p);
++
++		/* Reset datalen to avoid display below */
++		datalen = 0;
++		break;
++
++	case BRCMF_E_RSSI:
++		brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
++			  event_name, be32_to_cpu(*((__be32 *)event_data)));
++		break;
++
++	default:
++		brcmf_dbg(EVENT,
++			  "MACEVENT: %s %d, MAC %s, status %d, reason %d, "
++			  "auth %d\n", event_name, event_type, eabuf,
++			  (int)status, (int)reason, (int)auth_type);
++		break;
++	}
++
++	/* show any appended data */
++	if (datalen) {
++		buf = (unsigned char *) event_data;
++		brcmf_dbg(EVENT, " data (%d) : ", datalen);
++		for (i = 0; i < datalen; i++)
++			brcmf_dbg(EVENT, " 0x%02x ", *buf++);
++		brcmf_dbg(EVENT, "\n");
++	}
++}
++#endif				/* DEBUG */
++
++int
++brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
++		   struct brcmf_event_msg *event, void **data_ptr)
++{
++	/* check whether packet is a BRCM event pkt */
++	struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
++	struct brcmf_if_event *ifevent;
++	char *event_data;
++	u32 type, status;
++	u16 flags;
++	int evlen;
++
++	if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
++		brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
++		return -EBADE;
++	}
++
++	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
++	if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
++	    BCMILCP_BCM_SUBTYPE_EVENT) {
++		brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
++		return -EBADE;
++	}
++
++	*data_ptr = &pvt_data[1];
++	event_data = *data_ptr;
++
++	/* memcpy since BRCM event pkt may be unaligned. */
++	memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
++
++	type = get_unaligned_be32(&event->event_type);
++	flags = get_unaligned_be16(&event->flags);
++	status = get_unaligned_be32(&event->status);
++	evlen = get_unaligned_be32(&event->datalen) +
++		sizeof(struct brcmf_event);
++
++	switch (type) {
++	case BRCMF_E_IF:
++		ifevent = (struct brcmf_if_event *) event_data;
++		brcmf_dbg(TRACE, "if event\n");
++
++		if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
++			if (ifevent->action == BRCMF_E_IF_ADD)
++				brcmf_add_if(drvr->dev, ifevent->ifidx,
++					     event->ifname,
++					     pvt_data->eth.h_dest);
++			else
++				brcmf_del_if(drvr, ifevent->ifidx);
++		} else {
++			brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
++				  ifevent->ifidx, event->ifname);
++		}
++
++		/* send up the if event: btamp user needs it */
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		break;
++
++		/* These are what external supplicant/authenticator wants */
++	case BRCMF_E_LINK:
++	case BRCMF_E_ASSOC_IND:
++	case BRCMF_E_REASSOC_IND:
++	case BRCMF_E_DISASSOC_IND:
++	case BRCMF_E_MIC_ERROR:
++	default:
++		/* Fall through: this should get _everything_  */
++
++		*ifidx = brcmf_ifname2idx(drvr, event->ifname);
++		brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
++			  type, flags, status);
++
++		/* put it back to BRCMF_E_NDIS_LINK */
++		if (type == BRCMF_E_NDIS_LINK) {
++			u32 temp1;
++			__be32 temp2;
++
++			temp1 = get_unaligned_be32(&event->event_type);
++			brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
++				  temp1);
++
++			temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
++			memcpy((void *)(&pvt_data->msg.event_type), &temp2,
++			       sizeof(pvt_data->msg.event_type));
++		}
++		break;
++	}
++
++#ifdef DEBUG
++	brcmf_c_show_host_event(event, event_data);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++/* Convert user's input in hex pattern to byte-size mask */
++static int brcmf_c_pattern_atoh(char *src, char *dst)
++{
++	int i;
++	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
++		return -EINVAL;
++	}
++	src = src + 2;		/* Skip past 0x */
++	if (strlen(src) % 2 != 0) {
++		brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
++		return -EINVAL;
++	}
++	for (i = 0; *src != '\0'; i++) {
++		unsigned long res;
++		char num[3];
++		strncpy(num, src, 2);
++		num[2] = '\0';
++		if (kstrtoul(num, 16, &res))
++			return -EINVAL;
++		dst[i] = (u8)res;
++		src += 2;
++	}
++	return i;
++}
++
++void
++brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
++			     int master_mode)
++{
++	unsigned long res;
++	char *argv[8];
++	int i = 0;
++	const char *str;
++	int buf_len;
++	int str_len;
++	char *arg_save = NULL, *arg_org = NULL;
++	int rc;
++	char buf[128];
++	struct brcmf_pkt_filter_enable_le enable_parm;
++	struct brcmf_pkt_filter_enable_le *pkt_filterp;
++	__le32 mmode_le;
++
++	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++	memcpy(arg_save, arg, strlen(arg) + 1);
++
++	argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_enable";
++	str_len = strlen(str);
++	strncpy(buf, str, str_len);
++	buf[str_len] = '\0';
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	enable_parm.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		enable_parm.id = cpu_to_le32((u32)res);
++
++	/* Parse enable/disable value. */
++	enable_parm.enable = cpu_to_le32(enable);
++
++	buf_len += sizeof(enable_parm);
++	memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
++
++	/* Enable/disable the specified filter. */
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++	/* Contorl the master mode */
++	mmode_le = cpu_to_le32(master_mode);
++	brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
++		    sizeof(buf));
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
++				       sizeof(buf));
++	rc = rc >= 0 ? 0 : rc;
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++
++fail:
++	kfree(arg_org);
++}
++
++void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
++{
++	const char *str;
++	struct brcmf_pkt_filter_le pkt_filter;
++	struct brcmf_pkt_filter_le *pkt_filterp;
++	unsigned long res;
++	int buf_len;
++	int str_len;
++	int rc;
++	u32 mask_size;
++	u32 pattern_size;
++	char *argv[8], *buf = NULL;
++	int i = 0;
++	char *arg_save = NULL, *arg_org = NULL;
++
++	arg_save = kstrdup(arg, GFP_ATOMIC);
++	if (!arg_save)
++		goto fail;
++
++	arg_org = arg_save;
++
++	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
++	if (!buf)
++		goto fail;
++
++	argv[i] = strsep(&arg_save, " ");
++	while (argv[i++])
++		argv[i] = strsep(&arg_save, " ");
++
++	i = 0;
++	if (NULL == argv[i]) {
++		brcmf_dbg(ERROR, "No args provided\n");
++		goto fail;
++	}
++
++	str = "pkt_filter_add";
++	strcpy(buf, str);
++	str_len = strlen(str);
++	buf_len = str_len + 1;
++
++	pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
++
++	/* Parse packet filter id. */
++	pkt_filter.id = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.id = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Polarity not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter polarity. */
++	pkt_filter.negate_match = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.negate_match = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Filter type not provided\n");
++		goto fail;
++	}
++
++	/* Parse filter type. */
++	pkt_filter.type = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.type = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Offset not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter offset. */
++	pkt_filter.u.pattern.offset = 0;
++	if (!kstrtoul(argv[i], 0, &res))
++		pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Bitmask not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter mask. */
++	mask_size =
++	    brcmf_c_pattern_atoh
++		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
++
++	if (NULL == argv[++i]) {
++		brcmf_dbg(ERROR, "Pattern not provided\n");
++		goto fail;
++	}
++
++	/* Parse pattern filter pattern. */
++	pattern_size =
++	    brcmf_c_pattern_atoh(argv[i],
++				   (char *)&pkt_filterp->u.pattern.
++				   mask_and_pattern[mask_size]);
++
++	if (mask_size != pattern_size) {
++		brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
++		goto fail;
++	}
++
++	pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
++	buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
++	buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
++
++	/* Keep-alive attributes are set in local
++	 * variable (keep_alive_pkt), and
++	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
++	 ** guarantee that the buffer is properly aligned.
++	 */
++	memcpy((char *)pkt_filterp,
++	       &pkt_filter,
++	       BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
++
++	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
++	rc = rc >= 0 ? 0 : rc;
++
++	if (rc)
++		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
++			  arg, rc);
++	else
++		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
++
++fail:
++	kfree(arg_org);
++
++	kfree(buf);
++}
++
++static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
++			  arp_mode, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
++			  arp_mode);
++}
++
++static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
++{
++	char iovbuf[32];
++	int retcode;
++
++	brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
++			iovbuf, sizeof(iovbuf));
++	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++	retcode = retcode >= 0 ? 0 : retcode;
++	if (retcode)
++		brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
++			  arp_enable, retcode);
++	else
++		brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
++			  arp_enable);
++}
++
++int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
++{
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];	/*  Room for
++				 "event_msgs" + '\0' + bitvec  */
++	char buf[128], *ptr;
++	u32 dongle_align = drvr->bus_if->align;
++	u32 glom = 0;
++	u32 roaming = 1;
++	uint bcn_timeout = 3;
++	int scan_assoc_time = 40;
++	int scan_unassoc_time = 40;
++	int i;
++
++	mutex_lock(&drvr->proto_block);
++
++	/* Set Country code */
++	if (drvr->country_code[0] != 0) {
++		if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
++					      drvr->country_code,
++					      sizeof(drvr->country_code)) < 0)
++			brcmf_dbg(ERROR, "country code setting failed\n");
++	}
++
++	/* query for 'ver' to get version info from firmware */
++	memset(buf, 0, sizeof(buf));
++	ptr = buf;
++	brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
++	strsep(&ptr, "\n");
++	/* Print fw version info */
++	brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
++
++	/* Match Host and Dongle rx alignment */
++	brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* disable glom option per default */
++	brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup timeout if Beacons are lost and roam is off to report
++		 link down */
++	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
++		    sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Enable/Disable build-in roaming to allowed ext supplicant to take
++		 of romaing */
++	brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
++				  sizeof(iovbuf));
++
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
++
++	/* Set and enable ARP offload feature */
++	brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
++	brcmf_c_arp_offload_enable(drvr, true);
++
++	/* Set up pkt filter */
++	for (i = 0; i < drvr->pktfilter_count; i++) {
++		brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
++		brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
++						 0, true);
++	}
++
++	mutex_unlock(&drvr->proto_block);
++
++	return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+new file mode 100644
+index 0000000..a2c4576
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_DBG_H_
++#define _BRCMF_DBG_H_
++
++/* message levels */
++#define BRCMF_ERROR_VAL	0x0001
++#define BRCMF_TRACE_VAL	0x0002
++#define BRCMF_INFO_VAL	0x0004
++#define BRCMF_DATA_VAL	0x0008
++#define BRCMF_CTL_VAL	0x0010
++#define BRCMF_TIMER_VAL	0x0020
++#define BRCMF_HDRS_VAL	0x0040
++#define BRCMF_BYTES_VAL	0x0080
++#define BRCMF_INTR_VAL	0x0100
++#define BRCMF_GLOM_VAL	0x0400
++#define BRCMF_EVENT_VAL	0x0800
++#define BRCMF_BTA_VAL	0x1000
++#define BRCMF_ISCAN_VAL 0x2000
++
++#if defined(DEBUG)
++
++#define brcmf_dbg(level, fmt, ...)					\
++do {									\
++	if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) {			\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			if (net_ratelimit())				\
++				pr_debug("%s: " fmt,			\
++					 __func__, ##__VA_ARGS__);	\
++		}							\
++	} else {							\
++		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
++			pr_debug("%s: " fmt,				\
++				 __func__, ##__VA_ARGS__);		\
++		}							\
++	}								\
++} while (0)
++
++#define BRCMF_DATA_ON()		(brcmf_msg_level & BRCMF_DATA_VAL)
++#define BRCMF_CTL_ON()		(brcmf_msg_level & BRCMF_CTL_VAL)
++#define BRCMF_HDRS_ON()		(brcmf_msg_level & BRCMF_HDRS_VAL)
++#define BRCMF_BYTES_ON()	(brcmf_msg_level & BRCMF_BYTES_VAL)
++#define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
++
++#else	/* (defined DEBUG) || (defined DEBUG) */
++
++#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
++
++#define BRCMF_DATA_ON()		0
++#define BRCMF_CTL_ON()		0
++#define BRCMF_HDRS_ON()		0
++#define BRCMF_BYTES_ON()	0
++#define BRCMF_GLOM_ON()		0
++
++#endif				/* defined(DEBUG) */
++
++#define brcmf_dbg_hex_dump(test, data, len, fmt, ...)			\
++do {									\
++	if (test)							\
++		brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__);	\
++} while (0)
++
++extern int brcmf_msg_level;
++
++#endif				/* _BRCMF_DBG_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+new file mode 100644
+index 0000000..7c42840
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+@@ -0,0 +1,1232 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/version.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/random.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/hardirq.h>
++#include <linux/mutex.h>
++#include <linux/wait.h>
++#include <linux/module.h>
++#include <net/cfg80211.h>
++#include <net/rtnetlink.h>
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#include "dhd.h"
++#include "dhd_bus.h"
++#include "dhd_proto.h"
++#include "dhd_dbg.h"
++#include "wl_cfg80211.h"
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* Interface control information */
++struct brcmf_if {
++	struct brcmf_pub *drvr;	/* back pointer to brcmf_pub */
++	/* OS/stack specifics */
++	struct net_device *ndev;
++	struct net_device_stats stats;
++	int idx;		/* iface idx in dongle */
++	u8 mac_addr[ETH_ALEN];	/* assigned MAC address */
++};
++
++/* Error bits */
++int brcmf_msg_level = BRCMF_ERROR_VAL;
++module_param(brcmf_msg_level, int, 0);
++
++int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name)
++{
++	int i = BRCMF_MAX_IFS;
++	struct brcmf_if *ifp;
++
++	if (name == NULL || *name == '\0')
++		return 0;
++
++	while (--i > 0) {
++		ifp = drvr->iflist[i];
++		if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ))
++			break;
++	}
++
++	brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name);
++
++	return i;		/* default - the primary interface */
++}
++
++char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
++{
++	if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
++		brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx);
++		return "<if_bad>";
++	}
++
++	if (drvr->iflist[ifidx] == NULL) {
++		brcmf_dbg(ERROR, "null i/f %d\n", ifidx);
++		return "<if_null>";
++	}
++
++	if (drvr->iflist[ifidx]->ndev)
++		return drvr->iflist[ifidx]->ndev->name;
++
++	return "<if_none>";
++}
++
++static void _brcmf_set_multicast_list(struct work_struct *work)
++{
++	struct net_device *ndev;
++	struct netdev_hw_addr *ha;
++	u32 dcmd_value, cnt;
++	__le32 cnt_le;
++	__le32 dcmd_le_value;
++
++	struct brcmf_dcmd dcmd;
++	char *buf, *bufp;
++	uint buflen;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    multicast_work);
++
++	ndev = drvr->iflist[0]->ndev;
++	cnt = netdev_mc_count(ndev);
++
++	/* Determine initial value of allmulti flag */
++	dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
++
++	/* Send down the multicast list first. */
++
++	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
++	bufp = buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!bufp)
++		return;
++
++	strcpy(bufp, "mcast_list");
++	bufp += strlen("mcast_list") + 1;
++
++	cnt_le = cpu_to_le32(cnt);
++	memcpy(bufp, &cnt_le, sizeof(cnt));
++	bufp += sizeof(cnt_le);
++
++	netdev_for_each_mc_addr(ha, ndev) {
++		if (!cnt)
++			break;
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
++		memcpy(bufp, ha->addr, ETH_ALEN);
++#else
++		memcpy(bufp, ha->dmi_addr, ETH_ALEN);
++#endif
++		bufp += ETH_ALEN;
++		cnt--;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
++			  brcmf_ifname(drvr, 0), cnt);
++		dcmd_value = cnt ? true : dcmd_value;
++	}
++
++	kfree(buf);
++
++	/* Now send the allmulti setting.  This is based on the setting in the
++	 * net_device flags, but might be modified above to be turned on if we
++	 * were trying to set some addresses and dongle rejected it...
++	 */
++
++	buflen = sizeof("allmulti") + sizeof(dcmd_value);
++	buf = kmalloc(buflen, GFP_ATOMIC);
++	if (!buf)
++		return;
++
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	if (!brcmf_c_mkiovar
++	    ("allmulti", (void *)&dcmd_le_value,
++	    sizeof(dcmd_le_value), buf, buflen)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
++			  brcmf_ifname(drvr, 0),
++			  (int)sizeof(dcmd_value), buflen);
++		kfree(buf);
++		return;
++	}
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = buflen;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++
++	kfree(buf);
++
++	/* Finally, pick up the PROMISC flag as well, like the NIC
++		 driver does */
++
++	dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
++	dcmd_le_value = cpu_to_le32(dcmd_value);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_PROMISC;
++	dcmd.buf = &dcmd_le_value;
++	dcmd.len = sizeof(dcmd_le_value);
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
++			  brcmf_ifname(drvr, 0),
++			  le32_to_cpu(dcmd_le_value));
++	}
++}
++
++static void
++_brcmf_set_mac_address(struct work_struct *work)
++{
++	char buf[32];
++	struct brcmf_dcmd dcmd;
++	int ret;
++
++	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++						    setmacaddr_work);
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
++			   ETH_ALEN, buf, 32)) {
++		brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
++			  brcmf_ifname(drvr, 0));
++		return;
++	}
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = 32;
++	dcmd.set = true;
++
++	ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
++			  brcmf_ifname(drvr, 0));
++	else
++		memcpy(drvr->iflist[0]->ndev->dev_addr,
++		       drvr->macvalue, ETH_ALEN);
++
++	return;
++}
++
++static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct sockaddr *sa = (struct sockaddr *)addr;
++
++	memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN);
++	schedule_work(&drvr->setmacaddr_work);
++	return 0;
++}
++
++static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	schedule_work(&drvr->multicast_work);
++}
++
++int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
++{
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN))
++		return -ENODEV;
++
++	/* Update multicast statistic */
++	if (pktbuf->len >= ETH_ALEN) {
++		u8 *pktdata = (u8 *) (pktbuf->data);
++		struct ethhdr *eh = (struct ethhdr *)pktdata;
++
++		if (is_multicast_ether_addr(eh->h_dest))
++			drvr->tx_multicast++;
++		if (ntohs(eh->h_proto) == ETH_P_PAE)
++			atomic_inc(&drvr->pend_8021x_cnt);
++	}
++
++	/* If the protocol uses a data header, apply it */
++	brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
++
++	/* Use bus module to send data frame */
++	return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf);
++}
++
++static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++	int ret;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Reject if down */
++	if (!drvr->bus_if->drvr_up ||
++	    (drvr->bus_if->state == BRCMF_BUS_DOWN)) {
++		brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
++			  drvr->bus_if->drvr_up,
++			  drvr->bus_if->state);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	if (!drvr->iflist[ifp->idx]) {
++		brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx);
++		netif_stop_queue(ndev);
++		return -ENODEV;
++	}
++
++	/* Make sure there's enough room for any header */
++	if (skb_headroom(skb) < drvr->hdrlen) {
++		struct sk_buff *skb2;
++
++		brcmf_dbg(INFO, "%s: insufficient headroom\n",
++			  brcmf_ifname(drvr, ifp->idx));
++		drvr->bus_if->tx_realloc++;
++		skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
++		dev_kfree_skb(skb);
++		skb = skb2;
++		if (skb == NULL) {
++			brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n",
++				  brcmf_ifname(drvr, ifp->idx));
++			ret = -ENOMEM;
++			goto done;
++		}
++	}
++
++	ret = brcmf_sendpkt(drvr, ifp->idx, skb);
++
++done:
++	if (ret)
++		drvr->bus_if->dstats.tx_dropped++;
++	else
++		drvr->bus_if->dstats.tx_packets++;
++
++	/* Return ok: we always eat the packet */
++	return 0;
++}
++
++void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
++{
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	ndev = drvr->iflist[ifidx]->ndev;
++	if (state == ON)
++		netif_stop_queue(ndev);
++	else
++		netif_wake_queue(ndev);
++}
++
++static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
++			    void *pktdata, struct brcmf_event_msg *event,
++			    void **data)
++{
++	int bcmerror = 0;
++
++	bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data);
++	if (bcmerror != 0)
++		return bcmerror;
++
++	if (drvr->iflist[*ifidx]->ndev)
++		brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
++				     event, *data);
++
++	return bcmerror;
++}
++
++void brcmf_rx_frame(struct device *dev, int ifidx,
++		    struct sk_buff_head *skb_list)
++{
++	unsigned char *eth;
++	uint len;
++	void *data;
++	struct sk_buff *skb, *pnext;
++	struct brcmf_if *ifp;
++	struct brcmf_event_msg event;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	skb_queue_walk_safe(skb_list, skb, pnext) {
++		skb_unlink(skb, skb_list);
++
++		/* Get the protocol, maintain skb around eth_type_trans()
++		 * The main reason for this hack is for the limitation of
++		 * Linux 2.4 where 'eth_type_trans' uses the
++		 * 'net->hard_header_len'
++		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
++		 * coping of the packet coming from the network stack to add
++		 * BDC, Hardware header etc, during network interface
++		 * registration
++		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
++		 * required
++		 * for BDC, Hardware header etc. and not just the ETH_HLEN
++		 */
++		eth = skb->data;
++		len = skb->len;
++
++		ifp = drvr->iflist[ifidx];
++		if (ifp == NULL)
++			ifp = drvr->iflist[0];
++
++		if (!ifp || !ifp->ndev ||
++		    ifp->ndev->reg_state != NETREG_REGISTERED) {
++			brcmu_pkt_buf_free_skb(skb);
++			continue;
++		}
++
++		skb->dev = ifp->ndev;
++		skb->protocol = eth_type_trans(skb, skb->dev);
++
++		if (skb->pkt_type == PACKET_MULTICAST)
++			bus_if->dstats.multicast++;
++
++		skb->data = eth;
++		skb->len = len;
++
++		/* Strip header, count, deliver upward */
++		skb_pull(skb, ETH_HLEN);
++
++		/* Process special event packets and then discard them */
++		if (ntohs(skb->protocol) == ETH_P_LINK_CTL)
++			brcmf_host_event(drvr, &ifidx,
++					  skb_mac_header(skb),
++					  &event, &data);
++
++		if (drvr->iflist[ifidx]) {
++			ifp = drvr->iflist[ifidx];
++			ifp->ndev->last_rx = jiffies;
++		}
++
++		bus_if->dstats.rx_bytes += skb->len;
++		bus_if->dstats.rx_packets++;	/* Local count */
++
++		if (in_interrupt())
++			netif_rx(skb);
++		else
++			/* If the receive is not processed inside an ISR,
++			 * the softirqd must be woken explicitly to service
++			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
++			 * by netif_rx_ni(), but in earlier kernels, we need
++			 * to do it manually.
++			 */
++			netif_rx_ni(skb);
++	}
++}
++
++void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
++{
++	uint ifidx;
++	struct ethhdr *eh;
++	u16 type;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_proto_hdrpull(dev, &ifidx, txp);
++
++	eh = (struct ethhdr *)(txp->data);
++	type = ntohs(eh->h_proto);
++
++	if (type == ETH_P_PAE)
++		atomic_dec(&drvr->pend_8021x_cnt);
++
++}
++
++static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_bus *bus_if = ifp->drvr->bus_if;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Copy dongle stats to net device stats */
++	ifp->stats.rx_packets = bus_if->dstats.rx_packets;
++	ifp->stats.tx_packets = bus_if->dstats.tx_packets;
++	ifp->stats.rx_bytes = bus_if->dstats.rx_bytes;
++	ifp->stats.tx_bytes = bus_if->dstats.tx_bytes;
++	ifp->stats.rx_errors = bus_if->dstats.rx_errors;
++	ifp->stats.tx_errors = bus_if->dstats.tx_errors;
++	ifp->stats.rx_dropped = bus_if->dstats.rx_dropped;
++	ifp->stats.tx_dropped = bus_if->dstats.tx_dropped;
++	ifp->stats.multicast = bus_if->dstats.multicast;
++
++	return &ifp->stats;
++}
++
++/* Retrieve current toe component enables, which are kept
++	 as a bitmap in toe_ol iovar */
++static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	__le32 toe_le;
++	char buf[32];
++	int ret;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_GET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = false;
++
++	strcpy(buf, "toe_ol");
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		/* Check for older dongle image that doesn't support toe_ol */
++		if (ret == -EIO) {
++			brcmf_dbg(ERROR, "%s: toe not supported by device\n",
++				  brcmf_ifname(drvr, ifidx));
++			return -EOPNOTSUPP;
++		}
++
++		brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	memcpy(&toe_le, buf, sizeof(u32));
++	*toe_ol = le32_to_cpu(toe_le);
++	return 0;
++}
++
++/* Set current toe component enables in toe_ol iovar,
++	 and set toe global enable iovar */
++static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
++{
++	struct brcmf_dcmd dcmd;
++	char buf[32];
++	int ret;
++	__le32 toe_le = cpu_to_le32(toe_ol);
++
++	memset(&dcmd, 0, sizeof(dcmd));
++
++	dcmd.cmd = BRCMF_C_SET_VAR;
++	dcmd.buf = buf;
++	dcmd.len = (uint) sizeof(buf);
++	dcmd.set = true;
++
++	/* Set toe_ol as requested */
++	strcpy(buf, "toe_ol");
++	memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	/* Enable toe globally only if any components are enabled. */
++	toe_le = cpu_to_le32(toe_ol != 0);
++
++	strcpy(buf, "toe");
++	memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
++
++	ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
++			  brcmf_ifname(drvr, ifidx), ret);
++		return ret;
++	}
++
++	return 0;
++}
++
++static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
++				    struct ethtool_drvinfo *info)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	sprintf(info->driver, KBUILD_MODNAME);
++	sprintf(info->version, "%lu", drvr->drv_version);
++	sprintf(info->bus_info, "%s", dev_name(drvr->dev));
++}
++
++static const struct ethtool_ops brcmf_ethtool_ops = {
++	.get_drvinfo = brcmf_ethtool_get_drvinfo,
++};
++
++static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
++{
++	struct ethtool_drvinfo info;
++	char drvname[sizeof(info.driver)];
++	u32 cmd;
++	struct ethtool_value edata;
++	u32 toe_cmpnt, csum_dir;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* all ethtool calls start with a cmd word */
++	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
++		return -EFAULT;
++
++	switch (cmd) {
++	case ETHTOOL_GDRVINFO:
++		/* Copy out any request driver name */
++		if (copy_from_user(&info, uaddr, sizeof(info)))
++			return -EFAULT;
++		strncpy(drvname, info.driver, sizeof(info.driver));
++		drvname[sizeof(info.driver) - 1] = '\0';
++
++		/* clear struct for return */
++		memset(&info, 0, sizeof(info));
++		info.cmd = cmd;
++
++		/* if requested, identify ourselves */
++		if (strcmp(drvname, "?dhd") == 0) {
++			sprintf(info.driver, "dhd");
++			strcpy(info.version, BRCMF_VERSION_STR);
++		}
++
++		/* otherwise, require dongle to be up */
++		else if (!drvr->bus_if->drvr_up) {
++			brcmf_dbg(ERROR, "dongle is not up\n");
++			return -ENODEV;
++		}
++
++		/* finally, report dongle driver type */
++		else if (drvr->iswl)
++			sprintf(info.driver, "wl");
++		else
++			sprintf(info.driver, "xx");
++
++		sprintf(info.version, "%lu", drvr->drv_version);
++		if (copy_to_user(uaddr, &info, sizeof(info)))
++			return -EFAULT;
++		brcmf_dbg(CTL, "given %*s, returning %s\n",
++			  (int)sizeof(drvname), drvname, info.driver);
++		break;
++
++		/* Get toe offload components from dongle */
++	case ETHTOOL_GRXCSUM:
++	case ETHTOOL_GTXCSUM:
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		edata.cmd = cmd;
++		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
++
++		if (copy_to_user(uaddr, &edata, sizeof(edata)))
++			return -EFAULT;
++		break;
++
++		/* Set toe offload components in dongle */
++	case ETHTOOL_SRXCSUM:
++	case ETHTOOL_STXCSUM:
++		if (copy_from_user(&edata, uaddr, sizeof(edata)))
++			return -EFAULT;
++
++		/* Read the current settings, update and write back */
++		ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		csum_dir =
++		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
++
++		if (edata.data != 0)
++			toe_cmpnt |= csum_dir;
++		else
++			toe_cmpnt &= ~csum_dir;
++
++		ret = brcmf_toe_set(drvr, 0, toe_cmpnt);
++		if (ret < 0)
++			return ret;
++
++		/* If setting TX checksum mode, tell Linux the new mode */
++		if (cmd == ETHTOOL_STXCSUM) {
++			if (edata.data)
++				drvr->iflist[0]->ndev->features |=
++				    NETIF_F_IP_CSUM;
++			else
++				drvr->iflist[0]->ndev->features &=
++				    ~NETIF_F_IP_CSUM;
++		}
++
++		break;
++
++	default:
++		return -EOPNOTSUPP;
++	}
++
++	return 0;
++}
++
++static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
++				    int cmd)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd);
++
++	if (!drvr->iflist[ifp->idx])
++		return -1;
++
++	if (cmd == SIOCETHTOOL)
++		return brcmf_ethtool(drvr, ifr->ifr_data);
++
++	return -EOPNOTSUPP;
++}
++
++/* called only from within this driver. Sends a command to the dongle. */
++s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len)
++{
++	struct brcmf_dcmd dcmd;
++	s32 err = 0;
++	int buflen = 0;
++	bool is_set_key_cmd;
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	memset(&dcmd, 0, sizeof(dcmd));
++	dcmd.cmd = cmd;
++	dcmd.buf = arg;
++	dcmd.len = len;
++
++	if (dcmd.buf != NULL)
++		buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN);
++
++	/* send to dongle (must be up, and wl) */
++	if ((drvr->bus_if->state != BRCMF_BUS_DATA)) {
++		brcmf_dbg(ERROR, "DONGLE_DOWN\n");
++		err = -EIO;
++		goto done;
++	}
++
++	if (!drvr->iswl) {
++		err = -EIO;
++		goto done;
++	}
++
++	/*
++	 * Intercept BRCMF_C_SET_KEY CMD - serialize M4 send and
++	 * set key CMD to prevent M4 encryption.
++	 */
++	is_set_key_cmd = ((dcmd.cmd == BRCMF_C_SET_KEY) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("wsec_key", dcmd.buf, 9))) ||
++			  ((dcmd.cmd == BRCMF_C_SET_VAR) &&
++			   !(strncmp("bsscfg:wsec_key", dcmd.buf, 15))));
++	if (is_set_key_cmd)
++		brcmf_netdev_wait_pend8021x(ndev);
++
++	err = brcmf_proto_dcmd(drvr, ifp->idx, &dcmd, buflen);
++
++done:
++	if (err > 0)
++		err = 0;
++
++	return err;
++}
++
++static int brcmf_netdev_stop(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++	brcmf_cfg80211_down(drvr->config);
++	if (drvr->bus_if->drvr_up == 0)
++		return 0;
++
++	/* Set state and stop OS transmissions */
++	drvr->bus_if->drvr_up = false;
++	netif_stop_queue(ndev);
++
++	return 0;
++}
++
++static int brcmf_netdev_open(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct brcmf_bus *bus_if = drvr->bus_if;
++	u32 toe_ol;
++	s32 ret = 0;
++	uint up = 0;
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	if (ifp->idx == 0) {	/* do it only for primary eth0 */
++		/* If bus is not ready, can't continue */
++		if (bus_if->state != BRCMF_BUS_DATA) {
++			brcmf_dbg(ERROR, "failed bus is not ready\n");
++			return -EAGAIN;
++		}
++
++		atomic_set(&drvr->pend_8021x_cnt, 0);
++
++		memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
++
++		/* Get current TOE mode from dongle */
++		if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0
++		    && (toe_ol & TOE_TX_CSUM_OL) != 0)
++			drvr->iflist[ifp->idx]->ndev->features |=
++				NETIF_F_IP_CSUM;
++		else
++			drvr->iflist[ifp->idx]->ndev->features &=
++				~NETIF_F_IP_CSUM;
++	}
++
++	/* make sure RF is ready for work */
++	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
++
++	/* Allow transmit calls */
++	netif_start_queue(ndev);
++	drvr->bus_if->drvr_up = true;
++	if (brcmf_cfg80211_up(drvr->config)) {
++		brcmf_dbg(ERROR, "failed to bring up cfg80211\n");
++		return -1;
++	}
++
++	return ret;
++}
++
++static const struct net_device_ops brcmf_netdev_ops_pri = {
++	.ndo_open = brcmf_netdev_open,
++	.ndo_stop = brcmf_netdev_stop,
++	.ndo_get_stats = brcmf_netdev_get_stats,
++	.ndo_do_ioctl = brcmf_netdev_ioctl_entry,
++	.ndo_start_xmit = brcmf_netdev_start_xmit,
++	.ndo_set_mac_address = brcmf_netdev_set_mac_address,
++	.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
++};
++
++static int brcmf_net_attach(struct brcmf_if *ifp)
++{
++	struct brcmf_pub *drvr = ifp->drvr;
++	struct net_device *ndev;
++	u8 temp_addr[ETH_ALEN];
++
++	brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
++
++	ndev = drvr->iflist[ifp->idx]->ndev;
++	ndev->netdev_ops = &brcmf_netdev_ops_pri;
++
++	/*
++	 * determine mac address to use
++	 */
++	if (is_valid_ether_addr(ifp->mac_addr))
++		memcpy(temp_addr, ifp->mac_addr, ETH_ALEN);
++	else
++		memcpy(temp_addr, drvr->mac, ETH_ALEN);
++
++	if (ifp->idx == 1) {
++		brcmf_dbg(TRACE, "ACCESS POINT MAC:\n");
++		/*  ACCESSPOINT INTERFACE CASE */
++		temp_addr[0] |= 0X02;	/* set bit 2 ,
++			 - Locally Administered address  */
++
++	}
++	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
++	ndev->ethtool_ops = &brcmf_ethtool_ops;
++
++	drvr->rxsz = ndev->mtu + ndev->hard_header_len +
++			      drvr->hdrlen;
++
++	memcpy(ndev->dev_addr, temp_addr, ETH_ALEN);
++
++	/* attach to cfg80211 for primary interface */
++	if (!ifp->idx) {
++		drvr->config = brcmf_cfg80211_attach(ndev, drvr->dev, drvr);
++		if (drvr->config == NULL) {
++			brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n");
++			goto fail;
++		}
++	}
++
++	if (register_netdev(ndev) != 0) {
++		brcmf_dbg(ERROR, "couldn't register the net device\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
++
++	return 0;
++
++fail:
++	ndev->netdev_ops = NULL;
++	return -EBADE;
++}
++
++int
++brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr)
++{
++	struct brcmf_if *ifp;
++	struct net_device *ndev;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	/*
++	 * Delete the existing interface before overwriting it
++	 * in case we missed the BRCMF_E_IF_DEL event.
++	 */
++	if (ifp) {
++		brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n",
++			  ifp->ndev->name);
++		netif_stop_queue(ifp->ndev);
++		unregister_netdev(ifp->ndev);
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++	}
++
++	/* Allocate netdev, including space for private structure */
++	ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup);
++	if (!ndev) {
++		brcmf_dbg(ERROR, "OOM - alloc_netdev\n");
++		return -ENOMEM;
++	}
++
++	ifp = netdev_priv(ndev);
++	ifp->ndev = ndev;
++	ifp->drvr = drvr;
++	drvr->iflist[ifidx] = ifp;
++	ifp->idx = ifidx;
++	if (mac_addr != NULL)
++		memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
++
++	if (brcmf_net_attach(ifp)) {
++		brcmf_dbg(ERROR, "brcmf_net_attach failed");
++		free_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		return -EOPNOTSUPP;
++	}
++
++	brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n",
++		  current->pid, ifp->ndev->name);
++
++	return 0;
++}
++
++void brcmf_del_if(struct brcmf_pub *drvr, int ifidx)
++{
++	struct brcmf_if *ifp;
++
++	brcmf_dbg(TRACE, "idx %d\n", ifidx);
++
++	ifp = drvr->iflist[ifidx];
++	if (!ifp) {
++		brcmf_dbg(ERROR, "Null interface\n");
++		return;
++	}
++	if (ifp->ndev) {
++		if (ifidx == 0) {
++			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
++				rtnl_lock();
++				brcmf_netdev_stop(ifp->ndev);
++				rtnl_unlock();
++			}
++		} else {
++			netif_stop_queue(ifp->ndev);
++		}
++
++		unregister_netdev(ifp->ndev);
++		drvr->iflist[ifidx] = NULL;
++		if (ifidx == 0)
++			brcmf_cfg80211_detach(drvr->config);
++		free_netdev(ifp->ndev);
++	}
++}
++
++int brcmf_attach(uint bus_hdrlen, struct device *dev)
++{
++	struct brcmf_pub *drvr = NULL;
++	int ret = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Allocate primary brcmf_info */
++	drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC);
++	if (!drvr)
++		return -ENOMEM;
++
++	mutex_init(&drvr->proto_block);
++
++	/* Link to bus module */
++	drvr->hdrlen = bus_hdrlen;
++	drvr->bus_if = dev_get_drvdata(dev);
++	drvr->bus_if->drvr = drvr;
++	drvr->dev = dev;
++
++	/* Attach and link in the protocol */
++	ret = brcmf_proto_attach(drvr);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_prot_attach failed\n");
++		goto fail;
++	}
++
++	INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address);
++	INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list);
++
++	return ret;
++
++fail:
++	brcmf_detach(dev);
++
++	return ret;
++}
++
++int brcmf_bus_start(struct device *dev)
++{
++	int ret = -1;
++	/* Room for "event_msgs" + '\0' + bitvec */
++	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "\n");
++
++	/* Bring up the bus */
++	ret = bus_if->brcmf_bus_init(dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret);
++		return ret;
++	}
++
++	brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
++		      iovbuf, sizeof(iovbuf));
++	brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
++				    sizeof(iovbuf));
++	memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(drvr->eventmask, BRCMF_E_SET_SSID);
++	setbit(drvr->eventmask, BRCMF_E_PRUNE);
++	setbit(drvr->eventmask, BRCMF_E_AUTH);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC);
++	setbit(drvr->eventmask, BRCMF_E_REASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_DISASSOC);
++	setbit(drvr->eventmask, BRCMF_E_JOIN);
++	setbit(drvr->eventmask, BRCMF_E_ASSOC_IND);
++	setbit(drvr->eventmask, BRCMF_E_PSK_SUP);
++	setbit(drvr->eventmask, BRCMF_E_LINK);
++	setbit(drvr->eventmask, BRCMF_E_NDIS_LINK);
++	setbit(drvr->eventmask, BRCMF_E_MIC_ERROR);
++	setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(drvr->eventmask, BRCMF_E_TXFAIL);
++	setbit(drvr->eventmask, BRCMF_E_JOIN_START);
++	setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE);
++
++/* enable dongle roaming event */
++
++	drvr->pktfilter_count = 1;
++	/* Setup filter to allow only unicast */
++	drvr->pktfilter[0] = "100 0 0 0 0x01 0x00";
++
++	/* Bus is ready, do any protocol initialization */
++	ret = brcmf_proto_init(drvr);
++	if (ret < 0)
++		return ret;
++
++	/* add primary networking interface */
++	ret = brcmf_add_if(dev, 0, "wlan%d", drvr->mac);
++	if (ret < 0)
++		return ret;
++
++	/* signal bus ready */
++	bus_if->state = BRCMF_BUS_DATA;
++	return 0;
++}
++
++static void brcmf_bus_detach(struct brcmf_pub *drvr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (drvr) {
++		/* Stop the protocol module */
++		brcmf_proto_stop(drvr);
++
++		/* Stop the bus module */
++		drvr->bus_if->brcmf_bus_stop(drvr->dev);
++	}
++}
++
++void brcmf_detach(struct device *dev)
++{
++	int i;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pub *drvr = bus_if->drvr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++
++	/* make sure primary interface removed last */
++	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
++		if (drvr->iflist[i])
++			brcmf_del_if(drvr, i);
++
++	brcmf_bus_detach(drvr);
++
++	if (drvr->prot) {
++		cancel_work_sync(&drvr->setmacaddr_work);
++		cancel_work_sync(&drvr->multicast_work);
++		brcmf_proto_detach(drvr);
++	}
++
++	bus_if->drvr = NULL;
++	kfree(drvr);
++}
++
++static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
++{
++	return atomic_read(&drvr->pend_8021x_cnt);
++}
++
++#define MAX_WAIT_FOR_8021X_TX	10
++
++int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
++{
++	struct brcmf_if *ifp = netdev_priv(ndev);
++	struct brcmf_pub *drvr = ifp->drvr;
++	int timeout = 10 * HZ / 1000;
++	int ntimes = MAX_WAIT_FOR_8021X_TX;
++	int pend = brcmf_get_pend_8021x_cnt(drvr);
++
++	while (ntimes && pend) {
++		if (pend) {
++			set_current_state(TASK_INTERRUPTIBLE);
++			schedule_timeout(timeout);
++			set_current_state(TASK_RUNNING);
++			ntimes--;
++		}
++		pend = brcmf_get_pend_8021x_cnt(drvr);
++	}
++	return pend;
++}
++
++#ifdef DEBUG
++int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
++{
++	int ret = 0;
++	struct file *fp;
++	mm_segment_t old_fs;
++	loff_t pos = 0;
++
++	/* change to KERNEL_DS address limit */
++	old_fs = get_fs();
++	set_fs(KERNEL_DS);
++
++	/* open file to write */
++	fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
++	if (!fp) {
++		brcmf_dbg(ERROR, "open file error\n");
++		ret = -1;
++		goto exit;
++	}
++
++	/* Write buf to file */
++	fp->f_op->write(fp, (char __user *)buf, size, &pos);
++
++exit:
++	/* free buf before return */
++	kfree(buf);
++	/* close file before return */
++	if (fp)
++		filp_close(fp, current->files);
++	/* restore previous address limit */
++	set_fs(old_fs);
++
++	return ret;
++}
++#endif				/* DEBUG */
++
++static void brcmf_driver_init(struct work_struct *work)
++{
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_init();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_init();
++#endif
++}
++static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init);
++
++static int __init brcmfmac_module_init(void)
++{
++	if (!schedule_work(&brcmf_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++static void __exit brcmfmac_module_exit(void)
++{
++	cancel_work_sync(&brcmf_driver_work);
++
++#ifdef CONFIG_BRCMFMAC_SDIO
++	brcmf_sdio_exit();
++#endif
++#ifdef CONFIG_BRCMFMAC_USB
++	brcmf_usb_exit();
++#endif
++}
++
++module_init(brcmfmac_module_init);
++module_exit(brcmfmac_module_exit);
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+new file mode 100644
+index 0000000..6bc4425
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMF_PROTO_H_
++#define _BRCMF_PROTO_H_
++
++/*
++ * Exported from the brcmf protocol module (brcmf_cdc)
++ */
++
++/* Linkage, sets prot link and updates hdrlen in pub */
++extern int brcmf_proto_attach(struct brcmf_pub *drvr);
++
++/* Unlink, frees allocated protocol memory (including brcmf_proto) */
++extern void brcmf_proto_detach(struct brcmf_pub *drvr);
++
++/* Initialize protocol: sync w/dongle state.
++ * Sets dongle media info (iswl, drv_version, mac address).
++ */
++extern int brcmf_proto_init(struct brcmf_pub *drvr);
++
++/* Stop protocol: sync w/dongle state. */
++extern void brcmf_proto_stop(struct brcmf_pub *drvr);
++
++/* Add any protocol-specific data header.
++ * Caller must reserve prot_hdrlen prepend space.
++ */
++extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
++				struct sk_buff *txp);
++
++/* Use protocol to issue command to dongle */
++extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
++				struct brcmf_dcmd *dcmd, int len);
++
++extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
++
++extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
++				     uint cmd, void *buf, uint len);
++
++#endif				/* _BRCMF_PROTO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+new file mode 100644
+index 0000000..0d23b8d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+@@ -0,0 +1,4014 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/kthread.h>
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/netdevice.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/mmc/sdio.h>
++#include <linux/mmc/sdio_func.h>
++#include <linux/mmc/card.h>
++#include <linux/semaphore.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <asm/unaligned.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++#define DCMD_RESP_TIMEOUT  2000	/* In milli second */
++
++#ifdef DEBUG
++
++#define BRCMF_TRAP_INFO_SIZE	80
++
++#define CBUF_LEN	(128)
++
++struct rte_log_le {
++	__le32 buf;		/* Can't be pointer on (64-bit) hosts */
++	__le32 buf_size;
++	__le32 idx;
++	char *_buf_compat;	/* Redundant pointer for backward compat. */
++};
++
++struct rte_console {
++	/* Virtual UART
++	 * When there is no UART (e.g. Quickturn),
++	 * the host should write a complete
++	 * input line directly into cbuf and then write
++	 * the length into vcons_in.
++	 * This may also be used when there is a real UART
++	 * (at risk of conflicting with
++	 * the real UART).  vcons_out is currently unused.
++	 */
++	uint vcons_in;
++	uint vcons_out;
++
++	/* Output (logging) buffer
++	 * Console output is written to a ring buffer log_buf at index log_idx.
++	 * The host may read the output when it sees log_idx advance.
++	 * Output will be lost if the output wraps around faster than the host
++	 * polls.
++	 */
++	struct rte_log_le log_le;
++
++	/* Console input line buffer
++	 * Characters are read one at a time into cbuf
++	 * until <CR> is received, then
++	 * the buffer is processed as a command line.
++	 * Also used for virtual UART.
++	 */
++	uint cbuf_idx;
++	char cbuf[CBUF_LEN];
++};
++
++#endif				/* DEBUG */
++#include <chipcommon.h>
++
++#include "dhd_bus.h"
++#include "dhd_dbg.h"
++
++#define TXQLEN		2048	/* bulk tx queue length */
++#define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
++#define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
++#define PRIOMASK	7
++
++#define TXRETRIES	2	/* # of retries for tx frames */
++
++#define BRCMF_RXBOUND	50	/* Default for max rx frames in
++				 one scheduling */
++
++#define BRCMF_TXBOUND	20	/* Default for max tx frames in
++				 one scheduling */
++
++#define BRCMF_TXMINMAX	1	/* Max tx frames if rx still pending */
++
++#define MEMBLOCK	2048	/* Block size used for downloading
++				 of dongle image */
++#define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
++				 biggest possible glom */
++
++#define BRCMF_FIRSTREAD	(1 << 6)
++
++
++/* SBSDIO_DEVICE_CTL */
++
++/* 1: device will assert busy signal when receiving CMD53 */
++#define SBSDIO_DEVCTL_SETBUSY		0x01
++/* 1: assertion of sdio interrupt is synchronous to the sdio clock */
++#define SBSDIO_DEVCTL_SPI_INTR_SYNC	0x02
++/* 1: mask all interrupts to host except the chipActive (rev 8) */
++#define SBSDIO_DEVCTL_CA_INT_ONLY	0x04
++/* 1: isolate internal sdio signals, put external pads in tri-state; requires
++ * sdio bus power cycle to clear (rev 9) */
++#define SBSDIO_DEVCTL_PADS_ISO		0x08
++/* Force SD->SB reset mapping (rev 11) */
++#define SBSDIO_DEVCTL_SB_RST_CTL	0x30
++/*   Determined by CoreControl bit */
++#define SBSDIO_DEVCTL_RST_CORECTL	0x00
++/*   Force backplane reset */
++#define SBSDIO_DEVCTL_RST_BPRESET	0x10
++/*   Force no backplane reset */
++#define SBSDIO_DEVCTL_RST_NOBPRESET	0x20
++
++/* direct(mapped) cis space */
++
++/* MAPPED common CIS address */
++#define SBSDIO_CIS_BASE_COMMON		0x1000
++/* maximum bytes in one CIS */
++#define SBSDIO_CIS_SIZE_LIMIT		0x200
++/* cis offset addr is < 17 bits */
++#define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF
++
++/* manfid tuple length, include tuple, link bytes */
++#define SBSDIO_CIS_MANFID_TUPLE_LEN	6
++
++/* intstatus */
++#define I_SMB_SW0	(1 << 0)	/* To SB Mail S/W interrupt 0 */
++#define I_SMB_SW1	(1 << 1)	/* To SB Mail S/W interrupt 1 */
++#define I_SMB_SW2	(1 << 2)	/* To SB Mail S/W interrupt 2 */
++#define I_SMB_SW3	(1 << 3)	/* To SB Mail S/W interrupt 3 */
++#define I_SMB_SW_MASK	0x0000000f	/* To SB Mail S/W interrupts mask */
++#define I_SMB_SW_SHIFT	0	/* To SB Mail S/W interrupts shift */
++#define I_HMB_SW0	(1 << 4)	/* To Host Mail S/W interrupt 0 */
++#define I_HMB_SW1	(1 << 5)	/* To Host Mail S/W interrupt 1 */
++#define I_HMB_SW2	(1 << 6)	/* To Host Mail S/W interrupt 2 */
++#define I_HMB_SW3	(1 << 7)	/* To Host Mail S/W interrupt 3 */
++#define I_HMB_SW_MASK	0x000000f0	/* To Host Mail S/W interrupts mask */
++#define I_HMB_SW_SHIFT	4	/* To Host Mail S/W interrupts shift */
++#define I_WR_OOSYNC	(1 << 8)	/* Write Frame Out Of Sync */
++#define I_RD_OOSYNC	(1 << 9)	/* Read Frame Out Of Sync */
++#define	I_PC		(1 << 10)	/* descriptor error */
++#define	I_PD		(1 << 11)	/* data error */
++#define	I_DE		(1 << 12)	/* Descriptor protocol Error */
++#define	I_RU		(1 << 13)	/* Receive descriptor Underflow */
++#define	I_RO		(1 << 14)	/* Receive fifo Overflow */
++#define	I_XU		(1 << 15)	/* Transmit fifo Underflow */
++#define	I_RI		(1 << 16)	/* Receive Interrupt */
++#define I_BUSPWR	(1 << 17)	/* SDIO Bus Power Change (rev 9) */
++#define I_XMTDATA_AVAIL (1 << 23)	/* bits in fifo */
++#define	I_XI		(1 << 24)	/* Transmit Interrupt */
++#define I_RF_TERM	(1 << 25)	/* Read Frame Terminate */
++#define I_WF_TERM	(1 << 26)	/* Write Frame Terminate */
++#define I_PCMCIA_XU	(1 << 27)	/* PCMCIA Transmit FIFO Underflow */
++#define I_SBINT		(1 << 28)	/* sbintstatus Interrupt */
++#define I_CHIPACTIVE	(1 << 29)	/* chip from doze to active state */
++#define I_SRESET	(1 << 30)	/* CCCR RES interrupt */
++#define I_IOE2		(1U << 31)	/* CCCR IOE2 Bit Changed */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
++#define I_DMA		(I_RI | I_XI | I_ERRORS)
++
++/* corecontrol */
++#define CC_CISRDY		(1 << 0)	/* CIS Ready */
++#define CC_BPRESEN		(1 << 1)	/* CCCR RES signal */
++#define CC_F2RDY		(1 << 2)	/* set CCCR IOR2 bit */
++#define CC_CLRPADSISO		(1 << 3)	/* clear SDIO pads isolation */
++#define CC_XMTDATAAVAIL_MODE	(1 << 4)
++#define CC_XMTDATAAVAIL_CTRL	(1 << 5)
++
++/* SDA_FRAMECTRL */
++#define SFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
++#define SFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
++#define SFC_CRC4WOOS	(1 << 2)	/* CRC error for write out of sync */
++#define SFC_ABORTALL	(1 << 3)	/* Abort all in-progress frames */
++
++/* HW frame tag */
++#define SDPCM_FRAMETAG_LEN	4	/* 2 bytes len, 2 bytes check val */
++
++/* Total length of frame header for dongle protocol */
++#define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
++#define SDPCM_RESERVE	(SDPCM_HDRLEN + BRCMF_SDALIGN)
++
++/*
++ * Software allocation of To SB Mailbox resources
++ */
++
++/* tosbmailbox bits corresponding to intstatus bits */
++#define SMB_NAK		(1 << 0)	/* Frame NAK */
++#define SMB_INT_ACK	(1 << 1)	/* Host Interrupt ACK */
++#define SMB_USE_OOB	(1 << 2)	/* Use OOB Wakeup */
++#define SMB_DEV_INT	(1 << 3)	/* Miscellaneous Interrupt */
++
++/* tosbmailboxdata */
++#define SMB_DATA_VERSION_SHIFT	16	/* host protocol version */
++
++/*
++ * Software allocation of To Host Mailbox resources
++ */
++
++/* intstatus bits */
++#define I_HMB_FC_STATE	I_HMB_SW0	/* Flow Control State */
++#define I_HMB_FC_CHANGE	I_HMB_SW1	/* Flow Control State Changed */
++#define I_HMB_FRAME_IND	I_HMB_SW2	/* Frame Indication */
++#define I_HMB_HOST_INT	I_HMB_SW3	/* Miscellaneous Interrupt */
++
++/* tohostmailboxdata */
++#define HMB_DATA_NAKHANDLED	1	/* retransmit NAK'd frame */
++#define HMB_DATA_DEVREADY	2	/* talk to host after enable */
++#define HMB_DATA_FC		4	/* per prio flowcontrol update flag */
++#define HMB_DATA_FWREADY	8	/* fw ready for protocol activity */
++
++#define HMB_DATA_FCDATA_MASK	0xff000000
++#define HMB_DATA_FCDATA_SHIFT	24
++
++#define HMB_DATA_VERSION_MASK	0x00ff0000
++#define HMB_DATA_VERSION_SHIFT	16
++
++/*
++ * Software-defined protocol header
++ */
++
++/* Current protocol version */
++#define SDPCM_PROT_VERSION	4
++
++/* SW frame header */
++#define SDPCM_PACKET_SEQUENCE(p)	(((u8 *)p)[0] & 0xff)
++
++#define SDPCM_CHANNEL_MASK		0x00000f00
++#define SDPCM_CHANNEL_SHIFT		8
++#define SDPCM_PACKET_CHANNEL(p)		(((u8 *)p)[1] & 0x0f)
++
++#define SDPCM_NEXTLEN_OFFSET		2
++
++/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
++#define SDPCM_DOFFSET_OFFSET		3	/* Data Offset */
++#define SDPCM_DOFFSET_VALUE(p)		(((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
++#define SDPCM_DOFFSET_MASK		0xff000000
++#define SDPCM_DOFFSET_SHIFT		24
++#define SDPCM_FCMASK_OFFSET		4	/* Flow control */
++#define SDPCM_FCMASK_VALUE(p)		(((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
++#define SDPCM_WINDOW_OFFSET		5	/* Credit based fc */
++#define SDPCM_WINDOW_VALUE(p)		(((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
++
++#define SDPCM_SWHEADER_LEN	8	/* SW header is 64 bits */
++
++/* logical channel numbers */
++#define SDPCM_CONTROL_CHANNEL	0	/* Control channel Id */
++#define SDPCM_EVENT_CHANNEL	1	/* Asyc Event Indication Channel Id */
++#define SDPCM_DATA_CHANNEL	2	/* Data Xmit/Recv Channel Id */
++#define SDPCM_GLOM_CHANNEL	3	/* For coalesced packets */
++#define SDPCM_TEST_CHANNEL	15	/* Reserved for test/debug packets */
++
++#define SDPCM_SEQUENCE_WRAP	256	/* wrap-around val for 8bit frame seq */
++
++#define SDPCM_GLOMDESC(p)	(((u8 *)p)[1] & 0x80)
++
++/*
++ * Shared structure between dongle and the host.
++ * The structure contains pointers to trap or assert information.
++ */
++#define SDPCM_SHARED_VERSION       0x0002
++#define SDPCM_SHARED_VERSION_MASK  0x00FF
++#define SDPCM_SHARED_ASSERT_BUILT  0x0100
++#define SDPCM_SHARED_ASSERT        0x0200
++#define SDPCM_SHARED_TRAP          0x0400
++
++/* Space for header read, limit for data packets */
++#define MAX_HDR_READ	(1 << 6)
++#define MAX_RX_DATASZ	2048
++
++/* Maximum milliseconds to wait for F2 to come up */
++#define BRCMF_WAIT_F2RDY	3000
++
++/* Bump up limit on waiting for HT to account for first startup;
++ * if the image is doing a CRC calculation before programming the PMU
++ * for HT availability, it could take a couple hundred ms more, so
++ * max out at a 1 second (1000000us).
++ */
++#undef PMU_MAX_TRANSITION_DLY
++#define PMU_MAX_TRANSITION_DLY 1000000
++
++/* Value for ChipClockCSR during initial setup */
++#define BRCMF_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
++					SBSDIO_ALP_AVAIL_REQ)
++
++/* Flags for SDH calls */
++#define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
++
++#define BRCMF_SDIO_FW_NAME	"brcm/brcmfmac-sdio.bin"
++#define BRCMF_SDIO_NV_NAME	"brcm/brcmfmac-sdio.txt"
++MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
++MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
++
++#define BRCMF_IDLE_IMMEDIATE	(-1)	/* Enter idle immediately */
++#define BRCMF_IDLE_ACTIVE	0	/* Do not request any SD clock change
++					 * when idle
++					 */
++#define BRCMF_IDLE_INTERVAL	1
++
++/*
++ * Conversion of 802.1D priority to precedence level
++ */
++static uint prio2prec(u32 prio)
++{
++	return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
++	       (prio^2) : prio;
++}
++
++/* core registers */
++struct sdpcmd_regs {
++	u32 corecontrol;		/* 0x00, rev8 */
++	u32 corestatus;			/* rev8 */
++	u32 PAD[1];
++	u32 biststatus;			/* rev8 */
++
++	/* PCMCIA access */
++	u16 pcmciamesportaladdr;	/* 0x010, rev8 */
++	u16 PAD[1];
++	u16 pcmciamesportalmask;	/* rev8 */
++	u16 PAD[1];
++	u16 pcmciawrframebc;		/* rev8 */
++	u16 PAD[1];
++	u16 pcmciaunderflowtimer;	/* rev8 */
++	u16 PAD[1];
++
++	/* interrupt */
++	u32 intstatus;			/* 0x020, rev8 */
++	u32 hostintmask;		/* rev8 */
++	u32 intmask;			/* rev8 */
++	u32 sbintstatus;		/* rev8 */
++	u32 sbintmask;			/* rev8 */
++	u32 funcintmask;		/* rev4 */
++	u32 PAD[2];
++	u32 tosbmailbox;		/* 0x040, rev8 */
++	u32 tohostmailbox;		/* rev8 */
++	u32 tosbmailboxdata;		/* rev8 */
++	u32 tohostmailboxdata;		/* rev8 */
++
++	/* synchronized access to registers in SDIO clock domain */
++	u32 sdioaccess;			/* 0x050, rev8 */
++	u32 PAD[3];
++
++	/* PCMCIA frame control */
++	u8 pcmciaframectrl;		/* 0x060, rev8 */
++	u8 PAD[3];
++	u8 pcmciawatermark;		/* rev8 */
++	u8 PAD[155];
++
++	/* interrupt batching control */
++	u32 intrcvlazy;			/* 0x100, rev8 */
++	u32 PAD[3];
++
++	/* counters */
++	u32 cmd52rd;			/* 0x110, rev8 */
++	u32 cmd52wr;			/* rev8 */
++	u32 cmd53rd;			/* rev8 */
++	u32 cmd53wr;			/* rev8 */
++	u32 abort;			/* rev8 */
++	u32 datacrcerror;		/* rev8 */
++	u32 rdoutofsync;		/* rev8 */
++	u32 wroutofsync;		/* rev8 */
++	u32 writebusy;			/* rev8 */
++	u32 readwait;			/* rev8 */
++	u32 readterm;			/* rev8 */
++	u32 writeterm;			/* rev8 */
++	u32 PAD[40];
++	u32 clockctlstatus;		/* rev8 */
++	u32 PAD[7];
++
++	u32 PAD[128];			/* DMA engines */
++
++	/* SDIO/PCMCIA CIS region */
++	char cis[512];			/* 0x400-0x5ff, rev6 */
++
++	/* PCMCIA function control registers */
++	char pcmciafcr[256];		/* 0x600-6ff, rev6 */
++	u16 PAD[55];
++
++	/* PCMCIA backplane access */
++	u16 backplanecsr;		/* 0x76E, rev6 */
++	u16 backplaneaddr0;		/* rev6 */
++	u16 backplaneaddr1;		/* rev6 */
++	u16 backplaneaddr2;		/* rev6 */
++	u16 backplaneaddr3;		/* rev6 */
++	u16 backplanedata0;		/* rev6 */
++	u16 backplanedata1;		/* rev6 */
++	u16 backplanedata2;		/* rev6 */
++	u16 backplanedata3;		/* rev6 */
++	u16 PAD[31];
++
++	/* sprom "size" & "blank" info */
++	u16 spromstatus;		/* 0x7BE, rev2 */
++	u32 PAD[464];
++
++	u16 PAD[0x80];
++};
++
++#ifdef DEBUG
++/* Device console log buffer state */
++struct brcmf_console {
++	uint count;		/* Poll interval msec counter */
++	uint log_addr;		/* Log struct address (fixed) */
++	struct rte_log_le log_le;	/* Log struct (host copy) */
++	uint bufsize;		/* Size of log buffer */
++	u8 *buf;		/* Log buffer (host copy) */
++	uint last;		/* Last buffer read index */
++};
++#endif				/* DEBUG */
++
++struct sdpcm_shared {
++	u32 flags;
++	u32 trap_addr;
++	u32 assert_exp_addr;
++	u32 assert_file_addr;
++	u32 assert_line;
++	u32 console_addr;	/* Address of struct rte_console */
++	u32 msgtrace_addr;
++	u8 tag[32];
++};
++
++struct sdpcm_shared_le {
++	__le32 flags;
++	__le32 trap_addr;
++	__le32 assert_exp_addr;
++	__le32 assert_file_addr;
++	__le32 assert_line;
++	__le32 console_addr;	/* Address of struct rte_console */
++	__le32 msgtrace_addr;
++	u8 tag[32];
++};
++
++
++/* misc chip info needed by some of the routines */
++/* Private data for SDIO bus interaction */
++struct brcmf_sdio {
++	struct brcmf_sdio_dev *sdiodev;	/* sdio device handler */
++	struct chip_info *ci;	/* Chip info struct */
++	char *vars;		/* Variables (from CIS and/or other) */
++	uint varsz;		/* Size of variables buffer */
++
++	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
++
++	u32 hostintmask;	/* Copy of Host Interrupt Mask */
++	u32 intstatus;	/* Intstatus bits (events) pending */
++	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
++	bool fcstate;		/* State of dongle flow-control */
++
++	uint blocksize;		/* Block size of SDIO transfers */
++	uint roundup;		/* Max roundup limit */
++
++	struct pktq txq;	/* Queue length used for flow-control */
++	u8 flowcontrol;	/* per prio flow control bitmask */
++	u8 tx_seq;		/* Transmit sequence number (next) */
++	u8 tx_max;		/* Maximum transmit sequence allowed */
++
++	u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
++	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
++	u16 nextlen;		/* Next Read Len from last header */
++	u8 rx_seq;		/* Receive sequence number (expected) */
++	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
++
++	uint rxbound;		/* Rx frames to read before resched */
++	uint txbound;		/* Tx frames to send before resched */
++	uint txminmax;
++
++	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
++	struct sk_buff_head glom; /* Packet list for glommed superframe */
++	uint glomerr;		/* Glom packet read errors */
++
++	u8 *rxbuf;		/* Buffer for receiving control packets */
++	uint rxblen;		/* Allocated length of rxbuf */
++	u8 *rxctl;		/* Aligned pointer into rxbuf */
++	u8 *databuf;		/* Buffer for receiving big glom packet */
++	u8 *dataptr;		/* Aligned pointer into databuf */
++	uint rxlen;		/* Length of valid data in buffer */
++
++	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
++
++	bool intr;		/* Use interrupts */
++	bool poll;		/* Use polling */
++	bool ipend;		/* Device interrupt is pending */
++	uint intrcount;		/* Count of device interrupt callbacks */
++	uint lastintrs;		/* Count as of last watchdog timer */
++	uint spurious;		/* Count of spurious interrupts */
++	uint pollrate;		/* Ticks between device polls */
++	uint polltick;		/* Tick counter */
++	uint pollcnt;		/* Count of active polls */
++
++#ifdef DEBUG
++	uint console_interval;
++	struct brcmf_console console;	/* Console output polling support */
++	uint console_addr;	/* Console address from shared struct */
++#endif				/* DEBUG */
++
++	uint regfails;		/* Count of R_REG failures */
++
++	uint clkstate;		/* State of sd and backplane clock(s) */
++	bool activity;		/* Activity flag for clock down */
++	s32 idletime;		/* Control for activity timeout */
++	s32 idlecount;	/* Activity timeout counter */
++	s32 idleclock;	/* How to set bus driver when idle */
++	s32 sd_rxchain;
++	bool use_rxchain;	/* If brcmf should use PKT chains */
++	bool sleeping;		/* Is SDIO bus sleeping? */
++	bool rxflow_mode;	/* Rx flow control mode */
++	bool rxflow;		/* Is rx flow control on */
++	bool alp_only;		/* Don't use HT clock (ALP only) */
++/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
++	bool usebufpool;
++
++	/* Some additional counters */
++	uint tx_sderrs;		/* Count of tx attempts with sd errors */
++	uint fcqueued;		/* Tx packets that got queued */
++	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
++	uint rx_toolong;	/* Receive frames too long to receive */
++	uint rxc_errors;	/* SDIO errors when reading control frames */
++	uint rx_hdrfail;	/* SDIO errors on header reads */
++	uint rx_badhdr;		/* Bad received headers (roosync?) */
++	uint rx_badseq;		/* Mismatched rx sequence number */
++	uint fc_rcvd;		/* Number of flow-control events received */
++	uint fc_xoff;		/* Number which turned on flow-control */
++	uint fc_xon;		/* Number which turned off flow-control */
++	uint rxglomfail;	/* Failed deglom attempts */
++	uint rxglomframes;	/* Number of glom frames (superframes) */
++	uint rxglompkts;	/* Number of packets from glom frames */
++	uint f2rxhdrs;		/* Number of header reads */
++	uint f2rxdata;		/* Number of frame data reads */
++	uint f2txdata;		/* Number of f2 frame writes */
++	uint f1regdata;		/* Number of f1 register accesses */
++	uint tickcnt;		/* Number of watchdog been schedule */
++	unsigned long tx_ctlerrs;	/* Err of sending ctrl frames */
++	unsigned long tx_ctlpkts;	/* Ctrl frames sent to dongle */
++	unsigned long rx_ctlerrs;	/* Err of processing rx ctrl frames */
++	unsigned long rx_ctlpkts;	/* Ctrl frames processed from dongle */
++	unsigned long rx_readahead_cnt;	/* Number of packets where header
++					 * read-ahead was used. */
++
++	u8 *ctrl_frame_buf;
++	u32 ctrl_frame_len;
++	bool ctrl_frame_stat;
++
++	spinlock_t txqlock;
++	wait_queue_head_t ctrl_wait;
++	wait_queue_head_t dcmd_resp_wait;
++
++	struct timer_list timer;
++	struct completion watchdog_wait;
++	struct task_struct *watchdog_tsk;
++	bool wd_timer_valid;
++	uint save_ms;
++
++	struct task_struct *dpc_tsk;
++	struct completion dpc_wait;
++	struct list_head dpc_tsklst;
++	spinlock_t dpc_tl_lock;
++
++	struct semaphore sdsem;
++
++	const struct firmware *firmware;
++	u32 fw_ptr;
++
++	bool txoff;		/* Transmit flow-controlled */
++};
++
++/* clkstate */
++#define CLK_NONE	0
++#define CLK_SDONLY	1
++#define CLK_PENDING	2	/* Not used yet */
++#define CLK_AVAIL	3
++
++#ifdef DEBUG
++static int qcount[NUMPRIO];
++static int tx_packets[NUMPRIO];
++#endif				/* DEBUG */
++
++#define SDIO_DRIVE_STRENGTH	6	/* in milliamps */
++
++#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
++
++/* Retry count for register access failures */
++static const uint retry_limit = 2;
++
++/* Limit on rounding up frames */
++static const uint max_roundup = 512;
++
++#define ALIGNMENT  4
++
++static void pkt_align(struct sk_buff *p, int len, int align)
++{
++	uint datalign;
++	datalign = (unsigned long)(p->data);
++	datalign = roundup(datalign, (align)) - datalign;
++	if (datalign)
++		skb_pull(p, datalign);
++	__skb_trim(p, len);
++}
++
++/* To check if there's window offered */
++static bool data_ok(struct brcmf_sdio *bus)
++{
++	return (u8)(bus->tx_max - bus->tx_seq) != 0 &&
++	       ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0;
++}
++
++/*
++ * Reads a register in the SDIO hardware block. This block occupies a series of
++ * adresses on the 32 bit backplane bus.
++ */
++static int
++r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	*regvar = brcmf_sdio_regrl(bus->sdiodev,
++				   bus->ci->c_inf[idx].base + offset, &ret);
++
++	return ret;
++}
++
++static int
++w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
++{
++	u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	int ret;
++
++	brcmf_sdio_regwl(bus->sdiodev,
++			 bus->ci->c_inf[idx].base + reg_offset,
++			 regval, &ret);
++
++	return ret;
++}
++
++#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
++
++#define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
++
++/* Packet free applicable unconditionally for sdio and sdspi.
++ * Conditional if bufpool was present for gspi bus.
++ */
++static void brcmf_sdbrcm_pktfree2(struct brcmf_sdio *bus, struct sk_buff *pkt)
++{
++	if (bus->usebufpool)
++		brcmu_pkt_buf_free_skb(pkt);
++}
++
++/* Turn backplane clock on or off */
++static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
++{
++	int err;
++	u8 clkctl, clkreq, devctl;
++	unsigned long timeout;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	clkctl = 0;
++
++	if (on) {
++		/* Request HT Avail */
++		clkreq =
++		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Check current status */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail read error: %d\n", err);
++			return -EBADE;
++		}
++
++		/* Go to pending and await interrupt if appropriate */
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
++			/* Allow only clock-available interrupt */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "Devctl error setting CA: %d\n",
++					  err);
++				return -EBADE;
++			}
++
++			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			brcmf_dbg(INFO, "CLKCTL: set PENDING\n");
++			bus->clkstate = CLK_PENDING;
++
++			return 0;
++		} else if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		/* Otherwise, wait here (polling) for HT Avail */
++		timeout = jiffies +
++			  msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000);
++		while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			clkctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_FUNC1_CHIPCLKCSR,
++						  &err);
++			if (time_after(jiffies, timeout))
++				break;
++			else
++				usleep_range(5000, 10000);
++		}
++		if (err) {
++			brcmf_dbg(ERROR, "HT Avail request error: %d\n", err);
++			return -EBADE;
++		}
++		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
++			brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n",
++				  PMU_MAX_TRANSITION_DLY, clkctl);
++			return -EBADE;
++		}
++
++		/* Mark clock available */
++		bus->clkstate = CLK_AVAIL;
++		brcmf_dbg(INFO, "CLKCTL: turned ON\n");
++
++#if defined(DEBUG)
++		if (!bus->alp_only) {
++			if (SBSDIO_ALPONLY(clkctl))
++				brcmf_dbg(ERROR, "HT Clock should be on\n");
++		}
++#endif				/* defined (DEBUG) */
++
++		bus->activity = true;
++	} else {
++		clkreq = 0;
++
++		if (bus->clkstate == CLK_PENDING) {
++			/* Cancel CA-only interrupt filter */
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++		}
++
++		bus->clkstate = CLK_SDONLY;
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 clkreq, &err);
++		brcmf_dbg(INFO, "CLKCTL: turned OFF\n");
++		if (err) {
++			brcmf_dbg(ERROR, "Failed access turning clock off: %d\n",
++				  err);
++			return -EBADE;
++		}
++	}
++	return 0;
++}
++
++/* Change idle/active SD state */
++static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (on)
++		bus->clkstate = CLK_SDONLY;
++	else
++		bus->clkstate = CLK_NONE;
++
++	return 0;
++}
++
++/* Transition SD and backplane clock readiness */
++static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
++{
++#ifdef DEBUG
++	uint oldstate = bus->clkstate;
++#endif				/* DEBUG */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Early exit if we're already there */
++	if (bus->clkstate == target) {
++		if (target == CLK_AVAIL) {
++			brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			bus->activity = true;
++		}
++		return 0;
++	}
++
++	switch (target) {
++	case CLK_AVAIL:
++		/* Make sure SD clock is available */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		/* Now request HT Avail on the backplane */
++		brcmf_sdbrcm_htclk(bus, true, pendok);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		bus->activity = true;
++		break;
++
++	case CLK_SDONLY:
++		/* Remove HT request, or bring up SD clock */
++		if (bus->clkstate == CLK_NONE)
++			brcmf_sdbrcm_sdclk(bus, true);
++		else if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		else
++			brcmf_dbg(ERROR, "request for %d -> %d\n",
++				  bus->clkstate, target);
++		brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++		break;
++
++	case CLK_NONE:
++		/* Make sure to remove HT request */
++		if (bus->clkstate == CLK_AVAIL)
++			brcmf_sdbrcm_htclk(bus, false, false);
++		/* Now remove the SD clock */
++		brcmf_sdbrcm_sdclk(bus, false);
++		brcmf_sdbrcm_wd_timer(bus, 0);
++		break;
++	}
++#ifdef DEBUG
++	brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
++#endif				/* DEBUG */
++
++	return 0;
++}
++
++static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
++{
++	int ret;
++
++	brcmf_dbg(INFO, "request %s (currently %s)\n",
++		  sleep ? "SLEEP" : "WAKE",
++		  bus->sleeping ? "SLEEP" : "WAKE");
++
++	/* Done if we're already in the requested state */
++	if (sleep == bus->sleeping)
++		return 0;
++
++	/* Going to sleep: set the alarm and turn off the lights... */
++	if (sleep) {
++		/* Don't sleep if something is pending */
++		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
++			return -EBUSY;
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Tell device to start using OOB wakeup */
++		ret = w_sdreg32(bus, SMB_USE_OOB,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
++
++		/* Turn off our contribution to the HT clock request */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
++
++		/* Isolate the bus */
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++				 SBSDIO_DEVCTL_PADS_ISO, NULL);
++
++		/* Change state */
++		bus->sleeping = true;
++
++	} else {
++		/* Waking up: bus power up is ok, set local state */
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 0, NULL);
++
++		/* Make sure the controller has the bus up */
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++		/* Send misc interrupt to indicate OOB not needed */
++		ret = w_sdreg32(bus, 0,
++				offsetof(struct sdpcmd_regs, tosbmailboxdata));
++		if (ret == 0)
++			ret = w_sdreg32(bus, SMB_DEV_INT,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		if (ret != 0)
++			brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
++
++		/* Make sure we have SD bus access */
++		brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++		/* Change state */
++		bus->sleeping = false;
++	}
++
++	return 0;
++}
++
++static void bus_wake(struct brcmf_sdio *bus)
++{
++	if (bus->sleeping)
++		brcmf_sdbrcm_bussleep(bus, false);
++}
++
++static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
++{
++	u32 intstatus = 0;
++	u32 hmb_data;
++	u8 fcbits;
++	int ret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Read mailbox data and ack that we did so */
++	ret = r_sdreg32(bus, &hmb_data,
++			offsetof(struct sdpcmd_regs, tohostmailboxdata));
++
++	if (ret == 0)
++		w_sdreg32(bus, SMB_INT_ACK,
++			  offsetof(struct sdpcmd_regs, tosbmailbox));
++	bus->f1regdata += 2;
++
++	/* Dongle recomposed rx frames, accept them again */
++	if (hmb_data & HMB_DATA_NAKHANDLED) {
++		brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n",
++			  bus->rx_seq);
++		if (!bus->rxskip)
++			brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n");
++
++		bus->rxskip = false;
++		intstatus |= I_HMB_FRAME_IND;
++	}
++
++	/*
++	 * DEVREADY does not occur with gSPI.
++	 */
++	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
++		bus->sdpcm_ver =
++		    (hmb_data & HMB_DATA_VERSION_MASK) >>
++		    HMB_DATA_VERSION_SHIFT;
++		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
++			brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, "
++				  "expecting %d\n",
++				  bus->sdpcm_ver, SDPCM_PROT_VERSION);
++		else
++			brcmf_dbg(INFO, "Dongle ready, protocol version %d\n",
++				  bus->sdpcm_ver);
++	}
++
++	/*
++	 * Flow Control has been moved into the RX headers and this out of band
++	 * method isn't used any more.
++	 * remaining backward compatible with older dongles.
++	 */
++	if (hmb_data & HMB_DATA_FC) {
++		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
++							HMB_DATA_FCDATA_SHIFT;
++
++		if (fcbits & ~bus->flowcontrol)
++			bus->fc_xoff++;
++
++		if (bus->flowcontrol & ~fcbits)
++			bus->fc_xon++;
++
++		bus->fc_rcvd++;
++		bus->flowcontrol = fcbits;
++	}
++
++	/* Shouldn't be any others */
++	if (hmb_data & ~(HMB_DATA_DEVREADY |
++			 HMB_DATA_NAKHANDLED |
++			 HMB_DATA_FC |
++			 HMB_DATA_FWREADY |
++			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK))
++		brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n",
++			  hmb_data);
++
++	return intstatus;
++}
++
++static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
++{
++	uint retries = 0;
++	u16 lastrbc;
++	u8 hi, lo;
++	int err;
++
++	brcmf_dbg(ERROR, "%sterminate frame%s\n",
++		  abort ? "abort command, " : "",
++		  rtx ? ", send NAK" : "");
++
++	if (abort)
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++			 SFC_RF_TERM, &err);
++	bus->f1regdata++;
++
++	/* Wait until the packet has been flushed (device/FIFO stable) */
++	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
++		hi = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCHI, &err);
++		lo = brcmf_sdio_regrb(bus->sdiodev,
++				      SBSDIO_FUNC1_RFRAMEBCLO, &err);
++		bus->f1regdata += 2;
++
++		if ((hi == 0) && (lo == 0))
++			break;
++
++		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
++			brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n",
++				  lastrbc, (hi << 8) + lo);
++		}
++		lastrbc = (hi << 8) + lo;
++	}
++
++	if (!retries)
++		brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc);
++	else
++		brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries);
++
++	if (rtx) {
++		bus->rxrtx++;
++		err = w_sdreg32(bus, SMB_NAK,
++				offsetof(struct sdpcmd_regs, tosbmailbox));
++
++		bus->f1regdata++;
++		if (err == 0)
++			bus->rxskip = true;
++	}
++
++	/* Clear partial in any case */
++	bus->nextlen = 0;
++
++	/* If we can't reach the device, signal failure */
++	if (err)
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++}
++
++/* copy a buffer into a pkt buffer chain */
++static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len)
++{
++	uint n, ret = 0;
++	struct sk_buff *p;
++	u8 *buf;
++
++	buf = bus->dataptr;
++
++	/* copy the data */
++	skb_queue_walk(&bus->glom, p) {
++		n = min_t(uint, p->len, len);
++		memcpy(p->data, buf, n);
++		buf += n;
++		len -= n;
++		ret += n;
++		if (!len)
++			break;
++	}
++
++	return ret;
++}
++
++/* return total length of buffer chain */
++static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
++{
++	struct sk_buff *p;
++	uint total;
++
++	total = 0;
++	skb_queue_walk(&bus->glom, p)
++		total += p->len;
++	return total;
++}
++
++static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
++{
++	struct sk_buff *cur, *next;
++
++	skb_queue_walk_safe(&bus->glom, cur, next) {
++		skb_unlink(cur, &bus->glom);
++		brcmu_pkt_buf_free_skb(cur);
++	}
++}
++
++static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
++{
++	u16 dlen, totlen;
++	u8 *dptr, num = 0;
++
++	u16 sublen, check;
++	struct sk_buff *pfirst, *pnext;
++
++	int errcode;
++	u8 chan, seq, doff, sfdoff;
++	u8 txmax;
++
++	int ifidx = 0;
++	bool usechain = bus->use_rxchain;
++
++	/* If packets, issue read(s) and send up packet chain */
++	/* Return sequence numbers consumed? */
++
++	brcmf_dbg(TRACE, "start: glomd %p glom %p\n",
++		  bus->glomd, skb_peek(&bus->glom));
++
++	/* If there's a descriptor, generate the packet chain */
++	if (bus->glomd) {
++		pfirst = pnext = NULL;
++		dlen = (u16) (bus->glomd->len);
++		dptr = bus->glomd->data;
++		if (!dlen || (dlen & 1)) {
++			brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n",
++				  dlen);
++			dlen = 0;
++		}
++
++		for (totlen = num = 0; dlen; num++) {
++			/* Get (and move past) next length */
++			sublen = get_unaligned_le16(dptr);
++			dlen -= sizeof(u16);
++			dptr += sizeof(u16);
++			if ((sublen < SDPCM_HDRLEN) ||
++			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
++				brcmf_dbg(ERROR, "descriptor len %d bad: %d\n",
++					  num, sublen);
++				pnext = NULL;
++				break;
++			}
++			if (sublen % BRCMF_SDALIGN) {
++				brcmf_dbg(ERROR, "sublen %d not multiple of %d\n",
++					  sublen, BRCMF_SDALIGN);
++				usechain = false;
++			}
++			totlen += sublen;
++
++			/* For last frame, adjust read len so total
++				 is a block multiple */
++			if (!dlen) {
++				sublen +=
++				    (roundup(totlen, bus->blocksize) - totlen);
++				totlen = roundup(totlen, bus->blocksize);
++			}
++
++			/* Allocate/chain packet for next subframe */
++			pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN);
++			if (pnext == NULL) {
++				brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n",
++					  num, sublen);
++				break;
++			}
++			skb_queue_tail(&bus->glom, pnext);
++
++			/* Adhere to start alignment requirements */
++			pkt_align(pnext, sublen, BRCMF_SDALIGN);
++		}
++
++		/* If all allocations succeeded, save packet chain
++			 in bus structure */
++		if (pnext) {
++			brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
++				  totlen, num);
++			if (BRCMF_GLOM_ON() && bus->nextlen &&
++			    totlen != bus->nextlen) {
++				brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
++					  bus->nextlen, totlen, rxseq);
++			}
++			pfirst = pnext = NULL;
++		} else {
++			brcmf_sdbrcm_free_glom(bus);
++			num = 0;
++		}
++
++		/* Done with descriptor packet */
++		brcmu_pkt_buf_free_skb(bus->glomd);
++		bus->glomd = NULL;
++		bus->nextlen = 0;
++	}
++
++	/* Ok -- either we just generated a packet chain,
++		 or had one from before */
++	if (!skb_queue_empty(&bus->glom)) {
++		if (BRCMF_GLOM_ON()) {
++			brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
++			skb_queue_walk(&bus->glom, pnext) {
++				brcmf_dbg(GLOM, "    %p: %p len 0x%04x (%d)\n",
++					  pnext, (u8 *) (pnext->data),
++					  pnext->len, pnext->len);
++			}
++		}
++
++		pfirst = skb_peek(&bus->glom);
++		dlen = (u16) brcmf_sdbrcm_glom_len(bus);
++
++		/* Do an SDIO read for the superframe.  Configurable iovar to
++		 * read directly into the chained packet, or allocate a large
++		 * packet and and copy into the chain.
++		 */
++		if (usechain) {
++			errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC, &bus->glom);
++		} else if (bus->dataptr) {
++			errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
++					bus->sdiodev->sbwad,
++					SDIO_FUNC_2, F2SYNC,
++					bus->dataptr, dlen);
++			sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
++			if (sublen != dlen) {
++				brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n",
++					  dlen, sublen);
++				errcode = -1;
++			}
++			pnext = NULL;
++		} else {
++			brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
++				  dlen);
++			errcode = -1;
++		}
++		bus->f2rxdata++;
++
++		/* On failure, kill the superframe, allow a couple retries */
++		if (errcode < 0) {
++			brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n",
++				  dlen, errcode);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++
++			if (bus->glomerr++ < 3) {
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			return 0;
++		}
++
++		brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++				   pfirst->data, min_t(int, pfirst->len, 48),
++				   "SUPERFRAME:\n");
++
++		/* Validate the superframe header */
++		dptr = (u8 *) (pfirst->data);
++		sublen = get_unaligned_le16(dptr);
++		check = get_unaligned_le16(dptr + sizeof(u16));
++
++		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++		errcode = 0;
++		if ((u16)~(sublen ^ check)) {
++			brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
++				  sublen, check);
++			errcode = -1;
++		} else if (roundup(sublen, bus->blocksize) != dlen) {
++			brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
++				  sublen, roundup(sublen, bus->blocksize),
++				  dlen);
++			errcode = -1;
++		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
++			   SDPCM_GLOM_CHANNEL) {
++			brcmf_dbg(ERROR, "(superframe): bad channel %d\n",
++				  SDPCM_PACKET_CHANNEL(
++					  &dptr[SDPCM_FRAMETAG_LEN]));
++			errcode = -1;
++		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
++			brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n");
++			errcode = -1;
++		} else if ((doff < SDPCM_HDRLEN) ||
++			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
++			brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
++				  doff, sublen, pfirst->len, SDPCM_HDRLEN);
++			errcode = -1;
++		}
++
++		/* Check sequence number of superframe SW header */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n",
++				  seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Remove superframe header, remember offset */
++		skb_pull(pfirst, doff);
++		sfdoff = doff;
++		num = 0;
++
++		/* Validate all the subframe headers */
++		skb_queue_walk(&bus->glom, pnext) {
++			/* leave when invalid subframe is found */
++			if (errcode)
++				break;
++
++			dptr = (u8 *) (pnext->data);
++			dlen = (u16) (pnext->len);
++			sublen = get_unaligned_le16(dptr);
++			check = get_unaligned_le16(dptr + sizeof(u16));
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   dptr, 32, "subframe:\n");
++
++			if ((u16)~(sublen ^ check)) {
++				brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
++					  num, sublen, check);
++				errcode = -1;
++			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
++				brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
++					  num, sublen, dlen);
++				errcode = -1;
++			} else if ((chan != SDPCM_DATA_CHANNEL) &&
++				   (chan != SDPCM_EVENT_CHANNEL)) {
++				brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n",
++					  num, chan);
++				errcode = -1;
++			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
++				brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n",
++					  num, doff, sublen, SDPCM_HDRLEN);
++				errcode = -1;
++			}
++			/* increase the subframe count */
++			num++;
++		}
++
++		if (errcode) {
++			/* Terminate frame on error, request
++				 a couple retries */
++			if (bus->glomerr++ < 3) {
++				/* Restore superframe header space */
++				skb_push(pfirst, sfdoff);
++				brcmf_sdbrcm_rxfail(bus, true, true);
++			} else {
++				bus->glomerr = 0;
++				brcmf_sdbrcm_rxfail(bus, true, false);
++				bus->rxglomfail++;
++				brcmf_sdbrcm_free_glom(bus);
++			}
++			bus->nextlen = 0;
++			return 0;
++		}
++
++		/* Basic SD framing looks ok - process each packet (header) */
++
++		skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
++			dptr = (u8 *) (pfirst->data);
++			sublen = get_unaligned_le16(dptr);
++			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
++
++			brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
++				  num, pfirst, pfirst->data,
++				  pfirst->len, sublen, chan, seq);
++
++			/* precondition: chan == SDPCM_DATA_CHANNEL ||
++					 chan == SDPCM_EVENT_CHANNEL */
++
++			if (rxseq != seq) {
++				brcmf_dbg(GLOM, "rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++			rxseq++;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   dptr, dlen, "Rx Subframe Data:\n");
++
++			__skb_trim(pfirst, sublen);
++			skb_pull(pfirst, doff);
++
++			if (pfirst->len == 0) {
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			} else if (brcmf_proto_hdrpull(bus->sdiodev->dev,
++						       &ifidx, pfirst) != 0) {
++				brcmf_dbg(ERROR, "rx protocol error\n");
++				bus->sdiodev->bus_if->dstats.rx_errors++;
++				skb_unlink(pfirst, &bus->glom);
++				brcmu_pkt_buf_free_skb(pfirst);
++				continue;
++			}
++
++			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++					   pfirst->data,
++					   min_t(int, pfirst->len, 32),
++					   "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
++					   bus->glom.qlen, pfirst, pfirst->data,
++					   pfirst->len, pfirst->next,
++					   pfirst->prev);
++		}
++		/* sent any remaining packets up */
++		if (bus->glom.qlen) {
++			up(&bus->sdsem);
++			brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
++			down(&bus->sdsem);
++		}
++
++		bus->rxglomframes++;
++		bus->rxglompkts += bus->glom.qlen;
++	}
++	return num;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
++					bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT);
++
++	/* Wait until control frame is available */
++	add_wait_queue(&bus->dcmd_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	while (!(*condition) && (!signal_pending(current) && timeout))
++		timeout = schedule_timeout(timeout);
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&bus->dcmd_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->dcmd_resp_wait))
++		wake_up_interruptible(&bus->dcmd_resp_wait);
++
++	return 0;
++}
++static void
++brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
++{
++	uint rdlen, pad;
++
++	int sdret;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Set rxctl for frame (w/optional alignment) */
++	bus->rxctl = bus->rxbuf;
++	bus->rxctl += BRCMF_FIRSTREAD;
++	pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
++	if (pad)
++		bus->rxctl += (BRCMF_SDALIGN - pad);
++	bus->rxctl -= BRCMF_FIRSTREAD;
++
++	/* Copy the already-read portion over */
++	memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
++	if (len <= BRCMF_FIRSTREAD)
++		goto gotpkt;
++
++	/* Raise rdlen to next SDIO block to avoid tail command */
++	rdlen = len - BRCMF_FIRSTREAD;
++	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
++		pad = bus->blocksize - (rdlen % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++		    ((len + pad) < bus->sdiodev->bus_if->maxctl))
++			rdlen += pad;
++	} else if (rdlen % BRCMF_SDALIGN) {
++		rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (rdlen & (ALIGNMENT - 1))
++		rdlen = roundup(rdlen, ALIGNMENT);
++
++	/* Drop if the read is too big or it exceeds our maximum */
++	if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n",
++			  rdlen, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	if ((len - doff) > bus->sdiodev->bus_if->maxctl) {
++		brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
++			  len, len - doff, bus->sdiodev->bus_if->maxctl);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		bus->rx_toolong++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto done;
++	}
++
++	/* Read remainder of frame body into the rxctl buffer */
++	sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
++				bus->sdiodev->sbwad,
++				SDIO_FUNC_2,
++				F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen);
++	bus->f2rxdata++;
++
++	/* Control frame failures need retransmission */
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "read %d control bytes failed: %d\n",
++			  rdlen, sdret);
++		bus->rxc_errors++;
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto done;
++	}
++
++gotpkt:
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++			   bus->rxctl, len, "RxCtrl:\n");
++
++	/* Point to valid data and indicate its length */
++	bus->rxctl += doff;
++	bus->rxlen = len - doff;
++
++done:
++	/* Awake any waiters */
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++}
++
++/* Pad read to blocksize for efficiency */
++static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
++{
++	if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) {
++		*pad = bus->blocksize - (*rdlen % bus->blocksize);
++		if (*pad <= bus->roundup && *pad < bus->blocksize &&
++		    *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
++			*rdlen += *pad;
++	} else if (*rdlen % BRCMF_SDALIGN) {
++		*rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
++	}
++}
++
++static void
++brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen,
++			 struct sk_buff **pkt, u8 **rxbuf)
++{
++	int sdret;		/* Return code from calls */
++
++	*pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
++	if (*pkt == NULL)
++		return;
++
++	pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
++	*rxbuf = (u8 *) ((*pkt)->data);
++	/* Read the entire frame */
++	sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				      SDIO_FUNC_2, F2SYNC, *pkt);
++	bus->f2rxdata++;
++
++	if (sdret < 0) {
++		brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
++			  rdlen, sdret);
++		brcmu_pkt_buf_free_skb(*pkt);
++		bus->sdiodev->bus_if->dstats.rx_errors++;
++		/* Force retry w/normal header read.
++		 * Don't attempt NAK for
++		 * gSPI
++		 */
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		*pkt = NULL;
++	}
++}
++
++/* Checks the header */
++static int
++brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf,
++		  u8 rxseq, u16 nextlen, u16 *len)
++{
++	u16 check;
++	bool len_consistent;	/* Result of comparing readahead len and
++				   len from hw-hdr */
++
++	memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
++
++	/* Extract hardware header fields */
++	*len = get_unaligned_le16(bus->rxhdr);
++	check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++	/* All zeros means readahead info was bad */
++	if (!(*len | check)) {
++		brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
++		goto fail;
++	}
++
++	/* Validate check bytes */
++	if ((u16)~(*len ^ check)) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
++			  nextlen, *len, check);
++		bus->rx_badhdr++;
++		brcmf_sdbrcm_rxfail(bus, false, false);
++		goto fail;
++	}
++
++	/* Validate frame length */
++	if (*len < SDPCM_HDRLEN) {
++		brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
++			  *len);
++		goto fail;
++	}
++
++	/* Check for consistency with readahead info */
++	len_consistent = (nextlen != (roundup(*len, 16) >> 4));
++	if (len_consistent) {
++		/* Mismatch, force retry w/normal
++			header (may be >4K) */
++		brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
++			  nextlen, *len, roundup(*len, 16),
++			  rxseq);
++		brcmf_sdbrcm_rxfail(bus, true, true);
++		goto fail;
++	}
++
++	return 0;
++
++fail:
++	brcmf_sdbrcm_pktfree2(bus, pkt);
++	return -EINVAL;
++}
++
++/* Return true if there may be more frames to read */
++static uint
++brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
++{
++	u16 len, check;	/* Extracted hardware header fields */
++	u8 chan, seq, doff;	/* Extracted software header fields */
++	u8 fcbits;		/* Extracted fcbits from software header */
++
++	struct sk_buff *pkt;		/* Packet for event or data frames */
++	u16 pad;		/* Number of pad bytes to read */
++	u16 rdlen;		/* Total number of bytes to read */
++	u8 rxseq;		/* Next sequence number to expect */
++	uint rxleft = 0;	/* Remaining number of frames allowed */
++	int sdret;		/* Return code from calls */
++	u8 txmax;		/* Maximum tx sequence offered */
++	u8 *rxbuf;
++	int ifidx = 0;
++	uint rxcount = 0;	/* Total frames read */
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Not finished unless we encounter no more frames indication */
++	*finished = false;
++
++	for (rxseq = bus->rx_seq, rxleft = maxframes;
++	     !bus->rxskip && rxleft &&
++	     bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
++	     rxseq++, rxleft--) {
++
++		/* Handle glomming separately */
++		if (bus->glomd || !skb_queue_empty(&bus->glom)) {
++			u8 cnt;
++			brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
++				  bus->glomd, skb_peek(&bus->glom));
++			cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
++			brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
++			rxseq += cnt - 1;
++			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
++			continue;
++		}
++
++		/* Try doing single read if we can */
++		if (bus->nextlen) {
++			u16 nextlen = bus->nextlen;
++			bus->nextlen = 0;
++
++			rdlen = len = nextlen << 4;
++			brcmf_pad(bus, &pad, &rdlen);
++
++			/*
++			 * After the frame is received we have to
++			 * distinguish whether it is data
++			 * or non-data frame.
++			 */
++			brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf);
++			if (pkt == NULL) {
++				/* Give up on data, request rtx of events */
++				brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
++					  len, rdlen, rxseq);
++				continue;
++			}
++
++			if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
++					      &len) < 0)
++				continue;
++
++			/* Extract software header fields */
++			chan = SDPCM_PACKET_CHANNEL(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			seq = SDPCM_PACKET_SEQUENCE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			doff = SDPCM_DOFFSET_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++			txmax = SDPCM_WINDOW_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			bus->nextlen =
++			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
++				       SDPCM_NEXTLEN_OFFSET];
++			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++				brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++					  bus->nextlen, seq);
++				bus->nextlen = 0;
++			}
++
++			bus->rx_readahead_cnt++;
++
++			/* Handle Flow Control */
++			fcbits = SDPCM_FCMASK_VALUE(
++					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++			if (bus->flowcontrol != fcbits) {
++				if (~bus->flowcontrol & fcbits)
++					bus->fc_xoff++;
++
++				if (bus->flowcontrol & ~fcbits)
++					bus->fc_xon++;
++
++				bus->fc_rcvd++;
++				bus->flowcontrol = fcbits;
++			}
++
++			/* Check and update sequence number */
++			if (rxseq != seq) {
++				brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
++					  seq, rxseq);
++				bus->rx_badseq++;
++				rxseq = seq;
++			}
++
++			/* Check window for sanity */
++			if ((u8) (txmax - bus->tx_seq) > 0x40) {
++				brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
++					  txmax, bus->tx_seq);
++				txmax = bus->tx_seq + 2;
++			}
++			bus->tx_max = txmax;
++
++			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++					   rxbuf, len, "Rx Data:\n");
++			brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++					     BRCMF_DATA_ON()) &&
++					   BRCMF_HDRS_ON(),
++					   bus->rxhdr, SDPCM_HDRLEN,
++					   "RxHdr:\n");
++
++			if (chan == SDPCM_CONTROL_CHANNEL) {
++				brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
++					  seq);
++				/* Force retry w/normal header read */
++				bus->nextlen = 0;
++				brcmf_sdbrcm_rxfail(bus, false, true);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* Validate data offset */
++			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++				brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n",
++					  doff, len, SDPCM_HDRLEN);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++				brcmf_sdbrcm_pktfree2(bus, pkt);
++				continue;
++			}
++
++			/* All done with this one -- now deliver the packet */
++			goto deliver;
++		}
++
++		/* Read frame header (hardware and software) */
++		sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, bus->rxhdr,
++					      BRCMF_FIRSTREAD);
++		bus->f2rxhdrs++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
++			bus->rx_hdrfail++;
++			brcmf_sdbrcm_rxfail(bus, true, true);
++			continue;
++		}
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
++				   bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
++
++
++		/* Extract hardware header fields */
++		len = get_unaligned_le16(bus->rxhdr);
++		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
++
++		/* All zeros means no more frames */
++		if (!(len | check)) {
++			*finished = true;
++			break;
++		}
++
++		/* Validate check bytes */
++		if ((u16) ~(len ^ check)) {
++			brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
++				  len, check);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Validate frame length */
++		if (len < SDPCM_HDRLEN) {
++			brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
++			continue;
++		}
++
++		/* Extract software header fields */
++		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		/* Validate data offset */
++		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
++			brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
++				  doff, len, SDPCM_HDRLEN, seq);
++			bus->rx_badhdr++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		/* Save the readahead length if there is one */
++		bus->nextlen =
++		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
++		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
++			brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
++				  bus->nextlen, seq);
++			bus->nextlen = 0;
++		}
++
++		/* Handle Flow Control */
++		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
++
++		if (bus->flowcontrol != fcbits) {
++			if (~bus->flowcontrol & fcbits)
++				bus->fc_xoff++;
++
++			if (bus->flowcontrol & ~fcbits)
++				bus->fc_xon++;
++
++			bus->fc_rcvd++;
++			bus->flowcontrol = fcbits;
++		}
++
++		/* Check and update sequence number */
++		if (rxseq != seq) {
++			brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
++			bus->rx_badseq++;
++			rxseq = seq;
++		}
++
++		/* Check window for sanity */
++		if ((u8) (txmax - bus->tx_seq) > 0x40) {
++			brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
++				  txmax, bus->tx_seq);
++			txmax = bus->tx_seq + 2;
++		}
++		bus->tx_max = txmax;
++
++		/* Call a separate function for control frames */
++		if (chan == SDPCM_CONTROL_CHANNEL) {
++			brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
++			continue;
++		}
++
++		/* precondition: chan is either SDPCM_DATA_CHANNEL,
++		   SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
++		   SDPCM_GLOM_CHANNEL */
++
++		/* Length to read */
++		rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
++
++		/* May pad read to blocksize for efficiency */
++		if (bus->roundup && bus->blocksize &&
++			(rdlen > bus->blocksize)) {
++			pad = bus->blocksize - (rdlen % bus->blocksize);
++			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
++			    ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
++				rdlen += pad;
++		} else if (rdlen % BRCMF_SDALIGN) {
++			rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
++		}
++
++		/* Satisfy length-alignment requirements */
++		if (rdlen & (ALIGNMENT - 1))
++			rdlen = roundup(rdlen, ALIGNMENT);
++
++		if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
++			/* Too long -- skip this frame */
++			brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
++				  len, rdlen);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			bus->rx_toolong++;
++			brcmf_sdbrcm_rxfail(bus, false, false);
++			continue;
++		}
++
++		pkt = brcmu_pkt_buf_get_skb(rdlen +
++					    BRCMF_FIRSTREAD + BRCMF_SDALIGN);
++		if (!pkt) {
++			/* Give up on data, request rtx of events */
++			brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n",
++				  rdlen, chan);
++			bus->sdiodev->bus_if->dstats.rx_dropped++;
++			brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Leave room for what we already read, and align remainder */
++		skb_pull(pkt, BRCMF_FIRSTREAD);
++		pkt_align(pkt, rdlen, BRCMF_SDALIGN);
++
++		/* Read the remaining frame data */
++		sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++					      SDIO_FUNC_2, F2SYNC, pkt);
++		bus->f2rxdata++;
++
++		if (sdret < 0) {
++			brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen,
++				  ((chan == SDPCM_EVENT_CHANNEL) ? "event"
++				   : ((chan == SDPCM_DATA_CHANNEL) ? "data"
++				      : "test")), sdret);
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan));
++			continue;
++		}
++
++		/* Copy the already-read portion */
++		skb_push(pkt, BRCMF_FIRSTREAD);
++		memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
++
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
++				   pkt->data, len, "Rx Data:\n");
++
++deliver:
++		/* Save superframe descriptor and allocate packet frame */
++		if (chan == SDPCM_GLOM_CHANNEL) {
++			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
++				brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
++					  len);
++				brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
++						   pkt->data, len,
++						   "Glom Data:\n");
++				__skb_trim(pkt, len);
++				skb_pull(pkt, SDPCM_HDRLEN);
++				bus->glomd = pkt;
++			} else {
++				brcmf_dbg(ERROR, "%s: glom superframe w/o "
++					  "descriptor!\n", __func__);
++				brcmf_sdbrcm_rxfail(bus, false, false);
++			}
++			continue;
++		}
++
++		/* Fill in packet len and prio, deliver upward */
++		__skb_trim(pkt, len);
++		skb_pull(pkt, doff);
++
++		if (pkt->len == 0) {
++			brcmu_pkt_buf_free_skb(pkt);
++			continue;
++		} else if (brcmf_proto_hdrpull(bus->sdiodev->dev, &ifidx,
++			   pkt) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(pkt);
++			bus->sdiodev->bus_if->dstats.rx_errors++;
++			continue;
++		}
++
++		/* Unlock during rx call */
++		up(&bus->sdsem);
++		brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
++		down(&bus->sdsem);
++	}
++	rxcount = maxframes - rxleft;
++	/* Message if we hit the limit */
++	if (!rxleft)
++		brcmf_dbg(DATA, "hit rx limit of %d frames\n",
++			  maxframes);
++	else
++		brcmf_dbg(DATA, "processed %d frames\n", rxcount);
++	/* Back off rxseq if awaiting rtx, update rx_seq */
++	if (bus->rxskip)
++		rxseq--;
++	bus->rx_seq = rxseq;
++
++	return rxcount;
++}
++
++static void
++brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
++{
++	up(&bus->sdsem);
++	wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
++	down(&bus->sdsem);
++	return;
++}
++
++static void
++brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
++{
++	if (waitqueue_active(&bus->ctrl_wait))
++		wake_up_interruptible(&bus->ctrl_wait);
++	return;
++}
++
++/* Writes a HW/SW header into the packet and sends it. */
++/* Assumes: (a) header space already there, (b) caller holds lock */
++static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
++			      uint chan, bool free_pkt)
++{
++	int ret;
++	u8 *frame;
++	u16 len, pad = 0;
++	u32 swheader;
++	struct sk_buff *new;
++	int i;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	frame = (u8 *) (pkt->data);
++
++	/* Add alignment padding, allocate new packet if needed */
++	pad = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (pad) {
++		if (skb_headroom(pkt) < pad) {
++			brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n",
++				  skb_headroom(pkt), pad);
++			bus->sdiodev->bus_if->tx_realloc++;
++			new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN);
++			if (!new) {
++				brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n",
++					  pkt->len + BRCMF_SDALIGN);
++				ret = -ENOMEM;
++				goto done;
++			}
++
++			pkt_align(new, pkt->len, BRCMF_SDALIGN);
++			memcpy(new->data, pkt->data, pkt->len);
++			if (free_pkt)
++				brcmu_pkt_buf_free_skb(pkt);
++			/* free the pkt if canned one is not used */
++			free_pkt = true;
++			pkt = new;
++			frame = (u8 *) (pkt->data);
++			/* precondition: (frame % BRCMF_SDALIGN) == 0) */
++			pad = 0;
++		} else {
++			skb_push(pkt, pad);
++			frame = (u8 *) (pkt->data);
++			/* precondition: pad + SDPCM_HDRLEN <= pkt->len */
++			memset(frame, 0, pad + SDPCM_HDRLEN);
++		}
++	}
++	/* precondition: pad < BRCMF_SDALIGN */
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	len = (u16) (pkt->len);
++	*(__le16 *) frame = cpu_to_le16(len);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~len);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
++	    (((pad +
++	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
++
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++#ifdef DEBUG
++	tx_packets[pkt->priority]++;
++#endif
++
++	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() &&
++			   ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
++			    (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)),
++			   frame, len, "Tx Frame:\n");
++	brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
++			     ((BRCMF_CTL_ON() &&
++			       chan == SDPCM_CONTROL_CHANNEL) ||
++			      (BRCMF_DATA_ON() &&
++			       chan != SDPCM_CONTROL_CHANNEL))) &&
++			   BRCMF_HDRS_ON(),
++			   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++	/* Raise len to next SDIO block to eliminate tail command */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++				len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Some controllers have trouble with odd bytes -- round to even */
++	if (len & (ALIGNMENT - 1))
++			len = roundup(len, ALIGNMENT);
++
++	ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, pkt);
++	bus->f2txdata++;
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if ((hi == 0) && (lo == 0))
++				break;
++		}
++
++	}
++	if (ret == 0)
++		bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++done:
++	/* restore pkt buffer pointer before calling tx complete routine */
++	skb_pull(pkt, SDPCM_HDRLEN + pad);
++	up(&bus->sdsem);
++	brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
++	down(&bus->sdsem);
++
++	if (free_pkt)
++		brcmu_pkt_buf_free_skb(pkt);
++
++	return ret;
++}
++
++static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
++{
++	struct sk_buff *pkt;
++	u32 intstatus = 0;
++	int ret = 0, prec_out;
++	uint cnt = 0;
++	uint datalen;
++	u8 tx_prec_map;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	tx_prec_map = ~bus->flowcontrol;
++
++	/* Send frames until the limit or some other event */
++	for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
++		spin_lock_bh(&bus->txqlock);
++		pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
++		if (pkt == NULL) {
++			spin_unlock_bh(&bus->txqlock);
++			break;
++		}
++		spin_unlock_bh(&bus->txqlock);
++		datalen = pkt->len - SDPCM_HDRLEN;
++
++		ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
++		if (ret)
++			bus->sdiodev->bus_if->dstats.tx_errors++;
++		else
++			bus->sdiodev->bus_if->dstats.tx_bytes += datalen;
++
++		/* In poll mode, need to check for other events */
++		if (!bus->intr && cnt) {
++			/* Check device status, signal pending interrupt */
++			ret = r_sdreg32(bus, &intstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f2txdata++;
++			if (ret != 0)
++				break;
++			if (intstatus & bus->hostintmask)
++				bus->ipend = true;
++		}
++	}
++
++	/* Deflow-control stack if needed */
++	if (bus->sdiodev->bus_if->drvr_up &&
++	    (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
++	    bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
++		bus->txoff = OFF;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF);
++	}
++
++	return cnt;
++}
++
++static void brcmf_sdbrcm_bus_stop(struct device *dev)
++{
++	u32 local_hostintmask;
++	u8 saveclk;
++	int err;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->watchdog_tsk) {
++		send_sig(SIGTERM, bus->watchdog_tsk, 1);
++		kthread_stop(bus->watchdog_tsk);
++		bus->watchdog_tsk = NULL;
++	}
++
++	if (bus->dpc_tsk && bus->dpc_tsk != current) {
++		send_sig(SIGTERM, bus->dpc_tsk, 1);
++		kthread_stop(bus->dpc_tsk);
++		bus->dpc_tsk = NULL;
++	}
++
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Enable clock for device interrupts */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Disable and clear interrupts at the chip level also */
++	w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));
++	local_hostintmask = bus->hostintmask;
++	bus->hostintmask = 0;
++
++	/* Change our idea of bus state */
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err)
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++
++	/* Turn off the bus (F2), free any pending packets */
++	brcmf_dbg(INTR, "disable SDIO interrupts\n");
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1,
++			 NULL);
++
++	/* Clear any pending interrupts now that F2 is disabled */
++	w_sdreg32(bus, local_hostintmask,
++		  offsetof(struct sdpcmd_regs, intstatus));
++
++	/* Turn off the backplane clock (only) */
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	/* Clear the data packet queues */
++	brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
++
++	/* Clear any held glomming stuff */
++	if (bus->glomd)
++		brcmu_pkt_buf_free_skb(bus->glomd);
++	brcmf_sdbrcm_free_glom(bus);
++
++	/* Clear rx control and wake any waiters */
++	bus->rxlen = 0;
++	brcmf_sdbrcm_dcmd_resp_wake(bus);
++
++	/* Reset some F2 state stuff */
++	bus->rxskip = false;
++	bus->tx_seq = bus->rx_seq = 0;
++
++	up(&bus->sdsem);
++}
++
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
++	if (!bus->sdiodev->irq_en && !bus->ipend) {
++		enable_irq(bus->sdiodev->irq);
++		bus->sdiodev->irq_en = true;
++	}
++	spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags);
++}
++#else
++static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
++{
++}
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++
++static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
++{
++	u32 intstatus, newstatus = 0;
++	uint rxlimit = bus->rxbound;	/* Rx frames to read before resched */
++	uint txlimit = bus->txbound;	/* Tx frames to send before resched */
++	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
++	bool rxdone = true;	/* Flag for no more read data */
++	bool resched = false;	/* Flag indicating resched wanted */
++	int err = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Start with leftover status bits */
++	intstatus = bus->intstatus;
++
++	down(&bus->sdsem);
++
++	/* If waiting for HTAVAIL, check status */
++	if (bus->clkstate == CLK_PENDING) {
++		u8 clkctl, devctl = 0;
++
++#ifdef DEBUG
++		/* Check for inconsistent device control */
++		devctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_DEVICE_CTL, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++#endif				/* DEBUG */
++
++		/* Read CSR, if clock on switch to AVAIL, else ignore */
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++		if (err) {
++			brcmf_dbg(ERROR, "error reading CSR: %d\n",
++				  err);
++			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		}
++
++		brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
++			  devctl, clkctl);
++
++		if (SBSDIO_HTAV(clkctl)) {
++			devctl = brcmf_sdio_regrb(bus->sdiodev,
++						  SBSDIO_DEVICE_CTL, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error reading DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
++					 devctl, &err);
++			if (err) {
++				brcmf_dbg(ERROR, "error writing DEVCTL: %d\n",
++					  err);
++				bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++			}
++			bus->clkstate = CLK_AVAIL;
++		} else {
++			goto clkwait;
++		}
++	}
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
++	if (bus->clkstate == CLK_PENDING)
++		goto clkwait;
++
++	/* Pending interrupt indicates new device status */
++	if (bus->ipend) {
++		bus->ipend = false;
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata++;
++		if (err != 0)
++			newstatus = 0;
++		newstatus &= bus->hostintmask;
++		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
++		if (newstatus) {
++			err = w_sdreg32(bus, newstatus,
++					offsetof(struct sdpcmd_regs,
++						 intstatus));
++			bus->f1regdata++;
++		}
++	}
++
++	/* Merge new bits with previous */
++	intstatus |= newstatus;
++	bus->intstatus = 0;
++
++	/* Handle flow-control change: read new state in case our ack
++	 * crossed another change interrupt.  If change still set, assume
++	 * FC ON for safety, let next loop through do the debounce.
++	 */
++	if (intstatus & I_HMB_FC_CHANGE) {
++		intstatus &= ~I_HMB_FC_CHANGE;
++		err = w_sdreg32(bus, I_HMB_FC_CHANGE,
++				offsetof(struct sdpcmd_regs, intstatus));
++
++		err = r_sdreg32(bus, &newstatus,
++				offsetof(struct sdpcmd_regs, intstatus));
++		bus->f1regdata += 2;
++		bus->fcstate =
++		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
++		intstatus |= (newstatus & bus->hostintmask);
++	}
++
++	/* Handle host mailbox indication */
++	if (intstatus & I_HMB_HOST_INT) {
++		intstatus &= ~I_HMB_HOST_INT;
++		intstatus |= brcmf_sdbrcm_hostmail(bus);
++	}
++
++	/* Generally don't ask for these, can get CRC errors... */
++	if (intstatus & I_WR_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
++		intstatus &= ~I_WR_OOSYNC;
++	}
++
++	if (intstatus & I_RD_OOSYNC) {
++		brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n");
++		intstatus &= ~I_RD_OOSYNC;
++	}
++
++	if (intstatus & I_SBINT) {
++		brcmf_dbg(ERROR, "Dongle reports SBINT\n");
++		intstatus &= ~I_SBINT;
++	}
++
++	/* Would be active due to wake-wlan in gSPI */
++	if (intstatus & I_CHIPACTIVE) {
++		brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n");
++		intstatus &= ~I_CHIPACTIVE;
++	}
++
++	/* Ignore frame indications if rxskip is set */
++	if (bus->rxskip)
++		intstatus &= ~I_HMB_FRAME_IND;
++
++	/* On frame indication, read available frames */
++	if (PKT_AVAILABLE()) {
++		framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone);
++		if (rxdone || bus->rxskip)
++			intstatus &= ~I_HMB_FRAME_IND;
++		rxlimit -= min(framecnt, rxlimit);
++	}
++
++	/* Keep still-pending events for next scheduling */
++	bus->intstatus = intstatus;
++
++clkwait:
++	brcmf_sdbrcm_clrintr(bus);
++
++	if (data_ok(bus) && bus->ctrl_frame_stat &&
++		(bus->clkstate == CLK_AVAIL)) {
++		int ret, i;
++
++		ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++			SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf,
++			(u32) bus->ctrl_frame_len);
++
++		if (ret < 0) {
++			/* On failure, abort the command and
++				terminate the frame */
++			brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++				  ret);
++			bus->tx_sderrs++;
++
++			brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++			brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++					 SFC_WF_TERM, &err);
++			bus->f1regdata++;
++
++			for (i = 0; i < 3; i++) {
++				u8 hi, lo;
++				hi = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCHI,
++						      &err);
++				lo = brcmf_sdio_regrb(bus->sdiodev,
++						      SBSDIO_FUNC1_WFRAMEBCLO,
++						      &err);
++				bus->f1regdata += 2;
++				if ((hi == 0) && (lo == 0))
++					break;
++			}
++
++		}
++		if (ret == 0)
++			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++		brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
++		bus->ctrl_frame_stat = false;
++		brcmf_sdbrcm_wait_event_wakeup(bus);
++	}
++	/* Send queued frames (limit 1 if rx may still be pending) */
++	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
++		 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
++		 && data_ok(bus)) {
++		framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax);
++		framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
++		txlimit -= framecnt;
++	}
++
++	/* Resched if events or tx frames are pending,
++		 else await next interrupt */
++	/* On failed register access, all bets are off:
++		 no resched or interrupts */
++	if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
++		brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
++		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++		bus->intstatus = 0;
++	} else if (bus->clkstate == CLK_PENDING) {
++		brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n");
++		resched = true;
++	} else if (bus->intstatus || bus->ipend ||
++		(!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)
++		 && data_ok(bus)) || PKT_AVAILABLE()) {
++		resched = true;
++	}
++
++	bus->dpc_sched = resched;
++
++	/* If we're done for now, turn off clock request. */
++	if ((bus->clkstate != CLK_PENDING)
++	    && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++	}
++
++	up(&bus->sdsem);
++
++	return resched;
++}
++
++static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
++{
++	struct list_head *new_hd;
++	unsigned long flags;
++
++	if (in_interrupt())
++		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
++	else
++		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
++	if (new_hd == NULL)
++		return;
++
++	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++	list_add_tail(new_hd, &bus->dpc_tsklst);
++	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++}
++
++static int brcmf_sdbrcm_dpc_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
++	struct list_head *cur_hd, *tmp_hd;
++	unsigned long flags;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++
++		if (list_empty(&bus->dpc_tsklst))
++			if (wait_for_completion_interruptible(&bus->dpc_wait))
++				break;
++
++		spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++		list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
++			spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++
++			if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++				/* after stopping the bus, exit thread */
++				brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
++				bus->dpc_tsk = NULL;
++				spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++				break;
++			}
++
++			if (brcmf_sdbrcm_dpc(bus))
++				brcmf_sdbrcm_adddpctsk(bus);
++
++			spin_lock_irqsave(&bus->dpc_tl_lock, flags);
++			list_del(cur_hd);
++			kfree(cur_hd);
++		}
++		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
++	}
++	return 0;
++}
++
++static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
++{
++	int ret = -EBADE;
++	uint datalen, prec;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	datalen = pkt->len;
++
++	/* Add space for the header */
++	skb_push(pkt, SDPCM_HDRLEN);
++	/* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */
++
++	prec = prio2prec((pkt->priority & PRIOMASK));
++
++	/* Check for existing queue, current flow-control,
++			 pending event, or pending clock */
++	brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq));
++	bus->fcqueued++;
++
++	/* Priority based enq */
++	spin_lock_bh(&bus->txqlock);
++	if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
++		skb_pull(pkt, SDPCM_HDRLEN);
++		brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
++		brcmu_pkt_buf_free_skb(pkt);
++		brcmf_dbg(ERROR, "out of bus->txq !!!\n");
++		ret = -ENOSR;
++	} else {
++		ret = 0;
++	}
++	spin_unlock_bh(&bus->txqlock);
++
++	if (pktq_len(&bus->txq) >= TXHI) {
++		bus->txoff = ON;
++		brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
++	}
++
++#ifdef DEBUG
++	if (pktq_plen(&bus->txq, prec) > qcount[prec])
++		qcount[prec] = pktq_plen(&bus->txq, prec);
++#endif
++	/* Schedule DPC if needed to send queued packet(s) */
++	if (!bus->dpc_sched) {
++		bus->dpc_sched = true;
++		if (bus->dpc_tsk) {
++			brcmf_sdbrcm_adddpctsk(bus);
++			complete(&bus->dpc_wait);
++		}
++	}
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
++		 uint size)
++{
++	int bcmerror = 0;
++	u32 sdaddr;
++	uint dsize;
++
++	/* Determine initial transfer parameters */
++	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
++	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
++		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
++	else
++		dsize = size;
++
++	/* Set the backplane window to include the start address */
++	bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
++	if (bcmerror) {
++		brcmf_dbg(ERROR, "window change failed\n");
++		goto xfer_done;
++	}
++
++	/* Do the transfer(s) */
++	while (size) {
++		brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
++			  write ? "write" : "read", dsize,
++			  sdaddr, address & SBSDIO_SBWINDOW_MASK);
++		bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
++					       sdaddr, data, dsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "membytes transfer failed\n");
++			break;
++		}
++
++		/* Adjust for next transfer (if any) */
++		size -= dsize;
++		if (size) {
++			data += dsize;
++			address += dsize;
++			bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
++								  address);
++			if (bcmerror) {
++				brcmf_dbg(ERROR, "window change failed\n");
++				break;
++			}
++			sdaddr = 0;
++			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
++		}
++	}
++
++xfer_done:
++	/* Return the window to backplane enumeration space for core access */
++	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
++		brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
++			  bus->sdiodev->sbwad);
++
++	return bcmerror;
++}
++
++#ifdef DEBUG
++#define CONSOLE_LINE_MAX	192
++
++static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
++{
++	struct brcmf_console *c = &bus->console;
++	u8 line[CONSOLE_LINE_MAX], ch;
++	u32 n, idx, addr;
++	int rv;
++
++	/* Don't do anything until FWREADY updates console address */
++	if (bus->console_addr == 0)
++		return 0;
++
++	/* Read console log struct */
++	addr = bus->console_addr + offsetof(struct rte_console, log_le);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le,
++				   sizeof(c->log_le));
++	if (rv < 0)
++		return rv;
++
++	/* Allocate console buffer (one time only) */
++	if (c->buf == NULL) {
++		c->bufsize = le32_to_cpu(c->log_le.buf_size);
++		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
++		if (c->buf == NULL)
++			return -ENOMEM;
++	}
++
++	idx = le32_to_cpu(c->log_le.idx);
++
++	/* Protect against corrupt value */
++	if (idx > c->bufsize)
++		return -EBADE;
++
++	/* Skip reading the console buffer if the index pointer
++	 has not moved */
++	if (idx == c->last)
++		return 0;
++
++	/* Read the console buffer */
++	addr = le32_to_cpu(c->log_le.buf);
++	rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize);
++	if (rv < 0)
++		return rv;
++
++	while (c->last != idx) {
++		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
++			if (c->last == idx) {
++				/* This would output a partial line.
++				 * Instead, back up
++				 * the buffer pointer and output this
++				 * line next time around.
++				 */
++				if (c->last >= n)
++					c->last -= n;
++				else
++					c->last = c->bufsize - n;
++				goto break2;
++			}
++			ch = c->buf[c->last];
++			c->last = (c->last + 1) % c->bufsize;
++			if (ch == '\n')
++				break;
++			line[n] = ch;
++		}
++
++		if (n > 0) {
++			if (line[n - 1] == '\r')
++				n--;
++			line[n] = 0;
++			pr_debug("CONSOLE: %s\n", line);
++		}
++	}
++break2:
++
++	return 0;
++}
++#endif				/* DEBUG */
++
++static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
++{
++	int i;
++	int ret;
++
++	bus->ctrl_frame_stat = false;
++	ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
++				    SDIO_FUNC_2, F2SYNC, frame, len);
++
++	if (ret < 0) {
++		/* On failure, abort the command and terminate the frame */
++		brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
++			  ret);
++		bus->tx_sderrs++;
++
++		brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL,
++				 SFC_WF_TERM, NULL);
++		bus->f1regdata++;
++
++		for (i = 0; i < 3; i++) {
++			u8 hi, lo;
++			hi = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCHI, NULL);
++			lo = brcmf_sdio_regrb(bus->sdiodev,
++					      SBSDIO_FUNC1_WFRAMEBCLO, NULL);
++			bus->f1regdata += 2;
++			if (hi == 0 && lo == 0)
++				break;
++		}
++		return ret;
++	}
++
++	bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
++
++	return ret;
++}
++
++static int
++brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	u8 *frame;
++	u16 len;
++	u32 swheader;
++	uint retries = 0;
++	u8 doff = 0;
++	int ret = -1;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Back the pointer to make a room for bus header */
++	frame = msg - SDPCM_HDRLEN;
++	len = (msglen += SDPCM_HDRLEN);
++
++	/* Add alignment padding (optional for ctl frames) */
++	doff = ((unsigned long)frame % BRCMF_SDALIGN);
++	if (doff) {
++		frame -= doff;
++		len += doff;
++		msglen += doff;
++		memset(frame, 0, doff + SDPCM_HDRLEN);
++	}
++	/* precondition: doff < BRCMF_SDALIGN */
++	doff += SDPCM_HDRLEN;
++
++	/* Round send length to next SDIO block */
++	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
++		u16 pad = bus->blocksize - (len % bus->blocksize);
++		if ((pad <= bus->roundup) && (pad < bus->blocksize))
++			len += pad;
++	} else if (len % BRCMF_SDALIGN) {
++		len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
++	}
++
++	/* Satisfy length-alignment requirements */
++	if (len & (ALIGNMENT - 1))
++		len = roundup(len, ALIGNMENT);
++
++	/* precondition: IS_ALIGNED((unsigned long)frame, 2) */
++
++	/* Need to lock here to protect txseq and SDIO tx calls */
++	down(&bus->sdsem);
++
++	bus_wake(bus);
++
++	/* Make sure backplane clock is on */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
++	*(__le16 *) frame = cpu_to_le16((u16) msglen);
++	*(((__le16 *) frame) + 1) = cpu_to_le16(~msglen);
++
++	/* Software tag: channel, sequence number, data offset */
++	swheader =
++	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
++	     SDPCM_CHANNEL_MASK)
++	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
++			     SDPCM_DOFFSET_MASK);
++	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
++	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
++
++	if (!data_ok(bus)) {
++		brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
++			  bus->tx_max, bus->tx_seq);
++		bus->ctrl_frame_stat = true;
++		/* Send from dpc */
++		bus->ctrl_frame_buf = frame;
++		bus->ctrl_frame_len = len;
++
++		brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
++
++		if (!bus->ctrl_frame_stat) {
++			brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
++			ret = 0;
++		} else {
++			brcmf_dbg(INFO, "ctrl_frame_stat == true\n");
++			ret = -1;
++		}
++	}
++
++	if (ret == -1) {
++		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
++				   frame, len, "Tx Frame:\n");
++		brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
++				   BRCMF_HDRS_ON(),
++				   frame, min_t(u16, len, 16), "TxHdr:\n");
++
++		do {
++			ret = brcmf_tx_frame(bus, frame, len);
++		} while (ret < 0 && retries++ < TXRETRIES);
++	}
++
++	if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) {
++		bus->activity = false;
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
++	}
++
++	up(&bus->sdsem);
++
++	if (ret)
++		bus->tx_ctlerrs++;
++	else
++		bus->tx_ctlpkts++;
++
++	return ret ? -EIO : 0;
++}
++
++static int
++brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
++{
++	int timeleft;
++	uint rxlen = 0;
++	bool pending;
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Wait until control frame is available */
++	timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);
++
++	down(&bus->sdsem);
++	rxlen = bus->rxlen;
++	memcpy(msg, bus->rxctl, min(msglen, rxlen));
++	bus->rxlen = 0;
++	up(&bus->sdsem);
++
++	if (rxlen) {
++		brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
++			  rxlen, msglen);
++	} else if (timeleft == 0) {
++		brcmf_dbg(ERROR, "resumed on timeout\n");
++	} else if (pending) {
++		brcmf_dbg(CTL, "cancelled\n");
++		return -ERESTARTSYS;
++	} else {
++		brcmf_dbg(CTL, "resumed for unknown reason?\n");
++	}
++
++	if (rxlen)
++		bus->rx_ctlpkts++;
++	else
++		bus->rx_ctlerrs++;
++
++	return rxlen ? (int)rxlen : -ETIMEDOUT;
++}
++
++static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
++{
++	int bcmerror = 0;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Basic sanity checks */
++	if (bus->sdiodev->bus_if->drvr_up) {
++		bcmerror = -EISCONN;
++		goto err;
++	}
++	if (!len) {
++		bcmerror = -EOVERFLOW;
++		goto err;
++	}
++
++	/* Free the old ones and replace with passed variables */
++	kfree(bus->vars);
++
++	bus->vars = kmalloc(len, GFP_ATOMIC);
++	bus->varsz = bus->vars ? len : 0;
++	if (bus->vars == NULL) {
++		bcmerror = -ENOMEM;
++		goto err;
++	}
++
++	/* Copy the passed variables, which should include the
++		 terminating double-null */
++	memcpy(bus->vars, arg, bus->varsz);
++err:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
++{
++	int bcmerror = 0;
++	u32 varsize;
++	u32 varaddr;
++	u8 *vbuffer;
++	u32 varsizew;
++	__le32 varsizew_le;
++#ifdef DEBUG
++	char *nvram_ularray;
++#endif				/* DEBUG */
++
++	/* Even if there are no vars are to be written, we still
++		 need to set the ramsize. */
++	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
++	varaddr = (bus->ramsize - 4) - varsize;
++
++	if (bus->vars) {
++		vbuffer = kzalloc(varsize, GFP_ATOMIC);
++		if (!vbuffer)
++			return -ENOMEM;
++
++		memcpy(vbuffer, bus->vars, bus->varsz);
++
++		/* Write the vars list */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
++#ifdef DEBUG
++		/* Verify NVRAM bytes */
++		brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
++		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
++		if (!nvram_ularray) {
++			kfree(vbuffer);
++			return -ENOMEM;
++		}
++
++		/* Upload image to verify downloaded contents. */
++		memset(nvram_ularray, 0xaa, varsize);
++
++		/* Read the vars list to temp buffer for comparison */
++		bcmerror =
++		    brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
++				     varsize);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
++				  bcmerror, varsize, varaddr);
++		}
++		/* Compare the org NVRAM with the one read from RAM */
++		if (memcmp(vbuffer, nvram_ularray, varsize))
++			brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
++		else
++			brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
++
++		kfree(nvram_ularray);
++#endif				/* DEBUG */
++
++		kfree(vbuffer);
++	}
++
++	/* adjust to the user specified RAM */
++	brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
++	brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
++		  varaddr, varsize);
++	varsize = ((bus->ramsize - 4) - varaddr);
++
++	/*
++	 * Determine the length token:
++	 * Varsize, converted to words, in lower 16-bits, checksum
++	 * in upper 16-bits.
++	 */
++	if (bcmerror) {
++		varsizew = 0;
++		varsizew_le = cpu_to_le32(0);
++	} else {
++		varsizew = varsize / 4;
++		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
++		varsizew_le = cpu_to_le32(varsizew);
++	}
++
++	brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
++		  varsize, varsizew);
++
++	/* Write the length token to the last word */
++	bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
++					 (u8 *)&varsizew_le, 4);
++
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
++{
++	int bcmerror = 0;
++	struct chip_info *ci = bus->ci;
++
++	/* To enter download state, disable ARM and reset SOCRAM.
++	 * To exit download state, simply reset ARM (default is RAM boot).
++	 */
++	if (enter) {
++		bus->alp_only = true;
++
++		ci->coredisable(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM);
++
++		/* Clear the top bit of memory */
++		if (bus->ramsize) {
++			u32 zeros = 0;
++			brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4,
++					 (u8 *)&zeros, 4);
++		}
++	} else {
++		if (!ci->iscoreup(bus->sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
++			brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
++			bcmerror = -EBADE;
++			goto fail;
++		}
++
++		bcmerror = brcmf_sdbrcm_write_vars(bus);
++		if (bcmerror) {
++			brcmf_dbg(ERROR, "no vars written to RAM\n");
++			bcmerror = 0;
++		}
++
++		w_sdreg32(bus, 0xFFFFFFFF,
++			  offsetof(struct sdpcmd_regs, intstatus));
++
++		ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3);
++
++		/* Allow HT Clock now that the ARM is running. */
++		bus->alp_only = false;
++
++		bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD;
++	}
++fail:
++	return bcmerror;
++}
++
++static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus)
++{
++	if (bus->firmware->size < bus->fw_ptr + len)
++		len = bus->firmware->size - bus->fw_ptr;
++
++	memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
++	bus->fw_ptr += len;
++	return len;
++}
++
++static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
++{
++	int offset = 0;
++	uint len;
++	u8 *memblock = NULL, *memptr;
++	int ret;
++
++	brcmf_dbg(INFO, "Enter\n");
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++	if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
++		memptr += (BRCMF_SDALIGN -
++			   ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
++
++	/* Download image */
++	while ((len =
++		brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
++		ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len);
++		if (ret) {
++			brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n",
++				  ret, MEMBLOCK, offset);
++			goto err;
++		}
++
++		offset += MEMBLOCK;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++/*
++ * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
++ * and ending in a NUL.
++ * Removes carriage returns, empty lines, comment lines, and converts
++ * newlines to NULs.
++ * Shortens buffer as needed and pads with NULs.  End of buffer is marked
++ * by two NULs.
++*/
++
++static uint brcmf_process_nvram_vars(char *varbuf, uint len)
++{
++	char *dp;
++	bool findNewline;
++	int column;
++	uint buf_len, n;
++
++	dp = varbuf;
++
++	findNewline = false;
++	column = 0;
++
++	for (n = 0; n < len; n++) {
++		if (varbuf[n] == 0)
++			break;
++		if (varbuf[n] == '\r')
++			continue;
++		if (findNewline && varbuf[n] != '\n')
++			continue;
++		findNewline = false;
++		if (varbuf[n] == '#') {
++			findNewline = true;
++			continue;
++		}
++		if (varbuf[n] == '\n') {
++			if (column == 0)
++				continue;
++			*dp++ = 0;
++			column = 0;
++			continue;
++		}
++		*dp++ = varbuf[n];
++		column++;
++	}
++	buf_len = dp - varbuf;
++
++	while (dp < varbuf + n)
++		*dp++ = 0;
++
++	return buf_len;
++}
++
++static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
++{
++	uint len;
++	char *memblock = NULL;
++	char *bufp;
++	int ret;
++
++	ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
++			       &bus->sdiodev->func[2]->dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
++		return ret;
++	}
++	bus->fw_ptr = 0;
++
++	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
++	if (memblock == NULL) {
++		ret = -ENOMEM;
++		goto err;
++	}
++
++	len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
++
++	if (len > 0 && len < MEMBLOCK) {
++		bufp = (char *)memblock;
++		bufp[len] = 0;
++		len = brcmf_process_nvram_vars(bufp, len);
++		bufp += len;
++		*bufp++ = 0;
++		if (len)
++			ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
++		if (ret)
++			brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
++	} else {
++		brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
++		ret = -EIO;
++	}
++
++err:
++	kfree(memblock);
++
++	release_firmware(bus->firmware);
++	bus->fw_ptr = 0;
++
++	return ret;
++}
++
++static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	int bcmerror = -1;
++
++	/* Keep arm in reset */
++	if (brcmf_sdbrcm_download_state(bus, true)) {
++		brcmf_dbg(ERROR, "error placing ARM core in reset\n");
++		goto err;
++	}
++
++	/* External image takes precedence if specified */
++	if (brcmf_sdbrcm_download_code_file(bus)) {
++		brcmf_dbg(ERROR, "dongle image file download failed\n");
++		goto err;
++	}
++
++	/* External nvram takes precedence if specified */
++	if (brcmf_sdbrcm_download_nvram(bus))
++		brcmf_dbg(ERROR, "dongle nvram file download failed\n");
++
++	/* Take arm out of reset */
++	if (brcmf_sdbrcm_download_state(bus, false)) {
++		brcmf_dbg(ERROR, "error getting out of ARM core reset\n");
++		goto err;
++	}
++
++	bcmerror = 0;
++
++err:
++	return bcmerror;
++}
++
++static bool
++brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
++{
++	bool ret;
++
++	/* Download the firmware */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++
++	ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
++
++	brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
++
++	return ret;
++}
++
++static int brcmf_sdbrcm_bus_init(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	struct brcmf_sdio *bus = sdiodev->bus;
++	unsigned long timeout;
++	u8 ready, enable;
++	int err, ret = 0;
++	u8 saveclk;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* try to download image and nvram to the dongle */
++	if (bus_if->state == BRCMF_BUS_DOWN) {
++		if (!(brcmf_sdbrcm_download_firmware(bus)))
++			return -1;
++	}
++
++	if (!bus->sdiodev->bus_if->drvr)
++		return 0;
++
++	/* Start the watchdog timer */
++	bus->tickcnt = 0;
++	brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++
++	down(&bus->sdsem);
++
++	/* Make sure backplane clock is on, needed to generate F2 interrupt */
++	brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++	if (bus->clkstate != CLK_AVAIL)
++		goto exit;
++
++	/* Force clocks on backplane to be sure F2 interrupt propagates */
++	saveclk = brcmf_sdio_regrb(bus->sdiodev,
++				   SBSDIO_FUNC1_CHIPCLKCSR, &err);
++	if (!err) {
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++				 (saveclk | SBSDIO_FORCE_HT), &err);
++	}
++	if (err) {
++		brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err);
++		goto exit;
++	}
++
++	/* Enable function 2 (frame transfers) */
++	w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT,
++		  offsetof(struct sdpcmd_regs, tosbmailboxdata));
++	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
++
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++
++	timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY);
++	ready = 0;
++	while (enable != ready) {
++		ready = brcmf_sdio_regrb(bus->sdiodev,
++					 SDIO_CCCR_IORx, NULL);
++		if (time_after(jiffies, timeout))
++			break;
++		else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50))
++			/* prevent busy waiting if it takes too long */
++			msleep_interruptible(20);
++	}
++
++	brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready);
++
++	/* If F2 successfully enabled, set core and enable interrupts */
++	if (ready == enable) {
++		/* Set up the interrupt mask and enable interrupts */
++		bus->hostintmask = HOSTINTMASK;
++		w_sdreg32(bus, bus->hostintmask,
++			  offsetof(struct sdpcmd_regs, hostintmask));
++
++		brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err);
++	} else {
++		/* Disable F2 again */
++		enable = SDIO_FUNC_ENABLE_1;
++		brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL);
++		ret = -ENODEV;
++	}
++
++	/* Restore previous clock setting */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
++
++	if (ret == 0) {
++		ret = brcmf_sdio_intr_register(bus->sdiodev);
++		if (ret != 0)
++			brcmf_dbg(ERROR, "intr register failed:%d\n", ret);
++	}
++
++	/* If we didn't come up, turn off backplane clock */
++	if (bus_if->state != BRCMF_BUS_DATA)
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++
++exit:
++	up(&bus->sdsem);
++
++	return ret;
++}
++
++void brcmf_sdbrcm_isr(void *arg)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *) arg;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (!bus) {
++		brcmf_dbg(ERROR, "bus is null pointer, exiting\n");
++		return;
++	}
++
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
++		brcmf_dbg(ERROR, "bus is down. we have nothing to do\n");
++		return;
++	}
++	/* Count the interrupt call */
++	bus->intrcount++;
++	bus->ipend = true;
++
++	/* Shouldn't get this interrupt if we're sleeping? */
++	if (bus->sleeping) {
++		brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n");
++		return;
++	}
++
++	/* Disable additional interrupts (is this needed now)? */
++	if (!bus->intr)
++		brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
++
++#ifndef CONFIG_BRCMFMAC_SDIO_OOB
++	while (brcmf_sdbrcm_dpc(bus))
++		;
++#else
++	bus->dpc_sched = true;
++	if (bus->dpc_tsk) {
++		brcmf_sdbrcm_adddpctsk(bus);
++		complete(&bus->dpc_wait);
++	}
++#endif
++}
++
++static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
++{
++#ifdef DEBUG
++	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
++#endif	/* DEBUG */
++
++	brcmf_dbg(TIMER, "Enter\n");
++
++	/* Ignore the timer if simulating bus down */
++	if (bus->sleeping)
++		return false;
++
++	down(&bus->sdsem);
++
++	/* Poll period: check device if appropriate. */
++	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
++		u32 intstatus = 0;
++
++		/* Reset poll tick */
++		bus->polltick = 0;
++
++		/* Check device if no interrupts */
++		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
++
++			if (!bus->dpc_sched) {
++				u8 devpend;
++				devpend = brcmf_sdio_regrb(bus->sdiodev,
++							   SDIO_CCCR_INTx,
++							   NULL);
++				intstatus =
++				    devpend & (INTR_STATUS_FUNC1 |
++					       INTR_STATUS_FUNC2);
++			}
++
++			/* If there is something, make like the ISR and
++				 schedule the DPC */
++			if (intstatus) {
++				bus->pollcnt++;
++				bus->ipend = true;
++
++				bus->dpc_sched = true;
++				if (bus->dpc_tsk) {
++					brcmf_sdbrcm_adddpctsk(bus);
++					complete(&bus->dpc_wait);
++				}
++			}
++		}
++
++		/* Update interrupt tracking */
++		bus->lastintrs = bus->intrcount;
++	}
++#ifdef DEBUG
++	/* Poll for console output periodically */
++	if (bus_if->state == BRCMF_BUS_DATA &&
++	    bus->console_interval != 0) {
++		bus->console.count += BRCMF_WD_POLL_MS;
++		if (bus->console.count >= bus->console_interval) {
++			bus->console.count -= bus->console_interval;
++			/* Make sure backplane clock is on */
++			brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++			if (brcmf_sdbrcm_readconsole(bus) < 0)
++				/* stop on error */
++				bus->console_interval = 0;
++		}
++	}
++#endif				/* DEBUG */
++
++	/* On idle timeout clear activity flag and/or turn off clock */
++	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
++		if (++bus->idlecount >= bus->idletime) {
++			bus->idlecount = 0;
++			if (bus->activity) {
++				bus->activity = false;
++				brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
++			} else {
++				brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++			}
++		}
++	}
++
++	up(&bus->sdsem);
++
++	return bus->ipend;
++}
++
++static bool brcmf_sdbrcm_chipmatch(u16 chipid)
++{
++	if (chipid == BCM4329_CHIP_ID)
++		return true;
++	if (chipid == BCM4330_CHIP_ID)
++		return true;
++	return false;
++}
++
++static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(bus->rxbuf);
++	bus->rxctl = bus->rxbuf = NULL;
++	bus->rxlen = 0;
++
++	kfree(bus->databuf);
++	bus->databuf = NULL;
++}
++
++static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->sdiodev->bus_if->maxctl) {
++		bus->rxblen =
++		    roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
++			    ALIGNMENT) + BRCMF_SDALIGN;
++		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
++		if (!(bus->rxbuf))
++			goto fail;
++	}
++
++	/* Allocate buffer to receive glomed packet */
++	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
++	if (!(bus->databuf)) {
++		/* release rxbuf which was already located as above */
++		if (!bus->rxblen)
++			kfree(bus->rxbuf);
++		goto fail;
++	}
++
++	/* Align the buffer */
++	if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
++		bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
++			       ((unsigned long)bus->databuf % BRCMF_SDALIGN));
++	else
++		bus->dataptr = bus->databuf;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool
++brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
++{
++	u8 clkctl = 0;
++	int err = 0;
++	int reg_addr;
++	u32 reg_val;
++	u8 idx;
++
++	bus->alp_only = true;
++
++	pr_debug("F1 signature read @0x18000000=0x%4x\n",
++		 brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
++
++	/*
++	 * Force PLL off until brcmf_sdio_chip_attach()
++	 * programs PLL control regs
++	 */
++
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
++			 BRCMF_INIT_CLKCTL1, &err);
++	if (!err)
++		clkctl = brcmf_sdio_regrb(bus->sdiodev,
++					  SBSDIO_FUNC1_CHIPCLKCSR, &err);
++
++	if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
++			  err, BRCMF_INIT_CLKCTL1, clkctl);
++		goto fail;
++	}
++
++	if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) {
++		brcmf_dbg(ERROR, "brcmf_sdio_chip_attach failed!\n");
++		goto fail;
++	}
++
++	if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
++		brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip);
++		goto fail;
++	}
++
++	brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci,
++					  SDIO_DRIVE_STRENGTH);
++
++	/* Get info on the SOCRAM cores... */
++	bus->ramsize = bus->ci->ramsize;
++	if (!(bus->ramsize)) {
++		brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n");
++		goto fail;
++	}
++
++	/* Set core control so an SDIO reset does a backplane reset */
++	idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
++	reg_addr = bus->ci->c_inf[idx].base +
++		   offsetof(struct sdpcmd_regs, corecontrol);
++	reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
++	brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);
++
++	brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
++
++	/* Locate an appropriately-aligned portion of hdrbuf */
++	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
++				    BRCMF_SDALIGN);
++
++	/* Set the poll and/or interrupt flags */
++	bus->intr = true;
++	bus->poll = false;
++	if (bus->poll)
++		bus->pollrate = 1;
++
++	return true;
++
++fail:
++	return false;
++}
++
++static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* Disable F2 to clear any intermediate frame state on the dongle */
++	brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
++			 SDIO_FUNC_ENABLE_1, NULL);
++
++	bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
++	bus->sleeping = false;
++	bus->rxflow = false;
++
++	/* Done with backplane-dependent accesses, can drop clock... */
++	brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
++
++	/* ...and initialize clock/power states */
++	bus->clkstate = CLK_SDONLY;
++	bus->idletime = BRCMF_IDLE_INTERVAL;
++	bus->idleclock = BRCMF_IDLE_ACTIVE;
++
++	/* Query the F2 block size, set roundup accordingly */
++	bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
++	bus->roundup = min(max_roundup, bus->blocksize);
++
++	/* bus module does not support packet chaining */
++	bus->use_rxchain = false;
++	bus->sd_rxchain = false;
++
++	return true;
++}
++
++static int
++brcmf_sdbrcm_watchdog_thread(void *data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	allow_signal(SIGTERM);
++	/* Run until signal received */
++	while (1) {
++		if (kthread_should_stop())
++			break;
++		if (!wait_for_completion_interruptible(&bus->watchdog_wait)) {
++			brcmf_sdbrcm_bus_watchdog(bus);
++			/* Count the tick for reference */
++			bus->tickcnt++;
++		} else
++			break;
++	}
++	return 0;
++}
++
++static void
++brcmf_sdbrcm_watchdog(unsigned long data)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
++
++	if (bus->watchdog_tsk) {
++		complete(&bus->watchdog_wait);
++		/* Reschedule the watchdog */
++		if (bus->wd_timer_valid)
++			mod_timer(&bus->timer,
++				  jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++	}
++}
++
++static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus->ci) {
++		brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
++		brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
++		brcmf_sdio_chip_detach(&bus->ci);
++		if (bus->vars && bus->varsz)
++			kfree(bus->vars);
++		bus->vars = NULL;
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++/* Detach and free everything */
++static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus) {
++		/* De-register interrupt handler */
++		brcmf_sdio_intr_unregister(bus->sdiodev);
++
++		if (bus->sdiodev->bus_if->drvr) {
++			brcmf_detach(bus->sdiodev->dev);
++			brcmf_sdbrcm_release_dongle(bus);
++		}
++
++		brcmf_sdbrcm_release_malloc(bus);
++
++		kfree(bus);
++	}
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
++{
++	int ret;
++	struct brcmf_sdio *bus;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* We make an assumption about address window mappings:
++	 * regsva == SI_ENUM_BASE*/
++
++	/* Allocate private bus interface state */
++	bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC);
++	if (!bus)
++		goto fail;
++
++	bus->sdiodev = sdiodev;
++	sdiodev->bus = bus;
++	skb_queue_head_init(&bus->glom);
++	bus->txbound = BRCMF_TXBOUND;
++	bus->rxbound = BRCMF_RXBOUND;
++	bus->txminmax = BRCMF_TXMINMAX;
++	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
++	bus->usebufpool = false;	/* Use bufpool if allocated,
++					 else use locally malloced rxbuf */
++
++	/* attempt to attach to the dongle */
++	if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n");
++		goto fail;
++	}
++
++	spin_lock_init(&bus->txqlock);
++	init_waitqueue_head(&bus->ctrl_wait);
++	init_waitqueue_head(&bus->dcmd_resp_wait);
++
++	/* Set up the watchdog timer */
++	init_timer(&bus->timer);
++	bus->timer.data = (unsigned long)bus;
++	bus->timer.function = brcmf_sdbrcm_watchdog;
++
++	/* Initialize thread based operation and lock */
++	sema_init(&bus->sdsem, 1);
++
++	/* Initialize watchdog thread */
++	init_completion(&bus->watchdog_wait);
++	bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
++					bus, "brcmf_watchdog");
++	if (IS_ERR(bus->watchdog_tsk)) {
++		pr_warn("brcmf_watchdog thread failed to start\n");
++		bus->watchdog_tsk = NULL;
++	}
++	/* Initialize DPC thread */
++	init_completion(&bus->dpc_wait);
++	INIT_LIST_HEAD(&bus->dpc_tsklst);
++	spin_lock_init(&bus->dpc_tl_lock);
++	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
++				   bus, "brcmf_dpc");
++	if (IS_ERR(bus->dpc_tsk)) {
++		pr_warn("brcmf_dpc thread failed to start\n");
++		bus->dpc_tsk = NULL;
++	}
++
++	/* Assign bus interface call back */
++	bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
++	bus->sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init;
++	bus->sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata;
++	bus->sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl;
++	bus->sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl;
++	/* Attach to the brcmf/OS/network interface */
++	ret = brcmf_attach(SDPCM_RESERVE, bus->sdiodev->dev);
++	if (ret != 0) {
++		brcmf_dbg(ERROR, "brcmf_attach failed\n");
++		goto fail;
++	}
++
++	/* Allocate buffers */
++	if (!(brcmf_sdbrcm_probe_malloc(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n");
++		goto fail;
++	}
++
++	if (!(brcmf_sdbrcm_probe_init(bus))) {
++		brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n");
++		goto fail;
++	}
++
++	brcmf_dbg(INFO, "completed!!\n");
++
++	/* if firmware path present try to download and bring up bus */
++	ret = brcmf_bus_start(bus->sdiodev->dev);
++	if (ret != 0) {
++		if (ret == -ENOLINK) {
++			brcmf_dbg(ERROR, "dongle is not responding\n");
++			goto fail;
++		}
++	}
++
++	return bus;
++
++fail:
++	brcmf_sdbrcm_release(bus);
++	return NULL;
++}
++
++void brcmf_sdbrcm_disconnect(void *ptr)
++{
++	struct brcmf_sdio *bus = (struct brcmf_sdio *)ptr;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	if (bus)
++		brcmf_sdbrcm_release(bus);
++
++	brcmf_dbg(TRACE, "Disconnected\n");
++}
++
++void
++brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
++{
++	/* Totally stop the timer */
++	if (!wdtick && bus->wd_timer_valid) {
++		del_timer_sync(&bus->timer);
++		bus->wd_timer_valid = false;
++		bus->save_ms = wdtick;
++		return;
++	}
++
++	/* don't start the wd until fw is loaded */
++	if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN)
++		return;
++
++	if (wdtick) {
++		if (bus->save_ms != BRCMF_WD_POLL_MS) {
++			if (bus->wd_timer_valid)
++				/* Stop timer and restart at new value */
++				del_timer_sync(&bus->timer);
++
++			/* Create timer again when watchdog period is
++			   dynamically changed or in the first instance
++			 */
++			bus->timer.expires =
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000;
++			add_timer(&bus->timer);
++
++		} else {
++			/* Re arm the timer, at last watchdog period */
++			mod_timer(&bus->timer,
++				jiffies + BRCMF_WD_POLL_MS * HZ / 1000);
++		}
++
++		bus->wd_timer_valid = true;
++		bus->save_ms = wdtick;
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+new file mode 100644
+index 0000000..13f630c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+@@ -0,0 +1,622 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++/* ***** SDIO interface chip backplane handle functions ***** */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/types.h>
++#include <linux/netdevice.h>
++#include <linux/printk.h>
++#include <linux/mmc/card.h>
++#include <linux/ssb/ssb_regs.h>
++#include <linux/bcma/bcma.h>
++
++#include <chipcommon.h>
++#include <brcm_hw_ids.h>
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++#include <soc.h>
++#include "dhd_dbg.h"
++#include "sdio_host.h"
++#include "sdio_chip.h"
++
++/* chip core base & ramsize */
++/* bcm4329 */
++/* SDIO device core, ID 0x829 */
++#define BCM4329_CORE_BUS_BASE		0x18011000
++/* internal memory core, ID 0x80e */
++#define BCM4329_CORE_SOCRAM_BASE	0x18003000
++/* ARM Cortex M3 core, ID 0x82a */
++#define BCM4329_CORE_ARM_BASE		0x18002000
++#define BCM4329_RAMSIZE			0x48000
++
++#define	SBCOREREV(sbidh) \
++	((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
++	  ((sbidh) & SSB_IDHIGH_RCLO))
++
++/* SOC Interconnect types (aka chip types) */
++#define SOCI_SB		0
++#define SOCI_AI		1
++
++/* EROM CompIdentB */
++#define CIB_REV_MASK		0xff000000
++#define CIB_REV_SHIFT		24
++
++#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
++/* SDIO Pad drive strength to select value mappings */
++struct sdiod_drive_str {
++	u8 strength;	/* Pad Drive Strength in mA */
++	u8 sel;		/* Chip-specific select value */
++};
++/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
++static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
++	{32, 0x6},
++	{26, 0x7},
++	{22, 0x4},
++	{16, 0x5},
++	{12, 0x2},
++	{8, 0x3},
++	{4, 0x0},
++	{0, 0x1}
++};
++
++u8
++brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
++		if (coreid == ci->c_inf[idx].id)
++			return idx;
++
++	return BRCMF_MAX_CORENUM;
++}
++
++static u32
++brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbidhigh),
++				   NULL);
++	return SBCOREREV(regdata);
++}
++
++static u32
++brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
++		      struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
++}
++
++static bool
++brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
++		    SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
++	return (SSB_TMSLOW_CLOCK == regdata);
++}
++
++static bool
++brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
++		       struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++	bool ret;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
++
++	return ret;
++}
++
++static void
++brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u32 regdata, base;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++	base = ci->c_inf[idx].base;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if (regdata & SSB_TMSLOW_RESET)
++		return;
++
++	regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
++	if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
++		/*
++		 * set target reject and spin until busy is clear
++		 * (preserve core-specific bits)
++		 */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata | SSB_TMSLOW_REJECT, NULL);
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(1);
++		SPINWAIT((brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL) &
++			SSB_TMSHIGH_BUSY), 100000);
++
++		regdata = brcmf_sdio_regrl(sdiodev,
++					   CORE_SB(base, sbtmstatehigh),
++					   NULL);
++		if (regdata & SSB_TMSHIGH_BUSY)
++			brcmf_dbg(ERROR, "core state still busy\n");
++
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata |= SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			udelay(1);
++			SPINWAIT((brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL) &
++				SSB_IMSTATE_BUSY), 100000);
++		}
++
++		/* set reset and reject while enabling the clocks */
++		regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
++			  SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
++		brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++				 regdata, NULL);
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow),
++					   NULL);
++		udelay(10);
++
++		/* clear the initiator reject bit */
++		regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow),
++					   NULL);
++		if (regdata & SSB_IDLOW_INITIATOR) {
++			regdata = brcmf_sdio_regrl(sdiodev,
++						   CORE_SB(base, sbimstate),
++						   NULL);
++			regdata &= ~SSB_IMSTATE_REJECT;
++			brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate),
++					 regdata, NULL);
++		}
++	}
++
++	/* leave reset and reject asserted */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
++			 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
++			  struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* if core is already in reset, just return */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++				   NULL);
++	if ((regdata & BCMA_RESET_CTL_RESET) != 0)
++		return;
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(10);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 BCMA_RESET_CTL_RESET, NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u32 regdata;
++	u8 idx;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/*
++	 * Must do the disable sequence first to work for
++	 * arbitrary current core state.
++	 */
++	brcmf_sdio_sb_coredisable(sdiodev, ci, coreid);
++
++	/*
++	 * Now do the initialization sequence.
++	 * set reset while enabling the clock and
++	 * forcing them on throughout the core
++	 */
++	brcmf_sdio_regwl(sdiodev,
++			 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
++			 NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* clear any serror */
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				   NULL);
++	if (regdata & SSB_TMSHIGH_SERR)
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
++				 0, NULL);
++
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbimstate),
++				   NULL);
++	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
++		brcmf_sdio_regwl(sdiodev,
++				 CORE_SB(ci->c_inf[idx].base, sbimstate),
++				 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
++				 NULL);
++
++	/* clear reset and allow it to propagate throughout the core */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++
++	/* leave clock enabled */
++	brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++			 SSB_TMSLOW_CLOCK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
++				   NULL);
++	udelay(1);
++}
++
++static void
++brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid)
++{
++	u8 idx;
++	u32 regdata;
++
++	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
++
++	/* must disable first to work for arbitrary current core state */
++	brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
++
++	/* now do initialization sequence */
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
++			 0, NULL);
++	udelay(1);
++
++	brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++			 BCMA_IOCTL_CLK, NULL);
++	regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
++				   NULL);
++	udelay(1);
++}
++
++static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
++				       struct chip_info *ci, u32 regs)
++{
++	u32 regdata;
++
++	/*
++	 * Get CC core rev
++	 * Chipid is assume to be at offset 0 from regs arg
++	 * For different chiptypes or old sdio hosts w/o chipcommon,
++	 * other ways of recognition should be added here.
++	 */
++	ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
++	ci->c_inf[0].base = regs;
++	regdata = brcmf_sdio_regrl(sdiodev,
++				   CORE_CC_REG(ci->c_inf[0].base, chipid),
++				   NULL);
++	ci->chip = regdata & CID_ID_MASK;
++	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
++	ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
++
++	brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
++
++	/* Address of cores for new chips should be added here */
++	switch (ci->chip) {
++	case BCM4329_CHIP_ID:
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
++		ci->ramsize = BCM4329_RAMSIZE;
++		break;
++	case BCM4330_CHIP_ID:
++		ci->c_inf[0].wrapbase = 0x18100000;
++		ci->c_inf[0].cib = 0x27004211;
++		ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
++		ci->c_inf[1].base = 0x18002000;
++		ci->c_inf[1].wrapbase = 0x18102000;
++		ci->c_inf[1].cib = 0x07004211;
++		ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
++		ci->c_inf[2].base = 0x18004000;
++		ci->c_inf[2].wrapbase = 0x18104000;
++		ci->c_inf[2].cib = 0x0d080401;
++		ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
++		ci->c_inf[3].base = 0x18003000;
++		ci->c_inf[3].wrapbase = 0x18103000;
++		ci->c_inf[3].cib = 0x03004211;
++		ci->ramsize = 0x48000;
++		break;
++	default:
++		brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
++		return -ENODEV;
++	}
++
++	switch (ci->socitype) {
++	case SOCI_SB:
++		ci->iscoreup = brcmf_sdio_sb_iscoreup;
++		ci->corerev = brcmf_sdio_sb_corerev;
++		ci->coredisable = brcmf_sdio_sb_coredisable;
++		ci->resetcore = brcmf_sdio_sb_resetcore;
++		break;
++	case SOCI_AI:
++		ci->iscoreup = brcmf_sdio_ai_iscoreup;
++		ci->corerev = brcmf_sdio_ai_corerev;
++		ci->coredisable = brcmf_sdio_ai_coredisable;
++		ci->resetcore = brcmf_sdio_ai_resetcore;
++		break;
++	default:
++		brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype);
++		return -ENODEV;
++	}
++
++	return 0;
++}
++
++static int
++brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
++{
++	int err = 0;
++	u8 clkval, clkset;
++
++	/* Try forcing SDIO core to do ALPAvail request only */
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	if (err) {
++		brcmf_dbg(ERROR, "error writing for HT off\n");
++		return err;
++	}
++
++	/* If register supported, wait for ALPAvail and then force ALP */
++	/* This may take up to 15 milliseconds */
++	clkval = brcmf_sdio_regrb(sdiodev,
++				  SBSDIO_FUNC1_CHIPCLKCSR, NULL);
++
++	if ((clkval & ~SBSDIO_AVBITS) != clkset) {
++		brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
++			  clkset, clkval);
++		return -EACCES;
++	}
++
++	SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev,
++					     SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
++			!SBSDIO_ALPAV(clkval)),
++			PMU_MAX_TRANSITION_DLY);
++	if (!SBSDIO_ALPAV(clkval)) {
++		brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
++			  clkval);
++		return -EBUSY;
++	}
++
++	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
++	udelay(65);
++
++	/* Also, disable the extra SDIO pull-ups */
++	brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
++
++	return 0;
++}
++
++static void
++brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
++			     struct chip_info *ci)
++{
++	u32 base = ci->c_inf[0].base;
++
++	/* get chipcommon rev */
++	ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
++
++	/* get chipcommon capabilites */
++	ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev,
++					     CORE_CC_REG(base, capabilities),
++					     NULL);
++
++	/* get pmu caps & rev */
++	if (ci->c_inf[0].caps & CC_CAP_PMU) {
++		ci->pmucaps =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, pmucapabilities),
++					 NULL);
++		ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
++	}
++
++	ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
++
++	brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
++		  ci->c_inf[0].rev, ci->pmurev,
++		  ci->c_inf[1].rev, ci->c_inf[1].id);
++
++	/*
++	 * Make sure any on-chip ARM is off (in case strapping is wrong),
++	 * or downloaded code was already running.
++	 */
++	ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3);
++}
++
++int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++			   struct chip_info **ci_ptr, u32 regs)
++{
++	int ret;
++	struct chip_info *ci;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	/* alloc chip_info_t */
++	ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
++	if (!ci)
++		return -ENOMEM;
++
++	ret = brcmf_sdio_chip_buscoreprep(sdiodev);
++	if (ret != 0)
++		goto err;
++
++	ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
++	if (ret != 0)
++		goto err;
++
++	brcmf_sdio_chip_buscoresetup(sdiodev, ci);
++
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
++			 0, NULL);
++	brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
++			 0, NULL);
++
++	*ci_ptr = ci;
++	return 0;
++
++err:
++	kfree(ci);
++	return ret;
++}
++
++void
++brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
++{
++	brcmf_dbg(TRACE, "Enter\n");
++
++	kfree(*ci_ptr);
++	*ci_ptr = NULL;
++}
++
++static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
++{
++	const char *fmt;
++
++	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
++	snprintf(buf, len, fmt, chipid);
++	return buf;
++}
++
++void
++brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info *ci, u32 drivestrength)
++{
++	struct sdiod_drive_str *str_tab = NULL;
++	u32 str_mask = 0;
++	u32 str_shift = 0;
++	char chn[8];
++	u32 base = ci->c_inf[0].base;
++
++	if (!(ci->c_inf[0].caps & CC_CAP_PMU))
++		return;
++
++	switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
++	case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
++		str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8;
++		str_mask = 0x00003800;
++		str_shift = 11;
++		break;
++	default:
++		brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
++			  brcmf_sdio_chip_name(ci->chip, chn, 8),
++			  ci->chiprev, ci->pmurev);
++		break;
++	}
++
++	if (str_tab != NULL) {
++		u32 drivestrength_sel = 0;
++		u32 cc_data_temp;
++		int i;
++
++		for (i = 0; str_tab[i].strength != 0; i++) {
++			if (drivestrength >= str_tab[i].strength) {
++				drivestrength_sel = str_tab[i].sel;
++				break;
++			}
++		}
++
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 1, NULL);
++		cc_data_temp =
++			brcmf_sdio_regrl(sdiodev,
++					 CORE_CC_REG(base, chipcontrol_addr),
++					 NULL);
++		cc_data_temp &= ~str_mask;
++		drivestrength_sel <<= str_shift;
++		cc_data_temp |= drivestrength_sel;
++		brcmf_sdio_regwl(sdiodev, CORE_CC_REG(base, chipcontrol_addr),
++				 cc_data_temp, NULL);
++
++		brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
++			  drivestrength, cc_data_temp);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+new file mode 100644
+index 0000000..ce974d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+@@ -0,0 +1,136 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCMFMAC_SDIO_CHIP_H_
++#define _BRCMFMAC_SDIO_CHIP_H_
++
++/*
++ * Core reg address translation.
++ * Both macro's returns a 32 bits byte address on the backplane bus.
++ */
++#define CORE_CC_REG(base, field) \
++		(base + offsetof(struct chipcregs, field))
++#define CORE_BUS_REG(base, field) \
++		(base + offsetof(struct sdpcmd_regs, field))
++#define CORE_SB(base, field) \
++		(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
++
++/* SDIO function 1 register CHIPCLKCSR */
++/* Force ALP request to backplane */
++#define SBSDIO_FORCE_ALP		0x01
++/* Force HT request to backplane */
++#define SBSDIO_FORCE_HT			0x02
++/* Force ILP request to backplane */
++#define SBSDIO_FORCE_ILP		0x04
++/* Make ALP ready (power up xtal) */
++#define SBSDIO_ALP_AVAIL_REQ		0x08
++/* Make HT ready (power up PLL) */
++#define SBSDIO_HT_AVAIL_REQ		0x10
++/* Squelch clock requests from HW */
++#define SBSDIO_FORCE_HW_CLKREQ_OFF	0x20
++/* Status: ALP is ready */
++#define SBSDIO_ALP_AVAIL		0x40
++/* Status: HT is ready */
++#define SBSDIO_HT_AVAIL			0x80
++#define SBSDIO_AVBITS		(SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
++#define SBSDIO_ALPAV(regval)	((regval) & SBSDIO_AVBITS)
++#define SBSDIO_HTAV(regval)	(((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
++#define SBSDIO_ALPONLY(regval)	(SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
++#define SBSDIO_CLKAV(regval, alponly) \
++	(SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
++
++#define BRCMF_MAX_CORENUM	6
++
++struct chip_core_info {
++	u16 id;
++	u16 rev;
++	u32 base;
++	u32 wrapbase;
++	u32 caps;
++	u32 cib;
++};
++
++struct chip_info {
++	u32 chip;
++	u32 chiprev;
++	u32 socitype;
++	/* core info */
++	/* always put chipcommon core at 0, bus core at 1 */
++	struct chip_core_info c_inf[BRCMF_MAX_CORENUM];
++	u32 pmurev;
++	u32 pmucaps;
++	u32 ramsize;
++
++	bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci,
++			 u16 coreid);
++	void (*coredisable)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++	void (*resetcore)(struct brcmf_sdio_dev *sdiodev,
++			struct chip_info *ci, u16 coreid);
++};
++
++struct sbconfig {
++	u32 PAD[2];
++	u32 sbipsflag;	/* initiator port ocp slave flag */
++	u32 PAD[3];
++	u32 sbtpsflag;	/* target port ocp slave flag */
++	u32 PAD[11];
++	u32 sbtmerrloga;	/* (sonics >= 2.3) */
++	u32 PAD;
++	u32 sbtmerrlog;	/* (sonics >= 2.3) */
++	u32 PAD[3];
++	u32 sbadmatch3;	/* address match3 */
++	u32 PAD;
++	u32 sbadmatch2;	/* address match2 */
++	u32 PAD;
++	u32 sbadmatch1;	/* address match1 */
++	u32 PAD[7];
++	u32 sbimstate;	/* initiator agent state */
++	u32 sbintvec;	/* interrupt mask */
++	u32 sbtmstatelow;	/* target state */
++	u32 sbtmstatehigh;	/* target state */
++	u32 sbbwa0;		/* bandwidth allocation table0 */
++	u32 PAD;
++	u32 sbimconfiglow;	/* initiator configuration */
++	u32 sbimconfighigh;	/* initiator configuration */
++	u32 sbadmatch0;	/* address match0 */
++	u32 PAD;
++	u32 sbtmconfiglow;	/* target configuration */
++	u32 sbtmconfighigh;	/* target configuration */
++	u32 sbbconfig;	/* broadcast configuration */
++	u32 PAD;
++	u32 sbbstate;	/* broadcast state */
++	u32 PAD[3];
++	u32 sbactcnfg;	/* activate configuration */
++	u32 PAD[3];
++	u32 sbflagst;	/* current sbflags */
++	u32 PAD[3];
++	u32 sbidlow;		/* identification */
++	u32 sbidhigh;	/* identification */
++};
++
++extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
++				  struct chip_info **ci_ptr, u32 regs);
++extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr);
++extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
++					      struct chip_info *ci,
++					      u32 drivestrength);
++extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid);
++
++
++#endif		/* _BRCMFMAC_SDIO_CHIP_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+new file mode 100644
+index 0000000..29bf78d2
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+@@ -0,0 +1,272 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SDH_H_
++#define	_BRCM_SDH_H_
++
++#include <linux/skbuff.h>
++
++#define SDIO_FUNC_0		0
++#define SDIO_FUNC_1		1
++#define SDIO_FUNC_2		2
++
++#define SDIOD_FBR_SIZE		0x100
++
++/* io_en */
++#define SDIO_FUNC_ENABLE_1	0x02
++#define SDIO_FUNC_ENABLE_2	0x04
++
++/* io_rdys */
++#define SDIO_FUNC_READY_1	0x02
++#define SDIO_FUNC_READY_2	0x04
++
++/* intr_status */
++#define INTR_STATUS_FUNC1	0x2
++#define INTR_STATUS_FUNC2	0x4
++
++/* Maximum number of I/O funcs */
++#define SDIOD_MAX_IOFUNCS	7
++
++/* mask of register map */
++#define REG_F0_REG_MASK		0x7FF
++#define REG_F1_MISC_MASK	0x1FFFF
++
++/* as of sdiod rev 0, supports 3 functions */
++#define SBSDIO_NUM_FUNCTION		3
++
++/* function 0 vendor specific CCCR registers */
++#define SDIO_CCCR_BRCM_SEPINT		0xf2
++
++#define  SDIO_SEPINT_MASK		0x01
++#define  SDIO_SEPINT_OE			0x02
++#define  SDIO_SEPINT_ACT_HI		0x04
++
++/* function 1 miscellaneous registers */
++
++/* sprom command and status */
++#define SBSDIO_SPROM_CS			0x10000
++/* sprom info register */
++#define SBSDIO_SPROM_INFO		0x10001
++/* sprom indirect access data byte 0 */
++#define SBSDIO_SPROM_DATA_LOW		0x10002
++/* sprom indirect access data byte 1 */
++#define SBSDIO_SPROM_DATA_HIGH		0x10003
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_LOW		0x10004
++/* sprom indirect access addr byte 0 */
++#define SBSDIO_SPROM_ADDR_HIGH		0x10005
++/* xtal_pu (gpio) output */
++#define SBSDIO_CHIP_CTRL_DATA		0x10006
++/* xtal_pu (gpio) enable */
++#define SBSDIO_CHIP_CTRL_EN		0x10007
++/* rev < 7, watermark for sdio device */
++#define SBSDIO_WATERMARK		0x10008
++/* control busy signal generation */
++#define SBSDIO_DEVICE_CTL		0x10009
++
++/* SB Address Window Low (b15) */
++#define SBSDIO_FUNC1_SBADDRLOW		0x1000A
++/* SB Address Window Mid (b23:b16) */
++#define SBSDIO_FUNC1_SBADDRMID		0x1000B
++/* SB Address Window High (b31:b24)    */
++#define SBSDIO_FUNC1_SBADDRHIGH		0x1000C
++/* Frame Control (frame term/abort) */
++#define SBSDIO_FUNC1_FRAMECTRL		0x1000D
++/* ChipClockCSR (ALP/HT ctl/status) */
++#define SBSDIO_FUNC1_CHIPCLKCSR		0x1000E
++/* SdioPullUp (on cmd, d0-d2) */
++#define SBSDIO_FUNC1_SDIOPULLUP		0x1000F
++/* Write Frame Byte Count Low */
++#define SBSDIO_FUNC1_WFRAMEBCLO		0x10019
++/* Write Frame Byte Count High */
++#define SBSDIO_FUNC1_WFRAMEBCHI		0x1001A
++/* Read Frame Byte Count Low */
++#define SBSDIO_FUNC1_RFRAMEBCLO		0x1001B
++/* Read Frame Byte Count High */
++#define SBSDIO_FUNC1_RFRAMEBCHI		0x1001C
++
++#define SBSDIO_FUNC1_MISC_REG_START	0x10000	/* f1 misc register start */
++#define SBSDIO_FUNC1_MISC_REG_LIMIT	0x1001C	/* f1 misc register end */
++
++/* function 1 OCP space */
++
++/* sb offset addr is <= 15 bits, 32k */
++#define SBSDIO_SB_OFT_ADDR_MASK		0x07FFF
++#define SBSDIO_SB_OFT_ADDR_LIMIT	0x08000
++/* with b15, maps to 32-bit SB access */
++#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000
++
++/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
++
++#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */
++#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */
++#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */
++/* Address bits from SBADDR regs */
++#define SBSDIO_SBWINDOW_MASK		0xffff8000
++
++#define SDIOH_READ              0	/* Read request */
++#define SDIOH_WRITE             1	/* Write request */
++
++#define SDIOH_DATA_FIX          0	/* Fixed addressing */
++#define SDIOH_DATA_INC          1	/* Incremental addressing */
++
++/* internal return code */
++#define SUCCESS	0
++#define ERROR	1
++
++/* Packet alignment for most efficient SDIO (can change based on platform) */
++#define BRCMF_SDALIGN	(1 << 6)
++
++/* watchdog polling interval in ms */
++#define BRCMF_WD_POLL_MS	10
++
++struct brcmf_sdreg {
++	int func;
++	int offset;
++	int value;
++};
++
++struct brcmf_sdio;
++
++struct brcmf_sdio_dev {
++	struct sdio_func *func[SDIO_MAX_FUNCS];
++	u8 num_funcs;			/* Supported funcs on client */
++	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
++	u32 sbwad;			/* Save backplane window address */
++	void *bus;
++	atomic_t suspend;		/* suspend flag */
++	wait_queue_head_t request_byte_wait;
++	wait_queue_head_t request_word_wait;
++	wait_queue_head_t request_chain_wait;
++	wait_queue_head_t request_buffer_wait;
++	struct device *dev;
++	struct brcmf_bus *bus_if;
++#ifdef CONFIG_BRCMFMAC_SDIO_OOB
++	unsigned int irq;		/* oob interrupt number */
++	unsigned long irq_flags;	/* board specific oob flags */
++	bool irq_en;			/* irq enable flags */
++	spinlock_t irq_en_lock;
++	bool irq_wake;			/* irq wake enable flags */
++#endif		/* CONFIG_BRCMFMAC_SDIO_OOB */
++};
++
++/* Register/deregister interrupt handler. */
++extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
++
++/* sdio device register access interface */
++extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret);
++extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u8 data, int *ret);
++extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
++			     u32 data, int *ret);
++
++/* Buffer transfer to/from device (client) core via cmd53.
++ *   fn:       function number
++ *   addr:     backplane address (i.e. >= regsva from attach)
++ *   flags:    backplane width, address increment, sync/async
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ *   pkt:      pointer to packet associated with buf (if any)
++ *   complete: callback function for command completion (async only)
++ *   handle:   handle for completion callback (first arg in callback)
++ * Returns 0 or error code.
++ * NOTE: Async operation is not currently supported.
++ */
++extern int
++brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++
++extern int
++brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, struct sk_buff *pkt);
++extern int
++brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++		      uint flags, u8 *buf, uint nbytes);
++extern int
++brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
++			uint flags, struct sk_buff_head *pktq);
++
++/* Flags bits */
++
++/* Four-byte target (backplane) width (vs. two-byte) */
++#define SDIO_REQ_4BYTE	0x1
++/* Fixed address (FIFO) (vs. incrementing address) */
++#define SDIO_REQ_FIXED	0x2
++/* Async request (vs. sync request) */
++#define SDIO_REQ_ASYNC	0x4
++
++/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
++ *   rw:       read or write (0/1)
++ *   addr:     direct SDIO address
++ *   buf:      pointer to memory data buffer
++ *   nbytes:   number of bytes to transfer to/from buf
++ * Returns 0 or error code.
++ */
++extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
++			       u32 addr, u8 *buf, uint nbytes);
++
++/* Issue an abort to the specified function */
++extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
++
++/* platform specific/high level functions */
++extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
++extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
++
++extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
++					  u32 address);
++
++/* attach, return handler on success, NULL if failed.
++ *  The handler shall be provided by all subsequent calls. No local cache
++ *  cfghdl points to the starting address of pci device mapped memory
++ */
++extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
++
++/* read or write one byte using cmd52 */
++extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
++				    uint fnc, uint addr, u8 *byte);
++
++/* read or write 2/4 bytes using cmd53 */
++extern int
++brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
++			 uint rw, uint fnc, uint addr,
++			 u32 *word, uint nbyte);
++
++/* read or write any buffer using cmd53 */
++extern int
++brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
++			   uint fix_inc, uint rw, uint fnc_num, u32 addr,
++			   struct sk_buff *pkt);
++extern int
++brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
++			  uint write, uint func, uint addr,
++			  struct sk_buff_head *pktq);
++
++/* Watchdog timer interface for pm ops */
++extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
++				    bool enable);
++
++extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev);
++extern void brcmf_sdbrcm_disconnect(void *ptr);
++extern void brcmf_sdbrcm_isr(void *arg);
++
++extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
++#endif				/* _BRCM_SDH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+new file mode 100644
+index 0000000..be1edc8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+@@ -0,0 +1,1617 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/slab.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/fcntl.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/firmware.h>
++#include <linux/usb.h>
++#include <linux/vmalloc.h>
++#include <net/cfg80211.h>
++
++#include <defs.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <dhd_bus.h>
++#include <dhd_dbg.h>
++
++#include "usb_rdl.h"
++#include "usb.h"
++
++#define IOCTL_RESP_TIMEOUT  2000
++
++#define BRCMF_USB_SYNC_TIMEOUT		300	/* ms */
++#define BRCMF_USB_DLIMAGE_SPINWAIT	100	/* in unit of ms */
++#define BRCMF_USB_DLIMAGE_LIMIT		500	/* spinwait limit (ms) */
++
++#define BRCMF_POSTBOOT_ID		0xA123  /* ID to detect if dongle
++						   has boot up */
++#define BRCMF_USB_RESETCFG_SPINWAIT	1	/* wait after resetcfg (ms) */
++
++#define BRCMF_USB_NRXQ	50
++#define BRCMF_USB_NTXQ	50
++
++#define CONFIGDESC(usb)         (&((usb)->actconfig)->desc)
++#define IFPTR(usb, idx)         ((usb)->actconfig->interface[(idx)])
++#define IFALTS(usb, idx)        (IFPTR((usb), (idx))->altsetting[0])
++#define IFDESC(usb, idx)        IFALTS((usb), (idx)).desc
++#define IFEPDESC(usb, idx, ep)  (IFALTS((usb), (idx)).endpoint[(ep)]).desc
++
++#define CONTROL_IF              0
++#define BULK_IF                 0
++
++#define BRCMF_USB_CBCTL_WRITE	0
++#define BRCMF_USB_CBCTL_READ	1
++#define BRCMF_USB_MAX_PKT_SIZE	1600
++
++#define BRCMF_USB_43236_FW_NAME	"brcm/brcmfmac43236b.bin"
++
++enum usbdev_suspend_state {
++	USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
++						  suspend */
++	USBOS_SUSPEND_STATE_SUSPEND_PENDING,	/* Device is idle, can be
++						 * suspended. Wating PM to
++						 * suspend the device
++						 */
++	USBOS_SUSPEND_STATE_SUSPENDED	/* Device suspended */
++};
++
++struct brcmf_usb_probe_info {
++	void *usbdev_info;
++	struct usb_device *usb; /* USB device pointer from OS */
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++	int intr_size; /* Size of interrupt message */
++	int interval;  /* Interrupt polling interval */
++	int vid;
++	int pid;
++	enum usb_device_speed device_speed;
++	enum usbdev_suspend_state suspend_state;
++	struct usb_interface *intf;
++};
++static struct brcmf_usb_probe_info usbdev_probe_info;
++
++struct brcmf_usb_image {
++	void *data;
++	u32 len;
++};
++static struct brcmf_usb_image g_image = { NULL, 0 };
++
++struct intr_transfer_buf {
++	u32 notification;
++	u32 reserved;
++};
++
++struct brcmf_usbdev_info {
++	struct brcmf_usbdev bus_pub; /* MUST BE FIRST */
++	spinlock_t qlock;
++	struct list_head rx_freeq;
++	struct list_head rx_postq;
++	struct list_head tx_freeq;
++	struct list_head tx_postq;
++	enum usbdev_suspend_state suspend_state;
++	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
++
++	bool activity;
++	int rx_low_watermark;
++	int tx_low_watermark;
++	int tx_high_watermark;
++	bool txoff;
++	bool rxoff;
++	bool txoverride;
++
++	struct brcmf_usbreq *tx_reqs;
++	struct brcmf_usbreq *rx_reqs;
++
++	u8 *image;	/* buffer for combine fw and nvram */
++	int image_len;
++
++	wait_queue_head_t wait;
++	bool waitdone;
++	int sync_urb_status;
++
++	struct usb_device *usbdev;
++	struct device *dev;
++	enum usb_device_speed  device_speed;
++
++	int ctl_in_pipe, ctl_out_pipe;
++	struct urb *ctl_urb; /* URB for control endpoint */
++	struct usb_ctrlrequest ctl_write;
++	struct usb_ctrlrequest ctl_read;
++	u32 ctl_urb_actual_length;
++	int ctl_urb_status;
++	int ctl_completed;
++	wait_queue_head_t ioctl_resp_wait;
++	wait_queue_head_t ctrl_wait;
++	ulong ctl_op;
++
++	bool rxctl_deferrespok;
++
++	struct urb *bulk_urb; /* used for FW download */
++	struct urb *intr_urb; /* URB for interrupt endpoint */
++	int intr_size;          /* Size of interrupt message */
++	int interval;           /* Interrupt polling interval */
++	struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
++
++	struct brcmf_usb_probe_info probe_info;
++
++};
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req);
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	return bus_if->bus_priv.usb;
++}
++
++static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
++{
++	return brcmf_usb_get_buspub(dev)->devinfo;
++}
++
++#if 0
++static void
++brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
++{
++	dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
++}
++#endif
++
++static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
++	 uint *condition, bool *pending)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	int timeout = IOCTL_RESP_TIMEOUT;
++
++	/* Convert timeout in millsecond to jiffies */
++	timeout = msecs_to_jiffies(timeout);
++	/* Wait until control frame is available */
++	add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++	set_current_state(TASK_INTERRUPTIBLE);
++
++	smp_mb();
++	while (!(*condition) && (!signal_pending(current) && timeout)) {
++		timeout = schedule_timeout(timeout);
++		/* Wait until control frame is available */
++		smp_mb();
++	}
++
++	if (signal_pending(current))
++		*pending = true;
++
++	set_current_state(TASK_RUNNING);
++	remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
++
++	return timeout;
++}
++
++static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
++{
++	if (waitqueue_active(&devinfo->ioctl_resp_wait))
++		wake_up_interruptible(&devinfo->ioctl_resp_wait);
++
++	return 0;
++}
++
++static void
++brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
++{
++
++	if (unlikely(devinfo == NULL))
++		return;
++
++	if (type == BRCMF_USB_CBCTL_READ) {
++		if (status == 0)
++			devinfo->bus_pub.stats.rx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.rx_ctlerrs++;
++	} else if (type == BRCMF_USB_CBCTL_WRITE) {
++		if (status == 0)
++			devinfo->bus_pub.stats.tx_ctlpkts++;
++		else
++			devinfo->bus_pub.stats.tx_ctlerrs++;
++	}
++
++	devinfo->ctl_urb_status = status;
++	devinfo->ctl_completed = true;
++	brcmf_usb_ioctl_resp_wake(devinfo);
++}
++
++static void
++brcmf_usb_ctlread_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->ctl_urb_actual_length = urb->actual_length;
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
++		urb->status);
++}
++
++static void
++brcmf_usb_ctlwrite_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)urb->context;
++
++	brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
++		urb->status);
++}
++
++static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
++{
++	return 0;
++}
++
++static int
++brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if (devinfo == NULL || buf == NULL ||
++	    len == 0 || devinfo->ctl_urb == NULL)
++		return -EINVAL;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED)
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++
++	devinfo->activity = true;
++	size = len;
++	devinfo->ctl_write.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++	devinfo->ctl_urb_status = 0;
++	devinfo->ctl_urb_actual_length = 0;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_out_pipe,
++		(unsigned char *) &devinfo->ctl_write,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlwrite_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int
++brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
++{
++	int ret;
++	u16 size;
++
++	if ((devinfo == NULL) || (buf == NULL) || (len == 0)
++		|| (devinfo->ctl_urb == NULL))
++		return -EINVAL;
++
++	size = len;
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	if (devinfo->rxctl_deferrespok) {
++		/* BMAC model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK;
++	} else {
++		/* full dongle model */
++		devinfo->ctl_read.bRequestType = USB_DIR_IN
++			| USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++	}
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		devinfo->ctl_in_pipe,
++		(unsigned char *) &devinfo->ctl_read,
++		buf, size,
++		(usb_complete_t)brcmf_usb_ctlread_complete,
++		devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0)
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++
++	return ret;
++}
++
++static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_send_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "Txctl wait timed out\n");
++		err = -EIO;
++	}
++	return err;
++}
++
++static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
++{
++	int err = 0;
++	int timeout = 0;
++	bool pending;
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++	if (test_and_set_bit(0, &devinfo->ctl_op))
++		return -EIO;
++
++	err = brcmf_usb_recv_ctl(devinfo, buf, len);
++	if (err) {
++		brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
++		return err;
++	}
++	devinfo->ctl_completed = false;
++	timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
++					    &pending);
++	err = devinfo->ctl_urb_status;
++	clear_bit(0, &devinfo->ctl_op);
++	if (!timeout) {
++		brcmf_dbg(ERROR, "rxctl wait timed out\n");
++		err = -EIO;
++	}
++	if (!err)
++		return devinfo->ctl_urb_actual_length;
++	else
++		return err;
++}
++
++static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
++					  struct list_head *q)
++{
++	unsigned long flags;
++	struct brcmf_usbreq  *req;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	if (list_empty(q)) {
++		spin_unlock_irqrestore(&devinfo->qlock, flags);
++		return NULL;
++	}
++	req = list_entry(q->next, struct brcmf_usbreq, list);
++	list_del_init(q->next);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++	return req;
++
++}
++
++static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
++			  struct list_head *q, struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_add_tail(&req->list, q);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++static struct brcmf_usbreq *
++brcmf_usbdev_qinit(struct list_head *q, int qsize)
++{
++	int i;
++	struct brcmf_usbreq *req, *reqs;
++
++	reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC);
++	if (reqs == NULL) {
++		brcmf_dbg(ERROR, "fail to allocate memory!\n");
++		return NULL;
++	}
++	req = reqs;
++
++	for (i = 0; i < qsize; i++) {
++		req->urb = usb_alloc_urb(0, GFP_ATOMIC);
++		if (!req->urb)
++			goto fail;
++
++		INIT_LIST_HEAD(&req->list);
++		list_add_tail(&req->list, q);
++		req++;
++	}
++	return reqs;
++fail:
++	brcmf_dbg(ERROR, "fail!\n");
++	while (!list_empty(q)) {
++		req = list_entry(q->next, struct brcmf_usbreq, list);
++		if (req && req->urb)
++			usb_free_urb(req->urb);
++		list_del(q->next);
++	}
++	return NULL;
++
++}
++
++static void brcmf_usb_free_q(struct list_head *q, bool pending)
++{
++	struct brcmf_usbreq *req, *next;
++	int i = 0;
++	list_for_each_entry_safe(req, next, q, list) {
++		if (!req->urb) {
++			brcmf_dbg(ERROR, "bad req\n");
++			break;
++		}
++		i++;
++		if (pending) {
++			usb_kill_urb(req->urb);
++		} else {
++			usb_free_urb(req->urb);
++			list_del_init(&req->list);
++		}
++	}
++}
++
++static void brcmf_usb_del_fromq(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq *req)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&devinfo->qlock, flags);
++	list_del_init(&req->list);
++	spin_unlock_irqrestore(&devinfo->qlock, flags);
++}
++
++
++static void brcmf_usb_tx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	if (urb->status == 0)
++		devinfo->bus_pub.bus->dstats.tx_packets++;
++	else
++		devinfo->bus_pub.bus->dstats.tx_errors++;
++
++	dev_kfree_skb(req->skb);
++	req->skb = NULL;
++	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++
++}
++
++static void brcmf_usb_rx_complete(struct urb *urb)
++{
++	struct brcmf_usbreq  *req = (struct brcmf_usbreq *)urb->context;
++	struct brcmf_usbdev_info *devinfo = req->devinfo;
++	struct sk_buff *skb;
++	int ifidx = 0;
++
++	brcmf_usb_del_fromq(devinfo, req);
++	skb = req->skb;
++	req->skb = NULL;
++
++	if (urb->status == 0) {
++		devinfo->bus_pub.bus->dstats.rx_packets++;
++	} else {
++		devinfo->bus_pub.bus->dstats.rx_errors++;
++		dev_kfree_skb(skb);
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) {
++		skb_put(skb, urb->actual_length);
++		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
++			brcmf_dbg(ERROR, "rx protocol error\n");
++			brcmu_pkt_buf_free_skb(skb);
++			devinfo->bus_pub.bus->dstats.rx_errors++;
++		} else {
++			brcmf_rx_packet(devinfo->dev, ifidx, skb);
++			brcmf_usb_rx_refill(devinfo, req);
++		}
++	} else {
++		dev_kfree_skb(skb);
++	}
++	return;
++
++}
++
++static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
++				struct brcmf_usbreq  *req)
++{
++	struct sk_buff *skb;
++	int ret;
++
++	if (!req || !devinfo)
++		return;
++
++	skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
++	if (!skb) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++		return;
++	}
++	req->skb = skb;
++
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
++			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
++			  req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	req->devinfo = devinfo;
++
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (ret == 0) {
++		brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
++	} else {
++		dev_kfree_skb(req->skb);
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
++	}
++	return;
++}
++
++static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
++{
++	struct brcmf_usbreq *req;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		brcmf_dbg(ERROR, "bus is not up\n");
++		return;
++	}
++	while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
++		brcmf_usb_rx_refill(devinfo, req);
++}
++
++static void
++brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
++{
++	struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
++	int old_state;
++
++
++	if (devinfo->bus_pub.state == state)
++		return;
++
++	old_state = devinfo->bus_pub.state;
++	brcmf_dbg(TRACE, "dbus state change from %d to to %d\n",
++		  old_state, state);
++
++	/* Don't update state if it's PnP firmware re-download */
++	if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
++		devinfo->bus_pub.state = state;
++
++	if ((old_state  == BCMFMAC_USB_STATE_SLEEP)
++		&& (state == BCMFMAC_USB_STATE_UP)) {
++		brcmf_usb_rx_fill_all(devinfo);
++	}
++
++	/* update state of upper layer */
++	if (state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(INFO, "DBUS is down\n");
++		bcmf_bus->state = BRCMF_BUS_DOWN;
++	} else {
++		brcmf_dbg(INFO, "DBUS current state=%d\n", state);
++	}
++}
++
++static void
++brcmf_usb_intr_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++	bool killed;
++
++	if (devinfo == NULL)
++		return;
++
++	if (unlikely(urb->status)) {
++		if (devinfo->suspend_state ==
++			USBOS_SUSPEND_STATE_SUSPEND_PENDING)
++			killed = true;
++
++		if ((urb->status == -ENOENT && (!killed))
++			|| urb->status == -ESHUTDOWN ||
++			urb->status == -ENODEV) {
++			brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++		}
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) {
++		brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n");
++		return;
++	}
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++}
++
++static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	struct brcmf_usbreq  *req;
++	int ret;
++
++	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
++		/* TODO: handle suspend/resume */
++		return -EIO;
++	}
++
++	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
++	if (!req) {
++		brcmf_dbg(ERROR, "no req to send\n");
++		return -ENOMEM;
++	}
++	if (!req->urb) {
++		brcmf_dbg(ERROR, "no urb for req %p\n", req);
++		return -ENOBUFS;
++	}
++
++	req->skb = skb;
++	req->devinfo = devinfo;
++	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
++			  skb->data, skb->len, brcmf_usb_tx_complete, req);
++	req->urb->transfer_flags |= URB_ZERO_PACKET;
++	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
++	if (!ret) {
++		brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
++	} else {
++		req->skb = NULL;
++		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
++	}
++
++	return ret;
++}
++
++
++static int brcmf_usb_up(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	u16 ifnum;
++
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
++		return 0;
++
++	/* If the USB/HSIC bus in sleep state, wake it up */
++	if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
++		if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
++			brcmf_dbg(ERROR, "Could not Resume the bus!\n");
++			return -EIO;
++		}
++	}
++	devinfo->activity = true;
++
++	/* Success, indicate devinfo is fully up */
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP);
++
++	if (devinfo->intr_urb) {
++		int ret;
++
++		usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
++			devinfo->intr_pipe,
++			&devinfo->intr,
++			devinfo->intr_size,
++			(usb_complete_t)brcmf_usb_intr_complete,
++			devinfo,
++			devinfo->interval);
++
++		ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
++		if (ret) {
++			brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n",
++				  ret);
++			return -EINVAL;
++		}
++	}
++
++	if (devinfo->ctl_urb) {
++		devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
++		devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
++
++		ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
++
++		/* CTL Write */
++		devinfo->ctl_write.bRequestType =
++			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_write.bRequest = 0;
++		devinfo->ctl_write.wValue = cpu_to_le16(0);
++		devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);
++
++		/* CTL Read */
++		devinfo->ctl_read.bRequestType =
++			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
++		devinfo->ctl_read.bRequest = 1;
++		devinfo->ctl_read.wValue = cpu_to_le16(0);
++		devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
++	}
++	brcmf_usb_rx_fill_all(devinfo);
++	return 0;
++}
++
++static void brcmf_usb_down(struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++
++	if (devinfo == NULL)
++		return;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
++		return;
++
++	brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
++	if (devinfo->intr_urb)
++		usb_kill_urb(devinfo->intr_urb);
++
++	if (devinfo->ctl_urb)
++		usb_kill_urb(devinfo->ctl_urb);
++
++	if (devinfo->bulk_urb)
++		usb_kill_urb(devinfo->bulk_urb);
++	brcmf_usb_free_q(&devinfo->tx_postq, true);
++
++	brcmf_usb_free_q(&devinfo->rx_postq, true);
++}
++
++static int
++brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time)
++{
++	int ret;
++	int err = 0;
++	int ms = time;
++
++	ret = wait_event_interruptible_timeout(devinfo->wait,
++		devinfo->waitdone == true, (ms * HZ / 1000));
++
++	if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) {
++		brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n",
++			  ret, devinfo->sync_urb_status);
++		err = -EINVAL;
++	}
++	devinfo->waitdone = false;
++	return err;
++}
++
++static void
++brcmf_usb_sync_complete(struct urb *urb)
++{
++	struct brcmf_usbdev_info *devinfo =
++			(struct brcmf_usbdev_info *)urb->context;
++
++	devinfo->waitdone = true;
++	wake_up_interruptible(&devinfo->wait);
++	devinfo->sync_urb_status = urb->status;
++}
++
++static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
++			     void *buffer, int buflen)
++{
++	int ret = 0;
++	char *tmpbuf;
++	u16 size;
++
++	if ((!devinfo) || (devinfo->ctl_urb == NULL))
++		return false;
++
++	tmpbuf = kmalloc(buflen, GFP_ATOMIC);
++	if (!tmpbuf)
++		return false;
++
++	size = buflen;
++	devinfo->ctl_urb->transfer_buffer_length = size;
++
++	devinfo->ctl_read.wLength = cpu_to_le16p(&size);
++	devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
++		USB_RECIP_INTERFACE;
++	devinfo->ctl_read.bRequest = cmd;
++
++	usb_fill_control_urb(devinfo->ctl_urb,
++		devinfo->usbdev,
++		usb_rcvctrlpipe(devinfo->usbdev, 0),
++		(unsigned char *) &devinfo->ctl_read,
++		(void *) tmpbuf, size,
++		(usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
++	if (ret < 0) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		kfree(tmpbuf);
++		return false;
++	}
++
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	memcpy(buffer, tmpbuf, buflen);
++	kfree(tmpbuf);
++
++	return (ret == 0);
++}
++
++static bool
++brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u32 chipid, chiprev;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return false;
++
++	/* Check if firmware downloaded already by querying runtime ID */
++	id.chip = cpu_to_le32(0xDEAD);
++	brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++		sizeof(struct bootrom_id_le));
++
++	chipid = le32_to_cpu(id.chip);
++	chiprev = le32_to_cpu(id.chiprev);
++
++	if ((chipid & 0x4300) == 0x4300)
++		brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev);
++	else
++		brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev);
++	if (chipid == BRCMF_POSTBOOT_ID) {
++		brcmf_dbg(INFO, "firmware already downloaded\n");
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++		return false;
++	} else {
++		devinfo->bus_pub.devid = chipid;
++		devinfo->bus_pub.chiprev = chiprev;
++	}
++	return true;
++}
++
++static int
++brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
++{
++	struct bootrom_id_le id;
++	u16 wait = 0, wait_time;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	/* Give dongle chance to boot */
++	wait_time = BRCMF_USB_DLIMAGE_SPINWAIT;
++	while (wait < BRCMF_USB_DLIMAGE_LIMIT) {
++		mdelay(wait_time);
++		wait += wait_time;
++		id.chip = cpu_to_le32(0xDEAD);       /* Get the ID */
++		brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id,
++			sizeof(struct bootrom_id_le));
++		if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
++			break;
++	}
++
++	if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
++		brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
++			  wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));
++
++		brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
++			sizeof(struct bootrom_id_le));
++
++		/* XXX this wait may not be necessary */
++		mdelay(BRCMF_USB_RESETCFG_SPINWAIT);
++		return 0;
++	} else {
++		brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n",
++			  wait);
++		return -EINVAL;
++	}
++}
++
++
++static int
++brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len)
++{
++	int ret;
++
++	if ((devinfo == NULL) || (devinfo->bulk_urb == NULL))
++		return -EINVAL;
++
++	/* Prepare the URB */
++	usb_fill_bulk_urb(devinfo->bulk_urb, devinfo->usbdev,
++			  devinfo->tx_pipe, buffer, len,
++			  (usb_complete_t)brcmf_usb_sync_complete, devinfo);
++
++	devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET;
++
++	ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC);
++	if (ret) {
++		brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret);
++		return ret;
++	}
++	ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT);
++	return ret;
++}
++
++static int
++brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
++{
++	unsigned int sendlen, sent, dllen;
++	char *bulkchunk = NULL, *dlpos;
++	struct rdl_state_le state;
++	u32 rdlstate, rdlbytes;
++	int err = 0;
++	brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen);
++
++	bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
++	if (bulkchunk == NULL) {
++		err = -ENOMEM;
++		goto fail;
++	}
++
++	/* 1) Prepare USB boot loader for runtime image */
++	brcmf_usb_dl_cmd(devinfo, DL_START, &state,
++			 sizeof(struct rdl_state_le));
++
++	rdlstate = le32_to_cpu(state.state);
++	rdlbytes = le32_to_cpu(state.bytes);
++
++	/* 2) Check we are in the Waiting state */
++	if (rdlstate != DL_WAITING) {
++		brcmf_dbg(ERROR, "Failed to DL_START\n");
++		err = -EINVAL;
++		goto fail;
++	}
++	sent = 0;
++	dlpos = fw;
++	dllen = fwlen;
++
++	/* Get chip id and rev */
++	while (rdlbytes != dllen) {
++		/* Wait until the usb device reports it received all
++		 * the bytes we sent */
++		if ((rdlbytes == sent) && (rdlbytes != dllen)) {
++			if ((dllen-sent) < RDL_CHUNK)
++				sendlen = dllen-sent;
++			else
++				sendlen = RDL_CHUNK;
++
++			/* simply avoid having to send a ZLP by ensuring we
++			 * never have an even
++			 * multiple of 64
++			 */
++			if (!(sendlen % 64))
++				sendlen -= 4;
++
++			/* send data */
++			memcpy(bulkchunk, dlpos, sendlen);
++			if (brcmf_usb_dl_send_bulk(devinfo, bulkchunk,
++						   sendlen)) {
++				brcmf_dbg(ERROR, "send_bulk failed\n");
++				err = -EINVAL;
++				goto fail;
++			}
++
++			dlpos += sendlen;
++			sent += sendlen;
++		}
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++				      sizeof(struct rdl_state_le))) {
++			brcmf_dbg(ERROR, "DL_GETSTATE Failed xxxx\n");
++			err = -EINVAL;
++			goto fail;
++		}
++
++		rdlstate = le32_to_cpu(state.state);
++		rdlbytes = le32_to_cpu(state.bytes);
++
++		/* restart if an error is reported */
++		if (rdlstate == DL_BAD_HDR || rdlstate == DL_BAD_CRC) {
++			brcmf_dbg(ERROR, "Bad Hdr or Bad CRC state %d\n",
++				  rdlstate);
++			err = -EINVAL;
++			goto fail;
++		}
++	}
++
++fail:
++	kfree(bulkchunk);
++	brcmf_dbg(TRACE, "err=%d\n", err);
++	return err;
++}
++
++static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
++{
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	if (devinfo == NULL)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	err = brcmf_usb_dl_writeimage(devinfo, fw, len);
++	if (err == 0)
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE;
++	else
++		devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING;
++	brcmf_dbg(TRACE, "exit: err=%d\n", err);
++
++	return err;
++}
++
++static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
++{
++	struct rdl_state_le state;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (!devinfo)
++		return -EINVAL;
++
++	if (devinfo->bus_pub.devid == 0xDEAD)
++		return -EINVAL;
++
++	/* Check we are runnable */
++	brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
++		sizeof(struct rdl_state_le));
++
++	/* Start the image */
++	if (state.state == cpu_to_le32(DL_RUNNABLE)) {
++		if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state,
++			sizeof(struct rdl_state_le)))
++			return -ENODEV;
++		if (brcmf_usb_resetcfg(devinfo))
++			return -ENODEV;
++		/* The Dongle may go for re-enumeration. */
++	} else {
++		brcmf_dbg(ERROR, "Dongle not runnable\n");
++		return -EINVAL;
++	}
++	brcmf_dbg(TRACE, "exit\n");
++	return 0;
++}
++
++static bool brcmf_usb_chip_support(int chipid, int chiprev)
++{
++	switch(chipid) {
++	case 43235:
++	case 43236:
++	case 43238:
++		return (chiprev == 3);
++	default:
++		break;
++	}
++	return false;
++}
++
++static int
++brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
++{
++	int devid, chiprev;
++	int err;
++
++	brcmf_dbg(TRACE, "enter\n");
++	if (devinfo == NULL)
++		return -ENODEV;
++
++	devid = devinfo->bus_pub.devid;
++	chiprev = devinfo->bus_pub.chiprev;
++
++	if (!brcmf_usb_chip_support(devid, chiprev)) {
++		brcmf_dbg(ERROR, "unsupported chip %d rev %d\n",
++			  devid, chiprev);
++		return -EINVAL;
++	}
++
++	if (!devinfo->image) {
++		brcmf_dbg(ERROR, "No firmware!\n");
++		return -ENOENT;
++	}
++
++	err = brcmf_usb_dlstart(devinfo,
++		devinfo->image, devinfo->image_len);
++	if (err == 0)
++		err = brcmf_usb_dlrun(devinfo);
++	return err;
++}
++
++
++static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
++{
++	struct brcmf_usbdev_info *devinfo =
++		(struct brcmf_usbdev_info *)bus_pub;
++
++	brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
++
++	/* store the image globally */
++	g_image.data = devinfo->image;
++	g_image.len = devinfo->image_len;
++
++	/* free the URBS */
++	brcmf_usb_free_q(&devinfo->rx_freeq, false);
++	brcmf_usb_free_q(&devinfo->tx_freeq, false);
++
++	usb_free_urb(devinfo->intr_urb);
++	usb_free_urb(devinfo->ctl_urb);
++	usb_free_urb(devinfo->bulk_urb);
++
++	kfree(devinfo->tx_reqs);
++	kfree(devinfo->rx_reqs);
++	kfree(devinfo);
++}
++
++#define TRX_MAGIC       0x30524448      /* "HDR0" */
++#define TRX_VERSION     1               /* Version 1 */
++#define TRX_MAX_LEN     0x3B0000        /* Max length */
++#define TRX_NO_HEADER   1               /* Do not write TRX header */
++#define TRX_MAX_OFFSET  3               /* Max number of individual files */
++#define TRX_UNCOMP_IMAGE        0x20    /* Trx contains uncompressed image */
++
++struct trx_header_le {
++	__le32 magic;		/* "HDR0" */
++	__le32 len;		/* Length of file including header */
++	__le32 crc32;		/* CRC from flag_version to end of file */
++	__le32 flag_version;	/* 0:15 flags, 16:31 version */
++	__le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of
++					 * header */
++};
++
++static int check_file(const u8 *headers)
++{
++	struct trx_header_le *trx;
++	int actual_len = -1;
++
++	/* Extract trx header */
++	trx = (struct trx_header_le *) headers;
++	if (trx->magic != cpu_to_le32(TRX_MAGIC))
++		return -1;
++
++	headers += sizeof(struct trx_header_le);
++
++	if (le32_to_cpu(trx->flag_version) & TRX_UNCOMP_IMAGE) {
++		actual_len = le32_to_cpu(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]);
++		return actual_len + sizeof(struct trx_header_le);
++	}
++	return -1;
++}
++
++static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
++{
++	s8 *fwname;
++	const struct firmware *fw;
++	int err;
++
++	devinfo->image = g_image.data;
++	devinfo->image_len = g_image.len;
++
++	/*
++	 * if we have an image we can leave here.
++	 */
++	if (devinfo->image)
++		return 0;
++
++	fwname = BRCMF_USB_43236_FW_NAME;
++
++	err = request_firmware(&fw, fwname, devinfo->dev);
++	if (!fw) {
++		brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname);
++		return err;
++	}
++	if (check_file(fw->data) < 0) {
++		brcmf_dbg(ERROR, "invalid firmware %s\n", fwname);
++		return -EINVAL;
++	}
++
++	devinfo->image = vmalloc(fw->size); /* plus nvram */
++	if (!devinfo->image)
++		return -ENOMEM;
++
++	memcpy(devinfo->image, fw->data, fw->size);
++	devinfo->image_len = fw->size;
++
++	release_firmware(fw);
++	return 0;
++}
++
++
++static
++struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
++{
++	struct brcmf_usbdev_info *devinfo;
++
++	devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
++	if (devinfo == NULL)
++		return NULL;
++
++	devinfo->bus_pub.nrxq = nrxq;
++	devinfo->rx_low_watermark = nrxq / 2;
++	devinfo->bus_pub.devinfo = devinfo;
++	devinfo->bus_pub.ntxq = ntxq;
++
++	/* flow control when too many tx urbs posted */
++	devinfo->tx_low_watermark = ntxq / 4;
++	devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
++	devinfo->dev = dev;
++	devinfo->usbdev = usbdev_probe_info.usb;
++	devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
++	devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
++	devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
++	devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
++
++	devinfo->interval = usbdev_probe_info.interval;
++	devinfo->intr_size = usbdev_probe_info.intr_size;
++
++	memcpy(&devinfo->probe_info, &usbdev_probe_info,
++		sizeof(struct brcmf_usb_probe_info));
++	devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
++
++	/* Initialize other structure content */
++	init_waitqueue_head(&devinfo->ioctl_resp_wait);
++
++	/* Initialize the spinlocks */
++	spin_lock_init(&devinfo->qlock);
++
++	INIT_LIST_HEAD(&devinfo->rx_freeq);
++	INIT_LIST_HEAD(&devinfo->rx_postq);
++
++	INIT_LIST_HEAD(&devinfo->tx_freeq);
++	INIT_LIST_HEAD(&devinfo->tx_postq);
++
++	devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
++	if (!devinfo->rx_reqs)
++		goto error;
++
++	devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
++	if (!devinfo->tx_reqs)
++		goto error;
++
++	devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->intr_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n");
++		goto error;
++	}
++	devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->ctl_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
++		goto error;
++	}
++	devinfo->rxctl_deferrespok = 0;
++
++	devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
++	if (!devinfo->bulk_urb) {
++		brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
++		goto error;
++	}
++
++	init_waitqueue_head(&devinfo->wait);
++	if (!brcmf_usb_dlneeded(devinfo))
++		return &devinfo->bus_pub;
++
++	brcmf_dbg(TRACE, "start fw downloading\n");
++	if (brcmf_usb_get_fw(devinfo))
++		goto error;
++
++	if (brcmf_usb_fw_download(devinfo))
++		goto error;
++
++	return &devinfo->bus_pub;
++
++error:
++	brcmf_dbg(ERROR, "failed!\n");
++	brcmf_usb_detach(&devinfo->bus_pub);
++	return NULL;
++}
++
++static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
++				u32 bustype, u32 hdrlen)
++{
++	struct brcmf_bus *bus = NULL;
++	struct brcmf_usbdev *bus_pub = NULL;
++	int ret;
++
++
++	bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
++	if (!bus_pub) {
++		ret = -ENODEV;
++		goto fail;
++	}
++
++	bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
++	if (!bus) {
++		ret = -ENOMEM;
++		goto fail;
++	}
++
++	bus_pub->bus = bus;
++	bus->brcmf_bus_txdata = brcmf_usb_tx;
++	bus->brcmf_bus_init = brcmf_usb_up;
++	bus->brcmf_bus_stop = brcmf_usb_down;
++	bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
++	bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
++	bus->type = bustype;
++	bus->bus_priv.usb = bus_pub;
++	dev_set_drvdata(dev, bus);
++
++	/* Attach to the common driver interface */
++	ret = brcmf_attach(hdrlen, dev);
++	if (ret) {
++		brcmf_dbg(ERROR, "dhd_attach failed\n");
++		goto fail;
++	}
++
++	ret = brcmf_bus_start(dev);
++	if (ret == -ENOLINK) {
++		brcmf_dbg(ERROR, "dongle is not responding\n");
++		brcmf_detach(dev);
++		goto fail;
++	}
++
++	return 0;
++fail:
++	/* Release resources in reverse order */
++	if (bus_pub)
++		brcmf_usb_detach(bus_pub);
++	kfree(bus);
++	return ret;
++}
++
++static void
++brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
++{
++	if (!bus_pub)
++		return;
++	brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
++
++	brcmf_detach(bus_pub->devinfo->dev);
++	kfree(bus_pub->bus);
++	brcmf_usb_detach(bus_pub);
++
++}
++
++static int
++brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++	int ep;
++	struct usb_endpoint_descriptor *endpoint;
++	int ret = 0;
++	struct usb_device *usb = interface_to_usbdev(intf);
++	int num_of_eps;
++	u8 endpoint_num;
++
++	brcmf_dbg(TRACE, "enter\n");
++
++	usbdev_probe_info.usb = usb;
++	usbdev_probe_info.intf = intf;
++
++	if (id != NULL) {
++		usbdev_probe_info.vid = id->idVendor;
++		usbdev_probe_info.pid = id->idProduct;
++	}
++
++	usb_set_intfdata(intf, &usbdev_probe_info);
++
++	/* Check that the device supports only one configuration */
++	if (usb->descriptor.bNumConfigurations != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
++		ret = -1;
++		goto fail;
++	}
++
++	/*
++	 * Only the BDC interface configuration is supported:
++	 *	Device class: USB_CLASS_VENDOR_SPEC
++	 *	if0 class: USB_CLASS_VENDOR_SPEC
++	 *	if0/ep0: control
++	 *	if0/ep1: bulk in
++	 *	if0/ep2: bulk out (ok if swapped with bulk in)
++	 */
++	if (CONFIGDESC(usb)->bNumInterfaces != 1) {
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check interface */
++	if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
++	    IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) {
++		brcmf_dbg(ERROR, "invalid control interface: class %d, subclass %d, proto %d\n",
++			  IFDESC(usb, CONTROL_IF).bInterfaceClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
++			  IFDESC(usb, CONTROL_IF).bInterfaceProtocol);
++		ret = -1;
++		goto fail;
++	}
++
++	/* Check control endpoint */
++	endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
++	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
++		!= USB_ENDPOINT_XFER_INT) {
++		brcmf_dbg(ERROR, "invalid control endpoint %d\n",
++			  endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
++		ret = -1;
++		goto fail;
++	}
++
++	endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
++	usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
++
++	usbdev_probe_info.rx_pipe = 0;
++	usbdev_probe_info.rx_pipe2 = 0;
++	usbdev_probe_info.tx_pipe = 0;
++	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
++
++	/* Check data endpoints and get pipes */
++	for (ep = 1; ep <= num_of_eps; ep++) {
++		endpoint = &IFEPDESC(usb, BULK_IF, ep);
++		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
++		    USB_ENDPOINT_XFER_BULK) {
++			brcmf_dbg(ERROR, "invalid data endpoint %d\n", ep);
++			ret = -1;
++			goto fail;
++		}
++
++		endpoint_num = endpoint->bEndpointAddress &
++			       USB_ENDPOINT_NUMBER_MASK;
++		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
++			== USB_DIR_IN) {
++			if (!usbdev_probe_info.rx_pipe) {
++				usbdev_probe_info.rx_pipe =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			} else {
++				usbdev_probe_info.rx_pipe2 =
++					usb_rcvbulkpipe(usb, endpoint_num);
++			}
++		} else {
++			usbdev_probe_info.tx_pipe =
++					usb_sndbulkpipe(usb, endpoint_num);
++		}
++	}
++
++	/* Allocate interrupt URB and data buffer */
++	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
++	if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
++		usbdev_probe_info.intr_size = 8;
++	else
++		usbdev_probe_info.intr_size = 4;
++
++	usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
++
++	usbdev_probe_info.device_speed = usb->speed;
++	if (usb->speed == USB_SPEED_HIGH)
++		brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
++	else
++		brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
++
++	ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
++	if (ret)
++		goto fail;
++
++	/* Success */
++	return 0;
++
++fail:
++	brcmf_dbg(ERROR, "failed with errno %d\n", ret);
++	usb_set_intfdata(intf, NULL);
++	return ret;
++
++}
++
++static void
++brcmf_usb_disconnect(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++
++	brcmf_dbg(TRACE, "enter\n");
++	brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
++	usb_set_intfdata(intf, NULL);
++}
++
++/*
++ *	only need to signal the bus being down and update the suspend state.
++ */
++static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
++	return 0;
++}
++
++/*
++ *	mark suspend state active and crank up the bus.
++ */
++static int brcmf_usb_resume(struct usb_interface *intf)
++{
++	struct usb_device *usb = interface_to_usbdev(intf);
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
++
++	brcmf_dbg(TRACE, "enter\n");
++	devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
++	brcmf_bus_start(&usb->dev);
++	return 0;
++}
++
++#define BRCMF_USB_VENDOR_ID_BROADCOM	0x0a5c
++#define BRCMF_USB_DEVICE_ID_43236	0xbd17
++#define BRCMF_USB_DEVICE_ID_BCMFW	0x0bdc
++
++static struct usb_device_id brcmf_usb_devid_table[] = {
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
++	/* special entry for device with firmware loaded and running */
++	{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
++	{ }
++};
++MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
++MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
++
++/* TODO: suspend and resume entries */
++static struct usb_driver brcmf_usbdrvr = {
++	.name = KBUILD_MODNAME,
++	.probe = brcmf_usb_probe,
++	.disconnect = brcmf_usb_disconnect,
++	.id_table = brcmf_usb_devid_table,
++	.suspend = brcmf_usb_suspend,
++	.resume = brcmf_usb_resume,
++	.supports_autosuspend = 1,
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
++	.disable_hub_initiated_lpm = 1,
++#endif
++};
++
++void brcmf_usb_exit(void)
++{
++	usb_deregister(&brcmf_usbdrvr);
++	vfree(g_image.data);
++	g_image.data = NULL;
++	g_image.len = 0;
++}
++
++void brcmf_usb_init(void)
++{
++	usb_register(&brcmf_usbdrvr);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+new file mode 100644
+index 0000000..acfa5e8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h
+@@ -0,0 +1,61 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef BRCMFMAC_USB_H
++#define BRCMFMAC_USB_H
++
++enum brcmf_usb_state {
++	BCMFMAC_USB_STATE_DL_PENDING,
++	BCMFMAC_USB_STATE_DL_DONE,
++	BCMFMAC_USB_STATE_UP,
++	BCMFMAC_USB_STATE_DOWN,
++	BCMFMAC_USB_STATE_PNP_FWDL,
++	BCMFMAC_USB_STATE_DISCONNECT,
++	BCMFMAC_USB_STATE_SLEEP
++};
++
++enum brcmf_usb_pnp_state {
++	BCMFMAC_USB_PNP_DISCONNECT,
++	BCMFMAC_USB_PNP_SLEEP,
++	BCMFMAC_USB_PNP_RESUME,
++};
++
++struct brcmf_stats {
++	u32 tx_ctlpkts;
++	u32 tx_ctlerrs;
++	u32 rx_ctlpkts;
++	u32 rx_ctlerrs;
++};
++
++struct brcmf_usbdev {
++	struct brcmf_bus *bus;
++	struct brcmf_usbdev_info *devinfo;
++	enum brcmf_usb_state state;
++	struct brcmf_stats stats;
++	int ntxq, nrxq, rxsize;
++	u32 bus_mtu;
++	int devid;
++	int chiprev; /* chip revsion number */
++};
++
++/* IO Request Block (IRB) */
++struct brcmf_usbreq {
++	struct list_head list;
++	struct brcmf_usbdev_info *devinfo;
++	struct urb *urb;
++	struct sk_buff  *skb;
++};
++
++#endif /* BRCMFMAC_USB_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+new file mode 100644
+index 0000000..0a35c51
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _USB_RDL_H
++#define _USB_RDL_H
++
++/* Control messages: bRequest values */
++#define DL_GETSTATE	0	/* returns the rdl_state_t struct */
++#define DL_CHECK_CRC	1	/* currently unused */
++#define DL_GO		2	/* execute downloaded image */
++#define DL_START	3	/* initialize dl state */
++#define DL_REBOOT	4	/* reboot the device in 2 seconds */
++#define DL_GETVER	5	/* returns the bootrom_id_t struct */
++#define DL_GO_PROTECTED	6	/* execute the downloaded code and set reset
++				 * event to occur in 2 seconds.  It is the
++				 * responsibility of the downloaded code to
++				 * clear this event
++				 */
++#define DL_EXEC		7	/* jump to a supplied address */
++#define DL_RESETCFG	8	/* To support single enum on dongle
++				 * - Not used by bootloader
++				 */
++#define DL_DEFER_RESP_OK 9	/* Potentially defer the response to setup
++				 * if resp unavailable
++				 */
++
++/* states */
++#define DL_WAITING	0	/* waiting to rx first pkt */
++#define DL_READY	1	/* hdr was good, waiting for more of the
++				 * compressed image */
++#define DL_BAD_HDR	2	/* hdr was corrupted */
++#define DL_BAD_CRC	3	/* compressed image was corrupted */
++#define DL_RUNNABLE	4	/* download was successful,waiting for go cmd */
++#define DL_START_FAIL	5	/* failed to initialize correctly */
++#define DL_NVRAM_TOOBIG	6	/* host specified nvram data exceeds DL_NVRAM
++				 * value */
++#define DL_IMAGE_TOOBIG	7	/* download image too big (exceeds DATA_START
++				 *  for rdl) */
++
++struct rdl_state_le {
++	__le32 state;
++	__le32 bytes;
++};
++
++struct bootrom_id_le {
++	__le32 chip;	/* Chip id */
++	__le32 chiprev;	/* Chip rev */
++	__le32 ramsize;	/* Size of  RAM */
++	__le32 remapbase;	/* Current remap base address */
++	__le32 boardtype;	/* Type of board */
++	__le32 boardrev;	/* Board revision */
++};
++
++#define RDL_CHUNK	1500  /* size of each dl transfer */
++
++#define TRX_OFFSETS_DLFWLEN_IDX	0
++#define TRX_OFFSETS_JUMPTO_IDX	1
++#define TRX_OFFSETS_NVM_LEN_IDX	2
++
++#define TRX_OFFSETS_DLBASE_IDX  0
++
++#endif  /* _USB_RDL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+new file mode 100644
+index 0000000..65e48d7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+@@ -0,0 +1,3881 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/if_arp.h>
++#include <linux/sched.h>
++#include <linux/kthread.h>
++#include <linux/netdevice.h>
++#include <linux/bitops.h>
++#include <linux/etherdevice.h>
++#include <linux/ieee80211.h>
++#include <linux/uaccess.h>
++#include <net/cfg80211.h>
++
++#include <brcmu_utils.h>
++#include <defs.h>
++#include <brcmu_wifi.h>
++#include "dhd.h"
++#include "wl_cfg80211.h"
++
++#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
++	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
++
++static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++
++static u32 brcmf_dbg_level = WL_DBG_ERR;
++
++static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
++{
++	dev->driver_data = data;
++}
++
++static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
++{
++	void *data = NULL;
++
++	if (dev)
++		data = dev->driver_data;
++	return data;
++}
++
++static
++struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
++	return ci->cfg_priv;
++}
++
++static bool check_sys_up(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("device is not ready : status (%d)\n",
++			(int)cfg_priv->status);
++		return false;
++	}
++	return true;
++}
++
++#define CHAN2G(_channel, _freq, _flags) {			\
++	.band			= IEEE80211_BAND_2GHZ,		\
++	.center_freq		= (_freq),			\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define CHAN5G(_channel, _flags) {				\
++	.band			= IEEE80211_BAND_5GHZ,		\
++	.center_freq		= 5000 + (5 * (_channel)),	\
++	.hw_value		= (_channel),			\
++	.flags			= (_flags),			\
++	.max_antenna_gain	= 0,				\
++	.max_power		= 30,				\
++}
++
++#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
++#define RATETAB_ENT(_rateid, _flags) \
++	{                                                               \
++		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
++		.hw_value       = (_rateid),                            \
++		.flags          = (_flags),                             \
++	}
++
++static struct ieee80211_rate __wl_rates[] = {
++	RATETAB_ENT(BRCM_RATE_1M, 0),
++	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATETAB_ENT(BRCM_RATE_6M, 0),
++	RATETAB_ENT(BRCM_RATE_9M, 0),
++	RATETAB_ENT(BRCM_RATE_12M, 0),
++	RATETAB_ENT(BRCM_RATE_18M, 0),
++	RATETAB_ENT(BRCM_RATE_24M, 0),
++	RATETAB_ENT(BRCM_RATE_36M, 0),
++	RATETAB_ENT(BRCM_RATE_48M, 0),
++	RATETAB_ENT(BRCM_RATE_54M, 0),
++};
++
++#define wl_a_rates		(__wl_rates + 4)
++#define wl_a_rates_size	8
++#define wl_g_rates		(__wl_rates + 0)
++#define wl_g_rates_size	12
++
++static struct ieee80211_channel __wl_2ghz_channels[] = {
++	CHAN2G(1, 2412, 0),
++	CHAN2G(2, 2417, 0),
++	CHAN2G(3, 2422, 0),
++	CHAN2G(4, 2427, 0),
++	CHAN2G(5, 2432, 0),
++	CHAN2G(6, 2437, 0),
++	CHAN2G(7, 2442, 0),
++	CHAN2G(8, 2447, 0),
++	CHAN2G(9, 2452, 0),
++	CHAN2G(10, 2457, 0),
++	CHAN2G(11, 2462, 0),
++	CHAN2G(12, 2467, 0),
++	CHAN2G(13, 2472, 0),
++	CHAN2G(14, 2484, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_a_channels[] = {
++	CHAN5G(34, 0), CHAN5G(36, 0),
++	CHAN5G(38, 0), CHAN5G(40, 0),
++	CHAN5G(42, 0), CHAN5G(44, 0),
++	CHAN5G(46, 0), CHAN5G(48, 0),
++	CHAN5G(52, 0), CHAN5G(56, 0),
++	CHAN5G(60, 0), CHAN5G(64, 0),
++	CHAN5G(100, 0), CHAN5G(104, 0),
++	CHAN5G(108, 0), CHAN5G(112, 0),
++	CHAN5G(116, 0), CHAN5G(120, 0),
++	CHAN5G(124, 0), CHAN5G(128, 0),
++	CHAN5G(132, 0), CHAN5G(136, 0),
++	CHAN5G(140, 0), CHAN5G(149, 0),
++	CHAN5G(153, 0), CHAN5G(157, 0),
++	CHAN5G(161, 0), CHAN5G(165, 0),
++	CHAN5G(184, 0), CHAN5G(188, 0),
++	CHAN5G(192, 0), CHAN5G(196, 0),
++	CHAN5G(200, 0), CHAN5G(204, 0),
++	CHAN5G(208, 0), CHAN5G(212, 0),
++	CHAN5G(216, 0),
++};
++
++static struct ieee80211_channel __wl_5ghz_n_channels[] = {
++	CHAN5G(32, 0), CHAN5G(34, 0),
++	CHAN5G(36, 0), CHAN5G(38, 0),
++	CHAN5G(40, 0), CHAN5G(42, 0),
++	CHAN5G(44, 0), CHAN5G(46, 0),
++	CHAN5G(48, 0), CHAN5G(50, 0),
++	CHAN5G(52, 0), CHAN5G(54, 0),
++	CHAN5G(56, 0), CHAN5G(58, 0),
++	CHAN5G(60, 0), CHAN5G(62, 0),
++	CHAN5G(64, 0), CHAN5G(66, 0),
++	CHAN5G(68, 0), CHAN5G(70, 0),
++	CHAN5G(72, 0), CHAN5G(74, 0),
++	CHAN5G(76, 0), CHAN5G(78, 0),
++	CHAN5G(80, 0), CHAN5G(82, 0),
++	CHAN5G(84, 0), CHAN5G(86, 0),
++	CHAN5G(88, 0), CHAN5G(90, 0),
++	CHAN5G(92, 0), CHAN5G(94, 0),
++	CHAN5G(96, 0), CHAN5G(98, 0),
++	CHAN5G(100, 0), CHAN5G(102, 0),
++	CHAN5G(104, 0), CHAN5G(106, 0),
++	CHAN5G(108, 0), CHAN5G(110, 0),
++	CHAN5G(112, 0), CHAN5G(114, 0),
++	CHAN5G(116, 0), CHAN5G(118, 0),
++	CHAN5G(120, 0), CHAN5G(122, 0),
++	CHAN5G(124, 0), CHAN5G(126, 0),
++	CHAN5G(128, 0), CHAN5G(130, 0),
++	CHAN5G(132, 0), CHAN5G(134, 0),
++	CHAN5G(136, 0), CHAN5G(138, 0),
++	CHAN5G(140, 0), CHAN5G(142, 0),
++	CHAN5G(144, 0), CHAN5G(145, 0),
++	CHAN5G(146, 0), CHAN5G(147, 0),
++	CHAN5G(148, 0), CHAN5G(149, 0),
++	CHAN5G(150, 0), CHAN5G(151, 0),
++	CHAN5G(152, 0), CHAN5G(153, 0),
++	CHAN5G(154, 0), CHAN5G(155, 0),
++	CHAN5G(156, 0), CHAN5G(157, 0),
++	CHAN5G(158, 0), CHAN5G(159, 0),
++	CHAN5G(160, 0), CHAN5G(161, 0),
++	CHAN5G(162, 0), CHAN5G(163, 0),
++	CHAN5G(164, 0), CHAN5G(165, 0),
++	CHAN5G(166, 0), CHAN5G(168, 0),
++	CHAN5G(170, 0), CHAN5G(172, 0),
++	CHAN5G(174, 0), CHAN5G(176, 0),
++	CHAN5G(178, 0), CHAN5G(180, 0),
++	CHAN5G(182, 0), CHAN5G(184, 0),
++	CHAN5G(186, 0), CHAN5G(188, 0),
++	CHAN5G(190, 0), CHAN5G(192, 0),
++	CHAN5G(194, 0), CHAN5G(196, 0),
++	CHAN5G(198, 0), CHAN5G(200, 0),
++	CHAN5G(202, 0), CHAN5G(204, 0),
++	CHAN5G(206, 0), CHAN5G(208, 0),
++	CHAN5G(210, 0), CHAN5G(212, 0),
++	CHAN5G(214, 0), CHAN5G(216, 0),
++	CHAN5G(218, 0), CHAN5G(220, 0),
++	CHAN5G(222, 0), CHAN5G(224, 0),
++	CHAN5G(226, 0), CHAN5G(228, 0),
++};
++
++static struct ieee80211_supported_band __wl_band_2ghz = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = __wl_2ghz_channels,
++	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
++	.bitrates = wl_g_rates,
++	.n_bitrates = wl_g_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_a = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_a_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static struct ieee80211_supported_band __wl_band_5ghz_n = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = __wl_5ghz_n_channels,
++	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
++	.bitrates = wl_a_rates,
++	.n_bitrates = wl_a_rates_size,
++};
++
++static const u32 __wl_cipher_suites[] = {
++	WLAN_CIPHER_SUITE_WEP40,
++	WLAN_CIPHER_SUITE_WEP104,
++	WLAN_CIPHER_SUITE_TKIP,
++	WLAN_CIPHER_SUITE_CCMP,
++	WLAN_CIPHER_SUITE_AES_CMAC,
++};
++
++/* tag_ID/length/value_buffer tuple */
++struct brcmf_tlv {
++	u8 id;
++	u8 len;
++	u8 data[1];
++};
++
++/* Quarter dBm units to mW
++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
++ * Table is offset so the last entry is largest mW value that fits in
++ * a u16.
++ */
++
++#define QDBM_OFFSET 153		/* Offset for first entry */
++#define QDBM_TABLE_LEN 40	/* Table size */
++
++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
++ */
++#define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
++
++/* Largest mW value that will round down to the last table entry,
++ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
++ * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
++ */
++#define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
++
++static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
++/* qdBm:	+0	+1	+2	+3	+4	+5	+6	+7 */
++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
++};
++
++static u16 brcmf_qdbm_to_mw(u8 qdbm)
++{
++	uint factor = 1;
++	int idx = qdbm - QDBM_OFFSET;
++
++	if (idx >= QDBM_TABLE_LEN)
++		/* clamp to max u16 mW value */
++		return 0xFFFF;
++
++	/* scale the qdBm index up to the range of the table 0-40
++	 * where an offset of 40 qdBm equals a factor of 10 mW.
++	 */
++	while (idx < 0) {
++		idx += 40;
++		factor *= 10;
++	}
++
++	/* return the mW value scaled down to the correct factor of 10,
++	 * adding in factor/2 to get proper rounding.
++	 */
++	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
++}
++
++static u8 brcmf_mw_to_qdbm(u16 mw)
++{
++	u8 qdbm;
++	int offset;
++	uint mw_uint = mw;
++	uint boundary;
++
++	/* handle boundary case */
++	if (mw_uint <= 1)
++		return 0;
++
++	offset = QDBM_OFFSET;
++
++	/* move mw into the range of the table */
++	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
++		mw_uint *= 10;
++		offset -= 40;
++	}
++
++	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
++		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
++						    nqdBm_to_mW_map[qdbm]) / 2;
++		if (mw_uint < boundary)
++			break;
++	}
++
++	qdbm += (u8) offset;
++
++	return qdbm;
++}
++
++/* function for reading/writing a single u32 from/to the dongle */
++static int
++brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
++{
++	int err;
++	__le32 par_le = cpu_to_le32(*par);
++
++	err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
++	*par = le32_to_cpu(par_le);
++
++	return err;
++}
++
++static void convert_key_from_CPU(struct brcmf_wsec_key *key,
++				 struct brcmf_wsec_key_le *key_le)
++{
++	key_le->index = cpu_to_le32(key->index);
++	key_le->len = cpu_to_le32(key->len);
++	key_le->algo = cpu_to_le32(key->algo);
++	key_le->flags = cpu_to_le32(key->flags);
++	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
++	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
++	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
++	memcpy(key_le->data, key->data, sizeof(key->data));
++	memcpy(key_le->ea, key->ea, sizeof(key->ea));
++}
++
++static int send_key_to_dongle(struct net_device *ndev,
++			      struct brcmf_wsec_key *key)
++{
++	int err;
++	struct brcmf_wsec_key_le key_le;
++
++	convert_key_from_CPU(key, &key_le);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
++	if (err)
++		WL_ERR("WLC_SET_KEY error (%d)\n", err);
++	return err;
++}
++
++static s32
++brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
++			 enum nl80211_iftype type, u32 *flags,
++			 struct vif_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct wireless_dev *wdev;
++	s32 infra = 0;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this type\n",
++		       type);
++		return -EOPNOTSUPP;
++	case NL80211_IFTYPE_ADHOC:
++		cfg_priv->conf->mode = WL_MODE_IBSS;
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		cfg_priv->conf->mode = WL_MODE_BSS;
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		err = -EAGAIN;
++	} else {
++		wdev = ndev->ieee80211_ptr;
++		wdev->iftype = type;
++	}
++
++	WL_INFO("IF Type = %s\n",
++		(cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
++
++done:
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
++{
++	s8 buf[BRCMF_DCMD_SMLEN];
++	u32 len;
++	s32 err = 0;
++	__le32 val_le;
++
++	val_le = cpu_to_le32(val);
++	len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
++			    sizeof(buf));
++	BUG_ON(!len);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	return err;
++}
++
++static s32
++brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
++{
++	union {
++		s8 buf[BRCMF_DCMD_SMLEN];
++		__le32 val;
++	} var;
++	u32 len;
++	u32 data_null;
++	s32 err = 0;
++
++	len =
++	    brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
++			sizeof(var.buf));
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	*retval = le32_to_cpu(var.val);
++
++	return err;
++}
++
++static void brcmf_set_mpc(struct net_device *ndev, int mpc)
++{
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
++		if (err) {
++			WL_ERR("fail to set mpc\n");
++			return;
++		}
++		WL_INFO("MPC : %d\n", mpc);
++	}
++}
++
++static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
++			  struct brcmf_ssid *ssid)
++{
++	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
++	params_le->bss_type = DOT11_BSSTYPE_ANY;
++	params_le->scan_type = 0;
++	params_le->channel_num = 0;
++	params_le->nprobes = cpu_to_le32(-1);
++	params_le->active_time = cpu_to_le32(-1);
++	params_le->passive_time = cpu_to_le32(-1);
++	params_le->home_time = cpu_to_le32(-1);
++	if (ssid && ssid->SSID_len)
++		memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
++}
++
++static s32
++brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
++}
++
++static s32
++brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
++		    s32 paramlen, void *bufptr, s32 buflen)
++{
++	s32 iolen;
++
++	iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
++	BUG_ON(!iolen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
++}
++
++static s32
++brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
++		struct brcmf_ssid *ssid, u16 action)
++{
++	s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
++			  offsetof(struct brcmf_iscan_params_le, params_le);
++	struct brcmf_iscan_params_le *params;
++	s32 err = 0;
++
++	if (ssid && ssid->SSID_len)
++		params_size += sizeof(struct brcmf_ssid);
++	params = kzalloc(params_size, GFP_KERNEL);
++	if (!params)
++		return -ENOMEM;
++	BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
++
++	wl_iscan_prep(&params->params_le, ssid);
++
++	params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
++	params->action = cpu_to_le16(action);
++	params->scan_duration = cpu_to_le16(0);
++
++	err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
++				     iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
++	if (err) {
++		if (err == -EBUSY)
++			WL_INFO("system busy : iscan canceled\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++
++	kfree(params);
++	return err;
++}
++
++static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_ssid ssid;
++	__le32 passive_scan;
++	s32 err = 0;
++
++	/* Broadcast scan by default */
++	memset(&ssid, 0, sizeof(ssid));
++
++	iscan->state = WL_ISCAN_STATE_SCANING;
++
++	passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
++			&passive_scan, sizeof(passive_scan));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	brcmf_set_mpc(ndev, 0);
++	cfg_priv->iscan_kickstart = true;
++	err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
++	if (err) {
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->iscan_kickstart = false;
++		return err;
++	}
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++	return err;
++}
++
++static s32
++__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		   struct cfg80211_scan_request *request,
++		   struct cfg80211_ssid *this_ssid)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct cfg80211_ssid *ssids;
++	struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
++	__le32 passive_scan;
++	bool iscan_req;
++	bool spec_scan;
++	s32 err = 0;
++	u32 SSID_len;
++
++	if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
++		WL_ERR("Scanning being aborted : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++	if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		WL_ERR("Connecting : status (%lu)\n",
++		       cfg_priv->status);
++		return -EAGAIN;
++	}
++
++	iscan_req = false;
++	spec_scan = false;
++	if (request) {
++		/* scan bss */
++		ssids = request->ssids;
++		if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
++			iscan_req = true;
++	} else {
++		/* scan in ibss */
++		/* we don't do iscan in ibss */
++		ssids = this_ssid;
++	}
++
++	cfg_priv->scan_request = request;
++	set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	if (iscan_req) {
++		err = brcmf_do_iscan(cfg_priv);
++		if (!err)
++			return err;
++		else
++			goto scan_out;
++	} else {
++		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
++		       ssids->ssid, ssids->ssid_len);
++		memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
++		SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
++		sr->ssid_le.SSID_len = cpu_to_le32(0);
++		if (SSID_len) {
++			memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
++			sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
++			spec_scan = true;
++		} else {
++			WL_SCAN("Broadcast scan\n");
++		}
++
++		passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
++				&passive_scan, sizeof(passive_scan));
++		if (err) {
++			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
++			goto scan_out;
++		}
++		brcmf_set_mpc(ndev, 0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
++				      sizeof(sr->ssid_le));
++		if (err) {
++			if (err == -EBUSY)
++				WL_INFO("system busy : scan for \"%s\" "
++					"canceled\n", sr->ssid_le.SSID);
++			else
++				WL_ERR("WLC_SCAN error (%d)\n", err);
++
++			brcmf_set_mpc(ndev, 1);
++			goto scan_out;
++		}
++	}
++
++	return 0;
++
++scan_out:
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	cfg_priv->scan_request = NULL;
++	return err;
++}
++
++static s32
++brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
++		 struct cfg80211_scan_request *request)
++{
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
++	if (err)
++		WL_ERR("scan error (%d)\n", err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
++{
++	s32 err = 0;
++
++	err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
++	if (err)
++		WL_ERR("Error (%d)\n", err);
++
++	return err;
++}
++
++static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
++{
++	s32 err = 0;
++	u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
++
++	err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
++	if (err) {
++		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
++		return err;
++	}
++	return err;
++}
++
++static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
++	    (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
++		cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
++		err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
++	    (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
++		cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
++		err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_LONG
++	    && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
++		cfg_priv->conf->retry_long = wiphy->retry_long;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
++		if (!err)
++			goto done;
++	}
++	if (changed & WIPHY_PARAM_RETRY_SHORT
++	    && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
++		cfg_priv->conf->retry_short = wiphy->retry_short;
++		err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
++		if (!err)
++			goto done;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
++{
++	switch (item) {
++	case WL_PROF_SEC:
++		return &cfg_priv->profile->sec;
++	case WL_PROF_BSSID:
++		return &cfg_priv->profile->bssid;
++	case WL_PROF_SSID:
++		return &cfg_priv->profile->ssid;
++	}
++	WL_ERR("invalid item (%d)\n", item);
++	return NULL;
++}
++
++static s32
++brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
++		  const struct brcmf_event_msg *e, void *data, s32 item)
++{
++	s32 err = 0;
++	struct brcmf_ssid *ssid;
++
++	switch (item) {
++	case WL_PROF_SSID:
++		ssid = (struct brcmf_ssid *) data;
++		memset(cfg_priv->profile->ssid.SSID, 0,
++		       sizeof(cfg_priv->profile->ssid.SSID));
++		memcpy(cfg_priv->profile->ssid.SSID,
++		       ssid->SSID, ssid->SSID_len);
++		cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
++		break;
++	case WL_PROF_BSSID:
++		if (data)
++			memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
++		else
++			memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
++		break;
++	case WL_PROF_SEC:
++		memcpy(&cfg_priv->profile->sec, data,
++		       sizeof(cfg_priv->profile->sec));
++		break;
++	case WL_PROF_BEACONINT:
++		cfg_priv->profile->beacon_interval = *(u16 *)data;
++		break;
++	case WL_PROF_DTIMPERIOD:
++		cfg_priv->profile->dtim_period = *(u8 *)data;
++		break;
++	default:
++		WL_ERR("unsupported item (%d)\n", item);
++		err = -EOPNOTSUPP;
++		break;
++	}
++
++	return err;
++}
++
++static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
++{
++	memset(prof, 0, sizeof(*prof));
++}
++
++static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
++	size_t *join_params_size)
++{
++	u16 chanspec = 0;
++
++	if (ch != 0) {
++		if (ch <= CH_MAX_2G_CHANNEL)
++			chanspec |= WL_CHANSPEC_BAND_2G;
++		else
++			chanspec |= WL_CHANSPEC_BAND_5G;
++
++		chanspec |= WL_CHANSPEC_BW_20;
++		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
++
++		*join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
++				     sizeof(u16);
++
++		chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
++		join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
++		join_params->params_le.chanspec_num = cpu_to_le32(1);
++
++		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
++			"channel %d, chanspec %#X\n",
++			chanspec, ch, chanspec);
++	}
++}
++
++static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = NULL;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->link_up) {
++		ndev = cfg_to_ndev(cfg_priv);
++		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
++		if (err)
++			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
++		cfg_priv->link_up = false;
++	}
++	WL_TRACE("Exit\n");
++}
++
++static s32
++brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_ibss_params *params)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_join_params join_params;
++	size_t join_params_size = 0;
++	s32 err = 0;
++	s32 wsec = 0;
++	s32 bcnprd;
++	struct brcmf_ssid ssid;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (params->ssid)
++		WL_CONN("SSID: %s\n", params->ssid);
++	else {
++		WL_CONN("SSID: NULL, Not supported\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (params->bssid)
++		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
++		params->bssid[0], params->bssid[1], params->bssid[2],
++		params->bssid[3], params->bssid[4], params->bssid[5]);
++	else
++		WL_CONN("No BSSID specified\n");
++
++	if (params->channel)
++		WL_CONN("channel: %d\n", params->channel->center_freq);
++	else
++		WL_CONN("no channel specified\n");
++
++	if (params->channel_fixed)
++		WL_CONN("fixed channel required\n");
++	else
++		WL_CONN("no fixed channel required\n");
++
++	if (params->ie && params->ie_len)
++		WL_CONN("ie len: %d\n", params->ie_len);
++	else
++		WL_CONN("no ie specified\n");
++
++	if (params->beacon_interval)
++		WL_CONN("beacon interval: %d\n", params->beacon_interval);
++	else
++		WL_CONN("no beacon interval specified\n");
++
++	if (params->basic_rates)
++		WL_CONN("basic rates: %08X\n", params->basic_rates);
++	else
++		WL_CONN("no basic rates specified\n");
++
++	if (params->privacy)
++		WL_CONN("privacy required\n");
++	else
++		WL_CONN("no privacy required\n");
++
++	/* Configure Privacy for starter */
++	if (params->privacy)
++		wsec |= WEP_ENABLED;
++
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("wsec failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure Beacon Interval for starter */
++	if (params->beacon_interval)
++		bcnprd = params->beacon_interval;
++	else
++		bcnprd = 100;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
++	if (err) {
++		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
++		goto done;
++	}
++
++	/* Configure required join parameter */
++	memset(&join_params, 0, sizeof(struct brcmf_join_params));
++
++	/* SSID */
++	ssid.SSID_len = min_t(u32, params->ssid_len, 32);
++	memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
++	memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	join_params_size = sizeof(join_params.ssid_le);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	/* BSSID */
++	if (params->bssid) {
++		memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
++		join_params_size = sizeof(join_params.ssid_le) +
++				   BRCMF_ASSOC_PARAMS_FIXED_SIZE;
++	} else {
++		memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++	}
++
++	brcmf_update_prof(cfg_priv, NULL,
++			  &join_params.params_le.bssid, WL_PROF_BSSID);
++
++	/* Channel */
++	if (params->channel) {
++		u32 target_channel;
++
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(
++				params->channel->center_freq);
++		if (params->channel_fixed) {
++			/* adding chanspec */
++			brcmf_ch_to_chanspec(cfg_priv->channel,
++				&join_params, &join_params_size);
++		}
++
++		/* set channel for starter */
++		target_channel = cfg_priv->channel;
++		err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
++					  &target_channel);
++		if (err) {
++			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
++			goto done;
++		}
++	} else
++		cfg_priv->channel = 0;
++
++	cfg_priv->ibss_starter = false;
++
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err) {
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++		goto done;
++	}
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	brcmf_link_down(cfg_priv);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static s32 brcmf_set_wpa_version(struct net_device *ndev,
++				 struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
++		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
++	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
++		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
++	else
++		val = WPA_AUTH_DISABLED;
++	WL_CONN("setting wpa_auth to 0x%0x\n", val);
++	err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++	if (err) {
++		WL_ERR("set wpa_auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_versions = sme->crypto.wpa_versions;
++	return err;
++}
++
++static s32 brcmf_set_auth_type(struct net_device *ndev,
++			       struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	switch (sme->auth_type) {
++	case NL80211_AUTHTYPE_OPEN_SYSTEM:
++		val = 0;
++		WL_CONN("open system\n");
++		break;
++	case NL80211_AUTHTYPE_SHARED_KEY:
++		val = 1;
++		WL_CONN("shared key\n");
++		break;
++	case NL80211_AUTHTYPE_AUTOMATIC:
++		val = 2;
++		WL_CONN("automatic\n");
++		break;
++	case NL80211_AUTHTYPE_NETWORK_EAP:
++		WL_CONN("network eap\n");
++	default:
++		val = 2;
++		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
++		break;
++	}
++
++	err = brcmf_dev_intvar_set(ndev, "auth", val);
++	if (err) {
++		WL_ERR("set auth failed (%d)\n", err);
++		return err;
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->auth_type = sme->auth_type;
++	return err;
++}
++
++static s32
++brcmf_set_set_cipher(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 pval = 0;
++	s32 gval = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_ciphers_pairwise) {
++		switch (sme->crypto.ciphers_pairwise[0]) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			pval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			pval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			pval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			pval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher pairwise (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++	}
++	if (sme->crypto.cipher_group) {
++		switch (sme->crypto.cipher_group) {
++		case WLAN_CIPHER_SUITE_WEP40:
++		case WLAN_CIPHER_SUITE_WEP104:
++			gval = WEP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			gval = TKIP_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			gval = AES_ENABLED;
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			gval = AES_ENABLED;
++			break;
++		default:
++			WL_ERR("invalid cipher group (%d)\n",
++			       sme->crypto.cipher_group);
++			return -EINVAL;
++		}
++	}
++
++	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
++	err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
++	sec->cipher_group = sme->crypto.cipher_group;
++
++	return err;
++}
++
++static s32
++brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	s32 val = 0;
++	s32 err = 0;
++
++	if (sme->crypto.n_akm_suites) {
++		err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
++		if (err) {
++			WL_ERR("could not get wpa_auth (%d)\n", err);
++			return err;
++		}
++		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
++			switch (sme->crypto.akm_suites[0]) {
++			case WLAN_AKM_SUITE_8021X:
++				val = WPA2_AUTH_UNSPECIFIED;
++				break;
++			case WLAN_AKM_SUITE_PSK:
++				val = WPA2_AUTH_PSK;
++				break;
++			default:
++				WL_ERR("invalid cipher group (%d)\n",
++				       sme->crypto.cipher_group);
++				return -EINVAL;
++			}
++		}
++
++		WL_CONN("setting wpa_auth to %d\n", val);
++		err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
++		if (err) {
++			WL_ERR("could not set wpa_auth (%d)\n", err);
++			return err;
++		}
++	}
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	sec->wpa_auth = sme->crypto.akm_suites[0];
++
++	return err;
++}
++
++static s32
++brcmf_set_wep_sharedkey(struct net_device *ndev,
++		     struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	struct brcmf_cfg80211_security *sec;
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 err = 0;
++
++	WL_CONN("key len (%d)\n", sme->key_len);
++
++	if (sme->key_len == 0)
++		return 0;
++
++	sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++	WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
++		sec->wpa_versions, sec->cipher_pairwise);
++
++	if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
++		return 0;
++
++	if (sec->cipher_pairwise &
++	    (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
++		memset(&key, 0, sizeof(key));
++		key.len = (u32) sme->key_len;
++		key.index = (u32) sme->key_idx;
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Too long key length (%u)\n", key.len);
++			return -EINVAL;
++		}
++		memcpy(key.data, sme->key, key.len);
++		key.flags = BRCMF_PRIMARY_KEY;
++		switch (sec->cipher_pairwise) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			break;
++		default:
++			WL_ERR("Invalid algorithm (%d)\n",
++			       sme->crypto.ciphers_pairwise[0]);
++			return -EINVAL;
++		}
++		/* Set the new key/index */
++		WL_CONN("key length (%d) key index (%d) algo (%d)\n",
++			key.len, key.index, key.algo);
++		WL_CONN("key \"%s\"\n", key.data);
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++
++		if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
++			WL_CONN("set auth_type to shared key\n");
++			val = 1;	/* shared key */
++			err = brcmf_dev_intvar_set(ndev, "auth", val);
++			if (err) {
++				WL_ERR("set auth failed (%d)\n", err);
++				return err;
++			}
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
++		    struct cfg80211_connect_params *sme)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct ieee80211_channel *chan = sme->channel;
++	struct brcmf_join_params join_params;
++	size_t join_params_size;
++	struct brcmf_ssid ssid;
++
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (!sme->ssid) {
++		WL_ERR("Invalid ssid\n");
++		return -EOPNOTSUPP;
++	}
++
++	set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++
++	if (chan) {
++		cfg_priv->channel =
++			ieee80211_frequency_to_channel(chan->center_freq);
++		WL_CONN("channel (%d), center_req (%d)\n",
++				cfg_priv->channel, chan->center_freq);
++	} else
++		cfg_priv->channel = 0;
++
++	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
++
++	err = brcmf_set_wpa_version(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_wpa_version failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_auth_type(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_auth_type failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_set_cipher(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_set_cipher failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_key_mgmt(ndev, sme);
++	if (err) {
++		WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
++		goto done;
++	}
++
++	err = brcmf_set_wep_sharedkey(ndev, sme);
++	if (err) {
++		WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
++		goto done;
++	}
++
++	memset(&join_params, 0, sizeof(join_params));
++	join_params_size = sizeof(join_params.ssid_le);
++
++	ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
++	memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
++	memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
++	join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
++	brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
++
++	memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
++
++	if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
++		WL_CONN("ssid \"%s\", len (%d)\n",
++		       ssid.SSID, ssid.SSID_len);
++
++	brcmf_ch_to_chanspec(cfg_priv->channel,
++			     &join_params, &join_params_size);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
++			   &join_params, join_params_size);
++	if (err)
++		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
++
++done:
++	if (err)
++		clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
++		       u16 reason_code)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scbval;
++	s32 err = 0;
++
++	WL_TRACE("Enter. Reason code = %d\n", reason_code);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++
++	memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
++	scbval.val = cpu_to_le32(reason_code);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
++			      sizeof(struct brcmf_scb_val_le));
++	if (err)
++		WL_ERR("error (%d)\n", err);
++
++	cfg_priv->link_up = false;
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
++			    enum nl80211_tx_power_setting type, s32 mbm)
++{
++
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	u16 txpwrmw;
++	s32 err = 0;
++	s32 disable = 0;
++	s32 dbm = MBM_TO_DBM(mbm);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	switch (type) {
++	case NL80211_TX_POWER_AUTOMATIC:
++		break;
++	case NL80211_TX_POWER_LIMITED:
++	case NL80211_TX_POWER_FIXED:
++		if (dbm < 0) {
++			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
++			err = -EINVAL;
++			goto done;
++		}
++		break;
++	}
++	/* Make sure radio is off or on as far as software is concerned */
++	disable = WL_RADIO_SW_DISABLE << 16;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
++	if (err)
++		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
++
++	if (dbm > 0xffff)
++		txpwrmw = 0xffff;
++	else
++		txpwrmw = (u16) dbm;
++	err = brcmf_dev_intvar_set(ndev, "qtxpower",
++			(s32) (brcmf_mw_to_qdbm(txpwrmw)));
++	if (err)
++		WL_ERR("qtxpower error (%d)\n", err);
++	cfg_priv->conf->tx_power = dbm;
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	s32 txpwrdbm;
++	u8 result;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		goto done;
++	}
++
++	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
++	*dbm = (s32) brcmf_qdbm_to_mw(result);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
++			       u8 key_idx, bool unicast, bool multicast)
++{
++	u32 index;
++	u32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		goto done;
++	}
++
++	if (wsec & WEP_ENABLED) {
++		/* Just select a new current key */
++		index = key_idx;
++		err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
++					  &index);
++		if (err)
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
++	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	struct brcmf_wsec_key_le key_le;
++	s32 err = 0;
++
++	memset(&key, 0, sizeof(key));
++	key.index = (u32) key_idx;
++	/* Instead of bcast for ea address for default wep keys,
++		 driver needs it to be Null */
++	if (!is_multicast_ether_addr(mac_addr))
++		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
++	key.len = (u32) params->key_len;
++	/* check for key index change */
++	if (key.len == 0) {
++		/* key delete */
++		err = send_key_to_dongle(ndev, &key);
++		if (err)
++			return err;
++	} else {
++		if (key.len > sizeof(key.data)) {
++			WL_ERR("Invalid key length (%d)\n", key.len);
++			return -EINVAL;
++		}
++
++		WL_CONN("Setting the key index %d\n", key.index);
++		memcpy(key.data, params->key, key.len);
++
++		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
++			u8 keybuf[8];
++			memcpy(keybuf, &key.data[24], sizeof(keybuf));
++			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++			memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		}
++
++		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
++		if (params->seq && params->seq_len == 6) {
++			/* rx iv */
++			u8 *ivptr;
++			ivptr = (u8 *) params->seq;
++			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
++			    (ivptr[3] << 8) | ivptr[2];
++			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
++			key.iv_initialized = true;
++		}
++
++		switch (params->cipher) {
++		case WLAN_CIPHER_SUITE_WEP40:
++			key.algo = CRYPTO_ALGO_WEP1;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++			break;
++		case WLAN_CIPHER_SUITE_WEP104:
++			key.algo = CRYPTO_ALGO_WEP128;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++			break;
++		case WLAN_CIPHER_SUITE_TKIP:
++			key.algo = CRYPTO_ALGO_TKIP;
++			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++			break;
++		case WLAN_CIPHER_SUITE_AES_CMAC:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++			break;
++		case WLAN_CIPHER_SUITE_CCMP:
++			key.algo = CRYPTO_ALGO_AES_CCM;
++			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++			break;
++		default:
++			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++			return -EINVAL;
++		}
++		convert_key_from_CPU(&key, &key_le);
++
++		brcmf_netdev_wait_pend8021x(ndev);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
++				      sizeof(key_le));
++		if (err) {
++			WL_ERR("WLC_SET_KEY error (%d)\n", err);
++			return err;
++		}
++	}
++	return err;
++}
++
++static s32
++brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr,
++		    struct key_params *params)
++{
++	struct brcmf_wsec_key key;
++	s32 val;
++	s32 wsec;
++	s32 err = 0;
++	u8 keybuf[8];
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (mac_addr) {
++		WL_TRACE("Exit");
++		return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
++	}
++	memset(&key, 0, sizeof(key));
++
++	key.len = (u32) params->key_len;
++	key.index = (u32) key_idx;
++
++	if (key.len > sizeof(key.data)) {
++		WL_ERR("Too long key length (%u)\n", key.len);
++		err = -EINVAL;
++		goto done;
++	}
++	memcpy(key.data, params->key, key.len);
++
++	key.flags = BRCMF_PRIMARY_KEY;
++	switch (params->cipher) {
++	case WLAN_CIPHER_SUITE_WEP40:
++		key.algo = CRYPTO_ALGO_WEP1;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		break;
++	case WLAN_CIPHER_SUITE_WEP104:
++		key.algo = CRYPTO_ALGO_WEP128;
++		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		break;
++	case WLAN_CIPHER_SUITE_TKIP:
++		memcpy(keybuf, &key.data[24], sizeof(keybuf));
++		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
++		memcpy(&key.data[16], keybuf, sizeof(keybuf));
++		key.algo = CRYPTO_ALGO_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case WLAN_CIPHER_SUITE_AES_CMAC:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	case WLAN_CIPHER_SUITE_CCMP:
++		key.algo = CRYPTO_ALGO_AES_CCM;
++		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
++		break;
++	default:
++		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
++		err = -EINVAL;
++		goto done;
++	}
++
++	err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
++	if (err)
++		goto done;
++
++	val = WEP_ENABLED;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		goto done;
++	}
++
++	val = 1;		/* assume shared key. otherwise 0 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err)
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr)
++{
++	struct brcmf_wsec_key key;
++	s32 err = 0;
++	s32 val;
++	s32 wsec;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&key, 0, sizeof(key));
++
++	key.index = (u32) key_idx;
++	key.flags = BRCMF_PRIMARY_KEY;
++	key.algo = CRYPTO_ALGO_OFF;
++
++	WL_CONN("key index (%d)\n", key_idx);
++
++	/* Set the new key/index */
++	err = send_key_to_dongle(ndev, &key);
++	if (err) {
++		if (err == -EINVAL) {
++			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
++				/* we ignore this key index in this case */
++				WL_ERR("invalid key index (%d)\n", key_idx);
++		}
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;
++	err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
++	if (err) {
++		WL_ERR("get wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	wsec &= ~(WEP_ENABLED);
++	wsec |= val;
++	err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
++	if (err) {
++		WL_ERR("set wsec error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++
++	val = 0;		/* assume open key. otherwise 1 */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
++	if (err) {
++		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
++		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
++		    void (*callback) (void *cookie, struct key_params * params))
++{
++	struct key_params params;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_cfg80211_security *sec;
++	s32 wsec;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	WL_CONN("key index (%d)\n", key_idx);
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(&params, 0, sizeof(params));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
++	if (err) {
++		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
++		/* Ignore this error, may happen during DISASSOC */
++		err = -EAGAIN;
++		goto done;
++	}
++	switch (wsec) {
++	case WEP_ENABLED:
++		sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
++		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP40;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
++		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
++			params.cipher = WLAN_CIPHER_SUITE_WEP104;
++			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
++		}
++		break;
++	case TKIP_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_TKIP;
++		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
++		break;
++	case AES_ENABLED:
++		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
++		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
++		break;
++	default:
++		WL_ERR("Invalid algo (0x%x)\n", wsec);
++		err = -EINVAL;
++		goto done;
++	}
++	callback(cookie, &params);
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
++				    struct net_device *ndev, u8 key_idx)
++{
++	WL_INFO("Not supported\n");
++
++	return -EOPNOTSUPP;
++}
++
++static s32
++brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
++			u8 *mac, struct station_info *sinfo)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct brcmf_scb_val_le scb_val;
++	int rssi;
++	s32 rate;
++	s32 err = 0;
++	u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	if (memcmp(mac, bssid, ETH_ALEN)) {
++		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
++			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
++			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
++			bssid[0], bssid[1], bssid[2], bssid[3],
++			bssid[4], bssid[5]);
++		err = -ENOENT;
++		goto done;
++	}
++
++	/* Report the current tx rate */
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
++	if (err) {
++		WL_ERR("Could not get rate (%d)\n", err);
++	} else {
++		sinfo->filled |= STATION_INFO_TX_BITRATE;
++		sinfo->txrate.legacy = rate * 5;
++		WL_CONN("Rate %d Mbps\n", rate / 2);
++	}
++
++	if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
++		scb_val.val = cpu_to_le32(0);
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
++				      sizeof(struct brcmf_scb_val_le));
++		if (err)
++			WL_ERR("Could not get rssi (%d)\n", err);
++
++		rssi = le32_to_cpu(scb_val.val);
++		sinfo->filled |= STATION_INFO_SIGNAL;
++		sinfo->signal = rssi;
++		WL_CONN("RSSI %d dBm\n", rssi);
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
++			   bool enabled, s32 timeout)
++{
++	s32 pm;
++	s32 err = 0;
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Powersave enable/disable request is coming from the
++	 * cfg80211 even before the interface is up. In that
++	 * scenario, driver will be storing the power save
++	 * preference in cfg_priv struct to apply this to
++	 * FW later while initializing the dongle
++	 */
++	cfg_priv->pwr_save = enabled;
++	if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++
++		WL_INFO("Device is not ready,"
++			"storing the value in cfg_priv struct\n");
++		goto done;
++	}
++
++	pm = enabled ? PM_FAST : PM_OFF;
++	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
++
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
++	if (err) {
++		if (err == -ENODEV)
++			WL_ERR("net_device is not ready yet\n");
++		else
++			WL_ERR("error (%d)\n", err);
++	}
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
++			     const u8 *addr,
++			     const struct cfg80211_bitrate_mask *mask)
++{
++	struct brcm_rateset_le rateset_le;
++	s32 rate;
++	s32 val;
++	s32 err_bg;
++	s32 err_a;
++	u32 legacy;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	/* addr param is always NULL. ignore it */
++	/* Get current rateset */
++	err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
++			      sizeof(rateset_le));
++	if (err) {
++		WL_ERR("could not get current rateset (%d)\n", err);
++		goto done;
++	}
++
++	legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
++	if (!legacy)
++		legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
++			     0xFFFF);
++
++	val = wl_g_rates[legacy - 1].bitrate * 100000;
++
++	if (val < le32_to_cpu(rateset_le.count))
++		/* Select rate by rateset index */
++		rate = rateset_le.rates[val] & 0x7f;
++	else
++		/* Specified rate in bps */
++		rate = val / 500000;
++
++	WL_CONN("rate %d mbps\n", rate / 2);
++
++	/*
++	 *
++	 *      Set rate override,
++	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
++	 */
++	err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
++	err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
++	if (err_bg && err_a) {
++		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
++		err = err_bg | err_a;
++	}
++
++done:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
++				   struct brcmf_bss_info_le *bi)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct cfg80211_bss *bss;
++	struct ieee80211_supported_band *band;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
++		WL_ERR("Bss info is larger than buffer. Discarding\n");
++		return 0;
++	}
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
++			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
++			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
++	WL_CONN("Channel: %d(%d)\n", channel, freq);
++	WL_CONN("Capability: %X\n", notify_capability);
++	WL_CONN("Beacon interval: %d\n", notify_interval);
++	WL_CONN("Signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
++		0, notify_capability, notify_interval, notify_ie,
++		notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss)
++		return -ENOMEM;
++
++	cfg80211_put_bss(bss);
++
++	return err;
++}
++
++static struct brcmf_bss_info_le *
++next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
++{
++	if (bss == NULL)
++		return list->bss_info_le;
++	return (struct brcmf_bss_info_le *)((unsigned long)bss +
++					    le32_to_cpu(bss->length));
++}
++
++static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_scan_results *bss_list;
++	struct brcmf_bss_info_le *bi = NULL;	/* must be initialized */
++	s32 err = 0;
++	int i;
++
++	bss_list = cfg_priv->bss_list;
++	if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
++		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
++		       bss_list->version);
++		return -EOPNOTSUPP;
++	}
++	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
++	for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
++		bi = next_bss_le(bss_list, bi);
++		err = brcmf_inform_single_bss(cfg_priv, bi);
++		if (err)
++			break;
++	}
++	return err;
++}
++
++static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
++			  struct net_device *ndev, const u8 *bssid)
++{
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct ieee80211_channel *notify_channel;
++	struct brcmf_bss_info_le *bi = NULL;
++	struct ieee80211_supported_band *band;
++	struct cfg80211_bss *bss;
++	u8 *buf = NULL;
++	s32 err = 0;
++	u16 channel;
++	u32 freq;
++	u16 notify_capability;
++	u16 notify_interval;
++	u8 *notify_ie;
++	size_t notify_ielen;
++	s32 notify_signal;
++
++	WL_TRACE("Enter\n");
++
++	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (buf == NULL) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
++	if (err) {
++		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
++		goto CleanUp;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(buf + 4);
++
++	channel = bi->ctl_ch ? bi->ctl_ch :
++				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	notify_capability = le16_to_cpu(bi->capability);
++	notify_interval = le16_to_cpu(bi->beacon_period);
++	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
++	notify_ielen = le32_to_cpu(bi->ie_length);
++	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
++
++	WL_CONN("channel: %d(%d)\n", channel, freq);
++	WL_CONN("capability: %X\n", notify_capability);
++	WL_CONN("beacon interval: %d\n", notify_interval);
++	WL_CONN("signal: %d\n", notify_signal);
++
++	bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
++		0, notify_capability, notify_interval,
++		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
++
++	if (!bss) {
++		err = -ENOMEM;
++		goto CleanUp;
++	}
++
++	cfg80211_put_bss(bss);
++
++CleanUp:
++
++	kfree(buf);
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return cfg_priv->conf->mode == WL_MODE_IBSS;
++}
++
++/*
++ * Traverse a string of 1-byte tag/1-byte length/variable-length value
++ * triples, returning a pointer to the substring whose first element
++ * matches tag
++ */
++static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
++{
++	struct brcmf_tlv *elt;
++	int totlen;
++
++	elt = (struct brcmf_tlv *) buf;
++	totlen = buflen;
++
++	/* find tagged parameter */
++	while (totlen >= 2) {
++		int len = elt->len;
++
++		/* validate remaining totlen */
++		if ((elt->id == key) && (totlen >= (len + 2)))
++			return elt;
++
++		elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
++		totlen -= (len + 2);
++	}
++
++	return NULL;
++}
++
++static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_bss_info_le *bi;
++	struct brcmf_ssid *ssid;
++	struct brcmf_tlv *tim;
++	u16 beacon_interval;
++	u8 dtim_period;
++	size_t ie_len;
++	u8 *ie;
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (brcmf_is_ibssmode(cfg_priv))
++		return err;
++
++	ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
++
++	*(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
++			cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
++	if (err) {
++		WL_ERR("Could not get bss info %d\n", err);
++		goto update_bss_info_out;
++	}
++
++	bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
++	err = brcmf_inform_single_bss(cfg_priv, bi);
++	if (err)
++		goto update_bss_info_out;
++
++	ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
++	ie_len = le32_to_cpu(bi->ie_length);
++	beacon_interval = le16_to_cpu(bi->beacon_period);
++
++	tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
++	if (tim)
++		dtim_period = tim->data[1];
++	else {
++		/*
++		* active scan was done so we could not get dtim
++		* information out of probe response.
++		* so we speficially query dtim information to dongle.
++		*/
++		u32 var;
++		err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
++					   "dtim_assoc", &var);
++		if (err) {
++			WL_ERR("wl dtim_assoc failed (%d)\n", err);
++			goto update_bss_info_out;
++		}
++		dtim_period = (u8)var;
++	}
++
++	brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
++	brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
++
++update_bss_info_out:
++	WL_TRACE("Exit");
++	return err;
++}
++
++static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	struct brcmf_ssid ssid;
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++
++		if (iscan->timer_on) {
++			del_timer_sync(&iscan->timer);
++			iscan->timer_on = 0;
++		}
++
++		cancel_work_sync(&iscan->work);
++
++		/* Abort iscan running in FW */
++		memset(&ssid, 0, sizeof(ssid));
++		brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
++	}
++}
++
++static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
++					bool aborted)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		return;
++	}
++	if (cfg_priv->scan_request) {
++		WL_SCAN("ISCAN Completed scan: %s\n",
++				aborted ? "Aborted" : "Done");
++		cfg80211_scan_done(cfg_priv->scan_request, aborted);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++	cfg_priv->iscan_kickstart = false;
++}
++
++static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
++{
++	if (iscan->state != WL_ISCAN_STATE_IDLE) {
++		WL_SCAN("wake up iscan\n");
++		schedule_work(&iscan->work);
++		return 0;
++	}
++
++	return -EIO;
++}
++
++static s32
++brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
++		     struct brcmf_scan_results **bss_list)
++{
++	struct brcmf_iscan_results list;
++	struct brcmf_scan_results *results;
++	struct brcmf_scan_results_le *results_le;
++	struct brcmf_iscan_results *list_buf;
++	s32 err = 0;
++
++	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
++	list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
++	results = &list_buf->results;
++	results_le = &list_buf->results_le;
++	results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
++	results->version = 0;
++	results->count = 0;
++
++	memset(&list, 0, sizeof(list));
++	list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
++	err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
++				     BRCMF_ISCAN_RESULTS_FIXED_SIZE,
++				     iscan->scan_buf, WL_ISCAN_BUF_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	results->buflen = le32_to_cpu(results_le->buflen);
++	results->version = le32_to_cpu(results_le->version);
++	results->count = le32_to_cpu(results_le->count);
++	WL_SCAN("results->count = %d\n", results_le->count);
++	WL_SCAN("results->buflen = %d\n", results_le->buflen);
++	*status = le32_to_cpu(list_buf->status_le);
++	WL_SCAN("status = %d\n", *status);
++	*bss_list = results;
++
++	return err;
++}
++
++static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_inform_bss(cfg_priv);
++	brcmf_notify_iscan_complete(iscan, false);
++
++	return err;
++}
++
++static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	brcmf_inform_bss(cfg_priv);
++	brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
++	/* Reschedule the timer */
++	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
++	iscan->timer_on = 1;
++
++	return err;
++}
++
++static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
++	s32 err = 0;
++
++	iscan->state = WL_ISCAN_STATE_IDLE;
++	brcmf_notify_iscan_complete(iscan, true);
++
++	return err;
++}
++
++static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			container_of(work, struct brcmf_cfg80211_iscan_ctrl,
++				     work);
++	struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
++	struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
++	u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
++
++	if (iscan->timer_on) {
++		del_timer_sync(&iscan->timer);
++		iscan->timer_on = 0;
++	}
++
++	if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
++		status = BRCMF_SCAN_RESULTS_ABORTED;
++		WL_ERR("Abort iscan\n");
++	}
++
++	el->handler[status](cfg_priv);
++}
++
++static void brcmf_iscan_timer(unsigned long data)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan =
++			(struct brcmf_cfg80211_iscan_ctrl *)data;
++
++	if (iscan) {
++		iscan->timer_on = 0;
++		WL_SCAN("timer expired\n");
++		brcmf_wakeup_iscan(iscan);
++	}
++}
++
++static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++
++	if (cfg_priv->iscan_on) {
++		iscan->state = WL_ISCAN_STATE_IDLE;
++		INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
++	}
++
++	return 0;
++}
++
++static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
++	el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
++	el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
++	el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
++	el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
++}
++
++static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
++	int err = 0;
++
++	if (cfg_priv->iscan_on) {
++		iscan->ndev = cfg_to_ndev(cfg_priv);
++		brcmf_init_iscan_eloop(&iscan->el);
++		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
++		init_timer(&iscan->timer);
++		iscan->timer.data = (unsigned long) iscan;
++		iscan->timer.function = brcmf_iscan_timer;
++		err = brcmf_invoke_iscan(cfg_priv);
++		if (!err)
++			iscan->data = cfg_priv;
++	}
++
++	return err;
++}
++
++static __always_inline void brcmf_delay(u32 ms)
++{
++	if (ms < 1000 / HZ) {
++		cond_resched();
++		mdelay(ms);
++	} else {
++		msleep(ms);
++	}
++}
++
++static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the resume for
++	 * any driver error conditions
++	 */
++	WL_TRACE("Enter\n");
++
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
++
++	WL_TRACE("Exit\n");
++	return 0;
++}
++
++static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
++				  struct cfg80211_wowlan *wow)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++
++	WL_TRACE("Enter\n");
++
++	/*
++	 * Check for WL_STATUS_READY before any function call which
++	 * could result is bus access. Don't block the suspend for
++	 * any driver error conditions
++	 */
++
++	/*
++	 * While going to suspend if associated with AP disassociate
++	 * from AP to save power while system is in suspended state
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP"
++			" while entering suspend state\n");
++		brcmf_link_down(cfg_priv);
++
++		/*
++		 * Make sure WPA_Supplicant receives all the event
++		 * generated due to DISASSOC call to the fw to keep
++		 * the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
++		brcmf_term_iscan(cfg_priv);
++
++	if (cfg_priv->scan_request) {
++		/* Indidate scan abort to cfg80211 layer */
++		WL_INFO("Terminating scan in progress\n");
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	/* Turn off watchdog timer */
++	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Enable MPC\n");
++		brcmf_set_mpc(ndev, 1);
++	}
++
++	WL_TRACE("Exit\n");
++
++	return 0;
++}
++
++static __used s32
++brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 buflen;
++
++	buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
++			       WL_DCMD_LEN_MAX);
++	BUG_ON(!buflen);
++
++	return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
++			       buflen);
++}
++
++static s32
++brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
++		  s32 buf_len)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++	u32 len;
++	s32 err = 0;
++
++	len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
++			    WL_DCMD_LEN_MAX);
++	BUG_ON(!len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
++			      WL_DCMD_LEN_MAX);
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++	memcpy(buf, cfg_priv->dcmd_buf, buf_len);
++
++	return err;
++}
++
++static __used s32
++brcmf_update_pmklist(struct net_device *ndev,
++		     struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
++{
++	int i, j;
++	int pmkid_len;
++
++	pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
++
++	WL_CONN("No of elements %d\n", pmkid_len);
++	for (i = 0; i < pmkid_len; i++) {
++		WL_CONN("PMKID[%d]: %pM =\n", i,
++			&pmk_list->pmkids.pmkid[i].BSSID);
++		for (j = 0; j < WLAN_PMKID_LEN; j++)
++			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
++	}
++
++	if (!err)
++		brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
++					sizeof(*pmk_list));
++
++	return err;
++}
++
++static s32
++brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++			 struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
++	s32 err = 0;
++	int i;
++	int pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	pmkid_len = le32_to_cpu(pmkids->npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
++			break;
++	if (i < WL_NUM_PMKIDS_MAX) {
++		memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
++		memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++		if (i == pmkid_len) {
++			pmkid_len++;
++			pmkids->npmkid = cpu_to_le32(pmkid_len);
++		}
++	} else
++		err = -EINVAL;
++
++	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
++		pmkids->pmkid[pmkid_len].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
++		      struct cfg80211_pmksa *pmksa)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	struct pmkid_list pmkid;
++	s32 err = 0;
++	int i, pmkid_len;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
++	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
++
++	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
++	       &pmkid.pmkid[0].BSSID);
++	for (i = 0; i < WLAN_PMKID_LEN; i++)
++		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
++
++	pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
++	for (i = 0; i < pmkid_len; i++)
++		if (!memcmp
++		    (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++		     ETH_ALEN))
++			break;
++
++	if ((pmkid_len > 0)
++	    && (i < pmkid_len)) {
++		memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
++		       sizeof(struct pmkid));
++		for (; i < (pmkid_len - 1); i++) {
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
++			       ETH_ALEN);
++			memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
++			       &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
++			       WLAN_PMKID_LEN);
++		}
++		cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
++	} else
++		err = -EINVAL;
++
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static s32
++brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++	if (!check_sys_up(wiphy))
++		return -EIO;
++
++	memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
++	err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
++
++	WL_TRACE("Exit\n");
++	return err;
++
++}
++
++static struct cfg80211_ops wl_cfg80211_ops = {
++	.change_virtual_intf = brcmf_cfg80211_change_iface,
++	.scan = brcmf_cfg80211_scan,
++	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
++	.join_ibss = brcmf_cfg80211_join_ibss,
++	.leave_ibss = brcmf_cfg80211_leave_ibss,
++	.get_station = brcmf_cfg80211_get_station,
++	.set_tx_power = brcmf_cfg80211_set_tx_power,
++	.get_tx_power = brcmf_cfg80211_get_tx_power,
++	.add_key = brcmf_cfg80211_add_key,
++	.del_key = brcmf_cfg80211_del_key,
++	.get_key = brcmf_cfg80211_get_key,
++	.set_default_key = brcmf_cfg80211_config_default_key,
++	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
++	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
++	.set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
++	.connect = brcmf_cfg80211_connect,
++	.disconnect = brcmf_cfg80211_disconnect,
++	.suspend = brcmf_cfg80211_suspend,
++	.resume = brcmf_cfg80211_resume,
++	.set_pmksa = brcmf_cfg80211_set_pmksa,
++	.del_pmksa = brcmf_cfg80211_del_pmksa,
++	.flush_pmksa = brcmf_cfg80211_flush_pmksa
++};
++
++static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
++{
++	s32 err = 0;
++
++	switch (mode) {
++	case WL_MODE_BSS:
++		return NL80211_IFTYPE_STATION;
++	case WL_MODE_IBSS:
++		return NL80211_IFTYPE_ADHOC;
++	default:
++		return NL80211_IFTYPE_UNSPECIFIED;
++	}
++
++	return err;
++}
++
++static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
++					  struct device *ndev)
++{
++	struct wireless_dev *wdev;
++	s32 err = 0;
++
++	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
++	if (!wdev)
++		return ERR_PTR(-ENOMEM);
++
++	wdev->wiphy =
++	    wiphy_new(&wl_cfg80211_ops,
++		      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
++	if (!wdev->wiphy) {
++		WL_ERR("Could not allocate wiphy device\n");
++		err = -ENOMEM;
++		goto wiphy_new_out;
++	}
++	set_wiphy_dev(wdev->wiphy, ndev);
++	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
++	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
++	wdev->wiphy->interface_modes =
++	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
++	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
++	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
++						* it as 11a by default.
++						* This will be updated with
++						* 11n phy tables in
++						* "ifconfig up"
++						* if phy has 11n capability
++						*/
++	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
++	wdev->wiphy->cipher_suites = __wl_cipher_suites;
++	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
++	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
++								 * save mode
++								 * by default
++								 */
++	err = wiphy_register(wdev->wiphy);
++	if (err < 0) {
++		WL_ERR("Could not register wiphy device (%d)\n", err);
++		goto wiphy_register_out;
++	}
++	return wdev;
++
++wiphy_register_out:
++	wiphy_free(wdev->wiphy);
++
++wiphy_new_out:
++	kfree(wdev);
++
++	return ERR_PTR(err);
++}
++
++static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wireless_dev *wdev = cfg_priv->wdev;
++
++	if (!wdev) {
++		WL_ERR("wdev is invalid\n");
++		return;
++	}
++	wiphy_unregister(wdev->wiphy);
++	wiphy_free(wdev->wiphy);
++	kfree(wdev);
++	cfg_priv->wdev = NULL;
++}
++
++static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
++			    const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing set ssid\n");
++		cfg_priv->link_up = true;
++		return true;
++	}
++
++	return false;
++}
++
++static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
++			      const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u16 flags = be16_to_cpu(e->flags);
++
++	if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
++		WL_CONN("Processing link down\n");
++		return true;
++	}
++	return false;
++}
++
++static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
++			       const struct brcmf_event_msg *e)
++{
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
++		WL_CONN("Processing Link %s & no network found\n",
++				be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
++				"up" : "down");
++		return true;
++	}
++
++	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
++		WL_CONN("Processing connecting & no network found\n");
++		return true;
++	}
++
++	return false;
++}
++
++static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++
++	kfree(conn_info->req_ie);
++	conn_info->req_ie = NULL;
++	conn_info->req_ie_len = 0;
++	kfree(conn_info->resp_ie);
++	conn_info->resp_ie = NULL;
++	conn_info->resp_ie_len = 0;
++}
++
++static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev = cfg_to_ndev(cfg_priv);
++	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	u32 req_len;
++	u32 resp_len;
++	s32 err = 0;
++
++	brcmf_clear_assoc_ies(cfg_priv);
++
++	err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
++				WL_ASSOC_INFO_MAX);
++	if (err) {
++		WL_ERR("could not get assoc info (%d)\n", err);
++		return err;
++	}
++	assoc_info =
++		(struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
++	req_len = le32_to_cpu(assoc_info->req_len);
++	resp_len = le32_to_cpu(assoc_info->resp_len);
++	if (req_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc req (%d)\n", err);
++			return err;
++		}
++		conn_info->req_ie_len = req_len;
++		conn_info->req_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->req_ie_len = 0;
++		conn_info->req_ie = NULL;
++	}
++	if (resp_len) {
++		err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
++					   cfg_priv->extra_buf,
++					   WL_ASSOC_INFO_MAX);
++		if (err) {
++			WL_ERR("could not get assoc resp (%d)\n", err);
++			return err;
++		}
++		conn_info->resp_ie_len = resp_len;
++		conn_info->resp_ie =
++		    kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
++			    GFP_KERNEL);
++	} else {
++		conn_info->resp_ie_len = 0;
++		conn_info->resp_ie = NULL;
++	}
++	WL_CONN("req len (%d) resp len (%d)\n",
++	       conn_info->req_ie_len, conn_info->resp_ie_len);
++
++	return err;
++}
++
++static s32
++brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev,
++		       const struct brcmf_event_msg *e)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
++	struct brcmf_channel_info_le channel_le;
++	struct ieee80211_channel *notify_channel;
++	struct ieee80211_supported_band *band;
++	u32 freq;
++	s32 err = 0;
++	u32 target_channel;
++
++	WL_TRACE("Enter\n");
++
++	brcmf_get_assoc_ies(cfg_priv);
++	brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
++	brcmf_update_bss_info(cfg_priv);
++
++	brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
++			sizeof(channel_le));
++
++	target_channel = le32_to_cpu(channel_le.target_channel);
++	WL_CONN("Roamed to channel %d\n", target_channel);
++
++	if (target_channel <= CH_MAX_2G_CHANNEL)
++		band = wiphy->bands[IEEE80211_BAND_2GHZ];
++	else
++		band = wiphy->bands[IEEE80211_BAND_5GHZ];
++
++	freq = ieee80211_channel_to_frequency(target_channel, band->band);
++	notify_channel = ieee80211_get_channel(wiphy, freq);
++
++	cfg80211_roamed(ndev, notify_channel,
++			(u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
++			conn_info->req_ie, conn_info->req_ie_len,
++			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
++	WL_CONN("Report roaming result\n");
++
++	set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
++		       struct net_device *ndev, const struct brcmf_event_msg *e,
++		       bool completed)
++{
++	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
++		if (completed) {
++			brcmf_get_assoc_ies(cfg_priv);
++			brcmf_update_prof(cfg_priv, NULL, &e->addr,
++					  WL_PROF_BSSID);
++			brcmf_update_bss_info(cfg_priv);
++		}
++		cfg80211_connect_result(ndev,
++					(u8 *)brcmf_read_prof(cfg_priv,
++							      WL_PROF_BSSID),
++					conn_info->req_ie,
++					conn_info->req_ie_len,
++					conn_info->resp_ie,
++					conn_info->resp_ie_len,
++					completed ? WLAN_STATUS_SUCCESS :
++						    WLAN_STATUS_AUTH_TIMEOUT,
++					GFP_KERNEL);
++		if (completed)
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		WL_CONN("Report connect result - connection %s\n",
++				completed ? "succeeded" : "failed");
++	}
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++
++	if (brcmf_is_linkup(cfg_priv, e)) {
++		WL_CONN("Linkup\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
++				WL_PROF_BSSID);
++			wl_inform_ibss(cfg_priv, ndev, e->addr);
++			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
++		} else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	} else if (brcmf_is_linkdown(cfg_priv, e)) {
++		WL_CONN("Linkdown\n");
++		if (brcmf_is_ibssmode(cfg_priv)) {
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status))
++				brcmf_link_down(cfg_priv);
++		} else {
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++			if (test_and_clear_bit(WL_STATUS_CONNECTED,
++				&cfg_priv->status)) {
++				cfg80211_disconnected(ndev, 0, NULL, 0,
++					GFP_KERNEL);
++				brcmf_link_down(cfg_priv);
++			}
++		}
++		brcmf_init_prof(cfg_priv->profile);
++	} else if (brcmf_is_nonetwork(cfg_priv, e)) {
++		if (brcmf_is_ibssmode(cfg_priv))
++			clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, false);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
++			    struct net_device *ndev,
++			    const struct brcmf_event_msg *e, void *data)
++{
++	s32 err = 0;
++	u32 event = be32_to_cpu(e->event_type);
++	u32 status = be32_to_cpu(e->status);
++
++	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
++		if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
++			brcmf_bss_roaming_done(cfg_priv, ndev, e);
++		else
++			brcmf_bss_connect_done(cfg_priv, ndev, e, true);
++	}
++
++	return err;
++}
++
++static s32
++brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
++			struct net_device *ndev,
++			const struct brcmf_event_msg *e, void *data)
++{
++	u16 flags = be16_to_cpu(e->flags);
++	enum nl80211_key_type key_type;
++
++	if (flags & BRCMF_EVENT_MSG_GROUP)
++		key_type = NL80211_KEYTYPE_GROUP;
++	else
++		key_type = NL80211_KEYTYPE_PAIRWISE;
++
++	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
++				     NULL, GFP_KERNEL);
++
++	return 0;
++}
++
++static s32
++brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
++			 struct net_device *ndev,
++			 const struct brcmf_event_msg *e, void *data)
++{
++	struct brcmf_channel_info_le channel_inform_le;
++	struct brcmf_scan_results_le *bss_list_le;
++	u32 len = WL_SCAN_BUF_MAX;
++	s32 err = 0;
++	bool scan_abort = false;
++	u32 scan_channel;
++
++	WL_TRACE("Enter\n");
++
++	if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
++		WL_TRACE("Exit\n");
++		return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
++	}
++
++	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
++		WL_ERR("Scan complete while device not scanning\n");
++		scan_abort = true;
++		err = -EINVAL;
++		goto scan_done_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
++			      sizeof(channel_inform_le));
++	if (err) {
++		WL_ERR("scan busy (%d)\n", err);
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
++	if (scan_channel)
++		WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
++	cfg_priv->bss_list = cfg_priv->scan_results;
++	bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
++
++	memset(cfg_priv->scan_results, 0, len);
++	bss_list_le->buflen = cpu_to_le32(len);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
++			      cfg_priv->scan_results, len);
++	if (err) {
++		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
++		err = -EINVAL;
++		scan_abort = true;
++		goto scan_done_out;
++	}
++	cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
++	cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
++	cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
++
++	err = brcmf_inform_bss(cfg_priv);
++	if (err) {
++		scan_abort = true;
++		goto scan_done_out;
++	}
++
++scan_done_out:
++	if (cfg_priv->scan_request) {
++		WL_SCAN("calling cfg80211_scan_done\n");
++		cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
++		brcmf_set_mpc(ndev, 1);
++		cfg_priv->scan_request = NULL;
++	}
++
++	WL_TRACE("Exit\n");
++
++	return err;
++}
++
++static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
++{
++	conf->mode = (u32)-1;
++	conf->frag_threshold = (u32)-1;
++	conf->rts_threshold = (u32)-1;
++	conf->retry_short = (u32)-1;
++	conf->retry_long = (u32)-1;
++	conf->tx_power = -1;
++}
++
++static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
++{
++	memset(el, 0, sizeof(*el));
++	el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
++	el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
++	el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
++	el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
++	el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
++}
++
++static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	kfree(cfg_priv->scan_results);
++	cfg_priv->scan_results = NULL;
++	kfree(cfg_priv->bss_info);
++	cfg_priv->bss_info = NULL;
++	kfree(cfg_priv->conf);
++	cfg_priv->conf = NULL;
++	kfree(cfg_priv->profile);
++	cfg_priv->profile = NULL;
++	kfree(cfg_priv->scan_req_int);
++	cfg_priv->scan_req_int = NULL;
++	kfree(cfg_priv->dcmd_buf);
++	cfg_priv->dcmd_buf = NULL;
++	kfree(cfg_priv->extra_buf);
++	cfg_priv->extra_buf = NULL;
++	kfree(cfg_priv->iscan);
++	cfg_priv->iscan = NULL;
++	kfree(cfg_priv->pmk_list);
++	cfg_priv->pmk_list = NULL;
++}
++
++static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->scan_results)
++		goto init_priv_mem_out;
++	cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
++	if (!cfg_priv->conf)
++		goto init_priv_mem_out;
++	cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
++	if (!cfg_priv->profile)
++		goto init_priv_mem_out;
++	cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
++	if (!cfg_priv->bss_info)
++		goto init_priv_mem_out;
++	cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
++					 GFP_KERNEL);
++	if (!cfg_priv->scan_req_int)
++		goto init_priv_mem_out;
++	cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
++	if (!cfg_priv->dcmd_buf)
++		goto init_priv_mem_out;
++	cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
++	if (!cfg_priv->extra_buf)
++		goto init_priv_mem_out;
++	cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
++	if (!cfg_priv->iscan)
++		goto init_priv_mem_out;
++	cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
++	if (!cfg_priv->pmk_list)
++		goto init_priv_mem_out;
++
++	return 0;
++
++init_priv_mem_out:
++	brcmf_deinit_priv_mem(cfg_priv);
++
++	return -ENOMEM;
++}
++
++/*
++* retrieve first queued event from head
++*/
++
++static struct brcmf_cfg80211_event_q *brcmf_deq_event(
++	struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e = NULL;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	if (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++
++	return e;
++}
++
++/*
++*	push event to tail of the queue
++*
++*	remark: this function may not sleep as it is called in atomic context.
++*/
++
++static s32
++brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
++		const struct brcmf_event_msg *msg)
++{
++	struct brcmf_cfg80211_event_q *e;
++	s32 err = 0;
++	ulong flags;
++
++	e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
++	if (!e)
++		return -ENOMEM;
++
++	e->etype = event;
++	memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
++
++	spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
++	list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
++	spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
++
++	return err;
++}
++
++static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
++{
++	kfree(e);
++}
++
++static void brcmf_cfg80211_event_handler(struct work_struct *work)
++{
++	struct brcmf_cfg80211_priv *cfg_priv =
++			container_of(work, struct brcmf_cfg80211_priv,
++				     event_work);
++	struct brcmf_cfg80211_event_q *e;
++
++	e = brcmf_deq_event(cfg_priv);
++	if (unlikely(!e)) {
++		WL_ERR("event queue empty...\n");
++		return;
++	}
++
++	do {
++		WL_INFO("event type (%d)\n", e->etype);
++		if (cfg_priv->el.handler[e->etype])
++			cfg_priv->el.handler[e->etype](cfg_priv,
++						       cfg_to_ndev(cfg_priv),
++						       &e->emsg, e->edata);
++		else
++			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
++		brcmf_put_event(e);
++	} while ((e = brcmf_deq_event(cfg_priv)));
++
++}
++
++static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	spin_lock_init(&cfg_priv->evt_q_lock);
++	INIT_LIST_HEAD(&cfg_priv->evt_q_list);
++}
++
++static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct brcmf_cfg80211_event_q *e;
++
++	spin_lock_irq(&cfg_priv->evt_q_lock);
++	while (!list_empty(&cfg_priv->evt_q_list)) {
++		e = list_first_entry(&cfg_priv->evt_q_list,
++				     struct brcmf_cfg80211_event_q, evt_q_list);
++		list_del(&e->evt_q_list);
++		kfree(e);
++	}
++	spin_unlock_irq(&cfg_priv->evt_q_lock);
++}
++
++static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	cfg_priv->scan_request = NULL;
++	cfg_priv->pwr_save = true;
++	cfg_priv->iscan_on = true;	/* iscan on & off switch.
++				 we enable iscan per default */
++	cfg_priv->roam_on = true;	/* roam on & off switch.
++				 we enable roam per default */
++
++	cfg_priv->iscan_kickstart = false;
++	cfg_priv->active_scan = true;	/* we do active scan for
++				 specific scan per default */
++	cfg_priv->dongle_up = false;	/* dongle is not up yet */
++	brcmf_init_eq(cfg_priv);
++	err = brcmf_init_priv_mem(cfg_priv);
++	if (err)
++		return err;
++	INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
++	brcmf_init_eloop_handler(&cfg_priv->el);
++	mutex_init(&cfg_priv->usr_sync);
++	err = brcmf_init_iscan(cfg_priv);
++	if (err)
++		return err;
++	brcmf_init_conf(cfg_priv->conf);
++	brcmf_init_prof(cfg_priv->profile);
++	brcmf_link_down(cfg_priv);
++
++	return err;
++}
++
++static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	cancel_work_sync(&cfg_priv->event_work);
++	cfg_priv->dongle_up = false;	/* dongle down */
++	brcmf_flush_eq(cfg_priv);
++	brcmf_link_down(cfg_priv);
++	brcmf_term_iscan(cfg_priv);
++	brcmf_deinit_priv_mem(cfg_priv);
++}
++
++struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++						 struct device *busdev,
++						 void *data)
++{
++	struct wireless_dev *wdev;
++	struct brcmf_cfg80211_priv *cfg_priv;
++	struct brcmf_cfg80211_iface *ci;
++	struct brcmf_cfg80211_dev *cfg_dev;
++	s32 err = 0;
++
++	if (!ndev) {
++		WL_ERR("ndev is invalid\n");
++		return NULL;
++	}
++	cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
++	if (!cfg_dev)
++		return NULL;
++
++	wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
++	if (IS_ERR(wdev)) {
++		kfree(cfg_dev);
++		return NULL;
++	}
++
++	wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
++	cfg_priv = wdev_to_cfg(wdev);
++	cfg_priv->wdev = wdev;
++	cfg_priv->pub = data;
++	ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
++	ci->cfg_priv = cfg_priv;
++	ndev->ieee80211_ptr = wdev;
++	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
++	wdev->netdev = ndev;
++	err = wl_init_priv(cfg_priv);
++	if (err) {
++		WL_ERR("Failed to init iwm_priv (%d)\n", err);
++		goto cfg80211_attach_out;
++	}
++	brcmf_set_drvdata(cfg_dev, ci);
++
++	return cfg_dev;
++
++cfg80211_attach_out:
++	brcmf_free_wdev(cfg_priv);
++	kfree(cfg_dev);
++	return NULL;
++}
++
++void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++
++	wl_deinit_priv(cfg_priv);
++	brcmf_free_wdev(cfg_priv);
++	brcmf_set_drvdata(cfg_dev, NULL);
++	kfree(cfg_dev);
++}
++
++void
++brcmf_cfg80211_event(struct net_device *ndev,
++		  const struct brcmf_event_msg *e, void *data)
++{
++	u32 event_type = be32_to_cpu(e->event_type);
++	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
++
++	if (!brcmf_enq_event(cfg_priv, event_type, e))
++		schedule_work(&cfg_priv->event_work);
++}
++
++static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
++{
++	s32 infra = 0;
++	s32 err = 0;
++
++	switch (iftype) {
++	case NL80211_IFTYPE_MONITOR:
++	case NL80211_IFTYPE_WDS:
++		WL_ERR("type (%d) : currently we do not support this mode\n",
++		       iftype);
++		err = -EINVAL;
++		return err;
++	case NL80211_IFTYPE_ADHOC:
++		infra = 0;
++		break;
++	case NL80211_IFTYPE_STATION:
++		infra = 1;
++		break;
++	default:
++		err = -EINVAL;
++		WL_ERR("invalid type (%d)\n", iftype);
++		return err;
++	}
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
++	if (err) {
++		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
++		return err;
++	}
++
++	return 0;
++}
++
++static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
++{
++	/* Room for "event_msgs" + '\0' + bitvec */
++	s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
++	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
++	s32 err = 0;
++
++	WL_TRACE("Enter\n");
++
++	/* Setup event_msgs */
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Get event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++	memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
++
++	setbit(eventmask, BRCMF_E_SET_SSID);
++	setbit(eventmask, BRCMF_E_ROAM);
++	setbit(eventmask, BRCMF_E_PRUNE);
++	setbit(eventmask, BRCMF_E_AUTH);
++	setbit(eventmask, BRCMF_E_REASSOC);
++	setbit(eventmask, BRCMF_E_REASSOC_IND);
++	setbit(eventmask, BRCMF_E_DEAUTH_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC_IND);
++	setbit(eventmask, BRCMF_E_DISASSOC);
++	setbit(eventmask, BRCMF_E_JOIN);
++	setbit(eventmask, BRCMF_E_ASSOC_IND);
++	setbit(eventmask, BRCMF_E_PSK_SUP);
++	setbit(eventmask, BRCMF_E_LINK);
++	setbit(eventmask, BRCMF_E_NDIS_LINK);
++	setbit(eventmask, BRCMF_E_MIC_ERROR);
++	setbit(eventmask, BRCMF_E_PMKID_CACHE);
++	setbit(eventmask, BRCMF_E_TXFAIL);
++	setbit(eventmask, BRCMF_E_JOIN_START);
++	setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
++
++	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
++			iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("Set event_msgs error (%d)\n", err);
++		goto dongle_eventmsg_out;
++	}
++
++dongle_eventmsg_out:
++	WL_TRACE("Exit\n");
++	return err;
++}
++
++static s32
++brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
++{
++	s8 iovbuf[32];
++	s32 err = 0;
++	__le32 roamtrigger[2];
++	__le32 roam_delta[2];
++	__le32 bcn_to_le;
++	__le32 roamvar_le;
++
++	/*
++	 * Setup timeout if Beacons are lost and roam is
++	 * off to report link down
++	 */
++	if (roamvar) {
++		bcn_to_le = cpu_to_le32(bcn_timeout);
++		brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
++			sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
++		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
++				   iovbuf, sizeof(iovbuf));
++		if (err) {
++			WL_ERR("bcn_timeout error (%d)\n", err);
++			goto dongle_rom_out;
++		}
++	}
++
++	/*
++	 * Enable/Disable built-in roaming to allow supplicant
++	 * to take care of roaming
++	 */
++	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
++	roamvar_le = cpu_to_le32(roamvar);
++	brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
++				sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
++	if (err) {
++		WL_ERR("roam_off error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
++	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
++			(void *)roamtrigger, sizeof(roamtrigger));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
++	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
++				(void *)roam_delta, sizeof(roam_delta));
++	if (err) {
++		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
++		goto dongle_rom_out;
++	}
++
++dongle_rom_out:
++	return err;
++}
++
++static s32
++brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
++		      s32 scan_unassoc_time, s32 scan_passive_time)
++{
++	s32 err = 0;
++	__le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
++	__le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
++	__le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
++			   &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan assoc time is not supported\n");
++		else
++			WL_ERR("Scan assoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
++			   &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan unassoc time is not supported\n");
++		else
++			WL_ERR("Scan unassoc time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
++			   &scan_passive_tm_le, sizeof(scan_passive_tm_le));
++	if (err) {
++		if (err == -EOPNOTSUPP)
++			WL_INFO("Scan passive time is not supported\n");
++		else
++			WL_ERR("Scan passive time error (%d)\n", err);
++		goto dongle_scantime_out;
++	}
++
++dongle_scantime_out:
++	return err;
++}
++
++static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct wiphy *wiphy;
++	s32 phy_list;
++	s8 phy;
++	s32 err = 0;
++
++	err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
++			      &phy_list, sizeof(phy_list));
++	if (err) {
++		WL_ERR("error (%d)\n", err);
++		return err;
++	}
++
++	phy = ((char *)&phy_list)[1];
++	WL_INFO("%c phy\n", phy);
++	if (phy == 'n' || phy == 'a') {
++		wiphy = cfg_to_wiphy(cfg_priv);
++		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
++	}
++
++	return err;
++}
++
++static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	return wl_update_wiphybands(cfg_priv);
++}
++
++static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	struct net_device *ndev;
++	struct wireless_dev *wdev;
++	s32 power_mode;
++	s32 err = 0;
++
++	if (cfg_priv->dongle_up)
++		return err;
++
++	ndev = cfg_to_ndev(cfg_priv);
++	wdev = ndev->ieee80211_ptr;
++
++	brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
++			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
++
++	err = brcmf_dongle_eventmsg(ndev);
++	if (err)
++		goto default_conf_out;
++
++	power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
++	err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
++	if (err)
++		goto default_conf_out;
++	WL_INFO("power save set to %s\n",
++		(power_mode ? "enabled" : "disabled"));
++
++	err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
++				WL_BEACON_TIMEOUT);
++	if (err)
++		goto default_conf_out;
++	err = brcmf_dongle_mode(ndev, wdev->iftype);
++	if (err && err != -EINPROGRESS)
++		goto default_conf_out;
++	err = brcmf_dongle_probecap(cfg_priv);
++	if (err)
++		goto default_conf_out;
++
++	/* -EINPROGRESS: Call commit handler */
++
++default_conf_out:
++
++	cfg_priv->dongle_up = true;
++
++	return err;
++
++}
++
++static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	char buf[10+IFNAMSIZ];
++	struct dentry *fd;
++	s32 err = 0;
++
++	sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
++	cfg_priv->debugfsdir = debugfs_create_dir(buf,
++					cfg_to_wiphy(cfg_priv)->debugfsdir);
++
++	fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
++		(u16 *)&cfg_priv->profile->beacon_interval);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++	fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
++		(u8 *)&cfg_priv->profile->dtim_period);
++	if (!fd) {
++		err = -ENOMEM;
++		goto err_out;
++	}
++
++err_out:
++	return err;
++}
++
++static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	debugfs_remove_recursive(cfg_priv->debugfsdir);
++	cfg_priv->debugfsdir = NULL;
++}
++
++static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	s32 err = 0;
++
++	set_bit(WL_STATUS_READY, &cfg_priv->status);
++
++	brcmf_debugfs_add_netdev_params(cfg_priv);
++
++	err = brcmf_config_dongle(cfg_priv);
++	if (err)
++		return err;
++
++	brcmf_invoke_iscan(cfg_priv);
++
++	return err;
++}
++
++static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
++{
++	/*
++	 * While going down, if associated with AP disassociate
++	 * from AP to save power
++	 */
++	if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
++	     test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
++	     test_bit(WL_STATUS_READY, &cfg_priv->status)) {
++		WL_INFO("Disassociating from AP");
++		brcmf_link_down(cfg_priv);
++
++		/* Make sure WPA_Supplicant receives all the event
++		   generated due to DISASSOC call to the fw to keep
++		   the state fw and WPA_Supplicant state consistent
++		 */
++		brcmf_delay(500);
++	}
++
++	set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++	brcmf_term_iscan(cfg_priv);
++	if (cfg_priv->scan_request) {
++		cfg80211_scan_done(cfg_priv->scan_request, true);
++		/* May need to perform this to cover rmmod */
++		/* wl_set_mpc(cfg_to_ndev(wl), 1); */
++		cfg_priv->scan_request = NULL;
++	}
++	clear_bit(WL_STATUS_READY, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
++	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
++
++	brcmf_debugfs_remove_netdev(cfg_priv);
++
++	return 0;
++}
++
++s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_up(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
++{
++	struct brcmf_cfg80211_priv *cfg_priv;
++	s32 err = 0;
++
++	cfg_priv = brcmf_priv_get(cfg_dev);
++	mutex_lock(&cfg_priv->usr_sync);
++	err = __brcmf_cfg80211_down(cfg_priv);
++	mutex_unlock(&cfg_priv->usr_sync);
++
++	return err;
++}
++
++static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
++			       u8 t, u8 l, u8 *v)
++{
++	struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
++	s32 err = 0;
++
++	if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
++		WL_ERR("ei crosses buffer boundary\n");
++		return -ENOSPC;
++	}
++	ie->buf[ie->offset] = t;
++	ie->buf[ie->offset + 1] = l;
++	memcpy(&ie->buf[ie->offset + 2], v, l);
++	ie->offset += l + 2;
++
++	return err;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+new file mode 100644
+index 0000000..b5d9b36
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+@@ -0,0 +1,366 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _wl_cfg80211_h_
++#define _wl_cfg80211_h_
++
++struct brcmf_cfg80211_conf;
++struct brcmf_cfg80211_iface;
++struct brcmf_cfg80211_priv;
++struct brcmf_cfg80211_security;
++struct brcmf_cfg80211_ibss;
++
++#define WL_DBG_NONE		0
++#define WL_DBG_CONN		(1 << 5)
++#define WL_DBG_SCAN		(1 << 4)
++#define WL_DBG_TRACE		(1 << 3)
++#define WL_DBG_INFO		(1 << 1)
++#define WL_DBG_ERR		(1 << 0)
++#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
++				(WL_DBG_SCAN) | (WL_DBG_CONN))
++
++#define	WL_ERR(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_ERR) {			\
++		if (net_ratelimit()) {				\
++			pr_err("ERROR @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#if (defined DEBUG)
++#define	WL_INFO(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_INFO) {			\
++		if (net_ratelimit()) {				\
++			pr_err("INFO @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_TRACE(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_TRACE) {			\
++		if (net_ratelimit()) {				\
++			pr_err("TRACE @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_SCAN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_SCAN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("SCAN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#define	WL_CONN(fmt, ...)					\
++do {								\
++	if (brcmf_dbg_level & WL_DBG_CONN) {			\
++		if (net_ratelimit()) {				\
++			pr_err("CONN @%s : " fmt,		\
++			       __func__, ##__VA_ARGS__);	\
++		}						\
++	}							\
++} while (0)
++
++#else /* (defined DEBUG) */
++#define	WL_INFO(fmt, args...)
++#define	WL_TRACE(fmt, args...)
++#define	WL_SCAN(fmt, args...)
++#define	WL_CONN(fmt, args...)
++#endif /* (defined DEBUG) */
++
++#define WL_NUM_SCAN_MAX		1
++#define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
++						 * for 2.6.33 kernel
++						 * or later
++						 */
++#define WL_SCAN_BUF_MAX			(1024 * 8)
++#define WL_TLV_INFO_MAX			1024
++#define WL_BSS_INFO_MAX			2048
++#define WL_ASSOC_INFO_MAX	512	/*
++				 * needs to grab assoc info from dongle to
++				 * report it to cfg80211 through "connect"
++				 * event
++				 */
++#define WL_DCMD_LEN_MAX	1024
++#define WL_EXTRA_BUF_MAX	2048
++#define WL_ISCAN_BUF_MAX	2048	/*
++				 * the buf length can be BRCMF_DCMD_MAXLEN
++				 * to reduce iteration
++				 */
++#define WL_ISCAN_TIMER_INTERVAL_MS	3000
++#define WL_SCAN_ERSULTS_LAST	(BRCMF_SCAN_RESULTS_NO_MEM+1)
++#define WL_AP_MAX	256	/* virtually unlimitted as long
++				 * as kernel memory allows
++				 */
++
++#define WL_ROAM_TRIGGER_LEVEL		-75
++#define WL_ROAM_DELTA			20
++#define WL_BEACON_TIMEOUT		3
++
++#define WL_SCAN_CHANNEL_TIME		40
++#define WL_SCAN_UNASSOC_TIME		40
++#define WL_SCAN_PASSIVE_TIME		120
++
++/* dongle status */
++enum wl_status {
++	WL_STATUS_READY,
++	WL_STATUS_SCANNING,
++	WL_STATUS_SCAN_ABORTING,
++	WL_STATUS_CONNECTING,
++	WL_STATUS_CONNECTED
++};
++
++/* wi-fi mode */
++enum wl_mode {
++	WL_MODE_BSS,
++	WL_MODE_IBSS,
++	WL_MODE_AP
++};
++
++/* dongle profile list */
++enum wl_prof_list {
++	WL_PROF_MODE,
++	WL_PROF_SSID,
++	WL_PROF_SEC,
++	WL_PROF_IBSS,
++	WL_PROF_BAND,
++	WL_PROF_BSSID,
++	WL_PROF_ACT,
++	WL_PROF_BEACONINT,
++	WL_PROF_DTIMPERIOD
++};
++
++/* dongle iscan state */
++enum wl_iscan_state {
++	WL_ISCAN_STATE_IDLE,
++	WL_ISCAN_STATE_SCANING
++};
++
++/* dongle configuration */
++struct brcmf_cfg80211_conf {
++	u32 mode;		/* adhoc , infrastructure or ap */
++	u32 frag_threshold;
++	u32 rts_threshold;
++	u32 retry_short;
++	u32 retry_long;
++	s32 tx_power;
++	struct ieee80211_channel channel;
++};
++
++/* cfg80211 main event loop */
++struct brcmf_cfg80211_event_loop {
++	s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
++				     struct net_device *ndev,
++				     const struct brcmf_event_msg *e,
++				     void *data);
++};
++
++/* representing interface of cfg80211 plane */
++struct brcmf_cfg80211_iface {
++	struct brcmf_cfg80211_priv *cfg_priv;
++};
++
++struct brcmf_cfg80211_dev {
++	void *driver_data;	/* to store cfg80211 object information */
++};
++
++/* basic structure of scan request */
++struct brcmf_cfg80211_scan_req {
++	struct brcmf_ssid_le ssid_le;
++};
++
++/* basic structure of information element */
++struct brcmf_cfg80211_ie {
++	u16 offset;
++	u8 buf[WL_TLV_INFO_MAX];
++};
++
++/* event queue for cfg80211 main event */
++struct brcmf_cfg80211_event_q {
++	struct list_head evt_q_list;
++	u32 etype;
++	struct brcmf_event_msg emsg;
++	s8 edata[1];
++};
++
++/* security information with currently associated ap */
++struct brcmf_cfg80211_security {
++	u32 wpa_versions;
++	u32 auth_type;
++	u32 cipher_pairwise;
++	u32 cipher_group;
++	u32 wpa_auth;
++};
++
++/* ibss information for currently joined ibss network */
++struct brcmf_cfg80211_ibss {
++	u8 beacon_interval;	/* in millisecond */
++	u8 atim;		/* in millisecond */
++	s8 join_only;
++	u8 band;
++	u8 channel;
++};
++
++/* dongle profile */
++struct brcmf_cfg80211_profile {
++	u32 mode;
++	struct brcmf_ssid ssid;
++	u8 bssid[ETH_ALEN];
++	u16 beacon_interval;
++	u8 dtim_period;
++	struct brcmf_cfg80211_security sec;
++	struct brcmf_cfg80211_ibss ibss;
++	s32 band;
++};
++
++/* dongle iscan event loop */
++struct brcmf_cfg80211_iscan_eloop {
++	s32 (*handler[WL_SCAN_ERSULTS_LAST])
++		(struct brcmf_cfg80211_priv *cfg_priv);
++};
++
++/* dongle iscan controller */
++struct brcmf_cfg80211_iscan_ctrl {
++	struct net_device *ndev;
++	struct timer_list timer;
++	u32 timer_ms;
++	u32 timer_on;
++	s32 state;
++	struct work_struct work;
++	struct brcmf_cfg80211_iscan_eloop el;
++	void *data;
++	s8 dcmd_buf[BRCMF_DCMD_SMLEN];
++	s8 scan_buf[WL_ISCAN_BUF_MAX];
++};
++
++/* association inform */
++struct brcmf_cfg80211_connect_info {
++	u8 *req_ie;
++	s32 req_ie_len;
++	u8 *resp_ie;
++	s32 resp_ie_len;
++};
++
++/* assoc ie length */
++struct brcmf_cfg80211_assoc_ielen_le {
++	__le32 req_len;
++	__le32 resp_len;
++};
++
++/* wpa2 pmk list */
++struct brcmf_cfg80211_pmk_list {
++	struct pmkid_list pmkids;
++	struct pmkid foo[MAXPMKID - 1];
++};
++
++/* dongle private data of cfg80211 interface */
++struct brcmf_cfg80211_priv {
++	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
++	struct brcmf_cfg80211_conf *conf;	/* dongle configuration */
++	struct cfg80211_scan_request *scan_request;	/* scan request
++							 object */
++	struct brcmf_cfg80211_event_loop el;	/* main event loop */
++	struct list_head evt_q_list;	/* used for event queue */
++	spinlock_t	 evt_q_lock;	/* for event queue synchronization */
++	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
++	struct brcmf_scan_results *bss_list;	/* bss_list holding scanned
++						 ap information */
++	struct brcmf_scan_results *scan_results;
++	struct brcmf_cfg80211_scan_req *scan_req_int;	/* scan request object
++						 for internal purpose */
++	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
++						 cfg80211 layer */
++	struct brcmf_cfg80211_ie ie;	/* information element object for
++					 internal purpose */
++	struct brcmf_cfg80211_profile *profile;	/* holding dongle profile */
++	struct brcmf_cfg80211_iscan_ctrl *iscan;	/* iscan controller */
++	struct brcmf_cfg80211_connect_info conn_info; /* association info */
++	struct brcmf_cfg80211_pmk_list *pmk_list;	/* wpa2 pmk list */
++	struct work_struct event_work;	/* event handler work struct */
++	unsigned long status;		/* current dongle status */
++	void *pub;
++	u32 channel;		/* current channel */
++	bool iscan_on;		/* iscan on/off switch */
++	bool iscan_kickstart;	/* indicate iscan already started */
++	bool active_scan;	/* current scan mode */
++	bool ibss_starter;	/* indicates this sta is ibss starter */
++	bool link_up;		/* link/connection up flag */
++	bool pwr_save;		/* indicate whether dongle to support
++					 power save mode */
++	bool dongle_up;		/* indicate whether dongle up or not */
++	bool roam_on;		/* on/off switch for dongle self-roaming */
++	bool scan_tried;	/* indicates if first scan attempted */
++	u8 *dcmd_buf;		/* dcmd buffer */
++	u8 *extra_buf;		/* maily to grab assoc information */
++	struct dentry *debugfsdir;
++	u8 ci[0] __aligned(NETDEV_ALIGN);
++};
++
++static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
++{
++	return w->wdev->wiphy;
++}
++
++static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
++{
++	return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
++}
++
++static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
++{
++	return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
++}
++
++static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
++{
++	return cfg->wdev->netdev;
++}
++
++static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
++{
++	return wdev_to_cfg(ndev->ieee80211_ptr);
++}
++
++#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
++#define cfg_to_iscan(w) (w->iscan)
++
++static inline struct
++brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg)
++{
++	return &cfg->conn_info;
++}
++
++extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
++							struct device *busdev,
++							void *data);
++extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
++
++/* event handler from dongle */
++extern void brcmf_cfg80211_event(struct net_device *ndev,
++				 const struct brcmf_event_msg *e, void *data);
++extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
++extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
++
++#endif				/* _wl_cfg80211_h_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+new file mode 100644
+index 0000000..3c1f39d
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile
+@@ -0,0 +1,48 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver
++#
++# Copyright (c) 2010 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y := \
++	-D__CHECK_ENDIAN__ \
++	-I$(obj)				\
++	-I$(obj)/phy				\
++	-I$(obj)/../include
++
++BRCMSMAC_OFILES := \
++	mac80211_if.o \
++	ucode_loader.o \
++	ampdu.o \
++	antsel.o \
++	channel.o \
++	main.o \
++	phy_shim.o \
++	pmu.o \
++	rate.o \
++	stf.o \
++	aiutils.o \
++	phy/phy_cmn.o \
++	phy/phy_lcn.o \
++	phy/phy_n.o \
++	phy/phytbl_lcn.o \
++	phy/phytbl_n.o \
++	phy/phy_qmath.o \
++	dma.o \
++	brcms_trace_events.o
++
++MODULEPFX := brcmsmac
++
++obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+new file mode 100644
+index 0000000..94e040a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+@@ -0,0 +1,841 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * File contents: support functions for PCI/PCIe
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/delay.h>
++
++#include <defs.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include <brcm_hw_ids.h>
++#include <soc.h>
++#include "types.h"
++#include "pub.h"
++#include "pmu.h"
++#include "aiutils.h"
++
++/* slow_clk_ctl */
++ /* slow clock source mask */
++#define SCC_SS_MASK		0x00000007
++ /* source of slow clock is LPO */
++#define	SCC_SS_LPO		0x00000000
++ /* source of slow clock is crystal */
++#define	SCC_SS_XTAL		0x00000001
++ /* source of slow clock is PCI */
++#define	SCC_SS_PCI		0x00000002
++ /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
++#define SCC_LF			0x00000200
++ /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
++#define SCC_LP			0x00000400
++ /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
++#define SCC_FS			0x00000800
++ /* IgnorePllOffReq, 1/0:
++  *  power logic ignores/honors PLL clock disable requests from core
++  */
++#define SCC_IP			0x00001000
++ /* XtalControlEn, 1/0:
++  *  power logic does/doesn't disable crystal when appropriate
++  */
++#define SCC_XC			0x00002000
++ /* XtalPU (RO), 1/0: crystal running/disabled */
++#define SCC_XP			0x00004000
++ /* ClockDivider (SlowClk = 1/(4+divisor)) */
++#define SCC_CD_MASK		0xffff0000
++#define SCC_CD_SHIFT		16
++
++/* system_clk_ctl */
++ /* ILPen: Enable Idle Low Power */
++#define	SYCC_IE			0x00000001
++ /* ALPen: Enable Active Low Power */
++#define	SYCC_AE			0x00000002
++ /* ForcePLLOn */
++#define	SYCC_FP			0x00000004
++ /* Force ALP (or HT if ALPen is not set */
++#define	SYCC_AR			0x00000008
++ /* Force HT */
++#define	SYCC_HR			0x00000010
++ /* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
++#define SYCC_CD_MASK		0xffff0000
++#define SYCC_CD_SHIFT		16
++
++#define CST4329_SPROM_OTP_SEL_MASK	0x00000003
++ /* OTP is powered up, use def. CIS, no SPROM */
++#define CST4329_DEFCIS_SEL		0
++ /* OTP is powered up, SPROM is present */
++#define CST4329_SPROM_SEL		1
++ /* OTP is powered up, no SPROM */
++#define CST4329_OTP_SEL			2
++ /* OTP is powered down, SPROM is present */
++#define CST4329_OTP_PWRDN		3
++
++#define CST4329_SPI_SDIO_MODE_MASK	0x00000004
++#define CST4329_SPI_SDIO_MODE_SHIFT	2
++
++/* 43224 chip-specific ChipControl register bits */
++#define CCTRL43224_GPIO_TOGGLE          0x8000
++ /* 12 mA drive strength */
++#define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0
++ /* 12 mA drive strength for later 43224s */
++#define CCTRL_43224B0_12MA_LED_DRIVE    0xF0
++
++/* 43236 Chip specific ChipStatus register bits */
++#define CST43236_SFLASH_MASK		0x00000040
++#define CST43236_OTP_MASK		0x00000080
++#define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
++#define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
++#define CST43236_BOOT_MASK		0x00001800
++#define CST43236_BOOT_SHIFT		11
++#define CST43236_BOOT_FROM_SRAM		0 /* boot from SRAM, ARM in reset */
++#define CST43236_BOOT_FROM_ROM		1 /* boot from ROM */
++#define CST43236_BOOT_FROM_FLASH	2 /* boot from FLASH */
++#define CST43236_BOOT_FROM_INVALID	3
++
++/* 4331 chip-specific ChipControl register bits */
++ /* 0 disable */
++#define CCTRL4331_BT_COEXIST		(1<<0)
++ /* 0 SECI is disabled (JTAG functional) */
++#define CCTRL4331_SECI			(1<<1)
++ /* 0 disable */
++#define CCTRL4331_EXT_LNA		(1<<2)
++ /* sprom/gpio13-15 mux */
++#define CCTRL4331_SPROM_GPIO13_15       (1<<3)
++ /* 0 ext pa disable, 1 ext pa enabled */
++#define CCTRL4331_EXTPA_EN		(1<<4)
++ /* set drive out GPIO_CLK on sprom_cs pin */
++#define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)
++ /* use sprom_cs pin as PCIE mdio interface */
++#define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)
++ /* aband extpa will be at gpio2/5 and sprom_dout */
++#define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)
++ /* override core control on pipe_AuxClkEnable */
++#define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)
++ /* override core control on pipe_AuxPowerDown */
++#define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)
++ /* pcie_auxclkenable */
++#define CCTRL4331_PCIE_AUXCLKEN		(1<<10)
++ /* pcie_pipe_pllpowerdown */
++#define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)
++ /* enable bt_shd0 at gpio4 */
++#define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)
++ /* enable bt_shd1 at gpio5 */
++#define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)
++
++/* 4331 Chip specific ChipStatus register bits */
++ /* crystal frequency 20/40Mhz */
++#define	CST4331_XTAL_FREQ		0x00000001
++#define	CST4331_SPROM_PRESENT		0x00000002
++#define	CST4331_OTP_PRESENT		0x00000004
++#define	CST4331_LDO_RF			0x00000008
++#define	CST4331_LDO_PAR			0x00000010
++
++/* 4319 chip-specific ChipStatus register bits */
++#define	CST4319_SPI_CPULESSUSB		0x00000001
++#define	CST4319_SPI_CLK_POL		0x00000002
++#define	CST4319_SPI_CLK_PH		0x00000008
++ /* gpio [7:6], SDIO CIS selection */
++#define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0
++#define	CST4319_SPROM_OTP_SEL_SHIFT	6
++ /* use default CIS, OTP is powered up */
++#define	CST4319_DEFCIS_SEL		0x00000000
++ /* use SPROM, OTP is powered up */
++#define	CST4319_SPROM_SEL		0x00000040
++ /* use OTP, OTP is powered up */
++#define	CST4319_OTP_SEL			0x00000080
++ /* use SPROM, OTP is powered down */
++#define	CST4319_OTP_PWRDN		0x000000c0
++ /* gpio [8], sdio/usb mode */
++#define	CST4319_SDIO_USB_MODE		0x00000100
++#define	CST4319_REMAP_SEL_MASK		0x00000600
++#define	CST4319_ILPDIV_EN		0x00000800
++#define	CST4319_XTAL_PD_POL		0x00001000
++#define	CST4319_LPO_SEL			0x00002000
++#define	CST4319_RES_INIT_MODE		0x0000c000
++ /* PALDO is configured with external PNP */
++#define	CST4319_PALDO_EXTPNP		0x00010000
++#define	CST4319_CBUCK_MODE_MASK		0x00060000
++#define CST4319_CBUCK_MODE_BURST	0x00020000
++#define CST4319_CBUCK_MODE_LPBURST	0x00060000
++#define	CST4319_RCAL_VALID		0x01000000
++#define	CST4319_RCAL_VALUE_MASK		0x3e000000
++#define	CST4319_RCAL_VALUE_SHIFT	25
++
++/* 4336 chip-specific ChipStatus register bits */
++#define	CST4336_SPI_MODE_MASK		0x00000001
++#define	CST4336_SPROM_PRESENT		0x00000002
++#define	CST4336_OTP_PRESENT		0x00000004
++#define	CST4336_ARMREMAP_0		0x00000008
++#define	CST4336_ILPDIV_EN_MASK		0x00000010
++#define	CST4336_ILPDIV_EN_SHIFT		4
++#define	CST4336_XTAL_PD_POL_MASK	0x00000020
++#define	CST4336_XTAL_PD_POL_SHIFT	5
++#define	CST4336_LPO_SEL_MASK		0x00000040
++#define	CST4336_LPO_SEL_SHIFT		6
++#define	CST4336_RES_INIT_MODE_MASK	0x00000180
++#define	CST4336_RES_INIT_MODE_SHIFT	7
++#define	CST4336_CBUCK_MODE_MASK		0x00000600
++#define	CST4336_CBUCK_MODE_SHIFT	9
++
++/* 4313 chip-specific ChipStatus register bits */
++#define	CST4313_SPROM_PRESENT			1
++#define	CST4313_OTP_PRESENT			2
++#define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
++#define	CST4313_SPROM_OTP_SEL_SHIFT		0
++
++/* 4313 Chip specific ChipControl register bits */
++ /* 12 mA drive strengh for later 4313 */
++#define CCTRL_4313_12MA_LED_DRIVE    0x00000007
++
++/* Manufacturer Ids */
++#define	MFGID_ARM		0x43b
++#define	MFGID_BRCM		0x4bf
++#define	MFGID_MIPS		0x4a7
++
++/* Enumeration ROM registers */
++#define	ER_EROMENTRY		0x000
++#define	ER_REMAPCONTROL		0xe00
++#define	ER_REMAPSELECT		0xe04
++#define	ER_MASTERSELECT		0xe10
++#define	ER_ITCR			0xf00
++#define	ER_ITIP			0xf04
++
++/* Erom entries */
++#define	ER_TAG			0xe
++#define	ER_TAG1			0x6
++#define	ER_VALID		1
++#define	ER_CI			0
++#define	ER_MP			2
++#define	ER_ADD			4
++#define	ER_END			0xe
++#define	ER_BAD			0xffffffff
++
++/* EROM CompIdentA */
++#define	CIA_MFG_MASK		0xfff00000
++#define	CIA_MFG_SHIFT		20
++#define	CIA_CID_MASK		0x000fff00
++#define	CIA_CID_SHIFT		8
++#define	CIA_CCL_MASK		0x000000f0
++#define	CIA_CCL_SHIFT		4
++
++/* EROM CompIdentB */
++#define	CIB_REV_MASK		0xff000000
++#define	CIB_REV_SHIFT		24
++#define	CIB_NSW_MASK		0x00f80000
++#define	CIB_NSW_SHIFT		19
++#define	CIB_NMW_MASK		0x0007c000
++#define	CIB_NMW_SHIFT		14
++#define	CIB_NSP_MASK		0x00003e00
++#define	CIB_NSP_SHIFT		9
++#define	CIB_NMP_MASK		0x000001f0
++#define	CIB_NMP_SHIFT		4
++
++/* EROM AddrDesc */
++#define	AD_ADDR_MASK		0xfffff000
++#define	AD_SP_MASK		0x00000f00
++#define	AD_SP_SHIFT		8
++#define	AD_ST_MASK		0x000000c0
++#define	AD_ST_SHIFT		6
++#define	AD_ST_SLAVE		0x00000000
++#define	AD_ST_BRIDGE		0x00000040
++#define	AD_ST_SWRAP		0x00000080
++#define	AD_ST_MWRAP		0x000000c0
++#define	AD_SZ_MASK		0x00000030
++#define	AD_SZ_SHIFT		4
++#define	AD_SZ_4K		0x00000000
++#define	AD_SZ_8K		0x00000010
++#define	AD_SZ_16K		0x00000020
++#define	AD_SZ_SZD		0x00000030
++#define	AD_AG32			0x00000008
++#define	AD_ADDR_ALIGN		0x00000fff
++#define	AD_SZ_BASE		0x00001000	/* 4KB */
++
++/* EROM SizeDesc */
++#define	SD_SZ_MASK		0xfffff000
++#define	SD_SG32			0x00000008
++#define	SD_SZ_ALIGN		0x00000fff
++
++/* PCI config space bit 4 for 4306c0 slow clock source */
++#define	PCI_CFG_GPIO_SCS	0x10
++/* PCI config space GPIO 14 for Xtal power-up */
++#define PCI_CFG_GPIO_XTAL	0x40
++/* PCI config space GPIO 15 for PLL power-down */
++#define PCI_CFG_GPIO_PLL	0x80
++
++/* power control defines */
++#define PLL_DELAY		150	/* us pll on delay */
++#define FREF_DELAY		200	/* us fref change delay */
++#define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
++
++/* resetctrl */
++#define	AIRC_RESET		1
++
++#define	NOREV		-1	/* Invalid rev */
++
++/* GPIO Based LED powersave defines */
++#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
++#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
++
++/* When Srom support present, fields in sromcontrol */
++#define	SRC_START		0x80000000
++#define	SRC_BUSY		0x80000000
++#define	SRC_OPCODE		0x60000000
++#define	SRC_OP_READ		0x00000000
++#define	SRC_OP_WRITE		0x20000000
++#define	SRC_OP_WRDIS		0x40000000
++#define	SRC_OP_WREN		0x60000000
++#define	SRC_OTPSEL		0x00000010
++#define	SRC_LOCK		0x00000008
++#define	SRC_SIZE_MASK		0x00000006
++#define	SRC_SIZE_1K		0x00000000
++#define	SRC_SIZE_4K		0x00000002
++#define	SRC_SIZE_16K		0x00000004
++#define	SRC_SIZE_SHIFT		1
++#define	SRC_PRESENT		0x00000001
++
++/* External PA enable mask */
++#define GPIO_CTRL_EPA_EN_MASK 0x40
++
++#define DEFAULT_GPIOTIMERVAL \
++	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
++
++#define	BADIDX		(SI_MAXCORES + 1)
++
++#define	IS_SIM(chippkg)	\
++	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
++
++#define PCIE(sih)	(ai_get_buscoretype(sih) == PCIE_CORE_ID)
++
++#define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
++
++#ifdef DEBUG
++#define	SI_MSG(fmt, ...)	pr_debug(fmt, ##__VA_ARGS__)
++#else
++#define	SI_MSG(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	GOODCOREADDR(x, b) \
++	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
++		IS_ALIGNED((x), SI_CORE_SIZE))
++
++struct aidmp {
++	u32 oobselina30;	/* 0x000 */
++	u32 oobselina74;	/* 0x004 */
++	u32 PAD[6];
++	u32 oobselinb30;	/* 0x020 */
++	u32 oobselinb74;	/* 0x024 */
++	u32 PAD[6];
++	u32 oobselinc30;	/* 0x040 */
++	u32 oobselinc74;	/* 0x044 */
++	u32 PAD[6];
++	u32 oobselind30;	/* 0x060 */
++	u32 oobselind74;	/* 0x064 */
++	u32 PAD[38];
++	u32 oobselouta30;	/* 0x100 */
++	u32 oobselouta74;	/* 0x104 */
++	u32 PAD[6];
++	u32 oobseloutb30;	/* 0x120 */
++	u32 oobseloutb74;	/* 0x124 */
++	u32 PAD[6];
++	u32 oobseloutc30;	/* 0x140 */
++	u32 oobseloutc74;	/* 0x144 */
++	u32 PAD[6];
++	u32 oobseloutd30;	/* 0x160 */
++	u32 oobseloutd74;	/* 0x164 */
++	u32 PAD[38];
++	u32 oobsynca;	/* 0x200 */
++	u32 oobseloutaen;	/* 0x204 */
++	u32 PAD[6];
++	u32 oobsyncb;	/* 0x220 */
++	u32 oobseloutben;	/* 0x224 */
++	u32 PAD[6];
++	u32 oobsyncc;	/* 0x240 */
++	u32 oobseloutcen;	/* 0x244 */
++	u32 PAD[6];
++	u32 oobsyncd;	/* 0x260 */
++	u32 oobseloutden;	/* 0x264 */
++	u32 PAD[38];
++	u32 oobaextwidth;	/* 0x300 */
++	u32 oobainwidth;	/* 0x304 */
++	u32 oobaoutwidth;	/* 0x308 */
++	u32 PAD[5];
++	u32 oobbextwidth;	/* 0x320 */
++	u32 oobbinwidth;	/* 0x324 */
++	u32 oobboutwidth;	/* 0x328 */
++	u32 PAD[5];
++	u32 oobcextwidth;	/* 0x340 */
++	u32 oobcinwidth;	/* 0x344 */
++	u32 oobcoutwidth;	/* 0x348 */
++	u32 PAD[5];
++	u32 oobdextwidth;	/* 0x360 */
++	u32 oobdinwidth;	/* 0x364 */
++	u32 oobdoutwidth;	/* 0x368 */
++	u32 PAD[37];
++	u32 ioctrlset;	/* 0x400 */
++	u32 ioctrlclear;	/* 0x404 */
++	u32 ioctrl;		/* 0x408 */
++	u32 PAD[61];
++	u32 iostatus;	/* 0x500 */
++	u32 PAD[127];
++	u32 ioctrlwidth;	/* 0x700 */
++	u32 iostatuswidth;	/* 0x704 */
++	u32 PAD[62];
++	u32 resetctrl;	/* 0x800 */
++	u32 resetstatus;	/* 0x804 */
++	u32 resetreadid;	/* 0x808 */
++	u32 resetwriteid;	/* 0x80c */
++	u32 PAD[60];
++	u32 errlogctrl;	/* 0x900 */
++	u32 errlogdone;	/* 0x904 */
++	u32 errlogstatus;	/* 0x908 */
++	u32 errlogaddrlo;	/* 0x90c */
++	u32 errlogaddrhi;	/* 0x910 */
++	u32 errlogid;	/* 0x914 */
++	u32 errloguser;	/* 0x918 */
++	u32 errlogflags;	/* 0x91c */
++	u32 PAD[56];
++	u32 intstatus;	/* 0xa00 */
++	u32 PAD[127];
++	u32 config;		/* 0xe00 */
++	u32 PAD[63];
++	u32 itcr;		/* 0xf00 */
++	u32 PAD[3];
++	u32 itipooba;	/* 0xf10 */
++	u32 itipoobb;	/* 0xf14 */
++	u32 itipoobc;	/* 0xf18 */
++	u32 itipoobd;	/* 0xf1c */
++	u32 PAD[4];
++	u32 itipoobaout;	/* 0xf30 */
++	u32 itipoobbout;	/* 0xf34 */
++	u32 itipoobcout;	/* 0xf38 */
++	u32 itipoobdout;	/* 0xf3c */
++	u32 PAD[4];
++	u32 itopooba;	/* 0xf50 */
++	u32 itopoobb;	/* 0xf54 */
++	u32 itopoobc;	/* 0xf58 */
++	u32 itopoobd;	/* 0xf5c */
++	u32 PAD[4];
++	u32 itopoobain;	/* 0xf70 */
++	u32 itopoobbin;	/* 0xf74 */
++	u32 itopoobcin;	/* 0xf78 */
++	u32 itopoobdin;	/* 0xf7c */
++	u32 PAD[4];
++	u32 itopreset;	/* 0xf90 */
++	u32 PAD[15];
++	u32 peripherialid4;	/* 0xfd0 */
++	u32 peripherialid5;	/* 0xfd4 */
++	u32 peripherialid6;	/* 0xfd8 */
++	u32 peripherialid7;	/* 0xfdc */
++	u32 peripherialid0;	/* 0xfe0 */
++	u32 peripherialid1;	/* 0xfe4 */
++	u32 peripherialid2;	/* 0xfe8 */
++	u32 peripherialid3;	/* 0xfec */
++	u32 componentid0;	/* 0xff0 */
++	u32 componentid1;	/* 0xff4 */
++	u32 componentid2;	/* 0xff8 */
++	u32 componentid3;	/* 0xffc */
++};
++
++static bool
++ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
++{
++	/* no cores found, bail out */
++	if (cc->bus->nr_cores == 0)
++		return false;
++
++	/* get chipcommon rev */
++	sii->pub.ccrev = cc->id.rev;
++
++	/* get chipcommon chipstatus */
++	sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
++
++	/* get chipcommon capabilites */
++	sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
++
++	/* get pmu rev and caps */
++	if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
++		sii->pub.pmucaps = bcma_read32(cc,
++					       CHIPCREGOFFS(pmucapabilities));
++		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
++	}
++
++	/* figure out buscore */
++	sii->buscore = ai_findcore(&sii->pub, PCIE_CORE_ID, 0);
++
++	return true;
++}
++
++static struct si_info *ai_doattach(struct si_info *sii,
++				   struct bcma_bus *pbus)
++{
++	struct si_pub *sih = &sii->pub;
++	u32 w, savewin;
++	struct bcma_device *cc;
++	struct ssb_sprom *sprom = &pbus->sprom;
++
++	savewin = 0;
++
++	sii->icbus = pbus;
++	sii->pcibus = pbus->host_pci;
++
++	/* switch to Chipcommon core */
++	cc = pbus->drv_cc.core;
++
++	sih->chip = pbus->chipinfo.id;
++	sih->chiprev = pbus->chipinfo.rev;
++	sih->chippkg = pbus->chipinfo.pkg;
++	sih->boardvendor = pbus->boardinfo.vendor;
++	sih->boardtype = pbus->boardinfo.type;
++
++	if (!ai_buscore_setup(sii, cc))
++		goto exit;
++
++	/* === NVRAM, clock is ready === */
++	bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
++	bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
++
++	/* PMU specific initializations */
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		si_pmu_init(sih);
++		(void)si_pmu_measure_alpclk(sih);
++		si_pmu_res_init(sih);
++	}
++
++	/* setup the GPIO based LED powersave register */
++	w = (sprom->leddc_on_time << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
++		 (sprom->leddc_off_time << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT);
++	if (w == 0)
++		w = DEFAULT_GPIOTIMERVAL;
++	ai_cc_reg(sih, offsetof(struct chipcregs, gpiotimerval),
++		  ~0, w);
++
++	if (ai_get_chip_id(sih) == BCM43224_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 43224 and
++		 * set chipControl register bit 15
++		 */
++		if (ai_get_chiprev(sih) == 0) {
++			SI_MSG("Applying 43224A0 WARs\n");
++			ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol),
++				  CCTRL43224_GPIO_TOGGLE,
++				  CCTRL43224_GPIO_TOGGLE);
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
++					   CCTRL_43224A0_12MA_LED_DRIVE);
++		}
++		if (ai_get_chiprev(sih) >= 1) {
++			SI_MSG("Applying 43224B0+ WARs\n");
++			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
++					   CCTRL_43224B0_12MA_LED_DRIVE);
++		}
++	}
++
++	if (ai_get_chip_id(sih) == BCM4313_CHIP_ID) {
++		/*
++		 * enable 12 mA drive strenth for 4313 and
++		 * set chipControl register bit 1
++		 */
++		SI_MSG("Applying 4313 WARs\n");
++		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
++				   CCTRL_4313_12MA_LED_DRIVE);
++	}
++
++	return sii;
++
++ exit:
++
++	return NULL;
++}
++
++/*
++ * Allocate a si handle and do the attach.
++ */
++struct si_pub *
++ai_attach(struct bcma_bus *pbus)
++{
++	struct si_info *sii;
++
++	/* alloc struct si_info */
++	sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC);
++	if (sii == NULL)
++		return NULL;
++
++	if (ai_doattach(sii, pbus) == NULL) {
++		kfree(sii);
++		return NULL;
++	}
++
++	return (struct si_pub *) sii;
++}
++
++/* may be called with core in reset */
++void ai_detach(struct si_pub *sih)
++{
++	struct si_info *sii;
++
++	struct si_pub *si_local = NULL;
++	memcpy(&si_local, &sih, sizeof(struct si_pub **));
++
++	sii = (struct si_info *)sih;
++
++	if (sii == NULL)
++		return;
++
++	kfree(sii);
++}
++
++/* return index of coreid or BADIDX if not found */
++struct bcma_device *ai_findcore(struct si_pub *sih, u16 coreid, u16 coreunit)
++{
++	struct bcma_device *core;
++	struct si_info *sii;
++	uint found;
++
++	sii = (struct si_info *)sih;
++
++	found = 0;
++
++	list_for_each_entry(core, &sii->icbus->cores, list)
++		if (core->id.id == coreid) {
++			if (found == coreunit)
++				return core;
++			found++;
++		}
++
++	return NULL;
++}
++
++/*
++ * read/modify chipcommon core register.
++ */
++uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
++{
++	struct bcma_device *cc;
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++	cc = sii->icbus->drv_cc.core;
++
++	/* mask and set */
++	if (mask || val) {
++		bcma_maskset32(cc, regoff, ~mask, val);
++	}
++
++	/* readback */
++	w = bcma_read32(cc, regoff);
++
++	return w;
++}
++
++/* return the slow clock source - LPO, XTAL, or PCI */
++static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
++{
++	return SCC_SS_XTAL;
++}
++
++/*
++* return the ILP (slowclock) min or max frequency
++* precondition: we've established the chip has dynamic clk control
++*/
++static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
++			    struct bcma_device *cc)
++{
++	uint div;
++
++	/* Chipc rev 10 is InstaClock */
++	div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
++	div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
++	return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
++}
++
++static void
++ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
++{
++	uint slowmaxfreq, pll_delay, slowclk;
++	uint pll_on_delay, fref_sel_delay;
++
++	pll_delay = PLL_DELAY;
++
++	/*
++	 * If the slow clock is not sourced by the xtal then
++	 * add the xtal_on_delay since the xtal will also be
++	 * powered down by dynamic clk control logic.
++	 */
++
++	slowclk = ai_slowclk_src(sih, cc);
++	if (slowclk != SCC_SS_XTAL)
++		pll_delay += XTAL_ON_DELAY;
++
++	/* Starting with 4318 it is ILP that is used for the delays */
++	slowmaxfreq =
++	    ai_slowclk_freq(sih, false, cc);
++
++	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
++	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
++
++	bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay);
++	bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay);
++}
++
++/* initialize power control delay registers */
++void ai_clkctl_init(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return;
++
++	cc = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++	if (cc == NULL)
++		return;
++
++	/* set all Instaclk chip ILP to 1 MHz */
++	bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
++		       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
++
++	ai_clkctl_setdelay(sih, cc);
++}
++
++/*
++ * return the value suitable for writing to the
++ * dot11 core FAST_PWRUP_DELAY register
++ */
++u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++	uint slowminfreq;
++	u16 fpdelay;
++
++	sii = (struct si_info *)sih;
++	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
++		fpdelay = si_pmu_fast_pwrup_delay(sih);
++		return fpdelay;
++	}
++
++	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
++		return 0;
++
++	fpdelay = 0;
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++	if (cc) {
++		slowminfreq = ai_slowclk_freq(sih, false, cc);
++		fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2)
++			    * 1000000) + (slowminfreq - 1)) / slowminfreq;
++	}
++	return fpdelay;
++}
++
++/*
++ *  clock control policy function throught chipcommon
++ *
++ *    set dynamic clk control mode (forceslow, forcefast, dynamic)
++ *    returns true if we are forcing fast clock
++ *    this is a wrapper over the next internal function
++ *      to allow flexible policy settings for outside caller
++ */
++bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih))
++		return mode == BCMA_CLKMODE_FAST;
++
++	cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++	bcma_core_set_clockmode(cc, mode);
++	return mode == BCMA_CLKMODE_FAST;
++}
++
++void ai_pci_up(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_FAST);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, true);
++}
++
++/* Unconfigure and/or apply various WARs when going down */
++void ai_pci_down(struct si_pub *sih)
++{
++	struct si_info *sii;
++	struct bcma_device *cc;
++
++	sii = (struct si_info *)sih;
++
++	/* release FORCEHT since chip is going to "down" state */
++	if (PCI_FORCEHT(sih)) {
++		cc = ai_findcore(&sii->pub, BCMA_CORE_CHIPCOMMON, 0);
++		bcma_core_set_clockmode(cc, BCMA_CLKMODE_DYNAMIC);
++	}
++
++	if (PCIE(sih))
++		bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci, false);
++}
++
++/* Enable BT-COEX & Ex-PA for 4313 */
++void ai_epa_4313war(struct si_pub *sih)
++{
++	struct bcma_device *cc;
++
++	cc = ai_findcore(sih, CC_CORE_ID, 0);
++
++	/* EPA Fix */
++	bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK);
++}
++
++/* check if the device is removed */
++bool ai_deviceremoved(struct si_pub *sih)
++{
++	u32 w;
++	struct si_info *sii;
++
++	sii = (struct si_info *)sih;
++
++	if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
++		return false;
++
++	pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
++	if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	return false;
++}
++
++uint ai_get_buscoretype(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.id;
++}
++
++uint ai_get_buscorerev(struct si_pub *sih)
++{
++	struct si_info *sii = (struct si_info *)sih;
++	return sii->buscore->id.rev;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+new file mode 100644
+index 0000000..d9f04a6
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_AIUTILS_H_
++#define	_BRCM_AIUTILS_H_
++
++#include <linux/bcma/bcma.h>
++
++#include "types.h"
++
++/*
++ * SOC Interconnect Address Map.
++ * All regions may not exist on all chips.
++ */
++/* each core gets 4Kbytes for registers */
++#define SI_CORE_SIZE		0x1000
++/*
++ * Max cores (this is arbitrary, for software
++ * convenience and could be changed if we
++ * make any larger chips
++ */
++#define	SI_MAXCORES		16
++
++/* Client Mode sb2pcitranslation2 size in bytes */
++#define SI_PCI_DMA_SZ		0x40000000
++
++/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
++#define SI_PCIE_DMA_H32		0x80000000
++
++/* chipcommon being the first core: */
++#define	SI_CC_IDX		0
++
++/* SOC Interconnect types (aka chip types) */
++#define	SOCI_AI			1
++
++/* A register that is common to all cores to
++ * communicate w/PMU regarding clock control.
++ */
++#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
++
++/* clk_ctl_st register */
++#define	CCS_FORCEALP		0x00000001	/* force ALP request */
++#define	CCS_FORCEHT		0x00000002	/* force HT request */
++#define	CCS_FORCEILP		0x00000004	/* force ILP request */
++#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
++#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
++#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
++#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
++#define CCS_ERSRC_REQ_SHIFT	8
++#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
++#define	CCS_HTAVAIL		0x00020000	/* HT is available */
++#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
++#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
++#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
++#define CCS_ERSRC_STS_SHIFT	24
++
++/* HT avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_HTAVAIL		0x00010000
++/* ALP avail in chipc and pcmcia on 4328a0 */
++#define	CCS0_ALPAVAIL		0x00020000
++
++/* Not really related to SOC Interconnect, but a couple of software
++ * conventions for the use the flash space:
++ */
++
++/* Minumum amount of flash we support */
++#define FLASH_MIN		0x00020000	/* Minimum flash size */
++
++#define	CC_SROM_OTP		0x800	/* SROM/OTP address space */
++
++/* gpiotimerval */
++#define GPIO_ONTIME_SHIFT	16
++
++/* Fields in clkdiv */
++#define	CLKD_OTP		0x000f0000
++#define	CLKD_OTP_SHIFT		16
++
++/* Package IDs */
++#define	BCM4717_PKG_ID		9	/* 4717 package id */
++#define	BCM4718_PKG_ID		10	/* 4718 package id */
++#define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
++
++/* these are router chips */
++#define	BCM4716_CHIP_ID		0x4716	/* 4716 chipcommon chipid */
++#define	BCM47162_CHIP_ID	47162	/* 47162 chipcommon chipid */
++#define	BCM4748_CHIP_ID		0x4748	/* 4716 chipcommon chipid (OTP, RBBU) */
++
++/* dynamic clock control defines */
++#define	LPOMINFREQ		25000	/* low power oscillator min */
++#define	LPOMAXFREQ		43000	/* low power oscillator max */
++#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
++#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
++#define	PCIMINFREQ		25000000	/* 25 MHz */
++#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
++
++#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
++#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
++
++/* clkctl xtal what flags */
++#define	XTAL			0x1	/* primary crystal oscillator (2050) */
++#define	PLL			0x2	/* main chip pll */
++
++/* GPIO usage priorities */
++#define GPIO_DRV_PRIORITY	0	/* Driver */
++#define GPIO_APP_PRIORITY	1	/* Application */
++#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
++					 * reservation
++					 */
++
++/* GPIO pull up/down */
++#define GPIO_PULLUP		0
++#define GPIO_PULLDN		1
++
++/* GPIO event regtype */
++#define GPIO_REGEVT		0	/* GPIO register event */
++#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
++#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
++
++/* device path */
++#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
++
++/* SI routine enumeration: to be used by update function with multiple hooks */
++#define	SI_DOATTACH	1
++#define SI_PCIDOWN	2
++#define SI_PCIUP	3
++
++/*
++ * Data structure to export all chip specific common variables
++ *   public (read-only) portion of aiutils handle returned by si_attach()
++ */
++struct si_pub {
++	int ccrev;		/* chip common core rev */
++	u32 cccaps;		/* chip common capabilities */
++	int pmurev;		/* pmu core rev */
++	u32 pmucaps;		/* pmu capabilities */
++	uint boardtype;		/* board type */
++	uint boardvendor;	/* board vendor */
++	uint chip;		/* chip number */
++	uint chiprev;		/* chip revision */
++	uint chippkg;		/* chip package option */
++};
++
++struct pci_dev;
++
++struct gpioh_item {
++	void *arg;
++	bool level;
++	void (*handler) (u32 stat, void *arg);
++	u32 event;
++	struct gpioh_item *next;
++};
++
++/* misc si info needed by some of the routines */
++struct si_info {
++	struct si_pub pub;	/* back plane public state (must be first) */
++	struct bcma_bus *icbus;	/* handle to soc interconnect bus */
++	struct pci_dev *pcibus;	/* handle to pci bus */
++	struct bcma_device *buscore;
++
++	u32 chipst;		/* chip status */
++};
++
++/*
++ * Many of the routines below take an 'sih' handle as their first arg.
++ * Allocate this by calling si_attach().  Free it by calling si_detach().
++ * At any one time, the sih is logically focused on one particular si core
++ * (the "current core").
++ * Use si_setcore() or si_setcoreidx() to change the association to another core
++ */
++
++
++/* AMBA Interconnect exported externs */
++extern struct bcma_device *ai_findcore(struct si_pub *sih,
++				       u16 coreid, u16 coreunit);
++extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
++
++/* === exported functions === */
++extern struct si_pub *ai_attach(struct bcma_bus *pbus);
++extern void ai_detach(struct si_pub *sih);
++extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
++extern void ai_clkctl_init(struct si_pub *sih);
++extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
++extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
++extern bool ai_deviceremoved(struct si_pub *sih);
++
++extern void ai_pci_down(struct si_pub *sih);
++extern void ai_pci_up(struct si_pub *sih);
++
++/* Enable Ex-PA for 4313 */
++extern void ai_epa_4313war(struct si_pub *sih);
++
++extern uint ai_get_buscoretype(struct si_pub *sih);
++extern uint ai_get_buscorerev(struct si_pub *sih);
++
++static inline u32 ai_get_cccaps(struct si_pub *sih)
++{
++	return sih->cccaps;
++}
++
++static inline int ai_get_pmurev(struct si_pub *sih)
++{
++	return sih->pmurev;
++}
++
++static inline u32 ai_get_pmucaps(struct si_pub *sih)
++{
++	return sih->pmucaps;
++}
++
++static inline uint ai_get_boardtype(struct si_pub *sih)
++{
++	return sih->boardtype;
++}
++
++static inline uint ai_get_boardvendor(struct si_pub *sih)
++{
++	return sih->boardvendor;
++}
++
++static inline uint ai_get_chip_id(struct si_pub *sih)
++{
++	return sih->chip;
++}
++
++static inline uint ai_get_chiprev(struct si_pub *sih)
++{
++	return sih->chiprev;
++}
++
++static inline uint ai_get_chippkg(struct si_pub *sih)
++{
++	return sih->chippkg;
++}
++
++#endif				/* _BRCM_AIUTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+new file mode 100644
+index 0000000..95b5902
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+@@ -0,0 +1,1236 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <net/mac80211.h>
++
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "antsel.h"
++#include "main.h"
++#include "ampdu.h"
++
++/* max number of mpdus in an ampdu */
++#define AMPDU_MAX_MPDU			32
++/* max number of mpdus in an ampdu to a legacy */
++#define AMPDU_NUM_MPDU_LEGACY		16
++/* max Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_MAX_WSIZE		64
++/* default Tx ba window size (in pdu) */
++#define AMPDU_TX_BA_DEF_WSIZE		64
++/* default Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_DEF_WSIZE		64
++/* max Rx ba window size (in pdu) */
++#define AMPDU_RX_BA_MAX_WSIZE		64
++/* max dur of tx ampdu (in msec) */
++#define	AMPDU_MAX_DUR			5
++/* default tx retry limit */
++#define AMPDU_DEF_RETRY_LIMIT		5
++/* default tx retry limit at reg rate */
++#define AMPDU_DEF_RR_RETRY_LIMIT	2
++/* default weight of ampdu in txfifo */
++#define AMPDU_DEF_TXPKT_WEIGHT		2
++/* default ffpld reserved bytes */
++#define AMPDU_DEF_FFPLD_RSVD		2048
++/* # of inis to be freed on detach */
++#define AMPDU_INI_FREE			10
++/* max # of mpdus released at a time */
++#define	AMPDU_SCB_MAX_RELEASE		20
++
++#define NUM_FFPLD_FIFO 4	/* number of fifo concerned by pre-loading */
++#define FFPLD_TX_MAX_UNFL   200	/* default value of the average number of ampdu
++				 * without underflows
++				 */
++#define FFPLD_MPDU_SIZE 1800	/* estimate of maximum mpdu size */
++#define FFPLD_MAX_MCS 23	/* we don't deal with mcs 32 */
++#define FFPLD_PLD_INCR 1000	/* increments in bytes */
++#define FFPLD_MAX_AMPDU_CNT 5000	/* maximum number of ampdu we
++					 * accumulate between resets.
++					 */
++
++#define AMPDU_DELIMITER_LEN	4
++
++/* max allowed number of mpdus in an ampdu (2 streams) */
++#define AMPDU_NUM_MPDU		16
++
++#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
++
++/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
++#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
++	AMPDU_DELIMITER_LEN + 3\
++	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
++
++/* modulo add/sub, bound = 2^k */
++#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
++#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
++
++/* structure to hold tx fifo information and pre-loading state
++ * counters specific to tx underflows of ampdus
++ * some counters might be redundant with the ones in wlc or ampdu structures.
++ * This allows to maintain a specific state independently of
++ * how often and/or when the wlc counters are updated.
++ *
++ * ampdu_pld_size: number of bytes to be pre-loaded
++ * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
++ * prev_txfunfl: num of underflows last read from the HW macstats counter
++ * accum_txfunfl: num of underflows since we modified pld params
++ * accum_txampdu: num of tx ampdu since we modified pld params
++ * prev_txampdu: previous reading of tx ampdu
++ * dmaxferrate: estimated dma avg xfer rate in kbits/sec
++ */
++struct brcms_fifo_info {
++	u16 ampdu_pld_size;
++	u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
++	u16 prev_txfunfl;
++	u32 accum_txfunfl;
++	u32 accum_txampdu;
++	u32 prev_txampdu;
++	u32 dmaxferrate;
++};
++
++/* AMPDU module specific state
++ *
++ * wlc: pointer to main wlc structure
++ * scb_handle: scb cubby handle to retrieve data from scb
++ * ini_enable: per-tid initiator enable/disable of ampdu
++ * ba_tx_wsize: Tx ba window size (in pdu)
++ * ba_rx_wsize: Rx ba window size (in pdu)
++ * retry_limit: mpdu transmit retry limit
++ * rr_retry_limit: mpdu transmit retry limit at regular rate
++ * retry_limit_tid: per-tid mpdu transmit retry limit
++ * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
++ * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
++ * max_pdu: max pdus allowed in ampdu
++ * dur: max duration of an ampdu (in msec)
++ * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
++ * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
++ * ffpld_rsvd: number of bytes to reserve for preload
++ * max_txlen: max size of ampdu per mcs, bw and sgi
++ * mfbr: enable multiple fallback rate
++ * tx_max_funl: underflows should be kept such that
++ *		(tx_max_funfl*underflows) < tx frames
++ * fifo_tb: table of fifo infos
++ */
++struct ampdu_info {
++	struct brcms_c_info *wlc;
++	int scb_handle;
++	u8 ini_enable[AMPDU_MAX_SCB_TID];
++	u8 ba_tx_wsize;
++	u8 ba_rx_wsize;
++	u8 retry_limit;
++	u8 rr_retry_limit;
++	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
++	u8 mpdu_density;
++	s8 max_pdu;
++	u8 dur;
++	u8 txpkt_weight;
++	u8 rx_factor;
++	u32 ffpld_rsvd;
++	u32 max_txlen[MCS_TABLE_SIZE][2][2];
++	bool mfbr;
++	u32 tx_max_funl;
++	struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
++};
++
++/* used for flushing ampdu packets */
++struct cb_del_ampdu_pars {
++	struct ieee80211_sta *sta;
++	u16 tid;
++};
++
++static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
++{
++	u32 rate, mcs;
++
++	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
++		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
++		/* 20MHz, No SGI */
++		rate = mcs_2_rate(mcs, false, false);
++		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
++		/* 40 MHz, No SGI */
++		rate = mcs_2_rate(mcs, true, false);
++		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
++		/* 20MHz, SGI */
++		rate = mcs_2_rate(mcs, false, true);
++		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
++		/* 40 MHz, SGI */
++		rate = mcs_2_rate(mcs, true, true);
++		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
++	}
++}
++
++static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
++{
++	if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
++		return true;
++	else
++		return false;
++}
++
++static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	wlc->pub->_ampdu = false;
++
++	if (on) {
++		if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
++				"nmode enabled\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		if (!brcms_c_ampdu_cap(ampdu)) {
++			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
++				"ampdu capable\n", wlc->pub->unit);
++			return -ENOTSUPP;
++		}
++		wlc->pub->_ampdu = on;
++	}
++
++	return 0;
++}
++
++static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
++{
++	int i, j;
++	struct brcms_fifo_info *fifo;
++
++	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
++		fifo = (ampdu->fifo_tb + j);
++		fifo->ampdu_pld_size = 0;
++		for (i = 0; i <= FFPLD_MAX_MCS; i++)
++			fifo->mcs2ampdu_table[i] = 255;
++		fifo->dmaxferrate = 0;
++		fifo->accum_txampdu = 0;
++		fifo->prev_txfunfl = 0;
++		fifo->accum_txfunfl = 0;
++
++	}
++}
++
++struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
++{
++	struct ampdu_info *ampdu;
++	int i;
++
++	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
++	if (!ampdu)
++		return NULL;
++
++	ampdu->wlc = wlc;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
++		ampdu->ini_enable[i] = true;
++	/* Disable ampdu for VO by default */
++	ampdu->ini_enable[PRIO_8021D_VO] = false;
++	ampdu->ini_enable[PRIO_8021D_NC] = false;
++
++	/* Disable ampdu for BK by default since not enough fifo space */
++	ampdu->ini_enable[PRIO_8021D_NONE] = false;
++	ampdu->ini_enable[PRIO_8021D_BK] = false;
++
++	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
++	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
++	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
++	ampdu->max_pdu = AUTO;
++	ampdu->dur = AMPDU_MAX_DUR;
++	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
++
++	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
++	/*
++	 * bump max ampdu rcv size to 64k for all 11n
++	 * devices except 4321A0 and 4321A1
++	 */
++	if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
++	else
++		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
++	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
++	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
++
++	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
++		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
++		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
++	}
++
++	brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
++	ampdu->mfbr = false;
++	/* try to set ampdu to the default value */
++	brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
++
++	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
++	brcms_c_ffpld_init(ampdu);
++
++	return ampdu;
++}
++
++void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
++{
++	kfree(ampdu);
++}
++
++static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
++					    struct scb *scb)
++{
++	struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
++	int i;
++
++	scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
++
++	/* go back to legacy size if some preloading is occurring */
++	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
++		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
++			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
++	}
++
++	/* apply user override */
++	if (ampdu->max_pdu != AUTO)
++		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
++
++	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
++				   AMPDU_SCB_MAX_RELEASE);
++
++	if (scb_ampdu->max_rx_ampdu_bytes)
++		scb_ampdu->release = min_t(u8, scb_ampdu->release,
++			scb_ampdu->max_rx_ampdu_bytes / 1600);
++
++	scb_ampdu->release = min(scb_ampdu->release,
++				 ampdu->fifo_tb[TX_AC_BE_FIFO].
++				 mcs2ampdu_table[FFPLD_MAX_MCS]);
++}
++
++static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
++{
++	brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
++}
++
++static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
++{
++	int i;
++	u32 phy_rate, dma_rate, tmp;
++	u8 max_mpdu;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
++
++	/* recompute the dma rate */
++	/* note : we divide/multiply by 100 to avoid integer overflows */
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++	phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	dma_rate =
++	    (((phy_rate / 100) *
++	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++	fifo->dmaxferrate = dma_rate;
++
++	/* fill up the mcs2ampdu table; do not recalc the last mcs */
++	dma_rate = dma_rate >> 7;
++	for (i = 0; i < FFPLD_MAX_MCS; i++) {
++		/* shifting to keep it within integer range */
++		phy_rate = mcs_2_rate(i, true, false) >> 7;
++		if (phy_rate > dma_rate) {
++			tmp = ((fifo->ampdu_pld_size * phy_rate) /
++			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
++			tmp = min_t(u32, tmp, 255);
++			fifo->mcs2ampdu_table[i] = (u8) tmp;
++		}
++	}
++}
++
++/* evaluate the dma transfer rate using the tx underflows as feedback.
++ * If necessary, increase tx fifo preloading. If not enough,
++ * decrease maximum ampdu size for each mcs till underflows stop
++ * Return 1 if pre-loading not active, -1 if not an underflow event,
++ * 0 if pre-loading module took care of the event.
++ */
++static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
++{
++	struct ampdu_info *ampdu = wlc->ampdu;
++	u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
++	u32 txunfl_ratio;
++	u8 max_mpdu;
++	u32 current_ampdu_cnt = 0;
++	u16 max_pld_size;
++	u32 new_txunfl;
++	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
++	uint xmtfifo_sz;
++	u16 cur_txunfl;
++
++	/* return if we got here for a different reason than underflows */
++	cur_txunfl = brcms_b_read_shm(wlc->hw,
++				      M_UCODE_MACSTAT +
++				      offsetof(struct macstat, txfunfl[fid]));
++	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
++	if (new_txunfl == 0) {
++		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
++		return -1;
++	}
++	fifo->prev_txfunfl = cur_txunfl;
++
++	if (!ampdu->tx_max_funl)
++		return 1;
++
++	/* check if fifo is big enough */
++	if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
++		return -1;
++
++	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
++		return 1;
++
++	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
++	fifo->accum_txfunfl += new_txunfl;
++
++	/* we need to wait for at least 10 underflows */
++	if (fifo->accum_txfunfl < 10)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
++		current_ampdu_cnt, fifo->accum_txfunfl);
++
++	/*
++	   compute the current ratio of tx unfl per ampdu.
++	   When the current ampdu count becomes too
++	   big while the ratio remains small, we reset
++	   the current count in order to not
++	   introduce too big of a latency in detecting a
++	   large amount of tx underflows later.
++	 */
++
++	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
++
++	if (txunfl_ratio > ampdu->tx_max_funl) {
++		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
++			fifo->accum_txfunfl = 0;
++
++		return 0;
++	}
++	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
++			 AMPDU_NUM_MPDU_LEGACY);
++
++	/* In case max value max_pdu is already lower than
++	   the fifo depth, there is nothing more we can do.
++	 */
++
++	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
++		fifo->accum_txfunfl = 0;
++		return 0;
++	}
++
++	if (fifo->ampdu_pld_size < max_pld_size) {
++
++		/* increment by TX_FIFO_PLD_INC bytes */
++		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
++		if (fifo->ampdu_pld_size > max_pld_size)
++			fifo->ampdu_pld_size = max_pld_size;
++
++		/* update scb release size */
++		brcms_c_scb_ampdu_update_config_all(ampdu);
++
++		/*
++		 * compute a new dma xfer rate for max_mpdu @ max mcs.
++		 * This is the minimum dma rate that can achieve no
++		 * underflow condition for the current mpdu size.
++		 *
++		 * note : we divide/multiply by 100 to avoid integer overflows
++		 */
++		fifo->dmaxferrate =
++		    (((phy_rate / 100) *
++		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
++		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
++
++		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
++			"pre-load size %d\n",
++			fifo->dmaxferrate, fifo->ampdu_pld_size);
++	} else {
++
++		/* decrease ampdu size */
++		if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
++			if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
++				    AMPDU_NUM_MPDU_LEGACY - 1;
++			else
++				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
++
++			/* recompute the table */
++			brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
++
++			/* update scb release size */
++			brcms_c_scb_ampdu_update_config_all(ampdu);
++		}
++	}
++	fifo->accum_txfunfl = 0;
++	return 0;
++}
++
++void
++brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++	u8 ba_wsize,		/* negotiated ba window size (in pdu) */
++	uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
++{
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	struct ampdu_info *ampdu = wlc->ampdu;
++	struct scb *scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++
++	if (!ampdu->ini_enable[tid]) {
++		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
++			  __func__, tid);
++		return;
++	}
++
++	ini = &scb_ampdu->ini[tid];
++	ini->tid = tid;
++	ini->scb = scb_ampdu->scb;
++	ini->ba_wsize = ba_wsize;
++	scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
++}
++
++int
++brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
++	      struct sk_buff **pdu, int prec)
++{
++	struct brcms_c_info *wlc;
++	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
++	u8 tid, ndelim;
++	int err = 0;
++	u8 preamble_type = BRCMS_GF_PREAMBLE;
++	u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
++	u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
++	u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
++
++	bool rr = true, fbr = false;
++	uint i, count = 0, fifo, seg_cnt = 0;
++	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
++	u32 ampdu_len, max_ampdu_bytes = 0;
++	struct d11txh *txh = NULL;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++	struct scb_ampdu *scb_ampdu;
++	struct scb_ampdu_tid_ini *ini;
++	u8 mcs = 0;
++	bool use_rts = false, use_cts = false;
++	u32 rspec = 0, rspec_fallback = 0;
++	u32 rts_rspec = 0, rts_rspec_fallback = 0;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++	struct ieee80211_rts *rts;
++	u8 rr_retry_limit;
++	struct brcms_fifo_info *f;
++	bool fbr_iscck;
++	struct ieee80211_tx_info *tx_info;
++	u16 qlen;
++	struct wiphy *wiphy;
++
++	wlc = ampdu->wlc;
++	wiphy = wlc->wiphy;
++	p = *pdu;
++
++	tid = (u8) (p->priority);
++
++	f = ampdu->fifo_tb + prio2fifo[tid];
++
++	scb = &wlc->pri_scb;
++	scb_ampdu = &scb->scb_ampdu;
++	ini = &scb_ampdu->ini[tid];
++
++	/* Let pressure continue to build ... */
++	qlen = pktq_plen(&qi->q, prec);
++	if (ini->tx_in_transit > 0 &&
++	    qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
++		/* Collect multiple MPDU's to be sent in the next AMPDU */
++		return -EBUSY;
++
++	/* at this point we intend to transmit an AMPDU */
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	ampdu_len = 0;
++	dma_len = 0;
++	while (p) {
++		struct ieee80211_tx_rate *txrate;
++
++		tx_info = IEEE80211_SKB_CB(p);
++		txrate = tx_info->status.rates;
++
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_prep_pdu(wlc, p, &fifo);
++		} else {
++			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
++			*pdu = NULL;
++			err = 0;
++			break;
++		}
++
++		if (err) {
++			if (err == -EBUSY) {
++				wiphy_err(wiphy, "wl%d: sendampdu: "
++					  "prep_xdu retry; seq 0x%x\n",
++					  wlc->pub->unit, seq);
++				*pdu = p;
++				break;
++			}
++
++			/* error in the packet; reject it */
++			wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
++				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
++			*pdu = NULL;
++			break;
++		}
++
++		/* pkt is good to be aggregated */
++		txh = (struct d11txh *) p->data;
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++		index = TX_SEQ_TO_INDEX(seq);
++
++		/* check mcl fields and test whether it can be agg'd */
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
++		txh->PreloadSize = 0;	/* always default to 0 */
++
++		/*  Handle retry limits */
++		if (txrate[0].count <= rr_retry_limit) {
++			txrate[0].count++;
++			rr = true;
++			fbr = false;
++		} else {
++			fbr = true;
++			rr = false;
++			txrate[1].count++;
++		}
++
++		/* extract the length info */
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++
++		/* retrieve null delimiter count */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		seg_cnt += 1;
++
++		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
++			wlc->pub->unit, count, len);
++
++		/*
++		 * aggregateable mpdu. For ucode/hw agg,
++		 * test whether need to break or change the epoch
++		 */
++		if (count == 0) {
++			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
++			/* refill the bits since might be a retx mpdu */
++			mcl |= TXC_STARTMSDU;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++			if (ieee80211_is_rts(rts->frame_control)) {
++				mcl |= TXC_SENDRTS;
++				use_rts = true;
++			}
++			if (ieee80211_is_cts(rts->frame_control)) {
++				mcl |= TXC_SENDCTS;
++				use_cts = true;
++			}
++		} else {
++			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
++			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
++		}
++
++		len = roundup(len, 4);
++		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
++
++		dma_len += (u16) p->len;
++
++		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
++			" seg_cnt %d null delim %d\n",
++			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
++
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* this packet is added */
++		pkt[count++] = p;
++
++		/* patch the first MPDU */
++		if (count == 1) {
++			u8 plcp0, plcp3, is40, sgi;
++			struct ieee80211_sta *sta;
++
++			sta = tx_info->control.sta;
++
++			if (rr) {
++				plcp0 = plcp[0];
++				plcp3 = plcp[3];
++			} else {
++				plcp0 = txh->FragPLCPFallback[0];
++				plcp3 = txh->FragPLCPFallback[3];
++
++			}
++			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
++			sgi = plcp3_issgi(plcp3) ? 1 : 0;
++			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
++			max_ampdu_bytes =
++			    min(scb_ampdu->max_rx_ampdu_bytes,
++				ampdu->max_txlen[mcs][is40][sgi]);
++
++			if (is40)
++				mimo_ctlchbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++			/* rebuild the rspec and rspec_fallback */
++			rspec = RSPEC_MIMORATE;
++			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
++			if (plcp[0] & MIMO_PLCP_40MHZ)
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++
++			if (fbr_iscck)	/* CCK */
++				rspec_fallback = cck_rspec(cck_phy2mac_rate
++						    (txh->FragPLCPFallback[0]));
++			else {	/* MIMO */
++				rspec_fallback = RSPEC_MIMORATE;
++				rspec_fallback |=
++				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
++				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
++					rspec_fallback |=
++					    (PHY_TXC1_BW_40MHZ <<
++					     RSPEC_BW_SHIFT);
++			}
++
++			if (use_rts || use_cts) {
++				rts_rspec =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec, false, mimo_ctlchbw);
++				rts_rspec_fallback =
++				    brcms_c_rspec_to_rts_rspec(wlc,
++					rspec_fallback, false, mimo_ctlchbw);
++			}
++		}
++
++		/* if (first mpdu for host agg) */
++		/* test whether to add more */
++		if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
++		    (count == f->mcs2ampdu_table[mcs])) {
++			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
++				" ampdu at %d for mcs %d\n",
++				wlc->pub->unit, count, mcs);
++			break;
++		}
++
++		if (count == scb_ampdu->max_pdu)
++			break;
++
++		/*
++		 * check to see if the next pkt is
++		 * a candidate for aggregation
++		 */
++		p = pktq_ppeek(&qi->q, prec);
++		/* tx_info must be checked with current p */
++		tx_info = IEEE80211_SKB_CB(p);
++
++		if (p) {
++			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++			    ((u8) (p->priority) == tid)) {
++				plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
++				plen = max(scb_ampdu->min_len, plen);
++
++				if ((plen + ampdu_len) > max_ampdu_bytes) {
++					p = NULL;
++					continue;
++				}
++
++				/*
++				 * check if there are enough
++				 * descriptors available
++				 */
++				if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
++					wiphy_err(wiphy, "%s: No fifo space  "
++						  "!!\n", __func__);
++					p = NULL;
++					continue;
++				}
++				p = brcmu_pktq_pdeq(&qi->q, prec);
++			} else {
++				p = NULL;
++			}
++		}
++	}			/* end while(p) */
++
++	ini->tx_in_transit += count;
++
++	if (count) {
++		/* patch up the last txh */
++		txh = (struct d11txh *) pkt[count - 1]->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		mcl &= ~TXC_AMPDU_MASK;
++		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
++		txh->MacTxControlLow = cpu_to_le16(mcl);
++
++		/* remove the null delimiter after last mpdu */
++		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
++		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
++
++		/* remove the pad len from last mpdu */
++		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
++		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
++		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
++		ampdu_len -= roundup(len, 4) - len;
++
++		/* patch up the first txh & plcp */
++		txh = (struct d11txh *) pkt[0]->data;
++		plcp = (u8 *) (txh + 1);
++
++		BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
++		/* mark plcp to indicate ampdu */
++		BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++
++		/* reset the mixed mode header durations */
++		if (txh->MModeLen) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++			preamble_type = BRCMS_MM_PREAMBLE;
++		}
++		if (txh->MModeFbrLen) {
++			u16 mmfbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec_fallback,
++						  ampdu_len);
++			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
++			fbr_preamble_type = BRCMS_MM_PREAMBLE;
++		}
++
++		/* set the preload length */
++		if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
++			dma_len = min(dma_len, f->ampdu_pld_size);
++			txh->PreloadSize = cpu_to_le16(dma_len);
++		} else
++			txh->PreloadSize = 0;
++
++		mch = le16_to_cpu(txh->MacTxControlHigh);
++
++		/* update RTS dur fields */
++		if (use_rts || use_cts) {
++			u16 durid;
++			rts = (struct ieee80211_rts *)&txh->rts_frame;
++			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
++			    TXC_PREAMBLE_RTS_MAIN_SHORT)
++				rts_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
++			    TXC_PREAMBLE_RTS_FB_SHORT)
++				rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
++
++			durid =
++			    brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
++						   rspec, rts_preamble_type,
++						   preamble_type, ampdu_len,
++						   true);
++			rts->duration = cpu_to_le16(durid);
++			durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++						       rts_rspec_fallback,
++						       rspec_fallback,
++						       rts_fbr_preamble_type,
++						       fbr_preamble_type,
++						       ampdu_len, true);
++			txh->RTSDurFallback = cpu_to_le16(durid);
++			/* set TxFesTimeNormal */
++			txh->TxFesTimeNormal = rts->duration;
++			/* set fallback rate version of TxFesTimeNormal */
++			txh->TxFesTimeFallback = txh->RTSDurFallback;
++		}
++
++		/* set flag and plcp for fallback rate */
++		if (fbr) {
++			mch |= TXC_AMPDU_FBR;
++			txh->MacTxControlHigh = cpu_to_le16(mch);
++			BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
++			BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
++		}
++
++		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
++			wlc->pub->unit, count, ampdu_len);
++
++		/* inform rate_sel if it this is a rate probe pkt */
++		frameid = le16_to_cpu(txh->TxFrameID);
++		if (frameid & TXFID_RATE_PROBE_MASK)
++			wiphy_err(wiphy, "%s: XXX what to do with "
++				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
++
++		for (i = 0; i < count; i++)
++			brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
++				   ampdu->txpkt_weight);
++
++	}
++	/* endif (count) */
++	return err;
++}
++
++static void
++brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
++			  struct ieee80211_tx_info *tx_info,
++			  struct tx_status *txs, u8 mcs)
++{
++	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
++	int i;
++
++	/* clear the rest of the rates */
++	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++		txrate[i].idx = -1;
++		txrate[i].count = 0;
++	}
++}
++
++static void
++brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
++			      struct sk_buff *p, struct tx_status *txs,
++			      u32 s1, u32 s2)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u8 bitmap[8], queue, tid;
++	struct d11txh *txh;
++	u8 *plcp;
++	struct ieee80211_hdr *h;
++	u16 seq, start_seq = 0, bindex, index, mcl;
++	u8 mcs = 0;
++	bool ba_recd = false, ack_recd = false;
++	u8 suc_mpdu = 0, tot_mpdu = 0;
++	uint supr_status;
++	bool update_rate = true, retry = true, tx_error = false;
++	u16 mimoantsel = 0;
++	u8 antselid = 0;
++	u8 retry_limit, rr_retry_limit;
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
++	struct wiphy *wiphy = wlc->wiphy;
++
++#ifdef DEBUG
++	u8 hole[AMPDU_MAX_MPDU];
++	memset(hole, 0, sizeof(hole));
++#endif
++
++	scb_ampdu = &scb->scb_ampdu;
++	tid = (u8) (p->priority);
++
++	ini = &scb_ampdu->ini[tid];
++	retry_limit = ampdu->retry_limit_tid[tid];
++	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
++	memset(bitmap, 0, sizeof(bitmap));
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		if (TX_STATUS_SUPR_UF == supr_status)
++			update_rate = false;
++
++		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
++		start_seq = txs->sequence >> SEQNUM_SHIFT;
++		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
++		    TX_STATUS_BA_BMAP03_SHIFT;
++
++		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
++		WARN_ON(!(s1 & TX_STATUS_AMPDU));
++
++		bitmap[0] |=
++		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
++		    TX_STATUS_BA_BMAP47_SHIFT;
++		bitmap[1] = (s1 >> 8) & 0xff;
++		bitmap[2] = (s1 >> 16) & 0xff;
++		bitmap[3] = (s1 >> 24) & 0xff;
++
++		bitmap[4] = s2 & 0xff;
++		bitmap[5] = (s2 >> 8) & 0xff;
++		bitmap[6] = (s2 >> 16) & 0xff;
++		bitmap[7] = (s2 >> 24) & 0xff;
++
++		ba_recd = true;
++	} else {
++		if (supr_status) {
++			update_rate = false;
++			if (supr_status == TX_STATUS_SUPR_BADCH) {
++				wiphy_err(wiphy,
++					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
++					  __func__, CHSPEC_CHANNEL(
++					  wlc->default_bss->chanspec));
++			} else {
++				if (supr_status != TX_STATUS_SUPR_FRAG)
++					wiphy_err(wiphy, "%s: supr_status 0x%x\n",
++						  __func__, supr_status);
++			}
++			/* no need to retry for badch; will fail again */
++			if (supr_status == TX_STATUS_SUPR_BADCH ||
++			    supr_status == TX_STATUS_SUPR_EXPTIME) {
++				retry = false;
++			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
++				/* TX underflow:
++				 *   try tuning pre-loading or ampdu size
++				 */
++			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
++				/*
++				 * if there were underflows, but pre-loading
++				 * is not active, notify rate adaptation.
++				 */
++				if (brcms_c_ffpld_check_txfunfl(wlc,
++					prio2fifo[tid]) > 0)
++					tx_error = true;
++			}
++		} else if (txs->phyerr) {
++			update_rate = false;
++			wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
++				  __func__, txs->phyerr);
++
++			if (brcm_msg_level & LOG_ERROR_VAL) {
++				brcmu_prpkt("txpkt (AMPDU)", p);
++				brcms_c_print_txdesc((struct d11txh *) p->data);
++			}
++			brcms_c_print_txstatus(txs);
++		}
++	}
++
++	/* loop through all pkts and retry if not acked */
++	while (p) {
++		tx_info = IEEE80211_SKB_CB(p);
++		txh = (struct d11txh *) p->data;
++		mcl = le16_to_cpu(txh->MacTxControlLow);
++		plcp = (u8 *) (txh + 1);
++		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
++		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
++
++		if (tot_mpdu == 0) {
++			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
++			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
++		}
++
++		index = TX_SEQ_TO_INDEX(seq);
++		ack_recd = false;
++		if (ba_recd) {
++			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
++			BCMMSG(wiphy,
++			       "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
++			       tid, seq, start_seq, bindex,
++			       isset(bitmap, bindex), index);
++			/* if acked then clear bit and free packet */
++			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
++			    && isset(bitmap, bindex)) {
++				ini->tx_in_transit--;
++				ini->txretry[index] = 0;
++
++				/*
++				 * ampdu_ack_len:
++				 *   number of acked aggregated frames
++				 */
++				/* ampdu_len: number of aggregated frames */
++				brcms_c_ampdu_rate_status(wlc, tx_info, txs,
++							  mcs);
++				tx_info->flags |= IEEE80211_TX_STAT_ACK;
++				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
++				tx_info->status.ampdu_ack_len =
++					tx_info->status.ampdu_len = 1;
++
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++				ack_recd = true;
++				suc_mpdu++;
++			}
++		}
++		/* either retransmit or send bar if ack not recd */
++		if (!ack_recd) {
++			if (retry && (ini->txretry[index] < (int)retry_limit)) {
++				ini->txretry[index]++;
++				ini->tx_in_transit--;
++				/*
++				 * Use high prededence for retransmit to
++				 * give some punch
++				 */
++				brcms_c_txq_enq(wlc, scb, p,
++						BRCMS_PRIO_TO_HI_PREC(tid));
++			} else {
++				/* Retry timeout */
++				ini->tx_in_transit--;
++				ieee80211_tx_info_clear_status(tx_info);
++				tx_info->status.ampdu_ack_len = 0;
++				tx_info->status.ampdu_len = 1;
++				tx_info->flags |=
++				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
++				skb_pull(p, D11_PHY_HDR_LEN);
++				skb_pull(p, D11_TXH_LEN);
++				BCMMSG(wiphy,
++				       "BA Timeout, seq %d, in_transit %d\n",
++				       seq, ini->tx_in_transit);
++				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
++							    p);
++			}
++		}
++		tot_mpdu++;
++
++		/* break out if last packet of ampdu */
++		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++		    TXC_AMPDU_LAST)
++			break;
++
++		p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	}
++	brcms_c_send_q(wlc);
++
++	/* update rate state */
++	antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
++
++	brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++}
++
++void
++brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++		     struct sk_buff *p, struct tx_status *txs)
++{
++	struct scb_ampdu *scb_ampdu;
++	struct brcms_c_info *wlc = ampdu->wlc;
++	struct scb_ampdu_tid_ini *ini;
++	u32 s1 = 0, s2 = 0;
++	struct ieee80211_tx_info *tx_info;
++
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* BMAC_NOTE: For the split driver, second level txstatus comes later
++	 * So if the ACK was received then wait for the second level else just
++	 * call the first one
++	 */
++	if (txs->status & TX_STATUS_ACK_RCV) {
++		u8 status_delay = 0;
++
++		/* wait till the next 8 bytes of txstatus is available */
++		s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
++		while ((s1 & TXS_V) == 0) {
++			udelay(1);
++			status_delay++;
++			if (status_delay > 10)
++				return; /* error condition */
++			s1 = bcma_read32(wlc->hw->d11core,
++					 D11REGOFFS(frmtxstatus));
++		}
++
++		s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
++	}
++
++	if (scb) {
++		scb_ampdu = &scb->scb_ampdu;
++		ini = &scb_ampdu->ini[p->priority];
++		brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
++	} else {
++		/* loop through all pkts and free */
++		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
++		struct d11txh *txh;
++		u16 mcl;
++		while (p) {
++			tx_info = IEEE80211_SKB_CB(p);
++			txh = (struct d11txh *) p->data;
++			mcl = le16_to_cpu(txh->MacTxControlLow);
++			brcmu_pkt_buf_free_skb(p);
++			/* break out if last packet of ampdu */
++			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
++			    TXC_AMPDU_LAST)
++				break;
++			p = dma_getnexttxp(wlc->hw->di[queue],
++					   DMA_RANGE_TRANSMITTED);
++		}
++		brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
++	}
++}
++
++void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
++{
++	char template[T_RAM_ACCESS_SZ * 2];
++
++	/* driver needs to write the ta in the template; ta is at offset 16 */
++	memset(template, 0, sizeof(template));
++	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
++	brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
++				  (T_RAM_ACCESS_SZ * 2),
++				  template);
++}
++
++bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
++{
++	return wlc->ampdu->ini_enable[tid];
++}
++
++void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
++{
++	struct brcms_c_info *wlc = ampdu->wlc;
++
++	/*
++	 * Extend ucode internal watchdog timer to
++	 * match larger received frames
++	 */
++	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
++	    IEEE80211_HT_MAX_AMPDU_64K) {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
++	} else {
++		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
++		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
++	}
++}
++
++/*
++ * callback function that helps flushing ampdu packets from a priority queue
++ */
++static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
++{
++	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
++	struct cb_del_ampdu_pars *ampdu_pars =
++				 (struct cb_del_ampdu_pars *)arg_a;
++	bool rc;
++
++	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
++	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
++		    tx_info->control.sta == ampdu_pars->sta);
++	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
++	return rc;
++}
++
++/*
++ * callback function that helps invalidating ampdu packets in a DMA queue
++ */
++static void dma_cb_fn_ampdu(void *txi, void *arg_a)
++{
++	struct ieee80211_sta *sta = arg_a;
++	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
++
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
++	    (tx_info->control.sta == sta || sta == NULL))
++		tx_info->control.sta = NULL;
++}
++
++/*
++ * When a remote party is no longer available for ampdu communication, any
++ * pending tx ampdu packets in the driver have to be flushed.
++ */
++void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++		     struct ieee80211_sta *sta, u16 tid)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *pq = &qi->q;
++	int prec;
++	struct cb_del_ampdu_pars ampdu_pars;
++
++	ampdu_pars.sta = sta;
++	ampdu_pars.tid = tid;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
++			    (void *)&ampdu_pars);
++	brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+new file mode 100644
+index 0000000..421f4ba
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_AMPDU_H_
++#define _BRCM_AMPDU_H_
++
++extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
++extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
++			     struct brcms_txq_info *qi,
++			     struct sk_buff **aggp, int prec);
++extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
++				 struct sk_buff *p, struct tx_status *txs);
++extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
++
++#endif				/* _BRCM_AMPDU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+new file mode 100644
+index 0000000..55e12c3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c
+@@ -0,0 +1,307 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "main.h"
++#include "phy_shim.h"
++#include "antsel.h"
++
++#define ANT_SELCFG_AUTO		0x80	/* bit indicates antenna sel AUTO */
++#define ANT_SELCFG_MASK		0x33	/* antenna configuration mask */
++#define ANT_SELCFG_TX_UNICAST	0	/* unicast tx antenna configuration */
++#define ANT_SELCFG_RX_UNICAST	1	/* unicast rx antenna configuration */
++#define ANT_SELCFG_TX_DEF	2	/* default tx antenna configuration */
++#define ANT_SELCFG_RX_DEF	3	/* default rx antenna configuration */
++
++/* useful macros */
++#define BRCMS_ANTSEL_11N_0(ant)	((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
++#define BRCMS_ANTSEL_11N_1(ant)	(((ant) & ANT_SELCFG_MASK) & 0xf)
++#define BRCMS_ANTIDX_11N(ant)	(((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
++				(BRCMS_ANTSEL_11N_1(ant)))
++#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
++#define BRCMS_ANTSEL_11N(ant)	((ant) & ANT_SELCFG_MASK)
++
++/* antenna switch */
++/* defines for no boardlevel antenna diversity */
++#define ANT_SELCFG_DEF_2x2	0x01	/* default antenna configuration */
++
++/* 2x3 antdiv defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x3	3
++#define ANT_SELCFG_DEF_2x3	0x01	/* default antenna configuration */
++
++/* 2x4 antdiv rev4 defines and tables for GPIO communication */
++#define ANT_SELCFG_NUM_2x4	4
++#define ANT_SELCFG_DEF_2x4	0x02	/* default antenna configuration */
++
++static const u16 mimo_2x4_div_antselpat_tbl[] = {
++	0, 0, 0x9, 0xa,		/* ant0: 0 ant1: 2,3 */
++	0, 0, 0x5, 0x6,		/* ant0: 1 ant1: 2,3 */
++	0, 0, 0, 0,		/* n.a.              */
++	0, 0, 0, 0		/* n.a.              */
++};
++
++static const u8 mimo_2x4_div_antselid_tbl[16] = {
++	0, 0, 0, 0, 0, 2, 3, 0,
++	0, 0, 1, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++static const u16 mimo_2x3_div_antselpat_tbl[] = {
++	16, 0, 1, 16,		/* ant0: 0 ant1: 1,2 */
++	16, 16, 16, 16,		/* n.a.              */
++	16, 2, 16, 16,		/* ant0: 2 ant1: 1   */
++	16, 16, 16, 16		/* n.a.              */
++};
++
++static const u8 mimo_2x3_div_antselid_tbl[16] = {
++	0, 1, 2, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0	/* pat to antselid */
++};
++
++/* boardlevel antenna selection: init antenna selection structure */
++static void
++brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
++		    bool auto_sel)
++{
++	if (asi->antsel_type == ANTSEL_2x3) {
++		u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
++		    ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
++
++	} else if (asi->antsel_type == ANTSEL_2x4) {
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
++		antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
++
++	} else {		/* no antenna selection available */
++
++		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
++		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
++		antsel->num_antcfg = 0;
++	}
++}
++
++struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
++{
++	struct antsel_info *asi;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
++	if (!asi)
++		return NULL;
++
++	asi->wlc = wlc;
++	asi->pub = wlc->pub;
++	asi->antsel_type = ANTSEL_NA;
++	asi->antsel_avail = false;
++	asi->antsel_antswitch = sprom->antswitch;
++
++	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
++		switch (asi->antsel_antswitch) {
++		case ANTSWITCH_TYPE_1:
++		case ANTSWITCH_TYPE_2:
++		case ANTSWITCH_TYPE_3:
++			/* 4321/2 board with 2x3 switch logic */
++			asi->antsel_type = ANTSEL_2x3;
++			/* Antenna selection availability */
++			if ((sprom->ant_available_bg == 7) ||
++			    (sprom->ant_available_a == 7)) {
++				asi->antsel_avail = true;
++			} else if (
++				sprom->ant_available_bg == 3 ||
++				sprom->ant_available_a == 3) {
++				asi->antsel_avail = false;
++			} else {
++				asi->antsel_avail = false;
++				wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
++					  "board cfg invalid\n");
++			}
++
++			break;
++		default:
++			break;
++		}
++	} else if ((asi->pub->sromrev == 4) &&
++		   (sprom->ant_available_bg == 7) &&
++		   (sprom->ant_available_a == 0)) {
++		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
++		asi->antsel_type = ANTSEL_2x3;
++		asi->antsel_avail = true;
++	} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
++		asi->antsel_type = ANTSEL_2x4;
++		asi->antsel_avail = true;
++	}
++
++	/* Set the antenna selection type for the low driver */
++	brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
++
++	/* Init (auto/manual) antenna selection */
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
++	brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
++
++	return asi;
++}
++
++void brcms_c_antsel_detach(struct antsel_info *asi)
++{
++	kfree(asi);
++}
++
++/*
++ * boardlevel antenna selection:
++ *   convert ant_cfg to mimo_antsel (ucode interface)
++ */
++static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
++{
++	u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
++	u16 mimo_antsel = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
++		return mimo_antsel;
++	}
++
++	return mimo_antsel;
++}
++
++/* boardlevel antenna selection: ucode interface control */
++static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
++				 struct brcms_antselcfg *antsel)
++{
++	struct brcms_c_info *wlc = asi->wlc;
++	u8 ant_cfg;
++	u16 mimo_antsel;
++
++	/* 1) Update TX antconfig for all frames that are not unicast data
++	 *    (aka default TX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
++
++	/* 2) Update RX antconfig for all frames that are not unicast data
++	 *    (aka default RX)
++	 */
++	ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
++	mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
++	brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
++	/*
++	 * Update driver stats for currently selected
++	 * default tx/rx antenna config
++	 */
++	asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
++
++	return 0;
++}
++
++void brcms_c_antsel_init(struct antsel_info *asi)
++{
++	if ((asi->antsel_type == ANTSEL_2x3) ||
++	    (asi->antsel_type == ANTSEL_2x4))
++		brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
++}
++
++/* boardlevel antenna selection: convert id to ant_cfg */
++static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
++{
++	u8 antcfg = ANT_SELCFG_DEF_2x2;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
++		return antcfg;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
++		return antcfg;
++	}
++
++	return antcfg;
++}
++
++void
++brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
++		      u8 antselid, u8 fbantselid, u8 *antcfg,
++		      u8 *fbantcfg)
++{
++	u8 ant;
++
++	/* if use default, assign it and return */
++	if (usedef) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
++		*fbantcfg = *antcfg;
++		return;
++	}
++
++	if (!sel) {
++		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		*fbantcfg = *antcfg;
++
++	} else {
++		ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++		if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
++			*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
++			*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
++		} else {
++			*antcfg =
++			    asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
++			*fbantcfg = *antcfg;
++		}
++	}
++	return;
++}
++
++/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
++u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
++{
++	u8 antselid = 0;
++
++	if (asi->antsel_type == ANTSEL_2x4) {
++		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
++		antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++
++	} else if (asi->antsel_type == ANTSEL_2x3) {
++		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
++		antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
++		return antselid;
++	}
++
++	return antselid;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+new file mode 100644
+index 0000000..97ea388
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h
+@@ -0,0 +1,29 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_ANTSEL_H_
++#define _BRCM_ANTSEL_H_
++
++extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
++extern void brcms_c_antsel_detach(struct antsel_info *asi);
++extern void brcms_c_antsel_init(struct antsel_info *asi);
++extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
++				  bool sel,
++				  u8 id, u8 fbid, u8 *antcfg,
++				  u8 *fbantcfg);
++extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
++
++#endif /* _BRCM_ANTSEL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+new file mode 100644
+index 0000000..52fc9ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/module.h> /* bug in tracepoint.h, it should include this */
++
++#ifndef __CHECKER__
++#include "mac80211_if.h"
++#define CREATE_TRACE_POINTS
++#include "brcms_trace_events.h"
++#endif
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+new file mode 100644
+index 0000000..27dd73e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM brcmsmac
++
++#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
++
++#define __TRACE_BRCMSMAC_H
++
++#include <linux/tracepoint.h>
++#include "mac80211_if.h"
++
++#ifndef CONFIG_BRCMDBG
++#undef TRACE_EVENT
++#define TRACE_EVENT(name, proto, ...) \
++static inline void trace_ ## name(proto) {}
++#endif
++
++/*
++ * We define a tracepoint, its arguments, its printk format and its
++ * 'fast binary record' layout.
++ */
++TRACE_EVENT(brcms_timer,
++	/* TPPROTO is the prototype of the function called by this tracepoint */
++	TP_PROTO(struct brcms_timer *t),
++	/*
++	 * TPARGS(firstarg, p) are the parameters names, same as found in the
++	 * prototype.
++	 */
++	TP_ARGS(t),
++	/*
++	 * Fast binary tracing: define the trace record via TP_STRUCT__entry().
++	 * You can think about it like a regular C structure local variable
++	 * definition.
++	 */
++	TP_STRUCT__entry(
++		__field(uint, ms)
++		__field(uint, set)
++		__field(uint, periodic)
++	),
++	TP_fast_assign(
++		__entry->ms = t->ms;
++		__entry->set = t->set;
++		__entry->periodic = t->periodic;
++	),
++	TP_printk(
++		"ms=%u set=%u periodic=%u",
++		__entry->ms, __entry->set, __entry->periodic
++	)
++);
++
++TRACE_EVENT(brcms_dpc,
++	TP_PROTO(unsigned long data),
++	TP_ARGS(data),
++	TP_STRUCT__entry(
++		__field(unsigned long, data)
++	),
++	TP_fast_assign(
++		__entry->data = data;
++	),
++	TP_printk(
++		"data=%p",
++		(void *)__entry->data
++	)
++);
++
++#endif /* __TRACE_BRCMSMAC_H */
++
++#ifdef CONFIG_BRCMDBG
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH .
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE brcms_trace_events
++
++#include <trace/define_trace.h>
++
++#endif /* CONFIG_BRCMDBG */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+new file mode 100644
+index 0000000..eb77ac3
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+@@ -0,0 +1,1506 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/types.h>
++#include <net/mac80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "phy/phy_hal.h"
++#include "main.h"
++#include "stf.h"
++#include "channel.h"
++
++/* QDB() macro takes a dB value and converts to a quarter dB value */
++#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR)
++
++#define  LOCALE_CHAN_01_11	 (1<<0)
++#define  LOCALE_CHAN_12_13	 (1<<1)
++#define  LOCALE_CHAN_14		 (1<<2)
++#define  LOCALE_SET_5G_LOW_JP1   (1<<3)	/* 34-48, step 2 */
++#define  LOCALE_SET_5G_LOW_JP2   (1<<4)	/* 34-46, step 4 */
++#define  LOCALE_SET_5G_LOW1      (1<<5)	/* 36-48, step 4 */
++#define  LOCALE_SET_5G_LOW2      (1<<6)	/* 52 */
++#define  LOCALE_SET_5G_LOW3      (1<<7)	/* 56-64, step 4 */
++#define  LOCALE_SET_5G_MID1      (1<<8)	/* 100-116, step 4 */
++#define  LOCALE_SET_5G_MID2	 (1<<9)	/* 120-124, step 4 */
++#define  LOCALE_SET_5G_MID3      (1<<10)	/* 128 */
++#define  LOCALE_SET_5G_HIGH1     (1<<11)	/* 132-140, step 4 */
++#define  LOCALE_SET_5G_HIGH2     (1<<12)	/* 149-161, step 4 */
++#define  LOCALE_SET_5G_HIGH3     (1<<13)	/* 165 */
++#define  LOCALE_CHAN_52_140_ALL  (1<<14)
++#define  LOCALE_SET_5G_HIGH4     (1<<15)	/* 184-216 */
++
++#define  LOCALE_CHAN_36_64	(LOCALE_SET_5G_LOW1 | \
++				 LOCALE_SET_5G_LOW2 | \
++				 LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_52_64	(LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
++#define  LOCALE_CHAN_100_124	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
++#define  LOCALE_CHAN_100_140	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \
++				  LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
++#define  LOCALE_CHAN_149_165	(LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
++#define  LOCALE_CHAN_184_216	LOCALE_SET_5G_HIGH4
++
++#define  LOCALE_CHAN_01_14	(LOCALE_CHAN_01_11 | \
++				 LOCALE_CHAN_12_13 | \
++				 LOCALE_CHAN_14)
++
++#define  LOCALE_RADAR_SET_NONE		  0
++#define  LOCALE_RADAR_SET_1		  1
++
++#define  LOCALE_RESTRICTED_NONE		  0
++#define  LOCALE_RESTRICTED_SET_2G_SHORT   1
++#define  LOCALE_RESTRICTED_CHAN_165       2
++#define  LOCALE_CHAN_ALL_5G		  3
++#define  LOCALE_RESTRICTED_JAPAN_LEGACY   4
++#define  LOCALE_RESTRICTED_11D_2G	  5
++#define  LOCALE_RESTRICTED_11D_5G	  6
++#define  LOCALE_RESTRICTED_LOW_HI	  7
++#define  LOCALE_RESTRICTED_12_13_14	  8
++
++#define LOCALE_2G_IDX_i			0
++#define LOCALE_5G_IDX_11		0
++#define LOCALE_MIMO_IDX_bn		0
++#define LOCALE_MIMO_IDX_11n		0
++
++/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
++#define BRCMS_MAXPWR_TBL_SIZE		6
++/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
++#define BRCMS_MAXPWR_MIMO_TBL_SIZE	14
++
++/* power level in group of 2.4GHz band channels:
++ * maxpwr[0] - CCK  channels [1]
++ * maxpwr[1] - CCK  channels [2-10]
++ * maxpwr[2] - CCK  channels [11-14]
++ * maxpwr[3] - OFDM channels [1]
++ * maxpwr[4] - OFDM channels [2-10]
++ * maxpwr[5] - OFDM channels [11-14]
++ */
++
++/* maxpwr mapping to 5GHz band channels:
++ * maxpwr[0] - channels [34-48]
++ * maxpwr[1] - channels [52-60]
++ * maxpwr[2] - channels [62-64]
++ * maxpwr[3] - channels [100-140]
++ * maxpwr[4] - channels [149-165]
++ */
++#define BAND_5G_PWR_LVLS	5	/* 5 power levels for 5G */
++
++#define LC(id)	LOCALE_MIMO_IDX_ ## id
++
++#define LC_2G(id)	LOCALE_2G_IDX_ ## id
++
++#define LC_5G(id)	LOCALE_5G_IDX_ ## id
++
++#define LOCALES(band2, band5, mimo2, mimo5) \
++		{LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
++
++/* macro to get 2.4 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))
++#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))
++
++/* macro to get 5 GHz channel group index for tx power */
++#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \
++				 (((c) < 62) ? 1 : \
++				 (((c) < 100) ? 2 : \
++				 (((c) < 149) ? 3 : 4))))
++
++#define ISDFS_EU(fl)		(((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU)
++
++struct brcms_cm_band {
++	/* struct locale_info flags */
++	u8 locale_flags;
++	/* List of valid channels in the country */
++	struct brcms_chanvec valid_channels;
++	/* List of restricted use channels */
++	const struct brcms_chanvec *restricted_channels;
++	/* List of radar sensitive channels */
++	const struct brcms_chanvec *radar_channels;
++	u8 PAD[8];
++};
++
++ /* locale per-channel tx power limits for MIMO frames
++  * maxpwr arrays are index by channel for 2.4 GHz limits, and
++  * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
++  */
++struct locale_mimo_info {
++	/* tx 20 MHz power limits, qdBm units */
++	s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	/* tx 40 MHz power limits, qdBm units */
++	s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE];
++	u8 flags;
++};
++
++/* Country names and abbreviations with locale defined from ISO 3166 */
++struct country_info {
++	const u8 locale_2G;	/* 2.4G band locale */
++	const u8 locale_5G;	/* 5G band locale */
++	const u8 locale_mimo_2G;	/* 2.4G mimo info */
++	const u8 locale_mimo_5G;	/* 5G mimo info */
++};
++
++struct brcms_cm_info {
++	struct brcms_pub *pub;
++	struct brcms_c_info *wlc;
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	uint srom_regrev;	/* Regulatory Rev for the SROM ccode */
++	const struct country_info *country;	/* current country def */
++	char ccode[BRCM_CNTRY_BUF_SZ];	/* current internal Country Code */
++	uint regrev;		/* current Regulatory Revision */
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];	/* current advertised ccode */
++	/* per-band state (one per phy/radio) */
++	struct brcms_cm_band bandstate[MAXBANDS];
++	/* quiet channels currently for radar sensitivity or 11h support */
++	/* channels on which we cannot transmit */
++	struct brcms_chanvec quiet_channels;
++};
++
++/* locale channel and power info. */
++struct locale_info {
++	u32 valid_channels;
++	/* List of radar sensitive channels */
++	u8 radar_channels;
++	/* List of channels used only if APs are detected */
++	u8 restricted_channels;
++	/* Max tx pwr in qdBm for each sub-band */
++	s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE];
++	/* Country IE advertised max tx pwr in dBm per sub-band */
++	s8 pub_maxpwr[BAND_5G_PWR_LVLS];
++	u8 flags;
++};
++
++/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
++
++/*
++ * Some common channel sets
++ */
++
++/* No channels */
++static const struct brcms_chanvec chanvec_none = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 2.4 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_2G = {
++	{0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* All 5 GHz HW channels */
++static const struct brcms_chanvec chanvec_all_5G = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x01}
++};
++
++/*
++ * Radar channel sets
++ */
++
++/* Channels 52 - 64, 100 - 140 */
++static const struct brcms_chanvec radar_set1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,  /* 52 - 60 */
++	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,  /* 64, 100 - 124 */
++	 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 128 - 140 */
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/*
++ * Restricted channel sets
++ */
++
++/* Channels 34, 38, 42, 46 */
++static const struct brcms_chanvec restricted_set_japan_legacy = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12, 13 */
++static const struct brcms_chanvec restricted_set_2g_short = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channel 165 */
++static const struct brcms_chanvec restricted_chan_165 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 36 - 48 & 149 - 165 */
++static const struct brcms_chanvec restricted_low_hi = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Channels 12 - 14 */
++static const struct brcms_chanvec restricted_set_12_13_14 = {
++	{0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++/* global memory to provide working buffer for expanded locale */
++
++static const struct brcms_chanvec *g_table_radar_set[] = {
++	&chanvec_none,
++	&radar_set1
++};
++
++static const struct brcms_chanvec *g_table_restricted_chan[] = {
++	&chanvec_none,		/* restricted_set_none */
++	&restricted_set_2g_short,
++	&restricted_chan_165,
++	&chanvec_all_5G,
++	&restricted_set_japan_legacy,
++	&chanvec_all_2G,	/* restricted_set_11d_2G */
++	&chanvec_all_5G,	/* restricted_set_11d_5G */
++	&restricted_low_hi,
++	&restricted_set_12_13_14
++};
++
++static const struct brcms_chanvec locale_2g_01_11 = {
++	{0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_12_13 = {
++	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_2g_14 = {
++	{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW_JP2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_LOW3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_MID3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH1 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH2 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH3 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_52_140_ALL = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
++	 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
++	 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_chanvec locale_5g_HIGH4 = {
++	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
++	 0x11, 0x11, 0x11, 0x11}
++};
++
++static const struct brcms_chanvec *g_table_locale_base[] = {
++	&locale_2g_01_11,
++	&locale_2g_12_13,
++	&locale_2g_14,
++	&locale_5g_LOW_JP1,
++	&locale_5g_LOW_JP2,
++	&locale_5g_LOW1,
++	&locale_5g_LOW2,
++	&locale_5g_LOW3,
++	&locale_5g_MID1,
++	&locale_5g_MID2,
++	&locale_5g_MID3,
++	&locale_5g_HIGH1,
++	&locale_5g_HIGH2,
++	&locale_5g_HIGH3,
++	&locale_5g_52_140_ALL,
++	&locale_5g_HIGH4
++};
++
++static void brcms_c_locale_add_channels(struct brcms_chanvec *target,
++				    const struct brcms_chanvec *channels)
++{
++	u8 i;
++	for (i = 0; i < sizeof(struct brcms_chanvec); i++)
++		target->vec[i] |= channels->vec[i];
++}
++
++static void brcms_c_locale_get_channels(const struct locale_info *locale,
++				    struct brcms_chanvec *channels)
++{
++	u8 i;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
++		if (locale->valid_channels & (1 << i))
++			brcms_c_locale_add_channels(channels,
++						g_table_locale_base[i]);
++	}
++}
++
++/*
++ * Locale Definitions - 2.4 GHz
++ */
++static const struct locale_info locale_i = {	/* locale i. channel 1 - 13 */
++	LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
++	LOCALE_RADAR_SET_NONE,
++	LOCALE_RESTRICTED_SET_2G_SHORT,
++	{QDB(19), QDB(19), QDB(19),
++	 QDB(19), QDB(19), QDB(19)},
++	{20, 20, 20, 0},
++	BRCMS_EIRP
++};
++
++/*
++ * Locale Definitions - 5 GHz
++ */
++static const struct locale_info locale_11 = {
++	/* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
++	LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
++	LOCALE_RADAR_SET_1,
++	LOCALE_RESTRICTED_NONE,
++	{QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
++	{23, 23, 23, 30, 30},
++	BRCMS_EIRP | BRCMS_DFS_EU
++};
++
++static const struct locale_info *g_locale_2g_table[] = {
++	&locale_i
++};
++
++static const struct locale_info *g_locale_5g_table[] = {
++	&locale_11
++};
++
++/*
++ * MIMO Locale Definitions - 2.4 GHz
++ */
++static const struct locale_mimo_info locale_bn = {
++	{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13)},
++	{0, 0, QDB(13), QDB(13), QDB(13),
++	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
++	 QDB(13), 0, 0},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_2g_table[] = {
++	&locale_bn
++};
++
++/*
++ * MIMO Locale Definitions - 5 GHz
++ */
++static const struct locale_mimo_info locale_11n = {
++	{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
++	{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
++	0
++};
++
++static const struct locale_mimo_info *g_mimo_5g_table[] = {
++	&locale_11n
++};
++
++static const struct {
++	char abbrev[BRCM_CNTRY_BUF_SZ];	/* country abbreviation */
++	struct country_info country;
++} cntry_locales[] = {
++	{
++	"X2", LOCALES(i, 11, bn, 11n)},	/* Worldwide RoW 2 */
++};
++
++#ifdef SUPPORT_40MHZ
++/* 20MHz channel info for 40MHz pairing support */
++struct chan20_info {
++	u8 sb;
++	u8 adj_sbs;
++};
++
++/* indicates adjacent channels that are allowed for a 40 Mhz channel and
++ * those that permitted by the HT
++ */
++struct chan20_info chan20_info[] = {
++	/* 11b/11g */
++/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
++/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 11 */ {12, (CH_LOWER_SB)},
++/* 12 */ {13, (CH_LOWER_SB)},
++/* 13 */ {14, (CH_LOWER_SB)},
++
++/* 11a japan high */
++/* 14 */ {34, (CH_UPPER_SB)},
++/* 15 */ {38, (CH_LOWER_SB)},
++/* 16 */ {42, (CH_LOWER_SB)},
++/* 17 */ {46, (CH_LOWER_SB)},
++
++/* 11a usa low */
++/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
++
++/* 11a Europe */
++/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 36 */ {140, (CH_LOWER_SB)},
++
++/* 11a usa high, ref5 only */
++/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
++/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
++/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
++/* 41 */ {165, (CH_LOWER_SB)},
++
++/* 11a japan */
++/* 42 */ {184, (CH_UPPER_SB)},
++/* 43 */ {188, (CH_LOWER_SB)},
++/* 44 */ {192, (CH_UPPER_SB)},
++/* 45 */ {196, (CH_LOWER_SB)},
++/* 46 */ {200, (CH_UPPER_SB)},
++/* 47 */ {204, (CH_LOWER_SB)},
++/* 48 */ {208, (CH_UPPER_SB)},
++/* 49 */ {212, (CH_LOWER_SB)},
++/* 50 */ {216, (CH_LOWER_SB)}
++};
++#endif				/* SUPPORT_40MHZ */
++
++static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table))
++		return NULL; /* error condition */
++
++	return g_locale_2g_table[locale_idx];
++}
++
++static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table))
++		return NULL; /* error condition */
++
++	return g_locale_5g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table))
++		return NULL;
++
++	return g_mimo_2g_table[locale_idx];
++}
++
++static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx)
++{
++	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table))
++		return NULL;
++
++	return g_mimo_5g_table[locale_idx];
++}
++
++static int
++brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			  char *mapped_ccode, uint *mapped_regrev)
++{
++	return false;
++}
++
++/*
++ * Indicates whether the country provided is valid to pass
++ * to cfg80211 or not.
++ *
++ * returns true if valid; false if not.
++ */
++static bool brcms_c_country_valid(const char *ccode)
++{
++	/*
++	 * only allow ascii alpha uppercase for the first 2
++	 * chars.
++	 */
++	if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
++	      (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A &&
++	      ccode[2] == '\0'))
++		return false;
++
++	/*
++	 * do not match ISO 3166-1 user assigned country codes
++	 * that may be in the driver table
++	 */
++	if (!strcmp("AA", ccode) ||        /* AA */
++	    !strcmp("ZZ", ccode) ||        /* ZZ */
++	    ccode[0] == 'X' ||             /* XA - XZ */
++	    (ccode[0] == 'Q' &&            /* QM - QZ */
++	     (ccode[1] >= 'M' && ccode[1] <= 'Z')))
++		return false;
++
++	if (!strcmp("NA", ccode))
++		return false;
++
++	return true;
++}
++
++/* Lookup a country info structure from a null terminated country
++ * abbreviation and regrev directly with no translation.
++ */
++static const struct country_info *
++brcms_c_country_lookup_direct(const char *ccode, uint regrev)
++{
++	uint size, i;
++
++	/* Should just return 0 for single locale driver. */
++	/* Keep it this way in case we add more locales. (for now anyway) */
++
++	/*
++	 * all other country def arrays are for regrev == 0, so if
++	 * regrev is non-zero, fail
++	 */
++	if (regrev > 0)
++		return NULL;
++
++	/* find matched table entry from country code */
++	size = ARRAY_SIZE(cntry_locales);
++	for (i = 0; i < size; i++) {
++		if (strcmp(ccode, cntry_locales[i].abbrev) == 0)
++			return &cntry_locales[i].country;
++	}
++	return NULL;
++}
++
++static const struct country_info *
++brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode,
++			char *mapped_ccode, uint *mapped_regrev)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	const struct country_info *country;
++	uint srom_regrev = wlc_cm->srom_regrev;
++	const char *srom_ccode = wlc_cm->srom_ccode;
++	int mapped;
++
++	/* check for currently supported ccode size */
++	if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
++			  "match\n", wlc->pub->unit, __func__, ccode);
++		return NULL;
++	}
++
++	/* default mapping is the given ccode and regrev 0 */
++	strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++	*mapped_regrev = 0;
++
++	/* If the desired country code matches the srom country code,
++	 * then the mapped country is the srom regulatory rev.
++	 * Otherwise look for an aggregate mapping.
++	 */
++	if (!strcmp(srom_ccode, ccode)) {
++		*mapped_regrev = srom_regrev;
++		mapped = 0;
++		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
++	} else {
++		mapped =
++		    brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
++					      mapped_regrev);
++	}
++
++	/* find the matching built-in country definition */
++	country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++
++	/* if there is not an exact rev match, default to rev zero */
++	if (country == NULL && *mapped_regrev != 0) {
++		*mapped_regrev = 0;
++		country =
++		    brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev);
++	}
++
++	return country;
++}
++
++/* Lookup a country info structure from a null terminated country code
++ * The lookup is case sensitive.
++ */
++static const struct country_info *
++brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/*
++	 * map the country code to a built-in country code, regrev, and
++	 * country_info struct
++	 */
++	country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode,
++					  &mapped_regrev);
++
++	return country;
++}
++
++/*
++ * reset the quiet channels vector to the union
++ * of the restricted and radar channel sets
++ */
++static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct brcms_chanvec *chanvec;
++
++	memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec));
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		/* initialize quiet channels for restricted channels */
++		chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
++
++	}
++}
++
++/* Is the channel valid for the current locale and current band? */
++static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return ((val < MAXCHANNEL) &&
++		isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
++		      val));
++}
++
++/* Is the channel valid for the current locale and specified band? */
++static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm,
++					    uint bandunit, uint val)
++{
++	return ((val < MAXCHANNEL)
++		&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
++}
++
++/* Is the channel valid for the current locale? (but don't consider channels not
++ *   available due to bandlocking)
++ */
++static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++
++	return brcms_c_valid_channel20(wlc->cmi, val) ||
++		(!wlc->bandlocked
++		 && brcms_c_valid_channel20_in_band(wlc->cmi,
++						    OTHERBANDUNIT(wlc), val));
++}
++
++/* JP, J1 - J10 are Japan ccodes */
++static bool brcms_c_japan_ccode(const char *ccode)
++{
++	return (ccode[0] == 'J' &&
++		(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
++}
++
++/* Returns true if currently set country is Japan or variant */
++static bool brcms_c_japan(struct brcms_c_info *wlc)
++{
++	return brcms_c_japan_ccode(wlc->cmi->country_abbrev);
++}
++
++static void
++brcms_c_channel_min_txpower_limits_with_local_constraint(
++		struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr,
++		u8 local_constraint_qdbm)
++{
++	int j;
++
++	/* CCK Rates */
++	for (j = 0; j < WL_TX_POWER_CCK_NUM; j++)
++		txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM SISO */
++	for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++)
++		txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
++
++	/* 20 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_cdd[j] =
++		    min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_siso[j] =
++		    min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
++
++	/* 40 MHz Legacy OFDM CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++)
++		txpwr->ofdm_40_cdd[j] =
++		    min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_siso[j] =
++		    min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_cdd[j] =
++		    min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_20_stbc[j] =
++		    min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
++
++	/* 20MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_20_mimo[j] =
++		    min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 SISO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_siso[j] =
++		    min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 CDD */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_cdd[j] =
++		    min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 0-7 STBC */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++)
++		txpwr->mcs_40_stbc[j] =
++		    min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 8-15 MIMO */
++	for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++)
++		txpwr->mcs_40_mimo[j] =
++		    min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
++
++	/* 40MHz MCS 32 */
++	txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
++
++}
++
++/* Update the radio state (enable/disable) and tx power targets
++ * based on a new set of channel/regulatory information
++ */
++static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint chan;
++	struct txpwr_limits txpwr;
++
++	/* search for the existence of any valid channel */
++	for (chan = 0; chan < MAXCHANNEL; chan++) {
++		if (brcms_c_valid_channel20_db(wlc->cmi, chan))
++			break;
++	}
++	if (chan == MAXCHANNEL)
++		chan = INVCHANNEL;
++
++	/*
++	 * based on the channel search above, set or
++	 * clear WL_RADIO_COUNTRY_DISABLE.
++	 */
++	if (chan == INVCHANNEL) {
++		/*
++		 * country/locale with no valid channels, set
++		 * the radio disable bit
++		 */
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
++			  "nbands %d bandlocked %d\n", wlc->pub->unit,
++			  __func__, wlc_cm->country_abbrev, wlc->pub->_nbands,
++			  wlc->bandlocked);
++	} else if (mboolisset(wlc->pub->radio_disabled,
++			      WL_RADIO_COUNTRY_DISABLE)) {
++		/*
++		 * country/locale with valid channel, clear
++		 * the radio disable bit
++		 */
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
++	}
++
++	/*
++	 * Now that the country abbreviation is set, if the radio supports 2G,
++	 * then set channel 14 restrictions based on the new locale.
++	 */
++	if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G)
++		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
++						     brcms_c_japan(wlc) ? true :
++						     false);
++
++	if (wlc->pub->up && chan != INVCHANNEL) {
++		brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
++		brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm,
++			&txpwr, BRCMS_TXPWR_MAX);
++		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
++	}
++}
++
++static int
++brcms_c_channels_init(struct brcms_cm_info *wlc_cm,
++		      const struct country_info *country)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i, j;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	struct brcms_chanvec sup_chan;
++	const struct locale_mimo_info *li_mimo;
++
++	band = wlc->band;
++	for (i = 0; i < wlc->pub->_nbands;
++	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
++
++		li = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_locale_5g(country->locale_5G) :
++		    brcms_c_get_locale_2g(country->locale_2G);
++		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
++		li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++		    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++		    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++		/* merge the mimo non-mimo locale flags */
++		wlc_cm->bandstate[band->bandunit].locale_flags |=
++		    li_mimo->flags;
++
++		wlc_cm->bandstate[band->bandunit].restricted_channels =
++		    g_table_restricted_chan[li->restricted_channels];
++		wlc_cm->bandstate[band->bandunit].radar_channels =
++		    g_table_radar_set[li->radar_channels];
++
++		/*
++		 * set the channel availability, masking out the channels
++		 * that may not be supported on this phy.
++		 */
++		wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
++					      &sup_chan);
++		brcms_c_locale_get_channels(li,
++					&wlc_cm->bandstate[band->bandunit].
++					valid_channels);
++		for (j = 0; j < sizeof(struct brcms_chanvec); j++)
++			wlc_cm->bandstate[band->bandunit].valid_channels.
++			    vec[j] &= sup_chan.vec[j];
++	}
++
++	brcms_c_quiet_channels_reset(wlc_cm);
++	brcms_c_channels_commit(wlc_cm);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information
++ * using a country code as the source. Look up built in country
++ * information found with the country code.
++ */
++static void
++brcms_c_set_country_common(struct brcms_cm_info *wlc_cm,
++		       const char *country_abbrev,
++		       const char *ccode, uint regrev,
++		       const struct country_info *country)
++{
++	const struct locale_info *locale;
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	char prev_country_abbrev[BRCM_CNTRY_BUF_SZ];
++
++	/* save current country state */
++	wlc_cm->country = country;
++
++	memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
++		BRCM_CNTRY_BUF_SZ - 1);
++
++	strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++	strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1);
++	wlc_cm->regrev = regrev;
++
++	if ((wlc->pub->_n_enab & SUPPORT_11N) !=
++	    wlc->protection->nmode_user)
++		brcms_c_set_nmode(wlc);
++
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	/* set or restore gmode as required by regulatory */
++	locale = brcms_c_get_locale_2g(country->locale_2G);
++	if (locale && (locale->flags & BRCMS_NO_OFDM))
++		brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false);
++	else
++		brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
++
++	brcms_c_channels_init(wlc_cm, country);
++
++	return;
++}
++
++static int
++brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm,
++			const char *country_abbrev,
++			const char *ccode, int regrev)
++{
++	const struct country_info *country;
++	char mapped_ccode[BRCM_CNTRY_BUF_SZ];
++	uint mapped_regrev;
++
++	/* if regrev is -1, lookup the mapped country code,
++	 * otherwise use the ccode and regrev directly
++	 */
++	if (regrev == -1) {
++		/*
++		 * map the country code to a built-in country
++		 * code, regrev, and country_info
++		 */
++		country =
++		    brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode,
++					&mapped_regrev);
++	} else {
++		/* find the matching built-in country definition */
++		country = brcms_c_country_lookup_direct(ccode, regrev);
++		strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ);
++		mapped_regrev = regrev;
++	}
++
++	if (country == NULL)
++		return -EINVAL;
++
++	/* set the driver state for the country */
++	brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
++			       mapped_regrev, country);
++
++	return 0;
++}
++
++/*
++ * set the driver's current country and regulatory information using
++ * a country code as the source. Lookup built in country information
++ * found with the country code.
++ */
++static int
++brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode)
++{
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ);
++	return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
++}
++
++struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc)
++{
++	struct brcms_cm_info *wlc_cm;
++	char country_abbrev[BRCM_CNTRY_BUF_SZ];
++	const struct country_info *country;
++	struct brcms_pub *pub = wlc->pub;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC);
++	if (wlc_cm == NULL)
++		return NULL;
++	wlc_cm->pub = pub;
++	wlc_cm->wlc = wlc;
++	wlc->cmi = wlc_cm;
++
++	/* store the country code for passing up as a regulatory hint */
++	if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2))
++		strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2));
++
++	/*
++	 * internal country information which must match
++	 * regulatory constraints in firmware
++	 */
++	memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ);
++	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
++	country = brcms_c_country_lookup(wlc, country_abbrev);
++
++	/* save default country for exiting 11d regulatory mode */
++	strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1);
++
++	/* initialize autocountry_default to driver default */
++	strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1);
++
++	brcms_c_set_countrycode(wlc_cm, country_abbrev);
++
++	return wlc_cm;
++}
++
++void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm)
++{
++	kfree(wlc_cm);
++}
++
++u8
++brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++				     uint bandunit)
++{
++	return wlc_cm->bandstate[bandunit].locale_flags;
++}
++
++static bool
++brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) &&
++		CHSPEC_IS40(chspec) ?
++		(isset(wlc_cm->quiet_channels.vec,
++		       lower_20_sb(CHSPEC_CHANNEL(chspec))) ||
++		 isset(wlc_cm->quiet_channels.vec,
++		       upper_20_sb(CHSPEC_CHANNEL(chspec)))) :
++		isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec));
++}
++
++void
++brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
++			 u8 local_constraint_qdbm)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	struct txpwr_limits txpwr;
++
++	brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr);
++
++	brcms_c_channel_min_txpower_limits_with_local_constraint(
++		wlc_cm, &txpwr, local_constraint_qdbm
++	);
++
++	brcms_b_set_chanspec(wlc->hw, chanspec,
++			      (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0),
++			      &txpwr);
++}
++
++void
++brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec,
++		       struct txpwr_limits *txpwr)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	uint i;
++	uint chan;
++	int maxpwr;
++	int delta;
++	const struct country_info *country;
++	struct brcms_band *band;
++	const struct locale_info *li;
++	int conducted_max = BRCMS_TXPWR_MAX;
++	int conducted_ofdm_max = BRCMS_TXPWR_MAX;
++	const struct locale_mimo_info *li_mimo;
++	int maxpwr20, maxpwr40;
++	int maxpwr_idx;
++	uint j;
++
++	memset(txpwr, 0, sizeof(struct txpwr_limits));
++
++	if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) {
++		country = brcms_c_country_lookup(wlc, wlc->autocountry_default);
++		if (country == NULL)
++			return;
++	} else {
++		country = wlc_cm->country;
++	}
++
++	chan = CHSPEC_CHANNEL(chanspec);
++	band = wlc->bandstate[chspec_bandunit(chanspec)];
++	li = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_locale_5g(country->locale_5G) :
++	    brcms_c_get_locale_2g(country->locale_2G);
++
++	li_mimo = (band->bandtype == BRCM_BAND_5G) ?
++	    brcms_c_get_mimo_5g(country->locale_mimo_5G) :
++	    brcms_c_get_mimo_2g(country->locale_mimo_2G);
++
++	if (li->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (li == &locale_i) {
++		conducted_max = QDB(22);
++		conducted_ofdm_max = QDB(22);
++	}
++
++	/* CCK txpwr limits for 2.4G band */
++	if (band->bandtype == BRCM_BAND_2G) {
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
++
++		maxpwr = maxpwr - delta;
++		maxpwr = max(maxpwr, 0);
++		maxpwr = min(maxpwr, conducted_max);
++
++		for (i = 0; i < BRCMS_NUM_RATES_CCK; i++)
++			txpwr->cck[i] = (u8) maxpwr;
++	}
++
++	/* OFDM txpwr limits for 2.4G or 5G bands */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
++	else
++		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
++
++	maxpwr = maxpwr - delta;
++	maxpwr = max(maxpwr, 0);
++	maxpwr = min(maxpwr, conducted_ofdm_max);
++
++	/* Keep OFDM lmit below CCK limit */
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++)
++		txpwr->ofdm[i] = (u8) maxpwr;
++
++	for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) {
++		/*
++		 * OFDM 40 MHz SISO has the same power as the corresponding
++		 * MCS0-7 rate unless overriden by the locale specific code.
++		 * We set this value to 0 as a flag (presumably 0 dBm isn't
++		 * a possibility) and then copy the MCS0-7 value to the 40 MHz
++		 * value if it wasn't explicitly set.
++		 */
++		txpwr->ofdm_40_siso[i] = 0;
++
++		txpwr->ofdm_cdd[i] = (u8) maxpwr;
++
++		txpwr->ofdm_40_cdd[i] = 0;
++	}
++
++	/* MIMO/HT specific limits */
++	if (li_mimo->flags & BRCMS_EIRP) {
++		delta = band->antgain;
++	} else {
++		delta = 0;
++		if (band->antgain > QDB(6))
++			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
++	}
++
++	if (band->bandtype == BRCM_BAND_2G)
++		maxpwr_idx = (chan - 1);
++	else
++		maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
++
++	maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
++	maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
++
++	maxpwr20 = maxpwr20 - delta;
++	maxpwr20 = max(maxpwr20, 0);
++	maxpwr40 = maxpwr40 - delta;
++	maxpwr40 = max(maxpwr40, 0);
++
++	/* Fill in the MCS 0-7 (SISO) rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++
++		/*
++		 * 20 MHz has the same power as the corresponding OFDM rate
++		 * unless overriden by the locale specific code.
++		 */
++		txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
++		txpwr->mcs_40_siso[i] = 0;
++	}
++
++	/* Fill in the MCS 0-7 CDD rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
++		txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
++	}
++
++	/*
++	 * These locales have SISO expressed in the
++	 * table and override CDD later
++	 */
++	if (li_mimo == &locale_bn) {
++		if (li_mimo == &locale_bn) {
++			maxpwr20 = QDB(16);
++			maxpwr40 = 0;
++
++			if (chan >= 3 && chan <= 11)
++				maxpwr40 = QDB(16);
++		}
++
++		for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++			txpwr->mcs_20_siso[i] = (u8) maxpwr20;
++			txpwr->mcs_40_siso[i] = (u8) maxpwr40;
++		}
++	}
++
++	/* Fill in the MCS 0-7 STBC rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		txpwr->mcs_20_stbc[i] = 0;
++		txpwr->mcs_40_stbc[i] = 0;
++	}
++
++	/* Fill in the MCS 8-15 SDM rates */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) {
++		txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
++		txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
++	}
++
++	/* Fill in MCS32 */
++	txpwr->mcs32 = (u8) maxpwr40;
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_cdd[i] == 0)
++			txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_cdd[i] == 0)
++				txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
++		}
++	}
++
++	/*
++	 * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO
++	 * value if it wasn't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_40_siso[i] == 0)
++			txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) {
++		if (txpwr->ofdm_40_siso[i] == 0)
++			txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		if (i == 0) {
++			i = i + 1;
++			if (txpwr->ofdm_40_siso[i] == 0)
++				txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
++		}
++	}
++
++	/*
++	 * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding
++	 * STBC values if they weren't provided explicitly.
++	 */
++	for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) {
++		if (txpwr->mcs_20_stbc[i] == 0)
++			txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
++
++		if (txpwr->mcs_40_stbc[i] == 0)
++			txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
++	}
++
++	return;
++}
++
++/*
++ * Verify the chanspec is using a legal set of parameters, i.e. that the
++ * chanspec specified a band, bw, ctl_sb and channel and that the
++ * combination could be legal given any set of circumstances.
++ * RETURNS: true is the chanspec is malformed, false if it looks good.
++ */
++static bool brcms_c_chspec_malformed(u16 chanspec)
++{
++	/* must be 2G or 5G band */
++	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
++		return true;
++	/* must be 20 or 40 bandwidth */
++	if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
++		return true;
++
++	/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
++	if (CHSPEC_IS20(chanspec)) {
++		if (!CHSPEC_SB_NONE(chanspec))
++			return true;
++	} else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) {
++		return true;
++	}
++
++	return false;
++}
++
++/*
++ * Validate the chanspec for this locale, for 40MHZ we need to also
++ * check that the sidebands are valid 20MZH channels in this locale
++ * and they are also a legal HT combination
++ */
++static bool
++brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec,
++			   bool dualband)
++{
++	struct brcms_c_info *wlc = wlc_cm->wlc;
++	u8 channel = CHSPEC_CHANNEL(chspec);
++
++	/* check the chanspec */
++	if (brcms_c_chspec_malformed(chspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
++			wlc->pub->unit, chspec);
++		return false;
++	}
++
++	if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
++	    chspec_bandunit(chspec))
++		return false;
++
++	/* Check a 20Mhz channel */
++	if (CHSPEC_IS20(chspec)) {
++		if (dualband)
++			return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi,
++							  channel);
++		else
++			return brcms_c_valid_channel20(wlc_cm->wlc->cmi,
++						       channel);
++	}
++#ifdef SUPPORT_40MHZ
++	/*
++	 * We know we are now checking a 40MHZ channel, so we should
++	 * only be here for NPHYS
++	 */
++	if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) {
++		u8 upper_sideband = 0, idx;
++		u8 num_ch20_entries =
++		    sizeof(chan20_info) / sizeof(struct chan20_info);
++
++		if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec)))
++			return false;
++
++		if (dualband) {
++			if (!brcms_c_valid_channel20_db(wlc->cmi,
++							lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20_db(wlc->cmi,
++							upper_20_sb(channel)))
++				return false;
++		} else {
++			if (!brcms_c_valid_channel20(wlc->cmi,
++						     lower_20_sb(channel)) ||
++			    !brcms_c_valid_channel20(wlc->cmi,
++						     upper_20_sb(channel)))
++				return false;
++		}
++
++		/* find the lower sideband info in the sideband array */
++		for (idx = 0; idx < num_ch20_entries; idx++) {
++			if (chan20_info[idx].sb == lower_20_sb(channel))
++				upper_sideband = chan20_info[idx].adj_sbs;
++		}
++		/* check that the lower sideband allows an upper sideband */
++		if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
++		    (CH_UPPER_SB | CH_EWA_VALID))
++			return true;
++		return false;
++	}
++#endif				/* 40 MHZ */
++
++	return false;
++}
++
++bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec)
++{
++	return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+new file mode 100644
+index 0000000..808cb4f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_CHANNEL_H_
++#define _BRCM_CHANNEL_H_
++
++/* conversion for phy txpwr calculations that use .25 dB units */
++#define BRCMS_TXPWR_DB_FACTOR 4
++
++/* bits for locale_info flags */
++#define BRCMS_PEAK_CONDUCTED	0x00	/* Peak for locals */
++#define BRCMS_EIRP		0x01	/* Flag for EIRP */
++#define BRCMS_DFS_TPC		0x02	/* Flag for DFS TPC */
++#define BRCMS_NO_OFDM		0x04	/* Flag for No OFDM */
++#define BRCMS_NO_40MHZ		0x08	/* Flag for No MIMO 40MHz */
++#define BRCMS_NO_MIMO		0x10	/* Flag for No MIMO, 20 or 40 MHz */
++#define BRCMS_RADAR_TYPE_EU       0x20	/* Flag for EU */
++#define BRCMS_DFS_FCC             BRCMS_DFS_TPC	/* Flag for DFS FCC */
++
++#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
++
++extern struct brcms_cm_info *
++brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
++
++extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
++
++extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
++					   uint bandunit);
++
++extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
++				      u16 chspec);
++
++extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
++				   u16 chanspec,
++				   struct txpwr_limits *txpwr);
++extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
++				     u16 chanspec,
++				     u8 local_constraint_qdbm);
++
++#endif				/* _WLC_CHANNEL_H */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/d11.h b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+new file mode 100644
+index 0000000..3f659e0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h
+@@ -0,0 +1,1901 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_D11_H_
++#define	_BRCM_D11_H_
++
++#include <linux/ieee80211.h>
++
++#include <defs.h>
++#include "pub.h"
++#include "dma.h"
++
++/* RX FIFO numbers */
++#define	RX_FIFO			0	/* data and ctl frames */
++#define	RX_TXSTATUS_FIFO	3	/* RX fifo for tx status packages */
++
++/* TX FIFO numbers using WME Access Category */
++#define	TX_AC_BK_FIFO		0	/* Background TX FIFO */
++#define	TX_AC_BE_FIFO		1	/* Best-Effort TX FIFO */
++#define	TX_AC_VI_FIFO		2	/* Video TX FIFO */
++#define	TX_AC_VO_FIFO		3	/* Voice TX FIFO */
++#define	TX_BCMC_FIFO		4	/* Broadcast/Multicast TX FIFO */
++#define	TX_ATIM_FIFO		5	/* TX fifo for ATIM window info */
++
++/* Addr is byte address used by SW; offset is word offset used by uCode */
++
++/* Per AC TX limit settings */
++#define M_AC_TXLMT_BASE_ADDR         (0x180 * 2)
++#define M_AC_TXLMT_ADDR(_ac)         (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
++
++/* Legacy TX FIFO numbers */
++#define	TX_DATA_FIFO		TX_AC_BE_FIFO
++#define	TX_CTL_FIFO		TX_AC_VO_FIFO
++
++#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
++
++struct intctrlregs {
++	u32 intstatus;
++	u32 intmask;
++};
++
++/* PIO structure,
++ *  support two PIO format: 2 bytes access and 4 bytes access
++ *  basic FIFO register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++/* 2byte-wide pio register set per channel(xmt or rcv) */
++struct pio2regs {
++	u16 fifocontrol;
++	u16 fifodata;
++	u16 fifofree;	/* only valid in xmt channel, not in rcv channel */
++	u16 PAD;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio2regp {
++	struct pio2regs tx;
++	struct pio2regs rx;
++};
++
++/* 4byte-wide pio register set per channel(xmt or rcv) */
++struct pio4regs {
++	u32 fifocontrol;
++	u32 fifodata;
++};
++
++/* a pair of pio channels(tx and rx) */
++struct pio4regp {
++	struct pio4regs tx;
++	struct pio4regs rx;
++};
++
++/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
++ * write: only low 16b-it half can be written
++ */
++union pmqreg {
++	u32 pmqhostdata;	/* read only! */
++	struct {
++		u16 pmqctrlstatus;	/* read/write */
++		u16 PAD;
++	} w;
++};
++
++struct fifo64 {
++	struct dma64regs dmaxmt;	/* dma tx */
++	struct pio4regs piotx;	/* pio tx */
++	struct dma64regs dmarcv;	/* dma rx */
++	struct pio4regs piorx;	/* pio rx */
++};
++
++/*
++ * Host Interface Registers
++ */
++struct d11regs {
++	/* Device Control ("semi-standard host registers") */
++	u32 PAD[3];		/* 0x0 - 0x8 */
++	u32 biststatus;	/* 0xC */
++	u32 biststatus2;	/* 0x10 */
++	u32 PAD;		/* 0x14 */
++	u32 gptimer;		/* 0x18 */
++	u32 usectimer;	/* 0x1c *//* for corerev >= 26 */
++
++	/* Interrupt Control *//* 0x20 */
++	struct intctrlregs intctrlregs[8];
++
++	u32 PAD[40];		/* 0x60 - 0xFC */
++
++	u32 intrcvlazy[4];	/* 0x100 - 0x10C */
++
++	u32 PAD[4];		/* 0x110 - 0x11c */
++
++	u32 maccontrol;	/* 0x120 */
++	u32 maccommand;	/* 0x124 */
++	u32 macintstatus;	/* 0x128 */
++	u32 macintmask;	/* 0x12C */
++
++	/* Transmit Template Access */
++	u32 tplatewrptr;	/* 0x130 */
++	u32 tplatewrdata;	/* 0x134 */
++	u32 PAD[2];		/* 0x138 - 0x13C */
++
++	/* PMQ registers */
++	union pmqreg pmqreg;	/* 0x140 */
++	u32 pmqpatl;		/* 0x144 */
++	u32 pmqpath;		/* 0x148 */
++	u32 PAD;		/* 0x14C */
++
++	u32 chnstatus;	/* 0x150 */
++	u32 psmdebug;	/* 0x154 */
++	u32 phydebug;	/* 0x158 */
++	u32 machwcap;	/* 0x15C */
++
++	/* Extended Internal Objects */
++	u32 objaddr;		/* 0x160 */
++	u32 objdata;		/* 0x164 */
++	u32 PAD[2];		/* 0x168 - 0x16c */
++
++	u32 frmtxstatus;	/* 0x170 */
++	u32 frmtxstatus2;	/* 0x174 */
++	u32 PAD[2];		/* 0x178 - 0x17c */
++
++	/* TSF host access */
++	u32 tsf_timerlow;	/* 0x180 */
++	u32 tsf_timerhigh;	/* 0x184 */
++	u32 tsf_cfprep;	/* 0x188 */
++	u32 tsf_cfpstart;	/* 0x18c */
++	u32 tsf_cfpmaxdur32;	/* 0x190 */
++	u32 PAD[3];		/* 0x194 - 0x19c */
++
++	u32 maccontrol1;	/* 0x1a0 */
++	u32 machwcap1;	/* 0x1a4 */
++	u32 PAD[14];		/* 0x1a8 - 0x1dc */
++
++	/* Clock control and hardware workarounds*/
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 d11_phypllctl;	/* the phypll request/avail bits are
++				 * moved to clk_ctl_st
++				 */
++	u32 PAD[5];		/* 0x1ec - 0x1fc */
++
++	/* 0x200-0x37F dma/pio registers */
++	struct fifo64 fifo64regs[6];
++
++	/* FIFO diagnostic port access */
++	struct dma32diag dmafifo;	/* 0x380 - 0x38C */
++
++	u32 aggfifocnt;	/* 0x390 */
++	u32 aggfifodata;	/* 0x394 */
++	u32 PAD[16];		/* 0x398 - 0x3d4 */
++	u16 radioregaddr;	/* 0x3d8 */
++	u16 radioregdata;	/* 0x3da */
++
++	/*
++	 * time delay between the change on rf disable input and
++	 * radio shutdown
++	 */
++	u32 rfdisabledly;	/* 0x3DC */
++
++	/* PHY register access */
++	u16 phyversion;	/* 0x3e0 - 0x0 */
++	u16 phybbconfig;	/* 0x3e2 - 0x1 */
++	u16 phyadcbias;	/* 0x3e4 - 0x2  Bphy only */
++	u16 phyanacore;	/* 0x3e6 - 0x3  pwwrdwn on aphy */
++	u16 phyrxstatus0;	/* 0x3e8 - 0x4 */
++	u16 phyrxstatus1;	/* 0x3ea - 0x5 */
++	u16 phycrsth;	/* 0x3ec - 0x6 */
++	u16 phytxerror;	/* 0x3ee - 0x7 */
++	u16 phychannel;	/* 0x3f0 - 0x8 */
++	u16 PAD[1];		/* 0x3f2 - 0x9 */
++	u16 phytest;		/* 0x3f4 - 0xa */
++	u16 phy4waddr;	/* 0x3f6 - 0xb */
++	u16 phy4wdatahi;	/* 0x3f8 - 0xc */
++	u16 phy4wdatalo;	/* 0x3fa - 0xd */
++	u16 phyregaddr;	/* 0x3fc - 0xe */
++	u16 phyregdata;	/* 0x3fe - 0xf */
++
++	/* IHR *//* 0x400 - 0x7FE */
++
++	/* RXE Block */
++	u16 PAD[3];		/* 0x400 - 0x406 */
++	u16 rcv_fifo_ctl;	/* 0x406 */
++	u16 PAD;		/* 0x408 - 0x40a */
++	u16 rcv_frm_cnt;	/* 0x40a */
++	u16 PAD[4];		/* 0x40a - 0x414 */
++	u16 rssi;		/* 0x414 */
++	u16 PAD[5];		/* 0x414 - 0x420 */
++	u16 rcm_ctl;		/* 0x420 */
++	u16 rcm_mat_data;	/* 0x422 */
++	u16 rcm_mat_mask;	/* 0x424 */
++	u16 rcm_mat_dly;	/* 0x426 */
++	u16 rcm_cond_mask_l;	/* 0x428 */
++	u16 rcm_cond_mask_h;	/* 0x42A */
++	u16 rcm_cond_dly;	/* 0x42C */
++	u16 PAD[1];		/* 0x42E */
++	u16 ext_ihr_addr;	/* 0x430 */
++	u16 ext_ihr_data;	/* 0x432 */
++	u16 rxe_phyrs_2;	/* 0x434 */
++	u16 rxe_phyrs_3;	/* 0x436 */
++	u16 phy_mode;	/* 0x438 */
++	u16 rcmta_ctl;	/* 0x43a */
++	u16 rcmta_size;	/* 0x43c */
++	u16 rcmta_addr0;	/* 0x43e */
++	u16 rcmta_addr1;	/* 0x440 */
++	u16 rcmta_addr2;	/* 0x442 */
++	u16 PAD[30];		/* 0x444 - 0x480 */
++
++	/* PSM Block *//* 0x480 - 0x500 */
++
++	u16 PAD;		/* 0x480 */
++	u16 psm_maccontrol_h;	/* 0x482 */
++	u16 psm_macintstatus_l;	/* 0x484 */
++	u16 psm_macintstatus_h;	/* 0x486 */
++	u16 psm_macintmask_l;	/* 0x488 */
++	u16 psm_macintmask_h;	/* 0x48A */
++	u16 PAD;		/* 0x48C */
++	u16 psm_maccommand;	/* 0x48E */
++	u16 psm_brc;		/* 0x490 */
++	u16 psm_phy_hdr_param;	/* 0x492 */
++	u16 psm_postcard;	/* 0x494 */
++	u16 psm_pcard_loc_l;	/* 0x496 */
++	u16 psm_pcard_loc_h;	/* 0x498 */
++	u16 psm_gpio_in;	/* 0x49A */
++	u16 psm_gpio_out;	/* 0x49C */
++	u16 psm_gpio_oe;	/* 0x49E */
++
++	u16 psm_bred_0;	/* 0x4A0 */
++	u16 psm_bred_1;	/* 0x4A2 */
++	u16 psm_bred_2;	/* 0x4A4 */
++	u16 psm_bred_3;	/* 0x4A6 */
++	u16 psm_brcl_0;	/* 0x4A8 */
++	u16 psm_brcl_1;	/* 0x4AA */
++	u16 psm_brcl_2;	/* 0x4AC */
++	u16 psm_brcl_3;	/* 0x4AE */
++	u16 psm_brpo_0;	/* 0x4B0 */
++	u16 psm_brpo_1;	/* 0x4B2 */
++	u16 psm_brpo_2;	/* 0x4B4 */
++	u16 psm_brpo_3;	/* 0x4B6 */
++	u16 psm_brwk_0;	/* 0x4B8 */
++	u16 psm_brwk_1;	/* 0x4BA */
++	u16 psm_brwk_2;	/* 0x4BC */
++	u16 psm_brwk_3;	/* 0x4BE */
++
++	u16 psm_base_0;	/* 0x4C0 */
++	u16 psm_base_1;	/* 0x4C2 */
++	u16 psm_base_2;	/* 0x4C4 */
++	u16 psm_base_3;	/* 0x4C6 */
++	u16 psm_base_4;	/* 0x4C8 */
++	u16 psm_base_5;	/* 0x4CA */
++	u16 psm_base_6;	/* 0x4CC */
++	u16 psm_pc_reg_0;	/* 0x4CE */
++	u16 psm_pc_reg_1;	/* 0x4D0 */
++	u16 psm_pc_reg_2;	/* 0x4D2 */
++	u16 psm_pc_reg_3;	/* 0x4D4 */
++	u16 PAD[0xD];	/* 0x4D6 - 0x4DE */
++	u16 psm_corectlsts;	/* 0x4f0 *//* Corerev >= 13 */
++	u16 PAD[0x7];	/* 0x4f2 - 0x4fE */
++
++	/* TXE0 Block *//* 0x500 - 0x580 */
++	u16 txe_ctl;		/* 0x500 */
++	u16 txe_aux;		/* 0x502 */
++	u16 txe_ts_loc;	/* 0x504 */
++	u16 txe_time_out;	/* 0x506 */
++	u16 txe_wm_0;	/* 0x508 */
++	u16 txe_wm_1;	/* 0x50A */
++	u16 txe_phyctl;	/* 0x50C */
++	u16 txe_status;	/* 0x50E */
++	u16 txe_mmplcp0;	/* 0x510 */
++	u16 txe_mmplcp1;	/* 0x512 */
++	u16 txe_phyctl1;	/* 0x514 */
++
++	u16 PAD[0x05];	/* 0x510 - 0x51E */
++
++	/* Transmit control */
++	u16 xmtfifodef;	/* 0x520 */
++	u16 xmtfifo_frame_cnt;	/* 0x522 *//* Corerev >= 16 */
++	u16 xmtfifo_byte_cnt;	/* 0x524 *//* Corerev >= 16 */
++	u16 xmtfifo_head;	/* 0x526 *//* Corerev >= 16 */
++	u16 xmtfifo_rd_ptr;	/* 0x528 *//* Corerev >= 16 */
++	u16 xmtfifo_wr_ptr;	/* 0x52A *//* Corerev >= 16 */
++	u16 xmtfifodef1;	/* 0x52C *//* Corerev >= 16 */
++
++	u16 PAD[0x09];	/* 0x52E - 0x53E */
++
++	u16 xmtfifocmd;	/* 0x540 */
++	u16 xmtfifoflush;	/* 0x542 */
++	u16 xmtfifothresh;	/* 0x544 */
++	u16 xmtfifordy;	/* 0x546 */
++	u16 xmtfifoprirdy;	/* 0x548 */
++	u16 xmtfiforqpri;	/* 0x54A */
++	u16 xmttplatetxptr;	/* 0x54C */
++	u16 PAD;		/* 0x54E */
++	u16 xmttplateptr;	/* 0x550 */
++	u16 smpl_clct_strptr;	/* 0x552 *//* Corerev >= 22 */
++	u16 smpl_clct_stpptr;	/* 0x554 *//* Corerev >= 22 */
++	u16 smpl_clct_curptr;	/* 0x556 *//* Corerev >= 22 */
++	u16 PAD[0x04];	/* 0x558 - 0x55E */
++	u16 xmttplatedatalo;	/* 0x560 */
++	u16 xmttplatedatahi;	/* 0x562 */
++
++	u16 PAD[2];		/* 0x564 - 0x566 */
++
++	u16 xmtsel;		/* 0x568 */
++	u16 xmttxcnt;	/* 0x56A */
++	u16 xmttxshmaddr;	/* 0x56C */
++
++	u16 PAD[0x09];	/* 0x56E - 0x57E */
++
++	/* TXE1 Block */
++	u16 PAD[0x40];	/* 0x580 - 0x5FE */
++
++	/* TSF Block */
++	u16 PAD[0X02];	/* 0x600 - 0x602 */
++	u16 tsf_cfpstrt_l;	/* 0x604 */
++	u16 tsf_cfpstrt_h;	/* 0x606 */
++	u16 PAD[0X05];	/* 0x608 - 0x610 */
++	u16 tsf_cfppretbtt;	/* 0x612 */
++	u16 PAD[0XD];	/* 0x614 - 0x62C */
++	u16 tsf_clk_frac_l;	/* 0x62E */
++	u16 tsf_clk_frac_h;	/* 0x630 */
++	u16 PAD[0X14];	/* 0x632 - 0x658 */
++	u16 tsf_random;	/* 0x65A */
++	u16 PAD[0x05];	/* 0x65C - 0x664 */
++	/* GPTimer 2 registers */
++	u16 tsf_gpt2_stat;	/* 0x666 */
++	u16 tsf_gpt2_ctr_l;	/* 0x668 */
++	u16 tsf_gpt2_ctr_h;	/* 0x66A */
++	u16 tsf_gpt2_val_l;	/* 0x66C */
++	u16 tsf_gpt2_val_h;	/* 0x66E */
++	u16 tsf_gptall_stat;	/* 0x670 */
++	u16 PAD[0x07];	/* 0x672 - 0x67E */
++
++	/* IFS Block */
++	u16 ifs_sifs_rx_tx_tx;	/* 0x680 */
++	u16 ifs_sifs_nav_tx;	/* 0x682 */
++	u16 ifs_slot;	/* 0x684 */
++	u16 PAD;		/* 0x686 */
++	u16 ifs_ctl;		/* 0x688 */
++	u16 PAD[0x3];	/* 0x68a - 0x68F */
++	u16 ifsstat;		/* 0x690 */
++	u16 ifsmedbusyctl;	/* 0x692 */
++	u16 iftxdur;		/* 0x694 */
++	u16 PAD[0x3];	/* 0x696 - 0x69b */
++	/* EDCF support in dot11macs */
++	u16 ifs_aifsn;	/* 0x69c */
++	u16 ifs_ctl1;	/* 0x69e */
++
++	/* slow clock registers */
++	u16 scc_ctl;		/* 0x6a0 */
++	u16 scc_timer_l;	/* 0x6a2 */
++	u16 scc_timer_h;	/* 0x6a4 */
++	u16 scc_frac;	/* 0x6a6 */
++	u16 scc_fastpwrup_dly;	/* 0x6a8 */
++	u16 scc_per;		/* 0x6aa */
++	u16 scc_per_frac;	/* 0x6ac */
++	u16 scc_cal_timer_l;	/* 0x6ae */
++	u16 scc_cal_timer_h;	/* 0x6b0 */
++	u16 PAD;		/* 0x6b2 */
++
++	u16 PAD[0x26];
++
++	/* NAV Block */
++	u16 nav_ctl;		/* 0x700 */
++	u16 navstat;		/* 0x702 */
++	u16 PAD[0x3e];	/* 0x702 - 0x77E */
++
++	/* WEP/PMQ Block *//* 0x780 - 0x7FE */
++	u16 PAD[0x20];	/* 0x780 - 0x7BE */
++
++	u16 wepctl;		/* 0x7C0 */
++	u16 wepivloc;	/* 0x7C2 */
++	u16 wepivkey;	/* 0x7C4 */
++	u16 wepwkey;		/* 0x7C6 */
++
++	u16 PAD[4];		/* 0x7C8 - 0x7CE */
++	u16 pcmctl;		/* 0X7D0 */
++	u16 pcmstat;		/* 0X7D2 */
++	u16 PAD[6];		/* 0x7D4 - 0x7DE */
++
++	u16 pmqctl;		/* 0x7E0 */
++	u16 pmqstatus;	/* 0x7E2 */
++	u16 pmqpat0;		/* 0x7E4 */
++	u16 pmqpat1;		/* 0x7E6 */
++	u16 pmqpat2;		/* 0x7E8 */
++
++	u16 pmqdat;		/* 0x7EA */
++	u16 pmqdator;	/* 0x7EC */
++	u16 pmqhst;		/* 0x7EE */
++	u16 pmqpath0;	/* 0x7F0 */
++	u16 pmqpath1;	/* 0x7F2 */
++	u16 pmqpath2;	/* 0x7F4 */
++	u16 pmqdath;		/* 0x7F6 */
++
++	u16 PAD[0x04];	/* 0x7F8 - 0x7FE */
++
++	/* SHM *//* 0x800 - 0xEFE */
++	u16 PAD[0x380];	/* 0x800 - 0xEFE */
++};
++
++/* d11 register field offset */
++#define D11REGOFFS(field)	offsetof(struct d11regs, field)
++
++#define	PIHR_BASE	0x0400	/* byte address of packed IHR region */
++
++/* biststatus */
++#define	BT_DONE		(1U << 31)	/* bist done */
++#define	BT_B2S		(1 << 30)	/* bist2 ram summary bit */
++
++/* intstatus and intmask */
++#define	I_PC		(1 << 10)	/* pci descriptor error */
++#define	I_PD		(1 << 11)	/* pci data error */
++#define	I_DE		(1 << 12)	/* descriptor protocol error */
++#define	I_RU		(1 << 13)	/* receive descriptor underflow */
++#define	I_RO		(1 << 14)	/* receive fifo overflow */
++#define	I_XU		(1 << 15)	/* transmit fifo underflow */
++#define	I_RI		(1 << 16)	/* receive interrupt */
++#define	I_XI		(1 << 24)	/* transmit interrupt */
++
++/* interrupt receive lazy */
++#define	IRL_TO_MASK		0x00ffffff	/* timeout */
++#define	IRL_FC_MASK		0xff000000	/* frame count */
++#define	IRL_FC_SHIFT		24	/* frame count */
++
++/*== maccontrol register ==*/
++#define	MCTL_GMODE		(1U << 31)
++#define	MCTL_DISCARD_PMQ	(1 << 30)
++#define	MCTL_WAKE		(1 << 26)
++#define	MCTL_HPS		(1 << 25)
++#define	MCTL_PROMISC		(1 << 24)
++#define	MCTL_KEEPBADFCS		(1 << 23)
++#define	MCTL_KEEPCONTROL	(1 << 22)
++#define	MCTL_PHYLOCK		(1 << 21)
++#define	MCTL_BCNS_PROMISC	(1 << 20)
++#define	MCTL_LOCK_RADIO		(1 << 19)
++#define	MCTL_AP			(1 << 18)
++#define	MCTL_INFRA		(1 << 17)
++#define	MCTL_BIGEND		(1 << 16)
++#define	MCTL_GPOUT_SEL_MASK	(3 << 14)
++#define	MCTL_GPOUT_SEL_SHIFT	14
++#define	MCTL_EN_PSMDBG		(1 << 13)
++#define	MCTL_IHR_EN		(1 << 10)
++#define	MCTL_SHM_UPPER		(1 <<  9)
++#define	MCTL_SHM_EN		(1 <<  8)
++#define	MCTL_PSM_JMP_0		(1 <<  2)
++#define	MCTL_PSM_RUN		(1 <<  1)
++#define	MCTL_EN_MAC		(1 <<  0)
++
++/*== maccommand register ==*/
++#define	MCMD_BCN0VLD		(1 <<  0)
++#define	MCMD_BCN1VLD		(1 <<  1)
++#define	MCMD_DIRFRMQVAL		(1 <<  2)
++#define	MCMD_CCA		(1 <<  3)
++#define	MCMD_BG_NOISE		(1 <<  4)
++#define	MCMD_SKIP_SHMINIT	(1 <<  5)	/* only used for simulation */
++#define MCMD_SAMPLECOLL		MCMD_SKIP_SHMINIT /* reuse for sample collect */
++
++/*== macintstatus/macintmask ==*/
++/* gracefully suspended */
++#define	MI_MACSSPNDD		(1 <<  0)
++/* beacon template available */
++#define	MI_BCNTPL		(1 <<  1)
++/* TBTT indication */
++#define	MI_TBTT			(1 <<  2)
++/* beacon successfully tx'd */
++#define	MI_BCNSUCCESS		(1 <<  3)
++/* beacon canceled (IBSS) */
++#define	MI_BCNCANCLD		(1 <<  4)
++/* end of ATIM-window (IBSS) */
++#define	MI_ATIMWINEND		(1 <<  5)
++/* PMQ entries available */
++#define	MI_PMQ			(1 <<  6)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_0		(1 <<  7)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_1		(1 <<  8)
++/* MAC level Tx error */
++#define	MI_MACTXERR		(1 <<  9)
++/* non-specific gen-stat bits that are set by PSM */
++#define	MI_NSPECGEN_3		(1 << 10)
++/* PHY Tx error */
++#define	MI_PHYTXERR		(1 << 11)
++/* Power Management Event */
++#define	MI_PME			(1 << 12)
++/* General-purpose timer0 */
++#define	MI_GP0			(1 << 13)
++/* General-purpose timer1 */
++#define	MI_GP1			(1 << 14)
++/* (ORed) DMA-interrupts */
++#define	MI_DMAINT		(1 << 15)
++/* MAC has completed a TX FIFO Suspend/Flush */
++#define	MI_TXSTOP		(1 << 16)
++/* MAC has completed a CCA measurement */
++#define	MI_CCA			(1 << 17)
++/* MAC has collected background noise samples */
++#define	MI_BG_NOISE		(1 << 18)
++/* MBSS DTIM TBTT indication */
++#define	MI_DTIM_TBTT		(1 << 19)
++/* Probe response queue needs attention */
++#define MI_PRQ			(1 << 20)
++/* Radio/PHY has been powered back up. */
++#define	MI_PWRUP		(1 << 21)
++#define	MI_RESERVED3		(1 << 22)
++#define	MI_RESERVED2		(1 << 23)
++#define MI_RESERVED1		(1 << 25)
++/* MAC detected change on RF Disable input*/
++#define MI_RFDISABLE		(1 << 28)
++/* MAC has completed a TX */
++#define	MI_TFS			(1 << 29)
++/* A phy status change wrt G mode */
++#define	MI_PHYCHANGED		(1 << 30)
++/* general purpose timeout */
++#define	MI_TO			(1U << 31)
++
++/* Mac capabilities registers */
++/*== machwcap ==*/
++#define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
++
++/*== pmqhost data ==*/
++/* data entry of head pmq entry */
++#define	PMQH_DATA_MASK		0xffff0000
++/* PM entry for BSS config */
++#define	PMQH_BSSCFG		0x00100000
++/* PM Mode OFF: power save off */
++#define	PMQH_PMOFF		0x00010000
++/* PM Mode ON: power save on */
++#define	PMQH_PMON		0x00020000
++/* Dis-associated or De-authenticated */
++#define	PMQH_DASAT		0x00040000
++/* ATIM not acknowledged */
++#define	PMQH_ATIMFAIL		0x00080000
++/* delete head entry */
++#define	PMQH_DEL_ENTRY		0x00000001
++/* delete head entry to cur read pointer -1 */
++#define	PMQH_DEL_MULT		0x00000002
++/* pmq overflow indication */
++#define	PMQH_OFLO		0x00000004
++/* entries are present in pmq */
++#define	PMQH_NOT_EMPTY		0x00000008
++
++/*== phydebug ==*/
++/* phy is asserting carrier sense */
++#define	PDBG_CRS		(1 << 0)
++/* phy is taking xmit byte from mac this cycle */
++#define	PDBG_TXA		(1 << 1)
++/* mac is instructing the phy to transmit a frame */
++#define	PDBG_TXF		(1 << 2)
++/* phy is signalling a transmit Error to the mac */
++#define	PDBG_TXE		(1 << 3)
++/* phy detected the end of a valid frame preamble */
++#define	PDBG_RXF		(1 << 4)
++/* phy detected the end of a valid PLCP header */
++#define	PDBG_RXS		(1 << 5)
++/* rx start not asserted */
++#define	PDBG_RXFRG		(1 << 6)
++/* mac is taking receive byte from phy this cycle */
++#define	PDBG_RXV		(1 << 7)
++/* RF portion of the radio is disabled */
++#define	PDBG_RFD		(1 << 16)
++
++/*== objaddr register ==*/
++#define	OBJADDR_SEL_MASK	0x000F0000
++#define	OBJADDR_UCM_SEL		0x00000000
++#define	OBJADDR_SHM_SEL		0x00010000
++#define	OBJADDR_SCR_SEL		0x00020000
++#define	OBJADDR_IHR_SEL		0x00030000
++#define	OBJADDR_RCMTA_SEL	0x00040000
++#define	OBJADDR_SRCHM_SEL	0x00060000
++#define	OBJADDR_WINC		0x01000000
++#define	OBJADDR_RINC		0x02000000
++#define	OBJADDR_AUTO_INC	0x03000000
++
++#define	WEP_PCMADDR		0x07d4
++#define	WEP_PCMDATA		0x07d6
++
++/*== frmtxstatus ==*/
++#define	TXS_V			(1 << 0)	/* valid bit */
++#define	TXS_STATUS_MASK		0xffff
++#define	TXS_FID_MASK		0xffff0000
++#define	TXS_FID_SHIFT		16
++
++/*== frmtxstatus2 ==*/
++#define	TXS_SEQ_MASK		0xffff
++#define	TXS_PTX_MASK		0xff0000
++#define	TXS_PTX_SHIFT		16
++#define	TXS_MU_MASK		0x01000000
++#define	TXS_MU_SHIFT		24
++
++/*== clk_ctl_st ==*/
++#define CCS_ERSRC_REQ_D11PLL	0x00000100	/* d11 core pll request */
++#define CCS_ERSRC_REQ_PHYPLL	0x00000200	/* PHY pll request */
++#define CCS_ERSRC_AVAIL_D11PLL	0x01000000	/* d11 core pll available */
++#define CCS_ERSRC_AVAIL_PHYPLL	0x02000000	/* PHY pll available */
++
++/* HT Cloclk Ctrl and Clock Avail for 4313 */
++#define CCS_ERSRC_REQ_HT    0x00000010	/* HT avail request */
++#define CCS_ERSRC_AVAIL_HT  0x00020000	/* HT clock available */
++
++/* tsf_cfprep register */
++#define	CFPREP_CBI_MASK		0xffffffc0
++#define	CFPREP_CBI_SHIFT	6
++#define	CFPREP_CFPP		0x00000001
++
++/* tx fifo sizes values are in terms of 256 byte blocks */
++#define TXFIFOCMD_RESET_MASK	(1 << 15)	/* reset */
++#define TXFIFOCMD_FIFOSEL_SHIFT	8	/* fifo */
++#define TXFIFO_FIFOTOP_SHIFT	8	/* fifo start */
++
++#define TXFIFO_START_BLK16	 65	/* Base address + 32 * 512 B/P */
++#define TXFIFO_START_BLK	 6	/* Base address + 6 * 256 B */
++#define TXFIFO_SIZE_UNIT	256	/* one unit corresponds to 256 bytes */
++#define MBSS16_TEMPLMEM_MINBLKS	65	/* one unit corresponds to 256 bytes */
++
++/*== phy versions (PhyVersion:Revision field) ==*/
++/* analog block version */
++#define	PV_AV_MASK		0xf000
++/* analog block version bitfield offset */
++#define	PV_AV_SHIFT		12
++/* phy type */
++#define	PV_PT_MASK		0x0f00
++/* phy type bitfield offset */
++#define	PV_PT_SHIFT		8
++/* phy version */
++#define	PV_PV_MASK		0x000f
++#define	PHY_TYPE(v)		((v & PV_PT_MASK) >> PV_PT_SHIFT)
++
++/*== phy types (PhyVersion:PhyType field) ==*/
++#define	PHY_TYPE_N		4	/* N-Phy value */
++#define	PHY_TYPE_SSN		6	/* SSLPN-Phy value */
++#define	PHY_TYPE_LCN		8	/* LCN-Phy value */
++#define	PHY_TYPE_LCNXN		9	/* LCNXN-Phy value */
++#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
++
++/*== analog types (PhyVersion:AnalogType field) ==*/
++#define	ANA_11N_013		5
++
++/* 802.11a PLCP header def */
++struct ofdm_phy_hdr {
++	u8 rlpt[3];		/* rate, length, parity, tail */
++	u16 service;
++	u8 pad;
++} __packed;
++
++#define	D11A_PHY_HDR_GRATE(phdr)	((phdr)->rlpt[0] & 0x0f)
++#define	D11A_PHY_HDR_GRES(phdr)		(((phdr)->rlpt[0] >> 4) & 0x01)
++#define	D11A_PHY_HDR_GLENGTH(phdr)	(((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
++#define	D11A_PHY_HDR_GPARITY(phdr)	(((phdr)->rlpt[3] >> 1) & 0x01)
++#define	D11A_PHY_HDR_GTAIL(phdr)	(((phdr)->rlpt[3] >> 2) & 0x3f)
++
++/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
++#define	D11A_PHY_HDR_SRATE(phdr, rate)		\
++	((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
++/* set reserved field to zero */
++#define	D11A_PHY_HDR_SRES(phdr)		((phdr)->rlpt[0] &= 0xef)
++/* length is number of octets in PSDU */
++#define	D11A_PHY_HDR_SLENGTH(phdr, length)	\
++	(*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
++	(((length) & 0x0fff) << 5))
++/* set the tail to all zeros */
++#define	D11A_PHY_HDR_STAIL(phdr)	((phdr)->rlpt[3] &= 0x03)
++
++#define	D11A_PHY_HDR_LEN_L	3	/* low-rate part of PLCP header */
++#define	D11A_PHY_HDR_LEN_R	2	/* high-rate part of PLCP header */
++
++#define	D11A_PHY_TX_DELAY	(2)	/* 2.1 usec */
++
++#define	D11A_PHY_HDR_TIME	(4)	/* low-rate part of PLCP header */
++#define	D11A_PHY_PRE_TIME	(16)
++#define	D11A_PHY_PREHDR_TIME	(D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
++
++/* 802.11b PLCP header def */
++struct cck_phy_hdr {
++	u8 signal;
++	u8 service;
++	u16 length;
++	u16 crc;
++} __packed;
++
++#define	D11B_PHY_HDR_LEN	6
++
++#define	D11B_PHY_TX_DELAY	(3)	/* 3.4 usec */
++
++#define	D11B_PHY_LHDR_TIME	(D11B_PHY_HDR_LEN << 3)
++#define	D11B_PHY_LPRE_TIME	(144)
++#define	D11B_PHY_LPREHDR_TIME	(D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
++
++#define	D11B_PHY_SHDR_TIME	(D11B_PHY_LHDR_TIME >> 1)
++#define	D11B_PHY_SPRE_TIME	(D11B_PHY_LPRE_TIME >> 1)
++#define	D11B_PHY_SPREHDR_TIME	(D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
++
++#define	D11B_PLCP_SIGNAL_LOCKED	(1 << 2)
++#define	D11B_PLCP_SIGNAL_LE	(1 << 7)
++
++#define MIMO_PLCP_MCS_MASK	0x7f	/* mcs index */
++#define MIMO_PLCP_40MHZ		0x80	/* 40 Hz frame */
++#define MIMO_PLCP_AMPDU		0x08	/* ampdu */
++
++#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
++#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
++#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \
++	do { \
++		plcp[1] = len & 0xff; \
++		plcp[2] = ((len >> 8) & 0xff); \
++	} while (0)
++
++#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
++#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
++#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
++
++/*
++ * The dot11a PLCP header is 5 bytes.  To simplify the software (so that we
++ * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header
++ * has padding added in the ucode.
++ */
++#define	D11_PHY_HDR_LEN	6
++
++/* TX DMA buffer header */
++struct d11txh {
++	__le16 MacTxControlLow;	/* 0x0 */
++	__le16 MacTxControlHigh;	/* 0x1 */
++	__le16 MacFrameControl;	/* 0x2 */
++	__le16 TxFesTimeNormal;	/* 0x3 */
++	__le16 PhyTxControlWord;	/* 0x4 */
++	__le16 PhyTxControlWord_1;	/* 0x5 */
++	__le16 PhyTxControlWord_1_Fbr;	/* 0x6 */
++	__le16 PhyTxControlWord_1_Rts;	/* 0x7 */
++	__le16 PhyTxControlWord_1_FbrRts;	/* 0x8 */
++	__le16 MainRates;	/* 0x9 */
++	__le16 XtraFrameTypes;	/* 0xa */
++	u8 IV[16];		/* 0x0b - 0x12 */
++	u8 TxFrameRA[6];	/* 0x13 - 0x15 */
++	__le16 TxFesTimeFallback;	/* 0x16 */
++	u8 RTSPLCPFallback[6];	/* 0x17 - 0x19 */
++	__le16 RTSDurFallback;	/* 0x1a */
++	u8 FragPLCPFallback[6];	/* 0x1b - 1d */
++	__le16 FragDurFallback;	/* 0x1e */
++	__le16 MModeLen;	/* 0x1f */
++	__le16 MModeFbrLen;	/* 0x20 */
++	__le16 TstampLow;	/* 0x21 */
++	__le16 TstampHigh;	/* 0x22 */
++	__le16 ABI_MimoAntSel;	/* 0x23 */
++	__le16 PreloadSize;	/* 0x24 */
++	__le16 AmpduSeqCtl;	/* 0x25 */
++	__le16 TxFrameID;	/* 0x26 */
++	__le16 TxStatus;	/* 0x27 */
++	__le16 MaxNMpdus;	/* 0x28 */
++	__le16 MaxABytes_MRT;	/* 0x29 */
++	__le16 MaxABytes_FBR;	/* 0x2a */
++	__le16 MinMBytes;	/* 0x2b */
++	u8 RTSPhyHeader[D11_PHY_HDR_LEN];	/* 0x2c - 0x2e */
++	struct ieee80211_rts rts_frame;	/* 0x2f - 0x36 */
++	u16 PAD;		/* 0x37 */
++} __packed;
++
++#define	D11_TXH_LEN		112	/* bytes */
++
++/* Frame Types */
++#define FT_CCK	0
++#define FT_OFDM	1
++#define FT_HT	2
++#define FT_N	3
++
++/*
++ * Position of MPDU inside A-MPDU; indicated with bits 10:9
++ * of MacTxControlLow
++ */
++#define TXC_AMPDU_SHIFT		9	/* shift for ampdu settings */
++#define TXC_AMPDU_NONE		0	/* Regular MPDU, not an A-MPDU */
++#define TXC_AMPDU_FIRST		1	/* first MPDU of an A-MPDU */
++#define TXC_AMPDU_MIDDLE	2	/* intermediate MPDU of an A-MPDU */
++#define TXC_AMPDU_LAST		3	/* last (or single) MPDU of an A-MPDU */
++
++/*== MacTxControlLow ==*/
++#define TXC_AMIC		0x8000
++#define	TXC_SENDCTS		0x0800
++#define TXC_AMPDU_MASK		0x0600
++#define TXC_BW_40		0x0100
++#define TXC_FREQBAND_5G		0x0080
++#define	TXC_DFCS		0x0040
++#define	TXC_IGNOREPMQ		0x0020
++#define	TXC_HWSEQ		0x0010
++#define	TXC_STARTMSDU		0x0008
++#define	TXC_SENDRTS		0x0004
++#define	TXC_LONGFRAME		0x0002
++#define	TXC_IMMEDACK		0x0001
++
++/*== MacTxControlHigh ==*/
++/* RTS fallback preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_FB_SHORT	0x8000
++/* RTS main rate preamble type 1 = SHORT 0 = LONG */
++#define TXC_PREAMBLE_RTS_MAIN_SHORT	0x4000
++/*
++ * Main fallback rate preamble type
++ *   1 = SHORT for OFDM/GF for MIMO
++ *   0 = LONG for CCK/MM for MIMO
++ */
++#define TXC_PREAMBLE_DATA_FB_SHORT	0x2000
++
++/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
++/* use fallback rate for this AMPDU */
++#define	TXC_AMPDU_FBR		0x1000
++#define	TXC_SECKEY_MASK		0x0FF0
++#define	TXC_SECKEY_SHIFT	4
++/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
++#define	TXC_ALT_TXPWR		0x0008
++#define	TXC_SECTYPE_MASK	0x0007
++#define	TXC_SECTYPE_SHIFT	0
++
++/* Null delimiter for Fallback rate */
++#define AMPDU_FBR_NULL_DELIM  5	/* Location of Null delimiter count for AMPDU */
++
++/* PhyTxControl for Mimophy */
++#define	PHY_TXC_PWR_MASK	0xFC00
++#define	PHY_TXC_PWR_SHIFT	10
++#define	PHY_TXC_ANT_MASK	0x03C0	/* bit 6, 7, 8, 9 */
++#define	PHY_TXC_ANT_SHIFT	6
++#define	PHY_TXC_ANT_0_1		0x00C0	/* auto, last rx */
++#define	PHY_TXC_LCNPHY_ANT_LAST	0x0000
++#define	PHY_TXC_ANT_3		0x0200	/* virtual antenna 3 */
++#define	PHY_TXC_ANT_2		0x0100	/* virtual antenna 2 */
++#define	PHY_TXC_ANT_1		0x0080	/* virtual antenna 1 */
++#define	PHY_TXC_ANT_0		0x0040	/* virtual antenna 0 */
++#define	PHY_TXC_SHORT_HDR	0x0010
++
++#define	PHY_TXC_OLD_ANT_0	0x0000
++#define	PHY_TXC_OLD_ANT_1	0x0100
++#define	PHY_TXC_OLD_ANT_LAST	0x0300
++
++/* PhyTxControl_1 for Mimophy */
++#define PHY_TXC1_BW_MASK		0x0007
++#define PHY_TXC1_BW_10MHZ		0
++#define PHY_TXC1_BW_10MHZ_UP		1
++#define PHY_TXC1_BW_20MHZ		2
++#define PHY_TXC1_BW_20MHZ_UP		3
++#define PHY_TXC1_BW_40MHZ		4
++#define PHY_TXC1_BW_40MHZ_DUP		5
++#define PHY_TXC1_MODE_SHIFT		3
++#define PHY_TXC1_MODE_MASK		0x0038
++#define PHY_TXC1_MODE_SISO		0
++#define PHY_TXC1_MODE_CDD		1
++#define PHY_TXC1_MODE_STBC		2
++#define PHY_TXC1_MODE_SDM		3
++
++/* PhyTxControl for HTphy that are different from Mimophy */
++#define	PHY_TXC_HTANT_MASK		0x3fC0	/* bits 6-13 */
++
++/* XtraFrameTypes */
++#define XFTS_RTS_FT_SHIFT	2
++#define XFTS_FBRRTS_FT_SHIFT	4
++#define XFTS_CHANNEL_SHIFT	8
++
++/* Antenna diversity bit in ant_wr_settle */
++#define	PHY_AWS_ANTDIV		0x2000
++
++/* IFS ctl */
++#define IFS_USEEDCF	(1 << 2)
++
++/* IFS ctl1 */
++#define IFS_CTL1_EDCRS	(1 << 3)
++#define IFS_CTL1_EDCRS_20L (1 << 4)
++#define IFS_CTL1_EDCRS_40 (1 << 5)
++
++/* ABI_MimoAntSel */
++#define ABI_MAS_ADDR_BMP_IDX_MASK	0x0f00
++#define ABI_MAS_ADDR_BMP_IDX_SHIFT	8
++#define ABI_MAS_FBR_ANT_PTN_MASK	0x00f0
++#define ABI_MAS_FBR_ANT_PTN_SHIFT	4
++#define ABI_MAS_MRT_ANT_PTN_MASK	0x000f
++
++/* tx status packet */
++struct tx_status {
++	u16 framelen;
++	u16 PAD;
++	u16 frameid;
++	u16 status;
++	u16 lasttxtime;
++	u16 sequence;
++	u16 phyerr;
++	u16 ackphyrxsh;
++} __packed;
++
++#define	TXSTATUS_LEN	16
++
++/* status field bit definitions */
++#define	TX_STATUS_FRM_RTX_MASK	0xF000
++#define	TX_STATUS_FRM_RTX_SHIFT	12
++#define	TX_STATUS_RTS_RTX_MASK	0x0F00
++#define	TX_STATUS_RTS_RTX_SHIFT	8
++#define TX_STATUS_MASK		0x00FE
++#define	TX_STATUS_PMINDCTD	(1 << 7) /* PM mode indicated to AP */
++#define	TX_STATUS_INTERMEDIATE	(1 << 6) /* intermediate or 1st ampdu pkg */
++#define	TX_STATUS_AMPDU		(1 << 5) /* AMPDU status */
++#define TX_STATUS_SUPR_MASK	0x1C	 /* suppress status bits (4:2) */
++#define TX_STATUS_SUPR_SHIFT	2
++#define	TX_STATUS_ACK_RCV	(1 << 1) /* ACK received */
++#define	TX_STATUS_VALID		(1 << 0) /* Tx status valid */
++#define	TX_STATUS_NO_ACK	0
++
++/* suppress status reason codes */
++#define	TX_STATUS_SUPR_PMQ	(1 << 2) /* PMQ entry */
++#define	TX_STATUS_SUPR_FLUSH	(2 << 2) /* flush request */
++#define	TX_STATUS_SUPR_FRAG	(3 << 2) /* previous frag failure */
++#define	TX_STATUS_SUPR_TBTT	(3 << 2) /* SHARED: Probe resp supr for TBTT */
++#define	TX_STATUS_SUPR_BADCH	(4 << 2) /* channel mismatch */
++#define	TX_STATUS_SUPR_EXPTIME	(5 << 2) /* lifetime expiry */
++#define	TX_STATUS_SUPR_UF	(6 << 2) /* underflow */
++
++/* Unexpected tx status for rate update */
++#define TX_STATUS_UNEXP(status) \
++	((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
++	 TX_STATUS_UNEXP_AMPDU(status))
++
++/* Unexpected tx status for A-MPDU rate update */
++#define TX_STATUS_UNEXP_AMPDU(status) \
++	((((status) & TX_STATUS_SUPR_MASK) != 0) && \
++	 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
++
++#define TX_STATUS_BA_BMAP03_MASK	0xF000	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP03_SHIFT	12	/* ba bitmap 0:3 in 1st pkg */
++#define TX_STATUS_BA_BMAP47_MASK	0x001E	/* ba bitmap 4:7 in 2nd pkg */
++#define TX_STATUS_BA_BMAP47_SHIFT	3	/* ba bitmap 4:7 in 2nd pkg */
++
++/* RXE (Receive Engine) */
++
++/* RCM_CTL */
++#define	RCM_INC_MASK_H		0x0080
++#define	RCM_INC_MASK_L		0x0040
++#define	RCM_INC_DATA		0x0020
++#define	RCM_INDEX_MASK		0x001F
++#define	RCM_SIZE		15
++
++#define	RCM_MAC_OFFSET		0	/* current MAC address */
++#define	RCM_BSSID_OFFSET	3	/* current BSSID address */
++#define	RCM_F_BSSID_0_OFFSET	6	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_1_OFFSET	9	/* foreign BSS CFP tracking */
++#define	RCM_F_BSSID_2_OFFSET	12	/* foreign BSS CFP tracking */
++
++#define RCM_WEP_TA0_OFFSET	16
++#define RCM_WEP_TA1_OFFSET	19
++#define RCM_WEP_TA2_OFFSET	22
++#define RCM_WEP_TA3_OFFSET	25
++
++/* PSM Block */
++
++/* psm_phy_hdr_param bits */
++#define MAC_PHY_RESET		1
++#define MAC_PHY_CLOCK_EN	2
++#define MAC_PHY_FORCE_CLK	4
++
++/* WEP Block */
++
++/* WEP_WKEY */
++#define	WKEY_START		(1 << 8)
++#define	WKEY_SEL_MASK		0x1F
++
++/* WEP data formats */
++
++/* the number of RCMTA entries */
++#define RCMTA_SIZE 50
++
++#define M_ADDR_BMP_BLK		(0x37e * 2)
++#define M_ADDR_BMP_BLK_SZ	12
++
++#define ADDR_BMP_RA		(1 << 0)	/* Receiver Address (RA) */
++#define ADDR_BMP_TA		(1 << 1)	/* Transmitter Address (TA) */
++#define ADDR_BMP_BSSID		(1 << 2)	/* BSSID */
++#define ADDR_BMP_AP		(1 << 3)	/* Infra-BSS Access Point */
++#define ADDR_BMP_STA		(1 << 4)	/* Infra-BSS Station */
++#define ADDR_BMP_RESERVED1	(1 << 5)
++#define ADDR_BMP_RESERVED2	(1 << 6)
++#define ADDR_BMP_RESERVED3	(1 << 7)
++#define ADDR_BMP_BSS_IDX_MASK	(3 << 8)	/* BSS control block index */
++#define ADDR_BMP_BSS_IDX_SHIFT	8
++
++#define	WSEC_MAX_RCMTA_KEYS	54
++
++/* max keys in M_TKMICKEYS_BLK */
++#define	WSEC_MAX_TKMIC_ENGINE_KEYS		12	/* 8 + 4 default */
++
++/* max RXE match registers */
++#define WSEC_MAX_RXE_KEYS	4
++
++/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
++/* SKL (Security Key Lookup) */
++#define	SKL_ALGO_MASK		0x0007
++#define	SKL_ALGO_SHIFT		0
++#define	SKL_KEYID_MASK		0x0008
++#define	SKL_KEYID_SHIFT		3
++#define	SKL_INDEX_MASK		0x03F0
++#define	SKL_INDEX_SHIFT		4
++#define	SKL_GRP_ALGO_MASK	0x1c00
++#define	SKL_GRP_ALGO_SHIFT	10
++
++/* additional bits defined for IBSS group key support */
++#define	SKL_IBSS_INDEX_MASK	0x01F0
++#define	SKL_IBSS_INDEX_SHIFT	4
++#define	SKL_IBSS_KEYID1_MASK	0x0600
++#define	SKL_IBSS_KEYID1_SHIFT	9
++#define	SKL_IBSS_KEYID2_MASK	0x1800
++#define	SKL_IBSS_KEYID2_SHIFT	11
++#define	SKL_IBSS_KEYALGO_MASK	0xE000
++#define	SKL_IBSS_KEYALGO_SHIFT	13
++
++#define	WSEC_MODE_OFF		0
++#define	WSEC_MODE_HW		1
++#define	WSEC_MODE_SW		2
++
++#define	WSEC_ALGO_OFF		0
++#define	WSEC_ALGO_WEP1		1
++#define	WSEC_ALGO_TKIP		2
++#define	WSEC_ALGO_AES		3
++#define	WSEC_ALGO_WEP128	4
++#define	WSEC_ALGO_AES_LEGACY	5
++#define	WSEC_ALGO_NALG		6
++
++#define	AES_MODE_NONE		0
++#define	AES_MODE_CCM		1
++
++/* WEP_CTL (Rev 0) */
++#define	WECR0_KEYREG_SHIFT	0
++#define	WECR0_KEYREG_MASK	0x7
++#define	WECR0_DECRYPT		(1 << 3)
++#define	WECR0_IVINLINE		(1 << 4)
++#define	WECR0_WEPALG_SHIFT	5
++#define	WECR0_WEPALG_MASK	(0x7 << 5)
++#define	WECR0_WKEYSEL_SHIFT	8
++#define	WECR0_WKEYSEL_MASK	(0x7 << 8)
++#define	WECR0_WKEYSTART		(1 << 11)
++#define	WECR0_WEPINIT		(1 << 14)
++#define	WECR0_ICVERR		(1 << 15)
++
++/* Frame template map byte offsets */
++#define	T_ACTS_TPL_BASE		(0)
++#define	T_NULL_TPL_BASE		(0xc * 2)
++#define	T_QNULL_TPL_BASE	(0x1c * 2)
++#define	T_RR_TPL_BASE		(0x2c * 2)
++#define	T_BCN0_TPL_BASE		(0x34 * 2)
++#define	T_PRS_TPL_BASE		(0x134 * 2)
++#define	T_BCN1_TPL_BASE		(0x234 * 2)
++#define T_TX_FIFO_TXRAM_BASE	(T_ACTS_TPL_BASE + \
++				 (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
++
++#define T_BA_TPL_BASE		T_QNULL_TPL_BASE /* template area for BA */
++
++#define T_RAM_ACCESS_SZ		4	/* template ram is 4 byte access only */
++
++/* Shared Mem byte offsets */
++
++/* Location where the ucode expects the corerev */
++#define	M_MACHW_VER		(0x00b * 2)
++
++/* Location where the ucode expects the MAC capabilities */
++#define	M_MACHW_CAP_L		(0x060 * 2)
++#define	M_MACHW_CAP_H	(0x061 * 2)
++
++/* WME shared memory */
++#define M_EDCF_STATUS_OFF	(0x007 * 2)
++#define M_TXF_CUR_INDEX		(0x018 * 2)
++#define M_EDCF_QINFO		(0x120 * 2)
++
++/* PS-mode related parameters */
++#define	M_DOT11_SLOT		(0x008 * 2)
++#define	M_DOT11_DTIMPERIOD	(0x009 * 2)
++#define	M_NOSLPZNATDTIM		(0x026 * 2)
++
++/* Beacon-related parameters */
++#define	M_BCN0_FRM_BYTESZ	(0x00c * 2)	/* Bcn 0 template length */
++#define	M_BCN1_FRM_BYTESZ	(0x00d * 2)	/* Bcn 1 template length */
++#define	M_BCN_TXTSF_OFFSET	(0x00e * 2)
++#define	M_TIMBPOS_INBEACON	(0x00f * 2)
++#define	M_SFRMTXCNTFBRTHSD	(0x022 * 2)
++#define	M_LFRMTXCNTFBRTHSD	(0x023 * 2)
++#define	M_BCN_PCTLWD		(0x02a * 2)
++#define M_BCN_LI		(0x05b * 2)	/* beacon listen interval */
++
++/* MAX Rx Frame len */
++#define M_MAXRXFRM_LEN		(0x010 * 2)
++
++/* ACK/CTS related params */
++#define	M_RSP_PCTLWD		(0x011 * 2)
++
++/* Hardware Power Control */
++#define M_TXPWR_N		(0x012 * 2)
++#define M_TXPWR_TARGET		(0x013 * 2)
++#define M_TXPWR_MAX		(0x014 * 2)
++#define M_TXPWR_CUR		(0x019 * 2)
++
++/* Rx-related parameters */
++#define	M_RX_PAD_DATA_OFFSET	(0x01a * 2)
++
++/* WEP Shared mem data */
++#define	M_SEC_DEFIVLOC		(0x01e * 2)
++#define	M_SEC_VALNUMSOFTMCHTA	(0x01f * 2)
++#define	M_PHYVER		(0x028 * 2)
++#define	M_PHYTYPE		(0x029 * 2)
++#define	M_SECRXKEYS_PTR		(0x02b * 2)
++#define	M_TKMICKEYS_PTR		(0x059 * 2)
++#define	M_SECKINDXALGO_BLK	(0x2ea * 2)
++#define M_SECKINDXALGO_BLK_SZ	54
++#define	M_SECPSMRXTAMCH_BLK	(0x2fa * 2)
++#define	M_TKIP_TSC_TTAK		(0x18c * 2)
++#define	D11_MAX_KEY_SIZE	16
++
++#define	M_MAX_ANTCNT		(0x02e * 2)	/* antenna swap threshold */
++
++/* Probe response related parameters */
++#define	M_SSIDLEN		(0x024 * 2)
++#define	M_PRB_RESP_FRM_LEN	(0x025 * 2)
++#define	M_PRS_MAXTIME		(0x03a * 2)
++#define	M_SSID			(0xb0 * 2)
++#define	M_CTXPRS_BLK		(0xc0 * 2)
++#define	C_CTX_PCTLWD_POS	(0x4 * 2)
++
++/* Delta between OFDM and CCK power in CCK power boost mode */
++#define M_OFDM_OFFSET		(0x027 * 2)
++
++/* TSSI for last 4 11b/g CCK packets transmitted */
++#define	M_B_TSSI_0		(0x02c * 2)
++#define	M_B_TSSI_1		(0x02d * 2)
++
++/* Host flags to turn on ucode options */
++#define	M_HOST_FLAGS1		(0x02f * 2)
++#define	M_HOST_FLAGS2		(0x030 * 2)
++#define	M_HOST_FLAGS3		(0x031 * 2)
++#define	M_HOST_FLAGS4		(0x03c * 2)
++#define	M_HOST_FLAGS5		(0x06a * 2)
++#define	M_HOST_FLAGS_SZ		16
++
++#define M_RADAR_REG		(0x033 * 2)
++
++/* TSSI for last 4 11a OFDM packets transmitted */
++#define	M_A_TSSI_0		(0x034 * 2)
++#define	M_A_TSSI_1		(0x035 * 2)
++
++/* noise interference measurement */
++#define M_NOISE_IF_COUNT	(0x034 * 2)
++#define M_NOISE_IF_TIMEOUT	(0x035 * 2)
++
++#define	M_RF_RX_SP_REG1		(0x036 * 2)
++
++/* TSSI for last 4 11g OFDM packets transmitted */
++#define	M_G_TSSI_0		(0x038 * 2)
++#define	M_G_TSSI_1		(0x039 * 2)
++
++/* Background noise measure */
++#define	M_JSSI_0		(0x44 * 2)
++#define	M_JSSI_1		(0x45 * 2)
++#define	M_JSSI_AUX		(0x46 * 2)
++
++#define	M_CUR_2050_RADIOCODE	(0x47 * 2)
++
++/* TX fifo sizes */
++#define M_FIFOSIZE0		(0x4c * 2)
++#define M_FIFOSIZE1		(0x4d * 2)
++#define M_FIFOSIZE2		(0x4e * 2)
++#define M_FIFOSIZE3		(0x4f * 2)
++#define D11_MAX_TX_FRMS		32	/* max frames allowed in tx fifo */
++
++/* Current channel number plus upper bits */
++#define M_CURCHANNEL		(0x50 * 2)
++#define D11_CURCHANNEL_5G	0x0100;
++#define D11_CURCHANNEL_40	0x0200;
++#define D11_CURCHANNEL_MAX	0x00FF;
++
++/* last posted frameid on the bcmc fifo */
++#define M_BCMC_FID		(0x54 * 2)
++#define INVALIDFID		0xffff
++
++/* extended beacon phyctl bytes for 11N */
++#define	M_BCN_PCTL1WD		(0x058 * 2)
++
++/* idle busy ratio to duty_cycle requirement  */
++#define M_TX_IDLE_BUSY_RATIO_X_16_CCK  (0x52 * 2)
++#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
++
++/* CW RSSI for LCNPHY */
++#define M_LCN_RSSI_0		0x1332
++#define M_LCN_RSSI_1		0x1338
++#define M_LCN_RSSI_2		0x133e
++#define M_LCN_RSSI_3		0x1344
++
++/* SNR for LCNPHY */
++#define M_LCN_SNR_A_0	0x1334
++#define M_LCN_SNR_B_0	0x1336
++
++#define M_LCN_SNR_A_1	0x133a
++#define M_LCN_SNR_B_1	0x133c
++
++#define M_LCN_SNR_A_2	0x1340
++#define M_LCN_SNR_B_2	0x1342
++
++#define M_LCN_SNR_A_3	0x1346
++#define M_LCN_SNR_B_3	0x1348
++
++#define M_LCN_LAST_RESET	(81*2)
++#define M_LCN_LAST_LOC	(63*2)
++#define M_LCNPHY_RESET_STATUS (4902)
++#define M_LCNPHY_DSC_TIME	(0x98d*2)
++#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
++#define M_LCNPHY_RESET_CNT	(0x98c*2)
++
++/* Rate table offsets */
++#define	M_RT_DIRMAP_A		(0xe0 * 2)
++#define	M_RT_BBRSMAP_A		(0xf0 * 2)
++#define	M_RT_DIRMAP_B		(0x100 * 2)
++#define	M_RT_BBRSMAP_B		(0x110 * 2)
++
++/* Rate table entry offsets */
++#define	M_RT_PRS_PLCP_POS	10
++#define	M_RT_PRS_DUR_POS	16
++#define	M_RT_OFDM_PCTL1_POS	18
++
++#define M_20IN40_IQ			(0x380 * 2)
++
++/* SHM locations where ucode stores the current power index */
++#define M_CURR_IDX1		(0x384 * 2)
++#define M_CURR_IDX2		(0x387 * 2)
++
++#define M_BSCALE_ANT0	(0x5e * 2)
++#define M_BSCALE_ANT1	(0x5f * 2)
++
++/* Antenna Diversity Testing */
++#define M_MIMO_ANTSEL_RXDFLT	(0x63 * 2)
++#define M_ANTSEL_CLKDIV	(0x61 * 2)
++#define M_MIMO_ANTSEL_TXDFLT	(0x64 * 2)
++
++#define M_MIMO_MAXSYM	(0x5d * 2)
++#define MIMO_MAXSYM_DEF		0x8000	/* 32k */
++#define MIMO_MAXSYM_MAX		0xffff	/* 64k */
++
++#define M_WATCHDOG_8TU		(0x1e * 2)
++#define WATCHDOG_8TU_DEF	5
++#define WATCHDOG_8TU_MAX	10
++
++/* Manufacturing Test Variables */
++/* PER test mode */
++#define M_PKTENG_CTRL		(0x6c * 2)
++/* IFS for TX mode */
++#define M_PKTENG_IFS		(0x6d * 2)
++/* Lower word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_LO	(0x6e * 2)
++/* Upper word of tx frmcnt/rx lostcnt */
++#define M_PKTENG_FRMCNT_HI	(0x6f * 2)
++
++/* Index variation in vbat ripple */
++#define M_LCN_PWR_IDX_MAX	(0x67 * 2) /* highest index read by ucode */
++#define M_LCN_PWR_IDX_MIN	(0x66 * 2) /* lowest index read by ucode */
++
++/* M_PKTENG_CTRL bit definitions */
++#define M_PKTENG_MODE_TX		0x0001
++#define M_PKTENG_MODE_TX_RIFS	        0x0004
++#define M_PKTENG_MODE_TX_CTS            0x0008
++#define M_PKTENG_MODE_RX		0x0002
++#define M_PKTENG_MODE_RX_WITH_ACK	0x0402
++#define M_PKTENG_MODE_MASK		0x0003
++/* TX frames indicated in the frmcnt reg */
++#define M_PKTENG_FRMCNT_VLD		0x0100
++
++/* Sample Collect parameters (bitmap and type) */
++/* Trigger bitmap for sample collect */
++#define M_SMPL_COL_BMP		(0x37d * 2)
++/* Sample collect type */
++#define M_SMPL_COL_CTL		(0x3b2 * 2)
++
++#define ANTSEL_CLKDIV_4MHZ	6
++#define MIMO_ANTSEL_BUSY	0x4000	/* bit 14 (busy) */
++#define MIMO_ANTSEL_SEL		0x8000	/* bit 15 write the value */
++#define MIMO_ANTSEL_WAIT	50	/* 50us wait */
++#define MIMO_ANTSEL_OVERRIDE	0x8000	/* flag */
++
++struct shm_acparams {
++	u16 txop;
++	u16 cwmin;
++	u16 cwmax;
++	u16 cwcur;
++	u16 aifs;
++	u16 bslots;
++	u16 reggap;
++	u16 status;
++	u16 rsvd[8];
++} __packed;
++#define M_EDCF_QLEN	(16 * 2)
++
++#define WME_STATUS_NEWAC	(1 << 8)
++
++/* M_HOST_FLAGS */
++#define MHFMAX		5	/* Number of valid hostflag half-word (u16) */
++#define MHF1		0	/* Hostflag 1 index */
++#define MHF2		1	/* Hostflag 2 index */
++#define MHF3		2	/* Hostflag 3 index */
++#define MHF4		3	/* Hostflag 4 index */
++#define MHF5		4	/* Hostflag 5 index */
++
++/* Flags in M_HOST_FLAGS */
++/* Enable ucode antenna diversity help */
++#define	MHF1_ANTDIV		0x0001
++/* Enable EDCF access control */
++#define	MHF1_EDCF		0x0100
++#define MHF1_IQSWAP_WAR		0x0200
++/* Disable Slow clock request, for corerev < 11 */
++#define	MHF1_FORCEFASTCLK	0x0400
++
++/* Flags in M_HOST_FLAGS2 */
++
++/* Flush BCMC FIFO immediately */
++#define MHF2_TXBCMC_NOW		0x0040
++/* Enable ucode/hw power control */
++#define MHF2_HWPWRCTL		0x0080
++#define MHF2_NPHY40MHZ_WAR	0x0800
++
++/* Flags in M_HOST_FLAGS3 */
++/* enabled mimo antenna selection */
++#define MHF3_ANTSEL_EN		0x0001
++/* antenna selection mode: 0: 2x3, 1: 2x4 */
++#define MHF3_ANTSEL_MODE	0x0002
++#define MHF3_RESERVED1		0x0004
++#define MHF3_RESERVED2		0x0008
++#define MHF3_NPHY_MLADV_WAR	0x0010
++
++/* Flags in M_HOST_FLAGS4 */
++/* force bphy Tx on core 0 (board level WAR) */
++#define MHF4_BPHY_TXCORE0	0x0080
++/* for 4313A0 FEM boards */
++#define MHF4_EXTPA_ENABLE	0x4000
++
++/* Flags in M_HOST_FLAGS5 */
++#define MHF5_4313_GPIOCTRL	0x0001
++#define MHF5_RESERVED1		0x0002
++#define MHF5_RESERVED2		0x0004
++/* Radio power setting for ucode */
++#define	M_RADIO_PWR		(0x32 * 2)
++
++/* phy noise recorded by ucode right after tx */
++#define	M_PHY_NOISE		(0x037 * 2)
++#define	PHY_NOISE_MASK		0x00ff
++
++/*
++ * Receive Frame Data Header for 802.11b DCF-only frames
++ *
++ * RxFrameSize: Actual byte length of the frame data received
++ * PAD: padding (not used)
++ * PhyRxStatus_0: PhyRxStatus 15:0
++ * PhyRxStatus_1: PhyRxStatus 31:16
++ * PhyRxStatus_2: PhyRxStatus 47:32
++ * PhyRxStatus_3: PhyRxStatus 63:48
++ * PhyRxStatus_4: PhyRxStatus 79:64
++ * PhyRxStatus_5: PhyRxStatus 95:80
++ * RxStatus1: MAC Rx Status
++ * RxStatus2: extended MAC Rx status
++ * RxTSFTime: RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY
++ * RxChan: gain code, channel radio code, and phy type
++ */
++struct d11rxhdr_le {
++	__le16 RxFrameSize;
++	u16 PAD;
++	__le16 PhyRxStatus_0;
++	__le16 PhyRxStatus_1;
++	__le16 PhyRxStatus_2;
++	__le16 PhyRxStatus_3;
++	__le16 PhyRxStatus_4;
++	__le16 PhyRxStatus_5;
++	__le16 RxStatus1;
++	__le16 RxStatus2;
++	__le16 RxTSFTime;
++	__le16 RxChan;
++} __packed;
++
++struct d11rxhdr {
++	u16 RxFrameSize;
++	u16 PAD;
++	u16 PhyRxStatus_0;
++	u16 PhyRxStatus_1;
++	u16 PhyRxStatus_2;
++	u16 PhyRxStatus_3;
++	u16 PhyRxStatus_4;
++	u16 PhyRxStatus_5;
++	u16 RxStatus1;
++	u16 RxStatus2;
++	u16 RxTSFTime;
++	u16 RxChan;
++} __packed;
++
++/* PhyRxStatus_0: */
++/* NPHY only: CCK, OFDM, preN, N */
++#define	PRXS0_FT_MASK		0x0003
++/* NPHY only: clip count adjustment steps by AGC */
++#define	PRXS0_CLIP_MASK		0x000C
++#define	PRXS0_CLIP_SHIFT	2
++/* PHY received a frame with unsupported rate */
++#define	PRXS0_UNSRATE		0x0010
++/* GPHY: rx ant, NPHY: upper sideband */
++#define	PRXS0_RXANT_UPSUBBAND	0x0020
++/* CCK frame only: lost crs during cck frame reception */
++#define	PRXS0_LCRS		0x0040
++/* Short Preamble */
++#define	PRXS0_SHORTH		0x0080
++/* PLCP violation */
++#define	PRXS0_PLCPFV		0x0100
++/* PLCP header integrity check failed */
++#define	PRXS0_PLCPHCF		0x0200
++/* legacy PHY gain control */
++#define	PRXS0_GAIN_CTL		0x4000
++/* NPHY: Antennas used for received frame, bitmask */
++#define PRXS0_ANTSEL_MASK	0xF000
++#define PRXS0_ANTSEL_SHIFT	0x12
++
++/* subfield PRXS0_FT_MASK */
++#define	PRXS0_CCK		0x0000
++/* valid only for G phy, use rxh->RxChan for A phy */
++#define	PRXS0_OFDM		0x0001
++#define	PRXS0_PREN		0x0002
++#define	PRXS0_STDN		0x0003
++
++/* subfield PRXS0_ANTSEL_MASK */
++#define PRXS0_ANTSEL_0		0x0	/* antenna 0 is used */
++#define PRXS0_ANTSEL_1		0x2	/* antenna 1 is used */
++#define PRXS0_ANTSEL_2		0x4	/* antenna 2 is used */
++#define PRXS0_ANTSEL_3		0x8	/* antenna 3 is used */
++
++/* PhyRxStatus_1: */
++#define	PRXS1_JSSI_MASK		0x00FF
++#define	PRXS1_JSSI_SHIFT	0
++#define	PRXS1_SQ_MASK		0xFF00
++#define	PRXS1_SQ_SHIFT		8
++
++/* nphy PhyRxStatus_1: */
++#define PRXS1_nphy_PWR0_MASK	0x00FF
++#define PRXS1_nphy_PWR1_MASK	0xFF00
++
++/* HTPHY Rx Status defines */
++/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
++#define PRXS0_BAND	        0x0400	/* 0 = 2.4G, 1 = 5G */
++#define PRXS0_RSVD	        0x0800	/* reserved; set to 0 */
++#define PRXS0_UNUSED	        0xF000	/* unused and not defined; set to 0 */
++
++/* htphy PhyRxStatus_1: */
++/* core enables for {3..0}, 0=disabled, 1=enabled */
++#define PRXS1_HTPHY_CORE_MASK	0x000F
++/* antenna configation */
++#define PRXS1_HTPHY_ANTCFG_MASK	0x00F0
++/* Mixmode PLCP Length low byte mask */
++#define PRXS1_HTPHY_MMPLCPLenL_MASK	0xFF00
++
++/* htphy PhyRxStatus_2: */
++/* Mixmode PLCP Length high byte maskw */
++#define PRXS2_HTPHY_MMPLCPLenH_MASK	0x000F
++/* Mixmode PLCP rate mask */
++#define PRXS2_HTPHY_MMPLCH_RATE_MASK	0x00F0
++/* Rx power on core 0 */
++#define PRXS2_HTPHY_RXPWR_ANT0	0xFF00
++
++/* htphy PhyRxStatus_3: */
++/* Rx power on core 1 */
++#define PRXS3_HTPHY_RXPWR_ANT1	0x00FF
++/* Rx power on core 2 */
++#define PRXS3_HTPHY_RXPWR_ANT2	0xFF00
++
++/* htphy PhyRxStatus_4: */
++/* Rx power on core 3 */
++#define PRXS4_HTPHY_RXPWR_ANT3	0x00FF
++/* Coarse frequency offset */
++#define PRXS4_HTPHY_CFO		0xFF00
++
++/* htphy PhyRxStatus_5: */
++/* Fine frequency offset */
++#define PRXS5_HTPHY_FFO	        0x00FF
++/* Advance Retard */
++#define PRXS5_HTPHY_AR	        0xFF00
++
++#define HTPHY_MMPLCPLen(rxs) \
++	((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
++	(((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
++/* Get Rx power on core 0 */
++#define HTPHY_RXPWR_ANT0(rxs) \
++	((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
++/* Get Rx power on core 1 */
++#define HTPHY_RXPWR_ANT1(rxs) \
++	(((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
++/* Get Rx power on core 2 */
++#define HTPHY_RXPWR_ANT2(rxs) \
++	((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
++
++/* ucode RxStatus1: */
++#define	RXS_BCNSENT		0x8000
++#define	RXS_SECKINDX_MASK	0x07e0
++#define	RXS_SECKINDX_SHIFT	5
++#define	RXS_DECERR		(1 << 4)
++#define	RXS_DECATMPT		(1 << 3)
++/* PAD bytes to make IP data 4 bytes aligned */
++#define	RXS_PBPRES		(1 << 2)
++#define	RXS_RESPFRAMETX		(1 << 1)
++#define	RXS_FCSERR		(1 << 0)
++
++/* ucode RxStatus2: */
++#define RXS_AMSDU_MASK		1
++#define	RXS_AGGTYPE_MASK	0x6
++#define	RXS_AGGTYPE_SHIFT	1
++#define	RXS_PHYRXST_VALID	(1 << 8)
++#define RXS_RXANT_MASK		0x3
++#define RXS_RXANT_SHIFT		12
++
++/* RxChan */
++#define RXS_CHAN_40		0x1000
++#define RXS_CHAN_5G		0x0800
++#define	RXS_CHAN_ID_MASK	0x07f8
++#define	RXS_CHAN_ID_SHIFT	3
++#define	RXS_CHAN_PHYTYPE_MASK	0x0007
++#define	RXS_CHAN_PHYTYPE_SHIFT	0
++
++/* Index of attenuations used during ucode power control. */
++#define M_PWRIND_BLKS	(0x184 * 2)
++#define M_PWRIND_MAP0	(M_PWRIND_BLKS + 0x0)
++#define M_PWRIND_MAP1	(M_PWRIND_BLKS + 0x2)
++#define M_PWRIND_MAP2	(M_PWRIND_BLKS + 0x4)
++#define M_PWRIND_MAP3	(M_PWRIND_BLKS + 0x6)
++/* M_PWRIND_MAP(core) macro */
++#define M_PWRIND_MAP(core)  (M_PWRIND_BLKS + ((core)<<1))
++
++/* PSM SHM variable offsets */
++#define	M_PSM_SOFT_REGS	0x0
++#define	M_BOM_REV_MAJOR	(M_PSM_SOFT_REGS + 0x0)
++#define	M_BOM_REV_MINOR	(M_PSM_SOFT_REGS + 0x2)
++#define	M_UCODE_DBGST	(M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */
++#define	M_UCODE_MACSTAT	(M_PSM_SOFT_REGS + 0xE0) /* macstat counters */
++
++#define M_AGING_THRSH	(0x3e * 2) /* max time waiting for medium before tx */
++#define	M_MBURST_SIZE	(0x40 * 2) /* max frames in a frameburst */
++#define	M_MBURST_TXOP	(0x41 * 2) /* max frameburst TXOP in unit of us */
++#define M_SYNTHPU_DLY	(0x4a * 2) /* pre-wakeup for synthpu, default: 500 */
++#define	M_PRETBTT	(0x4b * 2)
++
++/* offset to the target txpwr */
++#define M_ALT_TXPWR_IDX		(M_PSM_SOFT_REGS + (0x3b * 2))
++#define M_PHY_TX_FLT_PTR	(M_PSM_SOFT_REGS + (0x3d * 2))
++#define M_CTS_DURATION		(M_PSM_SOFT_REGS + (0x5c * 2))
++#define M_LP_RCCAL_OVR		(M_PSM_SOFT_REGS + (0x6b * 2))
++
++/* PKTENG Rx Stats Block */
++#define M_RXSTATS_BLK_PTR	(M_PSM_SOFT_REGS + (0x65 * 2))
++
++/* ucode debug status codes */
++/* not valid really */
++#define	DBGST_INACTIVE		0
++/* after zeroing SHM, before suspending at init */
++#define	DBGST_INIT		1
++/* "normal" state */
++#define	DBGST_ACTIVE		2
++/* suspended */
++#define	DBGST_SUSPENDED		3
++/* asleep (PS mode) */
++#define	DBGST_ASLEEP		4
++
++/* Scratch Reg defs */
++enum _ePsmScratchPadRegDefinitions {
++	S_RSV0 = 0,
++	S_RSV1,
++	S_RSV2,
++
++	/* offset 0x03: scratch registers for Dot11-contants */
++	S_DOT11_CWMIN,		/* CW-minimum */
++	S_DOT11_CWMAX,		/* CW-maximum */
++	S_DOT11_CWCUR,		/* CW-current */
++	S_DOT11_SRC_LMT,	/* short retry count limit */
++	S_DOT11_LRC_LMT,	/* long retry count limit */
++	S_DOT11_DTIMCOUNT,	/* DTIM-count */
++
++	/* offset 0x09: Tx-side scratch registers */
++	S_SEQ_NUM,		/* hardware sequence number reg */
++	S_SEQ_NUM_FRAG,		/* seq num for frags (at the start of MSDU) */
++	S_FRMRETX_CNT,		/* frame retx count */
++	S_SSRC,			/* Station short retry count */
++	S_SLRC,			/* Station long retry count */
++	S_EXP_RSP,		/* Expected response frame */
++	S_OLD_BREM,		/* Remaining backoff ctr */
++	S_OLD_CWWIN,		/* saved-off CW-cur */
++	S_TXECTL,		/* TXE-Ctl word constructed in scr-pad */
++	S_CTXTST,		/* frm type-subtype as read from Tx-descr */
++
++	/* offset 0x13: Rx-side scratch registers */
++	S_RXTST,		/* Type and subtype in Rxframe */
++
++	/* Global state register */
++	S_STREG,		/* state storage actual bit maps below */
++
++	S_TXPWR_SUM,		/* Tx power control: accumulator */
++	S_TXPWR_ITER,		/* Tx power control: iteration */
++	S_RX_FRMTYPE,		/* Rate and PHY type for frames */
++	S_THIS_AGG,		/* Size of this AGG (A-MSDU) */
++
++	S_KEYINDX,
++	S_RXFRMLEN,		/* Receive MPDU length in bytes */
++
++	/* offset 0x1B: Receive TSF time stored in SCR */
++	S_RXTSFTMRVAL_WD3,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD2,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD1,	/* TSF value at the start of rx */
++	S_RXTSFTMRVAL_WD0,	/* TSF value at the start of rx */
++	S_RXSSN,		/* Received start seq number for A-MPDU BA */
++	S_RXQOSFLD,		/* Rx-QoS field (if present) */
++
++	/* offset 0x21: Scratch pad regs used in microcode as temp storage */
++	S_TMP0,			/* stmp0 */
++	S_TMP1,			/* stmp1 */
++	S_TMP2,			/* stmp2 */
++	S_TMP3,			/* stmp3 */
++	S_TMP4,			/* stmp4 */
++	S_TMP5,			/* stmp5 */
++	S_PRQPENALTY_CTR,	/* Probe response queue penalty counter */
++	S_ANTCNT,		/* unsuccessful attempts on current ant. */
++	S_SYMBOL,		/* flag for possible symbol ctl frames */
++	S_RXTP,			/* rx frame type */
++	S_STREG2,		/* extra state storage */
++	S_STREG3,		/* even more extra state storage */
++	S_STREG4,		/* ... */
++	S_STREG5,		/* remember to initialize it to zero */
++
++	S_ADJPWR_IDX,
++	S_CUR_PTR,		/* Temp pointer for A-MPDU re-Tx SHM table */
++	S_REVID4,		/* 0x33 */
++	S_INDX,			/* 0x34 */
++	S_ADDR0,		/* 0x35 */
++	S_ADDR1,		/* 0x36 */
++	S_ADDR2,		/* 0x37 */
++	S_ADDR3,		/* 0x38 */
++	S_ADDR4,		/* 0x39 */
++	S_ADDR5,		/* 0x3A */
++	S_TMP6,			/* 0x3B */
++	S_KEYINDX_BU,		/* Backup for Key index */
++	S_MFGTEST_TMP0,		/* Temp regs used for RX test calculations */
++	S_RXESN,		/* Received end sequence number for A-MPDU BA */
++	S_STREG6,		/* 0x3F */
++};
++
++#define S_BEACON_INDX	S_OLD_BREM
++#define S_PRS_INDX	S_OLD_CWWIN
++#define S_PHYTYPE	S_SSRC
++#define S_PHYVER	S_SLRC
++
++/* IHR SLOW_CTRL values */
++#define SLOW_CTRL_PDE		(1 << 0)
++#define SLOW_CTRL_FD		(1 << 8)
++
++/* ucode mac statistic counters in shared memory */
++struct macstat {
++	u16 txallfrm;	/* 0x80 */
++	u16 txrtsfrm;	/* 0x82 */
++	u16 txctsfrm;	/* 0x84 */
++	u16 txackfrm;	/* 0x86 */
++	u16 txdnlfrm;	/* 0x88 */
++	u16 txbcnfrm;	/* 0x8a */
++	u16 txfunfl[8];	/* 0x8c - 0x9b */
++	u16 txtplunfl;	/* 0x9c */
++	u16 txphyerr;	/* 0x9e */
++	u16 pktengrxducast;	/* 0xa0 */
++	u16 pktengrxdmcast;	/* 0xa2 */
++	u16 rxfrmtoolong;	/* 0xa4 */
++	u16 rxfrmtooshrt;	/* 0xa6 */
++	u16 rxinvmachdr;	/* 0xa8 */
++	u16 rxbadfcs;	/* 0xaa */
++	u16 rxbadplcp;	/* 0xac */
++	u16 rxcrsglitch;	/* 0xae */
++	u16 rxstrt;		/* 0xb0 */
++	u16 rxdfrmucastmbss;	/* 0xb2 */
++	u16 rxmfrmucastmbss;	/* 0xb4 */
++	u16 rxcfrmucast;	/* 0xb6 */
++	u16 rxrtsucast;	/* 0xb8 */
++	u16 rxctsucast;	/* 0xba */
++	u16 rxackucast;	/* 0xbc */
++	u16 rxdfrmocast;	/* 0xbe */
++	u16 rxmfrmocast;	/* 0xc0 */
++	u16 rxcfrmocast;	/* 0xc2 */
++	u16 rxrtsocast;	/* 0xc4 */
++	u16 rxctsocast;	/* 0xc6 */
++	u16 rxdfrmmcast;	/* 0xc8 */
++	u16 rxmfrmmcast;	/* 0xca */
++	u16 rxcfrmmcast;	/* 0xcc */
++	u16 rxbeaconmbss;	/* 0xce */
++	u16 rxdfrmucastobss;	/* 0xd0 */
++	u16 rxbeaconobss;	/* 0xd2 */
++	u16 rxrsptmout;	/* 0xd4 */
++	u16 bcntxcancl;	/* 0xd6 */
++	u16 PAD;
++	u16 rxf0ovfl;	/* 0xda */
++	u16 rxf1ovfl;	/* 0xdc */
++	u16 rxf2ovfl;	/* 0xde */
++	u16 txsfovfl;	/* 0xe0 */
++	u16 pmqovfl;		/* 0xe2 */
++	u16 rxcgprqfrm;	/* 0xe4 */
++	u16 rxcgprsqovfl;	/* 0xe6 */
++	u16 txcgprsfail;	/* 0xe8 */
++	u16 txcgprssuc;	/* 0xea */
++	u16 prs_timeout;	/* 0xec */
++	u16 rxnack;
++	u16 frmscons;
++	u16 txnack;
++	u16 txglitch_nack;
++	u16 txburst;		/* 0xf6 # tx bursts */
++	u16 bphy_rxcrsglitch;	/* bphy rx crs glitch */
++	u16 phywatchdog;	/* 0xfa # of phy watchdog events */
++	u16 PAD;
++	u16 bphy_badplcp;	/* bphy bad plcp */
++};
++
++/* dot11 core-specific control flags */
++#define	SICF_PCLKE		0x0004	/* PHY clock enable */
++#define	SICF_PRST		0x0008	/* PHY reset */
++#define	SICF_MPCLKE		0x0010	/* MAC PHY clockcontrol enable */
++#define	SICF_FREF		0x0020	/* PLL FreqRefSelect */
++/* NOTE: the following bw bits only apply when the core is attached
++ * to a NPHY
++ */
++#define	SICF_BWMASK		0x00c0	/* phy clock mask (b6 & b7) */
++#define	SICF_BW40		0x0080	/* 40MHz BW (160MHz phyclk) */
++#define	SICF_BW20		0x0040	/* 20MHz BW (80MHz phyclk) */
++#define	SICF_BW10		0x0000	/* 10MHz BW (40MHz phyclk) */
++#define	SICF_GMODE		0x2000	/* gmode enable */
++
++/* dot11 core-specific status flags */
++#define	SISF_2G_PHY		0x0001	/* 2.4G capable phy */
++#define	SISF_5G_PHY		0x0002	/* 5G capable phy */
++#define	SISF_FCLKA		0x0004	/* FastClkAvailable */
++#define	SISF_DB_PHY		0x0008	/* Dualband phy */
++
++/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg === */
++/* radio and LPPHY regs are separated */
++
++#define	BPHY_REG_OFT_BASE	0x0
++/* offsets for indirect access to bphy registers */
++#define	BPHY_BB_CONFIG		0x01
++#define	BPHY_ADCBIAS		0x02
++#define	BPHY_ANACORE		0x03
++#define	BPHY_PHYCRSTH		0x06
++#define	BPHY_TEST		0x0a
++#define	BPHY_PA_TX_TO		0x10
++#define	BPHY_SYNTH_DC_TO	0x11
++#define	BPHY_PA_TX_TIME_UP	0x12
++#define	BPHY_RX_FLTR_TIME_UP	0x13
++#define	BPHY_TX_POWER_OVERRIDE	0x14
++#define	BPHY_RF_OVERRIDE	0x15
++#define	BPHY_RF_TR_LOOKUP1	0x16
++#define	BPHY_RF_TR_LOOKUP2	0x17
++#define	BPHY_COEFFS		0x18
++#define	BPHY_PLL_OUT		0x19
++#define	BPHY_REFRESH_MAIN	0x1a
++#define	BPHY_REFRESH_TO0	0x1b
++#define	BPHY_REFRESH_TO1	0x1c
++#define	BPHY_RSSI_TRESH		0x20
++#define	BPHY_IQ_TRESH_HH	0x21
++#define	BPHY_IQ_TRESH_H		0x22
++#define	BPHY_IQ_TRESH_L		0x23
++#define	BPHY_IQ_TRESH_LL	0x24
++#define	BPHY_GAIN		0x25
++#define	BPHY_LNA_GAIN_RANGE	0x26
++#define	BPHY_JSSI		0x27
++#define	BPHY_TSSI_CTL		0x28
++#define	BPHY_TSSI		0x29
++#define	BPHY_TR_LOSS_CTL	0x2a
++#define	BPHY_LO_LEAKAGE		0x2b
++#define	BPHY_LO_RSSI_ACC	0x2c
++#define	BPHY_LO_IQMAG_ACC	0x2d
++#define	BPHY_TX_DC_OFF1		0x2e
++#define	BPHY_TX_DC_OFF2		0x2f
++#define	BPHY_PEAK_CNT_THRESH	0x30
++#define	BPHY_FREQ_OFFSET	0x31
++#define	BPHY_DIVERSITY_CTL	0x32
++#define	BPHY_PEAK_ENERGY_LO	0x33
++#define	BPHY_PEAK_ENERGY_HI	0x34
++#define	BPHY_SYNC_CTL		0x35
++#define	BPHY_TX_PWR_CTRL	0x36
++#define BPHY_TX_EST_PWR		0x37
++#define	BPHY_STEP		0x38
++#define	BPHY_WARMUP		0x39
++#define	BPHY_LMS_CFF_READ	0x3a
++#define	BPHY_LMS_COEFF_I	0x3b
++#define	BPHY_LMS_COEFF_Q	0x3c
++#define	BPHY_SIG_POW		0x3d
++#define	BPHY_RFDC_CANCEL_CTL	0x3e
++#define	BPHY_HDR_TYPE		0x40
++#define	BPHY_SFD_TO		0x41
++#define	BPHY_SFD_CTL		0x42
++#define	BPHY_DEBUG		0x43
++#define	BPHY_RX_DELAY_COMP	0x44
++#define	BPHY_CRS_DROP_TO	0x45
++#define	BPHY_SHORT_SFD_NZEROS	0x46
++#define	BPHY_DSSS_COEFF1	0x48
++#define	BPHY_DSSS_COEFF2	0x49
++#define	BPHY_CCK_COEFF1		0x4a
++#define	BPHY_CCK_COEFF2		0x4b
++#define	BPHY_TR_CORR		0x4c
++#define	BPHY_ANGLE_SCALE	0x4d
++#define	BPHY_TX_PWR_BASE_IDX	0x4e
++#define	BPHY_OPTIONAL_MODES2	0x4f
++#define	BPHY_CCK_LMS_STEP	0x50
++#define	BPHY_BYPASS		0x51
++#define	BPHY_CCK_DELAY_LONG	0x52
++#define	BPHY_CCK_DELAY_SHORT	0x53
++#define	BPHY_PPROC_CHAN_DELAY	0x54
++#define	BPHY_DDFS_ENABLE	0x58
++#define	BPHY_PHASE_SCALE	0x59
++#define	BPHY_FREQ_CONTROL	0x5a
++#define	BPHY_LNA_GAIN_RANGE_10	0x5b
++#define	BPHY_LNA_GAIN_RANGE_32	0x5c
++#define	BPHY_OPTIONAL_MODES	0x5d
++#define	BPHY_RX_STATUS2		0x5e
++#define	BPHY_RX_STATUS3		0x5f
++#define	BPHY_DAC_CONTROL	0x60
++#define	BPHY_ANA11G_FILT_CTRL	0x62
++#define	BPHY_REFRESH_CTRL	0x64
++#define	BPHY_RF_OVERRIDE2	0x65
++#define	BPHY_SPUR_CANCEL_CTRL	0x66
++#define	BPHY_FINE_DIGIGAIN_CTRL	0x67
++#define	BPHY_RSSI_LUT		0x88
++#define	BPHY_RSSI_LUT_END	0xa7
++#define	BPHY_TSSI_LUT		0xa8
++#define	BPHY_TSSI_LUT_END	0xc7
++#define	BPHY_TSSI2PWR_LUT	0x380
++#define	BPHY_TSSI2PWR_LUT_END	0x39f
++#define	BPHY_LOCOMP_LUT		0x3a0
++#define	BPHY_LOCOMP_LUT_END	0x3bf
++#define	BPHY_TXGAIN_LUT		0x3c0
++#define	BPHY_TXGAIN_LUT_END	0x3ff
++
++/* Bits in BB_CONFIG: */
++#define	PHY_BBC_ANT_MASK	0x0180
++#define	PHY_BBC_ANT_SHIFT	7
++#define	BB_DARWIN		0x1000
++#define BBCFG_RESETCCA		0x4000
++#define BBCFG_RESETRX		0x8000
++
++/* Bits in phytest(0x0a): */
++#define	TST_DDFS		0x2000
++#define	TST_TXFILT1		0x0800
++#define	TST_UNSCRAM		0x0400
++#define	TST_CARR_SUPP		0x0200
++#define	TST_DC_COMP_LOOP	0x0100
++#define	TST_LOOPBACK		0x0080
++#define	TST_TXFILT0		0x0040
++#define	TST_TXTEST_ENABLE	0x0020
++#define	TST_TXTEST_RATE		0x0018
++#define	TST_TXTEST_PHASE	0x0007
++
++/* phytest txTestRate values */
++#define	TST_TXTEST_RATE_1MBPS	0
++#define	TST_TXTEST_RATE_2MBPS	1
++#define	TST_TXTEST_RATE_5_5MBPS	2
++#define	TST_TXTEST_RATE_11MBPS	3
++#define	TST_TXTEST_RATE_SHIFT	3
++
++#define SHM_BYT_CNT	0x2	/* IHR location */
++#define MAX_BYT_CNT	0x600	/* Maximum frame len */
++
++struct d11cnt {
++	u32 txfrag;
++	u32 txmulti;
++	u32 txfail;
++	u32 txretry;
++	u32 txretrie;
++	u32 rxdup;
++	u32 txrts;
++	u32 txnocts;
++	u32 txnoack;
++	u32 rxfrag;
++	u32 rxmulti;
++	u32 rxcrc;
++	u32 txfrmsnt;
++	u32 rxundec;
++};
++
++#endif				/* _BRCM_D11_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+new file mode 100644
+index 0000000..e898266
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+@@ -0,0 +1,1444 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/pci.h>
++
++#include <brcmu_utils.h>
++#include <aiutils.h>
++#include "types.h"
++#include "dma.h"
++#include "soc.h"
++
++/*
++ * dma register field offset calculation
++ */
++#define DMA64REGOFFS(field)		offsetof(struct dma64regs, field)
++#define DMA64TXREGOFFS(di, field)	(di->d64txregbase + DMA64REGOFFS(field))
++#define DMA64RXREGOFFS(di, field)	(di->d64rxregbase + DMA64REGOFFS(field))
++
++/*
++ * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
++ * a contiguous 8kB physical address.
++ */
++#define D64RINGALIGN_BITS	13
++#define	D64MAXRINGSZ		(1 << D64RINGALIGN_BITS)
++#define	D64RINGALIGN		(1 << D64RINGALIGN_BITS)
++
++#define	D64MAXDD	(D64MAXRINGSZ / sizeof(struct dma64desc))
++
++/* transmit channel control */
++#define	D64_XC_XE		0x00000001	/* transmit enable */
++#define	D64_XC_SE		0x00000002	/* transmit suspend request */
++#define	D64_XC_LE		0x00000004	/* loopback enable */
++#define	D64_XC_FL		0x00000010	/* flush request */
++#define	D64_XC_PD		0x00000800	/* parity check disable */
++#define	D64_XC_AE		0x00030000	/* address extension bits */
++#define	D64_XC_AE_SHIFT		16
++
++/* transmit descriptor table pointer */
++#define	D64_XP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* transmit channel status */
++#define	D64_XS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_XS0_XS_MASK		0xf0000000	/* transmit state */
++#define	D64_XS0_XS_SHIFT		28
++#define	D64_XS0_XS_DISABLED	0x00000000	/* disabled */
++#define	D64_XS0_XS_ACTIVE	0x10000000	/* active */
++#define	D64_XS0_XS_IDLE		0x20000000	/* idle wait */
++#define	D64_XS0_XS_STOPPED	0x30000000	/* stopped */
++#define	D64_XS0_XS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_XS1_AD_MASK		0x00001fff	/* active descriptor */
++#define	D64_XS1_XE_MASK		0xf0000000	/* transmit errors */
++#define	D64_XS1_XE_SHIFT		28
++#define	D64_XS1_XE_NOERR	0x00000000	/* no error */
++#define	D64_XS1_XE_DPE		0x10000000	/* descriptor protocol error */
++#define	D64_XS1_XE_DFU		0x20000000	/* data fifo underrun */
++#define	D64_XS1_XE_DTE		0x30000000	/* data transfer error */
++#define	D64_XS1_XE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_XS1_XE_COREE	0x50000000	/* core error */
++
++/* receive channel control */
++/* receive enable */
++#define	D64_RC_RE		0x00000001
++/* receive frame offset */
++#define	D64_RC_RO_MASK		0x000000fe
++#define	D64_RC_RO_SHIFT		1
++/* direct fifo receive (pio) mode */
++#define	D64_RC_FM		0x00000100
++/* separate rx header descriptor enable */
++#define	D64_RC_SH		0x00000200
++/* overflow continue */
++#define	D64_RC_OC		0x00000400
++/* parity check disable */
++#define	D64_RC_PD		0x00000800
++/* address extension bits */
++#define	D64_RC_AE		0x00030000
++#define	D64_RC_AE_SHIFT		16
++
++/* flags for dma controller */
++/* partity enable */
++#define DMA_CTRL_PEN		(1 << 0)
++/* rx overflow continue */
++#define DMA_CTRL_ROC		(1 << 1)
++/* allow rx scatter to multiple descriptors */
++#define DMA_CTRL_RXMULTI	(1 << 2)
++/* Unframed Rx/Tx data */
++#define DMA_CTRL_UNFRAMED	(1 << 3)
++
++/* receive descriptor table pointer */
++#define	D64_RP_LD_MASK		0x00000fff	/* last valid descriptor */
++
++/* receive channel status */
++#define	D64_RS0_CD_MASK		0x00001fff	/* current descriptor pointer */
++#define	D64_RS0_RS_MASK		0xf0000000	/* receive state */
++#define	D64_RS0_RS_SHIFT		28
++#define	D64_RS0_RS_DISABLED	0x00000000	/* disabled */
++#define	D64_RS0_RS_ACTIVE	0x10000000	/* active */
++#define	D64_RS0_RS_IDLE		0x20000000	/* idle wait */
++#define	D64_RS0_RS_STOPPED	0x30000000	/* stopped */
++#define	D64_RS0_RS_SUSP		0x40000000	/* suspend pending */
++
++#define	D64_RS1_AD_MASK		0x0001ffff	/* active descriptor */
++#define	D64_RS1_RE_MASK		0xf0000000	/* receive errors */
++#define	D64_RS1_RE_SHIFT		28
++#define	D64_RS1_RE_NOERR	0x00000000	/* no error */
++#define	D64_RS1_RE_DPO		0x10000000	/* descriptor protocol error */
++#define	D64_RS1_RE_DFU		0x20000000	/* data fifo overflow */
++#define	D64_RS1_RE_DTE		0x30000000	/* data transfer error */
++#define	D64_RS1_RE_DESRE	0x40000000	/* descriptor read error */
++#define	D64_RS1_RE_COREE	0x50000000	/* core error */
++
++/* fifoaddr */
++#define	D64_FA_OFF_MASK		0xffff	/* offset */
++#define	D64_FA_SEL_MASK		0xf0000	/* select */
++#define	D64_FA_SEL_SHIFT	16
++#define	D64_FA_SEL_XDD		0x00000	/* transmit dma data */
++#define	D64_FA_SEL_XDP		0x10000	/* transmit dma pointers */
++#define	D64_FA_SEL_RDD		0x40000	/* receive dma data */
++#define	D64_FA_SEL_RDP		0x50000	/* receive dma pointers */
++#define	D64_FA_SEL_XFD		0x80000	/* transmit fifo data */
++#define	D64_FA_SEL_XFP		0x90000	/* transmit fifo pointers */
++#define	D64_FA_SEL_RFD		0xc0000	/* receive fifo data */
++#define	D64_FA_SEL_RFP		0xd0000	/* receive fifo pointers */
++#define	D64_FA_SEL_RSD		0xe0000	/* receive frame status data */
++#define	D64_FA_SEL_RSP		0xf0000	/* receive frame status pointers */
++
++/* descriptor control flags 1 */
++#define D64_CTRL_COREFLAGS	0x0ff00000	/* core specific flags */
++#define	D64_CTRL1_EOT		((u32)1 << 28)	/* end of descriptor table */
++#define	D64_CTRL1_IOC		((u32)1 << 29)	/* interrupt on completion */
++#define	D64_CTRL1_EOF		((u32)1 << 30)	/* end of frame */
++#define	D64_CTRL1_SOF		((u32)1 << 31)	/* start of frame */
++
++/* descriptor control flags 2 */
++/* buffer byte count. real data len must <= 16KB */
++#define	D64_CTRL2_BC_MASK	0x00007fff
++/* address extension bits */
++#define	D64_CTRL2_AE		0x00030000
++#define	D64_CTRL2_AE_SHIFT	16
++/* parity bit */
++#define D64_CTRL2_PARITY	0x00040000
++
++/* control flags in the range [27:20] are core-specific and not defined here */
++#define	D64_CTRL_CORE_MASK	0x0ff00000
++
++#define D64_RX_FRM_STS_LEN	0x0000ffff	/* frame length mask */
++#define D64_RX_FRM_STS_OVFL	0x00800000	/* RxOverFlow */
++#define D64_RX_FRM_STS_DSCRCNT	0x0f000000  /* no. of descriptors used - 1 */
++#define D64_RX_FRM_STS_DATATYPE	0xf0000000	/* core-dependent data type */
++
++/*
++ * packet headroom necessary to accommodate the largest header
++ * in the system, (i.e TXOFF). By doing, we avoid the need to
++ * allocate an extra buffer for the header when bridging to WL.
++ * There is a compile time check in wlc.c which ensure that this
++ * value is at least as big as TXOFF. This value is used in
++ * dma_rxfill().
++ */
++
++#define BCMEXTRAHDROOM 172
++
++/* debug/trace */
++#ifdef DEBUG
++#define	DMA_ERROR(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 1)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#define	DMA_TRACE(fmt, ...)					\
++do {								\
++	if (*di->msg_level & 2)					\
++		pr_debug("%s: " fmt, __func__, ##__VA_ARGS__);	\
++} while (0)
++#else
++#define	DMA_ERROR(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#define	DMA_TRACE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++#endif				/* DEBUG */
++
++#define	DMA_NONE(fmt, ...)			\
++	no_printk(fmt, ##__VA_ARGS__)
++
++#define	MAXNAMEL	8	/* 8 char names */
++
++/* macros to convert between byte offsets and indexes */
++#define	B2I(bytes, type)	((bytes) / sizeof(type))
++#define	I2B(index, type)	((index) * sizeof(type))
++
++#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
++#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
++
++#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
++#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
++
++/*
++ * DMA Descriptor
++ * Descriptors are only read by the hardware, never written back.
++ */
++struct dma64desc {
++	__le32 ctrl1;	/* misc control bits & bufcount */
++	__le32 ctrl2;	/* buffer count and address extension */
++	__le32 addrlow;	/* memory address of the date buffer, bits 31:0 */
++	__le32 addrhigh; /* memory address of the date buffer, bits 63:32 */
++};
++
++/* dma engine software state */
++struct dma_info {
++	struct dma_pub dma; /* exported structure */
++	uint *msg_level;	/* message level pointer */
++	char name[MAXNAMEL];	/* callers name for diag msgs */
++
++	struct bcma_device *core;
++	struct device *dmadev;
++
++	bool dma64;	/* this dma engine is operating in 64-bit mode */
++	bool addrext;	/* this dma engine supports DmaExtendedAddrChanges */
++
++	/* 64-bit dma tx engine registers */
++	uint d64txregbase;
++	/* 64-bit dma rx engine registers */
++	uint d64rxregbase;
++	/* pointer to dma64 tx descriptor ring */
++	struct dma64desc *txd64;
++	/* pointer to dma64 rx descriptor ring */
++	struct dma64desc *rxd64;
++
++	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
++
++	u16 ntxd;		/* # tx descriptors tunable */
++	u16 txin;		/* index of next descriptor to reclaim */
++	u16 txout;		/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **txp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t txdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t txdpaorig;
++	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
++	u32 txdalloc;	/* #bytes allocated for the ring */
++	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
++			 * is not just an index, it needs all 13 bits to be
++			 * an offset from the addr register.
++			 */
++
++	u16 nrxd;	/* # rx descriptors tunable */
++	u16 rxin;	/* index of next descriptor to reclaim */
++	u16 rxout;	/* index of next descriptor to post */
++	/* pointer to parallel array of pointers to packets */
++	struct sk_buff **rxp;
++	/* Aligned physical address of descriptor ring */
++	dma_addr_t rxdpa;
++	/* Original physical address of descriptor ring */
++	dma_addr_t rxdpaorig;
++	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
++	u32 rxdalloc;	/* #bytes allocated for the ring */
++	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
++
++	/* tunables */
++	unsigned int rxbufsize;	/* rx buffer size in bytes, not including
++				 * the extra headroom
++				 */
++	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper
++				 * stack, e.g. some rx pkt buffers will be
++				 * bridged to tx side without byte copying.
++				 * The extra headroom needs to be large enough
++				 * to fit txheader needs. Some dongle driver may
++				 * not need it.
++				 */
++	uint nrxpost;		/* # rx buffers to keep posted */
++	unsigned int rxoffset;	/* rxcontrol offset */
++	/* add to get dma address of descriptor ring, low 32 bits */
++	uint ddoffsetlow;
++	/*   high 32 bits */
++	uint ddoffsethigh;
++	/* add to get dma address of data buffer, low 32 bits */
++	uint dataoffsetlow;
++	/*   high 32 bits */
++	uint dataoffsethigh;
++	/* descriptor base need to be aligned or not */
++	bool aligndesc_4k;
++};
++
++/*
++ * default dma message level (if input msg_level
++ * pointer is null in dma_attach())
++ */
++static uint dma_msg_level;
++
++/* Check for odd number of 1's */
++static u32 parity32(__le32 data)
++{
++	/* no swap needed for counting 1's */
++	u32 par_data = *(u32 *)&data;
++
++	par_data ^= par_data >> 16;
++	par_data ^= par_data >> 8;
++	par_data ^= par_data >> 4;
++	par_data ^= par_data >> 2;
++	par_data ^= par_data >> 1;
++
++	return par_data & 1;
++}
++
++static bool dma64_dd_parity(struct dma64desc *dd)
++{
++	return parity32(dd->addrlow ^ dd->addrhigh ^ dd->ctrl1 ^ dd->ctrl2);
++}
++
++/* descriptor bumping functions */
++
++static uint xxd(uint x, uint n)
++{
++	return x & (n - 1); /* faster than %, but n must be power of 2 */
++}
++
++static uint txd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->ntxd);
++}
++
++static uint rxd(struct dma_info *di, uint x)
++{
++	return xxd(x, di->nrxd);
++}
++
++static uint nexttxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint prevtxd(struct dma_info *di, uint i)
++{
++	return txd(di, i - 1);
++}
++
++static uint nextrxd(struct dma_info *di, uint i)
++{
++	return txd(di, i + 1);
++}
++
++static uint ntxdactive(struct dma_info *di, uint h, uint t)
++{
++	return txd(di, t-h);
++}
++
++static uint nrxdactive(struct dma_info *di, uint h, uint t)
++{
++	return rxd(di, t-h);
++}
++
++static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
++{
++	uint dmactrlflags;
++
++	if (di == NULL) {
++		DMA_ERROR("NULL dma handle\n");
++		return 0;
++	}
++
++	dmactrlflags = di->dma.dmactrlflags;
++	dmactrlflags &= ~mask;
++	dmactrlflags |= flags;
++
++	/* If trying to enable parity, check if parity is actually supported */
++	if (dmactrlflags & DMA_CTRL_PEN) {
++		u32 control;
++
++		control = bcma_read32(di->core, DMA64TXREGOFFS(di, control));
++		bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++		      control | D64_XC_PD);
++		if (bcma_read32(di->core, DMA64TXREGOFFS(di, control)) &
++		    D64_XC_PD)
++			/* We *can* disable it so it is supported,
++			 * restore control register
++			 */
++			bcma_write32(di->core, DMA64TXREGOFFS(di, control),
++				     control);
++		else
++			/* Not supported, don't allow it to be enabled */
++			dmactrlflags &= ~DMA_CTRL_PEN;
++	}
++
++	di->dma.dmactrlflags = dmactrlflags;
++
++	return dmactrlflags;
++}
++
++static bool _dma64_addrext(struct dma_info *di, uint ctrl_offset)
++{
++	u32 w;
++	bcma_set32(di->core, ctrl_offset, D64_XC_AE);
++	w = bcma_read32(di->core, ctrl_offset);
++	bcma_mask32(di->core, ctrl_offset, ~D64_XC_AE);
++	return (w & D64_XC_AE) == D64_XC_AE;
++}
++
++/*
++ * return true if this dma engine supports DmaExtendedAddrChanges,
++ * otherwise false
++ */
++static bool _dma_isaddrext(struct dma_info *di)
++{
++	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
++
++	/* not all tx or rx channel are available */
++	if (di->d64txregbase != 0) {
++		if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
++				  di->name);
++		return true;
++	} else if (di->d64rxregbase != 0) {
++		if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
++			DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
++				  di->name);
++		return true;
++	}
++
++	return false;
++}
++
++static bool _dma_descriptor_align(struct dma_info *di)
++{
++	u32 addrl;
++
++	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
++	if (di->d64txregbase != 0) {
++		bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64TXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	} else if (di->d64rxregbase != 0) {
++		bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow), 0xff0);
++		addrl = bcma_read32(di->core, DMA64RXREGOFFS(di, addrlow));
++		if (addrl != 0)
++			return false;
++	}
++	return true;
++}
++
++/*
++ * Descriptor table must start at the DMA hardware dictated alignment, so
++ * allocated memory must be large enough to support this requirement.
++ */
++static void *dma_alloc_consistent(struct dma_info *di, uint size,
++				  u16 align_bits, uint *alloced,
++				  dma_addr_t *pap)
++{
++	if (align_bits) {
++		u16 align = (1 << align_bits);
++		if (!IS_ALIGNED(PAGE_SIZE, align))
++			size += align;
++		*alloced = size;
++	}
++	return dma_alloc_coherent(di->dmadev, size, pap, GFP_ATOMIC);
++}
++
++static
++u8 dma_align_sizetobits(uint size)
++{
++	u8 bitpos = 0;
++	while (size >>= 1)
++		bitpos++;
++	return bitpos;
++}
++
++/* This function ensures that the DMA descriptor ring will not get allocated
++ * across Page boundary. If the allocation is done across the page boundary
++ * at the first time, then it is freed and the allocation is done at
++ * descriptor ring size aligned location. This will ensure that the ring will
++ * not cross page boundary
++ */
++static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
++			   u16 *alignbits, uint *alloced,
++			   dma_addr_t *descpa)
++{
++	void *va;
++	u32 desc_strtaddr;
++	u32 alignbytes = 1 << *alignbits;
++
++	va = dma_alloc_consistent(di, size, *alignbits, alloced, descpa);
++
++	if (NULL == va)
++		return NULL;
++
++	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
++	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
++							& boundary)) {
++		*alignbits = dma_align_sizetobits(size);
++		dma_free_coherent(di->dmadev, size, va, *descpa);
++		va = dma_alloc_consistent(di, size, *alignbits,
++			alloced, descpa);
++	}
++	return va;
++}
++
++static bool dma64_alloc(struct dma_info *di, uint direction)
++{
++	u16 size;
++	uint ddlen;
++	void *va;
++	uint alloced = 0;
++	u16 align;
++	u16 align_bits;
++
++	ddlen = sizeof(struct dma64desc);
++
++	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++	align_bits = di->dmadesc_align;
++	align = (1 << align_bits);
++
++	if (direction == DMA_TX) {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->txdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->txd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
++		di->txdpa = di->txdpaorig + di->txdalign;
++		di->txdalloc = alloced;
++	} else {
++		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
++			&alloced, &di->rxdpaorig);
++		if (va == NULL) {
++			DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n",
++				  di->name);
++			return false;
++		}
++		align = (1 << align_bits);
++		di->rxd64 = (struct dma64desc *)
++					roundup((unsigned long)va, align);
++		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
++		di->rxdpa = di->rxdpaorig + di->rxdalign;
++		di->rxdalloc = alloced;
++	}
++
++	return true;
++}
++
++static bool _dma_alloc(struct dma_info *di, uint direction)
++{
++	return dma64_alloc(di, direction);
++}
++
++struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++			   struct bcma_device *core,
++			   uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
++			   uint rxbufsize, int rxextheadroom,
++			   uint nrxpost, uint rxoffset, uint *msg_level)
++{
++	struct dma_info *di;
++	u8 rev = core->id.rev;
++	uint size;
++
++	/* allocate private info structure */
++	di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC);
++	if (di == NULL)
++		return NULL;
++
++	di->msg_level = msg_level ? msg_level : &dma_msg_level;
++
++
++	di->dma64 =
++		((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);
++
++	/* init dma reg info */
++	di->core = core;
++	di->d64txregbase = txregbase;
++	di->d64rxregbase = rxregbase;
++
++	/*
++	 * Default flags (which can be changed by the driver calling
++	 * dma_ctrlflags before enable): For backwards compatibility
++	 * both Rx Overflow Continue and Parity are DISABLED.
++	 */
++	_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
++
++	DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
++		  "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
++		  "txregbase %u rxregbase %u\n", name, "DMA64",
++		  di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
++		  rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
++
++	/* make a private copy of our callers name */
++	strncpy(di->name, name, MAXNAMEL);
++	di->name[MAXNAMEL - 1] = '\0';
++
++	di->dmadev = core->dma_dev;
++
++	/* save tunables */
++	di->ntxd = (u16) ntxd;
++	di->nrxd = (u16) nrxd;
++
++	/* the actual dma size doesn't include the extra headroom */
++	di->rxextrahdrroom =
++	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
++	if (rxbufsize > BCMEXTRAHDROOM)
++		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
++	else
++		di->rxbufsize = (u16) rxbufsize;
++
++	di->nrxpost = (u16) nrxpost;
++	di->rxoffset = (u8) rxoffset;
++
++	/*
++	 * figure out the DMA physical address offset for dd and data
++	 *     PCI/PCIE: they map silicon backplace address to zero
++	 *     based memory, need offset
++	 *     Other bus: use zero SI_BUS BIGENDIAN kludge: use sdram
++	 *     swapped region for data buffer, not descriptor
++	 */
++	di->ddoffsetlow = 0;
++	di->dataoffsetlow = 0;
++	/* add offset for pcie with DMA64 bus */
++	di->ddoffsetlow = 0;
++	di->ddoffsethigh = SI_PCIE_DMA_H32;
++	di->dataoffsetlow = di->ddoffsetlow;
++	di->dataoffsethigh = di->ddoffsethigh;
++	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
++	if ((core->id.id == SDIOD_CORE_ID)
++	    && ((rev > 0) && (rev <= 2)))
++		di->addrext = false;
++	else if ((core->id.id == I2S_CORE_ID) &&
++		 ((rev == 0) || (rev == 1)))
++		di->addrext = false;
++	else
++		di->addrext = _dma_isaddrext(di);
++
++	/* does the descriptor need to be aligned and if yes, on 4K/8K or not */
++	di->aligndesc_4k = _dma_descriptor_align(di);
++	if (di->aligndesc_4k) {
++		di->dmadesc_align = D64RINGALIGN_BITS;
++		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2))
++			/* for smaller dd table, HW relax alignment reqmnt */
++			di->dmadesc_align = D64RINGALIGN_BITS - 1;
++	} else {
++		di->dmadesc_align = 4;	/* 16 byte alignment */
++	}
++
++	DMA_NONE("DMA descriptor align_needed %d, align %d\n",
++		 di->aligndesc_4k, di->dmadesc_align);
++
++	/* allocate tx packet pointer vector */
++	if (ntxd) {
++		size = ntxd * sizeof(void *);
++		di->txp = kzalloc(size, GFP_ATOMIC);
++		if (di->txp == NULL)
++			goto fail;
++	}
++
++	/* allocate rx packet pointer vector */
++	if (nrxd) {
++		size = nrxd * sizeof(void *);
++		di->rxp = kzalloc(size, GFP_ATOMIC);
++		if (di->rxp == NULL)
++			goto fail;
++	}
++
++	/*
++	 * allocate transmit descriptor ring, only need ntxd descriptors
++	 * but it must be aligned
++	 */
++	if (ntxd) {
++		if (!_dma_alloc(di, DMA_TX))
++			goto fail;
++	}
++
++	/*
++	 * allocate receive descriptor ring, only need nrxd descriptors
++	 * but it must be aligned
++	 */
++	if (nrxd) {
++		if (!_dma_alloc(di, DMA_RX))
++			goto fail;
++	}
++
++	if ((di->ddoffsetlow != 0) && !di->addrext) {
++		if (di->txdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->txdpa);
++			goto fail;
++		}
++		if (di->rxdpa > SI_PCI_DMA_SZ) {
++			DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n",
++				  di->name, (u32)di->rxdpa);
++			goto fail;
++		}
++	}
++
++	DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n",
++		  di->ddoffsetlow, di->ddoffsethigh,
++		  di->dataoffsetlow, di->dataoffsethigh,
++		  di->addrext);
++
++	return (struct dma_pub *) di;
++
++ fail:
++	dma_detach((struct dma_pub *)di);
++	return NULL;
++}
++
++static inline void
++dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
++	     dma_addr_t pa, uint outidx, u32 *flags, u32 bufcount)
++{
++	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
++
++	/* PCI bus with big(>1G) physical address, use address extension */
++	if ((di->dataoffsetlow == 0) || !(pa & PCI32ADDR_HIGH)) {
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	} else {
++		/* address extension for 32-bit PCI */
++		u32 ae;
++
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
++		ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow);
++		ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh);
++		ddring[outidx].ctrl1 = cpu_to_le32(*flags);
++		ddring[outidx].ctrl2 = cpu_to_le32(ctrl2);
++	}
++	if (di->dma.dmactrlflags & DMA_CTRL_PEN) {
++		if (dma64_dd_parity(&ddring[outidx]))
++			ddring[outidx].ctrl2 =
++			     cpu_to_le32(ctrl2 | D64_CTRL2_PARITY);
++	}
++}
++
++/* !! may be called with core in reset */
++void dma_detach(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	/* free dma descriptor rings */
++	if (di->txd64)
++		dma_free_coherent(di->dmadev, di->txdalloc,
++				  ((s8 *)di->txd64 - di->txdalign),
++				  (di->txdpaorig));
++	if (di->rxd64)
++		dma_free_coherent(di->dmadev, di->rxdalloc,
++				  ((s8 *)di->rxd64 - di->rxdalign),
++				  (di->rxdpaorig));
++
++	/* free packet pointer vectors */
++	kfree(di->txp);
++	kfree(di->rxp);
++
++	/* free our private info structure */
++	kfree(di);
++
++}
++
++/* initialize descriptor table base address */
++static void
++_dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
++{
++	if (!di->aligndesc_4k) {
++		if (direction == DMA_TX)
++			di->xmtptrbase = pa;
++		else
++			di->rcvptrbase = pa;
++	}
++
++	if ((di->ddoffsetlow == 0)
++	    || !(pa & PCI32ADDR_HIGH)) {
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++		}
++	} else {
++		/* DMA64 32bits address extension */
++		u32 ae;
++
++		/* shift the high bit(s) from pa to ae */
++		ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++		pa &= ~PCI32ADDR_HIGH;
++
++		if (direction == DMA_TX) {
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64TXREGOFFS(di, control),
++				       D64_XC_AE, (ae << D64_XC_AE_SHIFT));
++		} else {
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
++				     pa + di->ddoffsetlow);
++			bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
++				     di->ddoffsethigh);
++			bcma_maskset32(di->core, DMA64RXREGOFFS(di, control),
++				       D64_RC_AE, (ae << D64_RC_AE_SHIFT));
++		}
++	}
++}
++
++static void _dma_rxenable(struct dma_info *di)
++{
++	uint dmactrlflags = di->dma.dmactrlflags;
++	u32 control;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	control = D64_RC_RE | (bcma_read32(di->core,
++					   DMA64RXREGOFFS(di, control)) &
++			       D64_RC_AE);
++
++	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_RC_PD;
++
++	if (dmactrlflags & DMA_CTRL_ROC)
++		control |= D64_RC_OC;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control),
++		((di->rxoffset << D64_RC_RO_SHIFT) | control));
++}
++
++void dma_rxinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return;
++
++	di->rxin = di->rxout = 0;
++
++	/* clear rx descriptor ring */
++	memset(di->rxd64, '\0', di->nrxd * sizeof(struct dma64desc));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++
++	_dma_rxenable(di);
++
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
++}
++
++static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
++{
++	uint i, curr;
++	struct sk_buff *rxp;
++	dma_addr_t pa;
++
++	i = di->rxin;
++
++	/* return if no packets posted */
++	if (i == di->rxout)
++		return NULL;
++
++	curr =
++	    B2I(((bcma_read32(di->core,
++			      DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) -
++		 di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
++
++	/* ignore curr if forceall */
++	if (!forceall && (i == curr))
++		return NULL;
++
++	/* get the packet pointer that corresponds to the rx descriptor */
++	rxp = di->rxp[i];
++	di->rxp[i] = NULL;
++
++	pa = le32_to_cpu(di->rxd64[i].addrlow) - di->dataoffsetlow;
++
++	/* clear this packet from the descriptor ring */
++	dma_unmap_single(di->dmadev, pa, di->rxbufsize, DMA_FROM_DEVICE);
++
++	di->rxd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++	di->rxd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++	di->rxin = nextrxd(di, i);
++
++	return rxp;
++}
++
++static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall)
++{
++	if (di->nrxd == 0)
++		return NULL;
++
++	return dma64_getnextrxp(di, forceall);
++}
++
++/*
++ * !! rx entry routine
++ * returns the number packages in the next frame, or 0 if there are no more
++ *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is
++ *   supported with pkts chain
++ *   otherwise, it's treated as giant pkt and will be tossed.
++ *   The DMA scattering starts with normal DMA header, followed by first
++ *   buffer data. After it reaches the max size of buffer, the data continues
++ *   in next DMA descriptor buffer WITHOUT DMA header
++ */
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff_head dma_frames;
++	struct sk_buff *p, *next;
++	uint len;
++	uint pkt_len;
++	int resid = 0;
++	int pktcnt = 1;
++
++	skb_queue_head_init(&dma_frames);
++ next_frame:
++	p = _dma_getnextrxp(di, false);
++	if (p == NULL)
++		return 0;
++
++	len = le16_to_cpu(*(__le16 *) (p->data));
++	DMA_TRACE("%s: dma_rx len %d\n", di->name, len);
++	dma_spin_for_len(len, p);
++
++	/* set actual length */
++	pkt_len = min((di->rxoffset + len), di->rxbufsize);
++	__skb_trim(p, pkt_len);
++	skb_queue_tail(&dma_frames, p);
++	resid = len - (di->rxbufsize - di->rxoffset);
++
++	/* check for single or multi-buffer rx */
++	if (resid > 0) {
++		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
++			pkt_len = min_t(uint, resid, di->rxbufsize);
++			__skb_trim(p, pkt_len);
++			skb_queue_tail(&dma_frames, p);
++			resid -= di->rxbufsize;
++			pktcnt++;
++		}
++
++#ifdef DEBUG
++		if (resid > 0) {
++			uint cur;
++			cur =
++			    B2I(((bcma_read32(di->core,
++					      DMA64RXREGOFFS(di, status0)) &
++				  D64_RS0_CD_MASK) - di->rcvptrbase) &
++				D64_RS0_CD_MASK, struct dma64desc);
++			DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
++				   di->rxin, di->rxout, cur);
++		}
++#endif				/* DEBUG */
++
++		if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
++			DMA_ERROR("%s: bad frame length (%d)\n",
++				  di->name, len);
++			skb_queue_walk_safe(&dma_frames, p, next) {
++				skb_unlink(p, &dma_frames);
++				brcmu_pkt_buf_free_skb(p);
++			}
++			di->dma.rxgiants++;
++			pktcnt = 1;
++			goto next_frame;
++		}
++	}
++
++	skb_queue_splice_tail(&dma_frames, skb_list);
++	return pktcnt;
++}
++
++static bool dma64_rxidle(struct dma_info *di)
++{
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->nrxd == 0)
++		return true;
++
++	return ((bcma_read32(di->core,
++			     DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) ==
++		(bcma_read32(di->core, DMA64RXREGOFFS(di, ptr)) &
++		 D64_RS0_CD_MASK));
++}
++
++/*
++ * post receive buffers
++ *  return false is refill failed completely and ring is empty this will stall
++ *  the rx dma and user might want to call rxfill again asap. This unlikely
++ *  happens on memory-rich NIC, but often on memory-constrained dongle
++ */
++bool dma_rxfill(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++	u16 rxin, rxout;
++	u32 flags = 0;
++	uint n;
++	uint i;
++	dma_addr_t pa;
++	uint extra_offset = 0;
++	bool ring_empty;
++
++	ring_empty = false;
++
++	/*
++	 * Determine how many receive buffers we're lacking
++	 * from the full complement, allocate, initialize,
++	 * and post them, then update the chip rx lastdscr.
++	 */
++
++	rxin = di->rxin;
++	rxout = di->rxout;
++
++	n = di->nrxpost - nrxdactive(di, rxin, rxout);
++
++	DMA_TRACE("%s: post %d\n", di->name, n);
++
++	if (di->rxbufsize > BCMEXTRAHDROOM)
++		extra_offset = di->rxextrahdrroom;
++
++	for (i = 0; i < n; i++) {
++		/*
++		 * the di->rxbufsize doesn't include the extra headroom,
++		 * we need to add it to the size to be allocated
++		 */
++		p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset);
++
++		if (p == NULL) {
++			DMA_ERROR("%s: out of rxbufs\n", di->name);
++			if (i == 0 && dma64_rxidle(di)) {
++				DMA_ERROR("%s: ring is empty !\n", di->name);
++				ring_empty = true;
++			}
++			di->dma.rxnobuf++;
++			break;
++		}
++		/* reserve an extra headroom, if applicable */
++		if (extra_offset)
++			skb_pull(p, extra_offset);
++
++		/* Do a cached write instead of uncached write since DMA_MAP
++		 * will flush the cache.
++		 */
++		*(u32 *) (p->data) = 0;
++
++		pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
++				    DMA_FROM_DEVICE);
++
++		/* save the free packet pointer */
++		di->rxp[rxout] = p;
++
++		/* reset flags for each descriptor */
++		flags = 0;
++		if (rxout == (di->nrxd - 1))
++			flags = D64_CTRL1_EOT;
++
++		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
++			     di->rxbufsize);
++		rxout = nextrxd(di, rxout);
++	}
++
++	di->rxout = rxout;
++
++	/* update the chip lastdscr pointer */
++	bcma_write32(di->core, DMA64RXREGOFFS(di, ptr),
++	      di->rcvptrbase + I2B(rxout, struct dma64desc));
++
++	return ring_empty;
++}
++
++void dma_rxreclaim(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	while ((p = _dma_getnextrxp(di, true)))
++		brcmu_pkt_buf_free_skb(p);
++}
++
++void dma_counterreset(struct dma_pub *pub)
++{
++	/* reset all software counters */
++	pub->rxgiants = 0;
++	pub->rxnobuf = 0;
++	pub->txnobuf = 0;
++}
++
++/* get the address of the var in order to change later */
++unsigned long dma_getvar(struct dma_pub *pub, const char *name)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	if (!strcmp(name, "&txavail"))
++		return (unsigned long)&(di->dma.txavail);
++	return 0;
++}
++
++/* 64-bit DMA functions */
++
++void dma_txinit(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 control = D64_XC_XE;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	di->txin = di->txout = 0;
++	di->dma.txavail = di->ntxd - 1;
++
++	/* clear tx descriptor ring */
++	memset(di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc)));
++
++	/* DMA engine with out alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (!di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++
++	if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
++		control |= D64_XC_PD;
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), control);
++
++	/* DMA engine with alignment requirement requires table to be inited
++	 * before enabling the engine
++	 */
++	if (di->aligndesc_4k)
++		_dma_ddtable_init(di, DMA_TX, di->txdpa);
++}
++
++void dma_txsuspend(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_set32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++}
++
++void dma_txresume(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	if (di->ntxd == 0)
++		return;
++
++	bcma_mask32(di->core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
++}
++
++bool dma_txsuspended(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++
++	return (di->ntxd == 0) ||
++	       ((bcma_read32(di->core,
++			     DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
++		D64_XC_SE);
++}
++
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	struct sk_buff *p;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->txin == di->txout)
++		return;
++
++	while ((p = dma_getnexttxp(pub, range))) {
++		/* For unframed data, we don't have any packets to free */
++		if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED))
++			brcmu_pkt_buf_free_skb(p);
++	}
++}
++
++bool dma_txreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->ntxd == 0)
++		return true;
++
++	/* suspend tx DMA first */
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) &&
++		  (status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED),
++		 10000);
++
++	bcma_write32(di->core, DMA64TXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
++		    D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000);
++
++	/* wait for the last transaction to complete */
++	udelay(300);
++
++	return status == D64_XS0_XS_DISABLED;
++}
++
++bool dma_rxreset(struct dma_pub *pub)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u32 status;
++
++	if (di->nrxd == 0)
++		return true;
++
++	bcma_write32(di->core, DMA64RXREGOFFS(di, control), 0);
++	SPINWAIT(((status =
++		   (bcma_read32(di->core, DMA64RXREGOFFS(di, status0)) &
++		    D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000);
++
++	return status == D64_RS0_RS_DISABLED;
++}
++
++/*
++ * !! tx entry routine
++ * WARNING: call must check the return value for error.
++ *   the error(toss frames) could be fatal and cause many subsequent hard
++ *   to debug problems
++ */
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	unsigned char *data;
++	uint len;
++	u16 txout;
++	u32 flags = 0;
++	dma_addr_t pa;
++
++	DMA_TRACE("%s:\n", di->name);
++
++	txout = di->txout;
++
++	/*
++	 * obtain and initialize transmit descriptor entry.
++	 */
++	data = p->data;
++	len = p->len;
++
++	/* no use to transmit a zero length packet */
++	if (len == 0)
++		return 0;
++
++	/* return nonzero if out of tx descriptors */
++	if (nexttxd(di, txout) == di->txin)
++		goto outoftxd;
++
++	/* get physical address of buffer start */
++	pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
++
++	/* With a DMA segment list, Descriptor table is filled
++	 * using the segment list instead of looping over
++	 * buffers in multi-chain DMA. Therefore, EOF for SGLIST
++	 * is when end of segment list is reached.
++	 */
++	flags = D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF;
++	if (txout == (di->ntxd - 1))
++		flags |= D64_CTRL1_EOT;
++
++	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
++
++	txout = nexttxd(di, txout);
++
++	/* save the packet */
++	di->txp[prevtxd(di, txout)] = p;
++
++	/* bump the tx descriptor index */
++	di->txout = txout;
++
++	/* kick the chip */
++	if (commit)
++		bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
++		      di->xmtptrbase + I2B(txout, struct dma64desc));
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return 0;
++
++ outoftxd:
++	DMA_ERROR("%s: out of txds !!!\n", di->name);
++	brcmu_pkt_buf_free_skb(p);
++	di->dma.txavail = 0;
++	di->dma.txnobuf++;
++	return -1;
++}
++
++/*
++ * Reclaim next completed txd (txds if using chained buffers) in the range
++ * specified and return associated packet.
++ * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be
++ * transmitted as noted by the hardware "CurrDescr" pointer.
++ * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be
++ * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
++ * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
++ * return associated packet regardless of the value of hardware pointers.
++ */
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
++{
++	struct dma_info *di = (struct dma_info *)pub;
++	u16 start, end, i;
++	u16 active_desc;
++	struct sk_buff *txp;
++
++	DMA_TRACE("%s: %s\n",
++		  di->name,
++		  range == DMA_RANGE_ALL ? "all" :
++		  range == DMA_RANGE_TRANSMITTED ? "transmitted" :
++		  "transferred");
++
++	if (di->ntxd == 0)
++		return NULL;
++
++	txp = NULL;
++
++	start = di->txin;
++	if (range == DMA_RANGE_ALL)
++		end = di->txout;
++	else {
++		end = (u16) (B2I(((bcma_read32(di->core,
++					       DMA64TXREGOFFS(di, status0)) &
++				   D64_XS0_CD_MASK) - di->xmtptrbase) &
++				 D64_XS0_CD_MASK, struct dma64desc));
++
++		if (range == DMA_RANGE_TRANSFERED) {
++			active_desc =
++				(u16)(bcma_read32(di->core,
++						  DMA64TXREGOFFS(di, status1)) &
++				      D64_XS1_AD_MASK);
++			active_desc =
++			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
++			active_desc = B2I(active_desc, struct dma64desc);
++			if (end != active_desc)
++				end = prevtxd(di, active_desc);
++		}
++	}
++
++	if ((start == 0) && (end > di->txout))
++		goto bogus;
++
++	for (i = start; i != end && !txp; i = nexttxd(di, i)) {
++		dma_addr_t pa;
++		uint size;
++
++		pa = le32_to_cpu(di->txd64[i].addrlow) - di->dataoffsetlow;
++
++		size =
++		    (le32_to_cpu(di->txd64[i].ctrl2) &
++		     D64_CTRL2_BC_MASK);
++
++		di->txd64[i].addrlow = cpu_to_le32(0xdeadbeef);
++		di->txd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
++
++		txp = di->txp[i];
++		di->txp[i] = NULL;
++
++		dma_unmap_single(di->dmadev, pa, size, DMA_TO_DEVICE);
++	}
++
++	di->txin = i;
++
++	/* tx flow control */
++	di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1;
++
++	return txp;
++
++ bogus:
++	DMA_NONE("bogus curr: start %d end %d txout %d\n",
++		 start, end, di->txout);
++	return NULL;
++}
++
++/*
++ * Mac80211 initiated actions sometimes require packets in the DMA queue to be
++ * modified. The modified portion of the packet is not under control of the DMA
++ * engine. This function calls a caller-supplied function for each packet in
++ * the caller specified dma chain.
++ */
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a)
++{
++	struct dma_info *di = (struct dma_info *) dmah;
++	uint i =   di->txin;
++	uint end = di->txout;
++	struct sk_buff *skb;
++	struct ieee80211_tx_info *tx_info;
++
++	while (i != end) {
++		skb = (struct sk_buff *)di->txp[i];
++		if (skb != NULL) {
++			tx_info = (struct ieee80211_tx_info *)skb->cb;
++			(callback_fnc)(tx_info, arg_a);
++		}
++		i = nexttxd(di, i);
++	}
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+new file mode 100644
+index 0000000..cc269ee
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h
+@@ -0,0 +1,122 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DMA_H_
++#define	_BRCM_DMA_H_
++
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include "types.h"		/* forward structure declarations */
++
++/* map/unmap direction */
++#define	DMA_TX	1		/* TX direction for DMA */
++#define	DMA_RX	2		/* RX direction for DMA */
++
++/* DMA structure:
++ *  support two DMA engines: 32 bits address or 64 bit addressing
++ *  basic DMA register set is per channel(transmit or receive)
++ *  a pair of channels is defined for convenience
++ */
++
++/* 32 bits addressing */
++
++struct dma32diag {	/* diag access */
++	u32 fifoaddr;	/* diag address */
++	u32 fifodatalow;	/* low 32bits of data */
++	u32 fifodatahigh;	/* high 32bits of data */
++	u32 pad;		/* reserved */
++};
++
++/* 64 bits addressing */
++
++/* dma registers per channel(xmt or rcv) */
++struct dma64regs {
++	u32 control;	/* enable, et al */
++	u32 ptr;	/* last descriptor posted to chip */
++	u32 addrlow;	/* desc ring base address low 32-bits (8K aligned) */
++	u32 addrhigh;	/* desc ring base address bits 63:32 (8K aligned) */
++	u32 status0;	/* current descriptor, xmt state */
++	u32 status1;	/* active descriptor, xmt error */
++};
++
++/* range param for dma_getnexttxp() and dma_txreclaim */
++enum txd_range {
++	DMA_RANGE_ALL = 1,
++	DMA_RANGE_TRANSMITTED,
++	DMA_RANGE_TRANSFERED
++};
++
++/*
++ * Exported data structure (read-only)
++ */
++/* export structure */
++struct dma_pub {
++	uint txavail;		/* # free tx descriptors */
++	uint dmactrlflags;	/* dma control flags */
++
++	/* rx error counters */
++	uint rxgiants;		/* rx giant frames */
++	uint rxnobuf;		/* rx out of dma descriptors */
++	/* tx error counters */
++	uint txnobuf;		/* tx out of dma descriptors */
++};
++
++extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
++				  struct bcma_device *d11core,
++				  uint txregbase, uint rxregbase,
++				  uint ntxd, uint nrxd,
++				  uint rxbufsize, int rxextheadroom,
++				  uint nrxpost, uint rxoffset, uint *msg_level);
++
++void dma_rxinit(struct dma_pub *pub);
++int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
++bool dma_rxfill(struct dma_pub *pub);
++bool dma_rxreset(struct dma_pub *pub);
++bool dma_txreset(struct dma_pub *pub);
++void dma_txinit(struct dma_pub *pub);
++int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
++void dma_txsuspend(struct dma_pub *pub);
++bool dma_txsuspended(struct dma_pub *pub);
++void dma_txresume(struct dma_pub *pub);
++void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
++void dma_rxreclaim(struct dma_pub *pub);
++void dma_detach(struct dma_pub *pub);
++unsigned long dma_getvar(struct dma_pub *pub, const char *name);
++struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
++void dma_counterreset(struct dma_pub *pub);
++
++void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
++		      (void *pkt, void *arg_a), void *arg_a);
++
++/*
++ * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
++ * the packet length is not updated yet (by DMA) on the expected time.
++ * Workaround is to hold processor till DMA updates the length, and stay off
++ * the bus to allow DMA update the length in buffer
++ */
++static inline void dma_spin_for_len(uint len, struct sk_buff *head)
++{
++#if defined(CONFIG_BCM47XX)
++	if (!len) {
++		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
++			udelay(1);
++
++		*(u16 *) (head->data) = cpu_to_le16((u16) len);
++	}
++#endif				/* defined(CONFIG_BCM47XX) */
++}
++
++#endif				/* _BRCM_DMA_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+new file mode 100644
+index 0000000..21f7939
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+@@ -0,0 +1,1609 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define __UNDEF_NO_VERSION__
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/etherdevice.h>
++#include <linux/sched.h>
++#include <linux/firmware.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/bcma/bcma.h>
++#include <net/mac80211.h>
++#include <defs.h>
++#include "phy/phy_int.h"
++#include "d11.h"
++#include "channel.h"
++#include "scb.h"
++#include "pub.h"
++#include "ucode_loader.h"
++#include "mac80211_if.h"
++#include "main.h"
++
++#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
++
++/* Flags we support */
++#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
++	FIF_ALLMULTI | \
++	FIF_FCSFAIL | \
++	FIF_CONTROL | \
++	FIF_OTHER_BSS | \
++	FIF_BCN_PRBRESP_PROMISC | \
++	FIF_PSPOLL)
++
++#define CHAN2GHZ(channel, freqency, chflags)  { \
++	.band = IEEE80211_BAND_2GHZ, \
++	.center_freq = (freqency), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 19, \
++}
++
++#define CHAN5GHZ(channel, chflags)  { \
++	.band = IEEE80211_BAND_5GHZ, \
++	.center_freq = 5000 + 5*(channel), \
++	.hw_value = (channel), \
++	.flags = chflags, \
++	.max_antenna_gain = 0, \
++	.max_power = 21, \
++}
++
++#define RATE(rate100m, _flags) { \
++	.bitrate = (rate100m), \
++	.flags = (_flags), \
++	.hw_value = (rate100m / 5), \
++}
++
++struct firmware_hdr {
++	__le32 offset;
++	__le32 len;
++	__le32 idx;
++};
++
++static const char * const brcms_firmwares[MAX_FW_IMAGES] = {
++	"brcm/bcm43xx",
++	NULL
++};
++
++static int n_adapters_found;
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++/* recognized BCMA Core IDs */
++static struct bcma_device_id brcms_coreid_table[] = {
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
++	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
++	BCMA_CORETABLE_END
++};
++MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
++
++#ifdef DEBUG
++static int msglevel = 0xdeadbeef;
++module_param(msglevel, int, 0);
++#endif				/* DEBUG */
++
++static struct ieee80211_channel brcms_2ghz_chantable[] = {
++	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN2GHZ(5, 2432, 0),
++	CHAN2GHZ(6, 2437, 0),
++	CHAN2GHZ(7, 2442, 0),
++	CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(12, 2467,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(13, 2472,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN2GHZ(14, 2484,
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
++	/* UNII-1 */
++	CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
++	/* UNII-2 */
++	CHAN5GHZ(52,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(56,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(60,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(64,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	/* MID */
++	CHAN5GHZ(100,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(104,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(108,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(112,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(116,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(120,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(124,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(128,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(132,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(136,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(140,
++		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
++		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
++		 IEEE80211_CHAN_NO_HT40MINUS),
++	/* UNII-3 */
++	CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
++	CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
++	CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
++};
++
++/*
++ * The rate table is used for both 2.4G and 5G rates. The
++ * latter being a subset as it does not support CCK rates.
++ */
++static struct ieee80211_rate legacy_ratetable[] = {
++	RATE(10, 0),
++	RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
++	RATE(60, 0),
++	RATE(90, 0),
++	RATE(120, 0),
++	RATE(180, 0),
++	RATE(240, 0),
++	RATE(360, 0),
++	RATE(480, 0),
++	RATE(540, 0),
++};
++
++static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = {
++	.band = IEEE80211_BAND_2GHZ,
++	.channels = brcms_2ghz_chantable,
++	.n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
++	.bitrates = legacy_ratetable,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable),
++	.ht_cap = {
++		   /* from include/linux/ieee80211.h */
++		   .cap = IEEE80211_HT_CAP_GRN_FLD |
++			  IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = {
++	.band = IEEE80211_BAND_5GHZ,
++	.channels = brcms_5ghz_nphy_chantable,
++	.n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
++	.bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
++	.n_bitrates = ARRAY_SIZE(legacy_ratetable) -
++			BRCMS_LEGACY_5G_RATE_OFFSET,
++	.ht_cap = {
++		   .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
++			  IEEE80211_HT_CAP_SGI_40,
++		   .ht_supported = true,
++		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
++		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
++		   .mcs = {
++			   /* placeholders for now */
++			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
++			   .rx_highest = cpu_to_le16(500),
++			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
++		   }
++};
++
++/* flags the given rate in rateset as requested */
++static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
++{
++	u32 i;
++
++	for (i = 0; i < rs->count; i++) {
++		if (rate != (rs->rates[i] & 0x7f))
++			continue;
++
++		if (is_br)
++			rs->rates[i] |= BRCMS_RATE_FLAG;
++		else
++			rs->rates[i] &= BRCMS_RATE_MASK;
++		return;
++	}
++}
++
++static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	if (!wl->pub->up) {
++		wiphy_err(wl->wiphy, "ops->tx called while down\n");
++		kfree_skb(skb);
++		goto done;
++	}
++	brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++static int brcms_ops_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++	int err;
++
++	ieee80211_wake_queues(hw);
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_rfkill_set_hw_state(wl);
++	spin_unlock_bh(&wl->lock);
++	if (!blocked)
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++
++	spin_lock_bh(&wl->lock);
++	/* avoid acknowledging frames before a non-monitor device is added */
++	wl->mute_tx = true;
++
++	if (!wl->pub->up)
++		err = brcms_up(wl);
++	else
++		err = -ENODEV;
++	spin_unlock_bh(&wl->lock);
++
++	if (err != 0)
++		wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
++			  err);
++	return err;
++}
++
++static void brcms_ops_stop(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	int status;
++
++	ieee80211_stop_queues(hw);
++
++	if (wl->wlc == NULL)
++		return;
++
++	spin_lock_bh(&wl->lock);
++	status = brcms_c_chipmatch(wl->wlc->hw->vendorid,
++				   wl->wlc->hw->deviceid);
++	spin_unlock_bh(&wl->lock);
++	if (!status) {
++		wiphy_err(wl->wiphy,
++			  "wl: brcms_ops_stop: chipmatch failed\n");
++		return;
++	}
++
++	/* put driver in down state */
++	spin_lock_bh(&wl->lock);
++	brcms_down(wl);
++	spin_unlock_bh(&wl->lock);
++}
++
++static int
++brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++	struct brcms_info *wl = hw->priv;
++
++	/* Just STA for now */
++	if (vif->type != NL80211_IFTYPE_STATION) {
++		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
++			  " STA for now\n", __func__, vif->type);
++		return -EOPNOTSUPP;
++	}
++
++	wl->mute_tx = false;
++	brcms_c_mute(wl->wlc, false);
++
++	return 0;
++}
++
++static void
++brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
++{
++}
++
++static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
++{
++	struct ieee80211_conf *conf = &hw->conf;
++	struct brcms_info *wl = hw->priv;
++	int err = 0;
++	int new_int;
++	struct wiphy *wiphy = hw->wiphy;
++
++	spin_lock_bh(&wl->lock);
++	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
++		brcms_c_set_beacon_listen_interval(wl->wlc,
++						   conf->listen_interval);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
++		wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
++			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
++			  "true" : "false");
++	if (changed & IEEE80211_CONF_CHANGE_PS)
++		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
++			  __func__, conf->flags & IEEE80211_CONF_PS ?
++			  "true" : "false");
++
++	if (changed & IEEE80211_CONF_CHANGE_POWER) {
++		err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
++		if (err < 0) {
++			wiphy_err(wiphy, "%s: Error setting power_level\n",
++				  __func__);
++			goto config_out;
++		}
++		new_int = brcms_c_get_tx_power(wl->wlc);
++		if (new_int != conf->power_level)
++			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
++				  "\n", __func__, conf->power_level,
++				  new_int);
++	}
++	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
++		if (conf->channel_type == NL80211_CHAN_HT20 ||
++		    conf->channel_type == NL80211_CHAN_NO_HT)
++			err = brcms_c_set_channel(wl->wlc,
++						  conf->channel->hw_value);
++		else
++			err = -ENOTSUPP;
++	}
++	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
++		err = brcms_c_set_rate_limit(wl->wlc,
++					     conf->short_frame_max_tx_count,
++					     conf->long_frame_max_tx_count);
++
++ config_out:
++	spin_unlock_bh(&wl->lock);
++	return err;
++}
++
++static void
++brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
++			struct ieee80211_vif *vif,
++			struct ieee80211_bss_conf *info, u32 changed)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	if (changed & BSS_CHANGED_ASSOC) {
++		/* association status changed (associated/disassociated)
++		 * also implies a change in the AID.
++		 */
++		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
++			  __func__, info->assoc ? "" : "dis");
++		spin_lock_bh(&wl->lock);
++		brcms_c_associate_upd(wl->wlc, info->assoc);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_ERP_SLOT) {
++		s8 val;
++
++		/* slot timing changed */
++		if (info->use_short_slot)
++			val = 1;
++		else
++			val = 0;
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_shortslot_override(wl->wlc, val);
++		spin_unlock_bh(&wl->lock);
++	}
++
++	if (changed & BSS_CHANGED_HT) {
++		/* 802.11n parameters changed */
++		u16 mode = info->ht_operation_mode;
++
++		spin_lock_bh(&wl->lock);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
++			mode & IEEE80211_HT_OP_MODE_PROTECTION);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
++			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
++		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
++			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BASIC_RATES) {
++		struct ieee80211_supported_band *bi;
++		u32 br_mask, i;
++		u16 rate;
++		struct brcm_rateset rs;
++		int error;
++
++		/* retrieve the current rates */
++		spin_lock_bh(&wl->lock);
++		brcms_c_get_current_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++
++		br_mask = info->basic_rates;
++		bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
++		for (i = 0; i < bi->n_bitrates; i++) {
++			/* convert to internal rate value */
++			rate = (bi->bitrates[i].bitrate << 1) / 10;
++
++			/* set/clear basic rate flag */
++			brcms_set_basic_rate(&rs, rate, br_mask & 1);
++			br_mask >>= 1;
++		}
++
++		/* update the rate set */
++		spin_lock_bh(&wl->lock);
++		error = brcms_c_set_rateset(wl->wlc, &rs);
++		spin_unlock_bh(&wl->lock);
++		if (error)
++			wiphy_err(wiphy, "changing basic rates failed: %d\n",
++				  error);
++	}
++	if (changed & BSS_CHANGED_BEACON_INT) {
++		/* Beacon interval changed */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BSSID) {
++		/* BSSID changed, for whatever reason (IBSS and managed mode) */
++		spin_lock_bh(&wl->lock);
++		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
++		spin_unlock_bh(&wl->lock);
++	}
++	if (changed & BSS_CHANGED_BEACON)
++		/* Beacon data changed, retrieve new beacon (beaconing modes) */
++		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
++
++	if (changed & BSS_CHANGED_BEACON_ENABLED) {
++		/* Beaconing should be enabled/disabled (beaconing modes) */
++		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
++			  info->enable_beacon ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_CQM) {
++		/* Connection quality monitor config changed */
++		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
++			  " (implement)\n", __func__, info->cqm_rssi_thold,
++			  info->cqm_rssi_hyst);
++	}
++
++	if (changed & BSS_CHANGED_IBSS) {
++		/* IBSS join status changed */
++		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
++			  info->ibss_joined ? "true" : "false");
++	}
++
++	if (changed & BSS_CHANGED_ARP_FILTER) {
++		/* Hardware ARP filter address list or state changed */
++		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
++			  " (implement)\n", __func__, info->arp_filter_enabled ?
++			  "true" : "false", info->arp_addr_cnt);
++	}
++
++	if (changed & BSS_CHANGED_QOS) {
++		/*
++		 * QoS for this association was enabled/disabled.
++		 * Note that it is only ever disabled for station mode.
++		 */
++		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
++			  info->qos ? "true" : "false");
++	}
++	return;
++}
++
++static void
++brcms_ops_configure_filter(struct ieee80211_hw *hw,
++			unsigned int changed_flags,
++			unsigned int *total_flags, u64 multicast)
++{
++	struct brcms_info *wl = hw->priv;
++	struct wiphy *wiphy = hw->wiphy;
++
++	changed_flags &= MAC_FILTERS;
++	*total_flags &= MAC_FILTERS;
++
++	if (changed_flags & FIF_PROMISC_IN_BSS)
++		wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
++	if (changed_flags & FIF_ALLMULTI)
++		wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
++	if (changed_flags & FIF_FCSFAIL)
++		wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
++	if (changed_flags & FIF_CONTROL)
++		wiphy_dbg(wiphy, "FIF_CONTROL\n");
++	if (changed_flags & FIF_OTHER_BSS)
++		wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
++	if (changed_flags & FIF_PSPOLL)
++		wiphy_dbg(wiphy, "FIF_PSPOLL\n");
++	if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
++		wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_mac_promisc(wl->wlc, *total_flags);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_start(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	spin_lock_bh(&wl->lock);
++	brcms_c_scan_stop(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++	return;
++}
++
++static int
++brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
++		  const struct ieee80211_tx_queue_params *params)
++{
++	struct brcms_info *wl = hw->priv;
++
++	spin_lock_bh(&wl->lock);
++	brcms_c_wme_setparams(wl->wlc, queue, params, true);
++	spin_unlock_bh(&wl->lock);
++
++	return 0;
++}
++
++static int
++brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
++	       struct ieee80211_sta *sta)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++
++	brcms_c_init_scb(scb);
++
++	wl->pub->global_ampdu = &(scb->scb_ampdu);
++	wl->pub->global_ampdu->scb = scb;
++	wl->pub->global_ampdu->max_pdu = 16;
++
++	/*
++	 * minstrel_ht initiates addBA on our behalf by calling
++	 * ieee80211_start_tx_ba_session()
++	 */
++	return 0;
++}
++
++static int
++brcms_ops_ampdu_action(struct ieee80211_hw *hw,
++		    struct ieee80211_vif *vif,
++		    enum ieee80211_ampdu_mlme_action action,
++		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
++		    u8 buf_size)
++{
++	struct brcms_info *wl = hw->priv;
++	struct scb *scb = &wl->wlc->pri_scb;
++	int status;
++
++	if (WARN_ON(scb->magic != SCB_MAGIC))
++		return -EIDRM;
++	switch (action) {
++	case IEEE80211_AMPDU_RX_START:
++		break;
++	case IEEE80211_AMPDU_RX_STOP:
++		break;
++	case IEEE80211_AMPDU_TX_START:
++		spin_lock_bh(&wl->lock);
++		status = brcms_c_aggregatable(wl->wlc, tid);
++		spin_unlock_bh(&wl->lock);
++		if (!status) {
++			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
++				  tid);
++			return -EINVAL;
++		}
++		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++
++	case IEEE80211_AMPDU_TX_STOP:
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_flush(wl->wlc, sta, tid);
++		spin_unlock_bh(&wl->lock);
++		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
++		break;
++	case IEEE80211_AMPDU_TX_OPERATIONAL:
++		/*
++		 * BA window size from ADDBA response ('buf_size') defines how
++		 * many outstanding MPDUs are allowed for the BA stream by
++		 * recipient and traffic class. 'ampdu_factor' gives maximum
++		 * AMPDU size.
++		 */
++		spin_lock_bh(&wl->lock);
++		brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
++			(1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
++			 sta->ht_cap.ampdu_factor)) - 1);
++		spin_unlock_bh(&wl->lock);
++		/* Power save wakeup */
++		break;
++	default:
++		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
++			  __func__);
++	}
++
++	return 0;
++}
++
++static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	bool blocked;
++
++	spin_lock_bh(&wl->lock);
++	blocked = brcms_c_check_radio_disabled(wl->wlc);
++	spin_unlock_bh(&wl->lock);
++
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++}
++
++static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
++{
++	struct brcms_info *wl = hw->priv;
++
++	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
++
++	/* wait for packet queue and dma fifos to run empty */
++	spin_lock_bh(&wl->lock);
++	brcms_c_wait_for_tx_completion(wl->wlc, drop);
++	spin_unlock_bh(&wl->lock);
++}
++
++static const struct ieee80211_ops brcms_ops = {
++	.tx = brcms_ops_tx,
++	.start = brcms_ops_start,
++	.stop = brcms_ops_stop,
++	.add_interface = brcms_ops_add_interface,
++	.remove_interface = brcms_ops_remove_interface,
++	.config = brcms_ops_config,
++	.bss_info_changed = brcms_ops_bss_info_changed,
++	.configure_filter = brcms_ops_configure_filter,
++	.sw_scan_start = brcms_ops_sw_scan_start,
++	.sw_scan_complete = brcms_ops_sw_scan_complete,
++	.conf_tx = brcms_ops_conf_tx,
++	.sta_add = brcms_ops_sta_add,
++	.ampdu_action = brcms_ops_ampdu_action,
++	.rfkill_poll = brcms_ops_rfkill_poll,
++	.flush = brcms_ops_flush,
++};
++
++/*
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
++{
++	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
++}
++
++void brcms_dpc(unsigned long data)
++{
++	struct brcms_info *wl;
++
++	wl = (struct brcms_info *) data;
++
++	spin_lock_bh(&wl->lock);
++
++	/* call the common second level interrupt handler */
++	if (wl->pub->up) {
++		if (wl->resched) {
++			unsigned long flags;
++
++			spin_lock_irqsave(&wl->isr_lock, flags);
++			brcms_c_intrsupd(wl->wlc);
++			spin_unlock_irqrestore(&wl->isr_lock, flags);
++		}
++
++		wl->resched = brcms_c_dpc(wl->wlc, true);
++	}
++
++	/* brcms_c_dpc() may bring the driver down */
++	if (!wl->pub->up)
++		goto done;
++
++	/* re-schedule dpc */
++	if (wl->resched)
++		tasklet_schedule(&wl->tasklet);
++	else
++		/* re-enable interrupts */
++		brcms_intrson(wl);
++
++ done:
++	spin_unlock_bh(&wl->lock);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
++{
++	int status;
++	struct device *device = &pdev->dev;
++	char fw_name[100];
++	int i;
++
++	memset(&wl->fw, 0, sizeof(struct brcms_firmware));
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		if (brcms_firmwares[i] == NULL)
++			break;
++		sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
++			UCODE_LOADER_API_VER);
++		status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
++		if (status) {
++			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
++				  KBUILD_MODNAME, fw_name);
++			return status;
++		}
++		wl->fw.hdr_num_entries[i] =
++		    wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
++	}
++	wl->fw.fw_cnt = i;
++	return brcms_ucode_data_init(wl, &wl->ucode);
++}
++
++/*
++ * Precondition: Since this function is called in brcms_pci_probe() context,
++ * no locking is required.
++ */
++static void brcms_release_fw(struct brcms_info *wl)
++{
++	int i;
++	for (i = 0; i < MAX_FW_IMAGES; i++) {
++		release_firmware(wl->fw.fw_bin[i]);
++		release_firmware(wl->fw.fw_hdr[i]);
++	}
++}
++
++/**
++ * This function frees the WL per-device resources.
++ *
++ * This function frees resources owned by the WL device pointed to
++ * by the wl parameter.
++ *
++ * precondition: can both be called locked and unlocked
++ *
++ */
++static void brcms_free(struct brcms_info *wl)
++{
++	struct brcms_timer *t, *next;
++
++	/* free ucode data */
++	if (wl->fw.fw_cnt)
++		brcms_ucode_data_free(&wl->ucode);
++	if (wl->irq)
++		free_irq(wl->irq, wl);
++
++	/* kill dpc */
++	tasklet_kill(&wl->tasklet);
++
++	if (wl->pub)
++		brcms_c_module_unregister(wl->pub, "linux", wl);
++
++	/* free common resources */
++	if (wl->wlc) {
++		brcms_c_detach(wl->wlc);
++		wl->wlc = NULL;
++		wl->pub = NULL;
++	}
++
++	/* virtual interface deletion is deferred so we cannot spinwait */
++
++	/* wait for all pending callbacks to complete */
++	while (atomic_read(&wl->callbacks) > 0)
++		schedule();
++
++	/* free timers */
++	for (t = wl->timers; t; t = next) {
++		next = t->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++	}
++}
++
++/*
++* called from both kernel as from this kernel module (error flow on attach)
++* precondition: perimeter lock is not acquired.
++*/
++static void brcms_remove(struct bcma_device *pdev)
++{
++	struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
++	struct brcms_info *wl = hw->priv;
++
++	if (wl->wlc) {
++		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
++		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
++		ieee80211_unregister_hw(hw);
++	}
++
++	brcms_free(wl);
++
++	bcma_set_drvdata(pdev, NULL);
++	ieee80211_free_hw(hw);
++}
++
++static irqreturn_t brcms_isr(int irq, void *dev_id)
++{
++	struct brcms_info *wl;
++	bool ours, wantdpc;
++
++	wl = (struct brcms_info *) dev_id;
++
++	spin_lock(&wl->isr_lock);
++
++	/* call common first level interrupt handler */
++	ours = brcms_c_isr(wl->wlc, &wantdpc);
++	if (ours) {
++		/* if more to do... */
++		if (wantdpc) {
++
++			/* ...and call the second level interrupt handler */
++			/* schedule dpc */
++			tasklet_schedule(&wl->tasklet);
++		}
++	}
++
++	spin_unlock(&wl->isr_lock);
++
++	return IRQ_RETVAL(ours);
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_rate_init(struct ieee80211_hw *hw)
++{
++	struct brcms_info *wl = hw->priv;
++	struct brcms_c_info *wlc = wl->wlc;
++	struct ieee80211_supported_band *band;
++	int has_5g = 0;
++	u16 phy_type;
++
++	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
++	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
++
++	phy_type = brcms_c_get_phy_type(wl->wlc, 0);
++	if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++		band = &wlc->bandstate[BAND_2G_INDEX]->band;
++		*band = brcms_band_2GHz_nphy_template;
++		if (phy_type == PHY_TYPE_LCN) {
++			/* Single stream */
++			band->ht_cap.mcs.rx_mask[1] = 0;
++			band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
++		}
++		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
++	} else {
++		return -EPERM;
++	}
++
++	/* Assume all bands use the same phy.  True for 11n devices. */
++	if (wl->pub->_nbands > 1) {
++		has_5g++;
++		if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
++			band = &wlc->bandstate[BAND_5G_INDEX]->band;
++			*band = brcms_band_5GHz_nphy_template;
++			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
++		} else {
++			return -EPERM;
++		}
++	}
++	return 0;
++}
++
++/*
++ * is called in brcms_pci_probe() context, therefore no locking required.
++ */
++static int ieee_hw_init(struct ieee80211_hw *hw)
++{
++	hw->flags = IEEE80211_HW_SIGNAL_DBM
++	    /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
++	    | IEEE80211_HW_REPORTS_TX_ACK_STATUS
++	    | IEEE80211_HW_AMPDU_AGGREGATION;
++
++	hw->extra_tx_headroom = brcms_c_get_header_len();
++	hw->queues = N_TX_QUEUES;
++	hw->max_rates = 2;	/* Primary rate and 1 fallback rate */
++
++	/* channel change time is dependent on chip and band  */
++	hw->channel_change_time = 7 * 1000;
++	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
++
++	hw->rate_control_algorithm = "minstrel_ht";
++
++	hw->sta_data_size = 0;
++	return ieee_hw_rate_init(hw);
++}
++
++/**
++ * attach to the WL device.
++ *
++ * Attach to the WL device identified by vendor and device parameters.
++ * regs is a host accessible memory address pointing to WL device registers.
++ *
++ * brcms_attach is not defined as static because in the case where no bus
++ * is defined, wl_attach will never be called, and thus, gcc will issue
++ * a warning that this function is defined but not used if we declare
++ * it as static.
++ *
++ *
++ * is called in brcms_bcma_probe() context, therefore no locking required.
++ */
++static struct brcms_info *brcms_attach(struct bcma_device *pdev)
++{
++	struct brcms_info *wl = NULL;
++	int unit, err;
++	struct ieee80211_hw *hw;
++	u8 perm[ETH_ALEN];
++
++	unit = n_adapters_found;
++	err = 0;
++
++	if (unit < 0)
++		return NULL;
++
++	/* allocate private info */
++	hw = bcma_get_drvdata(pdev);
++	if (hw != NULL)
++		wl = hw->priv;
++	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
++		return NULL;
++	wl->wiphy = hw->wiphy;
++
++	atomic_set(&wl->callbacks, 0);
++
++	/* setup the bottom half handler */
++	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
++
++	spin_lock_init(&wl->lock);
++	spin_lock_init(&wl->isr_lock);
++
++	/* prepare ucode */
++	if (brcms_request_fw(wl, pdev) < 0) {
++		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
++			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
++		brcms_release_fw(wl);
++		brcms_remove(pdev);
++		return NULL;
++	}
++
++	/* common load-time initialization */
++	wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
++	brcms_release_fw(wl);
++	if (!wl->wlc) {
++		wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
++			  KBUILD_MODNAME, err);
++		goto fail;
++	}
++	wl->pub = brcms_c_pub(wl->wlc);
++
++	wl->pub->ieee_hw = hw;
++
++	/* register our interrupt handler */
++	if (request_irq(pdev->irq, brcms_isr,
++			IRQF_SHARED, KBUILD_MODNAME, wl)) {
++		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
++		goto fail;
++	}
++	wl->irq = pdev->irq;
++
++	/* register module */
++	brcms_c_module_register(wl->pub, "linux", wl, NULL);
++
++	if (ieee_hw_init(hw)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
++			  __func__);
++		goto fail;
++	}
++
++	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
++	if (WARN_ON(!is_valid_ether_addr(perm)))
++		goto fail;
++	SET_IEEE80211_PERM_ADDR(hw, perm);
++
++	err = ieee80211_register_hw(hw);
++	if (err)
++		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
++			  "%d\n", __func__, err);
++
++	if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode))
++		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
++			  __func__, err);
++
++	n_adapters_found++;
++	return wl;
++
++fail:
++	brcms_free(wl);
++	return NULL;
++}
++
++
++
++/**
++ * determines if a device is a WL device, and if so, attaches it.
++ *
++ * This function determines if a device pointed to by pdev is a WL device,
++ * and if so, performs a brcms_attach() on it.
++ *
++ * Perimeter lock is initialized in the course of this function.
++ */
++static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
++		 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
++		 pdev->irq);
++
++	if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
++	    (pdev->id.id != BCMA_CORE_80211))
++		return -ENODEV;
++
++	hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
++	if (!hw) {
++		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
++		return -ENOMEM;
++	}
++
++	SET_IEEE80211_DEV(hw, &pdev->dev);
++
++	bcma_set_drvdata(pdev, hw);
++
++	memset(hw->priv, 0, sizeof(*wl));
++
++	wl = brcms_attach(pdev);
++	if (!wl) {
++		pr_err("%s: brcms_attach failed!\n", __func__);
++		return -ENODEV;
++	}
++	return 0;
++}
++
++static int brcms_suspend(struct bcma_device *pdev)
++{
++	struct brcms_info *wl;
++	struct ieee80211_hw *hw;
++
++	hw = bcma_get_drvdata(pdev);
++	wl = hw->priv;
++	if (!wl) {
++		pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
++		       __func__);
++		return -ENODEV;
++	}
++
++	/* only need to flag hw is down for proper resume */
++	spin_lock_bh(&wl->lock);
++	wl->pub->hw_up = false;
++	spin_unlock_bh(&wl->lock);
++
++	pr_debug("brcms_suspend ok\n");
++
++	return 0;
++}
++
++static int brcms_resume(struct bcma_device *pdev)
++{
++	pr_debug("brcms_resume ok\n");
++	return 0;
++}
++
++static struct bcma_driver brcms_bcma_driver = {
++	.name     = KBUILD_MODNAME,
++	.probe    = brcms_bcma_probe,
++	.suspend  = brcms_suspend,
++	.resume   = brcms_resume,
++	.remove   = __devexit_p(brcms_remove),
++	.id_table = brcms_coreid_table,
++};
++
++/**
++ * This is the main entry point for the brcmsmac driver.
++ *
++ * This function is scheduled upon module initialization and
++ * does the driver registration, which result in brcms_bcma_probe()
++ * call resulting in the driver bringup.
++ */
++static void brcms_driver_init(struct work_struct *work)
++{
++	int error;
++
++	error = bcma_driver_register(&brcms_bcma_driver);
++	if (error)
++		pr_err("%s: register returned %d\n", __func__, error);
++}
++
++static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
++
++static int __init brcms_module_init(void)
++{
++#ifdef DEBUG
++	if (msglevel != 0xdeadbeef)
++		brcm_msg_level = msglevel;
++#endif
++	if (!schedule_work(&brcms_driver_work))
++		return -EBUSY;
++
++	return 0;
++}
++
++/**
++ * This function unloads the brcmsmac driver from the system.
++ *
++ * This function unconditionally unloads the brcmsmac driver module from the
++ * system.
++ *
++ */
++static void __exit brcms_module_exit(void)
++{
++	cancel_work_sync(&brcms_driver_work);
++	bcma_driver_unregister(&brcms_bcma_driver);
++}
++
++module_init(brcms_module_init);
++module_exit(brcms_module_exit);
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++			 bool state, int prio)
++{
++	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_init(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_reset(wl);
++	brcms_c_init(wl->wlc, wl->mute_tx);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++uint brcms_reset(struct brcms_info *wl)
++{
++	BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
++	brcms_c_reset(wl->wlc);
++
++	/* dpc will not be rescheduled */
++	wl->resched = false;
++
++	return 0;
++}
++
++void brcms_fatal_error(struct brcms_info *wl)
++{
++	wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n",
++		  wl->wlc->pub->unit);
++	brcms_reset(wl);
++	ieee80211_restart_hw(wl->pub->ieee_hw);
++}
++
++/*
++ * These are interrupt on/off entry points. Disable interrupts
++ * during interrupt state transition.
++ */
++void brcms_intrson(struct brcms_info *wl)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrson(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++u32 brcms_intrsoff(struct brcms_info *wl)
++{
++	unsigned long flags;
++	u32 status;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	status = brcms_c_intrsoff(wl->wlc);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++	return status;
++}
++
++void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&wl->isr_lock, flags);
++	brcms_c_intrsrestore(wl->wlc, macintmask);
++	spin_unlock_irqrestore(&wl->isr_lock, flags);
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_up(struct brcms_info *wl)
++{
++	int error = 0;
++
++	if (wl->pub->up)
++		return 0;
++
++	error = brcms_c_up(wl->wlc);
++
++	return error;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_down(struct brcms_info *wl)
++{
++	uint callbacks, ret_val = 0;
++
++	/* call common down function */
++	ret_val = brcms_c_down(wl->wlc);
++	callbacks = atomic_read(&wl->callbacks) - ret_val;
++
++	/* wait for down callbacks to complete */
++	spin_unlock_bh(&wl->lock);
++
++	/* For HIGH_only driver, it's important to actually schedule other work,
++	 * not just spin wait since everything runs at schedule level
++	 */
++	SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
++
++	spin_lock_bh(&wl->lock);
++}
++
++/*
++* precondition: perimeter lock is not acquired
++ */
++static void _brcms_timer(struct work_struct *work)
++{
++	struct brcms_timer *t = container_of(work, struct brcms_timer,
++					     dly_wrk.work);
++
++	spin_lock_bh(&t->wl->lock);
++
++	if (t->set) {
++		if (t->periodic) {
++			atomic_inc(&t->wl->callbacks);
++			ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
++						     &t->dly_wrk,
++						     msecs_to_jiffies(t->ms));
++		} else {
++			t->set = false;
++		}
++
++		t->fn(t->arg);
++	}
++
++	atomic_dec(&t->wl->callbacks);
++
++	spin_unlock_bh(&t->wl->lock);
++}
++
++/*
++ * Adds a timer to the list. Caller supplies a timer function.
++ * Is called from wlc.
++ *
++ * precondition: perimeter lock has been acquired
++ */
++struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				     void (*fn) (void *arg),
++				     void *arg, const char *name)
++{
++	struct brcms_timer *t;
++
++	t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
++	if (!t)
++		return NULL;
++
++	INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
++	t->wl = wl;
++	t->fn = fn;
++	t->arg = arg;
++	t->next = wl->timers;
++	wl->timers = t;
++
++#ifdef DEBUG
++	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
++	if (t->name)
++		strcpy(t->name, name);
++#endif
++
++	return t;
++}
++
++/*
++ * adds only the kernel timer since it's going to be more accurate
++ * as well as it's easier to make it periodic
++ *
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
++{
++	struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
++
++#ifdef DEBUG
++	if (t->set)
++		wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
++			  __func__, t->name, periodic);
++#endif
++	t->ms = ms;
++	t->periodic = (bool) periodic;
++	t->set = true;
++
++	atomic_inc(&t->wl->callbacks);
++
++	ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
++}
++
++/*
++ * return true if timer successfully deleted, false if still pending
++ *
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_del_timer(struct brcms_timer *t)
++{
++	if (t->set) {
++		t->set = false;
++		if (!cancel_delayed_work(&t->dly_wrk))
++			return false;
++
++		atomic_dec(&t->wl->callbacks);
++	}
++
++	return true;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_free_timer(struct brcms_timer *t)
++{
++	struct brcms_info *wl = t->wl;
++	struct brcms_timer *tmp;
++
++	/* delete the timer in case it is active */
++	brcms_del_timer(t);
++
++	if (wl->timers == t) {
++		wl->timers = wl->timers->next;
++#ifdef DEBUG
++		kfree(t->name);
++#endif
++		kfree(t);
++		return;
++
++	}
++
++	tmp = wl->timers;
++	while (tmp) {
++		if (tmp->next == t) {
++			tmp->next = t->next;
++#ifdef DEBUG
++			kfree(t->name);
++#endif
++			kfree(t);
++			return;
++		}
++		tmp = tmp->next;
++	}
++
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			u32 len = le32_to_cpu(hdr->len);
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				*pbuf = kmemdup(pdata, len, GFP_ATOMIC);
++				if (*pbuf == NULL)
++					goto fail;
++
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
++		  idx);
++	*pbuf = NULL;
++fail:
++	return -ENODATA;
++}
++
++/*
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
++{
++	int i, entry;
++	const u8 *pdata;
++	struct firmware_hdr *hdr;
++	for (i = 0; i < wl->fw.fw_cnt; i++) {
++		hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
++		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
++		     entry++, hdr++) {
++			if (le32_to_cpu(hdr->idx) == idx) {
++				pdata = wl->fw.fw_bin[i]->data +
++					le32_to_cpu(hdr->offset);
++				if (le32_to_cpu(hdr->len) != 4) {
++					wiphy_err(wl->wiphy,
++						  "ERROR: fw hdr len\n");
++					return -ENOMSG;
++				}
++				*n_bytes = le32_to_cpu(*((__le32 *) pdata));
++				return 0;
++			}
++		}
++	}
++	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
++	return -ENOMSG;
++}
++
++/*
++ * precondition: can both be called locked and unlocked
++ */
++void brcms_ucode_free_buf(void *p)
++{
++	kfree(p);
++}
++
++/*
++ * checks validity of all firmware images loaded from user space
++ *
++ * Precondition: Since this function is called in brcms_bcma_probe() context,
++ * no locking is required.
++ */
++int brcms_check_firmwares(struct brcms_info *wl)
++{
++	int i;
++	int entry;
++	int rc = 0;
++	const struct firmware *fw;
++	const struct firmware *fw_hdr;
++	struct firmware_hdr *ucode_hdr;
++	for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
++		fw =  wl->fw.fw_bin[i];
++		fw_hdr = wl->fw.fw_hdr[i];
++		if (fw == NULL && fw_hdr == NULL) {
++			break;
++		} else if (fw == NULL || fw_hdr == NULL) {
++			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
++				  __func__);
++			rc = -EBADF;
++		} else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
++			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
++				"size %zu/%zu\n", __func__, fw_hdr->size,
++				sizeof(struct firmware_hdr));
++			rc = -EBADF;
++		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
++			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
++				  "%zu\n", __func__, fw->size);
++			rc = -EBADF;
++		} else {
++			/* check if ucode section overruns firmware image */
++			ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
++			for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
++			     !rc; entry++, ucode_hdr++) {
++				if (le32_to_cpu(ucode_hdr->offset) +
++				    le32_to_cpu(ucode_hdr->len) >
++				    fw->size) {
++					wiphy_err(wl->wiphy,
++						  "%s: conflicting bin/hdr\n",
++						  __func__);
++					rc = -EBADF;
++				}
++			}
++		}
++	}
++	if (rc == 0 && wl->fw.fw_cnt != i) {
++		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
++			wl->fw.fw_cnt);
++		rc = -EBADF;
++	}
++	return rc;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
++{
++	bool blocked = brcms_c_check_radio_disabled(wl->wlc);
++
++	spin_unlock_bh(&wl->lock);
++	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
++	if (blocked)
++		wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
++	spin_lock_bh(&wl->lock);
++	return blocked;
++}
++
++/*
++ * precondition: perimeter lock has been acquired
++ */
++void brcms_msleep(struct brcms_info *wl, uint ms)
++{
++	spin_unlock_bh(&wl->lock);
++	msleep(ms);
++	spin_lock_bh(&wl->lock);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+new file mode 100644
+index 0000000..9358bd5
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+@@ -0,0 +1,108 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAC80211_IF_H_
++#define _BRCM_MAC80211_IF_H_
++
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/workqueue.h>
++
++#include "ucode_loader.h"
++/*
++ * Starting index for 5G rates in the
++ * legacy rate table.
++ */
++#define BRCMS_LEGACY_5G_RATE_OFFSET	4
++
++/* softmac ioctl definitions */
++#define BRCMS_SET_SHORTSLOT_OVERRIDE		146
++
++struct brcms_timer {
++	struct delayed_work dly_wrk;
++	struct brcms_info *wl;
++	void (*fn) (void *);	/* function called upon expiration */
++	void *arg;		/* fixed argument provided to called function */
++	uint ms;
++	bool periodic;
++	bool set;		/* indicates if timer is active */
++	struct brcms_timer *next;	/* for freeing on unload */
++#ifdef DEBUG
++	char *name;		/* Description of the timer */
++#endif
++};
++
++struct brcms_if {
++	uint subunit;		/* WDS/BSS unit */
++	struct pci_dev *pci_dev;
++};
++
++#define MAX_FW_IMAGES		4
++struct brcms_firmware {
++	u32 fw_cnt;
++	const struct firmware *fw_bin[MAX_FW_IMAGES];
++	const struct firmware *fw_hdr[MAX_FW_IMAGES];
++	u32 hdr_num_entries[MAX_FW_IMAGES];
++};
++
++struct brcms_info {
++	struct brcms_pub *pub;		/* pointer to public wlc state */
++	struct brcms_c_info *wlc;	/* pointer to private common data */
++	u32 magic;
++
++	int irq;
++
++	spinlock_t lock;	/* per-device perimeter lock */
++	spinlock_t isr_lock;	/* per-device ISR synchronization lock */
++
++
++	/* timer related fields */
++	atomic_t callbacks;	/* # outstanding callback functions */
++	struct brcms_timer *timers;	/* timer cleanup queue */
++
++	struct tasklet_struct tasklet;	/* dpc tasklet */
++	bool resched;		/* dpc needs to be and is rescheduled */
++	struct brcms_firmware fw;
++	struct wiphy *wiphy;
++	struct brcms_ucode ucode;
++	bool mute_tx;
++};
++
++/* misc callbacks */
++extern void brcms_init(struct brcms_info *wl);
++extern uint brcms_reset(struct brcms_info *wl);
++extern void brcms_intrson(struct brcms_info *wl);
++extern u32 brcms_intrsoff(struct brcms_info *wl);
++extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
++extern int brcms_up(struct brcms_info *wl);
++extern void brcms_down(struct brcms_info *wl);
++extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
++				bool state, int prio);
++extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
++
++/* timer functions */
++extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
++				      void (*fn) (void *arg), void *arg,
++				      const char *name);
++extern void brcms_free_timer(struct brcms_timer *timer);
++extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
++extern bool brcms_del_timer(struct brcms_timer *timer);
++extern void brcms_msleep(struct brcms_info *wl, uint ms);
++extern void brcms_dpc(unsigned long data);
++extern void brcms_timer(struct brcms_timer *t);
++extern void brcms_fatal_error(struct brcms_info *wl);
++
++#endif				/* _BRCM_MAC80211_IF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+new file mode 100644
+index 0000000..d7d4a33
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -0,0 +1,8495 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/printk.h>
++#include <linux/pci_ids.h>
++#include <linux/if_ether.h>
++#include <net/mac80211.h>
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include "rate.h"
++#include "scb.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "antsel.h"
++#include "stf.h"
++#include "ampdu.h"
++#include "mac80211_if.h"
++#include "ucode_loader.h"
++#include "main.h"
++#include "soc.h"
++
++/*
++ * Indication for txflowcontrol that all priority bits in
++ * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
++ */
++#define ALLPRIO				-1
++
++/* watchdog timer, in unit of ms */
++#define TIMER_INTERVAL_WATCHDOG		1000
++/* radio monitor timer, in unit of ms */
++#define TIMER_INTERVAL_RADIOCHK		800
++
++/* beacon interval, in unit of 1024TU */
++#define BEACON_INTERVAL_DEFAULT		100
++
++/* n-mode support capability */
++/* 2x2 includes both 1x1 & 2x2 devices
++ * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
++ * control it independently
++ */
++#define WL_11N_2x2			1
++#define WL_11N_3x3			3
++#define WL_11N_4x4			4
++
++#define EDCF_ACI_MASK			0x60
++#define EDCF_ACI_SHIFT			5
++#define EDCF_ECWMIN_MASK		0x0f
++#define EDCF_ECWMAX_SHIFT		4
++#define EDCF_AIFSN_MASK			0x0f
++#define EDCF_AIFSN_MAX			15
++#define EDCF_ECWMAX_MASK		0xf0
++
++#define EDCF_AC_BE_TXOP_STA		0x0000
++#define EDCF_AC_BK_TXOP_STA		0x0000
++#define EDCF_AC_VO_ACI_STA		0x62
++#define EDCF_AC_VO_ECW_STA		0x32
++#define EDCF_AC_VI_ACI_STA		0x42
++#define EDCF_AC_VI_ECW_STA		0x43
++#define EDCF_AC_BK_ECW_STA		0xA4
++#define EDCF_AC_VI_TXOP_STA		0x005e
++#define EDCF_AC_VO_TXOP_STA		0x002f
++#define EDCF_AC_BE_ACI_STA		0x03
++#define EDCF_AC_BE_ECW_STA		0xA4
++#define EDCF_AC_BK_ACI_STA		0x27
++#define EDCF_AC_VO_TXOP_AP		0x002f
++
++#define EDCF_TXOP2USEC(txop)		((txop) << 5)
++#define EDCF_ECW2CW(exp)		((1 << (exp)) - 1)
++
++#define APHY_SYMBOL_TIME		4
++#define APHY_PREAMBLE_TIME		16
++#define APHY_SIGNAL_TIME		4
++#define APHY_SIFS_TIME			16
++#define APHY_SERVICE_NBITS		16
++#define APHY_TAIL_NBITS			6
++#define BPHY_SIFS_TIME			10
++#define BPHY_PLCP_SHORT_TIME		96
++
++#define PREN_PREAMBLE			24
++#define PREN_MM_EXT			12
++#define PREN_PREAMBLE_EXT		4
++
++#define DOT11_MAC_HDR_LEN		24
++#define DOT11_ACK_LEN			10
++#define DOT11_BA_LEN			4
++#define DOT11_OFDM_SIGNAL_EXTENSION	6
++#define DOT11_MIN_FRAG_LEN		256
++#define DOT11_RTS_LEN			16
++#define DOT11_CTS_LEN			10
++#define DOT11_BA_BITMAP_LEN		128
++#define DOT11_MIN_BEACON_PERIOD		1
++#define DOT11_MAX_BEACON_PERIOD		0xFFFF
++#define DOT11_MAXNUMFRAGS		16
++#define DOT11_MAX_FRAG_LEN		2346
++
++#define BPHY_PLCP_TIME			192
++#define RIFS_11N_TIME			2
++
++/* length of the BCN template area */
++#define BCN_TMPL_LEN			512
++
++/* brcms_bss_info flag bit values */
++#define BRCMS_BSS_HT			0x0020	/* BSS is HT (MIMO) capable */
++
++/* chip rx buffer offset */
++#define BRCMS_HWRXOFF			38
++
++/* rfdisable delay timer 500 ms, runs of ALP clock */
++#define RFDISABLE_DEFAULT		10000000
++
++#define BRCMS_TEMPSENSE_PERIOD		10	/* 10 second timeout */
++
++/* precedences numbers for wlc queues. These are twice as may levels as
++ * 802.1D priorities.
++ * Odd numbers are used for HI priority traffic at same precedence levels
++ * These constants are used ONLY by wlc_prio2prec_map.  Do not use them
++ * elsewhere.
++ */
++#define _BRCMS_PREC_NONE		0	/* None = - */
++#define _BRCMS_PREC_BK			2	/* BK - Background */
++#define _BRCMS_PREC_BE			4	/* BE - Best-effort */
++#define _BRCMS_PREC_EE			6	/* EE - Excellent-effort */
++#define _BRCMS_PREC_CL			8	/* CL - Controlled Load */
++#define _BRCMS_PREC_VI			10	/* Vi - Video */
++#define _BRCMS_PREC_VO			12	/* Vo - Voice */
++#define _BRCMS_PREC_NC			14	/* NC - Network Control */
++
++/* synthpu_dly times in us */
++#define SYNTHPU_DLY_APHY_US		3700
++#define SYNTHPU_DLY_BPHY_US		1050
++#define SYNTHPU_DLY_NPHY_US		2048
++#define SYNTHPU_DLY_LPPHY_US		300
++
++#define ANTCNT				10	/* vanilla M_MAX_ANTCNT val */
++
++/* Per-AC retry limit register definitions; uses defs.h bitfield macros */
++#define EDCF_SHORT_S			0
++#define EDCF_SFB_S			4
++#define EDCF_LONG_S			8
++#define EDCF_LFB_S			12
++#define EDCF_SHORT_M			BITFIELD_MASK(4)
++#define EDCF_SFB_M			BITFIELD_MASK(4)
++#define EDCF_LONG_M			BITFIELD_MASK(4)
++#define EDCF_LFB_M			BITFIELD_MASK(4)
++
++#define RETRY_SHORT_DEF			7	/* Default Short retry Limit */
++#define RETRY_SHORT_MAX			255	/* Maximum Short retry Limit */
++#define RETRY_LONG_DEF			4	/* Default Long retry count */
++#define RETRY_SHORT_FB			3	/* Short count for fb rate */
++#define RETRY_LONG_FB			2	/* Long count for fb rate */
++
++#define APHY_CWMIN			15
++#define PHY_CWMAX			1023
++
++#define EDCF_AIFSN_MIN			1
++
++#define FRAGNUM_MASK			0xF
++
++#define APHY_SLOT_TIME			9
++#define BPHY_SLOT_TIME			20
++
++#define WL_SPURAVOID_OFF		0
++#define WL_SPURAVOID_ON1		1
++#define WL_SPURAVOID_ON2		2
++
++/* invalid core flags, use the saved coreflags */
++#define BRCMS_USE_COREFLAGS		0xffffffff
++
++/* values for PLCPHdr_override */
++#define BRCMS_PLCP_AUTO			-1
++#define BRCMS_PLCP_SHORT		0
++#define BRCMS_PLCP_LONG			1
++
++/* values for g_protection_override and n_protection_override */
++#define BRCMS_PROTECTION_AUTO		-1
++#define BRCMS_PROTECTION_OFF		0
++#define BRCMS_PROTECTION_ON		1
++#define BRCMS_PROTECTION_MMHDR_ONLY	2
++#define BRCMS_PROTECTION_CTS_ONLY	3
++
++/* values for g_protection_control and n_protection_control */
++#define BRCMS_PROTECTION_CTL_OFF	0
++#define BRCMS_PROTECTION_CTL_LOCAL	1
++#define BRCMS_PROTECTION_CTL_OVERLAP	2
++
++/* values for n_protection */
++#define BRCMS_N_PROTECTION_OFF		0
++#define BRCMS_N_PROTECTION_OPTIONAL	1
++#define BRCMS_N_PROTECTION_20IN40	2
++#define BRCMS_N_PROTECTION_MIXEDMODE	3
++
++/* values for band specific 40MHz capabilities */
++#define BRCMS_N_BW_20ALL		0
++#define BRCMS_N_BW_40ALL		1
++#define BRCMS_N_BW_20IN2G_40IN5G	2
++
++/* bitflags for SGI support (sgi_rx iovar) */
++#define BRCMS_N_SGI_20			0x01
++#define BRCMS_N_SGI_40			0x02
++
++/* defines used by the nrate iovar */
++/* MSC in use,indicates b0-6 holds an mcs */
++#define NRATE_MCS_INUSE			0x00000080
++/* rate/mcs value */
++#define NRATE_RATE_MASK			0x0000007f
++/* stf mode mask: siso, cdd, stbc, sdm */
++#define NRATE_STF_MASK			0x0000ff00
++/* stf mode shift */
++#define NRATE_STF_SHIFT			8
++/* bit indicate to override mcs only */
++#define NRATE_OVERRIDE_MCS_ONLY		0x40000000
++#define NRATE_SGI_MASK			0x00800000	/* sgi mode */
++#define NRATE_SGI_SHIFT			23		/* sgi mode */
++#define NRATE_LDPC_CODING		0x00400000	/* adv coding in use */
++#define NRATE_LDPC_SHIFT		22		/* ldpc shift */
++
++#define NRATE_STF_SISO			0		/* stf mode SISO */
++#define NRATE_STF_CDD			1		/* stf mode CDD */
++#define NRATE_STF_STBC			2		/* stf mode STBC */
++#define NRATE_STF_SDM			3		/* stf mode SDM */
++
++#define MAX_DMA_SEGS			4
++
++/* Max # of entries in Tx FIFO based on 4kb page size */
++#define NTXD				256
++/* Max # of entries in Rx FIFO based on 4kb page size */
++#define NRXD				256
++
++/* try to keep this # rbufs posted to the chip */
++#define NRXBUFPOST			32
++
++/* data msg txq hiwat mark */
++#define BRCMS_DATAHIWAT			50
++
++/* max # frames to process in brcms_c_recv() */
++#define RXBND				8
++/* max # tx status to process in wlc_txstatus() */
++#define TXSBND				8
++
++/* brcmu_format_flags() bit description structure */
++struct brcms_c_bit_desc {
++	u32 bit;
++	const char *name;
++};
++
++/*
++ * The following table lists the buffer memory allocated to xmt fifos in HW.
++ * the size is in units of 256bytes(one block), total size is HW dependent
++ * ucode has default fifo partition, sw can overwrite if necessary
++ *
++ * This is documented in twiki under the topic UcodeTxFifo. Please ensure
++ * the twiki is updated before making changes.
++ */
++
++/* Starting corerev for the fifo size table */
++#define XMTFIFOTBL_STARTREV	20
++
++struct d11init {
++	__le16 addr;
++	__le16 size;
++	__le32 value;
++};
++
++struct edcf_acparam {
++	u8 ACI;
++	u8 ECW;
++	u16 TXOP;
++} __packed;
++
++const u8 prio2fifo[NUMPRIO] = {
++	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
++	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
++	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
++	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
++	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
++	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
++	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
++	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
++};
++
++/* debug/trace */
++uint brcm_msg_level =
++#if defined(DEBUG)
++	LOG_ERROR_VAL;
++#else
++	0;
++#endif				/* DEBUG */
++
++/* TX FIFO number to WME/802.1E Access Category */
++static const u8 wme_fifo2ac[] = {
++	IEEE80211_AC_BK,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_VI,
++	IEEE80211_AC_VO,
++	IEEE80211_AC_BE,
++	IEEE80211_AC_BE
++};
++
++/* ieee80211 Access Category to TX FIFO number */
++static const u8 wme_ac2fifo[] = {
++	TX_AC_VO_FIFO,
++	TX_AC_VI_FIFO,
++	TX_AC_BE_FIFO,
++	TX_AC_BK_FIFO
++};
++
++/* 802.1D Priority to precedence queue mapping */
++const u8 wlc_prio2prec_map[] = {
++	_BRCMS_PREC_BE,		/* 0 BE - Best-effort */
++	_BRCMS_PREC_BK,		/* 1 BK - Background */
++	_BRCMS_PREC_NONE,		/* 2 None = - */
++	_BRCMS_PREC_EE,		/* 3 EE - Excellent-effort */
++	_BRCMS_PREC_CL,		/* 4 CL - Controlled Load */
++	_BRCMS_PREC_VI,		/* 5 Vi - Video */
++	_BRCMS_PREC_VO,		/* 6 Vo - Voice */
++	_BRCMS_PREC_NC,		/* 7 NC - Network Control */
++};
++
++static const u16 xmtfifo_sz[][NFIFO] = {
++	/* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++	/* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
++	{20, 192, 192, 21, 17, 5},
++	/* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
++	{9, 58, 22, 14, 14, 5},
++};
++
++#ifdef DEBUG
++static const char * const fifo_names[] = {
++	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
++#else
++static const char fifo_names[6][0];
++#endif
++
++#ifdef DEBUG
++/* pointer to most recently allocated wl/wlc */
++static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
++#endif
++
++/* Find basic rate for a given rate */
++static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec)
++{
++	if (is_mcs_rate(rspec))
++		return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK]
++		       .leg_ofdm];
++	return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK];
++}
++
++static u16 frametype(u32 rspec, u8 mimoframe)
++{
++	if (is_mcs_rate(rspec))
++		return mimoframe;
++	return is_cck_rate(rspec) ? FT_CCK : FT_OFDM;
++}
++
++/* currently the best mechanism for determining SIFS is the band in use */
++static u16 get_sifs(struct brcms_band *band)
++{
++	return band->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME :
++				 BPHY_SIFS_TIME;
++}
++
++/*
++ * Detect Card removed.
++ * Even checking an sbconfig register read will not false trigger when the core
++ * is in reset it breaks CF address mechanism. Accessing gphy phyversion will
++ * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible
++ * reg with fixed 0/1 pattern (some platforms return all 0).
++ * If clocks are present, call the sb routine which will figure out if the
++ * device is removed.
++ */
++static bool brcms_deviceremoved(struct brcms_c_info *wlc)
++{
++	u32 macctrl;
++
++	if (!wlc->hw->clk)
++		return ai_deviceremoved(wlc->hw->sih);
++	macctrl = bcma_read32(wlc->hw->d11core,
++			      D11REGOFFS(maccontrol));
++	return (macctrl & (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN;
++}
++
++/* sum the individual fifo tx pending packet counts */
++static s16 brcms_txpktpendtot(struct brcms_c_info *wlc)
++{
++	return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] +
++	       wlc->core->txpktpend[2] + wlc->core->txpktpend[3];
++}
++
++static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc)
++{
++	return wlc->pub->_nbands > 1 && !wlc->bandlocked;
++}
++
++static int brcms_chspec_bw(u16 chanspec)
++{
++	if (CHSPEC_IS40(chanspec))
++		return BRCMS_40_MHZ;
++	if (CHSPEC_IS20(chanspec))
++		return BRCMS_20_MHZ;
++
++	return BRCMS_10_MHZ;
++}
++
++static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg)
++{
++	if (cfg == NULL)
++		return;
++
++	kfree(cfg->current_bss);
++	kfree(cfg);
++}
++
++static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
++{
++	if (wlc == NULL)
++		return;
++
++	brcms_c_bsscfg_mfree(wlc->bsscfg);
++	kfree(wlc->pub);
++	kfree(wlc->modulecb);
++	kfree(wlc->default_bss);
++	kfree(wlc->protection);
++	kfree(wlc->stf);
++	kfree(wlc->bandstate[0]);
++	kfree(wlc->corestate->macstat_snapshot);
++	kfree(wlc->corestate);
++	kfree(wlc->hw->bandstate[0]);
++	kfree(wlc->hw);
++
++	/* free the wlc */
++	kfree(wlc);
++	wlc = NULL;
++}
++
++static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit)
++{
++	struct brcms_bss_cfg *cfg;
++
++	cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC);
++	if (cfg == NULL)
++		goto fail;
++
++	cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (cfg->current_bss == NULL)
++		goto fail;
++
++	return cfg;
++
++ fail:
++	brcms_c_bsscfg_mfree(cfg);
++	return NULL;
++}
++
++static struct brcms_c_info *
++brcms_c_attach_malloc(uint unit, uint *err, uint devid)
++{
++	struct brcms_c_info *wlc;
++
++	wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC);
++	if (wlc == NULL) {
++		*err = 1002;
++		goto fail;
++	}
++
++	/* allocate struct brcms_c_pub state structure */
++	wlc->pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC);
++	if (wlc->pub == NULL) {
++		*err = 1003;
++		goto fail;
++	}
++	wlc->pub->wlc = wlc;
++
++	/* allocate struct brcms_hardware state structure */
++
++	wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC);
++	if (wlc->hw == NULL) {
++		*err = 1005;
++		goto fail;
++	}
++	wlc->hw->wlc = wlc;
++
++	wlc->hw->bandstate[0] =
++		kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC);
++	if (wlc->hw->bandstate[0] == NULL) {
++		*err = 1006;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->hw->bandstate[i] = (struct brcms_hw_band *)
++			    ((unsigned long)wlc->hw->bandstate[0] +
++			     (sizeof(struct brcms_hw_band) * i));
++	}
++
++	wlc->modulecb =
++		kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC);
++	if (wlc->modulecb == NULL) {
++		*err = 1009;
++		goto fail;
++	}
++
++	wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC);
++	if (wlc->default_bss == NULL) {
++		*err = 1010;
++		goto fail;
++	}
++
++	wlc->bsscfg = brcms_c_bsscfg_malloc(unit);
++	if (wlc->bsscfg == NULL) {
++		*err = 1011;
++		goto fail;
++	}
++
++	wlc->protection = kzalloc(sizeof(struct brcms_protection),
++				  GFP_ATOMIC);
++	if (wlc->protection == NULL) {
++		*err = 1016;
++		goto fail;
++	}
++
++	wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC);
++	if (wlc->stf == NULL) {
++		*err = 1017;
++		goto fail;
++	}
++
++	wlc->bandstate[0] =
++		kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC);
++	if (wlc->bandstate[0] == NULL) {
++		*err = 1025;
++		goto fail;
++	} else {
++		int i;
++
++		for (i = 1; i < MAXBANDS; i++)
++			wlc->bandstate[i] = (struct brcms_band *)
++				((unsigned long)wlc->bandstate[0]
++				+ (sizeof(struct brcms_band)*i));
++	}
++
++	wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC);
++	if (wlc->corestate == NULL) {
++		*err = 1026;
++		goto fail;
++	}
++
++	wlc->corestate->macstat_snapshot =
++		kzalloc(sizeof(struct macstat), GFP_ATOMIC);
++	if (wlc->corestate->macstat_snapshot == NULL) {
++		*err = 1027;
++		goto fail;
++	}
++
++	return wlc;
++
++ fail:
++	brcms_c_detach_mfree(wlc);
++	return NULL;
++}
++
++/*
++ * Update the slot timing for standard 11b/g (20us slots)
++ * or shortslot 11g (9us slots)
++ * The PSM needs to be suspended for this call.
++ */
++static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw,
++					bool shortslot)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if (shortslot) {
++		/* 11g short slot: 11a timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0207);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
++	} else {
++		/* 11g long slot: 11b timing */
++		bcma_write16(core, D11REGOFFS(ifs_slot), 0x0212);
++		brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
++	}
++}
++
++/*
++ * calculate frame duration of a given rate and length, return
++ * time in usec unit
++ */
++static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec,
++				    u8 preamble_type, uint mac_len)
++{
++	uint nsyms, dur = 0, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	if (rate == 0) {
++		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
++			  wlc->pub->unit);
++		rate = BRCM_RATE_1M;
++	}
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
++		 wlc->pub->unit, ratespec, preamble_type, mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++
++		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		if (preamble_type == BRCMS_MM_PREAMBLE)
++			dur += PREN_MM_EXT;
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else if (is_ofdm_rate(rate)) {
++		dur = APHY_PREAMBLE_TIME;
++		dur += APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
++		nsyms =
++		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
++			 Ndps);
++		dur += APHY_SYMBOL_TIME * nsyms;
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur += DOT11_OFDM_SIGNAL_EXTENSION;
++	} else {
++		/*
++		 * calc # bits * 2 so factor of 2 in rate (1/2 mbps)
++		 * will divide out
++		 */
++		mac_len = mac_len * 8 * 2;
++		/* calc ceiling of bits/rate = microseconds of air time */
++		dur = (mac_len + rate - 1) / rate;
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur += BPHY_PLCP_SHORT_TIME;
++		else
++			dur += BPHY_PLCP_TIME;
++	}
++	return dur;
++}
++
++static void brcms_c_write_inits(struct brcms_hardware *wlc_hw,
++				const struct d11init *inits)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	int i;
++	uint offset;
++	u16 size;
++	u32 value;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) {
++		size = le16_to_cpu(inits[i].size);
++		offset = le16_to_cpu(inits[i].addr);
++		value = le32_to_cpu(inits[i].value);
++		if (size == 2)
++			bcma_write16(core, offset, value);
++		else if (size == 4)
++			bcma_write32(core, offset, value);
++		else
++			break;
++	}
++}
++
++static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs)
++{
++	u8 idx;
++	u16 addr[] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++
++	for (idx = 0; idx < MHFMAX; idx++)
++		brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]);
++}
++
++static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw)
++{
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	/* init microcode host flags */
++	brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs);
++
++	/* do band-specific ucode IHR, SHM, and SCR inits */
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		if (D11REV_IS(wlc_hw->corerev, 24)) {
++			if (BRCMS_ISLCNPHY(wlc_hw->band))
++				brcms_c_write_inits(wlc_hw,
++						    ucode->d11lcn0bsinitvals24);
++			else
++				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
++					  " core rev %d\n", __func__,
++					  wlc_hw->unit, wlc_hw->corerev);
++		} else {
++			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++				__func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 ioctl = bcma_aread32(core, BCMA_IOCTL) & ~m;
++
++	bcma_awrite32(core, BCMA_IOCTL, ioctl | v);
++}
++
++static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
++
++	wlc_hw->phyclk = clk;
++
++	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC | SICF_GMODE),
++				   (SICF_PRST | SICF_FGC));
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_PRST);
++		udelay(1);
++
++	} else {		/* take phy out of reset */
++
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_FGC), SICF_FGC);
++		udelay(1);
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++		udelay(1);
++
++	}
++}
++
++/* low-level band switch utility routine */
++static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		bandunit);
++
++	wlc_hw->band = wlc_hw->bandstate[bandunit];
++
++	/*
++	 * BMAC_NOTE:
++	 *   until we eliminate need for wlc->band refs in low level code
++	 */
++	wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
++
++	/* set gmode core flag */
++	if (wlc_hw->sbclk && !wlc_hw->noreset) {
++		u32 gmode = 0;
++
++		if (bandunit == 0)
++			gmode = SICF_GMODE;
++
++		brcms_b_core_ioctl(wlc_hw, SICF_GMODE, gmode);
++	}
++}
++
++/* switch to new band but leave it inactive */
++static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++	u32 macctrl;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	macctrl = bcma_read32(wlc_hw->d11core,
++			      D11REGOFFS(maccontrol));
++	WARN_ON((macctrl & MCTL_EN_MAC) != 0);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	brcms_b_core_phy_clk(wlc_hw, OFF);
++
++	brcms_c_setxband(wlc_hw, bandunit);
++
++	return macintmask;
++}
++
++/* process an individual struct tx_status */
++static bool
++brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
++{
++	struct sk_buff *p;
++	uint queue;
++	struct d11txh *txh;
++	struct scb *scb = NULL;
++	bool free_pdu;
++	int tx_rts, tx_frame_count, tx_rts_count;
++	uint totlen, supr_status;
++	bool lastframe;
++	struct ieee80211_hdr *h;
++	u16 mcl;
++	struct ieee80211_tx_info *tx_info;
++	struct ieee80211_tx_rate *txrate;
++	int i;
++
++	/* discard intermediate indications for ucode with one legitimate case:
++	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange,
++	 *   but the subsequent tx of DATA failed. so it will start rts/cts
++	 *   from the beginning (resetting the rts transmission count)
++	 */
++	if (!(txs->status & TX_STATUS_AMPDU)
++	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
++		BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
++		return false;
++	}
++
++	queue = txs->frameid & TXFID_QUEUE_MASK;
++	if (queue >= NFIFO) {
++		p = NULL;
++		goto fatal;
++	}
++
++	p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
++	if (p == NULL)
++		goto fatal;
++
++	txh = (struct d11txh *) (p->data);
++	mcl = le16_to_cpu(txh->MacTxControlLow);
++
++	if (txs->phyerr) {
++		if (brcm_msg_level & LOG_ERROR_VAL) {
++			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
++				  txs->phyerr, txh->MainRates);
++			brcms_c_print_txdesc(txh);
++		}
++		brcms_c_print_txstatus(txs);
++	}
++
++	if (txs->frameid != le16_to_cpu(txh->TxFrameID))
++		goto fatal;
++	tx_info = IEEE80211_SKB_CB(p);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	if (tx_info->control.sta)
++		scb = &wlc->pri_scb;
++
++	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++		brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
++		return false;
++	}
++
++	supr_status = txs->status & TX_STATUS_SUPR_MASK;
++	if (supr_status == TX_STATUS_SUPR_BADCH)
++		BCMMSG(wlc->wiphy,
++		       "%s: Pkt tx suppressed, possibly channel %d\n",
++		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
++
++	tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS;
++	tx_frame_count =
++	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
++	tx_rts_count =
++	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
++
++	lastframe = !ieee80211_has_morefrags(h->frame_control);
++
++	if (!lastframe) {
++		wiphy_err(wlc->wiphy, "Not last frame!\n");
++	} else {
++		/*
++		 * Set information to be consumed by Minstrel ht.
++		 *
++		 * The "fallback limit" is the number of tx attempts a given
++		 * MPDU is sent at the "primary" rate. Tx attempts beyond that
++		 * limit are sent at the "secondary" rate.
++		 * A 'short frame' does not exceed RTS treshold.
++		 */
++		u16 sfbl,	/* Short Frame Rate Fallback Limit */
++		    lfbl,	/* Long Frame Rate Fallback Limit */
++		    fbl;
++
++		if (queue < IEEE80211_NUM_ACS) {
++			sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_SFB);
++			lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],
++				      EDCF_LFB);
++		} else {
++			sfbl = wlc->SFBL;
++			lfbl = wlc->LFBL;
++		}
++
++		txrate = tx_info->status.rates;
++		if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
++			fbl = lfbl;
++		else
++			fbl = sfbl;
++
++		ieee80211_tx_info_clear_status(tx_info);
++
++		if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) {
++			/*
++			 * rate selection requested a fallback rate
++			 * and we used it
++			 */
++			txrate[0].count = fbl;
++			txrate[1].count = tx_frame_count - fbl;
++		} else {
++			/*
++			 * rate selection did not request fallback rate, or
++			 * we didn't need it
++			 */
++			txrate[0].count = tx_frame_count;
++			/*
++			 * rc80211_minstrel.c:minstrel_tx_status() expects
++			 * unused rates to be marked with idx = -1
++			 */
++			txrate[1].idx = -1;
++			txrate[1].count = 0;
++		}
++
++		/* clear the rest of the rates */
++		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
++			txrate[i].idx = -1;
++			txrate[i].count = 0;
++		}
++
++		if (txs->status & TX_STATUS_ACK_RCV)
++			tx_info->flags |= IEEE80211_TX_STAT_ACK;
++	}
++
++	totlen = p->len;
++	free_pdu = true;
++
++	brcms_c_txfifo_complete(wlc, queue, 1);
++
++	if (lastframe) {
++		/* remove PLCP & Broadcom tx descriptor header */
++		skb_pull(p, D11_PHY_HDR_LEN);
++		skb_pull(p, D11_TXH_LEN);
++		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
++	} else {
++		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
++			  "tx_status\n", __func__);
++	}
++
++	return false;
++
++ fatal:
++	if (p)
++		brcmu_pkt_buf_free_skb(p);
++
++	return true;
++
++}
++
++/* process tx completion events in BMAC
++ * Return true if more tx status need to be processed. false otherwise.
++ */
++static bool
++brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
++{
++	bool morepending = false;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	struct bcma_device *core;
++	struct tx_status txstatus, *txs;
++	u32 s1, s2;
++	uint n = 0;
++	/*
++	 * Param 'max_tx_num' indicates max. # tx status to process before
++	 * break out.
++	 */
++	uint max_tx_num = bound ? TXSBND : -1;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	txs = &txstatus;
++	core = wlc_hw->d11core;
++	*fatal = false;
++	s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	while (!(*fatal)
++	       && (s1 & TXS_V)) {
++
++		if (s1 == 0xffffffff) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
++				wlc_hw->unit, __func__);
++			return morepending;
++		}
++		s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
++
++		txs->status = s1 & TXS_STATUS_MASK;
++		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
++		txs->sequence = s2 & TXS_SEQ_MASK;
++		txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
++		txs->lasttxtime = 0;
++
++		*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
++
++		/* !give others some time to run! */
++		if (++n >= max_tx_num)
++			break;
++		s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
++	}
++
++	if (*fatal)
++		return 0;
++
++	if (n >= max_tx_num)
++		morepending = true;
++
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	return morepending;
++}
++
++static void brcms_c_tbtt(struct brcms_c_info *wlc)
++{
++	if (!wlc->bsscfg->BSS)
++		/*
++		 * DirFrmQ is now valid...defer setting until end
++		 * of ATIM window
++		 */
++		wlc->qvalid |= MCMD_DIRFRMQVAL;
++}
++
++/* set initial host flags value */
++static void
++brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	memset(mhfs, 0, MHFMAX * sizeof(u16));
++
++	mhfs[MHF2] |= mhf2_init;
++
++	/* prohibit use of slowclock on multifunction boards */
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		mhfs[MHF1] |= MHF1_FORCEFASTCLK;
++
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
++		mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
++		mhfs[MHF1] |= MHF1_IQSWAP_WAR;
++	}
++}
++
++static uint
++dmareg(uint direction, uint fifonum)
++{
++	if (direction == DMA_TX)
++		return offsetof(struct d11regs, fifo64regs[fifonum].dmaxmt);
++	return offsetof(struct d11regs, fifo64regs[fifonum].dmarcv);
++}
++
++static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme)
++{
++	uint i;
++	char name[8];
++	/*
++	 * ucode host flag 2 needed for pio mode, independent of band and fifo
++	 */
++	u16 pio_mhf2 = 0;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint unit = wlc_hw->unit;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	/* name and offsets for dma_attach */
++	snprintf(name, sizeof(name), "wl%d", unit);
++
++	if (wlc_hw->di[0] == NULL) {	/* Init FIFOs */
++		int dma_attach_err = 0;
++
++		/*
++		 * FIFO 0
++		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
++		 * RX: RX_FIFO (RX data packets)
++		 */
++		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   (wme ? dmareg(DMA_TX, 0) : 0),
++					   dmareg(DMA_RX, 0),
++					   (wme ? NTXD : 0), NRXD,
++					   RXBUFSZ, -1, NRXBUFPOST,
++					   BRCMS_HWRXOFF, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[0]);
++
++		/*
++		 * FIFO 1
++		 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
++		 *   (legacy) TX_DATA_FIFO (TX data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 1), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[1]);
++
++		/*
++		 * FIFO 2
++		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
++		 * RX: UNUSED
++		 */
++		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 2), 0,
++					   NTXD, 0, 0, -1, 0, 0,
++					   &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[2]);
++		/*
++		 * FIFO 3
++		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
++		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
++		 */
++		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core,
++					   dmareg(DMA_TX, 3),
++					   0, NTXD, 0, 0, -1,
++					   0, 0, &brcm_msg_level);
++		dma_attach_err |= (NULL == wlc_hw->di[3]);
++/* Cleaner to leave this as if with AP defined */
++
++		if (dma_attach_err) {
++			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
++				  "\n", unit);
++			return false;
++		}
++
++		/* get pointer to dma engine tx flow control variable */
++		for (i = 0; i < NFIFO; i++)
++			if (wlc_hw->di[i])
++				wlc_hw->txavail[i] =
++				    (uint *) dma_getvar(wlc_hw->di[i],
++							"&txavail");
++	}
++
++	/* initial ucode host flags */
++	brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
++
++	return true;
++}
++
++static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw)
++{
++	uint j;
++
++	for (j = 0; j < NFIFO; j++) {
++		if (wlc_hw->di[j]) {
++			dma_detach(wlc_hw->di[j]);
++			wlc_hw->di[j] = NULL;
++		}
++	}
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ *  BMAC_NOTES, move low out and resolve the dangling ones
++ */
++static void brcms_b_info_init(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	/* set default sw macintmask value */
++	wlc->defmacintmask = DEF_MACINTMASK;
++
++	/* various 802.11g modes */
++	wlc_hw->shortslot = false;
++
++	wlc_hw->SFBL = RETRY_SHORT_FB;
++	wlc_hw->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc_hw->SRL = RETRY_SHORT_DEF;
++	wlc_hw->LRL = RETRY_LONG_DEF;
++	wlc_hw->chanspec = ch20mhz_chspec(1);
++}
++
++static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw)
++{
++	/* delay before first read of ucode state */
++	udelay(40);
++
++	/* wait until ucode is no longer asleep */
++	SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) ==
++		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
++}
++
++/* control chip clock to save power, enable dynamic clock or force fast clock */
++static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, enum bcma_clkmode mode)
++{
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU) {
++		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock
++		 * on backplane, but mac core will still run on ALP(not HT) when
++		 * it enters powersave mode, which means the FCA bit may not be
++		 * set. Should wakeup mac if driver wants it to run on HT.
++		 */
++
++		if (wlc_hw->clk) {
++			if (mode == BCMA_CLKMODE_FAST) {
++				bcma_set32(wlc_hw->d11core,
++					   D11REGOFFS(clk_ctl_st),
++					   CCS_FORCEHT);
++
++				udelay(64);
++
++				SPINWAIT(
++				    ((bcma_read32(wlc_hw->d11core,
++				      D11REGOFFS(clk_ctl_st)) &
++				      CCS_HTAVAIL) == 0),
++				      PMU_MAX_TRANSITION_DLY);
++				WARN_ON(!(bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					CCS_HTAVAIL));
++			} else {
++				if ((ai_get_pmurev(wlc_hw->sih) == 0) &&
++				    (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st)) &
++					(CCS_FORCEHT | CCS_HTAREQ)))
++					SPINWAIT(
++					    ((bcma_read32(wlc_hw->d11core,
++					      offsetof(struct d11regs,
++						       clk_ctl_st)) &
++					      CCS_HTAVAIL) == 0),
++					      PMU_MAX_TRANSITION_DLY);
++				bcma_mask32(wlc_hw->d11core,
++					D11REGOFFS(clk_ctl_st),
++					~CCS_FORCEHT);
++			}
++		}
++		wlc_hw->forcefastclk = (mode == BCMA_CLKMODE_FAST);
++	} else {
++
++		/* old chips w/o PMU, force HT through cc,
++		 * then use FCA to verify mac is running fast clock
++		 */
++
++		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
++
++		/* check fast clock is available (if core is not in reset) */
++		if (wlc_hw->forcefastclk && wlc_hw->clk)
++			WARN_ON(!(bcma_aread32(wlc_hw->d11core, BCMA_IOST) &
++				  SISF_FCLKA));
++
++		/*
++		 * keep the ucode wake bit on if forcefastclk is on since we
++		 * do not want ucode to put us back to slow clock when it dozes
++		 * for PM mode. Code below matches the wake override bit with
++		 * current forcefastclk state. Only setting bit in wake_override
++		 * instead of waking ucode immediately since old code had this
++		 * behavior. Older code set wlc->forcefastclk but only had the
++		 * wake happen if the wakup_ucode work (protected by an up
++		 * check) was executed just below.
++		 */
++		if (wlc_hw->forcefastclk)
++			mboolset(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++		else
++			mboolclr(wlc_hw->wake_override,
++				 BRCMS_WAKE_OVERRIDE_FORCEFAST);
++	}
++}
++
++/* set or clear ucode host flag bits
++ * it has an optimization for no-change write
++ * it only writes through shared memory when the core has clock;
++ * pre-CLK changes should use wlc_write_mhf to get around the optimization
++ *
++ *
++ * bands values are: BRCM_BAND_AUTO <--- Current band only
++ *                   BRCM_BAND_5G   <--- 5G band only
++ *                   BRCM_BAND_2G   <--- 2G band only
++ *                   BRCM_BAND_ALL  <--- All bands
++ */
++void
++brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val,
++	     int bands)
++{
++	u16 save;
++	u16 addr[MHFMAX] = {
++		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
++		M_HOST_FLAGS5
++	};
++	struct brcms_hw_band *band;
++
++	if ((val & ~mask) || idx >= MHFMAX)
++		return; /* error condition */
++
++	switch (bands) {
++		/* Current band only or all bands,
++		 * then set the band to current band
++		 */
++	case BRCM_BAND_AUTO:
++	case BRCM_BAND_ALL:
++		band = wlc_hw->band;
++		break;
++	case BRCM_BAND_5G:
++		band = wlc_hw->bandstate[BAND_5G_INDEX];
++		break;
++	case BRCM_BAND_2G:
++		band = wlc_hw->bandstate[BAND_2G_INDEX];
++		break;
++	default:
++		band = NULL;	/* error condition */
++	}
++
++	if (band) {
++		save = band->mhfs[idx];
++		band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
++
++		/* optimization: only write through if changed, and
++		 * changed band is the current band
++		 */
++		if (wlc_hw->clk && (band->mhfs[idx] != save)
++		    && (band == wlc_hw->band))
++			brcms_b_write_shm(wlc_hw, addr[idx],
++					   (u16) band->mhfs[idx]);
++	}
++
++	if (bands == BRCM_BAND_ALL) {
++		wlc_hw->bandstate[0]->mhfs[idx] =
++		    (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
++		wlc_hw->bandstate[1]->mhfs[idx] =
++		    (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
++	}
++}
++
++/* set the maccontrol register to desired reset state and
++ * initialize the sw cache of the register
++ */
++static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw)
++{
++	/* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
++	wlc_hw->maccontrol = 0;
++	wlc_hw->suspended_fifos = 0;
++	wlc_hw->wake_override = 0;
++	wlc_hw->mute_override = 0;
++	brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
++}
++
++/*
++ * write the software state of maccontrol and
++ * overrides to the maccontrol register
++ */
++static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw)
++{
++	u32 maccontrol = wlc_hw->maccontrol;
++
++	/* OR in the wake bit if overridden */
++	if (wlc_hw->wake_override)
++		maccontrol |= MCTL_WAKE;
++
++	/* set AP and INFRA bits for mute if needed */
++	if (wlc_hw->mute_override) {
++		maccontrol &= ~(MCTL_AP);
++		maccontrol |= MCTL_INFRA;
++	}
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(maccontrol),
++		     maccontrol);
++}
++
++/* set or clear maccontrol bits */
++void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val)
++{
++	u32 maccontrol;
++	u32 new_maccontrol;
++
++	if (val & ~mask)
++		return; /* error condition */
++	maccontrol = wlc_hw->maccontrol;
++	new_maccontrol = (maccontrol & ~mask) | val;
++
++	/* if the new maccontrol value is the same as the old, nothing to do */
++	if (new_maccontrol == maccontrol)
++		return;
++
++	/* something changed, cache the new value */
++	wlc_hw->maccontrol = new_maccontrol;
++
++	/* write the new values with overrides applied */
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++				 u32 override_bit)
++{
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
++		mboolset(wlc_hw->wake_override, override_bit);
++		return;
++	}
++
++	mboolset(wlc_hw->wake_override, override_bit);
++
++	brcms_c_mctrl_write(wlc_hw);
++	brcms_b_wait_for_wake(wlc_hw);
++}
++
++void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++				   u32 override_bit)
++{
++	mboolclr(wlc_hw->wake_override, override_bit);
++
++	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* When driver needs ucode to stop beaconing, it has to make sure that
++ * MCTL_AP is clear and MCTL_INFRA is set
++ * Mode           MCTL_AP        MCTL_INFRA
++ * AP                1              1
++ * STA               0              1 <--- This will ensure no beacons
++ * IBSS              0              0
++ */
++static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw)
++{
++	wlc_hw->mute_override = 1;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/* Clear the override on AP and INFRA bits */
++static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->mute_override == 0)
++		return;
++
++	wlc_hw->mute_override = 0;
++
++	/* if maccontrol already has AP == 0 and INFRA == 1 without this
++	 * override, then there is no change to write
++	 */
++	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
++		return;
++
++	brcms_c_mctrl_write(wlc_hw);
++}
++
++/*
++ * Write a MAC address to the given match reg offset in the RXE match engine.
++ */
++static void
++brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset,
++		       const u8 *addr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 mac_l;
++	u16 mac_m;
++	u16 mac_h;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n",
++		 wlc_hw->unit);
++
++	mac_l = addr[0] | (addr[1] << 8);
++	mac_m = addr[2] | (addr[3] << 8);
++	mac_h = addr[4] | (addr[5] << 8);
++
++	/* enter the MAC addr into the RXE match registers */
++	bcma_write16(core, D11REGOFFS(rcm_ctl),
++		     RCM_INC_DATA | match_reg_offset);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_l);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_m);
++	bcma_write16(core, D11REGOFFS(rcm_mat_data), mac_h);
++}
++
++void
++brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len,
++			    void *buf)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 word;
++	__le32 word_le;
++	__be32 word_be;
++	bool be_bit;
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	bcma_write32(core, D11REGOFFS(tplatewrptr), offset);
++
++	/* if MCTL_BIGEND bit set in mac control register,
++	 * the chip swaps data in fifo, as well as data in
++	 * template ram
++	 */
++	be_bit = (bcma_read32(core, D11REGOFFS(maccontrol)) & MCTL_BIGEND) != 0;
++
++	while (len > 0) {
++		memcpy(&word, buf, sizeof(u32));
++
++		if (be_bit) {
++			word_be = cpu_to_be32(word);
++			word = *(u32 *)&word_be;
++		} else {
++			word_le = cpu_to_le32(word);
++			word = *(u32 *)&word_le;
++		}
++
++		bcma_write32(core, D11REGOFFS(tplatewrdata), word);
++
++		buf = (u8 *) buf + sizeof(u32);
++		len -= sizeof(u32);
++	}
++}
++
++static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin)
++{
++	wlc_hw->band->CWmin = newmin;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMIN);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmin);
++}
++
++static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax)
++{
++	wlc_hw->band->CWmax = newmax;
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_CWMAX);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), newmax);
++}
++
++void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw)
++{
++	bool fastclk;
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
++
++	brcms_b_phy_reset(wlc_hw);
++	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw)
++{
++	u16 v;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	/* update SYNTHPU_DLY */
++
++	if (BRCMS_ISLCNPHY(wlc->band))
++		v = SYNTHPU_DLY_LPPHY_US;
++	else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3)))
++		v = SYNTHPU_DLY_NPHY_US;
++	else
++		v = SYNTHPU_DLY_BPHY_US;
++
++	brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
++}
++
++static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw)
++{
++	u16 phyctl;
++	u16 phytxant = wlc_hw->bmac_phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* set the Probe Response frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
++
++	/* set the Response (ACK/CTS) frame phy control word */
++	phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
++}
++
++static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw,
++					 u8 rate)
++{
++	uint i;
++	u8 plcp_rate = 0;
++	struct plcp_signal_rate_lookup {
++		u8 rate;
++		u8 signal_rate;
++	};
++	/* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
++	const struct plcp_signal_rate_lookup rate_lookup[] = {
++		{BRCM_RATE_6M, 0xB},
++		{BRCM_RATE_9M, 0xF},
++		{BRCM_RATE_12M, 0xA},
++		{BRCM_RATE_18M, 0xE},
++		{BRCM_RATE_24M, 0x9},
++		{BRCM_RATE_36M, 0xD},
++		{BRCM_RATE_48M, 0x8},
++		{BRCM_RATE_54M, 0xC}
++	};
++
++	for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
++		if (rate == rate_lookup[i].rate) {
++			plcp_rate = rate_lookup[i].signal_rate;
++			break;
++		}
++	}
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
++}
++
++static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw)
++{
++	u8 rate;
++	u8 rates[8] = {
++		BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M,
++		BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M
++	};
++	u16 entry_ptr;
++	u16 pctl1;
++	uint i;
++
++	if (!BRCMS_PHY_11N_CAP(wlc_hw->band))
++		return;
++
++	/* walk the phy rate table and update the entries */
++	for (i = 0; i < ARRAY_SIZE(rates); i++) {
++		rate = rates[i];
++
++		entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate);
++
++		/* read the SHM Rate Table entry OFDM PCTL1 values */
++		pctl1 =
++		    brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
++
++		/* modify the value */
++		pctl1 &= ~PHY_TXC1_MODE_MASK;
++		pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
++
++		/* Update the SHM Rate Table entry OFDM PCTL1 values */
++		brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
++				   pctl1);
++	}
++}
++
++/* band-specific init */
++static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	brcms_c_ucode_bsinit(wlc_hw);
++
++	wlc_phy_init(wlc_hw->band->pi, chanspec);
++
++	brcms_c_ucode_txant_set(wlc_hw);
++
++	/*
++	 * cwmin is band-specific, update hardware
++	 * with value for current band
++	 */
++	brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
++	brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
++
++	brcms_b_update_slot_timing(wlc_hw,
++				   wlc_hw->band->bandtype == BRCM_BAND_5G ?
++				   true : wlc_hw->shortslot);
++
++	/* write phytype and phyvers */
++	brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
++	brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
++
++	/*
++	 * initialize the txphyctl1 rate table since
++	 * shmem is shared between bands
++	 */
++	brcms_upd_ofdm_pctl1_table(wlc_hw);
++
++	brcms_b_upd_synthpu(wlc_hw);
++}
++
++/* Perform a soft reset of the PHY PLL */
++void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr),
++		  ~0, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 4);
++	udelay(1);
++	ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_data),
++		  0x4, 0);
++	udelay(1);
++}
++
++/* light way to turn on phy clock without reset for NPHY only
++ *  refer to brcms_b_core_phy_clk for full version
++ */
++void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk)
++{
++	/* support(necessary for NPHY and HYPHY) only */
++	if (!BRCMS_ISNPHY(wlc_hw->band))
++		return;
++
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, SICF_FGC);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_FGC, 0);
++
++}
++
++void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk)
++{
++	if (ON == clk)
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, SICF_MPCLKE);
++	else
++		brcms_b_core_ioctl(wlc_hw, SICF_MPCLKE, 0);
++}
++
++void brcms_b_phy_reset(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_phy_pub *pih = wlc_hw->band->pi;
++	u32 phy_bw_clkbits;
++	bool phy_in_reset = false;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (pih == NULL)
++		return;
++
++	phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
++
++	/* Specific reset sequence required for NPHY rev 3 and 4 */
++	if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
++	    NREV_LE(wlc_hw->band->phyrev, 4)) {
++		/* Set the PHY bandwidth */
++		brcms_b_core_ioctl(wlc_hw, SICF_BWMASK, phy_bw_clkbits);
++
++		udelay(1);
++
++		/* Perform a soft reset of the PHY PLL */
++		brcms_b_core_phypll_reset(wlc_hw);
++
++		/* reset the PHY */
++		brcms_b_core_ioctl(wlc_hw, (SICF_PRST | SICF_PCLKE),
++				   (SICF_PRST | SICF_PCLKE));
++		phy_in_reset = true;
++	} else {
++		brcms_b_core_ioctl(wlc_hw,
++				   (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
++				   (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
++	}
++
++	udelay(2);
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	if (pih)
++		wlc_phy_anacore(pih, ON);
++}
++
++/* switch to and initialize new band */
++static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit,
++			    u16 chanspec) {
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++	u32 macintmask;
++
++	/* Enable the d11 core before accessing it */
++	if (!bcma_core_is_enabled(wlc_hw->d11core)) {
++		bcma_core_enable(wlc_hw->d11core, 0);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	macintmask = brcms_c_setband_inact(wlc, bandunit);
++
++	if (!wlc_hw->up)
++		return;
++
++	brcms_b_core_phy_clk(wlc_hw, ON);
++
++	/* band-specific initializations */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/*
++	 * If there are any pending software interrupt bits,
++	 * then replace these with a harmless nonzero value
++	 * so brcms_c_dpc() will re-enable interrupts when done.
++	 */
++	if (wlc->macintstatus)
++		wlc->macintstatus = MI_DMAINT;
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* ucode should still be suspended.. */
++	WARN_ON((bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)) &
++		 MCTL_EN_MAC) != 0);
++}
++
++static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw)
++{
++
++	/* reject unsupported corerev */
++	if (!CONF_HAS(D11CONF, wlc_hw->corerev)) {
++		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
++			  wlc_hw->corerev);
++		return false;
++	}
++
++	return true;
++}
++
++/* Validate some board info parameters */
++static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw)
++{
++	uint boardrev = wlc_hw->boardrev;
++
++	/* 4 bits each for board type, major, minor, and tiny version */
++	uint brt = (boardrev & 0xf000) >> 12;
++	uint b0 = (boardrev & 0xf00) >> 8;
++	uint b1 = (boardrev & 0xf0) >> 4;
++	uint b2 = boardrev & 0xf;
++
++	/* voards from other vendors are always considered valid */
++	if (ai_get_boardvendor(wlc_hw->sih) != PCI_VENDOR_ID_BROADCOM)
++		return true;
++
++	/* do some boardrev sanity checks when boardvendor is Broadcom */
++	if (boardrev == 0)
++		return false;
++
++	if (boardrev <= 0xff)
++		return true;
++
++	if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
++		|| (b2 > 9))
++		return false;
++
++	return true;
++}
++
++static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ALEN])
++{
++	struct ssb_sprom *sprom = &wlc_hw->d11core->bus->sprom;
++
++	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
++	if (!is_zero_ether_addr(sprom->il0mac)) {
++		memcpy(etheraddr, sprom->il0mac, 6);
++		return;
++	}
++
++	if (wlc_hw->_nbands > 1)
++		memcpy(etheraddr, sprom->et1mac, 6);
++	else
++		memcpy(etheraddr, sprom->il0mac, 6);
++}
++
++/* power both the pll and external oscillator on/off */
++static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
++
++	/*
++	 * dont power down if plldown is false or
++	 * we must poll hw radio disable
++	 */
++	if (!want && wlc_hw->pllreq)
++		return;
++
++	wlc_hw->sbclk = want;
++	if (!wlc_hw->sbclk) {
++		wlc_hw->clk = false;
++		if (wlc_hw->band && wlc_hw->band->pi)
++			wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++	}
++}
++
++/*
++ * Return true if radio is disabled, otherwise false.
++ * hw radio disable signal is an external pin, users activate it asynchronously
++ * this function could be called when driver is down and w/o clock
++ * it operates on different registers depending on corerev and boardflag.
++ */
++static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw)
++{
++	bool v, clk, xtal;
++	u32 flags = 0;
++
++	xtal = wlc_hw->sbclk;
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, ON);
++
++	/* may need to take core out of reset first */
++	clk = wlc_hw->clk;
++	if (!clk) {
++		/*
++		 * mac no longer enables phyclk automatically when driver
++		 * accesses phyreg throughput mac. This can be skipped since
++		 * only mac reg is accessed below
++		 */
++		flags |= SICF_PCLKE;
++
++		/*
++		 * TODO: test suspend/resume
++		 *
++		 * AI chip doesn't restore bar0win2 on
++		 * hibernation/resume, need sw fixup
++		 */
++
++		bcma_core_enable(wlc_hw->d11core, flags);
++		brcms_c_mctrl_reset(wlc_hw);
++	}
++
++	v = ((bcma_read32(wlc_hw->d11core,
++			  D11REGOFFS(phydebug)) & PDBG_RFD) != 0);
++
++	/* put core back into reset */
++	if (!clk)
++		bcma_core_disable(wlc_hw->d11core, 0);
++
++	if (!xtal)
++		brcms_b_xtal(wlc_hw, OFF);
++
++	return v;
++}
++
++static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo)
++{
++	struct dma_pub *di = wlc_hw->di[fifo];
++	return dma_rxreset(di);
++}
++
++/* d11 core reset
++ *   ensure fask clock during reset
++ *   reset dma
++ *   reset d11(out of reset)
++ *   reset phy(out of reset)
++ *   clear software macintstatus for fresh new start
++ * one testing hack wlc_hw->noreset will bypass the d11/phy reset
++ */
++void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags)
++{
++	uint i;
++	bool fastclk;
++
++	if (flags == BRCMS_USE_COREFLAGS)
++		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on  */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* reset the dma engines except first time thru */
++	if (bcma_core_is_enabled(wlc_hw->d11core)) {
++		for (i = 0; i < NFIFO; i++)
++			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i])))
++				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
++					  "dma_txreset[%d]: cannot stop dma\n",
++					   wlc_hw->unit, __func__, i);
++
++		if ((wlc_hw->di[RX_FIFO])
++		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO)))
++			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
++				  "[%d]: cannot stop dma\n",
++				  wlc_hw->unit, __func__, RX_FIFO);
++	}
++	/* if noreset, just stop the psm and return */
++	if (wlc_hw->noreset) {
++		wlc_hw->wlc->macintstatus = 0;	/* skip wl_dpc after down */
++		brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
++		return;
++	}
++
++	/*
++	 * mac no longer enables phyclk automatically when driver accesses
++	 * phyreg throughput mac, AND phy_reset is skipped at early stage when
++	 * band->pi is invalid. need to enable PHY CLK
++	 */
++	flags |= SICF_PCLKE;
++
++	/*
++	 * reset the core
++	 * In chips with PMU, the fastclk request goes through d11 core
++	 * reg 0x1e0, which is cleared by the core_reset. have to re-request it.
++	 *
++	 * This adds some delay and we can optimize it by also requesting
++	 * fastclk through chipcommon during this period if necessary. But
++	 * that has to work coordinate with other driver like mips/arm since
++	 * they may touch chipcommon as well.
++	 */
++	wlc_hw->clk = false;
++	bcma_core_enable(wlc_hw->d11core, flags);
++	wlc_hw->clk = true;
++	if (wlc_hw->band && wlc_hw->band->pi)
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
++
++	brcms_c_mctrl_reset(wlc_hw);
++
++	if (ai_get_cccaps(wlc_hw->sih) & CC_CAP_PMU)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	brcms_b_phy_reset(wlc_hw);
++
++	/* turn on PHY_PLL */
++	brcms_b_core_phypll_ctl(wlc_hw, true);
++
++	/* clear sw intstatus */
++	wlc_hw->wlc->macintstatus = 0;
++
++	/* restore the clk setting */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++/* txfifo sizes needs to be modified(increased) since the newer cores
++ * have more memory.
++ */
++static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 fifo_nu;
++	u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
++	u16 txfifo_def, txfifo_def1;
++	u16 txfifo_cmd;
++
++	/* tx fifos start at TXFIFO_START_BLK from the Base address */
++	txfifo_startblk = TXFIFO_START_BLK;
++
++	/* sequence of operations:  reset fifo, set fifo size, reset fifo */
++	for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
++
++		txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
++		txfifo_def = (txfifo_startblk & 0xff) |
++		    (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
++		    ((((txfifo_endblk -
++			1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
++		txfifo_cmd =
++		    TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++		bcma_write16(core, D11REGOFFS(xmtfifodef), txfifo_def);
++		bcma_write16(core, D11REGOFFS(xmtfifodef1), txfifo_def1);
++
++		bcma_write16(core, D11REGOFFS(xmtfifocmd), txfifo_cmd);
++
++		txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
++	}
++	/*
++	 * need to propagate to shm location to be in sync since ucode/hw won't
++	 * do this
++	 */
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE0,
++			   wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE1,
++			   wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE2,
++			   ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_AC_BK_FIFO]));
++	brcms_b_write_shm(wlc_hw, M_FIFOSIZE3,
++			   ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
++			    xmtfifo_sz[TX_BCMC_FIFO]));
++}
++
++/* This function is used for changing the tsf frac register
++ * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
++ * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
++ * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
++ * HTPHY Formula is 2^26/freq(MHz) e.g.
++ * For spuron2 - 126MHz -> 2^26/126 = 532610.0
++ *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
++ * For spuron: 123MHz -> 2^26/123    = 545600.5
++ *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
++ * For spur off: 120MHz -> 2^26/120    = 559240.5
++ *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
++ */
++
++void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43224_CHIP_ID) ||
++	    (ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID)) {
++		if (spurmode == WL_SPURAVOID_ON2) {	/* 126Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x2082);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else if (spurmode == WL_SPURAVOID_ON1) {	/* 123Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x5341);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		} else {	/* 120Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x8889);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0x8);
++		}
++	} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++		if (spurmode == WL_SPURAVOID_ON1) {	/* 82Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0x7CE0);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		} else {	/* 80Mhz */
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_l), 0xCCCD);
++			bcma_write16(core, D11REGOFFS(tsf_clk_frac_h), 0xC);
++		}
++	}
++}
++
++/* Initialize GPIOs that are controlled by D11 core */
++static void brcms_c_gpio_init(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 gc, gm;
++
++	/* use GPIO select 0 to get all gpio signals from the gpio out reg */
++	brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
++
++	/*
++	 * Common GPIO setup:
++	 *      G0 = LED 0 = WLAN Activity
++	 *      G1 = LED 1 = WLAN 2.4 GHz Radio State
++	 *      G2 = LED 2 = WLAN 5 GHz Radio State
++	 *      G4 = radio disable input (HI enabled, LO disabled)
++	 */
++
++	gc = gm = 0;
++
++	/* Allocate GPIOs for mimo antenna diversity feature */
++	if (wlc_hw->antsel_type == ANTSEL_2x3) {
++		/* Enable antenna diversity, use 2x3 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
++			     MHF3_ANTSEL_MODE, BRCM_BAND_ALL);
++
++		/* init superswitch control */
++		wlc_phy_antsel_init(wlc_hw->band->pi, false);
++
++	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
++		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
++		/*
++		 * The board itself is powered by these GPIOs
++		 * (when not sending pattern) so set them high
++		 */
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_oe),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++		bcma_set16(wlc_hw->d11core, D11REGOFFS(psm_gpio_out),
++			   (BOARD_GPIO_12 | BOARD_GPIO_13));
++
++		/* Enable antenna diversity, use 2x4 mode */
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
++			     MHF3_ANTSEL_EN, BRCM_BAND_ALL);
++		brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
++			     BRCM_BAND_ALL);
++
++		/* Configure the desired clock to be 4Mhz */
++		brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
++				   ANTSEL_CLKDIV_4MHZ);
++	}
++
++	/*
++	 * gpio 9 controls the PA. ucode is responsible
++	 * for wiggling out and oe
++	 */
++	if (wlc_hw->boardflags & BFL_PACTRL)
++		gm |= gc |= BOARD_GPIO_PACTRL;
++
++	/* apply to gpiocontrol register */
++	bcma_chipco_gpio_control(&wlc_hw->d11core->bus->drv_cc, gm, gc);
++}
++
++static void brcms_ucode_write(struct brcms_hardware *wlc_hw,
++			      const __le32 ucode[], const size_t nbytes)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	uint i;
++	uint count;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	count = (nbytes / sizeof(u32));
++
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_AUTO_INC | OBJADDR_UCM_SEL);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	for (i = 0; i < count; i++)
++		bcma_write32(core, D11REGOFFS(objdata), le32_to_cpu(ucode[i]));
++
++}
++
++static void brcms_ucode_download(struct brcms_hardware *wlc_hw)
++{
++	struct brcms_c_info *wlc;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	wlc = wlc_hw->wlc;
++
++	if (wlc_hw->ucode_loaded)
++		return;
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo,
++					  ucode->bcm43xx_16_mimosz);
++			wlc_hw->ucode_loaded = true;
++		} else
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			brcms_ucode_write(wlc_hw, ucode->bcm43xx_24_lcn,
++					  ucode->bcm43xx_24_lcnsz);
++			wlc_hw->ucode_loaded = true;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
++				  "corerev %d\n",
++				  __func__, wlc_hw->unit, wlc_hw->corerev);
++		}
++	}
++}
++
++void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant)
++{
++	/* update sw state */
++	wlc_hw->bmac_phytxant = phytxant;
++
++	/* push to ucode if up */
++	if (!wlc_hw->up)
++		return;
++	brcms_c_ucode_txant_set(wlc_hw);
++
++}
++
++u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw)
++{
++	return (u16) wlc_hw->wlc->stf->txant;
++}
++
++void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type)
++{
++	wlc_hw->antsel_type = antsel_type;
++
++	/* Update the antsel type for phy module to use */
++	wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
++}
++
++static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw)
++{
++	bool fatal = false;
++	uint unit;
++	uint intstatus, idx;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	unit = wlc_hw->unit;
++
++	for (idx = 0; idx < NFIFO; idx++) {
++		/* read intstatus register and ignore any non-error bits */
++		intstatus =
++			bcma_read32(core,
++				    D11REGOFFS(intctrlregs[idx].intstatus)) &
++			I_ERRORS;
++		if (!intstatus)
++			continue;
++
++		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
++			unit, idx, intstatus);
++
++		if (intstatus & I_RO) {
++			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
++				  "overflow\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PC) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
++				 unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_PD) {
++			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
++				  idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_DE) {
++			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
++				  "error\n", unit, idx);
++			fatal = true;
++		}
++
++		if (intstatus & I_RU)
++			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
++				  "underflow\n", idx, unit);
++
++		if (intstatus & I_XU) {
++			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
++				  "underflow\n", idx, unit);
++			fatal = true;
++		}
++
++		if (fatal) {
++			brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */
++			break;
++		} else
++			bcma_write32(core,
++				     D11REGOFFS(intctrlregs[idx].intstatus),
++				     intstatus);
++	}
++}
++
++void brcms_c_intrson(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	wlc->macintmask = wlc->defmacintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++u32 brcms_c_intrsoff(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintmask;
++
++	if (!wlc_hw->clk)
++		return 0;
++
++	macintmask = wlc->macintmask;	/* isr can still happen */
++
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(macintmask));
++	udelay(1);		/* ensure int line is no longer driven */
++	wlc->macintmask = 0;
++
++	/* return previous macintmask; resolve race between us and our isr */
++	return wlc->macintstatus ? 0 : macintmask;
++}
++
++void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	if (!wlc_hw->clk)
++		return;
++
++	wlc->macintmask = macintmask;
++	bcma_write32(wlc_hw->d11core, D11REGOFFS(macintmask), wlc->macintmask);
++}
++
++/* assumes that the d11 MAC is enabled */
++static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
++				    uint tx_fifo)
++{
++	u8 fifo = 1 << tx_fifo;
++
++	/* Two clients of this code, 11h Quiet period and scanning. */
++
++	/* only suspend if not already suspended */
++	if ((wlc_hw->suspended_fifos & fifo) == fifo)
++		return;
++
++	/* force the core awake only if not already */
++	if (wlc_hw->suspended_fifos == 0)
++		brcms_c_ucode_wake_override_set(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++
++	wlc_hw->suspended_fifos |= fifo;
++
++	if (wlc_hw->di[tx_fifo]) {
++		/*
++		 * Suspending AMPDU transmissions in the middle can cause
++		 * underflow which may result in mismatch between ucode and
++		 * driver so suspend the mac before suspending the FIFO
++		 */
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++
++		dma_txsuspend(wlc_hw->di[tx_fifo]);
++
++		if (BRCMS_PHY_11N_CAP(wlc_hw->band))
++			brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
++				   uint tx_fifo)
++{
++	/* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case
++	 * but need to be done here for PIO otherwise the watchdog will catch
++	 * the inconsistency and fire
++	 */
++	/* Two clients of this code, 11h Quiet period and scanning. */
++	if (wlc_hw->di[tx_fifo])
++		dma_txresume(wlc_hw->di[tx_fifo]);
++
++	/* allow core to sleep again */
++	if (wlc_hw->suspended_fifos == 0)
++		return;
++	else {
++		wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
++		if (wlc_hw->suspended_fifos == 0)
++			brcms_c_ucode_wake_override_clear(wlc_hw,
++						BRCMS_WAKE_OVERRIDE_TXFIFO);
++	}
++}
++
++/* precondition: requires the mac core to be enabled */
++static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
++{
++	static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
++
++	if (mute_tx) {
++		/* suspend tx fifos */
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
++
++		/* zero the address match register so we do not send ACKs */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       null_ether_addr);
++	} else {
++		/* resume tx fifos */
++		brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
++		brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
++
++		/* Restore address */
++		brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
++				       wlc_hw->etheraddr);
++	}
++
++	wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
++
++	if (mute_tx)
++		brcms_c_ucode_mute_override_set(wlc_hw);
++	else
++		brcms_c_ucode_mute_override_clear(wlc_hw);
++}
++
++void
++brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
++{
++	brcms_b_mute(wlc->hw, mute_tx);
++}
++
++/*
++ * Read and clear macintmask and macintstatus and intstatus registers.
++ * This routine should be called with interrupts off
++ * Return:
++ *   -1 if brcms_deviceremoved(wlc) evaluates to true;
++ *   0 if the interrupt is not for us, or we are in some special cases;
++ *   device interrupt status bits otherwise.
++ */
++static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 macintstatus;
++
++	/* macintstatus includes a DMA interrupt summary bit */
++	macintstatus = bcma_read32(core, D11REGOFFS(macintstatus));
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
++		 macintstatus);
++
++	/* detect cardbus removed, in power down(suspend) and in reset */
++	if (brcms_deviceremoved(wlc))
++		return -1;
++
++	/* brcms_deviceremoved() succeeds even when the core is still resetting,
++	 * handle that case here.
++	 */
++	if (macintstatus == 0xffffffff)
++		return 0;
++
++	/* defer unsolicited interrupts */
++	macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
++
++	/* if not for us */
++	if (macintstatus == 0)
++		return 0;
++
++	/* interrupts are already turned off for CFE build
++	 * Caution: For CFE Turning off the interrupts again has some undesired
++	 * consequences
++	 */
++	/* turn off the interrupts */
++	bcma_write32(core, D11REGOFFS(macintmask), 0);
++	(void)bcma_read32(core, D11REGOFFS(macintmask));
++	wlc->macintmask = 0;
++
++	/* clear device interrupts */
++	bcma_write32(core, D11REGOFFS(macintstatus), macintstatus);
++
++	/* MI_DMAINT is indication of non-zero intstatus */
++	if (macintstatus & MI_DMAINT)
++		/*
++		 * only fifo interrupt enabled is I_RI in
++		 * RX_FIFO. If MI_DMAINT is set, assume it
++		 * is set and clear the interrupt.
++		 */
++		bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intstatus),
++			     DEF_RXINTMASK);
++
++	return macintstatus;
++}
++
++/* Update wlc->macintstatus and wlc->intstatus[]. */
++/* Return true if they are updated successfully. false otherwise */
++bool brcms_c_intrsupd(struct brcms_c_info *wlc)
++{
++	u32 macintstatus;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, false);
++
++	/* device is removed */
++	if (macintstatus == 0xffffffff)
++		return false;
++
++	/* update interrupt status in software */
++	wlc->macintstatus |= macintstatus;
++
++	return true;
++}
++
++/*
++ * First-level interrupt processing.
++ * Return true if this was our interrupt, false otherwise.
++ * *wantdpc will be set to true if further brcms_c_dpc() processing is required,
++ * false otherwise.
++ */
++bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	u32 macintstatus;
++
++	*wantdpc = false;
++
++	if (!wlc_hw->up || !wlc->macintmask)
++		return false;
++
++	/* read and clear macintstatus and intstatus registers */
++	macintstatus = wlc_intstatus(wlc, true);
++
++	if (macintstatus == 0xffffffff)
++		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
++			  " path\n");
++
++	/* it is not for us */
++	if (macintstatus == 0)
++		return false;
++
++	*wantdpc = true;
++
++	/* save interrupt status bits */
++	wlc->macintstatus = macintstatus;
++
++	return true;
++
++}
++
++void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc_hw->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth++;
++	if (wlc_hw->mac_suspend_depth > 1)
++		return;
++
++	/* force the core awake */
++	brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(!(mc & MCTL_EN_MAC));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	if (mi == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0);
++
++	SPINWAIT(!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD),
++		 BRCMS_MAX_MAC_SUSPEND);
++
++	if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) {
++		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
++			  " and MI_MACSSPNDD is still not on.\n",
++			  wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND);
++		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
++			  "psm_brc 0x%04x\n", wlc_hw->unit,
++			  bcma_read32(core, D11REGOFFS(psmdebug)),
++			  bcma_read32(core, D11REGOFFS(phydebug)),
++			  bcma_read16(core, D11REGOFFS(psm_brc)));
++	}
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	if (mc == 0xffffffff) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++	WARN_ON(mc & MCTL_EN_MAC);
++}
++
++void brcms_c_enable_mac(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 mc, mi;
++
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
++		wlc->band->bandunit);
++
++	/*
++	 * Track overlapping suspend requests
++	 */
++	wlc_hw->mac_suspend_depth--;
++	if (wlc_hw->mac_suspend_depth > 0)
++		return;
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(mc & MCTL_EN_MAC);
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_MACSSPNDD);
++
++	mc = bcma_read32(core, D11REGOFFS(maccontrol));
++	WARN_ON(mc & MCTL_PSM_JMP_0);
++	WARN_ON(!(mc & MCTL_EN_MAC));
++	WARN_ON(!(mc & MCTL_PSM_RUN));
++
++	mi = bcma_read32(core, D11REGOFFS(macintstatus));
++	WARN_ON(mi & MI_MACSSPNDD);
++
++	brcms_c_ucode_wake_override_clear(wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++}
++
++void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode)
++{
++	wlc_hw->hw_stf_ss_opmode = stf_mode;
++
++	if (wlc_hw->clk)
++		brcms_upd_ofdm_pctl1_table(wlc_hw);
++}
++
++static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 w, val;
++	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
++
++	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* Validate dchip register access */
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	w = bcma_read32(core, D11REGOFFS(objdata));
++
++	/* Can we write and read back a 32bit register? */
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0xaa5555aa);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0xaa5555aa) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), (u32) 0x55aaaa55);
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	val = bcma_read32(core, D11REGOFFS(objdata));
++	if (val != (u32) 0x55aaaa55) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
++			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
++		return false;
++	}
++
++	bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), w);
++
++	/* clear CFPStart */
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), 0);
++
++	w = bcma_read32(core, D11REGOFFS(maccontrol));
++	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
++	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
++		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
++			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
++			  (MCTL_IHR_EN | MCTL_WAKE),
++			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
++		return false;
++	}
++
++	return true;
++}
++
++#define PHYPLL_WAIT_US	100000
++
++void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 tmp;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	tmp = 0;
++
++	if (on) {
++		if ((ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   CCS_ERSRC_REQ_HT |
++				   CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT,
++				 PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT)
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
++					  " PLL failed\n", __func__);
++		} else {
++			bcma_set32(core, D11REGOFFS(clk_ctl_st),
++				   tmp | CCS_ERSRC_REQ_D11PLL |
++				   CCS_ERSRC_REQ_PHYPLL);
++			SPINWAIT((bcma_read32(core, D11REGOFFS(clk_ctl_st)) &
++				  (CCS_ERSRC_AVAIL_D11PLL |
++				   CCS_ERSRC_AVAIL_PHYPLL)) !=
++				 (CCS_ERSRC_AVAIL_D11PLL |
++				  CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
++
++			tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st));
++			if ((tmp &
++			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++			    !=
++			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
++				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
++					  "PHY PLL failed\n", __func__);
++		}
++	} else {
++		/*
++		 * Since the PLL may be shared, other cores can still
++		 * be requesting it; so we'll deassert the request but
++		 * not wait for status to comply.
++		 */
++		bcma_mask32(core, D11REGOFFS(clk_ctl_st),
++			    ~CCS_ERSRC_REQ_PHYPLL);
++		(void)bcma_read32(core, D11REGOFFS(clk_ctl_st));
++	}
++}
++
++static void brcms_c_coredisable(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone)
++		return;
++
++	if (wlc_hw->noreset)
++		return;
++
++	/* radio off */
++	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
++
++	/* turn off analog core */
++	wlc_phy_anacore(wlc_hw->band->pi, OFF);
++
++	/* turn off PHYPLL to save power */
++	brcms_b_core_phypll_ctl(wlc_hw, false);
++
++	wlc_hw->clk = false;
++	bcma_core_disable(wlc_hw->d11core, 0);
++	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++}
++
++static void brcms_c_flushqueues(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	uint i;
++
++	/* free any posted tx packets */
++	for (i = 0; i < NFIFO; i++)
++		if (wlc_hw->di[i]) {
++			dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL);
++			wlc->core->txpktpend[i] = 0;
++			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
++		}
++
++	/* free any posted rx packets */
++	dma_rxreclaim(wlc_hw->di[RX_FIFO]);
++}
++
++static u16
++brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	return bcma_read16(core, objoff);
++}
++
++static void
++brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v,
++		     u32 sel)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++	u16 objoff = D11REGOFFS(objdata);
++
++	bcma_write32(core, D11REGOFFS(objaddr), sel | (offset >> 2));
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	if (offset & 2)
++		objoff += 2;
++
++	bcma_write16(core, objoff, v);
++}
++
++/*
++ * Read a single u16 from shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset)
++{
++	return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Write a single u16 to shared memory.
++ * SHM 'offset' needs to be an even address
++ */
++void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v)
++{
++	brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
++}
++
++/*
++ * Copy a buffer to shared memory of specified type .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset,
++		      const void *buf, int len, u32 sel)
++{
++	u16 v;
++	const u8 *p = (const u8 *)buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = p[i] | (p[i + 1] << 8);
++		brcms_b_write_objmem(wlc_hw, offset + i, v, sel);
++	}
++}
++
++/*
++ * Copy a piece of shared memory of specified type to a buffer .
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ * 'sel' selects the type of memory
++ */
++void
++brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf,
++			 int len, u32 sel)
++{
++	u16 v;
++	u8 *p = (u8 *) buf;
++	int i;
++
++	if (len <= 0 || (offset & 1) || (len & 1))
++		return;
++
++	for (i = 0; i < len; i += 2) {
++		v = brcms_b_read_objmem(wlc_hw, offset + i, sel);
++		p[i] = v & 0xFF;
++		p[i + 1] = (v >> 8) & 0xFF;
++	}
++}
++
++/* Copy a buffer to shared memory.
++ * SHM 'offset' needs to be an even address and
++ * Buffer length 'len' must be an even number of bytes
++ */
++static void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset,
++			const void *buf, int len)
++{
++	brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
++}
++
++static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw,
++				   u16 SRL, u16 LRL)
++{
++	wlc_hw->SRL = SRL;
++	wlc_hw->LRL = LRL;
++
++	/* write retry limit to SCR, shouldn't need to suspend */
++	if (wlc_hw->up) {
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->SRL);
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objaddr),
++			     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++		(void)bcma_read32(wlc_hw->d11core, D11REGOFFS(objaddr));
++		bcma_write32(wlc_hw->d11core, D11REGOFFS(objdata), wlc_hw->LRL);
++	}
++}
++
++static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit)
++{
++	if (set) {
++		if (mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolset(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (!wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, ON);
++		}
++	} else {
++		if (!mboolisset(wlc_hw->pllreq, req_bit))
++			return;
++
++		mboolclr(wlc_hw->pllreq, req_bit);
++
++		if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) {
++			if (wlc_hw->sbclk)
++				brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++}
++
++static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail)
++{
++	wlc_hw->antsel_avail = antsel_avail;
++}
++
++/*
++ * conditions under which the PM bit should be set in outgoing frames
++ * and STAY_AWAKE is meaningful
++ */
++static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *cfg = wlc->bsscfg;
++
++	/* disallow PS when one of the following global conditions meets */
++	if (!wlc->pub->associated)
++		return false;
++
++	/* disallow PS when one of these meets when not scanning */
++	if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
++		return false;
++
++	if (cfg->associated) {
++		/*
++		 * disallow PS when one of the following
++		 * bsscfg specific conditions meets
++		 */
++		if (!cfg->BSS)
++			return false;
++
++		return false;
++	}
++
++	return true;
++}
++
++static void brcms_c_statsupd(struct brcms_c_info *wlc)
++{
++	int i;
++	struct macstat macstats;
++#ifdef DEBUG
++	u16 delta;
++	u16 rxf0ovfl;
++	u16 txfunfl[NFIFO];
++#endif				/* DEBUG */
++
++	/* if driver down, make no sense to update stats */
++	if (!wlc->pub->up)
++		return;
++
++#ifdef DEBUG
++	/* save last rx fifo 0 overflow count */
++	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
++
++	/* save last tx fifo  underflow count */
++	for (i = 0; i < NFIFO; i++)
++		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
++#endif				/* DEBUG */
++
++	/* Read mac stats from contiguous shared memory */
++	brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
++				sizeof(struct macstat), OBJADDR_SHM_SEL);
++
++#ifdef DEBUG
++	/* check for rx fifo 0 overflow */
++	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
++	if (delta)
++		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
++			  wlc->pub->unit, delta);
++
++	/* check for tx fifo underflows */
++	for (i = 0; i < NFIFO; i++) {
++		delta =
++		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
++			      txfunfl[i]);
++		if (delta)
++			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
++				  "\n", wlc->pub->unit, delta, i);
++	}
++#endif				/* DEBUG */
++
++	/* merge counters from dma module */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc->hw->di[i])
++			dma_counterreset(wlc->hw->di[i]);
++	}
++}
++
++static void brcms_b_reset(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset the core */
++	if (!brcms_deviceremoved(wlc_hw->wlc))
++		brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	/* purge the dma rings */
++	brcms_c_flushqueues(wlc_hw->wlc);
++}
++
++void brcms_c_reset(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* slurp up hw mac counters before core reset */
++	brcms_c_statsupd(wlc);
++
++	/* reset our snapshot of macstat counters */
++	memset((char *)wlc->core->macstat_snapshot, 0,
++		sizeof(struct macstat));
++
++	brcms_b_reset(wlc->hw);
++}
++
++/* Return the channel the driver should initialize during brcms_c_init.
++ * the channel may have to be changed from the currently configured channel
++ * if other configurations are in conflict (bandlocked, 11n mode disabled,
++ * invalid channel for current country, etc.)
++ */
++static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
++{
++	u16 chanspec =
++	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
++	    WL_CHANSPEC_BAND_2G;
++
++	return chanspec;
++}
++
++void brcms_c_init_scb(struct scb *scb)
++{
++	int i;
++
++	memset(scb, 0, sizeof(struct scb));
++	scb->flags = SCB_WMECAP | SCB_HTCAP;
++	for (i = 0; i < NUMPRIO; i++) {
++		scb->seqnum[i] = 0;
++		scb->seqctl[i] = 0xFFFF;
++	}
++
++	scb->seqctl_nonqos = 0xFFFF;
++	scb->magic = SCB_MAGIC;
++}
++
++/* d11 core init
++ *   reset PSM
++ *   download ucode/PCM
++ *   let ucode run to suspended
++ *   download ucode inits
++ *   config other core registers
++ *   init dma
++ */
++static void brcms_b_coreinit(struct brcms_c_info *wlc)
++{
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	u32 sflags;
++	u32 bcnint_us;
++	uint i = 0;
++	bool fifosz_fixup = false;
++	int err = 0;
++	u16 buf[NFIFO];
++	struct wiphy *wiphy = wlc->wiphy;
++	struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* reset PSM */
++	brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
++
++	brcms_ucode_download(wlc_hw);
++	/*
++	 * FIFOSZ fixup. driver wants to controls the fifo allocation.
++	 */
++	fifosz_fixup = true;
++
++	/* let the PSM run to the suspended state, set mode to BSS STA */
++	bcma_write32(core, D11REGOFFS(macintstatus), -1);
++	brcms_b_mctrl(wlc_hw, ~0,
++		       (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
++
++	/* wait for ucode to self-suspend after auto-init */
++	SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) &
++		   MI_MACSSPNDD) == 0), 1000 * 1000);
++	if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0)
++		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
++			  "suspend!\n", wlc_hw->unit);
++
++	brcms_c_gpio_init(wlc);
++
++	sflags = bcma_aread32(core, BCMA_IOST);
++
++	if (D11REV_IS(wlc_hw->corerev, 23)) {
++		if (BRCMS_ISNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
++		if (BRCMS_ISLCNPHY(wlc_hw->band))
++			brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24);
++		else
++			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
++				  " %d\n", __func__, wlc_hw->unit,
++				  wlc_hw->corerev);
++	} else {
++		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
++			  __func__, wlc_hw->unit, wlc_hw->corerev);
++	}
++
++	/* For old ucode, txfifo sizes needs to be modified(increased) */
++	if (fifosz_fixup)
++		brcms_b_corerev_fifofixup(wlc_hw);
++
++	/* check txfifo allocations match between ucode and driver */
++	buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0);
++	if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
++		i = TX_AC_BE_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1);
++	if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
++		i = TX_AC_VI_FIFO;
++		err = -1;
++	}
++	buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2);
++	buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
++	buf[TX_AC_BK_FIFO] &= 0xff;
++	if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
++		i = TX_AC_BK_FIFO;
++		err = -1;
++	}
++	if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
++		i = TX_AC_VO_FIFO;
++		err = -1;
++	}
++	buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3);
++	buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
++	buf[TX_BCMC_FIFO] &= 0xff;
++	if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
++		i = TX_BCMC_FIFO;
++		err = -1;
++	}
++	if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
++		i = TX_ATIM_FIFO;
++		err = -1;
++	}
++	if (err != 0)
++		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
++			  " driver size %d index %d\n", buf[i],
++			  wlc_hw->xmtfifo_sz[i], i);
++
++	/* make sure we can still talk to the mac */
++	WARN_ON(bcma_read32(core, D11REGOFFS(maccontrol)) == 0xffffffff);
++
++	/* band-specific inits done by wlc_bsinit() */
++
++	/* Set up frame burst size and antenna swap threshold init values */
++	brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
++	brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
++
++	/* enable one rx interrupt per received frame */
++	bcma_write32(core, D11REGOFFS(intrcvlazy[0]), (1 << IRL_FC_SHIFT));
++
++	/* set the station mode (BSS STA) */
++	brcms_b_mctrl(wlc_hw,
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
++		       (MCTL_INFRA | MCTL_DISCARD_PMQ));
++
++	/* set up Beacon interval */
++	bcnint_us = 0x8000 << 10;
++	bcma_write32(core, D11REGOFFS(tsf_cfprep),
++		     (bcnint_us << CFPREP_CBI_SHIFT));
++	bcma_write32(core, D11REGOFFS(tsf_cfpstart), bcnint_us);
++	bcma_write32(core, D11REGOFFS(macintstatus), MI_GP1);
++
++	/* write interrupt mask */
++	bcma_write32(core, D11REGOFFS(intctrlregs[RX_FIFO].intmask),
++		     DEF_RXINTMASK);
++
++	/* allow the MAC to control the PHY clock (dynamic on/off) */
++	brcms_b_macphyclk_set(wlc_hw, ON);
++
++	/* program dynamic clock control fast powerup delay register */
++	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
++	bcma_write16(core, D11REGOFFS(scc_fastpwrup_dly), wlc->fastpwrup_dly);
++
++	/* tell the ucode the corerev */
++	brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
++
++	/* tell the ucode MAC capabilities */
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L,
++			   (u16) (wlc_hw->machwcap & 0xffff));
++	brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H,
++			   (u16) ((wlc_hw->
++				      machwcap >> 16) & 0xffff));
++
++	/* write retry limits to SCR, this done after PSM init */
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->SRL);
++	bcma_write32(core, D11REGOFFS(objaddr),
++		     OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
++	(void)bcma_read32(core, D11REGOFFS(objaddr));
++	bcma_write32(core, D11REGOFFS(objdata), wlc_hw->LRL);
++
++	/* write rate fallback retry limits */
++	brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
++	brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
++
++	bcma_mask16(core, D11REGOFFS(ifs_ctl), 0x0FFF);
++	bcma_write16(core, D11REGOFFS(ifs_aifsn), EDCF_AIFSN_MIN);
++
++	/* init the tx dma engines */
++	for (i = 0; i < NFIFO; i++) {
++		if (wlc_hw->di[i])
++			dma_txinit(wlc_hw->di[i]);
++	}
++
++	/* init the rx dma engine(s) and post receive buffers */
++	dma_rxinit(wlc_hw->di[RX_FIFO]);
++	dma_rxfill(wlc_hw->di[RX_FIFO]);
++}
++
++void
++static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
++	u32 macintmask;
++	bool fastclk;
++	struct brcms_c_info *wlc = wlc_hw->wlc;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/* request FAST clock if not on */
++	fastclk = wlc_hw->forcefastclk;
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/* disable interrupts */
++	macintmask = brcms_intrsoff(wlc->wl);
++
++	/* set up the specified band and chanspec */
++	brcms_c_setxband(wlc_hw, chspec_bandunit(chanspec));
++	wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++
++	/* do one-time phy inits and calibration */
++	wlc_phy_cal_init(wlc_hw->band->pi);
++
++	/* core-specific initialization */
++	brcms_b_coreinit(wlc);
++
++	/* band-specific inits */
++	brcms_b_bsinit(wlc, chanspec);
++
++	/* restore macintmask */
++	brcms_intrsrestore(wlc->wl, macintmask);
++
++	/* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac
++	 * is suspended and brcms_c_enable_mac() will clear this override bit.
++	 */
++	mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND);
++
++	/*
++	 * initialize mac_suspend_depth to 1 to match ucode
++	 * initial suspended state
++	 */
++	wlc_hw->mac_suspend_depth = 1;
++
++	/* restore the clk */
++	if (!fastclk)
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++}
++
++static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	/* Save our copy of the chanspec */
++	wlc->chanspec = chanspec;
++
++	/* Set the chanspec and power limits for this locale */
++	brcms_c_channel_set_chanspec(wlc->cmi, chanspec, BRCMS_TXPWR_MAX);
++
++	if (wlc->stf->ss_algosel_auto)
++		brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
++					    chanspec);
++
++	brcms_c_stf_ss_update(wlc, wlc->band);
++}
++
++static void
++brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs)
++{
++	brcms_c_rateset_default(rs, NULL, wlc->band->phytype,
++		wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(wlc->default_bss->chanspec),
++		wlc->stf->txstreams);
++}
++
++/* derive wlc->band->basic_rate[] table from 'rateset' */
++static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc,
++			      struct brcms_c_rateset *rateset)
++{
++	u8 rate;
++	u8 mandatory;
++	u8 cck_basic = 0;
++	u8 ofdm_basic = 0;
++	u8 *br = wlc->band->basic_rate;
++	uint i;
++
++	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
++	memset(br, 0, BRCM_MAXRATE + 1);
++
++	/* For each basic rate in the rates list, make an entry in the
++	 * best basic lookup.
++	 */
++	for (i = 0; i < rateset->count; i++) {
++		/* only make an entry for a basic rate */
++		if (!(rateset->rates[i] & BRCMS_RATE_FLAG))
++			continue;
++
++		/* mask off basic bit */
++		rate = (rateset->rates[i] & BRCMS_RATE_MASK);
++
++		if (rate > BRCM_MAXRATE) {
++			wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: "
++				  "invalid rate 0x%X in rate set\n",
++				  rateset->rates[i]);
++			continue;
++		}
++
++		br[rate] = rate;
++	}
++
++	/* The rate lookup table now has non-zero entries for each
++	 * basic rate, equal to the basic rate: br[basicN] = basicN
++	 *
++	 * To look up the best basic rate corresponding to any
++	 * particular rate, code can use the basic_rate table
++	 * like this
++	 *
++	 * basic_rate = wlc->band->basic_rate[tx_rate]
++	 *
++	 * Make sure there is a best basic rate entry for
++	 * every rate by walking up the table from low rates
++	 * to high, filling in holes in the lookup table
++	 */
++
++	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
++		rate = wlc->band->hw_rateset.rates[i];
++
++		if (br[rate] != 0) {
++			/* This rate is a basic rate.
++			 * Keep track of the best basic rate so far by
++			 * modulation type.
++			 */
++			if (is_ofdm_rate(rate))
++				ofdm_basic = rate;
++			else
++				cck_basic = rate;
++
++			continue;
++		}
++
++		/* This rate is not a basic rate so figure out the
++		 * best basic rate less than this rate and fill in
++		 * the hole in the table
++		 */
++
++		br[rate] = is_ofdm_rate(rate) ? ofdm_basic : cck_basic;
++
++		if (br[rate] != 0)
++			continue;
++
++		if (is_ofdm_rate(rate)) {
++			/*
++			 * In 11g and 11a, the OFDM mandatory rates
++			 * are 6, 12, and 24 Mbps
++			 */
++			if (rate >= BRCM_RATE_24M)
++				mandatory = BRCM_RATE_24M;
++			else if (rate >= BRCM_RATE_12M)
++				mandatory = BRCM_RATE_12M;
++			else
++				mandatory = BRCM_RATE_6M;
++		} else {
++			/* In 11b, all CCK rates are mandatory 1 - 11 Mbps */
++			mandatory = rate;
++		}
++
++		br[rate] = mandatory;
++	}
++}
++
++static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
++				     u16 chanspec)
++{
++	struct brcms_c_rateset default_rateset;
++	uint parkband;
++	uint i, band_order[2];
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++	/*
++	 * We might have been bandlocked during down and the chip
++	 * power-cycled (hibernate). Figure out the right band to park on
++	 */
++	if (wlc->bandlocked || wlc->pub->_nbands == 1) {
++		/* updated in brcms_c_bandlock() */
++		parkband = wlc->band->bandunit;
++		band_order[0] = band_order[1] = parkband;
++	} else {
++		/* park on the band of the specified chanspec */
++		parkband = chspec_bandunit(chanspec);
++
++		/* order so that parkband initialize last */
++		band_order[0] = parkband ^ 1;
++		band_order[1] = parkband;
++	}
++
++	/* make each band operational, software state init */
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		uint j = band_order[i];
++
++		wlc->band = wlc->bandstate[j];
++
++		brcms_default_rateset(wlc, &default_rateset);
++
++		/* fill in hw_rate */
++		brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
++				   false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++
++		/* init basic rate lookup */
++		brcms_c_rate_lookup_init(wlc, &default_rateset);
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++}
++
++/*
++ * Set or clear filtering related maccontrol bits based on
++ * specified filter flags
++ */
++void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
++{
++	u32 promisc_bits = 0;
++
++	wlc->filter_flags = filter_flags;
++
++	if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
++		promisc_bits |= MCTL_PROMISC;
++
++	if (filter_flags & FIF_BCN_PRBRESP_PROMISC)
++		promisc_bits |= MCTL_BCNS_PROMISC;
++
++	if (filter_flags & FIF_FCSFAIL)
++		promisc_bits |= MCTL_KEEPBADFCS;
++
++	if (filter_flags & (FIF_CONTROL | FIF_PSPOLL))
++		promisc_bits |= MCTL_KEEPCONTROL;
++
++	brcms_b_mctrl(wlc->hw,
++		MCTL_PROMISC | MCTL_BCNS_PROMISC |
++		MCTL_KEEPCONTROL | MCTL_KEEPBADFCS,
++		promisc_bits);
++}
++
++/*
++ * ucode, hwmac update
++ *    Channel dependent updates for ucode and hw
++ */
++static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
++{
++	/* enable or disable any active IBSSs depending on whether or not
++	 * we are on the home channel
++	 */
++	if (wlc->home_chanspec == wlc_phy_chanspec_get(wlc->band->pi)) {
++		if (wlc->pub->associated) {
++			/*
++			 * BMAC_NOTE: This is something that should be fixed
++			 * in ucode inits. I think that the ucode inits set
++			 * up the bcn templates and shm values with a bogus
++			 * beacon. This should not be done in the inits. If
++			 * ucode needs to set up a beacon for testing, the
++			 * test routines should write it down, not expect the
++			 * inits to populate a bogus beacon.
++			 */
++			if (BRCMS_PHY_11N_CAP(wlc->band))
++				brcms_b_write_shm(wlc->hw,
++						M_BCN_TXTSF_OFFSET, 0);
++		}
++	} else {
++		/* disable an active IBSS if we are not on the home channel */
++	}
++}
++
++static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
++				   u8 basic_rate)
++{
++	u8 phy_rate, index;
++	u8 basic_phy_rate, basic_index;
++	u16 dir_table, basic_table;
++	u16 basic_ptr;
++
++	/* Shared memory address for the table we are reading */
++	dir_table = is_ofdm_rate(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
++
++	/* Shared memory address for the table we are writing */
++	basic_table = is_ofdm_rate(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
++
++	/*
++	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++	basic_index = basic_phy_rate & 0xf;
++
++	/* Find the SHM pointer to the ACK rate entry by looking in the
++	 * Direct-map Table
++	 */
++	basic_ptr = brcms_b_read_shm(wlc->hw, (dir_table + basic_index * 2));
++
++	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
++	 * to the correct basic rate for the given incoming rate
++	 */
++	brcms_b_write_shm(wlc->hw, (basic_table + index * 2), basic_ptr);
++}
++
++static const struct brcms_c_rateset *
++brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (wlc->band->bandtype == BRCM_BAND_5G)
++			rs_dflt = &ofdm_mimo_rates;
++		else
++			rs_dflt = &cck_ofdm_mimo_rates;
++	} else if (wlc->band->gmode)
++		rs_dflt = &cck_ofdm_rates;
++	else
++		rs_dflt = &cck_rates;
++
++	return rs_dflt;
++}
++
++static void brcms_c_set_ratetable(struct brcms_c_info *wlc)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate, basic_rate;
++	uint i;
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/* walk the phy rate table and update SHM basic rate lookup table */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		/* for a given rate brcms_basic_rate returns the rate at
++		 * which a response ACK/CTS should be sent.
++		 */
++		basic_rate = brcms_basic_rate(wlc, rate);
++		if (basic_rate == 0)
++			/* This should only happen if we are using a
++			 * restricted rateset.
++			 */
++			basic_rate = rs.rates[0] & BRCMS_RATE_MASK;
++
++		brcms_c_write_rate_shm(wlc, rate, basic_rate);
++	}
++}
++
++/* band-specific init */
++static void brcms_c_bsinit(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
++		 wlc->pub->unit, wlc->band->bandunit);
++
++	/* write ucode ACK/CTS rate table */
++	brcms_c_set_ratetable(wlc);
++
++	/* update some band specific mac configuration */
++	brcms_c_ucode_mac_upd(wlc);
++
++	/* init antenna selection */
++	brcms_c_antsel_init(wlc->asi);
++
++}
++
++/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
++static int
++brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM,
++		   bool writeToShm)
++{
++	int idle_busy_ratio_x_16 = 0;
++	uint offset =
++	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
++	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
++	if (duty_cycle > 100 || duty_cycle < 0) {
++		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
++			  wlc->pub->unit);
++		return -EINVAL;
++	}
++	if (duty_cycle)
++		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
++	/* Only write to shared memory  when wl is up */
++	if (writeToShm)
++		brcms_b_write_shm(wlc->hw, offset, (u16) idle_busy_ratio_x_16);
++
++	if (isOFDM)
++		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
++	else
++		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
++
++	return 0;
++}
++
++/*
++ * Initialize the base precedence map for dequeueing
++ * from txq based on WME settings
++ */
++static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc)
++{
++	wlc->tx_prec_map = BRCMS_PREC_BMP_ALL;
++	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
++
++	wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK;
++	wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE;
++	wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI;
++	wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO;
++}
++
++static void
++brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi, bool on, int prio)
++{
++	/* transmit flowcontrol is not yet implemented */
++}
++
++static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi;
++
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
++		if (qi->stopped) {
++			brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
++			qi->stopped = 0;
++		}
++	}
++}
++
++/* push sw hps and wake state through hardware */
++static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc)
++{
++	u32 v1, v2;
++	bool hps;
++	bool awake_before;
++
++	hps = brcms_c_ps_allowed(wlc);
++
++	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
++
++	v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol));
++	v2 = MCTL_WAKE;
++	if (hps)
++		v2 |= MCTL_HPS;
++
++	brcms_b_mctrl(wlc->hw, MCTL_WAKE | MCTL_HPS, v2);
++
++	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
++
++	if (!awake_before)
++		brcms_b_wait_for_wake(wlc->hw);
++}
++
++/*
++ * Write this BSS config's MAC address to core.
++ * Updates RXE match engine.
++ */
++static int brcms_c_set_mac(struct brcms_bss_cfg *bsscfg)
++{
++	int err = 0;
++	struct brcms_c_info *wlc = bsscfg->wlc;
++
++	/* enter the MAC addr into the RXE match registers */
++	brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr);
++
++	brcms_c_ampdu_macaddr_upd(wlc);
++
++	return err;
++}
++
++/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
++ * Updates RXE match engine.
++ */
++static void brcms_c_set_bssid(struct brcms_bss_cfg *bsscfg)
++{
++	/* we need to update BSSID in RXE match registers */
++	brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID);
++}
++
++static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot)
++{
++	wlc_hw->shortslot = shortslot;
++
++	if (wlc_hw->band->bandtype == BRCM_BAND_2G && wlc_hw->up) {
++		brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++		brcms_b_update_slot_timing(wlc_hw, shortslot);
++		brcms_c_enable_mac(wlc_hw->wlc);
++	}
++}
++
++/*
++ * Suspend the the MAC and update the slot timing
++ * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
++ */
++static void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot)
++{
++	/* use the override if it is set */
++	if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO)
++		shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON);
++
++	if (wlc->shortslot == shortslot)
++		return;
++
++	wlc->shortslot = shortslot;
++
++	brcms_b_set_shortslot(wlc->hw, shortslot);
++}
++
++static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	if (wlc->home_chanspec != chanspec) {
++		wlc->home_chanspec = chanspec;
++
++		if (wlc->bsscfg->associated)
++			wlc->bsscfg->current_bss->chanspec = chanspec;
++	}
++}
++
++void
++brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
++		      bool mute_tx, struct txpwr_limits *txpwr)
++{
++	uint bandunit;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
++
++	wlc_hw->chanspec = chanspec;
++
++	/* Switch bands if necessary */
++	if (wlc_hw->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc_hw->band->bandunit != bandunit) {
++			/* brcms_b_setband disables other bandunit,
++			 *  use light band switch if not up yet
++			 */
++			if (wlc_hw->up) {
++				wlc_phy_chanspec_radio_set(wlc_hw->
++							   bandstate[bandunit]->
++							   pi, chanspec);
++				brcms_b_setband(wlc_hw, bandunit, chanspec);
++			} else {
++				brcms_c_setxband(wlc_hw, bandunit);
++			}
++		}
++	}
++
++	wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx);
++
++	if (!wlc_hw->up) {
++		if (wlc_hw->clk)
++			wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
++						  chanspec);
++		wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
++	} else {
++		wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
++		wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
++
++		/* Update muting of the channel */
++		brcms_b_mute(wlc_hw, mute_tx);
++	}
++}
++
++/* switch to and initialize new band */
++static void brcms_c_setband(struct brcms_c_info *wlc,
++					   uint bandunit)
++{
++	wlc->band = wlc->bandstate[bandunit];
++
++	if (!wlc->pub->up)
++		return;
++
++	/* wait for at least one beacon before entering sleeping state */
++	brcms_c_set_ps_ctrl(wlc);
++
++	/* band-specific initializations */
++	brcms_c_bsinit(wlc);
++}
++
++static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec)
++{
++	uint bandunit;
++	bool switchband = false;
++	u16 old_chanspec = wlc->chanspec;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
++			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
++		return;
++	}
++
++	/* Switch bands if necessary */
++	if (wlc->pub->_nbands > 1) {
++		bandunit = chspec_bandunit(chanspec);
++		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
++			switchband = true;
++			if (wlc->bandlocked) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
++					  "band is locked!\n",
++					  wlc->pub->unit, __func__,
++					  CHSPEC_CHANNEL(chanspec));
++				return;
++			}
++			/*
++			 * should the setband call come after the
++			 * brcms_b_chanspec() ? if the setband updates
++			 * (brcms_c_bsinit) use low level calls to inspect and
++			 * set state, the state inspected may be from the wrong
++			 * band, or the following brcms_b_set_chanspec() may
++			 * undo the work.
++			 */
++			brcms_c_setband(wlc, bandunit);
++		}
++	}
++
++	/* sync up phy/radio chanspec */
++	brcms_c_set_phy_chanspec(wlc, chanspec);
++
++	/* init antenna selection */
++	if (brcms_chspec_bw(old_chanspec) != brcms_chspec_bw(chanspec)) {
++		brcms_c_antsel_init(wlc->asi);
++
++		/* Fix the hardware rateset based on bw.
++		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
++		 */
++		brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
++			wlc->band->mimo_cap_40 ? brcms_chspec_bw(chanspec) : 0);
++	}
++
++	/* update some mac configuration since chanspec changed */
++	brcms_c_ucode_mac_upd(wlc);
++}
++
++/*
++ * This function changes the phytxctl for beacon based on current
++ * beacon ratespec AND txant setting as per this table:
++ *  ratespec     CCK		ant = wlc->stf->txant
++ *		OFDM		ant = 3
++ */
++void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++				       u32 bcn_rspec)
++{
++	u16 phyctl;
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_PHY_11N_CAP(wlc->band))
++		phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec);
++
++	phyctl = brcms_b_read_shm(wlc->hw, M_BCN_PCTLWD);
++	phyctl = (phyctl & ~mask) | phytxant;
++	brcms_b_write_shm(wlc->hw, M_BCN_PCTLWD, phyctl);
++}
++
++/*
++ * centralized protection config change function to simplify debugging, no
++ * consistency checking this should be called only on changes to avoid overhead
++ * in periodic function
++ */
++void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val)
++{
++	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
++
++	switch (idx) {
++	case BRCMS_PROT_G_SPEC:
++		wlc->protection->_g = (bool) val;
++		break;
++	case BRCMS_PROT_G_OVR:
++		wlc->protection->g_override = (s8) val;
++		break;
++	case BRCMS_PROT_G_USER:
++		wlc->protection->gmode_user = (u8) val;
++		break;
++	case BRCMS_PROT_OVERLAP:
++		wlc->protection->overlap = (s8) val;
++		break;
++	case BRCMS_PROT_N_USER:
++		wlc->protection->nmode_user = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG:
++		wlc->protection->n_cfg = (s8) val;
++		break;
++	case BRCMS_PROT_N_CFG_OVR:
++		wlc->protection->n_cfg_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_NONGF:
++		wlc->protection->nongf = (bool) val;
++		break;
++	case BRCMS_PROT_N_NONGF_OVR:
++		wlc->protection->nongf_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_PAM_OVR:
++		wlc->protection->n_pam_override = (s8) val;
++		break;
++	case BRCMS_PROT_N_OBSS:
++		wlc->protection->n_obss = (bool) val;
++		break;
++
++	default:
++		break;
++	}
++
++}
++
++static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val)
++{
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val)
++{
++	wlc->stf->ldpc = val;
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
++	}
++}
++
++void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++		       const struct ieee80211_tx_queue_params *params,
++		       bool suspend)
++{
++	int i;
++	struct shm_acparams acp_shm;
++	u16 *shm_entry;
++
++	/* Only apply params if the core is out of reset and has clocks */
++	if (!wlc->clk) {
++		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
++			  __func__);
++		return;
++	}
++
++	memset((char *)&acp_shm, 0, sizeof(struct shm_acparams));
++	/* fill in shm ac params struct */
++	acp_shm.txop = params->txop;
++	/* convert from units of 32us to us for ucode */
++	wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
++	    EDCF_TXOP2USEC(acp_shm.txop);
++	acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
++
++	if (aci == IEEE80211_AC_VI && acp_shm.txop == 0
++	    && acp_shm.aifs < EDCF_AIFSN_MAX)
++		acp_shm.aifs++;
++
++	if (acp_shm.aifs < EDCF_AIFSN_MIN
++	    || acp_shm.aifs > EDCF_AIFSN_MAX) {
++		wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad "
++			  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
++	} else {
++		acp_shm.cwmin = params->cw_min;
++		acp_shm.cwmax = params->cw_max;
++		acp_shm.cwcur = acp_shm.cwmin;
++		acp_shm.bslots =
++			bcma_read16(wlc->hw->d11core, D11REGOFFS(tsf_random)) &
++			acp_shm.cwcur;
++		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
++		/* Indicate the new params to the ucode */
++		acp_shm.status = brcms_b_read_shm(wlc->hw, (M_EDCF_QINFO +
++						  wme_ac2fifo[aci] *
++						  M_EDCF_QLEN +
++						  M_EDCF_STATUS_OFF));
++		acp_shm.status |= WME_STATUS_NEWAC;
++
++		/* Fill in shm acparam table */
++		shm_entry = (u16 *) &acp_shm;
++		for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2)
++			brcms_b_write_shm(wlc->hw,
++					  M_EDCF_QINFO +
++					  wme_ac2fifo[aci] * M_EDCF_QLEN + i,
++					  *shm_entry++);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
++{
++	u16 aci;
++	int i_ac;
++	struct ieee80211_tx_queue_params txq_pars;
++	static const struct edcf_acparam default_edcf_acparams[] = {
++		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, EDCF_AC_BE_TXOP_STA},
++		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, EDCF_AC_BK_TXOP_STA},
++		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, EDCF_AC_VI_TXOP_STA},
++		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, EDCF_AC_VO_TXOP_STA}
++	}; /* ucode needs these parameters during its initialization */
++	const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];
++
++	for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) {
++		/* find out which ac this set of params applies to */
++		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
++
++		/* fill in shm ac params struct */
++		txq_pars.txop = edcf_acp->TXOP;
++		txq_pars.aifs = edcf_acp->ACI;
++
++		/* CWmin = 2^(ECWmin) - 1 */
++		txq_pars.cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
++		/* CWmax = 2^(ECWmax) - 1 */
++		txq_pars.cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
++					    >> EDCF_ECWMAX_SHIFT);
++		brcms_c_wme_setparams(wlc, aci, &txq_pars, suspend);
++	}
++
++	if (suspend) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_enable_mac(wlc);
++	}
++}
++
++static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
++{
++	/* Don't start the timer if HWRADIO feature is disabled */
++	if (wlc->radio_monitor)
++		return;
++
++	wlc->radio_monitor = true;
++	brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_RADIO_MON);
++	brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
++}
++
++static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
++{
++	if (!wlc->radio_monitor)
++		return true;
++
++	wlc->radio_monitor = false;
++	brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_RADIO_MON);
++	return brcms_del_timer(wlc->radio_timer);
++}
++
++/* read hwdisable state and propagate to wlc flag */
++static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
++{
++	if (wlc->pub->hw_off)
++		return;
++
++	if (brcms_b_radio_read_hwdisabled(wlc->hw))
++		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++	else
++		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
++}
++
++/* update hwradio status and return it */
++bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
++{
++	brcms_c_radio_hwdisable_upd(wlc);
++
++	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ?
++			true : false;
++}
++
++/* periodical query hw radio button while driver is "down" */
++static void brcms_c_radio_timer(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			__func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	brcms_c_radio_hwdisable_upd(wlc);
++}
++
++/* common low-level watchdog code */
++static void brcms_b_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return;
++
++	/* increment second count */
++	wlc_hw->now++;
++
++	/* Check for FIFO error interrupts */
++	brcms_b_fifoerrors(wlc_hw);
++
++	/* make sure RX dma has buffers */
++	dma_rxfill(wlc->hw->di[RX_FIFO]);
++
++	wlc_phy_watchdog(wlc_hw->band->pi);
++}
++
++/* common watchdog code */
++static void brcms_c_watchdog(void *arg)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) arg;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	if (!wlc->pub->up)
++		return;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return;
++	}
++
++	/* increment second count */
++	wlc->pub->now++;
++
++	brcms_c_radio_hwdisable_upd(wlc);
++	/* if radio is disable, driver may be down, quit here */
++	if (wlc->pub->radio_disabled)
++		return;
++
++	brcms_b_watchdog(wlc);
++
++	/*
++	 * occasionally sample mac stat counters to
++	 * detect 16-bit counter wrap
++	 */
++	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
++		brcms_c_statsupd(wlc);
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
++	     BRCMS_TEMPSENSE_PERIOD)) {
++		wlc->tempsense_lasttime = wlc->pub->now;
++		brcms_c_tempsense_upd(wlc);
++	}
++}
++
++static void brcms_c_watchdog_by_timer(void *arg)
++{
++	brcms_c_watchdog(arg);
++}
++
++static bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit)
++{
++	wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer,
++		wlc, "watchdog");
++	if (!wlc->wdtimer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer,
++		wlc, "radio");
++	if (!wlc->radio_timer) {
++		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
++			  "failed\n", unit);
++		goto fail;
++	}
++
++	return true;
++
++ fail:
++	return false;
++}
++
++/*
++ * Initialize brcms_c_info default values ...
++ * may get overrides later in this function
++ */
++static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
++{
++	int i;
++
++	/* Save our copy of the chanspec */
++	wlc->chanspec = ch20mhz_chspec(1);
++
++	/* various 802.11g modes */
++	wlc->shortslot = false;
++	wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR,
++			       BRCMS_PROTECTION_AUTO);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false);
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO);
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP,
++			       BRCMS_PROTECTION_CTL_OVERLAP);
++
++	/* 802.11g draft 4.0 NonERP elt advertisement */
++	wlc->include_legacy_erp = true;
++
++	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
++	wlc->stf->txant = ANT_TX_DEF;
++
++	wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT;
++
++	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
++	for (i = 0; i < NFIFO; i++)
++		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
++	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
++
++	/* default rate fallback retry limits */
++	wlc->SFBL = RETRY_SHORT_FB;
++	wlc->LFBL = RETRY_LONG_FB;
++
++	/* default mac retry limits */
++	wlc->SRL = RETRY_SHORT_DEF;
++	wlc->LRL = RETRY_LONG_DEF;
++
++	/* WME QoS mode is Auto by default */
++	wlc->pub->_ampdu = AMPDU_AGG_HOST;
++	wlc->pub->bcmerror = 0;
++}
++
++static uint brcms_c_attach_module(struct brcms_c_info *wlc)
++{
++	uint err = 0;
++	uint unit;
++	unit = wlc->pub->unit;
++
++	wlc->asi = brcms_c_antsel_attach(wlc);
++	if (wlc->asi == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach "
++			  "failed\n", unit);
++		err = 44;
++		goto fail;
++	}
++
++	wlc->ampdu = brcms_c_ampdu_attach(wlc);
++	if (wlc->ampdu == NULL) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach "
++			  "failed\n", unit);
++		err = 50;
++		goto fail;
++	}
++
++	if ((brcms_c_stf_attach(wlc) != 0)) {
++		wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach "
++			  "failed\n", unit);
++		err = 68;
++		goto fail;
++	}
++ fail:
++	return err;
++}
++
++struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc)
++{
++	return wlc->pub;
++}
++
++/* low level attach
++ *    run backplane attach, init nvram
++ *    run phy attach
++ *    initialize software state for each core and band
++ *    put the whole chip in reset(driver down state), no clock
++ */
++static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
++			  uint unit, bool piomode)
++{
++	struct brcms_hardware *wlc_hw;
++	uint err = 0;
++	uint j;
++	bool wme = false;
++	struct shared_phy_params sha_params;
++	struct wiphy *wiphy = wlc->wiphy;
++	struct pci_dev *pcidev = core->bus->host_pci;
++	struct ssb_sprom *sprom = &core->bus->sprom;
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI)
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       pcidev->vendor,
++		       pcidev->device);
++	else
++		BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit,
++		       core->bus->boardinfo.vendor,
++		       core->bus->boardinfo.type);
++
++	wme = true;
++
++	wlc_hw = wlc->hw;
++	wlc_hw->wlc = wlc;
++	wlc_hw->unit = unit;
++	wlc_hw->band = wlc_hw->bandstate[0];
++	wlc_hw->_piomode = piomode;
++
++	/* populate struct brcms_hardware with default values  */
++	brcms_b_info_init(wlc_hw);
++
++	/*
++	 * Do the hardware portion of the attach. Also initialize software
++	 * state that depends on the particular hardware we are running.
++	 */
++	wlc_hw->sih = ai_attach(core->bus);
++	if (wlc_hw->sih == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n",
++			  unit);
++		err = 11;
++		goto fail;
++	}
++
++	/* verify again the device is supported */
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI &&
++	    !brcms_c_chipmatch(pcidev->vendor, pcidev->device)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported "
++			"vendor/device (0x%x/0x%x)\n",
++			 unit, pcidev->vendor, pcidev->device);
++		err = 12;
++		goto fail;
++	}
++
++	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
++		wlc_hw->vendorid = pcidev->vendor;
++		wlc_hw->deviceid = pcidev->device;
++	} else {
++		wlc_hw->vendorid = core->bus->boardinfo.vendor;
++		wlc_hw->deviceid = core->bus->boardinfo.type;
++	}
++
++	wlc_hw->d11core = core;
++	wlc_hw->corerev = core->id.rev;
++
++	/* validate chip, chiprev and corerev */
++	if (!brcms_c_isgoodchip(wlc_hw)) {
++		err = 13;
++		goto fail;
++	}
++
++	/* initialize power control registers */
++	ai_clkctl_init(wlc_hw->sih);
++
++	/* request fastclock and force fastclock for the rest of attach
++	 * bring the d11 core out of reset.
++	 *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk
++	 *   is still false; But it will be called again inside wlc_corereset,
++	 *   after d11 is out of reset.
++	 */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	if (!brcms_b_validate_chip_access(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access "
++			"failed\n", unit);
++		err = 14;
++		goto fail;
++	}
++
++	/* get the board rev, used just below */
++	j = sprom->board_rev;
++	/* promote srom boardrev of 0xFF to 1 */
++	if (j == BOARDREV_PROMOTABLE)
++		j = BOARDREV_PROMOTED;
++	wlc_hw->boardrev = (u16) j;
++	if (!brcms_c_validboardtype(wlc_hw)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom "
++			  "board type (0x%x)" " or revision level (0x%x)\n",
++			  unit, ai_get_boardtype(wlc_hw->sih),
++			  wlc_hw->boardrev);
++		err = 15;
++		goto fail;
++	}
++	wlc_hw->sromrev = sprom->revision;
++	wlc_hw->boardflags = sprom->boardflags_lo + (sprom->boardflags_hi << 16);
++	wlc_hw->boardflags2 = sprom->boardflags2_lo + (sprom->boardflags2_hi << 16);
++
++	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
++		brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED);
++
++	/* check device id(srom, nvram etc.) to set bands */
++	if (wlc_hw->deviceid == BCM43224_D11N_ID ||
++	    wlc_hw->deviceid == BCM43224_D11N_ID_VEN1)
++		/* Dualband boards */
++		wlc_hw->_nbands = 2;
++	else
++		wlc_hw->_nbands = 1;
++
++	if ((ai_get_chip_id(wlc_hw->sih) == BCM43225_CHIP_ID))
++		wlc_hw->_nbands = 1;
++
++	/* BMAC_NOTE: remove init of pub values when brcms_c_attach()
++	 * unconditionally does the init of these values
++	 */
++	wlc->vendorid = wlc_hw->vendorid;
++	wlc->deviceid = wlc_hw->deviceid;
++	wlc->pub->sih = wlc_hw->sih;
++	wlc->pub->corerev = wlc_hw->corerev;
++	wlc->pub->sromrev = wlc_hw->sromrev;
++	wlc->pub->boardrev = wlc_hw->boardrev;
++	wlc->pub->boardflags = wlc_hw->boardflags;
++	wlc->pub->boardflags2 = wlc_hw->boardflags2;
++	wlc->pub->_nbands = wlc_hw->_nbands;
++
++	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
++
++	if (wlc_hw->physhim == NULL) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach "
++			"failed\n", unit);
++		err = 25;
++		goto fail;
++	}
++
++	/* pass all the parameters to wlc_phy_shared_attach in one struct */
++	sha_params.sih = wlc_hw->sih;
++	sha_params.physhim = wlc_hw->physhim;
++	sha_params.unit = unit;
++	sha_params.corerev = wlc_hw->corerev;
++	sha_params.vid = wlc_hw->vendorid;
++	sha_params.did = wlc_hw->deviceid;
++	sha_params.chip = ai_get_chip_id(wlc_hw->sih);
++	sha_params.chiprev = ai_get_chiprev(wlc_hw->sih);
++	sha_params.chippkg = ai_get_chippkg(wlc_hw->sih);
++	sha_params.sromrev = wlc_hw->sromrev;
++	sha_params.boardtype = ai_get_boardtype(wlc_hw->sih);
++	sha_params.boardrev = wlc_hw->boardrev;
++	sha_params.boardflags = wlc_hw->boardflags;
++	sha_params.boardflags2 = wlc_hw->boardflags2;
++
++	/* alloc and save pointer to shared phy state area */
++	wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
++	if (!wlc_hw->phy_sh) {
++		err = 16;
++		goto fail;
++	}
++
++	/* initialize software state for each core and band */
++	for (j = 0; j < wlc_hw->_nbands; j++) {
++		/*
++		 * band0 is always 2.4Ghz
++		 * band1, if present, is 5Ghz
++		 */
++
++		brcms_c_setxband(wlc_hw, j);
++
++		wlc_hw->band->bandunit = j;
++		wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->band->bandunit = j;
++		wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G;
++		wlc->core->coreidx = core->core_index;
++
++		wlc_hw->machwcap = bcma_read32(core, D11REGOFFS(machwcap));
++		wlc_hw->machwcap_backup = wlc_hw->machwcap;
++
++		/* init tx fifo size */
++		wlc_hw->xmtfifo_sz =
++		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
++
++		/* Get a phy for this band */
++		wlc_hw->band->pi =
++			wlc_phy_attach(wlc_hw->phy_sh, core,
++				       wlc_hw->band->bandtype,
++				       wlc->wiphy);
++		if (wlc_hw->band->pi == NULL) {
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_"
++				  "attach failed\n", unit);
++			err = 17;
++			goto fail;
++		}
++
++		wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
++
++		wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
++				       &wlc_hw->band->phyrev,
++				       &wlc_hw->band->radioid,
++				       &wlc_hw->band->radiorev);
++		wlc_hw->band->abgphy_encore =
++		    wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
++		wlc_hw->band->core_flags =
++		    wlc_phy_get_coreflags(wlc_hw->band->pi);
++
++		/* verify good phy_type & supported phy revision */
++		if (BRCMS_ISNPHY(wlc_hw->band)) {
++			if (NCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else if (BRCMS_ISLCNPHY(wlc_hw->band)) {
++			if (LCNCONF_HAS(wlc_hw->band->phyrev))
++				goto good_phy;
++			else
++				goto bad_phy;
++		} else {
++ bad_phy:
++			wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported "
++				  "phy type/rev (%d/%d)\n", unit,
++				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
++			err = 18;
++			goto fail;
++		}
++
++ good_phy:
++		/*
++		 * BMAC_NOTE: wlc->band->pi should not be set below and should
++		 * be done in the high level attach. However we can not make
++		 * that change until all low level access is changed to
++		 * wlc_hw->band->pi. Instead do the wlc->band->pi init below,
++		 * keeping wlc_hw->band->pi as well for incremental update of
++		 * low level fns, and cut over low only init when all fns
++		 * updated.
++		 */
++		wlc->band->pi = wlc_hw->band->pi;
++		wlc->band->phytype = wlc_hw->band->phytype;
++		wlc->band->phyrev = wlc_hw->band->phyrev;
++		wlc->band->radioid = wlc_hw->band->radioid;
++		wlc->band->radiorev = wlc_hw->band->radiorev;
++
++		/* default contention windows size limits */
++		wlc_hw->band->CWmin = APHY_CWMIN;
++		wlc_hw->band->CWmax = PHY_CWMAX;
++
++		if (!brcms_b_attach_dmapio(wlc, j, wme)) {
++			err = 19;
++			goto fail;
++		}
++	}
++
++	/* disable core to match driver "down" state */
++	brcms_c_coredisable(wlc_hw);
++
++	/* Match driver "down" state */
++	ai_pci_down(wlc_hw->sih);
++
++	/* turn off pll and xtal to match driver "down" state */
++	brcms_b_xtal(wlc_hw, OFF);
++
++	/* *******************************************************************
++	 * The hardware is in the DOWN state at this point. D11 core
++	 * or cores are in reset with clocks off, and the board PLLs
++	 * are off if possible.
++	 *
++	 * Beyond this point, wlc->sbclk == false and chip registers
++	 * should not be touched.
++	 *********************************************************************
++	 */
++
++	/* init etheraddr state variables */
++	brcms_c_get_macaddr(wlc_hw, wlc_hw->etheraddr);
++
++	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
++	    is_zero_ether_addr(wlc_hw->etheraddr)) {
++		wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr\n",
++			  unit);
++		err = 22;
++		goto fail;
++	}
++
++	BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n",
++	       wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih));
++
++	return err;
++
++ fail:
++	wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit,
++		  err);
++	return err;
++}
++
++static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
++{
++	uint unit;
++	unit = wlc->pub->unit;
++
++	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
++		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
++		wlc->band->antgain = 8;
++	} else if (wlc->band->antgain == -1) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom, using 2dB\n", unit, __func__);
++		wlc->band->antgain = 8;
++	} else {
++		s8 gain, fract;
++		/* Older sroms specified gain in whole dbm only.  In order
++		 * be able to specify qdbm granularity and remain backward
++		 * compatible the whole dbms are now encoded in only
++		 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
++		 * 6 bit signed number ranges from -32 - 31.
++		 *
++		 * Examples:
++		 * 0x1 = 1 db,
++		 * 0xc1 = 1.75 db (1 + 3 quarters),
++		 * 0x3f = -1 (-1 + 0 quarters),
++		 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
++		 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
++		 */
++		gain = wlc->band->antgain & 0x3f;
++		gain <<= 2;	/* Sign extend */
++		gain >>= 2;
++		fract = (wlc->band->antgain & 0xc0) >> 6;
++		wlc->band->antgain = 4 * gain + fract;
++	}
++}
++
++static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
++{
++	int aa;
++	uint unit;
++	int bandtype;
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	unit = wlc->pub->unit;
++	bandtype = wlc->band->bandtype;
++
++	/* get antennas available */
++	if (bandtype == BRCM_BAND_5G)
++		aa = sprom->ant_available_a;
++	else
++		aa = sprom->ant_available_bg;
++
++	if ((aa < 1) || (aa > 15)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
++			  " srom (0x%x), using 3\n", unit, __func__, aa);
++		aa = 3;
++	}
++
++	/* reset the defaults if we have a single antenna */
++	if (aa == 1) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
++		wlc->stf->txant = ANT_TX_FORCE_0;
++	} else if (aa == 2) {
++		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
++		wlc->stf->txant = ANT_TX_FORCE_1;
++	} else {
++	}
++
++	/* Compute Antenna Gain */
++	if (bandtype == BRCM_BAND_5G)
++		wlc->band->antgain = sprom->antenna_gain.a1;
++	else
++		wlc->band->antgain = sprom->antenna_gain.a0;
++
++	brcms_c_attach_antgain_init(wlc);
++
++	return true;
++}
++
++static void brcms_c_bss_default_init(struct brcms_c_info *wlc)
++{
++	u16 chanspec;
++	struct brcms_band *band;
++	struct brcms_bss_info *bi = wlc->default_bss;
++
++	/* init default and target BSS with some sane initial values */
++	memset((char *)(bi), 0, sizeof(struct brcms_bss_info));
++	bi->beacon_period = BEACON_INTERVAL_DEFAULT;
++
++	/* fill the default channel as the first valid channel
++	 * starting from the 2G channels
++	 */
++	chanspec = ch20mhz_chspec(1);
++	wlc->home_chanspec = bi->chanspec = chanspec;
++
++	/* find the band of our default channel */
++	band = wlc->band;
++	if (wlc->pub->_nbands > 1 &&
++	    band->bandunit != chspec_bandunit(chanspec))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++
++	/* init bss rates to the band specific default rate set */
++	brcms_c_rateset_default(&bi->rateset, NULL, band->phytype,
++		band->bandtype, false, BRCMS_RATE_MASK_FULL,
++		(bool) (wlc->pub->_n_enab & SUPPORT_11N),
++		brcms_chspec_bw(chanspec), wlc->stf->txstreams);
++
++	if (wlc->pub->_n_enab & SUPPORT_11N)
++		bi->flags |= BRCMS_BSS_HT;
++}
++
++static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc)
++{
++	struct brcms_txq_info *qi, *p;
++
++	qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC);
++	if (qi != NULL) {
++		/*
++		 * Have enough room for control packets along with HI watermark
++		 * Also, add room to txq for total psq packets if all the SCBs
++		 * leave PS mode. The watermark for flowcontrol to OS packets
++		 * will remain the same
++		 */
++		brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT,
++			  2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT);
++
++		/* add this queue to the the global list */
++		p = wlc->tx_queues;
++		if (p == NULL) {
++			wlc->tx_queues = qi;
++		} else {
++			while (p->next != NULL)
++				p = p->next;
++			p->next = qi;
++		}
++	}
++	return qi;
++}
++
++static void brcms_c_txq_free(struct brcms_c_info *wlc,
++			     struct brcms_txq_info *qi)
++{
++	struct brcms_txq_info *p;
++
++	if (qi == NULL)
++		return;
++
++	/* remove the queue from the linked list */
++	p = wlc->tx_queues;
++	if (p == qi)
++		wlc->tx_queues = p->next;
++	else {
++		while (p != NULL && p->next != qi)
++			p = p->next;
++		if (p != NULL)
++			p->next = p->next->next;
++	}
++
++	kfree(qi);
++}
++
++static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap)
++{
++	uint i;
++	struct brcms_band *band;
++
++	for (i = 0; i < wlc->pub->_nbands; i++) {
++		band = wlc->bandstate[i];
++		if (band->bandtype == BRCM_BAND_5G) {
++			if ((bwcap == BRCMS_N_BW_40ALL)
++			    || (bwcap == BRCMS_N_BW_20IN2G_40IN5G))
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		} else {
++			if (bwcap == BRCMS_N_BW_40ALL)
++				band->mimo_cap_40 = true;
++			else
++				band->mimo_cap_40 = false;
++		}
++	}
++}
++
++static void brcms_c_timers_deinit(struct brcms_c_info *wlc)
++{
++	/* free timer state */
++	if (wlc->wdtimer) {
++		brcms_free_timer(wlc->wdtimer);
++		wlc->wdtimer = NULL;
++	}
++	if (wlc->radio_timer) {
++		brcms_free_timer(wlc->radio_timer);
++		wlc->radio_timer = NULL;
++	}
++}
++
++static void brcms_c_detach_module(struct brcms_c_info *wlc)
++{
++	if (wlc->asi) {
++		brcms_c_antsel_detach(wlc->asi);
++		wlc->asi = NULL;
++	}
++
++	if (wlc->ampdu) {
++		brcms_c_ampdu_detach(wlc->ampdu);
++		wlc->ampdu = NULL;
++	}
++
++	brcms_c_stf_detach(wlc);
++}
++
++/*
++ * low level detach
++ */
++static int brcms_b_detach(struct brcms_c_info *wlc)
++{
++	uint i;
++	struct brcms_hw_band *band;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	int callbacks;
++
++	callbacks = 0;
++
++	brcms_b_detach_dmapio(wlc_hw);
++
++	band = wlc_hw->band;
++	for (i = 0; i < wlc_hw->_nbands; i++) {
++		if (band->pi) {
++			/* Detach this band's phy */
++			wlc_phy_detach(band->pi);
++			band->pi = NULL;
++		}
++		band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
++	}
++
++	/* Free shared phy state */
++	kfree(wlc_hw->phy_sh);
++
++	wlc_phy_shim_detach(wlc_hw->physhim);
++
++	if (wlc_hw->sih) {
++		ai_detach(wlc_hw->sih);
++		wlc_hw->sih = NULL;
++	}
++
++	return callbacks;
++
++}
++
++/*
++ * Return a count of the number of driver callbacks still pending.
++ *
++ * General policy is that brcms_c_detach can only dealloc/free software states.
++ * It can NOT touch hardware registers since the d11core may be in reset and
++ * clock may not be available.
++ * One exception is sb register access, which is possible if crystal is turned
++ * on after "down" state, driver should avoid software timer with the exception
++ * of radio_monitor.
++ */
++uint brcms_c_detach(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	if (wlc == NULL)
++		return 0;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	callbacks += brcms_b_detach(wlc);
++
++	/* delete software timers */
++	if (!brcms_c_radio_monitor_stop(wlc))
++		callbacks++;
++
++	brcms_c_channel_mgr_detach(wlc->cmi);
++
++	brcms_c_timers_deinit(wlc);
++
++	brcms_c_detach_module(wlc);
++
++
++	while (wlc->tx_queues != NULL)
++		brcms_c_txq_free(wlc, wlc->tx_queues);
++
++	brcms_c_detach_mfree(wlc);
++	return callbacks;
++}
++
++/* update state that depends on the current value of "ap" */
++static void brcms_c_ap_upd(struct brcms_c_info *wlc)
++{
++	/* STA-BSS; short capable */
++	wlc->PLCPHdr_override = BRCMS_PLCP_SHORT;
++}
++
++/* Initialize just the hardware when coming out of POR or S3/S5 system states */
++static void brcms_b_hw_up(struct brcms_hardware *wlc_hw)
++{
++	if (wlc_hw->wlc->pub->hw_up)
++		return;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * TODO: test suspend/resume
++	 *
++	 * AI chip doesn't restore bar0win2 on
++	 * hibernation/resume, need sw fixup
++	 */
++
++	/*
++	 * Inform phy that a POR reset has occurred so
++	 * it does a complete phy init
++	 */
++	wlc_phy_por_inform(wlc_hw->band->pi);
++
++	wlc_hw->ucode_loaded = false;
++	wlc_hw->wlc->pub->hw_up = true;
++
++	if ((wlc_hw->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc_hw->sih) == BCM4313_CHIP_ID)) {
++		if (!
++		    (wlc_hw->boardrev >= 0x1250
++		     && (wlc_hw->boardflags & BFL_FEM_BT)))
++			ai_epa_4313war(wlc_hw->sih);
++	}
++}
++
++static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	/*
++	 * Enable pll and xtal, initialize the power control registers,
++	 * and force fastclock for the remainder of brcms_c_up().
++	 */
++	brcms_b_xtal(wlc_hw, ON);
++	ai_clkctl_init(wlc_hw->sih);
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++
++	/*
++	 * Configure pci/pcmcia here instead of in brcms_c_attach()
++	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
++	 */
++	bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci, wlc_hw->d11core,
++			      true);
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to
++	 * bring the driver up in this case.
++	 */
++	if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
++		/* put SB PCI in down state again */
++		ai_pci_down(wlc_hw->sih);
++		brcms_b_xtal(wlc_hw, OFF);
++		return -ENOMEDIUM;
++	}
++
++	ai_pci_up(wlc_hw->sih);
++
++	/* reset the d11 core */
++	brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
++
++	return 0;
++}
++
++static int brcms_b_up_finish(struct brcms_hardware *wlc_hw)
++{
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	wlc_hw->up = true;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
++
++	/* FULLY enable dynamic power control and d11 core interrupt */
++	brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_DYNAMIC);
++	brcms_intrson(wlc_hw->wlc->wl);
++	return 0;
++}
++
++/*
++ * Write WME tunable parameters for retransmit/max rate
++ * from wlc struct to ucode
++ */
++static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
++{
++	int ac;
++
++	/* Need clock to do this */
++	if (!wlc->clk)
++		return;
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++		brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),
++				  wlc->wme_retries[ac]);
++}
++
++/* make interface operational */
++int brcms_c_up(struct brcms_c_info *wlc)
++{
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* HW is turned off so don't try to access it */
++	if (wlc->pub->hw_off || brcms_deviceremoved(wlc))
++		return -ENOMEDIUM;
++
++	if (!wlc->pub->hw_up) {
++		brcms_b_hw_up(wlc->hw);
++		wlc->pub->hw_up = true;
++	}
++
++	if ((wlc->pub->boardflags & BFL_FEM)
++	    && (ai_get_chip_id(wlc->hw->sih) == BCM4313_CHIP_ID)) {
++		if (wlc->pub->boardrev >= 0x1250
++		    && (wlc->pub->boardflags & BFL_FEM_BT))
++			brcms_b_mhf(wlc->hw, MHF5, MHF5_4313_GPIOCTRL,
++				MHF5_4313_GPIOCTRL, BRCM_BAND_ALL);
++		else
++			brcms_b_mhf(wlc->hw, MHF4, MHF4_EXTPA_ENABLE,
++				    MHF4_EXTPA_ENABLE, BRCM_BAND_ALL);
++	}
++
++	/*
++	 * Need to read the hwradio status here to cover the case where the
++	 * system is loaded with the hw radio disabled. We do not want to bring
++	 * the driver up in this case. If radio is disabled, abort up, lower
++	 * power, start radio timer and return 0(for NDIS) don't call
++	 * radio_update to avoid looping brcms_c_up.
++	 *
++	 * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only
++	 */
++	if (!wlc->pub->radio_disabled) {
++		int status = brcms_b_up_prep(wlc->hw);
++		if (status == -ENOMEDIUM) {
++			if (!mboolisset
++			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
++				struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++				mboolset(wlc->pub->radio_disabled,
++					 WL_RADIO_HW_DISABLE);
++
++				if (bsscfg->enable && bsscfg->BSS)
++					wiphy_err(wlc->wiphy, "wl%d: up"
++						  ": rfdisable -> "
++						  "bsscfg_disable()\n",
++						   wlc->pub->unit);
++			}
++		}
++	}
++
++	if (wlc->pub->radio_disabled) {
++		brcms_c_radio_monitor_start(wlc);
++		return 0;
++	}
++
++	/* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */
++	wlc->clk = true;
++
++	brcms_c_radio_monitor_stop(wlc);
++
++	/* Set EDCF hostflags */
++	brcms_b_mhf(wlc->hw, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL);
++
++	brcms_init(wlc->wl);
++	wlc->pub->up = true;
++
++	if (wlc->bandinit_pending) {
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
++		wlc->bandinit_pending = false;
++		brcms_c_enable_mac(wlc);
++	}
++
++	brcms_b_up_finish(wlc->hw);
++
++	/* Program the TX wme params with the current settings */
++	brcms_c_wme_retries_write(wlc);
++
++	/* start one second watchdog timer */
++	brcms_add_timer(wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
++	wlc->WDarmed = true;
++
++	/* ensure antenna config is up to date */
++	brcms_c_stf_phy_txant_upd(wlc);
++	/* ensure LDPC config is in sync */
++	brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc);
++
++	return 0;
++}
++
++static uint brcms_c_down_del_timer(struct brcms_c_info *wlc)
++{
++	uint callbacks = 0;
++
++	return callbacks;
++}
++
++static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw)
++{
++	bool dev_gone;
++	uint callbacks = 0;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	/* disable interrupts */
++	if (dev_gone)
++		wlc_hw->wlc->macintmask = 0;
++	else {
++		/* now disable interrupts */
++		brcms_intrsoff(wlc_hw->wlc->wl);
++
++		/* ensure we're running on the pll clock again */
++		brcms_b_clkctl_clk(wlc_hw, BCMA_CLKMODE_FAST);
++	}
++	/* down phy at the last of this stage */
++	callbacks += wlc_phy_down(wlc_hw->band->pi);
++
++	return callbacks;
++}
++
++static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
++{
++	uint callbacks = 0;
++	bool dev_gone;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++
++	if (!wlc_hw->up)
++		return callbacks;
++
++	wlc_hw->up = false;
++	wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
++
++	dev_gone = brcms_deviceremoved(wlc_hw->wlc);
++
++	if (dev_gone) {
++		wlc_hw->sbclk = false;
++		wlc_hw->clk = false;
++		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
++
++		/* reclaim any posted packets */
++		brcms_c_flushqueues(wlc_hw->wlc);
++	} else {
++
++		/* Reset and disable the core */
++		if (bcma_core_is_enabled(wlc_hw->d11core)) {
++			if (bcma_read32(wlc_hw->d11core,
++					D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++				brcms_c_suspend_mac_and_wait(wlc_hw->wlc);
++			callbacks += brcms_reset(wlc_hw->wlc->wl);
++			brcms_c_coredisable(wlc_hw);
++		}
++
++		/* turn off primary xtal and pll */
++		if (!wlc_hw->noreset) {
++			ai_pci_down(wlc_hw->sih);
++			brcms_b_xtal(wlc_hw, OFF);
++		}
++	}
++
++	return callbacks;
++}
++
++/*
++ * Mark the interface nonoperational, stop the software mechanisms,
++ * disable the hardware, free any transient buffer state.
++ * Return a count of the number of driver callbacks still pending.
++ */
++uint brcms_c_down(struct brcms_c_info *wlc)
++{
++
++	uint callbacks = 0;
++	int i;
++	bool dev_gone = false;
++	struct brcms_txq_info *qi;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* check if we are already in the going down path */
++	if (wlc->going_down) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
++			  "\n", wlc->pub->unit, __func__);
++		return 0;
++	}
++	if (!wlc->pub->up)
++		return callbacks;
++
++	wlc->going_down = true;
++
++	callbacks += brcms_b_bmac_down_prep(wlc->hw);
++
++	dev_gone = brcms_deviceremoved(wlc);
++
++	/* Call any registered down handlers */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].down_fn)
++			callbacks +=
++			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
++	}
++
++	/* cancel the watchdog timer */
++	if (wlc->WDarmed) {
++		if (!brcms_del_timer(wlc->wdtimer))
++			callbacks++;
++		wlc->WDarmed = false;
++	}
++	/* cancel all other timers */
++	callbacks += brcms_c_down_del_timer(wlc);
++
++	wlc->pub->up = false;
++
++	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
++
++	/* clear txq flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* flush tx queues */
++	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next)
++		brcmu_pktq_flush(&qi->q, true, NULL, NULL);
++
++	callbacks += brcms_b_down_finish(wlc->hw);
++
++	/* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */
++	wlc->clk = false;
++
++	wlc->going_down = false;
++	return callbacks;
++}
++
++/* Set the current gmode configuration */
++int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
++{
++	int ret = 0;
++	uint i;
++	struct brcms_c_rateset rs;
++	/* Default to 54g Auto */
++	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
++	s8 shortslot = BRCMS_SHORTSLOT_AUTO;
++	bool shortslot_restrict = false; /* Restrict association to stations
++					  * that support shortslot
++					  */
++	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
++	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
++	int preamble = BRCMS_PLCP_LONG;
++	bool preamble_restrict = false;	/* Restrict association to stations
++					 * that support short preambles
++					 */
++	struct brcms_band *band;
++
++	/* if N-support is enabled, allow Gmode set as long as requested
++	 * Gmode is not GMODE_LEGACY_B
++	 */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && gmode == GMODE_LEGACY_B)
++		return -ENOTSUPP;
++
++	/* verify that we are dealing with 2G band and grab the band pointer */
++	if (wlc->band->bandtype == BRCM_BAND_2G)
++		band = wlc->band;
++	else if ((wlc->pub->_nbands > 1) &&
++		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G))
++		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
++	else
++		return -EINVAL;
++
++	/* Legacy or bust when no OFDM is supported by regulatory */
++	if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
++	     BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
++		return -EINVAL;
++
++	/* update configuration value */
++	if (config)
++		brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
++
++	/* Clear rateset override */
++	memset(&rs, 0, sizeof(struct brcms_c_rateset));
++
++	switch (gmode) {
++	case GMODE_LEGACY_B:
++		shortslot = BRCMS_SHORTSLOT_OFF;
++		brcms_c_rateset_copy(&gphy_legacy_rates, &rs);
++
++		break;
++
++	case GMODE_LRS:
++		break;
++
++	case GMODE_AUTO:
++		/* Accept defaults */
++		break;
++
++	case GMODE_ONLY:
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	case GMODE_PERFORMANCE:
++		shortslot = BRCMS_SHORTSLOT_ON;
++		shortslot_restrict = true;
++		ofdm_basic = true;
++		preamble = BRCMS_PLCP_SHORT;
++		preamble_restrict = true;
++		break;
++
++	default:
++		/* Error */
++		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
++			  wlc->pub->unit, __func__, gmode);
++		return -ENOTSUPP;
++	}
++
++	band->gmode = gmode;
++
++	wlc->shortslot_override = shortslot;
++
++	/* Use the default 11g rateset */
++	if (!rs.count)
++		brcms_c_rateset_copy(&cck_ofdm_rates, &rs);
++
++	if (ofdm_basic) {
++		for (i = 0; i < rs.count; i++) {
++			if (rs.rates[i] == BRCM_RATE_6M
++			    || rs.rates[i] == BRCM_RATE_12M
++			    || rs.rates[i] == BRCM_RATE_24M)
++				rs.rates[i] |= BRCMS_RATE_FLAG;
++		}
++	}
++
++	/* Set default bss rateset */
++	wlc->default_bss->rateset.count = rs.count;
++	memcpy(wlc->default_bss->rateset.rates, rs.rates,
++	       sizeof(wlc->default_bss->rateset.rates));
++
++	return ret;
++}
++
++int brcms_c_set_nmode(struct brcms_c_info *wlc)
++{
++	uint i;
++	s32 nmode = AUTO;
++
++	if (wlc->stf->txstreams == WL_11N_3x3)
++		nmode = WL_11N_3x3;
++	else
++		nmode = WL_11N_2x2;
++
++	/* force GMODE_AUTO if NMODE is ON */
++	brcms_c_set_gmode(wlc, GMODE_AUTO, true);
++	if (nmode == WL_11N_3x3)
++		wlc->pub->_n_enab = SUPPORT_HT;
++	else
++		wlc->pub->_n_enab = SUPPORT_11N;
++	wlc->default_bss->flags |= BRCMS_BSS_HT;
++	/* add the mcs rates to the default and hw ratesets */
++	brcms_c_rateset_mcs_build(&wlc->default_bss->rateset,
++			      wlc->stf->txstreams);
++	for (i = 0; i < wlc->pub->_nbands; i++)
++		memcpy(wlc->bandstate[i]->hw_rateset.mcs,
++		       wlc->default_bss->rateset.mcs, MCSSET_LEN);
++
++	return 0;
++}
++
++static int
++brcms_c_set_internal_rateset(struct brcms_c_info *wlc,
++			     struct brcms_c_rateset *rs_arg)
++{
++	struct brcms_c_rateset rs, new;
++	uint bandunit;
++
++	memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset));
++
++	/* check for bad count value */
++	if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES))
++		return -EINVAL;
++
++	/* try the current band */
++	bandunit = wlc->band->bandunit;
++	memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++	if (brcms_c_rate_hwrs_filter_sort_validate
++	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
++	     wlc->stf->txstreams))
++		goto good;
++
++	/* try the other band */
++	if (brcms_is_mband_unlocked(wlc)) {
++		bandunit = OTHERBANDUNIT(wlc);
++		memcpy(&new, &rs, sizeof(struct brcms_c_rateset));
++		if (brcms_c_rate_hwrs_filter_sort_validate(&new,
++						       &wlc->
++						       bandstate[bandunit]->
++						       hw_rateset, true,
++						       wlc->stf->txstreams))
++			goto good;
++	}
++
++	return -EBADE;
++
++ good:
++	/* apply new rateset */
++	memcpy(&wlc->default_bss->rateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
++	       sizeof(struct brcms_c_rateset));
++	return 0;
++}
++
++static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc)
++{
++	u8 r;
++	bool war = false;
++
++	if (wlc->bsscfg->associated)
++		r = wlc->bsscfg->current_bss->rateset.rates[0];
++	else
++		r = wlc->default_bss->rateset.rates[0];
++
++	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
++}
++
++int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel)
++{
++	u16 chspec = ch20mhz_chspec(channel);
++
++	if (channel < 0 || channel > MAXCHANNEL)
++		return -EINVAL;
++
++	if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec))
++		return -EINVAL;
++
++
++	if (!wlc->pub->up && brcms_is_mband_unlocked(wlc)) {
++		if (wlc->band->bandunit != chspec_bandunit(chspec))
++			wlc->bandinit_pending = true;
++		else
++			wlc->bandinit_pending = false;
++	}
++
++	wlc->default_bss->chanspec = chspec;
++	/* brcms_c_BSSinit() will sanitize the rateset before
++	 * using it.. */
++	if (wlc->pub->up && (wlc_phy_chanspec_get(wlc->band->pi) != chspec)) {
++		brcms_c_set_home_chanspec(wlc, chspec);
++		brcms_c_suspend_mac_and_wait(wlc);
++		brcms_c_set_chanspec(wlc, chspec);
++		brcms_c_enable_mac(wlc);
++	}
++	return 0;
++}
++
++int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl)
++{
++	int ac;
++
++	if (srl < 1 || srl > RETRY_SHORT_MAX ||
++	    lrl < 1 || lrl > RETRY_SHORT_MAX)
++		return -EINVAL;
++
++	wlc->SRL = srl;
++	wlc->LRL = lrl;
++
++	brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
++
++	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_SHORT,  wlc->SRL);
++		wlc->wme_retries[ac] =	SFIELD(wlc->wme_retries[ac],
++					       EDCF_LONG, wlc->LRL);
++	}
++	brcms_c_wme_retries_write(wlc);
++
++	return 0;
++}
++
++void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs)
++{
++	struct brcms_c_rateset *rs;
++
++	if (wlc->pub->associated)
++		rs = &wlc->bsscfg->current_bss->rateset;
++	else
++		rs = &wlc->default_bss->rateset;
++
++	/* Copy only legacy rateset section */
++	currs->count = rs->count;
++	memcpy(&currs->rates, &rs->rates, rs->count);
++}
++
++int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs)
++{
++	struct brcms_c_rateset internal_rs;
++	int bcmerror;
++
++	if (rs->count > BRCMS_NUMRATES)
++		return -ENOBUFS;
++
++	memset(&internal_rs, 0, sizeof(struct brcms_c_rateset));
++
++	/* Copy only legacy rateset section */
++	internal_rs.count = rs->count;
++	memcpy(&internal_rs.rates, &rs->rates, internal_rs.count);
++
++	/* merge rateset coming in with the current mcsset */
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		struct brcms_bss_info *mcsset_bss;
++		if (wlc->bsscfg->associated)
++			mcsset_bss = wlc->bsscfg->current_bss;
++		else
++			mcsset_bss = wlc->default_bss;
++		memcpy(internal_rs.mcs, &mcsset_bss->rateset.mcs[0],
++		       MCSSET_LEN);
++	}
++
++	bcmerror = brcms_c_set_internal_rateset(wlc, &internal_rs);
++	if (!bcmerror)
++		brcms_c_ofdm_rateset_war(wlc);
++
++	return bcmerror;
++}
++
++int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period)
++{
++	if (period < DOT11_MIN_BEACON_PERIOD ||
++	    period > DOT11_MAX_BEACON_PERIOD)
++		return -EINVAL;
++
++	wlc->default_bss->beacon_period = period;
++	return 0;
++}
++
++u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx)
++{
++	return wlc->band->phytype;
++}
++
++void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override)
++{
++	wlc->shortslot_override = sslot_override;
++
++	/*
++	 * shortslot is an 11g feature, so no more work if we are
++	 * currently on the 5G band
++	 */
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		return;
++
++	if (wlc->pub->up && wlc->pub->associated) {
++		/* let watchdog or beacon processing update shortslot */
++	} else if (wlc->pub->up) {
++		/* unassociated shortslot is off */
++		brcms_c_switch_shortslot(wlc, false);
++	} else {
++		/* driver is down, so just update the brcms_c_info
++		 * value */
++		if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO)
++			wlc->shortslot = false;
++		else
++			wlc->shortslot =
++			    (wlc->shortslot_override ==
++			     BRCMS_SHORTSLOT_ON);
++	}
++}
++
++/*
++ * register watchdog and down handlers.
++ */
++int brcms_c_module_register(struct brcms_pub *pub,
++			    const char *name, struct brcms_info *hdl,
++			    int (*d_fn)(void *handle))
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	/* find an empty entry and just add, no duplication check! */
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (wlc->modulecb[i].name[0] == '\0') {
++			strncpy(wlc->modulecb[i].name, name,
++				sizeof(wlc->modulecb[i].name) - 1);
++			wlc->modulecb[i].hdl = hdl;
++			wlc->modulecb[i].down_fn = d_fn;
++			return 0;
++		}
++	}
++
++	return -ENOSR;
++}
++
++/* unregister module callbacks */
++int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++			      struct brcms_info *hdl)
++{
++	struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc;
++	int i;
++
++	if (wlc == NULL)
++		return -ENODATA;
++
++	for (i = 0; i < BRCMS_MAXMODULES; i++) {
++		if (!strcmp(wlc->modulecb[i].name, name) &&
++		    (wlc->modulecb[i].hdl == hdl)) {
++			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
++			return 0;
++		}
++	}
++
++	/* table not found! */
++	return -ENODATA;
++}
++
++void brcms_c_print_txstatus(struct tx_status *txs)
++{
++	pr_debug("\ntxpkt (MPDU) Complete\n");
++
++	pr_debug("FrameID: %04x   TxStatus: %04x\n", txs->frameid, txs->status);
++
++	pr_debug("[15:12]  %d  frame attempts\n",
++		  (txs->status & TX_STATUS_FRM_RTX_MASK) >>
++		 TX_STATUS_FRM_RTX_SHIFT);
++	pr_debug(" [11:8]  %d  rts attempts\n",
++		 (txs->status & TX_STATUS_RTS_RTX_MASK) >>
++		 TX_STATUS_RTS_RTX_SHIFT);
++	pr_debug("    [7]  %d  PM mode indicated\n",
++		 txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
++	pr_debug("    [6]  %d  intermediate status\n",
++		 txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
++	pr_debug("    [5]  %d  AMPDU\n",
++		 txs->status & TX_STATUS_AMPDU ? 1 : 0);
++	pr_debug("  [4:2]  %d  Frame Suppressed Reason (%s)\n",
++		 (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
++		 (const char *[]) {
++			"None",
++			"PMQ Entry",
++			"Flush request",
++			"Previous frag failure",
++			"Channel mismatch",
++			"Lifetime Expiry",
++			"Underflow"
++		 } [(txs->status & TX_STATUS_SUPR_MASK) >>
++		    TX_STATUS_SUPR_SHIFT]);
++	pr_debug("    [1]  %d  acked\n",
++		 txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
++
++	pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
++		 txs->lasttxtime, txs->sequence, txs->phyerr,
++		 (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
++		 (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
++}
++
++bool brcms_c_chipmatch(u16 vendor, u16 device)
++{
++	if (vendor != PCI_VENDOR_ID_BROADCOM) {
++		pr_err("unknown vendor id %04x\n", vendor);
++		return false;
++	}
++
++	if (device == BCM43224_D11N_ID_VEN1)
++		return true;
++	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
++		return true;
++	if (device == BCM4313_D11N2G_ID)
++		return true;
++	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
++		return true;
++
++	pr_err("unknown device id %04x\n", device);
++	return false;
++}
++
++#if defined(DEBUG)
++void brcms_c_print_txdesc(struct d11txh *txh)
++{
++	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
++	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
++	u16 mfc = le16_to_cpu(txh->MacFrameControl);
++	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
++	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
++	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
++	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
++	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
++	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
++	u16 mainrates = le16_to_cpu(txh->MainRates);
++	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
++	u8 *iv = txh->IV;
++	u8 *ra = txh->TxFrameRA;
++	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
++	u8 *rtspfb = txh->RTSPLCPFallback;
++	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
++	u8 *fragpfb = txh->FragPLCPFallback;
++	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
++	u16 mmodelen = le16_to_cpu(txh->MModeLen);
++	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
++	u16 tfid = le16_to_cpu(txh->TxFrameID);
++	u16 txs = le16_to_cpu(txh->TxStatus);
++	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
++	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
++	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
++	u16 mmbyte = le16_to_cpu(txh->MinMBytes);
++
++	u8 *rtsph = txh->RTSPhyHeader;
++	struct ieee80211_rts rts = txh->rts_frame;
++
++	/* add plcp header along with txh descriptor */
++	brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
++			   "Raw TxDesc + plcp header:\n");
++
++	pr_debug("TxCtlLow: %04x ", mtcl);
++	pr_debug("TxCtlHigh: %04x ", mtch);
++	pr_debug("FC: %04x ", mfc);
++	pr_debug("FES Time: %04x\n", tfest);
++	pr_debug("PhyCtl: %04x%s ", ptcw,
++	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
++	pr_debug("PhyCtl_1: %04x ", ptcw_1);
++	pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
++	pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
++	pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
++	pr_debug("MainRates: %04x ", mainrates);
++	pr_debug("XtraFrameTypes: %04x ", xtraft);
++	pr_debug("\n");
++
++	print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
++	print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
++			     ra, sizeof(txh->TxFrameRA));
++
++	pr_debug("Fb FES Time: %04x ", tfestfb);
++	print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtspfb, sizeof(txh->RTSPLCPFallback));
++	pr_debug("RTS DUR: %04x ", rtsdfb);
++	print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
++			     fragpfb, sizeof(txh->FragPLCPFallback));
++	pr_debug("DUR: %04x", fragdfb);
++	pr_debug("\n");
++
++	pr_debug("MModeLen: %04x ", mmodelen);
++	pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
++
++	pr_debug("FrameID:     %04x\n", tfid);
++	pr_debug("TxStatus:    %04x\n", txs);
++
++	pr_debug("MaxNumMpdu:  %04x\n", mnmpdu);
++	pr_debug("MaxAggbyte:  %04x\n", mabyte);
++	pr_debug("MaxAggbyte_fb:  %04x\n", mabyte_f);
++	pr_debug("MinByte:     %04x\n", mmbyte);
++
++	print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
++			     rtsph, sizeof(txh->RTSPhyHeader));
++	print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
++			     (u8 *)&rts, sizeof(txh->rts_frame));
++	pr_debug("\n");
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++static int
++brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
++		     int len)
++{
++	int i;
++	char *p = buf;
++	char hexstr[16];
++	int slen = 0, nlen = 0;
++	u32 bit;
++	const char *name;
++
++	if (len < 2 || !buf)
++		return 0;
++
++	buf[0] = '\0';
++
++	for (i = 0; flags != 0; i++) {
++		bit = bd[i].bit;
++		name = bd[i].name;
++		if (bit == 0 && flags != 0) {
++			/* print any unnamed bits */
++			snprintf(hexstr, 16, "0x%X", flags);
++			name = hexstr;
++			flags = 0;	/* exit loop */
++		} else if ((flags & bit) == 0)
++			continue;
++		flags &= ~bit;
++		nlen = strlen(name);
++		slen += nlen;
++		/* count btwn flag space */
++		if (flags != 0)
++			slen += 1;
++		/* need NULL char as well */
++		if (len <= slen)
++			break;
++		/* copy NULL char but don't count it */
++		strncpy(p, name, nlen + 1);
++		p += nlen;
++		/* copy btwn flag space and NULL char */
++		if (flags != 0)
++			p += snprintf(p, 2, " ");
++		len -= slen;
++	}
++
++	/* indicate the str was too short */
++	if (flags != 0) {
++		if (len < 2)
++			p -= 2 - len;	/* overwrite last char */
++		p += snprintf(p, 2, ">");
++	}
++
++	return (int)(p - buf);
++}
++#endif				/* defined(DEBUG) */
++
++#if defined(DEBUG)
++void brcms_c_print_rxh(struct d11rxhdr *rxh)
++{
++	u16 len = rxh->RxFrameSize;
++	u16 phystatus_0 = rxh->PhyRxStatus_0;
++	u16 phystatus_1 = rxh->PhyRxStatus_1;
++	u16 phystatus_2 = rxh->PhyRxStatus_2;
++	u16 phystatus_3 = rxh->PhyRxStatus_3;
++	u16 macstatus1 = rxh->RxStatus1;
++	u16 macstatus2 = rxh->RxStatus2;
++	char flagstr[64];
++	char lenbuf[20];
++	static const struct brcms_c_bit_desc macstat_flags[] = {
++		{RXS_FCSERR, "FCSErr"},
++		{RXS_RESPFRAMETX, "Reply"},
++		{RXS_PBPRES, "PADDING"},
++		{RXS_DECATMPT, "DeCr"},
++		{RXS_DECERR, "DeCrErr"},
++		{RXS_BCNSENT, "Bcn"},
++		{0, NULL}
++	};
++
++	brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
++
++	brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
++
++	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
++
++	pr_debug("RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
++	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
++	pr_debug("RxPHYStatus:     %04x %04x %04x %04x\n",
++	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
++	pr_debug("RxMACStatus:     %x %s\n", macstatus1, flagstr);
++	pr_debug("RXMACaggtype:    %x\n",
++	       (macstatus2 & RXS_AGGTYPE_MASK));
++	pr_debug("RxTSFTime:       %04x\n", rxh->RxTSFTime);
++}
++#endif				/* defined(DEBUG) */
++
++u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
++{
++	u16 table_ptr;
++	u8 phy_rate, index;
++
++	/* get the phy specific rate encoding for the PLCP SIGNAL field */
++	if (is_ofdm_rate(rate))
++		table_ptr = M_RT_DIRMAP_A;
++	else
++		table_ptr = M_RT_DIRMAP_B;
++
++	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
++	 * the index into the rate table.
++	 */
++	phy_rate = rate_info[rate] & BRCMS_RATE_MASK;
++	index = phy_rate & 0xf;
++
++	/* Find the SHM pointer to the rate table entry by looking in the
++	 * Direct-map Table
++	 */
++	return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2));
++}
++
++static bool
++brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec, bool head)
++{
++	struct sk_buff *p;
++	int eprec = -1;		/* precedence to evict from */
++
++	/* Determine precedence from which to evict packet, if any */
++	if (pktq_pfull(q, prec))
++		eprec = prec;
++	else if (pktq_full(q)) {
++		p = brcmu_pktq_peek_tail(q, &eprec);
++		if (eprec > prec) {
++			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
++				  "\n", __func__, eprec, prec);
++			return false;
++		}
++	}
++
++	/* Evict if needed */
++	if (eprec >= 0) {
++		bool discard_oldest;
++
++		discard_oldest = ac_bitmap_tst(0, eprec);
++
++		/* Refuse newer packet unless configured to discard oldest */
++		if (eprec == prec && !discard_oldest) {
++			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
++				  "\n", __func__, prec);
++			return false;
++		}
++
++		/* Evict packet according to discard policy */
++		p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
++			brcmu_pktq_pdeq_tail(q, eprec);
++		brcmu_pkt_buf_free_skb(p);
++	}
++
++	/* Enqueue */
++	if (head)
++		p = brcmu_pktq_penq_head(q, prec, pkt);
++	else
++		p = brcmu_pktq_penq(q, prec, pkt);
++
++	return true;
++}
++
++/*
++ * Attempts to queue a packet onto a multiple-precedence queue,
++ * if necessary evicting a lower precedence packet from the queue.
++ *
++ * 'prec' is the precedence number that has already been mapped
++ * from the packet priority.
++ *
++ * Returns true if packet consumed (queued), false if not.
++ */
++static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q,
++		      struct sk_buff *pkt, int prec)
++{
++	return brcms_c_prec_enq_head(wlc, q, pkt, prec, false);
++}
++
++void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++		     struct sk_buff *sdu, uint prec)
++{
++	struct brcms_txq_info *qi = wlc->pkt_queue;	/* Check me */
++	struct pktq *q = &qi->q;
++	int prio;
++
++	prio = sdu->priority;
++
++	if (!brcms_c_prec_enq(wlc, q, sdu, prec)) {
++		/*
++		 * we might hit this condtion in case
++		 * packet flooding from mac80211 stack
++		 */
++		brcmu_pkt_buf_free_skb(sdu);
++	}
++}
++
++/*
++ * bcmc_fid_generate:
++ * Generate frame ID for a BCMC packet.  The frag field is not used
++ * for MC frames so is used as part of the sequence number.
++ */
++static inline u16
++bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg,
++		  struct d11txh *txh)
++{
++	u16 frameid;
++
++	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
++						  TXFID_QUEUE_MASK);
++	frameid |=
++	    (((wlc->
++	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++	    TX_BCMC_FIFO;
++
++	return frameid;
++}
++
++static uint
++brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	uint dur = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
++	dur =
++	    brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				(DOT11_ACK_LEN + FCS_LEN));
++	return dur;
++}
++
++static uint
++brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec,
++		      u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
++		wlc->pub->unit, rspec, preamble_type);
++	return brcms_c_calc_ack_time(wlc, rspec, preamble_type);
++}
++
++static uint
++brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec,
++		     u8 preamble_type)
++{
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
++		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
++	/*
++	 * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that
++	 * is less than or equal to the rate of the immediately previous
++	 * frame in the FES
++	 */
++	rspec = brcms_basic_rate(wlc, rspec);
++	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
++	return brcms_c_calc_frame_time(wlc, rspec, preamble_type,
++				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
++				    FCS_LEN));
++}
++
++/* brcms_c_compute_frame_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for MPDU
++ * DUR for a single frame = 1 SIFS + 1 ACK
++ * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
++ *
++ * rate			MPDU rate in unit of 500kbps
++ * next_frag_len	next MPDU length in bytes
++ * preamble_type	use short/GF or long/MM PLCP header
++ */
++static u16
++brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate,
++		      u8 preamble_type, uint next_frag_len)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	dur = sifs;
++	dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type);
++
++	if (next_frag_len) {
++		/* Double the current DUR to get 2 SIFS + 2 ACKs */
++		dur *= 2;
++		/* add another SIFS and the frag time */
++		dur += sifs;
++		dur +=
++		    (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type,
++						 next_frag_len);
++	}
++	return dur;
++}
++
++/* The opposite of brcms_c_calc_frame_time */
++static uint
++brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec,
++		   u8 preamble_type, uint dur)
++{
++	uint nsyms, mac_len, Ndps, kNdps;
++	uint rate = rspec2rate(ratespec);
++
++	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
++		 wlc->pub->unit, ratespec, preamble_type, dur);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec);
++		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
++		/* payload calculation matches that of regular ofdm */
++		if (wlc->band->bandtype == BRCM_BAND_2G)
++			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
++		/* kNdbps = kbps * 4 */
++		kNdps =	mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * kNdps) -
++		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
++	} else if (is_ofdm_rate(ratespec)) {
++		dur -= APHY_PREAMBLE_TIME;
++		dur -= APHY_SIGNAL_TIME;
++		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
++		Ndps = rate * 2;
++		nsyms = dur / APHY_SYMBOL_TIME;
++		mac_len =
++		    ((nsyms * Ndps) -
++		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
++	} else {
++		if (preamble_type & BRCMS_SHORT_PREAMBLE)
++			dur -= BPHY_PLCP_SHORT_TIME;
++		else
++			dur -= BPHY_PLCP_TIME;
++		mac_len = dur * rate;
++		/* divide out factor of 2 in rate (1/2 mbps) */
++		mac_len = mac_len / 8 / 2;
++	}
++	return mac_len;
++}
++
++/*
++ * Return true if the specified rate is supported by the specified band.
++ * BRCM_BAND_AUTO indicates the current band.
++ */
++static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band,
++		    bool verbose)
++{
++	struct brcms_c_rateset *hw_rateset;
++	uint i;
++
++	if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype))
++		hw_rateset = &wlc->band->hw_rateset;
++	else if (wlc->pub->_nbands > 1)
++		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
++	else
++		/* other band specified and we are a single band device */
++		return false;
++
++	/* check if this is a mimo rate */
++	if (is_mcs_rate(rspec)) {
++		if ((rspec & RSPEC_RATE_MASK) >= MCS_TABLE_SIZE)
++			goto error;
++
++		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
++	}
++
++	for (i = 0; i < hw_rateset->count; i++)
++		if (hw_rateset->rates[i] == rspec2rate(rspec))
++			return true;
++ error:
++	if (verbose)
++		wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x "
++			  "not in hw_rateset\n", wlc->pub->unit, rspec);
++
++	return false;
++}
++
++static u32
++mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band,
++		       u32 int_val)
++{
++	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
++	u8 rate = int_val & NRATE_RATE_MASK;
++	u32 rspec;
++	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
++	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
++	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
++				  == NRATE_OVERRIDE_MCS_ONLY);
++	int bcmerror = 0;
++
++	if (!ismcs)
++		return (u32) rate;
++
++	/* validate the combination of rate/mcs/stf is allowed */
++	if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) {
++		/* mcs only allowed when nmode */
++		if (stf > PHY_TXC1_MODE_SDM) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++
++		/* mcs 32 is a special case, DUP mode 40 only */
++		if (rate == 32) {
++			if (!CHSPEC_IS40(wlc->home_chanspec) ||
++			    ((stf != PHY_TXC1_MODE_SISO)
++			     && (stf != PHY_TXC1_MODE_CDD))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
++					  "32\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++			/* mcs > 7 must use stf SDM */
++		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
++			/* mcs > 7 must use stf SDM */
++			if (stf != PHY_TXC1_MODE_SDM) {
++				BCMMSG(wlc->wiphy, "wl%d: enabling "
++				       "SDM mode for mcs %d\n",
++				       wlc->pub->unit, rate);
++				stf = PHY_TXC1_MODE_SDM;
++			}
++		} else {
++			/*
++			 * MCS 0-7 may use SISO, CDD, and for
++			 * phy_rev >= 3 STBC
++			 */
++			if ((stf > PHY_TXC1_MODE_STBC) ||
++			    (!BRCMS_STBC_CAP_PHY(wlc)
++			     && (stf == PHY_TXC1_MODE_STBC))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
++					  "\n", wlc->pub->unit, __func__);
++				bcmerror = -EINVAL;
++				goto done;
++			}
++		}
++	} else if (is_ofdm_rate(rate)) {
++		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else if (is_cck_rate(rate)) {
++		if ((cur_band->bandtype != BRCM_BAND_2G)
++		    || (stf != PHY_TXC1_MODE_SISO)) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
++				  wlc->pub->unit, __func__);
++			bcmerror = -EINVAL;
++			goto done;
++		}
++	} else {
++		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
++			  wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++	/* make sure multiple antennae are available for non-siso rates */
++	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
++		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
++			  "request\n", wlc->pub->unit, __func__);
++		bcmerror = -EINVAL;
++		goto done;
++	}
++
++	rspec = rate;
++	if (ismcs) {
++		rspec |= RSPEC_MIMORATE;
++		/* For STBC populate the STC field of the ratespec */
++		if (stf == PHY_TXC1_MODE_STBC) {
++			u8 stc;
++			stc = 1;	/* Nss for single stream is always 1 */
++			rspec |= (stc << RSPEC_STC_SHIFT);
++		}
++	}
++
++	rspec |= (stf << RSPEC_STF_SHIFT);
++
++	if (override_mcs_only)
++		rspec |= RSPEC_OVERRIDE_MCS_ONLY;
++
++	if (issgi)
++		rspec |= RSPEC_SHORT_GI;
++
++	if ((rate != 0)
++	    && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true))
++		return rate;
++
++	return rspec;
++done:
++	return rate;
++}
++
++/*
++ * Compute PLCP, but only requires actual rate and length of pkt.
++ * Rate is given in the driver standard multiple of 500 kbps.
++ * le is set for 11 Mbps rate if necessary.
++ * Broken out for PRQ.
++ */
++
++static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500,
++			     uint length, u8 *plcp)
++{
++	u16 usec = 0;
++	u8 le = 0;
++
++	switch (rate_500) {
++	case BRCM_RATE_1M:
++		usec = length << 3;
++		break;
++	case BRCM_RATE_2M:
++		usec = length << 2;
++		break;
++	case BRCM_RATE_5M5:
++		usec = (length << 4) / 11;
++		if ((length << 4) - (usec * 11) > 0)
++			usec++;
++		break;
++	case BRCM_RATE_11M:
++		usec = (length << 3) / 11;
++		if ((length << 3) - (usec * 11) > 0) {
++			usec++;
++			if ((usec * 11) - (length << 3) >= 8)
++				le = D11B_PLCP_SIGNAL_LE;
++		}
++		break;
++
++	default:
++		wiphy_err(wlc->wiphy,
++			  "brcms_c_cck_plcp_set: unsupported rate %d\n",
++			  rate_500);
++		rate_500 = BRCM_RATE_1M;
++		usec = length << 3;
++		break;
++	}
++	/* PLCP signal byte */
++	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
++	/* PLCP service byte */
++	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
++	/* PLCP length u16, little endian */
++	plcp[2] = usec & 0xff;
++	plcp[3] = (usec >> 8) & 0xff;
++	/* PLCP CRC16 */
++	plcp[4] = 0;
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp)
++{
++	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
++	plcp[0] = mcs;
++	if (rspec_is40mhz(rspec) || (mcs == 32))
++		plcp[0] |= MIMO_PLCP_40MHZ;
++	BRCMS_SET_MIMO_PLCP_LEN(plcp, length);
++	plcp[3] = rspec_mimoplcp3(rspec); /* rspec already holds this byte */
++	plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */
++	plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */
++	plcp[5] = 0;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void
++brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp)
++{
++	u8 rate_signal;
++	u32 tmp = 0;
++	int rate = rspec2rate(rspec);
++
++	/*
++	 * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb
++	 * transmitted first
++	 */
++	rate_signal = rate_info[rate] & BRCMS_RATE_MASK;
++	memset(plcp, 0, D11_PHY_HDR_LEN);
++	D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal);
++
++	tmp = (length & 0xfff) << 5;
++	plcp[2] |= (tmp >> 16) & 0xff;
++	plcp[1] |= (tmp >> 8) & 0xff;
++	plcp[0] |= tmp & 0xff;
++}
++
++/* Rate: 802.11 rate code, length: PSDU length in octets */
++static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec,
++				 uint length, u8 *plcp)
++{
++	int rate = rspec2rate(rspec);
++
++	brcms_c_cck_plcp_set(wlc, rate, length, plcp);
++}
++
++static void
++brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec,
++		     uint length, u8 *plcp)
++{
++	if (is_mcs_rate(rspec))
++		brcms_c_compute_mimo_plcp(rspec, length, plcp);
++	else if (is_ofdm_rate(rspec))
++		brcms_c_compute_ofdm_plcp(rspec, length, plcp);
++	else
++		brcms_c_compute_cck_plcp(wlc, rspec, length, plcp);
++}
++
++/* brcms_c_compute_rtscts_dur()
++ *
++ * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
++ * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
++ * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
++ *
++ * cts			cts-to-self or rts/cts
++ * rts_rate		rts or cts rate in unit of 500kbps
++ * rate			next MPDU rate in unit of 500kbps
++ * frame_len		next MPDU frame length in bytes
++ */
++u16
++brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++			   u32 rts_rate,
++			   u32 frame_rate, u8 rts_preamble_type,
++			   u8 frame_preamble_type, uint frame_len, bool ba)
++{
++	u16 dur, sifs;
++
++	sifs = get_sifs(wlc->band);
++
++	if (!cts_only) {
++		/* RTS/CTS */
++		dur = 3 * sifs;
++		dur +=
++		    (u16) brcms_c_calc_cts_time(wlc, rts_rate,
++					       rts_preamble_type);
++	} else {
++		/* CTS-TO-SELF */
++		dur = 2 * sifs;
++	}
++
++	dur +=
++	    (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type,
++					 frame_len);
++	if (ba)
++		dur +=
++		    (u16) brcms_c_calc_ba_time(wlc, frame_rate,
++					      BRCMS_SHORT_PREAMBLE);
++	else
++		dur +=
++		    (u16) brcms_c_calc_ack_time(wlc, frame_rate,
++					       frame_preamble_type);
++	return dur;
++}
++
++static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phyctl1 = 0;
++	u16 bw;
++
++	if (BRCMS_ISLCNPHY(wlc->band)) {
++		bw = PHY_TXC1_BW_20MHZ;
++	} else {
++		bw = rspec_get_bw(rspec);
++		/* 10Mhz is not supported yet */
++		if (bw < PHY_TXC1_BW_20MHZ) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is "
++				  "not supported yet, set to 20L\n", bw);
++			bw = PHY_TXC1_BW_20MHZ;
++		}
++	}
++
++	if (is_mcs_rate(rspec)) {
++		uint mcs = rspec & RSPEC_RATE_MASK;
++
++		/* bw, stf, coding-type is part of rspec_phytxbyte2 returns */
++		phyctl1 = rspec_phytxbyte2(rspec);
++		/* set the upper byte of phyctl1 */
++		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
++	} else if (is_cck_rate(rspec) && !BRCMS_ISLCNPHY(wlc->band)
++		   && !BRCMS_ISSSLPNPHY(wlc->band)) {
++		/*
++		 * In CCK mode LPPHY overloads OFDM Modulation bits with CCK
++		 * Data Rate. Eventually MIMOPHY would also be converted to
++		 * this format
++		 */
++		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
++		phyctl1 = (bw | (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	} else {		/* legacy OFDM/CCK */
++		s16 phycfg;
++		/* get the phyctl byte from rate phycfg table */
++		phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec));
++		if (phycfg == -1) {
++			wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong "
++				  "legacy OFDM/CCK rate\n");
++			phycfg = 0;
++		}
++		/* set the upper byte of phyctl1 */
++		phyctl1 =
++		    (bw | (phycfg << 8) |
++		     (rspec_stf(rspec) << PHY_TXC1_MODE_SHIFT));
++	}
++	return phyctl1;
++}
++
++/*
++ * Add struct d11txh, struct cck_phy_hdr.
++ *
++ * 'p' data must start with 802.11 MAC header
++ * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
++ *
++ * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
++ *
++ */
++static u16
++brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw,
++		     struct sk_buff *p, struct scb *scb, uint frag,
++		     uint nfrags, uint queue, uint next_frag_len)
++{
++	struct ieee80211_hdr *h;
++	struct d11txh *txh;
++	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
++	int len, phylen, rts_phylen;
++	u16 mch, phyctl, xfts, mainrates;
++	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
++	u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	u32 rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M };
++	bool use_rts = false;
++	bool use_cts = false;
++	bool use_rifs = false;
++	bool short_preamble[2] = { false, false };
++	u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE };
++	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
++	struct ieee80211_rts *rts = NULL;
++	bool qos;
++	uint ac;
++	bool hwtkmic = false;
++	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
++#define ANTCFG_NONE 0xFF
++	u8 antcfg = ANTCFG_NONE;
++	u8 fbantcfg = ANTCFG_NONE;
++	uint phyctl1_stf = 0;
++	u16 durid = 0;
++	struct ieee80211_tx_rate *txrate[2];
++	int k;
++	struct ieee80211_tx_info *tx_info;
++	bool is_mcs;
++	u16 mimo_txbw;
++	u8 mimo_preamble_type;
++
++	/* locate 802.11 MAC header */
++	h = (struct ieee80211_hdr *)(p->data);
++	qos = ieee80211_is_data_qos(h->frame_control);
++
++	/* compute length of frame in bytes for use in PLCP computations */
++	len = p->len;
++	phylen = len + FCS_LEN;
++
++	/* Get tx_info */
++	tx_info = IEEE80211_SKB_CB(p);
++
++	/* add PLCP */
++	plcp = skb_push(p, D11_PHY_HDR_LEN);
++
++	/* add Broadcom tx descriptor header */
++	txh = (struct d11txh *) skb_push(p, D11_TXH_LEN);
++	memset(txh, 0, D11_TXH_LEN);
++
++	/* setup frameid */
++	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
++		/* non-AP STA should never use BCMC queue */
++		if (queue == TX_BCMC_FIFO) {
++			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
++				  "TX_BCMC!\n", wlc->pub->unit, __func__);
++			frameid = bcmc_fid_generate(wlc, NULL, txh);
++		} else {
++			/* Increment the counter for first fragment */
++			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
++				scb->seqnum[p->priority]++;
++
++			/* extract fragment number from frame first */
++			seq = le16_to_cpu(h->seq_ctrl) & FRAGNUM_MASK;
++			seq |= (scb->seqnum[p->priority] << SEQNUM_SHIFT);
++			h->seq_ctrl = cpu_to_le16(seq);
++
++			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
++			    (queue & TXFID_QUEUE_MASK);
++		}
++	}
++	frameid |= queue & TXFID_QUEUE_MASK;
++
++	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
++	if (ieee80211_is_beacon(h->frame_control))
++		mcl |= TXC_IGNOREPMQ;
++
++	txrate[0] = tx_info->control.rates;
++	txrate[1] = txrate[0] + 1;
++
++	/*
++	 * if rate control algorithm didn't give us a fallback
++	 * rate, use the primary rate
++	 */
++	if (txrate[1]->idx < 0)
++		txrate[1] = txrate[0];
++
++	for (k = 0; k < hw->max_rates; k++) {
++		is_mcs = txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
++		if (!is_mcs) {
++			if ((txrate[k]->idx >= 0)
++			    && (txrate[k]->idx <
++				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
++				rspec[k] =
++				    hw->wiphy->bands[tx_info->band]->
++				    bitrates[txrate[k]->idx].hw_value;
++				short_preamble[k] =
++				    txrate[k]->
++				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
++				    true : false;
++			} else {
++				rspec[k] = BRCM_RATE_1M;
++			}
++		} else {
++			rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band,
++					NRATE_MCS_INUSE | txrate[k]->idx);
++		}
++
++		/*
++		 * Currently only support same setting for primay and
++		 * fallback rates. Unify flags for each rate into a
++		 * single value for the frame
++		 */
++		use_rts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
++		use_cts |=
++		    txrate[k]->
++		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
++
++
++		/*
++		 * (1) RATE:
++		 *   determine and validate primary rate
++		 *   and fallback rates
++		 */
++		if (!rspec_active(rspec[k])) {
++			rspec[k] = BRCM_RATE_1M;
++		} else {
++			if (!is_multicast_ether_addr(h->addr1)) {
++				/* set tx antenna config */
++				brcms_c_antsel_antcfg_get(wlc->asi, false,
++					false, 0, 0, &antcfg, &fbantcfg);
++			}
++		}
++	}
++
++	phyctl1_stf = wlc->stf->ss_opmode;
++
++	if (wlc->pub->_n_enab & SUPPORT_11N) {
++		for (k = 0; k < hw->max_rates; k++) {
++			/*
++			 * apply siso/cdd to single stream mcs's or ofdm
++			 * if rspec is auto selected
++			 */
++			if (((is_mcs_rate(rspec[k]) &&
++			      is_single_stream(rspec[k] & RSPEC_RATE_MASK)) ||
++			     is_ofdm_rate(rspec[k]))
++			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
++				|| !(rspec[k] & RSPEC_OVERRIDE))) {
++				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
++
++				/* For SISO MCS use STBC if possible */
++				if (is_mcs_rate(rspec[k])
++				    && BRCMS_STF_SS_STBC_TX(wlc, scb)) {
++					u8 stc;
++
++					/* Nss for single stream is always 1 */
++					stc = 1;
++					rspec[k] |= (PHY_TXC1_MODE_STBC <<
++							RSPEC_STF_SHIFT) |
++						    (stc << RSPEC_STC_SHIFT);
++				} else
++					rspec[k] |=
++					    (phyctl1_stf << RSPEC_STF_SHIFT);
++			}
++
++			/*
++			 * Is the phy configured to use 40MHZ frames? If
++			 * so then pick the desired txbw
++			 */
++			if (brcms_chspec_bw(wlc->chanspec) == BRCMS_40_MHZ) {
++				/* default txbw is 20in40 SB */
++				mimo_ctlchbw = mimo_txbw =
++				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
++								 wlc->band->pi))
++				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
++
++				if (is_mcs_rate(rspec[k])) {
++					/* mcs 32 must be 40b/w DUP */
++					if ((rspec[k] & RSPEC_RATE_MASK)
++					    == 32) {
++						mimo_txbw =
++						    PHY_TXC1_BW_40MHZ_DUP;
++						/* use override */
++					} else if (wlc->mimo_40txbw != AUTO)
++						mimo_txbw = wlc->mimo_40txbw;
++					/* else check if dst is using 40 Mhz */
++					else if (scb->flags & SCB_IS40)
++						mimo_txbw = PHY_TXC1_BW_40MHZ;
++				} else if (is_ofdm_rate(rspec[k])) {
++					if (wlc->ofdm_40txbw != AUTO)
++						mimo_txbw = wlc->ofdm_40txbw;
++				} else if (wlc->cck_40txbw != AUTO) {
++					mimo_txbw = wlc->cck_40txbw;
++				}
++			} else {
++				/*
++				 * mcs32 is 40 b/w only.
++				 * This is possible for probe packets on
++				 * a STA during SCAN
++				 */
++				if ((rspec[k] & RSPEC_RATE_MASK) == 32)
++					/* mcs 0 */
++					rspec[k] = RSPEC_MIMORATE;
++
++				mimo_txbw = PHY_TXC1_BW_20MHZ;
++			}
++
++			/* Set channel width */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			if ((k == 0) || ((k > 0) && is_mcs_rate(rspec[k])))
++				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
++			else
++				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++			/* Disable short GI, not supported yet */
++			rspec[k] &= ~RSPEC_SHORT_GI;
++
++			mimo_preamble_type = BRCMS_MM_PREAMBLE;
++			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
++				mimo_preamble_type = BRCMS_GF_PREAMBLE;
++
++			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
++			    && (!is_mcs_rate(rspec[k]))) {
++				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
++					  "RC_MCS != is_mcs_rate(rspec)\n",
++					  wlc->pub->unit, __func__);
++			}
++
++			if (is_mcs_rate(rspec[k])) {
++				preamble_type[k] = mimo_preamble_type;
++
++				/*
++				 * if SGI is selected, then forced mm
++				 * for single stream
++				 */
++				if ((rspec[k] & RSPEC_SHORT_GI)
++				    && is_single_stream(rspec[k] &
++							RSPEC_RATE_MASK))
++					preamble_type[k] = BRCMS_MM_PREAMBLE;
++			}
++
++			/* should be better conditionalized */
++			if (!is_mcs_rate(rspec[0])
++			    && (tx_info->control.rates[0].
++				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
++				preamble_type[k] = BRCMS_SHORT_PREAMBLE;
++		}
++	} else {
++		for (k = 0; k < hw->max_rates; k++) {
++			/* Set ctrlchbw as 20Mhz */
++			rspec[k] &= ~RSPEC_BW_MASK;
++			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
++
++			/* for nphy, stf of ofdm frames must follow policies */
++			if (BRCMS_ISNPHY(wlc->band) && is_ofdm_rate(rspec[k])) {
++				rspec[k] &= ~RSPEC_STF_MASK;
++				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
++			}
++		}
++	}
++
++	/* Reset these for use with AMPDU's */
++	txrate[0]->count = 0;
++	txrate[1]->count = 0;
++
++	/* (2) PROTECTION, may change rspec */
++	if ((ieee80211_is_data(h->frame_control) ||
++	    ieee80211_is_mgmt(h->frame_control)) &&
++	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
++		use_rts = true;
++
++	/* (3) PLCP: determine PLCP header and MAC duration,
++	 * fill struct d11txh */
++	brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp);
++	brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
++	memcpy(&txh->FragPLCPFallback,
++	       plcp_fallback, sizeof(txh->FragPLCPFallback));
++
++	/* Length field now put in CCK FBR CRC field */
++	if (is_cck_rate(rspec[1])) {
++		txh->FragPLCPFallback[4] = phylen & 0xff;
++		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
++	}
++
++	/* MIMO-RATE: need validation ?? */
++	mainrates = is_ofdm_rate(rspec[0]) ?
++			D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) :
++			plcp[0];
++
++	/* DUR field for main rate */
++	if (!ieee80211_is_pspoll(h->frame_control) &&
++	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
++		durid =
++		    brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0],
++					  next_frag_len);
++		h->duration_id = cpu_to_le16(durid);
++	} else if (use_rifs) {
++		/* NAV protect to end of next max packet size */
++		durid =
++		    (u16) brcms_c_calc_frame_time(wlc, rspec[0],
++						 preamble_type[0],
++						 DOT11_MAX_FRAG_LEN);
++		durid += RIFS_11N_TIME;
++		h->duration_id = cpu_to_le16(durid);
++	}
++
++	/* DUR field for fallback rate */
++	if (ieee80211_is_pspoll(h->frame_control))
++		txh->FragDurFallback = h->duration_id;
++	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
++		txh->FragDurFallback = 0;
++	else {
++		durid = brcms_c_compute_frame_dur(wlc, rspec[1],
++					      preamble_type[1], next_frag_len);
++		txh->FragDurFallback = cpu_to_le16(durid);
++	}
++
++	/* (4) MAC-HDR: MacTxControlLow */
++	if (frag == 0)
++		mcl |= TXC_STARTMSDU;
++
++	if (!is_multicast_ether_addr(h->addr1))
++		mcl |= TXC_IMMEDACK;
++
++	if (wlc->band->bandtype == BRCM_BAND_5G)
++		mcl |= TXC_FREQBAND_5G;
++
++	if (CHSPEC_IS40(wlc_phy_chanspec_get(wlc->band->pi)))
++		mcl |= TXC_BW_40;
++
++	/* set AMIC bit if using hardware TKIP MIC */
++	if (hwtkmic)
++		mcl |= TXC_AMIC;
++
++	txh->MacTxControlLow = cpu_to_le16(mcl);
++
++	/* MacTxControlHigh */
++	mch = 0;
++
++	/* Set fallback rate preamble type */
++	if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[1] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[1]) != BRCM_RATE_1M)
++			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
++	}
++
++	/* MacFrameControl */
++	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
++	txh->TxFesTimeNormal = cpu_to_le16(0);
++
++	txh->TxFesTimeFallback = cpu_to_le16(0);
++
++	/* TxFrameRA */
++	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
++
++	/* TxFrameID */
++	txh->TxFrameID = cpu_to_le16(frameid);
++
++	/*
++	 * TxStatus, Note the case of recreating the first frag of a suppressed
++	 * frame then we may need to reset the retry cnt's via the status reg
++	 */
++	txh->TxStatus = cpu_to_le16(status);
++
++	/*
++	 * extra fields for ucode AMPDU aggregation, the new fields are added to
++	 * the END of previous structure so that it's compatible in driver.
++	 */
++	txh->MaxNMpdus = cpu_to_le16(0);
++	txh->MaxABytes_MRT = cpu_to_le16(0);
++	txh->MaxABytes_FBR = cpu_to_le16(0);
++	txh->MinMBytes = cpu_to_le16(0);
++
++	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration,
++	 * furnish struct d11txh */
++	/* RTS PLCP header and RTS frame */
++	if (use_rts || use_cts) {
++		if (use_rts && use_cts)
++			use_cts = false;
++
++		for (k = 0; k < 2; k++) {
++			rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k],
++							      false,
++							      mimo_ctlchbw);
++		}
++
++		if (!is_ofdm_rate(rts_rspec[0]) &&
++		    !((rspec2rate(rts_rspec[0]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
++		}
++
++		if (!is_ofdm_rate(rts_rspec[1]) &&
++		    !((rspec2rate(rts_rspec[1]) == BRCM_RATE_1M) ||
++		      (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) {
++			rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE;
++			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
++		}
++
++		/* RTS/CTS additions to MacTxControlLow */
++		if (use_cts) {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
++		} else {
++			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
++			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
++		}
++
++		/* RTS PLCP header */
++		rts_plcp = txh->RTSPhyHeader;
++		if (use_cts)
++			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
++		else
++			rts_phylen = DOT11_RTS_LEN + FCS_LEN;
++
++		brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
++
++		/* fallback rate version of RTS PLCP header */
++		brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen,
++				 rts_plcp_fallback);
++		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
++		       sizeof(txh->RTSPLCPFallback));
++
++		/* RTS frame fields... */
++		rts = (struct ieee80211_rts *)&txh->rts_frame;
++
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
++					       rspec[0], rts_preamble_type[0],
++					       preamble_type[0], phylen, false);
++		rts->duration = cpu_to_le16(durid);
++		/* fallback rate version of RTS DUR field */
++		durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
++					       rts_rspec[1], rspec[1],
++					       rts_preamble_type[1],
++					       preamble_type[1], phylen, false);
++		txh->RTSDurFallback = cpu_to_le16(durid);
++
++		if (use_cts) {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_CTS);
++
++			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
++		} else {
++			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
++							 IEEE80211_STYPE_RTS);
++
++			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
++		}
++
++		/* mainrate
++		 *    low 8 bits: main frag rate/mcs,
++		 *    high 8 bits: rts/cts rate/mcs
++		 */
++		mainrates |= (is_ofdm_rate(rts_rspec[0]) ?
++				D11A_PHY_HDR_GRATE(
++					(struct ofdm_phy_hdr *) rts_plcp) :
++				rts_plcp[0]) << 8;
++	} else {
++		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
++		memset((char *)&txh->rts_frame, 0,
++			sizeof(struct ieee80211_rts));
++		memset((char *)txh->RTSPLCPFallback, 0,
++		      sizeof(txh->RTSPLCPFallback));
++		txh->RTSDurFallback = 0;
++	}
++
++#ifdef SUPPORT_40MHZ
++	/* add null delimiter count */
++	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && is_mcs_rate(rspec))
++		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
++		   brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
++
++#endif
++
++	/*
++	 * Now that RTS/RTS FB preamble types are updated, write
++	 * the final value
++	 */
++	txh->MacTxControlHigh = cpu_to_le16(mch);
++
++	/*
++	 * MainRates (both the rts and frag plcp rates have
++	 * been calculated now)
++	 */
++	txh->MainRates = cpu_to_le16(mainrates);
++
++	/* XtraFrameTypes */
++	xfts = frametype(rspec[1], wlc->mimoft);
++	xfts |= (frametype(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
++	xfts |= (frametype(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
++	xfts |= CHSPEC_CHANNEL(wlc_phy_chanspec_get(wlc->band->pi)) <<
++							     XFTS_CHANNEL_SHIFT;
++	txh->XtraFrameTypes = cpu_to_le16(xfts);
++
++	/* PhyTxControlWord */
++	phyctl = frametype(rspec[0], wlc->mimoft);
++	if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) ||
++	    (preamble_type[0] == BRCMS_GF_PREAMBLE)) {
++		if (rspec2rate(rspec[0]) != BRCM_RATE_1M)
++			phyctl |= PHY_TXC_SHORT_HDR;
++	}
++
++	/* phytxant is properly bit shifted */
++	phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
++	txh->PhyTxControlWord = cpu_to_le16(phyctl);
++
++	/* PhyTxControlWord_1 */
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		u16 phyctl1 = 0;
++
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]);
++		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
++		phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]);
++		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
++
++		if (use_rts || use_cts) {
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]);
++			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
++			phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]);
++			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
++		}
++
++		/*
++		 * For mcs frames, if mixedmode(overloaded with long preamble)
++		 * is going to be set, fill in non-zero MModeLen and/or
++		 * MModeFbrLen it will be unnecessary if they are separated
++		 */
++		if (is_mcs_rate(rspec[0]) &&
++		    (preamble_type[0] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodelen =
++			    brcms_c_calc_lsig_len(wlc, rspec[0], phylen);
++			txh->MModeLen = cpu_to_le16(mmodelen);
++		}
++
++		if (is_mcs_rate(rspec[1]) &&
++		    (preamble_type[1] == BRCMS_MM_PREAMBLE)) {
++			u16 mmodefbrlen =
++			    brcms_c_calc_lsig_len(wlc, rspec[1], phylen);
++			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
++		}
++	}
++
++	ac = skb_get_queue_mapping(p);
++	if ((scb->flags & SCB_WMECAP) && qos && wlc->edcf_txop[ac]) {
++		uint frag_dur, dur, dur_fallback;
++
++		/* WME: Update TXOP threshold */
++		if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) {
++			frag_dur =
++			    brcms_c_calc_frame_time(wlc, rspec[0],
++					preamble_type[0], phylen);
++
++			if (rts) {
++				/* 1 RTS or CTS-to-self frame */
++				dur =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[0],
++						      rts_preamble_type[0]);
++				dur_fallback =
++				    brcms_c_calc_cts_time(wlc, rts_rspec[1],
++						      rts_preamble_type[1]);
++				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
++				dur += le16_to_cpu(rts->duration);
++				dur_fallback +=
++					le16_to_cpu(txh->RTSDurFallback);
++			} else if (use_rifs) {
++				dur = frag_dur;
++				dur_fallback = 0;
++			} else {
++				/* frame + SIFS + ACK */
++				dur = frag_dur;
++				dur +=
++				    brcms_c_compute_frame_dur(wlc, rspec[0],
++							  preamble_type[0], 0);
++
++				dur_fallback =
++				    brcms_c_calc_frame_time(wlc, rspec[1],
++							preamble_type[1],
++							phylen);
++				dur_fallback +=
++				    brcms_c_compute_frame_dur(wlc, rspec[1],
++							  preamble_type[1], 0);
++			}
++			/* NEED to set TxFesTimeNormal (hard) */
++			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
++			/*
++			 * NEED to set fallback rate version of
++			 * TxFesTimeNormal (hard)
++			 */
++			txh->TxFesTimeFallback =
++				cpu_to_le16((u16) dur_fallback);
++
++			/*
++			 * update txop byte threshold (txop minus intraframe
++			 * overhead)
++			 */
++			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
++				uint newfragthresh;
++
++				newfragthresh =
++				    brcms_c_calc_frame_len(wlc,
++					rspec[0], preamble_type[0],
++					(wlc->edcf_txop[ac] -
++						(dur - frag_dur)));
++				/* range bound the fragthreshold */
++				if (newfragthresh < DOT11_MIN_FRAG_LEN)
++					newfragthresh =
++					    DOT11_MIN_FRAG_LEN;
++				else if (newfragthresh >
++					 wlc->usr_fragthresh)
++					newfragthresh =
++					    wlc->usr_fragthresh;
++				/* update the fragthresh and do txc update */
++				if (wlc->fragthresh[queue] !=
++				    (u16) newfragthresh)
++					wlc->fragthresh[queue] =
++					    (u16) newfragthresh;
++			} else {
++				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
++					  "for rate %d\n",
++					  wlc->pub->unit, fifo_names[queue],
++					  rspec2rate(rspec[0]));
++			}
++
++			if (dur > wlc->edcf_txop[ac])
++				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
++					  "exceeded phylen %d/%d dur %d/%d\n",
++					  wlc->pub->unit, __func__,
++					  fifo_names[queue],
++					  phylen, wlc->fragthresh[queue],
++					  dur, wlc->edcf_txop[ac]);
++		}
++	}
++
++	return 0;
++}
++
++void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
++			      struct ieee80211_hw *hw)
++{
++	u8 prio;
++	uint fifo;
++	struct scb *scb = &wlc->pri_scb;
++	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
++
++	/*
++	 * 802.11 standard requires management traffic
++	 * to go at highest priority
++	 */
++	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
++		MAXPRIO;
++	fifo = prio2fifo[prio];
++	if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0))
++		return;
++	brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio));
++	brcms_c_send_q(wlc);
++}
++
++void brcms_c_send_q(struct brcms_c_info *wlc)
++{
++	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
++	int prec;
++	u16 prec_map;
++	int err = 0, i, count;
++	uint fifo;
++	struct brcms_txq_info *qi = wlc->pkt_queue;
++	struct pktq *q = &qi->q;
++	struct ieee80211_tx_info *tx_info;
++
++	prec_map = wlc->tx_prec_map;
++
++	/* Send all the enq'd pkts that we can.
++	 * Dequeue packets with precedence with empty HW fifo only
++	 */
++	while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) {
++		tx_info = IEEE80211_SKB_CB(pkt[0]);
++		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
++			err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec);
++		} else {
++			count = 1;
++			err = brcms_c_prep_pdu(wlc, pkt[0], &fifo);
++			if (!err) {
++				for (i = 0; i < count; i++)
++					brcms_c_txfifo(wlc, fifo, pkt[i], true,
++						       1);
++			}
++		}
++
++		if (err == -EBUSY) {
++			brcmu_pktq_penq_head(q, prec, pkt[0]);
++			/*
++			 * If send failed due to any other reason than a
++			 * change in HW FIFO condition, quit. Otherwise,
++			 * read the new prec_map!
++			 */
++			if (prec_map == wlc->tx_prec_map)
++				break;
++			prec_map = wlc->tx_prec_map;
++		}
++	}
++}
++
++void
++brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p,
++	       bool commit, s8 txpktpend)
++{
++	u16 frameid = INVALIDFID;
++	struct d11txh *txh;
++
++	txh = (struct d11txh *) (p->data);
++
++	/* When a BC/MC frame is being committed to the BCMC fifo
++	 * via DMA (NOT PIO), update ucode or BSS info as appropriate.
++	 */
++	if (fifo == TX_BCMC_FIFO)
++		frameid = le16_to_cpu(txh->TxFrameID);
++
++	/*
++	 * Bump up pending count for if not using rpc. If rpc is
++	 * used, this will be handled in brcms_b_txfifo()
++	 */
++	if (commit) {
++		wlc->core->txpktpend[fifo] += txpktpend;
++		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
++			 txpktpend, wlc->core->txpktpend[fifo]);
++	}
++
++	/* Commit BCMC sequence number in the SHM frame ID location */
++	if (frameid != INVALIDFID) {
++		/*
++		 * To inform the ucode of the last mcast frame posted
++		 * so that it can clear moredata bit
++		 */
++		brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid);
++	}
++
++	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0)
++		wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n");
++}
++
++u32
++brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec,
++			   bool use_rspec, u16 mimo_ctlchbw)
++{
++	u32 rts_rspec = 0;
++
++	if (use_rspec)
++		/* use frame rate as rts rate */
++		rts_rspec = rspec;
++	else if (wlc->band->gmode && wlc->protection->_g && !is_cck_rate(rspec))
++		/* Use 11Mbps as the g protection RTS target rate and fallback.
++		 * Use the brcms_basic_rate() lookup to find the best basic rate
++		 * under the target in case 11 Mbps is not Basic.
++		 * 6 and 9 Mbps are not usually selected by rate selection, but
++		 * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11
++		 * is more robust.
++		 */
++		rts_rspec = brcms_basic_rate(wlc, BRCM_RATE_11M);
++	else
++		/* calculate RTS rate and fallback rate based on the frame rate
++		 * RTS must be sent at a basic rate since it is a
++		 * control frame, sec 9.6 of 802.11 spec
++		 */
++		rts_rspec = brcms_basic_rate(wlc, rspec);
++
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		/* set rts txbw to correct side band */
++		rts_rspec &= ~RSPEC_BW_MASK;
++
++		/*
++		 * if rspec/rspec_fallback is 40MHz, then send RTS on both
++		 * 20MHz channel (DUP), otherwise send RTS on control channel
++		 */
++		if (rspec_is40mhz(rspec) && !is_cck_rate(rts_rspec))
++			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
++		else
++			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
++
++		/* pick siso/cdd as default for ofdm */
++		if (is_ofdm_rate(rts_rspec)) {
++			rts_rspec &= ~RSPEC_STF_MASK;
++			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
++		}
++	}
++	return rts_rspec;
++}
++
++void
++brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend)
++{
++	wlc->core->txpktpend[fifo] -= txpktpend;
++	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
++	       wlc->core->txpktpend[fifo]);
++
++	/* There is more room; mark precedences related to this FIFO sendable */
++	wlc->tx_prec_map |= wlc->fifo2prec_map[fifo];
++
++	/* figure out which bsscfg is being worked on... */
++}
++
++/* Update beacon listen interval in shared memory */
++static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc)
++{
++	/* wake up every DTIM is the default */
++	if (wlc->bcn_li_dtim == 1)
++		brcms_b_write_shm(wlc->hw, M_BCN_LI, 0);
++	else
++		brcms_b_write_shm(wlc->hw, M_BCN_LI,
++			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
++}
++
++static void
++brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr,
++		  u32 *tsf_h_ptr)
++{
++	struct bcma_device *core = wlc_hw->d11core;
++
++	/* read the tsf timer low, then high to get an atomic read */
++	*tsf_l_ptr = bcma_read32(core, D11REGOFFS(tsf_timerlow));
++	*tsf_h_ptr = bcma_read32(core, D11REGOFFS(tsf_timerhigh));
++}
++
++/*
++ * recover 64bit TSF value from the 16bit TSF value in the rx header
++ * given the assumption that the TSF passed in header is within 65ms
++ * of the current tsf.
++ *
++ * 6       5       4       4       3       2       1
++ * 3.......6.......8.......0.......2.......4.......6.......8......0
++ * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
++ *
++ * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
++ * tsf_l is filled in by brcms_b_recv, which is done earlier in the
++ * receive call sequence after rx interrupt. Only the higher 16 bits
++ * are used. Finally, the tsf_h is read from the tsf register.
++ */
++static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc,
++				 struct d11rxhdr *rxh)
++{
++	u32 tsf_h, tsf_l;
++	u16 rx_tsf_0_15, rx_tsf_16_31;
++
++	brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h);
++
++	rx_tsf_16_31 = (u16)(tsf_l >> 16);
++	rx_tsf_0_15 = rxh->RxTSFTime;
++
++	/*
++	 * a greater tsf time indicates the low 16 bits of
++	 * tsf_l wrapped, so decrement the high 16 bits.
++	 */
++	if ((u16)tsf_l < rx_tsf_0_15) {
++		rx_tsf_16_31 -= 1;
++		if (rx_tsf_16_31 == 0xffff)
++			tsf_h -= 1;
++	}
++
++	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
++}
++
++static void
++prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		     struct sk_buff *p,
++		     struct ieee80211_rx_status *rx_status)
++{
++	int preamble;
++	int channel;
++	u32 rspec;
++	unsigned char *plcp;
++
++	/* fill in TSF and flag its presence */
++	rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh);
++	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
++
++	channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
++
++	if (channel > 14) {
++		rx_status->band = IEEE80211_BAND_5GHZ;
++		rx_status->freq = ieee80211_ofdm_chan_to_freq(
++					WF_CHAN_FACTOR_5_G/2, channel);
++
++	} else {
++		rx_status->band = IEEE80211_BAND_2GHZ;
++		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
++	}
++
++	rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
++
++	/* noise */
++	/* qual */
++	rx_status->antenna =
++		(rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
++
++	plcp = p->data;
++
++	rspec = brcms_c_compute_rspec(rxh, plcp);
++	if (is_mcs_rate(rspec)) {
++		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
++		rx_status->flag |= RX_FLAG_HT;
++		if (rspec_is40mhz(rspec))
++			rx_status->flag |= RX_FLAG_40MHZ;
++	} else {
++		switch (rspec2rate(rspec)) {
++		case BRCM_RATE_1M:
++			rx_status->rate_idx = 0;
++			break;
++		case BRCM_RATE_2M:
++			rx_status->rate_idx = 1;
++			break;
++		case BRCM_RATE_5M5:
++			rx_status->rate_idx = 2;
++			break;
++		case BRCM_RATE_11M:
++			rx_status->rate_idx = 3;
++			break;
++		case BRCM_RATE_6M:
++			rx_status->rate_idx = 4;
++			break;
++		case BRCM_RATE_9M:
++			rx_status->rate_idx = 5;
++			break;
++		case BRCM_RATE_12M:
++			rx_status->rate_idx = 6;
++			break;
++		case BRCM_RATE_18M:
++			rx_status->rate_idx = 7;
++			break;
++		case BRCM_RATE_24M:
++			rx_status->rate_idx = 8;
++			break;
++		case BRCM_RATE_36M:
++			rx_status->rate_idx = 9;
++			break;
++		case BRCM_RATE_48M:
++			rx_status->rate_idx = 10;
++			break;
++		case BRCM_RATE_54M:
++			rx_status->rate_idx = 11;
++			break;
++		default:
++			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
++		}
++
++		/*
++		 * For 5GHz, we should decrease the index as it is
++		 * a subset of the 2.4G rates. See bitrates field
++		 * of brcms_band_5GHz_nphy (in mac80211_if.c).
++		 */
++		if (rx_status->band == IEEE80211_BAND_5GHZ)
++			rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET;
++
++		/* Determine short preamble and rate_idx */
++		preamble = 0;
++		if (is_cck_rate(rspec)) {
++			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
++				rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else if (is_ofdm_rate(rspec)) {
++			rx_status->flag |= RX_FLAG_SHORTPRE;
++		} else {
++			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
++				  __func__);
++		}
++	}
++
++	if (plcp3_issgi(plcp[3]))
++		rx_status->flag |= RX_FLAG_SHORT_GI;
++
++	if (rxh->RxStatus1 & RXS_DECERR) {
++		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
++			  __func__);
++	}
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
++		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
++			  __func__);
++	}
++}
++
++static void
++brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
++		struct sk_buff *p)
++{
++	int len_mpdu;
++	struct ieee80211_rx_status rx_status;
++	struct ieee80211_hdr *hdr;
++
++	memset(&rx_status, 0, sizeof(rx_status));
++	prep_mac80211_status(wlc, rxh, p, &rx_status);
++
++	/* mac header+body length, exclude CRC and plcp header */
++	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
++	skb_pull(p, D11_PHY_HDR_LEN);
++	__skb_trim(p, len_mpdu);
++
++	/* unmute transmit */
++	if (wlc->hw->suspended_fifos) {
++		hdr = (struct ieee80211_hdr *)p->data;
++		if (ieee80211_is_beacon(hdr->frame_control))
++			brcms_b_mute(wlc->hw, false);
++	}
++
++	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
++	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
++}
++
++/* calculate frame duration for Mixed-mode L-SIG spoofing, return
++ * number of bytes goes in the length field
++ *
++ * Formula given by HT PHY Spec v 1.13
++ *   len = 3(nsyms + nstream + 3) - 3
++ */
++u16
++brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++		      uint mac_len)
++{
++	uint nsyms, len = 0, kNdps;
++
++	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
++		 wlc->pub->unit, rspec2rate(ratespec), mac_len);
++
++	if (is_mcs_rate(ratespec)) {
++		uint mcs = ratespec & RSPEC_RATE_MASK;
++		int tot_streams = (mcs_2_txstreams(mcs) + 1) +
++				  rspec_stc(ratespec);
++
++		/*
++		 * the payload duration calculation matches that
++		 * of regular ofdm
++		 */
++		/* 1000Ndbps = kbps * 4 */
++		kNdps = mcs_2_rate(mcs, rspec_is40mhz(ratespec),
++				   rspec_issgi(ratespec)) * 4;
++
++		if (rspec_stc(ratespec) == 0)
++			nsyms =
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, kNdps);
++		else
++			/* STBC needs to have even number of symbols */
++			nsyms =
++			    2 *
++			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
++				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
++
++		/* (+3) account for HT-SIG(2) and HT-STF(1) */
++		nsyms += (tot_streams + 3);
++		/*
++		 * 3 bytes/symbol @ legacy 6Mbps rate
++		 * (-3) excluding service bits and tail bits
++		 */
++		len = (3 * nsyms) - 3;
++	}
++
++	return (u16) len;
++}
++
++static void
++brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs;
++	u8 rate;
++	u16 entry_ptr;
++	u8 plcp[D11_PHY_HDR_LEN];
++	u16 dur, sifs;
++	uint i;
++
++	sifs = get_sifs(wlc->band);
++
++	rs_dflt = brcms_c_rateset_get_hwrs(wlc);
++
++	brcms_c_rateset_copy(rs_dflt, &rs);
++	brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams);
++
++	/*
++	 * walk the phy rate table and update MAC core SHM
++	 * basic rate table entries
++	 */
++	for (i = 0; i < rs.count; i++) {
++		rate = rs.rates[i] & BRCMS_RATE_MASK;
++
++		entry_ptr = brcms_b_rate_shm_offset(wlc->hw, rate);
++
++		/* Calculate the Probe Response PLCP for the given rate */
++		brcms_c_compute_plcp(wlc, rate, frame_len, plcp);
++
++		/*
++		 * Calculate the duration of the Probe Response
++		 * frame plus SIFS for the MAC
++		 */
++		dur = (u16) brcms_c_calc_frame_time(wlc, rate,
++						BRCMS_LONG_PREAMBLE, frame_len);
++		dur += sifs;
++
++		/* Update the SHM Rate Table entry Probe Response values */
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS,
++			      (u16) (plcp[0] + (plcp[1] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_PLCP_POS + 2,
++			      (u16) (plcp[2] + (plcp[3] << 8)));
++		brcms_b_write_shm(wlc->hw, entry_ptr + M_RT_PRS_DUR_POS, dur);
++	}
++}
++
++/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
++ *
++ *	PLCP header is 6 bytes.
++ *	802.11 A3 header is 24 bytes.
++ *	Max beacon frame body template length is 112 bytes.
++ *	Max probe resp frame body template length is 110 bytes.
++ *
++ *      *len on input contains the max length of the packet available.
++ *
++ *	The *len value is set to the number of bytes in buf used, and starts
++ *	with the PLCP and included up to, but not including, the 4 byte FCS.
++ */
++static void
++brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
++			 u32 bcn_rspec,
++			 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
++{
++	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
++	struct cck_phy_hdr *plcp;
++	struct ieee80211_mgmt *h;
++	int hdr_len, body_len;
++
++	hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
++
++	/* calc buffer size provided for frame body */
++	body_len = *len - hdr_len;
++	/* return actual size */
++	*len = hdr_len + body_len;
++
++	/* format PHY and MAC headers */
++	memset((char *)buf, 0, hdr_len);
++
++	plcp = (struct cck_phy_hdr *) buf;
++
++	/*
++	 * PLCP for Probe Response frames are filled in from
++	 * core's rate table
++	 */
++	if (type == IEEE80211_STYPE_BEACON)
++		/* fill in PLCP */
++		brcms_c_compute_plcp(wlc, bcn_rspec,
++				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
++				 (u8 *) plcp);
++
++	/* "Regular" and 16 MBSS but not for 4 MBSS */
++	/* Update the phytxctl for the beacon based on the rspec */
++	brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
++
++	h = (struct ieee80211_mgmt *)&plcp[1];
++
++	/* fill in 802.11 header */
++	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
++
++	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
++	/* A1 filled in by MAC for prb resp, broadcast for bcn */
++	if (type == IEEE80211_STYPE_BEACON)
++		memcpy(&h->da, &ether_bcast, ETH_ALEN);
++	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
++	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
++
++	/* SEQ filled in by MAC */
++}
++
++int brcms_c_get_header_len(void)
++{
++	return TXOFF;
++}
++
++/*
++ * Update all beacons for the system.
++ */
++void brcms_c_update_beacon(struct brcms_c_info *wlc)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	if (bsscfg->up && !bsscfg->BSS)
++		/* Clear the soft intmask */
++		wlc->defmacintmask &= ~MI_BCNTPL;
++}
++
++/* Write ssid into shared memory */
++static void
++brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
++{
++	u8 *ssidptr = cfg->SSID;
++	u16 base = M_SSID;
++	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
++
++	/* padding the ssid with zero and copy it into shm */
++	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
++	memcpy(ssidbuf, ssidptr, cfg->SSID_len);
++
++	brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
++	brcms_b_write_shm(wlc->hw, M_SSIDLEN, (u16) cfg->SSID_len);
++}
++
++static void
++brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
++			      struct brcms_bss_cfg *cfg,
++			      bool suspend)
++{
++	u16 prb_resp[BCN_TMPL_LEN / 2];
++	int len = BCN_TMPL_LEN;
++
++	/*
++	 * write the probe response to hardware, or save in
++	 * the config structure
++	 */
++
++	/* create the probe response template */
++	brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
++				 cfg, prb_resp, &len);
++
++	if (suspend)
++		brcms_c_suspend_mac_and_wait(wlc);
++
++	/* write the probe response into the template region */
++	brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
++				    (len + 3) & ~3, prb_resp);
++
++	/* write the length of the probe response frame (+PLCP/-FCS) */
++	brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
++
++	/* write the SSID and SSID length */
++	brcms_c_shm_ssid_upd(wlc, cfg);
++
++	/*
++	 * Write PLCP headers and durations for probe response frames
++	 * at all rates. Use the actual frame length covered by the
++	 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
++	 * by subtracting the PLCP len and adding the FCS.
++	 */
++	len += (-D11_PHY_HDR_LEN + FCS_LEN);
++	brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
++
++	if (suspend)
++		brcms_c_enable_mac(wlc);
++}
++
++void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
++{
++	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
++
++	/* update AP or IBSS probe responses */
++	if (bsscfg->up && !bsscfg->BSS)
++		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
++}
++
++/* prepares pdu for transmission. returns BCM error codes */
++int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop)
++{
++	uint fifo;
++	struct d11txh *txh;
++	struct ieee80211_hdr *h;
++	struct scb *scb;
++
++	txh = (struct d11txh *) (pdu->data);
++	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
++
++	/* get the pkt queue info. This was put at brcms_c_sendctl or
++	 * brcms_c_send for PDU */
++	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
++
++	scb = NULL;
++
++	*fifop = fifo;
++
++	/* return if insufficient dma resources */
++	if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) {
++		/* Mark precedences related to this FIFO, unsendable */
++		/* A fifo is full. Clear precedences related to that FIFO */
++		wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]);
++		return -EBUSY;
++	}
++	return 0;
++}
++
++int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++			   uint *blocks)
++{
++	if (fifo >= NFIFO)
++		return -EINVAL;
++
++	*blocks = wlc_hw->xmtfifo_sz[fifo];
++
++	return 0;
++}
++
++void
++brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset,
++		  const u8 *addr)
++{
++	brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr);
++	if (match_reg_offset == RCM_BSSID_OFFSET)
++		memcpy(wlc->bsscfg->BSSID, addr, ETH_ALEN);
++}
++
++/*
++ * Flag 'scan in progress' to withhold dynamic phy calibration
++ */
++void brcms_c_scan_start(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
++}
++
++void brcms_c_scan_stop(struct brcms_c_info *wlc)
++{
++	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
++}
++
++void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state)
++{
++	wlc->pub->associated = state;
++	wlc->bsscfg->associated = state;
++}
++
++/*
++ * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
++ * AMPDU traffic, packets pending in hardware have to be invalidated so that
++ * when later on hardware releases them, they can be handled appropriately.
++ */
++void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn))
++{
++	struct dma_pub *dmah;
++	int i;
++	for (i = 0; i < NFIFO; i++) {
++		dmah = hw->di[i];
++		if (dmah != NULL)
++			dma_walk_packets(dmah, dma_callback_fn, sta);
++	}
++}
++
++int brcms_c_get_curband(struct brcms_c_info *wlc)
++{
++	return wlc->band->bandunit;
++}
++
++void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
++{
++	int timeout = 20;
++
++	/* flush packet queue when requested */
++	if (drop)
++		brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
++
++	/* wait for queue and DMA fifos to run dry */
++	while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
++		brcms_msleep(wlc->wl, 1);
++
++		if (--timeout == 0)
++			break;
++	}
++
++	WARN_ON_ONCE(timeout == 0);
++}
++
++void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
++{
++	wlc->bcn_li_bcn = interval;
++	if (wlc->pub->up)
++		brcms_c_bcn_li_upd(wlc);
++}
++
++int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr)
++{
++	uint qdbm;
++
++	/* Remove override bit and clip to max qdbm value */
++	qdbm = min_t(uint, txpwr * BRCMS_TXPWR_DB_FACTOR, 0xff);
++	return wlc_phy_txpower_set(wlc->band->pi, qdbm, false);
++}
++
++int brcms_c_get_tx_power(struct brcms_c_info *wlc)
++{
++	uint qdbm;
++	bool override;
++
++	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
++
++	/* Return qdbm units */
++	return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
++{
++	struct d11rxhdr *rxh;
++	struct ieee80211_hdr *h;
++	uint len;
++	bool is_amsdu;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/* frame starts with rxhdr */
++	rxh = (struct d11rxhdr *) (p->data);
++
++	/* strip off rxhdr */
++	skb_pull(p, BRCMS_HWRXOFF);
++
++	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
++	if (rxh->RxStatus1 & RXS_PBPRES) {
++		if (p->len < 2) {
++			wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of "
++				  "len %d\n", wlc->pub->unit, p->len);
++			goto toss;
++		}
++		skb_pull(p, 2);
++	}
++
++	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
++	len = p->len;
++
++	if (rxh->RxStatus1 & RXS_FCSERR) {
++		if (!(wlc->filter_flags & FIF_FCSFAIL))
++			goto toss;
++	}
++
++	/* check received pkt has at least frame control field */
++	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control))
++		goto toss;
++
++	/* not supporting A-MSDU */
++	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
++	if (is_amsdu)
++		goto toss;
++
++	brcms_c_recvctl(wlc, rxh, p);
++	return;
++
++ toss:
++	brcmu_pkt_buf_free_skb(p);
++}
++
++/* Process received frames */
++/*
++ * Return true if more frames need to be processed. false otherwise.
++ * Param 'bound' indicates max. # frames to process before break out.
++ */
++static bool
++brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
++{
++	struct sk_buff *p;
++	struct sk_buff *next = NULL;
++	struct sk_buff_head recv_frames;
++
++	uint n = 0;
++	uint bound_limit = bound ? RXBND : -1;
++
++	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
++	skb_queue_head_init(&recv_frames);
++
++	/* gather received frames */
++	while (dma_rx(wlc_hw->di[fifo], &recv_frames)) {
++
++		/* !give others some time to run! */
++		if (++n >= bound_limit)
++			break;
++	}
++
++	/* post more rbufs */
++	dma_rxfill(wlc_hw->di[fifo]);
++
++	/* process each frame */
++	skb_queue_walk_safe(&recv_frames, p, next) {
++		struct d11rxhdr_le *rxh_le;
++		struct d11rxhdr *rxh;
++
++		skb_unlink(p, &recv_frames);
++		rxh_le = (struct d11rxhdr_le *)p->data;
++		rxh = (struct d11rxhdr *)p->data;
++
++		/* fixup rx header endianness */
++		rxh->RxFrameSize = le16_to_cpu(rxh_le->RxFrameSize);
++		rxh->PhyRxStatus_0 = le16_to_cpu(rxh_le->PhyRxStatus_0);
++		rxh->PhyRxStatus_1 = le16_to_cpu(rxh_le->PhyRxStatus_1);
++		rxh->PhyRxStatus_2 = le16_to_cpu(rxh_le->PhyRxStatus_2);
++		rxh->PhyRxStatus_3 = le16_to_cpu(rxh_le->PhyRxStatus_3);
++		rxh->PhyRxStatus_4 = le16_to_cpu(rxh_le->PhyRxStatus_4);
++		rxh->PhyRxStatus_5 = le16_to_cpu(rxh_le->PhyRxStatus_5);
++		rxh->RxStatus1 = le16_to_cpu(rxh_le->RxStatus1);
++		rxh->RxStatus2 = le16_to_cpu(rxh_le->RxStatus2);
++		rxh->RxTSFTime = le16_to_cpu(rxh_le->RxTSFTime);
++		rxh->RxChan = le16_to_cpu(rxh_le->RxChan);
++
++		brcms_c_recv(wlc_hw->wlc, p);
++	}
++
++	return n >= bound_limit;
++}
++
++/* second-level interrupt processing
++ *   Return true if another dpc needs to be re-scheduled. false otherwise.
++ *   Param 'bounded' indicates if applicable loops should be bounded.
++ */
++bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
++{
++	u32 macintstatus;
++	struct brcms_hardware *wlc_hw = wlc->hw;
++	struct bcma_device *core = wlc_hw->d11core;
++	struct wiphy *wiphy = wlc->wiphy;
++
++	if (brcms_deviceremoved(wlc)) {
++		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
++			  __func__);
++		brcms_down(wlc->wl);
++		return false;
++	}
++
++	/* grab and clear the saved software intstatus bits */
++	macintstatus = wlc->macintstatus;
++	wlc->macintstatus = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
++	       wlc_hw->unit, macintstatus);
++
++	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
++
++	/* tx status */
++	if (macintstatus & MI_TFS) {
++		bool fatal;
++		if (brcms_b_txstatus(wlc->hw, bounded, &fatal))
++			wlc->macintstatus |= MI_TFS;
++		if (fatal) {
++			wiphy_err(wiphy, "MI_TFS: fatal\n");
++			goto fatal;
++		}
++	}
++
++	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
++		brcms_c_tbtt(wlc);
++
++	/* ATIM window end */
++	if (macintstatus & MI_ATIMWINEND) {
++		BCMMSG(wlc->wiphy, "end of ATIM window\n");
++		bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid);
++		wlc->qvalid = 0;
++	}
++
++	/*
++	 * received data or control frame, MI_DMAINT is
++	 * indication of RX_FIFO interrupt
++	 */
++	if (macintstatus & MI_DMAINT)
++		if (brcms_b_recv(wlc_hw, RX_FIFO, bounded))
++			wlc->macintstatus |= MI_DMAINT;
++
++	/* noise sample collected */
++	if (macintstatus & MI_BG_NOISE)
++		wlc_phy_noise_sample_intr(wlc_hw->band->pi);
++
++	if (macintstatus & MI_GP0) {
++		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
++			  "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
++
++		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
++			    __func__, ai_get_chip_id(wlc_hw->sih),
++			    ai_get_chiprev(wlc_hw->sih));
++		brcms_fatal_error(wlc_hw->wlc->wl);
++	}
++
++	/* gptimer timeout */
++	if (macintstatus & MI_TO)
++		bcma_write32(core, D11REGOFFS(gptimer), 0);
++
++	if (macintstatus & MI_RFDISABLE) {
++		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
++		       " RF Disable Input\n", wlc_hw->unit);
++		brcms_rfkill_set_hw_state(wlc->wl);
++	}
++
++	/* send any enq'd tx packets. Just makes sure to jump start tx */
++	if (!pktq_empty(&wlc->pkt_queue->q))
++		brcms_c_send_q(wlc);
++
++	/* it isn't done and needs to be resched if macintstatus is non-zero */
++	return wlc->macintstatus != 0;
++
++ fatal:
++	brcms_fatal_error(wlc_hw->wlc->wl);
++	return wlc->macintstatus != 0;
++}
++
++void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
++{
++	struct bcma_device *core = wlc->hw->d11core;
++	u16 chanspec;
++
++	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
++
++	/*
++	 * This will happen if a big-hammer was executed. In
++	 * that case, we want to go back to the channel that
++	 * we were on and not new channel
++	 */
++	if (wlc->pub->associated)
++		chanspec = wlc->home_chanspec;
++	else
++		chanspec = brcms_c_init_chanspec(wlc);
++
++	brcms_b_init(wlc->hw, chanspec);
++
++	/* update beacon listen interval */
++	brcms_c_bcn_li_upd(wlc);
++
++	/* write ethernet address to core */
++	brcms_c_set_mac(wlc->bsscfg);
++	brcms_c_set_bssid(wlc->bsscfg);
++
++	/* Update tsf_cfprep if associated and up */
++	if (wlc->pub->associated && wlc->bsscfg->up) {
++		u32 bi;
++
++		/* get beacon period and convert to uS */
++		bi = wlc->bsscfg->current_bss->beacon_period << 10;
++		/*
++		 * update since init path would reset
++		 * to default value
++		 */
++		bcma_write32(core, D11REGOFFS(tsf_cfprep),
++			     bi << CFPREP_CBI_SHIFT);
++
++		/* Update maccontrol PM related bits */
++		brcms_c_set_ps_ctrl(wlc);
++	}
++
++	brcms_c_bandinit_ordered(wlc, chanspec);
++
++	/* init probe response timeout */
++	brcms_b_write_shm(wlc->hw, M_PRS_MAXTIME, wlc->prb_resp_timeout);
++
++	/* init max burst txop (framebursting) */
++	brcms_b_write_shm(wlc->hw, M_MBURST_TXOP,
++		      (wlc->
++		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
++
++	/* initialize maximum allowed duty cycle */
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
++	brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
++
++	/*
++	 * Update some shared memory locations related to
++	 * max AMPDU size allowed to received
++	 */
++	brcms_c_ampdu_shm_upd(wlc->ampdu);
++
++	/* band-specific inits */
++	brcms_c_bsinit(wlc);
++
++	/* Enable EDCF mode (while the MAC is suspended) */
++	bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF);
++	brcms_c_edcf_setparams(wlc, false);
++
++	/* Init precedence maps for empty FIFOs */
++	brcms_c_tx_prec_map_init(wlc);
++
++	/* read the ucode version if we have not yet done so */
++	if (wlc->ucode_rev == 0) {
++		wlc->ucode_rev =
++		    brcms_b_read_shm(wlc->hw, M_BOM_REV_MAJOR) << NBITS(u16);
++		wlc->ucode_rev |= brcms_b_read_shm(wlc->hw, M_BOM_REV_MINOR);
++	}
++
++	/* ..now really unleash hell (allow the MAC out of suspend) */
++	brcms_c_enable_mac(wlc);
++
++	/* suspend the tx fifos and mute the phy for preism cac time */
++	if (mute_tx)
++		brcms_b_mute(wlc->hw, true);
++
++	/* clear tx flow control */
++	brcms_c_txflowcontrol_reset(wlc);
++
++	/* enable the RF Disable Delay timer */
++	bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT);
++
++	/*
++	 * Initialize WME parameters; if they haven't been set by some other
++	 * mechanism (IOVar, etc) then read them from the hardware.
++	 */
++	if (GFIELD(wlc->wme_retries[0], EDCF_SHORT) == 0) {
++		/* Uninitialized; read from HW */
++		int ac;
++
++		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
++			wlc->wme_retries[ac] =
++			    brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));
++	}
++}
++
++/*
++ * The common driver entry routine. Error codes should be unique
++ */
++struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr)
++{
++	struct brcms_c_info *wlc;
++	uint err = 0;
++	uint i, j;
++	struct brcms_pub *pub;
++
++	/* allocate struct brcms_c_info state and its substructures */
++	wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0);
++	if (wlc == NULL)
++		goto fail;
++	wlc->wiphy = wl->wiphy;
++	pub = wlc->pub;
++
++#if defined(DEBUG)
++	wlc_info_dbg = wlc;
++#endif
++
++	wlc->band = wlc->bandstate[0];
++	wlc->core = wlc->corestate;
++	wlc->wl = wl;
++	pub->unit = unit;
++	pub->_piomode = piomode;
++	wlc->bandinit_pending = false;
++
++	/* populate struct brcms_c_info with default values  */
++	brcms_c_info_init(wlc, unit);
++
++	/* update sta/ap related parameters */
++	brcms_c_ap_upd(wlc);
++
++	/*
++	 * low level attach steps(all hw accesses go
++	 * inside, no more in rest of the attach)
++	 */
++	err = brcms_b_attach(wlc, core, unit, piomode);
++	if (err)
++		goto fail;
++
++	brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, OFF);
++
++	pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band);
++
++	/* disable allowed duty cycle */
++	wlc->tx_duty_cycle_ofdm = 0;
++	wlc->tx_duty_cycle_cck = 0;
++
++	brcms_c_stf_phy_chain_calc(wlc);
++
++	/* txchain 1: txant 0, txchain 2: txant 1 */
++	if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
++		wlc->stf->txant = wlc->stf->hw_txchain - 1;
++
++	/* push to BMAC driver */
++	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
++			       wlc->stf->hw_rxchain);
++
++	/* pull up some info resulting from the low attach */
++	for (i = 0; i < NFIFO; i++)
++		wlc->core->txavail[i] = wlc->hw->txavail[i];
++
++	memcpy(&wlc->perm_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++	memcpy(&pub->cur_etheraddr, &wlc->hw->etheraddr, ETH_ALEN);
++
++	for (j = 0; j < wlc->pub->_nbands; j++) {
++		wlc->band = wlc->bandstate[j];
++
++		if (!brcms_c_attach_stf_ant_init(wlc)) {
++			err = 24;
++			goto fail;
++		}
++
++		/* default contention windows size limits */
++		wlc->band->CWmin = APHY_CWMIN;
++		wlc->band->CWmax = PHY_CWMAX;
++
++		/* init gmode value */
++		if (wlc->band->bandtype == BRCM_BAND_2G) {
++			wlc->band->gmode = GMODE_AUTO;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER,
++					   wlc->band->gmode);
++		}
++
++		/* init _n_enab supported mode */
++		if (BRCMS_PHY_11N_CAP(wlc->band)) {
++			pub->_n_enab = SUPPORT_11N;
++			brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER,
++						   ((pub->_n_enab ==
++						     SUPPORT_11N) ? WL_11N_2x2 :
++						    WL_11N_3x3));
++		}
++
++		/* init per-band default rateset, depend on band->gmode */
++		brcms_default_rateset(wlc, &wlc->band->defrateset);
++
++		/* fill in hw_rateset */
++		brcms_c_rateset_filter(&wlc->band->defrateset,
++				   &wlc->band->hw_rateset, false,
++				   BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK,
++				   (bool) (wlc->pub->_n_enab & SUPPORT_11N));
++	}
++
++	/*
++	 * update antenna config due to
++	 * wlc->stf->txant/txchain/ant_rx_ovr change
++	 */
++	brcms_c_stf_phy_txant_upd(wlc);
++
++	/* attach each modules */
++	err = brcms_c_attach_module(wlc);
++	if (err != 0)
++		goto fail;
++
++	if (!brcms_c_timers_init(wlc, unit)) {
++		wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit,
++			  __func__);
++		err = 32;
++		goto fail;
++	}
++
++	/* depend on rateset, gmode */
++	wlc->cmi = brcms_c_channel_mgr_attach(wlc);
++	if (!wlc->cmi) {
++		wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed"
++			  "\n", unit, __func__);
++		err = 33;
++		goto fail;
++	}
++
++	/* init default when all parameters are ready, i.e. ->rateset */
++	brcms_c_bss_default_init(wlc);
++
++	/*
++	 * Complete the wlc default state initializations..
++	 */
++
++	/* allocate our initial queue */
++	wlc->pkt_queue = brcms_c_txq_alloc(wlc);
++	if (wlc->pkt_queue == NULL) {
++		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
++			  unit, __func__);
++		err = 100;
++		goto fail;
++	}
++
++	wlc->bsscfg->wlc = wlc;
++
++	wlc->mimoft = FT_HT;
++	wlc->mimo_40txbw = AUTO;
++	wlc->ofdm_40txbw = AUTO;
++	wlc->cck_40txbw = AUTO;
++	brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G);
++
++	/* Set default values of SGI */
++	if (BRCMS_SGI_CAP_PHY(wlc)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else if (BRCMS_ISSSLPNPHY(wlc->band)) {
++		brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 |
++					       BRCMS_N_SGI_40));
++	} else {
++		brcms_c_ht_update_sgi_rx(wlc, 0);
++	}
++
++	brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
++
++	if (perr)
++		*perr = 0;
++
++	return wlc;
++
++ fail:
++	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
++		  unit, __func__, err);
++	if (wlc)
++		brcms_c_detach(wlc);
++
++	if (perr)
++		*perr = err;
++	return NULL;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+new file mode 100644
+index 0000000..8debc74
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
+@@ -0,0 +1,720 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_MAIN_H_
++#define _BRCM_MAIN_H_
++
++#include <linux/etherdevice.h>
++
++#include <brcmu_utils.h>
++#include "types.h"
++#include "d11.h"
++#include "scb.h"
++
++#define	INVCHANNEL		255	/* invalid channel */
++
++/* max # brcms_c_module_register() calls */
++#define BRCMS_MAXMODULES	22
++
++#define SEQNUM_SHIFT		4
++#define SEQNUM_MAX		0x1000
++
++#define NTXRATE			64	/* # tx MPDUs rate is reported for */
++
++/* Maximum wait time for a MAC suspend */
++/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
++#define	BRCMS_MAX_MAC_SUSPEND	83000
++
++/* responses for probe requests older that this are tossed, zero to disable */
++#define BRCMS_PRB_RESP_TIMEOUT	0	/* Disable probe response timeout */
++
++/* transmit buffer max headroom for protocol headers */
++#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
++
++/* Macros for doing definition and get/set of bitfields
++ * Usage example, e.g. a three-bit field (bits 4-6):
++ *    #define <NAME>_M	BITFIELD_MASK(3)
++ *    #define <NAME>_S	4
++ * ...
++ *    regval = R_REG(osh, &regs->regfoo);
++ *    field = GFIELD(regval, <NAME>);
++ *    regval = SFIELD(regval, <NAME>, 1);
++ *    W_REG(osh, &regs->regfoo, regval);
++ */
++#define BITFIELD_MASK(width) \
++		(((unsigned)1 << (width)) - 1)
++#define GFIELD(val, field) \
++		(((val) >> field ## _S) & field ## _M)
++#define SFIELD(val, field, bits) \
++		(((val) & (~(field ## _M << field ## _S))) | \
++		 ((unsigned)(bits) << field ## _S))
++
++#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */
++
++/* max # supported core revisions (0 .. MAXCOREREV - 1) */
++#define	MAXCOREREV		28
++
++/* Double check that unsupported cores are not enabled */
++#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
++#error "Configuration for D11CONF includes unsupported versions."
++#endif				/* Bad versions */
++
++/* values for shortslot_override */
++#define BRCMS_SHORTSLOT_AUTO	-1 /* Driver will manage Shortslot setting */
++#define BRCMS_SHORTSLOT_OFF	0  /* Turn off short slot */
++#define BRCMS_SHORTSLOT_ON	1  /* Turn on short slot */
++
++/* value for short/long and mixmode/greenfield preamble */
++#define BRCMS_LONG_PREAMBLE	(0)
++#define BRCMS_SHORT_PREAMBLE	(1 << 0)
++#define BRCMS_GF_PREAMBLE		(1 << 1)
++#define BRCMS_MM_PREAMBLE		(1 << 2)
++#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
++				      ((_pre) == BRCMS_MM_PREAMBLE))
++
++/* TxFrameID */
++/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
++/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
++#define TXFID_QUEUE_MASK	0x0007	/* Bits 0-2 */
++#define TXFID_SEQ_MASK		0x7FE0	/* Bits 5-15 */
++#define TXFID_SEQ_SHIFT		5	/* Number of bit shifts */
++#define	TXFID_RATE_PROBE_MASK	0x8000	/* Bit 15 for rate probe */
++#define TXFID_RATE_MASK		0x0018	/* Mask for bits 3 and 4 */
++#define TXFID_RATE_SHIFT	3	/* Shift 3 bits for rate mask */
++
++/* promote boardrev */
++#define BOARDREV_PROMOTABLE	0xFF	/* from */
++#define BOARDREV_PROMOTED	1	/* to */
++
++#define DATA_BLOCK_TX_SUPR	(1 << 4)
++
++/* 802.1D Priority to TX FIFO number for wme */
++extern const u8 prio2fifo[];
++
++/* Ucode MCTL_WAKE override bits */
++#define BRCMS_WAKE_OVERRIDE_CLKCTL	0x01
++#define BRCMS_WAKE_OVERRIDE_PHYREG	0x02
++#define BRCMS_WAKE_OVERRIDE_MACSUSPEND	0x04
++#define BRCMS_WAKE_OVERRIDE_TXFIFO	0x08
++#define BRCMS_WAKE_OVERRIDE_FORCEFAST	0x10
++
++/* stuff pulled in from wlc.c */
++
++/* Interrupt bit error summary.  Don't include I_RU: we refill DMA at other
++ * times; and if we run out, constant I_RU interrupts may cause lockup.  We
++ * will still get error counts from rx0ovfl.
++ */
++#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RO | I_XU)
++/* default software intmasks */
++#define	DEF_RXINTMASK	(I_RI)	/* enable rx int on rxfifo only */
++#define	DEF_MACINTMASK	(MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
++			 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
++			 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
++
++#define	MAXTXPKTS		6	/* max # pkts pending */
++
++/* frameburst */
++#define	MAXTXFRAMEBURST		8 /* vanilla xpress mode: max frames/burst */
++#define	MAXFRAMEBURST_TXOP	10000	/* Frameburst TXOP in usec */
++
++#define	NFIFO			6	/* # tx/rx fifopairs */
++
++/* PLL requests */
++
++/* pll is shared on old chips */
++#define BRCMS_PLLREQ_SHARED	0x1
++/* hold pll for radio monitor register checking */
++#define BRCMS_PLLREQ_RADIO_MON	0x2
++/* hold/release pll for some short operation */
++#define BRCMS_PLLREQ_FLIP		0x4
++
++#define	CHANNEL_BANDUNIT(wlc, ch) \
++	(((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
++
++#define	OTHERBANDUNIT(wlc) \
++	((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
++
++/*
++ * 802.11 protection information
++ *
++ * _g: use g spec protection, driver internal.
++ * g_override: override for use of g spec protection.
++ * gmode_user: user config gmode, operating band->gmode is different.
++ * overlap: Overlap BSS/IBSS protection for both 11g and 11n.
++ * nmode_user: user config nmode, operating pub->nmode is different.
++ * n_cfg: use OFDM protection on MIMO frames.
++ * n_cfg_override: override for use of N protection.
++ * nongf: non-GF present protection.
++ * nongf_override: override for use of GF protection.
++ * n_pam_override: override for preamble: MM or GF.
++ * n_obss: indicated OBSS Non-HT STA present.
++*/
++struct brcms_protection {
++	bool _g;
++	s8 g_override;
++	u8 gmode_user;
++	s8 overlap;
++	s8 nmode_user;
++	s8 n_cfg;
++	s8 n_cfg_override;
++	bool nongf;
++	s8 nongf_override;
++	s8 n_pam_override;
++	bool n_obss;
++};
++
++/*
++ * anything affecting the single/dual streams/antenna operation
++ *
++ * hw_txchain: HW txchain bitmap cfg.
++ * txchain: txchain bitmap being used.
++ * txstreams: number of txchains being used.
++ * hw_rxchain: HW rxchain bitmap cfg.
++ * rxchain: rxchain bitmap being used.
++ * rxstreams: number of rxchains being used.
++ * ant_rx_ovr: rx antenna override.
++ * txant: userTx antenna setting.
++ * phytxant: phyTx antenna setting in txheader.
++ * ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
++ * ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
++ *			else use wlc->band->stf->ss_mode_band.
++ * ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
++ * rxchain_restore_delay: delay time to restore default rxchain.
++ * ldpc: AUTO/ON/OFF ldpc cap supported.
++ * txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
++ * spatial_policy:
++ */
++struct brcms_stf {
++	u8 hw_txchain;
++	u8 txchain;
++	u8 txstreams;
++	u8 hw_rxchain;
++	u8 rxchain;
++	u8 rxstreams;
++	u8 ant_rx_ovr;
++	s8 txant;
++	u16 phytxant;
++	u8 ss_opmode;
++	bool ss_algosel_auto;
++	u16 ss_algo_channel;
++	u8 rxchain_restore_delay;
++	s8 ldpc;
++	u8 txcore[MAX_STREAMS_SUPPORTED + 1];
++	s8 spatial_policy;
++};
++
++#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
++	(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
++	 || (((scb)->flags & SCB_STBCCAP) && \
++	     (wlc)->band->band_stf_stbc_tx == AUTO && \
++	     isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
++
++#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3))
++
++#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
++				 NREV_GE(wlc->band->phyrev, 3)) || \
++				BRCMS_ISLCNPHY(wlc->band))
++
++#define BRCMS_CHAN_PHYTYPE(x)     (((x) & RXS_CHAN_PHYTYPE_MASK) \
++				   >> RXS_CHAN_PHYTYPE_SHIFT)
++#define BRCMS_CHAN_CHANNEL(x)     (((x) & RXS_CHAN_ID_MASK) \
++				   >> RXS_CHAN_ID_SHIFT)
++
++/*
++ * core state (mac)
++ */
++struct brcms_core {
++	uint coreidx;		/* # sb enumerated core */
++
++	/* fifo */
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	s16 txpktpend[NFIFO];	/* tx admission control */
++
++	struct macstat *macstat_snapshot;	/* mac hw prev read values */
++};
++
++/*
++ * band state (phy+ana+radio)
++ */
++struct brcms_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++
++	u8 gmode;		/* currently active gmode */
++
++	struct scb *hwrs_scb;	/* permanent scb for hw rateset */
++
++	/* band-specific copy of default_bss.rateset */
++	struct brcms_c_rateset defrateset;
++
++	u8 band_stf_ss_mode;	/* Configured STF type, 0:siso; 1:cdd */
++	s8 band_stf_stbc_tx;	/* STBC TX 0:off; 1:force on; -1:auto */
++	/* rates supported by chip (phy-specific) */
++	struct brcms_c_rateset hw_rateset;
++	u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
++	bool mimo_cap_40;	/* 40 MHz cap enabled on this band */
++	s8 antgain;		/* antenna gain from srom */
++
++	u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
++	u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
++	struct ieee80211_supported_band band;
++};
++
++/* module control blocks */
++struct modulecb {
++	/* module name : NULL indicates empty array member */
++	char name[32];
++	/* handle passed when handler 'doiovar' is called */
++	struct brcms_info *hdl;
++
++	int (*down_fn)(void *handle); /* down handler. Note: the int returned
++				       * by the down function is a count of the
++				       * number of timers that could not be
++				       * freed.
++				       */
++
++};
++
++struct brcms_hw_band {
++	int bandtype;		/* BRCM_BAND_2G, BRCM_BAND_5G */
++	uint bandunit;		/* bandstate[] index */
++	u16 mhfs[MHFMAX];	/* MHF array shadow */
++	u8 bandhw_stf_ss_mode;	/* HW configured STF type, 0:siso; 1:cdd */
++	u16 CWmin;
++	u16 CWmax;
++	u32 core_flags;
++
++	u16 phytype;		/* phytype */
++	u16 phyrev;
++	u16 radioid;
++	u16 radiorev;
++	struct brcms_phy_pub *pi; /* pointer to phy specific information */
++	bool abgphy_encore;
++};
++
++struct brcms_hardware {
++	bool _piomode;		/* true if pio mode */
++	struct brcms_c_info *wlc;
++
++	/* fifo */
++	struct dma_pub *di[NFIFO];	/* dma handles, per fifo */
++
++	uint unit;		/* device instance number */
++
++	/* version info */
++	u16 vendorid;	/* PCI vendor id */
++	u16 deviceid;	/* PCI device id */
++	uint corerev;		/* core revision */
++	u8 sromrev;		/* version # of the srom */
++	u16 boardrev;	/* version # of particular board */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	u32 machwcap;	/* MAC capabilities */
++	u32 machwcap_backup;	/* backup of machwcap */
++
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	struct bcma_device *d11core;	/* pointer to 802.11 core */
++	struct phy_shim_info *physhim; /* phy shim layer handler */
++	struct shared_phy *phy_sh;	/* pointer to shared phy state */
++	struct brcms_hw_band *band;/* pointer to active per-band state */
++	/* band state per phy/radio */
++	struct brcms_hw_band *bandstate[MAXBANDS];
++	u16 bmac_phytxant;	/* cache of high phytxant state */
++	bool shortslot;		/* currently using 11g ShortSlot timing */
++	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
++	u16 LRL;		/* 802.11 dot11LongRetryLimit */
++	u16 SFBL;		/* Short Frame Rate Fallback Limit */
++	u16 LFBL;		/* Long Frame Rate Fallback Limit */
++
++	bool up;		/* d11 hardware up and running */
++	uint now;		/* # elapsed seconds */
++	uint _nbands;		/* # bands supported */
++	u16 chanspec;	/* bmac chanspec shadow */
++
++	uint *txavail[NFIFO];	/* # tx descriptors available */
++	const u16 *xmtfifo_sz;	/* fifo size in 256B for each xmt fifo */
++
++	u32 pllreq;		/* pll requests to keep PLL on */
++
++	u8 suspended_fifos;	/* Which TX fifo to remain awake for */
++	u32 maccontrol;	/* Cached value of maccontrol */
++	uint mac_suspend_depth;	/* current depth of mac_suspend levels */
++	u32 wake_override;	/* bit flags to force MAC to WAKE mode */
++	u32 mute_override;	/* Prevent ucode from sending beacons */
++	u8 etheraddr[ETH_ALEN];	/* currently configured ethernet address */
++	bool noreset;		/* true= do not reset hw, used by WLC_OUT */
++	bool forcefastclk;	/* true if h/w is forcing to use fast clk */
++	bool clk;		/* core is out of reset and has clock */
++	bool sbclk;		/* sb has clock */
++	bool phyclk;		/* phy is out of reset and has clock */
++
++	bool ucode_loaded;	/* true after ucode downloaded */
++
++
++	u8 hw_stf_ss_opmode;	/* STF single stream operation mode */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u32 antsel_avail;	/*
++				 * put struct antsel_info here if more info is
++				 * needed
++				 */
++};
++
++/* TX Queue information
++ *
++ * Each flow of traffic out of the device has a TX Queue with independent
++ * flow control. Several interfaces may be associated with a single TX Queue
++ * if they belong to the same flow of traffic from the device. For multi-channel
++ * operation there are independent TX Queues for each channel.
++ */
++struct brcms_txq_info {
++	struct brcms_txq_info *next;
++	struct pktq q;
++	uint stopped;		/* tx flow control bits */
++};
++
++/*
++ * Principal common driver data structure.
++ *
++ * pub: pointer to driver public state.
++ * wl: pointer to specific private state.
++ * hw: HW related state.
++ * clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
++ * fastpwrup_dly: time in us needed to bring up d11 fast clock.
++ * macintstatus: bit channel between isr and dpc.
++ * macintmask: sw runtime master macintmask value.
++ * defmacintmask: default "on" macintmask value.
++ * clk: core is out of reset and has clock.
++ * core: pointer to active io core.
++ * band: pointer to active per-band state.
++ * corestate: per-core state (one per hw core).
++ * bandstate: per-band state (one per phy/radio).
++ * qvalid: DirFrmQValid and BcMcFrmQValid.
++ * ampdu: ampdu module handler.
++ * asi: antsel module handler.
++ * cmi: channel manager module handler.
++ * vendorid: PCI vendor id.
++ * deviceid: PCI device id.
++ * ucode_rev: microcode revision.
++ * machwcap: MAC capabilities, BMAC shadow.
++ * perm_etheraddr: original sprom local ethernet address.
++ * bandlocked: disable auto multi-band switching.
++ * bandinit_pending: track band init in auto band.
++ * radio_monitor: radio timer is running.
++ * going_down: down path intermediate variable.
++ * wdtimer: timer for watchdog routine.
++ * radio_timer: timer for hw radio button monitor routine.
++ * monitor: monitor (MPDU sniffing) mode.
++ * bcnmisc_monitor: bcns promisc mode override for monitor.
++ * _rifs: enable per-packet rifs.
++ * bcn_li_bcn: beacon listen interval in # beacons.
++ * bcn_li_dtim: beacon listen interval in # dtims.
++ * WDarmed: watchdog timer is armed.
++ * WDlast: last time wlc_watchdog() was called.
++ * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.
++ * wme_retries: per-AC retry limits.
++ * tx_prec_map: Precedence map based on HW FIFO space.
++ * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
++ * bsscfg: set of BSS configurations, idx 0 is default and always valid.
++ * cfg: the primary bsscfg (can be AP or STA).
++ * tx_queues: common TX Queue list.
++ * modulecb:
++ * mimoft: SIGN or 11N.
++ * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
++ * ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
++ * mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
++ * default_bss: configured BSS parameters.
++ * mc_fid_counter: BC/MC FIFO frame ID counter.
++ * country_default: saved country for leaving 802.11d auto-country mode.
++ * autocountry_default: initial country for 802.11d auto-country mode.
++ * prb_resp_timeout: do not send prb resp if request older
++ *		     than this, 0 = disable.
++ * home_chanspec: shared home chanspec.
++ * chanspec: target operational channel.
++ * usr_fragthresh: user configured fragmentation threshold.
++ * fragthresh[NFIFO]: per-fifo fragmentation thresholds.
++ * RTSThresh: 802.11 dot11RTSThreshold.
++ * SRL: 802.11 dot11ShortRetryLimit.
++ * LRL: 802.11 dot11LongRetryLimit.
++ * SFBL: Short Frame Rate Fallback Limit.
++ * LFBL: Long Frame Rate Fallback Limit.
++ * shortslot: currently using 11g ShortSlot timing.
++ * shortslot_override: 11g ShortSlot override.
++ * include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
++ * PLCPHdr_override: 802.11b Preamble Type override.
++ * stf:
++ * bcn_rspec: save bcn ratespec purpose.
++ * tempsense_lasttime;
++ * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
++ * tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
++ * pkt_queue: txq for transmit packets.
++ * wiphy:
++ * pri_scb: primary Station Control Block
++ */
++struct brcms_c_info {
++	struct brcms_pub *pub;
++	struct brcms_info *wl;
++	struct brcms_hardware *hw;
++
++	/* clock */
++	u16 fastpwrup_dly;
++
++	/* interrupt */
++	u32 macintstatus;
++	u32 macintmask;
++	u32 defmacintmask;
++
++	bool clk;
++
++	/* multiband */
++	struct brcms_core *core;
++	struct brcms_band *band;
++	struct brcms_core *corestate;
++	struct brcms_band *bandstate[MAXBANDS];
++
++	/* packet queue */
++	uint qvalid;
++
++	struct ampdu_info *ampdu;
++	struct antsel_info *asi;
++	struct brcms_cm_info *cmi;
++
++	u16 vendorid;
++	u16 deviceid;
++	uint ucode_rev;
++
++	u8 perm_etheraddr[ETH_ALEN];
++
++	bool bandlocked;
++	bool bandinit_pending;
++
++	bool radio_monitor;
++	bool going_down;
++
++	struct brcms_timer *wdtimer;
++	struct brcms_timer *radio_timer;
++
++	/* promiscuous */
++	uint filter_flags;
++
++	/* driver feature */
++	bool _rifs;
++
++	/* AP-STA synchronization, power save */
++	u8 bcn_li_bcn;
++	u8 bcn_li_dtim;
++
++	bool WDarmed;
++	u32 WDlast;
++
++	/* WME */
++	u16 edcf_txop[IEEE80211_NUM_ACS];
++
++	u16 wme_retries[IEEE80211_NUM_ACS];
++	u16 tx_prec_map;
++	u16 fifo2prec_map[NFIFO];
++
++	struct brcms_bss_cfg *bsscfg;
++
++	/* tx queue */
++	struct brcms_txq_info *tx_queues;
++
++	struct modulecb *modulecb;
++
++	u8 mimoft;
++	s8 cck_40txbw;
++	s8 ofdm_40txbw;
++	s8 mimo_40txbw;
++
++	struct brcms_bss_info *default_bss;
++
++	u16 mc_fid_counter;
++
++	char country_default[BRCM_CNTRY_BUF_SZ];
++	char autocountry_default[BRCM_CNTRY_BUF_SZ];
++	u16 prb_resp_timeout;
++
++	u16 home_chanspec;
++
++	/* PHY parameters */
++	u16 chanspec;
++	u16 usr_fragthresh;
++	u16 fragthresh[NFIFO];
++	u16 RTSThresh;
++	u16 SRL;
++	u16 LRL;
++	u16 SFBL;
++	u16 LFBL;
++
++	/* network config */
++	bool shortslot;
++	s8 shortslot_override;
++	bool include_legacy_erp;
++
++	struct brcms_protection *protection;
++	s8 PLCPHdr_override;
++
++	struct brcms_stf *stf;
++
++	u32 bcn_rspec;
++
++	uint tempsense_lasttime;
++
++	u16 tx_duty_cycle_ofdm;
++	u16 tx_duty_cycle_cck;
++
++	struct brcms_txq_info *pkt_queue;
++	struct wiphy *wiphy;
++	struct scb pri_scb;
++};
++
++/* antsel module specific state */
++struct antsel_info {
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_pub *pub;		/* pointer to public fn */
++	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
++				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
++				 */
++	u8 antsel_antswitch;	/* board level antenna switch type */
++	bool antsel_avail;	/* Ant selection availability (SROM based) */
++	struct brcms_antselcfg antcfg_11n; /* antenna configuration */
++	struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
++};
++
++/*
++ * BSS configuration state
++ *
++ * wlc: wlc to which this bsscfg belongs to.
++ * up: is this configuration up operational
++ * enable: is this configuration enabled
++ * associated: is BSS in ASSOCIATED state
++ * BSS: infraustructure or adhoc
++ * SSID_len: the length of SSID
++ * SSID: SSID string
++ *
++ *
++ * BSSID: BSSID (associated)
++ * cur_etheraddr: h/w address
++ * flags: BSSCFG flags; see below
++ *
++ * current_bss: BSS parms in ASSOCIATED state
++ *
++ *
++ * ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
++ */
++struct brcms_bss_cfg {
++	struct brcms_c_info *wlc;
++	bool up;
++	bool enable;
++	bool associated;
++	bool BSS;
++	u8 SSID_len;
++	u8 SSID[IEEE80211_MAX_SSID_LEN];
++	u8 BSSID[ETH_ALEN];
++	u8 cur_etheraddr[ETH_ALEN];
++	struct brcms_bss_info *current_bss;
++};
++
++extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
++			   struct sk_buff *p,
++			   bool commit, s8 txpktpend);
++extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
++				    s8 txpktpend);
++extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
++			    struct sk_buff *sdu, uint prec);
++extern void brcms_c_print_txstatus(struct tx_status *txs);
++extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
++		   uint *blocks);
++
++#if defined(DEBUG)
++extern void brcms_c_print_txdesc(struct d11txh *txh);
++#else
++static inline void brcms_c_print_txdesc(struct d11txh *txh)
++{
++}
++#endif
++
++extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
++extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
++extern void brcms_c_send_q(struct brcms_c_info *wlc);
++extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
++			    uint *fifo);
++extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
++				uint mac_len);
++extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
++					     u32 rspec,
++					     bool use_rspec, u16 mimo_ctlchbw);
++extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
++				      u32 rts_rate,
++				      u32 frame_rate,
++				      u8 rts_preamble_type,
++				      u8 frame_preamble_type, uint frame_len,
++				      bool ba);
++extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
++			       struct ieee80211_sta *sta,
++			       void (*dma_callback_fn));
++extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
++extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
++extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
++extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
++					  u32 bcn_rate);
++extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
++				     u8 antsel_type);
++extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
++				  u16 chanspec,
++				  bool mute, struct txpwr_limits *txpwr);
++extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
++			      u16 v);
++extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
++extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
++			u16 val, int bands);
++extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
++extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
++extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
++extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
++extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
++					u32 override_bit);
++extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
++					  u32 override_bit);
++extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
++				       int offset, int len, void *buf);
++extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
++extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
++				   uint offset, const void *buf, int len,
++				   u32 sel);
++extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
++				     void *buf, int len, u32 sel);
++extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
++extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
++extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
++extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
++extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
++extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
++				    u8 stf_mode);
++extern void brcms_c_init_scb(struct scb *scb);
++
++#endif				/* _BRCM_MAIN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+new file mode 100644
+index 0000000..264f8c4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+@@ -0,0 +1,2961 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <aiutils.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_hal.h"
++#include "phy_int.h"
++#include "phy_radio.h"
++#include "phy_lcn.h"
++#include "phyreg_n.h"
++
++#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \
++				 (radioid == BCM2056_ID) || \
++				 (radioid == BCM2057_ID))
++
++#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
++
++#define VALID_RADIO(pi, radioid)        ( \
++		(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
++		(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
++
++/* basic mux operation - can be optimized on several architectures */
++#define MUX(pred, true, false) ((pred) ? (true) : (false))
++
++/* modulo inc/dec - assumes x E [0, bound - 1] */
++#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
++
++/* modulo inc/dec, bound = 2^k */
++#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
++#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
++
++struct chan_info_basic {
++	u16 chan;
++	u16 freq;
++};
++
++static const struct chan_info_basic chan_info_all[] = {
++	{1, 2412},
++	{2, 2417},
++	{3, 2422},
++	{4, 2427},
++	{5, 2432},
++	{6, 2437},
++	{7, 2442},
++	{8, 2447},
++	{9, 2452},
++	{10, 2457},
++	{11, 2462},
++	{12, 2467},
++	{13, 2472},
++	{14, 2484},
++
++	{34, 5170},
++	{38, 5190},
++	{42, 5210},
++	{46, 5230},
++
++	{36, 5180},
++	{40, 5200},
++	{44, 5220},
++	{48, 5240},
++	{52, 5260},
++	{56, 5280},
++	{60, 5300},
++	{64, 5320},
++
++	{100, 5500},
++	{104, 5520},
++	{108, 5540},
++	{112, 5560},
++	{116, 5580},
++	{120, 5600},
++	{124, 5620},
++	{128, 5640},
++	{132, 5660},
++	{136, 5680},
++	{140, 5700},
++
++	{149, 5745},
++	{153, 5765},
++	{157, 5785},
++	{161, 5805},
++	{165, 5825},
++
++	{184, 4920},
++	{188, 4940},
++	{192, 4960},
++	{196, 4980},
++	{200, 5000},
++	{204, 5020},
++	{208, 5040},
++	{212, 5060},
++	{216, 5080}
++};
++
++static const u8 ofdm_rate_lookup[] = {
++
++	BRCM_RATE_48M,
++	BRCM_RATE_24M,
++	BRCM_RATE_12M,
++	BRCM_RATE_6M,
++	BRCM_RATE_54M,
++	BRCM_RATE_36M,
++	BRCM_RATE_18M,
++	BRCM_RATE_9M
++};
++
++#define PHY_WREG_LIMIT  24
++
++void wlc_phyreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
++}
++
++void wlc_phyreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
++}
++
++void wlc_radioreg_enter(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
++
++	udelay(10);
++}
++
++void wlc_radioreg_exit(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	pi->phy_wreg = 0;
++	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
++}
++
++u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
++{
++	u16 data;
++
++	if ((addr == RADIO_IDCODE))
++		return 0xffff;
++
++	switch (pi->pubpi.phy_type) {
++	case PHY_TYPE_N:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_N))
++			break;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			addr |= RADIO_2057_READ_OFF;
++		else
++			addr |= RADIO_2055_READ_OFF;
++		break;
++
++	case PHY_TYPE_LCN:
++		if (!CONF_HAS(PHYTYPE, PHY_TYPE_LCN))
++			break;
++		addr |= RADIO_2064_READ_OFF;
++		break;
++
++	default:
++		break;
++	}
++
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		data = bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++	}
++	pi->phy_wreg = 0;
++
++	return data;
++}
++
++void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	if ((D11REV_GE(pi->sh->corerev, 24)) ||
++	    (D11REV_IS(pi->sh->corerev, 22)
++	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(radioregdata), val);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
++		bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
++	}
++
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		pi->phy_wreg = 0;
++	}
++}
++
++static u32 read_radio_id(struct brcms_phy *pi)
++{
++	u32 id;
++
++	if (D11REV_GE(pi->sh->corerev, 24)) {
++		u32 b0, b1, b2;
++
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 0);
++		b0 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 1);
++		b1 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++		bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 2);
++		b2 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
++
++		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
++								      & 0xf);
++	} else {
++		bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), RADIO_IDCODE);
++		id = (u32) bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
++		id |= (u32) bcma_read16(pi->d11core,
++					D11REGOFFS(phy4wdatahi)) << 16;
++	}
++	pi->phy_wreg = 0;
++	return id;
++}
++
++void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & val));
++}
++
++void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval | val));
++}
++
++void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval ^ mask));
++}
++
++void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	u16 rval;
++
++	rval = read_radio_reg(pi, addr);
++	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
++}
++
++void write_phy_channel_reg(struct brcms_phy *pi, uint val)
++{
++	bcma_write16(pi->d11core, D11REGOFFS(phychannel), val);
++}
++
++u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++
++	pi->phy_wreg = 0;
++	return bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
++}
++
++void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++#ifdef CONFIG_BCM47XX
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_write16(pi->d11core, D11REGOFFS(phyregdata), val);
++	if (addr == 0x72)
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++#else
++	bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
++	if (++pi->phy_wreg >= pi->phy_wreg_limit) {
++		pi->phy_wreg = 0;
++		(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++	}
++#endif
++}
++
++void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_mask16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
++{
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_set16(pi->d11core, D11REGOFFS(phyregdata), val);
++	pi->phy_wreg = 0;
++}
++
++void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
++{
++	val &= mask;
++	bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
++	bcma_maskset16(pi->d11core, D11REGOFFS(phyregdata), ~mask, val);
++	pi->phy_wreg = 0;
++}
++
++static void wlc_set_phy_uninitted(struct brcms_phy *pi)
++{
++	int i, j;
++
++	pi->initialized = false;
++
++	pi->tx_vos = 0xffff;
++	pi->nrssi_table_delta = 0x7fffffff;
++	pi->rc_cal = 0xffff;
++	pi->mintxbias = 0xffff;
++	pi->txpwridx = -1;
++	if (ISNPHY(pi)) {
++		pi->phy_spuravoid = SPURAVOID_DISABLE;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7))
++			pi->phy_spuravoid = SPURAVOID_AUTO;
++
++		pi->nphy_papd_skip = 0;
++		pi->nphy_papd_epsilon_offset[0] = 0xf588;
++		pi->nphy_papd_epsilon_offset[1] = 0xf588;
++		pi->nphy_txpwr_idx[0] = 128;
++		pi->nphy_txpwr_idx[1] = 128;
++		pi->nphy_txpwrindex[0].index_internal = 40;
++		pi->nphy_txpwrindex[1].index_internal = 40;
++		pi->phy_pabias = 0;
++	} else {
++		pi->phy_spuravoid = SPURAVOID_AUTO;
++	}
++	pi->radiopwr = 0xffff;
++	for (i = 0; i < STATIC_NUM_RF; i++) {
++		for (j = 0; j < STATIC_NUM_BB; j++)
++			pi->stats_11b_txpower[i][j] = -1;
++	}
++}
++
++struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
++{
++	struct shared_phy *sh;
++
++	sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC);
++	if (sh == NULL)
++		return NULL;
++
++	sh->sih = shp->sih;
++	sh->physhim = shp->physhim;
++	sh->unit = shp->unit;
++	sh->corerev = shp->corerev;
++
++	sh->vid = shp->vid;
++	sh->did = shp->did;
++	sh->chip = shp->chip;
++	sh->chiprev = shp->chiprev;
++	sh->chippkg = shp->chippkg;
++	sh->sromrev = shp->sromrev;
++	sh->boardtype = shp->boardtype;
++	sh->boardrev = shp->boardrev;
++	sh->boardflags = shp->boardflags;
++	sh->boardflags2 = shp->boardflags2;
++
++	sh->fast_timer = PHY_SW_TIMER_FAST;
++	sh->slow_timer = PHY_SW_TIMER_SLOW;
++	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
++
++	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
++
++	return sh;
++}
++
++static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
++{
++	uint delay = 5;
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
++		if (!pi->sh->up) {
++			wlc_phy_cal_perical_mphase_reset(pi);
++			return;
++		}
++
++		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
++
++			delay = 1000;
++			wlc_phy_cal_perical_mphase_restart(pi);
++		} else
++			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
++		wlapi_add_timer(pi->phycal_timer, delay, 0);
++		return;
++	}
++
++}
++
++static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
++{
++	u32 ver;
++
++	ver = read_radio_id(pi);
++
++	return ver;
++}
++
++struct brcms_phy_pub *
++wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core,
++	       int bandtype, struct wiphy *wiphy)
++{
++	struct brcms_phy *pi;
++	u32 sflags = 0;
++	uint phyversion;
++	u32 idcode;
++	int i;
++
++	if (D11REV_IS(sh->corerev, 4))
++		sflags = SISF_2G_PHY | SISF_5G_PHY;
++	else
++		sflags = bcma_aread32(d11core, BCMA_IOST);
++
++	if (bandtype == BRCM_BAND_5G) {
++		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
++			return NULL;
++	}
++
++	pi = sh->phy_head;
++	if ((sflags & SISF_DB_PHY) && pi) {
++		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++		pi->refcnt++;
++		return &pi->pubpi_ro;
++	}
++
++	pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC);
++	if (pi == NULL)
++		return NULL;
++	pi->wiphy = wiphy;
++	pi->d11core = d11core;
++	pi->sh = sh;
++	pi->phy_init_por = true;
++	pi->phy_wreg_limit = PHY_WREG_LIMIT;
++
++	pi->txpwr_percent = 100;
++
++	pi->do_initcal = true;
++
++	pi->phycal_tempdelta = 0;
++
++	if (bandtype == BRCM_BAND_2G && (sflags & SISF_2G_PHY))
++		pi->pubpi.coreflags = SICF_GMODE;
++
++	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
++	phyversion = bcma_read16(pi->d11core, D11REGOFFS(phyversion));
++
++	pi->pubpi.phy_type = PHY_TYPE(phyversion);
++	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
++
++	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
++		pi->pubpi.phy_type = PHY_TYPE_N;
++		pi->pubpi.phy_rev += LCNXN_BASEREV;
++	}
++	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
++	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
++
++	if (pi->pubpi.phy_type != PHY_TYPE_N &&
++	    pi->pubpi.phy_type != PHY_TYPE_LCN)
++		goto err;
++
++	if (bandtype == BRCM_BAND_5G) {
++		if (!ISNPHY(pi))
++			goto err;
++	} else if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
++		goto err;
++	}
++
++	wlc_phy_anacore((struct brcms_phy_pub *) pi, ON);
++
++	idcode = wlc_phy_get_radio_ver(pi);
++	pi->pubpi.radioid =
++		(idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
++	pi->pubpi.radiorev =
++		(idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
++	pi->pubpi.radiover =
++		(idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
++	if (!VALID_RADIO(pi, pi->pubpi.radioid))
++		goto err;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF);
++
++	wlc_set_phy_uninitted(pi);
++
++	pi->bw = WL_CHANSPEC_BW_20;
++	pi->radio_chanspec = (bandtype == BRCM_BAND_2G) ?
++			     ch20mhz_chspec(1) : ch20mhz_chspec(36);
++
++	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++	pi->rxiq_antsel = ANT_RX_DIV_DEF;
++
++	pi->watchdog_override = true;
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++
++	pi->nphy_saved_noisevars.bufcount = 0;
++
++	if (ISNPHY(pi))
++		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
++	else
++		pi->min_txpower = PHY_TXPWR_MIN;
++
++	pi->sh->phyrxchain = 0x3;
++
++	pi->rx2tx_biasentry = -1;
++
++	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++	pi->phy_txcore_enable_temp =
++		PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
++	pi->phy_tempsense_offset = 0;
++	pi->phy_txcore_heatedup = false;
++
++	pi->nphy_lastcal_temp = -50;
++
++	pi->phynoise_polling = true;
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		pi->phynoise_polling = false;
++
++	for (i = 0; i < TXP_NUM_RATES; i++) {
++		pi->txpwr_limit[i] = BRCMS_TXPWR_MAX;
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++		pi->tx_user_target[i] = BRCMS_TXPWR_MAX;
++	}
++
++	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
++
++	pi->user_txpwr_at_rfport = false;
++
++	if (ISNPHY(pi)) {
++
++		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
++						    wlc_phy_timercb_phycal,
++						    pi, "phycal");
++		if (!pi->phycal_timer)
++			goto err;
++
++		if (!wlc_phy_attach_nphy(pi))
++			goto err;
++
++	} else if (ISLCNPHY(pi)) {
++		if (!wlc_phy_attach_lcnphy(pi))
++			goto err;
++
++	}
++
++	pi->refcnt++;
++	pi->next = pi->sh->phy_head;
++	sh->phy_head = pi;
++
++	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub));
++
++	return &pi->pubpi_ro;
++
++err:
++	kfree(pi);
++	return NULL;
++}
++
++void wlc_phy_detach(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pih) {
++		if (--pi->refcnt)
++			return;
++
++		if (pi->phycal_timer) {
++			wlapi_free_timer(pi->phycal_timer);
++			pi->phycal_timer = NULL;
++		}
++
++		if (pi->sh->phy_head == pi)
++			pi->sh->phy_head = pi->next;
++		else if (pi->sh->phy_head->next == pi)
++			pi->sh->phy_head->next = NULL;
++
++		if (pi->pi_fptr.detach)
++			(pi->pi_fptr.detach)(pi);
++
++		kfree(pi);
++	}
++}
++
++bool
++wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
++		       u16 *radioid, u16 *radiover)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	*phytype = (u16) pi->pubpi.phy_type;
++	*phyrev = (u16) pi->pubpi.phy_rev;
++	*radioid = pi->pubpi.radioid;
++	*radiover = pi->pubpi.radiorev;
++
++	return true;
++}
++
++bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.abgphy_encore;
++}
++
++u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	return pi->pubpi.coreflags;
++}
++
++void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		if (on) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0xa6, 0x0d);
++				write_phy_reg(pi, 0x8f, 0x0);
++				write_phy_reg(pi, 0xa7, 0x0d);
++				write_phy_reg(pi, 0xa5, 0x0);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x0);
++			}
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				write_phy_reg(pi, 0x8f, 0x07ff);
++				write_phy_reg(pi, 0xa6, 0x0fd);
++				write_phy_reg(pi, 0xa5, 0x07ff);
++				write_phy_reg(pi, 0xa7, 0x0fd);
++			} else {
++				write_phy_reg(pi, 0xa5, 0x7fff);
++			}
++		}
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x43b,
++				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++		} else {
++			or_phy_reg(pi, 0x43c,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++			or_phy_reg(pi, 0x43b,
++				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++		}
++	}
++}
++
++u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	u32 phy_bw_clkbits = 0;
++
++	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
++		switch (pi->bw) {
++		case WL_CHANSPEC_BW_10:
++			phy_bw_clkbits = SICF_BW10;
++			break;
++		case WL_CHANSPEC_BW_20:
++			phy_bw_clkbits = SICF_BW20;
++			break;
++		case WL_CHANSPEC_BW_40:
++			phy_bw_clkbits = SICF_BW40;
++			break;
++		default:
++			break;
++		}
++	}
++
++	return phy_bw_clkbits;
++}
++
++void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->phy_init_por = true;
++}
++
++void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->edcrs_threshold_lock = lock;
++
++	write_phy_reg(pi, 0x22c, 0x46b);
++	write_phy_reg(pi, 0x22d, 0x46b);
++	write_phy_reg(pi, 0x22e, 0x3c0);
++	write_phy_reg(pi, 0x22f, 0x3c0);
++}
++
++void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->do_initcal = initcal;
++}
++
++void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->clk = newstate;
++}
++
++void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!pi || !pi->sh)
++		return;
++
++	pi->sh->up = newstate;
++}
++
++void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	u32 mc;
++	void (*phy_init)(struct brcms_phy *) = NULL;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (pi->init_in_progress)
++		return;
++
++	pi->init_in_progress = true;
++
++	pi->radio_chanspec = chanspec;
++
++	mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
++		return;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if (WARN(!(bcma_aread32(pi->d11core, BCMA_IOST) & SISF_FCLKA),
++		 "HW error SISF_FCLKA\n"))
++		return;
++
++	phy_init = pi->pi_fptr.init;
++
++	if (phy_init == NULL)
++		return;
++
++	wlc_phy_anacore(pih, ON);
++
++	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim,
++				  CHSPEC_BW(pi->radio_chanspec));
++
++	pi->nphy_gain_boost = true;
++
++	wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON);
++
++	(*phy_init)(pi);
++
++	pi->phy_init_por = false;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlc_phy_do_dummy_tx(pi, true, OFF);
++
++	if (!(ISNPHY(pi)))
++		wlc_phy_txpower_update_shm(pi);
++
++	wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv);
++
++	pi->init_in_progress = false;
++}
++
++void wlc_phy_cal_init(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	void (*cal_init)(struct brcms_phy *) = NULL;
++
++	if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++		  MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n"))
++		return;
++
++	if (!pi->initialized) {
++		cal_init = pi->pi_fptr.calinit;
++		if (cal_init)
++			(*cal_init)(pi);
++
++		pi->initialized = true;
++	}
++}
++
++int wlc_phy_down(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	int callbacks = 0;
++
++	if (pi->phycal_timer
++	    && !wlapi_del_timer(pi->phycal_timer))
++		callbacks++;
++
++	pi->nphy_iqcal_chanspec_2G = 0;
++	pi->nphy_iqcal_chanspec_5G = 0;
++
++	return callbacks;
++}
++
++void
++wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	pi->tbl_data_hi = tblDataHi;
++	pi->tbl_data_lo = tblDataLo;
++
++	if (pi->sh->chip == BCM43224_CHIP_ID &&
++	    pi->sh->chiprev == 1) {
++		pi->tbl_addr = tblAddr;
++		pi->tbl_save_id = tbl_id;
++		pi->tbl_save_offset = tbl_offset;
++	}
++}
++
++void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val)
++{
++	if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++	    (pi->sh->chiprev == 1) &&
++	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++		read_phy_reg(pi, pi->tbl_data_lo);
++
++		write_phy_reg(pi, pi->tbl_addr,
++			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
++		pi->tbl_save_offset++;
++	}
++
++	if (width == 32) {
++		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	} else {
++		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
++	}
++}
++
++void
++wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
++	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
++	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1) &&
++		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
++			read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			write_phy_reg(pi, tblDataHi,
++				      (u16) (ptbl_32b[idx] >> 16));
++			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
++		} else if (tbl_width == 16) {
++			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
++		} else {
++			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
++		}
++	}
++}
++
++void
++wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info,
++		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
++{
++	uint idx;
++	uint tbl_id = ptbl_info->tbl_id;
++	uint tbl_offset = ptbl_info->tbl_offset;
++	uint tbl_width = ptbl_info->tbl_width;
++	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
++	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
++	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
++
++	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
++
++	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) &&
++		    (pi->sh->chiprev == 1)) {
++			(void)read_phy_reg(pi, tblDataLo);
++
++			write_phy_reg(pi, tblAddr,
++				      (tbl_id << 10) | (tbl_offset + idx));
++		}
++
++		if (tbl_width == 32) {
++			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
++			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
++		} else if (tbl_width == 16) {
++			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
++		} else {
++			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
++		}
++	}
++}
++
++uint
++wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++				 struct radio_20xx_regs *radioregs)
++{
++	uint i = 0;
++
++	do {
++		if (radioregs[i].do_init)
++			write_radio_reg(pi, radioregs[i].address,
++					(u16) radioregs[i].init);
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++uint
++wlc_phy_init_radio_regs(struct brcms_phy *pi,
++			const struct radio_regs *radioregs,
++			u16 core_offset)
++{
++	uint i = 0;
++	uint count = 0;
++
++	do {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (radioregs[i].do_init_a) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_a);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		} else {
++			if (radioregs[i].do_init_g) {
++				write_radio_reg(pi,
++						radioregs[i].
++						address | core_offset,
++						(u16) radioregs[i].init_g);
++				if (ISNPHY(pi) && (++count % 4 == 0))
++					BRCMS_PHY_WAR_PR51571(pi);
++			}
++		}
++
++		i++;
++	} while (radioregs[i].address != 0xffff);
++
++	return i;
++}
++
++void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
++{
++#define DUMMY_PKT_LEN   20
++	struct bcma_device *core = pi->d11core;
++	int i, count;
++	u8 ofdmpkt[DUMMY_PKT_LEN] = {
++		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u8 cckpkt[DUMMY_PKT_LEN] = {
++		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
++		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
++	};
++	u32 *dummypkt;
++
++	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
++	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
++				      dummypkt);
++
++	bcma_write16(core, D11REGOFFS(xmtsel), 0);
++
++	if (D11REV_GE(pi->sh->corerev, 11))
++		bcma_write16(core, D11REGOFFS(wepctl), 0x100);
++	else
++		bcma_write16(core, D11REGOFFS(wepctl), 0);
++
++	bcma_write16(core, D11REGOFFS(txe_phyctl),
++		     (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_phyctl1), 0x1A02);
++
++	bcma_write16(core, D11REGOFFS(txe_wm_0), 0);
++	bcma_write16(core, D11REGOFFS(txe_wm_1), 0);
++
++	bcma_write16(core, D11REGOFFS(xmttplatetxptr), 0);
++	bcma_write16(core, D11REGOFFS(xmttxcnt), DUMMY_PKT_LEN);
++
++	bcma_write16(core, D11REGOFFS(xmtsel),
++		     ((8 << 8) | (1 << 5) | (1 << 2) | 2));
++
++	bcma_write16(core, D11REGOFFS(txe_ctl), 0);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, OFF);
++	}
++
++	if (ISNPHY(pi) || ISLCNPHY(pi))
++		bcma_write16(core, D11REGOFFS(txe_aux), 0xD0);
++	else
++		bcma_write16(core, D11REGOFFS(txe_aux), ((1 << 5) | (1 << 4)));
++
++	(void)bcma_read16(core, D11REGOFFS(txe_aux));
++
++	i = 0;
++	count = ofdm ? 30 : 250;
++	while ((i++ < count)
++	       && (bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 7)))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 10)) == 0))
++		udelay(10);
++
++	i = 0;
++
++	while ((i++ < 10) &&
++	       ((bcma_read16(core, D11REGOFFS(ifsstat)) & (1 << 8))))
++		udelay(10);
++
++	if (!pa_on) {
++		if (ISNPHY(pi))
++			wlc_phy_pa_override_nphy(pi, ON);
++	}
++}
++
++void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (set)
++		mboolset(pi->measure_hold, id);
++	else
++		mboolclr(pi->measure_hold, id);
++
++	return;
++}
++
++void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (mute)
++		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++	else
++		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
++
++	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
++		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
++	return;
++}
++
++void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (ISNPHY(pi)) {
++		return;
++	} else {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
++	}
++}
++
++static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
++{
++	return false;
++}
++
++void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++
++	if (ISNPHY(pi)) {
++		wlc_phy_switch_radio_nphy(pi, on);
++	} else if (ISLCNPHY(pi)) {
++		if (on) {
++			and_phy_reg(pi, 0x44c,
++				    ~((0x1 << 8) |
++				      (0x1 << 9) |
++				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
++			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
++			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
++		} else {
++			and_phy_reg(pi, 0x44d,
++				    ~((0x1 << 10) |
++				      (0x1 << 11) |
++				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
++			or_phy_reg(pi, 0x44c,
++				   (0x1 << 8) |
++				   (0x1 << 9) |
++				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
++
++			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
++			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
++			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
++			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
++			or_phy_reg(pi, 0x4f9, (0x1 << 3));
++		}
++	}
++}
++
++u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->bw;
++}
++
++void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->bw = bw;
++}
++
++void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	pi->radio_chanspec = newch;
++
++}
++
++u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->radio_chanspec;
++}
++
++void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 m_cur_channel;
++	void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
++	m_cur_channel = CHSPEC_CHANNEL(chanspec);
++	if (CHSPEC_IS5G(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_5G;
++	if (CHSPEC_IS40(chanspec))
++		m_cur_channel |= D11_CURCHANNEL_40;
++	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
++
++	chanspec_set = pi->pi_fptr.chanset;
++	if (chanspec_set)
++		(*chanspec_set)(pi, chanspec);
++
++}
++
++int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
++{
++	int range = -1;
++
++	if (freq < 2500)
++		range = WL_CHAN_FREQ_RANGE_2G;
++	else if (freq <= 5320)
++		range = WL_CHAN_FREQ_RANGE_5GL;
++	else if (freq <= 5700)
++		range = WL_CHAN_FREQ_RANGE_5GM;
++	else
++		range = WL_CHAN_FREQ_RANGE_5GH;
++
++	return range;
++}
++
++int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
++{
++	int range = -1;
++	uint channel = CHSPEC_CHANNEL(chanspec);
++	uint freq = wlc_phy_channel2freq(channel);
++
++	if (ISNPHY(pi))
++		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
++	else if (ISLCNPHY(pi))
++		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
++
++	return range;
++}
++
++void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++					  bool wide_filter)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->channel_14_wide_filter = wide_filter;
++
++}
++
++int wlc_phy_channel2freq(uint channel)
++{
++	uint i;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
++		if (chan_info_all[i].chan == channel)
++			return chan_info_all[i].freq;
++	return 0;
++}
++
++void
++wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++			      struct brcms_chanvec *channels)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++
++	memset(channels, 0, sizeof(struct brcms_chanvec));
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			setbit(channels->vec, channel);
++	}
++}
++
++u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++	uint channel;
++	u16 chspec;
++
++	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++		channel = chan_info_all[i].chan;
++
++		if (ISNPHY(pi) && pi->bw == WL_CHANSPEC_BW_40) {
++			uint j;
++
++			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
++				if (chan_info_all[j].chan ==
++				    channel + CH_10MHZ_APART)
++					break;
++			}
++
++			if (j == ARRAY_SIZE(chan_info_all))
++				continue;
++
++			channel = upper_20_sb(channel);
++			chspec =  channel | WL_CHANSPEC_BW_40 |
++				  WL_CHANSPEC_CTL_SB_LOWER;
++			if (band == BRCM_BAND_2G)
++				chspec |= WL_CHANSPEC_BAND_2G;
++			else
++				chspec |= WL_CHANSPEC_BAND_5G;
++		} else
++			chspec = ch20mhz_chspec(channel);
++
++		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
++		    && (channel <= LAST_REF5_CHANNUM))
++			continue;
++
++		if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) ||
++		    (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL))
++			return chspec;
++	}
++
++	return (u16) INVCHANSPEC;
++}
++
++int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	*qdbm = pi->tx_user_target[0];
++	if (override != NULL)
++		*override = pi->txpwroverride;
++	return 0;
++}
++
++void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				struct txpwr_limits *txpwr)
++{
++	bool mac_enabled = false;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
++	       &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
++	       &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
++	       &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
++	       &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
++	       &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
++	       &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
++	       &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
++	       &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
++	       &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
++	       &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
++	       &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
++	       &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM);
++	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
++	       &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
++
++	if (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
++		mac_enabled = true;
++
++	if (mac_enabled)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++
++	if (mac_enabled)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	int i;
++
++	if (qdbm > 127)
++		return -EINVAL;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->tx_user_target[i] = (u8) qdbm;
++
++	pi->txpwroverride = false;
++
++	if (pi->sh->up) {
++		if (!SCAN_INPROG_PHY(pi)) {
++			bool suspend;
++
++			suspend = (0 == (bcma_read32(pi->d11core,
++						     D11REGOFFS(maccontrol)) &
++					 MCTL_EN_MAC));
++
++			if (!suspend)
++				wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++			wlc_phy_txpower_recalc_target(pi);
++			wlc_phy_cal_txpower_recalc_sw(pi);
++
++			if (!suspend)
++				wlapi_enable_mac(pi->sh->physhim);
++		}
++	}
++	return 0;
++}
++
++void
++wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
++			  u8 *max_pwr, int txp_rate_idx)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint i;
++
++	*min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
++
++	if (ISNPHY(pi)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
++						   (u8) txp_rate_idx);
++
++	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_CCK;
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++	} else {
++
++		*max_pwr = BRCMS_TXPWR_MAX;
++
++		if (txp_rate_idx < 0)
++			txp_rate_idx = TXP_FIRST_OFDM;
++
++		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
++			if (channel == chan_info_all[i].chan)
++				break;
++		}
++
++		if (pi->hwtxpwr) {
++			*max_pwr = pi->hwtxpwr[i];
++		} else {
++
++			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++			if ((i >= FIRST_HIGH_5G_CHAN)
++			    && (i <= LAST_HIGH_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
++				*max_pwr =
++				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		}
++	}
++}
++
++void
++wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
++				  u8 *max_txpwr, u8 *min_txpwr)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 max_num_rate;
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++
++	pactrl = 0;
++
++	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
++		       ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 +
++				       1) : (TXP_LAST_OFDM + 1);
++
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
++					  rate);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
++		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
++	}
++	*max_txpwr = tx_pwr_max;
++	*min_txpwr = tx_pwr_min;
++}
++
++void
++wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
++				s32 *max_pwr, s32 *min_pwr, u32 *step_pwr)
++{
++	return;
++}
++
++u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_min;
++}
++
++u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->tx_power_max;
++}
++
++static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_vbatsense(pi, 0);
++	else
++		return 0;
++}
++
++static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi)
++{
++	if (ISLCNPHY(pi))
++		return wlc_lcnphy_tempsense_degree(pi, 0);
++	else
++		return 0;
++}
++
++static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band)
++{
++	u8 i;
++	s8 temp, vbat;
++
++	for (i = 0; i < TXP_NUM_RATES; i++)
++		pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX;
++
++	vbat = wlc_phy_env_measure_vbat(pi);
++	temp = wlc_phy_env_measure_temperature(pi);
++
++}
++
++static s8
++wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
++				 u8 rate)
++{
++	s8 offset = 0;
++
++	if (!pi->user_txpwr_at_rfport)
++		return offset;
++	return offset;
++}
++
++void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	u8 maxtxpwr, mintxpwr, rate, pactrl;
++	uint target_chan;
++	u8 tx_pwr_target[TXP_NUM_RATES];
++	u8 tx_pwr_max = 0;
++	u8 tx_pwr_min = 255;
++	u8 tx_pwr_max_rate_ind = 0;
++	u8 max_num_rate;
++	u8 start_rate = 0;
++	u16 chspec;
++	u32 band = CHSPEC2BAND(pi->radio_chanspec);
++	void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL;
++
++	chspec = pi->radio_chanspec;
++	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
++		target_chan = CHSPEC_CHANNEL(chspec);
++	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
++		target_chan = upper_20_sb(CHSPEC_CHANNEL(chspec));
++	else
++		target_chan = lower_20_sb(CHSPEC_CHANNEL(chspec));
++
++	pactrl = 0;
++	if (ISLCNPHY(pi)) {
++		u32 offset_mcs, i;
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			offset_mcs = pi->mcs40_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		} else {
++			offset_mcs = pi->mcs20_po;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i - 8] =
++					pi->tx_srom_max_2g -
++					((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++	}
++
++	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++			((ISLCNPHY(pi)) ?
++			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
++
++	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
++
++	for (rate = start_rate; rate < max_num_rate; rate++) {
++
++		tx_pwr_target[rate] = pi->tx_user_target[rate];
++
++		if (pi->user_txpwr_at_rfport)
++			tx_pwr_target[rate] +=
++				wlc_user_txpwr_antport_to_rfport(pi,
++								 target_chan,
++								 band,
++								 rate);
++
++		wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi,
++					  target_chan,
++					  &mintxpwr, &maxtxpwr, rate);
++
++		maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
++
++		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
++
++		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
++
++		maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
++
++		if (pi->txpwr_percent <= 100)
++			maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
++
++		tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
++
++		tx_pwr_target[rate] =
++			min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
++
++		if (tx_pwr_target[rate] > tx_pwr_max)
++			tx_pwr_max_rate_ind = rate;
++
++		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
++		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
++	}
++
++	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
++	pi->tx_power_max = tx_pwr_max;
++	pi->tx_power_min = tx_pwr_min;
++	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
++	for (rate = 0; rate < max_num_rate; rate++) {
++
++		pi->tx_power_target[rate] = tx_pwr_target[rate];
++
++		if (!pi->hwpwrctrl || ISNPHY(pi))
++			pi->tx_power_offset[rate] =
++				pi->tx_power_max - pi->tx_power_target[rate];
++		else
++			pi->tx_power_offset[rate] =
++				pi->tx_power_target[rate] - pi->tx_power_min;
++	}
++
++	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
++	if (txpwr_recalc_fn)
++		(*txpwr_recalc_fn)(pi);
++}
++
++static void
++wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
++			       u16 chanspec)
++{
++	u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM];
++	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
++	int rate_start_index = 0, rate1, rate2, k;
++
++	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
++
++	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
++	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
++		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
++
++	if (ISNPHY(pi)) {
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->mcs_20_siso;
++				txpwr_ptr2 = txpwr->ofdm;
++				rate_start_index = WL_TX_POWER_OFDM_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->mcs_20_cdd;
++				txpwr_ptr2 = txpwr->ofdm_cdd;
++				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->mcs_40_siso;
++				txpwr_ptr2 = txpwr->ofdm_40_siso;
++				rate_start_index =
++					WL_TX_POWER_OFDM40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->mcs_40_cdd;
++				txpwr_ptr2 = txpwr->ofdm_40_cdd;
++				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
++				break;
++			}
++
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_mcs_to_ofdm_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 4; k++) {
++			switch (k) {
++			case 0:
++
++				txpwr_ptr1 = txpwr->ofdm;
++				txpwr_ptr2 = txpwr->mcs_20_siso;
++				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
++				break;
++			case 1:
++
++				txpwr_ptr1 = txpwr->ofdm_cdd;
++				txpwr_ptr2 = txpwr->mcs_20_cdd;
++				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
++				break;
++			case 2:
++
++				txpwr_ptr1 = txpwr->ofdm_40_siso;
++				txpwr_ptr2 = txpwr->mcs_40_siso;
++				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
++				break;
++			case 3:
++
++				txpwr_ptr1 = txpwr->ofdm_40_cdd;
++				txpwr_ptr2 = txpwr->mcs_40_cdd;
++				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
++				break;
++			}
++			for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM;
++			     rate2++) {
++				tmp_txpwr_limit[rate2] = 0;
++				tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] =
++					txpwr_ptr1[rate2];
++			}
++			wlc_phy_ofdm_to_mcs_powers_nphy(
++				tmp_txpwr_limit, 0,
++				BRCMS_NUM_RATES_OFDM -
++				1, BRCMS_NUM_RATES_OFDM);
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] =
++					min(txpwr_ptr2[rate2],
++					    tmp_txpwr_limit[rate2]);
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_stbc;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_stbc;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_1_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		for (k = 0; k < 2; k++) {
++			switch (k) {
++			case 0:
++
++				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_20_mimo;
++				break;
++			case 1:
++
++				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
++				txpwr_ptr1 = txpwr->mcs_40_mimo;
++				break;
++			}
++			for (rate1 = rate_start_index, rate2 = 0;
++			     rate2 < BRCMS_NUM_RATES_MCS_2_STREAM;
++			     rate1++, rate2++)
++				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
++		}
++
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
++
++		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
++			min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
++			    pi->txpwr_limit[WL_TX_POWER_MCS_32]);
++		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
++			pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
++	}
++}
++
++void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->txpwr_percent = txpwr_percent;
++}
++
++void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->sh->machwcap = machwcap;
++}
++
++void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 rxc;
++	rxc = 0;
++
++	if (start_end == ON) {
++		if (!ISNPHY(pi))
++			return;
++
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_set16(pi->d11core, D11REGOFFS(phyregdata),
++				   0x1 << 15);
++		}
++	} else {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)
++		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
++			bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
++				      0xa0);
++			bcma_write16(pi->d11core, D11REGOFFS(phyregdata), rxc);
++		}
++
++		wlc_phy_por_inform(ppi);
++	}
++}
++
++void
++wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
++			  u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
++
++	if (ISLCNPHY(pi)) {
++		int i, j;
++		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
++		     j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) {
++			if (txpwr->mcs_20_siso[j])
++				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
++			else
++				pi->txpwr_limit[i] = txpwr->ofdm[j];
++		}
++	}
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_txpower_recalc_target(pi);
++	wlc_phy_cal_txpower_recalc_sw(pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->ofdm_rateset_war = war;
++}
++
++void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->bf_preempt_4306 = bf_preempt;
++}
++
++void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
++{
++	int j;
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	if (pi->hwpwrctrl) {
++		u16 offset;
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
++				     1 << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
++				     pi->tx_power_min << NUM_TSSI_FRAMES);
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
++				     pi->hwpwr_txcur);
++
++		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
++			const u8 ucode_ofdm_rates[] = {
++				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
++			};
++			offset = wlapi_bmac_rate_shm_offset(
++				pi->sh->physhim,
++				ucode_ofdm_rates[j - TXP_FIRST_OFDM]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
++					     pi->tx_power_offset[j]);
++			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
++					     -(pi->tx_power_offset[j] / 2));
++		}
++
++		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
++			       MHF2_HWPWRCTL, BRCM_BAND_ALL);
++	} else {
++		int i;
++
++		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
++			pi->tx_power_offset[i] =
++				(u8) roundup(pi->tx_power_offset[i], 8);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
++				     (u16)
++				     ((pi->tx_power_offset[TXP_FIRST_OFDM]
++				       + 7) >> 3));
++	}
++}
++
++bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return pi->nphy_txpwrctrl;
++	else
++		return pi->hwpwrctrl;
++}
++
++void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	if (!pi->hwpwrctrl_capable)
++		return;
++
++	pi->hwpwrctrl = hwpwrctrl;
++	pi->nphy_txpwrctrl = hwpwrctrl;
++	pi->txpwrctrl = hwpwrctrl;
++
++	if (ISNPHY(pi)) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++			wlc_phy_txpwr_fixpower_nphy(pi);
++		else
++			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++				    pi->saved_txpwr_idx);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++}
++
++void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
++		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
++	} else {
++		pi->ipa2g_on = false;
++		pi->ipa5g_on = false;
++	}
++}
++
++static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi)
++{
++	s16 tx0_status, tx1_status;
++	u16 estPower1, estPower2;
++	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
++	u32 est_pwr;
++
++	estPower1 = read_phy_reg(pi, 0x118);
++	estPower2 = read_phy_reg(pi, 0x119);
++
++	if ((estPower1 & (0x1 << 8)) == (0x1 << 8))
++		pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0;
++	else
++		pwr0 = 0x80;
++
++	if ((estPower2 & (0x1 << 8)) == (0x1 << 8))
++		pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0;
++	else
++		pwr1 = 0x80;
++
++	tx0_status = read_phy_reg(pi, 0x1ed);
++	tx1_status = read_phy_reg(pi, 0x1ee);
++
++	if ((tx0_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr0 = 0x80;
++	if ((tx1_status & (0x1 << 15)) == (0x1 << 15))
++		adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0;
++	else
++		adj_pwr1 = 0x80;
++
++	est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) |
++			 adj_pwr1);
++
++	return est_pwr;
++}
++
++void
++wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
++			    uint channel)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	uint rate, num_rates;
++	u8 min_pwr, max_pwr;
++
++#if WL_TX_POWER_RATES != TXP_NUM_RATES
++#error "struct tx_power out of sync with this fn"
++#endif
++
++	if (ISNPHY(pi)) {
++		power->rf_cores = 2;
++		power->flags |= (WL_TX_POWER_F_MIMO);
++		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++			power->flags |=
++				(WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
++	} else if (ISLCNPHY(pi)) {
++		power->rf_cores = 1;
++		power->flags |= (WL_TX_POWER_F_SISO);
++		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
++			power->flags |= WL_TX_POWER_F_ENABLED;
++		if (pi->hwpwrctrl)
++			power->flags |= WL_TX_POWER_F_HW;
++	}
++
++	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
++		     ((ISLCNPHY(pi)) ?
++		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
++
++	for (rate = 0; rate < num_rates; rate++) {
++		power->user_limit[rate] = pi->tx_user_target[rate];
++		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
++					  rate);
++		power->board_limit[rate] = (u8) max_pwr;
++		power->target[rate] = pi->tx_power_target[rate];
++	}
++
++	if (ISNPHY(pi)) {
++		u32 est_pout;
++
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++		est_pout = wlc_phy_txpower_est_power_nphy(pi);
++		wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		power->est_Pout[0] = (est_pout >> 8) & 0xff;
++		power->est_Pout[1] = est_pout & 0xff;
++
++		power->est_Pout_act[0] = est_pout >> 24;
++		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
++
++		if (power->est_Pout[0] == 0x80)
++			power->est_Pout[0] = 0;
++		if (power->est_Pout[1] == 0x80)
++			power->est_Pout[1] = 0;
++
++		if (power->est_Pout_act[0] == 0x80)
++			power->est_Pout_act[0] = 0;
++		if (power->est_Pout_act[1] == 0x80)
++			power->est_Pout_act[1] = 0;
++
++		power->est_Pout_cck = 0;
++
++		power->tx_power_max[0] = pi->tx_power_max;
++		power->tx_power_max[1] = pi->tx_power_max;
++
++		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
++		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
++	} else if (pi->hwpwrctrl && pi->sh->up) {
++
++		wlc_phyreg_enter(ppi);
++		if (ISLCNPHY(pi)) {
++
++			power->tx_power_max[0] = pi->tx_power_max;
++			power->tx_power_max[1] = pi->tx_power_max;
++
++			power->tx_power_max_rate_ind[0] =
++				pi->tx_power_max_rate_ind;
++			power->tx_power_max_rate_ind[1] =
++				pi->tx_power_max_rate_ind;
++
++			if (wlc_phy_tpc_isenabled_lcnphy(pi))
++				power->flags |=
++					(WL_TX_POWER_F_HW |
++					 WL_TX_POWER_F_ENABLED);
++			else
++				power->flags &=
++					~(WL_TX_POWER_F_HW |
++					  WL_TX_POWER_F_ENABLED);
++
++			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
++					    (s8 *) &power->est_Pout_cck);
++		}
++		wlc_phyreg_exit(ppi);
++	}
++}
++
++void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	pi->antsel_type = antsel_type;
++}
++
++bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	return pi->phytest_on;
++}
++
++void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	bool suspend;
++
++	pi->sh->rx_antdiv = val;
++
++	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
++		if (val > ANT_RX_DIV_FORCE_1)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
++				       MHF1_ANTDIV, BRCM_BAND_ALL);
++		else
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
++				       BRCM_BAND_ALL);
++	}
++
++	if (ISNPHY(pi))
++		return;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (ISLCNPHY(pi)) {
++		if (val > ANT_RX_DIV_FORCE_1) {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
++			mod_phy_reg(pi, 0x410,
++				    (0x1 << 0),
++				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
++		} else {
++			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
++			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
++		}
++	}
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return;
++}
++
++static bool
++wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant)
++{
++	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
++	u8 i;
++
++	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
++	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
++		else
++
++			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
++	}
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
++		pwr_ant[i] = cmplx_pwr_dbm[i];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++	return true;
++}
++
++static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm)
++{
++	if (!pi->phynoise_state)
++		return;
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
++		if (pi->phynoise_chan_watchdog == channel) {
++			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
++				noise_dbm;
++			pi->sh->phy_noise_index =
++				MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
++		}
++		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
++	}
++
++	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL)
++		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
++
++}
++
++static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
++{
++	u32 cmplx_pwr[PHY_CORE_MAX];
++	s8 noise_dbm_ant[PHY_CORE_MAX];
++	u16 lo, hi;
++	u32 cmplx_pwr_tot = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	u8 idx, core;
++
++	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2,
++	     core++) {
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
++		hi = wlapi_bmac_read_shm(pi->sh->physhim,
++					 M_PWRIND_MAP(idx + 1));
++		cmplx_pwr[core] = (hi << 16) + lo;
++		cmplx_pwr_tot += cmplx_pwr[core];
++		if (cmplx_pwr[core] == 0)
++			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
++		else
++			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
++	}
++
++	if (cmplx_pwr_tot != 0)
++		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		pi->nphy_noise_win[core][pi->nphy_noise_index] =
++			noise_dbm_ant[core];
++
++		if (noise_dbm_ant[core] > noise_dbm)
++			noise_dbm = noise_dbm_ant[core];
++	}
++	pi->nphy_noise_index =
++		MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
++
++	return noise_dbm;
++
++}
++
++void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 jssi_aux;
++	u8 channel = 0;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++
++	if (ISLCNPHY(pi)) {
++		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
++		u16 lo, hi;
++		s32 pwr_offset_dB, gain_dB;
++		u16 status_0, status_1;
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
++		cmplx_pwr0 = (hi << 16) + lo;
++
++		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
++		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
++		cmplx_pwr1 = (hi << 16) + lo;
++		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
++
++		status_0 = 0x44;
++		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
++		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
++		    && ((status_1 & 0xc000) == 0x4000)) {
++
++			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
++					   pi->pubpi.phy_corenum);
++			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
++			if (pwr_offset_dB > 127)
++				pwr_offset_dB -= 256;
++
++			noise_dbm += (s8) (pwr_offset_dB - 30);
++
++			gain_dB = (status_0 & 0x1ff);
++			noise_dbm -= (s8) (gain_dB);
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
++		}
++	} else if (ISNPHY(pi)) {
++
++		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
++		channel = jssi_aux & D11_CURCHANNEL_MAX;
++
++		noise_dbm = wlc_phy_noise_read_shmem(pi);
++	}
++
++	wlc_phy_noise_cb(pi, channel, noise_dbm);
++
++}
++
++static void
++wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++	bool sampling_in_progress = (pi->phynoise_state != 0);
++	bool wait_for_intr = true;
++
++	switch (reason) {
++	case PHY_NOISE_SAMPLE_MON:
++		pi->phynoise_chan_watchdog = ch;
++		pi->phynoise_state |= PHY_NOISE_STATE_MON;
++		break;
++
++	case PHY_NOISE_SAMPLE_EXTERNAL:
++		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
++		break;
++
++	default:
++		break;
++	}
++
++	if (sampling_in_progress)
++		return;
++
++	pi->phynoise_now = pi->sh->now;
++
++	if (pi->phy_fixed_noise) {
++		if (ISNPHY(pi)) {
++			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
++				PHY_NOISE_FIXED_VAL_NPHY;
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
++		} else {
++			noise_dbm = PHY_NOISE_FIXED_VAL;
++		}
++
++		wait_for_intr = false;
++		goto done;
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_lcnphy_deaf_mode(pi, (bool) 0);
++			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
++			wlc_lcnphy_deaf_mode(pi, (bool) 1);
++			wlapi_enable_mac(pi->sh->physhim);
++			wait_for_intr = false;
++		}
++	} else if (ISNPHY(pi)) {
++		if (!pi->phynoise_polling
++		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
++
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
++
++			bcma_set32(pi->d11core, D11REGOFFS(maccommand),
++				   MCMD_BG_NOISE);
++		} else {
++			struct phy_iq_est est[PHY_CORE_MAX];
++			u32 cmplx_pwr[PHY_CORE_MAX];
++			s8 noise_dbm_ant[PHY_CORE_MAX];
++			u16 log_num_samps, num_samps, classif_state = 0;
++			u8 wait_time = 32;
++			u8 wait_crs = 0;
++			u8 i;
++
++			memset((u8 *) est, 0, sizeof(est));
++			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
++			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
++
++			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
++			num_samps = 1 << log_num_samps;
++
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, 3, 0);
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
++					       wait_crs);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++			wlapi_enable_mac(pi->sh->physhim);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++)
++				cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >>
++					       log_num_samps;
++
++			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
++
++			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
++				pi->nphy_noise_win[i][pi->nphy_noise_index] =
++					noise_dbm_ant[i];
++
++				if (noise_dbm_ant[i] > noise_dbm)
++					noise_dbm = noise_dbm_ant[i];
++			}
++			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
++							   PHY_NOISE_WINDOW_SZ);
++
++			wait_for_intr = false;
++		}
++	}
++
++done:
++
++	if (!wait_for_intr)
++		wlc_phy_noise_cb(pi, ch, noise_dbm);
++
++}
++
++void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih)
++{
++	u8 channel;
++
++	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
++
++	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
++}
++
++static const s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	8,
++	9,
++	10,
++	8,
++	8,
++	7,
++	7,
++	1,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	1,
++	1,
++	0,
++	0,
++	0,
++	0
++};
++
++void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
++{
++	u8 msb, secondmsb, i;
++	u32 tmp;
++
++	for (i = 0; i < core; i++) {
++		secondmsb = 0;
++		tmp = cmplx_pwr[i];
++		msb = fls(tmp);
++		if (msb)
++			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
++		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
++	}
++}
++
++int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++			 struct d11rxhdr *rxh)
++{
++	int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
++	uint radioid = pih->radioid;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if ((pi->sh->corerev >= 11)
++	    && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
++		rssi = BRCMS_RSSI_INVALID;
++		goto end;
++	}
++
++	if (ISLCNPHY(pi)) {
++		u8 gidx = (rxh->PhyRxStatus_2 & 0xFC00) >> 10;
++		struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++		if (rssi > 127)
++			rssi -= 256;
++
++		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
++		if ((rssi > -46) && (gidx > 18))
++			rssi = rssi + 7;
++
++		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
++
++		rssi = rssi + 2;
++
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (rssi > 127)
++			rssi -= 256;
++	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
++		   || radioid == BCM2057_ID) {
++		rssi = wlc_phy_rssi_compute_nphy(pi, rxh);
++	}
++
++end:
++	return rssi;
++}
++
++void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih)
++{
++	return;
++}
++
++void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
++{
++	struct brcms_phy *pi;
++	pi = (struct brcms_phy *) ppi;
++
++	if (ISLCNPHY(pi))
++		wlc_lcnphy_deaf_mode(pi, true);
++	else if (ISNPHY(pi))
++		wlc_nphy_deaf_mode(pi, true);
++}
++
++void wlc_phy_watchdog(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	bool delay_phy_cal = false;
++	pi->sh->now++;
++
++	if (!pi->watchdog_override)
++		return;
++
++	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)))
++		wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi,
++					     PHY_NOISE_SAMPLE_MON,
++					     CHSPEC_CHANNEL(pi->
++							    radio_chanspec));
++
++	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5)
++		pi->phynoise_state = 0;
++
++	if ((!pi->phycal_txpower) ||
++	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
++
++		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi))
++			pi->phycal_txpower = pi->sh->now;
++	}
++
++	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++	     || ASSOC_INPROG_PHY(pi)))
++		return;
++
++	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
++
++		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
++		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
++		    ((pi->sh->now - pi->nphy_perical_last) >=
++		     pi->sh->glacial_timer))
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_WATCHDOG);
++
++		wlc_phy_txpwr_papd_cal_nphy(pi);
++	}
++
++	if (ISLCNPHY(pi)) {
++		if (pi->phy_forcecal ||
++		    ((pi->sh->now - pi->phy_lastcal) >=
++		     pi->sh->glacial_timer)) {
++			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
++				wlc_lcnphy_calib_modes(
++					pi,
++					LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++			if (!
++			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
++			     || ASSOC_INPROG_PHY(pi)
++			     || pi->carrier_suppr_disable
++			     || pi->disable_percal))
++				wlc_lcnphy_calib_modes(pi,
++						       PHY_PERICAL_WATCHDOG);
++		}
++	}
++}
++
++void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	uint i;
++	uint k;
++
++	for (i = 0; i < MA_WINDOW_SZ; i++)
++		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
++	if (ISLCNPHY(pi)) {
++		for (i = 0; i < MA_WINDOW_SZ; i++)
++			pi->sh->phy_noise_window[i] =
++				PHY_NOISE_FIXED_VAL_LCNPHY;
++	}
++	pi->sh->phy_noise_index = 0;
++
++	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
++		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
++			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
++	}
++	pi->nphy_noise_index = 0;
++}
++
++void
++wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
++{
++	*eps_imag = (epsilon >> 13);
++	if (*eps_imag > 0xfff)
++		*eps_imag -= 0x2000;
++
++	*eps_real = (epsilon & 0x1fff);
++	if (*eps_real > 0xfff)
++		*eps_real -= 0x2000;
++}
++
++void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi)
++{
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->cal_type_override = PHY_PERICAL_AUTO;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++static void
++wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay)
++{
++
++	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
++	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
++		return;
++
++	wlapi_del_timer(pi->phycal_timer);
++
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	wlapi_add_timer(pi->phycal_timer, delay, 0);
++}
++
++void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
++{
++	s16 nphy_currtemp = 0;
++	s16 delta_temp = 0;
++	bool do_periodic_cal = true;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	if (!ISNPHY(pi))
++		return;
++
++	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
++	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
++		return;
++
++	switch (reason) {
++	case PHY_PERICAL_DRIVERUP:
++		break;
++
++	case PHY_PERICAL_PHYINIT:
++		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++			if (PHY_PERICAL_MPHASE_PENDING(pi))
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			wlc_phy_cal_perical_mphase_schedule(
++				pi,
++				PHY_PERICAL_INIT_DELAY);
++		}
++		break;
++
++	case PHY_PERICAL_JOIN_BSS:
++	case PHY_PERICAL_START_IBSS:
++	case PHY_PERICAL_UP_BSS:
++		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
++		    PHY_PERICAL_MPHASE_PENDING(pi))
++			wlc_phy_cal_perical_mphase_reset(pi);
++
++		pi->first_cal_after_assoc = true;
++
++		pi->cal_type_override = PHY_PERICAL_FULL;
++
++		if (pi->phycal_tempdelta)
++			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
++
++		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
++		break;
++
++	case PHY_PERICAL_WATCHDOG:
++		if (pi->phycal_tempdelta) {
++			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++			delta_temp =
++				(nphy_currtemp > pi->nphy_lastcal_temp) ?
++				nphy_currtemp - pi->nphy_lastcal_temp :
++				pi->nphy_lastcal_temp - nphy_currtemp;
++
++			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
++			    (pi->nphy_txiqlocal_chanspec ==
++			     pi->radio_chanspec))
++				do_periodic_cal = false;
++			else
++				pi->nphy_lastcal_temp = nphy_currtemp;
++		}
++
++		if (do_periodic_cal) {
++			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
++				if (!PHY_PERICAL_MPHASE_PENDING(pi))
++					wlc_phy_cal_perical_mphase_schedule(
++						pi,
++						PHY_PERICAL_WDOG_DELAY);
++			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
++				wlc_phy_cal_perical_nphy_run(pi,
++							     PHY_PERICAL_AUTO);
++		}
++		break;
++	default:
++		break;
++	}
++}
++
++void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi)
++{
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
++	pi->mphase_txcal_cmdidx = 0;
++}
++
++u8 wlc_phy_nbits(s32 value)
++{
++	s32 abs_val;
++	u8 nbits = 0;
++
++	abs_val = abs(value);
++	while ((abs_val >> nbits) > 0)
++		nbits++;
++
++	return nbits;
++}
++
++void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->hw_phytxchain = txchain;
++	pi->sh->hw_phyrxchain = rxchain;
++	pi->sh->phytxchain = txchain;
++	pi->sh->phyrxchain = rxchain;
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	pi->sh->phytxchain = txchain;
++
++	if (ISNPHY(pi))
++		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
++
++	pi->pubpi.phy_corenum = (u8)hweight8(pi->sh->phyrxchain);
++}
++
++void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	*txchain = pi->sh->phytxchain;
++	*rxchain = pi->sh->phyrxchain;
++}
++
++u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
++{
++	s16 nphy_currtemp;
++	u8 active_bitmap;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
++
++	if (!pi->watchdog_override)
++		return active_bitmap;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
++		wlapi_enable_mac(pi->sh->physhim);
++
++		if (!pi->phy_txcore_heatedup) {
++			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
++				active_bitmap &= 0xFD;
++				pi->phy_txcore_heatedup = true;
++			}
++		} else {
++			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
++				active_bitmap |= 0x2;
++				pi->phy_txcore_heatedup = false;
++			}
++		}
++	}
++
++	return active_bitmap;
++}
++
++s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u8 siso_mcs_id, cdd_mcs_id;
++
++	siso_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
++		TXP_FIRST_MCS_20_SISO;
++	cdd_mcs_id =
++		(CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
++		TXP_FIRST_MCS_20_CDD;
++
++	if (pi->tx_power_target[siso_mcs_id] >
++	    (pi->tx_power_target[cdd_mcs_id] + 12))
++		return PHY_TXC1_MODE_SISO;
++	else
++		return PHY_TXC1_MODE_CDD;
++}
++
++const u8 *wlc_phy_get_ofdm_rate_lookup(void)
++{
++	return ofdm_rate_lookup;
++}
++
++void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
++{
++	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
++	    (pi->sh->boardflags & BFL_FEM)) {
++		if (mode) {
++			u16 txant = 0;
++			txant = wlapi_bmac_get_txant(pi->sh->physhim);
++			if (txant == 1) {
++				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
++
++			}
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x40);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x40);
++		} else {
++			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
++
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioout),
++				  0x40, 0x00);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpioouten),
++				  0x40, 0x0);
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, gpiocontrol),
++				  ~0x0, 0x40);
++		}
++	}
++}
++
++void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc)
++{
++	return;
++}
++
++void
++wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset)
++{
++	*cckoffset = 0;
++	*ofdmoffset = 0;
++}
++
++s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
++{
++
++	return rssi;
++}
++
++bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	if (ISNPHY(pi))
++		return wlc_phy_n_txpower_ipa_ison(pi);
++	else
++		return 0;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+new file mode 100644
+index 0000000..e34a71e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
+@@ -0,0 +1,299 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_hal.h:  functionality exported from the phy to higher layers
++ */
++
++#ifndef _BRCM_PHY_HAL_H_
++#define _BRCM_PHY_HAL_H_
++
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++#include <phy_shim.h>
++
++#define	IDCODE_VER_MASK		0x0000000f
++#define	IDCODE_VER_SHIFT	0
++#define	IDCODE_MFG_MASK		0x00000fff
++#define	IDCODE_MFG_SHIFT	0
++#define	IDCODE_ID_MASK		0x0ffff000
++#define	IDCODE_ID_SHIFT		12
++#define	IDCODE_REV_MASK		0xf0000000
++#define	IDCODE_REV_SHIFT	28
++
++#define	NORADIO_ID		0xe4f5
++#define	NORADIO_IDCODE		0x4e4f5246
++
++#define BCM2055_ID		0x2055
++#define BCM2055_IDCODE		0x02055000
++#define BCM2055A0_IDCODE	0x1205517f
++
++#define BCM2056_ID		0x2056
++#define BCM2056_IDCODE		0x02056000
++#define BCM2056A0_IDCODE	0x1205617f
++
++#define BCM2057_ID		0x2057
++#define BCM2057_IDCODE		0x02057000
++#define BCM2057A0_IDCODE	0x1205717f
++
++#define BCM2064_ID		0x2064
++#define BCM2064_IDCODE		0x02064000
++#define BCM2064A0_IDCODE	0x0206417f
++
++#define PHY_TPC_HW_OFF		false
++#define PHY_TPC_HW_ON		true
++
++#define PHY_PERICAL_DRIVERUP	1
++#define PHY_PERICAL_WATCHDOG	2
++#define PHY_PERICAL_PHYINIT	3
++#define PHY_PERICAL_JOIN_BSS	4
++#define PHY_PERICAL_START_IBSS	5
++#define PHY_PERICAL_UP_BSS	6
++#define PHY_PERICAL_CHAN	7
++#define PHY_FULLCAL	8
++
++#define PHY_PERICAL_DISABLE	0
++#define PHY_PERICAL_SPHASE	1
++#define PHY_PERICAL_MPHASE	2
++#define PHY_PERICAL_MANUAL	3
++
++#define PHY_HOLD_FOR_ASSOC	1
++#define PHY_HOLD_FOR_SCAN	2
++#define PHY_HOLD_FOR_RM		4
++#define PHY_HOLD_FOR_PLT	8
++#define PHY_HOLD_FOR_MUTE	16
++#define PHY_HOLD_FOR_NOT_ASSOC 0x20
++
++#define PHY_MUTE_FOR_PREISM	1
++#define PHY_MUTE_ALL		0xffffffff
++
++#define PHY_NOISE_FIXED_VAL		(-95)
++#define PHY_NOISE_FIXED_VAL_NPHY	(-92)
++#define PHY_NOISE_FIXED_VAL_LCNPHY	(-92)
++
++#define PHY_MODE_CAL		0x0002
++#define PHY_MODE_NOISEM		0x0004
++
++#define BRCMS_TXPWR_DB_FACTOR	4
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++#define BRCMS_NUM_RATES_CCK           4
++#define BRCMS_NUM_RATES_OFDM          8
++#define BRCMS_NUM_RATES_MCS_1_STREAM  8
++#define BRCMS_NUM_RATES_MCS_2_STREAM  8
++#define BRCMS_NUM_RATES_MCS_3_STREAM  8
++#define BRCMS_NUM_RATES_MCS_4_STREAM  8
++
++#define	BRCMS_RSSI_INVALID	 0	/* invalid RSSI value */
++
++struct d11regs;
++struct phy_shim_info;
++
++struct txpwr_limits {
++	u8 cck[BRCMS_NUM_RATES_CCK];
++	u8 ofdm[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
++	u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
++
++	u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++
++	u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
++	u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
++	u8 mcs32;
++};
++
++struct tx_power {
++	u32 flags;
++	u16 chanspec;   /* txpwr report for this channel */
++	u16 local_chanspec;     /* channel on which we are associated */
++	u8 local_max;   /* local max according to the AP */
++	u8 local_constraint;    /* local constraint according to the AP */
++	s8 antgain[2];  /* Ant gain for each band - from SROM */
++	u8 rf_cores;            /* count of RF Cores being reported */
++	u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
++	u8 est_Pout_act[4];     /* Latest tx power out estimate per RF chain
++				 * without adjustment */
++	u8 est_Pout_cck;        /* Latest CCK tx power out estimate */
++	u8 tx_power_max[4];     /* Maximum target power among all rates */
++	/* Index of the rate with the max target power */
++	u8 tx_power_max_rate_ind[4];
++	/* User limit */
++	u8 user_limit[WL_TX_POWER_RATES];
++	/* Regulatory power limit */
++	u8 reg_limit[WL_TX_POWER_RATES];
++	/* Max power board can support (SROM) */
++	u8 board_limit[WL_TX_POWER_RATES];
++	/* Latest target power */
++	u8 target[WL_TX_POWER_RATES];
++};
++
++struct tx_inst_power {
++	u8 txpwr_est_Pout[2];   /* Latest estimate for 2.4 and 5 Ghz */
++	u8 txpwr_est_Pout_gofdm;        /* Pwr estimate for 2.4 OFDM */
++};
++
++struct brcms_chanvec {
++	u8 vec[MAXCHANNEL / NBBY];
++};
++
++struct shared_phy_params {
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint unit;
++	uint corerev;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++};
++
++
++extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
++extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
++					    struct bcma_device *d11core,
++					    int bandtype, struct wiphy *wiphy);
++extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
++
++extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
++				   u16 *phyrev, u16 *radioid,
++				   u16 *radiover);
++extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
++extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
++extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
++extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
++extern int wlc_phy_down(struct brcms_phy_pub *ppi);
++extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
++extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
++extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
++
++extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
++				 u16 chanspec);
++extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
++				       u16 newch);
++extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
++
++extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
++				struct d11rxhdr *rxh);
++extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
++extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
++
++extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
++extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
++
++
++extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
++
++extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
++						 bool wide_filter);
++extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
++					  struct brcms_chanvec *channels);
++extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
++					 uint band);
++
++extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
++				      u8 *_min_, u8 *_max_, int rate);
++extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
++					      uint chan, u8 *_max_, u8 *_min_);
++extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
++					    uint band, s32 *, s32 *, u32 *);
++extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
++				      struct txpwr_limits *,
++				      u16 chanspec);
++extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
++			       bool *override);
++extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
++			       bool override);
++extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
++				       struct txpwr_limits *);
++extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
++					bool hwpwrctrl);
++extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
++extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
++extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
++				   u8 rxchain);
++extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
++				  u8 rxchain);
++extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
++				  u8 *rxchain);
++extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
++extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
++				 u16 chanspec);
++extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
++
++extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
++extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
++extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
++extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
++
++extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
++extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
++extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
++extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
++
++extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
++
++extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
++					struct tx_power *power, uint channel);
++
++extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
++extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
++extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
++				      u8 txpwr_percent);
++extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
++extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
++				      bool bf_preempt);
++extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
++
++extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
++
++extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
++extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
++
++extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
++
++extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
++					     u8 mcs_offset);
++extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
++#endif                          /* _BRCM_PHY_HAL_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+new file mode 100644
+index 0000000..af00e2c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
+@@ -0,0 +1,1162 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_INT_H_
++#define _BRCM_PHY_INT_H_
++
++#include <types.h>
++#include <brcmu_utils.h>
++#include <brcmu_wifi.h>
++
++#define	PHY_VERSION			{ 1, 82, 8, 0 }
++
++#define LCNXN_BASEREV		16
++
++struct phy_shim_info;
++
++struct brcms_phy_srom_fem {
++	/* TSSI positive slope, 1: positive, 0: negative */
++	u8 tssipos;
++	/* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
++	u8 extpagain;
++	/* support 32 combinations of different Pdet dynamic ranges */
++	u8 pdetrange;
++	/* TR switch isolation */
++	u8 triso;
++	/* antswctrl lookup table configuration: 32 possible choices */
++	u8 antswctrllut;
++};
++
++#define ISNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
++#define ISLCNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
++
++#define PHY_GET_RFATTN(rfgain)	((rfgain) & 0x0f)
++#define PHY_GET_PADMIX(rfgain)	(((rfgain) & 0x10) >> 4)
++#define PHY_GET_RFGAINID(rfattn, padmix, width)	((rfattn) + ((padmix)*(width)))
++#define PHY_SAT(x, n)		((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
++				((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
++#define PHY_SHIFT_ROUND(x, n)	((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
++#define PHY_HW_ROUND(x, s)		((x >> s) + ((x >> (s-1)) & (s != 0)))
++
++#define CH_5G_GROUP	3
++#define A_LOW_CHANS	0
++#define A_MID_CHANS	1
++#define A_HIGH_CHANS	2
++#define CH_2G_GROUP	1
++#define G_ALL_CHANS	0
++
++#define FIRST_REF5_CHANNUM	149
++#define LAST_REF5_CHANNUM	165
++#define	FIRST_5G_CHAN		14
++#define	LAST_5G_CHAN		50
++#define	FIRST_MID_5G_CHAN	14
++#define	LAST_MID_5G_CHAN	35
++#define	FIRST_HIGH_5G_CHAN	36
++#define	LAST_HIGH_5G_CHAN	41
++#define	FIRST_LOW_5G_CHAN	42
++#define	LAST_LOW_5G_CHAN	50
++
++#define BASE_LOW_5G_CHAN	4900
++#define BASE_MID_5G_CHAN	5100
++#define BASE_HIGH_5G_CHAN	5500
++
++#define CHAN5G_FREQ(chan)  (5000 + chan*5)
++#define CHAN2G_FREQ(chan)  (2407 + chan*5)
++
++#define TXP_FIRST_CCK		0
++#define TXP_LAST_CCK		3
++#define TXP_FIRST_OFDM		4
++#define TXP_LAST_OFDM		11
++#define TXP_FIRST_OFDM_20_CDD	12
++#define TXP_LAST_OFDM_20_CDD	19
++#define TXP_FIRST_MCS_20_SISO	20
++#define TXP_LAST_MCS_20_SISO	27
++#define TXP_FIRST_MCS_20_CDD	28
++#define TXP_LAST_MCS_20_CDD	35
++#define TXP_FIRST_MCS_20_STBC	36
++#define TXP_LAST_MCS_20_STBC	43
++#define TXP_FIRST_MCS_20_SDM	44
++#define TXP_LAST_MCS_20_SDM	51
++#define TXP_FIRST_OFDM_40_SISO	52
++#define TXP_LAST_OFDM_40_SISO	59
++#define TXP_FIRST_OFDM_40_CDD	60
++#define TXP_LAST_OFDM_40_CDD	67
++#define TXP_FIRST_MCS_40_SISO	68
++#define TXP_LAST_MCS_40_SISO	75
++#define TXP_FIRST_MCS_40_CDD	76
++#define TXP_LAST_MCS_40_CDD	83
++#define TXP_FIRST_MCS_40_STBC	84
++#define TXP_LAST_MCS_40_STBC	91
++#define TXP_FIRST_MCS_40_SDM	92
++#define TXP_LAST_MCS_40_SDM	99
++#define TXP_MCS_32	        100
++#define TXP_NUM_RATES		101
++#define ADJ_PWR_TBL_LEN		84
++
++#define TXP_FIRST_SISO_MCS_20	20
++#define TXP_LAST_SISO_MCS_20	27
++
++#define PHY_CORE_NUM_1	1
++#define PHY_CORE_NUM_2	2
++#define PHY_CORE_NUM_3	3
++#define PHY_CORE_NUM_4	4
++#define PHY_CORE_MAX	PHY_CORE_NUM_4
++#define PHY_CORE_0	0
++#define PHY_CORE_1	1
++#define PHY_CORE_2	2
++#define PHY_CORE_3	3
++
++#define MA_WINDOW_SZ		8
++
++#define PHY_NOISE_SAMPLE_MON		1
++#define PHY_NOISE_SAMPLE_EXTERNAL	2
++#define PHY_NOISE_WINDOW_SZ	16
++#define PHY_NOISE_GLITCH_INIT_MA 10
++#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
++#define PHY_NOISE_STATE_MON		0x1
++#define PHY_NOISE_STATE_EXTERNAL	0x2
++#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY	10
++#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE	9
++
++#define PHY_NOISE_OFFSETFACT_4322  (-103)
++#define PHY_NOISE_MA_WINDOW_SZ	2
++
++#define	PHY_RSSI_TABLE_SIZE	64
++#define RSSI_ANT_MERGE_MAX	0
++#define RSSI_ANT_MERGE_MIN	1
++#define RSSI_ANT_MERGE_AVG	2
++
++#define	PHY_TSSI_TABLE_SIZE	64
++#define	APHY_TSSI_TABLE_SIZE	256
++#define	TX_GAIN_TABLE_LENGTH	64
++#define	DEFAULT_11A_TXP_IDX	24
++#define NUM_TSSI_FRAMES        4
++#define	NULL_TSSI		0x7f
++#define	NULL_TSSI_W		0x7f7f
++
++#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
++
++#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
++
++#define PHY_TXPWR_MIN		10
++#define PHY_TXPWR_MIN_NPHY	8
++#define RADIOPWR_OVERRIDE_DEF	(-1)
++
++#define PWRTBL_NUM_COEFF	3
++
++#define SPURAVOID_DISABLE	0
++#define SPURAVOID_AUTO		1
++#define SPURAVOID_FORCEON	2
++#define SPURAVOID_FORCEON2	3
++
++#define PHY_SW_TIMER_FAST		15
++#define PHY_SW_TIMER_SLOW		60
++#define PHY_SW_TIMER_GLACIAL	120
++
++#define PHY_PERICAL_AUTO	0
++#define PHY_PERICAL_FULL	1
++#define PHY_PERICAL_PARTIAL	2
++
++#define PHY_PERICAL_NODELAY	0
++#define PHY_PERICAL_INIT_DELAY	5
++#define PHY_PERICAL_ASSOC_DELAY	5
++#define PHY_PERICAL_WDOG_DELAY	5
++
++#define MPHASE_TXCAL_NUMCMDS	2
++
++#define PHY_PERICAL_MPHASE_PENDING(pi) \
++	(pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
++
++enum {
++	MPHASE_CAL_STATE_IDLE = 0,
++	MPHASE_CAL_STATE_INIT = 1,
++	MPHASE_CAL_STATE_TXPHASE0,
++	MPHASE_CAL_STATE_TXPHASE1,
++	MPHASE_CAL_STATE_TXPHASE2,
++	MPHASE_CAL_STATE_TXPHASE3,
++	MPHASE_CAL_STATE_TXPHASE4,
++	MPHASE_CAL_STATE_TXPHASE5,
++	MPHASE_CAL_STATE_PAPDCAL,
++	MPHASE_CAL_STATE_RXCAL,
++	MPHASE_CAL_STATE_RSSICAL,
++	MPHASE_CAL_STATE_IDLETSSI
++};
++
++enum phy_cal_mode {
++	CAL_FULL,
++	CAL_RECAL,
++	CAL_CURRECAL,
++	CAL_DIGCAL,
++	CAL_GCTRL,
++	CAL_SOFT,
++	CAL_DIGLO
++};
++
++#define RDR_NTIERS  1
++#define RDR_TIER_SIZE 64
++#define RDR_LIST_SIZE (512/3)
++#define RDR_EPOCH_SIZE 40
++#define RDR_NANTENNAS 2
++#define RDR_NTIER_SIZE  RDR_LIST_SIZE
++#define RDR_LP_BUFFER_SIZE 64
++#define LP_LEN_HIS_SIZE 10
++
++#define STATIC_NUM_RF 32
++#define STATIC_NUM_BB 9
++
++#define BB_MULT_MASK		0x0000ffff
++#define BB_MULT_VALID_MASK	0x80000000
++
++#define CORDIC_AG	39797
++#define	CORDIC_NI	18
++#define	FIXED(X)	((s32)((X) << 16))
++
++#define	FLOAT(X) \
++	(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
++
++#define PHY_CHAIN_TX_DISABLE_TEMP	115
++#define PHY_HYSTERESIS_DELTATEMP	5
++
++#define SCAN_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
++
++#define PLT_INPROG_PHY(pi)      (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
++
++#define ASSOC_INPROG_PHY(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
++
++#define SCAN_RM_IN_PROGRESS(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
++
++#define PHY_MUTED(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
++
++#define PUB_NOT_ASSOC(pi) \
++	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
++
++struct phy_table_info {
++	uint table;
++	int q;
++	uint max;
++};
++
++struct phytbl_info {
++	const void *tbl_ptr;
++	u32 tbl_len;
++	u32 tbl_id;
++	u32 tbl_offset;
++	u32 tbl_width;
++};
++
++struct interference_info {
++	u8 curr_home_channel;
++	u16 crsminpwrthld_40_stored;
++	u16 crsminpwrthld_20L_stored;
++	u16 crsminpwrthld_20U_stored;
++	u16 init_gain_code_core1_stored;
++	u16 init_gain_code_core2_stored;
++	u16 init_gain_codeb_core1_stored;
++	u16 init_gain_codeb_core2_stored;
++	u16 init_gain_table_stored[4];
++
++	u16 clip1_hi_gain_code_core1_stored;
++	u16 clip1_hi_gain_code_core2_stored;
++	u16 clip1_hi_gain_codeb_core1_stored;
++	u16 clip1_hi_gain_codeb_core2_stored;
++	u16 nb_clip_thresh_core1_stored;
++	u16 nb_clip_thresh_core2_stored;
++	u16 init_ofdmlna2gainchange_stored[4];
++	u16 init_ccklna2gainchange_stored[4];
++	u16 clip1_lo_gain_code_core1_stored;
++	u16 clip1_lo_gain_code_core2_stored;
++	u16 clip1_lo_gain_codeb_core1_stored;
++	u16 clip1_lo_gain_codeb_core2_stored;
++	u16 w1_clip_thresh_core1_stored;
++	u16 w1_clip_thresh_core2_stored;
++	u16 radio_2056_core1_rssi_gain_stored;
++	u16 radio_2056_core2_rssi_gain_stored;
++	u16 energy_drop_timeout_len_stored;
++
++	u16 ed_crs40_assertthld0_stored;
++	u16 ed_crs40_assertthld1_stored;
++	u16 ed_crs40_deassertthld0_stored;
++	u16 ed_crs40_deassertthld1_stored;
++	u16 ed_crs20L_assertthld0_stored;
++	u16 ed_crs20L_assertthld1_stored;
++	u16 ed_crs20L_deassertthld0_stored;
++	u16 ed_crs20L_deassertthld1_stored;
++	u16 ed_crs20U_assertthld0_stored;
++	u16 ed_crs20U_assertthld1_stored;
++	u16 ed_crs20U_deassertthld0_stored;
++	u16 ed_crs20U_deassertthld1_stored;
++
++	u16 badplcp_ma;
++	u16 badplcp_ma_previous;
++	u16 badplcp_ma_total;
++	u16 badplcp_ma_list[MA_WINDOW_SZ];
++	int badplcp_ma_index;
++	s16 pre_badplcp_cnt;
++	s16 bphy_pre_badplcp_cnt;
++
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u16 init_gain_rfseq[4];
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++
++	s16 crsminpwr_index;
++
++	u16 radio_2057_core1_rssi_wb1a_gc_stored;
++	u16 radio_2057_core2_rssi_wb1a_gc_stored;
++	u16 radio_2057_core1_rssi_wb1g_gc_stored;
++	u16 radio_2057_core2_rssi_wb1g_gc_stored;
++	u16 radio_2057_core1_rssi_wb2_gc_stored;
++	u16 radio_2057_core2_rssi_wb2_gc_stored;
++	u16 radio_2057_core1_rssi_nb_gc_stored;
++	u16 radio_2057_core2_rssi_nb_gc_stored;
++};
++
++struct aci_save_gphy {
++	u16 rc_cal_ovr;
++	u16 phycrsth1;
++	u16 phycrsth2;
++	u16 init_n1p1_gain;
++	u16 p1_p2_gain;
++	u16 n1_n2_gain;
++	u16 n1_p1_gain;
++	u16 div_search_gain;
++	u16 div_p1_p2_gain;
++	u16 div_search_gn_change;
++	u16 table_7_2;
++	u16 table_7_3;
++	u16 cckshbits_gnref;
++	u16 clip_thresh;
++	u16 clip2_thresh;
++	u16 clip3_thresh;
++	u16 clip_p2_thresh;
++	u16 clip_pwdn_thresh;
++	u16 clip_n1p1_thresh;
++	u16 clip_n1_pwdn_thresh;
++	u16 bbconfig;
++	u16 cthr_sthr_shdin;
++	u16 energy;
++	u16 clip_p1_p2_thresh;
++	u16 threshold;
++	u16 reg15;
++	u16 reg16;
++	u16 reg17;
++	u16 div_srch_idx;
++	u16 div_srch_p1_p2;
++	u16 div_srch_gn_back;
++	u16 ant_dwell;
++	u16 ant_wr_settle;
++};
++
++struct lo_complex_abgphy_info {
++	s8 i;
++	s8 q;
++};
++
++struct nphy_iq_comp {
++	s16 a0;
++	s16 b0;
++	s16 a1;
++	s16 b1;
++};
++
++struct nphy_txpwrindex {
++	s8 index;
++	s8 index_internal;
++	s8 index_internal_save;
++	u16 AfectrlOverride;
++	u16 AfeCtrlDacGain;
++	u16 rad_gain;
++	u8 bbmult;
++	u16 iqcomp_a;
++	u16 iqcomp_b;
++	u16 locomp;
++};
++
++struct txiqcal_cache {
++
++	u16 txcal_coeffs_2G[8];
++	u16 txcal_radio_regs_2G[8];
++	struct nphy_iq_comp rxcal_coeffs_2G;
++
++	u16 txcal_coeffs_5G[8];
++	u16 txcal_radio_regs_5G[8];
++	struct nphy_iq_comp rxcal_coeffs_5G;
++};
++
++struct nphy_pwrctrl {
++	s8 max_pwr_2g;
++	s8 idle_targ_2g;
++	s16 pwrdet_2g_a1;
++	s16 pwrdet_2g_b0;
++	s16 pwrdet_2g_b1;
++	s8 max_pwr_5gm;
++	s8 idle_targ_5gm;
++	s8 max_pwr_5gh;
++	s8 max_pwr_5gl;
++	s16 pwrdet_5gm_a1;
++	s16 pwrdet_5gm_b0;
++	s16 pwrdet_5gm_b1;
++	s16 pwrdet_5gl_a1;
++	s16 pwrdet_5gl_b0;
++	s16 pwrdet_5gl_b1;
++	s16 pwrdet_5gh_a1;
++	s16 pwrdet_5gh_b0;
++	s16 pwrdet_5gh_b1;
++	s8 idle_targ_5gl;
++	s8 idle_targ_5gh;
++	s8 idle_tssi_2g;
++	s8 idle_tssi_5g;
++	s8 idle_tssi;
++	s16 a1;
++	s16 b0;
++	s16 b1;
++};
++
++struct nphy_txgains {
++	u16 txlpf[2];
++	u16 txgm[2];
++	u16 pga[2];
++	u16 pad[2];
++	u16 ipa[2];
++};
++
++#define PHY_NOISEVAR_BUFSIZE 10
++
++struct nphy_noisevar_buf {
++	int bufcount;
++	int tone_id[PHY_NOISEVAR_BUFSIZE];
++	u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
++	u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
++};
++
++struct rssical_cache {
++	u16 rssical_radio_regs_2G[2];
++	u16 rssical_phyregs_2G[12];
++
++	u16 rssical_radio_regs_5G[2];
++	u16 rssical_phyregs_5G[12];
++};
++
++struct lcnphy_cal_results {
++
++	u16 txiqlocal_a;
++	u16 txiqlocal_b;
++	u16 txiqlocal_didq;
++	u8 txiqlocal_ei0;
++	u8 txiqlocal_eq0;
++	u8 txiqlocal_fi0;
++	u8 txiqlocal_fq0;
++
++	u16 txiqlocal_bestcoeffs[11];
++	u16 txiqlocal_bestcoeffs_valid;
++
++	u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
++	u16 analog_gain_ref;
++	u16 lut_begin;
++	u16 lut_end;
++	u16 lut_step;
++	u16 rxcompdbm;
++	u16 papdctrl;
++	u16 sslpnCalibClkEnCtrl;
++
++	u16 rxiqcal_coeff_a0;
++	u16 rxiqcal_coeff_b0;
++};
++
++struct shared_phy {
++	struct brcms_phy *phy_head;
++	uint unit;
++	struct si_pub *sih;
++	struct phy_shim_info *physhim;
++	uint corerev;
++	u32 machwcap;
++	bool up;
++	bool clk;
++	uint now;
++	u16 vid;
++	u16 did;
++	uint chip;
++	uint chiprev;
++	uint chippkg;
++	uint sromrev;
++	uint boardtype;
++	uint boardrev;
++	u32 boardflags;
++	u32 boardflags2;
++	uint fast_timer;
++	uint slow_timer;
++	uint glacial_timer;
++	u8 rx_antdiv;
++	s8 phy_noise_window[MA_WINDOW_SZ];
++	uint phy_noise_index;
++	u8 hw_phytxchain;
++	u8 hw_phyrxchain;
++	u8 phytxchain;
++	u8 phyrxchain;
++	u8 rssi_mode;
++	bool _rifs_phy;
++};
++
++struct brcms_phy_pub {
++	uint phy_type;
++	uint phy_rev;
++	u8 phy_corenum;
++	u16 radioid;
++	u8 radiorev;
++	u8 radiover;
++
++	uint coreflags;
++	uint ana_rev;
++	bool abgphy_encore;
++};
++
++struct phy_func_ptr {
++	void (*init)(struct brcms_phy *);
++	void (*calinit)(struct brcms_phy *);
++	void (*chanset)(struct brcms_phy *, u16 chanspec);
++	void (*txpwrrecalc)(struct brcms_phy *);
++	int (*longtrn)(struct brcms_phy *, int);
++	void (*txiqccget)(struct brcms_phy *, u16 *, u16 *);
++	void (*txiqccset)(struct brcms_phy *, u16, u16);
++	u16 (*txloccget)(struct brcms_phy *);
++	void (*radioloftget)(struct brcms_phy *, u8 *, u8 *, u8 *, u8 *);
++	void (*carrsuppr)(struct brcms_phy *);
++	s32 (*rxsigpwr)(struct brcms_phy *, s32);
++	void (*detach)(struct brcms_phy *);
++};
++
++struct brcms_phy {
++	struct brcms_phy_pub pubpi_ro;
++	struct shared_phy *sh;
++	struct phy_func_ptr pi_fptr;
++
++	union {
++		struct brcms_phy_lcnphy *pi_lcnphy;
++	} u;
++	bool user_txpwr_at_rfport;
++
++	struct bcma_device *d11core;
++	struct brcms_phy *next;
++	struct brcms_phy_pub pubpi;
++
++	bool do_initcal;
++	bool phytest_on;
++	bool ofdm_rateset_war;
++	bool bf_preempt_4306;
++	u16 radio_chanspec;
++	u8 antsel_type;
++	u16 bw;
++	u8 txpwr_percent;
++	bool phy_init_por;
++
++	bool init_in_progress;
++	bool initialized;
++	bool sbtml_gm;
++	uint refcnt;
++	bool watchdog_override;
++	u8 phynoise_state;
++	uint phynoise_now;
++	int phynoise_chan_watchdog;
++	bool phynoise_polling;
++	bool disable_percal;
++	u32 measure_hold;
++
++	s16 txpa_2g[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_low[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
++	s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
++
++	u8 tx_srom_max_2g;
++	u8 tx_srom_max_5g_low;
++	u8 tx_srom_max_5g_mid;
++	u8 tx_srom_max_5g_hi;
++	u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
++	u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
++	u8 tx_user_target[TXP_NUM_RATES];
++	s8 tx_power_offset[TXP_NUM_RATES];
++	u8 tx_power_target[TXP_NUM_RATES];
++
++	struct brcms_phy_srom_fem srom_fem2g;
++	struct brcms_phy_srom_fem srom_fem5g;
++
++	u8 tx_power_max;
++	u8 tx_power_max_rate_ind;
++	bool hwpwrctrl;
++	u8 nphy_txpwrctrl;
++	s8 nphy_txrx_chain;
++	bool phy_5g_pwrgain;
++
++	u16 phy_wreg;
++	u16 phy_wreg_limit;
++
++	s8 n_preamble_override;
++	u8 antswitch;
++	u8 aa2g, aa5g;
++
++	s8 idle_tssi[CH_5G_GROUP];
++	s8 target_idle_tssi;
++	s8 txpwr_est_Pout;
++	u8 tx_power_min;
++	u8 txpwr_limit[TXP_NUM_RATES];
++	u8 txpwr_env_limit[TXP_NUM_RATES];
++	u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
++
++	bool channel_14_wide_filter;
++
++	bool txpwroverride;
++	bool txpwridx_override_aphy;
++	s16 radiopwr_override;
++	u16 hwpwr_txcur;
++	u8 saved_txpwr_idx;
++
++	bool edcrs_threshold_lock;
++
++	u32 tr_R_gain_val;
++	u32 tr_T_gain_val;
++
++	s16 ofdm_analog_filt_bw_override;
++	s16 cck_analog_filt_bw_override;
++	s16 ofdm_rccal_override;
++	s16 cck_rccal_override;
++	u16 extlna_type;
++
++	uint interference_mode_crs_time;
++	u16 crsglitch_prev;
++	bool interference_mode_crs;
++
++	u32 phy_tx_tone_freq;
++	uint phy_lastcal;
++	bool phy_forcecal;
++	bool phy_fixed_noise;
++	u32 xtalfreq;
++	u8 pdiv;
++	s8 carrier_suppr_disable;
++
++	bool phy_bphy_evm;
++	bool phy_bphy_rfcs;
++	s8 phy_scraminit;
++	u8 phy_gpiosel;
++
++	s16 phy_txcore_disable_temp;
++	s16 phy_txcore_enable_temp;
++	s8 phy_tempsense_offset;
++	bool phy_txcore_heatedup;
++
++	u16 radiopwr;
++	u16 bb_atten;
++	u16 txctl1;
++
++	u16 mintxbias;
++	u16 mintxmag;
++	struct lo_complex_abgphy_info gphy_locomp_iq
++			[STATIC_NUM_RF][STATIC_NUM_BB];
++	s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
++	u16 gain_table[TX_GAIN_TABLE_LENGTH];
++	bool loopback_gain;
++	s16 max_lpback_gain_hdB;
++	s16 trsw_rx_gain_hdB;
++	u8 power_vec[8];
++
++	u16 rc_cal;
++	int nrssi_table_delta;
++	int nrssi_slope_scale;
++	int nrssi_slope_offset;
++	int min_rssi;
++	int max_rssi;
++
++	s8 txpwridx;
++	u8 min_txpower;
++
++	u8 a_band_high_disable;
++
++	u16 tx_vos;
++	u16 global_tx_bb_dc_bias_loft;
++
++	int rf_max;
++	int bb_max;
++	int rf_list_size;
++	int bb_list_size;
++	u16 *rf_attn_list;
++	u16 *bb_attn_list;
++	u16 padmix_mask;
++	u16 padmix_reg;
++	u16 *txmag_list;
++	uint txmag_len;
++	bool txmag_enable;
++
++	s8 *a_tssi_to_dbm;
++	s8 *m_tssi_to_dbm;
++	s8 *l_tssi_to_dbm;
++	s8 *h_tssi_to_dbm;
++	u8 *hwtxpwr;
++
++	u16 freqtrack_saved_regs[2];
++	int cur_interference_mode;
++	bool hwpwrctrl_capable;
++	bool temppwrctrl_capable;
++
++	uint phycal_nslope;
++	uint phycal_noffset;
++	uint phycal_mlo;
++	uint phycal_txpower;
++
++	u8 phy_aa2g;
++
++	bool nphy_tableloaded;
++	s8 nphy_rssisel;
++	u32 nphy_bb_mult_save;
++	u16 nphy_txiqlocal_bestc[11];
++	bool nphy_txiqlocal_coeffsvalid;
++	struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2];
++	struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2];
++	u16 cck2gpo;
++	u32 ofdm2gpo;
++	u32 ofdm5gpo;
++	u32 ofdm5glpo;
++	u32 ofdm5ghpo;
++	u8 bw402gpo;
++	u8 bw405gpo;
++	u8 bw405glpo;
++	u8 bw405ghpo;
++	u8 cdd2gpo;
++	u8 cdd5gpo;
++	u8 cdd5glpo;
++	u8 cdd5ghpo;
++	u8 stbc2gpo;
++	u8 stbc5gpo;
++	u8 stbc5glpo;
++	u8 stbc5ghpo;
++	u8 bwdup2gpo;
++	u8 bwdup5gpo;
++	u8 bwdup5glpo;
++	u8 bwdup5ghpo;
++	u16 mcs2gpo[8];
++	u16 mcs5gpo[8];
++	u16 mcs5glpo[8];
++	u16 mcs5ghpo[8];
++	u32 nphy_rxcalparams;
++
++	u8 phy_spuravoid;
++	bool phy_isspuravoid;
++
++	u8 phy_pabias;
++	u8 nphy_papd_skip;
++	u8 nphy_tssi_slope;
++
++	s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
++	u8 nphy_noise_index;
++
++	bool nphy_gain_boost;
++	bool nphy_elna_gain_config;
++	u16 old_bphy_test;
++	u16 old_bphy_testcontrol;
++
++	bool phyhang_avoid;
++
++	bool rssical_nphy;
++	u8 nphy_perical;
++	uint nphy_perical_last;
++	u8 cal_type_override;
++	u8 mphase_cal_phase_id;
++	u8 mphase_txcal_cmdidx;
++	u8 mphase_txcal_numcmds;
++	u16 mphase_txcal_bestcoeffs[11];
++	u16 nphy_txiqlocal_chanspec;
++	u16 nphy_iqcal_chanspec_2G;
++	u16 nphy_iqcal_chanspec_5G;
++	u16 nphy_rssical_chanspec_2G;
++	u16 nphy_rssical_chanspec_5G;
++	struct wlapi_timer *phycal_timer;
++	bool use_int_tx_iqlo_cal_nphy;
++	bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
++	s16 nphy_lastcal_temp;
++
++	struct txiqcal_cache calibration_cache;
++	struct rssical_cache rssical_cache;
++
++	u8 nphy_txpwr_idx[2];
++	u8 nphy_papd_cal_type;
++	uint nphy_papd_last_cal;
++	u16 nphy_papd_tx_gain_at_last_cal[2];
++	u8 nphy_papd_cal_gain_index[2];
++	s16 nphy_papd_epsilon_offset[2];
++	bool nphy_papd_recal_enable;
++	u32 nphy_papd_recal_counter;
++	bool nphy_force_papd_cal;
++	bool nphy_papdcomp;
++	bool ipa2g_on;
++	bool ipa5g_on;
++
++	u16 classifier_state;
++	u16 clip_state[2];
++	uint nphy_deaf_count;
++	u8 rxiq_samps;
++	u8 rxiq_antsel;
++
++	u16 rfctrlIntc1_save;
++	u16 rfctrlIntc2_save;
++	bool first_cal_after_assoc;
++	u16 tx_rx_cal_radio_saveregs[22];
++	u16 tx_rx_cal_phy_saveregs[15];
++
++	u8 nphy_cal_orig_pwr_idx[2];
++	u8 nphy_txcal_pwr_idx[2];
++	u8 nphy_rxcal_pwr_idx[2];
++	u16 nphy_cal_orig_tx_gain[2];
++	struct nphy_txgains nphy_cal_target_gain;
++	u16 nphy_txcal_bbmult;
++	u16 nphy_gmval;
++
++	u16 nphy_saved_bbconf;
++
++	bool nphy_gband_spurwar_en;
++	bool nphy_gband_spurwar2_en;
++	bool nphy_aband_spurwar_en;
++	u16 nphy_rccal_value;
++	u16 nphy_crsminpwr[3];
++	struct nphy_noisevar_buf nphy_saved_noisevars;
++	bool nphy_anarxlpf_adjusted;
++	bool nphy_crsminpwr_adjusted;
++	bool nphy_noisevars_adjusted;
++
++	bool nphy_rxcal_active;
++	u16 radar_percal_mask;
++	bool dfs_lp_buffer_nphy;
++
++	u16 nphy_fineclockgatecontrol;
++
++	s8 rx2tx_biasentry;
++
++	u16 crsminpwr0;
++	u16 crsminpwrl0;
++	u16 crsminpwru0;
++	s16 noise_crsminpwr_index;
++	u16 init_gain_core1;
++	u16 init_gain_core2;
++	u16 init_gainb_core1;
++	u16 init_gainb_core2;
++	u8 aci_noise_curr_channel;
++	u16 init_gain_rfseq[4];
++
++	bool radio_is_on;
++
++	bool nphy_sample_play_lpf_bw_ctl_ovr;
++
++	u16 tbl_data_hi;
++	u16 tbl_data_lo;
++	u16 tbl_addr;
++
++	uint tbl_save_id;
++	uint tbl_save_offset;
++
++	u8 txpwrctrl;
++	s8 txpwrindex[PHY_CORE_MAX];
++
++	u8 phycal_tempdelta;
++	u32 mcs20_po;
++	u32 mcs40_po;
++	struct wiphy *wiphy;
++};
++
++struct cs32 {
++	s32 q;
++	s32 i;
++};
++
++struct radio_regs {
++	u16 address;
++	u32 init_a;
++	u32 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++struct radio_20xx_regs {
++	u16 address;
++	u8 init;
++	u8 do_init;
++};
++
++struct lcnphy_radio_regs {
++	u16 address;
++	u8 init_a;
++	u8 init_g;
++	u8 do_init_a;
++	u8 do_init_g;
++};
++
++extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr);
++extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val);
++
++extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr);
++extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask,
++			  u16 val);
++extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask);
++
++extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val);
++
++extern void wlc_phyreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_phyreg_exit(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_enter(struct brcms_phy_pub *pih);
++extern void wlc_radioreg_exit(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_read_table(struct brcms_phy *pi,
++			       const struct phytbl_info *ptbl_info,
++			       u16 tblAddr, u16 tblDataHi,
++			       u16 tblDatalo);
++extern void wlc_phy_write_table(struct brcms_phy *pi,
++				const struct phytbl_info *ptbl_info,
++				u16 tblAddr, u16 tblDataHi, u16 tblDatalo);
++extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id,
++			       uint tbl_offset, u16 tblAddr, u16 tblDataHi,
++			       u16 tblDataLo);
++extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val);
++
++extern void write_phy_channel_reg(struct brcms_phy *pi, uint val);
++extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi);
++
++extern u8 wlc_phy_nbits(s32 value);
++extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
++
++extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi,
++					     struct radio_20xx_regs *radioregs);
++extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi,
++				    const struct radio_regs *radioregs,
++				    u16 core_offset);
++
++extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi);
++
++extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on);
++extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
++					s32 *eps_imag);
++
++extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi);
++extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi);
++
++extern bool wlc_phy_attach_nphy(struct brcms_phy *pi);
++extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi,
++				      u16 chanspec);
++extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi,
++					u16 chanspec);
++extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi,
++					      u16 chanspec);
++extern int wlc_phy_channel2freq(uint channel);
++extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
++extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec);
++
++extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode);
++extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi);
++extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi);
++
++extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index);
++extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable);
++extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi);
++extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz,
++				     u16 max_val, bool iqcalmode);
++
++extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan,
++					       u8 *max_pwr, u8 rate_id);
++extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++					    u8 rate_mcs_end,
++					    u8 rate_ofdm_start);
++extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
++					    u8 rate_ofdm_start,
++					    u8 rate_ofdm_end,
++					    u8 rate_mcs_start);
++
++extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode);
++extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode);
++extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode);
++extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel);
++extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode);
++extern void wlc_2064_vco_cal(struct brcms_phy *pi);
++
++extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi);
++
++#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
++#define LCNPHY_TX_POWER_TABLE_SIZE	128
++#define LCNPHY_MAX_TX_POWER_INDEX	(LCNPHY_TX_POWER_TABLE_SIZE - 1)
++#define LCNPHY_TBL_ID_TXPWRCTL	0x07
++#define LCNPHY_TX_PWR_CTRL_OFF	0
++#define LCNPHY_TX_PWR_CTRL_SW		(0x1 << 15)
++#define LCNPHY_TX_PWR_CTRL_HW         ((0x1 << 15) | \
++					(0x1 << 14) | \
++					(0x1 << 13))
++
++#define LCNPHY_TX_PWR_CTRL_TEMPBASED	0xE001
++
++extern void wlc_lcnphy_write_table(struct brcms_phy *pi,
++				   const struct phytbl_info *pti);
++extern void wlc_lcnphy_read_table(struct brcms_phy *pi,
++				  struct phytbl_info *pti);
++extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b);
++extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq);
++extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b);
++extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi);
++extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0,
++				      u8 *eq0, u8 *fi0, u8 *fq0);
++extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode);
++extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode);
++extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi);
++extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi);
++extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
++extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr,
++				s8 *cck_pwr);
++extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi);
++
++extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index);
++
++#define NPHY_MAX_HPVGA1_INDEX		10
++#define NPHY_DEF_HPVGA1_INDEXLIMIT	7
++
++struct phy_iq_est {
++	s32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi,
++					       bool enable);
++extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode);
++
++#define wlc_phy_write_table_nphy(pi, pti) \
++	wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_phy_read_table_nphy(pi, pti) \
++	wlc_phy_read_table(pi, pti, 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_addr(pi, id, off) \
++	wlc_phy_table_addr((pi), (id), (off), 0x72, 0x74, 0x73)
++
++#define wlc_nphy_table_data_write(pi, w, v) \
++	wlc_phy_table_data_write((pi), (w), (v))
++
++extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o,
++				    u32 w, void *d);
++extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
++				     u32, const void *);
++
++#define	PHY_IPA(pi) \
++	((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
++	 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
++
++#define BRCMS_PHY_WAR_PR51571(pi) \
++	if (NREV_LT((pi)->pubpi.phy_rev, 3)) \
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol))
++
++extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
++extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
++extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en);
++
++extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan);
++extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on);
++
++extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd);
++extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi);
++
++extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val);
++
++extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++				   u16 num_samps, u8 wait_time,
++				   u8 wait_for_crs);
++
++extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++				      struct nphy_iq_comp *comp);
++extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi);
++
++extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih,
++					 u8 rxcore_bitmask);
++extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih);
++
++extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type);
++extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi);
++extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi);
++extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi);
++
++extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi);
++extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi,
++				   struct nphy_txgains target_gain,
++				   bool full, bool m);
++extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi,
++				 struct nphy_txgains target_gain,
++				 u8 type, bool d);
++extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask,
++				     s8 txpwrindex, bool res);
++extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type);
++extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type,
++				  s32 *rssi_buf, u8 nsamps);
++extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi);
++extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi);
++extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi,
++					s32 dBm_targetpower, bool debug);
++extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++				u8 mode, u8, bool);
++extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi);
++extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf,
++				     u8 num_samps);
++extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi);
++
++extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi,
++				     struct d11rxhdr *rxh);
++
++#define NPHY_TESTPATTERN_BPHY_EVM   0
++#define NPHY_TESTPATTERN_BPHY_RFCS  1
++
++extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs);
++
++void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset,
++				s8 *ofdmoffset);
++extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi,
++				  u16 chanspec);
++
++extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih);
++#endif				/* _BRCM_PHY_INT_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+new file mode 100644
+index 0000000..abfd788
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+@@ -0,0 +1,5137 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_qmath.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phytbl_lcn.h"
++#include "phy_lcn.h"
++
++#define PLL_2064_NDIV		90
++#define PLL_2064_LOW_END_VCO	3000
++#define PLL_2064_LOW_END_KVCO	27
++#define PLL_2064_HIGH_END_VCO	4200
++#define PLL_2064_HIGH_END_KVCO	68
++#define PLL_2064_LOOP_BW_DOUBLER	200
++#define PLL_2064_D30_DOUBLER		10500
++#define PLL_2064_LOOP_BW	260
++#define PLL_2064_D30		8000
++#define PLL_2064_CAL_REF_TO	8
++#define PLL_2064_MHZ		1000000
++#define PLL_2064_OPEN_LOOP_DELAY	5
++
++#define TEMPSENSE			1
++#define VBATSENSE           2
++
++#define NOISE_IF_UPD_CHK_INTERVAL	1
++#define NOISE_IF_UPD_RST_INTERVAL	60
++#define NOISE_IF_UPD_THRESHOLD_CNT	1
++#define NOISE_IF_UPD_TRHRESHOLD	50
++#define NOISE_IF_UPD_TIMEOUT		1000
++#define NOISE_IF_OFF			0
++#define NOISE_IF_CHK			1
++#define NOISE_IF_ON			2
++
++#define PAPD_BLANKING_PROFILE		3
++#define PAPD2LUT			0
++#define PAPD_CORR_NORM			0
++#define PAPD_BLANKING_THRESHOLD		0
++#define PAPD_STOP_AFTER_LAST_UPDATE	0
++
++#define LCN_TARGET_PWR  60
++
++#define LCN_VBAT_OFFSET_433X 34649679
++#define LCN_VBAT_SLOPE_433X  8258032
++
++#define LCN_VBAT_SCALE_NOM  53
++#define LCN_VBAT_SCALE_DEN  432
++
++#define LCN_TEMPSENSE_OFFSET  80812
++#define LCN_TEMPSENSE_DEN  2647
++
++#define LCN_BW_LMT	200
++#define LCN_CUR_LMT	1250
++#define LCN_MULT	1
++#define LCN_VCO_DIV	30
++#define LCN_OFFSET	680
++#define LCN_FACT	490
++#define LCN_CUR_DIV	2640
++
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
++	(0 + 8)
++#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
++	(0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
++
++#define wlc_lcnphy_enable_tx_gain_override(pi) \
++	wlc_lcnphy_set_tx_gain_override(pi, true)
++#define wlc_lcnphy_disable_tx_gain_override(pi)	\
++	wlc_lcnphy_set_tx_gain_override(pi, false)
++
++#define wlc_lcnphy_iqcal_active(pi)	\
++	(read_phy_reg((pi), 0x451) & \
++	 ((0x1 << 15) | (0x1 << 14)))
++
++#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
++#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)	\
++	(pi->temppwrctrl_capable)
++#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
++	(pi->hwpwrctrl_capable)
++
++#define SWCTRL_BT_TX		0x18
++#define SWCTRL_OVR_DISABLE	0x40
++
++#define	AFE_CLK_INIT_MODE_TXRX2X	1
++#define	AFE_CLK_INIT_MODE_PAPD		0
++
++#define LCNPHY_TBL_ID_IQLOCAL			0x00
++
++#define LCNPHY_TBL_ID_RFSEQ         0x08
++#define LCNPHY_TBL_ID_GAIN_IDX		0x0d
++#define LCNPHY_TBL_ID_SW_CTRL			0x0f
++#define LCNPHY_TBL_ID_GAIN_TBL		0x12
++#define LCNPHY_TBL_ID_SPUR			0x14
++#define LCNPHY_TBL_ID_SAMPLEPLAY		0x15
++#define LCNPHY_TBL_ID_SAMPLEPLAY1		0x16
++
++#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET	832
++#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET	128
++#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET	192
++#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET		320
++#define LCNPHY_TX_PWR_CTRL_LO_OFFSET		448
++#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET		576
++
++#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313	140
++
++#define LCNPHY_TX_PWR_CTRL_START_NPT		1
++#define LCNPHY_TX_PWR_CTRL_MAX_NPT			7
++
++#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
++
++#define LCNPHY_ACI_DETECT_START      1
++#define LCNPHY_ACI_DETECT_PROGRESS   2
++#define LCNPHY_ACI_DETECT_STOP       3
++
++#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
++#define LCNPHY_ACI_GLITCH_TRSH 2000
++#define	LCNPHY_ACI_TMOUT 250
++#define LCNPHY_ACI_DETECT_TIMEOUT  2
++#define LCNPHY_ACI_START_DELAY 0
++
++#define wlc_lcnphy_tx_gain_override_enabled(pi)	\
++	(0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
++
++#define wlc_lcnphy_total_tx_frames(pi) \
++	wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + \
++			    offsetof(struct macstat, txallfrm))
++
++struct lcnphy_txgains {
++	u16 gm_gain;
++	u16 pga_gain;
++	u16 pad_gain;
++	u16 dac_gain;
++};
++
++enum lcnphy_cal_mode {
++	LCNPHY_CAL_FULL,
++	LCNPHY_CAL_RECAL,
++	LCNPHY_CAL_CURRECAL,
++	LCNPHY_CAL_DIGCAL,
++	LCNPHY_CAL_GCTRL
++};
++
++struct lcnphy_rx_iqcomp {
++	u8 chan;
++	s16 a;
++	s16 b;
++};
++
++struct lcnphy_spb_tone {
++	s16 re;
++	s16 im;
++};
++
++struct lcnphy_unsign16_struct {
++	u16 re;
++	u16 im;
++};
++
++struct lcnphy_iq_est {
++	u32 iq_prod;
++	u32 i_pwr;
++	u32 q_pwr;
++};
++
++struct lcnphy_sfo_cfg {
++	u16 ptcentreTs20;
++	u16 ptcentreFactor;
++};
++
++enum lcnphy_papd_cal_type {
++	LCNPHY_PAPD_CAL_CW,
++	LCNPHY_PAPD_CAL_OFDM
++};
++
++typedef u16 iqcal_gain_params_lcnphy[9];
++
++static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
++	{0, 0, 0, 0, 0, 0, 0, 0, 0},
++};
++
++static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
++	tbl_iqcal_gainparams_lcnphy_2G,
++};
++
++static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
++	ARRAY_SIZE(tbl_iqcal_gainparams_lcnphy_2G),
++};
++
++static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = {
++	{965, 1087},
++	{967, 1085},
++	{969, 1082},
++	{971, 1080},
++	{973, 1078},
++	{975, 1076},
++	{977, 1073},
++	{979, 1071},
++	{981, 1069},
++	{983, 1067},
++	{985, 1065},
++	{987, 1063},
++	{989, 1060},
++	{994, 1055}
++};
++
++static const
++u16 lcnphy_iqcal_loft_gainladder[] = {
++	((2 << 8) | 0),
++	((3 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((16 << 8) | 1),
++	((16 << 8) | 2),
++	((16 << 8) | 3),
++	((16 << 8) | 4),
++	((16 << 8) | 5),
++	((16 << 8) | 6),
++	((16 << 8) | 7),
++	((23 << 8) | 7),
++	((32 << 8) | 7),
++	((45 << 8) | 7),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++u16 lcnphy_iqcal_ir_gainladder[] = {
++	((1 << 8) | 0),
++	((2 << 8) | 0),
++	((4 << 8) | 0),
++	((6 << 8) | 0),
++	((8 << 8) | 0),
++	((11 << 8) | 0),
++	((16 << 8) | 0),
++	((23 << 8) | 0),
++	((32 << 8) | 0),
++	((45 << 8) | 0),
++	((64 << 8) | 0),
++	((64 << 8) | 1),
++	((64 << 8) | 2),
++	((64 << 8) | 3),
++	((64 << 8) | 4),
++	((64 << 8) | 5),
++	((64 << 8) | 6),
++	((64 << 8) | 7),
++	((91 << 8) | 7),
++	((128 << 8) | 7)
++};
++
++static const
++struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = {
++	{88, 0},
++	{73, 49},
++	{34, 81},
++	{-17, 86},
++	{-62, 62},
++	{-86, 17},
++	{-81, -34},
++	{-49, -73},
++	{0, -88},
++	{49, -73},
++	{81, -34},
++	{86, 17},
++	{62, 62},
++	{17, 86},
++	{-34, 81},
++	{-73, 49},
++	{-88, 0},
++	{-73, -49},
++	{-34, -81},
++	{17, -86},
++	{62, -62},
++	{86, -17},
++	{81, 34},
++	{49, 73},
++	{0, 88},
++	{-49, 73},
++	{-81, 34},
++	{-86, -17},
++	{-62, -62},
++	{-17, -86},
++	{34, -81},
++	{73, -49},
++};
++
++static const
++u16 iqlo_loopback_rf_regs[20] = {
++	RADIO_2064_REG036,
++	RADIO_2064_REG11A,
++	RADIO_2064_REG03A,
++	RADIO_2064_REG025,
++	RADIO_2064_REG028,
++	RADIO_2064_REG005,
++	RADIO_2064_REG112,
++	RADIO_2064_REG0FF,
++	RADIO_2064_REG11F,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG007,
++	RADIO_2064_REG0FC,
++	RADIO_2064_REG0FD,
++	RADIO_2064_REG012,
++	RADIO_2064_REG057,
++	RADIO_2064_REG059,
++	RADIO_2064_REG05C,
++	RADIO_2064_REG078,
++	RADIO_2064_REG092,
++};
++
++static const
++u16 tempsense_phy_regs[14] = {
++	0x503,
++	0x4a4,
++	0x4d0,
++	0x4d9,
++	0x4da,
++	0x4a6,
++	0x938,
++	0x939,
++	0x4d8,
++	0x4d0,
++	0x4d7,
++	0x4a5,
++	0x40d,
++	0x4a2,
++};
++
++static const
++u16 rxiq_cal_rf_reg[11] = {
++	RADIO_2064_REG098,
++	RADIO_2064_REG116,
++	RADIO_2064_REG12C,
++	RADIO_2064_REG06A,
++	RADIO_2064_REG00B,
++	RADIO_2064_REG01B,
++	RADIO_2064_REG113,
++	RADIO_2064_REG01D,
++	RADIO_2064_REG114,
++	RADIO_2064_REG02E,
++	RADIO_2064_REG12A,
++};
++
++static const
++struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = {
++	{1, 0, 0},
++	{2, 0, 0},
++	{3, 0, 0},
++	{4, 0, 0},
++	{5, 0, 0},
++	{6, 0, 0},
++	{7, 0, 0},
++	{8, 0, 0},
++	{9, 0, 0},
++	{10, 0, 0},
++	{11, 0, 0},
++	{12, 0, 0},
++	{13, 0, 0},
++	{14, 0, 0},
++	{34, 0, 0},
++	{38, 0, 0},
++	{42, 0, 0},
++	{46, 0, 0},
++	{36, 0, 0},
++	{40, 0, 0},
++	{44, 0, 0},
++	{48, 0, 0},
++	{52, 0, 0},
++	{56, 0, 0},
++	{60, 0, 0},
++	{64, 0, 0},
++	{100, 0, 0},
++	{104, 0, 0},
++	{108, 0, 0},
++	{112, 0, 0},
++	{116, 0, 0},
++	{120, 0, 0},
++	{124, 0, 0},
++	{128, 0, 0},
++	{132, 0, 0},
++	{136, 0, 0},
++	{140, 0, 0},
++	{149, 0, 0},
++	{153, 0, 0},
++	{157, 0, 0},
++	{161, 0, 0},
++	{165, 0, 0},
++	{184, 0, 0},
++	{188, 0, 0},
++	{192, 0, 0},
++	{196, 0, 0},
++	{200, 0, 0},
++	{204, 0, 0},
++	{208, 0, 0},
++	{212, 0, 0},
++	{216, 0, 0},
++};
++
++static const u32 lcnphy_23bitgaincode_table[] = {
++	0x200100,
++	0x200200,
++	0x200004,
++	0x200014,
++	0x200024,
++	0x200034,
++	0x200134,
++	0x200234,
++	0x200334,
++	0x200434,
++	0x200037,
++	0x200137,
++	0x200237,
++	0x200337,
++	0x200437,
++	0x000035,
++	0x000135,
++	0x000235,
++	0x000037,
++	0x000137,
++	0x000237,
++	0x000337,
++	0x00013f,
++	0x00023f,
++	0x00033f,
++	0x00034f,
++	0x00044f,
++	0x00144f,
++	0x00244f,
++	0x00254f,
++	0x00354f,
++	0x00454f,
++	0x00464f,
++	0x01464f,
++	0x02464f,
++	0x03464f,
++	0x04464f,
++};
++
++static const s8 lcnphy_gain_table[] = {
++	-16,
++	-13,
++	10,
++	7,
++	4,
++	0,
++	3,
++	6,
++	9,
++	12,
++	15,
++	18,
++	21,
++	24,
++	27,
++	30,
++	33,
++	36,
++	39,
++	42,
++	45,
++	48,
++	50,
++	53,
++	56,
++	59,
++	62,
++	65,
++	68,
++	71,
++	74,
++	77,
++	80,
++	83,
++	86,
++	89,
++	92,
++};
++
++static const s8 lcnphy_gain_index_offset_for_rssi[] = {
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	7,
++	8,
++	7,
++	7,
++	6,
++	7,
++	7,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	4,
++	3,
++	3,
++	3,
++	3,
++	3,
++	3,
++	4,
++	2,
++	2,
++	2,
++	2,
++	2,
++	2,
++	-1,
++	-2,
++	-2,
++	-2
++};
++
++struct chan_info_2064_lcnphy {
++	uint chan;
++	uint freq;
++	u8 logen_buftune;
++	u8 logen_rccr_tx;
++	u8 txrf_mix_tune_ctrl;
++	u8 pa_input_tune_g;
++	u8 logen_rccr_rx;
++	u8 pa_rxrf_lna1_freq_tune;
++	u8 pa_rxrf_lna2_freq_tune;
++	u8 rxrf_rxrf_spare1;
++};
++
++static const struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = {
++	{1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++	{14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
++};
++
++static const struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = {
++	{0x00, 0, 0, 0, 0},
++	{0x01, 0x64, 0x64, 0, 0},
++	{0x02, 0x20, 0x20, 0, 0},
++	{0x03, 0x66, 0x66, 0, 0},
++	{0x04, 0xf8, 0xf8, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x10, 0x10, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0x37, 0x37, 0, 0},
++	{0x0B, 0x6, 0x6, 0, 0},
++	{0x0C, 0x55, 0x55, 0, 0},
++	{0x0D, 0x8b, 0x8b, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0x5, 0x5, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0xe, 0xe, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0xb, 0xb, 0, 0},
++	{0x14, 0x2, 0x2, 0, 0},
++	{0x15, 0x12, 0x12, 0, 0},
++	{0x16, 0x12, 0x12, 0, 0},
++	{0x17, 0xc, 0xc, 0, 0},
++	{0x18, 0xc, 0xc, 0, 0},
++	{0x19, 0xc, 0xc, 0, 0},
++	{0x1A, 0x8, 0x8, 0, 0},
++	{0x1B, 0x2, 0x2, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0x1, 0x1, 0, 0},
++	{0x1E, 0x12, 0x12, 0, 0},
++	{0x1F, 0x6e, 0x6e, 0, 0},
++	{0x20, 0x2, 0x2, 0, 0},
++	{0x21, 0x23, 0x23, 0, 0},
++	{0x22, 0x8, 0x8, 0, 0},
++	{0x23, 0, 0, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0x33, 0x33, 0, 0},
++	{0x27, 0x55, 0x55, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x30, 0x30, 0, 0},
++	{0x2A, 0xb, 0xb, 0, 0},
++	{0x2B, 0x1b, 0x1b, 0, 0},
++	{0x2C, 0x3, 0x3, 0, 0},
++	{0x2D, 0x1b, 0x1b, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x20, 0x20, 0, 0},
++	{0x30, 0xa, 0xa, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0x62, 0x62, 0, 0},
++	{0x33, 0x19, 0x19, 0, 0},
++	{0x34, 0x33, 0x33, 0, 0},
++	{0x35, 0x77, 0x77, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x70, 0x70, 0, 0},
++	{0x38, 0x3, 0x3, 0, 0},
++	{0x39, 0xf, 0xf, 0, 0},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0xcf, 0xcf, 0, 0},
++	{0x3C, 0x1a, 0x1a, 0, 0},
++	{0x3D, 0x6, 0x6, 0, 0},
++	{0x3E, 0x42, 0x42, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0xfb, 0xfb, 0, 0},
++	{0x41, 0x9a, 0x9a, 0, 0},
++	{0x42, 0x7a, 0x7a, 0, 0},
++	{0x43, 0x29, 0x29, 0, 0},
++	{0x44, 0, 0, 0, 0},
++	{0x45, 0x8, 0x8, 0, 0},
++	{0x46, 0xce, 0xce, 0, 0},
++	{0x47, 0x27, 0x27, 0, 0},
++	{0x48, 0x62, 0x62, 0, 0},
++	{0x49, 0x6, 0x6, 0, 0},
++	{0x4A, 0x58, 0x58, 0, 0},
++	{0x4B, 0xf7, 0xf7, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0xb3, 0xb3, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0, 0, 0, 0},
++	{0x51, 0x9, 0x9, 0, 0},
++	{0x52, 0x5, 0x5, 0, 0},
++	{0x53, 0x17, 0x17, 0, 0},
++	{0x54, 0x38, 0x38, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0xb, 0xb, 0, 0},
++	{0x58, 0, 0, 0, 0},
++	{0x59, 0, 0, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0, 0, 0, 0},
++	{0x5C, 0, 0, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x88, 0x88, 0, 0},
++	{0x5F, 0xcc, 0xcc, 0, 0},
++	{0x60, 0x74, 0x74, 0, 0},
++	{0x61, 0x74, 0x74, 0, 0},
++	{0x62, 0x74, 0x74, 0, 0},
++	{0x63, 0x44, 0x44, 0, 0},
++	{0x64, 0x77, 0x77, 0, 0},
++	{0x65, 0x44, 0x44, 0, 0},
++	{0x66, 0x77, 0x77, 0, 0},
++	{0x67, 0x55, 0x55, 0, 0},
++	{0x68, 0x77, 0x77, 0, 0},
++	{0x69, 0x77, 0x77, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0x7f, 0x7f, 0, 0},
++	{0x6C, 0x8, 0x8, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0x88, 0x88, 0, 0},
++	{0x6F, 0x66, 0x66, 0, 0},
++	{0x70, 0x66, 0x66, 0, 0},
++	{0x71, 0x28, 0x28, 0, 0},
++	{0x72, 0x55, 0x55, 0, 0},
++	{0x73, 0x4, 0x4, 0, 0},
++	{0x74, 0, 0, 0, 0},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0, 0, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0xd6, 0xd6, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0xb4, 0xb4, 0, 0},
++	{0x84, 0x1, 0x1, 0, 0},
++	{0x85, 0x20, 0x20, 0, 0},
++	{0x86, 0x5, 0x5, 0, 0},
++	{0x87, 0xff, 0xff, 0, 0},
++	{0x88, 0x7, 0x7, 0, 0},
++	{0x89, 0x77, 0x77, 0, 0},
++	{0x8A, 0x77, 0x77, 0, 0},
++	{0x8B, 0x77, 0x77, 0, 0},
++	{0x8C, 0x77, 0x77, 0, 0},
++	{0x8D, 0x8, 0x8, 0, 0},
++	{0x8E, 0xa, 0xa, 0, 0},
++	{0x8F, 0x8, 0x8, 0, 0},
++	{0x90, 0x18, 0x18, 0, 0},
++	{0x91, 0x5, 0x5, 0, 0},
++	{0x92, 0x1f, 0x1f, 0, 0},
++	{0x93, 0x10, 0x10, 0, 0},
++	{0x94, 0x3, 0x3, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0xaa, 0xaa, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0x23, 0x23, 0, 0},
++	{0x9A, 0x7, 0x7, 0, 0},
++	{0x9B, 0xf, 0xf, 0, 0},
++	{0x9C, 0x10, 0x10, 0, 0},
++	{0x9D, 0x3, 0x3, 0, 0},
++	{0x9E, 0x4, 0x4, 0, 0},
++	{0x9F, 0x20, 0x20, 0, 0},
++	{0xA0, 0, 0, 0, 0},
++	{0xA1, 0, 0, 0, 0},
++	{0xA2, 0, 0, 0, 0},
++	{0xA3, 0, 0, 0, 0},
++	{0xA4, 0x1, 0x1, 0, 0},
++	{0xA5, 0x77, 0x77, 0, 0},
++	{0xA6, 0x77, 0x77, 0, 0},
++	{0xA7, 0x77, 0x77, 0, 0},
++	{0xA8, 0x77, 0x77, 0, 0},
++	{0xA9, 0x8c, 0x8c, 0, 0},
++	{0xAA, 0x88, 0x88, 0, 0},
++	{0xAB, 0x78, 0x78, 0, 0},
++	{0xAC, 0x57, 0x57, 0, 0},
++	{0xAD, 0x88, 0x88, 0, 0},
++	{0xAE, 0, 0, 0, 0},
++	{0xAF, 0x8, 0x8, 0, 0},
++	{0xB0, 0x88, 0x88, 0, 0},
++	{0xB1, 0, 0, 0, 0},
++	{0xB2, 0x1b, 0x1b, 0, 0},
++	{0xB3, 0x3, 0x3, 0, 0},
++	{0xB4, 0x24, 0x24, 0, 0},
++	{0xB5, 0x3, 0x3, 0, 0},
++	{0xB6, 0x1b, 0x1b, 0, 0},
++	{0xB7, 0x24, 0x24, 0, 0},
++	{0xB8, 0x3, 0x3, 0, 0},
++	{0xB9, 0, 0, 0, 0},
++	{0xBA, 0xaa, 0xaa, 0, 0},
++	{0xBB, 0, 0, 0, 0},
++	{0xBC, 0x4, 0x4, 0, 0},
++	{0xBD, 0, 0, 0, 0},
++	{0xBE, 0x8, 0x8, 0, 0},
++	{0xBF, 0x11, 0x11, 0, 0},
++	{0xC0, 0, 0, 0, 0},
++	{0xC1, 0, 0, 0, 0},
++	{0xC2, 0x62, 0x62, 0, 0},
++	{0xC3, 0x1e, 0x1e, 0, 0},
++	{0xC4, 0x33, 0x33, 0, 0},
++	{0xC5, 0x37, 0x37, 0, 0},
++	{0xC6, 0, 0, 0, 0},
++	{0xC7, 0x70, 0x70, 0, 0},
++	{0xC8, 0x1e, 0x1e, 0, 0},
++	{0xC9, 0x6, 0x6, 0, 0},
++	{0xCA, 0x4, 0x4, 0, 0},
++	{0xCB, 0x2f, 0x2f, 0, 0},
++	{0xCC, 0xf, 0xf, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0xff, 0xff, 0, 0},
++	{0xCF, 0x8, 0x8, 0, 0},
++	{0xD0, 0x3f, 0x3f, 0, 0},
++	{0xD1, 0x3f, 0x3f, 0, 0},
++	{0xD2, 0x3f, 0x3f, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0xcc, 0xcc, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0x8, 0x8, 0, 0},
++	{0xD9, 0x8, 0x8, 0, 0},
++	{0xDA, 0x8, 0x8, 0, 0},
++	{0xDB, 0x11, 0x11, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x87, 0x87, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0x8, 0x8, 0, 0},
++	{0xE0, 0x8, 0x8, 0, 0},
++	{0xE1, 0x8, 0x8, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xE3, 0, 0, 0, 0},
++	{0xE4, 0, 0, 0, 0},
++	{0xE5, 0xf5, 0xf5, 0, 0},
++	{0xE6, 0x30, 0x30, 0, 0},
++	{0xE7, 0x1, 0x1, 0, 0},
++	{0xE8, 0, 0, 0, 0},
++	{0xE9, 0xff, 0xff, 0, 0},
++	{0xEA, 0, 0, 0, 0},
++	{0xEB, 0, 0, 0, 0},
++	{0xEC, 0x22, 0x22, 0, 0},
++	{0xED, 0, 0, 0, 0},
++	{0xEE, 0, 0, 0, 0},
++	{0xEF, 0, 0, 0, 0},
++	{0xF0, 0x3, 0x3, 0, 0},
++	{0xF1, 0x1, 0x1, 0, 0},
++	{0xF2, 0, 0, 0, 0},
++	{0xF3, 0, 0, 0, 0},
++	{0xF4, 0, 0, 0, 0},
++	{0xF5, 0, 0, 0, 0},
++	{0xF6, 0, 0, 0, 0},
++	{0xF7, 0x6, 0x6, 0, 0},
++	{0xF8, 0, 0, 0, 0},
++	{0xF9, 0, 0, 0, 0},
++	{0xFA, 0x40, 0x40, 0, 0},
++	{0xFB, 0, 0, 0, 0},
++	{0xFC, 0x1, 0x1, 0, 0},
++	{0xFD, 0x80, 0x80, 0, 0},
++	{0xFE, 0x2, 0x2, 0, 0},
++	{0xFF, 0x10, 0x10, 0, 0},
++	{0x100, 0x2, 0x2, 0, 0},
++	{0x101, 0x1e, 0x1e, 0, 0},
++	{0x102, 0x1e, 0x1e, 0, 0},
++	{0x103, 0, 0, 0, 0},
++	{0x104, 0x1f, 0x1f, 0, 0},
++	{0x105, 0, 0x8, 0, 1},
++	{0x106, 0x2a, 0x2a, 0, 0},
++	{0x107, 0xf, 0xf, 0, 0},
++	{0x108, 0, 0, 0, 0},
++	{0x109, 0, 0, 0, 0},
++	{0x10A, 0, 0, 0, 0},
++	{0x10B, 0, 0, 0, 0},
++	{0x10C, 0, 0, 0, 0},
++	{0x10D, 0, 0, 0, 0},
++	{0x10E, 0, 0, 0, 0},
++	{0x10F, 0, 0, 0, 0},
++	{0x110, 0, 0, 0, 0},
++	{0x111, 0, 0, 0, 0},
++	{0x112, 0, 0, 0, 0},
++	{0x113, 0, 0, 0, 0},
++	{0x114, 0, 0, 0, 0},
++	{0x115, 0, 0, 0, 0},
++	{0x116, 0, 0, 0, 0},
++	{0x117, 0, 0, 0, 0},
++	{0x118, 0, 0, 0, 0},
++	{0x119, 0, 0, 0, 0},
++	{0x11A, 0, 0, 0, 0},
++	{0x11B, 0, 0, 0, 0},
++	{0x11C, 0x1, 0x1, 0, 0},
++	{0x11D, 0, 0, 0, 0},
++	{0x11E, 0, 0, 0, 0},
++	{0x11F, 0, 0, 0, 0},
++	{0x120, 0, 0, 0, 0},
++	{0x121, 0, 0, 0, 0},
++	{0x122, 0x80, 0x80, 0, 0},
++	{0x123, 0, 0, 0, 0},
++	{0x124, 0xf8, 0xf8, 0, 0},
++	{0x125, 0, 0, 0, 0},
++	{0x126, 0, 0, 0, 0},
++	{0x127, 0, 0, 0, 0},
++	{0x128, 0, 0, 0, 0},
++	{0x129, 0, 0, 0, 0},
++	{0x12A, 0, 0, 0, 0},
++	{0x12B, 0, 0, 0, 0},
++	{0x12C, 0, 0, 0, 0},
++	{0x12D, 0, 0, 0, 0},
++	{0x12E, 0, 0, 0, 0},
++	{0x12F, 0, 0, 0, 0},
++	{0x130, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++#define LCNPHY_NUM_DIG_FILT_COEFFS 16
++#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
++
++static const u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
++	 128, 64,},
++	{1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
++	 167, 93,},
++	{2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
++	 128, 64,},
++	{3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++	{20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
++	 256, 185, 256,},
++	{21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
++	 256, 273, 256,},
++	{22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
++	 256, 352, 256,},
++	{23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
++	 128, 233, 128,},
++	{24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
++	 1881, 256,},
++	{25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
++	 1881, 256,},
++	{26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
++	 384, 288,},
++	{27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
++	 128, 384, 288,},
++	{30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
++	 170, 340, 170,},
++};
++
++#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
++static const u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
++	[LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
++	{0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
++	 0x278, 0xfea0, 0x80, 0x100, 0x80,},
++	{1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
++	 750, 0xFE2B, 212, 0xFFCE, 212,},
++	{2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
++	 0xFEF2, 128, 0xFFE2, 128}
++};
++
++#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
++	mod_phy_reg(pi, 0x4a4, \
++		    (0x1ff << 0), \
++		    (u16)(idx) << 0)
++
++#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
++	mod_phy_reg(pi, 0x4a5, \
++		    (0x7 << 8),	\
++		    (u16)(npt) << 8)
++
++#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
++	(read_phy_reg((pi), 0x4a4) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++#define wlc_lcnphy_get_tx_pwr_npt(pi) \
++	((read_phy_reg(pi, 0x4a5) & \
++	  (0x7 << 8)) >> \
++	 8)
++
++#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
++	(read_phy_reg(pi, 0x473) & 0x1ff)
++
++#define wlc_lcnphy_get_target_tx_pwr(pi) \
++	((read_phy_reg(pi, 0x4a7) & \
++	  (0xff << 0)) >> \
++	 0)
++
++#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
++	mod_phy_reg(pi, 0x4a7, \
++		    (0xff << 0), \
++		    (u16)(target) << 0)
++
++#define wlc_radio_2064_rcal_done(pi) \
++	(0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
++
++#define tempsense_done(pi) \
++	(0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
++
++#define LCNPHY_IQLOCC_READ(val) \
++	((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
++
++#define FIXED_TXPWR 78
++#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
++
++void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti)
++{
++	wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti)
++{
++	wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
++}
++
++static void
++wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id,
++			     const u16 *tbl_ptr, u32 tbl_len,
++			     u32 tbl_width, u32 tbl_offset)
++{
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_read_table(pi, &tab);
++}
++
++static void
++wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id,
++			      const u16 *tbl_ptr, u32 tbl_len,
++			      u32 tbl_width, u32 tbl_offset)
++{
++
++	struct phytbl_info tab;
++	tab.tbl_id = tbl_id;
++	tab.tbl_ptr = tbl_ptr;
++	tab.tbl_len = tbl_len;
++	tab.tbl_width = tbl_width;
++	tab.tbl_offset = tbl_offset;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static u32
++wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
++{
++	u32 quotient, remainder, roundup, rbit;
++
++	quotient = dividend / divisor;
++	remainder = dividend % divisor;
++	rbit = divisor & 1;
++	roundup = (divisor >> 1) + rbit;
++
++	while (precision--) {
++		quotient <<= 1;
++		if (remainder >= roundup) {
++			quotient++;
++			remainder = ((remainder - roundup) << 1) + rbit;
++		} else {
++			remainder <<= 1;
++		}
++	}
++
++	if (remainder >= roundup)
++		quotient++;
++
++	return quotient;
++}
++
++static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
++{
++	int k;
++	k = 0;
++	if (type == 0) {
++		if (coeff_x < 0)
++			k = (coeff_x - 1) / 2;
++		else
++			k = coeff_x / 2;
++	}
++
++	if (type == 1) {
++		if ((coeff_x + 1) < 0)
++			k = (coeff_x) / 2;
++		else
++			k = (coeff_x + 1) / 2;
++	}
++	return k;
++}
++
++static void
++wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains)
++{
++	u16 dac_gain, rfgain0, rfgain1;
++
++	dac_gain = read_phy_reg(pi, 0x439) >> 0;
++	gains->dac_gain = (dac_gain & 0x380) >> 7;
++
++	rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
++	rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
++
++	gains->gm_gain = rfgain0 & 0xff;
++	gains->pga_gain = (rfgain0 >> 8) & 0xff;
++	gains->pad_gain = rfgain1 & 0xff;
++}
++
++
++static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain)
++{
++	u16 dac_ctrl;
++
++	dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
++	dac_ctrl = dac_ctrl & 0xc7f;
++	dac_ctrl = dac_ctrl | (dac_gain << 7);
++	mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
++
++}
++
++static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable)
++{
++	u16 bit = bEnable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
++}
++
++static void
++wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable)
++{
++	u16 ebit = enable ? 1 : 0;
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
++		mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
++		mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
++	}
++}
++
++static void
++wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
++				       u16 trsw,
++				       u16 ext_lna,
++				       u16 biq2,
++				       u16 biq1,
++				       u16 tia, u16 lna2, u16 lna1)
++{
++	u16 gain0_15, gain16_19;
++
++	gain16_19 = biq2 & 0xf;
++	gain0_15 = ((biq1 & 0xf) << 12) |
++		   ((tia & 0xf) << 8) |
++		   ((lna2 & 0x3) << 6) |
++		   ((lna2 &
++		     0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
++
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	} else {
++		mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
++
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	}
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
++
++}
++
++static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx)
++{
++
++	mod_phy_reg(pi, 0x44d,
++		    (0x1 << 1) |
++		    (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
++
++	or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
++}
++
++static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
++}
++
++static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b)
++{
++	mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
++
++	mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
++
++	mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
++
++}
++
++static bool
++wlc_lcnphy_rx_iq_est(struct brcms_phy *pi,
++		     u16 num_samps,
++		     u8 wait_time, struct lcnphy_iq_est *iq_est)
++{
++	int wait_count = 0;
++	bool result = true;
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
++
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
++
++	mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
++
++	while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
++
++		if (wait_count > (10 * 500)) {
++			result = false;
++			goto cleanup;
++		}
++		udelay(100);
++		wait_count++;
++	}
++
++	iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
++			  (u32) read_phy_reg(pi, 0x484);
++	iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
++			(u32) read_phy_reg(pi, 0x486);
++	iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
++			(u32) read_phy_reg(pi, 0x488);
++
++cleanup:
++	mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
++
++	return result;
++}
++
++static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps)
++{
++#define LCNPHY_MIN_RXIQ_PWR 2
++	bool result;
++	u16 a0_new, b0_new;
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++	s32 a, b, temp;
++	s16 iq_nbits, qq_nbits, arsh, brsh;
++	s32 iq;
++	u32 ii, qq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
++	b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
++	mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
++
++	wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
++
++	result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
++	if (!result)
++		goto cleanup;
++
++	iq = (s32) iq_est.iq_prod;
++	ii = iq_est.i_pwr;
++	qq = iq_est.q_pwr;
++
++	if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
++		result = false;
++		goto cleanup;
++	}
++
++	iq_nbits = wlc_phy_nbits(iq);
++	qq_nbits = wlc_phy_nbits(qq);
++
++	arsh = 10 - (30 - iq_nbits);
++	if (arsh >= 0) {
++		a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++		temp = (s32) (ii >> arsh);
++		if (temp == 0)
++			return false;
++	} else {
++		a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++		temp = (s32) (ii << -arsh);
++		if (temp == 0)
++			return false;
++	}
++	a /= temp;
++	brsh = qq_nbits - 31 + 20;
++	if (brsh >= 0) {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii >> brsh);
++		if (temp == 0)
++			return false;
++	} else {
++		b = (qq << (31 - qq_nbits));
++		temp = (s32) (ii << -brsh);
++		if (temp == 0)
++			return false;
++	}
++	b /= temp;
++	b -= a * a;
++	b = (s32) int_sqrt((unsigned long) b);
++	b -= (1 << 10);
++	a0_new = (u16) (a & 0x3ff);
++	b0_new = (u16) (b & 0x3ff);
++cleanup:
++
++	wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
++
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
++	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
++
++	return result;
++}
++
++static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
++{
++	struct lcnphy_iq_est iq_est = { 0, 0, 0 };
++
++	if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
++		return 0;
++	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
++}
++
++static bool
++wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
++		     const struct lcnphy_rx_iqcomp *iqcomp,
++		     int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
++		     int tx_gain_idx)
++{
++	struct lcnphy_txgains old_gains;
++	u16 tx_pwr_ctrl;
++	u8 tx_gain_index_old = 0;
++	bool result = false, tx_gain_override_old = false;
++	u16 i, Core1TxControl_old, RFOverride0_old,
++	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
++	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
++	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
++	int tia_gain;
++	u32 received_power, rx_pwr_threshold;
++	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
++	u16 values_to_save[11];
++	s16 *ptr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return false;
++	if (module == 2) {
++		while (iqcomp_sz--) {
++			if (iqcomp[iqcomp_sz].chan ==
++			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
++				wlc_lcnphy_set_rx_iq_comp(pi,
++							  (u16)
++							  iqcomp[iqcomp_sz].a,
++							  (u16)
++							  iqcomp[iqcomp_sz].b);
++				result = true;
++				break;
++			}
++		}
++		goto cal_done;
++	}
++
++	if (module == 1) {
++
++		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++		for (i = 0; i < 11; i++)
++			values_to_save[i] =
++				read_radio_reg(pi, rxiq_cal_rf_reg[i]);
++		Core1TxControl_old = read_phy_reg(pi, 0x631);
++
++		or_phy_reg(pi, 0x631, 0x0015);
++
++		RFOverride0_old = read_phy_reg(pi, 0x44c);
++		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
++		rfoverride2_old = read_phy_reg(pi, 0x4b0);
++		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
++		rfoverride3_old = read_phy_reg(pi, 0x4f9);
++		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
++		rfoverride4_old = read_phy_reg(pi, 0x938);
++		rfoverride4val_old = read_phy_reg(pi, 0x939);
++		afectrlovr_old = read_phy_reg(pi, 0x43b);
++		afectrlovrval_old = read_phy_reg(pi, 0x43c);
++		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++
++		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++		if (tx_gain_override_old) {
++			wlc_lcnphy_get_tx_gain(pi, &old_gains);
++			tx_gain_index_old = pi_lcn->lcnphy_current_index;
++		}
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
++
++		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
++		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
++		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
++		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
++		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
++		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
++		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
++		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
++
++		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
++		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
++		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
++		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
++		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
++		write_phy_reg(pi, 0x6da, 0xffff);
++		or_phy_reg(pi, 0x6db, 0x3);
++		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
++		wlc_lcnphy_rx_gain_override_enable(pi, true);
++
++		tia_gain = 8;
++		rx_pwr_threshold = 950;
++		while (tia_gain > 0) {
++			tia_gain -= 1;
++			wlc_lcnphy_set_rx_gain_by_distribution(pi,
++							       0, 0, 2, 2,
++							       (u16)
++							       tia_gain, 1, 0);
++			udelay(500);
++
++			received_power =
++				wlc_lcnphy_measure_digital_power(pi, 2000);
++			if (received_power < rx_pwr_threshold)
++				break;
++		}
++		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
++
++		wlc_lcnphy_stop_tx_tone(pi);
++
++		write_phy_reg(pi, 0x631, Core1TxControl_old);
++
++		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
++		write_phy_reg(pi, 0x4b0, rfoverride2_old);
++		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
++		write_phy_reg(pi, 0x4f9, rfoverride3_old);
++		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
++		write_phy_reg(pi, 0x938, rfoverride4_old);
++		write_phy_reg(pi, 0x939, rfoverride4val_old);
++		write_phy_reg(pi, 0x43b, afectrlovr_old);
++		write_phy_reg(pi, 0x43c, afectrlovrval_old);
++		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
++
++		wlc_lcnphy_clear_trsw_override(pi);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
++
++		for (i = 0; i < 11; i++)
++			write_radio_reg(pi, rxiq_cal_rf_reg[i],
++					values_to_save[i]);
++
++		if (tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
++		else
++			wlc_lcnphy_disable_tx_gain_override(pi);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
++		wlc_lcnphy_rx_gain_override_enable(pi, false);
++	}
++
++cal_done:
++	kfree(ptr);
++	return result;
++}
++
++s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi)
++{
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (txpwrctrl_off(pi))
++		index = pi_lcn->lcnphy_current_index;
++	else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		index =	(s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(
++			      pi) / 2);
++	else
++		index = pi_lcn->lcnphy_current_index;
++	return index;
++}
++
++void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel)
++{
++	u16 afectrlovr, afectrlovrval;
++	afectrlovr = read_phy_reg(pi, 0x43b);
++	afectrlovrval = read_phy_reg(pi, 0x43c);
++	if (channel != 0) {
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
++
++		write_phy_reg(pi, 0x44b, 0xffff);
++		wlc_lcnphy_tx_pu(pi, 1);
++
++		mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
++
++		or_phy_reg(pi, 0x6da, 0x0080);
++
++		or_phy_reg(pi, 0x00a, 0x228);
++	} else {
++		and_phy_reg(pi, 0x00a, ~(0x228));
++
++		and_phy_reg(pi, 0x6da, 0xFF7F);
++		write_phy_reg(pi, 0x43b, afectrlovr);
++		write_phy_reg(pi, 0x43c, afectrlovrval);
++	}
++}
++
++static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi)
++{
++	u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
++
++	save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
++	save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
++
++	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
++	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
++}
++
++static void
++wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable)
++{
++	if (enable) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
++
++		write_phy_reg(pi, 0x44a, 0x084);
++		write_phy_reg(pi, 0x44a, 0x080);
++		write_phy_reg(pi, 0x6d3, 0x2222);
++		write_phy_reg(pi, 0x6d3, 0x2220);
++	} else {
++		write_phy_reg(pi, 0x942, 0x0);
++		write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
++		write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
++	}
++	wlapi_switch_macfreq(pi->sh->physhim, enable);
++}
++
++static void
++wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (channel == 14)
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++	else
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++	pi_lcn->lcnphy_bandedge_corr = 2;
++	if (channel == 1)
++		pi_lcn->lcnphy_bandedge_corr = 4;
++
++	if (channel == 1 || channel == 2 || channel == 3 ||
++	    channel == 4 || channel == 9 ||
++	    channel == 10 || channel == 11 || channel == 12) {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
++
++		write_phy_reg(pi, 0x425, 0x5907);
++	} else {
++		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
++		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
++		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
++
++		si_pmu_pllupd(pi->sh->sih);
++		write_phy_reg(pi, 0x942, 0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++
++		pi_lcn->lcnphy_spurmod = false;
++		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
++
++		write_phy_reg(pi, 0x425, 0x590a);
++	}
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++}
++
++static void
++wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
++{
++	uint i;
++	const struct chan_info_2064_lcnphy *ci;
++	u8 rfpll_doubler = 0;
++	u8 pll_pwrup, pll_pwrup_ovr;
++	s32 qFxtal, qFref, qFvco, qFcal;
++	u8 d15, d16, f16, e44, e45;
++	u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
++	u16 loop_bw, d30, setCount;
++
++	u8 h29, h28_ten, e30, h30_ten, cp_current;
++	u16 g30, d28;
++
++	ci = &chan_info_2064_lcnphy[0];
++	rfpll_doubler = 1;
++
++	mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
++
++	write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
++	if (!rfpll_doubler) {
++		loop_bw = PLL_2064_LOOP_BW;
++		d30 = PLL_2064_D30;
++	} else {
++		loop_bw = PLL_2064_LOOP_BW_DOUBLER;
++		d30 = PLL_2064_D30_DOUBLER;
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
++			if (chan_info_2064_lcnphy[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_2064_lcnphy))
++			return;
++
++		ci = &chan_info_2064_lcnphy[i];
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
++
++	mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
++
++	mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
++
++	mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
++		      (ci->logen_rccr_rx) << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
++
++	mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
++		      (ci->pa_rxrf_lna2_freq_tune) << 4);
++
++	write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
++
++	pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
++	pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
++
++	or_radio_reg(pi, RADIO_2064_REG044, 0x07);
++
++	or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
++	e44 = 0;
++	e45 = 0;
++
++	fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
++	if (pi->xtalfreq > 26000000)
++		e44 = 1;
++	if (pi->xtalfreq > 52000000)
++		e45 = 1;
++	if (e44 == 0)
++		fcal_div = 1;
++	else if (e45 == 0)
++		fcal_div = 2;
++	else
++		fcal_div = 4;
++	fvco3 = (ci->freq * 3);
++	fref3 = 2 * fpfd;
++
++	qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
++	qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
++	qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
++	qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
++
++	write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
++
++	d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
++	write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
++	write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
++
++	d16 = (qFcal * 8 / (d15 + 1)) - 1;
++	write_radio_reg(pi, RADIO_2064_REG051, d16);
++
++	f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
++	setCount = f16 * 3 * (ci->freq) / 32 - 1;
++	mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
++		      (u8) (setCount >> 8));
++
++	or_radio_reg(pi, RADIO_2064_REG053, 0x10);
++	write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
++
++	div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
++
++	div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
++	while (div_frac >= fref3) {
++		div_int++;
++		div_frac -= fref3;
++	}
++	div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
++
++	mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
++		      (u8) (div_int >> 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
++		      (u8) (div_int << 4));
++	mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
++		      (u8) (div_frac >> 16));
++	write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
++	write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
++
++	write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
++
++	write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
++	write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
++	write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
++
++	h29 = LCN_BW_LMT / loop_bw;
++	d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
++		(fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
++	       (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
++	      + PLL_2064_LOW_END_KVCO;
++	h28_ten = (d28 * 10) / LCN_VCO_DIV;
++	e30 = (d30 - LCN_OFFSET) / LCN_FACT;
++	g30 = LCN_OFFSET + (e30 * LCN_FACT);
++	h30_ten = (g30 * 10) / LCN_CUR_DIV;
++	cp_current = ((LCN_CUR_LMT * h29 * LCN_MULT * 100) / h28_ten) / h30_ten;
++	mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
++
++	if (channel >= 1 && channel <= 5)
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
++	else
++		write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
++	write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
++
++	mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
++	udelay(1);
++
++	wlc_2064_vco_cal(pi);
++
++	write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
++	write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		write_radio_reg(pi, RADIO_2064_REG038, 3);
++		write_radio_reg(pi, RADIO_2064_REG091, 7);
++	}
++}
++
++static int
++wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
++{
++	s16 filt_index = -1;
++	int j;
++
++	u16 addr[] = {
++		0x910,
++		0x91e,
++		0x91f,
++		0x924,
++		0x925,
++		0x926,
++		0x920,
++		0x921,
++		0x927,
++		0x928,
++		0x929,
++		0x922,
++		0x923,
++		0x930,
++		0x931,
++		0x932
++	};
++
++	u16 addr_ofdm[] = {
++		0x90f,
++		0x900,
++		0x901,
++		0x906,
++		0x907,
++		0x908,
++		0x902,
++		0x903,
++		0x909,
++		0x90a,
++		0x90b,
++		0x904,
++		0x905,
++		0x90c,
++		0x90d,
++		0x90e
++	};
++
++	if (!is_ofdm) {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr[j],
++					      LCNPHY_txdigfiltcoeffs_cck
++					      [filt_index][j + 1]);
++		}
++	} else {
++		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
++			if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
++				filt_index = (s16) j;
++				break;
++			}
++		}
++
++		if (filt_index != -1) {
++			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, addr_ofdm[j],
++					      LCNPHY_txdigfiltcoeffs_ofdm
++					      [filt_index][j + 1]);
++		}
++	}
++
++	return (filt_index != -1) ? 0 : -1;
++}
++
++void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
++{
++	u8 channel = CHSPEC_CHANNEL(chanspec);
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
++	udelay(1000);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++
++	write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
++	write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
++	} else {
++		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
++
++		wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
++	}
++
++	wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
++
++}
++
++static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
++{
++	u16 pa_gain;
++
++	pa_gain = (read_phy_reg(pi, 0x4fb) &
++		   LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
++		  LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
++
++	return pa_gain;
++}
++
++static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
++				   struct lcnphy_txgains *target_gains)
++{
++	u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	mod_phy_reg(
++		pi, 0x4b5,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fb,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	mod_phy_reg(
++		pi, 0x4fc,
++		(0xffff << 0),
++		((target_gains->gm_gain) |
++		 (target_gains->pga_gain << 8)) <<
++		0);
++	mod_phy_reg(pi, 0x4fd,
++		    (0x7fff << 0),
++		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
++
++	wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++}
++
++static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
++{
++	u16 m0m1 = (u16) m0 << 8;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi)
++{
++	u32 data_buf[64];
++	struct phytbl_info tab;
++
++	memset(data_buf, 0, sizeof(data_buf));
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = data_buf;
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		tab.tbl_len = 30;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_len = 64;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++enum lcnphy_tssi_mode {
++	LCNPHY_TSSI_PRE_PA,
++	LCNPHY_TSSI_POST_PA,
++	LCNPHY_TSSI_EXT
++};
++
++static void
++wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
++{
++	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
++
++	if (LCNPHY_TSSI_POST_PA == pos) {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	} else {
++		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
++
++		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++		} else {
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
++		}
++	}
++	mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
++
++	if (LCNPHY_TSSI_EXT == pos) {
++		write_radio_reg(pi, RADIO_2064_REG07F, 1);
++		mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
++		mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
++	}
++}
++
++static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi)
++{
++	u16 N1, N2, N3, N4, N5, N6, N;
++	N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
++	      >> 0);
++	N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
++		   >> 12);
++	N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
++	      >> 0);
++	N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
++		   >> 8);
++	N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
++	      >> 0);
++	N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
++		   >> 8);
++	N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
++	if (N < 1600)
++		N = 1600;
++	return N;
++}
++
++static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
++{
++	u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	auxpga_vmid = (2 << 8) |
++		      (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
++	auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
++	auxpga_gain_temp = 2;
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
++
++	mod_phy_reg(pi, 0x4db,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x4dc,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40a,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
++
++	mod_phy_reg(pi, 0x40b,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_phy_reg(pi, 0x40c,
++		    (0x3ff << 0) |
++		    (0x7 << 12),
++		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
++
++	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
++}
++
++static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rfseq, ind;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &ind;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 0;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	tab.tbl_offset = 704;
++	for (ind = 0; ind < 128; ind++) {
++		wlc_lcnphy_write_table(pi, &tab);
++		tab.tbl_offset++;
++	}
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
++
++	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
++
++	mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
++
++	wlc_lcnphy_clear_tx_power_offsets(pi);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
++
++	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
++		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
++	} else {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xc);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
++	} else {
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
++	else
++		mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
++
++	mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		mod_phy_reg(pi, 0x4d7,
++			    (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
++
++	rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &rfseq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
++
++	wlc_lcnphy_pwrctrl_rssiparams(pi);
++}
++
++void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi)
++{
++	u16 tx_cnt, tx_total, npt;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	tx_total = wlc_lcnphy_total_tx_frames(pi);
++	tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
++	npt = wlc_lcnphy_get_tx_pwr_npt(pi);
++
++	if (tx_cnt > (1 << npt)) {
++
++		pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
++
++		pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++		pi_lcn->lcnphy_tssi_npt = npt;
++
++	}
++}
++
++s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
++{
++	s32 a, b, p;
++
++	a = 32768 + (a1 * tssi);
++	b = (1024 * b0) + (64 * b1 * tssi);
++	p = ((2 * b) + a) / (2 * a);
++
++	return p;
++}
++
++static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
++	pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
++}
++
++void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM +
++		       BRCMS_NUM_RATES_MCS_1_STREAM];
++	uint i, j;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return;
++
++	for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
++
++		if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM)
++			j = TXP_FIRST_MCS_20_SISO;
++
++		rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = ARRAY_SIZE(rate_table);
++	tab.tbl_ptr = rate_table;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
++		wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
++
++		wlc_lcnphy_txpower_reset_npt(pi);
++	}
++}
++
++static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index)
++{
++	u32 cck_offset[4] = { 22, 22, 22, 22 };
++	u32 ofdm_offset, reg_offset_cck;
++	int i;
++	u16 index2;
++	struct phytbl_info tab;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return;
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
++
++	or_phy_reg(pi, 0x6da, 0x0040);
++
++	reg_offset_cck = 0;
++	for (i = 0; i < 4; i++)
++		cck_offset[i] -= reg_offset_cck;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 4;
++	tab.tbl_ptr = cck_offset;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++	wlc_lcnphy_write_table(pi, &tab);
++	ofdm_offset = 0;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &ofdm_offset;
++	for (i = 836; i < 862; i++) {
++		tab.tbl_offset = i;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
++
++	mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
++
++	mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
++
++	index2 = (u16) (index * 2);
++	mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
++
++}
++
++static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi)
++{
++	s8 index, delta_brd, delta_temp, new_index, tempcorrx;
++	s16 manp, meas_temp, temp_diff;
++	bool neg = false;
++	u16 temp;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
++		return pi_lcn->lcnphy_current_index;
++
++	index = FIXED_TXPWR;
++
++	if (pi_lcn->lcnphy_tempsense_slope == 0)
++		return index;
++
++	temp = (u16) wlc_lcnphy_tempsense(pi, 0);
++	meas_temp = LCNPHY_TEMPSENSE(temp);
++
++	if (pi->tx_power_min != 0)
++		delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
++	else
++		delta_brd = 0;
++
++	manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
++	temp_diff = manp - meas_temp;
++	if (temp_diff < 0) {
++		neg = true;
++		temp_diff = -temp_diff;
++	}
++
++	delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
++						  (u32) (pi_lcn->
++							 lcnphy_tempsense_slope
++							 * 10), 0);
++	if (neg)
++		delta_temp = -delta_temp;
++
++	if (pi_lcn->lcnphy_tempsense_option == 3
++	    && LCNREV_IS(pi->pubpi.phy_rev, 0))
++		delta_temp = 0;
++	if (pi_lcn->lcnphy_tempcorrx > 31)
++		tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
++	else
++		tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		tempcorrx = 4;
++	new_index =
++		index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
++	new_index += tempcorrx;
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		index = 127;
++
++	if (new_index < 0 || new_index > 126)
++		return index;
++
++	return new_index;
++}
++
++static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode)
++{
++
++	u16 current_mode = mode;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_HW)
++		current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
++		current_mode = LCNPHY_TX_PWR_CTRL_HW;
++	return current_mode;
++}
++
++void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode)
++{
++	u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
++	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 6),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
++
++	mod_phy_reg(pi, 0x6a3, (0x1 << 4),
++		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
++
++	if (old_mode != mode) {
++		if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
++
++			wlc_lcnphy_tx_pwr_update_npt(pi);
++
++			wlc_lcnphy_clear_tx_power_offsets(pi);
++		}
++		if (LCNPHY_TX_PWR_CTRL_HW == mode) {
++
++			wlc_lcnphy_txpower_recalc_target(pi);
++
++			wlc_lcnphy_set_start_tx_pwr_idx(pi,
++							pi_lcn->
++							lcnphy_tssi_idx);
++			wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
++			mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
++
++			pi_lcn->lcnphy_tssi_tx_cnt =
++				wlc_lcnphy_total_tx_frames(pi);
++
++			wlc_lcnphy_disable_tx_gain_override(pi);
++			pi_lcn->lcnphy_tx_power_idx_override = -1;
++		} else
++			wlc_lcnphy_enable_tx_gain_override(pi);
++
++		mod_phy_reg(pi, 0x4a4,
++			    ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
++		if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
++			index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++			wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
++			pi_lcn->lcnphy_current_index = (s8)
++						       ((read_phy_reg(pi,
++								      0x4a9) &
++							 0xFF) / 2);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save)
++{
++	u16 vmid;
++	int i;
++	for (i = 0; i < 20; i++)
++		values_to_save[i] =
++			read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++	mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
++	mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
++	else
++		and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
++
++	or_radio_reg(pi, RADIO_2064_REG036, 0x01);
++	or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
++	udelay(20);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 1);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
++		else
++			or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xF);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec))
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
++		else
++			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
++	}
++
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG005, 0x8);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x80);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
++	or_radio_reg(pi, RADIO_2064_REG113, 0x10);
++	udelay(20);
++
++	write_radio_reg(pi, RADIO_2064_REG007, 0x1);
++	udelay(20);
++
++	vmid = 0x2A6;
++	mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
++	write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
++	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
++	udelay(20);
++
++	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
++	udelay(20);
++	write_radio_reg(pi, RADIO_2064_REG012, 0x02);
++	or_radio_reg(pi, RADIO_2064_REG112, 0x06);
++	write_radio_reg(pi, RADIO_2064_REG036, 0x11);
++	write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
++	write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
++	write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
++	write_radio_reg(pi, RADIO_2064_REG092, 0x15);
++}
++
++static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi)
++{
++	uint delay_count = 0;
++
++	while (wlc_lcnphy_iqcal_active(pi)) {
++		udelay(100);
++		delay_count++;
++
++		if (delay_count > (10 * 500))
++			break;
++	}
++
++	return (0 == wlc_lcnphy_iqcal_active(pi));
++}
++
++static void
++wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save)
++{
++	int i;
++
++	and_phy_reg(pi, 0x44c, 0x0 >> 11);
++
++	and_phy_reg(pi, 0x43b, 0xC);
++
++	for (i = 0; i < 20; i++)
++		write_radio_reg(pi, iqlo_loopback_rf_regs[i],
++				values_to_save[i]);
++}
++
++static void
++wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi,
++		       struct lcnphy_txgains *target_gains,
++		       enum lcnphy_cal_mode cal_mode, bool keep_tone)
++{
++
++	struct lcnphy_txgains cal_gains, temp_gains;
++	u16 hash;
++	u8 band_idx;
++	int j;
++	u16 ncorr_override[5];
++	u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++			      0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
++
++	u16 commands_fullcal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 commands_recal[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234
++	};
++
++	u16 command_nums_fullcal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++
++	u16 command_nums_recal[] = {
++		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97
++	};
++	u16 *command_nums = command_nums_fullcal;
++
++	u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
++	u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
++	u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
++	bool tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	uint i, n_cal_cmds = 0, n_cal_start = 0;
++	u16 *values_to_save;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == values_to_save)
++		return;
++
++	save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
++	save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	or_phy_reg(pi, 0x6da, 0x40);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	switch (cal_mode) {
++	case LCNPHY_CAL_FULL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_fullcal;
++		n_cal_cmds = ARRAY_SIZE(commands_fullcal);
++		break;
++
++	case LCNPHY_CAL_RECAL:
++		start_coeffs = syst_coeffs;
++		cal_cmds = commands_recal;
++		n_cal_cmds = ARRAY_SIZE(commands_recal);
++		command_nums = command_nums_recal;
++		break;
++
++	default:
++		break;
++	}
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      start_coeffs, 11, 16, 64);
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++	mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
++
++	tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
++
++	mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
++
++	mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	if (tx_gain_override_old)
++		wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	if (!target_gains) {
++		if (!tx_gain_override_old)
++			wlc_lcnphy_set_tx_pwr_by_index(pi,
++						       pi_lcn->lcnphy_tssi_idx);
++		wlc_lcnphy_get_tx_gain(pi, &temp_gains);
++		target_gains = &temp_gains;
++	}
++
++	hash = (target_gains->gm_gain << 8) |
++	       (target_gains->pga_gain << 4) | (target_gains->pad_gain);
++
++	band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	cal_gains = *target_gains;
++	memset(ncorr_override, 0, sizeof(ncorr_override));
++	for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
++		if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
++			cal_gains.gm_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
++			cal_gains.pga_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
++			cal_gains.pad_gain =
++				tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
++			memcpy(ncorr_override,
++			       &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
++			       sizeof(ncorr_override));
++			break;
++		}
++	}
++
++	wlc_lcnphy_set_tx_gain(pi, &cal_gains);
++
++	write_phy_reg(pi, 0x453, 0xaa9);
++	write_phy_reg(pi, 0x93d, 0xc0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_loft_gainladder,
++				      ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
++				      16, 0);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      lcnphy_iqcal_ir_gainladder,
++				      ARRAY_SIZE(
++					      lcnphy_iqcal_ir_gainladder), 16,
++				      32);
++
++	if (pi->phy_tx_tone_freq) {
++
++		wlc_lcnphy_stop_tx_tone(pi);
++		udelay(5);
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	} else {
++		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
++	}
++
++	write_phy_reg(pi, 0x6da, 0xffff);
++
++	for (i = n_cal_start; i < n_cal_cmds; i++) {
++		u16 zero_diq = 0;
++		u16 best_coeffs[11];
++		u16 command_num;
++
++		cal_type = (cal_cmds[i] & 0x0f00) >> 8;
++
++		command_num = command_nums[i];
++		if (ncorr_override[cal_type])
++			command_num =
++				ncorr_override[cal_type] << 8 | (command_num &
++								 0xff);
++
++		write_phy_reg(pi, 0x452, command_num);
++
++		if ((cal_type == 3) || (cal_type == 4)) {
++			wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						     &diq_start, 1, 16, 69);
++
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &zero_diq, 1, 16, 69);
++		}
++
++		write_phy_reg(pi, 0x451, cal_cmds[i]);
++
++		if (!wlc_lcnphy_iqcal_wait(pi))
++			goto cleanup;
++
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     best_coeffs,
++					     ARRAY_SIZE(best_coeffs), 16, 96);
++		wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					      best_coeffs,
++					      ARRAY_SIZE(best_coeffs), 16, 64);
++
++		if ((cal_type == 3) || (cal_type == 4))
++			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++						      &diq_start, 1, 16, 69);
++		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++					     pi_lcn->lcnphy_cal_results.
++					     txiqlocal_bestcoeffs,
++					     ARRAY_SIZE(pi_lcn->
++							lcnphy_cal_results.
++							txiqlocal_bestcoeffs),
++					     16, 96);
++	}
++
++	wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				     pi_lcn->lcnphy_cal_results.
++				     txiqlocal_bestcoeffs,
++				     ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
++						txiqlocal_bestcoeffs), 16, 96);
++	pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[0], 4, 16, 80);
++
++	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
++				      &pi_lcn->lcnphy_cal_results.
++				      txiqlocal_bestcoeffs[5], 2, 16, 85);
++
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
++	kfree(values_to_save);
++
++	if (!keep_tone)
++		wlc_lcnphy_stop_tx_tone(pi);
++
++	write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
++
++	write_phy_reg(pi, 0x453, 0);
++
++	if (tx_gain_override_old)
++		wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
++
++	write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
++	write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
++
++}
++
++static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
++{
++	bool suspend, tx_gain_override_old;
++	struct lcnphy_txgains old_gains;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
++	    idleTssi0_regvalue_2C;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
++	u16 SAVE_jtag_bb_afe_switch =
++		read_radio_reg(pi, RADIO_2064_REG007) & 1;
++	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
++	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
++	idleTssi = read_phy_reg(pi, 0x4ab);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
++	wlc_lcnphy_tssi_setup(pi);
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++		    >> 0);
++
++	idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
++			>> 0);
++
++	if (idleTssi0_2C >= 256)
++		idleTssi0_OB = idleTssi0_2C - 256;
++	else
++		idleTssi0_OB = idleTssi0_2C + 256;
++
++	idleTssi0_regvalue_OB = idleTssi0_OB;
++	if (idleTssi0_regvalue_OB >= 256)
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
++	else
++		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
++	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
++
++	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
++
++	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
++	mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
++{
++	bool suspend;
++	u16 save_txpwrCtrlEn;
++	u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
++	u16 auxpga_vmid;
++	struct phytbl_info tab;
++	u32 val;
++	u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
++	   save_reg112;
++	u16 values_to_save[14];
++	s8 index;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	udelay(999);
++
++	save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
++	save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
++	save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
++	save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
++	save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
++	save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
++
++	for (i = 0; i < 14; i++)
++		values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++	index = pi_lcn->lcnphy_current_index;
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
++	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
++	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
++	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
++	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
++
++	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
++
++	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
++
++	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
++
++	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
++
++	mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
++
++	mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
++
++	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
++
++	write_radio_reg(pi, RADIO_2064_REG025, 0xC);
++
++	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
++
++	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
++
++	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
++
++	val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++	tab.tbl_offset = 6;
++	wlc_lcnphy_write_table(pi, &tab);
++	if (mode == TEMPSENSE) {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
++
++		auxpga_vmidcourse = 8;
++		auxpga_vmidfine = 0x4;
++		auxpga_gain = 2;
++		mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
++	} else {
++		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
++
++		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
++
++		auxpga_vmidcourse = 7;
++		auxpga_vmidfine = 0xa;
++		auxpga_gain = 2;
++	}
++	auxpga_vmid =
++		(u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
++	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
++
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
++
++	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
++
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
++
++	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
++
++	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
++
++	wlc_phy_do_dummy_tx(pi, true, OFF);
++	if (!tempsense_done(pi))
++		udelay(10);
++
++	write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
++	write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
++	write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
++	write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
++	write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
++	write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
++	for (i = 0; i < 14; i++)
++		write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
++
++	write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++	udelay(999);
++}
++
++static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
++{
++	struct lcnphy_txgains tx_gains;
++	u8 bbmult;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	bool suspend;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (!pi->hwpwrctrl_capable) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			tx_gains.gm_gain = 4;
++			tx_gains.pga_gain = 12;
++			tx_gains.pad_gain = 12;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		} else {
++			tx_gains.gm_gain = 7;
++			tx_gains.pga_gain = 15;
++			tx_gains.pad_gain = 14;
++			tx_gains.dac_gain = 0;
++
++			bbmult = 150;
++		}
++		wlc_lcnphy_set_tx_gain(pi, &tx_gains);
++		wlc_lcnphy_set_bbmult(pi, bbmult);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	} else {
++
++		wlc_lcnphy_idle_tssi_est(ppi);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
++
++		write_phy_reg(pi, 0x4a8, 10);
++
++		wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
++
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	}
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
++{
++	u16 m0m1;
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = &m0m1;
++	tab.tbl_len = 1;
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_offset = 87;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return (u8) ((m0m1 & 0xff00) >> 8);
++}
++
++static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
++{
++	mod_phy_reg(pi, 0x4fb,
++		    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
++	mod_phy_reg(pi, 0x4fd,
++		    LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
++		    gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
++}
++
++void
++wlc_lcnphy_get_radio_loft(struct brcms_phy *pi,
++			  u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
++{
++	*ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
++	*eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
++	*fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
++	*fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
++}
++
++void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b)
++{
++	struct phytbl_info tab;
++	u16 iqcc[2];
++
++	iqcc[0] = a;
++	iqcc[1] = b;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_offset = 80;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq)
++{
++	struct phytbl_info tab;
++
++	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_write_table(pi, &tab);
++}
++
++void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index)
++{
++	struct phytbl_info tab;
++	u16 a, b;
++	u8 bb_mult;
++	u32 bbmultiqcomp, txgain, locoeffs, rfpower;
++	struct lcnphy_txgains gains;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
++	pi_lcn->lcnphy_current_index = (u8) index;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++	tab.tbl_ptr = &bbmultiqcomp;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &txgain;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	gains.gm_gain = (u16) (txgain & 0xff);
++	gains.pga_gain = (u16) (txgain >> 8) & 0xff;
++	gains.pad_gain = (u16) (txgain >> 16) & 0xff;
++	gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
++	wlc_lcnphy_set_tx_gain(pi, &gains);
++	wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
++
++	bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
++	wlc_lcnphy_set_bbmult(pi, bb_mult);
++
++	wlc_lcnphy_enable_tx_gain_override(pi);
++
++	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++
++		a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
++		b = (u16) (bbmultiqcomp & 0x3ff);
++		wlc_lcnphy_set_tx_iqcc(pi, a, b);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
++		tab.tbl_ptr = &locoeffs;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		tab.tbl_ptr = &rfpower;
++		wlc_lcnphy_read_table(pi, &tab);
++		mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
++
++	}
++}
++
++static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 temp_offset[128];
++	tab.tbl_ptr = temp_offset;
++	tab.tbl_len = 128;
++	tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
++	tab.tbl_width = 32;
++	tab.tbl_offset = 0;
++
++	memset(temp_offset, 0, sizeof(temp_offset));
++	for (j = 1; j < 128; j += 2)
++		temp_offset[j] = 0x80000;
++
++	wlc_lcnphy_write_table(pi, &tab);
++	return;
++}
++
++void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable)
++{
++	if (!bEnable) {
++
++		and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
++
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
++
++		and_phy_reg(pi, 0x44c,
++			    ~(u16) ((0x1 << 3) |
++				    (0x1 << 5) |
++				    (0x1 << 12) |
++				    (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x44d,
++			    ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
++
++		and_phy_reg(pi, 0x4f9,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++
++		and_phy_reg(pi, 0x4fa,
++			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
++	} else {
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
++		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
++
++		mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
++		mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
++
++		mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
++		mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
++
++		wlc_lcnphy_set_trsw_override(pi, true, false);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
++		mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
++		} else {
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
++			mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
++
++			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
++			mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
++
++			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
++			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
++		}
++	}
++}
++
++static void
++wlc_lcnphy_run_samples(struct brcms_phy *pi,
++		       u16 num_samps,
++		       u16 num_loops, u16 wait, bool iqcalmode)
++{
++
++	or_phy_reg(pi, 0x6da, 0x8080);
++
++	mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
++	if (num_loops != 0xffff)
++		num_loops--;
++	mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
++
++	mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
++
++	if (iqcalmode) {
++
++		and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
++		or_phy_reg(pi, 0x453, (0x1 << 15));
++	} else {
++		write_phy_reg(pi, 0x63f, 1);
++		wlc_lcnphy_tx_pu(pi, 1);
++	}
++
++	or_radio_reg(pi, RADIO_2064_REG112, 0x6);
++}
++
++void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	} else {
++		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
++		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
++	}
++
++	if (phybw40 == 0) {
++		mod_phy_reg((pi), 0x410,
++			    (0x1 << 6) |
++			    (0x1 << 5),
++			    ((CHSPEC_IS2G(
++				      pi->radio_chanspec)) ? (!mode) : 0) <<
++			    6 | (!mode) << 5);
++		mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
++	}
++}
++
++void
++wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val,
++			 bool iqcalmode)
++{
++	u8 phy_bw;
++	u16 num_samps, t, k;
++	u32 bw;
++	s32 theta = 0, rot = 0;
++	struct cordic_iq tone_samp;
++	u32 data_buf[64];
++	u16 i_samp, q_samp;
++	struct phytbl_info tab;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = f_kHz;
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	phy_bw = 40;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x2);
++		write_phy_reg(pi, 0x93b, 0x0);
++		write_phy_reg(pi, 0x93c, 0x0);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
++	}
++
++	if (f_kHz) {
++		k = 1;
++		do {
++			bw = phy_bw * 1000 * k;
++			num_samps = bw / abs(f_kHz);
++			k++;
++		} while ((num_samps * (u32) (abs(f_kHz))) != bw);
++	} else
++		num_samps = 2;
++
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_samp = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
++		q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
++		data_buf[t] = (i_samp << 10) | q_samp;
++	}
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
++
++	tab.tbl_ptr = data_buf;
++	tab.tbl_len = num_samps;
++	tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
++	tab.tbl_offset = 0;
++	tab.tbl_width = 32;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
++}
++
++void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi)
++{
++	s16 playback_status;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_tx_tone_freq = 0;
++	if (pi_lcn->lcnphy_spurmod) {
++		write_phy_reg(pi, 0x942, 0x7);
++		write_phy_reg(pi, 0x93b, 0x2017);
++		write_phy_reg(pi, 0x93c, 0x27c5);
++		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
++	}
++
++	playback_status = read_phy_reg(pi, 0x644);
++	if (playback_status & (0x1 << 0)) {
++		wlc_lcnphy_tx_pu(pi, 0);
++		mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
++	} else if (playback_status & (0x1 << 1))
++		mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
++
++	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
++
++	mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
++
++	and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
++
++	wlc_lcnphy_deaf_mode(pi, false);
++}
++
++static void
++wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y)
++{
++	u16 di0dq0;
++	u16 x, y, data_rf;
++	int k;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
++		break;
++	case 2:
++		di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
++		wlc_lcnphy_set_tx_locc(pi, di0dq0);
++		break;
++	case 3:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG089, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
++		break;
++	case 4:
++		k = wlc_lcnphy_calc_floor(coeff_x, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_x, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
++		k = wlc_lcnphy_calc_floor(coeff_y, 0);
++		y = 8 + k;
++		k = wlc_lcnphy_calc_floor(coeff_y, 1);
++		x = 8 - k;
++		data_rf = (x * 16 + y);
++		write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
++		break;
++	}
++}
++
++static struct lcnphy_unsign16_struct
++wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type)
++{
++	u16 a, b, didq;
++	u8 di0, dq0, ei, eq, fi, fq;
++	struct lcnphy_unsign16_struct cc;
++	cc.re = 0;
++	cc.im = 0;
++	switch (cal_type) {
++	case 0:
++		wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++		cc.re = a;
++		cc.im = b;
++		break;
++	case 2:
++		didq = wlc_lcnphy_get_tx_locc(pi);
++		di0 = (((didq & 0xff00) << 16) >> 24);
++		dq0 = (((didq & 0x00ff) << 24) >> 24);
++		cc.re = (u16) di0;
++		cc.im = (u16) dq0;
++		break;
++	case 3:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) ei;
++		cc.im = (u16) eq;
++		break;
++	case 4:
++		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
++		cc.re = (u16) fi;
++		cc.im = (u16) fq;
++		break;
++	}
++	return cc;
++}
++
++static void
++wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
++		    s16 *ptr, int mode)
++{
++	u32 curval1, curval2, stpptr, curptr, strptr, val;
++	u16 sslpnCalibClkEnCtrl, timer;
++	u16 old_sslpnCalibClkEnCtrl;
++	s16 imag, real;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	timer = 0;
++	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++
++	curval1 = bcma_read16(pi->d11core, D11REGOFFS(psm_corectlsts));
++	ptr[130] = 0;
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts),
++		     ((1 << 6) | curval1));
++
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_strptr), 0x7E00);
++	bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_stpptr), 0x8000);
++	udelay(20);
++	curval2 = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		     curval2 | 0x30);
++
++	write_phy_reg(pi, 0x555, 0x0);
++	write_phy_reg(pi, 0x5a6, 0x5);
++
++	write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
++	write_phy_reg(pi, 0x5cf, 3);
++	write_phy_reg(pi, 0x5a5, 0x3);
++	write_phy_reg(pi, 0x583, 0x0);
++	write_phy_reg(pi, 0x584, 0x0);
++	write_phy_reg(pi, 0x585, 0x0fff);
++	write_phy_reg(pi, 0x586, 0x0000);
++
++	write_phy_reg(pi, 0x580, 0x4501);
++
++	sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
++	write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
++	stpptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_stpptr));
++	curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++	do {
++		udelay(10);
++		curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
++		timer++;
++	} while ((curptr != stpptr) && (timer < 500));
++
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), 0x2);
++	strptr = 0x7E00;
++	bcma_write32(pi->d11core, D11REGOFFS(tplatewrptr), strptr);
++	while (strptr < 0x8000) {
++		val = bcma_read32(pi->d11core, D11REGOFFS(tplatewrdata));
++		imag = ((val >> 16) & 0x3ff);
++		real = ((val) & 0x3ff);
++		if (imag > 511)
++			imag -= 1024;
++
++		if (real > 511)
++			real -= 1024;
++
++		if (pi_lcn->lcnphy_iqcal_swp_dis)
++			ptr[(strptr - 0x7E00) / 4] = real;
++		else
++			ptr[(strptr - 0x7E00) / 4] = imag;
++
++		if (clip_detect_algo) {
++			if (imag > thresh || imag < -thresh) {
++				strptr = 0x8000;
++				ptr[130] = 1;
++			}
++		}
++
++		strptr += 4;
++	}
++
++	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), curval2);
++	bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts), curval1);
++}
++
++static void
++wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels,
++	      int step_size_lg2)
++{
++	const struct lcnphy_spb_tone *phy_c1;
++	struct lcnphy_spb_tone phy_c2;
++	struct lcnphy_unsign16_struct phy_c3;
++	int phy_c4, phy_c5, k, l, j, phy_c6;
++	u16 phy_c7, phy_c8, phy_c9;
++	s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
++	s16 *ptr, phy_c17;
++	s32 phy_c18, phy_c19;
++	u32 phy_c20, phy_c21;
++	bool phy_c22, phy_c23, phy_c24, phy_c25;
++	u16 phy_c26, phy_c27;
++	u16 phy_c28, phy_c29, phy_c30;
++	u16 phy_c31;
++	u16 *phy_c32;
++	phy_c21 = 0;
++	phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
++	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
++	if (NULL == ptr)
++		return;
++
++	phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
++	if (NULL == phy_c32) {
++		kfree(ptr);
++		return;
++	}
++	phy_c26 = read_phy_reg(pi, 0x6da);
++	phy_c27 = read_phy_reg(pi, 0x6db);
++	phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
++	write_phy_reg(pi, 0x93d, 0xC0);
++
++	wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
++	write_phy_reg(pi, 0x6da, 0xffff);
++	or_phy_reg(pi, 0x6db, 0x3);
++
++	wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
++	udelay(500);
++	phy_c28 = read_phy_reg(pi, 0x938);
++	phy_c29 = read_phy_reg(pi, 0x4d7);
++	phy_c30 = read_phy_reg(pi, 0x4d8);
++	or_phy_reg(pi, 0x938, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 2);
++	or_phy_reg(pi, 0x4d7, 0x1 << 3);
++	mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
++	or_phy_reg(pi, 0x4d8, 1 << 0);
++	or_phy_reg(pi, 0x4d8, 1 << 1);
++	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
++	mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
++	phy_c1 = &lcnphy_spb_tone_3750[0];
++	phy_c4 = 32;
++
++	if (num_levels == 0) {
++		if (cal_type != 0)
++			num_levels = 4;
++		else
++			num_levels = 9;
++	}
++	if (step_size_lg2 == 0) {
++		if (cal_type != 0)
++			step_size_lg2 = 3;
++		else
++			step_size_lg2 = 8;
++	}
++
++	phy_c7 = (1 << step_size_lg2);
++	phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
++	phy_c15 = (s16) phy_c3.re;
++	phy_c16 = (s16) phy_c3.im;
++	if (cal_type == 2) {
++		if (phy_c3.re > 127)
++			phy_c15 = phy_c3.re - 256;
++		if (phy_c3.im > 127)
++			phy_c16 = phy_c3.im - 256;
++	}
++	wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++	udelay(20);
++	for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
++		phy_c23 = true;
++		phy_c22 = false;
++		switch (cal_type) {
++		case 0:
++			phy_c10 = 511;
++			break;
++		case 2:
++			phy_c10 = 127;
++			break;
++		case 3:
++			phy_c10 = 15;
++			break;
++		case 4:
++			phy_c10 = 15;
++			break;
++		}
++
++		phy_c9 = read_phy_reg(pi, 0x93d);
++		phy_c9 = 2 * phy_c9;
++		phy_c24 = false;
++		phy_c5 = 7;
++		phy_c25 = true;
++		while (1) {
++			write_radio_reg(pi, RADIO_2064_REG026,
++					(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
++			udelay(50);
++			phy_c22 = false;
++			ptr[130] = 0;
++			wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
++			if (ptr[130] == 1)
++				phy_c22 = true;
++			if (phy_c22)
++				phy_c5 -= 1;
++			if ((phy_c22 != phy_c24) && (!phy_c25))
++				break;
++			if (!phy_c22)
++				phy_c5 += 1;
++			if (phy_c5 <= 0 || phy_c5 >= 7)
++				break;
++			phy_c24 = phy_c22;
++			phy_c25 = false;
++		}
++
++		if (phy_c5 < 0)
++			phy_c5 = 0;
++		else if (phy_c5 > 7)
++			phy_c5 = 7;
++
++		for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
++			for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
++				phy_c11 = phy_c15 + k;
++				phy_c12 = phy_c16 + l;
++
++				if (phy_c11 < -phy_c10)
++					phy_c11 = -phy_c10;
++				else if (phy_c11 > phy_c10)
++					phy_c11 = phy_c10;
++				if (phy_c12 < -phy_c10)
++					phy_c12 = -phy_c10;
++				else if (phy_c12 > phy_c10)
++					phy_c12 = phy_c10;
++				wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
++						  phy_c12);
++				udelay(20);
++				wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
++
++				phy_c18 = 0;
++				phy_c19 = 0;
++				for (j = 0; j < 128; j++) {
++					if (cal_type != 0)
++						phy_c6 = j % phy_c4;
++					else
++						phy_c6 = (2 * j) % phy_c4;
++
++					phy_c2.re = phy_c1[phy_c6].re;
++					phy_c2.im = phy_c1[phy_c6].im;
++					phy_c17 = ptr[j];
++					phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
++					phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
++				}
++
++				phy_c18 = phy_c18 >> 10;
++				phy_c19 = phy_c19 >> 10;
++				phy_c20 = ((phy_c18 * phy_c18) +
++					   (phy_c19 * phy_c19));
++
++				if (phy_c23 || phy_c20 < phy_c21) {
++					phy_c21 = phy_c20;
++					phy_c13 = phy_c11;
++					phy_c14 = phy_c12;
++				}
++				phy_c23 = false;
++			}
++		}
++		phy_c23 = true;
++		phy_c15 = phy_c13;
++		phy_c16 = phy_c14;
++		phy_c7 = phy_c7 >> 1;
++		wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
++		udelay(20);
++	}
++	goto cleanup;
++cleanup:
++	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
++	wlc_lcnphy_stop_tx_tone(pi);
++	write_phy_reg(pi, 0x6da, phy_c26);
++	write_phy_reg(pi, 0x6db, phy_c27);
++	write_phy_reg(pi, 0x938, phy_c28);
++	write_phy_reg(pi, 0x4d7, phy_c29);
++	write_phy_reg(pi, 0x4d8, phy_c30);
++	write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
++
++	kfree(phy_c32);
++	kfree(ptr);
++}
++
++void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b)
++{
++	u16 iqcc[2];
++	struct phytbl_info tab;
++
++	tab.tbl_ptr = iqcc;
++	tab.tbl_len = 2;
++	tab.tbl_id = 0;
++	tab.tbl_offset = 80;
++	tab.tbl_width = 16;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	*a = iqcc[0];
++	*b = iqcc[1];
++}
++
++static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi)
++{
++	struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
++
++	wlc_lcnphy_set_cc(pi, 0, 0, 0);
++	wlc_lcnphy_set_cc(pi, 2, 0, 0);
++	wlc_lcnphy_set_cc(pi, 3, 0, 0);
++	wlc_lcnphy_set_cc(pi, 4, 0, 0);
++
++	wlc_lcnphy_a1(pi, 4, 0, 0);
++	wlc_lcnphy_a1(pi, 3, 0, 0);
++	wlc_lcnphy_a1(pi, 2, 3, 2);
++	wlc_lcnphy_a1(pi, 0, 5, 8);
++	wlc_lcnphy_a1(pi, 2, 2, 1);
++	wlc_lcnphy_a1(pi, 0, 4, 3);
++
++	iqcc0 = wlc_lcnphy_get_cc(pi, 0);
++	locc2 = wlc_lcnphy_get_cc(pi, 2);
++	locc3 = wlc_lcnphy_get_cc(pi, 3);
++	locc4 = wlc_lcnphy_get_cc(pi, 4);
++}
++
++u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u16 didq;
++
++	tab.tbl_id = 0;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &didq;
++	tab.tbl_len = 1;
++	tab.tbl_offset = 85;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	return didq;
++}
++
++static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
++{
++
++	struct lcnphy_txgains target_gains, old_gains;
++	u8 save_bb_mult;
++	u16 a, b, didq, save_pa_gain = 0;
++	uint idx, SAVE_txpwrindex = 0xFF;
++	u32 val;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct phytbl_info tab;
++	u8 ei0, eq0, fi0, fq0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	wlc_lcnphy_get_tx_gain(pi, &old_gains);
++	save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
++
++	save_bb_mult = wlc_lcnphy_get_bbmult(pi);
++
++	if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
++		SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++
++	target_gains.gm_gain = 7;
++	target_gains.pga_gain = 0;
++	target_gains.pad_gain = 21;
++	target_gains.dac_gain = 0;
++	wlc_lcnphy_set_tx_gain(pi, &target_gains);
++	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
++
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
++
++		wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++				       (pi_lcn->
++					lcnphy_recal ? LCNPHY_CAL_RECAL :
++					LCNPHY_CAL_FULL), false);
++	} else {
++		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++	}
++
++	wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
++	if ((abs((s8) fi0) == 15) && (abs((s8) fq0) == 15)) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			target_gains.gm_gain = 255;
++			target_gains.pga_gain = 255;
++			target_gains.pad_gain = 0xf0;
++			target_gains.dac_gain = 0;
++		} else {
++			target_gains.gm_gain = 7;
++			target_gains.pga_gain = 45;
++			target_gains.pad_gain = 186;
++			target_gains.dac_gain = 0;
++		}
++
++		if (LCNREV_IS(pi->pubpi.phy_rev, 1)
++		    || pi_lcn->lcnphy_hw_iqcal_en) {
++
++			target_gains.pga_gain = 0;
++			target_gains.pad_gain = 30;
++			wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
++			wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
++					       LCNPHY_CAL_FULL, false);
++		} else {
++			wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
++		}
++	}
++
++	wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
++
++	didq = wlc_lcnphy_get_tx_locc(pi);
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_ptr = &val;
++
++	tab.tbl_len = 1;
++	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
++
++	for (idx = 0; idx < 128; idx++) {
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
++
++		wlc_lcnphy_read_table(pi, &tab);
++		val = (val & 0xfff00000) |
++		      ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = didq;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
++	pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
++	pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
++	pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
++	pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
++
++	wlc_lcnphy_set_bbmult(pi, save_bb_mult);
++	wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
++	wlc_lcnphy_set_tx_gain(pi, &old_gains);
++
++	if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++	else
++		wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
++}
++
++s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s16 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (s16) (tempsenseval1 - 512);
++	else
++		avg = (s16) tempsenseval1;
++
++	if (tempsenseval2 > 255)
++		avg += (s16) (tempsenseval2 - 512);
++	else
++		avg += (s16) tempsenseval2;
++
++	avg /= 2;
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return avg;
++}
++
++u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
++{
++	u16 tempsenseval1, tempsenseval2;
++	s32 avg = 0;
++	bool suspend = false;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
++	}
++	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
++	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
++
++	if (tempsenseval1 > 255)
++		avg = (int)(tempsenseval1 - 512);
++	else
++		avg = (int)tempsenseval1;
++
++	if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg - tempsenseval2 + 512);
++		else
++			avg = (int)(avg - tempsenseval2);
++	} else {
++		if (tempsenseval2 > 255)
++			avg = (int)(avg + tempsenseval2 - 512);
++		else
++			avg = (int)(avg + tempsenseval2);
++		avg = avg / 2;
++	}
++	if (avg < 0)
++		avg = avg + 512;
++
++	if (pi_lcn->lcnphy_tempsense_option == 2)
++		avg = tempsenseval1;
++
++	if (mode)
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
++
++	if (mode == 1) {
++
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++		udelay(100);
++		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (u16) avg;
++}
++
++s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode)
++{
++	s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
++	degree =
++		((degree <<
++		  10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
++		/ LCN_TEMPSENSE_DEN;
++	return (s8) degree;
++}
++
++s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
++{
++	u16 vbatsenseval;
++	s32 avg = 0;
++	bool suspend = false;
++
++	if (mode == 1) {
++		suspend = (0 == (bcma_read32(pi->d11core,
++					     D11REGOFFS(maccontrol)) &
++				 MCTL_EN_MAC));
++		if (!suspend)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++		wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
++	}
++
++	vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
++
++	if (vbatsenseval > 255)
++		avg = (s32) (vbatsenseval - 512);
++	else
++		avg = (s32) vbatsenseval;
++
++	avg =	(avg * LCN_VBAT_SCALE_NOM +
++		 (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
++
++	if (mode == 1) {
++		if (!suspend)
++			wlapi_enable_mac(pi->sh->physhim);
++	}
++	return (s8) avg;
++}
++
++static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode)
++{
++	u8 phybw40;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
++
++	if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
++	    (mode == AFE_CLK_INIT_MODE_TXRX2X))
++		write_phy_reg(pi, 0x6d0, 0x7);
++
++	wlc_lcnphy_toggle_afe_pwdn(pi);
++}
++
++static void wlc_lcnphy_temp_adj(struct brcms_phy *pi)
++{
++}
++
++static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
++{
++	bool suspend;
++	s8 index;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	wlc_lcnphy_deaf_mode(pi, true);
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	index = pi_lcn->lcnphy_current_index;
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++
++}
++
++static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
++{
++	bool suspend, full_cal;
++	const struct lcnphy_rx_iqcomp *rx_iqcomp;
++	int rx_iqcomp_sz;
++	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	s8 index;
++	struct phytbl_info tab;
++	s32 a1, b0, b1;
++	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	pi->phy_lastcal = pi->sh->now;
++	pi->phy_forcecal = false;
++	full_cal =
++		(pi_lcn->lcnphy_full_cal_channel !=
++		 CHSPEC_CHANNEL(pi->radio_chanspec));
++	pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++	index = pi_lcn->lcnphy_current_index;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend) {
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	wlc_lcnphy_deaf_mode(pi, true);
++
++	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
++
++	rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
++	rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
++	else
++		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
++
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++
++		wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi);
++
++		b0 = pi->txpa_2g[0];
++		b1 = pi->txpa_2g[1];
++		a1 = pi->txpa_2g[2];
++		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
++		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
++
++		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++		tab.tbl_width = 32;
++		tab.tbl_ptr = &pwr;
++		tab.tbl_len = 1;
++		tab.tbl_offset = 0;
++		for (tssi = 0; tssi < 128; tssi++) {
++			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
++			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
++			wlc_lcnphy_write_table(pi, &tab);
++			tab.tbl_offset++;
++		}
++	}
++
++	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
++	wlc_lcnphy_deaf_mode(pi, false);
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode)
++{
++	u16 temp_new;
++	int temp1, temp2, temp_diff;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	switch (mode) {
++	case PHY_PERICAL_CHAN:
++		break;
++	case PHY_FULLCAL:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_PHYINIT:
++		wlc_lcnphy_periodic_cal(pi);
++		break;
++	case PHY_PERICAL_WATCHDOG:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++			temp_new = wlc_lcnphy_tempsense(pi, 0);
++			temp1 = LCNPHY_TEMPSENSE(temp_new);
++			temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
++			temp_diff = temp1 - temp2;
++			if ((pi_lcn->lcnphy_cal_counter > 90) ||
++			    (temp_diff > 60) || (temp_diff < -60)) {
++				wlc_lcnphy_glacial_timer_based_cal(pi);
++				wlc_2064_vco_cal(pi);
++				pi_lcn->lcnphy_cal_temper = temp_new;
++				pi_lcn->lcnphy_cal_counter = 0;
++			} else
++				pi_lcn->lcnphy_cal_counter++;
++		}
++		break;
++	case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
++		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++			wlc_lcnphy_tx_power_adjustment(
++				(struct brcms_phy_pub *) pi);
++		break;
++	}
++}
++
++void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr)
++{
++	s8 cck_offset;
++	u16 status;
++	status = (read_phy_reg(pi, 0x4ab));
++	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
++	    (status  & (0x1 << 15))) {
++		*ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
++				   >> 0) >> 1);
++
++		if (wlc_phy_tpc_isenabled_lcnphy(pi))
++			cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
++		else
++			cck_offset = 0;
++
++		*cck_pwr = *ofdm_pwr + cck_offset;
++	} else {
++		*cck_pwr = 0;
++		*ofdm_pwr = 0;
++	}
++}
++
++void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi)
++{
++	return;
++
++}
++
++void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
++{
++	s8 index;
++	u16 index2;
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
++	    SAVE_txpwrctrl) {
++		index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
++		index2 = (u16) (index * 2);
++		mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
++
++		pi_lcn->lcnphy_current_index =
++			(s8)((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
++	}
++}
++
++static void
++wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
++			      const struct lcnphy_tx_gain_tbl_entry *gain_table)
++{
++	u32 j;
++	struct phytbl_info tab;
++	u32 val;
++	u16 pa_gain;
++	u16 gm_gain;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		pa_gain = 0x70;
++	else
++		pa_gain = 0x70;
++
++	if (pi->sh->boardflags & BFL_FEM)
++		pa_gain = 0x10;
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++	tab.tbl_ptr = &val;
++
++	for (j = 0; j < 128; j++) {
++		gm_gain = gain_table[j].gm;
++		val = (((u32) pa_gain << 24) |
++		       (gain_table[j].pad << 16) |
++		       (gain_table[j].pga << 8) | gm_gain);
++
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++
++		val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi)
++{
++	struct phytbl_info tab;
++	u32 val, bbmult, rfgain;
++	u8 index;
++	u8 scale_factor = 1;
++	s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
++
++	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
++	tab.tbl_width = 32;
++	tab.tbl_len = 1;
++
++	for (index = 0; index < 128; index++) {
++		tab.tbl_ptr = &bbmult;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++		bbmult = bbmult >> 20;
++
++		tab.tbl_ptr = &rfgain;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
++		wlc_lcnphy_read_table(pi, &tab);
++
++		qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
++		qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
++
++		if (qQ1 < qQ2) {
++			temp2 = qm_shr16(temp2, qQ2 - qQ1);
++			qQ = qQ1;
++		} else {
++			temp1 = qm_shr16(temp1, qQ1 - qQ2);
++			qQ = qQ2;
++		}
++		temp = qm_sub16(temp1, temp2);
++
++		if (qQ >= 4)
++			shift = qQ - 4;
++		else
++			shift = 4 - qQ;
++
++		val = (((index << shift) + (5 * temp) +
++			(1 << (scale_factor + shift - 3))) >> (scale_factor +
++							       shift - 2));
++
++		tab.tbl_ptr = &val;
++		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++}
++
++static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi)
++{
++	or_phy_reg(pi, 0x805, 0x1);
++
++	mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
++
++	mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
++
++	write_phy_reg(pi, 0x414, 0x1e10);
++	write_phy_reg(pi, 0x415, 0x0640);
++
++	mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++	mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
++
++	mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
++
++	if (!(pi->sh->boardrev < 0x1204))
++		mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
++
++	write_phy_reg(pi, 0x7d6, 0x0902);
++	mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
++
++	mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++		mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
++
++		mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
++
++		mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
++
++		mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
++
++		mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
++
++		mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
++		mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
++		mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
++		mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
++
++		mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
++
++		wlc_lcnphy_clear_tx_power_offsets(pi);
++		mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
++
++	}
++}
++
++static void wlc_lcnphy_rcal(struct brcms_phy *pi)
++{
++	u8 rcal_value;
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	or_radio_reg(pi, RADIO_2064_REG004, 0x40);
++	or_radio_reg(pi, RADIO_2064_REG120, 0x10);
++
++	or_radio_reg(pi, RADIO_2064_REG078, 0x80);
++	or_radio_reg(pi, RADIO_2064_REG129, 0x02);
++
++	or_radio_reg(pi, RADIO_2064_REG057, 0x01);
++
++	or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
++	mdelay(5);
++	SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
++
++	if (wlc_radio_2064_rcal_done(pi)) {
++		rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
++		rcal_value = rcal_value & 0x1f;
++	}
++
++	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
++
++	and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
++}
++
++static void wlc_lcnphy_rc_cal(struct brcms_phy *pi)
++{
++	u8 dflt_rc_cal_val;
++	u16 flt_val;
++
++	dflt_rc_cal_val = 7;
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
++		dflt_rc_cal_val = 11;
++	flt_val =
++		(dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
++		(dflt_rc_cal_val);
++	write_phy_reg(pi, 0x933, flt_val);
++	write_phy_reg(pi, 0x934, flt_val);
++	write_phy_reg(pi, 0x935, flt_val);
++	write_phy_reg(pi, 0x936, flt_val);
++	write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
++
++	return;
++}
++
++static void wlc_radio_2064_init(struct brcms_phy *pi)
++{
++	u32 i;
++	const struct lcnphy_radio_regs *lcnphyregs = NULL;
++
++	lcnphyregs = lcnphy_radio_regs_2064;
++
++	for (i = 0; lcnphyregs[i].address != 0xffff; i++)
++		if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_a);
++		else if (lcnphyregs[i].do_init_g)
++			write_radio_reg(pi,
++					((lcnphyregs[i].address & 0x3fff) |
++					 RADIO_DEFAULT_CORE),
++					(u16) lcnphyregs[i].init_g);
++
++	write_radio_reg(pi, RADIO_2064_REG032, 0x62);
++	write_radio_reg(pi, RADIO_2064_REG033, 0x19);
++
++	write_radio_reg(pi, RADIO_2064_REG090, 0x10);
++
++	write_radio_reg(pi, RADIO_2064_REG010, 0x00);
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
++
++		write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
++		write_radio_reg(pi, RADIO_2064_REG061, 0x72);
++		write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
++	}
++
++	write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
++	write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
++
++	mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
++
++	write_phy_reg(pi, 0x4ea, 0x4688);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
++
++	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
++
++	mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
++
++	wlc_lcnphy_set_tx_locc(pi, 0);
++
++	wlc_lcnphy_rcal(pi);
++
++	wlc_lcnphy_rc_cal(pi);
++}
++
++static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
++{
++	wlc_radio_2064_init(pi);
++}
++
++static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
++{
++	uint idx;
++	u8 phybw40;
++	struct phytbl_info tab;
++	u32 val;
++
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++)
++		wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
++
++	if (pi->sh->boardflags & BFL_FEM_BT) {
++		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++		tab.tbl_width = 16;
++		tab.tbl_ptr = &val;
++		tab.tbl_len = 1;
++		val = 100;
++		tab.tbl_offset = 4;
++		wlc_lcnphy_write_table(pi, &tab);
++	}
++
++	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
++	tab.tbl_width = 16;
++	tab.tbl_ptr = &val;
++	tab.tbl_len = 1;
++
++	val = 114;
++	tab.tbl_offset = 0;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 130;
++	tab.tbl_offset = 1;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	val = 6;
++	tab.tbl_offset = 8;
++	wlc_lcnphy_write_table(pi, &tab);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->sh->boardflags & BFL_FEM)
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_extPA_gaintable_rev0);
++		else
++			wlc_lcnphy_load_tx_gain_table(
++				pi,
++				dot11lcnphy_2GHz_gaintable_rev0);
++	}
++
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
++		const struct phytbl_info *tb;
++		int l;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			l = dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_2G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_2G_rev2;
++		} else {
++			l = dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++			if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
++				tb = dot11lcnphytbl_rx_gain_info_extlna_5G_rev2;
++			else
++				tb = dot11lcnphytbl_rx_gain_info_5G_rev2;
++		}
++
++		for (idx = 0; idx < l; idx++)
++			wlc_lcnphy_write_table(pi, &tb[idx]);
++	}
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && !(pi->sh->boardflags & BFL_FEM_BT))
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
++	else if (pi->sh->boardflags & BFL_FEM_BT) {
++		if (pi->sh->boardrev < 0x1250)
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
++		else
++			wlc_lcnphy_write_table(
++				pi,
++				&dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
++	} else
++		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
++
++	wlc_lcnphy_load_rfpower(pi);
++
++	wlc_lcnphy_clear_papd_comptable(pi);
++}
++
++static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi)
++{
++	u16 afectrl1;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
++
++	write_phy_reg(pi, 0x43b, 0x0);
++	write_phy_reg(pi, 0x43c, 0x0);
++	write_phy_reg(pi, 0x44c, 0x0);
++	write_phy_reg(pi, 0x4e6, 0x0);
++	write_phy_reg(pi, 0x4f9, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x938, 0x0);
++	write_phy_reg(pi, 0x4b0, 0x0);
++	write_phy_reg(pi, 0x44e, 0);
++
++	or_phy_reg(pi, 0x567, 0x03);
++
++	or_phy_reg(pi, 0x44a, 0x44);
++	write_phy_reg(pi, 0x44a, 0x80);
++
++	if (!(pi->sh->boardflags & BFL_FEM))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
++
++	if (0) {
++		afectrl1 = 0;
++		afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
++				  (pi_lcn->lcnphy_rssi_vc << 4) |
++				  (pi_lcn->lcnphy_rssi_gs << 10));
++		write_phy_reg(pi, 0x43e, afectrl1);
++	}
++
++	mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
++	if (pi->sh->boardflags & BFL_FEM) {
++		mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
++
++		write_phy_reg(pi, 0x910, 0x1);
++	}
++
++	mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
++	mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
++	mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
++
++}
++
++static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
++		mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
++	}
++}
++
++static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi)
++{
++	s16 temp;
++	struct phytbl_info tab;
++	u32 tableBuffer[2];
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	temp = (s16) read_phy_reg(pi, 0x4df);
++	pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
++
++	if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
++		pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
++
++	pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
++
++	if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
++		pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = 17;
++	tab.tbl_offset = 59;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	if (tableBuffer[0] > 63)
++		tableBuffer[0] -= 128;
++	pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
++
++	if (tableBuffer[1] > 63)
++		tableBuffer[1] -= 128;
++	pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
++
++	temp = (s16) (read_phy_reg(pi, 0x434) & (0xff << 0));
++	if (temp > 127)
++		temp -= 256;
++	pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
++
++	pi_lcn->lcnphy_Med_Low_Gain_db =
++		(read_phy_reg(pi, 0x424) & (0xff << 8)) >> 8;
++	pi_lcn->lcnphy_Very_Low_Gain_db =
++		(read_phy_reg(pi, 0x425) & (0xff << 0)) >> 0;
++
++	tab.tbl_ptr = tableBuffer;
++	tab.tbl_len = 2;
++	tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
++	tab.tbl_offset = 28;
++	tab.tbl_width = 32;
++	wlc_lcnphy_read_table(pi, &tab);
++
++	pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
++	pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
++
++}
++
++static void wlc_lcnphy_baseband_init(struct brcms_phy *pi)
++{
++
++	wlc_lcnphy_tbl_init(pi);
++	wlc_lcnphy_rev0_baseband_init(pi);
++	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
++		wlc_lcnphy_rev2_baseband_init(pi);
++	wlc_lcnphy_bu_tweaks(pi);
++}
++
++void wlc_phy_init_lcnphy(struct brcms_phy *pi)
++{
++	u8 phybw40;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++
++	pi_lcn->lcnphy_cal_counter = 0;
++	pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
++
++	or_phy_reg(pi, 0x44a, 0x80);
++	and_phy_reg(pi, 0x44a, 0x7f);
++
++	wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
++
++	write_phy_reg(pi, 0x60a, 160);
++
++	write_phy_reg(pi, 0x46a, 25);
++
++	wlc_lcnphy_baseband_init(pi);
++
++	wlc_lcnphy_radio_init(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi);
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
++
++	si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
++
++	if ((pi->sh->boardflags & BFL_FEM)
++	    && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
++
++	wlc_lcnphy_agc_temp_init(pi);
++
++	wlc_lcnphy_temp_adj(pi);
++
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
++
++	udelay(100);
++	mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
++
++	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
++	pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
++	wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
++}
++
++static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi)
++{
++	s8 txpwr = 0;
++	int i;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 cckpo = 0;
++		u32 offset_ofdm, offset_mcs;
++
++		pi_lcn->lcnphy_tr_isolation_mid = sprom->fem.ghz2.tr_iso;
++
++		pi_lcn->lcnphy_rx_power_offset = sprom->rxpo2g;
++
++		pi->txpa_2g[0] = sprom->pa0b0;
++		pi->txpa_2g[1] = sprom->pa0b1;
++		pi->txpa_2g[2] = sprom->pa0b2;
++
++		pi_lcn->lcnphy_rssi_vf = sprom->rssismf2g;
++		pi_lcn->lcnphy_rssi_vc = sprom->rssismc2g;
++		pi_lcn->lcnphy_rssi_gs = sprom->rssisav2g;
++
++		pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
++
++		pi_lcn->lcnphy_rssi_vf_hightemp = pi_lcn->lcnphy_rssi_vf;
++		pi_lcn->lcnphy_rssi_vc_hightemp = pi_lcn->lcnphy_rssi_vc;
++		pi_lcn->lcnphy_rssi_gs_hightemp = pi_lcn->lcnphy_rssi_gs;
++
++		txpwr = sprom->core_pwr_info[0].maxpwr_2g;
++		pi->tx_srom_max_2g = txpwr;
++
++		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
++			pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
++			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
++		}
++
++		cckpo = sprom->cck2gpo;
++		offset_ofdm = sprom->ofdm2gpo;
++		if (cckpo) {
++			uint max_pwr_chan = txpwr;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan - ((cckpo & 0xf) * 2);
++				cckpo >>= 4;
++			}
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					max_pwr_chan -
++					((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++		} else {
++			u8 opo = 0;
++
++			opo = sprom->opo;
++
++			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++)
++				pi->tx_srom_max_rate_2g[i] = txpwr;
++
++			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
++				pi->tx_srom_max_rate_2g[i] = txpwr -
++						((offset_ofdm & 0xf) * 2);
++				offset_ofdm >>= 4;
++			}
++			offset_mcs = sprom->mcs2gpo[1] << 16;
++			offset_mcs |= sprom->mcs2gpo[0];
++			pi_lcn->lcnphy_mcs20_po = offset_mcs;
++			for (i = TXP_FIRST_SISO_MCS_20;
++			     i <= TXP_LAST_SISO_MCS_20; i++) {
++				pi->tx_srom_max_rate_2g[i] =
++					txpwr - ((offset_mcs & 0xf) * 2);
++				offset_mcs >>= 4;
++			}
++		}
++
++		pi_lcn->lcnphy_rawtempsense = sprom->rawtempsense;
++		pi_lcn->lcnphy_measPower = sprom->measpower;
++		pi_lcn->lcnphy_tempsense_slope = sprom->tempsense_slope;
++		pi_lcn->lcnphy_hw_iqcal_en = sprom->hw_iqcal_en;
++		pi_lcn->lcnphy_iqcal_swp_dis = sprom->iqcal_swp_dis;
++		pi_lcn->lcnphy_tempcorrx = sprom->tempcorrx;
++		pi_lcn->lcnphy_tempsense_option = sprom->tempsense_option;
++		pi_lcn->lcnphy_freqoffset_corr = sprom->freqoffset_corr;
++		if (sprom->ant_available_bg > 1)
++			wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi,
++				sprom->ant_available_bg);
++	}
++	pi_lcn->lcnphy_cck_dig_filt_type = -1;
++
++	return true;
++}
++
++void wlc_2064_vco_cal(struct brcms_phy *pi)
++{
++	u8 calnrst;
++
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
++	calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
++	udelay(1);
++	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
++	udelay(300);
++	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
++}
++
++bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi)
++{
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
++		return 0;
++	else
++		return (LCNPHY_TX_PWR_CTRL_HW ==
++			wlc_lcnphy_get_tx_pwr_ctrl((pi)));
++}
++
++void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
++{
++	u16 pwr_ctrl;
++	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
++		wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
++	} else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
++		pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
++		wlc_lcnphy_txpower_recalc_target(pi);
++		wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
++	}
++}
++
++void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
++{
++	kfree(pi->u.pi_lcnphy);
++}
++
++bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
++{
++	struct brcms_phy_lcnphy *pi_lcn;
++
++	pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC);
++	if (pi->u.pi_lcnphy == NULL)
++		return false;
++
++	pi_lcn = pi->u.pi_lcnphy;
++
++	if (0 == (pi->sh->boardflags & BFL_NOPA)) {
++		pi->hwpwrctrl = true;
++		pi->hwpwrctrl_capable = true;
++	}
++
++	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
++	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
++
++	pi->pi_fptr.init = wlc_phy_init_lcnphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
++	pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
++	pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
++	pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
++	pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
++	pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
++
++	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
++		return false;
++
++	if ((pi->sh->boardflags & BFL_FEM) &&
++	    (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
++		if (pi_lcn->lcnphy_tempsense_option == 3) {
++			pi->hwpwrctrl = true;
++			pi->hwpwrctrl_capable = true;
++			pi->temppwrctrl_capable = false;
++		} else {
++			pi->hwpwrctrl = false;
++			pi->hwpwrctrl_capable = false;
++			pi->temppwrctrl_capable = true;
++		}
++	}
++
++	return true;
++}
++
++static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain)
++{
++	u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
++
++	trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
++	ext_lna = (u16) (gain >> 29) & 0x01;
++	lna1 = (u16) (gain >> 0) & 0x0f;
++	lna2 = (u16) (gain >> 4) & 0x0f;
++	tia = (u16) (gain >> 8) & 0xf;
++	biq0 = (u16) (gain >> 12) & 0xf;
++	biq1 = (u16) (gain >> 16) & 0xf;
++
++	gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
++			  ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
++			  ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
++	gain16_19 = biq1;
++
++	mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
++	mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
++	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
++	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
++		mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
++	}
++	wlc_lcnphy_rx_gain_override_enable(pi, true);
++}
++
++static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index)
++{
++	u32 received_power = 0;
++	s32 max_index = 0;
++	u32 gain_code = 0;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	max_index = 36;
++	if (*gain_index >= 0)
++		gain_code = lcnphy_23bitgaincode_table[*gain_index];
++
++	if (-1 == *gain_index) {
++		*gain_index = 0;
++		while ((*gain_index <= (s32) max_index)
++		       && (received_power < 700)) {
++			wlc_lcnphy_set_rx_gain(pi,
++					       lcnphy_23bitgaincode_table
++					       [*gain_index]);
++			received_power =
++				wlc_lcnphy_measure_digital_power(
++					pi,
++					pi_lcn->
++					lcnphy_noise_samples);
++			(*gain_index)++;
++		}
++		(*gain_index)--;
++	} else {
++		wlc_lcnphy_set_rx_gain(pi, gain_code);
++		received_power =
++			wlc_lcnphy_measure_digital_power(pi,
++							 pi_lcn->
++							 lcnphy_noise_samples);
++	}
++
++	return received_power;
++}
++
++s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index)
++{
++	s32 gain = 0;
++	s32 nominal_power_db;
++	s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
++	    input_power_db;
++	s32 received_power, temperature;
++	u32 power;
++	u32 msb1, msb2, val1, val2, diff1, diff2;
++	uint freq;
++	struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
++
++	received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
++
++	gain = lcnphy_gain_table[gain_index];
++
++	nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
++
++	power = (received_power * 16);
++	msb1 = ffs(power) - 1;
++	msb2 = msb1 + 1;
++	val1 = 1 << msb1;
++	val2 = 1 << msb2;
++	diff1 = (power - val1);
++	diff2 = (val2 - power);
++	if (diff1 < diff2)
++		log_val = msb1;
++	else
++		log_val = msb2;
++
++	log_val = log_val * 3;
++
++	gain_mismatch = (nominal_power_db / 2) - (log_val);
++
++	desired_gain = gain + gain_mismatch;
++
++	input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
++
++	if (input_power_offset_db > 127)
++		input_power_offset_db -= 256;
++
++	input_power_db = input_power_offset_db - desired_gain;
++
++	input_power_db =
++		input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
++
++	freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
++	if ((freq > 2427) && (freq <= 2467))
++		input_power_db = input_power_db - 1;
++
++	temperature = pi_lcn->lcnphy_lastsensed_temperature;
++
++	if ((temperature - 15) < -30)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			7;
++	else if ((temperature - 15) < 4)
++		input_power_db =
++			input_power_db +
++			(((temperature - 10 - 25) * 286) >> 12) -
++			3;
++	else
++		input_power_db = input_power_db +
++					(((temperature - 10 - 25) * 286) >> 12);
++
++	wlc_lcnphy_rx_gain_override_enable(pi, 0);
++
++	return input_power_db;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+new file mode 100644
+index 0000000..f4a8ab0
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
+@@ -0,0 +1,121 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PHY_LCN_H_
++#define _BRCM_PHY_LCN_H_
++
++#include <types.h>
++
++struct brcms_phy_lcnphy {
++	int lcnphy_txrf_sp_9_override;
++	u8 lcnphy_full_cal_channel;
++	u8 lcnphy_cal_counter;
++	u16 lcnphy_cal_temper;
++	bool lcnphy_recal;
++
++	u8 lcnphy_rc_cap;
++	u32 lcnphy_mcs20_po;
++
++	u8 lcnphy_tr_isolation_mid;
++	u8 lcnphy_tr_isolation_low;
++	u8 lcnphy_tr_isolation_hi;
++
++	u8 lcnphy_bx_arch;
++	u8 lcnphy_rx_power_offset;
++	u8 lcnphy_rssi_vf;
++	u8 lcnphy_rssi_vc;
++	u8 lcnphy_rssi_gs;
++	u8 lcnphy_tssi_val;
++	u8 lcnphy_rssi_vf_lowtemp;
++	u8 lcnphy_rssi_vc_lowtemp;
++	u8 lcnphy_rssi_gs_lowtemp;
++
++	u8 lcnphy_rssi_vf_hightemp;
++	u8 lcnphy_rssi_vc_hightemp;
++	u8 lcnphy_rssi_gs_hightemp;
++
++	s16 lcnphy_pa0b0;
++	s16 lcnphy_pa0b1;
++	s16 lcnphy_pa0b2;
++
++	u16 lcnphy_rawtempsense;
++	u8 lcnphy_measPower;
++	u8 lcnphy_tempsense_slope;
++	u8 lcnphy_freqoffset_corr;
++	u8 lcnphy_tempsense_option;
++	u8 lcnphy_tempcorrx;
++	bool lcnphy_iqcal_swp_dis;
++	bool lcnphy_hw_iqcal_en;
++	uint lcnphy_bandedge_corr;
++	bool lcnphy_spurmod;
++	u16 lcnphy_tssi_tx_cnt;
++	u16 lcnphy_tssi_idx;
++	u16 lcnphy_tssi_npt;
++
++	u16 lcnphy_target_tx_freq;
++	s8 lcnphy_tx_power_idx_override;
++	u16 lcnphy_noise_samples;
++
++	u32 lcnphy_papdRxGnIdx;
++	u32 lcnphy_papd_rxGnCtrl_init;
++
++	u32 lcnphy_gain_idx_14_lowword;
++	u32 lcnphy_gain_idx_14_hiword;
++	u32 lcnphy_gain_idx_27_lowword;
++	u32 lcnphy_gain_idx_27_hiword;
++	s16 lcnphy_ofdmgainidxtableoffset;
++	s16 lcnphy_dsssgainidxtableoffset;
++	u32 lcnphy_tr_R_gain_val;
++	u32 lcnphy_tr_T_gain_val;
++	s8 lcnphy_input_pwr_offset_db;
++	u16 lcnphy_Med_Low_Gain_db;
++	u16 lcnphy_Very_Low_Gain_db;
++	s8 lcnphy_lastsensed_temperature;
++	s8 lcnphy_pkteng_rssi_slope;
++	u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
++	u8 lcnphy_volt_winner;
++	u8 lcnphy_volt_low;
++	u8 lcnphy_54_48_36_24mbps_backoff;
++	u8 lcnphy_11n_backoff;
++	u8 lcnphy_lowerofdm;
++	u8 lcnphy_cck;
++	u8 lcnphy_psat_2pt3_detected;
++	s32 lcnphy_lowest_Re_div_Im;
++	s8 lcnphy_final_papd_cal_idx;
++	u16 lcnphy_extstxctrl4;
++	u16 lcnphy_extstxctrl0;
++	u16 lcnphy_extstxctrl1;
++	s16 lcnphy_cck_dig_filt_type;
++	s16 lcnphy_ofdm_dig_filt_type;
++	struct lcnphy_cal_results lcnphy_cal_results;
++
++	u8 lcnphy_psat_pwr;
++	u8 lcnphy_psat_indx;
++	s32 lcnphy_min_phase;
++	u8 lcnphy_final_idx;
++	u8 lcnphy_start_idx;
++	u8 lcnphy_current_index;
++	u16 lcnphy_logen_buf_1;
++	u16 lcnphy_local_ovr_2;
++	u16 lcnphy_local_oval_6;
++	u16 lcnphy_local_oval_5;
++	u16 lcnphy_logen_mixer_1;
++
++	u8 lcnphy_aci_stat;
++	uint lcnphy_aci_start_time;
++	s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
++};
++#endif				/* _BRCM_PHY_LCN_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+new file mode 100644
+index 0000000..06975af
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+@@ -0,0 +1,28685 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/kernel.h>
++#include <linux/printk.h>
++#include <linux/delay.h>
++#include <linux/cordic.h>
++
++#include <brcm_hw_ids.h>
++#include <aiutils.h>
++#include <chipcommon.h>
++#include <pmu.h>
++#include <d11.h>
++#include <phy_shim.h>
++#include "phy_int.h"
++#include "phy_hal.h"
++#include "phy_radio.h"
++#include "phyreg_n.h"
++#include "phytbl_n.h"
++#include "soc.h"
++
++#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, radio_type##_##jspace##_##reg_name |	\
++		       ((core == PHY_CORE_0) ? \
++			radio_type##_##jspace##0 : \
++			radio_type##_##jspace##1))
++
++#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
++			((core ==  PHY_CORE_0) ? \
++			 radio_type##_##jspace##0 : \
++			 radio_type##_##jspace##1), value)
++
++#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
++	write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value)
++
++#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			    radio_type##_##jspace##0##_##reg_name : \
++			    radio_type##_##jspace##1##_##reg_name))
++
++#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core ==  PHY_CORE_0) ? \
++			     radio_type##_##jspace##0##_##reg_name : \
++			     radio_type##_##jspace##1##_##reg_name), \
++			value)
++
++#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name)	\
++	read_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			     radio_type##_##reg_name##_##jspace##0 : \
++			     radio_type##_##reg_name##_##jspace##1))
++
++#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value)	\
++	write_radio_reg(pi, ((core == PHY_CORE_0) ? \
++			radio_type##_##reg_name##_##jspace##0 : \
++			radio_type##_##reg_name##_##jspace##1), \
++			value)
++
++#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
++#define NPHY_ACI_CHANNEL_DELTA 5
++#define NPHY_ACI_CHANNEL_SKIP 4
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
++#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
++#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
++#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
++#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
++
++#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
++
++#define NPHY_NOISE_NOASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_ENTER_TH  400
++
++#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH  400
++
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
++#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
++
++#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
++
++#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
++
++#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
++
++#define NPHY_RSSICAL_MAXREAD 31
++
++#define NPHY_RSSICAL_NPOLL 8
++#define NPHY_RSSICAL_MAXD  (1<<20)
++#define NPHY_MIN_RXIQ_PWR 2
++
++#define NPHY_RSSICAL_W1_TARGET 25
++#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
++#define NPHY_RSSICAL_NB_TARGET 0
++
++#define NPHY_RSSICAL_W1_TARGET_REV3 29
++#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
++
++#define NPHY_CALSANITY_RSSI_NB_MAX_POS  9
++#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
++#define NPHY_CALSANITY_RSSI_W1_MAX_POS  12
++#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_CALSANITY_RSSI_W2_MAX_POS  NPHY_CALSANITY_RSSI_W1_MAX_POS
++#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - \
++					NPHY_RSSICAL_MAXREAD)
++#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
++#define NPHY_RSSI_NB_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
++#define NPHY_RSSI_W1_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
++#define NPHY_RSSI_W2_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
++			       ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
++
++#define NPHY_IQCAL_NUMGAINS 9
++#define NPHY_N_GCTL 0x66
++
++#define NPHY_PAPD_EPS_TBL_SIZE 64
++#define NPHY_PAPD_SCL_TBL_SIZE 64
++#define NPHY_NUM_DIG_FILT_COEFFS 15
++
++#define NPHY_PAPD_COMP_OFF 0
++#define NPHY_PAPD_COMP_ON  1
++
++#define NPHY_SROM_TEMPSHIFT             32
++#define NPHY_SROM_MAXTEMPOFFSET         16
++#define NPHY_SROM_MINTEMPOFFSET         -16
++
++#define NPHY_CAL_MAXTEMPDELTA           64
++
++#define NPHY_NOISEVAR_TBLLEN40 256
++#define NPHY_NOISEVAR_TBLLEN20 128
++
++#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
++
++#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
++
++/* 5357 Chip specific ChipControl register bits */
++#define CCTRL5357_EXTPA            (1<<14) /* extPA in ChipControl 1, bit 14 */
++#define CCTRL5357_ANT_MUX_2o3      (1<<15) /* 2o3 in ChipControl 1, bit 15 */
++
++#define NPHY_CAL_TSSISAMPS      64
++#define NPHY_TEST_TONE_FREQ_40MHz 4000
++#define NPHY_TEST_TONE_FREQ_20MHz 2500
++
++#define MAX_205x_RCAL_WAITLOOPS 10000
++
++#define NPHY_RXCAL_TONEAMP 181
++#define NPHY_RXCAL_TONEFREQ_40MHz 4000
++#define NPHY_RXCAL_TONEFREQ_20MHz 2000
++
++#define TXFILT_SHAPING_OFDM20   0
++#define TXFILT_SHAPING_OFDM40   1
++#define TXFILT_SHAPING_CCK      2
++#define TXFILT_DEFAULT_OFDM20   3
++#define TXFILT_DEFAULT_OFDM40   4
++
++struct nphy_iqcal_params {
++	u16 txlpf;
++	u16 txgm;
++	u16 pga;
++	u16 pad;
++	u16 ipa;
++	u16 cal_gain;
++	u16 ncorr[5];
++};
++
++struct nphy_txiqcal_ladder {
++	u8 percent;
++	u8 g_env;
++};
++
++struct nphy_ipa_txcalgains {
++	struct nphy_txgains gains;
++	bool useindex;
++	u8 index;
++};
++
++struct nphy_papd_restore_state {
++	u16 fbmix[2];
++	u16 vga_master[2];
++	u16 intpa_master[2];
++	u16 afectrl[2];
++	u16 afeoverride[2];
++	u16 pwrup[2];
++	u16 atten[2];
++	u16 mm;
++};
++
++struct nphy_ipa_txrxgain {
++	u16 hpvga;
++	u16 lpf_biq1;
++	u16 lpf_biq0;
++	u16 lna2;
++	u16 lna1;
++	s8 txpwrindex;
++};
++
++#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 2, 3, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = {
++	{0, 0, 0, 0, 0, 128},
++	{0, 0, 0, 0, 0, 70},
++	{0, 0, 0, 0, 0, 20},
++	{0, 0, 0, 3, 0, 20},
++	{0, 0, 3, 3, 0, 20},
++	{0, 2, 3, 3, 0, 20}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 100},
++	{0, 0, 0, 0, 0, 50},
++	{0, 0, 0, 0, 0, -1},
++	{0, 0, 0, 3, 0, -1},
++	{0, 0, 3, 3, 0, -1},
++	{0, 0, 5, 3, 0, -1}
++};
++
++static const struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = {
++	{0, 0, 0, 0, 0, 10},
++	{0, 0, 0, 1, 0, 10},
++	{0, 0, 1, 2, 0, 10},
++	{0, 0, 1, 3, 0, 10},
++	{0, 0, 4, 3, 0, 10},
++	{0, 0, 6, 3, 0, 10}
++};
++
++enum {
++	NPHY_RXCAL_GAIN_INIT = 0,
++	NPHY_RXCAL_GAIN_UP,
++	NPHY_RXCAL_GAIN_DOWN
++};
++
++#define wlc_phy_get_papd_nphy(pi) \
++	(read_phy_reg((pi), 0x1e7) & \
++	 ((0x1 << 15) |	\
++	  (0x1 << 14) |	\
++	  (0x1 << 13)))
++
++static const u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
++	{-377, 137, -407, 208, -1527, 956, 93, 186, 93,
++	 230, -44, 230, 201, -191, 201},
++	{-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
++	 26, 34, -32, 34},
++	{-360, 164, -376, 164, -1533, 576, 308, -314, 308,
++	 121, -73, 121, 91, 124, 91},
++	{-295, 200, -363, 142, -1391, 826, 151, 301, 151,
++	 151, 301, 151, 602, -752, 602},
++	{-92, 58, -96, 49, -104, 44, 17, 35, 17,
++	 12, 25, 12, 13, 27, 13},
++	{-375, 136, -399, 209, -1479, 949, 130, 260, 130,
++	 230, -44, 230, 201, -191, 201},
++	{0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
++	 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
++};
++
++struct chan_info_nphy_2055 {
++	u16 chan;
++	u16 freq;
++	uint unknown;
++	u8 RF_pll_ref;
++	u8 RF_rf_pll_mod1;
++	u8 RF_rf_pll_mod0;
++	u8 RF_vco_cap_tail;
++	u8 RF_vco_cal1;
++	u8 RF_vco_cal2;
++	u8 RF_pll_lf_c1;
++	u8 RF_pll_lf_r1;
++	u8 RF_pll_lf_c2;
++	u8 RF_lgbuf_cen_buf;
++	u8 RF_lgen_tune1;
++	u8 RF_lgen_tune2;
++	u8 RF_core1_lgbuf_a_tune;
++	u8 RF_core1_lgbuf_g_tune;
++	u8 RF_core1_rxrf_reg1;
++	u8 RF_core1_tx_pga_pad_tn;
++	u8 RF_core1_tx_mx_bgtrim;
++	u8 RF_core2_lgbuf_a_tune;
++	u8 RF_core2_lgbuf_g_tune;
++	u8 RF_core2_rxrf_reg1;
++	u8 RF_core2_tx_pga_pad_tn;
++	u8 RF_core2_tx_mx_bgtrim;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio205x {
++	u16 chan;
++	u16 freq;
++	u8 RF_SYN_pll_vcocal1;
++	u8 RF_SYN_pll_vcocal2;
++	u8 RF_SYN_pll_refdiv;
++	u8 RF_SYN_pll_mmd2;
++	u8 RF_SYN_pll_mmd1;
++	u8 RF_SYN_pll_loopfilter1;
++	u8 RF_SYN_pll_loopfilter2;
++	u8 RF_SYN_pll_loopfilter3;
++	u8 RF_SYN_pll_loopfilter4;
++	u8 RF_SYN_pll_loopfilter5;
++	u8 RF_SYN_reserved_addr27;
++	u8 RF_SYN_reserved_addr28;
++	u8 RF_SYN_reserved_addr29;
++	u8 RF_SYN_logen_VCOBUF1;
++	u8 RF_SYN_logen_MIXER2;
++	u8 RF_SYN_logen_BUF3;
++	u8 RF_SYN_logen_BUF4;
++	u8 RF_RX0_lnaa_tune;
++	u8 RF_RX0_lnag_tune;
++	u8 RF_TX0_intpaa_boost_tune;
++	u8 RF_TX0_intpag_boost_tune;
++	u8 RF_TX0_pada_boost_tune;
++	u8 RF_TX0_padg_boost_tune;
++	u8 RF_TX0_pgaa_boost_tune;
++	u8 RF_TX0_pgag_boost_tune;
++	u8 RF_TX0_mixa_boost_tune;
++	u8 RF_TX0_mixg_boost_tune;
++	u8 RF_RX1_lnaa_tune;
++	u8 RF_RX1_lnag_tune;
++	u8 RF_TX1_intpaa_boost_tune;
++	u8 RF_TX1_intpag_boost_tune;
++	u8 RF_TX1_pada_boost_tune;
++	u8 RF_TX1_padg_boost_tune;
++	u8 RF_TX1_pgaa_boost_tune;
++	u8 RF_TX1_pgag_boost_tune;
++	u8 RF_TX1_mixa_boost_tune;
++	u8 RF_TX1_mixg_boost_tune;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_mx5g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_logen_indbuf5g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_pga_boost_tune_core0;
++	u8 RF_txmix5g_boost_tune_core0;
++	u8 RF_pad5g_tune_misc_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_lna5g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_pga_boost_tune_core1;
++	u8 RF_txmix5g_boost_tune_core1;
++	u8 RF_pad5g_tune_misc_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u8 RF_lna5g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct chan_info_nphy_radio2057_rev5 {
++	u16 chan;
++	u16 freq;
++	u8 RF_vcocal_countval0;
++	u8 RF_vcocal_countval1;
++	u8 RF_rfpll_refmaster_sparextalsize;
++	u8 RF_rfpll_loopfilter_r1;
++	u8 RF_rfpll_loopfilter_c2;
++	u8 RF_rfpll_loopfilter_c1;
++	u8 RF_cp_kpd_idac;
++	u8 RF_rfpll_mmd0;
++	u8 RF_rfpll_mmd1;
++	u8 RF_vcobuf_tune;
++	u8 RF_logen_mx2g_tune;
++	u8 RF_logen_indbuf2g_tune;
++	u8 RF_txmix2g_tune_boost_pu_core0;
++	u8 RF_pad2g_tune_pus_core0;
++	u8 RF_lna2g_tune_core0;
++	u8 RF_txmix2g_tune_boost_pu_core1;
++	u8 RF_pad2g_tune_pus_core1;
++	u8 RF_lna2g_tune_core1;
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++struct nphy_sfo_cfg {
++	u16 PHY_BW1a;
++	u16 PHY_BW2;
++	u16 PHY_BW3;
++	u16 PHY_BW4;
++	u16 PHY_BW5;
++	u16 PHY_BW6;
++};
++
++static const struct chan_info_nphy_2055 chan_info_nphy_2055[] = {
++	{
++	 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
++	{
++	 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
++	{
++	 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
++	{
++	 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
++	{
++	 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
++	{
++	 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
++	{
++	 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
++	{
++	 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
++	{
++	 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
++	{
++	 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
++	{
++	 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
++	{
++	 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
++	{
++	 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
++	{
++	 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
++	 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
++	{
++	 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
++	{
++	 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
++	 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
++	{
++	 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
++	{
++	 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
++	 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
++	{
++	 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
++	{
++	 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
++	 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
++	{
++	 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
++	{
++	 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
++	 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
++	{
++	 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
++	 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
++	{
++	 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
++	{
++	 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
++	 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
++	{
++	 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
++	{
++	 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
++	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
++	 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
++	{
++	 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
++	{
++	 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
++	 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
++	{
++	 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
++	{
++	 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
++	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
++	 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
++	{
++	 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
++	{
++	 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
++	 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
++	{
++	 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
++	{
++	 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
++	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
++	 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
++	{
++	 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
++	{
++	 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
++	 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
++	{
++	 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
++	{
++	 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
++	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
++	 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
++	{
++	 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
++	{
++	 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
++	 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
++	{
++	 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
++	{
++	 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
++	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
++	 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
++	{
++	 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
++	{
++	 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
++	 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
++	{
++	 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
++	{
++	 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
++	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
++	 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
++	{
++	 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
++	{
++	 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
++	 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
++	{
++	 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
++	{
++	 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
++	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
++	 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
++	{
++	 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
++	{
++	 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
++	 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
++	{
++	 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
++	{
++	 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
++	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
++	 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
++	{
++	 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
++	{
++	 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
++	{
++	 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
++	{
++	 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
++	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
++	 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
++	{
++	 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
++	{
++	 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
++	{
++	 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
++	{
++	 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
++	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
++	 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
++	{
++	 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
++	{
++	 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
++	{
++	 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
++	{
++	 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
++	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
++	 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
++	{
++	 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
++	{
++	 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
++	 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
++	{
++	 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
++	{
++	 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
++	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
++	 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
++	{
++	 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
++	{
++	 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
++	{
++	 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
++	{
++	 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
++	{
++	 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
++	{
++	 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
++	{
++	 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
++	{
++	 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
++	{
++	 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
++	{
++	 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
++	{
++	 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
++	{
++	 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
++	{
++	 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
++	{
++	 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
++	{
++	 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
++	{
++	 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
++	{
++	 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
++	{
++	 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
++	{
++	 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
++	{
++	 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
++	{
++	 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
++	{
++	 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
++	{
++	 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
++	{
++	 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
++	{
++	 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
++	{
++	 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
++	{
++	 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
++	{
++	 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
++	{
++	 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
++	{
++	 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
++	{
++	 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
++	{
++	 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
++	{
++	 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
++	{
++	 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
++	{
++	 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
++	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
++	 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
++	{
++	 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
++	 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
++	{
++	 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
++	{
++	 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
++	{
++	 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
++	 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
++	{
++	 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
++	 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
++	{
++	 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
++	 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
++	{
++	 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
++	 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
++	{
++	 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
++	 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
++	{
++	 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
++	 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
++	{
++	 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
++	 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
++	{
++	 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
++	 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
++	{
++	 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
++	 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
++	{
++	 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
++	 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
++	{
++	 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
++	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
++	 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
++	 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
++	 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
++	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
++	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
++	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
++	 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
++	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
++	 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
++	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
++	 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
++	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
++	 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
++	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
++	 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
++	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
++	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
++	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
++	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
++	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
++	 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
++	 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
++	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
++	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
++	 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
++	 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
++	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
++	 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = {
++	{
++	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
++	{
++	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
++	{
++	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
++	{
++	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
++	{
++	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
++	{
++	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
++	{
++	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
++	{
++	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
++	{
++	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
++	{
++	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
++	{
++	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
++	{
++	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
++	{
++	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
++	{
++	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
++	{
++	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
++	{
++	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
++	{
++	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
++	{
++	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
++	{
++	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
++	{
++	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
++	{
++	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
++	{
++	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
++	{
++	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
++	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
++	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
++	{
++	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
++	{
++	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
++	{
++	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
++	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
++	{
++	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
++	{
++	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
++	{
++	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
++	{
++	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
++	{
++	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
++	{
++	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
++	{
++	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
++	{
++	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
++	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
++	{
++	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
++	{
++	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
++	{
++	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
++	{
++	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
++	{
++	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
++	{
++	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
++	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
++	{
++	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
++	{
++	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
++	{
++	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
++	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
++	{
++	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
++	{
++	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
++	{
++	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
++	{
++	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
++	{
++	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
++	{
++	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
++	{
++	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
++	{
++	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
++	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
++	{
++	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
++	{
++	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
++	{
++	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
++	{
++	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
++	{
++	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
++	{
++	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
++	{
++	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
++	{
++	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
++	{
++	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
++	{
++	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
++	{
++	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
++	{
++	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
++	{
++	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
++	{
++	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
++	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
++	{
++	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
++	{
++	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
++	{
++	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
++	{
++	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
++	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
++	{
++	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
++	{
++	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
++	{
++	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
++	{
++	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
++	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
++	{
++	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
++	{
++	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
++	{
++	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
++	{
++	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
++	{
++	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
++	{
++	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
++	{
++	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
++	{
++	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
++	{
++	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
++	{
++	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
++	{
++	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
++	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
++	{
++	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
++	{
++	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
++	{
++	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
++	{
++	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
++	{
++	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
++	{
++	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
++	{
++	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
++	{
++	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
++	{
++	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
++	{
++	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
++	{
++	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
++	{
++	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
++	{
++	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
++	{
++	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
++	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
++	{
++	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
++	{
++	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
++	{
++	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
++	{
++	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
++	{
++	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
++	{
++	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
++	{
++	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
++	{
++	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
++	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
++	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
++	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
++	{
++	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
++	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
++	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
++	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216,
++	 },
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215,
++	 },
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214,
++	 },
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213,
++	 },
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212,
++	 },
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211,
++	 },
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f,
++	 },
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e,
++	 },
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d,
++	 },
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c,
++	 },
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b,
++	 },
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a,
++	 },
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209,
++	 },
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208,
++	 },
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207,
++	 },
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206,
++	 },
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205,
++	 },
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204,
++	 },
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203,
++	 },
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202,
++	 },
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201,
++	 },
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200,
++	 },
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff,
++	 },
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd,
++	 },
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc,
++	 },
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb,
++	 },
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa,
++	 },
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9,
++	 },
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8,
++	 },
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7,
++	 },
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6,
++	 },
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5,
++	 },
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4,
++	 },
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3,
++	 },
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
++	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2,
++	 },
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1,
++	 },
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0,
++	 },
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0,
++	 },
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef,
++	 },
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee,
++	 },
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
++	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed,
++	 },
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec,
++	 },
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb,
++	 },
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea,
++	 },
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9,
++	 },
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8,
++	 },
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
++	 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7,
++	 },
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6,
++	 },
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5,
++	 },
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5,
++	 },
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4,
++	 },
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3,
++	 },
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2,
++	 },
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1,
++	 },
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0,
++	 },
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df,
++	 },
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de,
++	 },
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd,
++	 },
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd,
++	 },
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc,
++	 },
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db,
++	 },
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da,
++	 },
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9,
++	 },
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8,
++	 },
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7,
++	 },
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7,
++	 },
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
++	 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6,
++	 },
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5,
++	 },
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4,
++	 },
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3,
++	 },
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2,
++	 },
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2,
++	 },
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1,
++	 },
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
++	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0,
++	 },
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf,
++	 },
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce,
++	 },
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce,
++	 },
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd,
++	 },
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc,
++	 },
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb,
++	 },
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca,
++	 },
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9,
++	 },
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9,
++	 },
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8,
++	 },
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8,
++	 },
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7,
++	 },
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6,
++	 },
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6,
++	 },
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5,
++	 },
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4,
++	 },
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4,
++	 },
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3,
++	 },
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2,
++	 },
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2,
++	 },
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1,
++	 },
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0,
++	 },
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf,
++	 },
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf,
++	 },
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be,
++	 },
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
++	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd,
++	 },
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443,
++	 },
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441,
++	 },
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f,
++	 },
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
++	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d,
++	 },
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a,
++	 },
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438,
++	 },
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436,
++	 },
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434,
++	 },
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431,
++	 },
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f,
++	 },
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
++	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d,
++	 },
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b,
++	 },
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
++	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429,
++	 },
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
++	 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev8_2057_rev5[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057_rev5
++chan_info_nphyrev9_2057_rev5v1[] = {
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
++	 0x043a, 0x043f, 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
++	 0x0438, 0x043d, 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
++	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
++	 0x0436, 0x043a, 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
++	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
++	 0x0434, 0x0438, 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
++	 0x0431, 0x0436, 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
++	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
++	 0x042f, 0x0434, 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
++	 0x042d, 0x0431, 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
++	 0x042b, 0x042f, 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
++	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
++	 0x0429, 0x042d, 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
++	 0x0427, 0x042b, 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
++	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
++	 0x0424, 0x0429, 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
++	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
++	 0x0422, 0x0427, 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
++	 0x0420, 0x0424, 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
++	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
++	 0x041b, 0x041f, 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = {
++	{
++	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
++	 0x0215,
++	 0x0216},
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static const struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = {
++	{
++	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
++	 0x0214,
++	 0x0215},
++	{
++	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
++	 0x0213,
++	 0x0214},
++	{
++	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
++	 0x0212,
++	 0x0213},
++	{
++	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
++	 0x0211,
++	 0x0212},
++	{
++	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
++	 0x020f,
++	 0x0211},
++	{
++	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
++	 0x020e,
++	 0x020f},
++	{
++	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
++	 0x020d,
++	 0x020e},
++	{
++	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
++	 0x020c,
++	 0x020d},
++	{
++	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
++	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
++	 0x020b,
++	 0x020c},
++	{
++	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
++	 0x020a,
++	 0x020b},
++	{
++	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
++	 0x0209,
++	 0x020a},
++	{
++	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
++	 0x0208,
++	 0x0209},
++	{
++	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
++	 0x0207,
++	 0x0208},
++	{
++	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
++	 0x0206,
++	 0x0207},
++	{
++	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
++	 0x0205,
++	 0x0206},
++	{
++	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
++	 0x0204,
++	 0x0205},
++	{
++	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
++	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
++	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
++	 0x0203,
++	 0x0204},
++	{
++	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
++	 0x0202,
++	 0x0203},
++	{
++	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
++	 0x0201,
++	 0x0202},
++	{
++	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
++	 0x0200,
++	 0x0201},
++	{
++	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
++	 0x01ff,
++	 0x0200},
++	{
++	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
++	 0x01fe,
++	 0x01ff},
++	{
++	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
++	 0x01fc,
++	 0x01fd},
++	{
++	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
++	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
++	 0x01fb,
++	 0x01fc},
++	{
++	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
++	 0x01fa,
++	 0x01fb},
++	{
++	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
++	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
++	 0x01f9,
++	 0x01fa},
++	{
++	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
++	 0x01f8,
++	 0x01f9},
++	{
++	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
++	 0x01f7,
++	 0x01f8},
++	{
++	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
++	 0x01f6,
++	 0x01f7},
++	{
++	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
++	 0x01f5,
++	 0x01f6},
++	{
++	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
++	 0x01f4,
++	 0x01f5},
++	{
++	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
++	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
++	 0x01f3,
++	 0x01f4},
++	{
++	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
++	 0x01f2,
++	 0x01f3},
++	{
++	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
++	 0x01f1,
++	 0x01f2},
++	{
++	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
++	 0x01f0,
++	 0x01f1},
++	{
++	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
++	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
++	 0x01f0,
++	 0x01f0},
++	{
++	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
++	 0x01ef,
++	 0x01f0},
++	{
++	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
++	 0x01ee,
++	 0x01ef},
++	{
++	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
++	 0x01ed,
++	 0x01ee},
++	{
++	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
++	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
++	 0x01ec,
++	 0x01ed},
++	{
++	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
++	 0x01eb,
++	 0x01ec},
++	{
++	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
++	 0x01ea,
++	 0x01eb},
++	{
++	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
++	 0x01e9,
++	 0x01ea},
++	{
++	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
++	 0x01e8,
++	 0x01e9},
++	{
++	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
++	 0x01e7,
++	 0x01e8},
++	{
++	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
++	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
++	 0x01e6,
++	 0x01e7},
++	{
++	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
++	 0x01e5,
++	 0x01e6},
++	{
++	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
++	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
++	 0x01e5,
++	 0x01e5},
++	{
++	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
++	 0x01e4,
++	 0x01e5},
++	{
++	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
++	 0x01e3,
++	 0x01e4},
++	{
++	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
++	 0x01e2,
++	 0x01e3},
++	{
++	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
++	 0x01e1,
++	 0x01e2},
++	{
++	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
++	 0x01e0,
++	 0x01e1},
++	{
++	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
++	 0x01df,
++	 0x01e0},
++	{
++	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
++	 0x01de,
++	 0x01df},
++	{
++	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
++	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
++	 0x01dd,
++	 0x01de},
++	{
++	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
++	 0x01dd,
++	 0x01dd},
++	{
++	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
++	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
++	 0x01dc,
++	 0x01dd},
++	{
++	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
++	 0x01db,
++	 0x01dc},
++	{
++	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
++	 0x01da,
++	 0x01db},
++	{
++	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
++	 0x01d9,
++	 0x01da},
++	{
++	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
++	 0x01d8,
++	 0x01d9},
++	{
++	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
++	 0x01d7,
++	 0x01d8},
++	{
++	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
++	 0x01d7,
++	 0x01d7},
++	{
++	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
++	 0x01d6,
++	 0x01d7},
++	{
++	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
++	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
++	 0x01d5,
++	 0x01d6},
++	{
++	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
++	 0x01d4,
++	 0x01d5},
++	{
++	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
++	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
++	 0x01d3,
++	 0x01d4},
++	{
++	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
++	 0x01d2,
++	 0x01d3},
++	{
++	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
++	 0x01d2,
++	 0x01d2},
++	{
++	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
++	 0x01d1,
++	 0x01d2},
++	{
++	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
++	 0x01d0,
++	 0x01d1},
++	{
++	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
++	 0x01cf,
++	 0x01d0},
++	{
++	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
++	 0x01ce,
++	 0x01cf},
++	{
++	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
++	 0x01ce,
++	 0x01ce},
++	{
++	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
++	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
++	 0x01cd,
++	 0x01ce},
++	{
++	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
++	 0x01cc,
++	 0x01cd},
++	{
++	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
++	 0x01cb,
++	 0x01cc},
++	{
++	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
++	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
++	 0x01ca,
++	 0x01cb},
++	{
++	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
++	 0x01c9,
++	 0x01ca},
++	{
++	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
++	 0x01c9,
++	 0x01ca},
++	{
++	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
++	 0x01c9,
++	 0x01c9},
++	{
++	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
++	 0x01c8,
++	 0x01c9},
++	{
++	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
++	 0x01c8,
++	 0x01c9},
++	{
++	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
++	 0x01c8,
++	 0x01c8},
++	{
++	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
++	 0x01c7,
++	 0x01c8},
++	{
++	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
++	 0x01c6,
++	 0x01c7},
++	{
++	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
++	 0x01c6,
++	 0x01c7},
++	{
++	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
++	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
++	 0x01c6,
++	 0x01c6},
++	{
++	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
++	 0x01c5,
++	 0x01c6},
++	{
++	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
++	 0x01c4,
++	 0x01c5},
++	{
++	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
++	 0x01c4,
++	 0x01c5},
++	{
++	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
++	 0x01c4,
++	 0x01c4},
++	{
++	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
++	 0x01c3,
++	 0x01c4},
++	{
++	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
++	 0x01c2,
++	 0x01c3},
++	{
++	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
++	 0x01c2,
++	 0x01c3},
++	{
++	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
++	 0x01c2,
++	 0x01c2},
++	{
++	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
++	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
++	 0x01c1,
++	 0x01c2},
++	{
++	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
++	 0x01c0,
++	 0x01c1},
++	{
++	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
++	 0x01bf,
++	 0x01c0},
++	{
++	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
++	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
++	 0x01bf,
++	 0x01bf},
++	{
++	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
++	 0x01be,
++	 0x01bf},
++	{
++	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
++	 0x01bd,
++	 0x01be},
++	{
++	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
++	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
++	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
++	 0x01bc,
++	 0x01bd},
++	{
++	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
++	 0x043f,
++	 0x0443},
++	{
++	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
++	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
++	 0x043d,
++	 0x0441},
++	{
++	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
++	 0x043a,
++	 0x043f},
++	{
++	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
++	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
++	 0x0438,
++	 0x043d},
++	{
++	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
++	 0x0436,
++	 0x043a},
++	{
++	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
++	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
++	 0x0434,
++	 0x0438},
++	{
++	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
++	 0x0431,
++	 0x0436},
++	{
++	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
++	 0x042f,
++	 0x0434},
++	{
++	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
++	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
++	 0x042d,
++	 0x0431},
++	{
++	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
++	 0x042b,
++	 0x042f},
++	{
++	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
++	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
++	 0x0429,
++	 0x042d},
++	{
++	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
++	 0x0427,
++	 0x042b},
++	{
++	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
++	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
++	 0x0424,
++	 0x0429},
++	{
++	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
++	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
++	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
++	 0x041f,
++	 0x0424}
++};
++
++static struct radio_regs regs_2055[] = {
++	{0x02, 0x80, 0x80, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0x27, 0x27, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0x27, 0x27, 0, 0},
++	{0x07, 0x7f, 0x7f, 1, 1},
++	{0x08, 0x7, 0x7, 1, 1},
++	{0x09, 0x7f, 0x7f, 1, 1},
++	{0x0A, 0x7, 0x7, 1, 1},
++	{0x0B, 0x15, 0x15, 0, 0},
++	{0x0C, 0x15, 0x15, 0, 0},
++	{0x0D, 0x4f, 0x4f, 1, 1},
++	{0x0E, 0x5, 0x5, 1, 1},
++	{0x0F, 0x4f, 0x4f, 1, 1},
++	{0x10, 0x5, 0x5, 1, 1},
++	{0x11, 0xd0, 0xd0, 0, 0},
++	{0x12, 0x2, 0x2, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0x40, 0x40, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0xc0, 0xc0, 0, 0},
++	{0x1E, 0xff, 0xff, 0, 0},
++	{0x1F, 0xc0, 0xc0, 0, 0},
++	{0x20, 0xff, 0xff, 0, 0},
++	{0x21, 0xc0, 0xc0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x2c, 0x2c, 0, 0},
++	{0x24, 0, 0, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0xa4, 0xa4, 0, 0},
++	{0x2E, 0x38, 0x38, 0, 0},
++	{0x2F, 0, 0, 0, 0},
++	{0x30, 0x4, 0x4, 1, 1},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0xa, 0xa, 0, 0},
++	{0x33, 0x87, 0x87, 0, 0},
++	{0x34, 0x9, 0x9, 0, 0},
++	{0x35, 0x70, 0x70, 0, 0},
++	{0x36, 0x11, 0x11, 0, 0},
++	{0x37, 0x18, 0x18, 1, 1},
++	{0x38, 0x6, 0x6, 0, 0},
++	{0x39, 0x4, 0x4, 1, 1},
++	{0x3A, 0x6, 0x6, 0, 0},
++	{0x3B, 0x9e, 0x9e, 0, 0},
++	{0x3C, 0x9, 0x9, 0, 0},
++	{0x3D, 0xc8, 0xc8, 1, 1},
++	{0x3E, 0x88, 0x88, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0, 0, 0, 0},
++	{0x42, 0x1, 0x1, 0, 0},
++	{0x43, 0x2, 0x2, 0, 0},
++	{0x44, 0x96, 0x96, 0, 0},
++	{0x45, 0x3e, 0x3e, 0, 0},
++	{0x46, 0x3e, 0x3e, 0, 0},
++	{0x47, 0x13, 0x13, 0, 0},
++	{0x48, 0x2, 0x2, 0, 0},
++	{0x49, 0x15, 0x15, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0, 0, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0, 0, 0, 0},
++	{0x50, 0x8, 0x8, 0, 0},
++	{0x51, 0x8, 0x8, 0, 0},
++	{0x52, 0x6, 0x6, 0, 0},
++	{0x53, 0x84, 0x84, 1, 1},
++	{0x54, 0xc3, 0xc3, 0, 0},
++	{0x55, 0x8f, 0x8f, 0, 0},
++	{0x56, 0xff, 0xff, 0, 0},
++	{0x57, 0xff, 0xff, 0, 0},
++	{0x58, 0x88, 0x88, 0, 0},
++	{0x59, 0x88, 0x88, 0, 0},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0xcc, 0xcc, 0, 0},
++	{0x5C, 0x6, 0x6, 0, 0},
++	{0x5D, 0x80, 0x80, 0, 0},
++	{0x5E, 0x80, 0x80, 0, 0},
++	{0x5F, 0xf8, 0xf8, 0, 0},
++	{0x60, 0x88, 0x88, 0, 0},
++	{0x61, 0x88, 0x88, 0, 0},
++	{0x62, 0x88, 0x8, 1, 1},
++	{0x63, 0x88, 0x88, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0x1, 0x1, 1, 1},
++	{0x66, 0x8a, 0x8a, 0, 0},
++	{0x67, 0x8, 0x8, 0, 0},
++	{0x68, 0x83, 0x83, 0, 0},
++	{0x69, 0x6, 0x6, 0, 0},
++	{0x6A, 0xa0, 0xa0, 0, 0},
++	{0x6B, 0xa, 0xa, 0, 0},
++	{0x6C, 0x87, 0x87, 1, 1},
++	{0x6D, 0x2a, 0x2a, 0, 0},
++	{0x6E, 0x2a, 0x2a, 0, 0},
++	{0x6F, 0x2a, 0x2a, 0, 0},
++	{0x70, 0x2a, 0x2a, 0, 0},
++	{0x71, 0x18, 0x18, 0, 0},
++	{0x72, 0x6a, 0x6a, 1, 1},
++	{0x73, 0xab, 0xab, 1, 1},
++	{0x74, 0x13, 0x13, 1, 1},
++	{0x75, 0xc1, 0xc1, 1, 1},
++	{0x76, 0xaa, 0xaa, 1, 1},
++	{0x77, 0x87, 0x87, 1, 1},
++	{0x78, 0, 0, 0, 0},
++	{0x79, 0x6, 0x6, 0, 0},
++	{0x7A, 0x7, 0x7, 0, 0},
++	{0x7B, 0x7, 0x7, 0, 0},
++	{0x7C, 0x15, 0x15, 0, 0},
++	{0x7D, 0x55, 0x55, 0, 0},
++	{0x7E, 0x97, 0x97, 1, 1},
++	{0x7F, 0x8, 0x8, 0, 0},
++	{0x80, 0x14, 0x14, 1, 1},
++	{0x81, 0x33, 0x33, 0, 0},
++	{0x82, 0x88, 0x88, 0, 0},
++	{0x83, 0x6, 0x6, 0, 0},
++	{0x84, 0x3, 0x3, 1, 1},
++	{0x85, 0xa, 0xa, 0, 0},
++	{0x86, 0x3, 0x3, 1, 1},
++	{0x87, 0x2a, 0x2a, 0, 0},
++	{0x88, 0xa4, 0xa4, 0, 0},
++	{0x89, 0x18, 0x18, 0, 0},
++	{0x8A, 0x28, 0x28, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0x4a, 0x4a, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0xf8, 0xf8, 0, 0},
++	{0x8F, 0x88, 0x88, 0, 0},
++	{0x90, 0x88, 0x88, 0, 0},
++	{0x91, 0x88, 0x8, 1, 1},
++	{0x92, 0x88, 0x88, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0x1, 0x1, 1, 1},
++	{0x95, 0x8a, 0x8a, 0, 0},
++	{0x96, 0x8, 0x8, 0, 0},
++	{0x97, 0x83, 0x83, 0, 0},
++	{0x98, 0x6, 0x6, 0, 0},
++	{0x99, 0xa0, 0xa0, 0, 0},
++	{0x9A, 0xa, 0xa, 0, 0},
++	{0x9B, 0x87, 0x87, 1, 1},
++	{0x9C, 0x2a, 0x2a, 0, 0},
++	{0x9D, 0x2a, 0x2a, 0, 0},
++	{0x9E, 0x2a, 0x2a, 0, 0},
++	{0x9F, 0x2a, 0x2a, 0, 0},
++	{0xA0, 0x18, 0x18, 0, 0},
++	{0xA1, 0x6a, 0x6a, 1, 1},
++	{0xA2, 0xab, 0xab, 1, 1},
++	{0xA3, 0x13, 0x13, 1, 1},
++	{0xA4, 0xc1, 0xc1, 1, 1},
++	{0xA5, 0xaa, 0xaa, 1, 1},
++	{0xA6, 0x87, 0x87, 1, 1},
++	{0xA7, 0, 0, 0, 0},
++	{0xA8, 0x6, 0x6, 0, 0},
++	{0xA9, 0x7, 0x7, 0, 0},
++	{0xAA, 0x7, 0x7, 0, 0},
++	{0xAB, 0x15, 0x15, 0, 0},
++	{0xAC, 0x55, 0x55, 0, 0},
++	{0xAD, 0x97, 0x97, 1, 1},
++	{0xAE, 0x8, 0x8, 0, 0},
++	{0xAF, 0x14, 0x14, 1, 1},
++	{0xB0, 0x33, 0x33, 0, 0},
++	{0xB1, 0x88, 0x88, 0, 0},
++	{0xB2, 0x6, 0x6, 0, 0},
++	{0xB3, 0x3, 0x3, 1, 1},
++	{0xB4, 0xa, 0xa, 0, 0},
++	{0xB5, 0x3, 0x3, 1, 1},
++	{0xB6, 0x2a, 0x2a, 0, 0},
++	{0xB7, 0xa4, 0xa4, 0, 0},
++	{0xB8, 0x18, 0x18, 0, 0},
++	{0xB9, 0x28, 0x28, 0, 0},
++	{0xBA, 0, 0, 0, 0},
++	{0xBB, 0x4a, 0x4a, 0, 0},
++	{0xBC, 0, 0, 0, 0},
++	{0xBD, 0x71, 0x71, 0, 0},
++	{0xBE, 0x72, 0x72, 0, 0},
++	{0xBF, 0x73, 0x73, 0, 0},
++	{0xC0, 0x74, 0x74, 0, 0},
++	{0xC1, 0x75, 0x75, 0, 0},
++	{0xC2, 0x76, 0x76, 0, 0},
++	{0xC3, 0x77, 0x77, 0, 0},
++	{0xC4, 0x78, 0x78, 0, 0},
++	{0xC5, 0x79, 0x79, 0, 0},
++	{0xC6, 0x7a, 0x7a, 0, 0},
++	{0xC7, 0, 0, 0, 0},
++	{0xC8, 0, 0, 0, 0},
++	{0xC9, 0, 0, 0, 0},
++	{0xCA, 0, 0, 0, 0},
++	{0xCB, 0, 0, 0, 0},
++	{0xCC, 0, 0, 0, 0},
++	{0xCD, 0, 0, 0, 0},
++	{0xCE, 0x6, 0x6, 0, 0},
++	{0xCF, 0, 0, 0, 0},
++	{0xD0, 0, 0, 0, 0},
++	{0xD1, 0x18, 0x18, 0, 0},
++	{0xD2, 0x88, 0x88, 0, 0},
++	{0xD3, 0, 0, 0, 0},
++	{0xD4, 0, 0, 0, 0},
++	{0xD5, 0, 0, 0, 0},
++	{0xD6, 0, 0, 0, 0},
++	{0xD7, 0, 0, 0, 0},
++	{0xD8, 0, 0, 0, 0},
++	{0xD9, 0, 0, 0, 0},
++	{0xDA, 0x6, 0x6, 0, 0},
++	{0xDB, 0, 0, 0, 0},
++	{0xDC, 0, 0, 0, 0},
++	{0xDD, 0x18, 0x18, 0, 0},
++	{0xDE, 0x88, 0x88, 0, 0},
++	{0xDF, 0, 0, 0, 0},
++	{0xE0, 0, 0, 0, 0},
++	{0xE1, 0, 0, 0, 0},
++	{0xE2, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x74, 0x74, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x99, 0x99, 0, 0},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x99, 0x99, 0, 0},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x66, 0x66, 0, 0},
++	{0x50, 0x66, 0x66, 0, 0},
++	{0x51, 0x57, 0x57, 0, 0},
++	{0x52, 0x57, 0x57, 0, 0},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x23, 0x23, 0, 0},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0x2, 0x2, 0, 0},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0xd, 0xd, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0x72, 0x72, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_A1[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x44, 0x44, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0xf, 0xf, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0x50, 0x50, 1, 1},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x2f, 0x2f, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0x11, 0x11, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0xf, 0xf, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x2d, 0x2d, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev5[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_TX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_RX_2056_rev6[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0}
++};
++
++static struct radio_regs regs_SYN_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x71, 0x71, 1, 1},
++	{0x96, 0x71, 0x71, 1, 1},
++	{0x97, 0x72, 0x72, 1, 1},
++	{0x98, 0x73, 0x73, 1, 1},
++	{0x99, 0x74, 0x74, 1, 1},
++	{0x9A, 0x75, 0x75, 1, 1},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev7[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 1, 1},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0, 0, 1, 1},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_SYN_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x4, 0x4, 0, 0},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x30, 0x30, 0, 0},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0xd, 0xd, 0, 0},
++	{0x4C, 0xd, 0xd, 0, 0},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x6, 0x6, 0, 0},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_TX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_regs regs_RX_2056_rev8[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_SYN_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0x1, 0x1, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0x60, 0x60, 0, 0},
++	{0x23, 0x6, 0x6, 0, 0},
++	{0x24, 0xc, 0xc, 0, 0},
++	{0x25, 0, 0, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0, 0, 0, 0},
++	{0x28, 0x1, 0x1, 0, 0},
++	{0x29, 0, 0, 0, 0},
++	{0x2A, 0, 0, 0, 0},
++	{0x2B, 0, 0, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0, 0, 0, 0},
++	{0x2F, 0x1f, 0x1f, 0, 0},
++	{0x30, 0x15, 0x15, 0, 0},
++	{0x31, 0xf, 0xf, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0, 0, 0, 0},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0, 0, 0, 0},
++	{0x38, 0, 0, 0, 0},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0, 0, 0, 0},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x13, 0x13, 0, 0},
++	{0x3D, 0xf, 0xf, 0, 0},
++	{0x3E, 0x18, 0x18, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x20, 0x20, 0, 0},
++	{0x42, 0x20, 0x20, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x77, 0x77, 0, 0},
++	{0x45, 0x7, 0x7, 0, 0},
++	{0x46, 0x1, 0x1, 0, 0},
++	{0x47, 0x6, 0x6, 1, 1},
++	{0x48, 0xf, 0xf, 0, 0},
++	{0x49, 0x3f, 0x3f, 1, 1},
++	{0x4A, 0x32, 0x32, 0, 0},
++	{0x4B, 0x6, 0x6, 1, 1},
++	{0x4C, 0x6, 0x6, 1, 1},
++	{0x4D, 0x4, 0x4, 0, 0},
++	{0x4E, 0x2b, 0x2b, 1, 1},
++	{0x4F, 0x1, 0x1, 0, 0},
++	{0x50, 0x1c, 0x1c, 0, 0},
++	{0x51, 0x2, 0x2, 0, 0},
++	{0x52, 0x2, 0x2, 0, 0},
++	{0x53, 0xf7, 0xf7, 1, 1},
++	{0x54, 0xb4, 0xb4, 0, 0},
++	{0x55, 0xd2, 0xd2, 0, 0},
++	{0x56, 0, 0, 0, 0},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x4, 0x4, 0, 0},
++	{0x59, 0x96, 0x96, 0, 0},
++	{0x5A, 0x3e, 0x3e, 0, 0},
++	{0x5B, 0x3e, 0x3e, 0, 0},
++	{0x5C, 0x13, 0x13, 0, 0},
++	{0x5D, 0x2, 0x2, 0, 0},
++	{0x5E, 0, 0, 0, 0},
++	{0x5F, 0x7, 0x7, 0, 0},
++	{0x60, 0x7, 0x7, 1, 1},
++	{0x61, 0x8, 0x8, 0, 0},
++	{0x62, 0x3, 0x3, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0x40, 0x40, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0x1, 0x1, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0x60, 0x60, 0, 0},
++	{0x71, 0x66, 0x66, 0, 0},
++	{0x72, 0xc, 0xc, 0, 0},
++	{0x73, 0x66, 0x66, 0, 0},
++	{0x74, 0x8f, 0x8f, 1, 1},
++	{0x75, 0, 0, 0, 0},
++	{0x76, 0xcc, 0xcc, 0, 0},
++	{0x77, 0x1, 0x1, 0, 0},
++	{0x78, 0x66, 0x66, 0, 0},
++	{0x79, 0x66, 0x66, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0, 0, 0, 0},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0xff, 0xff, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0x95, 0, 0, 0, 0},
++	{0x96, 0, 0, 0, 0},
++	{0x97, 0, 0, 0, 0},
++	{0x98, 0, 0, 0, 0},
++	{0x99, 0, 0, 0, 0},
++	{0x9A, 0, 0, 0, 0},
++	{0x9B, 0, 0, 0, 0},
++	{0x9C, 0, 0, 0, 0},
++	{0x9D, 0, 0, 0, 0},
++	{0x9E, 0, 0, 0, 0},
++	{0x9F, 0x6, 0x6, 0, 0},
++	{0xA0, 0x66, 0x66, 0, 0},
++	{0xA1, 0x66, 0x66, 0, 0},
++	{0xA2, 0x66, 0x66, 0, 0},
++	{0xA3, 0x66, 0x66, 0, 0},
++	{0xA4, 0x66, 0x66, 0, 0},
++	{0xA5, 0x66, 0x66, 0, 0},
++	{0xA6, 0x66, 0x66, 0, 0},
++	{0xA7, 0x66, 0x66, 0, 0},
++	{0xA8, 0x66, 0x66, 0, 0},
++	{0xA9, 0x66, 0x66, 0, 0},
++	{0xAA, 0x66, 0x66, 0, 0},
++	{0xAB, 0x66, 0x66, 0, 0},
++	{0xAC, 0x66, 0x66, 0, 0},
++	{0xAD, 0x66, 0x66, 0, 0},
++	{0xAE, 0x66, 0x66, 0, 0},
++	{0xAF, 0x66, 0x66, 0, 0},
++	{0xB0, 0x66, 0x66, 0, 0},
++	{0xB1, 0x66, 0x66, 0, 0},
++	{0xB2, 0x66, 0x66, 0, 0},
++	{0xB3, 0xa, 0xa, 0, 0},
++	{0xB4, 0, 0, 0, 0},
++	{0xB5, 0, 0, 0, 0},
++	{0xB6, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_TX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0, 0, 0, 0},
++	{0x21, 0x88, 0x88, 0, 0},
++	{0x22, 0x88, 0x88, 0, 0},
++	{0x23, 0x88, 0x88, 0, 0},
++	{0x24, 0x88, 0x88, 0, 0},
++	{0x25, 0xc, 0xc, 0, 0},
++	{0x26, 0, 0, 0, 0},
++	{0x27, 0x3, 0x3, 0, 0},
++	{0x28, 0, 0, 0, 0},
++	{0x29, 0x3, 0x3, 0, 0},
++	{0x2A, 0x37, 0x37, 0, 0},
++	{0x2B, 0x3, 0x3, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0, 0, 0, 0},
++	{0x2E, 0x1, 0x1, 0, 0},
++	{0x2F, 0x1, 0x1, 0, 0},
++	{0x30, 0, 0, 0, 0},
++	{0x31, 0, 0, 0, 0},
++	{0x32, 0, 0, 0, 0},
++	{0x33, 0x11, 0x11, 0, 0},
++	{0x34, 0xee, 0xee, 1, 1},
++	{0x35, 0, 0, 0, 0},
++	{0x36, 0, 0, 0, 0},
++	{0x37, 0x3, 0x3, 0, 0},
++	{0x38, 0x50, 0x50, 1, 1},
++	{0x39, 0, 0, 0, 0},
++	{0x3A, 0x50, 0x50, 1, 1},
++	{0x3B, 0, 0, 0, 0},
++	{0x3C, 0x6e, 0x6e, 0, 0},
++	{0x3D, 0xf0, 0xf0, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0, 0, 0, 0},
++	{0x40, 0, 0, 0, 0},
++	{0x41, 0x3, 0x3, 0, 0},
++	{0x42, 0x3, 0x3, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x1e, 0x1e, 0, 0},
++	{0x45, 0, 0, 0, 0},
++	{0x46, 0x6e, 0x6e, 0, 0},
++	{0x47, 0xf0, 0xf0, 1, 1},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x2, 0x2, 0, 0},
++	{0x4A, 0xff, 0xff, 1, 1},
++	{0x4B, 0xc, 0xc, 0, 0},
++	{0x4C, 0, 0, 0, 0},
++	{0x4D, 0x38, 0x38, 0, 0},
++	{0x4E, 0x70, 0x70, 1, 1},
++	{0x4F, 0x2, 0x2, 0, 0},
++	{0x50, 0x88, 0x88, 0, 0},
++	{0x51, 0xc, 0xc, 0, 0},
++	{0x52, 0, 0, 0, 0},
++	{0x53, 0x8, 0x8, 0, 0},
++	{0x54, 0x70, 0x70, 1, 1},
++	{0x55, 0x2, 0x2, 0, 0},
++	{0x56, 0xff, 0xff, 1, 1},
++	{0x57, 0, 0, 0, 0},
++	{0x58, 0x83, 0x83, 0, 0},
++	{0x59, 0x77, 0x77, 1, 1},
++	{0x5A, 0, 0, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x88, 0x88, 0, 0},
++	{0x5D, 0, 0, 0, 0},
++	{0x5E, 0x8, 0x8, 0, 0},
++	{0x5F, 0x77, 0x77, 1, 1},
++	{0x60, 0x1, 0x1, 0, 0},
++	{0x61, 0, 0, 0, 0},
++	{0x62, 0x7, 0x7, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0x7, 0x7, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 1, 1},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0xa, 0xa, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0, 0, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0x2, 0x2, 0, 0},
++	{0x72, 0, 0, 0, 0},
++	{0x73, 0, 0, 0, 0},
++	{0x74, 0xe, 0xe, 0, 0},
++	{0x75, 0xe, 0xe, 0, 0},
++	{0x76, 0xe, 0xe, 0, 0},
++	{0x77, 0x13, 0x13, 0, 0},
++	{0x78, 0x13, 0x13, 0, 0},
++	{0x79, 0x1b, 0x1b, 0, 0},
++	{0x7A, 0x1b, 0x1b, 0, 0},
++	{0x7B, 0x55, 0x55, 0, 0},
++	{0x7C, 0x5b, 0x5b, 0, 0},
++	{0x7D, 0x30, 0x30, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0x70, 0x70, 0, 0},
++	{0x94, 0x70, 0x70, 0, 0},
++	{0x95, 0x70, 0x70, 0, 0},
++	{0x96, 0x70, 0x70, 0, 0},
++	{0x97, 0x70, 0x70, 0, 0},
++	{0x98, 0x70, 0x70, 0, 0},
++	{0x99, 0x70, 0x70, 0, 0},
++	{0x9A, 0x70, 0x70, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static const struct radio_regs regs_RX_2056_rev11[] = {
++	{0x02, 0, 0, 0, 0},
++	{0x03, 0, 0, 0, 0},
++	{0x04, 0, 0, 0, 0},
++	{0x05, 0, 0, 0, 0},
++	{0x06, 0, 0, 0, 0},
++	{0x07, 0, 0, 0, 0},
++	{0x08, 0, 0, 0, 0},
++	{0x09, 0, 0, 0, 0},
++	{0x0A, 0, 0, 0, 0},
++	{0x0B, 0, 0, 0, 0},
++	{0x0C, 0, 0, 0, 0},
++	{0x0D, 0, 0, 0, 0},
++	{0x0E, 0, 0, 0, 0},
++	{0x0F, 0, 0, 0, 0},
++	{0x10, 0, 0, 0, 0},
++	{0x11, 0, 0, 0, 0},
++	{0x12, 0, 0, 0, 0},
++	{0x13, 0, 0, 0, 0},
++	{0x14, 0, 0, 0, 0},
++	{0x15, 0, 0, 0, 0},
++	{0x16, 0, 0, 0, 0},
++	{0x17, 0, 0, 0, 0},
++	{0x18, 0, 0, 0, 0},
++	{0x19, 0, 0, 0, 0},
++	{0x1A, 0, 0, 0, 0},
++	{0x1B, 0, 0, 0, 0},
++	{0x1C, 0, 0, 0, 0},
++	{0x1D, 0, 0, 0, 0},
++	{0x1E, 0, 0, 0, 0},
++	{0x1F, 0, 0, 0, 0},
++	{0x20, 0x3, 0x3, 0, 0},
++	{0x21, 0, 0, 0, 0},
++	{0x22, 0, 0, 0, 0},
++	{0x23, 0x90, 0x90, 0, 0},
++	{0x24, 0x55, 0x55, 0, 0},
++	{0x25, 0x15, 0x15, 0, 0},
++	{0x26, 0x5, 0x5, 0, 0},
++	{0x27, 0x15, 0x15, 0, 0},
++	{0x28, 0x5, 0x5, 0, 0},
++	{0x29, 0x20, 0x20, 0, 0},
++	{0x2A, 0x11, 0x11, 0, 0},
++	{0x2B, 0x90, 0x90, 0, 0},
++	{0x2C, 0, 0, 0, 0},
++	{0x2D, 0x88, 0x88, 0, 0},
++	{0x2E, 0x32, 0x32, 0, 0},
++	{0x2F, 0x77, 0x77, 0, 0},
++	{0x30, 0x17, 0x17, 1, 1},
++	{0x31, 0xff, 0xff, 1, 1},
++	{0x32, 0x20, 0x20, 0, 0},
++	{0x33, 0, 0, 0, 0},
++	{0x34, 0x88, 0x88, 0, 0},
++	{0x35, 0x32, 0x32, 0, 0},
++	{0x36, 0x77, 0x77, 0, 0},
++	{0x37, 0x17, 0x17, 1, 1},
++	{0x38, 0xf0, 0xf0, 1, 1},
++	{0x39, 0x20, 0x20, 0, 0},
++	{0x3A, 0x8, 0x8, 0, 0},
++	{0x3B, 0x55, 0x55, 1, 1},
++	{0x3C, 0, 0, 0, 0},
++	{0x3D, 0x88, 0x88, 1, 1},
++	{0x3E, 0, 0, 0, 0},
++	{0x3F, 0x44, 0x44, 0, 0},
++	{0x40, 0x7, 0x7, 1, 1},
++	{0x41, 0x6, 0x6, 0, 0},
++	{0x42, 0x4, 0x4, 0, 0},
++	{0x43, 0, 0, 0, 0},
++	{0x44, 0x8, 0x8, 0, 0},
++	{0x45, 0x55, 0x55, 1, 1},
++	{0x46, 0, 0, 0, 0},
++	{0x47, 0x11, 0x11, 0, 0},
++	{0x48, 0, 0, 0, 0},
++	{0x49, 0x44, 0x44, 0, 0},
++	{0x4A, 0x7, 0x7, 0, 0},
++	{0x4B, 0x6, 0x6, 0, 0},
++	{0x4C, 0x4, 0x4, 0, 0},
++	{0x4D, 0, 0, 0, 0},
++	{0x4E, 0, 0, 0, 0},
++	{0x4F, 0x26, 0x26, 1, 1},
++	{0x50, 0x26, 0x26, 1, 1},
++	{0x51, 0xf, 0xf, 1, 1},
++	{0x52, 0xf, 0xf, 1, 1},
++	{0x53, 0x44, 0x44, 0, 0},
++	{0x54, 0, 0, 0, 0},
++	{0x55, 0, 0, 0, 0},
++	{0x56, 0x8, 0x8, 0, 0},
++	{0x57, 0x8, 0x8, 0, 0},
++	{0x58, 0x7, 0x7, 0, 0},
++	{0x59, 0x22, 0x22, 0, 0},
++	{0x5A, 0x22, 0x22, 0, 0},
++	{0x5B, 0x2, 0x2, 0, 0},
++	{0x5C, 0x4, 0x4, 1, 1},
++	{0x5D, 0x7, 0x7, 0, 0},
++	{0x5E, 0x55, 0x55, 0, 0},
++	{0x5F, 0x23, 0x23, 0, 0},
++	{0x60, 0x41, 0x41, 0, 0},
++	{0x61, 0x1, 0x1, 0, 0},
++	{0x62, 0xa, 0xa, 0, 0},
++	{0x63, 0, 0, 0, 0},
++	{0x64, 0, 0, 0, 0},
++	{0x65, 0, 0, 0, 0},
++	{0x66, 0, 0, 0, 0},
++	{0x67, 0, 0, 0, 0},
++	{0x68, 0, 0, 0, 0},
++	{0x69, 0, 0, 0, 0},
++	{0x6A, 0, 0, 0, 0},
++	{0x6B, 0xc, 0xc, 0, 0},
++	{0x6C, 0, 0, 0, 0},
++	{0x6D, 0, 0, 0, 0},
++	{0x6E, 0, 0, 0, 0},
++	{0x6F, 0, 0, 0, 0},
++	{0x70, 0, 0, 0, 0},
++	{0x71, 0, 0, 0, 0},
++	{0x72, 0x22, 0x22, 0, 0},
++	{0x73, 0x22, 0x22, 0, 0},
++	{0x74, 0, 0, 1, 1},
++	{0x75, 0xa, 0xa, 0, 0},
++	{0x76, 0x1, 0x1, 0, 0},
++	{0x77, 0x22, 0x22, 0, 0},
++	{0x78, 0x30, 0x30, 0, 0},
++	{0x79, 0, 0, 0, 0},
++	{0x7A, 0, 0, 0, 0},
++	{0x7B, 0, 0, 0, 0},
++	{0x7C, 0, 0, 0, 0},
++	{0x7D, 0x5, 0x5, 1, 1},
++	{0x7E, 0, 0, 0, 0},
++	{0x7F, 0, 0, 0, 0},
++	{0x80, 0, 0, 0, 0},
++	{0x81, 0, 0, 0, 0},
++	{0x82, 0, 0, 0, 0},
++	{0x83, 0, 0, 0, 0},
++	{0x84, 0, 0, 0, 0},
++	{0x85, 0, 0, 0, 0},
++	{0x86, 0, 0, 0, 0},
++	{0x87, 0, 0, 0, 0},
++	{0x88, 0, 0, 0, 0},
++	{0x89, 0, 0, 0, 0},
++	{0x8A, 0, 0, 0, 0},
++	{0x8B, 0, 0, 0, 0},
++	{0x8C, 0, 0, 0, 0},
++	{0x8D, 0, 0, 0, 0},
++	{0x8E, 0, 0, 0, 0},
++	{0x8F, 0, 0, 0, 0},
++	{0x90, 0, 0, 0, 0},
++	{0x91, 0, 0, 0, 0},
++	{0x92, 0, 0, 0, 0},
++	{0x93, 0, 0, 0, 0},
++	{0x94, 0, 0, 0, 0},
++	{0xFFFF, 0, 0, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev4[] = {
++	{0x00, 0x84, 0},
++	{0x01, 0, 0},
++	{0x02, 0x60, 0},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 1},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0xf7, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x4, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x26, 1},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 1},
++	{0x3D, 0xff, 1},
++	{0x3E, 0xff, 1},
++	{0x3F, 0xff, 1},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x75, 0},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0xa8, 0},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x30, 0},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0x19, 0},
++	{0x64, 0x62, 0},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0xc8, 0},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x1e, 0},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x1e, 0},
++	{0x7C, 0x62, 0},
++	{0x7D, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x9c, 0},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 1},
++	{0x8B, 0x10, 1},
++	{0x8C, 0xf0, 1},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0xe1, 0},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 1},
++	{0xA5, 0x6d, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 1},
++	{0xA9, 0xc, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 1},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x75, 0},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0xa8, 0},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x30, 0},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0x19, 0},
++	{0xE9, 0x62, 0},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0xc8, 0},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x1e, 0},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x1e, 0},
++	{0x101, 0x62, 0},
++	{0x102, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x9c, 0},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 1},
++	{0x110, 0x10, 1},
++	{0x111, 0xf0, 1},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0xe1, 0},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 1},
++	{0x12A, 0x6d, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 1},
++	{0x12E, 0xc, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 1},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x152, 0, 0},
++	{0x153, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0x2, 1},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0xFFFF, 0, 0},
++};
++
++static struct radio_20xx_regs regs_2057_rev5[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev5v1[] = {
++	{0x00, 0x15, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 1},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0xc, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0x1, 1},
++	{0x1C2, 0x80, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev7[] = {
++	{0x00, 0, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0x13, 1},
++	{0x65, 0, 0},
++	{0x66, 0xee, 1},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0x14, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0, 0},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0x13, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0xee, 1},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0x14, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0, 0},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static struct radio_20xx_regs regs_2057_rev8[] = {
++	{0x00, 0x8, 1},
++	{0x01, 0x57, 1},
++	{0x02, 0x20, 1},
++	{0x03, 0x1f, 0},
++	{0x04, 0x4, 0},
++	{0x05, 0x2, 0},
++	{0x06, 0x1, 0},
++	{0x07, 0x1, 0},
++	{0x08, 0x1, 0},
++	{0x09, 0x69, 0},
++	{0x0A, 0x66, 0},
++	{0x0B, 0x6, 0},
++	{0x0C, 0x18, 0},
++	{0x0D, 0x3, 0},
++	{0x0E, 0x20, 0},
++	{0x0F, 0x20, 0},
++	{0x10, 0, 0},
++	{0x11, 0x7c, 0},
++	{0x12, 0x42, 0},
++	{0x13, 0xbd, 0},
++	{0x14, 0x7, 0},
++	{0x15, 0x87, 0},
++	{0x16, 0x8, 0},
++	{0x17, 0x17, 0},
++	{0x18, 0x7, 0},
++	{0x19, 0, 0},
++	{0x1A, 0x2, 0},
++	{0x1B, 0x13, 0},
++	{0x1C, 0x3e, 0},
++	{0x1D, 0x3e, 0},
++	{0x1E, 0x96, 0},
++	{0x1F, 0x4, 0},
++	{0x20, 0, 0},
++	{0x21, 0, 0},
++	{0x22, 0x17, 0},
++	{0x23, 0x6, 0},
++	{0x24, 0x1, 0},
++	{0x25, 0x6, 0},
++	{0x26, 0x4, 0},
++	{0x27, 0xd, 0},
++	{0x28, 0xd, 0},
++	{0x29, 0x30, 0},
++	{0x2A, 0x32, 0},
++	{0x2B, 0x8, 0},
++	{0x2C, 0x1c, 0},
++	{0x2D, 0x2, 0},
++	{0x2E, 0x4, 0},
++	{0x2F, 0x7f, 0},
++	{0x30, 0x27, 0},
++	{0x31, 0, 1},
++	{0x32, 0, 1},
++	{0x33, 0, 1},
++	{0x34, 0, 0},
++	{0x35, 0x20, 0},
++	{0x36, 0x18, 0},
++	{0x37, 0x7, 0},
++	{0x38, 0x66, 0},
++	{0x39, 0x66, 0},
++	{0x3A, 0x66, 0},
++	{0x3B, 0x66, 0},
++	{0x3C, 0xff, 0},
++	{0x3D, 0xff, 0},
++	{0x3E, 0xff, 0},
++	{0x3F, 0xff, 0},
++	{0x40, 0x16, 0},
++	{0x41, 0x7, 0},
++	{0x42, 0x19, 0},
++	{0x43, 0x7, 0},
++	{0x44, 0x6, 0},
++	{0x45, 0x3, 0},
++	{0x46, 0x1, 0},
++	{0x47, 0x7, 0},
++	{0x48, 0x33, 0},
++	{0x49, 0x5, 0},
++	{0x4A, 0x77, 0},
++	{0x4B, 0x66, 0},
++	{0x4C, 0x66, 0},
++	{0x4D, 0, 0},
++	{0x4E, 0x4, 0},
++	{0x4F, 0xc, 0},
++	{0x50, 0, 0},
++	{0x51, 0x70, 1},
++	{0x56, 0x7, 0},
++	{0x57, 0, 0},
++	{0x58, 0, 0},
++	{0x59, 0x88, 1},
++	{0x5A, 0, 0},
++	{0x5B, 0x1f, 0},
++	{0x5C, 0x20, 1},
++	{0x5D, 0x1, 0},
++	{0x5E, 0x30, 0},
++	{0x5F, 0x70, 0},
++	{0x60, 0, 0},
++	{0x61, 0, 0},
++	{0x62, 0x33, 1},
++	{0x63, 0xf, 1},
++	{0x64, 0xf, 1},
++	{0x65, 0, 0},
++	{0x66, 0x11, 0},
++	{0x69, 0, 0},
++	{0x6A, 0x7e, 0},
++	{0x6B, 0x3f, 0},
++	{0x6C, 0x7f, 0},
++	{0x6D, 0x78, 0},
++	{0x6E, 0x58, 1},
++	{0x6F, 0x88, 0},
++	{0x70, 0x8, 0},
++	{0x71, 0xf, 0},
++	{0x72, 0xbc, 0},
++	{0x73, 0x8, 0},
++	{0x74, 0x60, 0},
++	{0x75, 0x13, 1},
++	{0x76, 0x70, 0},
++	{0x77, 0, 0},
++	{0x78, 0, 0},
++	{0x79, 0, 0},
++	{0x7A, 0x33, 0},
++	{0x7B, 0x13, 1},
++	{0x7C, 0xf, 1},
++	{0x7D, 0xee, 1},
++	{0x80, 0x3c, 0},
++	{0x81, 0x1, 1},
++	{0x82, 0xa, 0},
++	{0x83, 0x9d, 0},
++	{0x84, 0xa, 0},
++	{0x85, 0, 0},
++	{0x86, 0x40, 0},
++	{0x87, 0x40, 0},
++	{0x88, 0x88, 0},
++	{0x89, 0x10, 0},
++	{0x8A, 0xf0, 0},
++	{0x8B, 0x10, 0},
++	{0x8C, 0xf0, 0},
++	{0x8D, 0, 0},
++	{0x8E, 0, 0},
++	{0x8F, 0x10, 0},
++	{0x90, 0x55, 0},
++	{0x91, 0x3f, 1},
++	{0x92, 0x36, 1},
++	{0x93, 0, 0},
++	{0x94, 0, 0},
++	{0x95, 0, 0},
++	{0x96, 0x87, 0},
++	{0x97, 0x11, 0},
++	{0x98, 0, 0},
++	{0x99, 0x33, 0},
++	{0x9A, 0x88, 0},
++	{0x9B, 0, 0},
++	{0x9C, 0x87, 0},
++	{0x9D, 0x11, 0},
++	{0x9E, 0, 0},
++	{0x9F, 0x33, 0},
++	{0xA0, 0x88, 0},
++	{0xA1, 0x20, 1},
++	{0xA2, 0x3f, 0},
++	{0xA3, 0x44, 0},
++	{0xA4, 0x8c, 0},
++	{0xA5, 0x6c, 0},
++	{0xA6, 0x22, 0},
++	{0xA7, 0xbe, 0},
++	{0xA8, 0x55, 0},
++	{0xAA, 0xc, 0},
++	{0xAB, 0xaa, 0},
++	{0xAC, 0x2, 0},
++	{0xAD, 0, 0},
++	{0xAE, 0x10, 0},
++	{0xAF, 0x1, 0},
++	{0xB0, 0, 0},
++	{0xB1, 0, 0},
++	{0xB2, 0x80, 0},
++	{0xB3, 0x60, 0},
++	{0xB4, 0x44, 0},
++	{0xB5, 0x55, 0},
++	{0xB6, 0x1, 0},
++	{0xB7, 0x55, 0},
++	{0xB8, 0x1, 0},
++	{0xB9, 0x5, 0},
++	{0xBA, 0x55, 0},
++	{0xBB, 0x55, 0},
++	{0xC1, 0, 0},
++	{0xC2, 0, 0},
++	{0xC3, 0, 0},
++	{0xC4, 0, 0},
++	{0xC5, 0, 0},
++	{0xC6, 0, 0},
++	{0xC7, 0, 0},
++	{0xC8, 0, 0},
++	{0xC9, 0x1, 1},
++	{0xCA, 0, 0},
++	{0xCB, 0, 0},
++	{0xCC, 0, 0},
++	{0xCD, 0, 0},
++	{0xCE, 0x5e, 0},
++	{0xCF, 0xc, 0},
++	{0xD0, 0xc, 0},
++	{0xD1, 0xc, 0},
++	{0xD2, 0, 0},
++	{0xD3, 0x2b, 0},
++	{0xD4, 0xc, 0},
++	{0xD5, 0, 0},
++	{0xD6, 0x70, 1},
++	{0xDB, 0x7, 0},
++	{0xDC, 0, 0},
++	{0xDD, 0, 0},
++	{0xDE, 0x88, 1},
++	{0xDF, 0, 0},
++	{0xE0, 0x1f, 0},
++	{0xE1, 0x20, 1},
++	{0xE2, 0x1, 0},
++	{0xE3, 0x30, 0},
++	{0xE4, 0x70, 0},
++	{0xE5, 0, 0},
++	{0xE6, 0, 0},
++	{0xE7, 0x33, 0},
++	{0xE8, 0xf, 1},
++	{0xE9, 0xf, 1},
++	{0xEA, 0, 0},
++	{0xEB, 0x11, 0},
++	{0xEE, 0, 0},
++	{0xEF, 0x7e, 0},
++	{0xF0, 0x3f, 0},
++	{0xF1, 0x7f, 0},
++	{0xF2, 0x78, 0},
++	{0xF3, 0x58, 1},
++	{0xF4, 0x88, 0},
++	{0xF5, 0x8, 0},
++	{0xF6, 0xf, 0},
++	{0xF7, 0xbc, 0},
++	{0xF8, 0x8, 0},
++	{0xF9, 0x60, 0},
++	{0xFA, 0x13, 1},
++	{0xFB, 0x70, 0},
++	{0xFC, 0, 0},
++	{0xFD, 0, 0},
++	{0xFE, 0, 0},
++	{0xFF, 0x33, 0},
++	{0x100, 0x13, 1},
++	{0x101, 0xf, 1},
++	{0x102, 0xee, 1},
++	{0x105, 0x3c, 0},
++	{0x106, 0x1, 1},
++	{0x107, 0xa, 0},
++	{0x108, 0x9d, 0},
++	{0x109, 0xa, 0},
++	{0x10A, 0, 0},
++	{0x10B, 0x40, 0},
++	{0x10C, 0x40, 0},
++	{0x10D, 0x88, 0},
++	{0x10E, 0x10, 0},
++	{0x10F, 0xf0, 0},
++	{0x110, 0x10, 0},
++	{0x111, 0xf0, 0},
++	{0x112, 0, 0},
++	{0x113, 0, 0},
++	{0x114, 0x10, 0},
++	{0x115, 0x55, 0},
++	{0x116, 0x3f, 1},
++	{0x117, 0x36, 1},
++	{0x118, 0, 0},
++	{0x119, 0, 0},
++	{0x11A, 0, 0},
++	{0x11B, 0x87, 0},
++	{0x11C, 0x11, 0},
++	{0x11D, 0, 0},
++	{0x11E, 0x33, 0},
++	{0x11F, 0x88, 0},
++	{0x120, 0, 0},
++	{0x121, 0x87, 0},
++	{0x122, 0x11, 0},
++	{0x123, 0, 0},
++	{0x124, 0x33, 0},
++	{0x125, 0x88, 0},
++	{0x126, 0x20, 1},
++	{0x127, 0x3f, 0},
++	{0x128, 0x44, 0},
++	{0x129, 0x8c, 0},
++	{0x12A, 0x6c, 0},
++	{0x12B, 0x22, 0},
++	{0x12C, 0xbe, 0},
++	{0x12D, 0x55, 0},
++	{0x12F, 0xc, 0},
++	{0x130, 0xaa, 0},
++	{0x131, 0x2, 0},
++	{0x132, 0, 0},
++	{0x133, 0x10, 0},
++	{0x134, 0x1, 0},
++	{0x135, 0, 0},
++	{0x136, 0, 0},
++	{0x137, 0x80, 0},
++	{0x138, 0x60, 0},
++	{0x139, 0x44, 0},
++	{0x13A, 0x55, 0},
++	{0x13B, 0x1, 0},
++	{0x13C, 0x55, 0},
++	{0x13D, 0x1, 0},
++	{0x13E, 0x5, 0},
++	{0x13F, 0x55, 0},
++	{0x140, 0x55, 0},
++	{0x146, 0, 0},
++	{0x147, 0, 0},
++	{0x148, 0, 0},
++	{0x149, 0, 0},
++	{0x14A, 0, 0},
++	{0x14B, 0, 0},
++	{0x14C, 0, 0},
++	{0x14D, 0, 0},
++	{0x14E, 0x1, 1},
++	{0x14F, 0, 0},
++	{0x150, 0, 0},
++	{0x151, 0, 0},
++	{0x154, 0xc, 0},
++	{0x155, 0xc, 0},
++	{0x156, 0xc, 0},
++	{0x157, 0, 0},
++	{0x158, 0x2b, 0},
++	{0x159, 0x84, 0},
++	{0x15A, 0x15, 0},
++	{0x15B, 0xf, 0},
++	{0x15C, 0, 0},
++	{0x15D, 0, 0},
++	{0x15E, 0, 1},
++	{0x15F, 0, 1},
++	{0x160, 0, 1},
++	{0x161, 0, 1},
++	{0x162, 0, 1},
++	{0x163, 0, 1},
++	{0x164, 0, 0},
++	{0x165, 0, 0},
++	{0x166, 0, 0},
++	{0x167, 0, 0},
++	{0x168, 0, 0},
++	{0x169, 0, 0},
++	{0x16A, 0, 1},
++	{0x16B, 0, 1},
++	{0x16C, 0, 1},
++	{0x16D, 0, 0},
++	{0x170, 0, 0},
++	{0x171, 0x77, 0},
++	{0x172, 0x77, 0},
++	{0x173, 0x77, 0},
++	{0x174, 0x77, 0},
++	{0x175, 0, 0},
++	{0x176, 0x3, 0},
++	{0x177, 0x37, 0},
++	{0x178, 0x3, 0},
++	{0x179, 0, 0},
++	{0x17A, 0x21, 0},
++	{0x17B, 0x21, 0},
++	{0x17C, 0, 0},
++	{0x17D, 0xaa, 0},
++	{0x17E, 0, 0},
++	{0x17F, 0xaa, 0},
++	{0x180, 0, 0},
++	{0x190, 0, 0},
++	{0x191, 0x77, 0},
++	{0x192, 0x77, 0},
++	{0x193, 0x77, 0},
++	{0x194, 0x77, 0},
++	{0x195, 0, 0},
++	{0x196, 0x3, 0},
++	{0x197, 0x37, 0},
++	{0x198, 0x3, 0},
++	{0x199, 0, 0},
++	{0x19A, 0x21, 0},
++	{0x19B, 0x21, 0},
++	{0x19C, 0, 0},
++	{0x19D, 0xaa, 0},
++	{0x19E, 0, 0},
++	{0x19F, 0xaa, 0},
++	{0x1A0, 0, 0},
++	{0x1A1, 0x2, 0},
++	{0x1A2, 0xf, 0},
++	{0x1A3, 0xf, 0},
++	{0x1A4, 0, 1},
++	{0x1A5, 0, 1},
++	{0x1A6, 0, 1},
++	{0x1A7, 0x2, 0},
++	{0x1A8, 0xf, 0},
++	{0x1A9, 0xf, 0},
++	{0x1AA, 0, 1},
++	{0x1AB, 0, 1},
++	{0x1AC, 0, 1},
++	{0x1AD, 0x84, 0},
++	{0x1AE, 0x60, 0},
++	{0x1AF, 0x47, 0},
++	{0x1B0, 0x47, 0},
++	{0x1B1, 0, 0},
++	{0x1B2, 0, 0},
++	{0x1B3, 0, 0},
++	{0x1B4, 0, 0},
++	{0x1B5, 0, 0},
++	{0x1B6, 0, 0},
++	{0x1B7, 0x5, 1},
++	{0x1B8, 0, 0},
++	{0x1B9, 0, 0},
++	{0x1BA, 0, 0},
++	{0x1BB, 0, 0},
++	{0x1BC, 0, 0},
++	{0x1BD, 0, 0},
++	{0x1BE, 0, 0},
++	{0x1BF, 0, 0},
++	{0x1C0, 0, 0},
++	{0x1C1, 0, 0},
++	{0x1C2, 0xa0, 1},
++	{0x1C3, 0, 0},
++	{0x1C4, 0, 0},
++	{0x1C5, 0, 0},
++	{0x1C6, 0, 0},
++	{0x1C7, 0, 0},
++	{0x1C8, 0, 0},
++	{0x1C9, 0, 0},
++	{0x1CA, 0, 0},
++	{0xFFFF, 0, 0}
++};
++
++static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
++
++static s32 nphy_lnagain_est0[] = { -315, 40370 };
++static s32 nphy_lnagain_est1[] = { -224, 23242 };
++
++static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
++	{
++		{0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
++		{0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
++		{0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
++		{0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
++		{0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
++		{0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
++		{0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
++		{0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
++		{0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
++	},
++	{
++		{0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
++		{0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
++		{0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
++		{0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
++		{0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
++	}
++};
++
++static const u32 nphy_tpc_txgain[] = {
++	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
++	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
++	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
++	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
++	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
++	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
++	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
++	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
++	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
++	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
++	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
++	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
++	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
++	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
++	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
++	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
++	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
++	0x03902942, 0x03902844, 0x03902842, 0x03902744,
++	0x03902742, 0x03902644, 0x03902642, 0x03902544,
++	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
++	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
++	0x03802842, 0x03802744, 0x03802742, 0x03802644,
++	0x03802642, 0x03802544, 0x03802542, 0x03802444,
++	0x03802442, 0x03802344, 0x03802342, 0x03802244,
++	0x03802242, 0x03802144, 0x03802142, 0x03802044,
++	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
++	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
++	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
++	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
++	0x03801842, 0x03801744, 0x03801742, 0x03801644,
++	0x03801642, 0x03801544, 0x03801542, 0x03801444,
++	0x03801442, 0x03801344, 0x03801342, 0x00002b00
++};
++
++static const u16 nphy_tpc_loscale[] = {
++	256, 256, 271, 271, 287, 256, 256, 271,
++	271, 287, 287, 304, 304, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 256,
++	256, 271, 271, 287, 287, 304, 304, 322,
++	322, 341, 341, 362, 362, 256, 256, 271,
++	271, 287, 287, 304, 304, 322, 322, 341,
++	341, 362, 362, 383, 383, 406, 406, 430,
++	430, 455, 455, 482, 482, 511, 511, 541,
++	541, 573, 573, 607, 607, 643, 643, 681,
++	681, 722, 722, 764, 764, 810, 810, 858,
++	858, 908, 908, 962, 962, 1019, 1019, 256
++};
++
++static u32 nphy_tpc_txgain_ipa[] = {
++	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
++	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
++	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
++	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
++	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
++	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
++	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
++	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
++	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
++	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
++	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
++	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
++	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
++	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
++	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
++	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
++	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
++	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
++	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
++	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
++	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
++	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
++	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
++	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
++	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
++	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
++	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
++	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
++	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
++	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
++	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
++	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev5[] = {
++	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
++	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
++	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
++	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
++	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
++	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
++	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
++	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
++	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
++	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
++	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
++	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
++	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
++	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
++	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
++	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
++	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
++	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
++	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
++	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
++	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
++	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
++	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
++	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
++	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
++	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
++	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
++	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
++	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
++	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
++	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
++	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_rev6[] = {
++	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
++	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
++	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
++	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
++	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
++	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
++	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
++	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
++	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
++	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
++	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
++	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
++	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
++	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
++	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
++	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
++	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
++	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
++	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
++	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
++	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
++	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
++	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
++	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
++	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
++	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
++	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
++	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
++	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
++	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
++	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
++	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
++	0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
++	0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
++	0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
++	0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
++	0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
++	0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
++	0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
++	0x70470028, 0x70470026, 0x70470024, 0x70470022,
++	0x7047001f, 0x70370027, 0x70370024, 0x70370022,
++	0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
++	0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
++	0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
++	0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
++	0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
++	0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
++	0x70170019, 0x70170018, 0x70170016, 0x70170015,
++	0x70170014, 0x70170013, 0x70170012, 0x70170010,
++	0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
++	0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
++	0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
++	0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
++	0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
++	0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
++	0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
++	0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
++	0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
++	0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
++	0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
++	0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
++	0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
++	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
++	0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
++	0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
++	0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
++	0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
++	0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
++	0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
++	0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
++	0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
++	0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
++	0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
++	0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
++	0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
++	0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
++	0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
++	0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
++	0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
++	0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
++	0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
++	0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
++	0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
++	0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
++	0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
++	0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
++	0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
++	0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
++	0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
++	0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
++	0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
++	0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
++	0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
++	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
++	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
++	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
++	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
++	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
++	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
++	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
++	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
++	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
++	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
++	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
++	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
++	0x30170028, 0x30170026, 0x30170024, 0x30170022,
++	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
++	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
++	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
++	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
++	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
++	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
++	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
++	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
++};
++
++static u32 nphy_tpc_txgain_ipa_5g[] = {
++	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
++	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
++	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
++	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
++	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
++	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
++	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
++	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
++	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
++	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
++	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
++	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
++	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
++	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
++	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
++	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
++	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
++	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
++	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
++	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
++	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
++	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
++	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
++	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
++	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
++	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
++	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
++	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
++	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
++	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
++	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
++	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
++	0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
++	0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
++	0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
++	0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
++	0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
++	0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
++	0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
++	0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
++	0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
++	0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
++	0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
++	0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
++	0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
++	0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
++	0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
++	0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
++	0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
++	0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
++	0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
++	0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
++	0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
++	0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
++	0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
++	0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
++	0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
++	0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
++	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
++	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
++	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
++};
++
++static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
++	0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
++	0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
++	0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
++	0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
++	0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
++	0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
++	0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
++	0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
++	0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
++	0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
++	0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
++	0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
++	0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
++	0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
++	0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
++	0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
++	0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
++	0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
++	0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
++	0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
++	0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
++	0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
++	0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
++	0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
++	0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
++	0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
++	0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
++	0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
++	0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
++	-114, -108, -98, -91, -84, -78, -70, -62,
++	-54, -46, -39, -31, -23, -15, -8, 0
++};
++
++static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
++	-100, -95, -89, -83, -77, -70, -63, -56,
++	-48, -41, -33, -25, -19, -12, -6, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
++	-159, -113, -86, -72, -62, -54, -48, -43,
++	-39, -35, -31, -28, -25, -23, -20, -18,
++	-17, -15, -13, -11, -10, -8, -7, -6,
++	-5, -4, -3, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
++	-109, -109, -82, -68, -58, -50, -44, -39,
++	-35, -31, -28, -26, -23, -21, -19, -17,
++	-16, -14, -13, -11, -10, -9, -8, -7,
++	-5, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
++	-122, -122, -95, -80, -69, -61, -54, -49,
++	-43, -39, -35, -32, -28, -26, -23, -21,
++	-18, -16, -15, -13, -11, -10, -8, -7,
++	-6, -5, -4, -3, -2, -1, -1, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
++	-107, -101, -92, -85, -78, -71, -62, -55,
++	-47, -39, -32, -24, -19, -12, -6, 0
++};
++
++static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
++	-110, -104, -95, -88, -81, -74, -66, -58,
++	-50, -44, -36, -28, -23, -15, -8, 0
++};
++
++static u8 pad_gain_codes_used_2057rev5[] = {
++	20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
++	10, 9, 8, 7, 6, 5, 4, 3, 2, 1
++};
++
++static u8 pad_gain_codes_used_2057rev7[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
++	5, 4, 3, 2, 1
++};
++
++static u8 pad_all_gain_codes_2057[] = {
++	31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
++	21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
++	11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
++	1, 0
++};
++
++static u8 pga_all_gain_codes_2057[] = {
++	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
++};
++
++static u32 nphy_papd_scaltbl[] = {
++	0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
++	0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
++	0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
++	0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
++	0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
++	0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
++	0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
++	0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
++	0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
++	0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
++	0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
++	0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
++	0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
++	0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
++	0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
++	0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
++};
++
++static u32 nphy_tpc_txgain_rev3[] = {
++	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
++	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
++	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
++	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
++	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
++	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
++	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
++	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
++	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
++	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
++	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
++	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
++	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
++	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
++	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
++	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
++	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
++	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
++	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
++	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
++	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
++	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
++	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
++	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
++	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
++	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
++	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
++	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
++	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
++	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
++	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
++	0x1041003c, 0x1041003b, 0x10410039, 0x10410037
++};
++
++static u32 nphy_tpc_txgain_HiPwrEPA[] = {
++	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
++	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
++	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
++	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
++	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
++	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
++	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
++	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
++	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
++	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
++	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
++	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
++	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
++	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
++	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
++	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
++	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
++	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
++	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
++	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
++	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
++	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
++	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
++	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
++	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
++	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
++	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
++	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
++	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
++	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
++	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
++	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev3[] = {
++	0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
++	0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
++	0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
++	0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
++	0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
++	0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
++	0x80390038, 0x80390035, 0x8031003a, 0x80310036,
++	0x80310033, 0x8029003a, 0x80290037, 0x80290034,
++	0x80290031, 0x80210039, 0x80210036, 0x80210033,
++	0x80210030, 0x8019003c, 0x80190039, 0x80190036,
++	0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
++	0x80190028, 0x8011003a, 0x80110036, 0x80110033,
++	0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
++	0x80110027, 0x80110024, 0x80110022, 0x80110020,
++	0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
++	0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
++	0x80090029, 0x80090027, 0x80090025, 0x80090023,
++	0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
++	0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
++	0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
++	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
++};
++
++static u32 nphy_tpc_txgain_epa_2057rev5[] = {
++	0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
++	0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
++	0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
++	0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
++	0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
++	0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
++	0x10390038, 0x10390035, 0x1031003a, 0x10310036,
++	0x10310033, 0x1029003a, 0x10290037, 0x10290034,
++	0x10290031, 0x10210039, 0x10210036, 0x10210033,
++	0x10210030, 0x1019003c, 0x10190039, 0x10190036,
++	0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
++	0x10190028, 0x1011003a, 0x10110036, 0x10110033,
++	0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
++	0x10110027, 0x10110024, 0x10110022, 0x10110020,
++	0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
++	0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
++	0x10090029, 0x10090027, 0x10090025, 0x10090023,
++	0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
++	0x1009001a, 0x10090018, 0x10090017, 0x10090016,
++	0x10090015, 0x10090013, 0x10090012, 0x10090011,
++	0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
++	0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
++	0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
++	0x10090008, 0x10090008, 0x10090007, 0x10090007,
++	0x10090007, 0x10090006, 0x10090006, 0x10090005,
++	0x10090005, 0x10090005, 0x10090005, 0x10090004,
++	0x10090004, 0x10090004, 0x10090004, 0x10090003,
++	0x10090003, 0x10090003, 0x10090003, 0x10090003,
++	0x10090003, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090002, 0x10090002,
++	0x10090002, 0x10090002, 0x10090001, 0x10090001,
++	0x10090001, 0x10090001, 0x10090001, 0x10090001
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev3[] = {
++	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
++	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
++	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
++	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
++	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
++	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
++	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
++	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
++	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
++	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
++	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
++	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
++	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
++	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
++	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
++	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
++	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
++	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
++	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
++	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
++	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
++	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
++	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
++	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
++	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
++	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
++	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
++	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
++	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
++	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
++	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
++	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev4[] = {
++	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
++	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
++	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
++	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
++	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
++	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
++	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
++	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
++	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
++	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
++	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
++	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
++	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
++	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
++	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
++	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
++	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
++	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
++	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
++	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
++	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
++	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
++	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
++	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
++	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
++	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
++	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
++	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
++	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
++	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
++	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
++	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
++};
++
++static u32 nphy_tpc_5GHz_txgain_rev5[] = {
++	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
++	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
++	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
++	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
++	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
++	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
++	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
++	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
++	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
++	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
++	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
++	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
++	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
++	0x09620039, 0x09620037, 0x09620035, 0x09620033,
++	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
++	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
++	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
++	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
++	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
++	0x06620039, 0x06620037, 0x06620035, 0x06620033,
++	0x05620046, 0x05620044, 0x05620042, 0x05620040,
++	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
++	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
++	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
++	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
++	0x03620038, 0x03620037, 0x03620035, 0x03620033,
++	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
++	0x02620046, 0x02620044, 0x02620043, 0x02620042,
++	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
++	0x01620043, 0x01620042, 0x01620041, 0x01620040,
++	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
++	0x0062003b, 0x00620039, 0x00620037, 0x00620035
++};
++
++static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
++	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
++	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
++	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
++	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
++	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
++	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
++	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
++	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
++	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
++	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
++	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
++	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
++	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
++	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
++	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
++	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
++	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
++	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
++	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
++	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
++	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
++	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
++	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
++	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
++	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
++	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
++	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
++	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
++	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
++	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
++	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
++	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
++};
++
++static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
++static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
++	0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a
++};
++static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
++	0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16
++};
++
++bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u32 phybist0, phybist1, phybist2, phybist3, phybist4;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16))
++		return true;
++
++	phybist0 = read_phy_reg(pi, 0x0e);
++	phybist1 = read_phy_reg(pi, 0x0f);
++	phybist2 = read_phy_reg(pi, 0xea);
++	phybist3 = read_phy_reg(pi, 0xeb);
++	phybist4 = read_phy_reg(pi, 0x156);
++
++	if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
++	    (phybist3 == 0) && (phybist4 == 0))
++		return true;
++
++	return false;
++}
++
++static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi)
++{
++	u16 addr, val;
++
++	val = 0x1e1f;
++	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
++	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
++		write_phy_reg(pi, addr, val);
++		if (addr == (NPHY_TO_BPHY_OFF + 0x97))
++			val = 0x3e3f;
++		else
++			val -= 0x0202;
++	}
++
++	write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
++}
++
++void
++wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			 u32 width, const void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_write_table_nphy(pi, &tbl);
++}
++
++void
++wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset,
++			u32 width, void *data)
++{
++	struct phytbl_info tbl;
++
++	tbl.tbl_id = id;
++	tbl.tbl_len = len;
++	tbl.tbl_offset = offset;
++	tbl.tbl_width = width;
++	tbl.tbl_ptr = data;
++	wlc_phy_read_table_nphy(pi, &tbl);
++}
++
++static void
++wlc_phy_static_table_download_nphy(struct brcms_phy *pi)
++{
++	uint idx;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 16)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev16[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev7[idx]);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev3[idx]);
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0[idx]);
++	}
++}
++
++static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi)
++{
++	uint idx = 0;
++	u8 antswctrllut;
++
++	if (pi->phy_init_por)
++		wlc_phy_static_table_download_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
++			       pi->srom_fem2g.antswctrllut : pi->srom_fem5g.
++			       antswctrllut;
++
++		switch (antswctrllut) {
++		case 0:
++
++			break;
++
++		case 1:
++
++			if (pi->aa2g == 7)
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8_2o3[0]);
++			else
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_ANTSWCTRLLUT,
++					2, 0x21, 8,
++					&ant_sw_ctrl_tbl_rev8
++					[0]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x25, 8,
++						 &ant_sw_ctrl_tbl_rev8[2]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 2, 0x29, 8,
++						 &ant_sw_ctrl_tbl_rev8[4]);
++			break;
++
++		case 2:
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x1, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x5, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x9, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core0[4]);
++
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x21, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[0]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x25, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[2]);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++				2, 0x29, 8,
++				&ant_sw_ctrl_tbl_rev8_2057v7_core1[4]);
++			break;
++
++		default:
++			break;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
++
++			if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
++				antswctrllut =
++					CHSPEC_IS2G(pi->radio_chanspec) ?
++					pi->srom_fem2g.antswctrllut :
++					pi->srom_fem5g.antswctrllut;
++				switch (antswctrllut) {
++				case 0:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile
++						[idx]);
++					break;
++				case 1:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile1
++						[idx]);
++					break;
++				case 2:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile2
++						[idx]);
++					break;
++				case 3:
++					wlc_phy_write_table_nphy(
++						pi,
++						&mimophytbl_info_rev3_volatile3
++						[idx]);
++					break;
++				default:
++					break;
++				}
++			} else {
++				wlc_phy_write_table_nphy(
++					pi,
++					&mimophytbl_info_rev3_volatile[idx]);
++			}
++		}
++	} else {
++		for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++)
++			wlc_phy_write_table_nphy(pi,
++						 &mimophytbl_info_rev0_volatile
++						 [idx]);
++	}
++}
++
++static void
++wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay)
++{
++	write_phy_reg(pi, 0x77, holdoff);
++	write_phy_reg(pi, 0xb4, delay);
++}
++
++void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs)
++{
++	u16 holdoff, delay;
++
++	if (rifs) {
++
++		holdoff = 0x10;
++		delay = 0x258;
++	} else {
++
++		holdoff = 0x15;
++		delay = 0x320;
++	}
++
++	wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
++
++	if (pi && pi->sh && (pi->sh->_rifs_phy != rifs))
++		pi->sh->_rifs_phy = rifs;
++}
++
++static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi)
++{
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++		pi->phy_5g_pwrgain = true;
++		return;
++	}
++
++	pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
++	pi->phy_5g_pwrgain = false;
++
++	if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
++	    NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
++		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
++	else if ((pi->sh->sromrev >= 4)
++		 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
++		pi->phy_5g_pwrgain = true;
++}
++
++static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi)
++{
++	u16 bw40po, cddpo, stbcpo, bwduppo;
++	uint band_num;
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	if (pi->sh->sromrev >= 9)
++		return;
++
++	bw40po = sprom->bw40po;
++	pi->bw402gpo = bw40po & 0xf;
++	pi->bw405gpo = (bw40po & 0xf0) >> 4;
++	pi->bw405glpo = (bw40po & 0xf00) >> 8;
++	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
++
++	cddpo = sprom->cddpo;
++	pi->cdd2gpo = cddpo & 0xf;
++	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
++	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
++	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
++
++	stbcpo = sprom->stbcpo;
++	pi->stbc2gpo = stbcpo & 0xf;
++	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
++	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
++	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
++
++	bwduppo = sprom->bwduppo;
++	pi->bwdup2gpo = bwduppo & 0xf;
++	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
++	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
++	pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
++				sprom->core_pwr_info[0].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
++				sprom->core_pwr_info[1].maxpwr_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
++				sprom->core_pwr_info[0].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
++				sprom->core_pwr_info[1].pa_2g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
++				sprom->core_pwr_info[0].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
++				sprom->core_pwr_info[1].pa_2g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
++				sprom->core_pwr_info[0].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
++				sprom->core_pwr_info[1].pa_2g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
++				sprom->core_pwr_info[0].itssi_2g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
++				sprom->core_pwr_info[1].itssi_2g;
++
++			pi->cck2gpo = sprom->cck2gpo;
++
++			pi->ofdm2gpo = sprom->ofdm2gpo;
++
++			pi->mcs2gpo[0] = sprom->mcs2gpo[0];
++			pi->mcs2gpo[1] = sprom->mcs2gpo[1];
++			pi->mcs2gpo[2] = sprom->mcs2gpo[2];
++			pi->mcs2gpo[3] = sprom->mcs2gpo[3];
++			pi->mcs2gpo[4] = sprom->mcs2gpo[4];
++			pi->mcs2gpo[5] = sprom->mcs2gpo[5];
++			pi->mcs2gpo[6] = sprom->mcs2gpo[6];
++			pi->mcs2gpo[7] = sprom->mcs2gpo[7];
++			break;
++		case 1:
++
++			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
++				sprom->core_pwr_info[0].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
++				sprom->core_pwr_info[1].maxpwr_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[0].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
++				sprom->core_pwr_info[1].pa_5g[0];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[0].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
++				sprom->core_pwr_info[1].pa_5g[1];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[0].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
++				sprom->core_pwr_info[1].pa_5g[2];
++			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
++				sprom->core_pwr_info[0].itssi_5g;
++			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
++				sprom->core_pwr_info[1].itssi_5g;
++
++			pi->ofdm5gpo = sprom->ofdm5gpo;
++
++			pi->mcs5gpo[0] = sprom->mcs5gpo[0];
++			pi->mcs5gpo[1] = sprom->mcs5gpo[1];
++			pi->mcs5gpo[2] = sprom->mcs5gpo[2];
++			pi->mcs5gpo[3] = sprom->mcs5gpo[3];
++			pi->mcs5gpo[4] = sprom->mcs5gpo[4];
++			pi->mcs5gpo[5] = sprom->mcs5gpo[5];
++			pi->mcs5gpo[6] = sprom->mcs5gpo[6];
++			pi->mcs5gpo[7] = sprom->mcs5gpo[7];
++			break;
++		case 2:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
++				sprom->core_pwr_info[0].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
++				sprom->core_pwr_info[1].maxpwr_5gl;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[0].pa_5gl[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
++				sprom->core_pwr_info[1].pa_5gl[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[0].pa_5gl[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
++				sprom->core_pwr_info[1].pa_5gl[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[0].pa_5gl[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
++				sprom->core_pwr_info[1].pa_5gl[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
++
++			pi->ofdm5glpo = sprom->ofdm5glpo;
++
++			pi->mcs5glpo[0] = sprom->mcs5glpo[0];
++			pi->mcs5glpo[1] = sprom->mcs5glpo[1];
++			pi->mcs5glpo[2] = sprom->mcs5glpo[2];
++			pi->mcs5glpo[3] = sprom->mcs5glpo[3];
++			pi->mcs5glpo[4] = sprom->mcs5glpo[4];
++			pi->mcs5glpo[5] = sprom->mcs5glpo[5];
++			pi->mcs5glpo[6] = sprom->mcs5glpo[6];
++			pi->mcs5glpo[7] = sprom->mcs5glpo[7];
++			break;
++		case 3:
++
++			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
++				sprom->core_pwr_info[0].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
++				sprom->core_pwr_info[1].maxpwr_5gh;
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[0].pa_5gh[0];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
++				sprom->core_pwr_info[1].pa_5gh[0];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[0].pa_5gh[1];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
++				sprom->core_pwr_info[1].pa_5gh[1];
++			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[0].pa_5gh[2];
++			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
++				sprom->core_pwr_info[1].pa_5gh[2];
++			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
++			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
++
++			pi->ofdm5ghpo = sprom->ofdm5ghpo;
++
++			pi->mcs5ghpo[0] = sprom->mcs5ghpo[0];
++			pi->mcs5ghpo[1] = sprom->mcs5ghpo[1];
++			pi->mcs5ghpo[2] = sprom->mcs5ghpo[2];
++			pi->mcs5ghpo[3] = sprom->mcs5ghpo[3];
++			pi->mcs5ghpo[4] = sprom->mcs5ghpo[4];
++			pi->mcs5ghpo[5] = sprom->mcs5ghpo[5];
++			pi->mcs5ghpo[6] = sprom->mcs5ghpo[6];
++			pi->mcs5ghpo[7] = sprom->mcs5ghpo[7];
++			break;
++		}
++	}
++
++	wlc_phy_txpwr_apply_nphy(pi);
++}
++
++static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi)
++{
++	struct ssb_sprom *sprom = &pi->d11core->bus->sprom;
++
++	pi->antswitch = sprom->antswitch;
++	pi->aa2g = sprom->ant_available_bg;
++	pi->aa5g = sprom->ant_available_a;
++
++	pi->srom_fem2g.tssipos = sprom->fem.ghz2.tssipos;
++	pi->srom_fem2g.extpagain = sprom->fem.ghz2.extpa_gain;
++	pi->srom_fem2g.pdetrange = sprom->fem.ghz2.pdet_range;
++	pi->srom_fem2g.triso = sprom->fem.ghz2.tr_iso;
++	pi->srom_fem2g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	pi->srom_fem5g.tssipos = sprom->fem.ghz5.tssipos;
++	pi->srom_fem5g.extpagain = sprom->fem.ghz5.extpa_gain;
++	pi->srom_fem5g.pdetrange = sprom->fem.ghz5.pdet_range;
++	pi->srom_fem5g.triso = sprom->fem.ghz5.tr_iso;
++	if (sprom->fem.ghz5.antswlut)
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz5.antswlut;
++	else
++		pi->srom_fem5g.antswctrllut = sprom->fem.ghz2.antswlut;
++
++	wlc_phy_txpower_ipa_upd(pi);
++
++	pi->phy_txcore_disable_temp = sprom->tempthresh;
++	if (pi->phy_txcore_disable_temp == 0)
++		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
++
++	pi->phy_tempsense_offset = sprom->tempoffset;
++	if (pi->phy_tempsense_offset != 0) {
++		if (pi->phy_tempsense_offset >
++		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
++		else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
++						     NPHY_SROM_MINTEMPOFFSET))
++			pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
++		else
++			pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
++	}
++
++	pi->phy_txcore_enable_temp =
++		pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
++
++	pi->phycal_tempdelta = sprom->phycal_tempdelta;
++	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA)
++		pi->phycal_tempdelta = 0;
++
++	wlc_phy_txpwr_srom_read_ppr_nphy(pi);
++
++	return true;
++}
++
++bool wlc_phy_attach_nphy(struct brcms_phy *pi)
++{
++	uint i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6))
++		pi->phyhang_avoid = true;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		pi->nphy_gband_spurwar_en = true;
++		if (pi->sh->boardflags2 & BFL2_SPUR_WAR)
++			pi->nphy_aband_spurwar_en = true;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR)
++			pi->nphy_gband_spurwar2_en = true;
++	}
++
++	pi->n_preamble_override = AUTO;
++	if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
++		pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE;
++
++	pi->nphy_txrx_chain = AUTO;
++	pi->phy_scraminit = AUTO;
++
++	pi->nphy_rxcalparams = 0x010100B5;
++
++	pi->nphy_perical = PHY_PERICAL_MPHASE;
++	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
++	pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
++
++	pi->nphy_gain_boost = true;
++	pi->nphy_elna_gain_config = false;
++	pi->radio_is_on = false;
++
++	for (i = 0; i < pi->pubpi.phy_corenum; i++)
++		pi->nphy_txpwrindex[i].index = AUTO;
++
++	wlc_phy_txpwrctrl_config_nphy(pi);
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
++		pi->hwpwrctrl_capable = true;
++
++	pi->pi_fptr.init = wlc_phy_init_nphy;
++	pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
++	pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
++	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
++
++	if (!wlc_phy_txpwr_srom_read_nphy(pi))
++		return false;
++
++	return true;
++}
++
++static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn)
++{
++	s32 rfpwr_offset = 0;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev3n4
++				       [pad_gn];
++		else if (pi->pubpi.radiorev == 5)
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev5
++				       [pad_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_padgain_dlt_2g_2057rev7
++				       [pad_gn];
++	} else {
++		if ((pi->pubpi.radiorev == 3) ||
++		    (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057
++				       [pga_gn];
++		else if ((pi->pubpi.radiorev == 7)
++			 || (pi->pubpi.radiorev ==
++			     8))
++			rfpwr_offset = (s16)
++				       nphy_papd_pgagain_dlt_5g_2057rev7
++				       [pga_gn];
++	}
++	return rfpwr_offset;
++}
++
++static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble)
++{
++	bool gf_preamble = false;
++	u16 val;
++
++	if (preamble == BRCMS_N_PREAMBLE_GF)
++		gf_preamble = true;
++
++	val = read_phy_reg(pi, 0xed);
++
++	val |= RX_GF_MM_AUTO;
++	val &= ~RX_GF_OR_MM;
++	if (gf_preamble)
++		val |= RX_GF_OR_MM;
++
++	write_phy_reg(pi, 0xed, val);
++}
++
++static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type;
++	u16 addr_offset[] = { 0x186, 0x195, 0x2c5};
++
++	for (type = 0; type < 3; type++) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, addr_offset[type] + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++	}
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x186 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[5][j]);
++		}
++
++		if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++				write_phy_reg(pi, 0x2c5 + j,
++					NPHY_IPA_REV4_txdigi_filtcoeffs[6][j]);
++		}
++	}
++}
++
++static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j;
++
++	if (pi->bw == WL_CHANSPEC_BW_40) {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x195 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
++	} else {
++		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++			write_phy_reg(pi, 0x186 + j,
++				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
++	}
++}
++
++static void
++wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
++		       u8 len)
++{
++	u32 t1_offset, t2_offset;
++	u8 ctr;
++	u8 end_event =
++		NREV_GE(pi->pubpi.phy_rev,
++			3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
++	u8 end_dly = 1;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	t1_offset = cmd << 4;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
++				 events);
++	t2_offset = t1_offset + 0x080;
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
++				 dlys);
++
++	for (ctr = len; ctr < 16; ctr++) {
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t1_offset + ctr, 8, &end_event);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++					 t2_offset + ctr, 8, &end_dly);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset)
++{
++	u16 lpf_bw_ctl_val = 0;
++	u16 rx2tx_lpf_rc_lut_offset = 0;
++
++	if (offset == 0) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			rx2tx_lpf_rc_lut_offset = 0x159;
++		else
++			rx2tx_lpf_rc_lut_offset = 0x154;
++	} else {
++		rx2tx_lpf_rc_lut_offset = offset;
++	}
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
++				(u32) rx2tx_lpf_rc_lut_offset, 16,
++				&lpf_bw_ctl_val);
++
++	lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
++
++	return lpf_bw_ctl_val;
++}
++
++static void
++wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value,
++				  u8 core_mask, u8 off, u8 override_id)
++{
++	u8 core_num;
++	u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
++	u8 val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++			if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
++
++				switch (field) {
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 7):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7a :
++						   0x7d;
++					val_mask = (0x1 << 7);
++					val_shift = 7;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0xf8 :
++						   0xfa;
++					val_mask = (0x7 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7b :
++						   0x7e;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 12):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x7c :
++						   0x7f;
++					val_mask = (0xffff << 0);
++					val_shift = 0;
++					break;
++				case (0x3 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xff << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 13):
++					en_addr = (core_num == 0) ? 0xe7 : 0xec;
++					val_addr = (core_num == 0) ? 0x348 :
++						   0x349;
++					val_mask = (0xf << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID1) {
++
++				switch (field) {
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 5):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 5);
++					val_shift = 5;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				case (0x1 << 2):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 7):
++
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x7 << 8);
++					val_shift = 8;
++					break;
++				case (0x1 << 11):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 14);
++					val_shift = 14;
++					break;
++				case (0x1 << 10):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 13);
++					val_shift = 13;
++					break;
++				case (0x1 << 9):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 12);
++					val_shift = 12;
++					break;
++				case (0x1 << 8):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 11);
++					val_shift = 11;
++					break;
++				case (0x1 << 6):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 6);
++					val_shift = 6;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x342 :
++						  0x343;
++					val_addr = (core_num == 0) ? 0x340 :
++						   0x341;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			} else if (override_id ==
++				   NPHY_REV7_RFCTRLOVERRIDE_ID2) {
++
++				switch (field) {
++				case (0x1 << 3):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 3);
++					val_shift = 3;
++					break;
++				case (0x1 << 1):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 1);
++					val_shift = 1;
++					break;
++				case (0x1 << 0):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 0);
++					val_shift = 0;
++					break;
++				case (0x1 << 2):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 2);
++					val_shift = 2;
++					break;
++				case (0x1 << 4):
++					en_addr = (core_num == 0) ? 0x346 :
++						  0x347;
++					val_addr = (core_num == 0) ? 0x344 :
++						   0x345;
++					val_mask = (0x1 << 4);
++					val_shift = 4;
++					break;
++				default:
++					addr = 0xffff;
++					break;
++				}
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	}
++}
++
++static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	int ctr;
++	s16 gain_delta[2];
++	u8 curr_channel;
++	u16 minmax_gain[2];
++	u16 regval[4];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->nphy_gain_boost) {
++		if ((CHSPEC_IS2G(pi->radio_chanspec))) {
++
++			gain_delta[0] = 6;
++			gain_delta[1] = 6;
++		} else {
++
++			curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++			gain_delta[0] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est0[0] *
++					       curr_channel) +
++					      nphy_lnagain_est0[1]), 13);
++			gain_delta[1] =
++				(s16)
++				PHY_HW_ROUND(((nphy_lnagain_est1[0] *
++					       curr_channel) +
++					      nphy_lnagain_est1[1]), 13);
++		}
++	} else {
++
++		gain_delta[0] = 0;
++		gain_delta[1] = 0;
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (pi->nphy_elna_gain_config) {
++
++			regval[0] = nphy_def_lnagains[2] + gain_delta[core];
++			regval[1] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[2] = nphy_def_lnagains[3] + gain_delta[core];
++			regval[3] = nphy_def_lnagains[3] + gain_delta[core];
++		} else {
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] =
++					nphy_def_lnagains[ctr] +
++					gain_delta[core];
++		}
++		wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
++
++		minmax_gain[core] =
++			(u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
++	}
++
++	mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
++	mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core)
++{
++	if (core == PHY_CORE_0) {
++		write_phy_reg(pi, 0x38, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x37, 0x0060);
++		else
++			write_phy_reg(pi, 0x37, 0x1080);
++	} else if (core == PHY_CORE_1) {
++		write_phy_reg(pi, 0x2ae, 0x4);
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x2ad, 0x0060);
++		else
++			write_phy_reg(pi, 0x2ad, 0x1080);
++	}
++}
++
++static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain)
++{
++	u8 txchain0, txchain1;
++
++	txchain0 = txchain & 0x1;
++	txchain1 = (txchain & 0x2) >> 1;
++	if (!txchain0)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++
++	if (!txchain1)
++		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
++{
++	s8 lna1_gain_db[] = { 8, 13, 17, 22 };
++	s8 lna2_gain_db[] = { -2, 7, 11, 15 };
++	s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
++	s8 tia_gainbits[] = {
++		0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++	mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
++	mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
++				 lna1_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
++				 lna1_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
++				 lna2_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
++				 lna2_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++				 tia_gain_db);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++				 tia_gain_db);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++				 tia_gainbits);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++				 tia_gainbits);
++
++	write_phy_reg(pi, 0x37, 0x74);
++	write_phy_reg(pi, 0x2ad, 0x74);
++	write_phy_reg(pi, 0x38, 0x18);
++	write_phy_reg(pi, 0x2ae, 0x18);
++
++	write_phy_reg(pi, 0x2b, 0xe8);
++	write_phy_reg(pi, 0x41, 0xe8);
++
++	if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
++	} else {
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
++{
++	u16 currband;
++	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
++	s8 *lna1_gain_db = NULL;
++	s8 *lna1_gain_db_2 = NULL;
++	s8 *lna2_gain_db = NULL;
++	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
++	s8 *tia_gain_db;
++	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
++	s8 *tia_gainbits;
++	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
++	u16 *rfseq_init_gain;
++	u16 init_gaincode;
++	u16 clip1hi_gaincode;
++	u16 clip1md_gaincode = 0;
++	u16 clip1md_gaincode_B;
++	u16 clip1lo_gaincode;
++	u16 clip1lo_gaincode_B;
++	u8 crsminl_th = 0;
++	u8 crsminu_th;
++	u16 nbclip_th = 0;
++	u8 w1clip_th;
++	u16 freq;
++	s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
++	u8 chg_nbclip_th = 0;
++
++	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++	currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (currband == 0) {
++
++		lna1_gain_db = lna1G_gain_db_rev7;
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++					 lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++					 lna1_gain_db);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
++
++		if (CHSPEC_IS40(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
++		}
++
++		mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
++			mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
++		}
++	} else {
++
++		init_gaincode = 0x9e;
++		clip1hi_gaincode = 0x9e;
++		clip1md_gaincode_B = 0x24;
++		clip1lo_gaincode = 0x8a;
++		clip1lo_gaincode_B = 8;
++		rfseq_init_gain = rfseqA_init_gain_rev7;
++
++		tia_gain_db = tiaA_gain_db_rev7;
++		tia_gainbits = tiaA_gainbits_rev7;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			w1clip_th = 25;
++			clip1md_gaincode = 0x82;
++
++			if ((freq <= 5080) || (freq == 5825)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					11, 17, 22, 25};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x3e;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else if ((freq >= 5500) && (freq <= 5700)) {
++
++				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
++
++				crsminu_th = 0x45;
++				clip1md_gaincode_B = 0x14;
++				nbclip_th = 0xff;
++				chg_nbclip_th = 1;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			} else {
++
++				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
++				s8 lna1A_gain_db_2_rev7[] = {
++					12, 18, 22, 26};
++				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
++
++				crsminu_th = 0x41;
++				lna1_gain_db = lna1A_gain_db_rev7;
++				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
++				lna2_gain_db = lna2A_gain_db_rev7;
++			}
++
++			if (freq <= 4920) {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5700)) {
++				nvar_baseline_offset0 = 3;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 0;
++			}
++		} else {
++
++			crsminu_th = 0x3a;
++			crsminl_th = 0x3a;
++			w1clip_th = 20;
++
++			if ((freq >= 4920) && (freq <= 5320)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 5;
++			} else if ((freq > 5320) && (freq <= 5550)) {
++				nvar_baseline_offset0 = 4;
++				nvar_baseline_offset1 = 2;
++			} else {
++				nvar_baseline_offset0 = 5;
++				nvar_baseline_offset1 = 3;
++			}
++		}
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x36, clip1md_gaincode_B);
++		write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++		write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
++		write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
++					 tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
++					 tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
++					 tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
++					 tia_gainbits);
++
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		if (chg_nbclip_th == 1) {
++			write_phy_reg(pi, 0x2b, nbclip_th);
++			write_phy_reg(pi, 0x41, nbclip_th);
++		}
++
++		mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 0), (nvar_baseline_offset0 << 0));
++
++		mod_phy_reg(pi, 0x2e4,
++			    (0x3f << 6), (nvar_baseline_offset1 << 6));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
++						 lna1_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
++						 lna1_gain_db_2);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++						 8, lna2_gain_db);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++						 8, lna2_gain_db);
++
++			write_phy_reg(pi, 0x24, clip1md_gaincode);
++			write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++		} else {
++			mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		}
++	}
++}
++
++static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
++{
++	u16 w1th, hpf_code, currband;
++	int ctr;
++	u8 rfseq_updategainu_events[] = {
++		NPHY_RFSEQ_CMD_RX_GAIN,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_SET_HPF_BW
++	};
++	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
++	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
++	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
++	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
++	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
++	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
++	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
++	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
++	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
++	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
++	s8 *lna1_gain_db = NULL;
++	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
++	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
++	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
++	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
++	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
++	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
++	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
++	s8 *lna2_gain_db = NULL;
++	s8 tiaG_gain_db[] = {
++		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
++	s8 tiaA_gain_db[] = {
++		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
++	s8 tiaA_gain_db_rev4[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev5[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 tiaA_gain_db_rev6[] = {
++		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
++	s8 *tia_gain_db;
++	s8 tiaG_gainbits[] = {
++		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
++	s8 tiaA_gainbits[] = {
++		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
++	s8 tiaA_gainbits_rev4[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev5[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 tiaA_gainbits_rev6[] = {
++		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
++	s8 *tia_gainbits;
++	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
++	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
++	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
++	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev5_elna[] = {
++		0x013f, 0x013f, 0x013f, 0x013f };
++	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
++	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
++	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
++	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
++	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
++	u16 rfseqA_init_gain_rev4_elna[] = {
++		0x314f, 0x314f, 0x314f, 0x314f };
++	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
++	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
++	u16 *rfseq_init_gain;
++	u16 initG_gaincode = 0x627e;
++	u16 initG_gaincode_rev4 = 0x527e;
++	u16 initG_gaincode_rev5 = 0x427e;
++	u16 initG_gaincode_rev5_elna = 0x027e;
++	u16 initG_gaincode_rev6 = 0x527e;
++	u16 initG_gaincode_rev6_224B0 = 0x427e;
++	u16 initG_gaincode_rev6_elna = 0x127e;
++	u16 initA_gaincode = 0x52de;
++	u16 initA_gaincode_rev4 = 0x629e;
++	u16 initA_gaincode_rev4_elna = 0x329e;
++	u16 initA_gaincode_rev5 = 0x729e;
++	u16 initA_gaincode_rev6 = 0x729e;
++	u16 init_gaincode;
++	u16 clip1hiG_gaincode = 0x107e;
++	u16 clip1hiG_gaincode_rev4 = 0x007e;
++	u16 clip1hiG_gaincode_rev5 = 0x1076;
++	u16 clip1hiG_gaincode_rev6 = 0x007e;
++	u16 clip1hiA_gaincode = 0x00de;
++	u16 clip1hiA_gaincode_rev4 = 0x029e;
++	u16 clip1hiA_gaincode_rev5 = 0x029e;
++	u16 clip1hiA_gaincode_rev6 = 0x029e;
++	u16 clip1hi_gaincode;
++	u16 clip1mdG_gaincode = 0x0066;
++	u16 clip1mdA_gaincode = 0x00ca;
++	u16 clip1mdA_gaincode_rev4 = 0x1084;
++	u16 clip1mdA_gaincode_rev5 = 0x2084;
++	u16 clip1mdA_gaincode_rev6 = 0x2084;
++	u16 clip1md_gaincode = 0;
++	u16 clip1loG_gaincode = 0x0074;
++	u16 clip1loG_gaincode_rev5[] = {
++		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
++	};
++	u16 clip1loG_gaincode_rev6[] = {
++		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
++	};
++	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
++	u16 clip1loA_gaincode = 0x00cc;
++	u16 clip1loA_gaincode_rev4 = 0x0086;
++	u16 clip1loA_gaincode_rev5 = 0x2086;
++	u16 clip1loA_gaincode_rev6 = 0x2086;
++	u16 clip1lo_gaincode;
++	u8 crsminG_th = 0x18;
++	u8 crsminG_th_rev5 = 0x18;
++	u8 crsminG_th_rev6 = 0x18;
++	u8 crsminA_th = 0x1e;
++	u8 crsminA_th_rev4 = 0x24;
++	u8 crsminA_th_rev5 = 0x24;
++	u8 crsminA_th_rev6 = 0x24;
++	u8 crsmin_th;
++	u8 crsminlG_th = 0x18;
++	u8 crsminlG_th_rev5 = 0x18;
++	u8 crsminlG_th_rev6 = 0x18;
++	u8 crsminlA_th = 0x1e;
++	u8 crsminlA_th_rev4 = 0x24;
++	u8 crsminlA_th_rev5 = 0x24;
++	u8 crsminlA_th_rev6 = 0x24;
++	u8 crsminl_th = 0;
++	u8 crsminuG_th = 0x18;
++	u8 crsminuG_th_rev5 = 0x18;
++	u8 crsminuG_th_rev6 = 0x18;
++	u8 crsminuA_th = 0x1e;
++	u8 crsminuA_th_rev4 = 0x24;
++	u8 crsminuA_th_rev5 = 0x24;
++	u8 crsminuA_th_rev6 = 0x24;
++	u8 crsminuA_th_rev6_224B0 = 0x2d;
++	u8 crsminu_th;
++	u16 nbclipG_th = 0x20d;
++	u16 nbclipG_th_rev4 = 0x1a1;
++	u16 nbclipG_th_rev5 = 0x1d0;
++	u16 nbclipG_th_rev6 = 0x1d0;
++	u16 nbclipA_th = 0x1a1;
++	u16 nbclipA_th_rev4 = 0x107;
++	u16 nbclipA_th_rev5 = 0x0a9;
++	u16 nbclipA_th_rev6 = 0x0f0;
++	u16 nbclip_th = 0;
++	u8 w1clipG_th = 5;
++	u8 w1clipG_th_rev5 = 9;
++	u8 w1clipG_th_rev6 = 5;
++	u8 w1clipA_th = 25, w1clip_th;
++	u8 rssi_gain_default = 0x50;
++	u8 rssiG_gain_rev6_224B0 = 0x50;
++	u8 rssiA_gain_rev5 = 0x90;
++	u8 rssiA_gain_rev6 = 0x90;
++	u8 rssi_gain;
++	u16 regval[21];
++	u8 triso;
++
++	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
++		pi->srom_fem2g.triso;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (pi->pubpi.radiorev == 5) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
++		} else if (pi->pubpi.radiorev == 7) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
++			mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
++
++		} else if ((pi->pubpi.radiorev == 3)
++			   || (pi->pubpi.radiorev == 8)) {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++
++			if (pi->pubpi.radiorev == 8) {
++				mod_phy_reg(pi, 0x283,
++					    (0xff << 0), (0x44 << 0));
++				mod_phy_reg(pi, 0x280,
++					    (0xff << 0), (0x44 << 0));
++			}
++		} else {
++			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		currband =
++			read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++		if (currband == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				if (pi->pubpi.radiorev == 11) {
++					lna1_gain_db = lna1G_gain_db_rev6_224B0;
++					lna2_gain_db = lna2G_gain_db_rev6_224B0;
++					rfseq_init_gain =
++						rfseqG_init_gain_rev6_224B0;
++					init_gaincode =
++						initG_gaincode_rev6_224B0;
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev6_224B0;
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssiG_gain_rev6_224B0;
++				} else {
++					lna1_gain_db = lna1G_gain_db_rev6;
++					lna2_gain_db = lna2G_gain_db_rev6;
++					if (pi->sh->boardflags & BFL_EXTLNA) {
++
++						rfseq_init_gain =
++						     rfseqG_init_gain_rev6_elna;
++						init_gaincode =
++						       initG_gaincode_rev6_elna;
++					} else {
++						rfseq_init_gain =
++							rfseqG_init_gain_rev6;
++						init_gaincode =
++							initG_gaincode_rev6;
++					}
++					clip1hi_gaincode =
++						clip1hiG_gaincode_rev6;
++					switch (triso) {
++					case 0:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[0];
++						break;
++					case 1:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[1];
++						break;
++					case 2:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[2];
++						break;
++					case 3:
++					default:
++
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[3];
++						break;
++					case 4:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[4];
++						break;
++					case 5:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[5];
++						break;
++					case 6:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[6];
++						break;
++					case 7:
++						clip1lo_gaincode =
++							clip1loG_gaincode_rev6
++							[7];
++						break;
++					}
++					nbclip_th = nbclipG_th_rev6;
++					w1clip_th = w1clipG_th_rev6;
++					crsmin_th = crsminG_th_rev6;
++					crsminl_th = crsminlG_th_rev6;
++					crsminu_th = crsminuG_th_rev6;
++					rssi_gain = rssi_gain_default;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1G_gain_db_rev5;
++				lna2_gain_db = lna2G_gain_db_rev5;
++				if (pi->sh->boardflags & BFL_EXTLNA) {
++
++					rfseq_init_gain =
++						rfseqG_init_gain_rev5_elna;
++					init_gaincode =
++						initG_gaincode_rev5_elna;
++				} else {
++					rfseq_init_gain = rfseqG_init_gain_rev5;
++					init_gaincode = initG_gaincode_rev5;
++				}
++				clip1hi_gaincode = clip1hiG_gaincode_rev5;
++				switch (triso) {
++				case 0:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[0];
++					break;
++				case 1:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[1];
++					break;
++				case 2:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[2];
++					break;
++				case 3:
++
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				case 4:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[4];
++					break;
++				case 5:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[5];
++					break;
++				case 6:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[6];
++					break;
++				case 7:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[7];
++					break;
++				default:
++					clip1lo_gaincode =
++						clip1loG_gaincode_rev5[3];
++					break;
++				}
++				nbclip_th = nbclipG_th_rev5;
++				w1clip_th = w1clipG_th_rev5;
++				crsmin_th = crsminG_th_rev5;
++				crsminl_th = crsminlG_th_rev5;
++				crsminu_th = crsminuG_th_rev5;
++				rssi_gain = rssi_gain_default;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1G_gain_db_rev4;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain_rev4;
++				init_gaincode = initG_gaincode_rev4;
++				clip1hi_gaincode = clip1hiG_gaincode_rev4;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th_rev4;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1G_gain_db;
++				lna2_gain_db = lna2G_gain_db;
++				rfseq_init_gain = rfseqG_init_gain;
++				init_gaincode = initG_gaincode;
++				clip1hi_gaincode = clip1hiG_gaincode;
++				clip1lo_gaincode = clip1loG_gaincode;
++				nbclip_th = nbclipG_th;
++				w1clip_th = w1clipG_th;
++				crsmin_th = crsminG_th;
++				crsminl_th = crsminlG_th;
++				crsminu_th = crsminuG_th;
++				rssi_gain = rssi_gain_default;
++			}
++			tia_gain_db = tiaG_gain_db;
++			tia_gainbits = tiaG_gainbits;
++			clip1md_gaincode = clip1mdG_gaincode;
++		} else {
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				lna1_gain_db = lna1A_gain_db_rev6;
++				lna2_gain_db = lna2A_gain_db_rev6;
++				tia_gain_db = tiaA_gain_db_rev6;
++				tia_gainbits = tiaA_gainbits_rev6;
++				rfseq_init_gain = rfseqA_init_gain_rev6;
++				init_gaincode = initA_gaincode_rev6;
++				clip1hi_gaincode = clip1hiA_gaincode_rev6;
++				clip1md_gaincode = clip1mdA_gaincode_rev6;
++				clip1lo_gaincode = clip1loA_gaincode_rev6;
++				crsmin_th = crsminA_th_rev6;
++				crsminl_th = crsminlA_th_rev6;
++				if ((pi->pubpi.radiorev == 11) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 0))
++					crsminu_th = crsminuA_th_rev6_224B0;
++				else
++					crsminu_th = crsminuA_th_rev6;
++
++				nbclip_th = nbclipA_th_rev6;
++				rssi_gain = rssiA_gain_rev6;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				lna1_gain_db = lna1A_gain_db_rev5;
++				lna2_gain_db = lna2A_gain_db_rev5;
++				tia_gain_db = tiaA_gain_db_rev5;
++				tia_gainbits = tiaA_gainbits_rev5;
++				rfseq_init_gain = rfseqA_init_gain_rev5;
++				init_gaincode = initA_gaincode_rev5;
++				clip1hi_gaincode = clip1hiA_gaincode_rev5;
++				clip1md_gaincode = clip1mdA_gaincode_rev5;
++				clip1lo_gaincode = clip1loA_gaincode_rev5;
++				crsmin_th = crsminA_th_rev5;
++				crsminl_th = crsminlA_th_rev5;
++				crsminu_th = crsminuA_th_rev5;
++				nbclip_th = nbclipA_th_rev5;
++				rssi_gain = rssiA_gain_rev5;
++			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++				lna1_gain_db = lna1A_gain_db_rev4;
++				lna2_gain_db = lna2A_gain_db_rev4;
++				tia_gain_db = tiaA_gain_db_rev4;
++				tia_gainbits = tiaA_gainbits_rev4;
++				if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
++
++					rfseq_init_gain =
++						rfseqA_init_gain_rev4_elna;
++					init_gaincode =
++						initA_gaincode_rev4_elna;
++				} else {
++					rfseq_init_gain = rfseqA_init_gain_rev4;
++					init_gaincode = initA_gaincode_rev4;
++				}
++				clip1hi_gaincode = clip1hiA_gaincode_rev4;
++				clip1md_gaincode = clip1mdA_gaincode_rev4;
++				clip1lo_gaincode = clip1loA_gaincode_rev4;
++				crsmin_th = crsminA_th_rev4;
++				crsminl_th = crsminlA_th_rev4;
++				crsminu_th = crsminuA_th_rev4;
++				nbclip_th = nbclipA_th_rev4;
++				rssi_gain = rssi_gain_default;
++			} else {
++				lna1_gain_db = lna1A_gain_db;
++				lna2_gain_db = lna2A_gain_db;
++				tia_gain_db = tiaA_gain_db;
++				tia_gainbits = tiaA_gainbits;
++				rfseq_init_gain = rfseqA_init_gain;
++				init_gaincode = initA_gaincode;
++				clip1hi_gaincode = clip1hiA_gaincode;
++				clip1md_gaincode = clip1mdA_gaincode;
++				clip1lo_gaincode = clip1loA_gaincode;
++				crsmin_th = crsminA_th;
++				crsminl_th = crsminlA_th;
++				crsminu_th = crsminuA_th;
++				nbclip_th = nbclipA_th;
++				rssi_gain = rssi_gain_default;
++			}
++			w1clip_th = w1clipA_th;
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
++				0xf0);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
++				0xf0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
++				rssi_gain);
++		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
++				rssi_gain);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX0), 0x17);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
++				 RADIO_2056_RX1), 0x17);
++
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
++				0xFF);
++		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
++				0xFF);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
++					 8, lna1_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
++					 8, lna1_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
++					 8, lna2_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
++					 8, lna2_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
++					 8, tia_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
++					 8, tia_gain_db);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
++					 8, tia_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
++					 8, tia_gainbits);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
++					 8, &lpf_gain_db);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
++					 8, &lpf_gainbits);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
++					 8, &lpf_gainbits);
++
++		write_phy_reg(pi, 0x20, init_gaincode);
++		write_phy_reg(pi, 0x2a7, init_gaincode);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 pi->pubpi.phy_corenum, 0x106, 16,
++					 rfseq_init_gain);
++
++		write_phy_reg(pi, 0x22, clip1hi_gaincode);
++		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
++
++		write_phy_reg(pi, 0x24, clip1md_gaincode);
++		write_phy_reg(pi, 0x2ab, clip1md_gaincode);
++
++		write_phy_reg(pi, 0x37, clip1lo_gaincode);
++		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
++
++		mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
++		mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
++		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
++
++		write_phy_reg(pi, 0x2b, nbclip_th);
++		write_phy_reg(pi, 0x41, nbclip_th);
++
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++	} else {
++
++		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
++		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
++
++		write_phy_reg(pi, 0x2b, 0x84);
++		write_phy_reg(pi, 0x41, 0x84);
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			write_phy_reg(pi, 0x6b, 0x2b);
++			write_phy_reg(pi, 0x6c, 0x2b);
++			write_phy_reg(pi, 0x6d, 0x9);
++			write_phy_reg(pi, 0x6e, 0x9);
++		}
++
++		w1th = NPHY_RSSICAL_W1_TARGET - 4;
++		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
++		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
++
++		if (CHSPEC_IS20(pi->radio_chanspec)) {
++			mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
++
++			mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
++		}
++
++		write_phy_reg(pi, 0x150, 0x809c);
++
++		if (pi->nphy_gain_boost)
++			if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
++			    (CHSPEC_IS40(pi->radio_chanspec)))
++				hpf_code = 4;
++			else
++				hpf_code = 5;
++		else if (CHSPEC_IS40(pi->radio_chanspec))
++			hpf_code = 6;
++		else
++			hpf_code = 7;
++
++		mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
++		mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
++
++		for (ctr = 0; ctr < 4; ctr++)
++			regval[ctr] = (hpf_code << 8) | 0x7c;
++		wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++		if (pi->nphy_elna_gain_config) {
++			regval[0] = 0;
++			regval[1] = 1;
++			regval[2] = 1;
++			regval[3] = 1;
++			wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
++
++			for (ctr = 0; ctr < 4; ctr++)
++				regval[ctr] = (hpf_code << 8) | 0x74;
++			wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = 3 * ctr;
++			wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
++
++			for (ctr = 0; ctr < 21; ctr++)
++				regval[ctr] = (u16) ctr;
++			wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
++			wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
++		}
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
++				       rfseq_updategainu_events,
++				       rfseq_updategainu_dlys,
++				       sizeof(rfseq_updategainu_events) /
++				       sizeof(rfseq_updategainu_events[0]));
++
++		mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			mod_phy_reg(pi,
++				    (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
++				    0x7f, 0x4);
++	}
++}
++
++static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
++{
++	u8 rfseq_rx2tx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_EXT_PA
++	};
++	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
++	u8 rfseq_tx2rx_events[] = {
++		NPHY_RFSEQ_CMD_NOP,
++		NPHY_RFSEQ_CMD_EXT_PA,
++		NPHY_RFSEQ_CMD_TX_GAIN,
++		NPHY_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_RFSEQ_CMD_TR_SWITCH,
++		NPHY_RFSEQ_CMD_RXG_FBW,
++		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
++	};
++	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
++	u8 rfseq_tx2rx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
++	u8 rfseq_rx2tx_events_rev3[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_EXT_PA,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
++
++	u8 rfseq_rx2tx_events_rev3_ipa[] = {
++		NPHY_REV3_RFSEQ_CMD_NOP,
++		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
++		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
++		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
++		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
++		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
++		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
++		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
++		NPHY_REV3_RFSEQ_CMD_END
++	};
++	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
++	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
++
++	s16 alpha0, alpha1, alpha2;
++	s16 beta0, beta1, beta2;
++	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
++	    stbc_data_weights;
++	u8 chan_freq_range = 0;
++	u16 dac_control = 0x0002;
++	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
++	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
++	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
++	u16 *aux_adc_vmid;
++	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
++	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
++	u16 *aux_adc_gain;
++	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
++	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
++	s32 min_nvar_val = 0x18d;
++	s32 min_nvar_offset_6mbps = 20;
++	u8 pdetrange;
++	u8 triso;
++	u16 regval;
++	u16 afectrl_adc_ctrl1_rev7 = 0x20;
++	u16 afectrl_adc_ctrl2_rev7 = 0x0;
++	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
++	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
++	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
++	u16 ipalvlshift_3p3_war_en = 0;
++	u16 rccal_bcap_val, rccal_scap_val;
++	u16 rccal_tx20_11b_bcap = 0;
++	u16 rccal_tx20_11b_scap = 0;
++	u16 rccal_tx20_11n_bcap = 0;
++	u16 rccal_tx20_11n_scap = 0;
++	u16 rccal_tx40_11n_bcap = 0;
++	u16 rccal_tx40_11n_scap = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
++	u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
++	u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
++	u16 tx_lpf_bw_ofdm_20mhz = 0;
++	u16 tx_lpf_bw_ofdm_40mhz = 0;
++	u16 tx_lpf_bw_11b = 0;
++	u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
++	u16 txgm_idac_bleed = 0;
++	bool rccal_ovrd = false;
++	u16 freq;
++	int coreNum;
++
++	if (CHSPEC_IS5G(pi->radio_chanspec))
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
++	else
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
++
++			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
++			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
++			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
++			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
++			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
++			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
++			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
++			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
++			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
++			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
++			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
++			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
++			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
++			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
++		}
++
++		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
++			write_phy_reg(pi, 0x23f, 0x1b0);
++			write_phy_reg(pi, 0x240, 0x1b0);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8))
++			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++					 2, 0x15e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
++					 rfseq_rx2tx_dacbufpu_rev7);
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
++		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
++
++		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
++		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
++		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
++
++		if (PHY_IPA(pi)) {
++
++			if (((pi->pubpi.radiorev == 5)
++			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				if ((pi->pubpi.radiorev == 5) &&
++				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
++
++					rccal_tx20_11n_bcap = rccal_bcap_val;
++					rccal_tx20_11n_scap = rccal_scap_val;
++					rccal_tx40_11n_bcap = 0xc;
++					rccal_tx40_11n_scap = 0xc;
++
++					rccal_ovrd = true;
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					tx_lpf_bw_ofdm_20mhz = 4;
++					tx_lpf_bw_11b = 1;
++
++					if (CHSPEC_IS2G(pi->radio_chanspec)) {
++						rccal_tx20_11n_bcap = 0xc;
++						rccal_tx20_11n_scap = 0xc;
++						rccal_tx40_11n_bcap = 0xa;
++						rccal_tx40_11n_scap = 0xa;
++					} else {
++						rccal_tx20_11n_bcap = 0x14;
++						rccal_tx20_11n_scap = 0x14;
++						rccal_tx40_11n_bcap = 0xf;
++						rccal_tx40_11n_scap = 0xf;
++					}
++
++					rccal_ovrd = true;
++				}
++			}
++
++		} else {
++
++			if (pi->pubpi.radiorev == 5) {
++
++				tx_lpf_bw_ofdm_20mhz = 1;
++				tx_lpf_bw_ofdm_40mhz = 3;
++
++				rccal_bcap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_BCAP_VAL);
++				rccal_scap_val =
++					read_radio_reg(
++						pi,
++						RADIO_2057_RCCAL_SCAP_VAL);
++
++				rccal_tx20_11b_bcap = rccal_bcap_val;
++				rccal_tx20_11b_scap = rccal_scap_val;
++
++				rccal_tx20_11n_bcap = 0x13;
++				rccal_tx20_11n_scap = 0x11;
++				rccal_tx40_11n_bcap = 0x13;
++				rccal_tx40_11n_scap = 0x11;
++
++				rccal_ovrd = true;
++			}
++		}
++
++		if (rccal_ovrd) {
++
++			rx2tx_lpf_rc_lut_tx20_11b =
++				(rccal_tx20_11b_bcap << 8) |
++				(rccal_tx20_11b_scap << 3) |
++				tx_lpf_bw_11b;
++			rx2tx_lpf_rc_lut_tx20_11n =
++				(rccal_tx20_11n_bcap << 8) |
++				(rccal_tx20_11n_scap << 3) |
++				tx_lpf_bw_ofdm_20mhz;
++			rx2tx_lpf_rc_lut_tx40_11n =
++				(rccal_tx40_11n_bcap << 8) |
++				(rccal_tx40_11n_scap << 3) |
++				tx_lpf_bw_ofdm_40mhz;
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x152 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11b);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x153 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x154 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx20_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x155 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x156 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x157 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x158 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++				wlc_phy_table_write_nphy(
++					pi, NPHY_TBL_ID_RFSEQ,
++					1,
++					0x159 + coreNum * 0x10,
++					16,
++					&rx2tx_lpf_rc_lut_tx40_11n);
++			}
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		}
++
++		write_phy_reg(pi, 0x32f, 0x3);
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
++		    (pi->pubpi.radiorev == 6)) {
++			if ((pi->sh->sromrev >= 8)
++			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
++				ipalvlshift_3p3_war_en = 1;
++
++			if (ipalvlshift_3p3_war_en) {
++				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
++						0x5);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
++						0x30);
++				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
++					     0x1);
++				or_radio_reg(pi,
++					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
++					     0x1);
++
++				ipa2g_mainbias = 0x1f;
++
++				ipa2g_casconv = 0x6f;
++
++				ipa2g_biasfilt = 0xaa;
++			} else {
++
++				ipa2g_mainbias = 0x2b;
++
++				ipa2g_casconv = 0x7f;
++
++				ipa2g_biasfilt = 0xee;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_IMAIN,
++							 ipa2g_mainbias);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum, IPA2G_CASCONV,
++							 ipa2g_casconv);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 IPA2G_BIAS_FILTER,
++							 ipa2g_biasfilt);
++				}
++			}
++		}
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6))
++					txgm_idac_bleed = 0x7f;
++
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					if (txgm_idac_bleed != 0)
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							TXGM_IDAC_BLEED,
++							txgm_idac_bleed);
++				}
++
++				if (pi->pubpi.radiorev == 5) {
++
++					for (coreNum = 0; coreNum <= 1;
++					     coreNum++) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_CASCONV,
++								 0x13);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 IPA2G_IMAIN,
++								 0x1f);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							IPA2G_BIAS_FILTER,
++							0xee);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, coreNum,
++								 PAD2G_IDACS,
++								 0x8a);
++						WRITE_RADIO_REG4(
++							pi, RADIO_2057,
++							CORE, coreNum,
++							PAD_BIAS_FILTER_BWS,
++							0x3e);
++					}
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					if (CHSPEC_IS40(pi->radio_chanspec) ==
++					    0) {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x14);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x12);
++					} else {
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 0,
++								 IPA2G_IMAIN,
++								 0x16);
++						WRITE_RADIO_REG4(pi, RADIO_2057,
++								 CORE, 1,
++								 IPA2G_IMAIN,
++								 0x16);
++					}
++				}
++
++			} else {
++				freq = CHAN5G_FREQ(CHSPEC_CHANNEL(
++							pi->radio_chanspec));
++				if (((freq >= 5180) && (freq <= 5230))
++				    || ((freq >= 5745) && (freq <= 5805))) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 0, IPA5G_BIAS_FILTER,
++							 0xff);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 1, IPA5G_BIAS_FILTER,
++							 0xff);
++				}
++			}
++		} else {
++
++			if (pi->pubpi.radiorev != 5) {
++				for (coreNum = 0; coreNum <= 1; coreNum++) {
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXMIX2G_TUNE_BOOST_PU,
++							 0x61);
++					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
++							 coreNum,
++							 TXGM_IDAC_BLEED, 0x70);
++				}
++			}
++		}
++
++		if (pi->pubpi.radiorev == 4) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl1_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl1_rev7);
++
++			for (coreNum = 0; coreNum <= 1; coreNum++) {
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_VCM_CAL_MASTER, 0x0);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_I, 0x3f);
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 AFE_SET_VCM_Q, 0x3f);
++			}
++		} else {
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
++			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x05, 16,
++						 &afectrl_adc_ctrl2_rev7);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
++						 0x15, 16,
++						 &afectrl_adc_ctrl2_rev7);
++
++			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
++		}
++
++		write_phy_reg(pi, 0x6a, 0x2);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
++					 &min_nvar_offset_6mbps);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
++					 &rfseq_pktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
++					 &rfseq_pktgn_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
++					 &rfseq_htpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
++					 &rfseq_cckpktgn_lpf_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
++					 &rfseq_tx2rx_lpf_h_hpc_rev7);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
++					 &rfseq_rx2tx_lpf_h_hpc_rev7);
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev7[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev7[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			}
++		} else if (pdetrange == 1) {
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x7c;
++				aux_adc_vmid_rev7_core1[3] = 0x7c;
++				aux_adc_gain_rev7[3] = 2;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x8c;
++				aux_adc_vmid_rev7_core1[3] = 0x8c;
++				aux_adc_gain_rev7[3] = 1;
++			}
++		} else if (pdetrange == 2) {
++			if (pi->pubpi.radioid == BCM2057_ID) {
++				if ((pi->pubpi.radiorev == 5)
++				    || (pi->pubpi.radiorev == 7)
++				    || (pi->pubpi.radiorev == 8)) {
++					if (chan_freq_range ==
++					    WL_CHAN_FREQ_RANGE_2G) {
++						aux_adc_vmid_rev7_core0[3] =
++							0x8c;
++						aux_adc_vmid_rev7_core1[3] =
++							0x8c;
++						aux_adc_gain_rev7[3] = 0;
++					} else {
++						aux_adc_vmid_rev7_core0[3] =
++							0x96;
++						aux_adc_vmid_rev7_core1[3] =
++							0x96;
++						aux_adc_gain_rev7[3] = 0;
++					}
++				}
++			}
++
++		} else if (pdetrange == 3) {
++			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x89;
++				aux_adc_vmid_rev7_core1[3] = 0x89;
++				aux_adc_gain_rev7[3] = 0;
++			}
++
++		} else if (pdetrange == 5) {
++
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				aux_adc_vmid_rev7_core0[3] = 0x80;
++				aux_adc_vmid_rev7_core1[3] = 0x80;
++				aux_adc_gain_rev7[3] = 3;
++			} else {
++				aux_adc_vmid_rev7_core0[3] = 0x70;
++				aux_adc_vmid_rev7_core1[3] = 0x70;
++				aux_adc_gain_rev7[3] = 2;
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
++					 &aux_adc_vmid_rev7_core0);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
++					 &aux_adc_vmid_rev7_core1);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
++					 &aux_adc_gain_rev7);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
++					 &aux_adc_gain_rev7);
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		write_phy_reg(pi, 0x23f, 0x1f8);
++		write_phy_reg(pi, 0x240, 0x1f8);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					1, 0, 32, &leg_data_weights);
++		leg_data_weights = leg_data_weights & 0xffffff;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 0, 32, &leg_data_weights);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		write_phy_reg(pi, 0x38, 0xC);
++		write_phy_reg(pi, 0x2ae, 0xC);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
++				       rfseq_tx2rx_events_rev3,
++				       rfseq_tx2rx_dlys_rev3,
++				       ARRAY_SIZE(rfseq_tx2rx_events_rev3));
++
++		if (PHY_IPA(pi))
++			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
++					       rfseq_rx2tx_events_rev3_ipa,
++					       rfseq_rx2tx_dlys_rev3_ipa,
++					       ARRAY_SIZE(rfseq_rx2tx_events_rev3_ipa));
++
++		if ((pi->sh->hw_phyrxchain != 0x3) &&
++		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
++
++			if (PHY_IPA(pi)) {
++				rfseq_rx2tx_dlys_rev3[5] = 59;
++				rfseq_rx2tx_dlys_rev3[6] = 1;
++				rfseq_rx2tx_events_rev3[7] =
++					NPHY_REV3_RFSEQ_CMD_END;
++			}
++
++			wlc_phy_set_rfseq_nphy(
++				pi, NPHY_RFSEQ_RX2TX,
++				rfseq_rx2tx_events_rev3,
++				rfseq_rx2tx_dlys_rev3,
++				ARRAY_SIZE(rfseq_rx2tx_events_rev3));
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			write_phy_reg(pi, 0x6a, 0x2);
++		else
++			write_phy_reg(pi, 0x6a, 0x9c40);
++
++		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
++
++		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		} else {
++			min_nvar_val = noise_var_tbl_rev3[3];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
++						 32, &min_nvar_val);
++
++			min_nvar_val = noise_var_tbl_rev3[127];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 127, 32, &min_nvar_val);
++		}
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
++					 &dac_control);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
++					 &dac_control);
++
++		pdetrange =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			pdetrange : pi->srom_fem2g.pdetrange;
++
++		if (pdetrange == 0) {
++			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++				aux_adc_vmid = aux_adc_vmid_rev4;
++				aux_adc_gain = aux_adc_gain_rev4;
++			} else {
++				aux_adc_vmid = aux_adc_vmid_rev3;
++				aux_adc_gain = aux_adc_gain_rev3;
++			}
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				switch (chan_freq_range) {
++				case WL_CHAN_FREQ_RANGE_5GL:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GM:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				case WL_CHAN_FREQ_RANGE_5GH:
++					aux_adc_vmid[3] = 0x89;
++					aux_adc_gain[3] = 0;
++					break;
++				default:
++					break;
++				}
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, aux_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, aux_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, aux_adc_gain);
++		} else if (pdetrange == 1) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, sk_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, sk_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, sk_adc_gain);
++		} else if (pdetrange == 2) {
++
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++				chan_freq_range =
++					wlc_phy_get_chan_freq_range_nphy(pi, 0);
++				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++					bcm_adc_vmid[3] = 0x8e;
++					bcm_adc_gain[3] = 0x03;
++				} else {
++					bcm_adc_vmid[3] = 0x94;
++					bcm_adc_gain[3] = 0x03;
++				}
++			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++				bcm_adc_vmid[3] = 0x84;
++				bcm_adc_gain[3] = 0x02;
++			}
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		} else if (pdetrange == 3) {
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if ((NREV_GE(pi->pubpi.phy_rev, 4))
++			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
++
++				u16 auxadc_vmid[] = {
++					0xa2, 0xb4, 0xb4, 0x270
++				};
++				u16 auxadc_gain[] = {
++					0x02, 0x02, 0x02, 0x00
++				};
++
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x08, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x18, 16, auxadc_vmid);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x0c, 16, auxadc_gain);
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_AFECTRL, 4,
++							 0x1c, 16, auxadc_gain);
++			}
++		} else if ((pdetrange == 4) || (pdetrange == 5)) {
++			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
++			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
++			u16 Vmid[2], Av[2];
++
++			chan_freq_range =
++				wlc_phy_get_chan_freq_range_nphy(pi, 0);
++			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
++				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
++				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			} else {
++				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
++				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
++				Av[0] = (pdetrange == 4) ? 2 : 0;
++				Av[1] = (pdetrange == 4) ? 2 : 0;
++			}
++
++			bcm_adc_vmid[3] = Vmid[0];
++			bcm_adc_gain[3] = Av[0];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x08, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x0c, 16, bcm_adc_gain);
++
++			bcm_adc_vmid[3] = Vmid[1];
++			bcm_adc_gain[3] = Av[1];
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x18, 16, bcm_adc_vmid);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
++						 0x1c, 16, bcm_adc_gain);
++		}
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
++				0x6);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
++				0x6);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
++				0x7);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
++				0x7);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
++				0x88);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
++				0x88);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
++				0x0);
++		write_radio_reg(pi,
++				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
++				0x0);
++
++		triso =
++			(CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
++			triso : pi->srom_fem2g.triso;
++		if (triso == 7) {
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
++			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
++		}
++
++		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
++
++		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
++		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
++		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
++		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
++		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
++			nss1_data_weights = 0x00088888;
++			ht_data_weights = 0x00088888;
++			stbc_data_weights = 0x00088888;
++		} else {
++			nss1_data_weights = 0x88888888;
++			ht_data_weights = 0x88888888;
++			stbc_data_weights = 0x88888888;
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 1, 32, &nss1_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 2, 32, &ht_data_weights);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
++					 1, 3, 32, &stbc_data_weights);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX0, 0x70);
++				write_radio_reg(pi,
++						RADIO_2056_TX_GMBB_IDAC |
++						RADIO_2056_TX1, 0x70);
++			}
++		}
++
++		if (!pi->edcrs_threshold_lock) {
++			write_phy_reg(pi, 0x224, 0x3eb);
++			write_phy_reg(pi, 0x225, 0x3eb);
++			write_phy_reg(pi, 0x226, 0x341);
++			write_phy_reg(pi, 0x227, 0x341);
++			write_phy_reg(pi, 0x228, 0x42b);
++			write_phy_reg(pi, 0x229, 0x42b);
++			write_phy_reg(pi, 0x22a, 0x381);
++			write_phy_reg(pi, 0x22b, 0x381);
++			write_phy_reg(pi, 0x22c, 0x42b);
++			write_phy_reg(pi, 0x22d, 0x42b);
++			write_phy_reg(pi, 0x22e, 0x381);
++			write_phy_reg(pi, 0x22f, 0x381);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++
++			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
++					      MHF4_BPHY_TXCORE0,
++					      MHF4_BPHY_TXCORE0, BRCM_BAND_ALL);
++		}
++	} else {
++
++		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
++		    (pi->sh->boardtype == 0x8b)) {
++			uint i;
++			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
++			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
++				rfseq_rx2tx_dlys[i] = war_dlys[i];
++		}
++
++		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
++		} else {
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
++		}
++
++		regval = 0x000a;
++		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
++		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			regval = 0xcdaa;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			regval = 0x0000;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
++
++			regval = 0x7aab;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
++
++			regval = 0x0800;
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
++			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
++		}
++
++		write_phy_reg(pi, 0xf8, 0x02d8);
++		write_phy_reg(pi, 0xf9, 0x0301);
++		write_phy_reg(pi, 0xfa, 0x02d8);
++		write_phy_reg(pi, 0xfb, 0x0301);
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
++				       rfseq_rx2tx_dlys,
++				       ARRAY_SIZE(rfseq_rx2tx_events));
++
++		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
++				       rfseq_tx2rx_dlys,
++				       ARRAY_SIZE(rfseq_tx2rx_events));
++
++		wlc_phy_workarounds_nphy_gainctrl(pi);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
++				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
++					       MHF3_NPHY_MLADV_WAR,
++					       MHF3_NPHY_MLADV_WAR,
++					       BRCM_BAND_ALL);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
++			write_phy_reg(pi, 0x1e3, 0x0);
++			write_phy_reg(pi, 0x1e4, 0x0);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
++
++		alpha0 = 293;
++		alpha1 = 435;
++		alpha2 = 261;
++		beta0 = 366;
++		beta1 = 205;
++		beta2 = 32;
++		write_phy_reg(pi, 0x145, alpha0);
++		write_phy_reg(pi, 0x146, alpha1);
++		write_phy_reg(pi, 0x147, alpha2);
++		write_phy_reg(pi, 0x148, beta0);
++		write_phy_reg(pi, 0x149, beta1);
++		write_phy_reg(pi, 0x14a, beta2);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
++
++			write_phy_reg(pi, 0x192, 0xb5);
++			write_phy_reg(pi, 0x193, 0xa4);
++			write_phy_reg(pi, 0x194, 0x0);
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0x221,
++				    NPHY_FORCESIG_DECODEGATEDCLKS,
++				    NPHY_FORCESIG_DECODEGATEDCLKS);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi)
++{
++	int j, type = 2;
++	u16 addr_offset = 0x2c5;
++
++	for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++)
++		write_phy_reg(pi, addr_offset + j,
++			      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
++}
++
++static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals)
++{
++
++	if (write == 0) {
++		vals[0] = read_phy_reg(pi, 0x2c);
++		vals[1] = read_phy_reg(pi, 0x42);
++	} else {
++		write_phy_reg(pi, 0x2c, vals[0]);
++		write_phy_reg(pi, 0x42, vals[1]);
++	}
++}
++
++static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi)
++{
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x5);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xe);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0);
++
++				if (!NREV_IS(pi->pubpi.phy_rev, 7))
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x1);
++				else
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIG, 0x31);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MUX, 0xc);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0);
++
++				if (pi->pubpi.radiorev != 5) {
++					if (!NREV_IS(pi->pubpi.phy_rev, 7))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x1);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++				}
++			}
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 0x0);
++		}
++	} else {
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
++				(CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
++				0x80);
++		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
++		WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
++					 0x3);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
++					 0x8);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
++					 0x0);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
++					 0x0);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x5);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIA, 0x0);
++				if (NREV_GE(pi->pubpi.phy_rev, 5))
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x31);
++				else
++					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
++							 core, TSSIG, 0x11);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xe);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MASTER, 0x9);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIA, 0x31);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TSSIG, 0x0);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 TX_SSI_MUX, 0xc);
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value,
++			     u8 core_mask, u8 off)
++{
++	u8 core_num;
++	u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
++		0, val_mask = 0;
++	u8 shift = 0, val_shift = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		en_mask = field;
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 2):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 1);
++				val_shift = 1;
++				break;
++			case (0x1 << 3):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 2);
++				val_shift = 2;
++				break;
++			case (0x1 << 4):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 4);
++				val_shift = 4;
++				break;
++			case (0x1 << 5):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 5);
++				val_shift = 5;
++				break;
++			case (0x1 << 6):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 7):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x1 << 7);
++				val_shift = 7;
++				break;
++			case (0x1 << 8):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 8);
++				val_shift = 8;
++				break;
++			case (0x1 << 11):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7a : 0x7d;
++				val_mask = (0x7 << 13);
++				val_shift = 13;
++				break;
++
++			case (0x1 << 9):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 0);
++				val_shift = 0;
++				break;
++
++			case (0x1 << 10):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
++				val_mask = (0x7 << 4);
++				val_shift = 4;
++				break;
++
++			case (0x1 << 12):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7b : 0x7e;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 13):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0x7c : 0x7f;
++				val_mask = (0xffff << 0);
++				val_shift = 0;
++				break;
++			case (0x1 << 14):
++				en_addr = (core_num == 0) ? 0xe7 : 0xec;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x3 << 6);
++				val_shift = 6;
++				break;
++			case (0x1 << 0):
++				en_addr = (core_num == 0) ? 0xe5 : 0xe6;
++				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
++				val_mask = (0x1 << 15);
++				val_shift = 15;
++				break;
++			default:
++				addr = 0xffff;
++				break;
++			}
++
++			if (off) {
++				and_phy_reg(pi, en_addr, ~en_mask);
++				and_phy_reg(pi, val_addr, ~val_mask);
++			} else {
++
++				if ((core_mask == 0)
++				    || (core_mask & (1 << core_num))) {
++					or_phy_reg(pi, en_addr, en_mask);
++
++					if (addr != 0xffff)
++						mod_phy_reg(pi, val_addr,
++							    val_mask,
++							    (value <<
++							     val_shift));
++				}
++			}
++		}
++	} else {
++
++		if (off) {
++			and_phy_reg(pi, 0xec, ~field);
++			value = 0x0;
++		} else {
++			or_phy_reg(pi, 0xec, field);
++		}
++
++		for (core_num = 0; core_num < 2; core_num++) {
++
++			switch (field) {
++			case (0x1 << 1):
++			case (0x1 << 9):
++			case (0x1 << 12):
++			case (0x1 << 13):
++			case (0x1 << 14):
++				addr = 0x78;
++
++				core_mask = 0x1;
++				break;
++			case (0x1 << 2):
++			case (0x1 << 3):
++			case (0x1 << 4):
++			case (0x1 << 5):
++			case (0x1 << 6):
++			case (0x1 << 7):
++			case (0x1 << 8):
++				addr = (core_num == 0) ? 0x7a : 0x7d;
++				break;
++			case (0x1 << 10):
++				addr = (core_num == 0) ? 0x7b : 0x7e;
++				break;
++			case (0x1 << 11):
++				addr = (core_num == 0) ? 0x7c : 0x7f;
++				break;
++			default:
++				addr = 0xffff;
++			}
++
++			switch (field) {
++			case (0x1 << 1):
++				mask = (0x7 << 3);
++				shift = 3;
++				break;
++			case (0x1 << 9):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 12):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 13):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 14):
++				mask = (0xf << 12);
++				shift = 12;
++				break;
++			case (0x1 << 2):
++				mask = (0x1 << 0);
++				shift = 0;
++				break;
++			case (0x1 << 3):
++				mask = (0x1 << 1);
++				shift = 1;
++				break;
++			case (0x1 << 4):
++				mask = (0x1 << 2);
++				shift = 2;
++				break;
++			case (0x1 << 5):
++				mask = (0x3 << 4);
++				shift = 4;
++				break;
++			case (0x1 << 6):
++				mask = (0x3 << 6);
++				shift = 6;
++				break;
++			case (0x1 << 7):
++				mask = (0x1 << 8);
++				shift = 8;
++				break;
++			case (0x1 << 8):
++				mask = (0x1 << 9);
++				shift = 9;
++				break;
++			case (0x1 << 10):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			case (0x1 << 11):
++				mask = 0x1fff;
++				shift = 0x0;
++				break;
++			default:
++				mask = 0x0;
++				shift = 0x0;
++				break;
++			}
++
++			if ((addr != 0xffff) && (core_mask & (1 << core_num)))
++				mod_phy_reg(pi, addr, mask, (value << shift));
++		}
++
++		or_phy_reg(pi, 0xec, (0x1 << 0));
++		or_phy_reg(pi, 0x78, (0x1 << 0));
++		udelay(1);
++		and_phy_reg(pi, 0xec, ~(0x1 << 0));
++	}
++}
++
++static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi)
++{
++	s32 rssi_buf[4];
++	s32 int_val;
++
++	if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
++
++		return;
++
++	if (PHY_IPA(pi))
++		wlc_phy_ipa_internal_tssi_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
++
++	udelay(20);
++	int_val =
++		wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
++				       1);
++	wlc_phy_stopplayback_nphy(pi);
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val >> 8) & 0xff);
++	} else {
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
++			(u8) ((int_val >> 24) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
++			(u8) ((int_val >> 8) & 0xff);
++
++		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
++			(u8) ((int_val >> 16) & 0xff);
++		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
++			(u8) ((int_val) & 0xff);
++	}
++
++}
++
++static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi)
++{
++	u8 idx, idx2, i, delta_ind;
++
++	for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++)
++		pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
++
++	for (i = 0; i < 4; i++) {
++		idx2 = 0;
++
++		delta_ind = 0;
++
++		switch (i) {
++		case 0:
++
++			if (CHSPEC_IS40(pi->radio_chanspec)
++			    && NPHY_IS_SROM_REINTERPRET) {
++				idx = TXP_FIRST_MCS_40_SISO;
++			} else {
++				idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++				      TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
++				delta_ind = 1;
++			}
++			break;
++
++		case 1:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
++			break;
++
++		case 2:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
++			break;
++
++		case 3:
++
++			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
++			      TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
++			break;
++		}
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx++];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		idx = idx + 1 - delta_ind;
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
++			pi->tx_power_offset[idx];
++	}
++}
++
++static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	s16 a1[2], b0[2], b1[2];
++	s8 target_pwr_qtrdbm[2];
++	s32 num, den, pwr_est;
++	u8 chan_freq_range;
++	u8 idle_tssi[2];
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[64];
++	u8 core;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	or_phy_reg(pi, 0x122, (0x1 << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
++	else
++		or_phy_reg(pi, 0x1e7, (0x1 << 15));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	if (pi->sh->sromrev < 4) {
++		idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++		idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++		a1[0] = -424;
++		a1[1] = -424;
++		b0[0] = 5612;
++		b0[1] = 5612;
++		b1[1] = -1393;
++		b1[0] = -1393;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GL:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GM:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
++			break;
++		case WL_CHAN_FREQ_RANGE_5GH:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
++			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
++			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
++			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
++			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
++			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
++			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
++			break;
++		default:
++			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
++			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
++			a1[0] = -424;
++			a1[1] = -424;
++			b0[0] = 5612;
++			b0[1] = 5612;
++			b1[1] = -1393;
++			b1[0] = -1393;
++			break;
++		}
++	}
++
++	/* use the provided transmit power */
++	target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
++	target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->srom_fem2g.tssipos)
++			or_phy_reg(pi, 0x1e9, (0x1 << 14));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			for (core = 0; core <= 1; core++) {
++				if (PHY_IPA(pi)) {
++					if (CHSPEC_IS2G(pi->radio_chanspec))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xe);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TX_SSI_MUX,
++								 0xc);
++				}
++			}
++		} else {
++			if (PHY_IPA(pi)) {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1,
++						(CHSPEC_IS5G
++						 (pi->radio_chanspec)) ?
++						 0xc : 0xe);
++			} else {
++
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX0, 0x11);
++				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
++						RADIO_2056_TX1, 0x11);
++			}
++		}
++	}
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else
++		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
++	else if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0),
++			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++
++	write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
++
++	write_phy_reg(pi, 0x1e9,
++		      (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
++
++	write_phy_reg(pi, 0x1ea,
++		      (target_pwr_qtrdbm[0] << 0) |
++		      (target_pwr_qtrdbm[1] << 8));
++
++	tbl_len = 64;
++	tbl_offset = 0;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		for (idx = 0; idx < tbl_len; idx++) {
++			num = 8 *
++			      (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
++			den = 32768 + a1[tbl_id - 26] * idx;
++			pwr_est = max(((4 * num + den / 2) / den), -8);
++			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
++				if (idx <=
++				    (uint) (31 - idle_tssi[tbl_id - 26] + 1))
++					pwr_est =
++						max(pwr_est,
++						    target_pwr_qtrdbm
++						    [tbl_id - 26] + 1);
++			}
++			regval[idx] = (u32) pwr_est;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
++				 pi->adj_pwr_tbl_nphy);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev4n6;
++			else if (pi->pubpi.radiorev == 3)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev3;
++			else if (pi->pubpi.radiorev == 5)
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev5;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_2g_2057rev7;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
++		}
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				tx_pwrctrl_tbl =
++					nphy_tpc_txgain_ipa_5g_2057rev7;
++		} else {
++			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
++		}
++	}
++
++	return tx_pwrctrl_tbl;
++}
++
++static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi)
++{
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_rssical_chanspec_2G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_2G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_2G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_2G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_2G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_2G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_2G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_2G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_2G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_2G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_2G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_2G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_2G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_2G[11]);
++
++	} else {
++		if (pi->nphy_rssical_chanspec_5G == 0)
++			return;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		} else {
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[0]);
++			mod_radio_reg(pi,
++				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
++				      RADIO_2056_VCM_MASK,
++				      pi->rssical_cache.
++				      rssical_radio_regs_5G[1]);
++		}
++
++		write_phy_reg(pi, 0x1a6,
++			      pi->rssical_cache.rssical_phyregs_5G[0]);
++		write_phy_reg(pi, 0x1ac,
++			      pi->rssical_cache.rssical_phyregs_5G[1]);
++		write_phy_reg(pi, 0x1b2,
++			      pi->rssical_cache.rssical_phyregs_5G[2]);
++		write_phy_reg(pi, 0x1b8,
++			      pi->rssical_cache.rssical_phyregs_5G[3]);
++		write_phy_reg(pi, 0x1a4,
++			      pi->rssical_cache.rssical_phyregs_5G[4]);
++		write_phy_reg(pi, 0x1aa,
++			      pi->rssical_cache.rssical_phyregs_5G[5]);
++		write_phy_reg(pi, 0x1b0,
++			      pi->rssical_cache.rssical_phyregs_5G[6]);
++		write_phy_reg(pi, 0x1b6,
++			      pi->rssical_cache.rssical_phyregs_5G[7]);
++		write_phy_reg(pi, 0x1a5,
++			      pi->rssical_cache.rssical_phyregs_5G[8]);
++		write_phy_reg(pi, 0x1ab,
++			      pi->rssical_cache.rssical_phyregs_5G[9]);
++		write_phy_reg(pi, 0x1b1,
++			      pi->rssical_cache.rssical_phyregs_5G[10]);
++		write_phy_reg(pi, 0x1b7,
++			      pi->rssical_cache.rssical_phyregs_5G[11]);
++	}
++}
++
++static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi)
++{
++	u16 txcal_gain[2];
++
++	pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
++	pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				txcal_gain);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
++	} else {
++		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
++		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 txcal_gain);
++}
++
++static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi)
++{
++	bool save_bbmult = false;
++	u8 txcal_index_2057_rev5n7 = 0;
++	u8 txcal_index_2057_rev3n4n6 = 10;
++
++	if (pi->use_int_tx_iqlo_cal_nphy) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6)) {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev3n4n6;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev3n4n6;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev3n4n6,
++					false);
++			} else {
++
++				pi->nphy_txcal_pwr_idx[0] =
++					txcal_index_2057_rev5n7;
++				pi->nphy_txcal_pwr_idx[1] =
++					txcal_index_2057_rev5n7;
++				wlc_phy_txpwr_index_nphy(
++					pi, 3,
++					txcal_index_2057_rev5n7,
++					false);
++			}
++			save_bbmult = true;
++
++		} else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
++			wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
++			if (pi->sh->hw_phytxchain != 3) {
++				pi->nphy_txcal_pwr_idx[1] =
++					pi->nphy_txcal_pwr_idx[0];
++				wlc_phy_txpwr_index_nphy(pi, 3,
++							 pi->
++							 nphy_txcal_pwr_idx[0],
++							 true);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				} else {
++					pi->nphy_txcal_pwr_idx[0] = 80;
++					pi->nphy_txcal_pwr_idx[1] = 80;
++					wlc_phy_txpwr_index_nphy(pi, 3, 80,
++								 false);
++					save_bbmult = true;
++				}
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
++			if (PHY_IPA(pi)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					wlc_phy_cal_txgainctrl_nphy(pi, 12,
++								    false);
++				else
++					wlc_phy_cal_txgainctrl_nphy(pi, 14,
++								    false);
++			} else {
++				wlc_phy_internal_cal_txgain_nphy(pi);
++				save_bbmult = true;
++			}
++		}
++
++	} else {
++		wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
++	}
++
++	if (save_bbmult)
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++					&pi->nphy_txcal_bbmult);
++}
++
++static void
++wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value,
++				 u8 core_code)
++{
++	u16 mask;
++	u16 val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			if (core_code == RADIO_MIMO_CORESEL_CORE1
++			    && core == PHY_CORE_1)
++				continue;
++			else if (core_code == RADIO_MIMO_CORESEL_CORE2
++				 && core == PHY_CORE_0)
++				continue;
++
++			if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++				mask = (0x1 << 10);
++				val = 1 << 10;
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					    0x92, mask, val);
++			}
++
++			if (field == NPHY_RfctrlIntc_override_OFF) {
++
++				write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
++					      0x92, 0);
++
++				wlc_phy_force_rfseq_nphy(pi,
++							 NPHY_RFSEQ_RESET2RX);
++			} else if (field == NPHY_RfctrlIntc_override_TRSW) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 6) | (0x1 << 7);
++
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 10));
++
++					and_phy_reg(pi, 0x2ff, (u16)
++						    ~(0x3 << 14));
++					or_phy_reg(pi, 0x2ff, (0x1 << 13));
++					or_phy_reg(pi, 0x2ff, (0x1 << 0));
++				} else {
++
++					mask = (0x1 << 6) |
++					       (0x1 << 7) |
++					       (0x1 << 8) | (0x1 << 9);
++					val = value << 6;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					mask = (0x1 << 0);
++					val = 1 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++
++					mask = (core == PHY_CORE_0) ?
++					       (0x1 << 0) : (0x1 << 1);
++					val = 1 << ((core == PHY_CORE_0) ?
++						    0 : 1);
++					mod_phy_reg(pi, 0x78, mask, val);
++
++					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
++						  != 0), 10000);
++					if (WARN(read_phy_reg(pi, 0x78) & val,
++						 "HW error: override failed"))
++						return;
++
++					mask = (0x1 << 0);
++					val = 0 << 0;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xe7 : 0xec,
++						    mask, val);
++				}
++			} else if (field == NPHY_RfctrlIntc_override_PA) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++					mask = (0x1 << 4) | (0x1 << 5);
++
++					if (CHSPEC_IS5G(pi->radio_chanspec))
++						val = value << 5;
++					else
++						val = value << 4;
++
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++
++					or_phy_reg(pi,
++						   (core ==
++						    PHY_CORE_0) ? 0x91 : 0x92,
++						   (0x1 << 12));
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 5);
++						val = value << 5;
++					} else {
++						mask = (0x1 << 4);
++						val = value << 4;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_PU) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 0);
++						val = value << 0;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 2);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 2);
++						val = value << 2;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 0);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 0);
++						val = value << 0;
++					} else {
++						mask = (0x1 << 2);
++						val = value << 2;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			} else if (field ==
++				   NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++						mask = (0x1 << 1);
++						val = value << 1;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 3);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					} else {
++
++						mask = (0x1 << 3);
++						val = value << 3;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, val);
++
++						mask = (0x1 << 1);
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0x91
++							    : 0x92, mask, 0);
++					}
++
++					mask = (0x1 << 11);
++					val = 1 << 11;
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				} else {
++
++					if (CHSPEC_IS5G(pi->radio_chanspec)) {
++						mask = (0x1 << 1);
++						val = value << 1;
++					} else {
++						mask = (0x1 << 3);
++						val = value << 3;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0x91 : 0x92,
++						    mask, val);
++				}
++			}
++		}
++	}
++}
++
++void
++wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower,
++			    bool debug)
++{
++	int gainctrl_loopidx;
++	uint core;
++	u16 m0m1, curr_m0m1;
++	s32 delta_power;
++	s32 txpwrindex;
++	s32 qdBm_power[2];
++	u16 orig_BBConfig;
++	u16 phy_saveregs[4];
++	u32 freq_test;
++	u16 ampl_test = 250;
++	uint stepsize;
++	bool phyhang_avoid_state = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		stepsize = 2;
++	else
++		stepsize = 1;
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		freq_test = 5000;
++	else
++		freq_test = 2500;
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phyhang_avoid_state = pi->phyhang_avoid;
++	pi->phyhang_avoid = false;
++
++	phy_saveregs[0] = read_phy_reg(pi, 0x91);
++	phy_saveregs[1] = read_phy_reg(pi, 0x92);
++	phy_saveregs[2] = read_phy_reg(pi, 0xe7);
++	phy_saveregs[3] = read_phy_reg(pi, 0xec);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (!debug) {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++	} else {
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x7, RADIO_MIMO_CORESEL_CORE2);
++	}
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
++
++		for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
++		     gainctrl_loopidx++) {
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			if (core == PHY_CORE_0)
++				curr_m0m1 = m0m1 & 0xff00;
++			else
++				curr_m0m1 = m0m1 & 0x00ff;
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
++
++			udelay(50);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++
++			delta_power = (dBm_targetpower * 4) - qdBm_power[core];
++
++			txpwrindex -= stepsize * delta_power;
++			if (txpwrindex < 0)
++				txpwrindex = 0;
++			else if (txpwrindex > 127)
++				txpwrindex = 127;
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 4) &&
++				    (pi->srom_fem5g.extpagain == 3)) {
++					if (txpwrindex < 30)
++						txpwrindex = 30;
++				}
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++				    (pi->srom_fem2g.extpagain == 3)) {
++					if (txpwrindex < 50)
++						txpwrindex = 50;
++				}
++			}
++
++			wlc_phy_txpwr_index_nphy(pi, (1 << core),
++						 (u8) txpwrindex, true);
++		}
++
++		pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
++
++		if (debug) {
++			u16 radio_gain;
++			u16 dbg_m0m1;
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++
++			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
++					     false);
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
++			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
++
++			udelay(100);
++
++			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
++						 NPHY_CAL_TSSISAMPS);
++
++			wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
++						&radio_gain);
++
++			mdelay(4000);
++			pi->nphy_bb_mult_save = 0;
++			wlc_phy_stopplayback_nphy(pi);
++		}
++	}
++
++	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
++	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	write_phy_reg(pi, 0x91, phy_saveregs[0]);
++	write_phy_reg(pi, 0x92, phy_saveregs[1]);
++	write_phy_reg(pi, 0xe7, phy_saveregs[2]);
++	write_phy_reg(pi, 0xec, phy_saveregs[3]);
++
++	pi->phyhang_avoid = phyhang_avoid_state;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_savecal_nphy(struct brcms_phy *pi)
++{
++	void *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_2G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_2G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_2G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_2G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_2G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_2G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++	} else {
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_FINE_Q |
++					       RADIO_2056_TX1);
++
++			pi->calibration_cache.txcal_radio_regs_5G[4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX0);
++			pi->calibration_cache.txcal_radio_regs_5G[6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_I |
++					       RADIO_2056_TX1);
++			pi->calibration_cache.txcal_radio_regs_5G[7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_LOFT_COARSE_Q |
++					       RADIO_2056_TX1);
++		} else {
++			pi->calibration_cache.txcal_radio_regs_5G[0] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[1] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
++			pi->calibration_cache.txcal_radio_regs_5G[2] =
++			       read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
++			pi->calibration_cache.txcal_radio_regs_5G[3] =
++			       read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
++		}
++
++		pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++	}
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			txcal_radio_regs[2 * coreNum] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_I);
++			txcal_radio_regs[2 * coreNum + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_FINE_Q);
++
++			txcal_radio_regs[2 * coreNum + 4] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_I);
++			txcal_radio_regs[2 * coreNum + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++						LOFT_COARSE_Q);
++		}
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi)
++{
++	struct nphy_iq_comp tx_comp;
++
++	wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, &tx_comp);
++
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
++	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
++}
++
++static void wlc_phy_restorecal_nphy(struct brcms_phy *pi)
++{
++	u16 *loft_comp;
++	u16 txcal_coeffs_bphy[4];
++	u16 *tbl_ptr;
++	int coreNum;
++	u16 *txcal_radio_regs = NULL;
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (pi->nphy_iqcal_chanspec_2G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
++	} else {
++		if (pi->nphy_iqcal_chanspec_5G == 0)
++			return;
++
++		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
++		loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, tbl_ptr);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		txcal_coeffs_bphy[0] = tbl_ptr[0];
++		txcal_coeffs_bphy[1] = tbl_ptr[1];
++		txcal_coeffs_bphy[2] = tbl_ptr[2];
++		txcal_coeffs_bphy[3] = tbl_ptr[3];
++	} else {
++		txcal_coeffs_bphy[0] = 0;
++		txcal_coeffs_bphy[1] = 0;
++		txcal_coeffs_bphy[2] = 0;
++		txcal_coeffs_bphy[3] = 0;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
++				 txcal_coeffs_bphy);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_tx_iq_war_nphy(pi);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_2G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_2G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_2G);
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			txcal_radio_regs =
++				pi->calibration_cache.txcal_radio_regs_5G;
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_FINE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[4]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX0,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[5]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_I |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[6]);
++			write_radio_reg(pi,
++					RADIO_2056_TX_LOFT_COARSE_Q |
++					RADIO_2056_TX1,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[7]);
++		} else {
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[0]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[1]);
++			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[2]);
++			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
++					pi->calibration_cache.
++					txcal_radio_regs_5G[3]);
++		}
++
++		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
++					  &pi->calibration_cache.
++					  rxcal_coeffs_5G);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_I,
++					 txcal_radio_regs[2 * coreNum]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_FINE_Q,
++					 txcal_radio_regs[2 * coreNum + 1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_I,
++					 txcal_radio_regs[2 * coreNum + 4]);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
++					 LOFT_COARSE_Q,
++					 txcal_radio_regs[2 * coreNum + 5]);
++		}
++	}
++}
++
++static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi)
++{
++	u32 idx;
++	u16 iqloCalbuf[7];
++	u32 iqcomp, locomp, curr_locomp;
++	s8 locomp_i, locomp_q;
++	s8 curr_locomp_i, curr_locomp_q;
++	u32 tbl_id, tbl_len, tbl_offset;
++	u32 regval[128];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
++
++	tbl_len = 128;
++	tbl_offset = 320;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++		iqcomp =
++			(tbl_id ==
++			 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
++			(iqloCalbuf[1] & 0x3ff)
++			: (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
++			(iqloCalbuf[3] & 0x3ff);
++
++		for (idx = 0; idx < tbl_len; idx++)
++			regval[idx] = iqcomp;
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	tbl_offset = 448;
++	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
++	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
++
++		locomp =
++			(u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
++		locomp_i = (s8) ((locomp >> 8) & 0xff);
++		locomp_q = (s8) ((locomp) & 0xff);
++		for (idx = 0; idx < tbl_len; idx++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				curr_locomp_i = locomp_i;
++				curr_locomp_q = locomp_q;
++			} else {
++				curr_locomp_i = (s8) ((locomp_i *
++						       nphy_tpc_loscale[idx] +
++						       128) >> 8);
++				curr_locomp_q =
++					(s8) ((locomp_q *
++					       nphy_tpc_loscale[idx] +
++					       128) >> 8);
++			}
++			curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
++			curr_locomp |= (u32) (curr_locomp_q & 0xff);
++			regval[idx] = curr_locomp;
++		}
++		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
++					 regval);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi)
++{
++	u8 tx_lpf_bw = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			tx_lpf_bw = 3;
++		else
++			tx_lpf_bw = 1;
++
++		if (PHY_IPA(pi)) {
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 5;
++			else
++				tx_lpf_bw = 4;
++		}
++
++		write_phy_reg(pi, 0xe8,
++			      (tx_lpf_bw << 0) |
++			      (tx_lpf_bw << 3) |
++			      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++
++		if (PHY_IPA(pi)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec))
++				tx_lpf_bw = 4;
++			else
++				tx_lpf_bw = 1;
++
++			write_phy_reg(pi, 0xe9,
++				      (tx_lpf_bw << 0) |
++				      (tx_lpf_bw << 3) |
++				      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						((pi->nphy_rccal_value +
++						  reduction_factr) | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_anarxlpf_adjusted) {
++				write_radio_reg(pi,
++						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++						 RADIO_2056_RX0),
++						(pi->nphy_rccal_value | 0x80));
++
++				pi->nphy_anarxlpf_adjusted = false;
++			}
++		}
++	}
++}
++
++static void
++wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones,
++				 int *tone_id_buf, u32 *noise_var_buf)
++{
++	int i;
++	u32 offset;
++	int tone_id;
++	int tbllen =
++		CHSPEC_IS40(pi->radio_chanspec) ?
++		NPHY_NOISEVAR_TBLLEN40 : NPHY_NOISEVAR_TBLLEN20;
++
++	if (pi->nphy_noisevars_adjusted) {
++		for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
++			tone_id = pi->nphy_saved_noisevars.tone_id[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id *
++				   2) + 1) : (tbllen + (tone_id * 2) + 1);
++			wlc_phy_table_write_nphy(
++				pi, NPHY_TBL_ID_NOISEVAR, 1,
++				offset, 32,
++				&pi->nphy_saved_noisevars.min_noise_vars[i]);
++		}
++
++		pi->nphy_saved_noisevars.bufcount = 0;
++		pi->nphy_noisevars_adjusted = false;
++	}
++
++	if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
++		pi->nphy_saved_noisevars.bufcount = 0;
++
++		for (i = 0; i < ntones; i++) {
++			tone_id = tone_id_buf[i];
++			offset = (tone_id >= 0) ?
++				 ((tone_id * 2) + 1) :
++				 (tbllen + (tone_id * 2) + 1);
++			pi->nphy_saved_noisevars.tone_id[i] = tone_id;
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						offset, 32,
++						&pi->nphy_saved_noisevars.
++						min_noise_vars[i]);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
++						 offset, 32, &noise_var_buf[i]);
++			pi->nphy_saved_noisevars.bufcount++;
++		}
++
++		pi->nphy_noisevars_adjusted = true;
++	}
++}
++
++static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr)
++{
++	u16 regval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
++		    CHSPEC_IS40(pi->radio_chanspec)) {
++			if (!pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				pi->nphy_crsminpwr[0] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				pi->nphy_crsminpwr[1] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				pi->nphy_crsminpwr[2] = regval & 0xff;
++				regval &= 0xff00;
++				regval |= (u16) minpwr;
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = true;
++			}
++		} else {
++			if (pi->nphy_crsminpwr_adjusted) {
++				regval = read_phy_reg(pi, 0x27d);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[0];
++				write_phy_reg(pi, 0x27d, regval);
++
++				regval = read_phy_reg(pi, 0x280);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[1];
++				write_phy_reg(pi, 0x280, regval);
++
++				regval = read_phy_reg(pi, 0x283);
++				regval &= 0xff00;
++				regval |= pi->nphy_crsminpwr[2];
++				write_phy_reg(pi, 0x283, regval);
++
++				pi->nphy_crsminpwr_adjusted = false;
++			}
++		}
++	}
++}
++
++static void wlc_phy_spurwar_nphy(struct brcms_phy *pi)
++{
++	u16 cur_channel = 0;
++	int nphy_adj_tone_id_buf[] = { 57, 58 };
++	u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
++	bool isAdjustNoiseVar = false;
++	uint numTonesAdjust = 0;
++	u32 tempval = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++		if (pi->nphy_gband_spurwar_en) {
++
++			wlc_phy_adjust_rx_analpfbw_nphy(
++				pi,
++				NPHY_ANARXLPFBW_REDUCTIONFACT);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((cur_channel == 11)
++				    && CHSPEC_IS40(pi->radio_chanspec))
++					wlc_phy_adjust_min_noisevar_nphy(
++						pi, 2,
++						nphy_adj_tone_id_buf,
++						nphy_adj_noise_var_buf);
++				else
++					wlc_phy_adjust_min_noisevar_nphy(pi, 0,
++									 NULL,
++									 NULL);
++			}
++
++			wlc_phy_adjust_crsminpwr_nphy(pi,
++						     NPHY_ADJUSTED_MINCRSPOWER);
++		}
++
++		if ((pi->nphy_gband_spurwar2_en)
++		    && CHSPEC_IS2G(pi->radio_chanspec)) {
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				switch (cur_channel) {
++				case 3:
++					nphy_adj_tone_id_buf[0] = 57;
++					nphy_adj_tone_id_buf[1] = 58;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 4:
++					nphy_adj_tone_id_buf[0] = 41;
++					nphy_adj_tone_id_buf[1] = 42;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 5:
++					nphy_adj_tone_id_buf[0] = 25;
++					nphy_adj_tone_id_buf[1] = 26;
++					nphy_adj_noise_var_buf[0] = 0x24f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 6:
++					nphy_adj_tone_id_buf[0] = 9;
++					nphy_adj_tone_id_buf[1] = 10;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 7:
++					nphy_adj_tone_id_buf[0] = 121;
++					nphy_adj_tone_id_buf[1] = 122;
++					nphy_adj_noise_var_buf[0] = 0x18f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 8:
++					nphy_adj_tone_id_buf[0] = 105;
++					nphy_adj_tone_id_buf[1] = 106;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x25f;
++					isAdjustNoiseVar = true;
++					break;
++				case 9:
++					nphy_adj_tone_id_buf[0] = 89;
++					nphy_adj_tone_id_buf[1] = 90;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				case 10:
++					nphy_adj_tone_id_buf[0] = 73;
++					nphy_adj_tone_id_buf[1] = 74;
++					nphy_adj_noise_var_buf[0] = 0x22f;
++					nphy_adj_noise_var_buf[1] = 0x24f;
++					isAdjustNoiseVar = true;
++					break;
++				default:
++					isAdjustNoiseVar = false;
++					break;
++				}
++			}
++
++			if (isAdjustNoiseVar) {
++				numTonesAdjust = ARRAY_SIZE(nphy_adj_tone_id_buf);
++
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi,
++					numTonesAdjust,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++
++				tempval = 0;
++
++			} else {
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++			}
++		}
++
++		if ((pi->nphy_aband_spurwar_en) &&
++		    (CHSPEC_IS5G(pi->radio_chanspec))) {
++			switch (cur_channel) {
++			case 54:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x25f;
++				break;
++			case 38:
++			case 102:
++			case 118:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			case 134:
++				nphy_adj_tone_id_buf[0] = 32;
++				nphy_adj_noise_var_buf[0] = 0x21f;
++				break;
++			case 151:
++				nphy_adj_tone_id_buf[0] = 16;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			case 153:
++			case 161:
++				nphy_adj_tone_id_buf[0] = 48;
++				nphy_adj_noise_var_buf[0] = 0x23f;
++				break;
++			default:
++				nphy_adj_tone_id_buf[0] = 0;
++				nphy_adj_noise_var_buf[0] = 0x0;
++				break;
++			}
++
++			if (nphy_adj_tone_id_buf[0]
++			    && nphy_adj_noise_var_buf[0])
++				wlc_phy_adjust_min_noisevar_nphy(
++					pi, 1,
++					nphy_adj_tone_id_buf,
++					nphy_adj_noise_var_buf);
++			else
++				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
++								 NULL);
++		}
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++}
++
++void wlc_phy_init_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++	u16 clip1_ths[2];
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool do_nphy_cal = false;
++	uint core;
++	u32 d11_clk_ctl_st;
++	bool do_rssi_cal = false;
++
++	core = 0;
++
++	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
++		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
++
++	if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
++	    ((pi->sh->chippkg == BCM4717_PKG_ID) ||
++	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
++		if ((pi->sh->boardflags & BFL_EXTLNA) &&
++		    (CHSPEC_IS2G(pi->radio_chanspec)))
++			ai_cc_reg(pi->sh->sih,
++				  offsetof(struct chipcregs, chipcontrol),
++				  0x40, 0x40);
++	}
++
++	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
++	    CHSPEC_IS40(pi->radio_chanspec)) {
++
++		d11_clk_ctl_st = bcma_read32(pi->d11core,
++					     D11REGOFFS(clk_ctl_st));
++		bcma_mask32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			    ~(CCS_FORCEHT | CCS_HTAREQ));
++
++		bcma_write32(pi->d11core, D11REGOFFS(clk_ctl_st),
++			     d11_clk_ctl_st);
++	}
++
++	pi->use_int_tx_iqlo_cal_nphy =
++		(PHY_IPA(pi) ||
++		 (NREV_GE(pi->pubpi.phy_rev, 7) ||
++		  (NREV_GE(pi->pubpi.phy_rev, 5)
++		   && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
++
++	pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
++
++	pi->nphy_deaf_count = 0;
++
++	wlc_phy_tbl_init_nphy(pi);
++
++	pi->nphy_crsminpwr_adjusted = false;
++	pi->nphy_noisevars_adjusted = false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xe7, 0);
++		write_phy_reg(pi, 0xec, 0);
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_phy_reg(pi, 0x342, 0);
++			write_phy_reg(pi, 0x343, 0);
++			write_phy_reg(pi, 0x346, 0);
++			write_phy_reg(pi, 0x347, 0);
++		}
++		write_phy_reg(pi, 0xe5, 0);
++		write_phy_reg(pi, 0xe6, 0);
++	} else {
++		write_phy_reg(pi, 0xec, 0);
++	}
++
++	write_phy_reg(pi, 0x91, 0);
++	write_phy_reg(pi, 0x92, 0);
++	if (NREV_LT(pi->pubpi.phy_rev, 6)) {
++		write_phy_reg(pi, 0x93, 0);
++		write_phy_reg(pi, 0x94, 0);
++	}
++
++	and_phy_reg(pi, 0xa1, ~3);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0x8f, 0);
++		write_phy_reg(pi, 0xa5, 0);
++	} else {
++		write_phy_reg(pi, 0xa5, 0);
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++	else if (NREV_LT(pi->pubpi.phy_rev, 2))
++		mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++	write_phy_reg(pi, 0x203, 32);
++	write_phy_reg(pi, 0x201, 32);
++
++	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
++		write_phy_reg(pi, 0x20d, 160);
++	else
++		write_phy_reg(pi, 0x20d, 184);
++
++	write_phy_reg(pi, 0x13a, 200);
++
++	write_phy_reg(pi, 0x70, 80);
++
++	write_phy_reg(pi, 0x1ff, 48);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 8))
++		wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
++
++	wlc_phy_stf_chain_upd_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		write_phy_reg(pi, 0x180, 0xaa8);
++		write_phy_reg(pi, 0x181, 0x9a4);
++	}
++
++	if (PHY_IPA(pi)) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 0), (1) << 0);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7),
++				    (pi->nphy_papd_epsilon_offset[core]) << 7);
++
++		}
++
++		wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++		wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
++	}
++
++	wlc_phy_workarounds_nphy(pi);
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
++
++	wlc_phy_pa_override_nphy(pi, OFF);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	wlc_phy_pa_override_nphy(pi, ON);
++
++	wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		wlc_phy_bphy_init_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_txpwr_fixpower_nphy(pi);
++
++	wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u32 *tx_pwrctrl_tbl = NULL;
++		u16 idx;
++		s16 pga_gn = 0;
++		s16 pad_gn = 0;
++		s32 rfpwr_offset;
++
++		if (PHY_IPA(pi)) {
++			tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (NREV_IS(pi->pubpi.phy_rev, 3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev3;
++				else if (NREV_IS(pi->pubpi.phy_rev, 4))
++					tx_pwrctrl_tbl =
++						(pi->srom_fem5g.extpagain ==
++						 3) ?
++						nphy_tpc_5GHz_txgain_HiPwrEPA :
++						nphy_tpc_5GHz_txgain_rev4;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_5GHz_txgain_rev5;
++			} else {
++				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++					if (pi->pubpi.radiorev == 5)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev5;
++					else if (pi->pubpi.radiorev == 3)
++						tx_pwrctrl_tbl =
++						   nphy_tpc_txgain_epa_2057rev3;
++				} else {
++					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3))
++						tx_pwrctrl_tbl =
++						       nphy_tpc_txgain_HiPwrEPA;
++					else
++						tx_pwrctrl_tbl =
++							nphy_tpc_txgain_rev3;
++				}
++			}
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, tx_pwrctrl_tbl);
++
++		pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
++				rfpwr_offset = get_rf_pwr_offset(pi, pga_gn,
++								 pad_gn);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++		} else {
++
++			for (idx = 0; idx < 128; idx++) {
++				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
++				if (CHSPEC_IS2G(pi->radio_chanspec))
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_2g
++								       [pga_gn];
++				else
++					rfpwr_offset = (s16)
++						 nphy_papd_pga_gain_delta_ipa_5g
++								       [pga_gn];
++
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE1TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++				wlc_phy_table_write_nphy(
++					pi,
++					NPHY_TBL_ID_CORE2TXPWRCTL,
++					1, 576 + idx, 32,
++					&rfpwr_offset);
++			}
++
++		}
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
++					 192, 32, nphy_tpc_txgain);
++	}
++
++	if (pi->sh->phyrxchain != 0x3)
++		wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi,
++					     pi->sh->phyrxchain);
++
++	if (PHY_PERICAL_MPHASE_PENDING(pi))
++		wlc_phy_cal_perical_mphase_restart(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_rssical_chanspec_2G == 0) :
++			      (pi->nphy_rssical_chanspec_5G == 0);
++
++		if (do_rssi_cal)
++			wlc_phy_rssi_cal_nphy(pi);
++		else
++			wlc_phy_restore_rssical_nphy(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy(pi);
++	}
++
++	if (!SCAN_RM_IN_PROGRESS(pi))
++		do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
++			      (pi->nphy_iqcal_chanspec_2G == 0) :
++			      (pi->nphy_iqcal_chanspec_5G == 0);
++
++	if (!pi->do_initcal)
++		do_nphy_cal = false;
++
++	if (do_nphy_cal) {
++
++		target_gain = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (pi->antsel_type == ANTSEL_2x3)
++			wlc_phy_antsel_init((struct brcms_phy_pub *) pi,
++					    true);
++
++		if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				pi->nphy_cal_orig_pwr_idx[0] =
++					pi->nphy_txpwrindex[PHY_CORE_0]
++					.
++					index_internal;
++				pi->nphy_cal_orig_pwr_idx[1] =
++					pi->nphy_txpwrindex[PHY_CORE_1]
++					.
++					index_internal;
++
++				wlc_phy_precal_txgain_nphy(pi);
++				target_gain =
++					wlc_phy_get_tx_gain_nphy(pi);
++			}
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, target_gain, true,
++				    false) == 0) {
++				if (wlc_phy_cal_rxiq_nphy
++					    (pi, target_gain, 2,
++					    false) == 0)
++					wlc_phy_savecal_nphy(pi);
++
++			}
++		} else if (pi->mphase_cal_phase_id ==
++			   MPHASE_CAL_STATE_IDLE) {
++			wlc_phy_cal_perical((struct brcms_phy_pub *) pi,
++					    PHY_PERICAL_PHYINIT);
++		}
++	} else {
++		wlc_phy_restorecal_nphy(pi);
++	}
++
++	wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
++
++		write_phy_reg(pi, 0x70, 50);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	wlc_phy_spurwar_nphy(pi);
++
++}
++
++static void wlc_phy_resetcca_nphy(struct brcms_phy *pi)
++{
++	u16 val;
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++	val = read_phy_reg(pi, 0x01);
++	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
++	udelay(1);
++	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
++
++	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++}
++
++void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en)
++{
++	u16 rfctrlintc_override_val;
++
++	if (!en) {
++
++		pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
++		pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			rfctrlintc_override_val = 0x1480;
++		else if (NREV_GE(pi->pubpi.phy_rev, 3))
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
++		else
++			rfctrlintc_override_val =
++				CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++
++		write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++		write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	} else {
++		write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
++		write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
++	}
++
++}
++
++void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi)
++{
++
++	u16 txrx_chain =
++		(NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
++	bool CoreActv_override = false;
++
++	if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			and_phy_reg(pi, 0xa0, ~0x20);
++	} else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) {
++		txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
++		CoreActv_override = true;
++
++		if (NREV_LE(pi->pubpi.phy_rev, 2))
++			or_phy_reg(pi, 0xa0, 0x20);
++	}
++
++	mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
++
++	if (CoreActv_override) {
++		pi->nphy_perical = PHY_PERICAL_DISABLE;
++		or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	} else {
++		pi->nphy_perical = PHY_PERICAL_MPHASE;
++		and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
++	}
++}
++
++void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
++{
++	u16 regval;
++	u16 tbl_buf[16];
++	uint i;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++	u16 tbl_opcode;
++	bool suspend;
++
++	pi->sh->phyrxchain = rxcore_bitmask;
++
++	if (!pi->sh->clk)
++		return;
++
++	suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			 MCTL_EN_MAC));
++	if (!suspend)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	regval = read_phy_reg(pi, 0xa2);
++	regval &= ~(0xf << 4);
++	regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
++	write_phy_reg(pi, 0xa2, regval);
++
++	if ((rxcore_bitmask & 0x3) != 0x3) {
++
++		write_phy_reg(pi, 0x20e, 1);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry == -1) {
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							ARRAY_SIZE(tbl_buf), 80,
++							16, tbl_buf);
++
++				for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
++					if (tbl_buf[i] ==
++					    NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
++						pi->rx2tx_biasentry = (u8) i;
++						tbl_opcode =
++							NPHY_REV3_RFSEQ_CMD_NOP;
++						wlc_phy_table_write_nphy(
++							pi,
++							NPHY_TBL_ID_RFSEQ,
++							1, i,
++							16,
++							&tbl_opcode);
++						break;
++					} else if (tbl_buf[i] ==
++						   NPHY_REV3_RFSEQ_CMD_END)
++						break;
++				}
++			}
++		}
++	} else {
++
++		write_phy_reg(pi, 0x20e, 30);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if (pi->rx2tx_biasentry != -1) {
++				tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
++				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++							 1, pi->rx2tx_biasentry,
++							 16, &tbl_opcode);
++				pi->rx2tx_biasentry = -1;
++			}
++		}
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!suspend)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
++{
++	u16 regval, rxen_bits;
++	struct brcms_phy *pi = (struct brcms_phy *) pih;
++
++	regval = read_phy_reg(pi, 0xa2);
++	rxen_bits = (regval >> 4) & 0xf;
++
++	return (u8) rxen_bits;
++}
++
++bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi)
++{
++	return PHY_IPA(pi);
++}
++
++void wlc_phy_cal_init_nphy(struct brcms_phy *pi)
++{
++}
++
++static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++	and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
++
++}
++
++static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
++{
++	struct radio_20xx_regs *regs_2057_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++		regs_2057_ptr = regs_2057_rev4;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++		   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++
++			if (NREV_IS(pi->pubpi.phy_rev, 8))
++				regs_2057_ptr = regs_2057_rev5;
++			else if (NREV_IS(pi->pubpi.phy_rev, 9))
++				regs_2057_ptr = regs_2057_rev5v1;
++			break;
++
++		case 7:
++
++			regs_2057_ptr = regs_2057_rev7;
++			break;
++
++		case 8:
++
++			regs_2057_ptr = regs_2057_rev8;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
++}
++
++static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi)
++{
++	u16 rcal_reg = 0;
++	int i;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (pi->pubpi.radiorev == 5) {
++
++			and_phy_reg(pi, 0x342, ~(0x1 << 1));
++
++			udelay(10);
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x1);
++		}
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
++
++		udelay(10);
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
++			if (rcal_reg & 0x1)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib2"))
++			return 0;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
++
++		rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
++
++		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
++		if (pi->pubpi.radiorev == 5) {
++
++			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
++			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
++				      0x0);
++		}
++
++		if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++			mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
++				      rcal_reg);
++			mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
++				      rcal_reg << 2);
++		}
++
++	} else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		u16 savereg;
++
++		savereg =
++			read_radio_reg(
++				pi,
++				RADIO_2056_SYN_PLL_MAST2 |
++				RADIO_2056_SYN);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg | 0x7);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++		udelay(10);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x9);
++
++		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++			rcal_reg = read_radio_reg(
++				pi,
++				RADIO_2056_SYN_RCAL_CODE_OUT |
++				RADIO_2056_SYN);
++			if (rcal_reg & 0x80)
++				break;
++
++			udelay(100);
++		}
++
++		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
++			 "HW error: radio calib3"))
++			return 0;
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x1);
++
++		rcal_reg =
++			read_radio_reg(pi,
++				       RADIO_2056_SYN_RCAL_CODE_OUT |
++				       RADIO_2056_SYN);
++
++		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
++				0x0);
++
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
++				savereg);
++
++		return rcal_reg & 0x1f;
++	}
++	return rcal_reg & 0x3e;
++}
++
++static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi)
++{
++	u16 rccal_valid;
++	int i;
++	bool chip43226_6362A0;
++
++	chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
++			    || (pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6));
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	rccal_valid = 0;
++	if (chip43226_6362A0) {
++		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
++
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
++	} else {
++		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
++		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
++		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
++	}
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
++
++	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
++		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
++		if (rccal_valid & 0x2)
++			break;
++
++		udelay(500);
++	}
++
++	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
++		return 0;
++
++	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
++
++	return rccal_valid;
++}
++
++static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi)
++{
++
++	mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
++	mdelay(2);
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
++	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
++
++	if (pi->phy_init_por) {
++		wlc_phy_radio205x_rcal(pi);
++		wlc_phy_radio2057_rccal(pi);
++	}
++
++	mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
++}
++
++static void wlc_phy_radio_init_2056(struct brcms_phy *pi)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++	const struct radio_regs *regs_TX_2056_ptr = NULL;
++	const struct radio_regs *regs_RX_2056_ptr = NULL;
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++		regs_SYN_2056_ptr = regs_SYN_2056;
++		regs_TX_2056_ptr = regs_TX_2056;
++		regs_RX_2056_ptr = regs_RX_2056;
++	} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++		regs_TX_2056_ptr = regs_TX_2056_A1;
++		regs_RX_2056_ptr = regs_RX_2056_A1;
++	} else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			regs_TX_2056_ptr = regs_TX_2056_rev5;
++			regs_RX_2056_ptr = regs_RX_2056_rev5;
++			break;
++
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			regs_TX_2056_ptr = regs_TX_2056_rev6;
++			regs_RX_2056_ptr = regs_RX_2056_rev6;
++			break;
++
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			regs_TX_2056_ptr = regs_TX_2056_rev7;
++			regs_RX_2056_ptr = regs_RX_2056_rev7;
++			break;
++
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			regs_TX_2056_ptr = regs_TX_2056_rev8;
++			regs_RX_2056_ptr = regs_RX_2056_rev8;
++			break;
++
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			regs_TX_2056_ptr = regs_TX_2056_rev11;
++			regs_RX_2056_ptr = regs_RX_2056_rev11;
++			break;
++
++		default:
++			break;
++		}
++	}
++
++	wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
++
++	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
++
++	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
++}
++
++static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi)
++{
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
++	udelay(1000);
++	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
++
++	if ((pi->sh->boardflags2 & BFL2_LEGACY)
++	    || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN))
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
++	else
++		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
++
++	mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
++
++	if (pi->phy_init_por)
++		wlc_phy_radio205x_rcal(pi);
++}
++
++static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi)
++{
++
++	and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
++	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
++
++	or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
++}
++
++static void wlc_phy_radio_init_2055(struct brcms_phy *pi)
++{
++	wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
++}
++
++static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi)
++{
++
++	and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
++		      ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
++
++	if (((pi->sh->sromrev >= 4)
++	     && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
++	    || ((pi->sh->sromrev < 4))) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
++		and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
++	write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
++
++	and_radio_reg(pi, RADIO_2055_CAL_MISC,
++		      ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
++
++	or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
++
++	udelay(1000);
++
++	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
++
++	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
++
++	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
++		  RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
++		 "HW error: radio calibration1\n"))
++		return;
++
++	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
++		      ~(RADIO_2055_CAL_LPO_ENABLE));
++
++	wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
++
++	mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
++		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
++	if (pi->nphy_gain_boost) {
++		and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++		and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			      ~(RADIO_2055_GAINBST_DISABLE));
++	} else {
++		or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++		or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
++			     RADIO_2055_GAINBST_DISABLE);
++	}
++
++	udelay(2);
++}
++
++void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on)
++{
++	if (on) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (!pi->radio_is_on) {
++				wlc_phy_radio_preinit_205x(pi);
++				wlc_phy_radio_init_2057(pi);
++				wlc_phy_radio_postinit_2057(pi);
++			}
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_radio_preinit_205x(pi);
++			wlc_phy_radio_init_2056(pi);
++			wlc_phy_radio_postinit_2056(pi);
++
++			wlc_phy_chanspec_set((struct brcms_phy_pub *) pi,
++					     pi->radio_chanspec);
++		} else {
++			wlc_phy_radio_preinit_2055(pi);
++			wlc_phy_radio_init_2055(pi);
++			wlc_phy_radio_postinit_2055(pi);
++		}
++
++		pi->radio_is_on = true;
++
++	} else {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX0, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX0, 0);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PADG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAA_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_PGAG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++			mod_radio_reg(pi,
++				      RADIO_2056_TX_MIXA_BOOST_TUNE |
++				      RADIO_2056_TX1, 0xf0, 0);
++			write_radio_reg(pi,
++					RADIO_2056_TX_MIXG_BOOST_TUNE |
++					RADIO_2056_TX1, 0);
++
++			pi->radio_is_on = false;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
++			pi->radio_is_on = false;
++		}
++
++	}
++}
++
++static bool
++wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f,
++		       const struct chan_info_nphy_radio2057 **t0,
++		       const struct chan_info_nphy_radio205x **t1,
++		       const struct chan_info_nphy_radio2057_rev5 **t2,
++		       const struct chan_info_nphy_2055 **t3)
++{
++	uint i;
++	const struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL;
++	const struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL;
++	u32 tbl_len = 0;
++
++	int freq = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
++
++		} else if (NREV_IS(pi->pubpi.phy_rev, 8)
++			   || NREV_IS(pi->pubpi.phy_rev, 9)) {
++			switch (pi->pubpi.radiorev) {
++
++			case 5:
++
++				if (pi->pubpi.radiover == 0x0) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev8_2057_rev5;
++					tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev5);
++
++				} else if (pi->pubpi.radiover == 0x1) {
++
++					chan_info_tbl_p_2 =
++						chan_info_nphyrev9_2057_rev5v1;
++					tbl_len = ARRAY_SIZE(
++						chan_info_nphyrev9_2057_rev5v1);
++
++				}
++				break;
++
++			case 7:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev7;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev7);
++				break;
++
++			case 8:
++				chan_info_tbl_p_0 =
++					chan_info_nphyrev8_2057_rev8;
++				tbl_len = ARRAY_SIZE(
++						  chan_info_nphyrev8_2057_rev8);
++				break;
++
++			default:
++				break;
++			}
++		} else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
++
++			chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
++		} else {
++			goto fail;
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (pi->pubpi.radiorev == 5) {
++
++				if (chan_info_tbl_p_2[i].chan == channel)
++					break;
++			} else {
++
++				if (chan_info_tbl_p_0[i].chan == channel)
++					break;
++			}
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		if (pi->pubpi.radiorev == 5) {
++			*t2 = &chan_info_tbl_p_2[i];
++			freq = chan_info_tbl_p_2[i].freq;
++		} else {
++			*t0 = &chan_info_tbl_p_0[i];
++			freq = chan_info_tbl_p_0[i].freq;
++		}
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_IS(pi->pubpi.phy_rev, 3)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
++			chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
++			tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
++		} else if (NREV_IS(pi->pubpi.phy_rev, 5)
++			   || NREV_IS(pi->pubpi.phy_rev, 6)) {
++			switch (pi->pubpi.radiorev) {
++			case 5:
++				chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
++				break;
++			case 6:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
++				break;
++			case 7:
++			case 9:
++				chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
++				tbl_len =
++					ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
++				break;
++			case 8:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
++				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
++				break;
++			case 11:
++				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
++				tbl_len = ARRAY_SIZE(
++						    chan_info_nphyrev6_2056v11);
++				break;
++			default:
++				break;
++			}
++		}
++
++		for (i = 0; i < tbl_len; i++) {
++			if (chan_info_tbl_p_1[i].chan == channel)
++				break;
++		}
++
++		if (i >= tbl_len)
++			goto fail;
++
++		*t1 = &chan_info_tbl_p_1[i];
++		freq = chan_info_tbl_p_1[i].freq;
++
++	} else {
++		for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
++			if (chan_info_nphy_2055[i].chan == channel)
++				break;
++
++		if (i >= ARRAY_SIZE(chan_info_nphy_2055))
++			goto fail;
++
++		*t3 = &chan_info_nphy_2055[i];
++		freq = chan_info_nphy_2055[i].freq;
++	}
++
++	*f = freq;
++	return true;
++
++fail:
++	*f = WL_CHAN_FREQ_RANGE_2G;
++	return false;
++}
++
++u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (channel == 0)
++		channel = CHSPEC_CHANNEL(pi->radio_chanspec);
++
++	wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		return WL_CHAN_FREQ_RANGE_2G;
++
++	if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GL;
++	else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN))
++		return WL_CHAN_FREQ_RANGE_5GM;
++	else
++		return WL_CHAN_FREQ_RANGE_5GH;
++}
++
++static void
++wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_2055 *ci)
++{
++
++	write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
++	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
++	write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
++	write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
++	write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
++			ci->RF_core1_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
++			ci->RF_core1_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
++			ci->RF_core1_tx_pga_pad_tn);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
++			ci->RF_core1_tx_mx_bgtrim);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
++			ci->RF_core2_lgbuf_a_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
++			ci->RF_core2_lgbuf_g_tune);
++	write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
++			ci->RF_core2_tx_pga_pad_tn);
++	write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
++			ci->RF_core2_tx_mx_bgtrim);
++
++	udelay(50);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
++
++	BRCMS_PHY_WAR_PR51571(pi);
++
++	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi,
++				 const struct chan_info_nphy_radio205x *ci)
++{
++	const struct radio_regs *regs_SYN_2056_ptr = NULL;
++
++	write_radio_reg(pi,
++			RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_vcocal2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
++			ci->RF_SYN_pll_refdiv);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_mmd1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter1);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter2);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter3);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter4);
++	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
++			ci->RF_SYN_pll_loopfilter5);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr27);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr28);
++	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
++			ci->RF_SYN_reserved_addr29);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_VCOBUF1);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_MIXER2);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF3);
++	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
++			ci->RF_SYN_logen_BUF4);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
++			ci->RF_RX0_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
++			ci->RF_TX0_mixg_boost_tune);
++
++	write_radio_reg(pi,
++			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnaa_tune);
++	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
++			ci->RF_RX1_lnag_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_intpag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pada_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_padg_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgaa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_pgag_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixa_boost_tune);
++	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
++			ci->RF_TX1_mixg_boost_tune);
++
++	if (NREV_IS(pi->pubpi.phy_rev, 3))
++		regs_SYN_2056_ptr = regs_SYN_2056;
++	else if (NREV_IS(pi->pubpi.phy_rev, 4))
++		regs_SYN_2056_ptr = regs_SYN_2056_A1;
++	else {
++		switch (pi->pubpi.radiorev) {
++		case 5:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
++			break;
++		case 6:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
++			break;
++		case 7:
++		case 9:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
++			break;
++		case 8:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
++			break;
++		case 11:
++			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
++			break;
++		}
++	}
++	if (CHSPEC_IS2G(pi->radio_chanspec))
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
++	else
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++				RADIO_2056_SYN,
++				(u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
++
++	if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0xb);
++			write_radio_reg(pi,
++					RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0x14);
++		}
++	}
++
++	if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
++	    (CHSPEC_IS2G(pi->radio_chanspec))) {
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
++				0x1f);
++		write_radio_reg(pi,
++				RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
++				0xb);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
++				0x20);
++	}
++
++	if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
++					RADIO_2056_SYN, 0x1f);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
++					RADIO_2056_SYN, 0x5);
++			write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
++					RADIO_2056_SYN, 0xc);
++		}
++	}
++
++	if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
++		u16 pag_boost_tune;
++		u16 padg_boost_tune;
++		u16 pgag_boost_tune;
++		u16 mixg_boost_tune;
++		u16 bias, cascbias;
++		uint core;
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (NREV_GE(pi->pubpi.phy_rev, 5)) {
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_IDAC, 0xcc);
++
++				bias = 0x25;
++				cascbias = 0x20;
++
++				if ((pi->sh->chip ==
++				     BCM43224_CHIP_ID)
++				    || (pi->sh->chip ==
++					BCM43225_CHIP_ID)) {
++					if (pi->sh->chippkg ==
++					    BCM43224_FAB_SMIC) {
++						bias = 0x2a;
++						cascbias = 0x38;
++					}
++				}
++
++				pag_boost_tune = 0x4;
++				pgag_boost_tune = 0x03;
++				padg_boost_tune = 0x77;
++				mixg_boost_tune = 0x65;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, cascbias);
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_BOOST_TUNE,
++						 pag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PGAG_BOOST_TUNE,
++						 pgag_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 PADG_BOOST_TUNE,
++						 padg_boost_tune);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 MIXG_BOOST_TUNE,
++						 mixg_boost_tune);
++			} else {
++
++				bias = (pi->bw == WL_CHANSPEC_BW_40) ?
++				       0x40 : 0x20;
++
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IMAIN_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_IAUX_STAT, bias);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_CASCBIAS, 0x30);
++			}
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
++					 0xee);
++		}
++	}
++
++	if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
++	    && CHSPEC_IS5G(pi->radio_chanspec)) {
++		u16 paa_boost_tune;
++		u16 pada_boost_tune;
++		u16 pgaa_boost_tune;
++		u16 mixa_boost_tune;
++		u16 freq, pabias, cascbias;
++		uint core;
++
++		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
++
++		if (freq < 5150) {
++
++			paa_boost_tune = 0xa;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xf;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5340) {
++
++			paa_boost_tune = 0x8;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xfb;
++			mixa_boost_tune = 0xf;
++		} else if (freq < 5650) {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			pgaa_boost_tune = 0xb;
++			mixa_boost_tune = 0xf;
++		} else {
++
++			paa_boost_tune = 0x0;
++			pada_boost_tune = 0x77;
++			if (freq != 5825)
++				pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
++			else
++				pgaa_boost_tune = 6;
++
++			mixa_boost_tune = 0xf;
++		}
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_BOOST_TUNE, paa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_BOOST_TUNE, pada_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PGAA_BOOST_TUNE, pgaa_boost_tune);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 MIXA_BOOST_TUNE, mixa_boost_tune);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 TXSPARE1, 0x30);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PA_SPARE2, 0xee);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 PADA_CASCBIAS, 0x3);
++
++			cascbias = 0x30;
++
++			if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++			    (pi->sh->chip == BCM43225_CHIP_ID)) {
++				if (pi->sh->chippkg == BCM43224_FAB_SMIC)
++					cascbias = 0x35;
++			}
++
++			pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IAUX_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_IMAIN_STAT, pabias);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_CASCBIAS, cascbias);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
++			      (1 << 2));
++		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
++		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
++	}
++
++	udelay(300);
++}
++
++static void
++wlc_phy_chanspec_radio2057_setup(
++	struct brcms_phy *pi,
++	const struct chan_info_nphy_radio2057 *ci,
++	const struct chan_info_nphy_radio2057_rev5 *
++	ci2)
++{
++	int coreNum;
++	u16 txmix2g_tune_boost_pu = 0;
++	u16 pad2g_tune_pus = 0;
++
++	if (pi->pubpi.radiorev == 5) {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci2->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci2->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci2->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci2->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci2->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci2->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
++				ci2->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
++		write_radio_reg(pi,
++				RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci2->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci2->RF_logen_indbuf2g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci2->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci2->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci2->RF_lna2g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci2->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci2->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci2->RF_lna2g_tune_core1);
++
++	} else {
++
++		write_radio_reg(pi,
++				RADIO_2057_VCOCAL_COUNTVAL0,
++				ci->RF_vcocal_countval0);
++		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
++				ci->RF_vcocal_countval1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
++				ci->RF_rfpll_refmaster_sparextalsize);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++				ci->RF_rfpll_loopfilter_r1);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++				ci->RF_rfpll_loopfilter_c2);
++		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++				ci->RF_rfpll_loopfilter_c1);
++		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
++		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
++		write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
++		write_radio_reg(pi,
++				RADIO_2057_LOGEN_MX2G_TUNE,
++				ci->RF_logen_mx2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
++				ci->RF_logen_mx5g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
++				ci->RF_logen_indbuf2g_tune);
++		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
++				ci->RF_logen_indbuf5g_tune);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
++				ci->RF_txmix2g_tune_boost_pu_core0);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++				ci->RF_pad2g_tune_pus_core0);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
++				ci->RF_pga_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
++				ci->RF_txmix5g_boost_tune_core0);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
++				ci->RF_pad5g_tune_misc_pus_core0);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
++				ci->RF_lna2g_tune_core0);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
++				ci->RF_lna5g_tune_core0);
++
++		write_radio_reg(pi,
++				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
++				ci->RF_txmix2g_tune_boost_pu_core1);
++		write_radio_reg(pi,
++				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++				ci->RF_pad2g_tune_pus_core1);
++		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
++				ci->RF_pga_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
++				ci->RF_txmix5g_boost_tune_core1);
++		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
++				ci->RF_pad5g_tune_misc_pus_core1);
++		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
++				ci->RF_lna2g_tune_core1);
++		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
++				ci->RF_lna5g_tune_core1);
++	}
++
++	if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x3f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++	} else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
++		   (pi->pubpi.radiorev == 8)) {
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1b);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0xa);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0xa);
++		} else {
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
++					0x1f);
++			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
++					0x8);
++			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
++					0x8);
++		}
++
++	}
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (PHY_IPA(pi)) {
++			if (pi->pubpi.radiorev == 3)
++				txmix2g_tune_boost_pu = 0x6b;
++
++			if (pi->pubpi.radiorev == 5)
++				pad2g_tune_pus = 0x73;
++
++		} else {
++			if (pi->pubpi.radiorev != 5) {
++				pad2g_tune_pus = 0x3;
++
++				txmix2g_tune_boost_pu = 0x61;
++			}
++		}
++
++		for (coreNum = 0; coreNum <= 1; coreNum++) {
++
++			if (txmix2g_tune_boost_pu != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 TXMIX2G_TUNE_BOOST_PU,
++						 txmix2g_tune_boost_pu);
++
++			if (pad2g_tune_pus != 0)
++				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
++						 PAD2G_TUNE_PUS,
++						 pad2g_tune_pus);
++		}
++	}
++
++	udelay(50);
++
++	wlc_phy_radio205x_vcocal_nphy(pi);
++}
++
++static void
++wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
++			    const struct nphy_sfo_cfg *ci)
++{
++	u16 val;
++
++	val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
++	if (CHSPEC_IS5G(chanspec) && !val) {
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			   (BBCFG_RESETCCA | BBCFG_RESETRX));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++
++		or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
++	} else if (!CHSPEC_IS5G(chanspec) && val) {
++
++		and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
++
++		val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
++		      (val | MAC_PHY_FORCE_CLK));
++
++		and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
++			    (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
++
++		bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
++	}
++
++	write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
++	write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
++	write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
++
++	write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
++	write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
++	write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
++
++	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
++
++		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
++	} else {
++		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
++					NPHY_ClassifierCtrl_ofdm_en);
++
++		if (CHSPEC_IS2G(chanspec))
++			and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
++	}
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF)
++		wlc_phy_txpwr_fixpower_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		wlc_phy_adjust_lnagaintbl_nphy(pi);
++
++	wlc_phy_txlpfbw_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)
++	    && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
++		u8 spuravoid = 0;
++
++		val = CHSPEC_CHANNEL(chanspec);
++		if (!CHSPEC_IS40(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				if ((val == 13) || (val == 14) || (val == 153))
++					spuravoid = 1;
++			} else if (((val >= 5) && (val <= 8)) || (val == 13)
++				   || (val == 14)) {
++				spuravoid = 1;
++			}
++		} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (val == 54)
++				spuravoid = 1;
++		} else {
++			if (pi->nphy_aband_spurwar_en &&
++			    ((val == 38) || (val == 102)
++			     || (val == 118)))
++				spuravoid = 1;
++		}
++
++		if (pi->phy_spuravoid == SPURAVOID_FORCEON)
++			spuravoid = 1;
++
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
++		si_pmu_spuravoid_pllupdate(pi->sh->sih, spuravoid);
++		wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
++
++		if ((pi->sh->chip == BCM43224_CHIP_ID) ||
++		    (pi->sh->chip == BCM43225_CHIP_ID)) {
++			if (spuravoid == 1) {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x5341);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			} else {
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_l),
++					     0x8889);
++				bcma_write16(pi->d11core,
++					     D11REGOFFS(tsf_clk_frac_h), 0x8);
++			}
++		}
++
++		wlapi_bmac_core_phypll_reset(pi->sh->physhim);
++
++		mod_phy_reg(pi, 0x01, (0x1 << 15),
++			    ((spuravoid > 0) ? (0x1 << 15) : 0));
++
++		wlc_phy_resetcca_nphy(pi);
++
++		pi->phy_isspuravoid = (spuravoid > 0);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0x17e, 0x3830);
++
++	wlc_phy_spurwar_nphy(pi);
++}
++
++void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec)
++{
++	int freq;
++	const struct chan_info_nphy_radio2057 *t0 = NULL;
++	const struct chan_info_nphy_radio205x *t1 = NULL;
++	const struct chan_info_nphy_radio2057_rev5 *t2 = NULL;
++	const struct chan_info_nphy_2055 *t3 = NULL;
++
++	if (!wlc_phy_chan2freq_nphy
++		    (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
++		return;
++
++	wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
++
++	if (CHSPEC_BW(chanspec) != pi->bw)
++		wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
++
++	if (CHSPEC_IS40(chanspec)) {
++		if (CHSPEC_SB_UPPER(chanspec)) {
++			or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
++		} else {
++			and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				and_phy_reg(pi, 0x310,
++					    (~PRIM_SEL_UP20 & 0xffff));
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
++					      0x2,
++					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
++					       : 0));
++			}
++
++			wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(pi->pubpi.radiorev == 5) ?
++				(const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) :
++				(const struct nphy_sfo_cfg *)&(t0->PHY_BW1a));
++
++		} else {
++
++			mod_radio_reg(pi,
++				      RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
++				      0x4,
++				      (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
++			wlc_phy_chanspec_radio2056_setup(pi, t1);
++
++			wlc_phy_chanspec_nphy_setup(pi, chanspec,
++				(const struct nphy_sfo_cfg *) &(t1->PHY_BW1a));
++		}
++
++	} else {
++
++		mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
++			      (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
++			       : (0x05 << 4)));
++
++		wlc_phy_chanspec_radio2055_setup(pi, t3);
++		wlc_phy_chanspec_nphy_setup(pi, chanspec,
++					    (const struct nphy_sfo_cfg *)
++					     &(t3->PHY_BW1a));
++	}
++
++}
++
++void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
++{
++	struct brcms_phy *pi = (struct brcms_phy *) ppi;
++	u16 mask = 0xfc00;
++	u32 mc = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
++
++		if (!lut_init)
++			return;
++
++		if (pi->srom_fem2g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x02, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x03, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x08, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x0C, 16, &v3);
++		}
++
++		if (pi->srom_fem5g.antswctrllut == 0) {
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x12, 16, &v0);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x13, 16, &v1);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x18, 16, &v2);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
++						 1, 0x1C, 16, &v3);
++		}
++	} else {
++
++		write_phy_reg(pi, 0xc8, 0x0);
++		write_phy_reg(pi, 0xc9, 0x0);
++
++		bcma_chipco_gpio_control(&pi->d11core->bus->drv_cc, mask, mask);
++
++		mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		mc &= ~MCTL_GPOUT_SEL_MASK;
++		bcma_write32(pi->d11core, D11REGOFFS(maccontrol), mc);
++
++		bcma_set16(pi->d11core, D11REGOFFS(psm_gpio_oe), mask);
++
++		bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), ~mask);
++
++		if (lut_init) {
++			write_phy_reg(pi, 0xf8, 0x02d8);
++			write_phy_reg(pi, 0xf9, 0x0301);
++			write_phy_reg(pi, 0xfa, 0x02d8);
++			write_phy_reg(pi, 0xfb, 0x0301);
++		}
++	}
++}
++
++u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
++{
++	u16 curr_ctl, new_ctl;
++	bool suspended = false;
++
++	if (D11REV_IS(pi->sh->corerev, 16)) {
++		suspended = (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			     MCTL_EN_MAC) ? false : true;
++		if (!suspended)
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++	}
++
++	curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
++
++	new_ctl = (curr_ctl & (~mask)) | (val & mask);
++
++	mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
++
++	if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
++		wlapi_enable_mac(pi->sh->physhim);
++
++	return new_ctl;
++}
++
++void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd)
++{
++	u16 trigger_mask, status_mask;
++	u16 orig_RfseqCoreActv;
++
++	switch (cmd) {
++	case NPHY_RFSEQ_RX2TX:
++		trigger_mask = NPHY_RfseqTrigger_rx2tx;
++		status_mask = NPHY_RfseqStatus_rx2tx;
++		break;
++	case NPHY_RFSEQ_TX2RX:
++		trigger_mask = NPHY_RfseqTrigger_tx2rx;
++		status_mask = NPHY_RfseqStatus_tx2rx;
++		break;
++	case NPHY_RFSEQ_RESET2RX:
++		trigger_mask = NPHY_RfseqTrigger_reset2rx;
++		status_mask = NPHY_RfseqStatus_reset2rx;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINH:
++		trigger_mask = NPHY_RfseqTrigger_updategainh;
++		status_mask = NPHY_RfseqStatus_updategainh;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINL:
++		trigger_mask = NPHY_RfseqTrigger_updategainl;
++		status_mask = NPHY_RfseqStatus_updategainl;
++		break;
++	case NPHY_RFSEQ_UPDATEGAINU:
++		trigger_mask = NPHY_RfseqTrigger_updategainu;
++		status_mask = NPHY_RfseqStatus_updategainu;
++		break;
++	default:
++		return;
++	}
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1,
++		   (NPHY_RfseqMode_CoreActv_override |
++		    NPHY_RfseqMode_Trigger_override));
++	or_phy_reg(pi, 0xa3, trigger_mask);
++	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
++}
++
++static void
++wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value,
++				     u8 core_mask, u8 off)
++{
++	u16 rfmxgain = 0, lpfgain = 0;
++	u16 tgain = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		switch (cmd) {
++		case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 3), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 0,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				value, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 1), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 0), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2), value,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID2);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11), 1,
++				core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_rxgain:
++			rfmxgain = value & 0x000ff;
++			lpfgain = value & 0x0ff00;
++			lpfgain = lpfgain >> 8;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 11),
++				rfmxgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x3 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		case NPHY_REV7_RfctrlOverride_cmd_txgain:
++			tgain = value & 0x7fff;
++			lpfgain = value & 0x8000;
++			lpfgain = lpfgain >> 14;
++
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 12),
++				tgain, core_mask, off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 13),
++				lpfgain, core_mask,
++				off,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			break;
++		}
++	}
++}
++
++static void
++wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset,
++			       u8 coresel, u8 rail, u8 rssi_type)
++{
++	u16 valuetostuff;
++
++	offset = (offset > NPHY_RSSICAL_MAXREAD) ?
++		 NPHY_RSSICAL_MAXREAD : offset;
++	offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
++		 -NPHY_RSSICAL_MAXREAD - 1 : offset;
++
++	valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1a6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1ac, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b2, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB))
++		write_phy_reg(pi, 0x1b8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1a4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1aa, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b0, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1))
++		write_phy_reg(pi, 0x1b6, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1a5, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1ab, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b1, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2))
++		write_phy_reg(pi, 0x1b7, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1a7, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1ad, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b3, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD))
++		write_phy_reg(pi, 0x1b9, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1a8, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ae, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1b4, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ))
++		write_phy_reg(pi, 0x1ba, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1a9, valuetostuff);
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G))
++		write_phy_reg(pi, 0x1b5, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1af, valuetostuff);
++
++	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
++	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
++	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G))
++		write_phy_reg(pi, 0x1bb, valuetostuff);
++}
++
++static void brcms_phy_wr_tx_mux(struct brcms_phy *pi, u8 core)
++{
++	if (PHY_IPA(pi)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++		else
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					(CHSPEC_IS5G(pi->radio_chanspec) ?
++					0xc : 0xe));
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			write_radio_reg(pi,
++					((core == PHY_CORE_0) ?
++					 RADIO_2057_TX0_TX_SSI_MUX :
++					 RADIO_2057_TX1_TX_SSI_MUX),
++					0x11);
++
++			if (pi->pubpi.radioid == BCM2057_ID)
++				write_radio_reg(pi,
++						RADIO_2057_IQTEST_SEL_PU, 0x1);
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX |
++					((core == PHY_CORE_0) ?
++					 RADIO_2056_TX0 : RADIO_2056_TX1),
++					0x11);
++		}
++	}
++}
++
++void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type)
++{
++	u16 mask, val;
++	u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
++	    startseq;
++	u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
++	    rfctrlovr_trigger_val;
++	u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
++	u16 rfctrlcmd_val, rfctrlovr_val;
++	u8 core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
++			mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
++
++			mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
++			mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
++
++			mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
++			mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
++
++			mask = (0x1 << 2) |
++			       (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
++			mod_phy_reg(pi, 0xf9, mask, 0);
++			mod_phy_reg(pi, 0xfb, mask, 0);
++
++		} else {
++			for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++				if (core_code == RADIO_MIMO_CORESEL_CORE1
++				    && core == PHY_CORE_1)
++					continue;
++				else if (core_code == RADIO_MIMO_CORESEL_CORE2
++					 && core == PHY_CORE_0)
++					continue;
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ?
++					    0x8f : 0xa5, (0x1 << 9), 1 << 9);
++
++				if (rssi_type == NPHY_RSSI_SEL_W1 ||
++				    rssi_type == NPHY_RSSI_SEL_W2 ||
++				    rssi_type == NPHY_RSSI_SEL_NB) {
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xa6 : 0xa7,
++						    (0x3 << 8), 0);
++
++					mask = (0x1 << 2) |
++					       (0x1 << 3) |
++					       (0x1 << 4) | (0x1 << 5);
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, 0);
++
++					if (rssi_type == NPHY_RSSI_SEL_W1) {
++						if (CHSPEC_IS5G(
++							  pi->radio_chanspec)) {
++							mask = (0x1 << 2);
++							val = 1 << 2;
++						} else {
++							mask = (0x1 << 3);
++							val = 1 << 3;
++						}
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_W2) {
++						mask = (0x1 << 4);
++						val = 1 << 4;
++					} else {
++						mask = (0x1 << 5);
++						val = 1 << 5;
++					}
++					mod_phy_reg(pi,
++						    (core ==
++						     PHY_CORE_0) ? 0xf9 : 0xfb,
++						    mask, val);
++
++					mask = (0x1 << 5);
++					val = 1 << 5;
++					mod_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xe5 : 0xe6, mask, val);
++				} else {
++					if (rssi_type == NPHY_RSSI_SEL_TBD) {
++						mask = (0x3 << 8);
++						val = 1 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 1 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else if (rssi_type ==
++						   NPHY_RSSI_SEL_IQ) {
++						mask = (0x3 << 8);
++						val = 2 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 2 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++					} else {
++						mask = (0x3 << 8);
++						val = 3 << 8;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						mask = (0x3 << 10);
++						val = 3 << 10;
++						mod_phy_reg(pi,
++							    (core ==
++							     PHY_CORE_0) ? 0xa6
++							    : 0xa7, mask, val);
++						brcms_phy_wr_tx_mux(pi, core);
++						afectrlovr_rssi_val = 1 << 9;
++						mod_phy_reg(pi,
++							   (core ==
++							    PHY_CORE_0) ? 0x8f
++							   : 0xa5, (0x1 << 9),
++							   afectrlovr_rssi_val);
++					}
++				}
++			}
++		}
++	} else {
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB))
++			val = 0x0;
++		else if (rssi_type == NPHY_RSSI_SEL_TBD)
++			val = 0x1;
++		else if (rssi_type == NPHY_RSSI_SEL_IQ)
++			val = 0x2;
++		else
++			val = 0x3;
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (val << 12) | (val << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			if (rssi_type == NPHY_RSSI_SEL_W1)
++				val = 0x1;
++			if (rssi_type == NPHY_RSSI_SEL_W2)
++				val = 0x2;
++			if (rssi_type == NPHY_RSSI_SEL_NB)
++				val = 0x3;
++
++			mask = (0x3 << 4);
++			val = (val << 4);
++			mod_phy_reg(pi, 0x7a, mask, val);
++			mod_phy_reg(pi, 0x7d, mask, val);
++		}
++
++		if (core_code == RADIO_MIMO_CORESEL_OFF) {
++			afectrlovr_rssi_val = 0;
++			rfctrlcmd_rxen_val = 0;
++			rfctrlcmd_coresel_val = 0;
++			rfctrlovr_rssi_val = 0;
++			rfctrlovr_rxen_val = 0;
++			rfctrlovr_coresel_val = 0;
++			rfctrlovr_trigger_val = 0;
++			startseq = 0;
++		} else {
++			afectrlovr_rssi_val = 1;
++			rfctrlcmd_rxen_val = 1;
++			rfctrlcmd_coresel_val = core_code;
++			rfctrlovr_rssi_val = 1;
++			rfctrlovr_rxen_val = 1;
++			rfctrlovr_coresel_val = 1;
++			rfctrlovr_trigger_val = 1;
++			startseq = 1;
++		}
++
++		afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
++		afectrlovr_rssi_val = (afectrlovr_rssi_val <<
++				       12) | (afectrlovr_rssi_val << 13);
++		mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
++			    afectrlovr_rssi_val);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
++		    (rssi_type == NPHY_RSSI_SEL_W2) ||
++		    (rssi_type == NPHY_RSSI_SEL_NB)) {
++			rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
++			rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
++					(rfctrlcmd_coresel_val << 3);
++
++			rfctrlovr_mask = ((0x1 << 5) |
++					  (0x1 << 12) |
++					  (0x1 << 1) | (0x1 << 0));
++			rfctrlovr_val = (rfctrlovr_rssi_val <<
++					 5) |
++					(rfctrlovr_rxen_val << 12) |
++					(rfctrlovr_coresel_val << 1) |
++					(rfctrlovr_trigger_val << 0);
++
++			mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
++			mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
++
++			mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
++			udelay(20);
++
++			mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++		}
++	}
++}
++
++int
++wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf,
++		       u8 nsamps)
++{
++	s16 rssi0, rssi1;
++	u16 afectrlCore1_save = 0;
++	u16 afectrlCore2_save = 0;
++	u16 afectrlOverride1_save = 0;
++	u16 afectrlOverride2_save = 0;
++	u16 rfctrlOverrideAux0_save = 0;
++	u16 rfctrlOverrideAux1_save = 0;
++	u16 rfctrlMiscReg1_save = 0;
++	u16 rfctrlMiscReg2_save = 0;
++	u16 rfctrlcmd_save = 0;
++	u16 rfctrloverride_save = 0;
++	u16 rfctrlrssiothers1_save = 0;
++	u16 rfctrlrssiothers2_save = 0;
++	s8 tmp_buf[4];
++	u8 ctr = 0, samp = 0;
++	s32 rssi_out_val;
++	u16 gpiosel_orig;
++
++	afectrlCore1_save = read_phy_reg(pi, 0xa6);
++	afectrlCore2_save = read_phy_reg(pi, 0xa7);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++		rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++		afectrlOverride1_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++		rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	} else {
++		afectrlOverride1_save = read_phy_reg(pi, 0xa5);
++		rfctrlcmd_save = read_phy_reg(pi, 0x78);
++		rfctrloverride_save = read_phy_reg(pi, 0xec);
++		rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
++		rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
++	}
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	gpiosel_orig = read_phy_reg(pi, 0xca);
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, 5);
++
++	for (ctr = 0; ctr < 4; ctr++)
++		rssi_buf[ctr] = 0;
++
++	for (samp = 0; samp < nsamps; samp++) {
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++			rssi0 = read_phy_reg(pi, 0x1c9);
++			rssi1 = read_phy_reg(pi, 0x1ca);
++		} else {
++			rssi0 = read_phy_reg(pi, 0x219);
++			rssi1 = read_phy_reg(pi, 0x21a);
++		}
++
++		ctr = 0;
++		tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
++		tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
++
++		for (ctr = 0; ctr < 4; ctr++)
++			rssi_buf[ctr] += tmp_buf[ctr];
++
++	}
++
++	rssi_out_val = rssi_buf[3] & 0xff;
++	rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
++	rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
++	rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		write_phy_reg(pi, 0xca, gpiosel_orig);
++
++	write_phy_reg(pi, 0xa6, afectrlCore1_save);
++	write_phy_reg(pi, 0xa7, afectrlCore2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
++		write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride1_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
++		write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
++	} else {
++		write_phy_reg(pi, 0xa5, afectrlOverride1_save);
++		write_phy_reg(pi, 0x78, rfctrlcmd_save);
++		write_phy_reg(pi, 0xec, rfctrloverride_save);
++		write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
++		write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
++	}
++
++	return rssi_out_val;
++}
++
++s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi)
++{
++	u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
++	u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
++	u16 pwrdet_rxtx_core1_save;
++	u16 pwrdet_rxtx_core2_save;
++	u16 afectrlCore1_save;
++	u16 afectrlCore2_save;
++	u16 afectrlOverride_save;
++	u16 afectrlOverride2_save;
++	u16 pd_pll_ts_save;
++	u16 gpioSel_save;
++	s32 radio_temp[4];
++	s32 radio_temp2[4];
++	u16 syn_tempprocsense_save;
++	s16 offset = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
++		u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
++		u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
++		s32 auxADC_Vl;
++		u16 RfctrlOverride5_save, RfctrlOverride6_save;
++		u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
++		u16 RSSIMultCoef0QPowerDet_save;
++		u16 tempsense_Rcal;
++
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
++		RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++		RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					&auxADC_Vmid_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					&auxADC_Av_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					&auxADC_rssi_ctrlL_save);
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					&auxADC_rssi_ctrlH_save);
++
++		write_phy_reg(pi, 0x1ae, 0x0);
++
++		auxADC_rssi_ctrlL = 0x0;
++		auxADC_rssi_ctrlH = 0x20;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH);
++
++		tempsense_Rcal = syn_tempprocsense_save & 0x1c;
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
++		mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
++
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
++		udelay(5);
++		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
++		mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
++		mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
++		mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
++		mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
++
++		auxADC_Vmid = 0xA3;
++		auxADC_Av = 0x0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x03);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++
++		auxADC_Av = 0x7;
++		if (radio_temp[1] + radio_temp2[1] < -30) {
++			auxADC_Vmid = 0x45;
++			auxADC_Vl = 263;
++		} else if (radio_temp[1] + radio_temp2[1] < -9) {
++			auxADC_Vmid = 0x200;
++			auxADC_Vl = 467;
++		} else if (radio_temp[1] + radio_temp2[1] < 11) {
++			auxADC_Vmid = 0x266;
++			auxADC_Vl = 634;
++		} else {
++			auxADC_Vmid = 0x2D5;
++			auxADC_Vl = 816;
++		}
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av);
++
++		udelay(3);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				tempsense_Rcal | 0x01);
++
++		udelay(5);
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++
++		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++		write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
++		write_phy_reg(pi, 0x346, RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, RfctrlOverride6_save);
++		write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
++					 &auxADC_Vmid_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
++					 &auxADC_Av_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
++					 &auxADC_rssi_ctrlL_save);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
++					 &auxADC_rssi_ctrlH_save);
++
++		radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
++				 + 82 * (auxADC_Vl) - 28861 +
++				 128) / 256;
++
++		offset = (s16) pi->phy_tempsense_offset;
++
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		syn_tempprocsense_save =
++			read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0x8f);
++		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		if (NREV_LT(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
++		else
++			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
++
++		radio_temp[0] =
++			(126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
++
++		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
++				syn_tempprocsense_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0x8f, afectrlOverride_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
++
++		offset = (s16) pi->phy_tempsense_offset;
++	} else {
++
++		pwrdet_rxtx_core1_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pwrdet_rxtx_core2_save =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++		core1_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		core1_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		core2_txrf_iqcal1_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		core2_txrf_iqcal2_save =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
++
++		afectrlCore1_save = read_phy_reg(pi, 0xa6);
++		afectrlCore2_save = read_phy_reg(pi, 0xa7);
++		afectrlOverride_save = read_phy_reg(pi, 0xa5);
++		gpioSel_save = read_phy_reg(pi, 0xca);
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
++		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
++
++		radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
++		radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
++		radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
++		radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] + radio_temp[1] + radio_temp[2] +
++			 radio_temp[3]);
++
++		radio_temp[0] =
++			(radio_temp[0] +
++			 (8 * 32)) * (950 - 350) / 63 + (350 * 8);
++
++		radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
++
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pwrdet_rxtx_core1_save);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pwrdet_rxtx_core2_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				core1_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				core2_txrf_iqcal1_save);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				core1_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				core2_txrf_iqcal2_save);
++		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
++
++		write_phy_reg(pi, 0xca, gpioSel_save);
++		write_phy_reg(pi, 0xa6, afectrlCore1_save);
++		write_phy_reg(pi, 0xa7, afectrlCore2_save);
++		write_phy_reg(pi, 0xa5, afectrlOverride_save);
++	}
++
++	return (s16) radio_temp[0] + offset;
++}
++
++static void
++wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf)
++{
++	u8 core;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		if (rssi_type == NPHY_RSSI_SEL_NB) {
++			if (core == PHY_CORE_0) {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			} else {
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_B0_NBRSSI_VCM,
++					      RADIO_2055_NBRSSI_VCM_I_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_NBRSSI_VCM_Q_MASK,
++					      vcm_buf[2 * core +
++						      1] <<
++					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
++			}
++		} else {
++			if (core == PHY_CORE_0)
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++			else
++				mod_radio_reg(pi,
++					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
++					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
++					      vcm_buf[2 *
++						      core] <<
++					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
++		}
++	}
++}
++
++static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi)
++{
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 clip_off[] = { 0xffff, 0xffff };
++	s32 target_code;
++	u8 vcm, min_vcm;
++	u8 vcm_final = 0;
++	u8 result_idx;
++	s32 poll_results[8][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_result_core[4] = { 0, 0, 0, 0 };
++	s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++	u8 vcm_level_max;
++	u8 core;
++	u8 wb_cnt;
++	u8 rssi_type;
++	u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
++	u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
++	u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
++	u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
++	u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
++	u16 NPHY_RfctrlCmd_save;
++	u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
++	u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
++	u8 rxcore_state;
++	u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
++	u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
++	u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
++	u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
++
++	NPHY_REV7_RfctrlOverride3_save =
++		NPHY_REV7_RfctrlOverride4_save =
++		NPHY_REV7_RfctrlOverride5_save =
++		NPHY_REV7_RfctrlOverride6_save =
++		NPHY_REV7_RfctrlMiscReg3_save =
++		NPHY_REV7_RfctrlMiscReg4_save =
++		NPHY_REV7_RfctrlMiscReg5_save =
++		NPHY_REV7_RfctrlMiscReg6_save = 0;
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
++	NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
++	NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
++	NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
++	NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
++	NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
++	NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
++	NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
++		NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
++		NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
++		NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
++	}
++	NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
++	NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
++	NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
++	NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
++	NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
++		NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
++		NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
++		NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
++	}
++	NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
++	NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
++					 RADIO_MIMO_CORESEL_ALLRXTX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
++			0, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rx_pu,
++			1, 0, 0);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
++	}
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
++		}
++
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 4),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 5), 1, 0,
++				0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		} else {
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
++		}
++	}
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	vcm_level_max = 8;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++					       core ==
++					       PHY_CORE_0 ?
++					       RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
++
++		for (vcm = 0; vcm < vcm_level_max; vcm++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7))
++				mod_radio_reg(pi, (core == PHY_CORE_0) ?
++					      RADIO_2057_NB_MASTER_CORE0 :
++					      RADIO_2057_NB_MASTER_CORE1,
++					      RADIO_2057_VCM_MASK, vcm);
++			else
++				mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++					      ((core ==
++						PHY_CORE_0) ? RADIO_2056_RX0 :
++					       RADIO_2056_RX1),
++					      RADIO_2056_VCM_MASK,
++					      vcm << RADIO_2056_RSSI_VCM_SHIFT);
++
++			wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
++					       &poll_results[vcm][0],
++					       NPHY_RSSICAL_NPOLL);
++		}
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if ((core == result_idx / 2) &&
++			    (result_idx % 2 == 0)) {
++
++				min_d = NPHY_RSSICAL_MAXD;
++				min_vcm = 0;
++				min_poll =
++					NPHY_RSSICAL_MAXREAD *
++					NPHY_RSSICAL_NPOLL + 1;
++				for (vcm = 0; vcm < vcm_level_max; vcm++) {
++					curr_d =
++						poll_results[vcm][result_idx] *
++						poll_results[vcm][result_idx] +
++						poll_results[vcm][result_idx +
++								  1] *
++						poll_results[vcm][result_idx +
++								  1];
++					if (curr_d < min_d) {
++						min_d = curr_d;
++						min_vcm = vcm;
++					}
++					if (poll_results[vcm][result_idx] <
++					    min_poll)
++						min_poll =
++							poll_results[vcm]
++							[result_idx];
++				}
++				vcm_final = min_vcm;
++				poll_results_min[result_idx] = min_poll;
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mod_radio_reg(pi, (core == PHY_CORE_0) ?
++				      RADIO_2057_NB_MASTER_CORE0 :
++				      RADIO_2057_NB_MASTER_CORE1,
++				      RADIO_2057_VCM_MASK, vcm_final);
++		else
++			mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
++				      ((core ==
++					PHY_CORE_0) ? RADIO_2056_RX0 :
++				       RADIO_2056_RX1), RADIO_2056_VCM_MASK,
++				      vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
++
++		for (result_idx = 0; result_idx < 4; result_idx++) {
++			if (core == result_idx / 2) {
++				fine_digital_offset[result_idx] =
++					(NPHY_RSSICAL_NB_TARGET *
++					 NPHY_RSSICAL_NPOLL) -
++					poll_results[vcm_final][result_idx];
++				if (fine_digital_offset[result_idx] < 0) {
++					fine_digital_offset[result_idx] =
++						abs(fine_digital_offset
++						    [result_idx]);
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++					fine_digital_offset[result_idx] =
++						-fine_digital_offset[
++								    result_idx];
++				} else {
++					fine_digital_offset[result_idx] +=
++						(NPHY_RSSICAL_NPOLL / 2);
++					fine_digital_offset[result_idx] /=
++						NPHY_RSSICAL_NPOLL;
++				}
++
++				if (poll_results_min[result_idx] ==
++				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++					fine_digital_offset[result_idx] =
++						(NPHY_RSSICAL_NB_TARGET -
++						 NPHY_RSSICAL_MAXREAD - 1);
++
++				wlc_phy_scale_offset_rssi_nphy(
++					pi, 0x0,
++					(s8)
++					fine_digital_offset
++					[result_idx],
++					(result_idx / 2 == 0) ?
++					RADIO_MIMO_CORESEL_CORE1 :
++					RADIO_MIMO_CORESEL_CORE2,
++					(result_idx % 2 == 0) ?
++					NPHY_RAIL_I : NPHY_RAIL_Q,
++					NPHY_RSSI_SEL_NB);
++			}
++		}
++
++	}
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((rxcore_state & (1 << core)) == 0)
++			continue;
++
++		for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
++			if (wb_cnt == 0) {
++				rssi_type = NPHY_RSSI_SEL_W1;
++				target_code = NPHY_RSSICAL_W1_TARGET_REV3;
++			} else {
++				rssi_type = NPHY_RSSI_SEL_W2;
++				target_code = NPHY_RSSICAL_W2_TARGET_REV3;
++			}
++
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_I, rssi_type);
++			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
++						       core ==
++						       PHY_CORE_0 ?
++						       RADIO_MIMO_CORESEL_CORE1
++						       :
++						       RADIO_MIMO_CORESEL_CORE2,
++						       NPHY_RAIL_Q, rssi_type);
++
++			wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
++					       NPHY_RSSICAL_NPOLL);
++
++			for (result_idx = 0; result_idx < 4; result_idx++) {
++				if (core == result_idx / 2) {
++					fine_digital_offset[result_idx] =
++						(target_code *
++						 NPHY_RSSICAL_NPOLL) -
++						poll_result_core[result_idx];
++					if (fine_digital_offset[result_idx] <
++					    0) {
++						fine_digital_offset[result_idx]
++							= abs(
++							    fine_digital_offset
++							    [result_idx]);
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++						fine_digital_offset[result_idx]
++							= -fine_digital_offset
++								[result_idx];
++					} else {
++						fine_digital_offset[result_idx]
++							+= (NPHY_RSSICAL_NPOLL
++							    / 2);
++						fine_digital_offset[result_idx]
++							/= NPHY_RSSICAL_NPOLL;
++					}
++
++					wlc_phy_scale_offset_rssi_nphy(
++						pi, 0x0,
++						(s8)
++						fine_digital_offset
++						[core *
++						 2],
++						(core == PHY_CORE_0) ?
++						RADIO_MIMO_CORESEL_CORE1 :
++						RADIO_MIMO_CORESEL_CORE2,
++						(result_idx % 2 == 0) ?
++						NPHY_RAIL_I :
++						NPHY_RAIL_Q,
++						rssi_type);
++				}
++			}
++
++		}
++	}
++
++	write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
++	write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
++
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
++	mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
++	mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
++
++	write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
++	write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
++	write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
++	write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
++	write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
++	write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
++		write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
++		write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
++		write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
++	}
++	write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
++	write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
++	write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
++	write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
++	write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
++		write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
++		write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
++		write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
++	}
++	write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
++	write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
++
++	if (CHSPEC_IS2G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_2G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_2G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_2G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_2G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_2G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_2G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_2G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_2G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_2G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_2G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_2G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_2G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_2G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_2G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
++		} else {
++			pi->rssical_cache.rssical_radio_regs_5G[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX0);
++			pi->rssical_cache.rssical_radio_regs_5G[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RSSI_MISC |
++					       RADIO_2056_RX1);
++		}
++
++		pi->rssical_cache.rssical_phyregs_5G[0] =
++			read_phy_reg(pi, 0x1a6);
++		pi->rssical_cache.rssical_phyregs_5G[1] =
++			read_phy_reg(pi, 0x1ac);
++		pi->rssical_cache.rssical_phyregs_5G[2] =
++			read_phy_reg(pi, 0x1b2);
++		pi->rssical_cache.rssical_phyregs_5G[3] =
++			read_phy_reg(pi, 0x1b8);
++		pi->rssical_cache.rssical_phyregs_5G[4] =
++			read_phy_reg(pi, 0x1a4);
++		pi->rssical_cache.rssical_phyregs_5G[5] =
++			read_phy_reg(pi, 0x1aa);
++		pi->rssical_cache.rssical_phyregs_5G[6] =
++			read_phy_reg(pi, 0x1b0);
++		pi->rssical_cache.rssical_phyregs_5G[7] =
++			read_phy_reg(pi, 0x1b6);
++		pi->rssical_cache.rssical_phyregs_5G[8] =
++			read_phy_reg(pi, 0x1a5);
++		pi->rssical_cache.rssical_phyregs_5G[9] =
++			read_phy_reg(pi, 0x1ab);
++		pi->rssical_cache.rssical_phyregs_5G[10] =
++			read_phy_reg(pi, 0x1b1);
++		pi->rssical_cache.rssical_phyregs_5G[11] =
++			read_phy_reg(pi, 0x1b7);
++
++		pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
++	}
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++}
++
++static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
++{
++	s32 target_code;
++	u16 classif_state;
++	u16 clip_state[2];
++	u16 rssi_ctrl_state[2], pd_state[2];
++	u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
++	u16 rfctrlintc_override_val;
++	u16 clip_off[] = { 0xffff, 0xffff };
++	u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
++	u8 vcm, min_vcm, vcm_tmp[4];
++	u8 vcm_final[4] = { 0, 0, 0, 0 };
++	u8 result_idx, ctr;
++	s32 poll_results[4][4] = {
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0},
++		{0, 0, 0, 0}
++	};
++	s32 poll_miniq[4][2] = {
++		{0, 0},
++		{0, 0},
++		{0, 0},
++		{0, 0}
++	};
++	s32 min_d, curr_d;
++	s32 fine_digital_offset[4];
++	s32 poll_results_min[4] = { 0, 0, 0, 0 };
++	s32 min_poll;
++
++	switch (rssi_type) {
++	case NPHY_RSSI_SEL_NB:
++		target_code = NPHY_RSSICAL_NB_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W1:
++		target_code = NPHY_RSSICAL_W1_TARGET;
++		break;
++	case NPHY_RSSI_SEL_W2:
++		target_code = NPHY_RSSICAL_W2_TARGET;
++		break;
++	default:
++		return;
++		break;
++	}
++
++	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++	wlc_phy_clip_det_nphy(pi, 0, clip_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_off);
++
++	rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
++	rfctrlintc_override_val =
++		CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
++
++	rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
++	rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
++	write_phy_reg(pi, 0x91, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
++
++	rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
++	rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
++	write_phy_reg(pi, 0x92, rfctrlintc_override_val);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
++
++	pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
++		  RADIO_2055_WBRSSI_G2_PD;
++	pd_state[0] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
++	pd_state[1] =
++		read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
++	rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
++			 RADIO_2055_WBRSSI_G2_SEL;
++	rssi_ctrl_state[0] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
++	rssi_ctrl_state[1] =
++		read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
++
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_I, rssi_type);
++	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
++				       NPHY_RAIL_Q, rssi_type);
++
++	for (vcm = 0; vcm < 4; vcm++) {
++
++		vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
++		if (rssi_type != NPHY_RSSI_SEL_W2)
++			wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
++
++		wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
++				       NPHY_RSSICAL_NPOLL);
++
++		if ((rssi_type == NPHY_RSSI_SEL_W1)
++		    || (rssi_type == NPHY_RSSI_SEL_W2)) {
++			for (ctr = 0; ctr < 2; ctr++)
++				poll_miniq[vcm][ctr] =
++					min(poll_results[vcm][ctr * 2 + 0],
++					    poll_results[vcm][ctr * 2 + 1]);
++		}
++	}
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		min_d = NPHY_RSSICAL_MAXD;
++		min_vcm = 0;
++		min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
++		for (vcm = 0; vcm < 4; vcm++) {
++			curr_d = abs(((rssi_type == NPHY_RSSI_SEL_NB) ?
++				      poll_results[vcm][result_idx] :
++				      poll_miniq[vcm][result_idx / 2]) -
++				     (target_code * NPHY_RSSICAL_NPOLL));
++			if (curr_d < min_d) {
++				min_d = curr_d;
++				min_vcm = vcm;
++			}
++			if (poll_results[vcm][result_idx] < min_poll)
++				min_poll = poll_results[vcm][result_idx];
++		}
++		vcm_final[result_idx] = min_vcm;
++		poll_results_min[result_idx] = min_poll;
++	}
++
++	if (rssi_type != NPHY_RSSI_SEL_W2)
++		wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
++
++	for (result_idx = 0; result_idx < 4; result_idx++) {
++		fine_digital_offset[result_idx] =
++			(target_code * NPHY_RSSICAL_NPOLL) -
++			poll_results[vcm_final[result_idx]][result_idx];
++		if (fine_digital_offset[result_idx] < 0) {
++			fine_digital_offset[result_idx] =
++				abs(fine_digital_offset[result_idx]);
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++			fine_digital_offset[result_idx] =
++				-fine_digital_offset[result_idx];
++		} else {
++			fine_digital_offset[result_idx] +=
++				(NPHY_RSSICAL_NPOLL / 2);
++			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
++		}
++
++		if (poll_results_min[result_idx] ==
++		    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL)
++			fine_digital_offset[result_idx] =
++				(target_code - NPHY_RSSICAL_MAXREAD - 1);
++
++		wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
++					       (s8)
++					       fine_digital_offset[result_idx],
++					       (result_idx / 2 ==
++						0) ? RADIO_MIMO_CORESEL_CORE1 :
++					       RADIO_MIMO_CORESEL_CORE2,
++					       (result_idx % 2 ==
++						0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
++					       rssi_type);
++	}
++
++	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
++	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
++	if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
++				     NPHY_RSSI_SEL_W2);
++	if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_NB);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W1);
++	else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL)
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++	else
++		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
++				     NPHY_RSSI_SEL_W2);
++
++	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
++
++	write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
++	write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
++	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
++
++	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
++	wlc_phy_clip_det_nphy(pi, 1, clip_state);
++
++	wlc_phy_resetcca_nphy(pi);
++}
++
++void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		wlc_phy_rssi_cal_nphy_rev3(pi);
++	} else {
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
++		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
++	}
++}
++
++int
++wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh)
++{
++	s16 rxpwr, rxpwr0, rxpwr1;
++	s16 phyRx0_l, phyRx2_l;
++
++	rxpwr = 0;
++	rxpwr0 = rxh->PhyRxStatus_1 & PRXS1_nphy_PWR0_MASK;
++	rxpwr1 = (rxh->PhyRxStatus_1 & PRXS1_nphy_PWR1_MASK) >> 8;
++
++	if (rxpwr0 > 127)
++		rxpwr0 -= 256;
++	if (rxpwr1 > 127)
++		rxpwr1 -= 256;
++
++	phyRx0_l = rxh->PhyRxStatus_0 & 0x00ff;
++	phyRx2_l = rxh->PhyRxStatus_2 & 0x00ff;
++	if (phyRx2_l > 127)
++		phyRx2_l -= 256;
++
++	if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
++		rxpwr0 = rxpwr1;
++		rxpwr1 = phyRx2_l;
++	}
++
++	if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
++		rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
++		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
++	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
++		rxpwr = (rxpwr0 + rxpwr1) >> 1;
++
++	return rxpwr;
++}
++
++static void
++wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf,
++			     u16 num_samps)
++{
++	u16 t;
++	u32 *data_buf = NULL;
++
++	data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
++	if (data_buf == NULL)
++		return;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	for (t = 0; t < num_samps; t++)
++		data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
++			      (((unsigned int)tone_buf[t].q) & 0x3ff);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
++				 data_buf);
++
++	kfree(data_buf);
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u16
++wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++			      u8 dac_test_mode)
++{
++	u8 phy_bw, is_phybw40;
++	u16 num_samps, t, spur;
++	s32 theta = 0, rot = 0;
++	u32 tbl_len;
++	struct cordic_iq *tone_buf = NULL;
++
++	is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
++	phy_bw = (is_phybw40 == 1) ? 40 : 20;
++	tbl_len = (phy_bw << 3);
++
++	if (dac_test_mode == 1) {
++		spur = read_phy_reg(pi, 0x01);
++		spur = (spur >> 15) & 1;
++		phy_bw = (spur == 1) ? 82 : 80;
++		phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
++
++		tbl_len = (phy_bw << 1);
++	}
++
++	tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC);
++	if (tone_buf == NULL)
++		return 0;
++
++	num_samps = (u16) tbl_len;
++	rot = ((f_kHz * 36) / phy_bw) / 100;
++	theta = 0;
++
++	for (t = 0; t < num_samps; t++) {
++
++		tone_buf[t] = cordic_calc_iq(theta);
++
++		theta += rot;
++
++		tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
++		tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
++	}
++
++	wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
++
++	kfree(tone_buf);
++
++	return num_samps;
++}
++
++static void
++wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops,
++			u16 wait, u8 iqmode, u8 dac_test_mode,
++			bool modify_bbmult)
++{
++	u16 bb_mult;
++	u8 phy_bw, sample_cmd;
++	u16 orig_RfseqCoreActv;
++	u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
++	    lpf_bw_ctl_miscreg4;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	phy_bw = 20;
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
++		lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
++		if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		} else {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
++
++			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
++					      (0x7 << 8);
++			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
++					      (0x7 << 8);
++		}
++	}
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					&bb_mult);
++		pi->nphy_bb_mult_save =
++			BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
++	}
++
++	if (modify_bbmult) {
++		bb_mult = (phy_bw == 20) ? 100 : 71;
++		bb_mult = (bb_mult << 8) + bb_mult;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	write_phy_reg(pi, 0xc6, num_samps - 1);
++
++	if (loops != 0xffff)
++		write_phy_reg(pi, 0xc4, loops - 1);
++	else
++		write_phy_reg(pi, 0xc4, loops);
++
++	write_phy_reg(pi, 0xc5, wait);
++
++	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
++	or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
++	if (iqmode) {
++
++		and_phy_reg(pi, 0xc2, 0x7FFF);
++
++		or_phy_reg(pi, 0xc2, 0x8000);
++	} else {
++
++		sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
++		write_phy_reg(pi, 0xc3, sample_cmd);
++	}
++
++	SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
++
++	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
++}
++
++int
++wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val,
++		     u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
++{
++	u16 num_samps;
++	u16 loops = 0xffff;
++	u16 wait = 0;
++
++	num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val,
++						  dac_test_mode);
++	if (num_samps == 0)
++		return -EBADE;
++
++	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
++				dac_test_mode, modify_bbmult);
++
++	return 0;
++}
++
++void wlc_phy_stopplayback_nphy(struct brcms_phy *pi)
++{
++	u16 playback_status;
++	u16 bb_mult;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	playback_status = read_phy_reg(pi, 0xc7);
++	if (playback_status & 0x1)
++		or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
++	else if (playback_status & 0x2)
++		and_phy_reg(pi, 0xc2,
++			    (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
++
++	and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
++
++	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
++
++		bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
++					 &bb_mult);
++
++		pi->nphy_bb_mult_save = 0;
++	}
++
++	if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
++		if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++			pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
++		}
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static u32 *brcms_phy_get_tx_pwrctrl_tbl(struct brcms_phy *pi)
++{
++	u32 *tx_pwrctrl_tbl = NULL;
++	uint phyrev = pi->pubpi.phy_rev;
++
++	if (PHY_IPA(pi)) {
++		tx_pwrctrl_tbl =
++			wlc_phy_get_ipa_gaintbl_nphy(pi);
++	} else {
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_IS(phyrev, 3))
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3;
++			else if (NREV_IS(phyrev, 4))
++				tx_pwrctrl_tbl =
++					(pi->srom_fem5g.extpagain == 3) ?
++					nphy_tpc_5GHz_txgain_HiPwrEPA :
++					nphy_tpc_5GHz_txgain_rev4;
++			else
++				tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev5;
++		} else {
++			if (NREV_GE(phyrev, 7)) {
++				if (pi->pubpi.radiorev == 3)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev3;
++				else if (pi->pubpi.radiorev == 5)
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_epa_2057rev5;
++			} else {
++				if (NREV_GE(phyrev, 5) &&
++				   (pi->srom_fem2g.extpagain ==	3))
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_HiPwrEPA;
++				else
++					tx_pwrctrl_tbl =
++						nphy_tpc_txgain_rev3;
++			}
++		}
++	}
++	return tx_pwrctrl_tbl;
++}
++
++struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi)
++{
++	u16 base_idx[2], curr_gain[2];
++	u8 core_no;
++	struct nphy_txgains target_gain;
++	u32 *tx_pwrctrl_tbl = NULL;
++
++	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++					curr_gain);
++
++		if (pi->phyhang_avoid)
++			wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0007;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F8) >> 3);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++				target_gain.txlpf[core_no] =
++					((curr_gain[core_no] & 0x8000) >> 15);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x000F;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x00F0) >> 4);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0F00) >> 8);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x7000) >> 12);
++			} else {
++				target_gain.ipa[core_no] =
++					curr_gain[core_no] & 0x0003;
++				target_gain.pad[core_no] =
++					((curr_gain[core_no] & 0x000C) >> 2);
++				target_gain.pga[core_no] =
++					((curr_gain[core_no] & 0x0070) >> 4);
++				target_gain.txgm[core_no] =
++					((curr_gain[core_no] & 0x0380) >> 7);
++			}
++		}
++	} else {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
++		base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
++		for (core_no = 0; core_no < 2; core_no++) {
++			if (NREV_GE(phyrev, 3)) {
++				tx_pwrctrl_tbl =
++					brcms_phy_get_tx_pwrctrl_tbl(pi);
++				if (NREV_GE(phyrev, 7)) {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0x7;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 19) & 0x1f;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 28) & 0x7;
++					target_gain.txlpf[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 31) & 0x1;
++				} else {
++					target_gain.ipa[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 16) & 0xf;
++					target_gain.pad[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 20) & 0xf;
++					target_gain.pga[core_no] =
++						(tx_pwrctrl_tbl
++						 [base_idx[core_no]]
++						 >> 24) & 0xf;
++					target_gain.txgm[core_no] =
++						(tx_pwrctrl_tbl
++						[base_idx[core_no]]
++						 >> 28) & 0x7;
++				}
++			} else {
++				target_gain.ipa[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 16) & 0x3;
++				target_gain.pad[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 18) & 0x3;
++				target_gain.pga[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 20) & 0x7;
++				target_gain.txgm[core_no] =
++					(nphy_tpc_txgain[base_idx[core_no]] >>
++					 23) & 0x7;
++			}
++		}
++	}
++
++	return target_gain;
++}
++
++static void
++wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no,
++			      struct nphy_txgains target_gain,
++			      struct nphy_iqcal_params *params)
++{
++	u8 k;
++	int idx;
++	u16 gain_index;
++	u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->txlpf = target_gain.txlpf[core_no];
++
++		params->txgm = target_gain.txgm[core_no];
++		params->pga = target_gain.pga[core_no];
++		params->pad = target_gain.pad[core_no];
++		params->ipa = target_gain.ipa[core_no];
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			params->cal_gain =
++				((params->txlpf << 15) | (params->txgm << 12) |
++				 (params->pga << 8) |
++				 (params->pad << 3) | (params->ipa));
++		else
++			params->cal_gain =
++				((params->txgm << 12) | (params->pga << 8) |
++				 (params->pad << 4) | (params->ipa));
++
++		params->ncorr[0] = 0x79;
++		params->ncorr[1] = 0x79;
++		params->ncorr[2] = 0x79;
++		params->ncorr[3] = 0x79;
++		params->ncorr[4] = 0x79;
++	} else {
++
++		gain_index = ((target_gain.pad[core_no] << 0) |
++			      (target_gain.pga[core_no] << 4) |
++			      (target_gain.txgm[core_no] << 8));
++
++		idx = -1;
++		for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
++			if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
++			    gain_index) {
++				idx = k;
++				break;
++			}
++		}
++
++		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
++		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
++		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
++		params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
++				    (params->pad << 2));
++		params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
++		params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
++		params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
++		params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
++	}
++}
++
++static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core <= 1; core++) {
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MASTER);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_VCM_HG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						IQCAL_IDAC);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_VCM);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TX_SSI_MUX);
++
++			if (pi->pubpi.radiorev != 5)
++				pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++					READ_RADIO_REG3(pi, RADIO_2057, TX,
++							core,
++							TSSIA);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++			       READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TSSI_MISC1);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x0a);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIG, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX, 0x4);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIA, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TX_SSI_MASTER, 0x06);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_VCM_HG, 0x43);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 IQCAL_IDAC, 0x55);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_VCM, 0x00);
++
++				if (pi->pubpi.radiorev != 5)
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TSSIA, 0x00);
++				if (pi->use_int_tx_iqlo_cal_nphy) {
++					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
++							 core, TX_SSI_MUX,
++							 0x06);
++					if (!(pi->
++					internal_tx_iqlo_cal_tapoff_intpa_nphy))
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x31);
++					else
++						WRITE_RADIO_REG3(pi, RADIO_2057,
++								 TX, core,
++								 TSSIG, 0x21);
++				}
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSI_MISC1, 0x00);
++			}
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++		for (core = 0; core <= 1; core++) {
++			jtag_core =
++				(core ==
++				 PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MASTER |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_VCM_HG |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_IQCAL_IDAC |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
++				read_radio_reg(
++					pi,
++					RADIO_2056_TX_TSSI_VCM |
++					jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_AMP_DET |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TX_SSI_MUX |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIA | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSIG | jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC1 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC2 |
++					       jtag_core);
++
++			pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_TSSI_MISC3 |
++					       jtag_core);
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x0a);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++
++				if (PHY_IPA(pi)) {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x4);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIA |
++							jtag_core, 0x2f);
++				}
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIG | jtag_core,
++						0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			} else {
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_SSI_MASTER |
++						jtag_core, 0x06);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_VCM_HG |
++						jtag_core, 0x40);
++				write_radio_reg(pi,
++						RADIO_2056_TX_IQCAL_IDAC |
++						jtag_core, 0x55);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_VCM |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TX_AMP_DET |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSIA | jtag_core,
++						0x00);
++
++				if (PHY_IPA(pi)) {
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x06);
++					if (NREV_LT(pi->pubpi.phy_rev, 5))
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x11);
++					else
++						write_radio_reg(
++							pi,
++							RADIO_2056_TX_TSSIG
++							| jtag_core,
++							0x1);
++				} else {
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TX_SSI_MUX
++						| jtag_core, 0x00);
++					write_radio_reg(pi,
++							RADIO_2056_TX_TSSIG |
++							jtag_core, 0x20);
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC1 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC2 |
++						jtag_core, 0x00);
++				write_radio_reg(pi,
++						RADIO_2056_TX_TSSI_MISC3 |
++						jtag_core, 0x00);
++			}
++		}
++	} else {
++
++		pi->tx_rx_cal_radio_saveregs[0] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[1] =
++			read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[2] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
++		pi->tx_rx_cal_radio_saveregs[3] =
++			read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
++
++		pi->tx_rx_cal_radio_saveregs[4] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
++		pi->tx_rx_cal_radio_saveregs[5] =
++			read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
++
++		if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
++		    0) {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
++		} else {
++
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
++			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
++		}
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++			or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
++			or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
++		} else {
++
++			and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
++			and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
++		}
++	}
++}
++
++static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi)
++{
++	u16 jtag_core, core;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		for (core = 0; core <= 1; core++) {
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TX_SSI_MASTER,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  0]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  1]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  2]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  3]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  5]);
++
++			if (pi->pubpi.radiorev != 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TSSIA,
++						 pi->tx_rx_cal_radio_saveregs
++							     [(core * 11) + 6]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  7]);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
++					 pi->
++					 tx_rx_cal_radio_saveregs[(core * 11) +
++								  8]);
++		}
++	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		for (core = 0; core <= 1; core++) {
++			jtag_core = (core == PHY_CORE_0) ?
++				     RADIO_2056_TX0 : RADIO_2056_TX1;
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 1]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_IQCAL_IDAC | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 2]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 3]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_AMP_DET | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 4]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TX_SSI_MUX | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 5]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 6]);
++
++			write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 7]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC1 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 8]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC2 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 9]);
++
++			write_radio_reg(pi,
++					RADIO_2056_TX_TSSI_MISC3 | jtag_core,
++					pi->
++					tx_rx_cal_radio_saveregs[(core * 11) +
++								 10]);
++		}
++	} else {
++
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[0]);
++		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[1]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
++				pi->tx_rx_cal_radio_saveregs[2]);
++		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
++				pi->tx_rx_cal_radio_saveregs[3]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
++				pi->tx_rx_cal_radio_saveregs[4]);
++		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
++				pi->tx_rx_cal_radio_saveregs[5]);
++	}
++}
++
++static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi)
++{
++	u16 val, mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 8) | (0x3 << 10));
++		val = (0x2 << 8);
++		val |= (0x2 << 10);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0x8f);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0x8f, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= ((0x1 << 9) | (0x1 << 10));
++		write_phy_reg(pi, 0xa5, val);
++
++		pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
++		mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[5] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[6] = val;
++		val = 0;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
++
++		if (!(pi->use_int_tx_iqlo_cal_nphy))
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				1,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++		else
++			wlc_phy_rfctrlintc_override_nphy(
++				pi,
++				NPHY_RfctrlIntc_override_PA,
++				0,
++				RADIO_MIMO_CORESEL_CORE1
++				|
++				RADIO_MIMO_CORESEL_CORE2);
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x2, RADIO_MIMO_CORESEL_CORE1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x8, RADIO_MIMO_CORESEL_CORE2);
++
++		pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++		pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      1 << 4);
++
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 0);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 0);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 0);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 0);
++				}
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 0,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
++		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
++
++		mask = ((0x3 << 12) | (0x3 << 14));
++		val = (0x2 << 12);
++		val |= (0x2 << 14);
++		mod_phy_reg(pi, 0xa6, mask, val);
++		mod_phy_reg(pi, 0xa7, mask, val);
++
++		val = read_phy_reg(pi, 0xa5);
++		pi->tx_rx_cal_phy_saveregs[2] = val;
++		val |= ((0x1 << 12) | (0x1 << 13));
++		write_phy_reg(pi, 0xa5, val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[3] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &val);
++
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					&val);
++		pi->tx_rx_cal_phy_saveregs[4] = val;
++		val |= 0x2000;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &val);
++
++		pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
++		pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
++		val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
++		write_phy_reg(pi, 0x91, val);
++		write_phy_reg(pi, 0x92, val);
++	}
++}
++
++static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi)
++{
++	u16 mask;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
++		write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
++		write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
++					 &pi->tx_rx_cal_phy_saveregs[5]);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
++					 &pi->tx_rx_cal_phy_saveregs[6]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
++
++		write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++		write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_resetcca_nphy(pi);
++
++		if (pi->use_int_tx_iqlo_cal_nphy
++		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
++
++			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE0,
++						1, 1);
++					mod_radio_reg(
++						pi,
++						RADIO_2057_PAD2G_TUNE_PUS_CORE1,
++						1, 1);
++				} else {
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
++					     1, 1);
++					mod_radio_reg(
++					     pi,
++					     RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
++					     1, 1);
++				}
++
++				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
++					      0);
++			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
++				wlc_phy_rfctrl_override_nphy_rev7(
++					pi,
++					(0x1 << 3), 0,
++					0x3, 1,
++					NPHY_REV7_RFCTRLOVERRIDE_ID0);
++			}
++		}
++	} else {
++		mask = ((0x3 << 12) | (0x3 << 14));
++		mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
++		mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
++		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
++					 &pi->tx_rx_cal_phy_saveregs[3]);
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
++					 &pi->tx_rx_cal_phy_saveregs[4]);
++
++		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
++		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
++	}
++}
++
++void
++wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps)
++{
++	u16 tssi_reg;
++	s32 temp, pwrindex[2];
++	s32 idle_tssi[2];
++	s32 rssi_buf[4];
++	s32 tssival[2];
++	u8 tssi_type;
++
++	tssi_reg = read_phy_reg(pi, 0x1e9);
++
++	temp = (s32) (tssi_reg & 0x3f);
++	idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
++
++	temp = (s32) ((tssi_reg >> 8) & 0x3f);
++	idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
++
++	tssi_type =
++		CHSPEC_IS5G(pi->radio_chanspec) ?
++		(u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G;
++
++	wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
++
++	tssival[0] = rssi_buf[0] / ((s32) num_samps);
++	tssival[1] = rssi_buf[2] / ((s32) num_samps);
++
++	pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
++	pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
++
++	if (pwrindex[0] < 0)
++		pwrindex[0] = 0;
++	else if (pwrindex[0] > 63)
++		pwrindex[0] = 63;
++
++	if (pwrindex[1] < 0)
++		pwrindex[1] = 0;
++	else if (pwrindex[1] > 63)
++		pwrindex[1] = 63;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
++				(u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
++				(u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
++}
++
++static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
++{
++	int index;
++	u32 bbmult_scale;
++	u16 bbmult;
++	u16 tblentry;
++
++	struct nphy_txiqcal_ladder ladder_lo[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
++		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
++	};
++
++	struct nphy_txiqcal_ladder ladder_iq[] = {
++		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
++		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
++		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
++	};
++
++	bbmult = (core == PHY_CORE_0) ?
++		 ((pi->nphy_txcal_bbmult >> 8) & 0xff) :
++		 (pi->nphy_txcal_bbmult & 0xff);
++
++	for (index = 0; index < 18; index++) {
++		bbmult_scale = ladder_lo[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
++					 &tblentry);
++
++		bbmult_scale = ladder_iq[index].percent * bbmult;
++		bbmult_scale /= 100;
++
++		tblentry =
++			((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
++					 16, &tblentry);
++	}
++}
++
++static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core)
++{
++	u16 tmp;
++	tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
++
++	tmp = (tmp & (0x7f << 8)) >> 8;
++	return (u8) tmp;
++}
++
++static void
++wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1)
++{
++	mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
++
++	if (NREV_GT(pi->pubpi.phy_rev, 1))
++		mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
++}
++
++static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi)
++{
++	u16 m0m1;
++
++	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
++
++	return m0m1;
++}
++
++static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1)
++{
++	u16 m0m1 = (u16) ((m0 << 8) | m1);
++
++	wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
++	wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
++}
++
++static void
++wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi,
++			    struct nphy_papd_restore_state *state, u8 core)
++{
++	s32 tone_freq;
++	u8 off_core;
++	u16 mixgain = 0;
++
++	off_core = core ^ 0x1;
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7),
++				wlc_phy_read_lpf_bw_ctl_nphy
++					(pi,
++					0), 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5)
++				mixgain = (core == 0) ? 0x20 : 0x00;
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x00;
++			else if ((pi->pubpi.radiorev <= 4)
++				 || (pi->pubpi.radiorev == 6))
++				mixgain = 0x00;
++		} else {
++			if ((pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				mixgain = 0x50;
++			else if ((pi->pubpi.radiorev == 3)
++				 || (pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				mixgain = 0x0;
++		}
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
++						  mixgain, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			1, (1 << core), 0);
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_tx_pu,
++			0, (1 << off_core), 0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
++						  0, (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
++						  (1 << core), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++		state->afectrl[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
++		state->afeoverride[off_core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5), (0x1 << 2), (0x1 << 2));
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
++			    (0x1 << 2), (0x1 << 2));
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
++				 0x8f), (0x1 << 2), (0x1 << 2));
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_2G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_2G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_2G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 3) ||
++			    (pi->pubpi.radiorev == 4) ||
++			    (pi->pubpi.radiorev == 6))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++			else if (pi->pubpi.radiorev == 5)
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 (core == 0) ? 0xf7 : 0xf2);
++			else if ((pi->pubpi.radiorev == 7)
++				 || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_2G_ATTEN, 0xff);
++		} else {
++			state->pwrup[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, core,
++						TXRXCOUPLE_5G_ATTEN);
++			state->pwrup[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_PWRUP);
++			state->atten[off_core] =
++				READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++						TXRXCOUPLE_5G_ATTEN);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++					 TXRXCOUPLE_5G_PWRUP, 0xc);
++
++			if ((pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8))
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf4);
++
++			else
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN, 0xf0);
++
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_PWRUP, 0x0);
++			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
++					 TXRXCOUPLE_5G_ATTEN, 0xff);
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
++
++		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
++						    0xa6 : 0xa7);
++		state->afeoverride[core] =
++			read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
++
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
++		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++				 0xa5),
++			    (0x1 << 0) |
++			    (0x1 << 1) |
++			    (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
++
++		state->vga_master[core] =
++			READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
++		WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_G);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAG_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAG_MASTER, 0x04);
++		} else {
++			state->fbmix[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, RX, core,
++						TXFBMIX_A);
++			state->intpa_master[core] =
++				READ_RADIO_REG2(pi, RADIO_2056, TX, core,
++						INTPAA_MASTER);
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
++					 0x03);
++			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++					 INTPAA_MASTER, 0x04);
++
++		}
++
++		tone_freq = 4000;
++
++		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++	}
++}
++
++static void
++wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi,
++			      struct nphy_papd_restore_state *state)
++{
++	u8 core;
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_2G_ATTEN,
++						 state->atten[core]);
++			} else {
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_PWRUP, 0);
++				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
++						 TXRXCOUPLE_5G_ATTEN,
++						 state->atten[core]);
++			}
++		}
++
++		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				1, 0x3, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 2),
++				0, 0x3, 1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
++						  0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		if (NREV_IS(pi->pubpi.phy_rev, 7)
++		    || NREV_GE(pi->pubpi.phy_rev, 8))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi, (0x1 << 7), 0, 0,
++				1,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
++
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
++					 state->vga_master[core]);
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_G, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAG_MASTER,
++						 state->intpa_master[core]);
++			} else {
++				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
++						 TXFBMIX_A, state->fbmix[core]);
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
++						 INTPAA_MASTER,
++						 state->intpa_master[core]);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xa6 : 0xa7, state->afectrl[core]);
++			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
++				      0xa5, state->afeoverride[core]);
++		}
++
++		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
++					    (state->mm & 0xff));
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
++	}
++}
++
++static void
++wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start,
++		u32 end)
++{
++	u32 *buf, *src, *dst, sz;
++
++	sz = end - start + 1;
++
++	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
++	if (NULL == buf)
++		return;
++
++	src = buf;
++	dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
++
++	wlc_phy_table_read_nphy(pi,
++				(core ==
++				 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1),
++				NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
++
++	do {
++		u32 phy_a1, phy_a2;
++		s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
++
++		phy_a1 = end - min(end, (winsz >> 1));
++		phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1,
++			       end + (winsz >> 1));
++		phy_a3 = phy_a2 - phy_a1 + 1;
++		phy_a6 = 0;
++		phy_a7 = 0;
++
++		do {
++			wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
++						    &phy_a5);
++			phy_a6 += phy_a4;
++			phy_a7 += phy_a5;
++		} while (phy_a2-- != phy_a1);
++
++		phy_a6 /= phy_a3;
++		phy_a7 /= phy_a3;
++		dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
++	} while (end-- != start);
++
++	wlc_phy_table_write_nphy(pi,
++				 (core ==
++				  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
++				 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
++
++	kfree(buf);
++}
++
++static void
++wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains,
++		enum phy_cal_mode cal_mode, u8 core)
++{
++	u16 phy_a1, phy_a2, phy_a3;
++	u16 phy_a4, phy_a5;
++	bool phy_a6;
++	u8 phy_a7, m[2];
++	u32 phy_a8 = 0;
++	struct nphy_txgains phy_a9;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 3))
++		return;
++
++	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
++
++	phy_a6 = ((cal_mode == CAL_GCTRL)
++		  || (cal_mode == CAL_SOFT)) ? true : false;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (phy_a9.pga[core] << 8) |
++				  (txgains->gains.pad[core] << 3) |
++				  (phy_a9.ipa[core]));
++		else
++			phy_a5 = ((phy_a9.txlpf[core] << 15) |
++				  (phy_a9.txgm[core] << 12) |
++				  (txgains->gains.pga[core] << 8) |
++				  (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 0);
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev <= 4)
++			    || (pi->pubpi.radiorev == 6))
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  60 : 79;
++			else
++				m[core] = (pi->bw == WL_CHANSPEC_BW_40) ?
++					  45 : 64;
++		} else {
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++		}
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if ((pi->pubpi.radiorev == 4)
++			    || (pi->pubpi.radiorev == 6)) {
++				phy_a1 = 30;
++				phy_a3 = 30;
++			} else {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			}
++		} else {
++			if ((pi->pubpi.radiorev == 5)
++			    || (pi->pubpi.radiorev == 7)
++			    || (pi->pubpi.radiorev == 8)) {
++				phy_a1 = 25;
++				phy_a3 = 25;
++			} else {
++				phy_a1 = 35;
++				phy_a3 = 35;
++			}
++		}
++
++		if (cal_mode == CAL_GCTRL) {
++			if ((pi->pubpi.radiorev == 5)
++			    && (CHSPEC_IS2G(pi->radio_chanspec)))
++				phy_a1 = 55;
++			else if (((pi->pubpi.radiorev == 7) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))) ||
++				 ((pi->pubpi.radiorev == 8) &&
++				  (CHSPEC_IS2G(pi->radio_chanspec))))
++				phy_a1 = 60;
++			else
++				phy_a1 = 63;
++
++		} else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
++
++			phy_a1 = 35;
++			phy_a3 = 35;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (1) << 13);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		write_phy_reg(pi, 0x2a1, 0x80);
++		write_phy_reg(pi, 0x2a2, 0x100);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 4), (11) << 4);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 8), (11) << 8);
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x7 << 0), (0x3) << 0);
++
++		write_phy_reg(pi, 0x2e5, 0x20);
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  1, ((core == 0) ? 1 : 2), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, ((core == 0) ? 2 : 1), 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0x3, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL) {
++			if (CHSPEC_IS5G(pi->radio_chanspec))
++				wlc_phy_a1_nphy(pi, core, 5, 0, 35);
++		}
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_txgain,
++			phy_a5, (1 << core), 1);
++
++	} else {
++
++		if (txgains) {
++			if (txgains->useindex) {
++				phy_a4 = 15 - ((txgains->index) >> 3);
++				if (CHSPEC_IS2G(pi->radio_chanspec)) {
++					if (NREV_GE(pi->pubpi.phy_rev, 6))
++						phy_a5 = 0x00f7 | (phy_a4 << 8);
++
++					else
++					if (NREV_IS(pi->pubpi.phy_rev, 5))
++						phy_a5 = 0x10f7 | (phy_a4 << 8);
++					else
++						phy_a5 = 0x50f7 | (phy_a4 << 8);
++				} else {
++					phy_a5 = 0x70f7 | (phy_a4 << 8);
++				}
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     phy_a5,
++							     (1 << core), 0);
++			} else {
++				wlc_phy_rfctrl_override_nphy(pi,
++							     (0x1 << 13),
++							     0x5bf7,
++							     (1 << core), 0);
++			}
++		}
++
++		if (CHSPEC_IS2G(pi->radio_chanspec))
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 45 : 64;
++		else
++			m[core] = (pi->bw == WL_CHANSPEC_BW_40) ? 75 : 107;
++
++		m[phy_a7] = 0;
++		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
++
++		phy_a2 = 63;
++
++		if (cal_mode == CAL_FULL) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_SOFT) {
++			phy_a1 = 25;
++			phy_a3 = 25;
++		} else if (cal_mode == CAL_GCTRL) {
++			phy_a1 = 63;
++			phy_a3 = 25;
++		} else {
++
++			phy_a1 = 25;
++			phy_a3 = 25;
++		}
++
++		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (1) << 0);
++
++		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
++			    0x29b, (0x1 << 0), (0) << 0);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (1) << 13);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 13), (0) << 13);
++
++			write_phy_reg(pi, 0x2a1, 0x20);
++			write_phy_reg(pi, 0x2a2, 0x60);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 4), (9) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 8), (9) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0xf << 0), (0x2) << 0);
++
++			write_phy_reg(pi, 0x2e5, 0x20);
++		} else {
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (1) << 11);
++
++			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x1 << 11), (0) << 11);
++
++			write_phy_reg(pi, 0x2a1, 0x80);
++			write_phy_reg(pi, 0x2a2, 0x600);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 4), (0) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 8), (0) << 8);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
++				    0x2a4, (0x7 << 0), (0x3) << 0);
++
++			mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
++
++		}
++
++		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
++
++		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
++
++		write_phy_reg(pi, 0x2be, 1);
++		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
++
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
++
++		wlc_phy_table_write_nphy(pi,
++					 (core ==
++					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
++					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
++					 32, &phy_a8);
++
++		if (cal_mode != CAL_GCTRL)
++			wlc_phy_a1_nphy(pi, core, 5, 0, 40);
++	}
++}
++
++static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core)
++{
++	int phy_a1;
++	int phy_a2;
++	bool phy_a3;
++	struct nphy_ipa_txcalgains phy_a4;
++	bool phy_a5 = false;
++	bool phy_a6 = true;
++	s32 phy_a7, phy_a8;
++	u32 phy_a9;
++	int phy_a10;
++	bool phy_a11 = false;
++	int phy_a12;
++	u8 phy_a13 = 0;
++	u8 phy_a14;
++	u8 *phy_a15 = NULL;
++
++	phy_a4.useindex = true;
++	phy_a12 = start_gain;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		phy_a2 = 20;
++		phy_a1 = 1;
++
++		if (CHSPEC_IS2G(pi->radio_chanspec)) {
++			if (pi->pubpi.radiorev == 5) {
++
++				phy_a15 = pad_gain_codes_used_2057rev5;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev5) - 1;
++
++			} else if ((pi->pubpi.radiorev == 7)
++				   || (pi->pubpi.radiorev == 8)) {
++
++				phy_a15 = pad_gain_codes_used_2057rev7;
++				phy_a13 =
++					ARRAY_SIZE(pad_gain_codes_used_2057rev7) - 1;
++
++			} else {
++
++				phy_a15 = pad_all_gain_codes_2057;
++				phy_a13 = ARRAY_SIZE(pad_all_gain_codes_2057) -
++					  1;
++			}
++
++		} else {
++
++			phy_a15 = pga_all_gain_codes_2057;
++			phy_a13 = ARRAY_SIZE(pga_all_gain_codes_2057) - 1;
++		}
++
++		phy_a14 = 0;
++
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_a4.gains.pad[core] =
++					(u16) phy_a15[phy_a12];
++			else
++				phy_a4.gains.pga[core] =
++					(u16) phy_a15[phy_a12];
++
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
++				if (phy_a12 < phy_a14)
++					phy_a12 = phy_a14;
++				else
++					phy_a12 = phy_a13;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	} else {
++		phy_a2 = 10;
++		phy_a1 = 8;
++		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
++			phy_a4.index = (u8) phy_a12;
++			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
++
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_EPSILONTBL0 :
++						 NPHY_TBL_ID_EPSILONTBL1), 1,
++						63, 32, &phy_a9);
++
++			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
++
++			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
++				  (phy_a8 == 4095) || (phy_a8 == -4096));
++
++			if (!phy_a6 && (phy_a3 != phy_a5)) {
++				if (!phy_a3)
++					phy_a12 -= (u8) phy_a1;
++
++				phy_a11 = true;
++				break;
++			}
++
++			if (phy_a3)
++				phy_a12 += (u8) phy_a1;
++			else
++				phy_a12 -= (u8) phy_a1;
++
++			if ((phy_a12 < 0) || (phy_a12 > 127)) {
++				if (phy_a12 < 0)
++					phy_a12 = 0;
++				else
++					phy_a12 = 127;
++
++				phy_a11 = true;
++				break;
++			}
++
++			phy_a6 = false;
++			phy_a5 = phy_a3;
++		}
++
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return (u8) phy_a15[phy_a12];
++	else
++		return (u8) phy_a12;
++
++}
++
++static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
++{
++	struct nphy_ipa_txcalgains phy_b1[2];
++	struct nphy_papd_restore_state phy_b2;
++	bool phy_b3;
++	u8 phy_b4;
++	u8 phy_b5;
++	s16 phy_b6, phy_b7, phy_b8;
++	u16 phy_b9;
++	s16 phy_b10, phy_b11, phy_b12;
++
++	phy_b11 = 0;
++	phy_b12 = 0;
++	phy_b7 = 0;
++	phy_b8 = 0;
++	phy_b6 = 0;
++
++	if (pi->nphy_papd_skip == 1)
++		return;
++
++	phy_b3 = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
++			MCTL_EN_MAC));
++	if (!phy_b3)
++		wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	pi->nphy_force_papd_cal = false;
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
++		pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
++			wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
++
++	pi->nphy_papd_last_cal = pi->sh->now;
++	pi->nphy_papd_recal_counter++;
++
++	phy_b4 = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
++				 nphy_papd_scaltbl);
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
++				 nphy_papd_scaltbl);
++
++	phy_b9 = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		s32 i, val = 0;
++		for (i = 0; i < 64; i++)
++			wlc_phy_table_write_nphy(pi,
++						 ((phy_b5 ==
++						   PHY_CORE_0) ?
++						  NPHY_TBL_ID_EPSILONTBL0 :
++						  NPHY_TBL_ID_EPSILONTBL1), 1,
++						 i, 32, &val);
++	}
++
++	wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
++
++	phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if ((pi->pubpi.radiorev == 3)
++				    || (pi->pubpi.radiorev == 4)
++				    || (pi->pubpi.radiorev == 6)) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						23;
++				} else if (pi->pubpi.radiorev == 5) {
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				} else if ((pi->pubpi.radiorev == 7)
++					   || (pi->pubpi.radiorev == 8)) {
++
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						0;
++					pi->nphy_papd_cal_gain_index[phy_b5] =
++						wlc_phy_a3_nphy(
++							pi,
++							pi->
++							nphy_papd_cal_gain_index
++							[phy_b5],
++							phy_b5);
++
++				}
++
++				phy_b1[phy_b5].gains.pad[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++
++			} else {
++				pi->nphy_papd_cal_gain_index[phy_b5] = 0;
++				pi->nphy_papd_cal_gain_index[phy_b5] =
++					wlc_phy_a3_nphy(
++						pi,
++						pi->
++						nphy_papd_cal_gain_index
++						[phy_b5], phy_b5);
++				phy_b1[phy_b5].gains.pga[phy_b5] =
++					pi->nphy_papd_cal_gain_index[phy_b5];
++			}
++		} else {
++			phy_b1[phy_b5].useindex = true;
++			phy_b1[phy_b5].index = 16;
++			phy_b1[phy_b5].index =
++				wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index,
++						phy_b5);
++
++			pi->nphy_papd_cal_gain_index[phy_b5] =
++				15 - ((phy_b1[phy_b5].index) >> 3);
++		}
++
++		switch (pi->nphy_papd_cal_type) {
++		case 0:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
++			break;
++		case 1:
++			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
++			break;
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++	}
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7))
++		wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
++
++	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
++		int eps_offset = 0;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev == 3)
++					eps_offset = -2;
++				else if (pi->pubpi.radiorev == 5)
++					eps_offset = 3;
++				else
++					eps_offset = -1;
++			} else {
++				eps_offset = 2;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
++				phy_b10 = 0;
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev3n4
++							     [phy_b8] + 1) / 2;
++					phy_b10 = -1;
++				} else if (pi->pubpi.radiorev == 5) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev5
++							     [phy_b8] + 1) / 2;
++				} else if ((pi->pubpi.radiorev == 7) ||
++					   (pi->pubpi.radiorev == 8)) {
++					phy_b12 = -(
++					    nphy_papd_padgain_dlt_2g_2057rev7
++							     [phy_b8] + 1) / 2;
++				}
++			} else {
++				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
++				if ((pi->pubpi.radiorev == 3) ||
++				    (pi->pubpi.radiorev == 4) ||
++				    (pi->pubpi.radiorev == 6))
++					phy_b11 =
++						-(nphy_papd_pgagain_dlt_5g_2057
++						  [phy_b7]
++						  + 1) / 2;
++				else if ((pi->pubpi.radiorev == 7)
++					 || (pi->pubpi.radiorev == 8))
++					phy_b11 = -(
++					      nphy_papd_pgagain_dlt_5g_2057rev7
++							     [phy_b7] + 1) / 2;
++
++				phy_b10 = -9;
++			}
++
++			if (CHSPEC_IS2G(pi->radio_chanspec))
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b12 +
++					phy_b10;
++			else
++				phy_b6 =
++					-60 + 27 + eps_offset + phy_b11 +
++					phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		} else {
++			if (NREV_LT(pi->pubpi.phy_rev, 5))
++				eps_offset = 4;
++			else
++				eps_offset = 2;
++
++			phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
++
++			if (CHSPEC_IS2G(pi->radio_chanspec)) {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_2g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = 0;
++			} else {
++				phy_b11 =
++					-(nphy_papd_pga_gain_delta_ipa_5g[
++						  phy_b7] +
++					  1) / 2;
++				phy_b10 = -9;
++			}
++
++			phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
++
++			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
++				    0x29c, (0x1ff << 7), (phy_b6) << 7);
++
++			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
++		}
++	}
++
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 13), (0) << 13);
++
++	} else {
++		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
++			    0x2a4, (0x1 << 11), (0) << 11);
++
++	}
++	pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
++
++	write_phy_reg(pi, 0x01, phy_b9);
++
++	wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
++	if (phy_b4 == PHY_TPC_HW_OFF) {
++		wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++					 (s8) (pi->nphy_txpwrindex[0].
++					       index_internal), false);
++		wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++					 (s8) (pi->nphy_txpwrindex[1].
++					       index_internal), false);
++	}
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	if (!phy_b3)
++		wlapi_enable_mac(pi->sh->physhim);
++}
++
++void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype)
++{
++	struct nphy_txgains target_gain;
++	u8 tx_pwr_ctrl_state;
++	bool fullcal = true;
++	bool restore_tx_gain = false;
++	bool mphase;
++
++	if (PHY_MUTED(pi))
++		return;
++
++	if (caltype == PHY_PERICAL_AUTO)
++		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
++	else if (caltype == PHY_PERICAL_PARTIAL)
++		fullcal = false;
++
++	if (pi->cal_type_override != PHY_PERICAL_AUTO)
++		fullcal =
++			(pi->cal_type_override ==
++			 PHY_PERICAL_FULL) ? true : false;
++
++	if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
++		if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
++			wlc_phy_cal_perical_mphase_restart(pi);
++	}
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL))
++		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
++
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
++	    (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
++		pi->nphy_cal_orig_pwr_idx[0] =
++			(u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
++		pi->nphy_cal_orig_pwr_idx[1] =
++			(u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
++
++		if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
++						0x110, 16,
++						pi->nphy_cal_orig_tx_gain);
++		} else {
++			pi->nphy_cal_orig_tx_gain[0] = 0;
++			pi->nphy_cal_orig_tx_gain[1] = 0;
++		}
++	}
++	target_gain = wlc_phy_get_tx_gain_nphy(pi);
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++	if (pi->antsel_type == ANTSEL_2x3)
++		wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true);
++
++	mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
++	if (!mphase) {
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			wlc_phy_precal_txgain_nphy(pi);
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			restore_tx_gain = true;
++
++			target_gain = pi->nphy_cal_target_gain;
++		}
++		if (0 ==
++		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal,
++					    mphase)) {
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++			wlapi_enable_mac(pi->sh->physhim);
++			wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
++					     10000);
++			wlapi_suspend_mac_and_wait(pi->sh->physhim);
++			wlc_phyreg_enter((struct brcms_phy_pub *) pi);
++
++			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
++					(pi->first_cal_after_assoc ||
++					(pi->cal_type_override ==
++					 PHY_PERICAL_FULL)) ? 2 : 0, false)) {
++				wlc_phy_savecal_nphy(pi);
++
++				wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++
++				pi->nphy_perical_last = pi->sh->now;
++			}
++		}
++		if (caltype != PHY_PERICAL_AUTO)
++			wlc_phy_rssi_cal_nphy(pi);
++
++		if (pi->first_cal_after_assoc
++		    || (pi->cal_type_override == PHY_PERICAL_FULL)) {
++			pi->first_cal_after_assoc = false;
++			wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++			wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_radio205x_vcocal_nphy(pi);
++	} else {
++		switch (pi->mphase_cal_phase_id) {
++		case MPHASE_CAL_STATE_INIT:
++			pi->nphy_perical_last = pi->sh->now;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_precal_txgain_nphy(pi);
++
++			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_TXPHASE0:
++		case MPHASE_CAL_STATE_TXPHASE1:
++		case MPHASE_CAL_STATE_TXPHASE2:
++		case MPHASE_CAL_STATE_TXPHASE3:
++		case MPHASE_CAL_STATE_TXPHASE4:
++		case MPHASE_CAL_STATE_TXPHASE5:
++			if ((pi->radar_percal_mask & 0x10) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (wlc_phy_cal_txiqlo_nphy
++				    (pi, pi->nphy_cal_target_gain, fullcal,
++				    true) != 0) {
++
++				wlc_phy_cal_perical_mphase_reset(pi);
++				break;
++			}
++
++			if (NREV_LE(pi->pubpi.phy_rev, 2) &&
++			    (pi->mphase_cal_phase_id ==
++			     MPHASE_CAL_STATE_TXPHASE4))
++				pi->mphase_cal_phase_id += 2;
++			else
++				pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_PAPDCAL:
++			if ((pi->radar_percal_mask & 0x2) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (PHY_IPA(pi))
++				wlc_phy_a4(pi, true);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RXCAL:
++			if ((pi->radar_percal_mask & 0x1) != 0)
++				pi->nphy_rxcal_active = true;
++			if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
++						  (pi->first_cal_after_assoc ||
++						   (pi->cal_type_override ==
++						    PHY_PERICAL_FULL)) ? 2 : 0,
++						  false) == 0)
++				wlc_phy_savecal_nphy(pi);
++
++			pi->mphase_cal_phase_id++;
++			break;
++
++		case MPHASE_CAL_STATE_RSSICAL:
++			if ((pi->radar_percal_mask & 0x4) != 0)
++				pi->nphy_rxcal_active = true;
++			wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
++			wlc_phy_rssi_cal_nphy(pi);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				wlc_phy_radio205x_vcocal_nphy(pi);
++
++			restore_tx_gain = true;
++
++			if (pi->first_cal_after_assoc)
++				pi->mphase_cal_phase_id++;
++			else
++				wlc_phy_cal_perical_mphase_reset(pi);
++
++			break;
++
++		case MPHASE_CAL_STATE_IDLETSSI:
++			if ((pi->radar_percal_mask & 0x8) != 0)
++				pi->nphy_rxcal_active = true;
++
++			if (pi->first_cal_after_assoc) {
++				pi->first_cal_after_assoc = false;
++				wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
++				wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++			}
++
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++
++		default:
++			wlc_phy_cal_perical_mphase_reset(pi);
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++		if (restore_tx_gain) {
++			if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
++
++				wlc_phy_txpwr_index_nphy(pi, 1,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [0], false);
++				wlc_phy_txpwr_index_nphy(pi, 2,
++							 pi->
++							 nphy_cal_orig_pwr_idx
++							 [1], false);
++
++				pi->nphy_txpwrindex[0].index = -1;
++				pi->nphy_txpwrindex[1].index = -1;
++			} else {
++				wlc_phy_txpwr_index_nphy(pi, (1 << 0),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [0].
++							       index_internal),
++							 false);
++				wlc_phy_txpwr_index_nphy(pi, (1 << 1),
++							 (s8) (pi->
++							       nphy_txpwrindex
++							       [1].
++							       index_internal),
++							 false);
++			}
++		}
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++	wlc_phyreg_exit((struct brcms_phy_pub *) pi);
++	wlapi_enable_mac(pi->sh->physhim);
++}
++
++int
++wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++			bool fullcal, bool mphase)
++{
++	u16 val;
++	u16 tbl_buf[11];
++	u8 cal_cnt;
++	u16 cal_cmd;
++	u8 num_cals, max_cal_cmds;
++	u16 core_no, cal_type;
++	u16 diq_start = 0;
++	u8 phy_bw;
++	u16 max_val;
++	u16 tone_freq;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u32 tbl_len;
++	void *tbl_ptr;
++	bool ladder_updated[2];
++	u8 mphase_cal_lastphase = 0;
++	int bcmerror = 0;
++	bool phyhang_avoid_state = false;
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
++		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
++		0x1902,
++		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
++		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
++		0x3200,
++		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
++		0x6407
++	};
++
++	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
++		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
++		0x1202,
++		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
++		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
++		0x2300,
++		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
++		0x4707
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
++		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
++		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
++		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
++		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
++	};
++
++	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
++		0x0000
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
++		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
++		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
++	};
++
++	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
++		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
++		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
++	};
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	if (CHSPEC_IS40(pi->radio_chanspec))
++		phy_bw = 40;
++	else
++		phy_bw = 20;
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	wlc_phy_txcal_radio_setup_nphy(pi);
++
++	wlc_phy_txcal_physetup_nphy(pi);
++
++	ladder_updated[0] = ladder_updated[1] = false;
++	if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
++	      (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
++	       && (CHSPEC_IS2G(pi->radio_chanspec))))) {
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
++					 16, tbl_ptr);
++
++		if (phy_bw == 40) {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
++		} else {
++			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
++			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
++					 16, tbl_ptr);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		write_phy_reg(pi, 0xc2, 0x8ad9);
++	else
++		write_phy_reg(pi, 0xc2, 0x8aa9);
++
++	max_val = 250;
++	tone_freq = (phy_bw == 20) ? 2500 : 5000;
++
++	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
++		bcmerror = 0;
++	} else {
++		bcmerror =
++			wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0,
++					     false);
++	}
++
++	if (bcmerror == 0) {
++
++		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
++			tbl_ptr = pi->mphase_txcal_bestcoeffs;
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++		} else {
++			if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
++
++				tbl_ptr = pi->nphy_txiqlocal_bestc;
++				tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++				if (NREV_LT(pi->pubpi.phy_rev, 3))
++					tbl_len -= 2;
++			} else {
++
++				fullcal = true;
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					tbl_ptr =
++					    tbl_tx_iqlo_cal_startcoefs_nphyrev3;
++					tbl_len = ARRAY_SIZE(
++					   tbl_tx_iqlo_cal_startcoefs_nphyrev3);
++				} else {
++					tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
++					tbl_len = ARRAY_SIZE(
++						    tbl_tx_iqlo_cal_startcoefs);
++				}
++			}
++		}
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
++					 16, tbl_ptr);
++
++		if (fullcal) {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
++		} else {
++			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++				       ARRAY_SIZE(
++				tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
++				       ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
++		}
++
++		if (mphase) {
++			cal_cnt = pi->mphase_txcal_cmdidx;
++			if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds)
++				num_cals = cal_cnt + pi->mphase_txcal_numcmds;
++			else
++				num_cals = max_cal_cmds;
++		} else {
++			cal_cnt = 0;
++			num_cals = max_cal_cmds;
++		}
++
++		for (; cal_cnt < num_cals; cal_cnt++) {
++
++			if (fullcal) {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
++					  [cal_cnt] :
++					  tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
++			} else {
++				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
++					  tbl_tx_iqlo_cal_cmds_recal_nphyrev3[
++					cal_cnt]
++					  : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
++			}
++
++			core_no = ((cal_cmd & 0x3000) >> 12);
++			cal_type = ((cal_cmd & 0x0F00) >> 8);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 6) ||
++			    (NREV_IS(pi->pubpi.phy_rev, 5) &&
++			     PHY_IPA(pi)
++			     && (CHSPEC_IS2G(pi->radio_chanspec)))) {
++				if (!ladder_updated[core_no]) {
++					wlc_phy_update_txcal_ladder_nphy(
++						pi,
++						core_no);
++					ladder_updated[core_no] = true;
++				}
++			}
++
++			val =
++				(cal_params[core_no].
++				 ncorr[cal_type] << 8) | NPHY_N_GCTL;
++			write_phy_reg(pi, 0xc1, val);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++							1, 69 + core_no, 16,
++							tbl_buf);
++
++				diq_start = tbl_buf[0];
++
++				tbl_buf[0] = 0;
++				wlc_phy_table_write_nphy(pi,
++							 NPHY_TBL_ID_IQLOCAL, 1,
++							 69 + core_no, 16,
++							 tbl_buf);
++			}
++
++			write_phy_reg(pi, 0xc0, cal_cmd);
++
++			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
++				 20000);
++			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
++				 "HW error: txiq calib"))
++				return -EIO;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						 tbl_len, 64, 16, tbl_buf);
++
++			if ((cal_type == 1) || (cal_type == 3)
++			    || (cal_type == 4)) {
++
++				tbl_buf[0] = diq_start;
++
++			}
++
++		}
++
++		if (mphase) {
++			pi->mphase_txcal_cmdidx = num_cals;
++			if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
++				pi->mphase_txcal_cmdidx = 0;
++		}
++
++		mphase_cal_lastphase =
++			(NREV_LE(pi->pubpi.phy_rev, 2)) ?
++			MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
++
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, tbl_buf);
++
++			if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++
++				tbl_buf[0] = 0;
++				tbl_buf[1] = 0;
++				tbl_buf[2] = 0;
++				tbl_buf[3] = 0;
++
++			}
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
++						16, tbl_buf);
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16, tbl_buf);
++
++			tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->nphy_txiqlocal_bestc);
++
++			pi->nphy_txiqlocal_coeffsvalid = true;
++			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
++		} else {
++			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
++			if (NREV_LT(pi->pubpi.phy_rev, 3))
++				tbl_len -= 2;
++
++			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++						tbl_len, 96, 16,
++						pi->mphase_txcal_bestcoeffs);
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++
++		write_phy_reg(pi, 0xc2, 0x0000);
++
++	}
++
++	wlc_phy_txcal_phycleanup_nphy(pi);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_txcal_radio_cleanup_nphy(pi);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
++		if (!mphase
++		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
++			wlc_phy_tx_iq_war_nphy(pi);
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi)
++{
++	u16 tbl_buf[7];
++
++	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
++	    (pi->nphy_txiqlocal_coeffsvalid)) {
++		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
++					ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
++
++		if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
++		    (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
++		    (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
++		    (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
++						 16, pi->nphy_txiqlocal_bestc);
++
++			tbl_buf[0] = 0;
++			tbl_buf[1] = 0;
++			tbl_buf[2] = 0;
++			tbl_buf[3] = 0;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
++						 16, tbl_buf);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
++						 16,
++						 &pi->nphy_txiqlocal_bestc[5]);
++		}
++	}
++}
++
++void
++wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write,
++			  struct nphy_iq_comp *pcomp)
++{
++	if (write) {
++		write_phy_reg(pi, 0x9a, pcomp->a0);
++		write_phy_reg(pi, 0x9b, pcomp->b0);
++		write_phy_reg(pi, 0x9c, pcomp->a1);
++		write_phy_reg(pi, 0x9d, pcomp->b1);
++	} else {
++		pcomp->a0 = read_phy_reg(pi, 0x9a);
++		pcomp->b0 = read_phy_reg(pi, 0x9b);
++		pcomp->a1 = read_phy_reg(pi, 0x9c);
++		pcomp->b1 = read_phy_reg(pi, 0x9d);
++	}
++}
++
++void
++wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est,
++		       u16 num_samps, u8 wait_time, u8 wait_for_crs)
++{
++	u8 core;
++
++	write_phy_reg(pi, 0x12b, num_samps);
++	mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
++		    (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
++
++	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
++
++	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
++		 10000);
++	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
++		 "HW error: rxiq est"))
++		return;
++
++	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
++		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++			est[core].i_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestipwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
++			est[core].q_pwr =
++				(read_phy_reg(pi,
++					      NPHY_IqestqpwrAccHi(core)) << 16)
++				| read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
++			est[core].iq_prod =
++				(read_phy_reg(pi,
++					      NPHY_IqestIqAccHi(core)) << 16) |
++				read_phy_reg(pi, NPHY_IqestIqAccLo(core));
++		}
++	}
++}
++
++#define CAL_RETRY_CNT 2
++static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask)
++{
++	u8 curr_core;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	struct nphy_iq_comp old_comp, new_comp;
++	s32 iq = 0;
++	u32 ii = 0, qq = 0;
++	s16 iq_nbits, qq_nbits, brsh, arsh;
++	s32 a, b, temp;
++	int bcmerror = 0;
++	uint cal_retry = 0;
++
++	if (core_mask == 0x0)
++		return;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
++	new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++
++cal_try:
++	wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
++
++	new_comp = old_comp;
++
++	for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			iq = est[curr_core].iq_prod;
++			ii = est[curr_core].i_pwr;
++			qq = est[curr_core].q_pwr;
++		} else {
++			continue;
++		}
++
++		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
++			bcmerror = -EBADE;
++			break;
++		}
++
++		iq_nbits = wlc_phy_nbits(iq);
++		qq_nbits = wlc_phy_nbits(qq);
++
++		arsh = 10 - (30 - iq_nbits);
++		if (arsh >= 0) {
++			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
++			temp = (s32) (ii >> arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
++			temp = (s32) (ii << -arsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++
++		a /= temp;
++
++		brsh = qq_nbits - 31 + 20;
++		if (brsh >= 0) {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii >> brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		} else {
++			b = (qq << (31 - qq_nbits));
++			temp = (s32) (ii << -brsh);
++			if (temp == 0) {
++				bcmerror = -EBADE;
++				break;
++			}
++		}
++		b /= temp;
++		b -= a * a;
++		b = (s32) int_sqrt((unsigned long) b);
++		b -= (1 << 10);
++
++		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a0 = (s16) a & 0x3ff;
++				new_comp.b0 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a0 = (s16) b & 0x3ff;
++				new_comp.b0 = (s16) a & 0x3ff;
++			}
++		}
++		if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				new_comp.a1 = (s16) a & 0x3ff;
++				new_comp.b1 = (s16) b & 0x3ff;
++			} else {
++
++				new_comp.a1 = (s16) b & 0x3ff;
++				new_comp.b1 = (s16) a & 0x3ff;
++			}
++		}
++	}
++
++	if (bcmerror != 0) {
++		pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry);
++
++		if (cal_retry < CAL_RETRY_CNT) {
++			cal_retry++;
++			goto cal_try;
++		}
++
++		new_comp = old_comp;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
++}
++
++static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u16 offtune_val;
++	u16 bias_g = 0;
++	u16 bias_a = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
++
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					0x3);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					0xaf);
++
++			} else {
++				pi->tx_rx_cal_radio_saveregs[0] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
++				pi->tx_rx_cal_radio_saveregs[1] =
++					read_radio_reg(pi,
++					    RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
++
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					0x3);
++				write_radio_reg(pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					0x7f);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX1);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX0);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX0);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX1);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_MASTER
++						      | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1, bias_a);
++
++					write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->tx_rx_cal_radio_saveregs
++						 [2] & 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX0);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX1, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX0, bias_g);
++
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX0);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX0, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX1, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX0, 0x6);
++			}
++
++		} else {
++			pi->tx_rx_cal_radio_saveregs[0] =
++				read_radio_reg(pi,
++					       RADIO_2056_TX_RXIQCAL_TXMUX |
++					       RADIO_2056_TX0);
++			pi->tx_rx_cal_radio_saveregs[1] =
++				read_radio_reg(pi,
++					       RADIO_2056_RX_RXIQCAL_RXMUX |
++					       RADIO_2056_RX1);
++
++			if (pi->pubpi.radiorev >= 5) {
++				pi->tx_rx_cal_radio_saveregs[2] =
++					read_radio_reg(pi,
++						       RADIO_2056_RX_RXSPARE2 |
++						       RADIO_2056_RX1);
++				pi->tx_rx_cal_radio_saveregs[3] =
++					read_radio_reg(pi,
++						       RADIO_2056_TX_TXSPARE2 |
++						       RADIO_2056_TX0);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						       pi,
++						       RADIO_2056_RX_LNAA_MASTER
++						       | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER |
++						RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_a);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_a);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAA_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAA_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x9);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x9);
++			} else {
++				if (pi->pubpi.radiorev >= 5) {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++						      pi,
++						      RADIO_2056_RX_LNAG_MASTER
++						    | RADIO_2056_RX1);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1, 0x40);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_TX_TXSPARE2
++						|
++						RADIO_2056_TX0, bias_g);
++
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_RXSPARE2
++						|
++						RADIO_2056_RX1, bias_g);
++				} else {
++					pi->tx_rx_cal_radio_saveregs[4] =
++						read_radio_reg(
++							pi,
++							RADIO_2056_RX_LNAG_TUNE
++							| RADIO_2056_RX1);
++
++					offtune_val =
++						(pi->
++						 tx_rx_cal_radio_saveregs[2] &
++						 0xF0) >> 8;
++					offtune_val =
++						(offtune_val <= 0x7) ? 0xF : 0;
++
++					mod_radio_reg(pi,
++						      RADIO_2056_RX_LNAG_TUNE |
++						      RADIO_2056_RX1, 0xF0,
++						      (offtune_val << 8));
++				}
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_RXIQCAL_TXMUX |
++						RADIO_2056_TX0, 0x6);
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXIQCAL_RXMUX |
++						RADIO_2056_RX1, 0x6);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		if (rx_core == PHY_CORE_0) {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++
++		} else {
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++
++			} else {
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
++					pi->
++					tx_rx_cal_radio_saveregs[0]);
++				write_radio_reg(
++					pi,
++					RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
++					pi->
++					tx_rx_cal_radio_saveregs[1]);
++			}
++		}
++
++	} else {
++		if (rx_core == PHY_CORE_0) {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX1,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX0,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX1,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX0,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++
++		} else {
++			write_radio_reg(pi,
++					RADIO_2056_TX_RXIQCAL_TXMUX |
++					RADIO_2056_TX0,
++					pi->tx_rx_cal_radio_saveregs[0]);
++
++			write_radio_reg(pi,
++					RADIO_2056_RX_RXIQCAL_RXMUX |
++					RADIO_2056_RX1,
++					pi->tx_rx_cal_radio_saveregs[1]);
++
++			if (pi->pubpi.radiorev >= 5) {
++				write_radio_reg(pi,
++						RADIO_2056_RX_RXSPARE2 |
++						RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs[2]);
++
++				write_radio_reg(pi,
++						RADIO_2056_TX_TXSPARE2 |
++						RADIO_2056_TX0,
++						pi->
++						tx_rx_cal_radio_saveregs[3]);
++			}
++
++			if (CHSPEC_IS5G(pi->radio_chanspec)) {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAA_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			} else {
++				if (pi->pubpi.radiorev >= 5)
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_MASTER
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++				else
++					write_radio_reg(
++						pi,
++						RADIO_2056_RX_LNAG_TUNE
++						| RADIO_2056_RX1,
++						pi->
++						tx_rx_cal_radio_saveregs
++						[4]);
++			}
++		}
++	}
++}
++
++static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++	u8 tx_core;
++	u16 rx_antval, tx_antval;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
++
++	pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
++	pi->tx_rx_cal_phy_saveregs[1] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
++	pi->tx_rx_cal_phy_saveregs[2] =
++		read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
++	pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
++	pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
++	pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
++	pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
++	pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
++	pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
++		pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
++		pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
++		pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
++	}
++
++	pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
++	pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
++	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++		    0x29b, (0x1 << 0), (0) << 0);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
++
++	} else {
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++		mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
++		mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
++	}
++
++	mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
++	mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		    (0x1 << 2), (0x1 << 2));
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++		mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			    (0x1 << 0) | (0x1 << 1), 0);
++		mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++			    0x8f : 0xa5,
++			    (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
++	}
++
++	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
++					 RADIO_MIMO_CORESEL_CORE1 |
++					 RADIO_MIMO_CORESEL_CORE2);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		if (CHSPEC_IS40(pi->radio_chanspec))
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				2, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		else
++			wlc_phy_rfctrl_override_nphy_rev7(
++				pi,
++				(0x1 << 7),
++				0, 0, 0,
++				NPHY_REV7_RFCTRLOVERRIDE_ID1);
++
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
++						  0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
++						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
++	} else {
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
++	}
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 0x1, rx_core + 1);
++	} else {
++
++		if (rx_core == PHY_CORE_0) {
++			rx_antval = 0x1;
++			tx_antval = 0x8;
++		} else {
++			rx_antval = 0x4;
++			tx_antval = 0x2;
++		}
++
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 rx_antval, rx_core + 1);
++		wlc_phy_rfctrlintc_override_nphy(pi,
++						 NPHY_RfctrlIntc_override_TRSW,
++						 tx_antval, tx_core + 1);
++	}
++}
++
++static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core)
++{
++
++	write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
++		      pi->tx_rx_cal_phy_saveregs[1]);
++	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
++		      pi->tx_rx_cal_phy_saveregs[2]);
++	write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
++	write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
++
++	write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
++	write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
++	write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
++	write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
++		write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
++		write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
++		write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
++	}
++
++	write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
++	write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core,
++				 u16 *rxgain, u8 cal_type)
++{
++
++	u16 num_samps;
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 tx_core;
++	struct nphy_iq_comp save_comp, zero_comp;
++	u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0,
++	    thresh_pwr = 10000;
++	s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
++	bool gainctrl_done = false;
++	u8 mix_tia_gain = 3;
++	s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
++	s8 curr_gaintbl_index = 3;
++	u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
++	const struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl;
++	u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
++	int fine_gain_idx;
++	s8 txpwrindex;
++	u16 nphy_rxcal_txgain[2];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		tx_core = rx_core;
++	else
++		tx_core = 1 - rx_core;
++
++	num_samps = 1024;
++	desired_log2_pwr = (cal_type == 0) ? 13 : 13;
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
++	zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
++
++	if (CHSPEC_IS5G(pi->radio_chanspec)) {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			mix_tia_gain = 3;
++		else if (NREV_GE(pi->pubpi.phy_rev, 4))
++			mix_tia_gain = 4;
++		else
++			mix_tia_gain = 6;
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
++	} else {
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
++		else
++			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
++	}
++
++	do {
++
++		hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
++			0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
++		lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
++		lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
++		lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
++		lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
++		txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
++
++		if (NREV_GE(pi->pubpi.phy_rev, 7))
++			wlc_phy_rfctrl_override_1tomany_nphy(
++				pi,
++				NPHY_REV7_RfctrlOverride_cmd_rxgain,
++				((lpf_biq1 << 12) |
++				 (lpf_biq0 << 8) |
++				 (mix_tia_gain << 4) | (lna2 << 2)
++				 | lna1), 0x3, 0);
++		else
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++						     ((hpvga << 12) |
++						      (lpf_biq1 << 10) |
++						      (lpf_biq0 << 8) |
++						      (mix_tia_gain << 4) |
++						      (lna2 << 2) | lna1), 0x3,
++						     0);
++
++		pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
++
++		if (txpwrindex == -1) {
++			nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
++			nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
++			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
++						 2, 0x110, 16,
++						 nphy_rxcal_txgain);
++		} else {
++			wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
++						 false);
++		}
++
++		wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
++				     NPHY_RXCAL_TONEFREQ_40MHz :
++				     NPHY_RXCAL_TONEFREQ_20MHz,
++				     NPHY_RXCAL_TONEAMP, 0, cal_type, false);
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++		i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
++		q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
++		curr_pwr = i_pwr + q_pwr;
++
++		switch (gainctrl_dirn) {
++		case NPHY_RXCAL_GAIN_INIT:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_UP:
++			if (curr_pwr > thresh_pwr) {
++				gainctrl_done = true;
++				optim_pwr = prev_pwr;
++				optim_gaintbl_index = prev_gaintbl_index;
++			} else {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index++;
++			}
++			break;
++
++		case NPHY_RXCAL_GAIN_DOWN:
++			if (curr_pwr > thresh_pwr) {
++				prev_gaintbl_index = curr_gaintbl_index;
++				curr_gaintbl_index--;
++			} else {
++				gainctrl_done = true;
++				optim_pwr = curr_pwr;
++				optim_gaintbl_index = curr_gaintbl_index;
++			}
++			break;
++
++		default:
++			break;
++		}
++
++		if ((curr_gaintbl_index < 0) ||
++		    (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
++			gainctrl_done = true;
++			optim_pwr = curr_pwr;
++			optim_gaintbl_index = prev_gaintbl_index;
++		} else {
++			prev_pwr = curr_pwr;
++		}
++
++		wlc_phy_stopplayback_nphy(pi);
++	} while (!gainctrl_done);
++
++	hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
++	lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
++	lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
++	lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
++	lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
++	txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
++
++	actual_log2_pwr = wlc_phy_nbits(optim_pwr);
++	delta_pwr = desired_log2_pwr - actual_log2_pwr;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++		fine_gain_idx = (int)lpf_biq1 + delta_pwr;
++
++		if (fine_gain_idx + (int)lpf_biq0 > 10)
++			lpf_biq1 = 10 - lpf_biq0;
++		else
++			lpf_biq1 = (u16) max(fine_gain_idx, 0);
++
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			((lpf_biq1 << 12) |
++			 (lpf_biq0 << 8) |
++			 (mix_tia_gain << 4) |
++			 (lna2 << 2) | lna1), 0x3,
++			0);
++	} else {
++		hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
++					     ((hpvga << 12) |
++					      (lpf_biq1 << 10) |
++					      (lpf_biq0 << 8) |
++					      (mix_tia_gain << 4) |
++					      (lna2 << 2) |
++					      lna1), 0x3, 0);
++	}
++
++	if (rxgain != NULL) {
++		*rxgain++ = lna1;
++		*rxgain++ = lna2;
++		*rxgain++ = mix_tia_gain;
++		*rxgain++ = lpf_biq0;
++		*rxgain++ = lpf_biq1;
++		*rxgain = hpvga;
++	}
++
++	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
++}
++
++static void
++wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain,
++			    u8 cal_type)
++{
++	wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
++}
++
++static u8
++wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type)
++{
++	u32 target_bws[2] = { 9500, 21000 };
++	u32 ref_tones[2] = { 3000, 6000 };
++	u32 target_bw, ref_tone;
++
++	u32 target_pwr_ratios[2] = { 28606, 18468 };
++	u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
++
++	u16 start_rccal_ovr_val = 128;
++	u16 txlpf_rccal_lpc_ovr_val = 128;
++	u16 rxlpf_rccal_hpc_ovr_val = 159;
++
++	u16 orig_txlpf_rccal_lpc_ovr_val;
++	u16 orig_rxlpf_rccal_hpc_ovr_val;
++	u16 radio_addr_offset_rx;
++	u16 radio_addr_offset_tx;
++	u16 orig_dcBypass;
++	u16 orig_RxStrnFilt40Num[6];
++	u16 orig_RxStrnFilt40Den[4];
++	u16 orig_rfctrloverride[2];
++	u16 orig_rfctrlauxreg[2];
++	u16 orig_rfctrlrssiothers;
++	u16 tx_lpf_bw = 4;
++
++	u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
++	u16 lpf_hpc = 7, hpvga_hpc = 7;
++
++	s8 rccal_stepsize;
++	u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
++	u32 ref_iq_vals = 0, target_iq_vals = 0;
++	u16 num_samps, log_num_samps = 10;
++	struct phy_iq_est est[PHY_CORE_MAX];
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		return 0;
++
++	num_samps = (1 << log_num_samps);
++
++	if (CHSPEC_IS40(pi->radio_chanspec)) {
++		target_bw = target_bws[1];
++		target_pwr_ratio = target_pwr_ratios[1];
++		ref_tone = ref_tones[1];
++		rx_lpf_bw = rx_lpf_bws[1];
++	} else {
++		target_bw = target_bws[0];
++		target_pwr_ratio = target_pwr_ratios[0];
++		ref_tone = ref_tones[0];
++		rx_lpf_bw = rx_lpf_bws[0];
++	}
++
++	if (core_idx == 0) {
++		radio_addr_offset_rx = RADIO_2056_RX0;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
++	} else {
++		radio_addr_offset_rx = RADIO_2056_RX1;
++		radio_addr_offset_tx =
++			(loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
++	}
++
++	orig_txlpf_rccal_lpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_TX_TXLPF_RCCAL |
++				radio_addr_offset_tx));
++	orig_rxlpf_rccal_hpc_ovr_val =
++		read_radio_reg(pi,
++			       (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++				radio_addr_offset_rx));
++
++	orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
++
++	orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
++	orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
++	orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
++	orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
++	orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
++	orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
++	orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
++	orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
++	orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
++	orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
++
++	orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
++	orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
++	orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
++	orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
++	orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			txlpf_rccal_lpc_ovr_val);
++
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
++
++	write_phy_reg(pi, 0x267, 0x02d4);
++	write_phy_reg(pi, 0x268, 0x0000);
++	write_phy_reg(pi, 0x269, 0x0000);
++	write_phy_reg(pi, 0x26a, 0x0000);
++	write_phy_reg(pi, 0x26b, 0x0000);
++	write_phy_reg(pi, 0x26c, 0x02d4);
++	write_phy_reg(pi, 0x26d, 0x0000);
++	write_phy_reg(pi, 0x26e, 0x0000);
++	write_phy_reg(pi, 0x26f, 0x0000);
++	write_phy_reg(pi, 0x270, 0x0000);
++
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
++	or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
++	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
++
++	mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
++		    (0x7 << 10), (tx_lpf_bw << 10));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 0), (hpvga_hpc << 0));
++	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
++		    (0x7 << 4), (lpf_hpc << 4));
++	mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
++		    (0x7 << 8), (rx_lpf_bw << 8));
++
++	rccal_stepsize = 16;
++	rccal_val = start_rccal_ovr_val + rccal_stepsize;
++
++	while (rccal_stepsize >= 0) {
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 radio_addr_offset_rx), rccal_val);
++
++		if (rccal_stepsize == 16) {
++
++			wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++
++			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++			if (core_idx == 0)
++				ref_iq_vals =
++					max_t(u32, (est[0].i_pwr +
++						    est[0].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++			else
++				ref_iq_vals =
++					max_t(u32, (est[1].i_pwr +
++						    est[1].q_pwr) >>
++					      (log_num_samps + 1),
++					      1);
++
++			wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
++					     0, 1, false);
++			udelay(2);
++		}
++
++		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
++
++		if (core_idx == 0)
++			target_iq_vals = (est[0].i_pwr + est[0].q_pwr) >>
++					 (log_num_samps + 1);
++		else
++			target_iq_vals =
++				(est[1].i_pwr +
++				 est[1].q_pwr) >> (log_num_samps + 1);
++
++		pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
++
++		if (rccal_stepsize == 0)
++			rccal_stepsize--;
++		else if (rccal_stepsize == 1) {
++			last_rccal_val = rccal_val;
++			rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
++			last_pwr_ratio = pwr_ratio;
++			rccal_stepsize--;
++		} else {
++			rccal_stepsize = (rccal_stepsize >> 1);
++			rccal_val += ((pwr_ratio > target_pwr_ratio) ?
++				      rccal_stepsize : (-rccal_stepsize));
++		}
++
++		if (rccal_stepsize == -1) {
++			best_rccal_val =
++				(abs((int)last_pwr_ratio -
++				     (int)target_pwr_ratio) <
++				 abs((int)pwr_ratio -
++				     (int)target_pwr_ratio)) ? last_rccal_val :
++				rccal_val;
++
++			if (CHSPEC_IS40(pi->radio_chanspec)) {
++				if ((best_rccal_val > 140)
++				    || (best_rccal_val < 135))
++					best_rccal_val = 138;
++			} else {
++				if ((best_rccal_val > 142)
++				    || (best_rccal_val < 137))
++					best_rccal_val = 140;
++			}
++
++			write_radio_reg(pi,
++					(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++					 radio_addr_offset_rx), best_rccal_val);
++		}
++	}
++
++	wlc_phy_stopplayback_nphy(pi);
++
++	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
++			orig_txlpf_rccal_lpc_ovr_val);
++	write_radio_reg(pi,
++			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
++			orig_rxlpf_rccal_hpc_ovr_val);
++
++	mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
++
++	write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
++	write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
++	write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
++	write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
++	write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
++	write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
++	write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
++	write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
++	write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
++	write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
++
++	write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
++	write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
++	write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
++	write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
++	write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
++
++	pi->nphy_anarxlpf_adjusted = false;
++
++	return best_rccal_val - 0x80;
++}
++
++#define WAIT_FOR_SCOPE  4000
++static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi,
++				      struct nphy_txgains target_gain,
++				      u8 cal_type, bool debug)
++{
++	u16 orig_BBConfig;
++	u8 core_no, rx_core;
++	u8 best_rccal[2];
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 rxcore_state;
++	s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
++	s8 txlpf_idac;
++	bool phyhang_avoid_state = false;
++	bool skip_rxiqcal = false;
++
++	orig_BBConfig = read_phy_reg(pi, 0x01);
++	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
++		phyhang_avoid_state = pi->phyhang_avoid;
++		pi->phyhang_avoid = false;
++	}
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	rxcore_state = wlc_phy_rxcore_getstate_nphy(
++		(struct brcms_phy_pub *) pi);
++
++	for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++
++		skip_rxiqcal =
++			((rxcore_state & (1 << rx_core)) == 0) ? true : false;
++
++		wlc_phy_rxcal_physetup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
++
++		if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
++
++			wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
++
++			wlc_phy_tx_tone_nphy(pi,
++					     (CHSPEC_IS40(
++						      pi->radio_chanspec)) ?
++					     NPHY_RXCAL_TONEFREQ_40MHz :
++					     NPHY_RXCAL_TONEFREQ_20MHz,
++					     NPHY_RXCAL_TONEAMP, 0, cal_type,
++					     false);
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
++			wlc_phy_stopplayback_nphy(pi);
++		}
++
++		if (((cal_type == 1) || (cal_type == 2))
++		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++			if (rx_core == PHY_CORE_1) {
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi, 3);
++
++				wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
++							    1);
++
++				best_rccal[rx_core] =
++					wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
++				pi->nphy_rccal_value = best_rccal[rx_core];
++
++				if (rxcore_state == 1)
++					wlc_phy_rxcore_setstate_nphy(
++						(struct brcms_phy_pub *) pi,
++						rxcore_state);
++			}
++		}
++
++		wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
++
++		wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
++		wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++	}
++
++	if ((cal_type == 1) || (cal_type == 2)) {
++
++		best_rccal[0] = best_rccal[1];
++		write_radio_reg(pi,
++				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
++				 RADIO_2056_RX0), (best_rccal[0] | 0x80));
++
++		for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
++			rxlpf_rccal_hpc =
++				(((int)best_rccal[rx_core] - 12) >> 1) + 10;
++			txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
++
++			if (PHY_IPA(pi)) {
++				txlpf_rccal_lpc +=
++					(pi->bw == WL_CHANSPEC_BW_40) ? 24 : 12;
++				txlpf_idac = (pi->bw == WL_CHANSPEC_BW_40) ?
++					     0x0e : 0x13;
++				WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
++						 TXLPF_IDAC_4, txlpf_idac);
++			}
++
++			rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31),
++					      0);
++			txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31),
++					      0);
++
++			write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_RX0 :
++					      RADIO_2056_RX1)),
++					(rxlpf_rccal_hpc | 0x80));
++
++			write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
++					     ((rx_core ==
++					       PHY_CORE_0) ? RADIO_2056_TX0 :
++					      RADIO_2056_TX1)),
++					(txlpf_rccal_lpc | 0x80));
++		}
++	}
++
++	write_phy_reg(pi, 0x01, orig_BBConfig);
++
++	wlc_phy_resetcca_nphy(pi);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		wlc_phy_rfctrl_override_1tomany_nphy(
++			pi,
++			NPHY_REV7_RfctrlOverride_cmd_rxgain,
++			0, 0x3, 1);
++	else
++		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
++
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	if (NREV_GE(pi->pubpi.phy_rev, 4))
++		pi->phyhang_avoid = phyhang_avoid_state;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return 0;
++}
++
++static int
++wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi,
++			   struct nphy_txgains target_gain, bool debug)
++{
++	struct phy_iq_est est[PHY_CORE_MAX];
++	u8 core_num, rx_core, tx_core;
++	u16 lna_vals[] = { 0x3, 0x3, 0x1 };
++	u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
++	u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
++	s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
++	s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
++	u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
++	u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
++	u16 num_samps;
++	u32 i_pwr, q_pwr, tot_pwr[3];
++	u8 gain_pass, use_hpf_num;
++	u16 mask, val1, val2;
++	u16 core_no;
++	u16 gain_save[2];
++	u16 cal_gain[2];
++	struct nphy_iqcal_params cal_params[2];
++	u8 phy_bw;
++	int bcmerror = 0;
++	bool first_playtone = true;
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (NREV_LT(pi->pubpi.phy_rev, 2))
++		wlc_phy_reapply_txcal_coeffs_nphy(pi);
++
++	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
++
++	for (core_no = 0; core_no <= 1; core_no++) {
++		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
++					      &cal_params[core_no]);
++		cal_gain[core_no] = cal_params[core_no].cal_gain;
++	}
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
++
++	num_samps = 1024;
++	desired_log2_pwr = 13;
++
++	for (core_num = 0; core_num < 2; core_num++) {
++
++		rx_core = core_num;
++		tx_core = 1 - core_num;
++
++		orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
++		orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						0xa6 : 0xa7);
++		orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
++		orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++		orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
++						 0x91 : 0x92);
++
++		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
++		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
++
++		or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
++			   ((0x1 << 1) | (0x1 << 2)));
++		or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
++
++		if (((pi->nphy_rxcalparams) & 0xff000000))
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++					0x140 : 0x110));
++		else
++			write_phy_reg(pi,
++				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
++				      (CHSPEC_IS5G(pi->radio_chanspec) ?
++				       0x180 : 0x120));
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
++			      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
++			       0x114));
++
++		mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
++		if (rx_core == PHY_CORE_0) {
++			val1 = RADIO_2055_COUPLE_RX_MASK;
++			val2 = RADIO_2055_COUPLE_TX_MASK;
++		} else {
++			val1 = RADIO_2055_COUPLE_TX_MASK;
++			val2 = RADIO_2055_COUPLE_RX_MASK;
++		}
++
++		if ((pi->nphy_rxcalparams & 0x10000)) {
++			mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
++				      val1);
++			mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
++				      val2);
++		}
++
++		for (gain_pass = 0; gain_pass < 4; gain_pass++) {
++
++			if (debug)
++				mdelay(WAIT_FOR_SCOPE);
++
++			if (gain_pass < 3) {
++				curr_lna = lna_vals[gain_pass];
++				curr_hpf1 = hpf1_vals[gain_pass];
++				curr_hpf2 = hpf2_vals[gain_pass];
++			} else {
++
++				if (tot_pwr[1] > 10000) {
++					curr_lna = lna_vals[2];
++					curr_hpf1 = hpf1_vals[2];
++					curr_hpf2 = hpf2_vals[2];
++					use_hpf_num = 1;
++					curr_hpf = curr_hpf1;
++					actual_log2_pwr =
++						wlc_phy_nbits(tot_pwr[2]);
++				} else {
++					if (tot_pwr[0] > 10000) {
++						curr_lna = lna_vals[1];
++						curr_hpf1 = hpf1_vals[1];
++						curr_hpf2 = hpf2_vals[1];
++						use_hpf_num = 1;
++						curr_hpf = curr_hpf1;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[1]);
++					} else {
++						curr_lna = lna_vals[0];
++						curr_hpf1 = hpf1_vals[0];
++						curr_hpf2 = hpf2_vals[0];
++						use_hpf_num = 2;
++						curr_hpf = curr_hpf2;
++						actual_log2_pwr =
++							wlc_phy_nbits(
++								tot_pwr[0]);
++					}
++				}
++
++				hpf_change = desired_log2_pwr - actual_log2_pwr;
++				curr_hpf += hpf_change;
++				curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
++				if (use_hpf_num == 1)
++					curr_hpf1 = curr_hpf;
++				else
++					curr_hpf2 = curr_hpf;
++			}
++
++			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
++						     ((curr_hpf2 << 8) |
++						      (curr_hpf1 << 4) |
++						      (curr_lna << 2)), 0x3, 0);
++			wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++			wlc_phy_stopplayback_nphy(pi);
++
++			if (first_playtone) {
++				bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
++						(u16) (pi->nphy_rxcalparams &
++						       0xffff), 0, 0, true);
++				first_playtone = false;
++			} else {
++				phy_bw = (CHSPEC_IS40(pi->radio_chanspec)) ?
++					  40 : 20;
++				wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
++							0, 0, 0, true);
++			}
++
++			if (bcmerror == 0) {
++				if (gain_pass < 3) {
++
++					wlc_phy_rx_iq_est_nphy(pi, est,
++							       num_samps, 32,
++							       0);
++					i_pwr =	(est[rx_core].i_pwr +
++						 num_samps / 2) / num_samps;
++					q_pwr =	(est[rx_core].q_pwr +
++						 num_samps / 2) / num_samps;
++					tot_pwr[gain_pass] = i_pwr + q_pwr;
++				} else {
++
++					wlc_phy_calc_rx_iq_comp_nphy(pi,
++								     (1 <<
++								      rx_core));
++				}
++
++				wlc_phy_stopplayback_nphy(pi);
++			}
++
++			if (bcmerror != 0)
++				break;
++		}
++
++		and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
++		and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
++
++		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcTx);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
++			      0x92, orig_RfctrlIntcRx);
++		write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
++		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
++			      0xa7, orig_AfectrlCore);
++		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
++
++		if (bcmerror != 0)
++			break;
++	}
++
++	wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
++	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
++
++	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
++				 gain_save);
++
++	wlc_phy_stay_in_carriersearch_nphy(pi, false);
++
++	return bcmerror;
++}
++
++int
++wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
++		      u8 cal_type, bool debug)
++{
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		cal_type = 0;
++
++	if (NREV_GE(pi->pubpi.phy_rev, 3))
++		return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
++						  debug);
++	else
++		return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
++}
++
++void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi)
++{
++	uint core;
++	u32 txgain;
++	u16 rad_gain, dac_gain, bbmult, m1m2;
++	u8 txpi[2], chan_freq_range;
++	s32 rfpwr_offset;
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	if (pi->sh->sromrev < 4) {
++		txpi[0] = txpi[1] = 72;
++	} else {
++
++		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
++		switch (chan_freq_range) {
++		case WL_CHAN_FREQ_RANGE_2G:
++		case WL_CHAN_FREQ_RANGE_5GL:
++		case WL_CHAN_FREQ_RANGE_5GM:
++		case WL_CHAN_FREQ_RANGE_5GH:
++			txpi[0] = 0;
++			txpi[1] = 0;
++			break;
++		default:
++			txpi[0] = txpi[1] = 91;
++			break;
++		}
++	}
++
++	if (NREV_GE(pi->pubpi.phy_rev, 7))
++		txpi[0] = txpi[1] = 30;
++	else if (NREV_GE(pi->pubpi.phy_rev, 3))
++		txpi[0] = txpi[1] = 40;
++
++	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
++
++		if ((txpi[0] < 40) || (txpi[0] > 100) ||
++		    (txpi[1] < 40) || (txpi[1] > 100))
++			txpi[0] = txpi[1] = 91;
++	}
++
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
++	pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
++	pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++		uint phyrev = pi->pubpi.phy_rev;
++
++		if (NREV_GE(phyrev, 3)) {
++			if (PHY_IPA(pi)) {
++				u32 *tx_gaintbl =
++					wlc_phy_get_ipa_gaintbl_nphy(pi);
++				txgain = tx_gaintbl[txpi[core]];
++			} else {
++				if (CHSPEC_IS5G(pi->radio_chanspec)) {
++					if (NREV_IS(phyrev, 3)) {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev3
++								   [txpi[core]];
++					} else if (NREV_IS(phyrev, 4)) {
++						txgain = (
++						  pi->srom_fem5g.extpagain ==
++						  3) ?
++						  nphy_tpc_5GHz_txgain_HiPwrEPA
++						 [txpi[core]] :
++						 nphy_tpc_5GHz_txgain_rev4
++						 [txpi[core]];
++					} else {
++						txgain =
++						      nphy_tpc_5GHz_txgain_rev5
++								   [txpi[core]];
++					}
++				} else {
++					if (NREV_GE(phyrev, 5) &&
++					    (pi->srom_fem2g.extpagain == 3)) {
++						txgain =
++							nphy_tpc_txgain_HiPwrEPA
++							[txpi[core]];
++					} else {
++						txgain = nphy_tpc_txgain_rev3
++							 [txpi[core]];
++					}
++				}
++			}
++		} else {
++			txgain = nphy_tpc_txgain[txpi[core]];
++		}
++
++		if (NREV_GE(phyrev, 3))
++			rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
++		else
++			rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 7))
++			dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
++		else
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++
++		bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++		if (NREV_GE(phyrev, 3))
++			mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++					 0xa5), (0x1 << 8), (0x1 << 8));
++		else
++			mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++		write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
++
++		wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++					 &rad_gain);
++
++		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++		m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++		m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
++		wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++		if (PHY_IPA(pi)) {
++			wlc_phy_table_read_nphy(pi,
++						(core ==
++						 PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
++						576 + txpi[core], 32,
++						&rfpwr_offset);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1ff << 4),
++				    ((s16) rfpwr_offset) << 4);
++
++			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (1) << 2);
++
++		}
++	}
++
++	and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++static void
++wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
++				u8 tmp_max_pwr, u8 rate_start,
++				u8 rate_end)
++{
++	u8 rate;
++	u8 word_num, nibble_num;
++	u8 tmp_nibble;
++
++	for (rate = rate_start; rate <= rate_end; rate++) {
++		word_num = (rate - rate_start) >> 2;
++		nibble_num = (rate - rate_start) & 0x3;
++		tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
++
++		srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
++	}
++}
++
++static void
++wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
++			    u8 rate_start, u8 rate_end)
++{
++	u8 rate;
++
++	for (rate = rate_start; rate <= rate_end; rate++)
++		srom_max[rate] -= 2 * pwr_offset;
++}
++
++void
++wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
++				u8 rate_mcs_end, u8 rate_ofdm_start)
++{
++	u8 rate1, rate2;
++
++	rate2 = rate_ofdm_start;
++	for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
++		power[rate1] = power[rate2];
++		rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
++	}
++	power[rate_mcs_end] = power[rate_mcs_end - 1];
++}
++
++void
++wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
++				u8 rate_ofdm_end, u8 rate_mcs_start)
++{
++	u8 rate1, rate2;
++
++	for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
++	     rate1 <= rate_ofdm_end; rate1++, rate2++) {
++		power[rate1] = power[rate2];
++		if (rate1 == rate_ofdm_start)
++			power[++rate1] = power[rate2];
++	}
++}
++
++void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi)
++{
++	uint rate1, rate2, band_num;
++	u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
++	u8 tmp_max_pwr = 0;
++	u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
++	u8 *tx_srom_max_rate = NULL;
++
++	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP);
++	     band_num++) {
++		switch (band_num) {
++		case 0:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
++					  pi->nphy_pwrctrl_info[1].max_pwr_2g);
++
++			pwr_offsets1[0] = pi->cck2gpo;
++			wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
++							pwr_offsets1,
++							tmp_max_pwr,
++							TXP_FIRST_CCK,
++							TXP_LAST_CCK);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm2gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs2gpo;
++
++			tmp_cddpo = pi->cdd2gpo;
++			tmp_stbcpo = pi->stbc2gpo;
++			tmp_bw40po = pi->bw402gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_2g;
++			break;
++		case 1:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gm);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5gpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5gpo;
++
++			tmp_cddpo = pi->cdd5gpo;
++			tmp_stbcpo = pi->stbc5gpo;
++			tmp_bw40po = pi->bw405gpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
++			break;
++		case 2:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gl);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5glpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5glpo;
++
++			tmp_cddpo = pi->cdd5glpo;
++			tmp_stbcpo = pi->stbc5glpo;
++			tmp_bw40po = pi->bw405glpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
++			break;
++		case 3:
++
++			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
++					  pi->nphy_pwrctrl_info[1].max_pwr_5gh);
++
++			pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
++			pwr_offsets1[1] =
++				(u16) (pi->ofdm5ghpo >> 16) & 0xffff;
++
++			pwr_offsets2 = pi->mcs5ghpo;
++
++			tmp_cddpo = pi->cdd5ghpo;
++			tmp_stbcpo = pi->stbc5ghpo;
++			tmp_bw40po = pi->bw405ghpo;
++
++			tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
++			break;
++		}
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
++						tmp_max_pwr, TXP_FIRST_OFDM,
++						TXP_LAST_OFDM);
++
++		wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_MCS_20_SISO,
++						TXP_LAST_MCS_20_SISO,
++						TXP_FIRST_OFDM);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_CDD,
++						TXP_LAST_MCS_20_CDD);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_20_CDD,
++						    TXP_LAST_MCS_20_CDD);
++
++		wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++						TXP_FIRST_OFDM_20_CDD,
++						TXP_LAST_OFDM_20_CDD,
++						TXP_FIRST_MCS_20_CDD);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
++						tmp_max_pwr,
++						TXP_FIRST_MCS_20_STBC,
++						TXP_LAST_MCS_20_STBC);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_20_STBC,
++						    TXP_LAST_MCS_20_STBC);
++
++		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++						&pwr_offsets2[2], tmp_max_pwr,
++						TXP_FIRST_MCS_20_SDM,
++						TXP_LAST_MCS_20_SDM);
++
++		if (NPHY_IS_SROM_REINTERPRET) {
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SISO,
++							TXP_LAST_MCS_40_SISO);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_SISO,
++							TXP_LAST_OFDM_40_SISO,
++							TXP_FIRST_MCS_40_SISO);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_CDD,
++							TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
++						    TXP_FIRST_MCS_40_CDD,
++						    TXP_LAST_MCS_40_CDD);
++
++			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
++							TXP_FIRST_OFDM_40_CDD,
++							TXP_LAST_OFDM_40_CDD,
++							TXP_FIRST_MCS_40_CDD);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[4],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_STBC,
++							TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_stbcpo,
++						    TXP_FIRST_MCS_40_STBC,
++						    TXP_LAST_MCS_40_STBC);
++
++			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
++							&pwr_offsets2[6],
++							tmp_max_pwr,
++							TXP_FIRST_MCS_40_SDM,
++							TXP_LAST_MCS_40_SDM);
++		} else {
++
++			for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
++				     TXP_FIRST_OFDM;
++			     rate1 <= TXP_LAST_MCS_40_SDM;
++			     rate1++, rate2++)
++				tx_srom_max_rate[rate1] =
++					tx_srom_max_rate[rate2];
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
++						    tmp_bw40po,
++						    TXP_FIRST_OFDM_40_SISO,
++						    TXP_LAST_MCS_40_SDM);
++
++		tx_srom_max_rate[TXP_MCS_32] =
++			tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
++	}
++
++	return;
++}
++
++void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
++{
++	u8 tx_pwr_ctrl_state;
++	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
++	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
++
++	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
++		(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
++		udelay(1);
++	}
++
++	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++
++	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
++		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
++}
++
++static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi)
++{
++	return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
++					    (0x1 << 14) | (0x1 << 13));
++}
++
++u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi)
++{
++	u16 tmp;
++	u16 pwr_idx[2];
++
++	if (wlc_phy_txpwr_ison_nphy(pi)) {
++		pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
++		pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
++
++		tmp = (pwr_idx[0] << 8) | pwr_idx[1];
++	} else {
++		tmp = ((pi->nphy_txpwrindex[PHY_CORE_0].index_internal & 0xff)
++			<< 8) |
++			(pi->nphy_txpwrindex[PHY_CORE_1].index_internal & 0xff);
++	}
++
++	return tmp;
++}
++
++void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi)
++{
++	if (PHY_IPA(pi)
++	    && (pi->nphy_force_papd_cal
++		|| (wlc_phy_txpwr_ison_nphy(pi)
++		    &&
++		    (((u32)
++		      abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
++			  pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
++		     || ((u32)
++			 abs(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
++			     pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4)))))
++		wlc_phy_a4(pi, true);
++}
++
++void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type)
++{
++	u16 mask = 0, val = 0, ishw = 0;
++	u8 ctr;
++	uint core;
++	u32 tbl_offset;
++	u32 tbl_len;
++	u16 regval[84];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	switch (ctrl_type) {
++	case PHY_TPC_HW_OFF:
++	case PHY_TPC_HW_ON:
++		pi->nphy_txpwrctrl = ctrl_type;
++		break;
++	default:
++		break;
++	}
++
++	if (ctrl_type == PHY_TPC_HW_OFF) {
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++
++			if (wlc_phy_txpwr_ison_nphy(pi)) {
++				for (core = 0; core < pi->pubpi.phy_corenum;
++				     core++)
++					pi->nphy_txpwr_idx[core] =
++						wlc_phy_txpwr_idx_cur_get_nphy(
++							pi,
++							(u8) core);
++			}
++
++		}
++
++		tbl_len = 84;
++		tbl_offset = 64;
++		for (ctr = 0; ctr < tbl_len; ctr++)
++			regval[ctr] = 0;
++		wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
++					 regval);
++		wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
++					 regval);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3))
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 15) |
++					     (0x1 << 14) | (0x1 << 13))));
++		else
++			and_phy_reg(pi, 0x1e7,
++				    (u16) (~((0x1 << 14) | (0x1 << 13))));
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			or_phy_reg(pi, 0x8f, (0x1 << 8));
++			or_phy_reg(pi, 0xa5, (0x1 << 8));
++		} else {
++			or_phy_reg(pi, 0xa5, (0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       MHF1_IQSWAP_WAR, BRCM_BAND_ALL);
++
++	} else {
++
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
++					 8, pi->adj_pwr_tbl_nphy);
++
++		ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
++		mask = (0x1 << 14) | (0x1 << 13);
++		val = (ishw << 14) | (ishw << 13);
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			mask |= (0x1 << 15);
++			val |= (ishw << 15);
++		}
++
++		mod_phy_reg(pi, 0x1e7, mask, val);
++
++		if (CHSPEC_IS5G(pi->radio_chanspec)) {
++			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
++				mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
++			} else {
++				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
++				if (NREV_GT(pi->pubpi.phy_rev, 1))
++					mod_phy_reg(pi, 0x222,
++						    (0xff << 0), 0x64);
++			}
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			if ((pi->nphy_txpwr_idx[0] != 128)
++			    && (pi->nphy_txpwr_idx[1] != 128))
++				wlc_phy_txpwr_idx_cur_set_nphy(pi,
++							       pi->
++							       nphy_txpwr_idx
++							       [0],
++							       pi->
++							       nphy_txpwr_idx
++							       [1]);
++		}
++
++		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++			and_phy_reg(pi, 0x8f, ~(0x1 << 8));
++			and_phy_reg(pi, 0xa5, ~(0x1 << 8));
++		} else {
++			and_phy_reg(pi, 0xa5, ~(0x1 << 14));
++		}
++
++		if (NREV_IS(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
++		else if (NREV_LT(pi->pubpi.phy_rev, 2))
++			mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
++
++		if (NREV_LT(pi->pubpi.phy_rev, 2) &&
++		    pi->bw == WL_CHANSPEC_BW_40)
++			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
++				       0x0, BRCM_BAND_ALL);
++
++		if (PHY_IPA(pi)) {
++			mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++			mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
++				    0x29b, (0x1 << 2), (0) << 2);
++
++		}
++
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex,
++			 bool restore_cals)
++{
++	u8 core, txpwrctl_tbl;
++	u16 tx_ind0, iq_ind0, lo_ind0;
++	u16 m1m2;
++	u32 txgain;
++	u16 rad_gain, dac_gain;
++	u8 bbmult;
++	u32 iqcomp;
++	u16 iqcomp_a, iqcomp_b;
++	u32 locomp;
++	u16 tmpval;
++	u8 tx_pwr_ctrl_state;
++	s32 rfpwr_offset;
++	u16 regval[2];
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, true);
++
++	tx_ind0 = 192;
++	iq_ind0 = 320;
++	lo_ind0 = 448;
++
++	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
++
++		if ((core_mask & (1 << core)) == 0)
++			continue;
++
++		txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
++
++		if (txpwrindex < 0) {
++			if (pi->nphy_txpwrindex[core].index < 0)
++				continue;
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++				mod_phy_reg(pi, 0x8f,
++					    (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++				mod_phy_reg(pi, 0xa5, (0x1 << 8),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			} else {
++				mod_phy_reg(pi, 0xa5,
++					    (0x1 << 14),
++					    pi->nphy_txpwrindex[core].
++					    AfectrlOverride);
++			}
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab,
++				      pi->nphy_txpwrindex[core].AfeCtrlDacGain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &pi->nphy_txpwrindex[core].
++						 rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				 (pi->nphy_txpwrindex[core].bbmult << 8) :
++				 (pi->nphy_txpwrindex[core].bbmult << 0));
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			if (restore_cals) {
++				wlc_phy_table_write_nphy(
++					pi, 15, 2, (80 + 2 * core), 16,
++					&pi->nphy_txpwrindex[core].iqcomp_a);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (85 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++				wlc_phy_table_write_nphy(
++					pi, 15, 1, (93 + core), 16,
++					&pi->nphy_txpwrindex[core].locomp);
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
++
++			pi->nphy_txpwrindex[core].index_internal =
++				pi->nphy_txpwrindex[core].index_internal_save;
++		} else {
++
++			if (pi->nphy_txpwrindex[core].index < 0) {
++
++				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
++					mod_phy_reg(pi, 0x8f,
++						    (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++					mod_phy_reg(pi, 0xa5, (0x1 << 8),
++						    pi->nphy_txpwrindex[core].
++						    AfectrlOverride);
++				} else {
++					pi->nphy_txpwrindex[core].
++					AfectrlOverride =
++						read_phy_reg(pi, 0xa5);
++				}
++
++				pi->nphy_txpwrindex[core].AfeCtrlDacGain =
++					read_phy_reg(pi, (core == PHY_CORE_0) ?
++							 0xaa : 0xab);
++
++				wlc_phy_table_read_nphy(pi, 7, 1,
++							(0x110 + core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							rad_gain);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
++							&tmpval);
++				tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
++				tmpval &= 0xff;
++				pi->nphy_txpwrindex[core].bbmult = (u8) tmpval;
++
++				wlc_phy_table_read_nphy(pi, 15, 2,
++							(80 + 2 * core), 16,
++							&pi->
++							nphy_txpwrindex[core].
++							iqcomp_a);
++
++				wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
++							16,
++							&pi->
++							nphy_txpwrindex[core].
++							locomp);
++
++				pi->nphy_txpwrindex[core].index_internal_save =
++					pi->nphy_txpwrindex[core].
++					index_internal;
++			}
++
++			tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
++			wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(tx_ind0 + txpwrindex), 32,
++						&txgain);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				rad_gain = (txgain >> 16) &
++					   ((1 << (32 - 16 + 1)) - 1);
++			else
++				rad_gain = (txgain >> 16) &
++					   ((1 << (28 - 16 + 1)) - 1);
++
++			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
++			bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
++
++			if (NREV_GE(pi->pubpi.phy_rev, 3))
++				mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
++						 0xa5), (0x1 << 8), (0x1 << 8));
++			else
++				mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
++
++			write_phy_reg(pi, (core == PHY_CORE_0) ?
++				      0xaa : 0xab, dac_gain);
++
++			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
++						 &rad_gain);
++
++			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
++			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
++			m1m2 |= ((core == PHY_CORE_0) ?
++				(bbmult << 8) : (bbmult << 0));
++
++			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(iq_ind0 + txpwrindex), 32,
++						&iqcomp);
++			iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
++			iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
++
++			if (restore_cals) {
++				regval[0] = (u16) iqcomp_a;
++				regval[1] = (u16) iqcomp_b;
++				wlc_phy_table_write_nphy(pi, 15, 2,
++							 (80 + 2 * core), 16,
++							 regval);
++			}
++
++			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
++						(lo_ind0 + txpwrindex), 32,
++						&locomp);
++			if (restore_cals)
++				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
++							 16, &locomp);
++
++			if (NREV_IS(pi->pubpi.phy_rev, 1))
++				wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
++
++			if (PHY_IPA(pi)) {
++				wlc_phy_table_read_nphy(pi,
++						(core == PHY_CORE_0 ?
++						 NPHY_TBL_ID_CORE1TXPWRCTL :
++						 NPHY_TBL_ID_CORE2TXPWRCTL),
++						1, 576 + txpwrindex, 32,
++						&rfpwr_offset);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1ff << 4),
++					    ((s16) rfpwr_offset) << 4);
++
++				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
++					    0x29b, (0x1 << 2), (1) << 2);
++
++			}
++
++			wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
++		}
++
++		pi->nphy_txpwrindex[core].index = txpwrindex;
++	}
++
++	if (pi->phyhang_avoid)
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++}
++
++void
++wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr,
++				   u8 txp_rate_idx)
++{
++	u8 chan_freq_range;
++
++	chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
++	switch (chan_freq_range) {
++	case WL_CHAN_FREQ_RANGE_2G:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GM:
++		*max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GL:
++		*max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
++		break;
++	case WL_CHAN_FREQ_RANGE_5GH:
++		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
++		break;
++	default:
++		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
++		break;
++	}
++
++	return;
++}
++
++void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable)
++{
++	u16 clip_off[] = { 0xffff, 0xffff };
++
++	if (enable) {
++		if (pi->nphy_deaf_count == 0) {
++			pi->classifier_state =
++				wlc_phy_classifier_nphy(pi, 0, 0);
++			wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
++			wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
++			wlc_phy_clip_det_nphy(pi, 1, clip_off);
++		}
++
++		pi->nphy_deaf_count++;
++
++		wlc_phy_resetcca_nphy(pi);
++
++	} else {
++		pi->nphy_deaf_count--;
++
++		if (pi->nphy_deaf_count == 0) {
++			wlc_phy_classifier_nphy(pi, (0x7 << 0),
++						pi->classifier_state);
++			wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
++		}
++	}
++}
++
++void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode)
++{
++	wlapi_suspend_mac_and_wait(pi->sh->physhim);
++
++	if (mode) {
++		if (pi->nphy_deaf_count == 0)
++			wlc_phy_stay_in_carriersearch_nphy(pi, true);
++	} else if (pi->nphy_deaf_count > 0) {
++		wlc_phy_stay_in_carriersearch_nphy(pi, false);
++	}
++
++	wlapi_enable_mac(pi->sh->physhim);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+new file mode 100644
+index 0000000..faf1ebe
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
+@@ -0,0 +1,308 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include "phy_qmath.h"
++
++/*
++ * Description: This function make 16 bit unsigned multiplication.
++ * To fit the output into 16 bits the 32 bit multiplication result is right
++ * shifted by 16 bits.
++ */
++u16 qm_mulu16(u16 op1, u16 op2)
++{
++	return (u16) (((u32) op1 * (u32) op2) >> 16);
++}
++
++/*
++ * Description: This function make 16 bit multiplication and return the result
++ * in 16 bits. To fit the multiplication result into 16 bits the multiplication
++ * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
++ * is done to remove the extra sign bit formed due to the multiplication.
++ * When both the 16bit inputs are 0x8000 then the output is saturated to
++ * 0x7fffffff.
++ */
++s16 qm_muls16(s16 op1, s16 op2)
++{
++	s32 result;
++	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
++		result = 0x7fffffff;
++	else
++		result = ((s32) (op1) * (s32) (op2));
++
++	return (s16) (result >> 15);
++}
++
++/*
++ * Description: This function add two 32 bit numbers and return the 32bit
++ * result. If the result overflow 32 bits, the output will be saturated to
++ * 32bits.
++ */
++s32 qm_add32(s32 op1, s32 op2)
++{
++	s32 result;
++	result = op1 + op2;
++	if (op1 < 0 && op2 < 0 && result > 0)
++		result = 0x80000000;
++	else if (op1 > 0 && op2 > 0 && result < 0)
++		result = 0x7fffffff;
++
++	return result;
++}
++
++/*
++ * Description: This function add two 16 bit numbers and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_add16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 + (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make 16 bit subtraction and return the 16bit
++ * result. If the result overflow 16 bits, the output will be saturated to
++ * 16bits.
++ */
++s16 qm_sub16(s16 op1, s16 op2)
++{
++	s16 result;
++	s32 temp = (s32) op1 - (s32) op2;
++	if (temp > (s32) 0x7fff)
++		result = (s16) 0x7fff;
++	else if (temp < (s32) 0xffff8000)
++		result = (s16) 0xffff8000;
++	else
++		result = (s16) temp;
++
++	return result;
++}
++
++/*
++ * Description: This function make a 32 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 32 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s32 qm_shl32(s32 op, int shift)
++{
++	int i;
++	s32 result;
++	result = op;
++	if (shift > 31)
++		shift = 31;
++	else if (shift < -31)
++		shift = -31;
++	if (shift >= 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add32(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit saturated left shift when the
++ * specified shift is +ve. This function will make a 16 bit right shift when
++ * the specified shift is -ve. This function return the result after shifting
++ * operation.
++ */
++s16 qm_shl16(s16 op, int shift)
++{
++	int i;
++	s16 result;
++	result = op;
++	if (shift > 15)
++		shift = 15;
++	else if (shift < -15)
++		shift = -15;
++	if (shift > 0) {
++		for (i = 0; i < shift; i++)
++			result = qm_add16(result, result);
++	} else {
++		result = result >> (-shift);
++	}
++
++	return result;
++}
++
++/*
++ * Description: This function make a 16 bit right shift when shift is +ve.
++ * This function make a 16 bit saturated left shift when shift is -ve. This
++ * function return the result of the shift operation.
++ */
++s16 qm_shr16(s16 op, int shift)
++{
++	return qm_shl16(op, -shift);
++}
++
++/*
++ * Description: This function return the number of redundant sign bits in a
++ * 32 bit number. Example: qm_norm32(0x00000080) = 23
++ */
++s16 qm_norm32(s32 op)
++{
++	u16 u16extraSignBits;
++	if (op == 0) {
++		return 31;
++	} else {
++		u16extraSignBits = 0;
++		while ((op >> 31) == (op >> 30)) {
++			u16extraSignBits++;
++			op = op << 1;
++		}
++	}
++	return u16extraSignBits;
++}
++
++/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
++static const s16 log_table[] = {
++	0,
++	1455,
++	2866,
++	4236,
++	5568,
++	6863,
++	8124,
++	9352,
++	10549,
++	11716,
++	12855,
++	13968,
++	15055,
++	16117,
++	17156,
++	18173,
++	19168,
++	20143,
++	21098,
++	22034,
++	22952,
++	23852,
++	24736,
++	25604,
++	26455,
++	27292,
++	28114,
++	28922,
++	29717,
++	30498,
++	31267,
++	32024
++};
++
++#define LOG_TABLE_SIZE 32       /* log_table size */
++#define LOG2_LOG_TABLE_SIZE 5   /* log2(log_table size) */
++#define Q_LOG_TABLE 15          /* qformat of log_table */
++#define LOG10_2         19728   /* log10(2) in q.16 */
++
++/*
++ * Description:
++ * This routine takes the input number N and its q format qN and compute
++ * the log10(N). This routine first normalizes the input no N.	Then N is in
++ * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
++ * Then log2(mag * 2^x) = log2(mag) + x is computed. From that
++ * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
++ * This routine looks the log2 value in the table considering
++ * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
++ * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
++ * for interpolation.
++ * Inputs:
++ * N - number to which log10 has to be found.
++ * qN - q format of N
++ * log10N - address where log10(N) will be written.
++ * qLog10N - address where log10N qformat will be written.
++ * Note/Problem:
++ * For accurate results input should be in normalized or near normalized form.
++ */
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
++{
++	s16 s16norm, s16tableIndex, s16errorApproximation;
++	u16 u16offset;
++	s32 s32log;
++
++	/* normalize the N. */
++	s16norm = qm_norm32(N);
++	N = N << s16norm;
++
++	/* The qformat of N after normalization.
++	 * -30 is added to treat the no as between 1.0 to 2.0
++	 * i.e. after adding the -30 to the qformat the decimal point will be
++	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
++	 * at the right side of 30th bit.
++	 */
++	qN = qN + s16norm - 30;
++
++	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
++	 * MSB */
++	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
++
++	/* remove the MSB. the MSB is always 1 after normalization. */
++	s16tableIndex =
++		s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
++
++	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
++	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
++
++	/* take the offset as the 16 MSBS after table index.
++	 */
++	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
++
++	/* look the log value in the table. */
++	s32log = log_table[s16tableIndex];      /* q.15 format */
++
++	/* interpolate using the offset. q.15 format. */
++	s16errorApproximation = (s16) qm_mulu16(u16offset,
++				(u16) (log_table[s16tableIndex + 1] -
++				       log_table[s16tableIndex]));
++
++	 /* q.15 format */
++	s32log = qm_add16((s16) s32log, s16errorApproximation);
++
++	/* adjust for the qformat of the N as
++	 * log2(mag * 2^x) = log2(mag) + x
++	 */
++	s32log = qm_add32(s32log, ((s32) -qN) << 15);   /* q.15 format */
++
++	/* normalize the result. */
++	s16norm = qm_norm32(s32log);
++
++	/* bring all the important bits into lower 16 bits */
++	/* q.15+s16norm-16 format */
++	s32log = qm_shl32(s32log, s16norm - 16);
++
++	/* compute the log10(N) by multiplying log2(N) with log10(2).
++	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
++	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
++	 */
++	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
++
++	/* write the q format of the result. */
++	*qLog10N = 15 + s16norm - 16 + 1;
++
++	return;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+new file mode 100644
+index 0000000..20e3783
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_QMATH_H_
++#define _BRCM_QMATH_H_
++
++#include <types.h>
++
++u16 qm_mulu16(u16 op1, u16 op2);
++
++s16 qm_muls16(s16 op1, s16 op2);
++
++s32 qm_add32(s32 op1, s32 op2);
++
++s16 qm_add16(s16 op1, s16 op2);
++
++s16 qm_sub16(s16 op1, s16 op2);
++
++s32 qm_shl32(s32 op, int shift);
++
++s16 qm_shl16(s16 op, int shift);
++
++s16 qm_shr16(s16 op, int shift);
++
++s16 qm_norm32(s32 op);
++
++void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
++
++#endif				/* #ifndef _BRCM_QMATH_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+new file mode 100644
+index 0000000..c3a6754
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
+@@ -0,0 +1,1533 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_PHY_RADIO_H_
++#define	_BRCM_PHY_RADIO_H_
++
++#define	RADIO_IDCODE			0x01
++
++#define RADIO_DEFAULT_CORE		0
++
++#define	RXC0_RSSI_RST			0x80
++#define	RXC0_MODE_RSSI			0x40
++#define	RXC0_MODE_OFF			0x20
++#define	RXC0_MODE_CM			0x10
++#define	RXC0_LAN_LOAD			0x08
++#define	RXC0_OFF_ADJ_MASK		0x07
++
++#define	TXC0_MODE_TXLPF			0x04
++#define	TXC0_PA_TSSI_EN			0x02
++#define	TXC0_TSSI_EN			0x01
++
++#define	TXC1_PA_GAIN_MASK		0x60
++#define	TXC1_PA_GAIN_3DB		0x40
++#define	TXC1_PA_GAIN_2DB		0x20
++#define	TXC1_TX_MIX_GAIN		0x10
++#define	TXC1_OFF_I_MASK			0x0c
++#define	TXC1_OFF_Q_MASK			0x03
++
++#define	RADIO_2055_READ_OFF		0x100
++#define	RADIO_2057_READ_OFF		0x200
++
++#define RADIO_2055_GEN_SPARE		0x00
++#define RADIO_2055_SP_PIN_PD		0x02
++#define RADIO_2055_SP_RSSI_CORE1	0x03
++#define RADIO_2055_SP_PD_MISC_CORE1	0x04
++#define RADIO_2055_SP_RSSI_CORE2	0x05
++#define RADIO_2055_SP_PD_MISC_CORE2	0x06
++#define RADIO_2055_SP_RX_GC1_CORE1	0x07
++#define RADIO_2055_SP_RX_GC2_CORE1	0x08
++#define RADIO_2055_SP_RX_GC1_CORE2	0x09
++#define RADIO_2055_SP_RX_GC2_CORE2	0x0a
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
++#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
++#define RADIO_2055_SP_TX_GC1_CORE1	0x0d
++#define RADIO_2055_SP_TX_GC2_CORE1	0x0e
++#define RADIO_2055_SP_TX_GC1_CORE2	0x0f
++#define RADIO_2055_SP_TX_GC2_CORE2	0x10
++#define RADIO_2055_MASTER_CNTRL1	0x11
++#define RADIO_2055_MASTER_CNTRL2	0x12
++#define RADIO_2055_PD_LGEN		0x13
++#define RADIO_2055_PD_PLL_TS		0x14
++#define RADIO_2055_PD_CORE1_LGBUF	0x15
++#define RADIO_2055_PD_CORE1_TX		0x16
++#define RADIO_2055_PD_CORE1_RXTX	0x17
++#define RADIO_2055_PD_CORE1_RSSI_MISC	0x18
++#define RADIO_2055_PD_CORE2_LGBUF	0x19
++#define RADIO_2055_PD_CORE2_TX		0x1a
++#define RADIO_2055_PD_CORE2_RXTX	0x1b
++#define RADIO_2055_PD_CORE2_RSSI_MISC	0x1c
++#define RADIO_2055_PWRDET_LGEN		0x1d
++#define RADIO_2055_PWRDET_LGBUF_CORE1	0x1e
++#define RADIO_2055_PWRDET_RXTX_CORE1	0x1f
++#define RADIO_2055_PWRDET_LGBUF_CORE2	0x20
++#define RADIO_2055_PWRDET_RXTX_CORE2	0x21
++#define RADIO_2055_RRCCAL_CNTRL_SPARE	0x22
++#define RADIO_2055_RRCCAL_N_OPT_SEL	0x23
++#define RADIO_2055_CAL_MISC		0x24
++#define RADIO_2055_CAL_COUNTER_OUT	0x25
++#define RADIO_2055_CAL_COUNTER_OUT2	0x26
++#define RADIO_2055_CAL_CVAR_CNTRL	0x27
++#define RADIO_2055_CAL_RVAR_CNTRL	0x28
++#define RADIO_2055_CAL_LPO_CNTRL	0x29
++#define RADIO_2055_CAL_TS		0x2a
++#define RADIO_2055_CAL_RCCAL_READ_TS	0x2b
++#define RADIO_2055_CAL_RCAL_READ_TS	0x2c
++#define RADIO_2055_PAD_DRIVER		0x2d
++#define RADIO_2055_XO_CNTRL1		0x2e
++#define RADIO_2055_XO_CNTRL2		0x2f
++#define RADIO_2055_XO_REGULATOR		0x30
++#define RADIO_2055_XO_MISC		0x31
++#define RADIO_2055_PLL_LF_C1		0x32
++#define RADIO_2055_PLL_CAL_VTH		0x33
++#define RADIO_2055_PLL_LF_C2		0x34
++#define RADIO_2055_PLL_REF		0x35
++#define RADIO_2055_PLL_LF_R1		0x36
++#define RADIO_2055_PLL_PFD_CP		0x37
++#define RADIO_2055_PLL_IDAC_CPOPAMP	0x38
++#define RADIO_2055_PLL_CP_REGULATOR	0x39
++#define RADIO_2055_PLL_RCAL		0x3a
++#define RADIO_2055_RF_PLL_MOD0		0x3b
++#define RADIO_2055_RF_PLL_MOD1		0x3c
++#define RADIO_2055_RF_MMD_IDAC1		0x3d
++#define RADIO_2055_RF_MMD_IDAC0		0x3e
++#define RADIO_2055_RF_MMD_SPARE		0x3f
++#define RADIO_2055_VCO_CAL1		0x40
++#define RADIO_2055_VCO_CAL2		0x41
++#define RADIO_2055_VCO_CAL3		0x42
++#define RADIO_2055_VCO_CAL4		0x43
++#define RADIO_2055_VCO_CAL5		0x44
++#define RADIO_2055_VCO_CAL6		0x45
++#define RADIO_2055_VCO_CAL7		0x46
++#define RADIO_2055_VCO_CAL8		0x47
++#define RADIO_2055_VCO_CAL9		0x48
++#define RADIO_2055_VCO_CAL10		0x49
++#define RADIO_2055_VCO_CAL11		0x4a
++#define RADIO_2055_VCO_CAL12		0x4b
++#define RADIO_2055_VCO_CAL13		0x4c
++#define RADIO_2055_VCO_CAL14		0x4d
++#define RADIO_2055_VCO_CAL15		0x4e
++#define RADIO_2055_VCO_CAL16		0x4f
++#define RADIO_2055_VCO_KVCO		0x50
++#define RADIO_2055_VCO_CAP_TAIL		0x51
++#define RADIO_2055_VCO_IDAC_VCO		0x52
++#define RADIO_2055_VCO_REGULATOR	0x53
++#define RADIO_2055_PLL_RF_VTH		0x54
++#define RADIO_2055_LGBUF_CEN_BUF	0x55
++#define RADIO_2055_LGEN_TUNE1		0x56
++#define RADIO_2055_LGEN_TUNE2		0x57
++#define RADIO_2055_LGEN_IDAC1		0x58
++#define RADIO_2055_LGEN_IDAC2		0x59
++#define RADIO_2055_LGEN_BIAS_CNT	0x5a
++#define RADIO_2055_LGEN_BIAS_IDAC	0x5b
++#define RADIO_2055_LGEN_RCAL		0x5c
++#define RADIO_2055_LGEN_DIV		0x5d
++#define RADIO_2055_LGEN_SPARE2		0x5e
++#define RADIO_2055_CORE1_LGBUF_A_TUNE	0x5f
++#define RADIO_2055_CORE1_LGBUF_G_TUNE	0x60
++#define RADIO_2055_CORE1_LGBUF_DIV	0x61
++#define RADIO_2055_CORE1_LGBUF_A_IDAC	0x62
++#define RADIO_2055_CORE1_LGBUF_G_IDAC	0x63
++#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
++#define RADIO_2055_CORE1_LGBUF_SPARE	0x65
++#define RADIO_2055_CORE1_RXRF_SPC1	0x66
++#define RADIO_2055_CORE1_RXRF_REG1	0x67
++#define RADIO_2055_CORE1_RXRF_REG2	0x68
++#define RADIO_2055_CORE1_RXRF_RCAL	0x69
++#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
++#define RADIO_2055_CORE1_RXBB_LPF	0x6b
++#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
++#define RADIO_2055_CORE1_RXBB_VGA1_IDAC	0x6d
++#define RADIO_2055_CORE1_RXBB_VGA2_IDAC	0x6e
++#define RADIO_2055_CORE1_RXBB_VGA3_IDAC	0x6f
++#define RADIO_2055_CORE1_RXBB_BUFO_CTRL	0x70
++#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
++#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
++#define RADIO_2055_CORE1_RXBB_REGULATOR	0x77
++#define RADIO_2055_CORE1_RXBB_SPARE1	0x78
++#define RADIO_2055_CORE1_RXTXBB_RCAL	0x79
++#define RADIO_2055_CORE1_TXRF_SGM_PGA	0x7a
++#define RADIO_2055_CORE1_TXRF_SGM_PAD	0x7b
++#define RADIO_2055_CORE1_TXRF_CNTR_PGA1	0x7c
++#define RADIO_2055_CORE1_TXRF_CNTR_PAD1	0x7d
++#define RADIO_2055_CORE1_TX_RFPGA_IDAC	0x7e
++#define RADIO_2055_CORE1_TX_PGA_PAD_TN	0x7f
++#define RADIO_2055_CORE1_TX_PAD_IDAC1	0x80
++#define RADIO_2055_CORE1_TX_PAD_IDAC2	0x81
++#define RADIO_2055_CORE1_TX_MX_BGTRIM	0x82
++#define RADIO_2055_CORE1_TXRF_RCAL	0x83
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI1	0x84
++#define RADIO_2055_CORE1_TXRF_PAD_TSSI2	0x85
++#define RADIO_2055_CORE1_TX_RF_SPARE	0x86
++#define RADIO_2055_CORE1_TXRF_IQCAL1	0x87
++#define RADIO_2055_CORE1_TXRF_IQCAL2	0x88
++#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
++#define RADIO_2055_CORE1_TXBB_LPF1	0x8a
++#define RADIO_2055_CORE1_TX_VOS_CNCL	0x8b
++#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
++#define RADIO_2055_CORE1_TX_BB_MXGM	0x8d
++#define RADIO_2055_CORE2_LGBUF_A_TUNE	0x8e
++#define RADIO_2055_CORE2_LGBUF_G_TUNE	0x8f
++#define RADIO_2055_CORE2_LGBUF_DIV	0x90
++#define RADIO_2055_CORE2_LGBUF_A_IDAC	0x91
++#define RADIO_2055_CORE2_LGBUF_G_IDAC	0x92
++#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
++#define RADIO_2055_CORE2_LGBUF_SPARE	0x94
++#define RADIO_2055_CORE2_RXRF_SPC1	0x95
++#define RADIO_2055_CORE2_RXRF_REG1	0x96
++#define RADIO_2055_CORE2_RXRF_REG2	0x97
++#define RADIO_2055_CORE2_RXRF_RCAL	0x98
++#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
++#define RADIO_2055_CORE2_RXBB_LPF	0x9a
++#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
++#define RADIO_2055_CORE2_RXBB_VGA1_IDAC	0x9c
++#define RADIO_2055_CORE2_RXBB_VGA2_IDAC	0x9d
++#define RADIO_2055_CORE2_RXBB_VGA3_IDAC	0x9e
++#define RADIO_2055_CORE2_RXBB_BUFO_CTRL	0x9f
++#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
++#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
++#define RADIO_2055_CORE2_RXBB_REGULATOR	0xa6
++#define RADIO_2055_CORE2_RXBB_SPARE1	0xa7
++#define RADIO_2055_CORE2_RXTXBB_RCAL	0xa8
++#define RADIO_2055_CORE2_TXRF_SGM_PGA	0xa9
++#define RADIO_2055_CORE2_TXRF_SGM_PAD	0xaa
++#define RADIO_2055_CORE2_TXRF_CNTR_PGA1	0xab
++#define RADIO_2055_CORE2_TXRF_CNTR_PAD1	0xac
++#define RADIO_2055_CORE2_TX_RFPGA_IDAC	0xad
++#define RADIO_2055_CORE2_TX_PGA_PAD_TN	0xae
++#define RADIO_2055_CORE2_TX_PAD_IDAC1	0xaf
++#define RADIO_2055_CORE2_TX_PAD_IDAC2	0xb0
++#define RADIO_2055_CORE2_TX_MX_BGTRIM	0xb1
++#define RADIO_2055_CORE2_TXRF_RCAL	0xb2
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI1	0xb3
++#define RADIO_2055_CORE2_TXRF_PAD_TSSI2	0xb4
++#define RADIO_2055_CORE2_TX_RF_SPARE	0xb5
++#define RADIO_2055_CORE2_TXRF_IQCAL1	0xb6
++#define RADIO_2055_CORE2_TXRF_IQCAL2	0xb7
++#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
++#define RADIO_2055_CORE2_TXBB_LPF1	0xb9
++#define RADIO_2055_CORE2_TX_VOS_CNCL	0xba
++#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
++#define RADIO_2055_CORE2_TX_BB_MXGM	0xbc
++#define RADIO_2055_PRG_GC_HPVGA23_21	0xbd
++#define RADIO_2055_PRG_GC_HPVGA23_22	0xbe
++#define RADIO_2055_PRG_GC_HPVGA23_23	0xbf
++#define RADIO_2055_PRG_GC_HPVGA23_24	0xc0
++#define RADIO_2055_PRG_GC_HPVGA23_25	0xc1
++#define RADIO_2055_PRG_GC_HPVGA23_26	0xc2
++#define RADIO_2055_PRG_GC_HPVGA23_27	0xc3
++#define RADIO_2055_PRG_GC_HPVGA23_28	0xc4
++#define RADIO_2055_PRG_GC_HPVGA23_29	0xc5
++#define RADIO_2055_PRG_GC_HPVGA23_30	0xc6
++#define RADIO_2055_CORE1_LNA_GAINBST	0xcd
++#define RADIO_2055_CORE1_B0_NBRSSI_VCM	0xd2
++#define RADIO_2055_CORE1_GEN_SPARE2		0xd6
++#define RADIO_2055_CORE2_LNA_GAINBST	0xd9
++#define RADIO_2055_CORE2_B0_NBRSSI_VCM	0xde
++#define RADIO_2055_CORE2_GEN_SPARE2		0xe2
++
++#define RADIO_2055_GAINBST_GAIN_DB	6
++#define RADIO_2055_GAINBST_CODE		0x6
++
++#define RADIO_2055_JTAGCTRL_MASK	0x04
++#define RADIO_2055_JTAGSYNC_MASK	0x08
++#define RADIO_2055_RRCAL_START		0x40
++#define RADIO_2055_RRCAL_RST_N		0x01
++#define RADIO_2055_CAL_LPO_ENABLE	0x80
++#define RADIO_2055_RCAL_DONE		0x80
++#define RADIO_2055_NBRSSI_VCM_I_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_I_SHIFT	0x00
++#define RADIO_2055_NBRSSI_VCM_Q_MASK	0x03
++#define RADIO_2055_NBRSSI_VCM_Q_SHIFT	0x00
++#define RADIO_2055_WBRSSI_VCM_IQ_MASK	0x0c
++#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT	0x02
++#define RADIO_2055_NBRSSI_PD		0x01
++#define RADIO_2055_WBRSSI_G1_PD		0x04
++#define RADIO_2055_WBRSSI_G2_PD		0x02
++#define RADIO_2055_NBRSSI_SEL		0x01
++#define RADIO_2055_WBRSSI_G1_SEL	0x04
++#define RADIO_2055_WBRSSI_G2_SEL	0x02
++#define RADIO_2055_COUPLE_RX_MASK	0x01
++#define RADIO_2055_COUPLE_TX_MASK	0x02
++#define RADIO_2055_GAINBST_DISABLE	0x02
++#define RADIO_2055_GAINBST_VAL_MASK	0x07
++#define RADIO_2055_RXMX_GC_MASK		0x0c
++
++#define RADIO_MIMO_CORESEL_OFF		0x0
++#define RADIO_MIMO_CORESEL_CORE1	0x1
++#define RADIO_MIMO_CORESEL_CORE2	0x2
++#define RADIO_MIMO_CORESEL_CORE3	0x3
++#define RADIO_MIMO_CORESEL_CORE4	0x4
++#define RADIO_MIMO_CORESEL_ALLRX	0x5
++#define RADIO_MIMO_CORESEL_ALLTX	0x6
++#define RADIO_MIMO_CORESEL_ALLRXTX	0x7
++
++#define	RADIO_2064_READ_OFF		0x200
++
++#define RADIO_2064_REG000               0x0
++#define RADIO_2064_REG001               0x1
++#define RADIO_2064_REG002               0x2
++#define RADIO_2064_REG003               0x3
++#define RADIO_2064_REG004               0x4
++#define RADIO_2064_REG005               0x5
++#define RADIO_2064_REG006               0x6
++#define RADIO_2064_REG007               0x7
++#define RADIO_2064_REG008               0x8
++#define RADIO_2064_REG009               0x9
++#define RADIO_2064_REG00A               0xa
++#define RADIO_2064_REG00B               0xb
++#define RADIO_2064_REG00C               0xc
++#define RADIO_2064_REG00D               0xd
++#define RADIO_2064_REG00E               0xe
++#define RADIO_2064_REG00F               0xf
++#define RADIO_2064_REG010               0x10
++#define RADIO_2064_REG011               0x11
++#define RADIO_2064_REG012               0x12
++#define RADIO_2064_REG013               0x13
++#define RADIO_2064_REG014               0x14
++#define RADIO_2064_REG015               0x15
++#define RADIO_2064_REG016               0x16
++#define RADIO_2064_REG017               0x17
++#define RADIO_2064_REG018               0x18
++#define RADIO_2064_REG019               0x19
++#define RADIO_2064_REG01A               0x1a
++#define RADIO_2064_REG01B               0x1b
++#define RADIO_2064_REG01C               0x1c
++#define RADIO_2064_REG01D               0x1d
++#define RADIO_2064_REG01E               0x1e
++#define RADIO_2064_REG01F               0x1f
++#define RADIO_2064_REG020               0x20
++#define RADIO_2064_REG021               0x21
++#define RADIO_2064_REG022               0x22
++#define RADIO_2064_REG023               0x23
++#define RADIO_2064_REG024               0x24
++#define RADIO_2064_REG025               0x25
++#define RADIO_2064_REG026               0x26
++#define RADIO_2064_REG027               0x27
++#define RADIO_2064_REG028               0x28
++#define RADIO_2064_REG029               0x29
++#define RADIO_2064_REG02A               0x2a
++#define RADIO_2064_REG02B               0x2b
++#define RADIO_2064_REG02C               0x2c
++#define RADIO_2064_REG02D               0x2d
++#define RADIO_2064_REG02E               0x2e
++#define RADIO_2064_REG02F               0x2f
++#define RADIO_2064_REG030               0x30
++#define RADIO_2064_REG031               0x31
++#define RADIO_2064_REG032               0x32
++#define RADIO_2064_REG033               0x33
++#define RADIO_2064_REG034               0x34
++#define RADIO_2064_REG035               0x35
++#define RADIO_2064_REG036               0x36
++#define RADIO_2064_REG037               0x37
++#define RADIO_2064_REG038               0x38
++#define RADIO_2064_REG039               0x39
++#define RADIO_2064_REG03A               0x3a
++#define RADIO_2064_REG03B               0x3b
++#define RADIO_2064_REG03C               0x3c
++#define RADIO_2064_REG03D               0x3d
++#define RADIO_2064_REG03E               0x3e
++#define RADIO_2064_REG03F               0x3f
++#define RADIO_2064_REG040               0x40
++#define RADIO_2064_REG041               0x41
++#define RADIO_2064_REG042               0x42
++#define RADIO_2064_REG043               0x43
++#define RADIO_2064_REG044               0x44
++#define RADIO_2064_REG045               0x45
++#define RADIO_2064_REG046               0x46
++#define RADIO_2064_REG047               0x47
++#define RADIO_2064_REG048               0x48
++#define RADIO_2064_REG049               0x49
++#define RADIO_2064_REG04A               0x4a
++#define RADIO_2064_REG04B               0x4b
++#define RADIO_2064_REG04C               0x4c
++#define RADIO_2064_REG04D               0x4d
++#define RADIO_2064_REG04E               0x4e
++#define RADIO_2064_REG04F               0x4f
++#define RADIO_2064_REG050               0x50
++#define RADIO_2064_REG051               0x51
++#define RADIO_2064_REG052               0x52
++#define RADIO_2064_REG053               0x53
++#define RADIO_2064_REG054               0x54
++#define RADIO_2064_REG055               0x55
++#define RADIO_2064_REG056               0x56
++#define RADIO_2064_REG057               0x57
++#define RADIO_2064_REG058               0x58
++#define RADIO_2064_REG059               0x59
++#define RADIO_2064_REG05A               0x5a
++#define RADIO_2064_REG05B               0x5b
++#define RADIO_2064_REG05C               0x5c
++#define RADIO_2064_REG05D               0x5d
++#define RADIO_2064_REG05E               0x5e
++#define RADIO_2064_REG05F               0x5f
++#define RADIO_2064_REG060               0x60
++#define RADIO_2064_REG061               0x61
++#define RADIO_2064_REG062               0x62
++#define RADIO_2064_REG063               0x63
++#define RADIO_2064_REG064               0x64
++#define RADIO_2064_REG065               0x65
++#define RADIO_2064_REG066               0x66
++#define RADIO_2064_REG067               0x67
++#define RADIO_2064_REG068               0x68
++#define RADIO_2064_REG069               0x69
++#define RADIO_2064_REG06A               0x6a
++#define RADIO_2064_REG06B               0x6b
++#define RADIO_2064_REG06C               0x6c
++#define RADIO_2064_REG06D               0x6d
++#define RADIO_2064_REG06E               0x6e
++#define RADIO_2064_REG06F               0x6f
++#define RADIO_2064_REG070               0x70
++#define RADIO_2064_REG071               0x71
++#define RADIO_2064_REG072               0x72
++#define RADIO_2064_REG073               0x73
++#define RADIO_2064_REG074               0x74
++#define RADIO_2064_REG075               0x75
++#define RADIO_2064_REG076               0x76
++#define RADIO_2064_REG077               0x77
++#define RADIO_2064_REG078               0x78
++#define RADIO_2064_REG079               0x79
++#define RADIO_2064_REG07A               0x7a
++#define RADIO_2064_REG07B               0x7b
++#define RADIO_2064_REG07C               0x7c
++#define RADIO_2064_REG07D               0x7d
++#define RADIO_2064_REG07E               0x7e
++#define RADIO_2064_REG07F               0x7f
++#define RADIO_2064_REG080               0x80
++#define RADIO_2064_REG081               0x81
++#define RADIO_2064_REG082               0x82
++#define RADIO_2064_REG083               0x83
++#define RADIO_2064_REG084               0x84
++#define RADIO_2064_REG085               0x85
++#define RADIO_2064_REG086               0x86
++#define RADIO_2064_REG087               0x87
++#define RADIO_2064_REG088               0x88
++#define RADIO_2064_REG089               0x89
++#define RADIO_2064_REG08A               0x8a
++#define RADIO_2064_REG08B               0x8b
++#define RADIO_2064_REG08C               0x8c
++#define RADIO_2064_REG08D               0x8d
++#define RADIO_2064_REG08E               0x8e
++#define RADIO_2064_REG08F               0x8f
++#define RADIO_2064_REG090               0x90
++#define RADIO_2064_REG091               0x91
++#define RADIO_2064_REG092               0x92
++#define RADIO_2064_REG093               0x93
++#define RADIO_2064_REG094               0x94
++#define RADIO_2064_REG095               0x95
++#define RADIO_2064_REG096               0x96
++#define RADIO_2064_REG097               0x97
++#define RADIO_2064_REG098               0x98
++#define RADIO_2064_REG099               0x99
++#define RADIO_2064_REG09A               0x9a
++#define RADIO_2064_REG09B               0x9b
++#define RADIO_2064_REG09C               0x9c
++#define RADIO_2064_REG09D               0x9d
++#define RADIO_2064_REG09E               0x9e
++#define RADIO_2064_REG09F               0x9f
++#define RADIO_2064_REG0A0               0xa0
++#define RADIO_2064_REG0A1               0xa1
++#define RADIO_2064_REG0A2               0xa2
++#define RADIO_2064_REG0A3               0xa3
++#define RADIO_2064_REG0A4               0xa4
++#define RADIO_2064_REG0A5               0xa5
++#define RADIO_2064_REG0A6               0xa6
++#define RADIO_2064_REG0A7               0xa7
++#define RADIO_2064_REG0A8               0xa8
++#define RADIO_2064_REG0A9               0xa9
++#define RADIO_2064_REG0AA               0xaa
++#define RADIO_2064_REG0AB               0xab
++#define RADIO_2064_REG0AC               0xac
++#define RADIO_2064_REG0AD               0xad
++#define RADIO_2064_REG0AE               0xae
++#define RADIO_2064_REG0AF               0xaf
++#define RADIO_2064_REG0B0               0xb0
++#define RADIO_2064_REG0B1               0xb1
++#define RADIO_2064_REG0B2               0xb2
++#define RADIO_2064_REG0B3               0xb3
++#define RADIO_2064_REG0B4               0xb4
++#define RADIO_2064_REG0B5               0xb5
++#define RADIO_2064_REG0B6               0xb6
++#define RADIO_2064_REG0B7               0xb7
++#define RADIO_2064_REG0B8               0xb8
++#define RADIO_2064_REG0B9               0xb9
++#define RADIO_2064_REG0BA               0xba
++#define RADIO_2064_REG0BB               0xbb
++#define RADIO_2064_REG0BC               0xbc
++#define RADIO_2064_REG0BD               0xbd
++#define RADIO_2064_REG0BE               0xbe
++#define RADIO_2064_REG0BF               0xbf
++#define RADIO_2064_REG0C0               0xc0
++#define RADIO_2064_REG0C1               0xc1
++#define RADIO_2064_REG0C2               0xc2
++#define RADIO_2064_REG0C3               0xc3
++#define RADIO_2064_REG0C4               0xc4
++#define RADIO_2064_REG0C5               0xc5
++#define RADIO_2064_REG0C6               0xc6
++#define RADIO_2064_REG0C7               0xc7
++#define RADIO_2064_REG0C8               0xc8
++#define RADIO_2064_REG0C9               0xc9
++#define RADIO_2064_REG0CA               0xca
++#define RADIO_2064_REG0CB               0xcb
++#define RADIO_2064_REG0CC               0xcc
++#define RADIO_2064_REG0CD               0xcd
++#define RADIO_2064_REG0CE               0xce
++#define RADIO_2064_REG0CF               0xcf
++#define RADIO_2064_REG0D0               0xd0
++#define RADIO_2064_REG0D1               0xd1
++#define RADIO_2064_REG0D2               0xd2
++#define RADIO_2064_REG0D3               0xd3
++#define RADIO_2064_REG0D4               0xd4
++#define RADIO_2064_REG0D5               0xd5
++#define RADIO_2064_REG0D6               0xd6
++#define RADIO_2064_REG0D7               0xd7
++#define RADIO_2064_REG0D8               0xd8
++#define RADIO_2064_REG0D9               0xd9
++#define RADIO_2064_REG0DA               0xda
++#define RADIO_2064_REG0DB               0xdb
++#define RADIO_2064_REG0DC               0xdc
++#define RADIO_2064_REG0DD               0xdd
++#define RADIO_2064_REG0DE               0xde
++#define RADIO_2064_REG0DF               0xdf
++#define RADIO_2064_REG0E0               0xe0
++#define RADIO_2064_REG0E1               0xe1
++#define RADIO_2064_REG0E2               0xe2
++#define RADIO_2064_REG0E3               0xe3
++#define RADIO_2064_REG0E4               0xe4
++#define RADIO_2064_REG0E5               0xe5
++#define RADIO_2064_REG0E6               0xe6
++#define RADIO_2064_REG0E7               0xe7
++#define RADIO_2064_REG0E8               0xe8
++#define RADIO_2064_REG0E9               0xe9
++#define RADIO_2064_REG0EA               0xea
++#define RADIO_2064_REG0EB               0xeb
++#define RADIO_2064_REG0EC               0xec
++#define RADIO_2064_REG0ED               0xed
++#define RADIO_2064_REG0EE               0xee
++#define RADIO_2064_REG0EF               0xef
++#define RADIO_2064_REG0F0               0xf0
++#define RADIO_2064_REG0F1               0xf1
++#define RADIO_2064_REG0F2               0xf2
++#define RADIO_2064_REG0F3               0xf3
++#define RADIO_2064_REG0F4               0xf4
++#define RADIO_2064_REG0F5               0xf5
++#define RADIO_2064_REG0F6               0xf6
++#define RADIO_2064_REG0F7               0xf7
++#define RADIO_2064_REG0F8               0xf8
++#define RADIO_2064_REG0F9               0xf9
++#define RADIO_2064_REG0FA               0xfa
++#define RADIO_2064_REG0FB               0xfb
++#define RADIO_2064_REG0FC               0xfc
++#define RADIO_2064_REG0FD               0xfd
++#define RADIO_2064_REG0FE               0xfe
++#define RADIO_2064_REG0FF               0xff
++#define RADIO_2064_REG100               0x100
++#define RADIO_2064_REG101               0x101
++#define RADIO_2064_REG102               0x102
++#define RADIO_2064_REG103               0x103
++#define RADIO_2064_REG104               0x104
++#define RADIO_2064_REG105               0x105
++#define RADIO_2064_REG106               0x106
++#define RADIO_2064_REG107               0x107
++#define RADIO_2064_REG108               0x108
++#define RADIO_2064_REG109               0x109
++#define RADIO_2064_REG10A               0x10a
++#define RADIO_2064_REG10B               0x10b
++#define RADIO_2064_REG10C               0x10c
++#define RADIO_2064_REG10D               0x10d
++#define RADIO_2064_REG10E               0x10e
++#define RADIO_2064_REG10F               0x10f
++#define RADIO_2064_REG110               0x110
++#define RADIO_2064_REG111               0x111
++#define RADIO_2064_REG112               0x112
++#define RADIO_2064_REG113               0x113
++#define RADIO_2064_REG114               0x114
++#define RADIO_2064_REG115               0x115
++#define RADIO_2064_REG116               0x116
++#define RADIO_2064_REG117               0x117
++#define RADIO_2064_REG118               0x118
++#define RADIO_2064_REG119               0x119
++#define RADIO_2064_REG11A               0x11a
++#define RADIO_2064_REG11B               0x11b
++#define RADIO_2064_REG11C               0x11c
++#define RADIO_2064_REG11D               0x11d
++#define RADIO_2064_REG11E               0x11e
++#define RADIO_2064_REG11F               0x11f
++#define RADIO_2064_REG120               0x120
++#define RADIO_2064_REG121               0x121
++#define RADIO_2064_REG122               0x122
++#define RADIO_2064_REG123               0x123
++#define RADIO_2064_REG124               0x124
++#define RADIO_2064_REG125               0x125
++#define RADIO_2064_REG126               0x126
++#define RADIO_2064_REG127               0x127
++#define RADIO_2064_REG128               0x128
++#define RADIO_2064_REG129               0x129
++#define RADIO_2064_REG12A               0x12a
++#define RADIO_2064_REG12B               0x12b
++#define RADIO_2064_REG12C               0x12c
++#define RADIO_2064_REG12D               0x12d
++#define RADIO_2064_REG12E               0x12e
++#define RADIO_2064_REG12F               0x12f
++#define RADIO_2064_REG130               0x130
++
++#define RADIO_2056_SYN                           (0x0 << 12)
++#define RADIO_2056_TX0                           (0x2 << 12)
++#define RADIO_2056_TX1                           (0x3 << 12)
++#define RADIO_2056_RX0                           (0x6 << 12)
++#define RADIO_2056_RX1                           (0x7 << 12)
++#define RADIO_2056_ALLTX                         (0xe << 12)
++#define RADIO_2056_ALLRX                         (0xf << 12)
++
++#define RADIO_2056_SYN_RESERVED_ADDR0            0x0
++#define RADIO_2056_SYN_IDCODE                    0x1
++#define RADIO_2056_SYN_RESERVED_ADDR2            0x2
++#define RADIO_2056_SYN_RESERVED_ADDR3            0x3
++#define RADIO_2056_SYN_RESERVED_ADDR4            0x4
++#define RADIO_2056_SYN_RESERVED_ADDR5            0x5
++#define RADIO_2056_SYN_RESERVED_ADDR6            0x6
++#define RADIO_2056_SYN_RESERVED_ADDR7            0x7
++#define RADIO_2056_SYN_COM_CTRL                  0x8
++#define RADIO_2056_SYN_COM_PU                    0x9
++#define RADIO_2056_SYN_COM_OVR                   0xa
++#define RADIO_2056_SYN_COM_RESET                 0xb
++#define RADIO_2056_SYN_COM_RCAL                  0xc
++#define RADIO_2056_SYN_COM_RC_RXLPF              0xd
++#define RADIO_2056_SYN_COM_RC_TXLPF              0xe
++#define RADIO_2056_SYN_COM_RC_RXHPF              0xf
++#define RADIO_2056_SYN_RESERVED_ADDR16           0x10
++#define RADIO_2056_SYN_RESERVED_ADDR17           0x11
++#define RADIO_2056_SYN_RESERVED_ADDR18           0x12
++#define RADIO_2056_SYN_RESERVED_ADDR19           0x13
++#define RADIO_2056_SYN_RESERVED_ADDR20           0x14
++#define RADIO_2056_SYN_RESERVED_ADDR21           0x15
++#define RADIO_2056_SYN_RESERVED_ADDR22           0x16
++#define RADIO_2056_SYN_RESERVED_ADDR23           0x17
++#define RADIO_2056_SYN_RESERVED_ADDR24           0x18
++#define RADIO_2056_SYN_RESERVED_ADDR25           0x19
++#define RADIO_2056_SYN_RESERVED_ADDR26           0x1a
++#define RADIO_2056_SYN_RESERVED_ADDR27           0x1b
++#define RADIO_2056_SYN_RESERVED_ADDR28           0x1c
++#define RADIO_2056_SYN_RESERVED_ADDR29           0x1d
++#define RADIO_2056_SYN_RESERVED_ADDR30           0x1e
++#define RADIO_2056_SYN_RESERVED_ADDR31           0x1f
++#define RADIO_2056_SYN_GPIO_MASTER1              0x20
++#define RADIO_2056_SYN_GPIO_MASTER2              0x21
++#define RADIO_2056_SYN_TOPBIAS_MASTER            0x22
++#define RADIO_2056_SYN_TOPBIAS_RCAL              0x23
++#define RADIO_2056_SYN_AFEREG                    0x24
++#define RADIO_2056_SYN_TEMPPROCSENSE             0x25
++#define RADIO_2056_SYN_TEMPPROCSENSEIDAC         0x26
++#define RADIO_2056_SYN_TEMPPROCSENSERCAL         0x27
++#define RADIO_2056_SYN_LPO                       0x28
++#define RADIO_2056_SYN_VDDCAL_MASTER             0x29
++#define RADIO_2056_SYN_VDDCAL_IDAC               0x2a
++#define RADIO_2056_SYN_VDDCAL_STATUS             0x2b
++#define RADIO_2056_SYN_RCAL_MASTER               0x2c
++#define RADIO_2056_SYN_RCAL_CODE_OUT             0x2d
++#define RADIO_2056_SYN_RCCAL_CTRL0               0x2e
++#define RADIO_2056_SYN_RCCAL_CTRL1               0x2f
++#define RADIO_2056_SYN_RCCAL_CTRL2               0x30
++#define RADIO_2056_SYN_RCCAL_CTRL3               0x31
++#define RADIO_2056_SYN_RCCAL_CTRL4               0x32
++#define RADIO_2056_SYN_RCCAL_CTRL5               0x33
++#define RADIO_2056_SYN_RCCAL_CTRL6               0x34
++#define RADIO_2056_SYN_RCCAL_CTRL7               0x35
++#define RADIO_2056_SYN_RCCAL_CTRL8               0x36
++#define RADIO_2056_SYN_RCCAL_CTRL9               0x37
++#define RADIO_2056_SYN_RCCAL_CTRL10              0x38
++#define RADIO_2056_SYN_RCCAL_CTRL11              0x39
++#define RADIO_2056_SYN_ZCAL_SPARE1               0x3a
++#define RADIO_2056_SYN_ZCAL_SPARE2               0x3b
++#define RADIO_2056_SYN_PLL_MAST1                 0x3c
++#define RADIO_2056_SYN_PLL_MAST2                 0x3d
++#define RADIO_2056_SYN_PLL_MAST3                 0x3e
++#define RADIO_2056_SYN_PLL_BIAS_RESET            0x3f
++#define RADIO_2056_SYN_PLL_XTAL0                 0x40
++#define RADIO_2056_SYN_PLL_XTAL1                 0x41
++#define RADIO_2056_SYN_PLL_XTAL3                 0x42
++#define RADIO_2056_SYN_PLL_XTAL4                 0x43
++#define RADIO_2056_SYN_PLL_XTAL5                 0x44
++#define RADIO_2056_SYN_PLL_XTAL6                 0x45
++#define RADIO_2056_SYN_PLL_REFDIV                0x46
++#define RADIO_2056_SYN_PLL_PFD                   0x47
++#define RADIO_2056_SYN_PLL_CP1                   0x48
++#define RADIO_2056_SYN_PLL_CP2                   0x49
++#define RADIO_2056_SYN_PLL_CP3                   0x4a
++#define RADIO_2056_SYN_PLL_LOOPFILTER1           0x4b
++#define RADIO_2056_SYN_PLL_LOOPFILTER2           0x4c
++#define RADIO_2056_SYN_PLL_LOOPFILTER3           0x4d
++#define RADIO_2056_SYN_PLL_LOOPFILTER4           0x4e
++#define RADIO_2056_SYN_PLL_LOOPFILTER5           0x4f
++#define RADIO_2056_SYN_PLL_MMD1                  0x50
++#define RADIO_2056_SYN_PLL_MMD2                  0x51
++#define RADIO_2056_SYN_PLL_VCO1                  0x52
++#define RADIO_2056_SYN_PLL_VCO2                  0x53
++#define RADIO_2056_SYN_PLL_MONITOR1              0x54
++#define RADIO_2056_SYN_PLL_MONITOR2              0x55
++#define RADIO_2056_SYN_PLL_VCOCAL1               0x56
++#define RADIO_2056_SYN_PLL_VCOCAL2               0x57
++#define RADIO_2056_SYN_PLL_VCOCAL4               0x58
++#define RADIO_2056_SYN_PLL_VCOCAL5               0x59
++#define RADIO_2056_SYN_PLL_VCOCAL6               0x5a
++#define RADIO_2056_SYN_PLL_VCOCAL7               0x5b
++#define RADIO_2056_SYN_PLL_VCOCAL8               0x5c
++#define RADIO_2056_SYN_PLL_VCOCAL9               0x5d
++#define RADIO_2056_SYN_PLL_VCOCAL10              0x5e
++#define RADIO_2056_SYN_PLL_VCOCAL11              0x5f
++#define RADIO_2056_SYN_PLL_VCOCAL12              0x60
++#define RADIO_2056_SYN_PLL_VCOCAL13              0x61
++#define RADIO_2056_SYN_PLL_VREG                  0x62
++#define RADIO_2056_SYN_PLL_STATUS1               0x63
++#define RADIO_2056_SYN_PLL_STATUS2               0x64
++#define RADIO_2056_SYN_PLL_STATUS3               0x65
++#define RADIO_2056_SYN_LOGEN_PU0                 0x66
++#define RADIO_2056_SYN_LOGEN_PU1                 0x67
++#define RADIO_2056_SYN_LOGEN_PU2                 0x68
++#define RADIO_2056_SYN_LOGEN_PU3                 0x69
++#define RADIO_2056_SYN_LOGEN_PU5                 0x6a
++#define RADIO_2056_SYN_LOGEN_PU6                 0x6b
++#define RADIO_2056_SYN_LOGEN_PU7                 0x6c
++#define RADIO_2056_SYN_LOGEN_PU8                 0x6d
++#define RADIO_2056_SYN_LOGEN_BIAS_RESET          0x6e
++#define RADIO_2056_SYN_LOGEN_RCCR1               0x6f
++#define RADIO_2056_SYN_LOGEN_VCOBUF1             0x70
++#define RADIO_2056_SYN_LOGEN_MIXER1              0x71
++#define RADIO_2056_SYN_LOGEN_MIXER2              0x72
++#define RADIO_2056_SYN_LOGEN_BUF1                0x73
++#define RADIO_2056_SYN_LOGENBUF2                 0x74
++#define RADIO_2056_SYN_LOGEN_BUF3                0x75
++#define RADIO_2056_SYN_LOGEN_BUF4                0x76
++#define RADIO_2056_SYN_LOGEN_DIV1                0x77
++#define RADIO_2056_SYN_LOGEN_DIV2                0x78
++#define RADIO_2056_SYN_LOGEN_DIV3                0x79
++#define RADIO_2056_SYN_LOGEN_ACL1                0x7a
++#define RADIO_2056_SYN_LOGEN_ACL2                0x7b
++#define RADIO_2056_SYN_LOGEN_ACL3                0x7c
++#define RADIO_2056_SYN_LOGEN_ACL4                0x7d
++#define RADIO_2056_SYN_LOGEN_ACL5                0x7e
++#define RADIO_2056_SYN_LOGEN_ACL6                0x7f
++#define RADIO_2056_SYN_LOGEN_ACLOUT              0x80
++#define RADIO_2056_SYN_LOGEN_ACLCAL1             0x81
++#define RADIO_2056_SYN_LOGEN_ACLCAL2             0x82
++#define RADIO_2056_SYN_LOGEN_ACLCAL3             0x83
++#define RADIO_2056_SYN_CALEN                     0x84
++#define RADIO_2056_SYN_LOGEN_PEAKDET1            0x85
++#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR        0x86
++#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR     0x87
++#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR     0x88
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR     0x89
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR     0x8a
++#define RADIO_2056_SYN_LOGEN_VCOBUF2             0x8b
++#define RADIO_2056_SYN_LOGEN_MIXER3              0x8c
++#define RADIO_2056_SYN_LOGEN_BUF5                0x8d
++#define RADIO_2056_SYN_LOGEN_BUF6                0x8e
++#define RADIO_2056_SYN_LOGEN_CBUFRX1             0x8f
++#define RADIO_2056_SYN_LOGEN_CBUFRX2             0x90
++#define RADIO_2056_SYN_LOGEN_CBUFRX3             0x91
++#define RADIO_2056_SYN_LOGEN_CBUFRX4             0x92
++#define RADIO_2056_SYN_LOGEN_CBUFTX1             0x93
++#define RADIO_2056_SYN_LOGEN_CBUFTX2             0x94
++#define RADIO_2056_SYN_LOGEN_CBUFTX3             0x95
++#define RADIO_2056_SYN_LOGEN_CBUFTX4             0x96
++#define RADIO_2056_SYN_LOGEN_CMOSRX1             0x97
++#define RADIO_2056_SYN_LOGEN_CMOSRX2             0x98
++#define RADIO_2056_SYN_LOGEN_CMOSRX3             0x99
++#define RADIO_2056_SYN_LOGEN_CMOSRX4             0x9a
++#define RADIO_2056_SYN_LOGEN_CMOSTX1             0x9b
++#define RADIO_2056_SYN_LOGEN_CMOSTX2             0x9c
++#define RADIO_2056_SYN_LOGEN_CMOSTX3             0x9d
++#define RADIO_2056_SYN_LOGEN_CMOSTX4             0x9e
++#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL      0x9f
++#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL       0xa0
++#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL         0xa1
++#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL         0xa2
++#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL      0xa3
++#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL      0xa4
++#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL      0xa5
++#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL      0xa6
++#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL      0xa7
++#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL      0xa8
++#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL      0xa9
++#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL      0xaa
++#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL      0xab
++#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL      0xac
++#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL      0xad
++#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL      0xae
++#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL      0xaf
++#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL      0xb0
++#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL      0xb1
++#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL      0xb2
++#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT         0xb3
++#define RADIO_2056_SYN_LOGEN_CORE_CALVALID       0xb4
++#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID    0xb5
++#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID       0xb6
++
++#define RADIO_2056_TX_RESERVED_ADDR0             0x0
++#define RADIO_2056_TX_IDCODE                     0x1
++#define RADIO_2056_TX_RESERVED_ADDR2             0x2
++#define RADIO_2056_TX_RESERVED_ADDR3             0x3
++#define RADIO_2056_TX_RESERVED_ADDR4             0x4
++#define RADIO_2056_TX_RESERVED_ADDR5             0x5
++#define RADIO_2056_TX_RESERVED_ADDR6             0x6
++#define RADIO_2056_TX_RESERVED_ADDR7             0x7
++#define RADIO_2056_TX_COM_CTRL                   0x8
++#define RADIO_2056_TX_COM_PU                     0x9
++#define RADIO_2056_TX_COM_OVR                    0xa
++#define RADIO_2056_TX_COM_RESET                  0xb
++#define RADIO_2056_TX_COM_RCAL                   0xc
++#define RADIO_2056_TX_COM_RC_RXLPF               0xd
++#define RADIO_2056_TX_COM_RC_TXLPF               0xe
++#define RADIO_2056_TX_COM_RC_RXHPF               0xf
++#define RADIO_2056_TX_RESERVED_ADDR16            0x10
++#define RADIO_2056_TX_RESERVED_ADDR17            0x11
++#define RADIO_2056_TX_RESERVED_ADDR18            0x12
++#define RADIO_2056_TX_RESERVED_ADDR19            0x13
++#define RADIO_2056_TX_RESERVED_ADDR20            0x14
++#define RADIO_2056_TX_RESERVED_ADDR21            0x15
++#define RADIO_2056_TX_RESERVED_ADDR22            0x16
++#define RADIO_2056_TX_RESERVED_ADDR23            0x17
++#define RADIO_2056_TX_RESERVED_ADDR24            0x18
++#define RADIO_2056_TX_RESERVED_ADDR25            0x19
++#define RADIO_2056_TX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_TX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_TX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_TX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_TX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_TX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_TX_IQCAL_GAIN_BW              0x20
++#define RADIO_2056_TX_LOFT_FINE_I                0x21
++#define RADIO_2056_TX_LOFT_FINE_Q                0x22
++#define RADIO_2056_TX_LOFT_COARSE_I              0x23
++#define RADIO_2056_TX_LOFT_COARSE_Q              0x24
++#define RADIO_2056_TX_TX_COM_MASTER1             0x25
++#define RADIO_2056_TX_TX_COM_MASTER2             0x26
++#define RADIO_2056_TX_RXIQCAL_TXMUX              0x27
++#define RADIO_2056_TX_TX_SSI_MASTER              0x28
++#define RADIO_2056_TX_IQCAL_VCM_HG               0x29
++#define RADIO_2056_TX_IQCAL_IDAC                 0x2a
++#define RADIO_2056_TX_TSSI_VCM                   0x2b
++#define RADIO_2056_TX_TX_AMP_DET                 0x2c
++#define RADIO_2056_TX_TX_SSI_MUX                 0x2d
++#define RADIO_2056_TX_TSSIA                      0x2e
++#define RADIO_2056_TX_TSSIG                      0x2f
++#define RADIO_2056_TX_TSSI_MISC1                 0x30
++#define RADIO_2056_TX_TSSI_MISC2                 0x31
++#define RADIO_2056_TX_TSSI_MISC3                 0x32
++#define RADIO_2056_TX_PA_SPARE1                  0x33
++#define RADIO_2056_TX_PA_SPARE2                  0x34
++#define RADIO_2056_TX_INTPAA_MASTER              0x35
++#define RADIO_2056_TX_INTPAA_GAIN                0x36
++#define RADIO_2056_TX_INTPAA_BOOST_TUNE          0x37
++#define RADIO_2056_TX_INTPAA_IAUX_STAT           0x38
++#define RADIO_2056_TX_INTPAA_IAUX_DYN            0x39
++#define RADIO_2056_TX_INTPAA_IMAIN_STAT          0x3a
++#define RADIO_2056_TX_INTPAA_IMAIN_DYN           0x3b
++#define RADIO_2056_TX_INTPAA_CASCBIAS            0x3c
++#define RADIO_2056_TX_INTPAA_PASLOPE             0x3d
++#define RADIO_2056_TX_INTPAA_PA_MISC             0x3e
++#define RADIO_2056_TX_INTPAG_MASTER              0x3f
++#define RADIO_2056_TX_INTPAG_GAIN                0x40
++#define RADIO_2056_TX_INTPAG_BOOST_TUNE          0x41
++#define RADIO_2056_TX_INTPAG_IAUX_STAT           0x42
++#define RADIO_2056_TX_INTPAG_IAUX_DYN            0x43
++#define RADIO_2056_TX_INTPAG_IMAIN_STAT          0x44
++#define RADIO_2056_TX_INTPAG_IMAIN_DYN           0x45
++#define RADIO_2056_TX_INTPAG_CASCBIAS            0x46
++#define RADIO_2056_TX_INTPAG_PASLOPE             0x47
++#define RADIO_2056_TX_INTPAG_PA_MISC             0x48
++#define RADIO_2056_TX_PADA_MASTER                0x49
++#define RADIO_2056_TX_PADA_IDAC                  0x4a
++#define RADIO_2056_TX_PADA_CASCBIAS              0x4b
++#define RADIO_2056_TX_PADA_GAIN                  0x4c
++#define RADIO_2056_TX_PADA_BOOST_TUNE            0x4d
++#define RADIO_2056_TX_PADA_SLOPE                 0x4e
++#define RADIO_2056_TX_PADG_MASTER                0x4f
++#define RADIO_2056_TX_PADG_IDAC                  0x50
++#define RADIO_2056_TX_PADG_CASCBIAS              0x51
++#define RADIO_2056_TX_PADG_GAIN                  0x52
++#define RADIO_2056_TX_PADG_BOOST_TUNE            0x53
++#define RADIO_2056_TX_PADG_SLOPE                 0x54
++#define RADIO_2056_TX_PGAA_MASTER                0x55
++#define RADIO_2056_TX_PGAA_IDAC                  0x56
++#define RADIO_2056_TX_PGAA_GAIN                  0x57
++#define RADIO_2056_TX_PGAA_BOOST_TUNE            0x58
++#define RADIO_2056_TX_PGAA_SLOPE                 0x59
++#define RADIO_2056_TX_PGAA_MISC                  0x5a
++#define RADIO_2056_TX_PGAG_MASTER                0x5b
++#define RADIO_2056_TX_PGAG_IDAC                  0x5c
++#define RADIO_2056_TX_PGAG_GAIN                  0x5d
++#define RADIO_2056_TX_PGAG_BOOST_TUNE            0x5e
++#define RADIO_2056_TX_PGAG_SLOPE                 0x5f
++#define RADIO_2056_TX_PGAG_MISC                  0x60
++#define RADIO_2056_TX_MIXA_MASTER                0x61
++#define RADIO_2056_TX_MIXA_BOOST_TUNE            0x62
++#define RADIO_2056_TX_MIXG                       0x63
++#define RADIO_2056_TX_MIXG_BOOST_TUNE            0x64
++#define RADIO_2056_TX_BB_GM_MASTER               0x65
++#define RADIO_2056_TX_GMBB_GM                    0x66
++#define RADIO_2056_TX_GMBB_IDAC                  0x67
++#define RADIO_2056_TX_TXLPF_MASTER               0x68
++#define RADIO_2056_TX_TXLPF_RCCAL                0x69
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF0           0x6a
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF1           0x6b
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF2           0x6c
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF3           0x6d
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF4           0x6e
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF5           0x6f
++#define RADIO_2056_TX_TXLPF_RCCAL_OFF6           0x70
++#define RADIO_2056_TX_TXLPF_BW                   0x71
++#define RADIO_2056_TX_TXLPF_GAIN                 0x72
++#define RADIO_2056_TX_TXLPF_IDAC                 0x73
++#define RADIO_2056_TX_TXLPF_IDAC_0               0x74
++#define RADIO_2056_TX_TXLPF_IDAC_1               0x75
++#define RADIO_2056_TX_TXLPF_IDAC_2               0x76
++#define RADIO_2056_TX_TXLPF_IDAC_3               0x77
++#define RADIO_2056_TX_TXLPF_IDAC_4               0x78
++#define RADIO_2056_TX_TXLPF_IDAC_5               0x79
++#define RADIO_2056_TX_TXLPF_IDAC_6               0x7a
++#define RADIO_2056_TX_TXLPF_OPAMP_IDAC           0x7b
++#define RADIO_2056_TX_TXLPF_MISC                 0x7c
++#define RADIO_2056_TX_TXSPARE1                   0x7d
++#define RADIO_2056_TX_TXSPARE2                   0x7e
++#define RADIO_2056_TX_TXSPARE3                   0x7f
++#define RADIO_2056_TX_TXSPARE4                   0x80
++#define RADIO_2056_TX_TXSPARE5                   0x81
++#define RADIO_2056_TX_TXSPARE6                   0x82
++#define RADIO_2056_TX_TXSPARE7                   0x83
++#define RADIO_2056_TX_TXSPARE8                   0x84
++#define RADIO_2056_TX_TXSPARE9                   0x85
++#define RADIO_2056_TX_TXSPARE10                  0x86
++#define RADIO_2056_TX_TXSPARE11                  0x87
++#define RADIO_2056_TX_TXSPARE12                  0x88
++#define RADIO_2056_TX_TXSPARE13                  0x89
++#define RADIO_2056_TX_TXSPARE14                  0x8a
++#define RADIO_2056_TX_TXSPARE15                  0x8b
++#define RADIO_2056_TX_TXSPARE16                  0x8c
++#define RADIO_2056_TX_STATUS_INTPA_GAIN          0x8d
++#define RADIO_2056_TX_STATUS_PAD_GAIN            0x8e
++#define RADIO_2056_TX_STATUS_PGA_GAIN            0x8f
++#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN       0x90
++#define RADIO_2056_TX_STATUS_TXLPF_BW            0x91
++#define RADIO_2056_TX_STATUS_TXLPF_RC            0x92
++#define RADIO_2056_TX_GMBB_IDAC0                 0x93
++#define RADIO_2056_TX_GMBB_IDAC1                 0x94
++#define RADIO_2056_TX_GMBB_IDAC2                 0x95
++#define RADIO_2056_TX_GMBB_IDAC3                 0x96
++#define RADIO_2056_TX_GMBB_IDAC4                 0x97
++#define RADIO_2056_TX_GMBB_IDAC5                 0x98
++#define RADIO_2056_TX_GMBB_IDAC6                 0x99
++#define RADIO_2056_TX_GMBB_IDAC7                 0x9a
++
++#define RADIO_2056_RX_RESERVED_ADDR0             0x0
++#define RADIO_2056_RX_IDCODE                     0x1
++#define RADIO_2056_RX_RESERVED_ADDR2             0x2
++#define RADIO_2056_RX_RESERVED_ADDR3             0x3
++#define RADIO_2056_RX_RESERVED_ADDR4             0x4
++#define RADIO_2056_RX_RESERVED_ADDR5             0x5
++#define RADIO_2056_RX_RESERVED_ADDR6             0x6
++#define RADIO_2056_RX_RESERVED_ADDR7             0x7
++#define RADIO_2056_RX_COM_CTRL                   0x8
++#define RADIO_2056_RX_COM_PU                     0x9
++#define RADIO_2056_RX_COM_OVR                    0xa
++#define RADIO_2056_RX_COM_RESET                  0xb
++#define RADIO_2056_RX_COM_RCAL                   0xc
++#define RADIO_2056_RX_COM_RC_RXLPF               0xd
++#define RADIO_2056_RX_COM_RC_TXLPF               0xe
++#define RADIO_2056_RX_COM_RC_RXHPF               0xf
++#define RADIO_2056_RX_RESERVED_ADDR16            0x10
++#define RADIO_2056_RX_RESERVED_ADDR17            0x11
++#define RADIO_2056_RX_RESERVED_ADDR18            0x12
++#define RADIO_2056_RX_RESERVED_ADDR19            0x13
++#define RADIO_2056_RX_RESERVED_ADDR20            0x14
++#define RADIO_2056_RX_RESERVED_ADDR21            0x15
++#define RADIO_2056_RX_RESERVED_ADDR22            0x16
++#define RADIO_2056_RX_RESERVED_ADDR23            0x17
++#define RADIO_2056_RX_RESERVED_ADDR24            0x18
++#define RADIO_2056_RX_RESERVED_ADDR25            0x19
++#define RADIO_2056_RX_RESERVED_ADDR26            0x1a
++#define RADIO_2056_RX_RESERVED_ADDR27            0x1b
++#define RADIO_2056_RX_RESERVED_ADDR28            0x1c
++#define RADIO_2056_RX_RESERVED_ADDR29            0x1d
++#define RADIO_2056_RX_RESERVED_ADDR30            0x1e
++#define RADIO_2056_RX_RESERVED_ADDR31            0x1f
++#define RADIO_2056_RX_RXIQCAL_RXMUX              0x20
++#define RADIO_2056_RX_RSSI_PU                    0x21
++#define RADIO_2056_RX_RSSI_SEL                   0x22
++#define RADIO_2056_RX_RSSI_GAIN                  0x23
++#define RADIO_2056_RX_RSSI_NB_IDAC               0x24
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_1           0x25
++#define RADIO_2056_RX_RSSI_WB2I_IDAC_2           0x26
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1           0x27
++#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2           0x28
++#define RADIO_2056_RX_RSSI_POLE                  0x29
++#define RADIO_2056_RX_RSSI_WB1_IDAC              0x2a
++#define RADIO_2056_RX_RSSI_MISC                  0x2b
++#define RADIO_2056_RX_LNAA_MASTER                0x2c
++#define RADIO_2056_RX_LNAA_TUNE                  0x2d
++#define RADIO_2056_RX_LNAA_GAIN                  0x2e
++#define RADIO_2056_RX_LNA_A_SLOPE                0x2f
++#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC        0x30
++#define RADIO_2056_RX_LNAA2_IDAC                 0x31
++#define RADIO_2056_RX_LNA1A_MISC                 0x32
++#define RADIO_2056_RX_LNAG_MASTER                0x33
++#define RADIO_2056_RX_LNAG_TUNE                  0x34
++#define RADIO_2056_RX_LNAG_GAIN                  0x35
++#define RADIO_2056_RX_LNA_G_SLOPE                0x36
++#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC        0x37
++#define RADIO_2056_RX_LNAG2_IDAC                 0x38
++#define RADIO_2056_RX_LNA1G_MISC                 0x39
++#define RADIO_2056_RX_MIXA_MASTER                0x3a
++#define RADIO_2056_RX_MIXA_VCM                   0x3b
++#define RADIO_2056_RX_MIXA_CTRLPTAT              0x3c
++#define RADIO_2056_RX_MIXA_LOB_BIAS              0x3d
++#define RADIO_2056_RX_MIXA_CORE_IDAC             0x3e
++#define RADIO_2056_RX_MIXA_CMFB_IDAC             0x3f
++#define RADIO_2056_RX_MIXA_BIAS_AUX              0x40
++#define RADIO_2056_RX_MIXA_BIAS_MAIN             0x41
++#define RADIO_2056_RX_MIXA_BIAS_MISC             0x42
++#define RADIO_2056_RX_MIXA_MAST_BIAS             0x43
++#define RADIO_2056_RX_MIXG_MASTER                0x44
++#define RADIO_2056_RX_MIXG_VCM                   0x45
++#define RADIO_2056_RX_MIXG_CTRLPTAT              0x46
++#define RADIO_2056_RX_MIXG_LOB_BIAS              0x47
++#define RADIO_2056_RX_MIXG_CORE_IDAC             0x48
++#define RADIO_2056_RX_MIXG_CMFB_IDAC             0x49
++#define RADIO_2056_RX_MIXG_BIAS_AUX              0x4a
++#define RADIO_2056_RX_MIXG_BIAS_MAIN             0x4b
++#define RADIO_2056_RX_MIXG_BIAS_MISC             0x4c
++#define RADIO_2056_RX_MIXG_MAST_BIAS             0x4d
++#define RADIO_2056_RX_TIA_MASTER                 0x4e
++#define RADIO_2056_RX_TIA_IOPAMP                 0x4f
++#define RADIO_2056_RX_TIA_QOPAMP                 0x50
++#define RADIO_2056_RX_TIA_IMISC                  0x51
++#define RADIO_2056_RX_TIA_QMISC                  0x52
++#define RADIO_2056_RX_TIA_GAIN                   0x53
++#define RADIO_2056_RX_TIA_SPARE1                 0x54
++#define RADIO_2056_RX_TIA_SPARE2                 0x55
++#define RADIO_2056_RX_BB_LPF_MASTER              0x56
++#define RADIO_2056_RX_AACI_MASTER                0x57
++#define RADIO_2056_RX_RXLPF_IDAC                 0x58
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ       0x59
++#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ      0x5a
++#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL        0x5b
++#define RADIO_2056_RX_RXLPF_OUTVCM               0x5c
++#define RADIO_2056_RX_RXLPF_INVCM_BODY           0x5d
++#define RADIO_2056_RX_RXLPF_CC_OP                0x5e
++#define RADIO_2056_RX_RXLPF_GAIN                 0x5f
++#define RADIO_2056_RX_RXLPF_Q_BW                 0x60
++#define RADIO_2056_RX_RXLPF_HP_CORNER_BW         0x61
++#define RADIO_2056_RX_RXLPF_RCCAL_HPC            0x62
++#define RADIO_2056_RX_RXHPF_OFF0                 0x63
++#define RADIO_2056_RX_RXHPF_OFF1                 0x64
++#define RADIO_2056_RX_RXHPF_OFF2                 0x65
++#define RADIO_2056_RX_RXHPF_OFF3                 0x66
++#define RADIO_2056_RX_RXHPF_OFF4                 0x67
++#define RADIO_2056_RX_RXHPF_OFF5                 0x68
++#define RADIO_2056_RX_RXHPF_OFF6                 0x69
++#define RADIO_2056_RX_RXHPF_OFF7                 0x6a
++#define RADIO_2056_RX_RXLPF_RCCAL_LPC            0x6b
++#define RADIO_2056_RX_RXLPF_OFF_0                0x6c
++#define RADIO_2056_RX_RXLPF_OFF_1                0x6d
++#define RADIO_2056_RX_RXLPF_OFF_2                0x6e
++#define RADIO_2056_RX_RXLPF_OFF_3                0x6f
++#define RADIO_2056_RX_RXLPF_OFF_4                0x70
++#define RADIO_2056_RX_UNUSED                     0x71
++#define RADIO_2056_RX_VGA_MASTER                 0x72
++#define RADIO_2056_RX_VGA_BIAS                   0x73
++#define RADIO_2056_RX_VGA_BIAS_DCCANCEL          0x74
++#define RADIO_2056_RX_VGA_GAIN                   0x75
++#define RADIO_2056_RX_VGA_HP_CORNER_BW           0x76
++#define RADIO_2056_RX_VGABUF_BIAS                0x77
++#define RADIO_2056_RX_VGABUF_GAIN_BW             0x78
++#define RADIO_2056_RX_TXFBMIX_A                  0x79
++#define RADIO_2056_RX_TXFBMIX_G                  0x7a
++#define RADIO_2056_RX_RXSPARE1                   0x7b
++#define RADIO_2056_RX_RXSPARE2                   0x7c
++#define RADIO_2056_RX_RXSPARE3                   0x7d
++#define RADIO_2056_RX_RXSPARE4                   0x7e
++#define RADIO_2056_RX_RXSPARE5                   0x7f
++#define RADIO_2056_RX_RXSPARE6                   0x80
++#define RADIO_2056_RX_RXSPARE7                   0x81
++#define RADIO_2056_RX_RXSPARE8                   0x82
++#define RADIO_2056_RX_RXSPARE9                   0x83
++#define RADIO_2056_RX_RXSPARE10                  0x84
++#define RADIO_2056_RX_RXSPARE11                  0x85
++#define RADIO_2056_RX_RXSPARE12                  0x86
++#define RADIO_2056_RX_RXSPARE13                  0x87
++#define RADIO_2056_RX_RXSPARE14                  0x88
++#define RADIO_2056_RX_RXSPARE15                  0x89
++#define RADIO_2056_RX_RXSPARE16                  0x8a
++#define RADIO_2056_RX_STATUS_LNAA_GAIN           0x8b
++#define RADIO_2056_RX_STATUS_LNAG_GAIN           0x8c
++#define RADIO_2056_RX_STATUS_MIXTIA_GAIN         0x8d
++#define RADIO_2056_RX_STATUS_RXLPF_GAIN          0x8e
++#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN        0x8f
++#define RADIO_2056_RX_STATUS_RXLPF_Q             0x90
++#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW        0x91
++#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC       0x92
++#define RADIO_2056_RX_STATUS_RXLPF_RC            0x93
++#define RADIO_2056_RX_STATUS_HPC_RC              0x94
++
++#define RADIO_2056_LNA1_A_PU		0x01
++#define RADIO_2056_LNA2_A_PU		0x02
++#define RADIO_2056_LNA1_G_PU		0x01
++#define RADIO_2056_LNA2_G_PU		0x02
++#define RADIO_2056_MIXA_PU_I		0x01
++#define RADIO_2056_MIXA_PU_Q		0x02
++#define RADIO_2056_MIXA_PU_GM		0x10
++#define RADIO_2056_MIXG_PU_I		0x01
++#define RADIO_2056_MIXG_PU_Q		0x02
++#define RADIO_2056_MIXG_PU_GM		0x10
++#define RADIO_2056_TIA_PU			0x01
++#define RADIO_2056_BB_LPF_PU		0x20
++#define RADIO_2056_W1_PU			0x02
++#define RADIO_2056_W2_PU			0x04
++#define RADIO_2056_NB_PU			0x08
++#define RADIO_2056_RSSI_W1_SEL		0x02
++#define RADIO_2056_RSSI_W2_SEL		0x04
++#define RADIO_2056_RSSI_NB_SEL		0x08
++#define RADIO_2056_VCM_MASK			0x1c
++#define RADIO_2056_RSSI_VCM_SHIFT	0x02
++
++#define RADIO_2057_DACBUF_VINCM_CORE0            0x0
++#define RADIO_2057_IDCODE                        0x1
++#define RADIO_2057_RCCAL_MASTER                  0x2
++#define RADIO_2057_RCCAL_CAP_SIZE                0x3
++#define RADIO_2057_RCAL_CONFIG                   0x4
++#define RADIO_2057_GPAIO_CONFIG                  0x5
++#define RADIO_2057_GPAIO_SEL1                    0x6
++#define RADIO_2057_GPAIO_SEL0                    0x7
++#define RADIO_2057_CLPO_CONFIG                   0x8
++#define RADIO_2057_BANDGAP_CONFIG                0x9
++#define RADIO_2057_BANDGAP_RCAL_TRIM             0xa
++#define RADIO_2057_AFEREG_CONFIG                 0xb
++#define RADIO_2057_TEMPSENSE_CONFIG              0xc
++#define RADIO_2057_XTAL_CONFIG1                  0xd
++#define RADIO_2057_XTAL_ICORE_SIZE               0xe
++#define RADIO_2057_XTAL_BUF_SIZE                 0xf
++#define RADIO_2057_XTAL_PULLCAP_SIZE             0x10
++#define RADIO_2057_RFPLL_MASTER                  0x11
++#define RADIO_2057_VCOMONITOR_VTH_L              0x12
++#define RADIO_2057_VCOMONITOR_VTH_H              0x13
++#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
++#define RADIO_2057_VCO_VARCSIZE_IDAC             0x15
++#define RADIO_2057_VCOCAL_COUNTVAL0              0x16
++#define RADIO_2057_VCOCAL_COUNTVAL1              0x17
++#define RADIO_2057_VCOCAL_INTCLK_COUNT           0x18
++#define RADIO_2057_VCOCAL_MASTER                 0x19
++#define RADIO_2057_VCOCAL_NUMCAPCHANGE           0x1a
++#define RADIO_2057_VCOCAL_WINSIZE                0x1b
++#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH    0x1c
++#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP  0x1d
++#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP   0x1e
++#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP  0x1f
++#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1      0x20
++#define RADIO_2057_VCO_FORCECAP0                 0x21
++#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
++#define RADIO_2057_RFPLL_PFD_RESET_PW            0x23
++#define RADIO_2057_RFPLL_LOOPFILTER_R2           0x24
++#define RADIO_2057_RFPLL_LOOPFILTER_R1           0x25
++#define RADIO_2057_RFPLL_LOOPFILTER_C3           0x26
++#define RADIO_2057_RFPLL_LOOPFILTER_C2           0x27
++#define RADIO_2057_RFPLL_LOOPFILTER_C1           0x28
++#define RADIO_2057_CP_KPD_IDAC                   0x29
++#define RADIO_2057_RFPLL_IDACS                   0x2a
++#define RADIO_2057_RFPLL_MISC_EN                 0x2b
++#define RADIO_2057_RFPLL_MMD0                    0x2c
++#define RADIO_2057_RFPLL_MMD1                    0x2d
++#define RADIO_2057_RFPLL_MISC_CAL_RESETN         0x2e
++#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES  0x2f
++#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE     0x30
++#define RADIO_2057_VCOCAL_READCAP0               0x31
++#define RADIO_2057_VCOCAL_READCAP1               0x32
++#define RADIO_2057_VCOCAL_STATUS                 0x33
++#define RADIO_2057_LOGEN_PUS                     0x34
++#define RADIO_2057_LOGEN_PTAT_RESETS             0x35
++#define RADIO_2057_VCOBUF_IDACS                  0x36
++#define RADIO_2057_VCOBUF_TUNE                   0x37
++#define RADIO_2057_CMOSBUF_TX2GQ_IDACS           0x38
++#define RADIO_2057_CMOSBUF_TX2GI_IDACS           0x39
++#define RADIO_2057_CMOSBUF_TX5GQ_IDACS           0x3a
++#define RADIO_2057_CMOSBUF_TX5GI_IDACS           0x3b
++#define RADIO_2057_CMOSBUF_RX2GQ_IDACS           0x3c
++#define RADIO_2057_CMOSBUF_RX2GI_IDACS           0x3d
++#define RADIO_2057_CMOSBUF_RX5GQ_IDACS           0x3e
++#define RADIO_2057_CMOSBUF_RX5GI_IDACS           0x3f
++#define RADIO_2057_LOGEN_MX2G_IDACS              0x40
++#define RADIO_2057_LOGEN_MX2G_TUNE               0x41
++#define RADIO_2057_LOGEN_MX5G_IDACS              0x42
++#define RADIO_2057_LOGEN_MX5G_TUNE               0x43
++#define RADIO_2057_LOGEN_MX5G_RCCR               0x44
++#define RADIO_2057_LOGEN_INDBUF2G_IDAC           0x45
++#define RADIO_2057_LOGEN_INDBUF2G_IBOOST         0x46
++#define RADIO_2057_LOGEN_INDBUF2G_TUNE           0x47
++#define RADIO_2057_LOGEN_INDBUF5G_IDAC           0x48
++#define RADIO_2057_LOGEN_INDBUF5G_IBOOST         0x49
++#define RADIO_2057_LOGEN_INDBUF5G_TUNE           0x4a
++#define RADIO_2057_CMOSBUF_TX_RCCR               0x4b
++#define RADIO_2057_CMOSBUF_RX_RCCR               0x4c
++#define RADIO_2057_LOGEN_SEL_PKDET               0x4d
++#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT          0x4e
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE0         0x4f
++#define RADIO_2057_TXGM_TXRF_PUS_CORE0           0x50
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE0         0x51
++#define RADIO_2057_TXGM_GAIN_CORE0               0x56
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0        0x57
++#define RADIO_2057_PAD2G_PTATS_CORE0             0x58
++#define RADIO_2057_PAD2G_IDACS_CORE0             0x59
++#define RADIO_2057_PAD2G_BOOST_PU_CORE0          0x5a
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0        0x5b
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0   0x5c
++#define RADIO_2057_TXMIX2G_LODC_CORE0            0x5d
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE0          0x5e
++#define RADIO_2057_IPA2G_GAIN_CORE0              0x5f
++#define RADIO_2057_TSSI2G_SPARE1_CORE0           0x60
++#define RADIO_2057_TSSI2G_SPARE2_CORE0           0x61
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0  0x62
++#define RADIO_2057_IPA2G_IMAIN_CORE0             0x63
++#define RADIO_2057_IPA2G_CASCONV_CORE0           0x64
++#define RADIO_2057_IPA2G_CASCOFFV_CORE0          0x65
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0       0x66
++#define RADIO_2057_TX5G_PKDET_CORE0              0x69
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0      0x6a
++#define RADIO_2057_PAD5G_PTATS1_CORE0            0x6b
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0      0x6c
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0     0x6d
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0       0x6e
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
++#define RADIO_2057_PGA_BOOST_TUNE_CORE0          0x70
++#define RADIO_2057_PGA_GAIN_CORE0                0x71
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0      0x73
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0     0x74
++#define RADIO_2057_IPA5G_IAUX_CORE0              0x75
++#define RADIO_2057_IPA5G_GAIN_CORE0              0x76
++#define RADIO_2057_TSSI5G_SPARE1_CORE0           0x77
++#define RADIO_2057_TSSI5G_SPARE2_CORE0           0x78
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0       0x79
++#define RADIO_2057_IPA5G_PTAT_CORE0              0x7a
++#define RADIO_2057_IPA5G_IMAIN_CORE0             0x7b
++#define RADIO_2057_IPA5G_CASCONV_CORE0           0x7c
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0       0x7d
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0     0x80
++#define RADIO_2057_TR2G_CONFIG1_CORE0_NU         0x81
++#define RADIO_2057_TR2G_CONFIG2_CORE0_NU         0x82
++#define RADIO_2057_LNA5G_RFEN_CORE0              0x83
++#define RADIO_2057_TR5G_CONFIG2_CORE0_NU         0x84
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0      0x85
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0  0x87
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0   0x88
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0      0x89
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0      0x8a
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE0          0x8b
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0      0x8c
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0        0x8e
++#define RADIO_2057_TIA_CONFIG_CORE0              0x8f
++#define RADIO_2057_TIA_IQGAIN_CORE0              0x90
++#define RADIO_2057_TIA_IBIAS2_CORE0              0x91
++#define RADIO_2057_TIA_IBIAS1_CORE0              0x92
++#define RADIO_2057_TIA_SPARE_Q_CORE0             0x93
++#define RADIO_2057_TIA_SPARE_I_CORE0             0x94
++#define RADIO_2057_RXMIX2G_PUS_CORE0             0x95
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE0         0x96
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE0         0x97
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0       0x98
++#define RADIO_2057_LNA2G_GAIN_CORE0              0x99
++#define RADIO_2057_LNA2G_TUNE_CORE0              0x9a
++#define RADIO_2057_RXMIX5G_PUS_CORE0             0x9b
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE0         0x9c
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE0         0x9d
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0       0x9e
++#define RADIO_2057_LNA5G_GAIN_CORE0              0x9f
++#define RADIO_2057_LNA5G_TUNE_CORE0              0xa0
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0    0xa1
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE0        0xa2
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0       0xa3
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
++#define RADIO_2057_TXBUF_VINCM_CORE0             0xa5
++#define RADIO_2057_TXBUF_IDACS_CORE0             0xa6
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0       0xa7
++#define RADIO_2057_RXBB_CC_CORE0                 0xa8
++#define RADIO_2057_RXBB_SPARE3_CORE0             0xa9
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE0          0xaa
++#define RADIO_2057_LPF_IDACS_CORE0               0xab
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0  0xac
++#define RADIO_2057_TXBUF_GAIN_CORE0              0xad
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0   0xae
++#define RADIO_2057_RXBUF_DEGEN_CORE0             0xaf
++#define RADIO_2057_RXBB_SPARE2_CORE0             0xb0
++#define RADIO_2057_RXBB_SPARE1_CORE0             0xb1
++#define RADIO_2057_RSSI_MASTER_CORE0             0xb2
++#define RADIO_2057_W2_MASTER_CORE0               0xb3
++#define RADIO_2057_NB_MASTER_CORE0               0xb4
++#define RADIO_2057_W2_IDACS0_Q_CORE0             0xb5
++#define RADIO_2057_W2_IDACS1_Q_CORE0             0xb6
++#define RADIO_2057_W2_IDACS0_I_CORE0             0xb7
++#define RADIO_2057_W2_IDACS1_I_CORE0             0xb8
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0  0xb9
++#define RADIO_2057_NB_IDACS_Q_CORE0              0xba
++#define RADIO_2057_NB_IDACS_I_CORE0              0xbb
++#define RADIO_2057_BACKUP4_CORE0                 0xc1
++#define RADIO_2057_BACKUP3_CORE0                 0xc2
++#define RADIO_2057_BACKUP2_CORE0                 0xc3
++#define RADIO_2057_BACKUP1_CORE0                 0xc4
++#define RADIO_2057_SPARE16_CORE0                 0xc5
++#define RADIO_2057_SPARE15_CORE0                 0xc6
++#define RADIO_2057_SPARE14_CORE0                 0xc7
++#define RADIO_2057_SPARE13_CORE0                 0xc8
++#define RADIO_2057_SPARE12_CORE0                 0xc9
++#define RADIO_2057_SPARE11_CORE0                 0xca
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE0        0xcb
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE0        0xcc
++#define RADIO_2057_IQTEST_SEL_PU                 0xcd
++#define RADIO_2057_XTAL_CONFIG2                  0xce
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE0         0xcf
++#define RADIO_2057_TXLPF_RCCAL_CORE0             0xd0
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
++#define RADIO_2057_LPF_GAIN_CORE0                0xd2
++#define RADIO_2057_DACBUF_IDACS_BW_CORE0         0xd3
++#define RADIO_2057_RXTXBIAS_CONFIG_CORE1         0xd4
++#define RADIO_2057_TXGM_TXRF_PUS_CORE1           0xd5
++#define RADIO_2057_TXGM_IDAC_BLEED_CORE1         0xd6
++#define RADIO_2057_TXGM_GAIN_CORE1               0xdb
++#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1        0xdc
++#define RADIO_2057_PAD2G_PTATS_CORE1             0xdd
++#define RADIO_2057_PAD2G_IDACS_CORE1             0xde
++#define RADIO_2057_PAD2G_BOOST_PU_CORE1          0xdf
++#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1        0xe0
++#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1   0xe1
++#define RADIO_2057_TXMIX2G_LODC_CORE1            0xe2
++#define RADIO_2057_PAD2G_TUNE_PUS_CORE1          0xe3
++#define RADIO_2057_IPA2G_GAIN_CORE1              0xe4
++#define RADIO_2057_TSSI2G_SPARE1_CORE1           0xe5
++#define RADIO_2057_TSSI2G_SPARE2_CORE1           0xe6
++#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1  0xe7
++#define RADIO_2057_IPA2G_IMAIN_CORE1             0xe8
++#define RADIO_2057_IPA2G_CASCONV_CORE1           0xe9
++#define RADIO_2057_IPA2G_CASCOFFV_CORE1          0xea
++#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1       0xeb
++#define RADIO_2057_TX5G_PKDET_CORE1              0xee
++#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1      0xef
++#define RADIO_2057_PAD5G_PTATS1_CORE1            0xf0
++#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1      0xf1
++#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1     0xf2
++#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1       0xf3
++#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
++#define RADIO_2057_PGA_BOOST_TUNE_CORE1          0xf5
++#define RADIO_2057_PGA_GAIN_CORE1                0xf6
++#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
++#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1      0xf8
++#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1     0xf9
++#define RADIO_2057_IPA5G_IAUX_CORE1              0xfa
++#define RADIO_2057_IPA5G_GAIN_CORE1              0xfb
++#define RADIO_2057_TSSI5G_SPARE1_CORE1           0xfc
++#define RADIO_2057_TSSI5G_SPARE2_CORE1           0xfd
++#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1       0xfe
++#define RADIO_2057_IPA5G_PTAT_CORE1              0xff
++#define RADIO_2057_IPA5G_IMAIN_CORE1             0x100
++#define RADIO_2057_IPA5G_CASCONV_CORE1           0x101
++#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1       0x102
++#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1     0x105
++#define RADIO_2057_TR2G_CONFIG1_CORE1_NU         0x106
++#define RADIO_2057_TR2G_CONFIG2_CORE1_NU         0x107
++#define RADIO_2057_LNA5G_RFEN_CORE1              0x108
++#define RADIO_2057_TR5G_CONFIG2_CORE1_NU         0x109
++#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1      0x10a
++#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
++#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1  0x10c
++#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1   0x10d
++#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1      0x10e
++#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1      0x10f
++#define RADIO_2057_LNA2_IAUX_PTAT_CORE1          0x110
++#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1      0x111
++#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
++#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1        0x113
++#define RADIO_2057_TIA_CONFIG_CORE1              0x114
++#define RADIO_2057_TIA_IQGAIN_CORE1              0x115
++#define RADIO_2057_TIA_IBIAS2_CORE1              0x116
++#define RADIO_2057_TIA_IBIAS1_CORE1              0x117
++#define RADIO_2057_TIA_SPARE_Q_CORE1             0x118
++#define RADIO_2057_TIA_SPARE_I_CORE1             0x119
++#define RADIO_2057_RXMIX2G_PUS_CORE1             0x11a
++#define RADIO_2057_RXMIX2G_VCMREFS_CORE1         0x11b
++#define RADIO_2057_RXMIX2G_LODC_QI_CORE1         0x11c
++#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1       0x11d
++#define RADIO_2057_LNA2G_GAIN_CORE1              0x11e
++#define RADIO_2057_LNA2G_TUNE_CORE1              0x11f
++#define RADIO_2057_RXMIX5G_PUS_CORE1             0x120
++#define RADIO_2057_RXMIX5G_VCMREFS_CORE1         0x121
++#define RADIO_2057_RXMIX5G_LODC_QI_CORE1         0x122
++#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1       0x123
++#define RADIO_2057_LNA5G_GAIN_CORE1              0x124
++#define RADIO_2057_LNA5G_TUNE_CORE1              0x125
++#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1    0x126
++#define RADIO_2057_RXBB_BIAS_MASTER_CORE1        0x127
++#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1       0x128
++#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
++#define RADIO_2057_TXBUF_VINCM_CORE1             0x12a
++#define RADIO_2057_TXBUF_IDACS_CORE1             0x12b
++#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1       0x12c
++#define RADIO_2057_RXBB_CC_CORE1                 0x12d
++#define RADIO_2057_RXBB_SPARE3_CORE1             0x12e
++#define RADIO_2057_RXBB_RCCAL_HPC_CORE1          0x12f
++#define RADIO_2057_LPF_IDACS_CORE1               0x130
++#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1  0x131
++#define RADIO_2057_TXBUF_GAIN_CORE1              0x132
++#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1   0x133
++#define RADIO_2057_RXBUF_DEGEN_CORE1             0x134
++#define RADIO_2057_RXBB_SPARE2_CORE1             0x135
++#define RADIO_2057_RXBB_SPARE1_CORE1             0x136
++#define RADIO_2057_RSSI_MASTER_CORE1             0x137
++#define RADIO_2057_W2_MASTER_CORE1               0x138
++#define RADIO_2057_NB_MASTER_CORE1               0x139
++#define RADIO_2057_W2_IDACS0_Q_CORE1             0x13a
++#define RADIO_2057_W2_IDACS1_Q_CORE1             0x13b
++#define RADIO_2057_W2_IDACS0_I_CORE1             0x13c
++#define RADIO_2057_W2_IDACS1_I_CORE1             0x13d
++#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1  0x13e
++#define RADIO_2057_NB_IDACS_Q_CORE1              0x13f
++#define RADIO_2057_NB_IDACS_I_CORE1              0x140
++#define RADIO_2057_BACKUP4_CORE1                 0x146
++#define RADIO_2057_BACKUP3_CORE1                 0x147
++#define RADIO_2057_BACKUP2_CORE1                 0x148
++#define RADIO_2057_BACKUP1_CORE1                 0x149
++#define RADIO_2057_SPARE16_CORE1                 0x14a
++#define RADIO_2057_SPARE15_CORE1                 0x14b
++#define RADIO_2057_SPARE14_CORE1                 0x14c
++#define RADIO_2057_SPARE13_CORE1                 0x14d
++#define RADIO_2057_SPARE12_CORE1                 0x14e
++#define RADIO_2057_SPARE11_CORE1                 0x14f
++#define RADIO_2057_TX2G_BIAS_RESETS_CORE1        0x150
++#define RADIO_2057_TX5G_BIAS_RESETS_CORE1        0x151
++#define RADIO_2057_SPARE8_CORE1                  0x152
++#define RADIO_2057_SPARE7_CORE1                  0x153
++#define RADIO_2057_BUFS_MISC_LPFBW_CORE1         0x154
++#define RADIO_2057_TXLPF_RCCAL_CORE1             0x155
++#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
++#define RADIO_2057_LPF_GAIN_CORE1                0x157
++#define RADIO_2057_DACBUF_IDACS_BW_CORE1         0x158
++#define RADIO_2057_DACBUF_VINCM_CORE1            0x159
++#define RADIO_2057_RCCAL_START_R1_Q1_P1          0x15a
++#define RADIO_2057_RCCAL_X1                      0x15b
++#define RADIO_2057_RCCAL_TRC0                    0x15c
++#define RADIO_2057_RCCAL_TRC1                    0x15d
++#define RADIO_2057_RCCAL_DONE_OSCCAP             0x15e
++#define RADIO_2057_RCCAL_N0_0                    0x15f
++#define RADIO_2057_RCCAL_N0_1                    0x160
++#define RADIO_2057_RCCAL_N1_0                    0x161
++#define RADIO_2057_RCCAL_N1_1                    0x162
++#define RADIO_2057_RCAL_STATUS                   0x163
++#define RADIO_2057_XTALPUOVR_PINCTRL             0x164
++#define RADIO_2057_OVR_REG0                      0x165
++#define RADIO_2057_OVR_REG1                      0x166
++#define RADIO_2057_OVR_REG2                      0x167
++#define RADIO_2057_OVR_REG3                      0x168
++#define RADIO_2057_OVR_REG4                      0x169
++#define RADIO_2057_RCCAL_SCAP_VAL                0x16a
++#define RADIO_2057_RCCAL_BCAP_VAL                0x16b
++#define RADIO_2057_RCCAL_HPC_VAL                 0x16c
++#define RADIO_2057_RCCAL_OVERRIDES               0x16d
++#define RADIO_2057_TX0_IQCAL_GAIN_BW             0x170
++#define RADIO_2057_TX0_LOFT_FINE_I               0x171
++#define RADIO_2057_TX0_LOFT_FINE_Q               0x172
++#define RADIO_2057_TX0_LOFT_COARSE_I             0x173
++#define RADIO_2057_TX0_LOFT_COARSE_Q             0x174
++#define RADIO_2057_TX0_TX_SSI_MASTER             0x175
++#define RADIO_2057_TX0_IQCAL_VCM_HG              0x176
++#define RADIO_2057_TX0_IQCAL_IDAC                0x177
++#define RADIO_2057_TX0_TSSI_VCM                  0x178
++#define RADIO_2057_TX0_TX_SSI_MUX                0x179
++#define RADIO_2057_TX0_TSSIA                     0x17a
++#define RADIO_2057_TX0_TSSIG                     0x17b
++#define RADIO_2057_TX0_TSSI_MISC1                0x17c
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN       0x17d
++#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP       0x17e
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN       0x17f
++#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP       0x180
++#define RADIO_2057_TX1_IQCAL_GAIN_BW             0x190
++#define RADIO_2057_TX1_LOFT_FINE_I               0x191
++#define RADIO_2057_TX1_LOFT_FINE_Q               0x192
++#define RADIO_2057_TX1_LOFT_COARSE_I             0x193
++#define RADIO_2057_TX1_LOFT_COARSE_Q             0x194
++#define RADIO_2057_TX1_TX_SSI_MASTER             0x195
++#define RADIO_2057_TX1_IQCAL_VCM_HG              0x196
++#define RADIO_2057_TX1_IQCAL_IDAC                0x197
++#define RADIO_2057_TX1_TSSI_VCM                  0x198
++#define RADIO_2057_TX1_TX_SSI_MUX                0x199
++#define RADIO_2057_TX1_TSSIA                     0x19a
++#define RADIO_2057_TX1_TSSIG                     0x19b
++#define RADIO_2057_TX1_TSSI_MISC1                0x19c
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN       0x19d
++#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP       0x19e
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN       0x19f
++#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP       0x1a0
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0      0x1a1
++#define RADIO_2057_AFE_SET_VCM_I_CORE0           0x1a2
++#define RADIO_2057_AFE_SET_VCM_Q_CORE0           0x1a3
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0    0x1a4
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE0        0x1a5
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0        0x1a6
++#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1      0x1a7
++#define RADIO_2057_AFE_SET_VCM_I_CORE1           0x1a8
++#define RADIO_2057_AFE_SET_VCM_Q_CORE1           0x1a9
++#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1    0x1aa
++#define RADIO_2057_AFE_STATUS_VCM_I_CORE1        0x1ab
++#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1        0x1ac
++
++#define RADIO_2057v7_DACBUF_VINCM_CORE0          0x1ad
++#define RADIO_2057v7_RCCAL_MASTER                0x1ae
++#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU       0x1af
++#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU       0x1b0
++#define RADIO_2057v7_LOGEN_PUS1                  0x1b1
++#define RADIO_2057v7_OVR_REG5                    0x1b2
++#define RADIO_2057v7_OVR_REG6                    0x1b3
++#define RADIO_2057v7_OVR_REG7                    0x1b4
++#define RADIO_2057v7_OVR_REG8                    0x1b5
++#define RADIO_2057v7_OVR_REG9                    0x1b6
++#define RADIO_2057v7_OVR_REG10                   0x1b7
++#define RADIO_2057v7_OVR_REG11                   0x1b8
++#define RADIO_2057v7_OVR_REG12                   0x1b9
++#define RADIO_2057v7_OVR_REG13                   0x1ba
++#define RADIO_2057v7_OVR_REG14                   0x1bb
++#define RADIO_2057v7_OVR_REG15                   0x1bc
++#define RADIO_2057v7_OVR_REG16                   0x1bd
++#define RADIO_2057v7_OVR_REG1                    0x1be
++#define RADIO_2057v7_OVR_REG18                   0x1bf
++#define RADIO_2057v7_OVR_REG19                   0x1c0
++#define RADIO_2057v7_OVR_REG20                   0x1c1
++#define RADIO_2057v7_OVR_REG21                   0x1c2
++#define RADIO_2057v7_OVR_REG2                    0x1c3
++#define RADIO_2057v7_OVR_REG23                   0x1c4
++#define RADIO_2057v7_OVR_REG24                   0x1c5
++#define RADIO_2057v7_OVR_REG25                   0x1c6
++#define RADIO_2057v7_OVR_REG26                   0x1c7
++#define RADIO_2057v7_OVR_REG27                   0x1c8
++#define RADIO_2057v7_OVR_REG28                   0x1c9
++#define RADIO_2057v7_IQTEST_SEL_PU2              0x1ca
++
++#define RADIO_2057_VCM_MASK			 0x7
++
++#endif				/* _BRCM_PHY_RADIO_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+new file mode 100644
+index 0000000..a97c3a7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define NPHY_TBL_ID_GAIN1		0
++#define NPHY_TBL_ID_GAIN2		1
++#define NPHY_TBL_ID_GAINBITS1		2
++#define NPHY_TBL_ID_GAINBITS2		3
++#define NPHY_TBL_ID_GAINLIMIT		4
++#define NPHY_TBL_ID_WRSSIGainLimit	5
++#define NPHY_TBL_ID_RFSEQ		7
++#define NPHY_TBL_ID_AFECTRL		8
++#define NPHY_TBL_ID_ANTSWCTRLLUT	9
++#define NPHY_TBL_ID_IQLOCAL		15
++#define NPHY_TBL_ID_NOISEVAR		16
++#define NPHY_TBL_ID_SAMPLEPLAY		17
++#define NPHY_TBL_ID_CORE1TXPWRCTL	26
++#define NPHY_TBL_ID_CORE2TXPWRCTL	27
++#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL	30
++
++#define NPHY_TBL_ID_EPSILONTBL0   31
++#define NPHY_TBL_ID_SCALARTBL0    32
++#define NPHY_TBL_ID_EPSILONTBL1   33
++#define NPHY_TBL_ID_SCALARTBL1    34
++
++#define	NPHY_TO_BPHY_OFF	0xc00
++
++#define NPHY_BandControl_currentBand			0x0001
++#define RFCC_CHIP0_PU			0x0400
++#define RFCC_POR_FORCE			0x0040
++#define RFCC_OE_POR_FORCE		0x0080
++#define NPHY_RfctrlIntc_override_OFF			0
++#define NPHY_RfctrlIntc_override_TRSW			1
++#define NPHY_RfctrlIntc_override_PA				2
++#define NPHY_RfctrlIntc_override_EXT_LNA_PU		3
++#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN	4
++#define RIFS_ENABLE			0x80
++#define BPHY_BAND_SEL_UP20		0x10
++#define NPHY_MLenable			0x02
++
++#define NPHY_RfseqMode_CoreActv_override 0x0001
++#define NPHY_RfseqMode_Trigger_override	0x0002
++#define NPHY_RfseqCoreActv_TxRxChain0	(0x11)
++#define NPHY_RfseqCoreActv_TxRxChain1	(0x22)
++
++#define NPHY_RfseqTrigger_rx2tx		0x0001
++#define NPHY_RfseqTrigger_tx2rx		0x0002
++#define NPHY_RfseqTrigger_updategainh	0x0004
++#define NPHY_RfseqTrigger_updategainl	0x0008
++#define NPHY_RfseqTrigger_updategainu	0x0010
++#define NPHY_RfseqTrigger_reset2rx	0x0020
++#define NPHY_RfseqStatus_rx2tx		0x0001
++#define NPHY_RfseqStatus_tx2rx		0x0002
++#define NPHY_RfseqStatus_updategainh	0x0004
++#define NPHY_RfseqStatus_updategainl	0x0008
++#define NPHY_RfseqStatus_updategainu	0x0010
++#define NPHY_RfseqStatus_reset2rx	0x0020
++#define NPHY_ClassifierCtrl_cck_en	0x1
++#define NPHY_ClassifierCtrl_ofdm_en	0x2
++#define NPHY_ClassifierCtrl_waited_en	0x4
++#define NPHY_IQFlip_ADC1		0x0001
++#define NPHY_IQFlip_ADC2		0x0010
++#define NPHY_sampleCmd_STOP		0x0002
++
++#define RX_GF_OR_MM			0x0004
++#define RX_GF_MM_AUTO			0x0100
++
++#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN	0x8000
++
++#define NPHY_IqestCmd_iqstart		0x1
++#define NPHY_IqestCmd_iqMode		0x2
++
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init		0x40
++#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7	0x19
++
++#define PRIM_SEL_UP20		0x8000
++
++#define NPHY_RFSEQ_RX2TX		0x0
++#define NPHY_RFSEQ_TX2RX		0x1
++#define NPHY_RFSEQ_RESET2RX		0x2
++#define NPHY_RFSEQ_UPDATEGAINH		0x3
++#define NPHY_RFSEQ_UPDATEGAINL		0x4
++#define NPHY_RFSEQ_UPDATEGAINU		0x5
++
++#define NPHY_RFSEQ_CMD_NOP		0x0
++#define NPHY_RFSEQ_CMD_RXG_FBW		0x1
++#define NPHY_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_RFSEQ_CMD_EXT_PA		0x3
++#define NPHY_RFSEQ_CMD_RXPD_TXPD	0x4
++#define NPHY_RFSEQ_CMD_TX_GAIN		0x5
++#define NPHY_RFSEQ_CMD_RX_GAIN		0x6
++#define NPHY_RFSEQ_CMD_SET_HPF_BW	0x7
++#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_RFSEQ_CMD_END		0xf
++
++#define NPHY_REV3_RFSEQ_CMD_NOP		0x0
++#define NPHY_REV3_RFSEQ_CMD_RXG_FBW	0x1
++#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH	0x2
++#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU	0x3
++#define NPHY_REV3_RFSEQ_CMD_EXT_PA	0x4
++#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD	0x5
++#define NPHY_REV3_RFSEQ_CMD_TX_GAIN	0x6
++#define NPHY_REV3_RFSEQ_CMD_RX_GAIN	0x7
++#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS	0x8
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC	0x9
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC	0xa
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC	0xb
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC	0xc
++#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC	0xd
++#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC	0xe
++#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS	0xf
++#define NPHY_REV3_RFSEQ_CMD_END		0x1f
++
++#define NPHY_RSSI_SEL_W1		0x0
++#define NPHY_RSSI_SEL_W2		0x1
++#define NPHY_RSSI_SEL_NB		0x2
++#define NPHY_RSSI_SEL_IQ		0x3
++#define NPHY_RSSI_SEL_TSSI_2G		0x4
++#define NPHY_RSSI_SEL_TSSI_5G		0x5
++#define NPHY_RSSI_SEL_TBD		0x6
++
++#define NPHY_RAIL_I			0x0
++#define NPHY_RAIL_Q			0x1
++
++#define NPHY_FORCESIG_DECODEGATEDCLKS	0x8
++
++#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
++#define NPHY_REV7_RfctrlOverride_cmd_rx_pu   0x1
++#define NPHY_REV7_RfctrlOverride_cmd_tx_pu   0x2
++#define NPHY_REV7_RfctrlOverride_cmd_rxgain  0x3
++#define NPHY_REV7_RfctrlOverride_cmd_txgain  0x4
++
++#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
++#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK  0x0ff00
++#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
++
++#define NPHY_REV7_TXGAINCODE_TGAIN_MASK     0x7fff
++#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK   0x8000
++#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
++
++#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
++#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
++#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
++
++#define NPHY_IqestIqAccLo(core)  ((core == 0) ? 0x12c : 0x134)
++
++#define NPHY_IqestIqAccHi(core)  ((core == 0) ? 0x12d : 0x135)
++
++#define NPHY_IqestipwrAccLo(core)  ((core == 0) ? 0x12e : 0x136)
++
++#define NPHY_IqestipwrAccHi(core)  ((core == 0) ? 0x12f : 0x137)
++
++#define NPHY_IqestqpwrAccLo(core)  ((core == 0) ? 0x130 : 0x138)
++
++#define NPHY_IqestqpwrAccHi(core)  ((core == 0) ? 0x131 : 0x139)
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+new file mode 100644
+index 0000000..622c01c
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+@@ -0,0 +1,3250 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_lcn.h"
++
++static const u32 dot11lcn_gain_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00001193,
++	0x00005193,
++	0x00009193,
++	0x0000d193,
++	0x00011193,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000004,
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x000000cd,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x000000d3,
++	0x00000113,
++	0x00000513,
++	0x00000913,
++	0x00000953,
++	0x00000d53,
++	0x00001153,
++	0x00005153,
++	0x00009153,
++	0x0000d153,
++	0x00011153,
++	0x00015153,
++	0x00019153,
++	0x0001d153,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 dot11lcn_gain_tbl_rev1[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00001197,
++	0x00005197,
++	0x00009197,
++	0x0000d197,
++	0x00011197,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000D,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x00000011,
++	0x00000051,
++	0x00000091,
++	0x000000d1,
++	0x00000053,
++	0x00000093,
++	0x000000d3,
++	0x000000d7,
++	0x00000117,
++	0x00000517,
++	0x00000917,
++	0x00000957,
++	0x00000d57,
++	0x00001157,
++	0x00005157,
++	0x00009157,
++	0x0000d157,
++	0x00011157,
++	0x00015157,
++	0x00019157,
++	0x0001d157,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0405,
++	0x0406,
++	0x0407,
++	0x0408,
++	0x0409,
++	0x040a,
++	0x058b,
++	0x058c,
++	0x058d,
++	0x058e,
++	0x058f,
++	0x0090,
++	0x0091,
++	0x0092,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x019e,
++	0x019f,
++	0x01a0,
++	0x01a1,
++	0x01a2,
++	0x01a3,
++	0x01a4,
++	0x01a5,
++	0x0000,
++};
++
++static const u32 dot11lcn_gain_idx_tbl_rev0[] = {
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x50000000,
++	0x00000000,
++	0x60000000,
++	0x00000000,
++	0x70000000,
++	0x00000000,
++	0x80000000,
++	0x00000000,
++	0x90000000,
++	0x00000008,
++	0xa0000000,
++	0x00000008,
++	0xb0000000,
++	0x00000008,
++	0xc0000000,
++	0x00000008,
++	0xd0000000,
++	0x00000008,
++	0xe0000000,
++	0x00000008,
++	0xf0000000,
++	0x00000008,
++	0x00000000,
++	0x00000009,
++	0x10000000,
++	0x00000009,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0xe0000000,
++	0x00000019,
++	0xf0000000,
++	0x00000019,
++	0x00000000,
++	0x0000001a,
++	0x10000000,
++	0x0000001a,
++	0x20000000,
++	0x0000001a,
++	0x30000000,
++	0x0000001a,
++	0x40000000,
++	0x0000001a,
++	0x50000000,
++	0x00000002,
++	0x60000000,
++	0x00000002,
++	0x70000000,
++	0x00000002,
++	0x80000000,
++	0x00000002,
++	0x90000000,
++	0x00000002,
++	0xa0000000,
++	0x00000002,
++	0xb0000000,
++	0x00000002,
++	0xc0000000,
++	0x0000000a,
++	0xd0000000,
++	0x0000000a,
++	0xe0000000,
++	0x0000000a,
++	0xf0000000,
++	0x0000000a,
++	0x00000000,
++	0x0000000b,
++	0x10000000,
++	0x0000000b,
++	0x20000000,
++	0x0000000b,
++	0x30000000,
++	0x0000000b,
++	0x40000000,
++	0x0000000b,
++	0x50000000,
++	0x0000001b,
++	0x60000000,
++	0x0000001b,
++	0x70000000,
++	0x0000001b,
++	0x80000000,
++	0x0000001b,
++	0x90000000,
++	0x0000001b,
++	0xa0000000,
++	0x0000001b,
++	0xb0000000,
++	0x0000001b,
++	0xc0000000,
++	0x0000001b,
++	0xd0000000,
++	0x0000001b,
++	0xe0000000,
++	0x0000001b,
++	0xf0000000,
++	0x0000001b,
++	0x00000000,
++	0x0000001c,
++	0x10000000,
++	0x0000001c,
++	0x20000000,
++	0x0000001c,
++	0x30000000,
++	0x0000001c,
++	0x40000000,
++	0x0000001c,
++	0x50000000,
++	0x0000001c,
++	0x60000000,
++	0x0000001c,
++	0x70000000,
++	0x0000001c,
++	0x80000000,
++	0x0000001c,
++	0x90000000,
++	0x0000001c,
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0080,
++	0x0081,
++	0x0100,
++	0x0101,
++	0x0180,
++	0x0181,
++	0x0182,
++	0x0183,
++	0x0184,
++	0x0185,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0285,
++	0x0289,
++	0x028a,
++	0x028b,
++	0x028c,
++	0x028d,
++	0x028e,
++	0x028f,
++	0x0290,
++	0x0291,
++	0x0292,
++	0x0293,
++	0x0294,
++	0x0295,
++	0x0296,
++	0x0297,
++	0x0298,
++	0x0299,
++	0x029a,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_2G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x00000000,
++	0x00000008,
++	0x10000000,
++	0x00000008,
++	0x00000000,
++	0x00000010,
++	0x10000000,
++	0x00000010,
++	0x00000000,
++	0x00000018,
++	0x10000000,
++	0x00000018,
++	0x20000000,
++	0x00000018,
++	0x30000000,
++	0x00000018,
++	0x40000000,
++	0x00000018,
++	0x50000000,
++	0x00000018,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x50000000,
++	0x00000028,
++	0x90000000,
++	0x00000028,
++	0xa0000000,
++	0x00000028,
++	0xb0000000,
++	0x00000028,
++	0xc0000000,
++	0x00000028,
++	0xd0000000,
++	0x00000028,
++	0xe0000000,
++	0x00000028,
++	0xf0000000,
++	0x00000028,
++	0x00000000,
++	0x00000029,
++	0x10000000,
++	0x00000029,
++	0x20000000,
++	0x00000029,
++	0x30000000,
++	0x00000029,
++	0x40000000,
++	0x00000029,
++	0x50000000,
++	0x00000029,
++	0x60000000,
++	0x00000029,
++	0x70000000,
++	0x00000029,
++	0x80000000,
++	0x00000029,
++	0x90000000,
++	0x00000029,
++	0xa0000000,
++	0x00000029,
++	0xb0000000,
++	0x00000029,
++	0xc0000000,
++	0x00000029,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x0000004d,
++	0x0000008d,
++	0x00000049,
++	0x00000089,
++	0x000000c9,
++	0x0000004b,
++	0x0000008b,
++	0x000000cb,
++	0x000000cf,
++	0x0000010f,
++	0x0000050f,
++	0x0000090f,
++	0x0000094f,
++	0x00000d4f,
++	0x0000114f,
++	0x0000118f,
++	0x0000518f,
++	0x0000918f,
++	0x0000d18f,
++	0x0001118f,
++	0x0001518f,
++	0x0001918f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000004,
++	0x00000008,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000003,
++	0x00000007,
++	0x0000000b,
++	0x0000000f,
++	0x0000004f,
++	0x0000008f,
++	0x000000cf,
++	0x0000010f,
++	0x0000014f,
++	0x0000018f,
++	0x0000058f,
++	0x0000098f,
++	0x00000d8f,
++	0x00008000,
++	0x00008004,
++	0x00008008,
++	0x00008001,
++	0x00008005,
++	0x00008009,
++	0x0000800d,
++	0x00008003,
++	0x00008007,
++	0x0000800b,
++	0x0000800f,
++	0x0000804f,
++	0x0000808f,
++	0x000080cf,
++	0x0000810f,
++	0x0000814f,
++	0x0000818f,
++	0x0000858f,
++	0x0000898f,
++	0x00008d8f,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0400,
++	0x0401,
++	0x0402,
++	0x0403,
++	0x0404,
++	0x0483,
++	0x0484,
++	0x0485,
++	0x0486,
++	0x0583,
++	0x0584,
++	0x0585,
++	0x0587,
++	0x0588,
++	0x0589,
++	0x058a,
++	0x0687,
++	0x0688,
++	0x0689,
++	0x068a,
++	0x068b,
++	0x068c,
++	0x068d,
++	0x068e,
++	0x068f,
++	0x0690,
++	0x0691,
++	0x0692,
++	0x0693,
++	0x0000
++};
++
++static const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x02,
++	0x08,
++	0x0e,
++	0x13,
++	0x1b,
++	0xfc,
++	0x00,
++	0x0f,
++	0x03,
++	0xeb,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x00000000,
++	0x00000040,
++	0x10000000,
++	0x00000040,
++	0x20000000,
++	0x00000040,
++	0x30000000,
++	0x00000040,
++	0x40000000,
++	0x00000040,
++	0x30000000,
++	0x00000048,
++	0x40000000,
++	0x00000048,
++	0x50000000,
++	0x00000048,
++	0x60000000,
++	0x00000048,
++	0x30000000,
++	0x00000058,
++	0x40000000,
++	0x00000058,
++	0x50000000,
++	0x00000058,
++	0x70000000,
++	0x00000058,
++	0x80000000,
++	0x00000058,
++	0x90000000,
++	0x00000058,
++	0xa0000000,
++	0x00000058,
++	0x70000000,
++	0x00000068,
++	0x80000000,
++	0x00000068,
++	0x90000000,
++	0x00000068,
++	0xa0000000,
++	0x00000068,
++	0xb0000000,
++	0x00000068,
++	0xc0000000,
++	0x00000068,
++	0xd0000000,
++	0x00000068,
++	0xe0000000,
++	0x00000068,
++	0xf0000000,
++	0x00000068,
++	0x00000000,
++	0x00000069,
++	0x10000000,
++	0x00000069,
++	0x20000000,
++	0x00000069,
++	0x30000000,
++	0x00000069,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x40000000,
++	0x00000041,
++	0x50000000,
++	0x00000041,
++	0x60000000,
++	0x00000041,
++	0x70000000,
++	0x00000041,
++	0x80000000,
++	0x00000041,
++	0x70000000,
++	0x00000049,
++	0x80000000,
++	0x00000049,
++	0x90000000,
++	0x00000049,
++	0xa0000000,
++	0x00000049,
++	0x70000000,
++	0x00000059,
++	0x80000000,
++	0x00000059,
++	0x90000000,
++	0x00000059,
++	0xb0000000,
++	0x00000059,
++	0xc0000000,
++	0x00000059,
++	0xd0000000,
++	0x00000059,
++	0xe0000000,
++	0x00000059,
++	0xb0000000,
++	0x00000069,
++	0xc0000000,
++	0x00000069,
++	0xd0000000,
++	0x00000069,
++	0xe0000000,
++	0x00000069,
++	0xf0000000,
++	0x00000069,
++	0x00000000,
++	0x0000006a,
++	0x10000000,
++	0x0000006a,
++	0x20000000,
++	0x0000006a,
++	0x30000000,
++	0x0000006a,
++	0x40000000,
++	0x0000006a,
++	0x50000000,
++	0x0000006a,
++	0x60000000,
++	0x0000006a,
++	0x70000000,
++	0x0000006a,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0001,
++	0x0002,
++	0x0003,
++	0x0004,
++	0x0083,
++	0x0084,
++	0x0085,
++	0x0086,
++	0x0087,
++	0x0186,
++	0x0187,
++	0x0188,
++	0x0189,
++	0x018a,
++	0x018b,
++	0x018c,
++	0x018d,
++	0x018e,
++	0x018f,
++	0x0190,
++	0x0191,
++	0x0192,
++	0x0193,
++	0x0194,
++	0x0195,
++	0x0196,
++	0x0197,
++	0x0198,
++	0x0199,
++	0x019a,
++	0x019b,
++	0x019c,
++	0x019d,
++	0x0000
++};
++
++static const u32 dot11lcn_gain_val_tbl_5G[] = {
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf7,
++	0xfd,
++	0x00,
++	0x04,
++	0x04,
++	0x04,
++	0xf6,
++	0x00,
++	0x0c,
++	0x03,
++	0xeb,
++	0xfe,
++	0x06,
++	0x0a,
++	0x10,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00
++};
++
++static const u32 dot11lcn_gain_idx_tbl_5G[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x10000000,
++	0x00000000,
++	0x20000000,
++	0x00000000,
++	0x30000000,
++	0x00000000,
++	0x40000000,
++	0x00000000,
++	0x30000000,
++	0x00000008,
++	0x40000000,
++	0x00000008,
++	0x50000000,
++	0x00000008,
++	0x60000000,
++	0x00000008,
++	0x70000000,
++	0x00000008,
++	0x60000000,
++	0x00000018,
++	0x70000000,
++	0x00000018,
++	0x80000000,
++	0x00000018,
++	0x90000000,
++	0x00000018,
++	0xa0000000,
++	0x00000018,
++	0xb0000000,
++	0x00000018,
++	0xc0000000,
++	0x00000018,
++	0xd0000000,
++	0x00000018,
++	0xe0000000,
++	0x00000018,
++	0xf0000000,
++	0x00000018,
++	0x00000000,
++	0x00000019,
++	0x10000000,
++	0x00000019,
++	0x20000000,
++	0x00000019,
++	0x30000000,
++	0x00000019,
++	0x40000000,
++	0x00000019,
++	0x50000000,
++	0x00000019,
++	0x60000000,
++	0x00000019,
++	0x70000000,
++	0x00000019,
++	0x80000000,
++	0x00000019,
++	0x90000000,
++	0x00000019,
++	0xa0000000,
++	0x00000019,
++	0xb0000000,
++	0x00000019,
++	0xc0000000,
++	0x00000019,
++	0xd0000000,
++	0x00000019,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++static const u32 dot11lcn_gain_tbl_5G[] = {
++	0x00000000,
++	0x00000040,
++	0x00000080,
++	0x00000001,
++	0x00000005,
++	0x00000009,
++	0x0000000d,
++	0x00000011,
++	0x00000015,
++	0x00000055,
++	0x00000095,
++	0x00000017,
++	0x0000001b,
++	0x0000005b,
++	0x0000009b,
++	0x000000db,
++	0x0000011b,
++	0x0000015b,
++	0x0000019b,
++	0x0000059b,
++	0x0000099b,
++	0x00000d9b,
++	0x0000119b,
++	0x0000519b,
++	0x0000919b,
++	0x0000d19b,
++	0x0001119b,
++	0x0001519b,
++	0x0001919b,
++	0x0001d19b,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = {
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++static const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = {
++	{&dot11lcn_gain_tbl_rev1,
++	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_2G,
++	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_2G,
++	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
++	{&dot11lcn_gain_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_extlna_2G,
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
++	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
++};
++
++const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
++	{&dot11lcn_gain_tbl_5G,
++	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
++	 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
++	,
++	{&dot11lcn_gain_idx_tbl_5G,
++	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
++	 13, 0, 32}
++	,
++	{&dot11lcn_gain_val_tbl_5G,
++	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
++	 17, 0, 8}
++};
++
++const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
++	sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
++
++const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
++	sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
++
++static const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++	0x014d,
++};
++
++static const u16 dot11lcn_noise_scale_tbl_rev0[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
++	0x000141f8,
++	0x000021f8,
++	0x000021fb,
++	0x000041fb,
++	0x0001fe4b,
++	0x0000217b,
++	0x00002133,
++	0x000040eb,
++	0x0001fea3,
++	0x0000024b,
++};
++
++static const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
++	0x00100001,
++	0x00200010,
++	0x00300001,
++	0x00400010,
++	0x00500022,
++	0x00600122,
++	0x00700222,
++	0x00800322,
++	0x00900422,
++	0x00a00522,
++	0x00b00622,
++	0x00c00722,
++	0x00d00822,
++	0x00f00922,
++	0x00100a22,
++	0x00200b22,
++	0x00300c22,
++	0x00400d22,
++	0x00500e22,
++	0x00600f22,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x0007,
++	0x0005,
++	0x0006,
++	0x0004,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++	0x000b,
++	0x000b,
++	0x000a,
++	0x000a,
++
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0005,
++	0x0002,
++	0x0000,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++	0x0007,
++	0x0007,
++	0x0002,
++	0x0002,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++	0x0002,
++	0x0008,
++	0x0004,
++	0x0001,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++	0x000a,
++	0x0009,
++	0x0006,
++	0x0005,
++};
++
++static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++	0x0004,
++	0x0004,
++	0x0002,
++	0x0002,
++};
++
++static const u8 dot11lcn_nf_table_rev0[] = {
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++	0x5f,
++	0x36,
++	0x29,
++	0x1f,
++};
++
++static const u8 dot11lcn_gain_val_tbl_rev0[] = {
++	0x09,
++	0x0f,
++	0x14,
++	0x18,
++	0xfe,
++	0x07,
++	0x0b,
++	0x0f,
++	0xfb,
++	0xfe,
++	0x01,
++	0x05,
++	0x08,
++	0x0b,
++	0x0e,
++	0x11,
++	0x14,
++	0x17,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0x06,
++	0x09,
++	0x0c,
++	0x0f,
++	0x12,
++	0x15,
++	0x18,
++	0x1b,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x03,
++	0xeb,
++	0x00,
++	0x00,
++};
++
++static const u8 dot11lcn_spur_tbl_rev0[] = {
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x02,
++	0x03,
++	0x01,
++	0x03,
++	0x02,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++	0x01,
++};
++
++static const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
++	0x001a,
++	0x0034,
++	0x004e,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x00ea,
++	0x0104,
++	0x0034,
++	0x0068,
++	0x009c,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x004e,
++	0x009c,
++	0x00ea,
++	0x0138,
++	0x01d4,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x0068,
++	0x00d0,
++	0x0138,
++	0x01a0,
++	0x0270,
++	0x0340,
++	0x03a8,
++	0x0410,
++	0x0018,
++	0x009c,
++	0x00d0,
++	0x0104,
++	0x00ea,
++	0x0138,
++	0x0186,
++	0x00d0,
++	0x0104,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x016c,
++	0x01a0,
++	0x0138,
++	0x0186,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x0222,
++	0x0270,
++	0x0104,
++	0x0138,
++	0x016c,
++	0x0138,
++	0x016c,
++	0x01a0,
++	0x01d4,
++	0x01a0,
++	0x01d4,
++	0x0208,
++	0x0208,
++	0x023c,
++	0x0186,
++	0x01d4,
++	0x0222,
++	0x01d4,
++	0x0222,
++	0x0270,
++	0x02be,
++	0x0270,
++	0x02be,
++	0x030c,
++	0x030c,
++	0x035a,
++	0x0036,
++	0x006c,
++	0x00a2,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x01e6,
++	0x021c,
++	0x006c,
++	0x00d8,
++	0x0144,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x00a2,
++	0x0144,
++	0x01e6,
++	0x0288,
++	0x03cc,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x00d8,
++	0x01b0,
++	0x0288,
++	0x0360,
++	0x0510,
++	0x06c0,
++	0x0798,
++	0x0870,
++	0x0018,
++	0x0144,
++	0x01b0,
++	0x021c,
++	0x01e6,
++	0x0288,
++	0x032a,
++	0x01b0,
++	0x021c,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x02f4,
++	0x0360,
++	0x0288,
++	0x032a,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x046e,
++	0x0510,
++	0x021c,
++	0x0288,
++	0x02f4,
++	0x0288,
++	0x02f4,
++	0x0360,
++	0x03cc,
++	0x0360,
++	0x03cc,
++	0x0438,
++	0x0438,
++	0x04a4,
++	0x032a,
++	0x03cc,
++	0x046e,
++	0x03cc,
++	0x046e,
++	0x0510,
++	0x05b2,
++	0x0510,
++	0x05b2,
++	0x0654,
++	0x0654,
++	0x06f6,
++};
++
++static const u16 dot11lcn_iq_local_tbl_rev0[] = {
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0200,
++	0x0300,
++	0x0400,
++	0x0600,
++	0x0800,
++	0x0b00,
++	0x1000,
++	0x1001,
++	0x1002,
++	0x1003,
++	0x1004,
++	0x1005,
++	0x1006,
++	0x1007,
++	0x1707,
++	0x2007,
++	0x2d07,
++	0x4007,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x4000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++	0x00080000,
++};
++
++const struct phytbl_info dot11lcnphytbl_info_rev0[] = {
++	{&dot11lcn_min_sig_sq_tbl_rev0,
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
++	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
++	,
++	{&dot11lcn_noise_scale_tbl_rev0,
++	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
++	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
++	,
++	{&dot11lcn_fltr_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
++	,
++	{&dot11lcn_ps_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
++	,
++	{&dot11lcn_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
++	,
++	{&dot11lcn_aux_gain_idx_tbl_rev0,
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
++	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
++	,
++	{&dot11lcn_sw_ctrl_tbl_rev0,
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
++	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
++	,
++	{&dot11lcn_nf_table_rev0,
++	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
++	 0, 8}
++	,
++	{&dot11lcn_gain_val_tbl_rev0,
++	 sizeof(dot11lcn_gain_val_tbl_rev0) /
++	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
++	,
++	{&dot11lcn_gain_tbl_rev0,
++	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
++	 0, 32}
++	,
++	{&dot11lcn_spur_tbl_rev0,
++	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
++	 0, 8}
++	,
++	{&dot11lcn_unsup_mcs_tbl_rev0,
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
++	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
++	,
++	{&dot11lcn_iq_local_tbl_rev0,
++	 sizeof(dot11lcn_iq_local_tbl_rev0) /
++	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
++	,
++	{&dot11lcn_papd_compdelta_tbl_rev0,
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
++	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
++	,
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = {
++	&dot11lcn_sw_ctrl_tbl_4313_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
++	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
++};
++
++const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
++	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
++	sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
++};
++
++const u32 dot11lcnphytbl_info_sz_rev0 =
++	sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
++
++const struct lcnphy_tx_gain_tbl_entry
++dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
++	{3, 0, 31, 0, 72},
++	{3, 0, 31, 0, 70},
++	{3, 0, 31, 0, 68},
++	{3, 0, 30, 0, 67},
++	{3, 0, 29, 0, 68},
++	{3, 0, 28, 0, 68},
++	{3, 0, 27, 0, 69},
++	{3, 0, 26, 0, 70},
++	{3, 0, 25, 0, 70},
++	{3, 0, 24, 0, 71},
++	{3, 0, 23, 0, 72},
++	{3, 0, 23, 0, 70},
++	{3, 0, 22, 0, 71},
++	{3, 0, 21, 0, 72},
++	{3, 0, 21, 0, 70},
++	{3, 0, 21, 0, 68},
++	{3, 0, 21, 0, 66},
++	{3, 0, 21, 0, 64},
++	{3, 0, 21, 0, 63},
++	{3, 0, 20, 0, 64},
++	{3, 0, 19, 0, 65},
++	{3, 0, 19, 0, 64},
++	{3, 0, 18, 0, 65},
++	{3, 0, 18, 0, 64},
++	{3, 0, 17, 0, 65},
++	{3, 0, 17, 0, 64},
++	{3, 0, 16, 0, 65},
++	{3, 0, 16, 0, 64},
++	{3, 0, 16, 0, 62},
++	{3, 0, 16, 0, 60},
++	{3, 0, 16, 0, 58},
++	{3, 0, 15, 0, 61},
++	{3, 0, 15, 0, 59},
++	{3, 0, 14, 0, 61},
++	{3, 0, 14, 0, 60},
++	{3, 0, 14, 0, 58},
++	{3, 0, 13, 0, 60},
++	{3, 0, 13, 0, 59},
++	{3, 0, 12, 0, 62},
++	{3, 0, 12, 0, 60},
++	{3, 0, 12, 0, 58},
++	{3, 0, 11, 0, 62},
++	{3, 0, 11, 0, 60},
++	{3, 0, 11, 0, 59},
++	{3, 0, 11, 0, 57},
++	{3, 0, 10, 0, 61},
++	{3, 0, 10, 0, 59},
++	{3, 0, 10, 0, 57},
++	{3, 0, 9, 0, 62},
++	{3, 0, 9, 0, 60},
++	{3, 0, 9, 0, 58},
++	{3, 0, 9, 0, 57},
++	{3, 0, 8, 0, 62},
++	{3, 0, 8, 0, 60},
++	{3, 0, 8, 0, 58},
++	{3, 0, 8, 0, 57},
++	{3, 0, 8, 0, 55},
++	{3, 0, 7, 0, 61},
++	{3, 0, 7, 0, 60},
++	{3, 0, 7, 0, 58},
++	{3, 0, 7, 0, 56},
++	{3, 0, 7, 0, 55},
++	{3, 0, 6, 0, 62},
++	{3, 0, 6, 0, 60},
++	{3, 0, 6, 0, 58},
++	{3, 0, 6, 0, 57},
++	{3, 0, 6, 0, 55},
++	{3, 0, 6, 0, 54},
++	{3, 0, 6, 0, 52},
++	{3, 0, 5, 0, 61},
++	{3, 0, 5, 0, 59},
++	{3, 0, 5, 0, 57},
++	{3, 0, 5, 0, 56},
++	{3, 0, 5, 0, 54},
++	{3, 0, 5, 0, 53},
++	{3, 0, 5, 0, 51},
++	{3, 0, 4, 0, 62},
++	{3, 0, 4, 0, 60},
++	{3, 0, 4, 0, 58},
++	{3, 0, 4, 0, 57},
++	{3, 0, 4, 0, 55},
++	{3, 0, 4, 0, 54},
++	{3, 0, 4, 0, 52},
++	{3, 0, 4, 0, 51},
++	{3, 0, 4, 0, 49},
++	{3, 0, 4, 0, 48},
++	{3, 0, 4, 0, 46},
++	{3, 0, 3, 0, 60},
++	{3, 0, 3, 0, 58},
++	{3, 0, 3, 0, 57},
++	{3, 0, 3, 0, 55},
++	{3, 0, 3, 0, 54},
++	{3, 0, 3, 0, 52},
++	{3, 0, 3, 0, 51},
++	{3, 0, 3, 0, 49},
++	{3, 0, 3, 0, 48},
++	{3, 0, 3, 0, 46},
++	{3, 0, 3, 0, 45},
++	{3, 0, 3, 0, 44},
++	{3, 0, 3, 0, 43},
++	{3, 0, 3, 0, 41},
++	{3, 0, 2, 0, 61},
++	{3, 0, 2, 0, 59},
++	{3, 0, 2, 0, 57},
++	{3, 0, 2, 0, 56},
++	{3, 0, 2, 0, 54},
++	{3, 0, 2, 0, 53},
++	{3, 0, 2, 0, 51},
++	{3, 0, 2, 0, 50},
++	{3, 0, 2, 0, 48},
++	{3, 0, 2, 0, 47},
++	{3, 0, 2, 0, 46},
++	{3, 0, 2, 0, 44},
++	{3, 0, 2, 0, 43},
++	{3, 0, 2, 0, 42},
++	{3, 0, 2, 0, 41},
++	{3, 0, 2, 0, 39},
++	{3, 0, 2, 0, 38},
++	{3, 0, 2, 0, 37},
++	{3, 0, 2, 0, 36},
++	{3, 0, 2, 0, 35},
++	{3, 0, 2, 0, 34},
++	{3, 0, 2, 0, 33},
++	{3, 0, 2, 0, 32},
++	{3, 0, 1, 0, 63},
++	{3, 0, 1, 0, 61},
++	{3, 0, 1, 0, 59},
++	{3, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
++	{7, 0, 31, 0, 72},
++	{7, 0, 31, 0, 70},
++	{7, 0, 31, 0, 68},
++	{7, 0, 30, 0, 67},
++	{7, 0, 29, 0, 68},
++	{7, 0, 28, 0, 68},
++	{7, 0, 27, 0, 69},
++	{7, 0, 26, 0, 70},
++	{7, 0, 25, 0, 70},
++	{7, 0, 24, 0, 71},
++	{7, 0, 23, 0, 72},
++	{7, 0, 23, 0, 70},
++	{7, 0, 22, 0, 71},
++	{7, 0, 21, 0, 72},
++	{7, 0, 21, 0, 70},
++	{7, 0, 21, 0, 68},
++	{7, 0, 21, 0, 66},
++	{7, 0, 21, 0, 64},
++	{7, 0, 21, 0, 63},
++	{7, 0, 20, 0, 64},
++	{7, 0, 19, 0, 65},
++	{7, 0, 19, 0, 64},
++	{7, 0, 18, 0, 65},
++	{7, 0, 18, 0, 64},
++	{7, 0, 17, 0, 65},
++	{7, 0, 17, 0, 64},
++	{7, 0, 16, 0, 65},
++	{7, 0, 16, 0, 64},
++	{7, 0, 16, 0, 62},
++	{7, 0, 16, 0, 60},
++	{7, 0, 16, 0, 58},
++	{7, 0, 15, 0, 61},
++	{7, 0, 15, 0, 59},
++	{7, 0, 14, 0, 61},
++	{7, 0, 14, 0, 60},
++	{7, 0, 14, 0, 58},
++	{7, 0, 13, 0, 60},
++	{7, 0, 13, 0, 59},
++	{7, 0, 12, 0, 62},
++	{7, 0, 12, 0, 60},
++	{7, 0, 12, 0, 58},
++	{7, 0, 11, 0, 62},
++	{7, 0, 11, 0, 60},
++	{7, 0, 11, 0, 59},
++	{7, 0, 11, 0, 57},
++	{7, 0, 10, 0, 61},
++	{7, 0, 10, 0, 59},
++	{7, 0, 10, 0, 57},
++	{7, 0, 9, 0, 62},
++	{7, 0, 9, 0, 60},
++	{7, 0, 9, 0, 58},
++	{7, 0, 9, 0, 57},
++	{7, 0, 8, 0, 62},
++	{7, 0, 8, 0, 60},
++	{7, 0, 8, 0, 58},
++	{7, 0, 8, 0, 57},
++	{7, 0, 8, 0, 55},
++	{7, 0, 7, 0, 61},
++	{7, 0, 7, 0, 60},
++	{7, 0, 7, 0, 58},
++	{7, 0, 7, 0, 56},
++	{7, 0, 7, 0, 55},
++	{7, 0, 6, 0, 62},
++	{7, 0, 6, 0, 60},
++	{7, 0, 6, 0, 58},
++	{7, 0, 6, 0, 57},
++	{7, 0, 6, 0, 55},
++	{7, 0, 6, 0, 54},
++	{7, 0, 6, 0, 52},
++	{7, 0, 5, 0, 61},
++	{7, 0, 5, 0, 59},
++	{7, 0, 5, 0, 57},
++	{7, 0, 5, 0, 56},
++	{7, 0, 5, 0, 54},
++	{7, 0, 5, 0, 53},
++	{7, 0, 5, 0, 51},
++	{7, 0, 4, 0, 62},
++	{7, 0, 4, 0, 60},
++	{7, 0, 4, 0, 58},
++	{7, 0, 4, 0, 57},
++	{7, 0, 4, 0, 55},
++	{7, 0, 4, 0, 54},
++	{7, 0, 4, 0, 52},
++	{7, 0, 4, 0, 51},
++	{7, 0, 4, 0, 49},
++	{7, 0, 4, 0, 48},
++	{7, 0, 4, 0, 46},
++	{7, 0, 3, 0, 60},
++	{7, 0, 3, 0, 58},
++	{7, 0, 3, 0, 57},
++	{7, 0, 3, 0, 55},
++	{7, 0, 3, 0, 54},
++	{7, 0, 3, 0, 52},
++	{7, 0, 3, 0, 51},
++	{7, 0, 3, 0, 49},
++	{7, 0, 3, 0, 48},
++	{7, 0, 3, 0, 46},
++	{7, 0, 3, 0, 45},
++	{7, 0, 3, 0, 44},
++	{7, 0, 3, 0, 43},
++	{7, 0, 3, 0, 41},
++	{7, 0, 2, 0, 61},
++	{7, 0, 2, 0, 59},
++	{7, 0, 2, 0, 57},
++	{7, 0, 2, 0, 56},
++	{7, 0, 2, 0, 54},
++	{7, 0, 2, 0, 53},
++	{7, 0, 2, 0, 51},
++	{7, 0, 2, 0, 50},
++	{7, 0, 2, 0, 48},
++	{7, 0, 2, 0, 47},
++	{7, 0, 2, 0, 46},
++	{7, 0, 2, 0, 44},
++	{7, 0, 2, 0, 43},
++	{7, 0, 2, 0, 42},
++	{7, 0, 2, 0, 41},
++	{7, 0, 2, 0, 39},
++	{7, 0, 2, 0, 38},
++	{7, 0, 2, 0, 37},
++	{7, 0, 2, 0, 36},
++	{7, 0, 2, 0, 35},
++	{7, 0, 2, 0, 34},
++	{7, 0, 2, 0, 33},
++	{7, 0, 2, 0, 32},
++	{7, 0, 1, 0, 63},
++	{7, 0, 1, 0, 61},
++	{7, 0, 1, 0, 59},
++	{7, 0, 1, 0, 57},
++};
++
++const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
++	{255, 255, 0xf0, 0, 152},
++	{255, 255, 0xf0, 0, 147},
++	{255, 255, 0xf0, 0, 143},
++	{255, 255, 0xf0, 0, 139},
++	{255, 255, 0xf0, 0, 135},
++	{255, 255, 0xf0, 0, 131},
++	{255, 255, 0xf0, 0, 128},
++	{255, 255, 0xf0, 0, 124},
++	{255, 255, 0xf0, 0, 121},
++	{255, 255, 0xf0, 0, 117},
++	{255, 255, 0xf0, 0, 114},
++	{255, 255, 0xf0, 0, 111},
++	{255, 255, 0xf0, 0, 107},
++	{255, 255, 0xf0, 0, 104},
++	{255, 255, 0xf0, 0, 101},
++	{255, 255, 0xf0, 0, 99},
++	{255, 255, 0xf0, 0, 96},
++	{255, 255, 0xf0, 0, 93},
++	{255, 255, 0xf0, 0, 90},
++	{255, 255, 0xf0, 0, 88},
++	{255, 255, 0xf0, 0, 85},
++	{255, 255, 0xf0, 0, 83},
++	{255, 255, 0xf0, 0, 81},
++	{255, 255, 0xf0, 0, 78},
++	{255, 255, 0xf0, 0, 76},
++	{255, 255, 0xf0, 0, 74},
++	{255, 255, 0xf0, 0, 72},
++	{255, 255, 0xf0, 0, 70},
++	{255, 255, 0xf0, 0, 68},
++	{255, 255, 0xf0, 0, 66},
++	{255, 255, 0xf0, 0, 64},
++	{255, 248, 0xf0, 0, 64},
++	{255, 241, 0xf0, 0, 64},
++	{255, 251, 0xe0, 0, 64},
++	{255, 244, 0xe0, 0, 64},
++	{255, 254, 0xd0, 0, 64},
++	{255, 246, 0xd0, 0, 64},
++	{255, 239, 0xd0, 0, 64},
++	{255, 249, 0xc0, 0, 64},
++	{255, 242, 0xc0, 0, 64},
++	{255, 255, 0xb0, 0, 64},
++	{255, 248, 0xb0, 0, 64},
++	{255, 241, 0xb0, 0, 64},
++	{255, 254, 0xa0, 0, 64},
++	{255, 246, 0xa0, 0, 64},
++	{255, 239, 0xa0, 0, 64},
++	{255, 255, 0x90, 0, 64},
++	{255, 248, 0x90, 0, 64},
++	{255, 241, 0x90, 0, 64},
++	{255, 234, 0x90, 0, 64},
++	{255, 255, 0x80, 0, 64},
++	{255, 248, 0x80, 0, 64},
++	{255, 241, 0x80, 0, 64},
++	{255, 234, 0x80, 0, 64},
++	{255, 255, 0x70, 0, 64},
++	{255, 248, 0x70, 0, 64},
++	{255, 241, 0x70, 0, 64},
++	{255, 234, 0x70, 0, 64},
++	{255, 227, 0x70, 0, 64},
++	{255, 221, 0x70, 0, 64},
++	{255, 215, 0x70, 0, 64},
++	{255, 208, 0x70, 0, 64},
++	{255, 203, 0x70, 0, 64},
++	{255, 197, 0x70, 0, 64},
++	{255, 255, 0x60, 0, 64},
++	{255, 248, 0x60, 0, 64},
++	{255, 241, 0x60, 0, 64},
++	{255, 234, 0x60, 0, 64},
++	{255, 227, 0x60, 0, 64},
++	{255, 221, 0x60, 0, 64},
++	{255, 255, 0x50, 0, 64},
++	{255, 248, 0x50, 0, 64},
++	{255, 241, 0x50, 0, 64},
++	{255, 234, 0x50, 0, 64},
++	{255, 227, 0x50, 0, 64},
++	{255, 221, 0x50, 0, 64},
++	{255, 215, 0x50, 0, 64},
++	{255, 208, 0x50, 0, 64},
++	{255, 255, 0x40, 0, 64},
++	{255, 248, 0x40, 0, 64},
++	{255, 241, 0x40, 0, 64},
++	{255, 234, 0x40, 0, 64},
++	{255, 227, 0x40, 0, 64},
++	{255, 221, 0x40, 0, 64},
++	{255, 215, 0x40, 0, 64},
++	{255, 208, 0x40, 0, 64},
++	{255, 203, 0x40, 0, 64},
++	{255, 197, 0x40, 0, 64},
++	{255, 255, 0x30, 0, 64},
++	{255, 248, 0x30, 0, 64},
++	{255, 241, 0x30, 0, 64},
++	{255, 234, 0x30, 0, 64},
++	{255, 227, 0x30, 0, 64},
++	{255, 221, 0x30, 0, 64},
++	{255, 215, 0x30, 0, 64},
++	{255, 208, 0x30, 0, 64},
++	{255, 203, 0x30, 0, 64},
++	{255, 197, 0x30, 0, 64},
++	{255, 191, 0x30, 0, 64},
++	{255, 186, 0x30, 0, 64},
++	{255, 181, 0x30, 0, 64},
++	{255, 175, 0x30, 0, 64},
++	{255, 255, 0x20, 0, 64},
++	{255, 248, 0x20, 0, 64},
++	{255, 241, 0x20, 0, 64},
++	{255, 234, 0x20, 0, 64},
++	{255, 227, 0x20, 0, 64},
++	{255, 221, 0x20, 0, 64},
++	{255, 215, 0x20, 0, 64},
++	{255, 208, 0x20, 0, 64},
++	{255, 203, 0x20, 0, 64},
++	{255, 197, 0x20, 0, 64},
++	{255, 191, 0x20, 0, 64},
++	{255, 186, 0x20, 0, 64},
++	{255, 181, 0x20, 0, 64},
++	{255, 175, 0x20, 0, 64},
++	{255, 170, 0x20, 0, 64},
++	{255, 166, 0x20, 0, 64},
++	{255, 161, 0x20, 0, 64},
++	{255, 156, 0x20, 0, 64},
++	{255, 152, 0x20, 0, 64},
++	{255, 148, 0x20, 0, 64},
++	{255, 143, 0x20, 0, 64},
++	{255, 139, 0x20, 0, 64},
++	{255, 135, 0x20, 0, 64},
++	{255, 132, 0x20, 0, 64},
++	{255, 255, 0x10, 0, 64},
++	{255, 248, 0x10, 0, 64},
++};
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+new file mode 100644
+index 0000000..5f75e16
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
++extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
++extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
++
++extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
++extern const u32 dot11lcnphytbl_info_sz_rev0;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
++extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
++
++extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
++
++struct lcnphy_tx_gain_tbl_entry {
++	unsigned char gm;
++	unsigned char pga;
++	unsigned char pad;
++	unsigned char dac;
++	unsigned char bb_mult;
++};
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
++
++extern const struct
++lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
++
++extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+new file mode 100644
+index 0000000..dbf50ef
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
+@@ -0,0 +1,10630 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <types.h>
++#include "phytbl_n.h"
++
++static const u32 frame_struct_rev0[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u8 frame_lut_rev0[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u32 tmap_tbl_rev0[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdtrn_tbl_rev0[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++static const u32 intlv_tbl_rev0[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u16 pilot_tbl_rev0[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 pltlut_tbl_rev0[] = {
++	0x76540123,
++	0x62407351,
++	0x76543201,
++	0x76540213,
++	0x76540123,
++	0x76430521,
++};
++
++static const u32 tdi_tbl20_ant0_rev0[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev0[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev0[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev0[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 bdi_tbl_rev0[] = {
++	0x0070,
++	0x0126,
++	0x012c,
++	0x0246,
++	0x048d,
++	0x04d2,
++};
++
++static const u32 chanest_tbl_rev0[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 mcs_tbl_rev0[] = {
++	0x00,
++	0x08,
++	0x0a,
++	0x10,
++	0x12,
++	0x19,
++	0x1a,
++	0x1c,
++	0x40,
++	0x48,
++	0x4a,
++	0x50,
++	0x52,
++	0x59,
++	0x5a,
++	0x5c,
++	0x80,
++	0x88,
++	0x8a,
++	0x90,
++	0x92,
++	0x99,
++	0x9a,
++	0x9c,
++	0xc0,
++	0xc8,
++	0xca,
++	0xd0,
++	0xd2,
++	0xd9,
++	0xda,
++	0xdc,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x01,
++	0x02,
++	0x04,
++	0x08,
++	0x09,
++	0x0a,
++	0x0c,
++	0x10,
++	0x11,
++	0x12,
++	0x14,
++	0x18,
++	0x19,
++	0x1a,
++	0x1c,
++	0x20,
++	0x21,
++	0x22,
++	0x24,
++	0x40,
++	0x41,
++	0x42,
++	0x44,
++	0x48,
++	0x49,
++	0x4a,
++	0x4c,
++	0x50,
++	0x51,
++	0x52,
++	0x54,
++	0x58,
++	0x59,
++	0x5a,
++	0x5c,
++	0x60,
++	0x61,
++	0x62,
++	0x64,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 noise_var_tbl0_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 noise_var_tbl1_rev0[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u8 est_pwr_lut_core0_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 est_pwr_lut_core1_rev0[] = {
++	0x50,
++	0x4f,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3b,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x34,
++	0x33,
++	0x32,
++	0x31,
++	0x30,
++	0x2f,
++	0x2e,
++	0x2d,
++	0x2c,
++	0x2b,
++	0x2a,
++	0x29,
++	0x28,
++	0x27,
++	0x26,
++	0x25,
++	0x24,
++	0x23,
++	0x22,
++	0x21,
++	0x20,
++	0x1f,
++	0x1e,
++	0x1d,
++	0x1c,
++	0x1b,
++	0x1a,
++	0x19,
++	0x18,
++	0x17,
++	0x16,
++	0x15,
++	0x14,
++	0x13,
++	0x12,
++	0x11,
++};
++
++static const u8 adj_pwr_lut_core0_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev0[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 gainctrl_lut_core1_rev0[] = {
++	0x03cc2b44,
++	0x03cc2b42,
++	0x03cc2b40,
++	0x03cc2b3e,
++	0x03cc2b3d,
++	0x03cc2b3b,
++	0x03c82b44,
++	0x03c82b42,
++	0x03c82b40,
++	0x03c82b3e,
++	0x03c82b3d,
++	0x03c82b3b,
++	0x03c82b39,
++	0x03c82b38,
++	0x03c82b36,
++	0x03c82b34,
++	0x03c42b44,
++	0x03c42b42,
++	0x03c42b40,
++	0x03c42b3e,
++	0x03c42b3d,
++	0x03c42b3b,
++	0x03c42b39,
++	0x03c42b38,
++	0x03c42b36,
++	0x03c42b34,
++	0x03c42b33,
++	0x03c42b32,
++	0x03c42b30,
++	0x03c42b2f,
++	0x03c42b2d,
++	0x03c02b44,
++	0x03c02b42,
++	0x03c02b40,
++	0x03c02b3e,
++	0x03c02b3d,
++	0x03c02b3b,
++	0x03c02b39,
++	0x03c02b38,
++	0x03c02b36,
++	0x03c02b34,
++	0x03b02b44,
++	0x03b02b42,
++	0x03b02b40,
++	0x03b02b3e,
++	0x03b02b3d,
++	0x03b02b3b,
++	0x03b02b39,
++	0x03b02b38,
++	0x03b02b36,
++	0x03b02b34,
++	0x03b02b33,
++	0x03b02b32,
++	0x03b02b30,
++	0x03b02b2f,
++	0x03b02b2d,
++	0x03a02b44,
++	0x03a02b42,
++	0x03a02b40,
++	0x03a02b3e,
++	0x03a02b3d,
++	0x03a02b3b,
++	0x03a02b39,
++	0x03a02b38,
++	0x03a02b36,
++	0x03a02b34,
++	0x03902b44,
++	0x03902b42,
++	0x03902b40,
++	0x03902b3e,
++	0x03902b3d,
++	0x03902b3b,
++	0x03902b39,
++	0x03902b38,
++	0x03902b36,
++	0x03902b34,
++	0x03902b33,
++	0x03902b32,
++	0x03902b30,
++	0x03802b44,
++	0x03802b42,
++	0x03802b40,
++	0x03802b3e,
++	0x03802b3d,
++	0x03802b3b,
++	0x03802b39,
++	0x03802b38,
++	0x03802b36,
++	0x03802b34,
++	0x03802b33,
++	0x03802b32,
++	0x03802b30,
++	0x03802b2f,
++	0x03802b2d,
++	0x03802b2c,
++	0x03802b2b,
++	0x03802b2a,
++	0x03802b29,
++	0x03802b27,
++	0x03802b26,
++	0x03802b25,
++	0x03802b24,
++	0x03802b23,
++	0x03802b22,
++	0x03802b21,
++	0x03802b20,
++	0x03802b1f,
++	0x03802b1e,
++	0x03802b1e,
++	0x03802b1d,
++	0x03802b1c,
++	0x03802b1b,
++	0x03802b1a,
++	0x03802b1a,
++	0x03802b19,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x03802b18,
++	0x00002b00,
++};
++
++static const u32 iq_lut_core0_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u32 iq_lut_core1_rev0[] = {
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++	0x0000007f,
++};
++
++static const u16 loft_lut_core0_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++static const u16 loft_lut_core1_rev0[] = {
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++	0x0000,
++	0x0101,
++	0x0002,
++	0x0103,
++};
++
++const struct phytbl_info mimophytbl_info_rev0_volatile[] = {
++	{&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
++	 16}
++	,
++	{&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
++	 20, 0, 32}
++	,
++	{&gainctrl_lut_core0_rev0,
++	 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev0,
++	 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
++	 27, 192, 32}
++	,
++
++	{&est_pwr_lut_core0_rev0,
++	 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev0,
++	 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev0,
++	 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev0,
++	 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
++	 64, 8}
++	,
++	{&iq_lut_core0_rev0,
++	 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev0,
++	 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev0,
++	 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev0,
++	 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev0[] = {
++	{&frame_struct_rev0,
++	 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
++	,
++	{&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
++	 24, 0, 8}
++	,
++	{&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
++	 0, 32}
++	,
++	{&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
++	 14, 0, 32}
++	,
++	{&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
++	 13, 0, 32}
++	,
++	{&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
++	 11, 0, 16}
++	,
++	{&tdi_tbl20_ant0_rev0,
++	 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev0,
++	 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev0,
++	 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev0,
++	 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
++	 32}
++	,
++	{&chanest_tbl_rev0,
++	 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
++	,
++	{&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0,
++	 8}
++	,
++	{&noise_var_tbl0_rev0,
++	 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
++	 32}
++	,
++	{&noise_var_tbl1_rev0,
++	 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
++	 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev0 =
++	sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
++const u32 mimophytbl_info_sz_rev0_volatile =
++	sizeof(mimophytbl_info_rev0_volatile) /
++	sizeof(mimophytbl_info_rev0_volatile[0]);
++
++static const u16 ant_swctrl_tbl_rev3[] = {
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0082,
++	0x0082,
++	0x0211,
++	0x0222,
++	0x0328,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0144,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0188,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_1[] = {
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0022,
++	0x0011,
++	0x0022,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0011,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0022,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_2[] = {
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0088,
++	0x0044,
++	0x0088,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0044,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0088,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 ant_swctrl_tbl_rev3_3[] = {
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc,
++	0x022,
++	0x022,
++	0x011,
++	0x022,
++	0x000,
++	0x000,
++	0x000,
++	0x000,
++	0x011,
++	0x000,
++	0x000,
++	0x000,
++	0x022,
++	0x000,
++	0x000,
++	0x3cc
++};
++
++static const u32 frame_struct_rev3[] = {
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x09804506,
++	0x00100030,
++	0x09804507,
++	0x00100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100004,
++	0x01000a0d,
++	0x00100024,
++	0x0980450e,
++	0x00100034,
++	0x0980450f,
++	0x00100034,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x01800504,
++	0x00100030,
++	0x11808505,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000a04,
++	0x00100000,
++	0x11008a05,
++	0x00100020,
++	0x21810506,
++	0x00100030,
++	0x21810506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x1980c506,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x11808504,
++	0x00100030,
++	0x3981ca05,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x10008a04,
++	0x00100000,
++	0x3981ca05,
++	0x00100030,
++	0x1980c506,
++	0x00100030,
++	0x29814507,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a0c,
++	0x00100008,
++	0x01000a0d,
++	0x00100028,
++	0x1980c50e,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x1180850c,
++	0x00100038,
++	0x3981ca0d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x10008a0c,
++	0x00100008,
++	0x3981ca0d,
++	0x00100038,
++	0x1980c50e,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x02001405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x13008a06,
++	0x01900060,
++	0x13008a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x0200140d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x0b004a06,
++	0x01900060,
++	0x0b004a06,
++	0x01900060,
++	0x5b02ca04,
++	0x00100060,
++	0x3b01d405,
++	0x00100060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x5802d404,
++	0x00100000,
++	0x3b01d405,
++	0x00100060,
++	0x0b004a06,
++	0x01900060,
++	0x23010a07,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x5002940c,
++	0x00100010,
++	0x3201940d,
++	0x00100050,
++	0x0b004a0e,
++	0x01900070,
++	0x0b004a0e,
++	0x01900070,
++	0x5b02ca0c,
++	0x00100070,
++	0x3b01d40d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x5802d40c,
++	0x00100010,
++	0x3b01d40d,
++	0x00100070,
++	0x0b004a0e,
++	0x01900070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x000f4800,
++	0x62031405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x53028a07,
++	0x01900060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x000f4808,
++	0x6203140d,
++	0x00100048,
++	0x53028a0e,
++	0x01900068,
++	0x53028a0f,
++	0x01900068,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100004,
++	0x11008a0d,
++	0x00100024,
++	0x1980c50e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x2181050e,
++	0x00100034,
++	0x0180050c,
++	0x00100038,
++	0x1180850d,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000a0c,
++	0x00100008,
++	0x11008a0d,
++	0x00100028,
++	0x2181050e,
++	0x00100038,
++	0x2181050e,
++	0x00100038,
++	0x1181850d,
++	0x00100038,
++	0x2981450f,
++	0x01100038,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x08004a04,
++	0x00100000,
++	0x01000a05,
++	0x00100020,
++	0x0180c506,
++	0x00100030,
++	0x0180c506,
++	0x00100030,
++	0x2180c50c,
++	0x00100030,
++	0x49820a0d,
++	0x0016a130,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x2000ca0c,
++	0x00100000,
++	0x49820a0d,
++	0x0016a130,
++	0x1980c50e,
++	0x00100030,
++	0x41824a0d,
++	0x0016a130,
++	0x2981450f,
++	0x01100030,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100008,
++	0x0200140d,
++	0x00100048,
++	0x0b004a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x13008a0e,
++	0x01900068,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x13008a0e,
++	0x01900070,
++	0x13008a0e,
++	0x01900070,
++	0x1b014a0d,
++	0x00100070,
++	0x23010a0f,
++	0x01500070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x50029404,
++	0x00100000,
++	0x32019405,
++	0x00100040,
++	0x03004a06,
++	0x01900060,
++	0x03004a06,
++	0x01900060,
++	0x6b030a0c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x6b03140c,
++	0x00100060,
++	0x4b02140d,
++	0x0016a160,
++	0x0b004a0e,
++	0x01900060,
++	0x4302540d,
++	0x0016a160,
++	0x23010a0f,
++	0x01500060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x53028a06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x43020a04,
++	0x00100060,
++	0x1b00ca05,
++	0x00100060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x53028a0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x43020a0c,
++	0x00100070,
++	0x1b00ca0d,
++	0x00100070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x40021404,
++	0x00100000,
++	0x1a00d405,
++	0x00100040,
++	0x5b02ca06,
++	0x01900060,
++	0x5b02ca06,
++	0x01900060,
++	0x53028a07,
++	0x0190c060,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x4002140c,
++	0x00100010,
++	0x1a00d40d,
++	0x00100050,
++	0x5b02ca0e,
++	0x01900070,
++	0x5b02ca0e,
++	0x01900070,
++	0x53028a0f,
++	0x0190c070,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 pilot_tbl_rev3[] = {
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0xff08,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0x80d5,
++	0xff0a,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xff82,
++	0xffa0,
++	0xff28,
++	0xff0a,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xffff,
++	0xf83f,
++	0xfa1f,
++	0xfa97,
++	0xfab5,
++	0xf2bd,
++	0xf0bf,
++	0xffff,
++	0xffff,
++	0xf017,
++	0xf815,
++	0xf215,
++	0xf095,
++	0xf035,
++	0xf01d,
++	0xffff,
++	0xffff,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xff08,
++	0xff02,
++	0xff80,
++	0xff20,
++	0xf01f,
++	0xf817,
++	0xfa15,
++	0xf295,
++	0xf0b5,
++	0xf03d,
++	0xffff,
++	0xffff,
++	0xf82a,
++	0xfa0a,
++	0xfa82,
++	0xfaa0,
++	0xf2a8,
++	0xf0aa,
++	0xffff,
++	0xffff,
++	0xf002,
++	0xf800,
++	0xf200,
++	0xf080,
++	0xf020,
++	0xf008,
++	0xffff,
++	0xffff,
++	0xf00a,
++	0xf802,
++	0xfa00,
++	0xf280,
++	0xf0a0,
++	0xf028,
++	0xffff,
++	0xffff,
++};
++
++static const u32 tmap_tbl_rev3[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 intlv_tbl_rev3[] = {
++	0x00802070,
++	0x0671188d,
++	0x0a60192c,
++	0x0a300e46,
++	0x00c1188d,
++	0x080024d2,
++	0x00000070,
++};
++
++static const u32 tdtrn_tbl_rev3[] = {
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x061c061c,
++	0x0050ee68,
++	0xf592fe36,
++	0xfe5212f6,
++	0x00000c38,
++	0xfe5212f6,
++	0xf592fe36,
++	0x0050ee68,
++	0x061c061c,
++	0xee680050,
++	0xfe36f592,
++	0x12f6fe52,
++	0x0c380000,
++	0x12f6fe52,
++	0xfe36f592,
++	0xee680050,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0x05e305e3,
++	0x004def0c,
++	0xf5f3fe47,
++	0xfe611246,
++	0x00000bc7,
++	0xfe611246,
++	0xf5f3fe47,
++	0x004def0c,
++	0x05e305e3,
++	0xef0c004d,
++	0xfe47f5f3,
++	0x1246fe61,
++	0x0bc70000,
++	0x1246fe61,
++	0xfe47f5f3,
++	0xef0c004d,
++	0xfa58fa58,
++	0xf895043b,
++	0xff4c09c0,
++	0xfbc6ffa8,
++	0xfb84f384,
++	0x0798f6f9,
++	0x05760122,
++	0x058409f6,
++	0x0b500000,
++	0x05b7f542,
++	0x08860432,
++	0x06ddfee7,
++	0xfb84f384,
++	0xf9d90664,
++	0xf7e8025c,
++	0x00fff7bd,
++	0x05a805a8,
++	0xf7bd00ff,
++	0x025cf7e8,
++	0x0664f9d9,
++	0xf384fb84,
++	0xfee706dd,
++	0x04320886,
++	0xf54205b7,
++	0x00000b50,
++	0x09f60584,
++	0x01220576,
++	0xf6f90798,
++	0xf384fb84,
++	0xffa8fbc6,
++	0x09c0ff4c,
++	0x043bf895,
++	0x02d402d4,
++	0x07de0270,
++	0xfc96079c,
++	0xf90afe94,
++	0xfe00ff2c,
++	0x02d4065d,
++	0x092a0096,
++	0x0014fbb8,
++	0xfd2cfd2c,
++	0x076afb3c,
++	0x0096f752,
++	0xf991fd87,
++	0xfb2c0200,
++	0xfeb8f960,
++	0x08e0fc96,
++	0x049802a8,
++	0xfd2cfd2c,
++	0x02a80498,
++	0xfc9608e0,
++	0xf960feb8,
++	0x0200fb2c,
++	0xfd87f991,
++	0xf7520096,
++	0xfb3c076a,
++	0xfd2cfd2c,
++	0xfbb80014,
++	0x0096092a,
++	0x065d02d4,
++	0xff2cfe00,
++	0xfe94f90a,
++	0x079cfc96,
++	0x027007de,
++	0x02d402d4,
++	0x027007de,
++	0x079cfc96,
++	0xfe94f90a,
++	0xff2cfe00,
++	0x065d02d4,
++	0x0096092a,
++	0xfbb80014,
++	0xfd2cfd2c,
++	0xfb3c076a,
++	0xf7520096,
++	0xfd87f991,
++	0x0200fb2c,
++	0xf960feb8,
++	0xfc9608e0,
++	0x02a80498,
++	0xfd2cfd2c,
++	0x049802a8,
++	0x08e0fc96,
++	0xfeb8f960,
++	0xfb2c0200,
++	0xf991fd87,
++	0x0096f752,
++	0x076afb3c,
++	0xfd2cfd2c,
++	0x0014fbb8,
++	0x092a0096,
++	0x02d4065d,
++	0xfe00ff2c,
++	0xf90afe94,
++	0xfc96079c,
++	0x07de0270,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x062a0000,
++	0xfefa0759,
++	0x08b80908,
++	0xf396fc2d,
++	0xf9d6045c,
++	0xfc4ef608,
++	0xf748f596,
++	0x07b207bf,
++	0x062a062a,
++	0xf84ef841,
++	0xf748f596,
++	0x03b209f8,
++	0xf9d6045c,
++	0x0c6a03d3,
++	0x08b80908,
++	0x0106f8a7,
++	0x062a0000,
++	0xfefaf8a7,
++	0x08b8f6f8,
++	0xf39603d3,
++	0xf9d6fba4,
++	0xfc4e09f8,
++	0xf7480a6a,
++	0x07b2f841,
++	0x062af9d6,
++	0xf84e07bf,
++	0xf7480a6a,
++	0x03b2f608,
++	0xf9d6fba4,
++	0x0c6afc2d,
++	0x08b8f6f8,
++	0x01060759,
++	0x061c061c,
++	0xff30009d,
++	0xffb21141,
++	0xfd87fb54,
++	0xf65dfe59,
++	0x02eef99e,
++	0x0166f03c,
++	0xfff809b6,
++	0x000008a4,
++	0x000af42b,
++	0x00eff577,
++	0xfa840bf2,
++	0xfc02ff51,
++	0x08260f67,
++	0xfff0036f,
++	0x0842f9c3,
++	0x00000000,
++	0x063df7be,
++	0xfc910010,
++	0xf099f7da,
++	0x00af03fe,
++	0xf40e057c,
++	0x0a89ff11,
++	0x0bd5fff6,
++	0xf75c0000,
++	0xf64a0008,
++	0x0fc4fe9a,
++	0x0662fd12,
++	0x01a709a3,
++	0x04ac0279,
++	0xeebf004e,
++	0xff6300d0,
++	0xf9e4f9e4,
++	0x00d0ff63,
++	0x004eeebf,
++	0x027904ac,
++	0x09a301a7,
++	0xfd120662,
++	0xfe9a0fc4,
++	0x0008f64a,
++	0x0000f75c,
++	0xfff60bd5,
++	0xff110a89,
++	0x057cf40e,
++	0x03fe00af,
++	0xf7daf099,
++	0x0010fc91,
++	0xf7be063d,
++	0x00000000,
++	0xf9c30842,
++	0x036ffff0,
++	0x0f670826,
++	0xff51fc02,
++	0x0bf2fa84,
++	0xf57700ef,
++	0xf42b000a,
++	0x08a40000,
++	0x09b6fff8,
++	0xf03c0166,
++	0xf99e02ee,
++	0xfe59f65d,
++	0xfb54fd87,
++	0x1141ffb2,
++	0x009dff30,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0x05e30000,
++	0xff060705,
++	0x085408a0,
++	0xf425fc59,
++	0xfa1d042a,
++	0xfc78f67a,
++	0xf7acf60e,
++	0x075a0766,
++	0x05e305e3,
++	0xf8a6f89a,
++	0xf7acf60e,
++	0x03880986,
++	0xfa1d042a,
++	0x0bdb03a7,
++	0x085408a0,
++	0x00faf8fb,
++	0x05e30000,
++	0xff06f8fb,
++	0x0854f760,
++	0xf42503a7,
++	0xfa1dfbd6,
++	0xfc780986,
++	0xf7ac09f2,
++	0x075af89a,
++	0x05e3fa1d,
++	0xf8a60766,
++	0xf7ac09f2,
++	0x0388f67a,
++	0xfa1dfbd6,
++	0x0bdbfc59,
++	0x0854f760,
++	0x00fa0705,
++	0xfa58fa58,
++	0xf8f0fe00,
++	0x0448073d,
++	0xfdc9fe46,
++	0xf9910258,
++	0x089d0407,
++	0xfd5cf71a,
++	0x02affde0,
++	0x083e0496,
++	0xff5a0740,
++	0xff7afd97,
++	0x00fe01f1,
++	0x0009082e,
++	0xfa94ff75,
++	0xfecdf8ea,
++	0xffb0f693,
++	0xfd2cfa58,
++	0x0433ff16,
++	0xfba405dd,
++	0xfa610341,
++	0x06a606cb,
++	0x0039fd2d,
++	0x0677fa97,
++	0x01fa05e0,
++	0xf896003e,
++	0x075a068b,
++	0x012cfc3e,
++	0xfa23f98d,
++	0xfc7cfd43,
++	0xff90fc0d,
++	0x01c10982,
++	0x00c601d6,
++	0xfd2cfd2c,
++	0x01d600c6,
++	0x098201c1,
++	0xfc0dff90,
++	0xfd43fc7c,
++	0xf98dfa23,
++	0xfc3e012c,
++	0x068b075a,
++	0x003ef896,
++	0x05e001fa,
++	0xfa970677,
++	0xfd2d0039,
++	0x06cb06a6,
++	0x0341fa61,
++	0x05ddfba4,
++	0xff160433,
++	0xfa58fd2c,
++	0xf693ffb0,
++	0xf8eafecd,
++	0xff75fa94,
++	0x082e0009,
++	0x01f100fe,
++	0xfd97ff7a,
++	0x0740ff5a,
++	0x0496083e,
++	0xfde002af,
++	0xf71afd5c,
++	0x0407089d,
++	0x0258f991,
++	0xfe46fdc9,
++	0x073d0448,
++	0xfe00f8f0,
++	0xfd2cfd2c,
++	0xfce00500,
++	0xfc09fddc,
++	0xfe680157,
++	0x04c70571,
++	0xfc3aff21,
++	0xfcd70228,
++	0x056d0277,
++	0x0200fe00,
++	0x0022f927,
++	0xfe3c032b,
++	0xfc44ff3c,
++	0x03e9fbdb,
++	0x04570313,
++	0x04c9ff5c,
++	0x000d03b8,
++	0xfa580000,
++	0xfbe900d2,
++	0xf9d0fe0b,
++	0x0125fdf9,
++	0x042501bf,
++	0x0328fa2b,
++	0xffa902f0,
++	0xfa250157,
++	0x0200fe00,
++	0x03740438,
++	0xff0405fd,
++	0x030cfe52,
++	0x0037fb39,
++	0xff6904c5,
++	0x04f8fd23,
++	0xfd31fc1b,
++	0xfd2cfd2c,
++	0xfc1bfd31,
++	0xfd2304f8,
++	0x04c5ff69,
++	0xfb390037,
++	0xfe52030c,
++	0x05fdff04,
++	0x04380374,
++	0xfe000200,
++	0x0157fa25,
++	0x02f0ffa9,
++	0xfa2b0328,
++	0x01bf0425,
++	0xfdf90125,
++	0xfe0bf9d0,
++	0x00d2fbe9,
++	0x0000fa58,
++	0x03b8000d,
++	0xff5c04c9,
++	0x03130457,
++	0xfbdb03e9,
++	0xff3cfc44,
++	0x032bfe3c,
++	0xf9270022,
++	0xfe000200,
++	0x0277056d,
++	0x0228fcd7,
++	0xff21fc3a,
++	0x057104c7,
++	0x0157fe68,
++	0xfddcfc09,
++	0x0500fce0,
++	0xfd2cfd2c,
++	0x0500fce0,
++	0xfddcfc09,
++	0x0157fe68,
++	0x057104c7,
++	0xff21fc3a,
++	0x0228fcd7,
++	0x0277056d,
++	0xfe000200,
++	0xf9270022,
++	0x032bfe3c,
++	0xff3cfc44,
++	0xfbdb03e9,
++	0x03130457,
++	0xff5c04c9,
++	0x03b8000d,
++	0x0000fa58,
++	0x00d2fbe9,
++	0xfe0bf9d0,
++	0xfdf90125,
++	0x01bf0425,
++	0xfa2b0328,
++	0x02f0ffa9,
++	0x0157fa25,
++	0xfe000200,
++	0x04380374,
++	0x05fdff04,
++	0xfe52030c,
++	0xfb390037,
++	0x04c5ff69,
++	0xfd2304f8,
++	0xfc1bfd31,
++	0xfd2cfd2c,
++	0xfd31fc1b,
++	0x04f8fd23,
++	0xff6904c5,
++	0x0037fb39,
++	0x030cfe52,
++	0xff0405fd,
++	0x03740438,
++	0x0200fe00,
++	0xfa250157,
++	0xffa902f0,
++	0x0328fa2b,
++	0x042501bf,
++	0x0125fdf9,
++	0xf9d0fe0b,
++	0xfbe900d2,
++	0xfa580000,
++	0x000d03b8,
++	0x04c9ff5c,
++	0x04570313,
++	0x03e9fbdb,
++	0xfc44ff3c,
++	0xfe3c032b,
++	0x0022f927,
++	0x0200fe00,
++	0x056d0277,
++	0xfcd70228,
++	0xfc3aff21,
++	0x04c70571,
++	0xfe680157,
++	0xfc09fddc,
++	0xfce00500,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++	0x05a80000,
++	0xff1006be,
++	0x0800084a,
++	0xf49cfc7e,
++	0xfa580400,
++	0xfc9cf6da,
++	0xf800f672,
++	0x0710071c,
++	0x05a805a8,
++	0xf8f0f8e4,
++	0xf800f672,
++	0x03640926,
++	0xfa580400,
++	0x0b640382,
++	0x0800084a,
++	0x00f0f942,
++	0x05a80000,
++	0xff10f942,
++	0x0800f7b6,
++	0xf49c0382,
++	0xfa58fc00,
++	0xfc9c0926,
++	0xf800098e,
++	0x0710f8e4,
++	0x05a8fa58,
++	0xf8f0071c,
++	0xf800098e,
++	0x0364f6da,
++	0xfa58fc00,
++	0x0b64fc7e,
++	0x0800f7b6,
++	0x00f006be,
++};
++
++const u32 noise_var_tbl_rev3[] = {
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++	0x02110211,
++	0x0000014d,
++};
++
++static const u16 mcs_tbl_rev3[] = {
++	0x0000,
++	0x0008,
++	0x000a,
++	0x0010,
++	0x0012,
++	0x0019,
++	0x001a,
++	0x001c,
++	0x0080,
++	0x0088,
++	0x008a,
++	0x0090,
++	0x0092,
++	0x0099,
++	0x009a,
++	0x009c,
++	0x0100,
++	0x0108,
++	0x010a,
++	0x0110,
++	0x0112,
++	0x0119,
++	0x011a,
++	0x011c,
++	0x0180,
++	0x0188,
++	0x018a,
++	0x0190,
++	0x0192,
++	0x0199,
++	0x019a,
++	0x019c,
++	0x0000,
++	0x0098,
++	0x00a0,
++	0x00a8,
++	0x009a,
++	0x00a2,
++	0x00aa,
++	0x0120,
++	0x0128,
++	0x0128,
++	0x0130,
++	0x0138,
++	0x0138,
++	0x0140,
++	0x0122,
++	0x012a,
++	0x012a,
++	0x0132,
++	0x013a,
++	0x013a,
++	0x0142,
++	0x01a8,
++	0x01b0,
++	0x01b8,
++	0x01b0,
++	0x01b8,
++	0x01c0,
++	0x01c8,
++	0x01c0,
++	0x01c8,
++	0x01d0,
++	0x01d0,
++	0x01d8,
++	0x01aa,
++	0x01b2,
++	0x01ba,
++	0x01b2,
++	0x01ba,
++	0x01c2,
++	0x01ca,
++	0x01c2,
++	0x01ca,
++	0x01d2,
++	0x01d2,
++	0x01da,
++	0x0001,
++	0x0002,
++	0x0004,
++	0x0009,
++	0x000c,
++	0x0011,
++	0x0014,
++	0x0018,
++	0x0020,
++	0x0021,
++	0x0022,
++	0x0024,
++	0x0081,
++	0x0082,
++	0x0084,
++	0x0089,
++	0x008c,
++	0x0091,
++	0x0094,
++	0x0098,
++	0x00a0,
++	0x00a1,
++	0x00a2,
++	0x00a4,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++	0x0007,
++};
++
++static const u32 tdi_tbl20_ant0_rev3[] = {
++	0x00091226,
++	0x000a1429,
++	0x000b56ad,
++	0x000c58b0,
++	0x000d5ab3,
++	0x000e9cb6,
++	0x000f9eba,
++	0x0000c13d,
++	0x00020301,
++	0x00030504,
++	0x00040708,
++	0x0005090b,
++	0x00064b8e,
++	0x00095291,
++	0x000a5494,
++	0x000b9718,
++	0x000c9927,
++	0x000d9b2a,
++	0x000edd2e,
++	0x000fdf31,
++	0x000101b4,
++	0x000243b7,
++	0x000345bb,
++	0x000447be,
++	0x00058982,
++	0x00068c05,
++	0x00099309,
++	0x000a950c,
++	0x000bd78f,
++	0x000cd992,
++	0x000ddb96,
++	0x000f1d99,
++	0x00005fa8,
++	0x0001422c,
++	0x0002842f,
++	0x00038632,
++	0x00048835,
++	0x0005ca38,
++	0x0006ccbc,
++	0x0009d3bf,
++	0x000b1603,
++	0x000c1806,
++	0x000d1a0a,
++	0x000e1c0d,
++	0x000f5e10,
++	0x00008093,
++	0x00018297,
++	0x0002c49a,
++	0x0003c680,
++	0x0004c880,
++	0x00060b00,
++	0x00070d00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl20_ant1_rev3[] = {
++	0x00014b26,
++	0x00028d29,
++	0x000393ad,
++	0x00049630,
++	0x0005d833,
++	0x0006da36,
++	0x00099c3a,
++	0x000a9e3d,
++	0x000bc081,
++	0x000cc284,
++	0x000dc488,
++	0x000f068b,
++	0x0000488e,
++	0x00018b91,
++	0x0002d214,
++	0x0003d418,
++	0x0004d6a7,
++	0x000618aa,
++	0x00071aae,
++	0x0009dcb1,
++	0x000b1eb4,
++	0x000c0137,
++	0x000d033b,
++	0x000e053e,
++	0x000f4702,
++	0x00008905,
++	0x00020c09,
++	0x0003128c,
++	0x0004148f,
++	0x00051712,
++	0x00065916,
++	0x00091b19,
++	0x000a1d28,
++	0x000b5f2c,
++	0x000c41af,
++	0x000d43b2,
++	0x000e85b5,
++	0x000f87b8,
++	0x0000c9bc,
++	0x00024cbf,
++	0x00035303,
++	0x00045506,
++	0x0005978a,
++	0x0006998d,
++	0x00095b90,
++	0x000a5d93,
++	0x000b9f97,
++	0x000c821a,
++	0x000d8400,
++	0x000ec600,
++	0x000fc800,
++	0x00010a00,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant0_rev3[] = {
++	0x0011a346,
++	0x00136ccf,
++	0x0014f5d9,
++	0x001641e2,
++	0x0017cb6b,
++	0x00195475,
++	0x001b2383,
++	0x001cad0c,
++	0x001e7616,
++	0x0000821f,
++	0x00020ba8,
++	0x0003d4b2,
++	0x00056447,
++	0x00072dd0,
++	0x0008b6da,
++	0x000a02e3,
++	0x000b8c6c,
++	0x000d15f6,
++	0x0011e484,
++	0x0013ae0d,
++	0x00153717,
++	0x00168320,
++	0x00180ca9,
++	0x00199633,
++	0x001b6548,
++	0x001ceed1,
++	0x001eb7db,
++	0x0000c3e4,
++	0x00024d6d,
++	0x000416f7,
++	0x0005a585,
++	0x00076f0f,
++	0x0008f818,
++	0x000a4421,
++	0x000bcdab,
++	0x000d9734,
++	0x00122649,
++	0x0013efd2,
++	0x001578dc,
++	0x0016c4e5,
++	0x00184e6e,
++	0x001a17f8,
++	0x001ba686,
++	0x001d3010,
++	0x001ef999,
++	0x00010522,
++	0x00028eac,
++	0x00045835,
++	0x0005e74a,
++	0x0007b0d3,
++	0x00093a5d,
++	0x000a85e6,
++	0x000c0f6f,
++	0x000dd8f9,
++	0x00126787,
++	0x00143111,
++	0x0015ba9a,
++	0x00170623,
++	0x00188fad,
++	0x001a5936,
++	0x001be84b,
++	0x001db1d4,
++	0x001f3b5e,
++	0x000146e7,
++	0x00031070,
++	0x000499fa,
++	0x00062888,
++	0x0007f212,
++	0x00097b9b,
++	0x000ac7a4,
++	0x000c50ae,
++	0x000e1a37,
++	0x0012a94c,
++	0x001472d5,
++	0x0015fc5f,
++	0x00174868,
++	0x0018d171,
++	0x001a9afb,
++	0x001c2989,
++	0x001df313,
++	0x001f7c9c,
++	0x000188a5,
++	0x000351af,
++	0x0004db38,
++	0x0006aa4d,
++	0x000833d7,
++	0x0009bd60,
++	0x000b0969,
++	0x000c9273,
++	0x000e5bfc,
++	0x00132a8a,
++	0x0014b414,
++	0x00163d9d,
++	0x001789a6,
++	0x001912b0,
++	0x001adc39,
++	0x001c6bce,
++	0x001e34d8,
++	0x001fbe61,
++	0x0001ca6a,
++	0x00039374,
++	0x00051cfd,
++	0x0006ec0b,
++	0x00087515,
++	0x0009fe9e,
++	0x000b4aa7,
++	0x000cd3b1,
++	0x000e9d3a,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 tdi_tbl40_ant1_rev3[] = {
++	0x001edb36,
++	0x000129ca,
++	0x0002b353,
++	0x00047cdd,
++	0x0005c8e6,
++	0x000791ef,
++	0x00091bf9,
++	0x000aaa07,
++	0x000c3391,
++	0x000dfd1a,
++	0x00120923,
++	0x0013d22d,
++	0x00155c37,
++	0x0016eacb,
++	0x00187454,
++	0x001a3dde,
++	0x001b89e7,
++	0x001d12f0,
++	0x001f1cfa,
++	0x00016b88,
++	0x00033492,
++	0x0004be1b,
++	0x00060a24,
++	0x0007d32e,
++	0x00095d38,
++	0x000aec4c,
++	0x000c7555,
++	0x000e3edf,
++	0x00124ae8,
++	0x001413f1,
++	0x0015a37b,
++	0x00172c89,
++	0x0018b593,
++	0x001a419c,
++	0x001bcb25,
++	0x001d942f,
++	0x001f63b9,
++	0x0001ad4d,
++	0x00037657,
++	0x0004c260,
++	0x00068be9,
++	0x000814f3,
++	0x0009a47c,
++	0x000b2d8a,
++	0x000cb694,
++	0x000e429d,
++	0x00128c26,
++	0x001455b0,
++	0x0015e4ba,
++	0x00176e4e,
++	0x0018f758,
++	0x001a8361,
++	0x001c0cea,
++	0x001dd674,
++	0x001fa57d,
++	0x0001ee8b,
++	0x0003b795,
++	0x0005039e,
++	0x0006cd27,
++	0x000856b1,
++	0x0009e5c6,
++	0x000b6f4f,
++	0x000cf859,
++	0x000e8462,
++	0x00130deb,
++	0x00149775,
++	0x00162603,
++	0x0017af8c,
++	0x00193896,
++	0x001ac49f,
++	0x001c4e28,
++	0x001e17b2,
++	0x0000a6c7,
++	0x00023050,
++	0x0003f9da,
++	0x00054563,
++	0x00070eec,
++	0x00089876,
++	0x000a2704,
++	0x000bb08d,
++	0x000d3a17,
++	0x001185a0,
++	0x00134f29,
++	0x0014d8b3,
++	0x001667c8,
++	0x0017f151,
++	0x00197adb,
++	0x001b0664,
++	0x001c8fed,
++	0x001e5977,
++	0x0000e805,
++	0x0002718f,
++	0x00043b18,
++	0x000586a1,
++	0x0007502b,
++	0x0008d9b4,
++	0x000a68c9,
++	0x000bf252,
++	0x000dbbdc,
++	0x0011c7e5,
++	0x001390ee,
++	0x00151a78,
++	0x0016a906,
++	0x00183290,
++	0x0019bc19,
++	0x001b4822,
++	0x001cd12c,
++	0x001e9ab5,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 pltlut_tbl_rev3[] = {
++	0x76540213,
++	0x62407351,
++	0x76543210,
++	0x76540213,
++	0x76540213,
++	0x76430521,
++};
++
++static const u32 chanest_tbl_rev3[] = {
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x44444444,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++	0x10101010,
++};
++
++static const u8 frame_lut_rev3[] = {
++	0x02,
++	0x04,
++	0x14,
++	0x14,
++	0x03,
++	0x05,
++	0x16,
++	0x16,
++	0x0a,
++	0x0c,
++	0x1c,
++	0x1c,
++	0x0b,
++	0x0d,
++	0x1e,
++	0x1e,
++	0x06,
++	0x08,
++	0x18,
++	0x18,
++	0x07,
++	0x09,
++	0x1a,
++	0x1a,
++	0x0e,
++	0x10,
++	0x20,
++	0x28,
++	0x0f,
++	0x11,
++	0x22,
++	0x2a,
++};
++
++static const u8 est_pwr_lut_core0_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 est_pwr_lut_core1_rev3[] = {
++	0x55,
++	0x54,
++	0x54,
++	0x53,
++	0x52,
++	0x52,
++	0x51,
++	0x51,
++	0x50,
++	0x4f,
++	0x4f,
++	0x4e,
++	0x4e,
++	0x4d,
++	0x4c,
++	0x4c,
++	0x4b,
++	0x4a,
++	0x49,
++	0x49,
++	0x48,
++	0x47,
++	0x46,
++	0x46,
++	0x45,
++	0x44,
++	0x43,
++	0x42,
++	0x41,
++	0x40,
++	0x40,
++	0x3f,
++	0x3e,
++	0x3d,
++	0x3c,
++	0x3a,
++	0x39,
++	0x38,
++	0x37,
++	0x36,
++	0x35,
++	0x33,
++	0x32,
++	0x31,
++	0x2f,
++	0x2e,
++	0x2c,
++	0x2b,
++	0x29,
++	0x27,
++	0x25,
++	0x23,
++	0x21,
++	0x1f,
++	0x1d,
++	0x1a,
++	0x18,
++	0x15,
++	0x12,
++	0x0e,
++	0x0b,
++	0x07,
++	0x02,
++	0xfd,
++};
++
++static const u8 adj_pwr_lut_core0_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u8 adj_pwr_lut_core1_rev3[] = {
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++	0x00,
++};
++
++static const u32 gainctrl_lut_core0_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 gainctrl_lut_core1_rev3[] = {
++	0x5bf70044,
++	0x5bf70042,
++	0x5bf70040,
++	0x5bf7003e,
++	0x5bf7003c,
++	0x5bf7003b,
++	0x5bf70039,
++	0x5bf70037,
++	0x5bf70036,
++	0x5bf70034,
++	0x5bf70033,
++	0x5bf70031,
++	0x5bf70030,
++	0x5ba70044,
++	0x5ba70042,
++	0x5ba70040,
++	0x5ba7003e,
++	0x5ba7003c,
++	0x5ba7003b,
++	0x5ba70039,
++	0x5ba70037,
++	0x5ba70036,
++	0x5ba70034,
++	0x5ba70033,
++	0x5b770044,
++	0x5b770042,
++	0x5b770040,
++	0x5b77003e,
++	0x5b77003c,
++	0x5b77003b,
++	0x5b770039,
++	0x5b770037,
++	0x5b770036,
++	0x5b770034,
++	0x5b770033,
++	0x5b770031,
++	0x5b770030,
++	0x5b77002f,
++	0x5b77002d,
++	0x5b77002c,
++	0x5b470044,
++	0x5b470042,
++	0x5b470040,
++	0x5b47003e,
++	0x5b47003c,
++	0x5b47003b,
++	0x5b470039,
++	0x5b470037,
++	0x5b470036,
++	0x5b470034,
++	0x5b470033,
++	0x5b470031,
++	0x5b470030,
++	0x5b47002f,
++	0x5b47002d,
++	0x5b47002c,
++	0x5b47002b,
++	0x5b47002a,
++	0x5b270044,
++	0x5b270042,
++	0x5b270040,
++	0x5b27003e,
++	0x5b27003c,
++	0x5b27003b,
++	0x5b270039,
++	0x5b270037,
++	0x5b270036,
++	0x5b270034,
++	0x5b270033,
++	0x5b270031,
++	0x5b270030,
++	0x5b27002f,
++	0x5b170044,
++	0x5b170042,
++	0x5b170040,
++	0x5b17003e,
++	0x5b17003c,
++	0x5b17003b,
++	0x5b170039,
++	0x5b170037,
++	0x5b170036,
++	0x5b170034,
++	0x5b170033,
++	0x5b170031,
++	0x5b170030,
++	0x5b17002f,
++	0x5b17002d,
++	0x5b17002c,
++	0x5b17002b,
++	0x5b17002a,
++	0x5b170028,
++	0x5b170027,
++	0x5b170026,
++	0x5b170025,
++	0x5b170024,
++	0x5b170023,
++	0x5b070044,
++	0x5b070042,
++	0x5b070040,
++	0x5b07003e,
++	0x5b07003c,
++	0x5b07003b,
++	0x5b070039,
++	0x5b070037,
++	0x5b070036,
++	0x5b070034,
++	0x5b070033,
++	0x5b070031,
++	0x5b070030,
++	0x5b07002f,
++	0x5b07002d,
++	0x5b07002c,
++	0x5b07002b,
++	0x5b07002a,
++	0x5b070028,
++	0x5b070027,
++	0x5b070026,
++	0x5b070025,
++	0x5b070024,
++	0x5b070023,
++	0x5b070022,
++	0x5b070021,
++	0x5b070020,
++	0x5b07001f,
++	0x5b07001e,
++	0x5b07001d,
++	0x5b07001d,
++	0x5b07001c,
++};
++
++static const u32 iq_lut_core0_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u32 iq_lut_core1_rev3[] = {
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++static const u16 loft_lut_core0_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 loft_lut_core1_rev3[] = {
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++	0x0000,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x0036,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x002a,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x001e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x000e,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01fc,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01ee,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++	0x01d6,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
++	0x00000000,
++	0x00001fa0,
++	0x00019f78,
++	0x0001df7e,
++	0x03fa9f86,
++	0x03fd1f90,
++	0x03fe5f8a,
++	0x03fb1f94,
++	0x03fd9fa0,
++	0x00009f98,
++	0x03fd1fac,
++	0x03ff9fa2,
++	0x03fe9fae,
++	0x00001fae,
++	0x03fddfb4,
++	0x03ff1fb8,
++	0x03ff9fbc,
++	0x03ffdfbe,
++	0x03fe9fc2,
++	0x03fedfc6,
++	0x03fedfc6,
++	0x03ff9fc8,
++	0x03ff5fc6,
++	0x03fedfc2,
++	0x03ff9fc0,
++	0x03ff5fac,
++	0x03ff5fac,
++	0x03ff9fa2,
++	0x03ff9fa6,
++	0x03ff9faa,
++	0x03ff5fb0,
++	0x03ff5fb4,
++	0x03ff1fca,
++	0x03ff5fce,
++	0x03fcdfdc,
++	0x03fb4006,
++	0x00000030,
++	0x03ff808a,
++	0x03ff80da,
++	0x0000016c,
++	0x03ff8318,
++	0x03ff063a,
++	0x03fd8bd6,
++	0x00014ffe,
++	0x00034ffe,
++	0x00034ffe,
++	0x0003cffe,
++	0x00040ffe,
++	0x00040ffe,
++	0x0003cffe,
++	0x0003cffe,
++	0x00020ffe,
++	0x03fe0ffe,
++	0x03fdcffe,
++	0x03f94ffe,
++	0x03f54ffe,
++	0x03f44ffe,
++	0x03ef8ffe,
++	0x03ee0ffe,
++	0x03ebcffe,
++	0x03e8cffe,
++	0x03e74ffe,
++	0x03e4cffe,
++	0x03e38ffe,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev3[] = {
++	0x05af005a,
++	0x0571005e,
++	0x05040066,
++	0x04bd006c,
++	0x047d0072,
++	0x04430078,
++	0x03f70081,
++	0x03cb0087,
++	0x03870091,
++	0x035e0098,
++	0x032e00a1,
++	0x030300aa,
++	0x02d800b4,
++	0x02ae00bf,
++	0x028900ca,
++	0x026400d6,
++	0x024100e3,
++	0x022200f0,
++	0x020200ff,
++	0x01e5010e,
++	0x01ca011e,
++	0x01b0012f,
++	0x01990140,
++	0x01830153,
++	0x016c0168,
++	0x0158017d,
++	0x01450193,
++	0x013301ab,
++	0x012101c5,
++	0x011101e0,
++	0x010201fc,
++	0x00f4021a,
++	0x00e6011d,
++	0x00d9012e,
++	0x00cd0140,
++	0x00c20153,
++	0x00b70167,
++	0x00ac017c,
++	0x00a30193,
++	0x009a01ab,
++	0x009101c4,
++	0x008901df,
++	0x008101fb,
++	0x007a0219,
++	0x00730239,
++	0x006d025b,
++	0x0067027e,
++	0x006102a4,
++	0x005c02cc,
++	0x005602f6,
++	0x00520323,
++	0x004d0353,
++	0x00490385,
++	0x004503bb,
++	0x004103f3,
++	0x003d042f,
++	0x003a046f,
++	0x003704b2,
++	0x003404f9,
++	0x00310545,
++	0x002e0596,
++	0x002b05f5,
++	0x00290640,
++	0x002606a4,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile[] = {
++	{&ant_swctrl_tbl_rev3,
++	 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile1[] = {
++	{&ant_swctrl_tbl_rev3_1,
++	 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile2[] = {
++	{&ant_swctrl_tbl_rev3_2,
++	 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3_volatile3[] = {
++	{&ant_swctrl_tbl_rev3_3,
++	 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
++	 16}
++	,
++};
++
++const struct phytbl_info mimophytbl_info_rev3[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev3,
++	 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++};
++
++const u32 mimophytbl_info_sz_rev3 =
++	sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
++const u32 mimophytbl_info_sz_rev3_volatile =
++	sizeof(mimophytbl_info_rev3_volatile) /
++	sizeof(mimophytbl_info_rev3_volatile[0]);
++const u32 mimophytbl_info_sz_rev3_volatile1 =
++	sizeof(mimophytbl_info_rev3_volatile1) /
++	sizeof(mimophytbl_info_rev3_volatile1[0]);
++const u32 mimophytbl_info_sz_rev3_volatile2 =
++	sizeof(mimophytbl_info_rev3_volatile2) /
++	sizeof(mimophytbl_info_rev3_volatile2[0]);
++const u32 mimophytbl_info_sz_rev3_volatile3 =
++	sizeof(mimophytbl_info_rev3_volatile3) /
++	sizeof(mimophytbl_info_rev3_volatile3[0]);
++
++static const u32 tmap_tbl_rev7[] = {
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00011111,
++	0x11110000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00088aaa,
++	0xaaaa0000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xaaa8aaa0,
++	0x8aaa8aaa,
++	0xaa8a8a8a,
++	0x000aaa88,
++	0x8aaa0000,
++	0xaaa8a888,
++	0x8aa88a8a,
++	0x8a88a888,
++	0x08080a00,
++	0x0a08080a,
++	0x080a0a08,
++	0x00080808,
++	0x080a0000,
++	0x080a0808,
++	0x080a0808,
++	0x0a0a0a08,
++	0xa0a0a0a0,
++	0x80a0a080,
++	0x8080a0a0,
++	0x00008080,
++	0x80a00000,
++	0x80a080a0,
++	0xa080a0a0,
++	0x8080a0a0,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x99999000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x22000000,
++	0x2222b222,
++	0x22222222,
++	0x222222b2,
++	0xb2222220,
++	0x22222222,
++	0x22d22222,
++	0x00000222,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x33000000,
++	0x3333b333,
++	0x33333333,
++	0x333333b3,
++	0xb3333330,
++	0x33333333,
++	0x33d33333,
++	0x00000333,
++	0x22000000,
++	0x2222a222,
++	0x22222222,
++	0x222222a2,
++	0xa2222220,
++	0x22222222,
++	0x22c22222,
++	0x00000222,
++	0x99b99b00,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb99,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x22222200,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0x22222222,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x11111111,
++	0xf1111111,
++	0x11111111,
++	0x11f11111,
++	0x01111111,
++	0xbb9bb900,
++	0xb9b9bb99,
++	0xb99bbbbb,
++	0xbbbb9b9b,
++	0xb9bb99bb,
++	0xb99999b9,
++	0xb9b9b99b,
++	0x00000bbb,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88aa,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x0a888aaa,
++	0xaa000000,
++	0xa8a8aa88,
++	0xa88aaaaa,
++	0xaaaa8a8a,
++	0xa8aa88a0,
++	0xa88888a8,
++	0xa8a8a88a,
++	0x00000aaa,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0xbbbbbb00,
++	0x999bbbbb,
++	0x9bb99b9b,
++	0xb9b9b9bb,
++	0xb9b99bbb,
++	0xb9b9b9bb,
++	0xb9bb9b99,
++	0x00000999,
++	0x8a000000,
++	0xaa88a888,
++	0xa88888aa,
++	0xa88a8a88,
++	0xa88aa88a,
++	0x88a8aaaa,
++	0xa8aa8aaa,
++	0x0888a88a,
++	0x0b0b0b00,
++	0x090b0b0b,
++	0x0b090b0b,
++	0x0909090b,
++	0x09090b0b,
++	0x09090b0b,
++	0x09090b09,
++	0x00000909,
++	0x0a000000,
++	0x0a080808,
++	0x080a080a,
++	0x080a0a08,
++	0x080a080a,
++	0x0808080a,
++	0x0a0a0a08,
++	0x0808080a,
++	0xb0b0b000,
++	0x9090b0b0,
++	0x90b09090,
++	0xb0b0b090,
++	0xb0b090b0,
++	0x90b0b0b0,
++	0xb0b09090,
++	0x00000090,
++	0x80000000,
++	0xa080a080,
++	0xa08080a0,
++	0xa0808080,
++	0xa080a080,
++	0x80a0a0a0,
++	0xa0a080a0,
++	0x00a0a0a0,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x11000000,
++	0x1111f111,
++	0x11111111,
++	0x111111f1,
++	0xf1111110,
++	0x11111111,
++	0x11f11111,
++	0x00000111,
++	0x33000000,
++	0x3333f333,
++	0x33333333,
++	0x333333f3,
++	0xf3333330,
++	0x33333333,
++	0x33f33333,
++	0x00000333,
++	0x22000000,
++	0x2222f222,
++	0x22222222,
++	0x222222f2,
++	0xf2222220,
++	0x22222222,
++	0x22f22222,
++	0x00000222,
++	0x99000000,
++	0x9b9b99bb,
++	0x9bb99999,
++	0x9999b9b9,
++	0x9b99bb90,
++	0x9bbbbb9b,
++	0x9b9b9bb9,
++	0x00000999,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88888000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00aaa888,
++	0x88a88a00,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x000aa888,
++	0x88880000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa88,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x08aaa888,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x11000000,
++	0x1111a111,
++	0x11111111,
++	0x111111a1,
++	0xa1111110,
++	0x11111111,
++	0x11c11111,
++	0x00000111,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x88000000,
++	0x8a8a88aa,
++	0x8aa88888,
++	0x8888a8a8,
++	0x8a88aa80,
++	0x8aaaaa8a,
++	0x8a8a8aa8,
++	0x00000888,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++	0x00000000,
++};
++
++const u32 noise_var_tbl_rev7[] = {
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++	0x020c020c,
++	0x0000014d,
++};
++
++static const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core0_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++static const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
++	0x00000000,
++	0x00000000,
++	0x00016023,
++	0x00006028,
++	0x00034036,
++	0x0003402e,
++	0x0007203c,
++	0x0006e037,
++	0x00070030,
++	0x0009401f,
++	0x0009a00f,
++	0x000b600d,
++	0x000c8007,
++	0x000ce007,
++	0x00101fff,
++	0x00121ff9,
++	0x0012e004,
++	0x0014dffc,
++	0x0016dff6,
++	0x0018dfe9,
++	0x001b3fe5,
++	0x001c5fd0,
++	0x001ddfc2,
++	0x001f1fb6,
++	0x00207fa4,
++	0x00219f8f,
++	0x0022ff7d,
++	0x00247f6c,
++	0x0024df5b,
++	0x00267f4b,
++	0x0027df3b,
++	0x0029bf3b,
++	0x002b5f2f,
++	0x002d3f2e,
++	0x002f5f2a,
++	0x002fff15,
++	0x00315f0b,
++	0x0032defa,
++	0x0033beeb,
++	0x0034fed9,
++	0x00353ec5,
++	0x00361eb0,
++	0x00363e9b,
++	0x0036be87,
++	0x0036be70,
++	0x0038fe67,
++	0x0044beb2,
++	0x00513ef3,
++	0x00595f11,
++	0x00669f3d,
++	0x0078dfdf,
++	0x00a143aa,
++	0x01642fff,
++	0x0162afff,
++	0x01620fff,
++	0x0160cfff,
++	0x015f0fff,
++	0x015dafff,
++	0x015bcfff,
++	0x015bcfff,
++	0x015b4fff,
++	0x015acfff,
++	0x01590fff,
++	0x0156cfff,
++};
++
++static const u32 papd_cal_scalars_tbl_core1_rev7[] = {
++	0x0b5e002d,
++	0x0ae2002f,
++	0x0a3b0032,
++	0x09a70035,
++	0x09220038,
++	0x08ab003b,
++	0x081f003f,
++	0x07a20043,
++	0x07340047,
++	0x06d2004b,
++	0x067a004f,
++	0x06170054,
++	0x05bf0059,
++	0x0571005e,
++	0x051e0064,
++	0x04d3006a,
++	0x04910070,
++	0x044c0077,
++	0x040f007e,
++	0x03d90085,
++	0x03a1008d,
++	0x036f0095,
++	0x033d009e,
++	0x030b00a8,
++	0x02e000b2,
++	0x02b900bc,
++	0x029200c7,
++	0x026d00d3,
++	0x024900e0,
++	0x022900ed,
++	0x020a00fb,
++	0x01ec010a,
++	0x01d20119,
++	0x01b7012a,
++	0x019e013c,
++	0x0188014e,
++	0x01720162,
++	0x015d0177,
++	0x0149018e,
++	0x013701a5,
++	0x012601be,
++	0x011501d8,
++	0x010601f4,
++	0x00f70212,
++	0x00e90231,
++	0x00dc0253,
++	0x00d00276,
++	0x00c4029b,
++	0x00b902c3,
++	0x00af02ed,
++	0x00a50319,
++	0x009c0348,
++	0x0093037a,
++	0x008b03af,
++	0x008303e6,
++	0x007c0422,
++	0x00750460,
++	0x006e04a3,
++	0x006804e9,
++	0x00620533,
++	0x005d0582,
++	0x005805d6,
++	0x0053062e,
++	0x004e068c,
++};
++
++const struct phytbl_info mimophytbl_info_rev7[] = {
++	{&frame_struct_rev3,
++	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
++	,
++	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
++	 11, 0, 16}
++	,
++	{&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
++	 0, 32}
++	,
++	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
++	 13, 0, 32}
++	,
++	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
++	 14, 0, 32}
++	,
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
++	 16}
++	,
++	{&tdi_tbl20_ant0_rev3,
++	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
++	 32}
++	,
++	{&tdi_tbl20_ant1_rev3,
++	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
++	 32}
++	,
++	{&tdi_tbl40_ant0_rev3,
++	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
++	 32}
++	,
++	{&tdi_tbl40_ant1_rev3,
++	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
++	 32}
++	,
++	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
++	 20, 0, 32}
++	,
++	{&chanest_tbl_rev3,
++	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
++	,
++	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
++	 24, 0, 8}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++	{&papd_comp_rfpwr_tbl_core0_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
++	,
++	{&papd_comp_rfpwr_tbl_core1_rev3,
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
++	 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
++	,
++	{&papd_comp_epsilon_tbl_core0_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core0_rev7,
++	 sizeof(papd_cal_scalars_tbl_core0_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
++	,
++	{&papd_comp_epsilon_tbl_core1_rev7,
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
++	 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
++	,
++	{&papd_cal_scalars_tbl_core1_rev7,
++	 sizeof(papd_cal_scalars_tbl_core1_rev7) /
++	 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev7 =
++	sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
++
++const struct phytbl_info mimophytbl_info_rev16[] = {
++	{&noise_var_tbl_rev7,
++	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
++	,
++	{&est_pwr_lut_core0_rev3,
++	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
++	 0, 8}
++	,
++	{&est_pwr_lut_core1_rev3,
++	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
++	 0, 8}
++	,
++	{&adj_pwr_lut_core0_rev3,
++	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
++	 64, 8}
++	,
++	{&adj_pwr_lut_core1_rev3,
++	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
++	 64, 8}
++	,
++	{&gainctrl_lut_core0_rev3,
++	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
++	 26, 192, 32}
++	,
++	{&gainctrl_lut_core1_rev3,
++	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
++	 27, 192, 32}
++	,
++	{&iq_lut_core0_rev3,
++	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
++	,
++	{&iq_lut_core1_rev3,
++	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
++	,
++	{&loft_lut_core0_rev3,
++	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
++	 16}
++	,
++	{&loft_lut_core1_rev3,
++	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
++	 16}
++	,
++};
++
++const u32 mimophytbl_info_sz_rev16 =
++	sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+new file mode 100644
+index 0000000..dc8a84e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#define ANT_SWCTRL_TBL_REV3_IDX (0)
++
++#include <types.h>
++#include "phy_int.h"
++
++extern const struct phytbl_info mimophytbl_info_rev0[],
++				mimophytbl_info_rev0_volatile[];
++
++extern const u32 mimophytbl_info_sz_rev0,
++		 mimophytbl_info_sz_rev0_volatile;
++
++extern const struct phytbl_info mimophytbl_info_rev3[],
++				mimophytbl_info_rev3_volatile[],
++				mimophytbl_info_rev3_volatile1[],
++				mimophytbl_info_rev3_volatile2[],
++				mimophytbl_info_rev3_volatile3[];
++
++extern const u32 mimophytbl_info_sz_rev3,
++		 mimophytbl_info_sz_rev3_volatile,
++		 mimophytbl_info_sz_rev3_volatile1,
++		 mimophytbl_info_sz_rev3_volatile2,
++		 mimophytbl_info_sz_rev3_volatile3;
++
++extern const u32 noise_var_tbl_rev3[];
++
++extern const struct phytbl_info mimophytbl_info_rev7[];
++
++extern const u32 mimophytbl_info_sz_rev7;
++
++extern const u32 noise_var_tbl_rev7[];
++
++extern const struct phytbl_info mimophytbl_info_rev16[];
++
++extern const u32 mimophytbl_info_sz_rev16;
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+new file mode 100644
+index 0000000..a0de5db
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * This is "two-way" interface, acting as the SHIM layer between driver
++ * and PHY layer. The driver can optionally call this translation layer
++ * to do some preprocessing, then reach PHY. On the PHY->driver direction,
++ * all calls go through this layer since PHY doesn't have access to the
++ * driver's brcms_hardware pointer.
++ */
++#include <linux/slab.h>
++#include <net/mac80211.h>
++
++#include "main.h"
++#include "mac80211_if.h"
++#include "phy_shim.h"
++
++/* PHY SHIM module specific state */
++struct phy_shim_info {
++	struct brcms_hardware *wlc_hw;	/* pointer to main wlc_hw structure */
++	struct brcms_c_info *wlc;	/* pointer to main wlc structure */
++	struct brcms_info *wl; /* pointer to os-specific private state */
++};
++
++struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++					  struct brcms_info *wl,
++					  struct brcms_c_info *wlc) {
++	struct phy_shim_info *physhim = NULL;
++
++	physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
++	if (!physhim)
++		return NULL;
++
++	physhim->wlc_hw = wlc_hw;
++	physhim->wlc = wlc;
++	physhim->wl = wl;
++
++	return physhim;
++}
++
++void wlc_phy_shim_detach(struct phy_shim_info *physhim)
++{
++	kfree(physhim);
++}
++
++struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++				     void (*fn)(struct brcms_phy *pi),
++				     void *arg, const char *name)
++{
++	return (struct wlapi_timer *)
++			brcms_init_timer(physhim->wl, (void (*)(void *))fn,
++					 arg, name);
++}
++
++void wlapi_free_timer(struct wlapi_timer *t)
++{
++	brcms_free_timer((struct brcms_timer *)t);
++}
++
++void
++wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
++{
++	brcms_add_timer((struct brcms_timer *)t, ms, periodic);
++}
++
++bool wlapi_del_timer(struct wlapi_timer *t)
++{
++	return brcms_del_timer((struct brcms_timer *)t);
++}
++
++void wlapi_intrson(struct phy_shim_info *physhim)
++{
++	brcms_intrson(physhim->wl);
++}
++
++u32 wlapi_intrsoff(struct phy_shim_info *physhim)
++{
++	return brcms_intrsoff(physhim->wl);
++}
++
++void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
++{
++	brcms_intrsrestore(physhim->wl, macintmask);
++}
++
++void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
++{
++	brcms_b_write_shm(physhim->wlc_hw, offset, v);
++}
++
++u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
++{
++	return brcms_b_read_shm(physhim->wlc_hw, offset);
++}
++
++void
++wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
++	       u16 val, int bands)
++{
++	brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
++}
++
++void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
++{
++	brcms_b_corereset(physhim->wlc_hw, flags);
++}
++
++void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
++{
++	brcms_c_suspend_mac_and_wait(physhim->wlc);
++}
++
++void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
++{
++	brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
++}
++
++void wlapi_enable_mac(struct phy_shim_info *physhim)
++{
++	brcms_c_enable_mac(physhim->wlc);
++}
++
++void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
++{
++	brcms_b_mctrl(physhim->wlc_hw, mask, val);
++}
++
++void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_phy_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
++{
++	brcms_b_bw_set(physhim->wlc_hw, bw);
++}
++
++u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
++{
++	return brcms_b_get_txant(physhim->wlc_hw);
++}
++
++void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
++{
++	brcms_b_macphyclk_set(physhim->wlc_hw, clk);
++}
++
++void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
++{
++	brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
++}
++
++void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
++{
++	brcms_b_core_phypll_reset(physhim->wlc_hw);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_set(physhim->wlc_hw,
++					BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
++{
++	brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
++					  BRCMS_WAKE_OVERRIDE_PHYREG);
++}
++
++void
++wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
++			      int len, void *buf)
++{
++	brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
++}
++
++u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
++{
++	return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
++}
++
++void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
++{
++}
++
++void
++wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
++		      int len, u32 sel)
++{
++	brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
++}
++
++void
++wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
++		    int l, u32 sel)
++{
++	brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+new file mode 100644
+index 0000000..2c5b66b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++/*
++ * phy_shim.h: stuff defined in phy_shim.c and included only by the phy
++ */
++
++#ifndef _BRCM_PHY_SHIM_H_
++#define _BRCM_PHY_SHIM_H_
++
++#include "types.h"
++
++#define RADAR_TYPE_NONE		0	/* Radar type None */
++#define RADAR_TYPE_ETSI_1	1	/* ETSI 1 Radar type */
++#define RADAR_TYPE_ETSI_2	2	/* ETSI 2 Radar type */
++#define RADAR_TYPE_ETSI_3	3	/* ETSI 3 Radar type */
++#define RADAR_TYPE_ITU_E	4	/* ITU E Radar type */
++#define RADAR_TYPE_ITU_K	5	/* ITU K Radar type */
++#define RADAR_TYPE_UNCLASSIFIED	6	/* Unclassified Radar type  */
++#define RADAR_TYPE_BIN5		7	/* long pulse radar type */
++#define RADAR_TYPE_STG2		8	/* staggered-2 radar */
++#define RADAR_TYPE_STG3		9	/* staggered-3 radar */
++#define RADAR_TYPE_FRA		10	/* French radar */
++
++/* French radar pulse widths */
++#define FRA_T1_20MHZ	52770
++#define FRA_T2_20MHZ	61538
++#define FRA_T3_20MHZ	66002
++#define FRA_T1_40MHZ	105541
++#define FRA_T2_40MHZ	123077
++#define FRA_T3_40MHZ	132004
++#define FRA_ERR_20MHZ	60
++#define FRA_ERR_40MHZ	120
++
++#define ANTSEL_NA		0 /* No boardlevel selection available */
++#define ANTSEL_2x4		1 /* 2x4 boardlevel selection available */
++#define ANTSEL_2x3		2 /* 2x3 CB2 boardlevel selection available */
++
++/* Rx Antenna diversity control values */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0 /* default antdiv setting */
++
++#define WL_ANT_RX_MAX		2	/* max 2 receive antennas */
++#define WL_ANT_HT_RX_MAX	3	/* max 3 receive antennas/cores */
++#define WL_ANT_IDX_1		0	/* antenna index 1 */
++#define WL_ANT_IDX_2		1	/* antenna index 2 */
++
++/* values for n_preamble_type */
++#define BRCMS_N_PREAMBLE_MIXEDMODE	0
++#define BRCMS_N_PREAMBLE_GF		1
++#define BRCMS_N_PREAMBLE_GF_BRCM          2
++
++#define WL_TX_POWER_RATES_LEGACY	45
++#define WL_TX_POWER_MCS20_FIRST	        12
++#define WL_TX_POWER_MCS20_NUM	        16
++#define WL_TX_POWER_MCS40_FIRST	        28
++#define WL_TX_POWER_MCS40_NUM	        17
++
++
++#define WL_TX_POWER_RATES	       101
++#define WL_TX_POWER_CCK_FIRST	       0
++#define WL_TX_POWER_CCK_NUM	       4
++/* Index for first 20MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM_FIRST	       4
++/* Index for first 20MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM20_CDD_FIRST   12
++/* Index for first 40MHz OFDM SISO rate */
++#define WL_TX_POWER_OFDM40_SISO_FIRST  52
++/* Index for first 40MHz OFDM CDD rate */
++#define WL_TX_POWER_OFDM40_CDD_FIRST   60
++#define WL_TX_POWER_OFDM_NUM	       8
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST   20
++/* Index for first 20MHz MCS CDD rate */
++#define WL_TX_POWER_MCS20_CDD_FIRST    28
++/* Index for first 20MHz MCS STBC rate */
++#define WL_TX_POWER_MCS20_STBC_FIRST   36
++/* Index for first 20MHz MCS SDM rate */
++#define WL_TX_POWER_MCS20_SDM_FIRST    44
++/* Index for first 40MHz MCS SISO rate */
++#define WL_TX_POWER_MCS40_SISO_FIRST   68
++/* Index for first 40MHz MCS CDD rate */
++#define WL_TX_POWER_MCS40_CDD_FIRST    76
++/* Index for first 40MHz MCS STBC rate */
++#define WL_TX_POWER_MCS40_STBC_FIRST   84
++/* Index for first 40MHz MCS SDM rate */
++#define WL_TX_POWER_MCS40_SDM_FIRST    92
++#define WL_TX_POWER_MCS_1_STREAM_NUM   8
++#define WL_TX_POWER_MCS_2_STREAM_NUM   8
++/* Index for 40MHz rate MCS 32 */
++#define WL_TX_POWER_MCS_32	       100
++#define WL_TX_POWER_MCS_32_NUM	       1
++
++/* sslpnphy specifics */
++/* Index for first 20MHz MCS SISO rate */
++#define WL_TX_POWER_MCS20_SISO_FIRST_SSN   12
++
++/* struct tx_power::flags bits */
++#define WL_TX_POWER_F_ENABLED	1
++#define WL_TX_POWER_F_HW	2
++#define WL_TX_POWER_F_MIMO	4
++#define WL_TX_POWER_F_SISO	8
++
++/* values to force tx/rx chain */
++#define BRCMS_N_TXRX_CHAIN0		0
++#define BRCMS_N_TXRX_CHAIN1		1
++
++struct brcms_phy;
++
++extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
++						 struct brcms_info *wl,
++						 struct brcms_c_info *wlc);
++extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
++
++/* PHY to WL utility functions */
++extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
++					    void (*fn) (struct brcms_phy *pi),
++					    void *arg, const char *name);
++extern void wlapi_free_timer(struct wlapi_timer *t);
++extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
++extern bool wlapi_del_timer(struct wlapi_timer *t);
++extern void wlapi_intrson(struct phy_shim_info *physhim);
++extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
++extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
++			       u32 macintmask);
++
++extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
++				 u16 v);
++extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
++extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
++			   u16 mask, u16 val, int bands);
++extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
++extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
++extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
++extern void wlapi_enable_mac(struct phy_shim_info *physhim);
++extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
++			     u32 val);
++extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
++extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
++extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
++extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
++						      physhim);
++extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
++							physhim);
++extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
++					  int len, void *buf);
++extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
++					 u8 rate);
++extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
++extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
++				  void *buf, int, u32 sel);
++extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
++				const void *buf, int, u32);
++
++extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
++				       u32 phy_mode);
++extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
++
++#endif				/* _BRCM_PHY_SHIM_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+new file mode 100644
+index 0000000..4931d29
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c
+@@ -0,0 +1,375 @@
++/*
++ * Copyright (c) 2011 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++
++#include <brcm_hw_ids.h>
++#include <chipcommon.h>
++#include <brcmu_utils.h>
++#include "pub.h"
++#include "aiutils.h"
++#include "pmu.h"
++#include "soc.h"
++
++/*
++ * external LPO crystal frequency
++ */
++#define EXT_ILP_HZ 32768
++
++/*
++ * Duration for ILP clock frequency measurment in milliseconds
++ *
++ * remark: 1000 must be an integer multiple of this duration
++ */
++#define ILP_CALC_DUR	10
++
++/* Fields in pmucontrol */
++#define	PCTL_ILP_DIV_MASK	0xffff0000
++#define	PCTL_ILP_DIV_SHIFT	16
++#define PCTL_PLL_PLLCTL_UPD	0x00000400	/* rev 2 */
++#define PCTL_NOILP_ON_WAIT	0x00000200	/* rev 1 */
++#define	PCTL_HT_REQ_EN		0x00000100
++#define	PCTL_ALP_REQ_EN		0x00000080
++#define	PCTL_XTALFREQ_MASK	0x0000007c
++#define	PCTL_XTALFREQ_SHIFT	2
++#define	PCTL_ILP_DIV_EN		0x00000002
++#define	PCTL_LPO_SEL		0x00000001
++
++/* ILP clock */
++#define	ILP_CLOCK		32000
++
++/* ALP clock on pre-PMU chips */
++#define	ALP_CLOCK		20000000
++
++/* pmustatus */
++#define PST_EXTLPOAVAIL	0x0100
++#define PST_WDRESET	0x0080
++#define	PST_INTPEND	0x0040
++#define	PST_SBCLKST	0x0030
++#define	PST_SBCLKST_ILP	0x0010
++#define	PST_SBCLKST_ALP	0x0020
++#define	PST_SBCLKST_HT	0x0030
++#define	PST_ALPAVAIL	0x0008
++#define	PST_HTAVAIL	0x0004
++#define	PST_RESINIT	0x0003
++
++/* PMU resource bit position */
++#define PMURES_BIT(bit)	(1 << (bit))
++
++/* PMU corerev and chip specific PLL controls.
++ * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
++ * number to differentiate different PLLs controlled by the same PMU rev.
++ */
++/* pllcontrol registers:
++ * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
++ * p1div, p2div, _bypass_sdmod
++ */
++#define PMU1_PLL0_PLLCTL0		0
++#define PMU1_PLL0_PLLCTL1		1
++#define PMU1_PLL0_PLLCTL2		2
++#define PMU1_PLL0_PLLCTL3		3
++#define PMU1_PLL0_PLLCTL4		4
++#define PMU1_PLL0_PLLCTL5		5
++
++/* pmu XtalFreqRatio */
++#define	PMU_XTALFREQ_REG_ILPCTR_MASK	0x00001FFF
++#define	PMU_XTALFREQ_REG_MEASURE_MASK	0x80000000
++#define	PMU_XTALFREQ_REG_MEASURE_SHIFT	31
++
++/* 4313 resources */
++#define	RES4313_BB_PU_RSRC		0
++#define	RES4313_ILP_REQ_RSRC		1
++#define	RES4313_XTAL_PU_RSRC		2
++#define	RES4313_ALP_AVAIL_RSRC		3
++#define	RES4313_RADIO_PU_RSRC		4
++#define	RES4313_BG_PU_RSRC		5
++#define	RES4313_VREG1P4_PU_RSRC		6
++#define	RES4313_AFE_PWRSW_RSRC		7
++#define	RES4313_RX_PWRSW_RSRC		8
++#define	RES4313_TX_PWRSW_RSRC		9
++#define	RES4313_BB_PWRSW_RSRC		10
++#define	RES4313_SYNTH_PWRSW_RSRC	11
++#define	RES4313_MISC_PWRSW_RSRC		12
++#define	RES4313_BB_PLL_PWRSW_RSRC	13
++#define	RES4313_HT_AVAIL_RSRC		14
++#define	RES4313_MACPHY_CLK_AVAIL_RSRC	15
++
++/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
++static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
++{
++	u32 min_mask = 0, max_mask = 0;
++	uint rsrcs;
++
++	/* # resources */
++	rsrcs = (ai_get_pmucaps(sih) & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
++
++	/* determine min/max rsrc masks */
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		/* ??? */
++		break;
++
++	case BCM4313_CHIP_ID:
++		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
++		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
++		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
++		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
++		max_mask = 0xffff;
++		break;
++	default:
++		break;
++	}
++
++	*pmin = min_mask;
++	*pmax = max_mask;
++}
++
++void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid)
++{
++	u32 tmp = 0;
++	struct bcma_device *core;
++
++	/* switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++		if (spuravoid == 1) {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11500010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000C0C06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x0F600a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x2001E920);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		} else {
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x11100010);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL1);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x000c0c06);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL2);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x03000a08);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL3);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x00000000);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL4);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x200005c0);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
++				     PMU1_PLL0_PLLCTL5);
++			bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
++				     0x88888815);
++		}
++		tmp = 1 << 10;
++		break;
++
++	default:
++		/* bail out */
++		return;
++	}
++
++	bcma_set32(core, CHIPCREGOFFS(pmucontrol), tmp);
++}
++
++u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
++{
++	uint delay = PMU_MAX_TRANSITION_DLY;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		delay = 3700;
++		break;
++	default:
++		break;
++	}
++
++	return (u16) delay;
++}
++
++/* Read/write a chipcontrol reg */
++u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a regcontrol reg */
++u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_data),
++			 mask, val);
++}
++
++/* Read/write a pllcontrol reg */
++u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_addr), ~0, reg);
++	return ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_data),
++			 mask, val);
++}
++
++/* PMU PLL update */
++void si_pmu_pllupd(struct si_pub *sih)
++{
++	ai_cc_reg(sih, offsetof(struct chipcregs, pmucontrol),
++		  PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
++}
++
++/* query alp/xtal clock frequency */
++u32 si_pmu_alp_clock(struct si_pub *sih)
++{
++	u32 clock = ALP_CLOCK;
++
++	/* bail out with default */
++	if (!(ai_get_cccaps(sih) & CC_CAP_PMU))
++		return clock;
++
++	switch (ai_get_chip_id(sih)) {
++	case BCM43224_CHIP_ID:
++	case BCM43225_CHIP_ID:
++	case BCM4313_CHIP_ID:
++		/* always 20Mhz */
++		clock = 20000 * 1000;
++		break;
++	default:
++		break;
++	}
++
++	return clock;
++}
++
++/* initialize PMU */
++void si_pmu_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++
++	/* select chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (ai_get_pmurev(sih) == 1)
++		bcma_mask32(core, CHIPCREGOFFS(pmucontrol),
++			    ~PCTL_NOILP_ON_WAIT);
++	else if (ai_get_pmurev(sih) >= 2)
++		bcma_set32(core, CHIPCREGOFFS(pmucontrol), PCTL_NOILP_ON_WAIT);
++}
++
++/* initialize PMU resources */
++void si_pmu_res_init(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 min_mask = 0, max_mask = 0;
++
++	/* select to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	/* Determine min/max rsrc masks */
++	si_pmu_res_masks(sih, &min_mask, &max_mask);
++
++	/* It is required to program max_mask first and then min_mask */
++
++	/* Program max resource mask */
++
++	if (max_mask)
++		bcma_write32(core, CHIPCREGOFFS(max_res_mask), max_mask);
++
++	/* Program min resource mask */
++
++	if (min_mask)
++		bcma_write32(core, CHIPCREGOFFS(min_res_mask), min_mask);
++
++	/* Add some delay; allow resources to come up and settle. */
++	mdelay(2);
++}
++
++u32 si_pmu_measure_alpclk(struct si_pub *sih)
++{
++	struct bcma_device *core;
++	u32 alp_khz;
++
++	if (ai_get_pmurev(sih) < 10)
++		return 0;
++
++	/* Remember original core before switch to chipc */
++	core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
++
++	if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
++		u32 ilp_ctr, alp_hz;
++
++		/*
++		 * Enable the reg to measure the freq,
++		 * in case it was disabled before
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
++			    1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
++
++		/* Delay for well over 4 ILP clocks */
++		udelay(1000);
++
++		/* Read the latched number of ALP ticks per 4 ILP ticks */
++		ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
++			  PMU_XTALFREQ_REG_ILPCTR_MASK;
++
++		/*
++		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
++		 * bit to save power
++		 */
++		bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
++
++		/* Calculate ALP frequency */
++		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
++
++		/*
++		 * Round to nearest 100KHz, and at
++		 * the same time convert to KHz
++		 */
++		alp_khz = (alp_hz + 50000) / 100000 * 100;
++	} else
++		alp_khz = 0;
++
++	return alp_khz;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+new file mode 100644
+index 0000000..3e39c5e
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _BRCM_PMU_H_
++#define _BRCM_PMU_H_
++
++#include "types.h"
++
++extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih);
++extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable);
++extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern u32 si_pmu_alp_clock(struct si_pub *sih);
++extern void si_pmu_pllupd(struct si_pub *sih);
++extern void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid);
++extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
++extern void si_pmu_init(struct si_pub *sih);
++extern void si_pmu_res_init(struct si_pub *sih);
++extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
++
++#endif /* _BRCM_PMU_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+new file mode 100644
+index 0000000..aa5d67f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+@@ -0,0 +1,372 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_PUB_H_
++#define _BRCM_PUB_H_
++
++#include <linux/bcma/bcma.h>
++#include <brcmu_wifi.h>
++#include "types.h"
++#include "defs.h"
++
++#define	BRCMS_NUMRATES	16	/* max # of rates in a rateset */
++
++/* phy types */
++#define	PHY_TYPE_A	0	/* Phy type A */
++#define	PHY_TYPE_G	2	/* Phy type G */
++#define	PHY_TYPE_N	4	/* Phy type N */
++#define	PHY_TYPE_LP	5	/* Phy type Low Power A/B/G */
++#define	PHY_TYPE_SSN	6	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCN	8	/* Phy type Single Stream N */
++#define	PHY_TYPE_LCNXN	9	/* Phy type 2-stream N */
++#define	PHY_TYPE_HT	7	/* Phy type 3-Stream N */
++
++/* bw */
++#define BRCMS_10_MHZ	10	/* 10Mhz nphy channel bandwidth */
++#define BRCMS_20_MHZ	20	/* 20Mhz nphy channel bandwidth */
++#define BRCMS_40_MHZ	40	/* 40Mhz nphy channel bandwidth */
++
++#define	BRCMS_RSSI_MINVAL	-200	/* Low value, e.g. for forcing roam */
++#define	BRCMS_RSSI_NO_SIGNAL	-91	/* NDIS RSSI link quality cutoffs */
++#define	BRCMS_RSSI_VERY_LOW	-80	/* Very low quality cutoffs */
++#define	BRCMS_RSSI_LOW		-70	/* Low quality cutoffs */
++#define	BRCMS_RSSI_GOOD		-68	/* Good quality cutoffs */
++#define	BRCMS_RSSI_VERY_GOOD	-58	/* Very good quality cutoffs */
++#define	BRCMS_RSSI_EXCELLENT	-57	/* Excellent quality cutoffs */
++
++/* a large TX Power as an init value to factor out of min() calculations,
++ * keep low enough to fit in an s8, units are .25 dBm
++ */
++#define BRCMS_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
++
++/* rate related definitions */
++#define	BRCMS_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
++#define	BRCMS_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
++
++/* legacy rx Antenna diversity for SISO rates */
++#define	ANT_RX_DIV_FORCE_0	0	/* Use antenna 0 */
++#define	ANT_RX_DIV_FORCE_1	1	/* Use antenna 1 */
++#define	ANT_RX_DIV_START_1	2	/* Choose starting with 1 */
++#define	ANT_RX_DIV_START_0	3	/* Choose starting with 0 */
++#define	ANT_RX_DIV_ENABLE	3	/* APHY bbConfig Enable RX Diversity */
++/* default antdiv setting */
++#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0
++
++/* legacy rx Antenna diversity for SISO rates */
++/* Tx on antenna 0, "legacy term Main" */
++#define ANT_TX_FORCE_0		0
++/* Tx on antenna 1, "legacy term Aux" */
++#define ANT_TX_FORCE_1		1
++/* Tx on phy's last good Rx antenna */
++#define ANT_TX_LAST_RX		3
++/* driver's default tx antenna setting */
++#define ANT_TX_DEF		3
++
++/* Tx Chain values */
++/* def bitmap of txchain */
++#define TXCHAIN_DEF		0x1
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_NPHY	0x3
++/* default bitmap of tx chains for nphy */
++#define TXCHAIN_DEF_HTPHY	0x7
++/* def bitmap of rxchain */
++#define RXCHAIN_DEF		0x1
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_NPHY	0x3
++/* default bitmap of rx chains for nphy */
++#define RXCHAIN_DEF_HTPHY	0x7
++/* no antenna switch */
++#define ANTSWITCH_NONE		0
++/* antenna switch on 4321CB2, 2of3 */
++#define ANTSWITCH_TYPE_1	1
++/* antenna switch on 4321MPCI, 2of3 */
++#define ANTSWITCH_TYPE_2	2
++/* antenna switch on 4322, 2of3 */
++#define ANTSWITCH_TYPE_3	3
++
++#define RXBUFSZ		PKTBUFSZ
++
++#define MAX_STREAMS_SUPPORTED	4	/* max number of streams supported */
++
++struct brcm_rateset {
++	/* # rates in this set */
++	u32 count;
++	/* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[WL_NUMRATES];
++};
++
++struct brcms_c_rateset {
++	uint count;		/* number of rates in rates[] */
++	 /* rates in 500kbps units w/hi bit set if basic */
++	u8 rates[BRCMS_NUMRATES];
++	u8 htphy_membership;	/* HT PHY Membership */
++	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
++};
++
++/* All the HT-specific default advertised capabilities (including AMPDU)
++ * should be grouped here at one place
++ */
++#define AMPDU_DEF_MPDU_DENSITY	6	/* default mpdu density (110 ==> 4us) */
++
++/* wlc internal bss_info */
++struct brcms_bss_info {
++	u8 BSSID[ETH_ALEN];	/* network BSSID */
++	u16 flags;		/* flags for internal attributes */
++	u8 SSID_len;		/* the length of SSID */
++	u8 SSID[32];		/* SSID string */
++	s16 RSSI;		/* receive signal strength (in dBm) */
++	s16 SNR;		/* receive signal SNR in dB */
++	u16 beacon_period;	/* units are Kusec */
++	u16 chanspec;	/* Channel num, bw, ctrl_sb and band */
++	struct brcms_c_rateset rateset;	/* supported rates */
++};
++
++#define MAC80211_PROMISC_BCNS	(1 << 0)
++#define MAC80211_SCAN		(1 << 1)
++
++/*
++ * Public portion of common driver state structure.
++ * The wlc handle points at this.
++ */
++struct brcms_pub {
++	struct brcms_c_info *wlc;
++	struct ieee80211_hw *ieee_hw;
++	struct scb_ampdu *global_ampdu;
++	uint mac80211_state;
++	uint unit;		/* device instance number */
++	uint corerev;		/* core revision */
++	struct si_pub *sih;	/* SI handle (cookie for siutils calls) */
++	bool up;		/* interface up and running */
++	bool hw_off;		/* HW is off */
++	bool hw_up;		/* one time hw up/down */
++	bool _piomode;		/* true if pio mode */
++	uint _nbands;		/* # bands supported */
++	uint now;		/* # elapsed seconds */
++
++	bool delayed_down;	/* down delayed */
++	bool associated;	/* true:part of [I]BSS, false: not */
++	/* (union of stas_associated, aps_associated) */
++	bool _ampdu;		/* ampdu enabled or not */
++	u8 _n_enab;		/* bitmap of 11N + HT support */
++
++	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
++
++	int bcmerror;		/* last bcm error */
++
++	u32 radio_disabled;	/* bit vector for radio disabled reasons */
++
++	u16 boardrev;	/* version # of particular board */
++	u8 sromrev;		/* version # of the srom */
++	char srom_ccode[BRCM_CNTRY_BUF_SZ];	/* Country Code in SROM */
++	u32 boardflags;	/* Board specific flags from srom */
++	u32 boardflags2;	/* More board flags if sromrev >= 4 */
++	bool phy_11ncapable;	/* the PHY/HW is capable of 802.11N */
++
++	struct wl_cnt *_cnt;	/* low-level counters in driver */
++};
++
++enum wlc_par_id {
++	IOV_MPC = 1,
++	IOV_RTSTHRESH,
++	IOV_QTXPOWER,
++	IOV_BCN_LI_BCN		/* Beacon listen interval in # of beacons */
++};
++
++/***********************************************
++ * Feature-related macros to optimize out code *
++ * *********************************************
++ */
++
++#define ENAB_1x1	0x01
++#define ENAB_2x2	0x02
++#define ENAB_3x3	0x04
++#define ENAB_4x4	0x08
++#define SUPPORT_11N	(ENAB_1x1|ENAB_2x2)
++#define SUPPORT_HT	(ENAB_1x1|ENAB_2x2|ENAB_3x3)
++
++/* WL11N Support */
++#define AMPDU_AGG_HOST	1
++
++/* pri is priority encoded in the packet. This maps the Packet priority to
++ * enqueue precedence as defined in wlc_prec_map
++ */
++extern const u8 wlc_prio2prec_map[];
++#define BRCMS_PRIO_TO_PREC(pri)	wlc_prio2prec_map[(pri) & 7]
++
++#define	BRCMS_PREC_COUNT	16	/* Max precedence level implemented */
++
++/* Mask to describe all precedence levels */
++#define BRCMS_PREC_BMP_ALL		MAXBITVAL(BRCMS_PREC_COUNT)
++
++/*
++ * This maps priority to one precedence higher - Used by PS-Poll response
++ * packets to simulate enqueue-at-head operation, but still maintain the
++ * order on the queue
++ */
++#define BRCMS_PRIO_TO_HI_PREC(pri)	min(BRCMS_PRIO_TO_PREC(pri) + 1,\
++					    BRCMS_PREC_COUNT - 1)
++
++/* Define a bitmap of precedences comprised by each AC */
++#define BRCMS_PREC_BMP_AC_BE	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
++#define BRCMS_PREC_BMP_AC_BK	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
++#define BRCMS_PREC_BMP_AC_VI	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
++#define BRCMS_PREC_BMP_AC_VO	(NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
++			NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
++			NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
++
++/* network protection config */
++#define	BRCMS_PROT_G_SPEC		1	/* SPEC g protection */
++#define	BRCMS_PROT_G_OVR		2	/* SPEC g prot override */
++#define	BRCMS_PROT_G_USER		3	/* gmode specified by user */
++#define	BRCMS_PROT_OVERLAP	4	/* overlap */
++#define	BRCMS_PROT_N_USER		10	/* nmode specified by user */
++#define	BRCMS_PROT_N_CFG		11	/* n protection */
++#define	BRCMS_PROT_N_CFG_OVR	12	/* n protection override */
++#define	BRCMS_PROT_N_NONGF	13	/* non-GF protection */
++#define	BRCMS_PROT_N_NONGF_OVR	14	/* non-GF protection override */
++#define	BRCMS_PROT_N_PAM_OVR	15	/* n preamble override */
++#define	BRCMS_PROT_N_OBSS		16	/* non-HT OBSS present */
++
++/*
++ * 54g modes (basic bits may still be overridden)
++ *
++ * GMODE_LEGACY_B
++ *	Rateset: 1b, 2b, 5.5, 11
++ *	Preamble: Long
++ *	Shortslot: Off
++ * GMODE_AUTO
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: Auto
++ * GMODE_ONLY
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
++ *	Extended Rateset: 6b, 9, 12b, 48
++ *	Preamble: Short required
++ *	Shortslot: Auto
++ * GMODE_B_DEFERRED
++ *	Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
++ *	Extended Rateset: 6, 9, 12, 48
++ *	Preamble: Long
++ *	Shortslot: On
++ * GMODE_PERFORMANCE
++ *	Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
++ *	Preamble: Short required
++ *	Shortslot: On and required
++ * GMODE_LRS
++ *	Rateset: 1b, 2b, 5.5b, 11b
++ *	Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
++ *	Preamble: Long
++ *	Shortslot: Auto
++ */
++#define GMODE_LEGACY_B		0
++#define GMODE_AUTO		1
++#define GMODE_ONLY		2
++#define GMODE_B_DEFERRED	3
++#define GMODE_PERFORMANCE	4
++#define GMODE_LRS		5
++#define GMODE_MAX		6
++
++/* MCS values greater than this enable multiple streams */
++#define HIGHEST_SINGLE_STREAM_MCS	7
++
++#define	MAXBANDS		2	/* Maximum #of bands */
++
++/* max number of antenna configurations */
++#define ANT_SELCFG_MAX		4
++
++struct brcms_antselcfg {
++	u8 ant_config[ANT_SELCFG_MAX];	/* antenna configuration */
++	u8 num_antcfg;	/* number of available antenna configurations */
++};
++
++/* common functions for every port */
++extern struct brcms_c_info *
++brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
++	       bool piomode, uint *perr);
++extern uint brcms_c_detach(struct brcms_c_info *wlc);
++extern int brcms_c_up(struct brcms_c_info *wlc);
++extern uint brcms_c_down(struct brcms_c_info *wlc);
++
++extern bool brcms_c_chipmatch(u16 vendor, u16 device);
++extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx);
++extern void brcms_c_reset(struct brcms_c_info *wlc);
++
++extern void brcms_c_intrson(struct brcms_c_info *wlc);
++extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
++extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
++extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
++extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc);
++extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
++extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
++				     struct sk_buff *sdu,
++				     struct ieee80211_hw *hw);
++extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
++extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx,
++				   int val);
++extern int brcms_c_get_header_len(void);
++extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc,
++				  int match_reg_offset,
++				  const u8 *addr);
++extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci,
++			      const struct ieee80211_tx_queue_params *arg,
++			      bool suspend);
++extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc);
++extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
++			    struct ieee80211_sta *sta, u16 tid);
++extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
++					 u8 ba_wsize, uint max_rx_ampdu_bytes);
++extern int brcms_c_module_register(struct brcms_pub *pub,
++				   const char *name, struct brcms_info *hdl,
++				   int (*down_fn)(void *handle));
++extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
++				     struct brcms_info *hdl);
++extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc);
++extern void brcms_c_enable_mac(struct brcms_c_info *wlc);
++extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
++extern void brcms_c_scan_start(struct brcms_c_info *wlc);
++extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
++extern int brcms_c_get_curband(struct brcms_c_info *wlc);
++extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
++					   bool drop);
++extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
++extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
++extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
++				 struct brcm_rateset *currs);
++extern int brcms_c_set_rateset(struct brcms_c_info *wlc,
++					struct brcm_rateset *rs);
++extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period);
++extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx);
++extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc,
++				    s8 sslot_override);
++extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
++					u8 interval);
++extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
++extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
++extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
++extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
++
++#endif				/* _BRCM_PUB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.c b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+new file mode 100644
+index 0000000..0a0c0ad
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.c
+@@ -0,0 +1,514 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <brcmu_wifi.h>
++#include <brcmu_utils.h>
++
++#include "d11.h"
++#include "pub.h"
++#include "rate.h"
++
++/*
++ * Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate
++ * value
++ */
++const u8 rate_info[BRCM_MAXRATE + 1] = {
++	/*  0     1     2     3     4     5     6     7     8     9 */
++/*   0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
++/*  20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
++/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
++/*  50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++/*  90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
++/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
++};
++
++/* rates are in units of Kbps */
++const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = {
++	/* MCS  0: SS 1, MOD: BPSK,  CR 1/2 */
++	{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
++	 BRCM_RATE_6M},
++	/* MCS  1: SS 1, MOD: QPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
++	 BRCM_RATE_12M},
++	/* MCS  2: SS 1, MOD: QPSK,  CR 3/4 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
++	 BRCM_RATE_18M},
++	/* MCS  3: SS 1, MOD: 16QAM, CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
++	 BRCM_RATE_24M},
++	/* MCS  4: SS 1, MOD: 16QAM, CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
++	 BRCM_RATE_36M},
++	/* MCS  5: SS 1, MOD: 64QAM, CR 2/3 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
++	 BRCM_RATE_48M},
++	/* MCS  6: SS 1, MOD: 64QAM, CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
++	 BRCM_RATE_54M},
++	/* MCS  7: SS 1, MOD: 64QAM, CR 5/6 */
++	{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
++	 BRCM_RATE_54M},
++	/* MCS  8: SS 2, MOD: BPSK,  CR 1/2 */
++	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
++	 BRCM_RATE_6M},
++	/* MCS  9: SS 2, MOD: QPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
++	 BRCM_RATE_12M},
++	/* MCS 10: SS 2, MOD: QPSK,  CR 3/4 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
++	 BRCM_RATE_18M},
++	/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
++	 BRCM_RATE_24M},
++	/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
++	 BRCM_RATE_36M},
++	/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
++	 BRCM_RATE_48M},
++	/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
++	 BRCM_RATE_54M},
++	/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
++	{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
++	 BRCM_RATE_54M},
++	/* MCS 16: SS 3, MOD: BPSK,  CR 1/2 */
++	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
++	 BRCM_RATE_6M},
++	/* MCS 17: SS 3, MOD: QPSK,  CR 1/2 */
++	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
++	 BRCM_RATE_12M},
++	/* MCS 18: SS 3, MOD: QPSK,  CR 3/4 */
++	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
++	 BRCM_RATE_18M},
++	/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
++	 BRCM_RATE_24M},
++	/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
++	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
++	 BRCM_RATE_36M},
++	/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
++	 BRCM_RATE_48M},
++	/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
++	{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
++	 BRCM_RATE_54M},
++	/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
++	{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
++	 BRCM_RATE_54M},
++	/* MCS 24: SS 4, MOD: BPSK,  CR 1/2 */
++	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
++	 BRCM_RATE_6M},
++	/* MCS 25: SS 4, MOD: QPSK,  CR 1/2 */
++	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
++	 BRCM_RATE_12M},
++	/* MCS 26: SS 4, MOD: QPSK,  CR 3/4 */
++	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
++	 BRCM_RATE_18M},
++	/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
++	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
++	 BRCM_RATE_24M},
++	/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
++	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
++	 BRCM_RATE_36M},
++	/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
++	{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
++	 BRCM_RATE_48M},
++	/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
++	{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
++	 BRCM_RATE_54M},
++	/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
++	{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
++	 BRCM_RATE_54M},
++	/* MCS 32: SS 1, MOD: BPSK,  CR 1/2 */
++	{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M},
++};
++
++/*
++ * phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
++ * Number of spatial streams: always 1 other fields: refer to table 78 of
++ * section 17.3.2.2 of the original .11a standard
++ */
++struct legacy_phycfg {
++	u32 rate_ofdm;	/* ofdm mac rate */
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++};
++
++/* Number of legacy_rate_cfg entries in the table */
++#define LEGACY_PHYCFG_TABLE_SIZE	12
++
++/*
++ * In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate
++ * Eventually MIMOPHY would also be converted to this format
++ * 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps
++ */
++static const struct
++legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
++	{BRCM_RATE_1M, 0x00},	/* CCK  1Mbps,  data rate  0 */
++	{BRCM_RATE_2M, 0x08},	/* CCK  2Mbps,  data rate  1 */
++	{BRCM_RATE_5M5, 0x10},	/* CCK  5.5Mbps,  data rate  2 */
++	{BRCM_RATE_11M, 0x18},	/* CCK  11Mbps,  data rate   3 */
++	/* OFDM  6Mbps,  code rate 1/2, BPSK,   1 spatial stream */
++	{BRCM_RATE_6M, 0x00},
++	/* OFDM  9Mbps,  code rate 3/4, BPSK,   1 spatial stream */
++	{BRCM_RATE_9M, 0x02},
++	/* OFDM  12Mbps, code rate 1/2, QPSK,   1 spatial stream */
++	{BRCM_RATE_12M, 0x08},
++	/* OFDM  18Mbps, code rate 3/4, QPSK,   1 spatial stream */
++	{BRCM_RATE_18M, 0x0A},
++	/* OFDM  24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_24M, 0x10},
++	/* OFDM  36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
++	{BRCM_RATE_36M, 0x12},
++	/* OFDM  48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_48M, 0x19},
++	/* OFDM  54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
++	{BRCM_RATE_54M, 0x1A},
++};
++
++/* Hardware rates (also encodes default basic rates) */
++
++const struct brcms_c_rateset cck_ofdm_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48, */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* Default ratesets that include MCS32 for 40BW channels */
++static const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = {
++	12,
++	/*  1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48 */
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/* 54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++static const struct brcms_c_rateset ofdm_40bw_mimo_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_ofdm_rates = {
++	12,
++	/*  1b,   2b, 5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,*/
++	{ 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
++	/*54 Mbps */
++	  0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset gphy_legacy_rates = {
++	4,
++	/*  1b,   2b,   5.5b, 11b Mbps */
++	{ 0x82, 0x84, 0x8b, 0x96},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset ofdm_rates = {
++	8,
++	/*  6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
++	{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++const struct brcms_c_rateset cck_rates = {
++	4,
++	/*  1b,   2b,   5.5,  11 Mbps */
++	{ 0x82, 0x84, 0x0b, 0x16},
++	0x00,
++	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++	  0x00, 0x00, 0x00, 0x00, 0x00}
++};
++
++/* check if rateset is valid.
++ * if check_brate is true, rateset without a basic rate is considered NOT valid.
++ */
++static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate)
++{
++	uint idx;
++
++	if (!rs->count)
++		return false;
++
++	if (!check_brate)
++		return true;
++
++	/* error if no basic rates */
++	for (idx = 0; idx < rs->count; idx++) {
++		if (rs->rates[idx] & BRCMS_RATE_FLAG)
++			return true;
++	}
++	return false;
++}
++
++void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams)
++{
++	int i;
++	for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
++		rs->mcs[i] = 0;
++}
++
++/*
++ * filter based on hardware rateset, and sort filtered rateset with basic
++ * bit(s) preserved, and check if resulting rateset is valid.
++*/
++bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				   const struct brcms_c_rateset *hw_rs,
++				   bool check_brate, u8 txstreams)
++{
++	u8 rateset[BRCM_MAXRATE + 1];
++	u8 r;
++	uint count;
++	uint i;
++
++	memset(rateset, 0, sizeof(rateset));
++	count = rs->count;
++
++	for (i = 0; i < count; i++) {
++		/* mask off "basic rate" bit, BRCMS_RATE_FLAG */
++		r = (int)rs->rates[i] & BRCMS_RATE_MASK;
++		if ((r > BRCM_MAXRATE) || (rate_info[r] == 0))
++			continue;
++		rateset[r] = rs->rates[i];	/* preserve basic bit! */
++	}
++
++	/* fill out the rates in order, looking at only supported rates */
++	count = 0;
++	for (i = 0; i < hw_rs->count; i++) {
++		r = hw_rs->rates[i] & BRCMS_RATE_MASK;
++		if (rateset[r])
++			rs->rates[count++] = rateset[r];
++	}
++
++	rs->count = count;
++
++	/* only set the mcs rate bit if the equivalent hw mcs bit is set */
++	for (i = 0; i < MCSSET_LEN; i++)
++		rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
++
++	if (brcms_c_rateset_valid(rs, check_brate))
++		return true;
++	else
++		return false;
++}
++
++/* calculate the rate of a rx'd frame and return it as a ratespec */
++u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp)
++{
++	int phy_type;
++	u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
++
++	phy_type =
++	    ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
++
++	if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
++	    (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
++		switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
++		case PRXS0_CCK:
++			rspec =
++				cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++			break;
++		case PRXS0_OFDM:
++			rspec =
++			    ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++			break;
++		case PRXS0_PREN:
++			rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
++			if (plcp[0] & MIMO_PLCP_40MHZ) {
++				/* indicate rspec is for 40 MHz mode */
++				rspec &= ~RSPEC_BW_MASK;
++				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
++			}
++			break;
++		case PRXS0_STDN:
++			/* fallthru */
++		default:
++			/* not supported, error condition */
++			break;
++		}
++		if (plcp3_issgi(plcp[3]))
++			rspec |= RSPEC_SHORT_GI;
++	} else
++	    if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
++		rspec = ofdm_phy2mac_rate(
++				((struct ofdm_phy_hdr *) plcp)->rlpt[0]);
++	else
++		rspec = cck_phy2mac_rate(
++				((struct cck_phy_hdr *) plcp)->signal);
++
++	return rspec;
++}
++
++/* copy rateset src to dst as-is (no masking or sorting) */
++void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			  struct brcms_c_rateset *dst)
++{
++	memcpy(dst, src, sizeof(struct brcms_c_rateset));
++}
++
++/*
++ * Copy and selectively filter one rateset to another.
++ * 'basic_only' means only copy basic rates.
++ * 'rates' indicates cck (11b) and ofdm rates combinations.
++ *    - 0: cck and ofdm
++ *    - 1: cck only
++ *    - 2: ofdm only
++ * 'xmask' is the copy mask (typically 0x7f or 0xff).
++ */
++void
++brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst,
++		       bool basic_only, u8 rates, uint xmask, bool mcsallow)
++{
++	uint i;
++	uint r;
++	uint count;
++
++	count = 0;
++	for (i = 0; i < src->count; i++) {
++		r = src->rates[i];
++		if (basic_only && !(r & BRCMS_RATE_FLAG))
++			continue;
++		if (rates == BRCMS_RATES_CCK &&
++		    is_ofdm_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		if (rates == BRCMS_RATES_OFDM &&
++		    is_cck_rate((r & BRCMS_RATE_MASK)))
++			continue;
++		dst->rates[count++] = r & xmask;
++	}
++	dst->count = count;
++	dst->htphy_membership = src->htphy_membership;
++
++	if (mcsallow && rates != BRCMS_RATES_CCK)
++		memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
++	else
++		brcms_c_rateset_mcs_clear(dst);
++}
++
++/* select rateset for a given phy_type and bandtype and filter it, sort it
++ * and fill rs_tgt with result
++ */
++void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw,
++			uint phy_type, int bandtype, bool cck_only,
++			uint rate_mask, bool mcsallow, u8 bw, u8 txstreams)
++{
++	const struct brcms_c_rateset *rs_dflt;
++	struct brcms_c_rateset rs_sel;
++	if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
++	    (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
++		if (bandtype == BRCM_BAND_5G)
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
++		else
++			rs_dflt = (bw == BRCMS_20_MHZ ?
++				   &cck_ofdm_mimo_rates :
++				   &cck_ofdm_40bw_mimo_rates);
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
++		rs_dflt = (bandtype == BRCM_BAND_5G) ?
++			  &ofdm_rates : &cck_ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
++		rs_dflt = &ofdm_rates;
++	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
++		rs_dflt = &cck_ofdm_rates;
++	} else {
++		/* should not happen, error condition */
++		rs_dflt = &cck_rates;	/* force cck */
++	}
++
++	/* if hw rateset is not supplied, assign selected rateset to it */
++	if (!rs_hw)
++		rs_hw = rs_dflt;
++
++	brcms_c_rateset_copy(rs_dflt, &rs_sel);
++	brcms_c_rateset_mcs_upd(&rs_sel, txstreams);
++	brcms_c_rateset_filter(&rs_sel, rs_tgt, false,
++			   cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM,
++			   rate_mask, mcsallow);
++	brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
++					   mcsallow ? txstreams : 1);
++}
++
++s16 brcms_c_rate_legacy_phyctl(uint rate)
++{
++	uint i;
++	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
++		if (rate == legacy_phycfg_table[i].rate_ofdm)
++			return legacy_phycfg_table[i].tx_phy_ctl3;
++
++	return -1;
++}
++
++void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset)
++{
++	uint i;
++	for (i = 0; i < MCSSET_LEN; i++)
++		rateset->mcs[i] = 0;
++}
++
++void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams)
++{
++	memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
++	brcms_c_rateset_mcs_upd(rateset, txstreams);
++}
++
++/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
++void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw)
++{
++	if (bw == BRCMS_40_MHZ)
++		setbit(rateset->mcs, 32);
++	else
++		clrbit(rateset->mcs, 32);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+new file mode 100644
+index 0000000..980d578
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h
+@@ -0,0 +1,249 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_RATE_H_
++#define _BRCM_RATE_H_
++
++#include "types.h"
++#include "d11.h"
++#include "phy_hal.h"
++
++extern const u8 rate_info[];
++extern const struct brcms_c_rateset cck_ofdm_mimo_rates;
++extern const struct brcms_c_rateset ofdm_mimo_rates;
++extern const struct brcms_c_rateset cck_ofdm_rates;
++extern const struct brcms_c_rateset ofdm_rates;
++extern const struct brcms_c_rateset cck_rates;
++extern const struct brcms_c_rateset gphy_legacy_rates;
++extern const struct brcms_c_rateset rate_limit_1_2;
++
++struct brcms_mcs_info {
++	/* phy rate in kbps [20Mhz] */
++	u32 phy_rate_20;
++	/* phy rate in kbps [40Mhz] */
++	u32 phy_rate_40;
++	/* phy rate in kbps [20Mhz] with SGI */
++	u32 phy_rate_20_sgi;
++	/* phy rate in kbps [40Mhz] with SGI */
++	u32 phy_rate_40_sgi;
++	/* phy ctl byte 3, code rate, modulation type, # of streams */
++	u8 tx_phy_ctl3;
++	/* matching legacy ofdm rate in 500bkps */
++	u8 leg_ofdm;
++};
++
++#define BRCMS_MAXMCS	32	/* max valid mcs index */
++#define MCS_TABLE_SIZE	33	/* Number of mcs entries in the table */
++extern const struct brcms_mcs_info mcs_table[];
++
++#define MCS_TXS_MASK	0xc0	/* num tx streams - 1 bit mask */
++#define MCS_TXS_SHIFT	6	/* num tx streams - 1 bit shift */
++
++/* returns num tx streams - 1 */
++static inline u8 mcs_2_txstreams(u8 mcs)
++{
++	return (mcs_table[mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT;
++}
++
++static inline uint mcs_2_rate(u8 mcs, bool is40, bool sgi)
++{
++	if (sgi) {
++		if (is40)
++			return mcs_table[mcs].phy_rate_40_sgi;
++		return mcs_table[mcs].phy_rate_20_sgi;
++	}
++	if (is40)
++		return mcs_table[mcs].phy_rate_40;
++
++	return mcs_table[mcs].phy_rate_20;
++}
++
++/* Macro to use the rate_info table */
++#define	BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */
++
++/*
++ * rate spec : holds rate and mode specific information required to generate a
++ * tx frame. Legacy CCK and OFDM information is held in the same manner as was
++ * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO
++ * specific information
++ */
++
++/* rate spec bit fields */
++
++/* Either 500Kbps units or MIMO MCS idx */
++#define RSPEC_RATE_MASK		0x0000007F
++/* mimo MCS is stored in RSPEC_RATE_MASK */
++#define RSPEC_MIMORATE		0x08000000
++/* mimo bw mask */
++#define RSPEC_BW_MASK		0x00000700
++/* mimo bw shift */
++#define RSPEC_BW_SHIFT		8
++/* mimo Space/Time/Frequency mode mask */
++#define RSPEC_STF_MASK		0x00003800
++/* mimo Space/Time/Frequency mode shift */
++#define RSPEC_STF_SHIFT		11
++/* mimo coding type mask */
++#define RSPEC_CT_MASK		0x0000C000
++/* mimo coding type shift */
++#define RSPEC_CT_SHIFT		14
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_MASK		0x00300000
++/* mimo num STC streams per PLCP defn. */
++#define RSPEC_STC_SHIFT		20
++/* mimo bit indicates adv coding in use */
++#define RSPEC_LDPC_CODING	0x00400000
++/* mimo bit indicates short GI in use */
++#define RSPEC_SHORT_GI		0x00800000
++/* bit indicates override both rate & mode */
++#define RSPEC_OVERRIDE		0x80000000
++/* bit indicates override rate only */
++#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000
++
++static inline bool rspec_active(u32 rspec)
++{
++	return rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE);
++}
++
++static inline u8 rspec_phytxbyte2(u32 rspec)
++{
++	return (rspec & 0xff00) >> 8;
++}
++
++static inline u32 rspec_get_bw(u32 rspec)
++{
++	return (rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT;
++}
++
++static inline bool rspec_issgi(u32 rspec)
++{
++	return (rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI;
++}
++
++static inline bool rspec_is40mhz(u32 rspec)
++{
++	u32 bw = rspec_get_bw(rspec);
++
++	return bw == PHY_TXC1_BW_40MHZ || bw == PHY_TXC1_BW_40MHZ_DUP;
++}
++
++static inline uint rspec2rate(u32 rspec)
++{
++	if (rspec & RSPEC_MIMORATE)
++		return mcs_2_rate(rspec & RSPEC_RATE_MASK, rspec_is40mhz(rspec),
++				  rspec_issgi(rspec));
++	return rspec & RSPEC_RATE_MASK;
++}
++
++static inline u8 rspec_mimoplcp3(u32 rspec)
++{
++	return (rspec & 0xf00000) >> 16;
++}
++
++static inline bool plcp3_issgi(u8 plcp)
++{
++	return (plcp & (RSPEC_SHORT_GI >> 16)) != 0;
++}
++
++static inline uint rspec_stc(u32 rspec)
++{
++	return (rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT;
++}
++
++static inline uint rspec_stf(u32 rspec)
++{
++	return (rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT;
++}
++
++static inline bool is_mcs_rate(u32 ratespec)
++{
++	return (ratespec & RSPEC_MIMORATE) != 0;
++}
++
++static inline bool is_ofdm_rate(u32 ratespec)
++{
++	return !is_mcs_rate(ratespec) &&
++	       (rate_info[ratespec & RSPEC_RATE_MASK] & BRCMS_RATE_FLAG);
++}
++
++static inline bool is_cck_rate(u32 ratespec)
++{
++	u32 rate = (ratespec & BRCMS_RATE_MASK);
++
++	return !is_mcs_rate(ratespec) && (
++			rate == BRCM_RATE_1M || rate == BRCM_RATE_2M ||
++			rate == BRCM_RATE_5M5 || rate == BRCM_RATE_11M);
++}
++
++static inline bool is_single_stream(u8 mcs)
++{
++	return mcs <= HIGHEST_SINGLE_STREAM_MCS || mcs == 32;
++}
++
++static inline u8 cck_rspec(u8 cck)
++{
++	return cck & RSPEC_RATE_MASK;
++}
++
++/* Convert encoded rate value in plcp header to numerical rates in 500 KHz
++ * increments */
++static inline u8 ofdm_phy2mac_rate(u8 rlpt)
++{
++	return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7];
++}
++
++static inline u8 cck_phy2mac_rate(u8 signal)
++{
++	return signal/5;
++}
++
++/* Rates specified in brcms_c_rateset_filter() */
++#define BRCMS_RATES_CCK_OFDM	0
++#define BRCMS_RATES_CCK		1
++#define BRCMS_RATES_OFDM		2
++
++/* sanitize, and sort a rateset with the basic bit(s) preserved, validate
++ * rateset */
++extern bool
++brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs,
++				       const struct brcms_c_rateset *hw_rs,
++				       bool check_brate, u8 txstreams);
++/* copy rateset src to dst as-is (no masking or sorting) */
++extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src,
++			     struct brcms_c_rateset *dst);
++
++/* would be nice to have these documented ... */
++extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp);
++
++extern void brcms_c_rateset_filter(struct brcms_c_rateset *src,
++	struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask,
++	bool mcsallow);
++
++extern void
++brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt,
++			const struct brcms_c_rateset *rs_hw, uint phy_type,
++			int bandtype, bool cck_only, uint rate_mask,
++			bool mcsallow, u8 bw, u8 txstreams);
++
++extern s16 brcms_c_rate_legacy_phyctl(uint rate);
++
++extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams);
++extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset);
++extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset,
++				      u8 txstreams);
++extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset,
++					  u8 bw);
++
++#endif				/* _BRCM_RATE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/scb.h b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+new file mode 100644
+index 0000000..51c79c7
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/scb.h
+@@ -0,0 +1,82 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_SCB_H_
++#define _BRCM_SCB_H_
++
++#include <linux/if_ether.h>
++#include <brcmu_utils.h>
++#include <defs.h>
++#include "types.h"
++
++#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
++
++#define AMPDU_MAX_SCB_TID	NUMPRIO
++
++/* scb flags */
++#define SCB_WMECAP		0x0040
++#define SCB_HTCAP		0x10000	/* HT (MIMO) capable device */
++#define SCB_IS40		0x80000	/* 40MHz capable */
++#define SCB_STBCCAP		0x40000000	/* STBC Capable */
++
++#define SCB_MAGIC	0xbeefcafe
++
++/* structure to store per-tid state for the ampdu initiator */
++struct scb_ampdu_tid_ini {
++	u8 tx_in_transit; /* number of pending mpdus in transit in driver */
++	u8 tid;		  /* initiator tid for easy lookup */
++	/* tx retry count; indexed by seq modulo */
++	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];
++	struct scb *scb;  /* backptr for easy lookup */
++	u8 ba_wsize;	  /* negotiated ba window size (in pdu) */
++};
++
++struct scb_ampdu {
++	struct scb *scb;	/* back pointer for easy reference */
++	u8 mpdu_density;	/* mpdu density */
++	u8 max_pdu;		/* max pdus allowed in ampdu */
++	u8 release;		/* # of mpdus released at a time */
++	u16 min_len;		/* min mpdu len to support the density */
++	u32 max_rx_ampdu_bytes;	/* max ampdu rcv length; 8k, 16k, 32k, 64k */
++
++	/*
++	 * This could easily be a ini[] pointer and we keep this info in wl
++	 * itself instead of having mac80211 hold it for us. Also could be made
++	 * dynamic per tid instead of static.
++	 */
++	/* initiator info - per tid (NUMPRIO): */
++	struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID];
++};
++
++/* station control block - one per remote MAC address */
++struct scb {
++	u32 magic;
++	u32 flags;	/* various bit flags as defined below */
++	u32 flags2;	/* various bit flags2 as defined below */
++	u8 state;	/* current state bitfield of auth/assoc process */
++	u8 ea[ETH_ALEN];	/* station address */
++	uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */
++
++	u16 seqctl[NUMPRIO];	/* seqctl of last received frame (for dups) */
++	/* seqctl of last received frame (for dups) for non-QoS data and
++	 * management */
++	u16 seqctl_nonqos;
++	u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */
++
++	struct scb_ampdu scb_ampdu;	/* AMPDU state including per tid info */
++};
++
++#endif				/* _BRCM_SCB_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+new file mode 100644
+index 0000000..ed1d1aa
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c
+@@ -0,0 +1,438 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <net/mac80211.h>
++
++#include "types.h"
++#include "d11.h"
++#include "rate.h"
++#include "phy/phy_hal.h"
++#include "channel.h"
++#include "main.h"
++#include "stf.h"
++
++#define MIN_SPATIAL_EXPANSION	0
++#define MAX_SPATIAL_EXPANSION	1
++
++#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \
++	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
++
++#define NSTS_1	1
++#define NSTS_2	2
++#define NSTS_3	3
++#define NSTS_4	4
++
++static const u8 txcore_default[5] = {
++	(0),			/* bitmap of the core enabled */
++	(0x01),			/* For Nsts = 1, enable core 1 */
++	(0x03),			/* For Nsts = 2, enable core 1 & 2 */
++	(0x07),			/* For Nsts = 3, enable core 1, 2 & 3 */
++	(0x0f)			/* For Nsts = 4, enable all cores */
++};
++
++static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val)
++{
++	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
++			return;
++	}
++
++	if (wlc->pub->up) {
++		brcms_c_update_beacon(wlc);
++		brcms_c_update_probe_resp(wlc, true);
++	}
++}
++
++/*
++ * every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to
++ * turn on/off txchain.
++ */
++void brcms_c_tempsense_upd(struct brcms_c_info *wlc)
++{
++	struct brcms_phy_pub *pi = wlc->band->pi;
++	uint active_chains, txchain;
++
++	/* Check if the chip is too hot. Disable one Tx chain, if it is */
++	/* high 4 bits are for Rx chain, low 4 bits are  for Tx chain */
++	active_chains = wlc_phy_stf_chain_active_get(pi);
++	txchain = active_chains & 0xf;
++
++	if (wlc->stf->txchain == wlc->stf->hw_txchain) {
++		if (txchain && (txchain < wlc->stf->hw_txchain))
++			/* turn off 1 tx chain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
++		if (txchain == wlc->stf->hw_txchain)
++			/* turn back on txchain */
++			brcms_c_stf_txchain_set(wlc, txchain, true);
++	}
++}
++
++void
++brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel,
++			    u16 chanspec)
++{
++	struct tx_power power;
++	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
++
++	/* Clear previous settings */
++	*ss_algo_channel = 0;
++
++	if (!wlc->pub->up) {
++		*ss_algo_channel = (u16) -1;
++		return;
++	}
++
++	wlc_phy_txpower_get_current(wlc->band->pi, &power,
++				    CHSPEC_CHANNEL(chanspec));
++
++	siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
++	cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
++	stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
++	    WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
++
++	/* criteria to choose stf mode */
++
++	/*
++	 * the "+3dbm (12 0.25db units)" is to account for the fact that with
++	 * CDD, tx occurs on both chains
++	 */
++	if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
++	else
++		setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
++
++	/*
++	 * STBC is ORed into to algo channel as STBC requires per-packet SCB
++	 * capability check so cannot be default mode of operation. One of
++	 * SISO, CDD have to be set
++	 */
++	if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
++		setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
++}
++
++static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON))
++		return false;
++
++	if ((int_val == ON) && (wlc->stf->txstreams == 1))
++		return false;
++
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
++
++	return true;
++}
++
++bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val)
++{
++	if ((int_val != HT_CAP_RX_STBC_NO)
++	    && (int_val != HT_CAP_RX_STBC_ONE_STREAM))
++		return false;
++
++	if (BRCMS_STF_SS_STBC_RX(wlc)) {
++		if ((int_val != HT_CAP_RX_STBC_NO)
++		    && (wlc->stf->rxstreams == 1))
++			return false;
++	}
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, int_val);
++	return true;
++}
++
++static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts,
++				  u8 core_mask)
++{
++	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
++		 wlc->pub->unit, Nsts, core_mask);
++
++	if (hweight8(core_mask) > wlc->stf->txstreams)
++		core_mask = 0;
++
++	if ((hweight8(core_mask) == wlc->stf->txstreams) &&
++	    ((core_mask & ~wlc->stf->txchain)
++	     || !(core_mask & wlc->stf->txchain)))
++		core_mask = wlc->stf->txchain;
++
++	wlc->stf->txcore[Nsts] = core_mask;
++	/* Nsts = 1..4, txcore index = 1..4 */
++	if (Nsts == 1) {
++		/* Needs to update beacon and ucode generated response
++		 * frames when 1 stream core map changed
++		 */
++		wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
++		brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++		if (wlc->clk) {
++			brcms_c_suspend_mac_and_wait(wlc);
++			brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
++			brcms_c_enable_mac(wlc);
++		}
++	}
++
++	return 0;
++}
++
++static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val)
++{
++	int i;
++	u8 core_mask = 0;
++
++	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
++
++	wlc->stf->spatial_policy = (s8) val;
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
++		core_mask = (val == MAX_SPATIAL_EXPANSION) ?
++		    wlc->stf->txchain : txcore_default[i];
++		brcms_c_stf_txcore_set(wlc, (u8) i, core_mask);
++	}
++	return 0;
++}
++
++/*
++ * Centralized txant update function. call it whenever wlc->stf->txant and/or
++ * wlc->stf->txchain change.
++ *
++ * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
++ * achieve various tx/rx antenna selection schemes
++ *
++ * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means auto(last rx).
++ * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7
++ * means last rx and do tx-antenna selection for SISO transmissions
++ * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7
++ * means both cores active
++*/
++static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	s8 txant;
++
++	txant = (s8) wlc->stf->txant;
++	if (BRCMS_PHY_11N_CAP(wlc->band)) {
++		if (txant == ANT_TX_FORCE_0) {
++			wlc->stf->phytxant = PHY_TXC_ANT_0;
++		} else if (txant == ANT_TX_FORCE_1) {
++			wlc->stf->phytxant = PHY_TXC_ANT_1;
++
++			if (BRCMS_ISNPHY(wlc->band) &&
++			    NREV_GE(wlc->band->phyrev, 3)
++			    && NREV_LT(wlc->band->phyrev, 7))
++				wlc->stf->phytxant = PHY_TXC_ANT_2;
++		} else {
++			if (BRCMS_ISLCNPHY(wlc->band) ||
++			    BRCMS_ISSSLPNPHY(wlc->band))
++				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
++			else {
++				/* catch out of sync wlc->stf->txcore */
++				WARN_ON(wlc->stf->txchain <= 0);
++				wlc->stf->phytxant =
++				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++			}
++		}
++	} else {
++		if (txant == ANT_TX_FORCE_0)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
++		else if (txant == ANT_TX_FORCE_1)
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
++		else
++			wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
++	}
++
++	brcms_b_txant_set(wlc->hw, wlc->stf->phytxant);
++}
++
++int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force)
++{
++	u8 txchain = (u8) int_val;
++	u8 txstreams;
++	uint i;
++
++	if (wlc->stf->txchain == txchain)
++		return 0;
++
++	if ((txchain & ~wlc->stf->hw_txchain)
++	    || !(txchain & wlc->stf->hw_txchain))
++		return -EINVAL;
++
++	/*
++	 * if nrate override is configured to be non-SISO STF mode, reject
++	 * reducing txchain to 1
++	 */
++	txstreams = (u8) hweight8(txchain);
++	if (txstreams > MAX_STREAMS_SUPPORTED)
++		return -EINVAL;
++
++	wlc->stf->txchain = txchain;
++	wlc->stf->txstreams = txstreams;
++	brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++	wlc->stf->txant =
++	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
++	_brcms_c_stf_phy_txant_upd(wlc);
++
++	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
++			      wlc->stf->rxchain);
++
++	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
++		brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
++
++	return 0;
++}
++
++/*
++ * update wlc->stf->ss_opmode which represents the operational stf_ss mode
++ * we're using
++ */
++int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band)
++{
++	int ret_code = 0;
++	u8 prev_stf_ss;
++	u8 upd_stf_ss;
++
++	prev_stf_ss = wlc->stf->ss_opmode;
++
++	/*
++	 * NOTE: opmode can only be SISO or CDD as STBC is decided on a
++	 * per-packet basis
++	 */
++	if (BRCMS_STBC_CAP_PHY(wlc) &&
++	    wlc->stf->ss_algosel_auto
++	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
++		upd_stf_ss = (wlc->stf->txstreams == 1 ||
++			      isset(&wlc->stf->ss_algo_channel,
++				    PHY_TXC1_MODE_SISO)) ?
++				    PHY_TXC1_MODE_SISO : PHY_TXC1_MODE_CDD;
++	} else {
++		if (wlc->band != band)
++			return ret_code;
++		upd_stf_ss = (wlc->stf->txstreams == 1) ?
++				PHY_TXC1_MODE_SISO : band->band_stf_ss_mode;
++	}
++	if (prev_stf_ss != upd_stf_ss) {
++		wlc->stf->ss_opmode = upd_stf_ss;
++		brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss);
++	}
++
++	return ret_code;
++}
++
++int brcms_c_stf_attach(struct brcms_c_info *wlc)
++{
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
++
++	if (BRCMS_ISNPHY(wlc->band) &&
++	    (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
++		wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
++		    PHY_TXC1_MODE_CDD;
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
++	brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
++
++	brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
++	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
++	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
++
++	if (BRCMS_STBC_CAP_PHY(wlc)) {
++		wlc->stf->ss_algosel_auto = true;
++		/* Init the default value */
++		wlc->stf->ss_algo_channel = (u16) -1;
++	}
++	return 0;
++}
++
++void brcms_c_stf_detach(struct brcms_c_info *wlc)
++{
++}
++
++void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc)
++{
++	_brcms_c_stf_phy_txant_upd(wlc);
++}
++
++void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc)
++{
++	struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom;
++
++	/* get available rx/tx chains */
++	wlc->stf->hw_txchain = sprom->txchain;
++	wlc->stf->hw_rxchain = sprom->rxchain;
++
++	/* these parameter are intended to be used for all PHY types */
++	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_txchain = TXCHAIN_DEF;
++	}
++
++	wlc->stf->txchain = wlc->stf->hw_txchain;
++	wlc->stf->txstreams = (u8) hweight8(wlc->stf->hw_txchain);
++
++	if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
++		if (BRCMS_ISNPHY(wlc->band))
++			wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
++		else
++			wlc->stf->hw_rxchain = RXCHAIN_DEF;
++	}
++
++	wlc->stf->rxchain = wlc->stf->hw_rxchain;
++	wlc->stf->rxstreams = (u8) hweight8(wlc->stf->hw_rxchain);
++
++	/* initialize the txcore table */
++	memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
++
++	/* default spatial_policy */
++	wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
++	brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
++}
++
++static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				       u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++
++	if (rspec_stf(rspec) != PHY_TXC1_MODE_SISO)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	else if (wlc->stf->txant == ANT_TX_DEF)
++		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
++	phytxant &= PHY_TXC_ANT_MASK;
++	return phytxant;
++}
++
++u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec)
++{
++	return _brcms_c_stf_phytxchain_sel(wlc, rspec);
++}
++
++u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec)
++{
++	u16 phytxant = wlc->stf->phytxant;
++	u16 mask = PHY_TXC_ANT_MASK;
++
++	/* for non-siso rates or default setting, use the available chains */
++	if (BRCMS_ISNPHY(wlc->band)) {
++		phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec);
++		mask = PHY_TXC_HTANT_MASK;
++	}
++	phytxant |= phytxant & mask;
++	return phytxant;
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+new file mode 100644
+index 0000000..19f6580
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h
+@@ -0,0 +1,42 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_STF_H_
++#define _BRCM_STF_H_
++
++#include "types.h"
++
++extern int brcms_c_stf_attach(struct brcms_c_info *wlc);
++extern void brcms_c_stf_detach(struct brcms_c_info *wlc);
++
++extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc,
++					u16 *ss_algo_channel,
++					u16 chanspec);
++extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc,
++			     struct brcms_band *band);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val,
++			       bool force);
++extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val);
++extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc);
++extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc);
++extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc,
++				      u32 rspec);
++extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc,
++					u32 rspec);
++
++#endif				/* _BRCM_STF_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+new file mode 100644
+index 0000000..e11ae83
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h
+@@ -0,0 +1,304 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef _BRCM_TYPES_H_
++#define _BRCM_TYPES_H_
++
++#include <linux/types.h>
++#include <linux/io.h>
++
++#define WL_CHAN_FREQ_RANGE_2G      0
++#define WL_CHAN_FREQ_RANGE_5GL     1
++#define WL_CHAN_FREQ_RANGE_5GM     2
++#define WL_CHAN_FREQ_RANGE_5GH     3
++
++/* boardflags */
++
++/* Board has gpio 9 controlling the PA */
++#define	BFL_PACTRL		0x00000002
++/* Not ok to power down the chip pll and oscillator */
++#define	BFL_NOPLLDOWN		0x00000020
++/* Board supports the Front End Module */
++#define BFL_FEM			0x00000800
++/* Board has an external LNA in 2.4GHz band */
++#define BFL_EXTLNA		0x00001000
++/* Board has no PA */
++#define BFL_NOPA		0x00010000
++/* Power topology uses BUCKBOOST */
++#define BFL_BUCKBOOST		0x00200000
++/* Board has FEM and switch to share antenna w/ BT */
++#define BFL_FEM_BT		0x00400000
++/* Power topology doesn't use CBUCK */
++#define BFL_NOCBUCK		0x00800000
++/* Power topology uses PALDO */
++#define BFL_PALDO		0x02000000
++/* Board has an external LNA in 5GHz band */
++#define BFL_EXTLNA_5GHz		0x10000000
++
++/* boardflags2 */
++
++/* Board has an external rxbb regulator */
++#define BFL2_RXBB_INT_REG_DIS	0x00000001
++/* Flag to implement alternative A-band PLL settings */
++#define BFL2_APLL_WAR		0x00000002
++/* Board permits enabling TX Power Control */
++#define BFL2_TXPWRCTRL_EN	0x00000004
++/* Board supports the 2X4 diversity switch */
++#define BFL2_2X4_DIV		0x00000008
++/* Board supports 5G band power gain */
++#define BFL2_5G_PWRGAIN		0x00000010
++/* Board overrides ASPM and Clkreq settings */
++#define BFL2_PCIEWAR_OVR	0x00000020
++#define BFL2_LEGACY		0x00000080
++/* 4321mcm93 board uses Skyworks FEM */
++#define BFL2_SKWRKFEM_BRD	0x00000100
++/* Board has a WAR for clock-harmonic spurs */
++#define BFL2_SPUR_WAR		0x00000200
++/* Flag to narrow G-band PLL loop b/w */
++#define BFL2_GPLL_WAR		0x00000400
++/* Tx CCK pkts on Ant 0 only */
++#define BFL2_SINGLEANT_CCK	0x00001000
++/* WAR to reduce and avoid clock-harmonic spurs in 2G */
++#define BFL2_2G_SPUR_WAR	0x00002000
++/* Flag to widen G-band PLL loop b/w */
++#define BFL2_GPLL_WAR2	        0x00010000
++#define BFL2_IPALVLSHIFT_3P3    0x00020000
++/* Use internal envelope detector for TX IQCAL */
++#define BFL2_INTERNDET_TXIQCAL  0x00040000
++/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it
++ * off without this flag to save power. */
++#define BFL2_XTALBUFOUTEN       0x00080000
++
++/*
++ * board specific GPIO assignment, gpio 0-3 are also customer-configurable
++ * led
++ */
++
++/* bit 9 controls the PA on new 4306 boards */
++#define	BOARD_GPIO_PACTRL	0x200
++#define BOARD_GPIO_12		0x1000
++#define BOARD_GPIO_13		0x2000
++
++/* **** Core type/rev defaults **** */
++#define D11CONF		0x0fffffb0	/* Supported  D11 revs: 4, 5, 7-27
++					 * also need to update wlc.h MAXCOREREV
++					 */
++
++#define NCONF		0x000001ff	/* Supported nphy revs:
++					 *      0       4321a0
++					 *      1       4321a1
++					 *      2       4321b0/b1/c0/c1
++					 *      3       4322a0
++					 *      4       4322a1
++					 *      5       4716a0
++					 *      6       43222a0, 43224a0
++					 *      7       43226a0
++					 *      8       5357a0, 43236a0
++					 */
++
++#define LCNCONF		0x00000007	/* Supported lcnphy revs:
++					 *      0       4313a0, 4336a0, 4330a0
++					 *      1
++					 *      2       4330a0
++					 */
++
++#define SSLPNCONF	0x0000000f	/* Supported sslpnphy revs:
++					 *      0       4329a0/k0
++					 *      1       4329b0/4329C0
++					 *      2       4319a0
++					 *      3       5356a0
++					 */
++
++/********************************************************************
++ * Phy/Core Configuration.  Defines macros to to check core phy/rev *
++ * compile-time configuration.  Defines default core support.       *
++ * ******************************************************************
++ */
++
++/* Basic macros to check a configuration bitmask */
++
++#define CONF_HAS(config, val)	((config) & (1 << (val)))
++#define CONF_MSK(config, mask)	((config) & (mask))
++#define MSK_RANGE(low, hi)	((1 << ((hi)+1)) - (1 << (low)))
++#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
++
++#define CONF_IS(config, val)	((config) == (1 << (val)))
++#define CONF_GE(config, val)	((config) & (0-(1 << (val))))
++#define CONF_GT(config, val)	((config) & (0-2*(1 << (val))))
++#define CONF_LT(config, val)	((config) & ((1 << (val))-1))
++#define CONF_LE(config, val)	((config) & (2*(1 << (val))-1))
++
++/* Wrappers for some of the above, specific to config constants */
++
++#define NCONF_HAS(val)	CONF_HAS(NCONF, val)
++#define NCONF_MSK(mask)	CONF_MSK(NCONF, mask)
++#define NCONF_IS(val)	CONF_IS(NCONF, val)
++#define NCONF_GE(val)	CONF_GE(NCONF, val)
++#define NCONF_GT(val)	CONF_GT(NCONF, val)
++#define NCONF_LT(val)	CONF_LT(NCONF, val)
++#define NCONF_LE(val)	CONF_LE(NCONF, val)
++
++#define LCNCONF_HAS(val)	CONF_HAS(LCNCONF, val)
++#define LCNCONF_MSK(mask)	CONF_MSK(LCNCONF, mask)
++#define LCNCONF_IS(val)		CONF_IS(LCNCONF, val)
++#define LCNCONF_GE(val)		CONF_GE(LCNCONF, val)
++#define LCNCONF_GT(val)		CONF_GT(LCNCONF, val)
++#define LCNCONF_LT(val)		CONF_LT(LCNCONF, val)
++#define LCNCONF_LE(val)		CONF_LE(LCNCONF, val)
++
++#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
++#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
++#define D11CONF_IS(val)	CONF_IS(D11CONF, val)
++#define D11CONF_GE(val)	CONF_GE(D11CONF, val)
++#define D11CONF_GT(val)	CONF_GT(D11CONF, val)
++#define D11CONF_LT(val)	CONF_LT(D11CONF, val)
++#define D11CONF_LE(val)	CONF_LE(D11CONF, val)
++
++#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
++#define PHYCONF_IS(val)	CONF_IS(PHYTYPE, val)
++
++#define NREV_IS(var, val) \
++	(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
++
++#define NREV_GE(var, val) \
++	(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
++
++#define NREV_GT(var, val) \
++	(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
++
++#define NREV_LT(var, val) \
++	(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
++
++#define NREV_LE(var, val) \
++	(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
++
++#define LCNREV_IS(var, val) \
++	(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
++
++#define LCNREV_GE(var, val) \
++	(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
++
++#define LCNREV_GT(var, val) \
++	(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
++
++#define LCNREV_LT(var, val) \
++	(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
++
++#define LCNREV_LE(var, val) \
++	(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
++
++#define D11REV_IS(var, val) \
++	(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
++
++#define D11REV_GE(var, val) \
++	(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
++
++#define D11REV_GT(var, val) \
++	(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
++
++#define D11REV_LT(var, val) \
++	(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
++
++#define D11REV_LE(var, val) \
++	(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
++
++#define PHYTYPE_IS(var, val)\
++	(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
++
++/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
++
++#define _PHYCONF_N (1 << PHY_TYPE_N)
++#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
++#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
++
++#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
++
++/* Utility macro to identify 802.11n (HT) capable PHYs */
++#define PHYTYPE_11N_CAP(phytype) \
++	(PHYTYPE_IS(phytype, PHY_TYPE_N) ||	\
++	 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
++	 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
++
++/* Last but not least: shorter wlc-specific var checks */
++#define BRCMS_ISNPHY(band)		PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
++#define BRCMS_ISLCNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
++#define BRCMS_ISSSLPNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
++
++#define BRCMS_PHY_11N_CAP(band)	PHYTYPE_11N_CAP((band)->phytype)
++
++/**********************************************************************
++ * ------------- End of Core phy/rev configuration. ----------------- *
++ * ********************************************************************
++ */
++
++#define BCMMSG(dev, fmt, args...)		\
++do {						\
++	if (brcm_msg_level & LOG_TRACE_VAL)	\
++		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
++} while (0)
++
++#ifdef CONFIG_BCM47XX
++/*
++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
++ * transactions. As a fix, a read after write is performed on certain places
++ * in the code. Older chips and the newer 5357 family don't require this fix.
++ */
++#define bcma_wflush16(c, o, v) \
++	({ bcma_write16(c, o, v); (void)bcma_read16(c, o); })
++#else
++#define bcma_wflush16(c, o, v)	bcma_write16(c, o, v)
++#endif				/* CONFIG_BCM47XX */
++
++/* multi-bool data type: set of bools, mbool is true if any is set */
++
++/* set one bool */
++#define mboolset(mb, bit)		((mb) |= (bit))
++/* clear one bool */
++#define mboolclr(mb, bit)		((mb) &= ~(bit))
++/* true if one bool is set */
++#define mboolisset(mb, bit)		(((mb) & (bit)) != 0)
++#define	mboolmaskset(mb, mask, val)	((mb) = (((mb) & ~(mask)) | (val)))
++
++#define CEIL(x, y)		(((x) + ((y)-1)) / (y))
++
++/* forward declarations */
++struct wiphy;
++struct ieee80211_sta;
++struct ieee80211_tx_queue_params;
++struct brcms_info;
++struct brcms_c_info;
++struct brcms_hardware;
++struct brcms_txq_info;
++struct brcms_band;
++struct dma_pub;
++struct si_pub;
++struct tx_status;
++struct d11rxhdr;
++struct txpwr_limits;
++
++/* iovar structure */
++struct brcmu_iovar {
++	const char *name;	/* name for lookup and display */
++	u16 varid;	/* id for switch */
++	u16 flags;	/* driver-specific flag bits */
++	u16 type;	/* base type of argument */
++	u16 minlen;	/* min length for buffer vars */
++};
++
++/* brcm_msg_level is a bit vector with defs in defs.h */
++extern u32 brcm_msg_level;
++
++#endif				/* _BRCM_TYPES_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+new file mode 100644
+index 0000000..80e3ccf
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c
+@@ -0,0 +1,109 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <defs.h>
++#include "types.h"
++#include <ucode_loader.h>
++
++enum {
++	D11UCODE_NAMETAG_START = 0,
++	D11LCN0BSINITVALS24,
++	D11LCN0INITVALS24,
++	D11LCN1BSINITVALS24,
++	D11LCN1INITVALS24,
++	D11LCN2BSINITVALS24,
++	D11LCN2INITVALS24,
++	D11N0ABSINITVALS16,
++	D11N0BSINITVALS16,
++	D11N0INITVALS16,
++	D11UCODE_OVERSIGHT16_MIMO,
++	D11UCODE_OVERSIGHT16_MIMOSZ,
++	D11UCODE_OVERSIGHT24_LCN,
++	D11UCODE_OVERSIGHT24_LCNSZ,
++	D11UCODE_OVERSIGHT_BOMMAJOR,
++	D11UCODE_OVERSIGHT_BOMMINOR
++};
++
++int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode)
++{
++	int rc;
++
++	rc = brcms_check_firmwares(wl);
++
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0bsinitvals24,
++				     D11LCN0BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn0initvals24,
++				       D11LCN0INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1bsinitvals24,
++				       D11LCN1BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn1initvals24,
++				       D11LCN1INITVALS24);
++	rc = rc < 0 ? rc :
++		brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2bsinitvals24,
++				     D11LCN2BSINITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11lcn2initvals24,
++				       D11LCN2INITVALS24);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0absinitvals16,
++				       D11N0ABSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0bsinitvals16,
++				       D11N0BSINITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->d11n0initvals16,
++				       D11N0INITVALS16);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_16_mimo,
++				       D11UCODE_OVERSIGHT16_MIMO);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_16_mimosz,
++					D11UCODE_OVERSIGHT16_MIMOSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_24_lcn,
++				       D11UCODE_OVERSIGHT24_LCN);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_uint(wl, &ucode->bcm43xx_24_lcnsz,
++					D11UCODE_OVERSIGHT24_LCNSZ);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bommajor,
++				       D11UCODE_OVERSIGHT_BOMMAJOR);
++	rc = rc < 0 ?
++	     rc : brcms_ucode_init_buf(wl, (void **)&ucode->bcm43xx_bomminor,
++				       D11UCODE_OVERSIGHT_BOMMINOR);
++	return rc;
++}
++
++void brcms_ucode_data_free(struct brcms_ucode *ucode)
++{
++	brcms_ucode_free_buf((void *)ucode->d11lcn0bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn0initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn1initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2bsinitvals24);
++	brcms_ucode_free_buf((void *)ucode->d11lcn2initvals24);
++	brcms_ucode_free_buf((void *)ucode->d11n0absinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0bsinitvals16);
++	brcms_ucode_free_buf((void *)ucode->d11n0initvals16);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_16_mimo);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_24_lcn);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bommajor);
++	brcms_ucode_free_buf((void *)ucode->bcm43xx_bomminor);
++}
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+new file mode 100644
+index 0000000..18750a8
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef	_BRCM_UCODE_H_
++#define	_BRCM_UCODE_H_
++
++#include "types.h"		/* forward structure declarations */
++
++#define MIN_FW_SIZE 40000	/* minimum firmware file size in bytes */
++#define MAX_FW_SIZE 150000
++
++#define UCODE_LOADER_API_VER 0
++
++struct d11init;
++
++struct brcms_ucode {
++	struct d11init *d11lcn0bsinitvals24;
++	struct d11init *d11lcn0initvals24;
++	struct d11init *d11lcn1bsinitvals24;
++	struct d11init *d11lcn1initvals24;
++	struct d11init *d11lcn2bsinitvals24;
++	struct d11init *d11lcn2initvals24;
++	struct d11init *d11n0absinitvals16;
++	struct d11init *d11n0bsinitvals16;
++	struct d11init *d11n0initvals16;
++	__le32 *bcm43xx_16_mimo;
++	size_t bcm43xx_16_mimosz;
++	__le32 *bcm43xx_24_lcn;
++	size_t bcm43xx_24_lcnsz;
++	u32 *bcm43xx_bommajor;
++	u32 *bcm43xx_bomminor;
++};
++
++extern int
++brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode);
++
++extern void brcms_ucode_data_free(struct brcms_ucode *ucode);
++
++extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf,
++				unsigned int idx);
++extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes,
++				 unsigned int idx);
++extern void brcms_ucode_free_buf(void *);
++extern int  brcms_check_firmwares(struct brcms_info *wl);
++
++#endif	/* _BRCM_UCODE_H_ */
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/Makefile b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+new file mode 100644
+index 0000000..5529801
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/Makefile
+@@ -0,0 +1,28 @@
++#
++# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
++#
++# Copyright (c) 2011 Broadcom Corporation
++#
++# Permission to use, copy, modify, and/or distribute this software for any
++# purpose with or without fee is hereby granted, provided that the above
++# copyright notice and this permission notice appear in all copies.
++#
++# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++
++ccflags-y :=				\
++	-I$(obj)			\
++	-I$(obj)/../include
++
++BRCMUTIL_OFILES := \
++	utils.o
++
++MODULEPFX := brcmutil
++
++obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
++$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
+diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+new file mode 100644
+index 0000000..161851b
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
+@@ -0,0 +1,278 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#undef pr_fmt
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/netdevice.h>
++#include <linux/module.h>
++#include <linux/printk.h>
++
++#include <brcmu_utils.h>
++
++MODULE_AUTHOR("Broadcom Corporation");
++MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
++MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
++MODULE_LICENSE("Dual BSD/GPL");
++
++struct sk_buff *brcmu_pkt_buf_get_skb(uint len)
++{
++	struct sk_buff *skb;
++
++	skb = dev_alloc_skb(len);
++	if (skb) {
++		skb_put(skb, len);
++		skb->priority = 0;
++	}
++
++	return skb;
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_get_skb);
++
++/* Free the driver packet. Free the tag if present */
++void brcmu_pkt_buf_free_skb(struct sk_buff *skb)
++{
++	WARN_ON(skb->next);
++	if (skb->destructor)
++		/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
++		 * destructor exists
++		 */
++		dev_kfree_skb_any(skb);
++	else
++		/* can free immediately (even in_irq()) if destructor
++		 * does not exist
++		 */
++		dev_kfree_skb(skb);
++}
++EXPORT_SYMBOL(brcmu_pkt_buf_free_skb);
++
++/*
++ * osl multiple-precedence packet queue
++ * hi_prec is always >= the number of the highest non-empty precedence
++ */
++struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				      struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_tail(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq);
++
++struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++					   struct sk_buff *p)
++{
++	struct sk_buff_head *q;
++
++	if (pktq_full(pq) || pktq_pfull(pq, prec))
++		return NULL;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_head(q, p);
++	pq->len++;
++
++	if (pq->hi_prec < prec)
++		pq->hi_prec = (u8) prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_penq_head);
++
++struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq);
++
++struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue_tail(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
++
++void
++brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
++		  bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p, *next;
++
++	q = &pq->q[prec].skblist;
++	skb_queue_walk_safe(q, p, next) {
++		if (fn == NULL || (*fn) (p, arg)) {
++			skb_unlink(p, q);
++			brcmu_pkt_buf_free_skb(p);
++			pq->len--;
++		}
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_pflush);
++
++void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		      bool (*fn)(struct sk_buff *, void *), void *arg)
++{
++	int prec;
++	for (prec = 0; prec < pq->num_prec; prec++)
++		brcmu_pktq_pflush(pq, prec, dir, fn, arg);
++}
++EXPORT_SYMBOL(brcmu_pktq_flush);
++
++void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
++{
++	int prec;
++
++	/* pq is variable size; only zero out what's requested */
++	memset(pq, 0,
++	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
++
++	pq->num_prec = (u16) num_prec;
++
++	pq->max = (u16) max_len;
++
++	for (prec = 0; prec < num_prec; prec++) {
++		pq->q[prec].max = pq->max;
++		skb_queue_head_init(&pq->q[prec].skblist);
++	}
++}
++EXPORT_SYMBOL(brcmu_pktq_init);
++
++struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
++{
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	for (prec = 0; prec < pq->hi_prec; prec++)
++		if (!skb_queue_empty(&pq->q[prec].skblist))
++			break;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++EXPORT_SYMBOL(brcmu_pktq_peek_tail);
++
++/* Return sum of lengths of a specific set of precedences */
++int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
++{
++	int prec, len;
++
++	len = 0;
++
++	for (prec = 0; prec <= pq->hi_prec; prec++)
++		if (prec_bmp & (1 << prec))
++			len += pq->q[prec].skblist.qlen;
++
++	return len;
++}
++EXPORT_SYMBOL(brcmu_pktq_mlen);
++
++/* Priority dequeue from a specific set of precedences */
++struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++				      int *prec_out)
++{
++	struct sk_buff_head *q;
++	struct sk_buff *p;
++	int prec;
++
++	if (pq->len == 0)
++		return NULL;
++
++	while ((prec = pq->hi_prec) > 0 &&
++	       skb_queue_empty(&pq->q[prec].skblist))
++		pq->hi_prec--;
++
++	while ((prec_bmp & (1 << prec)) == 0 ||
++	       skb_queue_empty(&pq->q[prec].skblist))
++		if (prec-- == 0)
++			return NULL;
++
++	q = &pq->q[prec].skblist;
++	p = skb_dequeue(q);
++	if (p == NULL)
++		return NULL;
++
++	pq->len--;
++
++	if (prec_out)
++		*prec_out = prec;
++
++	return p;
++}
++EXPORT_SYMBOL(brcmu_pktq_mdeq);
++
++#if defined(DEBUG)
++/* pretty hex print a pkt buffer chain */
++void brcmu_prpkt(const char *msg, struct sk_buff *p0)
++{
++	struct sk_buff *p;
++
++	if (msg && (msg[0] != '\0'))
++		pr_debug("%s:\n", msg);
++
++	for (p = p0; p; p = p->next)
++		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
++}
++EXPORT_SYMBOL(brcmu_prpkt);
++
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++	struct va_format vaf;
++	va_list args;
++
++	va_start(args, fmt);
++
++	vaf.fmt = fmt;
++	vaf.va = &args;
++
++	pr_debug("%pV", &vaf);
++
++	va_end(args);
++
++	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size);
++}
++EXPORT_SYMBOL(brcmu_dbg_hex_dump);
++#endif				/* defined(DEBUG) */
+diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+new file mode 100644
+index 0000000..333193f
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_HW_IDS_H_
++#define	_BRCM_HW_IDS_H_
++
++#define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
++
++#define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
++#define BCM43224_D11N_ID_VEN1	0x0576	/* Vendor specific 43224 802.11n db */
++
++#define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
++
++#define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
++#define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
++
++/* Chipcommon Core Chip IDs */
++#define BCM4313_CHIP_ID		0x4313
++#define BCM43224_CHIP_ID	43224
++#define BCM43225_CHIP_ID	43225
++#define BCM43235_CHIP_ID	43235
++#define BCM43236_CHIP_ID	43236
++#define BCM43238_CHIP_ID	43238
++#define BCM4329_CHIP_ID		0x4329
++#define BCM4330_CHIP_ID		0x4330
++#define BCM4331_CHIP_ID		0x4331
++
++#endif				/* _BRCM_HW_IDS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+new file mode 100644
+index 0000000..477b92a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+@@ -0,0 +1,196 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_UTILS_H_
++#define	_BRCMU_UTILS_H_
++
++#include <linux/skbuff.h>
++
++/*
++ * Spin at most 'us' microseconds while 'exp' is true.
++ * Caller should explicitly test 'exp' when this completes
++ * and take appropriate error action if 'exp' is still true.
++ */
++#define SPINWAIT(exp, us) { \
++	uint countdown = (us) + 9; \
++	while ((exp) && (countdown >= 10)) {\
++		udelay(10); \
++		countdown -= 10; \
++	} \
++}
++
++/* osl multi-precedence packet queue */
++#define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
++#define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
++
++#define BCME_STRLEN		64	/* Max string length for BCM errors */
++
++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
++#define	PKTBUFSZ	2048
++
++#ifndef setbit
++#ifndef NBBY			/* the BSD family defines NBBY */
++#define	NBBY	8		/* 8 bits per byte */
++#endif				/* #ifndef NBBY */
++#define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
++#define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
++#define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
++#define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
++#endif				/* setbit */
++
++#define	NBITS(type)	(sizeof(type) * 8)
++#define NBITVAL(nbits)	(1 << (nbits))
++#define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
++#define	NBITMASK(nbits)	MAXBITVAL(nbits)
++#define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
++
++/* crc defines */
++#define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
++#define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
++
++/* 18-bytes of Ethernet address buffer length */
++#define ETHER_ADDR_STR_LEN	18
++
++struct pktq_prec {
++	struct sk_buff_head skblist;
++	u16 max;		/* maximum number of queued packets */
++};
++
++/* multi-priority pkt queue */
++struct pktq {
++	u16 num_prec;	/* number of precedences in use */
++	u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
++	u16 max;	/* total max packets */
++	u16 len;	/* total number of packets */
++	/*
++	 * q array must be last since # of elements can be either
++	 * PKTQ_MAX_PREC or 1
++	 */
++	struct pktq_prec q[PKTQ_MAX_PREC];
++};
++
++/* operations on a specific precedence in packet queue */
++
++static inline int pktq_plen(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen;
++}
++
++static inline int pktq_pavail(struct pktq *pq, int prec)
++{
++	return pq->q[prec].max - pq->q[prec].skblist.qlen;
++}
++
++static inline bool pktq_pfull(struct pktq *pq, int prec)
++{
++	return pq->q[prec].skblist.qlen >= pq->q[prec].max;
++}
++
++static inline bool pktq_pempty(struct pktq *pq, int prec)
++{
++	return skb_queue_empty(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
++{
++	return skb_peek(&pq->q[prec].skblist);
++}
++
++static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
++{
++	return skb_peek_tail(&pq->q[prec].skblist);
++}
++
++extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
++				 struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
++				      struct sk_buff *p);
++extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
++extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
++
++/* packet primitives */
++extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);
++extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb);
++
++/* Empty the queue at particular precedence level */
++/* callback function fn(pkt, arg) returns true if pkt belongs to if */
++extern void brcmu_pktq_pflush(struct pktq *pq, int prec,
++	bool dir, bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* operations on a set of precedences in packet queue */
++
++extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp);
++extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
++	int *prec_out);
++
++/* operations on packet queue as a whole */
++
++static inline int pktq_len(struct pktq *pq)
++{
++	return (int)pq->len;
++}
++
++static inline int pktq_max(struct pktq *pq)
++{
++	return (int)pq->max;
++}
++
++static inline int pktq_avail(struct pktq *pq)
++{
++	return (int)(pq->max - pq->len);
++}
++
++static inline bool pktq_full(struct pktq *pq)
++{
++	return pq->len >= pq->max;
++}
++
++static inline bool pktq_empty(struct pktq *pq)
++{
++	return pq->len == 0;
++}
++
++extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len);
++/* prec_out may be NULL if caller is not interested in return value */
++extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out);
++extern void brcmu_pktq_flush(struct pktq *pq, bool dir,
++		bool (*fn)(struct sk_buff *, void *), void *arg);
++
++/* externs */
++/* ip address */
++struct ipv4_addr;
++
++
++/* externs */
++/* format/print */
++#ifdef DEBUG
++extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
++#else
++#define brcmu_prpkt(a, b)
++#endif				/* DEBUG */
++
++#ifdef DEBUG
++extern __printf(3, 4)
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
++#else
++__printf(3, 4)
++static inline
++void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
++{
++}
++#endif
++
++#endif				/* _BRCMU_UTILS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+new file mode 100644
+index 0000000..f10d302
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+@@ -0,0 +1,239 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCMU_WIFI_H_
++#define	_BRCMU_WIFI_H_
++
++#include <linux/if_ether.h>		/* for ETH_ALEN */
++#include <linux/ieee80211.h>		/* for WLAN_PMKID_LEN */
++
++/*
++ * A chanspec (u16) holds the channel number, band, bandwidth and control
++ * sideband
++ */
++
++/* channel defines */
++#define CH_UPPER_SB			0x01
++#define CH_LOWER_SB			0x02
++#define CH_EWA_VALID			0x04
++#define CH_20MHZ_APART			4
++#define CH_10MHZ_APART			2
++#define CH_5MHZ_APART			1 /* 2G band channels are 5 Mhz apart */
++#define CH_MAX_2G_CHANNEL		14	/* Max channel in 2G band */
++#define BRCM_MAX_2G_CHANNEL	CH_MAX_2G_CHANNEL	/* legacy define */
++
++/* bandstate array indices */
++#define BAND_2G_INDEX		0	/* wlc->bandstate[x] index */
++#define BAND_5G_INDEX		1	/* wlc->bandstate[x] index */
++
++/*
++ * max # supported channels. The max channel no is 216, this is that + 1
++ * rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are
++ * u8's all over
++*/
++#define	MAXCHANNEL		224
++
++#define WL_CHANSPEC_CHAN_MASK		0x00ff
++#define WL_CHANSPEC_CHAN_SHIFT		0
++
++#define WL_CHANSPEC_CTL_SB_MASK		0x0300
++#define WL_CHANSPEC_CTL_SB_SHIFT	     8
++#define WL_CHANSPEC_CTL_SB_LOWER	0x0100
++#define WL_CHANSPEC_CTL_SB_UPPER	0x0200
++#define WL_CHANSPEC_CTL_SB_NONE		0x0300
++
++#define WL_CHANSPEC_BW_MASK		0x0C00
++#define WL_CHANSPEC_BW_SHIFT		    10
++#define WL_CHANSPEC_BW_10		0x0400
++#define WL_CHANSPEC_BW_20		0x0800
++#define WL_CHANSPEC_BW_40		0x0C00
++
++#define WL_CHANSPEC_BAND_MASK		0xf000
++#define WL_CHANSPEC_BAND_SHIFT		12
++#define WL_CHANSPEC_BAND_5G		0x1000
++#define WL_CHANSPEC_BAND_2G		0x2000
++#define INVCHANSPEC			255
++
++/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
++#define WF_CHAN_FACTOR_2_4_G		4814	/* 2.4 GHz band, 2407 MHz */
++#define WF_CHAN_FACTOR_5_G		10000	/* 5   GHz band, 5000 MHz */
++#define WF_CHAN_FACTOR_4_G		8000	/* 4.9 GHz band for Japan */
++
++#define CHSPEC_CHANNEL(chspec)	((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
++#define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
++
++#define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
++#define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
++
++#define CHSPEC_IS10(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
++
++#define CHSPEC_IS20(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
++
++#ifndef CHSPEC_IS40
++#define CHSPEC_IS40(chspec) \
++	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
++#endif
++
++#define CHSPEC_IS5G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
++
++#define CHSPEC_IS2G(chspec) \
++	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
++
++#define CHSPEC_SB_NONE(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
++
++#define CHSPEC_SB_UPPER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
++
++#define CHSPEC_SB_LOWER(chspec) \
++	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
++
++#define CHSPEC_CTL_CHAN(chspec) \
++	((CHSPEC_SB_LOWER(chspec)) ? \
++	(lower_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
++	(upper_20_sb(((chspec) & WL_CHANSPEC_CHAN_MASK))))
++
++#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G)
++
++#define CHANSPEC_STR_LEN    8
++
++static inline int lower_20_sb(int channel)
++{
++	return channel > CH_10MHZ_APART ? (channel - CH_10MHZ_APART) : 0;
++}
++
++static inline int upper_20_sb(int channel)
++{
++	return (channel < (MAXCHANNEL - CH_10MHZ_APART)) ?
++	       channel + CH_10MHZ_APART : 0;
++}
++
++static inline int chspec_bandunit(u16 chspec)
++{
++	return CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX;
++}
++
++static inline u16 ch20mhz_chspec(int channel)
++{
++	u16 rc = channel <= CH_MAX_2G_CHANNEL ?
++		 WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G;
++
++	return	(u16)((u16)channel | WL_CHANSPEC_BW_20 |
++		      WL_CHANSPEC_CTL_SB_NONE | rc);
++}
++
++static inline int next_20mhz_chan(int channel)
++{
++	return channel < (MAXCHANNEL - CH_20MHZ_APART) ?
++	       channel + CH_20MHZ_APART : 0;
++}
++
++/* defined rate in 500kbps */
++#define BRCM_MAXRATE	108	/* in 500kbps units */
++#define BRCM_RATE_1M	2	/* in 500kbps units */
++#define BRCM_RATE_2M	4	/* in 500kbps units */
++#define BRCM_RATE_5M5	11	/* in 500kbps units */
++#define BRCM_RATE_11M	22	/* in 500kbps units */
++#define BRCM_RATE_6M	12	/* in 500kbps units */
++#define BRCM_RATE_9M	18	/* in 500kbps units */
++#define BRCM_RATE_12M	24	/* in 500kbps units */
++#define BRCM_RATE_18M	36	/* in 500kbps units */
++#define BRCM_RATE_24M	48	/* in 500kbps units */
++#define BRCM_RATE_36M	72	/* in 500kbps units */
++#define BRCM_RATE_48M	96	/* in 500kbps units */
++#define BRCM_RATE_54M	108	/* in 500kbps units */
++
++#define BRCM_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
++
++#define MCSSET_LEN	16
++
++static inline bool ac_bitmap_tst(u8 bitmap, int prec)
++{
++	return (bitmap & (1 << (prec))) != 0;
++}
++
++/* Enumerate crypto algorithms */
++#define	CRYPTO_ALGO_OFF			0
++#define	CRYPTO_ALGO_WEP1		1
++#define	CRYPTO_ALGO_TKIP		2
++#define	CRYPTO_ALGO_WEP128		3
++#define CRYPTO_ALGO_AES_CCM		4
++#define CRYPTO_ALGO_AES_RESERVED1	5
++#define CRYPTO_ALGO_AES_RESERVED2	6
++#define CRYPTO_ALGO_NALG		7
++
++/* wireless security bitvec */
++
++#define WEP_ENABLED		0x0001
++#define TKIP_ENABLED		0x0002
++#define AES_ENABLED		0x0004
++#define WSEC_SWFLAG		0x0008
++/* to go into transition mode without setting wep */
++#define SES_OW_ENABLED		0x0040
++
++/* WPA authentication mode bitvec */
++#define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
++#define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
++#define WPA_AUTH_UNSPECIFIED	0x0002	/* over 802.1x */
++#define WPA_AUTH_PSK		0x0004	/* Pre-shared key */
++#define WPA_AUTH_RESERVED1	0x0008
++#define WPA_AUTH_RESERVED2	0x0010
++
++#define WPA2_AUTH_RESERVED1	0x0020
++#define WPA2_AUTH_UNSPECIFIED	0x0040	/* over 802.1x */
++#define WPA2_AUTH_PSK		0x0080	/* Pre-shared key */
++#define WPA2_AUTH_RESERVED3	0x0200
++#define WPA2_AUTH_RESERVED4	0x0400
++#define WPA2_AUTH_RESERVED5	0x0800
++
++/* pmkid */
++#define	MAXPMKID		16
++
++#define DOT11_DEFAULT_RTS_LEN		2347
++#define DOT11_DEFAULT_FRAG_LEN		2346
++
++#define DOT11_ICV_AES_LEN		8
++#define DOT11_QOS_LEN			2
++#define DOT11_IV_MAX_LEN		8
++#define DOT11_A4_HDR_LEN		30
++
++#define HT_CAP_RX_STBC_NO		0x0
++#define HT_CAP_RX_STBC_ONE_STREAM	0x1
++
++struct pmkid {
++	u8 BSSID[ETH_ALEN];
++	u8 PMKID[WLAN_PMKID_LEN];
++};
++
++struct pmkid_list {
++	__le32 npmkid;
++	struct pmkid pmkid[1];
++};
++
++struct pmkid_cand {
++	u8 BSSID[ETH_ALEN];
++	u8 preauth;
++};
++
++struct pmkid_cand_list {
++	u32 npmkid_cand;
++	struct pmkid_cand pmkid_cand[1];
++};
++
++#endif				/* _BRCMU_WIFI_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h
+new file mode 100644
+index 0000000..f96834a
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
+@@ -0,0 +1,286 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_SBCHIPC_H
++#define	_SBCHIPC_H
++
++#include "defs.h"		/* for PAD macro */
++
++#define CHIPCREGOFFS(field)	offsetof(struct chipcregs, field)
++
++struct chipcregs {
++	u32 chipid;		/* 0x0 */
++	u32 capabilities;
++	u32 corecontrol;	/* corerev >= 1 */
++	u32 bist;
++
++	/* OTP */
++	u32 otpstatus;	/* 0x10, corerev >= 10 */
++	u32 otpcontrol;
++	u32 otpprog;
++	u32 otplayout;	/* corerev >= 23 */
++
++	/* Interrupt control */
++	u32 intstatus;	/* 0x20 */
++	u32 intmask;
++
++	/* Chip specific regs */
++	u32 chipcontrol;	/* 0x28, rev >= 11 */
++	u32 chipstatus;	/* 0x2c, rev >= 11 */
++
++	/* Jtag Master */
++	u32 jtagcmd;		/* 0x30, rev >= 10 */
++	u32 jtagir;
++	u32 jtagdr;
++	u32 jtagctrl;
++
++	/* serial flash interface registers */
++	u32 flashcontrol;	/* 0x40 */
++	u32 flashaddress;
++	u32 flashdata;
++	u32 PAD[1];
++
++	/* Silicon backplane configuration broadcast control */
++	u32 broadcastaddress;	/* 0x50 */
++	u32 broadcastdata;
++
++	/* gpio - cleared only by power-on-reset */
++	u32 gpiopullup;	/* 0x58, corerev >= 20 */
++	u32 gpiopulldown;	/* 0x5c, corerev >= 20 */
++	u32 gpioin;		/* 0x60 */
++	u32 gpioout;		/* 0x64 */
++	u32 gpioouten;	/* 0x68 */
++	u32 gpiocontrol;	/* 0x6C */
++	u32 gpiointpolarity;	/* 0x70 */
++	u32 gpiointmask;	/* 0x74 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioevent;
++	u32 gpioeventintmask;
++
++	/* Watchdog timer */
++	u32 watchdog;	/* 0x80 */
++
++	/* GPIO events corerev >= 11 */
++	u32 gpioeventintpolarity;
++
++	/* GPIO based LED powersave registers corerev >= 16 */
++	u32 gpiotimerval;	/* 0x88 */
++	u32 gpiotimeroutmask;
++
++	/* clock control */
++	u32 clockcontrol_n;	/* 0x90 */
++	u32 clockcontrol_sb;	/* aka m0 */
++	u32 clockcontrol_pci;	/* aka m1 */
++	u32 clockcontrol_m2;	/* mii/uart/mipsref */
++	u32 clockcontrol_m3;	/* cpu */
++	u32 clkdiv;		/* corerev >= 3 */
++	u32 gpiodebugsel;	/* corerev >= 28 */
++	u32 capabilities_ext;	/* 0xac  */
++
++	/* pll delay registers (corerev >= 4) */
++	u32 pll_on_delay;	/* 0xb0 */
++	u32 fref_sel_delay;
++	u32 slow_clk_ctl;	/* 5 < corerev < 10 */
++	u32 PAD;
++
++	/* Instaclock registers (corerev >= 10) */
++	u32 system_clk_ctl;	/* 0xc0 */
++	u32 clkstatestretch;
++	u32 PAD[2];
++
++	/* Indirect backplane access (corerev >= 22) */
++	u32 bp_addrlow;	/* 0xd0 */
++	u32 bp_addrhigh;
++	u32 bp_data;
++	u32 PAD;
++	u32 bp_indaccess;
++	u32 PAD[3];
++
++	/* More clock dividers (corerev >= 32) */
++	u32 clkdiv2;
++	u32 PAD[2];
++
++	/* In AI chips, pointer to erom */
++	u32 eromptr;		/* 0xfc */
++
++	/* ExtBus control registers (corerev >= 3) */
++	u32 pcmcia_config;	/* 0x100 */
++	u32 pcmcia_memwait;
++	u32 pcmcia_attrwait;
++	u32 pcmcia_iowait;
++	u32 ide_config;
++	u32 ide_memwait;
++	u32 ide_attrwait;
++	u32 ide_iowait;
++	u32 prog_config;
++	u32 prog_waitcount;
++	u32 flash_config;
++	u32 flash_waitcount;
++	u32 SECI_config;	/* 0x130 SECI configuration */
++	u32 PAD[3];
++
++	/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
++	u32 eci_output;	/* 0x140 */
++	u32 eci_control;
++	u32 eci_inputlo;
++	u32 eci_inputmi;
++	u32 eci_inputhi;
++	u32 eci_inputintpolaritylo;
++	u32 eci_inputintpolaritymi;
++	u32 eci_inputintpolarityhi;
++	u32 eci_intmasklo;
++	u32 eci_intmaskmi;
++	u32 eci_intmaskhi;
++	u32 eci_eventlo;
++	u32 eci_eventmi;
++	u32 eci_eventhi;
++	u32 eci_eventmasklo;
++	u32 eci_eventmaskmi;
++	u32 eci_eventmaskhi;
++	u32 PAD[3];
++
++	/* SROM interface (corerev >= 32) */
++	u32 sromcontrol;	/* 0x190 */
++	u32 sromaddress;
++	u32 sromdata;
++	u32 PAD[17];
++
++	/* Clock control and hardware workarounds (corerev >= 20) */
++	u32 clk_ctl_st;	/* 0x1e0 */
++	u32 hw_war;
++	u32 PAD[70];
++
++	/* UARTs */
++	u8 uart0data;	/* 0x300 */
++	u8 uart0imr;
++	u8 uart0fcr;
++	u8 uart0lcr;
++	u8 uart0mcr;
++	u8 uart0lsr;
++	u8 uart0msr;
++	u8 uart0scratch;
++	u8 PAD[248];		/* corerev >= 1 */
++
++	u8 uart1data;	/* 0x400 */
++	u8 uart1imr;
++	u8 uart1fcr;
++	u8 uart1lcr;
++	u8 uart1mcr;
++	u8 uart1lsr;
++	u8 uart1msr;
++	u8 uart1scratch;
++	u32 PAD[126];
++
++	/* PMU registers (corerev >= 20) */
++	u32 pmucontrol;	/* 0x600 */
++	u32 pmucapabilities;
++	u32 pmustatus;
++	u32 res_state;
++	u32 res_pending;
++	u32 pmutimer;
++	u32 min_res_mask;
++	u32 max_res_mask;
++	u32 res_table_sel;
++	u32 res_dep_mask;
++	u32 res_updn_timer;
++	u32 res_timer;
++	u32 clkstretch;
++	u32 pmuwatchdog;
++	u32 gpiosel;		/* 0x638, rev >= 1 */
++	u32 gpioenable;	/* 0x63c, rev >= 1 */
++	u32 res_req_timer_sel;
++	u32 res_req_timer;
++	u32 res_req_mask;
++	u32 PAD;
++	u32 chipcontrol_addr;	/* 0x650 */
++	u32 chipcontrol_data;	/* 0x654 */
++	u32 regcontrol_addr;
++	u32 regcontrol_data;
++	u32 pllcontrol_addr;
++	u32 pllcontrol_data;
++	u32 pmustrapopt;	/* 0x668, corerev >= 28 */
++	u32 pmu_xtalfreq;	/* 0x66C, pmurev >= 10 */
++	u32 PAD[100];
++	u16 sromotp[768];
++};
++
++/* chipid */
++#define	CID_ID_MASK		0x0000ffff	/* Chip Id mask */
++#define	CID_REV_MASK		0x000f0000	/* Chip Revision mask */
++#define	CID_REV_SHIFT		16	/* Chip Revision shift */
++#define	CID_PKG_MASK		0x00f00000	/* Package Option mask */
++#define	CID_PKG_SHIFT		20	/* Package Option shift */
++#define	CID_CC_MASK		0x0f000000	/* CoreCount (corerev >= 4) */
++#define CID_CC_SHIFT		24
++#define	CID_TYPE_MASK		0xf0000000	/* Chip Type */
++#define CID_TYPE_SHIFT		28
++
++/* capabilities */
++#define	CC_CAP_UARTS_MASK	0x00000003	/* Number of UARTs */
++#define CC_CAP_MIPSEB		0x00000004	/* MIPS is in big-endian mode */
++#define CC_CAP_UCLKSEL		0x00000018	/* UARTs clock select */
++/* UARTs are driven by internal divided clock */
++#define CC_CAP_UINTCLK		0x00000008
++#define CC_CAP_UARTGPIO		0x00000020	/* UARTs own GPIOs 15:12 */
++#define CC_CAP_EXTBUS_MASK	0x000000c0	/* External bus mask */
++#define CC_CAP_EXTBUS_NONE	0x00000000	/* No ExtBus present */
++#define CC_CAP_EXTBUS_FULL	0x00000040	/* ExtBus: PCMCIA, IDE & Prog */
++#define CC_CAP_EXTBUS_PROG	0x00000080	/* ExtBus: ProgIf only */
++#define	CC_CAP_FLASH_MASK	0x00000700	/* Type of flash */
++#define	CC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
++#define CC_CAP_PWR_CTL		0x00040000	/* Power control */
++#define CC_CAP_OTPSIZE		0x00380000	/* OTP Size (0 = none) */
++#define CC_CAP_OTPSIZE_SHIFT	19	/* OTP Size shift */
++#define CC_CAP_OTPSIZE_BASE	5	/* OTP Size base */
++#define CC_CAP_JTAGP		0x00400000	/* JTAG Master Present */
++#define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
++#define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
++#define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
++#define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
++/* Nand flash present, rev >= 35 */
++#define	CC_CAP_NFLASH		0x80000000
++
++#define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
++/* GSIO (spi/i2c) present, rev >= 37 */
++#define	CC_CAP2_GSIO		0x00000002
++
++/* pmucapabilities */
++#define PCAP_REV_MASK	0x000000ff
++#define PCAP_RC_MASK	0x00001f00
++#define PCAP_RC_SHIFT	8
++#define PCAP_TC_MASK	0x0001e000
++#define PCAP_TC_SHIFT	13
++#define PCAP_PC_MASK	0x001e0000
++#define PCAP_PC_SHIFT	17
++#define PCAP_VC_MASK	0x01e00000
++#define PCAP_VC_SHIFT	21
++#define PCAP_CC_MASK	0x1e000000
++#define PCAP_CC_SHIFT	25
++#define PCAP5_PC_MASK	0x003e0000	/* PMU corerev >= 5 */
++#define PCAP5_PC_SHIFT	17
++#define PCAP5_VC_MASK	0x07c00000
++#define PCAP5_VC_SHIFT	22
++#define PCAP5_CC_MASK	0xf8000000
++#define PCAP5_CC_SHIFT	27
++
++/*
++* Maximum delay for the PMU state transition in us.
++* This is an upper bound intended for spinwaits etc.
++*/
++#define PMU_MAX_TRANSITION_DLY	15000
++
++#endif				/* _SBCHIPC_H */
+diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
+new file mode 100644
+index 0000000..f0d8c04
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/defs.h
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_DEFS_H_
++#define	_BRCM_DEFS_H_
++
++#include <linux/types.h>
++
++#define	SI_BUS			0
++#define	PCI_BUS			1
++#define	PCMCIA_BUS		2
++#define SDIO_BUS		3
++#define JTAG_BUS		4
++#define USB_BUS			5
++#define SPI_BUS			6
++
++#define	OFF	0
++#define	ON	1		/* ON = 1 */
++#define	AUTO	(-1)		/* Auto = -1 */
++
++/*
++ * Priority definitions according 802.1D
++ */
++#define	PRIO_8021D_NONE		2
++#define	PRIO_8021D_BK		1
++#define	PRIO_8021D_BE		0
++#define	PRIO_8021D_EE		3
++#define	PRIO_8021D_CL		4
++#define	PRIO_8021D_VI		5
++#define	PRIO_8021D_VO		6
++#define	PRIO_8021D_NC		7
++
++#define	MAXPRIO			7
++#define NUMPRIO			(MAXPRIO + 1)
++
++#define WL_NUMRATES		16	/* max # of rates in a rateset */
++
++#define BRCM_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
++
++#define BRCM_SET_CHANNEL	30
++#define BRCM_SET_SRL		32
++#define BRCM_SET_LRL		34
++#define BRCM_SET_BCNPRD		76
++
++#define BRCM_GET_CURR_RATESET	114	/* current rateset */
++#define BRCM_GET_PHYLIST	180
++
++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
++
++#define WL_RADIO_SW_DISABLE		(1<<0)
++#define WL_RADIO_HW_DISABLE		(1<<1)
++/* some countries don't support any channel */
++#define WL_RADIO_COUNTRY_DISABLE	(1<<3)
++
++/* Override bit for SET_TXPWR.  if set, ignore other level limits */
++#define WL_TXPWR_OVERRIDE	(1U<<31)
++
++/* band types */
++#define	BRCM_BAND_AUTO		0	/* auto-select */
++#define	BRCM_BAND_5G		1	/* 5 Ghz */
++#define	BRCM_BAND_2G		2	/* 2.4 Ghz */
++#define	BRCM_BAND_ALL		3	/* all bands */
++
++/* Values for PM */
++#define PM_OFF	0
++#define PM_MAX	1
++
++/* Message levels */
++#define LOG_ERROR_VAL		0x00000001
++#define LOG_TRACE_VAL		0x00000002
++
++#define PM_OFF	0
++#define PM_MAX	1
++#define PM_FAST 2
++
++/*
++ * Sonics Configuration Space Registers.
++ */
++
++/* core sbconfig regs are top 256bytes of regs */
++#define	SBCONFIGOFF		0xf00
++
++/* cpp contortions to concatenate w/arg prescan */
++#ifndef	PAD
++#define	_PADLINE(line)	pad ## line
++#define	_XSTR(line)	_PADLINE(line)
++#define	PAD		_XSTR(__LINE__)
++#endif
++
++#endif				/* _BRCM_DEFS_H_ */
+diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h
+new file mode 100644
+index 0000000..4e9b7e4
+--- /dev/null
++++ b/drivers/net/wireless/brcm80211/include/soc.h
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (c) 2010 Broadcom Corporation
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#ifndef	_BRCM_SOC_H
++#define	_BRCM_SOC_H
++
++#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
++
++/* core codes */
++#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
++#define	CC_CORE_ID		0x800	/* chipcommon core */
++#define	ILINE20_CORE_ID		0x801	/* iline20 core */
++#define	SRAM_CORE_ID		0x802	/* sram core */
++#define	SDRAM_CORE_ID		0x803	/* sdram core */
++#define	PCI_CORE_ID		0x804	/* pci core */
++#define	MIPS_CORE_ID		0x805	/* mips core */
++#define	ENET_CORE_ID		0x806	/* enet mac core */
++#define	CODEC_CORE_ID		0x807	/* v90 codec core */
++#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
++#define	ADSL_CORE_ID		0x809	/* ADSL core */
++#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
++#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
++#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
++#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
++#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
++#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
++#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
++#define	EXTIF_CORE_ID		0x811	/* external interface core */
++#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
++#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
++#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
++#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
++#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
++#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
++#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
++#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
++#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
++#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
++#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
++#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
++#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
++#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
++#define	PCIE_CORE_ID		0x820	/* pci express core */
++#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
++#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
++#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
++#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
++#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
++#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
++#define	PMU_CORE_ID		0x827	/* PMU core */
++#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
++#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
++#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
++#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
++#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
++#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
++#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
++#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
++#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
++#define	SC_CORE_ID		0x831	/* shared common core */
++#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
++#define	SPIH_CORE_ID		0x833	/* SPI host core */
++#define	I2S_CORE_ID		0x834	/* I2S core */
++#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
++#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
++#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
++#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
++					 * maps all unused address ranges
++					 */
++
++/* Common core control flags */
++#define	SICF_BIST_EN		0x8000
++#define	SICF_PME_EN		0x4000
++#define	SICF_CORE_BITS		0x3ffc
++#define	SICF_FGC		0x0002
++#define	SICF_CLOCK_EN		0x0001
++
++/* Common core status flags */
++#define	SISF_BIST_DONE		0x8000
++#define	SISF_BIST_ERROR		0x4000
++#define	SISF_GATED_CLK		0x2000
++#define	SISF_DMA64		0x1000
++#define	SISF_CORE_BITS		0x0fff
++
++#endif				/* _BRCM_SOC_H */
+-- 
+1.7.9.5
+
diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
new file mode 100644
index 0000000..96d3ce1
--- /dev/null
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch
@@ -0,0 +1,123141 @@
+From 748eb185cad62c456dcd316c941f9835520a946d Mon Sep 17 00:00:00 2001
+From: John Weber <rjohnweber@gmail.com>
+Date: Sat, 9 Mar 2013 09:23:58 -0600
+Subject: [meta-fsl-arm-extra][PATCH 1/2] linux-imx (3.0.35): remove brcm80211
+ staging driver
+
+Upstream-Status: Pending
+
+Signed-off-by: John Weber <rjohnweber@gmail.com>
+---
+ drivers/staging/Kconfig                            |    2 -
+ drivers/staging/Makefile                           |    2 -
+ drivers/staging/brcm80211/Kconfig                  |   40 -
+ drivers/staging/brcm80211/Makefile                 |   24 -
+ drivers/staging/brcm80211/README                   |   64 -
+ drivers/staging/brcm80211/TODO                     |   15 -
+ drivers/staging/brcm80211/brcmfmac/Makefile        |   56 -
+ drivers/staging/brcm80211/brcmfmac/README          |    2 -
+ drivers/staging/brcm80211/brcmfmac/aiutils.c       |    1 -
+ drivers/staging/brcm80211/brcmfmac/bcmcdc.h        |   98 -
+ drivers/staging/brcm80211/brcmfmac/bcmchip.h       |   35 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdbus.h      |  113 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh.c        |  631 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c  |  386 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c  | 1239 -
+ drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h  |  134 -
+ .../brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c        |  235 -
+ drivers/staging/brcm80211/brcmfmac/dhd.h           |  414 -
+ drivers/staging/brcm80211/brcmfmac/dhd_bus.h       |   82 -
+ drivers/staging/brcm80211/brcmfmac/dhd_cdc.c       |  474 -
+ drivers/staging/brcm80211/brcmfmac/dhd_common.c    | 1848 --
+ .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c   |  158 -
+ drivers/staging/brcm80211/brcmfmac/dhd_dbg.h       |  103 -
+ drivers/staging/brcm80211/brcmfmac/dhd_linux.c     | 2862 --
+ .../staging/brcm80211/brcmfmac/dhd_linux_sched.c   |   25 -
+ drivers/staging/brcm80211/brcmfmac/dhd_proto.h     |   90 -
+ drivers/staging/brcm80211/brcmfmac/dhd_sdio.c      | 6390 -----
+ drivers/staging/brcm80211/brcmfmac/dhdioctl.h      |  100 -
+ drivers/staging/brcm80211/brcmfmac/dngl_stats.h    |   32 -
+ .../staging/brcm80211/brcmfmac/hndrte_armtrap.h    |   75 -
+ drivers/staging/brcm80211/brcmfmac/hndrte_cons.h   |   62 -
+ drivers/staging/brcm80211/brcmfmac/msgtrace.h      |   61 -
+ drivers/staging/brcm80211/brcmfmac/sdioh.h         |   63 -
+ drivers/staging/brcm80211/brcmfmac/sdiovar.h       |   38 -
+ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c   | 4428 ---
+ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h   |  414 -
+ drivers/staging/brcm80211/brcmfmac/wl_iw.c         | 3693 ---
+ drivers/staging/brcm80211/brcmfmac/wl_iw.h         |  142 -
+ drivers/staging/brcm80211/brcmsmac/Makefile        |   59 -
+ drivers/staging/brcm80211/brcmsmac/aiutils.c       | 2054 --
+ drivers/staging/brcm80211/brcmsmac/aiutils.h       |  546 -
+ drivers/staging/brcm80211/brcmsmac/bcmotp.c        |  936 -
+ drivers/staging/brcm80211/brcmsmac/bcmsrom.c       |  714 -
+ drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h   |  513 -
+ drivers/staging/brcm80211/brcmsmac/d11.h           | 1773 --
+ drivers/staging/brcm80211/brcmsmac/hnddma.c        | 1756 --
+ drivers/staging/brcm80211/brcmsmac/nicpci.c        |  836 -
+ drivers/staging/brcm80211/brcmsmac/nvram.c         |  215 -
+ .../staging/brcm80211/brcmsmac/phy/phy_version.h   |   36 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c   | 3307 ---
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h   |  256 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_int.h   | 1226 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c   | 5302 ----
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h   |  119 -
+ drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c |29169 --------------------
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c |  296 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h |   40 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h | 1533 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h  |  167 -
+ .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c        | 3639 ---
+ .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h        |   49 -
+ .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c  |10632 -------
+ .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h  |   39 -
+ drivers/staging/brcm80211/brcmsmac/wl_dbg.h        |   92 -
+ drivers/staging/brcm80211/brcmsmac/wl_export.h     |   47 -
+ drivers/staging/brcm80211/brcmsmac/wl_mac80211.c   | 1942 --
+ drivers/staging/brcm80211/brcmsmac/wl_mac80211.h   |   85 -
+ drivers/staging/brcm80211/brcmsmac/wl_ucode.h      |   49 -
+ .../staging/brcm80211/brcmsmac/wl_ucode_loader.c   |  111 -
+ drivers/staging/brcm80211/brcmsmac/wlc_alloc.c     |  300 -
+ drivers/staging/brcm80211/brcmsmac/wlc_alloc.h     |   18 -
+ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c     | 1253 -
+ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h     |   29 -
+ drivers/staging/brcm80211/brcmsmac/wlc_antsel.c    |  320 -
+ drivers/staging/brcm80211/brcmsmac/wlc_antsel.h    |   29 -
+ drivers/staging/brcm80211/brcmsmac/wlc_bmac.c      | 3602 ---
+ drivers/staging/brcm80211/brcmsmac/wlc_bmac.h      |  179 -
+ drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h    |  135 -
+ drivers/staging/brcm80211/brcmsmac/wlc_cfg.h       |  280 -
+ drivers/staging/brcm80211/brcmsmac/wlc_channel.c   | 1557 --
+ drivers/staging/brcm80211/brcmsmac/wlc_channel.h   |  120 -
+ drivers/staging/brcm80211/brcmsmac/wlc_key.h       |  140 -
+ drivers/staging/brcm80211/brcmsmac/wlc_main.c      | 7537 -----
+ drivers/staging/brcm80211/brcmsmac/wlc_main.h      |  939 -
+ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c  |  243 -
+ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h  |  112 -
+ drivers/staging/brcm80211/brcmsmac/wlc_pmu.c       | 1929 --
+ drivers/staging/brcm80211/brcmsmac/wlc_pmu.h       |   58 -
+ drivers/staging/brcm80211/brcmsmac/wlc_pub.h       |  584 -
+ drivers/staging/brcm80211/brcmsmac/wlc_rate.c      |  499 -
+ drivers/staging/brcm80211/brcmsmac/wlc_rate.h      |  169 -
+ drivers/staging/brcm80211/brcmsmac/wlc_scb.h       |   80 -
+ drivers/staging/brcm80211/brcmsmac/wlc_stf.c       |  523 -
+ drivers/staging/brcm80211/brcmsmac/wlc_stf.h       |   38 -
+ drivers/staging/brcm80211/brcmsmac/wlc_types.h     |   37 -
+ drivers/staging/brcm80211/include/aidmp.h          |  374 -
+ drivers/staging/brcm80211/include/bcmdefs.h        |  150 -
+ drivers/staging/brcm80211/include/bcmdevs.h        |  124 -
+ drivers/staging/brcm80211/include/bcmnvram.h       |  153 -
+ drivers/staging/brcm80211/include/bcmotp.h         |   44 -
+ drivers/staging/brcm80211/include/bcmsdh.h         |  205 -
+ drivers/staging/brcm80211/include/bcmsdpcm.h       |  208 -
+ drivers/staging/brcm80211/include/bcmsrom.h        |   34 -
+ drivers/staging/brcm80211/include/bcmsrom_fmt.h    |  367 -
+ drivers/staging/brcm80211/include/bcmutils.h       |  500 -
+ drivers/staging/brcm80211/include/bcmwifi.h        |  167 -
+ drivers/staging/brcm80211/include/hnddma.h         |  226 -
+ drivers/staging/brcm80211/include/hndsoc.h         |  199 -
+ drivers/staging/brcm80211/include/nicpci.h         |   79 -
+ drivers/staging/brcm80211/include/pci_core.h       |  122 -
+ drivers/staging/brcm80211/include/pcicfg.h         |   50 -
+ drivers/staging/brcm80211/include/pcie_core.h      |  299 -
+ drivers/staging/brcm80211/include/proto/802.11.h   |  200 -
+ drivers/staging/brcm80211/include/proto/bcmeth.h   |   44 -
+ drivers/staging/brcm80211/include/proto/bcmevent.h |  207 -
+ drivers/staging/brcm80211/include/sbchipc.h        | 1588 --
+ drivers/staging/brcm80211/include/sbconfig.h       |  272 -
+ drivers/staging/brcm80211/include/sbhnddma.h       |  315 -
+ drivers/staging/brcm80211/include/sbsdio.h         |  152 -
+ drivers/staging/brcm80211/include/sbsdpcmdev.h     |  281 -
+ drivers/staging/brcm80211/include/sdio.h           |  552 -
+ drivers/staging/brcm80211/include/wlioctl.h        | 1365 -
+ drivers/staging/brcm80211/util/Makefile            |   29 -
+ drivers/staging/brcm80211/util/bcmutils.c          |  796 -
+ drivers/staging/brcm80211/util/bcmwifi.c           |  137 -
+ 125 files changed, 122118 deletions(-)
+ delete mode 100644 drivers/staging/brcm80211/Kconfig
+ delete mode 100644 drivers/staging/brcm80211/Makefile
+ delete mode 100644 drivers/staging/brcm80211/README
+ delete mode 100644 drivers/staging/brcm80211/TODO
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/Makefile
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/README
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/aiutils.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmcdc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmchip.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_bus.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_common.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_proto.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dhdioctl.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/dngl_stats.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/msgtrace.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/sdioh.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/sdiovar.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.c
+ delete mode 100644 drivers/staging/brcm80211/brcmfmac/wl_iw.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/Makefile
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/aiutils.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/aiutils.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmotp.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmsrom.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/d11.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/hnddma.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/nicpci.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/nvram.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_dbg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_export.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_key.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pub.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_scb.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.c
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.h
+ delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_types.h
+ delete mode 100644 drivers/staging/brcm80211/include/aidmp.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmdefs.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmdevs.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmnvram.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmotp.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsdh.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsdpcm.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsrom.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmsrom_fmt.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmutils.h
+ delete mode 100644 drivers/staging/brcm80211/include/bcmwifi.h
+ delete mode 100644 drivers/staging/brcm80211/include/hnddma.h
+ delete mode 100644 drivers/staging/brcm80211/include/hndsoc.h
+ delete mode 100644 drivers/staging/brcm80211/include/nicpci.h
+ delete mode 100644 drivers/staging/brcm80211/include/pci_core.h
+ delete mode 100644 drivers/staging/brcm80211/include/pcicfg.h
+ delete mode 100644 drivers/staging/brcm80211/include/pcie_core.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/802.11.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/bcmeth.h
+ delete mode 100644 drivers/staging/brcm80211/include/proto/bcmevent.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbchipc.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbconfig.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbhnddma.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbsdio.h
+ delete mode 100644 drivers/staging/brcm80211/include/sbsdpcmdev.h
+ delete mode 100644 drivers/staging/brcm80211/include/sdio.h
+ delete mode 100644 drivers/staging/brcm80211/include/wlioctl.h
+ delete mode 100644 drivers/staging/brcm80211/util/Makefile
+ delete mode 100644 drivers/staging/brcm80211/util/bcmutils.c
+ delete mode 100644 drivers/staging/brcm80211/util/bcmwifi.c
+
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+index 196284d..f73909f 100644
+--- a/drivers/staging/Kconfig
++++ b/drivers/staging/Kconfig
+@@ -48,8 +48,6 @@ source "drivers/staging/wlan-ng/Kconfig"
+ 
+ source "drivers/staging/echo/Kconfig"
+ 
+-source "drivers/staging/brcm80211/Kconfig"
+-
+ source "drivers/staging/comedi/Kconfig"
+ 
+ source "drivers/staging/olpc_dcon/Kconfig"
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
+index fa41b9c..482897c 100644
+--- a/drivers/staging/Makefile
++++ b/drivers/staging/Makefile
+@@ -16,8 +16,6 @@ obj-$(CONFIG_USBIP_CORE)	+= usbip/
+ obj-$(CONFIG_W35UND)		+= winbond/
+ obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
+ obj-$(CONFIG_ECHO)		+= echo/
+-obj-$(CONFIG_BRCMSMAC)		+= brcm80211/
+-obj-$(CONFIG_BRCMFMAC)		+= brcm80211/
+ obj-$(CONFIG_COMEDI)		+= comedi/
+ obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
+ obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
+diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig
+deleted file mode 100644
+index 379cf16..0000000
+--- a/drivers/staging/brcm80211/Kconfig
++++ /dev/null
+@@ -1,40 +0,0 @@
+-config BRCMUTIL
+-	tristate
+-	default n
+-
+-config BRCMSMAC
+-	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
+-	default n
+-	depends on PCI
+-	depends on WLAN && MAC80211
+-	depends on X86 || MIPS
+-	select BRCMUTIL
+-	select FW_LOADER
+-	select CRC_CCITT
+-	---help---
+-	  This module adds support for PCIe wireless adapters based on Broadcom
+-	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
+-	  be called brcmsmac.ko.
+-
+-config BRCMFMAC
+-	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
+-	default n
+-	depends on MMC
+-	depends on WLAN && CFG80211
+-	depends on X86 || MIPS
+-	select BRCMUTIL
+-	select FW_LOADER
+-	select WIRELESS_EXT
+-	select WEXT_PRIV
+-	---help---
+-	  This module adds support for embedded wireless adapters based on
+-	  Broadcom IEEE802.11n FullMAC chipsets.  This driver uses the kernel's
+-	  wireless extensions subsystem.  If you choose to build a module,
+-	  it'll be called brcmfmac.ko.
+-
+-config BRCMDBG
+-	bool "Broadcom driver debug functions"
+-	default n
+-	depends on BRCMSMAC || BRCMFMAC
+-	---help---
+-	  Selecting this enables additional code for debug purposes.
+diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile
+deleted file mode 100644
+index e7b3f27..0000000
+--- a/drivers/staging/brcm80211/Makefile
++++ /dev/null
+@@ -1,24 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-# common flags
+-subdir-ccflags-y					:= -DBCMDMA32
+-subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DBCMDBG -DBCMDBG_ASSERT
+-
+-obj-$(CONFIG_BRCMUTIL)	+= util/
+-obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
+-obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
+diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README
+deleted file mode 100644
+index 8ad5586..0000000
+--- a/drivers/staging/brcm80211/README
++++ /dev/null
+@@ -1,64 +0,0 @@
+-Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers.
+-
+-Completely open source host drivers, no binary object files.
+-
+-Support for the following chips:
+-===============================
+-
+-    brcmsmac (PCIe)
+-    Name        Device ID
+-    BCM4313     0x4727
+-    BCM43224    0x4353
+-    BCM43225    0x4357
+-
+-    brcmfmac (SDIO)
+-    Name
+-    BCM4329
+-
+-Both brcmsmac and brcmfmac drivers require firmware files that need to be
+-separately downloaded.
+-
+-Firmware
+-======================
+-Firmware is available from the Linux firmware repository at:
+-
+-    git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git
+-    http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+-    https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git
+-
+-
+-===============================================================
+-Broadcom brcmsmac driver
+-===============================================================
+-- Support for both 32 and 64 bit Linux kernels
+-
+-
+-Firmware installation
+-======================
+-Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to
+-/lib/firmware/brcm (or wherever firmware is normally installed
+-on your system).
+-
+-
+-===============================================================
+-Broadcom brcmfmac driver
+-===============================================================
+-- Support for 32 bit Linux kernel, 64 bit untested
+-
+-
+-Firmware installation
+-======================
+-Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt
+-to /lib/firmware/brcm (or wherever firmware is normally installed on your
+-system).
+-
+-
+-Contact Info:
+-=============
+-Brett Rudley		brudley@broadcom.com
+-Henry Ptasinski		henryp@broadcom.com
+-Dowan Kim		dowan@broadcom.com
+-Roland Vossen		rvossen@broadcom.com
+-Arend van Spriel	arend@broadcom.com
+-
+-For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
+diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO
+deleted file mode 100644
+index e9c1393..0000000
+--- a/drivers/staging/brcm80211/TODO
++++ /dev/null
+@@ -1,15 +0,0 @@
+-To Do List for Broadcom Mac80211 driver before getting in mainline
+-
+-Bugs
+-====
+-- Oops on AMPDU traffic, to be solved by new ucode (currently under test)
+-
+-brcmfmac and brcmsmac
+-=====================
+-- ASSERTS not allowed in mainline, replace by warning + error handling
+-- Replace printk and WL_ERROR() with proper routines
+-
+-brcmfmac
+-=====================
+-- Replace driver's proprietary ssb interface with generic kernel ssb module
+-- Build and test on 64 bit linux kernel
+diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile
+deleted file mode 100644
+index c5ec562..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/Makefile
++++ /dev/null
+@@ -1,56 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=			\
+-	-DARP_OFFLOAD_SUPPORT	\
+-	-DBCMLXSDMMC		\
+-	-DBCMPLATFORM_BUS	\
+-	-DBCMSDIO		\
+-	-DBDC			\
+-	-DBRCM_FULLMAC		\
+-	-DDHD_FIRSTREAD=64	\
+-	-DDHD_SCHED		\
+-	-DDHD_SDALIGN=64	\
+-	-DEMBEDDED_PLATFORM	\
+-	-DMAX_HDR_READ=64	\
+-	-DMMC_SDIO_ABORT	\
+-	-DPKT_FILTER_SUPPORT	\
+-	-DSHOW_EVENTS		\
+-	-DTOE
+-
+-ccflags-$(CONFIG_BRCMDBG)	+= -DDHD_DEBUG
+-
+-ccflags-y += \
+-	-Idrivers/staging/brcm80211/brcmfmac	\
+-	-Idrivers/staging/brcm80211/include
+-
+-DHDOFILES = \
+-	wl_cfg80211.o \
+-	wl_iw.o \
+-	dhd_cdc.o \
+-	dhd_common.o \
+-	dhd_custom_gpio.o \
+-	dhd_sdio.o	\
+-	dhd_linux.o \
+-	dhd_linux_sched.o \
+-	bcmsdh.o \
+-	bcmsdh_linux.o	\
+-	bcmsdh_sdmmc.o \
+-	bcmsdh_sdmmc_linux.o
+-
+-obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
+-brcmfmac-objs += $(DHDOFILES)
+diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README
+deleted file mode 100644
+index 139597f..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/README
++++ /dev/null
+@@ -1,2 +0,0 @@
+-
+-
+diff --git a/drivers/staging/brcm80211/brcmfmac/aiutils.c b/drivers/staging/brcm80211/brcmfmac/aiutils.c
+deleted file mode 100644
+index e648086..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/aiutils.c
++++ /dev/null
+@@ -1 +0,0 @@
+-#include "../util/aiutils.c"
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h b/drivers/staging/brcm80211/brcmfmac/bcmcdc.h
+deleted file mode 100644
+index ed4c4a5..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/if_ether.h>
+-
+-typedef struct cdc_ioctl {
+-	u32 cmd;		/* ioctl command value */
+-	u32 len;		/* lower 16: output buflen; upper 16:
+-				 input buflen (excludes header) */
+-	u32 flags;		/* flag defns given below */
+-	u32 status;		/* status code returned from the device */
+-} cdc_ioctl_t;
+-
+-/* Max valid buffer size that can be sent to the dongle */
+-#define CDC_MAX_MSG_SIZE	(ETH_FRAME_LEN+ETH_FCS_LEN)
+-
+-/* len field is divided into input and output buffer lengths */
+-#define CDCL_IOC_OUTLEN_MASK   0x0000FFFF	/* maximum or expected
+-						 response length, */
+-					   /* excluding IOCTL header */
+-#define CDCL_IOC_OUTLEN_SHIFT  0
+-#define CDCL_IOC_INLEN_MASK    0xFFFF0000	/* input buffer length,
+-						 excluding IOCTL header */
+-#define CDCL_IOC_INLEN_SHIFT   16
+-
+-/* CDC flag definitions */
+-#define CDCF_IOC_ERROR		0x01	/* 0=success, 1=ioctl cmd failed */
+-#define CDCF_IOC_SET		0x02	/* 0=get, 1=set cmd */
+-#define CDCF_IOC_IF_MASK	0xF000	/* I/F index */
+-#define CDCF_IOC_IF_SHIFT	12
+-#define CDCF_IOC_ID_MASK	0xFFFF0000	/* used to uniquely id an ioctl
+-						 req/resp pairing */
+-#define CDCF_IOC_ID_SHIFT	16	/* # of bits of shift for ID Mask */
+-
+-#define CDC_IOC_IF_IDX(flags)	\
+-	(((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)
+-#define CDC_IOC_ID(flags)	\
+-	(((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT)
+-
+-#define CDC_GET_IF_IDX(hdr) \
+-	((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT))
+-#define CDC_SET_IF_IDX(hdr, idx) \
+-	((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \
+-	((idx) << CDCF_IOC_IF_SHIFT)))
+-
+-/*
+- * BDC header
+- *
+- *   The BDC header is used on data packets to convey priority across USB.
+- */
+-
+-#define	BDC_HEADER_LEN		4
+-
+-#define BDC_PROTO_VER		1	/* Protocol version */
+-
+-#define BDC_FLAG_VER_MASK	0xf0	/* Protocol version mask */
+-#define BDC_FLAG_VER_SHIFT	4	/* Protocol version shift */
+-
+-#define BDC_FLAG__UNUSED	0x03	/* Unassigned */
+-#define BDC_FLAG_SUM_GOOD	0x04	/* Dongle has verified good
+-					 RX checksums */
+-#define BDC_FLAG_SUM_NEEDED	0x08	/* Dongle needs to do TX checksums */
+-
+-#define BDC_PRIORITY_MASK	0x7
+-
+-#define BDC_FLAG2_FC_FLAG	0x10	/* flag to indicate if pkt contains */
+-						/* FLOW CONTROL info only */
+-#define BDC_PRIORITY_FC_SHIFT	4	/* flow control info shift */
+-
+-#define BDC_FLAG2_IF_MASK	0x0f	/* APSTA: interface on which the
+-					 packet was received */
+-#define BDC_FLAG2_IF_SHIFT	0
+-
+-#define BDC_GET_IF_IDX(hdr) \
+-	((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
+-#define BDC_SET_IF_IDX(hdr, idx) \
+-	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
+-	((idx) << BDC_FLAG2_IF_SHIFT)))
+-
+-struct bdc_header {
+-	u8 flags;		/* Flags */
+-	u8 priority;		/* 802.1d Priority 0:2 bits, 4:7 flow
+-				 control info for usb */
+-	u8 flags2;
+-	u8 rssi;
+-};
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmchip.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h
+deleted file mode 100644
+index c0d4c3b..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmchip.h
++++ /dev/null
+@@ -1,35 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _bcmchip_h_
+-#define _bcmchip_h_
+-
+-/* Core reg address translation */
+-#define CORE_CC_REG(base, field)	(base + offsetof(chipcregs_t, field))
+-#define CORE_BUS_REG(base, field)	(base + offsetof(sdpcmd_regs_t, field))
+-#define CORE_SB(base, field) \
+-		(base + SBCONFIGOFF + offsetof(sbconfig_t, field))
+-
+-/* bcm4329 */
+-/* SDIO device core, ID 0x829 */
+-#define BCM4329_CORE_BUS_BASE		0x18011000
+-/* internal memory core, ID 0x80e */
+-#define BCM4329_CORE_SOCRAM_BASE	0x18003000
+-/* ARM Cortex M3 core, ID 0x82a */
+-#define BCM4329_CORE_ARM_BASE		0x18002000
+-#define BCM4329_RAMSIZE			0x48000
+-
+-#endif				/* _bcmchip_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
+deleted file mode 100644
+index 53c3291..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h
++++ /dev/null
+@@ -1,113 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sdio_api_h_
+-#define	_sdio_api_h_
+-
+-#define SDIOH_API_RC_SUCCESS                          (0x00)
+-#define SDIOH_API_RC_FAIL	                      (0x01)
+-#define SDIOH_API_SUCCESS(status) (status == 0)
+-
+-#define SDIOH_READ              0	/* Read request */
+-#define SDIOH_WRITE             1	/* Write request */
+-
+-#define SDIOH_DATA_FIX          0	/* Fixed addressing */
+-#define SDIOH_DATA_INC          1	/* Incremental addressing */
+-
+-#define SDIOH_CMD_TYPE_NORMAL   0	/* Normal command */
+-#define SDIOH_CMD_TYPE_APPEND   1	/* Append command */
+-#define SDIOH_CMD_TYPE_CUTTHRU  2	/* Cut-through command */
+-
+-#define SDIOH_DATA_PIO          0	/* PIO mode */
+-#define SDIOH_DATA_DMA          1	/* DMA mode */
+-
+-typedef int SDIOH_API_RC;
+-
+-/* SDio Host structure */
+-typedef struct sdioh_info sdioh_info_t;
+-
+-/* callback function, taking one arg */
+-typedef void (*sdioh_cb_fn_t) (void *);
+-
+-/* attach, return handler on success, NULL if failed.
+- *  The handler shall be provided by all subsequent calls. No local cache
+- *  cfghdl points to the starting address of pci device mapped memory
+- */
+-extern sdioh_info_t *sdioh_attach(void *cfghdl, uint irq);
+-extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si);
+-extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si,
+-					     sdioh_cb_fn_t fn, void *argh);
+-extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si);
+-
+-/* query whether SD interrupt is enabled or not */
+-extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff);
+-
+-/* enable or disable SD interrupt */
+-extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable);
+-
+-#if defined(DHD_DEBUG)
+-extern bool sdioh_interrupt_pending(sdioh_info_t *si);
+-#endif
+-
+-extern int sdioh_claim_host_and_lock(sdioh_info_t *si);
+-extern int sdioh_release_host_and_unlock(sdioh_info_t *si);
+-
+-/* read or write one byte using cmd52 */
+-extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc,
+-				       uint addr, u8 *byte);
+-
+-/* read or write 2/4 bytes using cmd53 */
+-extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type,
+-				       uint rw, uint fnc, uint addr,
+-				       u32 *word, uint nbyte);
+-
+-/* read or write any buffer using cmd53 */
+-extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma,
+-					 uint fix_inc, uint rw, uint fnc_num,
+-					 u32 addr, uint regwidth,
+-					 u32 buflen, u8 *buffer,
+-					 struct sk_buff *pkt);
+-
+-/* get cis data */
+-extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis,
+-				   u32 length);
+-
+-extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr,
+-				   u8 *data);
+-extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr,
+-				    u8 *data);
+-
+-/* query number of io functions */
+-extern uint sdioh_query_iofnum(sdioh_info_t *si);
+-
+-/* handle iovars */
+-extern int sdioh_iovar_op(sdioh_info_t *si, const char *name,
+-			  void *params, int plen, void *arg, int len, bool set);
+-
+-/* Issue abort to the specified function and clear controller as needed */
+-extern int sdioh_abort(sdioh_info_t *si, uint fnc);
+-
+-/* Start and Stop SDIO without re-enumerating the SD card. */
+-extern int sdioh_start(sdioh_info_t *si, int stage);
+-extern int sdioh_stop(sdioh_info_t *si);
+-
+-/* Reset and re-initialize the device */
+-extern int sdioh_sdio_reset(sdioh_info_t *si);
+-
+-/* Helper function */
+-void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+-
+-#endif				/* _sdio_api_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
+deleted file mode 100644
+index 3750fcf..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
++++ /dev/null
+@@ -1,631 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-/* ****************** BCMSDH Interface Functions *************************** */
+-
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <linux/pci_ids.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <hndsoc.h>
+-
+-#include <bcmsdh.h>		/* BRCM API for SDIO
+-			 clients (such as wl, dhd) */
+-#include <bcmsdbus.h>		/* common SDIO/controller interface */
+-#include <sbsdio.h>		/* BRCM sdio device core */
+-
+-#include <sdio.h>		/* sdio spec */
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-#define SDIOH_API_ACCESS_RETRY_LIMIT	2
+-const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
+-
+-struct bcmsdh_info {
+-	bool init_success;	/* underlying driver successfully attached */
+-	void *sdioh;		/* handler for sdioh */
+-	u32 vendevid;	/* Target Vendor and Device ID on SD bus */
+-	bool regfail;		/* Save status of last
+-				 reg_read/reg_write call */
+-	u32 sbwad;		/* Save backplane window address */
+-};
+-/* local copy of bcm sd handler */
+-bcmsdh_info_t *l_bcmsdh;
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
+-
+-void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
+-{
+-	sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
+-}
+-#endif
+-
+-bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq)
+-{
+-	bcmsdh_info_t *bcmsdh;
+-
+-	bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC);
+-	if (bcmsdh == NULL) {
+-		BCMSDH_ERROR(("bcmsdh_attach: out of memory"));
+-		return NULL;
+-	}
+-
+-	/* save the handler locally */
+-	l_bcmsdh = bcmsdh;
+-
+-	bcmsdh->sdioh = sdioh_attach(cfghdl, irq);
+-	if (!bcmsdh->sdioh) {
+-		bcmsdh_detach(bcmsdh);
+-		return NULL;
+-	}
+-
+-	bcmsdh->init_success = true;
+-
+-	*regsva = (u32 *) SI_ENUM_BASE;
+-
+-	/* Report the BAR, to fix if needed */
+-	bcmsdh->sbwad = SI_ENUM_BASE;
+-	return bcmsdh;
+-}
+-
+-int bcmsdh_detach(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (bcmsdh != NULL) {
+-		if (bcmsdh->sdioh) {
+-			sdioh_detach(bcmsdh->sdioh);
+-			bcmsdh->sdioh = NULL;
+-		}
+-		kfree(bcmsdh);
+-	}
+-
+-	l_bcmsdh = NULL;
+-	return 0;
+-}
+-
+-int
+-bcmsdh_iovar_op(void *sdh, const char *name,
+-		void *params, int plen, void *arg, int len, bool set)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
+-}
+-
+-bool bcmsdh_intr_query(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	bool on;
+-
+-	ASSERT(bcmsdh);
+-	status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
+-	if (SDIOH_API_SUCCESS(status))
+-		return false;
+-	else
+-		return on;
+-}
+-
+-int bcmsdh_intr_enable(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_set(bcmsdh->sdioh, true);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_disable(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_set(bcmsdh->sdioh, false);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_intr_dereg(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	ASSERT(bcmsdh);
+-
+-	status = sdioh_interrupt_deregister(bcmsdh->sdioh);
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-#if defined(DHD_DEBUG)
+-bool bcmsdh_intr_pending(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	ASSERT(sdh);
+-	return sdioh_interrupt_pending(bcmsdh->sdioh);
+-}
+-#endif
+-
+-int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+-{
+-	ASSERT(sdh);
+-
+-	/* don't support yet */
+-	return -ENOTSUPP;
+-}
+-
+-u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	s32 retry = 0;
+-#endif
+-	u8 data = 0;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	do {
+-		if (retry)	/* wait for 1 ms till bus get settled down */
+-			udelay(1000);
+-#endif
+-		status =
+-		    sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr,
+-				   (u8 *) &data);
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	} while (!SDIOH_API_SUCCESS(status)
+-		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+-#endif
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-
+-	return data;
+-}
+-
+-void
+-bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	s32 retry = 0;
+-#endif
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	do {
+-		if (retry)	/* wait for 1 ms till bus get settled down */
+-			udelay(1000);
+-#endif
+-		status =
+-		    sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr,
+-				    (u8 *) &data);
+-#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+-	} while (!SDIOH_API_SUCCESS(status)
+-		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+-#endif
+-	if (err)
+-		*err = SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-}
+-
+-u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	u32 data = 0;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ,
+-			       fnc_num, addr, &data, 4);
+-
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-
+-	return data;
+-}
+-
+-void
+-bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data,
+-		      int *err)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-			       SDIOH_WRITE, fnc_num, addr, &data, 4);
+-
+-	if (err)
+-		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
+-		     __func__, fnc_num, addr, data));
+-}
+-
+-int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	u8 *tmp_buf, *tmp_ptr;
+-	u8 *ptr;
+-	bool ascii = func & ~0xf;
+-	func &= 0x7;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-	ASSERT(cis);
+-	ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
+-
+-	status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
+-
+-	if (ascii) {
+-		/* Move binary bits to tmp and format them
+-			 into the provided buffer. */
+-		tmp_buf = kmalloc(length, GFP_ATOMIC);
+-		if (tmp_buf == NULL) {
+-			BCMSDH_ERROR(("%s: out of memory\n", __func__));
+-			return -ENOMEM;
+-		}
+-		memcpy(tmp_buf, cis, length);
+-		for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
+-		     tmp_ptr++) {
+-			ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
+-			if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
+-				ptr += sprintf((char *)ptr, "\n");
+-		}
+-		kfree(tmp_buf);
+-	}
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
+-{
+-	int err = 0;
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+-			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+-				 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+-				 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
+-				 &err);
+-
+-	return err;
+-}
+-
+-u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	u32 word = 0;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0))
+-			return 0xFFFFFFFF;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	if (size == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-				    SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
+-
+-	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+-
+-	BCMSDH_INFO(("u32data = 0x%x\n", word));
+-
+-	/* if ok, return appropriately masked word */
+-	if (SDIOH_API_SUCCESS(status)) {
+-		switch (size) {
+-		case sizeof(u8):
+-			return word & 0xff;
+-		case sizeof(u16):
+-			return word & 0xffff;
+-		case sizeof(u32):
+-			return word;
+-		default:
+-			bcmsdh->regfail = true;
+-
+-		}
+-	}
+-
+-	/* otherwise, bad sdio access or invalid size */
+-	BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
+-		      addr, size));
+-	return 0xFFFFFFFF;
+-}
+-
+-u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
+-		     __func__, addr, size * 8, data));
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	ASSERT(bcmsdh->init_success);
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	if (size == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-	status =
+-	    sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+-			       SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
+-	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+-
+-	if (SDIOH_API_SUCCESS(status))
+-		return 0;
+-
+-	BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
+-		      __func__, data, addr, size));
+-	return 0xFFFFFFFF;
+-}
+-
+-bool bcmsdh_regfail(void *sdh)
+-{
+-	return ((bcmsdh_info_t *) sdh)->regfail;
+-}
+-
+-int
+-bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
+-		u8 *buf, uint nbytes, struct sk_buff *pkt,
+-		bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint incr_fix;
+-	uint width;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+-		     __func__, fn, addr, nbytes));
+-
+-	/* Async not implemented yet */
+-	ASSERT(!(flags & SDIO_REQ_ASYNC));
+-	if (flags & SDIO_REQ_ASYNC)
+-		return -ENOTSUPP;
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+-	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+-	if (width == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+-				      SDIOH_READ, fn, addr, width, nbytes, buf,
+-				      pkt);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int
+-bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
+-		u8 *buf, uint nbytes, void *pkt,
+-		bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-	uint incr_fix;
+-	uint width;
+-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+-	int err = 0;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-
+-	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+-		     __func__, fn, addr, nbytes));
+-
+-	/* Async not implemented yet */
+-	ASSERT(!(flags & SDIO_REQ_ASYNC));
+-	if (flags & SDIO_REQ_ASYNC)
+-		return -ENOTSUPP;
+-
+-	if (bar0 != bcmsdh->sbwad) {
+-		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
+-		if (err)
+-			return err;
+-
+-		bcmsdh->sbwad = bar0;
+-	}
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-
+-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+-	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+-	if (width == 4)
+-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+-				      SDIOH_WRITE, fn, addr, width, nbytes, buf,
+-				      pkt);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	SDIOH_API_RC status;
+-
+-	ASSERT(bcmsdh);
+-	ASSERT(bcmsdh->init_success);
+-	ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
+-
+-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+-	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+-
+-	status =
+-	    sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
+-				 (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
+-				 addr, 4, nbytes, buf, NULL);
+-
+-	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
+-}
+-
+-int bcmsdh_abort(void *sdh, uint fn)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_abort(bcmsdh->sdioh, fn);
+-}
+-
+-int bcmsdh_start(void *sdh, int stage)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_start(bcmsdh->sdioh, stage);
+-}
+-
+-int bcmsdh_stop(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_stop(bcmsdh->sdioh);
+-}
+-
+-int bcmsdh_query_device(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-	bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
+-	return bcmsdh->vendevid;
+-}
+-
+-uint bcmsdh_query_iofnum(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	return sdioh_query_iofnum(bcmsdh->sdioh);
+-}
+-
+-int bcmsdh_reset(bcmsdh_info_t *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	return sdioh_sdio_reset(bcmsdh->sdioh);
+-}
+-
+-void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
+-{
+-	ASSERT(sdh);
+-	return sdh->sdioh;
+-}
+-
+-/* Function to pass device-status bits to DHD. */
+-u32 bcmsdh_get_dstatus(void *sdh)
+-{
+-	return 0;
+-}
+-
+-u32 bcmsdh_cur_sbwad(void *sdh)
+-{
+-	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
+-
+-	if (!bcmsdh)
+-		bcmsdh = l_bcmsdh;
+-
+-	return bcmsdh->sbwad;
+-}
+-
+-void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev)
+-{
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+deleted file mode 100644
+index 465f623..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
++++ /dev/null
+@@ -1,386 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/**
+- * @file bcmsdh_linux.c
+- */
+-
+-#define __UNDEF_NO_VERSION__
+-
+-#include <linux/netdevice.h>
+-#include <linux/pci.h>
+-#include <linux/completion.h>
+-
+-#include <pcicfg.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-
+-#if defined(OOB_INTR_ONLY)
+-#include <linux/irq.h>
+-extern void dhdsdio_isr(void *args);
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#endif				/* defined(OOB_INTR_ONLY) */
+-#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
+-#if !defined(BCMPLATFORM_BUS)
+-#define BCMPLATFORM_BUS
+-#endif				/* !defined(BCMPLATFORM_BUS) */
+-
+-#include <linux/platform_device.h>
+-#endif				/* CONFIG_MACH_SANDGATE2G */
+-
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-/**
+- * SDIO Host Controller info
+- */
+-typedef struct bcmsdh_hc bcmsdh_hc_t;
+-
+-struct bcmsdh_hc {
+-	bcmsdh_hc_t *next;
+-#ifdef BCMPLATFORM_BUS
+-	struct device *dev;	/* platform device handle */
+-#else
+-	struct pci_dev *dev;	/* pci device handle */
+-#endif				/* BCMPLATFORM_BUS */
+-	void *regs;		/* SDIO Host Controller address */
+-	bcmsdh_info_t *sdh;	/* SDIO Host Controller handle */
+-	void *ch;
+-	unsigned int oob_irq;
+-	unsigned long oob_flags;	/* OOB Host specifiction
+-					as edge and etc */
+-	bool oob_irq_registered;
+-#if defined(OOB_INTR_ONLY)
+-	spinlock_t irq_lock;
+-#endif
+-};
+-static bcmsdh_hc_t *sdhcinfo;
+-
+-/* driver info, initialized when bcmsdh_register is called */
+-static bcmsdh_driver_t drvinfo = { NULL, NULL };
+-
+-/* debugging macros */
+-#define SDLX_MSG(x)
+-
+-/**
+- * Checks to see if vendor and device IDs match a supported SDIO Host Controller.
+- */
+-bool bcmsdh_chipmatch(u16 vendor, u16 device)
+-{
+-	/* Add other vendors and devices as required */
+-
+-#ifdef BCMSDIOH_STD
+-	/* Check for Arasan host controller */
+-	if (vendor == VENDOR_SI_IMAGE)
+-		return true;
+-
+-	/* Check for BRCM 27XX Standard host controller */
+-	if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM)
+-		return true;
+-
+-	/* Check for BRCM Standard host controller */
+-	if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM)
+-		return true;
+-
+-	/* Check for TI PCIxx21 Standard host controller */
+-	if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI)
+-		return true;
+-
+-	if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI)
+-		return true;
+-
+-	/* Ricoh R5C822 Standard SDIO Host */
+-	if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH)
+-		return true;
+-
+-	/* JMicron Standard SDIO Host */
+-	if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON)
+-		return true;
+-#endif				/* BCMSDIOH_STD */
+-#ifdef BCMSDIOH_SPI
+-	/* This is the PciSpiHost. */
+-	if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) {
+-		return true;
+-	}
+-#endif				/* BCMSDIOH_SPI */
+-
+-	return false;
+-}
+-
+-#if defined(BCMPLATFORM_BUS)
+-#if defined(BCMLXSDMMC)
+-/* forward declarations */
+-int bcmsdh_probe(struct device *dev);
+-EXPORT_SYMBOL(bcmsdh_probe);
+-
+-int bcmsdh_remove(struct device *dev);
+-EXPORT_SYMBOL(bcmsdh_remove);
+-
+-#else
+-/* forward declarations */
+-static int __devinit bcmsdh_probe(struct device *dev);
+-static int __devexit bcmsdh_remove(struct device *dev);
+-#endif				/* BCMLXSDMMC */
+-
+-#ifndef BCMLXSDMMC
+-static
+-#endif				/* BCMLXSDMMC */
+-int bcmsdh_probe(struct device *dev)
+-{
+-	bcmsdh_hc_t *sdhc = NULL;
+-	unsigned long regs = 0;
+-	bcmsdh_info_t *sdh = NULL;
+-#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+-	struct platform_device *pdev;
+-	struct resource *r;
+-#endif				/* BCMLXSDMMC */
+-	int irq = 0;
+-	u32 vendevid;
+-	unsigned long irq_flags = 0;
+-
+-#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS)
+-	pdev = to_platform_device(dev);
+-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	irq = platform_get_irq(pdev, 0);
+-	if (!r || irq == NO_IRQ)
+-		return -ENXIO;
+-#endif				/* BCMLXSDMMC */
+-
+-#if defined(OOB_INTR_ONLY)
+-#ifdef HW_OOB
+-	irq_flags =
+-	    IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
+-	    IORESOURCE_IRQ_SHAREABLE;
+-#else
+-	irq_flags = IRQF_TRIGGER_FALLING;
+-#endif				/* HW_OOB */
+-	irq = dhd_customer_oob_irq_map(&irq_flags);
+-	if (irq < 0) {
+-		SDLX_MSG(("%s: Host irq is not defined\n", __func__));
+-		return 1;
+-	}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-	/* allocate SDIO Host Controller state info */
+-	sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC);
+-	if (!sdhc) {
+-		SDLX_MSG(("%s: out of memory\n", __func__));
+-		goto err;
+-	}
+-	sdhc->dev = (void *)dev;
+-
+-#ifdef BCMLXSDMMC
+-	sdh = bcmsdh_attach((void *)0, (void **)&regs, irq);
+-	if (!sdh) {
+-		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
+-		goto err;
+-	}
+-#else
+-	sdh = bcmsdh_attach((void *)r->start, (void **)&regs, irq);
+-	if (!sdh) {
+-		SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__));
+-		goto err;
+-	}
+-#endif				/* BCMLXSDMMC */
+-	sdhc->sdh = sdh;
+-	sdhc->oob_irq = irq;
+-	sdhc->oob_flags = irq_flags;
+-	sdhc->oob_irq_registered = false;	/* to make sure.. */
+-#if defined(OOB_INTR_ONLY)
+-	spin_lock_init(&sdhc->irq_lock);
+-#endif
+-
+-	/* chain SDIO Host Controller info together */
+-	sdhc->next = sdhcinfo;
+-	sdhcinfo = sdhc;
+-	/* Read the vendor/device ID from the CIS */
+-	vendevid = bcmsdh_query_device(sdh);
+-
+-	/* try to attach to the target device */
+-	sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
+-				  0, 0, 0, 0, (void *)regs, sdh);
+-	if (!sdhc->ch) {
+-		SDLX_MSG(("%s: device attach failed\n", __func__));
+-		goto err;
+-	}
+-
+-	return 0;
+-
+-	/* error handling */
+-err:
+-	if (sdhc) {
+-		if (sdhc->sdh)
+-			bcmsdh_detach(sdhc->sdh);
+-		kfree(sdhc);
+-	}
+-
+-	return -ENODEV;
+-}
+-
+-#ifndef BCMLXSDMMC
+-static
+-#endif				/* BCMLXSDMMC */
+-int bcmsdh_remove(struct device *dev)
+-{
+-	bcmsdh_hc_t *sdhc, *prev;
+-
+-	sdhc = sdhcinfo;
+-	drvinfo.detach(sdhc->ch);
+-	bcmsdh_detach(sdhc->sdh);
+-	/* find the SDIO Host Controller state for this pdev
+-		 and take it out from the list */
+-	for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
+-		if (sdhc->dev == (void *)dev) {
+-			if (prev)
+-				prev->next = sdhc->next;
+-			else
+-				sdhcinfo = NULL;
+-			break;
+-		}
+-		prev = sdhc;
+-	}
+-	if (!sdhc) {
+-		SDLX_MSG(("%s: failed\n", __func__));
+-		return 0;
+-	}
+-
+-	/* release SDIO Host Controller info */
+-	kfree(sdhc);
+-
+-#if !defined(BCMLXSDMMC)
+-	dev_set_drvdata(dev, NULL);
+-#endif				/* !defined(BCMLXSDMMC) */
+-
+-	return 0;
+-}
+-#endif				/* BCMPLATFORM_BUS */
+-
+-extern int sdio_function_init(void);
+-
+-int bcmsdh_register(bcmsdh_driver_t *driver)
+-{
+-	drvinfo = *driver;
+-
+-	SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
+-	return sdio_function_init();
+-}
+-
+-extern void sdio_function_cleanup(void);
+-
+-void bcmsdh_unregister(void)
+-{
+-	sdio_function_cleanup();
+-}
+-
+-#if defined(OOB_INTR_ONLY)
+-void bcmsdh_oob_intr_set(bool enable)
+-{
+-	static bool curstate = 1;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&sdhcinfo->irq_lock, flags);
+-	if (curstate != enable) {
+-		if (enable)
+-			enable_irq(sdhcinfo->oob_irq);
+-		else
+-			disable_irq_nosync(sdhcinfo->oob_irq);
+-		curstate = enable;
+-	}
+-	spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags);
+-}
+-
+-static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
+-{
+-	dhd_pub_t *dhdp;
+-
+-	dhdp = (dhd_pub_t *) dev_get_drvdata(sdhcinfo->dev);
+-
+-	bcmsdh_oob_intr_set(0);
+-
+-	if (dhdp == NULL) {
+-		SDLX_MSG(("Out of band GPIO interrupt fired way too early\n"));
+-		return IRQ_HANDLED;
+-	}
+-
+-	dhdsdio_isr((void *)dhdp->bus);
+-
+-	return IRQ_HANDLED;
+-}
+-
+-int bcmsdh_register_oob_intr(void *dhdp)
+-{
+-	int error = 0;
+-
+-	SDLX_MSG(("%s Enter\n", __func__));
+-
+-	sdhcinfo->oob_flags =
+-	    IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
+-	    IORESOURCE_IRQ_SHAREABLE;
+-	dev_set_drvdata(sdhcinfo->dev, dhdp);
+-
+-	if (!sdhcinfo->oob_irq_registered) {
+-		SDLX_MSG(("%s IRQ=%d Type=%X\n", __func__,
+-			  (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags));
+-		/* Refer to customer Host IRQ docs about
+-			 proper irqflags definition */
+-		error =
+-		    request_irq(sdhcinfo->oob_irq, wlan_oob_irq,
+-				sdhcinfo->oob_flags, "bcmsdh_sdmmc", NULL);
+-		if (error)
+-			return -ENODEV;
+-
+-		irq_set_irq_wake(sdhcinfo->oob_irq, 1);
+-		sdhcinfo->oob_irq_registered = true;
+-	}
+-
+-	return 0;
+-}
+-
+-void bcmsdh_unregister_oob_intr(void)
+-{
+-	SDLX_MSG(("%s: Enter\n", __func__));
+-
+-	irq_set_irq_wake(sdhcinfo->oob_irq, 0);
+-	disable_irq(sdhcinfo->oob_irq);	/* just in case.. */
+-	free_irq(sdhcinfo->oob_irq, NULL);
+-	sdhcinfo->oob_irq_registered = false;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-/* Module parameters specific to each host-controller driver */
+-
+-extern uint sd_msglevel;	/* Debug message level */
+-module_param(sd_msglevel, uint, 0);
+-
+-extern uint sd_power;		/* 0 = SD Power OFF,
+-					 1 = SD Power ON. */
+-module_param(sd_power, uint, 0);
+-
+-extern uint sd_clock;		/* SD Clock Control, 0 = SD Clock OFF,
+-				 1 = SD Clock ON */
+-module_param(sd_clock, uint, 0);
+-
+-extern uint sd_divisor;		/* Divisor (-1 means external clock) */
+-module_param(sd_divisor, uint, 0);
+-
+-extern uint sd_sdmode;		/* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
+-module_param(sd_sdmode, uint, 0);
+-
+-extern uint sd_hiok;		/* Ok to use hi-speed mode */
+-module_param(sd_hiok, uint, 0);
+-
+-extern uint sd_f2_blocksize;
+-module_param(sd_f2_blocksize, int, 0);
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+deleted file mode 100644
+index c0ffbd3..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
++++ /dev/null
+@@ -1,1239 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <sdio.h>		/* SDIO Device and Protocol Specs */
+-#include <sdioh.h>		/* SDIO Host Controller Specification */
+-#include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
+-#include <sdiovar.h>		/* ioctl/iovars */
+-
+-#include <linux/mmc/core.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/mmc/sdio_ids.h>
+-#include <linux/suspend.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#include "bcmsdh_sdmmc.h"
+-
+-extern int sdio_function_init(void);
+-extern void sdio_function_cleanup(void);
+-
+-#if !defined(OOB_INTR_ONLY)
+-static void IRQHandler(struct sdio_func *func);
+-static void IRQHandlerF2(struct sdio_func *func);
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr);
+-extern int sdio_reset_comm(struct mmc_card *card);
+-
+-extern PBCMSDH_SDMMC_INSTANCE gInstance;
+-
+-uint sd_sdmode = SDIOH_MODE_SD4;	/* Use SD4 mode by default */
+-uint sd_f2_blocksize = 512;	/* Default blocksize */
+-
+-uint sd_divisor = 2;		/* Default 48MHz/2 = 24MHz */
+-
+-uint sd_power = 1;		/* Default to SD Slot powered ON */
+-uint sd_clock = 1;		/* Default to SD Clock turned ON */
+-uint sd_hiok = false;		/* Don't use hi-speed mode by default */
+-uint sd_msglevel = 0x01;
+-uint sd_use_dma = true;
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
+-DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait);
+-
+-#define DMA_ALIGN_MASK	0x03
+-
+-int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
+-			     int regsize, u32 *data);
+-
+-void sdioh_sdio_set_host_pm_flags(int flag)
+-{
+-	if (sdio_set_host_pm_flags(gInstance->func[1], flag))
+-		printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\
+-			 __func__, (unsigned int)flag);
+-}
+-
+-static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
+-{
+-	int err_ret;
+-	u32 fbraddr;
+-	u8 func;
+-
+-	sd_trace(("%s\n", __func__));
+-
+-	/* Get the Card's common CIS address */
+-	sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0);
+-	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+-	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
+-		 sd->com_cis_ptr));
+-
+-	/* Get the Card's function CIS (for each function) */
+-	for (fbraddr = SDIOD_FBR_STARTADDR, func = 1;
+-	     func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
+-		sd->func_cis_ptr[func] =
+-		    sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr);
+-		sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func,
+-			 sd->func_cis_ptr[func]));
+-	}
+-
+-	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+-	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__,
+-		 sd->com_cis_ptr));
+-
+-	/* Enable Function 1 */
+-	sdio_claim_host(gInstance->func[1]);
+-	err_ret = sdio_enable_func(gInstance->func[1]);
+-	sdio_release_host(gInstance->func[1]);
+-	if (err_ret) {
+-		sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x",
+-			err_ret));
+-	}
+-
+-	return false;
+-}
+-
+-/*
+- *	Public entry points & extern's
+- */
+-sdioh_info_t *sdioh_attach(void *bar0, uint irq)
+-{
+-	sdioh_info_t *sd;
+-	int err_ret;
+-
+-	sd_trace(("%s\n", __func__));
+-
+-	if (gInstance == NULL) {
+-		sd_err(("%s: SDIO Device not present\n", __func__));
+-		return NULL;
+-	}
+-
+-	sd = kzalloc(sizeof(sdioh_info_t), GFP_ATOMIC);
+-	if (sd == NULL) {
+-		sd_err(("sdioh_attach: out of memory\n"));
+-		return NULL;
+-	}
+-	if (sdioh_sdmmc_osinit(sd) != 0) {
+-		sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__));
+-		kfree(sd);
+-		return NULL;
+-	}
+-
+-	sd->num_funcs = 2;
+-	sd->sd_blockmode = true;
+-	sd->use_client_ints = true;
+-	sd->client_block_size[0] = 64;
+-
+-	gInstance->sd = sd;
+-
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[1]);
+-
+-	sd->client_block_size[1] = 64;
+-	err_ret = sdio_set_block_size(gInstance->func[1], 64);
+-	if (err_ret)
+-		sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n"));
+-
+-	/* Release host controller F1 */
+-	sdio_release_host(gInstance->func[1]);
+-
+-	if (gInstance->func[2]) {
+-		/* Claim host controller F2 */
+-		sdio_claim_host(gInstance->func[2]);
+-
+-		sd->client_block_size[2] = sd_f2_blocksize;
+-		err_ret =
+-		    sdio_set_block_size(gInstance->func[2], sd_f2_blocksize);
+-		if (err_ret)
+-			sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize "
+-				"to %d\n", sd_f2_blocksize));
+-
+-		/* Release host controller F2 */
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	sdioh_sdmmc_card_enablefuncs(sd);
+-
+-	sd_trace(("%s: Done\n", __func__));
+-	return sd;
+-}
+-
+-extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s\n", __func__));
+-
+-	if (sd) {
+-
+-		/* Disable Function 2 */
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_disable_func(gInstance->func[2]);
+-		sdio_release_host(gInstance->func[2]);
+-
+-		/* Disable Function 1 */
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_disable_func(gInstance->func[1]);
+-		sdio_release_host(gInstance->func[1]);
+-
+-		/* deregister irq */
+-		sdioh_sdmmc_osfree(sd);
+-
+-		kfree(sd);
+-	}
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-
+-extern SDIOH_API_RC sdioh_enable_func_intr(void)
+-{
+-	u8 reg;
+-	int err;
+-
+-	if (gInstance->func[0]) {
+-		sdio_claim_host(gInstance->func[0]);
+-
+-		reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+-		if (err) {
+-			sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			sdio_release_host(gInstance->func[0]);
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* Enable F1 and F2 interrupts, set master enable */
+-		reg |=
+-		    (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN |
+-		     INTR_CTL_MASTER_EN);
+-
+-		sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+-		sdio_release_host(gInstance->func[0]);
+-
+-		if (err) {
+-			sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-	}
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_disable_func_intr(void)
+-{
+-	u8 reg;
+-	int err;
+-
+-	if (gInstance->func[0]) {
+-		sdio_claim_host(gInstance->func[0]);
+-		reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err);
+-		if (err) {
+-			sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			sdio_release_host(gInstance->func[0]);
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+-		/* Disable master interrupt with the last function interrupt */
+-		if (!(reg & 0xFE))
+-			reg = 0;
+-		sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
+-
+-		sdio_release_host(gInstance->func[0]);
+-		if (err) {
+-			sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n",
+-				__func__, err));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-	}
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+-
+-/* Configure callback to client when we receive client interrupt */
+-extern SDIOH_API_RC
+-sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-	if (fn == NULL) {
+-		sd_err(("%s: interrupt handler is NULL, not registering\n",
+-			__func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-#if !defined(OOB_INTR_ONLY)
+-	sd->intr_handler = fn;
+-	sd->intr_handler_arg = argh;
+-	sd->intr_handler_valid = true;
+-
+-	/* register and unmask irq */
+-	if (gInstance->func[2]) {
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_claim_irq(gInstance->func[2], IRQHandlerF2);
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	if (gInstance->func[1]) {
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_claim_irq(gInstance->func[1], IRQHandler);
+-		sdio_release_host(gInstance->func[1]);
+-	}
+-#elif defined(HW_OOB)
+-	sdioh_enable_func_intr();
+-#endif				/* defined(OOB_INTR_ONLY) */
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-
+-#if !defined(OOB_INTR_ONLY)
+-	if (gInstance->func[1]) {
+-		/* register and unmask irq */
+-		sdio_claim_host(gInstance->func[1]);
+-		sdio_release_irq(gInstance->func[1]);
+-		sdio_release_host(gInstance->func[1]);
+-	}
+-
+-	if (gInstance->func[2]) {
+-		/* Claim host controller F2 */
+-		sdio_claim_host(gInstance->func[2]);
+-		sdio_release_irq(gInstance->func[2]);
+-		/* Release host controller F2 */
+-		sdio_release_host(gInstance->func[2]);
+-	}
+-
+-	sd->intr_handler_valid = false;
+-	sd->intr_handler = NULL;
+-	sd->intr_handler_arg = NULL;
+-#elif defined(HW_OOB)
+-	sdioh_disable_func_intr();
+-#endif				/*  !defined(OOB_INTR_ONLY) */
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
+-{
+-	sd_trace(("%s: Entering\n", __func__));
+-	*onoff = sd->client_intr_enabled;
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-#if defined(DHD_DEBUG)
+-extern bool sdioh_interrupt_pending(sdioh_info_t *sd)
+-{
+-	return 0;
+-}
+-#endif
+-
+-uint sdioh_query_iofnum(sdioh_info_t *sd)
+-{
+-	return sd->num_funcs;
+-}
+-
+-/* IOVar table */
+-enum {
+-	IOV_MSGLEVEL = 1,
+-	IOV_BLOCKMODE,
+-	IOV_BLOCKSIZE,
+-	IOV_DMA,
+-	IOV_USEINTS,
+-	IOV_NUMINTS,
+-	IOV_NUMLOCALINTS,
+-	IOV_HOSTREG,
+-	IOV_DEVREG,
+-	IOV_DIVISOR,
+-	IOV_SDMODE,
+-	IOV_HISPEED,
+-	IOV_HCIREGS,
+-	IOV_POWER,
+-	IOV_CLOCK,
+-	IOV_RXCHAIN
+-};
+-
+-const bcm_iovar_t sdioh_iovars[] = {
+-	{"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0},
+-	{"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0},
+-	{"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) |
+-								 size) */
+-	{"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0},
+-	{"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0},
+-	{"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0},
+-	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0},
+-	{"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_power", IOV_POWER, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100}
+-	,
+-	{"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0}
+-	,
+-	{"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0}
+-	,
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-int
+-sdioh_iovar_op(sdioh_info_t *si, const char *name,
+-	       void *params, int plen, void *arg, int len, bool set)
+-{
+-	const bcm_iovar_t *vi = NULL;
+-	int bcmerror = 0;
+-	int val_size;
+-	s32 int_val = 0;
+-	bool bool_val;
+-	u32 actionid;
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get must have return space; Set does not take qualifiers */
+-	ASSERT(set || (arg && len));
+-	ASSERT(!set || (!params && !plen));
+-
+-	sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"),
+-		  name));
+-
+-	vi = bcm_iovar_lookup(sdioh_iovars, name);
+-	if (vi == NULL) {
+-		bcmerror = -ENOTSUPP;
+-		goto exit;
+-	}
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, set);
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	/* Set up params so get and set can share the convenience variables */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		val_size = sizeof(int);
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	bool_val = (int_val != 0) ? true : false;
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_MSGLEVEL):
+-		int_val = (s32) sd_msglevel;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_MSGLEVEL):
+-		sd_msglevel = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_BLOCKMODE):
+-		int_val = (s32) si->sd_blockmode;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_BLOCKMODE):
+-		si->sd_blockmode = (bool) int_val;
+-		/* Haven't figured out how to make non-block mode with DMA */
+-		break;
+-
+-	case IOV_GVAL(IOV_BLOCKSIZE):
+-		if ((u32) int_val > si->num_funcs) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		int_val = (s32) si->client_block_size[int_val];
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_BLOCKSIZE):
+-		{
+-			uint func = ((u32) int_val >> 16);
+-			uint blksize = (u16) int_val;
+-			uint maxsize;
+-
+-			if (func > si->num_funcs) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			switch (func) {
+-			case 0:
+-				maxsize = 32;
+-				break;
+-			case 1:
+-				maxsize = BLOCK_SIZE_4318;
+-				break;
+-			case 2:
+-				maxsize = BLOCK_SIZE_4328;
+-				break;
+-			default:
+-				maxsize = 0;
+-			}
+-			if (blksize > maxsize) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-			if (!blksize)
+-				blksize = maxsize;
+-
+-			/* Now set it */
+-			si->client_block_size[func] = blksize;
+-
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_RXCHAIN):
+-		int_val = false;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_DMA):
+-		int_val = (s32) si->sd_use_dma;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DMA):
+-		si->sd_use_dma = (bool) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_USEINTS):
+-		int_val = (s32) si->use_client_ints;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_USEINTS):
+-		si->use_client_ints = (bool) int_val;
+-		if (si->use_client_ints)
+-			si->intmask |= CLIENT_INTR;
+-		else
+-			si->intmask &= ~CLIENT_INTR;
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_DIVISOR):
+-		int_val = (u32) sd_divisor;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DIVISOR):
+-		sd_divisor = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_POWER):
+-		int_val = (u32) sd_power;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_POWER):
+-		sd_power = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_CLOCK):
+-		int_val = (u32) sd_clock;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_CLOCK):
+-		sd_clock = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDMODE):
+-		int_val = (u32) sd_sdmode;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDMODE):
+-		sd_sdmode = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_HISPEED):
+-		int_val = (u32) sd_hiok;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_HISPEED):
+-		sd_hiok = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_NUMINTS):
+-		int_val = (s32) si->intrcount;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_NUMLOCALINTS):
+-		int_val = (s32) 0;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_HOSTREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-
+-			if (sd_ptr->offset < SD_SysAddr
+-			    || sd_ptr->offset > SD_MaxCurCap) {
+-				sd_err(("%s: bad offset 0x%x\n", __func__,
+-					sd_ptr->offset));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			sd_trace(("%s: rreg%d at offset %d\n", __func__,
+-				  (sd_ptr->offset & 1) ? 8
+-				  : ((sd_ptr->offset & 2) ? 16 : 32),
+-				  sd_ptr->offset));
+-			if (sd_ptr->offset & 1)
+-				int_val = 8;	/* sdioh_sdmmc_rreg8(si,
+-						 sd_ptr->offset); */
+-			else if (sd_ptr->offset & 2)
+-				int_val = 16;	/* sdioh_sdmmc_rreg16(si,
+-						 sd_ptr->offset); */
+-			else
+-				int_val = 32;	/* sdioh_sdmmc_rreg(si,
+-						 sd_ptr->offset); */
+-
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_HOSTREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-
+-			if (sd_ptr->offset < SD_SysAddr
+-			    || sd_ptr->offset > SD_MaxCurCap) {
+-				sd_err(("%s: bad offset 0x%x\n", __func__,
+-					sd_ptr->offset));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			sd_trace(("%s: wreg%d value 0x%08x at offset %d\n",
+-				  __func__, sd_ptr->value,
+-				  (sd_ptr->offset & 1) ? 8
+-				  : ((sd_ptr->offset & 2) ? 16 : 32),
+-				  sd_ptr->offset));
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_DEVREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-			u8 data = 0;
+-
+-			if (sdioh_cfg_read
+-			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
+-				bcmerror = -EIO;
+-				break;
+-			}
+-
+-			int_val = (int)data;
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_DEVREG):
+-		{
+-			sdreg_t *sd_ptr = (sdreg_t *) params;
+-			u8 data = (u8) sd_ptr->value;
+-
+-			if (sdioh_cfg_write
+-			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
+-				bcmerror = -EIO;
+-				break;
+-			}
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-exit:
+-
+-	return bcmerror;
+-}
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-
+-SDIOH_API_RC sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
+-{
+-	SDIOH_API_RC status;
+-	u8 data;
+-
+-	if (enable)
+-		data = 3;	/* enable hw oob interrupt */
+-	else
+-		data = 4;	/* disable hw oob interrupt */
+-	data |= 4;		/* Active HIGH */
+-
+-	status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data);
+-	return status;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+-
+-extern SDIOH_API_RC
+-sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data)
+-{
+-	SDIOH_API_RC status;
+-	/* No lock needed since sdioh_request_byte does locking */
+-	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
+-	return status;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data)
+-{
+-	/* No lock needed since sdioh_request_byte does locking */
+-	SDIOH_API_RC status;
+-	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
+-	return status;
+-}
+-
+-static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr)
+-{
+-	/* read 24 bits and return valid 17 bit addr */
+-	int i;
+-	u32 scratch, regdata;
+-	u8 *ptr = (u8 *)&scratch;
+-	for (i = 0; i < 3; i++) {
+-		if ((sdioh_sdmmc_card_regread(sd, 0, regaddr, 1, &regdata)) !=
+-		    SUCCESS)
+-			sd_err(("%s: Can't read!\n", __func__));
+-
+-		*ptr++ = (u8) regdata;
+-		regaddr++;
+-	}
+-
+-	/* Only the lower 17-bits are valid */
+-	scratch = le32_to_cpu(scratch);
+-	scratch &= 0x0001FFFF;
+-	return scratch;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length)
+-{
+-	u32 count;
+-	int offset;
+-	u32 foo;
+-	u8 *cis = cisd;
+-
+-	sd_trace(("%s: Func = %d\n", __func__, func));
+-
+-	if (!sd->func_cis_ptr[func]) {
+-		memset(cis, 0, length);
+-		sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-
+-	sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func,
+-		sd->func_cis_ptr[func]));
+-
+-	for (count = 0; count < length; count++) {
+-		offset = sd->func_cis_ptr[func] + count;
+-		if (sdioh_sdmmc_card_regread(sd, 0, offset, 1, &foo) < 0) {
+-			sd_err(("%s: regread failed: Can't read CIS\n",
+-				__func__));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		*cis = (u8) (foo & 0xff);
+-		cis++;
+-	}
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr,
+-		   u8 *byte)
+-{
+-	int err_ret;
+-
+-	sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func,
+-		 regaddr));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_byte_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	if (rw) {		/* CMD52 Write */
+-		if (func == 0) {
+-			/* Can only directly write to some F0 registers.
+-			 * Handle F2 enable
+-			 * as a special case.
+-			 */
+-			if (regaddr == SDIOD_CCCR_IOEN) {
+-				if (gInstance->func[2]) {
+-					sdio_claim_host(gInstance->func[2]);
+-					if (*byte & SDIO_FUNC_ENABLE_2) {
+-						/* Enable Function 2 */
+-						err_ret =
+-						    sdio_enable_func
+-						    (gInstance->func[2]);
+-						if (err_ret)
+-							sd_err(("bcmsdh_sdmmc: enable F2 failed:%d",
+-								 err_ret));
+-					} else {
+-						/* Disable Function 2 */
+-						err_ret =
+-						    sdio_disable_func
+-						    (gInstance->func[2]);
+-						if (err_ret)
+-							sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d",
+-								 err_ret));
+-					}
+-					sdio_release_host(gInstance->func[2]);
+-				}
+-			}
+-#if defined(MMC_SDIO_ABORT)
+-			/* to allow abort command through F1 */
+-			else if (regaddr == SDIOD_CCCR_IOABORT) {
+-				sdio_claim_host(gInstance->func[func]);
+-				/*
+-				 * this sdio_f0_writeb() can be replaced
+-				 * with another api
+-				 * depending upon MMC driver change.
+-				 * As of this time, this is temporaray one
+-				 */
+-				sdio_writeb(gInstance->func[func], *byte,
+-					    regaddr, &err_ret);
+-				sdio_release_host(gInstance->func[func]);
+-			}
+-#endif				/* MMC_SDIO_ABORT */
+-			else if (regaddr < 0xF0) {
+-				sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write "
+-					"disallowed\n", regaddr));
+-			} else {
+-				/* Claim host controller, perform F0 write,
+-				 and release */
+-				sdio_claim_host(gInstance->func[func]);
+-				sdio_f0_writeb(gInstance->func[func], *byte,
+-					       regaddr, &err_ret);
+-				sdio_release_host(gInstance->func[func]);
+-			}
+-		} else {
+-			/* Claim host controller, perform Fn write,
+-			 and release */
+-			sdio_claim_host(gInstance->func[func]);
+-			sdio_writeb(gInstance->func[func], *byte, regaddr,
+-				    &err_ret);
+-			sdio_release_host(gInstance->func[func]);
+-		}
+-	} else {		/* CMD52 Read */
+-		/* Claim host controller, perform Fn read, and release */
+-		sdio_claim_host(gInstance->func[func]);
+-
+-		if (func == 0) {
+-			*byte =
+-			    sdio_f0_readb(gInstance->func[func], regaddr,
+-					  &err_ret);
+-		} else {
+-			*byte =
+-			    sdio_readb(gInstance->func[func], regaddr,
+-				       &err_ret);
+-		}
+-
+-		sdio_release_host(gInstance->func[func]);
+-	}
+-
+-	if (err_ret)
+-		sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, "
+-			"Err: %d\n", rw ? "Write" : "Read", func, regaddr,
+-			*byte, err_ret));
+-
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-extern SDIOH_API_RC
+-sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func,
+-		   uint addr, u32 *word, uint nbytes)
+-{
+-	int err_ret = SDIOH_API_RC_FAIL;
+-
+-	if (func == 0) {
+-		sd_err(("%s: Only CMD52 allowed to F0.\n", __func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-
+-	sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
+-		 __func__, cmd_type, rw, func, addr, nbytes));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_word_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[func]);
+-
+-	if (rw) {		/* CMD52 Write */
+-		if (nbytes == 4) {
+-			sdio_writel(gInstance->func[func], *word, addr,
+-				    &err_ret);
+-		} else if (nbytes == 2) {
+-			sdio_writew(gInstance->func[func], (*word & 0xFFFF),
+-				    addr, &err_ret);
+-		} else {
+-			sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
+-		}
+-	} else {		/* CMD52 Read */
+-		if (nbytes == 4) {
+-			*word =
+-			    sdio_readl(gInstance->func[func], addr, &err_ret);
+-		} else if (nbytes == 2) {
+-			*word =
+-			    sdio_readw(gInstance->func[func], addr,
+-				       &err_ret) & 0xFFFF;
+-		} else {
+-			sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes));
+-		}
+-	}
+-
+-	/* Release host controller */
+-	sdio_release_host(gInstance->func[func]);
+-
+-	if (err_ret) {
+-		sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x",
+-			rw ? "Write" : "Read", err_ret));
+-	}
+-
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-static SDIOH_API_RC
+-sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
+-		     uint addr, struct sk_buff *pkt)
+-{
+-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
+-	u32 SGCount = 0;
+-	int err_ret = 0;
+-
+-	struct sk_buff *pnext;
+-
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-	ASSERT(pkt);
+-	DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-
+-	/* Claim host controller */
+-	sdio_claim_host(gInstance->func[func]);
+-	for (pnext = pkt; pnext; pnext = pnext->next) {
+-		uint pkt_len = pnext->len;
+-		pkt_len += 3;
+-		pkt_len &= 0xFFFFFFFC;
+-
+-#ifdef CONFIG_MMC_MSM7X00A
+-		if ((pkt_len % 64) == 32) {
+-			sd_trace(("%s: Rounding up TX packet +=32\n",
+-				  __func__));
+-			pkt_len += 32;
+-		}
+-#endif				/* CONFIG_MMC_MSM7X00A */
+-		/* Make sure the packet is aligned properly.
+-		 * If it isn't, then this
+-		 * is the fault of sdioh_request_buffer() which
+-		 * is supposed to give
+-		 * us something we can work with.
+-		 */
+-		ASSERT(((u32) (pkt->data) & DMA_ALIGN_MASK) == 0);
+-
+-		if ((write) && (!fifo)) {
+-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
+-						   ((u8 *) (pnext->data)),
+-						   pkt_len);
+-		} else if (write) {
+-			err_ret = sdio_memcpy_toio(gInstance->func[func], addr,
+-						   ((u8 *) (pnext->data)),
+-						   pkt_len);
+-		} else if (fifo) {
+-			err_ret = sdio_readsb(gInstance->func[func],
+-					      ((u8 *) (pnext->data)),
+-					      addr, pkt_len);
+-		} else {
+-			err_ret = sdio_memcpy_fromio(gInstance->func[func],
+-						     ((u8 *) (pnext->data)),
+-						     addr, pkt_len);
+-		}
+-
+-		if (err_ret) {
+-			sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d,"
+-				 "ERR=0x%08x\n", __func__,
+-				 (write) ? "TX" : "RX",
+-				 pnext, SGCount, addr, pkt_len, err_ret));
+-		} else {
+-			sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
+-				  __func__,
+-				  (write) ? "TX" : "RX",
+-				  pnext, SGCount, addr, pkt_len));
+-		}
+-
+-		if (!fifo)
+-			addr += pkt_len;
+-		SGCount++;
+-
+-	}
+-
+-	/* Release host controller */
+-	sdio_release_host(gInstance->func[func]);
+-
+-	sd_trace(("%s: Exit\n", __func__));
+-	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+-}
+-
+-/*
+- * This function takes a buffer or packet, and fixes everything up
+- * so that in the end, a DMA-able packet is created.
+- *
+- * A buffer does not have an associated packet pointer,
+- * and may or may not be aligned.
+- * A packet may consist of a single packet, or a packet chain.
+- * If it is a packet chain, then all the packets in the chain
+- * must be properly aligned.
+- *
+- * If the packet data is not aligned, then there may only be
+- * one packet, and in this case,  it is copied to a new
+- * aligned packet.
+- *
+- */
+-extern SDIOH_API_RC
+-sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write,
+-		     uint func, uint addr, uint reg_width, uint buflen_u,
+-		     u8 *buffer, struct sk_buff *pkt)
+-{
+-	SDIOH_API_RC Status;
+-	struct sk_buff *mypkt = NULL;
+-
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-	DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
+-	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+-	/* Case 1: we don't have a packet. */
+-	if (pkt == NULL) {
+-		sd_data(("%s: Creating new %s Packet, len=%d\n",
+-			 __func__, write ? "TX" : "RX", buflen_u));
+-		mypkt = bcm_pkt_buf_get_skb(buflen_u);
+-		if (!mypkt) {
+-			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
+-				__func__, buflen_u));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* For a write, copy the buffer data into the packet. */
+-		if (write)
+-			memcpy(mypkt->data, buffer, buflen_u);
+-
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+-
+-		/* For a read, copy the packet data back to the buffer. */
+-		if (!write)
+-			memcpy(buffer, mypkt->data, buflen_u);
+-
+-		bcm_pkt_buf_free_skb(mypkt);
+-	} else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
+-		/* Case 2: We have a packet, but it is unaligned. */
+-
+-		/* In this case, we cannot have a chain. */
+-		ASSERT(pkt->next == NULL);
+-
+-		sd_data(("%s: Creating aligned %s Packet, len=%d\n",
+-			 __func__, write ? "TX" : "RX", pkt->len));
+-		mypkt = bcm_pkt_buf_get_skb(pkt->len);
+-		if (!mypkt) {
+-			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
+-				__func__, pkt->len));
+-			return SDIOH_API_RC_FAIL;
+-		}
+-
+-		/* For a write, copy the buffer data into the packet. */
+-		if (write)
+-			memcpy(mypkt->data, pkt->data, pkt->len);
+-
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt);
+-
+-		/* For a read, copy the packet data back to the buffer. */
+-		if (!write)
+-			memcpy(pkt->data, mypkt->data, mypkt->len);
+-
+-		bcm_pkt_buf_free_skb(mypkt);
+-	} else {		/* case 3: We have a packet and
+-				 it is aligned. */
+-		sd_data(("%s: Aligned %s Packet, direct DMA\n",
+-			 __func__, write ? "Tx" : "Rx"));
+-		Status =
+-		    sdioh_request_packet(sd, fix_inc, write, func, addr, pkt);
+-	}
+-
+-	return Status;
+-}
+-
+-/* this function performs "abort" for both of host & device */
+-extern int sdioh_abort(sdioh_info_t *sd, uint func)
+-{
+-#if defined(MMC_SDIO_ABORT)
+-	char t_func = (char)func;
+-#endif				/* defined(MMC_SDIO_ABORT) */
+-	sd_trace(("%s: Enter\n", __func__));
+-
+-#if defined(MMC_SDIO_ABORT)
+-	/* issue abort cmd52 command through F1 */
+-	sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT,
+-			   &t_func);
+-#endif				/* defined(MMC_SDIO_ABORT) */
+-
+-	sd_trace(("%s: Exit\n", __func__));
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/* Reset and re-initialize the device */
+-int sdioh_sdio_reset(sdioh_info_t *si)
+-{
+-	sd_trace(("%s: Enter\n", __func__));
+-	sd_trace(("%s: Exit\n", __func__));
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/* Disable device interrupt */
+-void sdioh_sdmmc_devintr_off(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
+-	sd->intmask &= ~CLIENT_INTR;
+-}
+-
+-/* Enable device interrupt */
+-void sdioh_sdmmc_devintr_on(sdioh_info_t *sd)
+-{
+-	sd_trace(("%s: %d\n", __func__, sd->use_client_ints));
+-	sd->intmask |= CLIENT_INTR;
+-}
+-
+-/* Read client card reg */
+-int
+-sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
+-			 int regsize, u32 *data)
+-{
+-
+-	if ((func == 0) || (regsize == 1)) {
+-		u8 temp = 0;
+-
+-		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+-		*data = temp;
+-		*data &= 0xff;
+-		sd_data(("%s: byte read data=0x%02x\n", __func__, *data));
+-	} else {
+-		sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data,
+-				   regsize);
+-		if (regsize == 2)
+-			*data &= 0xffff;
+-
+-		sd_data(("%s: word read data=0x%08x\n", __func__, *data));
+-	}
+-
+-	return SUCCESS;
+-}
+-
+-#if !defined(OOB_INTR_ONLY)
+-/* bcmsdh_sdmmc interrupt handler */
+-static void IRQHandler(struct sdio_func *func)
+-{
+-	sdioh_info_t *sd;
+-
+-	sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n"));
+-	sd = gInstance->sd;
+-
+-	ASSERT(sd != NULL);
+-	sdio_release_host(gInstance->func[0]);
+-
+-	if (sd->use_client_ints) {
+-		sd->intrcount++;
+-		ASSERT(sd->intr_handler);
+-		ASSERT(sd->intr_handler_arg);
+-		(sd->intr_handler) (sd->intr_handler_arg);
+-	} else {
+-		sd_err(("bcmsdh_sdmmc: ***IRQHandler\n"));
+-
+-		sd_err(("%s: Not ready for intr: enabled %d, handler %p\n",
+-			__func__, sd->client_intr_enabled, sd->intr_handler));
+-	}
+-
+-	sdio_claim_host(gInstance->func[0]);
+-}
+-
+-/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */
+-static void IRQHandlerF2(struct sdio_func *func)
+-{
+-	sdioh_info_t *sd;
+-
+-	sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n"));
+-
+-	sd = gInstance->sd;
+-
+-	ASSERT(sd != NULL);
+-}
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-
+-#ifdef NOTUSED
+-/* Write client card reg */
+-static int
+-sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, u32 regaddr,
+-			  int regsize, u32 data)
+-{
+-
+-	if ((func == 0) || (regsize == 1)) {
+-		u8 temp;
+-
+-		temp = data & 0xff;
+-		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+-		sd_data(("%s: byte write data=0x%02x\n", __func__, data));
+-	} else {
+-		if (regsize == 2)
+-			data &= 0xffff;
+-
+-		sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data,
+-				   regsize);
+-
+-		sd_data(("%s: word write data=0x%08x\n", __func__, data));
+-	}
+-
+-	return SUCCESS;
+-}
+-#endif				/* NOTUSED */
+-
+-int sdioh_start(sdioh_info_t *si, int stage)
+-{
+-	return 0;
+-}
+-
+-int sdioh_stop(sdioh_info_t *si)
+-{
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
+deleted file mode 100644
+index 3ef42b3..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h
++++ /dev/null
+@@ -1,134 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef __BCMSDH_SDMMC_H__
+-#define __BCMSDH_SDMMC_H__
+-
+-#ifdef BCMDBG
+-#define sd_err(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_trace(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_info(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_debug(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_data(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define sd_ctrl(x)	\
+-	do { \
+-		if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#else
+-#define sd_err(x)
+-#define sd_trace(x)
+-#define sd_info(x)
+-#define sd_debug(x)
+-#define sd_data(x)
+-#define sd_ctrl(x)
+-#endif
+-
+-/* Allocate/init/free per-OS private data */
+-extern int sdioh_sdmmc_osinit(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_osfree(sdioh_info_t *sd);
+-
+-#define BLOCK_SIZE_64 64
+-#define BLOCK_SIZE_512 512
+-#define BLOCK_SIZE_4318 64
+-#define BLOCK_SIZE_4328 512
+-
+-/* internal return code */
+-#define SUCCESS	0
+-#define ERROR	1
+-
+-/* private bus modes */
+-#define SDIOH_MODE_SD4		2
+-#define CLIENT_INTR 		0x100	/* Get rid of this! */
+-
+-struct sdioh_info {
+-	struct osl_info *osh;		/* osh handler */
+-	bool client_intr_enabled;	/* interrupt connnected flag */
+-	bool intr_handler_valid;	/* client driver interrupt handler valid */
+-	sdioh_cb_fn_t intr_handler;	/* registered interrupt handler */
+-	void *intr_handler_arg;	/* argument to call interrupt handler */
+-	u16 intmask;		/* Current active interrupts */
+-	void *sdos_info;	/* Pointer to per-OS private data */
+-
+-	uint irq;		/* Client irq */
+-	int intrcount;		/* Client interrupts */
+-	bool sd_use_dma;	/* DMA on CMD53 */
+-	bool sd_blockmode;	/* sd_blockmode == false => 64 Byte Cmd 53s. */
+-	/*  Must be on for sd_multiblock to be effective */
+-	bool use_client_ints;	/* If this is false, make sure to restore */
+-	int sd_mode;		/* SD1/SD4/SPI */
+-	int client_block_size[SDIOD_MAX_IOFUNCS];	/* Blocksize */
+-	u8 num_funcs;	/* Supported funcs on client */
+-	u32 com_cis_ptr;
+-	u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
+-	uint max_dma_len;
+-	uint max_dma_descriptors;	/* DMA Descriptors supported by this controller. */
+-	/*	SDDMA_DESCRIPTOR	SGList[32]; *//* Scatter/Gather DMA List */
+-};
+-
+-/************************************************************
+- * Internal interfaces: per-port references into bcmsdh_sdmmc.c
+- */
+-
+-/* Global message bits */
+-extern uint sd_msglevel;
+-
+-/* OS-independent interrupt handler */
+-extern bool check_client_intr(sdioh_info_t *sd);
+-
+-/* Core interrupt enable/disable of device interrupts */
+-extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+-
+-/**************************************************************
+- * Internal interfaces: bcmsdh_sdmmc.c references to per-port code
+- */
+-
+-/* Register mapping routines */
+-extern u32 *sdioh_sdmmc_reg_map(s32 addr, int size);
+-extern void sdioh_sdmmc_reg_unmap(s32 addr, int size);
+-
+-/* Interrupt (de)registration routines */
+-extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq);
+-extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd);
+-
+-typedef struct _BCMSDH_SDMMC_INSTANCE {
+-	sdioh_info_t *sd;
+-	struct sdio_func *func[SDIOD_MAX_IOFUNCS];
+-	u32 host_claimed;
+-} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE;
+-
+-#endif				/* __BCMSDH_SDMMC_H__ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
+deleted file mode 100644
+index 2792a4d..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
++++ /dev/null
+@@ -1,235 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/types.h>
+-#include <linux/sched.h>	/* request_irq() */
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <sdio.h>		/* SDIO Specs */
+-#include <bcmsdbus.h>		/* bcmsdh to/from specific controller APIs */
+-#include <sdiovar.h>		/* to get msglevel bit values */
+-
+-#include <linux/mmc/core.h>
+-#include <linux/mmc/card.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/mmc/sdio_ids.h>
+-
+-#include "dngl_stats.h"
+-#include "dhd.h"
+-
+-#if !defined(SDIO_VENDOR_ID_BROADCOM)
+-#define SDIO_VENDOR_ID_BROADCOM		0x02d0
+-#endif				/* !defined(SDIO_VENDOR_ID_BROADCOM) */
+-
+-#define SDIO_DEVICE_ID_BROADCOM_DEFAULT	0x0000
+-
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)
+-#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB	0x0492	/* BCM94325SDGWB */
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4325)
+-#define SDIO_DEVICE_ID_BROADCOM_4325	0x0493
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4329)
+-#define SDIO_DEVICE_ID_BROADCOM_4329	0x4329
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+-#if !defined(SDIO_DEVICE_ID_BROADCOM_4319)
+-#define SDIO_DEVICE_ID_BROADCOM_4319	0x4319
+-#endif		/* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */
+-
+-#include <bcmsdh_sdmmc.h>
+-
+-#include <dhd_dbg.h>
+-#include <wl_cfg80211.h>
+-
+-extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+-extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+-
+-int sdio_function_init(void);
+-void sdio_function_cleanup(void);
+-
+-/* module param defaults */
+-static int clockoverride;
+-
+-module_param(clockoverride, int, 0644);
+-MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
+-
+-PBCMSDH_SDMMC_INSTANCE gInstance;
+-
+-/* Maximum number of bcmsdh_sdmmc devices supported by driver */
+-#define BCMSDH_SDMMC_MAX_DEVICES 1
+-
+-extern int bcmsdh_probe(struct device *dev);
+-extern int bcmsdh_remove(struct device *dev);
+-struct device sdmmc_dev;
+-
+-static int bcmsdh_sdmmc_probe(struct sdio_func *func,
+-			      const struct sdio_device_id *id)
+-{
+-	int ret = 0;
+-	static struct sdio_func sdio_func_0;
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-	sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class));
+-	sd_trace(("sdio_vendor: 0x%04x\n", func->vendor));
+-	sd_trace(("sdio_device: 0x%04x\n", func->device));
+-	sd_trace(("Function#: 0x%04x\n", func->num));
+-
+-	if (func->num == 1) {
+-		sdio_func_0.num = 0;
+-		sdio_func_0.card = func->card;
+-		gInstance->func[0] = &sdio_func_0;
+-		if (func->device == 0x4) {	/* 4318 */
+-			gInstance->func[2] = NULL;
+-			sd_trace(("NIC found, calling bcmsdh_probe...\n"));
+-			ret = bcmsdh_probe(&sdmmc_dev);
+-		}
+-	}
+-
+-	gInstance->func[func->num] = func;
+-
+-	if (func->num == 2) {
+-		wl_cfg80211_sdio_func(func);
+-		sd_trace(("F2 found, calling bcmsdh_probe...\n"));
+-		ret = bcmsdh_probe(&sdmmc_dev);
+-	}
+-
+-	return ret;
+-}
+-
+-static void bcmsdh_sdmmc_remove(struct sdio_func *func)
+-{
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-	sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
+-	sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
+-	sd_info(("sdio_device: 0x%04x\n", func->device));
+-	sd_info(("Function#: 0x%04x\n", func->num));
+-
+-	if (func->num == 2) {
+-		sd_trace(("F2 found, calling bcmsdh_remove...\n"));
+-		bcmsdh_remove(&sdmmc_dev);
+-	}
+-}
+-
+-/* devices we support, null terminated */
+-static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)},
+-	{SDIO_DEVICE
+-	 (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
+-	{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)},
+-	{ /* end: all zeroes */ },
+-};
+-
+-MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+-
+-static struct sdio_driver bcmsdh_sdmmc_driver = {
+-	.probe = bcmsdh_sdmmc_probe,
+-	.remove = bcmsdh_sdmmc_remove,
+-	.name = "brcmfmac",
+-	.id_table = bcmsdh_sdmmc_ids,
+-};
+-
+-struct sdos_info {
+-	sdioh_info_t *sd;
+-	spinlock_t lock;
+-};
+-
+-int sdioh_sdmmc_osinit(sdioh_info_t *sd)
+-{
+-	struct sdos_info *sdos;
+-
+-	sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
+-	sd->sdos_info = (void *)sdos;
+-	if (sdos == NULL)
+-		return -ENOMEM;
+-
+-	sdos->sd = sd;
+-	spin_lock_init(&sdos->lock);
+-	return 0;
+-}
+-
+-void sdioh_sdmmc_osfree(sdioh_info_t *sd)
+-{
+-	struct sdos_info *sdos;
+-	ASSERT(sd && sd->sdos_info);
+-
+-	sdos = (struct sdos_info *)sd->sdos_info;
+-	kfree(sdos);
+-}
+-
+-/* Interrupt enable/disable */
+-SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
+-{
+-	unsigned long flags;
+-	struct sdos_info *sdos;
+-
+-	sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling"));
+-
+-	sdos = (struct sdos_info *)sd->sdos_info;
+-	ASSERT(sdos);
+-
+-#if !defined(OOB_INTR_ONLY)
+-	if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
+-		sd_err(("%s: no handler registered, will not enable\n",
+-			__func__));
+-		return SDIOH_API_RC_FAIL;
+-	}
+-#endif				/* !defined(OOB_INTR_ONLY) */
+-
+-	/* Ensure atomicity for enable/disable calls */
+-	spin_lock_irqsave(&sdos->lock, flags);
+-
+-	sd->client_intr_enabled = enable;
+-	if (enable)
+-		sdioh_sdmmc_devintr_on(sd);
+-	else
+-		sdioh_sdmmc_devintr_off(sd);
+-
+-	spin_unlock_irqrestore(&sdos->lock, flags);
+-
+-	return SDIOH_API_RC_SUCCESS;
+-}
+-
+-/*
+- * module init
+-*/
+-int sdio_function_init(void)
+-{
+-	int error = 0;
+-	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__));
+-
+-	gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL);
+-	if (!gInstance)
+-		return -ENOMEM;
+-
+-	memset(&sdmmc_dev, 0, sizeof(sdmmc_dev));
+-	error = sdio_register_driver(&bcmsdh_sdmmc_driver);
+-
+-	return error;
+-}
+-
+-/*
+- * module cleanup
+-*/
+-extern int bcmsdh_remove(struct device *dev);
+-void sdio_function_cleanup(void)
+-{
+-	sd_trace(("%s Enter\n", __func__));
+-
+-	sdio_unregister_driver(&bcmsdh_sdmmc_driver);
+-
+-	kfree(gInstance);
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h
+deleted file mode 100644
+index a726b49..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd.h
++++ /dev/null
+@@ -1,414 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/****************
+- * Common types *
+- */
+-
+-#ifndef _dhd_h_
+-#define _dhd_h_
+-
+-#include <linux/sched.h>
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/skbuff.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/random.h>
+-#include <linux/spinlock.h>
+-#include <linux/ethtool.h>
+-#include <linux/suspend.h>
+-#include <asm/uaccess.h>
+-#include <asm/unaligned.h>
+-/* The kernel threading is sdio-specific */
+-
+-#include <wlioctl.h>
+-
+-/* Forward decls */
+-struct dhd_bus;
+-struct dhd_prot;
+-struct dhd_info;
+-
+-/* The level of bus communication with the dongle */
+-enum dhd_bus_state {
+-	DHD_BUS_DOWN,		/* Not ready for frame transfers */
+-	DHD_BUS_LOAD,		/* Download access only (CPU reset) */
+-	DHD_BUS_DATA		/* Ready for frame transfers */
+-};
+-
+-/* Common structure for module and instance linkage */
+-typedef struct dhd_pub {
+-	/* Linkage ponters */
+-	struct dhd_bus *bus;	/* Bus module handle */
+-	struct dhd_prot *prot;	/* Protocol module handle */
+-	struct dhd_info *info;	/* Info module handle */
+-
+-	/* Internal dhd items */
+-	bool up;		/* Driver up/down (to OS) */
+-	bool txoff;		/* Transmit flow-controlled */
+-	bool dongle_reset;	/* true = DEVRESET put dongle into reset */
+-	enum dhd_bus_state busstate;
+-	uint hdrlen;		/* Total DHD header length (proto + bus) */
+-	uint maxctl;		/* Max size rxctl request from proto to bus */
+-	uint rxsz;		/* Rx buffer size bus module should use */
+-	u8 wme_dp;		/* wme discard priority */
+-
+-	/* Dongle media info */
+-	bool iswl;		/* Dongle-resident driver is wl */
+-	unsigned long drv_version;	/* Version of dongle-resident driver */
+-	u8 mac[ETH_ALEN];			/* MAC address obtained from dongle */
+-	dngl_stats_t dstats;		/* Stats for dongle-based data */
+-
+-	/* Additional stats for the bus level */
+-	unsigned long tx_packets;	/* Data packets sent to dongle */
+-	unsigned long tx_multicast;	/* Multicast data packets sent to dongle */
+-	unsigned long tx_errors;	/* Errors in sending data to dongle */
+-	unsigned long tx_ctlpkts;	/* Control packets sent to dongle */
+-	unsigned long tx_ctlerrs;	/* Errors sending control frames to dongle */
+-	unsigned long rx_packets;	/* Packets sent up the network interface */
+-	unsigned long rx_multicast;	/* Multicast packets sent up the network
+-					 interface */
+-	unsigned long rx_errors;	/* Errors processing rx data packets */
+-	unsigned long rx_ctlpkts;	/* Control frames processed from dongle */
+-	unsigned long rx_ctlerrs;	/* Errors in processing rx control frames */
+-	unsigned long rx_dropped;	/* Packets dropped locally (no memory) */
+-	unsigned long rx_flushed;	/* Packets flushed due to
+-				unscheduled sendup thread */
+-	unsigned long wd_dpc_sched;	/* Number of times dhd dpc scheduled by
+-					 watchdog timer */
+-
+-	unsigned long rx_readahead_cnt;	/* Number of packets where header read-ahead
+-					 was used. */
+-	unsigned long tx_realloc;	/* Number of tx packets we had to realloc for
+-					 headroom */
+-	unsigned long fc_packets;	/* Number of flow control pkts recvd */
+-
+-	/* Last error return */
+-	int bcmerror;
+-	uint tickcnt;
+-
+-	/* Last error from dongle */
+-	int dongle_error;
+-
+-	/* Suspend disable flag  flag */
+-	int suspend_disable_flag;	/* "1" to disable all extra powersaving
+-					 during suspend */
+-	int in_suspend;		/* flag set to 1 when early suspend called */
+-#ifdef PNO_SUPPORT
+-	int pno_enable;		/* pno status : "1" is pno enable */
+-#endif				/* PNO_SUPPORT */
+-	int dtim_skip;		/* dtim skip , default 0 means wake each dtim */
+-
+-	/* Pkt filter defination */
+-	char *pktfilter[100];
+-	int pktfilter_count;
+-
+-	u8 country_code[WLC_CNTRY_BUF_SZ];
+-	char eventmask[WL_EVENTING_MASK_LEN];
+-
+-} dhd_pub_t;
+-
+-#if defined(CONFIG_PM_SLEEP)
+-extern atomic_t dhd_mmc_suspend;
+-#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+-#define _DHD_PM_RESUME_WAIT(a, b) do { \
+-		int retry = 0; \
+-		while (atomic_read(&dhd_mmc_suspend) && retry++ != b) { \
+-			wait_event_timeout(a, false, HZ/100); \
+-		} \
+-	}	while (0)
+-#define DHD_PM_RESUME_WAIT(a)	_DHD_PM_RESUME_WAIT(a, 30)
+-#define DHD_PM_RESUME_WAIT_FOREVER(a)	_DHD_PM_RESUME_WAIT(a, ~0)
+-#define DHD_PM_RESUME_RETURN_ERROR(a)	\
+-	do { if (atomic_read(&dhd_mmc_suspend)) return a; } while (0)
+-#define DHD_PM_RESUME_RETURN	do { \
+-	if (atomic_read(&dhd_mmc_suspend)) \
+-		return; \
+-	} while (0)
+-
+-#define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+-#define SPINWAIT_SLEEP(a, exp, us) do { \
+-		uint countdown = (us) + 9999; \
+-		while ((exp) && (countdown >= 10000)) { \
+-			wait_event_timeout(a, false, HZ/100); \
+-			countdown -= 10000; \
+-		} \
+-	} while (0)
+-
+-#else
+-
+-#define DHD_PM_RESUME_WAIT_INIT(a)
+-#define DHD_PM_RESUME_WAIT(a)
+-#define DHD_PM_RESUME_WAIT_FOREVER(a)
+-#define DHD_PM_RESUME_RETURN_ERROR(a)
+-#define DHD_PM_RESUME_RETURN
+-
+-#define DHD_SPINWAIT_SLEEP_INIT(a)
+-#define SPINWAIT_SLEEP(a, exp, us)  do { \
+-		uint countdown = (us) + 9; \
+-		while ((exp) && (countdown >= 10)) { \
+-			udelay(10);  \
+-			countdown -= 10;  \
+-		} \
+-	} while (0)
+-
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-#define DHD_IF_VIF	0x01	/* Virtual IF (Hidden from user) */
+-
+-static inline void MUTEX_LOCK_INIT(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t *dhdp)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_WL_SCAN_SET_INIT(void)
+-{
+-}
+-
+-static inline void MUTEX_LOCK_WL_SCAN_SET(void)
+-{
+-}
+-
+-static inline void MUTEX_UNLOCK_WL_SCAN_SET(void)
+-{
+-}
+-
+-typedef struct dhd_if_event {
+-	u8 ifidx;
+-	u8 action;
+-	u8 flags;
+-	u8 bssidx;
+-} dhd_if_event_t;
+-
+-/*
+- * Exported from dhd OS modules (dhd_linux/dhd_ndis)
+- */
+-
+-/* Indication from bus module regarding presence/insertion of dongle.
+- * Return dhd_pub_t pointer, used as handle to OS module in later calls.
+- * Returned structure should have bus and prot pointers filled in.
+- * bus_hdrlen specifies required headroom for bus module header.
+- */
+-extern dhd_pub_t *dhd_attach(struct dhd_bus *bus,
+-				uint bus_hdrlen);
+-extern int dhd_net_attach(dhd_pub_t *dhdp, int idx);
+-
+-/* Indication from bus module regarding removal/absence of dongle */
+-extern void dhd_detach(dhd_pub_t *dhdp);
+-
+-/* Indication from bus module to change flow-control state */
+-extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on);
+-
+-extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q,
+-			 struct sk_buff *pkt, int prec);
+-
+-/* Receive frame for delivery to OS.  Callee disposes of rxp. */
+-extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx,
+-			 struct sk_buff *rxp, int numpkt);
+-
+-/* Return pointer to interface name */
+-extern char *dhd_ifname(dhd_pub_t *dhdp, int idx);
+-
+-/* Request scheduling of the bus dpc */
+-extern void dhd_sched_dpc(dhd_pub_t *dhdp);
+-
+-/* Notify tx completion */
+-extern void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success);
+-
+-/* Query ioctl */
+-extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			      uint len);
+-
+-/* OS independent layer functions */
+-extern int dhd_os_proto_block(dhd_pub_t *pub);
+-extern int dhd_os_proto_unblock(dhd_pub_t *pub);
+-extern int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition,
+-				  bool *pending);
+-extern int dhd_os_ioctl_resp_wake(dhd_pub_t *pub);
+-extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
+-extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
+-extern void *dhd_os_open_image(char *filename);
+-extern int dhd_os_get_image_block(char *buf, int len, void *image);
+-extern void dhd_os_close_image(void *image);
+-extern void dhd_os_wd_timer(void *bus, uint wdtick);
+-extern void dhd_os_sdlock(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_txq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_txq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t *pub);
+-extern void dhd_customer_gpio_wlan_ctrl(int onoff);
+-extern int dhd_custom_get_mac_address(unsigned char *buf);
+-extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t *pub);
+-extern void dhd_os_sdlock_eventq(dhd_pub_t *pub);
+-extern void dhd_os_sdunlock_eventq(dhd_pub_t *pub);
+-#ifdef DHD_DEBUG
+-extern int write_to_file(dhd_pub_t *dhd, u8 *buf, int size);
+-#endif				/* DHD_DEBUG */
+-#if defined(OOB_INTR_ONLY)
+-extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-extern void dhd_os_sdtxlock(dhd_pub_t *pub);
+-extern void dhd_os_sdtxunlock(dhd_pub_t *pub);
+-
+-int setScheduler(struct task_struct *p, int policy, struct sched_param *param);
+-
+-typedef struct {
+-	u32 limit;		/* Expiration time (usec) */
+-	u32 increment;	/* Current expiration increment (usec) */
+-	u32 elapsed;		/* Current elapsed time (usec) */
+-	u32 tick;		/* O/S tick time (usec) */
+-} dhd_timeout_t;
+-
+-extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
+-extern int dhd_timeout_expired(dhd_timeout_t *tmo);
+-
+-extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+-extern u8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx);
+-extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata,
+-			 wl_event_msg_t *, void **data_ptr);
+-
+-extern void dhd_common_init(void);
+-
+-extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle,
+-		      char *name, u8 *mac_addr, u32 flags, u8 bssidx);
+-extern void dhd_del_if(struct dhd_info *dhd, int ifidx);
+-
+-extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char *name);
+-extern void dhd_vif_del(struct dhd_info *dhd, int ifidx);
+-
+-extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx);
+-extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, unsigned char * cp,
+-			   int len);
+-
+-/* Send packet to dongle via data channel */
+-extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pkt);
+-
+-/* Send event to host */
+-extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event,
+-			     void *data);
+-extern int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag);
+-extern uint dhd_bus_status(dhd_pub_t *dhdp);
+-extern int dhd_bus_start(dhd_pub_t *dhdp);
+-
+-enum cust_gpio_modes {
+-	WLAN_RESET_ON,
+-	WLAN_RESET_OFF,
+-	WLAN_POWER_ON,
+-	WLAN_POWER_OFF
+-};
+-/*
+- * Insmod parameters for debug/test
+- */
+-
+-/* Watchdog timer interval */
+-extern uint dhd_watchdog_ms;
+-
+-#if defined(DHD_DEBUG)
+-/* Console output poll interval */
+-extern uint dhd_console_ms;
+-#endif				/* defined(DHD_DEBUG) */
+-
+-/* Use interrupts */
+-extern uint dhd_intr;
+-
+-/* Use polling */
+-extern uint dhd_poll;
+-
+-/* ARP offload agent mode */
+-extern uint dhd_arp_mode;
+-
+-/* ARP offload enable */
+-extern uint dhd_arp_enable;
+-
+-/* Pkt filte enable control */
+-extern uint dhd_pkt_filter_enable;
+-
+-/*  Pkt filter init setup */
+-extern uint dhd_pkt_filter_init;
+-
+-/* Pkt filter mode control */
+-extern uint dhd_master_mode;
+-
+-/* Roaming mode control */
+-extern uint dhd_roam;
+-
+-/* Roaming mode control */
+-extern uint dhd_radio_up;
+-
+-/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
+-extern int dhd_idletime;
+-#define DHD_IDLETIME_TICKS 1
+-
+-/* SDIO Drive Strength */
+-extern uint dhd_sdiod_drive_strength;
+-
+-/* Override to force tx queueing all the time */
+-extern uint dhd_force_tx_queueing;
+-
+-#ifdef SDTEST
+-/* Echo packet generator (SDIO), pkts/s */
+-extern uint dhd_pktgen;
+-
+-/* Echo packet len (0 => sawtooth, max 1800) */
+-extern uint dhd_pktgen_len;
+-#define MAX_PKTGEN_LEN 1800
+-#endif
+-
+-/* optionally set by a module_param_string() */
+-#define MOD_PARAM_PATHLEN	2048
+-extern char fw_path[MOD_PARAM_PATHLEN];
+-extern char nv_path[MOD_PARAM_PATHLEN];
+-
+-/* For supporting multiple interfaces */
+-#define DHD_MAX_IFS	16
+-#define DHD_DEL_IF	-0xe
+-#define DHD_BAD_IF	-0xf
+-
+-extern void dhd_wait_for_event(dhd_pub_t *dhd, bool * lockvar);
+-extern void dhd_wait_event_wakeup(dhd_pub_t *dhd);
+-
+-extern u32 g_assert_type;
+-
+-#ifdef BCMDBG
+-#define ASSERT(exp) \
+-	  do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
+-extern void osl_assert(char *exp, char *file, int line);
+-#else
+-#define ASSERT(exp)	do {} while (0)
+-#endif  /* defined(BCMDBG) */
+-
+-#endif				/* _dhd_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
+deleted file mode 100644
+index 065f1ae..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h
++++ /dev/null
+@@ -1,82 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_bus_h_
+-#define _dhd_bus_h_
+-
+-/*
+- * Exported from dhd bus module (dhd_usb, dhd_sdio)
+- */
+-
+-/* Indicate (dis)interest in finding dongles. */
+-extern int dhd_bus_register(void);
+-extern void dhd_bus_unregister(void);
+-
+-/* Download firmware image and nvram image */
+-extern bool dhd_bus_download_firmware(struct dhd_bus *bus,
+-				      char *fw_path, char *nv_path);
+-
+-/* Stop bus module: clear pending frames, disable data flow */
+-extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
+-
+-/* Initialize bus module: prepare for communication w/dongle */
+-extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
+-
+-/* Send a data frame to the dongle.  Callee disposes of txp. */
+-extern int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *txp);
+-
+-/* Send/receive a control message to/from the dongle.
+- * Expects caller to enforce a single outstanding transaction.
+- */
+-extern int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
+-extern int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen);
+-
+-/* Watchdog timer function */
+-extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+-
+-#ifdef DHD_DEBUG
+-/* Device console input function */
+-extern int dhd_bus_console_in(dhd_pub_t *dhd, unsigned char *msg, uint msglen);
+-#endif				/* DHD_DEBUG */
+-
+-/* Deferred processing for the bus, return true requests reschedule */
+-extern bool dhd_bus_dpc(struct dhd_bus *bus);
+-extern void dhd_bus_isr(bool *InterruptRecognized,
+-			bool *QueueMiniportHandleInterrupt, void *arg);
+-
+-/* Check for and handle local prot-specific iovar commands */
+-extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+-			    void *params, int plen, void *arg, int len,
+-			    bool set);
+-
+-/* Add bus dump output to a buffer */
+-extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+-
+-/* Clear any bus counters */
+-extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
+-
+-/* return the dongle chipid */
+-extern uint dhd_bus_chip(struct dhd_bus *bus);
+-
+-/* Set user-specified nvram parameters. */
+-extern void dhd_bus_set_nvram_params(struct dhd_bus *bus,
+-				     const char *nvram_params);
+-
+-extern void *dhd_bus_pub(struct dhd_bus *bus);
+-extern void *dhd_bus_txq(struct dhd_bus *bus);
+-extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
+-
+-#endif				/* _dhd_bus_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
+deleted file mode 100644
+index ba5a5cb..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
++++ /dev/null
+@@ -1,474 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-
+-#include <bcmutils.h>
+-#include <bcmcdc.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_proto.h>
+-#include <dhd_bus.h>
+-#include <dhd_dbg.h>
+-#ifdef CUSTOMER_HW2
+-int wifi_get_mac_addr(unsigned char *buf);
+-#endif
+-
+-extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#define RETRIES 2	/* # of retries to retrieve matching ioctl response */
+-#define BUS_HEADER_LEN	(16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE
+-					 * defined in dhd_sdio.c
+-					 * (amount of header tha might be added)
+-					 * plus any space that might be needed
+-					 * for alignment padding.
+-					 */
+-#define ROUND_UP_MARGIN	2048	/* Biggest SDIO block size possible for
+-				 * round off at the end of buffer
+-				 */
+-
+-typedef struct dhd_prot {
+-	u16 reqid;
+-	u8 pending;
+-	u32 lastcmd;
+-	u8 bus_header[BUS_HEADER_LEN];
+-	cdc_ioctl_t msg;
+-	unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
+-} dhd_prot_t;
+-
+-static int dhdcdc_msg(dhd_pub_t *dhd)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	int len = le32_to_cpu(prot->msg.len) + sizeof(cdc_ioctl_t);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
+-	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
+-	 *        is actually sent to the dongle
+-	 */
+-	if (len > CDC_MAX_MSG_SIZE)
+-		len = CDC_MAX_MSG_SIZE;
+-
+-	/* Send request */
+-	return dhd_bus_txctl(dhd->bus, (unsigned char *)&prot->msg, len);
+-}
+-
+-static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len)
+-{
+-	int ret;
+-	dhd_prot_t *prot = dhd->prot;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	do {
+-		ret =
+-		    dhd_bus_rxctl(dhd->bus, (unsigned char *)&prot->msg,
+-				  len + sizeof(cdc_ioctl_t));
+-		if (ret < 0)
+-			break;
+-	} while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id);
+-
+-	return ret;
+-}
+-
+-int
+-dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	cdc_ioctl_t *msg = &prot->msg;
+-	void *info;
+-	int ret = 0, retries = 0;
+-	u32 id, flags = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
+-
+-	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
+-	if (cmd == WLC_GET_VAR && buf) {
+-		if (!strcmp((char *)buf, "bcmerrorstr")) {
+-			strncpy((char *)buf, "bcm_error",
+-				BCME_STRLEN);
+-			goto done;
+-		} else if (!strcmp((char *)buf, "bcmerror")) {
+-			*(int *)buf = dhd->dongle_error;
+-			goto done;
+-		}
+-	}
+-
+-	memset(msg, 0, sizeof(cdc_ioctl_t));
+-
+-	msg->cmd = cpu_to_le32(cmd);
+-	msg->len = cpu_to_le32(len);
+-	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+-	CDC_SET_IF_IDX(msg, ifidx);
+-	msg->flags = cpu_to_le32(msg->flags);
+-
+-	if (buf)
+-		memcpy(prot->buf, buf, len);
+-
+-	ret = dhdcdc_msg(dhd);
+-	if (ret < 0) {
+-		DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status "
+-			"%d\n", ret));
+-		goto done;
+-	}
+-
+-retry:
+-	/* wait for interrupt and get first fragment */
+-	ret = dhdcdc_cmplt(dhd, prot->reqid, len);
+-	if (ret < 0)
+-		goto done;
+-
+-	flags = le32_to_cpu(msg->flags);
+-	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+-
+-	if ((id < prot->reqid) && (++retries < RETRIES))
+-		goto retry;
+-	if (id != prot->reqid) {
+-		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+-			   dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
+-		ret = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Check info buffer */
+-	info = (void *)&msg[1];
+-
+-	/* Copy info buffer */
+-	if (buf) {
+-		if (ret < (int)len)
+-			len = ret;
+-		memcpy(buf, info, len);
+-	}
+-
+-	/* Check the ERROR flag */
+-	if (flags & CDCF_IOC_ERROR) {
+-		ret = le32_to_cpu(msg->status);
+-		/* Cache error from dongle */
+-		dhd->dongle_error = ret;
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	cdc_ioctl_t *msg = &prot->msg;
+-	int ret = 0;
+-	u32 flags, id;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len));
+-
+-	memset(msg, 0, sizeof(cdc_ioctl_t));
+-
+-	msg->cmd = cpu_to_le32(cmd);
+-	msg->len = cpu_to_le32(len);
+-	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET;
+-	CDC_SET_IF_IDX(msg, ifidx);
+-	msg->flags = cpu_to_le32(msg->flags);
+-
+-	if (buf)
+-		memcpy(prot->buf, buf, len);
+-
+-	ret = dhdcdc_msg(dhd);
+-	if (ret < 0)
+-		goto done;
+-
+-	ret = dhdcdc_cmplt(dhd, prot->reqid, len);
+-	if (ret < 0)
+-		goto done;
+-
+-	flags = le32_to_cpu(msg->flags);
+-	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+-
+-	if (id != prot->reqid) {
+-		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+-			   dhd_ifname(dhd, ifidx), __func__, id, prot->reqid));
+-		ret = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Check the ERROR flag */
+-	if (flags & CDCF_IOC_ERROR) {
+-		ret = le32_to_cpu(msg->status);
+-		/* Cache error from dongle */
+-		dhd->dongle_error = ret;
+-	}
+-
+-done:
+-	return ret;
+-}
+-
+-extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void *arg2);
+-int
+-dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
+-{
+-	dhd_prot_t *prot = dhd->prot;
+-	int ret = -1;
+-
+-	if (dhd->busstate == DHD_BUS_DOWN) {
+-		DHD_ERROR(("%s : bus is down. we have nothing to do\n",
+-			   __func__));
+-		return ret;
+-	}
+-	dhd_os_proto_block(dhd);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(len <= WLC_IOCTL_MAXLEN);
+-
+-	if (len > WLC_IOCTL_MAXLEN)
+-		goto done;
+-
+-	if (prot->pending == true) {
+-		DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) "
+-			"lastcmd=0x%x (%lu)\n",
+-			ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
+-			(unsigned long)prot->lastcmd));
+-		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR))
+-			DHD_TRACE(("iovar cmd=%s\n", (char *)buf));
+-
+-		goto done;
+-	}
+-
+-	prot->pending = true;
+-	prot->lastcmd = ioc->cmd;
+-	if (ioc->set)
+-		ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len);
+-	else {
+-		ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len);
+-		if (ret > 0)
+-			ioc->used = ret - sizeof(cdc_ioctl_t);
+-	}
+-
+-	/* Too many programs assume ioctl() returns 0 on success */
+-	if (ret >= 0)
+-		ret = 0;
+-	else {
+-		cdc_ioctl_t *msg = &prot->msg;
+-		/* len == needed when set/query fails from dongle */
+-		ioc->needed = le32_to_cpu(msg->len);
+-	}
+-
+-	/* Intercept the wme_dp ioctl here */
+-	if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
+-		int slen, val = 0;
+-
+-		slen = strlen("wme_dp") + 1;
+-		if (len >= (int)(slen + sizeof(int)))
+-			memcpy(&val, (char *)buf + slen, sizeof(int));
+-		dhd->wme_dp = (u8) le32_to_cpu(val);
+-	}
+-
+-	prot->pending = false;
+-
+-done:
+-	dhd_os_proto_unblock(dhd);
+-
+-	return ret;
+-}
+-
+-#define PKTSUMNEEDED(skb) \
+-		(((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL)
+-#define PKTSETSUMGOOD(skb, x) \
+-		(((struct sk_buff *)(skb))->ip_summed = \
+-		((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE))
+-
+-/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because
+-	skb->ip_summed is overloaded */
+-
+-int
+-dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+-		  void *params, int plen, void *arg, int len, bool set)
+-{
+-	return -ENOTSUPP;
+-}
+-
+-void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+-{
+-	bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
+-}
+-
+-void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf)
+-{
+-#ifdef BDC
+-	struct bdc_header *h;
+-#endif				/* BDC */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef BDC
+-	/* Push BDC header used to convey priority for buses that don't */
+-
+-	skb_push(pktbuf, BDC_HEADER_LEN);
+-
+-	h = (struct bdc_header *)(pktbuf->data);
+-
+-	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+-	if (PKTSUMNEEDED(pktbuf))
+-		h->flags |= BDC_FLAG_SUM_NEEDED;
+-
+-	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
+-	h->flags2 = 0;
+-	h->rssi = 0;
+-#endif				/* BDC */
+-	BDC_SET_IF_IDX(h, ifidx);
+-}
+-
+-int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf)
+-{
+-#ifdef BDC
+-	struct bdc_header *h;
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef BDC
+-	/* Pop BDC header used to convey priority for buses that don't */
+-
+-	if (pktbuf->len < BDC_HEADER_LEN) {
+-		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
+-			   pktbuf->len, BDC_HEADER_LEN));
+-		return -EBADE;
+-	}
+-
+-	h = (struct bdc_header *)(pktbuf->data);
+-
+-	*ifidx = BDC_GET_IF_IDX(h);
+-	if (*ifidx >= DHD_MAX_IFS) {
+-		DHD_ERROR(("%s: rx data ifnum out of range (%d)\n",
+-			   __func__, *ifidx));
+-		return -EBADE;
+-	}
+-
+-	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
+-	    BDC_PROTO_VER) {
+-		DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
+-			   dhd_ifname(dhd, *ifidx), h->flags));
+-		return -EBADE;
+-	}
+-
+-	if (h->flags & BDC_FLAG_SUM_GOOD) {
+-		DHD_INFO(("%s: BDC packet received with good rx-csum, "
+-			"flags 0x%x\n",
+-			dhd_ifname(dhd, *ifidx), h->flags));
+-		PKTSETSUMGOOD(pktbuf, true);
+-	}
+-
+-	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
+-
+-	skb_pull(pktbuf, BDC_HEADER_LEN);
+-#endif				/* BDC */
+-
+-	return 0;
+-}
+-
+-int dhd_prot_attach(dhd_pub_t *dhd)
+-{
+-	dhd_prot_t *cdc;
+-
+-	cdc = kzalloc(sizeof(dhd_prot_t), GFP_ATOMIC);
+-	if (!cdc) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* ensure that the msg buf directly follows the cdc msg struct */
+-	if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
+-		DHD_ERROR(("dhd_prot_t is not correctly defined\n"));
+-		goto fail;
+-	}
+-
+-	dhd->prot = cdc;
+-#ifdef BDC
+-	dhd->hdrlen += BDC_HEADER_LEN;
+-#endif
+-	dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
+-	return 0;
+-
+-fail:
+-	kfree(cdc);
+-	return -ENOMEM;
+-}
+-
+-/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
+-void dhd_prot_detach(dhd_pub_t *dhd)
+-{
+-	kfree(dhd->prot);
+-	dhd->prot = NULL;
+-}
+-
+-void dhd_prot_dstats(dhd_pub_t *dhd)
+-{
+-	/* No stats from dongle added yet, copy bus stats */
+-	dhd->dstats.tx_packets = dhd->tx_packets;
+-	dhd->dstats.tx_errors = dhd->tx_errors;
+-	dhd->dstats.rx_packets = dhd->rx_packets;
+-	dhd->dstats.rx_errors = dhd->rx_errors;
+-	dhd->dstats.rx_dropped = dhd->rx_dropped;
+-	dhd->dstats.multicast = dhd->rx_multicast;
+-	return;
+-}
+-
+-int dhd_prot_init(dhd_pub_t *dhd)
+-{
+-	int ret = 0;
+-	char buf[128];
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhd_os_proto_block(dhd);
+-
+-	/* Get the device MAC address */
+-	strcpy(buf, "cur_etheraddr");
+-	ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
+-	if (ret < 0) {
+-		dhd_os_proto_unblock(dhd);
+-		return ret;
+-	}
+-	memcpy(dhd->mac, buf, ETH_ALEN);
+-
+-	dhd_os_proto_unblock(dhd);
+-
+-#ifdef EMBEDDED_PLATFORM
+-	ret = dhd_preinit_ioctls(dhd);
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	/* Always assumes wl for now */
+-	dhd->iswl = true;
+-
+-	return ret;
+-}
+-
+-void dhd_prot_stop(dhd_pub_t *dhd)
+-{
+-	/* Nothing to do for CDC */
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c
+deleted file mode 100644
+index 0bfb93c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c
++++ /dev/null
+@@ -1,1848 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <linux/netdevice.h>
+-#include <bcmutils.h>
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-#include <msgtrace.h>
+-#include <wlioctl.h>
+-
+-int dhd_msg_level;
+-char fw_path[MOD_PARAM_PATHLEN];
+-char nv_path[MOD_PARAM_PATHLEN];
+-
+-/* Last connection success/failure status */
+-u32 dhd_conn_event;
+-u32 dhd_conn_status;
+-u32 dhd_conn_reason;
+-
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-extern void dhd_ind_scan_confirm(void *h, bool status);
+-extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen);
+-void dhd_iscan_lock(void);
+-void dhd_iscan_unlock(void);
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#define EPI_VERSION_STR         "4.218.248.5"
+-#ifdef DHD_DEBUG
+-const char dhd_version[] =
+-"Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " __DATE__
+-" at " __TIME__;
+-#else
+-const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR;
+-#endif
+-
+-void dhd_set_timer(void *bus, uint wdtick);
+-
+-/* IOVar table */
+-enum {
+-	IOV_VERSION = 1,
+-	IOV_MSGLEVEL,
+-	IOV_BCMERRORSTR,
+-	IOV_BCMERROR,
+-	IOV_WDTICK,
+-	IOV_DUMP,
+-#ifdef DHD_DEBUG
+-	IOV_CONS,
+-	IOV_DCONSOLE_POLL,
+-#endif
+-	IOV_CLEARCOUNTS,
+-	IOV_LOGDUMP,
+-	IOV_LOGCAL,
+-	IOV_LOGSTAMP,
+-	IOV_GPIOOB,
+-	IOV_IOCTLTIMEOUT,
+-	IOV_LAST
+-};
+-
+-const bcm_iovar_t dhd_iovars[] = {
+-	{"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version)}
+-	,
+-#ifdef DHD_DEBUG
+-	{"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}
+-	,
+-#endif				/* DHD_DEBUG */
+-	{"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN}
+-	,
+-	{"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0}
+-	,
+-	{"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0}
+-	,
+-	{"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN}
+-	,
+-#ifdef DHD_DEBUG
+-	{"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0}
+-	,
+-	{"cons", IOV_CONS, 0, IOVT_BUFFER, 0}
+-	,
+-#endif
+-	{"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0}
+-	,
+-	{"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0}
+-	,
+-	{"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0}
+-	,
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-void dhd_common_init(void)
+-{
+-	/* Init global variables at run-time, not as part of the declaration.
+-	 * This is required to support init/de-init of the driver.
+-	 * Initialization
+-	 * of globals as part of the declaration results in non-deterministic
+-	 * behaviour since the value of the globals may be different on the
+-	 * first time that the driver is initialized vs subsequent
+-	 * initializations.
+-	 */
+-	dhd_msg_level = DHD_ERROR_VAL;
+-#ifdef CONFIG_BCM4329_FW_PATH
+-	strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN - 1);
+-#else
+-	fw_path[0] = '\0';
+-#endif
+-#ifdef CONFIG_BCM4329_NVRAM_PATH
+-	strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN - 1);
+-#else
+-	nv_path[0] = '\0';
+-#endif
+-}
+-
+-static int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
+-{
+-	struct bcmstrbuf b;
+-	struct bcmstrbuf *strbuf = &b;
+-
+-	bcm_binit(strbuf, buf, buflen);
+-
+-	/* Base DHD info */
+-	bcm_bprintf(strbuf, "%s\n", dhd_version);
+-	bcm_bprintf(strbuf, "\n");
+-	bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
+-		    dhdp->up, dhdp->txoff, dhdp->busstate);
+-	bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n",
+-		    dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
+-	bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n",
+-		    dhdp->iswl, dhdp->drv_version, &dhdp->mac);
+-	bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror,
+-		    dhdp->tickcnt);
+-
+-	bcm_bprintf(strbuf, "dongle stats:\n");
+-	bcm_bprintf(strbuf,
+-		    "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n",
+-		    dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes,
+-		    dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped);
+-	bcm_bprintf(strbuf,
+-		    "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n",
+-		    dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes,
+-		    dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped);
+-	bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast);
+-
+-	bcm_bprintf(strbuf, "bus stats:\n");
+-	bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n",
+-		    dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors);
+-	bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n",
+-		    dhdp->tx_ctlpkts, dhdp->tx_ctlerrs);
+-	bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n",
+-		    dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors);
+-	bcm_bprintf(strbuf,
+-		    "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n",
+-		    dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped,
+-		    dhdp->rx_flushed);
+-	bcm_bprintf(strbuf,
+-		    "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n",
+-		    dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets);
+-	bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched);
+-	bcm_bprintf(strbuf, "\n");
+-
+-	/* Add any prot info */
+-	dhd_prot_dump(dhdp, strbuf);
+-	bcm_bprintf(strbuf, "\n");
+-
+-	/* Add any bus info */
+-	dhd_bus_dump(dhdp, strbuf);
+-
+-	return !strbuf->size ? -EOVERFLOW : 0;
+-}
+-
+-static int
+-dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid,
+-	    const char *name, void *params, int plen, void *arg, int len,
+-	    int val_size)
+-{
+-	int bcmerror = 0;
+-	s32 int_val = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_VERSION):
+-		/* Need to have checked buffer length */
+-		strncpy((char *)arg, dhd_version, len);
+-		break;
+-
+-	case IOV_GVAL(IOV_MSGLEVEL):
+-		int_val = (s32) dhd_msg_level;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_MSGLEVEL):
+-		dhd_msg_level = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_BCMERRORSTR):
+-		strncpy((char *)arg, "bcm_error",
+-			BCME_STRLEN);
+-		((char *)arg)[BCME_STRLEN - 1] = 0x00;
+-		break;
+-
+-	case IOV_GVAL(IOV_BCMERROR):
+-		int_val = (s32) dhd_pub->bcmerror;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_WDTICK):
+-		int_val = (s32) dhd_watchdog_ms;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_WDTICK):
+-		if (!dhd_pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-		dhd_os_wd_timer(dhd_pub, (uint) int_val);
+-		break;
+-
+-	case IOV_GVAL(IOV_DUMP):
+-		bcmerror = dhd_dump(dhd_pub, arg, len);
+-		break;
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_DCONSOLE_POLL):
+-		int_val = (s32) dhd_console_ms;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_DCONSOLE_POLL):
+-		dhd_console_ms = (uint) int_val;
+-		break;
+-
+-	case IOV_SVAL(IOV_CONS):
+-		if (len > 0)
+-			bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
+-		break;
+-#endif
+-
+-	case IOV_SVAL(IOV_CLEARCOUNTS):
+-		dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
+-		dhd_pub->tx_errors = dhd_pub->rx_errors = 0;
+-		dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0;
+-		dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0;
+-		dhd_pub->rx_dropped = 0;
+-		dhd_pub->rx_readahead_cnt = 0;
+-		dhd_pub->tx_realloc = 0;
+-		dhd_pub->wd_dpc_sched = 0;
+-		memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats));
+-		dhd_bus_clearcounts(dhd_pub);
+-		break;
+-
+-	case IOV_GVAL(IOV_IOCTLTIMEOUT):{
+-			int_val = (s32) dhd_os_get_ioctl_resp_timeout();
+-			memcpy(arg, &int_val, sizeof(int_val));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_IOCTLTIMEOUT):{
+-			if (int_val <= 0)
+-				bcmerror = -EINVAL;
+-			else
+-				dhd_os_set_ioctl_resp_timeout((unsigned int)
+-							      int_val);
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt,
+-		  int prec)
+-{
+-	struct sk_buff *p;
+-	int eprec = -1;		/* precedence to evict from */
+-	bool discard_oldest;
+-
+-	/* Fast case, precedence queue is not full and we are also not
+-	 * exceeding total queue length
+-	 */
+-	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
+-		bcm_pktq_penq(q, prec, pkt);
+-		return true;
+-	}
+-
+-	/* Determine precedence from which to evict packet, if any */
+-	if (pktq_pfull(q, prec))
+-		eprec = prec;
+-	else if (pktq_full(q)) {
+-		p = bcm_pktq_peek_tail(q, &eprec);
+-		ASSERT(p);
+-		if (eprec > prec)
+-			return false;
+-	}
+-
+-	/* Evict if needed */
+-	if (eprec >= 0) {
+-		/* Detect queueing to unconfigured precedence */
+-		ASSERT(!pktq_pempty(q, eprec));
+-		discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec);
+-		if (eprec == prec && !discard_oldest)
+-			return false;	/* refuse newer (incoming) packet */
+-		/* Evict packet according to discard policy */
+-		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+-			bcm_pktq_pdeq_tail(q, eprec);
+-		if (p == NULL) {
+-			DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.",
+-				   __func__, discard_oldest));
+-			ASSERT(p);
+-		}
+-
+-		bcm_pkt_buf_free_skb(p);
+-	}
+-
+-	/* Enqueue */
+-	p = bcm_pktq_penq(q, prec, pkt);
+-	if (p == NULL) {
+-		DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__));
+-		ASSERT(p);
+-	}
+-
+-	return true;
+-}
+-
+-static int
+-dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name,
+-	     void *params, int plen, void *arg, int len, bool set)
+-{
+-	int bcmerror = 0;
+-	int val_size;
+-	const bcm_iovar_t *vi = NULL;
+-	u32 actionid;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get MUST have return space */
+-	ASSERT(set || (arg && len));
+-
+-	/* Set does NOT take qualifiers */
+-	ASSERT(!set || (!params && !plen));
+-
+-	vi = bcm_iovar_lookup(dhd_iovars, name);
+-	if (vi == NULL) {
+-		bcmerror = -ENOTSUPP;
+-		goto exit;
+-	}
+-
+-	DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__,
+-		 name, (set ? "set" : "get"), len, plen));
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	bcmerror =
+-	    dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len,
+-			val_size);
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
+-{
+-	int bcmerror = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (!buf)
+-		return -EINVAL;
+-
+-	switch (ioc->cmd) {
+-	case DHD_GET_MAGIC:
+-		if (buflen < sizeof(int))
+-			bcmerror = -EOVERFLOW;
+-		else
+-			*(int *)buf = DHD_IOCTL_MAGIC;
+-		break;
+-
+-	case DHD_GET_VERSION:
+-		if (buflen < sizeof(int))
+-			bcmerror = -EOVERFLOW;
+-		else
+-			*(int *)buf = DHD_IOCTL_VERSION;
+-		break;
+-
+-	case DHD_GET_VAR:
+-	case DHD_SET_VAR:{
+-			char *arg;
+-			uint arglen;
+-
+-			/* scan past the name to any arguments */
+-			for (arg = buf, arglen = buflen; *arg && arglen;
+-			     arg++, arglen--)
+-				;
+-
+-			if (*arg) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* account for the NUL terminator */
+-			arg++, arglen--;
+-
+-			/* call with the appropriate arguments */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror =
+-				    dhd_iovar_op(dhd_pub, buf, arg, arglen, buf,
+-						 buflen, IOV_GET);
+-			else
+-				bcmerror =
+-				    dhd_iovar_op(dhd_pub, buf, NULL, 0, arg,
+-						 arglen, IOV_SET);
+-			if (bcmerror != -ENOTSUPP)
+-				break;
+-
+-			/* not in generic table, try protocol module */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg,
+-							     arglen, buf,
+-							     buflen, IOV_GET);
+-			else
+-				bcmerror = dhd_prot_iovar_op(dhd_pub, buf,
+-							     NULL, 0, arg,
+-							     arglen, IOV_SET);
+-			if (bcmerror != -ENOTSUPP)
+-				break;
+-
+-			/* if still not found, try bus module */
+-			if (ioc->cmd == DHD_GET_VAR)
+-				bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+-							    arg, arglen, buf,
+-							    buflen, IOV_GET);
+-			else
+-				bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+-							    NULL, 0, arg,
+-							    arglen, IOV_SET);
+-
+-			break;
+-		}
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-	}
+-
+-	return bcmerror;
+-}
+-
+-#ifdef SHOW_EVENTS
+-static void wl_show_host_event(wl_event_msg_t *event, void *event_data)
+-{
+-	uint i, status, reason;
+-	bool group = false, flush_txq = false, link = false;
+-	char *auth_str, *event_name;
+-	unsigned char *buf;
+-	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
+-	static struct {
+-		uint event;
+-		char *event_name;
+-	} event_names[] = {
+-		{
+-		WLC_E_SET_SSID, "SET_SSID"}, {
+-		WLC_E_JOIN, "JOIN"}, {
+-		WLC_E_START, "START"}, {
+-		WLC_E_AUTH, "AUTH"}, {
+-		WLC_E_AUTH_IND, "AUTH_IND"}, {
+-		WLC_E_DEAUTH, "DEAUTH"}, {
+-		WLC_E_DEAUTH_IND, "DEAUTH_IND"}, {
+-		WLC_E_ASSOC, "ASSOC"}, {
+-		WLC_E_ASSOC_IND, "ASSOC_IND"}, {
+-		WLC_E_REASSOC, "REASSOC"}, {
+-		WLC_E_REASSOC_IND, "REASSOC_IND"}, {
+-		WLC_E_DISASSOC, "DISASSOC"}, {
+-		WLC_E_DISASSOC_IND, "DISASSOC_IND"}, {
+-		WLC_E_QUIET_START, "START_QUIET"}, {
+-		WLC_E_QUIET_END, "END_QUIET"}, {
+-		WLC_E_BEACON_RX, "BEACON_RX"}, {
+-		WLC_E_LINK, "LINK"}, {
+-		WLC_E_MIC_ERROR, "MIC_ERROR"}, {
+-		WLC_E_NDIS_LINK, "NDIS_LINK"}, {
+-		WLC_E_ROAM, "ROAM"}, {
+-		WLC_E_TXFAIL, "TXFAIL"}, {
+-		WLC_E_PMKID_CACHE, "PMKID_CACHE"}, {
+-		WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
+-		WLC_E_PRUNE, "PRUNE"}, {
+-		WLC_E_AUTOAUTH, "AUTOAUTH"}, {
+-		WLC_E_EAPOL_MSG, "EAPOL_MSG"}, {
+-		WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
+-		WLC_E_ADDTS_IND, "ADDTS_IND"}, {
+-		WLC_E_DELTS_IND, "DELTS_IND"}, {
+-		WLC_E_BCNSENT_IND, "BCNSENT_IND"}, {
+-		WLC_E_BCNRX_MSG, "BCNRX_MSG"}, {
+-		WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
+-		WLC_E_ROAM_PREP, "ROAM_PREP"}, {
+-		WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
+-		WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
+-		WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
+-		WLC_E_JOIN_START, "JOIN_START"}, {
+-		WLC_E_ROAM_START, "ROAM_START"}, {
+-		WLC_E_ASSOC_START, "ASSOC_START"}, {
+-		WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
+-		WLC_E_RADIO, "RADIO"}, {
+-		WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
+-		WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
+-		WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
+-		WLC_E_PSK_SUP, "PSK_SUP"}, {
+-		WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
+-		WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
+-		WLC_E_ICV_ERROR, "ICV_ERROR"}, {
+-		WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
+-		WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
+-		WLC_E_TRACE, "TRACE"}, {
+-		WLC_E_ACTION_FRAME, "ACTION FRAME"}, {
+-		WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
+-		WLC_E_IF, "IF"}, {
+-		WLC_E_RSSI, "RSSI"}, {
+-		WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
+-	};
+-	uint event_type, flags, auth_type, datalen;
+-	event_type = be32_to_cpu(event->event_type);
+-	flags = be16_to_cpu(event->flags);
+-	status = be32_to_cpu(event->status);
+-	reason = be32_to_cpu(event->reason);
+-	auth_type = be32_to_cpu(event->auth_type);
+-	datalen = be32_to_cpu(event->datalen);
+-	/* debug dump of event messages */
+-	sprintf(eabuf, "%pM", event->addr);
+-
+-	event_name = "UNKNOWN";
+-	for (i = 0; i < ARRAY_SIZE(event_names); i++) {
+-		if (event_names[i].event == event_type)
+-			event_name = event_names[i].event_name;
+-	}
+-
+-	DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type));
+-	DHD_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
+-				flags, status, reason, auth_type, eabuf));
+-
+-	if (flags & WLC_EVENT_MSG_LINK)
+-		link = true;
+-	if (flags & WLC_EVENT_MSG_GROUP)
+-		group = true;
+-	if (flags & WLC_EVENT_MSG_FLUSHTXQ)
+-		flush_txq = true;
+-
+-	switch (event_type) {
+-	case WLC_E_START:
+-	case WLC_E_DEAUTH:
+-	case WLC_E_DISASSOC:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_ASSOC:
+-	case WLC_E_REASSOC:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n",
+-				   event_name, eabuf));
+-		} else if (status == WLC_E_STATUS_TIMEOUT) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n",
+-				   event_name, eabuf));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
+-				   event_name, eabuf, (int)reason));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status "
+-				"%d\n", event_name, eabuf, (int)status));
+-		}
+-		break;
+-
+-	case WLC_E_DEAUTH_IND:
+-	case WLC_E_DISASSOC_IND:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name,
+-			   eabuf, (int)reason));
+-		break;
+-
+-	case WLC_E_AUTH:
+-	case WLC_E_AUTH_IND:
+-		if (auth_type == WLAN_AUTH_OPEN)
+-			auth_str = "Open System";
+-		else if (auth_type == WLAN_AUTH_SHARED_KEY)
+-			auth_str = "Shared Key";
+-		else {
+-			sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
+-			auth_str = err_msg;
+-		}
+-		if (event_type == WLC_E_AUTH_IND) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name,
+-				   eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n",
+-				   event_name, eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_TIMEOUT) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
+-				   event_name, eabuf, auth_str));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, "
+-				"reason %d\n",
+-				event_name, eabuf, auth_str, (int)reason));
+-		}
+-
+-		break;
+-
+-	case WLC_E_JOIN:
+-	case WLC_E_ROAM:
+-	case WLC_E_SET_SSID:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name,
+-				   eabuf));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, failed\n", event_name));
+-		} else if (status == WLC_E_STATUS_NO_NETWORKS) {
+-			DHD_EVENT(("MACEVENT: %s, no networks found\n",
+-				   event_name));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, unexpected status %d\n",
+-				   event_name, (int)status));
+-		}
+-		break;
+-
+-	case WLC_E_BEACON_RX:
+-		if (status == WLC_E_STATUS_SUCCESS) {
+-			DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name));
+-		} else if (status == WLC_E_STATUS_FAIL) {
+-			DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name));
+-		} else {
+-			DHD_EVENT(("MACEVENT: %s, status %d\n", event_name,
+-				   status));
+-		}
+-		break;
+-
+-	case WLC_E_LINK:
+-		DHD_EVENT(("MACEVENT: %s %s\n", event_name,
+-			   link ? "UP" : "DOWN"));
+-		break;
+-
+-	case WLC_E_MIC_ERROR:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
+-			   event_name, eabuf, group, flush_txq));
+-		break;
+-
+-	case WLC_E_ICV_ERROR:
+-	case WLC_E_UNICAST_DECODE_ERROR:
+-	case WLC_E_MULTICAST_DECODE_ERROR:
+-		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_TXFAIL:
+-		DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf));
+-		break;
+-
+-	case WLC_E_SCAN_COMPLETE:
+-	case WLC_E_PMKID_CACHE:
+-		DHD_EVENT(("MACEVENT: %s\n", event_name));
+-		break;
+-
+-	case WLC_E_PFN_NET_FOUND:
+-	case WLC_E_PFN_NET_LOST:
+-	case WLC_E_PFN_SCAN_COMPLETE:
+-		DHD_EVENT(("PNOEVENT: %s\n", event_name));
+-		break;
+-
+-	case WLC_E_PSK_SUP:
+-	case WLC_E_PRUNE:
+-		DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n",
+-			   event_name, (int)status, (int)reason));
+-		break;
+-
+-	case WLC_E_TRACE:
+-		{
+-			static u32 seqnum_prev;
+-			msgtrace_hdr_t hdr;
+-			u32 nblost;
+-			char *s, *p;
+-
+-			buf = (unsigned char *) event_data;
+-			memcpy(&hdr, buf, MSGTRACE_HDRLEN);
+-
+-			if (hdr.version != MSGTRACE_VERSION) {
+-				DHD_ERROR(
+-				    ("\nMACEVENT: %s [unsupported version --> "
+-				     "dhd version:%d dongle version:%d]\n",
+-				     event_name, MSGTRACE_VERSION, hdr.version)
+-				);
+-				/* Reset datalen to avoid display below */
+-				datalen = 0;
+-				break;
+-			}
+-
+-			/* There are 2 bytes available at the end of data */
+-			buf[MSGTRACE_HDRLEN + be16_to_cpu(hdr.len)] = '\0';
+-
+-			if (be32_to_cpu(hdr.discarded_bytes)
+-			    || be32_to_cpu(hdr.discarded_printf)) {
+-				DHD_ERROR(
+-				    ("\nWLC_E_TRACE: [Discarded traces in dongle -->"
+-				     "discarded_bytes %d discarded_printf %d]\n",
+-				     be32_to_cpu(hdr.discarded_bytes),
+-				     be32_to_cpu(hdr.discarded_printf)));
+-			}
+-
+-			nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
+-			if (nblost > 0) {
+-				DHD_ERROR(
+-				    ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n",
+-				     be32_to_cpu(hdr.seqnum), nblost));
+-			}
+-			seqnum_prev = be32_to_cpu(hdr.seqnum);
+-
+-			/* Display the trace buffer. Advance from \n to \n to
+-			 * avoid display big
+-			 * printf (issue with Linux printk )
+-			 */
+-			p = (char *)&buf[MSGTRACE_HDRLEN];
+-			while ((s = strstr(p, "\n")) != NULL) {
+-				*s = '\0';
+-				printk(KERN_DEBUG"%s\n", p);
+-				p = s + 1;
+-			}
+-			printk(KERN_DEBUG "%s\n", p);
+-
+-			/* Reset datalen to avoid display below */
+-			datalen = 0;
+-		}
+-		break;
+-
+-	case WLC_E_RSSI:
+-		DHD_EVENT(("MACEVENT: %s %d\n", event_name,
+-			   be32_to_cpu(*((int *)event_data))));
+-		break;
+-
+-	default:
+-		DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, "
+-			"auth %d\n", event_name, event_type, eabuf,
+-			(int)status, (int)reason, (int)auth_type));
+-		break;
+-	}
+-
+-	/* show any appended data */
+-	if (datalen) {
+-		buf = (unsigned char *) event_data;
+-		DHD_EVENT((" data (%d) : ", datalen));
+-		for (i = 0; i < datalen; i++)
+-			DHD_EVENT((" 0x%02x ", *buf++));
+-		DHD_EVENT(("\n"));
+-	}
+-}
+-#endif				/* SHOW_EVENTS */
+-
+-int
+-wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata,
+-	      wl_event_msg_t *event, void **data_ptr)
+-{
+-	/* check whether packet is a BRCM event pkt */
+-	bcm_event_t *pvt_data = (bcm_event_t *) pktdata;
+-	char *event_data;
+-	u32 type, status;
+-	u16 flags;
+-	int evlen;
+-
+-	if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
+-		DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__));
+-		return -EBADE;
+-	}
+-
+-	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
+-	if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) !=
+-	    BCMILCP_BCM_SUBTYPE_EVENT) {
+-		DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__));
+-		return -EBADE;
+-	}
+-
+-	*data_ptr = &pvt_data[1];
+-	event_data = *data_ptr;
+-
+-	/* memcpy since BRCM event pkt may be unaligned. */
+-	memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t));
+-
+-	type = get_unaligned_be32(&event->event_type);
+-	flags = get_unaligned_be16(&event->flags);
+-	status = get_unaligned_be32(&event->status);
+-	evlen = get_unaligned_be32(&event->datalen) + sizeof(bcm_event_t);
+-
+-	switch (type) {
+-	case WLC_E_IF:
+-		{
+-			dhd_if_event_t *ifevent = (dhd_if_event_t *) event_data;
+-			DHD_TRACE(("%s: if event\n", __func__));
+-
+-			if (ifevent->ifidx > 0 &&
+-				 ifevent->ifidx < DHD_MAX_IFS) {
+-				if (ifevent->action == WLC_E_IF_ADD)
+-					dhd_add_if(dhd, ifevent->ifidx,
+-						   NULL, event->ifname,
+-						   pvt_data->eth.h_dest,
+-						   ifevent->flags,
+-						   ifevent->bssidx);
+-				else
+-					dhd_del_if(dhd, ifevent->ifidx);
+-			} else {
+-				DHD_ERROR(("%s: Invalid ifidx %d for %s\n",
+-					   __func__, ifevent->ifidx,
+-					   event->ifname));
+-			}
+-		}
+-		/* send up the if event: btamp user needs it */
+-		*ifidx = dhd_ifname2idx(dhd, event->ifname);
+-		/* push up to external supp/auth */
+-		dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
+-		break;
+-
+-#ifdef P2P
+-	case WLC_E_NDIS_LINK:
+-		break;
+-#endif
+-		/* fall through */
+-		/* These are what external supplicant/authenticator wants */
+-	case WLC_E_LINK:
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-	case WLC_E_DISASSOC_IND:
+-	case WLC_E_MIC_ERROR:
+-	default:
+-		/* Fall through: this should get _everything_  */
+-
+-		*ifidx = dhd_ifname2idx(dhd, event->ifname);
+-		/* push up to external supp/auth */
+-		dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
+-		DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n",
+-			   __func__, type, flags, status));
+-
+-		/* put it back to WLC_E_NDIS_LINK */
+-		if (type == WLC_E_NDIS_LINK) {
+-			u32 temp;
+-
+-			temp = get_unaligned_be32(&event->event_type);
+-			DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp));
+-
+-			temp = be32_to_cpu(WLC_E_NDIS_LINK);
+-			memcpy((void *)(&pvt_data->event.event_type), &temp,
+-			       sizeof(pvt_data->event.event_type));
+-		}
+-		break;
+-	}
+-
+-#ifdef SHOW_EVENTS
+-	wl_show_host_event(event, event_data);
+-#endif				/* SHOW_EVENTS */
+-
+-	return 0;
+-}
+-
+-/* Convert user's input in hex pattern to byte-size mask */
+-static int wl_pattern_atoh(char *src, char *dst)
+-{
+-	int i;
+-	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
+-		DHD_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+-		return -1;
+-	}
+-	src = src + 2;		/* Skip past 0x */
+-	if (strlen(src) % 2 != 0) {
+-		DHD_ERROR(("Mask invalid format. Length must be even.\n"));
+-		return -1;
+-	}
+-	for (i = 0; *src != '\0'; i++) {
+-		char num[3];
+-		strncpy(num, src, 2);
+-		num[2] = '\0';
+-		dst[i] = (u8) simple_strtoul(num, NULL, 16);
+-		src += 2;
+-	}
+-	return i;
+-}
+-
+-void
+-dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable,
+-			     int master_mode)
+-{
+-	char *argv[8];
+-	int i = 0;
+-	const char *str;
+-	int buf_len;
+-	int str_len;
+-	char *arg_save = 0, *arg_org = 0;
+-	int rc;
+-	char buf[128];
+-	wl_pkt_filter_enable_t enable_parm;
+-	wl_pkt_filter_enable_t *pkt_filterp;
+-
+-	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
+-	if (!arg_save) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-	arg_org = arg_save;
+-	memcpy(arg_save, arg, strlen(arg) + 1);
+-
+-	argv[i] = strsep(&arg_save, " ");
+-
+-	i = 0;
+-	if (NULL == argv[i]) {
+-		DHD_ERROR(("No args provided\n"));
+-		goto fail;
+-	}
+-
+-	str = "pkt_filter_enable";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (wl_pkt_filter_enable_t *) (buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	enable_parm.id = simple_strtoul(argv[i], NULL, 0);
+-
+-	/* Parse enable/disable value. */
+-	enable_parm.enable = enable;
+-
+-	buf_len += sizeof(enable_parm);
+-	memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
+-
+-	/* Enable/disable the specified filter. */
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+-	rc = rc >= 0 ? 0 : rc;
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-	else
+-		DHD_TRACE(("%s: successfully added pktfilter %s\n",
+-			   __func__, arg));
+-
+-	/* Contorl the master mode */
+-	bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf,
+-		    sizeof(buf));
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+-	rc = rc >= 0 ? 0 : rc;
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-
+-fail:
+-	kfree(arg_org);
+-}
+-
+-void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg)
+-{
+-	const char *str;
+-	wl_pkt_filter_t pkt_filter;
+-	wl_pkt_filter_t *pkt_filterp;
+-	int buf_len;
+-	int str_len;
+-	int rc;
+-	u32 mask_size;
+-	u32 pattern_size;
+-	char *argv[8], *buf = 0;
+-	int i = 0;
+-	char *arg_save = 0, *arg_org = 0;
+-#define BUF_SIZE		2048
+-
+-	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
+-	if (!arg_save) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	arg_org = arg_save;
+-
+-	buf = kmalloc(BUF_SIZE, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: kmalloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	memcpy(arg_save, arg, strlen(arg) + 1);
+-
+-	if (strlen(arg) > BUF_SIZE) {
+-		DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg),
+-			   (int)sizeof(buf)));
+-		goto fail;
+-	}
+-
+-	argv[i] = strsep(&arg_save, " ");
+-	while (argv[i++])
+-		argv[i] = strsep(&arg_save, " ");
+-
+-	i = 0;
+-	if (NULL == argv[i]) {
+-		DHD_ERROR(("No args provided\n"));
+-		goto fail;
+-	}
+-
+-	str = "pkt_filter_add";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	pkt_filter.id = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Polarity not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse filter polarity. */
+-	pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Filter type not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse filter type. */
+-	pkt_filter.type = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Offset not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter offset. */
+-	pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Bitmask not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter mask. */
+-	mask_size =
+-	    wl_pattern_atoh
+-		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
+-
+-	if (NULL == argv[++i]) {
+-		DHD_ERROR(("Pattern not provided\n"));
+-		goto fail;
+-	}
+-
+-	/* Parse pattern filter pattern. */
+-	pattern_size =
+-	    wl_pattern_atoh(argv[i],
+-				   (char *)&pkt_filterp->u.pattern.
+-				   mask_and_pattern[mask_size]);
+-
+-	if (mask_size != pattern_size) {
+-		DHD_ERROR(("Mask and pattern not the same size\n"));
+-		goto fail;
+-	}
+-
+-	pkt_filter.u.pattern.size_bytes = mask_size;
+-	buf_len += WL_PKT_FILTER_FIXED_LEN;
+-	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+-
+-	/* Keep-alive attributes are set in local
+-	 * variable (keep_alive_pkt), and
+-	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
+-	 ** guarantee that the buffer is properly aligned.
+-	 */
+-	memcpy((char *)pkt_filterp,
+-	       &pkt_filter,
+-	       WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+-
+-	rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len);
+-	rc = rc >= 0 ? 0 : rc;
+-
+-	if (rc)
+-		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+-			   __func__, arg, rc));
+-	else
+-		DHD_TRACE(("%s: successfully added pktfilter %s\n",
+-			   __func__, arg));
+-
+-fail:
+-	kfree(arg_org);
+-
+-	kfree(buf);
+-}
+-
+-void dhd_arp_offload_set(dhd_pub_t *dhd, int arp_mode)
+-{
+-	char iovbuf[32];
+-	int retcode;
+-
+-	bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+-	retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	retcode = retcode >= 0 ? 0 : retcode;
+-	if (retcode)
+-		DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, "
+-			"retcode = %d\n", __func__, arp_mode, retcode));
+-	else
+-		DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n",
+-			   __func__, arp_mode));
+-}
+-
+-void dhd_arp_offload_enable(dhd_pub_t *dhd, int arp_enable)
+-{
+-	char iovbuf[32];
+-	int retcode;
+-
+-	bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf));
+-	retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	retcode = retcode >= 0 ? 0 : retcode;
+-	if (retcode)
+-		DHD_TRACE(("%s: failed to enabe ARP offload to %d, "
+-			"retcode = %d\n", __func__, arp_enable, retcode));
+-	else
+-		DHD_TRACE(("%s: successfully enabed ARP offload to %d\n",
+-			   __func__, arp_enable));
+-}
+-
+-int dhd_preinit_ioctls(dhd_pub_t *dhd)
+-{
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for
+-				 "event_msgs" + '\0' + bitvec  */
+-	uint up = 0;
+-	char buf[128], *ptr;
+-	uint power_mode = PM_FAST;
+-	u32 dongle_align = DHD_SDALIGN;
+-	u32 glom = 0;
+-	uint bcn_timeout = 3;
+-	int scan_assoc_time = 40;
+-	int scan_unassoc_time = 40;
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-	int ret = 0;
+-	u8 ea_addr[ETH_ALEN];
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+-
+-	dhd_os_proto_block(dhd);
+-
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-	/* Read MAC address from external customer place
+-	 ** NOTE that default mac address has to be present in
+-	 ** otp or nvram file to bring up
+-	 ** firmware but unique per board mac address maybe provided by
+-	 ** customer code
+-	 */
+-	ret = dhd_custom_get_mac_address(ea_addr);
+-	if (!ret) {
+-		bcm_mkiovar("cur_etheraddr", (void *)ea_addr, ETH_ALEN,
+-			    buf, sizeof(buf));
+-		ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf));
+-		if (ret < 0) {
+-			DHD_ERROR(("%s: can't set MAC address , error=%d\n",
+-				   __func__, ret));
+-		} else
+-			memcpy(dhd->mac.octet, (void *)&ea_addr,
+-			       ETH_ALEN);
+-	}
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+-
+-	/* Set Country code */
+-	if (dhd->country_code[0] != 0) {
+-		if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
+-				     dhd->country_code,
+-				     sizeof(dhd->country_code)) < 0) {
+-			DHD_ERROR(("%s: country code setting failed\n",
+-				   __func__));
+-		}
+-	}
+-
+-	/* query for 'ver' to get version info from firmware */
+-	memset(buf, 0, sizeof(buf));
+-	ptr = buf;
+-	bcm_mkiovar("ver", 0, 0, buf, sizeof(buf));
+-	dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
+-	strsep(&ptr, "\n");
+-	/* Print fw version info */
+-	DHD_ERROR(("Firmware version = %s\n", buf));
+-
+-	/* Set PowerSave mode */
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode,
+-			 sizeof(power_mode));
+-
+-	/* Match Host and Dongle rx alignment */
+-	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* disable glom option per default */
+-	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Setup timeout if Beacons are lost and roam is off to report
+-		 link down */
+-	bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Enable/Disable build-in roaming to allowed ext supplicant to take
+-		 of romaing */
+-	bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* Force STA UP */
+-	if (dhd_radio_up)
+-		dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));
+-
+-	/* Setup event_msgs */
+-	bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME,
+-			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME,
+-			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
+-
+-#ifdef ARP_OFFLOAD_SUPPORT
+-	/* Set and enable ARP offload feature */
+-	if (dhd_arp_enable)
+-		dhd_arp_offload_set(dhd, dhd_arp_mode);
+-	dhd_arp_offload_enable(dhd, dhd_arp_enable);
+-#endif				/* ARP_OFFLOAD_SUPPORT */
+-
+-#ifdef PKT_FILTER_SUPPORT
+-	{
+-		int i;
+-		/* Set up pkt filter */
+-		if (dhd_pkt_filter_enable) {
+-			for (i = 0; i < dhd->pktfilter_count; i++) {
+-				dhd_pktfilter_offload_set(dhd,
+-							  dhd->pktfilter[i]);
+-				dhd_pktfilter_offload_enable(dhd,
+-				     dhd->pktfilter[i],
+-				     dhd_pkt_filter_init,
+-				     dhd_master_mode);
+-			}
+-		}
+-	}
+-#endif				/* PKT_FILTER_SUPPORT */
+-
+-	dhd_os_proto_unblock(dhd);
+-
+-	return 0;
+-}
+-
+-#ifdef SIMPLE_ISCAN
+-uint iscan_thread_id;
+-iscan_buf_t *iscan_chain;
+-
+-iscan_buf_t *dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
+-{
+-	iscan_buf_t *iscanbuf_alloc = 0;
+-	iscan_buf_t *iscanbuf_head;
+-
+-	dhd_iscan_lock();
+-
+-	iscanbuf_alloc = kmalloc(sizeof(iscan_buf_t), GFP_ATOMIC);
+-	if (iscanbuf_alloc == NULL)
+-		goto fail;
+-
+-	iscanbuf_alloc->next = NULL;
+-	iscanbuf_head = *iscanbuf;
+-
+-	DHD_ISCAN(("%s: addr of allocated node = 0x%X"
+-		   "addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
+-		   __func__, iscanbuf_alloc, iscanbuf_head, dhd));
+-
+-	if (iscanbuf_head == NULL) {
+-		*iscanbuf = iscanbuf_alloc;
+-		DHD_ISCAN(("%s: Head is allocated\n", __func__));
+-		goto fail;
+-	}
+-
+-	while (iscanbuf_head->next)
+-		iscanbuf_head = iscanbuf_head->next;
+-
+-	iscanbuf_head->next = iscanbuf_alloc;
+-
+-fail:
+-	dhd_iscan_unlock();
+-	return iscanbuf_alloc;
+-}
+-
+-void dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
+-{
+-	iscan_buf_t *iscanbuf_free = 0;
+-	iscan_buf_t *iscanbuf_prv = 0;
+-	iscan_buf_t *iscanbuf_cur = iscan_chain;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-
+-	dhd_iscan_lock();
+-	/* If iscan_delete is null then delete the entire
+-	 * chain or else delete specific one provided
+-	 */
+-	if (!iscan_delete) {
+-		while (iscanbuf_cur) {
+-			iscanbuf_free = iscanbuf_cur;
+-			iscanbuf_cur = iscanbuf_cur->next;
+-			iscanbuf_free->next = 0;
+-			kfree(iscanbuf_free);
+-		}
+-		iscan_chain = 0;
+-	} else {
+-		while (iscanbuf_cur) {
+-			if (iscanbuf_cur == iscan_delete)
+-				break;
+-			iscanbuf_prv = iscanbuf_cur;
+-			iscanbuf_cur = iscanbuf_cur->next;
+-		}
+-		if (iscanbuf_prv)
+-			iscanbuf_prv->next = iscan_delete->next;
+-
+-		iscan_delete->next = 0;
+-		kfree(iscan_delete);
+-
+-		if (!iscanbuf_prv)
+-			iscan_chain = 0;
+-	}
+-	dhd_iscan_unlock();
+-}
+-
+-iscan_buf_t *dhd_iscan_result_buf(void)
+-{
+-	return iscan_chain;
+-}
+-
+-/*
+-* print scan cache
+-* print partial iscan_skip list differently
+-*/
+-int dhd_iscan_print_cache(iscan_buf_t *iscan_skip)
+-{
+-	int i = 0, l = 0;
+-	iscan_buf_t *iscan_cur;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi;
+-
+-	dhd_iscan_lock();
+-
+-	iscan_cur = dhd_iscan_result_buf();
+-
+-	while (iscan_cur) {
+-		list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-		if (!list)
+-			break;
+-
+-		results = (wl_scan_results_t *)&list->results;
+-		if (!results)
+-			break;
+-
+-		if (results->version != WL_BSS_INFO_VERSION) {
+-			DHD_ISCAN(("%s: results->version %d != "
+-				"WL_BSS_INFO_VERSION\n",
+-				__func__, results->version));
+-			goto done;
+-		}
+-
+-		bi = results->bss_info;
+-		for (i = 0; i < results->count; i++) {
+-			if (!bi)
+-				break;
+-
+-			DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
+-				   iscan_cur != iscan_skip ? "BSS" : "bss", l,
+-				   i, bi->BSSID.octet[0], bi->BSSID.octet[1],
+-				   bi->BSSID.octet[2], bi->BSSID.octet[3],
+-				   bi->BSSID.octet[4], bi->BSSID.octet[5]));
+-
+-			bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
+-		}
+-		iscan_cur = iscan_cur->next;
+-		l++;
+-	}
+-
+-done:
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-/*
+-* delete disappeared AP from specific scan cache but skip partial
+-* list in iscan_skip
+-*/
+-int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip)
+-{
+-	int i = 0, j = 0, l = 0;
+-	iscan_buf_t *iscan_cur;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;
+-
+-	unsigned char *s_addr = addr;
+-
+-	dhd_iscan_lock();
+-	DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n",
+-		   __func__, s_addr[0], s_addr[1], s_addr[2],
+-		   s_addr[3], s_addr[4], s_addr[5]));
+-
+-	iscan_cur = dhd_iscan_result_buf();
+-
+-	while (iscan_cur) {
+-		if (iscan_cur != iscan_skip) {
+-			list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-			if (!list)
+-				break;
+-
+-			results = (wl_scan_results_t *)&list->results;
+-			if (!results)
+-				break;
+-
+-			if (results->version != WL_BSS_INFO_VERSION) {
+-				DHD_ERROR(("%s: results->version %d != "
+-					"WL_BSS_INFO_VERSION\n",
+-					__func__, results->version));
+-				goto done;
+-			}
+-
+-			bi = results->bss_info;
+-			for (i = 0; i < results->count; i++) {
+-				if (!bi)
+-					break;
+-
+-				if (!memcmp
+-				    (bi->BSSID.octet, addr, ETH_ALEN)) {
+-					DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] "
+-					"%X:%X:%X:%X:%X:%X\n",
+-					__func__, l, i, bi->BSSID.octet[0],
+-					bi->BSSID.octet[1], bi->BSSID.octet[2],
+-					bi->BSSID.octet[3], bi->BSSID.octet[4],
+-					bi->BSSID.octet[5]));
+-
+-					bi_new = bi;
+-					bi = (wl_bss_info_t *)((unsigned long)
+-							       bi + bi->length);
+-/*
+-			if(bi && bi_new) {
+-				memcpy(bi_new, bi, results->buflen -
+-				bi_new->length);
+-				results->buflen -= bi_new->length;
+-			}
+-*/
+-					results->buflen -= bi_new->length;
+-					results->count--;
+-
+-					for (j = i; j < results->count; j++) {
+-						if (bi && bi_new) {
+-							DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" "%X:%X:%X:%X:%X:%X\n",
+-							__func__, l, j,
+-							bi->BSSID.octet[0],
+-							bi->BSSID.octet[1],
+-							bi->BSSID.octet[2],
+-							bi->BSSID.octet[3],
+-							bi->BSSID.octet[4],
+-							bi->BSSID.octet[5]));
+-
+-							bi_next =
+-							    (wl_bss_info_t *)((unsigned long)bi +
+-								 bi->length);
+-							memcpy(bi_new, bi,
+-							      bi->length);
+-							bi_new =
+-							    (wl_bss_info_t *)((unsigned long)bi_new +
+-								 bi_new->
+-								  length);
+-							bi = bi_next;
+-						}
+-					}
+-
+-					if (results->count == 0) {
+-						/* Prune now empty partial
+-						scan list */
+-						dhd_iscan_free_buf(dhdp,
+-								   iscan_cur);
+-						goto done;
+-					}
+-					break;
+-				}
+-				bi = (wl_bss_info_t *)((unsigned long)bi +
+-							bi->length);
+-			}
+-		}
+-		iscan_cur = iscan_cur->next;
+-		l++;
+-	}
+-
+-done:
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-int dhd_iscan_remove_duplicates(void *dhdp, iscan_buf_t *iscan_cur)
+-{
+-	int i = 0;
+-	wl_iscan_results_t *list;
+-	wl_scan_results_t *results;
+-	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;
+-
+-	dhd_iscan_lock();
+-
+-	DHD_ISCAN(("%s: Scan cache before delete\n", __func__));
+-	dhd_iscan_print_cache(iscan_cur);
+-
+-	if (!iscan_cur)
+-		goto done;
+-
+-	list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
+-	if (!list)
+-		goto done;
+-
+-	results = (wl_scan_results_t *)&list->results;
+-	if (!results)
+-		goto done;
+-
+-	if (results->version != WL_BSS_INFO_VERSION) {
+-		DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n",
+-			   __func__, results->version));
+-		goto done;
+-	}
+-
+-	bi = results->bss_info;
+-	for (i = 0; i < results->count; i++) {
+-		if (!bi)
+-			break;
+-
+-		DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n",
+-			   __func__, i, bi->BSSID.octet[0],
+-			   bi->BSSID.octet[1], bi->BSSID.octet[2],
+-			   bi->BSSID.octet[3], bi->BSSID.octet[4],
+-			   bi->BSSID.octet[5]));
+-
+-		dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur);
+-
+-		bi = (wl_bss_info_t *)((unsigned long)bi + bi->length);
+-	}
+-
+-done:
+-	DHD_ISCAN(("%s: Scan cache after delete\n", __func__));
+-	dhd_iscan_print_cache(iscan_cur);
+-	dhd_iscan_unlock();
+-	return 0;
+-}
+-
+-void dhd_iscan_ind_scan_confirm(void *dhdp, bool status)
+-{
+-
+-	dhd_ind_scan_confirm(dhdp, status);
+-}
+-
+-int dhd_iscan_request(void *dhdp, u16 action)
+-{
+-	int rc;
+-	wl_iscan_params_t params;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-	char buf[WLC_IOCTL_SMLEN];
+-
+-	memset(&params, 0, sizeof(wl_iscan_params_t));
+-	memcpy(&params.params.bssid, &ether_bcast, ETH_ALEN);
+-
+-	params.params.bss_type = DOT11_BSSTYPE_ANY;
+-	params.params.scan_type = DOT11_SCANTYPE_ACTIVE;
+-
+-	params.params.nprobes = -1;
+-	params.params.active_time = -1;
+-	params.params.passive_time = -1;
+-	params.params.home_time = -1;
+-	params.params.channel_num = 0;
+-
+-	params.version = ISCAN_REQ_VERSION;
+-	params.action = action;
+-	params.scan_duration = 0;
+-
+-	bcm_mkiovar("iscan", (char *)&params, sizeof(wl_iscan_params_t), buf,
+-		    WLC_IOCTL_SMLEN);
+-	rc = dhd_wl_ioctl(dhdp, WLC_SET_VAR, buf, WLC_IOCTL_SMLEN);
+-
+-	return rc;
+-}
+-
+-static int dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
+-{
+-	wl_iscan_results_t *list_buf;
+-	wl_iscan_results_t list;
+-	wl_scan_results_t *results;
+-	iscan_buf_t *iscan_cur;
+-	int status = -1;
+-	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+-	int rc;
+-
+-	iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain);
+-	if (!iscan_cur) {
+-		DHD_ERROR(("%s: Failed to allocate node\n", __func__));
+-		dhd_iscan_free_buf(dhdp, 0);
+-		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
+-		goto fail;
+-	}
+-
+-	dhd_iscan_lock();
+-
+-	memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+-	list_buf = (wl_iscan_results_t *) iscan_cur->iscan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = WLC_IW_ISCAN_MAXLEN;
+-	bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE,
+-		    iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+-	rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf,
+-			  WLC_IW_ISCAN_MAXLEN);
+-
+-	results->buflen = results->buflen;
+-	results->version = results->version;
+-	*scan_count = results->count = results->count;
+-	status = list_buf->status;
+-
+-	dhd_iscan_unlock();
+-
+-	if (!(*scan_count))
+-		dhd_iscan_free_buf(dhdp, iscan_cur);
+-	else
+-		dhd_iscan_remove_duplicates(dhdp, iscan_cur);
+-
+-fail:
+-	return status;
+-}
+-#endif				/* SIMPLE_ISCAN */
+-
+-#ifdef PNO_SUPPORT
+-int dhd_pno_clean(dhd_pub_t *dhd)
+-{
+-	char iovbuf[128];
+-	int pfn_enabled = 0;
+-	int iov_len = 0;
+-	int ret;
+-
+-	/* Disable pfn */
+-	iov_len =
+-	    bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf));
+-	ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (ret >= 0) {
+-		/* clear pfn */
+-		iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf));
+-		if (iov_len) {
+-			ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					iov_len);
+-			if (ret < 0) {
+-				DHD_ERROR(("%s failed code %d\n", __func__,
+-					   ret));
+-			}
+-		} else {
+-			ret = -1;
+-			DHD_ERROR(("%s failed code %d\n", __func__, iov_len));
+-		}
+-	} else
+-		DHD_ERROR(("%s failed code %d\n", __func__, ret));
+-
+-	return ret;
+-}
+-
+-int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
+-{
+-	char iovbuf[128];
+-	int ret = -1;
+-
+-	if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
+-		DHD_ERROR(("%s error exit\n", __func__));
+-		return ret;
+-	}
+-
+-	/* Enable/disable PNO */
+-	ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf,
+-			sizeof(iovbuf));
+-	if (ret > 0) {
+-		ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-				sizeof(iovbuf));
+-		if (ret < 0) {
+-			DHD_ERROR(("%s failed for error=%d\n", __func__, ret));
+-			return ret;
+-		} else {
+-			dhd->pno_enable = pfn_enabled;
+-			DHD_TRACE(("%s set pno as %d\n", __func__,
+-				   dhd->pno_enable));
+-		}
+-	} else
+-		DHD_ERROR(("%s failed err=%d\n", __func__, ret));
+-
+-	return ret;
+-}
+-
+-/* Function to execute combined scan */
+-int
+-dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char scan_fr)
+-{
+-	int err = -1;
+-	char iovbuf[128];
+-	int k, i;
+-	wl_pfn_param_t pfn_param;
+-	wl_pfn_t pfn_element;
+-
+-	DHD_TRACE(("%s nssid=%d nchan=%d\n", __func__, nssid, scan_fr));
+-
+-	if ((!dhd) && (!ssids_local)) {
+-		DHD_ERROR(("%s error exit\n", __func__));
+-		err = -1;
+-	}
+-
+-	/* Check for broadcast ssid */
+-	for (k = 0; k < nssid; k++) {
+-		if (!ssids_local[k].SSID_len) {
+-			DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO "
+-				"setting\n", k));
+-			return err;
+-		}
+-	}
+-/* #define  PNO_DUMP 1 */
+-#ifdef PNO_DUMP
+-	{
+-		int j;
+-		for (j = 0; j < nssid; j++) {
+-			DHD_ERROR(("%d: scan  for  %s size =%d\n", j,
+-				   ssids_local[j].SSID,
+-				   ssids_local[j].SSID_len));
+-		}
+-	}
+-#endif				/* PNO_DUMP */
+-
+-	/* clean up everything */
+-	err = dhd_pno_clean(dhd);
+-	if (err < 0) {
+-		DHD_ERROR(("%s failed error=%d\n", __func__, err));
+-		return err;
+-	}
+-	memset(&pfn_param, 0, sizeof(pfn_param));
+-	memset(&pfn_element, 0, sizeof(pfn_element));
+-
+-	/* set pfn parameters */
+-	pfn_param.version = PFN_VERSION;
+-	pfn_param.flags = (PFN_LIST_ORDER << SORT_CRITERIA_BIT);
+-
+-	/* set up pno scan fr */
+-	if (scan_fr != 0)
+-		pfn_param.scan_freq = scan_fr;
+-
+-	bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-
+-	/* set all pfn ssid */
+-	for (i = 0; i < nssid; i++) {
+-
+-		pfn_element.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE;
+-		pfn_element.auth = WLAN_AUTH_OPEN;
+-		pfn_element.wpa_auth = WPA_AUTH_PFN_ANY;
+-		pfn_element.wsec = 0;
+-		pfn_element.infra = 1;
+-
+-		memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID,
+-		       ssids_local[i].SSID_len);
+-		pfn_element.ssid.SSID_len = ssids_local[i].SSID_len;
+-
+-		err = bcm_mkiovar("pfn_add", (char *)&pfn_element,
+-				sizeof(pfn_element), iovbuf, sizeof(iovbuf));
+-		if (err > 0) {
+-			err = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					sizeof(iovbuf));
+-			if (err < 0) {
+-				DHD_ERROR(("%s failed for i=%d error=%d\n",
+-					   __func__, i, err));
+-				return err;
+-			}
+-		} else
+-			DHD_ERROR(("%s failed err=%d\n", __func__, err));
+-	}
+-
+-	/* Enable PNO */
+-	/* dhd_pno_enable(dhd, 1); */
+-	return err;
+-}
+-
+-int dhd_pno_get_status(dhd_pub_t *dhd)
+-{
+-	int ret = -1;
+-
+-	if (!dhd)
+-		return ret;
+-	else
+-		return dhd->pno_enable;
+-}
+-
+-#endif				/* PNO_SUPPORT */
+-
+-/* Androd ComboSCAN support */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
+deleted file mode 100644
+index 1cf6c5d..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c
++++ /dev/null
+@@ -1,158 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/netdevice.h>
+-#include <bcmutils.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#include <wlioctl.h>
+-#include <wl_iw.h>
+-
+-#define WL_ERROR(fmt, args...) printk(fmt, ##args)
+-#define WL_TRACE(fmt, args...) no_printk(fmt, ##args)
+-
+-#ifdef CUSTOMER_HW
+-extern void bcm_wlan_power_off(int);
+-extern void bcm_wlan_power_on(int);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-int wifi_set_carddetect(int on);
+-int wifi_set_power(int on, unsigned long msec);
+-int wifi_get_irq_number(unsigned long *irq_flags_ptr);
+-#endif
+-
+-#if defined(OOB_INTR_ONLY)
+-
+-#if defined(BCMLXSDMMC)
+-extern int sdioh_mmc_irq(int irq);
+-#endif				/* (BCMLXSDMMC)  */
+-
+-#ifdef CUSTOMER_HW3
+-#include <mach/gpio.h>
+-#endif
+-
+-/* Customer specific Host GPIO definition  */
+-static int dhd_oob_gpio_num = -1;	/* GG 19 */
+-
+-module_param(dhd_oob_gpio_num, int, 0644);
+-MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
+-
+-int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
+-{
+-	int host_oob_irq = 0;
+-
+-#ifdef CUSTOMER_HW2
+-	host_oob_irq = wifi_get_irq_number(irq_flags_ptr);
+-
+-#else				/* for NOT  CUSTOMER_HW2 */
+-#if defined(CUSTOM_OOB_GPIO_NUM)
+-	if (dhd_oob_gpio_num < 0)
+-		dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
+-#endif
+-
+-	if (dhd_oob_gpio_num < 0) {
+-		WL_ERROR("%s: ERROR customer specific Host GPIO is NOT defined\n",
+-			 __func__);
+-		return dhd_oob_gpio_num;
+-	}
+-
+-	WL_ERROR("%s: customer specific Host GPIO number is (%d)\n",
+-		 __func__, dhd_oob_gpio_num);
+-
+-#if defined CUSTOMER_HW
+-	host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
+-#elif defined CUSTOMER_HW3
+-	gpio_request(dhd_oob_gpio_num, "oob irq");
+-	host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
+-	gpio_direction_input(dhd_oob_gpio_num);
+-#endif				/* CUSTOMER_HW */
+-#endif				/* CUSTOMER_HW2 */
+-
+-	return host_oob_irq;
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-/* Customer function to control hw specific wlan gpios */
+-void dhd_customer_gpio_wlan_ctrl(int onoff)
+-{
+-	switch (onoff) {
+-	case WLAN_RESET_OFF:
+-		WL_TRACE("%s: call customer specific GPIO to insert WLAN RESET\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_off(2);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-		wifi_set_power(0, 0);
+-#endif
+-		WL_ERROR("=========== WLAN placed in RESET ========\n");
+-		break;
+-
+-	case WLAN_RESET_ON:
+-		WL_TRACE("%s: callc customer specific GPIO to remove WLAN RESET\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_on(2);
+-#endif				/* CUSTOMER_HW */
+-#ifdef CUSTOMER_HW2
+-		wifi_set_power(1, 0);
+-#endif
+-		WL_ERROR("=========== WLAN going back to live  ========\n");
+-		break;
+-
+-	case WLAN_POWER_OFF:
+-		WL_TRACE("%s: call customer specific GPIO to turn off WL_REG_ON\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_off(1);
+-#endif				/* CUSTOMER_HW */
+-		break;
+-
+-	case WLAN_POWER_ON:
+-		WL_TRACE("%s: call customer specific GPIO to turn on WL_REG_ON\n",
+-			 __func__);
+-#ifdef CUSTOMER_HW
+-		bcm_wlan_power_on(1);
+-#endif				/* CUSTOMER_HW */
+-		/* Lets customer power to get stable */
+-		udelay(200);
+-		break;
+-	}
+-}
+-
+-#ifdef GET_CUSTOM_MAC_ENABLE
+-/* Function to get custom MAC address */
+-int dhd_custom_get_mac_address(unsigned char *buf)
+-{
+-	WL_TRACE("%s Enter\n", __func__);
+-	if (!buf)
+-		return -EINVAL;
+-
+-	/* Customer access to MAC address stored outside of DHD driver */
+-
+-#ifdef EXAMPLE_GET_MAC
+-	/* EXAMPLE code */
+-	{
+-		u8 ea_example[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF};
+-		memcpy(buf, ea_example, ETH_ALEN);
+-	}
+-#endif				/* EXAMPLE_GET_MAC */
+-
+-	return 0;
+-}
+-#endif				/* GET_CUSTOM_MAC_ENABLE */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
+deleted file mode 100644
+index 0817f13..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_dbg_
+-#define _dhd_dbg_
+-
+-#if defined(DHD_DEBUG)
+-
+-#define DHD_ERROR(args)	       \
+-	do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
+-		printk args; } while (0)
+-#define DHD_TRACE(args)		do {if (dhd_msg_level & DHD_TRACE_VAL)	\
+-					printk args; } while (0)
+-#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL)	\
+-					printk args; } while (0)
+-#define DHD_DATA(args)		do {if (dhd_msg_level & DHD_DATA_VAL)	\
+-					printk args; } while (0)
+-#define DHD_CTL(args)		do {if (dhd_msg_level & DHD_CTL_VAL)	\
+-					printk args; } while (0)
+-#define DHD_TIMER(args)		do {if (dhd_msg_level & DHD_TIMER_VAL)	\
+-					printk args; } while (0)
+-#define DHD_HDRS(args)		do {if (dhd_msg_level & DHD_HDRS_VAL)	\
+-					printk args; } while (0)
+-#define DHD_BYTES(args)		do {if (dhd_msg_level & DHD_BYTES_VAL)	\
+-					printk args; } while (0)
+-#define DHD_INTR(args)		do {if (dhd_msg_level & DHD_INTR_VAL)	\
+-					printk args; } while (0)
+-#define DHD_GLOM(args)		do {if (dhd_msg_level & DHD_GLOM_VAL)	\
+-					printk args; } while (0)
+-#define DHD_EVENT(args)		do {if (dhd_msg_level & DHD_EVENT_VAL)	\
+-					printk args; } while (0)
+-#define DHD_BTA(args)		do {if (dhd_msg_level & DHD_BTA_VAL)	\
+-					printk args; } while (0)
+-#define DHD_ISCAN(args)		do {if (dhd_msg_level & DHD_ISCAN_VAL)	\
+-					printk args; } while (0)
+-
+-#define DHD_ERROR_ON()		(dhd_msg_level & DHD_ERROR_VAL)
+-#define DHD_TRACE_ON()		(dhd_msg_level & DHD_TRACE_VAL)
+-#define DHD_INFO_ON()		(dhd_msg_level & DHD_INFO_VAL)
+-#define DHD_DATA_ON()		(dhd_msg_level & DHD_DATA_VAL)
+-#define DHD_CTL_ON()		(dhd_msg_level & DHD_CTL_VAL)
+-#define DHD_TIMER_ON()		(dhd_msg_level & DHD_TIMER_VAL)
+-#define DHD_HDRS_ON()		(dhd_msg_level & DHD_HDRS_VAL)
+-#define DHD_BYTES_ON()		(dhd_msg_level & DHD_BYTES_VAL)
+-#define DHD_INTR_ON()		(dhd_msg_level & DHD_INTR_VAL)
+-#define DHD_GLOM_ON()		(dhd_msg_level & DHD_GLOM_VAL)
+-#define DHD_EVENT_ON()		(dhd_msg_level & DHD_EVENT_VAL)
+-#define DHD_BTA_ON()		(dhd_msg_level & DHD_BTA_VAL)
+-#define DHD_ISCAN_ON()		(dhd_msg_level & DHD_ISCAN_VAL)
+-
+-#else	/* (defined BCMDBG) || (defined DHD_DEBUG) */
+-
+-#define DHD_ERROR(args)  do {if (net_ratelimit()) printk args; } while (0)
+-#define DHD_TRACE(args)
+-#define DHD_INFO(args)
+-#define DHD_DATA(args)
+-#define DHD_CTL(args)
+-#define DHD_TIMER(args)
+-#define DHD_HDRS(args)
+-#define DHD_BYTES(args)
+-#define DHD_INTR(args)
+-#define DHD_GLOM(args)
+-#define DHD_EVENT(args)
+-#define DHD_BTA(args)
+-#define DHD_ISCAN(args)
+-
+-#define DHD_ERROR_ON()		0
+-#define DHD_TRACE_ON()		0
+-#define DHD_INFO_ON()		0
+-#define DHD_DATA_ON()		0
+-#define DHD_CTL_ON()		0
+-#define DHD_TIMER_ON()		0
+-#define DHD_HDRS_ON()		0
+-#define DHD_BYTES_ON()		0
+-#define DHD_INTR_ON()		0
+-#define DHD_GLOM_ON()		0
+-#define DHD_EVENT_ON()		0
+-#define DHD_BTA_ON()		0
+-#define DHD_ISCAN_ON()		0
+-#endif				/* defined(DHD_DEBUG) */
+-
+-#define DHD_LOG(args)
+-
+-#define DHD_NONE(args)
+-extern int dhd_msg_level;
+-
+-/* Defines msg bits */
+-#include <dhdioctl.h>
+-
+-#endif				/* _dhd_dbg_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
+deleted file mode 100644
+index f356c56..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
++++ /dev/null
+@@ -1,2862 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifdef CONFIG_WIFI_CONTROL_FUNC
+-#include <linux/platform_device.h>
+-#endif
+-#include <linux/init.h>
+-#include <linux/kernel.h>
+-#include <linux/kthread.h>
+-#include <linux/slab.h>
+-#include <linux/skbuff.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/random.h>
+-#include <linux/spinlock.h>
+-#include <linux/ethtool.h>
+-#include <linux/fcntl.h>
+-#include <linux/fs.h>
+-#include <linux/uaccess.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-
+-#include <wl_cfg80211.h>
+-
+-#define EPI_VERSION_STR		"4.218.248.5"
+-#define ETH_P_BRCM			0x886c
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-#include <linux/wifi_tiwlan.h>
+-
+-struct semaphore wifi_control_sem;
+-
+-struct dhd_bus *g_bus;
+-
+-static struct wifi_platform_data *wifi_control_data;
+-static struct resource *wifi_irqres;
+-
+-int wifi_get_irq_number(unsigned long *irq_flags_ptr)
+-{
+-	if (wifi_irqres) {
+-		*irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;
+-		return (int)wifi_irqres->start;
+-	}
+-#ifdef CUSTOM_OOB_GPIO_NUM
+-	return CUSTOM_OOB_GPIO_NUM;
+-#else
+-	return -1;
+-#endif
+-}
+-
+-int wifi_set_carddetect(int on)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_carddetect)
+-		wifi_control_data->set_carddetect(on);
+-	return 0;
+-}
+-
+-int wifi_set_power(int on, unsigned long msec)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_power)
+-		wifi_control_data->set_power(on);
+-	if (msec)
+-		mdelay(msec);
+-	return 0;
+-}
+-
+-int wifi_set_reset(int on, unsigned long msec)
+-{
+-	printk(KERN_ERR "%s = %d\n", __func__, on);
+-	if (wifi_control_data && wifi_control_data->set_reset)
+-		wifi_control_data->set_reset(on);
+-	if (msec)
+-		mdelay(msec);
+-	return 0;
+-}
+-
+-static int wifi_probe(struct platform_device *pdev)
+-{
+-	struct wifi_platform_data *wifi_ctrl =
+-	    (struct wifi_platform_data *)(pdev->dev.platform_data);
+-
+-	printk(KERN_ERR "## %s\n", __func__);
+-	wifi_irqres =
+-	    platform_get_resource_byname(pdev, IORESOURCE_IRQ,
+-					 "bcm4329_wlan_irq");
+-	wifi_control_data = wifi_ctrl;
+-
+-	wifi_set_power(1, 0);	/* Power On */
+-	wifi_set_carddetect(1);	/* CardDetect (0->1) */
+-
+-	up(&wifi_control_sem);
+-	return 0;
+-}
+-
+-static int wifi_remove(struct platform_device *pdev)
+-{
+-	struct wifi_platform_data *wifi_ctrl =
+-	    (struct wifi_platform_data *)(pdev->dev.platform_data);
+-
+-	printk(KERN_ERR "## %s\n", __func__);
+-	wifi_control_data = wifi_ctrl;
+-
+-	wifi_set_carddetect(0);	/* CardDetect (1->0) */
+-	wifi_set_power(0, 0);	/* Power Off */
+-
+-	up(&wifi_control_sem);
+-	return 0;
+-}
+-
+-static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
+-{
+-	DHD_TRACE(("##> %s\n", __func__));
+-	return 0;
+-}
+-
+-static int wifi_resume(struct platform_device *pdev)
+-{
+-	DHD_TRACE(("##> %s\n", __func__));
+-	return 0;
+-}
+-
+-static struct platform_driver wifi_device = {
+-	.probe = wifi_probe,
+-	.remove = wifi_remove,
+-	.suspend = wifi_suspend,
+-	.resume = wifi_resume,
+-	.driver = {
+-		   .name = KBUILD_MODNAME,
+-		   }
+-};
+-
+-int wifi_add_dev(void)
+-{
+-	DHD_TRACE(("## Calling platform_driver_register\n"));
+-	return platform_driver_register(&wifi_device);
+-}
+-
+-void wifi_del_dev(void)
+-{
+-	DHD_TRACE(("## Unregister platform_driver_register\n"));
+-	platform_driver_unregister(&wifi_device);
+-}
+-#endif	/* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+-
+-#if defined(CONFIG_PM_SLEEP)
+-#include <linux/suspend.h>
+-atomic_t dhd_mmc_suspend;
+-DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-#if defined(OOB_INTR_ONLY)
+-extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable);
+-#endif	/* defined(OOB_INTR_ONLY) */
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-#define DRV_MODULE_NAME "brcmfmac"
+-
+-/* Linux wireless extension support */
+-#if defined(CONFIG_WIRELESS_EXT)
+-#include <wl_iw.h>
+-extern wl_iw_extra_params_t g_wl_iw_params;
+-#endif		/* defined(CONFIG_WIRELESS_EXT) */
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-#include <linux/earlysuspend.h>
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-#endif		/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-#ifdef PKT_FILTER_SUPPORT
+-extern void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg);
+-extern void dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable,
+-					 int master_mode);
+-#endif
+-
+-/* Interface control information */
+-typedef struct dhd_if {
+-	struct dhd_info *info;	/* back pointer to dhd_info */
+-	/* OS/stack specifics */
+-	struct net_device *net;
+-	struct net_device_stats stats;
+-	int idx;		/* iface idx in dongle */
+-	int state;		/* interface state */
+-	uint subunit;		/* subunit */
+-	u8 mac_addr[ETH_ALEN];	/* assigned MAC address */
+-	bool attached;		/* Delayed attachment when unset */
+-	bool txflowcontrol;	/* Per interface flow control indicator */
+-	char name[IFNAMSIZ];	/* linux interface name */
+-} dhd_if_t;
+-
+-/* Local private structure (extension of pub) */
+-typedef struct dhd_info {
+-#if defined(CONFIG_WIRELESS_EXT)
+-	wl_iw_t iw;		/* wireless extensions state (must be first) */
+-#endif				/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	dhd_pub_t pub;
+-
+-	/* OS/stack specifics */
+-	dhd_if_t *iflist[DHD_MAX_IFS];
+-
+-	struct semaphore proto_sem;
+-	wait_queue_head_t ioctl_resp_wait;
+-	struct timer_list timer;
+-	bool wd_timer_valid;
+-	struct tasklet_struct tasklet;
+-	spinlock_t sdlock;
+-	spinlock_t txqlock;
+-	/* Thread based operation */
+-	bool threads_only;
+-	struct semaphore sdsem;
+-	struct task_struct *watchdog_tsk;
+-	struct semaphore watchdog_sem;
+-	struct task_struct *dpc_tsk;
+-	struct semaphore dpc_sem;
+-
+-	/* Thread to issue ioctl for multicast */
+-	struct task_struct *sysioc_tsk;
+-	struct semaphore sysioc_sem;
+-	bool set_multicast;
+-	bool set_macaddress;
+-	u8 macvalue[ETH_ALEN];
+-	wait_queue_head_t ctrl_wait;
+-	atomic_t pend_8021x_cnt;
+-
+-#ifdef CONFIG_HAS_EARLYSUSPEND
+-	struct early_suspend early_suspend;
+-#endif				/* CONFIG_HAS_EARLYSUSPEND */
+-} dhd_info_t;
+-
+-/* Definitions to provide path to the firmware and nvram
+- * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt"
+- */
+-char firmware_path[MOD_PARAM_PATHLEN];
+-char nvram_path[MOD_PARAM_PATHLEN];
+-
+-/* load firmware and/or nvram values from the filesystem */
+-module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0);
+-module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0);
+-
+-/* Error bits */
+-module_param(dhd_msg_level, int, 0);
+-
+-/* Spawn a thread for system ioctls (set mac, set mcast) */
+-uint dhd_sysioc = true;
+-module_param(dhd_sysioc, uint, 0);
+-
+-/* Watchdog interval */
+-uint dhd_watchdog_ms = 10;
+-module_param(dhd_watchdog_ms, uint, 0);
+-
+-#ifdef DHD_DEBUG
+-/* Console poll interval */
+-uint dhd_console_ms;
+-module_param(dhd_console_ms, uint, 0);
+-#endif				/* DHD_DEBUG */
+-
+-/* ARP offload agent mode : Enable ARP Host Auto-Reply
+-and ARP Peer Auto-Reply */
+-uint dhd_arp_mode = 0xb;
+-module_param(dhd_arp_mode, uint, 0);
+-
+-/* ARP offload enable */
+-uint dhd_arp_enable = true;
+-module_param(dhd_arp_enable, uint, 0);
+-
+-/* Global Pkt filter enable control */
+-uint dhd_pkt_filter_enable = true;
+-module_param(dhd_pkt_filter_enable, uint, 0);
+-
+-/*  Pkt filter init setup */
+-uint dhd_pkt_filter_init;
+-module_param(dhd_pkt_filter_init, uint, 0);
+-
+-/* Pkt filter mode control */
+-uint dhd_master_mode = true;
+-module_param(dhd_master_mode, uint, 1);
+-
+-/* Watchdog thread priority, -1 to use kernel timer */
+-int dhd_watchdog_prio = 97;
+-module_param(dhd_watchdog_prio, int, 0);
+-
+-/* DPC thread priority, -1 to use tasklet */
+-int dhd_dpc_prio = 98;
+-module_param(dhd_dpc_prio, int, 0);
+-
+-/* DPC thread priority, -1 to use tasklet */
+-extern int dhd_dongle_memsize;
+-module_param(dhd_dongle_memsize, int, 0);
+-
+-/* Contorl fw roaming */
+-#ifdef CUSTOMER_HW2
+-uint dhd_roam;
+-#else
+-uint dhd_roam = 1;
+-#endif
+-
+-/* Control radio state */
+-uint dhd_radio_up = 1;
+-
+-/* Network inteface name */
+-char iface_name[IFNAMSIZ] = "wlan";
+-module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
+-
+-/* The following are specific to the SDIO dongle */
+-
+-/* IOCTL response timeout */
+-int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
+-
+-/* Idle timeout for backplane clock */
+-int dhd_idletime = DHD_IDLETIME_TICKS;
+-module_param(dhd_idletime, int, 0);
+-
+-/* Use polling */
+-uint dhd_poll = false;
+-module_param(dhd_poll, uint, 0);
+-
+-/* Use cfg80211 */
+-uint dhd_cfg80211 = true;
+-module_param(dhd_cfg80211, uint, 0);
+-
+-/* Use interrupts */
+-uint dhd_intr = true;
+-module_param(dhd_intr, uint, 0);
+-
+-/* SDIO Drive Strength (in milliamps) */
+-uint dhd_sdiod_drive_strength = 6;
+-module_param(dhd_sdiod_drive_strength, uint, 0);
+-
+-/* Tx/Rx bounds */
+-extern uint dhd_txbound;
+-extern uint dhd_rxbound;
+-module_param(dhd_txbound, uint, 0);
+-module_param(dhd_rxbound, uint, 0);
+-
+-/* Deferred transmits */
+-extern uint dhd_deferred_tx;
+-module_param(dhd_deferred_tx, uint, 0);
+-
+-#ifdef SDTEST
+-/* Echo packet generator (pkts/s) */
+-uint dhd_pktgen;
+-module_param(dhd_pktgen, uint, 0);
+-
+-/* Echo packet len (0 => sawtooth, max 2040) */
+-uint dhd_pktgen_len;
+-module_param(dhd_pktgen_len, uint, 0);
+-#endif
+-
+-#define FAVORITE_WIFI_CP	(!!dhd_cfg80211)
+-#define IS_CFG80211_FAVORITE() FAVORITE_WIFI_CP
+-#define DBG_CFG80211_GET() ((dhd_cfg80211 & WL_DBG_MASK) >> 1)
+-#define NO_FW_REQ() (dhd_cfg80211 & 0x80)
+-
+-/* Version string to report */
+-#ifdef DHD_DEBUG
+-#define DHD_COMPILED "\nCompiled in " SRCBASE
+-#else
+-#define DHD_COMPILED
+-#endif
+-
+-static void dhd_dpc(unsigned long data);
+-/* forward decl */
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-
+-#ifdef TOE
+-#ifndef BDC
+-#error TOE requires BDC
+-#endif				/* !BDC */
+-static int dhd_toe_get(dhd_info_t *dhd, int idx, u32 *toe_ol);
+-static int dhd_toe_set(dhd_info_t *dhd, int idx, u32 toe_ol);
+-#endif				/* TOE */
+-
+-static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+-			     wl_event_msg_t *event_ptr, void **data_ptr);
+-
+-#if defined(CONFIG_PM_SLEEP)
+-static int dhd_sleep_pm_callback(struct notifier_block *nfb,
+-				 unsigned long action, void *ignored)
+-{
+-	switch (action) {
+-	case PM_HIBERNATION_PREPARE:
+-	case PM_SUSPEND_PREPARE:
+-		atomic_set(&dhd_mmc_suspend, true);
+-		return NOTIFY_OK;
+-	case PM_POST_HIBERNATION:
+-	case PM_POST_SUSPEND:
+-		atomic_set(&dhd_mmc_suspend, false);
+-		return NOTIFY_OK;
+-	}
+-	return 0;
+-}
+-
+-static struct notifier_block dhd_sleep_pm_notifier = {
+-	.notifier_call = dhd_sleep_pm_callback,
+-	.priority = 0
+-};
+-
+-extern int register_pm_notifier(struct notifier_block *nb);
+-extern int unregister_pm_notifier(struct notifier_block *nb);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-	/* && defined(DHD_GPL) */
+-static void dhd_set_packet_filter(int value, dhd_pub_t *dhd)
+-{
+-#ifdef PKT_FILTER_SUPPORT
+-	DHD_TRACE(("%s: %d\n", __func__, value));
+-	/* 1 - Enable packet filter, only allow unicast packet to send up */
+-	/* 0 - Disable packet filter */
+-	if (dhd_pkt_filter_enable) {
+-		int i;
+-
+-		for (i = 0; i < dhd->pktfilter_count; i++) {
+-			dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+-			dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+-						     value, dhd_master_mode);
+-		}
+-	}
+-#endif
+-}
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-static int dhd_set_suspend(int value, dhd_pub_t *dhd)
+-{
+-	int power_mode = PM_MAX;
+-	/* wl_pkt_filter_enable_t       enable_parm; */
+-	char iovbuf[32];
+-	int bcn_li_dtim = 3;
+-#ifdef CUSTOMER_HW2
+-	uint roamvar = 1;
+-#endif				/* CUSTOMER_HW2 */
+-
+-	DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n",
+-		   __func__, value, dhd->in_suspend));
+-
+-	if (dhd && dhd->up) {
+-		if (value && dhd->in_suspend) {
+-
+-			/* Kernel suspended */
+-			DHD_TRACE(("%s: force extra Suspend setting\n",
+-				   __func__));
+-
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
+-					 (char *)&power_mode,
+-					 sizeof(power_mode));
+-
+-			/* Enable packet filter, only allow unicast
+-				 packet to send up */
+-			dhd_set_packet_filter(1, dhd);
+-
+-			/* if dtim skip setup as default force it
+-			 * to wake each third dtim
+-			 * for better power saving.
+-			 * Note that side effect is chance to miss BC/MC
+-			 * packet
+-			 */
+-			if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
+-				bcn_li_dtim = 3;
+-			else
+-				bcn_li_dtim = dhd->dtim_skip;
+-			bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
+-				    4, iovbuf, sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#ifdef CUSTOMER_HW2
+-			/* Disable build-in roaming to allowed \
+-			 * supplicant to take of romaing
+-			 */
+-			bcm_mkiovar("roam_off", (char *)&roamvar, 4,
+-				    iovbuf, sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#endif				/* CUSTOMER_HW2 */
+-		} else {
+-
+-			/* Kernel resumed  */
+-			DHD_TRACE(("%s: Remove extra suspend setting\n",
+-				   __func__));
+-
+-			power_mode = PM_FAST;
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
+-					 (char *)&power_mode,
+-					 sizeof(power_mode));
+-
+-			/* disable pkt filter */
+-			dhd_set_packet_filter(0, dhd);
+-
+-			/* restore pre-suspend setting for dtim_skip */
+-			bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip,
+-				    4, iovbuf, sizeof(iovbuf));
+-
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#ifdef CUSTOMER_HW2
+-			roamvar = 0;
+-			bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf,
+-				    sizeof(iovbuf));
+-			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf,
+-					 sizeof(iovbuf));
+-#endif				/* CUSTOMER_HW2 */
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static void dhd_suspend_resume_helper(struct dhd_info *dhd, int val)
+-{
+-	dhd_pub_t *dhdp = &dhd->pub;
+-
+-	dhd_os_proto_block(dhdp);
+-	/* Set flag when early suspend was called */
+-	dhdp->in_suspend = val;
+-	if (!dhdp->suspend_disable_flag)
+-		dhd_set_suspend(val, dhdp);
+-	dhd_os_proto_unblock(dhdp);
+-}
+-
+-static void dhd_early_suspend(struct early_suspend *h)
+-{
+-	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+-
+-	DHD_TRACE(("%s: enter\n", __func__));
+-
+-	if (dhd)
+-		dhd_suspend_resume_helper(dhd, 1);
+-
+-}
+-
+-static void dhd_late_resume(struct early_suspend *h)
+-{
+-	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+-
+-	DHD_TRACE(("%s: enter\n", __func__));
+-
+-	if (dhd)
+-		dhd_suspend_resume_helper(dhd, 0);
+-}
+-#endif				/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-/*
+- * Generalized timeout mechanism.  Uses spin sleep with exponential
+- * back-off until
+- * the sleep time reaches one jiffy, then switches over to task delay.  Usage:
+- *
+- *      dhd_timeout_start(&tmo, usec);
+- *      while (!dhd_timeout_expired(&tmo))
+- *              if (poll_something())
+- *                      break;
+- *      if (dhd_timeout_expired(&tmo))
+- *              fatal();
+- */
+-
+-void dhd_timeout_start(dhd_timeout_t *tmo, uint usec)
+-{
+-	tmo->limit = usec;
+-	tmo->increment = 0;
+-	tmo->elapsed = 0;
+-	tmo->tick = 1000000 / HZ;
+-}
+-
+-int dhd_timeout_expired(dhd_timeout_t *tmo)
+-{
+-	/* Does nothing the first call */
+-	if (tmo->increment == 0) {
+-		tmo->increment = 1;
+-		return 0;
+-	}
+-
+-	if (tmo->elapsed >= tmo->limit)
+-		return 1;
+-
+-	/* Add the delay that's about to take place */
+-	tmo->elapsed += tmo->increment;
+-
+-	if (tmo->increment < tmo->tick) {
+-		udelay(tmo->increment);
+-		tmo->increment *= 2;
+-		if (tmo->increment > tmo->tick)
+-			tmo->increment = tmo->tick;
+-	} else {
+-		wait_queue_head_t delay_wait;
+-		DECLARE_WAITQUEUE(wait, current);
+-		int pending;
+-		init_waitqueue_head(&delay_wait);
+-		add_wait_queue(&delay_wait, &wait);
+-		set_current_state(TASK_INTERRUPTIBLE);
+-		schedule_timeout(1);
+-		pending = signal_pending(current);
+-		remove_wait_queue(&delay_wait, &wait);
+-		set_current_state(TASK_RUNNING);
+-		if (pending)
+-			return 1;	/* Interrupted */
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
+-{
+-	int i = 0;
+-
+-	ASSERT(dhd);
+-	while (i < DHD_MAX_IFS) {
+-		if (dhd->iflist[i] && (dhd->iflist[i]->net == net))
+-			return i;
+-		i++;
+-	}
+-
+-	return DHD_BAD_IF;
+-}
+-
+-int dhd_ifname2idx(dhd_info_t *dhd, char *name)
+-{
+-	int i = DHD_MAX_IFS;
+-
+-	ASSERT(dhd);
+-
+-	if (name == NULL || *name == '\0')
+-		return 0;
+-
+-	while (--i > 0)
+-		if (dhd->iflist[i]
+-		    && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ))
+-			break;
+-
+-	DHD_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name));
+-
+-	return i;		/* default - the primary interface */
+-}
+-
+-char *dhd_ifname(dhd_pub_t *dhdp, int ifidx)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-
+-	ASSERT(dhd);
+-
+-	if (ifidx < 0 || ifidx >= DHD_MAX_IFS) {
+-		DHD_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx));
+-		return "<if_bad>";
+-	}
+-
+-	if (dhd->iflist[ifidx] == NULL) {
+-		DHD_ERROR(("%s: null i/f %d\n", __func__, ifidx));
+-		return "<if_null>";
+-	}
+-
+-	if (dhd->iflist[ifidx]->net)
+-		return dhd->iflist[ifidx]->net->name;
+-
+-	return "<if_none>";
+-}
+-
+-static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
+-{
+-	struct net_device *dev;
+-	struct netdev_hw_addr *ha;
+-	u32 allmulti, cnt;
+-
+-	wl_ioctl_t ioc;
+-	char *buf, *bufp;
+-	uint buflen;
+-	int ret;
+-
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-	dev = dhd->iflist[ifidx]->net;
+-	cnt = netdev_mc_count(dev);
+-
+-	/* Determine initial value of allmulti flag */
+-	allmulti = (dev->flags & IFF_ALLMULTI) ? true : false;
+-
+-	/* Send down the multicast list first. */
+-
+-	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
+-	bufp = buf = kmalloc(buflen, GFP_ATOMIC);
+-	if (!bufp) {
+-		DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), cnt));
+-		return;
+-	}
+-
+-	strcpy(bufp, "mcast_list");
+-	bufp += strlen("mcast_list") + 1;
+-
+-	cnt = cpu_to_le32(cnt);
+-	memcpy(bufp, &cnt, sizeof(cnt));
+-	bufp += sizeof(cnt);
+-
+-	netdev_for_each_mc_addr(ha, dev) {
+-		if (!cnt)
+-			break;
+-		memcpy(bufp, ha->addr, ETH_ALEN);
+-		bufp += ETH_ALEN;
+-		cnt--;
+-	}
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = buflen;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set mcast_list failed, cnt %d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), cnt));
+-		allmulti = cnt ? true : allmulti;
+-	}
+-
+-	kfree(buf);
+-
+-	/* Now send the allmulti setting.  This is based on the setting in the
+-	 * net_device flags, but might be modified above to be turned on if we
+-	 * were trying to set some addresses and dongle rejected it...
+-	 */
+-
+-	buflen = sizeof("allmulti") + sizeof(allmulti);
+-	buf = kmalloc(buflen, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: out of memory for allmulti\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		return;
+-	}
+-	allmulti = cpu_to_le32(allmulti);
+-
+-	if (!bcm_mkiovar
+-	    ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) {
+-		DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d "
+-			"buflen %u\n", dhd_ifname(&dhd->pub, ifidx),
+-			(int)sizeof(allmulti), buflen));
+-		kfree(buf);
+-		return;
+-	}
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = buflen;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set allmulti %d failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx),
+-			   le32_to_cpu(allmulti)));
+-	}
+-
+-	kfree(buf);
+-
+-	/* Finally, pick up the PROMISC flag as well, like the NIC
+-		 driver does */
+-
+-	allmulti = (dev->flags & IFF_PROMISC) ? true : false;
+-	allmulti = cpu_to_le32(allmulti);
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_PROMISC;
+-	ioc.buf = &allmulti;
+-	ioc.len = sizeof(allmulti);
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set promisc %d failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx),
+-			   le32_to_cpu(allmulti)));
+-	}
+-}
+-
+-static int
+-_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, u8 *addr)
+-{
+-	char buf[32];
+-	wl_ioctl_t ioc;
+-	int ret;
+-
+-	DHD_TRACE(("%s enter\n", __func__));
+-	if (!bcm_mkiovar
+-	    ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) {
+-		DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		return -1;
+-	}
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = 32;
+-	ioc.set = true;
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: set cur_etheraddr failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-	} else {
+-		memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN);
+-	}
+-
+-	return ret;
+-}
+-
+-#ifdef SOFTAP
+-extern struct net_device *ap_net_dev;
+-#endif
+-
+-static void dhd_op_if(dhd_if_t *ifp)
+-{
+-	dhd_info_t *dhd;
+-	int ret = 0, err = 0;
+-
+-	ASSERT(ifp && ifp->info && ifp->idx);	/* Virtual interfaces only */
+-
+-	dhd = ifp->info;
+-
+-	DHD_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state));
+-
+-	switch (ifp->state) {
+-	case WLC_E_IF_ADD:
+-		/*
+-		 * Delete the existing interface before overwriting it
+-		 * in case we missed the WLC_E_IF_DEL event.
+-		 */
+-		if (ifp->net != NULL) {
+-			DHD_ERROR(("%s: ERROR: netdev:%s already exists, "
+-			"try free & unregister\n",
+-			__func__, ifp->net->name));
+-			netif_stop_queue(ifp->net);
+-			unregister_netdev(ifp->net);
+-			free_netdev(ifp->net);
+-		}
+-		/* Allocate etherdev, including space for private structure */
+-		ifp->net = alloc_etherdev(sizeof(dhd));
+-		if (!ifp->net) {
+-			DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
+-			ret = -ENOMEM;
+-		}
+-		if (ret == 0) {
+-			strcpy(ifp->net->name, ifp->name);
+-			memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
+-			err = dhd_net_attach(&dhd->pub, ifp->idx);
+-			if (err != 0) {
+-				DHD_ERROR(("%s: dhd_net_attach failed, "
+-					"err %d\n",
+-					__func__, err));
+-				ret = -EOPNOTSUPP;
+-			} else {
+-#ifdef SOFTAP
+-				/* semaphore that the soft AP CODE
+-					 waits on */
+-				extern struct semaphore ap_eth_sema;
+-
+-				/* save ptr to wl0.1 netdev for use
+-					 in wl_iw.c  */
+-				ap_net_dev = ifp->net;
+-				/* signal to the SOFTAP 'sleeper' thread,
+-					 wl0.1 is ready */
+-				up(&ap_eth_sema);
+-#endif
+-				DHD_TRACE(("\n ==== pid:%x, net_device for "
+-					"if:%s created ===\n\n",
+-					current->pid, ifp->net->name));
+-				ifp->state = 0;
+-			}
+-		}
+-		break;
+-	case WLC_E_IF_DEL:
+-		if (ifp->net != NULL) {
+-			DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n",
+-				   __func__));
+-			netif_stop_queue(ifp->net);
+-			unregister_netdev(ifp->net);
+-			ret = DHD_DEL_IF;	/* Make sure the free_netdev()
+-							 is called */
+-		}
+-		break;
+-	default:
+-		DHD_ERROR(("%s: bad op %d\n", __func__, ifp->state));
+-		ASSERT(!ifp->state);
+-		break;
+-	}
+-
+-	if (ret < 0) {
+-		if (ifp->net)
+-			free_netdev(ifp->net);
+-
+-		dhd->iflist[ifp->idx] = NULL;
+-		kfree(ifp);
+-#ifdef SOFTAP
+-		if (ifp->net == ap_net_dev)
+-			ap_net_dev = NULL;	/*  NULL  SOFTAP global
+-							 wl0.1 as well */
+-#endif				/*  SOFTAP */
+-	}
+-}
+-
+-static int _dhd_sysioc_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-	int i;
+-#ifdef SOFTAP
+-	bool in_ap = false;
+-#endif
+-
+-	allow_signal(SIGTERM);
+-
+-	while (down_interruptible(&dhd->sysioc_sem) == 0) {
+-		if (kthread_should_stop())
+-			break;
+-		for (i = 0; i < DHD_MAX_IFS; i++) {
+-			if (dhd->iflist[i]) {
+-#ifdef SOFTAP
+-				in_ap = (ap_net_dev != NULL);
+-#endif				/* SOFTAP */
+-				if (dhd->iflist[i]->state)
+-					dhd_op_if(dhd->iflist[i]);
+-#ifdef SOFTAP
+-				if (dhd->iflist[i] == NULL) {
+-					DHD_TRACE(("\n\n %s: interface %d "
+-						"removed!\n", __func__, i));
+-					continue;
+-				}
+-
+-				if (in_ap && dhd->set_macaddress) {
+-					DHD_TRACE(("attempt to set MAC for %s "
+-						"in AP Mode," "blocked. \n",
+-						dhd->iflist[i]->net->name));
+-					dhd->set_macaddress = false;
+-					continue;
+-				}
+-
+-				if (in_ap && dhd->set_multicast) {
+-					DHD_TRACE(("attempt to set MULTICAST list for %s" "in AP Mode, blocked. \n",
+-						dhd->iflist[i]->net->name));
+-					dhd->set_multicast = false;
+-					continue;
+-				}
+-#endif				/* SOFTAP */
+-				if (dhd->set_multicast) {
+-					dhd->set_multicast = false;
+-					_dhd_set_multicast_list(dhd, i);
+-				}
+-				if (dhd->set_macaddress) {
+-					dhd->set_macaddress = false;
+-					_dhd_set_mac_address(dhd, i,
+-							     dhd->macvalue);
+-				}
+-			}
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int dhd_set_mac_address(struct net_device *dev, void *addr)
+-{
+-	int ret = 0;
+-
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	struct sockaddr *sa = (struct sockaddr *)addr;
+-	int ifidx;
+-
+-	ifidx = dhd_net2idx(dhd, dev);
+-	if (ifidx == DHD_BAD_IF)
+-		return -1;
+-
+-	ASSERT(dhd->sysioc_tsk);
+-	memcpy(&dhd->macvalue, sa->sa_data, ETH_ALEN);
+-	dhd->set_macaddress = true;
+-	up(&dhd->sysioc_sem);
+-
+-	return ret;
+-}
+-
+-static void dhd_set_multicast_list(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	int ifidx;
+-
+-	ifidx = dhd_net2idx(dhd, dev);
+-	if (ifidx == DHD_BAD_IF)
+-		return;
+-
+-	ASSERT(dhd->sysioc_tsk);
+-	dhd->set_multicast = true;
+-	up(&dhd->sysioc_sem);
+-}
+-
+-int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf)
+-{
+-	int ret;
+-	dhd_info_t *dhd = (dhd_info_t *) (dhdp->info);
+-
+-	/* Reject if down */
+-	if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN))
+-		return -ENODEV;
+-
+-	/* Update multicast statistic */
+-	if (pktbuf->len >= ETH_ALEN) {
+-		u8 *pktdata = (u8 *) (pktbuf->data);
+-		struct ethhdr *eh = (struct ethhdr *)pktdata;
+-
+-		if (is_multicast_ether_addr(eh->h_dest))
+-			dhdp->tx_multicast++;
+-		if (ntohs(eh->h_proto) == ETH_P_PAE)
+-			atomic_inc(&dhd->pend_8021x_cnt);
+-	}
+-
+-	/* If the protocol uses a data header, apply it */
+-	dhd_prot_hdrpush(dhdp, ifidx, pktbuf);
+-
+-	/* Use bus module to send data frame */
+-#ifdef BCMDBUS
+-	ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */);
+-#else
+-	ret = dhd_bus_txdata(dhdp->bus, pktbuf);
+-#endif				/* BCMDBUS */
+-
+-	return ret;
+-}
+-
+-static inline void *
+-osl_pkt_frmnative(struct sk_buff *skb)
+-{
+-	return (void *)skb;
+-}
+-#define PKTFRMNATIVE(osh, skb)	\
+-	osl_pkt_frmnative((struct sk_buff *)(skb))
+-
+-static inline struct sk_buff *
+-osl_pkt_tonative(void *pkt)
+-{
+-	return (struct sk_buff *)pkt;
+-}
+-#define PKTTONATIVE(osh, pkt)	\
+-	osl_pkt_tonative((pkt))
+-
+-static int dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
+-{
+-	int ret;
+-	void *pktbuf;
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	int ifidx;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Reject if down */
+-	if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) {
+-		DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n",
+-			   __func__, dhd->pub.up, dhd->pub.busstate));
+-		netif_stop_queue(net);
+-		return -ENODEV;
+-	}
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	if (ifidx == DHD_BAD_IF) {
+-		DHD_ERROR(("%s: bad ifidx %d\n", __func__, ifidx));
+-		netif_stop_queue(net);
+-		return -ENODEV;
+-	}
+-
+-	/* Make sure there's enough room for any header */
+-	if (skb_headroom(skb) < dhd->pub.hdrlen) {
+-		struct sk_buff *skb2;
+-
+-		DHD_INFO(("%s: insufficient headroom\n",
+-			  dhd_ifname(&dhd->pub, ifidx)));
+-		dhd->pub.tx_realloc++;
+-		skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen);
+-		dev_kfree_skb(skb);
+-		skb = skb2;
+-		if (skb == NULL) {
+-			DHD_ERROR(("%s: skb_realloc_headroom failed\n",
+-				   dhd_ifname(&dhd->pub, ifidx)));
+-			ret = -ENOMEM;
+-			goto done;
+-		}
+-	}
+-
+-	/* Convert to packet */
+-	pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb);
+-	if (!pktbuf) {
+-		DHD_ERROR(("%s: PKTFRMNATIVE failed\n",
+-			   dhd_ifname(&dhd->pub, ifidx)));
+-		dev_kfree_skb_any(skb);
+-		ret = -ENOMEM;
+-		goto done;
+-	}
+-
+-	ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf);
+-
+-done:
+-	if (ret)
+-		dhd->pub.dstats.tx_dropped++;
+-	else
+-		dhd->pub.tx_packets++;
+-
+-	/* Return ok: we always eat the packet */
+-	return 0;
+-}
+-
+-void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state)
+-{
+-	struct net_device *net;
+-	dhd_info_t *dhd = dhdp->info;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhdp->txoff = state;
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-	net = dhd->iflist[ifidx]->net;
+-	if (state == ON)
+-		netif_stop_queue(net);
+-	else
+-		netif_wake_queue(net);
+-}
+-
+-void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf,
+-		  int numpkt)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-	struct sk_buff *skb;
+-	unsigned char *eth;
+-	uint len;
+-	void *data;
+-	struct sk_buff *pnext, *save_pktbuf;
+-	int i;
+-	dhd_if_t *ifp;
+-	wl_event_msg_t event;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	save_pktbuf = pktbuf;
+-
+-	for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) {
+-
+-		pnext = pktbuf->next;
+-		pktbuf->next = NULL;
+-
+-		skb = PKTTONATIVE(dhdp->osh, pktbuf);
+-
+-		/* Get the protocol, maintain skb around eth_type_trans()
+-		 * The main reason for this hack is for the limitation of
+-		 * Linux 2.4 where 'eth_type_trans' uses the
+-		 * 'net->hard_header_len'
+-		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
+-		 * coping of the packet coming from the network stack to add
+-		 * BDC, Hardware header etc, during network interface
+-		 * registration
+-		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
+-		 * required
+-		 * for BDC, Hardware header etc. and not just the ETH_HLEN
+-		 */
+-		eth = skb->data;
+-		len = skb->len;
+-
+-		ifp = dhd->iflist[ifidx];
+-		if (ifp == NULL)
+-			ifp = dhd->iflist[0];
+-
+-		ASSERT(ifp);
+-		skb->dev = ifp->net;
+-		skb->protocol = eth_type_trans(skb, skb->dev);
+-
+-		if (skb->pkt_type == PACKET_MULTICAST)
+-			dhd->pub.rx_multicast++;
+-
+-		skb->data = eth;
+-		skb->len = len;
+-
+-		/* Strip header, count, deliver upward */
+-		skb_pull(skb, ETH_HLEN);
+-
+-		/* Process special event packets and then discard them */
+-		if (ntohs(skb->protocol) == ETH_P_BRCM)
+-			dhd_wl_host_event(dhd, &ifidx,
+-					  skb_mac_header(skb),
+-					  &event, &data);
+-
+-		ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
+-		if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state)
+-			ifp = dhd->iflist[ifidx];
+-
+-		if (ifp->net)
+-			ifp->net->last_rx = jiffies;
+-
+-		dhdp->dstats.rx_bytes += skb->len;
+-		dhdp->rx_packets++;	/* Local count */
+-
+-		if (in_interrupt()) {
+-			netif_rx(skb);
+-		} else {
+-			/* If the receive is not processed inside an ISR,
+-			 * the softirqd must be woken explicitly to service
+-			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
+-			 * by netif_rx_ni(), but in earlier kernels, we need
+-			 * to do it manually.
+-			 */
+-			netif_rx_ni(skb);
+-		}
+-	}
+-}
+-
+-void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx)
+-{
+-	/* Linux version has nothing to do */
+-	return;
+-}
+-
+-void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success)
+-{
+-	uint ifidx;
+-	dhd_info_t *dhd = (dhd_info_t *) (dhdp->info);
+-	struct ethhdr *eh;
+-	u16 type;
+-
+-	dhd_prot_hdrpull(dhdp, &ifidx, txp);
+-
+-	eh = (struct ethhdr *)(txp->data);
+-	type = ntohs(eh->h_proto);
+-
+-	if (type == ETH_P_PAE)
+-		atomic_dec(&dhd->pend_8021x_cnt);
+-
+-}
+-
+-static struct net_device_stats *dhd_get_stats(struct net_device *net)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	dhd_if_t *ifp;
+-	int ifidx;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	if (ifidx == DHD_BAD_IF)
+-		return NULL;
+-
+-	ifp = dhd->iflist[ifidx];
+-	ASSERT(dhd && ifp);
+-
+-	if (dhd->pub.up) {
+-		/* Use the protocol to get dongle stats */
+-		dhd_prot_dstats(&dhd->pub);
+-	}
+-
+-	/* Copy dongle stats to net device stats */
+-	ifp->stats.rx_packets = dhd->pub.dstats.rx_packets;
+-	ifp->stats.tx_packets = dhd->pub.dstats.tx_packets;
+-	ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes;
+-	ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes;
+-	ifp->stats.rx_errors = dhd->pub.dstats.rx_errors;
+-	ifp->stats.tx_errors = dhd->pub.dstats.tx_errors;
+-	ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped;
+-	ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped;
+-	ifp->stats.multicast = dhd->pub.dstats.multicast;
+-
+-	return &ifp->stats;
+-}
+-
+-static int dhd_watchdog_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	/* This thread doesn't need any user-level access,
+-	 * so get rid of all our resources
+-	 */
+-#ifdef DHD_SCHED
+-	if (dhd_watchdog_prio > 0) {
+-		struct sched_param param;
+-		param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO) ?
+-		    dhd_watchdog_prio : (MAX_RT_PRIO - 1);
+-		setScheduler(current, SCHED_FIFO, &param);
+-	}
+-#endif				/* DHD_SCHED */
+-
+-	allow_signal(SIGTERM);
+-	/* Run until signal received */
+-	while (1) {
+-		if (kthread_should_stop())
+-			break;
+-		if (down_interruptible(&dhd->watchdog_sem) == 0) {
+-			if (dhd->pub.dongle_reset == false) {
+-				/* Call the bus module watchdog */
+-				dhd_bus_watchdog(&dhd->pub);
+-			}
+-			/* Count the tick for reference */
+-			dhd->pub.tickcnt++;
+-		} else
+-			break;
+-	}
+-	return 0;
+-}
+-
+-static void dhd_watchdog(unsigned long data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	if (dhd->watchdog_tsk) {
+-		up(&dhd->watchdog_sem);
+-
+-		/* Reschedule the watchdog */
+-		if (dhd->wd_timer_valid) {
+-			mod_timer(&dhd->timer,
+-				  jiffies + dhd_watchdog_ms * HZ / 1000);
+-		}
+-		return;
+-	}
+-
+-	/* Call the bus module watchdog */
+-	dhd_bus_watchdog(&dhd->pub);
+-
+-	/* Count the tick for reference */
+-	dhd->pub.tickcnt++;
+-
+-	/* Reschedule the watchdog */
+-	if (dhd->wd_timer_valid)
+-		mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+-}
+-
+-static int dhd_dpc_thread(void *data)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) data;
+-
+-	/* This thread doesn't need any user-level access,
+-	 * so get rid of all our resources
+-	 */
+-#ifdef DHD_SCHED
+-	if (dhd_dpc_prio > 0) {
+-		struct sched_param param;
+-		param.sched_priority =
+-		    (dhd_dpc_prio <
+-		     MAX_RT_PRIO) ? dhd_dpc_prio : (MAX_RT_PRIO - 1);
+-		setScheduler(current, SCHED_FIFO, &param);
+-	}
+-#endif				/* DHD_SCHED */
+-
+-	allow_signal(SIGTERM);
+-	/* Run until signal received */
+-	while (1) {
+-		if (kthread_should_stop())
+-			break;
+-		if (down_interruptible(&dhd->dpc_sem) == 0) {
+-			/* Call bus dpc unless it indicated down
+-				 (then clean stop) */
+-			if (dhd->pub.busstate != DHD_BUS_DOWN) {
+-				if (dhd_bus_dpc(dhd->pub.bus)) {
+-					up(&dhd->dpc_sem);
+-				}
+-			} else {
+-				dhd_bus_stop(dhd->pub.bus, true);
+-			}
+-		} else
+-			break;
+-	}
+-	return 0;
+-}
+-
+-static void dhd_dpc(unsigned long data)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) data;
+-
+-	/* Call bus dpc unless it indicated down (then clean stop) */
+-	if (dhd->pub.busstate != DHD_BUS_DOWN) {
+-		if (dhd_bus_dpc(dhd->pub.bus))
+-			tasklet_schedule(&dhd->tasklet);
+-	} else {
+-		dhd_bus_stop(dhd->pub.bus, true);
+-	}
+-}
+-
+-void dhd_sched_dpc(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-
+-	if (dhd->dpc_tsk) {
+-		up(&dhd->dpc_sem);
+-		return;
+-	}
+-
+-	tasklet_schedule(&dhd->tasklet);
+-}
+-
+-#ifdef TOE
+-/* Retrieve current toe component enables, which are kept
+-	 as a bitmap in toe_ol iovar */
+-static int dhd_toe_get(dhd_info_t *dhd, int ifidx, u32 *toe_ol)
+-{
+-	wl_ioctl_t ioc;
+-	char buf[32];
+-	int ret;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = WLC_GET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = (uint) sizeof(buf);
+-	ioc.set = false;
+-
+-	strcpy(buf, "toe_ol");
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		/* Check for older dongle image that doesn't support toe_ol */
+-		if (ret == -EIO) {
+-			DHD_ERROR(("%s: toe not supported by device\n",
+-				   dhd_ifname(&dhd->pub, ifidx)));
+-			return -EOPNOTSUPP;
+-		}
+-
+-		DHD_INFO(("%s: could not get toe_ol: ret=%d\n",
+-			  dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	memcpy(toe_ol, buf, sizeof(u32));
+-	return 0;
+-}
+-
+-/* Set current toe component enables in toe_ol iovar,
+-	 and set toe global enable iovar */
+-static int dhd_toe_set(dhd_info_t *dhd, int ifidx, u32 toe_ol)
+-{
+-	wl_ioctl_t ioc;
+-	char buf[32];
+-	int toe, ret;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = WLC_SET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = (uint) sizeof(buf);
+-	ioc.set = true;
+-
+-	/* Set toe_ol as requested */
+-
+-	strcpy(buf, "toe_ol");
+-	memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32));
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: could not set toe_ol: ret=%d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	/* Enable toe globally only if any components are enabled. */
+-
+-	toe = (toe_ol != 0);
+-
+-	strcpy(buf, "toe");
+-	memcpy(&buf[sizeof("toe")], &toe, sizeof(u32));
+-
+-	ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (ret < 0) {
+-		DHD_ERROR(("%s: could not set toe: ret=%d\n",
+-			   dhd_ifname(&dhd->pub, ifidx), ret));
+-		return ret;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* TOE */
+-
+-static void dhd_ethtool_get_drvinfo(struct net_device *net,
+-				    struct ethtool_drvinfo *info)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-
+-	sprintf(info->driver, DRV_MODULE_NAME);
+-	sprintf(info->version, "%lu", dhd->pub.drv_version);
+-	sprintf(info->fw_version, "%s", wl_cfg80211_get_fwname());
+-	sprintf(info->bus_info, "%s", dev_name(&wl_cfg80211_get_sdio_func()->dev));
+-}
+-
+-struct ethtool_ops dhd_ethtool_ops = {
+-	.get_drvinfo = dhd_ethtool_get_drvinfo
+-};
+-
+-static int dhd_ethtool(dhd_info_t *dhd, void *uaddr)
+-{
+-	struct ethtool_drvinfo info;
+-	char drvname[sizeof(info.driver)];
+-	u32 cmd;
+-#ifdef TOE
+-	struct ethtool_value edata;
+-	u32 toe_cmpnt, csum_dir;
+-	int ret;
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* all ethtool calls start with a cmd word */
+-	if (copy_from_user(&cmd, uaddr, sizeof(u32)))
+-		return -EFAULT;
+-
+-	switch (cmd) {
+-	case ETHTOOL_GDRVINFO:
+-		/* Copy out any request driver name */
+-		if (copy_from_user(&info, uaddr, sizeof(info)))
+-			return -EFAULT;
+-		strncpy(drvname, info.driver, sizeof(info.driver));
+-		drvname[sizeof(info.driver) - 1] = '\0';
+-
+-		/* clear struct for return */
+-		memset(&info, 0, sizeof(info));
+-		info.cmd = cmd;
+-
+-		/* if dhd requested, identify ourselves */
+-		if (strcmp(drvname, "?dhd") == 0) {
+-			sprintf(info.driver, "dhd");
+-			strcpy(info.version, EPI_VERSION_STR);
+-		}
+-
+-		/* otherwise, require dongle to be up */
+-		else if (!dhd->pub.up) {
+-			DHD_ERROR(("%s: dongle is not up\n", __func__));
+-			return -ENODEV;
+-		}
+-
+-		/* finally, report dongle driver type */
+-		else if (dhd->pub.iswl)
+-			sprintf(info.driver, "wl");
+-		else
+-			sprintf(info.driver, "xx");
+-
+-		sprintf(info.version, "%lu", dhd->pub.drv_version);
+-		if (copy_to_user(uaddr, &info, sizeof(info)))
+-			return -EFAULT;
+-		DHD_CTL(("%s: given %*s, returning %s\n", __func__,
+-			 (int)sizeof(drvname), drvname, info.driver));
+-		break;
+-
+-#ifdef TOE
+-		/* Get toe offload components from dongle */
+-	case ETHTOOL_GRXCSUM:
+-	case ETHTOOL_GTXCSUM:
+-		ret = dhd_toe_get(dhd, 0, &toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		csum_dir =
+-		    (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+-
+-		edata.cmd = cmd;
+-		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
+-
+-		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+-			return -EFAULT;
+-		break;
+-
+-		/* Set toe offload components in dongle */
+-	case ETHTOOL_SRXCSUM:
+-	case ETHTOOL_STXCSUM:
+-		if (copy_from_user(&edata, uaddr, sizeof(edata)))
+-			return -EFAULT;
+-
+-		/* Read the current settings, update and write back */
+-		ret = dhd_toe_get(dhd, 0, &toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		csum_dir =
+-		    (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+-
+-		if (edata.data != 0)
+-			toe_cmpnt |= csum_dir;
+-		else
+-			toe_cmpnt &= ~csum_dir;
+-
+-		ret = dhd_toe_set(dhd, 0, toe_cmpnt);
+-		if (ret < 0)
+-			return ret;
+-
+-		/* If setting TX checksum mode, tell Linux the new mode */
+-		if (cmd == ETHTOOL_STXCSUM) {
+-			if (edata.data)
+-				dhd->iflist[0]->net->features |=
+-				    NETIF_F_IP_CSUM;
+-			else
+-				dhd->iflist[0]->net->features &=
+-				    ~NETIF_F_IP_CSUM;
+-		}
+-
+-		break;
+-#endif				/* TOE */
+-
+-	default:
+-		return -EOPNOTSUPP;
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-	dhd_ioctl_t ioc;
+-	int bcmerror = 0;
+-	int buflen = 0;
+-	void *buf = NULL;
+-	uint driver = 0;
+-	int ifidx;
+-	bool is_set_key_cmd;
+-
+-	ifidx = dhd_net2idx(dhd, net);
+-	DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd));
+-
+-	if (ifidx == DHD_BAD_IF)
+-		return -1;
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-	/* linux wireless extensions */
+-	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+-		/* may recurse, do NOT lock */
+-		return wl_iw_ioctl(net, ifr, cmd);
+-	}
+-#endif				/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	if (cmd == SIOCETHTOOL)
+-		return dhd_ethtool(dhd, (void *)ifr->ifr_data);
+-
+-	if (cmd != SIOCDEVPRIVATE)
+-		return -EOPNOTSUPP;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	/* Copy the ioc control structure part of ioctl request */
+-	if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Copy out any buffer passed */
+-	if (ioc.buf) {
+-		buflen = min_t(int, ioc.len, DHD_IOCTL_MAXLEN);
+-		/* optimization for direct ioctl calls from kernel */
+-		/*
+-		   if (segment_eq(get_fs(), KERNEL_DS)) {
+-		   buf = ioc.buf;
+-		   } else {
+-		 */
+-		{
+-			buf = kmalloc(buflen, GFP_ATOMIC);
+-			if (!buf) {
+-				bcmerror = -ENOMEM;
+-				goto done;
+-			}
+-			if (copy_from_user(buf, ioc.buf, buflen)) {
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-		}
+-	}
+-
+-	/* To differentiate between wl and dhd read 4 more byes */
+-	if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
+-			    sizeof(uint)) != 0)) {
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	if (!capable(CAP_NET_ADMIN)) {
+-		bcmerror = -EPERM;
+-		goto done;
+-	}
+-
+-	/* check for local dhd ioctl and handle it */
+-	if (driver == DHD_IOCTL_MAGIC) {
+-		bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen);
+-		if (bcmerror)
+-			dhd->pub.bcmerror = bcmerror;
+-		goto done;
+-	}
+-
+-	/* send to dongle (must be up, and wl) */
+-	if ((dhd->pub.busstate != DHD_BUS_DATA)) {
+-		DHD_ERROR(("%s DONGLE_DOWN,__func__\n", __func__));
+-		bcmerror = -EIO;
+-		goto done;
+-	}
+-
+-	if (!dhd->pub.iswl) {
+-		bcmerror = -EIO;
+-		goto done;
+-	}
+-
+-	/* Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to
+-	 * prevent M4 encryption.
+-	 */
+-	is_set_key_cmd = ((ioc.cmd == WLC_SET_KEY) ||
+-			  ((ioc.cmd == WLC_SET_VAR) &&
+-			   !(strncmp("wsec_key", ioc.buf, 9))) ||
+-			  ((ioc.cmd == WLC_SET_VAR) &&
+-			   !(strncmp("bsscfg:wsec_key", ioc.buf, 15))));
+-	if (is_set_key_cmd)
+-		dhd_wait_pend8021x(net);
+-
+-	bcmerror =
+-	    dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
+-
+-done:
+-	if (!bcmerror && buf && ioc.buf) {
+-		if (copy_to_user(ioc.buf, buf, buflen))
+-			bcmerror = -EFAULT;
+-	}
+-
+-	kfree(buf);
+-
+-	if (bcmerror > 0)
+-		bcmerror = 0;
+-
+-	return bcmerror;
+-}
+-
+-static int dhd_stop(struct net_device *net)
+-{
+-#if !defined(IGNORE_ETH0_DOWN)
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	if (IS_CFG80211_FAVORITE()) {
+-		wl_cfg80211_down();
+-	}
+-	if (dhd->pub.up == 0)
+-		return 0;
+-
+-	/* Set state and stop OS transmissions */
+-	dhd->pub.up = 0;
+-	netif_stop_queue(net);
+-#else
+-	DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation\n",
+-		__func__));
+-#endif				/* !defined(IGNORE_ETH0_DOWN) */
+-
+-	return 0;
+-}
+-
+-static int dhd_open(struct net_device *net)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
+-#ifdef TOE
+-	u32 toe_ol;
+-#endif
+-	int ifidx = dhd_net2idx(dhd, net);
+-	s32 ret = 0;
+-
+-	DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx));
+-
+-	if (ifidx == 0) {	/* do it only for primary eth0 */
+-
+-		/* try to bring up bus */
+-		ret = dhd_bus_start(&dhd->pub);
+-		if (ret != 0) {
+-			DHD_ERROR(("%s: failed with code %d\n", __func__, ret));
+-			return -1;
+-		}
+-		atomic_set(&dhd->pend_8021x_cnt, 0);
+-
+-		memcpy(net->dev_addr, dhd->pub.mac, ETH_ALEN);
+-
+-#ifdef TOE
+-		/* Get current TOE mode from dongle */
+-		if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0
+-		    && (toe_ol & TOE_TX_CSUM_OL) != 0)
+-			dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM;
+-		else
+-			dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM;
+-#endif
+-	}
+-	/* Allow transmit calls */
+-	netif_start_queue(net);
+-	dhd->pub.up = 1;
+-	if (IS_CFG80211_FAVORITE()) {
+-		if (unlikely(wl_cfg80211_up())) {
+-			DHD_ERROR(("%s: failed to bring up cfg80211\n",
+-				   __func__));
+-			return -1;
+-		}
+-	}
+-
+-	return ret;
+-}
+-
+-int
+-dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name,
+-	   u8 *mac_addr, u32 flags, u8 bssidx)
+-{
+-	dhd_if_t *ifp;
+-
+-	DHD_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle));
+-
+-	ASSERT(dhd && (ifidx < DHD_MAX_IFS));
+-
+-	ifp = dhd->iflist[ifidx];
+-	if (!ifp && !(ifp = kmalloc(sizeof(dhd_if_t), GFP_ATOMIC))) {
+-		DHD_ERROR(("%s: OOM - dhd_if_t\n", __func__));
+-		return -ENOMEM;
+-	}
+-
+-	memset(ifp, 0, sizeof(dhd_if_t));
+-	ifp->info = dhd;
+-	dhd->iflist[ifidx] = ifp;
+-	strlcpy(ifp->name, name, IFNAMSIZ);
+-	if (mac_addr != NULL)
+-		memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN);
+-
+-	if (handle == NULL) {
+-		ifp->state = WLC_E_IF_ADD;
+-		ifp->idx = ifidx;
+-		ASSERT(dhd->sysioc_tsk);
+-		up(&dhd->sysioc_sem);
+-	} else
+-		ifp->net = (struct net_device *)handle;
+-
+-	return 0;
+-}
+-
+-void dhd_del_if(dhd_info_t *dhd, int ifidx)
+-{
+-	dhd_if_t *ifp;
+-
+-	DHD_TRACE(("%s: idx %d\n", __func__, ifidx));
+-
+-	ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS));
+-	ifp = dhd->iflist[ifidx];
+-	if (!ifp) {
+-		DHD_ERROR(("%s: Null interface\n", __func__));
+-		return;
+-	}
+-
+-	ifp->state = WLC_E_IF_DEL;
+-	ifp->idx = ifidx;
+-	ASSERT(dhd->sysioc_tsk);
+-	up(&dhd->sysioc_sem);
+-}
+-
+-dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen)
+-{
+-	dhd_info_t *dhd = NULL;
+-	struct net_device *net;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	/* updates firmware nvram path if it was provided as module
+-		 paramters */
+-	if ((firmware_path != NULL) && (firmware_path[0] != '\0'))
+-		strcpy(fw_path, firmware_path);
+-	if ((nvram_path != NULL) && (nvram_path[0] != '\0'))
+-		strcpy(nv_path, nvram_path);
+-
+-	/* Allocate etherdev, including space for private structure */
+-	net = alloc_etherdev(sizeof(dhd));
+-	if (!net) {
+-		DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Allocate primary dhd_info */
+-	dhd = kzalloc(sizeof(dhd_info_t), GFP_ATOMIC);
+-	if (!dhd) {
+-		DHD_ERROR(("%s: OOM - alloc dhd_info\n", __func__));
+-		goto fail;
+-	}
+-
+-	/*
+-	 * Save the dhd_info into the priv
+-	 */
+-	memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+-
+-	/* Set network interface name if it was provided as module parameter */
+-	if (iface_name[0]) {
+-		int len;
+-		char ch;
+-		strncpy(net->name, iface_name, IFNAMSIZ);
+-		net->name[IFNAMSIZ - 1] = 0;
+-		len = strlen(net->name);
+-		ch = net->name[len - 1];
+-		if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
+-			strcat(net->name, "%d");
+-	}
+-
+-	if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) ==
+-	    DHD_BAD_IF)
+-		goto fail;
+-
+-	net->netdev_ops = NULL;
+-	sema_init(&dhd->proto_sem, 1);
+-	/* Initialize other structure content */
+-	init_waitqueue_head(&dhd->ioctl_resp_wait);
+-	init_waitqueue_head(&dhd->ctrl_wait);
+-
+-	/* Initialize the spinlocks */
+-	spin_lock_init(&dhd->sdlock);
+-	spin_lock_init(&dhd->txqlock);
+-
+-	/* Link to info module */
+-	dhd->pub.info = dhd;
+-
+-	/* Link to bus module */
+-	dhd->pub.bus = bus;
+-	dhd->pub.hdrlen = bus_hdrlen;
+-
+-	/* Attach and link in the protocol */
+-	if (dhd_prot_attach(&dhd->pub) != 0) {
+-		DHD_ERROR(("dhd_prot_attach failed\n"));
+-		goto fail;
+-	}
+-#if defined(CONFIG_WIRELESS_EXT)
+-	/* Attach and link in the iw */
+-	if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
+-		DHD_ERROR(("wl_iw_attach failed\n"));
+-		goto fail;
+-	}
+-#endif	/* defined(CONFIG_WIRELESS_EXT) */
+-
+-	/* Attach and link in the cfg80211 */
+-	if (IS_CFG80211_FAVORITE()) {
+-		if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
+-			DHD_ERROR(("wl_cfg80211_attach failed\n"));
+-			goto fail;
+-		}
+-		if (!NO_FW_REQ()) {
+-			strcpy(fw_path, wl_cfg80211_get_fwname());
+-			strcpy(nv_path, wl_cfg80211_get_nvramname());
+-		}
+-	}
+-
+-	/* Set up the watchdog timer */
+-	init_timer(&dhd->timer);
+-	dhd->timer.data = (unsigned long) dhd;
+-	dhd->timer.function = dhd_watchdog;
+-
+-	/* Initialize thread based operation and lock */
+-	sema_init(&dhd->sdsem, 1);
+-	if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0))
+-		dhd->threads_only = true;
+-	else
+-		dhd->threads_only = false;
+-
+-	if (dhd_dpc_prio >= 0) {
+-		/* Initialize watchdog thread */
+-		sema_init(&dhd->watchdog_sem, 0);
+-		dhd->watchdog_tsk = kthread_run(dhd_watchdog_thread, dhd,
+-						"dhd_watchdog");
+-		if (IS_ERR(dhd->watchdog_tsk)) {
+-			printk(KERN_WARNING
+-				"dhd_watchdog thread failed to start\n");
+-			dhd->watchdog_tsk = NULL;
+-		}
+-	} else {
+-		dhd->watchdog_tsk = NULL;
+-	}
+-
+-	/* Set up the bottom half handler */
+-	if (dhd_dpc_prio >= 0) {
+-		/* Initialize DPC thread */
+-		sema_init(&dhd->dpc_sem, 0);
+-		dhd->dpc_tsk = kthread_run(dhd_dpc_thread, dhd, "dhd_dpc");
+-		if (IS_ERR(dhd->dpc_tsk)) {
+-			printk(KERN_WARNING
+-				"dhd_dpc thread failed to start\n");
+-			dhd->dpc_tsk = NULL;
+-		}
+-	} else {
+-		tasklet_init(&dhd->tasklet, dhd_dpc, (unsigned long) dhd);
+-		dhd->dpc_tsk = NULL;
+-	}
+-
+-	if (dhd_sysioc) {
+-		sema_init(&dhd->sysioc_sem, 0);
+-		dhd->sysioc_tsk = kthread_run(_dhd_sysioc_thread, dhd,
+-						"_dhd_sysioc");
+-		if (IS_ERR(dhd->sysioc_tsk)) {
+-			printk(KERN_WARNING
+-				"_dhd_sysioc thread failed to start\n");
+-			dhd->sysioc_tsk = NULL;
+-		}
+-	} else
+-		dhd->sysioc_tsk = NULL;
+-
+-	/*
+-	 * Save the dhd_info into the priv
+-	 */
+-	memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	g_bus = bus;
+-#endif
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, false);
+-	if (!IS_CFG80211_FAVORITE())
+-		register_pm_notifier(&dhd_sleep_pm_notifier);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-	/* && defined(DHD_GPL) */
+-	/* Init lock suspend to prevent kernel going to suspend */
+-#ifdef CONFIG_HAS_EARLYSUSPEND
+-	dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20;
+-	dhd->early_suspend.suspend = dhd_early_suspend;
+-	dhd->early_suspend.resume = dhd_late_resume;
+-	register_early_suspend(&dhd->early_suspend);
+-#endif
+-
+-	return &dhd->pub;
+-
+-fail:
+-	if (net)
+-		free_netdev(net);
+-	if (dhd)
+-		dhd_detach(&dhd->pub);
+-
+-	return NULL;
+-}
+-
+-int dhd_bus_start(dhd_pub_t *dhdp)
+-{
+-	int ret = -1;
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-#ifdef EMBEDDED_PLATFORM
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	ASSERT(dhd);
+-
+-	DHD_TRACE(("%s:\n", __func__));
+-
+-	/* try to download image and nvram to the dongle */
+-	if (dhd->pub.busstate == DHD_BUS_DOWN) {
+-		if (!(dhd_bus_download_firmware(dhd->pub.bus,
+-						fw_path, nv_path))) {
+-			DHD_ERROR(("%s: dhdsdio_probe_download failed. "
+-				"firmware = %s nvram = %s\n",
+-				__func__, fw_path, nv_path));
+-			return -1;
+-		}
+-	}
+-
+-	/* Start the watchdog timer */
+-	dhd->pub.tickcnt = 0;
+-	dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+-
+-	/* Bring up the bus */
+-	ret = dhd_bus_init(&dhd->pub, true);
+-	if (ret != 0) {
+-		DHD_ERROR(("%s, dhd_bus_init failed %d\n", __func__, ret));
+-		return ret;
+-	}
+-#if defined(OOB_INTR_ONLY)
+-	/* Host registration for OOB interrupt */
+-	if (bcmsdh_register_oob_intr(dhdp)) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		DHD_ERROR(("%s Host failed to resgister for OOB\n", __func__));
+-		return -ENODEV;
+-	}
+-
+-	/* Enable oob at firmware */
+-	dhd_enable_oob_intr(dhd->pub.bus, true);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-	/* If bus is not ready, can't come up */
+-	if (dhd->pub.busstate != DHD_BUS_DATA) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		DHD_ERROR(("%s failed bus is not ready\n", __func__));
+-		return -ENODEV;
+-	}
+-#ifdef EMBEDDED_PLATFORM
+-	bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+-	memcpy(dhdp->eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-
+-	setbit(dhdp->eventmask, WLC_E_SET_SSID);
+-	setbit(dhdp->eventmask, WLC_E_PRUNE);
+-	setbit(dhdp->eventmask, WLC_E_AUTH);
+-	setbit(dhdp->eventmask, WLC_E_REASSOC);
+-	setbit(dhdp->eventmask, WLC_E_REASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_DEAUTH_IND);
+-	setbit(dhdp->eventmask, WLC_E_DISASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_DISASSOC);
+-	setbit(dhdp->eventmask, WLC_E_JOIN);
+-	setbit(dhdp->eventmask, WLC_E_ASSOC_IND);
+-	setbit(dhdp->eventmask, WLC_E_PSK_SUP);
+-	setbit(dhdp->eventmask, WLC_E_LINK);
+-	setbit(dhdp->eventmask, WLC_E_NDIS_LINK);
+-	setbit(dhdp->eventmask, WLC_E_MIC_ERROR);
+-	setbit(dhdp->eventmask, WLC_E_PMKID_CACHE);
+-	setbit(dhdp->eventmask, WLC_E_TXFAIL);
+-	setbit(dhdp->eventmask, WLC_E_JOIN_START);
+-	setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
+-#ifdef PNO_SUPPORT
+-	setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
+-#endif				/* PNO_SUPPORT */
+-
+-/* enable dongle roaming event */
+-
+-	dhdp->pktfilter_count = 1;
+-	/* Setup filter to allow only unicast */
+-	dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00";
+-#endif				/* EMBEDDED_PLATFORM */
+-
+-	/* Bus is ready, do any protocol initialization */
+-	ret = dhd_prot_init(&dhd->pub);
+-	if (ret < 0)
+-		return ret;
+-
+-	return 0;
+-}
+-
+-int
+-dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len,
+-	  int set)
+-{
+-	char buf[strlen(name) + 1 + cmd_len];
+-	int len = sizeof(buf);
+-	wl_ioctl_t ioc;
+-	int ret;
+-
+-	len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-
+-	ioc.cmd = set ? WLC_SET_VAR : WLC_GET_VAR;
+-	ioc.buf = buf;
+-	ioc.len = len;
+-	ioc.set = set;
+-
+-	ret = dhd_prot_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+-	if (!set && ret >= 0)
+-		memcpy(cmd_buf, buf, cmd_len);
+-
+-	return ret;
+-}
+-
+-static struct net_device_ops dhd_ops_pri = {
+-	.ndo_open = dhd_open,
+-	.ndo_stop = dhd_stop,
+-	.ndo_get_stats = dhd_get_stats,
+-	.ndo_do_ioctl = dhd_ioctl_entry,
+-	.ndo_start_xmit = dhd_start_xmit,
+-	.ndo_set_mac_address = dhd_set_mac_address,
+-	.ndo_set_multicast_list = dhd_set_multicast_list
+-};
+-
+-int dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) dhdp->info;
+-	struct net_device *net;
+-	u8 temp_addr[ETH_ALEN] = {
+-		0x00, 0x90, 0x4c, 0x11, 0x22, 0x33};
+-
+-	DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx));
+-
+-	ASSERT(dhd && dhd->iflist[ifidx]);
+-
+-	net = dhd->iflist[ifidx]->net;
+-	ASSERT(net);
+-
+-	ASSERT(!net->netdev_ops);
+-	net->netdev_ops = &dhd_ops_pri;
+-
+-	/*
+-	 * We have to use the primary MAC for virtual interfaces
+-	 */
+-	if (ifidx != 0) {
+-		/* for virtual interfaces use the primary MAC  */
+-		memcpy(temp_addr, dhd->pub.mac, ETH_ALEN);
+-
+-	}
+-
+-	if (ifidx == 1) {
+-		DHD_TRACE(("%s ACCESS POINT MAC: \n", __func__));
+-		/*  ACCESSPOINT INTERFACE CASE */
+-		temp_addr[0] |= 0X02;	/* set bit 2 ,
+-			 - Locally Administered address  */
+-
+-	}
+-	net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
+-	net->ethtool_ops = &dhd_ethtool_ops;
+-
+-	dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen;
+-
+-	memcpy(net->dev_addr, temp_addr, ETH_ALEN);
+-
+-	if (register_netdev(net) != 0) {
+-		DHD_ERROR(("%s: couldn't register the net device\n",
+-			__func__));
+-		goto fail;
+-	}
+-
+-	DHD_INFO(("%s: Broadcom Dongle Host Driver\n", net->name));
+-
+-	return 0;
+-
+-fail:
+-	net->netdev_ops = NULL;
+-	return -EBADE;
+-}
+-
+-void dhd_bus_detach(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (dhdp) {
+-		dhd = (dhd_info_t *) dhdp->info;
+-		if (dhd) {
+-			/* Stop the protocol module */
+-			dhd_prot_stop(&dhd->pub);
+-
+-			/* Stop the bus module */
+-			dhd_bus_stop(dhd->pub.bus, true);
+-#if defined(OOB_INTR_ONLY)
+-			bcmsdh_unregister_oob_intr();
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-			/* Clear the watchdog timer */
+-			del_timer_sync(&dhd->timer);
+-			dhd->wd_timer_valid = false;
+-		}
+-	}
+-}
+-
+-void dhd_detach(dhd_pub_t *dhdp)
+-{
+-	dhd_info_t *dhd;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (dhdp) {
+-		dhd = (dhd_info_t *) dhdp->info;
+-		if (dhd) {
+-			dhd_if_t *ifp;
+-			int i;
+-
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-			if (dhd->early_suspend.suspend)
+-				unregister_early_suspend(&dhd->early_suspend);
+-#endif				/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-
+-			for (i = 1; i < DHD_MAX_IFS; i++)
+-				if (dhd->iflist[i])
+-					dhd_del_if(dhd, i);
+-
+-			ifp = dhd->iflist[0];
+-			ASSERT(ifp);
+-			if (ifp->net->netdev_ops == &dhd_ops_pri) {
+-				dhd_stop(ifp->net);
+-				unregister_netdev(ifp->net);
+-			}
+-
+-			if (dhd->watchdog_tsk) {
+-				send_sig(SIGTERM, dhd->watchdog_tsk, 1);
+-				kthread_stop(dhd->watchdog_tsk);
+-				dhd->watchdog_tsk = NULL;
+-			}
+-
+-			if (dhd->dpc_tsk) {
+-				send_sig(SIGTERM, dhd->dpc_tsk, 1);
+-				kthread_stop(dhd->dpc_tsk);
+-				dhd->dpc_tsk = NULL;
+-			} else
+-				tasklet_kill(&dhd->tasklet);
+-
+-			if (dhd->sysioc_tsk) {
+-				send_sig(SIGTERM, dhd->sysioc_tsk, 1);
+-				kthread_stop(dhd->sysioc_tsk);
+-				dhd->sysioc_tsk = NULL;
+-			}
+-
+-			dhd_bus_detach(dhdp);
+-
+-			if (dhdp->prot)
+-				dhd_prot_detach(dhdp);
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-			wl_iw_detach();
+-#endif				/* (CONFIG_WIRELESS_EXT) */
+-
+-			if (IS_CFG80211_FAVORITE())
+-				wl_cfg80211_detach();
+-
+-#if defined(CONFIG_PM_SLEEP)
+-			if (!IS_CFG80211_FAVORITE())
+-				unregister_pm_notifier(&dhd_sleep_pm_notifier);
+-#endif	/* defined(CONFIG_PM_SLEEP) */
+-			/* && defined(DHD_GPL) */
+-			free_netdev(ifp->net);
+-			kfree(ifp);
+-			kfree(dhd);
+-		}
+-	}
+-}
+-
+-static void __exit dhd_module_cleanup(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	dhd_bus_unregister();
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	wifi_del_dev();
+-#endif
+-	/* Call customer gpio to turn off power with WL_REG_ON signal */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+-}
+-
+-static int __init dhd_module_init(void)
+-{
+-	int error;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Sanity check on the module parameters */
+-	do {
+-		/* Both watchdog and DPC as tasklets are ok */
+-		if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0))
+-			break;
+-
+-		/* If both watchdog and DPC are threads, TX must be deferred */
+-		if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)
+-		    && dhd_deferred_tx)
+-			break;
+-
+-		DHD_ERROR(("Invalid module parameters.\n"));
+-		return -EINVAL;
+-	} while (0);
+-	/* Call customer gpio to turn on power with WL_REG_ON signal */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+-
+-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+-	sema_init(&wifi_control_sem, 0);
+-
+-	error = wifi_add_dev();
+-	if (error) {
+-		DHD_ERROR(("%s: platform_driver_register failed\n", __func__));
+-		goto failed;
+-	}
+-
+-	/* Waiting callback after platform_driver_register is done or
+-		 exit with error */
+-	if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
+-		printk(KERN_ERR "%s: platform_driver_register timeout\n",
+-			__func__);
+-		/* remove device */
+-		wifi_del_dev();
+-		goto failed;
+-	}
+-#endif	/* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+-
+-	error = dhd_bus_register();
+-
+-	if (error) {
+-		DHD_ERROR(("%s: sdio_register_driver failed\n", __func__));
+-		goto failed;
+-	}
+-	return error;
+-
+-failed:
+-	/* turn off power and exit */
+-	dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+-	return -EINVAL;
+-}
+-
+-module_init(dhd_module_init);
+-module_exit(dhd_module_cleanup);
+-
+-/*
+- * OS specific functions required to implement DHD driver in OS independent way
+- */
+-int dhd_os_proto_block(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd) {
+-		down(&dhd->proto_sem);
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-int dhd_os_proto_unblock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd) {
+-		up(&dhd->proto_sem);
+-		return 1;
+-	}
+-
+-	return 0;
+-}
+-
+-unsigned int dhd_os_get_ioctl_resp_timeout(void)
+-{
+-	return (unsigned int)dhd_ioctl_timeout_msec;
+-}
+-
+-void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
+-{
+-	dhd_ioctl_timeout_msec = (int)timeout_msec;
+-}
+-
+-int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-	DECLARE_WAITQUEUE(wait, current);
+-	int timeout = dhd_ioctl_timeout_msec;
+-
+-	/* Convert timeout in millsecond to jiffies */
+-	timeout = timeout * HZ / 1000;
+-
+-	/* Wait until control frame is available */
+-	add_wait_queue(&dhd->ioctl_resp_wait, &wait);
+-	set_current_state(TASK_INTERRUPTIBLE);
+-
+-	while (!(*condition) && (!signal_pending(current) && timeout))
+-		timeout = schedule_timeout(timeout);
+-
+-	if (signal_pending(current))
+-		*pending = true;
+-
+-	set_current_state(TASK_RUNNING);
+-	remove_wait_queue(&dhd->ioctl_resp_wait, &wait);
+-
+-	return timeout;
+-}
+-
+-int dhd_os_ioctl_resp_wake(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd = (dhd_info_t *) (pub->info);
+-
+-	if (waitqueue_active(&dhd->ioctl_resp_wait))
+-		wake_up_interruptible(&dhd->ioctl_resp_wait);
+-
+-	return 0;
+-}
+-
+-void dhd_os_wd_timer(void *bus, uint wdtick)
+-{
+-	dhd_pub_t *pub = bus;
+-	static uint save_dhd_watchdog_ms;
+-	dhd_info_t *dhd = (dhd_info_t *) pub->info;
+-
+-	/* don't start the wd until fw is loaded */
+-	if (pub->busstate == DHD_BUS_DOWN)
+-		return;
+-
+-	/* Totally stop the timer */
+-	if (!wdtick && dhd->wd_timer_valid == true) {
+-		del_timer_sync(&dhd->timer);
+-		dhd->wd_timer_valid = false;
+-		save_dhd_watchdog_ms = wdtick;
+-		return;
+-	}
+-
+-	if (wdtick) {
+-		dhd_watchdog_ms = (uint) wdtick;
+-
+-		if (save_dhd_watchdog_ms != dhd_watchdog_ms) {
+-
+-			if (dhd->wd_timer_valid == true)
+-				/* Stop timer and restart at new value */
+-				del_timer_sync(&dhd->timer);
+-
+-			/* Create timer again when watchdog period is
+-			   dynamically changed or in the first instance
+-			 */
+-			dhd->timer.expires =
+-			    jiffies + dhd_watchdog_ms * HZ / 1000;
+-			add_timer(&dhd->timer);
+-
+-		} else {
+-			/* Re arm the timer, at last watchdog period */
+-			mod_timer(&dhd->timer,
+-				  jiffies + dhd_watchdog_ms * HZ / 1000);
+-		}
+-
+-		dhd->wd_timer_valid = true;
+-		save_dhd_watchdog_ms = wdtick;
+-	}
+-}
+-
+-void *dhd_os_open_image(char *filename)
+-{
+-	struct file *fp;
+-
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_request_fw(filename);
+-
+-	fp = filp_open(filename, O_RDONLY, 0);
+-	/*
+-	 * 2.6.11 (FC4) supports filp_open() but later revs don't?
+-	 * Alternative:
+-	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
+-	 * ???
+-	 */
+-	if (IS_ERR(fp))
+-		fp = NULL;
+-
+-	return fp;
+-}
+-
+-int dhd_os_get_image_block(char *buf, int len, void *image)
+-{
+-	struct file *fp = (struct file *)image;
+-	int rdlen;
+-
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_read_fw(buf, len);
+-
+-	if (!image)
+-		return 0;
+-
+-	rdlen = kernel_read(fp, fp->f_pos, buf, len);
+-	if (rdlen > 0)
+-		fp->f_pos += rdlen;
+-
+-	return rdlen;
+-}
+-
+-void dhd_os_close_image(void *image)
+-{
+-	if (IS_CFG80211_FAVORITE() && !NO_FW_REQ())
+-		return wl_cfg80211_release_fw();
+-	if (image)
+-		filp_close((struct file *)image, NULL);
+-}
+-
+-void dhd_os_sdlock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd->threads_only)
+-		down(&dhd->sdsem);
+-	else
+-		spin_lock_bh(&dhd->sdlock);
+-}
+-
+-void dhd_os_sdunlock(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-
+-	if (dhd->threads_only)
+-		up(&dhd->sdsem);
+-	else
+-		spin_unlock_bh(&dhd->sdlock);
+-}
+-
+-void dhd_os_sdlock_txq(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-	spin_lock_bh(&dhd->txqlock);
+-}
+-
+-void dhd_os_sdunlock_txq(dhd_pub_t *pub)
+-{
+-	dhd_info_t *dhd;
+-
+-	dhd = (dhd_info_t *) (pub->info);
+-	spin_unlock_bh(&dhd->txqlock);
+-}
+-
+-void dhd_os_sdlock_rxq(dhd_pub_t *pub)
+-{
+-}
+-
+-void dhd_os_sdunlock_rxq(dhd_pub_t *pub)
+-{
+-}
+-
+-void dhd_os_sdtxlock(dhd_pub_t *pub)
+-{
+-	dhd_os_sdlock(pub);
+-}
+-
+-void dhd_os_sdtxunlock(dhd_pub_t *pub)
+-{
+-	dhd_os_sdunlock(pub);
+-}
+-
+-static int
+-dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
+-		  wl_event_msg_t *event, void **data)
+-{
+-	int bcmerror = 0;
+-
+-	ASSERT(dhd != NULL);
+-
+-	bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data);
+-	if (bcmerror != 0)
+-		return bcmerror;
+-
+-#if defined(CONFIG_WIRELESS_EXT)
+-	if (!IS_CFG80211_FAVORITE()) {
+-		if ((dhd->iflist[*ifidx] == NULL)
+-		    || (dhd->iflist[*ifidx]->net == NULL)) {
+-			DHD_ERROR(("%s Exit null pointer\n", __func__));
+-			return bcmerror;
+-		}
+-
+-		if (dhd->iflist[*ifidx]->net)
+-			wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+-	}
+-#endif				/* defined(CONFIG_WIRELESS_EXT)  */
+-
+-	if (IS_CFG80211_FAVORITE()) {
+-		ASSERT(dhd->iflist[*ifidx] != NULL);
+-		ASSERT(dhd->iflist[*ifidx]->net != NULL);
+-		if (dhd->iflist[*ifidx]->net)
+-			wl_cfg80211_event(dhd->iflist[*ifidx]->net, event,
+-					  *data);
+-	}
+-
+-	return bcmerror;
+-}
+-
+-/* send up locally generated event */
+-void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
+-{
+-	switch (be32_to_cpu(event->event_type)) {
+-	default:
+-		break;
+-	}
+-}
+-
+-void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
+-{
+-	struct dhd_info *dhdinfo = dhd->info;
+-	dhd_os_sdunlock(dhd);
+-	wait_event_interruptible_timeout(dhdinfo->ctrl_wait,
+-					 (*lockvar == false), HZ * 2);
+-	dhd_os_sdlock(dhd);
+-	return;
+-}
+-
+-void dhd_wait_event_wakeup(dhd_pub_t *dhd)
+-{
+-	struct dhd_info *dhdinfo = dhd->info;
+-	if (waitqueue_active(&dhdinfo->ctrl_wait))
+-		wake_up_interruptible(&dhdinfo->ctrl_wait);
+-	return;
+-}
+-
+-int dhd_dev_reset(struct net_device *dev, u8 flag)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	/* Turning off watchdog */
+-	if (flag)
+-		dhd_os_wd_timer(&dhd->pub, 0);
+-
+-	dhd_bus_devreset(&dhd->pub, flag);
+-
+-	/* Turning on watchdog back */
+-	if (!flag)
+-		dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+-	DHD_ERROR(("%s:  WLAN OFF DONE\n", __func__));
+-
+-	return 1;
+-}
+-
+-int net_os_set_suspend_disable(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-	int ret = 0;
+-
+-	if (dhd) {
+-		ret = dhd->pub.suspend_disable_flag;
+-		dhd->pub.suspend_disable_flag = val;
+-	}
+-	return ret;
+-}
+-
+-int net_os_set_suspend(struct net_device *dev, int val)
+-{
+-	int ret = 0;
+-#if defined(CONFIG_HAS_EARLYSUSPEND)
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	if (dhd) {
+-		dhd_os_proto_block(&dhd->pub);
+-		ret = dhd_set_suspend(val, &dhd->pub);
+-		dhd_os_proto_unblock(&dhd->pub);
+-	}
+-#endif		/* defined(CONFIG_HAS_EARLYSUSPEND) */
+-	return ret;
+-}
+-
+-int net_os_set_dtim_skip(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-
+-	if (dhd)
+-		dhd->pub.dtim_skip = val;
+-
+-	return 0;
+-}
+-
+-int net_os_set_packet_filter(struct net_device *dev, int val)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
+-	int ret = 0;
+-
+-	/* Packet filtering is set only if we still in early-suspend and
+-	 * we need either to turn it ON or turn it OFF
+-	 * We can always turn it OFF in case of early-suspend, but we turn it
+-	 * back ON only if suspend_disable_flag was not set
+-	 */
+-	if (dhd && dhd->pub.up) {
+-		dhd_os_proto_block(&dhd->pub);
+-		if (dhd->pub.in_suspend) {
+-			if (!val || (val && !dhd->pub.suspend_disable_flag))
+-				dhd_set_packet_filter(val, &dhd->pub);
+-		}
+-		dhd_os_proto_unblock(&dhd->pub);
+-	}
+-	return ret;
+-}
+-
+-void dhd_dev_init_ioctl(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	dhd_preinit_ioctls(&dhd->pub);
+-}
+-
+-#ifdef PNO_SUPPORT
+-/* Linux wrapper to call common dhd_pno_clean */
+-int dhd_dev_pno_reset(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_clean(&dhd->pub);
+-}
+-
+-/* Linux wrapper to call common dhd_pno_enable */
+-int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_enable(&dhd->pub, pfn_enabled);
+-}
+-
+-/* Linux wrapper to call common dhd_pno_set */
+-int
+-dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local, int nssid,
+-		unsigned char scan_fr)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr);
+-}
+-
+-/* Linux wrapper to get  pno status */
+-int dhd_dev_get_pno_status(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-
+-	return dhd_pno_get_status(&dhd->pub);
+-}
+-
+-#endif				/* PNO_SUPPORT */
+-
+-static int dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
+-{
+-	return atomic_read(&dhd->pend_8021x_cnt);
+-}
+-
+-#define MAX_WAIT_FOR_8021X_TX	10
+-
+-int dhd_wait_pend8021x(struct net_device *dev)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+-	int timeout = 10 * HZ / 1000;
+-	int ntimes = MAX_WAIT_FOR_8021X_TX;
+-	int pend = dhd_get_pend_8021x_cnt(dhd);
+-
+-	while (ntimes && pend) {
+-		if (pend) {
+-			set_current_state(TASK_INTERRUPTIBLE);
+-			schedule_timeout(timeout);
+-			set_current_state(TASK_RUNNING);
+-			ntimes--;
+-		}
+-		pend = dhd_get_pend_8021x_cnt(dhd);
+-	}
+-	return pend;
+-}
+-
+-void wl_os_wd_timer(struct net_device *ndev, uint wdtick)
+-{
+-	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+-
+-	dhd_os_wd_timer(&dhd->pub, wdtick);
+-}
+-
+-#ifdef DHD_DEBUG
+-int write_to_file(dhd_pub_t *dhd, u8 *buf, int size)
+-{
+-	int ret = 0;
+-	struct file *fp;
+-	mm_segment_t old_fs;
+-	loff_t pos = 0;
+-
+-	/* change to KERNEL_DS address limit */
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-
+-	/* open file to write */
+-	fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640);
+-	if (!fp) {
+-		DHD_ERROR(("%s: open file error\n", __func__));
+-		ret = -1;
+-		goto exit;
+-	}
+-
+-	/* Write buf to file */
+-	fp->f_op->write(fp, buf, size, &pos);
+-
+-exit:
+-	/* free buf before return */
+-	kfree(buf);
+-	/* close file before return */
+-	if (fp)
+-		filp_close(fp, current->files);
+-	/* restore previous address limit */
+-	set_fs(old_fs);
+-
+-	return ret;
+-}
+-#endif				/* DHD_DEBUG */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
+deleted file mode 100644
+index c66f1c2..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/sched.h>
+-
+-int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
+-{
+-	int rc = 0;
+-	rc = sched_setscheduler(p, policy, param);
+-	return rc;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
+deleted file mode 100644
+index 030d5ff..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h
++++ /dev/null
+@@ -1,90 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhd_proto_h_
+-#define _dhd_proto_h_
+-
+-#include <dhdioctl.h>
+-#include <wlioctl.h>
+-
+-#ifndef IOCTL_RESP_TIMEOUT
+-#define IOCTL_RESP_TIMEOUT  2000	/* In milli second */
+-#endif
+-
+-#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT
+-#define IOCTL_CHIP_ACTIVE_TIMEOUT  10	/* In milli second */
+-#endif
+-
+-/*
+- * Exported from the dhd protocol module (dhd_cdc, dhd_rndis)
+- */
+-
+-/* Linkage, sets prot link and updates hdrlen in pub */
+-extern int dhd_prot_attach(dhd_pub_t *dhdp);
+-
+-/* Unlink, frees allocated protocol memory (including dhd_prot) */
+-extern void dhd_prot_detach(dhd_pub_t *dhdp);
+-
+-/* Initialize protocol: sync w/dongle state.
+- * Sets dongle media info (iswl, drv_version, mac address).
+- */
+-extern int dhd_prot_init(dhd_pub_t *dhdp);
+-
+-/* Stop protocol: sync w/dongle state. */
+-extern void dhd_prot_stop(dhd_pub_t *dhdp);
+-
+-/* Add any protocol-specific data header.
+- * Caller must reserve prot_hdrlen prepend space.
+- */
+-extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, struct sk_buff *txp);
+-
+-/* Remove any protocol-specific data header. */
+-extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, struct sk_buff *rxp);
+-
+-/* Use protocol to issue ioctl to dongle */
+-extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc,
+-			  void *buf, int len);
+-
+-/* Check for and handle local prot-specific iovar commands */
+-extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+-			     void *params, int plen, void *arg, int len,
+-			     bool set);
+-
+-/* Add prot dump output to a buffer */
+-extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+-
+-/* Update local copy of dongle statistics */
+-extern void dhd_prot_dstats(dhd_pub_t *dhdp);
+-
+-extern int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf,
+-		     uint buflen);
+-
+-extern int dhd_preinit_ioctls(dhd_pub_t *dhd);
+-
+-/********************************
+- * For version-string expansion *
+- */
+-#if defined(BDC)
+-#define DHD_PROTOCOL "bdc"
+-#elif defined(CDC)
+-#define DHD_PROTOCOL "cdc"
+-#elif defined(RNDIS)
+-#define DHD_PROTOCOL "rndis"
+-#else
+-#define DHD_PROTOCOL "unknown"
+-#endif				/* proto */
+-
+-#endif				/* _dhd_proto_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
+deleted file mode 100644
+index a71c6f8..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
++++ /dev/null
+@@ -1,6390 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/printk.h>
+-#include <linux/pci_ids.h>
+-#include <linux/netdevice.h>
+-#include <bcmdefs.h>
+-#include <bcmsdh.h>
+-
+-#ifdef BCMEMBEDIMAGE
+-#include BCMEMBEDIMAGE
+-#endif				/* BCMEMBEDIMAGE */
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmdevs.h>
+-
+-#include <hndsoc.h>
+-#ifdef DHD_DEBUG
+-#include <hndrte_armtrap.h>
+-#include <hndrte_cons.h>
+-#endif				/* DHD_DEBUG */
+-#include <sbchipc.h>
+-#include <sbhnddma.h>
+-
+-#include <sdio.h>
+-#include <sbsdio.h>
+-#include <sbsdpcmdev.h>
+-#include <bcmsdpcm.h>
+-
+-#include <proto/802.11.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhd_bus.h>
+-#include <dhd_proto.h>
+-#include <dhd_dbg.h>
+-#include <dhdioctl.h>
+-#include <sdiovar.h>
+-#include <bcmchip.h>
+-
+-#ifndef DHDSDIO_MEM_DUMP_FNAME
+-#define DHDSDIO_MEM_DUMP_FNAME         "mem_dump"
+-#endif
+-
+-#define TXQLEN		2048	/* bulk tx queue length */
+-#define TXHI		(TXQLEN - 256)	/* turn on flow control above TXHI */
+-#define TXLOW		(TXHI - 256)	/* turn off flow control below TXLOW */
+-#define PRIOMASK	7
+-
+-#define TXRETRIES	2	/* # of retries for tx frames */
+-
+-#if defined(CONFIG_MACH_SANDGATE2G)
+-#define DHD_RXBOUND	250	/* Default for max rx frames in
+-				 one scheduling */
+-#else
+-#define DHD_RXBOUND	50	/* Default for max rx frames in
+-				 one scheduling */
+-#endif				/* defined(CONFIG_MACH_SANDGATE2G) */
+-
+-#define DHD_TXBOUND	20	/* Default for max tx frames in
+-				 one scheduling */
+-
+-#define DHD_TXMINMAX	1	/* Max tx frames if rx still pending */
+-
+-#define MEMBLOCK	2048	/* Block size used for downloading
+-				 of dongle image */
+-#define MAX_DATA_BUF	(32 * 1024)	/* Must be large enough to hold
+-				 biggest possible glom */
+-
+-/* Packet alignment for most efficient SDIO (can change based on platform) */
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-#if !ISPOWEROF2(DHD_SDALIGN)
+-#error DHD_SDALIGN is not a power of 2!
+-#endif
+-
+-#ifndef DHD_FIRSTREAD
+-#define DHD_FIRSTREAD	32
+-#endif
+-#if !ISPOWEROF2(DHD_FIRSTREAD)
+-#error DHD_FIRSTREAD is not a power of 2!
+-#endif
+-
+-/* Total length of frame header for dongle protocol */
+-#define SDPCM_HDRLEN	(SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
+-#ifdef SDTEST
+-#define SDPCM_RESERVE	(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN)
+-#else
+-#define SDPCM_RESERVE	(SDPCM_HDRLEN + DHD_SDALIGN)
+-#endif
+-
+-/* Space for header read, limit for data packets */
+-#ifndef MAX_HDR_READ
+-#define MAX_HDR_READ	32
+-#endif
+-#if !ISPOWEROF2(MAX_HDR_READ)
+-#error MAX_HDR_READ is not a power of 2!
+-#endif
+-
+-#define MAX_RX_DATASZ	2048
+-
+-/* Maximum milliseconds to wait for F2 to come up */
+-#define DHD_WAIT_F2RDY	3000
+-
+-/* Bump up limit on waiting for HT to account for first startup;
+- * if the image is doing a CRC calculation before programming the PMU
+- * for HT availability, it could take a couple hundred ms more, so
+- * max out at a 1 second (1000000us).
+- */
+-#if (PMU_MAX_TRANSITION_DLY <= 1000000)
+-#undef PMU_MAX_TRANSITION_DLY
+-#define PMU_MAX_TRANSITION_DLY 1000000
+-#endif
+-
+-/* Value for ChipClockCSR during initial setup */
+-#define DHD_INIT_CLKCTL1	(SBSDIO_FORCE_HW_CLKREQ_OFF |	\
+-					SBSDIO_ALP_AVAIL_REQ)
+-#define DHD_INIT_CLKCTL2	(SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP)
+-
+-/* Flags for SDH calls */
+-#define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
+-
+-/*
+- * Conversion of 802.1D priority to precedence level
+- */
+-#define PRIO2PREC(prio) \
+-	(((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \
+-	((prio^2)) : (prio))
+-
+-DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep);
+-extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf,
+-			    uint len);
+-
+-#ifdef DHD_DEBUG
+-/* Device console log buffer state */
+-typedef struct dhd_console {
+-	uint count;		/* Poll interval msec counter */
+-	uint log_addr;		/* Log struct address (fixed) */
+-	hndrte_log_t log;	/* Log struct (host copy) */
+-	uint bufsize;		/* Size of log buffer */
+-	u8 *buf;		/* Log buffer (host copy) */
+-	uint last;		/* Last buffer read index */
+-} dhd_console_t;
+-#endif				/* DHD_DEBUG */
+-
+-/* misc chip info needed by some of the routines */
+-struct chip_info {
+-	u32 chip;
+-	u32 chiprev;
+-	u32 cccorebase;
+-	u32 ccrev;
+-	u32 cccaps;
+-	u32 buscorebase;
+-	u32 buscorerev;
+-	u32 buscoretype;
+-	u32 ramcorebase;
+-	u32 armcorebase;
+-	u32 pmurev;
+-	u32 ramsize;
+-};
+-
+-/* Private data for SDIO bus interaction */
+-typedef struct dhd_bus {
+-	dhd_pub_t *dhd;
+-
+-	bcmsdh_info_t *sdh;	/* Handle for BCMSDH calls */
+-	struct chip_info *ci;	/* Chip info struct */
+-	char *vars;		/* Variables (from CIS and/or other) */
+-	uint varsz;		/* Size of variables buffer */
+-	u32 sbaddr;		/* Current SB window pointer (-1, invalid) */
+-
+-	sdpcmd_regs_t *regs;	/* Registers for SDIO core */
+-	uint sdpcmrev;		/* SDIO core revision */
+-	uint armrev;		/* CPU core revision */
+-	uint ramrev;		/* SOCRAM core revision */
+-	u32 ramsize;		/* Size of RAM in SOCRAM (bytes) */
+-	u32 orig_ramsize;	/* Size of RAM in SOCRAM (bytes) */
+-
+-	u32 bus;		/* gSPI or SDIO bus */
+-	u32 hostintmask;	/* Copy of Host Interrupt Mask */
+-	u32 intstatus;	/* Intstatus bits (events) pending */
+-	bool dpc_sched;		/* Indicates DPC schedule (intrpt rcvd) */
+-	bool fcstate;		/* State of dongle flow-control */
+-
+-	u16 cl_devid;	/* cached devid for dhdsdio_probe_attach() */
+-	char *fw_path;		/* module_param: path to firmware image */
+-	char *nv_path;		/* module_param: path to nvram vars file */
+-	const char *nvram_params;	/* user specified nvram params. */
+-
+-	uint blocksize;		/* Block size of SDIO transfers */
+-	uint roundup;		/* Max roundup limit */
+-
+-	struct pktq txq;	/* Queue length used for flow-control */
+-	u8 flowcontrol;	/* per prio flow control bitmask */
+-	u8 tx_seq;		/* Transmit sequence number (next) */
+-	u8 tx_max;		/* Maximum transmit sequence allowed */
+-
+-	u8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN];
+-	u8 *rxhdr;		/* Header of current rx frame (in hdrbuf) */
+-	u16 nextlen;		/* Next Read Len from last header */
+-	u8 rx_seq;		/* Receive sequence number (expected) */
+-	bool rxskip;		/* Skip receive (awaiting NAK ACK) */
+-
+-	struct sk_buff *glomd;	/* Packet containing glomming descriptor */
+-	struct sk_buff *glom;	/* Packet chain for glommed superframe */
+-	uint glomerr;		/* Glom packet read errors */
+-
+-	u8 *rxbuf;		/* Buffer for receiving control packets */
+-	uint rxblen;		/* Allocated length of rxbuf */
+-	u8 *rxctl;		/* Aligned pointer into rxbuf */
+-	u8 *databuf;		/* Buffer for receiving big glom packet */
+-	u8 *dataptr;		/* Aligned pointer into databuf */
+-	uint rxlen;		/* Length of valid data in buffer */
+-
+-	u8 sdpcm_ver;	/* Bus protocol reported by dongle */
+-
+-	bool intr;		/* Use interrupts */
+-	bool poll;		/* Use polling */
+-	bool ipend;		/* Device interrupt is pending */
+-	bool intdis;		/* Interrupts disabled by isr */
+-	uint intrcount;		/* Count of device interrupt callbacks */
+-	uint lastintrs;		/* Count as of last watchdog timer */
+-	uint spurious;		/* Count of spurious interrupts */
+-	uint pollrate;		/* Ticks between device polls */
+-	uint polltick;		/* Tick counter */
+-	uint pollcnt;		/* Count of active polls */
+-
+-#ifdef DHD_DEBUG
+-	dhd_console_t console;	/* Console output polling support */
+-	uint console_addr;	/* Console address from shared struct */
+-#endif				/* DHD_DEBUG */
+-
+-	uint regfails;		/* Count of R_REG/W_REG failures */
+-
+-	uint clkstate;		/* State of sd and backplane clock(s) */
+-	bool activity;		/* Activity flag for clock down */
+-	s32 idletime;		/* Control for activity timeout */
+-	s32 idlecount;	/* Activity timeout counter */
+-	s32 idleclock;	/* How to set bus driver when idle */
+-	s32 sd_divisor;	/* Speed control to bus driver */
+-	s32 sd_mode;		/* Mode control to bus driver */
+-	s32 sd_rxchain;	/* If bcmsdh api accepts PKT chains */
+-	bool use_rxchain;	/* If dhd should use PKT chains */
+-	bool sleeping;		/* Is SDIO bus sleeping? */
+-	bool rxflow_mode;	/* Rx flow control mode */
+-	bool rxflow;		/* Is rx flow control on */
+-	uint prev_rxlim_hit;	/* Is prev rx limit exceeded
+-					 (per dpc schedule) */
+-	bool alp_only;		/* Don't use HT clock (ALP only) */
+-/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
+-	bool usebufpool;
+-
+-#ifdef SDTEST
+-	/* external loopback */
+-	bool ext_loop;
+-	u8 loopid;
+-
+-	/* pktgen configuration */
+-	uint pktgen_freq;	/* Ticks between bursts */
+-	uint pktgen_count;	/* Packets to send each burst */
+-	uint pktgen_print;	/* Bursts between count displays */
+-	uint pktgen_total;	/* Stop after this many */
+-	uint pktgen_minlen;	/* Minimum packet data len */
+-	uint pktgen_maxlen;	/* Maximum packet data len */
+-	uint pktgen_mode;	/* Configured mode: tx, rx, or echo */
+-	uint pktgen_stop;	/* Number of tx failures causing stop */
+-
+-	/* active pktgen fields */
+-	uint pktgen_tick;	/* Tick counter for bursts */
+-	uint pktgen_ptick;	/* Burst counter for printing */
+-	uint pktgen_sent;	/* Number of test packets generated */
+-	uint pktgen_rcvd;	/* Number of test packets received */
+-	uint pktgen_fail;	/* Number of failed send attempts */
+-	u16 pktgen_len;	/* Length of next packet to send */
+-#endif				/* SDTEST */
+-
+-	/* Some additional counters */
+-	uint tx_sderrs;		/* Count of tx attempts with sd errors */
+-	uint fcqueued;		/* Tx packets that got queued */
+-	uint rxrtx;		/* Count of rtx requests (NAK to dongle) */
+-	uint rx_toolong;	/* Receive frames too long to receive */
+-	uint rxc_errors;	/* SDIO errors when reading control frames */
+-	uint rx_hdrfail;	/* SDIO errors on header reads */
+-	uint rx_badhdr;		/* Bad received headers (roosync?) */
+-	uint rx_badseq;		/* Mismatched rx sequence number */
+-	uint fc_rcvd;		/* Number of flow-control events received */
+-	uint fc_xoff;		/* Number which turned on flow-control */
+-	uint fc_xon;		/* Number which turned off flow-control */
+-	uint rxglomfail;	/* Failed deglom attempts */
+-	uint rxglomframes;	/* Number of glom frames (superframes) */
+-	uint rxglompkts;	/* Number of packets from glom frames */
+-	uint f2rxhdrs;		/* Number of header reads */
+-	uint f2rxdata;		/* Number of frame data reads */
+-	uint f2txdata;		/* Number of f2 frame writes */
+-	uint f1regdata;		/* Number of f1 register accesses */
+-
+-	u8 *ctrl_frame_buf;
+-	u32 ctrl_frame_len;
+-	bool ctrl_frame_stat;
+-} dhd_bus_t;
+-
+-/* clkstate */
+-#define CLK_NONE	0
+-#define CLK_SDONLY	1
+-#define CLK_PENDING	2	/* Not used yet */
+-#define CLK_AVAIL	3
+-
+-#define DHD_NOPMU(dhd)	(false)
+-
+-#ifdef DHD_DEBUG
+-static int qcount[NUMPRIO];
+-static int tx_packets[NUMPRIO];
+-#endif				/* DHD_DEBUG */
+-
+-/* Deferred transmit */
+-const uint dhd_deferred_tx = 1;
+-
+-extern uint dhd_watchdog_ms;
+-extern void dhd_os_wd_timer(void *bus, uint wdtick);
+-
+-/* Tx/Rx bounds */
+-uint dhd_txbound;
+-uint dhd_rxbound;
+-uint dhd_txminmax;
+-
+-/* override the RAM size if possible */
+-#define DONGLE_MIN_MEMSIZE (128 * 1024)
+-int dhd_dongle_memsize;
+-
+-static bool dhd_alignctl;
+-
+-static bool sd1idle;
+-
+-static bool retrydata;
+-#define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata)
+-
+-static const uint watermark = 8;
+-static const uint firstread = DHD_FIRSTREAD;
+-
+-#define HDATLEN (firstread - (SDPCM_HDRLEN))
+-
+-/* Retry count for register access failures */
+-static const uint retry_limit = 2;
+-
+-/* Force even SD lengths (some host controllers mess up on odd bytes) */
+-static bool forcealign;
+-
+-#define ALIGNMENT  4
+-
+-#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+-extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable);
+-#endif
+-
+-#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD)
+-#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD
+-#endif	/* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */
+-#define PKTALIGN(_p, _len, _align)				\
+-	do {								\
+-		uint datalign;						\
+-		datalign = (unsigned long)((_p)->data);			\
+-		datalign = roundup(datalign, (_align)) - datalign;	\
+-		ASSERT(datalign < (_align));				\
+-		ASSERT((_p)->len >= ((_len) + datalign));		\
+-		if (datalign)						\
+-			skb_pull((_p), datalign);			\
+-		__skb_trim((_p), (_len));				\
+-	} while (0)
+-
+-/* Limit on rounding up frames */
+-static const uint max_roundup = 512;
+-
+-/* Try doing readahead */
+-static bool dhd_readahead;
+-
+-/* To check if there's window offered */
+-#define DATAOK(bus) \
+-	(((u8)(bus->tx_max - bus->tx_seq) != 0) && \
+-	(((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
+-
+-/* Macros to get register read/write status */
+-/* NOTE: these assume a local dhdsdio_bus_t *bus! */
+-#define R_SDREG(regvar, regaddr, retryvar) \
+-do { \
+-	retryvar = 0; \
+-	do { \
+-		regvar = R_REG(regaddr); \
+-	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+-	if (retryvar) { \
+-		bus->regfails += (retryvar-1); \
+-		if (retryvar > retry_limit) { \
+-			DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \
+-			__func__, __LINE__)); \
+-			regvar = 0; \
+-		} \
+-	} \
+-} while (0)
+-
+-#define W_SDREG(regval, regaddr, retryvar) \
+-do { \
+-	retryvar = 0; \
+-	do { \
+-		W_REG(regaddr, regval); \
+-	} while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \
+-	if (retryvar) { \
+-		bus->regfails += (retryvar-1); \
+-		if (retryvar > retry_limit) \
+-			DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \
+-			__func__, __LINE__)); \
+-	} \
+-} while (0)
+-
+-#define DHD_BUS			SDIO_BUS
+-
+-#define PKT_AVAILABLE()		(intstatus & I_HMB_FRAME_IND)
+-
+-#define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
+-
+-#ifdef SDTEST
+-static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
+-static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
+-#endif
+-
+-#ifdef DHD_DEBUG
+-static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size);
+-static int dhdsdio_mem_dump(dhd_bus_t *bus);
+-#endif				/* DHD_DEBUG  */
+-static int dhdsdio_download_state(dhd_bus_t *bus, bool enter);
+-
+-static void dhdsdio_release(dhd_bus_t *bus);
+-static void dhdsdio_release_malloc(dhd_bus_t *bus);
+-static void dhdsdio_disconnect(void *ptr);
+-static bool dhdsdio_chipmatch(u16 chipid);
+-static bool dhdsdio_probe_attach(dhd_bus_t *bus, void *sdh,
+-				 void *regsva, u16 devid);
+-static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh);
+-static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh);
+-static void dhdsdio_release_dongle(dhd_bus_t *bus);
+-
+-static uint process_nvram_vars(char *varbuf, uint len);
+-
+-static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size);
+-static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn,
+-			       uint flags, u8 *buf, uint nbytes,
+-			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
+-			       void *handle);
+-
+-static bool dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh);
+-static int _dhdsdio_download_firmware(struct dhd_bus *bus);
+-
+-static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path);
+-static int dhdsdio_download_nvram(struct dhd_bus *bus);
+-#ifdef BCMEMBEDIMAGE
+-static int dhdsdio_download_code_array(struct dhd_bus *bus);
+-#endif
+-static void dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase);
+-static int dhdsdio_chip_attach(struct dhd_bus *bus, void *regs);
+-static void dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase);
+-static void dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus,
+-					u32 drivestrength);
+-static void dhdsdio_chip_detach(struct dhd_bus *bus);
+-
+-/* Packet free applicable unconditionally for sdio and sdspi.
+- * Conditional if bufpool was present for gspi bus.
+- */
+-static void dhdsdio_pktfree2(dhd_bus_t *bus, struct sk_buff *pkt)
+-{
+-	dhd_os_sdlock_rxq(bus->dhd);
+-	if ((bus->bus != SPI_BUS) || bus->usebufpool)
+-		bcm_pkt_buf_free_skb(pkt);
+-	dhd_os_sdunlock_rxq(bus->dhd);
+-}
+-
+-static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size)
+-{
+-	s32 min_size = DONGLE_MIN_MEMSIZE;
+-	/* Restrict the memsize to user specified limit */
+-	DHD_ERROR(("user: Restrict the dongle ram size to %d, min %d\n",
+-		dhd_dongle_memsize, min_size));
+-	if ((dhd_dongle_memsize > min_size) &&
+-	    (dhd_dongle_memsize < (s32) bus->orig_ramsize))
+-		bus->ramsize = dhd_dongle_memsize;
+-}
+-
+-static int dhdsdio_set_siaddr_window(dhd_bus_t *bus, u32 address)
+-{
+-	int err = 0;
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+-			 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+-				 (address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+-	if (!err)
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+-				 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
+-				 &err);
+-	return err;
+-}
+-
+-/* Turn backplane clock on or off */
+-static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok)
+-{
+-	int err;
+-	u8 clkctl, clkreq, devctl;
+-	bcmsdh_info_t *sdh;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#if defined(OOB_INTR_ONLY)
+-	pendok = false;
+-#endif
+-	clkctl = 0;
+-	sdh = bus->sdh;
+-
+-	if (on) {
+-		/* Request HT Avail */
+-		clkreq =
+-		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
+-
+-		if ((bus->ci->chip == BCM4329_CHIP_ID)
+-		    && (bus->ci->chiprev == 0))
+-			clkreq |= SBSDIO_FORCE_ALP;
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 clkreq, &err);
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail request error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-
+-		if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+-			       && (bus->ci->buscorerev == 9))) {
+-			u32 dummy, retries;
+-			R_SDREG(dummy, &bus->regs->clockctlstatus, retries);
+-		}
+-
+-		/* Check current status */
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail read error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-
+-		/* Go to pending and await interrupt if appropriate */
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) {
+-			/* Allow only clock-available interrupt */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			if (err) {
+-				DHD_ERROR(("%s: Devctl error setting CA: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-
+-			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-			DHD_INFO(("CLKCTL: set PENDING\n"));
+-			bus->clkstate = CLK_PENDING;
+-
+-			return 0;
+-		} else if (bus->clkstate == CLK_PENDING) {
+-			/* Cancel CA-only interrupt filter */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-		}
+-
+-		/* Otherwise, wait here (polling) for HT Avail */
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+-			SPINWAIT_SLEEP(sdioh_spinwait_sleep,
+-				       ((clkctl =
+-					 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						 SBSDIO_FUNC1_CHIPCLKCSR,
+-							 &err)),
+-					!SBSDIO_CLKAV(clkctl, bus->alp_only)),
+-				       PMU_MAX_TRANSITION_DLY);
+-		}
+-		if (err) {
+-			DHD_ERROR(("%s: HT Avail request error: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
+-			DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n",
+-				   __func__, PMU_MAX_TRANSITION_DLY, clkctl));
+-			return -EBADE;
+-		}
+-
+-		/* Mark clock available */
+-		bus->clkstate = CLK_AVAIL;
+-		DHD_INFO(("CLKCTL: turned ON\n"));
+-
+-#if defined(DHD_DEBUG)
+-		if (bus->alp_only == true) {
+-#if !defined(BCMLXSDMMC)
+-			if (!SBSDIO_ALPONLY(clkctl)) {
+-				DHD_ERROR(("%s: HT Clock, when ALP Only\n",
+-					   __func__));
+-			}
+-#endif				/* !defined(BCMLXSDMMC) */
+-		} else {
+-			if (SBSDIO_ALPONLY(clkctl)) {
+-				DHD_ERROR(("%s: HT Clock should be on.\n",
+-					   __func__));
+-			}
+-		}
+-#endif				/* defined (DHD_DEBUG) */
+-
+-		bus->activity = true;
+-	} else {
+-		clkreq = 0;
+-
+-		if (bus->clkstate == CLK_PENDING) {
+-			/* Cancel CA-only interrupt filter */
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-		}
+-
+-		bus->clkstate = CLK_SDONLY;
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 clkreq, &err);
+-		DHD_INFO(("CLKCTL: turned OFF\n"));
+-		if (err) {
+-			DHD_ERROR(("%s: Failed access turning clock off: %d\n",
+-				   __func__, err));
+-			return -EBADE;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/* Change idle/active SD state */
+-static int dhdsdio_sdclk(dhd_bus_t *bus, bool on)
+-{
+-	int err;
+-	s32 iovalue;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (on) {
+-		if (bus->idleclock == DHD_IDLE_STOP) {
+-			/* Turn on clock and restore mode */
+-			iovalue = 1;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error enabling sd_clock: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-
+-			iovalue = bus->sd_mode;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error changing sd_mode: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+-			/* Restore clock speed */
+-			iovalue = bus->sd_divisor;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error restoring sd_divisor: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-		}
+-		bus->clkstate = CLK_SDONLY;
+-	} else {
+-		/* Stop or slow the SD clock itself */
+-		if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) {
+-			DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n",
+-				   __func__, bus->sd_divisor, bus->sd_mode));
+-			return -EBADE;
+-		}
+-		if (bus->idleclock == DHD_IDLE_STOP) {
+-			if (sd1idle) {
+-				/* Change to SD1 mode and turn off clock */
+-				iovalue = 1;
+-				err =
+-				    bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL,
+-						    0, &iovalue,
+-						    sizeof(iovalue), true);
+-				if (err) {
+-					DHD_ERROR(("%s: error changing sd_clock: %d\n",
+-						__func__, err));
+-					return -EBADE;
+-				}
+-			}
+-
+-			iovalue = 0;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error disabling sd_clock: %d\n",
+-					   __func__, err));
+-				return -EBADE;
+-			}
+-		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
+-			/* Set divisor to idle value */
+-			iovalue = bus->idleclock;
+-			err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					      &iovalue, sizeof(iovalue), true);
+-			if (err) {
+-				DHD_ERROR(("%s: error changing sd_divisor: %d\n",
+-					__func__, err));
+-				return -EBADE;
+-			}
+-		}
+-		bus->clkstate = CLK_NONE;
+-	}
+-
+-	return 0;
+-}
+-
+-/* Transition SD and backplane clock readiness */
+-static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
+-{
+-#ifdef DHD_DEBUG
+-	uint oldstate = bus->clkstate;
+-#endif				/* DHD_DEBUG */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Early exit if we're already there */
+-	if (bus->clkstate == target) {
+-		if (target == CLK_AVAIL) {
+-			dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-			bus->activity = true;
+-		}
+-		return 0;
+-	}
+-
+-	switch (target) {
+-	case CLK_AVAIL:
+-		/* Make sure SD clock is available */
+-		if (bus->clkstate == CLK_NONE)
+-			dhdsdio_sdclk(bus, true);
+-		/* Now request HT Avail on the backplane */
+-		dhdsdio_htclk(bus, true, pendok);
+-		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-		bus->activity = true;
+-		break;
+-
+-	case CLK_SDONLY:
+-		/* Remove HT request, or bring up SD clock */
+-		if (bus->clkstate == CLK_NONE)
+-			dhdsdio_sdclk(bus, true);
+-		else if (bus->clkstate == CLK_AVAIL)
+-			dhdsdio_htclk(bus, false, false);
+-		else
+-			DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n",
+-				   bus->clkstate, target));
+-		dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-		break;
+-
+-	case CLK_NONE:
+-		/* Make sure to remove HT request */
+-		if (bus->clkstate == CLK_AVAIL)
+-			dhdsdio_htclk(bus, false, false);
+-		/* Now remove the SD clock */
+-		dhdsdio_sdclk(bus, false);
+-		dhd_os_wd_timer(bus->dhd, 0);
+-		break;
+-	}
+-#ifdef DHD_DEBUG
+-	DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
+-#endif				/* DHD_DEBUG */
+-
+-	return 0;
+-}
+-
+-int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-
+-	DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n",
+-		  (sleep ? "SLEEP" : "WAKE"),
+-		  (bus->sleeping ? "SLEEP" : "WAKE")));
+-
+-	/* Done if we're already in the requested state */
+-	if (sleep == bus->sleeping)
+-		return 0;
+-
+-	/* Going to sleep: set the alarm and turn off the lights... */
+-	if (sleep) {
+-		/* Don't sleep if something is pending */
+-		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
+-			return -EBUSY;
+-
+-		/* Disable SDIO interrupts (no longer interested) */
+-		bcmsdh_intr_disable(bus->sdh);
+-
+-		/* Make sure the controller has the bus up */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		/* Tell device to start using OOB wakeup */
+-		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
+-
+-		/* Turn off our contribution to the HT clock request */
+-		dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
+-
+-		/* Isolate the bus */
+-		if (bus->ci->chip != BCM4329_CHIP_ID
+-		    && bus->ci->chip != BCM4319_CHIP_ID) {
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 SBSDIO_DEVCTL_PADS_ISO, NULL);
+-		}
+-
+-		/* Change state */
+-		bus->sleeping = true;
+-
+-	} else {
+-		/* Waking up: bus power up is ok, set local state */
+-
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 0, NULL);
+-
+-		/* Force pad isolation off if possible
+-			 (in case power never toggled) */
+-		if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+-		    && (bus->ci->buscorerev >= 10))
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0,
+-					 NULL);
+-
+-		/* Make sure the controller has the bus up */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		/* Send misc interrupt to indicate OOB not needed */
+-		W_SDREG(0, &regs->tosbmailboxdata, retries);
+-		if (retries <= retry_limit)
+-			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+-
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"));
+-
+-		/* Make sure we have SD bus access */
+-		dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-		/* Change state */
+-		bus->sleeping = false;
+-
+-		/* Enable interrupts again */
+-		if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) {
+-			bus->intdis = false;
+-			bcmsdh_intr_enable(bus->sdh);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-#if defined(OOB_INTR_ONLY)
+-void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable)
+-{
+-#if defined(HW_OOB)
+-	bcmsdh_enable_hw_oob_intr(bus->sdh, enable);
+-#else
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	if (enable == true) {
+-
+-		/* Tell device to start using OOB wakeup */
+-		W_SDREG(SMB_USE_OOB, &regs->tosbmailbox, retries);
+-		if (retries > retry_limit)
+-			DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"));
+-
+-	} else {
+-		/* Send misc interrupt to indicate OOB not needed */
+-		W_SDREG(0, &regs->tosbmailboxdata, retries);
+-		if (retries <= retry_limit)
+-			W_SDREG(SMB_DEV_INT, &regs->tosbmailbox, retries);
+-	}
+-
+-	/* Turn off our contribution to the HT clock request */
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-#endif				/* !defined(HW_OOB) */
+-}
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-#define BUS_WAKE(bus) \
+-	do { \
+-		if ((bus)->sleeping) \
+-			dhdsdio_bussleep((bus), false); \
+-	} while (0);
+-
+-/* Writes a HW/SW header into the packet and sends it. */
+-/* Assumes: (a) header space already there, (b) caller holds lock */
+-static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan,
+-			 bool free_pkt)
+-{
+-	int ret;
+-	u8 *frame;
+-	u16 len, pad = 0;
+-	u32 swheader;
+-	uint retries = 0;
+-	bcmsdh_info_t *sdh;
+-	struct sk_buff *new;
+-	int i;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	sdh = bus->sdh;
+-
+-	if (bus->dhd->dongle_reset) {
+-		ret = -EPERM;
+-		goto done;
+-	}
+-
+-	frame = (u8 *) (pkt->data);
+-
+-	/* Add alignment padding, allocate new packet if needed */
+-	pad = ((unsigned long)frame % DHD_SDALIGN);
+-	if (pad) {
+-		if (skb_headroom(pkt) < pad) {
+-			DHD_INFO(("%s: insufficient headroom %d for %d pad\n",
+-				  __func__, skb_headroom(pkt), pad));
+-			bus->dhd->tx_realloc++;
+-			new = bcm_pkt_buf_get_skb(pkt->len + DHD_SDALIGN);
+-			if (!new) {
+-				DHD_ERROR(("%s: couldn't allocate new %d-byte "
+-					"packet\n",
+-					__func__, pkt->len + DHD_SDALIGN));
+-				ret = -ENOMEM;
+-				goto done;
+-			}
+-
+-			PKTALIGN(new, pkt->len, DHD_SDALIGN);
+-			memcpy(new->data, pkt->data, pkt->len);
+-			if (free_pkt)
+-				bcm_pkt_buf_free_skb(pkt);
+-			/* free the pkt if canned one is not used */
+-			free_pkt = true;
+-			pkt = new;
+-			frame = (u8 *) (pkt->data);
+-			ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0);
+-			pad = 0;
+-		} else {
+-			skb_push(pkt, pad);
+-			frame = (u8 *) (pkt->data);
+-
+-			ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len));
+-			memset(frame, 0, pad + SDPCM_HDRLEN);
+-		}
+-	}
+-	ASSERT(pad < DHD_SDALIGN);
+-
+-	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+-	len = (u16) (pkt->len);
+-	*(u16 *) frame = cpu_to_le16(len);
+-	*(((u16 *) frame) + 1) = cpu_to_le16(~len);
+-
+-	/* Software tag: channel, sequence number, data offset */
+-	swheader =
+-	    ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq |
+-	    (((pad +
+-	       SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK);
+-
+-	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
+-	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+-
+-#ifdef DHD_DEBUG
+-	tx_packets[pkt->priority]++;
+-	if (DHD_BYTES_ON() &&
+-	    (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
+-	      (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
+-		printk(KERN_DEBUG "Tx Frame:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
+-	} else if (DHD_HDRS_ON()) {
+-		printk(KERN_DEBUG "TxHdr:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-				     frame, min_t(u16, len, 16));
+-	}
+-#endif
+-
+-	/* Raise len to next SDIO block to eliminate tail command */
+-	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+-		u16 pad = bus->blocksize - (len % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize))
+-#ifdef NOTUSED
+-			if (pad <= skb_tailroom(pkt))
+-#endif				/* NOTUSED */
+-				len += pad;
+-	} else if (len % DHD_SDALIGN) {
+-		len += DHD_SDALIGN - (len % DHD_SDALIGN);
+-	}
+-
+-	/* Some controllers have trouble with odd bytes -- round to even */
+-	if (forcealign && (len & (ALIGNMENT - 1))) {
+-#ifdef NOTUSED
+-		if (skb_tailroom(pkt))
+-#endif
+-			len = roundup(len, ALIGNMENT);
+-#ifdef NOTUSED
+-		else
+-			DHD_ERROR(("%s: sending unrounded %d-byte packet\n",
+-				   __func__, len));
+-#endif
+-	}
+-
+-	do {
+-		ret =
+-		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, frame, len, pkt, NULL, NULL);
+-		bus->f2txdata++;
+-		ASSERT(ret != -BCME_PENDING);
+-
+-		if (ret < 0) {
+-			/* On failure, abort the command
+-			 and terminate the frame */
+-			DHD_INFO(("%s: sdio error %d, abort command and "
+-				"terminate frame.\n", __func__, ret));
+-			bus->tx_sderrs++;
+-
+-			bcmsdh_abort(sdh, SDIO_FUNC_2);
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
+-					 NULL);
+-			bus->f1regdata++;
+-
+-			for (i = 0; i < 3; i++) {
+-				u8 hi, lo;
+-				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCHI,
+-						     NULL);
+-				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCLO,
+-						     NULL);
+-				bus->f1regdata += 2;
+-				if ((hi == 0) && (lo == 0))
+-					break;
+-			}
+-
+-		}
+-		if (ret == 0)
+-			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-
+-	} while ((ret < 0) && retrydata && retries++ < TXRETRIES);
+-
+-done:
+-	/* restore pkt buffer pointer before calling tx complete routine */
+-	skb_pull(pkt, SDPCM_HDRLEN + pad);
+-	dhd_os_sdunlock(bus->dhd);
+-	dhd_txcomplete(bus->dhd, pkt, ret != 0);
+-	dhd_os_sdlock(bus->dhd);
+-
+-	if (free_pkt)
+-		bcm_pkt_buf_free_skb(pkt);
+-
+-	return ret;
+-}
+-
+-int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt)
+-{
+-	int ret = -EBADE;
+-	uint datalen, prec;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	datalen = pkt->len;
+-
+-#ifdef SDTEST
+-	/* Push the test header if doing loopback */
+-	if (bus->ext_loop) {
+-		u8 *data;
+-		skb_push(pkt, SDPCM_TEST_HDRLEN);
+-		data = pkt->data;
+-		*data++ = SDPCM_TEST_ECHOREQ;
+-		*data++ = (u8) bus->loopid++;
+-		*data++ = (datalen >> 0);
+-		*data++ = (datalen >> 8);
+-		datalen += SDPCM_TEST_HDRLEN;
+-	}
+-#endif				/* SDTEST */
+-
+-	/* Add space for the header */
+-	skb_push(pkt, SDPCM_HDRLEN);
+-	ASSERT(IS_ALIGNED((unsigned long)(pkt->data), 2));
+-
+-	prec = PRIO2PREC((pkt->priority & PRIOMASK));
+-
+-	/* Check for existing queue, current flow-control,
+-			 pending event, or pending clock */
+-	if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq)
+-	    || bus->dpc_sched || (!DATAOK(bus))
+-	    || (bus->flowcontrol & NBITVAL(prec))
+-	    || (bus->clkstate != CLK_AVAIL)) {
+-		DHD_TRACE(("%s: deferring pktq len %d\n", __func__,
+-			   pktq_len(&bus->txq)));
+-		bus->fcqueued++;
+-
+-		/* Priority based enq */
+-		dhd_os_sdlock_txq(bus->dhd);
+-		if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) {
+-			skb_pull(pkt, SDPCM_HDRLEN);
+-			dhd_txcomplete(bus->dhd, pkt, false);
+-			bcm_pkt_buf_free_skb(pkt);
+-			DHD_ERROR(("%s: out of bus->txq !!!\n", __func__));
+-			ret = -ENOSR;
+-		} else {
+-			ret = 0;
+-		}
+-		dhd_os_sdunlock_txq(bus->dhd);
+-
+-		if (pktq_len(&bus->txq) >= TXHI)
+-			dhd_txflowcontrol(bus->dhd, 0, ON);
+-
+-#ifdef DHD_DEBUG
+-		if (pktq_plen(&bus->txq, prec) > qcount[prec])
+-			qcount[prec] = pktq_plen(&bus->txq, prec);
+-#endif
+-		/* Schedule DPC if needed to send queued packet(s) */
+-		if (dhd_deferred_tx && !bus->dpc_sched) {
+-			bus->dpc_sched = true;
+-			dhd_sched_dpc(bus->dhd);
+-		}
+-	} else {
+-		/* Lock: we're about to use shared data/code (and SDIO) */
+-		dhd_os_sdlock(bus->dhd);
+-
+-		/* Otherwise, send it now */
+-		BUS_WAKE(bus);
+-		/* Make sure back plane ht clk is on, no pending allowed */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, true);
+-
+-#ifndef SDTEST
+-		DHD_TRACE(("%s: calling txpkt\n", __func__));
+-		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
+-#else
+-		ret = dhdsdio_txpkt(bus, pkt,
+-				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
+-				     SDPCM_DATA_CHANNEL), true);
+-#endif
+-		if (ret)
+-			bus->dhd->tx_errors++;
+-		else
+-			bus->dhd->dstats.tx_bytes += datalen;
+-
+-		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-			bus->activity = false;
+-			dhdsdio_clkctl(bus, CLK_NONE, true);
+-		}
+-
+-		dhd_os_sdunlock(bus->dhd);
+-	}
+-
+-	return ret;
+-}
+-
+-static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
+-{
+-	struct sk_buff *pkt;
+-	u32 intstatus = 0;
+-	uint retries = 0;
+-	int ret = 0, prec_out;
+-	uint cnt = 0;
+-	uint datalen;
+-	u8 tx_prec_map;
+-
+-	dhd_pub_t *dhd = bus->dhd;
+-	sdpcmd_regs_t *regs = bus->regs;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	tx_prec_map = ~bus->flowcontrol;
+-
+-	/* Send frames until the limit or some other event */
+-	for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
+-		dhd_os_sdlock_txq(bus->dhd);
+-		pkt = bcm_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
+-		if (pkt == NULL) {
+-			dhd_os_sdunlock_txq(bus->dhd);
+-			break;
+-		}
+-		dhd_os_sdunlock_txq(bus->dhd);
+-		datalen = pkt->len - SDPCM_HDRLEN;
+-
+-#ifndef SDTEST
+-		ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true);
+-#else
+-		ret = dhdsdio_txpkt(bus, pkt,
+-				    (bus->ext_loop ? SDPCM_TEST_CHANNEL :
+-				     SDPCM_DATA_CHANNEL), true);
+-#endif
+-		if (ret)
+-			bus->dhd->tx_errors++;
+-		else
+-			bus->dhd->dstats.tx_bytes += datalen;
+-
+-		/* In poll mode, need to check for other events */
+-		if (!bus->intr && cnt) {
+-			/* Check device status, signal pending interrupt */
+-			R_SDREG(intstatus, &regs->intstatus, retries);
+-			bus->f2txdata++;
+-			if (bcmsdh_regfail(bus->sdh))
+-				break;
+-			if (intstatus & bus->hostintmask)
+-				bus->ipend = true;
+-		}
+-	}
+-
+-	/* Deflow-control stack if needed */
+-	if (dhd->up && (dhd->busstate == DHD_BUS_DATA) &&
+-	    dhd->txoff && (pktq_len(&bus->txq) < TXLOW))
+-		dhd_txflowcontrol(dhd, 0, OFF);
+-
+-	return cnt;
+-}
+-
+-int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
+-{
+-	u8 *frame;
+-	u16 len;
+-	u32 swheader;
+-	uint retries = 0;
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	u8 doff = 0;
+-	int ret = -1;
+-	int i;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->dongle_reset)
+-		return -EIO;
+-
+-	/* Back the pointer to make a room for bus header */
+-	frame = msg - SDPCM_HDRLEN;
+-	len = (msglen += SDPCM_HDRLEN);
+-
+-	/* Add alignment padding (optional for ctl frames) */
+-	if (dhd_alignctl) {
+-		doff = ((unsigned long)frame % DHD_SDALIGN);
+-		if (doff) {
+-			frame -= doff;
+-			len += doff;
+-			msglen += doff;
+-			memset(frame, 0, doff + SDPCM_HDRLEN);
+-		}
+-		ASSERT(doff < DHD_SDALIGN);
+-	}
+-	doff += SDPCM_HDRLEN;
+-
+-	/* Round send length to next SDIO block */
+-	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
+-		u16 pad = bus->blocksize - (len % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize))
+-			len += pad;
+-	} else if (len % DHD_SDALIGN) {
+-		len += DHD_SDALIGN - (len % DHD_SDALIGN);
+-	}
+-
+-	/* Satisfy length-alignment requirements */
+-	if (forcealign && (len & (ALIGNMENT - 1)))
+-		len = roundup(len, ALIGNMENT);
+-
+-	ASSERT(IS_ALIGNED((unsigned long)frame, 2));
+-
+-	/* Need to lock here to protect txseq and SDIO tx calls */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	BUS_WAKE(bus);
+-
+-	/* Make sure backplane clock is on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
+-	*(u16 *) frame = cpu_to_le16((u16) msglen);
+-	*(((u16 *) frame) + 1) = cpu_to_le16(~msglen);
+-
+-	/* Software tag: channel, sequence number, data offset */
+-	swheader =
+-	    ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
+-	     SDPCM_CHANNEL_MASK)
+-	    | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
+-			     SDPCM_DOFFSET_MASK);
+-	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
+-	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
+-
+-	if (!DATAOK(bus)) {
+-		DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n",
+-			  __func__, bus->tx_max, bus->tx_seq));
+-		bus->ctrl_frame_stat = true;
+-		/* Send from dpc */
+-		bus->ctrl_frame_buf = frame;
+-		bus->ctrl_frame_len = len;
+-
+-		dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+-
+-		if (bus->ctrl_frame_stat == false) {
+-			DHD_INFO(("%s: ctrl_frame_stat == false\n", __func__));
+-			ret = 0;
+-		} else {
+-			DHD_INFO(("%s: ctrl_frame_stat == true\n", __func__));
+-			ret = -1;
+-		}
+-	}
+-
+-	if (ret == -1) {
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+-			printk(KERN_DEBUG "Tx Frame:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     frame, len);
+-		} else if (DHD_HDRS_ON()) {
+-			printk(KERN_DEBUG "TxHdr:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     frame, min_t(u16, len, 16));
+-		}
+-#endif
+-
+-		do {
+-			bus->ctrl_frame_stat = false;
+-			ret =
+-			    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh),
+-						SDIO_FUNC_2, F2SYNC, frame, len,
+-						NULL, NULL, NULL);
+-
+-			ASSERT(ret != -BCME_PENDING);
+-
+-			if (ret < 0) {
+-				/* On failure, abort the command and
+-				 terminate the frame */
+-				DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n",
+-					__func__, ret));
+-				bus->tx_sderrs++;
+-
+-				bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-				bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-						 SBSDIO_FUNC1_FRAMECTRL,
+-						 SFC_WF_TERM, NULL);
+-				bus->f1regdata++;
+-
+-				for (i = 0; i < 3; i++) {
+-					u8 hi, lo;
+-					hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-					     SBSDIO_FUNC1_WFRAMEBCHI,
+-					     NULL);
+-					lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-					     SBSDIO_FUNC1_WFRAMEBCLO,
+-							     NULL);
+-					bus->f1regdata += 2;
+-					if ((hi == 0) && (lo == 0))
+-						break;
+-				}
+-
+-			}
+-			if (ret == 0) {
+-				bus->tx_seq =
+-				    (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-			}
+-		} while ((ret < 0) && retries++ < TXRETRIES);
+-	}
+-
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (ret)
+-		bus->dhd->tx_ctlerrs++;
+-	else
+-		bus->dhd->tx_ctlpkts++;
+-
+-	return ret ? -EIO : 0;
+-}
+-
+-int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen)
+-{
+-	int timeleft;
+-	uint rxlen = 0;
+-	bool pending;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->dongle_reset)
+-		return -EIO;
+-
+-	/* Wait until control frame is available */
+-	timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending);
+-
+-	dhd_os_sdlock(bus->dhd);
+-	rxlen = bus->rxlen;
+-	memcpy(msg, bus->rxctl, min(msglen, rxlen));
+-	bus->rxlen = 0;
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (rxlen) {
+-		DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
+-			 __func__, rxlen, msglen));
+-	} else if (timeleft == 0) {
+-		DHD_ERROR(("%s: resumed on timeout\n", __func__));
+-#ifdef DHD_DEBUG
+-		dhd_os_sdlock(bus->dhd);
+-		dhdsdio_checkdied(bus, NULL, 0);
+-		dhd_os_sdunlock(bus->dhd);
+-#endif				/* DHD_DEBUG */
+-	} else if (pending == true) {
+-		DHD_CTL(("%s: cancelled\n", __func__));
+-		return -ERESTARTSYS;
+-	} else {
+-		DHD_CTL(("%s: resumed for unknown reason?\n", __func__));
+-#ifdef DHD_DEBUG
+-		dhd_os_sdlock(bus->dhd);
+-		dhdsdio_checkdied(bus, NULL, 0);
+-		dhd_os_sdunlock(bus->dhd);
+-#endif				/* DHD_DEBUG */
+-	}
+-
+-	if (rxlen)
+-		bus->dhd->rx_ctlpkts++;
+-	else
+-		bus->dhd->rx_ctlerrs++;
+-
+-	return rxlen ? (int)rxlen : -ETIMEDOUT;
+-}
+-
+-/* IOVar table */
+-enum {
+-	IOV_INTR = 1,
+-	IOV_POLLRATE,
+-	IOV_SDREG,
+-	IOV_SBREG,
+-	IOV_SDCIS,
+-	IOV_MEMBYTES,
+-	IOV_MEMSIZE,
+-#ifdef DHD_DEBUG
+-	IOV_CHECKDIED,
+-#endif
+-	IOV_DOWNLOAD,
+-	IOV_FORCEEVEN,
+-	IOV_SDIOD_DRIVE,
+-	IOV_READAHEAD,
+-	IOV_SDRXCHAIN,
+-	IOV_ALIGNCTL,
+-	IOV_SDALIGN,
+-	IOV_DEVRESET,
+-	IOV_CPU,
+-#ifdef SDTEST
+-	IOV_PKTGEN,
+-	IOV_EXTLOOP,
+-#endif				/* SDTEST */
+-	IOV_SPROM,
+-	IOV_TXBOUND,
+-	IOV_RXBOUND,
+-	IOV_TXMINMAX,
+-	IOV_IDLETIME,
+-	IOV_IDLECLOCK,
+-	IOV_SD1IDLE,
+-	IOV_SLEEP,
+-	IOV_VARS
+-};
+-
+-const bcm_iovar_t dhdsdio_iovars[] = {
+-	{"intr", IOV_INTR, 0, IOVT_BOOL, 0},
+-	{"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0},
+-	{"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0},
+-	{"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0},
+-	{"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0},
+-	{"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0},
+-	{"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)},
+-	{"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0},
+-	{"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0},
+-	{"vars", IOV_VARS, 0, IOVT_BUFFER, 0},
+-	{"sdiod_drive", IOV_SDIOD_DRIVE, 0, IOVT_UINT32, 0},
+-	{"readahead", IOV_READAHEAD, 0, IOVT_BOOL, 0},
+-	{"sdrxchain", IOV_SDRXCHAIN, 0, IOVT_BOOL, 0},
+-	{"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0},
+-	{"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0},
+-	{"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0},
+-#ifdef DHD_DEBUG
+-	{"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t)}
+-	,
+-	{"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN}
+-	,
+-	{"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0}
+-	,
+-	{"txbound", IOV_TXBOUND, 0, IOVT_UINT32, 0}
+-	,
+-	{"rxbound", IOV_RXBOUND, 0, IOVT_UINT32, 0}
+-	,
+-	{"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0}
+-	,
+-	{"cpu", IOV_CPU, 0, IOVT_BOOL, 0}
+-	,
+-#ifdef DHD_DEBUG
+-	{"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0}
+-	,
+-#endif				/* DHD_DEBUG  */
+-#endif				/* DHD_DEBUG */
+-#ifdef SDTEST
+-	{"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0}
+-	,
+-	{"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t)}
+-	,
+-#endif				/* SDTEST */
+-
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-static void
+-dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div)
+-{
+-	uint q1, q2;
+-
+-	if (!div) {
+-		bcm_bprintf(strbuf, "%s N/A", desc);
+-	} else {
+-		q1 = num / div;
+-		q2 = (100 * (num - (q1 * div))) / div;
+-		bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2);
+-	}
+-}
+-
+-void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-
+-	bcm_bprintf(strbuf, "Bus SDIO structure:\n");
+-	bcm_bprintf(strbuf,
+-		    "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n",
+-		    bus->hostintmask, bus->intstatus, bus->sdpcm_ver);
+-	bcm_bprintf(strbuf,
+-		    "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n",
+-		    bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max,
+-		    bus->rxskip, bus->rxlen, bus->rx_seq);
+-	bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n",
+-		    bus->intr, bus->intrcount, bus->lastintrs, bus->spurious);
+-	bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n",
+-		    bus->pollrate, bus->pollcnt, bus->regfails);
+-
+-	bcm_bprintf(strbuf, "\nAdditional counters:\n");
+-	bcm_bprintf(strbuf,
+-		    "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n",
+-		    bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong,
+-		    bus->rxc_errors);
+-	bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n",
+-		    bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq);
+-	bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", bus->fc_rcvd,
+-		    bus->fc_xoff, bus->fc_xon);
+-	bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n",
+-		    bus->rxglomfail, bus->rxglomframes, bus->rxglompkts);
+-	bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n",
+-		    (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs,
+-		    bus->f2rxdata, bus->f2txdata, bus->f1regdata);
+-	{
+-		dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets,
+-			     (bus->f2rxhdrs + bus->f2rxdata));
+-		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets,
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets,
+-			     (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets,
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts),
+-			     bus->dhd->rx_packets);
+-		dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts,
+-			     bus->rxglomframes);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets,
+-			     bus->f2txdata);
+-		dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets,
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets,
+-			     (bus->f2txdata + bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets,
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n");
+-
+-		dhd_dump_pct(strbuf, "Total: pkts/f2rw",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata));
+-		dhd_dump_pct(strbuf, ", pkts/f1sd",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     bus->f1regdata);
+-		dhd_dump_pct(strbuf, ", pkts/sd",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata +
+-			      bus->f1regdata));
+-		dhd_dump_pct(strbuf, ", pkts/int",
+-			     (bus->dhd->tx_packets + bus->dhd->rx_packets),
+-			     bus->intrcount);
+-		bcm_bprintf(strbuf, "\n\n");
+-	}
+-
+-#ifdef SDTEST
+-	if (bus->pktgen_count) {
+-		bcm_bprintf(strbuf, "pktgen config and count:\n");
+-		bcm_bprintf(strbuf,
+-			    "freq %d count %d print %d total %d min %d len %d\n",
+-			    bus->pktgen_freq, bus->pktgen_count,
+-			    bus->pktgen_print, bus->pktgen_total,
+-			    bus->pktgen_minlen, bus->pktgen_maxlen);
+-		bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n",
+-			    bus->pktgen_sent, bus->pktgen_rcvd,
+-			    bus->pktgen_fail);
+-	}
+-#endif				/* SDTEST */
+-#ifdef DHD_DEBUG
+-	bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n",
+-		    bus->dpc_sched,
+-		    (bcmsdh_intr_pending(bus->sdh) ? " " : " not "));
+-	bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize,
+-		    bus->roundup);
+-#endif				/* DHD_DEBUG */
+-	bcm_bprintf(strbuf,
+-		    "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n",
+-		    bus->clkstate, bus->activity, bus->idletime, bus->idlecount,
+-		    bus->sleeping);
+-}
+-
+-void dhd_bus_clearcounts(dhd_pub_t *dhdp)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *) dhdp->bus;
+-
+-	bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0;
+-	bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0;
+-	bus->rx_hdrfail = bus->rx_badhdr = bus->rx_badseq = 0;
+-	bus->tx_sderrs = bus->fc_rcvd = bus->fc_xoff = bus->fc_xon = 0;
+-	bus->rxglomfail = bus->rxglomframes = bus->rxglompkts = 0;
+-	bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0;
+-}
+-
+-#ifdef SDTEST
+-static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg)
+-{
+-	dhd_pktgen_t pktgen;
+-
+-	pktgen.version = DHD_PKTGEN_VERSION;
+-	pktgen.freq = bus->pktgen_freq;
+-	pktgen.count = bus->pktgen_count;
+-	pktgen.print = bus->pktgen_print;
+-	pktgen.total = bus->pktgen_total;
+-	pktgen.minlen = bus->pktgen_minlen;
+-	pktgen.maxlen = bus->pktgen_maxlen;
+-	pktgen.numsent = bus->pktgen_sent;
+-	pktgen.numrcvd = bus->pktgen_rcvd;
+-	pktgen.numfail = bus->pktgen_fail;
+-	pktgen.mode = bus->pktgen_mode;
+-	pktgen.stop = bus->pktgen_stop;
+-
+-	memcpy(arg, &pktgen, sizeof(pktgen));
+-
+-	return 0;
+-}
+-
+-static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg)
+-{
+-	dhd_pktgen_t pktgen;
+-	uint oldcnt, oldmode;
+-
+-	memcpy(&pktgen, arg, sizeof(pktgen));
+-	if (pktgen.version != DHD_PKTGEN_VERSION)
+-		return -EINVAL;
+-
+-	oldcnt = bus->pktgen_count;
+-	oldmode = bus->pktgen_mode;
+-
+-	bus->pktgen_freq = pktgen.freq;
+-	bus->pktgen_count = pktgen.count;
+-	bus->pktgen_print = pktgen.print;
+-	bus->pktgen_total = pktgen.total;
+-	bus->pktgen_minlen = pktgen.minlen;
+-	bus->pktgen_maxlen = pktgen.maxlen;
+-	bus->pktgen_mode = pktgen.mode;
+-	bus->pktgen_stop = pktgen.stop;
+-
+-	bus->pktgen_tick = bus->pktgen_ptick = 0;
+-	bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen);
+-	bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen);
+-
+-	/* Clear counts for a new pktgen (mode change, or was stopped) */
+-	if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode))
+-		bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0;
+-
+-	return 0;
+-}
+-#endif				/* SDTEST */
+-
+-static int
+-dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data,
+-		 uint size)
+-{
+-	int bcmerror = 0;
+-	u32 sdaddr;
+-	uint dsize;
+-
+-	/* Determine initial transfer parameters */
+-	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
+-	if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
+-		dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
+-	else
+-		dsize = size;
+-
+-	/* Set the backplane window to include the start address */
+-	bcmerror = dhdsdio_set_siaddr_window(bus, address);
+-	if (bcmerror) {
+-		DHD_ERROR(("%s: window change failed\n", __func__));
+-		goto xfer_done;
+-	}
+-
+-	/* Do the transfer(s) */
+-	while (size) {
+-		DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n",
+-			  __func__, (write ? "write" : "read"), dsize,
+-			  sdaddr, (address & SBSDIO_SBWINDOW_MASK)));
+-		bcmerror =
+-		     bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: membytes transfer failed\n", __func__));
+-			break;
+-		}
+-
+-		/* Adjust for next transfer (if any) */
+-		size -= dsize;
+-		if (size) {
+-			data += dsize;
+-			address += dsize;
+-			bcmerror = dhdsdio_set_siaddr_window(bus, address);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: window change failed\n",
+-					   __func__));
+-				break;
+-			}
+-			sdaddr = 0;
+-			dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
+-		}
+-	}
+-
+-xfer_done:
+-	/* Return the window to backplane enumeration space for core access */
+-	if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) {
+-		DHD_ERROR(("%s: FAILED to set window back to 0x%x\n",
+-			   __func__, bcmsdh_cur_sbwad(bus->sdh)));
+-	}
+-
+-	return bcmerror;
+-}
+-
+-#ifdef DHD_DEBUG
+-static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
+-{
+-	u32 addr;
+-	int rv;
+-
+-	/* Read last word in memory to determine address of
+-			 sdpcm_shared structure */
+-	rv = dhdsdio_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, 4);
+-	if (rv < 0)
+-		return rv;
+-
+-	addr = le32_to_cpu(addr);
+-
+-	DHD_INFO(("sdpcm_shared address 0x%08X\n", addr));
+-
+-	/*
+-	 * Check if addr is valid.
+-	 * NVRAM length at the end of memory should have been overwritten.
+-	 */
+-	if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
+-		DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
+-			   __func__, addr));
+-		return -EBADE;
+-	}
+-
+-	/* Read hndrte_shared structure */
+-	rv = dhdsdio_membytes(bus, false, addr, (u8 *) sh,
+-			      sizeof(sdpcm_shared_t));
+-	if (rv < 0)
+-		return rv;
+-
+-	/* Endianness */
+-	sh->flags = le32_to_cpu(sh->flags);
+-	sh->trap_addr = le32_to_cpu(sh->trap_addr);
+-	sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr);
+-	sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr);
+-	sh->assert_line = le32_to_cpu(sh->assert_line);
+-	sh->console_addr = le32_to_cpu(sh->console_addr);
+-	sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr);
+-
+-	if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
+-		DHD_ERROR(("%s: sdpcm_shared version %d in dhd "
+-			   "is different than sdpcm_shared version %d in dongle\n",
+-			   __func__, SDPCM_SHARED_VERSION,
+-			   sh->flags & SDPCM_SHARED_VERSION_MASK));
+-		return -EBADE;
+-	}
+-
+-	return 0;
+-}
+-
+-static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size)
+-{
+-	int bcmerror = 0;
+-	uint msize = 512;
+-	char *mbuffer = NULL;
+-	uint maxstrlen = 256;
+-	char *str = NULL;
+-	trap_t tr;
+-	sdpcm_shared_t sdpcm_shared;
+-	struct bcmstrbuf strbuf;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (data == NULL) {
+-		/*
+-		 * Called after a rx ctrl timeout. "data" is NULL.
+-		 * allocate memory to trace the trap or assert.
+-		 */
+-		size = msize;
+-		mbuffer = data = kmalloc(msize, GFP_ATOMIC);
+-		if (mbuffer == NULL) {
+-			DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__,
+-				   msize));
+-			bcmerror = -ENOMEM;
+-			goto done;
+-		}
+-	}
+-
+-	str = kmalloc(maxstrlen, GFP_ATOMIC);
+-	if (str == NULL) {
+-		DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen));
+-		bcmerror = -ENOMEM;
+-		goto done;
+-	}
+-
+-	bcmerror = dhdsdio_readshared(bus, &sdpcm_shared);
+-	if (bcmerror < 0)
+-		goto done;
+-
+-	bcm_binit(&strbuf, data, size);
+-
+-	bcm_bprintf(&strbuf,
+-		    "msgtrace address : 0x%08X\nconsole address  : 0x%08X\n",
+-		    sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr);
+-
+-	if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
+-		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
+-		 * (Avoids conflict with real asserts for programmatic
+-		 * parsing of output.)
+-		 */
+-		bcm_bprintf(&strbuf, "Assrt not built in dongle\n");
+-	}
+-
+-	if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) ==
+-	    0) {
+-		/* NOTE: Misspelled assert is intentional - DO NOT FIX.
+-		 * (Avoids conflict with real asserts for programmatic
+-		 * parsing of output.)
+-		 */
+-		bcm_bprintf(&strbuf, "No trap%s in dongle",
+-			    (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT)
+-			    ? "/assrt" : "");
+-	} else {
+-		if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) {
+-			/* Download assert */
+-			bcm_bprintf(&strbuf, "Dongle assert");
+-			if (sdpcm_shared.assert_exp_addr != 0) {
+-				str[0] = '\0';
+-				bcmerror = dhdsdio_membytes(bus, false,
+-						sdpcm_shared.assert_exp_addr,
+-						(u8 *) str, maxstrlen);
+-				if (bcmerror < 0)
+-					goto done;
+-
+-				str[maxstrlen - 1] = '\0';
+-				bcm_bprintf(&strbuf, " expr \"%s\"", str);
+-			}
+-
+-			if (sdpcm_shared.assert_file_addr != 0) {
+-				str[0] = '\0';
+-				bcmerror = dhdsdio_membytes(bus, false,
+-						sdpcm_shared.assert_file_addr,
+-						(u8 *) str, maxstrlen);
+-				if (bcmerror < 0)
+-					goto done;
+-
+-				str[maxstrlen - 1] = '\0';
+-				bcm_bprintf(&strbuf, " file \"%s\"", str);
+-			}
+-
+-			bcm_bprintf(&strbuf, " line %d ",
+-				    sdpcm_shared.assert_line);
+-		}
+-
+-		if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+-			bcmerror = dhdsdio_membytes(bus, false,
+-					sdpcm_shared.trap_addr, (u8 *)&tr,
+-					sizeof(trap_t));
+-			if (bcmerror < 0)
+-				goto done;
+-
+-			bcm_bprintf(&strbuf,
+-				    "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x,"
+-				    "lp 0x%x, rpc 0x%x Trap offset 0x%x, "
+-				    "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n",
+-				    tr.type, tr.epc, tr.cpsr, tr.spsr, tr.r13,
+-				    tr.r14, tr.pc, sdpcm_shared.trap_addr,
+-				    tr.r0, tr.r1, tr.r2, tr.r3, tr.r4, tr.r5,
+-				    tr.r6, tr.r7);
+-		}
+-	}
+-
+-	if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP))
+-		DHD_ERROR(("%s: %s\n", __func__, strbuf.origbuf));
+-
+-#ifdef DHD_DEBUG
+-	if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) {
+-		/* Mem dump to a file on device */
+-		dhdsdio_mem_dump(bus);
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-done:
+-	kfree(mbuffer);
+-	kfree(str);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_mem_dump(dhd_bus_t *bus)
+-{
+-	int ret = 0;
+-	int size;		/* Full mem size */
+-	int start = 0;		/* Start address */
+-	int read_size = 0;	/* Read size of each iteration */
+-	u8 *buf = NULL, *databuf = NULL;
+-
+-	/* Get full mem size */
+-	size = bus->ramsize;
+-	buf = kmalloc(size, GFP_ATOMIC);
+-	if (!buf) {
+-		DHD_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size));
+-		return -1;
+-	}
+-
+-	/* Read mem content */
+-	printk(KERN_DEBUG "Dump dongle memory");
+-	databuf = buf;
+-	while (size) {
+-		read_size = min(MEMBLOCK, size);
+-		ret = dhdsdio_membytes(bus, false, start, databuf, read_size);
+-		if (ret) {
+-			DHD_ERROR(("%s: Error membytes %d\n", __func__, ret));
+-			kfree(buf);
+-			return -1;
+-		}
+-		printk(".");
+-
+-		/* Decrement size and increment start address */
+-		size -= read_size;
+-		start += read_size;
+-		databuf += read_size;
+-	}
+-	printk(KERN_DEBUG "Done\n");
+-
+-	/* free buf before return !!! */
+-	if (write_to_file(bus->dhd, buf, bus->ramsize)) {
+-		DHD_ERROR(("%s: Error writing to files\n", __func__));
+-		return -1;
+-	}
+-
+-	/* buf free handled in write_to_file, not here */
+-	return 0;
+-}
+-
+-#define CONSOLE_LINE_MAX	192
+-
+-static int dhdsdio_readconsole(dhd_bus_t *bus)
+-{
+-	dhd_console_t *c = &bus->console;
+-	u8 line[CONSOLE_LINE_MAX], ch;
+-	u32 n, idx, addr;
+-	int rv;
+-
+-	/* Don't do anything until FWREADY updates console address */
+-	if (bus->console_addr == 0)
+-		return 0;
+-
+-	/* Read console log struct */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, log);
+-	rv = dhdsdio_membytes(bus, false, addr, (u8 *)&c->log,
+-				sizeof(c->log));
+-	if (rv < 0)
+-		return rv;
+-
+-	/* Allocate console buffer (one time only) */
+-	if (c->buf == NULL) {
+-		c->bufsize = le32_to_cpu(c->log.buf_size);
+-		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
+-		if (c->buf == NULL)
+-			return -ENOMEM;
+-	}
+-
+-	idx = le32_to_cpu(c->log.idx);
+-
+-	/* Protect against corrupt value */
+-	if (idx > c->bufsize)
+-		return -EBADE;
+-
+-	/* Skip reading the console buffer if the index pointer
+-	 has not moved */
+-	if (idx == c->last)
+-		return 0;
+-
+-	/* Read the console buffer */
+-	addr = le32_to_cpu(c->log.buf);
+-	rv = dhdsdio_membytes(bus, false, addr, c->buf, c->bufsize);
+-	if (rv < 0)
+-		return rv;
+-
+-	while (c->last != idx) {
+-		for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
+-			if (c->last == idx) {
+-				/* This would output a partial line.
+-				 * Instead, back up
+-				 * the buffer pointer and output this
+-				 * line next time around.
+-				 */
+-				if (c->last >= n)
+-					c->last -= n;
+-				else
+-					c->last = c->bufsize - n;
+-				goto break2;
+-			}
+-			ch = c->buf[c->last];
+-			c->last = (c->last + 1) % c->bufsize;
+-			if (ch == '\n')
+-				break;
+-			line[n] = ch;
+-		}
+-
+-		if (n > 0) {
+-			if (line[n - 1] == '\r')
+-				n--;
+-			line[n] = 0;
+-			printk(KERN_DEBUG "CONSOLE: %s\n", line);
+-		}
+-	}
+-break2:
+-
+-	return 0;
+-}
+-#endif				/* DHD_DEBUG */
+-
+-int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len)
+-{
+-	int bcmerror = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Basic sanity checks */
+-	if (bus->dhd->up) {
+-		bcmerror = -EISCONN;
+-		goto err;
+-	}
+-	if (!len) {
+-		bcmerror = -EOVERFLOW;
+-		goto err;
+-	}
+-
+-	/* Free the old ones and replace with passed variables */
+-	kfree(bus->vars);
+-
+-	bus->vars = kmalloc(len, GFP_ATOMIC);
+-	bus->varsz = bus->vars ? len : 0;
+-	if (bus->vars == NULL) {
+-		bcmerror = -ENOMEM;
+-		goto err;
+-	}
+-
+-	/* Copy the passed variables, which should include the
+-		 terminating double-null */
+-	memcpy(bus->vars, arg, bus->varsz);
+-err:
+-	return bcmerror;
+-}
+-
+-static int
+-dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid,
+-		const char *name, void *params, int plen, void *arg, int len,
+-		int val_size)
+-{
+-	int bcmerror = 0;
+-	s32 int_val = 0;
+-	bool bool_val = 0;
+-
+-	DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p "
+-		"len %d val_size %d\n",
+-		__func__, actionid, name, params, plen, arg, len, val_size));
+-
+-	bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid));
+-	if (bcmerror != 0)
+-		goto exit;
+-
+-	if (plen >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	bool_val = (int_val != 0) ? true : false;
+-
+-	/* Some ioctls use the bus */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Check if dongle is in reset. If so, only allow DEVRESET iovars */
+-	if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
+-					actionid == IOV_GVAL(IOV_DEVRESET))) {
+-		bcmerror = -EPERM;
+-		goto exit;
+-	}
+-
+-	/* Handle sleep stuff before any clock mucking */
+-	if (vi->varid == IOV_SLEEP) {
+-		if (IOV_ISSET(actionid)) {
+-			bcmerror = dhdsdio_bussleep(bus, bool_val);
+-		} else {
+-			int_val = (s32) bus->sleeping;
+-			memcpy(arg, &int_val, val_size);
+-		}
+-		goto exit;
+-	}
+-
+-	/* Request clock to allow SDIO accesses */
+-	if (!bus->dhd->dongle_reset) {
+-		BUS_WAKE(bus);
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	}
+-
+-	switch (actionid) {
+-	case IOV_GVAL(IOV_INTR):
+-		int_val = (s32) bus->intr;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_INTR):
+-		bus->intr = bool_val;
+-		bus->intdis = false;
+-		if (bus->dhd->up) {
+-			if (bus->intr) {
+-				DHD_INTR(("%s: enable SDIO device interrupts\n",
+-					  __func__));
+-				bcmsdh_intr_enable(bus->sdh);
+-			} else {
+-				DHD_INTR(("%s: disable SDIO interrupts\n",
+-					  __func__));
+-				bcmsdh_intr_disable(bus->sdh);
+-			}
+-		}
+-		break;
+-
+-	case IOV_GVAL(IOV_POLLRATE):
+-		int_val = (s32) bus->pollrate;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_POLLRATE):
+-		bus->pollrate = (uint) int_val;
+-		bus->poll = (bus->pollrate != 0);
+-		break;
+-
+-	case IOV_GVAL(IOV_IDLETIME):
+-		int_val = bus->idletime;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_IDLETIME):
+-		if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE))
+-			bcmerror = -EINVAL;
+-		else
+-			bus->idletime = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_IDLECLOCK):
+-		int_val = (s32) bus->idleclock;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_IDLECLOCK):
+-		bus->idleclock = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SD1IDLE):
+-		int_val = (s32) sd1idle;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SD1IDLE):
+-		sd1idle = bool_val;
+-		break;
+-
+-	case IOV_SVAL(IOV_MEMBYTES):
+-	case IOV_GVAL(IOV_MEMBYTES):
+-		{
+-			u32 address;
+-			uint size, dsize;
+-			u8 *data;
+-
+-			bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
+-
+-			ASSERT(plen >= 2 * sizeof(int));
+-
+-			address = (u32) int_val;
+-			memcpy(&int_val, (char *)params + sizeof(int_val),
+-			       sizeof(int_val));
+-			size = (uint) int_val;
+-
+-			/* Do some validation */
+-			dsize = set ? plen - (2 * sizeof(int)) : len;
+-			if (dsize < size) {
+-				DHD_ERROR(("%s: error on %s membytes, addr "
+-				"0x%08x size %d dsize %d\n",
+-				__func__, (set ? "set" : "get"),
+-				address, size, dsize));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			DHD_INFO(("%s: Request to %s %d bytes at address "
+-			"0x%08x\n",
+-			__func__, (set ? "write" : "read"), size, address));
+-
+-			/* If we know about SOCRAM, check for a fit */
+-			if ((bus->orig_ramsize) &&
+-			    ((address > bus->orig_ramsize)
+-			     || (address + size > bus->orig_ramsize))) {
+-				DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d "
+-				"bytes at 0x%08x\n",
+-				__func__, bus->orig_ramsize, size, address));
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* Generate the actual data pointer */
+-			data =
+-			    set ? (u8 *) params +
+-			    2 * sizeof(int) : (u8 *) arg;
+-
+-			/* Call to do the transfer */
+-			bcmerror =
+-			    dhdsdio_membytes(bus, set, address, data, size);
+-
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_MEMSIZE):
+-		int_val = (s32) bus->ramsize;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_GVAL(IOV_SDIOD_DRIVE):
+-		int_val = (s32) dhd_sdiod_drive_strength;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDIOD_DRIVE):
+-		dhd_sdiod_drive_strength = int_val;
+-		dhdsdio_sdiod_drive_strength_init(bus,
+-					     dhd_sdiod_drive_strength);
+-		break;
+-
+-	case IOV_SVAL(IOV_DOWNLOAD):
+-		bcmerror = dhdsdio_download_state(bus, bool_val);
+-		break;
+-
+-	case IOV_SVAL(IOV_VARS):
+-		bcmerror = dhdsdio_downloadvars(bus, arg, len);
+-		break;
+-
+-	case IOV_GVAL(IOV_READAHEAD):
+-		int_val = (s32) dhd_readahead;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_READAHEAD):
+-		if (bool_val && !dhd_readahead)
+-			bus->nextlen = 0;
+-		dhd_readahead = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDRXCHAIN):
+-		int_val = (s32) bus->use_rxchain;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_SDRXCHAIN):
+-		if (bool_val && !bus->sd_rxchain)
+-			bcmerror = -ENOTSUPP;
+-		else
+-			bus->use_rxchain = bool_val;
+-		break;
+-	case IOV_GVAL(IOV_ALIGNCTL):
+-		int_val = (s32) dhd_alignctl;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_ALIGNCTL):
+-		dhd_alignctl = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_SDALIGN):
+-		int_val = DHD_SDALIGN;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_VARS):
+-		if (bus->varsz < (uint) len)
+-			memcpy(arg, bus->vars, bus->varsz);
+-		else
+-			bcmerror = -EOVERFLOW;
+-		break;
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef DHD_DEBUG
+-	case IOV_GVAL(IOV_SDREG):
+-		{
+-			sdreg_t *sd_ptr;
+-			u32 addr, size;
+-
+-			sd_ptr = (sdreg_t *) params;
+-
+-			addr = (unsigned long)bus->regs + sd_ptr->offset;
+-			size = sd_ptr->func;
+-			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			memcpy(arg, &int_val, sizeof(s32));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_SDREG):
+-		{
+-			sdreg_t *sd_ptr;
+-			u32 addr, size;
+-
+-			sd_ptr = (sdreg_t *) params;
+-
+-			addr = (unsigned long)bus->regs + sd_ptr->offset;
+-			size = sd_ptr->func;
+-			bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			break;
+-		}
+-
+-		/* Same as above, but offset is not backplane
+-		 (not SDIO core) */
+-	case IOV_GVAL(IOV_SBREG):
+-		{
+-			sdreg_t sdreg;
+-			u32 addr, size;
+-
+-			memcpy(&sdreg, params, sizeof(sdreg));
+-
+-			addr = SI_ENUM_BASE + sdreg.offset;
+-			size = sdreg.func;
+-			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			memcpy(arg, &int_val, sizeof(s32));
+-			break;
+-		}
+-
+-	case IOV_SVAL(IOV_SBREG):
+-		{
+-			sdreg_t sdreg;
+-			u32 addr, size;
+-
+-			memcpy(&sdreg, params, sizeof(sdreg));
+-
+-			addr = SI_ENUM_BASE + sdreg.offset;
+-			size = sdreg.func;
+-			bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value);
+-			if (bcmsdh_regfail(bus->sdh))
+-				bcmerror = -EIO;
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_SDCIS):
+-		{
+-			*(char *)arg = 0;
+-
+-			strcat(arg, "\nFunc 0\n");
+-			bcmsdh_cis_read(bus->sdh, 0x10,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			strcat(arg, "\nFunc 1\n");
+-			bcmsdh_cis_read(bus->sdh, 0x11,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			strcat(arg, "\nFunc 2\n");
+-			bcmsdh_cis_read(bus->sdh, 0x12,
+-					(u8 *) arg + strlen(arg),
+-					SBSDIO_CIS_SIZE_LIMIT);
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_FORCEEVEN):
+-		int_val = (s32) forcealign;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_FORCEEVEN):
+-		forcealign = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_TXBOUND):
+-		int_val = (s32) dhd_txbound;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_TXBOUND):
+-		dhd_txbound = (uint) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_RXBOUND):
+-		int_val = (s32) dhd_rxbound;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_RXBOUND):
+-		dhd_rxbound = (uint) int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_TXMINMAX):
+-		int_val = (s32) dhd_txminmax;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_TXMINMAX):
+-		dhd_txminmax = (uint) int_val;
+-		break;
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef SDTEST
+-	case IOV_GVAL(IOV_EXTLOOP):
+-		int_val = (s32) bus->ext_loop;
+-		memcpy(arg, &int_val, val_size);
+-		break;
+-
+-	case IOV_SVAL(IOV_EXTLOOP):
+-		bus->ext_loop = bool_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_PKTGEN):
+-		bcmerror = dhdsdio_pktgen_get(bus, arg);
+-		break;
+-
+-	case IOV_SVAL(IOV_PKTGEN):
+-		bcmerror = dhdsdio_pktgen_set(bus, arg);
+-		break;
+-#endif				/* SDTEST */
+-
+-	case IOV_SVAL(IOV_DEVRESET):
+-		DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d "
+-			"busstate=%d\n",
+-			__func__, bool_val, bus->dhd->dongle_reset,
+-			bus->dhd->busstate));
+-
+-		dhd_bus_devreset(bus->dhd, (u8) bool_val);
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_DEVRESET):
+-		DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __func__));
+-
+-		/* Get its status */
+-		int_val = (bool) bus->dhd->dongle_reset;
+-		memcpy(arg, &int_val, val_size);
+-
+-		break;
+-
+-	default:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-	}
+-
+-exit:
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false)
+-		dhd_preinit_ioctls((dhd_pub_t *) bus->dhd);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_write_vars(dhd_bus_t *bus)
+-{
+-	int bcmerror = 0;
+-	u32 varsize;
+-	u32 varaddr;
+-	u8 *vbuffer;
+-	u32 varsizew;
+-#ifdef DHD_DEBUG
+-	char *nvram_ularray;
+-#endif				/* DHD_DEBUG */
+-
+-	/* Even if there are no vars are to be written, we still
+-		 need to set the ramsize. */
+-	varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
+-	varaddr = (bus->ramsize - 4) - varsize;
+-
+-	if (bus->vars) {
+-		vbuffer = kzalloc(varsize, GFP_ATOMIC);
+-		if (!vbuffer)
+-			return -ENOMEM;
+-
+-		memcpy(vbuffer, bus->vars, bus->varsz);
+-
+-		/* Write the vars list */
+-		bcmerror =
+-		    dhdsdio_membytes(bus, true, varaddr, vbuffer, varsize);
+-#ifdef DHD_DEBUG
+-		/* Verify NVRAM bytes */
+-		DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
+-		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
+-		if (!nvram_ularray)
+-			return -ENOMEM;
+-
+-		/* Upload image to verify downloaded contents. */
+-		memset(nvram_ularray, 0xaa, varsize);
+-
+-		/* Read the vars list to temp buffer for comparison */
+-		bcmerror =
+-		    dhdsdio_membytes(bus, false, varaddr, nvram_ularray,
+-				     varsize);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on reading %d nvram bytes at "
+-			"0x%08x\n", __func__, bcmerror, varsize, varaddr));
+-		}
+-		/* Compare the org NVRAM with the one read from RAM */
+-		if (memcmp(vbuffer, nvram_ularray, varsize)) {
+-			DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n",
+-				   __func__));
+-		} else
+-			DHD_ERROR(("%s: Download/Upload/Compare of NVRAM ok.\n",
+-				__func__));
+-
+-		kfree(nvram_ularray);
+-#endif				/* DHD_DEBUG */
+-
+-		kfree(vbuffer);
+-	}
+-
+-	/* adjust to the user specified RAM */
+-	DHD_INFO(("Physical memory size: %d, usable memory size: %d\n",
+-		  bus->orig_ramsize, bus->ramsize));
+-	DHD_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize));
+-	varsize = ((bus->orig_ramsize - 4) - varaddr);
+-
+-	/*
+-	 * Determine the length token:
+-	 * Varsize, converted to words, in lower 16-bits, checksum
+-	 * in upper 16-bits.
+-	 */
+-	if (bcmerror) {
+-		varsizew = 0;
+-	} else {
+-		varsizew = varsize / 4;
+-		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
+-		varsizew = cpu_to_le32(varsizew);
+-	}
+-
+-	DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize,
+-		  varsizew));
+-
+-	/* Write the length token to the last word */
+-	bcmerror = dhdsdio_membytes(bus, true, (bus->orig_ramsize - 4),
+-				    (u8 *)&varsizew, 4);
+-
+-	return bcmerror;
+-}
+-
+-static int dhdsdio_download_state(dhd_bus_t *bus, bool enter)
+-{
+-	uint retries;
+-	u32 regdata;
+-	int bcmerror = 0;
+-
+-	/* To enter download state, disable ARM and reset SOCRAM.
+-	 * To exit download state, simply reset ARM (default is RAM boot).
+-	 */
+-	if (enter) {
+-		bus->alp_only = true;
+-
+-		dhdsdio_chip_disablecore(bus->sdh, bus->ci->armcorebase);
+-
+-		dhdsdio_chip_resetcore(bus->sdh, bus->ci->ramcorebase);
+-
+-		/* Clear the top bit of memory */
+-		if (bus->ramsize) {
+-			u32 zeros = 0;
+-			dhdsdio_membytes(bus, true, bus->ramsize - 4,
+-					 (u8 *)&zeros, 4);
+-		}
+-	} else {
+-		regdata = bcmsdh_reg_read(bus->sdh,
+-			CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
+-		regdata &= (SBTML_RESET | SBTML_REJ_MASK |
+-			(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-		if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
+-			DHD_ERROR(("%s: SOCRAM core is down after reset?\n",
+-				   __func__));
+-			bcmerror = -EBADE;
+-			goto fail;
+-		}
+-
+-		bcmerror = dhdsdio_write_vars(bus);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: no vars written to RAM\n", __func__));
+-			bcmerror = 0;
+-		}
+-
+-		W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
+-
+-		dhdsdio_chip_resetcore(bus->sdh, bus->ci->armcorebase);
+-
+-		/* Allow HT Clock now that the ARM is running. */
+-		bus->alp_only = false;
+-
+-		bus->dhd->busstate = DHD_BUS_LOAD;
+-	}
+-fail:
+-	return bcmerror;
+-}
+-
+-int
+-dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+-		 void *params, int plen, void *arg, int len, bool set)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	const bcm_iovar_t *vi = NULL;
+-	int bcmerror = 0;
+-	int val_size;
+-	u32 actionid;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(name);
+-	ASSERT(len >= 0);
+-
+-	/* Get MUST have return space */
+-	ASSERT(set || (arg && len));
+-
+-	/* Set does NOT take qualifiers */
+-	ASSERT(!set || (!params && !plen));
+-
+-	/* Look up var locally; if not found pass to host driver */
+-	vi = bcm_iovar_lookup(dhdsdio_iovars, name);
+-	if (vi == NULL) {
+-		dhd_os_sdlock(bus->dhd);
+-
+-		BUS_WAKE(bus);
+-
+-		/* Turn on clock in case SD command needs backplane */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-		bcmerror =
+-		    bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len,
+-				    set);
+-
+-		/* Check for bus configuration changes of interest */
+-
+-		/* If it was divisor change, read the new one */
+-		if (set && strcmp(name, "sd_divisor") == 0) {
+-			if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
+-					    &bus->sd_divisor, sizeof(s32),
+-					    false) != 0) {
+-				bus->sd_divisor = -1;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   name));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, name, bus->sd_divisor));
+-			}
+-		}
+-		/* If it was a mode change, read the new one */
+-		if (set && strcmp(name, "sd_mode") == 0) {
+-			if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
+-					    &bus->sd_mode, sizeof(s32),
+-					    false) != 0) {
+-				bus->sd_mode = -1;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   name));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, name, bus->sd_mode));
+-			}
+-		}
+-		/* Similar check for blocksize change */
+-		if (set && strcmp(name, "sd_blocksize") == 0) {
+-			s32 fnum = 2;
+-			if (bcmsdh_iovar_op
+-			    (bus->sdh, "sd_blocksize", &fnum, sizeof(s32),
+-			     &bus->blocksize, sizeof(s32),
+-			     false) != 0) {
+-				bus->blocksize = 0;
+-				DHD_ERROR(("%s: fail on %s get\n", __func__,
+-					   "sd_blocksize"));
+-			} else {
+-				DHD_INFO(("%s: noted %s update, value now %d\n",
+-					  __func__, "sd_blocksize",
+-					  bus->blocksize));
+-			}
+-		}
+-		bus->roundup = min(max_roundup, bus->blocksize);
+-
+-		if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-			bus->activity = false;
+-			dhdsdio_clkctl(bus, CLK_NONE, true);
+-		}
+-
+-		dhd_os_sdunlock(bus->dhd);
+-		goto exit;
+-	}
+-
+-	DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__,
+-		 name, (set ? "set" : "get"), len, plen));
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		plen = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-	bcmerror =
+-	    dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len,
+-			    val_size);
+-
+-exit:
+-	return bcmerror;
+-}
+-
+-void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
+-{
+-	u32 local_hostintmask;
+-	u8 saveclk;
+-	uint retries;
+-	int err;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (enforce_mutex)
+-		dhd_os_sdlock(bus->dhd);
+-
+-	BUS_WAKE(bus);
+-
+-	/* Enable clock for device interrupts */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Disable and clear interrupts at the chip level also */
+-	W_SDREG(0, &bus->regs->hostintmask, retries);
+-	local_hostintmask = bus->hostintmask;
+-	bus->hostintmask = 0;
+-
+-	/* Change our idea of bus state */
+-	bus->dhd->busstate = DHD_BUS_DOWN;
+-
+-	/* Force clocks on backplane to be sure F2 interrupt propagates */
+-	saveclk =
+-	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			    &err);
+-	if (!err) {
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 (saveclk | SBSDIO_FORCE_HT), &err);
+-	}
+-	if (err) {
+-		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
+-			   __func__, err));
+-	}
+-
+-	/* Turn off the bus (F2), free any pending packets */
+-	DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-	bcmsdh_intr_disable(bus->sdh);
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
+-			 SDIO_FUNC_ENABLE_1, NULL);
+-
+-	/* Clear any pending interrupts now that F2 is disabled */
+-	W_SDREG(local_hostintmask, &bus->regs->intstatus, retries);
+-
+-	/* Turn off the backplane clock (only) */
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-	/* Clear the data packet queues */
+-	bcm_pktq_flush(&bus->txq, true, NULL, NULL);
+-
+-	/* Clear any held glomming stuff */
+-	if (bus->glomd)
+-		bcm_pkt_buf_free_skb(bus->glomd);
+-
+-	if (bus->glom)
+-		bcm_pkt_buf_free_skb(bus->glom);
+-
+-	bus->glom = bus->glomd = NULL;
+-
+-	/* Clear rx control and wake any waiters */
+-	bus->rxlen = 0;
+-	dhd_os_ioctl_resp_wake(bus->dhd);
+-
+-	/* Reset some F2 state stuff */
+-	bus->rxskip = false;
+-	bus->tx_seq = bus->rx_seq = 0;
+-
+-	if (enforce_mutex)
+-		dhd_os_sdunlock(bus->dhd);
+-}
+-
+-int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	dhd_timeout_t tmo;
+-	uint retries = 0;
+-	u8 ready, enable;
+-	int err, ret = 0;
+-	u8 saveclk;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(bus->dhd);
+-	if (!bus->dhd)
+-		return 0;
+-
+-	if (enforce_mutex)
+-		dhd_os_sdlock(bus->dhd);
+-
+-	/* Make sure backplane clock is on, needed to generate F2 interrupt */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-	if (bus->clkstate != CLK_AVAIL)
+-		goto exit;
+-
+-	/* Force clocks on backplane to be sure F2 interrupt propagates */
+-	saveclk =
+-	    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			    &err);
+-	if (!err) {
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 (saveclk | SBSDIO_FORCE_HT), &err);
+-	}
+-	if (err) {
+-		DHD_ERROR(("%s: Failed to force clock for F2: err %d\n",
+-			   __func__, err));
+-		goto exit;
+-	}
+-
+-	/* Enable function 2 (frame transfers) */
+-	W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT),
+-		&bus->regs->tosbmailboxdata, retries);
+-	enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2);
+-
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL);
+-
+-	/* Give the dongle some time to do its thing and set IOR2 */
+-	dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000);
+-
+-	ready = 0;
+-	while (ready != enable && !dhd_timeout_expired(&tmo))
+-		ready =
+-		    bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY,
+-				    NULL);
+-
+-	DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
+-		  __func__, enable, ready, tmo.elapsed));
+-
+-	/* If F2 successfully enabled, set core and enable interrupts */
+-	if (ready == enable) {
+-		/* Set up the interrupt mask and enable interrupts */
+-		bus->hostintmask = HOSTINTMASK;
+-		W_SDREG(bus->hostintmask,
+-			(unsigned int *)CORE_BUS_REG(bus->ci->buscorebase,
+-			hostintmask), retries);
+-
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK,
+-				 (u8) watermark, &err);
+-
+-		/* Set bus state according to enable result */
+-		dhdp->busstate = DHD_BUS_DATA;
+-
+-		/* bcmsdh_intr_unmask(bus->sdh); */
+-
+-		bus->intdis = false;
+-		if (bus->intr) {
+-			DHD_INTR(("%s: enable SDIO device interrupts\n",
+-				  __func__));
+-			bcmsdh_intr_enable(bus->sdh);
+-		} else {
+-			DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-			bcmsdh_intr_disable(bus->sdh);
+-		}
+-
+-	}
+-
+-	else {
+-		/* Disable F2 again */
+-		enable = SDIO_FUNC_ENABLE_1;
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable,
+-				 NULL);
+-	}
+-
+-	/* Restore previous clock setting */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			 saveclk, &err);
+-
+-	/* If we didn't come up, turn off backplane clock */
+-	if (dhdp->busstate != DHD_BUS_DATA)
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-
+-exit:
+-	if (enforce_mutex)
+-		dhd_os_sdunlock(bus->dhd);
+-
+-	return ret;
+-}
+-
+-static void dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	uint retries = 0;
+-	u16 lastrbc;
+-	u8 hi, lo;
+-	int err;
+-
+-	DHD_ERROR(("%s: %sterminate frame%s\n", __func__,
+-		   (abort ? "abort command, " : ""),
+-		   (rtx ? ", send NAK" : "")));
+-
+-	if (abort)
+-		bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM,
+-			 &err);
+-	bus->f1regdata++;
+-
+-	/* Wait until the packet has been flushed (device/FIFO stable) */
+-	for (lastrbc = retries = 0xffff; retries > 0; retries--) {
+-		hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI,
+-				     NULL);
+-		lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO,
+-				     NULL);
+-		bus->f1regdata += 2;
+-
+-		if ((hi == 0) && (lo == 0))
+-			break;
+-
+-		if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
+-			DHD_ERROR(("%s: count growing: last 0x%04x now "
+-				"0x%04x\n",
+-				__func__, lastrbc, ((hi << 8) + lo)));
+-		}
+-		lastrbc = (hi << 8) + lo;
+-	}
+-
+-	if (!retries) {
+-		DHD_ERROR(("%s: count never zeroed: last 0x%04x\n",
+-			   __func__, lastrbc));
+-	} else {
+-		DHD_INFO(("%s: flush took %d iterations\n", __func__,
+-			  (0xffff - retries)));
+-	}
+-
+-	if (rtx) {
+-		bus->rxrtx++;
+-		W_SDREG(SMB_NAK, &regs->tosbmailbox, retries);
+-		bus->f1regdata++;
+-		if (retries <= retry_limit)
+-			bus->rxskip = true;
+-	}
+-
+-	/* Clear partial in any case */
+-	bus->nextlen = 0;
+-
+-	/* If we can't reach the device, signal failure */
+-	if (err || bcmsdh_regfail(sdh))
+-		bus->dhd->busstate = DHD_BUS_DOWN;
+-}
+-
+-static void
+-dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	uint rdlen, pad;
+-
+-	int sdret;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Control data already received in aligned rxctl */
+-	if ((bus->bus == SPI_BUS) && (!bus->usebufpool))
+-		goto gotpkt;
+-
+-	ASSERT(bus->rxbuf);
+-	/* Set rxctl for frame (w/optional alignment) */
+-	bus->rxctl = bus->rxbuf;
+-	if (dhd_alignctl) {
+-		bus->rxctl += firstread;
+-		pad = ((unsigned long)bus->rxctl % DHD_SDALIGN);
+-		if (pad)
+-			bus->rxctl += (DHD_SDALIGN - pad);
+-		bus->rxctl -= firstread;
+-	}
+-	ASSERT(bus->rxctl >= bus->rxbuf);
+-
+-	/* Copy the already-read portion over */
+-	memcpy(bus->rxctl, hdr, firstread);
+-	if (len <= firstread)
+-		goto gotpkt;
+-
+-	/* Copy the full data pkt in gSPI case and process ioctl. */
+-	if (bus->bus == SPI_BUS) {
+-		memcpy(bus->rxctl, hdr, len);
+-		goto gotpkt;
+-	}
+-
+-	/* Raise rdlen to next SDIO block to avoid tail command */
+-	rdlen = len - firstread;
+-	if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) {
+-		pad = bus->blocksize - (rdlen % bus->blocksize);
+-		if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+-		    ((len + pad) < bus->dhd->maxctl))
+-			rdlen += pad;
+-	} else if (rdlen % DHD_SDALIGN) {
+-		rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-	}
+-
+-	/* Satisfy length-alignment requirements */
+-	if (forcealign && (rdlen & (ALIGNMENT - 1)))
+-		rdlen = roundup(rdlen, ALIGNMENT);
+-
+-	/* Drop if the read is too big or it exceeds our maximum */
+-	if ((rdlen + firstread) > bus->dhd->maxctl) {
+-		DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n",
+-			   __func__, rdlen, bus->dhd->maxctl));
+-		bus->dhd->rx_errors++;
+-		dhdsdio_rxfail(bus, false, false);
+-		goto done;
+-	}
+-
+-	if ((len - doff) > bus->dhd->maxctl) {
+-		DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds "
+-			"%d-byte limit\n",
+-			__func__, len, (len - doff), bus->dhd->maxctl));
+-		bus->dhd->rx_errors++;
+-		bus->rx_toolong++;
+-		dhdsdio_rxfail(bus, false, false);
+-		goto done;
+-	}
+-
+-	/* Read remainder of frame body into the rxctl buffer */
+-	sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-				F2SYNC, (bus->rxctl + firstread), rdlen,
+-				NULL, NULL, NULL);
+-	bus->f2rxdata++;
+-	ASSERT(sdret != -BCME_PENDING);
+-
+-	/* Control frame failures need retransmission */
+-	if (sdret < 0) {
+-		DHD_ERROR(("%s: read %d control bytes failed: %d\n",
+-			   __func__, rdlen, sdret));
+-		bus->rxc_errors++;	/* dhd.rx_ctlerrs is higher level */
+-		dhdsdio_rxfail(bus, true, true);
+-		goto done;
+-	}
+-
+-gotpkt:
+-
+-#ifdef DHD_DEBUG
+-	if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+-		printk(KERN_DEBUG "RxCtrl:\n");
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
+-	}
+-#endif
+-
+-	/* Point to valid data and indicate its length */
+-	bus->rxctl += doff;
+-	bus->rxlen = len - doff;
+-
+-done:
+-	/* Awake any waiters */
+-	dhd_os_ioctl_resp_wake(bus->dhd);
+-}
+-
+-static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq)
+-{
+-	u16 dlen, totlen;
+-	u8 *dptr, num = 0;
+-
+-	u16 sublen, check;
+-	struct sk_buff *pfirst, *plast, *pnext, *save_pfirst;
+-
+-	int errcode;
+-	u8 chan, seq, doff, sfdoff;
+-	u8 txmax;
+-
+-	int ifidx = 0;
+-	bool usechain = bus->use_rxchain;
+-
+-	/* If packets, issue read(s) and send up packet chain */
+-	/* Return sequence numbers consumed? */
+-
+-	DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd,
+-		   bus->glom));
+-
+-	/* If there's a descriptor, generate the packet chain */
+-	if (bus->glomd) {
+-		dhd_os_sdlock_rxq(bus->dhd);
+-
+-		pfirst = plast = pnext = NULL;
+-		dlen = (u16) (bus->glomd->len);
+-		dptr = bus->glomd->data;
+-		if (!dlen || (dlen & 1)) {
+-			DHD_ERROR(("%s: bad glomd len(%d), ignore descriptor\n",
+-			__func__, dlen));
+-			dlen = 0;
+-		}
+-
+-		for (totlen = num = 0; dlen; num++) {
+-			/* Get (and move past) next length */
+-			sublen = get_unaligned_le16(dptr);
+-			dlen -= sizeof(u16);
+-			dptr += sizeof(u16);
+-			if ((sublen < SDPCM_HDRLEN) ||
+-			    ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) {
+-				DHD_ERROR(("%s: descriptor len %d bad: %d\n",
+-					   __func__, num, sublen));
+-				pnext = NULL;
+-				break;
+-			}
+-			if (sublen % DHD_SDALIGN) {
+-				DHD_ERROR(("%s: sublen %d not multiple of %d\n",
+-				__func__, sublen, DHD_SDALIGN));
+-				usechain = false;
+-			}
+-			totlen += sublen;
+-
+-			/* For last frame, adjust read len so total
+-				 is a block multiple */
+-			if (!dlen) {
+-				sublen +=
+-				    (roundup(totlen, bus->blocksize) - totlen);
+-				totlen = roundup(totlen, bus->blocksize);
+-			}
+-
+-			/* Allocate/chain packet for next subframe */
+-			pnext = bcm_pkt_buf_get_skb(sublen + DHD_SDALIGN);
+-			if (pnext == NULL) {
+-				DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed, "
+-					"num %d len %d\n", __func__,
+-					num, sublen));
+-				break;
+-			}
+-			ASSERT(!(pnext->prev));
+-			if (!pfirst) {
+-				ASSERT(!plast);
+-				pfirst = plast = pnext;
+-			} else {
+-				ASSERT(plast);
+-				plast->next = pnext;
+-				plast = pnext;
+-			}
+-
+-			/* Adhere to start alignment requirements */
+-			PKTALIGN(pnext, sublen, DHD_SDALIGN);
+-		}
+-
+-		/* If all allocations succeeded, save packet chain
+-			 in bus structure */
+-		if (pnext) {
+-			DHD_GLOM(("%s: allocated %d-byte packet chain for %d "
+-				"subframes\n", __func__, totlen, num));
+-			if (DHD_GLOM_ON() && bus->nextlen) {
+-				if (totlen != bus->nextlen) {
+-					DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " "rxseq %d\n",
+-						__func__, bus->nextlen,
+-						totlen, rxseq));
+-				}
+-			}
+-			bus->glom = pfirst;
+-			pfirst = pnext = NULL;
+-		} else {
+-			if (pfirst)
+-				bcm_pkt_buf_free_skb(pfirst);
+-			bus->glom = NULL;
+-			num = 0;
+-		}
+-
+-		/* Done with descriptor packet */
+-		bcm_pkt_buf_free_skb(bus->glomd);
+-		bus->glomd = NULL;
+-		bus->nextlen = 0;
+-
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-	}
+-
+-	/* Ok -- either we just generated a packet chain,
+-		 or had one from before */
+-	if (bus->glom) {
+-		if (DHD_GLOM_ON()) {
+-			DHD_GLOM(("%s: try superframe read, packet chain:\n",
+-				__func__));
+-			for (pnext = bus->glom; pnext; pnext = pnext->next) {
+-				DHD_GLOM(("    %p: %p len 0x%04x (%d)\n",
+-					  pnext, (u8 *) (pnext->data),
+-					  pnext->len, pnext->len));
+-			}
+-		}
+-
+-		pfirst = bus->glom;
+-		dlen = (u16) bcm_pkttotlen(pfirst);
+-
+-		/* Do an SDIO read for the superframe.  Configurable iovar to
+-		 * read directly into the chained packet, or allocate a large
+-		 * packet and and copy into the chain.
+-		 */
+-		if (usechain) {
+-			errcode = bcmsdh_recv_buf(bus,
+-					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+-					F2SYNC, (u8 *) pfirst->data, dlen,
+-					pfirst, NULL, NULL);
+-		} else if (bus->dataptr) {
+-			errcode = bcmsdh_recv_buf(bus,
+-					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+-					F2SYNC, bus->dataptr, dlen,
+-					NULL, NULL, NULL);
+-			sublen = (u16) bcm_pktfrombuf(pfirst, 0, dlen,
+-						bus->dataptr);
+-			if (sublen != dlen) {
+-				DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n",
+-					__func__, dlen, sublen));
+-				errcode = -1;
+-			}
+-			pnext = NULL;
+-		} else {
+-			DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
+-				dlen));
+-			errcode = -1;
+-		}
+-		bus->f2rxdata++;
+-		ASSERT(errcode != -BCME_PENDING);
+-
+-		/* On failure, kill the superframe, allow a couple retries */
+-		if (errcode < 0) {
+-			DHD_ERROR(("%s: glom read of %d bytes failed: %d\n",
+-				   __func__, dlen, errcode));
+-			bus->dhd->rx_errors++;
+-
+-			if (bus->glomerr++ < 3) {
+-				dhdsdio_rxfail(bus, true, true);
+-			} else {
+-				bus->glomerr = 0;
+-				dhdsdio_rxfail(bus, true, false);
+-				dhd_os_sdlock_rxq(bus->dhd);
+-				bcm_pkt_buf_free_skb(bus->glom);
+-				dhd_os_sdunlock_rxq(bus->dhd);
+-				bus->rxglomfail++;
+-				bus->glom = NULL;
+-			}
+-			return 0;
+-		}
+-#ifdef DHD_DEBUG
+-		if (DHD_GLOM_ON()) {
+-			printk(KERN_DEBUG "SUPERFRAME:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-				pfirst->data, min_t(int, pfirst->len, 48));
+-		}
+-#endif
+-
+-		/* Validate the superframe header */
+-		dptr = (u8 *) (pfirst->data);
+-		sublen = get_unaligned_le16(dptr);
+-		check = get_unaligned_le16(dptr + sizeof(u16));
+-
+-		chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-		seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+-		bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+-		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-			DHD_INFO(("%s: nextlen too large (%d) seq %d\n",
+-				__func__, bus->nextlen, seq));
+-			bus->nextlen = 0;
+-		}
+-		doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-		txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-
+-		errcode = 0;
+-		if ((u16)~(sublen ^ check)) {
+-			DHD_ERROR(("%s (superframe): HW hdr error: len/check "
+-				"0x%04x/0x%04x\n", __func__, sublen, check));
+-			errcode = -1;
+-		} else if (roundup(sublen, bus->blocksize) != dlen) {
+-			DHD_ERROR(("%s (superframe): len 0x%04x, rounded "
+-				"0x%04x, expect 0x%04x\n",
+-				__func__, sublen,
+-				roundup(sublen, bus->blocksize), dlen));
+-			errcode = -1;
+-		} else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) !=
+-			   SDPCM_GLOM_CHANNEL) {
+-			DHD_ERROR(("%s (superframe): bad channel %d\n",
+-				   __func__,
+-				   SDPCM_PACKET_CHANNEL(&dptr
+-							[SDPCM_FRAMETAG_LEN])));
+-			errcode = -1;
+-		} else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) {
+-			DHD_ERROR(("%s (superframe): got second descriptor?\n",
+-				   __func__));
+-			errcode = -1;
+-		} else if ((doff < SDPCM_HDRLEN) ||
+-			   (doff > (pfirst->len - SDPCM_HDRLEN))) {
+-			DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d "
+-				"pkt %d min %d\n",
+-				__func__, doff, sublen,
+-				pfirst->len, SDPCM_HDRLEN));
+-			errcode = -1;
+-		}
+-
+-		/* Check sequence number of superframe SW header */
+-		if (rxseq != seq) {
+-			DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n",
+-				  __func__, seq, rxseq));
+-			bus->rx_badseq++;
+-			rxseq = seq;
+-		}
+-
+-		/* Check window for sanity */
+-		if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
+-				__func__, txmax, bus->tx_seq));
+-			txmax = bus->tx_seq + 2;
+-		}
+-		bus->tx_max = txmax;
+-
+-		/* Remove superframe header, remember offset */
+-		skb_pull(pfirst, doff);
+-		sfdoff = doff;
+-
+-		/* Validate all the subframe headers */
+-		for (num = 0, pnext = pfirst; pnext && !errcode;
+-		     num++, pnext = pnext->next) {
+-			dptr = (u8 *) (pnext->data);
+-			dlen = (u16) (pnext->len);
+-			sublen = get_unaligned_le16(dptr);
+-			check = get_unaligned_le16(dptr + sizeof(u16));
+-			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-#ifdef DHD_DEBUG
+-			if (DHD_GLOM_ON()) {
+-				printk(KERN_DEBUG "subframe:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     dptr, 32);
+-			}
+-#endif
+-
+-			if ((u16)~(sublen ^ check)) {
+-				DHD_ERROR(("%s (subframe %d): HW hdr error: "
+-					   "len/check 0x%04x/0x%04x\n",
+-					   __func__, num, sublen, check));
+-				errcode = -1;
+-			} else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) {
+-				DHD_ERROR(("%s (subframe %d): length mismatch: "
+-					   "len 0x%04x, expect 0x%04x\n",
+-					   __func__, num, sublen, dlen));
+-				errcode = -1;
+-			} else if ((chan != SDPCM_DATA_CHANNEL) &&
+-				   (chan != SDPCM_EVENT_CHANNEL)) {
+-				DHD_ERROR(("%s (subframe %d): bad channel %d\n",
+-					   __func__, num, chan));
+-				errcode = -1;
+-			} else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) {
+-				DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n",
+-					__func__, num, doff, sublen,
+-					SDPCM_HDRLEN));
+-				errcode = -1;
+-			}
+-		}
+-
+-		if (errcode) {
+-			/* Terminate frame on error, request
+-				 a couple retries */
+-			if (bus->glomerr++ < 3) {
+-				/* Restore superframe header space */
+-				skb_push(pfirst, sfdoff);
+-				dhdsdio_rxfail(bus, true, true);
+-			} else {
+-				bus->glomerr = 0;
+-				dhdsdio_rxfail(bus, true, false);
+-				dhd_os_sdlock_rxq(bus->dhd);
+-				bcm_pkt_buf_free_skb(bus->glom);
+-				dhd_os_sdunlock_rxq(bus->dhd);
+-				bus->rxglomfail++;
+-				bus->glom = NULL;
+-			}
+-			bus->nextlen = 0;
+-			return 0;
+-		}
+-
+-		/* Basic SD framing looks ok - process each packet (header) */
+-		save_pfirst = pfirst;
+-		bus->glom = NULL;
+-		plast = NULL;
+-
+-		dhd_os_sdlock_rxq(bus->dhd);
+-		for (num = 0; pfirst; rxseq++, pfirst = pnext) {
+-			pnext = pfirst->next;
+-			pfirst->next = NULL;
+-
+-			dptr = (u8 *) (pfirst->data);
+-			sublen = get_unaligned_le16(dptr);
+-			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
+-			seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
+-
+-			DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d "
+-				"chan %d seq %d\n",
+-				__func__, num, pfirst, pfirst->data,
+-				pfirst->len, sublen, chan, seq));
+-
+-			ASSERT((chan == SDPCM_DATA_CHANNEL)
+-			       || (chan == SDPCM_EVENT_CHANNEL));
+-
+-			if (rxseq != seq) {
+-				DHD_GLOM(("%s: rx_seq %d, expected %d\n",
+-					  __func__, seq, rxseq));
+-				bus->rx_badseq++;
+-				rxseq = seq;
+-			}
+-#ifdef DHD_DEBUG
+-			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-				printk(KERN_DEBUG "Rx Subframe Data:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     dptr, dlen);
+-			}
+-#endif
+-
+-			__skb_trim(pfirst, sublen);
+-			skb_pull(pfirst, doff);
+-
+-			if (pfirst->len == 0) {
+-				bcm_pkt_buf_free_skb(pfirst);
+-				if (plast) {
+-					plast->next = pnext;
+-				} else {
+-					ASSERT(save_pfirst == pfirst);
+-					save_pfirst = pnext;
+-				}
+-				continue;
+-			} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) !=
+-				   0) {
+-				DHD_ERROR(("%s: rx protocol error\n",
+-					   __func__));
+-				bus->dhd->rx_errors++;
+-				bcm_pkt_buf_free_skb(pfirst);
+-				if (plast) {
+-					plast->next = pnext;
+-				} else {
+-					ASSERT(save_pfirst == pfirst);
+-					save_pfirst = pnext;
+-				}
+-				continue;
+-			}
+-
+-			/* this packet will go up, link back into
+-				 chain and count it */
+-			pfirst->next = pnext;
+-			plast = pfirst;
+-			num++;
+-
+-#ifdef DHD_DEBUG
+-			if (DHD_GLOM_ON()) {
+-				DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) "
+-				"nxt/lnk %p/%p\n",
+-				__func__, num, pfirst, pfirst->data,
+-				pfirst->len, pfirst->next,
+-				pfirst->prev));
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						pfirst->data,
+-						min_t(int, pfirst->len, 32));
+-			}
+-#endif				/* DHD_DEBUG */
+-		}
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-		if (num) {
+-			dhd_os_sdunlock(bus->dhd);
+-			dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num);
+-			dhd_os_sdlock(bus->dhd);
+-		}
+-
+-		bus->rxglomframes++;
+-		bus->rxglompkts += num;
+-	}
+-	return num;
+-}
+-
+-/* Return true if there may be more frames to read */
+-static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-
+-	u16 len, check;	/* Extracted hardware header fields */
+-	u8 chan, seq, doff;	/* Extracted software header fields */
+-	u8 fcbits;		/* Extracted fcbits from software header */
+-
+-	struct sk_buff *pkt;		/* Packet for event or data frames */
+-	u16 pad;		/* Number of pad bytes to read */
+-	u16 rdlen;		/* Total number of bytes to read */
+-	u8 rxseq;		/* Next sequence number to expect */
+-	uint rxleft = 0;	/* Remaining number of frames allowed */
+-	int sdret;		/* Return code from bcmsdh calls */
+-	u8 txmax;		/* Maximum tx sequence offered */
+-	bool len_consistent;	/* Result of comparing readahead len and
+-					 len from hw-hdr */
+-	u8 *rxbuf;
+-	int ifidx = 0;
+-	uint rxcount = 0;	/* Total frames read */
+-
+-#if defined(DHD_DEBUG) || defined(SDTEST)
+-	bool sdtest = false;	/* To limit message spew from test mode */
+-#endif
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	ASSERT(maxframes);
+-
+-#ifdef SDTEST
+-	/* Allow pktgen to override maxframes */
+-	if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) {
+-		maxframes = bus->pktgen_count;
+-		sdtest = true;
+-	}
+-#endif
+-
+-	/* Not finished unless we encounter no more frames indication */
+-	*finished = false;
+-
+-	for (rxseq = bus->rx_seq, rxleft = maxframes;
+-	     !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN;
+-	     rxseq++, rxleft--) {
+-
+-		/* Handle glomming separately */
+-		if (bus->glom || bus->glomd) {
+-			u8 cnt;
+-			DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n",
+-				  __func__, bus->glomd, bus->glom));
+-			cnt = dhdsdio_rxglom(bus, rxseq);
+-			DHD_GLOM(("%s: rxglom returned %d\n", __func__, cnt));
+-			rxseq += cnt - 1;
+-			rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
+-			continue;
+-		}
+-
+-		/* Try doing single read if we can */
+-		if (dhd_readahead && bus->nextlen) {
+-			u16 nextlen = bus->nextlen;
+-			bus->nextlen = 0;
+-
+-			if (bus->bus == SPI_BUS) {
+-				rdlen = len = nextlen;
+-			} else {
+-				rdlen = len = nextlen << 4;
+-
+-				/* Pad read to blocksize for efficiency */
+-				if (bus->roundup && bus->blocksize
+-				    && (rdlen > bus->blocksize)) {
+-					pad =
+-					    bus->blocksize -
+-					    (rdlen % bus->blocksize);
+-					if ((pad <= bus->roundup)
+-					    && (pad < bus->blocksize)
+-					    && ((rdlen + pad + firstread) <
+-						MAX_RX_DATASZ))
+-						rdlen += pad;
+-				} else if (rdlen % DHD_SDALIGN) {
+-					rdlen +=
+-					    DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-				}
+-			}
+-
+-			/* We use bus->rxctl buffer in WinXP for initial
+-			 * control pkt receives.
+-			 * Later we use buffer-poll for data as well
+-			 * as control packets.
+-			 * This is required because dhd receives full
+-			 * frame in gSPI unlike SDIO.
+-			 * After the frame is received we have to
+-			 * distinguish whether it is data
+-			 * or non-data frame.
+-			 */
+-			/* Allocate a packet buffer */
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			pkt = bcm_pkt_buf_get_skb(rdlen + DHD_SDALIGN);
+-			if (!pkt) {
+-				if (bus->bus == SPI_BUS) {
+-					bus->usebufpool = false;
+-					bus->rxctl = bus->rxbuf;
+-					if (dhd_alignctl) {
+-						bus->rxctl += firstread;
+-						pad = ((unsigned long)bus->rxctl %
+-						      DHD_SDALIGN);
+-						if (pad)
+-							bus->rxctl +=
+-							    (DHD_SDALIGN - pad);
+-						bus->rxctl -= firstread;
+-					}
+-					ASSERT(bus->rxctl >= bus->rxbuf);
+-					rxbuf = bus->rxctl;
+-					/* Read the entire frame */
+-					sdret = bcmsdh_recv_buf(bus,
+-						    bcmsdh_cur_sbwad(sdh),
+-						    SDIO_FUNC_2, F2SYNC,
+-						    rxbuf, rdlen,
+-						    NULL, NULL, NULL);
+-					bus->f2rxdata++;
+-					ASSERT(sdret != -BCME_PENDING);
+-
+-					/* Control frame failures need
+-					 retransmission */
+-					if (sdret < 0) {
+-						DHD_ERROR(("%s: read %d control bytes failed: %d\n",
+-							__func__,
+-							rdlen, sdret));
+-						/* dhd.rx_ctlerrs is higher */
+-						bus->rxc_errors++;
+-						dhd_os_sdunlock_rxq(bus->dhd);
+-						dhdsdio_rxfail(bus, true,
+-						       (bus->bus ==
+-							SPI_BUS) ? false
+-						       : true);
+-						continue;
+-					}
+-				} else {
+-					/* Give up on data,
+-					request rtx of events */
+-					DHD_ERROR(("%s (nextlen): "
+-						   "bcm_pkt_buf_get_skb failed:"
+-						   " len %d rdlen %d expected"
+-						   " rxseq %d\n", __func__,
+-						   len, rdlen, rxseq));
+-					/* Just go try again w/normal
+-					header read */
+-					dhd_os_sdunlock_rxq(bus->dhd);
+-					continue;
+-				}
+-			} else {
+-				if (bus->bus == SPI_BUS)
+-					bus->usebufpool = true;
+-
+-				ASSERT(!(pkt->prev));
+-				PKTALIGN(pkt, rdlen, DHD_SDALIGN);
+-				rxbuf = (u8 *) (pkt->data);
+-				/* Read the entire frame */
+-				sdret = bcmsdh_recv_buf(bus,
+-						bcmsdh_cur_sbwad(sdh),
+-						SDIO_FUNC_2, F2SYNC,
+-						rxbuf, rdlen,
+-						pkt, NULL, NULL);
+-				bus->f2rxdata++;
+-				ASSERT(sdret != -BCME_PENDING);
+-
+-				if (sdret < 0) {
+-					DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n",
+-						__func__, rdlen, sdret));
+-					bcm_pkt_buf_free_skb(pkt);
+-					bus->dhd->rx_errors++;
+-					dhd_os_sdunlock_rxq(bus->dhd);
+-					/* Force retry w/normal header read.
+-					 * Don't attempt NAK for
+-					 * gSPI
+-					 */
+-					dhdsdio_rxfail(bus, true,
+-						       (bus->bus ==
+-							SPI_BUS) ? false :
+-						       true);
+-					continue;
+-				}
+-			}
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-
+-			/* Now check the header */
+-			memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
+-
+-			/* Extract hardware header fields */
+-			len = get_unaligned_le16(bus->rxhdr);
+-			check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
+-
+-			/* All zeros means readahead info was bad */
+-			if (!(len | check)) {
+-				DHD_INFO(("%s (nextlen): read zeros in HW "
+-					"header???\n", __func__));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Validate check bytes */
+-			if ((u16)~(len ^ check)) {
+-				DHD_ERROR(("%s (nextlen): HW hdr error:"
+-					" nextlen/len/check"
+-					" 0x%04x/0x%04x/0x%04x\n",
+-					__func__, nextlen, len, check));
+-				bus->rx_badhdr++;
+-				dhdsdio_rxfail(bus, false, false);
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Validate frame length */
+-			if (len < SDPCM_HDRLEN) {
+-				DHD_ERROR(("%s (nextlen): HW hdr length "
+-					"invalid: %d\n", __func__, len));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Check for consistency withreadahead info */
+-			len_consistent = (nextlen != (roundup(len, 16) >> 4));
+-			if (len_consistent) {
+-				/* Mismatch, force retry w/normal
+-					header (may be >4K) */
+-				DHD_ERROR(("%s (nextlen): mismatch, "
+-					"nextlen %d len %d rnd %d; "
+-					"expected rxseq %d\n",
+-					__func__, nextlen,
+-					len, roundup(len, 16), rxseq));
+-				dhdsdio_rxfail(bus, true, (bus->bus != SPI_BUS));
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* Extract software header fields */
+-			chan = SDPCM_PACKET_CHANNEL(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			seq = SDPCM_PACKET_SEQUENCE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			doff = SDPCM_DOFFSET_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-			txmax = SDPCM_WINDOW_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-			bus->nextlen =
+-			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
+-				       SDPCM_NEXTLEN_OFFSET];
+-			if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-				DHD_INFO(("%s (nextlen): got frame w/nextlen too large" " (%d), seq %d\n",
+-					__func__, bus->nextlen, seq));
+-				bus->nextlen = 0;
+-			}
+-
+-			bus->dhd->rx_readahead_cnt++;
+-
+-			/* Handle Flow Control */
+-			fcbits = SDPCM_FCMASK_VALUE(
+-					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-			if (bus->flowcontrol != fcbits) {
+-				if (~bus->flowcontrol & fcbits)
+-					bus->fc_xoff++;
+-
+-				if (bus->flowcontrol & ~fcbits)
+-					bus->fc_xon++;
+-
+-				bus->fc_rcvd++;
+-				bus->flowcontrol = fcbits;
+-			}
+-
+-			/* Check and update sequence number */
+-			if (rxseq != seq) {
+-				DHD_INFO(("%s (nextlen): rx_seq %d, expected "
+-					"%d\n", __func__, seq, rxseq));
+-				bus->rx_badseq++;
+-				rxseq = seq;
+-			}
+-
+-			/* Check window for sanity */
+-			if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-				DHD_ERROR(("%s: got unlikely tx max %d with "
+-					"tx_seq %d\n",
+-					__func__, txmax, bus->tx_seq));
+-				txmax = bus->tx_seq + 2;
+-			}
+-			bus->tx_max = txmax;
+-
+-#ifdef DHD_DEBUG
+-			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-				printk(KERN_DEBUG "Rx Data:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     rxbuf, len);
+-			} else if (DHD_HDRS_ON()) {
+-				printk(KERN_DEBUG "RxHdr:\n");
+-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-						     bus->rxhdr, SDPCM_HDRLEN);
+-			}
+-#endif
+-
+-			if (chan == SDPCM_CONTROL_CHANNEL) {
+-				if (bus->bus == SPI_BUS) {
+-					dhdsdio_read_control(bus, rxbuf, len,
+-							     doff);
+-				} else {
+-					DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n",
+-						__func__, seq));
+-					/* Force retry w/normal header read */
+-					bus->nextlen = 0;
+-					dhdsdio_rxfail(bus, false, true);
+-				}
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
+-				DHD_ERROR(("Received %d bytes on %d channel. Running out of " "rx pktbuf's or not yet malloced.\n",
+-					len, chan));
+-				continue;
+-			}
+-
+-			/* Validate data offset */
+-			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
+-				DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n",
+-					__func__, doff, len, SDPCM_HDRLEN));
+-				dhdsdio_rxfail(bus, false, false);
+-				dhdsdio_pktfree2(bus, pkt);
+-				continue;
+-			}
+-
+-			/* All done with this one -- now deliver the packet */
+-			goto deliver;
+-		}
+-		/* gSPI frames should not be handled in fractions */
+-		if (bus->bus == SPI_BUS)
+-			break;
+-
+-		/* Read frame header (hardware and software) */
+-		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh),
+-				SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread,
+-				NULL, NULL, NULL);
+-		bus->f2rxhdrs++;
+-		ASSERT(sdret != -BCME_PENDING);
+-
+-		if (sdret < 0) {
+-			DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__,
+-				   sdret));
+-			bus->rx_hdrfail++;
+-			dhdsdio_rxfail(bus, true, true);
+-			continue;
+-		}
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() || DHD_HDRS_ON()) {
+-			printk(KERN_DEBUG "RxHdr:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     bus->rxhdr, SDPCM_HDRLEN);
+-		}
+-#endif
+-
+-		/* Extract hardware header fields */
+-		len = get_unaligned_le16(bus->rxhdr);
+-		check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
+-
+-		/* All zeros means no more frames */
+-		if (!(len | check)) {
+-			*finished = true;
+-			break;
+-		}
+-
+-		/* Validate check bytes */
+-		if ((u16) ~(len ^ check)) {
+-			DHD_ERROR(("%s: HW hdr err: len/check 0x%04x/0x%04x\n",
+-				__func__, len, check));
+-			bus->rx_badhdr++;
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		/* Validate frame length */
+-		if (len < SDPCM_HDRLEN) {
+-			DHD_ERROR(("%s: HW hdr length invalid: %d\n",
+-				   __func__, len));
+-			continue;
+-		}
+-
+-		/* Extract software header fields */
+-		chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-		txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-		/* Validate data offset */
+-		if ((doff < SDPCM_HDRLEN) || (doff > len)) {
+-			DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d "
+-				"seq %d\n",
+-				__func__, doff, len, SDPCM_HDRLEN, seq));
+-			bus->rx_badhdr++;
+-			ASSERT(0);
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		/* Save the readahead length if there is one */
+-		bus->nextlen =
+-		    bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
+-		if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
+-			DHD_INFO(("%s (nextlen): got frame w/nextlen too large "
+-				"(%d), seq %d\n",
+-				__func__, bus->nextlen, seq));
+-			bus->nextlen = 0;
+-		}
+-
+-		/* Handle Flow Control */
+-		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+-
+-		if (bus->flowcontrol != fcbits) {
+-			if (~bus->flowcontrol & fcbits)
+-				bus->fc_xoff++;
+-
+-			if (bus->flowcontrol & ~fcbits)
+-				bus->fc_xon++;
+-
+-			bus->fc_rcvd++;
+-			bus->flowcontrol = fcbits;
+-		}
+-
+-		/* Check and update sequence number */
+-		if (rxseq != seq) {
+-			DHD_INFO(("%s: rx_seq %d, expected %d\n", __func__,
+-				  seq, rxseq));
+-			bus->rx_badseq++;
+-			rxseq = seq;
+-		}
+-
+-		/* Check window for sanity */
+-		if ((u8) (txmax - bus->tx_seq) > 0x40) {
+-			DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n",
+-				__func__, txmax, bus->tx_seq));
+-			txmax = bus->tx_seq + 2;
+-		}
+-		bus->tx_max = txmax;
+-
+-		/* Call a separate function for control frames */
+-		if (chan == SDPCM_CONTROL_CHANNEL) {
+-			dhdsdio_read_control(bus, bus->rxhdr, len, doff);
+-			continue;
+-		}
+-
+-		ASSERT((chan == SDPCM_DATA_CHANNEL)
+-		       || (chan == SDPCM_EVENT_CHANNEL)
+-		       || (chan == SDPCM_TEST_CHANNEL)
+-		       || (chan == SDPCM_GLOM_CHANNEL));
+-
+-		/* Length to read */
+-		rdlen = (len > firstread) ? (len - firstread) : 0;
+-
+-		/* May pad read to blocksize for efficiency */
+-		if (bus->roundup && bus->blocksize &&
+-			(rdlen > bus->blocksize)) {
+-			pad = bus->blocksize - (rdlen % bus->blocksize);
+-			if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
+-			    ((rdlen + pad + firstread) < MAX_RX_DATASZ))
+-				rdlen += pad;
+-		} else if (rdlen % DHD_SDALIGN) {
+-			rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN);
+-		}
+-
+-		/* Satisfy length-alignment requirements */
+-		if (forcealign && (rdlen & (ALIGNMENT - 1)))
+-			rdlen = roundup(rdlen, ALIGNMENT);
+-
+-		if ((rdlen + firstread) > MAX_RX_DATASZ) {
+-			/* Too long -- skip this frame */
+-			DHD_ERROR(("%s: too long: len %d rdlen %d\n",
+-				   __func__, len, rdlen));
+-			bus->dhd->rx_errors++;
+-			bus->rx_toolong++;
+-			dhdsdio_rxfail(bus, false, false);
+-			continue;
+-		}
+-
+-		dhd_os_sdlock_rxq(bus->dhd);
+-		pkt = bcm_pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN);
+-		if (!pkt) {
+-			/* Give up on data, request rtx of events */
+-			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed: rdlen %d "
+-				"chan %d\n", __func__, rdlen, chan));
+-			bus->dhd->rx_dropped++;
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			dhdsdio_rxfail(bus, false, RETRYCHAN(chan));
+-			continue;
+-		}
+-		dhd_os_sdunlock_rxq(bus->dhd);
+-
+-		ASSERT(!(pkt->prev));
+-
+-		/* Leave room for what we already read, and align remainder */
+-		ASSERT(firstread < pkt->len);
+-		skb_pull(pkt, firstread);
+-		PKTALIGN(pkt, rdlen, DHD_SDALIGN);
+-
+-		/* Read the remaining frame data */
+-		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, ((u8 *) (pkt->data)), rdlen,
+-					pkt, NULL, NULL);
+-		bus->f2rxdata++;
+-		ASSERT(sdret != -BCME_PENDING);
+-
+-		if (sdret < 0) {
+-			DHD_ERROR(("%s: read %d %s bytes failed: %d\n",
+-				   __func__, rdlen,
+-				   ((chan ==
+-				     SDPCM_EVENT_CHANNEL) ? "event" : ((chan ==
+-					SDPCM_DATA_CHANNEL)
+-				       ? "data" : "test")),
+-				   sdret));
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			bus->dhd->rx_errors++;
+-			dhdsdio_rxfail(bus, true, RETRYCHAN(chan));
+-			continue;
+-		}
+-
+-		/* Copy the already-read portion */
+-		skb_push(pkt, firstread);
+-		memcpy(pkt->data, bus->rxhdr, firstread);
+-
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-			printk(KERN_DEBUG "Rx Data:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-					     pkt->data, len);
+-		}
+-#endif
+-
+-deliver:
+-		/* Save superframe descriptor and allocate packet frame */
+-		if (chan == SDPCM_GLOM_CHANNEL) {
+-			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
+-				DHD_GLOM(("%s: glom descriptor, %d bytes:\n",
+-					__func__, len));
+-#ifdef DHD_DEBUG
+-				if (DHD_GLOM_ON()) {
+-					printk(KERN_DEBUG "Glom Data:\n");
+-					print_hex_dump_bytes("",
+-							     DUMP_PREFIX_OFFSET,
+-							     pkt->data, len);
+-				}
+-#endif
+-				__skb_trim(pkt, len);
+-				ASSERT(doff == SDPCM_HDRLEN);
+-				skb_pull(pkt, SDPCM_HDRLEN);
+-				bus->glomd = pkt;
+-			} else {
+-				DHD_ERROR(("%s: glom superframe w/o "
+-					"descriptor!\n", __func__));
+-				dhdsdio_rxfail(bus, false, false);
+-			}
+-			continue;
+-		}
+-
+-		/* Fill in packet len and prio, deliver upward */
+-		__skb_trim(pkt, len);
+-		skb_pull(pkt, doff);
+-
+-#ifdef SDTEST
+-		/* Test channel packets are processed separately */
+-		if (chan == SDPCM_TEST_CHANNEL) {
+-			dhdsdio_testrcv(bus, pkt, seq);
+-			continue;
+-		}
+-#endif				/* SDTEST */
+-
+-		if (pkt->len == 0) {
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			continue;
+-		} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) {
+-			DHD_ERROR(("%s: rx protocol error\n", __func__));
+-			dhd_os_sdlock_rxq(bus->dhd);
+-			bcm_pkt_buf_free_skb(pkt);
+-			dhd_os_sdunlock_rxq(bus->dhd);
+-			bus->dhd->rx_errors++;
+-			continue;
+-		}
+-
+-		/* Unlock during rx call */
+-		dhd_os_sdunlock(bus->dhd);
+-		dhd_rx_frame(bus->dhd, ifidx, pkt, 1);
+-		dhd_os_sdlock(bus->dhd);
+-	}
+-	rxcount = maxframes - rxleft;
+-#ifdef DHD_DEBUG
+-	/* Message if we hit the limit */
+-	if (!rxleft && !sdtest)
+-		DHD_DATA(("%s: hit rx limit of %d frames\n", __func__,
+-			  maxframes));
+-	else
+-#endif				/* DHD_DEBUG */
+-		DHD_DATA(("%s: processed %d frames\n", __func__, rxcount));
+-	/* Back off rxseq if awaiting rtx, update rx_seq */
+-	if (bus->rxskip)
+-		rxseq--;
+-	bus->rx_seq = rxseq;
+-
+-	return rxcount;
+-}
+-
+-static u32 dhdsdio_hostmail(dhd_bus_t *bus)
+-{
+-	sdpcmd_regs_t *regs = bus->regs;
+-	u32 intstatus = 0;
+-	u32 hmb_data;
+-	u8 fcbits;
+-	uint retries = 0;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Read mailbox data and ack that we did so */
+-	R_SDREG(hmb_data, &regs->tohostmailboxdata, retries);
+-	if (retries <= retry_limit)
+-		W_SDREG(SMB_INT_ACK, &regs->tosbmailbox, retries);
+-	bus->f1regdata += 2;
+-
+-	/* Dongle recomposed rx frames, accept them again */
+-	if (hmb_data & HMB_DATA_NAKHANDLED) {
+-		DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n",
+-			  bus->rx_seq));
+-		if (!bus->rxskip)
+-			DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __func__));
+-
+-		bus->rxskip = false;
+-		intstatus |= I_HMB_FRAME_IND;
+-	}
+-
+-	/*
+-	 * DEVREADY does not occur with gSPI.
+-	 */
+-	if (hmb_data & (HMB_DATA_DEVREADY | HMB_DATA_FWREADY)) {
+-		bus->sdpcm_ver =
+-		    (hmb_data & HMB_DATA_VERSION_MASK) >>
+-		    HMB_DATA_VERSION_SHIFT;
+-		if (bus->sdpcm_ver != SDPCM_PROT_VERSION)
+-			DHD_ERROR(("Version mismatch, dongle reports %d, "
+-				"expecting %d\n",
+-				bus->sdpcm_ver, SDPCM_PROT_VERSION));
+-		else
+-			DHD_INFO(("Dongle ready, protocol version %d\n",
+-				  bus->sdpcm_ver));
+-	}
+-
+-	/*
+-	 * Flow Control has been moved into the RX headers and this out of band
+-	 * method isn't used any more.
+-	 * remaining backward compatible with older dongles.
+-	 */
+-	if (hmb_data & HMB_DATA_FC) {
+-		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
+-							HMB_DATA_FCDATA_SHIFT;
+-
+-		if (fcbits & ~bus->flowcontrol)
+-			bus->fc_xoff++;
+-
+-		if (bus->flowcontrol & ~fcbits)
+-			bus->fc_xon++;
+-
+-		bus->fc_rcvd++;
+-		bus->flowcontrol = fcbits;
+-	}
+-
+-	/* Shouldn't be any others */
+-	if (hmb_data & ~(HMB_DATA_DEVREADY |
+-			 HMB_DATA_NAKHANDLED |
+-			 HMB_DATA_FC |
+-			 HMB_DATA_FWREADY |
+-			 HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) {
+-		DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data));
+-	}
+-
+-	return intstatus;
+-}
+-
+-bool dhdsdio_dpc(dhd_bus_t *bus)
+-{
+-	bcmsdh_info_t *sdh = bus->sdh;
+-	sdpcmd_regs_t *regs = bus->regs;
+-	u32 intstatus, newstatus = 0;
+-	uint retries = 0;
+-	uint rxlimit = dhd_rxbound;	/* Rx frames to read before resched */
+-	uint txlimit = dhd_txbound;	/* Tx frames to send before resched */
+-	uint framecnt = 0;	/* Temporary counter of tx/rx frames */
+-	bool rxdone = true;	/* Flag for no more read data */
+-	bool resched = false;	/* Flag indicating resched wanted */
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* Start with leftover status bits */
+-	intstatus = bus->intstatus;
+-
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* If waiting for HTAVAIL, check status */
+-	if (bus->clkstate == CLK_PENDING) {
+-		int err;
+-		u8 clkctl, devctl = 0;
+-
+-#ifdef DHD_DEBUG
+-		/* Check for inconsistent device control */
+-		devctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+-		if (err) {
+-			DHD_ERROR(("%s: error reading DEVCTL: %d\n",
+-				   __func__, err));
+-			bus->dhd->busstate = DHD_BUS_DOWN;
+-		} else {
+-			ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY);
+-		}
+-#endif				/* DHD_DEBUG */
+-
+-		/* Read CSR, if clock on switch to AVAIL, else ignore */
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-		if (err) {
+-			DHD_ERROR(("%s: error reading CSR: %d\n", __func__,
+-				   err));
+-			bus->dhd->busstate = DHD_BUS_DOWN;
+-		}
+-
+-		DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl,
+-			  clkctl));
+-
+-		if (SBSDIO_HTAV(clkctl)) {
+-			devctl =
+-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					    &err);
+-			if (err) {
+-				DHD_ERROR(("%s: error reading DEVCTL: %d\n",
+-					   __func__, err));
+-				bus->dhd->busstate = DHD_BUS_DOWN;
+-			}
+-			devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
+-					 devctl, &err);
+-			if (err) {
+-				DHD_ERROR(("%s: error writing DEVCTL: %d\n",
+-					   __func__, err));
+-				bus->dhd->busstate = DHD_BUS_DOWN;
+-			}
+-			bus->clkstate = CLK_AVAIL;
+-		} else {
+-			goto clkwait;
+-		}
+-	}
+-
+-	BUS_WAKE(bus);
+-
+-	/* Make sure backplane clock is on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, true);
+-	if (bus->clkstate == CLK_PENDING)
+-		goto clkwait;
+-
+-	/* Pending interrupt indicates new device status */
+-	if (bus->ipend) {
+-		bus->ipend = false;
+-		R_SDREG(newstatus, &regs->intstatus, retries);
+-		bus->f1regdata++;
+-		if (bcmsdh_regfail(bus->sdh))
+-			newstatus = 0;
+-		newstatus &= bus->hostintmask;
+-		bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
+-		if (newstatus) {
+-			W_SDREG(newstatus, &regs->intstatus, retries);
+-			bus->f1regdata++;
+-		}
+-	}
+-
+-	/* Merge new bits with previous */
+-	intstatus |= newstatus;
+-	bus->intstatus = 0;
+-
+-	/* Handle flow-control change: read new state in case our ack
+-	 * crossed another change interrupt.  If change still set, assume
+-	 * FC ON for safety, let next loop through do the debounce.
+-	 */
+-	if (intstatus & I_HMB_FC_CHANGE) {
+-		intstatus &= ~I_HMB_FC_CHANGE;
+-		W_SDREG(I_HMB_FC_CHANGE, &regs->intstatus, retries);
+-		R_SDREG(newstatus, &regs->intstatus, retries);
+-		bus->f1regdata += 2;
+-		bus->fcstate =
+-		    !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE));
+-		intstatus |= (newstatus & bus->hostintmask);
+-	}
+-
+-	/* Handle host mailbox indication */
+-	if (intstatus & I_HMB_HOST_INT) {
+-		intstatus &= ~I_HMB_HOST_INT;
+-		intstatus |= dhdsdio_hostmail(bus);
+-	}
+-
+-	/* Generally don't ask for these, can get CRC errors... */
+-	if (intstatus & I_WR_OOSYNC) {
+-		DHD_ERROR(("Dongle reports WR_OOSYNC\n"));
+-		intstatus &= ~I_WR_OOSYNC;
+-	}
+-
+-	if (intstatus & I_RD_OOSYNC) {
+-		DHD_ERROR(("Dongle reports RD_OOSYNC\n"));
+-		intstatus &= ~I_RD_OOSYNC;
+-	}
+-
+-	if (intstatus & I_SBINT) {
+-		DHD_ERROR(("Dongle reports SBINT\n"));
+-		intstatus &= ~I_SBINT;
+-	}
+-
+-	/* Would be active due to wake-wlan in gSPI */
+-	if (intstatus & I_CHIPACTIVE) {
+-		DHD_INFO(("Dongle reports CHIPACTIVE\n"));
+-		intstatus &= ~I_CHIPACTIVE;
+-	}
+-
+-	/* Ignore frame indications if rxskip is set */
+-	if (bus->rxskip)
+-		intstatus &= ~I_HMB_FRAME_IND;
+-
+-	/* On frame indication, read available frames */
+-	if (PKT_AVAILABLE()) {
+-		framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone);
+-		if (rxdone || bus->rxskip)
+-			intstatus &= ~I_HMB_FRAME_IND;
+-		rxlimit -= min(framecnt, rxlimit);
+-	}
+-
+-	/* Keep still-pending events for next scheduling */
+-	bus->intstatus = intstatus;
+-
+-clkwait:
+-#if defined(OOB_INTR_ONLY)
+-	bcmsdh_oob_intr_set(1);
+-#endif				/* (OOB_INTR_ONLY) */
+-	/* Re-enable interrupts to detect new device events (mailbox, rx frame)
+-	 * or clock availability.  (Allows tx loop to check ipend if desired.)
+-	 * (Unless register access seems hosed, as we may not be able to ACK...)
+-	 */
+-	if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
+-		DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
+-			  __func__, rxdone, framecnt));
+-		bus->intdis = false;
+-		bcmsdh_intr_enable(sdh);
+-	}
+-
+-	if (DATAOK(bus) && bus->ctrl_frame_stat &&
+-		(bus->clkstate == CLK_AVAIL)) {
+-		int ret, i;
+-
+-		ret =
+-		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+-					F2SYNC, (u8 *) bus->ctrl_frame_buf,
+-					(u32) bus->ctrl_frame_len, NULL,
+-					NULL, NULL);
+-		ASSERT(ret != -BCME_PENDING);
+-
+-		if (ret < 0) {
+-			/* On failure, abort the command and
+-				terminate the frame */
+-			DHD_INFO(("%s: sdio error %d, abort command and "
+-				"terminate frame.\n", __func__, ret));
+-			bus->tx_sderrs++;
+-
+-			bcmsdh_abort(sdh, SDIO_FUNC_2);
+-
+-			bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+-					 SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM,
+-					 NULL);
+-			bus->f1regdata++;
+-
+-			for (i = 0; i < 3; i++) {
+-				u8 hi, lo;
+-				hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCHI,
+-						     NULL);
+-				lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						     SBSDIO_FUNC1_WFRAMEBCLO,
+-						     NULL);
+-				bus->f1regdata += 2;
+-				if ((hi == 0) && (lo == 0))
+-					break;
+-			}
+-
+-		}
+-		if (ret == 0)
+-			bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
+-
+-		DHD_INFO(("Return_dpc value is : %d\n", ret));
+-		bus->ctrl_frame_stat = false;
+-		dhd_wait_event_wakeup(bus->dhd);
+-	}
+-	/* Send queued frames (limit 1 if rx may still be pending) */
+-	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
+-		 bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
+-		 && DATAOK(bus)) {
+-		framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax);
+-		framecnt = dhdsdio_sendfromq(bus, framecnt);
+-		txlimit -= framecnt;
+-	}
+-
+-	/* Resched if events or tx frames are pending,
+-		 else await next interrupt */
+-	/* On failed register access, all bets are off:
+-		 no resched or interrupts */
+-	if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) {
+-		DHD_ERROR(("%s: failed backplane access over SDIO, halting "
+-			"operation %d\n", __func__, bcmsdh_regfail(sdh)));
+-		bus->dhd->busstate = DHD_BUS_DOWN;
+-		bus->intstatus = 0;
+-	} else if (bus->clkstate == CLK_PENDING) {
+-		DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting "
+-			"I_CHIPACTIVE interrupt\n", __func__));
+-		resched = true;
+-	} else if (bus->intstatus || bus->ipend ||
+-		(!bus->fcstate && bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
+-			DATAOK(bus)) || PKT_AVAILABLE()) {
+-		resched = true;
+-	}
+-
+-	bus->dpc_sched = resched;
+-
+-	/* If we're done for now, turn off clock request. */
+-	if ((bus->clkstate != CLK_PENDING)
+-	    && bus->idletime == DHD_IDLE_IMMEDIATE) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return resched;
+-}
+-
+-bool dhd_bus_dpc(struct dhd_bus *bus)
+-{
+-	bool resched;
+-
+-	/* Call the DPC directly. */
+-	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
+-	resched = dhdsdio_dpc(bus);
+-
+-	return resched;
+-}
+-
+-void dhdsdio_isr(void *arg)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *) arg;
+-	bcmsdh_info_t *sdh;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (!bus) {
+-		DHD_ERROR(("%s : bus is null pointer , exit\n", __func__));
+-		return;
+-	}
+-	sdh = bus->sdh;
+-
+-	if (bus->dhd->busstate == DHD_BUS_DOWN) {
+-		DHD_ERROR(("%s : bus is down. we have nothing to do\n",
+-			   __func__));
+-		return;
+-	}
+-	/* Count the interrupt call */
+-	bus->intrcount++;
+-	bus->ipend = true;
+-
+-	/* Shouldn't get this interrupt if we're sleeping? */
+-	if (bus->sleeping) {
+-		DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n"));
+-		return;
+-	}
+-
+-	/* Disable additional interrupts (is this needed now)? */
+-	if (bus->intr)
+-		DHD_INTR(("%s: disable SDIO interrupts\n", __func__));
+-	else
+-		DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n"));
+-
+-	bcmsdh_intr_disable(sdh);
+-	bus->intdis = true;
+-
+-#if defined(SDIO_ISR_THREAD)
+-	DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__));
+-	while (dhdsdio_dpc(bus))
+-		;
+-#else
+-	bus->dpc_sched = true;
+-	dhd_sched_dpc(bus->dhd);
+-#endif
+-
+-}
+-
+-#ifdef SDTEST
+-static void dhdsdio_pktgen_init(dhd_bus_t *bus)
+-{
+-	/* Default to specified length, or full range */
+-	if (dhd_pktgen_len) {
+-		bus->pktgen_maxlen = min(dhd_pktgen_len, MAX_PKTGEN_LEN);
+-		bus->pktgen_minlen = bus->pktgen_maxlen;
+-	} else {
+-		bus->pktgen_maxlen = MAX_PKTGEN_LEN;
+-		bus->pktgen_minlen = 0;
+-	}
+-	bus->pktgen_len = (u16) bus->pktgen_minlen;
+-
+-	/* Default to per-watchdog burst with 10s print time */
+-	bus->pktgen_freq = 1;
+-	bus->pktgen_print = 10000 / dhd_watchdog_ms;
+-	bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000;
+-
+-	/* Default to echo mode */
+-	bus->pktgen_mode = DHD_PKTGEN_ECHO;
+-	bus->pktgen_stop = 1;
+-}
+-
+-static void dhdsdio_pktgen(dhd_bus_t *bus)
+-{
+-	struct sk_buff *pkt;
+-	u8 *data;
+-	uint pktcount;
+-	uint fillbyte;
+-	u16 len;
+-
+-	/* Display current count if appropriate */
+-	if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) {
+-		bus->pktgen_ptick = 0;
+-		printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n",
+-		       __func__, bus->pktgen_sent, bus->pktgen_rcvd);
+-	}
+-
+-	/* For recv mode, just make sure dongle has started sending */
+-	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+-		if (!bus->pktgen_rcvd)
+-			dhdsdio_sdtest_set(bus, true);
+-		return;
+-	}
+-
+-	/* Otherwise, generate or request the specified number of packets */
+-	for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) {
+-		/* Stop if total has been reached */
+-		if (bus->pktgen_total
+-		    && (bus->pktgen_sent >= bus->pktgen_total)) {
+-			bus->pktgen_count = 0;
+-			break;
+-		}
+-
+-		/* Allocate an appropriate-sized packet */
+-		len = bus->pktgen_len;
+-		pkt = bcm_pkt_buf_get_skb(
+-			(len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN),
+-			true);
+-		if (!pkt) {
+-			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n",
+-				__func__));
+-			break;
+-		}
+-		PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN),
+-			 DHD_SDALIGN);
+-		data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-
+-		/* Write test header cmd and extra based on mode */
+-		switch (bus->pktgen_mode) {
+-		case DHD_PKTGEN_ECHO:
+-			*data++ = SDPCM_TEST_ECHOREQ;
+-			*data++ = (u8) bus->pktgen_sent;
+-			break;
+-
+-		case DHD_PKTGEN_SEND:
+-			*data++ = SDPCM_TEST_DISCARD;
+-			*data++ = (u8) bus->pktgen_sent;
+-			break;
+-
+-		case DHD_PKTGEN_RXBURST:
+-			*data++ = SDPCM_TEST_BURST;
+-			*data++ = (u8) bus->pktgen_count;
+-			break;
+-
+-		default:
+-			DHD_ERROR(("Unrecognized pktgen mode %d\n",
+-				   bus->pktgen_mode));
+-			bcm_pkt_buf_free_skb(pkt, true);
+-			bus->pktgen_count = 0;
+-			return;
+-		}
+-
+-		/* Write test header length field */
+-		*data++ = (len >> 0);
+-		*data++ = (len >> 8);
+-
+-		/* Then fill in the remainder -- N/A for burst,
+-			 but who cares... */
+-		for (fillbyte = 0; fillbyte < len; fillbyte++)
+-			*data++ =
+-			    SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent);
+-
+-#ifdef DHD_DEBUG
+-		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+-			data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-			printk(KERN_DEBUG "dhdsdio_pktgen: Tx Data:\n");
+-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data,
+-					     pkt->len - SDPCM_HDRLEN);
+-		}
+-#endif
+-
+-		/* Send it */
+-		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) {
+-			bus->pktgen_fail++;
+-			if (bus->pktgen_stop
+-			    && bus->pktgen_stop == bus->pktgen_fail)
+-				bus->pktgen_count = 0;
+-		}
+-		bus->pktgen_sent++;
+-
+-		/* Bump length if not fixed, wrap at max */
+-		if (++bus->pktgen_len > bus->pktgen_maxlen)
+-			bus->pktgen_len = (u16) bus->pktgen_minlen;
+-
+-		/* Special case for burst mode: just send one request! */
+-		if (bus->pktgen_mode == DHD_PKTGEN_RXBURST)
+-			break;
+-	}
+-}
+-
+-static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start)
+-{
+-	struct sk_buff *pkt;
+-	u8 *data;
+-
+-	/* Allocate the packet */
+-	pkt = bcm_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
+-		DHD_SDALIGN, true);
+-	if (!pkt) {
+-		DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", __func__));
+-		return;
+-	}
+-	PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN);
+-	data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
+-
+-	/* Fill in the test header */
+-	*data++ = SDPCM_TEST_SEND;
+-	*data++ = start;
+-	*data++ = (bus->pktgen_maxlen >> 0);
+-	*data++ = (bus->pktgen_maxlen >> 8);
+-
+-	/* Send it */
+-	if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true))
+-		bus->pktgen_fail++;
+-}
+-
+-static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq)
+-{
+-	u8 *data;
+-	uint pktlen;
+-
+-	u8 cmd;
+-	u8 extra;
+-	u16 len;
+-	u16 offset;
+-
+-	/* Check for min length */
+-	pktlen = pkt->len;
+-	if (pktlen < SDPCM_TEST_HDRLEN) {
+-		DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n",
+-			   pktlen));
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		return;
+-	}
+-
+-	/* Extract header fields */
+-	data = pkt->data;
+-	cmd = *data++;
+-	extra = *data++;
+-	len = *data++;
+-	len += *data++ << 8;
+-
+-	/* Check length for relevant commands */
+-	if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ
+-	    || cmd == SDPCM_TEST_ECHORSP) {
+-		if (pktlen != len + SDPCM_TEST_HDRLEN) {
+-			DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, "
+-				"pktlen %d seq %d" " cmd %d extra %d len %d\n",
+-				pktlen, seq, cmd, extra, len));
+-			bcm_pkt_buf_free_skb(pkt, false);
+-			return;
+-		}
+-	}
+-
+-	/* Process as per command */
+-	switch (cmd) {
+-	case SDPCM_TEST_ECHOREQ:
+-		/* Rx->Tx turnaround ok (even on NDIS w/current
+-			 implementation) */
+-		*(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP;
+-		if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) {
+-			bus->pktgen_sent++;
+-		} else {
+-			bus->pktgen_fail++;
+-			bcm_pkt_buf_free_skb(pkt, false);
+-		}
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_ECHORSP:
+-		if (bus->ext_loop) {
+-			bcm_pkt_buf_free_skb(pkt, false);
+-			bus->pktgen_rcvd++;
+-			break;
+-		}
+-
+-		for (offset = 0; offset < len; offset++, data++) {
+-			if (*data != SDPCM_TEST_FILL(offset, extra)) {
+-				DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n",
+-					offset, len,
+-					SDPCM_TEST_FILL(offset, extra), *data));
+-				break;
+-			}
+-		}
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_DISCARD:
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		bus->pktgen_rcvd++;
+-		break;
+-
+-	case SDPCM_TEST_BURST:
+-	case SDPCM_TEST_SEND:
+-	default:
+-		DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, "
+-			"pktlen %d seq %d" " cmd %d extra %d len %d\n",
+-			pktlen, seq, cmd, extra, len));
+-		bcm_pkt_buf_free_skb(pkt, false);
+-		break;
+-	}
+-
+-	/* For recv mode, stop at limie (and tell dongle to stop sending) */
+-	if (bus->pktgen_mode == DHD_PKTGEN_RECV) {
+-		if (bus->pktgen_total
+-		    && (bus->pktgen_rcvd >= bus->pktgen_total)) {
+-			bus->pktgen_count = 0;
+-			dhdsdio_sdtest_set(bus, false);
+-		}
+-	}
+-}
+-#endif				/* SDTEST */
+-
+-extern bool dhd_bus_watchdog(dhd_pub_t *dhdp)
+-{
+-	dhd_bus_t *bus;
+-
+-	DHD_TIMER(("%s: Enter\n", __func__));
+-
+-	bus = dhdp->bus;
+-
+-	if (bus->dhd->dongle_reset)
+-		return false;
+-
+-	/* Ignore the timer if simulating bus down */
+-	if (bus->sleeping)
+-		return false;
+-
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Poll period: check device if appropriate. */
+-	if (bus->poll && (++bus->polltick >= bus->pollrate)) {
+-		u32 intstatus = 0;
+-
+-		/* Reset poll tick */
+-		bus->polltick = 0;
+-
+-		/* Check device if no interrupts */
+-		if (!bus->intr || (bus->intrcount == bus->lastintrs)) {
+-
+-			if (!bus->dpc_sched) {
+-				u8 devpend;
+-				devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0,
+-							  SDIOD_CCCR_INTPEND,
+-							  NULL);
+-				intstatus =
+-				    devpend & (INTR_STATUS_FUNC1 |
+-					       INTR_STATUS_FUNC2);
+-			}
+-
+-			/* If there is something, make like the ISR and
+-				 schedule the DPC */
+-			if (intstatus) {
+-				bus->pollcnt++;
+-				bus->ipend = true;
+-				if (bus->intr)
+-					bcmsdh_intr_disable(bus->sdh);
+-
+-				bus->dpc_sched = true;
+-				dhd_sched_dpc(bus->dhd);
+-
+-			}
+-		}
+-
+-		/* Update interrupt tracking */
+-		bus->lastintrs = bus->intrcount;
+-	}
+-#ifdef DHD_DEBUG
+-	/* Poll for console output periodically */
+-	if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) {
+-		bus->console.count += dhd_watchdog_ms;
+-		if (bus->console.count >= dhd_console_ms) {
+-			bus->console.count -= dhd_console_ms;
+-			/* Make sure backplane clock is on */
+-			dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-			if (dhdsdio_readconsole(bus) < 0)
+-				dhd_console_ms = 0;	/* On error,
+-							 stop trying */
+-		}
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef SDTEST
+-	/* Generate packets if configured */
+-	if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) {
+-		/* Make sure backplane clock is on */
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-		bus->pktgen_tick = 0;
+-		dhdsdio_pktgen(bus);
+-	}
+-#endif
+-
+-	/* On idle timeout clear activity flag and/or turn off clock */
+-	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+-		if (++bus->idlecount >= bus->idletime) {
+-			bus->idlecount = 0;
+-			if (bus->activity) {
+-				bus->activity = false;
+-				dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
+-			} else {
+-				dhdsdio_clkctl(bus, CLK_NONE, false);
+-			}
+-		}
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return bus->ipend;
+-}
+-
+-#ifdef DHD_DEBUG
+-extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen)
+-{
+-	dhd_bus_t *bus = dhdp->bus;
+-	u32 addr, val;
+-	int rv;
+-	struct sk_buff *pkt;
+-
+-	/* Address could be zero if CONSOLE := 0 in dongle Makefile */
+-	if (bus->console_addr == 0)
+-		return -ENOTSUPP;
+-
+-	/* Exclusive bus access */
+-	dhd_os_sdlock(bus->dhd);
+-
+-	/* Don't allow input if dongle is in reset */
+-	if (bus->dhd->dongle_reset) {
+-		dhd_os_sdunlock(bus->dhd);
+-		return -EPERM;
+-	}
+-
+-	/* Request clock to allow SDIO accesses */
+-	BUS_WAKE(bus);
+-	/* No pend allowed since txpkt is called later, ht clk has to be on */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	/* Zero cbuf_index */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf_idx);
+-	val = cpu_to_le32(0);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Write message into cbuf */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)msg, msglen);
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Write length into vcons_in */
+-	addr = bus->console_addr + offsetof(hndrte_cons_t, vcons_in);
+-	val = cpu_to_le32(msglen);
+-	rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val));
+-	if (rv < 0)
+-		goto done;
+-
+-	/* Bump dongle by sending an empty event pkt.
+-	 * sdpcm_sendup (RX) checks for virtual console input.
+-	 */
+-	pkt = bcm_pkt_buf_get_skb(4 + SDPCM_RESERVE);
+-	if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
+-		dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
+-
+-done:
+-	if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) {
+-		bus->activity = false;
+-		dhdsdio_clkctl(bus, CLK_NONE, true);
+-	}
+-
+-	dhd_os_sdunlock(bus->dhd);
+-
+-	return rv;
+-}
+-#endif				/* DHD_DEBUG */
+-
+-#ifdef DHD_DEBUG
+-static void dhd_dump_cis(uint fn, u8 *cis)
+-{
+-	uint byte, tag, tdata;
+-	DHD_INFO(("Function %d CIS:\n", fn));
+-
+-	for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) {
+-		if ((byte % 16) == 0)
+-			DHD_INFO(("    "));
+-		DHD_INFO(("%02x ", cis[byte]));
+-		if ((byte % 16) == 15)
+-			DHD_INFO(("\n"));
+-		if (!tdata--) {
+-			tag = cis[byte];
+-			if (tag == 0xff)
+-				break;
+-			else if (!tag)
+-				tdata = 0;
+-			else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT)
+-				tdata = cis[byte + 1] + 1;
+-			else
+-				DHD_INFO(("]"));
+-		}
+-	}
+-	if ((byte % 16) != 15)
+-		DHD_INFO(("\n"));
+-}
+-#endif				/* DHD_DEBUG */
+-
+-static bool dhdsdio_chipmatch(u16 chipid)
+-{
+-	if (chipid == BCM4325_CHIP_ID)
+-		return true;
+-	if (chipid == BCM4329_CHIP_ID)
+-		return true;
+-	if (chipid == BCM4319_CHIP_ID)
+-		return true;
+-	return false;
+-}
+-
+-static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no,
+-			   u16 slot, u16 func, uint bustype, void *regsva,
+-			   void *sdh)
+-{
+-	int ret;
+-	dhd_bus_t *bus;
+-
+-	/* Init global variables at run-time, not as part of the declaration.
+-	 * This is required to support init/de-init of the driver.
+-	 * Initialization
+-	 * of globals as part of the declaration results in non-deterministic
+-	 * behavior since the value of the globals may be different on the
+-	 * first time that the driver is initialized vs subsequent
+-	 * initializations.
+-	 */
+-	dhd_txbound = DHD_TXBOUND;
+-	dhd_rxbound = DHD_RXBOUND;
+-	dhd_alignctl = true;
+-	sd1idle = true;
+-	dhd_readahead = true;
+-	retrydata = false;
+-	dhd_dongle_memsize = 0;
+-	dhd_txminmax = DHD_TXMINMAX;
+-
+-	forcealign = true;
+-
+-	dhd_common_init();
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-	DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid));
+-
+-	/* We make assumptions about address window mappings */
+-	ASSERT((unsigned long)regsva == SI_ENUM_BASE);
+-
+-	/* BCMSDH passes venid and devid based on CIS parsing -- but
+-	 * low-power start
+-	 * means early parse could fail, so here we should get either an ID
+-	 * we recognize OR (-1) indicating we must request power first.
+-	 */
+-	/* Check the Vendor ID */
+-	switch (venid) {
+-	case 0x0000:
+-	case PCI_VENDOR_ID_BROADCOM:
+-		break;
+-	default:
+-		DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid));
+-		return NULL;
+-	}
+-
+-	/* Check the Device ID and make sure it's one that we support */
+-	switch (devid) {
+-	case BCM4325_D11DUAL_ID:	/* 4325 802.11a/g id */
+-	case BCM4325_D11G_ID:	/* 4325 802.11g 2.4Ghz band id */
+-	case BCM4325_D11A_ID:	/* 4325 802.11a 5Ghz band id */
+-		DHD_INFO(("%s: found 4325 Dongle\n", __func__));
+-		break;
+-	case BCM4329_D11NDUAL_ID:	/* 4329 802.11n dualband device */
+-	case BCM4329_D11N2G_ID:	/* 4329 802.11n 2.4G device */
+-	case BCM4329_D11N5G_ID:	/* 4329 802.11n 5G device */
+-	case 0x4329:
+-		DHD_INFO(("%s: found 4329 Dongle\n", __func__));
+-		break;
+-	case BCM4319_D11N_ID:	/* 4319 802.11n id */
+-	case BCM4319_D11N2G_ID:	/* 4319 802.11n2g id */
+-	case BCM4319_D11N5G_ID:	/* 4319 802.11n5g id */
+-		DHD_INFO(("%s: found 4319 Dongle\n", __func__));
+-		break;
+-	case 0:
+-		DHD_INFO(("%s: allow device id 0, will check chip internals\n",
+-			  __func__));
+-		break;
+-
+-	default:
+-		DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n",
+-			   __func__, venid, devid));
+-		return NULL;
+-	}
+-
+-	/* Allocate private bus interface state */
+-	bus = kzalloc(sizeof(dhd_bus_t), GFP_ATOMIC);
+-	if (!bus) {
+-		DHD_ERROR(("%s: kmalloc of dhd_bus_t failed\n", __func__));
+-		goto fail;
+-	}
+-	bus->sdh = sdh;
+-	bus->cl_devid = (u16) devid;
+-	bus->bus = DHD_BUS;
+-	bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
+-	bus->usebufpool = false;	/* Use bufpool if allocated,
+-					 else use locally malloced rxbuf */
+-
+-	/* attempt to attach to the dongle */
+-	if (!(dhdsdio_probe_attach(bus, sdh, regsva, devid))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Attach to the dhd/OS/network interface */
+-	bus->dhd = dhd_attach(bus, SDPCM_RESERVE);
+-	if (!bus->dhd) {
+-		DHD_ERROR(("%s: dhd_attach failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Allocate buffers */
+-	if (!(dhdsdio_probe_malloc(bus, sdh))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	if (!(dhdsdio_probe_init(bus, sdh))) {
+-		DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* Register interrupt callback, but mask it (not operational yet). */
+-	DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n",
+-		  __func__));
+-	bcmsdh_intr_disable(sdh);
+-	ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus);
+-	if (ret != 0) {
+-		DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n",
+-			   __func__, ret));
+-		goto fail;
+-	}
+-	DHD_INTR(("%s: registered SDIO interrupt function ok\n", __func__));
+-
+-	DHD_INFO(("%s: completed!!\n", __func__));
+-
+-	/* if firmware path present try to download and bring up bus */
+-	ret = dhd_bus_start(bus->dhd);
+-	if (ret != 0) {
+-		if (ret == -ENOLINK) {
+-			DHD_ERROR(("%s: dongle is not responding\n", __func__));
+-			goto fail;
+-		}
+-	}
+-	/* Ok, have the per-port tell the stack we're open for business */
+-	if (dhd_net_attach(bus->dhd, 0) != 0) {
+-		DHD_ERROR(("%s: Net attach failed!!\n", __func__));
+-		goto fail;
+-	}
+-
+-	return bus;
+-
+-fail:
+-	dhdsdio_release(bus);
+-	return NULL;
+-}
+-
+-static bool
+-dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid)
+-{
+-	u8 clkctl = 0;
+-	int err = 0;
+-
+-	bus->alp_only = true;
+-
+-	/* Return the window to backplane enumeration space for core access */
+-	if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE))
+-		DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __func__));
+-
+-#ifdef DHD_DEBUG
+-	printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
+-	       bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4));
+-
+-#endif				/* DHD_DEBUG */
+-
+-	/*
+-	 * Force PLL off until dhdsdio_chip_attach()
+-	 * programs PLL control regs
+-	 */
+-
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			 DHD_INIT_CLKCTL1, &err);
+-	if (!err)
+-		clkctl =
+-		    bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				    &err);
+-
+-	if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
+-		DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote "
+-			"0x%02x read 0x%02x\n",
+-			err, DHD_INIT_CLKCTL1, clkctl));
+-		goto fail;
+-	}
+-#ifdef DHD_DEBUG
+-	if (DHD_INFO_ON()) {
+-		uint fn, numfn;
+-		u8 *cis[SDIOD_MAX_IOFUNCS];
+-		int err = 0;
+-
+-		numfn = bcmsdh_query_iofnum(sdh);
+-		ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
+-
+-		/* Make sure ALP is available before trying to read CIS */
+-		SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
+-						    SBSDIO_FUNC1_CHIPCLKCSR,
+-						    NULL)),
+-			  !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY);
+-
+-		/* Now request ALP be put on the bus */
+-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-				 DHD_INIT_CLKCTL2, &err);
+-		udelay(65);
+-
+-		for (fn = 0; fn <= numfn; fn++) {
+-			cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC);
+-			if (!cis[fn]) {
+-				DHD_INFO(("dhdsdio_probe: fn %d cis malloc "
+-					"failed\n", fn));
+-				break;
+-			}
+-
+-			err = bcmsdh_cis_read(sdh, fn, cis[fn],
+-						SBSDIO_CIS_SIZE_LIMIT);
+-			if (err) {
+-				DHD_INFO(("dhdsdio_probe: fn %d cis read "
+-					"err %d\n", fn, err));
+-				kfree(cis[fn]);
+-				break;
+-			}
+-			dhd_dump_cis(fn, cis[fn]);
+-		}
+-
+-		while (fn-- > 0) {
+-			ASSERT(cis[fn]);
+-			kfree(cis[fn]);
+-		}
+-
+-		if (err) {
+-			DHD_ERROR(("dhdsdio_probe: error read/parsing CIS\n"));
+-			goto fail;
+-		}
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-	if (dhdsdio_chip_attach(bus, regsva)) {
+-		DHD_ERROR(("%s: dhdsdio_chip_attach failed!\n", __func__));
+-		goto fail;
+-	}
+-
+-	bcmsdh_chipinfo(sdh, bus->ci->chip, bus->ci->chiprev);
+-
+-	if (!dhdsdio_chipmatch((u16) bus->ci->chip)) {
+-		DHD_ERROR(("%s: unsupported chip: 0x%04x\n",
+-			   __func__, bus->ci->chip));
+-		goto fail;
+-	}
+-
+-	dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength);
+-
+-	/* Get info on the ARM and SOCRAM cores... */
+-	if (!DHD_NOPMU(bus)) {
+-		bus->armrev = SBCOREREV(bcmsdh_reg_read(bus->sdh,
+-			CORE_SB(bus->ci->armcorebase, sbidhigh), 4));
+-		bus->orig_ramsize = bus->ci->ramsize;
+-		if (!(bus->orig_ramsize)) {
+-			DHD_ERROR(("%s: failed to find SOCRAM memory!\n",
+-				   __func__));
+-			goto fail;
+-		}
+-		bus->ramsize = bus->orig_ramsize;
+-		if (dhd_dongle_memsize)
+-			dhd_dongle_setmemsize(bus, dhd_dongle_memsize);
+-
+-		DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n",
+-			   bus->ramsize, bus->orig_ramsize));
+-	}
+-
+-	bus->regs = (void *)bus->ci->buscorebase;
+-
+-	/* Set core control so an SDIO reset does a backplane reset */
+-	OR_REG(&bus->regs->corecontrol, CC_BPRESEN);
+-
+-	bcm_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
+-
+-	/* Locate an appropriately-aligned portion of hdrbuf */
+-	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN);
+-
+-	/* Set the poll and/or interrupt flags */
+-	bus->intr = (bool) dhd_intr;
+-	bus->poll = (bool) dhd_poll;
+-	if (bus->poll)
+-		bus->pollrate = 1;
+-
+-	return true;
+-
+-fail:
+-	return false;
+-}
+-
+-static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd->maxctl) {
+-		bus->rxblen =
+-		    roundup((bus->dhd->maxctl + SDPCM_HDRLEN),
+-			    ALIGNMENT) + DHD_SDALIGN;
+-		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
+-		if (!(bus->rxbuf)) {
+-			DHD_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n",
+-				   __func__, bus->rxblen));
+-			goto fail;
+-		}
+-	}
+-
+-	/* Allocate buffer to receive glomed packet */
+-	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
+-	if (!(bus->databuf)) {
+-		DHD_ERROR(("%s: kmalloc of %d-byte databuf failed\n",
+-			   __func__, MAX_DATA_BUF));
+-		/* release rxbuf which was already located as above */
+-		if (!bus->rxblen)
+-			kfree(bus->rxbuf);
+-		goto fail;
+-	}
+-
+-	/* Align the buffer */
+-	if ((unsigned long)bus->databuf % DHD_SDALIGN)
+-		bus->dataptr =
+-		    bus->databuf + (DHD_SDALIGN -
+-				    ((unsigned long)bus->databuf % DHD_SDALIGN));
+-	else
+-		bus->dataptr = bus->databuf;
+-
+-	return true;
+-
+-fail:
+-	return false;
+-}
+-
+-static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh)
+-{
+-	s32 fnum;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-#ifdef SDTEST
+-	dhdsdio_pktgen_init(bus);
+-#endif				/* SDTEST */
+-
+-	/* Disable F2 to clear any intermediate frame state on the dongle */
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1,
+-			 NULL);
+-
+-	bus->dhd->busstate = DHD_BUS_DOWN;
+-	bus->sleeping = false;
+-	bus->rxflow = false;
+-	bus->prev_rxlim_hit = 0;
+-
+-	/* Done with backplane-dependent accesses, can drop clock... */
+-	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);
+-
+-	/* ...and initialize clock/power states */
+-	bus->clkstate = CLK_SDONLY;
+-	bus->idletime = (s32) dhd_idletime;
+-	bus->idleclock = DHD_IDLE_ACTIVE;
+-
+-	/* Query the SD clock speed */
+-	if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0,
+-			    &bus->sd_divisor, sizeof(s32),
+-			    false) != 0) {
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor"));
+-		bus->sd_divisor = -1;
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_divisor", bus->sd_divisor));
+-	}
+-
+-	/* Query the SD bus mode */
+-	if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0,
+-			    &bus->sd_mode, sizeof(s32), false) != 0) {
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode"));
+-		bus->sd_mode = -1;
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_mode", bus->sd_mode));
+-	}
+-
+-	/* Query the F2 block size, set roundup accordingly */
+-	fnum = 2;
+-	if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32),
+-			    &bus->blocksize, sizeof(s32), false) != 0) {
+-		bus->blocksize = 0;
+-		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize"));
+-	} else {
+-		DHD_INFO(("%s: Initial value for %s is %d\n",
+-			  __func__, "sd_blocksize", bus->blocksize));
+-	}
+-	bus->roundup = min(max_roundup, bus->blocksize);
+-
+-	/* Query if bus module supports packet chaining,
+-		 default to use if supported */
+-	if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0,
+-			    &bus->sd_rxchain, sizeof(s32),
+-			    false) != 0) {
+-		bus->sd_rxchain = false;
+-	} else {
+-		DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n",
+-			  __func__,
+-			  (bus->sd_rxchain ? "supports" : "does not support")));
+-	}
+-	bus->use_rxchain = (bool) bus->sd_rxchain;
+-
+-	return true;
+-}
+-
+-bool
+-dhd_bus_download_firmware(struct dhd_bus *bus, char *fw_path, char *nv_path)
+-{
+-	bool ret;
+-	bus->fw_path = fw_path;
+-	bus->nv_path = nv_path;
+-
+-	ret = dhdsdio_download_firmware(bus, bus->sdh);
+-
+-	return ret;
+-}
+-
+-static bool
+-dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh)
+-{
+-	bool ret;
+-
+-	/* Download the firmware */
+-	dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-
+-	ret = _dhdsdio_download_firmware(bus) == 0;
+-
+-	dhdsdio_clkctl(bus, CLK_SDONLY, false);
+-
+-	return ret;
+-}
+-
+-/* Detach and free everything */
+-static void dhdsdio_release(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus) {
+-		/* De-register interrupt handler */
+-		bcmsdh_intr_disable(bus->sdh);
+-		bcmsdh_intr_dereg(bus->sdh);
+-
+-		if (bus->dhd) {
+-			dhd_detach(bus->dhd);
+-			dhdsdio_release_dongle(bus);
+-			bus->dhd = NULL;
+-		}
+-
+-		dhdsdio_release_malloc(bus);
+-
+-		kfree(bus);
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-static void dhdsdio_release_malloc(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd && bus->dhd->dongle_reset)
+-		return;
+-
+-	if (bus->rxbuf) {
+-		kfree(bus->rxbuf);
+-		bus->rxctl = bus->rxbuf = NULL;
+-		bus->rxlen = 0;
+-	}
+-
+-	kfree(bus->databuf);
+-	bus->databuf = NULL;
+-}
+-
+-static void dhdsdio_release_dongle(dhd_bus_t *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus->dhd && bus->dhd->dongle_reset)
+-		return;
+-
+-	if (bus->ci) {
+-		dhdsdio_clkctl(bus, CLK_AVAIL, false);
+-		dhdsdio_clkctl(bus, CLK_NONE, false);
+-		dhdsdio_chip_detach(bus);
+-		if (bus->vars && bus->varsz)
+-			kfree(bus->vars);
+-		bus->vars = NULL;
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-static void dhdsdio_disconnect(void *ptr)
+-{
+-	dhd_bus_t *bus = (dhd_bus_t *)ptr;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	if (bus) {
+-		ASSERT(bus->dhd);
+-		dhdsdio_release(bus);
+-	}
+-
+-	DHD_TRACE(("%s: Disconnected\n", __func__));
+-}
+-
+-/* Register/Unregister functions are called by the main DHD entry
+- * point (e.g. module insertion) to link with the bus driver, in
+- * order to look for or await the device.
+- */
+-
+-static bcmsdh_driver_t dhd_sdio = {
+-	dhdsdio_probe,
+-	dhdsdio_disconnect
+-};
+-
+-int dhd_bus_register(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	return bcmsdh_register(&dhd_sdio);
+-}
+-
+-void dhd_bus_unregister(void)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	bcmsdh_unregister();
+-}
+-
+-#ifdef BCMEMBEDIMAGE
+-static int dhdsdio_download_code_array(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-	int offset = 0;
+-
+-	DHD_INFO(("%s: download embedded firmware...\n", __func__));
+-
+-	/* Download image */
+-	while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+-		bcmerror =
+-		    dhdsdio_membytes(bus, true, offset, dlarray + offset,
+-				     MEMBLOCK);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-				"0x%08x\n",
+-				__func__, bcmerror, MEMBLOCK, offset));
+-			goto err;
+-		}
+-
+-		offset += MEMBLOCK;
+-	}
+-
+-	if (offset < sizeof(dlarray)) {
+-		bcmerror = dhdsdio_membytes(bus, true, offset,
+-					    dlarray + offset,
+-					    sizeof(dlarray) - offset);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-				"0x%08x\n", __func__, bcmerror,
+-				sizeof(dlarray) - offset, offset));
+-			goto err;
+-		}
+-	}
+-#ifdef DHD_DEBUG
+-	/* Upload and compare the downloaded code */
+-	{
+-		unsigned char *ularray;
+-
+-		ularray = kmalloc(bus->ramsize, GFP_ATOMIC);
+-		if (!ularray) {
+-			bcmerror = -ENOMEM;
+-			goto err;
+-		}
+-		/* Upload image to verify downloaded contents. */
+-		offset = 0;
+-		memset(ularray, 0xaa, bus->ramsize);
+-		while ((offset + MEMBLOCK) < sizeof(dlarray)) {
+-			bcmerror =
+-			    dhdsdio_membytes(bus, false, offset,
+-					     ularray + offset, MEMBLOCK);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: error %d on reading %d membytes"
+-					" at 0x%08x\n",
+-					__func__, bcmerror, MEMBLOCK, offset));
+-				goto free;
+-			}
+-
+-			offset += MEMBLOCK;
+-		}
+-
+-		if (offset < sizeof(dlarray)) {
+-			bcmerror = dhdsdio_membytes(bus, false, offset,
+-						    ularray + offset,
+-						    sizeof(dlarray) - offset);
+-			if (bcmerror) {
+-				DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n",
+-				__func__, bcmerror,
+-				sizeof(dlarray) - offset, offset));
+-				goto free;
+-			}
+-		}
+-
+-		if (memcmp(dlarray, ularray, sizeof(dlarray))) {
+-			DHD_ERROR(("%s: Downloaded image is corrupted.\n",
+-				   __func__));
+-			ASSERT(0);
+-			goto free;
+-		} else
+-			DHD_ERROR(("%s: Download/Upload/Compare succeeded.\n",
+-				__func__));
+-free:
+-		kfree(ularray);
+-	}
+-#endif				/* DHD_DEBUG */
+-
+-err:
+-	return bcmerror;
+-}
+-#endif				/* BCMEMBEDIMAGE */
+-
+-static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
+-{
+-	int bcmerror = -1;
+-	int offset = 0;
+-	uint len;
+-	void *image = NULL;
+-	u8 *memblock = NULL, *memptr;
+-
+-	DHD_INFO(("%s: download firmware %s\n", __func__, fw_path));
+-
+-	image = dhd_os_open_image(fw_path);
+-	if (image == NULL)
+-		goto err;
+-
+-	memptr = memblock = kmalloc(MEMBLOCK + DHD_SDALIGN, GFP_ATOMIC);
+-	if (memblock == NULL) {
+-		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+-			   __func__, MEMBLOCK));
+-		goto err;
+-	}
+-	if ((u32)(unsigned long)memblock % DHD_SDALIGN)
+-		memptr +=
+-		    (DHD_SDALIGN - ((u32)(unsigned long)memblock % DHD_SDALIGN));
+-
+-	/* Download image */
+-	while ((len =
+-		dhd_os_get_image_block((char *)memptr, MEMBLOCK, image))) {
+-		bcmerror = dhdsdio_membytes(bus, true, offset, memptr, len);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error %d on writing %d membytes at "
+-			"0x%08x\n", __func__, bcmerror, MEMBLOCK, offset));
+-			goto err;
+-		}
+-
+-		offset += MEMBLOCK;
+-	}
+-
+-err:
+-	kfree(memblock);
+-
+-	if (image)
+-		dhd_os_close_image(image);
+-
+-	return bcmerror;
+-}
+-
+-/*
+- * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file
+- * and ending in a NUL.
+- * Removes carriage returns, empty lines, comment lines, and converts
+- * newlines to NULs.
+- * Shortens buffer as needed and pads with NULs.  End of buffer is marked
+- * by two NULs.
+-*/
+-
+-static uint process_nvram_vars(char *varbuf, uint len)
+-{
+-	char *dp;
+-	bool findNewline;
+-	int column;
+-	uint buf_len, n;
+-
+-	dp = varbuf;
+-
+-	findNewline = false;
+-	column = 0;
+-
+-	for (n = 0; n < len; n++) {
+-		if (varbuf[n] == 0)
+-			break;
+-		if (varbuf[n] == '\r')
+-			continue;
+-		if (findNewline && varbuf[n] != '\n')
+-			continue;
+-		findNewline = false;
+-		if (varbuf[n] == '#') {
+-			findNewline = true;
+-			continue;
+-		}
+-		if (varbuf[n] == '\n') {
+-			if (column == 0)
+-				continue;
+-			*dp++ = 0;
+-			column = 0;
+-			continue;
+-		}
+-		*dp++ = varbuf[n];
+-		column++;
+-	}
+-	buf_len = dp - varbuf;
+-
+-	while (dp < varbuf + n)
+-		*dp++ = 0;
+-
+-	return buf_len;
+-}
+-
+-/*
+-	EXAMPLE: nvram_array
+-	nvram_arry format:
+-	name=value
+-	Use carriage return at the end of each assignment,
+-	 and an empty string with
+-	carriage return at the end of array.
+-
+-	For example:
+-	unsigned char  nvram_array[] = {"name1=value1\n",
+-	"name2=value2\n", "\n"};
+-	Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx.
+-
+-	Search "EXAMPLE: nvram_array" to see how the array is activated.
+-*/
+-
+-void dhd_bus_set_nvram_params(struct dhd_bus *bus, const char *nvram_params)
+-{
+-	bus->nvram_params = nvram_params;
+-}
+-
+-static int dhdsdio_download_nvram(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-	uint len;
+-	void *image = NULL;
+-	char *memblock = NULL;
+-	char *bufp;
+-	char *nv_path;
+-	bool nvram_file_exists;
+-
+-	nv_path = bus->nv_path;
+-
+-	nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
+-	if (!nvram_file_exists && (bus->nvram_params == NULL))
+-		return 0;
+-
+-	if (nvram_file_exists) {
+-		image = dhd_os_open_image(nv_path);
+-		if (image == NULL)
+-			goto err;
+-	}
+-
+-	memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
+-	if (memblock == NULL) {
+-		DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+-			   __func__, MEMBLOCK));
+-		goto err;
+-	}
+-
+-	/* Download variables */
+-	if (nvram_file_exists) {
+-		len = dhd_os_get_image_block(memblock, MEMBLOCK, image);
+-	} else {
+-		len = strlen(bus->nvram_params);
+-		ASSERT(len <= MEMBLOCK);
+-		if (len > MEMBLOCK)
+-			len = MEMBLOCK;
+-		memcpy(memblock, bus->nvram_params, len);
+-	}
+-
+-	if (len > 0 && len < MEMBLOCK) {
+-		bufp = (char *)memblock;
+-		bufp[len] = 0;
+-		len = process_nvram_vars(bufp, len);
+-		bufp += len;
+-		*bufp++ = 0;
+-		if (len)
+-			bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1);
+-		if (bcmerror) {
+-			DHD_ERROR(("%s: error downloading vars: %d\n",
+-				   __func__, bcmerror));
+-		}
+-	} else {
+-		DHD_ERROR(("%s: error reading nvram file: %d\n",
+-			   __func__, len));
+-		bcmerror = -EIO;
+-	}
+-
+-err:
+-	kfree(memblock);
+-
+-	if (image)
+-		dhd_os_close_image(image);
+-
+-	return bcmerror;
+-}
+-
+-static int _dhdsdio_download_firmware(struct dhd_bus *bus)
+-{
+-	int bcmerror = -1;
+-
+-	bool embed = false;	/* download embedded firmware */
+-	bool dlok = false;	/* download firmware succeeded */
+-
+-	/* Out immediately if no image to download */
+-	if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) {
+-#ifdef BCMEMBEDIMAGE
+-		embed = true;
+-#else
+-		return bcmerror;
+-#endif
+-	}
+-
+-	/* Keep arm in reset */
+-	if (dhdsdio_download_state(bus, true)) {
+-		DHD_ERROR(("%s: error placing ARM core in reset\n", __func__));
+-		goto err;
+-	}
+-
+-	/* External image takes precedence if specified */
+-	if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) {
+-		if (dhdsdio_download_code_file(bus, bus->fw_path)) {
+-			DHD_ERROR(("%s: dongle image file download failed\n",
+-				   __func__));
+-#ifdef BCMEMBEDIMAGE
+-			embed = true;
+-#else
+-			goto err;
+-#endif
+-		} else {
+-			embed = false;
+-			dlok = true;
+-		}
+-	}
+-#ifdef BCMEMBEDIMAGE
+-	if (embed) {
+-		if (dhdsdio_download_code_array(bus)) {
+-			DHD_ERROR(("%s: dongle image array download failed\n",
+-				   __func__));
+-			goto err;
+-		} else {
+-			dlok = true;
+-		}
+-	}
+-#endif
+-	if (!dlok) {
+-		DHD_ERROR(("%s: dongle image download failed\n", __func__));
+-		goto err;
+-	}
+-
+-	/* EXAMPLE: nvram_array */
+-	/* If a valid nvram_arry is specified as above, it can be passed
+-		 down to dongle */
+-	/* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */
+-
+-	/* External nvram takes precedence if specified */
+-	if (dhdsdio_download_nvram(bus)) {
+-		DHD_ERROR(("%s: dongle nvram file download failed\n",
+-			   __func__));
+-	}
+-
+-	/* Take arm out of reset */
+-	if (dhdsdio_download_state(bus, false)) {
+-		DHD_ERROR(("%s: error getting out of ARM core reset\n",
+-			   __func__));
+-		goto err;
+-	}
+-
+-	bcmerror = 0;
+-
+-err:
+-	return bcmerror;
+-}
+-
+-
+-static int
+-dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
+-		    u8 *buf, uint nbytes, struct sk_buff *pkt,
+-		    bcmsdh_cmplt_fn_t complete, void *handle)
+-{
+-	return bcmsdh_send_buf
+-		(bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete,
+-		 handle);
+-}
+-
+-uint dhd_bus_chip(struct dhd_bus *bus)
+-{
+-	ASSERT(bus->ci != NULL);
+-	return bus->ci->chip;
+-}
+-
+-void *dhd_bus_pub(struct dhd_bus *bus)
+-{
+-	return bus->dhd;
+-}
+-
+-void *dhd_bus_txq(struct dhd_bus *bus)
+-{
+-	return &bus->txq;
+-}
+-
+-uint dhd_bus_hdrlen(struct dhd_bus *bus)
+-{
+-	return SDPCM_HDRLEN;
+-}
+-
+-int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag)
+-{
+-	int bcmerror = 0;
+-	dhd_bus_t *bus;
+-
+-	bus = dhdp->bus;
+-
+-	if (flag == true) {
+-		if (!bus->dhd->dongle_reset) {
+-			/* Expect app to have torn down any
+-			 connection before calling */
+-			/* Stop the bus, disable F2 */
+-			dhd_bus_stop(bus, false);
+-
+-			/* Clean tx/rx buffer pointers,
+-			 detach from the dongle */
+-			dhdsdio_release_dongle(bus);
+-
+-			bus->dhd->dongle_reset = true;
+-			bus->dhd->up = false;
+-
+-			DHD_TRACE(("%s:  WLAN OFF DONE\n", __func__));
+-			/* App can now remove power from device */
+-		} else
+-			bcmerror = -EIO;
+-	} else {
+-		/* App must have restored power to device before calling */
+-
+-		DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __func__));
+-
+-		if (bus->dhd->dongle_reset) {
+-			/* Turn on WLAN */
+-			/* Reset SD client */
+-			bcmsdh_reset(bus->sdh);
+-
+-			/* Attempt to re-attach & download */
+-			if (dhdsdio_probe_attach(bus, bus->sdh,
+-						 (u32 *) SI_ENUM_BASE,
+-						 bus->cl_devid)) {
+-				/* Attempt to download binary to the dongle */
+-				if (dhdsdio_probe_init
+-				    (bus, bus->sdh)
+-				    && dhdsdio_download_firmware(bus,
+-								 bus->sdh)) {
+-
+-					/* Re-init bus, enable F2 transfer */
+-					dhd_bus_init((dhd_pub_t *) bus->dhd,
+-						     false);
+-
+-#if defined(OOB_INTR_ONLY)
+-					dhd_enable_oob_intr(bus, true);
+-#endif				/* defined(OOB_INTR_ONLY) */
+-
+-					bus->dhd->dongle_reset = false;
+-					bus->dhd->up = true;
+-
+-					DHD_TRACE(("%s: WLAN ON DONE\n",
+-						   __func__));
+-				} else
+-					bcmerror = -EIO;
+-			} else
+-				bcmerror = -EIO;
+-		} else {
+-			bcmerror = -EISCONN;
+-			DHD_ERROR(("%s: Set DEVRESET=false invoked when device "
+-				"is on\n", __func__));
+-			bcmerror = -EIO;
+-		}
+-	}
+-	return bcmerror;
+-}
+-
+-static int
+-dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs)
+-{
+-	u32 regdata;
+-
+-	/*
+-	 * Get CC core rev
+-	 * Chipid is assume to be at offset 0 from regs arg
+-	 * For different chiptypes or old sdio hosts w/o chipcommon,
+-	 * other ways of recognition should be added here.
+-	 */
+-	ci->cccorebase = (u32)regs;
+-	regdata = bcmsdh_reg_read(sdh, CORE_CC_REG(ci->cccorebase, chipid), 4);
+-	ci->chip = regdata & CID_ID_MASK;
+-	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
+-
+-	DHD_INFO(("%s: chipid=0x%x chiprev=%d\n",
+-		__func__, ci->chip, ci->chiprev));
+-
+-	/* Address of cores for new chips should be added here */
+-	switch (ci->chip) {
+-	case BCM4329_CHIP_ID:
+-		ci->buscorebase = BCM4329_CORE_BUS_BASE;
+-		ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
+-		ci->armcorebase	= BCM4329_CORE_ARM_BASE;
+-		ci->ramsize = BCM4329_RAMSIZE;
+-		break;
+-	default:
+-		DHD_ERROR(("%s: chipid 0x%x is not supported\n",
+-			__func__, ci->chip));
+-		return -ENODEV;
+-	}
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(ci->cccorebase, sbidhigh), 4);
+-	ci->ccrev = SBCOREREV(regdata);
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
+-	ci->pmurev = regdata & PCAP_REV_MASK;
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(ci->buscorebase, sbidhigh), 4);
+-	ci->buscorerev = SBCOREREV(regdata);
+-	ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
+-
+-	DHD_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
+-		__func__, ci->ccrev, ci->pmurev,
+-		ci->buscorerev, ci->buscoretype));
+-
+-	/* get chipcommon capabilites */
+-	ci->cccaps = bcmsdh_reg_read(sdh,
+-		CORE_CC_REG(ci->cccorebase, capabilities), 4);
+-
+-	return 0;
+-}
+-
+-static void
+-dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase)
+-{
+-	u32 regdata;
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(corebase, sbtmstatelow), 4);
+-	if (regdata & SBTML_RESET)
+-		return;
+-
+-	regdata = bcmsdh_reg_read(sdh,
+-		CORE_SB(corebase, sbtmstatelow), 4);
+-	if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
+-		/*
+-		 * set target reject and spin until busy is clear
+-		 * (preserve core-specific bits)
+-		 */
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-			regdata | SBTML_REJ);
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		udelay(1);
+-		SPINWAIT((bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatehigh), 4) &
+-			SBTMH_BUSY), 100000);
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatehigh), 4);
+-		if (regdata & SBTMH_BUSY)
+-			DHD_ERROR(("%s: ARM core still busy\n", __func__));
+-
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbidlow), 4);
+-		if (regdata & SBIDL_INIT) {
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) |
+-				SBIM_RJ;
+-			bcmsdh_reg_write(sdh,
+-				CORE_SB(corebase, sbimstate), 4,
+-				regdata);
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4);
+-			udelay(1);
+-			SPINWAIT((bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) &
+-				SBIM_BY), 100000);
+-		}
+-
+-		/* set reset and reject while enabling the clocks */
+-		bcmsdh_reg_write(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4,
+-			(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+-			SBTML_REJ | SBTML_RESET));
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbtmstatelow), 4);
+-		udelay(10);
+-
+-		/* clear the initiator reject bit */
+-		regdata = bcmsdh_reg_read(sdh,
+-			CORE_SB(corebase, sbidlow), 4);
+-		if (regdata & SBIDL_INIT) {
+-			regdata = bcmsdh_reg_read(sdh,
+-				CORE_SB(corebase, sbimstate), 4) &
+-				~SBIM_RJ;
+-			bcmsdh_reg_write(sdh,
+-				CORE_SB(corebase, sbimstate), 4,
+-				regdata);
+-		}
+-	}
+-
+-	/* leave reset and reject asserted */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SBTML_REJ | SBTML_RESET));
+-	udelay(1);
+-}
+-
+-static int
+-dhdsdio_chip_attach(struct dhd_bus *bus, void *regs)
+-{
+-	struct chip_info *ci;
+-	int err;
+-	u8 clkval, clkset;
+-
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	/* alloc chip_info_t */
+-	ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC);
+-	if (NULL == ci) {
+-		DHD_ERROR(("%s: malloc failed!\n", __func__));
+-		return -ENOMEM;
+-	}
+-
+-	memset((unsigned char *)ci, 0, sizeof(struct chip_info));
+-
+-	/* bus/core/clk setup for register access */
+-	/* Try forcing SDIO core to do ALPAvail request only */
+-	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+-			clkset, &err);
+-	if (err) {
+-		DHD_ERROR(("%s: error writing for HT off\n", __func__));
+-		goto fail;
+-	}
+-
+-	/* If register supported, wait for ALPAvail and then force ALP */
+-	/* This may take up to 15 milliseconds */
+-	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-			SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+-	if ((clkval & ~SBSDIO_AVBITS) == clkset) {
+-		SPINWAIT(((clkval =
+-				bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-						SBSDIO_FUNC1_CHIPCLKCSR,
+-						NULL)),
+-				!SBSDIO_ALPAV(clkval)),
+-				PMU_MAX_TRANSITION_DLY);
+-		if (!SBSDIO_ALPAV(clkval)) {
+-			DHD_ERROR(("%s: timeout on ALPAV wait, clkval 0x%02x\n",
+-				__func__, clkval));
+-			err = -EBUSY;
+-			goto fail;
+-		}
+-		clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
+-				SBSDIO_FORCE_ALP;
+-		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+-				SBSDIO_FUNC1_CHIPCLKCSR,
+-				clkset, &err);
+-		udelay(65);
+-	} else {
+-		DHD_ERROR(("%s: ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
+-			__func__, clkset, clkval));
+-		err = -EACCES;
+-		goto fail;
+-	}
+-
+-	/* Also, disable the extra SDIO pull-ups */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
+-			 NULL);
+-
+-	err = dhdsdio_chip_recognition(bus->sdh, ci, regs);
+-	if (err)
+-		goto fail;
+-
+-	/*
+-	 * Make sure any on-chip ARM is off (in case strapping is wrong),
+-	 * or downloaded code was already running.
+-	 */
+-	dhdsdio_chip_disablecore(bus->sdh, ci->armcorebase);
+-
+-	bcmsdh_reg_write(bus->sdh,
+-		CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
+-	bcmsdh_reg_write(bus->sdh,
+-		CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
+-
+-	/* Disable F2 to clear any intermediate frame state on the dongle */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
+-		SDIO_FUNC_ENABLE_1, NULL);
+-
+-	/* WAR: cmd52 backplane read so core HW will drop ALPReq */
+-	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+-			0, NULL);
+-
+-	/* Done with backplane-dependent accesses, can drop clock... */
+-	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0,
+-			 NULL);
+-
+-	bus->ci = ci;
+-	return 0;
+-fail:
+-	bus->ci = NULL;
+-	kfree(ci);
+-	return err;
+-}
+-
+-static void
+-dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase)
+-{
+-	u32 regdata;
+-
+-	/*
+-	 * Must do the disable sequence first to work for
+-	 * arbitrary current core state.
+-	 */
+-	dhdsdio_chip_disablecore(sdh, corebase);
+-
+-	/*
+-	 * Now do the initialization sequence.
+-	 * set reset while enabling the clock and
+-	 * forcing them on throughout the core
+-	 */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+-		SBTML_RESET);
+-	udelay(1);
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbtmstatehigh), 4);
+-	if (regdata & SBTMH_SERR)
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatehigh), 4, 0);
+-
+-	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbimstate), 4);
+-	if (regdata & (SBIM_IBE | SBIM_TO))
+-		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbimstate), 4,
+-			regdata & ~(SBIM_IBE | SBIM_TO));
+-
+-	/* clear reset and allow it to propagate throughout the core */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SICF_FGC << SBTML_SICF_SHIFT) |
+-		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-	udelay(1);
+-
+-	/* leave clock enabled */
+-	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+-		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+-	udelay(1);
+-}
+-
+-/* SDIO Pad drive strength to select value mappings */
+-struct sdiod_drive_str {
+-	u8 strength;	/* Pad Drive Strength in mA */
+-	u8 sel;		/* Chip-specific select value */
+-};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 1 */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
+-	{
+-	4, 0x2}, {
+-	2, 0x3}, {
+-	1, 0x0}, {
+-	0, 0x0}
+-	};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
+-	{
+-	12, 0x7}, {
+-	10, 0x6}, {
+-	8, 0x5}, {
+-	6, 0x4}, {
+-	4, 0x2}, {
+-	2, 0x1}, {
+-	0, 0x0}
+-	};
+-
+-/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
+-static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
+-	{
+-	32, 0x7}, {
+-	26, 0x6}, {
+-	22, 0x5}, {
+-	16, 0x4}, {
+-	12, 0x3}, {
+-	8, 0x2}, {
+-	4, 0x1}, {
+-	0, 0x0}
+-	};
+-
+-#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
+-
+-static void
+-dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) {
+-	struct sdiod_drive_str *str_tab = NULL;
+-	u32 str_mask = 0;
+-	u32 str_shift = 0;
+-	char chn[8];
+-
+-	if (!(bus->ci->cccaps & CC_CAP_PMU))
+-		return;
+-
+-	switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
+-		str_mask = 0x30000000;
+-		str_shift = 28;
+-		break;
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
+-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
+-		str_mask = 0x00003800;
+-		str_shift = 11;
+-		break;
+-	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
+-		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
+-		str_mask = 0x00003800;
+-		str_shift = 11;
+-		break;
+-	default:
+-		DHD_ERROR(("No SDIO Drive strength init"
+-			"done for chip %s rev %d pmurev %d\n",
+-			bcm_chipname(bus->ci->chip, chn, 8),
+-			bus->ci->chiprev, bus->ci->pmurev));
+-		break;
+-	}
+-
+-	if (str_tab != NULL) {
+-		u32 drivestrength_sel = 0;
+-		u32 cc_data_temp;
+-		int i;
+-
+-		for (i = 0; str_tab[i].strength != 0; i++) {
+-			if (drivestrength >= str_tab[i].strength) {
+-				drivestrength_sel = str_tab[i].sel;
+-				break;
+-			}
+-		}
+-
+-		bcmsdh_reg_write(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+-			4, 1);
+-		cc_data_temp = bcmsdh_reg_read(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
+-		cc_data_temp &= ~str_mask;
+-		drivestrength_sel <<= str_shift;
+-		cc_data_temp |= drivestrength_sel;
+-		bcmsdh_reg_write(bus->sdh,
+-			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+-			4, cc_data_temp);
+-
+-		DHD_INFO(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
+-			drivestrength, cc_data_temp));
+-	}
+-}
+-
+-static void
+-dhdsdio_chip_detach(struct dhd_bus *bus)
+-{
+-	DHD_TRACE(("%s: Enter\n", __func__));
+-
+-	kfree(bus->ci);
+-	bus->ci = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h b/drivers/staging/brcm80211/brcmfmac/dhdioctl.h
+deleted file mode 100644
+index f0ba535..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h
++++ /dev/null
+@@ -1,100 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dhdioctl_h_
+-#define	_dhdioctl_h_
+-
+-/* Linux network driver ioctl encoding */
+-typedef struct dhd_ioctl {
+-	uint cmd;		/* common ioctl definition */
+-	void *buf;		/* pointer to user buffer */
+-	uint len;		/* length of user buffer */
+-	bool set;		/* get or set request (optional) */
+-	uint used;		/* bytes read or written (optional) */
+-	uint needed;		/* bytes needed (optional) */
+-	uint driver;		/* to identify target driver */
+-} dhd_ioctl_t;
+-
+-/* per-driver magic numbers */
+-#define DHD_IOCTL_MAGIC		0x00444944
+-
+-/* bump this number if you change the ioctl interface */
+-#define DHD_IOCTL_VERSION	1
+-
+-#define	DHD_IOCTL_MAXLEN	8192	/* max length ioctl buffer required */
+-#define	DHD_IOCTL_SMLEN	256	/* "small" length ioctl buffer required */
+-
+-/* common ioctl definitions */
+-#define DHD_GET_MAGIC				0
+-#define DHD_GET_VERSION				1
+-#define DHD_GET_VAR				2
+-#define DHD_SET_VAR				3
+-
+-/* message levels */
+-#define DHD_ERROR_VAL	0x0001
+-#define DHD_TRACE_VAL	0x0002
+-#define DHD_INFO_VAL	0x0004
+-#define DHD_DATA_VAL	0x0008
+-#define DHD_CTL_VAL	0x0010
+-#define DHD_TIMER_VAL	0x0020
+-#define DHD_HDRS_VAL	0x0040
+-#define DHD_BYTES_VAL	0x0080
+-#define DHD_INTR_VAL	0x0100
+-#define DHD_LOG_VAL	0x0200
+-#define DHD_GLOM_VAL	0x0400
+-#define DHD_EVENT_VAL	0x0800
+-#define DHD_BTA_VAL	0x1000
+-#define DHD_ISCAN_VAL 0x2000
+-
+-#ifdef SDTEST
+-/* For pktgen iovar */
+-typedef struct dhd_pktgen {
+-	uint version;		/* To allow structure change tracking */
+-	uint freq;		/* Max ticks between tx/rx attempts */
+-	uint count;		/* Test packets to send/rcv each attempt */
+-	uint print;		/* Print counts every <print> attempts */
+-	uint total;		/* Total packets (or bursts) */
+-	uint minlen;		/* Minimum length of packets to send */
+-	uint maxlen;		/* Maximum length of packets to send */
+-	uint numsent;		/* Count of test packets sent */
+-	uint numrcvd;		/* Count of test packets received */
+-	uint numfail;		/* Count of test send failures */
+-	uint mode;		/* Test mode (type of test packets) */
+-	uint stop;		/* Stop after this many tx failures */
+-} dhd_pktgen_t;
+-
+-/* Version in case structure changes */
+-#define DHD_PKTGEN_VERSION 2
+-
+-/* Type of test packets to use */
+-#define DHD_PKTGEN_ECHO		1	/* Send echo requests */
+-#define DHD_PKTGEN_SEND		2	/* Send discard packets */
+-#define DHD_PKTGEN_RXBURST	3	/* Request dongle send N packets */
+-#define DHD_PKTGEN_RECV		4	/* Continuous rx from continuous
+-					 tx dongle */
+-#endif				/* SDTEST */
+-
+-/* Enter idle immediately (no timeout) */
+-#define DHD_IDLE_IMMEDIATE	(-1)
+-
+-/* Values for idleclock iovar: other values are the sd_divisor to use
+-	 when idle */
+-#define DHD_IDLE_ACTIVE	0	/* Do not request any SD clock change
+-				 when idle */
+-#define DHD_IDLE_STOP   (-1)	/* Request SD clock be stopped
+-				 (and use SD1 mode) */
+-
+-#endif				/* _dhdioctl_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h b/drivers/staging/brcm80211/brcmfmac/dngl_stats.h
+deleted file mode 100644
+index 699cbff..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h
++++ /dev/null
+@@ -1,32 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _dngl_stats_h_
+-#define _dngl_stats_h_
+-
+-typedef struct {
+-	unsigned long rx_packets;	/* total packets received */
+-	unsigned long tx_packets;	/* total packets transmitted */
+-	unsigned long rx_bytes;	/* total bytes received */
+-	unsigned long tx_bytes;	/* total bytes transmitted */
+-	unsigned long rx_errors;	/* bad packets received */
+-	unsigned long tx_errors;	/* packet transmit problems */
+-	unsigned long rx_dropped;	/* packets dropped by dongle */
+-	unsigned long tx_dropped;	/* packets dropped by dongle */
+-	unsigned long multicast;	/* multicast packets received */
+-} dngl_stats_t;
+-
+-#endif				/* _dngl_stats_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h b/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
+deleted file mode 100644
+index 28f092c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h
++++ /dev/null
+@@ -1,75 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_hndrte_armtrap_h
+-#define	_hndrte_armtrap_h
+-
+-/* ARM trap handling */
+-
+-/* Trap types defined by ARM (see arminc.h) */
+-
+-/* Trap locations in lo memory */
+-#define	TRAP_STRIDE	4
+-#define FIRST_TRAP	TR_RST
+-#define LAST_TRAP	(TR_FIQ * TRAP_STRIDE)
+-
+-#if defined(__ARM_ARCH_4T__)
+-#define	MAX_TRAP_TYPE	(TR_FIQ + 1)
+-#elif defined(__ARM_ARCH_7M__)
+-#define	MAX_TRAP_TYPE	(TR_ISR + ARMCM3_NUMINTS)
+-#endif				/* __ARM_ARCH_7M__ */
+-
+-/* The trap structure is defined here as offsets for assembly */
+-#define	TR_TYPE		0x00
+-#define	TR_EPC		0x04
+-#define	TR_CPSR		0x08
+-#define	TR_SPSR		0x0c
+-#define	TR_REGS		0x10
+-#define	TR_REG(n)	(TR_REGS + (n) * 4)
+-#define	TR_SP		TR_REG(13)
+-#define	TR_LR		TR_REG(14)
+-#define	TR_PC		TR_REG(15)
+-
+-#define	TRAP_T_SIZE	80
+-
+-#ifndef	_LANGUAGE_ASSEMBLY
+-
+-typedef struct _trap_struct {
+-	u32 type;
+-	u32 epc;
+-	u32 cpsr;
+-	u32 spsr;
+-	u32 r0;
+-	u32 r1;
+-	u32 r2;
+-	u32 r3;
+-	u32 r4;
+-	u32 r5;
+-	u32 r6;
+-	u32 r7;
+-	u32 r8;
+-	u32 r9;
+-	u32 r10;
+-	u32 r11;
+-	u32 r12;
+-	u32 r13;
+-	u32 r14;
+-	u32 pc;
+-} trap_t;
+-
+-#endif				/* !_LANGUAGE_ASSEMBLY */
+-
+-#endif				/* _hndrte_armtrap_h */
+diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
+deleted file mode 100644
+index 4df3eec..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h
++++ /dev/null
+@@ -1,62 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#ifndef _hndrte_cons_h
+-#define _hndrte_cons_h
+-
+-#define CBUF_LEN	(128)
+-
+-#define LOG_BUF_LEN	1024
+-
+-typedef struct {
+-	u32 buf;		/* Can't be pointer on (64-bit) hosts */
+-	uint buf_size;
+-	uint idx;
+-	char *_buf_compat;	/* Redundant pointer for backward compat. */
+-} hndrte_log_t;
+-
+-typedef struct {
+-	/* Virtual UART
+-	 * When there is no UART (e.g. Quickturn),
+-	 * the host should write a complete
+-	 * input line directly into cbuf and then write
+-	 * the length into vcons_in.
+-	 * This may also be used when there is a real UART
+-	 * (at risk of conflicting with
+-	 * the real UART).  vcons_out is currently unused.
+-	 */
+-	volatile uint vcons_in;
+-	volatile uint vcons_out;
+-
+-	/* Output (logging) buffer
+-	 * Console output is written to a ring buffer log_buf at index log_idx.
+-	 * The host may read the output when it sees log_idx advance.
+-	 * Output will be lost if the output wraps around faster than the host
+-	 * polls.
+-	 */
+-	hndrte_log_t log;
+-
+-	/* Console input line buffer
+-	 * Characters are read one at a time into cbuf
+-	 * until <CR> is received, then
+-	 * the buffer is processed as a command line.
+-	 * Also used for virtual UART.
+-	 */
+-	uint cbuf_idx;
+-	char cbuf[CBUF_LEN];
+-} hndrte_cons_t;
+-
+-#endif /* _hndrte_cons_h */
+-
+diff --git a/drivers/staging/brcm80211/brcmfmac/msgtrace.h b/drivers/staging/brcm80211/brcmfmac/msgtrace.h
+deleted file mode 100644
+index d654671..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/msgtrace.h
++++ /dev/null
+@@ -1,61 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_MSGTRACE_H
+-#define	_MSGTRACE_H
+-
+-#define MSGTRACE_VERSION 1
+-
+-/* Message trace header */
+-typedef struct msgtrace_hdr {
+-	u8 version;
+-	u8 spare;
+-	u16 len;		/* Len of the trace */
+-	u32 seqnum;		/* Sequence number of message. Useful
+-				 * if the messsage has been lost
+-				 * because of DMA error or a bus reset
+-				 * (ex: SDIO Func2)
+-				 */
+-	u32 discarded_bytes;	/* Number of discarded bytes because of
+-				 trace overflow  */
+-	u32 discarded_printf;	/* Number of discarded printf
+-				 because of trace overflow */
+-} __attribute__((packed)) msgtrace_hdr_t;
+-
+-#define MSGTRACE_HDRLEN		sizeof(msgtrace_hdr_t)
+-
+-/* The hbus driver generates traces when sending a trace message.
+- * This causes endless traces.
+- * This flag must be set to true in any hbus traces.
+- * The flag is reset in the function msgtrace_put.
+- * This prevents endless traces but generates hasardous
+- * lost of traces only in bus device code.
+- * It is recommendat to set this flag in macro SD_TRACE
+- * but not in SD_ERROR for avoiding missing
+- * hbus error traces. hbus error trace should not generates endless traces.
+- */
+-extern bool msgtrace_hbus_trace;
+-
+-typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr,
+-				      u16 hdrlen, u8 *buf,
+-				      u16 buflen);
+-
+-extern void msgtrace_sent(void);
+-extern void msgtrace_put(char *buf, int count);
+-extern void msgtrace_init(void *hdl1, void *hdl2,
+-			  msgtrace_func_send_t func_send);
+-
+-#endif				/* _MSGTRACE_H */
+diff --git a/drivers/staging/brcm80211/brcmfmac/sdioh.h b/drivers/staging/brcm80211/brcmfmac/sdioh.h
+deleted file mode 100644
+index f96aaf9..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/sdioh.h
++++ /dev/null
+@@ -1,63 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SDIOH_H
+-#define	_SDIOH_H
+-
+-#define SD_SysAddr			0x000
+-#define SD_BlockSize			0x004
+-#define SD_BlockCount 			0x006
+-#define SD_Arg0				0x008
+-#define SD_Arg1 			0x00A
+-#define SD_TransferMode			0x00C
+-#define SD_Command 			0x00E
+-#define SD_Response0			0x010
+-#define SD_Response1 			0x012
+-#define SD_Response2			0x014
+-#define SD_Response3 			0x016
+-#define SD_Response4			0x018
+-#define SD_Response5 			0x01A
+-#define SD_Response6			0x01C
+-#define SD_Response7 			0x01E
+-#define SD_BufferDataPort0		0x020
+-#define SD_BufferDataPort1 		0x022
+-#define SD_PresentState			0x024
+-#define SD_HostCntrl			0x028
+-#define SD_PwrCntrl			0x029
+-#define SD_BlockGapCntrl 		0x02A
+-#define SD_WakeupCntrl 			0x02B
+-#define SD_ClockCntrl			0x02C
+-#define SD_TimeoutCntrl 		0x02E
+-#define SD_SoftwareReset		0x02F
+-#define SD_IntrStatus			0x030
+-#define SD_ErrorIntrStatus 		0x032
+-#define SD_IntrStatusEnable		0x034
+-#define SD_ErrorIntrStatusEnable 	0x036
+-#define SD_IntrSignalEnable		0x038
+-#define SD_ErrorIntrSignalEnable 	0x03A
+-#define SD_CMD12ErrorStatus		0x03C
+-#define SD_Capabilities			0x040
+-#define SD_Capabilities_Reserved	0x044
+-#define SD_MaxCurCap			0x048
+-#define SD_MaxCurCap_Reserved		0x04C
+-#define SD_ADMA_SysAddr			0x58
+-#define SD_SlotInterruptStatus		0x0FC
+-#define SD_HostControllerVersion 	0x0FE
+-
+-/* SD specific registers in PCI config space */
+-#define SD_SlotInfo	0x40
+-
+-#endif				/* _SDIOH_H */
+diff --git a/drivers/staging/brcm80211/brcmfmac/sdiovar.h b/drivers/staging/brcm80211/brcmfmac/sdiovar.h
+deleted file mode 100644
+index d1cfa5f..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/sdiovar.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _sdiovar_h_
+-#define _sdiovar_h_
+-
+-typedef struct sdreg {
+-	int func;
+-	int offset;
+-	int value;
+-} sdreg_t;
+-
+-/* Common msglevel constants */
+-#define SDH_ERROR_VAL		0x0001	/* Error */
+-#define SDH_TRACE_VAL		0x0002	/* Trace */
+-#define SDH_INFO_VAL		0x0004	/* Info */
+-#define SDH_DEBUG_VAL		0x0008	/* Debug */
+-#define SDH_DATA_VAL		0x0010	/* Data */
+-#define SDH_CTRL_VAL		0x0020	/* Control Regs */
+-#define SDH_LOG_VAL		0x0040	/* Enable bcmlog */
+-#define SDH_DMA_VAL		0x0080	/* DMA */
+-
+-#define NUM_PREV_TRANSACTIONS	16
+-
+-#endif				/* _sdiovar_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+deleted file mode 100644
+index 1827b0b..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
++++ /dev/null
+@@ -1,4428 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/if_arp.h>
+-
+-#include <bcmutils.h>
+-
+-#include <asm/uaccess.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhdioctl.h>
+-#include <wlioctl.h>
+-
+-#include <linux/kthread.h>
+-#include <linux/netdevice.h>
+-#include <linux/sched.h>
+-#include <linux/etherdevice.h>
+-#include <linux/wireless.h>
+-#include <linux/ieee80211.h>
+-#include <net/cfg80211.h>
+-
+-#include <net/rtnetlink.h>
+-#include <linux/mmc/sdio_func.h>
+-#include <linux/firmware.h>
+-#include <wl_cfg80211.h>
+-
+-void sdioh_sdio_set_host_pm_flags(int flag);
+-
+-static struct sdio_func *cfg80211_sdio_func;
+-static struct wl_dev *wl_cfg80211_dev;
+-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-
+-u32 wl_dbg_level = WL_DBG_ERR;
+-
+-#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
+-#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
+-
+-/*
+-** cfg80211_ops api/callback list
+-*/
+-static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
+-				      struct net_device *ndev,
+-				      enum nl80211_iftype type, u32 *flags,
+-				      struct vif_params *params);
+-static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-				struct cfg80211_scan_request *request,
+-				struct cfg80211_ssid *this_ssid);
+-static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-			      struct cfg80211_scan_request *request);
+-static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+-static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_ibss_params *params);
+-static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
+-				    struct net_device *dev);
+-static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+-				     struct net_device *dev, u8 *mac,
+-				     struct station_info *sinfo);
+-static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+-					struct net_device *dev, bool enabled,
+-					s32 timeout);
+-static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
+-					  struct net_device *dev,
+-					  const u8 *addr,
+-					  const struct cfg80211_bitrate_mask
+-					  *mask);
+-static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+-			       struct cfg80211_connect_params *sme);
+-static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+-				    u16 reason_code);
+-static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+-				      enum nl80211_tx_power_setting type,
+-				      s32 dbm);
+-static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
+-static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
+-					  struct net_device *dev, u8 key_idx,
+-					  bool unicast, bool multicast);
+-static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr,
+-				 struct key_params *params);
+-static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr);
+-static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+-				 u8 key_idx, bool pairwise, const u8 *mac_addr,
+-				 void *cookie, void (*callback) (void *cookie,
+-								 struct
+-								 key_params *
+-								 params));
+-static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+-						 struct net_device *dev,
+-						 u8 key_idx);
+-static s32 wl_cfg80211_resume(struct wiphy *wiphy);
+-static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
+-static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_pmksa *pmksa);
+-static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-				   struct cfg80211_pmksa *pmksa);
+-static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
+-				     struct net_device *dev);
+-/*
+-** event & event Q handlers for cfg80211 interfaces
+-*/
+-static s32 wl_create_event_handler(struct wl_priv *wl);
+-static void wl_destroy_event_handler(struct wl_priv *wl);
+-static s32 wl_event_handler(void *data);
+-static void wl_init_eq(struct wl_priv *wl);
+-static void wl_flush_eq(struct wl_priv *wl);
+-static void wl_lock_eq(struct wl_priv *wl);
+-static void wl_unlock_eq(struct wl_priv *wl);
+-static void wl_init_eq_lock(struct wl_priv *wl);
+-static void wl_init_eloop_handler(struct wl_event_loop *el);
+-static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
+-static s32 wl_enq_event(struct wl_priv *wl, u32 type,
+-			  const wl_event_msg_t *msg, void *data);
+-static void wl_put_event(struct wl_event_q *e);
+-static void wl_wakeup_event(struct wl_priv *wl);
+-static s32 wl_notify_connect_status(struct wl_priv *wl,
+-				      struct net_device *ndev,
+-				      const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_roaming_status(struct wl_priv *wl,
+-				      struct net_device *ndev,
+-				      const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+-				   const wl_event_msg_t *e, void *data);
+-static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+-				 const wl_event_msg_t *e, void *data,
+-				bool completed);
+-static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+-				 const wl_event_msg_t *e, void *data);
+-static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+-				  const wl_event_msg_t *e, void *data);
+-
+-/*
+-** register/deregister sdio function
+-*/
+-struct sdio_func *wl_cfg80211_get_sdio_func(void);
+-static void wl_clear_sdio_func(void);
+-
+-/*
+-** ioctl utilites
+-*/
+-static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
+-			       s32 buf_len);
+-static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
+-				      s8 *buf, s32 len);
+-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
+-static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
+-			       s32 *retval);
+-static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
+-			  u32 len);
+-
+-/*
+-** cfg80211 set_wiphy_params utilities
+-*/
+-static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
+-static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
+-static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
+-
+-/*
+-** wl profile utilities
+-*/
+-static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
+-			    void *data, s32 item);
+-static void *wl_read_prof(struct wl_priv *wl, s32 item);
+-static void wl_init_prof(struct wl_profile *prof);
+-
+-/*
+-** cfg80211 connect utilites
+-*/
+-static s32 wl_set_wpa_version(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_auth_type(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_set_cipher(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_key_mgmt(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_set_set_sharedkey(struct net_device *dev,
+-			struct cfg80211_connect_params *sme);
+-static s32 wl_get_assoc_ies(struct wl_priv *wl);
+-static void wl_clear_assoc_ies(struct wl_priv *wl);
+-static void wl_ch_to_chanspec(int ch,
+-	struct wl_join_params *join_params, size_t *join_params_size);
+-
+-/*
+-** information element utilities
+-*/
+-static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
+-static s32 wl_mode_to_nl80211_iftype(s32 mode);
+-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
+-			struct device *dev);
+-static void wl_free_wdev(struct wl_priv *wl);
+-static s32 wl_inform_bss(struct wl_priv *wl);
+-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
+-static s32 wl_update_bss_info(struct wl_priv *wl);
+-static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+-			u8 key_idx, const u8 *mac_addr,
+-			struct key_params *params);
+-
+-/*
+-** key indianess swap utilities
+-*/
+-static void swap_key_from_BE(struct wl_wsec_key *key);
+-static void swap_key_to_BE(struct wl_wsec_key *key);
+-
+-/*
+-** wl_priv memory init/deinit utilities
+-*/
+-static s32 wl_init_priv_mem(struct wl_priv *wl);
+-static void wl_deinit_priv_mem(struct wl_priv *wl);
+-
+-static void wl_delay(u32 ms);
+-
+-/*
+-** store/restore cfg80211 instance data
+-*/
+-static void wl_set_drvdata(struct wl_dev *dev, void *data);
+-static void *wl_get_drvdata(struct wl_dev *dev);
+-
+-/*
+-** ibss mode utilities
+-*/
+-static bool wl_is_ibssmode(struct wl_priv *wl);
+-
+-/*
+-** dongle up/down , default configuration utilities
+-*/
+-static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
+-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
+-static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
+-static void wl_link_down(struct wl_priv *wl);
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
+-static s32 __wl_cfg80211_up(struct wl_priv *wl);
+-static s32 __wl_cfg80211_down(struct wl_priv *wl);
+-static s32 wl_dongle_probecap(struct wl_priv *wl);
+-static void wl_init_conf(struct wl_conf *conf);
+-
+-/*
+-** dongle configuration utilities
+-*/
+-#ifndef EMBEDDED_PLATFORM
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
+-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
+-static s32 wl_dongle_up(struct net_device *ndev, u32 up);
+-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
+-static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
+-			    u32 dongle_align);
+-static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
+-			       s32 arp_ol);
+-static s32 wl_pattern_atoh(s8 *src, s8 *dst);
+-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
+-static s32 wl_update_wiphybands(struct wl_priv *wl);
+-#endif				/* !EMBEDDED_PLATFORM */
+-
+-static s32 wl_dongle_eventmsg(struct net_device *ndev);
+-static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+-				s32 scan_unassoc_time, s32 scan_passive_time);
+-static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
+-static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
+-			    u32 bcn_timeout);
+-
+-/*
+-** iscan handler
+-*/
+-static void wl_iscan_timer(unsigned long data);
+-static void wl_term_iscan(struct wl_priv *wl);
+-static s32 wl_init_iscan(struct wl_priv *wl);
+-static s32 wl_iscan_thread(void *data);
+-static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
+-				 void *param, s32 paramlen, void *bufptr,
+-				 s32 buflen);
+-static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
+-				 void *param, s32 paramlen, void *bufptr,
+-				 s32 buflen);
+-static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
+-			  u16 action);
+-static s32 wl_do_iscan(struct wl_priv *wl);
+-static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
+-static s32 wl_invoke_iscan(struct wl_priv *wl);
+-static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+-				  struct wl_scan_results **bss_list);
+-static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
+-static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
+-static s32 wl_iscan_done(struct wl_priv *wl);
+-static s32 wl_iscan_pending(struct wl_priv *wl);
+-static s32 wl_iscan_inprogress(struct wl_priv *wl);
+-static s32 wl_iscan_aborted(struct wl_priv *wl);
+-
+-/*
+-** fw/nvram downloading handler
+-*/
+-static void wl_init_fw(struct wl_fw_ctrl *fw);
+-
+-/*
+-* find most significant bit set
+-*/
+-static __used u32 wl_find_msb(u16 bit16);
+-
+-/*
+-* update pmklist to dongle
+-*/
+-static __used s32 wl_update_pmklist(struct net_device *dev,
+-				      struct wl_pmk_list *pmk_list, s32 err);
+-
+-static void wl_set_mpc(struct net_device *ndev, int mpc);
+-
+-/*
+-* debufs support
+-*/
+-static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
+-static void wl_debugfs_remove_netdev(struct wl_priv *wl);
+-
+-#define WL_PRIV_GET() 							\
+-	({								\
+-	struct wl_iface *ci;						\
+-	if (unlikely(!(wl_cfg80211_dev && 				\
+-		(ci = wl_get_drvdata(wl_cfg80211_dev))))) {		\
+-		WL_ERR("wl_cfg80211_dev is unavailable\n");		\
+-		BUG();							\
+-	} 								\
+-	ci_to_wl(ci);							\
+-})
+-
+-#define CHECK_SYS_UP()							\
+-do {									\
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);			\
+-	if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {	\
+-		WL_INFO("device is not ready : status (%d)\n",		\
+-			(int)wl->status);				\
+-		return -EIO;						\
+-	}								\
+-} while (0)
+-
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-#define CHAN2G(_channel, _freq, _flags) {			\
+-	.band			= IEEE80211_BAND_2GHZ,		\
+-	.center_freq		= (_freq),			\
+-	.hw_value		= (_channel),			\
+-	.flags			= (_flags),			\
+-	.max_antenna_gain	= 0,				\
+-	.max_power		= 30,				\
+-}
+-
+-#define CHAN5G(_channel, _flags) {				\
+-	.band			= IEEE80211_BAND_5GHZ,		\
+-	.center_freq		= 5000 + (5 * (_channel)),	\
+-	.hw_value		= (_channel),			\
+-	.flags			= (_flags),			\
+-	.max_antenna_gain	= 0,				\
+-	.max_power		= 30,				\
+-}
+-
+-#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
+-#define RATETAB_ENT(_rateid, _flags) \
+-	{                                                               \
+-		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
+-		.hw_value       = (_rateid),                            \
+-		.flags          = (_flags),                             \
+-	}
+-
+-static struct ieee80211_rate __wl_rates[] = {
+-	RATETAB_ENT(WLC_RATE_1M, 0),
+-	RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATETAB_ENT(WLC_RATE_6M, 0),
+-	RATETAB_ENT(WLC_RATE_9M, 0),
+-	RATETAB_ENT(WLC_RATE_12M, 0),
+-	RATETAB_ENT(WLC_RATE_18M, 0),
+-	RATETAB_ENT(WLC_RATE_24M, 0),
+-	RATETAB_ENT(WLC_RATE_36M, 0),
+-	RATETAB_ENT(WLC_RATE_48M, 0),
+-	RATETAB_ENT(WLC_RATE_54M, 0),
+-};
+-
+-#define wl_a_rates		(__wl_rates + 4)
+-#define wl_a_rates_size	8
+-#define wl_g_rates		(__wl_rates + 0)
+-#define wl_g_rates_size	12
+-
+-static struct ieee80211_channel __wl_2ghz_channels[] = {
+-	CHAN2G(1, 2412, 0),
+-	CHAN2G(2, 2417, 0),
+-	CHAN2G(3, 2422, 0),
+-	CHAN2G(4, 2427, 0),
+-	CHAN2G(5, 2432, 0),
+-	CHAN2G(6, 2437, 0),
+-	CHAN2G(7, 2442, 0),
+-	CHAN2G(8, 2447, 0),
+-	CHAN2G(9, 2452, 0),
+-	CHAN2G(10, 2457, 0),
+-	CHAN2G(11, 2462, 0),
+-	CHAN2G(12, 2467, 0),
+-	CHAN2G(13, 2472, 0),
+-	CHAN2G(14, 2484, 0),
+-};
+-
+-static struct ieee80211_channel __wl_5ghz_a_channels[] = {
+-	CHAN5G(34, 0), CHAN5G(36, 0),
+-	CHAN5G(38, 0), CHAN5G(40, 0),
+-	CHAN5G(42, 0), CHAN5G(44, 0),
+-	CHAN5G(46, 0), CHAN5G(48, 0),
+-	CHAN5G(52, 0), CHAN5G(56, 0),
+-	CHAN5G(60, 0), CHAN5G(64, 0),
+-	CHAN5G(100, 0), CHAN5G(104, 0),
+-	CHAN5G(108, 0), CHAN5G(112, 0),
+-	CHAN5G(116, 0), CHAN5G(120, 0),
+-	CHAN5G(124, 0), CHAN5G(128, 0),
+-	CHAN5G(132, 0), CHAN5G(136, 0),
+-	CHAN5G(140, 0), CHAN5G(149, 0),
+-	CHAN5G(153, 0), CHAN5G(157, 0),
+-	CHAN5G(161, 0), CHAN5G(165, 0),
+-	CHAN5G(184, 0), CHAN5G(188, 0),
+-	CHAN5G(192, 0), CHAN5G(196, 0),
+-	CHAN5G(200, 0), CHAN5G(204, 0),
+-	CHAN5G(208, 0), CHAN5G(212, 0),
+-	CHAN5G(216, 0),
+-};
+-
+-static struct ieee80211_channel __wl_5ghz_n_channels[] = {
+-	CHAN5G(32, 0), CHAN5G(34, 0),
+-	CHAN5G(36, 0), CHAN5G(38, 0),
+-	CHAN5G(40, 0), CHAN5G(42, 0),
+-	CHAN5G(44, 0), CHAN5G(46, 0),
+-	CHAN5G(48, 0), CHAN5G(50, 0),
+-	CHAN5G(52, 0), CHAN5G(54, 0),
+-	CHAN5G(56, 0), CHAN5G(58, 0),
+-	CHAN5G(60, 0), CHAN5G(62, 0),
+-	CHAN5G(64, 0), CHAN5G(66, 0),
+-	CHAN5G(68, 0), CHAN5G(70, 0),
+-	CHAN5G(72, 0), CHAN5G(74, 0),
+-	CHAN5G(76, 0), CHAN5G(78, 0),
+-	CHAN5G(80, 0), CHAN5G(82, 0),
+-	CHAN5G(84, 0), CHAN5G(86, 0),
+-	CHAN5G(88, 0), CHAN5G(90, 0),
+-	CHAN5G(92, 0), CHAN5G(94, 0),
+-	CHAN5G(96, 0), CHAN5G(98, 0),
+-	CHAN5G(100, 0), CHAN5G(102, 0),
+-	CHAN5G(104, 0), CHAN5G(106, 0),
+-	CHAN5G(108, 0), CHAN5G(110, 0),
+-	CHAN5G(112, 0), CHAN5G(114, 0),
+-	CHAN5G(116, 0), CHAN5G(118, 0),
+-	CHAN5G(120, 0), CHAN5G(122, 0),
+-	CHAN5G(124, 0), CHAN5G(126, 0),
+-	CHAN5G(128, 0), CHAN5G(130, 0),
+-	CHAN5G(132, 0), CHAN5G(134, 0),
+-	CHAN5G(136, 0), CHAN5G(138, 0),
+-	CHAN5G(140, 0), CHAN5G(142, 0),
+-	CHAN5G(144, 0), CHAN5G(145, 0),
+-	CHAN5G(146, 0), CHAN5G(147, 0),
+-	CHAN5G(148, 0), CHAN5G(149, 0),
+-	CHAN5G(150, 0), CHAN5G(151, 0),
+-	CHAN5G(152, 0), CHAN5G(153, 0),
+-	CHAN5G(154, 0), CHAN5G(155, 0),
+-	CHAN5G(156, 0), CHAN5G(157, 0),
+-	CHAN5G(158, 0), CHAN5G(159, 0),
+-	CHAN5G(160, 0), CHAN5G(161, 0),
+-	CHAN5G(162, 0), CHAN5G(163, 0),
+-	CHAN5G(164, 0), CHAN5G(165, 0),
+-	CHAN5G(166, 0), CHAN5G(168, 0),
+-	CHAN5G(170, 0), CHAN5G(172, 0),
+-	CHAN5G(174, 0), CHAN5G(176, 0),
+-	CHAN5G(178, 0), CHAN5G(180, 0),
+-	CHAN5G(182, 0), CHAN5G(184, 0),
+-	CHAN5G(186, 0), CHAN5G(188, 0),
+-	CHAN5G(190, 0), CHAN5G(192, 0),
+-	CHAN5G(194, 0), CHAN5G(196, 0),
+-	CHAN5G(198, 0), CHAN5G(200, 0),
+-	CHAN5G(202, 0), CHAN5G(204, 0),
+-	CHAN5G(206, 0), CHAN5G(208, 0),
+-	CHAN5G(210, 0), CHAN5G(212, 0),
+-	CHAN5G(214, 0), CHAN5G(216, 0),
+-	CHAN5G(218, 0), CHAN5G(220, 0),
+-	CHAN5G(222, 0), CHAN5G(224, 0),
+-	CHAN5G(226, 0), CHAN5G(228, 0),
+-};
+-
+-static struct ieee80211_supported_band __wl_band_2ghz = {
+-	.band = IEEE80211_BAND_2GHZ,
+-	.channels = __wl_2ghz_channels,
+-	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
+-	.bitrates = wl_g_rates,
+-	.n_bitrates = wl_g_rates_size,
+-};
+-
+-static struct ieee80211_supported_band __wl_band_5ghz_a = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = __wl_5ghz_a_channels,
+-	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
+-	.bitrates = wl_a_rates,
+-	.n_bitrates = wl_a_rates_size,
+-};
+-
+-static struct ieee80211_supported_band __wl_band_5ghz_n = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = __wl_5ghz_n_channels,
+-	.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
+-	.bitrates = wl_a_rates,
+-	.n_bitrates = wl_a_rates_size,
+-};
+-
+-static const u32 __wl_cipher_suites[] = {
+-	WLAN_CIPHER_SUITE_WEP40,
+-	WLAN_CIPHER_SUITE_WEP104,
+-	WLAN_CIPHER_SUITE_TKIP,
+-	WLAN_CIPHER_SUITE_CCMP,
+-	WLAN_CIPHER_SUITE_AES_CMAC,
+-};
+-
+-static void swap_key_from_BE(struct wl_wsec_key *key)
+-{
+-	key->index = cpu_to_le32(key->index);
+-	key->len = cpu_to_le32(key->len);
+-	key->algo = cpu_to_le32(key->algo);
+-	key->flags = cpu_to_le32(key->flags);
+-	key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
+-	key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
+-	key->iv_initialized = cpu_to_le32(key->iv_initialized);
+-}
+-
+-static void swap_key_to_BE(struct wl_wsec_key *key)
+-{
+-	key->index = le32_to_cpu(key->index);
+-	key->len = le32_to_cpu(key->len);
+-	key->algo = le32_to_cpu(key->algo);
+-	key->flags = le32_to_cpu(key->flags);
+-	key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
+-	key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
+-	key->iv_initialized = le32_to_cpu(key->iv_initialized);
+-}
+-
+-static s32
+-wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
+-{
+-	struct ifreq ifr;
+-	struct wl_ioctl ioc;
+-	mm_segment_t fs;
+-	s32 err = 0;
+-
+-	memset(&ioc, 0, sizeof(ioc));
+-	ioc.cmd = cmd;
+-	ioc.buf = arg;
+-	ioc.len = len;
+-	strcpy(ifr.ifr_name, dev->name);
+-	ifr.ifr_data = (caddr_t)&ioc;
+-
+-	fs = get_fs();
+-	set_fs(get_ds());
+-	err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-	set_fs(fs);
+-
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
+-			 enum nl80211_iftype type, u32 *flags,
+-			 struct vif_params *params)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wireless_dev *wdev;
+-	s32 infra = 0;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	switch (type) {
+-	case NL80211_IFTYPE_MONITOR:
+-	case NL80211_IFTYPE_WDS:
+-		WL_ERR("type (%d) : currently we do not support this type\n",
+-		       type);
+-		return -EOPNOTSUPP;
+-	case NL80211_IFTYPE_ADHOC:
+-		wl->conf->mode = WL_MODE_IBSS;
+-		infra = 0;
+-		break;
+-	case NL80211_IFTYPE_STATION:
+-		wl->conf->mode = WL_MODE_BSS;
+-		infra = 1;
+-		break;
+-	default:
+-		err = -EINVAL;
+-		goto done;
+-	}
+-
+-	infra = cpu_to_le32(infra);
+-	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
+-		err = -EAGAIN;
+-	} else {
+-		wdev = ndev->ieee80211_ptr;
+-		wdev->iftype = type;
+-	}
+-
+-	WL_INFO("IF Type = %s\n",
+-		(wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
+-
+-done:
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
+-{
+-	memcpy(params->bssid, ether_bcast, ETH_ALEN);
+-	params->bss_type = DOT11_BSSTYPE_ANY;
+-	params->scan_type = 0;
+-	params->nprobes = -1;
+-	params->active_time = -1;
+-	params->passive_time = -1;
+-	params->home_time = -1;
+-	params->channel_num = 0;
+-
+-	params->nprobes = cpu_to_le32(params->nprobes);
+-	params->active_time = cpu_to_le32(params->active_time);
+-	params->passive_time = cpu_to_le32(params->passive_time);
+-	params->home_time = cpu_to_le32(params->home_time);
+-	if (ssid && ssid->SSID_len)
+-		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+-
+-}
+-
+-static s32
+-wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
+-		    s32 paramlen, void *bufptr, s32 buflen)
+-{
+-	s32 iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	BUG_ON(!iolen);
+-
+-	return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
+-}
+-
+-static s32
+-wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
+-		    s32 paramlen, void *bufptr, s32 buflen)
+-{
+-	s32 iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	BUG_ON(!iolen);
+-
+-	return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
+-}
+-
+-static s32
+-wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
+-{
+-	s32 params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+-	struct wl_iscan_params *params;
+-	s32 err = 0;
+-
+-	if (ssid && ssid->SSID_len)
+-		params_size += sizeof(struct wlc_ssid);
+-	params = kzalloc(params_size, GFP_KERNEL);
+-	if (unlikely(!params))
+-		return -ENOMEM;
+-	BUG_ON(params_size >= WLC_IOCTL_SMLEN);
+-
+-	wl_iscan_prep(&params->params, ssid);
+-
+-	params->version = cpu_to_le32(ISCAN_REQ_VERSION);
+-	params->action = cpu_to_le16(action);
+-	params->scan_duration = cpu_to_le16(0);
+-
+-	/* params_size += offsetof(wl_iscan_params_t, params); */
+-	err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
+-				iscan->ioctl_buf, WLC_IOCTL_SMLEN);
+-	if (unlikely(err)) {
+-		if (err == -EBUSY) {
+-			WL_INFO("system busy : iscan canceled\n");
+-		} else {
+-			WL_ERR("error (%d)\n", err);
+-		}
+-	}
+-	kfree(params);
+-	return err;
+-}
+-
+-static s32 wl_do_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	struct wlc_ssid ssid;
+-	s32 passive_scan;
+-	s32 err = 0;
+-
+-	/* Broadcast scan by default */
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-	iscan->state = WL_ISCAN_STATE_SCANING;
+-
+-	passive_scan = wl->active_scan ? 0 : 1;
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
+-			&passive_scan, sizeof(passive_scan));
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	wl_set_mpc(ndev, 0);
+-	wl->iscan_kickstart = true;
+-	wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32
+-__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-		   struct cfg80211_scan_request *request,
+-		   struct cfg80211_ssid *this_ssid)
+-{
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-	struct cfg80211_ssid *ssids;
+-	struct wl_scan_req *sr = wl_to_sr(wl);
+-	s32 passive_scan;
+-	bool iscan_req;
+-	bool spec_scan;
+-	s32 err = 0;
+-
+-	if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scanning already : status (%d)\n", (int)wl->status);
+-		return -EAGAIN;
+-	}
+-	if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
+-		WL_ERR("Scanning being aborted : status (%d)\n",
+-		       (int)wl->status);
+-		return -EAGAIN;
+-	}
+-	if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
+-		WL_ERR("Connecting : status (%d)\n",
+-		       (int)wl->status);
+-		return -EAGAIN;
+-	}
+-
+-	iscan_req = false;
+-	spec_scan = false;
+-	if (request) {
+-		/* scan bss */
+-		ssids = request->ssids;
+-		if (wl->iscan_on && (!ssids || !ssids->ssid_len))
+-			iscan_req = true;
+-	} else {
+-		/* scan in ibss */
+-		/* we don't do iscan in ibss */
+-		ssids = this_ssid;
+-	}
+-
+-	wl->scan_request = request;
+-	set_bit(WL_STATUS_SCANNING, &wl->status);
+-	if (iscan_req) {
+-		err = wl_do_iscan(wl);
+-		if (likely(!err))
+-			return err;
+-		else
+-			goto scan_out;
+-	} else {
+-		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
+-		       ssids->ssid, ssids->ssid_len);
+-		memset(&sr->ssid, 0, sizeof(sr->ssid));
+-		sr->ssid.SSID_len =
+-			    min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
+-		if (sr->ssid.SSID_len) {
+-			memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
+-			sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
+-			spec_scan = true;
+-		} else {
+-			WL_SCAN("Broadcast scan\n");
+-		}
+-
+-		passive_scan = wl->active_scan ? 0 : 1;
+-		err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
+-				&passive_scan, sizeof(passive_scan));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
+-			goto scan_out;
+-		}
+-		wl_set_mpc(ndev, 0);
+-		err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
+-				sizeof(sr->ssid));
+-		if (err) {
+-			if (err == -EBUSY) {
+-				WL_INFO("system busy : scan for \"%s\" canceled\n",
+-					sr->ssid.SSID);
+-			} else {
+-				WL_ERR("WLC_SCAN error (%d)\n", err);
+-			}
+-			wl_set_mpc(ndev, 1);
+-			goto scan_out;
+-		}
+-	}
+-
+-	return 0;
+-
+-scan_out:
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	wl->scan_request = NULL;
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+-		 struct cfg80211_scan_request *request)
+-{
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	CHECK_SYS_UP();
+-
+-	err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
+-	if (unlikely(err))
+-		WL_ERR("scan error (%d)\n", err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
+-{
+-	s8 buf[WLC_IOCTL_SMLEN];
+-	u32 len;
+-	s32 err = 0;
+-
+-	val = cpu_to_le32(val);
+-	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+-	BUG_ON(!len);
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32
+-wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
+-{
+-	union {
+-		s8 buf[WLC_IOCTL_SMLEN];
+-		s32 val;
+-	} var;
+-	u32 len;
+-	u32 data_null;
+-	s32 err = 0;
+-
+-	len =
+-	    bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
+-			sizeof(var.buf));
+-	BUG_ON(!len);
+-	err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	*retval = le32_to_cpu(var.val);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
+-	if (unlikely(err))
+-		WL_ERR("Error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
+-	if (unlikely(err))
+-		WL_ERR("Error (%d)\n", err);
+-
+-	return err;
+-}
+-
+-static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
+-{
+-	s32 err = 0;
+-	u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
+-
+-	retry = cpu_to_le32(retry);
+-	err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
+-	if (unlikely(err)) {
+-		WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
+-		return err;
+-	}
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+-	    (wl->conf->rts_threshold != wiphy->rts_threshold)) {
+-		wl->conf->rts_threshold = wiphy->rts_threshold;
+-		err = wl_set_rts(ndev, wl->conf->rts_threshold);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+-	    (wl->conf->frag_threshold != wiphy->frag_threshold)) {
+-		wl->conf->frag_threshold = wiphy->frag_threshold;
+-		err = wl_set_frag(ndev, wl->conf->frag_threshold);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_RETRY_LONG
+-	    && (wl->conf->retry_long != wiphy->retry_long)) {
+-		wl->conf->retry_long = wiphy->retry_long;
+-		err = wl_set_retry(ndev, wl->conf->retry_long, true);
+-		if (!err)
+-			goto done;
+-	}
+-	if (changed & WIPHY_PARAM_RETRY_SHORT
+-	    && (wl->conf->retry_short != wiphy->retry_short)) {
+-		wl->conf->retry_short = wiphy->retry_short;
+-		err = wl_set_retry(ndev, wl->conf->retry_short, false);
+-		if (!err)
+-			goto done;
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_ibss_params *params)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wl_join_params join_params;
+-	size_t join_params_size = 0;
+-	s32 err = 0;
+-	s32 wsec = 0;
+-	s32 bcnprd;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (params->ssid)
+-		WL_CONN("SSID: %s\n", params->ssid);
+-	else {
+-		WL_CONN("SSID: NULL, Not supported\n");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	if (params->bssid)
+-		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
+-		params->bssid[0], params->bssid[1], params->bssid[2],
+-		params->bssid[3], params->bssid[4], params->bssid[5]);
+-	else
+-		WL_CONN("No BSSID specified\n");
+-
+-	if (params->channel)
+-		WL_CONN("channel: %d\n", params->channel->center_freq);
+-	else
+-		WL_CONN("no channel specified\n");
+-
+-	if (params->channel_fixed)
+-		WL_CONN("fixed channel required\n");
+-	else
+-		WL_CONN("no fixed channel required\n");
+-
+-	if (params->ie && params->ie_len)
+-		WL_CONN("ie len: %d\n", params->ie_len);
+-	else
+-		WL_CONN("no ie specified\n");
+-
+-	if (params->beacon_interval)
+-		WL_CONN("beacon interval: %d\n", params->beacon_interval);
+-	else
+-		WL_CONN("no beacon interval specified\n");
+-
+-	if (params->basic_rates)
+-		WL_CONN("basic rates: %08X\n", params->basic_rates);
+-	else
+-		WL_CONN("no basic rates specified\n");
+-
+-	if (params->privacy)
+-		WL_CONN("privacy required\n");
+-	else
+-		WL_CONN("no privacy required\n");
+-
+-	/* Configure Privacy for starter */
+-	if (params->privacy)
+-		wsec |= WEP_ENABLED;
+-
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("wsec failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	/* Configure Beacon Interval for starter */
+-	if (params->beacon_interval)
+-		bcnprd = cpu_to_le32(params->beacon_interval);
+-	else
+-		bcnprd = cpu_to_le32(100);
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	/* Configure required join parameter */
+-	memset(&join_params, 0, sizeof(wl_join_params_t));
+-
+-	/* SSID */
+-	join_params.ssid.SSID_len =
+-			(params->ssid_len > 32) ? 32 : params->ssid_len;
+-	memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
+-	join_params_size = sizeof(join_params.ssid);
+-	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+-
+-	/* BSSID */
+-	if (params->bssid) {
+-		memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
+-		join_params_size =
+-			sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE;
+-	} else {
+-		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-	}
+-	wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID);
+-
+-	/* Channel */
+-	if (params->channel) {
+-		u32 target_channel;
+-
+-		wl->channel =
+-			ieee80211_frequency_to_channel(
+-				params->channel->center_freq);
+-		if (params->channel_fixed) {
+-			/* adding chanspec */
+-			wl_ch_to_chanspec(wl->channel,
+-				&join_params, &join_params_size);
+-		}
+-
+-		/* set channel for starter */
+-		target_channel = cpu_to_le32(wl->channel);
+-		err = wl_dev_ioctl(dev, WLC_SET_CHANNEL,
+-			&target_channel, sizeof(target_channel));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
+-			goto done;
+-		}
+-	} else
+-		wl->channel = 0;
+-
+-	wl->ibss_starter = false;
+-
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
+-		goto done;
+-	}
+-
+-	set_bit(WL_STATUS_CONNECTING, &wl->status);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	wl_link_down(wl);
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
+-		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+-	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
+-		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+-	else
+-		val = WPA_AUTH_DISABLED;
+-	WL_CONN("setting wpa_auth to 0x%0x\n", val);
+-	err = wl_dev_intvar_set(dev, "wpa_auth", val);
+-	if (unlikely(err)) {
+-		WL_ERR("set wpa_auth failed (%d)\n", err);
+-		return err;
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->wpa_versions = sme->crypto.wpa_versions;
+-	return err;
+-}
+-
+-static s32
+-wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	switch (sme->auth_type) {
+-	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+-		val = 0;
+-		WL_CONN("open system\n");
+-		break;
+-	case NL80211_AUTHTYPE_SHARED_KEY:
+-		val = 1;
+-		WL_CONN("shared key\n");
+-		break;
+-	case NL80211_AUTHTYPE_AUTOMATIC:
+-		val = 2;
+-		WL_CONN("automatic\n");
+-		break;
+-	case NL80211_AUTHTYPE_NETWORK_EAP:
+-		WL_CONN("network eap\n");
+-	default:
+-		val = 2;
+-		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
+-		break;
+-	}
+-
+-	err = wl_dev_intvar_set(dev, "auth", val);
+-	if (unlikely(err)) {
+-		WL_ERR("set auth failed (%d)\n", err);
+-		return err;
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->auth_type = sme->auth_type;
+-	return err;
+-}
+-
+-static s32
+-wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 pval = 0;
+-	s32 gval = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.n_ciphers_pairwise) {
+-		switch (sme->crypto.ciphers_pairwise[0]) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			pval = WEP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			pval = TKIP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			pval = AES_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			pval = AES_ENABLED;
+-			break;
+-		default:
+-			WL_ERR("invalid cipher pairwise (%d)\n",
+-			       sme->crypto.ciphers_pairwise[0]);
+-			return -EINVAL;
+-		}
+-	}
+-	if (sme->crypto.cipher_group) {
+-		switch (sme->crypto.cipher_group) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			gval = WEP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			gval = TKIP_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			gval = AES_ENABLED;
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			gval = AES_ENABLED;
+-			break;
+-		default:
+-			WL_ERR("invalid cipher group (%d)\n",
+-			       sme->crypto.cipher_group);
+-			return -EINVAL;
+-		}
+-	}
+-
+-	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
+-	err = wl_dev_intvar_set(dev, "wsec", pval | gval);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
+-	sec->cipher_group = sme->crypto.cipher_group;
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	s32 val = 0;
+-	s32 err = 0;
+-
+-	if (sme->crypto.n_akm_suites) {
+-		err = wl_dev_intvar_get(dev, "wpa_auth", &val);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get wpa_auth (%d)\n", err);
+-			return err;
+-		}
+-		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+-			switch (sme->crypto.akm_suites[0]) {
+-			case WLAN_AKM_SUITE_8021X:
+-				val = WPA_AUTH_UNSPECIFIED;
+-				break;
+-			case WLAN_AKM_SUITE_PSK:
+-				val = WPA_AUTH_PSK;
+-				break;
+-			default:
+-				WL_ERR("invalid cipher group (%d)\n",
+-				       sme->crypto.cipher_group);
+-				return -EINVAL;
+-			}
+-		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+-			switch (sme->crypto.akm_suites[0]) {
+-			case WLAN_AKM_SUITE_8021X:
+-				val = WPA2_AUTH_UNSPECIFIED;
+-				break;
+-			case WLAN_AKM_SUITE_PSK:
+-				val = WPA2_AUTH_PSK;
+-				break;
+-			default:
+-				WL_ERR("invalid cipher group (%d)\n",
+-				       sme->crypto.cipher_group);
+-				return -EINVAL;
+-			}
+-		}
+-
+-		WL_CONN("setting wpa_auth to %d\n", val);
+-		err = wl_dev_intvar_set(dev, "wpa_auth", val);
+-		if (unlikely(err)) {
+-			WL_ERR("could not set wpa_auth (%d)\n", err);
+-			return err;
+-		}
+-	}
+-	sec = wl_read_prof(wl, WL_PROF_SEC);
+-	sec->wpa_auth = sme->crypto.akm_suites[0];
+-
+-	return err;
+-}
+-
+-static s32
+-wl_set_set_sharedkey(struct net_device *dev,
+-		     struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	struct wl_security *sec;
+-	struct wl_wsec_key key;
+-	s32 val;
+-	s32 err = 0;
+-
+-	WL_CONN("key len (%d)\n", sme->key_len);
+-	if (sme->key_len) {
+-		sec = wl_read_prof(wl, WL_PROF_SEC);
+-		WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+-		       sec->wpa_versions, sec->cipher_pairwise);
+-		if (!
+-		    (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
+-					  NL80211_WPA_VERSION_2))
+-&& (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
+-			    WLAN_CIPHER_SUITE_WEP104))) {
+-			memset(&key, 0, sizeof(key));
+-			key.len = (u32) sme->key_len;
+-			key.index = (u32) sme->key_idx;
+-			if (unlikely(key.len > sizeof(key.data))) {
+-				WL_ERR("Too long key length (%u)\n", key.len);
+-				return -EINVAL;
+-			}
+-			memcpy(key.data, sme->key, key.len);
+-			key.flags = WL_PRIMARY_KEY;
+-			switch (sec->cipher_pairwise) {
+-			case WLAN_CIPHER_SUITE_WEP40:
+-				key.algo = CRYPTO_ALGO_WEP1;
+-				break;
+-			case WLAN_CIPHER_SUITE_WEP104:
+-				key.algo = CRYPTO_ALGO_WEP128;
+-				break;
+-			default:
+-				WL_ERR("Invalid algorithm (%d)\n",
+-				       sme->crypto.ciphers_pairwise[0]);
+-				return -EINVAL;
+-			}
+-			/* Set the new key/index */
+-			WL_CONN("key length (%d) key index (%d) algo (%d)\n",
+-			       key.len, key.index, key.algo);
+-			WL_CONN("key \"%s\"\n", key.data);
+-			swap_key_from_BE(&key);
+-			err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
+-					sizeof(key));
+-			if (unlikely(err)) {
+-				WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-				return err;
+-			}
+-			if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
+-				WL_CONN("set auth_type to shared key\n");
+-				val = 1;	/* shared key */
+-				err = wl_dev_intvar_set(dev, "auth", val);
+-				if (unlikely(err)) {
+-					WL_ERR("set auth failed (%d)\n", err);
+-					return err;
+-				}
+-			}
+-		}
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+-		    struct cfg80211_connect_params *sme)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct ieee80211_channel *chan = sme->channel;
+-	struct wl_join_params join_params;
+-	size_t join_params_size;
+-
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (unlikely(!sme->ssid)) {
+-		WL_ERR("Invalid ssid\n");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	if (chan) {
+-		wl->channel =
+-			ieee80211_frequency_to_channel(chan->center_freq);
+-		WL_CONN("channel (%d), center_req (%d)\n",
+-			wl->channel, chan->center_freq);
+-	} else
+-		wl->channel = 0;
+-
+-	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+-
+-	err = wl_set_wpa_version(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_auth_type(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_set_cipher(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_key_mgmt(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	err = wl_set_set_sharedkey(dev, sme);
+-	if (unlikely(err))
+-		return err;
+-
+-	wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
+-	/*
+-	 **  Join with specific BSSID and cached SSID
+-	 **  If SSID is zero join based on BSSID only
+-	 */
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
+-	memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
+-	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+-
+-	if (sme->bssid)
+-		memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
+-	else
+-		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-
+-	if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
+-		WL_CONN("ssid \"%s\", len (%d)\n",
+-		       join_params.ssid.SSID, join_params.ssid.SSID_len);
+-	}
+-
+-	wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
+-	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	set_bit(WL_STATUS_CONNECTING, &wl->status);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+-		       u16 reason_code)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	scb_val_t scbval;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter. Reason code = %d\n", reason_code);
+-	CHECK_SYS_UP();
+-
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	scbval.val = reason_code;
+-	memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN);
+-	scbval.val = cpu_to_le32(scbval.val);
+-	err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
+-			sizeof(scb_val_t));
+-	if (unlikely(err))
+-		WL_ERR("error (%d)\n", err);
+-
+-	wl->link_up = false;
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_tx_power(struct wiphy *wiphy,
+-			 enum nl80211_tx_power_setting type, s32 dbm)
+-{
+-
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	u16 txpwrmw;
+-	s32 err = 0;
+-	s32 disable = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	switch (type) {
+-	case NL80211_TX_POWER_AUTOMATIC:
+-		break;
+-	case NL80211_TX_POWER_LIMITED:
+-		if (dbm < 0) {
+-			WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
+-			err = -EINVAL;
+-			goto done;
+-		}
+-		break;
+-	case NL80211_TX_POWER_FIXED:
+-		if (dbm < 0) {
+-			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
+-			err = -EINVAL;
+-			goto done;
+-		}
+-		break;
+-	}
+-	/* Make sure radio is off or on as far as software is concerned */
+-	disable = WL_RADIO_SW_DISABLE << 16;
+-	disable = cpu_to_le32(disable);
+-	err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
+-	if (unlikely(err))
+-		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
+-
+-	if (dbm > 0xffff)
+-		txpwrmw = 0xffff;
+-	else
+-		txpwrmw = (u16) dbm;
+-	err = wl_dev_intvar_set(ndev, "qtxpower",
+-			(s32) (bcm_mw_to_qdbm(txpwrmw)));
+-	if (unlikely(err))
+-		WL_ERR("qtxpower error (%d)\n", err);
+-	wl->conf->tx_power = dbm;
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	s32 txpwrdbm;
+-	u8 result;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+-	*dbm = (s32) bcm_qdbm_to_mw(result);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
+-			       u8 key_idx, bool unicast, bool multicast)
+-{
+-	u32 index;
+-	s32 wsec;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	wsec = le32_to_cpu(wsec);
+-	if (wsec & WEP_ENABLED) {
+-		/* Just select a new current key */
+-		index = (u32) key_idx;
+-		index = cpu_to_le32(index);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
+-				sizeof(index));
+-		if (unlikely(err))
+-			WL_ERR("error (%d)\n", err);
+-	}
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
+-	      u8 key_idx, const u8 *mac_addr, struct key_params *params)
+-{
+-	struct wl_wsec_key key;
+-	s32 err = 0;
+-
+-	memset(&key, 0, sizeof(key));
+-	key.index = (u32) key_idx;
+-	/* Instead of bcast for ea address for default wep keys,
+-		 driver needs it to be Null */
+-	if (!is_multicast_ether_addr(mac_addr))
+-		memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
+-	key.len = (u32) params->key_len;
+-	/* check for key index change */
+-	if (key.len == 0) {
+-		/* key delete */
+-		swap_key_from_BE(&key);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (unlikely(err)) {
+-			WL_ERR("key delete error (%d)\n", err);
+-			return err;
+-		}
+-	} else {
+-		if (key.len > sizeof(key.data)) {
+-			WL_ERR("Invalid key length (%d)\n", key.len);
+-			return -EINVAL;
+-		}
+-
+-		WL_CONN("Setting the key index %d\n", key.index);
+-		memcpy(key.data, params->key, key.len);
+-
+-		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
+-			u8 keybuf[8];
+-			memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-			memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		}
+-
+-		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
+-		if (params->seq && params->seq_len == 6) {
+-			/* rx iv */
+-			u8 *ivptr;
+-			ivptr = (u8 *) params->seq;
+-			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+-			    (ivptr[3] << 8) | ivptr[2];
+-			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+-			key.iv_initialized = true;
+-		}
+-
+-		switch (params->cipher) {
+-		case WLAN_CIPHER_SUITE_WEP40:
+-			key.algo = CRYPTO_ALGO_WEP1;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_WEP104:
+-			key.algo = CRYPTO_ALGO_WEP128;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_AES_CMAC:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-			break;
+-		case WLAN_CIPHER_SUITE_CCMP:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
+-			break;
+-		default:
+-			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
+-			return -EINVAL;
+-		}
+-		swap_key_from_BE(&key);
+-
+-		dhd_wait_pend8021x(dev);
+-		err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (unlikely(err)) {
+-			WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-			return err;
+-		}
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr,
+-		    struct key_params *params)
+-{
+-	struct wl_wsec_key key;
+-	s32 val;
+-	s32 wsec;
+-	s32 err = 0;
+-	u8 keybuf[8];
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	if (mac_addr) {
+-		WL_TRACE("Exit");
+-		return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
+-	}
+-	memset(&key, 0, sizeof(key));
+-
+-	key.len = (u32) params->key_len;
+-	key.index = (u32) key_idx;
+-
+-	if (unlikely(key.len > sizeof(key.data))) {
+-		WL_ERR("Too long key length (%u)\n", key.len);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-	memcpy(key.data, params->key, key.len);
+-
+-	key.flags = WL_PRIMARY_KEY;
+-	switch (params->cipher) {
+-	case WLAN_CIPHER_SUITE_WEP40:
+-		key.algo = CRYPTO_ALGO_WEP1;
+-		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_WEP104:
+-		key.algo = CRYPTO_ALGO_WEP128;
+-		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_TKIP:
+-		memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-		memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		key.algo = CRYPTO_ALGO_TKIP;
+-		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_AES_CMAC:
+-		key.algo = CRYPTO_ALGO_AES_CCM;
+-		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-		break;
+-	case WLAN_CIPHER_SUITE_CCMP:
+-		key.algo = CRYPTO_ALGO_AES_CCM;
+-		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
+-		break;
+-	default:
+-		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-
+-	/* Set the new key/index */
+-	swap_key_from_BE(&key);
+-	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	val = WEP_ENABLED;
+-	err = wl_dev_intvar_get(dev, "wsec", &wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("get wsec error (%d)\n", err);
+-		goto done;
+-	}
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("set wsec error (%d)\n", err);
+-		goto done;
+-	}
+-
+-	val = 1;		/* assume shared key. otherwise 0 */
+-	val = cpu_to_le32(val);
+-	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (unlikely(err))
+-		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr)
+-{
+-	struct wl_wsec_key key;
+-	s32 err = 0;
+-	s32 val;
+-	s32 wsec;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-	memset(&key, 0, sizeof(key));
+-
+-	key.index = (u32) key_idx;
+-	key.flags = WL_PRIMARY_KEY;
+-	key.algo = CRYPTO_ALGO_OFF;
+-
+-	WL_CONN("key index (%d)\n", key_idx);
+-	/* Set the new key/index */
+-	swap_key_from_BE(&key);
+-	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-	if (unlikely(err)) {
+-		if (err == -EINVAL) {
+-			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-				/* we ignore this key index in this case */
+-				WL_ERR("invalid key index (%d)\n", key_idx);
+-		} else
+-			WL_ERR("WLC_SET_KEY error (%d)\n", err);
+-
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-
+-	val = 0;
+-	err = wl_dev_intvar_get(dev, "wsec", &wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("get wsec error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-	err = wl_dev_intvar_set(dev, "wsec", wsec);
+-	if (unlikely(err)) {
+-		WL_ERR("set wsec error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-
+-	val = 0;		/* assume open key. otherwise 1 */
+-	val = cpu_to_le32(val);
+-	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-	}
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+-		    u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
+-		    void (*callback) (void *cookie, struct key_params * params))
+-{
+-	struct key_params params;
+-	struct wl_wsec_key key;
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct wl_security *sec;
+-	s32 wsec;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	WL_CONN("key index (%d)\n", key_idx);
+-	CHECK_SYS_UP();
+-
+-	memset(&key, 0, sizeof(key));
+-	key.index = key_idx;
+-	swap_key_to_BE(&key);
+-	memset(&params, 0, sizeof(params));
+-	params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
+-	memcpy(params.key, key.data, params.key_len);
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
+-		/* Ignore this error, may happen during DISASSOC */
+-		err = -EAGAIN;
+-		goto done;
+-	}
+-	wsec = le32_to_cpu(wsec);
+-	switch (wsec) {
+-	case WEP_ENABLED:
+-		sec = wl_read_prof(wl, WL_PROF_SEC);
+-		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
+-			params.cipher = WLAN_CIPHER_SUITE_WEP40;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
+-		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
+-			params.cipher = WLAN_CIPHER_SUITE_WEP104;
+-			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
+-		}
+-		break;
+-	case TKIP_ENABLED:
+-		params.cipher = WLAN_CIPHER_SUITE_TKIP;
+-		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
+-		break;
+-	case AES_ENABLED:
+-		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+-		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
+-		break;
+-	default:
+-		WL_ERR("Invalid algo (0x%x)\n", wsec);
+-		err = -EINVAL;
+-		goto done;
+-	}
+-	callback(cookie, &params);
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
+-				    struct net_device *dev, u8 key_idx)
+-{
+-	WL_INFO("Not supported\n");
+-
+-	CHECK_SYS_UP();
+-	return -EOPNOTSUPP;
+-}
+-
+-static s32
+-wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+-			u8 *mac, struct station_info *sinfo)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	scb_val_t scb_val;
+-	int rssi;
+-	s32 rate;
+-	s32 err = 0;
+-	u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID);
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	if (unlikely
+-	    (memcmp(mac, bssid, ETH_ALEN))) {
+-		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
+-			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
+-			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+-			bssid[0], bssid[1], bssid[2], bssid[3],
+-			bssid[4], bssid[5]);
+-		err = -ENOENT;
+-		goto done;
+-	}
+-
+-	/* Report the current tx rate */
+-	err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+-	if (err) {
+-		WL_ERR("Could not get rate (%d)\n", err);
+-	} else {
+-		rate = le32_to_cpu(rate);
+-		sinfo->filled |= STATION_INFO_TX_BITRATE;
+-		sinfo->txrate.legacy = rate * 5;
+-		WL_CONN("Rate %d Mbps\n", rate / 2);
+-	}
+-
+-	if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
+-		scb_val.val = 0;
+-		err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+-				sizeof(scb_val_t));
+-		if (unlikely(err)) {
+-			WL_ERR("Could not get rssi (%d)\n", err);
+-		}
+-		rssi = le32_to_cpu(scb_val.val);
+-		sinfo->filled |= STATION_INFO_SIGNAL;
+-		sinfo->signal = rssi;
+-		WL_CONN("RSSI %d dBm\n", rssi);
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+-			   bool enabled, s32 timeout)
+-{
+-	s32 pm;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	pm = enabled ? PM_FAST : PM_OFF;
+-	pm = cpu_to_le32(pm);
+-	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
+-
+-	err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+-	if (unlikely(err)) {
+-		if (err == -ENODEV)
+-			WL_ERR("net_device is not ready yet\n");
+-		else
+-			WL_ERR("error (%d)\n", err);
+-	}
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static __used u32 wl_find_msb(u16 bit16)
+-{
+-	u32 ret = 0;
+-
+-	if (bit16 & 0xff00) {
+-		ret += 8;
+-		bit16 >>= 8;
+-	}
+-
+-	if (bit16 & 0xf0) {
+-		ret += 4;
+-		bit16 >>= 4;
+-	}
+-
+-	if (bit16 & 0xc) {
+-		ret += 2;
+-		bit16 >>= 2;
+-	}
+-
+-	if (bit16 & 2)
+-		ret += bit16 & 2;
+-	else if (bit16)
+-		ret += bit16;
+-
+-	return ret;
+-}
+-
+-static s32
+-wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
+-			     const u8 *addr,
+-			     const struct cfg80211_bitrate_mask *mask)
+-{
+-	struct wl_rateset rateset;
+-	s32 rate;
+-	s32 val;
+-	s32 err_bg;
+-	s32 err_a;
+-	u32 legacy;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	/* addr param is always NULL. ignore it */
+-	/* Get current rateset */
+-	err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-			sizeof(rateset));
+-	if (unlikely(err)) {
+-		WL_ERR("could not get current rateset (%d)\n", err);
+-		goto done;
+-	}
+-
+-	rateset.count = le32_to_cpu(rateset.count);
+-
+-	legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
+-	if (!legacy)
+-		legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
+-
+-	val = wl_g_rates[legacy - 1].bitrate * 100000;
+-
+-	if (val < rateset.count)
+-		/* Select rate by rateset index */
+-		rate = rateset.rates[val] & 0x7f;
+-	else
+-		/* Specified rate in bps */
+-		rate = val / 500000;
+-
+-	WL_CONN("rate %d mbps\n", rate / 2);
+-
+-	/*
+-	 *
+-	 *      Set rate override,
+-	 *      Since the is a/b/g-blind, both a/bg_rate are enforced.
+-	 */
+-	err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
+-	err_a = wl_dev_intvar_set(dev, "a_rate", rate);
+-	if (unlikely(err_bg && err_a)) {
+-		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
+-		err = err_bg | err_a;
+-	}
+-
+-done:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32 wl_cfg80211_resume(struct wiphy *wiphy)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	/*
+-	 * Check for WL_STATUS_READY before any function call which
+-	 * could result is bus access. Don't block the resume for
+-	 * any driver error conditions
+-	 */
+-	WL_TRACE("Enter\n");
+-
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, false);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		/* Turn on Watchdog timer */
+-		wl_os_wd_timer(ndev, dhd_watchdog_ms);
+-		wl_invoke_iscan(wiphy_to_wl(wiphy));
+-	}
+-
+-	WL_TRACE("Exit\n");
+-	return 0;
+-}
+-
+-static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	WL_TRACE("Enter\n");
+-
+-	/*
+-	 * Check for WL_STATUS_READY before any function call which
+-	 * could result is bus access. Don't block the suspend for
+-	 * any driver error conditions
+-	 */
+-
+-	/*
+-	 * While going to suspend if associated with AP disassociate
+-	 * from AP to save power while system is in suspended state
+-	 */
+-	if (test_bit(WL_STATUS_CONNECTED, &wl->status) &&
+-		test_bit(WL_STATUS_READY, &wl->status)) {
+-		WL_INFO("Disassociating from AP"
+-			" while entering suspend state\n");
+-		wl_link_down(wl);
+-
+-		/*
+-		 * Make sure WPA_Supplicant receives all the event
+-		 * generated due to DISASSOC call to the fw to keep
+-		 * the state fw and WPA_Supplicant state consistent
+-		 */
+-		rtnl_unlock();
+-		wl_delay(500);
+-		rtnl_lock();
+-	}
+-
+-	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	if (test_bit(WL_STATUS_READY, &wl->status))
+-		wl_term_iscan(wl);
+-
+-	if (wl->scan_request) {
+-		/* Indidate scan abort to cfg80211 layer */
+-		WL_INFO("Terminating scan in progress\n");
+-		cfg80211_scan_done(wl->scan_request, true);
+-		wl->scan_request = NULL;
+-	}
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	/* Inform SDIO stack not to switch off power to the chip */
+-	sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER);
+-
+-	/* Turn off watchdog timer */
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		WL_INFO("Terminate watchdog timer and enable MPC\n");
+-		wl_set_mpc(ndev, 1);
+-		wl_os_wd_timer(ndev, 0);
+-	}
+-
+-#if defined(CONFIG_PM_SLEEP)
+-	atomic_set(&dhd_mmc_suspend, true);
+-#endif	/*  defined(CONFIG_PM_SLEEP) */
+-
+-	WL_TRACE("Exit\n");
+-
+-	return 0;
+-}
+-
+-static __used s32
+-wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
+-		  s32 err)
+-{
+-	int i, j;
+-
+-	WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
+-	for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
+-		WL_CONN("PMKID[%d]: %pM =\n", i,
+-			&pmk_list->pmkids.pmkid[i].BSSID);
+-		for (j = 0; j < WLAN_PMKID_LEN; j++)
+-			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
+-	}
+-
+-	if (likely(!err))
+-		wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
+-					sizeof(*pmk_list));
+-
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_pmksa *pmksa)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-	int i;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+-		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+-			    ETH_ALEN))
+-			break;
+-	if (i < WL_NUM_PMKIDS_MAX) {
+-		memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
+-		       ETH_ALEN);
+-		memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
+-		       WLAN_PMKID_LEN);
+-		if (i == wl->pmk_list->pmkids.npmkid)
+-			wl->pmk_list->pmkids.npmkid++;
+-	} else
+-		err = -EINVAL;
+-
+-	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
+-	       &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
+-	for (i = 0; i < WLAN_PMKID_LEN; i++)
+-		WL_CONN("%02x\n",
+-		       wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
+-		       PMKID[i]);
+-
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
+-		      struct cfg80211_pmksa *pmksa)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	struct _pmkid_list pmkid;
+-	s32 err = 0;
+-	int i;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
+-	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
+-
+-	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
+-	       &pmkid.pmkid[0].BSSID);
+-	for (i = 0; i < WLAN_PMKID_LEN; i++)
+-		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
+-
+-	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
+-		if (!memcmp
+-		    (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
+-		     ETH_ALEN))
+-			break;
+-
+-	if ((wl->pmk_list->pmkids.npmkid > 0)
+-	    && (i < wl->pmk_list->pmkids.npmkid)) {
+-		memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
+-		for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
+-			memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
+-			       &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
+-			       ETH_ALEN);
+-			memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
+-			       &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
+-			       WLAN_PMKID_LEN);
+-		}
+-		wl->pmk_list->pmkids.npmkid--;
+-	} else
+-		err = -EINVAL;
+-
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-
+-}
+-
+-static s32
+-wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
+-{
+-	struct wl_priv *wl = wiphy_to_wl(wiphy);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	CHECK_SYS_UP();
+-
+-	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
+-	err = wl_update_pmklist(dev, wl->pmk_list, err);
+-
+-	WL_TRACE("Exit\n");
+-	return err;
+-
+-}
+-
+-static struct cfg80211_ops wl_cfg80211_ops = {
+-	.change_virtual_intf = wl_cfg80211_change_iface,
+-	.scan = wl_cfg80211_scan,
+-	.set_wiphy_params = wl_cfg80211_set_wiphy_params,
+-	.join_ibss = wl_cfg80211_join_ibss,
+-	.leave_ibss = wl_cfg80211_leave_ibss,
+-	.get_station = wl_cfg80211_get_station,
+-	.set_tx_power = wl_cfg80211_set_tx_power,
+-	.get_tx_power = wl_cfg80211_get_tx_power,
+-	.add_key = wl_cfg80211_add_key,
+-	.del_key = wl_cfg80211_del_key,
+-	.get_key = wl_cfg80211_get_key,
+-	.set_default_key = wl_cfg80211_config_default_key,
+-	.set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
+-	.set_power_mgmt = wl_cfg80211_set_power_mgmt,
+-	.set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
+-	.connect = wl_cfg80211_connect,
+-	.disconnect = wl_cfg80211_disconnect,
+-	.suspend = wl_cfg80211_suspend,
+-	.resume = wl_cfg80211_resume,
+-	.set_pmksa = wl_cfg80211_set_pmksa,
+-	.del_pmksa = wl_cfg80211_del_pmksa,
+-	.flush_pmksa = wl_cfg80211_flush_pmksa
+-};
+-
+-static s32 wl_mode_to_nl80211_iftype(s32 mode)
+-{
+-	s32 err = 0;
+-
+-	switch (mode) {
+-	case WL_MODE_BSS:
+-		return NL80211_IFTYPE_STATION;
+-	case WL_MODE_IBSS:
+-		return NL80211_IFTYPE_ADHOC;
+-	default:
+-		return NL80211_IFTYPE_UNSPECIFIED;
+-	}
+-
+-	return err;
+-}
+-
+-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
+-					  struct device *dev)
+-{
+-	struct wireless_dev *wdev;
+-	s32 err = 0;
+-
+-	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+-	if (unlikely(!wdev)) {
+-		WL_ERR("Could not allocate wireless device\n");
+-		return ERR_PTR(-ENOMEM);
+-	}
+-	wdev->wiphy =
+-	    wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
+-	if (unlikely(!wdev->wiphy)) {
+-		WL_ERR("Couldn not allocate wiphy device\n");
+-		err = -ENOMEM;
+-		goto wiphy_new_out;
+-	}
+-	set_wiphy_dev(wdev->wiphy, dev);
+-	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+-	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
+-	wdev->wiphy->interface_modes =
+-	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+-	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
+-	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set
+-						* it as 11a by default.
+-						* This will be updated with
+-						* 11n phy tables in
+-						* "ifconfig up"
+-						* if phy has 11n capability
+-						*/
+-	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+-	wdev->wiphy->cipher_suites = __wl_cipher_suites;
+-	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
+-#ifndef WL_POWERSAVE_DISABLED
+-	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;	/* enable power
+-								 * save mode
+-								 * by default
+-								 */
+-#else
+-	wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+-#endif				/* !WL_POWERSAVE_DISABLED */
+-	err = wiphy_register(wdev->wiphy);
+-	if (unlikely(err < 0)) {
+-		WL_ERR("Couldn not register wiphy device (%d)\n", err);
+-		goto wiphy_register_out;
+-	}
+-	return wdev;
+-
+-wiphy_register_out:
+-	wiphy_free(wdev->wiphy);
+-
+-wiphy_new_out:
+-	kfree(wdev);
+-
+-	return ERR_PTR(err);
+-}
+-
+-static void wl_free_wdev(struct wl_priv *wl)
+-{
+-	struct wireless_dev *wdev = wl_to_wdev(wl);
+-
+-	if (unlikely(!wdev)) {
+-		WL_ERR("wdev is invalid\n");
+-		return;
+-	}
+-	wiphy_unregister(wdev->wiphy);
+-	wiphy_free(wdev->wiphy);
+-	kfree(wdev);
+-	wl_to_wdev(wl) = NULL;
+-}
+-
+-static s32 wl_inform_bss(struct wl_priv *wl)
+-{
+-	struct wl_scan_results *bss_list;
+-	struct wl_bss_info *bi = NULL;	/* must be initialized */
+-	s32 err = 0;
+-	int i;
+-
+-	bss_list = wl->bss_list;
+-	if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
+-		WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
+-		       bss_list->version);
+-		return -EOPNOTSUPP;
+-	}
+-	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
+-	bi = next_bss(bss_list, bi);
+-	for_each_bss(bss_list, bi, i) {
+-		err = wl_inform_single_bss(wl, bi);
+-		if (unlikely(err))
+-			break;
+-	}
+-	return err;
+-}
+-
+-
+-static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	struct ieee80211_channel *notify_channel;
+-	struct cfg80211_bss *bss;
+-	struct ieee80211_supported_band *band;
+-	s32 err = 0;
+-	u16 channel;
+-	u32 freq;
+-	u64 notify_timestamp;
+-	u16 notify_capability;
+-	u16 notify_interval;
+-	u8 *notify_ie;
+-	size_t notify_ielen;
+-	s32 notify_signal;
+-
+-	if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
+-		WL_ERR("Bss info is larger than buffer. Discarding\n");
+-		return 0;
+-	}
+-
+-	channel = bi->ctl_ch ? bi->ctl_ch :
+-				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+-
+-	if (channel <= CH_MAX_2G_CHANNEL)
+-		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+-	else
+-		band = wiphy->bands[IEEE80211_BAND_5GHZ];
+-
+-	freq = ieee80211_channel_to_frequency(channel, band->band);
+-	notify_channel = ieee80211_get_channel(wiphy, freq);
+-
+-	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+-	notify_capability = le16_to_cpu(bi->capability);
+-	notify_interval = le16_to_cpu(bi->beacon_period);
+-	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+-	notify_ielen = le16_to_cpu(bi->ie_length);
+-	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+-
+-	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+-			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
+-			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
+-	WL_CONN("Channel: %d(%d)\n", channel, freq);
+-	WL_CONN("Capability: %X\n", notify_capability);
+-	WL_CONN("Beacon interval: %d\n", notify_interval);
+-	WL_CONN("Signal: %d\n", notify_signal);
+-	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+-
+-	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
+-		notify_timestamp, notify_capability, notify_interval, notify_ie,
+-		notify_ielen, notify_signal, GFP_KERNEL);
+-
+-	if (unlikely(!bss)) {
+-		WL_ERR("cfg80211_inform_bss_frame error\n");
+-		return -EINVAL;
+-	}
+-
+-	return err;
+-}
+-
+-static s32
+-wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	struct ieee80211_channel *notify_channel;
+-	struct wl_bss_info *bi = NULL;
+-	struct ieee80211_supported_band *band;
+-	u8 *buf = NULL;
+-	s32 err = 0;
+-	u16 channel;
+-	u32 freq;
+-	u64 notify_timestamp;
+-	u16 notify_capability;
+-	u16 notify_interval;
+-	u8 *notify_ie;
+-	size_t notify_ielen;
+-	s32 notify_signal;
+-
+-	WL_TRACE("Enter\n");
+-
+-	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+-	if (buf == NULL) {
+-		WL_ERR("kzalloc() failed\n");
+-		err = -ENOMEM;
+-		goto CleanUp;
+-	}
+-
+-	*(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+-
+-	err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
+-		goto CleanUp;
+-	}
+-
+-	bi = (wl_bss_info_t *)(buf + 4);
+-
+-	channel = bi->ctl_ch ? bi->ctl_ch :
+-				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+-
+-	if (channel <= CH_MAX_2G_CHANNEL)
+-		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+-	else
+-		band = wiphy->bands[IEEE80211_BAND_5GHZ];
+-
+-	freq = ieee80211_channel_to_frequency(channel, band->band);
+-	notify_channel = ieee80211_get_channel(wiphy, freq);
+-
+-	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+-	notify_capability = le16_to_cpu(bi->capability);
+-	notify_interval = le16_to_cpu(bi->beacon_period);
+-	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+-	notify_ielen = le16_to_cpu(bi->ie_length);
+-	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+-
+-	WL_CONN("channel: %d(%d)\n", channel, freq);
+-	WL_CONN("capability: %X\n", notify_capability);
+-	WL_CONN("beacon interval: %d\n", notify_interval);
+-	WL_CONN("signal: %d\n", notify_signal);
+-	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+-
+-	cfg80211_inform_bss(wiphy, notify_channel, bssid,
+-		notify_timestamp, notify_capability, notify_interval,
+-		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
+-
+-CleanUp:
+-
+-	kfree(buf);
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-
+-	if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) {
+-		WL_CONN("Processing set ssid\n");
+-		wl->link_up = true;
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u16 flags = be16_to_cpu(e->flags);
+-
+-	if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) {
+-		WL_CONN("Processing link down\n");
+-		return true;
+-	}
+-	return false;
+-}
+-
+-static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-	u16 flags = be16_to_cpu(e->flags);
+-
+-	if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) {
+-		WL_CONN("Processing Link %s & no network found\n",
+-				flags & WLC_EVENT_MSG_LINK ? "up" : "down");
+-		return true;
+-	}
+-
+-	if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
+-		WL_CONN("Processing connecting & no network found\n");
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static s32
+-wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
+-			 const wl_event_msg_t *e, void *data)
+-{
+-	s32 err = 0;
+-
+-	if (wl_is_linkup(wl, e)) {
+-		WL_CONN("Linkup\n");
+-		if (wl_is_ibssmode(wl)) {
+-			wl_update_prof(wl, NULL, (void *)e->addr,
+-				WL_PROF_BSSID);
+-			wl_inform_ibss(wl, ndev, e->addr);
+-			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
+-			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-			set_bit(WL_STATUS_CONNECTED, &wl->status);
+-		} else
+-			wl_bss_connect_done(wl, ndev, e, data, true);
+-	} else if (wl_is_linkdown(wl, e)) {
+-		WL_CONN("Linkdown\n");
+-		if (wl_is_ibssmode(wl)) {
+-			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+-				&wl->status))
+-				wl_link_down(wl);
+-		} else {
+-			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+-				&wl->status)) {
+-				cfg80211_disconnected(ndev, 0, NULL, 0,
+-					GFP_KERNEL);
+-				wl_link_down(wl);
+-			}
+-		}
+-		wl_init_prof(wl->profile);
+-	} else if (wl_is_nonetwork(wl, e)) {
+-		if (wl_is_ibssmode(wl))
+-			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-		else
+-			wl_bss_connect_done(wl, ndev, e, data, false);
+-	}
+-
+-	return err;
+-}
+-
+-static s32
+-wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
+-			 const wl_event_msg_t *e, void *data)
+-{
+-	s32 err = 0;
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-
+-	if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
+-		if (test_bit(WL_STATUS_CONNECTED, &wl->status))
+-			wl_bss_roaming_done(wl, ndev, e, data);
+-		else
+-			wl_bss_connect_done(wl, ndev, e, data, true);
+-	}
+-
+-	return err;
+-}
+-
+-static __used s32
+-wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	u32 buflen;
+-
+-	buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+-	BUG_ON(!buflen);
+-
+-	return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
+-}
+-
+-static s32
+-wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
+-		  s32 buf_len)
+-{
+-	struct wl_priv *wl = ndev_to_wl(dev);
+-	u32 len;
+-	s32 err = 0;
+-
+-	len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
+-	BUG_ON(!len);
+-	err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
+-			WL_IOCTL_LEN_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	memcpy(buf, wl->ioctl_buf, buf_len);
+-
+-	return err;
+-}
+-
+-static s32 wl_get_assoc_ies(struct wl_priv *wl)
+-{
+-	struct net_device *ndev = wl_to_ndev(wl);
+-	struct wl_assoc_ielen *assoc_info;
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	u32 req_len;
+-	u32 resp_len;
+-	s32 err = 0;
+-
+-	wl_clear_assoc_ies(wl);
+-
+-	err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
+-				WL_ASSOC_INFO_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("could not get assoc info (%d)\n", err);
+-		return err;
+-	}
+-	assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
+-	req_len = assoc_info->req_len;
+-	resp_len = assoc_info->resp_len;
+-	if (req_len) {
+-		err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
+-					WL_ASSOC_INFO_MAX);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get assoc req (%d)\n", err);
+-			return err;
+-		}
+-		conn_info->req_ie_len = req_len;
+-		conn_info->req_ie =
+-		    kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
+-	} else {
+-		conn_info->req_ie_len = 0;
+-		conn_info->req_ie = NULL;
+-	}
+-	if (resp_len) {
+-		err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
+-					WL_ASSOC_INFO_MAX);
+-		if (unlikely(err)) {
+-			WL_ERR("could not get assoc resp (%d)\n", err);
+-			return err;
+-		}
+-		conn_info->resp_ie_len = resp_len;
+-		conn_info->resp_ie =
+-		    kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
+-	} else {
+-		conn_info->resp_ie_len = 0;
+-		conn_info->resp_ie = NULL;
+-	}
+-	WL_CONN("req len (%d) resp len (%d)\n",
+-	       conn_info->req_ie_len, conn_info->resp_ie_len);
+-
+-	return err;
+-}
+-
+-static void wl_clear_assoc_ies(struct wl_priv *wl)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-
+-	kfree(conn_info->req_ie);
+-	conn_info->req_ie = NULL;
+-	conn_info->req_ie_len = 0;
+-	kfree(conn_info->resp_ie);
+-	conn_info->resp_ie = NULL;
+-	conn_info->resp_ie_len = 0;
+-}
+-
+-
+-static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
+-	size_t *join_params_size)
+-{
+-	chanspec_t chanspec = 0;
+-
+-	if (ch != 0) {
+-		join_params->params.chanspec_num = 1;
+-		join_params->params.chanspec_list[0] = ch;
+-
+-		if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
+-			chanspec |= WL_CHANSPEC_BAND_2G;
+-		else
+-			chanspec |= WL_CHANSPEC_BAND_5G;
+-
+-		chanspec |= WL_CHANSPEC_BW_20;
+-		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+-
+-		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+-			join_params->params.chanspec_num * sizeof(chanspec_t);
+-
+-		join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+-		join_params->params.chanspec_list[0] |= chanspec;
+-		join_params->params.chanspec_list[0] =
+-		cpu_to_le16(join_params->params.chanspec_list[0]);
+-
+-		join_params->params.chanspec_num =
+-			cpu_to_le32(join_params->params.chanspec_num);
+-
+-		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
+-			"channel %d, chanspec %#X\n",
+-		       join_params->params.chanspec_list[0], ch, chanspec);
+-	}
+-}
+-
+-static s32 wl_update_bss_info(struct wl_priv *wl)
+-{
+-	struct wl_bss_info *bi;
+-	struct wlc_ssid *ssid;
+-	struct bcm_tlv *tim;
+-	u16 beacon_interval;
+-	u8 dtim_period;
+-	size_t ie_len;
+-	u8 *ie;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	if (wl_is_ibssmode(wl))
+-		return err;
+-
+-	ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
+-
+-	*(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
+-			wl->extra_buf, WL_EXTRA_BUF_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("Could not get bss info %d\n", err);
+-		goto update_bss_info_out;
+-	}
+-
+-	bi = (struct wl_bss_info *)(wl->extra_buf + 4);
+-	err = wl_inform_single_bss(wl, bi);
+-	if (unlikely(err))
+-		goto update_bss_info_out;
+-
+-	ie = ((u8 *)bi) + bi->ie_offset;
+-	ie_len = bi->ie_length;
+-	beacon_interval = cpu_to_le16(bi->beacon_period);
+-
+-	tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
+-	if (tim)
+-		dtim_period = tim->data[1];
+-	else {
+-		/*
+-		* active scan was done so we could not get dtim
+-		* information out of probe response.
+-		* so we speficially query dtim information to dongle.
+-		*/
+-		u32 var;
+-		err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var);
+-		if (unlikely(err)) {
+-			WL_ERR("wl dtim_assoc failed (%d)\n", err);
+-			goto update_bss_info_out;
+-		}
+-		dtim_period = (u8)var;
+-	}
+-
+-	wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
+-	wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
+-
+-update_bss_info_out:
+-	WL_TRACE("Exit");
+-	return err;
+-}
+-
+-static s32
+-wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
+-		    const wl_event_msg_t *e, void *data)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	wl_get_assoc_ies(wl);
+-	wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
+-	wl_update_bss_info(wl);
+-
+-	cfg80211_roamed(ndev, NULL,
+-			(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
+-			conn_info->req_ie, conn_info->req_ie_len,
+-			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
+-	WL_CONN("Report roaming result\n");
+-
+-	set_bit(WL_STATUS_CONNECTED, &wl->status);
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
+-		    const wl_event_msg_t *e, void *data, bool completed)
+-{
+-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
+-		if (completed) {
+-			wl_get_assoc_ies(wl);
+-			wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
+-			wl_update_bss_info(wl);
+-		}
+-		cfg80211_connect_result(ndev,
+-					(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
+-					conn_info->req_ie,
+-					conn_info->req_ie_len,
+-					conn_info->resp_ie,
+-					conn_info->resp_ie_len,
+-					completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
+-					GFP_KERNEL);
+-		if (completed)
+-			set_bit(WL_STATUS_CONNECTED, &wl->status);
+-		WL_CONN("Report connect result - connection %s\n",
+-				completed ? "succeeded" : "failed");
+-	}
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
+-		     const wl_event_msg_t *e, void *data)
+-{
+-	u16 flags = be16_to_cpu(e->flags);
+-	enum nl80211_key_type key_type;
+-
+-	rtnl_lock();
+-	if (flags & WLC_EVENT_MSG_GROUP)
+-		key_type = NL80211_KEYTYPE_GROUP;
+-	else
+-		key_type = NL80211_KEYTYPE_PAIRWISE;
+-
+-	cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
+-				     NULL, GFP_KERNEL);
+-	rtnl_unlock();
+-
+-	return 0;
+-}
+-
+-static s32
+-wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
+-		      const wl_event_msg_t *e, void *data)
+-{
+-	struct channel_info channel_inform;
+-	struct wl_scan_results *bss_list;
+-	u32 len = WL_SCAN_BUF_MAX;
+-	s32 err = 0;
+-	bool scan_abort = false;
+-
+-	WL_TRACE("Enter\n");
+-
+-	if (wl->iscan_on && wl->iscan_kickstart) {
+-		WL_TRACE("Exit\n");
+-		return wl_wakeup_iscan(wl_to_iscan(wl));
+-	}
+-
+-	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scan complete while device not scanning\n");
+-		scan_abort = true;
+-		err = -EINVAL;
+-		goto scan_done_out;
+-	}
+-
+-	err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
+-			sizeof(channel_inform));
+-	if (unlikely(err)) {
+-		WL_ERR("scan busy (%d)\n", err);
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-	channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
+-	if (unlikely(channel_inform.scan_channel)) {
+-
+-		WL_CONN("channel_inform.scan_channel (%d)\n",
+-		       channel_inform.scan_channel);
+-	}
+-	wl->bss_list = wl->scan_results;
+-	bss_list = wl->bss_list;
+-	memset(bss_list, 0, len);
+-	bss_list->buflen = cpu_to_le32(len);
+-
+-	err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
+-	if (unlikely(err)) {
+-		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
+-		err = -EINVAL;
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-	bss_list->buflen = le32_to_cpu(bss_list->buflen);
+-	bss_list->version = le32_to_cpu(bss_list->version);
+-	bss_list->count = le32_to_cpu(bss_list->count);
+-
+-	err = wl_inform_bss(wl);
+-	if (err) {
+-		scan_abort = true;
+-		goto scan_done_out;
+-	}
+-
+-scan_done_out:
+-	if (wl->scan_request) {
+-		WL_SCAN("calling cfg80211_scan_done\n");
+-		cfg80211_scan_done(wl->scan_request, scan_abort);
+-		wl_set_mpc(ndev, 1);
+-		wl->scan_request = NULL;
+-	}
+-
+-	WL_TRACE("Exit\n");
+-
+-	return err;
+-}
+-
+-static void wl_init_conf(struct wl_conf *conf)
+-{
+-	conf->mode = (u32)-1;
+-	conf->frag_threshold = (u32)-1;
+-	conf->rts_threshold = (u32)-1;
+-	conf->retry_short = (u32)-1;
+-	conf->retry_long = (u32)-1;
+-	conf->tx_power = -1;
+-}
+-
+-static void wl_init_prof(struct wl_profile *prof)
+-{
+-	memset(prof, 0, sizeof(*prof));
+-}
+-
+-static void wl_init_eloop_handler(struct wl_event_loop *el)
+-{
+-	memset(el, 0, sizeof(*el));
+-	el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
+-	el->handler[WLC_E_LINK] = wl_notify_connect_status;
+-	el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
+-	el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
+-	el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
+-}
+-
+-static s32 wl_init_priv_mem(struct wl_priv *wl)
+-{
+-	wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->scan_results)) {
+-		WL_ERR("Scan results alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
+-	if (unlikely(!wl->conf)) {
+-		WL_ERR("wl_conf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
+-	if (unlikely(!wl->profile)) {
+-		WL_ERR("wl_profile alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->bss_info)) {
+-		WL_ERR("Bss information alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
+-	if (unlikely(!wl->scan_req_int)) {
+-		WL_ERR("Scan req alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->ioctl_buf)) {
+-		WL_ERR("Ioctl buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+-	if (unlikely(!wl->extra_buf)) {
+-		WL_ERR("Extra buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
+-	if (unlikely(!wl->iscan)) {
+-		WL_ERR("Iscan buf alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
+-	if (unlikely(!wl->fw)) {
+-		WL_ERR("fw object alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-	wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
+-	if (unlikely(!wl->pmk_list)) {
+-		WL_ERR("pmk list alloc failed\n");
+-		goto init_priv_mem_out;
+-	}
+-
+-	return 0;
+-
+-init_priv_mem_out:
+-	wl_deinit_priv_mem(wl);
+-
+-	return -ENOMEM;
+-}
+-
+-static void wl_deinit_priv_mem(struct wl_priv *wl)
+-{
+-	kfree(wl->scan_results);
+-	wl->scan_results = NULL;
+-	kfree(wl->bss_info);
+-	wl->bss_info = NULL;
+-	kfree(wl->conf);
+-	wl->conf = NULL;
+-	kfree(wl->profile);
+-	wl->profile = NULL;
+-	kfree(wl->scan_req_int);
+-	wl->scan_req_int = NULL;
+-	kfree(wl->ioctl_buf);
+-	wl->ioctl_buf = NULL;
+-	kfree(wl->extra_buf);
+-	wl->extra_buf = NULL;
+-	kfree(wl->iscan);
+-	wl->iscan = NULL;
+-	kfree(wl->fw);
+-	wl->fw = NULL;
+-	kfree(wl->pmk_list);
+-	wl->pmk_list = NULL;
+-}
+-
+-static s32 wl_create_event_handler(struct wl_priv *wl)
+-{
+-	sema_init(&wl->event_sync, 0);
+-	wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
+-	if (IS_ERR(wl->event_tsk)) {
+-		wl->event_tsk = NULL;
+-		WL_ERR("failed to create event thread\n");
+-		return -ENOMEM;
+-	}
+-	return 0;
+-}
+-
+-static void wl_destroy_event_handler(struct wl_priv *wl)
+-{
+-	if (wl->event_tsk) {
+-		send_sig(SIGTERM, wl->event_tsk, 1);
+-		kthread_stop(wl->event_tsk);
+-		wl->event_tsk = NULL;
+-	}
+-}
+-
+-static void wl_term_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-
+-	if (wl->iscan_on && iscan->tsk) {
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		send_sig(SIGTERM, iscan->tsk, 1);
+-		kthread_stop(iscan->tsk);
+-		iscan->tsk = NULL;
+-	}
+-}
+-
+-static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
+-{
+-	struct wl_priv *wl = iscan_to_wl(iscan);
+-	struct net_device *ndev = wl_to_ndev(wl);
+-
+-	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
+-		WL_ERR("Scan complete while device not scanning\n");
+-		return;
+-	}
+-	if (likely(wl->scan_request)) {
+-		WL_SCAN("ISCAN Completed scan: %s\n",
+-				aborted ? "Aborted" : "Done");
+-		cfg80211_scan_done(wl->scan_request, aborted);
+-		wl_set_mpc(ndev, 1);
+-		wl->scan_request = NULL;
+-	}
+-	wl->iscan_kickstart = false;
+-}
+-
+-static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
+-{
+-	if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
+-		WL_SCAN("wake up iscan\n");
+-		up(&iscan->sync);
+-		return 0;
+-	}
+-
+-	return -EIO;
+-}
+-
+-static s32
+-wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
+-		     struct wl_scan_results **bss_list)
+-{
+-	struct wl_iscan_results list;
+-	struct wl_scan_results *results;
+-	struct wl_iscan_results *list_buf;
+-	s32 err = 0;
+-
+-	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
+-	list_buf = (struct wl_iscan_results *)iscan->scan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
+-	err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
+-				WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
+-				WL_ISCAN_BUF_MAX);
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-	results->buflen = le32_to_cpu(results->buflen);
+-	results->version = le32_to_cpu(results->version);
+-	results->count = le32_to_cpu(results->count);
+-	WL_SCAN("results->count = %d\n", results->count);
+-	WL_SCAN("results->buflen = %d\n", results->buflen);
+-	*status = le32_to_cpu(list_buf->status);
+-	*bss_list = results;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_done(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	iscan->state = WL_ISCAN_STATE_IDLE;
+-	rtnl_lock();
+-	wl_inform_bss(wl);
+-	wl_notify_iscan_complete(iscan, false);
+-	rtnl_unlock();
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_pending(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	/* Reschedule the timer */
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_inprogress(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	rtnl_lock();
+-	wl_inform_bss(wl);
+-	wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+-	rtnl_unlock();
+-	/* Reschedule the timer */
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-	iscan->timer_on = 1;
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_aborted(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl->iscan;
+-	s32 err = 0;
+-
+-	iscan->state = WL_ISCAN_STATE_IDLE;
+-	rtnl_lock();
+-	wl_notify_iscan_complete(iscan, true);
+-	rtnl_unlock();
+-
+-	return err;
+-}
+-
+-static s32 wl_iscan_thread(void *data)
+-{
+-	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+-	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+-	struct wl_priv *wl = iscan_to_wl(iscan);
+-	struct wl_iscan_eloop *el = &iscan->el;
+-	u32 status;
+-	int err = 0;
+-
+-	sched_setscheduler(current, SCHED_FIFO, &param);
+-	allow_signal(SIGTERM);
+-	status = WL_SCAN_RESULTS_PARTIAL;
+-	while (likely(!down_interruptible(&iscan->sync))) {
+-		if (kthread_should_stop())
+-			break;
+-		if (iscan->timer_on) {
+-			del_timer_sync(&iscan->timer);
+-			iscan->timer_on = 0;
+-		}
+-		rtnl_lock();
+-		err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
+-		if (unlikely(err)) {
+-			status = WL_SCAN_RESULTS_ABORTED;
+-			WL_ERR("Abort iscan\n");
+-		}
+-		rtnl_unlock();
+-		el->handler[status] (wl);
+-	}
+-	if (iscan->timer_on) {
+-		del_timer_sync(&iscan->timer);
+-		iscan->timer_on = 0;
+-	}
+-	WL_SCAN("ISCAN thread terminated\n");
+-
+-	return 0;
+-}
+-
+-static void wl_iscan_timer(unsigned long data)
+-{
+-	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
+-
+-	if (iscan) {
+-		iscan->timer_on = 0;
+-		WL_SCAN("timer expired\n");
+-		wl_wakeup_iscan(iscan);
+-	}
+-}
+-
+-static s32 wl_invoke_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	int err = 0;
+-
+-	if (wl->iscan_on && !iscan->tsk) {
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		sema_init(&iscan->sync, 0);
+-		iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+-		if (IS_ERR(iscan->tsk)) {
+-			WL_ERR("Could not create iscan thread\n");
+-			iscan->tsk = NULL;
+-			return -ENOMEM;
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
+-{
+-	memset(el, 0, sizeof(*el));
+-	el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
+-	el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
+-	el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
+-	el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
+-	el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
+-}
+-
+-static s32 wl_init_iscan(struct wl_priv *wl)
+-{
+-	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
+-	int err = 0;
+-
+-	if (wl->iscan_on) {
+-		iscan->dev = wl_to_ndev(wl);
+-		iscan->state = WL_ISCAN_STATE_IDLE;
+-		wl_init_iscan_eloop(&iscan->el);
+-		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
+-		init_timer(&iscan->timer);
+-		iscan->timer.data = (unsigned long) iscan;
+-		iscan->timer.function = wl_iscan_timer;
+-		sema_init(&iscan->sync, 0);
+-		iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
+-		if (IS_ERR(iscan->tsk)) {
+-			WL_ERR("Could not create iscan thread\n");
+-			iscan->tsk = NULL;
+-			return -ENOMEM;
+-		}
+-		iscan->data = wl;
+-	}
+-
+-	return err;
+-}
+-
+-static void wl_init_fw(struct wl_fw_ctrl *fw)
+-{
+-	fw->status = 0;		/* init fw loading status.
+-				 0 means nothing was loaded yet */
+-}
+-
+-static s32 wl_init_priv(struct wl_priv *wl)
+-{
+-	struct wiphy *wiphy = wl_to_wiphy(wl);
+-	s32 err = 0;
+-
+-	wl->scan_request = NULL;
+-	wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
+-	wl->iscan_on = true;	/* iscan on & off switch.
+-				 we enable iscan per default */
+-	wl->roam_on = false;	/* roam on & off switch.
+-				 we enable roam per default */
+-
+-	wl->iscan_kickstart = false;
+-	wl->active_scan = true;	/* we do active scan for
+-				 specific scan per default */
+-	wl->dongle_up = false;	/* dongle is not up yet */
+-	wl_init_eq(wl);
+-	err = wl_init_priv_mem(wl);
+-	if (unlikely(err))
+-		return err;
+-	if (unlikely(wl_create_event_handler(wl)))
+-		return -ENOMEM;
+-	wl_init_eloop_handler(&wl->el);
+-	mutex_init(&wl->usr_sync);
+-	err = wl_init_iscan(wl);
+-	if (unlikely(err))
+-		return err;
+-	wl_init_fw(wl->fw);
+-	wl_init_conf(wl->conf);
+-	wl_init_prof(wl->profile);
+-	wl_link_down(wl);
+-
+-	return err;
+-}
+-
+-static void wl_deinit_priv(struct wl_priv *wl)
+-{
+-	wl_destroy_event_handler(wl);
+-	wl->dongle_up = false;	/* dongle down */
+-	wl_flush_eq(wl);
+-	wl_link_down(wl);
+-	wl_term_iscan(wl);
+-	wl_deinit_priv_mem(wl);
+-}
+-
+-s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
+-{
+-	struct wireless_dev *wdev;
+-	struct wl_priv *wl;
+-	struct wl_iface *ci;
+-	s32 err = 0;
+-
+-	if (unlikely(!ndev)) {
+-		WL_ERR("ndev is invalid\n");
+-		return -ENODEV;
+-	}
+-	wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
+-	if (unlikely(!wl_cfg80211_dev)) {
+-		WL_ERR("wl_cfg80211_dev is invalid\n");
+-		return -ENOMEM;
+-	}
+-	WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
+-	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
+-	if (IS_ERR(wdev))
+-		return -ENOMEM;
+-
+-	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
+-	wl = wdev_to_wl(wdev);
+-	wl->wdev = wdev;
+-	wl->pub = data;
+-	ci = (struct wl_iface *)wl_to_ci(wl);
+-	ci->wl = wl;
+-	ndev->ieee80211_ptr = wdev;
+-	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+-	wdev->netdev = ndev;
+-	err = wl_init_priv(wl);
+-	if (unlikely(err)) {
+-		WL_ERR("Failed to init iwm_priv (%d)\n", err);
+-		goto cfg80211_attach_out;
+-	}
+-	wl_set_drvdata(wl_cfg80211_dev, ci);
+-
+-	return err;
+-
+-cfg80211_attach_out:
+-	wl_free_wdev(wl);
+-	return err;
+-}
+-
+-void wl_cfg80211_detach(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-
+-	wl_deinit_priv(wl);
+-	wl_free_wdev(wl);
+-	wl_set_drvdata(wl_cfg80211_dev, NULL);
+-	kfree(wl_cfg80211_dev);
+-	wl_cfg80211_dev = NULL;
+-	wl_clear_sdio_func();
+-}
+-
+-static void wl_wakeup_event(struct wl_priv *wl)
+-{
+-	up(&wl->event_sync);
+-}
+-
+-static s32 wl_event_handler(void *data)
+-{
+-	struct wl_priv *wl = (struct wl_priv *)data;
+-	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+-	struct wl_event_q *e;
+-
+-	sched_setscheduler(current, SCHED_FIFO, &param);
+-	allow_signal(SIGTERM);
+-	while (likely(!down_interruptible(&wl->event_sync))) {
+-		if (kthread_should_stop())
+-			break;
+-		e = wl_deq_event(wl);
+-		if (unlikely(!e)) {
+-			WL_ERR("event queue empty...\n");
+-			BUG();
+-		}
+-		WL_INFO("event type (%d)\n", e->etype);
+-		if (wl->el.handler[e->etype]) {
+-			wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
+-						  e->edata);
+-		} else {
+-			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
+-		}
+-		wl_put_event(e);
+-	}
+-	WL_INFO("was terminated\n");
+-	return 0;
+-}
+-
+-void
+-wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
+-{
+-	u32 event_type = be32_to_cpu(e->event_type);
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-
+-	if (likely(!wl_enq_event(wl, event_type, e, data)))
+-		wl_wakeup_event(wl);
+-}
+-
+-static void wl_init_eq(struct wl_priv *wl)
+-{
+-	wl_init_eq_lock(wl);
+-	INIT_LIST_HEAD(&wl->eq_list);
+-}
+-
+-static void wl_flush_eq(struct wl_priv *wl)
+-{
+-	struct wl_event_q *e;
+-
+-	wl_lock_eq(wl);
+-	while (!list_empty(&wl->eq_list)) {
+-		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+-		list_del(&e->eq_list);
+-		kfree(e);
+-	}
+-	wl_unlock_eq(wl);
+-}
+-
+-/*
+-* retrieve first queued event from head
+-*/
+-
+-static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
+-{
+-	struct wl_event_q *e = NULL;
+-
+-	wl_lock_eq(wl);
+-	if (likely(!list_empty(&wl->eq_list))) {
+-		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
+-		list_del(&e->eq_list);
+-	}
+-	wl_unlock_eq(wl);
+-
+-	return e;
+-}
+-
+-/*
+-** push event to tail of the queue
+-*/
+-
+-static s32
+-wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
+-	     void *data)
+-{
+-	struct wl_event_q *e;
+-	s32 err = 0;
+-
+-	e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
+-	if (unlikely(!e)) {
+-		WL_ERR("event alloc failed\n");
+-		return -ENOMEM;
+-	}
+-
+-	e->etype = event;
+-	memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
+-	if (data) {
+-	}
+-	wl_lock_eq(wl);
+-	list_add_tail(&e->eq_list, &wl->eq_list);
+-	wl_unlock_eq(wl);
+-
+-	return err;
+-}
+-
+-static void wl_put_event(struct wl_event_q *e)
+-{
+-	kfree(e);
+-}
+-
+-void wl_cfg80211_sdio_func(void *func)
+-{
+-	cfg80211_sdio_func = (struct sdio_func *)func;
+-}
+-
+-static void wl_clear_sdio_func(void)
+-{
+-	cfg80211_sdio_func = NULL;
+-}
+-
+-struct sdio_func *wl_cfg80211_get_sdio_func(void)
+-{
+-	return cfg80211_sdio_func;
+-}
+-
+-static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
+-{
+-	s32 infra = 0;
+-	s32 err = 0;
+-
+-	switch (iftype) {
+-	case NL80211_IFTYPE_MONITOR:
+-	case NL80211_IFTYPE_WDS:
+-		WL_ERR("type (%d) : currently we do not support this mode\n",
+-		       iftype);
+-		err = -EINVAL;
+-		return err;
+-	case NL80211_IFTYPE_ADHOC:
+-		infra = 0;
+-		break;
+-	case NL80211_IFTYPE_STATION:
+-		infra = 1;
+-		break;
+-	default:
+-		err = -EINVAL;
+-		WL_ERR("invalid type (%d)\n", iftype);
+-		return err;
+-	}
+-	infra = cpu_to_le32(infra);
+-	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
+-		return err;
+-	}
+-
+-	return 0;
+-}
+-
+-#ifndef EMBEDDED_PLATFORM
+-static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
+-{
+-
+-	s32 err = 0;
+-
+-	return err;
+-}
+-
+-static s32 wl_dongle_up(struct net_device *ndev, u32 up)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_UP error (%d)\n", err);
+-	}
+-	return err;
+-}
+-
+-static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_PM error (%d)\n", err);
+-	}
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-	s32 err = 0;
+-
+-	/* Match Host and Dongle rx alignment */
+-	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("txglomalign error (%d)\n", err);
+-		goto dongle_glom_out;
+-	}
+-	/* disable glom option per default */
+-	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("txglom error (%d)\n", err);
+-		goto dongle_glom_out;
+-	}
+-dongle_glom_out:
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-							 '\0' + bitvec  */
+-	s32 err = 0;
+-
+-	/* Set ARP offload */
+-	bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("arpoe is not supported\n");
+-		else
+-			WL_ERR("arpoe error (%d)\n", err);
+-
+-		goto dongle_offload_out;
+-	}
+-	bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("arp_ol is not supported\n");
+-		else
+-			WL_ERR("arp_ol error (%d)\n", err);
+-
+-		goto dongle_offload_out;
+-	}
+-
+-dongle_offload_out:
+-	return err;
+-}
+-
+-static s32 wl_pattern_atoh(s8 *src, s8 *dst)
+-{
+-	int i;
+-	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
+-		WL_ERR("Mask invalid format. Needs to start with 0x\n");
+-		return -1;
+-	}
+-	src = src + 2;		/* Skip past 0x */
+-	if (strlen(src) % 2 != 0) {
+-		WL_ERR("Mask invalid format. Needs to be of even length\n");
+-		return -1;
+-	}
+-	for (i = 0; *src != '\0'; i++) {
+-		char num[3];
+-		strncpy(num, src, 2);
+-		num[2] = '\0';
+-		dst[i] = (u8) simple_strtoul(num, NULL, 16);
+-		src += 2;
+-	}
+-	return i;
+-}
+-
+-static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-							 '\0' + bitvec  */
+-	const s8 *str;
+-	struct wl_pkt_filter pkt_filter;
+-	struct wl_pkt_filter *pkt_filterp;
+-	s32 buf_len;
+-	s32 str_len;
+-	u32 mask_size;
+-	u32 pattern_size;
+-	s8 buf[256];
+-	s32 err = 0;
+-
+-/* add a default packet filter pattern */
+-	str = "pkt_filter_add";
+-	str_len = strlen(str);
+-	strncpy(buf, str, str_len);
+-	buf[str_len] = '\0';
+-	buf_len = str_len + 1;
+-
+-	pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
+-
+-	/* Parse packet filter id. */
+-	pkt_filter.id = cpu_to_le32(100);
+-
+-	/* Parse filter polarity. */
+-	pkt_filter.negate_match = cpu_to_le32(0);
+-
+-	/* Parse filter type. */
+-	pkt_filter.type = cpu_to_le32(0);
+-
+-	/* Parse pattern filter offset. */
+-	pkt_filter.u.pattern.offset = cpu_to_le32(0);
+-
+-	/* Parse pattern filter mask. */
+-	mask_size = cpu_to_le32(wl_pattern_atoh("0xff",
+-						(char *)pkt_filterp->u.pattern.
+-						mask_and_pattern));
+-
+-	/* Parse pattern filter pattern. */
+-	pattern_size = cpu_to_le32(wl_pattern_atoh("0x00",
+-						   (char *)&pkt_filterp->u.
+-						   pattern.
+-						   mask_and_pattern
+-						   [mask_size]));
+-
+-	if (mask_size != pattern_size) {
+-		WL_ERR("Mask and pattern not the same size\n");
+-		err = -EINVAL;
+-		goto dongle_filter_out;
+-	}
+-
+-	pkt_filter.u.pattern.size_bytes = mask_size;
+-	buf_len += WL_PKT_FILTER_FIXED_LEN;
+-	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+-
+-	/* Keep-alive attributes are set in local
+-	 * variable (keep_alive_pkt), and
+-	 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
+-	 * guarantee that the buffer is properly aligned.
+-	 */
+-	memcpy((char *)pkt_filterp, &pkt_filter,
+-	       WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
+-	if (err) {
+-		if (err == -EOPNOTSUPP) {
+-			WL_INFO("filter not supported\n");
+-		} else {
+-			WL_ERR("filter (%d)\n", err);
+-		}
+-		goto dongle_filter_out;
+-	}
+-
+-	/* set mode to allow pattern */
+-	bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (err) {
+-		if (err == -EOPNOTSUPP) {
+-			WL_INFO("filter_mode not supported\n");
+-		} else {
+-			WL_ERR("filter_mode (%d)\n", err);
+-		}
+-		goto dongle_filter_out;
+-	}
+-
+-dongle_filter_out:
+-	return err;
+-}
+-#endif				/* !EMBEDDED_PLATFORM */
+-
+-static s32 wl_dongle_eventmsg(struct net_device *ndev)
+-{
+-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+-						 '\0' + bitvec  */
+-	s8 eventmask[WL_EVENTING_MASK_LEN];
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-
+-	/* Setup event_msgs */
+-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("Get event_msgs error (%d)\n", err);
+-		goto dongle_eventmsg_out;
+-	}
+-	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-
+-	setbit(eventmask, WLC_E_SET_SSID);
+-	setbit(eventmask, WLC_E_ROAM);
+-	setbit(eventmask, WLC_E_PRUNE);
+-	setbit(eventmask, WLC_E_AUTH);
+-	setbit(eventmask, WLC_E_REASSOC);
+-	setbit(eventmask, WLC_E_REASSOC_IND);
+-	setbit(eventmask, WLC_E_DEAUTH_IND);
+-	setbit(eventmask, WLC_E_DISASSOC_IND);
+-	setbit(eventmask, WLC_E_DISASSOC);
+-	setbit(eventmask, WLC_E_JOIN);
+-	setbit(eventmask, WLC_E_ASSOC_IND);
+-	setbit(eventmask, WLC_E_PSK_SUP);
+-	setbit(eventmask, WLC_E_LINK);
+-	setbit(eventmask, WLC_E_NDIS_LINK);
+-	setbit(eventmask, WLC_E_MIC_ERROR);
+-	setbit(eventmask, WLC_E_PMKID_CACHE);
+-	setbit(eventmask, WLC_E_TXFAIL);
+-	setbit(eventmask, WLC_E_JOIN_START);
+-	setbit(eventmask, WLC_E_SCAN_COMPLETE);
+-
+-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+-		    sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("Set event_msgs error (%d)\n", err);
+-		goto dongle_eventmsg_out;
+-	}
+-
+-dongle_eventmsg_out:
+-	WL_TRACE("Exit\n");
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
+-{
+-	s8 iovbuf[32];
+-	s32 roamtrigger[2];
+-	s32 roam_delta[2];
+-	s32 err = 0;
+-
+-	/*
+-	 * Setup timeout if Beacons are lost and roam is
+-	 * off to report link down
+-	 */
+-	if (roamvar) {
+-		bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout,
+-			sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
+-		err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-		if (unlikely(err)) {
+-			WL_ERR("bcn_timeout error (%d)\n", err);
+-			goto dongle_rom_out;
+-		}
+-	}
+-
+-	/*
+-	 * Enable/Disable built-in roaming to allow supplicant
+-	 * to take care of roaming
+-	 */
+-	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
+-	bcm_mkiovar("roam_off", (char *)&roamvar,
+-				sizeof(roamvar), iovbuf, sizeof(iovbuf));
+-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+-	if (unlikely(err)) {
+-		WL_ERR("roam_off error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-	roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
+-	roamtrigger[1] = WLC_BAND_ALL;
+-	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_TRIGGER,
+-			(void *)roamtrigger, sizeof(roamtrigger));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-	roam_delta[0] = WL_ROAM_DELTA;
+-	roam_delta[1] = WLC_BAND_ALL;
+-	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_DELTA,
+-				(void *)roam_delta, sizeof(roam_delta));
+-	if (unlikely(err)) {
+-		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
+-		goto dongle_rom_out;
+-	}
+-
+-dongle_rom_out:
+-	return err;
+-}
+-
+-static s32
+-wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+-		s32 scan_unassoc_time, s32 scan_passive_time)
+-{
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
+-			sizeof(scan_assoc_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan assoc time is not supported\n");
+-		else
+-			WL_ERR("Scan assoc time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
+-			sizeof(scan_unassoc_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan unassoc time is not supported\n");
+-		else
+-			WL_ERR("Scan unassoc time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-
+-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME, &scan_passive_time,
+-			sizeof(scan_passive_time));
+-	if (err) {
+-		if (err == -EOPNOTSUPP)
+-			WL_INFO("Scan passive time is not supported\n");
+-		else
+-			WL_ERR("Scan passive time error (%d)\n", err);
+-		goto dongle_scantime_out;
+-	}
+-
+-dongle_scantime_out:
+-	return err;
+-}
+-
+-s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
+-{
+-#ifndef DHD_SDALIGN
+-#define DHD_SDALIGN	32
+-#endif
+-	struct net_device *ndev;
+-	struct wireless_dev *wdev;
+-	s32 err = 0;
+-
+-	if (wl->dongle_up)
+-		return err;
+-
+-	ndev = wl_to_ndev(wl);
+-	wdev = ndev->ieee80211_ptr;
+-	if (need_lock)
+-		rtnl_lock();
+-
+-#ifndef EMBEDDED_PLATFORM
+-	err = wl_dongle_up(ndev, 0);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_country(ndev, 0);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_power(ndev, PM_FAST);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-
+-	wl_dongle_offload(ndev, 1, 0xf);
+-	wl_dongle_filter(ndev, 1);
+-#endif /* !EMBEDDED_PLATFORM */
+-
+-	wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
+-			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
+-
+-	err = wl_dongle_eventmsg(ndev);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-	err = wl_dongle_mode(ndev, wdev->iftype);
+-	if (unlikely(err && err != -EINPROGRESS))
+-		goto default_conf_out;
+-	err = wl_dongle_probecap(wl);
+-	if (unlikely(err))
+-		goto default_conf_out;
+-
+-	/* -EINPROGRESS: Call commit handler */
+-
+-default_conf_out:
+-	if (need_lock)
+-		rtnl_unlock();
+-
+-	wl->dongle_up = true;
+-
+-	return err;
+-
+-}
+-
+-static s32 wl_update_wiphybands(struct wl_priv *wl)
+-{
+-	struct wiphy *wiphy;
+-	s32 phy_list;
+-	s8 phy;
+-	s32 err = 0;
+-
+-	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
+-			sizeof(phy_list));
+-	if (unlikely(err)) {
+-		WL_ERR("error (%d)\n", err);
+-		return err;
+-	}
+-
+-	phy = ((char *)&phy_list)[1];
+-	WL_INFO("%c phy\n", phy);
+-	if (phy == 'n' || phy == 'a') {
+-		wiphy = wl_to_wiphy(wl);
+-		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
+-	}
+-
+-	return err;
+-}
+-
+-static s32 __wl_cfg80211_up(struct wl_priv *wl)
+-{
+-	s32 err = 0;
+-
+-	set_bit(WL_STATUS_READY, &wl->status);
+-
+-	wl_debugfs_add_netdev_params(wl);
+-
+-	err = wl_config_dongle(wl, false);
+-	if (unlikely(err))
+-		return err;
+-
+-	wl_invoke_iscan(wl);
+-
+-	return err;
+-}
+-
+-static s32 __wl_cfg80211_down(struct wl_priv *wl)
+-{
+-	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	wl_term_iscan(wl);
+-	if (wl->scan_request) {
+-		cfg80211_scan_done(wl->scan_request, true);
+-		/* May need to perform this to cover rmmod */
+-		/* wl_set_mpc(wl_to_ndev(wl), 1); */
+-		wl->scan_request = NULL;
+-	}
+-	clear_bit(WL_STATUS_READY, &wl->status);
+-	clear_bit(WL_STATUS_SCANNING, &wl->status);
+-	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTING, &wl->status);
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	wl_debugfs_remove_netdev(wl);
+-
+-	return 0;
+-}
+-
+-s32 wl_cfg80211_up(void)
+-{
+-	struct wl_priv *wl;
+-	s32 err = 0;
+-
+-	wl = WL_PRIV_GET();
+-	mutex_lock(&wl->usr_sync);
+-	err = __wl_cfg80211_up(wl);
+-	mutex_unlock(&wl->usr_sync);
+-
+-	return err;
+-}
+-
+-s32 wl_cfg80211_down(void)
+-{
+-	struct wl_priv *wl;
+-	s32 err = 0;
+-
+-	wl = WL_PRIV_GET();
+-	mutex_lock(&wl->usr_sync);
+-	err = __wl_cfg80211_down(wl);
+-	mutex_unlock(&wl->usr_sync);
+-
+-	return err;
+-}
+-
+-static s32 wl_dongle_probecap(struct wl_priv *wl)
+-{
+-	s32 err = 0;
+-
+-	err = wl_update_wiphybands(wl);
+-	if (unlikely(err))
+-		return err;
+-
+-	return err;
+-}
+-
+-static void *wl_read_prof(struct wl_priv *wl, s32 item)
+-{
+-	switch (item) {
+-	case WL_PROF_SEC:
+-		return &wl->profile->sec;
+-	case WL_PROF_BSSID:
+-		return &wl->profile->bssid;
+-	case WL_PROF_SSID:
+-		return &wl->profile->ssid;
+-	}
+-	WL_ERR("invalid item (%d)\n", item);
+-	return NULL;
+-}
+-
+-static s32
+-wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
+-	       s32 item)
+-{
+-	s32 err = 0;
+-	struct wlc_ssid *ssid;
+-
+-	switch (item) {
+-	case WL_PROF_SSID:
+-		ssid = (wlc_ssid_t *) data;
+-		memset(wl->profile->ssid.SSID, 0,
+-		       sizeof(wl->profile->ssid.SSID));
+-		memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
+-		wl->profile->ssid.SSID_len = ssid->SSID_len;
+-		break;
+-	case WL_PROF_BSSID:
+-		if (data)
+-			memcpy(wl->profile->bssid, data, ETH_ALEN);
+-		else
+-			memset(wl->profile->bssid, 0, ETH_ALEN);
+-		break;
+-	case WL_PROF_SEC:
+-		memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
+-		break;
+-	case WL_PROF_BEACONINT:
+-		wl->profile->beacon_interval = *(u16 *)data;
+-		break;
+-	case WL_PROF_DTIMPERIOD:
+-		wl->profile->dtim_period = *(u8 *)data;
+-		break;
+-	default:
+-		WL_ERR("unsupported item (%d)\n", item);
+-		err = -EOPNOTSUPP;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-static bool wl_is_ibssmode(struct wl_priv *wl)
+-{
+-	return wl->conf->mode == WL_MODE_IBSS;
+-}
+-
+-static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
+-{
+-	struct wl_ie *ie = wl_to_ie(wl);
+-	s32 err = 0;
+-
+-	if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
+-		WL_ERR("ei crosses buffer boundary\n");
+-		return -ENOSPC;
+-	}
+-	ie->buf[ie->offset] = t;
+-	ie->buf[ie->offset + 1] = l;
+-	memcpy(&ie->buf[ie->offset + 2], v, l);
+-	ie->offset += l + 2;
+-
+-	return err;
+-}
+-
+-
+-static void wl_link_down(struct wl_priv *wl)
+-{
+-	struct net_device *dev = NULL;
+-	s32 err = 0;
+-
+-	WL_TRACE("Enter\n");
+-	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+-
+-	if (wl->link_up) {
+-		dev = wl_to_ndev(wl);
+-		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
+-		err = wl_dev_ioctl(dev, WLC_DISASSOC, NULL, 0);
+-		if (unlikely(err))
+-			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
+-		wl->link_up = false;
+-	}
+-	WL_TRACE("Exit\n");
+-}
+-
+-static void wl_lock_eq(struct wl_priv *wl)
+-{
+-	spin_lock_irq(&wl->eq_lock);
+-}
+-
+-static void wl_unlock_eq(struct wl_priv *wl)
+-{
+-	spin_unlock_irq(&wl->eq_lock);
+-}
+-
+-static void wl_init_eq_lock(struct wl_priv *wl)
+-{
+-	spin_lock_init(&wl->eq_lock);
+-}
+-
+-static void wl_delay(u32 ms)
+-{
+-	if (ms < 1000 / HZ) {
+-		cond_resched();
+-		mdelay(ms);
+-	} else {
+-		msleep(ms);
+-	}
+-}
+-
+-static void wl_set_drvdata(struct wl_dev *dev, void *data)
+-{
+-	dev->driver_data = data;
+-}
+-
+-static void *wl_get_drvdata(struct wl_dev *dev)
+-{
+-	return dev->driver_data;
+-}
+-
+-s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
+-{
+-	const struct firmware *fw_entry;
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-
+-	fw_entry = wl->fw->fw_entry;
+-
+-	if (fw_entry->size < wl->fw->ptr + size)
+-		size = fw_entry->size - wl->fw->ptr;
+-
+-	memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
+-	wl->fw->ptr += size;
+-	return size;
+-}
+-
+-void wl_cfg80211_release_fw(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	release_firmware(wl->fw->fw_entry);
+-	wl->fw->ptr = 0;
+-}
+-
+-void *wl_cfg80211_request_fw(s8 *file_name)
+-{
+-	struct wl_priv *wl;
+-	const struct firmware *fw_entry = NULL;
+-	s32 err = 0;
+-
+-	WL_INFO("file name : \"%s\"\n", file_name);
+-	wl = WL_PRIV_GET();
+-
+-	if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
+-		err = request_firmware(&wl->fw->fw_entry, file_name,
+-				&wl_cfg80211_get_sdio_func()->dev);
+-		if (unlikely(err)) {
+-			WL_ERR("Could not download fw (%d)\n", err);
+-			goto req_fw_out;
+-		}
+-		set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
+-		fw_entry = wl->fw->fw_entry;
+-		if (fw_entry) {
+-			WL_INFO("fw size (%zd), data (%p)\n",
+-			       fw_entry->size, fw_entry->data);
+-		}
+-	} else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
+-		err = request_firmware(&wl->fw->fw_entry, file_name,
+-				&wl_cfg80211_get_sdio_func()->dev);
+-		if (unlikely(err)) {
+-			WL_ERR("Could not download nvram (%d)\n", err);
+-			goto req_fw_out;
+-		}
+-		set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
+-		fw_entry = wl->fw->fw_entry;
+-		if (fw_entry) {
+-			WL_INFO("nvram size (%zd), data (%p)\n",
+-			       fw_entry->size, fw_entry->data);
+-		}
+-	} else {
+-		WL_INFO("Downloading already done. Nothing to do more\n");
+-		err = -EPERM;
+-	}
+-
+-req_fw_out:
+-	if (unlikely(err)) {
+-		return NULL;
+-	}
+-	wl->fw->ptr = 0;
+-	return (void *)fw_entry->data;
+-}
+-
+-s8 *wl_cfg80211_get_fwname(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
+-	return wl->fw->fw_name;
+-}
+-
+-s8 *wl_cfg80211_get_nvramname(void)
+-{
+-	struct wl_priv *wl;
+-
+-	wl = WL_PRIV_GET();
+-	strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
+-	return wl->fw->nvram_name;
+-}
+-
+-static void wl_set_mpc(struct net_device *ndev, int mpc)
+-{
+-	s32 err = 0;
+-	struct wl_priv *wl = ndev_to_wl(ndev);
+-
+-	if (test_bit(WL_STATUS_READY, &wl->status)) {
+-		err = wl_dev_intvar_set(ndev, "mpc", mpc);
+-		if (unlikely(err)) {
+-			WL_ERR("fail to set mpc\n");
+-			return;
+-		}
+-		WL_INFO("MPC : %d\n", mpc);
+-	}
+-}
+-
+-static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
+-{
+-	char buf[10+IFNAMSIZ];
+-	struct dentry *fd;
+-	s32 err = 0;
+-
+-	sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
+-	wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
+-
+-	fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
+-		(u16 *)&wl->profile->beacon_interval);
+-	if (!fd) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-
+-	fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
+-		(u8 *)&wl->profile->dtim_period);
+-	if (!fd) {
+-		err = -ENOMEM;
+-		goto err_out;
+-	}
+-
+-err_out:
+-	return err;
+-}
+-
+-static void wl_debugfs_remove_netdev(struct wl_priv *wl)
+-{
+-	debugfs_remove_recursive(wl->debugfsdir);
+-	wl->debugfsdir = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
+deleted file mode 100644
+index 996033c..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
++++ /dev/null
+@@ -1,414 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_cfg80211_h_
+-#define _wl_cfg80211_h_
+-
+-#include <linux/wireless.h>
+-#include <linux/wireless.h>
+-#include <net/cfg80211.h>
+-#include <wlioctl.h>
+-
+-struct wl_conf;
+-struct wl_iface;
+-struct wl_priv;
+-struct wl_security;
+-struct wl_ibss;
+-
+-#define WL_DBG_NONE		0
+-#define WL_DBG_CONN		(1 << 5)
+-#define WL_DBG_SCAN		(1 << 4)
+-#define WL_DBG_TRACE		(1 << 3)
+-#define WL_DBG_INFO		(1 << 1)
+-#define WL_DBG_ERR		(1 << 0)
+-#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
+-				(WL_DBG_SCAN) | (WL_DBG_CONN))
+-
+-#define	WL_ERR(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_ERR) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "ERROR @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#if (defined BCMDBG)
+-#define	WL_INFO(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_INFO) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "INFO @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_TRACE(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_TRACE) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "TRACE @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_SCAN(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_SCAN) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "SCAN @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#define	WL_CONN(fmt, args...)					\
+-do {								\
+-	if (wl_dbg_level & WL_DBG_CONN) {			\
+-		if (net_ratelimit()) {				\
+-			printk(KERN_ERR "CONN @%s : " fmt,	\
+-				__func__, ##args);		\
+-		}						\
+-	}							\
+-} while (0)
+-
+-#else /* (defined BCMDBG) */
+-#define	WL_INFO(fmt, args...)
+-#define	WL_TRACE(fmt, args...)
+-#define	WL_SCAN(fmt, args...)
+-#define	WL_CONN(fmt, args...)
+-#endif /* (defined BCMDBG) */
+-
+-
+-#define WL_SCAN_RETRY_MAX	3	/* used for ibss scan */
+-#define WL_NUM_SCAN_MAX		1
+-#define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
+-						 * for 2.6.33 kernel
+-						 * or later
+-						 */
+-#define WL_SCAN_BUF_MAX 		(1024 * 8)
+-#define WL_TLV_INFO_MAX 		1024
+-#define WL_BSS_INFO_MAX			2048
+-#define WL_ASSOC_INFO_MAX	512	/*
+-				 * needs to grab assoc info from dongle to
+-				 * report it to cfg80211 through "connect"
+-				 * event
+-				 */
+-#define WL_IOCTL_LEN_MAX	1024
+-#define WL_EXTRA_BUF_MAX	2048
+-#define WL_ISCAN_BUF_MAX	2048	/*
+-				 * the buf lengh can be WLC_IOCTL_MAXLEN (8K)
+-				 * to reduce iteration
+-				 */
+-#define WL_ISCAN_TIMER_INTERVAL_MS	3000
+-#define WL_SCAN_ERSULTS_LAST 	(WL_SCAN_RESULTS_NO_MEM+1)
+-#define WL_AP_MAX	256	/* virtually unlimitted as long
+-				 * as kernel memory allows
+-				 */
+-#define WL_FILE_NAME_MAX		256
+-
+-#define WL_ROAM_TRIGGER_LEVEL		-75
+-#define WL_ROAM_DELTA			20
+-#define WL_BEACON_TIMEOUT		3
+-
+-#define WL_SCAN_CHANNEL_TIME		40
+-#define WL_SCAN_UNASSOC_TIME		40
+-#define WL_SCAN_PASSIVE_TIME		120
+-
+-/* dongle status */
+-enum wl_status {
+-	WL_STATUS_READY,
+-	WL_STATUS_SCANNING,
+-	WL_STATUS_SCAN_ABORTING,
+-	WL_STATUS_CONNECTING,
+-	WL_STATUS_CONNECTED
+-};
+-
+-/* wi-fi mode */
+-enum wl_mode {
+-	WL_MODE_BSS,
+-	WL_MODE_IBSS,
+-	WL_MODE_AP
+-};
+-
+-/* dongle profile list */
+-enum wl_prof_list {
+-	WL_PROF_MODE,
+-	WL_PROF_SSID,
+-	WL_PROF_SEC,
+-	WL_PROF_IBSS,
+-	WL_PROF_BAND,
+-	WL_PROF_BSSID,
+-	WL_PROF_ACT,
+-	WL_PROF_BEACONINT,
+-	WL_PROF_DTIMPERIOD
+-};
+-
+-/* dongle iscan state */
+-enum wl_iscan_state {
+-	WL_ISCAN_STATE_IDLE,
+-	WL_ISCAN_STATE_SCANING
+-};
+-
+-/* fw downloading status */
+-enum wl_fw_status {
+-	WL_FW_LOADING_DONE,
+-	WL_NVRAM_LOADING_DONE
+-};
+-
+-/* beacon / probe_response */
+-struct beacon_proberesp {
+-	__le64 timestamp;
+-	__le16 beacon_int;
+-	__le16 capab_info;
+-	u8 variable[0];
+-} __attribute__ ((packed));
+-
+-/* dongle configuration */
+-struct wl_conf {
+-	u32 mode;		/* adhoc , infrastructure or ap */
+-	u32 frag_threshold;
+-	u32 rts_threshold;
+-	u32 retry_short;
+-	u32 retry_long;
+-	s32 tx_power;
+-	struct ieee80211_channel channel;
+-};
+-
+-/* cfg80211 main event loop */
+-struct wl_event_loop {
+-	s32(*handler[WLC_E_LAST]) (struct wl_priv *wl,
+-				     struct net_device *ndev,
+-				     const wl_event_msg_t *e, void *data);
+-};
+-
+-/* representing interface of cfg80211 plane */
+-struct wl_iface {
+-	struct wl_priv *wl;
+-};
+-
+-struct wl_dev {
+-	void *driver_data;	/* to store cfg80211 object information */
+-};
+-
+-/* bss inform structure for cfg80211 interface */
+-struct wl_cfg80211_bss_info {
+-	u16 band;
+-	u16 channel;
+-	s16 rssi;
+-	u16 frame_len;
+-	u8 frame_buf[1];
+-};
+-
+-/* basic structure of scan request */
+-struct wl_scan_req {
+-	struct wlc_ssid ssid;
+-};
+-
+-/* basic structure of information element */
+-struct wl_ie {
+-	u16 offset;
+-	u8 buf[WL_TLV_INFO_MAX];
+-};
+-
+-/* event queue for cfg80211 main event */
+-struct wl_event_q {
+-	struct list_head eq_list;
+-	u32 etype;
+-	wl_event_msg_t emsg;
+-	s8 edata[1];
+-};
+-
+-/* security information with currently associated ap */
+-struct wl_security {
+-	u32 wpa_versions;
+-	u32 auth_type;
+-	u32 cipher_pairwise;
+-	u32 cipher_group;
+-	u32 wpa_auth;
+-};
+-
+-/* ibss information for currently joined ibss network */
+-struct wl_ibss {
+-	u8 beacon_interval;	/* in millisecond */
+-	u8 atim;		/* in millisecond */
+-	s8 join_only;
+-	u8 band;
+-	u8 channel;
+-};
+-
+-/* dongle profile */
+-struct wl_profile {
+-	u32 mode;
+-	struct wlc_ssid ssid;
+-	u8 bssid[ETH_ALEN];
+-	u16 beacon_interval;
+-	u8 dtim_period;
+-	struct wl_security sec;
+-	struct wl_ibss ibss;
+-	s32 band;
+-};
+-
+-/* dongle iscan event loop */
+-struct wl_iscan_eloop {
+-	s32(*handler[WL_SCAN_ERSULTS_LAST]) (struct wl_priv *wl);
+-};
+-
+-/* dongle iscan controller */
+-struct wl_iscan_ctrl {
+-	struct net_device *dev;
+-	struct timer_list timer;
+-	u32 timer_ms;
+-	u32 timer_on;
+-	s32 state;
+-	struct task_struct *tsk;
+-	struct semaphore sync;
+-	struct wl_iscan_eloop el;
+-	void *data;
+-	s8 ioctl_buf[WLC_IOCTL_SMLEN];
+-	s8 scan_buf[WL_ISCAN_BUF_MAX];
+-};
+-
+-/* association inform */
+-struct wl_connect_info {
+-	u8 *req_ie;
+-	s32 req_ie_len;
+-	u8 *resp_ie;
+-	s32 resp_ie_len;
+-};
+-
+-/* firmware /nvram downloading controller */
+-struct wl_fw_ctrl {
+-	const struct firmware *fw_entry;
+-	unsigned long status;
+-	u32 ptr;
+-	s8 fw_name[WL_FILE_NAME_MAX];
+-	s8 nvram_name[WL_FILE_NAME_MAX];
+-};
+-
+-/* assoc ie length */
+-struct wl_assoc_ielen {
+-	u32 req_len;
+-	u32 resp_len;
+-};
+-
+-/* wpa2 pmk list */
+-struct wl_pmk_list {
+-	pmkid_list_t pmkids;
+-	pmkid_t foo[MAXPMKID - 1];
+-};
+-
+-/* dongle private data of cfg80211 interface */
+-struct wl_priv {
+-	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
+-	struct wl_conf *conf;	/* dongle configuration */
+-	struct cfg80211_scan_request *scan_request;	/* scan request
+-							 object */
+-	struct wl_event_loop el;	/* main event loop */
+-	struct list_head eq_list;	/* used for event queue */
+-	spinlock_t eq_lock;	/* for event queue synchronization */
+-	struct mutex usr_sync;	/* maily for dongle up/down synchronization */
+-	struct wl_scan_results *bss_list;	/* bss_list holding scanned
+-						 ap information */
+-	struct wl_scan_results *scan_results;
+-	struct wl_scan_req *scan_req_int;	/* scan request object for
+-						 internal purpose */
+-	struct wl_cfg80211_bss_info *bss_info;	/* bss information for
+-						 cfg80211 layer */
+-	struct wl_ie ie;	/* information element object for
+-					 internal purpose */
+-	struct semaphore event_sync;	/* for synchronization of main event
+-					 thread */
+-	struct wl_profile *profile;	/* holding dongle profile */
+-	struct wl_iscan_ctrl *iscan;	/* iscan controller */
+-	struct wl_connect_info conn_info;	/* association information
+-						 container */
+-	struct wl_fw_ctrl *fw;	/* control firwmare / nvram paramter
+-				 downloading */
+-	struct wl_pmk_list *pmk_list;	/* wpa2 pmk list */
+-	struct task_struct *event_tsk;	/* task of main event handler thread */
+-	unsigned long status;		/* current dongle status */
+-	void *pub;
+-	u32 channel;		/* current channel */
+-	bool iscan_on;		/* iscan on/off switch */
+-	bool iscan_kickstart;	/* indicate iscan already started */
+-	bool active_scan;	/* current scan mode */
+-	bool ibss_starter;	/* indicates this sta is ibss starter */
+-	bool link_up;		/* link/connection up flag */
+-	bool pwr_save;		/* indicate whether dongle to support
+-					 power save mode */
+-	bool dongle_up;		/* indicate whether dongle up or not */
+-	bool roam_on;		/* on/off switch for dongle self-roaming */
+-	bool scan_tried;	/* indicates if first scan attempted */
+-	u8 *ioctl_buf;	/* ioctl buffer */
+-	u8 *extra_buf;	/* maily to grab assoc information */
+-	struct dentry *debugfsdir;
+-	u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
+-};
+-
+-#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
+-#define wl_to_wiphy(w) (w->wdev->wiphy)
+-#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w)))
+-#define wl_to_wdev(w) (w->wdev)
+-#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w)))
+-#define wl_to_ndev(w) (w->wdev->netdev)
+-#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
+-#define ci_to_wl(c) (ci->wl)
+-#define wl_to_ci(w) (&w->ci)
+-#define wl_to_sr(w) (w->scan_req_int)
+-#define wl_to_ie(w) (&w->ie)
+-#define iscan_to_wl(i) ((struct wl_priv *)(i->data))
+-#define wl_to_iscan(w) (w->iscan)
+-#define wl_to_conn(w) (&w->conn_info)
+-
+-static inline struct wl_bss_info *next_bss(struct wl_scan_results *list,
+-					   struct wl_bss_info *bss)
+-{
+-	return bss = bss ?
+-		(struct wl_bss_info *)((unsigned long)bss +
+-				       le32_to_cpu(bss->length)) :
+-		list->bss_info;
+-}
+-
+-#define for_each_bss(list, bss, __i)	\
+-	for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
+-
+-extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data);
+-extern void wl_cfg80211_detach(void);
+-/* event handler from dongle */
+-extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
+-			      void *data);
+-extern void wl_cfg80211_sdio_func(void *func);	/* set sdio function info */
+-extern struct sdio_func *wl_cfg80211_get_sdio_func(void);	/* set sdio function info */
+-extern s32 wl_cfg80211_up(void);	/* dongle up */
+-extern s32 wl_cfg80211_down(void);	/* dongle down */
+-extern void wl_cfg80211_dbg_level(u32 level);	/* set dongle
+-							 debugging level */
+-extern void *wl_cfg80211_request_fw(s8 *file_name);	/* request fw /nvram
+-							 downloading */
+-extern s32 wl_cfg80211_read_fw(s8 *buf, u32 size);	/* read fw
+-								 image */
+-extern void wl_cfg80211_release_fw(void);	/* release fw */
+-extern s8 *wl_cfg80211_get_fwname(void);	/* get firmware name for
+-						 the dongle */
+-extern s8 *wl_cfg80211_get_nvramname(void);	/* get nvram name for
+-						 the dongle */
+-extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick);
+-
+-#endif				/* _wl_cfg80211_h_ */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c
+deleted file mode 100644
+index 15e1b05..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c
++++ /dev/null
+@@ -1,3693 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kthread.h>
+-#include <linux/semaphore.h>
+-#include <bcmdefs.h>
+-#include <linux/netdevice.h>
+-#include <wlioctl.h>
+-
+-#include <bcmutils.h>
+-
+-#include <linux/if_arp.h>
+-#include <asm/uaccess.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-#include <dhdioctl.h>
+-#include <linux/ieee80211.h>
+-typedef const struct si_pub si_t;
+-#include <wlioctl.h>
+-
+-#include <dngl_stats.h>
+-#include <dhd.h>
+-
+-#define WL_ERROR(fmt, args...)	printk(fmt, ##args)
+-#define WL_TRACE(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_INFORM(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_WSEC(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_SCAN(fmt, args...)	no_printk(fmt, ##args)
+-
+-#include <wl_iw.h>
+-
+-#define IW_WSEC_ENABLED(wsec)	((wsec) & (WEP_ENABLED |	\
+-					 TKIP_ENABLED | AES_ENABLED))
+-
+-#include <linux/rtnetlink.h>
+-
+-#define WL_IW_USE_ISCAN  1
+-#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS  1
+-
+-bool g_set_essid_before_scan = true;
+-
+-#define WL_IW_IOCTL_CALL(func_call) \
+-	do {				\
+-		func_call;		\
+-	} while (0)
+-
+-static int g_onoff = G_WLAN_SET_ON;
+-wl_iw_extra_params_t g_wl_iw_params;
+-
+-extern bool wl_iw_conn_status_str(u32 event_type, u32 status,
+-				  u32 reason, char *stringBuf, uint buflen);
+-
+-#define MAX_WLIW_IOCTL_LEN 1024
+-
+-#ifdef CONFIG_WIRELESS_EXT
+-extern int dhd_wait_pend8021x(struct net_device *dev);
+-#endif
+-
+-#if WIRELESS_EXT < 19
+-#define IW_IOCTL_IDX(cmd)	((cmd) - SIOCIWFIRST)
+-#define IW_EVENT_IDX(cmd)	((cmd) - IWEVFIRST)
+-#endif
+-
+-static void *g_scan;
+-static volatile uint g_scan_specified_ssid;
+-static wlc_ssid_t g_specific_ssid;
+-
+-static wlc_ssid_t g_ssid;
+-
+-#if defined(WL_IW_USE_ISCAN)
+-#define ISCAN_STATE_IDLE   0
+-#define ISCAN_STATE_SCANING 1
+-
+-#define WLC_IW_ISCAN_MAXLEN   2048
+-typedef struct iscan_buf {
+-	struct iscan_buf *next;
+-	char iscan_buf[WLC_IW_ISCAN_MAXLEN];
+-} iscan_buf_t;
+-
+-typedef struct iscan_info {
+-	struct net_device *dev;
+-	struct timer_list timer;
+-	u32 timer_ms;
+-	u32 timer_on;
+-	int iscan_state;
+-	iscan_buf_t *list_hdr;
+-	iscan_buf_t *list_cur;
+-
+-	struct task_struct *sysioc_tsk;
+-	struct semaphore sysioc_sem;
+-
+-#if defined CSCAN
+-	char ioctlbuf[WLC_IOCTL_MEDLEN];
+-#else
+-	char ioctlbuf[WLC_IOCTL_SMLEN];
+-#endif
+-	wl_iscan_params_t *iscan_ex_params_p;
+-	int iscan_ex_param_size;
+-} iscan_info_t;
+-iscan_info_t *g_iscan;
+-
+-static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-
+-/* Global ASSERT type flag */
+-u32 g_assert_type;
+-
+-static void wl_iw_timerfunc(unsigned long data);
+-static void wl_iw_set_event_mask(struct net_device *dev);
+-static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action);
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-static int
+-wl_iw_set_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       union iwreq_data *wrqu, char *extra);
+-
+-static int
+-wl_iw_get_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       struct iw_point *dwrq, char *extra);
+-
+-static uint
+-wl_iw_get_scan_prep(wl_scan_results_t *list,
+-		    struct iw_request_info *info, char *extra, short max_size);
+-
+-static void swap_key_from_BE(wl_wsec_key_t *key)
+-{
+-	key->index = cpu_to_le32(key->index);
+-	key->len = cpu_to_le32(key->len);
+-	key->algo = cpu_to_le32(key->algo);
+-	key->flags = cpu_to_le32(key->flags);
+-	key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
+-	key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
+-	key->iv_initialized = cpu_to_le32(key->iv_initialized);
+-}
+-
+-static void swap_key_to_BE(wl_wsec_key_t *key)
+-{
+-	key->index = le32_to_cpu(key->index);
+-	key->len = le32_to_cpu(key->len);
+-	key->algo = le32_to_cpu(key->algo);
+-	key->flags = le32_to_cpu(key->flags);
+-	key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
+-	key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
+-	key->iv_initialized = le32_to_cpu(key->iv_initialized);
+-}
+-
+-static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len)
+-{
+-	struct ifreq ifr;
+-	wl_ioctl_t ioc;
+-	mm_segment_t fs;
+-	int ret = -EINVAL;
+-
+-	if (!dev) {
+-		WL_ERROR("%s: dev is null\n", __func__);
+-		return ret;
+-	}
+-
+-	WL_INFORM("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n",
+-		  __func__, current->pid, cmd, arg, len);
+-
+-	if (g_onoff == G_WLAN_SET_ON) {
+-		memset(&ioc, 0, sizeof(ioc));
+-		ioc.cmd = cmd;
+-		ioc.buf = arg;
+-		ioc.len = len;
+-
+-		strcpy(ifr.ifr_name, dev->name);
+-		ifr.ifr_data = (caddr_t)&ioc;
+-
+-		ret = dev_open(dev);
+-		if (ret) {
+-			WL_ERROR("%s: Error dev_open: %d\n", __func__, ret);
+-			return ret;
+-		}
+-
+-		fs = get_fs();
+-		set_fs(get_ds());
+-		ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+-		set_fs(fs);
+-	} else {
+-		WL_TRACE("%s: call after driver stop : ignored\n", __func__);
+-	}
+-	return ret;
+-}
+-
+-static int dev_wlc_intvar_set(struct net_device *dev, char *name, int val)
+-{
+-	char buf[WLC_IOCTL_SMLEN];
+-	uint len;
+-
+-	val = cpu_to_le32(val);
+-	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
+-	ASSERT(len);
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len);
+-}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-static int
+-dev_iw_iovar_setbuf(struct net_device *dev,
+-		    char *iovar,
+-		    void *param, int paramlen, void *bufptr, int buflen)
+-{
+-	int iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	ASSERT(iolen);
+-
+-	if (iolen == 0)
+-		return 0;
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
+-}
+-
+-static int
+-dev_iw_iovar_getbuf(struct net_device *dev,
+-		    char *iovar,
+-		    void *param, int paramlen, void *bufptr, int buflen)
+-{
+-	int iolen;
+-
+-	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
+-	ASSERT(iolen);
+-
+-	return dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
+-}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-#if WIRELESS_EXT > 17
+-static int
+-dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
+-{
+-	static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
+-	uint buflen;
+-
+-	buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf));
+-	ASSERT(buflen);
+-
+-	return dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen);
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-dev_wlc_bufvar_get(struct net_device *dev, char *name, char *buf, int buflen)
+-{
+-	static char ioctlbuf[MAX_WLIW_IOCTL_LEN];
+-	int error;
+-	uint len;
+-
+-	len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf));
+-	ASSERT(len);
+-	error =
+-	    dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf,
+-			  MAX_WLIW_IOCTL_LEN);
+-	if (!error)
+-		memcpy(buf, ioctlbuf, buflen);
+-
+-	return error;
+-}
+-
+-static int dev_wlc_intvar_get(struct net_device *dev, char *name, int *retval)
+-{
+-	union {
+-		char buf[WLC_IOCTL_SMLEN];
+-		int val;
+-	} var;
+-	int error;
+-
+-	uint len;
+-	uint data_null;
+-
+-	len =
+-	    bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
+-			sizeof(var.buf));
+-	ASSERT(len);
+-	error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len);
+-
+-	*retval = le32_to_cpu(var.val);
+-
+-	return error;
+-}
+-
+-#if WIRELESS_EXT < 13
+-struct iw_request_info {
+-	__u16 cmd;
+-	__u16 flags;
+-};
+-
+-typedef int (*iw_handler) (struct net_device *dev,
+-			   struct iw_request_info *info,
+-			   void *wrqu, char *extra);
+-#endif
+-
+-static int
+-wl_iw_config_commit(struct net_device *dev,
+-		    struct iw_request_info *info, void *zwrq, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	int error;
+-	struct sockaddr bssid;
+-
+-	WL_TRACE("%s: SIOCSIWCOMMIT\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
+-	if (error)
+-		return error;
+-
+-	ssid.SSID_len = le32_to_cpu(ssid.SSID_len);
+-
+-	if (!ssid.SSID_len)
+-		return 0;
+-
+-	memset(&bssid, 0, sizeof(struct sockaddr));
+-	error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN);
+-	if (error) {
+-		WL_ERROR("%s: WLC_REASSOC to %s failed\n",
+-			 __func__, ssid.SSID);
+-		return error;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_name(struct net_device *dev,
+-	       struct iw_request_info *info, char *cwrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWNAME\n", dev->name);
+-
+-	strcpy(cwrq, "IEEE 802.11-DS");
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_freq(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_freq *fwrq, char *extra)
+-{
+-	int error, chan;
+-	uint sf = 0;
+-
+-	WL_TRACE("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name);
+-
+-	if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) {
+-		chan = fwrq->m;
+-	} else {
+-		if (fwrq->e >= 6) {
+-			fwrq->e -= 6;
+-			while (fwrq->e--)
+-				fwrq->m *= 10;
+-		} else if (fwrq->e < 6) {
+-			while (fwrq->e++ < 6)
+-				fwrq->m /= 10;
+-		}
+-		if (fwrq->m > 4000 && fwrq->m < 5000)
+-			sf = WF_CHAN_FACTOR_4_G;
+-
+-		chan = bcm_mhz2channel(fwrq->m, sf);
+-	}
+-	chan = cpu_to_le32(chan);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan));
+-	if (error)
+-		return error;
+-
+-	g_wl_iw_params.target_channel = chan;
+-	return -EINPROGRESS;
+-}
+-
+-static int
+-wl_iw_get_freq(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_freq *fwrq, char *extra)
+-{
+-	channel_info_t ci;
+-	int error;
+-
+-	WL_TRACE("%s: SIOCGIWFREQ\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci));
+-	if (error)
+-		return error;
+-
+-	fwrq->m = le32_to_cpu(ci.hw_channel);
+-	fwrq->e = le32_to_cpu(0);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_mode(struct net_device *dev,
+-	       struct iw_request_info *info, __u32 *uwrq, char *extra)
+-{
+-	int infra = 0, ap = 0, error = 0;
+-
+-	WL_TRACE("%s: SIOCSIWMODE\n", dev->name);
+-
+-	switch (*uwrq) {
+-	case IW_MODE_MASTER:
+-		infra = ap = 1;
+-		break;
+-	case IW_MODE_ADHOC:
+-	case IW_MODE_AUTO:
+-		break;
+-	case IW_MODE_INFRA:
+-		infra = 1;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-	infra = cpu_to_le32(infra);
+-	ap = cpu_to_le32(ap);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap));
+-	if (error)
+-		return error;
+-
+-	return -EINPROGRESS;
+-}
+-
+-static int
+-wl_iw_get_mode(struct net_device *dev,
+-	       struct iw_request_info *info, __u32 *uwrq, char *extra)
+-{
+-	int error, infra = 0, ap = 0;
+-
+-	WL_TRACE("%s: SIOCGIWMODE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap));
+-	if (error)
+-		return error;
+-
+-	infra = le32_to_cpu(infra);
+-	ap = le32_to_cpu(ap);
+-	*uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_range(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	struct iw_range *range = (struct iw_range *)extra;
+-	wl_u32_list_t *list;
+-	wl_rateset_t rateset;
+-	s8 *channels;
+-	int error, i, k;
+-	uint ch;
+-
+-	int phytype;
+-	int bw_cap = 0, sgi_tx = 0, nmode = 0;
+-	channel_info_t ci;
+-	u8 nrate_list2copy = 0;
+-	u16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130},
+-	{14, 29, 43, 58, 87, 116, 130, 144},
+-	{27, 54, 81, 108, 162, 216, 243, 270},
+-	{30, 60, 90, 120, 180, 240, 270, 300}
+-	};
+-
+-	WL_TRACE("%s: SIOCGIWRANGE\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	channels = kmalloc((MAXCHANNEL + 1) * 4, GFP_KERNEL);
+-	if (!channels) {
+-		WL_ERROR("Could not alloc channels\n");
+-		return -ENOMEM;
+-	}
+-	list = (wl_u32_list_t *) channels;
+-
+-	dwrq->length = sizeof(struct iw_range);
+-	memset(range, 0, sizeof(*range));
+-
+-	list->count = cpu_to_le32(MAXCHANNEL);
+-	error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels,
+-				(MAXCHANNEL + 1) * 4);
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	for (i = 0; i < le32_to_cpu(list->count) && i < IW_MAX_FREQUENCIES;
+-	     i++) {
+-		range->freq[i].i = le32_to_cpu(list->element[i]);
+-
+-		ch = le32_to_cpu(list->element[i]);
+-		if (ch <= CH_MAX_2G_CHANNEL) {
+-			range->freq[i].m = ieee80211_dsss_chan_to_freq(ch);
+-		} else {
+-			range->freq[i].m = ieee80211_ofdm_chan_to_freq(
+-						WF_CHAN_FACTOR_5_G/2, ch);
+-		}
+-		range->freq[i].e = 6;
+-	}
+-	range->num_frequency = range->num_channels = i;
+-
+-	range->max_qual.qual = 5;
+-	range->max_qual.level = 0x100 - 200;
+-	range->max_qual.noise = 0x100 - 200;
+-	range->sensitivity = 65535;
+-
+-#if WIRELESS_EXT > 11
+-	range->avg_qual.qual = 3;
+-	range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD;
+-	range->avg_qual.noise = 0x100 - 75;
+-#endif
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-				sizeof(rateset));
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	rateset.count = le32_to_cpu(rateset.count);
+-	range->num_bitrates = rateset.count;
+-	for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++)
+-		range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000;
+-	dev_wlc_intvar_get(dev, "nmode", &nmode);
+-	dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype));
+-
+-	if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) {
+-		dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap);
+-		dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx);
+-		dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci,
+-			      sizeof(channel_info_t));
+-		ci.hw_channel = le32_to_cpu(ci.hw_channel);
+-
+-		if (bw_cap == 0 || (bw_cap == 2 && ci.hw_channel <= 14)) {
+-			if (sgi_tx == 0)
+-				nrate_list2copy = 0;
+-			else
+-				nrate_list2copy = 1;
+-		}
+-		if (bw_cap == 1 || (bw_cap == 2 && ci.hw_channel >= 36)) {
+-			if (sgi_tx == 0)
+-				nrate_list2copy = 2;
+-			else
+-				nrate_list2copy = 3;
+-		}
+-		range->num_bitrates += 8;
+-		for (k = 0; i < range->num_bitrates; k++, i++) {
+-			range->bitrate[i] =
+-			    (nrate_list[nrate_list2copy][k]) * 500000;
+-		}
+-	}
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i));
+-	if (error) {
+-		kfree(channels);
+-		return error;
+-	}
+-	i = le32_to_cpu(i);
+-	if (i == WLC_PHY_TYPE_A)
+-		range->throughput = 24000000;
+-	else
+-		range->throughput = 1500000;
+-
+-	range->min_rts = 0;
+-	range->max_rts = 2347;
+-	range->min_frag = 256;
+-	range->max_frag = 2346;
+-
+-	range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS;
+-	range->num_encoding_sizes = 4;
+-	range->encoding_size[0] = WLAN_KEY_LEN_WEP40;
+-	range->encoding_size[1] = WLAN_KEY_LEN_WEP104;
+-#if WIRELESS_EXT > 17
+-	range->encoding_size[2] = WLAN_KEY_LEN_TKIP;
+-#else
+-	range->encoding_size[2] = 0;
+-#endif
+-	range->encoding_size[3] = WLAN_KEY_LEN_AES_CMAC;
+-
+-	range->min_pmp = 0;
+-	range->max_pmp = 0;
+-	range->min_pmt = 0;
+-	range->max_pmt = 0;
+-	range->pmp_flags = 0;
+-	range->pm_capa = 0;
+-
+-	range->num_txpower = 2;
+-	range->txpower[0] = 1;
+-	range->txpower[1] = 255;
+-	range->txpower_capa = IW_TXPOW_MWATT;
+-
+-#if WIRELESS_EXT > 10
+-	range->we_version_compiled = WIRELESS_EXT;
+-	range->we_version_source = 19;
+-
+-	range->retry_capa = IW_RETRY_LIMIT;
+-	range->retry_flags = IW_RETRY_LIMIT;
+-	range->r_time_flags = 0;
+-	range->min_retry = 1;
+-	range->max_retry = 255;
+-	range->min_r_time = 0;
+-	range->max_r_time = 0;
+-#endif
+-
+-#if WIRELESS_EXT > 17
+-	range->enc_capa = IW_ENC_CAPA_WPA;
+-	range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
+-	range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
+-	range->enc_capa |= IW_ENC_CAPA_WPA2;
+-
+-	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE);
+-	IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND);
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-	kfree(channels);
+-
+-	return 0;
+-}
+-
+-static int rssi_to_qual(int rssi)
+-{
+-	if (rssi <= WL_IW_RSSI_NO_SIGNAL)
+-		return 0;
+-	else if (rssi <= WL_IW_RSSI_VERY_LOW)
+-		return 1;
+-	else if (rssi <= WL_IW_RSSI_LOW)
+-		return 2;
+-	else if (rssi <= WL_IW_RSSI_GOOD)
+-		return 3;
+-	else if (rssi <= WL_IW_RSSI_VERY_GOOD)
+-		return 4;
+-	else
+-		return 5;
+-}
+-
+-static int
+-wl_iw_set_spy(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	int i;
+-
+-	WL_TRACE("%s: SIOCSIWSPY\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length);
+-	for (i = 0; i < iw->spy_num; i++)
+-		memcpy(iw->spy_addr[i], addr[i].sa_data, ETH_ALEN);
+-	memset(iw->spy_qual, 0, sizeof(iw->spy_qual));
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_spy(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality *qual = (struct iw_quality *)&addr[iw->spy_num];
+-	int i;
+-
+-	WL_TRACE("%s: SIOCGIWSPY\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	dwrq->length = iw->spy_num;
+-	for (i = 0; i < iw->spy_num; i++) {
+-		memcpy(addr[i].sa_data, iw->spy_addr[i], ETH_ALEN);
+-		addr[i].sa_family = AF_UNIX;
+-		memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality));
+-		iw->spy_qual[i].updated = 0;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params,
+-		     int *join_params_size)
+-{
+-	chanspec_t chanspec = 0;
+-
+-	if (ch != 0) {
+-		join_params->params.chanspec_num = 1;
+-		join_params->params.chanspec_list[0] = ch;
+-
+-		if (join_params->params.chanspec_list[0])
+-			chanspec |= WL_CHANSPEC_BAND_2G;
+-		else
+-			chanspec |= WL_CHANSPEC_BAND_5G;
+-
+-		chanspec |= WL_CHANSPEC_BW_20;
+-		chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+-
+-		*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
+-		    join_params->params.chanspec_num * sizeof(chanspec_t);
+-
+-		join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
+-		join_params->params.chanspec_list[0] |= chanspec;
+-		join_params->params.chanspec_list[0] =
+-		    cpu_to_le16(join_params->params.chanspec_list[0]);
+-
+-		join_params->params.chanspec_num =
+-		    cpu_to_le32(join_params->params.chanspec_num);
+-
+-		WL_TRACE("%s  join_params->params.chanspec_list[0]= %X\n",
+-			 __func__, join_params->params.chanspec_list[0]);
+-	}
+-	return 1;
+-}
+-
+-static int
+-wl_iw_set_wap(struct net_device *dev,
+-	      struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	int error = -EINVAL;
+-	wl_join_params_t join_params;
+-	int join_params_size;
+-
+-	WL_TRACE("%s: SIOCSIWAP\n", dev->name);
+-
+-	if (awrq->sa_family != ARPHRD_ETHER) {
+-		WL_ERROR("Invalid Header...sa_family\n");
+-		return -EINVAL;
+-	}
+-
+-	if (is_broadcast_ether_addr(awrq->sa_data) ||
+-	    is_zero_ether_addr(awrq->sa_data)) {
+-		scb_val_t scbval;
+-		memset(&scbval, 0, sizeof(scb_val_t));
+-		(void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval,
+-				    sizeof(scb_val_t));
+-		return 0;
+-	}
+-
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-	memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN);
+-
+-	WL_TRACE("%s  target_channel=%d\n",
+-		 __func__, g_wl_iw_params.target_channel);
+-	wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params,
+-			     &join_params_size);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params,
+-				join_params_size);
+-	if (error) {
+-		WL_ERROR("%s Invalid ioctl data=%d\n", __func__, error);
+-	}
+-
+-	if (g_ssid.SSID_len) {
+-		WL_TRACE("%s: join SSID=%s BSSID=%pM ch=%d\n",
+-			 __func__, g_ssid.SSID, awrq->sa_data,
+-			 g_wl_iw_params.target_channel);
+-	}
+-
+-	memset(&g_ssid, 0, sizeof(g_ssid));
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_wap(struct net_device *dev,
+-	      struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWAP\n", dev->name);
+-
+-	awrq->sa_family = ARPHRD_ETHER;
+-	memset(awrq->sa_data, 0, ETH_ALEN);
+-
+-	(void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETH_ALEN);
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-static int
+-wl_iw_mlme(struct net_device *dev,
+-	   struct iw_request_info *info, struct sockaddr *awrq, char *extra)
+-{
+-	struct iw_mlme *mlme;
+-	scb_val_t scbval;
+-	int error = -EINVAL;
+-
+-	WL_TRACE("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name);
+-
+-	mlme = (struct iw_mlme *)extra;
+-	if (mlme == NULL) {
+-		WL_ERROR("Invalid ioctl data\n");
+-		return error;
+-	}
+-
+-	scbval.val = mlme->reason_code;
+-	memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN);
+-
+-	if (mlme->cmd == IW_MLME_DISASSOC) {
+-		scbval.val = cpu_to_le32(scbval.val);
+-		error =
+-		    dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval,
+-				  sizeof(scb_val_t));
+-	} else if (mlme->cmd == IW_MLME_DEAUTH) {
+-		scbval.val = cpu_to_le32(scbval.val);
+-		error =
+-		    dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON,
+-				  &scbval, sizeof(scb_val_t));
+-	} else {
+-		WL_ERROR("Invalid ioctl data\n");
+-		return error;
+-	}
+-
+-	return error;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-#ifndef WL_IW_USE_ISCAN
+-static int
+-wl_iw_get_aplist(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality qual[IW_MAX_AP];
+-	wl_bss_info_t *bi = NULL;
+-	int error, i;
+-	uint buflen = dwrq->length;
+-
+-	WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	list = kzalloc(buflen, GFP_KERNEL);
+-	if (!list)
+-		return -ENOMEM;
+-	list->buflen = cpu_to_le32(buflen);
+-	error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen);
+-	if (error) {
+-		WL_ERROR("%d: Scan results error %d\n", __LINE__, error);
+-		kfree(list);
+-		return error;
+-	}
+-	list->buflen = le32_to_cpu(list->buflen);
+-	list->version = le32_to_cpu(list->version);
+-	list->count = le32_to_cpu(list->count);
+-	if (list->version != WL_BSS_INFO_VERSION) {
+-		WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-			 __func__, list->version);
+-		kfree(list);
+-		return -EINVAL;
+-	}
+-
+-	for (i = 0, dwrq->length = 0;
+-	     i < list->count && dwrq->length < IW_MAX_AP; i++) {
+-		bi = bi ? (wl_bss_info_t *) ((unsigned long)bi +
+-					     le32_to_cpu(bi->length)) : list->
+-		    bss_info;
+-		ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-		       ((unsigned long)list + buflen));
+-
+-		if (!(le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS))
+-			continue;
+-
+-		memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN);
+-		addr[dwrq->length].sa_family = ARPHRD_ETHER;
+-		qual[dwrq->length].qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-		qual[dwrq->length].level = 0x100 + le16_to_cpu(bi->RSSI);
+-		qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+-
+-#if WIRELESS_EXT > 18
+-		qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+-#else
+-		qual[dwrq->length].updated = 7;
+-#endif
+-		dwrq->length++;
+-	}
+-
+-	kfree(list);
+-
+-	if (dwrq->length) {
+-		memcpy(&addr[dwrq->length], qual,
+-		       sizeof(struct iw_quality) * dwrq->length);
+-		dwrq->flags = 1;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-#ifdef WL_IW_USE_ISCAN
+-static int
+-wl_iw_iscan_get_aplist(struct net_device *dev,
+-		       struct iw_request_info *info,
+-		       struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	iscan_buf_t *buf;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	struct sockaddr *addr = (struct sockaddr *)extra;
+-	struct iw_quality qual[IW_MAX_AP];
+-	wl_bss_info_t *bi = NULL;
+-	int i;
+-
+-	WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk)) {
+-		WL_ERROR("%s error\n", __func__);
+-		return 0;
+-	}
+-
+-	buf = iscan->list_hdr;
+-	while (buf) {
+-		list = &((wl_iscan_results_t *) buf->iscan_buf)->results;
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return -EINVAL;
+-		}
+-
+-		bi = NULL;
+-		for (i = 0, dwrq->length = 0;
+-		     i < list->count && dwrq->length < IW_MAX_AP; i++) {
+-			bi = bi ? (wl_bss_info_t *) ((unsigned long)bi +
+-						     le32_to_cpu(bi->length)) :
+-			    list->bss_info;
+-			ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-			       ((unsigned long)list + WLC_IW_ISCAN_MAXLEN));
+-
+-			if (!(le16_to_cpu(bi->capability) &
+-			      WLAN_CAPABILITY_ESS))
+-				continue;
+-
+-			memcpy(addr[dwrq->length].sa_data, &bi->BSSID,
+-			       ETH_ALEN);
+-			addr[dwrq->length].sa_family = ARPHRD_ETHER;
+-			qual[dwrq->length].qual =
+-			    rssi_to_qual(le16_to_cpu(bi->RSSI));
+-			qual[dwrq->length].level = 0x100 +
+-							le16_to_cpu(bi->RSSI);
+-			qual[dwrq->length].noise = 0x100 + bi->phy_noise;
+-
+-#if WIRELESS_EXT > 18
+-			qual[dwrq->length].updated =
+-			    IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+-#else
+-			qual[dwrq->length].updated = 7;
+-#endif
+-
+-			dwrq->length++;
+-		}
+-		buf = buf->next;
+-	}
+-	if (dwrq->length) {
+-		memcpy(&addr[dwrq->length], qual,
+-		       sizeof(struct iw_quality) * dwrq->length);
+-		dwrq->flags = 1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid)
+-{
+-	int err = 0;
+-
+-	memcpy(params->bssid, ether_bcast, ETH_ALEN);
+-	params->bss_type = DOT11_BSSTYPE_ANY;
+-	params->scan_type = 0;
+-	params->nprobes = -1;
+-	params->active_time = -1;
+-	params->passive_time = -1;
+-	params->home_time = -1;
+-	params->channel_num = 0;
+-
+-	params->nprobes = cpu_to_le32(params->nprobes);
+-	params->active_time = cpu_to_le32(params->active_time);
+-	params->passive_time = cpu_to_le32(params->passive_time);
+-	params->home_time = cpu_to_le32(params->home_time);
+-	if (ssid && ssid->SSID_len)
+-		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+-
+-	return err;
+-}
+-
+-static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action)
+-{
+-	int err = 0;
+-
+-	iscan->iscan_ex_params_p->version = cpu_to_le32(ISCAN_REQ_VERSION);
+-	iscan->iscan_ex_params_p->action = cpu_to_le16(action);
+-	iscan->iscan_ex_params_p->scan_duration = cpu_to_le16(0);
+-
+-	WL_SCAN("%s : nprobes=%d\n",
+-		__func__, iscan->iscan_ex_params_p->params.nprobes);
+-	WL_SCAN("active_time=%d\n",
+-		 iscan->iscan_ex_params_p->params.active_time);
+-	WL_SCAN("passive_time=%d\n",
+-		 iscan->iscan_ex_params_p->params.passive_time);
+-	WL_SCAN("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time);
+-	WL_SCAN("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type);
+-	WL_SCAN("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type);
+-
+-	(void)dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p,
+-				  iscan->iscan_ex_param_size, iscan->ioctlbuf,
+-				  sizeof(iscan->ioctlbuf));
+-
+-	return err;
+-}
+-
+-static void wl_iw_timerfunc(unsigned long data)
+-{
+-	iscan_info_t *iscan = (iscan_info_t *) data;
+-	if (iscan) {
+-		iscan->timer_on = 0;
+-		if (iscan->iscan_state != ISCAN_STATE_IDLE) {
+-			WL_TRACE("timer trigger\n");
+-			up(&iscan->sysioc_sem);
+-		}
+-	}
+-}
+-
+-static void wl_iw_set_event_mask(struct net_device *dev)
+-{
+-	char eventmask[WL_EVENTING_MASK_LEN];
+-	char iovbuf[WL_EVENTING_MASK_LEN + 12];
+-
+-	dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf));
+-	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+-	setbit(eventmask, WLC_E_SCAN_COMPLETE);
+-	dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN,
+-			    iovbuf, sizeof(iovbuf));
+-}
+-
+-static u32 wl_iw_iscan_get(iscan_info_t *iscan)
+-{
+-	iscan_buf_t *buf;
+-	iscan_buf_t *ptr;
+-	wl_iscan_results_t *list_buf;
+-	wl_iscan_results_t list;
+-	wl_scan_results_t *results;
+-	u32 status;
+-	int res = 0;
+-
+-	MUTEX_LOCK_WL_SCAN_SET();
+-	if (iscan->list_cur) {
+-		buf = iscan->list_cur;
+-		iscan->list_cur = buf->next;
+-	} else {
+-		buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL);
+-		if (!buf) {
+-			WL_ERROR("%s can't alloc iscan_buf_t : going to abort current iscan\n",
+-				 __func__);
+-			MUTEX_UNLOCK_WL_SCAN_SET();
+-			return WL_SCAN_RESULTS_NO_MEM;
+-		}
+-		buf->next = NULL;
+-		if (!iscan->list_hdr)
+-			iscan->list_hdr = buf;
+-		else {
+-			ptr = iscan->list_hdr;
+-			while (ptr->next) {
+-				ptr = ptr->next;
+-			}
+-			ptr->next = buf;
+-		}
+-	}
+-	memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+-	list_buf = (wl_iscan_results_t *) buf->iscan_buf;
+-	results = &list_buf->results;
+-	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+-	results->version = 0;
+-	results->count = 0;
+-
+-	memset(&list, 0, sizeof(list));
+-	list.results.buflen = cpu_to_le32(WLC_IW_ISCAN_MAXLEN);
+-	res = dev_iw_iovar_getbuf(iscan->dev,
+-				  "iscanresults",
+-				  &list,
+-				  WL_ISCAN_RESULTS_FIXED_SIZE,
+-				  buf->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+-	if (res == 0) {
+-		results->buflen = le32_to_cpu(results->buflen);
+-		results->version = le32_to_cpu(results->version);
+-		results->count = le32_to_cpu(results->count);
+-		WL_TRACE("results->count = %d\n", results->count);
+-		WL_TRACE("results->buflen = %d\n", results->buflen);
+-		status = le32_to_cpu(list_buf->status);
+-	} else {
+-		WL_ERROR("%s returns error %d\n", __func__, res);
+-		status = WL_SCAN_RESULTS_NO_MEM;
+-	}
+-	MUTEX_UNLOCK_WL_SCAN_SET();
+-	return status;
+-}
+-
+-static void wl_iw_force_specific_scan(iscan_info_t *iscan)
+-{
+-	WL_TRACE("%s force Specific SCAN for %s\n",
+-		 __func__, g_specific_ssid.SSID);
+-	rtnl_lock();
+-
+-	(void)dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid,
+-			    sizeof(g_specific_ssid));
+-
+-	rtnl_unlock();
+-}
+-
+-static void wl_iw_send_scan_complete(iscan_info_t *iscan)
+-{
+-#ifndef SANDGATE2G
+-	union iwreq_data wrqu;
+-
+-	memset(&wrqu, 0, sizeof(wrqu));
+-
+-	wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL);
+-	WL_TRACE("Send Event ISCAN complete\n");
+-#endif
+-}
+-
+-static int _iscan_sysioc_thread(void *data)
+-{
+-	u32 status;
+-	iscan_info_t *iscan = (iscan_info_t *) data;
+-	static bool iscan_pass_abort = false;
+-
+-	allow_signal(SIGTERM);
+-	status = WL_SCAN_RESULTS_PARTIAL;
+-	while (down_interruptible(&iscan->sysioc_sem) == 0) {
+-		if (kthread_should_stop())
+-			break;
+-
+-		if (iscan->timer_on) {
+-			del_timer_sync(&iscan->timer);
+-			iscan->timer_on = 0;
+-		}
+-		rtnl_lock();
+-		status = wl_iw_iscan_get(iscan);
+-		rtnl_unlock();
+-		if (g_scan_specified_ssid && (iscan_pass_abort == true)) {
+-			WL_TRACE("%s Get results from specific scan status = %d\n",
+-				 __func__, status);
+-			wl_iw_send_scan_complete(iscan);
+-			iscan_pass_abort = false;
+-			status = -1;
+-		}
+-
+-		switch (status) {
+-		case WL_SCAN_RESULTS_PARTIAL:
+-			WL_TRACE("iscanresults incomplete\n");
+-			rtnl_lock();
+-			wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
+-			rtnl_unlock();
+-			mod_timer(&iscan->timer,
+-				  jiffies + iscan->timer_ms * HZ / 1000);
+-			iscan->timer_on = 1;
+-			break;
+-		case WL_SCAN_RESULTS_SUCCESS:
+-			WL_TRACE("iscanresults complete\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			wl_iw_send_scan_complete(iscan);
+-			break;
+-		case WL_SCAN_RESULTS_PENDING:
+-			WL_TRACE("iscanresults pending\n");
+-			mod_timer(&iscan->timer,
+-				  jiffies + iscan->timer_ms * HZ / 1000);
+-			iscan->timer_on = 1;
+-			break;
+-		case WL_SCAN_RESULTS_ABORTED:
+-			WL_TRACE("iscanresults aborted\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			if (g_scan_specified_ssid == 0)
+-				wl_iw_send_scan_complete(iscan);
+-			else {
+-				iscan_pass_abort = true;
+-				wl_iw_force_specific_scan(iscan);
+-			}
+-			break;
+-		case WL_SCAN_RESULTS_NO_MEM:
+-			WL_TRACE("iscanresults can't alloc memory: skip\n");
+-			iscan->iscan_state = ISCAN_STATE_IDLE;
+-			break;
+-		default:
+-			WL_TRACE("iscanresults returned unknown status %d\n",
+-				 status);
+-			break;
+-		}
+-	}
+-
+-	if (iscan->timer_on) {
+-		del_timer_sync(&iscan->timer);
+-		iscan->timer_on = 0;
+-	}
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-static int
+-wl_iw_set_scan(struct net_device *dev,
+-	       struct iw_request_info *info,
+-	       union iwreq_data *wrqu, char *extra)
+-{
+-	int error;
+-	WL_TRACE("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name);
+-
+-	g_set_essid_before_scan = false;
+-#if defined(CSCAN)
+-	WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__);
+-	return -EINVAL;
+-#endif
+-
+-	if (g_onoff == G_WLAN_SET_OFF)
+-		return 0;
+-
+-	memset(&g_specific_ssid, 0, sizeof(g_specific_ssid));
+-#ifndef WL_IW_USE_ISCAN
+-	g_scan_specified_ssid = 0;
+-#endif
+-
+-#if WIRELESS_EXT > 17
+-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+-		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+-			struct iw_scan_req *req = (struct iw_scan_req *)extra;
+-			if (g_scan_specified_ssid) {
+-				WL_TRACE("%s Specific SCAN is not done ignore scan for = %s\n",
+-					 __func__, req->essid);
+-				return -EBUSY;
+-			} else {
+-				g_specific_ssid.SSID_len = min_t(size_t,
+-						sizeof(g_specific_ssid.SSID),
+-						req->essid_len);
+-				memcpy(g_specific_ssid.SSID, req->essid,
+-				       g_specific_ssid.SSID_len);
+-				g_specific_ssid.SSID_len =
+-				    cpu_to_le32(g_specific_ssid.SSID_len);
+-				g_scan_specified_ssid = 1;
+-				WL_TRACE("### Specific scan ssid=%s len=%d\n",
+-					 g_specific_ssid.SSID,
+-					 g_specific_ssid.SSID_len);
+-			}
+-		}
+-	}
+-#endif				/* WIRELESS_EXT > 17 */
+-	error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid,
+-				sizeof(g_specific_ssid));
+-	if (error) {
+-		WL_TRACE("#### Set SCAN for %s failed with %d\n",
+-			 g_specific_ssid.SSID, error);
+-		g_scan_specified_ssid = 0;
+-		return -EBUSY;
+-	}
+-
+-	return 0;
+-}
+-
+-#ifdef WL_IW_USE_ISCAN
+-int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag)
+-{
+-	wlc_ssid_t ssid;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	if (flag)
+-		rtnl_lock();
+-
+-	wl_iw_set_event_mask(dev);
+-
+-	WL_TRACE("+++: Set Broadcast ISCAN\n");
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-	iscan->list_cur = iscan->list_hdr;
+-	iscan->iscan_state = ISCAN_STATE_SCANING;
+-
+-	memset(&iscan->iscan_ex_params_p->params, 0,
+-	       iscan->iscan_ex_param_size);
+-	wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid);
+-	wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+-
+-	if (flag)
+-		rtnl_unlock();
+-
+-	mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
+-
+-	iscan->timer_on = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_iscan_set_scan(struct net_device *dev,
+-		     struct iw_request_info *info,
+-		     union iwreq_data *wrqu, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	WL_TRACE("%s: SIOCSIWSCAN : ISCAN\n", dev->name);
+-
+-#if defined(CSCAN)
+-	WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__);
+-	return -EINVAL;
+-#endif
+-
+-	if (g_onoff == G_WLAN_SET_OFF) {
+-		WL_TRACE("%s: driver is not up yet after START\n", __func__);
+-		return 0;
+-	}
+-#ifdef PNO_SUPPORT
+-	if (dhd_dev_get_pno_status(dev)) {
+-		WL_ERROR("%s: Scan called when PNO is active\n", __func__);
+-	}
+-#endif
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk))
+-		return wl_iw_set_scan(dev, info, wrqu, extra);
+-
+-	if (g_scan_specified_ssid) {
+-		WL_TRACE("%s Specific SCAN already running ignoring BC scan\n",
+-			 __func__);
+-		return -EBUSY;
+-	}
+-
+-	memset(&ssid, 0, sizeof(ssid));
+-
+-#if WIRELESS_EXT > 17
+-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
+-		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+-			struct iw_scan_req *req = (struct iw_scan_req *)extra;
+-			ssid.SSID_len = min_t(size_t, sizeof(ssid.SSID),
+-						req->essid_len);
+-			memcpy(ssid.SSID, req->essid, ssid.SSID_len);
+-			ssid.SSID_len = cpu_to_le32(ssid.SSID_len);
+-		} else {
+-			g_scan_specified_ssid = 0;
+-
+-			if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+-				WL_TRACE("%s ISCAN already in progress\n",
+-					 __func__);
+-				return 0;
+-			}
+-		}
+-	}
+-#endif				/* WIRELESS_EXT > 17 */
+-	wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
+-
+-	return 0;
+-}
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-#if WIRELESS_EXT > 17
+-static bool ie_is_wpa_ie(u8 **wpaie, u8 **tlvs, int *tlvs_len)
+-{
+-
+-	u8 *ie = *wpaie;
+-
+-	if ((ie[1] >= 6) &&
+-	    !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) {
+-		return true;
+-	}
+-
+-	ie += ie[1] + 2;
+-	*tlvs_len -= (int)(ie - *tlvs);
+-	*tlvs = ie;
+-	return false;
+-}
+-
+-static bool ie_is_wps_ie(u8 **wpsie, u8 **tlvs, int *tlvs_len)
+-{
+-
+-	u8 *ie = *wpsie;
+-
+-	if ((ie[1] >= 4) &&
+-	    !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) {
+-		return true;
+-	}
+-
+-	ie += ie[1] + 2;
+-	*tlvs_len -= (int)(ie - *tlvs);
+-	*tlvs = ie;
+-	return false;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-wl_iw_handle_scanresults_ies(char **event_p, char *end,
+-			     struct iw_request_info *info, wl_bss_info_t *bi)
+-{
+-#if WIRELESS_EXT > 17
+-	struct iw_event iwe;
+-	char *event;
+-
+-	event = *event_p;
+-	if (bi->ie_length) {
+-		bcm_tlv_t *ie;
+-		u8 *ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-		int ptr_len = bi->ie_length;
+-
+-		ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID);
+-		if (ie) {
+-			iwe.cmd = IWEVGENIE;
+-			iwe.u.data.length = ie->len + 2;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 (char *)ie);
+-		}
+-		ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-
+-		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+-			if (ie_is_wps_ie(((u8 **)&ie), &ptr, &ptr_len)) {
+-				iwe.cmd = IWEVGENIE;
+-				iwe.u.data.length = ie->len + 2;
+-				event =
+-				    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-							 (char *)ie);
+-				break;
+-			}
+-		}
+-
+-		ptr = ((u8 *) bi) + sizeof(wl_bss_info_t);
+-		ptr_len = bi->ie_length;
+-		while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) {
+-			if (ie_is_wpa_ie(((u8 **)&ie), &ptr, &ptr_len)) {
+-				iwe.cmd = IWEVGENIE;
+-				iwe.u.data.length = ie->len + 2;
+-				event =
+-				    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-							 (char *)ie);
+-				break;
+-			}
+-		}
+-
+-		*event_p = event;
+-	}
+-#endif		/* WIRELESS_EXT > 17 */
+-	return 0;
+-}
+-
+-static uint
+-wl_iw_get_scan_prep(wl_scan_results_t *list,
+-		    struct iw_request_info *info, char *extra, short max_size)
+-{
+-	int i, j;
+-	struct iw_event iwe;
+-	wl_bss_info_t *bi = NULL;
+-	char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value;
+-	int ret = 0;
+-
+-	ASSERT(list);
+-
+-	for (i = 0; i < list->count && i < IW_MAX_AP; i++) {
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return ret;
+-		}
+-
+-		bi = bi ? (wl_bss_info_t *)((unsigned long)bi +
+-					     le32_to_cpu(bi->length)) : list->
+-		    bss_info;
+-
+-		WL_TRACE("%s : %s\n", __func__, bi->SSID);
+-
+-		iwe.cmd = SIOCGIWAP;
+-		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+-		memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETH_ALEN);
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_ADDR_LEN);
+-		iwe.u.data.length = le32_to_cpu(bi->SSID_len);
+-		iwe.cmd = SIOCGIWESSID;
+-		iwe.u.data.flags = 1;
+-		event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+-
+-		if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS |
+-		    WLAN_CAPABILITY_IBSS)) {
+-			iwe.cmd = SIOCGIWMODE;
+-			if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS)
+-				iwe.u.mode = IW_MODE_INFRA;
+-			else
+-				iwe.u.mode = IW_MODE_ADHOC;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_UINT_LEN);
+-		}
+-
+-		iwe.cmd = SIOCGIWFREQ;
+-
+-		if (CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL)
+-			iwe.u.freq.m = ieee80211_dsss_chan_to_freq(
+-						CHSPEC_CHANNEL(bi->chanspec));
+-		else
+-			iwe.u.freq.m = ieee80211_ofdm_chan_to_freq(
+-						WF_CHAN_FACTOR_5_G/2,
+-						CHSPEC_CHANNEL(bi->chanspec));
+-
+-		iwe.u.freq.e = 6;
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_FREQ_LEN);
+-
+-		iwe.cmd = IWEVQUAL;
+-		iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-		iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI);
+-		iwe.u.qual.noise = 0x100 + bi->phy_noise;
+-		event =
+-		    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-					 IW_EV_QUAL_LEN);
+-
+-		wl_iw_handle_scanresults_ies(&event, end, info, bi);
+-
+-		iwe.cmd = SIOCGIWENCODE;
+-		if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_PRIVACY)
+-			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+-		else
+-			iwe.u.data.flags = IW_ENCODE_DISABLED;
+-		iwe.u.data.length = 0;
+-		event =
+-		    IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+-
+-		if (bi->rateset.count) {
+-			if (((event - extra) +
+-				IW_EV_LCP_LEN) <= (unsigned long)end) {
+-				value = event + IW_EV_LCP_LEN;
+-				iwe.cmd = SIOCGIWRATE;
+-				iwe.u.bitrate.fixed = iwe.u.bitrate.disabled =
+-				    0;
+-				for (j = 0;
+-				     j < bi->rateset.count
+-				     && j < IW_MAX_BITRATES; j++) {
+-					iwe.u.bitrate.value =
+-					    (bi->rateset.rates[j] & 0x7f) *
+-					    500000;
+-					value =
+-					    IWE_STREAM_ADD_VALUE(info, event,
+-						 value, end, &iwe,
+-						 IW_EV_PARAM_LEN);
+-				}
+-				event = value;
+-			}
+-		}
+-	}
+-
+-	ret = event - extra;
+-	if (ret < 0) {
+-		WL_ERROR("==> Wrong size\n");
+-		ret = 0;
+-	}
+-	WL_TRACE("%s: size=%d bytes prepared\n",
+-		 __func__, (unsigned int)(event - extra));
+-	return (uint)ret;
+-}
+-
+-static int
+-wl_iw_get_scan(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	channel_info_t ci;
+-	wl_scan_results_t *list_merge;
+-	wl_scan_results_t *list = (wl_scan_results_t *) g_scan;
+-	int error;
+-	uint buflen_from_user = dwrq->length;
+-	uint len = G_SCAN_RESULTS;
+-	__u16 len_ret = 0;
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_info_t *iscan = g_iscan;
+-	iscan_buf_t *p_buf;
+-#endif
+-
+-	WL_TRACE("%s: buflen_from_user %d:\n", dev->name, buflen_from_user);
+-
+-	if (!extra) {
+-		WL_TRACE("%s: wl_iw_get_scan return -EINVAL\n", dev->name);
+-		return -EINVAL;
+-	}
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci));
+-	if (error)
+-		return error;
+-	ci.scan_channel = le32_to_cpu(ci.scan_channel);
+-	if (ci.scan_channel)
+-		return -EAGAIN;
+-
+-	if (g_scan_specified_ssid) {
+-		list = kmalloc(len, GFP_KERNEL);
+-		if (!list) {
+-			WL_TRACE("%s: wl_iw_get_scan return -ENOMEM\n",
+-				 dev->name);
+-			g_scan_specified_ssid = 0;
+-			return -ENOMEM;
+-		}
+-	}
+-
+-	memset(list, 0, len);
+-	list->buflen = cpu_to_le32(len);
+-	error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len);
+-	if (error) {
+-		WL_ERROR("%s: %s : Scan_results ERROR %d\n",
+-			 dev->name, __func__, error);
+-		dwrq->length = len;
+-		if (g_scan_specified_ssid) {
+-			g_scan_specified_ssid = 0;
+-			kfree(list);
+-		}
+-		return 0;
+-	}
+-	list->buflen = le32_to_cpu(list->buflen);
+-	list->version = le32_to_cpu(list->version);
+-	list->count = le32_to_cpu(list->count);
+-
+-	if (list->version != WL_BSS_INFO_VERSION) {
+-		WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-			 __func__, list->version);
+-		if (g_scan_specified_ssid) {
+-			g_scan_specified_ssid = 0;
+-			kfree(list);
+-		}
+-		return -EINVAL;
+-	}
+-
+-	if (g_scan_specified_ssid) {
+-		WL_TRACE("%s: Specified scan APs in the list =%d\n",
+-			 __func__, list->count);
+-		len_ret =
+-		    (__u16) wl_iw_get_scan_prep(list, info, extra,
+-						buflen_from_user);
+-		kfree(list);
+-
+-#if defined(WL_IW_USE_ISCAN)
+-		p_buf = iscan->list_hdr;
+-		while (p_buf != iscan->list_cur) {
+-			list_merge =
+-			    &((wl_iscan_results_t *) p_buf->iscan_buf)->results;
+-			WL_TRACE("%s: Bcast APs list=%d\n",
+-				 __func__, list_merge->count);
+-			if (list_merge->count > 0)
+-				len_ret +=
+-				    (__u16) wl_iw_get_scan_prep(list_merge,
+-					info, extra + len_ret,
+-					buflen_from_user - len_ret);
+-			p_buf = p_buf->next;
+-		}
+-#else
+-		list_merge = (wl_scan_results_t *) g_scan;
+-		WL_TRACE("%s: Bcast APs list=%d\n",
+-			 __func__, list_merge->count);
+-		if (list_merge->count > 0)
+-			len_ret +=
+-			    (__u16) wl_iw_get_scan_prep(list_merge, info,
+-							extra + len_ret,
+-							buflen_from_user -
+-							len_ret);
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-	} else {
+-		list = (wl_scan_results_t *) g_scan;
+-		len_ret =
+-		    (__u16) wl_iw_get_scan_prep(list, info, extra,
+-						buflen_from_user);
+-	}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-	g_scan_specified_ssid = 0;
+-#endif
+-	if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user)
+-		len = len_ret;
+-
+-	dwrq->length = len;
+-	dwrq->flags = 0;
+-
+-	WL_TRACE("%s return to WE %d bytes APs=%d\n",
+-		 __func__, dwrq->length, list->count);
+-	return 0;
+-}
+-
+-#if defined(WL_IW_USE_ISCAN)
+-static int
+-wl_iw_iscan_get_scan(struct net_device *dev,
+-		     struct iw_request_info *info,
+-		     struct iw_point *dwrq, char *extra)
+-{
+-	wl_scan_results_t *list;
+-	struct iw_event iwe;
+-	wl_bss_info_t *bi = NULL;
+-	int ii, j;
+-	int apcnt;
+-	char *event = extra, *end = extra + dwrq->length, *value;
+-	iscan_info_t *iscan = g_iscan;
+-	iscan_buf_t *p_buf;
+-	u32 counter = 0;
+-	u8 channel;
+-
+-	WL_TRACE("%s %s buflen_from_user %d:\n",
+-		 dev->name, __func__, dwrq->length);
+-
+-	if (!extra) {
+-		WL_TRACE("%s: INVALID SIOCGIWSCAN GET bad parameter\n",
+-			 dev->name);
+-		return -EINVAL;
+-	}
+-
+-	if ((!iscan) || (!iscan->sysioc_tsk)) {
+-		WL_ERROR("%ssysioc_tsk\n", __func__);
+-		return wl_iw_get_scan(dev, info, dwrq, extra);
+-	}
+-
+-	if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+-		WL_TRACE("%s: SIOCGIWSCAN GET still scanning\n", dev->name);
+-		return -EAGAIN;
+-	}
+-
+-	WL_TRACE("%s: SIOCGIWSCAN GET broadcast results\n", dev->name);
+-	apcnt = 0;
+-	p_buf = iscan->list_hdr;
+-	while (p_buf != iscan->list_cur) {
+-		list = &((wl_iscan_results_t *) p_buf->iscan_buf)->results;
+-
+-		counter += list->count;
+-
+-		if (list->version != WL_BSS_INFO_VERSION) {
+-			WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+-				 __func__, list->version);
+-			return -EINVAL;
+-		}
+-
+-		bi = NULL;
+-		for (ii = 0; ii < list->count && apcnt < IW_MAX_AP;
+-		     apcnt++, ii++) {
+-			bi = bi ? (wl_bss_info_t *)((unsigned long)bi +
+-						     le32_to_cpu(bi->length)) :
+-			    list->bss_info;
+-			ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <=
+-			       ((unsigned long)list + WLC_IW_ISCAN_MAXLEN));
+-
+-			if (event + ETH_ALEN + bi->SSID_len +
+-			    IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >=
+-			    end)
+-				return -E2BIG;
+-			iwe.cmd = SIOCGIWAP;
+-			iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+-			memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID,
+-			       ETH_ALEN);
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_ADDR_LEN);
+-
+-			iwe.u.data.length = le32_to_cpu(bi->SSID_len);
+-			iwe.cmd = SIOCGIWESSID;
+-			iwe.u.data.flags = 1;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 bi->SSID);
+-
+-			if (le16_to_cpu(bi->capability) &
+-			    (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+-				iwe.cmd = SIOCGIWMODE;
+-				if (le16_to_cpu(bi->capability) &
+-				    WLAN_CAPABILITY_ESS)
+-					iwe.u.mode = IW_MODE_INFRA;
+-				else
+-					iwe.u.mode = IW_MODE_ADHOC;
+-				event =
+-				    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-							 IW_EV_UINT_LEN);
+-			}
+-
+-			iwe.cmd = SIOCGIWFREQ;
+-			channel =
+-			    (bi->ctl_ch ==
+-			     0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
+-
+-			if (channel <= CH_MAX_2G_CHANNEL)
+-				iwe.u.freq.m =
+-					ieee80211_dsss_chan_to_freq(channel);
+-			else
+-				iwe.u.freq.m = ieee80211_ofdm_chan_to_freq(
+-							WF_CHAN_FACTOR_5_G/2,
+-							channel);
+-
+-			iwe.u.freq.e = 6;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_FREQ_LEN);
+-
+-			iwe.cmd = IWEVQUAL;
+-			iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI));
+-			iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI);
+-			iwe.u.qual.noise = 0x100 + bi->phy_noise;
+-			event =
+-			    IWE_STREAM_ADD_EVENT(info, event, end, &iwe,
+-						 IW_EV_QUAL_LEN);
+-
+-			wl_iw_handle_scanresults_ies(&event, end, info, bi);
+-
+-			iwe.cmd = SIOCGIWENCODE;
+-			if (le16_to_cpu(bi->capability) &
+-			    WLAN_CAPABILITY_PRIVACY)
+-				iwe.u.data.flags =
+-				    IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+-			else
+-				iwe.u.data.flags = IW_ENCODE_DISABLED;
+-			iwe.u.data.length = 0;
+-			event =
+-			    IWE_STREAM_ADD_POINT(info, event, end, &iwe,
+-						 (char *)event);
+-
+-			if (bi->rateset.count) {
+-				if (event + IW_MAX_BITRATES * IW_EV_PARAM_LEN >=
+-				    end)
+-					return -E2BIG;
+-
+-				value = event + IW_EV_LCP_LEN;
+-				iwe.cmd = SIOCGIWRATE;
+-				iwe.u.bitrate.fixed = iwe.u.bitrate.disabled =
+-				    0;
+-				for (j = 0;
+-				     j < bi->rateset.count
+-				     && j < IW_MAX_BITRATES; j++) {
+-					iwe.u.bitrate.value =
+-					    (bi->rateset.rates[j] & 0x7f) *
+-					    500000;
+-					value =
+-					    IWE_STREAM_ADD_VALUE(info, event,
+-						 value, end,
+-						 &iwe,
+-						 IW_EV_PARAM_LEN);
+-				}
+-				event = value;
+-			}
+-		}
+-		p_buf = p_buf->next;
+-	}
+-
+-	dwrq->length = event - extra;
+-	dwrq->flags = 0;
+-
+-	WL_TRACE("%s return to WE %d bytes APs=%d\n",
+-		 __func__, dwrq->length, counter);
+-
+-	if (!dwrq->length)
+-		return -EAGAIN;
+-
+-	return 0;
+-}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-static int
+-wl_iw_set_essid(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	int error;
+-	wl_join_params_t join_params;
+-	int join_params_size;
+-
+-	WL_TRACE("%s: SIOCSIWESSID\n", dev->name);
+-
+-	if (g_set_essid_before_scan)
+-		return -EAGAIN;
+-
+-	memset(&g_ssid, 0, sizeof(g_ssid));
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	if (dwrq->length && extra) {
+-#if WIRELESS_EXT > 20
+-		g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID),
+-					dwrq->length);
+-#else
+-		g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID),
+-					dwrq->length - 1);
+-#endif
+-		memcpy(g_ssid.SSID, extra, g_ssid.SSID_len);
+-	} else {
+-		g_ssid.SSID_len = 0;
+-	}
+-	g_ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-
+-	memset(&join_params, 0, sizeof(join_params));
+-	join_params_size = sizeof(join_params.ssid);
+-
+-	memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len);
+-	join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len);
+-	memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
+-
+-	wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params,
+-			     &join_params_size);
+-
+-	error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params,
+-				join_params_size);
+-	if (error)
+-		WL_ERROR("Invalid ioctl data=%d\n", error);
+-
+-	if (g_ssid.SSID_len) {
+-		WL_TRACE("%s: join SSID=%s ch=%d\n",
+-			 __func__, g_ssid.SSID, g_wl_iw_params.target_channel);
+-	}
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_essid(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_point *dwrq, char *extra)
+-{
+-	wlc_ssid_t ssid;
+-	int error;
+-
+-	WL_TRACE("%s: SIOCGIWESSID\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid));
+-	if (error) {
+-		WL_ERROR("Error getting the SSID\n");
+-		return error;
+-	}
+-
+-	ssid.SSID_len = le32_to_cpu(ssid.SSID_len);
+-
+-	memcpy(extra, ssid.SSID, ssid.SSID_len);
+-
+-	dwrq->length = ssid.SSID_len;
+-
+-	dwrq->flags = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_nick(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCSIWNICKN\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	if (dwrq->length > sizeof(iw->nickname))
+-		return -E2BIG;
+-
+-	memcpy(iw->nickname, extra, dwrq->length);
+-	iw->nickname[dwrq->length - 1] = '\0';
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_nick(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+-{
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCGIWNICKN\n", dev->name);
+-
+-	if (!extra)
+-		return -EINVAL;
+-
+-	strcpy(extra, iw->nickname);
+-	dwrq->length = strlen(extra) + 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_rate(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	wl_rateset_t rateset;
+-	int error, rate, i, error_bg, error_a;
+-
+-	WL_TRACE("%s: SIOCSIWRATE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
+-				sizeof(rateset));
+-	if (error)
+-		return error;
+-
+-	rateset.count = le32_to_cpu(rateset.count);
+-
+-	if (vwrq->value < 0)
+-		rate = rateset.rates[rateset.count - 1] & 0x7f;
+-	else if (vwrq->value < rateset.count)
+-		rate = rateset.rates[vwrq->value] & 0x7f;
+-	else
+-		rate = vwrq->value / 500000;
+-
+-	if (vwrq->fixed) {
+-		error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate);
+-		error_a = dev_wlc_intvar_set(dev, "a_rate", rate);
+-
+-		if (error_bg && error_a)
+-			return error_bg | error_a;
+-	} else {
+-		error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0);
+-		error_a = dev_wlc_intvar_set(dev, "a_rate", 0);
+-
+-		if (error_bg && error_a)
+-			return error_bg | error_a;
+-
+-		for (i = 0; i < rateset.count; i++)
+-			if ((rateset.rates[i] & 0x7f) > rate)
+-				break;
+-		rateset.count = cpu_to_le32(i);
+-
+-		error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset,
+-					sizeof(rateset));
+-		if (error)
+-			return error;
+-	}
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_rate(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rate;
+-
+-	WL_TRACE("%s: SIOCGIWRATE\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
+-	if (error)
+-		return error;
+-	rate = le32_to_cpu(rate);
+-	vwrq->value = rate * 500000;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_rts(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rts;
+-
+-	WL_TRACE("%s: SIOCSIWRTS\n", dev->name);
+-
+-	if (vwrq->disabled)
+-		rts = DOT11_DEFAULT_RTS_LEN;
+-	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN)
+-		return -EINVAL;
+-	else
+-		rts = vwrq->value;
+-
+-	error = dev_wlc_intvar_set(dev, "rtsthresh", rts);
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_rts(struct net_device *dev,
+-	      struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, rts;
+-
+-	WL_TRACE("%s: SIOCGIWRTS\n", dev->name);
+-
+-	error = dev_wlc_intvar_get(dev, "rtsthresh", &rts);
+-	if (error)
+-		return error;
+-
+-	vwrq->value = rts;
+-	vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN);
+-	vwrq->fixed = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_frag(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, frag;
+-
+-	WL_TRACE("%s: SIOCSIWFRAG\n", dev->name);
+-
+-	if (vwrq->disabled)
+-		frag = DOT11_DEFAULT_FRAG_LEN;
+-	else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN)
+-		return -EINVAL;
+-	else
+-		frag = vwrq->value;
+-
+-	error = dev_wlc_intvar_set(dev, "fragthresh", frag);
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_frag(struct net_device *dev,
+-	       struct iw_request_info *info, struct iw_param *vwrq, char *extra)
+-{
+-	int error, fragthreshold;
+-
+-	WL_TRACE("%s: SIOCGIWFRAG\n", dev->name);
+-
+-	error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold);
+-	if (error)
+-		return error;
+-
+-	vwrq->value = fragthreshold;
+-	vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN);
+-	vwrq->fixed = 1;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_txpow(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, disable;
+-	u16 txpwrmw;
+-	WL_TRACE("%s: SIOCSIWTXPOW\n", dev->name);
+-
+-	disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0;
+-	disable += WL_RADIO_SW_DISABLE << 16;
+-
+-	disable = cpu_to_le32(disable);
+-	error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable));
+-	if (error)
+-		return error;
+-
+-	if (disable & WL_RADIO_SW_DISABLE)
+-		return 0;
+-
+-	if (!(vwrq->flags & IW_TXPOW_MWATT))
+-		return -EINVAL;
+-
+-	if (vwrq->value < 0)
+-		return 0;
+-
+-	if (vwrq->value > 0xffff)
+-		txpwrmw = 0xffff;
+-	else
+-		txpwrmw = (u16) vwrq->value;
+-
+-	error =
+-	    dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw)));
+-	return error;
+-}
+-
+-static int
+-wl_iw_get_txpow(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, disable, txpwrdbm;
+-	u8 result;
+-
+-	WL_TRACE("%s: SIOCGIWTXPOW\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm);
+-	if (error)
+-		return error;
+-
+-	disable = le32_to_cpu(disable);
+-	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+-	vwrq->value = (s32) bcm_qdbm_to_mw(result);
+-	vwrq->fixed = 0;
+-	vwrq->disabled =
+-	    (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0;
+-	vwrq->flags = IW_TXPOW_MWATT;
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 10
+-static int
+-wl_iw_set_retry(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, lrl, srl;
+-
+-	WL_TRACE("%s: SIOCSIWRETRY\n", dev->name);
+-
+-	if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME))
+-		return -EINVAL;
+-
+-	if (vwrq->flags & IW_RETRY_LIMIT) {
+-
+-#if WIRELESS_EXT > 20
+-		if ((vwrq->flags & IW_RETRY_LONG)
+-		    || (vwrq->flags & IW_RETRY_MAX)
+-		    || !((vwrq->flags & IW_RETRY_SHORT)
+-			 || (vwrq->flags & IW_RETRY_MIN))) {
+-#else
+-		if ((vwrq->flags & IW_RETRY_MAX)
+-		    || !(vwrq->flags & IW_RETRY_MIN)) {
+-#endif
+-			lrl = cpu_to_le32(vwrq->value);
+-			error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl,
+-						sizeof(lrl));
+-			if (error)
+-				return error;
+-		}
+-#if WIRELESS_EXT > 20
+-		if ((vwrq->flags & IW_RETRY_SHORT)
+-		    || (vwrq->flags & IW_RETRY_MIN)
+-		    || !((vwrq->flags & IW_RETRY_LONG)
+-			 || (vwrq->flags & IW_RETRY_MAX))) {
+-#else
+-		if ((vwrq->flags & IW_RETRY_MIN)
+-		    || !(vwrq->flags & IW_RETRY_MAX)) {
+-#endif
+-			srl = cpu_to_le32(vwrq->value);
+-			error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl,
+-						sizeof(srl));
+-			if (error)
+-				return error;
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_retry(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, lrl, srl;
+-
+-	WL_TRACE("%s: SIOCGIWRETRY\n", dev->name);
+-
+-	vwrq->disabled = 0;
+-
+-	if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
+-		return -EINVAL;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl));
+-	if (error)
+-		return error;
+-
+-	lrl = le32_to_cpu(lrl);
+-	srl = le32_to_cpu(srl);
+-
+-	if (vwrq->flags & IW_RETRY_MAX) {
+-		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+-		vwrq->value = lrl;
+-	} else {
+-		vwrq->flags = IW_RETRY_LIMIT;
+-		vwrq->value = srl;
+-		if (srl != lrl)
+-			vwrq->flags |= IW_RETRY_MIN;
+-	}
+-
+-	return 0;
+-}
+-#endif				/* WIRELESS_EXT > 10 */
+-
+-static int
+-wl_iw_set_encode(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error, val, wsec;
+-
+-	WL_TRACE("%s: SIOCSIWENCODE\n", dev->name);
+-
+-	memset(&key, 0, sizeof(key));
+-
+-	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+-		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS;
+-		     key.index++) {
+-			val = cpu_to_le32(key.index);
+-			error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val,
+-						sizeof(val));
+-			if (error)
+-				return error;
+-			val = le32_to_cpu(val);
+-			if (val)
+-				break;
+-		}
+-		if (key.index == DOT11_MAX_DEFAULT_KEYS)
+-			key.index = 0;
+-	} else {
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-		if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-			return -EINVAL;
+-	}
+-
+-	if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) {
+-		val = cpu_to_le32(key.index);
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val,
+-					sizeof(val));
+-		if (error)
+-			return error;
+-	} else {
+-		key.len = dwrq->length;
+-
+-		if (dwrq->length > sizeof(key.data))
+-			return -EINVAL;
+-
+-		memcpy(key.data, extra, dwrq->length);
+-
+-		key.flags = WL_PRIMARY_KEY;
+-		switch (key.len) {
+-		case WLAN_KEY_LEN_WEP40:
+-			key.algo = CRYPTO_ALGO_WEP1;
+-			break;
+-		case WLAN_KEY_LEN_WEP104:
+-			key.algo = CRYPTO_ALGO_WEP128;
+-			break;
+-		case WLAN_KEY_LEN_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			break;
+-		case WLAN_KEY_LEN_AES_CMAC:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			break;
+-		default:
+-			return -EINVAL;
+-		}
+-
+-		swap_key_from_BE(&key);
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (error)
+-			return error;
+-	}
+-
+-	val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED;
+-
+-	error = dev_wlc_intvar_get(dev, "wsec", &wsec);
+-	if (error)
+-		return error;
+-
+-	wsec &= ~(WEP_ENABLED);
+-	wsec |= val;
+-
+-	error = dev_wlc_intvar_set(dev, "wsec", wsec);
+-	if (error)
+-		return error;
+-
+-	val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0;
+-	val = cpu_to_le32(val);
+-	error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_encode(struct net_device *dev,
+-		 struct iw_request_info *info,
+-		 struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error, val, wsec, auth;
+-
+-	WL_TRACE("%s: SIOCGIWENCODE\n", dev->name);
+-
+-	memset(&key, 0, sizeof(wl_wsec_key_t));
+-
+-	if ((dwrq->flags & IW_ENCODE_INDEX) == 0) {
+-		for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS;
+-		     key.index++) {
+-			val = key.index;
+-			error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val,
+-						sizeof(val));
+-			if (error)
+-				return error;
+-			val = le32_to_cpu(val);
+-			if (val)
+-				break;
+-		}
+-	} else
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-
+-	if (key.index >= DOT11_MAX_DEFAULT_KEYS)
+-		key.index = 0;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
+-	if (error)
+-		return error;
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth));
+-	if (error)
+-		return error;
+-
+-	swap_key_to_BE(&key);
+-
+-	wsec = le32_to_cpu(wsec);
+-	auth = le32_to_cpu(auth);
+-	dwrq->length = min_t(u16, WLAN_MAX_KEY_LEN, key.len);
+-
+-	dwrq->flags = key.index + 1;
+-	if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)))
+-		dwrq->flags |= IW_ENCODE_DISABLED;
+-
+-	if (auth)
+-		dwrq->flags |= IW_ENCODE_RESTRICTED;
+-
+-	if (dwrq->length && extra)
+-		memcpy(extra, key.data, dwrq->length);
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_power(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, pm;
+-
+-	WL_TRACE("%s: SIOCSIWPOWER\n", dev->name);
+-
+-	pm = vwrq->disabled ? PM_OFF : PM_MAX;
+-
+-	pm = cpu_to_le32(pm);
+-	error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
+-	if (error)
+-		return error;
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_power(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	int error, pm;
+-
+-	WL_TRACE("%s: SIOCGIWPOWER\n", dev->name);
+-
+-	error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm));
+-	if (error)
+-		return error;
+-
+-	pm = le32_to_cpu(pm);
+-	vwrq->disabled = pm ? 0 : 1;
+-	vwrq->flags = IW_POWER_ALL_R;
+-
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-static int
+-wl_iw_set_wpaie(struct net_device *dev,
+-		struct iw_request_info *info, struct iw_point *iwp, char *extra)
+-{
+-
+-	WL_TRACE("%s: SIOCSIWGENIE\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length);
+-
+-	return 0;
+-}
+-
+-static int
+-wl_iw_get_wpaie(struct net_device *dev,
+-		struct iw_request_info *info, struct iw_point *iwp, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWGENIE\n", dev->name);
+-	iwp->length = 64;
+-	dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_encodeext(struct net_device *dev,
+-		    struct iw_request_info *info,
+-		    struct iw_point *dwrq, char *extra)
+-{
+-	wl_wsec_key_t key;
+-	int error;
+-	struct iw_encode_ext *iwe;
+-
+-	WL_TRACE("%s: SIOCSIWENCODEEXT\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	memset(&key, 0, sizeof(key));
+-	iwe = (struct iw_encode_ext *)extra;
+-
+-	if (dwrq->flags & IW_ENCODE_DISABLED) {
+-
+-	}
+-
+-	key.index = 0;
+-	if (dwrq->flags & IW_ENCODE_INDEX)
+-		key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+-
+-	key.len = iwe->key_len;
+-
+-	if (!is_multicast_ether_addr(iwe->addr.sa_data))
+-		memcpy(&key.ea, &iwe->addr.sa_data, ETH_ALEN);
+-
+-	if (key.len == 0) {
+-		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+-			WL_WSEC("Changing the the primary Key to %d\n",
+-				key.index);
+-			key.index = cpu_to_le32(key.index);
+-			error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY,
+-					      &key.index, sizeof(key.index));
+-			if (error)
+-				return error;
+-		} else {
+-			swap_key_from_BE(&key);
+-			dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		}
+-	} else {
+-		if (iwe->key_len > sizeof(key.data))
+-			return -EINVAL;
+-
+-		WL_WSEC("Setting the key index %d\n", key.index);
+-		if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+-			WL_WSEC("key is a Primary Key\n");
+-			key.flags = WL_PRIMARY_KEY;
+-		}
+-
+-		memcpy(key.data, iwe->key, iwe->key_len);
+-
+-		if (iwe->alg == IW_ENCODE_ALG_TKIP) {
+-			u8 keybuf[8];
+-			memcpy(keybuf, &key.data[24], sizeof(keybuf));
+-			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+-			memcpy(&key.data[16], keybuf, sizeof(keybuf));
+-		}
+-
+-		if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+-			unsigned char *ivptr;
+-			ivptr = (unsigned char *) iwe->rx_seq;
+-			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
+-			    (ivptr[3] << 8) | ivptr[2];
+-			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
+-			key.iv_initialized = true;
+-		}
+-
+-		switch (iwe->alg) {
+-		case IW_ENCODE_ALG_NONE:
+-			key.algo = CRYPTO_ALGO_OFF;
+-			break;
+-		case IW_ENCODE_ALG_WEP:
+-			if (iwe->key_len == WLAN_KEY_LEN_WEP40)
+-				key.algo = CRYPTO_ALGO_WEP1;
+-			else
+-				key.algo = CRYPTO_ALGO_WEP128;
+-			break;
+-		case IW_ENCODE_ALG_TKIP:
+-			key.algo = CRYPTO_ALGO_TKIP;
+-			break;
+-		case IW_ENCODE_ALG_CCMP:
+-			key.algo = CRYPTO_ALGO_AES_CCM;
+-			break;
+-		default:
+-			break;
+-		}
+-		swap_key_from_BE(&key);
+-
+-		dhd_wait_pend8021x(dev);
+-
+-		error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
+-		if (error)
+-			return error;
+-	}
+-	return 0;
+-}
+-
+-#if WIRELESS_EXT > 17
+-struct {
+-	pmkid_list_t pmkids;
+-	pmkid_t foo[MAXPMKID - 1];
+-} pmkid_list;
+-
+-static int
+-wl_iw_set_pmksa(struct net_device *dev,
+-		struct iw_request_info *info,
+-		struct iw_param *vwrq, char *extra)
+-{
+-	struct iw_pmksa *iwpmksa;
+-	uint i;
+-	int ret = 0;
+-
+-	WL_WSEC("%s: SIOCSIWPMKSA\n", dev->name);
+-
+-	CHECK_EXTRA_FOR_NULL(extra);
+-
+-	iwpmksa = (struct iw_pmksa *)extra;
+-
+-	if (iwpmksa->cmd == IW_PMKSA_FLUSH) {
+-		WL_WSEC("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n");
+-		memset((char *)&pmkid_list, 0, sizeof(pmkid_list));
+-	}
+-
+-	else if (iwpmksa->cmd == IW_PMKSA_REMOVE) {
+-		{
+-			pmkid_list_t pmkid, *pmkidptr;
+-			uint j;
+-			pmkidptr = &pmkid;
+-
+-			memcpy(&pmkidptr->pmkid[0].BSSID,
+-			       &iwpmksa->bssid.sa_data[0],
+-			       ETH_ALEN);
+-			memcpy(&pmkidptr->pmkid[0].PMKID,
+-			       &iwpmksa->pmkid[0],
+-			       WLAN_PMKID_LEN);
+-
+-			WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: "
+-				"%pM = ", &pmkidptr->pmkid[0].BSSID);
+-			for (j = 0; j < WLAN_PMKID_LEN; j++)
+-				WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]);
+-			WL_WSEC("\n");
+-		}
+-
+-		for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+-			if (!memcmp
+-			    (&iwpmksa->bssid.sa_data[0],
+-			     &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN))
+-				break;
+-
+-		if ((pmkid_list.pmkids.npmkid > 0)
+-		    && (i < pmkid_list.pmkids.npmkid)) {
+-			memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t));
+-			for (; i < (pmkid_list.pmkids.npmkid - 1); i++) {
+-				memcpy(&pmkid_list.pmkids.pmkid[i].BSSID,
+-				       &pmkid_list.pmkids.pmkid[i + 1].BSSID,
+-				       ETH_ALEN);
+-				memcpy(&pmkid_list.pmkids.pmkid[i].PMKID,
+-				       &pmkid_list.pmkids.pmkid[i + 1].PMKID,
+-				       WLAN_PMKID_LEN);
+-			}
+-			pmkid_list.pmkids.npmkid--;
+-		} else
+-			ret = -EINVAL;
+-	}
+-
+-	else if (iwpmksa->cmd == IW_PMKSA_ADD) {
+-		for (i = 0; i < pmkid_list.pmkids.npmkid; i++)
+-			if (!memcmp
+-			    (&iwpmksa->bssid.sa_data[0],
+-			     &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN))
+-				break;
+-		if (i < MAXPMKID) {
+-			memcpy(&pmkid_list.pmkids.pmkid[i].BSSID,
+-			       &iwpmksa->bssid.sa_data[0],
+-			       ETH_ALEN);
+-			memcpy(&pmkid_list.pmkids.pmkid[i].PMKID,
+-			       &iwpmksa->pmkid[0],
+-			       WLAN_PMKID_LEN);
+-			if (i == pmkid_list.pmkids.npmkid)
+-				pmkid_list.pmkids.npmkid++;
+-		} else
+-			ret = -EINVAL;
+-		{
+-			uint j;
+-			uint k;
+-			k = pmkid_list.pmkids.npmkid;
+-			WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ",
+-				&pmkid_list.pmkids.pmkid[k].BSSID);
+-			for (j = 0; j < WLAN_PMKID_LEN; j++)
+-				WL_WSEC("%02x ",
+-					pmkid_list.pmkids.pmkid[k].PMKID[j]);
+-			WL_WSEC("\n");
+-		}
+-	}
+-	WL_WSEC("PRINTING pmkid LIST - No of elements %d\n",
+-		pmkid_list.pmkids.npmkid);
+-	for (i = 0; i < pmkid_list.pmkids.npmkid; i++) {
+-		uint j;
+-		WL_WSEC("PMKID[%d]: %pM = ",
+-			i, &pmkid_list.pmkids.pmkid[i].BSSID);
+-		for (j = 0; j < WLAN_PMKID_LEN; j++)
+-			WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]);
+-		WL_WSEC("\n");
+-	}
+-	WL_WSEC("\n");
+-
+-	if (!ret)
+-		ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list,
+-					 sizeof(pmkid_list));
+-	return ret;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static int
+-wl_iw_get_encodeext(struct net_device *dev,
+-		    struct iw_request_info *info,
+-		    struct iw_param *vwrq, char *extra)
+-{
+-	WL_TRACE("%s: SIOCGIWENCODEEXT\n", dev->name);
+-	return 0;
+-}
+-
+-static int
+-wl_iw_set_wpaauth(struct net_device *dev,
+-		  struct iw_request_info *info,
+-		  struct iw_param *vwrq, char *extra)
+-{
+-	int error = 0;
+-	int paramid;
+-	int paramval;
+-	int val = 0;
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCSIWAUTH\n", dev->name);
+-
+-	paramid = vwrq->flags & IW_AUTH_INDEX;
+-	paramval = vwrq->value;
+-
+-	WL_TRACE("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n",
+-		 dev->name, paramid, paramval);
+-
+-	switch (paramid) {
+-	case IW_AUTH_WPA_VERSION:
+-		if (paramval & IW_AUTH_WPA_VERSION_DISABLED)
+-			val = WPA_AUTH_DISABLED;
+-		else if (paramval & (IW_AUTH_WPA_VERSION_WPA))
+-			val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
+-		else if (paramval & IW_AUTH_WPA_VERSION_WPA2)
+-			val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
+-		WL_INFORM("%s: %d: setting wpa_auth to 0x%0x\n",
+-			  __func__, __LINE__, val);
+-		error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+-		if (error)
+-			return error;
+-		break;
+-	case IW_AUTH_CIPHER_PAIRWISE:
+-	case IW_AUTH_CIPHER_GROUP:
+-		if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+-			val = WEP_ENABLED;
+-		if (paramval & IW_AUTH_CIPHER_TKIP)
+-			val = TKIP_ENABLED;
+-		if (paramval & IW_AUTH_CIPHER_CCMP)
+-			val = AES_ENABLED;
+-
+-		if (paramid == IW_AUTH_CIPHER_PAIRWISE) {
+-			iw->pwsec = val;
+-			val |= iw->gwsec;
+-		} else {
+-			iw->gwsec = val;
+-			val |= iw->pwsec;
+-		}
+-
+-		if (iw->privacy_invoked && !val) {
+-			WL_WSEC("%s: %s: 'Privacy invoked' true but clearing wsec, assuming we're a WPS enrollee\n",
+-				dev->name, __func__);
+-			error = dev_wlc_intvar_set(dev, "is_WPS_enrollee",
+-							true);
+-			if (error) {
+-				WL_WSEC("Failed to set is_WPS_enrollee\n");
+-				return error;
+-			}
+-		} else if (val) {
+-			error = dev_wlc_intvar_set(dev, "is_WPS_enrollee",
+-							false);
+-			if (error) {
+-				WL_WSEC("Failed to clear is_WPS_enrollee\n");
+-				return error;
+-			}
+-		}
+-
+-		error = dev_wlc_intvar_set(dev, "wsec", val);
+-		if (error)
+-			return error;
+-
+-		break;
+-
+-	case IW_AUTH_KEY_MGMT:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-
+-		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
+-			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+-				val = WPA_AUTH_PSK;
+-			else
+-				val = WPA_AUTH_UNSPECIFIED;
+-		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
+-			if (paramval & IW_AUTH_KEY_MGMT_PSK)
+-				val = WPA2_AUTH_PSK;
+-			else
+-				val = WPA2_AUTH_UNSPECIFIED;
+-		}
+-		WL_INFORM("%s: %d: setting wpa_auth to %d\n",
+-			  __func__, __LINE__, val);
+-		error = dev_wlc_intvar_set(dev, "wpa_auth", val);
+-		if (error)
+-			return error;
+-
+-		break;
+-	case IW_AUTH_TKIP_COUNTERMEASURES:
+-		dev_wlc_bufvar_set(dev, "tkip_countermeasures",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_80211_AUTH_ALG:
+-		WL_INFORM("Setting the D11auth %d\n", paramval);
+-		if (paramval == IW_AUTH_ALG_OPEN_SYSTEM)
+-			val = 0;
+-		else if (paramval == IW_AUTH_ALG_SHARED_KEY)
+-			val = 1;
+-		else if (paramval ==
+-			 (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY))
+-			val = 2;
+-		else
+-			error = 1;
+-		if (!error) {
+-			error = dev_wlc_intvar_set(dev, "auth", val);
+-			if (error)
+-				return error;
+-		}
+-		break;
+-
+-	case IW_AUTH_WPA_ENABLED:
+-		if (paramval == 0) {
+-			iw->pwsec = 0;
+-			iw->gwsec = 0;
+-			error = dev_wlc_intvar_get(dev, "wsec", &val);
+-			if (error)
+-				return error;
+-			if (val & (TKIP_ENABLED | AES_ENABLED)) {
+-				val &= ~(TKIP_ENABLED | AES_ENABLED);
+-				dev_wlc_intvar_set(dev, "wsec", val);
+-			}
+-			val = 0;
+-			WL_INFORM("%s: %d: setting wpa_auth to %d\n",
+-				  __func__, __LINE__, val);
+-			dev_wlc_intvar_set(dev, "wpa_auth", 0);
+-			return error;
+-		}
+-		break;
+-
+-	case IW_AUTH_DROP_UNENCRYPTED:
+-		dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+-		dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-#if WIRELESS_EXT > 17
+-	case IW_AUTH_ROAMING_CONTROL:
+-		WL_INFORM("%s: IW_AUTH_ROAMING_CONTROL\n", __func__);
+-		break;
+-	case IW_AUTH_PRIVACY_INVOKED:
+-		{
+-			int wsec;
+-
+-			if (paramval == 0) {
+-				iw->privacy_invoked = false;
+-				error = dev_wlc_intvar_set(dev,
+-						"is_WPS_enrollee", false);
+-				if (error) {
+-					WL_WSEC("Failed to clear iovar is_WPS_enrollee\n");
+-					return error;
+-				}
+-			} else {
+-				iw->privacy_invoked = true;
+-				error = dev_wlc_intvar_get(dev, "wsec", &wsec);
+-				if (error)
+-					return error;
+-
+-				if (!(IW_WSEC_ENABLED(wsec))) {
+-					error = dev_wlc_intvar_set(dev,
+-							"is_WPS_enrollee",
+-							true);
+-					if (error) {
+-						WL_WSEC("Failed to set iovar is_WPS_enrollee\n");
+-						return error;
+-					}
+-				} else {
+-					error = dev_wlc_intvar_set(dev,
+-							"is_WPS_enrollee",
+-							false);
+-					if (error) {
+-						WL_WSEC("Failed to clear is_WPS_enrollee\n");
+-						return error;
+-					}
+-				}
+-			}
+-			break;
+-		}
+-#endif				/* WIRELESS_EXT > 17 */
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK))
+-
+-static int
+-wl_iw_get_wpaauth(struct net_device *dev,
+-		  struct iw_request_info *info,
+-		  struct iw_param *vwrq, char *extra)
+-{
+-	int error;
+-	int paramid;
+-	int paramval = 0;
+-	int val;
+-	wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: SIOCGIWAUTH\n", dev->name);
+-
+-	paramid = vwrq->flags & IW_AUTH_INDEX;
+-
+-	switch (paramid) {
+-	case IW_AUTH_WPA_VERSION:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED))
+-			paramval = IW_AUTH_WPA_VERSION_DISABLED;
+-		else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED))
+-			paramval = IW_AUTH_WPA_VERSION_WPA;
+-		else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED))
+-			paramval = IW_AUTH_WPA_VERSION_WPA2;
+-		break;
+-	case IW_AUTH_CIPHER_PAIRWISE:
+-	case IW_AUTH_CIPHER_GROUP:
+-		if (paramid == IW_AUTH_CIPHER_PAIRWISE)
+-			val = iw->pwsec;
+-		else
+-			val = iw->gwsec;
+-
+-		paramval = 0;
+-		if (val) {
+-			if (val & WEP_ENABLED)
+-				paramval |=
+-				    (IW_AUTH_CIPHER_WEP40 |
+-				     IW_AUTH_CIPHER_WEP104);
+-			if (val & TKIP_ENABLED)
+-				paramval |= (IW_AUTH_CIPHER_TKIP);
+-			if (val & AES_ENABLED)
+-				paramval |= (IW_AUTH_CIPHER_CCMP);
+-		} else
+-			paramval = IW_AUTH_CIPHER_NONE;
+-		break;
+-	case IW_AUTH_KEY_MGMT:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (VAL_PSK(val))
+-			paramval = IW_AUTH_KEY_MGMT_PSK;
+-		else
+-			paramval = IW_AUTH_KEY_MGMT_802_1X;
+-
+-		break;
+-	case IW_AUTH_TKIP_COUNTERMEASURES:
+-		dev_wlc_bufvar_get(dev, "tkip_countermeasures",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_DROP_UNENCRYPTED:
+-		dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+-		dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol",
+-				   (char *)&paramval, 1);
+-		break;
+-
+-	case IW_AUTH_80211_AUTH_ALG:
+-		error = dev_wlc_intvar_get(dev, "auth", &val);
+-		if (error)
+-			return error;
+-		if (!val)
+-			paramval = IW_AUTH_ALG_OPEN_SYSTEM;
+-		else
+-			paramval = IW_AUTH_ALG_SHARED_KEY;
+-		break;
+-	case IW_AUTH_WPA_ENABLED:
+-		error = dev_wlc_intvar_get(dev, "wpa_auth", &val);
+-		if (error)
+-			return error;
+-		if (val)
+-			paramval = true;
+-		else
+-			paramval = false;
+-		break;
+-#if WIRELESS_EXT > 17
+-	case IW_AUTH_ROAMING_CONTROL:
+-		WL_ERROR("%s: IW_AUTH_ROAMING_CONTROL\n", __func__);
+-		break;
+-	case IW_AUTH_PRIVACY_INVOKED:
+-		paramval = iw->privacy_invoked;
+-		break;
+-
+-#endif
+-	}
+-	vwrq->value = paramval;
+-	return 0;
+-}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-static const iw_handler wl_iw_handler[] = {
+-	(iw_handler) wl_iw_config_commit,
+-	(iw_handler) wl_iw_get_name,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_freq,
+-	(iw_handler) wl_iw_get_freq,
+-	(iw_handler) wl_iw_set_mode,
+-	(iw_handler) wl_iw_get_mode,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_get_range,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_spy,
+-	(iw_handler) wl_iw_get_spy,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_wap,
+-	(iw_handler) wl_iw_get_wap,
+-#if WIRELESS_EXT > 17
+-	(iw_handler) wl_iw_mlme,
+-#else
+-	(iw_handler) NULL,
+-#endif
+-#if defined(WL_IW_USE_ISCAN)
+-	(iw_handler) wl_iw_iscan_get_aplist,
+-#else
+-	(iw_handler) wl_iw_get_aplist,
+-#endif
+-#if WIRELESS_EXT > 13
+-#if defined(WL_IW_USE_ISCAN)
+-	(iw_handler) wl_iw_iscan_set_scan,
+-	(iw_handler) wl_iw_iscan_get_scan,
+-#else
+-	(iw_handler) wl_iw_set_scan,
+-	(iw_handler) wl_iw_get_scan,
+-#endif
+-#else
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-#endif				/* WIRELESS_EXT > 13 */
+-	(iw_handler) wl_iw_set_essid,
+-	(iw_handler) wl_iw_get_essid,
+-	(iw_handler) wl_iw_set_nick,
+-	(iw_handler) wl_iw_get_nick,
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_rate,
+-	(iw_handler) wl_iw_get_rate,
+-	(iw_handler) wl_iw_set_rts,
+-	(iw_handler) wl_iw_get_rts,
+-	(iw_handler) wl_iw_set_frag,
+-	(iw_handler) wl_iw_get_frag,
+-	(iw_handler) wl_iw_set_txpow,
+-	(iw_handler) wl_iw_get_txpow,
+-#if WIRELESS_EXT > 10
+-	(iw_handler) wl_iw_set_retry,
+-	(iw_handler) wl_iw_get_retry,
+-#endif
+-	(iw_handler) wl_iw_set_encode,
+-	(iw_handler) wl_iw_get_encode,
+-	(iw_handler) wl_iw_set_power,
+-	(iw_handler) wl_iw_get_power,
+-#if WIRELESS_EXT > 17
+-	(iw_handler) NULL,
+-	(iw_handler) NULL,
+-	(iw_handler) wl_iw_set_wpaie,
+-	(iw_handler) wl_iw_get_wpaie,
+-	(iw_handler) wl_iw_set_wpaauth,
+-	(iw_handler) wl_iw_get_wpaauth,
+-	(iw_handler) wl_iw_set_encodeext,
+-	(iw_handler) wl_iw_get_encodeext,
+-	(iw_handler) wl_iw_set_pmksa,
+-#endif				/* WIRELESS_EXT > 17 */
+-};
+-
+-#if WIRELESS_EXT > 12
+-
+-const struct iw_handler_def wl_iw_handler_def = {
+-	.num_standard = ARRAY_SIZE(wl_iw_handler),
+-	.standard = (iw_handler *) wl_iw_handler,
+-	.num_private = 0,
+-	.num_private_args = 0,
+-	.private = 0,
+-	.private_args = 0,
+-
+-#if WIRELESS_EXT >= 19
+-	.get_wireless_stats = NULL,
+-#endif
+-};
+-#endif				/* WIRELESS_EXT > 12 */
+-
+-int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+-{
+-	struct iwreq *wrq = (struct iwreq *)rq;
+-	struct iw_request_info info;
+-	iw_handler handler;
+-	char *extra = NULL;
+-	int token_size = 1, max_tokens = 0, ret = 0;
+-
+-	WL_TRACE("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n",
+-		 __func__, cmd);
+-	if (cmd < SIOCIWFIRST ||
+-		IW_IOCTL_IDX(cmd) >= ARRAY_SIZE(wl_iw_handler)) {
+-		WL_ERROR("%s: error in cmd=%x : out of range\n",
+-			 __func__, cmd);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	handler = wl_iw_handler[IW_IOCTL_IDX(cmd)];
+-	if (!handler) {
+-		WL_ERROR("%s: error in cmd=%x : not supported\n",
+-			 __func__, cmd);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	switch (cmd) {
+-
+-	case SIOCSIWESSID:
+-	case SIOCGIWESSID:
+-	case SIOCSIWNICKN:
+-	case SIOCGIWNICKN:
+-		max_tokens = IW_ESSID_MAX_SIZE + 1;
+-		break;
+-
+-	case SIOCSIWENCODE:
+-	case SIOCGIWENCODE:
+-#if WIRELESS_EXT > 17
+-	case SIOCSIWENCODEEXT:
+-	case SIOCGIWENCODEEXT:
+-#endif
+-		max_tokens = wrq->u.data.length;
+-		break;
+-
+-	case SIOCGIWRANGE:
+-		max_tokens = sizeof(struct iw_range) + 500;
+-		break;
+-
+-	case SIOCGIWAPLIST:
+-		token_size =
+-		    sizeof(struct sockaddr) + sizeof(struct iw_quality);
+-		max_tokens = IW_MAX_AP;
+-		break;
+-
+-#if WIRELESS_EXT > 13
+-	case SIOCGIWSCAN:
+-#if defined(WL_IW_USE_ISCAN)
+-		if (g_iscan)
+-			max_tokens = wrq->u.data.length;
+-		else
+-#endif
+-			max_tokens = IW_SCAN_MAX_DATA;
+-		break;
+-#endif				/* WIRELESS_EXT > 13 */
+-
+-	case SIOCSIWSPY:
+-		token_size = sizeof(struct sockaddr);
+-		max_tokens = IW_MAX_SPY;
+-		break;
+-
+-	case SIOCGIWSPY:
+-		token_size =
+-		    sizeof(struct sockaddr) + sizeof(struct iw_quality);
+-		max_tokens = IW_MAX_SPY;
+-		break;
+-
+-#if WIRELESS_EXT > 17
+-	case SIOCSIWPMKSA:
+-	case SIOCSIWGENIE:
+-#endif
+-	case SIOCSIWPRIV:
+-		max_tokens = wrq->u.data.length;
+-		break;
+-	}
+-
+-	if (max_tokens && wrq->u.data.pointer) {
+-		if (wrq->u.data.length > max_tokens) {
+-			WL_ERROR("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n",
+-				 __func__, cmd, wrq->u.data.length, max_tokens);
+-			return -E2BIG;
+-		}
+-		extra = kmalloc(max_tokens * token_size, GFP_KERNEL);
+-		if (!extra)
+-			return -ENOMEM;
+-
+-		if (copy_from_user
+-		    (extra, wrq->u.data.pointer,
+-		     wrq->u.data.length * token_size)) {
+-			kfree(extra);
+-			return -EFAULT;
+-		}
+-	}
+-
+-	info.cmd = cmd;
+-	info.flags = 0;
+-
+-	ret = handler(dev, &info, &wrq->u, extra);
+-
+-	if (extra) {
+-		if (copy_to_user
+-		    (wrq->u.data.pointer, extra,
+-		     wrq->u.data.length * token_size)) {
+-			kfree(extra);
+-			return -EFAULT;
+-		}
+-
+-		kfree(extra);
+-	}
+-
+-	return ret;
+-}
+-
+-bool
+-wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason,
+-		      char *stringBuf, uint buflen)
+-{
+-	typedef struct conn_fail_event_map_t {
+-		u32 inEvent;
+-		u32 inStatus;
+-		u32 inReason;
+-		const char *outName;
+-		const char *outCause;
+-	} conn_fail_event_map_t;
+-
+-#define WL_IW_DONT_CARE	9999
+-	const conn_fail_event_map_t event_map[] = {
+-		{WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE,
+-		 "Conn", "Success"},
+-		{WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE,
+-		 "Conn", "NoNetworks"},
+-		{WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "ConfigMismatch"},
+-		{WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH,
+-		 "Conn", "EncrypMismatch"},
+-		{WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH,
+-		 "Conn", "RsnMismatch"},
+-		{WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+-		 "Conn", "AuthTimeout"},
+-		{WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "AuthFail"},
+-		{WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE,
+-		 "Conn", "AuthNoAck"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocFail"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocTimeout"},
+-		{WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE,
+-		 "Conn", "ReassocAbort"},
+-		{WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE,
+-		 "Sup", "ConnSuccess"},
+-		{WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Sup", "WpaHandshakeFail"},
+-		{WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "Deauth"},
+-		{WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "DisassocInd"},
+-		{WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE,
+-		 "Conn", "Disassoc"}
+-	};
+-
+-	const char *name = "";
+-	const char *cause = NULL;
+-	int i;
+-
+-	for (i = 0; i < sizeof(event_map) / sizeof(event_map[0]); i++) {
+-		const conn_fail_event_map_t *row = &event_map[i];
+-		if (row->inEvent == event_type &&
+-		    (row->inStatus == status
+-		     || row->inStatus == WL_IW_DONT_CARE)
+-		    && (row->inReason == reason
+-			|| row->inReason == WL_IW_DONT_CARE)) {
+-			name = row->outName;
+-			cause = row->outCause;
+-			break;
+-		}
+-	}
+-
+-	if (cause) {
+-		memset(stringBuf, 0, buflen);
+-		snprintf(stringBuf, buflen, "%s %s %02d %02d",
+-			 name, cause, status, reason);
+-		WL_INFORM("Connection status: %s\n", stringBuf);
+-		return true;
+-	} else {
+-		return false;
+-	}
+-}
+-
+-#if WIRELESS_EXT > 14
+-
+-static bool
+-wl_iw_check_conn_fail(wl_event_msg_t *e, char *stringBuf, uint buflen)
+-{
+-	u32 event = be32_to_cpu(e->event_type);
+-	u32 status = be32_to_cpu(e->status);
+-	u32 reason = be32_to_cpu(e->reason);
+-
+-	if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) {
+-		return true;
+-	} else
+-		return false;
+-}
+-#endif
+-
+-#ifndef IW_CUSTOM_MAX
+-#define IW_CUSTOM_MAX 256
+-#endif
+-
+-void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data)
+-{
+-#if WIRELESS_EXT > 13
+-	union iwreq_data wrqu;
+-	char extra[IW_CUSTOM_MAX + 1];
+-	int cmd = 0;
+-	u32 event_type = be32_to_cpu(e->event_type);
+-	u16 flags = be16_to_cpu(e->flags);
+-	u32 datalen = be32_to_cpu(e->datalen);
+-	u32 status = be32_to_cpu(e->status);
+-	wl_iw_t *iw;
+-	u32 toto;
+-	memset(&wrqu, 0, sizeof(wrqu));
+-	memset(extra, 0, sizeof(extra));
+-	iw = 0;
+-
+-	if (!dev) {
+-		WL_ERROR("%s: dev is null\n", __func__);
+-		return;
+-	}
+-
+-	iw = *(wl_iw_t **) netdev_priv(dev);
+-
+-	WL_TRACE("%s: dev=%s event=%d\n", __func__, dev->name, event_type);
+-
+-	switch (event_type) {
+-	case WLC_E_TXFAIL:
+-		cmd = IWEVTXDROP;
+-		memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		break;
+-#if WIRELESS_EXT > 14
+-	case WLC_E_JOIN:
+-	case WLC_E_ASSOC_IND:
+-	case WLC_E_REASSOC_IND:
+-		memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		cmd = IWEVREGISTERED;
+-		break;
+-	case WLC_E_DEAUTH_IND:
+-	case WLC_E_DISASSOC_IND:
+-		cmd = SIOCGIWAP;
+-		memset(wrqu.addr.sa_data, 0, ETH_ALEN);
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		memset(&extra, 0, ETH_ALEN);
+-		break;
+-	case WLC_E_LINK:
+-	case WLC_E_NDIS_LINK:
+-		cmd = SIOCGIWAP;
+-		if (!(flags & WLC_EVENT_MSG_LINK)) {
+-			memset(wrqu.addr.sa_data, 0, ETH_ALEN);
+-			memset(&extra, 0, ETH_ALEN);
+-		} else {
+-			memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN);
+-			WL_TRACE("Link UP\n");
+-
+-		}
+-		wrqu.addr.sa_family = ARPHRD_ETHER;
+-		break;
+-	case WLC_E_ACTION_FRAME:
+-		cmd = IWEVCUSTOM;
+-		if (datalen + 1 <= sizeof(extra)) {
+-			wrqu.data.length = datalen + 1;
+-			extra[0] = WLC_E_ACTION_FRAME;
+-			memcpy(&extra[1], data, datalen);
+-			WL_TRACE("WLC_E_ACTION_FRAME len %d\n",
+-				 wrqu.data.length);
+-		}
+-		break;
+-
+-	case WLC_E_ACTION_FRAME_COMPLETE:
+-		cmd = IWEVCUSTOM;
+-		memcpy(&toto, data, 4);
+-		if (sizeof(status) + 1 <= sizeof(extra)) {
+-			wrqu.data.length = sizeof(status) + 1;
+-			extra[0] = WLC_E_ACTION_FRAME_COMPLETE;
+-			memcpy(&extra[1], &status, sizeof(status));
+-			WL_TRACE("wl_iw_event status %d PacketId %d\n", status,
+-				 toto);
+-			WL_TRACE("WLC_E_ACTION_FRAME_COMPLETE len %d\n",
+-				 wrqu.data.length);
+-		}
+-		break;
+-#endif				/* WIRELESS_EXT > 14 */
+-#if WIRELESS_EXT > 17
+-	case WLC_E_MIC_ERROR:
+-		{
+-			struct iw_michaelmicfailure *micerrevt =
+-			    (struct iw_michaelmicfailure *)&extra;
+-			cmd = IWEVMICHAELMICFAILURE;
+-			wrqu.data.length = sizeof(struct iw_michaelmicfailure);
+-			if (flags & WLC_EVENT_MSG_GROUP)
+-				micerrevt->flags |= IW_MICFAILURE_GROUP;
+-			else
+-				micerrevt->flags |= IW_MICFAILURE_PAIRWISE;
+-			memcpy(micerrevt->src_addr.sa_data, &e->addr,
+-			       ETH_ALEN);
+-			micerrevt->src_addr.sa_family = ARPHRD_ETHER;
+-
+-			break;
+-		}
+-	case WLC_E_PMKID_CACHE:
+-		{
+-			if (data) {
+-				struct iw_pmkid_cand *iwpmkidcand =
+-				    (struct iw_pmkid_cand *)&extra;
+-				pmkid_cand_list_t *pmkcandlist;
+-				pmkid_cand_t *pmkidcand;
+-				int count;
+-
+-				cmd = IWEVPMKIDCAND;
+-				pmkcandlist = data;
+-				count = get_unaligned_be32(&pmkcandlist->
+-							   npmkid_cand);
+-				ASSERT(count >= 0);
+-				wrqu.data.length = sizeof(struct iw_pmkid_cand);
+-				pmkidcand = pmkcandlist->pmkid_cand;
+-				while (count) {
+-					memset(iwpmkidcand, 0,
+-					      sizeof(struct iw_pmkid_cand));
+-					if (pmkidcand->preauth)
+-						iwpmkidcand->flags |=
+-						    IW_PMKID_CAND_PREAUTH;
+-					memcpy(&iwpmkidcand->bssid.sa_data,
+-					       &pmkidcand->BSSID,
+-					       ETH_ALEN);
+-#ifndef SANDGATE2G
+-					wireless_send_event(dev, cmd, &wrqu,
+-							    extra);
+-#endif
+-					pmkidcand++;
+-					count--;
+-				}
+-			}
+-			return;
+-		}
+-#endif				/* WIRELESS_EXT > 17 */
+-
+-	case WLC_E_SCAN_COMPLETE:
+-#if defined(WL_IW_USE_ISCAN)
+-		if ((g_iscan) && (g_iscan->sysioc_tsk) &&
+-		    (g_iscan->iscan_state != ISCAN_STATE_IDLE)) {
+-			up(&g_iscan->sysioc_sem);
+-		} else {
+-			cmd = SIOCGIWSCAN;
+-			wrqu.data.length = strlen(extra);
+-			WL_TRACE("Event WLC_E_SCAN_COMPLETE from specific scan %d\n",
+-				 g_iscan->iscan_state);
+-		}
+-#else
+-		cmd = SIOCGIWSCAN;
+-		wrqu.data.length = strlen(extra);
+-		WL_TRACE("Event WLC_E_SCAN_COMPLETE\n");
+-#endif
+-		break;
+-
+-	case WLC_E_PFN_NET_FOUND:
+-		{
+-			wlc_ssid_t *ssid;
+-			ssid = (wlc_ssid_t *) data;
+-			WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n",
+-				 __func__, PNO_EVENT_UP,
+-				 ssid->SSID, ssid->SSID_len);
+-			cmd = IWEVCUSTOM;
+-			memset(&wrqu, 0, sizeof(wrqu));
+-			strcpy(extra, PNO_EVENT_UP);
+-			wrqu.data.length = strlen(extra);
+-		}
+-		break;
+-
+-	default:
+-		WL_TRACE("Unknown Event %d: ignoring\n", event_type);
+-		break;
+-	}
+-#ifndef SANDGATE2G
+-	if (cmd) {
+-		if (cmd == SIOCGIWSCAN)
+-			wireless_send_event(dev, cmd, &wrqu, NULL);
+-		else
+-			wireless_send_event(dev, cmd, &wrqu, extra);
+-	}
+-#endif
+-
+-#if WIRELESS_EXT > 14
+-	memset(extra, 0, sizeof(extra));
+-	if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) {
+-		cmd = IWEVCUSTOM;
+-		wrqu.data.length = strlen(extra);
+-#ifndef SANDGATE2G
+-		wireless_send_event(dev, cmd, &wrqu, extra);
+-#endif
+-	}
+-#endif				/* WIRELESS_EXT > 14 */
+-#endif				/* WIRELESS_EXT > 13 */
+-}
+-
+-int wl_iw_attach(struct net_device *dev, void *dhdp)
+-{
+-	int params_size;
+-	wl_iw_t *iw;
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_info_t *iscan = NULL;
+-
+-	if (!dev)
+-		return 0;
+-
+-	memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t));
+-
+-#ifdef CSCAN
+-	params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)) +
+-	    (WL_NUMCHANNELS * sizeof(u16)) +
+-	    WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t);
+-#else
+-	params_size =
+-	    (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+-#endif
+-	iscan = kzalloc(sizeof(iscan_info_t), GFP_KERNEL);
+-
+-	if (!iscan)
+-		return -ENOMEM;
+-
+-	iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL);
+-	if (!iscan->iscan_ex_params_p) {
+-		kfree(iscan);
+-		return -ENOMEM;
+-	}
+-	iscan->iscan_ex_param_size = params_size;
+-	iscan->sysioc_tsk = NULL;
+-
+-	g_iscan = iscan;
+-	iscan->dev = dev;
+-	iscan->iscan_state = ISCAN_STATE_IDLE;
+-
+-	iscan->timer_ms = 3000;
+-	init_timer(&iscan->timer);
+-	iscan->timer.data = (unsigned long) iscan;
+-	iscan->timer.function = wl_iw_timerfunc;
+-
+-	sema_init(&iscan->sysioc_sem, 0);
+-	iscan->sysioc_tsk = kthread_run(_iscan_sysioc_thread, iscan,
+-					"_iscan_sysioc");
+-	if (IS_ERR(iscan->sysioc_tsk)) {
+-		iscan->sysioc_tsk = NULL;
+-		return -ENOMEM;
+-	}
+-#endif				/* defined(WL_IW_USE_ISCAN) */
+-
+-	iw = *(wl_iw_t **) netdev_priv(dev);
+-	iw->pub = (dhd_pub_t *) dhdp;
+-	MUTEX_LOCK_INIT(iw->pub);
+-	MUTEX_LOCK_WL_SCAN_SET_INIT();
+-#ifdef SOFTAP
+-	priv_dev = dev;
+-	MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub);
+-#endif
+-	g_scan = kzalloc(G_SCAN_RESULTS, GFP_KERNEL);
+-	if (!g_scan)
+-		return -ENOMEM;
+-
+-	g_scan_specified_ssid = 0;
+-
+-	return 0;
+-}
+-
+-void wl_iw_detach(void)
+-{
+-#if defined(WL_IW_USE_ISCAN)
+-	iscan_buf_t *buf;
+-	iscan_info_t *iscan = g_iscan;
+-
+-	if (!iscan)
+-		return;
+-	if (iscan->sysioc_tsk) {
+-		send_sig(SIGTERM, iscan->sysioc_tsk, 1);
+-		kthread_stop(iscan->sysioc_tsk);
+-		iscan->sysioc_tsk = NULL;
+-	}
+-
+-	MUTEX_LOCK_WL_SCAN_SET();
+-	while (iscan->list_hdr) {
+-		buf = iscan->list_hdr->next;
+-		kfree(iscan->list_hdr);
+-		iscan->list_hdr = buf;
+-	}
+-	MUTEX_UNLOCK_WL_SCAN_SET();
+-	kfree(iscan->iscan_ex_params_p);
+-	kfree(iscan);
+-	g_iscan = NULL;
+-#endif				/* WL_IW_USE_ISCAN */
+-
+-	kfree(g_scan);
+-
+-	g_scan = NULL;
+-}
+-
+-#if defined(BCMDBG)
+-void osl_assert(char *exp, char *file, int line)
+-{
+-	char tempbuf[256];
+-	char *basename;
+-
+-	basename = strrchr(file, '/');
+-	/* skip the '/' */
+-	if (basename)
+-		basename++;
+-
+-	if (!basename)
+-		basename = file;
+-
+-	snprintf(tempbuf, 256,
+-		 "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
+-		 basename, line);
+-
+-	/*
+-	 * Print assert message and give it time to
+-	 * be written to /var/log/messages
+-	 */
+-	if (!in_interrupt()) {
+-		const int delay = 3;
+-		printk(KERN_ERR "%s", tempbuf);
+-		printk(KERN_ERR "panic in %d seconds\n", delay);
+-		set_current_state(TASK_INTERRUPTIBLE);
+-		schedule_timeout(delay * HZ);
+-	}
+-
+-	switch (g_assert_type) {
+-	case 0:
+-		panic(KERN_ERR "%s", tempbuf);
+-		break;
+-	case 1:
+-		printk(KERN_ERR "%s", tempbuf);
+-		BUG();
+-		break;
+-	case 2:
+-		printk(KERN_ERR "%s", tempbuf);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-#endif				/* defined(BCMDBG) */
+diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h
+deleted file mode 100644
+index fe06174..0000000
+--- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h
++++ /dev/null
+@@ -1,142 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_iw_h_
+-#define _wl_iw_h_
+-
+-#include <linux/wireless.h>
+-
+-#include <wlioctl.h>
+-
+-#define WL_SCAN_PARAMS_SSID_MAX	10
+-#define GET_SSID	"SSID="
+-#define GET_CHANNEL	"CH="
+-#define GET_NPROBE 			"NPROBE="
+-#define GET_ACTIVE_ASSOC_DWELL  	"ACTIVE="
+-#define GET_PASSIVE_ASSOC_DWELL	"PASSIVE="
+-#define GET_HOME_DWELL		"HOME="
+-#define GET_SCAN_TYPE			"TYPE="
+-
+-#define BAND_GET_CMD				"BANDGET"
+-#define BAND_SET_CMD				"BANDSET"
+-#define DTIM_SKIP_GET_CMD			"DTIMSKIPGET"
+-#define DTIM_SKIP_SET_CMD			"DTIMSKIPSET"
+-#define SETSUSPEND_CMD				"SETSUSPENDOPT"
+-#define PNOSSIDCLR_SET_CMD			"PNOSSIDCLR"
+-#define PNOSETUP_SET_CMD			"PNOSETUP"
+-#define PNOENABLE_SET_CMD			"PNOFORCE"
+-#define PNODEBUG_SET_CMD			"PNODEBUG"
+-
+-typedef struct wl_iw_extra_params {
+-	int target_channel;
+-} wl_iw_extra_params_t;
+-
+-#define	WL_IW_RSSI_MINVAL		-200
+-#define	WL_IW_RSSI_NO_SIGNAL	-91
+-#define	WL_IW_RSSI_VERY_LOW	-80
+-#define	WL_IW_RSSI_LOW		-70
+-#define	WL_IW_RSSI_GOOD		-68
+-#define	WL_IW_RSSI_VERY_GOOD	-58
+-#define	WL_IW_RSSI_EXCELLENT	-57
+-#define	WL_IW_RSSI_INVALID	 0
+-#define MAX_WX_STRING 80
+-#define WL_IW_SET_ACTIVE_SCAN	(SIOCIWFIRSTPRIV+1)
+-#define WL_IW_GET_RSSI			(SIOCIWFIRSTPRIV+3)
+-#define WL_IW_SET_PASSIVE_SCAN	(SIOCIWFIRSTPRIV+5)
+-#define WL_IW_GET_LINK_SPEED	(SIOCIWFIRSTPRIV+7)
+-#define WL_IW_GET_CURR_MACADDR	(SIOCIWFIRSTPRIV+9)
+-#define WL_IW_SET_STOP				(SIOCIWFIRSTPRIV+11)
+-#define WL_IW_SET_START			(SIOCIWFIRSTPRIV+13)
+-
+-#define WL_SET_AP_CFG           (SIOCIWFIRSTPRIV+15)
+-#define WL_AP_STA_LIST          (SIOCIWFIRSTPRIV+17)
+-#define WL_AP_MAC_FLTR	        (SIOCIWFIRSTPRIV+19)
+-#define WL_AP_BSS_START         (SIOCIWFIRSTPRIV+21)
+-#define AP_LPB_CMD              (SIOCIWFIRSTPRIV+23)
+-#define WL_AP_STOP              (SIOCIWFIRSTPRIV+25)
+-#define WL_FW_RELOAD            (SIOCIWFIRSTPRIV+27)
+-#define WL_COMBO_SCAN            (SIOCIWFIRSTPRIV+29)
+-#define WL_AP_SPARE3            (SIOCIWFIRSTPRIV+31)
+-#define G_SCAN_RESULTS		(8*1024)
+-#define	WE_ADD_EVENT_FIX	0x80
+-#define          G_WLAN_SET_ON	0
+-#define          G_WLAN_SET_OFF	1
+-
+-#define CHECK_EXTRA_FOR_NULL(extra) \
+-if (!extra) { \
+-	WL_ERROR("%s: error : extra is null pointer\n", __func__);	\
+-	return -EINVAL; \
+-}
+-
+-typedef struct wl_iw {
+-	char nickname[IW_ESSID_MAX_SIZE];
+-
+-	struct iw_statistics wstats;
+-
+-	int spy_num;
+-	u32 pwsec;
+-	u32 gwsec;
+-	bool privacy_invoked;
+-
+-	u8 spy_addr[IW_MAX_SPY][ETH_ALEN];
+-	struct iw_quality spy_qual[IW_MAX_SPY];
+-	void *wlinfo;
+-	dhd_pub_t *pub;
+-} wl_iw_t;
+-
+-#if WIRELESS_EXT > 12
+-#include <net/iw_handler.h>
+-extern const struct iw_handler_def wl_iw_handler_def;
+-#endif
+-
+-extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+-extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data);
+-extern int wl_iw_get_wireless_stats(struct net_device *dev,
+-				    struct iw_statistics *wstats);
+-int wl_iw_attach(struct net_device *dev, void *dhdp);
+-void wl_iw_detach(void);
+-extern int net_os_set_suspend_disable(struct net_device *dev, int val);
+-extern int net_os_set_suspend(struct net_device *dev, int val);
+-extern int net_os_set_dtim_skip(struct net_device *dev, int val);
+-extern int net_os_set_packet_filter(struct net_device *dev, int val);
+-
+-#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \
+-	iwe_stream_add_event(info, stream, ends, iwe, extra)
+-#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \
+-	iwe_stream_add_value(info, event, value, ends, iwe, event_len)
+-#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \
+-	iwe_stream_add_point(info, stream, ends, iwe, extra)
+-
+-extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
+-extern int dhd_pno_clean(dhd_pub_t *dhd);
+-extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid,
+-		       unsigned char scan_fr);
+-extern int dhd_pno_get_status(dhd_pub_t *dhd);
+-extern int dhd_dev_pno_reset(struct net_device *dev);
+-extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local,
+-			   int nssid, unsigned char scan_fr);
+-extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled);
+-extern int dhd_dev_get_pno_status(struct net_device *dev);
+-
+-#define PNO_TLV_PREFIX			'S'
+-#define PNO_TLV_VERSION			1
+-#define PNO_TLV_SUBVERSION		0
+-#define PNO_TLV_RESERVED		0
+-#define PNO_TLV_TYPE_SSID_IE		'S'
+-#define PNO_TLV_TYPE_TIME		'T'
+-#define  PNO_EVENT_UP			"PNO_EVENT"
+-
+-#endif				/* _wl_iw_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile
+deleted file mode 100644
+index 8d75fe1..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/Makefile
++++ /dev/null
+@@ -1,59 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver
+-#
+-# Copyright (c) 2010 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=				\
+-	-DWLC_HIGH				\
+-	-DWLC_LOW				\
+-	-DSTA					\
+-	-DWME					\
+-	-DWL11N					\
+-	-DDBAND					\
+-	-DBCMNVRAMR				\
+-	-Idrivers/staging/brcm80211/brcmsmac \
+-	-Idrivers/staging/brcm80211/brcmsmac/phy \
+-	-Idrivers/staging/brcm80211/include
+-
+-BRCMSMAC_OFILES := \
+-	wl_mac80211.o \
+-	wl_ucode_loader.o \
+-	wlc_alloc.o \
+-	wlc_ampdu.o \
+-	wlc_antsel.o \
+-	wlc_bmac.o \
+-	wlc_channel.o \
+-	wlc_main.o \
+-	wlc_phy_shim.o \
+-	wlc_pmu.o \
+-	wlc_rate.o \
+-	wlc_stf.o \
+-	aiutils.o \
+-	phy/wlc_phy_cmn.o \
+-	phy/wlc_phy_lcn.o \
+-	phy/wlc_phy_n.o \
+-	phy/wlc_phytbl_lcn.o \
+-	phy/wlc_phytbl_n.o \
+-	phy/wlc_phy_qmath.o \
+-	bcmotp.o \
+-	bcmsrom.o \
+-	hnddma.o \
+-	nicpci.o \
+-	nvram.o
+-
+-MODULEPFX := brcmsmac
+-
+-obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
+-$(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
+diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c
+deleted file mode 100644
+index a61185f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/aiutils.c
++++ /dev/null
+@@ -1,2054 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <bcmdevs.h>
+-
+-/* ********** from siutils.c *********** */
+-#include <pci_core.h>
+-#include <pcie_core.h>
+-#include <nicpci.h>
+-#include <bcmnvram.h>
+-#include <bcmsrom.h>
+-#include <wlc_pmu.h>
+-
+-#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
+-		(sih->chiprev == 0) && \
+-		(sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
+-
+-/* EROM parsing */
+-
+-static u32
+-get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match)
+-{
+-	u32 ent;
+-	uint inv = 0, nom = 0;
+-
+-	while (true) {
+-		ent = R_REG(*eromptr);
+-		(*eromptr)++;
+-
+-		if (mask == 0)
+-			break;
+-
+-		if ((ent & ER_VALID) == 0) {
+-			inv++;
+-			continue;
+-		}
+-
+-		if (ent == (ER_END | ER_VALID))
+-			break;
+-
+-		if ((ent & mask) == match)
+-			break;
+-
+-		nom++;
+-	}
+-
+-	SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
+-	if (inv + nom) {
+-		SI_VMSG(("  after %d invalid and %d non-matching entries\n",
+-			 inv, nom));
+-	}
+-	return ent;
+-}
+-
+-static u32
+-get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st,
+-	u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
+-{
+-	u32 asd, sz, szd;
+-
+-	asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+-	if (((asd & ER_TAG1) != ER_ADD) ||
+-	    (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+-	    ((asd & AD_ST_MASK) != st)) {
+-		/* This is not what we want, "push" it back */
+-		(*eromptr)--;
+-		return 0;
+-	}
+-	*addrl = asd & AD_ADDR_MASK;
+-	if (asd & AD_AG32)
+-		*addrh = get_erom_ent(sih, eromptr, 0, 0);
+-	else
+-		*addrh = 0;
+-	*sizeh = 0;
+-	sz = asd & AD_SZ_MASK;
+-	if (sz == AD_SZ_SZD) {
+-		szd = get_erom_ent(sih, eromptr, 0, 0);
+-		*sizel = szd & SD_SZ_MASK;
+-		if (szd & SD_SG32)
+-			*sizeh = get_erom_ent(sih, eromptr, 0, 0);
+-	} else
+-		*sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+-
+-	SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+-		 sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
+-
+-	return asd;
+-}
+-
+-static void ai_hwfixup(si_info_t *sii)
+-{
+-}
+-
+-/* parse the enumeration rom to identify all cores */
+-void ai_scan(si_t *sih, void *regs, uint devid)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	chipcregs_t *cc = (chipcregs_t *) regs;
+-	u32 erombase, *eromptr, *eromlim;
+-
+-	erombase = R_REG(&cc->eromptr);
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-		eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
+-		break;
+-
+-	case PCI_BUS:
+-		/* Set wrappers address */
+-		sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
+-
+-		/* Now point the window at the erom */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
+-		eromptr = regs;
+-		break;
+-
+-	case SPI_BUS:
+-	case SDIO_BUS:
+-		eromptr = (u32 *)(unsigned long)erombase;
+-		break;
+-
+-	default:
+-		SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
+-			  sih->bustype));
+-		return;
+-	}
+-	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
+-
+-	SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
+-	while (eromptr < eromlim) {
+-		u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+-		u32 mpd, asd, addrl, addrh, sizel, sizeh;
+-		u32 *base;
+-		uint i, j, idx;
+-		bool br;
+-
+-		br = false;
+-
+-		/* Grok a component */
+-		cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+-		if (cia == (ER_END | ER_VALID)) {
+-			SI_VMSG(("Found END of erom after %d cores\n",
+-				 sii->numcores));
+-			ai_hwfixup(sii);
+-			return;
+-		}
+-		base = eromptr - 1;
+-		cib = get_erom_ent(sih, &eromptr, 0, 0);
+-
+-		if ((cib & ER_TAG) != ER_CI) {
+-			SI_ERROR(("CIA not followed by CIB\n"));
+-			goto error;
+-		}
+-
+-		cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+-		mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+-		crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+-		nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+-		nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+-		nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+-		nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+-
+-		SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
+-
+-		if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
+-			continue;
+-		if ((nmw + nsw == 0)) {
+-			/* A component which is not a core */
+-			if (cid == OOB_ROUTER_CORE_ID) {
+-				asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+-					      &addrl, &addrh, &sizel, &sizeh);
+-				if (asd != 0) {
+-					sii->oob_router = addrl;
+-				}
+-			}
+-			continue;
+-		}
+-
+-		idx = sii->numcores;
+-/*		sii->eromptr[idx] = base; */
+-		sii->cia[idx] = cia;
+-		sii->cib[idx] = cib;
+-		sii->coreid[idx] = cid;
+-
+-		for (i = 0; i < nmp; i++) {
+-			mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+-			if ((mpd & ER_TAG) != ER_MP) {
+-				SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
+-				goto error;
+-			}
+-			SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
+-				 (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+-				 (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
+-		}
+-
+-		/* First Slave Address Descriptor should be port 0:
+-		 * the main register space for the core
+-		 */
+-		asd =
+-		    get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
+-			    &sizel, &sizeh);
+-		if (asd == 0) {
+-			/* Try again to see if it is a bridge */
+-			asd =
+-			    get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if (asd != 0)
+-				br = true;
+-			else if ((addrh != 0) || (sizeh != 0)
+-				 || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
+-				goto error;
+-			}
+-		}
+-		sii->coresba[idx] = addrl;
+-		sii->coresba_size[idx] = sizel;
+-		/* Get any more ASDs in port 0 */
+-		j = 1;
+-		do {
+-			asd =
+-			    get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
+-				sii->coresba2[idx] = addrl;
+-				sii->coresba2_size[idx] = sizel;
+-			}
+-			j++;
+-		} while (asd != 0);
+-
+-		/* Go through the ASDs for other slave ports */
+-		for (i = 1; i < nsp; i++) {
+-			j = 0;
+-			do {
+-				asd =
+-				    get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
+-					    &addrl, &addrh, &sizel, &sizeh);
+-			} while (asd != 0);
+-			if (j == 0) {
+-				SI_ERROR((" SP %d has no address descriptors\n",
+-					  i));
+-				goto error;
+-			}
+-		}
+-
+-		/* Now get master wrappers */
+-		for (i = 0; i < nmw; i++) {
+-			asd =
+-			    get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
+-				    &addrh, &sizel, &sizeh);
+-			if (asd == 0) {
+-				SI_ERROR(("Missing descriptor for MW %d\n", i));
+-				goto error;
+-			}
+-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("Master wrapper %d is not 4KB\n", i));
+-				goto error;
+-			}
+-			if (i == 0)
+-				sii->wrapba[idx] = addrl;
+-		}
+-
+-		/* And finally slave wrappers */
+-		for (i = 0; i < nsw; i++) {
+-			uint fwp = (nsp == 1) ? 0 : 1;
+-			asd =
+-			    get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
+-				    &addrl, &addrh, &sizel, &sizeh);
+-			if (asd == 0) {
+-				SI_ERROR(("Missing descriptor for SW %d\n", i));
+-				goto error;
+-			}
+-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+-				SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
+-				goto error;
+-			}
+-			if ((nmw == 0) && (i == 0))
+-				sii->wrapba[idx] = addrl;
+-		}
+-
+-		/* Don't record bridges */
+-		if (br)
+-			continue;
+-
+-		/* Done with core */
+-		sii->numcores++;
+-	}
+-
+-	SI_ERROR(("Reached end of erom without finding END"));
+-
+- error:
+-	sii->numcores = 0;
+-	return;
+-}
+-
+-/* This function changes the logical "focus" to the indicated core.
+- * Return the current core's virtual address.
+- */
+-void *ai_setcoreidx(si_t *sih, uint coreidx)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	u32 addr = sii->coresba[coreidx];
+-	u32 wrap = sii->wrapba[coreidx];
+-	void *regs;
+-
+-	if (coreidx >= sii->numcores)
+-		return NULL;
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-		/* map new one */
+-		if (!sii->regs[coreidx]) {
+-			sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
+-		}
+-		sii->curmap = regs = sii->regs[coreidx];
+-		if (!sii->wrappers[coreidx]) {
+-			sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+-		}
+-		sii->curwrap = sii->wrappers[coreidx];
+-		break;
+-
+-	case PCI_BUS:
+-		/* point bar0 window */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
+-		regs = sii->curmap;
+-		/* point bar0 2nd 4KB window */
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
+-		break;
+-
+-	case SPI_BUS:
+-	case SDIO_BUS:
+-		sii->curmap = regs = (void *)(unsigned long)addr;
+-		sii->curwrap = (void *)(unsigned long)wrap;
+-		break;
+-
+-	default:
+-		regs = NULL;
+-		break;
+-	}
+-
+-	sii->curmap = regs;
+-	sii->curidx = coreidx;
+-
+-	return regs;
+-}
+-
+-/* Return the number of address spaces in current core */
+-int ai_numaddrspaces(si_t *sih)
+-{
+-	return 2;
+-}
+-
+-/* Return the address of the nth address space in the current core */
+-u32 ai_addrspace(si_t *sih, uint asidx)
+-{
+-	si_info_t *sii;
+-	uint cidx;
+-
+-	sii = SI_INFO(sih);
+-	cidx = sii->curidx;
+-
+-	if (asidx == 0)
+-		return sii->coresba[cidx];
+-	else if (asidx == 1)
+-		return sii->coresba2[cidx];
+-	else {
+-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+-		return 0;
+-	}
+-}
+-
+-/* Return the size of the nth address space in the current core */
+-u32 ai_addrspacesize(si_t *sih, uint asidx)
+-{
+-	si_info_t *sii;
+-	uint cidx;
+-
+-	sii = SI_INFO(sih);
+-	cidx = sii->curidx;
+-
+-	if (asidx == 0)
+-		return sii->coresba_size[cidx];
+-	else if (asidx == 1)
+-		return sii->coresba2_size[cidx];
+-	else {
+-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+-		return 0;
+-	}
+-}
+-
+-uint ai_flag(si_t *sih)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
+-		return sii->curidx;
+-	}
+-	ai = sii->curwrap;
+-
+-	return R_REG(&ai->oobselouta30) & 0x1f;
+-}
+-
+-void ai_setint(si_t *sih, int siflag)
+-{
+-}
+-
+-uint ai_corevendor(si_t *sih)
+-{
+-	si_info_t *sii;
+-	u32 cia;
+-
+-	sii = SI_INFO(sih);
+-	cia = sii->cia[sii->curidx];
+-	return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+-}
+-
+-uint ai_corerev(si_t *sih)
+-{
+-	si_info_t *sii;
+-	u32 cib;
+-
+-	sii = SI_INFO(sih);
+-	cib = sii->cib[sii->curidx];
+-	return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+-}
+-
+-bool ai_iscoreup(si_t *sih)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-	ai = sii->curwrap;
+-
+-	return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
+-		 SICF_CLOCK_EN)
+-		&& ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
+-}
+-
+-void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+-			  __func__));
+-		return;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+-		W_REG(&ai->ioctrl, w);
+-	}
+-}
+-
+-u32 ai_core_cflags(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+-			  __func__));
+-		return 0;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+-		W_REG(&ai->ioctrl, w);
+-	}
+-
+-	return R_REG(&ai->ioctrl);
+-}
+-
+-u32 ai_core_sflags(si_t *sih, u32 mask, u32 val)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 w;
+-
+-	sii = SI_INFO(sih);
+-	if (BCM47162_DMP()) {
+-		SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
+-		return 0;
+-	}
+-
+-	ai = sii->curwrap;
+-
+-	if (mask || val) {
+-		w = ((R_REG(&ai->iostatus) & ~mask) | val);
+-		W_REG(&ai->iostatus, w);
+-	}
+-
+-	return R_REG(&ai->iostatus);
+-}
+-
+-/* *************** from siutils.c ************** */
+-/* local prototypes */
+-static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs,
+-			      uint bustype, void *sdh, char **vars,
+-			      uint *varsz);
+-static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+-			    void *sdh);
+-static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+-			     u32 savewin, uint *origidx, void *regs);
+-static void ai_nvram_process(si_info_t *sii, char *pvars);
+-
+-/* dev path concatenation util */
+-static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name);
+-static bool _ai_clkctl_cc(si_info_t *sii, uint mode);
+-static bool ai_ispcie(si_info_t *sii);
+-
+-/* global variable to indicate reservation/release of gpio's */
+-static u32 ai_gpioreservation;
+-
+-/*
+- * Allocate a si handle.
+- * devid - pci device id (used to determine chip#)
+- * osh - opaque OS handle
+- * regs - virtual address of initial core registers
+- * bustype - pci/sb/sdio/etc
+- * vars - pointer to a pointer area for "environment" variables
+- * varsz - pointer to int to return the size of the vars
+- */
+-si_t *ai_attach(uint devid, void *regs, uint bustype,
+-		void *sdh, char **vars, uint *varsz)
+-{
+-	si_info_t *sii;
+-
+-	/* alloc si_info_t */
+-	sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
+-	if (sii == NULL) {
+-		SI_ERROR(("si_attach: malloc failed!\n"));
+-		return NULL;
+-	}
+-
+-	if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
+-	    NULL) {
+-		kfree(sii);
+-		return NULL;
+-	}
+-	sii->vars = vars ? *vars : NULL;
+-	sii->varsz = varsz ? *varsz : 0;
+-
+-	return (si_t *) sii;
+-}
+-
+-/* global kernel resource */
+-static si_info_t ksii;
+-
+-static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+-			    void *sdh)
+-{
+-	/* kludge to enable the clock on the 4306 which lacks a slowclock */
+-	if (bustype == PCI_BUS && !ai_ispcie(sii))
+-		ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
+-	return true;
+-}
+-
+-static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+-			     u32 savewin, uint *origidx, void *regs)
+-{
+-	bool pci, pcie;
+-	uint i;
+-	uint pciidx, pcieidx, pcirev, pcierev;
+-
+-	cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
+-
+-	/* get chipcommon rev */
+-	sii->pub.ccrev = (int)ai_corerev(&sii->pub);
+-
+-	/* get chipcommon chipstatus */
+-	if (sii->pub.ccrev >= 11)
+-		sii->pub.chipst = R_REG(&cc->chipstatus);
+-
+-	/* get chipcommon capabilites */
+-	sii->pub.cccaps = R_REG(&cc->capabilities);
+-	/* get chipcommon extended capabilities */
+-
+-	if (sii->pub.ccrev >= 35)
+-		sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
+-
+-	/* get pmu rev and caps */
+-	if (sii->pub.cccaps & CC_CAP_PMU) {
+-		sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
+-		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+-	}
+-
+-	/* figure out bus/orignal core idx */
+-	sii->pub.buscoretype = NODEV_CORE_ID;
+-	sii->pub.buscorerev = NOREV;
+-	sii->pub.buscoreidx = BADIDX;
+-
+-	pci = pcie = false;
+-	pcirev = pcierev = NOREV;
+-	pciidx = pcieidx = BADIDX;
+-
+-	for (i = 0; i < sii->numcores; i++) {
+-		uint cid, crev;
+-
+-		ai_setcoreidx(&sii->pub, i);
+-		cid = ai_coreid(&sii->pub);
+-		crev = ai_corerev(&sii->pub);
+-
+-		/* Display cores found */
+-		SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
+-			 i, cid, crev, sii->coresba[i], sii->regs[i]));
+-
+-		if (bustype == PCI_BUS) {
+-			if (cid == PCI_CORE_ID) {
+-				pciidx = i;
+-				pcirev = crev;
+-				pci = true;
+-			} else if (cid == PCIE_CORE_ID) {
+-				pcieidx = i;
+-				pcierev = crev;
+-				pcie = true;
+-			}
+-		}
+-
+-		/* find the core idx before entering this func. */
+-		if ((savewin && (savewin == sii->coresba[i])) ||
+-		    (regs == sii->regs[i]))
+-			*origidx = i;
+-	}
+-
+-	if (pci && pcie) {
+-		if (ai_ispcie(sii))
+-			pci = false;
+-		else
+-			pcie = false;
+-	}
+-	if (pci) {
+-		sii->pub.buscoretype = PCI_CORE_ID;
+-		sii->pub.buscorerev = pcirev;
+-		sii->pub.buscoreidx = pciidx;
+-	} else if (pcie) {
+-		sii->pub.buscoretype = PCIE_CORE_ID;
+-		sii->pub.buscorerev = pcierev;
+-		sii->pub.buscoreidx = pcieidx;
+-	}
+-
+-	SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
+-		 sii->pub.buscoretype, sii->pub.buscorerev));
+-
+-	/* fixup necessary chip/core configurations */
+-	if (sii->pub.bustype == PCI_BUS) {
+-		if (SI_FAST(sii)) {
+-			if (!sii->pch) {
+-				sii->pch = (void *)pcicore_init(
+-					&sii->pub, sii->pbus,
+-					(void *)PCIEREGS(sii));
+-				if (sii->pch == NULL)
+-					return false;
+-			}
+-		}
+-		if (ai_pci_fixcfg(&sii->pub)) {
+-			SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
+-			return false;
+-		}
+-	}
+-
+-	/* return to the original core */
+-	ai_setcoreidx(&sii->pub, *origidx);
+-
+-	return true;
+-}
+-
+-static __used void ai_nvram_process(si_info_t *sii, char *pvars)
+-{
+-	uint w = 0;
+-
+-	/* get boardtype and boardrev */
+-	switch (sii->pub.bustype) {
+-	case PCI_BUS:
+-		/* do a pci config read to get subsystem id and subvendor id */
+-		pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
+-		/* Let nvram variables override subsystem Vend/ID */
+-		sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
+-			"boardvendor");
+-		if (sii->pub.boardvendor == 0)
+-			sii->pub.boardvendor = w & 0xffff;
+-		else
+-			SI_ERROR(("Overriding boardvendor: 0x%x instead of "
+-				  "0x%x\n", sii->pub.boardvendor, w & 0xffff));
+-		sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
+-			"boardtype");
+-		if (sii->pub.boardtype == 0)
+-			sii->pub.boardtype = (w >> 16) & 0xffff;
+-		else
+-			SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
+-				  , sii->pub.boardtype, (w >> 16) & 0xffff));
+-		break;
+-
+-		sii->pub.boardvendor = getintvar(pvars, "manfid");
+-		sii->pub.boardtype = getintvar(pvars, "prodid");
+-		break;
+-
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
+-		sii->pub.boardtype = getintvar(pvars, "prodid");
+-		if (pvars == NULL || (sii->pub.boardtype == 0)) {
+-			sii->pub.boardtype = getintvar(NULL, "boardtype");
+-			if (sii->pub.boardtype == 0)
+-				sii->pub.boardtype = 0xffff;
+-		}
+-		break;
+-	}
+-
+-	if (sii->pub.boardtype == 0) {
+-		SI_ERROR(("si_doattach: unknown board type\n"));
+-	}
+-
+-	sii->pub.boardflags = getintvar(pvars, "boardflags");
+-}
+-
+-static si_info_t *ai_doattach(si_info_t *sii, uint devid,
+-			      void *regs, uint bustype, void *pbus,
+-			      char **vars, uint *varsz)
+-{
+-	struct si_pub *sih = &sii->pub;
+-	u32 w, savewin;
+-	chipcregs_t *cc;
+-	char *pvars = NULL;
+-	uint socitype;
+-	uint origidx;
+-
+-	memset((unsigned char *) sii, 0, sizeof(si_info_t));
+-
+-	savewin = 0;
+-
+-	sih->buscoreidx = BADIDX;
+-
+-	sii->curmap = regs;
+-	sii->pbus = pbus;
+-
+-	/* check to see if we are a si core mimic'ing a pci core */
+-	if (bustype == PCI_BUS) {
+-		pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
+-		if (w == 0xffffffff) {
+-			SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
+-				" switching to SI devid:0x%x\n",
+-				__func__, devid));
+-			bustype = SI_BUS;
+-		}
+-	}
+-
+-	/* find Chipcommon address */
+-	if (bustype == PCI_BUS) {
+-		pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
+-		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
+-			savewin = SI_ENUM_BASE;
+-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
+-				       SI_ENUM_BASE);
+-		cc = (chipcregs_t *) regs;
+-	} else {
+-		cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+-	}
+-
+-	sih->bustype = bustype;
+-
+-	/* bus/core/clk setup for register access */
+-	if (!ai_buscore_prep(sii, bustype, devid, pbus)) {
+-		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
+-			  bustype));
+-		return NULL;
+-	}
+-
+-	/*
+-	 * ChipID recognition.
+-	 *   We assume we can read chipid at offset 0 from the regs arg.
+-	 *   If we add other chiptypes (or if we need to support old sdio
+-	 *   hosts w/o chipcommon), some way of recognizing them needs to
+-	 *   be added here.
+-	 */
+-	w = R_REG(&cc->chipid);
+-	socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+-	/* Might as wll fill in chip id rev & pkg */
+-	sih->chip = w & CID_ID_MASK;
+-	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+-	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+-
+-	sih->issim = IS_SIM(sih->chippkg);
+-
+-	/* scan for cores */
+-	if (socitype == SOCI_AI) {
+-		SI_MSG(("Found chip type AI (0x%08x)\n", w));
+-		/* pass chipc address instead of original core base */
+-		ai_scan(&sii->pub, (void *)cc, devid);
+-	} else {
+-		SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
+-		return NULL;
+-	}
+-	/* no cores found, bail out */
+-	if (sii->numcores == 0) {
+-		SI_ERROR(("si_doattach: could not find any cores\n"));
+-		return NULL;
+-	}
+-	/* bus/core/clk setup */
+-	origidx = SI_CC_IDX;
+-	if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+-		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
+-		goto exit;
+-	}
+-
+-	/* assume current core is CC */
+-	if ((sii->pub.ccrev == 0x25)
+-	    &&
+-	    ((sih->chip == BCM43236_CHIP_ID
+-	      || sih->chip == BCM43235_CHIP_ID
+-	      || sih->chip == BCM43238_CHIP_ID)
+-	     && (sii->pub.chiprev <= 2))) {
+-
+-		if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
+-			uint clkdiv;
+-			clkdiv = R_REG(&cc->clkdiv);
+-			/* otp_clk_div is even number, 120/14 < 9mhz */
+-			clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
+-			W_REG(&cc->clkdiv, clkdiv);
+-			SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
+-		}
+-		udelay(10);
+-	}
+-
+-	/* Init nvram from flash if it exists */
+-	nvram_init();
+-
+-	/* Init nvram from sprom/otp if they exist */
+-	if (srom_var_init
+-	    (&sii->pub, bustype, regs, vars, varsz)) {
+-		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
+-		goto exit;
+-	}
+-	pvars = vars ? *vars : NULL;
+-	ai_nvram_process(sii, pvars);
+-
+-	/* === NVRAM, clock is ready === */
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-	W_REG(&cc->gpiopullup, 0);
+-	W_REG(&cc->gpiopulldown, 0);
+-	ai_setcoreidx(sih, origidx);
+-
+-	/* PMU specific initializations */
+-	if (PMUCTL_ENAB(sih)) {
+-		u32 xtalfreq;
+-		si_pmu_init(sih);
+-		si_pmu_chip_init(sih);
+-		xtalfreq = getintvar(pvars, "xtalfreq");
+-		/* If xtalfreq var not available, try to measure it */
+-		if (xtalfreq == 0)
+-			xtalfreq = si_pmu_measure_alpclk(sih);
+-		si_pmu_pll_init(sih, xtalfreq);
+-		si_pmu_res_init(sih);
+-		si_pmu_swreg_init(sih);
+-	}
+-
+-	/* setup the GPIO based LED powersave register */
+-	w = getintvar(pvars, "leddc");
+-	if (w == 0)
+-		w = DEFAULT_GPIOTIMERVAL;
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
+-
+-	if (PCIE(sii)) {
+-		pcicore_attach(sii->pch, pvars, SI_DOATTACH);
+-	}
+-
+-	if ((sih->chip == BCM43224_CHIP_ID) ||
+-	    (sih->chip == BCM43421_CHIP_ID)) {
+-		/*
+-		 * enable 12 mA drive strenth for 43224 and
+-		 * set chipControl register bit 15
+-		 */
+-		if (sih->chiprev == 0) {
+-			SI_MSG(("Applying 43224A0 WARs\n"));
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol),
+-				   CCTRL43224_GPIO_TOGGLE,
+-				   CCTRL43224_GPIO_TOGGLE);
+-			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
+-					   CCTRL_43224A0_12MA_LED_DRIVE);
+-		}
+-		if (sih->chiprev >= 1) {
+-			SI_MSG(("Applying 43224B0+ WARs\n"));
+-			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
+-					   CCTRL_43224B0_12MA_LED_DRIVE);
+-		}
+-	}
+-
+-	if (sih->chip == BCM4313_CHIP_ID) {
+-		/*
+-		 * enable 12 mA drive strenth for 4313 and
+-		 * set chipControl register bit 1
+-		 */
+-		SI_MSG(("Applying 4313 WARs\n"));
+-		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
+-				   CCTRL_4313_12MA_LED_DRIVE);
+-	}
+-
+-	if (sih->chip == BCM4331_CHIP_ID) {
+-		/* Enable Ext PA lines depending on chip package option */
+-		ai_chipcontrl_epa4331(sih, true);
+-	}
+-
+-	return sii;
+- exit:
+-	if (sih->bustype == PCI_BUS) {
+-		if (sii->pch)
+-			pcicore_deinit(sii->pch);
+-		sii->pch = NULL;
+-	}
+-
+-	return NULL;
+-}
+-
+-/* may be called with core in reset */
+-void ai_detach(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint idx;
+-
+-	struct si_pub *si_local = NULL;
+-	bcopy(&sih, &si_local, sizeof(si_t **));
+-
+-	sii = SI_INFO(sih);
+-
+-	if (sii == NULL)
+-		return;
+-
+-	if (sih->bustype == SI_BUS)
+-		for (idx = 0; idx < SI_MAXCORES; idx++)
+-			if (sii->regs[idx]) {
+-				iounmap(sii->regs[idx]);
+-				sii->regs[idx] = NULL;
+-			}
+-
+-	nvram_exit();	/* free up nvram buffers */
+-
+-	if (sih->bustype == PCI_BUS) {
+-		if (sii->pch)
+-			pcicore_deinit(sii->pch);
+-		sii->pch = NULL;
+-	}
+-
+-	if (sii != &ksii)
+-		kfree(sii);
+-}
+-
+-/* register driver interrupt disabling and restoring callback functions */
+-void
+-ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+-			  void *intrsenabled_fn, void *intr_arg)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	sii->intr_arg = intr_arg;
+-	sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
+-	sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
+-	sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
+-	/* save current core id.  when this function called, the current core
+-	 * must be the core which provides driver functions(il, et, wl, etc.)
+-	 */
+-	sii->dev_coreid = sii->coreid[sii->curidx];
+-}
+-
+-void ai_deregister_intr_callback(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	sii->intrsoff_fn = NULL;
+-}
+-
+-uint ai_coreid(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	return sii->coreid[sii->curidx];
+-}
+-
+-uint ai_coreidx(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	return sii->curidx;
+-}
+-
+-bool ai_backplane64(si_t *sih)
+-{
+-	return (sih->cccaps & CC_CAP_BKPLN64) != 0;
+-}
+-
+-/* return index of coreid or BADIDX if not found */
+-uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit)
+-{
+-	si_info_t *sii;
+-	uint found;
+-	uint i;
+-
+-	sii = SI_INFO(sih);
+-
+-	found = 0;
+-
+-	for (i = 0; i < sii->numcores; i++)
+-		if (sii->coreid[i] == coreid) {
+-			if (found == coreunit)
+-				return i;
+-			found++;
+-		}
+-
+-	return BADIDX;
+-}
+-
+-/*
+- * This function changes logical "focus" to the indicated core;
+- * must be called with interrupts off.
+- * Moreover, callers should keep interrupts off during switching
+- * out of and back to d11 core.
+- */
+-void *ai_setcore(si_t *sih, uint coreid, uint coreunit)
+-{
+-	uint idx;
+-
+-	idx = ai_findcoreidx(sih, coreid, coreunit);
+-	if (!GOODIDX(idx))
+-		return NULL;
+-
+-	return ai_setcoreidx(sih, idx);
+-}
+-
+-/* Turn off interrupt as required by ai_setcore, before switch core */
+-void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
+-{
+-	void *cc;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (SI_FAST(sii)) {
+-		/* Overloading the origidx variable to remember the coreid,
+-		 * this works because the core ids cannot be confused with
+-		 * core indices.
+-		 */
+-		*origidx = coreid;
+-		if (coreid == CC_CORE_ID)
+-			return (void *)CCREGS_FAST(sii);
+-		else if (coreid == sih->buscoretype)
+-			return (void *)PCIEREGS(sii);
+-	}
+-	INTR_OFF(sii, *intr_val);
+-	*origidx = sii->curidx;
+-	cc = ai_setcore(sih, coreid, 0);
+-	return cc;
+-}
+-
+-/* restore coreidx and restore interrupt */
+-void ai_restore_core(si_t *sih, uint coreid, uint intr_val)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-	if (SI_FAST(sii)
+-	    && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+-		return;
+-
+-	ai_setcoreidx(sih, coreid);
+-	INTR_RESTORE(sii, intr_val);
+-}
+-
+-void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val)
+-{
+-	si_info_t *sii = SI_INFO(sih);
+-	u32 *w = (u32 *) sii->curwrap;
+-	W_REG(w + (offset / 4), val);
+-	return;
+-}
+-
+-/*
+- * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
+- * operation, switch back to the original core, and return the new value.
+- *
+- * When using the silicon backplane, no fiddling with interrupts or core
+- * switches is needed.
+- *
+- * Also, when using pci/pcie, we can optimize away the core switching for pci
+- * registers and (on newer pci cores) chipcommon registers.
+- */
+-uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+-{
+-	uint origidx = 0;
+-	u32 *r = NULL;
+-	uint w;
+-	uint intr_val = 0;
+-	bool fast = false;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (coreidx >= SI_MAXCORES)
+-		return 0;
+-
+-	if (sih->bustype == SI_BUS) {
+-		/* If internal bus, we can always get at everything */
+-		fast = true;
+-		/* map if does not exist */
+-		if (!sii->regs[coreidx]) {
+-			sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+-						     SI_CORE_SIZE);
+-		}
+-		r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
+-	} else if (sih->bustype == PCI_BUS) {
+-		/*
+-		 * If pci/pcie, we can get at pci/pcie regs
+-		 * and on newer cores to chipc
+-		 */
+-		if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+-			/* Chipc registers are mapped at 12KB */
+-
+-			fast = true;
+-			r = (u32 *) ((char *)sii->curmap +
+-					PCI_16KB0_CCREGS_OFFSET + regoff);
+-		} else if (sii->pub.buscoreidx == coreidx) {
+-			/*
+-			 * pci registers are at either in the last 2KB of
+-			 * an 8KB window or, in pcie and pci rev 13 at 8KB
+-			 */
+-			fast = true;
+-			if (SI_FAST(sii))
+-				r = (u32 *) ((char *)sii->curmap +
+-						PCI_16KB0_PCIREGS_OFFSET +
+-						regoff);
+-			else
+-				r = (u32 *) ((char *)sii->curmap +
+-						((regoff >= SBCONFIGOFF) ?
+-						 PCI_BAR0_PCISBR_OFFSET :
+-						 PCI_BAR0_PCIREGS_OFFSET) +
+-						regoff);
+-		}
+-	}
+-
+-	if (!fast) {
+-		INTR_OFF(sii, intr_val);
+-
+-		/* save current core index */
+-		origidx = ai_coreidx(&sii->pub);
+-
+-		/* switch core */
+-		r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
+-				+ regoff);
+-	}
+-
+-	/* mask and set */
+-	if (mask || val) {
+-		w = (R_REG(r) & ~mask) | val;
+-		W_REG(r, w);
+-	}
+-
+-	/* readback */
+-	w = R_REG(r);
+-
+-	if (!fast) {
+-		/* restore core index */
+-		if (origidx != coreidx)
+-			ai_setcoreidx(&sii->pub, origidx);
+-
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-
+-	return w;
+-}
+-
+-void ai_core_disable(si_t *sih, u32 bits)
+-{
+-	si_info_t *sii;
+-	u32 dummy;
+-	aidmp_t *ai;
+-
+-	sii = SI_INFO(sih);
+-
+-	ai = sii->curwrap;
+-
+-	/* if core is already in reset, just return */
+-	if (R_REG(&ai->resetctrl) & AIRC_RESET)
+-		return;
+-
+-	W_REG(&ai->ioctrl, bits);
+-	dummy = R_REG(&ai->ioctrl);
+-	udelay(10);
+-
+-	W_REG(&ai->resetctrl, AIRC_RESET);
+-	udelay(1);
+-}
+-
+-/* reset and re-enable a core
+- * inputs:
+- * bits - core specific bits that are set during and after reset sequence
+- * resetbits - core specific bits that are set only during reset sequence
+- */
+-void ai_core_reset(si_t *sih, u32 bits, u32 resetbits)
+-{
+-	si_info_t *sii;
+-	aidmp_t *ai;
+-	u32 dummy;
+-
+-	sii = SI_INFO(sih);
+-	ai = sii->curwrap;
+-
+-	/*
+-	 * Must do the disable sequence first to work
+-	 * for arbitrary current core state.
+-	 */
+-	ai_core_disable(sih, (bits | resetbits));
+-
+-	/*
+-	 * Now do the initialization sequence.
+-	 */
+-	W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+-	dummy = R_REG(&ai->ioctrl);
+-	W_REG(&ai->resetctrl, 0);
+-	udelay(1);
+-
+-	W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
+-	dummy = R_REG(&ai->ioctrl);
+-	udelay(1);
+-}
+-
+-/* return the slow clock source - LPO, XTAL, or PCI */
+-static uint ai_slowclk_src(si_info_t *sii)
+-{
+-	chipcregs_t *cc;
+-	u32 val;
+-
+-	if (sii->pub.ccrev < 6) {
+-		if (sii->pub.bustype == PCI_BUS) {
+-			pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
+-					      &val);
+-			if (val & PCI_CFG_GPIO_SCS)
+-				return SCC_SS_PCI;
+-		}
+-		return SCC_SS_XTAL;
+-	} else if (sii->pub.ccrev < 10) {
+-		cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
+-		return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
+-	} else			/* Insta-clock */
+-		return SCC_SS_XTAL;
+-}
+-
+-/*
+-* return the ILP (slowclock) min or max frequency
+-* precondition: we've established the chip has dynamic clk control
+-*/
+-static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+-{
+-	u32 slowclk;
+-	uint div;
+-
+-	slowclk = ai_slowclk_src(sii);
+-	if (sii->pub.ccrev < 6) {
+-		if (slowclk == SCC_SS_PCI)
+-			return max_freq ? (PCIMAXFREQ / 64)
+-				: (PCIMINFREQ / 64);
+-		else
+-			return max_freq ? (XTALMAXFREQ / 32)
+-				: (XTALMINFREQ / 32);
+-	} else if (sii->pub.ccrev < 10) {
+-		div = 4 *
+-		    (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
+-		      SCC_CD_SHIFT) + 1);
+-		if (slowclk == SCC_SS_LPO)
+-			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
+-		else if (slowclk == SCC_SS_XTAL)
+-			return max_freq ? (XTALMAXFREQ / div)
+-				: (XTALMINFREQ / div);
+-		else if (slowclk == SCC_SS_PCI)
+-			return max_freq ? (PCIMAXFREQ / div)
+-				: (PCIMINFREQ / div);
+-	} else {
+-		/* Chipc rev 10 is InstaClock */
+-		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+-		div = 4 * (div + 1);
+-		return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
+-	}
+-	return 0;
+-}
+-
+-static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs)
+-{
+-	chipcregs_t *cc = (chipcregs_t *) chipcregs;
+-	uint slowmaxfreq, pll_delay, slowclk;
+-	uint pll_on_delay, fref_sel_delay;
+-
+-	pll_delay = PLL_DELAY;
+-
+-	/*
+-	 * If the slow clock is not sourced by the xtal then
+-	 * add the xtal_on_delay since the xtal will also be
+-	 * powered down by dynamic clk control logic.
+-	 */
+-
+-	slowclk = ai_slowclk_src(sii);
+-	if (slowclk != SCC_SS_XTAL)
+-		pll_delay += XTAL_ON_DELAY;
+-
+-	/* Starting with 4318 it is ILP that is used for the delays */
+-	slowmaxfreq =
+-	    ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
+-
+-	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+-	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+-
+-	W_REG(&cc->pll_on_delay, pll_on_delay);
+-	W_REG(&cc->fref_sel_delay, fref_sel_delay);
+-}
+-
+-/* initialize power control delay registers */
+-void ai_clkctl_init(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	bool fast;
+-
+-	if (!CCCTL_ENAB(sih))
+-		return;
+-
+-	sii = SI_INFO(sih);
+-	fast = SI_FAST(sii);
+-	if (!fast) {
+-		origidx = sii->curidx;
+-		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-		if (cc == NULL)
+-			return;
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			return;
+-	}
+-
+-	/* set all Instaclk chip ILP to 1 MHz */
+-	if (sih->ccrev >= 10)
+-		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
+-			(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+-
+-	ai_clkctl_setdelay(sii, (void *)cc);
+-
+-	if (!fast)
+-		ai_setcoreidx(sih, origidx);
+-}
+-
+-/*
+- * return the value suitable for writing to the
+- * dot11 core FAST_PWRUP_DELAY register
+- */
+-u16 ai_clkctl_fast_pwrup_delay(si_t *sih)
+-{
+-	si_info_t *sii;
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	uint slowminfreq;
+-	u16 fpdelay;
+-	uint intr_val = 0;
+-	bool fast;
+-
+-	sii = SI_INFO(sih);
+-	if (PMUCTL_ENAB(sih)) {
+-		INTR_OFF(sii, intr_val);
+-		fpdelay = si_pmu_fast_pwrup_delay(sih);
+-		INTR_RESTORE(sii, intr_val);
+-		return fpdelay;
+-	}
+-
+-	if (!CCCTL_ENAB(sih))
+-		return 0;
+-
+-	fast = SI_FAST(sii);
+-	fpdelay = 0;
+-	if (!fast) {
+-		origidx = sii->curidx;
+-		INTR_OFF(sii, intr_val);
+-		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-		if (cc == NULL)
+-			goto done;
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			goto done;
+-	}
+-
+-	slowminfreq = ai_slowclk_freq(sii, false, cc);
+-	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
+-		   (slowminfreq - 1)) / slowminfreq;
+-
+- done:
+-	if (!fast) {
+-		ai_setcoreidx(sih, origidx);
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-	return fpdelay;
+-}
+-
+-/* turn primary xtal and/or pll off/on */
+-int ai_clkctl_xtal(si_t *sih, uint what, bool on)
+-{
+-	si_info_t *sii;
+-	u32 in, out, outen;
+-
+-	sii = SI_INFO(sih);
+-
+-	switch (sih->bustype) {
+-
+-	case PCI_BUS:
+-		/* pcie core doesn't have any mapping to control the xtal pu */
+-		if (PCIE(sii))
+-			return -1;
+-
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
+-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
+-
+-		/*
+-		 * Avoid glitching the clock if GPRS is already using it.
+-		 * We can't actually read the state of the PLLPD so we infer it
+-		 * by the value of XTAL_PU which *is* readable via gpioin.
+-		 */
+-		if (on && (in & PCI_CFG_GPIO_XTAL))
+-			return 0;
+-
+-		if (what & XTAL)
+-			outen |= PCI_CFG_GPIO_XTAL;
+-		if (what & PLL)
+-			outen |= PCI_CFG_GPIO_PLL;
+-
+-		if (on) {
+-			/* turn primary xtal on */
+-			if (what & XTAL) {
+-				out |= PCI_CFG_GPIO_XTAL;
+-				if (what & PLL)
+-					out |= PCI_CFG_GPIO_PLL;
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUT, out);
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUTEN, outen);
+-				udelay(XTAL_ON_DELAY);
+-			}
+-
+-			/* turn pll on */
+-			if (what & PLL) {
+-				out &= ~PCI_CFG_GPIO_PLL;
+-				pci_write_config_dword(sii->pbus,
+-						       PCI_GPIO_OUT, out);
+-				mdelay(2);
+-			}
+-		} else {
+-			if (what & XTAL)
+-				out &= ~PCI_CFG_GPIO_XTAL;
+-			if (what & PLL)
+-				out |= PCI_CFG_GPIO_PLL;
+-			pci_write_config_dword(sii->pbus,
+-					       PCI_GPIO_OUT, out);
+-			pci_write_config_dword(sii->pbus,
+-					       PCI_GPIO_OUTEN, outen);
+-		}
+-
+-	default:
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- *  clock control policy function throught chipcommon
+- *
+- *    set dynamic clk control mode (forceslow, forcefast, dynamic)
+- *    returns true if we are forcing fast clock
+- *    this is a wrapper over the next internal function
+- *      to allow flexible policy settings for outside caller
+- */
+-bool ai_clkctl_cc(si_t *sih, uint mode)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+-	if (sih->ccrev < 6)
+-		return false;
+-
+-	if (PCI_FORCEHT(sii))
+-		return mode == CLK_FAST;
+-
+-	return _ai_clkctl_cc(sii, mode);
+-}
+-
+-/* clk control mechanism through chipcommon, no policy checking */
+-static bool _ai_clkctl_cc(si_info_t *sii, uint mode)
+-{
+-	uint origidx = 0;
+-	chipcregs_t *cc;
+-	u32 scc;
+-	uint intr_val = 0;
+-	bool fast = SI_FAST(sii);
+-
+-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+-	if (sii->pub.ccrev < 6)
+-		return false;
+-
+-	if (!fast) {
+-		INTR_OFF(sii, intr_val);
+-		origidx = sii->curidx;
+-
+-		if ((sii->pub.bustype == SI_BUS) &&
+-		    ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
+-		    (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
+-			goto done;
+-
+-		cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
+-	} else {
+-		cc = (chipcregs_t *) CCREGS_FAST(sii);
+-		if (cc == NULL)
+-			goto done;
+-	}
+-
+-	if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
+-		goto done;
+-
+-	switch (mode) {
+-	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
+-		if (sii->pub.ccrev < 10) {
+-			/*
+-			 * don't forget to force xtal back
+-			 * on before we clear SCC_DYN_XTAL..
+-			 */
+-			ai_clkctl_xtal(&sii->pub, XTAL, ON);
+-			SET_REG(&cc->slow_clk_ctl,
+-				(SCC_XC | SCC_FS | SCC_IP), SCC_IP);
+-		} else if (sii->pub.ccrev < 20) {
+-			OR_REG(&cc->system_clk_ctl, SYCC_HR);
+-		} else {
+-			OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
+-		}
+-
+-		/* wait for the PLL */
+-		if (PMUCTL_ENAB(&sii->pub)) {
+-			u32 htavail = CCS_HTAVAIL;
+-			SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
+-				  == 0), PMU_MAX_TRANSITION_DLY);
+-		} else {
+-			udelay(PLL_DELAY);
+-		}
+-		break;
+-
+-	case CLK_DYNAMIC:	/* enable dynamic clock control */
+-		if (sii->pub.ccrev < 10) {
+-			scc = R_REG(&cc->slow_clk_ctl);
+-			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
+-			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
+-				scc |= SCC_XC;
+-			W_REG(&cc->slow_clk_ctl, scc);
+-
+-			/*
+-			 * for dynamic control, we have to
+-			 * release our xtal_pu "force on"
+-			 */
+-			if (scc & SCC_XC)
+-				ai_clkctl_xtal(&sii->pub, XTAL, OFF);
+-		} else if (sii->pub.ccrev < 20) {
+-			/* Instaclock */
+-			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
+-		} else {
+-			AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
+-		}
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+- done:
+-	if (!fast) {
+-		ai_setcoreidx(&sii->pub, origidx);
+-		INTR_RESTORE(sii, intr_val);
+-	}
+-	return mode == CLK_FAST;
+-}
+-
+-/* Build device path. Support SI, PCI, and JTAG for now. */
+-int ai_devpath(si_t *sih, char *path, int size)
+-{
+-	int slen;
+-
+-	if (!path || size <= 0)
+-		return -1;
+-
+-	switch (sih->bustype) {
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
+-		break;
+-	case PCI_BUS:
+-		slen = snprintf(path, (size_t) size, "pci/%u/%u/",
+-			((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
+-			PCI_SLOT(
+-			    ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
+-		break;
+-
+-	default:
+-		slen = -1;
+-		break;
+-	}
+-
+-	if (slen < 0 || slen >= size) {
+-		path[0] = '\0';
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-/* Get a variable, but only if it has a devpath prefix */
+-char *ai_getdevpathvar(si_t *sih, const char *name)
+-{
+-	char varname[SI_DEVPATH_BUFSZ + 32];
+-
+-	ai_devpathvar(sih, varname, sizeof(varname), name);
+-
+-	return getvar(NULL, varname);
+-}
+-
+-/* Get a variable, but only if it has a devpath prefix */
+-int ai_getdevpathintvar(si_t *sih, const char *name)
+-{
+-#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
+-	return getintvar(NULL, name);
+-#else
+-	char varname[SI_DEVPATH_BUFSZ + 32];
+-
+-	ai_devpathvar(sih, varname, sizeof(varname), name);
+-
+-	return getintvar(NULL, varname);
+-#endif
+-}
+-
+-char *ai_getnvramflvar(si_t *sih, const char *name)
+-{
+-	return getvar(NULL, name);
+-}
+-
+-/* Concatenate the dev path with a varname into the given 'var' buffer
+- * and return the 'var' pointer. Nothing is done to the arguments if
+- * len == 0 or var is NULL, var is still returned. On overflow, the
+- * first char will be set to '\0'.
+- */
+-static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name)
+-{
+-	uint path_len;
+-
+-	if (!var || len <= 0)
+-		return var;
+-
+-	if (ai_devpath(sih, var, len) == 0) {
+-		path_len = strlen(var);
+-
+-		if (strlen(name) + 1 > (uint) (len - path_len))
+-			var[0] = '\0';
+-		else
+-			strncpy(var + path_len, name, len - path_len - 1);
+-	}
+-
+-	return var;
+-}
+-
+-/* return true if PCIE capability exists in the pci config space */
+-static __used bool ai_ispcie(si_info_t *sii)
+-{
+-	u8 cap_ptr;
+-
+-	if (sii->pub.bustype != PCI_BUS)
+-		return false;
+-
+-	cap_ptr =
+-	    pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
+-					NULL);
+-	if (!cap_ptr)
+-		return false;
+-
+-	return true;
+-}
+-
+-bool ai_pci_war16165(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	return PCI(sii) && (sih->buscorerev <= 10);
+-}
+-
+-void ai_pci_up(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* if not pci bus, we're done */
+-	if (sih->bustype != PCI_BUS)
+-		return;
+-
+-	if (PCI_FORCEHT(sii))
+-		_ai_clkctl_cc(sii, CLK_FAST);
+-
+-	if (PCIE(sii))
+-		pcicore_up(sii->pch, SI_PCIUP);
+-
+-}
+-
+-/* Unconfigure and/or apply various WARs when system is going to sleep mode */
+-void ai_pci_sleep(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	pcicore_sleep(sii->pch);
+-}
+-
+-/* Unconfigure and/or apply various WARs when going down */
+-void ai_pci_down(si_t *sih)
+-{
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	/* if not pci bus, we're done */
+-	if (sih->bustype != PCI_BUS)
+-		return;
+-
+-	/* release FORCEHT since chip is going to "down" state */
+-	if (PCI_FORCEHT(sii))
+-		_ai_clkctl_cc(sii, CLK_DYNAMIC);
+-
+-	pcicore_down(sii->pch, SI_PCIDOWN);
+-}
+-
+-/*
+- * Configure the pci core for pci client (NIC) action
+- * coremask is the bitvec of cores by index to be enabled.
+- */
+-void ai_pci_setup(si_t *sih, uint coremask)
+-{
+-	si_info_t *sii;
+-	struct sbpciregs *pciregs = NULL;
+-	u32 siflag = 0, w;
+-	uint idx = 0;
+-
+-	sii = SI_INFO(sih);
+-
+-	if (sii->pub.bustype != PCI_BUS)
+-		return;
+-
+-	if (PCI(sii)) {
+-		/* get current core index */
+-		idx = sii->curidx;
+-
+-		/* we interrupt on this backplane flag number */
+-		siflag = ai_flag(sih);
+-
+-		/* switch over to pci core */
+-		pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx);
+-	}
+-
+-	/*
+-	 * Enable sb->pci interrupts.  Assume
+-	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
+-	 */
+-	if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
+-		/* pci config write to set this core bit in PCIIntMask */
+-		pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
+-		w |= (coremask << PCI_SBIM_SHIFT);
+-		pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
+-	} else {
+-		/* set sbintvec bit for our flag number */
+-		ai_setint(sih, siflag);
+-	}
+-
+-	if (PCI(sii)) {
+-		OR_REG(&pciregs->sbtopci2,
+-		       (SBTOPCI_PREF | SBTOPCI_BURST));
+-		if (sii->pub.buscorerev >= 11) {
+-			OR_REG(&pciregs->sbtopci2,
+-			       SBTOPCI_RC_READMULTI);
+-			w = R_REG(&pciregs->clkrun);
+-			W_REG(&pciregs->clkrun,
+-			      (w | PCI_CLKRUN_DSBL));
+-			w = R_REG(&pciregs->clkrun);
+-		}
+-
+-		/* switch back to previous core */
+-		ai_setcoreidx(sih, idx);
+-	}
+-}
+-
+-/*
+- * Fixup SROMless PCI device's configuration.
+- * The current core may be changed upon return.
+- */
+-int ai_pci_fixcfg(si_t *sih)
+-{
+-	uint origidx, pciidx;
+-	struct sbpciregs *pciregs = NULL;
+-	sbpcieregs_t *pcieregs = NULL;
+-	void *regs = NULL;
+-	u16 val16, *reg16 = NULL;
+-
+-	si_info_t *sii = SI_INFO(sih);
+-
+-	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
+-	/* save the current index */
+-	origidx = ai_coreidx(&sii->pub);
+-
+-	/* check 'pi' is correct and fix it if not */
+-	if (sii->pub.buscoretype == PCIE_CORE_ID) {
+-		pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0);
+-		regs = pcieregs;
+-		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
+-	} else if (sii->pub.buscoretype == PCI_CORE_ID) {
+-		pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0);
+-		regs = pciregs;
+-		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
+-	}
+-	pciidx = ai_coreidx(&sii->pub);
+-	val16 = R_REG(reg16);
+-	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) {
+-		val16 =
+-		    (u16) (pciidx << SRSH_PI_SHIFT) | (val16 &
+-							  ~SRSH_PI_MASK);
+-		W_REG(reg16, val16);
+-	}
+-
+-	/* restore the original index */
+-	ai_setcoreidx(&sii->pub, origidx);
+-
+-	pcicore_hwup(sii->pch);
+-	return 0;
+-}
+-
+-/* mask&set gpiocontrol bits */
+-u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
+-{
+-	uint regoff;
+-
+-	regoff = 0;
+-
+-	/* gpios could be shared on router platforms
+-	 * ignore reservation if it's high priority (e.g., test apps)
+-	 */
+-	if ((priority != GPIO_HI_PRIORITY) &&
+-	    (sih->bustype == SI_BUS) && (val || mask)) {
+-		mask = priority ? (ai_gpioreservation & mask) :
+-		    ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
+-		val &= mask;
+-	}
+-
+-	regoff = offsetof(chipcregs_t, gpiocontrol);
+-	return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
+-}
+-
+-void ai_chipcontrl_epa4331(si_t *sih, bool on)
+-{
+-	si_info_t *sii;
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 val;
+-
+-	sii = SI_INFO(sih);
+-	origidx = ai_coreidx(sih);
+-
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-
+-	val = R_REG(&cc->chipcontrol);
+-
+-	if (on) {
+-		if (sih->chippkg == 9 || sih->chippkg == 0xb) {
+-			/* Ext PA Controls for 4331 12x9 Package */
+-			W_REG(&cc->chipcontrol, val |
+-			      (CCTRL4331_EXTPA_EN |
+-			       CCTRL4331_EXTPA_ON_GPIO2_5));
+-		} else {
+-			/* Ext PA Controls for 4331 12x12 Package */
+-			W_REG(&cc->chipcontrol,
+-			      val | (CCTRL4331_EXTPA_EN));
+-		}
+-	} else {
+-		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+-		W_REG(&cc->chipcontrol, val);
+-	}
+-
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* Enable BT-COEX & Ex-PA for 4313 */
+-void ai_epa_4313war(si_t *sih)
+-{
+-	si_info_t *sii;
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	sii = SI_INFO(sih);
+-	origidx = ai_coreidx(sih);
+-
+-	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+-
+-	/* EPA Fix */
+-	W_REG(&cc->gpiocontrol,
+-	      R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
+-
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* check if the device is removed */
+-bool ai_deviceremoved(si_t *sih)
+-{
+-	u32 w;
+-	si_info_t *sii;
+-
+-	sii = SI_INFO(sih);
+-
+-	switch (sih->bustype) {
+-	case PCI_BUS:
+-		pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
+-		if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
+-			return true;
+-		break;
+-	}
+-	return false;
+-}
+-
+-bool ai_is_sprom_available(si_t *sih)
+-{
+-	if (sih->ccrev >= 31) {
+-		si_info_t *sii;
+-		uint origidx;
+-		chipcregs_t *cc;
+-		u32 sromctrl;
+-
+-		if ((sih->cccaps & CC_CAP_SROM) == 0)
+-			return false;
+-
+-		sii = SI_INFO(sih);
+-		origidx = sii->curidx;
+-		cc = ai_setcoreidx(sih, SI_CC_IDX);
+-		sromctrl = R_REG(&cc->sromcontrol);
+-		ai_setcoreidx(sih, origidx);
+-		return sromctrl & SRC_PRESENT;
+-	}
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return (sih->chipst & CST4329_SPROM_SEL) != 0;
+-	case BCM4319_CHIP_ID:
+-		return (sih->chipst & CST4319_SPROM_SEL) != 0;
+-	case BCM4336_CHIP_ID:
+-		return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+-	case BCM4330_CHIP_ID:
+-		return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+-	case BCM4313_CHIP_ID:
+-		return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+-	case BCM4331_CHIP_ID:
+-		return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
+-	default:
+-		return true;
+-	}
+-}
+-
+-bool ai_is_otp_disabled(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
+-		    CST4329_OTP_PWRDN;
+-	case BCM4319_CHIP_ID:
+-		return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
+-		    CST4319_OTP_PWRDN;
+-	case BCM4336_CHIP_ID:
+-		return (sih->chipst & CST4336_OTP_PRESENT) == 0;
+-	case BCM4330_CHIP_ID:
+-		return (sih->chipst & CST4330_OTP_PRESENT) == 0;
+-	case BCM4313_CHIP_ID:
+-		return (sih->chipst & CST4313_OTP_PRESENT) == 0;
+-		/* These chips always have their OTP on */
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	default:
+-		return false;
+-	}
+-}
+-
+-bool ai_is_otp_powered(si_t *sih)
+-{
+-	if (PMUCTL_ENAB(sih))
+-		return si_pmu_is_otp_powered(sih);
+-	return true;
+-}
+-
+-void ai_otp_power(si_t *sih, bool on)
+-{
+-	if (PMUCTL_ENAB(sih))
+-		si_pmu_otp_power(sih, on);
+-	udelay(1000);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h
+deleted file mode 100644
+index b98099e..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/aiutils.h
++++ /dev/null
+@@ -1,546 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_aiutils_h_
+-#define	_aiutils_h_
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* Include the soci specific files */
+-#include <aidmp.h>
+-
+-/*
+- * SOC Interconnect Address Map.
+- * All regions may not exist on all chips.
+- */
+-/* Physical SDRAM */
+-#define SI_SDRAM_BASE		0x00000000
+-/* Host Mode sb2pcitranslation0 (64 MB) */
+-#define SI_PCI_MEM		0x08000000
+-#define SI_PCI_MEM_SZ		(64 * 1024 * 1024)
+-/* Host Mode sb2pcitranslation1 (64 MB) */
+-#define SI_PCI_CFG		0x0c000000
+-/* Byteswapped Physical SDRAM */
+-#define	SI_SDRAM_SWAPPED	0x10000000
+-/* Region 2 for sdram (512 MB) */
+-#define SI_SDRAM_R2		0x80000000
+-
+-#ifdef SI_ENUM_BASE_VARIABLE
+-#define SI_ENUM_BASE		(sii->pub.si_enum_base)
+-#else
+-#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
+-#endif				/* SI_ENUM_BASE_VARIABLE */
+-
+-/* Wrapper space base */
+-#define SI_WRAP_BASE		0x18100000
+-/* each core gets 4Kbytes for registers */
+-#define SI_CORE_SIZE		0x1000
+-/*
+- * Max cores (this is arbitrary, for software
+- * convenience and could be changed if we
+- * make any larger chips
+- */
+-#define	SI_MAXCORES		16
+-
+-/* On-chip RAM on chips that also have DDR */
+-#define	SI_FASTRAM		0x19000000
+-#define	SI_FASTRAM_SWAPPED	0x19800000
+-
+-/* Flash Region 2 (region 1 shadowed here) */
+-#define	SI_FLASH2		0x1c000000
+-/* Size of Flash Region 2 */
+-#define	SI_FLASH2_SZ		0x02000000
+-/* ARM Cortex-M3 ROM */
+-#define	SI_ARMCM3_ROM		0x1e000000
+-/* MIPS Flash Region 1 */
+-#define	SI_FLASH1		0x1fc00000
+-/* MIPS Size of Flash Region 1 */
+-#define	SI_FLASH1_SZ		0x00400000
+-/* ARM7TDMI-S ROM */
+-#define	SI_ARM7S_ROM		0x20000000
+-/* ARM Cortex-M3 SRAM Region 2 */
+-#define	SI_ARMCM3_SRAM2		0x60000000
+-/* ARM7TDMI-S SRAM Region 2 */
+-#define	SI_ARM7S_SRAM2		0x80000000
+-/* ARM Flash Region 1 */
+-#define	SI_ARM_FLASH1		0xffff0000
+-/* ARM Size of Flash Region 1 */
+-#define	SI_ARM_FLASH1_SZ	0x00010000
+-
+-/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA		0x40000000
+-/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA2		0x80000000
+-/* Client Mode sb2pcitranslation2 size in bytes */
+-#define SI_PCI_DMA_SZ		0x40000000
+-/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
+-#define SI_PCIE_DMA_L32		0x00000000
+-/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
+-#define SI_PCIE_DMA_H32		0x80000000
+-
+-/* core codes */
+-#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
+-#define	CC_CORE_ID		0x800	/* chipcommon core */
+-#define	ILINE20_CORE_ID		0x801	/* iline20 core */
+-#define	SRAM_CORE_ID		0x802	/* sram core */
+-#define	SDRAM_CORE_ID		0x803	/* sdram core */
+-#define	PCI_CORE_ID		0x804	/* pci core */
+-#define	MIPS_CORE_ID		0x805	/* mips core */
+-#define	ENET_CORE_ID		0x806	/* enet mac core */
+-#define	CODEC_CORE_ID		0x807	/* v90 codec core */
+-#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
+-#define	ADSL_CORE_ID		0x809	/* ADSL core */
+-#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
+-#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
+-#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
+-#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
+-#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
+-#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
+-#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
+-#define	EXTIF_CORE_ID		0x811	/* external interface core */
+-#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
+-#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
+-#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
+-#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
+-#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
+-#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
+-#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
+-#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
+-#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
+-#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
+-#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
+-#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
+-#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
+-#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
+-#define	PCIE_CORE_ID		0x820	/* pci express core */
+-#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
+-#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
+-#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
+-#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
+-#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
+-#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
+-#define	PMU_CORE_ID		0x827	/* PMU core */
+-#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
+-#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
+-#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
+-#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
+-#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
+-#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
+-#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
+-#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
+-#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
+-#define	SC_CORE_ID		0x831	/* shared common core */
+-#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
+-#define	SPIH_CORE_ID		0x833	/* SPI host core */
+-#define	I2S_CORE_ID		0x834	/* I2S core */
+-#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
+-#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
+-#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
+-#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
+-					 * maps all unused address ranges
+-					 */
+-
+-/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+- * and chipcommon being the first core:
+- */
+-#define	SI_CC_IDX		0
+-
+-/* SOC Interconnect types (aka chip types) */
+-#define	SOCI_AI			1
+-
+-/* Common core control flags */
+-#define	SICF_BIST_EN		0x8000
+-#define	SICF_PME_EN		0x4000
+-#define	SICF_CORE_BITS		0x3ffc
+-#define	SICF_FGC		0x0002
+-#define	SICF_CLOCK_EN		0x0001
+-
+-/* Common core status flags */
+-#define	SISF_BIST_DONE		0x8000
+-#define	SISF_BIST_ERROR		0x4000
+-#define	SISF_GATED_CLK		0x2000
+-#define	SISF_DMA64		0x1000
+-#define	SISF_CORE_BITS		0x0fff
+-
+-/* A register that is common to all cores to
+- * communicate w/PMU regarding clock control.
+- */
+-#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
+-
+-/* clk_ctl_st register */
+-#define	CCS_FORCEALP		0x00000001	/* force ALP request */
+-#define	CCS_FORCEHT		0x00000002	/* force HT request */
+-#define	CCS_FORCEILP		0x00000004	/* force ILP request */
+-#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
+-#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
+-#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
+-#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
+-#define CCS_ERSRC_REQ_SHIFT	8
+-#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
+-#define	CCS_HTAVAIL		0x00020000	/* HT is available */
+-#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
+-#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
+-#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
+-#define CCS_ERSRC_STS_SHIFT	24
+-
+-/* HT avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_HTAVAIL		0x00010000
+-/* ALP avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_ALPAVAIL		0x00020000
+-
+-/* Not really related to SOC Interconnect, but a couple of software
+- * conventions for the use the flash space:
+- */
+-
+-/* Minumum amount of flash we support */
+-#define FLASH_MIN		0x00020000	/* Minimum flash size */
+-
+-/* A boot/binary may have an embedded block that describes its size  */
+-#define	BISZ_OFFSET		0x3e0	/* At this offset into the binary */
+-#define	BISZ_MAGIC		0x4249535a	/* Marked with value: 'BISZ' */
+-#define	BISZ_MAGIC_IDX		0	/* Word 0: magic */
+-#define	BISZ_TXTST_IDX		1	/*      1: text start */
+-#define	BISZ_TXTEND_IDX		2	/*      2: text end */
+-#define	BISZ_DATAST_IDX		3	/*      3: data start */
+-#define	BISZ_DATAEND_IDX	4	/*      4: data end */
+-#define	BISZ_BSSST_IDX		5	/*      5: bss start */
+-#define	BISZ_BSSEND_IDX		6	/*      6: bss end */
+-#define BISZ_SIZE		7	/* descriptor size in 32-bit integers */
+-
+-#define	SI_INFO(sih)	(si_info_t *)sih
+-
+-#define	GOODCOREADDR(x, b) \
+-	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
+-		IS_ALIGNED((x), SI_CORE_SIZE))
+-#define	GOODREGS(regs) \
+-	((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
+-#define BADCOREADDR	0
+-#define	GOODIDX(idx)	(((uint)idx) < SI_MAXCORES)
+-#define	NOREV		-1	/* Invalid rev */
+-
+-/* Newer chips can access PCI/PCIE and CC core without requiring to change
+- * PCI BAR0 WIN
+- */
+-#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) ||	\
+-		     (((si)->pub.buscoretype == PCI_CORE_ID) && \
+-		      (si)->pub.buscorerev >= 13))
+-
+-#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
+-#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
+-
+-/*
+- * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
+- * before after core switching to avoid invalid register accesss inside ISR.
+- */
+-#define INTR_OFF(si, intr_val) \
+-	if ((si)->intrsoff_fn && \
+-	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+-		intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
+-#define INTR_RESTORE(si, intr_val) \
+-	if ((si)->intrsrestore_fn && \
+-	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+-		(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
+-
+-/* dynamic clock control defines */
+-#define	LPOMINFREQ		25000	/* low power oscillator min */
+-#define	LPOMAXFREQ		43000	/* low power oscillator max */
+-#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
+-#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
+-#define	PCIMINFREQ		25000000	/* 25 MHz */
+-#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
+-
+-#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
+-#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
+-
+-#define PCI(si)		(((si)->pub.bustype == PCI_BUS) &&	\
+-			 ((si)->pub.buscoretype == PCI_CORE_ID))
+-#define PCIE(si)	(((si)->pub.bustype == PCI_BUS) &&	\
+-			 ((si)->pub.buscoretype == PCIE_CORE_ID))
+-#define PCI_FORCEHT(si)	\
+-	(PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
+-
+-/* GPIO Based LED powersave defines */
+-#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
+-#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
+-
+-#ifndef DEFAULT_GPIOTIMERVAL
+-#define DEFAULT_GPIOTIMERVAL \
+-	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
+-#endif
+-
+-/*
+- * Data structure to export all chip specific common variables
+- *   public (read-only) portion of aiutils handle returned by si_attach()
+- */
+-struct si_pub {
+-	uint bustype;		/* SI_BUS, PCI_BUS */
+-	uint buscoretype;	/* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+-	uint buscorerev;	/* buscore rev */
+-	uint buscoreidx;	/* buscore index */
+-	int ccrev;		/* chip common core rev */
+-	u32 cccaps;		/* chip common capabilities */
+-	u32 cccaps_ext;	/* chip common capabilities extension */
+-	int pmurev;		/* pmu core rev */
+-	u32 pmucaps;		/* pmu capabilities */
+-	uint boardtype;		/* board type */
+-	uint boardvendor;	/* board vendor */
+-	uint boardflags;	/* board flags */
+-	uint boardflags2;	/* board flags2 */
+-	uint chip;		/* chip number */
+-	uint chiprev;		/* chip revision */
+-	uint chippkg;		/* chip package option */
+-	u32 chipst;		/* chip status */
+-	bool issim;		/* chip is in simulation or emulation */
+-	uint socirev;		/* SOC interconnect rev */
+-	bool pci_pr32414;
+-
+-};
+-
+-/*
+- * for HIGH_ONLY driver, the si_t must be writable to allow states sync from
+- * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident
+- * change
+- */
+-typedef const struct si_pub si_t;
+-
+-/*
+- * Many of the routines below take an 'sih' handle as their first arg.
+- * Allocate this by calling si_attach().  Free it by calling si_detach().
+- * At any one time, the sih is logically focused on one particular si core
+- * (the "current core").
+- * Use si_setcore() or si_setcoreidx() to change the association to another core
+- */
+-
+-#define	BADIDX		(SI_MAXCORES + 1)
+-
+-/* clkctl xtal what flags */
+-#define	XTAL			0x1	/* primary crystal oscillator (2050) */
+-#define	PLL			0x2	/* main chip pll */
+-
+-/* clkctl clk mode */
+-#define	CLK_FAST		0	/* force fast (pll) clock */
+-#define	CLK_DYNAMIC		2	/* enable dynamic clock control */
+-
+-/* GPIO usage priorities */
+-#define GPIO_DRV_PRIORITY	0	/* Driver */
+-#define GPIO_APP_PRIORITY	1	/* Application */
+-#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
+-					 * reservation
+-					 */
+-
+-/* GPIO pull up/down */
+-#define GPIO_PULLUP		0
+-#define GPIO_PULLDN		1
+-
+-/* GPIO event regtype */
+-#define GPIO_REGEVT		0	/* GPIO register event */
+-#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
+-#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
+-
+-/* device path */
+-#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
+-
+-/* SI routine enumeration: to be used by update function with multiple hooks */
+-#define	SI_DOATTACH	1
+-#define SI_PCIDOWN	2
+-#define SI_PCIUP	3
+-
+-#define	ISSIM_ENAB(sih)	0
+-
+-/* PMU clock/power control */
+-#if defined(BCMPMUCTL)
+-#define PMUCTL_ENAB(sih)	(BCMPMUCTL)
+-#else
+-#define PMUCTL_ENAB(sih)	((sih)->cccaps & CC_CAP_PMU)
+-#endif
+-
+-/* chipcommon clock/power control (exclusive with PMU's) */
+-#if defined(BCMPMUCTL) && BCMPMUCTL
+-#define CCCTL_ENAB(sih)		(0)
+-#define CCPLL_ENAB(sih)		(0)
+-#else
+-#define CCCTL_ENAB(sih)		((sih)->cccaps & CC_CAP_PWR_CTL)
+-#define CCPLL_ENAB(sih)		((sih)->cccaps & CC_CAP_PLL_MASK)
+-#endif
+-
+-typedef void (*gpio_handler_t) (u32 stat, void *arg);
+-
+-/* External PA enable mask */
+-#define GPIO_CTRL_EPA_EN_MASK 0x40
+-
+-#define	SI_ERROR(args)
+-
+-#ifdef BCMDBG
+-#define	SI_MSG(args)	printk args
+-#else
+-#define	SI_MSG(args)
+-#endif				/* BCMDBG */
+-
+-/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
+-#define	SI_VMSG(args)
+-
+-#define	IS_SIM(chippkg)	\
+-	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
+-
+-typedef u32(*si_intrsoff_t) (void *intr_arg);
+-typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
+-typedef bool(*si_intrsenabled_t) (void *intr_arg);
+-
+-typedef struct gpioh_item {
+-	void *arg;
+-	bool level;
+-	gpio_handler_t handler;
+-	u32 event;
+-	struct gpioh_item *next;
+-} gpioh_item_t;
+-
+-/* misc si info needed by some of the routines */
+-typedef struct si_info {
+-	struct si_pub pub;	/* back plane public state (must be first) */
+-	void *pbus;		/* handle to bus (pci/sdio/..) */
+-	uint dev_coreid;	/* the core provides driver functions */
+-	void *intr_arg;		/* interrupt callback function arg */
+-	si_intrsoff_t intrsoff_fn;	/* turns chip interrupts off */
+-	si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+-	si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+-
+-	void *pch;		/* PCI/E core handle */
+-
+-	gpioh_item_t *gpioh_head;	/* GPIO event handlers list */
+-
+-	bool memseg;		/* flag to toggle MEM_SEG register */
+-
+-	char *vars;
+-	uint varsz;
+-
+-	void *curmap;		/* current regs va */
+-	void *regs[SI_MAXCORES];	/* other regs va */
+-
+-	uint curidx;		/* current core index */
+-	uint numcores;		/* # discovered cores */
+-	uint coreid[SI_MAXCORES]; /* id of each core */
+-	u32 coresba[SI_MAXCORES]; /* backplane address of each core */
+-	void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
+-	u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
+-	u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
+-	u32 coresba2_size[SI_MAXCORES];	/* second address space size */
+-
+-	void *curwrap;		/* current wrapper va */
+-	void *wrappers[SI_MAXCORES];	/* other cores wrapper va */
+-	u32 wrapba[SI_MAXCORES];	/* address of controlling wrapper */
+-
+-	u32 cia[SI_MAXCORES];	/* erom cia entry for each core */
+-	u32 cib[SI_MAXCORES];	/* erom cia entry for each core */
+-	u32 oob_router;	/* oob router registers for axi */
+-} si_info_t;
+-
+-/* AMBA Interconnect exported externs */
+-extern void ai_scan(si_t *sih, void *regs, uint devid);
+-
+-extern uint ai_flag(si_t *sih);
+-extern void ai_setint(si_t *sih, int siflag);
+-extern uint ai_coreidx(si_t *sih);
+-extern uint ai_corevendor(si_t *sih);
+-extern uint ai_corerev(si_t *sih);
+-extern bool ai_iscoreup(si_t *sih);
+-extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+-extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+-extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val);
+-extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+-extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+-		       uint val);
+-extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+-extern void ai_core_disable(si_t *sih, u32 bits);
+-extern int ai_numaddrspaces(si_t *sih);
+-extern u32 ai_addrspace(si_t *sih, uint asidx);
+-extern u32 ai_addrspacesize(si_t *sih, uint asidx);
+-extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val);
+-
+-/* === exported functions === */
+-extern si_t *ai_attach(uint pcidev, void *regs, uint bustype,
+-		       void *sdh, char **vars, uint *varsz);
+-
+-extern void ai_detach(si_t *sih);
+-extern bool ai_pci_war16165(si_t *sih);
+-
+-extern uint ai_coreid(si_t *sih);
+-extern uint ai_corerev(si_t *sih);
+-extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+-		uint val);
+-extern void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val);
+-extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+-extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+-extern bool ai_iscoreup(si_t *sih);
+-extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit);
+-extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+-extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit);
+-extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx,
+-			    uint *intr_val);
+-extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val);
+-extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+-extern void ai_core_disable(si_t *sih, u32 bits);
+-extern u32 ai_alp_clock(si_t *sih);
+-extern u32 ai_ilp_clock(si_t *sih);
+-extern void ai_pci_setup(si_t *sih, uint coremask);
+-extern void ai_setint(si_t *sih, int siflag);
+-extern bool ai_backplane64(si_t *sih);
+-extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn,
+-				      void *intrsrestore_fn,
+-				      void *intrsenabled_fn, void *intr_arg);
+-extern void ai_deregister_intr_callback(si_t *sih);
+-extern void ai_clkctl_init(si_t *sih);
+-extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih);
+-extern bool ai_clkctl_cc(si_t *sih, uint mode);
+-extern int ai_clkctl_xtal(si_t *sih, uint what, bool on);
+-extern bool ai_deviceremoved(si_t *sih);
+-extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val,
+-			     u8 priority);
+-
+-/* OTP status */
+-extern bool ai_is_otp_disabled(si_t *sih);
+-extern bool ai_is_otp_powered(si_t *sih);
+-extern void ai_otp_power(si_t *sih, bool on);
+-
+-/* SPROM availability */
+-extern bool ai_is_sprom_available(si_t *sih);
+-
+-/*
+- * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
+- * The returned path is NULL terminated and has trailing '/'.
+- * Return 0 on success, nonzero otherwise.
+- */
+-extern int ai_devpath(si_t *sih, char *path, int size);
+-/* Read variable with prepending the devpath to the name */
+-extern char *ai_getdevpathvar(si_t *sih, const char *name);
+-extern int ai_getdevpathintvar(si_t *sih, const char *name);
+-
+-extern void ai_pci_sleep(si_t *sih);
+-extern void ai_pci_down(si_t *sih);
+-extern void ai_pci_up(si_t *sih);
+-extern int ai_pci_fixcfg(si_t *sih);
+-
+-extern void ai_chipcontrl_epa4331(si_t *sih, bool on);
+-/* Enable Ex-PA for 4313 */
+-extern void ai_epa_4313war(si_t *sih);
+-
+-char *ai_getnvramflvar(si_t *sih, const char *name);
+-
+-#endif				/* _aiutils_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmotp.c b/drivers/staging/brcm80211/brcmsmac/bcmotp.c
+deleted file mode 100644
+index d09628b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmotp.c
++++ /dev/null
+@@ -1,936 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/crc-ccitt.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <bcmotp.h>
+-
+-/*
+- * There are two different OTP controllers so far:
+- * 	1. new IPX OTP controller:	chipc 21, >=23
+- * 	2. older HND OTP controller:	chipc 12, 17, 22
+- *
+- * Define BCMHNDOTP to include support for the HND OTP controller.
+- * Define BCMIPXOTP to include support for the IPX OTP controller.
+- *
+- * NOTE 1: More than one may be defined
+- * NOTE 2: If none are defined, the default is to include them all.
+- */
+-
+-#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
+-#define BCMHNDOTP	1
+-#define BCMIPXOTP	1
+-#endif
+-
+-#define OTPTYPE_HND(ccrev)	((ccrev) < 21 || (ccrev) == 22)
+-#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)
+-
+-#define OTPP_TRIES	10000000	/* # of tries for OTPP */
+-
+-#ifdef BCMIPXOTP
+-#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
+-#endif
+-
+-/* OTP common function type */
+-typedef int (*otp_status_t) (void *oh);
+-typedef int (*otp_size_t) (void *oh);
+-typedef void *(*otp_init_t) (si_t *sih);
+-typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
+-typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
+-				  uint *wlen);
+-typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
+-
+-/* OTP function struct */
+-typedef struct otp_fn_s {
+-	otp_size_t size;
+-	otp_read_bit_t read_bit;
+-	otp_init_t init;
+-	otp_read_region_t read_region;
+-	otp_nvread_t nvread;
+-	otp_status_t status;
+-} otp_fn_t;
+-
+-typedef struct {
+-	uint ccrev;		/* chipc revision */
+-	otp_fn_t *fn;		/* OTP functions */
+-	si_t *sih;		/* Saved sb handle */
+-
+-#ifdef BCMIPXOTP
+-	/* IPX OTP section */
+-	u16 wsize;		/* Size of otp in words */
+-	u16 rows;		/* Geometry */
+-	u16 cols;		/* Geometry */
+-	u32 status;		/* Flag bits (lock/prog/rv).
+-				 * (Reflected only when OTP is power cycled)
+-				 */
+-	u16 hwbase;		/* hardware subregion offset */
+-	u16 hwlim;		/* hardware subregion boundary */
+-	u16 swbase;		/* software subregion offset */
+-	u16 swlim;		/* software subregion boundary */
+-	u16 fbase;		/* fuse subregion offset */
+-	u16 flim;		/* fuse subregion boundary */
+-	int otpgu_base;		/* offset to General Use Region */
+-#endif				/* BCMIPXOTP */
+-
+-#ifdef BCMHNDOTP
+-	/* HND OTP section */
+-	uint size;		/* Size of otp in bytes */
+-	uint hwprot;		/* Hardware protection bits */
+-	uint signvalid;		/* Signature valid bits */
+-	int boundary;		/* hw/sw boundary */
+-#endif				/* BCMHNDOTP */
+-} otpinfo_t;
+-
+-static otpinfo_t otpinfo;
+-
+-/*
+- * IPX OTP Code
+- *
+- *   Exported functions:
+- *	ipxotp_status()
+- *	ipxotp_size()
+- *	ipxotp_init()
+- *	ipxotp_read_bit()
+- *	ipxotp_read_region()
+- *	ipxotp_nvread()
+- *
+- */
+-
+-#ifdef BCMIPXOTP
+-
+-#define HWSW_RGN(rgn)		(((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
+-
+-/* OTP layout */
+-/* CC revs 21, 24 and 27 OTP General Use Region word offset */
+-#define REVA4_OTPGU_BASE	12
+-
+-/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
+-#define REVB8_OTPGU_BASE	20
+-
+-/* CC rev 36 OTP General Use Region word offset */
+-#define REV36_OTPGU_BASE	12
+-
+-/* Subregion word offsets in General Use region */
+-#define OTPGU_HSB_OFF		0
+-#define OTPGU_SFB_OFF		1
+-#define OTPGU_CI_OFF		2
+-#define OTPGU_P_OFF		3
+-#define OTPGU_SROM_OFF		4
+-
+-/* Flag bit offsets in General Use region  */
+-#define OTPGU_HWP_OFF		60
+-#define OTPGU_SWP_OFF		61
+-#define OTPGU_CIP_OFF		62
+-#define OTPGU_FUSEP_OFF		63
+-#define OTPGU_CIP_MSK		0x4000
+-#define OTPGU_P_MSK		0xf000
+-#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)
+-
+-/* OTP Size */
+-#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
+-#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
+-#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
+-#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
+-#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
+-#define OTP4315_SWREG_SZ	178	/* 178 bytes */
+-#define OTP_SZ_FU_144		(144/8)	/* 144 bits */
+-
+-static int ipxotp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->status);
+-}
+-
+-/* Return size in bytes */
+-static int ipxotp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)oi->wsize * 2;
+-}
+-
+-static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+-{
+-	otpinfo_t *oi;
+-
+-	oi = (otpinfo_t *) oh;
+-
+-	return R_REG(&cc->sromotp[wn]);
+-}
+-
+-static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint k, row, col;
+-	u32 otpp, st;
+-
+-	row = off / oi->cols;
+-	col = off % oi->cols;
+-
+-	otpp = OTPP_START_BUSY |
+-	    ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
+-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
+-	    ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
+-	W_REG(&cc->otpprog, otpp);
+-
+-	for (k = 0;
+-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+-	     && (k < OTPP_TRIES); k++)
+-		;
+-	if (k >= OTPP_TRIES) {
+-		return 0xffff;
+-	}
+-	if (st & OTPP_READERR) {
+-		return 0xffff;
+-	}
+-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+-
+-	return (int)st;
+-}
+-
+-/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
+- * osizew is oi->wsize (OTP size - GU size) in words
+- */
+-static int ipxotp_max_rgnsz(si_t *sih, int osizew)
+-{
+-	int ret = 0;
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+-		break;
+-	case BCM4313_CHIP_ID:
+-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+-		break;
+-	default:
+-		break;	/* Don't know about this chip */
+-	}
+-
+-	return ret;
+-}
+-
+-static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
+-{
+-	uint k;
+-	u32 otpp, st;
+-
+-	/* record word offset of General Use Region for various chipcommon revs */
+-	if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
+-	    || oi->sih->ccrev == 27) {
+-		oi->otpgu_base = REVA4_OTPGU_BASE;
+-	} else if (oi->sih->ccrev == 36) {
+-		/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
+-		if (oi->wsize >= 128)
+-			oi->otpgu_base = REVB8_OTPGU_BASE;
+-		else
+-			oi->otpgu_base = REV36_OTPGU_BASE;
+-	} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
+-		oi->otpgu_base = REVB8_OTPGU_BASE;
+-	}
+-
+-	/* First issue an init command so the status is up to date */
+-	otpp =
+-	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
+-
+-	W_REG(&cc->otpprog, otpp);
+-	for (k = 0;
+-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+-	     && (k < OTPP_TRIES); k++)
+-		;
+-	if (k >= OTPP_TRIES) {
+-		return;
+-	}
+-
+-	/* Read OTP lock bits and subregion programmed indication bits */
+-	oi->status = R_REG(&cc->otpstatus);
+-
+-	if ((oi->sih->chip == BCM43224_CHIP_ID)
+-	    || (oi->sih->chip == BCM43225_CHIP_ID)) {
+-		u32 p_bits;
+-		p_bits =
+-		    (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
+-		     OTPGU_P_MSK)
+-		    >> OTPGU_P_SHIFT;
+-		oi->status |= (p_bits << OTPS_GUP_SHIFT);
+-	}
+-
+-	/*
+-	 * h/w region base and fuse region limit are fixed to the top and
+-	 * the bottom of the general use region. Everything else can be flexible.
+-	 */
+-	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
+-	oi->hwlim = oi->wsize;
+-	if (oi->status & OTPS_GUP_HW) {
+-		oi->hwlim =
+-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
+-		oi->swbase = oi->hwlim;
+-	} else
+-		oi->swbase = oi->hwbase;
+-
+-	/* subtract fuse and checksum from beginning */
+-	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
+-
+-	if (oi->status & OTPS_GUP_SW) {
+-		oi->swlim =
+-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
+-		oi->fbase = oi->swlim;
+-	} else
+-		oi->fbase = oi->swbase;
+-
+-	oi->flim = oi->wsize;
+-}
+-
+-static void *ipxotp_init(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	otpinfo_t *oi;
+-
+-	/* Make sure we're running IPX OTP */
+-	if (!OTPTYPE_IPX(sih->ccrev))
+-		return NULL;
+-
+-	/* Make sure OTP is not disabled */
+-	if (ai_is_otp_disabled(sih))
+-		return NULL;
+-
+-	/* Make sure OTP is powered up */
+-	if (!ai_is_otp_powered(sih))
+-		return NULL;
+-
+-	oi = &otpinfo;
+-
+-	/* Check for otp size */
+-	switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
+-	case 0:
+-		/* Nothing there */
+-		return NULL;
+-	case 1:		/* 32x64 */
+-		oi->rows = 32;
+-		oi->cols = 64;
+-		oi->wsize = 128;
+-		break;
+-	case 2:		/* 64x64 */
+-		oi->rows = 64;
+-		oi->cols = 64;
+-		oi->wsize = 256;
+-		break;
+-	case 5:		/* 96x64 */
+-		oi->rows = 96;
+-		oi->cols = 64;
+-		oi->wsize = 384;
+-		break;
+-	case 7:		/* 16x64 *//* 1024 bits */
+-		oi->rows = 16;
+-		oi->cols = 64;
+-		oi->wsize = 64;
+-		break;
+-	default:
+-		/* Don't know the geometry */
+-		return NULL;
+-	}
+-
+-	/* Retrieve OTP region info */
+-	idx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	_ipxotp_init(oi, cc);
+-
+-	ai_setcoreidx(sih, idx);
+-
+-	return (void *)oi;
+-}
+-
+-static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint idx;
+-	chipcregs_t *cc;
+-	uint base, i, sz;
+-
+-	/* Validate region selection */
+-	switch (region) {
+-	case OTP_HW_RGN:
+-		sz = (uint) oi->hwlim - oi->hwbase;
+-		if (!(oi->status & OTPS_GUP_HW)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->hwbase;
+-		break;
+-	case OTP_SW_RGN:
+-		sz = ((uint) oi->swlim - oi->swbase);
+-		if (!(oi->status & OTPS_GUP_SW)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->swbase;
+-		break;
+-	case OTP_CI_RGN:
+-		sz = OTPGU_CI_SZ;
+-		if (!(oi->status & OTPS_GUP_CI)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->otpgu_base + OTPGU_CI_OFF;
+-		break;
+-	case OTP_FUSE_RGN:
+-		sz = (uint) oi->flim - oi->fbase;
+-		if (!(oi->status & OTPS_GUP_FUSE)) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->fbase;
+-		break;
+-	case OTP_ALL_RGN:
+-		sz = ((uint) oi->flim - oi->hwbase);
+-		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
+-			*wlen = sz;
+-			return -ENODATA;
+-		}
+-		if (*wlen < sz) {
+-			*wlen = sz;
+-			return -EOVERFLOW;
+-		}
+-		base = oi->hwbase;
+-		break;
+-	default:
+-		return -EINVAL;
+-	}
+-
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	/* Read the data */
+-	for (i = 0; i < sz; i++)
+-		data[i] = ipxotp_otpr(oh, cc, base + i);
+-
+-	ai_setcoreidx(oi->sih, idx);
+-	*wlen = sz;
+-	return 0;
+-}
+-
+-static int ipxotp_nvread(void *oh, char *data, uint *len)
+-{
+-	return -ENOTSUPP;
+-}
+-
+-static otp_fn_t ipxotp_fn = {
+-	(otp_size_t) ipxotp_size,
+-	(otp_read_bit_t) ipxotp_read_bit,
+-
+-	(otp_init_t) ipxotp_init,
+-	(otp_read_region_t) ipxotp_read_region,
+-	(otp_nvread_t) ipxotp_nvread,
+-
+-	(otp_status_t) ipxotp_status
+-};
+-
+-#endif				/* BCMIPXOTP */
+-
+-/*
+- * HND OTP Code
+- *
+- *   Exported functions:
+- *	hndotp_status()
+- *	hndotp_size()
+- *	hndotp_init()
+- *	hndotp_read_bit()
+- *	hndotp_read_region()
+- *	hndotp_nvread()
+- *
+- */
+-
+-#ifdef BCMHNDOTP
+-
+-/* Fields in otpstatus */
+-#define	OTPS_PROGFAIL		0x80000000
+-#define	OTPS_PROTECT		0x00000007
+-#define	OTPS_HW_PROTECT		0x00000001
+-#define	OTPS_SW_PROTECT		0x00000002
+-#define	OTPS_CID_PROTECT	0x00000004
+-#define	OTPS_RCEV_MSK		0x00003f00
+-#define	OTPS_RCEV_SHIFT		8
+-
+-/* Fields in the otpcontrol register */
+-#define	OTPC_RECWAIT		0xff000000
+-#define	OTPC_PROGWAIT		0x00ffff00
+-#define	OTPC_PRW_SHIFT		8
+-#define	OTPC_MAXFAIL		0x00000038
+-#define	OTPC_VSEL		0x00000006
+-#define	OTPC_SELVL		0x00000001
+-
+-/* OTP regions (Word offsets from otp size) */
+-#define	OTP_SWLIM_OFF	(-4)
+-#define	OTP_CIDBASE_OFF	0
+-#define	OTP_CIDLIM_OFF	4
+-
+-/* Predefined OTP words (Word offset from otp size) */
+-#define	OTP_BOUNDARY_OFF (-4)
+-#define	OTP_HWSIGN_OFF	(-3)
+-#define	OTP_SWSIGN_OFF	(-2)
+-#define	OTP_CIDSIGN_OFF	(-1)
+-#define	OTP_CID_OFF	0
+-#define	OTP_PKG_OFF	1
+-#define	OTP_FID_OFF	2
+-#define	OTP_RSV_OFF	3
+-#define	OTP_LIM_OFF	4
+-#define	OTP_RD_OFF	4	/* Redundancy row starts here */
+-#define	OTP_RC0_OFF	28	/* Redundancy control word 1 */
+-#define	OTP_RC1_OFF	32	/* Redundancy control word 2 */
+-#define	OTP_RC_LIM_OFF	36	/* Redundancy control word end */
+-
+-#define	OTP_HW_REGION	OTPS_HW_PROTECT
+-#define	OTP_SW_REGION	OTPS_SW_PROTECT
+-#define	OTP_CID_REGION	OTPS_CID_PROTECT
+-
+-#if OTP_HW_REGION != OTP_HW_RGN
+-#error "incompatible OTP_HW_RGN"
+-#endif
+-#if OTP_SW_REGION != OTP_SW_RGN
+-#error "incompatible OTP_SW_RGN"
+-#endif
+-#if OTP_CID_REGION != OTP_CI_RGN
+-#error "incompatible OTP_CI_RGN"
+-#endif
+-
+-/* Redundancy entry definitions */
+-#define	OTP_RCE_ROW_SZ		6
+-#define	OTP_RCE_SIGN_MASK	0x7fff
+-#define	OTP_RCE_ROW_MASK	0x3f
+-#define	OTP_RCE_BITS		21
+-#define	OTP_RCE_SIGN_SZ		15
+-#define	OTP_RCE_BIT0		1
+-
+-#define	OTP_WPR		4
+-#define	OTP_SIGNATURE	0x578a
+-#define	OTP_MAGIC	0x4e56
+-
+-static int hndotp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->hwprot | oi->signvalid);
+-}
+-
+-static int hndotp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	return (int)(oi->size);
+-}
+-
+-static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+-{
+-	volatile u16 *ptr;
+-
+-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+-	return R_REG(&ptr[wn]);
+-}
+-
+-static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	volatile u16 *ptr;
+-
+-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+-
+-	return R_REG(&ptr[(oi->size / 2) + woff]);
+-}
+-
+-static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
+-{
+-	uint k, row, col;
+-	u32 otpp, st;
+-
+-	row = idx / 65;
+-	col = idx % 65;
+-
+-	otpp = OTPP_START_BUSY | OTPP_READ |
+-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
+-
+-	W_REG(&cc->otpprog, otpp);
+-	st = R_REG(&cc->otpprog);
+-	for (k = 0;
+-	     ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
+-	     k++)
+-		st = R_REG(&cc->otpprog);
+-
+-	if (k >= OTPP_TRIES) {
+-		return 0xffff;
+-	}
+-	if (st & OTPP_READERR) {
+-		return 0xffff;
+-	}
+-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+-	return (u16) st;
+-}
+-
+-static void *hndotp_init(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	otpinfo_t *oi;
+-	u32 cap = 0, clkdiv, otpdiv = 0;
+-	void *ret = NULL;
+-
+-	oi = &otpinfo;
+-
+-	idx = ai_coreidx(sih);
+-
+-	/* Check for otp */
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-	if (cc != NULL) {
+-		cap = R_REG(&cc->capabilities);
+-		if ((cap & CC_CAP_OTPSIZE) == 0) {
+-			/* Nothing there */
+-			goto out;
+-		}
+-
+-		if (!((oi->ccrev == 12) || (oi->ccrev == 17)
+-		     || (oi->ccrev == 22)))
+-			return NULL;
+-
+-		/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
+-		 * 8 row (64 bytes) smaller
+-		 */
+-		oi->size =
+-		    1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
+-			  + CC_CAP_OTPSIZE_BASE);
+-		if (oi->ccrev >= 18)
+-			oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
+-
+-		oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
+-		oi->boundary = -1;
+-
+-		/* Check the region signature */
+-		if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
+-			oi->signvalid |= OTP_HW_REGION;
+-			oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
+-		}
+-
+-		if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
+-			oi->signvalid |= OTP_SW_REGION;
+-
+-		if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
+-			oi->signvalid |= OTP_CID_REGION;
+-
+-		/* Set OTP clkdiv for stability */
+-		if (oi->ccrev == 22)
+-			otpdiv = 12;
+-
+-		if (otpdiv) {
+-			clkdiv = R_REG(&cc->clkdiv);
+-			clkdiv =
+-			    (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
+-			W_REG(&cc->clkdiv, clkdiv);
+-		}
+-		udelay(10);
+-
+-		ret = (void *)oi;
+-	}
+-
+- out:				/* All done */
+-	ai_setcoreidx(sih, idx);
+-
+-	return ret;
+-}
+-
+-static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	u32 idx, st;
+-	chipcregs_t *cc;
+-	int i;
+-
+-
+-	if (region != OTP_HW_REGION) {
+-		/*
+-		 * Only support HW region
+-		 * (no active chips use HND OTP SW region)
+-		 * */
+-		return -ENOTSUPP;
+-	}
+-
+-	/* Region empty? */
+-	st = oi->hwprot | oi->signvalid;
+-	if ((st & region) == 0)
+-		return -ENODATA;
+-
+-	*wlen =
+-	    ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
+-
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	for (i = 0; i < (int)*wlen; i++)
+-		data[i] = hndotp_otpr(oh, cc, i);
+-
+-	ai_setcoreidx(oi->sih, idx);
+-
+-	return 0;
+-}
+-
+-static int hndotp_nvread(void *oh, char *data, uint *len)
+-{
+-	int rc = 0;
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	u32 base, bound, lim = 0, st;
+-	int i, chunk, gchunks, tsz = 0;
+-	u32 idx;
+-	chipcregs_t *cc;
+-	uint offset;
+-	u16 *rawotp = NULL;
+-
+-	/* save the orig core */
+-	idx = ai_coreidx(oi->sih);
+-	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-
+-	st = hndotp_status(oh);
+-	if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
+-		rc = -1;
+-		goto out;
+-	}
+-
+-	/* Read the whole otp so we can easily manipulate it */
+-	lim = hndotp_size(oh);
+-	rawotp = kmalloc(lim, GFP_ATOMIC);
+-	if (rawotp == NULL) {
+-		rc = -2;
+-		goto out;
+-	}
+-	for (i = 0; i < (int)(lim / 2); i++)
+-		rawotp[i] = hndotp_otpr(oh, cc, i);
+-
+-	if ((st & OTP_HW_REGION) == 0) {
+-		/* This could be a programming failure in the first
+-		 * chunk followed by one or more good chunks
+-		 */
+-		for (i = 0; i < (int)(lim / 2); i++)
+-			if (rawotp[i] == OTP_MAGIC)
+-				break;
+-
+-		if (i < (int)(lim / 2)) {
+-			base = i;
+-			bound = (i * 2) + rawotp[i + 1];
+-		} else {
+-			rc = -3;
+-			goto out;
+-		}
+-	} else {
+-		bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
+-
+-		/* There are two cases: 1) The whole otp is used as nvram
+-		 * and 2) There is a hardware header followed by nvram.
+-		 */
+-		if (rawotp[0] == OTP_MAGIC) {
+-			base = 0;
+-		} else
+-			base = bound;
+-	}
+-
+-	/* Find and copy the data */
+-
+-	chunk = 0;
+-	gchunks = 0;
+-	i = base / 2;
+-	offset = 0;
+-	while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
+-		int dsz, rsz = rawotp[i + 1];
+-
+-		if (((i * 2) + rsz) >= (int)lim) {
+-			/* Bad length, try to find another chunk anyway */
+-			rsz = 6;
+-		}
+-		if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) ==
+-			CRC16_GOOD_VALUE) {
+-			/* Good crc, copy the vars */
+-			gchunks++;
+-			dsz = rsz - 6;
+-			tsz += dsz;
+-			if (offset + dsz >= *len) {
+-				goto out;
+-			}
+-			memcpy(&data[offset], &rawotp[i + 2], dsz);
+-			offset += dsz;
+-			/* Remove extra null characters at the end */
+-			while (offset > 1 &&
+-			       data[offset - 1] == 0 && data[offset - 2] == 0)
+-				offset--;
+-			i += rsz / 2;
+-		} else {
+-			/* bad length or crc didn't check, try to find the next set */
+-			if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
+-				/* Assume length is good */
+-				i += rsz / 2;
+-			} else {
+-				while (++i < (int)(lim / 2))
+-					if (rawotp[i] == OTP_MAGIC)
+-						break;
+-			}
+-		}
+-		chunk++;
+-	}
+-
+-	*len = offset;
+-
+- out:
+-	kfree(rawotp);
+-	ai_setcoreidx(oi->sih, idx);
+-
+-	return rc;
+-}
+-
+-static otp_fn_t hndotp_fn = {
+-	(otp_size_t) hndotp_size,
+-	(otp_read_bit_t) hndotp_read_bit,
+-
+-	(otp_init_t) hndotp_init,
+-	(otp_read_region_t) hndotp_read_region,
+-	(otp_nvread_t) hndotp_nvread,
+-
+-	(otp_status_t) hndotp_status
+-};
+-
+-#endif				/* BCMHNDOTP */
+-
+-/*
+- * Common Code: Compiled for IPX / HND / AUTO
+- *	otp_status()
+- *	otp_size()
+- *	otp_read_bit()
+- *	otp_init()
+- * 	otp_read_region()
+- * 	otp_nvread()
+- */
+-
+-int otp_status(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->status(oh);
+-}
+-
+-int otp_size(void *oh)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->size(oh);
+-}
+-
+-u16 otp_read_bit(void *oh, uint offset)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-	uint idx = ai_coreidx(oi->sih);
+-	chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+-	u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
+-	ai_setcoreidx(oi->sih, idx);
+-	return readBit;
+-}
+-
+-void *otp_init(si_t *sih)
+-{
+-	otpinfo_t *oi;
+-	void *ret = NULL;
+-
+-	oi = &otpinfo;
+-	memset(oi, 0, sizeof(otpinfo_t));
+-
+-	oi->ccrev = sih->ccrev;
+-
+-#ifdef BCMIPXOTP
+-	if (OTPTYPE_IPX(oi->ccrev))
+-		oi->fn = &ipxotp_fn;
+-#endif
+-
+-#ifdef BCMHNDOTP
+-	if (OTPTYPE_HND(oi->ccrev))
+-		oi->fn = &hndotp_fn;
+-#endif
+-
+-	if (oi->fn == NULL) {
+-		return NULL;
+-	}
+-
+-	oi->sih = sih;
+-
+-	ret = (oi->fn->init) (sih);
+-
+-	return ret;
+-}
+-
+-int
+-otp_read_region(si_t *sih, int region, u16 *data,
+-				 uint *wlen) {
+-	bool wasup = false;
+-	void *oh;
+-	int err = 0;
+-
+-	wasup = ai_is_otp_powered(sih);
+-	if (!wasup)
+-		ai_otp_power(sih, true);
+-
+-	if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) {
+-		err = -EPERM;
+-		goto out;
+-	}
+-
+-	oh = otp_init(sih);
+-	if (oh == NULL) {
+-		err = -EBADE;
+-		goto out;
+-	}
+-
+-	err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
+-
+- out:
+-	if (!wasup)
+-		ai_otp_power(sih, false);
+-
+-	return err;
+-}
+-
+-int otp_nvread(void *oh, char *data, uint *len)
+-{
+-	otpinfo_t *oi = (otpinfo_t *) oh;
+-
+-	return oi->fn->nvread(oh, data, len);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c
+deleted file mode 100644
+index bbfc642..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c
++++ /dev/null
+@@ -1,714 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/etherdevice.h>
+-#include <bcmdefs.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <stdarg.h>
+-#include <bcmutils.h>
+-#include <hndsoc.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <pcicfg.h>
+-#include <aiutils.h>
+-#include <bcmsrom.h>
+-#include <bcmsrom_tbl.h>
+-
+-#include <bcmnvram.h>
+-#include <bcmotp.h>
+-
+-#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
+-	(((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
+-	 ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
+-	((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
+-
+-#if defined(BCMDBG)
+-#define WRITE_ENABLE_DELAY	500	/* 500 ms after write enable/disable toggle */
+-#define WRITE_WORD_DELAY	20	/* 20 ms between each word write */
+-#endif
+-
+-typedef struct varbuf {
+-	char *base;		/* pointer to buffer base */
+-	char *buf;		/* pointer to current position */
+-	unsigned int size;	/* current (residual) size in bytes */
+-} varbuf_t;
+-extern char *_vars;
+-extern uint _varsz;
+-
+-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count);
+-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b);
+-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
+-static int initvars_flash_si(si_t *sih, char **vars, uint *count);
+-static int sprom_read_pci(si_t *sih, u16 *sprom,
+-			  uint wordoff, u16 *buf, uint nwords, bool check_crc);
+-#if defined(BCMNVRAMR)
+-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz);
+-#endif
+-static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+-			  uint wordoff, u16 data);
+-
+-static int initvars_table(char *start, char *end,
+-			  char **vars, uint *count);
+-static int initvars_flash(si_t *sih, char **vp,
+-			  uint len);
+-
+-/* Initialization of varbuf structure */
+-static void varbuf_init(varbuf_t *b, char *buf, uint size)
+-{
+-	b->size = size;
+-	b->base = b->buf = buf;
+-}
+-
+-/* append a null terminated var=value string */
+-static int varbuf_append(varbuf_t *b, const char *fmt, ...)
+-{
+-	va_list ap;
+-	int r;
+-	size_t len;
+-	char *s;
+-
+-	if (b->size < 2)
+-		return 0;
+-
+-	va_start(ap, fmt);
+-	r = vsnprintf(b->buf, b->size, fmt, ap);
+-	va_end(ap);
+-
+-	/* C99 snprintf behavior returns r >= size on overflow,
+-	 * others return -1 on overflow.
+-	 * All return -1 on format error.
+-	 * We need to leave room for 2 null terminations, one for the current var
+-	 * string, and one for final null of the var table. So check that the
+-	 * strlen written, r, leaves room for 2 chars.
+-	 */
+-	if ((r == -1) || (r > (int)(b->size - 2))) {
+-		b->size = 0;
+-		return 0;
+-	}
+-
+-	/* Remove any earlier occurrence of the same variable */
+-	s = strchr(b->buf, '=');
+-	if (s != NULL) {
+-		len = (size_t) (s - b->buf);
+-		for (s = b->base; s < b->buf;) {
+-			if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
+-				len = strlen(s) + 1;
+-				memmove(s, (s + len),
+-					((b->buf + r + 1) - (s + len)));
+-				b->buf -= len;
+-				b->size += (unsigned int)len;
+-				break;
+-			}
+-
+-			while (*s++)
+-				;
+-		}
+-	}
+-
+-	/* skip over this string's null termination */
+-	r++;
+-	b->size -= r;
+-	b->buf += r;
+-
+-	return r;
+-}
+-
+-/*
+- * Initialize local vars from the right source for this platform.
+- * Return 0 on success, nonzero on error.
+- */
+-int srom_var_init(si_t *sih, uint bustype, void *curmap,
+-		  char **vars, uint *count)
+-{
+-	uint len;
+-
+-	len = 0;
+-
+-	if (vars == NULL || count == NULL)
+-		return 0;
+-
+-	*vars = NULL;
+-	*count = 0;
+-
+-	switch (bustype) {
+-	case SI_BUS:
+-	case JTAG_BUS:
+-		return initvars_srom_si(sih, curmap, vars, count);
+-
+-	case PCI_BUS:
+-		if (curmap == NULL)
+-			return -1;
+-
+-		return initvars_srom_pci(sih, curmap, vars, count);
+-
+-	default:
+-		break;
+-	}
+-	return -1;
+-}
+-
+-/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
+- * not in the bus cores.
+- */
+-static u16
+-srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+-	    uint wordoff, u16 data)
+-{
+-	chipcregs_t *cc = (chipcregs_t *) ccregs;
+-	uint wait_cnt = 1000;
+-
+-	if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
+-		W_REG(&cc->sromaddress, wordoff * 2);
+-		if (cmd == SRC_OP_WRITE)
+-			W_REG(&cc->sromdata, data);
+-	}
+-
+-	W_REG(&cc->sromcontrol, SRC_START | cmd);
+-
+-	while (wait_cnt--) {
+-		if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0)
+-			break;
+-	}
+-
+-	if (!wait_cnt) {
+-		return 0xffff;
+-	}
+-	if (cmd == SRC_OP_READ)
+-		return (u16) R_REG(&cc->sromdata);
+-	else
+-		return 0xffff;
+-}
+-
+-static inline void ltoh16_buf(u16 *buf, unsigned int size)
+-{
+-	for (size /= 2; size; size--)
+-		*(buf + size) = le16_to_cpu(*(buf + size));
+-}
+-
+-static inline void htol16_buf(u16 *buf, unsigned int size)
+-{
+-	for (size /= 2; size; size--)
+-		*(buf + size) = cpu_to_le16(*(buf + size));
+-}
+-
+-/*
+- * Read in and validate sprom.
+- * Return 0 on success, nonzero on error.
+- */
+-static int
+-sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff,
+-	       u16 *buf, uint nwords, bool check_crc)
+-{
+-	int err = 0;
+-	uint i;
+-	void *ccregs = NULL;
+-
+-	/* read the sprom */
+-	for (i = 0; i < nwords; i++) {
+-
+-		if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
+-			/* use indirect since direct is too slow on QT */
+-			if ((sih->cccaps & CC_CAP_SROM) == 0)
+-				return 1;
+-
+-			ccregs = (void *)((u8 *) sprom - CC_SROM_OTP);
+-			buf[i] =
+-			    srom_cc_cmd(sih, ccregs, SRC_OP_READ,
+-					wordoff + i, 0);
+-
+-		} else {
+-			if (ISSIM_ENAB(sih))
+-				buf[i] = R_REG(&sprom[wordoff + i]);
+-
+-			buf[i] = R_REG(&sprom[wordoff + i]);
+-		}
+-
+-	}
+-
+-	/* bypass crc checking for simulation to allow srom hack */
+-	if (ISSIM_ENAB(sih))
+-		return err;
+-
+-	if (check_crc) {
+-
+-		if (buf[0] == 0xffff) {
+-			/* The hardware thinks that an srom that starts with 0xffff
+-			 * is blank, regardless of the rest of the content, so declare
+-			 * it bad.
+-			 */
+-			return 1;
+-		}
+-
+-		/* fixup the endianness so crc8 will pass */
+-		htol16_buf(buf, nwords * 2);
+-		if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
+-		    CRC8_GOOD_VALUE) {
+-			/* DBG only pci always read srom4 first, then srom8/9 */
+-			err = 1;
+-		}
+-		/* now correct the endianness of the byte array */
+-		ltoh16_buf(buf, nwords * 2);
+-	}
+-	return err;
+-}
+-
+-#if defined(BCMNVRAMR)
+-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz)
+-{
+-	u8 *otp;
+-	uint sz = OTP_SZ_MAX / 2;	/* size in words */
+-	int err = 0;
+-
+-	otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
+-	if (otp == NULL) {
+-		return -EBADE;
+-	}
+-
+-	err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
+-
+-	memcpy(buf, otp, bufsz);
+-
+-	kfree(otp);
+-
+-	/* Check CRC */
+-	if (buf[0] == 0xffff) {
+-		/* The hardware thinks that an srom that starts with 0xffff
+-		 * is blank, regardless of the rest of the content, so declare
+-		 * it bad.
+-		 */
+-		return 1;
+-	}
+-
+-	/* fixup the endianness so crc8 will pass */
+-	htol16_buf(buf, bufsz);
+-	if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
+-	    CRC8_GOOD_VALUE) {
+-		err = 1;
+-	}
+-	/* now correct the endianness of the byte array */
+-	ltoh16_buf(buf, bufsz);
+-
+-	return err;
+-}
+-#endif				/* defined(BCMNVRAMR) */
+-/*
+-* Create variable table from memory.
+-* Return 0 on success, nonzero on error.
+-*/
+-static int initvars_table(char *start, char *end,
+-			  char **vars, uint *count)
+-{
+-	int c = (int)(end - start);
+-
+-	/* do it only when there is more than just the null string */
+-	if (c > 1) {
+-		char *vp = kmalloc(c, GFP_ATOMIC);
+-		if (!vp)
+-			return -ENOMEM;
+-		memcpy(vp, start, c);
+-		*vars = vp;
+-		*count = c;
+-	} else {
+-		*vars = NULL;
+-		*count = 0;
+-	}
+-
+-	return 0;
+-}
+-
+-/*
+- * Find variables with <devpath> from flash. 'base' points to the beginning
+- * of the table upon enter and to the end of the table upon exit when success.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_flash(si_t *sih, char **base, uint len)
+-{
+-	char *vp = *base;
+-	char *flash;
+-	int err;
+-	char *s;
+-	uint l, dl, copy_len;
+-	char devpath[SI_DEVPATH_BUFSZ];
+-
+-	/* allocate memory and read in flash */
+-	flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC);
+-	if (!flash)
+-		return -ENOMEM;
+-	err = nvram_getall(flash, NVRAM_SPACE);
+-	if (err)
+-		goto exit;
+-
+-	ai_devpath(sih, devpath, sizeof(devpath));
+-
+-	/* grab vars with the <devpath> prefix in name */
+-	dl = strlen(devpath);
+-	for (s = flash; s && *s; s += l + 1) {
+-		l = strlen(s);
+-
+-		/* skip non-matching variable */
+-		if (strncmp(s, devpath, dl))
+-			continue;
+-
+-		/* is there enough room to copy? */
+-		copy_len = l - dl + 1;
+-		if (len < copy_len) {
+-			err = -EOVERFLOW;
+-			goto exit;
+-		}
+-
+-		/* no prefix, just the name=value */
+-		strncpy(vp, &s[dl], copy_len);
+-		vp += copy_len;
+-		len -= copy_len;
+-	}
+-
+-	/* add null string as terminator */
+-	if (len < 1) {
+-		err = -EOVERFLOW;
+-		goto exit;
+-	}
+-	*vp++ = '\0';
+-
+-	*base = vp;
+-
+- exit:	kfree(flash);
+-	return err;
+-}
+-
+-/*
+- * Initialize nonvolatile variable table from flash.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_flash_si(si_t *sih, char **vars, uint *count)
+-{
+-	char *vp, *base;
+-	int err;
+-
+-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+-	if (!vp)
+-		return -ENOMEM;
+-
+-	err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+-	if (err == 0)
+-		err = initvars_table(base, vp, vars, count);
+-
+-	kfree(base);
+-
+-	return err;
+-}
+-
+-/* Parse SROM and create name=value pairs. 'srom' points to
+- * the SROM word array. 'off' specifies the offset of the
+- * first word 'srom' points to, which should be either 0 or
+- * SROM3_SWRG_OFF (full SROM or software region).
+- */
+-
+-static uint mask_shift(u16 mask)
+-{
+-	uint i;
+-	for (i = 0; i < (sizeof(mask) << 3); i++) {
+-		if (mask & (1 << i))
+-			return i;
+-	}
+-	return 0;
+-}
+-
+-static uint mask_width(u16 mask)
+-{
+-	int i;
+-	for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
+-		if (mask & (1 << i))
+-			return (uint) (i - mask_shift(mask) + 1);
+-	}
+-	return 0;
+-}
+-
+-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b)
+-{
+-	u16 w;
+-	u32 val;
+-	const sromvar_t *srv;
+-	uint width;
+-	uint flags;
+-	u32 sr = (1 << sromrev);
+-
+-	varbuf_append(b, "sromrev=%d", sromrev);
+-
+-	for (srv = pci_sromvars; srv->name != NULL; srv++) {
+-		const char *name;
+-
+-		if ((srv->revmask & sr) == 0)
+-			continue;
+-
+-		if (srv->off < off)
+-			continue;
+-
+-		flags = srv->flags;
+-		name = srv->name;
+-
+-		/* This entry is for mfgc only. Don't generate param for it, */
+-		if (flags & SRFL_NOVAR)
+-			continue;
+-
+-		if (flags & SRFL_ETHADDR) {
+-			u8 ea[ETH_ALEN];
+-
+-			ea[0] = (srom[srv->off - off] >> 8) & 0xff;
+-			ea[1] = srom[srv->off - off] & 0xff;
+-			ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
+-			ea[3] = srom[srv->off + 1 - off] & 0xff;
+-			ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
+-			ea[5] = srom[srv->off + 2 - off] & 0xff;
+-
+-			varbuf_append(b, "%s=%pM", name, ea);
+-		} else {
+-			w = srom[srv->off - off];
+-			val = (w & srv->mask) >> mask_shift(srv->mask);
+-			width = mask_width(srv->mask);
+-
+-			while (srv->flags & SRFL_MORE) {
+-				srv++;
+-				if (srv->off == 0 || srv->off < off)
+-					continue;
+-
+-				w = srom[srv->off - off];
+-				val +=
+-				    ((w & srv->mask) >> mask_shift(srv->
+-								   mask)) <<
+-				    width;
+-				width += mask_width(srv->mask);
+-			}
+-
+-			if ((flags & SRFL_NOFFS)
+-			    && ((int)val == (1 << width) - 1))
+-				continue;
+-
+-			if (flags & SRFL_CCODE) {
+-				if (val == 0)
+-					varbuf_append(b, "ccode=");
+-				else
+-					varbuf_append(b, "ccode=%c%c",
+-						      (val >> 8), (val & 0xff));
+-			}
+-			/* LED Powersave duty cycle has to be scaled:
+-			 *(oncount >> 24) (offcount >> 8)
+-			 */
+-			else if (flags & SRFL_LEDDC) {
+-				u32 w32 = (((val >> 8) & 0xff) << 24) |	/* oncount */
+-				    (((val & 0xff)) << 8);	/* offcount */
+-				varbuf_append(b, "leddc=%d", w32);
+-			} else if (flags & SRFL_PRHEX)
+-				varbuf_append(b, "%s=0x%x", name, val);
+-			else if ((flags & SRFL_PRSIGN)
+-				 && (val & (1 << (width - 1))))
+-				varbuf_append(b, "%s=%d", name,
+-					      (int)(val | (~0 << width)));
+-			else
+-				varbuf_append(b, "%s=%u", name, val);
+-		}
+-	}
+-
+-	if (sromrev >= 4) {
+-		/* Do per-path variables */
+-		uint p, pb, psz;
+-
+-		if (sromrev >= 8) {
+-			pb = SROM8_PATH0;
+-			psz = SROM8_PATH1 - SROM8_PATH0;
+-		} else {
+-			pb = SROM4_PATH0;
+-			psz = SROM4_PATH1 - SROM4_PATH0;
+-		}
+-
+-		for (p = 0; p < MAX_PATH_SROM; p++) {
+-			for (srv = perpath_pci_sromvars; srv->name != NULL;
+-			     srv++) {
+-				if ((srv->revmask & sr) == 0)
+-					continue;
+-
+-				if (pb + srv->off < off)
+-					continue;
+-
+-				/* This entry is for mfgc only. Don't generate param for it, */
+-				if (srv->flags & SRFL_NOVAR)
+-					continue;
+-
+-				w = srom[pb + srv->off - off];
+-				val = (w & srv->mask) >> mask_shift(srv->mask);
+-				width = mask_width(srv->mask);
+-
+-				/* Cheating: no per-path var is more than 1 word */
+-
+-				if ((srv->flags & SRFL_NOFFS)
+-				    && ((int)val == (1 << width) - 1))
+-					continue;
+-
+-				if (srv->flags & SRFL_PRHEX)
+-					varbuf_append(b, "%s%d=0x%x", srv->name,
+-						      p, val);
+-				else
+-					varbuf_append(b, "%s%d=%d", srv->name,
+-						      p, val);
+-			}
+-			pb += psz;
+-		}
+-	}
+-}
+-
+-/*
+- * Initialize nonvolatile variable table from sprom.
+- * Return 0 on success, nonzero on error.
+- */
+-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count)
+-{
+-	u16 *srom, *sromwindow;
+-	u8 sromrev = 0;
+-	u32 sr;
+-	varbuf_t b;
+-	char *vp, *base = NULL;
+-	bool flash = false;
+-	int err = 0;
+-
+-	/*
+-	 * Apply CRC over SROM content regardless SROM is present or not,
+-	 * and use variable <devpath>sromrev's existence in flash to decide
+-	 * if we should return an error when CRC fails or read SROM variables
+-	 * from flash.
+-	 */
+-	srom = kmalloc(SROM_MAX, GFP_ATOMIC);
+-	if (!srom)
+-		return -2;
+-
+-	sromwindow = (u16 *) SROM_OFFSET(sih);
+-	if (ai_is_sprom_available(sih)) {
+-		err =
+-		    sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
+-				   true);
+-
+-		if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
+-		    (((sih->buscoretype == PCIE_CORE_ID)
+-		      && (sih->buscorerev >= 6))
+-		     || ((sih->buscoretype == PCI_CORE_ID)
+-			 && (sih->buscorerev >= 0xe)))) {
+-			/* sromrev >= 4, read more */
+-			err =
+-			    sprom_read_pci(sih, sromwindow, 0, srom,
+-					   SROM4_WORDS, true);
+-			sromrev = srom[SROM4_CRCREV] & 0xff;
+-		} else if (err == 0) {
+-			/* srom is good and is rev < 4 */
+-			/* top word of sprom contains version and crc8 */
+-			sromrev = srom[SROM_CRCREV] & 0xff;
+-			/* bcm4401 sroms misprogrammed */
+-			if (sromrev == 0x10)
+-				sromrev = 1;
+-		}
+-	}
+-#if defined(BCMNVRAMR)
+-	/* Use OTP if SPROM not available */
+-	else {
+-		err = otp_read_pci(sih, srom, SROM_MAX);
+-		if (err == 0)
+-			/* OTP only contain SROM rev8/rev9 for now */
+-			sromrev = srom[SROM4_CRCREV] & 0xff;
+-		else
+-			err = 1;
+-	}
+-#else
+-	else
+-		err = 1;
+-#endif
+-
+-	/*
+-	 * We want internal/wltest driver to come up with default
+-	 * sromvars so we can program a blank SPROM/OTP.
+-	 */
+-	if (err) {
+-		char *value;
+-		u32 val;
+-		val = 0;
+-
+-		value = ai_getdevpathvar(sih, "sromrev");
+-		if (value) {
+-			sromrev = (u8) simple_strtoul(value, NULL, 0);
+-			flash = true;
+-			goto varscont;
+-		}
+-
+-		value = ai_getnvramflvar(sih, "sromrev");
+-		if (value) {
+-			err = 0;
+-			goto errout;
+-		}
+-
+-		{
+-			err = -1;
+-			goto errout;
+-		}
+-	}
+-
+- varscont:
+-	/* Bitmask for the sromrev */
+-	sr = 1 << sromrev;
+-
+-	/* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
+-	if ((sr & 0x33e) == 0) {
+-		err = -2;
+-		goto errout;
+-	}
+-
+-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+-	if (!vp) {
+-		err = -2;
+-		goto errout;
+-	}
+-
+-	/* read variables from flash */
+-	if (flash) {
+-		err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+-		if (err)
+-			goto errout;
+-		goto varsdone;
+-	}
+-
+-	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
+-
+-	/* parse SROM into name=value pairs. */
+-	_initvars_srom_pci(sromrev, srom, 0, &b);
+-
+-	/* final nullbyte terminator */
+-	vp = b.buf;
+-	*vp++ = '\0';
+-
+- varsdone:
+-	err = initvars_table(base, vp, vars, count);
+-
+- errout:
+-	if (base)
+-		kfree(base);
+-
+-	kfree(srom);
+-	return err;
+-}
+-
+-
+-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz)
+-{
+-	/* Search flash nvram section for srom variables */
+-	return initvars_flash_si(sih, vars, varsz);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h b/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
+deleted file mode 100644
+index f4b3e61..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
++++ /dev/null
+@@ -1,513 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_tbl_h_
+-#define	_bcmsrom_tbl_h_
+-
+-#include "wlioctl.h"
+-
+-typedef struct {
+-	const char *name;
+-	u32 revmask;
+-	u32 flags;
+-	u16 off;
+-	u16 mask;
+-} sromvar_t;
+-
+-#define SRFL_MORE	1	/* value continues as described by the next entry */
+-#define	SRFL_NOFFS	2	/* value bits can't be all one's */
+-#define	SRFL_PRHEX	4	/* value is in hexdecimal format */
+-#define	SRFL_PRSIGN	8	/* value is in signed decimal format */
+-#define	SRFL_CCODE	0x10	/* value is in country code format */
+-#define	SRFL_ETHADDR	0x20	/* value is an Ethernet address */
+-#define SRFL_LEDDC	0x40	/* value is an LED duty cycle */
+-#define SRFL_NOVAR	0x80	/* do not generate a nvram param, entry is for mfgc */
+-
+-/* Assumptions:
+- * - Ethernet address spans across 3 consective words
+- *
+- * Table rules:
+- * - Add multiple entries next to each other if a value spans across multiple words
+- *   (even multiple fields in the same word) with each entry except the last having
+- *   it's SRFL_MORE bit set.
+- * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
+- *   bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
+- * - The last entry's name field must be NULL to indicate the end of the table. Other
+- *   entries must have non-NULL name.
+- */
+-
+-static const sromvar_t pci_sromvars[] = {
+-	{"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
+-	{"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
+-	{"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
+-	{"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
+-	{"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
+-	{"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+-	{"", 0, 0, SROM_BFL2, 0xffff},
+-	{"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+-	{"", 0, 0, SROM3_BFL2, 0xffff},
+-	{"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
+-	{"", 0, 0, SROM4_BFL1, 0xffff},
+-	{"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
+-	{"", 0, 0, SROM5_BFL1, 0xffff},
+-	{"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
+-	{"", 0, 0, SROM8_BFL1, 0xffff},
+-	{"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
+-	{"", 0, 0, SROM4_BFL3, 0xffff},
+-	{"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
+-	{"", 0, 0, SROM5_BFL3, 0xffff},
+-	{"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
+-	{"", 0, 0, SROM8_BFL3, 0xffff},
+-	{"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
+-	{"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
+-	{"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
+-	{"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
+-	{"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
+-	{"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
+-	{"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
+-	{"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
+-	{"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
+-	{"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
+-	{"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
+-	{"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
+-	{"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
+-	{"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
+-	{"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
+-	{"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
+-	{"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
+-	{"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
+-	{"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
+-	{"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
+-	{"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
+-	{"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
+-	{"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
+-	{"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
+-	{"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
+-	{"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
+-	{"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
+-	{"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
+-	{"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
+-	{"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
+-	{"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
+-	{"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
+-	{"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
+-	{"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
+-	{"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
+-	{"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
+-	{"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
+-	{"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
+-	{"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
+-	{"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
+-	{"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
+-	{"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
+-	{"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
+-	{"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
+-	{"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
+-	{"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
+-	{"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
+-	{"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
+-	{"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
+-	{"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
+-	{"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
+-	{"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
+-	{"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
+-	{"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
+-	{"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
+-	{"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
+-	{"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
+-	{"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
+-	{"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
+-	{"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
+-	{"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
+-	{"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
+-	{"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
+-	{"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
+-	{"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
+-	{"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
+-	{"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
+-	{"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
+-	{"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
+-	{"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
+-	{"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
+-	{"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
+-	{"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
+-	{"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
+-	{"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
+-	{"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
+-	{"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
+-	{"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
+-	{"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
+-	{"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
+-	{"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
+-	{"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
+-	{"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
+-	{"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
+-	{"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
+-	{"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
+-	{"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
+-	{"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
+-	{"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
+-	{"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
+-	{"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
+-	{"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
+-	{"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
+-	{"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
+-	{"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
+-	{"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
+-	{"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
+-	{"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
+-	{"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
+-	{"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
+-	{"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
+-	{"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
+-	{"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
+-	{"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
+-	{"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
+-	{"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
+-	{"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
+-	{"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
+-	{"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
+-	{"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
+-	{"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
+-	{"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
+-	{"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
+-	{"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
+-	{"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
+-	{"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
+-	{"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
+-	{"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
+-	{"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
+-	{"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
+-	{"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
+-	{"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
+-	{"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
+-	{"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
+-	{"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
+-	{"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
+-	{"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
+-	{"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
+-	{"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
+-	{"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
+-	{"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
+-	{"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
+-	{"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
+-	{"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
+-	{"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
+-	{"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
+-	{"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
+-	{"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
+-	{"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
+-
+-	{"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
+-	{"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
+-	{"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
+-	{"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
+-	{"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
+-	{"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
+-	{"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
+-	{"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
+-	{"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
+-	{"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
+-	{"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
+-	{"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
+-	{"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
+-	{"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
+-	{"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
+-	{"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
+-	{"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+-	 0x00ff},
+-	{"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
+-	{"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+-	 0x0300},
+-	{"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
+-	 0x000f},
+-	{"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
+-	{"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
+-	{"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
+-
+-	{"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
+-	{"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
+-	{"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
+-	{"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
+-	{"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
+-	{"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
+-	{"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
+-	{"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
+-	{"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
+-	{"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
+-	{"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
+-	{"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
+-	{"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
+-	{"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
+-	{"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
+-	{"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
+-	{"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
+-	{"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
+-	{"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
+-	{"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
+-	{"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
+-	{"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
+-	{"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
+-	{"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
+-	{"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
+-	{"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
+-	{"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
+-	{"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
+-	{"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
+-	{"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
+-	{"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
+-	{"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
+-	{"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
+-	{"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
+-	{"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
+-	{"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
+-	{"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
+-	{"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
+-	{"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
+-	{"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
+-	{"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
+-	{"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
+-	{"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
+-	{"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
+-	{"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
+-	{"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
+-	{"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
+-	{"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
+-	{"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
+-	{"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
+-	{"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
+-	{"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
+-	{"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
+-	{"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
+-	{"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
+-	{"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
+-	{"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
+-	{"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
+-	{"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
+-	{"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
+-	{"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
+-	{"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
+-	{"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
+-	{"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
+-	{"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
+-	{"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
+-	{"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
+-	{"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
+-	{"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
+-	{"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
+-	{"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
+-	{"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
+-	{"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
+-	{"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
+-	{"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
+-	{"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
+-	{"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
+-	{"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
+-	{"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
+-	{"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
+-	{"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
+-	{"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
+-	{"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
+-
+-	/* power per rate from sromrev 9 */
+-	{"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
+-	{"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
+-	{"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
+-	{"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
+-	{"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
+-	{"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
+-	{"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
+-	{"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
+-	 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
+-	{"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
+-	{"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
+-	{"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
+-	{"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
+-
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-static const sromvar_t perpath_pci_sromvars[] = {
+-	{"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
+-	{"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
+-	{"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
+-	{"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
+-	{"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
+-	{"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
+-	{"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
+-	{"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
+-	{"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
+-	{"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
+-	{"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
+-	{"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
+-	{"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
+-	{"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
+-	{"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
+-	{"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
+-	{"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
+-	{"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
+-	{"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
+-	{"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
+-	{"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
+-	{"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
+-	{"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
+-	{"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
+-	{"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
+-	{"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
+-	{"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
+-	{"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
+-	{"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
+-	{"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
+-	{"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
+-	{"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
+-	{"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
+-	{"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
+-	{"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
+-	{"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
+-	{"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
+-	{"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
+-	{"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
+-	{"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
+-#define	PHY_TYPE_N		4	/* N-Phy value */
+-#define	PHY_TYPE_LP		5	/* LP-Phy value */
+-#endif				/* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
+-#if !defined(PHY_TYPE_NULL)
+-#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
+-#endif				/* !defined(PHY_TYPE_NULL) */
+-
+-typedef struct {
+-	u16 phy_type;
+-	u16 bandrange;
+-	u16 chain;
+-	const char *vars;
+-} pavars_t;
+-
+-static const pavars_t pavars[] = {
+-	/* NPHY */
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0,
+-	 "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1,
+-	 "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0,
+-	 "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1,
+-	 "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
+-	/* LPPHY */
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
+-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
+-	{PHY_TYPE_NULL, 0, 0, ""}
+-};
+-
+-typedef struct {
+-	u16 phy_type;
+-	u16 bandrange;
+-	const char *vars;
+-} povars_t;
+-
+-static const povars_t povars[] = {
+-	/* NPHY */
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
+-	 "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
+-	 "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
+-	 "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
+-	 "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
+-	 "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
+-	 "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
+-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
+-	 "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
+-	 "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
+-	{PHY_TYPE_NULL, 0, ""}
+-};
+-
+-typedef struct {
+-	u8 tag;		/* Broadcom subtag name */
+-	u8 len;		/* Length field of the tuple, note that it includes the
+-				 * subtag name (1 byte): 1 + tuple content length
+-				 */
+-	const char *params;
+-} cis_tuple_t;
+-
+-#define OTP_RAW		(0xff - 1)	/* Reserved tuple number for wrvar Raw input */
+-#define OTP_VERS_1	(0xff - 2)	/* CISTPL_VERS_1 */
+-#define OTP_MANFID	(0xff - 3)	/* CISTPL_MANFID */
+-#define OTP_RAW1	(0xff - 4)	/* Like RAW, but comes first */
+-
+-#endif				/* _bcmsrom_tbl_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h
+deleted file mode 100644
+index d91e418..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/d11.h
++++ /dev/null
+@@ -1,1773 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_D11_H
+-#define	_D11_H
+-
+-#include <sbconfig.h>
+-
+-#ifndef WL_RSSI_ANT_MAX
+-#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
+-#elif WL_RSSI_ANT_MAX != 4
+-#error "WL_RSSI_ANT_MAX does not match"
+-#endif
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef	PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-#define	BCN_TMPL_LEN		512	/* length of the BCN template area */
+-
+-/* RX FIFO numbers */
+-#define	RX_FIFO			0	/* data and ctl frames */
+-#define	RX_TXSTATUS_FIFO	3	/* RX fifo for tx status packages */
+-
+-/* TX FIFO numbers using WME Access Classes */
+-#define	TX_AC_BK_FIFO		0	/* Access Category Background TX FIFO */
+-#define	TX_AC_BE_FIFO		1	/* Access Category Best-Effort TX FIFO */
+-#define	TX_AC_VI_FIFO		2	/* Access Class Video TX FIFO */
+-#define	TX_AC_VO_FIFO		3	/* Access Class Voice TX FIFO */
+-#define	TX_BCMC_FIFO		4	/* Broadcast/Multicast TX FIFO */
+-#define	TX_ATIM_FIFO		5	/* TX fifo for ATIM window info */
+-
+-/* Addr is byte address used by SW; offset is word offset used by uCode */
+-
+-/* Per AC TX limit settings */
+-#define M_AC_TXLMT_BASE_ADDR         (0x180 * 2)
+-#define M_AC_TXLMT_ADDR(_ac)         (M_AC_TXLMT_BASE_ADDR + (2 * (_ac)))
+-
+-/* Legacy TX FIFO numbers */
+-#define	TX_DATA_FIFO		TX_AC_BE_FIFO
+-#define	TX_CTL_FIFO		TX_AC_VO_FIFO
+-
+-typedef volatile struct {
+-	u32 intstatus;
+-	u32 intmask;
+-} intctrlregs_t;
+-
+-/* PIO structure,
+- *  support two PIO format: 2 bytes access and 4 bytes access
+- *  basic FIFO register set is per channel(transmit or receive)
+- *  a pair of channels is defined for convenience
+- */
+-/* 2byte-wide pio register set per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u16 fifocontrol;
+-	u16 fifodata;
+-	u16 fifofree;	/* only valid in xmt channel, not in rcv channel */
+-	u16 PAD;
+-} pio2regs_t;
+-
+-/* a pair of pio channels(tx and rx) */
+-typedef volatile struct {
+-	pio2regs_t tx;
+-	pio2regs_t rx;
+-} pio2regp_t;
+-
+-/* 4byte-wide pio register set per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 fifocontrol;
+-	u32 fifodata;
+-} pio4regs_t;
+-
+-/* a pair of pio channels(tx and rx) */
+-typedef volatile struct {
+-	pio4regs_t tx;
+-	pio4regs_t rx;
+-} pio4regp_t;
+-
+-/* read: 32-bit register that can be read as 32-bit or as 2 16-bit
+- * write: only low 16b-it half can be written
+- */
+-typedef volatile union {
+-	u32 pmqhostdata;	/* read only! */
+-	struct {
+-		u16 pmqctrlstatus;	/* read/write */
+-		u16 PAD;
+-	} w;
+-} pmqreg_t;
+-
+-typedef volatile struct {
+-	dma64regs_t dmaxmt;	/* dma tx */
+-	pio4regs_t piotx;	/* pio tx */
+-	dma64regs_t dmarcv;	/* dma rx */
+-	pio4regs_t piorx;	/* pio rx */
+-} fifo64_t;
+-
+-/*
+- * Host Interface Registers
+- * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h
+- * - but definitely not complete
+- */
+-typedef volatile struct _d11regs {
+-	/* Device Control ("semi-standard host registers") */
+-	u32 PAD[3];		/* 0x0 - 0x8 */
+-	u32 biststatus;	/* 0xC */
+-	u32 biststatus2;	/* 0x10 */
+-	u32 PAD;		/* 0x14 */
+-	u32 gptimer;		/* 0x18 */
+-	u32 usectimer;	/* 0x1c *//* for corerev >= 26 */
+-
+-	/* Interrupt Control *//* 0x20 */
+-	intctrlregs_t intctrlregs[8];
+-
+-	u32 PAD[40];		/* 0x60 - 0xFC */
+-
+-	u32 intrcvlazy[4];	/* 0x100 - 0x10C */
+-
+-	u32 PAD[4];		/* 0x110 - 0x11c */
+-
+-	u32 maccontrol;	/* 0x120 */
+-	u32 maccommand;	/* 0x124 */
+-	u32 macintstatus;	/* 0x128 */
+-	u32 macintmask;	/* 0x12C */
+-
+-	/* Transmit Template Access */
+-	u32 tplatewrptr;	/* 0x130 */
+-	u32 tplatewrdata;	/* 0x134 */
+-	u32 PAD[2];		/* 0x138 - 0x13C */
+-
+-	/* PMQ registers */
+-	pmqreg_t pmqreg;	/* 0x140 */
+-	u32 pmqpatl;		/* 0x144 */
+-	u32 pmqpath;		/* 0x148 */
+-	u32 PAD;		/* 0x14C */
+-
+-	u32 chnstatus;	/* 0x150 */
+-	u32 psmdebug;	/* 0x154 */
+-	u32 phydebug;	/* 0x158 */
+-	u32 machwcap;	/* 0x15C */
+-
+-	/* Extended Internal Objects */
+-	u32 objaddr;		/* 0x160 */
+-	u32 objdata;		/* 0x164 */
+-	u32 PAD[2];		/* 0x168 - 0x16c */
+-
+-	u32 frmtxstatus;	/* 0x170 */
+-	u32 frmtxstatus2;	/* 0x174 */
+-	u32 PAD[2];		/* 0x178 - 0x17c */
+-
+-	/* TSF host access */
+-	u32 tsf_timerlow;	/* 0x180 */
+-	u32 tsf_timerhigh;	/* 0x184 */
+-	u32 tsf_cfprep;	/* 0x188 */
+-	u32 tsf_cfpstart;	/* 0x18c */
+-	u32 tsf_cfpmaxdur32;	/* 0x190 */
+-	u32 PAD[3];		/* 0x194 - 0x19c */
+-
+-	u32 maccontrol1;	/* 0x1a0 */
+-	u32 machwcap1;	/* 0x1a4 */
+-	u32 PAD[14];		/* 0x1a8 - 0x1dc */
+-
+-	/* Clock control and hardware workarounds*/
+-	u32 clk_ctl_st;	/* 0x1e0 */
+-	u32 hw_war;
+-	u32 d11_phypllctl;	/* the phypll request/avail bits are
+-				 * moved to clk_ctl_st
+-				 */
+-	u32 PAD[5];		/* 0x1ec - 0x1fc */
+-
+-	/* 0x200-0x37F dma/pio registers */
+-	fifo64_t fifo64regs[6];
+-
+-	/* FIFO diagnostic port access */
+-	dma32diag_t dmafifo;	/* 0x380 - 0x38C */
+-
+-	u32 aggfifocnt;	/* 0x390 */
+-	u32 aggfifodata;	/* 0x394 */
+-	u32 PAD[16];		/* 0x398 - 0x3d4 */
+-	u16 radioregaddr;	/* 0x3d8 */
+-	u16 radioregdata;	/* 0x3da */
+-
+-	/*
+-	 * time delay between the change on rf disable input and
+-	 * radio shutdown
+-	 */
+-	u32 rfdisabledly;	/* 0x3DC */
+-
+-	/* PHY register access */
+-	u16 phyversion;	/* 0x3e0 - 0x0 */
+-	u16 phybbconfig;	/* 0x3e2 - 0x1 */
+-	u16 phyadcbias;	/* 0x3e4 - 0x2  Bphy only */
+-	u16 phyanacore;	/* 0x3e6 - 0x3  pwwrdwn on aphy */
+-	u16 phyrxstatus0;	/* 0x3e8 - 0x4 */
+-	u16 phyrxstatus1;	/* 0x3ea - 0x5 */
+-	u16 phycrsth;	/* 0x3ec - 0x6 */
+-	u16 phytxerror;	/* 0x3ee - 0x7 */
+-	u16 phychannel;	/* 0x3f0 - 0x8 */
+-	u16 PAD[1];		/* 0x3f2 - 0x9 */
+-	u16 phytest;		/* 0x3f4 - 0xa */
+-	u16 phy4waddr;	/* 0x3f6 - 0xb */
+-	u16 phy4wdatahi;	/* 0x3f8 - 0xc */
+-	u16 phy4wdatalo;	/* 0x3fa - 0xd */
+-	u16 phyregaddr;	/* 0x3fc - 0xe */
+-	u16 phyregdata;	/* 0x3fe - 0xf */
+-
+-	/* IHR *//* 0x400 - 0x7FE */
+-
+-	/* RXE Block */
+-	u16 PAD[3];		/* 0x400 - 0x406 */
+-	u16 rcv_fifo_ctl;	/* 0x406 */
+-	u16 PAD;		/* 0x408 - 0x40a */
+-	u16 rcv_frm_cnt;	/* 0x40a */
+-	u16 PAD[4];		/* 0x40a - 0x414 */
+-	u16 rssi;		/* 0x414 */
+-	u16 PAD[5];		/* 0x414 - 0x420 */
+-	u16 rcm_ctl;		/* 0x420 */
+-	u16 rcm_mat_data;	/* 0x422 */
+-	u16 rcm_mat_mask;	/* 0x424 */
+-	u16 rcm_mat_dly;	/* 0x426 */
+-	u16 rcm_cond_mask_l;	/* 0x428 */
+-	u16 rcm_cond_mask_h;	/* 0x42A */
+-	u16 rcm_cond_dly;	/* 0x42C */
+-	u16 PAD[1];		/* 0x42E */
+-	u16 ext_ihr_addr;	/* 0x430 */
+-	u16 ext_ihr_data;	/* 0x432 */
+-	u16 rxe_phyrs_2;	/* 0x434 */
+-	u16 rxe_phyrs_3;	/* 0x436 */
+-	u16 phy_mode;	/* 0x438 */
+-	u16 rcmta_ctl;	/* 0x43a */
+-	u16 rcmta_size;	/* 0x43c */
+-	u16 rcmta_addr0;	/* 0x43e */
+-	u16 rcmta_addr1;	/* 0x440 */
+-	u16 rcmta_addr2;	/* 0x442 */
+-	u16 PAD[30];		/* 0x444 - 0x480 */
+-
+-	/* PSM Block *//* 0x480 - 0x500 */
+-
+-	u16 PAD;		/* 0x480 */
+-	u16 psm_maccontrol_h;	/* 0x482 */
+-	u16 psm_macintstatus_l;	/* 0x484 */
+-	u16 psm_macintstatus_h;	/* 0x486 */
+-	u16 psm_macintmask_l;	/* 0x488 */
+-	u16 psm_macintmask_h;	/* 0x48A */
+-	u16 PAD;		/* 0x48C */
+-	u16 psm_maccommand;	/* 0x48E */
+-	u16 psm_brc;		/* 0x490 */
+-	u16 psm_phy_hdr_param;	/* 0x492 */
+-	u16 psm_postcard;	/* 0x494 */
+-	u16 psm_pcard_loc_l;	/* 0x496 */
+-	u16 psm_pcard_loc_h;	/* 0x498 */
+-	u16 psm_gpio_in;	/* 0x49A */
+-	u16 psm_gpio_out;	/* 0x49C */
+-	u16 psm_gpio_oe;	/* 0x49E */
+-
+-	u16 psm_bred_0;	/* 0x4A0 */
+-	u16 psm_bred_1;	/* 0x4A2 */
+-	u16 psm_bred_2;	/* 0x4A4 */
+-	u16 psm_bred_3;	/* 0x4A6 */
+-	u16 psm_brcl_0;	/* 0x4A8 */
+-	u16 psm_brcl_1;	/* 0x4AA */
+-	u16 psm_brcl_2;	/* 0x4AC */
+-	u16 psm_brcl_3;	/* 0x4AE */
+-	u16 psm_brpo_0;	/* 0x4B0 */
+-	u16 psm_brpo_1;	/* 0x4B2 */
+-	u16 psm_brpo_2;	/* 0x4B4 */
+-	u16 psm_brpo_3;	/* 0x4B6 */
+-	u16 psm_brwk_0;	/* 0x4B8 */
+-	u16 psm_brwk_1;	/* 0x4BA */
+-	u16 psm_brwk_2;	/* 0x4BC */
+-	u16 psm_brwk_3;	/* 0x4BE */
+-
+-	u16 psm_base_0;	/* 0x4C0 */
+-	u16 psm_base_1;	/* 0x4C2 */
+-	u16 psm_base_2;	/* 0x4C4 */
+-	u16 psm_base_3;	/* 0x4C6 */
+-	u16 psm_base_4;	/* 0x4C8 */
+-	u16 psm_base_5;	/* 0x4CA */
+-	u16 psm_base_6;	/* 0x4CC */
+-	u16 psm_pc_reg_0;	/* 0x4CE */
+-	u16 psm_pc_reg_1;	/* 0x4D0 */
+-	u16 psm_pc_reg_2;	/* 0x4D2 */
+-	u16 psm_pc_reg_3;	/* 0x4D4 */
+-	u16 PAD[0xD];	/* 0x4D6 - 0x4DE */
+-	u16 psm_corectlsts;	/* 0x4f0 *//* Corerev >= 13 */
+-	u16 PAD[0x7];	/* 0x4f2 - 0x4fE */
+-
+-	/* TXE0 Block *//* 0x500 - 0x580 */
+-	u16 txe_ctl;		/* 0x500 */
+-	u16 txe_aux;		/* 0x502 */
+-	u16 txe_ts_loc;	/* 0x504 */
+-	u16 txe_time_out;	/* 0x506 */
+-	u16 txe_wm_0;	/* 0x508 */
+-	u16 txe_wm_1;	/* 0x50A */
+-	u16 txe_phyctl;	/* 0x50C */
+-	u16 txe_status;	/* 0x50E */
+-	u16 txe_mmplcp0;	/* 0x510 */
+-	u16 txe_mmplcp1;	/* 0x512 */
+-	u16 txe_phyctl1;	/* 0x514 */
+-
+-	u16 PAD[0x05];	/* 0x510 - 0x51E */
+-
+-	/* Transmit control */
+-	u16 xmtfifodef;	/* 0x520 */
+-	u16 xmtfifo_frame_cnt;	/* 0x522 *//* Corerev >= 16 */
+-	u16 xmtfifo_byte_cnt;	/* 0x524 *//* Corerev >= 16 */
+-	u16 xmtfifo_head;	/* 0x526 *//* Corerev >= 16 */
+-	u16 xmtfifo_rd_ptr;	/* 0x528 *//* Corerev >= 16 */
+-	u16 xmtfifo_wr_ptr;	/* 0x52A *//* Corerev >= 16 */
+-	u16 xmtfifodef1;	/* 0x52C *//* Corerev >= 16 */
+-
+-	u16 PAD[0x09];	/* 0x52E - 0x53E */
+-
+-	u16 xmtfifocmd;	/* 0x540 */
+-	u16 xmtfifoflush;	/* 0x542 */
+-	u16 xmtfifothresh;	/* 0x544 */
+-	u16 xmtfifordy;	/* 0x546 */
+-	u16 xmtfifoprirdy;	/* 0x548 */
+-	u16 xmtfiforqpri;	/* 0x54A */
+-	u16 xmttplatetxptr;	/* 0x54C */
+-	u16 PAD;		/* 0x54E */
+-	u16 xmttplateptr;	/* 0x550 */
+-	u16 smpl_clct_strptr;	/* 0x552 *//* Corerev >= 22 */
+-	u16 smpl_clct_stpptr;	/* 0x554 *//* Corerev >= 22 */
+-	u16 smpl_clct_curptr;	/* 0x556 *//* Corerev >= 22 */
+-	u16 PAD[0x04];	/* 0x558 - 0x55E */
+-	u16 xmttplatedatalo;	/* 0x560 */
+-	u16 xmttplatedatahi;	/* 0x562 */
+-
+-	u16 PAD[2];		/* 0x564 - 0x566 */
+-
+-	u16 xmtsel;		/* 0x568 */
+-	u16 xmttxcnt;	/* 0x56A */
+-	u16 xmttxshmaddr;	/* 0x56C */
+-
+-	u16 PAD[0x09];	/* 0x56E - 0x57E */
+-
+-	/* TXE1 Block */
+-	u16 PAD[0x40];	/* 0x580 - 0x5FE */
+-
+-	/* TSF Block */
+-	u16 PAD[0X02];	/* 0x600 - 0x602 */
+-	u16 tsf_cfpstrt_l;	/* 0x604 */
+-	u16 tsf_cfpstrt_h;	/* 0x606 */
+-	u16 PAD[0X05];	/* 0x608 - 0x610 */
+-	u16 tsf_cfppretbtt;	/* 0x612 */
+-	u16 PAD[0XD];	/* 0x614 - 0x62C */
+-	u16 tsf_clk_frac_l;	/* 0x62E */
+-	u16 tsf_clk_frac_h;	/* 0x630 */
+-	u16 PAD[0X14];	/* 0x632 - 0x658 */
+-	u16 tsf_random;	/* 0x65A */
+-	u16 PAD[0x05];	/* 0x65C - 0x664 */
+-	/* GPTimer 2 registers */
+-	u16 tsf_gpt2_stat;	/* 0x666 */
+-	u16 tsf_gpt2_ctr_l;	/* 0x668 */
+-	u16 tsf_gpt2_ctr_h;	/* 0x66A */
+-	u16 tsf_gpt2_val_l;	/* 0x66C */
+-	u16 tsf_gpt2_val_h;	/* 0x66E */
+-	u16 tsf_gptall_stat;	/* 0x670 */
+-	u16 PAD[0x07];	/* 0x672 - 0x67E */
+-
+-	/* IFS Block */
+-	u16 ifs_sifs_rx_tx_tx;	/* 0x680 */
+-	u16 ifs_sifs_nav_tx;	/* 0x682 */
+-	u16 ifs_slot;	/* 0x684 */
+-	u16 PAD;		/* 0x686 */
+-	u16 ifs_ctl;		/* 0x688 */
+-	u16 PAD[0x3];	/* 0x68a - 0x68F */
+-	u16 ifsstat;		/* 0x690 */
+-	u16 ifsmedbusyctl;	/* 0x692 */
+-	u16 iftxdur;		/* 0x694 */
+-	u16 PAD[0x3];	/* 0x696 - 0x69b */
+-	/* EDCF support in dot11macs */
+-	u16 ifs_aifsn;	/* 0x69c */
+-	u16 ifs_ctl1;	/* 0x69e */
+-
+-	/* slow clock registers */
+-	u16 scc_ctl;		/* 0x6a0 */
+-	u16 scc_timer_l;	/* 0x6a2 */
+-	u16 scc_timer_h;	/* 0x6a4 */
+-	u16 scc_frac;	/* 0x6a6 */
+-	u16 scc_fastpwrup_dly;	/* 0x6a8 */
+-	u16 scc_per;		/* 0x6aa */
+-	u16 scc_per_frac;	/* 0x6ac */
+-	u16 scc_cal_timer_l;	/* 0x6ae */
+-	u16 scc_cal_timer_h;	/* 0x6b0 */
+-	u16 PAD;		/* 0x6b2 */
+-
+-	u16 PAD[0x26];
+-
+-	/* NAV Block */
+-	u16 nav_ctl;		/* 0x700 */
+-	u16 navstat;		/* 0x702 */
+-	u16 PAD[0x3e];	/* 0x702 - 0x77E */
+-
+-	/* WEP/PMQ Block *//* 0x780 - 0x7FE */
+-	u16 PAD[0x20];	/* 0x780 - 0x7BE */
+-
+-	u16 wepctl;		/* 0x7C0 */
+-	u16 wepivloc;	/* 0x7C2 */
+-	u16 wepivkey;	/* 0x7C4 */
+-	u16 wepwkey;		/* 0x7C6 */
+-
+-	u16 PAD[4];		/* 0x7C8 - 0x7CE */
+-	u16 pcmctl;		/* 0X7D0 */
+-	u16 pcmstat;		/* 0X7D2 */
+-	u16 PAD[6];		/* 0x7D4 - 0x7DE */
+-
+-	u16 pmqctl;		/* 0x7E0 */
+-	u16 pmqstatus;	/* 0x7E2 */
+-	u16 pmqpat0;		/* 0x7E4 */
+-	u16 pmqpat1;		/* 0x7E6 */
+-	u16 pmqpat2;		/* 0x7E8 */
+-
+-	u16 pmqdat;		/* 0x7EA */
+-	u16 pmqdator;	/* 0x7EC */
+-	u16 pmqhst;		/* 0x7EE */
+-	u16 pmqpath0;	/* 0x7F0 */
+-	u16 pmqpath1;	/* 0x7F2 */
+-	u16 pmqpath2;	/* 0x7F4 */
+-	u16 pmqdath;		/* 0x7F6 */
+-
+-	u16 PAD[0x04];	/* 0x7F8 - 0x7FE */
+-
+-	/* SHM *//* 0x800 - 0xEFE */
+-	u16 PAD[0x380];	/* 0x800 - 0xEFE */
+-
+-	/* SB configuration registers: 0xF00 */
+-	sbconfig_t sbconfig;	/* sb config regs occupy top 256 bytes */
+-} d11regs_t;
+-
+-#define	PIHR_BASE	0x0400	/* byte address of packed IHR region */
+-
+-/* biststatus */
+-#define	BT_DONE		(1U << 31)	/* bist done */
+-#define	BT_B2S		(1 << 30)	/* bist2 ram summary bit */
+-
+-/* intstatus and intmask */
+-#define	I_PC		(1 << 10)	/* pci descriptor error */
+-#define	I_PD		(1 << 11)	/* pci data error */
+-#define	I_DE		(1 << 12)	/* descriptor protocol error */
+-#define	I_RU		(1 << 13)	/* receive descriptor underflow */
+-#define	I_RO		(1 << 14)	/* receive fifo overflow */
+-#define	I_XU		(1 << 15)	/* transmit fifo underflow */
+-#define	I_RI		(1 << 16)	/* receive interrupt */
+-#define	I_XI		(1 << 24)	/* transmit interrupt */
+-
+-/* interrupt receive lazy */
+-#define	IRL_TO_MASK		0x00ffffff	/* timeout */
+-#define	IRL_FC_MASK		0xff000000	/* frame count */
+-#define	IRL_FC_SHIFT		24	/* frame count */
+-
+-/* maccontrol register */
+-#define	MCTL_GMODE		(1U << 31)
+-#define	MCTL_DISCARD_PMQ	(1 << 30)
+-#define	MCTL_WAKE		(1 << 26)
+-#define	MCTL_HPS		(1 << 25)
+-#define	MCTL_PROMISC		(1 << 24)
+-#define	MCTL_KEEPBADFCS		(1 << 23)
+-#define	MCTL_KEEPCONTROL	(1 << 22)
+-#define	MCTL_PHYLOCK		(1 << 21)
+-#define	MCTL_BCNS_PROMISC	(1 << 20)
+-#define	MCTL_LOCK_RADIO		(1 << 19)
+-#define	MCTL_AP			(1 << 18)
+-#define	MCTL_INFRA		(1 << 17)
+-#define	MCTL_BIGEND		(1 << 16)
+-#define	MCTL_GPOUT_SEL_MASK	(3 << 14)
+-#define	MCTL_GPOUT_SEL_SHIFT	14
+-#define	MCTL_EN_PSMDBG		(1 << 13)
+-#define	MCTL_IHR_EN		(1 << 10)
+-#define	MCTL_SHM_UPPER		(1 <<  9)
+-#define	MCTL_SHM_EN		(1 <<  8)
+-#define	MCTL_PSM_JMP_0		(1 <<  2)
+-#define	MCTL_PSM_RUN		(1 <<  1)
+-#define	MCTL_EN_MAC		(1 <<  0)
+-
+-/* maccommand register */
+-#define	MCMD_BCN0VLD		(1 <<  0)
+-#define	MCMD_BCN1VLD		(1 <<  1)
+-#define	MCMD_DIRFRMQVAL		(1 <<  2)
+-#define	MCMD_CCA		(1 <<  3)
+-#define	MCMD_BG_NOISE		(1 <<  4)
+-#define	MCMD_SKIP_SHMINIT	(1 <<  5)	/* only used for simulation */
+-#define MCMD_SAMPLECOLL		MCMD_SKIP_SHMINIT	/* reuse for sample collect */
+-
+-/* macintstatus/macintmask */
+-#define	MI_MACSSPNDD		(1 <<  0)	/* MAC has gracefully suspended */
+-#define	MI_BCNTPL		(1 <<  1)	/* beacon template available */
+-#define	MI_TBTT			(1 <<  2)	/* TBTT indication */
+-#define	MI_BCNSUCCESS		(1 <<  3)	/* beacon successfully tx'd */
+-#define	MI_BCNCANCLD		(1 <<  4)	/* beacon canceled (IBSS) */
+-#define	MI_ATIMWINEND		(1 <<  5)	/* end of ATIM-window (IBSS) */
+-#define	MI_PMQ			(1 <<  6)	/* PMQ entries available */
+-#define	MI_NSPECGEN_0		(1 <<  7)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_NSPECGEN_1		(1 <<  8)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_MACTXERR		(1 <<  9)	/* MAC level Tx error */
+-#define	MI_NSPECGEN_3		(1 << 10)	/* non-specific gen-stat bits that are set by PSM */
+-#define	MI_PHYTXERR		(1 << 11)	/* PHY Tx error */
+-#define	MI_PME			(1 << 12)	/* Power Management Event */
+-#define	MI_GP0			(1 << 13)	/* General-purpose timer0 */
+-#define	MI_GP1			(1 << 14)	/* General-purpose timer1 */
+-#define	MI_DMAINT		(1 << 15)	/* (ORed) DMA-interrupts */
+-#define	MI_TXSTOP		(1 << 16)	/* MAC has completed a TX FIFO Suspend/Flush */
+-#define	MI_CCA			(1 << 17)	/* MAC has completed a CCA measurement */
+-#define	MI_BG_NOISE		(1 << 18)	/* MAC has collected background noise samples */
+-#define	MI_DTIM_TBTT		(1 << 19)	/* MBSS DTIM TBTT indication */
+-#define MI_PRQ			(1 << 20)	/* Probe response queue needs attention */
+-#define	MI_PWRUP		(1 << 21)	/* Radio/PHY has been powered back up. */
+-#define	MI_RESERVED3		(1 << 22)
+-#define	MI_RESERVED2		(1 << 23)
+-#define MI_RESERVED1		(1 << 25)
+-/* MAC detected change on RF Disable input*/
+-#define MI_RFDISABLE		(1 << 28)
+-#define	MI_TFS			(1 << 29)	/* MAC has completed a TX */
+-#define	MI_PHYCHANGED		(1 << 30)	/* A phy status change wrt G mode */
+-#define	MI_TO			(1U << 31)	/* general purpose timeout */
+-
+-/* Mac capabilities registers */
+-/* machwcap */
+-#define	MCAP_TKIPMIC		0x80000000	/* TKIP MIC hardware present */
+-
+-/* pmqhost data */
+-#define	PMQH_DATA_MASK		0xffff0000	/* data entry of head pmq entry */
+-#define	PMQH_BSSCFG		0x00100000	/* PM entry for BSS config */
+-#define	PMQH_PMOFF		0x00010000	/* PM Mode OFF: power save off */
+-#define	PMQH_PMON		0x00020000	/* PM Mode ON: power save on */
+-#define	PMQH_DASAT		0x00040000	/* Dis-associated or De-authenticated */
+-#define	PMQH_ATIMFAIL		0x00080000	/* ATIM not acknowledged */
+-#define	PMQH_DEL_ENTRY		0x00000001	/* delete head entry */
+-#define	PMQH_DEL_MULT		0x00000002	/* delete head entry to cur read pointer -1 */
+-#define	PMQH_OFLO		0x00000004	/* pmq overflow indication */
+-#define	PMQH_NOT_EMPTY		0x00000008	/* entries are present in pmq */
+-
+-/* phydebug */
+-#define	PDBG_CRS		(1 << 0)	/* phy is asserting carrier sense */
+-#define	PDBG_TXA		(1 << 1)	/* phy is taking xmit byte from mac this cycle */
+-#define	PDBG_TXF		(1 << 2)	/* mac is instructing the phy to transmit a frame */
+-#define	PDBG_TXE		(1 << 3)	/* phy is signalling a transmit Error to the mac */
+-#define	PDBG_RXF		(1 << 4)	/* phy detected the end of a valid frame preamble */
+-#define	PDBG_RXS		(1 << 5)	/* phy detected the end of a valid PLCP header */
+-#define	PDBG_RXFRG		(1 << 6)	/* rx start not asserted */
+-#define	PDBG_RXV		(1 << 7)	/* mac is taking receive byte from phy this cycle */
+-#define	PDBG_RFD		(1 << 16)	/* RF portion of the radio is disabled */
+-
+-/* objaddr register */
+-#define	OBJADDR_SEL_MASK	0x000F0000
+-#define	OBJADDR_UCM_SEL		0x00000000
+-#define	OBJADDR_SHM_SEL		0x00010000
+-#define	OBJADDR_SCR_SEL		0x00020000
+-#define	OBJADDR_IHR_SEL		0x00030000
+-#define	OBJADDR_RCMTA_SEL	0x00040000
+-#define	OBJADDR_SRCHM_SEL	0x00060000
+-#define	OBJADDR_WINC		0x01000000
+-#define	OBJADDR_RINC		0x02000000
+-#define	OBJADDR_AUTO_INC	0x03000000
+-
+-#define	WEP_PCMADDR		0x07d4
+-#define	WEP_PCMDATA		0x07d6
+-
+-/* frmtxstatus */
+-#define	TXS_V			(1 << 0)	/* valid bit */
+-#define	TXS_STATUS_MASK		0xffff
+-#define	TXS_FID_MASK		0xffff0000
+-#define	TXS_FID_SHIFT		16
+-
+-/* frmtxstatus2 */
+-#define	TXS_SEQ_MASK		0xffff
+-#define	TXS_PTX_MASK		0xff0000
+-#define	TXS_PTX_SHIFT		16
+-#define	TXS_MU_MASK		0x01000000
+-#define	TXS_MU_SHIFT		24
+-
+-/* clk_ctl_st */
+-#define CCS_ERSRC_REQ_D11PLL	0x00000100	/* d11 core pll request */
+-#define CCS_ERSRC_REQ_PHYPLL	0x00000200	/* PHY pll request */
+-#define CCS_ERSRC_AVAIL_D11PLL	0x01000000	/* d11 core pll available */
+-#define CCS_ERSRC_AVAIL_PHYPLL	0x02000000	/* PHY pll available */
+-
+-/* HT Cloclk Ctrl and Clock Avail for 4313 */
+-#define CCS_ERSRC_REQ_HT    0x00000010	/* HT avail request */
+-#define CCS_ERSRC_AVAIL_HT  0x00020000	/* HT clock available */
+-
+-/* tsf_cfprep register */
+-#define	CFPREP_CBI_MASK		0xffffffc0
+-#define	CFPREP_CBI_SHIFT	6
+-#define	CFPREP_CFPP		0x00000001
+-
+-/* tx fifo sizes values are in terms of 256 byte blocks */
+-#define TXFIFOCMD_RESET_MASK	(1 << 15)	/* reset */
+-#define TXFIFOCMD_FIFOSEL_SHIFT	8	/* fifo */
+-#define TXFIFO_FIFOTOP_SHIFT	8	/* fifo start */
+-
+-#define TXFIFO_START_BLK16	 65	/* Base address + 32 * 512 B/P */
+-#define TXFIFO_START_BLK	 6	/* Base address + 6 * 256 B */
+-#define TXFIFO_SIZE_UNIT	256	/* one unit corresponds to 256 bytes */
+-#define MBSS16_TEMPLMEM_MINBLKS	65	/* one unit corresponds to 256 bytes */
+-
+-/* phy versions, PhyVersion:Revision field */
+-#define	PV_AV_MASK		0xf000	/* analog block version */
+-#define	PV_AV_SHIFT		12	/* analog block version bitfield offset */
+-#define	PV_PT_MASK		0x0f00	/* phy type */
+-#define	PV_PT_SHIFT		8	/* phy type bitfield offset */
+-#define	PV_PV_MASK		0x000f	/* phy version */
+-#define	PHY_TYPE(v)		((v & PV_PT_MASK) >> PV_PT_SHIFT)
+-
+-/* phy types, PhyVersion:PhyType field */
+-#define	PHY_TYPE_N		4	/* N-Phy value */
+-#define	PHY_TYPE_SSN		6	/* SSLPN-Phy value */
+-#define	PHY_TYPE_LCN		8	/* LCN-Phy value */
+-#define	PHY_TYPE_LCNXN		9	/* LCNXN-Phy value */
+-#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
+-
+-/* analog types, PhyVersion:AnalogType field */
+-#define	ANA_11N_013		5
+-
+-/* 802.11a PLCP header def */
+-typedef struct ofdm_phy_hdr ofdm_phy_hdr_t;
+-struct ofdm_phy_hdr {
+-	u8 rlpt[3];		/* rate, length, parity, tail */
+-	u16 service;
+-	u8 pad;
+-} __attribute__((packed));
+-
+-#define	D11A_PHY_HDR_GRATE(phdr)	((phdr)->rlpt[0] & 0x0f)
+-#define	D11A_PHY_HDR_GRES(phdr)		(((phdr)->rlpt[0] >> 4) & 0x01)
+-#define	D11A_PHY_HDR_GLENGTH(phdr)	(((u32 *)((phdr)->rlpt) >> 5) & 0x0fff)
+-#define	D11A_PHY_HDR_GPARITY(phdr)	(((phdr)->rlpt[3] >> 1) & 0x01)
+-#define	D11A_PHY_HDR_GTAIL(phdr)	(((phdr)->rlpt[3] >> 2) & 0x3f)
+-
+-/* rate encoded per 802.11a-1999 sec 17.3.4.1 */
+-#define	D11A_PHY_HDR_SRATE(phdr, rate)		\
+-	((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf))
+-/* set reserved field to zero */
+-#define	D11A_PHY_HDR_SRES(phdr)		((phdr)->rlpt[0] &= 0xef)
+-/* length is number of octets in PSDU */
+-#define	D11A_PHY_HDR_SLENGTH(phdr, length)	\
+-	(*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \
+-	(((length) & 0x0fff) << 5))
+-/* set the tail to all zeros */
+-#define	D11A_PHY_HDR_STAIL(phdr)	((phdr)->rlpt[3] &= 0x03)
+-
+-#define	D11A_PHY_HDR_LEN_L	3	/* low-rate part of PLCP header */
+-#define	D11A_PHY_HDR_LEN_R	2	/* high-rate part of PLCP header */
+-
+-#define	D11A_PHY_TX_DELAY	(2)	/* 2.1 usec */
+-
+-#define	D11A_PHY_HDR_TIME	(4)	/* low-rate part of PLCP header */
+-#define	D11A_PHY_PRE_TIME	(16)
+-#define	D11A_PHY_PREHDR_TIME	(D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME)
+-
+-/* 802.11b PLCP header def */
+-typedef struct cck_phy_hdr cck_phy_hdr_t;
+-struct cck_phy_hdr {
+-	u8 signal;
+-	u8 service;
+-	u16 length;
+-	u16 crc;
+-} __attribute__((packed));
+-
+-#define	D11B_PHY_HDR_LEN	6
+-
+-#define	D11B_PHY_TX_DELAY	(3)	/* 3.4 usec */
+-
+-#define	D11B_PHY_LHDR_TIME	(D11B_PHY_HDR_LEN << 3)
+-#define	D11B_PHY_LPRE_TIME	(144)
+-#define	D11B_PHY_LPREHDR_TIME	(D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME)
+-
+-#define	D11B_PHY_SHDR_TIME	(D11B_PHY_LHDR_TIME >> 1)
+-#define	D11B_PHY_SPRE_TIME	(D11B_PHY_LPRE_TIME >> 1)
+-#define	D11B_PHY_SPREHDR_TIME	(D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME)
+-
+-#define	D11B_PLCP_SIGNAL_LOCKED	(1 << 2)
+-#define	D11B_PLCP_SIGNAL_LE	(1 << 7)
+-
+-#define MIMO_PLCP_MCS_MASK	0x7f	/* mcs index */
+-#define MIMO_PLCP_40MHZ		0x80	/* 40 Hz frame */
+-#define MIMO_PLCP_AMPDU		0x08	/* ampdu */
+-
+-#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8))
+-#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8))
+-#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \
+-	do { \
+-		plcp[1] = len & 0xff; \
+-		plcp[2] = ((len >> 8) & 0xff); \
+-	} while (0);
+-
+-#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU)
+-#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU)
+-#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU)
+-
+-/* The dot11a PLCP header is 5 bytes.  To simplify the software (so that we
+- * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has
+- * padding added in the ucode.
+- */
+-#define	D11_PHY_HDR_LEN	6
+-
+-/* TX DMA buffer header */
+-typedef struct d11txh d11txh_t;
+-struct d11txh {
+-	u16 MacTxControlLow;	/* 0x0 */
+-	u16 MacTxControlHigh;	/* 0x1 */
+-	u16 MacFrameControl;	/* 0x2 */
+-	u16 TxFesTimeNormal;	/* 0x3 */
+-	u16 PhyTxControlWord;	/* 0x4 */
+-	u16 PhyTxControlWord_1;	/* 0x5 */
+-	u16 PhyTxControlWord_1_Fbr;	/* 0x6 */
+-	u16 PhyTxControlWord_1_Rts;	/* 0x7 */
+-	u16 PhyTxControlWord_1_FbrRts;	/* 0x8 */
+-	u16 MainRates;	/* 0x9 */
+-	u16 XtraFrameTypes;	/* 0xa */
+-	u8 IV[16];		/* 0x0b - 0x12 */
+-	u8 TxFrameRA[6];	/* 0x13 - 0x15 */
+-	u16 TxFesTimeFallback;	/* 0x16 */
+-	u8 RTSPLCPFallback[6];	/* 0x17 - 0x19 */
+-	u16 RTSDurFallback;	/* 0x1a */
+-	u8 FragPLCPFallback[6];	/* 0x1b - 1d */
+-	u16 FragDurFallback;	/* 0x1e */
+-	u16 MModeLen;	/* 0x1f */
+-	u16 MModeFbrLen;	/* 0x20 */
+-	u16 TstampLow;	/* 0x21 */
+-	u16 TstampHigh;	/* 0x22 */
+-	u16 ABI_MimoAntSel;	/* 0x23 */
+-	u16 PreloadSize;	/* 0x24 */
+-	u16 AmpduSeqCtl;	/* 0x25 */
+-	u16 TxFrameID;	/* 0x26 */
+-	u16 TxStatus;	/* 0x27 */
+-	u16 MaxNMpdus;	/* 0x28 */
+-	u16 MaxABytes_MRT;	/* 0x29 */
+-	u16 MaxABytes_FBR;	/* 0x2a */
+-	u16 MinMBytes;	/* 0x2b */
+-	u8 RTSPhyHeader[D11_PHY_HDR_LEN];	/* 0x2c - 0x2e */
+-	struct ieee80211_rts rts_frame;	/* 0x2f - 0x36 */
+-	u16 PAD;		/* 0x37 */
+-} __attribute__((packed));
+-
+-#define	D11_TXH_LEN		112	/* bytes */
+-
+-/* Frame Types */
+-#define FT_CCK	0
+-#define FT_OFDM	1
+-#define FT_HT	2
+-#define FT_N	3
+-
+-/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */
+-#define TXC_AMPDU_SHIFT		9	/* shift for ampdu settings */
+-#define TXC_AMPDU_NONE		0	/* Regular MPDU, not an A-MPDU */
+-#define TXC_AMPDU_FIRST		1	/* first MPDU of an A-MPDU */
+-#define TXC_AMPDU_MIDDLE	2	/* intermediate MPDU of an A-MPDU */
+-#define TXC_AMPDU_LAST		3	/* last (or single) MPDU of an A-MPDU */
+-
+-/* MacTxControlLow */
+-#define TXC_AMIC		0x8000
+-#define	TXC_SENDCTS		0x0800
+-#define TXC_AMPDU_MASK		0x0600
+-#define TXC_BW_40		0x0100
+-#define TXC_FREQBAND_5G		0x0080
+-#define	TXC_DFCS		0x0040
+-#define	TXC_IGNOREPMQ		0x0020
+-#define	TXC_HWSEQ		0x0010
+-#define	TXC_STARTMSDU		0x0008
+-#define	TXC_SENDRTS		0x0004
+-#define	TXC_LONGFRAME		0x0002
+-#define	TXC_IMMEDACK		0x0001
+-
+-/* MacTxControlHigh */
+-#define TXC_PREAMBLE_RTS_FB_SHORT	0x8000	/* RTS fallback preamble type 1 = SHORT 0 = LONG */
+-#define TXC_PREAMBLE_RTS_MAIN_SHORT	0x4000	/* RTS main rate preamble type 1 = SHORT 0 = LONG */
+-#define TXC_PREAMBLE_DATA_FB_SHORT	0x2000	/* Main fallback rate preamble type
+-						 * 1 = SHORT for OFDM/GF for MIMO
+-						 * 0 = LONG for CCK/MM for MIMO
+-						 */
+-/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */
+-#define	TXC_AMPDU_FBR		0x1000	/* use fallback rate for this AMPDU */
+-#define	TXC_SECKEY_MASK		0x0FF0
+-#define	TXC_SECKEY_SHIFT	4
+-#define	TXC_ALT_TXPWR		0x0008	/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
+-#define	TXC_SECTYPE_MASK	0x0007
+-#define	TXC_SECTYPE_SHIFT	0
+-
+-/* Null delimiter for Fallback rate */
+-#define AMPDU_FBR_NULL_DELIM  5	/* Location of Null delimiter count for AMPDU */
+-
+-/* PhyTxControl for Mimophy */
+-#define	PHY_TXC_PWR_MASK	0xFC00
+-#define	PHY_TXC_PWR_SHIFT	10
+-#define	PHY_TXC_ANT_MASK	0x03C0	/* bit 6, 7, 8, 9 */
+-#define	PHY_TXC_ANT_SHIFT	6
+-#define	PHY_TXC_ANT_0_1		0x00C0	/* auto, last rx */
+-#define	PHY_TXC_LCNPHY_ANT_LAST	0x0000
+-#define	PHY_TXC_ANT_3		0x0200	/* virtual antenna 3 */
+-#define	PHY_TXC_ANT_2		0x0100	/* virtual antenna 2 */
+-#define	PHY_TXC_ANT_1		0x0080	/* virtual antenna 1 */
+-#define	PHY_TXC_ANT_0		0x0040	/* virtual antenna 0 */
+-#define	PHY_TXC_SHORT_HDR	0x0010
+-
+-#define	PHY_TXC_OLD_ANT_0	0x0000
+-#define	PHY_TXC_OLD_ANT_1	0x0100
+-#define	PHY_TXC_OLD_ANT_LAST	0x0300
+-
+-/* PhyTxControl_1 for Mimophy */
+-#define PHY_TXC1_BW_MASK		0x0007
+-#define PHY_TXC1_BW_10MHZ		0
+-#define PHY_TXC1_BW_10MHZ_UP		1
+-#define PHY_TXC1_BW_20MHZ		2
+-#define PHY_TXC1_BW_20MHZ_UP		3
+-#define PHY_TXC1_BW_40MHZ		4
+-#define PHY_TXC1_BW_40MHZ_DUP		5
+-#define PHY_TXC1_MODE_SHIFT		3
+-#define PHY_TXC1_MODE_MASK		0x0038
+-#define PHY_TXC1_MODE_SISO		0
+-#define PHY_TXC1_MODE_CDD		1
+-#define PHY_TXC1_MODE_STBC		2
+-#define PHY_TXC1_MODE_SDM		3
+-
+-/* PhyTxControl for HTphy that are different from Mimophy */
+-#define	PHY_TXC_HTANT_MASK		0x3fC0	/* bit 6, 7, 8, 9, 10, 11, 12, 13 */
+-
+-/* XtraFrameTypes */
+-#define XFTS_RTS_FT_SHIFT	2
+-#define XFTS_FBRRTS_FT_SHIFT	4
+-#define XFTS_CHANNEL_SHIFT	8
+-
+-/* Antenna diversity bit in ant_wr_settle */
+-#define	PHY_AWS_ANTDIV		0x2000
+-
+-/* IFS ctl */
+-#define IFS_USEEDCF	(1 << 2)
+-
+-/* IFS ctl1 */
+-#define IFS_CTL1_EDCRS	(1 << 3)
+-#define IFS_CTL1_EDCRS_20L (1 << 4)
+-#define IFS_CTL1_EDCRS_40 (1 << 5)
+-
+-/* ABI_MimoAntSel */
+-#define ABI_MAS_ADDR_BMP_IDX_MASK	0x0f00
+-#define ABI_MAS_ADDR_BMP_IDX_SHIFT	8
+-#define ABI_MAS_FBR_ANT_PTN_MASK	0x00f0
+-#define ABI_MAS_FBR_ANT_PTN_SHIFT	4
+-#define ABI_MAS_MRT_ANT_PTN_MASK	0x000f
+-
+-/* tx status packet */
+-typedef struct tx_status tx_status_t;
+-struct tx_status {
+-	u16 framelen;
+-	u16 PAD;
+-	u16 frameid;
+-	u16 status;
+-	u16 lasttxtime;
+-	u16 sequence;
+-	u16 phyerr;
+-	u16 ackphyrxsh;
+-} __attribute__((packed));
+-
+-#define	TXSTATUS_LEN	16
+-
+-/* status field bit definitions */
+-#define	TX_STATUS_FRM_RTX_MASK	0xF000
+-#define	TX_STATUS_FRM_RTX_SHIFT	12
+-#define	TX_STATUS_RTS_RTX_MASK	0x0F00
+-#define	TX_STATUS_RTS_RTX_SHIFT	8
+-#define TX_STATUS_MASK		0x00FE
+-#define	TX_STATUS_PMINDCTD	(1 << 7)	/* PM mode indicated to AP */
+-#define	TX_STATUS_INTERMEDIATE	(1 << 6)	/* intermediate or 1st ampdu pkg */
+-#define	TX_STATUS_AMPDU		(1 << 5)	/* AMPDU status */
+-#define TX_STATUS_SUPR_MASK	0x1C	/* suppress status bits (4:2) */
+-#define TX_STATUS_SUPR_SHIFT	2
+-#define	TX_STATUS_ACK_RCV	(1 << 1)	/* ACK received */
+-#define	TX_STATUS_VALID		(1 << 0)	/* Tx status valid */
+-#define	TX_STATUS_NO_ACK	0
+-
+-/* suppress status reason codes */
+-#define	TX_STATUS_SUPR_PMQ	(1 << 2)	/* PMQ entry */
+-#define	TX_STATUS_SUPR_FLUSH	(2 << 2)	/* flush request */
+-#define	TX_STATUS_SUPR_FRAG	(3 << 2)	/* previous frag failure */
+-#define	TX_STATUS_SUPR_TBTT	(3 << 2)	/* SHARED: Probe response supr for TBTT */
+-#define	TX_STATUS_SUPR_BADCH	(4 << 2)	/* channel mismatch */
+-#define	TX_STATUS_SUPR_EXPTIME	(5 << 2)	/* lifetime expiry */
+-#define	TX_STATUS_SUPR_UF	(6 << 2)	/* underflow */
+-
+-/* Unexpected tx status for rate update */
+-#define TX_STATUS_UNEXP(status) \
+-	((((status) & TX_STATUS_INTERMEDIATE) != 0) && \
+-	 TX_STATUS_UNEXP_AMPDU(status))
+-
+-/* Unexpected tx status for A-MPDU rate update */
+-#define TX_STATUS_UNEXP_AMPDU(status) \
+-	((((status) & TX_STATUS_SUPR_MASK) != 0) && \
+-	 (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME))
+-
+-#define TX_STATUS_BA_BMAP03_MASK	0xF000	/* ba bitmap 0:3 in 1st pkg */
+-#define TX_STATUS_BA_BMAP03_SHIFT	12	/* ba bitmap 0:3 in 1st pkg */
+-#define TX_STATUS_BA_BMAP47_MASK	0x001E	/* ba bitmap 4:7 in 2nd pkg */
+-#define TX_STATUS_BA_BMAP47_SHIFT	3	/* ba bitmap 4:7 in 2nd pkg */
+-
+-/* RXE (Receive Engine) */
+-
+-/* RCM_CTL */
+-#define	RCM_INC_MASK_H		0x0080
+-#define	RCM_INC_MASK_L		0x0040
+-#define	RCM_INC_DATA		0x0020
+-#define	RCM_INDEX_MASK		0x001F
+-#define	RCM_SIZE		15
+-
+-#define	RCM_MAC_OFFSET		0	/* current MAC address */
+-#define	RCM_BSSID_OFFSET	3	/* current BSSID address */
+-#define	RCM_F_BSSID_0_OFFSET	6	/* foreign BSS CFP tracking */
+-#define	RCM_F_BSSID_1_OFFSET	9	/* foreign BSS CFP tracking */
+-#define	RCM_F_BSSID_2_OFFSET	12	/* foreign BSS CFP tracking */
+-
+-#define RCM_WEP_TA0_OFFSET	16
+-#define RCM_WEP_TA1_OFFSET	19
+-#define RCM_WEP_TA2_OFFSET	22
+-#define RCM_WEP_TA3_OFFSET	25
+-
+-/* PSM Block */
+-
+-/* psm_phy_hdr_param bits */
+-#define MAC_PHY_RESET		1
+-#define MAC_PHY_CLOCK_EN	2
+-#define MAC_PHY_FORCE_CLK	4
+-
+-/* WEP Block */
+-
+-/* WEP_WKEY */
+-#define	WKEY_START		(1 << 8)
+-#define	WKEY_SEL_MASK		0x1F
+-
+-/* WEP data formats */
+-
+-/* the number of RCMTA entries */
+-#define RCMTA_SIZE 50
+-
+-#define M_ADDR_BMP_BLK		(0x37e * 2)
+-#define M_ADDR_BMP_BLK_SZ	12
+-
+-#define ADDR_BMP_RA		(1 << 0)	/* Receiver Address (RA) */
+-#define ADDR_BMP_TA		(1 << 1)	/* Transmitter Address (TA) */
+-#define ADDR_BMP_BSSID		(1 << 2)	/* BSSID */
+-#define ADDR_BMP_AP		(1 << 3)	/* Infra-BSS Access Point (AP) */
+-#define ADDR_BMP_STA		(1 << 4)	/* Infra-BSS Station (STA) */
+-#define ADDR_BMP_RESERVED1	(1 << 5)
+-#define ADDR_BMP_RESERVED2	(1 << 6)
+-#define ADDR_BMP_RESERVED3	(1 << 7)
+-#define ADDR_BMP_BSS_IDX_MASK	(3 << 8)	/* BSS control block index */
+-#define ADDR_BMP_BSS_IDX_SHIFT	8
+-
+-#define	WSEC_MAX_RCMTA_KEYS	54
+-
+-/* max keys in M_TKMICKEYS_BLK */
+-#define	WSEC_MAX_TKMIC_ENGINE_KEYS		12	/* 8 + 4 default */
+-
+-/* max RXE match registers */
+-#define WSEC_MAX_RXE_KEYS	4
+-
+-/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */
+-/* SKL (Security Key Lookup) */
+-#define	SKL_ALGO_MASK		0x0007
+-#define	SKL_ALGO_SHIFT		0
+-#define	SKL_KEYID_MASK		0x0008
+-#define	SKL_KEYID_SHIFT		3
+-#define	SKL_INDEX_MASK		0x03F0
+-#define	SKL_INDEX_SHIFT		4
+-#define	SKL_GRP_ALGO_MASK	0x1c00
+-#define	SKL_GRP_ALGO_SHIFT	10
+-
+-/* additional bits defined for IBSS group key support */
+-#define	SKL_IBSS_INDEX_MASK	0x01F0
+-#define	SKL_IBSS_INDEX_SHIFT	4
+-#define	SKL_IBSS_KEYID1_MASK	0x0600
+-#define	SKL_IBSS_KEYID1_SHIFT	9
+-#define	SKL_IBSS_KEYID2_MASK	0x1800
+-#define	SKL_IBSS_KEYID2_SHIFT	11
+-#define	SKL_IBSS_KEYALGO_MASK	0xE000
+-#define	SKL_IBSS_KEYALGO_SHIFT	13
+-
+-#define	WSEC_MODE_OFF		0
+-#define	WSEC_MODE_HW		1
+-#define	WSEC_MODE_SW		2
+-
+-#define	WSEC_ALGO_OFF		0
+-#define	WSEC_ALGO_WEP1		1
+-#define	WSEC_ALGO_TKIP		2
+-#define	WSEC_ALGO_AES		3
+-#define	WSEC_ALGO_WEP128	4
+-#define	WSEC_ALGO_AES_LEGACY	5
+-#define	WSEC_ALGO_NALG		6
+-
+-#define	AES_MODE_NONE		0
+-#define	AES_MODE_CCM		1
+-
+-/* WEP_CTL (Rev 0) */
+-#define	WECR0_KEYREG_SHIFT	0
+-#define	WECR0_KEYREG_MASK	0x7
+-#define	WECR0_DECRYPT		(1 << 3)
+-#define	WECR0_IVINLINE		(1 << 4)
+-#define	WECR0_WEPALG_SHIFT	5
+-#define	WECR0_WEPALG_MASK	(0x7 << 5)
+-#define	WECR0_WKEYSEL_SHIFT	8
+-#define	WECR0_WKEYSEL_MASK	(0x7 << 8)
+-#define	WECR0_WKEYSTART		(1 << 11)
+-#define	WECR0_WEPINIT		(1 << 14)
+-#define	WECR0_ICVERR		(1 << 15)
+-
+-/* Frame template map byte offsets */
+-#define	T_ACTS_TPL_BASE		(0)
+-#define	T_NULL_TPL_BASE		(0xc * 2)
+-#define	T_QNULL_TPL_BASE	(0x1c * 2)
+-#define	T_RR_TPL_BASE		(0x2c * 2)
+-#define	T_BCN0_TPL_BASE		(0x34 * 2)
+-#define	T_PRS_TPL_BASE		(0x134 * 2)
+-#define	T_BCN1_TPL_BASE		(0x234 * 2)
+-#define T_TX_FIFO_TXRAM_BASE	(T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT))
+-
+-#define T_BA_TPL_BASE		T_QNULL_TPL_BASE	/* template area for BA */
+-
+-#define T_RAM_ACCESS_SZ		4	/* template ram is 4 byte access only */
+-
+-/* Shared Mem byte offsets */
+-
+-/* Location where the ucode expects the corerev */
+-#define	M_MACHW_VER		(0x00b * 2)
+-
+-/* Location where the ucode expects the MAC capabilities */
+-#define	M_MACHW_CAP_L		(0x060 * 2)
+-#define	M_MACHW_CAP_H	(0x061 * 2)
+-
+-/* WME shared memory */
+-#define M_EDCF_STATUS_OFF	(0x007 * 2)
+-#define M_TXF_CUR_INDEX		(0x018 * 2)
+-#define M_EDCF_QINFO		(0x120 * 2)
+-
+-/* PS-mode related parameters */
+-#define	M_DOT11_SLOT		(0x008 * 2)
+-#define	M_DOT11_DTIMPERIOD	(0x009 * 2)
+-#define	M_NOSLPZNATDTIM		(0x026 * 2)
+-
+-/* Beacon-related parameters */
+-#define	M_BCN0_FRM_BYTESZ	(0x00c * 2)	/* Bcn 0 template length */
+-#define	M_BCN1_FRM_BYTESZ	(0x00d * 2)	/* Bcn 1 template length */
+-#define	M_BCN_TXTSF_OFFSET	(0x00e * 2)
+-#define	M_TIMBPOS_INBEACON	(0x00f * 2)
+-#define	M_SFRMTXCNTFBRTHSD	(0x022 * 2)
+-#define	M_LFRMTXCNTFBRTHSD	(0x023 * 2)
+-#define	M_BCN_PCTLWD		(0x02a * 2)
+-#define M_BCN_LI		(0x05b * 2)	/* beacon listen interval */
+-
+-/* MAX Rx Frame len */
+-#define M_MAXRXFRM_LEN		(0x010 * 2)
+-
+-/* ACK/CTS related params */
+-#define	M_RSP_PCTLWD		(0x011 * 2)
+-
+-/* Hardware Power Control */
+-#define M_TXPWR_N		(0x012 * 2)
+-#define M_TXPWR_TARGET		(0x013 * 2)
+-#define M_TXPWR_MAX		(0x014 * 2)
+-#define M_TXPWR_CUR		(0x019 * 2)
+-
+-/* Rx-related parameters */
+-#define	M_RX_PAD_DATA_OFFSET	(0x01a * 2)
+-
+-/* WEP Shared mem data */
+-#define	M_SEC_DEFIVLOC		(0x01e * 2)
+-#define	M_SEC_VALNUMSOFTMCHTA	(0x01f * 2)
+-#define	M_PHYVER		(0x028 * 2)
+-#define	M_PHYTYPE		(0x029 * 2)
+-#define	M_SECRXKEYS_PTR		(0x02b * 2)
+-#define	M_TKMICKEYS_PTR		(0x059 * 2)
+-#define	M_SECKINDXALGO_BLK	(0x2ea * 2)
+-#define M_SECKINDXALGO_BLK_SZ	54
+-#define	M_SECPSMRXTAMCH_BLK	(0x2fa * 2)
+-#define	M_TKIP_TSC_TTAK		(0x18c * 2)
+-#define	D11_MAX_KEY_SIZE	16
+-
+-#define	M_MAX_ANTCNT		(0x02e * 2)	/* antenna swap threshold */
+-
+-/* Probe response related parameters */
+-#define	M_SSIDLEN		(0x024 * 2)
+-#define	M_PRB_RESP_FRM_LEN	(0x025 * 2)
+-#define	M_PRS_MAXTIME		(0x03a * 2)
+-#define	M_SSID			(0xb0 * 2)
+-#define	M_CTXPRS_BLK		(0xc0 * 2)
+-#define	C_CTX_PCTLWD_POS	(0x4 * 2)
+-
+-/* Delta between OFDM and CCK power in CCK power boost mode */
+-#define M_OFDM_OFFSET		(0x027 * 2)
+-
+-/* TSSI for last 4 11b/g CCK packets transmitted */
+-#define	M_B_TSSI_0		(0x02c * 2)
+-#define	M_B_TSSI_1		(0x02d * 2)
+-
+-/* Host flags to turn on ucode options */
+-#define	M_HOST_FLAGS1		(0x02f * 2)
+-#define	M_HOST_FLAGS2		(0x030 * 2)
+-#define	M_HOST_FLAGS3		(0x031 * 2)
+-#define	M_HOST_FLAGS4		(0x03c * 2)
+-#define	M_HOST_FLAGS5		(0x06a * 2)
+-#define	M_HOST_FLAGS_SZ		16
+-
+-#define M_RADAR_REG		(0x033 * 2)
+-
+-/* TSSI for last 4 11a OFDM packets transmitted */
+-#define	M_A_TSSI_0		(0x034 * 2)
+-#define	M_A_TSSI_1		(0x035 * 2)
+-
+-/* noise interference measurement */
+-#define M_NOISE_IF_COUNT	(0x034 * 2)
+-#define M_NOISE_IF_TIMEOUT	(0x035 * 2)
+-
+-#define	M_RF_RX_SP_REG1		(0x036 * 2)
+-
+-/* TSSI for last 4 11g OFDM packets transmitted */
+-#define	M_G_TSSI_0		(0x038 * 2)
+-#define	M_G_TSSI_1		(0x039 * 2)
+-
+-/* Background noise measure */
+-#define	M_JSSI_0		(0x44 * 2)
+-#define	M_JSSI_1		(0x45 * 2)
+-#define	M_JSSI_AUX		(0x46 * 2)
+-
+-#define	M_CUR_2050_RADIOCODE	(0x47 * 2)
+-
+-/* TX fifo sizes */
+-#define M_FIFOSIZE0		(0x4c * 2)
+-#define M_FIFOSIZE1		(0x4d * 2)
+-#define M_FIFOSIZE2		(0x4e * 2)
+-#define M_FIFOSIZE3		(0x4f * 2)
+-#define D11_MAX_TX_FRMS		32	/* max frames allowed in tx fifo */
+-
+-/* Current channel number plus upper bits */
+-#define M_CURCHANNEL		(0x50 * 2)
+-#define D11_CURCHANNEL_5G	0x0100;
+-#define D11_CURCHANNEL_40	0x0200;
+-#define D11_CURCHANNEL_MAX	0x00FF;
+-
+-/* last posted frameid on the bcmc fifo */
+-#define M_BCMC_FID		(0x54 * 2)
+-#define INVALIDFID		0xffff
+-
+-/* extended beacon phyctl bytes for 11N */
+-#define	M_BCN_PCTL1WD		(0x058 * 2)
+-
+-/* idle busy ratio to duty_cycle requirement  */
+-#define M_TX_IDLE_BUSY_RATIO_X_16_CCK  (0x52 * 2)
+-#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2)
+-
+-/* CW RSSI for LCNPHY */
+-#define M_LCN_RSSI_0 		0x1332
+-#define M_LCN_RSSI_1 		0x1338
+-#define M_LCN_RSSI_2 		0x133e
+-#define M_LCN_RSSI_3 		0x1344
+-
+-/* SNR for LCNPHY */
+-#define M_LCN_SNR_A_0 	0x1334
+-#define M_LCN_SNR_B_0 	0x1336
+-
+-#define M_LCN_SNR_A_1 	0x133a
+-#define M_LCN_SNR_B_1 	0x133c
+-
+-#define M_LCN_SNR_A_2 	0x1340
+-#define M_LCN_SNR_B_2 	0x1342
+-
+-#define M_LCN_SNR_A_3 	0x1346
+-#define M_LCN_SNR_B_3 	0x1348
+-
+-#define M_LCN_LAST_RESET 	(81*2)
+-#define M_LCN_LAST_LOC	(63*2)
+-#define M_LCNPHY_RESET_STATUS (4902)
+-#define M_LCNPHY_DSC_TIME	(0x98d*2)
+-#define M_LCNPHY_RESET_CNT_DSC (0x98b*2)
+-#define M_LCNPHY_RESET_CNT	(0x98c*2)
+-
+-/* Rate table offsets */
+-#define	M_RT_DIRMAP_A		(0xe0 * 2)
+-#define	M_RT_BBRSMAP_A		(0xf0 * 2)
+-#define	M_RT_DIRMAP_B		(0x100 * 2)
+-#define	M_RT_BBRSMAP_B		(0x110 * 2)
+-
+-/* Rate table entry offsets */
+-#define	M_RT_PRS_PLCP_POS	10
+-#define	M_RT_PRS_DUR_POS	16
+-#define	M_RT_OFDM_PCTL1_POS	18
+-
+-#define M_20IN40_IQ			(0x380 * 2)
+-
+-/* SHM locations where ucode stores the current power index */
+-#define M_CURR_IDX1		(0x384 * 2)
+-#define M_CURR_IDX2		(0x387 * 2)
+-
+-#define M_BSCALE_ANT0	(0x5e * 2)
+-#define M_BSCALE_ANT1	(0x5f * 2)
+-
+-/* Antenna Diversity Testing */
+-#define M_MIMO_ANTSEL_RXDFLT	(0x63 * 2)
+-#define M_ANTSEL_CLKDIV	(0x61 * 2)
+-#define M_MIMO_ANTSEL_TXDFLT	(0x64 * 2)
+-
+-#define M_MIMO_MAXSYM	(0x5d * 2)
+-#define MIMO_MAXSYM_DEF		0x8000	/* 32k */
+-#define MIMO_MAXSYM_MAX		0xffff	/* 64k */
+-
+-#define M_WATCHDOG_8TU		(0x1e * 2)
+-#define WATCHDOG_8TU_DEF	5
+-#define WATCHDOG_8TU_MAX	10
+-
+-/* Manufacturing Test Variables */
+-#define M_PKTENG_CTRL		(0x6c * 2)	/* PER test mode */
+-#define M_PKTENG_IFS		(0x6d * 2)	/* IFS for TX mode */
+-#define M_PKTENG_FRMCNT_LO		(0x6e * 2)	/* Lower word of tx frmcnt/rx lostcnt */
+-#define M_PKTENG_FRMCNT_HI		(0x6f * 2)	/* Upper word of tx frmcnt/rx lostcnt */
+-
+-/* Index variation in vbat ripple */
+-#define M_LCN_PWR_IDX_MAX	(0x67 * 2)	/* highest index read by ucode */
+-#define M_LCN_PWR_IDX_MIN	(0x66 * 2)	/* lowest index read by ucode */
+-
+-/* M_PKTENG_CTRL bit definitions */
+-#define M_PKTENG_MODE_TX		0x0001
+-#define M_PKTENG_MODE_TX_RIFS	        0x0004
+-#define M_PKTENG_MODE_TX_CTS            0x0008
+-#define M_PKTENG_MODE_RX		0x0002
+-#define M_PKTENG_MODE_RX_WITH_ACK	0x0402
+-#define M_PKTENG_MODE_MASK		0x0003
+-#define M_PKTENG_FRMCNT_VLD		0x0100	/* TX frames indicated in the frmcnt reg */
+-
+-/* Sample Collect parameters (bitmap and type) */
+-#define M_SMPL_COL_BMP		(0x37d * 2)	/* Trigger bitmap for sample collect */
+-#define M_SMPL_COL_CTL		(0x3b2 * 2)	/* Sample collect type */
+-
+-#define ANTSEL_CLKDIV_4MHZ	6
+-#define MIMO_ANTSEL_BUSY	0x4000	/* bit 14 (busy) */
+-#define MIMO_ANTSEL_SEL		0x8000	/* bit 15 write the value */
+-#define MIMO_ANTSEL_WAIT	50	/* 50us wait */
+-#define MIMO_ANTSEL_OVERRIDE	0x8000	/* flag */
+-
+-typedef struct shm_acparams shm_acparams_t;
+-struct shm_acparams {
+-	u16 txop;
+-	u16 cwmin;
+-	u16 cwmax;
+-	u16 cwcur;
+-	u16 aifs;
+-	u16 bslots;
+-	u16 reggap;
+-	u16 status;
+-	u16 rsvd[8];
+-} __attribute__((packed));
+-#define M_EDCF_QLEN	(16 * 2)
+-
+-#define WME_STATUS_NEWAC	(1 << 8)
+-
+-/* M_HOST_FLAGS */
+-#define MHFMAX		5	/* Number of valid hostflag half-word (u16) */
+-#define MHF1		0	/* Hostflag 1 index */
+-#define MHF2		1	/* Hostflag 2 index */
+-#define MHF3		2	/* Hostflag 3 index */
+-#define MHF4		3	/* Hostflag 4 index */
+-#define MHF5		4	/* Hostflag 5 index */
+-
+-/* Flags in M_HOST_FLAGS */
+-#define	MHF1_ANTDIV		0x0001	/* Enable ucode antenna diversity help */
+-#define	MHF1_EDCF		0x0100	/* Enable EDCF access control */
+-#define MHF1_IQSWAP_WAR		0x0200
+-#define	MHF1_FORCEFASTCLK	0x0400	/* Disable Slow clock request, for corerev < 11 */
+-
+-/* Flags in M_HOST_FLAGS2 */
+-#define MHF2_PCISLOWCLKWAR	0x0008	/* PR16165WAR : Enable ucode PCI slow clock WAR */
+-#define MHF2_TXBCMC_NOW		0x0040	/* Flush BCMC FIFO immediately */
+-#define MHF2_HWPWRCTL		0x0080	/* Enable ucode/hw power control */
+-#define MHF2_NPHY40MHZ_WAR	0x0800
+-
+-/* Flags in M_HOST_FLAGS3 */
+-#define MHF3_ANTSEL_EN		0x0001	/* enabled mimo antenna selection */
+-#define MHF3_ANTSEL_MODE	0x0002	/* antenna selection mode: 0: 2x3, 1: 2x4 */
+-#define MHF3_RESERVED1		0x0004
+-#define MHF3_RESERVED2		0x0008
+-#define MHF3_NPHY_MLADV_WAR	0x0010
+-
+-/* Flags in M_HOST_FLAGS4 */
+-#define MHF4_BPHY_TXCORE0	0x0080	/* force bphy Tx on core 0 (board level WAR) */
+-#define MHF4_EXTPA_ENABLE  	0x4000	/* for 4313A0 FEM boards */
+-
+-/* Flags in M_HOST_FLAGS5 */
+-#define MHF5_4313_GPIOCTRL	0x0001
+-#define MHF5_RESERVED1		0x0002
+-#define MHF5_RESERVED2		0x0004
+-/* Radio power setting for ucode */
+-#define	M_RADIO_PWR		(0x32 * 2)
+-
+-/* phy noise recorded by ucode right after tx */
+-#define	M_PHY_NOISE		(0x037 * 2)
+-#define	PHY_NOISE_MASK		0x00ff
+-
+-/* Receive Frame Data Header for 802.11b DCF-only frames */
+-typedef struct d11rxhdr d11rxhdr_t;
+-struct d11rxhdr {
+-	u16 RxFrameSize;	/* Actual byte length of the frame data received */
+-	u16 PAD;
+-	u16 PhyRxStatus_0;	/* PhyRxStatus 15:0 */
+-	u16 PhyRxStatus_1;	/* PhyRxStatus 31:16 */
+-	u16 PhyRxStatus_2;	/* PhyRxStatus 47:32 */
+-	u16 PhyRxStatus_3;	/* PhyRxStatus 63:48 */
+-	u16 PhyRxStatus_4;	/* PhyRxStatus 79:64 */
+-	u16 PhyRxStatus_5;	/* PhyRxStatus 95:80 */
+-	u16 RxStatus1;	/* MAC Rx Status */
+-	u16 RxStatus2;	/* extended MAC Rx status */
+-	u16 RxTSFTime;	/* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */
+-	u16 RxChan;		/* gain code, channel radio code, and phy type */
+-} __attribute__((packed));
+-
+-#define	RXHDR_LEN		24	/* sizeof d11rxhdr_t */
+-#define	FRAMELEN(h)		((h)->RxFrameSize)
+-
+-typedef struct wlc_d11rxhdr wlc_d11rxhdr_t;
+-struct wlc_d11rxhdr {
+-	d11rxhdr_t rxhdr;
+-	u32 tsf_l;		/* TSF_L reading */
+-	s8 rssi;		/* computed instanteneous rssi in BMAC */
+-	s8 rxpwr0;		/* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+-	s8 rxpwr1;		/* obsoleted, place holder for legacy ROM code. use rxpwr[] */
+-	s8 do_rssi_ma;	/* do per-pkt sampling for per-antenna ma in HIGH */
+-	s8 rxpwr[WL_RSSI_ANT_MAX];	/* rssi for supported antennas */
+-} __attribute__((packed));
+-
+-/* PhyRxStatus_0: */
+-#define	PRXS0_FT_MASK		0x0003	/* NPHY only: CCK, OFDM, preN, N */
+-#define	PRXS0_CLIP_MASK		0x000C	/* NPHY only: clip count adjustment steps by AGC */
+-#define	PRXS0_CLIP_SHIFT	2
+-#define	PRXS0_UNSRATE		0x0010	/* PHY received a frame with unsupported rate */
+-#define	PRXS0_RXANT_UPSUBBAND	0x0020	/* GPHY: rx ant, NPHY: upper sideband */
+-#define	PRXS0_LCRS		0x0040	/* CCK frame only: lost crs during cck frame reception */
+-#define	PRXS0_SHORTH		0x0080	/* Short Preamble */
+-#define	PRXS0_PLCPFV		0x0100	/* PLCP violation */
+-#define	PRXS0_PLCPHCF		0x0200	/* PLCP header integrity check failed */
+-#define	PRXS0_GAIN_CTL		0x4000	/* legacy PHY gain control */
+-#define PRXS0_ANTSEL_MASK	0xF000	/* NPHY: Antennas used for received frame, bitmask */
+-#define PRXS0_ANTSEL_SHIFT	0x12
+-
+-/* subfield PRXS0_FT_MASK */
+-#define	PRXS0_CCK		0x0000
+-#define	PRXS0_OFDM		0x0001	/* valid only for G phy, use rxh->RxChan for A phy */
+-#define	PRXS0_PREN		0x0002
+-#define	PRXS0_STDN		0x0003
+-
+-/* subfield PRXS0_ANTSEL_MASK */
+-#define PRXS0_ANTSEL_0		0x0	/* antenna 0 is used */
+-#define PRXS0_ANTSEL_1		0x2	/* antenna 1 is used */
+-#define PRXS0_ANTSEL_2		0x4	/* antenna 2 is used */
+-#define PRXS0_ANTSEL_3		0x8	/* antenna 3 is used */
+-
+-/* PhyRxStatus_1: */
+-#define	PRXS1_JSSI_MASK		0x00FF
+-#define	PRXS1_JSSI_SHIFT	0
+-#define	PRXS1_SQ_MASK		0xFF00
+-#define	PRXS1_SQ_SHIFT		8
+-
+-/* nphy PhyRxStatus_1: */
+-#define PRXS1_nphy_PWR0_MASK	0x00FF
+-#define PRXS1_nphy_PWR1_MASK	0xFF00
+-
+-/* HTPHY Rx Status defines */
+-/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */
+-#define PRXS0_BAND	        0x0400	/* 0 = 2.4G, 1 = 5G */
+-#define PRXS0_RSVD	        0x0800	/* reserved; set to 0 */
+-#define PRXS0_UNUSED	        0xF000	/* unused and not defined; set to 0 */
+-
+-/* htphy PhyRxStatus_1: */
+-#define PRXS1_HTPHY_CORE_MASK	0x000F	/* core enables for {3..0}, 0=disabled, 1=enabled */
+-#define PRXS1_HTPHY_ANTCFG_MASK	0x00F0	/* antenna configation */
+-#define PRXS1_HTPHY_MMPLCPLenL_MASK	0xFF00	/* Mixmode PLCP Length low byte mask */
+-
+-/* htphy PhyRxStatus_2: */
+-#define PRXS2_HTPHY_MMPLCPLenH_MASK	0x000F	/* Mixmode PLCP Length high byte maskw */
+-#define PRXS2_HTPHY_MMPLCH_RATE_MASK	0x00F0	/* Mixmode PLCP rate mask */
+-#define PRXS2_HTPHY_RXPWR_ANT0	0xFF00	/* Rx power on core 0 */
+-
+-/* htphy PhyRxStatus_3: */
+-#define PRXS3_HTPHY_RXPWR_ANT1	0x00FF	/* Rx power on core 1 */
+-#define PRXS3_HTPHY_RXPWR_ANT2	0xFF00	/* Rx power on core 2 */
+-
+-/* htphy PhyRxStatus_4: */
+-#define PRXS4_HTPHY_RXPWR_ANT3	0x00FF	/* Rx power on core 3 */
+-#define PRXS4_HTPHY_CFO		0xFF00	/* Coarse frequency offset */
+-
+-/* htphy PhyRxStatus_5: */
+-#define PRXS5_HTPHY_FFO	        0x00FF	/* Fine frequency offset */
+-#define PRXS5_HTPHY_AR	        0xFF00	/* Advance Retard */
+-
+-#define HTPHY_MMPLCPLen(rxs)	((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \
+-	(((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8))
+-/* Get Rx power on core 0 */
+-#define HTPHY_RXPWR_ANT0(rxs)	((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8)
+-/* Get Rx power on core 1 */
+-#define HTPHY_RXPWR_ANT1(rxs)	(((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1)
+-/* Get Rx power on core 2 */
+-#define HTPHY_RXPWR_ANT2(rxs)	((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8)
+-
+-/* ucode RxStatus1: */
+-#define	RXS_BCNSENT		0x8000
+-#define	RXS_SECKINDX_MASK	0x07e0
+-#define	RXS_SECKINDX_SHIFT	5
+-#define	RXS_DECERR		(1 << 4)
+-#define	RXS_DECATMPT		(1 << 3)
+-#define	RXS_PBPRES		(1 << 2)	/* PAD bytes to make IP data 4 bytes aligned */
+-#define	RXS_RESPFRAMETX		(1 << 1)
+-#define	RXS_FCSERR		(1 << 0)
+-
+-/* ucode RxStatus2: */
+-#define RXS_AMSDU_MASK		1
+-#define	RXS_AGGTYPE_MASK	0x6
+-#define	RXS_AGGTYPE_SHIFT	1
+-#define	RXS_PHYRXST_VALID	(1 << 8)
+-#define RXS_RXANT_MASK		0x3
+-#define RXS_RXANT_SHIFT		12
+-
+-/* RxChan */
+-#define RXS_CHAN_40		0x1000
+-#define RXS_CHAN_5G		0x0800
+-#define	RXS_CHAN_ID_MASK	0x07f8
+-#define	RXS_CHAN_ID_SHIFT	3
+-#define	RXS_CHAN_PHYTYPE_MASK	0x0007
+-#define	RXS_CHAN_PHYTYPE_SHIFT	0
+-
+-/* Index of attenuations used during ucode power control. */
+-#define M_PWRIND_BLKS	(0x184 * 2)
+-#define M_PWRIND_MAP0	(M_PWRIND_BLKS + 0x0)
+-#define M_PWRIND_MAP1	(M_PWRIND_BLKS + 0x2)
+-#define M_PWRIND_MAP2	(M_PWRIND_BLKS + 0x4)
+-#define M_PWRIND_MAP3	(M_PWRIND_BLKS + 0x6)
+-/* M_PWRIND_MAP(core) macro */
+-#define M_PWRIND_MAP(core)  (M_PWRIND_BLKS + ((core)<<1))
+-
+-/* PSM SHM variable offsets */
+-#define	M_PSM_SOFT_REGS	0x0
+-#define	M_BOM_REV_MAJOR	(M_PSM_SOFT_REGS + 0x0)
+-#define	M_BOM_REV_MINOR	(M_PSM_SOFT_REGS + 0x2)
+-#define	M_UCODE_DBGST	(M_PSM_SOFT_REGS + 0x40)	/* ucode debug status code */
+-#define	M_UCODE_MACSTAT	(M_PSM_SOFT_REGS + 0xE0)	/* macstat counters */
+-
+-#define M_AGING_THRSH	(0x3e * 2)	/* max time waiting for medium before tx */
+-#define	M_MBURST_SIZE	(0x40 * 2)	/* max frames in a frameburst */
+-#define	M_MBURST_TXOP	(0x41 * 2)	/* max frameburst TXOP in unit of us */
+-#define M_SYNTHPU_DLY	(0x4a * 2)	/* pre-wakeup for synthpu, default: 500 */
+-#define	M_PRETBTT	(0x4b * 2)
+-
+-#define M_ALT_TXPWR_IDX		(M_PSM_SOFT_REGS + (0x3b * 2))	/* offset to the target txpwr */
+-#define M_PHY_TX_FLT_PTR	(M_PSM_SOFT_REGS + (0x3d * 2))
+-#define M_CTS_DURATION		(M_PSM_SOFT_REGS + (0x5c * 2))
+-#define M_LP_RCCAL_OVR		(M_PSM_SOFT_REGS + (0x6b * 2))
+-
+-/* PKTENG Rx Stats Block */
+-#define M_RXSTATS_BLK_PTR	(M_PSM_SOFT_REGS + (0x65 * 2))
+-
+-/* ucode debug status codes */
+-#define	DBGST_INACTIVE		0	/* not valid really */
+-#define	DBGST_INIT		1	/* after zeroing SHM, before suspending at init */
+-#define	DBGST_ACTIVE		2	/* "normal" state */
+-#define	DBGST_SUSPENDED		3	/* suspended */
+-#define	DBGST_ASLEEP		4	/* asleep (PS mode) */
+-
+-/* Scratch Reg defs */
+-typedef enum {
+-	S_RSV0 = 0,
+-	S_RSV1,
+-	S_RSV2,
+-
+-	/* scratch registers for Dot11-contants */
+-	S_DOT11_CWMIN,		/* CW-minimum                                   0x03 */
+-	S_DOT11_CWMAX,		/* CW-maximum                                   0x04 */
+-	S_DOT11_CWCUR,		/* CW-current                                   0x05 */
+-	S_DOT11_SRC_LMT,	/* short retry count limit                      0x06 */
+-	S_DOT11_LRC_LMT,	/* long retry count limit                       0x07 */
+-	S_DOT11_DTIMCOUNT,	/* DTIM-count                                   0x08 */
+-
+-	/* Tx-side scratch registers */
+-	S_SEQ_NUM,		/* hardware sequence number reg                 0x09 */
+-	S_SEQ_NUM_FRAG,		/* seq-num for frags (Set at the start os MSDU  0x0A */
+-	S_FRMRETX_CNT,		/* frame retx count                             0x0B */
+-	S_SSRC,			/* Station short retry count                    0x0C */
+-	S_SLRC,			/* Station long retry count                     0x0D */
+-	S_EXP_RSP,		/* Expected response frame                      0x0E */
+-	S_OLD_BREM,		/* Remaining backoff ctr                        0x0F */
+-	S_OLD_CWWIN,		/* saved-off CW-cur                             0x10 */
+-	S_TXECTL,		/* TXE-Ctl word constructed in scr-pad          0x11 */
+-	S_CTXTST,		/* frm type-subtype as read from Tx-descr       0x12 */
+-
+-	/* Rx-side scratch registers */
+-	S_RXTST,		/* Type and subtype in Rxframe                  0x13 */
+-
+-	/* Global state register */
+-	S_STREG,		/* state storage actual bit maps below          0x14 */
+-
+-	S_TXPWR_SUM,		/* Tx power control: accumulator                0x15 */
+-	S_TXPWR_ITER,		/* Tx power control: iteration                  0x16 */
+-	S_RX_FRMTYPE,		/* Rate and PHY type for frames                 0x17 */
+-	S_THIS_AGG,		/* Size of this AGG (A-MSDU)                    0x18 */
+-
+-	S_KEYINDX,		/*                                              0x19 */
+-	S_RXFRMLEN,		/* Receive MPDU length in bytes                 0x1A */
+-
+-	/* Receive TSF time stored in SCR */
+-	S_RXTSFTMRVAL_WD3,	/* TSF value at the start of rx                 0x1B */
+-	S_RXTSFTMRVAL_WD2,	/* TSF value at the start of rx                 0x1C */
+-	S_RXTSFTMRVAL_WD1,	/* TSF value at the start of rx                 0x1D */
+-	S_RXTSFTMRVAL_WD0,	/* TSF value at the start of rx                 0x1E */
+-	S_RXSSN,		/* Received start seq number for A-MPDU BA      0x1F */
+-	S_RXQOSFLD,		/* Rx-QoS field (if present)                    0x20 */
+-
+-	/* Scratch pad regs used in microcode as temp storage */
+-	S_TMP0,			/* stmp0                                        0x21 */
+-	S_TMP1,			/* stmp1                                        0x22 */
+-	S_TMP2,			/* stmp2                                        0x23 */
+-	S_TMP3,			/* stmp3                                        0x24 */
+-	S_TMP4,			/* stmp4                                        0x25 */
+-	S_TMP5,			/* stmp5                                        0x26 */
+-	S_PRQPENALTY_CTR,	/* Probe response queue penalty counter         0x27 */
+-	S_ANTCNT,		/* unsuccessful attempts on current ant.        0x28 */
+-	S_SYMBOL,		/* flag for possible symbol ctl frames          0x29 */
+-	S_RXTP,			/* rx frame type                                0x2A */
+-	S_STREG2,		/* extra state storage                          0x2B */
+-	S_STREG3,		/* even more extra state storage                0x2C */
+-	S_STREG4,		/* ...                                          0x2D */
+-	S_STREG5,		/* remember to initialize it to zero            0x2E */
+-
+-	S_ADJPWR_IDX,
+-	S_CUR_PTR,		/* Temp pointer for A-MPDU re-Tx SHM table      0x32 */
+-	S_REVID4,		/* 0x33 */
+-	S_INDX,			/* 0x34 */
+-	S_ADDR0,		/* 0x35 */
+-	S_ADDR1,		/* 0x36 */
+-	S_ADDR2,		/* 0x37 */
+-	S_ADDR3,		/* 0x38 */
+-	S_ADDR4,		/* 0x39 */
+-	S_ADDR5,		/* 0x3A */
+-	S_TMP6,			/* 0x3B */
+-	S_KEYINDX_BU,		/* Backup for Key index                         0x3C */
+-	S_MFGTEST_TMP0,		/* Temp register used for RX test calculations  0x3D */
+-	S_RXESN,		/* Received end sequence number for A-MPDU BA   0x3E */
+-	S_STREG6,		/* 0x3F */
+-} ePsmScratchPadRegDefinitions;
+-
+-#define S_BEACON_INDX	S_OLD_BREM
+-#define S_PRS_INDX	S_OLD_CWWIN
+-#define S_PHYTYPE	S_SSRC
+-#define S_PHYVER	S_SLRC
+-
+-/* IHR SLOW_CTRL values */
+-#define SLOW_CTRL_PDE		(1 << 0)
+-#define SLOW_CTRL_FD		(1 << 8)
+-
+-/* ucode mac statistic counters in shared memory */
+-typedef struct macstat {
+-	u16 txallfrm;	/* 0x80 */
+-	u16 txrtsfrm;	/* 0x82 */
+-	u16 txctsfrm;	/* 0x84 */
+-	u16 txackfrm;	/* 0x86 */
+-	u16 txdnlfrm;	/* 0x88 */
+-	u16 txbcnfrm;	/* 0x8a */
+-	u16 txfunfl[8];	/* 0x8c - 0x9b */
+-	u16 txtplunfl;	/* 0x9c */
+-	u16 txphyerr;	/* 0x9e */
+-	u16 pktengrxducast;	/* 0xa0 */
+-	u16 pktengrxdmcast;	/* 0xa2 */
+-	u16 rxfrmtoolong;	/* 0xa4 */
+-	u16 rxfrmtooshrt;	/* 0xa6 */
+-	u16 rxinvmachdr;	/* 0xa8 */
+-	u16 rxbadfcs;	/* 0xaa */
+-	u16 rxbadplcp;	/* 0xac */
+-	u16 rxcrsglitch;	/* 0xae */
+-	u16 rxstrt;		/* 0xb0 */
+-	u16 rxdfrmucastmbss;	/* 0xb2 */
+-	u16 rxmfrmucastmbss;	/* 0xb4 */
+-	u16 rxcfrmucast;	/* 0xb6 */
+-	u16 rxrtsucast;	/* 0xb8 */
+-	u16 rxctsucast;	/* 0xba */
+-	u16 rxackucast;	/* 0xbc */
+-	u16 rxdfrmocast;	/* 0xbe */
+-	u16 rxmfrmocast;	/* 0xc0 */
+-	u16 rxcfrmocast;	/* 0xc2 */
+-	u16 rxrtsocast;	/* 0xc4 */
+-	u16 rxctsocast;	/* 0xc6 */
+-	u16 rxdfrmmcast;	/* 0xc8 */
+-	u16 rxmfrmmcast;	/* 0xca */
+-	u16 rxcfrmmcast;	/* 0xcc */
+-	u16 rxbeaconmbss;	/* 0xce */
+-	u16 rxdfrmucastobss;	/* 0xd0 */
+-	u16 rxbeaconobss;	/* 0xd2 */
+-	u16 rxrsptmout;	/* 0xd4 */
+-	u16 bcntxcancl;	/* 0xd6 */
+-	u16 PAD;
+-	u16 rxf0ovfl;	/* 0xda */
+-	u16 rxf1ovfl;	/* 0xdc */
+-	u16 rxf2ovfl;	/* 0xde */
+-	u16 txsfovfl;	/* 0xe0 */
+-	u16 pmqovfl;		/* 0xe2 */
+-	u16 rxcgprqfrm;	/* 0xe4 */
+-	u16 rxcgprsqovfl;	/* 0xe6 */
+-	u16 txcgprsfail;	/* 0xe8 */
+-	u16 txcgprssuc;	/* 0xea */
+-	u16 prs_timeout;	/* 0xec */
+-	u16 rxnack;
+-	u16 frmscons;
+-	u16 txnack;
+-	u16 txglitch_nack;
+-	u16 txburst;		/* 0xf6 # tx bursts */
+-	u16 bphy_rxcrsglitch;	/* bphy rx crs glitch */
+-	u16 phywatchdog;	/* 0xfa # of phy watchdog events */
+-	u16 PAD;
+-	u16 bphy_badplcp;	/* bphy bad plcp */
+-} macstat_t;
+-
+-/* dot11 core-specific control flags */
+-#define	SICF_PCLKE		0x0004	/* PHY clock enable */
+-#define	SICF_PRST		0x0008	/* PHY reset */
+-#define	SICF_MPCLKE		0x0010	/* MAC PHY clockcontrol enable */
+-#define	SICF_FREF		0x0020	/* PLL FreqRefSelect */
+-/* NOTE: the following bw bits only apply when the core is attached
+- * to a NPHY
+- */
+-#define	SICF_BWMASK		0x00c0	/* phy clock mask (b6 & b7) */
+-#define	SICF_BW40		0x0080	/* 40MHz BW (160MHz phyclk) */
+-#define	SICF_BW20		0x0040	/* 20MHz BW (80MHz phyclk) */
+-#define	SICF_BW10		0x0000	/* 10MHz BW (40MHz phyclk) */
+-#define	SICF_GMODE		0x2000	/* gmode enable */
+-
+-/* dot11 core-specific status flags */
+-#define	SISF_2G_PHY		0x0001	/* 2.4G capable phy */
+-#define	SISF_5G_PHY		0x0002	/* 5G capable phy */
+-#define	SISF_FCLKA		0x0004	/* FastClkAvailable */
+-#define	SISF_DB_PHY		0x0008	/* Dualband phy */
+-
+-/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */
+-
+-#define	BPHY_REG_OFT_BASE	0x0
+-/* offsets for indirect access to bphy registers */
+-#define	BPHY_BB_CONFIG		0x01
+-#define	BPHY_ADCBIAS		0x02
+-#define	BPHY_ANACORE		0x03
+-#define	BPHY_PHYCRSTH		0x06
+-#define	BPHY_TEST		0x0a
+-#define	BPHY_PA_TX_TO		0x10
+-#define	BPHY_SYNTH_DC_TO	0x11
+-#define	BPHY_PA_TX_TIME_UP	0x12
+-#define	BPHY_RX_FLTR_TIME_UP	0x13
+-#define	BPHY_TX_POWER_OVERRIDE	0x14
+-#define	BPHY_RF_OVERRIDE	0x15
+-#define	BPHY_RF_TR_LOOKUP1	0x16
+-#define	BPHY_RF_TR_LOOKUP2	0x17
+-#define	BPHY_COEFFS		0x18
+-#define	BPHY_PLL_OUT		0x19
+-#define	BPHY_REFRESH_MAIN	0x1a
+-#define	BPHY_REFRESH_TO0	0x1b
+-#define	BPHY_REFRESH_TO1	0x1c
+-#define	BPHY_RSSI_TRESH		0x20
+-#define	BPHY_IQ_TRESH_HH	0x21
+-#define	BPHY_IQ_TRESH_H		0x22
+-#define	BPHY_IQ_TRESH_L		0x23
+-#define	BPHY_IQ_TRESH_LL	0x24
+-#define	BPHY_GAIN		0x25
+-#define	BPHY_LNA_GAIN_RANGE	0x26
+-#define	BPHY_JSSI		0x27
+-#define	BPHY_TSSI_CTL		0x28
+-#define	BPHY_TSSI		0x29
+-#define	BPHY_TR_LOSS_CTL	0x2a
+-#define	BPHY_LO_LEAKAGE		0x2b
+-#define	BPHY_LO_RSSI_ACC	0x2c
+-#define	BPHY_LO_IQMAG_ACC	0x2d
+-#define	BPHY_TX_DC_OFF1		0x2e
+-#define	BPHY_TX_DC_OFF2		0x2f
+-#define	BPHY_PEAK_CNT_THRESH	0x30
+-#define	BPHY_FREQ_OFFSET	0x31
+-#define	BPHY_DIVERSITY_CTL	0x32
+-#define	BPHY_PEAK_ENERGY_LO	0x33
+-#define	BPHY_PEAK_ENERGY_HI	0x34
+-#define	BPHY_SYNC_CTL		0x35
+-#define	BPHY_TX_PWR_CTRL	0x36
+-#define BPHY_TX_EST_PWR 	0x37
+-#define	BPHY_STEP		0x38
+-#define	BPHY_WARMUP		0x39
+-#define	BPHY_LMS_CFF_READ	0x3a
+-#define	BPHY_LMS_COEFF_I	0x3b
+-#define	BPHY_LMS_COEFF_Q	0x3c
+-#define	BPHY_SIG_POW		0x3d
+-#define	BPHY_RFDC_CANCEL_CTL	0x3e
+-#define	BPHY_HDR_TYPE		0x40
+-#define	BPHY_SFD_TO		0x41
+-#define	BPHY_SFD_CTL		0x42
+-#define	BPHY_DEBUG		0x43
+-#define	BPHY_RX_DELAY_COMP	0x44
+-#define	BPHY_CRS_DROP_TO	0x45
+-#define	BPHY_SHORT_SFD_NZEROS	0x46
+-#define	BPHY_DSSS_COEFF1	0x48
+-#define	BPHY_DSSS_COEFF2	0x49
+-#define	BPHY_CCK_COEFF1		0x4a
+-#define	BPHY_CCK_COEFF2		0x4b
+-#define	BPHY_TR_CORR		0x4c
+-#define	BPHY_ANGLE_SCALE	0x4d
+-#define	BPHY_TX_PWR_BASE_IDX	0x4e
+-#define	BPHY_OPTIONAL_MODES2	0x4f
+-#define	BPHY_CCK_LMS_STEP	0x50
+-#define	BPHY_BYPASS		0x51
+-#define	BPHY_CCK_DELAY_LONG	0x52
+-#define	BPHY_CCK_DELAY_SHORT	0x53
+-#define	BPHY_PPROC_CHAN_DELAY	0x54
+-#define	BPHY_DDFS_ENABLE	0x58
+-#define	BPHY_PHASE_SCALE	0x59
+-#define	BPHY_FREQ_CONTROL	0x5a
+-#define	BPHY_LNA_GAIN_RANGE_10	0x5b
+-#define	BPHY_LNA_GAIN_RANGE_32	0x5c
+-#define	BPHY_OPTIONAL_MODES	0x5d
+-#define	BPHY_RX_STATUS2		0x5e
+-#define	BPHY_RX_STATUS3		0x5f
+-#define	BPHY_DAC_CONTROL	0x60
+-#define	BPHY_ANA11G_FILT_CTRL	0x62
+-#define	BPHY_REFRESH_CTRL	0x64
+-#define	BPHY_RF_OVERRIDE2	0x65
+-#define	BPHY_SPUR_CANCEL_CTRL	0x66
+-#define	BPHY_FINE_DIGIGAIN_CTRL	0x67
+-#define	BPHY_RSSI_LUT		0x88
+-#define	BPHY_RSSI_LUT_END	0xa7
+-#define	BPHY_TSSI_LUT		0xa8
+-#define	BPHY_TSSI_LUT_END	0xc7
+-#define	BPHY_TSSI2PWR_LUT	0x380
+-#define	BPHY_TSSI2PWR_LUT_END	0x39f
+-#define	BPHY_LOCOMP_LUT		0x3a0
+-#define	BPHY_LOCOMP_LUT_END	0x3bf
+-#define	BPHY_TXGAIN_LUT		0x3c0
+-#define	BPHY_TXGAIN_LUT_END	0x3ff
+-
+-/* Bits in BB_CONFIG: */
+-#define	PHY_BBC_ANT_MASK	0x0180
+-#define	PHY_BBC_ANT_SHIFT	7
+-#define	BB_DARWIN		0x1000
+-#define BBCFG_RESETCCA		0x4000
+-#define BBCFG_RESETRX		0x8000
+-
+-/* Bits in phytest(0x0a): */
+-#define	TST_DDFS		0x2000
+-#define	TST_TXFILT1		0x0800
+-#define	TST_UNSCRAM		0x0400
+-#define	TST_CARR_SUPP		0x0200
+-#define	TST_DC_COMP_LOOP	0x0100
+-#define	TST_LOOPBACK		0x0080
+-#define	TST_TXFILT0		0x0040
+-#define	TST_TXTEST_ENABLE	0x0020
+-#define	TST_TXTEST_RATE		0x0018
+-#define	TST_TXTEST_PHASE	0x0007
+-
+-/* phytest txTestRate values */
+-#define	TST_TXTEST_RATE_1MBPS	0
+-#define	TST_TXTEST_RATE_2MBPS	1
+-#define	TST_TXTEST_RATE_5_5MBPS	2
+-#define	TST_TXTEST_RATE_11MBPS	3
+-#define	TST_TXTEST_RATE_SHIFT	3
+-
+-#define SHM_BYT_CNT	0x2	/* IHR location */
+-#define MAX_BYT_CNT	0x600	/* Maximum frame len */
+-
+-#endif				/* _D11_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/hnddma.c b/drivers/staging/brcm80211/brcmsmac/hnddma.c
+deleted file mode 100644
+index f607315..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/hnddma.c
++++ /dev/null
+@@ -1,1756 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/netdevice.h>
+-#include <linux/pci.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <hndsoc.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#if defined(__mips__)
+-#include <asm/addrspace.h>
+-#endif
+-
+-#ifdef BRCM_FULLMAC
+-#error "hnddma.c shouldn't be needed for FULLMAC"
+-#endif
+-
+-/* debug/trace */
+-#ifdef BCMDBG
+-#define	DMA_ERROR(args) \
+-	do { \
+-		if (!(*di->msg_level & 1)) \
+-			; \
+-		else \
+-			printk args; \
+-	} while (0)
+-#define	DMA_TRACE(args) \
+-	do { \
+-		if (!(*di->msg_level & 2)) \
+-			; \
+-		else \
+-			printk args; \
+-	} while (0)
+-#else
+-#define	DMA_ERROR(args)
+-#define	DMA_TRACE(args)
+-#endif				/* BCMDBG */
+-
+-#define	DMA_NONE(args)
+-
+-#define d64txregs	dregs.d64_u.txregs_64
+-#define d64rxregs	dregs.d64_u.rxregs_64
+-#define txd64		dregs.d64_u.txd_64
+-#define rxd64		dregs.d64_u.rxd_64
+-
+-/* default dma message level (if input msg_level pointer is null in dma_attach()) */
+-static uint dma_msg_level;
+-
+-#define	MAXNAMEL	8	/* 8 char names */
+-
+-#define	DI_INFO(dmah)	((dma_info_t *)dmah)
+-
+-#define R_SM(r)		(*(r))
+-#define W_SM(r, v)	(*(r) = (v))
+-
+-/* dma engine software state */
+-typedef struct dma_info {
+-	struct hnddma_pub hnddma; /* exported structure */
+-	uint *msg_level;	/* message level pointer */
+-	char name[MAXNAMEL];	/* callers name for diag msgs */
+-
+-	void *pbus;		/* bus handle */
+-
+-	bool dma64;		/* this dma engine is operating in 64-bit mode */
+-	bool addrext;		/* this dma engine supports DmaExtendedAddrChanges */
+-
+-	union {
+-		struct {
+-			dma64regs_t *txregs_64;	/* 64-bit dma tx engine registers */
+-			dma64regs_t *rxregs_64;	/* 64-bit dma rx engine registers */
+-			dma64dd_t *txd_64;	/* pointer to dma64 tx descriptor ring */
+-			dma64dd_t *rxd_64;	/* pointer to dma64 rx descriptor ring */
+-		} d64_u;
+-	} dregs;
+-
+-	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
+-
+-	u16 ntxd;		/* # tx descriptors tunable */
+-	u16 txin;		/* index of next descriptor to reclaim */
+-	u16 txout;		/* index of next descriptor to post */
+-	void **txp;		/* pointer to parallel array of pointers to packets */
+-	hnddma_seg_map_t *txp_dmah;	/* DMA MAP meta-data handle */
+-	dmaaddr_t txdpa;	/* Aligned physical address of descriptor ring */
+-	dmaaddr_t txdpaorig;	/* Original physical address of descriptor ring */
+-	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
+-	u32 txdalloc;	/* #bytes allocated for the ring */
+-	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
+-				 * is not just an index, it needs all 13 bits to be
+-				 * an offset from the addr register.
+-				 */
+-
+-	u16 nrxd;		/* # rx descriptors tunable */
+-	u16 rxin;		/* index of next descriptor to reclaim */
+-	u16 rxout;		/* index of next descriptor to post */
+-	void **rxp;		/* pointer to parallel array of pointers to packets */
+-	hnddma_seg_map_t *rxp_dmah;	/* DMA MAP meta-data handle */
+-	dmaaddr_t rxdpa;	/* Aligned physical address of descriptor ring */
+-	dmaaddr_t rxdpaorig;	/* Original physical address of descriptor ring */
+-	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
+-	u32 rxdalloc;	/* #bytes allocated for the ring */
+-	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
+-
+-	/* tunables */
+-	unsigned int rxbufsize;	/* rx buffer size in bytes,
+-				 * not including the extra headroom
+-				 */
+-	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper stack
+-				 *  e.g. some rx pkt buffers will be bridged to tx side
+-				 *  without byte copying. The extra headroom needs to be
+-				 *  large enough to fit txheader needs.
+-				 *  Some dongle driver may not need it.
+-				 */
+-	uint nrxpost;		/* # rx buffers to keep posted */
+-	unsigned int rxoffset;	/* rxcontrol offset */
+-	uint ddoffsetlow;	/* add to get dma address of descriptor ring, low 32 bits */
+-	uint ddoffsethigh;	/*   high 32 bits */
+-	uint dataoffsetlow;	/* add to get dma address of data buffer, low 32 bits */
+-	uint dataoffsethigh;	/*   high 32 bits */
+-	bool aligndesc_4k;	/* descriptor base need to be aligned or not */
+-} dma_info_t;
+-
+-/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
+-#ifdef BCMDMASGLISTOSL
+-#define DMASGLIST_ENAB true
+-#else
+-#define DMASGLIST_ENAB false
+-#endif				/* BCMDMASGLISTOSL */
+-
+-/* descriptor bumping macros */
+-#define	XXD(x, n)	((x) & ((n) - 1))	/* faster than %, but n must be power of 2 */
+-#define	TXD(x)		XXD((x), di->ntxd)
+-#define	RXD(x)		XXD((x), di->nrxd)
+-#define	NEXTTXD(i)	TXD((i) + 1)
+-#define	PREVTXD(i)	TXD((i) - 1)
+-#define	NEXTRXD(i)	RXD((i) + 1)
+-#define	PREVRXD(i)	RXD((i) - 1)
+-
+-#define	NTXDACTIVE(h, t)	TXD((t) - (h))
+-#define	NRXDACTIVE(h, t)	RXD((t) - (h))
+-
+-/* macros to convert between byte offsets and indexes */
+-#define	B2I(bytes, type)	((bytes) / sizeof(type))
+-#define	I2B(index, type)	((index) * sizeof(type))
+-
+-#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
+-#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
+-
+-#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
+-#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
+-
+-/* Common prototypes */
+-static bool _dma_isaddrext(dma_info_t *di);
+-static bool _dma_descriptor_align(dma_info_t *di);
+-static bool _dma_alloc(dma_info_t *di, uint direction);
+-static void _dma_detach(dma_info_t *di);
+-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
+-static void _dma_rxinit(dma_info_t *di);
+-static void *_dma_rx(dma_info_t *di);
+-static bool _dma_rxfill(dma_info_t *di);
+-static void _dma_rxreclaim(dma_info_t *di);
+-static void _dma_rxenable(dma_info_t *di);
+-static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
+-static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
+-			      u16 *rxbufsize);
+-
+-static void _dma_txblock(dma_info_t *di);
+-static void _dma_txunblock(dma_info_t *di);
+-static uint _dma_txactive(dma_info_t *di);
+-static uint _dma_rxactive(dma_info_t *di);
+-static uint _dma_txpending(dma_info_t *di);
+-static uint _dma_txcommitted(dma_info_t *di);
+-
+-static void *_dma_peeknexttxp(dma_info_t *di);
+-static void *_dma_peeknextrxp(dma_info_t *di);
+-static unsigned long _dma_getvar(dma_info_t *di, const char *name);
+-static void _dma_counterreset(dma_info_t *di);
+-static void _dma_fifoloopbackenable(dma_info_t *di);
+-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
+-static u8 dma_align_sizetobits(uint size);
+-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+-			   u16 *alignbits, uint *alloced,
+-			   dmaaddr_t *descpa);
+-
+-/* Prototypes for 64-bit routines */
+-static bool dma64_alloc(dma_info_t *di, uint direction);
+-static bool dma64_txreset(dma_info_t *di);
+-static bool dma64_rxreset(dma_info_t *di);
+-static bool dma64_txsuspendedidle(dma_info_t *di);
+-static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit);
+-static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
+-static void *dma64_getpos(dma_info_t *di, bool direction);
+-static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
+-static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
+-static void dma64_txrotate(dma_info_t *di);
+-
+-static bool dma64_rxidle(dma_info_t *di);
+-static void dma64_txinit(dma_info_t *di);
+-static bool dma64_txenabled(dma_info_t *di);
+-static void dma64_txsuspend(dma_info_t *di);
+-static void dma64_txresume(dma_info_t *di);
+-static bool dma64_txsuspended(dma_info_t *di);
+-static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
+-static bool dma64_txstopped(dma_info_t *di);
+-static bool dma64_rxstopped(dma_info_t *di);
+-static bool dma64_rxenabled(dma_info_t *di);
+-static bool _dma64_addrext(dma64regs_t *dma64regs);
+-
+-static inline u32 parity32(u32 data);
+-
+-const di_fcn_t dma64proc = {
+-	(di_detach_t) _dma_detach,
+-	(di_txinit_t) dma64_txinit,
+-	(di_txreset_t) dma64_txreset,
+-	(di_txenabled_t) dma64_txenabled,
+-	(di_txsuspend_t) dma64_txsuspend,
+-	(di_txresume_t) dma64_txresume,
+-	(di_txsuspended_t) dma64_txsuspended,
+-	(di_txsuspendedidle_t) dma64_txsuspendedidle,
+-	(di_txfast_t) dma64_txfast,
+-	(di_txunframed_t) dma64_txunframed,
+-	(di_getpos_t) dma64_getpos,
+-	(di_txstopped_t) dma64_txstopped,
+-	(di_txreclaim_t) dma64_txreclaim,
+-	(di_getnexttxp_t) dma64_getnexttxp,
+-	(di_peeknexttxp_t) _dma_peeknexttxp,
+-	(di_txblock_t) _dma_txblock,
+-	(di_txunblock_t) _dma_txunblock,
+-	(di_txactive_t) _dma_txactive,
+-	(di_txrotate_t) dma64_txrotate,
+-
+-	(di_rxinit_t) _dma_rxinit,
+-	(di_rxreset_t) dma64_rxreset,
+-	(di_rxidle_t) dma64_rxidle,
+-	(di_rxstopped_t) dma64_rxstopped,
+-	(di_rxenable_t) _dma_rxenable,
+-	(di_rxenabled_t) dma64_rxenabled,
+-	(di_rx_t) _dma_rx,
+-	(di_rxfill_t) _dma_rxfill,
+-	(di_rxreclaim_t) _dma_rxreclaim,
+-	(di_getnextrxp_t) _dma_getnextrxp,
+-	(di_peeknextrxp_t) _dma_peeknextrxp,
+-	(di_rxparam_get_t) _dma_rx_param_get,
+-
+-	(di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+-	(di_getvar_t) _dma_getvar,
+-	(di_counterreset_t) _dma_counterreset,
+-	(di_ctrlflags_t) _dma_ctrlflags,
+-	NULL,
+-	NULL,
+-	NULL,
+-	(di_rxactive_t) _dma_rxactive,
+-	(di_txpending_t) _dma_txpending,
+-	(di_txcommitted_t) _dma_txcommitted,
+-	39
+-};
+-
+-struct hnddma_pub *dma_attach(char *name, si_t *sih,
+-		     void *dmaregstx, void *dmaregsrx, uint ntxd,
+-		     uint nrxd, uint rxbufsize, int rxextheadroom,
+-		     uint nrxpost, uint rxoffset, uint *msg_level)
+-{
+-	dma_info_t *di;
+-	uint size;
+-
+-	/* allocate private info structure */
+-	di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
+-	if (di == NULL) {
+-#ifdef BCMDBG
+-		printk(KERN_ERR "dma_attach: out of memory\n");
+-#endif
+-		return NULL;
+-	}
+-
+-	di->msg_level = msg_level ? msg_level : &dma_msg_level;
+-
+-
+-	di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
+-
+-	/* init dma reg pointer */
+-	di->d64txregs = (dma64regs_t *) dmaregstx;
+-	di->d64rxregs = (dma64regs_t *) dmaregsrx;
+-	di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
+-
+-	/* Default flags (which can be changed by the driver calling dma_ctrlflags
+-	 * before enable): For backwards compatibility both Rx Overflow Continue
+-	 * and Parity are DISABLED.
+-	 * supports it.
+-	 */
+-	di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
+-				    0);
+-
+-	DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
+-		   "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
+-		   "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
+-		   di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize,
+-		   rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+-
+-	/* make a private copy of our callers name */
+-	strncpy(di->name, name, MAXNAMEL);
+-	di->name[MAXNAMEL - 1] = '\0';
+-
+-	di->pbus = ((struct si_info *)sih)->pbus;
+-
+-	/* save tunables */
+-	di->ntxd = (u16) ntxd;
+-	di->nrxd = (u16) nrxd;
+-
+-	/* the actual dma size doesn't include the extra headroom */
+-	di->rxextrahdrroom =
+-	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
+-	if (rxbufsize > BCMEXTRAHDROOM)
+-		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
+-	else
+-		di->rxbufsize = (u16) rxbufsize;
+-
+-	di->nrxpost = (u16) nrxpost;
+-	di->rxoffset = (u8) rxoffset;
+-
+-	/*
+-	 * figure out the DMA physical address offset for dd and data
+-	 *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+-	 *     Other bus: use zero
+-	 *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+-	 */
+-	di->ddoffsetlow = 0;
+-	di->dataoffsetlow = 0;
+-	/* for pci bus, add offset */
+-	if (sih->bustype == PCI_BUS) {
+-		/* pcie with DMA64 */
+-		di->ddoffsetlow = 0;
+-		di->ddoffsethigh = SI_PCIE_DMA_H32;
+-		di->dataoffsetlow = di->ddoffsetlow;
+-		di->dataoffsethigh = di->ddoffsethigh;
+-	}
+-#if defined(__mips__) && defined(IL_BIGENDIAN)
+-	di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
+-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+-	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
+-	if ((ai_coreid(sih) == SDIOD_CORE_ID)
+-	    && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
+-		di->addrext = 0;
+-	else if ((ai_coreid(sih) == I2S_CORE_ID) &&
+-		 ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
+-		di->addrext = 0;
+-	else
+-		di->addrext = _dma_isaddrext(di);
+-
+-	/* does the descriptors need to be aligned and if yes, on 4K/8K or not */
+-	di->aligndesc_4k = _dma_descriptor_align(di);
+-	if (di->aligndesc_4k) {
+-		di->dmadesc_align = D64RINGALIGN_BITS;
+-		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
+-			/* for smaller dd table, HW relax alignment reqmnt */
+-			di->dmadesc_align = D64RINGALIGN_BITS - 1;
+-		}
+-	} else
+-		di->dmadesc_align = 4;	/* 16 byte alignment */
+-
+-	DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
+-		  di->aligndesc_4k, di->dmadesc_align));
+-
+-	/* allocate tx packet pointer vector */
+-	if (ntxd) {
+-		size = ntxd * sizeof(void *);
+-		di->txp = kzalloc(size, GFP_ATOMIC);
+-		if (di->txp == NULL) {
+-			DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
+-			goto fail;
+-		}
+-	}
+-
+-	/* allocate rx packet pointer vector */
+-	if (nrxd) {
+-		size = nrxd * sizeof(void *);
+-		di->rxp = kzalloc(size, GFP_ATOMIC);
+-		if (di->rxp == NULL) {
+-			DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
+-			goto fail;
+-		}
+-	}
+-
+-	/* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+-	if (ntxd) {
+-		if (!_dma_alloc(di, DMA_TX))
+-			goto fail;
+-	}
+-
+-	/* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+-	if (nrxd) {
+-		if (!_dma_alloc(di, DMA_RX))
+-			goto fail;
+-	}
+-
+-	if ((di->ddoffsetlow != 0) && !di->addrext) {
+-		if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
+-			DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
+-			goto fail;
+-		}
+-		if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
+-			DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
+-			goto fail;
+-		}
+-	}
+-
+-	DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+-
+-	/* allocate DMA mapping vectors */
+-	if (DMASGLIST_ENAB) {
+-		if (ntxd) {
+-			size = ntxd * sizeof(hnddma_seg_map_t);
+-			di->txp_dmah = kzalloc(size, GFP_ATOMIC);
+-			if (di->txp_dmah == NULL)
+-				goto fail;
+-		}
+-
+-		if (nrxd) {
+-			size = nrxd * sizeof(hnddma_seg_map_t);
+-			di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
+-			if (di->rxp_dmah == NULL)
+-				goto fail;
+-		}
+-	}
+-
+-	return (struct hnddma_pub *) di;
+-
+- fail:
+-	_dma_detach(di);
+-	return NULL;
+-}
+-
+-/* Check for odd number of 1's */
+-static inline u32 parity32(u32 data)
+-{
+-	data ^= data >> 16;
+-	data ^= data >> 8;
+-	data ^= data >> 4;
+-	data ^= data >> 2;
+-	data ^= data >> 1;
+-
+-	return data & 1;
+-}
+-
+-#define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
+-
+-static inline void
+-dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
+-	     u32 *flags, u32 bufcount)
+-{
+-	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+-
+-	/* PCI bus with big(>1G) physical address, use address extension */
+-#if defined(__mips__) && defined(IL_BIGENDIAN)
+-	if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
+-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-#else
+-	if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+-
+-		W_SM(&ddring[outidx].addrlow,
+-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+-		W_SM(&ddring[outidx].addrhigh,
+-		     BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
+-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+-	} else {
+-		/* address extension for 32-bit PCI */
+-		u32 ae;
+-
+-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+-
+-		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+-		W_SM(&ddring[outidx].addrlow,
+-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+-		W_SM(&ddring[outidx].addrhigh,
+-		     BUS_SWAP32(0 + di->dataoffsethigh));
+-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+-	}
+-	if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
+-		if (DMA64_DD_PARITY(&ddring[outidx])) {
+-			W_SM(&ddring[outidx].ctrl2,
+-			     BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
+-		}
+-	}
+-}
+-
+-static bool _dma_alloc(dma_info_t *di, uint direction)
+-{
+-	return dma64_alloc(di, direction);
+-}
+-
+-void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
+-			       uint *alloced, unsigned long *pap)
+-{
+-	if (align_bits) {
+-		u16 align = (1 << align_bits);
+-		if (!IS_ALIGNED(PAGE_SIZE, align))
+-			size += align;
+-		*alloced = size;
+-	}
+-	return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
+-}
+-
+-/* !! may be called with core in reset */
+-static void _dma_detach(dma_info_t *di)
+-{
+-
+-	DMA_TRACE(("%s: dma_detach\n", di->name));
+-
+-	/* free dma descriptor rings */
+-	if (di->txd64)
+-		pci_free_consistent(di->pbus, di->txdalloc,
+-				    ((s8 *)di->txd64 - di->txdalign),
+-				    (di->txdpaorig));
+-	if (di->rxd64)
+-		pci_free_consistent(di->pbus, di->rxdalloc,
+-				    ((s8 *)di->rxd64 - di->rxdalign),
+-				    (di->rxdpaorig));
+-
+-	/* free packet pointer vectors */
+-	kfree(di->txp);
+-	kfree(di->rxp);
+-
+-	/* free tx packet DMA handles */
+-	kfree(di->txp_dmah);
+-
+-	/* free rx packet DMA handles */
+-	kfree(di->rxp_dmah);
+-
+-	/* free our private info structure */
+-	kfree(di);
+-
+-}
+-
+-static bool _dma_descriptor_align(dma_info_t *di)
+-{
+-	u32 addrl;
+-
+-	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
+-	if (di->d64txregs != NULL) {
+-		W_REG(&di->d64txregs->addrlow, 0xff0);
+-		addrl = R_REG(&di->d64txregs->addrlow);
+-		if (addrl != 0)
+-			return false;
+-	} else if (di->d64rxregs != NULL) {
+-		W_REG(&di->d64rxregs->addrlow, 0xff0);
+-		addrl = R_REG(&di->d64rxregs->addrlow);
+-		if (addrl != 0)
+-			return false;
+-	}
+-	return true;
+-}
+-
+-/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
+-static bool _dma_isaddrext(dma_info_t *di)
+-{
+-	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
+-
+-	/* not all tx or rx channel are available */
+-	if (di->d64txregs != NULL) {
+-		if (!_dma64_addrext(di->d64txregs)) {
+-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
+-				   "AE set\n", di->name));
+-		}
+-		return true;
+-	} else if (di->d64rxregs != NULL) {
+-		if (!_dma64_addrext(di->d64rxregs)) {
+-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
+-				   "AE set\n", di->name));
+-		}
+-		return true;
+-	}
+-	return false;
+-}
+-
+-/* initialize descriptor table base address */
+-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
+-{
+-	if (!di->aligndesc_4k) {
+-		if (direction == DMA_TX)
+-			di->xmtptrbase = PHYSADDRLO(pa);
+-		else
+-			di->rcvptrbase = PHYSADDRLO(pa);
+-	}
+-
+-	if ((di->ddoffsetlow == 0)
+-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+-		if (direction == DMA_TX) {
+-			W_REG(&di->d64txregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64txregs->addrhigh,
+-			      (PHYSADDRHI(pa) + di->ddoffsethigh));
+-		} else {
+-			W_REG(&di->d64rxregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64rxregs->addrhigh,
+-				(PHYSADDRHI(pa) + di->ddoffsethigh));
+-		}
+-	} else {
+-		/* DMA64 32bits address extension */
+-		u32 ae;
+-
+-		/* shift the high bit(s) from pa to ae */
+-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
+-		    PCI32ADDR_HIGH_SHIFT;
+-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+-
+-		if (direction == DMA_TX) {
+-			W_REG(&di->d64txregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64txregs->addrhigh,
+-			      di->ddoffsethigh);
+-			SET_REG(&di->d64txregs->control,
+-				D64_XC_AE, (ae << D64_XC_AE_SHIFT));
+-		} else {
+-			W_REG(&di->d64rxregs->addrlow,
+-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+-			W_REG(&di->d64rxregs->addrhigh,
+-			      di->ddoffsethigh);
+-			SET_REG(&di->d64rxregs->control,
+-				D64_RC_AE, (ae << D64_RC_AE_SHIFT));
+-		}
+-	}
+-}
+-
+-static void _dma_fifoloopbackenable(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
+-
+-	OR_REG(&di->d64txregs->control, D64_XC_LE);
+-}
+-
+-static void _dma_rxinit(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_rxinit\n", di->name));
+-
+-	if (di->nrxd == 0)
+-		return;
+-
+-	di->rxin = di->rxout = 0;
+-
+-	/* clear rx descriptor ring */
+-	memset((void *)di->rxd64, '\0',
+-		(di->nrxd * sizeof(dma64dd_t)));
+-
+-	/* DMA engine with out alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (!di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+-
+-	_dma_rxenable(di);
+-
+-	if (di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+-}
+-
+-static void _dma_rxenable(dma_info_t *di)
+-{
+-	uint dmactrlflags = di->hnddma.dmactrlflags;
+-	u32 control;
+-
+-	DMA_TRACE(("%s: dma_rxenable\n", di->name));
+-
+-	control =
+-	    (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
+-	    D64_RC_RE;
+-
+-	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
+-		control |= D64_RC_PD;
+-
+-	if (dmactrlflags & DMA_CTRL_ROC)
+-		control |= D64_RC_OC;
+-
+-	W_REG(&di->d64rxregs->control,
+-		((di->rxoffset << D64_RC_RO_SHIFT) | control));
+-}
+-
+-static void
+-_dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
+-{
+-	/* the normal values fit into 16 bits */
+-	*rxoffset = (u16) di->rxoffset;
+-	*rxbufsize = (u16) di->rxbufsize;
+-}
+-
+-/* !! rx entry routine
+- * returns a pointer to the next frame received, or NULL if there are no more
+- *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
+- *      with pkts chain
+- *   otherwise, it's treated as giant pkt and will be tossed.
+- *   The DMA scattering starts with normal DMA header, followed by first buffer data.
+- *   After it reaches the max size of buffer, the data continues in next DMA descriptor
+- *   buffer WITHOUT DMA header
+- */
+-static void *_dma_rx(dma_info_t *di)
+-{
+-	struct sk_buff *p, *head, *tail;
+-	uint len;
+-	uint pkt_len;
+-	int resid = 0;
+-
+- next_frame:
+-	head = _dma_getnextrxp(di, false);
+-	if (head == NULL)
+-		return NULL;
+-
+-	len = le16_to_cpu(*(u16 *) (head->data));
+-	DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
+-	dma_spin_for_len(len, head);
+-
+-	/* set actual length */
+-	pkt_len = min((di->rxoffset + len), di->rxbufsize);
+-	__skb_trim(head, pkt_len);
+-	resid = len - (di->rxbufsize - di->rxoffset);
+-
+-	/* check for single or multi-buffer rx */
+-	if (resid > 0) {
+-		tail = head;
+-		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
+-			tail->next = p;
+-			pkt_len = min(resid, (int)di->rxbufsize);
+-			__skb_trim(p, pkt_len);
+-
+-			tail = p;
+-			resid -= di->rxbufsize;
+-		}
+-
+-#ifdef BCMDBG
+-		if (resid > 0) {
+-			uint cur;
+-			cur =
+-			    B2I(((R_REG(&di->d64rxregs->status0) &
+-				  D64_RS0_CD_MASK) -
+-				 di->rcvptrbase) & D64_RS0_CD_MASK,
+-				dma64dd_t);
+-			DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
+-				   di->rxin, di->rxout, cur));
+-		}
+-#endif				/* BCMDBG */
+-
+-		if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
+-			DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
+-				   di->name, len));
+-			bcm_pkt_buf_free_skb(head);
+-			di->hnddma.rxgiants++;
+-			goto next_frame;
+-		}
+-	}
+-
+-	return head;
+-}
+-
+-/* post receive buffers
+- *  return false is refill failed completely and ring is empty
+- *  this will stall the rx dma and user might want to call rxfill again asap
+- *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
+- */
+-static bool _dma_rxfill(dma_info_t *di)
+-{
+-	struct sk_buff *p;
+-	u16 rxin, rxout;
+-	u32 flags = 0;
+-	uint n;
+-	uint i;
+-	dmaaddr_t pa;
+-	uint extra_offset = 0;
+-	bool ring_empty;
+-
+-	ring_empty = false;
+-
+-	/*
+-	 * Determine how many receive buffers we're lacking
+-	 * from the full complement, allocate, initialize,
+-	 * and post them, then update the chip rx lastdscr.
+-	 */
+-
+-	rxin = di->rxin;
+-	rxout = di->rxout;
+-
+-	n = di->nrxpost - NRXDACTIVE(rxin, rxout);
+-
+-	DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
+-
+-	if (di->rxbufsize > BCMEXTRAHDROOM)
+-		extra_offset = di->rxextrahdrroom;
+-
+-	for (i = 0; i < n; i++) {
+-		/* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+-		   size to be allocated
+-		 */
+-
+-		p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset);
+-
+-		if (p == NULL) {
+-			DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
+-				   di->name));
+-			if (i == 0 && dma64_rxidle(di)) {
+-				DMA_ERROR(("%s: rxfill64: ring is empty !\n",
+-					   di->name));
+-				ring_empty = true;
+-			}
+-			di->hnddma.rxnobuf++;
+-			break;
+-		}
+-		/* reserve an extra headroom, if applicable */
+-		if (extra_offset)
+-			skb_pull(p, extra_offset);
+-
+-		/* Do a cached write instead of uncached write since DMA_MAP
+-		 * will flush the cache.
+-		 */
+-		*(u32 *) (p->data) = 0;
+-
+-		if (DMASGLIST_ENAB)
+-			memset(&di->rxp_dmah[rxout], 0,
+-				sizeof(hnddma_seg_map_t));
+-
+-		pa = pci_map_single(di->pbus, p->data,
+-			di->rxbufsize, PCI_DMA_FROMDEVICE);
+-
+-		/* save the free packet pointer */
+-		di->rxp[rxout] = p;
+-
+-		/* reset flags for each descriptor */
+-		flags = 0;
+-		if (rxout == (di->nrxd - 1))
+-			flags = D64_CTRL1_EOT;
+-
+-		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
+-			     di->rxbufsize);
+-		rxout = NEXTRXD(rxout);
+-	}
+-
+-	di->rxout = rxout;
+-
+-	/* update the chip lastdscr pointer */
+-	W_REG(&di->d64rxregs->ptr,
+-	      di->rcvptrbase + I2B(rxout, dma64dd_t));
+-
+-	return ring_empty;
+-}
+-
+-/* like getnexttxp but no reclaim */
+-static void *_dma_peeknexttxp(dma_info_t *di)
+-{
+-	uint end, i;
+-
+-	if (di->ntxd == 0)
+-		return NULL;
+-
+-	end =
+-	    B2I(((R_REG(&di->d64txregs->status0) &
+-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	for (i = di->txin; i != end; i = NEXTTXD(i))
+-		if (di->txp[i])
+-			return di->txp[i];
+-
+-	return NULL;
+-}
+-
+-/* like getnextrxp but not take off the ring */
+-static void *_dma_peeknextrxp(dma_info_t *di)
+-{
+-	uint end, i;
+-
+-	if (di->nrxd == 0)
+-		return NULL;
+-
+-	end =
+-	    B2I(((R_REG(&di->d64rxregs->status0) &
+-		  D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	for (i = di->rxin; i != end; i = NEXTRXD(i))
+-		if (di->rxp[i])
+-			return di->rxp[i];
+-
+-	return NULL;
+-}
+-
+-static void _dma_rxreclaim(dma_info_t *di)
+-{
+-	void *p;
+-
+-	DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+-
+-	while ((p = _dma_getnextrxp(di, true)))
+-		bcm_pkt_buf_free_skb(p);
+-}
+-
+-static void *_dma_getnextrxp(dma_info_t *di, bool forceall)
+-{
+-	if (di->nrxd == 0)
+-		return NULL;
+-
+-	return dma64_getnextrxp(di, forceall);
+-}
+-
+-static void _dma_txblock(dma_info_t *di)
+-{
+-	di->hnddma.txavail = 0;
+-}
+-
+-static void _dma_txunblock(dma_info_t *di)
+-{
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-}
+-
+-static uint _dma_txactive(dma_info_t *di)
+-{
+-	return NTXDACTIVE(di->txin, di->txout);
+-}
+-
+-static uint _dma_txpending(dma_info_t *di)
+-{
+-	uint curr;
+-
+-	curr =
+-	    B2I(((R_REG(&di->d64txregs->status0) &
+-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+-		  dma64dd_t);
+-
+-	return NTXDACTIVE(curr, di->txout);
+-}
+-
+-static uint _dma_txcommitted(dma_info_t *di)
+-{
+-	uint ptr;
+-	uint txin = di->txin;
+-
+-	if (txin == di->txout)
+-		return 0;
+-
+-	ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t);
+-
+-	return NTXDACTIVE(di->txin, ptr);
+-}
+-
+-static uint _dma_rxactive(dma_info_t *di)
+-{
+-	return NRXDACTIVE(di->rxin, di->rxout);
+-}
+-
+-static void _dma_counterreset(dma_info_t *di)
+-{
+-	/* reset all software counter */
+-	di->hnddma.rxgiants = 0;
+-	di->hnddma.rxnobuf = 0;
+-	di->hnddma.txnobuf = 0;
+-}
+-
+-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
+-{
+-	uint dmactrlflags = di->hnddma.dmactrlflags;
+-
+-	if (di == NULL) {
+-		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+-		return 0;
+-	}
+-
+-	dmactrlflags &= ~mask;
+-	dmactrlflags |= flags;
+-
+-	/* If trying to enable parity, check if parity is actually supported */
+-	if (dmactrlflags & DMA_CTRL_PEN) {
+-		u32 control;
+-
+-		control = R_REG(&di->d64txregs->control);
+-		W_REG(&di->d64txregs->control,
+-		      control | D64_XC_PD);
+-		if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
+-			/* We *can* disable it so it is supported,
+-			 * restore control register
+-			 */
+-			W_REG(&di->d64txregs->control,
+-			control);
+-		} else {
+-			/* Not supported, don't allow it to be enabled */
+-			dmactrlflags &= ~DMA_CTRL_PEN;
+-		}
+-	}
+-
+-	di->hnddma.dmactrlflags = dmactrlflags;
+-
+-	return dmactrlflags;
+-}
+-
+-/* get the address of the var in order to change later */
+-static unsigned long _dma_getvar(dma_info_t *di, const char *name)
+-{
+-	if (!strcmp(name, "&txavail"))
+-		return (unsigned long)&(di->hnddma.txavail);
+-	return 0;
+-}
+-
+-static
+-u8 dma_align_sizetobits(uint size)
+-{
+-	u8 bitpos = 0;
+-	while (size >>= 1) {
+-		bitpos++;
+-	}
+-	return bitpos;
+-}
+-
+-/* This function ensures that the DMA descriptor ring will not get allocated
+- * across Page boundary. If the allocation is done across the page boundary
+- * at the first time, then it is freed and the allocation is done at
+- * descriptor ring size aligned location. This will ensure that the ring will
+- * not cross page boundary
+- */
+-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+-			   u16 *alignbits, uint *alloced,
+-			   dmaaddr_t *descpa)
+-{
+-	void *va;
+-	u32 desc_strtaddr;
+-	u32 alignbytes = 1 << *alignbits;
+-
+-	va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
+-
+-	if (NULL == va)
+-		return NULL;
+-
+-	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
+-	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
+-							& boundary)) {
+-		*alignbits = dma_align_sizetobits(size);
+-		pci_free_consistent(di->pbus, size, va, *descpa);
+-		va = dma_alloc_consistent(di->pbus, size, *alignbits,
+-			alloced, descpa);
+-	}
+-	return va;
+-}
+-
+-/* 64-bit DMA functions */
+-
+-static void dma64_txinit(dma_info_t *di)
+-{
+-	u32 control = D64_XC_XE;
+-
+-	DMA_TRACE(("%s: dma_txinit\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	di->txin = di->txout = 0;
+-	di->hnddma.txavail = di->ntxd - 1;
+-
+-	/* clear tx descriptor ring */
+-	memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t)));
+-
+-	/* DMA engine with out alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (!di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+-
+-	if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
+-		control |= D64_XC_PD;
+-	OR_REG(&di->d64txregs->control, control);
+-
+-	/* DMA engine with alignment requirement requires table to be inited
+-	 * before enabling the engine
+-	 */
+-	if (di->aligndesc_4k)
+-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+-}
+-
+-static bool dma64_txenabled(dma_info_t *di)
+-{
+-	u32 xc;
+-
+-	/* If the chip is dead, it is not enabled :-) */
+-	xc = R_REG(&di->d64txregs->control);
+-	return (xc != 0xffffffff) && (xc & D64_XC_XE);
+-}
+-
+-static void dma64_txsuspend(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	OR_REG(&di->d64txregs->control, D64_XC_SE);
+-}
+-
+-static void dma64_txresume(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_txresume\n", di->name));
+-
+-	if (di->ntxd == 0)
+-		return;
+-
+-	AND_REG(&di->d64txregs->control, ~D64_XC_SE);
+-}
+-
+-static bool dma64_txsuspended(dma_info_t *di)
+-{
+-	return (di->ntxd == 0) ||
+-	    ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
+-	     D64_XC_SE);
+-}
+-
+-static void dma64_txreclaim(dma_info_t *di, txd_range_t range)
+-{
+-	void *p;
+-
+-	DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
+-		   (range == HNDDMA_RANGE_ALL) ? "all" :
+-		   ((range ==
+-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+-		    "transferred")));
+-
+-	if (di->txin == di->txout)
+-		return;
+-
+-	while ((p = dma64_getnexttxp(di, range))) {
+-		/* For unframed data, we don't have any packets to free */
+-		if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
+-			bcm_pkt_buf_free_skb(p);
+-	}
+-}
+-
+-static bool dma64_txstopped(dma_info_t *di)
+-{
+-	return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+-		D64_XS0_XS_STOPPED);
+-}
+-
+-static bool dma64_rxstopped(dma_info_t *di)
+-{
+-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+-		D64_RS0_RS_STOPPED);
+-}
+-
+-static bool dma64_alloc(dma_info_t *di, uint direction)
+-{
+-	u16 size;
+-	uint ddlen;
+-	void *va;
+-	uint alloced = 0;
+-	u16 align;
+-	u16 align_bits;
+-
+-	ddlen = sizeof(dma64dd_t);
+-
+-	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+-	align_bits = di->dmadesc_align;
+-	align = (1 << align_bits);
+-
+-	if (direction == DMA_TX) {
+-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+-			&alloced, &di->txdpaorig);
+-		if (va == NULL) {
+-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
+-			return false;
+-		}
+-		align = (1 << align_bits);
+-		di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+-		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
+-		PHYSADDRLOSET(di->txdpa,
+-			      PHYSADDRLO(di->txdpaorig) + di->txdalign);
+-		PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
+-		di->txdalloc = alloced;
+-	} else {
+-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+-			&alloced, &di->rxdpaorig);
+-		if (va == NULL) {
+-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
+-			return false;
+-		}
+-		align = (1 << align_bits);
+-		di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+-		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
+-		PHYSADDRLOSET(di->rxdpa,
+-			      PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
+-		PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
+-		di->rxdalloc = alloced;
+-	}
+-
+-	return true;
+-}
+-
+-static bool dma64_txreset(dma_info_t *di)
+-{
+-	u32 status;
+-
+-	if (di->ntxd == 0)
+-		return true;
+-
+-	/* suspend tx DMA first */
+-	W_REG(&di->d64txregs->control, D64_XC_SE);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+-		  != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+-		 && (status != D64_XS0_XS_STOPPED), 10000);
+-
+-	W_REG(&di->d64txregs->control, 0);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+-		  != D64_XS0_XS_DISABLED), 10000);
+-
+-	/* wait for the last transaction to complete */
+-	udelay(300);
+-
+-	return status == D64_XS0_XS_DISABLED;
+-}
+-
+-static bool dma64_rxidle(dma_info_t *di)
+-{
+-	DMA_TRACE(("%s: dma_rxidle\n", di->name));
+-
+-	if (di->nrxd == 0)
+-		return true;
+-
+-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+-		(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
+-}
+-
+-static bool dma64_rxreset(dma_info_t *di)
+-{
+-	u32 status;
+-
+-	if (di->nrxd == 0)
+-		return true;
+-
+-	W_REG(&di->d64rxregs->control, 0);
+-	SPINWAIT(((status =
+-		   (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
+-		  != D64_RS0_RS_DISABLED), 10000);
+-
+-	return status == D64_RS0_RS_DISABLED;
+-}
+-
+-static bool dma64_rxenabled(dma_info_t *di)
+-{
+-	u32 rc;
+-
+-	rc = R_REG(&di->d64rxregs->control);
+-	return (rc != 0xffffffff) && (rc & D64_RC_RE);
+-}
+-
+-static bool dma64_txsuspendedidle(dma_info_t *di)
+-{
+-
+-	if (di->ntxd == 0)
+-		return true;
+-
+-	if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
+-		return 0;
+-
+-	if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+-	    D64_XS0_XS_IDLE)
+-		return 1;
+-
+-	return 0;
+-}
+-
+-/* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
+- * We return a pointer to the beginning of the DATA buffer of the current descriptor.
+- * If DMA is idle, we return NULL.
+- */
+-static void *dma64_getpos(dma_info_t *di, bool direction)
+-{
+-	void *va;
+-	bool idle;
+-	u32 cd_offset;
+-
+-	if (direction == DMA_TX) {
+-		cd_offset =
+-		    R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
+-		idle = !NTXDACTIVE(di->txin, di->txout);
+-		va = di->txp[B2I(cd_offset, dma64dd_t)];
+-	} else {
+-		cd_offset =
+-		    R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
+-		idle = !NRXDACTIVE(di->rxin, di->rxout);
+-		va = di->rxp[B2I(cd_offset, dma64dd_t)];
+-	}
+-
+-	/* If DMA is IDLE, return NULL */
+-	if (idle) {
+-		DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
+-		va = NULL;
+-	}
+-
+-	return va;
+-}
+-
+-/* TX of unframed data
+- *
+- * Adds a DMA ring descriptor for the data pointed to by "buf".
+- * This is for DMA of a buffer of data and is unlike other hnddma TX functions
+- * that take a pointer to a "packet"
+- * Each call to this is results in a single descriptor being added for "len" bytes of
+- * data starting at "buf", it doesn't handle chained buffers.
+- */
+-static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
+-{
+-	u16 txout;
+-	u32 flags = 0;
+-	dmaaddr_t pa;		/* phys addr */
+-
+-	txout = di->txout;
+-
+-	/* return nonzero if out of tx descriptors */
+-	if (NEXTTXD(txout) == di->txin)
+-		goto outoftxd;
+-
+-	if (len == 0)
+-		return 0;
+-
+-	pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
+-
+-	flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
+-
+-	if (txout == (di->ntxd - 1))
+-		flags |= D64_CTRL1_EOT;
+-
+-	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+-
+-	/* save the buffer pointer - used by dma_getpos */
+-	di->txp[txout] = buf;
+-
+-	txout = NEXTTXD(txout);
+-	/* bump the tx descriptor index */
+-	di->txout = txout;
+-
+-	/* kick the chip */
+-	if (commit) {
+-		W_REG(&di->d64txregs->ptr,
+-		      di->xmtptrbase + I2B(txout, dma64dd_t));
+-	}
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return 0;
+-
+- outoftxd:
+-	DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
+-	di->hnddma.txavail = 0;
+-	di->hnddma.txnobuf++;
+-	return -1;
+-}
+-
+-/* !! tx entry routine
+- * WARNING: call must check the return value for error.
+- *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
+- */
+-static int dma64_txfast(dma_info_t *di, struct sk_buff *p0,
+-				    bool commit)
+-{
+-	struct sk_buff *p, *next;
+-	unsigned char *data;
+-	uint len;
+-	u16 txout;
+-	u32 flags = 0;
+-	dmaaddr_t pa;
+-
+-	DMA_TRACE(("%s: dma_txfast\n", di->name));
+-
+-	txout = di->txout;
+-
+-	/*
+-	 * Walk the chain of packet buffers
+-	 * allocating and initializing transmit descriptor entries.
+-	 */
+-	for (p = p0; p; p = next) {
+-		uint nsegs, j;
+-		hnddma_seg_map_t *map;
+-
+-		data = p->data;
+-		len = p->len;
+-		next = p->next;
+-
+-		/* return nonzero if out of tx descriptors */
+-		if (NEXTTXD(txout) == di->txin)
+-			goto outoftxd;
+-
+-		if (len == 0)
+-			continue;
+-
+-		/* get physical address of buffer start */
+-		if (DMASGLIST_ENAB)
+-			memset(&di->txp_dmah[txout], 0,
+-				sizeof(hnddma_seg_map_t));
+-
+-		pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
+-
+-		if (DMASGLIST_ENAB) {
+-			map = &di->txp_dmah[txout];
+-
+-			/* See if all the segments can be accounted for */
+-			if (map->nsegs >
+-			    (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
+-				    1))
+-				goto outoftxd;
+-
+-			nsegs = map->nsegs;
+-		} else
+-			nsegs = 1;
+-
+-		for (j = 1; j <= nsegs; j++) {
+-			flags = 0;
+-			if (p == p0 && j == 1)
+-				flags |= D64_CTRL1_SOF;
+-
+-			/* With a DMA segment list, Descriptor table is filled
+-			 * using the segment list instead of looping over
+-			 * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
+-			 * end of segment list is reached.
+-			 */
+-			if ((!DMASGLIST_ENAB && next == NULL) ||
+-			    (DMASGLIST_ENAB && j == nsegs))
+-				flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+-			if (txout == (di->ntxd - 1))
+-				flags |= D64_CTRL1_EOT;
+-
+-			if (DMASGLIST_ENAB) {
+-				len = map->segs[j - 1].length;
+-				pa = map->segs[j - 1].addr;
+-			}
+-			dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+-
+-			txout = NEXTTXD(txout);
+-		}
+-
+-		/* See above. No need to loop over individual buffers */
+-		if (DMASGLIST_ENAB)
+-			break;
+-	}
+-
+-	/* if last txd eof not set, fix it */
+-	if (!(flags & D64_CTRL1_EOF))
+-		W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
+-		     BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+-
+-	/* save the packet */
+-	di->txp[PREVTXD(txout)] = p0;
+-
+-	/* bump the tx descriptor index */
+-	di->txout = txout;
+-
+-	/* kick the chip */
+-	if (commit)
+-		W_REG(&di->d64txregs->ptr,
+-		      di->xmtptrbase + I2B(txout, dma64dd_t));
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return 0;
+-
+- outoftxd:
+-	DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
+-	bcm_pkt_buf_free_skb(p0);
+-	di->hnddma.txavail = 0;
+-	di->hnddma.txnobuf++;
+-	return -1;
+-}
+-
+-/*
+- * Reclaim next completed txd (txds if using chained buffers) in the range
+- * specified and return associated packet.
+- * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
+- * transmitted as noted by the hardware "CurrDescr" pointer.
+- * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
+- * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
+- * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
+- * return associated packet regardless of the value of hardware pointers.
+- */
+-static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range)
+-{
+-	u16 start, end, i;
+-	u16 active_desc;
+-	void *txp;
+-
+-	DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
+-		   (range == HNDDMA_RANGE_ALL) ? "all" :
+-		   ((range ==
+-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+-		    "transferred")));
+-
+-	if (di->ntxd == 0)
+-		return NULL;
+-
+-	txp = NULL;
+-
+-	start = di->txin;
+-	if (range == HNDDMA_RANGE_ALL)
+-		end = di->txout;
+-	else {
+-		dma64regs_t *dregs = di->d64txregs;
+-
+-		end =
+-		    (u16) (B2I
+-			      (((R_REG(&dregs->status0) &
+-				 D64_XS0_CD_MASK) -
+-				di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
+-
+-		if (range == HNDDMA_RANGE_TRANSFERED) {
+-			active_desc =
+-			    (u16) (R_REG(&dregs->status1) &
+-				      D64_XS1_AD_MASK);
+-			active_desc =
+-			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
+-			active_desc = B2I(active_desc, dma64dd_t);
+-			if (end != active_desc)
+-				end = PREVTXD(active_desc);
+-		}
+-	}
+-
+-	if ((start == 0) && (end > di->txout))
+-		goto bogus;
+-
+-	for (i = start; i != end && !txp; i = NEXTTXD(i)) {
+-		dmaaddr_t pa;
+-		hnddma_seg_map_t *map = NULL;
+-		uint size, j, nsegs;
+-
+-		PHYSADDRLOSET(pa,
+-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
+-			       di->dataoffsetlow));
+-		PHYSADDRHISET(pa,
+-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
+-			       di->dataoffsethigh));
+-
+-		if (DMASGLIST_ENAB) {
+-			map = &di->txp_dmah[i];
+-			size = map->origsize;
+-			nsegs = map->nsegs;
+-		} else {
+-			size =
+-			    (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
+-			     D64_CTRL2_BC_MASK);
+-			nsegs = 1;
+-		}
+-
+-		for (j = nsegs; j > 0; j--) {
+-			W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
+-			W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+-
+-			txp = di->txp[i];
+-			di->txp[i] = NULL;
+-			if (j > 1)
+-				i = NEXTTXD(i);
+-		}
+-
+-		pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
+-	}
+-
+-	di->txin = i;
+-
+-	/* tx flow control */
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	return txp;
+-
+- bogus:
+-	DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
+-	return NULL;
+-}
+-
+-static void *dma64_getnextrxp(dma_info_t *di, bool forceall)
+-{
+-	uint i, curr;
+-	void *rxp;
+-	dmaaddr_t pa;
+-
+-	i = di->rxin;
+-
+-	/* return if no packets posted */
+-	if (i == di->rxout)
+-		return NULL;
+-
+-	curr =
+-	    B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
+-		 di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
+-
+-	/* ignore curr if forceall */
+-	if (!forceall && (i == curr))
+-		return NULL;
+-
+-	/* get the packet pointer that corresponds to the rx descriptor */
+-	rxp = di->rxp[i];
+-	di->rxp[i] = NULL;
+-
+-	PHYSADDRLOSET(pa,
+-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
+-		       di->dataoffsetlow));
+-	PHYSADDRHISET(pa,
+-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
+-		       di->dataoffsethigh));
+-
+-	/* clear this packet from the descriptor ring */
+-	pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
+-
+-	W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
+-	W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+-
+-	di->rxin = NEXTRXD(i);
+-
+-	return rxp;
+-}
+-
+-static bool _dma64_addrext(dma64regs_t *dma64regs)
+-{
+-	u32 w;
+-	OR_REG(&dma64regs->control, D64_XC_AE);
+-	w = R_REG(&dma64regs->control);
+-	AND_REG(&dma64regs->control, ~D64_XC_AE);
+-	return (w & D64_XC_AE) == D64_XC_AE;
+-}
+-
+-/*
+- * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
+- */
+-static void dma64_txrotate(dma_info_t *di)
+-{
+-	u16 ad;
+-	uint nactive;
+-	uint rot;
+-	u16 old, new;
+-	u32 w;
+-	u16 first, last;
+-
+-	nactive = _dma_txactive(di);
+-	ad = (u16) (B2I
+-		       ((((R_REG(&di->d64txregs->status1) &
+-			   D64_XS1_AD_MASK)
+-			  - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
+-	rot = TXD(ad - di->txin);
+-
+-	/* full-ring case is a lot harder - don't worry about this */
+-	if (rot >= (di->ntxd - nactive)) {
+-		DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
+-		return;
+-	}
+-
+-	first = di->txin;
+-	last = PREVTXD(di->txout);
+-
+-	/* move entries starting at last and moving backwards to first */
+-	for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
+-		new = TXD(old + rot);
+-
+-		/*
+-		 * Move the tx dma descriptor.
+-		 * EOT is set only in the last entry in the ring.
+-		 */
+-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+-		if (new == (di->ntxd - 1))
+-			w |= D64_CTRL1_EOT;
+-		W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
+-
+-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
+-		W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
+-
+-		W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
+-		W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
+-
+-		/* zap the old tx dma descriptor address field */
+-		W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
+-		W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
+-
+-		/* move the corresponding txp[] entry */
+-		di->txp[new] = di->txp[old];
+-
+-		/* Move the map */
+-		if (DMASGLIST_ENAB) {
+-			memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
+-			       sizeof(hnddma_seg_map_t));
+-			memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t));
+-		}
+-
+-		di->txp[old] = NULL;
+-	}
+-
+-	/* update txin and txout */
+-	di->txin = ad;
+-	di->txout = TXD(di->txout + rot);
+-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+-
+-	/* kick the chip */
+-	W_REG(&di->d64txregs->ptr,
+-	      di->xmtptrbase + I2B(di->txout, dma64dd_t));
+-}
+-
+-uint dma_addrwidth(si_t *sih, void *dmaregs)
+-{
+-	/* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
+-	/* DMA engine is 64-bit capable */
+-	if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
+-		/* backplane are 64-bit capable */
+-		if (ai_backplane64(sih))
+-			/* If bus is System Backplane or PCIE then we can access 64-bits */
+-			if ((sih->bustype == SI_BUS) ||
+-			    ((sih->bustype == PCI_BUS) &&
+-			     (sih->buscoretype == PCIE_CORE_ID)))
+-				return DMADDRWIDTH_64;
+-	}
+-	/* DMA hardware not supported by this driver*/
+-	return DMADDRWIDTH_64;
+-}
+-
+-/*
+- * Mac80211 initiated actions sometimes require packets in the DMA queue to be
+- * modified. The modified portion of the packet is not under control of the DMA
+- * engine. This function calls a caller-supplied function for each packet in
+- * the caller specified dma chain.
+- */
+-void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
+-		      (void *pkt, void *arg_a), void *arg_a)
+-{
+-	dma_info_t *di = (dma_info_t *) dmah;
+-	uint i =   di->txin;
+-	uint end = di->txout;
+-	struct sk_buff *skb;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	while (i != end) {
+-		skb = (struct sk_buff *)di->txp[i];
+-		if (skb != NULL) {
+-			tx_info = (struct ieee80211_tx_info *)skb->cb;
+-			(callback_fnc)(tx_info, arg_a);
+-		}
+-		i = NEXTTXD(i);
+-	}
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c
+deleted file mode 100644
+index 18b844a..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/nicpci.c
++++ /dev/null
+@@ -1,836 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/string.h>
+-#include <linux/pci.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <hndsoc.h>
+-#include <bcmdevs.h>
+-#include <sbchipc.h>
+-#include <pci_core.h>
+-#include <pcie_core.h>
+-#include <nicpci.h>
+-#include <pcicfg.h>
+-
+-typedef struct {
+-	union {
+-		sbpcieregs_t *pcieregs;
+-		struct sbpciregs *pciregs;
+-	} regs;			/* Memory mapped register to the core */
+-
+-	si_t *sih;		/* System interconnect handle */
+-	struct pci_dev *dev;
+-	u8 pciecap_lcreg_offset;	/* PCIE capability LCreg offset in the config space */
+-	bool pcie_pr42767;
+-	u8 pcie_polarity;
+-	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
+-
+-	u8 pmecap_offset;	/* PM Capability offset in the config space */
+-	bool pmecap;		/* Capable of generating PME */
+-} pcicore_info_t;
+-
+-/* debug/trace */
+-#define	PCI_ERROR(args)
+-#define PCIE_PUB(sih) \
+-	(((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))
+-
+-/* routines to access mdio slave device registers */
+-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
+-static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
+-		       bool write, uint *val);
+-static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
+-			  uint val);
+-static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
+-			 uint *ret_val);
+-
+-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
+-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);
+-
+-static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
+-static void pcie_war_serdes(pcicore_info_t *pi);
+-static void pcie_war_noplldown(pcicore_info_t *pi);
+-static void pcie_war_polarity(pcicore_info_t *pi);
+-static void pcie_war_pci_setup(pcicore_info_t *pi);
+-
+-static bool pcicore_pmecap(pcicore_info_t *pi);
+-
+-#define PCIE_ASPM(sih)	((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))
+-
+-
+-/* delay needed between the mdio control/ mdiodata register data access */
+-#define PR28829_DELAY() udelay(10)
+-
+-/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
+- * only once
+- */
+-void *pcicore_init(si_t *sih, void *pdev, void *regs)
+-{
+-	pcicore_info_t *pi;
+-
+-	/* alloc pcicore_info_t */
+-	pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC);
+-	if (pi == NULL) {
+-		PCI_ERROR(("pci_attach: malloc failed!\n"));
+-		return NULL;
+-	}
+-
+-	pi->sih = sih;
+-	pi->dev = pdev;
+-
+-	if (sih->buscoretype == PCIE_CORE_ID) {
+-		u8 cap_ptr;
+-		pi->regs.pcieregs = (sbpcieregs_t *) regs;
+-		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
+-						      NULL, NULL);
+-		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
+-	} else
+-		pi->regs.pciregs = (struct sbpciregs *) regs;
+-
+-	return pi;
+-}
+-
+-void pcicore_deinit(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (pi == NULL)
+-		return;
+-	kfree(pi);
+-}
+-
+-/* return cap_offset if requested capability exists in the PCI config space */
+-/* Note that it's caller's responsibility to make sure it's a pci bus */
+-u8
+-pcicore_find_pci_capability(void *dev, u8 req_cap_id,
+-			    unsigned char *buf, u32 *buflen)
+-{
+-	u8 cap_id;
+-	u8 cap_ptr = 0;
+-	u32 bufsize;
+-	u8 byte_val;
+-
+-	/* check for Header type 0 */
+-	pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
+-	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
+-		goto end;
+-
+-	/* check if the capability pointer field exists */
+-	pci_read_config_byte(dev, PCI_STATUS, &byte_val);
+-	if (!(byte_val & PCI_STATUS_CAP_LIST))
+-		goto end;
+-
+-	pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
+-	/* check if the capability pointer is 0x00 */
+-	if (cap_ptr == 0x00)
+-		goto end;
+-
+-	/* loop thr'u the capability list and see if the pcie capabilty exists */
+-
+-	pci_read_config_byte(dev, cap_ptr, &cap_id);
+-
+-	while (cap_id != req_cap_id) {
+-		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
+-		if (cap_ptr == 0x00)
+-			break;
+-		pci_read_config_byte(dev, cap_ptr, &cap_id);
+-	}
+-	if (cap_id != req_cap_id) {
+-		goto end;
+-	}
+-	/* found the caller requested capability */
+-	if ((buf != NULL) && (buflen != NULL)) {
+-		u8 cap_data;
+-
+-		bufsize = *buflen;
+-		if (!bufsize)
+-			goto end;
+-		*buflen = 0;
+-		/* copy the cpability data excluding cap ID and next ptr */
+-		cap_data = cap_ptr + 2;
+-		if ((bufsize + cap_data) > PCI_SZPCR)
+-			bufsize = PCI_SZPCR - cap_data;
+-		*buflen = bufsize;
+-		while (bufsize--) {
+-			pci_read_config_byte(dev, cap_data, buf);
+-			cap_data++;
+-			buf++;
+-		}
+-	}
+- end:
+-	return cap_ptr;
+-}
+-
+-/* ***** Register Access API */
+-uint
+-pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype,
+-	     uint offset)
+-{
+-	uint retval = 0xFFFFFFFF;
+-
+-	switch (addrtype) {
+-	case PCIE_CONFIGREGS:
+-		W_REG((&pcieregs->configaddr), offset);
+-		(void)R_REG((&pcieregs->configaddr));
+-		retval = R_REG(&(pcieregs->configdata));
+-		break;
+-	case PCIE_PCIEREGS:
+-		W_REG(&(pcieregs->pcieindaddr), offset);
+-		(void)R_REG((&pcieregs->pcieindaddr));
+-		retval = R_REG(&(pcieregs->pcieinddata));
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	return retval;
+-}
+-
+-uint
+-pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype,
+-	      uint offset, uint val)
+-{
+-	switch (addrtype) {
+-	case PCIE_CONFIGREGS:
+-		W_REG((&pcieregs->configaddr), offset);
+-		W_REG((&pcieregs->configdata), val);
+-		break;
+-	case PCIE_PCIEREGS:
+-		W_REG((&pcieregs->pcieindaddr), offset);
+-		W_REG((&pcieregs->pcieinddata), val);
+-		break;
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	uint mdiodata, i = 0;
+-	uint pcie_serdes_spinwait = 200;
+-
+-	mdiodata =
+-	    MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
+-					       MDIODATA_DEVADDR_SHF) |
+-	    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
+-									 4);
+-	W_REG(&pcieregs->mdiodata, mdiodata);
+-
+-	PR28829_DELAY();
+-	/* retry till the transaction is complete */
+-	while (i < pcie_serdes_spinwait) {
+-		if (R_REG(&(pcieregs->mdiocontrol)) &
+-		    MDIOCTL_ACCESS_DONE) {
+-			break;
+-		}
+-		udelay(1000);
+-		i++;
+-	}
+-
+-	if (i >= pcie_serdes_spinwait) {
+-		PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-static int
+-pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
+-	    uint *val)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	uint mdiodata;
+-	uint i = 0;
+-	uint pcie_serdes_spinwait = 10;
+-
+-	/* enable mdio access to SERDES */
+-	W_REG((&pcieregs->mdiocontrol),
+-	      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+-
+-	if (pi->sih->buscorerev >= 10) {
+-		/* new serdes is slower in rw, using two layers of reg address mapping */
+-		if (!pcie_mdiosetblock(pi, physmedia))
+-			return 1;
+-		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
+-		    (regaddr << MDIODATA_REGADDR_SHF);
+-		pcie_serdes_spinwait *= 20;
+-	} else {
+-		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
+-		    (regaddr << MDIODATA_REGADDR_SHF_OLD);
+-	}
+-
+-	if (!write)
+-		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
+-	else
+-		mdiodata |=
+-		    (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);
+-
+-	W_REG(&pcieregs->mdiodata, mdiodata);
+-
+-	PR28829_DELAY();
+-
+-	/* retry till the transaction is complete */
+-	while (i < pcie_serdes_spinwait) {
+-		if (R_REG(&(pcieregs->mdiocontrol)) &
+-		    MDIOCTL_ACCESS_DONE) {
+-			if (!write) {
+-				PR28829_DELAY();
+-				*val =
+-				    (R_REG(&(pcieregs->mdiodata)) &
+-				     MDIODATA_MASK);
+-			}
+-			/* Disable mdio access to SERDES */
+-			W_REG((&pcieregs->mdiocontrol), 0);
+-			return 0;
+-		}
+-		udelay(1000);
+-		i++;
+-	}
+-
+-	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
+-	/* Disable mdio access to SERDES */
+-	W_REG((&pcieregs->mdiocontrol), 0);
+-	return 1;
+-}
+-
+-/* use the mdio interface to read from mdio slaves */
+-static int
+-pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
+-{
+-	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
+-}
+-
+-/* use the mdio interface to write to mdio slaves */
+-static int
+-pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
+-{
+-	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
+-}
+-
+-/* ***** Support functions ***** */
+-u8 pcie_clkreq(void *pch, u32 mask, u32 val)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 reg_val;
+-	u8 offset;
+-
+-	offset = pi->pciecap_lcreg_offset;
+-	if (!offset)
+-		return 0;
+-
+-	pci_read_config_dword(pi->dev, offset, &reg_val);
+-	/* set operation */
+-	if (mask) {
+-		if (val)
+-			reg_val |= PCIE_CLKREQ_ENAB;
+-		else
+-			reg_val &= ~PCIE_CLKREQ_ENAB;
+-		pci_write_config_dword(pi->dev, offset, reg_val);
+-		pci_read_config_dword(pi->dev, offset, &reg_val);
+-	}
+-	if (reg_val & PCIE_CLKREQ_ENAB)
+-		return 1;
+-	else
+-		return 0;
+-}
+-
+-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
+-{
+-	u32 w;
+-	si_t *sih = pi->sih;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-
+-	if (!PCIE_PUB(sih) || sih->buscorerev < 7)
+-		return;
+-
+-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+-	if (extend)
+-		w |= PCIE_ASPMTIMER_EXTEND;
+-	else
+-		w &= ~PCIE_ASPMTIMER_EXTEND;
+-	pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
+-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+-}
+-
+-/* centralized clkreq control policy */
+-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
+-{
+-	si_t *sih = pi->sih;
+-
+-	switch (state) {
+-	case SI_DOATTACH:
+-		if (PCIE_ASPM(sih))
+-			pcie_clkreq((void *)pi, 1, 0);
+-		break;
+-	case SI_PCIDOWN:
+-		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-				   0);
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_data),
+-				   ~0x40, 0);
+-		} else if (pi->pcie_pr42767) {
+-			pcie_clkreq((void *)pi, 1, 1);
+-		}
+-		break;
+-	case SI_PCIUP:
+-		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-				   0);
+-			ai_corereg(sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol_data),
+-				   ~0x40, 0x40);
+-		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
+-			pcie_clkreq((void *)pi, 1, 0);
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-/* ***** PCI core WARs ***** */
+-/* Done only once at attach time */
+-static void pcie_war_polarity(pcicore_info_t *pi)
+-{
+-	u32 w;
+-
+-	if (pi->pcie_polarity != 0)
+-		return;
+-
+-	w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS,
+-			 PCIE_PLP_STATUSREG);
+-
+-	/* Detect the current polarity at attach and force that polarity and
+-	 * disable changing the polarity
+-	 */
+-	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
+-		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
+-	else
+-		pi->pcie_polarity =
+-		    (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
+-}
+-
+-/* enable ASPM and CLKREQ if srom doesn't have it */
+-/* Needs to happen when update to shadow SROM is needed
+- *   : Coming out of 'standby'/'hibernate'
+- *   : If pcie_war_aspm_ovr state changed
+- */
+-static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	si_t *sih = pi->sih;
+-	u16 val16, *reg16;
+-	u32 w;
+-
+-	if (!PCIE_ASPM(sih))
+-		return;
+-
+-	/* bypass this on QT or VSIM */
+-	if (!ISSIM_ENAB(sih)) {
+-
+-		reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
+-		val16 = R_REG(reg16);
+-
+-		val16 &= ~SRSH_ASPM_ENB;
+-		if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
+-			val16 |= SRSH_ASPM_ENB;
+-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
+-			val16 |= SRSH_ASPM_L1_ENB;
+-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
+-			val16 |= SRSH_ASPM_L0s_ENB;
+-
+-		W_REG(reg16, val16);
+-
+-		pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset,
+-					&w);
+-		w &= ~PCIE_ASPM_ENAB;
+-		w |= pi->pcie_war_aspm_ovr;
+-		pci_write_config_dword(pi->dev,
+-					pi->pciecap_lcreg_offset, w);
+-	}
+-
+-	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
+-	val16 = R_REG(reg16);
+-
+-	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
+-		val16 |= SRSH_CLKREQ_ENB;
+-		pi->pcie_pr42767 = true;
+-	} else
+-		val16 &= ~SRSH_CLKREQ_ENB;
+-
+-	W_REG(reg16, val16);
+-}
+-
+-/* Apply the polarity determined at the start */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_serdes(pcicore_info_t *pi)
+-{
+-	u32 w = 0;
+-
+-	if (pi->pcie_polarity != 0)
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
+-			       pi->pcie_polarity);
+-
+-	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
+-	if (w & PLL_CTRL_FREQDET_EN) {
+-		w &= ~PLL_CTRL_FREQDET_EN;
+-		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
+-	}
+-}
+-
+-/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_misc_config_fixup(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u16 val16, *reg16;
+-
+-	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
+-	val16 = R_REG(reg16);
+-
+-	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
+-		val16 |= SRSH_L23READY_EXIT_NOPERST;
+-		W_REG(reg16, val16);
+-	}
+-}
+-
+-/* quick hack for testing */
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_noplldown(pcicore_info_t *pi)
+-{
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u16 *reg16;
+-
+-	/* turn off serdes PLL down */
+-	ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
+-		   CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
+-
+-	/*  clear srom shadow backdoor */
+-	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
+-	W_REG(reg16, 0);
+-}
+-
+-/* Needs to happen when coming out of 'standby'/'hibernate' */
+-static void pcie_war_pci_setup(pcicore_info_t *pi)
+-{
+-	si_t *sih = pi->sih;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-	u32 w;
+-
+-	if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+-				 PCIE_TLP_WORKAROUNDSREG);
+-		w |= 0x8;
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+-			      PCIE_TLP_WORKAROUNDSREG, w);
+-	}
+-
+-	if (sih->buscorerev == 1) {
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
+-		w |= (0x40);
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
+-	}
+-
+-	if (sih->buscorerev == 0) {
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
+-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
+-	} else if (PCIE_ASPM(sih)) {
+-		/* Change the L1 threshold for better performance */
+-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+-				 PCIE_DLLP_PMTHRESHREG);
+-		w &= ~(PCIE_L1THRESHOLDTIME_MASK);
+-		w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
+-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+-			      PCIE_DLLP_PMTHRESHREG, w);
+-
+-		pcie_war_serdes(pi);
+-
+-		pcie_war_aspm_clkreq(pi);
+-	} else if (pi->sih->buscorerev == 7)
+-		pcie_war_noplldown(pi);
+-
+-	/* Note that the fix is actually in the SROM, that's why this is open-ended */
+-	if (pi->sih->buscorerev >= 6)
+-		pcie_misc_config_fixup(pi);
+-}
+-
+-void pcie_war_ovr_aspm_update(void *pch, u8 aspm)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!PCIE_ASPM(pi->sih))
+-		return;
+-
+-	/* Validate */
+-	if (aspm > PCIE_ASPM_ENAB)
+-		return;
+-
+-	pi->pcie_war_aspm_ovr = aspm;
+-
+-	/* Update the current state */
+-	pcie_war_aspm_clkreq(pi);
+-}
+-
+-/* ***** Functions called during driver state changes ***** */
+-void pcicore_attach(void *pch, char *pvars, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	si_t *sih = pi->sih;
+-
+-	/* Determine if this board needs override */
+-	if (PCIE_ASPM(sih)) {
+-		if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
+-			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
+-		} else {
+-			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
+-		}
+-	}
+-
+-	/* These need to happen in this order only */
+-	pcie_war_polarity(pi);
+-
+-	pcie_war_serdes(pi);
+-
+-	pcie_war_aspm_clkreq(pi);
+-
+-	pcie_clkreq_upd(pi, state);
+-
+-}
+-
+-void pcicore_hwup(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	pcie_war_pci_setup(pi);
+-}
+-
+-void pcicore_up(void *pch, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	/* Restore L1 timer for better performance */
+-	pcie_extendL1timer(pi, true);
+-
+-	pcie_clkreq_upd(pi, state);
+-}
+-
+-/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
+-void pcicore_sleep(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pi || !PCIE_ASPM(pi->sih))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
+-	w &= ~PCIE_CAP_LCREG_ASPML1;
+-	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
+-
+-	pi->pcie_pr42767 = false;
+-}
+-
+-void pcicore_down(void *pch, int state)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (!pi || !PCIE_PUB(pi->sih))
+-		return;
+-
+-	pcie_clkreq_upd(pi, state);
+-
+-	/* Reduce L1 timer for better power savings */
+-	pcie_extendL1timer(pi, false);
+-}
+-
+-/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
+-/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
+-bool pcicore_pmecap_fast(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u8 cap_ptr;
+-	u32 pmecap;
+-
+-	cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_PM, NULL,
+-					      NULL);
+-
+-	if (!cap_ptr)
+-		return false;
+-
+-	pci_read_config_dword(pi->dev, cap_ptr, &pmecap);
+-
+-	return (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+-}
+-
+-/* return true if PM capability exists in the pci config space
+- * Uses and caches the information using core handle
+- */
+-static bool pcicore_pmecap(pcicore_info_t *pi)
+-{
+-	u8 cap_ptr;
+-	u32 pmecap;
+-
+-	if (!pi->pmecap_offset) {
+-		cap_ptr = pcicore_find_pci_capability(pi->dev,
+-						      PCI_CAP_ID_PM,
+-						      NULL, NULL);
+-		if (!cap_ptr)
+-			return false;
+-
+-		pi->pmecap_offset = cap_ptr;
+-
+-		pci_read_config_dword(pi->dev, pi->pmecap_offset,
+-					&pmecap);
+-
+-		/* At least one state can generate PME */
+-		pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+-	}
+-
+-	return pi->pmecap;
+-}
+-
+-/* Enable PME generation */
+-void pcicore_pmeen(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	/* if not pmecapable return */
+-	if (!pcicore_pmecap(pi))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-	w |= (PCI_PM_CTRL_PME_ENABLE);
+-	pci_write_config_dword(pi->dev,
+-				pi->pmecap_offset + PCI_PM_CTRL, w);
+-}
+-
+-/*
+- * Return true if PME status set
+- */
+-bool pcicore_pmestat(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pcicore_pmecap(pi))
+-		return false;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-
+-	return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS;
+-}
+-
+-/* Disable PME generation, clear the PME status bit if set
+- */
+-void pcicore_pmeclr(void *pch)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u32 w;
+-
+-	if (!pcicore_pmecap(pi))
+-		return;
+-
+-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+-				&w);
+-
+-	PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));
+-
+-	/* PMESTAT is cleared by writing 1 to it */
+-	w &= ~(PCI_PM_CTRL_PME_ENABLE);
+-
+-	pci_write_config_dword(pi->dev,
+-				pi->pmecap_offset + PCI_PM_CTRL, w);
+-}
+-
+-u32 pcie_lcreg(void *pch, u32 mask, u32 val)
+-{
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	u8 offset;
+-	u32 tmpval;
+-
+-	offset = pi->pciecap_lcreg_offset;
+-	if (!offset)
+-		return 0;
+-
+-	/* set operation */
+-	if (mask)
+-		pci_write_config_dword(pi->dev, offset, val);
+-
+-	pci_read_config_dword(pi->dev, offset, &tmpval);
+-	return tmpval;
+-}
+-
+-u32
+-pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type)
+-{
+-	u32 reg_val = 0;
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+-
+-	if (mask) {
+-		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
+-		pcie_writereg(pcieregs, type, offset, val);
+-	}
+-
+-	/* Should not read register 0x154 */
+-	if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
+-	    && type == PCIE_PCIEREGS)
+-		return reg_val;
+-
+-	reg_val = pcie_readreg(pcieregs, type, offset);
+-	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));
+-
+-	return reg_val;
+-}
+-
+-u32
+-pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask,
+-		      u32 val)
+-{
+-	u32 reg_val = 0;
+-	pcicore_info_t *pi = (pcicore_info_t *) pch;
+-
+-	if (mask) {
+-		PCI_ERROR(("PCIEMDIOREG: 0x%x writeval  0x%x\n", offset, val));
+-		pcie_mdiowrite(pi, mdioslave, offset, val);
+-	}
+-
+-	if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
+-		reg_val = 0xFFFFFFFF;
+-	PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
+-		   offset, reg_val));
+-
+-	return reg_val;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/nvram.c b/drivers/staging/brcm80211/brcmsmac/nvram.c
+deleted file mode 100644
+index 085ec0b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/nvram.c
++++ /dev/null
+@@ -1,215 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <hndsoc.h>
+-
+-#define NVR_MSG(x)
+-
+-typedef struct _vars {
+-	struct _vars *next;
+-	int bufsz;		/* allocated size */
+-	int size;		/* actual vars size */
+-	char *vars;
+-} vars_t;
+-
+-#define	VARS_T_OH	sizeof(vars_t)
+-
+-static vars_t *vars;
+-
+-#define NVRAM_FILE	1
+-
+-static char *findvar(char *vars, char *lim, const char *name);
+-
+-int nvram_init(void)
+-{
+-
+-	/* Make sure we read nvram in flash just once before freeing the memory */
+-	if (vars != NULL) {
+-		NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
+-		return 0;
+-	}
+-	return 0;
+-}
+-
+-int nvram_append(char *varlst, uint varsz)
+-{
+-	uint bufsz = VARS_T_OH;
+-	vars_t *new;
+-
+-	new = kmalloc(bufsz, GFP_ATOMIC);
+-	if (new == NULL)
+-		return -ENOMEM;
+-
+-	new->vars = varlst;
+-	new->bufsz = bufsz;
+-	new->size = varsz;
+-	new->next = vars;
+-	vars = new;
+-
+-	return 0;
+-}
+-
+-void nvram_exit(void)
+-{
+-	vars_t *this, *next;
+-
+-	this = vars;
+-	if (this)
+-		kfree(this->vars);
+-
+-	while (this) {
+-		next = this->next;
+-		kfree(this);
+-		this = next;
+-	}
+-	vars = NULL;
+-}
+-
+-static char *findvar(char *vars, char *lim, const char *name)
+-{
+-	char *s;
+-	int len;
+-
+-	len = strlen(name);
+-
+-	for (s = vars; (s < lim) && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-
+-	return NULL;
+-}
+-
+-/*
+- * Search the name=value vars for a specific one and return its value.
+- * Returns NULL if not found.
+- */
+-char *getvar(char *vars, const char *name)
+-{
+-	char *s;
+-	int len;
+-
+-	if (!name)
+-		return NULL;
+-
+-	len = strlen(name);
+-	if (len == 0)
+-		return NULL;
+-
+-	/* first look in vars[] */
+-	for (s = vars; s && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-	/* then query nvram */
+-	return nvram_get(name);
+-}
+-
+-/*
+- * Search the vars for a specific one and return its value as
+- * an integer. Returns 0 if not found.
+- */
+-int getintvar(char *vars, const char *name)
+-{
+-	char *val;
+-
+-	val = getvar(vars, name);
+-	if (val == NULL)
+-		return 0;
+-
+-	return simple_strtoul(val, NULL, 0);
+-}
+-
+-char *nvram_get(const char *name)
+-{
+-	char *v = NULL;
+-	vars_t *cur;
+-
+-	for (cur = vars; cur; cur = cur->next) {
+-		v = findvar(cur->vars, cur->vars + cur->size, name);
+-		if (v)
+-			break;
+-	}
+-
+-	return v;
+-}
+-
+-int nvram_set(const char *name, const char *value)
+-{
+-	return 0;
+-}
+-
+-int nvram_unset(const char *name)
+-{
+-	return 0;
+-}
+-
+-int nvram_reset(void)
+-{
+-	return 0;
+-}
+-
+-int nvram_commit(void)
+-{
+-	return 0;
+-}
+-
+-int nvram_getall(char *buf, int count)
+-{
+-	int len, resid = count;
+-	vars_t *this;
+-
+-	this = vars;
+-	while (this) {
+-		char *from, *lim, *to;
+-		int acc;
+-
+-		from = this->vars;
+-		lim = (char *)(this->vars + this->size);
+-		to = buf;
+-		acc = 0;
+-		while ((from < lim) && (*from)) {
+-			len = strlen(from) + 1;
+-			if (resid < (acc + len))
+-				return -EOVERFLOW;
+-			memcpy(to, from, len);
+-			acc += len;
+-			from += len;
+-			to += len;
+-		}
+-
+-		resid -= acc;
+-		buf += acc;
+-		this = this->next;
+-	}
+-	if (resid < 1)
+-		return -EOVERFLOW;
+-	*buf = '\0';
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
+deleted file mode 100644
+index 51a2238..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h
++++ /dev/null
+@@ -1,36 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef phy_version_h_
+-#define phy_version_h_
+-
+-#define	PHY_MAJOR_VERSION		1
+-
+-#define	PHY_MINOR_VERSION		82
+-
+-#define	PHY_RC_NUMBER		8
+-
+-#define	PHY_INCREMENTAL_NUMBER	0
+-
+-#define	PHY_BUILD_NUMBER		0
+-
+-#define	PHY_VERSION			{ 1, 82, 8, 0 }
+-
+-#define	PHY_VERSION_NUM		0x01520800
+-
+-#define	PHY_VERSION_STR		"1.82.8.0"
+-
+-#endif				/* phy_version_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
+deleted file mode 100644
+index 6cba4df..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
++++ /dev/null
+@@ -1,3307 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <wlc_cfg.h>
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/bitops.h>
+-#include <linux/delay.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmnvram.h>
+-#include <sbchipc.h>
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include <wlc_phy_int.h>
+-#include <wlc_phyreg_n.h>
+-#include <wlc_phy_radio.h>
+-#include <wlc_phy_lcn.h>
+-
+-u32 phyhal_msg_level = PHYHAL_ERROR;
+-
+-typedef struct _chan_info_basic {
+-	u16 chan;
+-	u16 freq;
+-} chan_info_basic_t;
+-
+-static chan_info_basic_t chan_info_all[] = {
+-
+-	{1, 2412},
+-	{2, 2417},
+-	{3, 2422},
+-	{4, 2427},
+-	{5, 2432},
+-	{6, 2437},
+-	{7, 2442},
+-	{8, 2447},
+-	{9, 2452},
+-	{10, 2457},
+-	{11, 2462},
+-	{12, 2467},
+-	{13, 2472},
+-	{14, 2484},
+-
+-	{34, 5170},
+-	{38, 5190},
+-	{42, 5210},
+-	{46, 5230},
+-
+-	{36, 5180},
+-	{40, 5200},
+-	{44, 5220},
+-	{48, 5240},
+-	{52, 5260},
+-	{56, 5280},
+-	{60, 5300},
+-	{64, 5320},
+-
+-	{100, 5500},
+-	{104, 5520},
+-	{108, 5540},
+-	{112, 5560},
+-	{116, 5580},
+-	{120, 5600},
+-	{124, 5620},
+-	{128, 5640},
+-	{132, 5660},
+-	{136, 5680},
+-	{140, 5700},
+-
+-	{149, 5745},
+-	{153, 5765},
+-	{157, 5785},
+-	{161, 5805},
+-	{165, 5825},
+-
+-	{184, 4920},
+-	{188, 4940},
+-	{192, 4960},
+-	{196, 4980},
+-	{200, 5000},
+-	{204, 5020},
+-	{208, 5040},
+-	{212, 5060},
+-	{216, 50800}
+-};
+-
+-u16 ltrn_list[PHY_LTRN_LIST_LEN] = {
+-	0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc,
+-	0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010,
+-	0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc,
+-	0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318,
+-	0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312,
+-	0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc,
+-	0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01,
+-	0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff,
+-	0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec,
+-	0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814,
+-	0x0507, 0x0fea, 0xe4f2, 0xf6e6
+-};
+-
+-const u8 ofdm_rate_lookup[] = {
+-
+-	WLC_RATE_48M,
+-	WLC_RATE_24M,
+-	WLC_RATE_12M,
+-	WLC_RATE_6M,
+-	WLC_RATE_54M,
+-	WLC_RATE_36M,
+-	WLC_RATE_18M,
+-	WLC_RATE_9M
+-};
+-
+-#define PHY_WREG_LIMIT	24
+-
+-static void wlc_set_phy_uninitted(phy_info_t *pi);
+-static u32 wlc_phy_get_radio_ver(phy_info_t *pi);
+-static void wlc_phy_timercb_phycal(void *arg);
+-
+-static bool wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr,
+-				   s8 *pwr_ant);
+-
+-static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay);
+-static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm);
+-static void wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason,
+-					 u8 ch);
+-
+-static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi,
+-					   struct txpwr_limits *tp, chanspec_t);
+-static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi);
+-
+-static s8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan,
+-					     u32 band, u8 rate);
+-static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band);
+-static s8 wlc_phy_env_measure_vbat(phy_info_t *pi);
+-static s8 wlc_phy_env_measure_temperature(phy_info_t *pi);
+-
+-char *phy_getvar(phy_info_t *pi, const char *name)
+-{
+-	char *vars = pi->vars;
+-	char *s;
+-	int len;
+-
+-	if (!name)
+-		return NULL;
+-
+-	len = strlen(name);
+-	if (len == 0)
+-		return NULL;
+-
+-	for (s = vars; s && *s;) {
+-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+-			return &s[len + 1];
+-
+-		while (*s++)
+-			;
+-	}
+-
+-	return nvram_get(name);
+-}
+-
+-int phy_getintvar(phy_info_t *pi, const char *name)
+-{
+-	char *val;
+-
+-	val = PHY_GETVAR(pi, name);
+-	if (val == NULL)
+-		return 0;
+-
+-	return simple_strtoul(val, NULL, 0);
+-}
+-
+-void wlc_phyreg_enter(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
+-}
+-
+-void wlc_phyreg_exit(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
+-}
+-
+-void wlc_radioreg_enter(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
+-
+-	udelay(10);
+-}
+-
+-void wlc_radioreg_exit(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	volatile u16 dummy;
+-
+-	dummy = R_REG(&pi->regs->phyversion);
+-	pi->phy_wreg = 0;
+-	wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
+-}
+-
+-u16 read_radio_reg(phy_info_t *pi, u16 addr)
+-{
+-	u16 data;
+-
+-	if ((addr == RADIO_IDCODE))
+-		return 0xffff;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return NORADIO_IDCODE & 0xffff;
+-
+-	switch (pi->pubpi.phy_type) {
+-	case PHY_TYPE_N:
+-		CASECHECK(PHYTYPE, PHY_TYPE_N);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7))
+-			addr |= RADIO_2057_READ_OFF;
+-		else
+-			addr |= RADIO_2055_READ_OFF;
+-		break;
+-
+-	case PHY_TYPE_LCN:
+-		CASECHECK(PHYTYPE, PHY_TYPE_LCN);
+-		addr |= RADIO_2064_READ_OFF;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	if ((D11REV_GE(pi->sh->corerev, 24)) ||
+-	    (D11REV_IS(pi->sh->corerev, 22)
+-	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+-		W_REG(&pi->regs->radioregaddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		data = R_REG(&pi->regs->radioregdata);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-
+-#ifdef __ARM_ARCH_4T__
+-		__asm__(" .align 4 ");
+-		__asm__(" nop ");
+-		data = R_REG(&pi->regs->phy4wdatalo);
+-#else
+-		data = R_REG(&pi->regs->phy4wdatalo);
+-#endif
+-
+-	}
+-	pi->phy_wreg = 0;
+-
+-	return data;
+-}
+-
+-void write_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if ((D11REV_GE(pi->sh->corerev, 24)) ||
+-	    (D11REV_IS(pi->sh->corerev, 22)
+-	     && (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
+-
+-		W_REG(&pi->regs->radioregaddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		W_REG(&pi->regs->radioregdata, val);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, addr);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-		W_REG(&pi->regs->phy4wdatalo, val);
+-	}
+-
+-	if (pi->sh->bustype == PCI_BUS) {
+-		if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+-			(void)R_REG(&pi->regs->maccontrol);
+-			pi->phy_wreg = 0;
+-		}
+-	}
+-}
+-
+-static u32 read_radio_id(phy_info_t *pi)
+-{
+-	u32 id;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return NORADIO_IDCODE;
+-
+-	if (D11REV_GE(pi->sh->corerev, 24)) {
+-		u32 b0, b1, b2;
+-
+-		W_REG(&pi->regs->radioregaddr, 0);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b0 = (u32) R_REG(&pi->regs->radioregdata);
+-		W_REG(&pi->regs->radioregaddr, 1);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b1 = (u32) R_REG(&pi->regs->radioregdata);
+-		W_REG(&pi->regs->radioregaddr, 2);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->radioregaddr);
+-#endif
+-		b2 = (u32) R_REG(&pi->regs->radioregdata);
+-
+-		id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
+-								      & 0xf);
+-	} else {
+-		W_REG(&pi->regs->phy4waddr, RADIO_IDCODE);
+-#ifdef __mips__
+-		(void)R_REG(&pi->regs->phy4waddr);
+-#endif
+-		id = (u32) R_REG(&pi->regs->phy4wdatalo);
+-		id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16;
+-	}
+-	pi->phy_wreg = 0;
+-	return id;
+-}
+-
+-void and_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval & val));
+-}
+-
+-void or_radio_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval | val));
+-}
+-
+-void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval ^ mask));
+-}
+-
+-void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val)
+-{
+-	u16 rval;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	rval = read_radio_reg(pi, addr);
+-	write_radio_reg(pi, addr, (rval & ~mask) | (val & mask));
+-}
+-
+-void write_phy_channel_reg(phy_info_t *pi, uint val)
+-{
+-	W_REG(&pi->regs->phychannel, val);
+-}
+-
+-u16 read_phy_reg(phy_info_t *pi, u16 addr)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	pi->phy_wreg = 0;
+-	return R_REG(&regs->phyregdata);
+-}
+-
+-void write_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-#ifdef __mips__
+-	W_REG(&regs->phyregaddr, addr);
+-	(void)R_REG(&regs->phyregaddr);
+-	W_REG(&regs->phyregdata, val);
+-	if (addr == 0x72)
+-		(void)R_REG(&regs->phyregdata);
+-#else
+-	W_REG((u32 *)(&regs->phyregaddr),
+-	      addr | (val << 16));
+-	if (pi->sh->bustype == PCI_BUS) {
+-		if (++pi->phy_wreg >= pi->phy_wreg_limit) {
+-			pi->phy_wreg = 0;
+-			(void)R_REG(&regs->phyversion);
+-		}
+-	}
+-#endif
+-}
+-
+-void and_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) & val));
+-	pi->phy_wreg = 0;
+-}
+-
+-void or_phy_reg(phy_info_t *pi, u16 addr, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) | val));
+-	pi->phy_wreg = 0;
+-}
+-
+-void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val)
+-{
+-	d11regs_t *regs;
+-
+-	regs = pi->regs;
+-
+-	W_REG(&regs->phyregaddr, addr);
+-#ifdef __mips__
+-	(void)R_REG(&regs->phyregaddr);
+-#endif
+-
+-	W_REG(&regs->phyregdata,
+-	      ((R_REG(&regs->phyregdata) & ~mask) | (val & mask)));
+-	pi->phy_wreg = 0;
+-}
+-
+-static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi)
+-{
+-	int i, j;
+-
+-	pi->initialized = false;
+-
+-	pi->tx_vos = 0xffff;
+-	pi->nrssi_table_delta = 0x7fffffff;
+-	pi->rc_cal = 0xffff;
+-	pi->mintxbias = 0xffff;
+-	pi->txpwridx = -1;
+-	if (ISNPHY(pi)) {
+-		pi->phy_spuravoid = SPURAVOID_DISABLE;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)
+-		    && NREV_LT(pi->pubpi.phy_rev, 7))
+-			pi->phy_spuravoid = SPURAVOID_AUTO;
+-
+-		pi->nphy_papd_skip = 0;
+-		pi->nphy_papd_epsilon_offset[0] = 0xf588;
+-		pi->nphy_papd_epsilon_offset[1] = 0xf588;
+-		pi->nphy_txpwr_idx[0] = 128;
+-		pi->nphy_txpwr_idx[1] = 128;
+-		pi->nphy_txpwrindex[0].index_internal = 40;
+-		pi->nphy_txpwrindex[1].index_internal = 40;
+-		pi->phy_pabias = 0;
+-	} else {
+-		pi->phy_spuravoid = SPURAVOID_AUTO;
+-	}
+-	pi->radiopwr = 0xffff;
+-	for (i = 0; i < STATIC_NUM_RF; i++) {
+-		for (j = 0; j < STATIC_NUM_BB; j++) {
+-			pi->stats_11b_txpower[i][j] = -1;
+-		}
+-	}
+-}
+-
+-shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp)
+-{
+-	shared_phy_t *sh;
+-
+-	sh = kzalloc(sizeof(shared_phy_t), GFP_ATOMIC);
+-	if (sh == NULL) {
+-		return NULL;
+-	}
+-
+-	sh->sih = shp->sih;
+-	sh->physhim = shp->physhim;
+-	sh->unit = shp->unit;
+-	sh->corerev = shp->corerev;
+-
+-	sh->vid = shp->vid;
+-	sh->did = shp->did;
+-	sh->chip = shp->chip;
+-	sh->chiprev = shp->chiprev;
+-	sh->chippkg = shp->chippkg;
+-	sh->sromrev = shp->sromrev;
+-	sh->boardtype = shp->boardtype;
+-	sh->boardrev = shp->boardrev;
+-	sh->boardvendor = shp->boardvendor;
+-	sh->boardflags = shp->boardflags;
+-	sh->boardflags2 = shp->boardflags2;
+-	sh->bustype = shp->bustype;
+-	sh->buscorerev = shp->buscorerev;
+-
+-	sh->fast_timer = PHY_SW_TIMER_FAST;
+-	sh->slow_timer = PHY_SW_TIMER_SLOW;
+-	sh->glacial_timer = PHY_SW_TIMER_GLACIAL;
+-
+-	sh->rssi_mode = RSSI_ANT_MERGE_MAX;
+-
+-	return sh;
+-}
+-
+-void wlc_phy_shared_detach(shared_phy_t *phy_sh)
+-{
+-	if (phy_sh) {
+-		kfree(phy_sh);
+-	}
+-}
+-
+-wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+-			  char *vars, struct wiphy *wiphy)
+-{
+-	phy_info_t *pi;
+-	u32 sflags = 0;
+-	uint phyversion;
+-	int i;
+-
+-	if (D11REV_IS(sh->corerev, 4))
+-		sflags = SISF_2G_PHY | SISF_5G_PHY;
+-	else
+-		sflags = ai_core_sflags(sh->sih, 0, 0);
+-
+-	if (BAND_5G(bandtype)) {
+-		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) {
+-			return NULL;
+-		}
+-	}
+-
+-	pi = sh->phy_head;
+-	if ((sflags & SISF_DB_PHY) && pi) {
+-
+-		wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+-		pi->refcnt++;
+-		return &pi->pubpi_ro;
+-	}
+-
+-	pi = kzalloc(sizeof(phy_info_t), GFP_ATOMIC);
+-	if (pi == NULL) {
+-		return NULL;
+-	}
+-	pi->wiphy = wiphy;
+-	pi->regs = (d11regs_t *) regs;
+-	pi->sh = sh;
+-	pi->phy_init_por = true;
+-	pi->phy_wreg_limit = PHY_WREG_LIMIT;
+-
+-	pi->vars = vars;
+-
+-	pi->txpwr_percent = 100;
+-
+-	pi->do_initcal = true;
+-
+-	pi->phycal_tempdelta = 0;
+-
+-	if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) {
+-
+-		pi->pubpi.coreflags = SICF_GMODE;
+-	}
+-
+-	wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
+-	phyversion = R_REG(&pi->regs->phyversion);
+-
+-	pi->pubpi.phy_type = PHY_TYPE(phyversion);
+-	pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
+-
+-	if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) {
+-		pi->pubpi.phy_type = PHY_TYPE_N;
+-		pi->pubpi.phy_rev += LCNXN_BASEREV;
+-	}
+-	pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
+-	pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
+-
+-	if (!VALID_PHYTYPE(pi->pubpi.phy_type)) {
+-		goto err;
+-	}
+-	if (BAND_5G(bandtype)) {
+-		if (!ISNPHY(pi)) {
+-			goto err;
+-		}
+-	} else {
+-		if (!ISNPHY(pi) && !ISLCNPHY(pi)) {
+-			goto err;
+-		}
+-	}
+-
+-	if (ISSIM_ENAB(pi->sh->sih)) {
+-		pi->pubpi.radioid = NORADIO_ID;
+-		pi->pubpi.radiorev = 5;
+-	} else {
+-		u32 idcode;
+-
+-		wlc_phy_anacore((wlc_phy_t *) pi, ON);
+-
+-		idcode = wlc_phy_get_radio_ver(pi);
+-		pi->pubpi.radioid =
+-		    (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT;
+-		pi->pubpi.radiorev =
+-		    (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT;
+-		pi->pubpi.radiover =
+-		    (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT;
+-		if (!VALID_RADIO(pi, pi->pubpi.radioid)) {
+-			goto err;
+-		}
+-
+-		wlc_phy_switch_radio((wlc_phy_t *) pi, OFF);
+-	}
+-
+-	wlc_set_phy_uninitted(pi);
+-
+-	pi->bw = WL_CHANSPEC_BW_20;
+-	pi->radio_chanspec =
+-	    BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36);
+-
+-	pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+-	pi->rxiq_antsel = ANT_RX_DIV_DEF;
+-
+-	pi->watchdog_override = true;
+-
+-	pi->cal_type_override = PHY_PERICAL_AUTO;
+-
+-	pi->nphy_saved_noisevars.bufcount = 0;
+-
+-	if (ISNPHY(pi))
+-		pi->min_txpower = PHY_TXPWR_MIN_NPHY;
+-	else
+-		pi->min_txpower = PHY_TXPWR_MIN;
+-
+-	pi->sh->phyrxchain = 0x3;
+-
+-	pi->rx2tx_biasentry = -1;
+-
+-	pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+-	pi->phy_txcore_enable_temp =
+-	    PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP;
+-	pi->phy_tempsense_offset = 0;
+-	pi->phy_txcore_heatedup = false;
+-
+-	pi->nphy_lastcal_temp = -50;
+-
+-	pi->phynoise_polling = true;
+-	if (ISNPHY(pi) || ISLCNPHY(pi))
+-		pi->phynoise_polling = false;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++) {
+-		pi->txpwr_limit[i] = WLC_TXPWR_MAX;
+-		pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+-		pi->tx_user_target[i] = WLC_TXPWR_MAX;
+-	}
+-
+-	pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF;
+-
+-	pi->user_txpwr_at_rfport = false;
+-
+-	if (ISNPHY(pi)) {
+-
+-		pi->phycal_timer = wlapi_init_timer(pi->sh->physhim,
+-							  wlc_phy_timercb_phycal,
+-							  pi, "phycal");
+-		if (!pi->phycal_timer) {
+-			goto err;
+-		}
+-
+-		if (!wlc_phy_attach_nphy(pi))
+-			goto err;
+-
+-	} else if (ISLCNPHY(pi)) {
+-		if (!wlc_phy_attach_lcnphy(pi))
+-			goto err;
+-
+-	} else {
+-
+-	}
+-
+-	pi->refcnt++;
+-	pi->next = pi->sh->phy_head;
+-	sh->phy_head = pi;
+-
+-	pi->vars = (char *)&pi->vars;
+-
+-	memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(wlc_phy_t));
+-
+-	return &pi->pubpi_ro;
+-
+- err:
+-	kfree(pi);
+-	return NULL;
+-}
+-
+-void wlc_phy_detach(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (pih) {
+-		if (--pi->refcnt) {
+-			return;
+-		}
+-
+-		if (pi->phycal_timer) {
+-			wlapi_free_timer(pi->sh->physhim, pi->phycal_timer);
+-			pi->phycal_timer = NULL;
+-		}
+-
+-		if (pi->sh->phy_head == pi)
+-			pi->sh->phy_head = pi->next;
+-		else if (pi->sh->phy_head->next == pi)
+-			pi->sh->phy_head->next = NULL;
+-
+-		if (pi->pi_fptr.detach)
+-			(pi->pi_fptr.detach) (pi);
+-
+-		kfree(pi);
+-	}
+-}
+-
+-bool
+-wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev,
+-		       u16 *radioid, u16 *radiover)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	*phytype = (u16) pi->pubpi.phy_type;
+-	*phyrev = (u16) pi->pubpi.phy_rev;
+-	*radioid = pi->pubpi.radioid;
+-	*radiover = pi->pubpi.radiorev;
+-
+-	return true;
+-}
+-
+-bool wlc_phy_get_encore(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	return pi->pubpi.abgphy_encore;
+-}
+-
+-u32 wlc_phy_get_coreflags(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	return pi->pubpi.coreflags;
+-}
+-
+-static void wlc_phy_timercb_phycal(void *arg)
+-{
+-	phy_info_t *pi = (phy_info_t *) arg;
+-	uint delay = 5;
+-
+-	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-		if (!pi->sh->up) {
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			return;
+-		}
+-
+-		if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) {
+-
+-			delay = 1000;
+-			wlc_phy_cal_perical_mphase_restart(pi);
+-		} else
+-			wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO);
+-		wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+-		return;
+-	}
+-
+-}
+-
+-void wlc_phy_anacore(wlc_phy_t *pih, bool on)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (ISNPHY(pi)) {
+-		if (on) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				write_phy_reg(pi, 0xa6, 0x0d);
+-				write_phy_reg(pi, 0x8f, 0x0);
+-				write_phy_reg(pi, 0xa7, 0x0d);
+-				write_phy_reg(pi, 0xa5, 0x0);
+-			} else {
+-				write_phy_reg(pi, 0xa5, 0x0);
+-			}
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				write_phy_reg(pi, 0x8f, 0x07ff);
+-				write_phy_reg(pi, 0xa6, 0x0fd);
+-				write_phy_reg(pi, 0xa5, 0x07ff);
+-				write_phy_reg(pi, 0xa7, 0x0fd);
+-			} else {
+-				write_phy_reg(pi, 0xa5, 0x7fff);
+-			}
+-		}
+-	} else if (ISLCNPHY(pi)) {
+-		if (on) {
+-			and_phy_reg(pi, 0x43b,
+-				    ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-		} else {
+-			or_phy_reg(pi, 0x43c,
+-				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-			or_phy_reg(pi, 0x43b,
+-				   (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-		}
+-	}
+-}
+-
+-u32 wlc_phy_clk_bwbits(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	u32 phy_bw_clkbits = 0;
+-
+-	if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) {
+-		switch (pi->bw) {
+-		case WL_CHANSPEC_BW_10:
+-			phy_bw_clkbits = SICF_BW10;
+-			break;
+-		case WL_CHANSPEC_BW_20:
+-			phy_bw_clkbits = SICF_BW20;
+-			break;
+-		case WL_CHANSPEC_BW_40:
+-			phy_bw_clkbits = SICF_BW40;
+-			break;
+-		default:
+-			break;
+-		}
+-	}
+-
+-	return phy_bw_clkbits;
+-}
+-
+-void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->phy_init_por = true;
+-}
+-
+-void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->edcrs_threshold_lock = lock;
+-
+-	write_phy_reg(pi, 0x22c, 0x46b);
+-	write_phy_reg(pi, 0x22d, 0x46b);
+-	write_phy_reg(pi, 0x22e, 0x3c0);
+-	write_phy_reg(pi, 0x22f, 0x3c0);
+-}
+-
+-void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->do_initcal = initcal;
+-}
+-
+-void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!pi || !pi->sh)
+-		return;
+-
+-	pi->sh->clk = newstate;
+-}
+-
+-void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!pi || !pi->sh)
+-		return;
+-
+-	pi->sh->up = newstate;
+-}
+-
+-void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec)
+-{
+-	u32 mc;
+-	initfn_t phy_init = NULL;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (pi->init_in_progress)
+-		return;
+-
+-	pi->init_in_progress = true;
+-
+-	pi->radio_chanspec = chanspec;
+-
+-	mc = R_REG(&pi->regs->maccontrol);
+-	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
+-		return;
+-
+-	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+-		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+-	}
+-
+-	if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
+-		 "HW error SISF_FCLKA\n"))
+-		return;
+-
+-	phy_init = pi->pi_fptr.init;
+-
+-	if (phy_init == NULL) {
+-		return;
+-	}
+-
+-	wlc_phy_anacore(pih, ON);
+-
+-	if (CHSPEC_BW(pi->radio_chanspec) != pi->bw)
+-		wlapi_bmac_bw_set(pi->sh->physhim,
+-				  CHSPEC_BW(pi->radio_chanspec));
+-
+-	pi->nphy_gain_boost = true;
+-
+-	wlc_phy_switch_radio((wlc_phy_t *) pi, ON);
+-
+-	(*phy_init) (pi);
+-
+-	pi->phy_init_por = false;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlc_phy_do_dummy_tx(pi, true, OFF);
+-
+-	if (!(ISNPHY(pi)))
+-		wlc_phy_txpower_update_shm(pi);
+-
+-	wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv);
+-
+-	pi->init_in_progress = false;
+-}
+-
+-void wlc_phy_cal_init(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	initfn_t cal_init = NULL;
+-
+-	if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
+-		 "HW error: MAC enabled during phy cal\n"))
+-		return;
+-
+-	if (!pi->initialized) {
+-		cal_init = pi->pi_fptr.calinit;
+-		if (cal_init)
+-			(*cal_init) (pi);
+-
+-		pi->initialized = true;
+-	}
+-}
+-
+-int wlc_phy_down(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	int callbacks = 0;
+-
+-	if (pi->phycal_timer
+-	    && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
+-		callbacks++;
+-
+-	pi->nphy_iqcal_chanspec_2G = 0;
+-	pi->nphy_iqcal_chanspec_5G = 0;
+-
+-	return callbacks;
+-}
+-
+-static u32 wlc_phy_get_radio_ver(phy_info_t *pi)
+-{
+-	u32 ver;
+-
+-	ver = read_radio_id(pi);
+-
+-	return ver;
+-}
+-
+-void
+-wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+-		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	pi->tbl_data_hi = tblDataHi;
+-	pi->tbl_data_lo = tblDataLo;
+-
+-	if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-	     pi->sh->chip == BCM43421_CHIP_ID) &&
+-	    (pi->sh->chiprev == 1)) {
+-		pi->tbl_addr = tblAddr;
+-		pi->tbl_save_id = tbl_id;
+-		pi->tbl_save_offset = tbl_offset;
+-	}
+-}
+-
+-void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val)
+-{
+-	if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-	     pi->sh->chip == BCM43421_CHIP_ID) &&
+-	    (pi->sh->chiprev == 1) &&
+-	    (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+-		read_phy_reg(pi, pi->tbl_data_lo);
+-
+-		write_phy_reg(pi, pi->tbl_addr,
+-			      (pi->tbl_save_id << 10) | pi->tbl_save_offset);
+-		pi->tbl_save_offset++;
+-	}
+-
+-	if (width == 32) {
+-
+-		write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16));
+-		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
+-	} else {
+-
+-		write_phy_reg(pi, pi->tbl_data_lo, (u16) val);
+-	}
+-}
+-
+-void
+-wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-		    u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	uint idx;
+-	uint tbl_id = ptbl_info->tbl_id;
+-	uint tbl_offset = ptbl_info->tbl_offset;
+-	uint tbl_width = ptbl_info->tbl_width;
+-	const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr;
+-	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
+-	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
+-
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-		     pi->sh->chip == BCM43421_CHIP_ID) &&
+-		    (pi->sh->chiprev == 1) &&
+-		    (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) {
+-			read_phy_reg(pi, tblDataLo);
+-
+-			write_phy_reg(pi, tblAddr,
+-				      (tbl_id << 10) | (tbl_offset + idx));
+-		}
+-
+-		if (tbl_width == 32) {
+-
+-			write_phy_reg(pi, tblDataHi,
+-				      (u16) (ptbl_32b[idx] >> 16));
+-			write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]);
+-		} else if (tbl_width == 16) {
+-
+-			write_phy_reg(pi, tblDataLo, ptbl_16b[idx]);
+-		} else {
+-
+-			write_phy_reg(pi, tblDataLo, ptbl_8b[idx]);
+-		}
+-	}
+-}
+-
+-void
+-wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-		   u16 tblAddr, u16 tblDataHi, u16 tblDataLo)
+-{
+-	uint idx;
+-	uint tbl_id = ptbl_info->tbl_id;
+-	uint tbl_offset = ptbl_info->tbl_offset;
+-	uint tbl_width = ptbl_info->tbl_width;
+-	u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr;
+-	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
+-	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
+-
+-	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
+-
+-	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID ||
+-		     pi->sh->chip == BCM43421_CHIP_ID) &&
+-		    (pi->sh->chiprev == 1)) {
+-			(void)read_phy_reg(pi, tblDataLo);
+-
+-			write_phy_reg(pi, tblAddr,
+-				      (tbl_id << 10) | (tbl_offset + idx));
+-		}
+-
+-		if (tbl_width == 32) {
+-
+-			ptbl_32b[idx] = read_phy_reg(pi, tblDataLo);
+-			ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16);
+-		} else if (tbl_width == 16) {
+-
+-			ptbl_16b[idx] = read_phy_reg(pi, tblDataLo);
+-		} else {
+-
+-			ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo);
+-		}
+-	}
+-}
+-
+-uint
+-wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs)
+-{
+-	uint i = 0;
+-
+-	do {
+-		if (radioregs[i].do_init) {
+-			write_radio_reg(pi, radioregs[i].address,
+-					(u16) radioregs[i].init);
+-		}
+-
+-		i++;
+-	} while (radioregs[i].address != 0xffff);
+-
+-	return i;
+-}
+-
+-uint
+-wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+-			u16 core_offset)
+-{
+-	uint i = 0;
+-	uint count = 0;
+-
+-	do {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			if (radioregs[i].do_init_a) {
+-				write_radio_reg(pi,
+-						radioregs[i].
+-						address | core_offset,
+-						(u16) radioregs[i].init_a);
+-				if (ISNPHY(pi) && (++count % 4 == 0))
+-					WLC_PHY_WAR_PR51571(pi);
+-			}
+-		} else {
+-			if (radioregs[i].do_init_g) {
+-				write_radio_reg(pi,
+-						radioregs[i].
+-						address | core_offset,
+-						(u16) radioregs[i].init_g);
+-				if (ISNPHY(pi) && (++count % 4 == 0))
+-					WLC_PHY_WAR_PR51571(pi);
+-			}
+-		}
+-
+-		i++;
+-	} while (radioregs[i].address != 0xffff);
+-
+-	return i;
+-}
+-
+-void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on)
+-{
+-#define	DUMMY_PKT_LEN	20
+-	d11regs_t *regs = pi->regs;
+-	int i, count;
+-	u8 ofdmpkt[DUMMY_PKT_LEN] = {
+-		0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+-		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+-	};
+-	u8 cckpkt[DUMMY_PKT_LEN] = {
+-		0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+-		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00
+-	};
+-	u32 *dummypkt;
+-
+-	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
+-	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
+-				      dummypkt);
+-
+-	W_REG(&regs->xmtsel, 0);
+-
+-	if (D11REV_GE(pi->sh->corerev, 11))
+-		W_REG(&regs->wepctl, 0x100);
+-	else
+-		W_REG(&regs->wepctl, 0);
+-
+-	W_REG(&regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
+-	if (ISNPHY(pi) || ISLCNPHY(pi)) {
+-		W_REG(&regs->txe_phyctl1, 0x1A02);
+-	}
+-
+-	W_REG(&regs->txe_wm_0, 0);
+-	W_REG(&regs->txe_wm_1, 0);
+-
+-	W_REG(&regs->xmttplatetxptr, 0);
+-	W_REG(&regs->xmttxcnt, DUMMY_PKT_LEN);
+-
+-	W_REG(&regs->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
+-
+-	W_REG(&regs->txe_ctl, 0);
+-
+-	if (!pa_on) {
+-		if (ISNPHY(pi))
+-			wlc_phy_pa_override_nphy(pi, OFF);
+-	}
+-
+-	if (ISNPHY(pi) || ISLCNPHY(pi))
+-		W_REG(&regs->txe_aux, 0xD0);
+-	else
+-		W_REG(&regs->txe_aux, ((1 << 5) | (1 << 4)));
+-
+-	(void)R_REG(&regs->txe_aux);
+-
+-	i = 0;
+-	count = ofdm ? 30 : 250;
+-
+-	if (ISSIM_ENAB(pi->sh->sih)) {
+-		count *= 100;
+-	}
+-
+-	while ((i++ < count)
+-	       && (R_REG(&regs->txe_status) & (1 << 7))) {
+-		udelay(10);
+-	}
+-
+-	i = 0;
+-
+-	while ((i++ < 10)
+-	       && ((R_REG(&regs->txe_status) & (1 << 10)) == 0)) {
+-		udelay(10);
+-	}
+-
+-	i = 0;
+-
+-	while ((i++ < 10) && ((R_REG(&regs->ifsstat) & (1 << 8))))
+-		udelay(10);
+-
+-	if (!pa_on) {
+-		if (ISNPHY(pi))
+-			wlc_phy_pa_override_nphy(pi, ON);
+-	}
+-}
+-
+-void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (set) {
+-		mboolset(pi->measure_hold, id);
+-	} else {
+-		mboolclr(pi->measure_hold, id);
+-	}
+-
+-	return;
+-}
+-
+-void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (mute) {
+-		mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+-	} else {
+-		mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE);
+-	}
+-
+-	if (!mute && (flags & PHY_MUTE_FOR_PREISM))
+-		pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer;
+-	return;
+-}
+-
+-void wlc_phy_clear_tssi(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (ISNPHY(pi)) {
+-		return;
+-	} else {
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W);
+-	}
+-}
+-
+-static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi)
+-{
+-	return false;
+-}
+-
+-void wlc_phy_switch_radio(wlc_phy_t *pih, bool on)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	{
+-		uint mc;
+-
+-		mc = R_REG(&pi->regs->maccontrol);
+-	}
+-
+-	if (ISNPHY(pi)) {
+-		wlc_phy_switch_radio_nphy(pi, on);
+-
+-	} else if (ISLCNPHY(pi)) {
+-		if (on) {
+-			and_phy_reg(pi, 0x44c,
+-				    ~((0x1 << 8) |
+-				      (0x1 << 9) |
+-				      (0x1 << 10) | (0x1 << 11) | (0x1 << 12)));
+-			and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11)));
+-			and_phy_reg(pi, 0x4f9, ~(0x1 << 3));
+-		} else {
+-			and_phy_reg(pi, 0x44d,
+-				    ~((0x1 << 10) |
+-				      (0x1 << 11) |
+-				      (0x1 << 12) | (0x1 << 13) | (0x1 << 14)));
+-			or_phy_reg(pi, 0x44c,
+-				   (0x1 << 8) |
+-				   (0x1 << 9) |
+-				   (0x1 << 10) | (0x1 << 11) | (0x1 << 12));
+-
+-			and_phy_reg(pi, 0x4b7, ~((0x7f << 8)));
+-			and_phy_reg(pi, 0x4b1, ~((0x1 << 13)));
+-			or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11));
+-			and_phy_reg(pi, 0x4fa, ~((0x1 << 3)));
+-			or_phy_reg(pi, 0x4f9, (0x1 << 3));
+-		}
+-	}
+-}
+-
+-u16 wlc_phy_bw_state_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->bw;
+-}
+-
+-void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->bw = bw;
+-}
+-
+-void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	pi->radio_chanspec = newch;
+-
+-}
+-
+-chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->radio_chanspec;
+-}
+-
+-void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 m_cur_channel;
+-	chansetfn_t chanspec_set = NULL;
+-
+-	m_cur_channel = CHSPEC_CHANNEL(chanspec);
+-	if (CHSPEC_IS5G(chanspec))
+-		m_cur_channel |= D11_CURCHANNEL_5G;
+-	if (CHSPEC_IS40(chanspec))
+-		m_cur_channel |= D11_CURCHANNEL_40;
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel);
+-
+-	chanspec_set = pi->pi_fptr.chanset;
+-	if (chanspec_set)
+-		(*chanspec_set) (pi, chanspec);
+-
+-}
+-
+-int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq)
+-{
+-	int range = -1;
+-
+-	if (freq < 2500)
+-		range = WL_CHAN_FREQ_RANGE_2G;
+-	else if (freq <= 5320)
+-		range = WL_CHAN_FREQ_RANGE_5GL;
+-	else if (freq <= 5700)
+-		range = WL_CHAN_FREQ_RANGE_5GM;
+-	else
+-		range = WL_CHAN_FREQ_RANGE_5GH;
+-
+-	return range;
+-}
+-
+-int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	int range = -1;
+-	uint channel = CHSPEC_CHANNEL(chanspec);
+-	uint freq = wlc_phy_channel2freq(channel);
+-
+-	if (ISNPHY(pi)) {
+-		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
+-	} else if (ISLCNPHY(pi)) {
+-		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
+-	}
+-
+-	return range;
+-}
+-
+-void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->channel_14_wide_filter = wide_filter;
+-
+-}
+-
+-int wlc_phy_channel2freq(uint channel)
+-{
+-	uint i;
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++)
+-		if (chan_info_all[i].chan == channel)
+-			return chan_info_all[i].freq;
+-	return 0;
+-}
+-
+-void
+-wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-	uint channel;
+-
+-	memset(channels, 0, sizeof(chanvec_t));
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-		channel = chan_info_all[i].chan;
+-
+-		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+-		    && (channel <= LAST_REF5_CHANNUM))
+-			continue;
+-
+-		if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+-		    ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+-			setbit(channels->vec, channel);
+-	}
+-}
+-
+-chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-	uint channel;
+-	chanspec_t chspec;
+-
+-	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-		channel = chan_info_all[i].chan;
+-
+-		if (ISNPHY(pi) && IS40MHZ(pi)) {
+-			uint j;
+-
+-			for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) {
+-				if (chan_info_all[j].chan ==
+-				    channel + CH_10MHZ_APART)
+-					break;
+-			}
+-
+-			if (j == ARRAY_SIZE(chan_info_all))
+-				continue;
+-
+-			channel = UPPER_20_SB(channel);
+-			chspec =
+-			    channel | WL_CHANSPEC_BW_40 |
+-			    WL_CHANSPEC_CTL_SB_LOWER;
+-			if (band == WLC_BAND_2G)
+-				chspec |= WL_CHANSPEC_BAND_2G;
+-			else
+-				chspec |= WL_CHANSPEC_BAND_5G;
+-		} else
+-			chspec = CH20MHZ_CHSPEC(channel);
+-
+-		if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM)
+-		    && (channel <= LAST_REF5_CHANNUM))
+-			continue;
+-
+-		if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) ||
+-		    ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL)))
+-			return chspec;
+-	}
+-
+-	return (chanspec_t) INVCHANSPEC;
+-}
+-
+-int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	*qdbm = pi->tx_user_target[0];
+-	if (override != NULL)
+-		*override = pi->txpwroverride;
+-	return 0;
+-}
+-
+-void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr)
+-{
+-	bool mac_enabled = false;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
+-	       &txpwr->cck[0], WLC_NUM_RATES_CCK);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM],
+-	       &txpwr->ofdm[0], WLC_NUM_RATES_OFDM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD],
+-	       &txpwr->ofdm_cdd[0], WLC_NUM_RATES_OFDM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO],
+-	       &txpwr->ofdm_40_siso[0], WLC_NUM_RATES_OFDM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD],
+-	       &txpwr->ofdm_40_cdd[0], WLC_NUM_RATES_OFDM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO],
+-	       &txpwr->mcs_20_siso[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD],
+-	       &txpwr->mcs_20_cdd[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC],
+-	       &txpwr->mcs_20_stbc[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM],
+-	       &txpwr->mcs_20_mimo[0], WLC_NUM_RATES_MCS_2_STREAM);
+-
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO],
+-	       &txpwr->mcs_40_siso[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD],
+-	       &txpwr->mcs_40_cdd[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC],
+-	       &txpwr->mcs_40_stbc[0], WLC_NUM_RATES_MCS_1_STREAM);
+-	memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
+-	       &txpwr->mcs_40_mimo[0], WLC_NUM_RATES_MCS_2_STREAM);
+-
+-	if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)
+-		mac_enabled = true;
+-
+-	if (mac_enabled)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phy_txpower_recalc_target(pi);
+-	wlc_phy_cal_txpower_recalc_sw(pi);
+-
+-	if (mac_enabled)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	int i;
+-
+-	if (qdbm > 127)
+-		return 5;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++)
+-		pi->tx_user_target[i] = (u8) qdbm;
+-
+-	pi->txpwroverride = false;
+-
+-	if (pi->sh->up) {
+-		if (!SCAN_INPROG_PHY(pi)) {
+-			bool suspend;
+-
+-			suspend =
+-			    (0 ==
+-			     (R_REG(&pi->regs->maccontrol) &
+-			      MCTL_EN_MAC));
+-
+-			if (!suspend)
+-				wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-			wlc_phy_txpower_recalc_target(pi);
+-			wlc_phy_cal_txpower_recalc_sw(pi);
+-
+-			if (!suspend)
+-				wlapi_enable_mac(pi->sh->physhim);
+-		}
+-	}
+-	return 0;
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr,
+-			  u8 *max_pwr, int txp_rate_idx)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint i;
+-
+-	*min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR;
+-
+-	if (ISNPHY(pi)) {
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_CCK;
+-		wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr,
+-						   (u8) txp_rate_idx);
+-
+-	} else if ((channel <= CH_MAX_2G_CHANNEL)) {
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_CCK;
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-	} else {
+-
+-		*max_pwr = WLC_TXPWR_MAX;
+-
+-		if (txp_rate_idx < 0)
+-			txp_rate_idx = TXP_FIRST_OFDM;
+-
+-		for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
+-			if (channel == chan_info_all[i].chan) {
+-				break;
+-			}
+-		}
+-
+-		if (pi->hwtxpwr) {
+-			*max_pwr = pi->hwtxpwr[i];
+-		} else {
+-
+-			if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+-			if ((i >= FIRST_HIGH_5G_CHAN)
+-			    && (i <= LAST_HIGH_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+-			if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN))
+-				*max_pwr =
+-				    pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+-		}
+-	}
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr,
+-				  u8 *min_txpwr)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u8 tx_pwr_max = 0;
+-	u8 tx_pwr_min = 255;
+-	u8 max_num_rate;
+-	u8 maxtxpwr, mintxpwr, rate, pactrl;
+-
+-	pactrl = 0;
+-
+-	max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES :
+-	    ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1);
+-
+-	for (rate = 0; rate < max_num_rate; rate++) {
+-
+-		wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr,
+-					  rate);
+-
+-		maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+-
+-		maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+-
+-		tx_pwr_max = max(tx_pwr_max, maxtxpwr);
+-		tx_pwr_min = min(tx_pwr_min, maxtxpwr);
+-	}
+-	*max_txpwr = tx_pwr_max;
+-	*min_txpwr = tx_pwr_min;
+-}
+-
+-void
+-wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, s32 *max_pwr,
+-				s32 *min_pwr, u32 *step_pwr)
+-{
+-	return;
+-}
+-
+-u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->tx_power_min;
+-}
+-
+-u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->tx_power_max;
+-}
+-
+-void wlc_phy_txpower_recalc_target(phy_info_t *pi)
+-{
+-	u8 maxtxpwr, mintxpwr, rate, pactrl;
+-	uint target_chan;
+-	u8 tx_pwr_target[TXP_NUM_RATES];
+-	u8 tx_pwr_max = 0;
+-	u8 tx_pwr_min = 255;
+-	u8 tx_pwr_max_rate_ind = 0;
+-	u8 max_num_rate;
+-	u8 start_rate = 0;
+-	chanspec_t chspec;
+-	u32 band = CHSPEC2WLC_BAND(pi->radio_chanspec);
+-	initfn_t txpwr_recalc_fn = NULL;
+-
+-	chspec = pi->radio_chanspec;
+-	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE)
+-		target_chan = CHSPEC_CHANNEL(chspec);
+-	else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER)
+-		target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+-	else
+-		target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+-
+-	pactrl = 0;
+-	if (ISLCNPHY(pi)) {
+-		u32 offset_mcs, i;
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			offset_mcs = pi->mcs40_po;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i - 8] =
+-				    pi->tx_srom_max_2g -
+-				    ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		} else {
+-			offset_mcs = pi->mcs20_po;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i - 8] =
+-				    pi->tx_srom_max_2g -
+-				    ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		}
+-	}
+-#if WL11N
+-	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+-			((ISLCNPHY(pi)) ?
+-			 (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1)));
+-#else
+-	max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1));
+-#endif
+-
+-	wlc_phy_upd_env_txpwr_rate_limits(pi, band);
+-
+-	for (rate = start_rate; rate < max_num_rate; rate++) {
+-
+-		tx_pwr_target[rate] = pi->tx_user_target[rate];
+-
+-		if (pi->user_txpwr_at_rfport) {
+-			tx_pwr_target[rate] +=
+-			    wlc_user_txpwr_antport_to_rfport(pi, target_chan,
+-							     band, rate);
+-		}
+-
+-		{
+-
+-			wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan,
+-						  &mintxpwr, &maxtxpwr, rate);
+-
+-			maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]);
+-
+-			maxtxpwr =
+-			    (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0;
+-
+-			maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0;
+-
+-			maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]);
+-
+-			if (pi->txpwr_percent <= 100)
+-				maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100;
+-
+-			tx_pwr_target[rate] = max(maxtxpwr, mintxpwr);
+-		}
+-
+-		tx_pwr_target[rate] =
+-		    min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]);
+-
+-		if (tx_pwr_target[rate] > tx_pwr_max)
+-			tx_pwr_max_rate_ind = rate;
+-
+-		tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]);
+-		tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]);
+-	}
+-
+-	memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset));
+-	pi->tx_power_max = tx_pwr_max;
+-	pi->tx_power_min = tx_pwr_min;
+-	pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind;
+-	for (rate = 0; rate < max_num_rate; rate++) {
+-
+-		pi->tx_power_target[rate] = tx_pwr_target[rate];
+-
+-		if (!pi->hwpwrctrl || ISNPHY(pi)) {
+-			pi->tx_power_offset[rate] =
+-			    pi->tx_power_max - pi->tx_power_target[rate];
+-		} else {
+-			pi->tx_power_offset[rate] =
+-			    pi->tx_power_target[rate] - pi->tx_power_min;
+-		}
+-	}
+-
+-	txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc;
+-	if (txpwr_recalc_fn)
+-		(*txpwr_recalc_fn) (pi);
+-}
+-
+-void
+-wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr,
+-			       chanspec_t chanspec)
+-{
+-	u8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM];
+-	u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL;
+-	int rate_start_index = 0, rate1, rate2, k;
+-
+-	for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0;
+-	     rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++)
+-		pi->txpwr_limit[rate1] = txpwr->cck[rate2];
+-
+-	for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0;
+-	     rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++)
+-		pi->txpwr_limit[rate1] = txpwr->ofdm[rate2];
+-
+-	if (ISNPHY(pi)) {
+-
+-		for (k = 0; k < 4; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				txpwr_ptr1 = txpwr->mcs_20_siso;
+-				txpwr_ptr2 = txpwr->ofdm;
+-				rate_start_index = WL_TX_POWER_OFDM_FIRST;
+-				break;
+-			case 1:
+-
+-				txpwr_ptr1 = txpwr->mcs_20_cdd;
+-				txpwr_ptr2 = txpwr->ofdm_cdd;
+-				rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST;
+-				break;
+-			case 2:
+-
+-				txpwr_ptr1 = txpwr->mcs_40_siso;
+-				txpwr_ptr2 = txpwr->ofdm_40_siso;
+-				rate_start_index =
+-				    WL_TX_POWER_OFDM40_SISO_FIRST;
+-				break;
+-			case 3:
+-
+-				txpwr_ptr1 = txpwr->mcs_40_cdd;
+-				txpwr_ptr2 = txpwr->ofdm_40_cdd;
+-				rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST;
+-				break;
+-			}
+-
+-			for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+-				tmp_txpwr_limit[rate2] = 0;
+-				tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+-				    txpwr_ptr1[rate2];
+-			}
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0,
+-							WLC_NUM_RATES_OFDM - 1,
+-							WLC_NUM_RATES_OFDM);
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++)
+-				pi->txpwr_limit[rate1] =
+-				    min(txpwr_ptr2[rate2],
+-					tmp_txpwr_limit[rate2]);
+-		}
+-
+-		for (k = 0; k < 4; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				txpwr_ptr1 = txpwr->ofdm;
+-				txpwr_ptr2 = txpwr->mcs_20_siso;
+-				rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST;
+-				break;
+-			case 1:
+-
+-				txpwr_ptr1 = txpwr->ofdm_cdd;
+-				txpwr_ptr2 = txpwr->mcs_20_cdd;
+-				rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST;
+-				break;
+-			case 2:
+-
+-				txpwr_ptr1 = txpwr->ofdm_40_siso;
+-				txpwr_ptr2 = txpwr->mcs_40_siso;
+-				rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST;
+-				break;
+-			case 3:
+-
+-				txpwr_ptr1 = txpwr->ofdm_40_cdd;
+-				txpwr_ptr2 = txpwr->mcs_40_cdd;
+-				rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST;
+-				break;
+-			}
+-			for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) {
+-				tmp_txpwr_limit[rate2] = 0;
+-				tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] =
+-				    txpwr_ptr1[rate2];
+-			}
+-			wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0,
+-							WLC_NUM_RATES_OFDM - 1,
+-							WLC_NUM_RATES_OFDM);
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] =
+-				    min(txpwr_ptr2[rate2],
+-					tmp_txpwr_limit[rate2]);
+-		}
+-
+-		for (k = 0; k < 2; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_20_stbc;
+-				break;
+-			case 1:
+-
+-				rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_40_stbc;
+-				break;
+-			}
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_1_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+-		}
+-
+-		for (k = 0; k < 2; k++) {
+-			switch (k) {
+-			case 0:
+-
+-				rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_20_mimo;
+-				break;
+-			case 1:
+-
+-				rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST;
+-				txpwr_ptr1 = txpwr->mcs_40_mimo;
+-				break;
+-			}
+-			for (rate1 = rate_start_index, rate2 = 0;
+-			     rate2 < WLC_NUM_RATES_MCS_2_STREAM;
+-			     rate1++, rate2++)
+-				pi->txpwr_limit[rate1] = txpwr_ptr1[rate2];
+-		}
+-
+-		pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32;
+-
+-		pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] =
+-		    min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST],
+-			pi->txpwr_limit[WL_TX_POWER_MCS_32]);
+-		pi->txpwr_limit[WL_TX_POWER_MCS_32] =
+-		    pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST];
+-	}
+-}
+-
+-void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->txpwr_percent = txpwr_percent;
+-}
+-
+-void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->sh->machwcap = machwcap;
+-}
+-
+-void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 rxc;
+-	rxc = 0;
+-
+-	if (start_end == ON) {
+-		if (!ISNPHY(pi))
+-			return;
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)
+-		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			W_REG(&pi->regs->phyregaddr, 0xa0);
+-			(void)R_REG(&pi->regs->phyregaddr);
+-			rxc = R_REG(&pi->regs->phyregdata);
+-			W_REG(&pi->regs->phyregdata,
+-			      (0x1 << 15) | rxc);
+-		}
+-	} else {
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)
+-		    || NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			W_REG(&pi->regs->phyregaddr, 0xa0);
+-			(void)R_REG(&pi->regs->phyregaddr);
+-			W_REG(&pi->regs->phyregdata, rxc);
+-		}
+-
+-		wlc_phy_por_inform(ppi);
+-	}
+-}
+-
+-void
+-wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr,
+-			  chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
+-
+-	if (ISLCNPHY(pi)) {
+-		int i, j;
+-		for (i = TXP_FIRST_OFDM_20_CDD, j = 0;
+-		     j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) {
+-			if (txpwr->mcs_20_siso[j])
+-				pi->txpwr_limit[i] = txpwr->mcs_20_siso[j];
+-			else
+-				pi->txpwr_limit[i] = txpwr->ofdm[j];
+-		}
+-	}
+-
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phy_txpower_recalc_target(pi);
+-	wlc_phy_cal_txpower_recalc_sw(pi);
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->ofdm_rateset_war = war;
+-}
+-
+-void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->bf_preempt_4306 = bf_preempt;
+-}
+-
+-void wlc_phy_txpower_update_shm(phy_info_t *pi)
+-{
+-	int j;
+-	if (ISNPHY(pi)) {
+-		return;
+-	}
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	if (pi->hwpwrctrl) {
+-		u16 offset;
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N,
+-				     1 << NUM_TSSI_FRAMES);
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET,
+-				     pi->tx_power_min << NUM_TSSI_FRAMES);
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR,
+-				     pi->hwpwr_txcur);
+-
+-		for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
+-			const u8 ucode_ofdm_rates[] = {
+-				0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
+-			};
+-			offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim,
+-							    ucode_ofdm_rates[j -
+-									     TXP_FIRST_OFDM]);
+-			wlapi_bmac_write_shm(pi->sh->physhim, offset + 6,
+-					     pi->tx_power_offset[j]);
+-			wlapi_bmac_write_shm(pi->sh->physhim, offset + 14,
+-					     -(pi->tx_power_offset[j] / 2));
+-		}
+-
+-		wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL,
+-			       MHF2_HWPWRCTL, WLC_BAND_ALL);
+-	} else {
+-		int i;
+-
+-		for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++)
+-			pi->tx_power_offset[i] =
+-			    (u8) roundup(pi->tx_power_offset[i], 8);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET,
+-				     (u16) ((pi->
+-						tx_power_offset[TXP_FIRST_OFDM]
+-						+ 7) >> 3));
+-	}
+-}
+-
+-bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	if (ISNPHY(pi)) {
+-		return pi->nphy_txpwrctrl;
+-	} else {
+-		return pi->hwpwrctrl;
+-	}
+-}
+-
+-void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool cur_hwpwrctrl = pi->hwpwrctrl;
+-	bool suspend;
+-
+-	if (!pi->hwpwrctrl_capable) {
+-		return;
+-	}
+-
+-	pi->hwpwrctrl = hwpwrctrl;
+-	pi->nphy_txpwrctrl = hwpwrctrl;
+-	pi->txpwrctrl = hwpwrctrl;
+-
+-	if (ISNPHY(pi)) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-		wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+-		if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-			wlc_phy_txpwr_fixpower_nphy(pi);
+-		} else {
+-
+-			mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-				    pi->saved_txpwr_idx);
+-		}
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	} else if (hwpwrctrl != cur_hwpwrctrl) {
+-
+-		return;
+-	}
+-}
+-
+-void wlc_phy_txpower_ipa_upd(phy_info_t *pi)
+-{
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2);
+-		pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2);
+-	} else {
+-		pi->ipa2g_on = false;
+-		pi->ipa5g_on = false;
+-	}
+-}
+-
+-static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi);
+-
+-static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi)
+-{
+-	s16 tx0_status, tx1_status;
+-	u16 estPower1, estPower2;
+-	u8 pwr0, pwr1, adj_pwr0, adj_pwr1;
+-	u32 est_pwr;
+-
+-	estPower1 = read_phy_reg(pi, 0x118);
+-	estPower2 = read_phy_reg(pi, 0x119);
+-
+-	if ((estPower1 & (0x1 << 8))
+-	    == (0x1 << 8)) {
+-		pwr0 = (u8) (estPower1 & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		pwr0 = 0x80;
+-	}
+-
+-	if ((estPower2 & (0x1 << 8))
+-	    == (0x1 << 8)) {
+-		pwr1 = (u8) (estPower2 & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		pwr1 = 0x80;
+-	}
+-
+-	tx0_status = read_phy_reg(pi, 0x1ed);
+-	tx1_status = read_phy_reg(pi, 0x1ee);
+-
+-	if ((tx0_status & (0x1 << 15))
+-	    == (0x1 << 15)) {
+-		adj_pwr0 = (u8) (tx0_status & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		adj_pwr0 = 0x80;
+-	}
+-	if ((tx1_status & (0x1 << 15))
+-	    == (0x1 << 15)) {
+-		adj_pwr1 = (u8) (tx1_status & (0xff << 0))
+-		    >> 0;
+-	} else {
+-		adj_pwr1 = 0x80;
+-	}
+-
+-	est_pwr =
+-	    (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1);
+-	return est_pwr;
+-}
+-
+-void
+-wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	uint rate, num_rates;
+-	u8 min_pwr, max_pwr;
+-
+-#if WL_TX_POWER_RATES != TXP_NUM_RATES
+-#error "tx_power_t struct out of sync with this fn"
+-#endif
+-
+-	if (ISNPHY(pi)) {
+-		power->rf_cores = 2;
+-		power->flags |= (WL_TX_POWER_F_MIMO);
+-		if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+-			power->flags |=
+-			    (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW);
+-	} else if (ISLCNPHY(pi)) {
+-		power->rf_cores = 1;
+-		power->flags |= (WL_TX_POWER_F_SISO);
+-		if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF)
+-			power->flags |= WL_TX_POWER_F_ENABLED;
+-		if (pi->hwpwrctrl)
+-			power->flags |= WL_TX_POWER_F_HW;
+-	}
+-
+-	num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) :
+-		     ((ISLCNPHY(pi)) ?
+-		      (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1)));
+-
+-	for (rate = 0; rate < num_rates; rate++) {
+-		power->user_limit[rate] = pi->tx_user_target[rate];
+-		wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr,
+-					  rate);
+-		power->board_limit[rate] = (u8) max_pwr;
+-		power->target[rate] = pi->tx_power_target[rate];
+-	}
+-
+-	if (ISNPHY(pi)) {
+-		u32 est_pout;
+-
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_phyreg_enter((wlc_phy_t *) pi);
+-		est_pout = wlc_phy_txpower_est_power_nphy(pi);
+-		wlc_phyreg_exit((wlc_phy_t *) pi);
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-		power->est_Pout[0] = (est_pout >> 8) & 0xff;
+-		power->est_Pout[1] = est_pout & 0xff;
+-
+-		power->est_Pout_act[0] = est_pout >> 24;
+-		power->est_Pout_act[1] = (est_pout >> 16) & 0xff;
+-
+-		if (power->est_Pout[0] == 0x80)
+-			power->est_Pout[0] = 0;
+-		if (power->est_Pout[1] == 0x80)
+-			power->est_Pout[1] = 0;
+-
+-		if (power->est_Pout_act[0] == 0x80)
+-			power->est_Pout_act[0] = 0;
+-		if (power->est_Pout_act[1] == 0x80)
+-			power->est_Pout_act[1] = 0;
+-
+-		power->est_Pout_cck = 0;
+-
+-		power->tx_power_max[0] = pi->tx_power_max;
+-		power->tx_power_max[1] = pi->tx_power_max;
+-
+-		power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind;
+-		power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind;
+-	} else if (!pi->hwpwrctrl) {
+-	} else if (pi->sh->up) {
+-
+-		wlc_phyreg_enter(ppi);
+-		if (ISLCNPHY(pi)) {
+-
+-			power->tx_power_max[0] = pi->tx_power_max;
+-			power->tx_power_max[1] = pi->tx_power_max;
+-
+-			power->tx_power_max_rate_ind[0] =
+-			    pi->tx_power_max_rate_ind;
+-			power->tx_power_max_rate_ind[1] =
+-			    pi->tx_power_max_rate_ind;
+-
+-			if (wlc_phy_tpc_isenabled_lcnphy(pi))
+-				power->flags |=
+-				    (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+-			else
+-				power->flags &=
+-				    ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED);
+-
+-			wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0],
+-					    (s8 *) &power->est_Pout_cck);
+-		}
+-		wlc_phyreg_exit(ppi);
+-	}
+-}
+-
+-void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	pi->antsel_type = antsel_type;
+-}
+-
+-bool wlc_phy_test_ison(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	return pi->phytest_on;
+-}
+-
+-bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool ret = true;
+-
+-	wlc_phyreg_enter(ppi);
+-
+-	if (ISNPHY(pi)) {
+-
+-		ret = false;
+-	} else if (ISLCNPHY(pi)) {
+-		u16 crsctrl = read_phy_reg(pi, 0x410);
+-		u16 div = crsctrl & (0x1 << 1);
+-		*pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1)));
+-	}
+-
+-	wlc_phyreg_exit(ppi);
+-
+-	return ret;
+-}
+-
+-void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	bool suspend;
+-
+-	pi->sh->rx_antdiv = val;
+-
+-	if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) {
+-		if (val > ANT_RX_DIV_FORCE_1)
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV,
+-				       MHF1_ANTDIV, WLC_BAND_ALL);
+-		else
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0,
+-				       WLC_BAND_ALL);
+-	}
+-
+-	if (ISNPHY(pi)) {
+-
+-		return;
+-	}
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (ISLCNPHY(pi)) {
+-		if (val > ANT_RX_DIV_FORCE_1) {
+-			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1);
+-			mod_phy_reg(pi, 0x410,
+-				    (0x1 << 0),
+-				    ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0);
+-		} else {
+-			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
+-			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
+-		}
+-	}
+-
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-	return;
+-}
+-
+-static bool
+-wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant)
+-{
+-	s8 cmplx_pwr_dbm[PHY_CORE_MAX];
+-	u8 i;
+-
+-	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
+-	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3))
+-			cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322;
+-		else
+-
+-			cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70);
+-	}
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i];
+-		pwr_ant[i] = cmplx_pwr_dbm[i];
+-	}
+-	pi->nphy_noise_index =
+-	    MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+-	return true;
+-}
+-
+-static void
+-wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-	bool sampling_in_progress = (pi->phynoise_state != 0);
+-	bool wait_for_intr = true;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		return;
+-	}
+-
+-	switch (reason) {
+-	case PHY_NOISE_SAMPLE_MON:
+-
+-		pi->phynoise_chan_watchdog = ch;
+-		pi->phynoise_state |= PHY_NOISE_STATE_MON;
+-
+-		break;
+-
+-	case PHY_NOISE_SAMPLE_EXTERNAL:
+-
+-		pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	if (sampling_in_progress)
+-		return;
+-
+-	pi->phynoise_now = pi->sh->now;
+-
+-	if (pi->phy_fixed_noise) {
+-		if (ISNPHY(pi)) {
+-			pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] =
+-			    PHY_NOISE_FIXED_VAL_NPHY;
+-			pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] =
+-			    PHY_NOISE_FIXED_VAL_NPHY;
+-			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+-							   PHY_NOISE_WINDOW_SZ);
+-
+-			noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-		} else {
+-
+-			noise_dbm = PHY_NOISE_FIXED_VAL;
+-		}
+-
+-		wait_for_intr = false;
+-		goto done;
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		if (!pi->phynoise_polling
+-		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+-
+-			OR_REG(&pi->regs->maccommand,
+-			       MCMD_BG_NOISE);
+-		} else {
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			wlc_lcnphy_deaf_mode(pi, (bool) 0);
+-			noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20);
+-			wlc_lcnphy_deaf_mode(pi, (bool) 1);
+-			wlapi_enable_mac(pi->sh->physhim);
+-			wait_for_intr = false;
+-		}
+-	} else if (ISNPHY(pi)) {
+-		if (!pi->phynoise_polling
+-		    || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) {
+-
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
+-
+-			OR_REG(&pi->regs->maccommand,
+-			       MCMD_BG_NOISE);
+-		} else {
+-			phy_iq_est_t est[PHY_CORE_MAX];
+-			u32 cmplx_pwr[PHY_CORE_MAX];
+-			s8 noise_dbm_ant[PHY_CORE_MAX];
+-			u16 log_num_samps, num_samps, classif_state = 0;
+-			u8 wait_time = 32;
+-			u8 wait_crs = 0;
+-			u8 i;
+-
+-			memset((u8 *) est, 0, sizeof(est));
+-			memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
+-			memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
+-
+-			log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY;
+-			num_samps = 1 << log_num_samps;
+-
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-			wlc_phy_classifier_nphy(pi, 3, 0);
+-			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time,
+-					       wait_crs);
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-			wlapi_enable_mac(pi->sh->physhim);
+-
+-			for (i = 0; i < pi->pubpi.phy_corenum; i++)
+-				cmplx_pwr[i] =
+-				    (est[i].i_pwr +
+-				     est[i].q_pwr) >> log_num_samps;
+-
+-			wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+-
+-			for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-				pi->nphy_noise_win[i][pi->nphy_noise_index] =
+-				    noise_dbm_ant[i];
+-
+-				if (noise_dbm_ant[i] > noise_dbm)
+-					noise_dbm = noise_dbm_ant[i];
+-			}
+-			pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index,
+-							   PHY_NOISE_WINDOW_SZ);
+-
+-			wait_for_intr = false;
+-		}
+-	}
+-
+- done:
+-
+-	if (!wait_for_intr)
+-		wlc_phy_noise_cb(pi, ch, noise_dbm);
+-
+-}
+-
+-void wlc_phy_noise_sample_request_external(wlc_phy_t *pih)
+-{
+-	u8 channel;
+-
+-	channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih));
+-
+-	wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel);
+-}
+-
+-static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm)
+-{
+-	if (!pi->phynoise_state)
+-		return;
+-
+-	if (pi->phynoise_state & PHY_NOISE_STATE_MON) {
+-		if (pi->phynoise_chan_watchdog == channel) {
+-			pi->sh->phy_noise_window[pi->sh->phy_noise_index] =
+-			    noise_dbm;
+-			pi->sh->phy_noise_index =
+-			    MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ);
+-		}
+-		pi->phynoise_state &= ~PHY_NOISE_STATE_MON;
+-	}
+-
+-	if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) {
+-		pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL;
+-	}
+-
+-}
+-
+-static s8 wlc_phy_noise_read_shmem(phy_info_t *pi)
+-{
+-	u32 cmplx_pwr[PHY_CORE_MAX];
+-	s8 noise_dbm_ant[PHY_CORE_MAX];
+-	u16 lo, hi;
+-	u32 cmplx_pwr_tot = 0;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-	u8 idx, core;
+-
+-	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
+-	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
+-
+-	for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) {
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx));
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim,
+-					 M_PWRIND_MAP(idx + 1));
+-		cmplx_pwr[core] = (hi << 16) + lo;
+-		cmplx_pwr_tot += cmplx_pwr[core];
+-		if (cmplx_pwr[core] == 0) {
+-			noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY;
+-		} else
+-			cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE;
+-	}
+-
+-	if (cmplx_pwr_tot != 0)
+-		wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant);
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		pi->nphy_noise_win[core][pi->nphy_noise_index] =
+-		    noise_dbm_ant[core];
+-
+-		if (noise_dbm_ant[core] > noise_dbm)
+-			noise_dbm = noise_dbm_ant[core];
+-	}
+-	pi->nphy_noise_index =
+-	    MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ);
+-
+-	return noise_dbm;
+-
+-}
+-
+-void wlc_phy_noise_sample_intr(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u16 jssi_aux;
+-	u8 channel = 0;
+-	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
+-
+-	if (ISLCNPHY(pi)) {
+-		u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1;
+-		u16 lo, hi;
+-		s32 pwr_offset_dB, gain_dB;
+-		u16 status_0, status_1;
+-
+-		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+-		channel = jssi_aux & D11_CURCHANNEL_MAX;
+-
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0);
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1);
+-		cmplx_pwr0 = (hi << 16) + lo;
+-
+-		lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2);
+-		hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3);
+-		cmplx_pwr1 = (hi << 16) + lo;
+-		cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6;
+-
+-		status_0 = 0x44;
+-		status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0);
+-		if ((cmplx_pwr > 0 && cmplx_pwr < 500)
+-		    && ((status_1 & 0xc000) == 0x4000)) {
+-
+-			wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm,
+-					   pi->pubpi.phy_corenum);
+-			pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF);
+-			if (pwr_offset_dB > 127)
+-				pwr_offset_dB -= 256;
+-
+-			noise_dbm += (s8) (pwr_offset_dB - 30);
+-
+-			gain_dB = (status_0 & 0x1ff);
+-			noise_dbm -= (s8) (gain_dB);
+-		} else {
+-			noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY;
+-		}
+-	} else if (ISNPHY(pi)) {
+-
+-		jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX);
+-		channel = jssi_aux & D11_CURCHANNEL_MAX;
+-
+-		noise_dbm = wlc_phy_noise_read_shmem(pi);
+-	}
+-
+-	wlc_phy_noise_cb(pi, channel, noise_dbm);
+-
+-}
+-
+-s8 lcnphy_gain_index_offset_for_pkt_rssi[] = {
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	8,
+-	9,
+-	10,
+-	8,
+-	8,
+-	7,
+-	7,
+-	1,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	1,
+-	1,
+-	0,
+-	0,
+-	0,
+-	0
+-};
+-
+-void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
+-{
+-	u8 msb, secondmsb, i;
+-	u32 tmp;
+-
+-	for (i = 0; i < core; i++) {
+-		secondmsb = 0;
+-		tmp = cmplx_pwr[i];
+-		msb = fls(tmp);
+-		if (msb)
+-			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
+-		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
+-	}
+-}
+-
+-void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx)
+-{
+-	wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx;
+-	d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr;
+-	int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK;
+-	uint radioid = pih->radioid;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		rssi = WLC_RSSI_INVALID;
+-		goto end;
+-	}
+-
+-	if ((pi->sh->corerev >= 11)
+-	    && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) {
+-		rssi = WLC_RSSI_INVALID;
+-		goto end;
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		u8 gidx = (le16_to_cpu(rxh->PhyRxStatus_2) & 0xFC00) >> 10;
+-		phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-		if (rssi > 127)
+-			rssi -= 256;
+-
+-		rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx];
+-		if ((rssi > -46) && (gidx > 18))
+-			rssi = rssi + 7;
+-
+-		rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope;
+-
+-		rssi = rssi + 2;
+-
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-
+-		if (rssi > 127)
+-			rssi -= 256;
+-	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
+-		   || radioid == BCM2057_ID) {
+-		rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr);
+-	}
+-
+- end:
+-	wlc_rxhdr->rssi = (s8) rssi;
+-}
+-
+-void wlc_phy_freqtrack_start(wlc_phy_t *pih)
+-{
+-	return;
+-}
+-
+-void wlc_phy_freqtrack_end(wlc_phy_t *pih)
+-{
+-	return;
+-}
+-
+-void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag)
+-{
+-	phy_info_t *pi;
+-	pi = (phy_info_t *) ppi;
+-
+-	if (ISLCNPHY(pi))
+-		wlc_lcnphy_deaf_mode(pi, true);
+-	else if (ISNPHY(pi))
+-		wlc_nphy_deaf_mode(pi, true);
+-}
+-
+-void wlc_phy_watchdog(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	bool delay_phy_cal = false;
+-	pi->sh->now++;
+-
+-	if (!pi->watchdog_override)
+-		return;
+-
+-	if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) {
+-		wlc_phy_noise_sample_request((wlc_phy_t *) pi,
+-					     PHY_NOISE_SAMPLE_MON,
+-					     CHSPEC_CHANNEL(pi->
+-							    radio_chanspec));
+-	}
+-
+-	if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) {
+-		pi->phynoise_state = 0;
+-	}
+-
+-	if ((!pi->phycal_txpower) ||
+-	    ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) {
+-
+-		if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) {
+-			pi->phycal_txpower = pi->sh->now;
+-		}
+-	}
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+-	     || ASSOC_INPROG_PHY(pi)))
+-		return;
+-
+-	if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) {
+-
+-		if ((pi->nphy_perical != PHY_PERICAL_DISABLE) &&
+-		    (pi->nphy_perical != PHY_PERICAL_MANUAL) &&
+-		    ((pi->sh->now - pi->nphy_perical_last) >=
+-		     pi->sh->glacial_timer))
+-			wlc_phy_cal_perical((wlc_phy_t *) pi,
+-					    PHY_PERICAL_WATCHDOG);
+-
+-		wlc_phy_txpwr_papd_cal_nphy(pi);
+-	}
+-
+-	if (ISLCNPHY(pi)) {
+-		if (pi->phy_forcecal ||
+-		    ((pi->sh->now - pi->phy_lastcal) >=
+-		     pi->sh->glacial_timer)) {
+-			if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi)))
+-				wlc_lcnphy_calib_modes(pi,
+-						       LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+-			if (!
+-			    (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)
+-			     || ASSOC_INPROG_PHY(pi)
+-			     || pi->carrier_suppr_disable
+-			     || pi->disable_percal))
+-				wlc_lcnphy_calib_modes(pi,
+-						       PHY_PERICAL_WATCHDOG);
+-		}
+-	}
+-}
+-
+-void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	uint i;
+-	uint k;
+-
+-	for (i = 0; i < MA_WINDOW_SZ; i++) {
+-		pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff);
+-	}
+-	if (ISLCNPHY(pi)) {
+-		for (i = 0; i < MA_WINDOW_SZ; i++)
+-			pi->sh->phy_noise_window[i] =
+-			    PHY_NOISE_FIXED_VAL_LCNPHY;
+-	}
+-	pi->sh->phy_noise_index = 0;
+-
+-	for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) {
+-		for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++)
+-			pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY;
+-	}
+-	pi->nphy_noise_index = 0;
+-}
+-
+-void
+-wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag)
+-{
+-	*eps_imag = (epsilon >> 13);
+-	if (*eps_imag > 0xfff)
+-		*eps_imag -= 0x2000;
+-
+-	*eps_real = (epsilon & 0x1fff);
+-	if (*eps_real > 0xfff)
+-		*eps_real -= 0x2000;
+-}
+-
+-static const fixed AtanTbl[] = {
+-	2949120,
+-	1740967,
+-	919879,
+-	466945,
+-	234379,
+-	117304,
+-	58666,
+-	29335,
+-	14668,
+-	7334,
+-	3667,
+-	1833,
+-	917,
+-	458,
+-	229,
+-	115,
+-	57,
+-	29
+-};
+-
+-void wlc_phy_cordic(fixed theta, cs32 *val)
+-{
+-	fixed angle, valtmp;
+-	unsigned iter;
+-	int signx = 1;
+-	int signtheta;
+-
+-	val[0].i = CORDIC_AG;
+-	val[0].q = 0;
+-	angle = 0;
+-
+-	signtheta = (theta < 0) ? -1 : 1;
+-	theta =
+-	    ((theta + FIXED(180) * signtheta) % FIXED(360)) -
+-	    FIXED(180) * signtheta;
+-
+-	if (FLOAT(theta) > 90) {
+-		theta -= FIXED(180);
+-		signx = -1;
+-	} else if (FLOAT(theta) < -90) {
+-		theta += FIXED(180);
+-		signx = -1;
+-	}
+-
+-	for (iter = 0; iter < CORDIC_NI; iter++) {
+-		if (theta > angle) {
+-			valtmp = val[0].i - (val[0].q >> iter);
+-			val[0].q = (val[0].i >> iter) + val[0].q;
+-			val[0].i = valtmp;
+-			angle += AtanTbl[iter];
+-		} else {
+-			valtmp = val[0].i + (val[0].q >> iter);
+-			val[0].q = -(val[0].i >> iter) + val[0].q;
+-			val[0].i = valtmp;
+-			angle -= AtanTbl[iter];
+-		}
+-	}
+-
+-	val[0].i = val[0].i * signx;
+-	val[0].q = val[0].q * signx;
+-}
+-
+-void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi)
+-{
+-	wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+-
+-	pi->cal_type_override = PHY_PERICAL_AUTO;
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+-	pi->mphase_txcal_cmdidx = 0;
+-}
+-
+-static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay)
+-{
+-
+-	if ((pi->nphy_perical != PHY_PERICAL_MPHASE) &&
+-	    (pi->nphy_perical != PHY_PERICAL_MANUAL))
+-		return;
+-
+-	wlapi_del_timer(pi->sh->physhim, pi->phycal_timer);
+-
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+-	wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0);
+-}
+-
+-void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason)
+-{
+-	s16 nphy_currtemp = 0;
+-	s16 delta_temp = 0;
+-	bool do_periodic_cal = true;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	if (!ISNPHY(pi))
+-		return;
+-
+-	if ((pi->nphy_perical == PHY_PERICAL_DISABLE) ||
+-	    (pi->nphy_perical == PHY_PERICAL_MANUAL))
+-		return;
+-
+-	switch (reason) {
+-	case PHY_PERICAL_DRIVERUP:
+-		break;
+-
+-	case PHY_PERICAL_PHYINIT:
+-		if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+-			if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-			}
+-			wlc_phy_cal_perical_mphase_schedule(pi,
+-							    PHY_PERICAL_INIT_DELAY);
+-		}
+-		break;
+-
+-	case PHY_PERICAL_JOIN_BSS:
+-	case PHY_PERICAL_START_IBSS:
+-	case PHY_PERICAL_UP_BSS:
+-		if ((pi->nphy_perical == PHY_PERICAL_MPHASE) &&
+-		    PHY_PERICAL_MPHASE_PENDING(pi)) {
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-		}
+-
+-		pi->first_cal_after_assoc = true;
+-
+-		pi->cal_type_override = PHY_PERICAL_FULL;
+-
+-		if (pi->phycal_tempdelta) {
+-			pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi);
+-		}
+-		wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL);
+-		break;
+-
+-	case PHY_PERICAL_WATCHDOG:
+-		if (pi->phycal_tempdelta) {
+-			nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+-			delta_temp =
+-			    (nphy_currtemp > pi->nphy_lastcal_temp) ?
+-			    nphy_currtemp - pi->nphy_lastcal_temp :
+-			    pi->nphy_lastcal_temp - nphy_currtemp;
+-
+-			if ((delta_temp < (s16) pi->phycal_tempdelta) &&
+-			    (pi->nphy_txiqlocal_chanspec ==
+-			     pi->radio_chanspec)) {
+-				do_periodic_cal = false;
+-			} else {
+-				pi->nphy_lastcal_temp = nphy_currtemp;
+-			}
+-		}
+-
+-		if (do_periodic_cal) {
+-
+-			if (pi->nphy_perical == PHY_PERICAL_MPHASE) {
+-
+-				if (!PHY_PERICAL_MPHASE_PENDING(pi))
+-					wlc_phy_cal_perical_mphase_schedule(pi,
+-									    PHY_PERICAL_WDOG_DELAY);
+-			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
+-				wlc_phy_cal_perical_nphy_run(pi,
+-							     PHY_PERICAL_AUTO);
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi)
+-{
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT;
+-	pi->mphase_txcal_cmdidx = 0;
+-}
+-
+-u8 wlc_phy_nbits(s32 value)
+-{
+-	s32 abs_val;
+-	u8 nbits = 0;
+-
+-	abs_val = ABS(value);
+-	while ((abs_val >> nbits) > 0)
+-		nbits++;
+-
+-	return nbits;
+-}
+-
+-void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->sh->hw_phytxchain = txchain;
+-	pi->sh->hw_phyrxchain = rxchain;
+-	pi->sh->phytxchain = txchain;
+-	pi->sh->phyrxchain = rxchain;
+-	pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
+-}
+-
+-void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	pi->sh->phytxchain = txchain;
+-
+-	if (ISNPHY(pi)) {
+-		wlc_phy_rxcore_setstate_nphy(pih, rxchain);
+-	}
+-	pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain);
+-}
+-
+-void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, u8 *rxchain)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	*txchain = pi->sh->phytxchain;
+-	*rxchain = pi->sh->phyrxchain;
+-}
+-
+-u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih)
+-{
+-	s16 nphy_currtemp;
+-	u8 active_bitmap;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
+-
+-	if (!pi->watchdog_override)
+-		return active_bitmap;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		nphy_currtemp = wlc_phy_tempsense_nphy(pi);
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-		if (!pi->phy_txcore_heatedup) {
+-			if (nphy_currtemp >= pi->phy_txcore_disable_temp) {
+-				active_bitmap &= 0xFD;
+-				pi->phy_txcore_heatedup = true;
+-			}
+-		} else {
+-			if (nphy_currtemp <= pi->phy_txcore_enable_temp) {
+-				active_bitmap |= 0x2;
+-				pi->phy_txcore_heatedup = false;
+-			}
+-		}
+-	}
+-
+-	return active_bitmap;
+-}
+-
+-s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u8 siso_mcs_id, cdd_mcs_id;
+-
+-	siso_mcs_id =
+-	    (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO :
+-	    TXP_FIRST_MCS_20_SISO;
+-	cdd_mcs_id =
+-	    (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD :
+-	    TXP_FIRST_MCS_20_CDD;
+-
+-	if (pi->tx_power_target[siso_mcs_id] >
+-	    (pi->tx_power_target[cdd_mcs_id] + 12))
+-		return PHY_TXC1_MODE_SISO;
+-	else
+-		return PHY_TXC1_MODE_CDD;
+-}
+-
+-const u8 *wlc_phy_get_ofdm_rate_lookup(void)
+-{
+-	return ofdm_rate_lookup;
+-}
+-
+-void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode)
+-{
+-	if ((pi->sh->chip == BCM4313_CHIP_ID) &&
+-	    (pi->sh->boardflags & BFL_FEM)) {
+-		if (mode) {
+-			u16 txant = 0;
+-			txant = wlapi_bmac_get_txant(pi->sh->physhim);
+-			if (txant == 1) {
+-				mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+-
+-				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
+-
+-			}
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
+-				   0x0);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioout), 0x40, 0x40);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioouten), 0x40,
+-				   0x40);
+-		} else {
+-			mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
+-
+-			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
+-
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioout), 0x40, 0x00);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpioouten), 0x40, 0x0);
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
+-				   0x40);
+-		}
+-	}
+-}
+-
+-static s8
+-wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band,
+-				 u8 rate)
+-{
+-	s8 offset = 0;
+-
+-	if (!pi->user_txpwr_at_rfport)
+-		return offset;
+-	return offset;
+-}
+-
+-static s8 wlc_phy_env_measure_vbat(phy_info_t *pi)
+-{
+-	if (ISLCNPHY(pi))
+-		return wlc_lcnphy_vbatsense(pi, 0);
+-	else
+-		return 0;
+-}
+-
+-static s8 wlc_phy_env_measure_temperature(phy_info_t *pi)
+-{
+-	if (ISLCNPHY(pi))
+-		return wlc_lcnphy_tempsense_degree(pi, 0);
+-	else
+-		return 0;
+-}
+-
+-static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band)
+-{
+-	u8 i;
+-	s8 temp, vbat;
+-
+-	for (i = 0; i < TXP_NUM_RATES; i++)
+-		pi->txpwr_env_limit[i] = WLC_TXPWR_MAX;
+-
+-	vbat = wlc_phy_env_measure_vbat(pi);
+-	temp = wlc_phy_env_measure_temperature(pi);
+-
+-}
+-
+-void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc)
+-{
+-	return;
+-}
+-
+-void
+-wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset)
+-{
+-	*cckoffset = 0;
+-	*ofdmoffset = 0;
+-}
+-
+-s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec)
+-{
+-
+-	return rssi;
+-}
+-
+-bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	if (ISNPHY(pi))
+-		return wlc_phy_n_txpower_ipa_ison(pi);
+-	else
+-		return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
+deleted file mode 100644
+index 8939153..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
++++ /dev/null
+@@ -1,256 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_h_
+-#define _wlc_phy_h_
+-
+-#include <wlioctl.h>
+-#include <aiutils.h>
+-#include <d11.h>
+-#include <wlc_phy_shim.h>
+-#include <net/mac80211.h>	/* struct wiphy */
+-
+-#define	IDCODE_VER_MASK		0x0000000f
+-#define	IDCODE_VER_SHIFT	0
+-#define	IDCODE_MFG_MASK		0x00000fff
+-#define	IDCODE_MFG_SHIFT	0
+-#define	IDCODE_ID_MASK		0x0ffff000
+-#define	IDCODE_ID_SHIFT		12
+-#define	IDCODE_REV_MASK		0xf0000000
+-#define	IDCODE_REV_SHIFT	28
+-
+-#define	NORADIO_ID		0xe4f5
+-#define	NORADIO_IDCODE		0x4e4f5246
+-
+-#define BCM2055_ID		0x2055
+-#define BCM2055_IDCODE		0x02055000
+-#define BCM2055A0_IDCODE	0x1205517f
+-
+-#define BCM2056_ID		0x2056
+-#define BCM2056_IDCODE		0x02056000
+-#define BCM2056A0_IDCODE	0x1205617f
+-
+-#define BCM2057_ID		0x2057
+-#define BCM2057_IDCODE		0x02057000
+-#define BCM2057A0_IDCODE	0x1205717f
+-
+-#define BCM2064_ID		0x2064
+-#define BCM2064_IDCODE		0x02064000
+-#define BCM2064A0_IDCODE	0x0206417f
+-
+-#define PHY_TPC_HW_OFF		false
+-#define PHY_TPC_HW_ON		true
+-
+-#define PHY_PERICAL_DRIVERUP	1
+-#define PHY_PERICAL_WATCHDOG	2
+-#define PHY_PERICAL_PHYINIT	3
+-#define PHY_PERICAL_JOIN_BSS	4
+-#define PHY_PERICAL_START_IBSS	5
+-#define PHY_PERICAL_UP_BSS	6
+-#define PHY_PERICAL_CHAN	7
+-#define PHY_FULLCAL	8
+-
+-#define PHY_PERICAL_DISABLE	0
+-#define PHY_PERICAL_SPHASE	1
+-#define PHY_PERICAL_MPHASE	2
+-#define PHY_PERICAL_MANUAL	3
+-
+-#define PHY_HOLD_FOR_ASSOC	1
+-#define PHY_HOLD_FOR_SCAN	2
+-#define PHY_HOLD_FOR_RM		4
+-#define PHY_HOLD_FOR_PLT	8
+-#define PHY_HOLD_FOR_MUTE	16
+-#define PHY_HOLD_FOR_NOT_ASSOC 0x20
+-
+-#define PHY_MUTE_FOR_PREISM	1
+-#define PHY_MUTE_ALL		0xffffffff
+-
+-#define PHY_NOISE_FIXED_VAL 		(-95)
+-#define PHY_NOISE_FIXED_VAL_NPHY       	(-92)
+-#define PHY_NOISE_FIXED_VAL_LCNPHY     	(-92)
+-
+-#define PHY_MODE_CAL		0x0002
+-#define PHY_MODE_NOISEM		0x0004
+-
+-#define WLC_TXPWR_DB_FACTOR	4
+-
+-#define WLC_NUM_RATES_CCK           4
+-#define WLC_NUM_RATES_OFDM          8
+-#define WLC_NUM_RATES_MCS_1_STREAM  8
+-#define WLC_NUM_RATES_MCS_2_STREAM  8
+-#define WLC_NUM_RATES_MCS_3_STREAM  8
+-#define WLC_NUM_RATES_MCS_4_STREAM  8
+-typedef struct txpwr_limits {
+-	u8 cck[WLC_NUM_RATES_CCK];
+-	u8 ofdm[WLC_NUM_RATES_OFDM];
+-
+-	u8 ofdm_cdd[WLC_NUM_RATES_OFDM];
+-
+-	u8 ofdm_40_siso[WLC_NUM_RATES_OFDM];
+-	u8 ofdm_40_cdd[WLC_NUM_RATES_OFDM];
+-
+-	u8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+-
+-	u8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM];
+-	u8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM];
+-	u8 mcs32;
+-} txpwr_limits_t;
+-
+-typedef struct {
+-	u8 vec[MAXCHANNEL / NBBY];
+-} chanvec_t;
+-
+-struct rpc_info;
+-typedef struct shared_phy shared_phy_t;
+-
+-struct phy_pub;
+-
+-typedef struct phy_pub wlc_phy_t;
+-
+-typedef struct shared_phy_params {
+-	si_t *sih;
+-	void *physhim;
+-	uint unit;
+-	uint corerev;
+-	uint bustype;
+-	uint buscorerev;
+-	char *vars;
+-	u16 vid;
+-	u16 did;
+-	uint chip;
+-	uint chiprev;
+-	uint chippkg;
+-	uint sromrev;
+-	uint boardtype;
+-	uint boardrev;
+-	uint boardvendor;
+-	u32 boardflags;
+-	u32 boardflags2;
+-} shared_phy_params_t;
+-
+-
+-extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp);
+-extern void wlc_phy_shared_detach(shared_phy_t *phy_sh);
+-extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+-				 char *vars, struct wiphy *wiphy);
+-extern void wlc_phy_detach(wlc_phy_t *ppi);
+-
+-extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype,
+-				   u16 *phyrev, u16 *radioid,
+-				   u16 *radiover);
+-extern bool wlc_phy_get_encore(wlc_phy_t *pih);
+-extern u32 wlc_phy_get_coreflags(wlc_phy_t *pih);
+-
+-extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate);
+-extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate);
+-extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec);
+-extern void wlc_phy_watchdog(wlc_phy_t *ppi);
+-extern int wlc_phy_down(wlc_phy_t *ppi);
+-extern u32 wlc_phy_clk_bwbits(wlc_phy_t *pih);
+-extern void wlc_phy_cal_init(wlc_phy_t *ppi);
+-extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init);
+-
+-extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec);
+-extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi);
+-extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch);
+-extern u16 wlc_phy_bw_state_get(wlc_phy_t *ppi);
+-extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw);
+-
+-extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx);
+-extern void wlc_phy_por_inform(wlc_phy_t *ppi);
+-extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi);
+-extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi);
+-
+-extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag);
+-
+-extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on);
+-extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on);
+-
+-
+-extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi);
+-
+-extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi,
+-						 bool wide_filter);
+-extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band,
+-					  chanvec_t *channels);
+-extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band);
+-
+-extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan,
+-				      u8 *_min_, u8 *_max_, int rate);
+-extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan,
+-					      u8 *_max_, u8 *_min_);
+-extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, s32 *,
+-					    s32 *, u32 *);
+-extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *,
+-				      chanspec_t chanspec);
+-extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override);
+-extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override);
+-extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *);
+-extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi);
+-extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl);
+-extern u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi);
+-extern u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi);
+-extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih);
+-
+-extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain,
+-				   u8 rxchain);
+-extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain,
+-				  u8 rxchain);
+-extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain,
+-				  u8 *rxchain);
+-extern u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih);
+-extern s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec);
+-extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val);
+-
+-extern void wlc_phy_cal_perical(wlc_phy_t *ppi, u8 reason);
+-extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi);
+-extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock);
+-extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi);
+-
+-extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val);
+-extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval);
+-extern void wlc_phy_clear_tssi(wlc_phy_t *ppi);
+-extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val);
+-extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags);
+-
+-extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type);
+-
+-extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power,
+-					uint channel);
+-
+-extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal);
+-extern bool wlc_phy_test_ison(wlc_phy_t *ppi);
+-extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent);
+-extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war);
+-extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt);
+-extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap);
+-
+-extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end);
+-
+-extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi);
+-extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi);
+-
+-extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
+-
+-extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi,
+-					       u8 mcs_offset);
+-extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset);
+-#endif				/* _wlc_phy_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
+deleted file mode 100644
+index 10cbf52..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
++++ /dev/null
+@@ -1,1226 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_int_h_
+-#define _wlc_phy_int_h_
+-
+-#include <linux/kernel.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-
+-#include <bcmsrom_fmt.h>
+-#include <wlc_phy_hal.h>
+-
+-#define PHYHAL_ERROR	0x0001
+-#define PHYHAL_TRACE	0x0002
+-#define PHYHAL_INFORM	0x0004
+-
+-extern u32 phyhal_msg_level;
+-
+-#define PHY_INFORM_ON()		(phyhal_msg_level & PHYHAL_INFORM)
+-#define PHY_THERMAL_ON()	(phyhal_msg_level & PHYHAL_THERMAL)
+-#define PHY_CAL_ON()		(phyhal_msg_level & PHYHAL_CAL)
+-
+-#ifdef BOARD_TYPE
+-#define BOARDTYPE(_type) BOARD_TYPE
+-#else
+-#define BOARDTYPE(_type) _type
+-#endif
+-
+-#define LCNXN_BASEREV		16
+-
+-struct wlc_hw_info;
+-typedef struct phy_info phy_info_t;
+-typedef void (*initfn_t) (phy_info_t *);
+-typedef void (*chansetfn_t) (phy_info_t *, chanspec_t);
+-typedef int (*longtrnfn_t) (phy_info_t *, int);
+-typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *);
+-typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16);
+-typedef u16(*txloccgetfn_t) (phy_info_t *);
+-typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *,
+-				  u8 *);
+-typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32);
+-typedef void (*detachfn_t) (phy_info_t *);
+-
+-#undef ISNPHY
+-#undef ISLCNPHY
+-#define ISNPHY(pi)	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N)
+-#define ISLCNPHY(pi)  	PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN)
+-
+-#define ISPHY_11N_CAP(pi)	(ISNPHY(pi) || ISLCNPHY(pi))
+-
+-#define IS20MHZ(pi)	((pi)->bw == WL_CHANSPEC_BW_20)
+-#define IS40MHZ(pi)	((pi)->bw == WL_CHANSPEC_BW_40)
+-
+-#define PHY_GET_RFATTN(rfgain)	((rfgain) & 0x0f)
+-#define PHY_GET_PADMIX(rfgain)	(((rfgain) & 0x10) >> 4)
+-#define PHY_GET_RFGAINID(rfattn, padmix, width)	((rfattn) + ((padmix)*(width)))
+-#define PHY_SAT(x, n)		((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \
+-				((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x)))
+-#define PHY_SHIFT_ROUND(x, n)	((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n))
+-#define PHY_HW_ROUND(x, s)		((x >> s) + ((x >> (s-1)) & (s != 0)))
+-
+-#define CH_5G_GROUP	3
+-#define A_LOW_CHANS	0
+-#define A_MID_CHANS	1
+-#define A_HIGH_CHANS	2
+-#define CH_2G_GROUP	1
+-#define G_ALL_CHANS	0
+-
+-#define FIRST_REF5_CHANNUM	149
+-#define LAST_REF5_CHANNUM	165
+-#define	FIRST_5G_CHAN		14
+-#define	LAST_5G_CHAN		50
+-#define	FIRST_MID_5G_CHAN	14
+-#define	LAST_MID_5G_CHAN	35
+-#define	FIRST_HIGH_5G_CHAN	36
+-#define	LAST_HIGH_5G_CHAN	41
+-#define	FIRST_LOW_5G_CHAN	42
+-#define	LAST_LOW_5G_CHAN	50
+-
+-#define BASE_LOW_5G_CHAN	4900
+-#define BASE_MID_5G_CHAN	5100
+-#define BASE_HIGH_5G_CHAN	5500
+-
+-#define CHAN5G_FREQ(chan)  (5000 + chan*5)
+-#define CHAN2G_FREQ(chan)  (2407 + chan*5)
+-
+-#define TXP_FIRST_CCK		0
+-#define TXP_LAST_CCK		3
+-#define TXP_FIRST_OFDM		4
+-#define TXP_LAST_OFDM		11
+-#define TXP_FIRST_OFDM_20_CDD	12
+-#define TXP_LAST_OFDM_20_CDD	19
+-#define TXP_FIRST_MCS_20_SISO	20
+-#define TXP_LAST_MCS_20_SISO	27
+-#define TXP_FIRST_MCS_20_CDD	28
+-#define TXP_LAST_MCS_20_CDD	35
+-#define TXP_FIRST_MCS_20_STBC	36
+-#define TXP_LAST_MCS_20_STBC	43
+-#define TXP_FIRST_MCS_20_SDM	44
+-#define TXP_LAST_MCS_20_SDM	51
+-#define TXP_FIRST_OFDM_40_SISO	52
+-#define TXP_LAST_OFDM_40_SISO	59
+-#define TXP_FIRST_OFDM_40_CDD	60
+-#define TXP_LAST_OFDM_40_CDD	67
+-#define TXP_FIRST_MCS_40_SISO	68
+-#define TXP_LAST_MCS_40_SISO	75
+-#define TXP_FIRST_MCS_40_CDD	76
+-#define TXP_LAST_MCS_40_CDD	83
+-#define TXP_FIRST_MCS_40_STBC	84
+-#define TXP_LAST_MCS_40_STBC	91
+-#define TXP_FIRST_MCS_40_SDM	92
+-#define TXP_LAST_MCS_40_SDM	99
+-#define TXP_MCS_32	        100
+-#define TXP_NUM_RATES		101
+-#define ADJ_PWR_TBL_LEN		84
+-
+-#define TXP_FIRST_SISO_MCS_20	20
+-#define TXP_LAST_SISO_MCS_20	27
+-
+-#define PHY_CORE_NUM_1	1
+-#define PHY_CORE_NUM_2	2
+-#define PHY_CORE_NUM_3	3
+-#define PHY_CORE_NUM_4	4
+-#define PHY_CORE_MAX	PHY_CORE_NUM_4
+-#define PHY_CORE_0	0
+-#define PHY_CORE_1	1
+-#define PHY_CORE_2	2
+-#define PHY_CORE_3	3
+-
+-#define MA_WINDOW_SZ		8
+-
+-#define PHY_NOISE_SAMPLE_MON		1
+-#define PHY_NOISE_SAMPLE_EXTERNAL	2
+-#define PHY_NOISE_WINDOW_SZ	16
+-#define PHY_NOISE_GLITCH_INIT_MA 10
+-#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10
+-#define PHY_NOISE_STATE_MON		0x1
+-#define PHY_NOISE_STATE_EXTERNAL	0x2
+-#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY	10
+-#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE	9
+-
+-#define PHY_NOISE_OFFSETFACT_4322  (-103)
+-#define PHY_NOISE_MA_WINDOW_SZ	2
+-
+-#define	PHY_RSSI_TABLE_SIZE	64
+-#define RSSI_ANT_MERGE_MAX	0
+-#define RSSI_ANT_MERGE_MIN	1
+-#define RSSI_ANT_MERGE_AVG	2
+-
+-#define	PHY_TSSI_TABLE_SIZE	64
+-#define	APHY_TSSI_TABLE_SIZE	256
+-#define	TX_GAIN_TABLE_LENGTH	64
+-#define	DEFAULT_11A_TXP_IDX	24
+-#define NUM_TSSI_FRAMES        4
+-#define	NULL_TSSI		0x7f
+-#define	NULL_TSSI_W		0x7f7f
+-
+-#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64
+-
+-#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9
+-
+-#define PHY_TXPWR_MIN		10
+-#define PHY_TXPWR_MIN_NPHY	8
+-#define RADIOPWR_OVERRIDE_DEF	(-1)
+-
+-#define PWRTBL_NUM_COEFF	3
+-
+-#define SPURAVOID_DISABLE	0
+-#define SPURAVOID_AUTO		1
+-#define SPURAVOID_FORCEON	2
+-#define SPURAVOID_FORCEON2	3
+-
+-#define PHY_SW_TIMER_FAST		15
+-#define PHY_SW_TIMER_SLOW		60
+-#define PHY_SW_TIMER_GLACIAL	120
+-
+-#define PHY_PERICAL_AUTO	0
+-#define PHY_PERICAL_FULL	1
+-#define PHY_PERICAL_PARTIAL	2
+-
+-#define PHY_PERICAL_NODELAY	0
+-#define PHY_PERICAL_INIT_DELAY	5
+-#define PHY_PERICAL_ASSOC_DELAY	5
+-#define PHY_PERICAL_WDOG_DELAY	5
+-
+-#define MPHASE_TXCAL_NUMCMDS	2
+-#define PHY_PERICAL_MPHASE_PENDING(pi)	(pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE)
+-
+-enum {
+-	MPHASE_CAL_STATE_IDLE = 0,
+-	MPHASE_CAL_STATE_INIT = 1,
+-	MPHASE_CAL_STATE_TXPHASE0,
+-	MPHASE_CAL_STATE_TXPHASE1,
+-	MPHASE_CAL_STATE_TXPHASE2,
+-	MPHASE_CAL_STATE_TXPHASE3,
+-	MPHASE_CAL_STATE_TXPHASE4,
+-	MPHASE_CAL_STATE_TXPHASE5,
+-	MPHASE_CAL_STATE_PAPDCAL,
+-	MPHASE_CAL_STATE_RXCAL,
+-	MPHASE_CAL_STATE_RSSICAL,
+-	MPHASE_CAL_STATE_IDLETSSI
+-};
+-
+-typedef enum {
+-	CAL_FULL,
+-	CAL_RECAL,
+-	CAL_CURRECAL,
+-	CAL_DIGCAL,
+-	CAL_GCTRL,
+-	CAL_SOFT,
+-	CAL_DIGLO
+-} phy_cal_mode_t;
+-
+-#define RDR_NTIERS  1
+-#define RDR_TIER_SIZE 64
+-#define RDR_LIST_SIZE (512/3)
+-#define RDR_EPOCH_SIZE 40
+-#define RDR_NANTENNAS 2
+-#define RDR_NTIER_SIZE  RDR_LIST_SIZE
+-#define RDR_LP_BUFFER_SIZE 64
+-#define LP_LEN_HIS_SIZE 10
+-
+-#define STATIC_NUM_RF 32
+-#define STATIC_NUM_BB 9
+-
+-#define BB_MULT_MASK		0x0000ffff
+-#define BB_MULT_VALID_MASK	0x80000000
+-
+-#define CORDIC_AG	39797
+-#define	CORDIC_NI	18
+-#define	FIXED(X)	((s32)((X) << 16))
+-#define	FLOAT(X)	(((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1))
+-
+-#define PHY_CHAIN_TX_DISABLE_TEMP	115
+-#define PHY_HYSTERESIS_DELTATEMP	5
+-
+-#define PHY_BITSCNT(x)	bcm_bitcount((u8 *)&(x), sizeof(u8))
+-
+-#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \
+-	mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \
+-	(value) << phy_type##_##reg_name##_##field##_##SHIFT);
+-#define READ_PHY_REG(pi, phy_type, reg_name, field) \
+-	((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\
+-	>> phy_type##_##reg_name##_##field##_##SHIFT)
+-
+-#define	VALID_PHYTYPE(phytype)	(((uint)phytype == PHY_TYPE_N) || \
+-				((uint)phytype == PHY_TYPE_LCN))
+-
+-#define VALID_N_RADIO(radioid)	((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \
+-				(radioid == BCM2057_ID))
+-#define VALID_LCN_RADIO(radioid)	(radioid == BCM2064_ID)
+-
+-#define	VALID_RADIO(pi, radioid)	(\
+-	(ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \
+-	(ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false))
+-
+-#define SCAN_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN))
+-#define RM_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM))
+-#define PLT_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT))
+-#define ASSOC_INPROG_PHY(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC))
+-#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM))
+-#define PHY_MUTED(pi)		(mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE))
+-#define PUB_NOT_ASSOC(pi)	(mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC))
+-
+-#if defined(EXT_CBALL)
+-#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID)
+-#else
+-#define NORADIO_ENAB(pub) 0
+-#endif
+-
+-#define PHY_LTRN_LIST_LEN	64
+-extern u16 ltrn_list[PHY_LTRN_LIST_LEN];
+-
+-typedef struct _phy_table_info {
+-	uint table;
+-	int q;
+-	uint max;
+-} phy_table_info_t;
+-
+-typedef struct phytbl_info {
+-	const void *tbl_ptr;
+-	u32 tbl_len;
+-	u32 tbl_id;
+-	u32 tbl_offset;
+-	u32 tbl_width;
+-} phytbl_info_t;
+-
+-typedef struct {
+-	u8 curr_home_channel;
+-	u16 crsminpwrthld_40_stored;
+-	u16 crsminpwrthld_20L_stored;
+-	u16 crsminpwrthld_20U_stored;
+-	u16 init_gain_code_core1_stored;
+-	u16 init_gain_code_core2_stored;
+-	u16 init_gain_codeb_core1_stored;
+-	u16 init_gain_codeb_core2_stored;
+-	u16 init_gain_table_stored[4];
+-
+-	u16 clip1_hi_gain_code_core1_stored;
+-	u16 clip1_hi_gain_code_core2_stored;
+-	u16 clip1_hi_gain_codeb_core1_stored;
+-	u16 clip1_hi_gain_codeb_core2_stored;
+-	u16 nb_clip_thresh_core1_stored;
+-	u16 nb_clip_thresh_core2_stored;
+-	u16 init_ofdmlna2gainchange_stored[4];
+-	u16 init_ccklna2gainchange_stored[4];
+-	u16 clip1_lo_gain_code_core1_stored;
+-	u16 clip1_lo_gain_code_core2_stored;
+-	u16 clip1_lo_gain_codeb_core1_stored;
+-	u16 clip1_lo_gain_codeb_core2_stored;
+-	u16 w1_clip_thresh_core1_stored;
+-	u16 w1_clip_thresh_core2_stored;
+-	u16 radio_2056_core1_rssi_gain_stored;
+-	u16 radio_2056_core2_rssi_gain_stored;
+-	u16 energy_drop_timeout_len_stored;
+-
+-	u16 ed_crs40_assertthld0_stored;
+-	u16 ed_crs40_assertthld1_stored;
+-	u16 ed_crs40_deassertthld0_stored;
+-	u16 ed_crs40_deassertthld1_stored;
+-	u16 ed_crs20L_assertthld0_stored;
+-	u16 ed_crs20L_assertthld1_stored;
+-	u16 ed_crs20L_deassertthld0_stored;
+-	u16 ed_crs20L_deassertthld1_stored;
+-	u16 ed_crs20U_assertthld0_stored;
+-	u16 ed_crs20U_assertthld1_stored;
+-	u16 ed_crs20U_deassertthld0_stored;
+-	u16 ed_crs20U_deassertthld1_stored;
+-
+-	u16 badplcp_ma;
+-	u16 badplcp_ma_previous;
+-	u16 badplcp_ma_total;
+-	u16 badplcp_ma_list[MA_WINDOW_SZ];
+-	int badplcp_ma_index;
+-	s16 pre_badplcp_cnt;
+-	s16 bphy_pre_badplcp_cnt;
+-
+-	u16 init_gain_core1;
+-	u16 init_gain_core2;
+-	u16 init_gainb_core1;
+-	u16 init_gainb_core2;
+-	u16 init_gain_rfseq[4];
+-
+-	u16 crsminpwr0;
+-	u16 crsminpwrl0;
+-	u16 crsminpwru0;
+-
+-	s16 crsminpwr_index;
+-
+-	u16 radio_2057_core1_rssi_wb1a_gc_stored;
+-	u16 radio_2057_core2_rssi_wb1a_gc_stored;
+-	u16 radio_2057_core1_rssi_wb1g_gc_stored;
+-	u16 radio_2057_core2_rssi_wb1g_gc_stored;
+-	u16 radio_2057_core1_rssi_wb2_gc_stored;
+-	u16 radio_2057_core2_rssi_wb2_gc_stored;
+-	u16 radio_2057_core1_rssi_nb_gc_stored;
+-	u16 radio_2057_core2_rssi_nb_gc_stored;
+-
+-} interference_info_t;
+-
+-typedef struct {
+-	u16 rc_cal_ovr;
+-	u16 phycrsth1;
+-	u16 phycrsth2;
+-	u16 init_n1p1_gain;
+-	u16 p1_p2_gain;
+-	u16 n1_n2_gain;
+-	u16 n1_p1_gain;
+-	u16 div_search_gain;
+-	u16 div_p1_p2_gain;
+-	u16 div_search_gn_change;
+-	u16 table_7_2;
+-	u16 table_7_3;
+-	u16 cckshbits_gnref;
+-	u16 clip_thresh;
+-	u16 clip2_thresh;
+-	u16 clip3_thresh;
+-	u16 clip_p2_thresh;
+-	u16 clip_pwdn_thresh;
+-	u16 clip_n1p1_thresh;
+-	u16 clip_n1_pwdn_thresh;
+-	u16 bbconfig;
+-	u16 cthr_sthr_shdin;
+-	u16 energy;
+-	u16 clip_p1_p2_thresh;
+-	u16 threshold;
+-	u16 reg15;
+-	u16 reg16;
+-	u16 reg17;
+-	u16 div_srch_idx;
+-	u16 div_srch_p1_p2;
+-	u16 div_srch_gn_back;
+-	u16 ant_dwell;
+-	u16 ant_wr_settle;
+-} aci_save_gphy_t;
+-
+-typedef struct _lo_complex_t {
+-	s8 i;
+-	s8 q;
+-} lo_complex_abgphy_info_t;
+-
+-typedef struct _nphy_iq_comp {
+-	s16 a0;
+-	s16 b0;
+-	s16 a1;
+-	s16 b1;
+-} nphy_iq_comp_t;
+-
+-typedef struct _nphy_txpwrindex {
+-	s8 index;
+-	s8 index_internal;
+-	s8 index_internal_save;
+-	u16 AfectrlOverride;
+-	u16 AfeCtrlDacGain;
+-	u16 rad_gain;
+-	u8 bbmult;
+-	u16 iqcomp_a;
+-	u16 iqcomp_b;
+-	u16 locomp;
+-} phy_txpwrindex_t;
+-
+-typedef struct {
+-
+-	u16 txcal_coeffs_2G[8];
+-	u16 txcal_radio_regs_2G[8];
+-	nphy_iq_comp_t rxcal_coeffs_2G;
+-
+-	u16 txcal_coeffs_5G[8];
+-	u16 txcal_radio_regs_5G[8];
+-	nphy_iq_comp_t rxcal_coeffs_5G;
+-} txiqcal_cache_t;
+-
+-typedef struct _nphy_pwrctrl {
+-	s8 max_pwr_2g;
+-	s8 idle_targ_2g;
+-	s16 pwrdet_2g_a1;
+-	s16 pwrdet_2g_b0;
+-	s16 pwrdet_2g_b1;
+-	s8 max_pwr_5gm;
+-	s8 idle_targ_5gm;
+-	s8 max_pwr_5gh;
+-	s8 max_pwr_5gl;
+-	s16 pwrdet_5gm_a1;
+-	s16 pwrdet_5gm_b0;
+-	s16 pwrdet_5gm_b1;
+-	s16 pwrdet_5gl_a1;
+-	s16 pwrdet_5gl_b0;
+-	s16 pwrdet_5gl_b1;
+-	s16 pwrdet_5gh_a1;
+-	s16 pwrdet_5gh_b0;
+-	s16 pwrdet_5gh_b1;
+-	s8 idle_targ_5gl;
+-	s8 idle_targ_5gh;
+-	s8 idle_tssi_2g;
+-	s8 idle_tssi_5g;
+-	s8 idle_tssi;
+-	s16 a1;
+-	s16 b0;
+-	s16 b1;
+-} phy_pwrctrl_t;
+-
+-typedef struct _nphy_txgains {
+-	u16 txlpf[2];
+-	u16 txgm[2];
+-	u16 pga[2];
+-	u16 pad[2];
+-	u16 ipa[2];
+-} nphy_txgains_t;
+-
+-#define PHY_NOISEVAR_BUFSIZE 10
+-
+-typedef struct _nphy_noisevar_buf {
+-	int bufcount;
+-	int tone_id[PHY_NOISEVAR_BUFSIZE];
+-	u32 noise_vars[PHY_NOISEVAR_BUFSIZE];
+-	u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE];
+-} phy_noisevar_buf_t;
+-
+-typedef struct {
+-	u16 rssical_radio_regs_2G[2];
+-	u16 rssical_phyregs_2G[12];
+-
+-	u16 rssical_radio_regs_5G[2];
+-	u16 rssical_phyregs_5G[12];
+-} rssical_cache_t;
+-
+-typedef struct {
+-
+-	u16 txiqlocal_a;
+-	u16 txiqlocal_b;
+-	u16 txiqlocal_didq;
+-	u8 txiqlocal_ei0;
+-	u8 txiqlocal_eq0;
+-	u8 txiqlocal_fi0;
+-	u8 txiqlocal_fq0;
+-
+-	u16 txiqlocal_bestcoeffs[11];
+-	u16 txiqlocal_bestcoeffs_valid;
+-
+-	u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY];
+-	u16 analog_gain_ref;
+-	u16 lut_begin;
+-	u16 lut_end;
+-	u16 lut_step;
+-	u16 rxcompdbm;
+-	u16 papdctrl;
+-	u16 sslpnCalibClkEnCtrl;
+-
+-	u16 rxiqcal_coeff_a0;
+-	u16 rxiqcal_coeff_b0;
+-} lcnphy_cal_results_t;
+-
+-struct shared_phy {
+-	struct phy_info *phy_head;
+-	uint unit;
+-	si_t *sih;
+-	void *physhim;
+-	uint corerev;
+-	u32 machwcap;
+-	bool up;
+-	bool clk;
+-	uint now;
+-	u16 vid;
+-	u16 did;
+-	uint chip;
+-	uint chiprev;
+-	uint chippkg;
+-	uint sromrev;
+-	uint boardtype;
+-	uint boardrev;
+-	uint boardvendor;
+-	u32 boardflags;
+-	u32 boardflags2;
+-	uint bustype;
+-	uint buscorerev;
+-	uint fast_timer;
+-	uint slow_timer;
+-	uint glacial_timer;
+-	u8 rx_antdiv;
+-	s8 phy_noise_window[MA_WINDOW_SZ];
+-	uint phy_noise_index;
+-	u8 hw_phytxchain;
+-	u8 hw_phyrxchain;
+-	u8 phytxchain;
+-	u8 phyrxchain;
+-	u8 rssi_mode;
+-	bool _rifs_phy;
+-};
+-
+-struct phy_pub {
+-	uint phy_type;
+-	uint phy_rev;
+-	u8 phy_corenum;
+-	u16 radioid;
+-	u8 radiorev;
+-	u8 radiover;
+-
+-	uint coreflags;
+-	uint ana_rev;
+-	bool abgphy_encore;
+-};
+-
+-struct phy_info_nphy;
+-typedef struct phy_info_nphy phy_info_nphy_t;
+-
+-struct phy_info_lcnphy;
+-typedef struct phy_info_lcnphy phy_info_lcnphy_t;
+-
+-struct phy_func_ptr {
+-	initfn_t init;
+-	initfn_t calinit;
+-	chansetfn_t chanset;
+-	initfn_t txpwrrecalc;
+-	longtrnfn_t longtrn;
+-	txiqccgetfn_t txiqccget;
+-	txiqccsetfn_t txiqccset;
+-	txloccgetfn_t txloccget;
+-	radioloftgetfn_t radioloftget;
+-	initfn_t carrsuppr;
+-	rxsigpwrfn_t rxsigpwr;
+-	detachfn_t detach;
+-};
+-typedef struct phy_func_ptr phy_func_ptr_t;
+-
+-struct phy_info {
+-	wlc_phy_t pubpi_ro;
+-	shared_phy_t *sh;
+-	phy_func_ptr_t pi_fptr;
+-	void *pi_ptr;
+-
+-	union {
+-		phy_info_lcnphy_t *pi_lcnphy;
+-	} u;
+-	bool user_txpwr_at_rfport;
+-
+-	d11regs_t *regs;
+-	struct phy_info *next;
+-	char *vars;
+-	wlc_phy_t pubpi;
+-
+-	bool do_initcal;
+-	bool phytest_on;
+-	bool ofdm_rateset_war;
+-	bool bf_preempt_4306;
+-	chanspec_t radio_chanspec;
+-	u8 antsel_type;
+-	u16 bw;
+-	u8 txpwr_percent;
+-	bool phy_init_por;
+-
+-	bool init_in_progress;
+-	bool initialized;
+-	bool sbtml_gm;
+-	uint refcnt;
+-	bool watchdog_override;
+-	u8 phynoise_state;
+-	uint phynoise_now;
+-	int phynoise_chan_watchdog;
+-	bool phynoise_polling;
+-	bool disable_percal;
+-	mbool measure_hold;
+-
+-	s16 txpa_2g[PWRTBL_NUM_COEFF];
+-	s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF];
+-	s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_low[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_mid[PWRTBL_NUM_COEFF];
+-	s16 txpa_5g_hi[PWRTBL_NUM_COEFF];
+-
+-	u8 tx_srom_max_2g;
+-	u8 tx_srom_max_5g_low;
+-	u8 tx_srom_max_5g_mid;
+-	u8 tx_srom_max_5g_hi;
+-	u8 tx_srom_max_rate_2g[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES];
+-	u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES];
+-	u8 tx_user_target[TXP_NUM_RATES];
+-	s8 tx_power_offset[TXP_NUM_RATES];
+-	u8 tx_power_target[TXP_NUM_RATES];
+-
+-	srom_fem_t srom_fem2g;
+-	srom_fem_t srom_fem5g;
+-
+-	u8 tx_power_max;
+-	u8 tx_power_max_rate_ind;
+-	bool hwpwrctrl;
+-	u8 nphy_txpwrctrl;
+-	s8 nphy_txrx_chain;
+-	bool phy_5g_pwrgain;
+-
+-	u16 phy_wreg;
+-	u16 phy_wreg_limit;
+-
+-	s8 n_preamble_override;
+-	u8 antswitch;
+-	u8 aa2g, aa5g;
+-
+-	s8 idle_tssi[CH_5G_GROUP];
+-	s8 target_idle_tssi;
+-	s8 txpwr_est_Pout;
+-	u8 tx_power_min;
+-	u8 txpwr_limit[TXP_NUM_RATES];
+-	u8 txpwr_env_limit[TXP_NUM_RATES];
+-	u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN];
+-
+-	bool channel_14_wide_filter;
+-
+-	bool txpwroverride;
+-	bool txpwridx_override_aphy;
+-	s16 radiopwr_override;
+-	u16 hwpwr_txcur;
+-	u8 saved_txpwr_idx;
+-
+-	bool edcrs_threshold_lock;
+-
+-	u32 tr_R_gain_val;
+-	u32 tr_T_gain_val;
+-
+-	s16 ofdm_analog_filt_bw_override;
+-	s16 cck_analog_filt_bw_override;
+-	s16 ofdm_rccal_override;
+-	s16 cck_rccal_override;
+-	u16 extlna_type;
+-
+-	uint interference_mode_crs_time;
+-	u16 crsglitch_prev;
+-	bool interference_mode_crs;
+-
+-	u32 phy_tx_tone_freq;
+-	uint phy_lastcal;
+-	bool phy_forcecal;
+-	bool phy_fixed_noise;
+-	u32 xtalfreq;
+-	u8 pdiv;
+-	s8 carrier_suppr_disable;
+-
+-	bool phy_bphy_evm;
+-	bool phy_bphy_rfcs;
+-	s8 phy_scraminit;
+-	u8 phy_gpiosel;
+-
+-	s16 phy_txcore_disable_temp;
+-	s16 phy_txcore_enable_temp;
+-	s8 phy_tempsense_offset;
+-	bool phy_txcore_heatedup;
+-
+-	u16 radiopwr;
+-	u16 bb_atten;
+-	u16 txctl1;
+-
+-	u16 mintxbias;
+-	u16 mintxmag;
+-	lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB];
+-	s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB];
+-	u16 gain_table[TX_GAIN_TABLE_LENGTH];
+-	bool loopback_gain;
+-	s16 max_lpback_gain_hdB;
+-	s16 trsw_rx_gain_hdB;
+-	u8 power_vec[8];
+-
+-	u16 rc_cal;
+-	int nrssi_table_delta;
+-	int nrssi_slope_scale;
+-	int nrssi_slope_offset;
+-	int min_rssi;
+-	int max_rssi;
+-
+-	s8 txpwridx;
+-	u8 min_txpower;
+-
+-	u8 a_band_high_disable;
+-
+-	u16 tx_vos;
+-	u16 global_tx_bb_dc_bias_loft;
+-
+-	int rf_max;
+-	int bb_max;
+-	int rf_list_size;
+-	int bb_list_size;
+-	u16 *rf_attn_list;
+-	u16 *bb_attn_list;
+-	u16 padmix_mask;
+-	u16 padmix_reg;
+-	u16 *txmag_list;
+-	uint txmag_len;
+-	bool txmag_enable;
+-
+-	s8 *a_tssi_to_dbm;
+-	s8 *m_tssi_to_dbm;
+-	s8 *l_tssi_to_dbm;
+-	s8 *h_tssi_to_dbm;
+-	u8 *hwtxpwr;
+-
+-	u16 freqtrack_saved_regs[2];
+-	int cur_interference_mode;
+-	bool hwpwrctrl_capable;
+-	bool temppwrctrl_capable;
+-
+-	uint phycal_nslope;
+-	uint phycal_noffset;
+-	uint phycal_mlo;
+-	uint phycal_txpower;
+-
+-	u8 phy_aa2g;
+-
+-	bool nphy_tableloaded;
+-	s8 nphy_rssisel;
+-	u32 nphy_bb_mult_save;
+-	u16 nphy_txiqlocal_bestc[11];
+-	bool nphy_txiqlocal_coeffsvalid;
+-	phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2];
+-	phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2];
+-	u16 cck2gpo;
+-	u32 ofdm2gpo;
+-	u32 ofdm5gpo;
+-	u32 ofdm5glpo;
+-	u32 ofdm5ghpo;
+-	u8 bw402gpo;
+-	u8 bw405gpo;
+-	u8 bw405glpo;
+-	u8 bw405ghpo;
+-	u8 cdd2gpo;
+-	u8 cdd5gpo;
+-	u8 cdd5glpo;
+-	u8 cdd5ghpo;
+-	u8 stbc2gpo;
+-	u8 stbc5gpo;
+-	u8 stbc5glpo;
+-	u8 stbc5ghpo;
+-	u8 bwdup2gpo;
+-	u8 bwdup5gpo;
+-	u8 bwdup5glpo;
+-	u8 bwdup5ghpo;
+-	u16 mcs2gpo[8];
+-	u16 mcs5gpo[8];
+-	u16 mcs5glpo[8];
+-	u16 mcs5ghpo[8];
+-	u32 nphy_rxcalparams;
+-
+-	u8 phy_spuravoid;
+-	bool phy_isspuravoid;
+-
+-	u8 phy_pabias;
+-	u8 nphy_papd_skip;
+-	u8 nphy_tssi_slope;
+-
+-	s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ];
+-	u8 nphy_noise_index;
+-
+-	u8 nphy_txpid2g[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5g[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5gl[PHY_CORE_NUM_2];
+-	u8 nphy_txpid5gh[PHY_CORE_NUM_2];
+-
+-	bool nphy_gain_boost;
+-	bool nphy_elna_gain_config;
+-	u16 old_bphy_test;
+-	u16 old_bphy_testcontrol;
+-
+-	bool phyhang_avoid;
+-
+-	bool rssical_nphy;
+-	u8 nphy_perical;
+-	uint nphy_perical_last;
+-	u8 cal_type_override;
+-	u8 mphase_cal_phase_id;
+-	u8 mphase_txcal_cmdidx;
+-	u8 mphase_txcal_numcmds;
+-	u16 mphase_txcal_bestcoeffs[11];
+-	chanspec_t nphy_txiqlocal_chanspec;
+-	chanspec_t nphy_iqcal_chanspec_2G;
+-	chanspec_t nphy_iqcal_chanspec_5G;
+-	chanspec_t nphy_rssical_chanspec_2G;
+-	chanspec_t nphy_rssical_chanspec_5G;
+-	struct wlapi_timer *phycal_timer;
+-	bool use_int_tx_iqlo_cal_nphy;
+-	bool internal_tx_iqlo_cal_tapoff_intpa_nphy;
+-	s16 nphy_lastcal_temp;
+-
+-	txiqcal_cache_t calibration_cache;
+-	rssical_cache_t rssical_cache;
+-
+-	u8 nphy_txpwr_idx[2];
+-	u8 nphy_papd_cal_type;
+-	uint nphy_papd_last_cal;
+-	u16 nphy_papd_tx_gain_at_last_cal[2];
+-	u8 nphy_papd_cal_gain_index[2];
+-	s16 nphy_papd_epsilon_offset[2];
+-	bool nphy_papd_recal_enable;
+-	u32 nphy_papd_recal_counter;
+-	bool nphy_force_papd_cal;
+-	bool nphy_papdcomp;
+-	bool ipa2g_on;
+-	bool ipa5g_on;
+-
+-	u16 classifier_state;
+-	u16 clip_state[2];
+-	uint nphy_deaf_count;
+-	u8 rxiq_samps;
+-	u8 rxiq_antsel;
+-
+-	u16 rfctrlIntc1_save;
+-	u16 rfctrlIntc2_save;
+-	bool first_cal_after_assoc;
+-	u16 tx_rx_cal_radio_saveregs[22];
+-	u16 tx_rx_cal_phy_saveregs[15];
+-
+-	u8 nphy_cal_orig_pwr_idx[2];
+-	u8 nphy_txcal_pwr_idx[2];
+-	u8 nphy_rxcal_pwr_idx[2];
+-	u16 nphy_cal_orig_tx_gain[2];
+-	nphy_txgains_t nphy_cal_target_gain;
+-	u16 nphy_txcal_bbmult;
+-	u16 nphy_gmval;
+-
+-	u16 nphy_saved_bbconf;
+-
+-	bool nphy_gband_spurwar_en;
+-	bool nphy_gband_spurwar2_en;
+-	bool nphy_aband_spurwar_en;
+-	u16 nphy_rccal_value;
+-	u16 nphy_crsminpwr[3];
+-	phy_noisevar_buf_t nphy_saved_noisevars;
+-	bool nphy_anarxlpf_adjusted;
+-	bool nphy_crsminpwr_adjusted;
+-	bool nphy_noisevars_adjusted;
+-
+-	bool nphy_rxcal_active;
+-	u16 radar_percal_mask;
+-	bool dfs_lp_buffer_nphy;
+-
+-	u16 nphy_fineclockgatecontrol;
+-
+-	s8 rx2tx_biasentry;
+-
+-	u16 crsminpwr0;
+-	u16 crsminpwrl0;
+-	u16 crsminpwru0;
+-	s16 noise_crsminpwr_index;
+-	u16 init_gain_core1;
+-	u16 init_gain_core2;
+-	u16 init_gainb_core1;
+-	u16 init_gainb_core2;
+-	u8 aci_noise_curr_channel;
+-	u16 init_gain_rfseq[4];
+-
+-	bool radio_is_on;
+-
+-	bool nphy_sample_play_lpf_bw_ctl_ovr;
+-
+-	u16 tbl_data_hi;
+-	u16 tbl_data_lo;
+-	u16 tbl_addr;
+-
+-	uint tbl_save_id;
+-	uint tbl_save_offset;
+-
+-	u8 txpwrctrl;
+-	s8 txpwrindex[PHY_CORE_MAX];
+-
+-	u8 phycal_tempdelta;
+-	u32 mcs20_po;
+-	u32 mcs40_po;
+-	struct wiphy *wiphy;
+-};
+-
+-typedef s32 fixed;
+-
+-typedef struct _cs32 {
+-	fixed q;
+-	fixed i;
+-} cs32;
+-
+-typedef struct radio_regs {
+-	u16 address;
+-	u32 init_a;
+-	u32 init_g;
+-	u8 do_init_a;
+-	u8 do_init_g;
+-} radio_regs_t;
+-
+-typedef struct radio_20xx_regs {
+-	u16 address;
+-	u8 init;
+-	u8 do_init;
+-} radio_20xx_regs_t;
+-
+-typedef struct lcnphy_radio_regs {
+-	u16 address;
+-	u8 init_a;
+-	u8 init_g;
+-	u8 do_init_a;
+-	u8 do_init_g;
+-} lcnphy_radio_regs_t;
+-
+-extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[];
+-extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[];
+-extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[],
+-    regs_RX_2056[];
+-extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[];
+-extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[],
+-    regs_RX_2056_rev5[];
+-extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[],
+-    regs_RX_2056_rev6[];
+-extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[],
+-    regs_RX_2056_rev7[];
+-extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[],
+-    regs_RX_2056_rev8[];
+-extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[];
+-extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[];
+-
+-extern char *phy_getvar(phy_info_t *pi, const char *name);
+-extern int phy_getintvar(phy_info_t *pi, const char *name);
+-#define PHY_GETVAR(pi, name)	phy_getvar(pi, name)
+-#define PHY_GETINTVAR(pi, name)	phy_getintvar(pi, name)
+-
+-extern u16 read_phy_reg(phy_info_t *pi, u16 addr);
+-extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val);
+-
+-extern u16 read_radio_reg(phy_info_t *pi, u16 addr);
+-extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask,
+-			  u16 val);
+-extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask);
+-
+-extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val);
+-
+-extern void wlc_phyreg_enter(wlc_phy_t *pih);
+-extern void wlc_phyreg_exit(wlc_phy_t *pih);
+-extern void wlc_radioreg_enter(wlc_phy_t *pih);
+-extern void wlc_radioreg_exit(wlc_phy_t *pih);
+-
+-extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info,
+-			       u16 tblAddr, u16 tblDataHi,
+-			       u16 tblDatalo);
+-extern void wlc_phy_write_table(phy_info_t *pi,
+-				const phytbl_info_t *ptbl_info, u16 tblAddr,
+-				u16 tblDataHi, u16 tblDatalo);
+-extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset,
+-			       u16 tblAddr, u16 tblDataHi,
+-			       u16 tblDataLo);
+-extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val);
+-
+-extern void write_phy_channel_reg(phy_info_t *pi, uint val);
+-extern void wlc_phy_txpower_update_shm(phy_info_t *pi);
+-
+-extern void wlc_phy_cordic(fixed theta, cs32 *val);
+-extern u8 wlc_phy_nbits(s32 value);
+-extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
+-
+-extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi,
+-					     radio_20xx_regs_t *radioregs);
+-extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs,
+-				    u16 core_offset);
+-
+-extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi);
+-
+-extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on);
+-extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real,
+-					s32 *eps_imag);
+-
+-extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi);
+-extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi);
+-
+-extern bool wlc_phy_attach_nphy(phy_info_t *pi);
+-extern bool wlc_phy_attach_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_detach_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_init_nphy(phy_info_t *pi);
+-extern void wlc_phy_init_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_cal_init_nphy(phy_info_t *pi);
+-extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec);
+-extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec);
+-extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi,
+-					      chanspec_t chanspec);
+-extern int wlc_phy_channel2freq(uint channel);
+-extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint);
+-extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t);
+-
+-extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode);
+-extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi);
+-
+-extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi);
+-extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi);
+-extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi);
+-
+-extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index);
+-extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable);
+-extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi);
+-extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz,
+-				     u16 max_val, bool iqcalmode);
+-
+-extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan,
+-					       u8 *max_pwr, u8 rate_id);
+-extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
+-					    u8 rate_mcs_end,
+-					    u8 rate_ofdm_start);
+-extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power,
+-					    u8 rate_ofdm_start,
+-					    u8 rate_ofdm_end,
+-					    u8 rate_mcs_start);
+-
+-extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode);
+-extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode);
+-extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode);
+-extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode);
+-extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi);
+-extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel);
+-extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode);
+-extern void wlc_2064_vco_cal(phy_info_t *pi);
+-
+-extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
+-
+-#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
+-#define LCNPHY_TX_POWER_TABLE_SIZE	128
+-#define LCNPHY_MAX_TX_POWER_INDEX	(LCNPHY_TX_POWER_TABLE_SIZE - 1)
+-#define LCNPHY_TBL_ID_TXPWRCTL 	0x07
+-#define LCNPHY_TX_PWR_CTRL_OFF	0
+-#define LCNPHY_TX_PWR_CTRL_SW		(0x1 << 15)
+-#define LCNPHY_TX_PWR_CTRL_HW         ((0x1 << 15) | \
+-					(0x1 << 14) | \
+-					(0x1 << 13))
+-
+-#define LCNPHY_TX_PWR_CTRL_TEMPBASED	0xE001
+-
+-extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti);
+-extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti);
+-extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b);
+-extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq);
+-extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b);
+-extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi);
+-extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0,
+-				      u8 *eq0, u8 *fi0, u8 *fq0);
+-extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode);
+-extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode);
+-extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi);
+-extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi);
+-extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1);
+-extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr,
+-				s8 *cck_pwr);
+-extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi);
+-
+-extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index);
+-
+-#define NPHY_MAX_HPVGA1_INDEX		10
+-#define NPHY_DEF_HPVGA1_INDEXLIMIT	7
+-
+-typedef struct _phy_iq_est {
+-	s32 iq_prod;
+-	u32 i_pwr;
+-	u32 q_pwr;
+-} phy_iq_est_t;
+-
+-extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable);
+-extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode);
+-
+-#define wlc_phy_write_table_nphy(pi, pti)	wlc_phy_write_table(pi, pti, 0x72, \
+-	0x74, 0x73)
+-#define wlc_phy_read_table_nphy(pi, pti)	wlc_phy_read_table(pi, pti, 0x72, \
+-	0x74, 0x73)
+-#define wlc_nphy_table_addr(pi, id, off)	wlc_phy_table_addr((pi), (id), (off), \
+-	0x72, 0x74, 0x73)
+-#define wlc_nphy_table_data_write(pi, w, v)	wlc_phy_table_data_write((pi), (w), (v))
+-
+-extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o,
+-				    u32 w, void *d);
+-extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32,
+-				     u32, const void *);
+-
+-#define	PHY_IPA(pi) \
+-	((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \
+-	 (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec)))
+-
+-#define WLC_PHY_WAR_PR51571(pi) \
+-	if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \
+-		(void)R_REG(&(pi)->regs->maccontrol)
+-
+-extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype);
+-extern void wlc_phy_aci_reset_nphy(phy_info_t *pi);
+-extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en);
+-
+-extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan);
+-extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on);
+-
+-extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi);
+-
+-extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd);
+-extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi);
+-
+-extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val);
+-
+-extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est,
+-				   u16 num_samps, u8 wait_time,
+-				   u8 wait_for_crs);
+-
+-extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write,
+-				      nphy_iq_comp_t *comp);
+-extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi);
+-
+-extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask);
+-extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih);
+-
+-extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type);
+-extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi);
+-extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi);
+-extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi);
+-extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi);
+-
+-extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi);
+-extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-				   bool full, bool m);
+-extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-				 u8 type, bool d);
+-extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask,
+-				     s8 txpwrindex, bool res);
+-extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type);
+-extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type,
+-				  s32 *rssi_buf, u8 nsamps);
+-extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi);
+-extern int wlc_phy_aci_scan_nphy(phy_info_t *pi);
+-extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower,
+-					bool debug);
+-extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-				u8 mode, u8, bool);
+-extern void wlc_phy_stopplayback_nphy(phy_info_t *pi);
+-extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf,
+-				     u8 num_samps);
+-extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi);
+-
+-extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh);
+-
+-#define NPHY_TESTPATTERN_BPHY_EVM   0
+-#define NPHY_TESTPATTERN_BPHY_RFCS  1
+-
+-extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs);
+-
+-void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset,
+-				s8 *ofdmoffset);
+-extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi,
+-				    chanspec_t chanspec);
+-
+-extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih);
+-#endif				/* _wlc_phy_int_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
+deleted file mode 100644
+index b8864c5..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
++++ /dev/null
+@@ -1,5302 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/bitops.h>
+-#include <linux/delay.h>
+-#include <wlc_cfg.h>
+-#include <linux/pci.h>
+-#include <aiutils.h>
+-#include <wlc_pmu.h>
+-#include <bcmnvram.h>
+-
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_phy_radio.h"
+-#include "wlc_phy_int.h"
+-#include "wlc_phy_qmath.h"
+-#include "wlc_phy_lcn.h"
+-#include "wlc_phytbl_lcn.h"
+-
+-#define PLL_2064_NDIV		90
+-#define PLL_2064_LOW_END_VCO 	3000
+-#define PLL_2064_LOW_END_KVCO 	27
+-#define PLL_2064_HIGH_END_VCO	4200
+-#define PLL_2064_HIGH_END_KVCO	68
+-#define PLL_2064_LOOP_BW_DOUBLER	200
+-#define PLL_2064_D30_DOUBLER		10500
+-#define PLL_2064_LOOP_BW	260
+-#define PLL_2064_D30		8000
+-#define PLL_2064_CAL_REF_TO	8
+-#define PLL_2064_MHZ		1000000
+-#define PLL_2064_OPEN_LOOP_DELAY	5
+-
+-#define TEMPSENSE 			1
+-#define VBATSENSE           2
+-
+-#define NOISE_IF_UPD_CHK_INTERVAL	1
+-#define NOISE_IF_UPD_RST_INTERVAL	60
+-#define NOISE_IF_UPD_THRESHOLD_CNT	1
+-#define NOISE_IF_UPD_TRHRESHOLD	50
+-#define NOISE_IF_UPD_TIMEOUT		1000
+-#define NOISE_IF_OFF			0
+-#define NOISE_IF_CHK			1
+-#define NOISE_IF_ON			2
+-
+-#define PAPD_BLANKING_PROFILE 		3
+-#define PAPD2LUT			0
+-#define PAPD_CORR_NORM 			0
+-#define PAPD_BLANKING_THRESHOLD 	0
+-#define PAPD_STOP_AFTER_LAST_UPDATE	0
+-
+-#define LCN_TARGET_PWR  60
+-
+-#define LCN_VBAT_OFFSET_433X 34649679
+-#define LCN_VBAT_SLOPE_433X  8258032
+-
+-#define LCN_VBAT_SCALE_NOM  53
+-#define LCN_VBAT_SCALE_DEN  432
+-
+-#define LCN_TEMPSENSE_OFFSET  80812
+-#define LCN_TEMPSENSE_DEN  2647
+-
+-#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \
+-	(0 + 8)
+-#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \
+-	(0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT)
+-
+-#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \
+-	(0 + 8)
+-#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \
+-	(0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT)
+-
+-#define wlc_lcnphy_enable_tx_gain_override(pi) \
+-	wlc_lcnphy_set_tx_gain_override(pi, true)
+-#define wlc_lcnphy_disable_tx_gain_override(pi) \
+-	wlc_lcnphy_set_tx_gain_override(pi, false)
+-
+-#define wlc_lcnphy_iqcal_active(pi)	\
+-	(read_phy_reg((pi), 0x451) & \
+-	((0x1 << 15) | (0x1 << 14)))
+-
+-#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13))
+-#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \
+-	(pi->temppwrctrl_capable)
+-#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \
+-	(pi->hwpwrctrl_capable)
+-
+-#define SWCTRL_BT_TX		0x18
+-#define SWCTRL_OVR_DISABLE	0x40
+-
+-#define	AFE_CLK_INIT_MODE_TXRX2X	1
+-#define	AFE_CLK_INIT_MODE_PAPD		0
+-
+-#define LCNPHY_TBL_ID_IQLOCAL			0x00
+-
+-#define LCNPHY_TBL_ID_RFSEQ         0x08
+-#define LCNPHY_TBL_ID_GAIN_IDX		0x0d
+-#define LCNPHY_TBL_ID_SW_CTRL			0x0f
+-#define LCNPHY_TBL_ID_GAIN_TBL		0x12
+-#define LCNPHY_TBL_ID_SPUR			0x14
+-#define LCNPHY_TBL_ID_SAMPLEPLAY		0x15
+-#define LCNPHY_TBL_ID_SAMPLEPLAY1		0x16
+-
+-#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 	832
+-#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 	128
+-#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 	192
+-#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET		320
+-#define LCNPHY_TX_PWR_CTRL_LO_OFFSET		448
+-#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET		576
+-
+-#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313	140
+-
+-#define LCNPHY_TX_PWR_CTRL_START_NPT		1
+-#define LCNPHY_TX_PWR_CTRL_MAX_NPT			7
+-
+-#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000
+-
+-#define LCNPHY_ACI_DETECT_START      1
+-#define LCNPHY_ACI_DETECT_PROGRESS   2
+-#define LCNPHY_ACI_DETECT_STOP       3
+-
+-#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100
+-#define LCNPHY_ACI_GLITCH_TRSH 2000
+-#define	LCNPHY_ACI_TMOUT 250
+-#define LCNPHY_ACI_DETECT_TIMEOUT  2
+-#define LCNPHY_ACI_START_DELAY 0
+-
+-#define wlc_lcnphy_tx_gain_override_enabled(pi) \
+-	(0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6)))
+-
+-#define wlc_lcnphy_total_tx_frames(pi) \
+-	wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + offsetof(macstat_t, txallfrm))
+-
+-typedef struct {
+-	u16 gm_gain;
+-	u16 pga_gain;
+-	u16 pad_gain;
+-	u16 dac_gain;
+-} lcnphy_txgains_t;
+-
+-typedef enum {
+-	LCNPHY_CAL_FULL,
+-	LCNPHY_CAL_RECAL,
+-	LCNPHY_CAL_CURRECAL,
+-	LCNPHY_CAL_DIGCAL,
+-	LCNPHY_CAL_GCTRL
+-} lcnphy_cal_mode_t;
+-
+-typedef struct {
+-	lcnphy_txgains_t gains;
+-	bool useindex;
+-	u8 index;
+-} lcnphy_txcalgains_t;
+-
+-typedef struct {
+-	u8 chan;
+-	s16 a;
+-	s16 b;
+-} lcnphy_rx_iqcomp_t;
+-
+-typedef struct {
+-	s16 re;
+-	s16 im;
+-} lcnphy_spb_tone_t;
+-
+-typedef struct {
+-	u16 re;
+-	u16 im;
+-} lcnphy_unsign16_struct;
+-
+-typedef struct {
+-	u32 iq_prod;
+-	u32 i_pwr;
+-	u32 q_pwr;
+-} lcnphy_iq_est_t;
+-
+-typedef struct {
+-	u16 ptcentreTs20;
+-	u16 ptcentreFactor;
+-} lcnphy_sfo_cfg_t;
+-
+-typedef enum {
+-	LCNPHY_PAPD_CAL_CW,
+-	LCNPHY_PAPD_CAL_OFDM
+-} lcnphy_papd_cal_type_t;
+-
+-typedef u16 iqcal_gain_params_lcnphy[9];
+-
+-static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = {
+-	{0, 0, 0, 0, 0, 0, 0, 0, 0},
+-};
+-
+-static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = {
+-	tbl_iqcal_gainparams_lcnphy_2G,
+-};
+-
+-static const u16 iqcal_gainparams_numgains_lcnphy[1] = {
+-	sizeof(tbl_iqcal_gainparams_lcnphy_2G) /
+-	    sizeof(*tbl_iqcal_gainparams_lcnphy_2G),
+-};
+-
+-static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = {
+-	{965, 1087},
+-	{967, 1085},
+-	{969, 1082},
+-	{971, 1080},
+-	{973, 1078},
+-	{975, 1076},
+-	{977, 1073},
+-	{979, 1071},
+-	{981, 1069},
+-	{983, 1067},
+-	{985, 1065},
+-	{987, 1063},
+-	{989, 1060},
+-	{994, 1055}
+-};
+-
+-static const
+-u16 lcnphy_iqcal_loft_gainladder[] = {
+-	((2 << 8) | 0),
+-	((3 << 8) | 0),
+-	((4 << 8) | 0),
+-	((6 << 8) | 0),
+-	((8 << 8) | 0),
+-	((11 << 8) | 0),
+-	((16 << 8) | 0),
+-	((16 << 8) | 1),
+-	((16 << 8) | 2),
+-	((16 << 8) | 3),
+-	((16 << 8) | 4),
+-	((16 << 8) | 5),
+-	((16 << 8) | 6),
+-	((16 << 8) | 7),
+-	((23 << 8) | 7),
+-	((32 << 8) | 7),
+-	((45 << 8) | 7),
+-	((64 << 8) | 7),
+-	((91 << 8) | 7),
+-	((128 << 8) | 7)
+-};
+-
+-static const
+-u16 lcnphy_iqcal_ir_gainladder[] = {
+-	((1 << 8) | 0),
+-	((2 << 8) | 0),
+-	((4 << 8) | 0),
+-	((6 << 8) | 0),
+-	((8 << 8) | 0),
+-	((11 << 8) | 0),
+-	((16 << 8) | 0),
+-	((23 << 8) | 0),
+-	((32 << 8) | 0),
+-	((45 << 8) | 0),
+-	((64 << 8) | 0),
+-	((64 << 8) | 1),
+-	((64 << 8) | 2),
+-	((64 << 8) | 3),
+-	((64 << 8) | 4),
+-	((64 << 8) | 5),
+-	((64 << 8) | 6),
+-	((64 << 8) | 7),
+-	((91 << 8) | 7),
+-	((128 << 8) | 7)
+-};
+-
+-static const
+-lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = {
+-	{88, 0},
+-	{73, 49},
+-	{34, 81},
+-	{-17, 86},
+-	{-62, 62},
+-	{-86, 17},
+-	{-81, -34},
+-	{-49, -73},
+-	{0, -88},
+-	{49, -73},
+-	{81, -34},
+-	{86, 17},
+-	{62, 62},
+-	{17, 86},
+-	{-34, 81},
+-	{-73, 49},
+-	{-88, 0},
+-	{-73, -49},
+-	{-34, -81},
+-	{17, -86},
+-	{62, -62},
+-	{86, -17},
+-	{81, 34},
+-	{49, 73},
+-	{0, 88},
+-	{-49, 73},
+-	{-81, 34},
+-	{-86, -17},
+-	{-62, -62},
+-	{-17, -86},
+-	{34, -81},
+-	{73, -49},
+-};
+-
+-static const
+-u16 iqlo_loopback_rf_regs[20] = {
+-	RADIO_2064_REG036,
+-	RADIO_2064_REG11A,
+-	RADIO_2064_REG03A,
+-	RADIO_2064_REG025,
+-	RADIO_2064_REG028,
+-	RADIO_2064_REG005,
+-	RADIO_2064_REG112,
+-	RADIO_2064_REG0FF,
+-	RADIO_2064_REG11F,
+-	RADIO_2064_REG00B,
+-	RADIO_2064_REG113,
+-	RADIO_2064_REG007,
+-	RADIO_2064_REG0FC,
+-	RADIO_2064_REG0FD,
+-	RADIO_2064_REG012,
+-	RADIO_2064_REG057,
+-	RADIO_2064_REG059,
+-	RADIO_2064_REG05C,
+-	RADIO_2064_REG078,
+-	RADIO_2064_REG092,
+-};
+-
+-static const
+-u16 tempsense_phy_regs[14] = {
+-	0x503,
+-	0x4a4,
+-	0x4d0,
+-	0x4d9,
+-	0x4da,
+-	0x4a6,
+-	0x938,
+-	0x939,
+-	0x4d8,
+-	0x4d0,
+-	0x4d7,
+-	0x4a5,
+-	0x40d,
+-	0x4a2,
+-};
+-
+-static const
+-u16 rxiq_cal_rf_reg[11] = {
+-	RADIO_2064_REG098,
+-	RADIO_2064_REG116,
+-	RADIO_2064_REG12C,
+-	RADIO_2064_REG06A,
+-	RADIO_2064_REG00B,
+-	RADIO_2064_REG01B,
+-	RADIO_2064_REG113,
+-	RADIO_2064_REG01D,
+-	RADIO_2064_REG114,
+-	RADIO_2064_REG02E,
+-	RADIO_2064_REG12A,
+-};
+-
+-static const
+-lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = {
+-	{1, 0, 0},
+-	{2, 0, 0},
+-	{3, 0, 0},
+-	{4, 0, 0},
+-	{5, 0, 0},
+-	{6, 0, 0},
+-	{7, 0, 0},
+-	{8, 0, 0},
+-	{9, 0, 0},
+-	{10, 0, 0},
+-	{11, 0, 0},
+-	{12, 0, 0},
+-	{13, 0, 0},
+-	{14, 0, 0},
+-	{34, 0, 0},
+-	{38, 0, 0},
+-	{42, 0, 0},
+-	{46, 0, 0},
+-	{36, 0, 0},
+-	{40, 0, 0},
+-	{44, 0, 0},
+-	{48, 0, 0},
+-	{52, 0, 0},
+-	{56, 0, 0},
+-	{60, 0, 0},
+-	{64, 0, 0},
+-	{100, 0, 0},
+-	{104, 0, 0},
+-	{108, 0, 0},
+-	{112, 0, 0},
+-	{116, 0, 0},
+-	{120, 0, 0},
+-	{124, 0, 0},
+-	{128, 0, 0},
+-	{132, 0, 0},
+-	{136, 0, 0},
+-	{140, 0, 0},
+-	{149, 0, 0},
+-	{153, 0, 0},
+-	{157, 0, 0},
+-	{161, 0, 0},
+-	{165, 0, 0},
+-	{184, 0, 0},
+-	{188, 0, 0},
+-	{192, 0, 0},
+-	{196, 0, 0},
+-	{200, 0, 0},
+-	{204, 0, 0},
+-	{208, 0, 0},
+-	{212, 0, 0},
+-	{216, 0, 0},
+-};
+-
+-static const u32 lcnphy_23bitgaincode_table[] = {
+-	0x200100,
+-	0x200200,
+-	0x200004,
+-	0x200014,
+-	0x200024,
+-	0x200034,
+-	0x200134,
+-	0x200234,
+-	0x200334,
+-	0x200434,
+-	0x200037,
+-	0x200137,
+-	0x200237,
+-	0x200337,
+-	0x200437,
+-	0x000035,
+-	0x000135,
+-	0x000235,
+-	0x000037,
+-	0x000137,
+-	0x000237,
+-	0x000337,
+-	0x00013f,
+-	0x00023f,
+-	0x00033f,
+-	0x00034f,
+-	0x00044f,
+-	0x00144f,
+-	0x00244f,
+-	0x00254f,
+-	0x00354f,
+-	0x00454f,
+-	0x00464f,
+-	0x01464f,
+-	0x02464f,
+-	0x03464f,
+-	0x04464f,
+-};
+-
+-static const s8 lcnphy_gain_table[] = {
+-	-16,
+-	-13,
+-	10,
+-	7,
+-	4,
+-	0,
+-	3,
+-	6,
+-	9,
+-	12,
+-	15,
+-	18,
+-	21,
+-	24,
+-	27,
+-	30,
+-	33,
+-	36,
+-	39,
+-	42,
+-	45,
+-	48,
+-	50,
+-	53,
+-	56,
+-	59,
+-	62,
+-	65,
+-	68,
+-	71,
+-	74,
+-	77,
+-	80,
+-	83,
+-	86,
+-	89,
+-	92,
+-};
+-
+-static const s8 lcnphy_gain_index_offset_for_rssi[] = {
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	7,
+-	8,
+-	7,
+-	7,
+-	6,
+-	7,
+-	7,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	4,
+-	3,
+-	3,
+-	3,
+-	3,
+-	3,
+-	3,
+-	4,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	2,
+-	-1,
+-	-2,
+-	-2,
+-	-2
+-};
+-
+-extern const u8 spur_tbl_rev0[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev1;
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[];
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
+-
+-typedef struct _chan_info_2064_lcnphy {
+-	uint chan;
+-	uint freq;
+-	u8 logen_buftune;
+-	u8 logen_rccr_tx;
+-	u8 txrf_mix_tune_ctrl;
+-	u8 pa_input_tune_g;
+-	u8 logen_rccr_rx;
+-	u8 pa_rxrf_lna1_freq_tune;
+-	u8 pa_rxrf_lna2_freq_tune;
+-	u8 rxrf_rxrf_spare1;
+-} chan_info_2064_lcnphy_t;
+-
+-static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = {
+-	{1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-	{14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80},
+-};
+-
+-lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = {
+-	{0x00, 0, 0, 0, 0},
+-	{0x01, 0x64, 0x64, 0, 0},
+-	{0x02, 0x20, 0x20, 0, 0},
+-	{0x03, 0x66, 0x66, 0, 0},
+-	{0x04, 0xf8, 0xf8, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0x10, 0x10, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0x37, 0x37, 0, 0},
+-	{0x0B, 0x6, 0x6, 0, 0},
+-	{0x0C, 0x55, 0x55, 0, 0},
+-	{0x0D, 0x8b, 0x8b, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0x5, 0x5, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0xe, 0xe, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0xb, 0xb, 0, 0},
+-	{0x14, 0x2, 0x2, 0, 0},
+-	{0x15, 0x12, 0x12, 0, 0},
+-	{0x16, 0x12, 0x12, 0, 0},
+-	{0x17, 0xc, 0xc, 0, 0},
+-	{0x18, 0xc, 0xc, 0, 0},
+-	{0x19, 0xc, 0xc, 0, 0},
+-	{0x1A, 0x8, 0x8, 0, 0},
+-	{0x1B, 0x2, 0x2, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0x1, 0x1, 0, 0},
+-	{0x1E, 0x12, 0x12, 0, 0},
+-	{0x1F, 0x6e, 0x6e, 0, 0},
+-	{0x20, 0x2, 0x2, 0, 0},
+-	{0x21, 0x23, 0x23, 0, 0},
+-	{0x22, 0x8, 0x8, 0, 0},
+-	{0x23, 0, 0, 0, 0},
+-	{0x24, 0, 0, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0x33, 0x33, 0, 0},
+-	{0x27, 0x55, 0x55, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x30, 0x30, 0, 0},
+-	{0x2A, 0xb, 0xb, 0, 0},
+-	{0x2B, 0x1b, 0x1b, 0, 0},
+-	{0x2C, 0x3, 0x3, 0, 0},
+-	{0x2D, 0x1b, 0x1b, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x20, 0x20, 0, 0},
+-	{0x30, 0xa, 0xa, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0x62, 0x62, 0, 0},
+-	{0x33, 0x19, 0x19, 0, 0},
+-	{0x34, 0x33, 0x33, 0, 0},
+-	{0x35, 0x77, 0x77, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x70, 0x70, 0, 0},
+-	{0x38, 0x3, 0x3, 0, 0},
+-	{0x39, 0xf, 0xf, 0, 0},
+-	{0x3A, 0x6, 0x6, 0, 0},
+-	{0x3B, 0xcf, 0xcf, 0, 0},
+-	{0x3C, 0x1a, 0x1a, 0, 0},
+-	{0x3D, 0x6, 0x6, 0, 0},
+-	{0x3E, 0x42, 0x42, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0xfb, 0xfb, 0, 0},
+-	{0x41, 0x9a, 0x9a, 0, 0},
+-	{0x42, 0x7a, 0x7a, 0, 0},
+-	{0x43, 0x29, 0x29, 0, 0},
+-	{0x44, 0, 0, 0, 0},
+-	{0x45, 0x8, 0x8, 0, 0},
+-	{0x46, 0xce, 0xce, 0, 0},
+-	{0x47, 0x27, 0x27, 0, 0},
+-	{0x48, 0x62, 0x62, 0, 0},
+-	{0x49, 0x6, 0x6, 0, 0},
+-	{0x4A, 0x58, 0x58, 0, 0},
+-	{0x4B, 0xf7, 0xf7, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0xb3, 0xb3, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0, 0, 0, 0},
+-	{0x51, 0x9, 0x9, 0, 0},
+-	{0x52, 0x5, 0x5, 0, 0},
+-	{0x53, 0x17, 0x17, 0, 0},
+-	{0x54, 0x38, 0x38, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0xb, 0xb, 0, 0},
+-	{0x58, 0, 0, 0, 0},
+-	{0x59, 0, 0, 0, 0},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0, 0, 0, 0},
+-	{0x5C, 0, 0, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x88, 0x88, 0, 0},
+-	{0x5F, 0xcc, 0xcc, 0, 0},
+-	{0x60, 0x74, 0x74, 0, 0},
+-	{0x61, 0x74, 0x74, 0, 0},
+-	{0x62, 0x74, 0x74, 0, 0},
+-	{0x63, 0x44, 0x44, 0, 0},
+-	{0x64, 0x77, 0x77, 0, 0},
+-	{0x65, 0x44, 0x44, 0, 0},
+-	{0x66, 0x77, 0x77, 0, 0},
+-	{0x67, 0x55, 0x55, 0, 0},
+-	{0x68, 0x77, 0x77, 0, 0},
+-	{0x69, 0x77, 0x77, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0x7f, 0x7f, 0, 0},
+-	{0x6C, 0x8, 0x8, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0x88, 0x88, 0, 0},
+-	{0x6F, 0x66, 0x66, 0, 0},
+-	{0x70, 0x66, 0x66, 0, 0},
+-	{0x71, 0x28, 0x28, 0, 0},
+-	{0x72, 0x55, 0x55, 0, 0},
+-	{0x73, 0x4, 0x4, 0, 0},
+-	{0x74, 0, 0, 0, 0},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0, 0, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0xd6, 0xd6, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0xb4, 0xb4, 0, 0},
+-	{0x84, 0x1, 0x1, 0, 0},
+-	{0x85, 0x20, 0x20, 0, 0},
+-	{0x86, 0x5, 0x5, 0, 0},
+-	{0x87, 0xff, 0xff, 0, 0},
+-	{0x88, 0x7, 0x7, 0, 0},
+-	{0x89, 0x77, 0x77, 0, 0},
+-	{0x8A, 0x77, 0x77, 0, 0},
+-	{0x8B, 0x77, 0x77, 0, 0},
+-	{0x8C, 0x77, 0x77, 0, 0},
+-	{0x8D, 0x8, 0x8, 0, 0},
+-	{0x8E, 0xa, 0xa, 0, 0},
+-	{0x8F, 0x8, 0x8, 0, 0},
+-	{0x90, 0x18, 0x18, 0, 0},
+-	{0x91, 0x5, 0x5, 0, 0},
+-	{0x92, 0x1f, 0x1f, 0, 0},
+-	{0x93, 0x10, 0x10, 0, 0},
+-	{0x94, 0x3, 0x3, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0xaa, 0xaa, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0x23, 0x23, 0, 0},
+-	{0x9A, 0x7, 0x7, 0, 0},
+-	{0x9B, 0xf, 0xf, 0, 0},
+-	{0x9C, 0x10, 0x10, 0, 0},
+-	{0x9D, 0x3, 0x3, 0, 0},
+-	{0x9E, 0x4, 0x4, 0, 0},
+-	{0x9F, 0x20, 0x20, 0, 0},
+-	{0xA0, 0, 0, 0, 0},
+-	{0xA1, 0, 0, 0, 0},
+-	{0xA2, 0, 0, 0, 0},
+-	{0xA3, 0, 0, 0, 0},
+-	{0xA4, 0x1, 0x1, 0, 0},
+-	{0xA5, 0x77, 0x77, 0, 0},
+-	{0xA6, 0x77, 0x77, 0, 0},
+-	{0xA7, 0x77, 0x77, 0, 0},
+-	{0xA8, 0x77, 0x77, 0, 0},
+-	{0xA9, 0x8c, 0x8c, 0, 0},
+-	{0xAA, 0x88, 0x88, 0, 0},
+-	{0xAB, 0x78, 0x78, 0, 0},
+-	{0xAC, 0x57, 0x57, 0, 0},
+-	{0xAD, 0x88, 0x88, 0, 0},
+-	{0xAE, 0, 0, 0, 0},
+-	{0xAF, 0x8, 0x8, 0, 0},
+-	{0xB0, 0x88, 0x88, 0, 0},
+-	{0xB1, 0, 0, 0, 0},
+-	{0xB2, 0x1b, 0x1b, 0, 0},
+-	{0xB3, 0x3, 0x3, 0, 0},
+-	{0xB4, 0x24, 0x24, 0, 0},
+-	{0xB5, 0x3, 0x3, 0, 0},
+-	{0xB6, 0x1b, 0x1b, 0, 0},
+-	{0xB7, 0x24, 0x24, 0, 0},
+-	{0xB8, 0x3, 0x3, 0, 0},
+-	{0xB9, 0, 0, 0, 0},
+-	{0xBA, 0xaa, 0xaa, 0, 0},
+-	{0xBB, 0, 0, 0, 0},
+-	{0xBC, 0x4, 0x4, 0, 0},
+-	{0xBD, 0, 0, 0, 0},
+-	{0xBE, 0x8, 0x8, 0, 0},
+-	{0xBF, 0x11, 0x11, 0, 0},
+-	{0xC0, 0, 0, 0, 0},
+-	{0xC1, 0, 0, 0, 0},
+-	{0xC2, 0x62, 0x62, 0, 0},
+-	{0xC3, 0x1e, 0x1e, 0, 0},
+-	{0xC4, 0x33, 0x33, 0, 0},
+-	{0xC5, 0x37, 0x37, 0, 0},
+-	{0xC6, 0, 0, 0, 0},
+-	{0xC7, 0x70, 0x70, 0, 0},
+-	{0xC8, 0x1e, 0x1e, 0, 0},
+-	{0xC9, 0x6, 0x6, 0, 0},
+-	{0xCA, 0x4, 0x4, 0, 0},
+-	{0xCB, 0x2f, 0x2f, 0, 0},
+-	{0xCC, 0xf, 0xf, 0, 0},
+-	{0xCD, 0, 0, 0, 0},
+-	{0xCE, 0xff, 0xff, 0, 0},
+-	{0xCF, 0x8, 0x8, 0, 0},
+-	{0xD0, 0x3f, 0x3f, 0, 0},
+-	{0xD1, 0x3f, 0x3f, 0, 0},
+-	{0xD2, 0x3f, 0x3f, 0, 0},
+-	{0xD3, 0, 0, 0, 0},
+-	{0xD4, 0, 0, 0, 0},
+-	{0xD5, 0, 0, 0, 0},
+-	{0xD6, 0xcc, 0xcc, 0, 0},
+-	{0xD7, 0, 0, 0, 0},
+-	{0xD8, 0x8, 0x8, 0, 0},
+-	{0xD9, 0x8, 0x8, 0, 0},
+-	{0xDA, 0x8, 0x8, 0, 0},
+-	{0xDB, 0x11, 0x11, 0, 0},
+-	{0xDC, 0, 0, 0, 0},
+-	{0xDD, 0x87, 0x87, 0, 0},
+-	{0xDE, 0x88, 0x88, 0, 0},
+-	{0xDF, 0x8, 0x8, 0, 0},
+-	{0xE0, 0x8, 0x8, 0, 0},
+-	{0xE1, 0x8, 0x8, 0, 0},
+-	{0xE2, 0, 0, 0, 0},
+-	{0xE3, 0, 0, 0, 0},
+-	{0xE4, 0, 0, 0, 0},
+-	{0xE5, 0xf5, 0xf5, 0, 0},
+-	{0xE6, 0x30, 0x30, 0, 0},
+-	{0xE7, 0x1, 0x1, 0, 0},
+-	{0xE8, 0, 0, 0, 0},
+-	{0xE9, 0xff, 0xff, 0, 0},
+-	{0xEA, 0, 0, 0, 0},
+-	{0xEB, 0, 0, 0, 0},
+-	{0xEC, 0x22, 0x22, 0, 0},
+-	{0xED, 0, 0, 0, 0},
+-	{0xEE, 0, 0, 0, 0},
+-	{0xEF, 0, 0, 0, 0},
+-	{0xF0, 0x3, 0x3, 0, 0},
+-	{0xF1, 0x1, 0x1, 0, 0},
+-	{0xF2, 0, 0, 0, 0},
+-	{0xF3, 0, 0, 0, 0},
+-	{0xF4, 0, 0, 0, 0},
+-	{0xF5, 0, 0, 0, 0},
+-	{0xF6, 0, 0, 0, 0},
+-	{0xF7, 0x6, 0x6, 0, 0},
+-	{0xF8, 0, 0, 0, 0},
+-	{0xF9, 0, 0, 0, 0},
+-	{0xFA, 0x40, 0x40, 0, 0},
+-	{0xFB, 0, 0, 0, 0},
+-	{0xFC, 0x1, 0x1, 0, 0},
+-	{0xFD, 0x80, 0x80, 0, 0},
+-	{0xFE, 0x2, 0x2, 0, 0},
+-	{0xFF, 0x10, 0x10, 0, 0},
+-	{0x100, 0x2, 0x2, 0, 0},
+-	{0x101, 0x1e, 0x1e, 0, 0},
+-	{0x102, 0x1e, 0x1e, 0, 0},
+-	{0x103, 0, 0, 0, 0},
+-	{0x104, 0x1f, 0x1f, 0, 0},
+-	{0x105, 0, 0x8, 0, 1},
+-	{0x106, 0x2a, 0x2a, 0, 0},
+-	{0x107, 0xf, 0xf, 0, 0},
+-	{0x108, 0, 0, 0, 0},
+-	{0x109, 0, 0, 0, 0},
+-	{0x10A, 0, 0, 0, 0},
+-	{0x10B, 0, 0, 0, 0},
+-	{0x10C, 0, 0, 0, 0},
+-	{0x10D, 0, 0, 0, 0},
+-	{0x10E, 0, 0, 0, 0},
+-	{0x10F, 0, 0, 0, 0},
+-	{0x110, 0, 0, 0, 0},
+-	{0x111, 0, 0, 0, 0},
+-	{0x112, 0, 0, 0, 0},
+-	{0x113, 0, 0, 0, 0},
+-	{0x114, 0, 0, 0, 0},
+-	{0x115, 0, 0, 0, 0},
+-	{0x116, 0, 0, 0, 0},
+-	{0x117, 0, 0, 0, 0},
+-	{0x118, 0, 0, 0, 0},
+-	{0x119, 0, 0, 0, 0},
+-	{0x11A, 0, 0, 0, 0},
+-	{0x11B, 0, 0, 0, 0},
+-	{0x11C, 0x1, 0x1, 0, 0},
+-	{0x11D, 0, 0, 0, 0},
+-	{0x11E, 0, 0, 0, 0},
+-	{0x11F, 0, 0, 0, 0},
+-	{0x120, 0, 0, 0, 0},
+-	{0x121, 0, 0, 0, 0},
+-	{0x122, 0x80, 0x80, 0, 0},
+-	{0x123, 0, 0, 0, 0},
+-	{0x124, 0xf8, 0xf8, 0, 0},
+-	{0x125, 0, 0, 0, 0},
+-	{0x126, 0, 0, 0, 0},
+-	{0x127, 0, 0, 0, 0},
+-	{0x128, 0, 0, 0, 0},
+-	{0x129, 0, 0, 0, 0},
+-	{0x12A, 0, 0, 0, 0},
+-	{0x12B, 0, 0, 0, 0},
+-	{0x12C, 0, 0, 0, 0},
+-	{0x12D, 0, 0, 0, 0},
+-	{0x12E, 0, 0, 0, 0},
+-	{0x12F, 0, 0, 0, 0},
+-	{0x130, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-#define LCNPHY_NUM_DIG_FILT_COEFFS 16
+-#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13
+-
+-u16
+-    LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK]
+-    [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+-	{0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64,
+-	 128, 64,},
+-	{1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93,
+-	 167, 93,},
+-	{2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64,
+-	 128, 64,},
+-	{3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760,
+-	 170, 340, 170,},
+-	{20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760,
+-	 256, 185, 256,},
+-	{21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760,
+-	 256, 273, 256,},
+-	{22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760,
+-	 256, 352, 256,},
+-	{23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760,
+-	 128, 233, 128,},
+-	{24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256,
+-	 1881, 256,},
+-	{25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256,
+-	 1881, 256,},
+-	{26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128,
+-	 384, 288,},
+-	{27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864,
+-	 128, 384, 288,},
+-	{30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760,
+-	 170, 340, 170,},
+-};
+-
+-#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3
+-u16
+-    LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM]
+-    [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = {
+-	{0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0,
+-	 0x278, 0xfea0, 0x80, 0x100, 0x80,},
+-	{1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50,
+-	 750, 0xFE2B, 212, 0xFFCE, 212,},
+-	{2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
+-	 0xFEF2, 128, 0xFFE2, 128}
+-};
+-
+-#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \
+-	mod_phy_reg(pi, 0x4a4, \
+-		(0x1ff << 0), \
+-		(u16)(idx) << 0)
+-
+-#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \
+-	mod_phy_reg(pi, 0x4a5, \
+-		(0x7 << 8), \
+-		(u16)(npt) << 8)
+-
+-#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \
+-	(read_phy_reg((pi), 0x4a4) & \
+-			((0x1 << 15) | \
+-			(0x1 << 14) | \
+-			(0x1 << 13)))
+-
+-#define wlc_lcnphy_get_tx_pwr_npt(pi) \
+-	((read_phy_reg(pi, 0x4a5) & \
+-		(0x7 << 8)) >> \
+-		8)
+-
+-#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \
+-	(read_phy_reg(pi, 0x473) & 0x1ff)
+-
+-#define wlc_lcnphy_get_target_tx_pwr(pi) \
+-	((read_phy_reg(pi, 0x4a7) & \
+-		(0xff << 0)) >> \
+-		0)
+-
+-#define wlc_lcnphy_set_target_tx_pwr(pi, target) \
+-	mod_phy_reg(pi, 0x4a7, \
+-		(0xff << 0), \
+-		(u16)(target) << 0)
+-
+-#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20))
+-#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000))
+-
+-#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f)))
+-#define FIXED_TXPWR 78
+-#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val))
+-
+-static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor,
+-				      u8 precision);
+-static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+-						   u16 ext_lna, u16 trsw,
+-						   u16 biq2, u16 biq1,
+-						   u16 tia, u16 lna2,
+-						   u16 lna1);
+-static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi);
+-static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain);
+-static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx);
+-static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0);
+-static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi);
+-static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains);
+-static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable);
+-static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi);
+-static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable);
+-static void wlc_lcnphy_set_tx_gain(phy_info_t *pi,
+-				   lcnphy_txgains_t *target_gains);
+-static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, u16 num_samps,
+-				 u8 wait_time, lcnphy_iq_est_t *iq_est);
+-static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps);
+-static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi);
+-static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode);
+-extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi);
+-static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi,
+-						    u8 channel);
+-
+-static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi,
+-					  const lcnphy_tx_gain_tbl_entry *g);
+-
+-static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo,
+-				u16 thresh, s16 *ptr, int mode);
+-static int wlc_lcnphy_calc_floor(s16 coeff, int type);
+-static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi,
+-					u16 *values_to_save);
+-static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi,
+-						u16 *values_to_save);
+-static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x,
+-			      s16 coeff_y);
+-static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type);
+-static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type,
+-			  int num_levels, int step_size_lg2);
+-static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi);
+-
+-static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi,
+-					   chanspec_t chanspec);
+-static void wlc_lcnphy_agc_temp_init(phy_info_t *pi);
+-static void wlc_lcnphy_temp_adj(phy_info_t *pi);
+-static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi);
+-static void wlc_lcnphy_baseband_init(phy_info_t *pi);
+-static void wlc_lcnphy_radio_init(phy_info_t *pi);
+-static void wlc_lcnphy_rc_cal(phy_info_t *pi);
+-static void wlc_lcnphy_rcal(phy_info_t *pi);
+-static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable);
+-static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm,
+-					 s16 filt_type);
+-static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b);
+-
+-void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti)
+-{
+-	wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456);
+-}
+-
+-void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti)
+-{
+-	wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456);
+-}
+-
+-static void
+-wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id,
+-			     const void *tbl_ptr, u32 tbl_len,
+-			     u32 tbl_width, u32 tbl_offset)
+-{
+-	phytbl_info_t tab;
+-	tab.tbl_id = tbl_id;
+-	tab.tbl_ptr = tbl_ptr;
+-	tab.tbl_len = tbl_len;
+-	tab.tbl_width = tbl_width;
+-	tab.tbl_offset = tbl_offset;
+-	wlc_lcnphy_read_table(pi, &tab);
+-}
+-
+-static void
+-wlc_lcnphy_common_write_table(phy_info_t *pi, u32 tbl_id,
+-			      const void *tbl_ptr, u32 tbl_len,
+-			      u32 tbl_width, u32 tbl_offset)
+-{
+-
+-	phytbl_info_t tab;
+-	tab.tbl_id = tbl_id;
+-	tab.tbl_ptr = tbl_ptr;
+-	tab.tbl_len = tbl_len;
+-	tab.tbl_width = tbl_width;
+-	tab.tbl_offset = tbl_offset;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-static u32
+-wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
+-{
+-	u32 quotient, remainder, roundup, rbit;
+-
+-	quotient = dividend / divisor;
+-	remainder = dividend % divisor;
+-	rbit = divisor & 1;
+-	roundup = (divisor >> 1) + rbit;
+-
+-	while (precision--) {
+-		quotient <<= 1;
+-		if (remainder >= roundup) {
+-			quotient++;
+-			remainder = ((remainder - roundup) << 1) + rbit;
+-		} else {
+-			remainder <<= 1;
+-		}
+-	}
+-
+-	if (remainder >= roundup)
+-		quotient++;
+-
+-	return quotient;
+-}
+-
+-static int wlc_lcnphy_calc_floor(s16 coeff_x, int type)
+-{
+-	int k;
+-	k = 0;
+-	if (type == 0) {
+-		if (coeff_x < 0) {
+-			k = (coeff_x - 1) / 2;
+-		} else {
+-			k = coeff_x / 2;
+-		}
+-	}
+-	if (type == 1) {
+-		if ((coeff_x + 1) < 0)
+-			k = (coeff_x) / 2;
+-		else
+-			k = (coeff_x + 1) / 2;
+-	}
+-	return k;
+-}
+-
+-s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi)
+-{
+-	s8 index;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (txpwrctrl_off(pi))
+-		index = pi_lcn->lcnphy_current_index;
+-	else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		index =
+-		    (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi)
+-			    / 2);
+-	else
+-		index = pi_lcn->lcnphy_current_index;
+-	return index;
+-}
+-
+-static u32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, u16 nsamples)
+-{
+-	lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+-
+-	if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est))
+-		return 0;
+-	return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
+-}
+-
+-void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel)
+-{
+-	u16 afectrlovr, afectrlovrval;
+-	afectrlovr = read_phy_reg(pi, 0x43b);
+-	afectrlovrval = read_phy_reg(pi, 0x43c);
+-	if (channel != 0) {
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1);
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4);
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6);
+-
+-		write_phy_reg(pi, 0x44b, 0xffff);
+-		wlc_lcnphy_tx_pu(pi, 1);
+-
+-		mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8);
+-
+-		or_phy_reg(pi, 0x6da, 0x0080);
+-
+-		or_phy_reg(pi, 0x00a, 0x228);
+-	} else {
+-		and_phy_reg(pi, 0x00a, ~(0x228));
+-
+-		and_phy_reg(pi, 0x6da, 0xFF7F);
+-		write_phy_reg(pi, 0x43b, afectrlovr);
+-		write_phy_reg(pi, 0x43c, afectrlovrval);
+-	}
+-}
+-
+-static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi)
+-{
+-	u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr;
+-
+-	save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c);
+-	save_AfeCtrlOvr = read_phy_reg(pi, 0x43b);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe);
+-
+-	write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal);
+-	write_phy_reg(pi, 0x43b, save_AfeCtrlOvr);
+-}
+-
+-static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable)
+-{
+-	if (enable) {
+-		write_phy_reg(pi, 0x942, 0x7);
+-		write_phy_reg(pi, 0x93b, ((1 << 13) + 23));
+-		write_phy_reg(pi, 0x93c, ((1 << 13) + 1989));
+-
+-		write_phy_reg(pi, 0x44a, 0x084);
+-		write_phy_reg(pi, 0x44a, 0x080);
+-		write_phy_reg(pi, 0x6d3, 0x2222);
+-		write_phy_reg(pi, 0x6d3, 0x2220);
+-	} else {
+-		write_phy_reg(pi, 0x942, 0x0);
+-		write_phy_reg(pi, 0x93b, ((0 << 13) + 23));
+-		write_phy_reg(pi, 0x93c, ((0 << 13) + 1989));
+-	}
+-	wlapi_switch_macfreq(pi->sh->physhim, enable);
+-}
+-
+-void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	u8 channel = CHSPEC_CHANNEL(chanspec);
+-
+-	wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+-
+-	wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-
+-	if (!NORADIO_ENAB(pi->pubpi)) {
+-		wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
+-		udelay(1000);
+-	}
+-
+-	wlc_lcnphy_toggle_afe_pwdn(pi);
+-
+-	write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
+-	write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
+-
+-	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+-
+-		wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
+-	} else {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+-
+-		wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
+-	}
+-
+-	wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
+-
+-}
+-
+-static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain)
+-{
+-	u16 dac_ctrl;
+-
+-	dac_ctrl = (read_phy_reg(pi, 0x439) >> 0);
+-	dac_ctrl = dac_ctrl & 0xc7f;
+-	dac_ctrl = dac_ctrl | (dac_gain << 7);
+-	mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0);
+-
+-}
+-
+-static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable)
+-{
+-	u16 bit = bEnable ? 1 : 0;
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7);
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6);
+-}
+-
+-static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi)
+-{
+-	u16 pa_gain;
+-
+-	pa_gain = (read_phy_reg(pi, 0x4fb) &
+-		   LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >>
+-	    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT;
+-
+-	return pa_gain;
+-}
+-
+-static void
+-wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains)
+-{
+-	u16 pa_gain = wlc_lcnphy_get_pa_gain(pi);
+-
+-	mod_phy_reg(pi, 0x4b5,
+-		    (0xffff << 0),
+-		    ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+-		    0);
+-	mod_phy_reg(pi, 0x4fb,
+-		    (0x7fff << 0),
+-		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+-
+-	mod_phy_reg(pi, 0x4fc,
+-		    (0xffff << 0),
+-		    ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) <<
+-		    0);
+-	mod_phy_reg(pi, 0x4fd,
+-		    (0x7fff << 0),
+-		    ((target_gains->pad_gain) | (pa_gain << 8)) << 0);
+-
+-	wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-}
+-
+-static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0)
+-{
+-	u16 m0m1 = (u16) m0 << 8;
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = &m0m1;
+-	tab.tbl_len = 1;
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_offset = 87;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi)
+-{
+-	u32 data_buf[64];
+-	phytbl_info_t tab;
+-
+-	memset(data_buf, 0, sizeof(data_buf));
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = data_buf;
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-
+-		tab.tbl_len = 30;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	tab.tbl_len = 64;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-typedef enum {
+-	LCNPHY_TSSI_PRE_PA,
+-	LCNPHY_TSSI_POST_PA,
+-	LCNPHY_TSSI_EXT
+-} lcnphy_tssi_mode_t;
+-
+-static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos)
+-{
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6);
+-
+-	if (LCNPHY_TSSI_POST_PA == pos) {
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2);
+-
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3);
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
+-			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+-		}
+-	} else {
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
+-
+-		mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3);
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+-			mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
+-		}
+-	}
+-	mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14);
+-
+-	if (LCNPHY_TSSI_EXT == pos) {
+-		write_radio_reg(pi, RADIO_2064_REG07F, 1);
+-		mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2);
+-		mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7);
+-		mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3);
+-	}
+-}
+-
+-static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi)
+-{
+-	u16 N1, N2, N3, N4, N5, N6, N;
+-	N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0))
+-	      >> 0);
+-	N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12))
+-		   >> 12);
+-	N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0))
+-	      >> 0);
+-	N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8))
+-		   >> 8);
+-	N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0))
+-	      >> 0);
+-	N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8))
+-		   >> 8);
+-	N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80;
+-	if (N < 1600)
+-		N = 1600;
+-	return N;
+-}
+-
+-static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi)
+-{
+-	u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	auxpga_vmid =
+-	    (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf;
+-	auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4;
+-	auxpga_gain_temp = 2;
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3);
+-
+-	mod_phy_reg(pi, 0x4db,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x4dc,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x40a,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12));
+-
+-	mod_phy_reg(pi, 0x40b,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+-
+-	mod_phy_reg(pi, 0x40c,
+-		    (0x3ff << 0) |
+-		    (0x7 << 12),
+-		    (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
+-
+-	mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
+-}
+-
+-static void wlc_lcnphy_tssi_setup(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 rfseq, ind;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &ind;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 0;
+-	for (ind = 0; ind < 128; ind++) {
+-		wlc_lcnphy_write_table(pi, &tab);
+-		tab.tbl_offset++;
+-	}
+-	tab.tbl_offset = 704;
+-	for (ind = 0; ind < 128; ind++) {
+-		wlc_lcnphy_write_table(pi, &tab);
+-		tab.tbl_offset++;
+-	}
+-	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
+-
+-	wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8);
+-
+-	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6);
+-
+-	mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0);
+-
+-	wlc_lcnphy_clear_tx_power_offsets(pi);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0);
+-
+-	mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
+-		mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
+-	} else {
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+-		mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xc);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
+-	} else {
+-		if (CHSPEC_IS2G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1);
+-	}
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1);
+-	else
+-		mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3);
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-		mod_phy_reg(pi, 0x4d7,
+-			    (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12);
+-	}
+-
+-	rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &rfseq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 6;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
+-
+-	wlc_lcnphy_pwrctrl_rssiparams(pi);
+-}
+-
+-void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi)
+-{
+-	u16 tx_cnt, tx_total, npt;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	tx_total = wlc_lcnphy_total_tx_frames(pi);
+-	tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt;
+-	npt = wlc_lcnphy_get_tx_pwr_npt(pi);
+-
+-	if (tx_cnt > (1 << npt)) {
+-
+-		pi_lcn->lcnphy_tssi_tx_cnt = tx_total;
+-
+-		pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+-		pi_lcn->lcnphy_tssi_npt = npt;
+-
+-	}
+-}
+-
+-s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1)
+-{
+-	s32 a, b, p;
+-
+-	a = 32768 + (a1 * tssi);
+-	b = (1024 * b0) + (64 * b1 * tssi);
+-	p = ((2 * b) + a) / (2 * a);
+-
+-	return p;
+-}
+-
+-static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi)
+-{
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313;
+-	pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT;
+-}
+-
+-void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM +
+-			  WLC_NUM_RATES_MCS_1_STREAM];
+-	uint i, j;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) {
+-
+-		if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM)
+-			j = TXP_FIRST_MCS_20_SISO;
+-
+-		rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j]));
+-	}
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = ARRAY_SIZE(rate_table);
+-	tab.tbl_ptr = rate_table;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) {
+-		wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min);
+-
+-		wlc_lcnphy_txpower_reset_npt(pi);
+-	}
+-}
+-
+-static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index)
+-{
+-	u32 cck_offset[4] = { 22, 22, 22, 22 };
+-	u32 ofdm_offset, reg_offset_cck;
+-	int i;
+-	u16 index2;
+-	phytbl_info_t tab;
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		return;
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14);
+-
+-	or_phy_reg(pi, 0x6da, 0x0040);
+-
+-	reg_offset_cck = 0;
+-	for (i = 0; i < 4; i++)
+-		cck_offset[i] -= reg_offset_cck;
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 4;
+-	tab.tbl_ptr = cck_offset;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-	wlc_lcnphy_write_table(pi, &tab);
+-	ofdm_offset = 0;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &ofdm_offset;
+-	for (i = 836; i < 862; i++) {
+-		tab.tbl_offset = i;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13);
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6);
+-
+-	mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15);
+-
+-	index2 = (u16) (index * 2);
+-	mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+-
+-	mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4);
+-
+-}
+-
+-static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi)
+-{
+-	s8 index, delta_brd, delta_temp, new_index, tempcorrx;
+-	s16 manp, meas_temp, temp_diff;
+-	bool neg = 0;
+-	u16 temp;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi))
+-		return pi_lcn->lcnphy_current_index;
+-
+-	index = FIXED_TXPWR;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return index;
+-
+-	if (pi_lcn->lcnphy_tempsense_slope == 0) {
+-		return index;
+-	}
+-	temp = (u16) wlc_lcnphy_tempsense(pi, 0);
+-	meas_temp = LCNPHY_TEMPSENSE(temp);
+-
+-	if (pi->tx_power_min != 0) {
+-		delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min);
+-	} else {
+-		delta_brd = 0;
+-	}
+-
+-	manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense);
+-	temp_diff = manp - meas_temp;
+-	if (temp_diff < 0) {
+-
+-		neg = 1;
+-
+-		temp_diff = -temp_diff;
+-	}
+-
+-	delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192),
+-						    (u32) (pi_lcn->
+-							      lcnphy_tempsense_slope
+-							      * 10), 0);
+-	if (neg)
+-		delta_temp = -delta_temp;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 3
+-	    && LCNREV_IS(pi->pubpi.phy_rev, 0))
+-		delta_temp = 0;
+-	if (pi_lcn->lcnphy_tempcorrx > 31)
+-		tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64);
+-	else
+-		tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx;
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		tempcorrx = 4;
+-	new_index =
+-	    index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr;
+-	new_index += tempcorrx;
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		index = 127;
+-	if (new_index < 0 || new_index > 126) {
+-		return index;
+-	}
+-	return new_index;
+-}
+-
+-static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode)
+-{
+-
+-	u16 current_mode = mode;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
+-	    mode == LCNPHY_TX_PWR_CTRL_HW)
+-		current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED;
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+-	    mode == LCNPHY_TX_PWR_CTRL_TEMPBASED)
+-		current_mode = LCNPHY_TX_PWR_CTRL_HW;
+-	return current_mode;
+-}
+-
+-void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode)
+-{
+-	u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	s8 index;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
+-	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 6),
+-		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6);
+-
+-	mod_phy_reg(pi, 0x6a3, (0x1 << 4),
+-		    ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4);
+-
+-	if (old_mode != mode) {
+-		if (LCNPHY_TX_PWR_CTRL_HW == old_mode) {
+-
+-			wlc_lcnphy_tx_pwr_update_npt(pi);
+-
+-			wlc_lcnphy_clear_tx_power_offsets(pi);
+-		}
+-		if (LCNPHY_TX_PWR_CTRL_HW == mode) {
+-
+-			wlc_lcnphy_txpower_recalc_target(pi);
+-
+-			wlc_lcnphy_set_start_tx_pwr_idx(pi,
+-							pi_lcn->
+-							lcnphy_tssi_idx);
+-			wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt);
+-			mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0);
+-
+-			pi_lcn->lcnphy_tssi_tx_cnt =
+-			    wlc_lcnphy_total_tx_frames(pi);
+-
+-			wlc_lcnphy_disable_tx_gain_override(pi);
+-			pi_lcn->lcnphy_tx_power_idx_override = -1;
+-		} else
+-			wlc_lcnphy_enable_tx_gain_override(pi);
+-
+-		mod_phy_reg(pi, 0x4a4,
+-			    ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode);
+-		if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) {
+-			index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+-			wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index);
+-			pi_lcn->lcnphy_current_index = (s8)
+-			    ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+-		}
+-	}
+-}
+-
+-static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi)
+-{
+-	uint delay_count = 0;
+-
+-	while (wlc_lcnphy_iqcal_active(pi)) {
+-		udelay(100);
+-		delay_count++;
+-
+-		if (delay_count > (10 * 500))
+-			break;
+-	}
+-
+-	return (0 == wlc_lcnphy_iqcal_active(pi));
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi,
+-		       lcnphy_txgains_t *target_gains,
+-		       lcnphy_cal_mode_t cal_mode, bool keep_tone)
+-{
+-
+-	lcnphy_txgains_t cal_gains, temp_gains;
+-	u16 hash;
+-	u8 band_idx;
+-	int j;
+-	u16 ncorr_override[5];
+-	u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+-	};
+-
+-	u16 commands_fullcal[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+-
+-	u16 commands_recal[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 };
+-
+-	u16 command_nums_fullcal[] = {
+-		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+-
+-	u16 command_nums_recal[] = {
+-		0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 };
+-	u16 *command_nums = command_nums_fullcal;
+-
+-	u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start;
+-	u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2;
+-	u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl;
+-	bool tx_gain_override_old;
+-	lcnphy_txgains_t old_gains;
+-	uint i, n_cal_cmds = 0, n_cal_start = 0;
+-	u16 *values_to_save;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
+-	if (NULL == values_to_save) {
+-		return;
+-	}
+-
+-	save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+-	save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-
+-	or_phy_reg(pi, 0x6da, 0x40);
+-	or_phy_reg(pi, 0x6db, 0x3);
+-
+-	switch (cal_mode) {
+-	case LCNPHY_CAL_FULL:
+-		start_coeffs = syst_coeffs;
+-		cal_cmds = commands_fullcal;
+-		n_cal_cmds = ARRAY_SIZE(commands_fullcal);
+-		break;
+-
+-	case LCNPHY_CAL_RECAL:
+-		start_coeffs = syst_coeffs;
+-		cal_cmds = commands_recal;
+-		n_cal_cmds = ARRAY_SIZE(commands_recal);
+-		command_nums = command_nums_recal;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      start_coeffs, 11, 16, 64);
+-
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-	mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3);
+-
+-	tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db);
+-
+-	mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0);
+-
+-	mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12);
+-
+-	wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save);
+-
+-	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-	if (tx_gain_override_old)
+-		wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-
+-	if (!target_gains) {
+-		if (!tx_gain_override_old)
+-			wlc_lcnphy_set_tx_pwr_by_index(pi,
+-						       pi_lcn->lcnphy_tssi_idx);
+-		wlc_lcnphy_get_tx_gain(pi, &temp_gains);
+-		target_gains = &temp_gains;
+-	}
+-
+-	hash = (target_gains->gm_gain << 8) |
+-	    (target_gains->pga_gain << 4) | (target_gains->pad_gain);
+-
+-	band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+-
+-	cal_gains = *target_gains;
+-	memset(ncorr_override, 0, sizeof(ncorr_override));
+-	for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) {
+-		if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) {
+-			cal_gains.gm_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][1];
+-			cal_gains.pga_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][2];
+-			cal_gains.pad_gain =
+-			    tbl_iqcal_gainparams_lcnphy[band_idx][j][3];
+-			memcpy(ncorr_override,
+-			       &tbl_iqcal_gainparams_lcnphy[band_idx][j][3],
+-			       sizeof(ncorr_override));
+-			break;
+-		}
+-	}
+-
+-	wlc_lcnphy_set_tx_gain(pi, &cal_gains);
+-
+-	write_phy_reg(pi, 0x453, 0xaa9);
+-	write_phy_reg(pi, 0x93d, 0xc0);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      (const void *)
+-				      lcnphy_iqcal_loft_gainladder,
+-				      ARRAY_SIZE(lcnphy_iqcal_loft_gainladder),
+-				      16, 0);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      (const void *)lcnphy_iqcal_ir_gainladder,
+-				      ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16,
+-				      32);
+-
+-	if (pi->phy_tx_tone_freq) {
+-
+-		wlc_lcnphy_stop_tx_tone(pi);
+-		udelay(5);
+-		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+-	} else {
+-		wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1);
+-	}
+-
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-
+-	for (i = n_cal_start; i < n_cal_cmds; i++) {
+-		u16 zero_diq = 0;
+-		u16 best_coeffs[11];
+-		u16 command_num;
+-
+-		cal_type = (cal_cmds[i] & 0x0f00) >> 8;
+-
+-		command_num = command_nums[i];
+-		if (ncorr_override[cal_type])
+-			command_num =
+-			    ncorr_override[cal_type] << 8 | (command_num &
+-							     0xff);
+-
+-		write_phy_reg(pi, 0x452, command_num);
+-
+-		if ((cal_type == 3) || (cal_type == 4)) {
+-
+-			wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						     &diq_start, 1, 16, 69);
+-
+-			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						      &zero_diq, 1, 16, 69);
+-		}
+-
+-		write_phy_reg(pi, 0x451, cal_cmds[i]);
+-
+-		if (!wlc_lcnphy_iqcal_wait(pi)) {
+-
+-			goto cleanup;
+-		}
+-
+-		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					     best_coeffs,
+-					     ARRAY_SIZE(best_coeffs), 16, 96);
+-		wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					      best_coeffs,
+-					      ARRAY_SIZE(best_coeffs), 16, 64);
+-
+-		if ((cal_type == 3) || (cal_type == 4)) {
+-			wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-						      &diq_start, 1, 16, 69);
+-		}
+-		wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-					     pi_lcn->lcnphy_cal_results.
+-					     txiqlocal_bestcoeffs,
+-					     ARRAY_SIZE(pi_lcn->
+-						       lcnphy_cal_results.
+-						       txiqlocal_bestcoeffs),
+-					     16, 96);
+-	}
+-
+-	wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				     pi_lcn->lcnphy_cal_results.
+-				     txiqlocal_bestcoeffs,
+-				     ARRAY_SIZE(pi_lcn->lcnphy_cal_results.
+-					       txiqlocal_bestcoeffs), 16, 96);
+-	pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true;
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      &pi_lcn->lcnphy_cal_results.
+-				      txiqlocal_bestcoeffs[0], 4, 16, 80);
+-
+-	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
+-				      &pi_lcn->lcnphy_cal_results.
+-				      txiqlocal_bestcoeffs[5], 2, 16, 85);
+-
+- cleanup:
+-	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save);
+-	kfree(values_to_save);
+-
+-	if (!keep_tone)
+-		wlc_lcnphy_stop_tx_tone(pi);
+-
+-	write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2);
+-
+-	write_phy_reg(pi, 0x453, 0);
+-
+-	if (tx_gain_override_old)
+-		wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old);
+-
+-	write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl);
+-	write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl);
+-
+-}
+-
+-static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi)
+-{
+-	bool suspend, tx_gain_override_old;
+-	lcnphy_txgains_t old_gains;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
+-	    idleTssi0_regvalue_2C;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112);
+-	u16 SAVE_jtag_bb_afe_switch =
+-	    read_radio_reg(pi, RADIO_2064_REG007) & 1;
+-	u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
+-	u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
+-	idleTssi = read_phy_reg(pi, 0x4ab);
+-	suspend =
+-	    (0 ==
+-	     (R_REG(&((phy_info_t *) pi)->regs->maccontrol) &
+-	      MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-	wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+-	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
+-	wlc_lcnphy_tssi_setup(pi);
+-	wlc_phy_do_dummy_tx(pi, true, OFF);
+-	idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+-		    >> 0);
+-
+-	idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0))
+-			>> 0);
+-
+-	if (idleTssi0_2C >= 256)
+-		idleTssi0_OB = idleTssi0_2C - 256;
+-	else
+-		idleTssi0_OB = idleTssi0_2C + 256;
+-
+-	idleTssi0_regvalue_OB = idleTssi0_OB;
+-	if (idleTssi0_regvalue_OB >= 256)
+-		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256;
+-	else
+-		idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256;
+-	mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
+-
+-	wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
+-	wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-
+-	write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en);
+-	mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode)
+-{
+-	bool suspend;
+-	u16 save_txpwrCtrlEn;
+-	u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
+-	u16 auxpga_vmid;
+-	phytbl_info_t tab;
+-	u32 val;
+-	u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025,
+-	    save_reg112;
+-	u16 values_to_save[14];
+-	s8 index;
+-	int i;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	udelay(999);
+-
+-	save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007);
+-	save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF);
+-	save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F);
+-	save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005);
+-	save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025);
+-	save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112);
+-
+-	for (i = 0; i < 14; i++)
+-		values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-	index = pi_lcn->lcnphy_current_index;
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 127);
+-	mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1);
+-	mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4);
+-	mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2);
+-	mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5);
+-
+-	mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12);
+-
+-	mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8);
+-
+-	mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0);
+-
+-	mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8);
+-
+-	mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12);
+-
+-	mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12);
+-
+-	mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13);
+-
+-	mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15);
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xC);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3);
+-
+-	mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2);
+-
+-	mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12);
+-
+-	val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi);
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &val;
+-	tab.tbl_offset = 6;
+-	wlc_lcnphy_write_table(pi, &tab);
+-	if (mode == TEMPSENSE) {
+-		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+-
+-		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12);
+-
+-		auxpga_vmidcourse = 8;
+-		auxpga_vmidfine = 0x4;
+-		auxpga_gain = 2;
+-		mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5);
+-	} else {
+-		mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3);
+-
+-		mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12);
+-
+-		auxpga_vmidcourse = 7;
+-		auxpga_vmidfine = 0xa;
+-		auxpga_gain = 2;
+-	}
+-	auxpga_vmid =
+-	    (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1);
+-
+-	mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12);
+-
+-	mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5);
+-
+-	write_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-
+-	wlc_phy_do_dummy_tx(pi, true, OFF);
+-	if (!tempsense_done(pi))
+-		udelay(10);
+-
+-	write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007);
+-	write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF);
+-	write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F);
+-	write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005);
+-	write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025);
+-	write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112);
+-	for (i = 0; i < 14; i++)
+-		write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index);
+-
+-	write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-	udelay(999);
+-}
+-
+-void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi)
+-{
+-	lcnphy_txgains_t tx_gains;
+-	u8 bbmult;
+-	phytbl_info_t tab;
+-	s32 a1, b0, b1;
+-	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
+-	bool suspend;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		wlc_lcnphy_set_bbmult(pi, 0x30);
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-		return;
+-	}
+-
+-	if (!pi->hwpwrctrl_capable) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			tx_gains.gm_gain = 4;
+-			tx_gains.pga_gain = 12;
+-			tx_gains.pad_gain = 12;
+-			tx_gains.dac_gain = 0;
+-
+-			bbmult = 150;
+-		} else {
+-			tx_gains.gm_gain = 7;
+-			tx_gains.pga_gain = 15;
+-			tx_gains.pad_gain = 14;
+-			tx_gains.dac_gain = 0;
+-
+-			bbmult = 150;
+-		}
+-		wlc_lcnphy_set_tx_gain(pi, &tx_gains);
+-		wlc_lcnphy_set_bbmult(pi, bbmult);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	} else {
+-
+-		wlc_lcnphy_idle_tssi_est(ppi);
+-
+-		wlc_lcnphy_clear_tx_power_offsets(pi);
+-
+-		b0 = pi->txpa_2g[0];
+-		b1 = pi->txpa_2g[1];
+-		a1 = pi->txpa_2g[2];
+-		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+-		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+-
+-		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-		tab.tbl_width = 32;
+-		tab.tbl_ptr = &pwr;
+-		tab.tbl_len = 1;
+-		tab.tbl_offset = 0;
+-		for (tssi = 0; tssi < 128; tssi++) {
+-			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+-
+-			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+-			wlc_lcnphy_write_table(pi, &tab);
+-			tab.tbl_offset++;
+-		}
+-
+-		mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
+-
+-		write_phy_reg(pi, 0x4a8, 10);
+-
+-		wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR);
+-
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+-	}
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi)
+-{
+-	u16 m0m1;
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = &m0m1;
+-	tab.tbl_len = 1;
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_offset = 87;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	return (u8) ((m0m1 & 0xff00) >> 8);
+-}
+-
+-static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain)
+-{
+-	mod_phy_reg(pi, 0x4fb,
+-		    LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK,
+-		    gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT);
+-	mod_phy_reg(pi, 0x4fd,
+-		    LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK,
+-		    gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT);
+-}
+-
+-void
+-wlc_lcnphy_get_radio_loft(phy_info_t *pi,
+-			  u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0)
+-{
+-	*ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089));
+-	*eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A));
+-	*fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B));
+-	*fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C));
+-}
+-
+-static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains)
+-{
+-	u16 dac_gain;
+-
+-	dac_gain = read_phy_reg(pi, 0x439) >> 0;
+-	gains->dac_gain = (dac_gain & 0x380) >> 7;
+-
+-	{
+-		u16 rfgain0, rfgain1;
+-
+-		rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0;
+-		rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0;
+-
+-		gains->gm_gain = rfgain0 & 0xff;
+-		gains->pga_gain = (rfgain0 >> 8) & 0xff;
+-		gains->pad_gain = rfgain1 & 0xff;
+-	}
+-}
+-
+-void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b)
+-{
+-	phytbl_info_t tab;
+-	u16 iqcc[2];
+-
+-	iqcc[0] = a;
+-	iqcc[1] = b;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = iqcc;
+-	tab.tbl_len = 2;
+-	tab.tbl_offset = 80;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq)
+-{
+-	phytbl_info_t tab;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &didq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 85;
+-	wlc_lcnphy_write_table(pi, &tab);
+-}
+-
+-void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index)
+-{
+-	phytbl_info_t tab;
+-	u16 a, b;
+-	u8 bb_mult;
+-	u32 bbmultiqcomp, txgain, locoeffs, rfpower;
+-	lcnphy_txgains_t gains;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
+-	pi_lcn->lcnphy_current_index = (u8) index;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+-	tab.tbl_ptr = &bbmultiqcomp;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &txgain;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	gains.gm_gain = (u16) (txgain & 0xff);
+-	gains.pga_gain = (u16) (txgain >> 8) & 0xff;
+-	gains.pad_gain = (u16) (txgain >> 16) & 0xff;
+-	gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07;
+-	wlc_lcnphy_set_tx_gain(pi, &gains);
+-	wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f);
+-
+-	bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff);
+-	wlc_lcnphy_set_bbmult(pi, bb_mult);
+-
+-	wlc_lcnphy_enable_tx_gain_override(pi);
+-
+-	if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-
+-		a = (u16) ((bbmultiqcomp >> 10) & 0x3ff);
+-		b = (u16) (bbmultiqcomp & 0x3ff);
+-		wlc_lcnphy_set_tx_iqcc(pi, a, b);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index;
+-		tab.tbl_ptr = &locoeffs;
+-		wlc_lcnphy_read_table(pi, &tab);
+-
+-		wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+-		tab.tbl_ptr = &rfpower;
+-		wlc_lcnphy_read_table(pi, &tab);
+-		mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0);
+-
+-	}
+-}
+-
+-static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx)
+-{
+-
+-	mod_phy_reg(pi, 0x44d,
+-		    (0x1 << 1) |
+-		    (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0));
+-
+-	or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0));
+-}
+-
+-static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi)
+-{
+-	u32 j;
+-	phytbl_info_t tab;
+-	u32 temp_offset[128];
+-	tab.tbl_ptr = temp_offset;
+-	tab.tbl_len = 128;
+-	tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL;
+-	tab.tbl_width = 32;
+-	tab.tbl_offset = 0;
+-
+-	memset(temp_offset, 0, sizeof(temp_offset));
+-	for (j = 1; j < 128; j += 2)
+-		temp_offset[j] = 0x80000;
+-
+-	wlc_lcnphy_write_table(pi, &tab);
+-	return;
+-}
+-
+-static void
+-wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi,
+-				       u16 trsw,
+-				       u16 ext_lna,
+-				       u16 biq2,
+-				       u16 biq1,
+-				       u16 tia, u16 lna2, u16 lna1)
+-{
+-	u16 gain0_15, gain16_19;
+-
+-	gain16_19 = biq2 & 0xf;
+-	gain0_15 = ((biq1 & 0xf) << 12) |
+-	    ((tia & 0xf) << 8) |
+-	    ((lna2 & 0x3) << 6) |
+-	    ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
+-
+-	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+-	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+-	mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+-	} else {
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10);
+-
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15);
+-
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-	}
+-
+-	mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
+-
+-}
+-
+-static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable)
+-{
+-	u16 ebit = enable ? 1 : 0;
+-
+-	mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4);
+-		mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6);
+-	} else {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13);
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5);
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10);
+-		mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3);
+-	}
+-}
+-
+-void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable)
+-{
+-	if (!bEnable) {
+-
+-		and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4)));
+-
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1);
+-
+-		and_phy_reg(pi, 0x44c,
+-			    ~(u16) ((0x1 << 3) |
+-				       (0x1 << 5) |
+-				       (0x1 << 12) |
+-				       (0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-
+-		and_phy_reg(pi, 0x44d,
+-			    ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14)));
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0));
+-
+-		and_phy_reg(pi, 0x4f9,
+-			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-
+-		and_phy_reg(pi, 0x4fa,
+-			    ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2)));
+-	} else {
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6);
+-
+-		mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+-		mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+-
+-		wlc_lcnphy_set_trsw_override(pi, true, false);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2);
+-		mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3);
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0);
+-		} else {
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3);
+-
+-			mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5);
+-			mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2);
+-
+-			mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-			mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+-		}
+-	}
+-}
+-
+-static void
+-wlc_lcnphy_run_samples(phy_info_t *pi,
+-		       u16 num_samps,
+-		       u16 num_loops, u16 wait, bool iqcalmode)
+-{
+-
+-	or_phy_reg(pi, 0x6da, 0x8080);
+-
+-	mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0);
+-	if (num_loops != 0xffff)
+-		num_loops--;
+-	mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0);
+-
+-	mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0);
+-
+-	if (iqcalmode) {
+-
+-		and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15));
+-		or_phy_reg(pi, 0x453, (0x1 << 15));
+-	} else {
+-		write_phy_reg(pi, 0x63f, 1);
+-		wlc_lcnphy_tx_pu(pi, 1);
+-	}
+-
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x6);
+-}
+-
+-void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode)
+-{
+-
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	if (LCNREV_LT(pi->pubpi.phy_rev, 2)) {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+-	} else {
+-		mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5);
+-		mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9);
+-	}
+-
+-	if (phybw40 == 0) {
+-		mod_phy_reg((pi), 0x410,
+-			    (0x1 << 6) |
+-			    (0x1 << 5),
+-			    ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) <<
+-			    6 | (!mode) << 5);
+-		mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7);
+-	}
+-}
+-
+-void
+-wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val,
+-			 bool iqcalmode)
+-{
+-	u8 phy_bw;
+-	u16 num_samps, t, k;
+-	u32 bw;
+-	fixed theta = 0, rot = 0;
+-	cs32 tone_samp;
+-	u32 data_buf[64];
+-	u16 i_samp, q_samp;
+-	phytbl_info_t tab;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi->phy_tx_tone_freq = f_kHz;
+-
+-	wlc_lcnphy_deaf_mode(pi, true);
+-
+-	phy_bw = 40;
+-	if (pi_lcn->lcnphy_spurmod) {
+-		write_phy_reg(pi, 0x942, 0x2);
+-		write_phy_reg(pi, 0x93b, 0x0);
+-		write_phy_reg(pi, 0x93c, 0x0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
+-	}
+-
+-	if (f_kHz) {
+-		k = 1;
+-		do {
+-			bw = phy_bw * 1000 * k;
+-			num_samps = bw / ABS(f_kHz);
+-			k++;
+-		} while ((num_samps * (u32) (ABS(f_kHz))) != bw);
+-	} else
+-		num_samps = 2;
+-
+-	rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+-	theta = 0;
+-
+-	for (t = 0; t < num_samps; t++) {
+-
+-		wlc_phy_cordic(theta, &tone_samp);
+-
+-		theta += rot;
+-
+-		i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff);
+-		q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff);
+-		data_buf[t] = (i_samp << 10) | q_samp;
+-	}
+-
+-	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3);
+-
+-	tab.tbl_ptr = data_buf;
+-	tab.tbl_len = num_samps;
+-	tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY;
+-	tab.tbl_offset = 0;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode);
+-}
+-
+-void wlc_lcnphy_stop_tx_tone(phy_info_t *pi)
+-{
+-	s16 playback_status;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	pi->phy_tx_tone_freq = 0;
+-	if (pi_lcn->lcnphy_spurmod) {
+-		write_phy_reg(pi, 0x942, 0x7);
+-		write_phy_reg(pi, 0x93b, 0x2017);
+-		write_phy_reg(pi, 0x93c, 0x27c5);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
+-	}
+-
+-	playback_status = read_phy_reg(pi, 0x644);
+-	if (playback_status & (0x1 << 0)) {
+-		wlc_lcnphy_tx_pu(pi, 0);
+-		mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1);
+-	} else if (playback_status & (0x1 << 1))
+-		mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15);
+-
+-	mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7);
+-
+-	and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9);
+-
+-	wlc_lcnphy_deaf_mode(pi, false);
+-}
+-
+-static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0)));
+-}
+-
+-void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b)
+-{
+-	u16 iqcc[2];
+-	phytbl_info_t tab;
+-
+-	tab.tbl_ptr = iqcc;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = 0;
+-	tab.tbl_offset = 80;
+-	tab.tbl_width = 16;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	*a = iqcc[0];
+-	*b = iqcc[1];
+-}
+-
+-u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u16 didq;
+-
+-	tab.tbl_id = 0;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &didq;
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = 85;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	return didq;
+-}
+-
+-static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi)
+-{
+-
+-	lcnphy_txgains_t target_gains, old_gains;
+-	u8 save_bb_mult;
+-	u16 a, b, didq, save_pa_gain = 0;
+-	uint idx, SAVE_txpwrindex = 0xFF;
+-	u32 val;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phytbl_info_t tab;
+-	u8 ei0, eq0, fi0, fq0;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-	save_pa_gain = wlc_lcnphy_get_pa_gain(pi);
+-
+-	save_bb_mult = wlc_lcnphy_get_bbmult(pi);
+-
+-	if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF)
+-		SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-	target_gains.gm_gain = 7;
+-	target_gains.pga_gain = 0;
+-	target_gains.pad_gain = 21;
+-	target_gains.dac_gain = 0;
+-	wlc_lcnphy_set_tx_gain(pi, &target_gains);
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
+-
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, 30);
+-
+-		wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+-				       (pi_lcn->
+-					lcnphy_recal ? LCNPHY_CAL_RECAL :
+-					LCNPHY_CAL_FULL), false);
+-	} else {
+-
+-		wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+-	}
+-
+-	wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0);
+-	if ((ABS((s8) fi0) == 15) && (ABS((s8) fq0) == 15)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			target_gains.gm_gain = 255;
+-			target_gains.pga_gain = 255;
+-			target_gains.pad_gain = 0xf0;
+-			target_gains.dac_gain = 0;
+-		} else {
+-			target_gains.gm_gain = 7;
+-			target_gains.pga_gain = 45;
+-			target_gains.pad_gain = 186;
+-			target_gains.dac_gain = 0;
+-		}
+-
+-		if (LCNREV_IS(pi->pubpi.phy_rev, 1)
+-		    || pi_lcn->lcnphy_hw_iqcal_en) {
+-
+-			target_gains.pga_gain = 0;
+-			target_gains.pad_gain = 30;
+-			wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
+-			wlc_lcnphy_tx_iqlo_cal(pi, &target_gains,
+-					       LCNPHY_CAL_FULL, false);
+-		} else {
+-
+-			wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
+-		}
+-
+-	}
+-
+-	wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+-
+-	didq = wlc_lcnphy_get_tx_locc(pi);
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_ptr = &val;
+-
+-	tab.tbl_len = 1;
+-	tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET;
+-
+-	for (idx = 0; idx < 128; idx++) {
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx;
+-
+-		wlc_lcnphy_read_table(pi, &tab);
+-		val = (val & 0xfff00000) |
+-		    ((u32) (a & 0x3FF) << 10) | (b & 0x3ff);
+-		wlc_lcnphy_write_table(pi, &tab);
+-
+-		val = didq;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	pi_lcn->lcnphy_cal_results.txiqlocal_a = a;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_b = b;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0;
+-	pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0;
+-
+-	wlc_lcnphy_set_bbmult(pi, save_bb_mult);
+-	wlc_lcnphy_set_pa_gain(pi, save_pa_gain);
+-	wlc_lcnphy_set_tx_gain(pi, &old_gains);
+-
+-	if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF)
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-	else
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex);
+-}
+-
+-s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode)
+-{
+-	u16 tempsenseval1, tempsenseval2;
+-	s16 avg = 0;
+-	bool suspend = 0;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	}
+-	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+-	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+-
+-	if (tempsenseval1 > 255)
+-		avg = (s16) (tempsenseval1 - 512);
+-	else
+-		avg = (s16) tempsenseval1;
+-
+-	if (tempsenseval2 > 255)
+-		avg += (s16) (tempsenseval2 - 512);
+-	else
+-		avg += (s16) tempsenseval2;
+-
+-	avg /= 2;
+-
+-	if (mode == 1) {
+-
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-		udelay(100);
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return avg;
+-}
+-
+-u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode)
+-{
+-	u16 tempsenseval1, tempsenseval2;
+-	s32 avg = 0;
+-	bool suspend = 0;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
+-	}
+-	tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF;
+-	tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF;
+-
+-	if (tempsenseval1 > 255)
+-		avg = (int)(tempsenseval1 - 512);
+-	else
+-		avg = (int)tempsenseval1;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) {
+-		if (tempsenseval2 > 255)
+-			avg = (int)(avg - tempsenseval2 + 512);
+-		else
+-			avg = (int)(avg - tempsenseval2);
+-	} else {
+-		if (tempsenseval2 > 255)
+-			avg = (int)(avg + tempsenseval2 - 512);
+-		else
+-			avg = (int)(avg + tempsenseval2);
+-		avg = avg / 2;
+-	}
+-	if (avg < 0)
+-		avg = avg + 512;
+-
+-	if (pi_lcn->lcnphy_tempsense_option == 2)
+-		avg = tempsenseval1;
+-
+-	if (mode)
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
+-
+-	if (mode == 1) {
+-
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-		udelay(100);
+-		mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return (u16) avg;
+-}
+-
+-s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode)
+-{
+-	s32 degree = wlc_lcnphy_tempsense_new(pi, mode);
+-	degree =
+-	    ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1))
+-	    / LCN_TEMPSENSE_DEN;
+-	return (s8) degree;
+-}
+-
+-s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode)
+-{
+-	u16 vbatsenseval;
+-	s32 avg = 0;
+-	bool suspend = 0;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return -1;
+-
+-	if (mode == 1) {
+-		suspend =
+-		    (0 ==
+-		     (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-		if (!suspend)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-		wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
+-	}
+-
+-	vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF;
+-
+-	if (vbatsenseval > 255)
+-		avg = (s32) (vbatsenseval - 512);
+-	else
+-		avg = (s32) vbatsenseval;
+-
+-	avg =
+-	    (avg * LCN_VBAT_SCALE_NOM +
+-	     (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN;
+-
+-	if (mode == 1) {
+-		if (!suspend)
+-			wlapi_enable_mac(pi->sh->physhim);
+-	}
+-	return (s8) avg;
+-}
+-
+-static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode)
+-{
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7);
+-
+-	if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) ||
+-	    (mode == AFE_CLK_INIT_MODE_TXRX2X))
+-		write_phy_reg(pi, 0x6d0, 0x7);
+-
+-	wlc_lcnphy_toggle_afe_pwdn(pi);
+-}
+-
+-static bool
+-wlc_lcnphy_rx_iq_est(phy_info_t *pi,
+-		     u16 num_samps,
+-		     u8 wait_time, lcnphy_iq_est_t *iq_est)
+-{
+-	int wait_count = 0;
+-	bool result = true;
+-	u8 phybw40;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5);
+-
+-	mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3);
+-
+-	mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0);
+-
+-	mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0);
+-
+-	mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8);
+-
+-	mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9);
+-
+-	while (read_phy_reg(pi, 0x481) & (0x1 << 9)) {
+-
+-		if (wait_count > (10 * 500)) {
+-			result = false;
+-			goto cleanup;
+-		}
+-		udelay(100);
+-		wait_count++;
+-	}
+-
+-	iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) |
+-	    (u32) read_phy_reg(pi, 0x484);
+-	iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) |
+-	    (u32) read_phy_reg(pi, 0x486);
+-	iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) |
+-	    (u32) read_phy_reg(pi, 0x488);
+-
+- cleanup:
+-	mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3);
+-
+-	mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5);
+-
+-	return result;
+-}
+-
+-static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps)
+-{
+-#define LCNPHY_MIN_RXIQ_PWR 2
+-	bool result;
+-	u16 a0_new, b0_new;
+-	lcnphy_iq_est_t iq_est = { 0, 0, 0 };
+-	s32 a, b, temp;
+-	s16 iq_nbits, qq_nbits, arsh, brsh;
+-	s32 iq;
+-	u32 ii, qq;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0);
+-	b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0);
+-	mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6);
+-
+-	wlc_lcnphy_set_rx_iq_comp(pi, 0, 0);
+-
+-	result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est);
+-	if (!result)
+-		goto cleanup;
+-
+-	iq = (s32) iq_est.iq_prod;
+-	ii = iq_est.i_pwr;
+-	qq = iq_est.q_pwr;
+-
+-	if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) {
+-		result = false;
+-		goto cleanup;
+-	}
+-
+-	iq_nbits = wlc_phy_nbits(iq);
+-	qq_nbits = wlc_phy_nbits(qq);
+-
+-	arsh = 10 - (30 - iq_nbits);
+-	if (arsh >= 0) {
+-		a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+-		temp = (s32) (ii >> arsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	} else {
+-		a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+-		temp = (s32) (ii << -arsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	}
+-	a /= temp;
+-	brsh = qq_nbits - 31 + 20;
+-	if (brsh >= 0) {
+-		b = (qq << (31 - qq_nbits));
+-		temp = (s32) (ii >> brsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	} else {
+-		b = (qq << (31 - qq_nbits));
+-		temp = (s32) (ii << -brsh);
+-		if (temp == 0) {
+-			return false;
+-		}
+-	}
+-	b /= temp;
+-	b -= a * a;
+-	b = (s32) int_sqrt((unsigned long) b);
+-	b -= (1 << 10);
+-	a0_new = (u16) (a & 0x3ff);
+-	b0_new = (u16) (b & 0x3ff);
+- cleanup:
+-
+-	wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0);
+-
+-	mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3);
+-
+-	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new;
+-	pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new;
+-
+-	return result;
+-}
+-
+-static bool
+-wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp,
+-		     int iqcomp_sz, bool tx_switch, bool rx_switch, int module,
+-		     int tx_gain_idx)
+-{
+-	lcnphy_txgains_t old_gains;
+-	u16 tx_pwr_ctrl;
+-	u8 tx_gain_index_old = 0;
+-	bool result = false, tx_gain_override_old = false;
+-	u16 i, Core1TxControl_old, RFOverride0_old,
+-	    RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
+-	    rfoverride3_old, rfoverride3val_old, rfoverride4_old,
+-	    rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
+-	int tia_gain;
+-	u32 received_power, rx_pwr_threshold;
+-	u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
+-	u16 values_to_save[11];
+-	s16 *ptr;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
+-	if (NULL == ptr) {
+-		return false;
+-	}
+-	if (module == 2) {
+-		while (iqcomp_sz--) {
+-			if (iqcomp[iqcomp_sz].chan ==
+-			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
+-
+-				wlc_lcnphy_set_rx_iq_comp(pi,
+-							  (u16)
+-							  iqcomp[iqcomp_sz].a,
+-							  (u16)
+-							  iqcomp[iqcomp_sz].b);
+-				result = true;
+-				break;
+-			}
+-		}
+-		goto cal_done;
+-	}
+-
+-	if (module == 1) {
+-
+-		tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-
+-		for (i = 0; i < 11; i++) {
+-			values_to_save[i] =
+-			    read_radio_reg(pi, rxiq_cal_rf_reg[i]);
+-		}
+-		Core1TxControl_old = read_phy_reg(pi, 0x631);
+-
+-		or_phy_reg(pi, 0x631, 0x0015);
+-
+-		RFOverride0_old = read_phy_reg(pi, 0x44c);
+-		RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
+-		rfoverride2_old = read_phy_reg(pi, 0x4b0);
+-		rfoverride2val_old = read_phy_reg(pi, 0x4b1);
+-		rfoverride3_old = read_phy_reg(pi, 0x4f9);
+-		rfoverride3val_old = read_phy_reg(pi, 0x4fa);
+-		rfoverride4_old = read_phy_reg(pi, 0x938);
+-		rfoverride4val_old = read_phy_reg(pi, 0x939);
+-		afectrlovr_old = read_phy_reg(pi, 0x43b);
+-		afectrlovrval_old = read_phy_reg(pi, 0x43c);
+-		old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-		old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
+-
+-		tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
+-		if (tx_gain_override_old) {
+-			wlc_lcnphy_get_tx_gain(pi, &old_gains);
+-			tx_gain_index_old = pi_lcn->lcnphy_current_index;
+-		}
+-
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
+-
+-		mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-		write_radio_reg(pi, RADIO_2064_REG116, 0x06);
+-		write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
+-		write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
+-		write_radio_reg(pi, RADIO_2064_REG098, 0x03);
+-		write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+-		mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
+-		write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
+-		write_radio_reg(pi, RADIO_2064_REG114, 0x01);
+-		write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
+-		write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
+-
+-		mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
+-		mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
+-		mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
+-		mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
+-		mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
+-		mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
+-		mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
+-		mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
+-
+-		mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+-		mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+-
+-		wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
+-		write_phy_reg(pi, 0x6da, 0xffff);
+-		or_phy_reg(pi, 0x6db, 0x3);
+-		wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
+-		wlc_lcnphy_rx_gain_override_enable(pi, true);
+-
+-		tia_gain = 8;
+-		rx_pwr_threshold = 950;
+-		while (tia_gain > 0) {
+-			tia_gain -= 1;
+-			wlc_lcnphy_set_rx_gain_by_distribution(pi,
+-							       0, 0, 2, 2,
+-							       (u16)
+-							       tia_gain, 1, 0);
+-			udelay(500);
+-
+-			received_power =
+-			    wlc_lcnphy_measure_digital_power(pi, 2000);
+-			if (received_power < rx_pwr_threshold)
+-				break;
+-		}
+-		result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
+-
+-		wlc_lcnphy_stop_tx_tone(pi);
+-
+-		write_phy_reg(pi, 0x631, Core1TxControl_old);
+-
+-		write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
+-		write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
+-		write_phy_reg(pi, 0x4b0, rfoverride2_old);
+-		write_phy_reg(pi, 0x4b1, rfoverride2val_old);
+-		write_phy_reg(pi, 0x4f9, rfoverride3_old);
+-		write_phy_reg(pi, 0x4fa, rfoverride3val_old);
+-		write_phy_reg(pi, 0x938, rfoverride4_old);
+-		write_phy_reg(pi, 0x939, rfoverride4val_old);
+-		write_phy_reg(pi, 0x43b, afectrlovr_old);
+-		write_phy_reg(pi, 0x43c, afectrlovrval_old);
+-		write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+-		write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
+-
+-		wlc_lcnphy_clear_trsw_override(pi);
+-
+-		mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
+-
+-		for (i = 0; i < 11; i++) {
+-			write_radio_reg(pi, rxiq_cal_rf_reg[i],
+-					values_to_save[i]);
+-		}
+-
+-		if (tx_gain_override_old) {
+-			wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
+-		} else
+-			wlc_lcnphy_disable_tx_gain_override(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
+-
+-		wlc_lcnphy_rx_gain_override_enable(pi, false);
+-	}
+-
+- cal_done:
+-	kfree(ptr);
+-	return result;
+-}
+-
+-static void wlc_lcnphy_temp_adj(phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-}
+-
+-static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi)
+-{
+-	bool suspend;
+-	s8 index;
+-	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	wlc_lcnphy_deaf_mode(pi, true);
+-	pi->phy_lastcal = pi->sh->now;
+-	pi->phy_forcecal = false;
+-	index = pi_lcn->lcnphy_current_index;
+-
+-	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+-
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+-	wlc_lcnphy_deaf_mode(pi, false);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-}
+-
+-static void wlc_lcnphy_periodic_cal(phy_info_t *pi)
+-{
+-	bool suspend, full_cal;
+-	const lcnphy_rx_iqcomp_t *rx_iqcomp;
+-	int rx_iqcomp_sz;
+-	u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	s8 index;
+-	phytbl_info_t tab;
+-	s32 a1, b0, b1;
+-	s32 tssi, pwr, maxtargetpwr, mintargetpwr;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	pi->phy_lastcal = pi->sh->now;
+-	pi->phy_forcecal = false;
+-	full_cal =
+-	    (pi_lcn->lcnphy_full_cal_channel !=
+-	     CHSPEC_CHANNEL(pi->radio_chanspec));
+-	pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-	index = pi_lcn->lcnphy_current_index;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend) {
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-	wlc_lcnphy_deaf_mode(pi, true);
+-
+-	wlc_lcnphy_txpwrtbl_iqlo_cal(pi);
+-
+-	rx_iqcomp = lcnphy_rx_iqcomp_table_rev0;
+-	rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40);
+-	else
+-		wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127);
+-
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+-
+-		wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi);
+-
+-		b0 = pi->txpa_2g[0];
+-		b1 = pi->txpa_2g[1];
+-		a1 = pi->txpa_2g[2];
+-		maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1);
+-		mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1);
+-
+-		tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-		tab.tbl_width = 32;
+-		tab.tbl_ptr = &pwr;
+-		tab.tbl_len = 1;
+-		tab.tbl_offset = 0;
+-		for (tssi = 0; tssi < 128; tssi++) {
+-			pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1);
+-			pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr;
+-			wlc_lcnphy_write_table(pi, &tab);
+-			tab.tbl_offset++;
+-		}
+-	}
+-
+-	wlc_lcnphy_set_tx_pwr_by_index(pi, index);
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl);
+-	wlc_lcnphy_deaf_mode(pi, false);
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode)
+-{
+-	u16 temp_new;
+-	int temp1, temp2, temp_diff;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	switch (mode) {
+-	case PHY_PERICAL_CHAN:
+-
+-		break;
+-	case PHY_FULLCAL:
+-		wlc_lcnphy_periodic_cal(pi);
+-		break;
+-	case PHY_PERICAL_PHYINIT:
+-		wlc_lcnphy_periodic_cal(pi);
+-		break;
+-	case PHY_PERICAL_WATCHDOG:
+-		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-			temp_new = wlc_lcnphy_tempsense(pi, 0);
+-			temp1 = LCNPHY_TEMPSENSE(temp_new);
+-			temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper);
+-			temp_diff = temp1 - temp2;
+-			if ((pi_lcn->lcnphy_cal_counter > 90) ||
+-			    (temp_diff > 60) || (temp_diff < -60)) {
+-				wlc_lcnphy_glacial_timer_based_cal(pi);
+-				wlc_2064_vco_cal(pi);
+-				pi_lcn->lcnphy_cal_temper = temp_new;
+-				pi_lcn->lcnphy_cal_counter = 0;
+-			} else
+-				pi_lcn->lcnphy_cal_counter++;
+-		}
+-		break;
+-	case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL:
+-		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-			wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi);
+-		break;
+-	}
+-}
+-
+-void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr)
+-{
+-	s8 cck_offset;
+-	u16 status;
+-	status = (read_phy_reg(pi, 0x4ab));
+-	if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) &&
+-	    (status  & (0x1 << 15))) {
+-		*ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
+-				     >> 0) >> 1);
+-
+-		if (wlc_phy_tpc_isenabled_lcnphy(pi))
+-			cck_offset = pi->tx_power_offset[TXP_FIRST_CCK];
+-		else
+-			cck_offset = 0;
+-
+-		*cck_pwr = *ofdm_pwr + cck_offset;
+-	} else {
+-		*cck_pwr = 0;
+-		*ofdm_pwr = 0;
+-	}
+-}
+-
+-void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi)
+-{
+-	return;
+-
+-}
+-
+-static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	u8 channel = CHSPEC_CHANNEL(chanspec);
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	if (channel == 14) {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
+-
+-	} else {
+-		mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
+-
+-	}
+-	pi_lcn->lcnphy_bandedge_corr = 2;
+-	if (channel == 1)
+-		pi_lcn->lcnphy_bandedge_corr = 4;
+-
+-	if (channel == 1 || channel == 2 || channel == 3 ||
+-	    channel == 4 || channel == 9 ||
+-	    channel == 10 || channel == 11 || channel == 12) {
+-		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0);
+-
+-		si_pmu_pllupd(pi->sh->sih);
+-		write_phy_reg(pi, 0x942, 0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, false);
+-		pi_lcn->lcnphy_spurmod = 0;
+-		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8);
+-
+-		write_phy_reg(pi, 0x425, 0x5907);
+-	} else {
+-		si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333);
+-		si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820);
+-
+-		si_pmu_pllupd(pi->sh->sih);
+-		write_phy_reg(pi, 0x942, 0);
+-		wlc_lcnphy_txrx_spur_avoidance_mode(pi, true);
+-
+-		pi_lcn->lcnphy_spurmod = 0;
+-		mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8);
+-
+-		write_phy_reg(pi, 0x425, 0x590a);
+-	}
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-}
+-
+-void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi)
+-{
+-	s8 index;
+-	u16 index2;
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) {
+-		index = wlc_lcnphy_tempcompensated_txpwrctrl(pi);
+-		index2 = (u16) (index * 2);
+-		mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0);
+-
+-		pi_lcn->lcnphy_current_index = (s8)
+-		    ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2);
+-	}
+-}
+-
+-static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b)
+-{
+-	mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0);
+-
+-	mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0);
+-
+-	mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0);
+-
+-	mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0);
+-
+-}
+-
+-void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi)
+-{
+-	u8 phybw40;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	pi_lcn->lcnphy_cal_counter = 0;
+-	pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense;
+-
+-	or_phy_reg(pi, 0x44a, 0x80);
+-	and_phy_reg(pi, 0x44a, 0x7f);
+-
+-	wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X);
+-
+-	write_phy_reg(pi, 0x60a, 160);
+-
+-	write_phy_reg(pi, 0x46a, 25);
+-
+-	wlc_lcnphy_baseband_init(pi);
+-
+-	wlc_lcnphy_radio_init(pi);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi);
+-
+-	wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+-
+-	si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9);
+-
+-	si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD);
+-
+-	if ((pi->sh->boardflags & BFL_FEM)
+-	    && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR);
+-
+-	wlc_lcnphy_agc_temp_init(pi);
+-
+-	wlc_lcnphy_temp_adj(pi);
+-
+-	mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14);
+-
+-	udelay(100);
+-	mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14);
+-
+-	wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW);
+-	pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT;
+-	wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT);
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save)
+-{
+-	u16 vmid;
+-	int i;
+-	for (i = 0; i < 20; i++) {
+-		values_to_save[i] =
+-		    read_radio_reg(pi, iqlo_loopback_rf_regs[i]);
+-	}
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12);
+-	mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14);
+-
+-	mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11);
+-	mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
+-	mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
+-
+-	mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		and_radio_reg(pi, RADIO_2064_REG03A, 0xFD);
+-	else
+-		and_radio_reg(pi, RADIO_2064_REG03A, 0xF9);
+-	or_radio_reg(pi, RADIO_2064_REG11A, 0x1);
+-
+-	or_radio_reg(pi, RADIO_2064_REG036, 0x01);
+-	or_radio_reg(pi, RADIO_2064_REG11A, 0x18);
+-	udelay(20);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0);
+-		else
+-			or_radio_reg(pi, RADIO_2064_REG03A, 1);
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1);
+-		else
+-			or_radio_reg(pi, RADIO_2064_REG03A, 0x3);
+-	}
+-
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG025, 0xF);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6);
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec))
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1);
+-		else
+-			mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1);
+-	}
+-
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG005, 0x8);
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x80);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+-	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG00B, 0x7);
+-	or_radio_reg(pi, RADIO_2064_REG113, 0x10);
+-	udelay(20);
+-
+-	write_radio_reg(pi, RADIO_2064_REG007, 0x1);
+-	udelay(20);
+-
+-	vmid = 0x2A6;
+-	mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3);
+-	write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff));
+-	or_radio_reg(pi, RADIO_2064_REG11F, 0x44);
+-	udelay(20);
+-
+-	or_radio_reg(pi, RADIO_2064_REG0FF, 0x10);
+-	udelay(20);
+-	write_radio_reg(pi, RADIO_2064_REG012, 0x02);
+-	or_radio_reg(pi, RADIO_2064_REG112, 0x06);
+-	write_radio_reg(pi, RADIO_2064_REG036, 0x11);
+-	write_radio_reg(pi, RADIO_2064_REG059, 0xcc);
+-	write_radio_reg(pi, RADIO_2064_REG05C, 0x2e);
+-	write_radio_reg(pi, RADIO_2064_REG078, 0xd7);
+-	write_radio_reg(pi, RADIO_2064_REG092, 0x15);
+-}
+-
+-static void
+-wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh,
+-		    s16 *ptr, int mode)
+-{
+-	u32 curval1, curval2, stpptr, curptr, strptr, val;
+-	u16 sslpnCalibClkEnCtrl, timer;
+-	u16 old_sslpnCalibClkEnCtrl;
+-	s16 imag, real;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	timer = 0;
+-	old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-
+-	curval1 = R_REG(&pi->regs->psm_corectlsts);
+-	ptr[130] = 0;
+-	W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1));
+-
+-	W_REG(&pi->regs->smpl_clct_strptr, 0x7E00);
+-	W_REG(&pi->regs->smpl_clct_stpptr, 0x8000);
+-	udelay(20);
+-	curval2 = R_REG(&pi->regs->psm_phy_hdr_param);
+-	W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30);
+-
+-	write_phy_reg(pi, 0x555, 0x0);
+-	write_phy_reg(pi, 0x5a6, 0x5);
+-
+-	write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6));
+-	write_phy_reg(pi, 0x5cf, 3);
+-	write_phy_reg(pi, 0x5a5, 0x3);
+-	write_phy_reg(pi, 0x583, 0x0);
+-	write_phy_reg(pi, 0x584, 0x0);
+-	write_phy_reg(pi, 0x585, 0x0fff);
+-	write_phy_reg(pi, 0x586, 0x0000);
+-
+-	write_phy_reg(pi, 0x580, 0x4501);
+-
+-	sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
+-	write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
+-	stpptr = R_REG(&pi->regs->smpl_clct_stpptr);
+-	curptr = R_REG(&pi->regs->smpl_clct_curptr);
+-	do {
+-		udelay(10);
+-		curptr = R_REG(&pi->regs->smpl_clct_curptr);
+-		timer++;
+-	} while ((curptr != stpptr) && (timer < 500));
+-
+-	W_REG(&pi->regs->psm_phy_hdr_param, 0x2);
+-	strptr = 0x7E00;
+-	W_REG(&pi->regs->tplatewrptr, strptr);
+-	while (strptr < 0x8000) {
+-		val = R_REG(&pi->regs->tplatewrdata);
+-		imag = ((val >> 16) & 0x3ff);
+-		real = ((val) & 0x3ff);
+-		if (imag > 511) {
+-			imag -= 1024;
+-		}
+-		if (real > 511) {
+-			real -= 1024;
+-		}
+-		if (pi_lcn->lcnphy_iqcal_swp_dis)
+-			ptr[(strptr - 0x7E00) / 4] = real;
+-		else
+-			ptr[(strptr - 0x7E00) / 4] = imag;
+-		if (clip_detect_algo) {
+-			if (imag > thresh || imag < -thresh) {
+-				strptr = 0x8000;
+-				ptr[130] = 1;
+-			}
+-		}
+-		strptr += 4;
+-	}
+-
+-	write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
+-	W_REG(&pi->regs->psm_phy_hdr_param, curval2);
+-	W_REG(&pi->regs->psm_corectlsts, curval1);
+-}
+-
+-static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi)
+-{
+-	lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4;
+-
+-	wlc_lcnphy_set_cc(pi, 0, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 2, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 3, 0, 0);
+-	wlc_lcnphy_set_cc(pi, 4, 0, 0);
+-
+-	wlc_lcnphy_a1(pi, 4, 0, 0);
+-	wlc_lcnphy_a1(pi, 3, 0, 0);
+-	wlc_lcnphy_a1(pi, 2, 3, 2);
+-	wlc_lcnphy_a1(pi, 0, 5, 8);
+-	wlc_lcnphy_a1(pi, 2, 2, 1);
+-	wlc_lcnphy_a1(pi, 0, 4, 3);
+-
+-	iqcc0 = wlc_lcnphy_get_cc(pi, 0);
+-	locc2 = wlc_lcnphy_get_cc(pi, 2);
+-	locc3 = wlc_lcnphy_get_cc(pi, 3);
+-	locc4 = wlc_lcnphy_get_cc(pi, 4);
+-}
+-
+-static void
+-wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y)
+-{
+-	u16 di0dq0;
+-	u16 x, y, data_rf;
+-	int k;
+-	switch (cal_type) {
+-	case 0:
+-		wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y);
+-		break;
+-	case 2:
+-		di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff);
+-		wlc_lcnphy_set_tx_locc(pi, di0dq0);
+-		break;
+-	case 3:
+-		k = wlc_lcnphy_calc_floor(coeff_x, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_x, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG089, data_rf);
+-		k = wlc_lcnphy_calc_floor(coeff_y, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_y, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08A, data_rf);
+-		break;
+-	case 4:
+-		k = wlc_lcnphy_calc_floor(coeff_x, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_x, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08B, data_rf);
+-		k = wlc_lcnphy_calc_floor(coeff_y, 0);
+-		y = 8 + k;
+-		k = wlc_lcnphy_calc_floor(coeff_y, 1);
+-		x = 8 - k;
+-		data_rf = (x * 16 + y);
+-		write_radio_reg(pi, RADIO_2064_REG08C, data_rf);
+-		break;
+-	}
+-}
+-
+-static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type)
+-{
+-	u16 a, b, didq;
+-	u8 di0, dq0, ei, eq, fi, fq;
+-	lcnphy_unsign16_struct cc;
+-	cc.re = 0;
+-	cc.im = 0;
+-	switch (cal_type) {
+-	case 0:
+-		wlc_lcnphy_get_tx_iqcc(pi, &a, &b);
+-		cc.re = a;
+-		cc.im = b;
+-		break;
+-	case 2:
+-		didq = wlc_lcnphy_get_tx_locc(pi);
+-		di0 = (((didq & 0xff00) << 16) >> 24);
+-		dq0 = (((didq & 0x00ff) << 24) >> 24);
+-		cc.re = (u16) di0;
+-		cc.im = (u16) dq0;
+-		break;
+-	case 3:
+-		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+-		cc.re = (u16) ei;
+-		cc.im = (u16) eq;
+-		break;
+-	case 4:
+-		wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq);
+-		cc.re = (u16) fi;
+-		cc.im = (u16) fq;
+-		break;
+-	}
+-	return cc;
+-}
+-
+-static void
+-wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2)
+-{
+-	const lcnphy_spb_tone_t *phy_c1;
+-	lcnphy_spb_tone_t phy_c2;
+-	lcnphy_unsign16_struct phy_c3;
+-	int phy_c4, phy_c5, k, l, j, phy_c6;
+-	u16 phy_c7, phy_c8, phy_c9;
+-	s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16;
+-	s16 *ptr, phy_c17;
+-	s32 phy_c18, phy_c19;
+-	u32 phy_c20, phy_c21;
+-	bool phy_c22, phy_c23, phy_c24, phy_c25;
+-	u16 phy_c26, phy_c27;
+-	u16 phy_c28, phy_c29, phy_c30;
+-	u16 phy_c31;
+-	u16 *phy_c32;
+-	phy_c21 = 0;
+-	phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0;
+-	ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC);
+-	if (NULL == ptr) {
+-		return;
+-	}
+-
+-	phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC);
+-	if (NULL == phy_c32) {
+-		kfree(ptr);
+-		return;
+-	}
+-	phy_c26 = read_phy_reg(pi, 0x6da);
+-	phy_c27 = read_phy_reg(pi, 0x6db);
+-	phy_c31 = read_radio_reg(pi, RADIO_2064_REG026);
+-	write_phy_reg(pi, 0x93d, 0xC0);
+-
+-	wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0);
+-	write_phy_reg(pi, 0x6da, 0xffff);
+-	or_phy_reg(pi, 0x6db, 0x3);
+-
+-	wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32);
+-	udelay(500);
+-	phy_c28 = read_phy_reg(pi, 0x938);
+-	phy_c29 = read_phy_reg(pi, 0x4d7);
+-	phy_c30 = read_phy_reg(pi, 0x4d8);
+-	or_phy_reg(pi, 0x938, 0x1 << 2);
+-	or_phy_reg(pi, 0x4d7, 0x1 << 2);
+-	or_phy_reg(pi, 0x4d7, 0x1 << 3);
+-	mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12);
+-	or_phy_reg(pi, 0x4d8, 1 << 0);
+-	or_phy_reg(pi, 0x4d8, 1 << 1);
+-	mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2);
+-	mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12);
+-	phy_c1 = &lcnphy_spb_tone_3750[0];
+-	phy_c4 = 32;
+-
+-	if (num_levels == 0) {
+-		if (cal_type != 0) {
+-			num_levels = 4;
+-		} else {
+-			num_levels = 9;
+-		}
+-	}
+-	if (step_size_lg2 == 0) {
+-		if (cal_type != 0) {
+-			step_size_lg2 = 3;
+-		} else {
+-			step_size_lg2 = 8;
+-		}
+-	}
+-
+-	phy_c7 = (1 << step_size_lg2);
+-	phy_c3 = wlc_lcnphy_get_cc(pi, cal_type);
+-	phy_c15 = (s16) phy_c3.re;
+-	phy_c16 = (s16) phy_c3.im;
+-	if (cal_type == 2) {
+-		if (phy_c3.re > 127)
+-			phy_c15 = phy_c3.re - 256;
+-		if (phy_c3.im > 127)
+-			phy_c16 = phy_c3.im - 256;
+-	}
+-	wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+-	udelay(20);
+-	for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) {
+-		phy_c23 = 1;
+-		phy_c22 = 0;
+-		switch (cal_type) {
+-		case 0:
+-			phy_c10 = 511;
+-			break;
+-		case 2:
+-			phy_c10 = 127;
+-			break;
+-		case 3:
+-			phy_c10 = 15;
+-			break;
+-		case 4:
+-			phy_c10 = 15;
+-			break;
+-		}
+-
+-		phy_c9 = read_phy_reg(pi, 0x93d);
+-		phy_c9 = 2 * phy_c9;
+-		phy_c24 = 0;
+-		phy_c5 = 7;
+-		phy_c25 = 1;
+-		while (1) {
+-			write_radio_reg(pi, RADIO_2064_REG026,
+-					(phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4));
+-			udelay(50);
+-			phy_c22 = 0;
+-			ptr[130] = 0;
+-			wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2);
+-			if (ptr[130] == 1)
+-				phy_c22 = 1;
+-			if (phy_c22)
+-				phy_c5 -= 1;
+-			if ((phy_c22 != phy_c24) && (!phy_c25))
+-				break;
+-			if (!phy_c22)
+-				phy_c5 += 1;
+-			if (phy_c5 <= 0 || phy_c5 >= 7)
+-				break;
+-			phy_c24 = phy_c22;
+-			phy_c25 = 0;
+-		}
+-
+-		if (phy_c5 < 0)
+-			phy_c5 = 0;
+-		else if (phy_c5 > 7)
+-			phy_c5 = 7;
+-
+-		for (k = -phy_c7; k <= phy_c7; k += phy_c7) {
+-			for (l = -phy_c7; l <= phy_c7; l += phy_c7) {
+-				phy_c11 = phy_c15 + k;
+-				phy_c12 = phy_c16 + l;
+-
+-				if (phy_c11 < -phy_c10)
+-					phy_c11 = -phy_c10;
+-				else if (phy_c11 > phy_c10)
+-					phy_c11 = phy_c10;
+-				if (phy_c12 < -phy_c10)
+-					phy_c12 = -phy_c10;
+-				else if (phy_c12 > phy_c10)
+-					phy_c12 = phy_c10;
+-				wlc_lcnphy_set_cc(pi, cal_type, phy_c11,
+-						  phy_c12);
+-				udelay(20);
+-				wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2);
+-
+-				phy_c18 = 0;
+-				phy_c19 = 0;
+-				for (j = 0; j < 128; j++) {
+-					if (cal_type != 0) {
+-						phy_c6 = j % phy_c4;
+-					} else {
+-						phy_c6 = (2 * j) % phy_c4;
+-					}
+-					phy_c2.re = phy_c1[phy_c6].re;
+-					phy_c2.im = phy_c1[phy_c6].im;
+-					phy_c17 = ptr[j];
+-					phy_c18 = phy_c18 + phy_c17 * phy_c2.re;
+-					phy_c19 = phy_c19 + phy_c17 * phy_c2.im;
+-				}
+-
+-				phy_c18 = phy_c18 >> 10;
+-				phy_c19 = phy_c19 >> 10;
+-				phy_c20 =
+-				    ((phy_c18 * phy_c18) + (phy_c19 * phy_c19));
+-
+-				if (phy_c23 || phy_c20 < phy_c21) {
+-					phy_c21 = phy_c20;
+-					phy_c13 = phy_c11;
+-					phy_c14 = phy_c12;
+-				}
+-				phy_c23 = 0;
+-			}
+-		}
+-		phy_c23 = 1;
+-		phy_c15 = phy_c13;
+-		phy_c16 = phy_c14;
+-		phy_c7 = phy_c7 >> 1;
+-		wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16);
+-		udelay(20);
+-	}
+-	goto cleanup;
+- cleanup:
+-	wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32);
+-	wlc_lcnphy_stop_tx_tone(pi);
+-	write_phy_reg(pi, 0x6da, phy_c26);
+-	write_phy_reg(pi, 0x6db, phy_c27);
+-	write_phy_reg(pi, 0x938, phy_c28);
+-	write_phy_reg(pi, 0x4d7, phy_c29);
+-	write_phy_reg(pi, 0x4d8, phy_c30);
+-	write_radio_reg(pi, RADIO_2064_REG026, phy_c31);
+-
+-	kfree(phy_c32);
+-	kfree(ptr);
+-}
+-
+-static void
+-wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save)
+-{
+-	int i;
+-
+-	and_phy_reg(pi, 0x44c, 0x0 >> 11);
+-
+-	and_phy_reg(pi, 0x43b, 0xC);
+-
+-	for (i = 0; i < 20; i++) {
+-		write_radio_reg(pi, iqlo_loopback_rf_regs[i],
+-				values_to_save[i]);
+-	}
+-}
+-
+-static void
+-WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi,
+-					     const lcnphy_tx_gain_tbl_entry *
+-					     gain_table) {
+-	u32 j;
+-	phytbl_info_t tab;
+-	u32 val;
+-	u16 pa_gain;
+-	u16 gm_gain;
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec))
+-		pa_gain = 0x70;
+-	else
+-		pa_gain = 0x70;
+-
+-	if (pi->sh->boardflags & BFL_FEM)
+-		pa_gain = 0x10;
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-	tab.tbl_ptr = &val;
+-
+-	for (j = 0; j < 128; j++) {
+-		gm_gain = gain_table[j].gm;
+-		val = (((u32) pa_gain << 24) |
+-		       (gain_table[j].pad << 16) |
+-		       (gain_table[j].pga << 8) | gm_gain);
+-
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j;
+-		wlc_lcnphy_write_table(pi, &tab);
+-
+-		val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20);
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-}
+-
+-static void wlc_lcnphy_load_rfpower(phy_info_t *pi)
+-{
+-	phytbl_info_t tab;
+-	u32 val, bbmult, rfgain;
+-	u8 index;
+-	u8 scale_factor = 1;
+-	s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift;
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
+-	tab.tbl_width = 32;
+-	tab.tbl_len = 1;
+-
+-	for (index = 0; index < 128; index++) {
+-		tab.tbl_ptr = &bbmult;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index;
+-		wlc_lcnphy_read_table(pi, &tab);
+-		bbmult = bbmult >> 20;
+-
+-		tab.tbl_ptr = &rfgain;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index;
+-		wlc_lcnphy_read_table(pi, &tab);
+-
+-		qm_log10((s32) (bbmult), 0, &temp1, &qQ1);
+-		qm_log10((s32) (1 << 6), 0, &temp2, &qQ2);
+-
+-		if (qQ1 < qQ2) {
+-			temp2 = qm_shr16(temp2, qQ2 - qQ1);
+-			qQ = qQ1;
+-		} else {
+-			temp1 = qm_shr16(temp1, qQ1 - qQ2);
+-			qQ = qQ2;
+-		}
+-		temp = qm_sub16(temp1, temp2);
+-
+-		if (qQ >= 4)
+-			shift = qQ - 4;
+-		else
+-			shift = 4 - qQ;
+-
+-		val = (((index << shift) + (5 * temp) +
+-			(1 << (scale_factor + shift - 3))) >> (scale_factor +
+-							       shift - 2));
+-
+-		tab.tbl_ptr = &val;
+-		tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi)
+-{
+-	uint idx;
+-	u8 phybw40;
+-	phytbl_info_t tab;
+-	u32 val;
+-
+-	phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-
+-	for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) {
+-		wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]);
+-	}
+-
+-	if (pi->sh->boardflags & BFL_FEM_BT) {
+-		tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-		tab.tbl_width = 16;
+-		tab.tbl_ptr = &val;
+-		tab.tbl_len = 1;
+-		val = 100;
+-		tab.tbl_offset = 4;
+-		wlc_lcnphy_write_table(pi, &tab);
+-	}
+-
+-	tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
+-	tab.tbl_width = 16;
+-	tab.tbl_ptr = &val;
+-	tab.tbl_len = 1;
+-
+-	val = 114;
+-	tab.tbl_offset = 0;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	val = 130;
+-	tab.tbl_offset = 1;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	val = 6;
+-	tab.tbl_offset = 8;
+-	wlc_lcnphy_write_table(pi, &tab);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->sh->boardflags & BFL_FEM)
+-			wlc_lcnphy_load_tx_gain_table(pi,
+-						      dot11lcnphy_2GHz_extPA_gaintable_rev0);
+-		else
+-			wlc_lcnphy_load_tx_gain_table(pi,
+-						      dot11lcnphy_2GHz_gaintable_rev0);
+-	}
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			for (idx = 0;
+-			     idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+-			     idx++)
+-				if (pi->sh->boardflags & BFL_EXTLNA)
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2
+-							       [idx]);
+-				else
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_2G_rev2
+-							       [idx]);
+-		} else {
+-			for (idx = 0;
+-			     idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+-			     idx++)
+-				if (pi->sh->boardflags & BFL_EXTLNA_5GHz)
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2
+-							       [idx]);
+-				else
+-					wlc_lcnphy_write_table(pi,
+-							       &dot11lcnphytbl_rx_gain_info_5G_rev2
+-							       [idx]);
+-		}
+-	}
+-
+-	if ((pi->sh->boardflags & BFL_FEM)
+-	    && !(pi->sh->boardflags & BFL_FEM_BT))
+-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa);
+-	else if (pi->sh->boardflags & BFL_FEM_BT) {
+-		if (pi->sh->boardrev < 0x1250)
+-			wlc_lcnphy_write_table(pi,
+-					       &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa);
+-		else
+-			wlc_lcnphy_write_table(pi,
+-					       &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250);
+-	} else
+-		wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313);
+-
+-	wlc_lcnphy_load_rfpower(pi);
+-
+-	wlc_lcnphy_clear_papd_comptable(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi)
+-{
+-	u16 afectrl1;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	write_radio_reg(pi, RADIO_2064_REG11C, 0x0);
+-
+-	write_phy_reg(pi, 0x43b, 0x0);
+-	write_phy_reg(pi, 0x43c, 0x0);
+-	write_phy_reg(pi, 0x44c, 0x0);
+-	write_phy_reg(pi, 0x4e6, 0x0);
+-	write_phy_reg(pi, 0x4f9, 0x0);
+-	write_phy_reg(pi, 0x4b0, 0x0);
+-	write_phy_reg(pi, 0x938, 0x0);
+-	write_phy_reg(pi, 0x4b0, 0x0);
+-	write_phy_reg(pi, 0x44e, 0);
+-
+-	or_phy_reg(pi, 0x567, 0x03);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-
+-	if (!(pi->sh->boardflags & BFL_FEM))
+-		wlc_lcnphy_set_tx_pwr_by_index(pi, 52);
+-
+-	if (0) {
+-		afectrl1 = 0;
+-		afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) |
+-				     (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn->
+-								      lcnphy_rssi_gs
+-								      << 10));
+-		write_phy_reg(pi, 0x43e, afectrl1);
+-	}
+-
+-	mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0);
+-	if (pi->sh->boardflags & BFL_FEM) {
+-		mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0);
+-
+-		write_phy_reg(pi, 0x910, 0x1);
+-	}
+-
+-	mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8);
+-	mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0);
+-	mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0);
+-
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi)
+-{
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0);
+-
+-		mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8);
+-	}
+-}
+-
+-static void wlc_lcnphy_agc_temp_init(phy_info_t *pi)
+-{
+-	s16 temp;
+-	phytbl_info_t tab;
+-	u32 tableBuffer[2];
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	temp = (s16) read_phy_reg(pi, 0x4df);
+-	pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0;
+-
+-	if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127)
+-		pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256;
+-
+-	pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8;
+-
+-	if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127)
+-		pi_lcn->lcnphy_dsssgainidxtableoffset -= 256;
+-
+-	tab.tbl_ptr = tableBuffer;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = 17;
+-	tab.tbl_offset = 59;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	if (tableBuffer[0] > 63)
+-		tableBuffer[0] -= 128;
+-	pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0];
+-
+-	if (tableBuffer[1] > 63)
+-		tableBuffer[1] -= 128;
+-	pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1];
+-
+-	temp = (s16) (read_phy_reg(pi, 0x434)
+-			& (0xff << 0));
+-	if (temp > 127)
+-		temp -= 256;
+-	pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp;
+-
+-	pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424)
+-					  & (0xff << 8))
+-	    >> 8;
+-	pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425)
+-					   & (0xff << 0))
+-	    >> 0;
+-
+-	tab.tbl_ptr = tableBuffer;
+-	tab.tbl_len = 2;
+-	tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX;
+-	tab.tbl_offset = 28;
+-	tab.tbl_width = 32;
+-	wlc_lcnphy_read_table(pi, &tab);
+-
+-	pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0];
+-	pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1];
+-
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	or_phy_reg(pi, 0x805, 0x1);
+-
+-	mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0);
+-
+-	mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0);
+-
+-	write_phy_reg(pi, 0x414, 0x1e10);
+-	write_phy_reg(pi, 0x415, 0x0640);
+-
+-	mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8);
+-
+-	or_phy_reg(pi, 0x44a, 0x44);
+-	write_phy_reg(pi, 0x44a, 0x80);
+-	mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0);
+-
+-	mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0);
+-
+-	if (!(pi->sh->boardrev < 0x1204))
+-		mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0);
+-
+-	write_phy_reg(pi, 0x7d6, 0x0902);
+-	mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0);
+-
+-	mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-		mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0);
+-
+-		mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0);
+-
+-		mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0);
+-
+-		mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2);
+-
+-		mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4);
+-		mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0);
+-		mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90);
+-		mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2);
+-		mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0);
+-
+-		mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2);
+-
+-		wlc_lcnphy_clear_tx_power_offsets(pi);
+-		mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6);
+-
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi)
+-{
+-
+-	wlc_lcnphy_tbl_init(pi);
+-	wlc_lcnphy_rev0_baseband_init(pi);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 2))
+-		wlc_lcnphy_rev2_baseband_init(pi);
+-	wlc_lcnphy_bu_tweaks(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi)
+-{
+-	u32 i;
+-	lcnphy_radio_regs_t *lcnphyregs = NULL;
+-
+-	lcnphyregs = lcnphy_radio_regs_2064;
+-
+-	for (i = 0; lcnphyregs[i].address != 0xffff; i++)
+-		if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a)
+-			write_radio_reg(pi,
+-					((lcnphyregs[i].address & 0x3fff) |
+-					 RADIO_DEFAULT_CORE),
+-					(u16) lcnphyregs[i].init_a);
+-		else if (lcnphyregs[i].do_init_g)
+-			write_radio_reg(pi,
+-					((lcnphyregs[i].address & 0x3fff) |
+-					 RADIO_DEFAULT_CORE),
+-					(u16) lcnphyregs[i].init_g);
+-
+-	write_radio_reg(pi, RADIO_2064_REG032, 0x62);
+-	write_radio_reg(pi, RADIO_2064_REG033, 0x19);
+-
+-	write_radio_reg(pi, RADIO_2064_REG090, 0x10);
+-
+-	write_radio_reg(pi, RADIO_2064_REG010, 0x00);
+-
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-
+-		write_radio_reg(pi, RADIO_2064_REG060, 0x7f);
+-		write_radio_reg(pi, RADIO_2064_REG061, 0x72);
+-		write_radio_reg(pi, RADIO_2064_REG062, 0x7f);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG01D, 0x02);
+-	write_radio_reg(pi, RADIO_2064_REG01E, 0x06);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9);
+-
+-	mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12);
+-
+-	write_phy_reg(pi, 0x4ea, 0x4688);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
+-
+-	mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
+-
+-	mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0);
+-
+-	wlc_lcnphy_set_tx_locc(pi, 0);
+-
+-	wlc_lcnphy_rcal(pi);
+-
+-	wlc_lcnphy_rc_cal(pi);
+-}
+-
+-static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi)
+-{
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	wlc_radio_2064_init(pi);
+-}
+-
+-static void wlc_lcnphy_rcal(phy_info_t *pi)
+-{
+-	u8 rcal_value;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+-
+-	or_radio_reg(pi, RADIO_2064_REG004, 0x40);
+-	or_radio_reg(pi, RADIO_2064_REG120, 0x10);
+-
+-	or_radio_reg(pi, RADIO_2064_REG078, 0x80);
+-	or_radio_reg(pi, RADIO_2064_REG129, 0x02);
+-
+-	or_radio_reg(pi, RADIO_2064_REG057, 0x01);
+-
+-	or_radio_reg(pi, RADIO_2064_REG05B, 0x02);
+-	mdelay(5);
+-	SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000);
+-
+-	if (wlc_radio_2064_rcal_done(pi)) {
+-		rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C);
+-		rcal_value = rcal_value & 0x1f;
+-	}
+-
+-	and_radio_reg(pi, RADIO_2064_REG05B, 0xfD);
+-
+-	and_radio_reg(pi, RADIO_2064_REG057, 0xFE);
+-}
+-
+-static void wlc_lcnphy_rc_cal(phy_info_t *pi)
+-{
+-	u8 dflt_rc_cal_val;
+-	u16 flt_val;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	dflt_rc_cal_val = 7;
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1))
+-		dflt_rc_cal_val = 11;
+-	flt_val =
+-	    (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) |
+-	    (dflt_rc_cal_val);
+-	write_phy_reg(pi, 0x933, flt_val);
+-	write_phy_reg(pi, 0x934, flt_val);
+-	write_phy_reg(pi, 0x935, flt_val);
+-	write_phy_reg(pi, 0x936, flt_val);
+-	write_phy_reg(pi, 0x937, (flt_val & 0x1FF));
+-
+-	return;
+-}
+-
+-static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi)
+-{
+-	s8 txpwr = 0;
+-	int i;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		u16 cckpo = 0;
+-		u32 offset_ofdm, offset_mcs;
+-
+-		pi_lcn->lcnphy_tr_isolation_mid =
+-		    (u8) PHY_GETINTVAR(pi, "triso2g");
+-
+-		pi_lcn->lcnphy_rx_power_offset =
+-		    (u8) PHY_GETINTVAR(pi, "rxpo2g");
+-
+-		pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0");
+-		pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1");
+-		pi->txpa_2g[2] = (s16) PHY_GETINTVAR(pi, "pa0b2");
+-
+-		pi_lcn->lcnphy_rssi_vf = (u8) PHY_GETINTVAR(pi, "rssismf2g");
+-		pi_lcn->lcnphy_rssi_vc = (u8) PHY_GETINTVAR(pi, "rssismc2g");
+-		pi_lcn->lcnphy_rssi_gs = (u8) PHY_GETINTVAR(pi, "rssisav2g");
+-
+-		{
+-			pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf;
+-			pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc;
+-			pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs;
+-
+-			pi_lcn->lcnphy_rssi_vf_hightemp =
+-			    pi_lcn->lcnphy_rssi_vf;
+-			pi_lcn->lcnphy_rssi_vc_hightemp =
+-			    pi_lcn->lcnphy_rssi_vc;
+-			pi_lcn->lcnphy_rssi_gs_hightemp =
+-			    pi_lcn->lcnphy_rssi_gs;
+-		}
+-
+-		txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0");
+-		pi->tx_srom_max_2g = txpwr;
+-
+-		for (i = 0; i < PWRTBL_NUM_COEFF; i++) {
+-			pi->txpa_2g_low_temp[i] = pi->txpa_2g[i];
+-			pi->txpa_2g_high_temp[i] = pi->txpa_2g[i];
+-		}
+-
+-		cckpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
+-		if (cckpo) {
+-			uint max_pwr_chan = txpwr;
+-
+-			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+-				pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+-				    ((cckpo & 0xf) * 2);
+-				cckpo >>= 4;
+-			}
+-
+-			offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+-				pi->tx_srom_max_rate_2g[i] = max_pwr_chan -
+-				    ((offset_ofdm & 0xf) * 2);
+-				offset_ofdm >>= 4;
+-			}
+-		} else {
+-			u8 opo = 0;
+-
+-			opo = (u8) PHY_GETINTVAR(pi, "opo");
+-
+-			for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) {
+-				pi->tx_srom_max_rate_2g[i] = txpwr;
+-			}
+-
+-			offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-
+-			for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) {
+-				pi->tx_srom_max_rate_2g[i] = txpwr -
+-				    ((offset_ofdm & 0xf) * 2);
+-				offset_ofdm >>= 4;
+-			}
+-			offset_mcs =
+-			    ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) |
+-			    (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
+-			pi_lcn->lcnphy_mcs20_po = offset_mcs;
+-			for (i = TXP_FIRST_SISO_MCS_20;
+-			     i <= TXP_LAST_SISO_MCS_20; i++) {
+-				pi->tx_srom_max_rate_2g[i] =
+-				    txpwr - ((offset_mcs & 0xf) * 2);
+-				offset_mcs >>= 4;
+-			}
+-		}
+-
+-		pi_lcn->lcnphy_rawtempsense =
+-		    (u16) PHY_GETINTVAR(pi, "rawtempsense");
+-		pi_lcn->lcnphy_measPower =
+-		    (u8) PHY_GETINTVAR(pi, "measpower");
+-		pi_lcn->lcnphy_tempsense_slope =
+-		    (u8) PHY_GETINTVAR(pi, "tempsense_slope");
+-		pi_lcn->lcnphy_hw_iqcal_en =
+-		    (bool) PHY_GETINTVAR(pi, "hw_iqcal_en");
+-		pi_lcn->lcnphy_iqcal_swp_dis =
+-		    (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis");
+-		pi_lcn->lcnphy_tempcorrx =
+-		    (u8) PHY_GETINTVAR(pi, "tempcorrx");
+-		pi_lcn->lcnphy_tempsense_option =
+-		    (u8) PHY_GETINTVAR(pi, "tempsense_option");
+-		pi_lcn->lcnphy_freqoffset_corr =
+-		    (u8) PHY_GETINTVAR(pi, "freqoffset_corr");
+-		if ((u8) getintvar(pi->vars, "aa2g") > 1)
+-			wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi,
+-					      (u8) getintvar(pi->vars,
+-								"aa2g"));
+-	}
+-	pi_lcn->lcnphy_cck_dig_filt_type = -1;
+-	if (PHY_GETVAR(pi, "cckdigfilttype")) {
+-		s16 temp;
+-		temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype");
+-		if (temp >= 0) {
+-			pi_lcn->lcnphy_cck_dig_filt_type = temp;
+-		}
+-	}
+-
+-	return true;
+-}
+-
+-void wlc_2064_vco_cal(phy_info_t *pi)
+-{
+-	u8 calnrst;
+-
+-	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3);
+-	calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8;
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst);
+-	udelay(1);
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03);
+-	udelay(1);
+-	write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07);
+-	udelay(300);
+-	mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0);
+-}
+-
+-static void
+-wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel)
+-{
+-	uint i;
+-	const chan_info_2064_lcnphy_t *ci;
+-	u8 rfpll_doubler = 0;
+-	u8 pll_pwrup, pll_pwrup_ovr;
+-	fixed qFxtal, qFref, qFvco, qFcal;
+-	u8 d15, d16, f16, e44, e45;
+-	u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div;
+-	u16 loop_bw, d30, setCount;
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-	ci = &chan_info_2064_lcnphy[0];
+-	rfpll_doubler = 1;
+-
+-	mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
+-
+-	write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
+-	if (!rfpll_doubler) {
+-		loop_bw = PLL_2064_LOOP_BW;
+-		d30 = PLL_2064_D30;
+-	} else {
+-		loop_bw = PLL_2064_LOOP_BW_DOUBLER;
+-		d30 = PLL_2064_D30_DOUBLER;
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
+-			if (chan_info_2064_lcnphy[i].chan == channel)
+-				break;
+-
+-		if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) {
+-			return;
+-		}
+-
+-		ci = &chan_info_2064_lcnphy[i];
+-	}
+-
+-	write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2,
+-		      (ci->logen_rccr_rx) << 2);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4,
+-		      (ci->pa_rxrf_lna2_freq_tune) << 4);
+-
+-	write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1);
+-
+-	pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044);
+-	pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B);
+-
+-	or_radio_reg(pi, RADIO_2064_REG044, 0x07);
+-
+-	or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1);
+-	e44 = 0;
+-	e45 = 0;
+-
+-	fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
+-	if (pi->xtalfreq > 26000000)
+-		e44 = 1;
+-	if (pi->xtalfreq > 52000000)
+-		e45 = 1;
+-	if (e44 == 0)
+-		fcal_div = 1;
+-	else if (e45 == 0)
+-		fcal_div = 2;
+-	else
+-		fcal_div = 4;
+-	fvco3 = (ci->freq * 3);
+-	fref3 = 2 * fpfd;
+-
+-	qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16);
+-	qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16);
+-	qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ;
+-	qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16);
+-
+-	write_radio_reg(pi, RADIO_2064_REG04F, 0x02);
+-
+-	d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1;
+-	write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2)));
+-	write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5);
+-
+-	d16 = (qFcal * 8 / (d15 + 1)) - 1;
+-	write_radio_reg(pi, RADIO_2064_REG051, d16);
+-
+-	f16 = ((d16 + 1) * (d15 + 1)) / qFcal;
+-	setCount = f16 * 3 * (ci->freq) / 32 - 1;
+-	mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0),
+-		      (u8) (setCount >> 8));
+-
+-	or_radio_reg(pi, RADIO_2064_REG053, 0x10);
+-	write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff));
+-
+-	div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4;
+-
+-	div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4;
+-	while (div_frac >= fref3) {
+-		div_int++;
+-		div_frac -= fref3;
+-	}
+-	div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0),
+-		      (u8) (div_int >> 4));
+-	mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4),
+-		      (u8) (div_int << 4));
+-	mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0),
+-		      (u8) (div_frac >> 16));
+-	write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff);
+-	write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff);
+-
+-	write_radio_reg(pi, RADIO_2064_REG040, 0xfb);
+-
+-	write_radio_reg(pi, RADIO_2064_REG041, 0x9A);
+-	write_radio_reg(pi, RADIO_2064_REG042, 0xA3);
+-	write_radio_reg(pi, RADIO_2064_REG043, 0x0C);
+-
+-	{
+-		u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current;
+-		u16 c29, c38, c30, g30, d28;
+-		c29 = loop_bw;
+-		d29 = 200;
+-		c38 = 1250;
+-		h29 = d29 / c29;
+-		h23 = 1;
+-		c28 = 30;
+-		d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) *
+-			(fvco3 / 2 - PLL_2064_LOW_END_VCO)) /
+-		       (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO))
+-		    + PLL_2064_LOW_END_KVCO;
+-		h28_ten = (d28 * 10) / c28;
+-		c30 = 2640;
+-		e30 = (d30 - 680) / 490;
+-		g30 = 680 + (e30 * 490);
+-		h30_ten = (g30 * 10) / c30;
+-		cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten;
+-		mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current);
+-	}
+-	if (channel >= 1 && channel <= 5)
+-		write_radio_reg(pi, RADIO_2064_REG03C, 0x8);
+-	else
+-		write_radio_reg(pi, RADIO_2064_REG03C, 0x7);
+-	write_radio_reg(pi, RADIO_2064_REG03D, 0x3);
+-
+-	mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c);
+-	udelay(1);
+-
+-	wlc_2064_vco_cal(pi);
+-
+-	write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup);
+-	write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr);
+-	if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
+-		write_radio_reg(pi, RADIO_2064_REG038, 3);
+-		write_radio_reg(pi, RADIO_2064_REG091, 7);
+-	}
+-}
+-
+-bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi)
+-{
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
+-		return 0;
+-	else
+-		return (LCNPHY_TX_PWR_CTRL_HW ==
+-			wlc_lcnphy_get_tx_pwr_ctrl((pi)));
+-}
+-
+-void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi)
+-{
+-	u16 pwr_ctrl;
+-	if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) {
+-		wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL);
+-	} else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) {
+-
+-		pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
+-		wlc_lcnphy_txpower_recalc_target(pi);
+-
+-		wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl);
+-	} else
+-		return;
+-}
+-
+-void wlc_phy_detach_lcnphy(phy_info_t *pi)
+-{
+-	kfree(pi->u.pi_lcnphy);
+-}
+-
+-bool wlc_phy_attach_lcnphy(phy_info_t *pi)
+-{
+-	phy_info_lcnphy_t *pi_lcn;
+-
+-	pi->u.pi_lcnphy = kzalloc(sizeof(phy_info_lcnphy_t), GFP_ATOMIC);
+-	if (pi->u.pi_lcnphy == NULL) {
+-		return false;
+-	}
+-
+-	pi_lcn = pi->u.pi_lcnphy;
+-
+-	if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) {
+-		pi->hwpwrctrl = true;
+-		pi->hwpwrctrl_capable = true;
+-	}
+-
+-	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
+-	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
+-
+-	pi->pi_fptr.init = wlc_phy_init_lcnphy;
+-	pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy;
+-	pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy;
+-	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy;
+-	pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc;
+-	pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc;
+-	pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc;
+-	pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft;
+-	pi->pi_fptr.detach = wlc_phy_detach_lcnphy;
+-
+-	if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
+-		return false;
+-
+-	if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
+-		if (pi_lcn->lcnphy_tempsense_option == 3) {
+-			pi->hwpwrctrl = true;
+-			pi->hwpwrctrl_capable = true;
+-			pi->temppwrctrl_capable = false;
+-		} else {
+-			pi->hwpwrctrl = false;
+-			pi->hwpwrctrl_capable = false;
+-			pi->temppwrctrl_capable = true;
+-		}
+-	}
+-
+-	return true;
+-}
+-
+-static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain)
+-{
+-	u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19;
+-
+-	trsw = (gain & ((u32) 1 << 28)) ? 0 : 1;
+-	ext_lna = (u16) (gain >> 29) & 0x01;
+-	lna1 = (u16) (gain >> 0) & 0x0f;
+-	lna2 = (u16) (gain >> 4) & 0x0f;
+-	tia = (u16) (gain >> 8) & 0xf;
+-	biq0 = (u16) (gain >> 12) & 0xf;
+-	biq1 = (u16) (gain >> 16) & 0xf;
+-
+-	gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) |
+-			     ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) |
+-			     ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12));
+-	gain16_19 = biq1;
+-
+-	mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0);
+-	mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9);
+-	mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10);
+-	mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
+-	mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
+-		mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
+-	}
+-	wlc_lcnphy_rx_gain_override_enable(pi, true);
+-}
+-
+-static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index)
+-{
+-	u32 received_power = 0;
+-	s32 max_index = 0;
+-	u32 gain_code = 0;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	max_index = 36;
+-	if (*gain_index >= 0)
+-		gain_code = lcnphy_23bitgaincode_table[*gain_index];
+-
+-	if (-1 == *gain_index) {
+-		*gain_index = 0;
+-		while ((*gain_index <= (s32) max_index)
+-		       && (received_power < 700)) {
+-			wlc_lcnphy_set_rx_gain(pi,
+-					       lcnphy_23bitgaincode_table
+-					       [*gain_index]);
+-			received_power =
+-			    wlc_lcnphy_measure_digital_power(pi,
+-							     pi_lcn->
+-							     lcnphy_noise_samples);
+-			(*gain_index)++;
+-		}
+-		(*gain_index)--;
+-	} else {
+-		wlc_lcnphy_set_rx_gain(pi, gain_code);
+-		received_power =
+-		    wlc_lcnphy_measure_digital_power(pi,
+-						     pi_lcn->
+-						     lcnphy_noise_samples);
+-	}
+-
+-	return received_power;
+-}
+-
+-s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index)
+-{
+-	s32 gain = 0;
+-	s32 nominal_power_db;
+-	s32 log_val, gain_mismatch, desired_gain, input_power_offset_db,
+-	    input_power_db;
+-	s32 received_power, temperature;
+-	uint freq;
+-	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
+-
+-	received_power = wlc_lcnphy_get_receive_power(pi, &gain_index);
+-
+-	gain = lcnphy_gain_table[gain_index];
+-
+-	nominal_power_db = read_phy_reg(pi, 0x425) >> 8;
+-
+-	{
+-		u32 power = (received_power * 16);
+-		u32 msb1, msb2, val1, val2, diff1, diff2;
+-		msb1 = ffs(power) - 1;
+-		msb2 = msb1 + 1;
+-		val1 = 1 << msb1;
+-		val2 = 1 << msb2;
+-		diff1 = (power - val1);
+-		diff2 = (val2 - power);
+-		if (diff1 < diff2)
+-			log_val = msb1;
+-		else
+-			log_val = msb2;
+-	}
+-
+-	log_val = log_val * 3;
+-
+-	gain_mismatch = (nominal_power_db / 2) - (log_val);
+-
+-	desired_gain = gain + gain_mismatch;
+-
+-	input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF;
+-
+-	if (input_power_offset_db > 127)
+-		input_power_offset_db -= 256;
+-
+-	input_power_db = input_power_offset_db - desired_gain;
+-
+-	input_power_db =
+-	    input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index];
+-
+-	freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec));
+-	if ((freq > 2427) && (freq <= 2467))
+-		input_power_db = input_power_db - 1;
+-
+-	temperature = pi_lcn->lcnphy_lastsensed_temperature;
+-
+-	if ((temperature - 15) < -30) {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+-		    7;
+-	} else if ((temperature - 15) < 4) {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12) -
+-		    3;
+-	} else {
+-		input_power_db =
+-		    input_power_db + (((temperature - 10 - 25) * 286) >> 12);
+-	}
+-
+-	wlc_lcnphy_rx_gain_override_enable(pi, 0);
+-
+-	return input_power_db;
+-}
+-
+-static int
+-wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type)
+-{
+-	s16 filt_index = -1;
+-	int j;
+-
+-	u16 addr[] = {
+-		0x910,
+-		0x91e,
+-		0x91f,
+-		0x924,
+-		0x925,
+-		0x926,
+-		0x920,
+-		0x921,
+-		0x927,
+-		0x928,
+-		0x929,
+-		0x922,
+-		0x923,
+-		0x930,
+-		0x931,
+-		0x932
+-	};
+-
+-	u16 addr_ofdm[] = {
+-		0x90f,
+-		0x900,
+-		0x901,
+-		0x906,
+-		0x907,
+-		0x908,
+-		0x902,
+-		0x903,
+-		0x909,
+-		0x90a,
+-		0x90b,
+-		0x904,
+-		0x905,
+-		0x90c,
+-		0x90d,
+-		0x90e
+-	};
+-
+-	if (!is_ofdm) {
+-		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) {
+-			if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) {
+-				filt_index = (s16) j;
+-				break;
+-			}
+-		}
+-
+-		if (filt_index != -1) {
+-			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, addr[j],
+-					      LCNPHY_txdigfiltcoeffs_cck
+-					      [filt_index][j + 1]);
+-			}
+-		}
+-	} else {
+-		for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) {
+-			if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) {
+-				filt_index = (s16) j;
+-				break;
+-			}
+-		}
+-
+-		if (filt_index != -1) {
+-			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, addr_ofdm[j],
+-					      LCNPHY_txdigfiltcoeffs_ofdm
+-					      [filt_index][j + 1]);
+-			}
+-		}
+-	}
+-
+-	return (filt_index != -1) ? 0 : -1;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
+deleted file mode 100644
+index b7bfc72..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h
++++ /dev/null
+@@ -1,119 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_lcn_h_
+-#define _wlc_phy_lcn_h_
+-
+-struct phy_info_lcnphy {
+-	int lcnphy_txrf_sp_9_override;
+-	u8 lcnphy_full_cal_channel;
+-	u8 lcnphy_cal_counter;
+-	u16 lcnphy_cal_temper;
+-	bool lcnphy_recal;
+-
+-	u8 lcnphy_rc_cap;
+-	u32 lcnphy_mcs20_po;
+-
+-	u8 lcnphy_tr_isolation_mid;
+-	u8 lcnphy_tr_isolation_low;
+-	u8 lcnphy_tr_isolation_hi;
+-
+-	u8 lcnphy_bx_arch;
+-	u8 lcnphy_rx_power_offset;
+-	u8 lcnphy_rssi_vf;
+-	u8 lcnphy_rssi_vc;
+-	u8 lcnphy_rssi_gs;
+-	u8 lcnphy_tssi_val;
+-	u8 lcnphy_rssi_vf_lowtemp;
+-	u8 lcnphy_rssi_vc_lowtemp;
+-	u8 lcnphy_rssi_gs_lowtemp;
+-
+-	u8 lcnphy_rssi_vf_hightemp;
+-	u8 lcnphy_rssi_vc_hightemp;
+-	u8 lcnphy_rssi_gs_hightemp;
+-
+-	s16 lcnphy_pa0b0;
+-	s16 lcnphy_pa0b1;
+-	s16 lcnphy_pa0b2;
+-
+-	u16 lcnphy_rawtempsense;
+-	u8 lcnphy_measPower;
+-	u8 lcnphy_tempsense_slope;
+-	u8 lcnphy_freqoffset_corr;
+-	u8 lcnphy_tempsense_option;
+-	u8 lcnphy_tempcorrx;
+-	bool lcnphy_iqcal_swp_dis;
+-	bool lcnphy_hw_iqcal_en;
+-	uint lcnphy_bandedge_corr;
+-	bool lcnphy_spurmod;
+-	u16 lcnphy_tssi_tx_cnt;
+-	u16 lcnphy_tssi_idx;
+-	u16 lcnphy_tssi_npt;
+-
+-	u16 lcnphy_target_tx_freq;
+-	s8 lcnphy_tx_power_idx_override;
+-	u16 lcnphy_noise_samples;
+-
+-	u32 lcnphy_papdRxGnIdx;
+-	u32 lcnphy_papd_rxGnCtrl_init;
+-
+-	u32 lcnphy_gain_idx_14_lowword;
+-	u32 lcnphy_gain_idx_14_hiword;
+-	u32 lcnphy_gain_idx_27_lowword;
+-	u32 lcnphy_gain_idx_27_hiword;
+-	s16 lcnphy_ofdmgainidxtableoffset;
+-	s16 lcnphy_dsssgainidxtableoffset;
+-	u32 lcnphy_tr_R_gain_val;
+-	u32 lcnphy_tr_T_gain_val;
+-	s8 lcnphy_input_pwr_offset_db;
+-	u16 lcnphy_Med_Low_Gain_db;
+-	u16 lcnphy_Very_Low_Gain_db;
+-	s8 lcnphy_lastsensed_temperature;
+-	s8 lcnphy_pkteng_rssi_slope;
+-	u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
+-	u8 lcnphy_volt_winner;
+-	u8 lcnphy_volt_low;
+-	u8 lcnphy_54_48_36_24mbps_backoff;
+-	u8 lcnphy_11n_backoff;
+-	u8 lcnphy_lowerofdm;
+-	u8 lcnphy_cck;
+-	u8 lcnphy_psat_2pt3_detected;
+-	s32 lcnphy_lowest_Re_div_Im;
+-	s8 lcnphy_final_papd_cal_idx;
+-	u16 lcnphy_extstxctrl4;
+-	u16 lcnphy_extstxctrl0;
+-	u16 lcnphy_extstxctrl1;
+-	s16 lcnphy_cck_dig_filt_type;
+-	s16 lcnphy_ofdm_dig_filt_type;
+-	lcnphy_cal_results_t lcnphy_cal_results;
+-
+-	u8 lcnphy_psat_pwr;
+-	u8 lcnphy_psat_indx;
+-	s32 lcnphy_min_phase;
+-	u8 lcnphy_final_idx;
+-	u8 lcnphy_start_idx;
+-	u8 lcnphy_current_index;
+-	u16 lcnphy_logen_buf_1;
+-	u16 lcnphy_local_ovr_2;
+-	u16 lcnphy_local_oval_6;
+-	u16 lcnphy_local_oval_5;
+-	u16 lcnphy_logen_mixer_1;
+-
+-	u8 lcnphy_aci_stat;
+-	uint lcnphy_aci_start_time;
+-	s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
+-};
+-#endif				/* _wlc_phy_lcn_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
+deleted file mode 100644
+index 7127509..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
++++ /dev/null
+@@ -1,29169 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <bcmdefs.h>
+-#include <wlc_cfg.h>
+-#include <linux/delay.h>
+-#include <linux/pci.h>
+-#include <aiutils.h>
+-#include <sbchipc.h>
+-#include <wlc_pmu.h>
+-
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-
+-#include <wlc_phy_radio.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phyreg_n.h>
+-#include <wlc_phytbl_n.h>
+-
+-#define	READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+-	((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1))
+-#define	WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \
+-	((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value);
+-#define	WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \
+-	write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value);
+-
+-#define	READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+-	radio_type##_##jspace##1##_##reg_name));
+-#define	WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \
+-	radio_type##_##jspace##1##_##reg_name), value);
+-#define	READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \
+-	read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+-	radio_type##_##reg_name##_##jspace##1));
+-#define	WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \
+-	write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \
+-	radio_type##_##reg_name##_##jspace##1), value);
+-
+-#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40
+-#define NPHY_ACI_CHANNEL_DELTA 5
+-#define NPHY_ACI_CHANNEL_SKIP 4
+-#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6
+-#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5
+-#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6
+-#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5
+-#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4
+-#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3
+-
+-#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2
+-
+-#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8
+-
+-#define NPHY_NOISE_NOASSOC_ENTER_TH  400
+-
+-#define NPHY_NOISE_ASSOC_ENTER_TH  400
+-
+-#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH  400
+-
+-#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44
+-#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56
+-
+-#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16
+-
+-#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8
+-
+-#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5)
+-
+-#define NPHY_RSSICAL_MAXREAD 31
+-
+-#define NPHY_RSSICAL_NPOLL 8
+-#define NPHY_RSSICAL_MAXD  (1<<20)
+-#define NPHY_MIN_RXIQ_PWR 2
+-
+-#define NPHY_RSSICAL_W1_TARGET 25
+-#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET
+-#define NPHY_RSSICAL_NB_TARGET 0
+-
+-#define NPHY_RSSICAL_W1_TARGET_REV3 29
+-#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3
+-
+-#define NPHY_CALSANITY_RSSI_NB_MAX_POS  9
+-#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9
+-#define NPHY_CALSANITY_RSSI_W1_MAX_POS  12
+-#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD)
+-#define NPHY_CALSANITY_RSSI_W2_MAX_POS  NPHY_CALSANITY_RSSI_W1_MAX_POS
+-#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD)
+-#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f)))
+-#define NPHY_RSSI_NB_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG))
+-#define NPHY_RSSI_W1_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG))
+-#define NPHY_RSSI_W2_VIOL(x)  (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \
+-			       ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG))
+-
+-#define NPHY_IQCAL_NUMGAINS 9
+-#define NPHY_N_GCTL 0x66
+-
+-#define NPHY_PAPD_EPS_TBL_SIZE 64
+-#define NPHY_PAPD_SCL_TBL_SIZE 64
+-#define NPHY_NUM_DIG_FILT_COEFFS 15
+-
+-#define NPHY_PAPD_COMP_OFF 0
+-#define NPHY_PAPD_COMP_ON  1
+-
+-#define NPHY_SROM_TEMPSHIFT		32
+-#define NPHY_SROM_MAXTEMPOFFSET		16
+-#define NPHY_SROM_MINTEMPOFFSET		-16
+-
+-#define NPHY_CAL_MAXTEMPDELTA		64
+-
+-#define NPHY_NOISEVAR_TBLLEN40 256
+-#define NPHY_NOISEVAR_TBLLEN20 128
+-
+-#define NPHY_ANARXLPFBW_REDUCTIONFACT 7
+-
+-#define NPHY_ADJUSTED_MINCRSPOWER 0x1e
+-
+-typedef struct _nphy_iqcal_params {
+-	u16 txlpf;
+-	u16 txgm;
+-	u16 pga;
+-	u16 pad;
+-	u16 ipa;
+-	u16 cal_gain;
+-	u16 ncorr[5];
+-} nphy_iqcal_params_t;
+-
+-typedef struct _nphy_txiqcal_ladder {
+-	u8 percent;
+-	u8 g_env;
+-} nphy_txiqcal_ladder_t;
+-
+-typedef struct {
+-	nphy_txgains_t gains;
+-	bool useindex;
+-	u8 index;
+-} nphy_ipa_txcalgains_t;
+-
+-typedef struct nphy_papd_restore_state_t {
+-	u16 fbmix[2];
+-	u16 vga_master[2];
+-	u16 intpa_master[2];
+-	u16 afectrl[2];
+-	u16 afeoverride[2];
+-	u16 pwrup[2];
+-	u16 atten[2];
+-	u16 mm;
+-} nphy_papd_restore_state;
+-
+-typedef struct _nphy_ipa_txrxgain {
+-	u16 hpvga;
+-	u16 lpf_biq1;
+-	u16 lpf_biq0;
+-	u16 lna2;
+-	u16 lna1;
+-	s8 txpwrindex;
+-} nphy_ipa_txrxgain_t;
+-
+-#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1)
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100},
+-{0, 0, 0, 0, 0, 50},
+-{0, 0, 0, 0, 0, -1},
+-{0, 0, 0, 3, 0, -1},
+-{0, 0, 3, 3, 0, -1},
+-{0, 2, 3, 3, 0, -1}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128},
+-{0, 0, 0, 0, 0, 70},
+-{0, 0, 0, 0, 0, 20},
+-{0, 0, 0, 3, 0, 20},
+-{0, 0, 3, 3, 0, 20},
+-{0, 2, 3, 3, 0, 20}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100},
+-{0, 0, 0, 0, 0, 50},
+-{0, 0, 0, 0, 0, -1},
+-{0, 0, 0, 3, 0, -1},
+-{0, 0, 3, 3, 0, -1},
+-{0, 0, 5, 3, 0, -1}
+-};
+-
+-nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10},
+-{0, 0, 0, 1, 0, 10},
+-{0, 0, 1, 2, 0, 10},
+-{0, 0, 1, 3, 0, 10},
+-{0, 0, 4, 3, 0, 10},
+-{0, 0, 6, 3, 0, 10}
+-};
+-
+-#define NPHY_RXCAL_TONEAMP 181
+-#define NPHY_RXCAL_TONEFREQ_40MHz 4000
+-#define NPHY_RXCAL_TONEFREQ_20MHz 2000
+-
+-enum {
+-	NPHY_RXCAL_GAIN_INIT = 0,
+-	NPHY_RXCAL_GAIN_UP,
+-	NPHY_RXCAL_GAIN_DOWN
+-};
+-
+-#define wlc_phy_get_papd_nphy(pi) \
+-	(read_phy_reg((pi), 0x1e7) & \
+-			((0x1 << 15) | \
+-			(0x1 << 14) | \
+-			(0x1 << 13)))
+-
+-#define TXFILT_SHAPING_OFDM20   0
+-#define TXFILT_SHAPING_OFDM40   1
+-#define TXFILT_SHAPING_CCK      2
+-#define TXFILT_DEFAULT_OFDM20   3
+-#define TXFILT_DEFAULT_OFDM40   4
+-
+-u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = {
+-	{-377, 137, -407, 208, -1527, 956, 93, 186, 93,
+-	 230, -44, 230, 201, -191, 201},
+-	{-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5,
+-	 26, 34, -32, 34},
+-	{-360, 164, -376, 164, -1533, 576, 308, -314, 308,
+-	 121, -73, 121, 91, 124, 91},
+-	{-295, 200, -363, 142, -1391, 826, 151, 301, 151,
+-	 151, 301, 151, 602, -752, 602},
+-	{-92, 58, -96, 49, -104, 44, 17, 35, 17,
+-	 12, 25, 12, 13, 27, 13},
+-	{-375, 136, -399, 209, -1479, 949, 130, 260, 130,
+-	 230, -44, 230, 201, -191, 201},
+-	{0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97,
+-	 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a}
+-};
+-
+-typedef struct _chan_info_nphy_2055 {
+-	u16 chan;
+-	u16 freq;
+-	uint unknown;
+-	u8 RF_pll_ref;
+-	u8 RF_rf_pll_mod1;
+-	u8 RF_rf_pll_mod0;
+-	u8 RF_vco_cap_tail;
+-	u8 RF_vco_cal1;
+-	u8 RF_vco_cal2;
+-	u8 RF_pll_lf_c1;
+-	u8 RF_pll_lf_r1;
+-	u8 RF_pll_lf_c2;
+-	u8 RF_lgbuf_cen_buf;
+-	u8 RF_lgen_tune1;
+-	u8 RF_lgen_tune2;
+-	u8 RF_core1_lgbuf_a_tune;
+-	u8 RF_core1_lgbuf_g_tune;
+-	u8 RF_core1_rxrf_reg1;
+-	u8 RF_core1_tx_pga_pad_tn;
+-	u8 RF_core1_tx_mx_bgtrim;
+-	u8 RF_core2_lgbuf_a_tune;
+-	u8 RF_core2_lgbuf_g_tune;
+-	u8 RF_core2_rxrf_reg1;
+-	u8 RF_core2_tx_pga_pad_tn;
+-	u8 RF_core2_tx_mx_bgtrim;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_2055_t;
+-
+-typedef struct _chan_info_nphy_radio205x {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_SYN_pll_vcocal1;
+-	u8 RF_SYN_pll_vcocal2;
+-	u8 RF_SYN_pll_refdiv;
+-	u8 RF_SYN_pll_mmd2;
+-	u8 RF_SYN_pll_mmd1;
+-	u8 RF_SYN_pll_loopfilter1;
+-	u8 RF_SYN_pll_loopfilter2;
+-	u8 RF_SYN_pll_loopfilter3;
+-	u8 RF_SYN_pll_loopfilter4;
+-	u8 RF_SYN_pll_loopfilter5;
+-	u8 RF_SYN_reserved_addr27;
+-	u8 RF_SYN_reserved_addr28;
+-	u8 RF_SYN_reserved_addr29;
+-	u8 RF_SYN_logen_VCOBUF1;
+-	u8 RF_SYN_logen_MIXER2;
+-	u8 RF_SYN_logen_BUF3;
+-	u8 RF_SYN_logen_BUF4;
+-	u8 RF_RX0_lnaa_tune;
+-	u8 RF_RX0_lnag_tune;
+-	u8 RF_TX0_intpaa_boost_tune;
+-	u8 RF_TX0_intpag_boost_tune;
+-	u8 RF_TX0_pada_boost_tune;
+-	u8 RF_TX0_padg_boost_tune;
+-	u8 RF_TX0_pgaa_boost_tune;
+-	u8 RF_TX0_pgag_boost_tune;
+-	u8 RF_TX0_mixa_boost_tune;
+-	u8 RF_TX0_mixg_boost_tune;
+-	u8 RF_RX1_lnaa_tune;
+-	u8 RF_RX1_lnag_tune;
+-	u8 RF_TX1_intpaa_boost_tune;
+-	u8 RF_TX1_intpag_boost_tune;
+-	u8 RF_TX1_pada_boost_tune;
+-	u8 RF_TX1_padg_boost_tune;
+-	u8 RF_TX1_pgaa_boost_tune;
+-	u8 RF_TX1_pgag_boost_tune;
+-	u8 RF_TX1_mixa_boost_tune;
+-	u8 RF_TX1_mixg_boost_tune;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio205x_t;
+-
+-typedef struct _chan_info_nphy_radio2057 {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_vcocal_countval0;
+-	u8 RF_vcocal_countval1;
+-	u8 RF_rfpll_refmaster_sparextalsize;
+-	u8 RF_rfpll_loopfilter_r1;
+-	u8 RF_rfpll_loopfilter_c2;
+-	u8 RF_rfpll_loopfilter_c1;
+-	u8 RF_cp_kpd_idac;
+-	u8 RF_rfpll_mmd0;
+-	u8 RF_rfpll_mmd1;
+-	u8 RF_vcobuf_tune;
+-	u8 RF_logen_mx2g_tune;
+-	u8 RF_logen_mx5g_tune;
+-	u8 RF_logen_indbuf2g_tune;
+-	u8 RF_logen_indbuf5g_tune;
+-	u8 RF_txmix2g_tune_boost_pu_core0;
+-	u8 RF_pad2g_tune_pus_core0;
+-	u8 RF_pga_boost_tune_core0;
+-	u8 RF_txmix5g_boost_tune_core0;
+-	u8 RF_pad5g_tune_misc_pus_core0;
+-	u8 RF_lna2g_tune_core0;
+-	u8 RF_lna5g_tune_core0;
+-	u8 RF_txmix2g_tune_boost_pu_core1;
+-	u8 RF_pad2g_tune_pus_core1;
+-	u8 RF_pga_boost_tune_core1;
+-	u8 RF_txmix5g_boost_tune_core1;
+-	u8 RF_pad5g_tune_misc_pus_core1;
+-	u8 RF_lna2g_tune_core1;
+-	u8 RF_lna5g_tune_core1;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio2057_t;
+-
+-typedef struct _chan_info_nphy_radio2057_rev5 {
+-	u16 chan;
+-	u16 freq;
+-	u8 RF_vcocal_countval0;
+-	u8 RF_vcocal_countval1;
+-	u8 RF_rfpll_refmaster_sparextalsize;
+-	u8 RF_rfpll_loopfilter_r1;
+-	u8 RF_rfpll_loopfilter_c2;
+-	u8 RF_rfpll_loopfilter_c1;
+-	u8 RF_cp_kpd_idac;
+-	u8 RF_rfpll_mmd0;
+-	u8 RF_rfpll_mmd1;
+-	u8 RF_vcobuf_tune;
+-	u8 RF_logen_mx2g_tune;
+-	u8 RF_logen_indbuf2g_tune;
+-	u8 RF_txmix2g_tune_boost_pu_core0;
+-	u8 RF_pad2g_tune_pus_core0;
+-	u8 RF_lna2g_tune_core0;
+-	u8 RF_txmix2g_tune_boost_pu_core1;
+-	u8 RF_pad2g_tune_pus_core1;
+-	u8 RF_lna2g_tune_core1;
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} chan_info_nphy_radio2057_rev5_t;
+-
+-typedef struct nphy_sfo_cfg {
+-	u16 PHY_BW1a;
+-	u16 PHY_BW2;
+-	u16 PHY_BW3;
+-	u16 PHY_BW4;
+-	u16 PHY_BW5;
+-	u16 PHY_BW6;
+-} nphy_sfo_cfg_t;
+-
+-static chan_info_nphy_2055_t chan_info_nphy_2055[] = {
+-	{
+-	 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216},
+-	{
+-	 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215},
+-	{
+-	 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214},
+-	{
+-	 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213},
+-	{
+-	 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212},
+-	{
+-	 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211},
+-	{
+-	 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F},
+-	{
+-	 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E},
+-	{
+-	 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D},
+-	{
+-	 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C},
+-	{
+-	 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B},
+-	{
+-	 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A},
+-	{
+-	 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209},
+-	{
+-	 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F,
+-	 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208},
+-	{
+-	 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+-	 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207},
+-	{
+-	 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E,
+-	 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206},
+-	{
+-	 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+-	 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205},
+-	{
+-	 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E,
+-	 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204},
+-	{
+-	 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+-	 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203},
+-	{
+-	 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D,
+-	 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202},
+-	{
+-	 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+-	 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201},
+-	{
+-	 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D,
+-	 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200},
+-	{
+-	 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C,
+-	 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF},
+-	{
+-	 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+-	 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD},
+-	{
+-	 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B,
+-	 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC},
+-	{
+-	 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+-	 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB},
+-	{
+-	 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B,
+-	 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA},
+-	{
+-	 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+-	 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9},
+-	{
+-	 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A,
+-	 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8},
+-	{
+-	 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+-	 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7},
+-	{
+-	 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09,
+-	 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6},
+-	{
+-	 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+-	 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5},
+-	{
+-	 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09,
+-	 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4},
+-	{
+-	 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+-	 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3},
+-	{
+-	 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+-	 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08,
+-	 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2},
+-	{
+-	 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+-	 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1},
+-	{
+-	 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08,
+-	 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0},
+-	{
+-	 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+-	 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0},
+-	{
+-	 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08,
+-	 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF},
+-	{
+-	 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+-	 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE},
+-	{
+-	 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07,
+-	 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED},
+-	{
+-	 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+-	 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC},
+-	{
+-	 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07,
+-	 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB},
+-	{
+-	 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+-	 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA},
+-	{
+-	 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06,
+-	 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9},
+-	{
+-	 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+-	 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8},
+-	{
+-	 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06,
+-	 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7},
+-	{
+-	 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+-	 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6},
+-	{
+-	 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05,
+-	 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5},
+-	{
+-	 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+-	 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5},
+-	{
+-	 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+-	 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05,
+-	 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4},
+-	{
+-	 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+-	 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3},
+-	{
+-	 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04,
+-	 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2},
+-	{
+-	 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+-	 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1},
+-	{
+-	 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+-	 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04,
+-	 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0},
+-	{
+-	 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF},
+-	{
+-	 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE},
+-	{
+-	 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD},
+-	{
+-	 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+-	 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03,
+-	 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD},
+-	{
+-	 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC},
+-	{
+-	 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB},
+-	{
+-	 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA},
+-	{
+-	 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02,
+-	 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9},
+-	{
+-	 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8},
+-	{
+-	 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7},
+-	{
+-	 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7},
+-	{
+-	 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+-	 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6},
+-	{
+-	 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5},
+-	{
+-	 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01,
+-	 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4},
+-	{
+-	 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+-	 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3},
+-	{
+-	 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+-	 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2},
+-	{
+-	 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2},
+-	{
+-	 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1},
+-	{
+-	 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0},
+-	{
+-	 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF},
+-	{
+-	 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE},
+-	{
+-	 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE},
+-	{
+-	 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD},
+-	{
+-	 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC},
+-	{
+-	 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB},
+-	{
+-	 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB},
+-	{
+-	 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA},
+-	{
+-	 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA},
+-	{
+-	 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9},
+-	{
+-	 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9},
+-	{
+-	 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9},
+-	{
+-	 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8},
+-	{
+-	 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8},
+-	{
+-	 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8},
+-	{
+-	 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7},
+-	{
+-	 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7},
+-	{
+-	 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6},
+-	{
+-	 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6},
+-	{
+-	 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6},
+-	{
+-	 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5},
+-	{
+-	 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5},
+-	{
+-	 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4},
+-	{
+-	 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4},
+-	{
+-	 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4},
+-	{
+-	 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3},
+-	{
+-	 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3},
+-	{
+-	 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2},
+-	{
+-	 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2},
+-	{
+-	 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1},
+-	{
+-	 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0},
+-	{
+-	 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF},
+-	{
+-	 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF},
+-	{
+-	 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE},
+-	{
+-	 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD},
+-	{
+-	 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+-	 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+-	 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC},
+-	{
+-	 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D,
+-	 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443},
+-	{
+-	 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441},
+-	{
+-	 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F},
+-	{
+-	 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D},
+-	{
+-	 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C,
+-	 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A},
+-	{
+-	 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B,
+-	 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438},
+-	{
+-	 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A,
+-	 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436},
+-	{
+-	 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A,
+-	 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434},
+-	{
+-	 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09,
+-	 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431},
+-	{
+-	 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08,
+-	 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F},
+-	{
+-	 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08,
+-	 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D},
+-	{
+-	 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08,
+-	 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B},
+-	{
+-	 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07,
+-	 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429},
+-	{
+-	 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+-	 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07,
+-	 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08,
+-	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06,
+-	 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+-	 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05,
+-	 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f,
+-	 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f,
+-	 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f,
+-	 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d,
+-	 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f,
+-	 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b,
+-	 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f,
+-	 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a,
+-	 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f,
+-	 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09,
+-	 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f,
+-	 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07,
+-	 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70,
+-	 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09,
+-	 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70,
+-	 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08,
+-	 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07,
+-	 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06,
+-	 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05,
+-	 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04,
+-	 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03,
+-	 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02,
+-	 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01,
+-	 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+-	 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
+-	 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = {
+-	{
+-	 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216},
+-	{
+-	 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215},
+-	{
+-	 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214},
+-	{
+-	 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213},
+-	{
+-	 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212},
+-	{
+-	 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211},
+-	{
+-	 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f},
+-	{
+-	 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e},
+-	{
+-	 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d},
+-	{
+-	 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c},
+-	{
+-	 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b},
+-	{
+-	 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a},
+-	{
+-	 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209},
+-	{
+-	 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208},
+-	{
+-	 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207},
+-	{
+-	 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206},
+-	{
+-	 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205},
+-	{
+-	 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204},
+-	{
+-	 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203},
+-	{
+-	 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202},
+-	{
+-	 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201},
+-	{
+-	 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200},
+-	{
+-	 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77,
+-	 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f,
+-	 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff},
+-	{
+-	 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd},
+-	{
+-	 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc},
+-	{
+-	 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
+-	 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb},
+-	{
+-	 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa},
+-	{
+-	 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9},
+-	{
+-	 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8},
+-	{
+-	 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7},
+-	{
+-	 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6},
+-	{
+-	 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5},
+-	{
+-	 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4},
+-	{
+-	 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d,
+-	 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3},
+-	{
+-	 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2},
+-	{
+-	 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1},
+-	{
+-	 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0},
+-	{
+-	 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0},
+-	{
+-	 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef},
+-	{
+-	 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c,
+-	 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee},
+-	{
+-	 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed},
+-	{
+-	 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec},
+-	{
+-	 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b,
+-	 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb},
+-	{
+-	 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea},
+-	{
+-	 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9},
+-	{
+-	 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8},
+-	{
+-	 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7},
+-	{
+-	 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6},
+-	{
+-	 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5},
+-	{
+-	 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5},
+-	{
+-	 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a,
+-	 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4},
+-	{
+-	 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3},
+-	{
+-	 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2},
+-	{
+-	 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1},
+-	{
+-	 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0},
+-	{
+-	 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df},
+-	{
+-	 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de},
+-	{
+-	 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd},
+-	{
+-	 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd},
+-	{
+-	 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc},
+-	{
+-	 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db},
+-	{
+-	 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9},
+-	{
+-	 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8},
+-	{
+-	 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09,
+-	 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7},
+-	{
+-	 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7},
+-	{
+-	 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6},
+-	{
+-	 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5},
+-	{
+-	 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08,
+-	 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4},
+-	{
+-	 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3},
+-	{
+-	 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2},
+-	{
+-	 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2},
+-	{
+-	 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07,
+-	 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1},
+-	{
+-	 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0},
+-	{
+-	 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf},
+-	{
+-	 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce},
+-	{
+-	 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce},
+-	{
+-	 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd},
+-	{
+-	 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc},
+-	{
+-	 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb},
+-	{
+-	 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca},
+-	{
+-	 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca},
+-	{
+-	 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9},
+-	{
+-	 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
+-	 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9},
+-	{
+-	 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9},
+-	{
+-	 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8},
+-	{
+-	 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8},
+-	{
+-	 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7},
+-	{
+-	 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7},
+-	{
+-	 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6},
+-	{
+-	 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6},
+-	{
+-	 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5},
+-	{
+-	 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5},
+-	{
+-	 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4},
+-	{
+-	 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4},
+-	{
+-	 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3},
+-	{
+-	 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3},
+-	{
+-	 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
+-	 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2},
+-	{
+-	 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2},
+-	{
+-	 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1},
+-	{
+-	 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0},
+-	{
+-	 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf},
+-	{
+-	 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf},
+-	{
+-	 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be},
+-	{
+-	 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd},
+-	{
+-	 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01,
+-	 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
+-	 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04,
+-	 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc},
+-	{
+-	 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01,
+-	 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+-	 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
+-	 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = {
+-	{
+-	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+-	 0x0215,
+-	 0x0216,
+-	 },
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215,
+-	 },
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214,
+-	 },
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213,
+-	 },
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212,
+-	 },
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211,
+-	 },
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f,
+-	 },
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e,
+-	 },
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d,
+-	 },
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c,
+-	 },
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b,
+-	 },
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a,
+-	 },
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209,
+-	 },
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208,
+-	 },
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207,
+-	 },
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206,
+-	 },
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205,
+-	 },
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204,
+-	 },
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203,
+-	 },
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202,
+-	 },
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201,
+-	 },
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200,
+-	 },
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff,
+-	 },
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd,
+-	 },
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc,
+-	 },
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb,
+-	 },
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa,
+-	 },
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9,
+-	 },
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8,
+-	 },
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7,
+-	 },
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6,
+-	 },
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5,
+-	 },
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4,
+-	 },
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3,
+-	 },
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00,
+-	 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2,
+-	 },
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1,
+-	 },
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0,
+-	 },
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0,
+-	 },
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef,
+-	 },
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee,
+-	 },
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00,
+-	 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed,
+-	 },
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec,
+-	 },
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb,
+-	 },
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea,
+-	 },
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9,
+-	 },
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8,
+-	 },
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00,
+-	 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7,
+-	 },
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6,
+-	 },
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5,
+-	 },
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5,
+-	 },
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4,
+-	 },
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3,
+-	 },
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2,
+-	 },
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00,
+-	 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1,
+-	 },
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0,
+-	 },
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df,
+-	 },
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de,
+-	 },
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd,
+-	 },
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd,
+-	 },
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc,
+-	 },
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db,
+-	 },
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da,
+-	 },
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9,
+-	 },
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8,
+-	 },
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7,
+-	 },
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7,
+-	 },
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00,
+-	 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6,
+-	 },
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5,
+-	 },
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4,
+-	 },
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3,
+-	 },
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2,
+-	 },
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2,
+-	 },
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1,
+-	 },
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00,
+-	 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0,
+-	 },
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf,
+-	 },
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce,
+-	 },
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce,
+-	 },
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd,
+-	 },
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc,
+-	 },
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb,
+-	 },
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb,
+-	 },
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca,
+-	 },
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca,
+-	 },
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9,
+-	 },
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9,
+-	 },
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9,
+-	 },
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8,
+-	 },
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8,
+-	 },
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8,
+-	 },
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7,
+-	 },
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7,
+-	 },
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6,
+-	 },
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6,
+-	 },
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6,
+-	 },
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5,
+-	 },
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5,
+-	 },
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4,
+-	 },
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4,
+-	 },
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4,
+-	 },
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3,
+-	 },
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3,
+-	 },
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2,
+-	 },
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2,
+-	 },
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1,
+-	 },
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0,
+-	 },
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf,
+-	 },
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf,
+-	 },
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be,
+-	 },
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00,
+-	 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd,
+-	 },
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443,
+-	 },
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441,
+-	 },
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f,
+-	 },
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71,
+-	 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d,
+-	 },
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a,
+-	 },
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438,
+-	 },
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436,
+-	 },
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434,
+-	 },
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431,
+-	 },
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f,
+-	 },
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31,
+-	 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d,
+-	 },
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+-	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b,
+-	 },
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11,
+-	 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429,
+-	 },
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11,
+-	 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = {
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+-	 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+-	 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+-	 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+-	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+-	 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+-	 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+-	 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+-	 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+-	 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+-	 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+-	 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+-	 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+-	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+-	 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+-	 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+-	 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = {
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1,
+-	 0x043a, 0x043f, 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3,
+-	 0x0438, 0x043d, 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d,
+-	 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5,
+-	 0x0436, 0x043a, 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c,
+-	 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7,
+-	 0x0434, 0x0438, 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9,
+-	 0x0431, 0x0436, 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c,
+-	 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb,
+-	 0x042f, 0x0434, 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd,
+-	 0x042d, 0x0431, 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf,
+-	 0x042b, 0x042f, 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b,
+-	 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1,
+-	 0x0429, 0x042d, 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3,
+-	 0x0427, 0x042b, 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b,
+-	 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5,
+-	 0x0424, 0x0429, 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b,
+-	 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7,
+-	 0x0422, 0x0427, 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9,
+-	 0x0420, 0x0424, 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a,
+-	 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de,
+-	 0x041b, 0x041f, 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = {
+-	{
+-	 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214,
+-	 0x0215,
+-	 0x0216},
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215},
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214},
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213},
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212},
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211},
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f},
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e},
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d},
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c},
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b},
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a},
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209},
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208},
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207},
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206},
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205},
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204},
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203},
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202},
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201},
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200},
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff},
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd},
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc},
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb},
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa},
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9},
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8},
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7},
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6},
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5},
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4},
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3},
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2},
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1},
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0},
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0},
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef},
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee},
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed},
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec},
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb},
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea},
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9},
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8},
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7},
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6},
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5},
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5},
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4},
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3},
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2},
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1},
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0},
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df},
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de},
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd},
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd},
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc},
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db},
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9},
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8},
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7},
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7},
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6},
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5},
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4},
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3},
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2},
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2},
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1},
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0},
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf},
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce},
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce},
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd},
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc},
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9},
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8},
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6},
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4},
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2},
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2},
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1},
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0},
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf},
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf},
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be},
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd},
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = {
+-	{
+-	 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213,
+-	 0x0214,
+-	 0x0215},
+-	{
+-	 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212,
+-	 0x0213,
+-	 0x0214},
+-	{
+-	 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211,
+-	 0x0212,
+-	 0x0213},
+-	{
+-	 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f,
+-	 0x0211,
+-	 0x0212},
+-	{
+-	 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e,
+-	 0x020f,
+-	 0x0211},
+-	{
+-	 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d,
+-	 0x020e,
+-	 0x020f},
+-	{
+-	 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c,
+-	 0x020d,
+-	 0x020e},
+-	{
+-	 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b,
+-	 0x020c,
+-	 0x020d},
+-	{
+-	 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f,
+-	 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a,
+-	 0x020b,
+-	 0x020c},
+-	{
+-	 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209,
+-	 0x020a,
+-	 0x020b},
+-	{
+-	 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208,
+-	 0x0209,
+-	 0x020a},
+-	{
+-	 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207,
+-	 0x0208,
+-	 0x0209},
+-	{
+-	 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206,
+-	 0x0207,
+-	 0x0208},
+-	{
+-	 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205,
+-	 0x0206,
+-	 0x0207},
+-	{
+-	 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204,
+-	 0x0205,
+-	 0x0206},
+-	{
+-	 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203,
+-	 0x0204,
+-	 0x0205},
+-	{
+-	 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e,
+-	 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202,
+-	 0x0203,
+-	 0x0204},
+-	{
+-	 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201,
+-	 0x0202,
+-	 0x0203},
+-	{
+-	 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200,
+-	 0x0201,
+-	 0x0202},
+-	{
+-	 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff,
+-	 0x0200,
+-	 0x0201},
+-	{
+-	 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe,
+-	 0x01ff,
+-	 0x0200},
+-	{
+-	 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd,
+-	 0x01fe,
+-	 0x01ff},
+-	{
+-	 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb,
+-	 0x01fc,
+-	 0x01fd},
+-	{
+-	 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d,
+-	 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa,
+-	 0x01fb,
+-	 0x01fc},
+-	{
+-	 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9,
+-	 0x01fa,
+-	 0x01fb},
+-	{
+-	 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00,
+-	 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8,
+-	 0x01f9,
+-	 0x01fa},
+-	{
+-	 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7,
+-	 0x01f8,
+-	 0x01f9},
+-	{
+-	 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6,
+-	 0x01f7,
+-	 0x01f8},
+-	{
+-	 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5,
+-	 0x01f6,
+-	 0x01f7},
+-	{
+-	 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4,
+-	 0x01f5,
+-	 0x01f6},
+-	{
+-	 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3,
+-	 0x01f4,
+-	 0x01f5},
+-	{
+-	 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c,
+-	 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2,
+-	 0x01f3,
+-	 0x01f4},
+-	{
+-	 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1,
+-	 0x01f2,
+-	 0x01f3},
+-	{
+-	 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0,
+-	 0x01f1,
+-	 0x01f2},
+-	{
+-	 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0,
+-	 0x01f0,
+-	 0x01f1},
+-	{
+-	 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00,
+-	 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef,
+-	 0x01f0,
+-	 0x01f0},
+-	{
+-	 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee,
+-	 0x01ef,
+-	 0x01f0},
+-	{
+-	 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed,
+-	 0x01ee,
+-	 0x01ef},
+-	{
+-	 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec,
+-	 0x01ed,
+-	 0x01ee},
+-	{
+-	 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b,
+-	 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb,
+-	 0x01ec,
+-	 0x01ed},
+-	{
+-	 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea,
+-	 0x01eb,
+-	 0x01ec},
+-	{
+-	 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9,
+-	 0x01ea,
+-	 0x01eb},
+-	{
+-	 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8,
+-	 0x01e9,
+-	 0x01ea},
+-	{
+-	 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7,
+-	 0x01e8,
+-	 0x01e9},
+-	{
+-	 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6,
+-	 0x01e7,
+-	 0x01e8},
+-	{
+-	 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00,
+-	 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5,
+-	 0x01e6,
+-	 0x01e7},
+-	{
+-	 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5,
+-	 0x01e5,
+-	 0x01e6},
+-	{
+-	 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a,
+-	 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4,
+-	 0x01e5,
+-	 0x01e5},
+-	{
+-	 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3,
+-	 0x01e4,
+-	 0x01e5},
+-	{
+-	 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2,
+-	 0x01e3,
+-	 0x01e4},
+-	{
+-	 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1,
+-	 0x01e2,
+-	 0x01e3},
+-	{
+-	 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0,
+-	 0x01e1,
+-	 0x01e2},
+-	{
+-	 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df,
+-	 0x01e0,
+-	 0x01e1},
+-	{
+-	 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de,
+-	 0x01df,
+-	 0x01e0},
+-	{
+-	 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd,
+-	 0x01de,
+-	 0x01df},
+-	{
+-	 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00,
+-	 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd,
+-	 0x01dd,
+-	 0x01de},
+-	{
+-	 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc,
+-	 0x01dd,
+-	 0x01dd},
+-	{
+-	 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09,
+-	 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db,
+-	 0x01dc,
+-	 0x01dd},
+-	{
+-	 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da,
+-	 0x01db,
+-	 0x01dc},
+-	{
+-	 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9,
+-	 0x01da,
+-	 0x01db},
+-	{
+-	 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8,
+-	 0x01d9,
+-	 0x01da},
+-	{
+-	 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7,
+-	 0x01d8,
+-	 0x01d9},
+-	{
+-	 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7,
+-	 0x01d7,
+-	 0x01d8},
+-	{
+-	 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6,
+-	 0x01d7,
+-	 0x01d7},
+-	{
+-	 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5,
+-	 0x01d6,
+-	 0x01d7},
+-	{
+-	 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00,
+-	 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4,
+-	 0x01d5,
+-	 0x01d6},
+-	{
+-	 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3,
+-	 0x01d4,
+-	 0x01d5},
+-	{
+-	 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08,
+-	 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2,
+-	 0x01d3,
+-	 0x01d4},
+-	{
+-	 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2,
+-	 0x01d2,
+-	 0x01d3},
+-	{
+-	 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1,
+-	 0x01d2,
+-	 0x01d2},
+-	{
+-	 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0,
+-	 0x01d1,
+-	 0x01d2},
+-	{
+-	 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf,
+-	 0x01d0,
+-	 0x01d1},
+-	{
+-	 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce,
+-	 0x01cf,
+-	 0x01d0},
+-	{
+-	 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce,
+-	 0x01ce,
+-	 0x01cf},
+-	{
+-	 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd,
+-	 0x01ce,
+-	 0x01ce},
+-	{
+-	 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00,
+-	 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc,
+-	 0x01cd,
+-	 0x01ce},
+-	{
+-	 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb,
+-	 0x01cc,
+-	 0x01cd},
+-	{
+-	 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca,
+-	 0x01cb,
+-	 0x01cc},
+-	{
+-	 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07,
+-	 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9,
+-	 0x01ca,
+-	 0x01cb},
+-	{
+-	 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8,
+-	 0x01c9,
+-	 0x01ca},
+-	{
+-	 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8,
+-	 0x01c9,
+-	 0x01c9},
+-	{
+-	 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7,
+-	 0x01c8,
+-	 0x01c9},
+-	{
+-	 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7,
+-	 0x01c8,
+-	 0x01c8},
+-	{
+-	 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6,
+-	 0x01c7,
+-	 0x01c8},
+-	{
+-	 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5,
+-	 0x01c6,
+-	 0x01c7},
+-	{
+-	 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06,
+-	 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5,
+-	 0x01c6,
+-	 0x01c6},
+-	{
+-	 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4,
+-	 0x01c5,
+-	 0x01c6},
+-	{
+-	 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3,
+-	 0x01c4,
+-	 0x01c5},
+-	{
+-	 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3,
+-	 0x01c4,
+-	 0x01c4},
+-	{
+-	 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2,
+-	 0x01c3,
+-	 0x01c4},
+-	{
+-	 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1,
+-	 0x01c2,
+-	 0x01c3},
+-	{
+-	 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1,
+-	 0x01c2,
+-	 0x01c2},
+-	{
+-	 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05,
+-	 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0,
+-	 0x01c1,
+-	 0x01c2},
+-	{
+-	 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf,
+-	 0x01c0,
+-	 0x01c1},
+-	{
+-	 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf,
+-	 0x01bf,
+-	 0x01c0},
+-	{
+-	 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04,
+-	 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be,
+-	 0x01bf,
+-	 0x01bf},
+-	{
+-	 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd,
+-	 0x01be,
+-	 0x01bf},
+-	{
+-	 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc,
+-	 0x01bd,
+-	 0x01be},
+-	{
+-	 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03,
+-	 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00,
+-	 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc,
+-	 0x01bc,
+-	 0x01bd},
+-	{
+-	 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a,
+-	 0x043f,
+-	 0x0443},
+-	{
+-	 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f,
+-	 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438,
+-	 0x043d,
+-	 0x0441},
+-	{
+-	 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436,
+-	 0x043a,
+-	 0x043f},
+-	{
+-	 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f,
+-	 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434,
+-	 0x0438,
+-	 0x043d},
+-	{
+-	 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431,
+-	 0x0436,
+-	 0x043a},
+-	{
+-	 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f,
+-	 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f,
+-	 0x0434,
+-	 0x0438},
+-	{
+-	 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d,
+-	 0x0431,
+-	 0x0436},
+-	{
+-	 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b,
+-	 0x042f,
+-	 0x0434},
+-	{
+-	 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f,
+-	 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429,
+-	 0x042d,
+-	 0x0431},
+-	{
+-	 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427,
+-	 0x042b,
+-	 0x042f},
+-	{
+-	 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f,
+-	 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424,
+-	 0x0429,
+-	 0x042d},
+-	{
+-	 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422,
+-	 0x0427,
+-	 0x042b},
+-	{
+-	 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f,
+-	 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420,
+-	 0x0424,
+-	 0x0429},
+-	{
+-	 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f,
+-	 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61,
+-	 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b,
+-	 0x041f,
+-	 0x0424}
+-};
+-
+-radio_regs_t regs_2055[] = {
+-	{0x02, 0x80, 0x80, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0x27, 0x27, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0x27, 0x27, 0, 0},
+-	{0x07, 0x7f, 0x7f, 1, 1},
+-	{0x08, 0x7, 0x7, 1, 1},
+-	{0x09, 0x7f, 0x7f, 1, 1},
+-	{0x0A, 0x7, 0x7, 1, 1},
+-	{0x0B, 0x15, 0x15, 0, 0},
+-	{0x0C, 0x15, 0x15, 0, 0},
+-	{0x0D, 0x4f, 0x4f, 1, 1},
+-	{0x0E, 0x5, 0x5, 1, 1},
+-	{0x0F, 0x4f, 0x4f, 1, 1},
+-	{0x10, 0x5, 0x5, 1, 1},
+-	{0x11, 0xd0, 0xd0, 0, 0},
+-	{0x12, 0x2, 0x2, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0x40, 0x40, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0xc0, 0xc0, 0, 0},
+-	{0x1E, 0xff, 0xff, 0, 0},
+-	{0x1F, 0xc0, 0xc0, 0, 0},
+-	{0x20, 0xff, 0xff, 0, 0},
+-	{0x21, 0xc0, 0xc0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x2c, 0x2c, 0, 0},
+-	{0x24, 0, 0, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0xa4, 0xa4, 0, 0},
+-	{0x2E, 0x38, 0x38, 0, 0},
+-	{0x2F, 0, 0, 0, 0},
+-	{0x30, 0x4, 0x4, 1, 1},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0xa, 0xa, 0, 0},
+-	{0x33, 0x87, 0x87, 0, 0},
+-	{0x34, 0x9, 0x9, 0, 0},
+-	{0x35, 0x70, 0x70, 0, 0},
+-	{0x36, 0x11, 0x11, 0, 0},
+-	{0x37, 0x18, 0x18, 1, 1},
+-	{0x38, 0x6, 0x6, 0, 0},
+-	{0x39, 0x4, 0x4, 1, 1},
+-	{0x3A, 0x6, 0x6, 0, 0},
+-	{0x3B, 0x9e, 0x9e, 0, 0},
+-	{0x3C, 0x9, 0x9, 0, 0},
+-	{0x3D, 0xc8, 0xc8, 1, 1},
+-	{0x3E, 0x88, 0x88, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0, 0, 0, 0},
+-	{0x42, 0x1, 0x1, 0, 0},
+-	{0x43, 0x2, 0x2, 0, 0},
+-	{0x44, 0x96, 0x96, 0, 0},
+-	{0x45, 0x3e, 0x3e, 0, 0},
+-	{0x46, 0x3e, 0x3e, 0, 0},
+-	{0x47, 0x13, 0x13, 0, 0},
+-	{0x48, 0x2, 0x2, 0, 0},
+-	{0x49, 0x15, 0x15, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0, 0, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0, 0, 0, 0},
+-	{0x50, 0x8, 0x8, 0, 0},
+-	{0x51, 0x8, 0x8, 0, 0},
+-	{0x52, 0x6, 0x6, 0, 0},
+-	{0x53, 0x84, 0x84, 1, 1},
+-	{0x54, 0xc3, 0xc3, 0, 0},
+-	{0x55, 0x8f, 0x8f, 0, 0},
+-	{0x56, 0xff, 0xff, 0, 0},
+-	{0x57, 0xff, 0xff, 0, 0},
+-	{0x58, 0x88, 0x88, 0, 0},
+-	{0x59, 0x88, 0x88, 0, 0},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0xcc, 0xcc, 0, 0},
+-	{0x5C, 0x6, 0x6, 0, 0},
+-	{0x5D, 0x80, 0x80, 0, 0},
+-	{0x5E, 0x80, 0x80, 0, 0},
+-	{0x5F, 0xf8, 0xf8, 0, 0},
+-	{0x60, 0x88, 0x88, 0, 0},
+-	{0x61, 0x88, 0x88, 0, 0},
+-	{0x62, 0x88, 0x8, 1, 1},
+-	{0x63, 0x88, 0x88, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0x1, 0x1, 1, 1},
+-	{0x66, 0x8a, 0x8a, 0, 0},
+-	{0x67, 0x8, 0x8, 0, 0},
+-	{0x68, 0x83, 0x83, 0, 0},
+-	{0x69, 0x6, 0x6, 0, 0},
+-	{0x6A, 0xa0, 0xa0, 0, 0},
+-	{0x6B, 0xa, 0xa, 0, 0},
+-	{0x6C, 0x87, 0x87, 1, 1},
+-	{0x6D, 0x2a, 0x2a, 0, 0},
+-	{0x6E, 0x2a, 0x2a, 0, 0},
+-	{0x6F, 0x2a, 0x2a, 0, 0},
+-	{0x70, 0x2a, 0x2a, 0, 0},
+-	{0x71, 0x18, 0x18, 0, 0},
+-	{0x72, 0x6a, 0x6a, 1, 1},
+-	{0x73, 0xab, 0xab, 1, 1},
+-	{0x74, 0x13, 0x13, 1, 1},
+-	{0x75, 0xc1, 0xc1, 1, 1},
+-	{0x76, 0xaa, 0xaa, 1, 1},
+-	{0x77, 0x87, 0x87, 1, 1},
+-	{0x78, 0, 0, 0, 0},
+-	{0x79, 0x6, 0x6, 0, 0},
+-	{0x7A, 0x7, 0x7, 0, 0},
+-	{0x7B, 0x7, 0x7, 0, 0},
+-	{0x7C, 0x15, 0x15, 0, 0},
+-	{0x7D, 0x55, 0x55, 0, 0},
+-	{0x7E, 0x97, 0x97, 1, 1},
+-	{0x7F, 0x8, 0x8, 0, 0},
+-	{0x80, 0x14, 0x14, 1, 1},
+-	{0x81, 0x33, 0x33, 0, 0},
+-	{0x82, 0x88, 0x88, 0, 0},
+-	{0x83, 0x6, 0x6, 0, 0},
+-	{0x84, 0x3, 0x3, 1, 1},
+-	{0x85, 0xa, 0xa, 0, 0},
+-	{0x86, 0x3, 0x3, 1, 1},
+-	{0x87, 0x2a, 0x2a, 0, 0},
+-	{0x88, 0xa4, 0xa4, 0, 0},
+-	{0x89, 0x18, 0x18, 0, 0},
+-	{0x8A, 0x28, 0x28, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0x4a, 0x4a, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0xf8, 0xf8, 0, 0},
+-	{0x8F, 0x88, 0x88, 0, 0},
+-	{0x90, 0x88, 0x88, 0, 0},
+-	{0x91, 0x88, 0x8, 1, 1},
+-	{0x92, 0x88, 0x88, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0x1, 0x1, 1, 1},
+-	{0x95, 0x8a, 0x8a, 0, 0},
+-	{0x96, 0x8, 0x8, 0, 0},
+-	{0x97, 0x83, 0x83, 0, 0},
+-	{0x98, 0x6, 0x6, 0, 0},
+-	{0x99, 0xa0, 0xa0, 0, 0},
+-	{0x9A, 0xa, 0xa, 0, 0},
+-	{0x9B, 0x87, 0x87, 1, 1},
+-	{0x9C, 0x2a, 0x2a, 0, 0},
+-	{0x9D, 0x2a, 0x2a, 0, 0},
+-	{0x9E, 0x2a, 0x2a, 0, 0},
+-	{0x9F, 0x2a, 0x2a, 0, 0},
+-	{0xA0, 0x18, 0x18, 0, 0},
+-	{0xA1, 0x6a, 0x6a, 1, 1},
+-	{0xA2, 0xab, 0xab, 1, 1},
+-	{0xA3, 0x13, 0x13, 1, 1},
+-	{0xA4, 0xc1, 0xc1, 1, 1},
+-	{0xA5, 0xaa, 0xaa, 1, 1},
+-	{0xA6, 0x87, 0x87, 1, 1},
+-	{0xA7, 0, 0, 0, 0},
+-	{0xA8, 0x6, 0x6, 0, 0},
+-	{0xA9, 0x7, 0x7, 0, 0},
+-	{0xAA, 0x7, 0x7, 0, 0},
+-	{0xAB, 0x15, 0x15, 0, 0},
+-	{0xAC, 0x55, 0x55, 0, 0},
+-	{0xAD, 0x97, 0x97, 1, 1},
+-	{0xAE, 0x8, 0x8, 0, 0},
+-	{0xAF, 0x14, 0x14, 1, 1},
+-	{0xB0, 0x33, 0x33, 0, 0},
+-	{0xB1, 0x88, 0x88, 0, 0},
+-	{0xB2, 0x6, 0x6, 0, 0},
+-	{0xB3, 0x3, 0x3, 1, 1},
+-	{0xB4, 0xa, 0xa, 0, 0},
+-	{0xB5, 0x3, 0x3, 1, 1},
+-	{0xB6, 0x2a, 0x2a, 0, 0},
+-	{0xB7, 0xa4, 0xa4, 0, 0},
+-	{0xB8, 0x18, 0x18, 0, 0},
+-	{0xB9, 0x28, 0x28, 0, 0},
+-	{0xBA, 0, 0, 0, 0},
+-	{0xBB, 0x4a, 0x4a, 0, 0},
+-	{0xBC, 0, 0, 0, 0},
+-	{0xBD, 0x71, 0x71, 0, 0},
+-	{0xBE, 0x72, 0x72, 0, 0},
+-	{0xBF, 0x73, 0x73, 0, 0},
+-	{0xC0, 0x74, 0x74, 0, 0},
+-	{0xC1, 0x75, 0x75, 0, 0},
+-	{0xC2, 0x76, 0x76, 0, 0},
+-	{0xC3, 0x77, 0x77, 0, 0},
+-	{0xC4, 0x78, 0x78, 0, 0},
+-	{0xC5, 0x79, 0x79, 0, 0},
+-	{0xC6, 0x7a, 0x7a, 0, 0},
+-	{0xC7, 0, 0, 0, 0},
+-	{0xC8, 0, 0, 0, 0},
+-	{0xC9, 0, 0, 0, 0},
+-	{0xCA, 0, 0, 0, 0},
+-	{0xCB, 0, 0, 0, 0},
+-	{0xCC, 0, 0, 0, 0},
+-	{0xCD, 0, 0, 0, 0},
+-	{0xCE, 0x6, 0x6, 0, 0},
+-	{0xCF, 0, 0, 0, 0},
+-	{0xD0, 0, 0, 0, 0},
+-	{0xD1, 0x18, 0x18, 0, 0},
+-	{0xD2, 0x88, 0x88, 0, 0},
+-	{0xD3, 0, 0, 0, 0},
+-	{0xD4, 0, 0, 0, 0},
+-	{0xD5, 0, 0, 0, 0},
+-	{0xD6, 0, 0, 0, 0},
+-	{0xD7, 0, 0, 0, 0},
+-	{0xD8, 0, 0, 0, 0},
+-	{0xD9, 0, 0, 0, 0},
+-	{0xDA, 0x6, 0x6, 0, 0},
+-	{0xDB, 0, 0, 0, 0},
+-	{0xDC, 0, 0, 0, 0},
+-	{0xDD, 0x18, 0x18, 0, 0},
+-	{0xDE, 0x88, 0x88, 0, 0},
+-	{0xDF, 0, 0, 0, 0},
+-	{0xE0, 0, 0, 0, 0},
+-	{0xE1, 0, 0, 0, 0},
+-	{0xE2, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0xd, 0xd, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0x74, 0x74, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x99, 0x99, 0, 0},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x44, 0x44, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0xf, 0xf, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0x50, 0x50, 1, 1},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x99, 0x99, 0, 0},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x66, 0x66, 0, 0},
+-	{0x50, 0x66, 0x66, 0, 0},
+-	{0x51, 0x57, 0x57, 0, 0},
+-	{0x52, 0x57, 0x57, 0, 0},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x23, 0x23, 0, 0},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0x2, 0x2, 0, 0},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0xd, 0xd, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0x72, 0x72, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_A1[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x44, 0x44, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0xf, 0xf, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0x50, 0x50, 1, 1},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x2f, 0x2f, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0x11, 0x11, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0xf, 0xf, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x2d, 0x2d, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x71, 0x71, 1, 1},
+-	{0x96, 0x71, 0x71, 1, 1},
+-	{0x97, 0x72, 0x72, 1, 1},
+-	{0x98, 0x73, 0x73, 1, 1},
+-	{0x99, 0x74, 0x74, 1, 1},
+-	{0x9A, 0x75, 0x75, 1, 1},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_rev5[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 1, 1},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0, 0, 1, 1},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_TX_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_RX_2056_rev6[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0}
+-};
+-
+-radio_regs_t regs_SYN_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x71, 0x71, 1, 1},
+-	{0x96, 0x71, 0x71, 1, 1},
+-	{0x97, 0x72, 0x72, 1, 1},
+-	{0x98, 0x73, 0x73, 1, 1},
+-	{0x99, 0x74, 0x74, 1, 1},
+-	{0x9A, 0x75, 0x75, 1, 1},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev7[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 1, 1},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0, 0, 1, 1},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x4, 0x4, 0, 0},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x30, 0x30, 0, 0},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0xd, 0xd, 0, 0},
+-	{0x4C, 0xd, 0xd, 0, 0},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x6, 0x6, 0, 0},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev8[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_SYN_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0x1, 0x1, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0x60, 0x60, 0, 0},
+-	{0x23, 0x6, 0x6, 0, 0},
+-	{0x24, 0xc, 0xc, 0, 0},
+-	{0x25, 0, 0, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0, 0, 0, 0},
+-	{0x28, 0x1, 0x1, 0, 0},
+-	{0x29, 0, 0, 0, 0},
+-	{0x2A, 0, 0, 0, 0},
+-	{0x2B, 0, 0, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0, 0, 0, 0},
+-	{0x2F, 0x1f, 0x1f, 0, 0},
+-	{0x30, 0x15, 0x15, 0, 0},
+-	{0x31, 0xf, 0xf, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0, 0, 0, 0},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0, 0, 0, 0},
+-	{0x38, 0, 0, 0, 0},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0, 0, 0, 0},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x13, 0x13, 0, 0},
+-	{0x3D, 0xf, 0xf, 0, 0},
+-	{0x3E, 0x18, 0x18, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x20, 0x20, 0, 0},
+-	{0x42, 0x20, 0x20, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x77, 0x77, 0, 0},
+-	{0x45, 0x7, 0x7, 0, 0},
+-	{0x46, 0x1, 0x1, 0, 0},
+-	{0x47, 0x6, 0x6, 1, 1},
+-	{0x48, 0xf, 0xf, 0, 0},
+-	{0x49, 0x3f, 0x3f, 1, 1},
+-	{0x4A, 0x32, 0x32, 0, 0},
+-	{0x4B, 0x6, 0x6, 1, 1},
+-	{0x4C, 0x6, 0x6, 1, 1},
+-	{0x4D, 0x4, 0x4, 0, 0},
+-	{0x4E, 0x2b, 0x2b, 1, 1},
+-	{0x4F, 0x1, 0x1, 0, 0},
+-	{0x50, 0x1c, 0x1c, 0, 0},
+-	{0x51, 0x2, 0x2, 0, 0},
+-	{0x52, 0x2, 0x2, 0, 0},
+-	{0x53, 0xf7, 0xf7, 1, 1},
+-	{0x54, 0xb4, 0xb4, 0, 0},
+-	{0x55, 0xd2, 0xd2, 0, 0},
+-	{0x56, 0, 0, 0, 0},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x4, 0x4, 0, 0},
+-	{0x59, 0x96, 0x96, 0, 0},
+-	{0x5A, 0x3e, 0x3e, 0, 0},
+-	{0x5B, 0x3e, 0x3e, 0, 0},
+-	{0x5C, 0x13, 0x13, 0, 0},
+-	{0x5D, 0x2, 0x2, 0, 0},
+-	{0x5E, 0, 0, 0, 0},
+-	{0x5F, 0x7, 0x7, 0, 0},
+-	{0x60, 0x7, 0x7, 1, 1},
+-	{0x61, 0x8, 0x8, 0, 0},
+-	{0x62, 0x3, 0x3, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0x40, 0x40, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0x1, 0x1, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0x60, 0x60, 0, 0},
+-	{0x71, 0x66, 0x66, 0, 0},
+-	{0x72, 0xc, 0xc, 0, 0},
+-	{0x73, 0x66, 0x66, 0, 0},
+-	{0x74, 0x8f, 0x8f, 1, 1},
+-	{0x75, 0, 0, 0, 0},
+-	{0x76, 0xcc, 0xcc, 0, 0},
+-	{0x77, 0x1, 0x1, 0, 0},
+-	{0x78, 0x66, 0x66, 0, 0},
+-	{0x79, 0x66, 0x66, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0, 0, 0, 0},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0xff, 0xff, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0x95, 0, 0, 0, 0},
+-	{0x96, 0, 0, 0, 0},
+-	{0x97, 0, 0, 0, 0},
+-	{0x98, 0, 0, 0, 0},
+-	{0x99, 0, 0, 0, 0},
+-	{0x9A, 0, 0, 0, 0},
+-	{0x9B, 0, 0, 0, 0},
+-	{0x9C, 0, 0, 0, 0},
+-	{0x9D, 0, 0, 0, 0},
+-	{0x9E, 0, 0, 0, 0},
+-	{0x9F, 0x6, 0x6, 0, 0},
+-	{0xA0, 0x66, 0x66, 0, 0},
+-	{0xA1, 0x66, 0x66, 0, 0},
+-	{0xA2, 0x66, 0x66, 0, 0},
+-	{0xA3, 0x66, 0x66, 0, 0},
+-	{0xA4, 0x66, 0x66, 0, 0},
+-	{0xA5, 0x66, 0x66, 0, 0},
+-	{0xA6, 0x66, 0x66, 0, 0},
+-	{0xA7, 0x66, 0x66, 0, 0},
+-	{0xA8, 0x66, 0x66, 0, 0},
+-	{0xA9, 0x66, 0x66, 0, 0},
+-	{0xAA, 0x66, 0x66, 0, 0},
+-	{0xAB, 0x66, 0x66, 0, 0},
+-	{0xAC, 0x66, 0x66, 0, 0},
+-	{0xAD, 0x66, 0x66, 0, 0},
+-	{0xAE, 0x66, 0x66, 0, 0},
+-	{0xAF, 0x66, 0x66, 0, 0},
+-	{0xB0, 0x66, 0x66, 0, 0},
+-	{0xB1, 0x66, 0x66, 0, 0},
+-	{0xB2, 0x66, 0x66, 0, 0},
+-	{0xB3, 0xa, 0xa, 0, 0},
+-	{0xB4, 0, 0, 0, 0},
+-	{0xB5, 0, 0, 0, 0},
+-	{0xB6, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_TX_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0, 0, 0, 0},
+-	{0x21, 0x88, 0x88, 0, 0},
+-	{0x22, 0x88, 0x88, 0, 0},
+-	{0x23, 0x88, 0x88, 0, 0},
+-	{0x24, 0x88, 0x88, 0, 0},
+-	{0x25, 0xc, 0xc, 0, 0},
+-	{0x26, 0, 0, 0, 0},
+-	{0x27, 0x3, 0x3, 0, 0},
+-	{0x28, 0, 0, 0, 0},
+-	{0x29, 0x3, 0x3, 0, 0},
+-	{0x2A, 0x37, 0x37, 0, 0},
+-	{0x2B, 0x3, 0x3, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0, 0, 0, 0},
+-	{0x2E, 0x1, 0x1, 0, 0},
+-	{0x2F, 0x1, 0x1, 0, 0},
+-	{0x30, 0, 0, 0, 0},
+-	{0x31, 0, 0, 0, 0},
+-	{0x32, 0, 0, 0, 0},
+-	{0x33, 0x11, 0x11, 0, 0},
+-	{0x34, 0xee, 0xee, 1, 1},
+-	{0x35, 0, 0, 0, 0},
+-	{0x36, 0, 0, 0, 0},
+-	{0x37, 0x3, 0x3, 0, 0},
+-	{0x38, 0x50, 0x50, 1, 1},
+-	{0x39, 0, 0, 0, 0},
+-	{0x3A, 0x50, 0x50, 1, 1},
+-	{0x3B, 0, 0, 0, 0},
+-	{0x3C, 0x6e, 0x6e, 0, 0},
+-	{0x3D, 0xf0, 0xf0, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0, 0, 0, 0},
+-	{0x40, 0, 0, 0, 0},
+-	{0x41, 0x3, 0x3, 0, 0},
+-	{0x42, 0x3, 0x3, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x1e, 0x1e, 0, 0},
+-	{0x45, 0, 0, 0, 0},
+-	{0x46, 0x6e, 0x6e, 0, 0},
+-	{0x47, 0xf0, 0xf0, 1, 1},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x2, 0x2, 0, 0},
+-	{0x4A, 0xff, 0xff, 1, 1},
+-	{0x4B, 0xc, 0xc, 0, 0},
+-	{0x4C, 0, 0, 0, 0},
+-	{0x4D, 0x38, 0x38, 0, 0},
+-	{0x4E, 0x70, 0x70, 1, 1},
+-	{0x4F, 0x2, 0x2, 0, 0},
+-	{0x50, 0x88, 0x88, 0, 0},
+-	{0x51, 0xc, 0xc, 0, 0},
+-	{0x52, 0, 0, 0, 0},
+-	{0x53, 0x8, 0x8, 0, 0},
+-	{0x54, 0x70, 0x70, 1, 1},
+-	{0x55, 0x2, 0x2, 0, 0},
+-	{0x56, 0xff, 0xff, 1, 1},
+-	{0x57, 0, 0, 0, 0},
+-	{0x58, 0x83, 0x83, 0, 0},
+-	{0x59, 0x77, 0x77, 1, 1},
+-	{0x5A, 0, 0, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x88, 0x88, 0, 0},
+-	{0x5D, 0, 0, 0, 0},
+-	{0x5E, 0x8, 0x8, 0, 0},
+-	{0x5F, 0x77, 0x77, 1, 1},
+-	{0x60, 0x1, 0x1, 0, 0},
+-	{0x61, 0, 0, 0, 0},
+-	{0x62, 0x7, 0x7, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0x7, 0x7, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 1, 1},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0xa, 0xa, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0, 0, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0x2, 0x2, 0, 0},
+-	{0x72, 0, 0, 0, 0},
+-	{0x73, 0, 0, 0, 0},
+-	{0x74, 0xe, 0xe, 0, 0},
+-	{0x75, 0xe, 0xe, 0, 0},
+-	{0x76, 0xe, 0xe, 0, 0},
+-	{0x77, 0x13, 0x13, 0, 0},
+-	{0x78, 0x13, 0x13, 0, 0},
+-	{0x79, 0x1b, 0x1b, 0, 0},
+-	{0x7A, 0x1b, 0x1b, 0, 0},
+-	{0x7B, 0x55, 0x55, 0, 0},
+-	{0x7C, 0x5b, 0x5b, 0, 0},
+-	{0x7D, 0x30, 0x30, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0x70, 0x70, 0, 0},
+-	{0x94, 0x70, 0x70, 0, 0},
+-	{0x95, 0x70, 0x70, 0, 0},
+-	{0x96, 0x70, 0x70, 0, 0},
+-	{0x97, 0x70, 0x70, 0, 0},
+-	{0x98, 0x70, 0x70, 0, 0},
+-	{0x99, 0x70, 0x70, 0, 0},
+-	{0x9A, 0x70, 0x70, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_regs_t regs_RX_2056_rev11[] = {
+-	{0x02, 0, 0, 0, 0},
+-	{0x03, 0, 0, 0, 0},
+-	{0x04, 0, 0, 0, 0},
+-	{0x05, 0, 0, 0, 0},
+-	{0x06, 0, 0, 0, 0},
+-	{0x07, 0, 0, 0, 0},
+-	{0x08, 0, 0, 0, 0},
+-	{0x09, 0, 0, 0, 0},
+-	{0x0A, 0, 0, 0, 0},
+-	{0x0B, 0, 0, 0, 0},
+-	{0x0C, 0, 0, 0, 0},
+-	{0x0D, 0, 0, 0, 0},
+-	{0x0E, 0, 0, 0, 0},
+-	{0x0F, 0, 0, 0, 0},
+-	{0x10, 0, 0, 0, 0},
+-	{0x11, 0, 0, 0, 0},
+-	{0x12, 0, 0, 0, 0},
+-	{0x13, 0, 0, 0, 0},
+-	{0x14, 0, 0, 0, 0},
+-	{0x15, 0, 0, 0, 0},
+-	{0x16, 0, 0, 0, 0},
+-	{0x17, 0, 0, 0, 0},
+-	{0x18, 0, 0, 0, 0},
+-	{0x19, 0, 0, 0, 0},
+-	{0x1A, 0, 0, 0, 0},
+-	{0x1B, 0, 0, 0, 0},
+-	{0x1C, 0, 0, 0, 0},
+-	{0x1D, 0, 0, 0, 0},
+-	{0x1E, 0, 0, 0, 0},
+-	{0x1F, 0, 0, 0, 0},
+-	{0x20, 0x3, 0x3, 0, 0},
+-	{0x21, 0, 0, 0, 0},
+-	{0x22, 0, 0, 0, 0},
+-	{0x23, 0x90, 0x90, 0, 0},
+-	{0x24, 0x55, 0x55, 0, 0},
+-	{0x25, 0x15, 0x15, 0, 0},
+-	{0x26, 0x5, 0x5, 0, 0},
+-	{0x27, 0x15, 0x15, 0, 0},
+-	{0x28, 0x5, 0x5, 0, 0},
+-	{0x29, 0x20, 0x20, 0, 0},
+-	{0x2A, 0x11, 0x11, 0, 0},
+-	{0x2B, 0x90, 0x90, 0, 0},
+-	{0x2C, 0, 0, 0, 0},
+-	{0x2D, 0x88, 0x88, 0, 0},
+-	{0x2E, 0x32, 0x32, 0, 0},
+-	{0x2F, 0x77, 0x77, 0, 0},
+-	{0x30, 0x17, 0x17, 1, 1},
+-	{0x31, 0xff, 0xff, 1, 1},
+-	{0x32, 0x20, 0x20, 0, 0},
+-	{0x33, 0, 0, 0, 0},
+-	{0x34, 0x88, 0x88, 0, 0},
+-	{0x35, 0x32, 0x32, 0, 0},
+-	{0x36, 0x77, 0x77, 0, 0},
+-	{0x37, 0x17, 0x17, 1, 1},
+-	{0x38, 0xf0, 0xf0, 1, 1},
+-	{0x39, 0x20, 0x20, 0, 0},
+-	{0x3A, 0x8, 0x8, 0, 0},
+-	{0x3B, 0x55, 0x55, 1, 1},
+-	{0x3C, 0, 0, 0, 0},
+-	{0x3D, 0x88, 0x88, 1, 1},
+-	{0x3E, 0, 0, 0, 0},
+-	{0x3F, 0x44, 0x44, 0, 0},
+-	{0x40, 0x7, 0x7, 1, 1},
+-	{0x41, 0x6, 0x6, 0, 0},
+-	{0x42, 0x4, 0x4, 0, 0},
+-	{0x43, 0, 0, 0, 0},
+-	{0x44, 0x8, 0x8, 0, 0},
+-	{0x45, 0x55, 0x55, 1, 1},
+-	{0x46, 0, 0, 0, 0},
+-	{0x47, 0x11, 0x11, 0, 0},
+-	{0x48, 0, 0, 0, 0},
+-	{0x49, 0x44, 0x44, 0, 0},
+-	{0x4A, 0x7, 0x7, 0, 0},
+-	{0x4B, 0x6, 0x6, 0, 0},
+-	{0x4C, 0x4, 0x4, 0, 0},
+-	{0x4D, 0, 0, 0, 0},
+-	{0x4E, 0, 0, 0, 0},
+-	{0x4F, 0x26, 0x26, 1, 1},
+-	{0x50, 0x26, 0x26, 1, 1},
+-	{0x51, 0xf, 0xf, 1, 1},
+-	{0x52, 0xf, 0xf, 1, 1},
+-	{0x53, 0x44, 0x44, 0, 0},
+-	{0x54, 0, 0, 0, 0},
+-	{0x55, 0, 0, 0, 0},
+-	{0x56, 0x8, 0x8, 0, 0},
+-	{0x57, 0x8, 0x8, 0, 0},
+-	{0x58, 0x7, 0x7, 0, 0},
+-	{0x59, 0x22, 0x22, 0, 0},
+-	{0x5A, 0x22, 0x22, 0, 0},
+-	{0x5B, 0x2, 0x2, 0, 0},
+-	{0x5C, 0x4, 0x4, 1, 1},
+-	{0x5D, 0x7, 0x7, 0, 0},
+-	{0x5E, 0x55, 0x55, 0, 0},
+-	{0x5F, 0x23, 0x23, 0, 0},
+-	{0x60, 0x41, 0x41, 0, 0},
+-	{0x61, 0x1, 0x1, 0, 0},
+-	{0x62, 0xa, 0xa, 0, 0},
+-	{0x63, 0, 0, 0, 0},
+-	{0x64, 0, 0, 0, 0},
+-	{0x65, 0, 0, 0, 0},
+-	{0x66, 0, 0, 0, 0},
+-	{0x67, 0, 0, 0, 0},
+-	{0x68, 0, 0, 0, 0},
+-	{0x69, 0, 0, 0, 0},
+-	{0x6A, 0, 0, 0, 0},
+-	{0x6B, 0xc, 0xc, 0, 0},
+-	{0x6C, 0, 0, 0, 0},
+-	{0x6D, 0, 0, 0, 0},
+-	{0x6E, 0, 0, 0, 0},
+-	{0x6F, 0, 0, 0, 0},
+-	{0x70, 0, 0, 0, 0},
+-	{0x71, 0, 0, 0, 0},
+-	{0x72, 0x22, 0x22, 0, 0},
+-	{0x73, 0x22, 0x22, 0, 0},
+-	{0x74, 0, 0, 1, 1},
+-	{0x75, 0xa, 0xa, 0, 0},
+-	{0x76, 0x1, 0x1, 0, 0},
+-	{0x77, 0x22, 0x22, 0, 0},
+-	{0x78, 0x30, 0x30, 0, 0},
+-	{0x79, 0, 0, 0, 0},
+-	{0x7A, 0, 0, 0, 0},
+-	{0x7B, 0, 0, 0, 0},
+-	{0x7C, 0, 0, 0, 0},
+-	{0x7D, 0x5, 0x5, 1, 1},
+-	{0x7E, 0, 0, 0, 0},
+-	{0x7F, 0, 0, 0, 0},
+-	{0x80, 0, 0, 0, 0},
+-	{0x81, 0, 0, 0, 0},
+-	{0x82, 0, 0, 0, 0},
+-	{0x83, 0, 0, 0, 0},
+-	{0x84, 0, 0, 0, 0},
+-	{0x85, 0, 0, 0, 0},
+-	{0x86, 0, 0, 0, 0},
+-	{0x87, 0, 0, 0, 0},
+-	{0x88, 0, 0, 0, 0},
+-	{0x89, 0, 0, 0, 0},
+-	{0x8A, 0, 0, 0, 0},
+-	{0x8B, 0, 0, 0, 0},
+-	{0x8C, 0, 0, 0, 0},
+-	{0x8D, 0, 0, 0, 0},
+-	{0x8E, 0, 0, 0, 0},
+-	{0x8F, 0, 0, 0, 0},
+-	{0x90, 0, 0, 0, 0},
+-	{0x91, 0, 0, 0, 0},
+-	{0x92, 0, 0, 0, 0},
+-	{0x93, 0, 0, 0, 0},
+-	{0x94, 0, 0, 0, 0},
+-	{0xFFFF, 0, 0, 0, 0},
+-};
+-
+-radio_20xx_regs_t regs_2057_rev4[] = {
+-	{0x00, 0x84, 0},
+-	{0x01, 0, 0},
+-	{0x02, 0x60, 0},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 1},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0xf7, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x4, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x26, 1},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 1},
+-	{0x3D, 0xff, 1},
+-	{0x3E, 0xff, 1},
+-	{0x3F, 0xff, 1},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x75, 0},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0xa8, 0},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x30, 0},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0x19, 0},
+-	{0x64, 0x62, 0},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0xc8, 0},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x1e, 0},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x1e, 0},
+-	{0x7C, 0x62, 0},
+-	{0x7D, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x9c, 0},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 1},
+-	{0x8B, 0x10, 1},
+-	{0x8C, 0xf0, 1},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0xe1, 0},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 1},
+-	{0xA5, 0x6d, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 1},
+-	{0xA9, 0xc, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 1},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x75, 0},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0xa8, 0},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x30, 0},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0x19, 0},
+-	{0xE9, 0x62, 0},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0xc8, 0},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x1e, 0},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x1e, 0},
+-	{0x101, 0x62, 0},
+-	{0x102, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x9c, 0},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 1},
+-	{0x110, 0x10, 1},
+-	{0x111, 0xf0, 1},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0xe1, 0},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 1},
+-	{0x12A, 0x6d, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 1},
+-	{0x12E, 0xc, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 1},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x152, 0, 0},
+-	{0x153, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0x2, 1},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0xFFFF, 0, 0},
+-};
+-
+-radio_20xx_regs_t regs_2057_rev5[] = {
+-	{0x00, 0, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 1},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0xc, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0x1, 1},
+-	{0x1C2, 0x80, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev5v1[] = {
+-	{0x00, 0x15, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 1},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0x1, 1},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0x1, 1},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0xc, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0x1, 1},
+-	{0x1C2, 0x80, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev7[] = {
+-	{0x00, 0, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x3E, 0xff, 0},
+-	{0x3F, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0x13, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0xee, 1},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0x58, 1},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x13, 1},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x13, 1},
+-	{0x7C, 0x14, 1},
+-	{0x7D, 0xee, 1},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0, 0},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0x13, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0xee, 1},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0x58, 1},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x13, 1},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x13, 1},
+-	{0x101, 0x14, 1},
+-	{0x102, 0xee, 1},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0, 0},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0x5, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0, 0},
+-	{0x1C2, 0xa0, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-radio_20xx_regs_t regs_2057_rev8[] = {
+-	{0x00, 0x8, 1},
+-	{0x01, 0x57, 1},
+-	{0x02, 0x20, 1},
+-	{0x03, 0x1f, 0},
+-	{0x04, 0x4, 0},
+-	{0x05, 0x2, 0},
+-	{0x06, 0x1, 0},
+-	{0x07, 0x1, 0},
+-	{0x08, 0x1, 0},
+-	{0x09, 0x69, 0},
+-	{0x0A, 0x66, 0},
+-	{0x0B, 0x6, 0},
+-	{0x0C, 0x18, 0},
+-	{0x0D, 0x3, 0},
+-	{0x0E, 0x20, 0},
+-	{0x0F, 0x20, 0},
+-	{0x10, 0, 0},
+-	{0x11, 0x7c, 0},
+-	{0x12, 0x42, 0},
+-	{0x13, 0xbd, 0},
+-	{0x14, 0x7, 0},
+-	{0x15, 0x87, 0},
+-	{0x16, 0x8, 0},
+-	{0x17, 0x17, 0},
+-	{0x18, 0x7, 0},
+-	{0x19, 0, 0},
+-	{0x1A, 0x2, 0},
+-	{0x1B, 0x13, 0},
+-	{0x1C, 0x3e, 0},
+-	{0x1D, 0x3e, 0},
+-	{0x1E, 0x96, 0},
+-	{0x1F, 0x4, 0},
+-	{0x20, 0, 0},
+-	{0x21, 0, 0},
+-	{0x22, 0x17, 0},
+-	{0x23, 0x6, 0},
+-	{0x24, 0x1, 0},
+-	{0x25, 0x6, 0},
+-	{0x26, 0x4, 0},
+-	{0x27, 0xd, 0},
+-	{0x28, 0xd, 0},
+-	{0x29, 0x30, 0},
+-	{0x2A, 0x32, 0},
+-	{0x2B, 0x8, 0},
+-	{0x2C, 0x1c, 0},
+-	{0x2D, 0x2, 0},
+-	{0x2E, 0x4, 0},
+-	{0x2F, 0x7f, 0},
+-	{0x30, 0x27, 0},
+-	{0x31, 0, 1},
+-	{0x32, 0, 1},
+-	{0x33, 0, 1},
+-	{0x34, 0, 0},
+-	{0x35, 0x20, 0},
+-	{0x36, 0x18, 0},
+-	{0x37, 0x7, 0},
+-	{0x38, 0x66, 0},
+-	{0x39, 0x66, 0},
+-	{0x3A, 0x66, 0},
+-	{0x3B, 0x66, 0},
+-	{0x3C, 0xff, 0},
+-	{0x3D, 0xff, 0},
+-	{0x3E, 0xff, 0},
+-	{0x3F, 0xff, 0},
+-	{0x40, 0x16, 0},
+-	{0x41, 0x7, 0},
+-	{0x42, 0x19, 0},
+-	{0x43, 0x7, 0},
+-	{0x44, 0x6, 0},
+-	{0x45, 0x3, 0},
+-	{0x46, 0x1, 0},
+-	{0x47, 0x7, 0},
+-	{0x48, 0x33, 0},
+-	{0x49, 0x5, 0},
+-	{0x4A, 0x77, 0},
+-	{0x4B, 0x66, 0},
+-	{0x4C, 0x66, 0},
+-	{0x4D, 0, 0},
+-	{0x4E, 0x4, 0},
+-	{0x4F, 0xc, 0},
+-	{0x50, 0, 0},
+-	{0x51, 0x70, 1},
+-	{0x56, 0x7, 0},
+-	{0x57, 0, 0},
+-	{0x58, 0, 0},
+-	{0x59, 0x88, 1},
+-	{0x5A, 0, 0},
+-	{0x5B, 0x1f, 0},
+-	{0x5C, 0x20, 1},
+-	{0x5D, 0x1, 0},
+-	{0x5E, 0x30, 0},
+-	{0x5F, 0x70, 0},
+-	{0x60, 0, 0},
+-	{0x61, 0, 0},
+-	{0x62, 0x33, 1},
+-	{0x63, 0xf, 1},
+-	{0x64, 0xf, 1},
+-	{0x65, 0, 0},
+-	{0x66, 0x11, 0},
+-	{0x69, 0, 0},
+-	{0x6A, 0x7e, 0},
+-	{0x6B, 0x3f, 0},
+-	{0x6C, 0x7f, 0},
+-	{0x6D, 0x78, 0},
+-	{0x6E, 0x58, 1},
+-	{0x6F, 0x88, 0},
+-	{0x70, 0x8, 0},
+-	{0x71, 0xf, 0},
+-	{0x72, 0xbc, 0},
+-	{0x73, 0x8, 0},
+-	{0x74, 0x60, 0},
+-	{0x75, 0x13, 1},
+-	{0x76, 0x70, 0},
+-	{0x77, 0, 0},
+-	{0x78, 0, 0},
+-	{0x79, 0, 0},
+-	{0x7A, 0x33, 0},
+-	{0x7B, 0x13, 1},
+-	{0x7C, 0xf, 1},
+-	{0x7D, 0xee, 1},
+-	{0x80, 0x3c, 0},
+-	{0x81, 0x1, 1},
+-	{0x82, 0xa, 0},
+-	{0x83, 0x9d, 0},
+-	{0x84, 0xa, 0},
+-	{0x85, 0, 0},
+-	{0x86, 0x40, 0},
+-	{0x87, 0x40, 0},
+-	{0x88, 0x88, 0},
+-	{0x89, 0x10, 0},
+-	{0x8A, 0xf0, 0},
+-	{0x8B, 0x10, 0},
+-	{0x8C, 0xf0, 0},
+-	{0x8D, 0, 0},
+-	{0x8E, 0, 0},
+-	{0x8F, 0x10, 0},
+-	{0x90, 0x55, 0},
+-	{0x91, 0x3f, 1},
+-	{0x92, 0x36, 1},
+-	{0x93, 0, 0},
+-	{0x94, 0, 0},
+-	{0x95, 0, 0},
+-	{0x96, 0x87, 0},
+-	{0x97, 0x11, 0},
+-	{0x98, 0, 0},
+-	{0x99, 0x33, 0},
+-	{0x9A, 0x88, 0},
+-	{0x9B, 0, 0},
+-	{0x9C, 0x87, 0},
+-	{0x9D, 0x11, 0},
+-	{0x9E, 0, 0},
+-	{0x9F, 0x33, 0},
+-	{0xA0, 0x88, 0},
+-	{0xA1, 0x20, 1},
+-	{0xA2, 0x3f, 0},
+-	{0xA3, 0x44, 0},
+-	{0xA4, 0x8c, 0},
+-	{0xA5, 0x6c, 0},
+-	{0xA6, 0x22, 0},
+-	{0xA7, 0xbe, 0},
+-	{0xA8, 0x55, 0},
+-	{0xAA, 0xc, 0},
+-	{0xAB, 0xaa, 0},
+-	{0xAC, 0x2, 0},
+-	{0xAD, 0, 0},
+-	{0xAE, 0x10, 0},
+-	{0xAF, 0x1, 0},
+-	{0xB0, 0, 0},
+-	{0xB1, 0, 0},
+-	{0xB2, 0x80, 0},
+-	{0xB3, 0x60, 0},
+-	{0xB4, 0x44, 0},
+-	{0xB5, 0x55, 0},
+-	{0xB6, 0x1, 0},
+-	{0xB7, 0x55, 0},
+-	{0xB8, 0x1, 0},
+-	{0xB9, 0x5, 0},
+-	{0xBA, 0x55, 0},
+-	{0xBB, 0x55, 0},
+-	{0xC1, 0, 0},
+-	{0xC2, 0, 0},
+-	{0xC3, 0, 0},
+-	{0xC4, 0, 0},
+-	{0xC5, 0, 0},
+-	{0xC6, 0, 0},
+-	{0xC7, 0, 0},
+-	{0xC8, 0, 0},
+-	{0xC9, 0x1, 1},
+-	{0xCA, 0, 0},
+-	{0xCB, 0, 0},
+-	{0xCC, 0, 0},
+-	{0xCD, 0, 0},
+-	{0xCE, 0x5e, 0},
+-	{0xCF, 0xc, 0},
+-	{0xD0, 0xc, 0},
+-	{0xD1, 0xc, 0},
+-	{0xD2, 0, 0},
+-	{0xD3, 0x2b, 0},
+-	{0xD4, 0xc, 0},
+-	{0xD5, 0, 0},
+-	{0xD6, 0x70, 1},
+-	{0xDB, 0x7, 0},
+-	{0xDC, 0, 0},
+-	{0xDD, 0, 0},
+-	{0xDE, 0x88, 1},
+-	{0xDF, 0, 0},
+-	{0xE0, 0x1f, 0},
+-	{0xE1, 0x20, 1},
+-	{0xE2, 0x1, 0},
+-	{0xE3, 0x30, 0},
+-	{0xE4, 0x70, 0},
+-	{0xE5, 0, 0},
+-	{0xE6, 0, 0},
+-	{0xE7, 0x33, 0},
+-	{0xE8, 0xf, 1},
+-	{0xE9, 0xf, 1},
+-	{0xEA, 0, 0},
+-	{0xEB, 0x11, 0},
+-	{0xEE, 0, 0},
+-	{0xEF, 0x7e, 0},
+-	{0xF0, 0x3f, 0},
+-	{0xF1, 0x7f, 0},
+-	{0xF2, 0x78, 0},
+-	{0xF3, 0x58, 1},
+-	{0xF4, 0x88, 0},
+-	{0xF5, 0x8, 0},
+-	{0xF6, 0xf, 0},
+-	{0xF7, 0xbc, 0},
+-	{0xF8, 0x8, 0},
+-	{0xF9, 0x60, 0},
+-	{0xFA, 0x13, 1},
+-	{0xFB, 0x70, 0},
+-	{0xFC, 0, 0},
+-	{0xFD, 0, 0},
+-	{0xFE, 0, 0},
+-	{0xFF, 0x33, 0},
+-	{0x100, 0x13, 1},
+-	{0x101, 0xf, 1},
+-	{0x102, 0xee, 1},
+-	{0x105, 0x3c, 0},
+-	{0x106, 0x1, 1},
+-	{0x107, 0xa, 0},
+-	{0x108, 0x9d, 0},
+-	{0x109, 0xa, 0},
+-	{0x10A, 0, 0},
+-	{0x10B, 0x40, 0},
+-	{0x10C, 0x40, 0},
+-	{0x10D, 0x88, 0},
+-	{0x10E, 0x10, 0},
+-	{0x10F, 0xf0, 0},
+-	{0x110, 0x10, 0},
+-	{0x111, 0xf0, 0},
+-	{0x112, 0, 0},
+-	{0x113, 0, 0},
+-	{0x114, 0x10, 0},
+-	{0x115, 0x55, 0},
+-	{0x116, 0x3f, 1},
+-	{0x117, 0x36, 1},
+-	{0x118, 0, 0},
+-	{0x119, 0, 0},
+-	{0x11A, 0, 0},
+-	{0x11B, 0x87, 0},
+-	{0x11C, 0x11, 0},
+-	{0x11D, 0, 0},
+-	{0x11E, 0x33, 0},
+-	{0x11F, 0x88, 0},
+-	{0x120, 0, 0},
+-	{0x121, 0x87, 0},
+-	{0x122, 0x11, 0},
+-	{0x123, 0, 0},
+-	{0x124, 0x33, 0},
+-	{0x125, 0x88, 0},
+-	{0x126, 0x20, 1},
+-	{0x127, 0x3f, 0},
+-	{0x128, 0x44, 0},
+-	{0x129, 0x8c, 0},
+-	{0x12A, 0x6c, 0},
+-	{0x12B, 0x22, 0},
+-	{0x12C, 0xbe, 0},
+-	{0x12D, 0x55, 0},
+-	{0x12F, 0xc, 0},
+-	{0x130, 0xaa, 0},
+-	{0x131, 0x2, 0},
+-	{0x132, 0, 0},
+-	{0x133, 0x10, 0},
+-	{0x134, 0x1, 0},
+-	{0x135, 0, 0},
+-	{0x136, 0, 0},
+-	{0x137, 0x80, 0},
+-	{0x138, 0x60, 0},
+-	{0x139, 0x44, 0},
+-	{0x13A, 0x55, 0},
+-	{0x13B, 0x1, 0},
+-	{0x13C, 0x55, 0},
+-	{0x13D, 0x1, 0},
+-	{0x13E, 0x5, 0},
+-	{0x13F, 0x55, 0},
+-	{0x140, 0x55, 0},
+-	{0x146, 0, 0},
+-	{0x147, 0, 0},
+-	{0x148, 0, 0},
+-	{0x149, 0, 0},
+-	{0x14A, 0, 0},
+-	{0x14B, 0, 0},
+-	{0x14C, 0, 0},
+-	{0x14D, 0, 0},
+-	{0x14E, 0x1, 1},
+-	{0x14F, 0, 0},
+-	{0x150, 0, 0},
+-	{0x151, 0, 0},
+-	{0x154, 0xc, 0},
+-	{0x155, 0xc, 0},
+-	{0x156, 0xc, 0},
+-	{0x157, 0, 0},
+-	{0x158, 0x2b, 0},
+-	{0x159, 0x84, 0},
+-	{0x15A, 0x15, 0},
+-	{0x15B, 0xf, 0},
+-	{0x15C, 0, 0},
+-	{0x15D, 0, 0},
+-	{0x15E, 0, 1},
+-	{0x15F, 0, 1},
+-	{0x160, 0, 1},
+-	{0x161, 0, 1},
+-	{0x162, 0, 1},
+-	{0x163, 0, 1},
+-	{0x164, 0, 0},
+-	{0x165, 0, 0},
+-	{0x166, 0, 0},
+-	{0x167, 0, 0},
+-	{0x168, 0, 0},
+-	{0x169, 0, 0},
+-	{0x16A, 0, 1},
+-	{0x16B, 0, 1},
+-	{0x16C, 0, 1},
+-	{0x16D, 0, 0},
+-	{0x170, 0, 0},
+-	{0x171, 0x77, 0},
+-	{0x172, 0x77, 0},
+-	{0x173, 0x77, 0},
+-	{0x174, 0x77, 0},
+-	{0x175, 0, 0},
+-	{0x176, 0x3, 0},
+-	{0x177, 0x37, 0},
+-	{0x178, 0x3, 0},
+-	{0x179, 0, 0},
+-	{0x17A, 0x21, 0},
+-	{0x17B, 0x21, 0},
+-	{0x17C, 0, 0},
+-	{0x17D, 0xaa, 0},
+-	{0x17E, 0, 0},
+-	{0x17F, 0xaa, 0},
+-	{0x180, 0, 0},
+-	{0x190, 0, 0},
+-	{0x191, 0x77, 0},
+-	{0x192, 0x77, 0},
+-	{0x193, 0x77, 0},
+-	{0x194, 0x77, 0},
+-	{0x195, 0, 0},
+-	{0x196, 0x3, 0},
+-	{0x197, 0x37, 0},
+-	{0x198, 0x3, 0},
+-	{0x199, 0, 0},
+-	{0x19A, 0x21, 0},
+-	{0x19B, 0x21, 0},
+-	{0x19C, 0, 0},
+-	{0x19D, 0xaa, 0},
+-	{0x19E, 0, 0},
+-	{0x19F, 0xaa, 0},
+-	{0x1A0, 0, 0},
+-	{0x1A1, 0x2, 0},
+-	{0x1A2, 0xf, 0},
+-	{0x1A3, 0xf, 0},
+-	{0x1A4, 0, 1},
+-	{0x1A5, 0, 1},
+-	{0x1A6, 0, 1},
+-	{0x1A7, 0x2, 0},
+-	{0x1A8, 0xf, 0},
+-	{0x1A9, 0xf, 0},
+-	{0x1AA, 0, 1},
+-	{0x1AB, 0, 1},
+-	{0x1AC, 0, 1},
+-	{0x1AD, 0x84, 0},
+-	{0x1AE, 0x60, 0},
+-	{0x1AF, 0x47, 0},
+-	{0x1B0, 0x47, 0},
+-	{0x1B1, 0, 0},
+-	{0x1B2, 0, 0},
+-	{0x1B3, 0, 0},
+-	{0x1B4, 0, 0},
+-	{0x1B5, 0, 0},
+-	{0x1B6, 0, 0},
+-	{0x1B7, 0x5, 1},
+-	{0x1B8, 0, 0},
+-	{0x1B9, 0, 0},
+-	{0x1BA, 0, 0},
+-	{0x1BB, 0, 0},
+-	{0x1BC, 0, 0},
+-	{0x1BD, 0, 0},
+-	{0x1BE, 0, 0},
+-	{0x1BF, 0, 0},
+-	{0x1C0, 0, 0},
+-	{0x1C1, 0, 0},
+-	{0x1C2, 0xa0, 1},
+-	{0x1C3, 0, 0},
+-	{0x1C4, 0, 0},
+-	{0x1C5, 0, 0},
+-	{0x1C6, 0, 0},
+-	{0x1C7, 0, 0},
+-	{0x1C8, 0, 0},
+-	{0x1C9, 0, 0},
+-	{0x1CA, 0, 0},
+-	{0xFFFF, 0, 0}
+-};
+-
+-static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 };
+-
+-static s32 nphy_lnagain_est0[] = { -315, 40370 };
+-static s32 nphy_lnagain_est1[] = { -224, 23242 };
+-
+-static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = {
+-	{
+-	 {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69},
+-	 {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69},
+-	 {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68},
+-	 {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67},
+-	 {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66},
+-	 {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65},
+-	 {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65},
+-	 {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65},
+-	 {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65}
+-	 },
+-	{
+-	 {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79},
+-	 {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78},
+-	 {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78},
+-	 {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78},
+-	 {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78}
+-	 }
+-};
+-
+-static const u32 nphy_tpc_txgain[] = {
+-	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
+-	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
+-	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
+-	0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
+-	0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
+-	0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
+-	0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
+-	0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
+-	0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
+-	0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
+-	0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
+-	0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
+-	0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
+-	0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
+-	0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
+-	0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
+-	0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
+-	0x03902942, 0x03902844, 0x03902842, 0x03902744,
+-	0x03902742, 0x03902644, 0x03902642, 0x03902544,
+-	0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
+-	0x03802a42, 0x03802944, 0x03802942, 0x03802844,
+-	0x03802842, 0x03802744, 0x03802742, 0x03802644,
+-	0x03802642, 0x03802544, 0x03802542, 0x03802444,
+-	0x03802442, 0x03802344, 0x03802342, 0x03802244,
+-	0x03802242, 0x03802144, 0x03802142, 0x03802044,
+-	0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
+-	0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
+-	0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
+-	0x03801a42, 0x03801944, 0x03801942, 0x03801844,
+-	0x03801842, 0x03801744, 0x03801742, 0x03801644,
+-	0x03801642, 0x03801544, 0x03801542, 0x03801444,
+-	0x03801442, 0x03801344, 0x03801342, 0x00002b00
+-};
+-
+-static const u16 nphy_tpc_loscale[] = {
+-	256, 256, 271, 271, 287, 256, 256, 271,
+-	271, 287, 287, 304, 304, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 341,
+-	341, 362, 362, 383, 383, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 256,
+-	256, 271, 271, 287, 287, 304, 304, 322,
+-	322, 341, 341, 362, 362, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 256,
+-	256, 271, 271, 287, 287, 304, 304, 322,
+-	322, 341, 341, 362, 362, 256, 256, 271,
+-	271, 287, 287, 304, 304, 322, 322, 341,
+-	341, 362, 362, 383, 383, 406, 406, 430,
+-	430, 455, 455, 482, 482, 511, 511, 541,
+-	541, 573, 573, 607, 607, 643, 643, 681,
+-	681, 722, 722, 764, 764, 810, 810, 858,
+-	858, 908, 908, 962, 962, 1019, 1019, 256
+-};
+-
+-static u32 nphy_tpc_txgain_ipa[] = {
+-	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
+-	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
+-	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
+-	0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
+-	0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
+-	0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
+-	0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
+-	0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
+-	0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
+-	0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
+-	0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
+-	0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
+-	0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
+-	0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
+-	0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
+-	0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
+-	0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
+-	0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
+-	0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
+-	0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
+-	0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
+-	0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
+-	0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
+-	0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
+-	0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
+-	0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
+-	0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
+-	0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
+-	0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
+-	0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
+-	0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
+-	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_rev5[] = {
+-	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
+-	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
+-	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
+-	0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
+-	0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
+-	0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
+-	0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
+-	0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
+-	0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
+-	0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
+-	0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
+-	0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
+-	0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
+-	0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
+-	0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
+-	0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
+-	0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
+-	0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
+-	0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
+-	0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
+-	0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
+-	0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
+-	0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
+-	0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
+-	0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
+-	0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
+-	0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
+-	0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
+-	0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
+-	0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
+-	0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
+-	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_rev6[] = {
+-	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
+-	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
+-	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
+-	0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
+-	0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
+-	0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
+-	0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
+-	0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
+-	0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
+-	0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
+-	0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
+-	0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
+-	0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
+-	0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
+-	0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
+-	0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
+-	0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
+-	0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
+-	0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
+-	0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
+-	0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
+-	0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
+-	0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
+-	0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
+-	0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
+-	0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
+-	0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
+-	0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
+-	0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
+-	0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
+-	0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
+-	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = {
+-	0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039,
+-	0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032,
+-	0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d,
+-	0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c,
+-	0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d,
+-	0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a,
+-	0x70570028, 0x704f002a, 0x7047002c, 0x7047002a,
+-	0x70470028, 0x70470026, 0x70470024, 0x70470022,
+-	0x7047001f, 0x70370027, 0x70370024, 0x70370022,
+-	0x70370020, 0x7037001f, 0x7037001d, 0x7037001b,
+-	0x7037001a, 0x70370018, 0x70370017, 0x7027001e,
+-	0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022,
+-	0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b,
+-	0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015,
+-	0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011,
+-	0x70170019, 0x70170018, 0x70170016, 0x70170015,
+-	0x70170014, 0x70170013, 0x70170012, 0x70170010,
+-	0x70170010, 0x7017000f, 0x700f001d, 0x700f001b,
+-	0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015,
+-	0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011,
+-	0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e,
+-	0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b,
+-	0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009,
+-	0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007,
+-	0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006,
+-	0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004,
+-	0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004,
+-	0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003,
+-	0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002,
+-	0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001,
+-	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001,
+-	0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = {
+-	0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039,
+-	0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032,
+-	0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d,
+-	0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c,
+-	0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d,
+-	0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a,
+-	0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a,
+-	0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022,
+-	0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022,
+-	0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b,
+-	0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e,
+-	0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022,
+-	0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b,
+-	0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015,
+-	0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011,
+-	0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015,
+-	0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010,
+-	0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b,
+-	0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015,
+-	0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011,
+-	0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e,
+-	0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b,
+-	0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009,
+-	0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007,
+-	0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006,
+-	0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004,
+-	0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004,
+-	0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003,
+-	0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002,
+-	0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001,
+-	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001,
+-	0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = {
+-	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+-	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+-	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+-	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+-	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+-	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+-	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+-	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+-	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+-	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+-	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+-	0x30170028, 0x30170026, 0x30170024, 0x30170022,
+-	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+-	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+-	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+-	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+-	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+-	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+-	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = {
+-	0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
+-	0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
+-	0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
+-	0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
+-	0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
+-	0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
+-	0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
+-	0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
+-	0x30270027, 0x30270025, 0x30270023, 0x301f002c,
+-	0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
+-	0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
+-	0x30170028, 0x30170026, 0x30170024, 0x30170022,
+-	0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
+-	0x3017001a, 0x30170018, 0x30170017, 0x30170015,
+-	0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
+-	0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
+-	0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
+-	0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
+-	0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
+-	0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g[] = {
+-	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
+-	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
+-	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
+-	0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
+-	0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
+-	0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
+-	0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
+-	0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
+-	0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
+-	0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
+-	0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
+-	0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
+-	0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
+-	0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
+-	0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
+-	0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
+-	0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
+-	0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
+-	0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
+-	0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
+-	0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
+-	0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
+-	0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
+-	0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
+-	0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
+-	0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
+-	0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
+-	0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
+-	0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
+-	0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
+-	0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
+-	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g_2057[] = {
+-	0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039,
+-	0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035,
+-	0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033,
+-	0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a,
+-	0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039,
+-	0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038,
+-	0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038,
+-	0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037,
+-	0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036,
+-	0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037,
+-	0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036,
+-	0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035,
+-	0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033,
+-	0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034,
+-	0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032,
+-	0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028,
+-	0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020,
+-	0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019,
+-	0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014,
+-	0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010,
+-	0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d,
+-	0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a,
+-	0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008,
+-	0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006,
+-	0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005,
+-	0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004,
+-	0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
+-	0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
+-	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+-	0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
+-	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
+-	0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001
+-};
+-
+-static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = {
+-	0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a,
+-	0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a,
+-	0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028,
+-	0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e,
+-	0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e,
+-	0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e,
+-	0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d,
+-	0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d,
+-	0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c,
+-	0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b,
+-	0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b,
+-	0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a,
+-	0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029,
+-	0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029,
+-	0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027,
+-	0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020,
+-	0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019,
+-	0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014,
+-	0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f,
+-	0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c,
+-	0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a,
+-	0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008,
+-	0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006,
+-	0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005,
+-	0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004,
+-	0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003,
+-	0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002,
+-	0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001,
+-	0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001
+-};
+-
+-static s8 nphy_papd_pga_gain_delta_ipa_2g[] = {
+-	-114, -108, -98, -91, -84, -78, -70, -62,
+-	-54, -46, -39, -31, -23, -15, -8, 0
+-};
+-
+-static s8 nphy_papd_pga_gain_delta_ipa_5g[] = {
+-	-100, -95, -89, -83, -77, -70, -63, -56,
+-	-48, -41, -33, -25, -19, -12, -6, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = {
+-	-159, -113, -86, -72, -62, -54, -48, -43,
+-	-39, -35, -31, -28, -25, -23, -20, -18,
+-	-17, -15, -13, -11, -10, -8, -7, -6,
+-	-5, -4, -3, -3, -2, -1, -1, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = {
+-	-109, -109, -82, -68, -58, -50, -44, -39,
+-	-35, -31, -28, -26, -23, -21, -19, -17,
+-	-16, -14, -13, -11, -10, -9, -8, -7,
+-	-5, -5, -4, -3, -2, -1, -1, 0
+-};
+-
+-static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = {
+-	-122, -122, -95, -80, -69, -61, -54, -49,
+-	-43, -39, -35, -32, -28, -26, -23, -21,
+-	-18, -16, -15, -13, -11, -10, -8, -7,
+-	-6, -5, -4, -3, -2, -1, -1, 0
+-};
+-
+-static s8 nphy_papd_pgagain_dlt_5g_2057[] = {
+-	-107, -101, -92, -85, -78, -71, -62, -55,
+-	-47, -39, -32, -24, -19, -12, -6, 0
+-};
+-
+-static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = {
+-	-110, -104, -95, -88, -81, -74, -66, -58,
+-	-50, -44, -36, -28, -23, -15, -8, 0
+-};
+-
+-static u8 pad_gain_codes_used_2057rev5[] = {
+-	20, 19, 18, 17, 16, 15, 14, 13, 12, 11,
+-	10, 9, 8, 7, 6, 5, 4, 3, 2, 1
+-};
+-
+-static u8 pad_gain_codes_used_2057rev7[] = {
+-	15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+-	5, 4, 3, 2, 1
+-};
+-
+-static u8 pad_all_gain_codes_2057[] = {
+-	31, 30, 29, 28, 27, 26, 25, 24, 23, 22,
+-	21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+-	11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
+-	1, 0
+-};
+-
+-static u8 pga_all_gain_codes_2057[] = {
+-	15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+-};
+-
+-static u32 nphy_papd_scaltbl[] = {
+-	0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038,
+-	0x0887003c, 0x081f003f, 0x07a20043, 0x07340047,
+-	0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059,
+-	0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070,
+-	0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d,
+-	0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2,
+-	0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0,
+-	0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a,
+-	0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162,
+-	0x015d0177, 0x0149018e, 0x013701a5, 0x012601be,
+-	0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232,
+-	0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3,
+-	0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a,
+-	0x008b03af, 0x008303e7, 0x007c0422, 0x00750461,
+-	0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583,
+-	0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1
+-};
+-
+-static u32 nphy_tpc_txgain_rev3[] = {
+-	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
+-	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
+-	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
+-	0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
+-	0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
+-	0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
+-	0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
+-	0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
+-	0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
+-	0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
+-	0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
+-	0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
+-	0x19410044, 0x19410042, 0x19410040, 0x1941003e,
+-	0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
+-	0x18410044, 0x18410042, 0x18410040, 0x1841003e,
+-	0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
+-	0x17410044, 0x17410042, 0x17410040, 0x1741003e,
+-	0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
+-	0x16410044, 0x16410042, 0x16410040, 0x1641003e,
+-	0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
+-	0x15410044, 0x15410042, 0x15410040, 0x1541003e,
+-	0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
+-	0x14410044, 0x14410042, 0x14410040, 0x1441003e,
+-	0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
+-	0x13410044, 0x13410042, 0x13410040, 0x1341003e,
+-	0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
+-	0x12410044, 0x12410042, 0x12410040, 0x1241003e,
+-	0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
+-	0x11410044, 0x11410042, 0x11410040, 0x1141003e,
+-	0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
+-	0x10410044, 0x10410042, 0x10410040, 0x1041003e,
+-	0x1041003c, 0x1041003b, 0x10410039, 0x10410037
+-};
+-
+-static u32 nphy_tpc_txgain_HiPwrEPA[] = {
+-	0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
+-	0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
+-	0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
+-	0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
+-	0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
+-	0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
+-	0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
+-	0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
+-	0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
+-	0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
+-	0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
+-	0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
+-	0x09410044, 0x09410042, 0x09410040, 0x0941003e,
+-	0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
+-	0x08410044, 0x08410042, 0x08410040, 0x0841003e,
+-	0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
+-	0x07410044, 0x07410042, 0x07410040, 0x0741003e,
+-	0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
+-	0x06410044, 0x06410042, 0x06410040, 0x0641003e,
+-	0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
+-	0x05410044, 0x05410042, 0x05410040, 0x0541003e,
+-	0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
+-	0x04410044, 0x04410042, 0x04410040, 0x0441003e,
+-	0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
+-	0x03410044, 0x03410042, 0x03410040, 0x0341003e,
+-	0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
+-	0x02410044, 0x02410042, 0x02410040, 0x0241003e,
+-	0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
+-	0x01410044, 0x01410042, 0x01410040, 0x0141003e,
+-	0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
+-	0x00410044, 0x00410042, 0x00410040, 0x0041003e,
+-	0x0041003c, 0x0041003b, 0x00410039, 0x00410037
+-};
+-
+-static u32 nphy_tpc_txgain_epa_2057rev3[] = {
+-	0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d,
+-	0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b,
+-	0x8091003b, 0x8089003a, 0x8081003a, 0x80790039,
+-	0x80710039, 0x8069003a, 0x8061003b, 0x8059003d,
+-	0x8051003f, 0x80490042, 0x8049003e, 0x8049003b,
+-	0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b,
+-	0x80390038, 0x80390035, 0x8031003a, 0x80310036,
+-	0x80310033, 0x8029003a, 0x80290037, 0x80290034,
+-	0x80290031, 0x80210039, 0x80210036, 0x80210033,
+-	0x80210030, 0x8019003c, 0x80190039, 0x80190036,
+-	0x80190033, 0x80190030, 0x8019002d, 0x8019002b,
+-	0x80190028, 0x8011003a, 0x80110036, 0x80110033,
+-	0x80110030, 0x8011002e, 0x8011002b, 0x80110029,
+-	0x80110027, 0x80110024, 0x80110022, 0x80110020,
+-	0x8011001f, 0x8011001d, 0x8009003a, 0x80090037,
+-	0x80090034, 0x80090031, 0x8009002e, 0x8009002c,
+-	0x80090029, 0x80090027, 0x80090025, 0x80090023,
+-	0x80090021, 0x8009001f, 0x8009001d, 0x8009011d,
+-	0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d,
+-	0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d,
+-	0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d
+-};
+-
+-static u32 nphy_tpc_txgain_epa_2057rev5[] = {
+-	0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d,
+-	0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b,
+-	0x1091003b, 0x1089003a, 0x1081003a, 0x10790039,
+-	0x10710039, 0x1069003a, 0x1061003b, 0x1059003d,
+-	0x1051003f, 0x10490042, 0x1049003e, 0x1049003b,
+-	0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b,
+-	0x10390038, 0x10390035, 0x1031003a, 0x10310036,
+-	0x10310033, 0x1029003a, 0x10290037, 0x10290034,
+-	0x10290031, 0x10210039, 0x10210036, 0x10210033,
+-	0x10210030, 0x1019003c, 0x10190039, 0x10190036,
+-	0x10190033, 0x10190030, 0x1019002d, 0x1019002b,
+-	0x10190028, 0x1011003a, 0x10110036, 0x10110033,
+-	0x10110030, 0x1011002e, 0x1011002b, 0x10110029,
+-	0x10110027, 0x10110024, 0x10110022, 0x10110020,
+-	0x1011001f, 0x1011001d, 0x1009003a, 0x10090037,
+-	0x10090034, 0x10090031, 0x1009002e, 0x1009002c,
+-	0x10090029, 0x10090027, 0x10090025, 0x10090023,
+-	0x10090021, 0x1009001f, 0x1009001d, 0x1009001b,
+-	0x1009001a, 0x10090018, 0x10090017, 0x10090016,
+-	0x10090015, 0x10090013, 0x10090012, 0x10090011,
+-	0x10090010, 0x1009000f, 0x1009000f, 0x1009000e,
+-	0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b,
+-	0x1009000a, 0x1009000a, 0x10090009, 0x10090009,
+-	0x10090008, 0x10090008, 0x10090007, 0x10090007,
+-	0x10090007, 0x10090006, 0x10090006, 0x10090005,
+-	0x10090005, 0x10090005, 0x10090005, 0x10090004,
+-	0x10090004, 0x10090004, 0x10090004, 0x10090003,
+-	0x10090003, 0x10090003, 0x10090003, 0x10090003,
+-	0x10090003, 0x10090002, 0x10090002, 0x10090002,
+-	0x10090002, 0x10090002, 0x10090002, 0x10090002,
+-	0x10090002, 0x10090002, 0x10090001, 0x10090001,
+-	0x10090001, 0x10090001, 0x10090001, 0x10090001
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev3[] = {
+-	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
+-	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
+-	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
+-	0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
+-	0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
+-	0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
+-	0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
+-	0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
+-	0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
+-	0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
+-	0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
+-	0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
+-	0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
+-	0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
+-	0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
+-	0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
+-	0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
+-	0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
+-	0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
+-	0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
+-	0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
+-	0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
+-	0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
+-	0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
+-	0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
+-	0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
+-	0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
+-	0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
+-	0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
+-	0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
+-	0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
+-	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev4[] = {
+-	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
+-	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
+-	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
+-	0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
+-	0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
+-	0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
+-	0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
+-	0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
+-	0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
+-	0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
+-	0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
+-	0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
+-	0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
+-	0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
+-	0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
+-	0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
+-	0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
+-	0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
+-	0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
+-	0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
+-	0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
+-	0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
+-	0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
+-	0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
+-	0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
+-	0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
+-	0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
+-	0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
+-	0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
+-	0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
+-	0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
+-	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_rev5[] = {
+-	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
+-	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
+-	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
+-	0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
+-	0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
+-	0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
+-	0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
+-	0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
+-	0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
+-	0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
+-	0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
+-	0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
+-	0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
+-	0x09620039, 0x09620037, 0x09620035, 0x09620033,
+-	0x08620044, 0x08620042, 0x08620040, 0x0862003e,
+-	0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
+-	0x07620043, 0x07620042, 0x07620040, 0x0762003f,
+-	0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
+-	0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
+-	0x06620039, 0x06620037, 0x06620035, 0x06620033,
+-	0x05620046, 0x05620044, 0x05620042, 0x05620040,
+-	0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
+-	0x04620044, 0x04620042, 0x04620040, 0x0462003e,
+-	0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
+-	0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
+-	0x03620038, 0x03620037, 0x03620035, 0x03620033,
+-	0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
+-	0x02620046, 0x02620044, 0x02620043, 0x02620042,
+-	0x0162004a, 0x01620048, 0x01620046, 0x01620044,
+-	0x01620043, 0x01620042, 0x01620041, 0x01620040,
+-	0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
+-	0x0062003b, 0x00620039, 0x00620037, 0x00620035
+-};
+-
+-static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = {
+-	0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
+-	0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
+-	0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
+-	0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
+-	0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
+-	0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
+-	0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
+-	0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
+-	0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
+-	0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
+-	0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
+-	0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
+-	0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
+-	0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
+-	0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
+-	0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
+-	0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
+-	0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
+-	0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
+-	0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
+-	0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
+-	0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
+-	0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
+-	0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
+-	0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
+-	0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
+-	0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
+-	0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
+-	0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
+-	0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
+-	0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
+-	0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
+-};
+-
+-static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 };
+-static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 };
+-static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = {
+-	0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a };
+-static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
+-	0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 };
+-
+-static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+-				   chan_info_nphy_radio2057_t **t0,
+-				   chan_info_nphy_radio205x_t **t1,
+-				   chan_info_nphy_radio2057_rev5_t **t2,
+-				   chan_info_nphy_2055_t **t3);
+-static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans,
+-					const nphy_sfo_cfg_t *c);
+-
+-static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi,
+-					    u16 reduction_factr);
+-static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *,
+-					     u32 *buf);
+-static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr);
+-static void wlc_phy_txlpfbw_nphy(phy_info_t *pi);
+-static void wlc_phy_spurwar_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_radio_preinit_2055(phy_info_t *pi);
+-static void wlc_phy_radio_init_2055(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2055(phy_info_t *pi);
+-static void wlc_phy_radio_preinit_205x(phy_info_t *pi);
+-static void wlc_phy_radio_init_2056(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2056(phy_info_t *pi);
+-static void wlc_phy_radio_init_2057(phy_info_t *pi);
+-static void wlc_phy_radio_postinit_2057(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi);
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi);
+-static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_restore_rssical_nphy(phy_info_t *pi);
+-static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi);
+-static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi);
+-static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg,
+-				      u8 type, bool d);
+-static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rxcore,
+-					     u16 *rg, u8 type);
+-static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble);
+-static void wlc_phy_savecal_nphy(phy_info_t *pi);
+-static void wlc_phy_restorecal_nphy(phy_info_t *pi);
+-static void wlc_phy_resetcca_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi);
+-static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi);
+-static void wlc_phy_precal_txgain_nphy(phy_info_t *pi);
+-static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core);
+-
+-static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi);
+-static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi);
+-static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1);
+-static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi);
+-
+-static void wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32,
+-			    u32 e);
+-static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core);
+-static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *,
+-			    phy_cal_mode_t, u8);
+-static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi,
+-					  nphy_papd_restore_state *state);
+-static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi,
+-					nphy_papd_restore_state *state, u8);
+-
+-static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals);
+-
+-static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *evts,
+-				   u8 *dlys, u8 len);
+-
+-static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset);
+-
+-static void
+-wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value,
+-				  u8 core_mask, u8 off,
+-				  u8 override_id);
+-
+-static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type);
+-static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi);
+-
+-static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max,
+-					    u16 *pwr_offset,
+-					    u8 tmp_max_pwr, u8 rate_start,
+-					    u8 rate_end);
+-
+-static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi);
+-static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi);
+-
+-static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi);
+-static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core);
+-static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0,
+-					   u8 idx1);
+-static void wlc_phy_a4(phy_info_t *pi, bool full_cal);
+-
+-static u16 wlc_phy_radio205x_rcal(phy_info_t *pi);
+-
+-static u16 wlc_phy_radio2057_rccal(phy_info_t *pi);
+-
+-static u16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz,
+-					    u16 max_val,
+-					    u8 dac_test_mode);
+-static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf,
+-					 u16 num_samps);
+-static void wlc_phy_runsamples_nphy(phy_info_t *pi, u16 n, u16 lps,
+-				    u16 wait, u8 iq, u8 dac_test_mode,
+-				    bool modify_bbmult);
+-
+-bool wlc_phy_bist_check_phy(wlc_phy_t *pih)
+-{
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u32 phybist0, phybist1, phybist2, phybist3, phybist4;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 16))
+-		return true;
+-
+-	phybist0 = read_phy_reg(pi, 0x0e);
+-	phybist1 = read_phy_reg(pi, 0x0f);
+-	phybist2 = read_phy_reg(pi, 0xea);
+-	phybist3 = read_phy_reg(pi, 0xeb);
+-	phybist4 = read_phy_reg(pi, 0x156);
+-
+-	if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) &&
+-	    (phybist3 == 0) && (phybist4 == 0)) {
+-		return true;
+-	}
+-
+-	return false;
+-}
+-
+-static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi)
+-{
+-	u16 addr, val;
+-
+-	val = 0x1e1f;
+-	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
+-	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
+-		write_phy_reg(pi, addr, val);
+-		if (addr == (NPHY_TO_BPHY_OFF + 0x97))
+-			val = 0x3e3f;
+-		else
+-			val -= 0x0202;
+-	}
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206);
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e);
+-
+-		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a);
+-
+-	} else {
+-
+-		write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668);
+-	}
+-}
+-
+-void
+-wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset,
+-			 u32 width, const void *data)
+-{
+-	mimophytbl_info_t tbl;
+-
+-	tbl.tbl_id = id;
+-	tbl.tbl_len = len;
+-	tbl.tbl_offset = offset;
+-	tbl.tbl_width = width;
+-	tbl.tbl_ptr = data;
+-	wlc_phy_write_table_nphy(pi, &tbl);
+-}
+-
+-void
+-wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset,
+-			u32 width, void *data)
+-{
+-	mimophytbl_info_t tbl;
+-
+-	tbl.tbl_id = id;
+-	tbl.tbl_len = len;
+-	tbl.tbl_offset = offset;
+-	tbl.tbl_width = width;
+-	tbl.tbl_ptr = data;
+-	wlc_phy_read_table_nphy(pi, &tbl);
+-}
+-
+-static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi)
+-{
+-	uint idx;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 16)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev16[idx]);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev7[idx]);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev3[idx]);
+-	} else {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++)
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev0[idx]);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi)
+-{
+-	uint idx = 0;
+-	u8 antswctrllut;
+-
+-	if (pi->phy_init_por)
+-		wlc_phy_static_table_download_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+-		    pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut;
+-
+-		switch (antswctrllut) {
+-		case 0:
+-
+-			break;
+-
+-		case 1:
+-
+-			if (pi->aa2g == 7) {
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_ANTSWCTRLLUT,
+-							 2, 0x21, 8,
+-							 &ant_sw_ctrl_tbl_rev8_2o3
+-							 [0]);
+-			} else {
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_ANTSWCTRLLUT,
+-							 2, 0x21, 8,
+-							 &ant_sw_ctrl_tbl_rev8
+-							 [0]);
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x25, 8,
+-						 &ant_sw_ctrl_tbl_rev8[2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x29, 8,
+-						 &ant_sw_ctrl_tbl_rev8[4]);
+-			break;
+-
+-		case 2:
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x1, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [0]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x5, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x9, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core0
+-						 [4]);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x21, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [0]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x25, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [2]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 2, 0x29, 8,
+-						 &ant_sw_ctrl_tbl_rev8_2057v7_core1
+-						 [4]);
+-			break;
+-
+-		default:
+-			break;
+-		}
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) {
+-
+-			if (idx == ANT_SWCTRL_TBL_REV3_IDX) {
+-				antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ?
+-				    pi->srom_fem2g.antswctrllut : pi->
+-				    srom_fem5g.antswctrllut;
+-				switch (antswctrllut) {
+-				case 0:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile
+-								 [idx]);
+-					break;
+-				case 1:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile1
+-								 [idx]);
+-					break;
+-				case 2:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile2
+-								 [idx]);
+-					break;
+-				case 3:
+-					wlc_phy_write_table_nphy(pi,
+-								 &mimophytbl_info_rev3_volatile3
+-								 [idx]);
+-					break;
+-				default:
+-					break;
+-				}
+-			} else {
+-				wlc_phy_write_table_nphy(pi,
+-							 &mimophytbl_info_rev3_volatile
+-							 [idx]);
+-			}
+-		}
+-	} else {
+-		for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) {
+-			wlc_phy_write_table_nphy(pi,
+-						 &mimophytbl_info_rev0_volatile
+-						 [idx]);
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_write_txmacreg_nphy(phy_info_t *pi, u16 holdoff, u16 delay)
+-{
+-	write_phy_reg(pi, 0x77, holdoff);
+-	write_phy_reg(pi, 0xb4, delay);
+-}
+-
+-void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs)
+-{
+-	u16 holdoff, delay;
+-
+-	if (rifs) {
+-
+-		holdoff = 0x10;
+-		delay = 0x258;
+-	} else {
+-
+-		holdoff = 0x15;
+-		delay = 0x320;
+-	}
+-
+-	wlc_phy_write_txmacreg_nphy(pi, holdoff, delay);
+-
+-	if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) {
+-		pi->sh->_rifs_phy = rifs;
+-	}
+-}
+-
+-bool wlc_phy_attach_nphy(phy_info_t *pi)
+-{
+-	uint i;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) {
+-		pi->phyhang_avoid = true;
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		pi->nphy_gband_spurwar_en = true;
+-
+-		if (pi->sh->boardflags2 & BFL2_SPUR_WAR) {
+-			pi->nphy_aband_spurwar_en = true;
+-		}
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) {
+-			pi->nphy_gband_spurwar2_en = true;
+-		}
+-	}
+-
+-	pi->n_preamble_override = AUTO;
+-	if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4))
+-		pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE;
+-
+-	pi->nphy_txrx_chain = AUTO;
+-	pi->phy_scraminit = AUTO;
+-
+-	pi->nphy_rxcalparams = 0x010100B5;
+-
+-	pi->nphy_perical = PHY_PERICAL_MPHASE;
+-	pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE;
+-	pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS;
+-
+-	pi->nphy_gain_boost = true;
+-	pi->nphy_elna_gain_config = false;
+-	pi->radio_is_on = false;
+-
+-	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
+-		pi->nphy_txpwrindex[i].index = AUTO;
+-	}
+-
+-	wlc_phy_txpwrctrl_config_nphy(pi);
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON)
+-		pi->hwpwrctrl_capable = true;
+-
+-	pi->pi_fptr.init = wlc_phy_init_nphy;
+-	pi->pi_fptr.calinit = wlc_phy_cal_init_nphy;
+-	pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy;
+-	pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy;
+-
+-	if (!wlc_phy_txpwr_srom_read_nphy(pi))
+-		return false;
+-
+-	return true;
+-}
+-
+-static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi)
+-{
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+-		pi->phy_5g_pwrgain = true;
+-		return;
+-	}
+-
+-	pi->nphy_txpwrctrl = PHY_TPC_HW_OFF;
+-	pi->phy_5g_pwrgain = false;
+-
+-	if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) &&
+-	    NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4))
+-		pi->nphy_txpwrctrl = PHY_TPC_HW_ON;
+-	else if ((pi->sh->sromrev >= 4)
+-		 && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN))
+-		pi->phy_5g_pwrgain = true;
+-}
+-
+-void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi)
+-{
+-	u16 val;
+-	u16 clip1_ths[2];
+-	nphy_txgains_t target_gain;
+-	u8 tx_pwr_ctrl_state;
+-	bool do_nphy_cal = false;
+-	uint core;
+-	uint origidx, intr_val;
+-	d11regs_t *regs;
+-	u32 d11_clk_ctl_st;
+-
+-	core = 0;
+-
+-	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
+-		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
+-	}
+-
+-	if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) &&
+-	    ((pi->sh->chippkg == BCM4717_PKG_ID) ||
+-	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
+-		if ((pi->sh->boardflags & BFL_EXTLNA) &&
+-		    (CHSPEC_IS2G(pi->radio_chanspec))) {
+-			ai_corereg(pi->sh->sih, SI_CC_IDX,
+-				   offsetof(chipcregs_t, chipcontrol), 0x40,
+-				   0x40);
+-		}
+-	}
+-
+-	if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) {
+-		si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA,
+-				   CCTRL5357_EXTPA);
+-	}
+-
+-	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
+-	    CHSPEC_IS40(pi->radio_chanspec)) {
+-
+-		regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID,
+-						    &origidx, &intr_val);
+-		d11_clk_ctl_st = R_REG(&regs->clk_ctl_st);
+-		AND_REG(&regs->clk_ctl_st,
+-			~(CCS_FORCEHT | CCS_HTAREQ));
+-
+-		W_REG(&regs->clk_ctl_st, d11_clk_ctl_st);
+-
+-		ai_restore_core(pi->sh->sih, origidx, intr_val);
+-	}
+-
+-	pi->use_int_tx_iqlo_cal_nphy =
+-	    (PHY_IPA(pi) ||
+-	     (NREV_GE(pi->pubpi.phy_rev, 7) ||
+-	      (NREV_GE(pi->pubpi.phy_rev, 5)
+-	       && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL)));
+-
+-	pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false;
+-
+-	pi->nphy_deaf_count = 0;
+-
+-	wlc_phy_tbl_init_nphy(pi);
+-
+-	pi->nphy_crsminpwr_adjusted = false;
+-	pi->nphy_noisevars_adjusted = false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xe7, 0);
+-		write_phy_reg(pi, 0xec, 0);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			write_phy_reg(pi, 0x342, 0);
+-			write_phy_reg(pi, 0x343, 0);
+-			write_phy_reg(pi, 0x346, 0);
+-			write_phy_reg(pi, 0x347, 0);
+-		}
+-		write_phy_reg(pi, 0xe5, 0);
+-		write_phy_reg(pi, 0xe6, 0);
+-	} else {
+-		write_phy_reg(pi, 0xec, 0);
+-	}
+-
+-	write_phy_reg(pi, 0x91, 0);
+-	write_phy_reg(pi, 0x92, 0);
+-	if (NREV_LT(pi->pubpi.phy_rev, 6)) {
+-		write_phy_reg(pi, 0x93, 0);
+-		write_phy_reg(pi, 0x94, 0);
+-	}
+-
+-	and_phy_reg(pi, 0xa1, ~3);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0x8f, 0);
+-		write_phy_reg(pi, 0xa5, 0);
+-	} else {
+-		write_phy_reg(pi, 0xa5, 0);
+-	}
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 2))
+-		mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+-	else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-		mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+-
+-	write_phy_reg(pi, 0x203, 32);
+-	write_phy_reg(pi, 0x201, 32);
+-
+-	if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD)
+-		write_phy_reg(pi, 0x20d, 160);
+-	else
+-		write_phy_reg(pi, 0x20d, 184);
+-
+-	write_phy_reg(pi, 0x13a, 200);
+-
+-	write_phy_reg(pi, 0x70, 80);
+-
+-	write_phy_reg(pi, 0x1ff, 48);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 8)) {
+-		wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override);
+-	}
+-
+-	wlc_phy_stf_chain_upd_nphy(pi);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0x180, 0xaa8);
+-		write_phy_reg(pi, 0x181, 0x9a4);
+-	}
+-
+-	if (PHY_IPA(pi)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 0), (1) << 0);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7),
+-				    (pi->nphy_papd_epsilon_offset[core]) << 7);
+-
+-		}
+-
+-		wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-			wlc_phy_extpa_set_tx_digi_filts_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_workarounds_nphy(pi);
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-	val = read_phy_reg(pi, 0x01);
+-	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+-	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-	wlapi_bmac_macphyclk_set(pi->sh->physhim, ON);
+-
+-	wlc_phy_pa_override_nphy(pi, OFF);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-	wlc_phy_pa_override_nphy(pi, ON);
+-
+-	wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_clip_det_nphy(pi, 0, clip1_ths);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		wlc_phy_bphy_init_nphy(pi);
+-
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	wlc_phy_txpwr_fixpower_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		u32 *tx_pwrctrl_tbl = NULL;
+-		u16 idx;
+-		s16 pga_gn = 0;
+-		s16 pad_gn = 0;
+-		s32 rfpwr_offset = 0;
+-
+-		if (PHY_IPA(pi)) {
+-			tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi);
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if NREV_IS
+-					(pi->pubpi.phy_rev, 3) {
+-					tx_pwrctrl_tbl =
+-					    nphy_tpc_5GHz_txgain_rev3;
+-				} else if NREV_IS
+-					(pi->pubpi.phy_rev, 4) {
+-					tx_pwrctrl_tbl =
+-					    (pi->srom_fem5g.extpagain == 3) ?
+-					    nphy_tpc_5GHz_txgain_HiPwrEPA :
+-					    nphy_tpc_5GHz_txgain_rev4;
+-				} else {
+-					tx_pwrctrl_tbl =
+-					    nphy_tpc_5GHz_txgain_rev5;
+-				}
+-
+-			} else {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (pi->pubpi.radiorev == 5) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_epa_2057rev5;
+-					} else if (pi->pubpi.radiorev == 3) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_epa_2057rev3;
+-					}
+-
+-				} else {
+-					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-					    (pi->srom_fem2g.extpagain == 3)) {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_HiPwrEPA;
+-					} else {
+-						tx_pwrctrl_tbl =
+-						    nphy_tpc_txgain_rev3;
+-					}
+-				}
+-			}
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+-					 192, 32, tx_pwrctrl_tbl);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+-					 192, 32, tx_pwrctrl_tbl);
+-
+-		pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			for (idx = 0; idx < 128; idx++) {
+-				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+-				pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f;
+-
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					if ((pi->pubpi.radiorev == 3) ||
+-					    (pi->pubpi.radiorev == 4) ||
+-					    (pi->pubpi.radiorev == 6)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev3n4
+-						    [pad_gn];
+-					} else if (pi->pubpi.radiorev == 5) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev5
+-						    [pad_gn];
+-					} else if ((pi->pubpi.radiorev == 7)
+-						   || (pi->pubpi.radiorev ==
+-						       8)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_padgain_dlt_2g_2057rev7
+-						    [pad_gn];
+-					}
+-				} else {
+-					if ((pi->pubpi.radiorev == 3) ||
+-					    (pi->pubpi.radiorev == 4) ||
+-					    (pi->pubpi.radiorev == 6)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_pgagain_dlt_5g_2057
+-						    [pga_gn];
+-					} else if ((pi->pubpi.radiorev == 7)
+-						   || (pi->pubpi.radiorev ==
+-						       8)) {
+-						rfpwr_offset = (s16)
+-						    nphy_papd_pgagain_dlt_5g_2057rev7
+-						    [pga_gn];
+-					}
+-				}
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE1TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE2TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-			}
+-		} else {
+-
+-			for (idx = 0; idx < 128; idx++) {
+-				pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf;
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					rfpwr_offset = (s16)
+-					    nphy_papd_pga_gain_delta_ipa_2g
+-					    [pga_gn];
+-				} else {
+-					rfpwr_offset = (s16)
+-					    nphy_papd_pga_gain_delta_ipa_5g
+-					    [pga_gn];
+-				}
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE1TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_CORE2TXPWRCTL,
+-							 1, 576 + idx, 32,
+-							 &rfpwr_offset);
+-			}
+-
+-		}
+-	} else {
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128,
+-					 192, 32, nphy_tpc_txgain);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128,
+-					 192, 32, nphy_tpc_txgain);
+-	}
+-
+-	if (pi->sh->phyrxchain != 0x3) {
+-		wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi,
+-					     pi->sh->phyrxchain);
+-	}
+-
+-	if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+-		wlc_phy_cal_perical_mphase_restart(pi);
+-	}
+-
+-	if (!NORADIO_ENAB(pi->pubpi)) {
+-		bool do_rssi_cal = false;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+-			    (pi->nphy_rssical_chanspec_2G == 0) :
+-			    (pi->nphy_rssical_chanspec_5G == 0);
+-
+-			if (do_rssi_cal) {
+-				wlc_phy_rssi_cal_nphy(pi);
+-			} else {
+-				wlc_phy_restore_rssical_nphy(pi);
+-			}
+-		} else {
+-			wlc_phy_rssi_cal_nphy(pi);
+-		}
+-
+-		if (!SCAN_RM_IN_PROGRESS(pi)) {
+-			do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ?
+-			    (pi->nphy_iqcal_chanspec_2G == 0) :
+-			    (pi->nphy_iqcal_chanspec_5G == 0);
+-		}
+-
+-		if (!pi->do_initcal)
+-			do_nphy_cal = false;
+-
+-		if (do_nphy_cal) {
+-
+-			target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-
+-			if (pi->antsel_type == ANTSEL_2x3)
+-				wlc_phy_antsel_init((wlc_phy_t *) pi, true);
+-
+-			if (pi->nphy_perical != PHY_PERICAL_MPHASE) {
+-				wlc_phy_rssi_cal_nphy(pi);
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					pi->nphy_cal_orig_pwr_idx[0] =
+-					    pi->nphy_txpwrindex[PHY_CORE_0].
+-					    index_internal;
+-					pi->nphy_cal_orig_pwr_idx[1] =
+-					    pi->nphy_txpwrindex[PHY_CORE_1].
+-					    index_internal;
+-
+-					wlc_phy_precal_txgain_nphy(pi);
+-					target_gain =
+-					    wlc_phy_get_tx_gain_nphy(pi);
+-				}
+-
+-				if (wlc_phy_cal_txiqlo_nphy
+-				    (pi, target_gain, true, false) == 0) {
+-					if (wlc_phy_cal_rxiq_nphy
+-					    (pi, target_gain, 2,
+-					     false) == 0) {
+-						wlc_phy_savecal_nphy(pi);
+-
+-					}
+-				}
+-			} else if (pi->mphase_cal_phase_id ==
+-				   MPHASE_CAL_STATE_IDLE) {
+-
+-				wlc_phy_cal_perical((wlc_phy_t *) pi,
+-						    PHY_PERICAL_PHYINIT);
+-			}
+-		} else {
+-			wlc_phy_restorecal_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-
+-	wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6))
+-
+-		write_phy_reg(pi, 0x70, 50);
+-
+-	wlc_phy_txlpfbw_nphy(pi);
+-
+-	wlc_phy_spurwar_nphy(pi);
+-
+-}
+-
+-static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble)
+-{
+-	bool gf_preamble = false;
+-	u16 val;
+-
+-	if (preamble == WLC_N_PREAMBLE_GF) {
+-		gf_preamble = true;
+-	}
+-
+-	val = read_phy_reg(pi, 0xed);
+-
+-	val |= RX_GF_MM_AUTO;
+-	val &= ~RX_GF_OR_MM;
+-	if (gf_preamble)
+-		val |= RX_GF_OR_MM;
+-
+-	write_phy_reg(pi, 0xed, val);
+-}
+-
+-static void wlc_phy_resetcca_nphy(phy_info_t *pi)
+-{
+-	u16 val;
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-	val = read_phy_reg(pi, 0x01);
+-	write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA);
+-	udelay(1);
+-	write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA));
+-
+-	wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-}
+-
+-void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en)
+-{
+-	u16 rfctrlintc_override_val;
+-
+-	if (!en) {
+-
+-		pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91);
+-		pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			rfctrlintc_override_val = 0x1480;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			rfctrlintc_override_val =
+-			    CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480;
+-		} else {
+-			rfctrlintc_override_val =
+-			    CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+-		}
+-
+-		write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+-		write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+-	} else {
+-
+-		write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save);
+-		write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save);
+-	}
+-
+-}
+-
+-void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi)
+-{
+-
+-	u16 txrx_chain =
+-	    (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1);
+-	bool CoreActv_override = false;
+-
+-	if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) {
+-		txrx_chain = NPHY_RfseqCoreActv_TxRxChain0;
+-		CoreActv_override = true;
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+-			and_phy_reg(pi, 0xa0, ~0x20);
+-		}
+-	} else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) {
+-		txrx_chain = NPHY_RfseqCoreActv_TxRxChain1;
+-		CoreActv_override = true;
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 2)) {
+-			or_phy_reg(pi, 0xa0, 0x20);
+-		}
+-	}
+-
+-	mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain);
+-
+-	if (CoreActv_override) {
+-
+-		pi->nphy_perical = PHY_PERICAL_DISABLE;
+-		or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+-	} else {
+-		pi->nphy_perical = PHY_PERICAL_MPHASE;
+-		and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override);
+-	}
+-}
+-
+-void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask)
+-{
+-	u16 regval;
+-	u16 tbl_buf[16];
+-	uint i;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-	u16 tbl_opcode;
+-	bool suspend;
+-
+-	pi->sh->phyrxchain = rxcore_bitmask;
+-
+-	if (!pi->sh->clk)
+-		return;
+-
+-	suspend =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!suspend)
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	regval = read_phy_reg(pi, 0xa2);
+-	regval &= ~(0xf << 4);
+-	regval |= ((u16) (rxcore_bitmask & 0x3)) << 4;
+-	write_phy_reg(pi, 0xa2, regval);
+-
+-	if ((rxcore_bitmask & 0x3) != 0x3) {
+-
+-		write_phy_reg(pi, 0x20e, 1);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (pi->rx2tx_biasentry == -1) {
+-				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							ARRAY_SIZE(tbl_buf), 80,
+-							16, tbl_buf);
+-
+-				for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) {
+-					if (tbl_buf[i] ==
+-					    NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) {
+-
+-						pi->rx2tx_biasentry = (u8) i;
+-						tbl_opcode =
+-						    NPHY_REV3_RFSEQ_CMD_NOP;
+-						wlc_phy_table_write_nphy(pi,
+-									 NPHY_TBL_ID_RFSEQ,
+-									 1, i,
+-									 16,
+-									 &tbl_opcode);
+-						break;
+-					} else if (tbl_buf[i] ==
+-						   NPHY_REV3_RFSEQ_CMD_END) {
+-						break;
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		write_phy_reg(pi, 0x20e, 30);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (pi->rx2tx_biasentry != -1) {
+-				tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS;
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1, pi->rx2tx_biasentry,
+-							 16, &tbl_opcode);
+-				pi->rx2tx_biasentry = -1;
+-			}
+-		}
+-	}
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	if (!suspend)
+-		wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih)
+-{
+-	u16 regval, rxen_bits;
+-	phy_info_t *pi = (phy_info_t *) pih;
+-
+-	regval = read_phy_reg(pi, 0xa2);
+-	rxen_bits = (regval >> 4) & 0xf;
+-
+-	return (u8) rxen_bits;
+-}
+-
+-bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi)
+-{
+-	return PHY_IPA(pi);
+-}
+-
+-static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi)
+-{
+-	u8 idx, idx2, i, delta_ind;
+-
+-	for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) {
+-		pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx];
+-	}
+-
+-	for (i = 0; i < 4; i++) {
+-		idx2 = 0;
+-
+-		delta_ind = 0;
+-
+-		switch (i) {
+-		case 0:
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)
+-			    && NPHY_IS_SROM_REINTERPRET) {
+-				idx = TXP_FIRST_MCS_40_SISO;
+-			} else {
+-				idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-				    TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM;
+-				delta_ind = 1;
+-			}
+-			break;
+-
+-		case 1:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD;
+-			break;
+-
+-		case 2:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC;
+-			break;
+-
+-		case 3:
+-
+-			idx = (CHSPEC_IS40(pi->radio_chanspec)) ?
+-			    TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM;
+-			break;
+-		}
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		idx = idx + delta_ind;
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx++];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		idx = idx + 1 - delta_ind;
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-		pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] =
+-		    pi->tx_power_offset[idx];
+-	}
+-}
+-
+-void wlc_phy_cal_init_nphy(phy_info_t *pi)
+-{
+-}
+-
+-static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core)
+-{
+-	if (core == PHY_CORE_0) {
+-		write_phy_reg(pi, 0x38, 0x4);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x37, 0x0060);
+-		} else {
+-			write_phy_reg(pi, 0x37, 0x1080);
+-		}
+-	} else if (core == PHY_CORE_1) {
+-		write_phy_reg(pi, 0x2ae, 0x4);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x2ad, 0x0060);
+-		} else {
+-			write_phy_reg(pi, 0x2ad, 0x1080);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain)
+-{
+-	u8 txchain0, txchain1;
+-
+-	txchain0 = txchain & 0x1;
+-	txchain1 = (txchain & 0x2) >> 1;
+-	if (!txchain0) {
+-		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+-	}
+-
+-	if (!txchain1) {
+-		wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy(phy_info_t *pi)
+-{
+-	u8 rfseq_rx2tx_events[] = {
+-		NPHY_RFSEQ_CMD_NOP,
+-		NPHY_RFSEQ_CMD_RXG_FBW,
+-		NPHY_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_RFSEQ_CMD_TX_GAIN,
+-		NPHY_RFSEQ_CMD_EXT_PA
+-	};
+-	u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
+-	u8 rfseq_tx2rx_events[] = {
+-		NPHY_RFSEQ_CMD_NOP,
+-		NPHY_RFSEQ_CMD_EXT_PA,
+-		NPHY_RFSEQ_CMD_TX_GAIN,
+-		NPHY_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_RFSEQ_CMD_RXG_FBW,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS
+-	};
+-	u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
+-	u8 rfseq_tx2rx_events_rev3[] = {
+-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
+-	u8 rfseq_rx2tx_events_rev3[] = {
+-		NPHY_REV3_RFSEQ_CMD_NOP,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_EXT_PA,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
+-
+-	u8 rfseq_rx2tx_events_rev3_ipa[] = {
+-		NPHY_REV3_RFSEQ_CMD_NOP,
+-		NPHY_REV3_RFSEQ_CMD_RXG_FBW,
+-		NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
+-		NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_REV3_RFSEQ_CMD_RXPD_TXPD,
+-		NPHY_REV3_RFSEQ_CMD_TX_GAIN,
+-		NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS,
+-		NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
+-		NPHY_REV3_RFSEQ_CMD_END
+-	};
+-	u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
+-	u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
+-
+-	s16 alpha0, alpha1, alpha2;
+-	s16 beta0, beta1, beta2;
+-	u32 leg_data_weights, ht_data_weights, nss1_data_weights,
+-	    stbc_data_weights;
+-	u8 chan_freq_range = 0;
+-	u16 dac_control = 0x0002;
+-	u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
+-	u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
+-	u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+-	u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 };
+-	u16 *aux_adc_vmid;
+-	u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 };
+-	u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
+-	u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
+-	u16 *aux_adc_gain;
+-	u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
+-	u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
+-	s32 min_nvar_val = 0x18d;
+-	s32 min_nvar_offset_6mbps = 20;
+-	u8 pdetrange;
+-	u8 triso;
+-	u16 regval;
+-	u16 afectrl_adc_ctrl1_rev7 = 0x20;
+-	u16 afectrl_adc_ctrl2_rev7 = 0x0;
+-	u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
+-	u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
+-	u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+-	u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
+-	u16 ipalvlshift_3p3_war_en = 0;
+-	u16 rccal_bcap_val, rccal_scap_val;
+-	u16 rccal_tx20_11b_bcap = 0;
+-	u16 rccal_tx20_11b_scap = 0;
+-	u16 rccal_tx20_11n_bcap = 0;
+-	u16 rccal_tx20_11n_scap = 0;
+-	u16 rccal_tx40_11n_bcap = 0;
+-	u16 rccal_tx40_11n_scap = 0;
+-	u16 rx2tx_lpf_rc_lut_tx20_11b = 0;
+-	u16 rx2tx_lpf_rc_lut_tx20_11n = 0;
+-	u16 rx2tx_lpf_rc_lut_tx40_11n = 0;
+-	u16 tx_lpf_bw_ofdm_20mhz = 0;
+-	u16 tx_lpf_bw_ofdm_40mhz = 0;
+-	u16 tx_lpf_bw_11b = 0;
+-	u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt;
+-	u16 txgm_idac_bleed = 0;
+-	bool rccal_ovrd = false;
+-	u16 freq;
+-	int coreNum;
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0);
+-	} else {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (!ISSIM_ENAB(pi->sh->sih)) {
+-		or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-			mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4));
+-
+-			mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0));
+-			mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8));
+-			mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0));
+-			mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8));
+-			mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0));
+-			mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8));
+-			mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0));
+-			mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8));
+-			mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0));
+-			mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8));
+-			mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0));
+-			mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8));
+-			mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0));
+-			mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8));
+-			mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0));
+-			mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8));
+-		}
+-
+-		if (NREV_LE(pi->pubpi.phy_rev, 8)) {
+-			write_phy_reg(pi, 0x23f, 0x1b0);
+-			write_phy_reg(pi, 0x240, 0x1b0);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0));
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+-					 &dac_control);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+-					 &dac_control);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					1, 0, 32, &leg_data_weights);
+-		leg_data_weights = leg_data_weights & 0xffffff;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 0, 32, &leg_data_weights);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 2, 0x15e, 16,
+-					 rfseq_rx2tx_dacbufpu_rev7);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16,
+-					 rfseq_rx2tx_dacbufpu_rev7);
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3_ipa,
+-					       rfseq_rx2tx_dlys_rev3_ipa,
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa) /
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa
+-						[0]));
+-		}
+-
+-		mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14));
+-		mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14));
+-
+-		tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154);
+-		tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159);
+-		tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152);
+-
+-		if (PHY_IPA(pi)) {
+-
+-			if (((pi->pubpi.radiorev == 5)
+-			     && (CHSPEC_IS40(pi->radio_chanspec) == 1))
+-			    || (pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-
+-				rccal_bcap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_BCAP_VAL);
+-				rccal_scap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_SCAP_VAL);
+-
+-				rccal_tx20_11b_bcap = rccal_bcap_val;
+-				rccal_tx20_11b_scap = rccal_scap_val;
+-
+-				if ((pi->pubpi.radiorev == 5) &&
+-				    (CHSPEC_IS40(pi->radio_chanspec) == 1)) {
+-
+-					rccal_tx20_11n_bcap = rccal_bcap_val;
+-					rccal_tx20_11n_scap = rccal_scap_val;
+-					rccal_tx40_11n_bcap = 0xc;
+-					rccal_tx40_11n_scap = 0xc;
+-
+-					rccal_ovrd = true;
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					tx_lpf_bw_ofdm_20mhz = 4;
+-					tx_lpf_bw_11b = 1;
+-
+-					if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-						rccal_tx20_11n_bcap = 0xc;
+-						rccal_tx20_11n_scap = 0xc;
+-						rccal_tx40_11n_bcap = 0xa;
+-						rccal_tx40_11n_scap = 0xa;
+-					} else {
+-						rccal_tx20_11n_bcap = 0x14;
+-						rccal_tx20_11n_scap = 0x14;
+-						rccal_tx40_11n_bcap = 0xf;
+-						rccal_tx40_11n_scap = 0xf;
+-					}
+-
+-					rccal_ovrd = true;
+-				}
+-			}
+-
+-		} else {
+-
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				tx_lpf_bw_ofdm_20mhz = 1;
+-				tx_lpf_bw_ofdm_40mhz = 3;
+-
+-				rccal_bcap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_BCAP_VAL);
+-				rccal_scap_val =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_RCCAL_SCAP_VAL);
+-
+-				rccal_tx20_11b_bcap = rccal_bcap_val;
+-				rccal_tx20_11b_scap = rccal_scap_val;
+-
+-				rccal_tx20_11n_bcap = 0x13;
+-				rccal_tx20_11n_scap = 0x11;
+-				rccal_tx40_11n_bcap = 0x13;
+-				rccal_tx40_11n_scap = 0x11;
+-
+-				rccal_ovrd = true;
+-			}
+-		}
+-
+-		if (rccal_ovrd) {
+-
+-			rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) |
+-			    (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b;
+-			rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) |
+-			    (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz;
+-			rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) |
+-			    (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz;
+-
+-			for (coreNum = 0; coreNum <= 1; coreNum++) {
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x152 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11b);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x153 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x154 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx20_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x155 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x156 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x157 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x158 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-				wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-							 1,
+-							 0x159 + coreNum * 0x10,
+-							 16,
+-							 &rx2tx_lpf_rc_lut_tx40_11n);
+-			}
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		}
+-
+-		if (!NORADIO_ENAB(pi->pubpi)) {
+-			write_phy_reg(pi, 0x32f, 0x3);
+-		}
+-
+-		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		}
+-
+-		if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) ||
+-		    (pi->pubpi.radiorev == 6)) {
+-			if ((pi->sh->sromrev >= 8)
+-			    && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3))
+-				ipalvlshift_3p3_war_en = 1;
+-
+-			if (ipalvlshift_3p3_war_en) {
+-				write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG,
+-						0x5);
+-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL1,
+-						0x30);
+-				write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0);
+-				or_radio_reg(pi,
+-					     RADIO_2057_RXTXBIAS_CONFIG_CORE0,
+-					     0x1);
+-				or_radio_reg(pi,
+-					     RADIO_2057_RXTXBIAS_CONFIG_CORE1,
+-					     0x1);
+-
+-				ipa2g_mainbias = 0x1f;
+-
+-				ipa2g_casconv = 0x6f;
+-
+-				ipa2g_biasfilt = 0xaa;
+-			} else {
+-
+-				ipa2g_mainbias = 0x2b;
+-
+-				ipa2g_casconv = 0x7f;
+-
+-				ipa2g_biasfilt = 0xee;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum, IPA2G_IMAIN,
+-							 ipa2g_mainbias);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum, IPA2G_CASCONV,
+-							 ipa2g_casconv);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 IPA2G_BIAS_FILTER,
+-							 ipa2g_biasfilt);
+-				}
+-			}
+-		}
+-
+-		if (PHY_IPA(pi)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if ((pi->pubpi.radiorev == 3)
+-				    || (pi->pubpi.radiorev == 4)
+-				    || (pi->pubpi.radiorev == 6)) {
+-
+-					txgm_idac_bleed = 0x7f;
+-				}
+-
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					if (txgm_idac_bleed != 0)
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 TXGM_IDAC_BLEED,
+-								 txgm_idac_bleed);
+-				}
+-
+-				if (pi->pubpi.radiorev == 5) {
+-
+-					for (coreNum = 0; coreNum <= 1;
+-					     coreNum++) {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_CASCONV,
+-								 0x13);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_IMAIN,
+-								 0x1f);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 IPA2G_BIAS_FILTER,
+-								 0xee);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 PAD2G_IDACS,
+-								 0x8a);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, coreNum,
+-								 PAD_BIAS_FILTER_BWS,
+-								 0x3e);
+-					}
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					if (CHSPEC_IS40(pi->radio_chanspec) ==
+-					    0) {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 0,
+-								 IPA2G_IMAIN,
+-								 0x14);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 1,
+-								 IPA2G_IMAIN,
+-								 0x12);
+-					} else {
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 0,
+-								 IPA2G_IMAIN,
+-								 0x16);
+-						WRITE_RADIO_REG4(pi, RADIO_2057,
+-								 CORE, 1,
+-								 IPA2G_IMAIN,
+-								 0x16);
+-					}
+-				}
+-
+-			} else {
+-				freq =
+-				    CHAN5G_FREQ(CHSPEC_CHANNEL
+-						(pi->radio_chanspec));
+-				if (((freq >= 5180) && (freq <= 5230))
+-				    || ((freq >= 5745) && (freq <= 5805))) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 0, IPA5G_BIAS_FILTER,
+-							 0xff);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 1, IPA5G_BIAS_FILTER,
+-							 0xff);
+-				}
+-			}
+-		} else {
+-
+-			if (pi->pubpi.radiorev != 5) {
+-				for (coreNum = 0; coreNum <= 1; coreNum++) {
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 TXMIX2G_TUNE_BOOST_PU,
+-							 0x61);
+-					WRITE_RADIO_REG4(pi, RADIO_2057, CORE,
+-							 coreNum,
+-							 TXGM_IDAC_BLEED, 0x70);
+-				}
+-			}
+-		}
+-
+-		if (pi->pubpi.radiorev == 4) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x05, 16,
+-						 &afectrl_adc_ctrl1_rev7);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x15, 16,
+-						 &afectrl_adc_ctrl1_rev7);
+-
+-			for (coreNum = 0; coreNum <= 1; coreNum++) {
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_VCM_CAL_MASTER, 0x0);
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_SET_VCM_I, 0x3f);
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 AFE_SET_VCM_Q, 0x3f);
+-			}
+-		} else {
+-			mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+-			mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+-
+-			mod_phy_reg(pi, 0xa6, (0x1 << 0), 0);
+-			mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0xa7, (0x1 << 0), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0));
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x05, 16,
+-						 &afectrl_adc_ctrl2_rev7);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1,
+-						 0x15, 16,
+-						 &afectrl_adc_ctrl2_rev7);
+-
+-			mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0x8f, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 2), 0);
+-		}
+-
+-		write_phy_reg(pi, 0x6a, 0x2);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32,
+-					 &min_nvar_offset_6mbps);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16,
+-					 &rfseq_pktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16,
+-					 &rfseq_pktgn_lpf_h_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16,
+-					 &rfseq_htpktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16,
+-					 &rfseq_cckpktgn_lpf_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16,
+-					 &rfseq_tx2rx_lpf_h_hpc_rev7);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16,
+-					 &rfseq_rx2tx_lpf_h_hpc_rev7);
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		} else {
+-			min_nvar_val = noise_var_tbl_rev7[3];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-
+-			min_nvar_val = noise_var_tbl_rev7[127];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		}
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		pdetrange =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    pdetrange : pi->srom_fem2g.pdetrange;
+-
+-		if (pdetrange == 0) {
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x70;
+-				aux_adc_vmid_rev7_core1[3] = 0x70;
+-				aux_adc_gain_rev7[3] = 2;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x80;
+-				aux_adc_vmid_rev7_core1[3] = 0x80;
+-				aux_adc_gain_rev7[3] = 3;
+-			}
+-		} else if (pdetrange == 1) {
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x7c;
+-				aux_adc_vmid_rev7_core1[3] = 0x7c;
+-				aux_adc_gain_rev7[3] = 2;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x8c;
+-				aux_adc_vmid_rev7_core1[3] = 0x8c;
+-				aux_adc_gain_rev7[3] = 1;
+-			}
+-		} else if (pdetrange == 2) {
+-			if (pi->pubpi.radioid == BCM2057_ID) {
+-				if ((pi->pubpi.radiorev == 5)
+-				    || (pi->pubpi.radiorev == 7)
+-				    || (pi->pubpi.radiorev == 8)) {
+-					if (chan_freq_range ==
+-					    WL_CHAN_FREQ_RANGE_2G) {
+-						aux_adc_vmid_rev7_core0[3] =
+-						    0x8c;
+-						aux_adc_vmid_rev7_core1[3] =
+-						    0x8c;
+-						aux_adc_gain_rev7[3] = 0;
+-					} else {
+-						aux_adc_vmid_rev7_core0[3] =
+-						    0x96;
+-						aux_adc_vmid_rev7_core1[3] =
+-						    0x96;
+-						aux_adc_gain_rev7[3] = 0;
+-					}
+-				}
+-			}
+-
+-		} else if (pdetrange == 3) {
+-			if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x89;
+-				aux_adc_vmid_rev7_core1[3] = 0x89;
+-				aux_adc_gain_rev7[3] = 0;
+-			}
+-
+-		} else if (pdetrange == 5) {
+-
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				aux_adc_vmid_rev7_core0[3] = 0x80;
+-				aux_adc_vmid_rev7_core1[3] = 0x80;
+-				aux_adc_gain_rev7[3] = 3;
+-			} else {
+-				aux_adc_vmid_rev7_core0[3] = 0x70;
+-				aux_adc_vmid_rev7_core1[3] = 0x70;
+-				aux_adc_gain_rev7[3] = 2;
+-			}
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16,
+-					 &aux_adc_vmid_rev7_core0);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16,
+-					 &aux_adc_vmid_rev7_core1);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16,
+-					 &aux_adc_gain_rev7);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16,
+-					 &aux_adc_gain_rev7);
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		write_phy_reg(pi, 0x23f, 0x1f8);
+-		write_phy_reg(pi, 0x240, 0x1f8);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					1, 0, 32, &leg_data_weights);
+-		leg_data_weights = leg_data_weights & 0xffffff;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 0, 32, &leg_data_weights);
+-
+-		alpha0 = 293;
+-		alpha1 = 435;
+-		alpha2 = 261;
+-		beta0 = 366;
+-		beta1 = 205;
+-		beta2 = 32;
+-		write_phy_reg(pi, 0x145, alpha0);
+-		write_phy_reg(pi, 0x146, alpha1);
+-		write_phy_reg(pi, 0x147, alpha2);
+-		write_phy_reg(pi, 0x148, beta0);
+-		write_phy_reg(pi, 0x149, beta1);
+-		write_phy_reg(pi, 0x14a, beta2);
+-
+-		write_phy_reg(pi, 0x38, 0xC);
+-		write_phy_reg(pi, 0x2ae, 0xC);
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX,
+-				       rfseq_tx2rx_events_rev3,
+-				       rfseq_tx2rx_dlys_rev3,
+-				       sizeof(rfseq_tx2rx_events_rev3) /
+-				       sizeof(rfseq_tx2rx_events_rev3[0]));
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3_ipa,
+-					       rfseq_rx2tx_dlys_rev3_ipa,
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa) /
+-					       sizeof
+-					       (rfseq_rx2tx_events_rev3_ipa
+-						[0]));
+-		}
+-
+-		if ((pi->sh->hw_phyrxchain != 0x3) &&
+-		    (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) {
+-
+-			if (PHY_IPA(pi)) {
+-				rfseq_rx2tx_dlys_rev3[5] = 59;
+-				rfseq_rx2tx_dlys_rev3[6] = 1;
+-				rfseq_rx2tx_events_rev3[7] =
+-				    NPHY_REV3_RFSEQ_CMD_END;
+-			}
+-
+-			wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX,
+-					       rfseq_rx2tx_events_rev3,
+-					       rfseq_rx2tx_dlys_rev3,
+-					       sizeof(rfseq_rx2tx_events_rev3) /
+-					       sizeof(rfseq_rx2tx_events_rev3
+-						      [0]));
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x6a, 0x2);
+-		} else {
+-			write_phy_reg(pi, 0x6a, 0x9c40);
+-		}
+-
+-		mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8));
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec) == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		} else {
+-			min_nvar_val = noise_var_tbl_rev3[3];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3,
+-						 32, &min_nvar_val);
+-
+-			min_nvar_val = noise_var_tbl_rev3[127];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 127, 32, &min_nvar_val);
+-		}
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16,
+-					 &dac_control);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16,
+-					 &dac_control);
+-
+-		pdetrange =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    pdetrange : pi->srom_fem2g.pdetrange;
+-
+-		if (pdetrange == 0) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-				aux_adc_vmid = aux_adc_vmid_rev4;
+-				aux_adc_gain = aux_adc_gain_rev4;
+-			} else {
+-				aux_adc_vmid = aux_adc_vmid_rev3;
+-				aux_adc_gain = aux_adc_gain_rev3;
+-			}
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				switch (chan_freq_range) {
+-				case WL_CHAN_FREQ_RANGE_5GL:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				case WL_CHAN_FREQ_RANGE_5GM:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				case WL_CHAN_FREQ_RANGE_5GH:
+-					aux_adc_vmid[3] = 0x89;
+-					aux_adc_gain[3] = 0;
+-					break;
+-				default:
+-					break;
+-				}
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, aux_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, aux_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, aux_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, aux_adc_gain);
+-		} else if (pdetrange == 1) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, sk_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, sk_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, sk_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, sk_adc_gain);
+-		} else if (pdetrange == 2) {
+-
+-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 };
+-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 };
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				chan_freq_range =
+-				    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-				if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-					bcm_adc_vmid[3] = 0x8e;
+-					bcm_adc_gain[3] = 0x03;
+-				} else {
+-					bcm_adc_vmid[3] = 0x94;
+-					bcm_adc_gain[3] = 0x03;
+-				}
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				bcm_adc_vmid[3] = 0x84;
+-				bcm_adc_gain[3] = 0x02;
+-			}
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, bcm_adc_gain);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, bcm_adc_gain);
+-		} else if (pdetrange == 3) {
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if ((NREV_GE(pi->pubpi.phy_rev, 4))
+-			    && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) {
+-
+-				u16 auxadc_vmid[] = {
+-					0xa2, 0xb4, 0xb4, 0x270 };
+-				u16 auxadc_gain[] = {
+-					0x02, 0x02, 0x02, 0x00 };
+-
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x08, 16, auxadc_vmid);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x18, 16, auxadc_vmid);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x0c, 16, auxadc_gain);
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_AFECTRL, 4,
+-							 0x1c, 16, auxadc_gain);
+-			}
+-		} else if ((pdetrange == 4) || (pdetrange == 5)) {
+-			u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 };
+-			u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 };
+-			u16 Vmid[2], Av[2];
+-
+-			chan_freq_range =
+-			    wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-			if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) {
+-				Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89;
+-				Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89;
+-				Av[0] = (pdetrange == 4) ? 2 : 0;
+-				Av[1] = (pdetrange == 4) ? 2 : 0;
+-			} else {
+-				Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74;
+-				Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70;
+-				Av[0] = (pdetrange == 4) ? 2 : 0;
+-				Av[1] = (pdetrange == 4) ? 2 : 0;
+-			}
+-
+-			bcm_adc_vmid[3] = Vmid[0];
+-			bcm_adc_gain[3] = Av[0];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x08, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x0c, 16, bcm_adc_gain);
+-
+-			bcm_adc_vmid[3] = Vmid[1];
+-			bcm_adc_gain[3] = Av[1];
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x18, 16, bcm_adc_vmid);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
+-						 0x1c, 16, bcm_adc_gain);
+-		}
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0),
+-				0x6);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1),
+-				0x6);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0),
+-				0x7);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1),
+-				0x7);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0),
+-				0x88);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1),
+-				0x88);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1),
+-				0x0);
+-
+-		triso =
+-		    (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.
+-		    triso : pi->srom_fem2g.triso;
+-		if (triso == 7) {
+-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0);
+-			wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1);
+-		}
+-
+-		wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain);
+-
+-		if (((pi->sh->boardflags2 & BFL2_APLL_WAR) &&
+-		     (CHSPEC_IS5G(pi->radio_chanspec))) ||
+-		    (((pi->sh->boardflags2 & BFL2_GPLL_WAR) ||
+-		      (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) &&
+-		     (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-			nss1_data_weights = 0x00088888;
+-			ht_data_weights = 0x00088888;
+-			stbc_data_weights = 0x00088888;
+-		} else {
+-			nss1_data_weights = 0x88888888;
+-			ht_data_weights = 0x88888888;
+-			stbc_data_weights = 0x88888888;
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 1, 32, &nss1_data_weights);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 2, 32, &ht_data_weights);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL,
+-					 1, 3, 32, &stbc_data_weights);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_GMBB_IDAC |
+-						RADIO_2056_TX0, 0x70);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_GMBB_IDAC |
+-						RADIO_2056_TX1, 0x70);
+-			}
+-		}
+-
+-		if (!pi->edcrs_threshold_lock) {
+-			write_phy_reg(pi, 0x224, 0x3eb);
+-			write_phy_reg(pi, 0x225, 0x3eb);
+-			write_phy_reg(pi, 0x226, 0x341);
+-			write_phy_reg(pi, 0x227, 0x341);
+-			write_phy_reg(pi, 0x228, 0x42b);
+-			write_phy_reg(pi, 0x229, 0x42b);
+-			write_phy_reg(pi, 0x22a, 0x381);
+-			write_phy_reg(pi, 0x22b, 0x381);
+-			write_phy_reg(pi, 0x22c, 0x42b);
+-			write_phy_reg(pi, 0x22d, 0x42b);
+-			write_phy_reg(pi, 0x22e, 0x381);
+-			write_phy_reg(pi, 0x22f, 0x381);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-
+-			if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) {
+-				wlapi_bmac_mhf(pi->sh->physhim, MHF4,
+-					       MHF4_BPHY_TXCORE0,
+-					       MHF4_BPHY_TXCORE0, WLC_BAND_ALL);
+-			}
+-		}
+-	} else {
+-
+-		if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD ||
+-		    (pi->sh->boardtype == 0x8b)) {
+-			uint i;
+-			u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 };
+-			for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++)
+-				rfseq_rx2tx_dlys[i] = war_dlys[i];
+-		}
+-
+-		if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) {
+-			and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7);
+-			and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7);
+-		} else {
+-			or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8);
+-			or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8);
+-		}
+-
+-		regval = 0x000a;
+-		wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, &regval);
+-		wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, &regval);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-			regval = 0xcdaa;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, &regval);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-			regval = 0x0000;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, &regval);
+-
+-			regval = 0x7aab;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, &regval);
+-
+-			regval = 0x0800;
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, &regval);
+-			wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, &regval);
+-		}
+-
+-		write_phy_reg(pi, 0xf8, 0x02d8);
+-		write_phy_reg(pi, 0xf9, 0x0301);
+-		write_phy_reg(pi, 0xfa, 0x02d8);
+-		write_phy_reg(pi, 0xfb, 0x0301);
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events,
+-				       rfseq_rx2tx_dlys,
+-				       sizeof(rfseq_rx2tx_events) /
+-				       sizeof(rfseq_rx2tx_events[0]));
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events,
+-				       rfseq_tx2rx_dlys,
+-				       sizeof(rfseq_tx2rx_events) /
+-				       sizeof(rfseq_tx2rx_events[0]));
+-
+-		wlc_phy_workarounds_nphy_gainctrl(pi);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-			if (read_phy_reg(pi, 0xa0) & NPHY_MLenable)
+-				wlapi_bmac_mhf(pi->sh->physhim, MHF3,
+-					       MHF3_NPHY_MLADV_WAR,
+-					       MHF3_NPHY_MLADV_WAR,
+-					       WLC_BAND_ALL);
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			write_phy_reg(pi, 0x1e3, 0x0);
+-			write_phy_reg(pi, 0x1e4, 0x0);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0x90, (0x1 << 7), 0);
+-
+-		alpha0 = 293;
+-		alpha1 = 435;
+-		alpha2 = 261;
+-		beta0 = 366;
+-		beta1 = 205;
+-		beta2 = 32;
+-		write_phy_reg(pi, 0x145, alpha0);
+-		write_phy_reg(pi, 0x146, alpha1);
+-		write_phy_reg(pi, 0x147, alpha2);
+-		write_phy_reg(pi, 0x148, beta0);
+-		write_phy_reg(pi, 0x149, beta1);
+-		write_phy_reg(pi, 0x14a, beta2);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-			mod_phy_reg(pi, 0x142, (0xf << 12), 0);
+-
+-			write_phy_reg(pi, 0x192, 0xb5);
+-			write_phy_reg(pi, 0x193, 0xa4);
+-			write_phy_reg(pi, 0x194, 0x0);
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			mod_phy_reg(pi, 0x221,
+-				    NPHY_FORCESIG_DECODEGATEDCLKS,
+-				    NPHY_FORCESIG_DECODEGATEDCLKS);
+-		}
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi)
+-{
+-	u16 w1th, hpf_code, currband;
+-	int ctr;
+-	u8 rfseq_updategainu_events[] = {
+-		NPHY_RFSEQ_CMD_RX_GAIN,
+-		NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
+-		NPHY_RFSEQ_CMD_SET_HPF_BW
+-	};
+-	u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
+-	s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
+-	s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
+-	s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
+-	s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
+-	s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
+-	s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
+-	s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
+-	s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
+-	s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
+-	s8 *lna1_gain_db = NULL;
+-	s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
+-	s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
+-	s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
+-	s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
+-	s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
+-	s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
+-	s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
+-	s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
+-	s8 *lna2_gain_db = NULL;
+-	s8 tiaG_gain_db[] = {
+-		0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
+-	s8 tiaA_gain_db[] = {
+-		0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
+-	s8 tiaA_gain_db_rev4[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 tiaA_gain_db_rev5[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 tiaA_gain_db_rev6[] = {
+-		0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
+-	s8 *tia_gain_db;
+-	s8 tiaG_gainbits[] = {
+-		0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+-	s8 tiaA_gainbits[] = {
+-		0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
+-	s8 tiaA_gainbits_rev4[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 tiaA_gainbits_rev5[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 tiaA_gainbits_rev6[] = {
+-		0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
+-	s8 *tia_gainbits;
+-	s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
+-	s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
+-	u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
+-	u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
+-	u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
+-	u16 rfseqG_init_gain_rev5_elna[] = {
+-		0x013f, 0x013f, 0x013f, 0x013f };
+-	u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
+-	u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
+-	u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
+-	u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
+-	u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
+-	u16 rfseqA_init_gain_rev4_elna[] = {
+-		0x314f, 0x314f, 0x314f, 0x314f };
+-	u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
+-	u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
+-	u16 *rfseq_init_gain;
+-	u16 initG_gaincode = 0x627e;
+-	u16 initG_gaincode_rev4 = 0x527e;
+-	u16 initG_gaincode_rev5 = 0x427e;
+-	u16 initG_gaincode_rev5_elna = 0x027e;
+-	u16 initG_gaincode_rev6 = 0x527e;
+-	u16 initG_gaincode_rev6_224B0 = 0x427e;
+-	u16 initG_gaincode_rev6_elna = 0x127e;
+-	u16 initA_gaincode = 0x52de;
+-	u16 initA_gaincode_rev4 = 0x629e;
+-	u16 initA_gaincode_rev4_elna = 0x329e;
+-	u16 initA_gaincode_rev5 = 0x729e;
+-	u16 initA_gaincode_rev6 = 0x729e;
+-	u16 init_gaincode;
+-	u16 clip1hiG_gaincode = 0x107e;
+-	u16 clip1hiG_gaincode_rev4 = 0x007e;
+-	u16 clip1hiG_gaincode_rev5 = 0x1076;
+-	u16 clip1hiG_gaincode_rev6 = 0x007e;
+-	u16 clip1hiA_gaincode = 0x00de;
+-	u16 clip1hiA_gaincode_rev4 = 0x029e;
+-	u16 clip1hiA_gaincode_rev5 = 0x029e;
+-	u16 clip1hiA_gaincode_rev6 = 0x029e;
+-	u16 clip1hi_gaincode;
+-	u16 clip1mdG_gaincode = 0x0066;
+-	u16 clip1mdA_gaincode = 0x00ca;
+-	u16 clip1mdA_gaincode_rev4 = 0x1084;
+-	u16 clip1mdA_gaincode_rev5 = 0x2084;
+-	u16 clip1mdA_gaincode_rev6 = 0x2084;
+-	u16 clip1md_gaincode = 0;
+-	u16 clip1loG_gaincode = 0x0074;
+-	u16 clip1loG_gaincode_rev5[] = {
+-		0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
+-	};
+-	u16 clip1loG_gaincode_rev6[] = {
+-		0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
+-	};
+-	u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
+-	u16 clip1loA_gaincode = 0x00cc;
+-	u16 clip1loA_gaincode_rev4 = 0x0086;
+-	u16 clip1loA_gaincode_rev5 = 0x2086;
+-	u16 clip1loA_gaincode_rev6 = 0x2086;
+-	u16 clip1lo_gaincode;
+-	u8 crsminG_th = 0x18;
+-	u8 crsminG_th_rev5 = 0x18;
+-	u8 crsminG_th_rev6 = 0x18;
+-	u8 crsminA_th = 0x1e;
+-	u8 crsminA_th_rev4 = 0x24;
+-	u8 crsminA_th_rev5 = 0x24;
+-	u8 crsminA_th_rev6 = 0x24;
+-	u8 crsmin_th;
+-	u8 crsminlG_th = 0x18;
+-	u8 crsminlG_th_rev5 = 0x18;
+-	u8 crsminlG_th_rev6 = 0x18;
+-	u8 crsminlA_th = 0x1e;
+-	u8 crsminlA_th_rev4 = 0x24;
+-	u8 crsminlA_th_rev5 = 0x24;
+-	u8 crsminlA_th_rev6 = 0x24;
+-	u8 crsminl_th = 0;
+-	u8 crsminuG_th = 0x18;
+-	u8 crsminuG_th_rev5 = 0x18;
+-	u8 crsminuG_th_rev6 = 0x18;
+-	u8 crsminuA_th = 0x1e;
+-	u8 crsminuA_th_rev4 = 0x24;
+-	u8 crsminuA_th_rev5 = 0x24;
+-	u8 crsminuA_th_rev6 = 0x24;
+-	u8 crsminuA_th_rev6_224B0 = 0x2d;
+-	u8 crsminu_th;
+-	u16 nbclipG_th = 0x20d;
+-	u16 nbclipG_th_rev4 = 0x1a1;
+-	u16 nbclipG_th_rev5 = 0x1d0;
+-	u16 nbclipG_th_rev6 = 0x1d0;
+-	u16 nbclipA_th = 0x1a1;
+-	u16 nbclipA_th_rev4 = 0x107;
+-	u16 nbclipA_th_rev5 = 0x0a9;
+-	u16 nbclipA_th_rev6 = 0x0f0;
+-	u16 nbclip_th = 0;
+-	u8 w1clipG_th = 5;
+-	u8 w1clipG_th_rev5 = 9;
+-	u8 w1clipG_th_rev6 = 5;
+-	u8 w1clipA_th = 25, w1clip_th;
+-	u8 rssi_gain_default = 0x50;
+-	u8 rssiG_gain_rev6_224B0 = 0x50;
+-	u8 rssiA_gain_rev5 = 0x90;
+-	u8 rssiA_gain_rev6 = 0x90;
+-	u8 rssi_gain;
+-	u16 regval[21];
+-	u8 triso;
+-
+-	triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso :
+-	    pi->srom_fem2g.triso;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi);
+-		} else if (pi->pubpi.radiorev == 7) {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-
+-			mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0));
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0));
+-
+-		} else if ((pi->pubpi.radiorev == 3)
+-			   || (pi->pubpi.radiorev == 8)) {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-
+-			if (pi->pubpi.radiorev == 8) {
+-				mod_phy_reg(pi, 0x283,
+-					    (0xff << 0), (0x44 << 0));
+-				mod_phy_reg(pi, 0x280,
+-					    (0xff << 0), (0x44 << 0));
+-			}
+-		} else {
+-			wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi);
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6));
+-
+-		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-		currband =
+-		    read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-		if (currband == 0) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				if (pi->pubpi.radiorev == 11) {
+-					lna1_gain_db = lna1G_gain_db_rev6_224B0;
+-					lna2_gain_db = lna2G_gain_db_rev6_224B0;
+-					rfseq_init_gain =
+-					    rfseqG_init_gain_rev6_224B0;
+-					init_gaincode =
+-					    initG_gaincode_rev6_224B0;
+-					clip1hi_gaincode =
+-					    clip1hiG_gaincode_rev6;
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev6_224B0;
+-					nbclip_th = nbclipG_th_rev6;
+-					w1clip_th = w1clipG_th_rev6;
+-					crsmin_th = crsminG_th_rev6;
+-					crsminl_th = crsminlG_th_rev6;
+-					crsminu_th = crsminuG_th_rev6;
+-					rssi_gain = rssiG_gain_rev6_224B0;
+-				} else {
+-					lna1_gain_db = lna1G_gain_db_rev6;
+-					lna2_gain_db = lna2G_gain_db_rev6;
+-					if (pi->sh->boardflags & BFL_EXTLNA) {
+-
+-						rfseq_init_gain =
+-						    rfseqG_init_gain_rev6_elna;
+-						init_gaincode =
+-						    initG_gaincode_rev6_elna;
+-					} else {
+-						rfseq_init_gain =
+-						    rfseqG_init_gain_rev6;
+-						init_gaincode =
+-						    initG_gaincode_rev6;
+-					}
+-					clip1hi_gaincode =
+-					    clip1hiG_gaincode_rev6;
+-					switch (triso) {
+-					case 0:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[0];
+-						break;
+-					case 1:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[1];
+-						break;
+-					case 2:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[2];
+-						break;
+-					case 3:
+-					default:
+-
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[3];
+-						break;
+-					case 4:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[4];
+-						break;
+-					case 5:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[5];
+-						break;
+-					case 6:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[6];
+-						break;
+-					case 7:
+-						clip1lo_gaincode =
+-						    clip1loG_gaincode_rev6[7];
+-						break;
+-					}
+-					nbclip_th = nbclipG_th_rev6;
+-					w1clip_th = w1clipG_th_rev6;
+-					crsmin_th = crsminG_th_rev6;
+-					crsminl_th = crsminlG_th_rev6;
+-					crsminu_th = crsminuG_th_rev6;
+-					rssi_gain = rssi_gain_default;
+-				}
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				lna1_gain_db = lna1G_gain_db_rev5;
+-				lna2_gain_db = lna2G_gain_db_rev5;
+-				if (pi->sh->boardflags & BFL_EXTLNA) {
+-
+-					rfseq_init_gain =
+-					    rfseqG_init_gain_rev5_elna;
+-					init_gaincode =
+-					    initG_gaincode_rev5_elna;
+-				} else {
+-					rfseq_init_gain = rfseqG_init_gain_rev5;
+-					init_gaincode = initG_gaincode_rev5;
+-				}
+-				clip1hi_gaincode = clip1hiG_gaincode_rev5;
+-				switch (triso) {
+-				case 0:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[0];
+-					break;
+-				case 1:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[1];
+-					break;
+-				case 2:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[2];
+-					break;
+-				case 3:
+-
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[3];
+-					break;
+-				case 4:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[4];
+-					break;
+-				case 5:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[5];
+-					break;
+-				case 6:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[6];
+-					break;
+-				case 7:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[7];
+-					break;
+-				default:
+-					clip1lo_gaincode =
+-					    clip1loG_gaincode_rev5[3];
+-					break;
+-				}
+-				nbclip_th = nbclipG_th_rev5;
+-				w1clip_th = w1clipG_th_rev5;
+-				crsmin_th = crsminG_th_rev5;
+-				crsminl_th = crsminlG_th_rev5;
+-				crsminu_th = crsminuG_th_rev5;
+-				rssi_gain = rssi_gain_default;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-				lna1_gain_db = lna1G_gain_db_rev4;
+-				lna2_gain_db = lna2G_gain_db;
+-				rfseq_init_gain = rfseqG_init_gain_rev4;
+-				init_gaincode = initG_gaincode_rev4;
+-				clip1hi_gaincode = clip1hiG_gaincode_rev4;
+-				clip1lo_gaincode = clip1loG_gaincode;
+-				nbclip_th = nbclipG_th_rev4;
+-				w1clip_th = w1clipG_th;
+-				crsmin_th = crsminG_th;
+-				crsminl_th = crsminlG_th;
+-				crsminu_th = crsminuG_th;
+-				rssi_gain = rssi_gain_default;
+-			} else {
+-				lna1_gain_db = lna1G_gain_db;
+-				lna2_gain_db = lna2G_gain_db;
+-				rfseq_init_gain = rfseqG_init_gain;
+-				init_gaincode = initG_gaincode;
+-				clip1hi_gaincode = clip1hiG_gaincode;
+-				clip1lo_gaincode = clip1loG_gaincode;
+-				nbclip_th = nbclipG_th;
+-				w1clip_th = w1clipG_th;
+-				crsmin_th = crsminG_th;
+-				crsminl_th = crsminlG_th;
+-				crsminu_th = crsminuG_th;
+-				rssi_gain = rssi_gain_default;
+-			}
+-			tia_gain_db = tiaG_gain_db;
+-			tia_gainbits = tiaG_gainbits;
+-			clip1md_gaincode = clip1mdG_gaincode;
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-				lna1_gain_db = lna1A_gain_db_rev6;
+-				lna2_gain_db = lna2A_gain_db_rev6;
+-				tia_gain_db = tiaA_gain_db_rev6;
+-				tia_gainbits = tiaA_gainbits_rev6;
+-				rfseq_init_gain = rfseqA_init_gain_rev6;
+-				init_gaincode = initA_gaincode_rev6;
+-				clip1hi_gaincode = clip1hiA_gaincode_rev6;
+-				clip1md_gaincode = clip1mdA_gaincode_rev6;
+-				clip1lo_gaincode = clip1loA_gaincode_rev6;
+-				crsmin_th = crsminA_th_rev6;
+-				crsminl_th = crsminlA_th_rev6;
+-				if ((pi->pubpi.radiorev == 11) &&
+-				    (CHSPEC_IS40(pi->radio_chanspec) == 0)) {
+-					crsminu_th = crsminuA_th_rev6_224B0;
+-				} else {
+-					crsminu_th = crsminuA_th_rev6;
+-				}
+-				nbclip_th = nbclipA_th_rev6;
+-				rssi_gain = rssiA_gain_rev6;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-				lna1_gain_db = lna1A_gain_db_rev5;
+-				lna2_gain_db = lna2A_gain_db_rev5;
+-				tia_gain_db = tiaA_gain_db_rev5;
+-				tia_gainbits = tiaA_gainbits_rev5;
+-				rfseq_init_gain = rfseqA_init_gain_rev5;
+-				init_gaincode = initA_gaincode_rev5;
+-				clip1hi_gaincode = clip1hiA_gaincode_rev5;
+-				clip1md_gaincode = clip1mdA_gaincode_rev5;
+-				clip1lo_gaincode = clip1loA_gaincode_rev5;
+-				crsmin_th = crsminA_th_rev5;
+-				crsminl_th = crsminlA_th_rev5;
+-				crsminu_th = crsminuA_th_rev5;
+-				nbclip_th = nbclipA_th_rev5;
+-				rssi_gain = rssiA_gain_rev5;
+-			} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-				lna1_gain_db = lna1A_gain_db_rev4;
+-				lna2_gain_db = lna2A_gain_db_rev4;
+-				tia_gain_db = tiaA_gain_db_rev4;
+-				tia_gainbits = tiaA_gainbits_rev4;
+-				if (pi->sh->boardflags & BFL_EXTLNA_5GHz) {
+-
+-					rfseq_init_gain =
+-					    rfseqA_init_gain_rev4_elna;
+-					init_gaincode =
+-					    initA_gaincode_rev4_elna;
+-				} else {
+-					rfseq_init_gain = rfseqA_init_gain_rev4;
+-					init_gaincode = initA_gaincode_rev4;
+-				}
+-				clip1hi_gaincode = clip1hiA_gaincode_rev4;
+-				clip1md_gaincode = clip1mdA_gaincode_rev4;
+-				clip1lo_gaincode = clip1loA_gaincode_rev4;
+-				crsmin_th = crsminA_th_rev4;
+-				crsminl_th = crsminlA_th_rev4;
+-				crsminu_th = crsminuA_th_rev4;
+-				nbclip_th = nbclipA_th_rev4;
+-				rssi_gain = rssi_gain_default;
+-			} else {
+-				lna1_gain_db = lna1A_gain_db;
+-				lna2_gain_db = lna2A_gain_db;
+-				tia_gain_db = tiaA_gain_db;
+-				tia_gainbits = tiaA_gainbits;
+-				rfseq_init_gain = rfseqA_init_gain;
+-				init_gaincode = initA_gaincode;
+-				clip1hi_gaincode = clip1hiA_gaincode;
+-				clip1md_gaincode = clip1mdA_gaincode;
+-				clip1lo_gaincode = clip1loA_gaincode;
+-				crsmin_th = crsminA_th;
+-				crsminl_th = crsminlA_th;
+-				crsminu_th = crsminuA_th;
+-				nbclip_th = nbclipA_th;
+-				rssi_gain = rssi_gain_default;
+-			}
+-			w1clip_th = w1clipA_th;
+-		}
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+-				 RADIO_2056_RX0), 0x17);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAG1_IDAC |
+-				 RADIO_2056_RX1), 0x17);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0),
+-				0xf0);
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1),
+-				0xf0);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0),
+-				0x0);
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1),
+-				0x0);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0),
+-				rssi_gain);
+-		write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1),
+-				rssi_gain);
+-
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+-				 RADIO_2056_RX0), 0x17);
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_BIASPOLE_LNAA1_IDAC |
+-				 RADIO_2056_RX1), 0x17);
+-
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0),
+-				0xFF);
+-		write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1),
+-				0xFF);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8,
+-					 8, lna1_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8,
+-					 8, lna1_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+-					 8, lna2_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+-					 8, lna2_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20,
+-					 8, tia_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20,
+-					 8, tia_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20,
+-					 8, tia_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20,
+-					 8, tia_gainbits);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40,
+-					 8, &lpf_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40,
+-					 8, &lpf_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40,
+-					 8, &lpf_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40,
+-					 8, &lpf_gainbits);
+-
+-		write_phy_reg(pi, 0x20, init_gaincode);
+-		write_phy_reg(pi, 0x2a7, init_gaincode);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 pi->pubpi.phy_corenum, 0x106, 16,
+-					 rfseq_init_gain);
+-
+-		write_phy_reg(pi, 0x22, clip1hi_gaincode);
+-		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+-
+-		write_phy_reg(pi, 0x24, clip1md_gaincode);
+-		write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+-
+-		write_phy_reg(pi, 0x37, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+-
+-		mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0));
+-		mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+-
+-		write_phy_reg(pi, 0x2b, nbclip_th);
+-		write_phy_reg(pi, 0x41, nbclip_th);
+-
+-		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0));
+-		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0));
+-
+-		write_phy_reg(pi, 0x150, 0x809c);
+-
+-	} else {
+-
+-		mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-		mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-		write_phy_reg(pi, 0x2b, 0x84);
+-		write_phy_reg(pi, 0x41, 0x84);
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			write_phy_reg(pi, 0x6b, 0x2b);
+-			write_phy_reg(pi, 0x6c, 0x2b);
+-			write_phy_reg(pi, 0x6d, 0x9);
+-			write_phy_reg(pi, 0x6e, 0x9);
+-		}
+-
+-		w1th = NPHY_RSSICAL_W1_TARGET - 4;
+-		mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0));
+-		mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0));
+-
+-			mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0));
+-			mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0));
+-		}
+-
+-		write_phy_reg(pi, 0x150, 0x809c);
+-
+-		if (pi->nphy_gain_boost)
+-			if ((CHSPEC_IS2G(pi->radio_chanspec)) &&
+-			    (CHSPEC_IS40(pi->radio_chanspec)))
+-				hpf_code = 4;
+-			else
+-				hpf_code = 5;
+-		else if (CHSPEC_IS40(pi->radio_chanspec))
+-			hpf_code = 6;
+-		else
+-			hpf_code = 7;
+-
+-		mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7));
+-		mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7));
+-
+-		for (ctr = 0; ctr < 4; ctr++) {
+-			regval[ctr] = (hpf_code << 8) | 0x7c;
+-		}
+-		wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+-
+-		wlc_phy_adjust_lnagaintbl_nphy(pi);
+-
+-		if (pi->nphy_elna_gain_config) {
+-			regval[0] = 0;
+-			regval[1] = 1;
+-			regval[2] = 1;
+-			regval[3] = 1;
+-			wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval);
+-
+-			for (ctr = 0; ctr < 4; ctr++) {
+-				regval[ctr] = (hpf_code << 8) | 0x74;
+-			}
+-			wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval);
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2)) {
+-			for (ctr = 0; ctr < 21; ctr++) {
+-				regval[ctr] = 3 * ctr;
+-			}
+-			wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval);
+-
+-			for (ctr = 0; ctr < 21; ctr++) {
+-				regval[ctr] = (u16) ctr;
+-			}
+-			wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval);
+-			wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval);
+-		}
+-
+-		wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU,
+-				       rfseq_updategainu_events,
+-				       rfseq_updategainu_dlys,
+-				       sizeof(rfseq_updategainu_events) /
+-				       sizeof(rfseq_updategainu_events[0]));
+-
+-		mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8));
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec))
+-			mod_phy_reg(pi,
+-				    (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES),
+-				    0x7f, 0x4);
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi)
+-{
+-	s8 lna1_gain_db[] = { 8, 13, 17, 22 };
+-	s8 lna2_gain_db[] = { -2, 7, 11, 15 };
+-	s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 };
+-	s8 tia_gainbits[] = {
+-		0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+-
+-	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-	mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+-
+-	mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0));
+-	mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0));
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8,
+-				 lna1_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8,
+-				 lna1_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8,
+-				 lna2_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8,
+-				 lna2_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+-				 tia_gain_db);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+-				 tia_gain_db);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+-				 tia_gainbits);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+-				 tia_gainbits);
+-
+-	write_phy_reg(pi, 0x37, 0x74);
+-	write_phy_reg(pi, 0x2ad, 0x74);
+-	write_phy_reg(pi, 0x38, 0x18);
+-	write_phy_reg(pi, 0x2ae, 0x18);
+-
+-	write_phy_reg(pi, 0x2b, 0xe8);
+-	write_phy_reg(pi, 0x41, 0xe8);
+-
+-	if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0));
+-	} else {
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0));
+-	}
+-}
+-
+-static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi)
+-{
+-	u16 currband;
+-	s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
+-	s8 *lna1_gain_db = NULL;
+-	s8 *lna1_gain_db_2 = NULL;
+-	s8 *lna2_gain_db = NULL;
+-	s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
+-	s8 *tia_gain_db;
+-	s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
+-	s8 *tia_gainbits;
+-	u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
+-	u16 *rfseq_init_gain;
+-	u16 init_gaincode;
+-	u16 clip1hi_gaincode;
+-	u16 clip1md_gaincode = 0;
+-	u16 clip1md_gaincode_B;
+-	u16 clip1lo_gaincode;
+-	u16 clip1lo_gaincode_B;
+-	u8 crsminl_th = 0;
+-	u8 crsminu_th;
+-	u16 nbclip_th = 0;
+-	u8 w1clip_th;
+-	u16 freq;
+-	s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0;
+-	u8 chg_nbclip_th = 0;
+-
+-	mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13));
+-	mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13));
+-
+-	currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-	if (currband == 0) {
+-
+-		lna1_gain_db = lna1G_gain_db_rev7;
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+-					 lna1_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+-					 lna1_gain_db);
+-
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0));
+-
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0));
+-			mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0));
+-		}
+-
+-		mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-			mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0));
+-			mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0));
+-		}
+-	} else {
+-
+-		init_gaincode = 0x9e;
+-		clip1hi_gaincode = 0x9e;
+-		clip1md_gaincode_B = 0x24;
+-		clip1lo_gaincode = 0x8a;
+-		clip1lo_gaincode_B = 8;
+-		rfseq_init_gain = rfseqA_init_gain_rev7;
+-
+-		tia_gain_db = tiaA_gain_db_rev7;
+-		tia_gainbits = tiaA_gainbits_rev7;
+-
+-		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-			w1clip_th = 25;
+-			clip1md_gaincode = 0x82;
+-
+-			if ((freq <= 5080) || (freq == 5825)) {
+-
+-				s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					11, 17, 22, 25 };
+-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+-
+-				crsminu_th = 0x3e;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			} else if ((freq >= 5500) && (freq <= 5700)) {
+-
+-				s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					12, 18, 22, 26 };
+-				s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
+-
+-				crsminu_th = 0x45;
+-				clip1md_gaincode_B = 0x14;
+-				nbclip_th = 0xff;
+-				chg_nbclip_th = 1;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			} else {
+-
+-				s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
+-				s8 lna1A_gain_db_2_rev7[] = {
+-					12, 18, 22, 26 };
+-				s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
+-
+-				crsminu_th = 0x41;
+-				lna1_gain_db = lna1A_gain_db_rev7;
+-				lna1_gain_db_2 = lna1A_gain_db_2_rev7;
+-				lna2_gain_db = lna2A_gain_db_rev7;
+-			}
+-
+-			if (freq <= 4920) {
+-				nvar_baseline_offset0 = 5;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 4920) && (freq <= 5320)) {
+-				nvar_baseline_offset0 = 3;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 5320) && (freq <= 5700)) {
+-				nvar_baseline_offset0 = 3;
+-				nvar_baseline_offset1 = 2;
+-			} else {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 0;
+-			}
+-		} else {
+-
+-			crsminu_th = 0x3a;
+-			crsminl_th = 0x3a;
+-			w1clip_th = 20;
+-
+-			if ((freq >= 4920) && (freq <= 5320)) {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 5;
+-			} else if ((freq > 5320) && (freq <= 5550)) {
+-				nvar_baseline_offset0 = 4;
+-				nvar_baseline_offset1 = 2;
+-			} else {
+-				nvar_baseline_offset0 = 5;
+-				nvar_baseline_offset1 = 3;
+-			}
+-		}
+-
+-		write_phy_reg(pi, 0x20, init_gaincode);
+-		write_phy_reg(pi, 0x2a7, init_gaincode);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-					 pi->pubpi.phy_corenum, 0x106, 16,
+-					 rfseq_init_gain);
+-
+-		write_phy_reg(pi, 0x22, clip1hi_gaincode);
+-		write_phy_reg(pi, 0x2a9, clip1hi_gaincode);
+-
+-		write_phy_reg(pi, 0x36, clip1md_gaincode_B);
+-		write_phy_reg(pi, 0x2ac, clip1md_gaincode_B);
+-
+-		write_phy_reg(pi, 0x37, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x2ad, clip1lo_gaincode);
+-		write_phy_reg(pi, 0x38, clip1lo_gaincode_B);
+-		write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8,
+-					 tia_gain_db);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8,
+-					 tia_gain_db);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8,
+-					 tia_gainbits);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8,
+-					 tia_gainbits);
+-
+-		mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0));
+-
+-		if (chg_nbclip_th == 1) {
+-			write_phy_reg(pi, 0x2b, nbclip_th);
+-			write_phy_reg(pi, 0x41, nbclip_th);
+-		}
+-
+-		mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0));
+-		mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0));
+-
+-		mod_phy_reg(pi, 0x2e4,
+-			    (0x3f << 0), (nvar_baseline_offset0 << 0));
+-
+-		mod_phy_reg(pi, 0x2e4,
+-			    (0x3f << 6), (nvar_baseline_offset1 << 6));
+-
+-		if (CHSPEC_IS20(pi->radio_chanspec)) {
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8,
+-						 lna1_gain_db);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8,
+-						 lna1_gain_db_2);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10,
+-						 8, lna2_gain_db);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10,
+-						 8, lna2_gain_db);
+-
+-			write_phy_reg(pi, 0x24, clip1md_gaincode);
+-			write_phy_reg(pi, 0x2ab, clip1md_gaincode);
+-		} else {
+-			mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0));
+-		}
+-
+-	}
+-
+-}
+-
+-static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi)
+-{
+-	uint core;
+-	int ctr;
+-	s16 gain_delta[2];
+-	u8 curr_channel;
+-	u16 minmax_gain[2];
+-	u16 regval[4];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (pi->nphy_gain_boost) {
+-		if ((CHSPEC_IS2G(pi->radio_chanspec))) {
+-
+-			gain_delta[0] = 6;
+-			gain_delta[1] = 6;
+-		} else {
+-
+-			curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-			gain_delta[0] =
+-			    (s16)
+-			    PHY_HW_ROUND(((nphy_lnagain_est0[0] *
+-					   curr_channel) +
+-					  nphy_lnagain_est0[1]), 13);
+-			gain_delta[1] =
+-			    (s16)
+-			    PHY_HW_ROUND(((nphy_lnagain_est1[0] *
+-					   curr_channel) +
+-					  nphy_lnagain_est1[1]), 13);
+-		}
+-	} else {
+-
+-		gain_delta[0] = 0;
+-		gain_delta[1] = 0;
+-	}
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (pi->nphy_elna_gain_config) {
+-
+-			regval[0] = nphy_def_lnagains[2] + gain_delta[core];
+-			regval[1] = nphy_def_lnagains[3] + gain_delta[core];
+-			regval[2] = nphy_def_lnagains[3] + gain_delta[core];
+-			regval[3] = nphy_def_lnagains[3] + gain_delta[core];
+-		} else {
+-			for (ctr = 0; ctr < 4; ctr++) {
+-				regval[ctr] =
+-				    nphy_def_lnagains[ctr] + gain_delta[core];
+-			}
+-		}
+-		wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval);
+-
+-		minmax_gain[core] =
+-		    (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4);
+-	}
+-
+-	mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0));
+-	mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0));
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on)
+-{
+-	if (on) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (!pi->radio_is_on) {
+-				wlc_phy_radio_preinit_205x(pi);
+-				wlc_phy_radio_init_2057(pi);
+-				wlc_phy_radio_postinit_2057(pi);
+-			}
+-
+-			wlc_phy_chanspec_set((wlc_phy_t *) pi,
+-					     pi->radio_chanspec);
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_radio_preinit_205x(pi);
+-			wlc_phy_radio_init_2056(pi);
+-			wlc_phy_radio_postinit_2056(pi);
+-
+-			wlc_phy_chanspec_set((wlc_phy_t *) pi,
+-					     pi->radio_chanspec);
+-		} else {
+-			wlc_phy_radio_preinit_2055(pi);
+-			wlc_phy_radio_init_2055(pi);
+-			wlc_phy_radio_postinit_2055(pi);
+-		}
+-
+-		pi->radio_is_on = true;
+-
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)
+-		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-			mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADA_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAA_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_TX_MIXA_BOOST_TUNE |
+-				      RADIO_2056_TX0, 0xf0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_MIXG_BOOST_TUNE |
+-					RADIO_2056_TX0, 0);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADA_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PADG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAA_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_PGAG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_TX_MIXA_BOOST_TUNE |
+-				      RADIO_2056_TX1, 0xf0, 0);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_MIXG_BOOST_TUNE |
+-					RADIO_2056_TX1, 0);
+-
+-			pi->radio_is_on = false;
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-			pi->radio_is_on = false;
+-		}
+-
+-	}
+-}
+-
+-static void wlc_phy_radio_preinit_2055(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE);
+-	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE);
+-
+-	or_phy_reg(pi, 0x78, RFCC_POR_FORCE);
+-}
+-
+-static void wlc_phy_radio_init_2055(phy_info_t *pi)
+-{
+-	wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE);
+-}
+-
+-static void wlc_phy_radio_postinit_2055(phy_info_t *pi)
+-{
+-
+-	and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1,
+-		      ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK));
+-
+-	if (((pi->sh->sromrev >= 4)
+-	     && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS))
+-	    || ((pi->sh->sromrev < 4))) {
+-		and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F);
+-		and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C);
+-	write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C);
+-
+-	and_radio_reg(pi, RADIO_2055_CAL_MISC,
+-		      ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N));
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE);
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N);
+-
+-	udelay(1000);
+-
+-	or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START);
+-
+-	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+-		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
+-
+-	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+-		 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
+-		 "HW error: radio calibration1\n"))
+-		return;
+-
+-	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
+-		      ~(RADIO_2055_CAL_LPO_ENABLE));
+-
+-	wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83);
+-
+-	mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST,
+-		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+-	mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST,
+-		      RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE);
+-	if (pi->nphy_gain_boost) {
+-		and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+-			      ~(RADIO_2055_GAINBST_DISABLE));
+-		and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+-			      ~(RADIO_2055_GAINBST_DISABLE));
+-	} else {
+-		or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1,
+-			     RADIO_2055_GAINBST_DISABLE);
+-		or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1,
+-			     RADIO_2055_GAINBST_DISABLE);
+-	}
+-
+-	udelay(2);
+-}
+-
+-static void wlc_phy_radio_preinit_205x(phy_info_t *pi)
+-{
+-
+-	and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU);
+-	and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE);
+-
+-	or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE);
+-	or_phy_reg(pi, 0x78, RFCC_CHIP0_PU);
+-
+-}
+-
+-static void wlc_phy_radio_init_2056(phy_info_t *pi)
+-{
+-	radio_regs_t *regs_SYN_2056_ptr = NULL;
+-	radio_regs_t *regs_TX_2056_ptr = NULL;
+-	radio_regs_t *regs_RX_2056_ptr = NULL;
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-		regs_SYN_2056_ptr = regs_SYN_2056;
+-		regs_TX_2056_ptr = regs_TX_2056;
+-		regs_RX_2056_ptr = regs_RX_2056;
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-		regs_SYN_2056_ptr = regs_SYN_2056_A1;
+-		regs_TX_2056_ptr = regs_TX_2056_A1;
+-		regs_RX_2056_ptr = regs_RX_2056_A1;
+-	} else {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+-			regs_TX_2056_ptr = regs_TX_2056_rev5;
+-			regs_RX_2056_ptr = regs_RX_2056_rev5;
+-			break;
+-
+-		case 6:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+-			regs_TX_2056_ptr = regs_TX_2056_rev6;
+-			regs_RX_2056_ptr = regs_RX_2056_rev6;
+-			break;
+-
+-		case 7:
+-		case 9:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+-			regs_TX_2056_ptr = regs_TX_2056_rev7;
+-			regs_RX_2056_ptr = regs_RX_2056_rev7;
+-			break;
+-
+-		case 8:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+-			regs_TX_2056_ptr = regs_TX_2056_rev8;
+-			regs_RX_2056_ptr = regs_RX_2056_rev8;
+-			break;
+-
+-		case 11:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+-			regs_TX_2056_ptr = regs_TX_2056_rev11;
+-			regs_RX_2056_ptr = regs_RX_2056_rev11;
+-			break;
+-
+-		default:
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN);
+-
+-	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0);
+-
+-	wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1);
+-
+-	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0);
+-
+-	wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1);
+-}
+-
+-static void wlc_phy_radio_postinit_2056(phy_info_t *pi)
+-{
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb);
+-
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2);
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2);
+-	udelay(1000);
+-	mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0);
+-
+-	if ((pi->sh->boardflags2 & BFL2_LEGACY)
+-	    || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) {
+-
+-		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0);
+-	} else {
+-
+-		mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0);
+-
+-	if (pi->phy_init_por) {
+-		wlc_phy_radio205x_rcal(pi);
+-	}
+-}
+-
+-static void wlc_phy_radio_init_2057(phy_info_t *pi)
+-{
+-	radio_20xx_regs_t *regs_2057_ptr = NULL;
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-		regs_2057_ptr = regs_2057_rev4;
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 8)
+-		   || NREV_IS(pi->pubpi.phy_rev, 9)) {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-
+-			if (pi->pubpi.radiover == 0x0) {
+-
+-				regs_2057_ptr = regs_2057_rev5;
+-
+-			} else if (pi->pubpi.radiover == 0x1) {
+-
+-				regs_2057_ptr = regs_2057_rev5v1;
+-			} else {
+-				break;
+-			}
+-
+-		case 7:
+-
+-			regs_2057_ptr = regs_2057_rev7;
+-			break;
+-
+-		case 8:
+-
+-			regs_2057_ptr = regs_2057_rev8;
+-			break;
+-
+-		default:
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
+-}
+-
+-static void wlc_phy_radio_postinit_2057(phy_info_t *pi)
+-{
+-
+-	mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1);
+-
+-	if (pi->sh->chip == !BCM6362_CHIP_ID) {
+-
+-		mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78);
+-	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80);
+-	mdelay(2);
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0);
+-	mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0);
+-
+-	if (pi->phy_init_por) {
+-		wlc_phy_radio205x_rcal(pi);
+-		wlc_phy_radio2057_rccal(pi);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0);
+-}
+-
+-static bool
+-wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f,
+-		       chan_info_nphy_radio2057_t **t0,
+-		       chan_info_nphy_radio205x_t **t1,
+-		       chan_info_nphy_radio2057_rev5_t **t2,
+-		       chan_info_nphy_2055_t **t3)
+-{
+-	uint i;
+-	chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL;
+-	chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL;
+-	u32 tbl_len = 0;
+-
+-	int freq = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-			chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4);
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 8)
+-			   || NREV_IS(pi->pubpi.phy_rev, 9)) {
+-			switch (pi->pubpi.radiorev) {
+-
+-			case 5:
+-
+-				if (pi->pubpi.radiover == 0x0) {
+-
+-					chan_info_tbl_p_2 =
+-					    chan_info_nphyrev8_2057_rev5;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (chan_info_nphyrev8_2057_rev5);
+-
+-				} else if (pi->pubpi.radiover == 0x1) {
+-
+-					chan_info_tbl_p_2 =
+-					    chan_info_nphyrev9_2057_rev5v1;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (chan_info_nphyrev9_2057_rev5v1);
+-
+-				}
+-				break;
+-
+-			case 7:
+-				chan_info_tbl_p_0 =
+-				    chan_info_nphyrev8_2057_rev7;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev8_2057_rev7);
+-				break;
+-
+-			case 8:
+-				chan_info_tbl_p_0 =
+-				    chan_info_nphyrev8_2057_rev8;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
+-				break;
+-
+-			default:
+-				if (NORADIO_ENAB(pi->pubpi)) {
+-					goto fail;
+-				}
+-				break;
+-			}
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 16)) {
+-
+-			chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8);
+-		} else {
+-			goto fail;
+-		}
+-
+-		for (i = 0; i < tbl_len; i++) {
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				if (chan_info_tbl_p_2[i].chan == channel)
+-					break;
+-			} else {
+-
+-				if (chan_info_tbl_p_0[i].chan == channel)
+-					break;
+-			}
+-		}
+-
+-		if (i >= tbl_len) {
+-			goto fail;
+-		}
+-		if (pi->pubpi.radiorev == 5) {
+-			*t2 = &chan_info_tbl_p_2[i];
+-			freq = chan_info_tbl_p_2[i].freq;
+-		} else {
+-			*t0 = &chan_info_tbl_p_0[i];
+-			freq = chan_info_tbl_p_0[i].freq;
+-		}
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-			chan_info_tbl_p_1 = chan_info_nphyrev3_2056;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056);
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 4)) {
+-			chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1;
+-			tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1);
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)
+-			   || NREV_IS(pi->pubpi.phy_rev, 6)) {
+-			switch (pi->pubpi.radiorev) {
+-			case 5:
+-				chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5);
+-				break;
+-			case 6:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6);
+-				break;
+-			case 7:
+-			case 9:
+-				chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7;
+-				tbl_len =
+-				    ARRAY_SIZE(chan_info_nphyrev5n6_2056v7);
+-				break;
+-			case 8:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8);
+-				break;
+-			case 11:
+-				chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11;
+-				tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11);
+-				break;
+-			default:
+-				if (NORADIO_ENAB(pi->pubpi)) {
+-					goto fail;
+-				}
+-				break;
+-			}
+-		}
+-
+-		for (i = 0; i < tbl_len; i++) {
+-			if (chan_info_tbl_p_1[i].chan == channel)
+-				break;
+-		}
+-
+-		if (i >= tbl_len) {
+-			goto fail;
+-		}
+-		*t1 = &chan_info_tbl_p_1[i];
+-		freq = chan_info_tbl_p_1[i].freq;
+-
+-	} else {
+-		for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++)
+-			if (chan_info_nphy_2055[i].chan == channel)
+-				break;
+-
+-		if (i >= ARRAY_SIZE(chan_info_nphy_2055)) {
+-			goto fail;
+-		}
+-		*t3 = &chan_info_nphy_2055[i];
+-		freq = chan_info_nphy_2055[i].freq;
+-	}
+-
+-	*f = freq;
+-	return true;
+-
+- fail:
+-	*f = WL_CHAN_FREQ_RANGE_2G;
+-	return false;
+-}
+-
+-u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel)
+-{
+-	int freq;
+-	chan_info_nphy_radio2057_t *t0 = NULL;
+-	chan_info_nphy_radio205x_t *t1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+-	chan_info_nphy_2055_t *t3 = NULL;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return WL_CHAN_FREQ_RANGE_2G;
+-
+-	if (channel == 0)
+-		channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-
+-	wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec))
+-		return WL_CHAN_FREQ_RANGE_2G;
+-
+-	if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) {
+-		return WL_CHAN_FREQ_RANGE_5GL;
+-	} else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) {
+-		return WL_CHAN_FREQ_RANGE_5GM;
+-	} else {
+-		return WL_CHAN_FREQ_RANGE_5GH;
+-	}
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci)
+-{
+-
+-	write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref);
+-	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0);
+-	write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2);
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1);
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2);
+-	write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf);
+-	write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1);
+-	write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE,
+-			ci->RF_core1_lgbuf_a_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE,
+-			ci->RF_core1_lgbuf_g_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1);
+-	write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN,
+-			ci->RF_core1_tx_pga_pad_tn);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM,
+-			ci->RF_core1_tx_mx_bgtrim);
+-	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE,
+-			ci->RF_core2_lgbuf_a_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE,
+-			ci->RF_core2_lgbuf_g_tune);
+-	write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN,
+-			ci->RF_core2_tx_pga_pad_tn);
+-	write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM,
+-			ci->RF_core2_tx_mx_bgtrim);
+-
+-	udelay(50);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05);
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45);
+-
+-	WLC_PHY_WAR_PR51571(pi);
+-
+-	write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65);
+-
+-	udelay(300);
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2056_setup(phy_info_t *pi,
+-				 const chan_info_nphy_radio205x_t *ci)
+-{
+-	radio_regs_t *regs_SYN_2056_ptr = NULL;
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_vcocal1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_vcocal2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_refdiv);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_mmd2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_mmd1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter1);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter2);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter3);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter4);
+-	write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN,
+-			ci->RF_SYN_pll_loopfilter5);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr27);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr28);
+-	write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN,
+-			ci->RF_SYN_reserved_addr29);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_VCOBUF1);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_MIXER2);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_BUF3);
+-	write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN,
+-			ci->RF_SYN_logen_BUF4);
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0,
+-			ci->RF_RX0_lnaa_tune);
+-	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0,
+-			ci->RF_RX0_lnag_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_intpaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_intpag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pada_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_padg_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pgaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_pgag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_mixa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0,
+-			ci->RF_TX0_mixg_boost_tune);
+-
+-	write_radio_reg(pi,
+-			RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1,
+-			ci->RF_RX1_lnaa_tune);
+-	write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1,
+-			ci->RF_RX1_lnag_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_intpaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_intpag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pada_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_padg_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pgaa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_pgag_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_mixa_boost_tune);
+-	write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1,
+-			ci->RF_TX1_mixg_boost_tune);
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 3))
+-		regs_SYN_2056_ptr = regs_SYN_2056;
+-	else if (NREV_IS(pi->pubpi.phy_rev, 4))
+-		regs_SYN_2056_ptr = regs_SYN_2056_A1;
+-	else {
+-		switch (pi->pubpi.radiorev) {
+-		case 5:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev5;
+-			break;
+-		case 6:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev6;
+-			break;
+-		case 7:
+-		case 9:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev7;
+-			break;
+-		case 8:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev8;
+-			break;
+-		case 11:
+-			regs_SYN_2056_ptr = regs_SYN_2056_rev11;
+-			break;
+-		}
+-	}
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-				RADIO_2056_SYN,
+-				(u16) regs_SYN_2056_ptr[0x49 - 2].init_g);
+-	} else {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-				RADIO_2056_SYN,
+-				(u16) regs_SYN_2056_ptr[0x49 - 2].init_a);
+-	}
+-
+-	if (pi->sh->boardflags2 & BFL2_GPLL_WAR) {
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+-					RADIO_2056_SYN, 0x1f);
+-
+-			if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-			    (pi->sh->chip == BCM47162_CHIP_ID)) {
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-						RADIO_2056_SYN, 0x14);
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_CP2 |
+-						RADIO_2056_SYN, 0x00);
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-						RADIO_2056_SYN, 0xb);
+-				write_radio_reg(pi,
+-						RADIO_2056_SYN_PLL_CP2 |
+-						RADIO_2056_SYN, 0x14);
+-			}
+-		}
+-	}
+-
+-	if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) &&
+-	    (CHSPEC_IS2G(pi->radio_chanspec))) {
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN,
+-				0x1f);
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN,
+-				0x1f);
+-		write_radio_reg(pi,
+-				RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN,
+-				0xb);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN,
+-				0x20);
+-	}
+-
+-	if (pi->sh->boardflags2 & BFL2_APLL_WAR) {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 |
+-					RADIO_2056_SYN, 0x1f);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 |
+-					RADIO_2056_SYN, 0x5);
+-			write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 |
+-					RADIO_2056_SYN, 0xc);
+-		}
+-	}
+-
+-	if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) {
+-		u16 pag_boost_tune;
+-		u16 padg_boost_tune;
+-		u16 pgag_boost_tune;
+-		u16 mixg_boost_tune;
+-		u16 bias, cascbias;
+-		uint core;
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PADG_IDAC, 0xcc);
+-
+-				if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-				    (pi->sh->chip ==
+-				     BCM47162_CHIP_ID)) {
+-					bias = 0x40;
+-					cascbias = 0x45;
+-					pag_boost_tune = 0x5;
+-					pgag_boost_tune = 0x33;
+-					padg_boost_tune = 0x77;
+-					mixg_boost_tune = 0x55;
+-				} else {
+-					bias = 0x25;
+-					cascbias = 0x20;
+-
+-					if ((pi->sh->chip ==
+-					     BCM43224_CHIP_ID)
+-					    || (pi->sh->chip ==
+-						BCM43225_CHIP_ID)
+-					    || (pi->sh->chip ==
+-						BCM43421_CHIP_ID)) {
+-						if (pi->sh->chippkg ==
+-						    BCM43224_FAB_SMIC) {
+-							bias = 0x2a;
+-							cascbias = 0x38;
+-						}
+-					}
+-
+-					pag_boost_tune = 0x4;
+-					pgag_boost_tune = 0x03;
+-					padg_boost_tune = 0x77;
+-					mixg_boost_tune = 0x65;
+-				}
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IMAIN_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IAUX_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_CASCBIAS, cascbias);
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_BOOST_TUNE,
+-						 pag_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PGAG_BOOST_TUNE,
+-						 pgag_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 PADG_BOOST_TUNE,
+-						 padg_boost_tune);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 MIXG_BOOST_TUNE,
+-						 mixg_boost_tune);
+-			} else {
+-
+-				bias = IS40MHZ(pi) ? 0x40 : 0x20;
+-
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IMAIN_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_IAUX_STAT, bias);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_CASCBIAS, 0x30);
+-			}
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1,
+-					 0xee);
+-		}
+-	}
+-
+-	if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6)
+-	    && CHSPEC_IS5G(pi->radio_chanspec)) {
+-		u16 paa_boost_tune;
+-		u16 pada_boost_tune;
+-		u16 pgaa_boost_tune;
+-		u16 mixa_boost_tune;
+-		u16 freq, pabias, cascbias;
+-		uint core;
+-
+-		freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec));
+-
+-		if (freq < 5150) {
+-
+-			paa_boost_tune = 0xa;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xf;
+-			mixa_boost_tune = 0xf;
+-		} else if (freq < 5340) {
+-
+-			paa_boost_tune = 0x8;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xfb;
+-			mixa_boost_tune = 0xf;
+-		} else if (freq < 5650) {
+-
+-			paa_boost_tune = 0x0;
+-			pada_boost_tune = 0x77;
+-			pgaa_boost_tune = 0xb;
+-			mixa_boost_tune = 0xf;
+-		} else {
+-
+-			paa_boost_tune = 0x0;
+-			pada_boost_tune = 0x77;
+-			if (freq != 5825) {
+-				pgaa_boost_tune = -(int)(freq - 18) / 36 + 168;
+-			} else {
+-				pgaa_boost_tune = 6;
+-			}
+-			mixa_boost_tune = 0xf;
+-		}
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_BOOST_TUNE, paa_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PADA_BOOST_TUNE, pada_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PGAA_BOOST_TUNE, pgaa_boost_tune);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 MIXA_BOOST_TUNE, mixa_boost_tune);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 TXSPARE1, 0x30);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PA_SPARE2, 0xee);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 PADA_CASCBIAS, 0x3);
+-
+-			cascbias = 0x30;
+-
+-			if ((pi->sh->chip == BCM43224_CHIP_ID) ||
+-			    (pi->sh->chip == BCM43225_CHIP_ID) ||
+-			    (pi->sh->chip == BCM43421_CHIP_ID)) {
+-				if (pi->sh->chippkg == BCM43224_FAB_SMIC) {
+-					cascbias = 0x35;
+-				}
+-			}
+-
+-			pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias;
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_IAUX_STAT, pabias);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_IMAIN_STAT, pabias);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_CASCBIAS, cascbias);
+-		}
+-	}
+-
+-	udelay(50);
+-
+-	wlc_phy_radio205x_vcocal_nphy(pi);
+-}
+-
+-void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0);
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0);
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04,
+-			      (1 << 2));
+-		mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39);
+-	}
+-
+-	udelay(300);
+-}
+-
+-#define MAX_205x_RCAL_WAITLOOPS 10000
+-
+-static u16 wlc_phy_radio205x_rcal(phy_info_t *pi)
+-{
+-	u16 rcal_reg = 0;
+-	int i;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			and_phy_reg(pi, 0x342, ~(0x1 << 1));
+-
+-			udelay(10);
+-
+-			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1);
+-			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+-				      0x1);
+-		}
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1);
+-
+-		udelay(10);
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3);
+-
+-		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-			rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS);
+-			if (rcal_reg & 0x1) {
+-				break;
+-			}
+-			udelay(100);
+-		}
+-
+-		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+-			 "HW error: radio calib2"))
+-			return 0;
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
+-
+-		rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e;
+-
+-		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0);
+-		if (pi->pubpi.radiorev == 5) {
+-
+-			mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0);
+-			mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2,
+-				      0x0);
+-		}
+-
+-		if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+-
+-			mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c,
+-				      rcal_reg);
+-			mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0,
+-				      rcal_reg << 2);
+-		}
+-
+-	} else if (NREV_IS(pi->pubpi.phy_rev, 3)) {
+-		u16 savereg;
+-
+-		savereg =
+-		    read_radio_reg(pi,
+-				   RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN);
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+-				savereg | 0x7);
+-		udelay(10);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x1);
+-		udelay(10);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x9);
+-
+-		for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-			rcal_reg = read_radio_reg(pi,
+-						  RADIO_2056_SYN_RCAL_CODE_OUT |
+-						  RADIO_2056_SYN);
+-			if (rcal_reg & 0x80) {
+-				break;
+-			}
+-			udelay(100);
+-		}
+-
+-		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+-			 "HW error: radio calib3"))
+-			return 0;
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x1);
+-
+-		rcal_reg =
+-		    read_radio_reg(pi,
+-				   RADIO_2056_SYN_RCAL_CODE_OUT |
+-				   RADIO_2056_SYN);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
+-				0x0);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN,
+-				savereg);
+-
+-		return rcal_reg & 0x1f;
+-	}
+-	return rcal_reg & 0x3e;
+-}
+-
+-static void
+-wlc_phy_chanspec_radio2057_setup(phy_info_t *pi,
+-				 const chan_info_nphy_radio2057_t *ci,
+-				 const chan_info_nphy_radio2057_rev5_t *ci2)
+-{
+-	int coreNum;
+-	u16 txmix2g_tune_boost_pu = 0;
+-	u16 pad2g_tune_pus = 0;
+-
+-	if (pi->pubpi.radiorev == 5) {
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOCAL_COUNTVAL0,
+-				ci2->RF_vcocal_countval0);
+-		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+-				ci2->RF_vcocal_countval1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+-				ci2->RF_rfpll_refmaster_sparextalsize);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-				ci2->RF_rfpll_loopfilter_r1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-				ci2->RF_rfpll_loopfilter_c2);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-				ci2->RF_rfpll_loopfilter_c1);
+-		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC,
+-				ci2->RF_cp_kpd_idac);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1);
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune);
+-		write_radio_reg(pi,
+-				RADIO_2057_LOGEN_MX2G_TUNE,
+-				ci2->RF_logen_mx2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+-				ci2->RF_logen_indbuf2g_tune);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+-				ci2->RF_txmix2g_tune_boost_pu_core0);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-				ci2->RF_pad2g_tune_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+-				ci2->RF_lna2g_tune_core0);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+-				ci2->RF_txmix2g_tune_boost_pu_core1);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-				ci2->RF_pad2g_tune_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+-				ci2->RF_lna2g_tune_core1);
+-
+-	} else {
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_VCOCAL_COUNTVAL0,
+-				ci->RF_vcocal_countval0);
+-		write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1,
+-				ci->RF_vcocal_countval1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE,
+-				ci->RF_rfpll_refmaster_sparextalsize);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-				ci->RF_rfpll_loopfilter_r1);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-				ci->RF_rfpll_loopfilter_c2);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-				ci->RF_rfpll_loopfilter_c1);
+-		write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0);
+-		write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1);
+-		write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune);
+-		write_radio_reg(pi,
+-				RADIO_2057_LOGEN_MX2G_TUNE,
+-				ci->RF_logen_mx2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE,
+-				ci->RF_logen_mx5g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE,
+-				ci->RF_logen_indbuf2g_tune);
+-		write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE,
+-				ci->RF_logen_indbuf5g_tune);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
+-				ci->RF_txmix2g_tune_boost_pu_core0);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-				ci->RF_pad2g_tune_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0,
+-				ci->RF_pga_boost_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0,
+-				ci->RF_txmix5g_boost_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0,
+-				ci->RF_pad5g_tune_misc_pus_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0,
+-				ci->RF_lna2g_tune_core0);
+-		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0,
+-				ci->RF_lna5g_tune_core0);
+-
+-		write_radio_reg(pi,
+-				RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
+-				ci->RF_txmix2g_tune_boost_pu_core1);
+-		write_radio_reg(pi,
+-				RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-				ci->RF_pad2g_tune_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1,
+-				ci->RF_pga_boost_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1,
+-				ci->RF_txmix5g_boost_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1,
+-				ci->RF_pad5g_tune_misc_pus_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1,
+-				ci->RF_lna2g_tune_core1);
+-		write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1,
+-				ci->RF_lna5g_tune_core1);
+-	}
+-
+-	if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) {
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x3f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		} else {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		}
+-	} else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) ||
+-		   (pi->pubpi.radiorev == 8)) {
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1b);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0xa);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0xa);
+-		} else {
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1,
+-					0x1f);
+-			write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1,
+-					0x8);
+-			write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2,
+-					0x8);
+-		}
+-
+-	}
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (PHY_IPA(pi)) {
+-			if (pi->pubpi.radiorev == 3) {
+-				txmix2g_tune_boost_pu = 0x6b;
+-			}
+-
+-			if (pi->pubpi.radiorev == 5)
+-				pad2g_tune_pus = 0x73;
+-
+-		} else {
+-			if (pi->pubpi.radiorev != 5) {
+-				pad2g_tune_pus = 0x3;
+-
+-				txmix2g_tune_boost_pu = 0x61;
+-			}
+-		}
+-
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			if (txmix2g_tune_boost_pu != 0)
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 TXMIX2G_TUNE_BOOST_PU,
+-						 txmix2g_tune_boost_pu);
+-
+-			if (pad2g_tune_pus != 0)
+-				WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum,
+-						 PAD2G_TUNE_PUS,
+-						 pad2g_tune_pus);
+-		}
+-	}
+-
+-	udelay(50);
+-
+-	wlc_phy_radio205x_vcocal_nphy(pi);
+-}
+-
+-static u16 wlc_phy_radio2057_rccal(phy_info_t *pi)
+-{
+-	u16 rccal_valid;
+-	int i;
+-	bool chip43226_6362A0;
+-
+-	chip43226_6362A0 = ((pi->pubpi.radiorev == 3)
+-			    || (pi->pubpi.radiorev == 4)
+-			    || (pi->pubpi.radiorev == 6));
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	rccal_valid = 0;
+-	if (chip43226_6362A0) {
+-		write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73);
+-
+-		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0);
+-	} else {
+-		write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e);
+-		write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99);
+-	}
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55);
+-
+-	for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) {
+-		rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP);
+-		if (rccal_valid & 0x2) {
+-			break;
+-		}
+-		udelay(500);
+-	}
+-
+-	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
+-		return 0;
+-
+-	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
+-
+-	return rccal_valid;
+-}
+-
+-static void
+-wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+-		    CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (!pi->nphy_anarxlpf_adjusted) {
+-				write_radio_reg(pi,
+-						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-						 RADIO_2056_RX0),
+-						((pi->nphy_rccal_value +
+-						  reduction_factr) | 0x80));
+-
+-				pi->nphy_anarxlpf_adjusted = true;
+-			}
+-		} else {
+-			if (pi->nphy_anarxlpf_adjusted) {
+-				write_radio_reg(pi,
+-						(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-						 RADIO_2056_RX0),
+-						(pi->nphy_rccal_value | 0x80));
+-
+-				pi->nphy_anarxlpf_adjusted = false;
+-			}
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf,
+-				 u32 *noise_var_buf)
+-{
+-	int i;
+-	u32 offset;
+-	int tone_id;
+-	int tbllen =
+-	    CHSPEC_IS40(pi->
+-			radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 :
+-	    NPHY_NOISEVAR_TBLLEN20;
+-
+-	if (pi->nphy_noisevars_adjusted) {
+-		for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) {
+-			tone_id = pi->nphy_saved_noisevars.tone_id[i];
+-			offset = (tone_id >= 0) ?
+-			    ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 offset, 32,
+-						 (void *)&pi->
+-						 nphy_saved_noisevars.
+-						 min_noise_vars[i]);
+-		}
+-
+-		pi->nphy_saved_noisevars.bufcount = 0;
+-		pi->nphy_noisevars_adjusted = false;
+-	}
+-
+-	if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) {
+-		pi->nphy_saved_noisevars.bufcount = 0;
+-
+-		for (i = 0; i < ntones; i++) {
+-			tone_id = tone_id_buf[i];
+-			offset = (tone_id >= 0) ?
+-			    ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1);
+-			pi->nphy_saved_noisevars.tone_id[i] = tone_id;
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						offset, 32,
+-						&pi->nphy_saved_noisevars.
+-						min_noise_vars[i]);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1,
+-						 offset, 32,
+-						 (void *)&noise_var_buf[i]);
+-			pi->nphy_saved_noisevars.bufcount++;
+-		}
+-
+-		pi->nphy_noisevars_adjusted = true;
+-	}
+-}
+-
+-static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr)
+-{
+-	u16 regval;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) &&
+-		    CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (!pi->nphy_crsminpwr_adjusted) {
+-				regval = read_phy_reg(pi, 0x27d);
+-				pi->nphy_crsminpwr[0] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x27d, regval);
+-
+-				regval = read_phy_reg(pi, 0x280);
+-				pi->nphy_crsminpwr[1] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x280, regval);
+-
+-				regval = read_phy_reg(pi, 0x283);
+-				pi->nphy_crsminpwr[2] = regval & 0xff;
+-				regval &= 0xff00;
+-				regval |= (u16) minpwr;
+-				write_phy_reg(pi, 0x283, regval);
+-
+-				pi->nphy_crsminpwr_adjusted = true;
+-			}
+-		} else {
+-			if (pi->nphy_crsminpwr_adjusted) {
+-				regval = read_phy_reg(pi, 0x27d);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[0];
+-				write_phy_reg(pi, 0x27d, regval);
+-
+-				regval = read_phy_reg(pi, 0x280);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[1];
+-				write_phy_reg(pi, 0x280, regval);
+-
+-				regval = read_phy_reg(pi, 0x283);
+-				regval &= 0xff00;
+-				regval |= pi->nphy_crsminpwr[2];
+-				write_phy_reg(pi, 0x283, regval);
+-
+-				pi->nphy_crsminpwr_adjusted = false;
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txlpfbw_nphy(phy_info_t *pi)
+-{
+-	u8 tx_lpf_bw = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			tx_lpf_bw = 3;
+-		} else {
+-			tx_lpf_bw = 1;
+-		}
+-
+-		if (PHY_IPA(pi)) {
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				tx_lpf_bw = 5;
+-			} else {
+-				tx_lpf_bw = 4;
+-			}
+-		}
+-		write_phy_reg(pi, 0xe8,
+-			      (tx_lpf_bw << 0) |
+-			      (tx_lpf_bw << 3) |
+-			      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+-
+-		if (PHY_IPA(pi)) {
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				tx_lpf_bw = 4;
+-			} else {
+-				tx_lpf_bw = 1;
+-			}
+-
+-			write_phy_reg(pi, 0xe9,
+-				      (tx_lpf_bw << 0) |
+-				      (tx_lpf_bw << 3) |
+-				      (tx_lpf_bw << 6) | (tx_lpf_bw << 9));
+-		}
+-	}
+-}
+-
+-static void wlc_phy_spurwar_nphy(phy_info_t *pi)
+-{
+-	u16 cur_channel = 0;
+-	int nphy_adj_tone_id_buf[] = { 57, 58 };
+-	u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff };
+-	bool isAdjustNoiseVar = false;
+-	uint numTonesAdjust = 0;
+-	u32 tempval = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-		cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
+-
+-		if (pi->nphy_gband_spurwar_en) {
+-
+-			wlc_phy_adjust_rx_analpfbw_nphy(pi,
+-							NPHY_ANARXLPFBW_REDUCTIONFACT);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if ((cur_channel == 11)
+-				    && CHSPEC_IS40(pi->radio_chanspec)) {
+-
+-					wlc_phy_adjust_min_noisevar_nphy(pi, 2,
+-									 nphy_adj_tone_id_buf,
+-									 nphy_adj_noise_var_buf);
+-				} else {
+-
+-					wlc_phy_adjust_min_noisevar_nphy(pi, 0,
+-									 NULL,
+-									 NULL);
+-				}
+-			}
+-			wlc_phy_adjust_crsminpwr_nphy(pi,
+-						      NPHY_ADJUSTED_MINCRSPOWER);
+-		}
+-
+-		if ((pi->nphy_gband_spurwar2_en)
+-		    && CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				switch (cur_channel) {
+-				case 3:
+-					nphy_adj_tone_id_buf[0] = 57;
+-					nphy_adj_tone_id_buf[1] = 58;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 4:
+-					nphy_adj_tone_id_buf[0] = 41;
+-					nphy_adj_tone_id_buf[1] = 42;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 5:
+-					nphy_adj_tone_id_buf[0] = 25;
+-					nphy_adj_tone_id_buf[1] = 26;
+-					nphy_adj_noise_var_buf[0] = 0x24f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 6:
+-					nphy_adj_tone_id_buf[0] = 9;
+-					nphy_adj_tone_id_buf[1] = 10;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 7:
+-					nphy_adj_tone_id_buf[0] = 121;
+-					nphy_adj_tone_id_buf[1] = 122;
+-					nphy_adj_noise_var_buf[0] = 0x18f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 8:
+-					nphy_adj_tone_id_buf[0] = 105;
+-					nphy_adj_tone_id_buf[1] = 106;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x25f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 9:
+-					nphy_adj_tone_id_buf[0] = 89;
+-					nphy_adj_tone_id_buf[1] = 90;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				case 10:
+-					nphy_adj_tone_id_buf[0] = 73;
+-					nphy_adj_tone_id_buf[1] = 74;
+-					nphy_adj_noise_var_buf[0] = 0x22f;
+-					nphy_adj_noise_var_buf[1] = 0x24f;
+-					isAdjustNoiseVar = true;
+-					break;
+-				default:
+-					isAdjustNoiseVar = false;
+-					break;
+-				}
+-			}
+-
+-			if (isAdjustNoiseVar) {
+-				numTonesAdjust = sizeof(nphy_adj_tone_id_buf) /
+-				    sizeof(nphy_adj_tone_id_buf[0]);
+-
+-				wlc_phy_adjust_min_noisevar_nphy(pi,
+-								 numTonesAdjust,
+-								 nphy_adj_tone_id_buf,
+-								 nphy_adj_noise_var_buf);
+-
+-				tempval = 0;
+-
+-			} else {
+-
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+-								 NULL);
+-			}
+-		}
+-
+-		if ((pi->nphy_aband_spurwar_en) &&
+-		    (CHSPEC_IS5G(pi->radio_chanspec))) {
+-			switch (cur_channel) {
+-			case 54:
+-				nphy_adj_tone_id_buf[0] = 32;
+-				nphy_adj_noise_var_buf[0] = 0x25f;
+-				break;
+-			case 38:
+-			case 102:
+-			case 118:
+-				if ((pi->sh->chip == BCM4716_CHIP_ID) &&
+-				    (pi->sh->chippkg == BCM4717_PKG_ID)) {
+-					nphy_adj_tone_id_buf[0] = 32;
+-					nphy_adj_noise_var_buf[0] = 0x21f;
+-				} else {
+-					nphy_adj_tone_id_buf[0] = 0;
+-					nphy_adj_noise_var_buf[0] = 0x0;
+-				}
+-				break;
+-			case 134:
+-				nphy_adj_tone_id_buf[0] = 32;
+-				nphy_adj_noise_var_buf[0] = 0x21f;
+-				break;
+-			case 151:
+-				nphy_adj_tone_id_buf[0] = 16;
+-				nphy_adj_noise_var_buf[0] = 0x23f;
+-				break;
+-			case 153:
+-			case 161:
+-				nphy_adj_tone_id_buf[0] = 48;
+-				nphy_adj_noise_var_buf[0] = 0x23f;
+-				break;
+-			default:
+-				nphy_adj_tone_id_buf[0] = 0;
+-				nphy_adj_noise_var_buf[0] = 0x0;
+-				break;
+-			}
+-
+-			if (nphy_adj_tone_id_buf[0]
+-			    && nphy_adj_noise_var_buf[0]) {
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 1,
+-								 nphy_adj_tone_id_buf,
+-								 nphy_adj_noise_var_buf);
+-			} else {
+-				wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL,
+-								 NULL);
+-			}
+-		}
+-
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-	}
+-}
+-
+-static void
+-wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec,
+-			    const nphy_sfo_cfg_t *ci)
+-{
+-	u16 val;
+-
+-	val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
+-	if (CHSPEC_IS5G(chanspec) && !val) {
+-
+-		val = R_REG(&pi->regs->psm_phy_hdr_param);
+-		W_REG(&pi->regs->psm_phy_hdr_param,
+-		      (val | MAC_PHY_FORCE_CLK));
+-
+-		or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+-			   (BBCFG_RESETCCA | BBCFG_RESETRX));
+-
+-		W_REG(&pi->regs->psm_phy_hdr_param, val);
+-
+-		or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
+-	} else if (!CHSPEC_IS5G(chanspec) && val) {
+-
+-		and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
+-
+-		val = R_REG(&pi->regs->psm_phy_hdr_param);
+-		W_REG(&pi->regs->psm_phy_hdr_param,
+-		      (val | MAC_PHY_FORCE_CLK));
+-
+-		and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
+-			    (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
+-
+-		W_REG(&pi->regs->psm_phy_hdr_param, val);
+-	}
+-
+-	write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
+-	write_phy_reg(pi, 0x1cf, ci->PHY_BW2);
+-	write_phy_reg(pi, 0x1d0, ci->PHY_BW3);
+-
+-	write_phy_reg(pi, 0x1d1, ci->PHY_BW4);
+-	write_phy_reg(pi, 0x1d2, ci->PHY_BW5);
+-	write_phy_reg(pi, 0x1d3, ci->PHY_BW6);
+-
+-	if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0);
+-
+-		or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800);
+-	} else {
+-		wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en,
+-					NPHY_ClassifierCtrl_ofdm_en);
+-
+-		if (CHSPEC_IS2G(chanspec))
+-			and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840);
+-	}
+-
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-		wlc_phy_txpwr_fixpower_nphy(pi);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-		wlc_phy_adjust_lnagaintbl_nphy(pi);
+-	}
+-
+-	wlc_phy_txlpfbw_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)
+-	    && (pi->phy_spuravoid != SPURAVOID_DISABLE)) {
+-		u8 spuravoid = 0;
+-
+-		val = CHSPEC_CHANNEL(chanspec);
+-		if (!CHSPEC_IS40(pi->radio_chanspec)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				if ((val == 13) || (val == 14) || (val == 153)) {
+-					spuravoid = 1;
+-				}
+-			} else {
+-
+-				if (((val >= 5) && (val <= 8)) || (val == 13)
+-				    || (val == 14)) {
+-					spuravoid = 1;
+-				}
+-			}
+-		} else {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				if (val == 54) {
+-					spuravoid = 1;
+-				}
+-			} else {
+-
+-				if (pi->nphy_aband_spurwar_en &&
+-				    ((val == 38) || (val == 102)
+-				     || (val == 118))) {
+-					if ((pi->sh->chip ==
+-					     BCM4716_CHIP_ID)
+-					    && (pi->sh->chippkg ==
+-						BCM4717_PKG_ID)) {
+-						spuravoid = 0;
+-					} else {
+-						spuravoid = 1;
+-					}
+-				}
+-			}
+-		}
+-
+-		if (pi->phy_spuravoid == SPURAVOID_FORCEON)
+-			spuravoid = 1;
+-
+-		if ((pi->sh->chip == BCM4716_CHIP_ID) ||
+-		    (pi->sh->chip == BCM47162_CHIP_ID)) {
+-			si_pmu_spuravoid(pi->sh->sih, spuravoid);
+-		} else {
+-			wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
+-			si_pmu_spuravoid(pi->sh->sih, spuravoid);
+-			wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
+-		}
+-
+-		if ((pi->sh->chip == BCM43224_CHIP_ID) ||
+-		    (pi->sh->chip == BCM43225_CHIP_ID) ||
+-		    (pi->sh->chip == BCM43421_CHIP_ID)) {
+-
+-			if (spuravoid == 1) {
+-
+-				W_REG(&pi->regs->tsf_clk_frac_l,
+-				      0x5341);
+-				W_REG(&pi->regs->tsf_clk_frac_h,
+-				      0x8);
+-			} else {
+-
+-				W_REG(&pi->regs->tsf_clk_frac_l,
+-				      0x8889);
+-				W_REG(&pi->regs->tsf_clk_frac_h,
+-				      0x8);
+-			}
+-		}
+-
+-		if (!((pi->sh->chip == BCM4716_CHIP_ID) ||
+-		      (pi->sh->chip == BCM47162_CHIP_ID))) {
+-			wlapi_bmac_core_phypll_reset(pi->sh->physhim);
+-		}
+-
+-		mod_phy_reg(pi, 0x01, (0x1 << 15),
+-			    ((spuravoid > 0) ? (0x1 << 15) : 0));
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-		pi->phy_isspuravoid = (spuravoid > 0);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7))
+-		write_phy_reg(pi, 0x17e, 0x3830);
+-
+-	wlc_phy_spurwar_nphy(pi);
+-}
+-
+-void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec)
+-{
+-	int freq;
+-	chan_info_nphy_radio2057_t *t0 = NULL;
+-	chan_info_nphy_radio205x_t *t1 = NULL;
+-	chan_info_nphy_radio2057_rev5_t *t2 = NULL;
+-	chan_info_nphy_2055_t *t3 = NULL;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		return;
+-	}
+-
+-	if (!wlc_phy_chan2freq_nphy
+-	    (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3))
+-		return;
+-
+-	wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec);
+-
+-	if (CHSPEC_BW(chanspec) != pi->bw)
+-		wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec));
+-
+-	if (CHSPEC_IS40(chanspec)) {
+-		if (CHSPEC_SB_UPPER(chanspec)) {
+-			or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20);
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				or_phy_reg(pi, 0x310, PRIM_SEL_UP20);
+-			}
+-		} else {
+-			and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20);
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				and_phy_reg(pi, 0x310,
+-					    (~PRIM_SEL_UP20 & 0xffff));
+-			}
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			if ((pi->pubpi.radiorev <= 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0,
+-					      0x2,
+-					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
+-					       : 0));
+-				mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1,
+-					      0x2,
+-					      (CHSPEC_IS5G(chanspec) ? (1 << 1)
+-					       : 0));
+-			}
+-
+-			wlc_phy_chanspec_radio2057_setup(pi, t0, t2);
+-			wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-						    (pi->pubpi.radiorev ==
+-						     5) ? (const nphy_sfo_cfg_t
+-							   *)&(t2->
+-							       PHY_BW1a)
+-						    : (const nphy_sfo_cfg_t *)
+-						    &(t0->PHY_BW1a));
+-
+-		} else {
+-
+-			mod_radio_reg(pi,
+-				      RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN,
+-				      0x4,
+-				      (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0));
+-			wlc_phy_chanspec_radio2056_setup(pi, t1);
+-
+-			wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-						    (const nphy_sfo_cfg_t *)
+-						    &(t1->PHY_BW1a));
+-		}
+-
+-	} else {
+-
+-		mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70,
+-			      (CHSPEC_IS5G(chanspec) ? (0x02 << 4)
+-			       : (0x05 << 4)));
+-
+-		wlc_phy_chanspec_radio2055_setup(pi, t3);
+-		wlc_phy_chanspec_nphy_setup(pi, chanspec,
+-					    (const nphy_sfo_cfg_t *)&(t3->
+-								      PHY_BW1a));
+-	}
+-
+-}
+-
+-static void wlc_phy_savecal_nphy(phy_info_t *pi)
+-{
+-	void *tbl_ptr;
+-	int coreNum;
+-	u16 *txcal_radio_regs = NULL;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_2G);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_2G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			pi->calibration_cache.txcal_radio_regs_2G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_2G[3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX1);
+-
+-			pi->calibration_cache.txcal_radio_regs_2G[4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_2G[6] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_2G[7] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX1);
+-		} else {
+-			pi->calibration_cache.txcal_radio_regs_2G[0] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_2G[1] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_2G[2] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+-			pi->calibration_cache.txcal_radio_regs_2G[3] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+-		}
+-
+-		pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec;
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+-	} else {
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 0,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_5G);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_5G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			pi->calibration_cache.txcal_radio_regs_5G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_5G[3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_FINE_Q |
+-					   RADIO_2056_TX1);
+-
+-			pi->calibration_cache.txcal_radio_regs_5G[4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX0);
+-			pi->calibration_cache.txcal_radio_regs_5G[6] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_I |
+-					   RADIO_2056_TX1);
+-			pi->calibration_cache.txcal_radio_regs_5G[7] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_LOFT_COARSE_Q |
+-					   RADIO_2056_TX1);
+-		} else {
+-			pi->calibration_cache.txcal_radio_regs_5G[0] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_5G[1] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL);
+-			pi->calibration_cache.txcal_radio_regs_5G[2] =
+-			    read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM);
+-			pi->calibration_cache.txcal_radio_regs_5G[3] =
+-			    read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM);
+-		}
+-
+-		pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec;
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			txcal_radio_regs[2 * coreNum] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_FINE_I);
+-			txcal_radio_regs[2 * coreNum + 1] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_FINE_Q);
+-
+-			txcal_radio_regs[2 * coreNum + 4] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_COARSE_I);
+-			txcal_radio_regs[2 * coreNum + 5] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					    LOFT_COARSE_Q);
+-		}
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_restorecal_nphy(phy_info_t *pi)
+-{
+-	u16 *loft_comp;
+-	u16 txcal_coeffs_bphy[4];
+-	u16 *tbl_ptr;
+-	int coreNum;
+-	u16 *txcal_radio_regs = NULL;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->nphy_iqcal_chanspec_2G == 0)
+-			return;
+-
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_2G;
+-		loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5];
+-	} else {
+-		if (pi->nphy_iqcal_chanspec_5G == 0)
+-			return;
+-
+-		tbl_ptr = pi->calibration_cache.txcal_coeffs_5G;
+-		loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5];
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16,
+-				 (void *)tbl_ptr);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		txcal_coeffs_bphy[0] = tbl_ptr[0];
+-		txcal_coeffs_bphy[1] = tbl_ptr[1];
+-		txcal_coeffs_bphy[2] = tbl_ptr[2];
+-		txcal_coeffs_bphy[3] = tbl_ptr[3];
+-	} else {
+-		txcal_coeffs_bphy[0] = 0;
+-		txcal_coeffs_bphy[1] = 0;
+-		txcal_coeffs_bphy[2] = 0;
+-		txcal_coeffs_bphy[3] = 0;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16,
+-				 txcal_coeffs_bphy);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2))
+-		wlc_phy_tx_iq_war_nphy(pi);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_2G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[0]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[1]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[2]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[4]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[5]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[6]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[7]);
+-		} else {
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[0]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[1]);
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[2]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_2G[3]);
+-		}
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_2G);
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			txcal_radio_regs =
+-			    pi->calibration_cache.txcal_radio_regs_5G;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[0]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[1]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[2]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_FINE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[4]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX0,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[5]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_I |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[6]);
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_LOFT_COARSE_Q |
+-					RADIO_2056_TX1,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[7]);
+-		} else {
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[0]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[1]);
+-			write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[2]);
+-			write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM,
+-					pi->calibration_cache.
+-					txcal_radio_regs_5G[3]);
+-		}
+-
+-		wlc_phy_rx_iq_coeffs_nphy(pi, 1,
+-					  &pi->calibration_cache.
+-					  rxcal_coeffs_5G);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (coreNum = 0; coreNum <= 1; coreNum++) {
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_FINE_I,
+-					 txcal_radio_regs[2 * coreNum]);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_FINE_Q,
+-					 txcal_radio_regs[2 * coreNum + 1]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_COARSE_I,
+-					 txcal_radio_regs[2 * coreNum + 4]);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum,
+-					 LOFT_COARSE_Q,
+-					 txcal_radio_regs[2 * coreNum + 5]);
+-		}
+-	}
+-}
+-
+-void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init)
+-{
+-	phy_info_t *pi = (phy_info_t *) ppi;
+-	u16 mask = 0xfc00;
+-	u32 mc = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7))
+-		return;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
+-
+-		if (lut_init == false)
+-			return;
+-
+-		if (pi->srom_fem2g.antswctrllut == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x02, 16, &v0);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x03, 16, &v1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x08, 16, &v2);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x0C, 16, &v3);
+-		}
+-
+-		if (pi->srom_fem5g.antswctrllut == 0) {
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x12, 16, &v0);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x13, 16, &v1);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x18, 16, &v2);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
+-						 1, 0x1C, 16, &v3);
+-		}
+-	} else {
+-
+-		write_phy_reg(pi, 0xc8, 0x0);
+-		write_phy_reg(pi, 0xc9, 0x0);
+-
+-		ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
+-
+-		mc = R_REG(&pi->regs->maccontrol);
+-		mc &= ~MCTL_GPOUT_SEL_MASK;
+-		W_REG(&pi->regs->maccontrol, mc);
+-
+-		OR_REG(&pi->regs->psm_gpio_oe, mask);
+-
+-		AND_REG(&pi->regs->psm_gpio_out, ~mask);
+-
+-		if (lut_init) {
+-			write_phy_reg(pi, 0xf8, 0x02d8);
+-			write_phy_reg(pi, 0xf9, 0x0301);
+-			write_phy_reg(pi, 0xfa, 0x02d8);
+-			write_phy_reg(pi, 0xfb, 0x0301);
+-		}
+-	}
+-}
+-
+-u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val)
+-{
+-	u16 curr_ctl, new_ctl;
+-	bool suspended = false;
+-
+-	if (D11REV_IS(pi->sh->corerev, 16)) {
+-		suspended =
+-		    (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ?
+-		    false : true;
+-		if (!suspended)
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-
+-	curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0);
+-
+-	new_ctl = (curr_ctl & (~mask)) | (val & mask);
+-
+-	mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl);
+-
+-	if (D11REV_IS(pi->sh->corerev, 16) && !suspended)
+-		wlapi_enable_mac(pi->sh->physhim);
+-
+-	return new_ctl;
+-}
+-
+-static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals)
+-{
+-
+-	if (write == 0) {
+-		vals[0] = read_phy_reg(pi, 0x2c);
+-		vals[1] = read_phy_reg(pi, 0x42);
+-	} else {
+-		write_phy_reg(pi, 0x2c, vals[0]);
+-		write_phy_reg(pi, 0x42, vals[1]);
+-	}
+-}
+-
+-void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd)
+-{
+-	u16 trigger_mask, status_mask;
+-	u16 orig_RfseqCoreActv;
+-
+-	switch (cmd) {
+-	case NPHY_RFSEQ_RX2TX:
+-		trigger_mask = NPHY_RfseqTrigger_rx2tx;
+-		status_mask = NPHY_RfseqStatus_rx2tx;
+-		break;
+-	case NPHY_RFSEQ_TX2RX:
+-		trigger_mask = NPHY_RfseqTrigger_tx2rx;
+-		status_mask = NPHY_RfseqStatus_tx2rx;
+-		break;
+-	case NPHY_RFSEQ_RESET2RX:
+-		trigger_mask = NPHY_RfseqTrigger_reset2rx;
+-		status_mask = NPHY_RfseqStatus_reset2rx;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINH:
+-		trigger_mask = NPHY_RfseqTrigger_updategainh;
+-		status_mask = NPHY_RfseqStatus_updategainh;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINL:
+-		trigger_mask = NPHY_RfseqTrigger_updategainl;
+-		status_mask = NPHY_RfseqStatus_updategainl;
+-		break;
+-	case NPHY_RFSEQ_UPDATEGAINU:
+-		trigger_mask = NPHY_RfseqTrigger_updategainu;
+-		status_mask = NPHY_RfseqStatus_updategainu;
+-		break;
+-	default:
+-		return;
+-	}
+-
+-	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+-	or_phy_reg(pi, 0xa1,
+-		   (NPHY_RfseqMode_CoreActv_override |
+-		    NPHY_RfseqMode_Trigger_override));
+-	or_phy_reg(pi, 0xa3, trigger_mask);
+-	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
+-	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+-	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
+-}
+-
+-static void
+-wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys,
+-		       u8 len)
+-{
+-	u32 t1_offset, t2_offset;
+-	u8 ctr;
+-	u8 end_event =
+-	    NREV_GE(pi->pubpi.phy_rev,
+-		    3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
+-	u8 end_dly = 1;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	t1_offset = cmd << 4;
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8,
+-				 events);
+-	t2_offset = t1_offset + 0x080;
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8,
+-				 dlys);
+-
+-	for (ctr = len; ctr < 16; ctr++) {
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-					 t1_offset + ctr, 8, &end_event);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-					 t2_offset + ctr, 8, &end_dly);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset)
+-{
+-	u16 lpf_bw_ctl_val = 0;
+-	u16 rx2tx_lpf_rc_lut_offset = 0;
+-
+-	if (offset == 0) {
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			rx2tx_lpf_rc_lut_offset = 0x159;
+-		} else {
+-			rx2tx_lpf_rc_lut_offset = 0x154;
+-		}
+-	} else {
+-		rx2tx_lpf_rc_lut_offset = offset;
+-	}
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1,
+-				(u32) rx2tx_lpf_rc_lut_offset, 16,
+-				&lpf_bw_ctl_val);
+-
+-	lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7;
+-
+-	return lpf_bw_ctl_val;
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value,
+-				  u8 core_mask, u8 off, u8 override_id)
+-{
+-	u8 core_num;
+-	u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0;
+-	u8 val_shift = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		en_mask = field;
+-		for (core_num = 0; core_num < 2; core_num++) {
+-			if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) {
+-
+-				switch (field) {
+-				case (0x1 << 2):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 5):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 5);
+-					val_shift = 5;
+-					break;
+-				case (0x1 << 6):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 6);
+-					val_shift = 6;
+-					break;
+-				case (0x1 << 7):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7a :
+-					    0x7d;
+-					val_mask = (0x1 << 7);
+-					val_shift = 7;
+-					break;
+-				case (0x1 << 10):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0xf8 :
+-					    0xfa;
+-					val_mask = (0x7 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 11):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7b :
+-					    0x7e;
+-					val_mask = (0xffff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 12):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x7c :
+-					    0x7f;
+-					val_mask = (0xffff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x3 << 13):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x348 :
+-					    0x349;
+-					val_mask = (0xff << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 13):
+-					en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-					val_addr = (core_num == 0) ? 0x348 :
+-					    0x349;
+-					val_mask = (0xf << 0);
+-					val_shift = 0;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			} else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) {
+-
+-				switch (field) {
+-				case (0x1 << 1):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 3);
+-					val_shift = 3;
+-					break;
+-				case (0x1 << 5):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 5);
+-					val_shift = 5;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				case (0x1 << 2):
+-
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 7):
+-
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x7 << 8);
+-					val_shift = 8;
+-					break;
+-				case (0x1 << 11):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 14);
+-					val_shift = 14;
+-					break;
+-				case (0x1 << 10):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 13);
+-					val_shift = 13;
+-					break;
+-				case (0x1 << 9):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 12);
+-					val_shift = 12;
+-					break;
+-				case (0x1 << 8):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 11);
+-					val_shift = 11;
+-					break;
+-				case (0x1 << 6):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 6);
+-					val_shift = 6;
+-					break;
+-				case (0x1 << 0):
+-					en_addr = (core_num == 0) ? 0x342 :
+-					    0x343;
+-					val_addr = (core_num == 0) ? 0x340 :
+-					    0x341;
+-					val_mask = (0x1 << 0);
+-					val_shift = 0;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			} else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) {
+-
+-				switch (field) {
+-				case (0x1 << 3):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 3);
+-					val_shift = 3;
+-					break;
+-				case (0x1 << 1):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 1);
+-					val_shift = 1;
+-					break;
+-				case (0x1 << 0):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 0);
+-					val_shift = 0;
+-					break;
+-				case (0x1 << 2):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 2);
+-					val_shift = 2;
+-					break;
+-				case (0x1 << 4):
+-					en_addr = (core_num == 0) ? 0x346 :
+-					    0x347;
+-					val_addr = (core_num == 0) ? 0x344 :
+-					    0x345;
+-					val_mask = (0x1 << 4);
+-					val_shift = 4;
+-					break;
+-				default:
+-					addr = 0xffff;
+-					break;
+-				}
+-			}
+-
+-			if (off) {
+-				and_phy_reg(pi, en_addr, ~en_mask);
+-				and_phy_reg(pi, val_addr, ~val_mask);
+-			} else {
+-
+-				if ((core_mask == 0)
+-				    || (core_mask & (1 << core_num))) {
+-					or_phy_reg(pi, en_addr, en_mask);
+-
+-					if (addr != 0xffff) {
+-						mod_phy_reg(pi, val_addr,
+-							    val_mask,
+-							    (value <<
+-							     val_shift));
+-					}
+-				}
+-			}
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value,
+-			     u8 core_mask, u8 off)
+-{
+-	u8 core_num;
+-	u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask =
+-	    0, val_mask = 0;
+-	u8 shift = 0, val_shift = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		en_mask = field;
+-		for (core_num = 0; core_num < 2; core_num++) {
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 2):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 1);
+-				val_shift = 1;
+-				break;
+-			case (0x1 << 3):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 2);
+-				val_shift = 2;
+-				break;
+-			case (0x1 << 4):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 4);
+-				val_shift = 4;
+-				break;
+-			case (0x1 << 5):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 5);
+-				val_shift = 5;
+-				break;
+-			case (0x1 << 6):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 6);
+-				val_shift = 6;
+-				break;
+-			case (0x1 << 7):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x1 << 7);
+-				val_shift = 7;
+-				break;
+-			case (0x1 << 8):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x7 << 8);
+-				val_shift = 8;
+-				break;
+-			case (0x1 << 11):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7a : 0x7d;
+-				val_mask = (0x7 << 13);
+-				val_shift = 13;
+-				break;
+-
+-			case (0x1 << 9):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+-				val_mask = (0x7 << 0);
+-				val_shift = 0;
+-				break;
+-
+-			case (0x1 << 10):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf8 : 0xfa;
+-				val_mask = (0x7 << 4);
+-				val_shift = 4;
+-				break;
+-
+-			case (0x1 << 12):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7b : 0x7e;
+-				val_mask = (0xffff << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 13):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0x7c : 0x7f;
+-				val_mask = (0xffff << 0);
+-				val_shift = 0;
+-				break;
+-			case (0x1 << 14):
+-				en_addr = (core_num == 0) ? 0xe7 : 0xec;
+-				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+-				val_mask = (0x3 << 6);
+-				val_shift = 6;
+-				break;
+-			case (0x1 << 0):
+-				en_addr = (core_num == 0) ? 0xe5 : 0xe6;
+-				val_addr = (core_num == 0) ? 0xf9 : 0xfb;
+-				val_mask = (0x1 << 15);
+-				val_shift = 15;
+-				break;
+-			default:
+-				addr = 0xffff;
+-				break;
+-			}
+-
+-			if (off) {
+-				and_phy_reg(pi, en_addr, ~en_mask);
+-				and_phy_reg(pi, val_addr, ~val_mask);
+-			} else {
+-
+-				if ((core_mask == 0)
+-				    || (core_mask & (1 << core_num))) {
+-					or_phy_reg(pi, en_addr, en_mask);
+-
+-					if (addr != 0xffff) {
+-						mod_phy_reg(pi, val_addr,
+-							    val_mask,
+-							    (value <<
+-							     val_shift));
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		if (off) {
+-			and_phy_reg(pi, 0xec, ~field);
+-			value = 0x0;
+-		} else {
+-			or_phy_reg(pi, 0xec, field);
+-		}
+-
+-		for (core_num = 0; core_num < 2; core_num++) {
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-			case (0x1 << 9):
+-			case (0x1 << 12):
+-			case (0x1 << 13):
+-			case (0x1 << 14):
+-				addr = 0x78;
+-
+-				core_mask = 0x1;
+-				break;
+-			case (0x1 << 2):
+-			case (0x1 << 3):
+-			case (0x1 << 4):
+-			case (0x1 << 5):
+-			case (0x1 << 6):
+-			case (0x1 << 7):
+-			case (0x1 << 8):
+-				addr = (core_num == 0) ? 0x7a : 0x7d;
+-				break;
+-			case (0x1 << 10):
+-				addr = (core_num == 0) ? 0x7b : 0x7e;
+-				break;
+-			case (0x1 << 11):
+-				addr = (core_num == 0) ? 0x7c : 0x7f;
+-				break;
+-			default:
+-				addr = 0xffff;
+-			}
+-
+-			switch (field) {
+-			case (0x1 << 1):
+-				mask = (0x7 << 3);
+-				shift = 3;
+-				break;
+-			case (0x1 << 9):
+-				mask = (0x1 << 2);
+-				shift = 2;
+-				break;
+-			case (0x1 << 12):
+-				mask = (0x1 << 8);
+-				shift = 8;
+-				break;
+-			case (0x1 << 13):
+-				mask = (0x1 << 9);
+-				shift = 9;
+-				break;
+-			case (0x1 << 14):
+-				mask = (0xf << 12);
+-				shift = 12;
+-				break;
+-			case (0x1 << 2):
+-				mask = (0x1 << 0);
+-				shift = 0;
+-				break;
+-			case (0x1 << 3):
+-				mask = (0x1 << 1);
+-				shift = 1;
+-				break;
+-			case (0x1 << 4):
+-				mask = (0x1 << 2);
+-				shift = 2;
+-				break;
+-			case (0x1 << 5):
+-				mask = (0x3 << 4);
+-				shift = 4;
+-				break;
+-			case (0x1 << 6):
+-				mask = (0x3 << 6);
+-				shift = 6;
+-				break;
+-			case (0x1 << 7):
+-				mask = (0x1 << 8);
+-				shift = 8;
+-				break;
+-			case (0x1 << 8):
+-				mask = (0x1 << 9);
+-				shift = 9;
+-				break;
+-			case (0x1 << 10):
+-				mask = 0x1fff;
+-				shift = 0x0;
+-				break;
+-			case (0x1 << 11):
+-				mask = 0x1fff;
+-				shift = 0x0;
+-				break;
+-			default:
+-				mask = 0x0;
+-				shift = 0x0;
+-				break;
+-			}
+-
+-			if ((addr != 0xffff) && (core_mask & (1 << core_num))) {
+-				mod_phy_reg(pi, addr, mask, (value << shift));
+-			}
+-		}
+-
+-		or_phy_reg(pi, 0xec, (0x1 << 0));
+-		or_phy_reg(pi, 0x78, (0x1 << 0));
+-		udelay(1);
+-		and_phy_reg(pi, 0xec, ~(0x1 << 0));
+-	}
+-}
+-
+-static void
+-wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value,
+-				     u8 core_mask, u8 off)
+-{
+-	u16 rfmxgain = 0, lpfgain = 0;
+-	u16 tgain = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		switch (cmd) {
+-		case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_rx_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_tx_pu:
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  value, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1,
+-							  core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_rxgain:
+-			rfmxgain = value & 0x000ff;
+-			lpfgain = value & 0x0ff00;
+-			lpfgain = lpfgain >> 8;
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+-							  rfmxgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13),
+-							  lpfgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			break;
+-		case NPHY_REV7_RfctrlOverride_cmd_txgain:
+-			tgain = value & 0x7fff;
+-			lpfgain = value & 0x8000;
+-			lpfgain = lpfgain >> 14;
+-
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-							  tgain, core_mask, off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13),
+-							  lpfgain, core_mask,
+-							  off,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			break;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset,
+-			       u8 coresel, u8 rail, u8 rssi_type)
+-{
+-	u16 valuetostuff;
+-
+-	offset = (offset > NPHY_RSSICAL_MAXREAD) ?
+-	    NPHY_RSSICAL_MAXREAD : offset;
+-	offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ?
+-	    -NPHY_RSSICAL_MAXREAD - 1 : offset;
+-
+-	valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f);
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1a6, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1ac, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1b2, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) {
+-		write_phy_reg(pi, 0x1b8, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1a4, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1aa, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1b0, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) {
+-		write_phy_reg(pi, 0x1b6, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1a5, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1ab, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1b1, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) {
+-		write_phy_reg(pi, 0x1b7, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1a7, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1ad, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1b3, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) {
+-		write_phy_reg(pi, 0x1b9, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1a8, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1ae, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1b4, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) {
+-		write_phy_reg(pi, 0x1ba, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+-		write_phy_reg(pi, 0x1a9, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) {
+-		write_phy_reg(pi, 0x1b5, valuetostuff);
+-	}
+-
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE1) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+-		write_phy_reg(pi, 0x1af, valuetostuff);
+-	}
+-	if (((coresel == RADIO_MIMO_CORESEL_CORE2) ||
+-	     (coresel == RADIO_MIMO_CORESEL_ALLRX)) &&
+-	    (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) {
+-		write_phy_reg(pi, 0x1bb, valuetostuff);
+-	}
+-}
+-
+-void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type)
+-{
+-	u16 mask, val;
+-	u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val,
+-	    startseq;
+-	u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val,
+-	    rfctrlovr_trigger_val;
+-	u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask;
+-	u16 rfctrlcmd_val, rfctrlovr_val;
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (core_code == RADIO_MIMO_CORESEL_OFF) {
+-			mod_phy_reg(pi, 0x8f, (0x1 << 9), 0);
+-			mod_phy_reg(pi, 0xa5, (0x1 << 9), 0);
+-
+-			mod_phy_reg(pi, 0xa6, (0x3 << 8), 0);
+-			mod_phy_reg(pi, 0xa7, (0x3 << 8), 0);
+-
+-			mod_phy_reg(pi, 0xe5, (0x1 << 5), 0);
+-			mod_phy_reg(pi, 0xe6, (0x1 << 5), 0);
+-
+-			mask = (0x1 << 2) |
+-			    (0x1 << 3) | (0x1 << 4) | (0x1 << 5);
+-			mod_phy_reg(pi, 0xf9, mask, 0);
+-			mod_phy_reg(pi, 0xfb, mask, 0);
+-
+-		} else {
+-			for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-				if (core_code == RADIO_MIMO_CORESEL_CORE1
+-				    && core == PHY_CORE_1)
+-					continue;
+-				else if (core_code == RADIO_MIMO_CORESEL_CORE2
+-					 && core == PHY_CORE_0)
+-					continue;
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ?
+-					    0x8f : 0xa5, (0x1 << 9), 1 << 9);
+-
+-				if (rssi_type == NPHY_RSSI_SEL_W1 ||
+-				    rssi_type == NPHY_RSSI_SEL_W2 ||
+-				    rssi_type == NPHY_RSSI_SEL_NB) {
+-
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xa6 : 0xa7,
+-						    (0x3 << 8), 0);
+-
+-					mask = (0x1 << 2) |
+-					    (0x1 << 3) |
+-					    (0x1 << 4) | (0x1 << 5);
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xf9 : 0xfb,
+-						    mask, 0);
+-
+-					if (rssi_type == NPHY_RSSI_SEL_W1) {
+-						if (CHSPEC_IS5G
+-						    (pi->radio_chanspec)) {
+-							mask = (0x1 << 2);
+-							val = 1 << 2;
+-						} else {
+-							mask = (0x1 << 3);
+-							val = 1 << 3;
+-						}
+-					} else if (rssi_type ==
+-						   NPHY_RSSI_SEL_W2) {
+-						mask = (0x1 << 4);
+-						val = 1 << 4;
+-					} else {
+-						mask = (0x1 << 5);
+-						val = 1 << 5;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xf9 : 0xfb,
+-						    mask, val);
+-
+-					mask = (0x1 << 5);
+-					val = 1 << 5;
+-					mod_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xe5 : 0xe6, mask, val);
+-				} else {
+-					if (rssi_type == NPHY_RSSI_SEL_TBD) {
+-
+-						mask = (0x3 << 8);
+-						val = 1 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 1 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-					} else if (rssi_type ==
+-						   NPHY_RSSI_SEL_IQ) {
+-
+-						mask = (0x3 << 8);
+-						val = 2 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 2 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-					} else {
+-
+-						mask = (0x3 << 8);
+-						val = 3 << 8;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-						mask = (0x3 << 10);
+-						val = 3 << 10;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0xa6
+-							    : 0xa7, mask, val);
+-
+-						if (PHY_IPA(pi)) {
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     7)) {
+-
+-								write_radio_reg
+-								    (pi,
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2057_TX0_TX_SSI_MUX
+-								      :
+-								      RADIO_2057_TX1_TX_SSI_MUX),
+-								     (CHSPEC_IS5G
+-								      (pi->
+-								       radio_chanspec)
+-								      ? 0xc :
+-								      0xe));
+-							} else {
+-								write_radio_reg
+-								    (pi,
+-								     RADIO_2056_TX_TX_SSI_MUX
+-								     |
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2056_TX0
+-								      :
+-								      RADIO_2056_TX1),
+-								     (CHSPEC_IS5G
+-								      (pi->
+-								       radio_chanspec)
+-								      ? 0xc :
+-								      0xe));
+-							}
+-						} else {
+-
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     7)) {
+-								write_radio_reg
+-								    (pi,
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2057_TX0_TX_SSI_MUX
+-								      :
+-								      RADIO_2057_TX1_TX_SSI_MUX),
+-								     0x11);
+-
+-								if (pi->pubpi.
+-								    radioid ==
+-								    BCM2057_ID)
+-									write_radio_reg
+-									    (pi,
+-									     RADIO_2057_IQTEST_SEL_PU,
+-									     0x1);
+-
+-							} else {
+-								write_radio_reg
+-								    (pi,
+-								     RADIO_2056_TX_TX_SSI_MUX
+-								     |
+-								     ((core ==
+-								       PHY_CORE_0)
+-								      ?
+-								      RADIO_2056_TX0
+-								      :
+-								      RADIO_2056_TX1),
+-								     0x11);
+-							}
+-						}
+-
+-						afectrlovr_rssi_val = 1 << 9;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x8f
+-							    : 0xa5, (0x1 << 9),
+-							    afectrlovr_rssi_val);
+-					}
+-				}
+-			}
+-		}
+-	} else {
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-
+-			val = 0x0;
+-		} else if (rssi_type == NPHY_RSSI_SEL_TBD) {
+-
+-			val = 0x1;
+-		} else if (rssi_type == NPHY_RSSI_SEL_IQ) {
+-
+-			val = 0x2;
+-		} else {
+-
+-			val = 0x3;
+-		}
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		val = (val << 12) | (val << 14);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-			if (rssi_type == NPHY_RSSI_SEL_W1) {
+-				val = 0x1;
+-			}
+-			if (rssi_type == NPHY_RSSI_SEL_W2) {
+-				val = 0x2;
+-			}
+-			if (rssi_type == NPHY_RSSI_SEL_NB) {
+-				val = 0x3;
+-			}
+-			mask = (0x3 << 4);
+-			val = (val << 4);
+-			mod_phy_reg(pi, 0x7a, mask, val);
+-			mod_phy_reg(pi, 0x7d, mask, val);
+-		}
+-
+-		if (core_code == RADIO_MIMO_CORESEL_OFF) {
+-			afectrlovr_rssi_val = 0;
+-			rfctrlcmd_rxen_val = 0;
+-			rfctrlcmd_coresel_val = 0;
+-			rfctrlovr_rssi_val = 0;
+-			rfctrlovr_rxen_val = 0;
+-			rfctrlovr_coresel_val = 0;
+-			rfctrlovr_trigger_val = 0;
+-			startseq = 0;
+-		} else {
+-			afectrlovr_rssi_val = 1;
+-			rfctrlcmd_rxen_val = 1;
+-			rfctrlcmd_coresel_val = core_code;
+-			rfctrlovr_rssi_val = 1;
+-			rfctrlovr_rxen_val = 1;
+-			rfctrlovr_coresel_val = 1;
+-			rfctrlovr_trigger_val = 1;
+-			startseq = 1;
+-		}
+-
+-		afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13));
+-		afectrlovr_rssi_val = (afectrlovr_rssi_val <<
+-				       12) | (afectrlovr_rssi_val << 13);
+-		mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask,
+-			    afectrlovr_rssi_val);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1) ||
+-		    (rssi_type == NPHY_RSSI_SEL_W2) ||
+-		    (rssi_type == NPHY_RSSI_SEL_NB)) {
+-			rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3));
+-			rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) |
+-			    (rfctrlcmd_coresel_val << 3);
+-
+-			rfctrlovr_mask = ((0x1 << 5) |
+-					  (0x1 << 12) |
+-					  (0x1 << 1) | (0x1 << 0));
+-			rfctrlovr_val = (rfctrlovr_rssi_val <<
+-					 5) |
+-			    (rfctrlovr_rxen_val << 12) |
+-			    (rfctrlovr_coresel_val << 1) |
+-			    (rfctrlovr_trigger_val << 0);
+-
+-			mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val);
+-			mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val);
+-
+-			mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0));
+-			udelay(20);
+-
+-			mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+-		}
+-	}
+-}
+-
+-int
+-wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf,
+-		       u8 nsamps)
+-{
+-	s16 rssi0, rssi1;
+-	u16 afectrlCore1_save = 0;
+-	u16 afectrlCore2_save = 0;
+-	u16 afectrlOverride1_save = 0;
+-	u16 afectrlOverride2_save = 0;
+-	u16 rfctrlOverrideAux0_save = 0;
+-	u16 rfctrlOverrideAux1_save = 0;
+-	u16 rfctrlMiscReg1_save = 0;
+-	u16 rfctrlMiscReg2_save = 0;
+-	u16 rfctrlcmd_save = 0;
+-	u16 rfctrloverride_save = 0;
+-	u16 rfctrlrssiothers1_save = 0;
+-	u16 rfctrlrssiothers2_save = 0;
+-	s8 tmp_buf[4];
+-	u8 ctr = 0, samp = 0;
+-	s32 rssi_out_val;
+-	u16 gpiosel_orig;
+-
+-	afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-	afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+-		rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+-		afectrlOverride1_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+-		rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+-	} else {
+-		afectrlOverride1_save = read_phy_reg(pi, 0xa5);
+-		rfctrlcmd_save = read_phy_reg(pi, 0x78);
+-		rfctrloverride_save = read_phy_reg(pi, 0xec);
+-		rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a);
+-		rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d);
+-	}
+-
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+-
+-	gpiosel_orig = read_phy_reg(pi, 0xca);
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0xca, 5);
+-	}
+-
+-	for (ctr = 0; ctr < 4; ctr++) {
+-		rssi_buf[ctr] = 0;
+-	}
+-
+-	for (samp = 0; samp < nsamps; samp++) {
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-			rssi0 = read_phy_reg(pi, 0x1c9);
+-			rssi1 = read_phy_reg(pi, 0x1ca);
+-		} else {
+-			rssi0 = read_phy_reg(pi, 0x219);
+-			rssi1 = read_phy_reg(pi, 0x21a);
+-		}
+-
+-		ctr = 0;
+-		tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2;
+-		tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2;
+-
+-		for (ctr = 0; ctr < 4; ctr++) {
+-			rssi_buf[ctr] += tmp_buf[ctr];
+-		}
+-
+-	}
+-
+-	rssi_out_val = rssi_buf[3] & 0xff;
+-	rssi_out_val |= (rssi_buf[2] & 0xff) << 8;
+-	rssi_out_val |= (rssi_buf[1] & 0xff) << 16;
+-	rssi_out_val |= (rssi_buf[0] & 0xff) << 24;
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		write_phy_reg(pi, 0xca, gpiosel_orig);
+-	}
+-
+-	write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-	write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save);
+-		write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride1_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-		write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save);
+-		write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save);
+-	} else {
+-		write_phy_reg(pi, 0xa5, afectrlOverride1_save);
+-		write_phy_reg(pi, 0x78, rfctrlcmd_save);
+-		write_phy_reg(pi, 0xec, rfctrloverride_save);
+-		write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save);
+-		write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save);
+-	}
+-
+-	return rssi_out_val;
+-}
+-
+-s16 wlc_phy_tempsense_nphy(phy_info_t *pi)
+-{
+-	u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save;
+-	u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save;
+-	u16 pwrdet_rxtx_core1_save;
+-	u16 pwrdet_rxtx_core2_save;
+-	u16 afectrlCore1_save;
+-	u16 afectrlCore2_save;
+-	u16 afectrlOverride_save;
+-	u16 afectrlOverride2_save;
+-	u16 pd_pll_ts_save;
+-	u16 gpioSel_save;
+-	s32 radio_temp[4];
+-	s32 radio_temp2[4];
+-	u16 syn_tempprocsense_save;
+-	s16 offset = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save;
+-		u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save;
+-		u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH;
+-		s32 auxADC_Vl;
+-		u16 RfctrlOverride5_save, RfctrlOverride6_save;
+-		u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save;
+-		u16 RSSIMultCoef0QPowerDet_save;
+-		u16 tempsense_Rcal;
+-
+-		syn_tempprocsense_save =
+-		    read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae);
+-		RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+-		RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+-		RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+-		RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					&auxADC_Vmid_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					&auxADC_Av_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					&auxADC_rssi_ctrlL_save);
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					&auxADC_rssi_ctrlH_save);
+-
+-		write_phy_reg(pi, 0x1ae, 0x0);
+-
+-		auxADC_rssi_ctrlL = 0x0;
+-		auxADC_rssi_ctrlH = 0x20;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					 &auxADC_rssi_ctrlL);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					 &auxADC_rssi_ctrlH);
+-
+-		tempsense_Rcal = syn_tempprocsense_save & 0x1c;
+-
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x01);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+-						  1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 7), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 7), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7));
+-
+-		mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2));
+-		udelay(5);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 2), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 2), 0);
+-		mod_phy_reg(pi, 0xa6, (0x1 << 3), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 3), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3));
+-		mod_phy_reg(pi, 0xa6, (0x1 << 6), 0);
+-		mod_phy_reg(pi, 0xa7, (0x1 << 6), 0);
+-		mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6));
+-		mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6));
+-
+-		auxADC_Vmid = 0xA3;
+-		auxADC_Av = 0x0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av);
+-
+-		udelay(3);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x03);
+-
+-		udelay(5);
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-
+-		auxADC_Av = 0x7;
+-		if (radio_temp[1] + radio_temp2[1] < -30) {
+-			auxADC_Vmid = 0x45;
+-			auxADC_Vl = 263;
+-		} else if (radio_temp[1] + radio_temp2[1] < -9) {
+-			auxADC_Vmid = 0x200;
+-			auxADC_Vl = 467;
+-		} else if (radio_temp[1] + radio_temp2[1] < 11) {
+-			auxADC_Vmid = 0x266;
+-			auxADC_Vl = 634;
+-		} else {
+-			auxADC_Vmid = 0x2D5;
+-			auxADC_Vl = 816;
+-		}
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av);
+-
+-		udelay(3);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				tempsense_Rcal | 0x01);
+-
+-		udelay(5);
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-
+-		write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG,
+-				syn_tempprocsense_save);
+-
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-		write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save);
+-		write_phy_reg(pi, 0x346, RfctrlOverride5_save);
+-		write_phy_reg(pi, 0x347, RfctrlOverride6_save);
+-		write_phy_reg(pi, 0x344, RfctrlMiscReg5_save);
+-		write_phy_reg(pi, 0x345, RfctrlMiscReg5_save);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16,
+-					 &auxADC_Vmid_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16,
+-					 &auxADC_Av_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16,
+-					 &auxADC_rssi_ctrlL_save);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16,
+-					 &auxADC_rssi_ctrlH_save);
+-
+-		if (pi->sh->chip == BCM5357_CHIP_ID) {
+-			radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1])
+-					 + 88 * (auxADC_Vl) - 27111 +
+-					 128) / 256;
+-		} else if (pi->sh->chip == BCM43236_CHIP_ID) {
+-			radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1])
+-					 + 91 * (auxADC_Vl) - 27243 +
+-					 128) / 256;
+-		} else {
+-			radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1])
+-					 + 82 * (auxADC_Vl) - 28861 +
+-					 128) / 256;
+-		}
+-
+-		offset = (s16) pi->phy_tempsense_offset;
+-
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		syn_tempprocsense_save =
+-		    read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0x8f);
+-		afectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-		gpioSel_save = read_phy_reg(pi, 0xca);
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		} else {
+-			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05);
+-		}
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01);
+-		} else {
+-			write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01);
+-		}
+-
+-		radio_temp[0] =
+-		    (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64;
+-
+-		write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE,
+-				syn_tempprocsense_save);
+-
+-		write_phy_reg(pi, 0xca, gpioSel_save);
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0x8f, afectrlOverride_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride2_save);
+-
+-		offset = (s16) pi->phy_tempsense_offset;
+-	} else {
+-
+-		pwrdet_rxtx_core1_save =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+-		pwrdet_rxtx_core2_save =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+-		core1_txrf_iqcal1_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+-		core1_txrf_iqcal2_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+-		core2_txrf_iqcal1_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+-		core2_txrf_iqcal2_save =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+-		pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS);
+-
+-		afectrlCore1_save = read_phy_reg(pi, 0xa6);
+-		afectrlCore2_save = read_phy_reg(pi, 0xa7);
+-		afectrlOverride_save = read_phy_reg(pi, 0xa5);
+-		gpioSel_save = read_phy_reg(pi, 0xca);
+-
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+-		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1);
+-		xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80);
+-
+-		radio_temp[0] = (radio_temp[0] + radio_temp2[0]);
+-		radio_temp[1] = (radio_temp[1] + radio_temp2[1]);
+-		radio_temp[2] = (radio_temp[2] + radio_temp2[2]);
+-		radio_temp[3] = (radio_temp[3] + radio_temp2[3]);
+-
+-		radio_temp[0] =
+-		    (radio_temp[0] + radio_temp[1] + radio_temp[2] +
+-		     radio_temp[3]);
+-
+-		radio_temp[0] =
+-		    (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8);
+-
+-		radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38;
+-
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+-				pwrdet_rxtx_core1_save);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+-				pwrdet_rxtx_core2_save);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+-				core1_txrf_iqcal1_save);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+-				core2_txrf_iqcal1_save);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+-				core1_txrf_iqcal2_save);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+-				core2_txrf_iqcal2_save);
+-		write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save);
+-
+-		write_phy_reg(pi, 0xca, gpioSel_save);
+-		write_phy_reg(pi, 0xa6, afectrlCore1_save);
+-		write_phy_reg(pi, 0xa7, afectrlCore2_save);
+-		write_phy_reg(pi, 0xa5, afectrlOverride_save);
+-	}
+-
+-	return (s16) radio_temp[0] + offset;
+-}
+-
+-static void
+-wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf)
+-{
+-	u8 core;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (rssi_type == NPHY_RSSI_SEL_NB) {
+-			if (core == PHY_CORE_0) {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_B0_NBRSSI_VCM,
+-					      RADIO_2055_NBRSSI_VCM_I_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_NBRSSI_VCM_Q_MASK,
+-					      vcm_buf[2 * core +
+-						      1] <<
+-					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+-			} else {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_B0_NBRSSI_VCM,
+-					      RADIO_2055_NBRSSI_VCM_I_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_NBRSSI_VCM_I_SHIFT);
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_NBRSSI_VCM_Q_MASK,
+-					      vcm_buf[2 * core +
+-						      1] <<
+-					      RADIO_2055_NBRSSI_VCM_Q_SHIFT);
+-			}
+-		} else {
+-
+-			if (core == PHY_CORE_0) {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE1_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+-			} else {
+-				mod_radio_reg(pi,
+-					      RADIO_2055_CORE2_RXBB_RSSI_CTRL5,
+-					      RADIO_2055_WBRSSI_VCM_IQ_MASK,
+-					      vcm_buf[2 *
+-						      core] <<
+-					      RADIO_2055_WBRSSI_VCM_IQ_SHIFT);
+-			}
+-		}
+-	}
+-}
+-
+-void wlc_phy_rssi_cal_nphy(phy_info_t *pi)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		wlc_phy_rssi_cal_nphy_rev3(pi);
+-	} else {
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB);
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1);
+-		wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2);
+-	}
+-}
+-
+-static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type)
+-{
+-	s32 target_code;
+-	u16 classif_state;
+-	u16 clip_state[2];
+-	u16 rssi_ctrl_state[2], pd_state[2];
+-	u16 rfctrlintc_state[2], rfpdcorerxtx_state[2];
+-	u16 rfctrlintc_override_val;
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-	u16 rf_pd_val, pd_mask, rssi_ctrl_mask;
+-	u8 vcm, min_vcm, vcm_tmp[4];
+-	u8 vcm_final[4] = { 0, 0, 0, 0 };
+-	u8 result_idx, ctr;
+-	s32 poll_results[4][4] = {
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0}
+-	};
+-	s32 poll_miniq[4][2] = {
+-		{0, 0},
+-		{0, 0},
+-		{0, 0},
+-		{0, 0}
+-	};
+-	s32 min_d, curr_d;
+-	s32 fine_digital_offset[4];
+-	s32 poll_results_min[4] = { 0, 0, 0, 0 };
+-	s32 min_poll;
+-
+-	switch (rssi_type) {
+-	case NPHY_RSSI_SEL_NB:
+-		target_code = NPHY_RSSICAL_NB_TARGET;
+-		break;
+-	case NPHY_RSSI_SEL_W1:
+-		target_code = NPHY_RSSICAL_W1_TARGET;
+-		break;
+-	case NPHY_RSSI_SEL_W2:
+-		target_code = NPHY_RSSICAL_W2_TARGET;
+-		break;
+-	default:
+-		return;
+-		break;
+-	}
+-
+-	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-	wlc_phy_clip_det_nphy(pi, 0, clip_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-
+-	rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4;
+-	rfctrlintc_override_val =
+-	    CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110;
+-
+-	rfctrlintc_state[0] = read_phy_reg(pi, 0x91);
+-	rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX);
+-	write_phy_reg(pi, 0x91, rfctrlintc_override_val);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val);
+-
+-	rfctrlintc_state[1] = read_phy_reg(pi, 0x92);
+-	rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX);
+-	write_phy_reg(pi, 0x92, rfctrlintc_override_val);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val);
+-
+-	pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD |
+-	    RADIO_2055_WBRSSI_G2_PD;
+-	pd_state[0] =
+-	    read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask;
+-	pd_state[1] =
+-	    read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask;
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0);
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0);
+-	rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL |
+-	    RADIO_2055_WBRSSI_G2_SEL;
+-	rssi_ctrl_state[0] =
+-	    read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask;
+-	rssi_ctrl_state[1] =
+-	    read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask;
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type);
+-
+-	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+-				       NPHY_RAIL_I, rssi_type);
+-	wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX,
+-				       NPHY_RAIL_Q, rssi_type);
+-
+-	for (vcm = 0; vcm < 4; vcm++) {
+-
+-		vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm;
+-		if (rssi_type != NPHY_RSSI_SEL_W2) {
+-			wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp);
+-		}
+-
+-		wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0],
+-				       NPHY_RSSICAL_NPOLL);
+-
+-		if ((rssi_type == NPHY_RSSI_SEL_W1)
+-		    || (rssi_type == NPHY_RSSI_SEL_W2)) {
+-			for (ctr = 0; ctr < 2; ctr++) {
+-				poll_miniq[vcm][ctr] =
+-				    min(poll_results[vcm][ctr * 2 + 0],
+-					poll_results[vcm][ctr * 2 + 1]);
+-			}
+-		}
+-	}
+-
+-	for (result_idx = 0; result_idx < 4; result_idx++) {
+-		min_d = NPHY_RSSICAL_MAXD;
+-		min_vcm = 0;
+-		min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1;
+-		for (vcm = 0; vcm < 4; vcm++) {
+-			curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ?
+-				      poll_results[vcm][result_idx] :
+-				      poll_miniq[vcm][result_idx / 2]) -
+-				     (target_code * NPHY_RSSICAL_NPOLL));
+-			if (curr_d < min_d) {
+-				min_d = curr_d;
+-				min_vcm = vcm;
+-			}
+-			if (poll_results[vcm][result_idx] < min_poll) {
+-				min_poll = poll_results[vcm][result_idx];
+-			}
+-		}
+-		vcm_final[result_idx] = min_vcm;
+-		poll_results_min[result_idx] = min_poll;
+-	}
+-
+-	if (rssi_type != NPHY_RSSI_SEL_W2) {
+-		wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final);
+-	}
+-
+-	for (result_idx = 0; result_idx < 4; result_idx++) {
+-		fine_digital_offset[result_idx] =
+-		    (target_code * NPHY_RSSICAL_NPOLL) -
+-		    poll_results[vcm_final[result_idx]][result_idx];
+-		if (fine_digital_offset[result_idx] < 0) {
+-			fine_digital_offset[result_idx] =
+-			    ABS(fine_digital_offset[result_idx]);
+-			fine_digital_offset[result_idx] +=
+-			    (NPHY_RSSICAL_NPOLL / 2);
+-			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+-			fine_digital_offset[result_idx] =
+-			    -fine_digital_offset[result_idx];
+-		} else {
+-			fine_digital_offset[result_idx] +=
+-			    (NPHY_RSSICAL_NPOLL / 2);
+-			fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL;
+-		}
+-
+-		if (poll_results_min[result_idx] ==
+-		    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+-			fine_digital_offset[result_idx] =
+-			    (target_code - NPHY_RSSICAL_MAXREAD - 1);
+-		}
+-
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-					       (s8)
+-					       fine_digital_offset[result_idx],
+-					       (result_idx / 2 ==
+-						0) ? RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       (result_idx % 2 ==
+-						0) ? NPHY_RAIL_I : NPHY_RAIL_Q,
+-					       rssi_type);
+-	}
+-
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]);
+-	mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]);
+-	if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_NB);
+-	} else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W1);
+-	} else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W2);
+-	} else {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
+-				     NPHY_RSSI_SEL_W2);
+-	}
+-	if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_NB);
+-	} else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W1);
+-	} else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W2);
+-	} else {
+-		wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
+-				     NPHY_RSSI_SEL_W2);
+-	}
+-
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
+-
+-	write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]);
+-	write_phy_reg(pi, 0x92, rfctrlintc_state[1]);
+-	write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]);
+-
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_state);
+-
+-	wlc_phy_resetcca_nphy(pi);
+-}
+-
+-int
+-wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh)
+-{
+-	d11rxhdr_t *rxh = &wlc_rxh->rxhdr;
+-	s16 rxpwr, rxpwr0, rxpwr1;
+-	s16 phyRx0_l, phyRx2_l;
+-
+-	rxpwr = 0;
+-	rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK;
+-	rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8;
+-
+-	if (rxpwr0 > 127)
+-		rxpwr0 -= 256;
+-	if (rxpwr1 > 127)
+-		rxpwr1 -= 256;
+-
+-	phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff;
+-	phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff;
+-	if (phyRx2_l > 127)
+-		phyRx2_l -= 256;
+-
+-	if (((rxpwr0 == 16) || (rxpwr0 == 32))) {
+-		rxpwr0 = rxpwr1;
+-		rxpwr1 = phyRx2_l;
+-	}
+-
+-	wlc_rxh->rxpwr[0] = (s8) rxpwr0;
+-	wlc_rxh->rxpwr[1] = (s8) rxpwr1;
+-	wlc_rxh->do_rssi_ma = 0;
+-
+-	if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX)
+-		rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1;
+-	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN)
+-		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
+-	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
+-		rxpwr = (rxpwr0 + rxpwr1) >> 1;
+-
+-	return rxpwr;
+-}
+-
+-static void
+-wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value,
+-				 u8 core_code)
+-{
+-	u16 mask;
+-	u16 val;
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			if (core_code == RADIO_MIMO_CORESEL_CORE1
+-			    && core == PHY_CORE_1)
+-				continue;
+-			else if (core_code == RADIO_MIMO_CORESEL_CORE2
+-				 && core == PHY_CORE_0)
+-				continue;
+-
+-			if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-				mask = (0x1 << 10);
+-				val = 1 << 10;
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+-					    0x92, mask, val);
+-			}
+-
+-			if (field == NPHY_RfctrlIntc_override_OFF) {
+-
+-				write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 :
+-					      0x92, 0);
+-
+-				wlc_phy_force_rfseq_nphy(pi,
+-							 NPHY_RFSEQ_RESET2RX);
+-			} else if (field == NPHY_RfctrlIntc_override_TRSW) {
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-					mask = (0x1 << 6) | (0x1 << 7);
+-
+-					val = value << 6;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					or_phy_reg(pi,
+-						   (core ==
+-						    PHY_CORE_0) ? 0x91 : 0x92,
+-						   (0x1 << 10));
+-
+-					and_phy_reg(pi, 0x2ff, (u16)
+-						    ~(0x3 << 14));
+-					or_phy_reg(pi, 0x2ff, (0x1 << 13));
+-					or_phy_reg(pi, 0x2ff, (0x1 << 0));
+-				} else {
+-
+-					mask = (0x1 << 6) |
+-					    (0x1 << 7) |
+-					    (0x1 << 8) | (0x1 << 9);
+-					val = value << 6;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					mask = (0x1 << 0);
+-					val = 1 << 0;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xe7 : 0xec,
+-						    mask, val);
+-
+-					mask = (core == PHY_CORE_0) ? (0x1 << 0)
+-					    : (0x1 << 1);
+-					val = 1 << ((core == PHY_CORE_0) ?
+-						    0 : 1);
+-					mod_phy_reg(pi, 0x78, mask, val);
+-
+-					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
+-						  != 0), 10000);
+-					if (WARN(read_phy_reg(pi, 0x78) & val,
+-						"HW error: override failed"))
+-						return;
+-
+-					mask = (0x1 << 0);
+-					val = 0 << 0;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0xe7 : 0xec,
+-						    mask, val);
+-				}
+-			} else if (field == NPHY_RfctrlIntc_override_PA) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-					mask = (0x1 << 4) | (0x1 << 5);
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						val = value << 5;
+-					} else {
+-						val = value << 4;
+-					}
+-
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-
+-					or_phy_reg(pi,
+-						   (core ==
+-						    PHY_CORE_0) ? 0x91 : 0x92,
+-						   (0x1 << 12));
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 5);
+-						val = value << 5;
+-					} else {
+-						mask = (0x1 << 4);
+-						val = value << 4;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			} else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-						mask = (0x1 << 0);
+-						val = value << 0;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 2);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					} else {
+-
+-						mask = (0x1 << 2);
+-						val = value << 2;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 0);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					}
+-
+-					mask = (0x1 << 11);
+-					val = 1 << 11;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 0);
+-						val = value << 0;
+-					} else {
+-						mask = (0x1 << 2);
+-						val = value << 2;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			} else if (field ==
+-				   NPHY_RfctrlIntc_override_EXT_LNA_GAIN) {
+-				if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-						mask = (0x1 << 1);
+-						val = value << 1;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 3);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					} else {
+-
+-						mask = (0x1 << 3);
+-						val = value << 3;
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, val);
+-
+-						mask = (0x1 << 1);
+-						mod_phy_reg(pi,
+-							    (core ==
+-							     PHY_CORE_0) ? 0x91
+-							    : 0x92, mask, 0);
+-					}
+-
+-					mask = (0x1 << 11);
+-					val = 1 << 11;
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				} else {
+-
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						mask = (0x1 << 1);
+-						val = value << 1;
+-					} else {
+-						mask = (0x1 << 3);
+-						val = value << 3;
+-					}
+-					mod_phy_reg(pi,
+-						    (core ==
+-						     PHY_CORE_0) ? 0x91 : 0x92,
+-						    mask, val);
+-				}
+-			}
+-		}
+-	} else {
+-		return;
+-	}
+-}
+-
+-static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi)
+-{
+-	u16 classif_state;
+-	u16 clip_state[2];
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-	s32 target_code;
+-	u8 vcm, min_vcm;
+-	u8 vcm_final = 0;
+-	u8 result_idx;
+-	s32 poll_results[8][4] = {
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0},
+-		{0, 0, 0, 0}
+-	};
+-	s32 poll_result_core[4] = { 0, 0, 0, 0 };
+-	s32 min_d = NPHY_RSSICAL_MAXD, curr_d;
+-	s32 fine_digital_offset[4];
+-	s32 poll_results_min[4] = { 0, 0, 0, 0 };
+-	s32 min_poll;
+-	u8 vcm_level_max;
+-	u8 core;
+-	u8 wb_cnt;
+-	u8 rssi_type;
+-	u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save;
+-	u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save;
+-	u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save;
+-	u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save;
+-	u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save;
+-	u16 NPHY_RfctrlCmd_save;
+-	u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save;
+-	u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save;
+-	u8 rxcore_state;
+-	u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save;
+-	u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save;
+-	u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save;
+-	u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save;
+-
+-	NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save =
+-	    NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save =
+-	    NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save =
+-	    NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0;
+-
+-	classif_state = wlc_phy_classifier_nphy(pi, 0, 0);
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-	wlc_phy_clip_det_nphy(pi, 0, clip_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-
+-	NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91);
+-	NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92);
+-	NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f);
+-	NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5);
+-	NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6);
+-	NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7);
+-	NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7);
+-	NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342);
+-		NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343);
+-		NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346);
+-		NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347);
+-	}
+-	NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5);
+-	NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6);
+-	NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78);
+-	NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9);
+-	NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340);
+-		NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341);
+-		NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344);
+-		NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345);
+-	}
+-	NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a);
+-	NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d);
+-
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0,
+-					 RADIO_MIMO_CORESEL_ALLRXTX);
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1,
+-					 RADIO_MIMO_CORESEL_ALLRXTX);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxrf_pu,
+-						     0, 0, 0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rx_pu,
+-						     1, 0, 0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-						  1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0);
+-	}
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0,
+-							  0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0);
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0);
+-		}
+-
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0,
+-							  0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0);
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0);
+-		}
+-	}
+-
+-	rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+-
+-	vcm_level_max = 8;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((rxcore_state & (1 << core)) == 0)
+-			continue;
+-
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-					       core ==
+-					       PHY_CORE_0 ?
+-					       RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       NPHY_RAIL_I, NPHY_RSSI_SEL_NB);
+-		wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-					       core ==
+-					       PHY_CORE_0 ?
+-					       RADIO_MIMO_CORESEL_CORE1 :
+-					       RADIO_MIMO_CORESEL_CORE2,
+-					       NPHY_RAIL_Q, NPHY_RSSI_SEL_NB);
+-
+-		for (vcm = 0; vcm < vcm_level_max; vcm++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-				mod_radio_reg(pi, (core == PHY_CORE_0) ?
+-					      RADIO_2057_NB_MASTER_CORE0 :
+-					      RADIO_2057_NB_MASTER_CORE1,
+-					      RADIO_2057_VCM_MASK, vcm);
+-			} else {
+-
+-				mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+-					      ((core ==
+-						PHY_CORE_0) ? RADIO_2056_RX0 :
+-					       RADIO_2056_RX1),
+-					      RADIO_2056_VCM_MASK,
+-					      vcm << RADIO_2056_RSSI_VCM_SHIFT);
+-			}
+-
+-			wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB,
+-					       &poll_results[vcm][0],
+-					       NPHY_RSSICAL_NPOLL);
+-		}
+-
+-		for (result_idx = 0; result_idx < 4; result_idx++) {
+-			if ((core == result_idx / 2) && (result_idx % 2 == 0)) {
+-
+-				min_d = NPHY_RSSICAL_MAXD;
+-				min_vcm = 0;
+-				min_poll =
+-				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL +
+-				    1;
+-				for (vcm = 0; vcm < vcm_level_max; vcm++) {
+-					curr_d = poll_results[vcm][result_idx] *
+-					    poll_results[vcm][result_idx] +
+-					    poll_results[vcm][result_idx + 1] *
+-					    poll_results[vcm][result_idx + 1];
+-					if (curr_d < min_d) {
+-						min_d = curr_d;
+-						min_vcm = vcm;
+-					}
+-					if (poll_results[vcm][result_idx] <
+-					    min_poll) {
+-						min_poll =
+-						    poll_results[vcm]
+-						    [result_idx];
+-					}
+-				}
+-				vcm_final = min_vcm;
+-				poll_results_min[result_idx] = min_poll;
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, (core == PHY_CORE_0) ?
+-				      RADIO_2057_NB_MASTER_CORE0 :
+-				      RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK, vcm_final);
+-		} else {
+-			mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC |
+-				      ((core ==
+-					PHY_CORE_0) ? RADIO_2056_RX0 :
+-				       RADIO_2056_RX1), RADIO_2056_VCM_MASK,
+-				      vcm_final << RADIO_2056_RSSI_VCM_SHIFT);
+-		}
+-
+-		for (result_idx = 0; result_idx < 4; result_idx++) {
+-			if (core == result_idx / 2) {
+-				fine_digital_offset[result_idx] =
+-				    (NPHY_RSSICAL_NB_TARGET *
+-				     NPHY_RSSICAL_NPOLL) -
+-				    poll_results[vcm_final][result_idx];
+-				if (fine_digital_offset[result_idx] < 0) {
+-					fine_digital_offset[result_idx] =
+-					    ABS(fine_digital_offset
+-						[result_idx]);
+-					fine_digital_offset[result_idx] +=
+-					    (NPHY_RSSICAL_NPOLL / 2);
+-					fine_digital_offset[result_idx] /=
+-					    NPHY_RSSICAL_NPOLL;
+-					fine_digital_offset[result_idx] =
+-					    -fine_digital_offset[result_idx];
+-				} else {
+-					fine_digital_offset[result_idx] +=
+-					    (NPHY_RSSICAL_NPOLL / 2);
+-					fine_digital_offset[result_idx] /=
+-					    NPHY_RSSICAL_NPOLL;
+-				}
+-
+-				if (poll_results_min[result_idx] ==
+-				    NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) {
+-					fine_digital_offset[result_idx] =
+-					    (NPHY_RSSICAL_NB_TARGET -
+-					     NPHY_RSSICAL_MAXREAD - 1);
+-				}
+-
+-				wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-							       (s8)
+-							       fine_digital_offset
+-							       [result_idx],
+-							       (result_idx /
+-								2 ==
+-								0) ?
+-							       RADIO_MIMO_CORESEL_CORE1
+-							       :
+-							       RADIO_MIMO_CORESEL_CORE2,
+-							       (result_idx %
+-								2 ==
+-								0) ? NPHY_RAIL_I
+-							       : NPHY_RAIL_Q,
+-							       NPHY_RSSI_SEL_NB);
+-			}
+-		}
+-
+-	}
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((rxcore_state & (1 << core)) == 0)
+-			continue;
+-
+-		for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) {
+-			if (wb_cnt == 0) {
+-				rssi_type = NPHY_RSSI_SEL_W1;
+-				target_code = NPHY_RSSICAL_W1_TARGET_REV3;
+-			} else {
+-				rssi_type = NPHY_RSSI_SEL_W2;
+-				target_code = NPHY_RSSICAL_W2_TARGET_REV3;
+-			}
+-
+-			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-						       core ==
+-						       PHY_CORE_0 ?
+-						       RADIO_MIMO_CORESEL_CORE1
+-						       :
+-						       RADIO_MIMO_CORESEL_CORE2,
+-						       NPHY_RAIL_I, rssi_type);
+-			wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0,
+-						       core ==
+-						       PHY_CORE_0 ?
+-						       RADIO_MIMO_CORESEL_CORE1
+-						       :
+-						       RADIO_MIMO_CORESEL_CORE2,
+-						       NPHY_RAIL_Q, rssi_type);
+-
+-			wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core,
+-					       NPHY_RSSICAL_NPOLL);
+-
+-			for (result_idx = 0; result_idx < 4; result_idx++) {
+-				if (core == result_idx / 2) {
+-					fine_digital_offset[result_idx] =
+-					    (target_code * NPHY_RSSICAL_NPOLL) -
+-					    poll_result_core[result_idx];
+-					if (fine_digital_offset[result_idx] < 0) {
+-						fine_digital_offset[result_idx]
+-						    =
+-						    ABS(fine_digital_offset
+-							[result_idx]);
+-						fine_digital_offset[result_idx]
+-						    += (NPHY_RSSICAL_NPOLL / 2);
+-						fine_digital_offset[result_idx]
+-						    /= NPHY_RSSICAL_NPOLL;
+-						fine_digital_offset[result_idx]
+-						    =
+-						    -fine_digital_offset
+-						    [result_idx];
+-					} else {
+-						fine_digital_offset[result_idx]
+-						    += (NPHY_RSSICAL_NPOLL / 2);
+-						fine_digital_offset[result_idx]
+-						    /= NPHY_RSSICAL_NPOLL;
+-					}
+-
+-					wlc_phy_scale_offset_rssi_nphy(pi, 0x0,
+-								       (s8)
+-								       fine_digital_offset
+-								       [core *
+-									2],
+-								       (core ==
+-									PHY_CORE_0)
+-								       ?
+-								       RADIO_MIMO_CORESEL_CORE1
+-								       :
+-								       RADIO_MIMO_CORESEL_CORE2,
+-								       (result_idx
+-									% 2 ==
+-									0) ?
+-								       NPHY_RAIL_I
+-								       :
+-								       NPHY_RAIL_Q,
+-								       rssi_type);
+-				}
+-			}
+-
+-		}
+-	}
+-
+-	write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save);
+-	write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save);
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0xe7, (0x1 << 0), 0);
+-
+-	mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0);
+-	mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1);
+-	mod_phy_reg(pi, 0xec, (0x1 << 0), 0);
+-
+-	write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save);
+-	write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save);
+-	write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save);
+-	write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save);
+-	write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save);
+-	write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save);
+-		write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save);
+-		write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save);
+-		write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save);
+-	}
+-	write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save);
+-	write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save);
+-	write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save);
+-	write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save);
+-	write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save);
+-		write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save);
+-		write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save);
+-		write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save);
+-	}
+-	write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save);
+-	write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			pi->rssical_cache.rssical_radio_regs_2G[0] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+-			pi->rssical_cache.rssical_radio_regs_2G[1] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+-		} else {
+-			pi->rssical_cache.rssical_radio_regs_2G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX0);
+-			pi->rssical_cache.rssical_radio_regs_2G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX1);
+-		}
+-
+-		pi->rssical_cache.rssical_phyregs_2G[0] =
+-		    read_phy_reg(pi, 0x1a6);
+-		pi->rssical_cache.rssical_phyregs_2G[1] =
+-		    read_phy_reg(pi, 0x1ac);
+-		pi->rssical_cache.rssical_phyregs_2G[2] =
+-		    read_phy_reg(pi, 0x1b2);
+-		pi->rssical_cache.rssical_phyregs_2G[3] =
+-		    read_phy_reg(pi, 0x1b8);
+-		pi->rssical_cache.rssical_phyregs_2G[4] =
+-		    read_phy_reg(pi, 0x1a4);
+-		pi->rssical_cache.rssical_phyregs_2G[5] =
+-		    read_phy_reg(pi, 0x1aa);
+-		pi->rssical_cache.rssical_phyregs_2G[6] =
+-		    read_phy_reg(pi, 0x1b0);
+-		pi->rssical_cache.rssical_phyregs_2G[7] =
+-		    read_phy_reg(pi, 0x1b6);
+-		pi->rssical_cache.rssical_phyregs_2G[8] =
+-		    read_phy_reg(pi, 0x1a5);
+-		pi->rssical_cache.rssical_phyregs_2G[9] =
+-		    read_phy_reg(pi, 0x1ab);
+-		pi->rssical_cache.rssical_phyregs_2G[10] =
+-		    read_phy_reg(pi, 0x1b1);
+-		pi->rssical_cache.rssical_phyregs_2G[11] =
+-		    read_phy_reg(pi, 0x1b7);
+-
+-		pi->nphy_rssical_chanspec_2G = pi->radio_chanspec;
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			pi->rssical_cache.rssical_radio_regs_5G[0] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0);
+-			pi->rssical_cache.rssical_radio_regs_5G[1] =
+-			    read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1);
+-		} else {
+-			pi->rssical_cache.rssical_radio_regs_5G[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX0);
+-			pi->rssical_cache.rssical_radio_regs_5G[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RSSI_MISC |
+-					   RADIO_2056_RX1);
+-		}
+-
+-		pi->rssical_cache.rssical_phyregs_5G[0] =
+-		    read_phy_reg(pi, 0x1a6);
+-		pi->rssical_cache.rssical_phyregs_5G[1] =
+-		    read_phy_reg(pi, 0x1ac);
+-		pi->rssical_cache.rssical_phyregs_5G[2] =
+-		    read_phy_reg(pi, 0x1b2);
+-		pi->rssical_cache.rssical_phyregs_5G[3] =
+-		    read_phy_reg(pi, 0x1b8);
+-		pi->rssical_cache.rssical_phyregs_5G[4] =
+-		    read_phy_reg(pi, 0x1a4);
+-		pi->rssical_cache.rssical_phyregs_5G[5] =
+-		    read_phy_reg(pi, 0x1aa);
+-		pi->rssical_cache.rssical_phyregs_5G[6] =
+-		    read_phy_reg(pi, 0x1b0);
+-		pi->rssical_cache.rssical_phyregs_5G[7] =
+-		    read_phy_reg(pi, 0x1b6);
+-		pi->rssical_cache.rssical_phyregs_5G[8] =
+-		    read_phy_reg(pi, 0x1a5);
+-		pi->rssical_cache.rssical_phyregs_5G[9] =
+-		    read_phy_reg(pi, 0x1ab);
+-		pi->rssical_cache.rssical_phyregs_5G[10] =
+-		    read_phy_reg(pi, 0x1b1);
+-		pi->rssical_cache.rssical_phyregs_5G[11] =
+-		    read_phy_reg(pi, 0x1b7);
+-
+-		pi->nphy_rssical_chanspec_5G = pi->radio_chanspec;
+-	}
+-
+-	wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state);
+-	wlc_phy_clip_det_nphy(pi, 1, clip_state);
+-}
+-
+-static void wlc_phy_restore_rssical_nphy(phy_info_t *pi)
+-{
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		if (pi->nphy_rssical_chanspec_2G == 0)
+-			return;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[0]);
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[1]);
+-		} else {
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[0]);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_2G[1]);
+-		}
+-
+-		write_phy_reg(pi, 0x1a6,
+-			      pi->rssical_cache.rssical_phyregs_2G[0]);
+-		write_phy_reg(pi, 0x1ac,
+-			      pi->rssical_cache.rssical_phyregs_2G[1]);
+-		write_phy_reg(pi, 0x1b2,
+-			      pi->rssical_cache.rssical_phyregs_2G[2]);
+-		write_phy_reg(pi, 0x1b8,
+-			      pi->rssical_cache.rssical_phyregs_2G[3]);
+-		write_phy_reg(pi, 0x1a4,
+-			      pi->rssical_cache.rssical_phyregs_2G[4]);
+-		write_phy_reg(pi, 0x1aa,
+-			      pi->rssical_cache.rssical_phyregs_2G[5]);
+-		write_phy_reg(pi, 0x1b0,
+-			      pi->rssical_cache.rssical_phyregs_2G[6]);
+-		write_phy_reg(pi, 0x1b6,
+-			      pi->rssical_cache.rssical_phyregs_2G[7]);
+-		write_phy_reg(pi, 0x1a5,
+-			      pi->rssical_cache.rssical_phyregs_2G[8]);
+-		write_phy_reg(pi, 0x1ab,
+-			      pi->rssical_cache.rssical_phyregs_2G[9]);
+-		write_phy_reg(pi, 0x1b1,
+-			      pi->rssical_cache.rssical_phyregs_2G[10]);
+-		write_phy_reg(pi, 0x1b7,
+-			      pi->rssical_cache.rssical_phyregs_2G[11]);
+-
+-	} else {
+-		if (pi->nphy_rssical_chanspec_5G == 0)
+-			return;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[0]);
+-			mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1,
+-				      RADIO_2057_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[1]);
+-		} else {
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[0]);
+-			mod_radio_reg(pi,
+-				      RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1,
+-				      RADIO_2056_VCM_MASK,
+-				      pi->rssical_cache.
+-				      rssical_radio_regs_5G[1]);
+-		}
+-
+-		write_phy_reg(pi, 0x1a6,
+-			      pi->rssical_cache.rssical_phyregs_5G[0]);
+-		write_phy_reg(pi, 0x1ac,
+-			      pi->rssical_cache.rssical_phyregs_5G[1]);
+-		write_phy_reg(pi, 0x1b2,
+-			      pi->rssical_cache.rssical_phyregs_5G[2]);
+-		write_phy_reg(pi, 0x1b8,
+-			      pi->rssical_cache.rssical_phyregs_5G[3]);
+-		write_phy_reg(pi, 0x1a4,
+-			      pi->rssical_cache.rssical_phyregs_5G[4]);
+-		write_phy_reg(pi, 0x1aa,
+-			      pi->rssical_cache.rssical_phyregs_5G[5]);
+-		write_phy_reg(pi, 0x1b0,
+-			      pi->rssical_cache.rssical_phyregs_5G[6]);
+-		write_phy_reg(pi, 0x1b6,
+-			      pi->rssical_cache.rssical_phyregs_5G[7]);
+-		write_phy_reg(pi, 0x1a5,
+-			      pi->rssical_cache.rssical_phyregs_5G[8]);
+-		write_phy_reg(pi, 0x1ab,
+-			      pi->rssical_cache.rssical_phyregs_5G[9]);
+-		write_phy_reg(pi, 0x1b1,
+-			      pi->rssical_cache.rssical_phyregs_5G[10]);
+-		write_phy_reg(pi, 0x1b7,
+-			      pi->rssical_cache.rssical_phyregs_5G[11]);
+-	}
+-}
+-
+-static u16
+-wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-			      u8 dac_test_mode)
+-{
+-	u8 phy_bw, is_phybw40;
+-	u16 num_samps, t, spur;
+-	fixed theta = 0, rot = 0;
+-	u32 tbl_len;
+-	cs32 *tone_buf = NULL;
+-
+-	is_phybw40 = CHSPEC_IS40(pi->radio_chanspec);
+-	phy_bw = (is_phybw40 == 1) ? 40 : 20;
+-	tbl_len = (phy_bw << 3);
+-
+-	if (dac_test_mode == 1) {
+-		spur = read_phy_reg(pi, 0x01);
+-		spur = (spur >> 15) & 1;
+-		phy_bw = (spur == 1) ? 82 : 80;
+-		phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw;
+-
+-		tbl_len = (phy_bw << 1);
+-	}
+-
+-	tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC);
+-	if (tone_buf == NULL) {
+-		return 0;
+-	}
+-
+-	num_samps = (u16) tbl_len;
+-	rot = FIXED((f_kHz * 36) / phy_bw) / 100;
+-	theta = 0;
+-
+-	for (t = 0; t < num_samps; t++) {
+-
+-		wlc_phy_cordic(theta, &tone_buf[t]);
+-
+-		theta += rot;
+-
+-		tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val);
+-		tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val);
+-	}
+-
+-	wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps);
+-
+-	kfree(tone_buf);
+-
+-	return num_samps;
+-}
+-
+-int
+-wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val,
+-		     u8 iqmode, u8 dac_test_mode, bool modify_bbmult)
+-{
+-	u16 num_samps;
+-	u16 loops = 0xffff;
+-	u16 wait = 0;
+-
+-	num_samps =
+-		wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode);
+-	if (num_samps == 0) {
+-		return -EBADE;
+-	}
+-
+-	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
+-				dac_test_mode, modify_bbmult);
+-
+-	return 0;
+-}
+-
+-static void
+-wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf,
+-			     u16 num_samps)
+-{
+-	u16 t;
+-	u32 *data_buf = NULL;
+-
+-	data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC);
+-	if (data_buf == NULL) {
+-		return;
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	for (t = 0; t < num_samps; t++) {
+-		data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) |
+-		    (((unsigned int)tone_buf[t].q) & 0x3ff);
+-	}
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32,
+-				 data_buf);
+-
+-	kfree(data_buf);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void
+-wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops,
+-			u16 wait, u8 iqmode, u8 dac_test_mode,
+-			bool modify_bbmult)
+-{
+-	u16 bb_mult;
+-	u8 phy_bw, sample_cmd;
+-	u16 orig_RfseqCoreActv;
+-	u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3,
+-	    lpf_bw_ctl_miscreg4;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	phy_bw = 20;
+-	if (CHSPEC_IS40(pi->radio_chanspec))
+-		phy_bw = 40;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7);
+-		lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7);
+-		if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) {
+-			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+-			    (0x7 << 8);
+-			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+-			    (0x7 << 8);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-			pi->nphy_sample_play_lpf_bw_ctl_ovr = true;
+-
+-			lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) &
+-			    (0x7 << 8);
+-			lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) &
+-			    (0x7 << 8);
+-		}
+-	}
+-
+-	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) {
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					&bb_mult);
+-		pi->nphy_bb_mult_save =
+-		    BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK);
+-	}
+-
+-	if (modify_bbmult) {
+-		bb_mult = (phy_bw == 20) ? 100 : 71;
+-		bb_mult = (bb_mult << 8) + bb_mult;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					 &bb_mult);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	write_phy_reg(pi, 0xc6, num_samps - 1);
+-
+-	if (loops != 0xffff) {
+-		write_phy_reg(pi, 0xc4, loops - 1);
+-	} else {
+-		write_phy_reg(pi, 0xc4, loops);
+-	}
+-	write_phy_reg(pi, 0xc5, wait);
+-
+-	orig_RfseqCoreActv = read_phy_reg(pi, 0xa1);
+-	or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override);
+-	if (iqmode) {
+-
+-		and_phy_reg(pi, 0xc2, 0x7FFF);
+-
+-		or_phy_reg(pi, 0xc2, 0x8000);
+-	} else {
+-
+-		sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1;
+-		write_phy_reg(pi, 0xc3, sample_cmd);
+-	}
+-
+-	SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000);
+-
+-	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
+-}
+-
+-void wlc_phy_stopplayback_nphy(phy_info_t *pi)
+-{
+-	u16 playback_status;
+-	u16 bb_mult;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	playback_status = read_phy_reg(pi, 0xc7);
+-	if (playback_status & 0x1) {
+-		or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP);
+-	} else if (playback_status & 0x2) {
+-
+-		and_phy_reg(pi, 0xc2,
+-			    (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN);
+-	}
+-
+-	and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2));
+-
+-	if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) {
+-
+-		bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16,
+-					 &bb_mult);
+-
+-		pi->nphy_bb_mult_save = 0;
+-	}
+-
+-	if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-		if (pi->nphy_sample_play_lpf_bw_ctl_ovr) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  0, 0, 1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-			pi->nphy_sample_play_lpf_bw_ctl_ovr = false;
+-		}
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi)
+-{
+-	u16 base_idx[2], curr_gain[2];
+-	u8 core_no;
+-	nphy_txgains_t target_gain;
+-	u32 *tx_pwrctrl_tbl = NULL;
+-
+-	if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) {
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-					curr_gain);
+-
+-		if (pi->phyhang_avoid)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-		for (core_no = 0; core_no < 2; core_no++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x0007;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x00F8) >> 3);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0F00) >> 8);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x7000) >> 12);
+-				target_gain.txlpf[core_no] =
+-				    ((curr_gain[core_no] & 0x8000) >> 15);
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x000F;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x00F0) >> 4);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0F00) >> 8);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x7000) >> 12);
+-			} else {
+-				target_gain.ipa[core_no] =
+-				    curr_gain[core_no] & 0x0003;
+-				target_gain.pad[core_no] =
+-				    ((curr_gain[core_no] & 0x000C) >> 2);
+-				target_gain.pga[core_no] =
+-				    ((curr_gain[core_no] & 0x0070) >> 4);
+-				target_gain.txgm[core_no] =
+-				    ((curr_gain[core_no] & 0x0380) >> 7);
+-			}
+-		}
+-	} else {
+-		base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f;
+-		base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f;
+-		for (core_no = 0; core_no < 2; core_no++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				if (PHY_IPA(pi)) {
+-					tx_pwrctrl_tbl =
+-					    wlc_phy_get_ipa_gaintbl_nphy(pi);
+-				} else {
+-					if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-						if NREV_IS
+-							(pi->pubpi.phy_rev, 3) {
+-							tx_pwrctrl_tbl =
+-							    nphy_tpc_5GHz_txgain_rev3;
+-						} else if NREV_IS
+-							(pi->pubpi.phy_rev, 4) {
+-							tx_pwrctrl_tbl =
+-							    (pi->srom_fem5g.
+-							     extpagain ==
+-							     3) ?
+-							    nphy_tpc_5GHz_txgain_HiPwrEPA
+-							    :
+-							    nphy_tpc_5GHz_txgain_rev4;
+-						} else {
+-							tx_pwrctrl_tbl =
+-							    nphy_tpc_5GHz_txgain_rev5;
+-						}
+-					} else {
+-						if (NREV_GE
+-						    (pi->pubpi.phy_rev, 7)) {
+-							if (pi->pubpi.
+-							    radiorev == 3) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_epa_2057rev3;
+-							} else if (pi->pubpi.
+-								   radiorev ==
+-								   5) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_epa_2057rev5;
+-							}
+-
+-						} else {
+-							if (NREV_GE
+-							    (pi->pubpi.phy_rev,
+-							     5)
+-							    && (pi->srom_fem2g.
+-								extpagain ==
+-								3)) {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_HiPwrEPA;
+-							} else {
+-								tx_pwrctrl_tbl =
+-								    nphy_tpc_txgain_rev3;
+-							}
+-						}
+-					}
+-				}
+-				if NREV_GE
+-					(pi->pubpi.phy_rev, 7) {
+-					target_gain.ipa[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 16) & 0x7;
+-					target_gain.pad[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 19) & 0x1f;
+-					target_gain.pga[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 24) & 0xf;
+-					target_gain.txgm[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 28) & 0x7;
+-					target_gain.txlpf[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 31) & 0x1;
+-				} else {
+-					target_gain.ipa[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 16) & 0xf;
+-					target_gain.pad[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 20) & 0xf;
+-					target_gain.pga[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 24) & 0xf;
+-					target_gain.txgm[core_no] =
+-					    (tx_pwrctrl_tbl[base_idx[core_no]]
+-					     >> 28) & 0x7;
+-				}
+-			} else {
+-				target_gain.ipa[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 16) &
+-				    0x3;
+-				target_gain.pad[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 18) &
+-				    0x3;
+-				target_gain.pga[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 20) &
+-				    0x7;
+-				target_gain.txgm[core_no] =
+-				    (nphy_tpc_txgain[base_idx[core_no]] >> 23) &
+-				    0x7;
+-			}
+-		}
+-	}
+-
+-	return target_gain;
+-}
+-
+-static void
+-wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no,
+-			      nphy_txgains_t target_gain,
+-			      nphy_iqcal_params_t *params)
+-{
+-	u8 k;
+-	int idx;
+-	u16 gain_index;
+-	u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			params->txlpf = target_gain.txlpf[core_no];
+-		}
+-		params->txgm = target_gain.txgm[core_no];
+-		params->pga = target_gain.pga[core_no];
+-		params->pad = target_gain.pad[core_no];
+-		params->ipa = target_gain.ipa[core_no];
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			params->cal_gain =
+-			    ((params->txlpf << 15) | (params->
+-						      txgm << 12) | (params->
+-								     pga << 8) |
+-			     (params->pad << 3) | (params->ipa));
+-		} else {
+-			params->cal_gain =
+-			    ((params->txgm << 12) | (params->
+-						     pga << 8) | (params->
+-								  pad << 4) |
+-			     (params->ipa));
+-		}
+-		params->ncorr[0] = 0x79;
+-		params->ncorr[1] = 0x79;
+-		params->ncorr[2] = 0x79;
+-		params->ncorr[3] = 0x79;
+-		params->ncorr[4] = 0x79;
+-	} else {
+-
+-		gain_index = ((target_gain.pad[core_no] << 0) |
+-			      (target_gain.pga[core_no] << 4) | (target_gain.
+-								 txgm[core_no]
+-								 << 8));
+-
+-		idx = -1;
+-		for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) {
+-			if (tbl_iqcal_gainparams_nphy[band_idx][k][0] ==
+-			    gain_index) {
+-				idx = k;
+-				break;
+-			}
+-		}
+-
+-		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
+-		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
+-		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
+-		params->cal_gain = ((params->txgm << 7) | (params->pga << 4) |
+-				    (params->pad << 2));
+-		params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4];
+-		params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5];
+-		params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6];
+-		params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7];
+-	}
+-}
+-
+-static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi)
+-{
+-	u16 jtag_core, core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		for (core = 0; core <= 1; core++) {
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TX_SSI_MASTER);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    IQCAL_VCM_HG);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    IQCAL_IDAC);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0;
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TX_SSI_MUX);
+-
+-			if (pi->pubpi.radiorev != 5)
+-				pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+-				    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						    TSSIA);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TSSI_MISC1);
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x0a);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_VCM_HG, 0x43);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_IDAC, 0x55);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_VCM, 0x00);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIG, 0x00);
+-				if (pi->use_int_tx_iqlo_cal_nphy) {
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TX_SSI_MUX, 0x4);
+-					if (!
+-					    (pi->
+-					     internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x31);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x21);
+-					}
+-				}
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_MISC1, 0x00);
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x06);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_VCM_HG, 0x43);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 IQCAL_IDAC, 0x55);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_VCM, 0x00);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIA, 0x00);
+-				if (pi->use_int_tx_iqlo_cal_nphy) {
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TX_SSI_MUX,
+-							 0x06);
+-					if (!
+-					    (pi->
+-					     internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIG, 0x31);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIG, 0x21);
+-					}
+-				}
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSI_MISC1, 0x00);
+-			}
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		for (core = 0; core <= 1; core++) {
+-			jtag_core =
+-			    (core ==
+-			     PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_SSI_MASTER |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_IQCAL_VCM_HG |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_IQCAL_IDAC |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_VCM | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_AMP_DET |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TX_SSI_MUX |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] =
+-			    read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] =
+-			    read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC1 |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC2 |
+-					   jtag_core);
+-
+-			pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_TSSI_MISC3 |
+-					   jtag_core);
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MASTER |
+-						jtag_core, 0x0a);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_VCM_HG |
+-						jtag_core, 0x40);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_IDAC |
+-						jtag_core, 0x55);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_VCM |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_AMP_DET |
+-						jtag_core, 0x00);
+-
+-				if (PHY_IPA(pi)) {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x4);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIA |
+-							jtag_core, 0x1);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x00);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIA |
+-							jtag_core, 0x2f);
+-				}
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSIG | jtag_core,
+-						0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC1 |
+-						jtag_core, 0x00);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC2 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC3 |
+-						jtag_core, 0x00);
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MASTER |
+-						jtag_core, 0x06);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_VCM_HG |
+-						jtag_core, 0x40);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_IQCAL_IDAC |
+-						jtag_core, 0x55);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_VCM |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_AMP_DET |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSIA | jtag_core,
+-						0x00);
+-
+-				if (PHY_IPA(pi)) {
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x06);
+-					if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-
+-						write_radio_reg(pi,
+-								RADIO_2056_TX_TSSIG
+-								| jtag_core,
+-								0x11);
+-					} else {
+-
+-						write_radio_reg(pi,
+-								RADIO_2056_TX_TSSIG
+-								| jtag_core,
+-								0x1);
+-					}
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TX_SSI_MUX
+-							| jtag_core, 0x00);
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TSSIG |
+-							jtag_core, 0x20);
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC1 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC2 |
+-						jtag_core, 0x00);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TSSI_MISC3 |
+-						jtag_core, 0x00);
+-			}
+-		}
+-	} else {
+-
+-		pi->tx_rx_cal_radio_saveregs[0] =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29);
+-		pi->tx_rx_cal_radio_saveregs[1] =
+-		    read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54);
+-
+-		pi->tx_rx_cal_radio_saveregs[2] =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29);
+-		pi->tx_rx_cal_radio_saveregs[3] =
+-		    read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54);
+-
+-		pi->tx_rx_cal_radio_saveregs[4] =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1);
+-		pi->tx_rx_cal_radio_saveregs[5] =
+-		    read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2);
+-
+-		if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) ==
+-		    0) {
+-
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04);
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04);
+-		} else {
+-
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20);
+-			write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20);
+-		}
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-			or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20);
+-			or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20);
+-		} else {
+-
+-			and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf);
+-			and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi)
+-{
+-	u16 jtag_core, core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (core = 0; core <= 1; core++) {
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TX_SSI_MASTER,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  0]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  1]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  2]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  3]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  5]);
+-
+-			if (pi->pubpi.radiorev != 5)
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIA,
+-						 pi->
+-						 tx_rx_cal_radio_saveregs[(core
+-									   *
+-									   11) +
+-									  6]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  7]);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+-					 pi->
+-					 tx_rx_cal_radio_saveregs[(core * 11) +
+-								  8]);
+-		}
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		for (core = 0; core <= 1; core++) {
+-			jtag_core =
+-			    (core ==
+-			     PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_SSI_MASTER | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_IQCAL_VCM_HG | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 1]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_IQCAL_IDAC | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 2]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 3]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_AMP_DET | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 4]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TX_SSI_MUX | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 5]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 6]);
+-
+-			write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 7]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC1 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 8]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC2 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 9]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_TSSI_MISC3 | jtag_core,
+-					pi->
+-					tx_rx_cal_radio_saveregs[(core * 11) +
+-								 10]);
+-		}
+-	} else {
+-
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1,
+-				pi->tx_rx_cal_radio_saveregs[0]);
+-		write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2,
+-				pi->tx_rx_cal_radio_saveregs[1]);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1,
+-				pi->tx_rx_cal_radio_saveregs[2]);
+-		write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2,
+-				pi->tx_rx_cal_radio_saveregs[3]);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1,
+-				pi->tx_rx_cal_radio_saveregs[4]);
+-		write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2,
+-				pi->tx_rx_cal_radio_saveregs[5]);
+-	}
+-}
+-
+-static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi)
+-{
+-	u16 val, mask;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+-		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+-
+-		mask = ((0x3 << 8) | (0x3 << 10));
+-		val = (0x2 << 8);
+-		val |= (0x2 << 10);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		val = read_phy_reg(pi, 0x8f);
+-		pi->tx_rx_cal_phy_saveregs[2] = val;
+-		val |= ((0x1 << 9) | (0x1 << 10));
+-		write_phy_reg(pi, 0x8f, val);
+-
+-		val = read_phy_reg(pi, 0xa5);
+-		pi->tx_rx_cal_phy_saveregs[3] = val;
+-		val |= ((0x1 << 9) | (0x1 << 10));
+-		write_phy_reg(pi, 0xa5, val);
+-
+-		pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01);
+-		mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[5] = val;
+-		val = 0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					 &val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[6] = val;
+-		val = 0;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					 &val);
+-
+-		pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91);
+-		pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92);
+-
+-		if (!(pi->use_int_tx_iqlo_cal_nphy)) {
+-
+-			wlc_phy_rfctrlintc_override_nphy(pi,
+-							 NPHY_RfctrlIntc_override_PA,
+-							 1,
+-							 RADIO_MIMO_CORESEL_CORE1
+-							 |
+-							 RADIO_MIMO_CORESEL_CORE2);
+-		} else {
+-
+-			wlc_phy_rfctrlintc_override_nphy(pi,
+-							 NPHY_RfctrlIntc_override_PA,
+-							 0,
+-							 RADIO_MIMO_CORESEL_CORE1
+-							 |
+-							 RADIO_MIMO_CORESEL_CORE2);
+-		}
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x2, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x8, RADIO_MIMO_CORESEL_CORE2);
+-
+-		pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+-		pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		if (pi->use_int_tx_iqlo_cal_nphy
+-		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+-					      1 << 4);
+-
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-						      1, 0);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-						      1, 0);
+-				} else {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+-						      1, 0);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+-						      1, 0);
+-				}
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-				wlc_phy_rfctrl_override_nphy_rev7(pi,
+-								  (0x1 << 3), 0,
+-								  0x3, 0,
+-								  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			}
+-		}
+-	} else {
+-		pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6);
+-		pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7);
+-
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		val = (0x2 << 12);
+-		val |= (0x2 << 14);
+-		mod_phy_reg(pi, 0xa6, mask, val);
+-		mod_phy_reg(pi, 0xa7, mask, val);
+-
+-		val = read_phy_reg(pi, 0xa5);
+-		pi->tx_rx_cal_phy_saveregs[2] = val;
+-		val |= ((0x1 << 12) | (0x1 << 13));
+-		write_phy_reg(pi, 0xa5, val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[3] = val;
+-		val |= 0x2000;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					 &val);
+-
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					&val);
+-		pi->tx_rx_cal_phy_saveregs[4] = val;
+-		val |= 0x2000;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					 &val);
+-
+-		pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91);
+-		pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92);
+-		val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120;
+-		write_phy_reg(pi, 0x91, val);
+-		write_phy_reg(pi, 0x92, val);
+-	}
+-}
+-
+-static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi)
+-{
+-	u16 mask;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]);
+-		write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]);
+-		write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]);
+-		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]);
+-		write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[5]);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[6]);
+-
+-		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]);
+-		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]);
+-
+-		write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+-		write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+-							  1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-		if (pi->use_int_tx_iqlo_cal_nphy
+-		    && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) {
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 7)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE0,
+-						      1, 1);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_PAD2G_TUNE_PUS_CORE1,
+-						      1, 1);
+-				} else {
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE0,
+-						      1, 1);
+-					mod_radio_reg(pi,
+-						      RADIO_2057_IPA5G_CASCOFFV_PU_CORE1,
+-						      1, 1);
+-				}
+-
+-				mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4,
+-					      0);
+-			} else if (NREV_GE(pi->pubpi.phy_rev, 8)) {
+-				wlc_phy_rfctrl_override_nphy_rev7(pi,
+-								  (0x1 << 3), 0,
+-								  0x3, 1,
+-								  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-			}
+-		}
+-	} else {
+-		mask = ((0x3 << 12) | (0x3 << 14));
+-		mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]);
+-		mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]);
+-		write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[3]);
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16,
+-					 &pi->tx_rx_cal_phy_saveregs[4]);
+-
+-		write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]);
+-		write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]);
+-	}
+-}
+-
+-#define NPHY_CAL_TSSISAMPS	64
+-#define NPHY_TEST_TONE_FREQ_40MHz 4000
+-#define NPHY_TEST_TONE_FREQ_20MHz 2500
+-
+-void
+-wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps)
+-{
+-	u16 tssi_reg;
+-	s32 temp, pwrindex[2];
+-	s32 idle_tssi[2];
+-	s32 rssi_buf[4];
+-	s32 tssival[2];
+-	u8 tssi_type;
+-
+-	tssi_reg = read_phy_reg(pi, 0x1e9);
+-
+-	temp = (s32) (tssi_reg & 0x3f);
+-	idle_tssi[0] = (temp <= 31) ? temp : (temp - 64);
+-
+-	temp = (s32) ((tssi_reg >> 8) & 0x3f);
+-	idle_tssi[1] = (temp <= 31) ? temp : (temp - 64);
+-
+-	tssi_type =
+-	    CHSPEC_IS5G(pi->radio_chanspec) ?
+-	    (u8)NPHY_RSSI_SEL_TSSI_5G:(u8)NPHY_RSSI_SEL_TSSI_2G;
+-
+-	wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps);
+-
+-	tssival[0] = rssi_buf[0] / ((s32) num_samps);
+-	tssival[1] = rssi_buf[2] / ((s32) num_samps);
+-
+-	pwrindex[0] = idle_tssi[0] - tssival[0] + 64;
+-	pwrindex[1] = idle_tssi[1] - tssival[1] + 64;
+-
+-	if (pwrindex[0] < 0) {
+-		pwrindex[0] = 0;
+-	} else if (pwrindex[0] > 63) {
+-		pwrindex[0] = 63;
+-	}
+-
+-	if (pwrindex[1] < 0) {
+-		pwrindex[1] = 0;
+-	} else if (pwrindex[1] > 63) {
+-		pwrindex[1] = 63;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1,
+-				(u32) pwrindex[0], 32, &qdBm_pwrbuf[0]);
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1,
+-				(u32) pwrindex[1], 32, &qdBm_pwrbuf[1]);
+-}
+-
+-static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi)
+-{
+-	u16 txcal_gain[2];
+-
+-	pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0];
+-	pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0];
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				txcal_gain);
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40;
+-		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40;
+-	} else {
+-		txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60;
+-		txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 txcal_gain);
+-}
+-
+-static void wlc_phy_precal_txgain_nphy(phy_info_t *pi)
+-{
+-	bool save_bbmult = false;
+-	u8 txcal_index_2057_rev5n7 = 0;
+-	u8 txcal_index_2057_rev3n4n6 = 10;
+-
+-	if (pi->use_int_tx_iqlo_cal_nphy) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				pi->nphy_txcal_pwr_idx[0] =
+-				    txcal_index_2057_rev3n4n6;
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    txcal_index_2057_rev3n4n6;
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 txcal_index_2057_rev3n4n6,
+-							 false);
+-			} else {
+-
+-				pi->nphy_txcal_pwr_idx[0] =
+-				    txcal_index_2057_rev5n7;
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    txcal_index_2057_rev5n7;
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 txcal_index_2057_rev5n7,
+-							 false);
+-			}
+-			save_bbmult = true;
+-
+-		} else if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-			wlc_phy_cal_txgainctrl_nphy(pi, 11, false);
+-			if (pi->sh->hw_phytxchain != 3) {
+-				pi->nphy_txcal_pwr_idx[1] =
+-				    pi->nphy_txcal_pwr_idx[0];
+-				wlc_phy_txpwr_index_nphy(pi, 3,
+-							 pi->
+-							 nphy_txcal_pwr_idx[0],
+-							 true);
+-				save_bbmult = true;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-			if (PHY_IPA(pi)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 12,
+-								    false);
+-				} else {
+-					pi->nphy_txcal_pwr_idx[0] = 80;
+-					pi->nphy_txcal_pwr_idx[1] = 80;
+-					wlc_phy_txpwr_index_nphy(pi, 3, 80,
+-								 false);
+-					save_bbmult = true;
+-				}
+-			} else {
+-
+-				wlc_phy_internal_cal_txgain_nphy(pi);
+-				save_bbmult = true;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+-			if (PHY_IPA(pi)) {
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 12,
+-								    false);
+-				} else {
+-					wlc_phy_cal_txgainctrl_nphy(pi, 14,
+-								    false);
+-				}
+-			} else {
+-
+-				wlc_phy_internal_cal_txgain_nphy(pi);
+-				save_bbmult = true;
+-			}
+-		}
+-
+-	} else {
+-		wlc_phy_cal_txgainctrl_nphy(pi, 10, false);
+-	}
+-
+-	if (save_bbmult) {
+-		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+-					&pi->nphy_txcal_bbmult);
+-	}
+-}
+-
+-void
+-wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug)
+-{
+-	int gainctrl_loopidx;
+-	uint core;
+-	u16 m0m1, curr_m0m1;
+-	s32 delta_power;
+-	s32 txpwrindex;
+-	s32 qdBm_power[2];
+-	u16 orig_BBConfig;
+-	u16 phy_saveregs[4];
+-	u32 freq_test;
+-	u16 ampl_test = 250;
+-	uint stepsize;
+-	bool phyhang_avoid_state = false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		stepsize = 2;
+-	} else {
+-
+-		stepsize = 1;
+-	}
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		freq_test = 5000;
+-	} else {
+-		freq_test = 2500;
+-	}
+-
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	phyhang_avoid_state = pi->phyhang_avoid;
+-	pi->phyhang_avoid = false;
+-
+-	phy_saveregs[0] = read_phy_reg(pi, 0x91);
+-	phy_saveregs[1] = read_phy_reg(pi, 0x92);
+-	phy_saveregs[2] = read_phy_reg(pi, 0xe7);
+-	phy_saveregs[3] = read_phy_reg(pi, 0xec);
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1,
+-					 RADIO_MIMO_CORESEL_CORE1 |
+-					 RADIO_MIMO_CORESEL_CORE2);
+-
+-	if (!debug) {
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x2, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x8, RADIO_MIMO_CORESEL_CORE2);
+-	} else {
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x1, RADIO_MIMO_CORESEL_CORE1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x7, RADIO_MIMO_CORESEL_CORE2);
+-	}
+-
+-	orig_BBConfig = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core];
+-
+-		for (gainctrl_loopidx = 0; gainctrl_loopidx < 2;
+-		     gainctrl_loopidx++) {
+-			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+-					     false);
+-
+-			if (core == PHY_CORE_0) {
+-				curr_m0m1 = m0m1 & 0xff00;
+-			} else {
+-				curr_m0m1 = m0m1 & 0x00ff;
+-			}
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1);
+-			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1);
+-
+-			udelay(50);
+-
+-			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+-						 NPHY_CAL_TSSISAMPS);
+-
+-			pi->nphy_bb_mult_save = 0;
+-			wlc_phy_stopplayback_nphy(pi);
+-
+-			delta_power = (dBm_targetpower * 4) - qdBm_power[core];
+-
+-			txpwrindex -= stepsize * delta_power;
+-			if (txpwrindex < 0) {
+-				txpwrindex = 0;
+-			} else if (txpwrindex > 127) {
+-				txpwrindex = 127;
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (NREV_IS(pi->pubpi.phy_rev, 4) &&
+-				    (pi->srom_fem5g.extpagain == 3)) {
+-					if (txpwrindex < 30) {
+-						txpwrindex = 30;
+-					}
+-				}
+-			} else {
+-				if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-				    (pi->srom_fem2g.extpagain == 3)) {
+-					if (txpwrindex < 50) {
+-						txpwrindex = 50;
+-					}
+-				}
+-			}
+-
+-			wlc_phy_txpwr_index_nphy(pi, (1 << core),
+-						 (u8) txpwrindex, true);
+-		}
+-
+-		pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex;
+-
+-		if (debug) {
+-			u16 radio_gain;
+-			u16 dbg_m0m1;
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+-
+-			wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0,
+-					     false);
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1);
+-			wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1);
+-
+-			udelay(100);
+-
+-			wlc_phy_est_tonepwr_nphy(pi, qdBm_power,
+-						 NPHY_CAL_TSSISAMPS);
+-
+-			wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16,
+-						&radio_gain);
+-
+-			mdelay(4000);
+-			pi->nphy_bb_mult_save = 0;
+-			wlc_phy_stopplayback_nphy(pi);
+-		}
+-	}
+-
+-	wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true);
+-	wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult);
+-
+-	write_phy_reg(pi, 0x01, orig_BBConfig);
+-
+-	write_phy_reg(pi, 0x91, phy_saveregs[0]);
+-	write_phy_reg(pi, 0x92, phy_saveregs[1]);
+-	write_phy_reg(pi, 0xe7, phy_saveregs[2]);
+-	write_phy_reg(pi, 0xec, phy_saveregs[3]);
+-
+-	pi->phyhang_avoid = phyhang_avoid_state;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core)
+-{
+-	int index;
+-	u32 bbmult_scale;
+-	u16 bbmult;
+-	u16 tblentry;
+-
+-	nphy_txiqcal_ladder_t ladder_lo[] = {
+-		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+-		{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
+-		{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
+-	};
+-
+-	nphy_txiqcal_ladder_t ladder_iq[] = {
+-		{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
+-		{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
+-		{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
+-	};
+-
+-	bbmult = (core == PHY_CORE_0) ?
+-	    ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi->
+-						     nphy_txcal_bbmult & 0xff);
+-
+-	for (index = 0; index < 18; index++) {
+-		bbmult_scale = ladder_lo[index].percent * bbmult;
+-		bbmult_scale /= 100;
+-
+-		tblentry =
+-		    ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16,
+-					 &tblentry);
+-
+-		bbmult_scale = ladder_iq[index].percent * bbmult;
+-		bbmult_scale /= 100;
+-
+-		tblentry =
+-		    ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env;
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32,
+-					 16, &tblentry);
+-	}
+-}
+-
+-void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype)
+-{
+-	nphy_txgains_t target_gain;
+-	u8 tx_pwr_ctrl_state;
+-	bool fullcal = true;
+-	bool restore_tx_gain = false;
+-	bool mphase;
+-
+-	if (NORADIO_ENAB(pi->pubpi)) {
+-		wlc_phy_cal_perical_mphase_reset(pi);
+-		return;
+-	}
+-
+-	if (PHY_MUTED(pi))
+-		return;
+-
+-	if (caltype == PHY_PERICAL_AUTO)
+-		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
+-	else if (caltype == PHY_PERICAL_PARTIAL)
+-		fullcal = false;
+-
+-	if (pi->cal_type_override != PHY_PERICAL_AUTO) {
+-		fullcal =
+-		    (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false;
+-	}
+-
+-	if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) {
+-		if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec)
+-			wlc_phy_cal_perical_mphase_restart(pi);
+-	}
+-
+-	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) {
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
+-	}
+-
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	wlc_phyreg_enter((wlc_phy_t *) pi);
+-
+-	if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) ||
+-	    (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) {
+-		pi->nphy_cal_orig_pwr_idx[0] =
+-		    (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f);
+-		pi->nphy_cal_orig_pwr_idx[1] =
+-		    (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f);
+-
+-		if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) {
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2,
+-						0x110, 16,
+-						pi->nphy_cal_orig_tx_gain);
+-		} else {
+-			pi->nphy_cal_orig_tx_gain[0] = 0;
+-			pi->nphy_cal_orig_tx_gain[1] = 0;
+-		}
+-	}
+-	target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	if (pi->antsel_type == ANTSEL_2x3)
+-		wlc_phy_antsel_init((wlc_phy_t *) pi, true);
+-
+-	mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE);
+-	if (!mphase) {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_precal_txgain_nphy(pi);
+-			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-			restore_tx_gain = true;
+-
+-			target_gain = pi->nphy_cal_target_gain;
+-		}
+-		if (0 ==
+-		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) {
+-			if (PHY_IPA(pi))
+-				wlc_phy_a4(pi, true);
+-
+-			wlc_phyreg_exit((wlc_phy_t *) pi);
+-			wlapi_enable_mac(pi->sh->physhim);
+-			wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION,
+-					     10000);
+-			wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-			wlc_phyreg_enter((wlc_phy_t *) pi);
+-
+-			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
+-							     (pi->
+-							      first_cal_after_assoc
+-							      || (pi->
+-								  cal_type_override
+-								  ==
+-								  PHY_PERICAL_FULL))
+-							     ? 2 : 0, false)) {
+-				wlc_phy_savecal_nphy(pi);
+-
+-				wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-
+-				pi->nphy_perical_last = pi->sh->now;
+-			}
+-		}
+-		if (caltype != PHY_PERICAL_AUTO) {
+-			wlc_phy_rssi_cal_nphy(pi);
+-		}
+-
+-		if (pi->first_cal_after_assoc
+-		    || (pi->cal_type_override == PHY_PERICAL_FULL)) {
+-			pi->first_cal_after_assoc = false;
+-			wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-			wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_radio205x_vcocal_nphy(pi);
+-		}
+-	} else {
+-		switch (pi->mphase_cal_phase_id) {
+-		case MPHASE_CAL_STATE_INIT:
+-			pi->nphy_perical_last = pi->sh->now;
+-			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				wlc_phy_precal_txgain_nphy(pi);
+-			}
+-			pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi);
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_TXPHASE0:
+-		case MPHASE_CAL_STATE_TXPHASE1:
+-		case MPHASE_CAL_STATE_TXPHASE2:
+-		case MPHASE_CAL_STATE_TXPHASE3:
+-		case MPHASE_CAL_STATE_TXPHASE4:
+-		case MPHASE_CAL_STATE_TXPHASE5:
+-			if ((pi->radar_percal_mask & 0x10) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (wlc_phy_cal_txiqlo_nphy
+-			    (pi, pi->nphy_cal_target_gain, fullcal,
+-			     true) != 0) {
+-
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-				break;
+-			}
+-
+-			if (NREV_LE(pi->pubpi.phy_rev, 2) &&
+-			    (pi->mphase_cal_phase_id ==
+-			     MPHASE_CAL_STATE_TXPHASE4)) {
+-				pi->mphase_cal_phase_id += 2;
+-			} else {
+-				pi->mphase_cal_phase_id++;
+-			}
+-			break;
+-
+-		case MPHASE_CAL_STATE_PAPDCAL:
+-			if ((pi->radar_percal_mask & 0x2) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (PHY_IPA(pi)) {
+-				wlc_phy_a4(pi, true);
+-			}
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_RXCAL:
+-			if ((pi->radar_percal_mask & 0x1) != 0)
+-				pi->nphy_rxcal_active = true;
+-			if (wlc_phy_cal_rxiq_nphy(pi, target_gain,
+-						  (pi->first_cal_after_assoc ||
+-						   (pi->cal_type_override ==
+-						    PHY_PERICAL_FULL)) ? 2 : 0,
+-						  false) == 0) {
+-				wlc_phy_savecal_nphy(pi);
+-			}
+-
+-			pi->mphase_cal_phase_id++;
+-			break;
+-
+-		case MPHASE_CAL_STATE_RSSICAL:
+-			if ((pi->radar_percal_mask & 0x4) != 0)
+-				pi->nphy_rxcal_active = true;
+-			wlc_phy_txpwrctrl_coeff_setup_nphy(pi);
+-			wlc_phy_rssi_cal_nphy(pi);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				wlc_phy_radio205x_vcocal_nphy(pi);
+-			}
+-			restore_tx_gain = true;
+-
+-			if (pi->first_cal_after_assoc) {
+-				pi->mphase_cal_phase_id++;
+-			} else {
+-				wlc_phy_cal_perical_mphase_reset(pi);
+-			}
+-
+-			break;
+-
+-		case MPHASE_CAL_STATE_IDLETSSI:
+-			if ((pi->radar_percal_mask & 0x8) != 0)
+-				pi->nphy_rxcal_active = true;
+-
+-			if (pi->first_cal_after_assoc) {
+-				pi->first_cal_after_assoc = false;
+-				wlc_phy_txpwrctrl_idle_tssi_nphy(pi);
+-				wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-			}
+-
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			break;
+-
+-		default:
+-			wlc_phy_cal_perical_mphase_reset(pi);
+-			break;
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (restore_tx_gain) {
+-			if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) {
+-
+-				wlc_phy_txpwr_index_nphy(pi, 1,
+-							 pi->
+-							 nphy_cal_orig_pwr_idx
+-							 [0], false);
+-				wlc_phy_txpwr_index_nphy(pi, 2,
+-							 pi->
+-							 nphy_cal_orig_pwr_idx
+-							 [1], false);
+-
+-				pi->nphy_txpwrindex[0].index = -1;
+-				pi->nphy_txpwrindex[1].index = -1;
+-			} else {
+-				wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+-							 (s8) (pi->
+-								 nphy_txpwrindex
+-								 [0].
+-								 index_internal),
+-							 false);
+-				wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+-							 (s8) (pi->
+-								 nphy_txpwrindex
+-								 [1].
+-								 index_internal),
+-							 false);
+-			}
+-		}
+-	}
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-	wlc_phyreg_exit((wlc_phy_t *) pi);
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+-
+-int
+-wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-			bool fullcal, bool mphase)
+-{
+-	u16 val;
+-	u16 tbl_buf[11];
+-	u8 cal_cnt;
+-	u16 cal_cmd;
+-	u8 num_cals, max_cal_cmds;
+-	u16 core_no, cal_type;
+-	u16 diq_start = 0;
+-	u8 phy_bw;
+-	u16 max_val;
+-	u16 tone_freq;
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u32 tbl_len;
+-	void *tbl_ptr;
+-	bool ladder_updated[2];
+-	u8 mphase_cal_lastphase = 0;
+-	int bcmerror = 0;
+-	bool phyhang_avoid_state = false;
+-
+-	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
+-		0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
+-		    0x1902,
+-		0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
+-		    0x6407
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
+-		0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
+-		    0x3200,
+-		0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
+-		    0x6407
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
+-		0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
+-		    0x1202,
+-		0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
+-		    0x4707
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
+-		0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
+-		    0x2300,
+-		0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
+-		    0x4707
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_startcoefs[] = {
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		    0x0000
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
+-		0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
+-		0x9123, 0x9264, 0x9086, 0x9245, 0x9056
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_recal[] = {
+-		0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
+-		0x9101, 0x9253, 0x9053, 0x9234, 0x9034
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+-		0x0000
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
+-		0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
+-		0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
+-	};
+-
+-	u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
+-		0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
+-		0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
+-	};
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		phyhang_avoid_state = pi->phyhang_avoid;
+-		pi->phyhang_avoid = false;
+-	}
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		phy_bw = 40;
+-	} else {
+-		phy_bw = 20;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	wlc_phy_txcal_radio_setup_nphy(pi);
+-
+-	wlc_phy_txcal_physetup_nphy(pi);
+-
+-	ladder_updated[0] = ladder_updated[1] = false;
+-	if (!(NREV_GE(pi->pubpi.phy_rev, 6) ||
+-	      (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi)
+-	       && (CHSPEC_IS2G(pi->radio_chanspec))))) {
+-
+-		if (phy_bw == 40) {
+-			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40);
+-		} else {
+-			tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20);
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0,
+-					 16, tbl_ptr);
+-
+-		if (phy_bw == 40) {
+-			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40);
+-		} else {
+-			tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20;
+-			tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20);
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32,
+-					 16, tbl_ptr);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0xc2, 0x8ad9);
+-	} else {
+-		write_phy_reg(pi, 0xc2, 0x8aa9);
+-	}
+-
+-	max_val = 250;
+-	tone_freq = (phy_bw == 20) ? 2500 : 5000;
+-
+-	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+-		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
+-		bcmerror = 0;
+-	} else {
+-		bcmerror =
+-		    wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false);
+-	}
+-
+-	if (bcmerror == 0) {
+-
+-		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
+-			tbl_ptr = pi->mphase_txcal_bestcoeffs;
+-			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-		} else {
+-			if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) {
+-
+-				tbl_ptr = pi->nphy_txiqlocal_bestc;
+-				tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
+-				if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-					tbl_len -= 2;
+-				}
+-			} else {
+-
+-				fullcal = true;
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					tbl_ptr =
+-					    tbl_tx_iqlo_cal_startcoefs_nphyrev3;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (tbl_tx_iqlo_cal_startcoefs_nphyrev3);
+-				} else {
+-					tbl_ptr = tbl_tx_iqlo_cal_startcoefs;
+-					tbl_len =
+-					    ARRAY_SIZE
+-					    (tbl_tx_iqlo_cal_startcoefs);
+-				}
+-			}
+-		}
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64,
+-					 16, tbl_ptr);
+-
+-		if (fullcal) {
+-			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) :
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal);
+-		} else {
+-			max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) :
+-			    ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal);
+-		}
+-
+-		if (mphase) {
+-			cal_cnt = pi->mphase_txcal_cmdidx;
+-			if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) {
+-				num_cals = cal_cnt + pi->mphase_txcal_numcmds;
+-			} else {
+-				num_cals = max_cal_cmds;
+-			}
+-		} else {
+-			cal_cnt = 0;
+-			num_cals = max_cal_cmds;
+-		}
+-
+-		for (; cal_cnt < num_cals; cal_cnt++) {
+-
+-			if (fullcal) {
+-				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-				    tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3
+-				    [cal_cnt] :
+-				    tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt];
+-			} else {
+-				cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ?
+-				    tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt]
+-				    : tbl_tx_iqlo_cal_cmds_recal[cal_cnt];
+-			}
+-
+-			core_no = ((cal_cmd & 0x3000) >> 12);
+-			cal_type = ((cal_cmd & 0x0F00) >> 8);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 6) ||
+-			    (NREV_IS(pi->pubpi.phy_rev, 5) &&
+-			     PHY_IPA(pi)
+-			     && (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-				if (!ladder_updated[core_no]) {
+-					wlc_phy_update_txcal_ladder_nphy(pi,
+-									 core_no);
+-					ladder_updated[core_no] = true;
+-				}
+-			}
+-
+-			val =
+-			    (cal_params[core_no].
+-			     ncorr[cal_type] << 8) | NPHY_N_GCTL;
+-			write_phy_reg(pi, 0xc1, val);
+-
+-			if ((cal_type == 1) || (cal_type == 3)
+-			    || (cal_type == 4)) {
+-
+-				wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-							1, 69 + core_no, 16,
+-							tbl_buf);
+-
+-				diq_start = tbl_buf[0];
+-
+-				tbl_buf[0] = 0;
+-				wlc_phy_table_write_nphy(pi,
+-							 NPHY_TBL_ID_IQLOCAL, 1,
+-							 69 + core_no, 16,
+-							 tbl_buf);
+-			}
+-
+-			write_phy_reg(pi, 0xc0, cal_cmd);
+-
+-			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
+-				 20000);
+-			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
+-				 "HW error: txiq calib"))
+-				return -EIO;
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						 tbl_len, 64, 16, tbl_buf);
+-
+-			if ((cal_type == 1) || (cal_type == 3)
+-			    || (cal_type == 4)) {
+-
+-				tbl_buf[0] = diq_start;
+-
+-			}
+-
+-		}
+-
+-		if (mphase) {
+-			pi->mphase_txcal_cmdidx = num_cals;
+-			if (pi->mphase_txcal_cmdidx >= max_cal_cmds)
+-				pi->mphase_txcal_cmdidx = 0;
+-		}
+-
+-		mphase_cal_lastphase =
+-		    (NREV_LE(pi->pubpi.phy_rev, 2)) ?
+-		    MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5;
+-
+-		if (!mphase
+-		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) {
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96,
+-						16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+-						 16, tbl_buf);
+-
+-			if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-				tbl_buf[0] = 0;
+-				tbl_buf[1] = 0;
+-				tbl_buf[2] = 0;
+-				tbl_buf[3] = 0;
+-
+-			}
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101,
+-						16, tbl_buf);
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+-						 16, tbl_buf);
+-
+-			tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16,
+-						pi->nphy_txiqlocal_bestc);
+-
+-			pi->nphy_txiqlocal_coeffsvalid = true;
+-			pi->nphy_txiqlocal_chanspec = pi->radio_chanspec;
+-		} else {
+-			tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-
+-				tbl_len -= 2;
+-			}
+-			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-						tbl_len, 96, 16,
+-						pi->mphase_txcal_bestcoeffs);
+-		}
+-
+-		wlc_phy_stopplayback_nphy(pi);
+-
+-		write_phy_reg(pi, 0xc2, 0x0000);
+-
+-	}
+-
+-	wlc_phy_txcal_phycleanup_nphy(pi);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	wlc_phy_txcal_radio_cleanup_nphy(pi);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-		if (!mphase
+-		    || (pi->mphase_cal_phase_id == mphase_cal_lastphase))
+-			wlc_phy_tx_iq_war_nphy(pi);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		pi->phyhang_avoid = phyhang_avoid_state;
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return bcmerror;
+-}
+-
+-static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi)
+-{
+-	u16 tbl_buf[7];
+-
+-	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
+-	    (pi->nphy_txiqlocal_coeffsvalid)) {
+-		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
+-					ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf);
+-
+-		if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) ||
+-		    (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) ||
+-		    (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) ||
+-		    (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) {
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80,
+-						 16, pi->nphy_txiqlocal_bestc);
+-
+-			tbl_buf[0] = 0;
+-			tbl_buf[1] = 0;
+-			tbl_buf[2] = 0;
+-			tbl_buf[3] = 0;
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88,
+-						 16, tbl_buf);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85,
+-						 16,
+-						 &pi->nphy_txiqlocal_bestc[5]);
+-
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93,
+-						 16,
+-						 &pi->nphy_txiqlocal_bestc[5]);
+-		}
+-	}
+-}
+-
+-static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi)
+-{
+-	nphy_iq_comp_t tx_comp;
+-
+-	wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp);
+-
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1);
+-	wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1);
+-}
+-
+-void
+-wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp)
+-{
+-	if (write) {
+-		write_phy_reg(pi, 0x9a, pcomp->a0);
+-		write_phy_reg(pi, 0x9b, pcomp->b0);
+-		write_phy_reg(pi, 0x9c, pcomp->a1);
+-		write_phy_reg(pi, 0x9d, pcomp->b1);
+-	} else {
+-		pcomp->a0 = read_phy_reg(pi, 0x9a);
+-		pcomp->b0 = read_phy_reg(pi, 0x9b);
+-		pcomp->a1 = read_phy_reg(pi, 0x9c);
+-		pcomp->b1 = read_phy_reg(pi, 0x9d);
+-	}
+-}
+-
+-void
+-wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps,
+-		       u8 wait_time, u8 wait_for_crs)
+-{
+-	u8 core;
+-
+-	write_phy_reg(pi, 0x12b, num_samps);
+-	mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0));
+-	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode,
+-		    (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0);
+-
+-	mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart);
+-
+-	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
+-		 10000);
+-	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
+-		 "HW error: rxiq est"))
+-		return;
+-
+-	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			est[core].i_pwr =
+-			    (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16)
+-			    | read_phy_reg(pi, NPHY_IqestipwrAccLo(core));
+-			est[core].q_pwr =
+-			    (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16)
+-			    | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core));
+-			est[core].iq_prod =
+-			    (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) |
+-			    read_phy_reg(pi, NPHY_IqestIqAccLo(core));
+-		}
+-	}
+-}
+-
+-#define CAL_RETRY_CNT 2
+-static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask)
+-{
+-	u8 curr_core;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	nphy_iq_comp_t old_comp, new_comp;
+-	s32 iq = 0;
+-	u32 ii = 0, qq = 0;
+-	s16 iq_nbits, qq_nbits, brsh, arsh;
+-	s32 a, b, temp;
+-	int bcmerror = 0;
+-	uint cal_retry = 0;
+-
+-	if (core_mask == 0x0)
+-		return;
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp);
+-	new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0;
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+-
+- cal_try:
+-	wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0);
+-
+-	new_comp = old_comp;
+-
+-	for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) {
+-
+-		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+-			iq = est[curr_core].iq_prod;
+-			ii = est[curr_core].i_pwr;
+-			qq = est[curr_core].q_pwr;
+-		} else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+-			iq = est[curr_core].iq_prod;
+-			ii = est[curr_core].i_pwr;
+-			qq = est[curr_core].q_pwr;
+-		} else {
+-			continue;
+-		}
+-
+-		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
+-			bcmerror = -EBADE;
+-			break;
+-		}
+-
+-		iq_nbits = wlc_phy_nbits(iq);
+-		qq_nbits = wlc_phy_nbits(qq);
+-
+-		arsh = 10 - (30 - iq_nbits);
+-		if (arsh >= 0) {
+-			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
+-			temp = (s32) (ii >> arsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		} else {
+-			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
+-			temp = (s32) (ii << -arsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		}
+-
+-		a /= temp;
+-
+-		brsh = qq_nbits - 31 + 20;
+-		if (brsh >= 0) {
+-			b = (qq << (31 - qq_nbits));
+-			temp = (s32) (ii >> brsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		} else {
+-			b = (qq << (31 - qq_nbits));
+-			temp = (s32) (ii << -brsh);
+-			if (temp == 0) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-		}
+-		b /= temp;
+-		b -= a * a;
+-		b = (s32) int_sqrt((unsigned long) b);
+-		b -= (1 << 10);
+-
+-		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				new_comp.a0 = (s16) a & 0x3ff;
+-				new_comp.b0 = (s16) b & 0x3ff;
+-			} else {
+-
+-				new_comp.a0 = (s16) b & 0x3ff;
+-				new_comp.b0 = (s16) a & 0x3ff;
+-			}
+-		}
+-		if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				new_comp.a1 = (s16) a & 0x3ff;
+-				new_comp.b1 = (s16) b & 0x3ff;
+-			} else {
+-
+-				new_comp.a1 = (s16) b & 0x3ff;
+-				new_comp.b1 = (s16) a & 0x3ff;
+-			}
+-		}
+-	}
+-
+-	if (bcmerror != 0) {
+-		printk("%s: Failed, cnt = %d\n", __func__, cal_retry);
+-
+-		if (cal_retry < CAL_RETRY_CNT) {
+-			cal_retry++;
+-			goto cal_try;
+-		}
+-
+-		new_comp = old_comp;
+-	} else if (cal_retry > 0) {
+-	}
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp);
+-}
+-
+-static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	u16 offtune_val;
+-	u16 bias_g = 0;
+-	u16 bias_a = 0;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (rx_core == PHY_CORE_0) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+-						0xaf);
+-
+-			} else {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+-						0x7f);
+-			}
+-
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+-						0xaf);
+-
+-			} else {
+-				pi->tx_rx_cal_radio_saveregs[0] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP);
+-				pi->tx_rx_cal_radio_saveregs[1] =
+-				    read_radio_reg(pi,
+-						   RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN);
+-
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+-						0x3);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+-						0x7f);
+-			}
+-		}
+-
+-	} else {
+-		if (rx_core == PHY_CORE_0) {
+-			pi->tx_rx_cal_radio_saveregs[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_RXIQCAL_TXMUX |
+-					   RADIO_2056_TX1);
+-			pi->tx_rx_cal_radio_saveregs[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RXIQCAL_RXMUX |
+-					   RADIO_2056_RX0);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				pi->tx_rx_cal_radio_saveregs[2] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_RX_RXSPARE2 |
+-						   RADIO_2056_RX0);
+-				pi->tx_rx_cal_radio_saveregs[3] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_TX_TXSPARE2 |
+-						   RADIO_2056_TX1);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_MASTER
+-							   | RADIO_2056_RX0);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX0, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX1, bias_a);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX0, bias_a);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_TUNE
+-							   | RADIO_2056_RX0);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAA_TUNE |
+-						      RADIO_2056_RX0, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX1, 0x9);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX0, 0x9);
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_MASTER
+-							   | RADIO_2056_RX0);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX0, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX1, bias_g);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX0, bias_g);
+-
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_TUNE
+-							   | RADIO_2056_RX0);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAG_TUNE |
+-						      RADIO_2056_RX0, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX1, 0x6);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX0, 0x6);
+-			}
+-
+-		} else {
+-			pi->tx_rx_cal_radio_saveregs[0] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_TX_RXIQCAL_TXMUX |
+-					   RADIO_2056_TX0);
+-			pi->tx_rx_cal_radio_saveregs[1] =
+-			    read_radio_reg(pi,
+-					   RADIO_2056_RX_RXIQCAL_RXMUX |
+-					   RADIO_2056_RX1);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				pi->tx_rx_cal_radio_saveregs[2] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_RX_RXSPARE2 |
+-						   RADIO_2056_RX1);
+-				pi->tx_rx_cal_radio_saveregs[3] =
+-				    read_radio_reg(pi,
+-						   RADIO_2056_TX_TXSPARE2 |
+-						   RADIO_2056_TX0);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_MASTER
+-							   | RADIO_2056_RX1);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX1, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX0, bias_a);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX1, bias_a);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAA_TUNE
+-							   | RADIO_2056_RX1);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAA_TUNE |
+-						      RADIO_2056_RX1, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX0, 0x9);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX1, 0x9);
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_MASTER
+-							   | RADIO_2056_RX1);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX1, 0x40);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_TX_TXSPARE2 |
+-							RADIO_2056_TX0, bias_g);
+-
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_RXSPARE2 |
+-							RADIO_2056_RX1, bias_g);
+-				} else {
+-					pi->tx_rx_cal_radio_saveregs[4] =
+-					    read_radio_reg(pi,
+-							   RADIO_2056_RX_LNAG_TUNE
+-							   | RADIO_2056_RX1);
+-
+-					offtune_val =
+-					    (pi->
+-					     tx_rx_cal_radio_saveregs[2] & 0xF0)
+-					    >> 8;
+-					offtune_val =
+-					    (offtune_val <= 0x7) ? 0xF : 0;
+-
+-					mod_radio_reg(pi,
+-						      RADIO_2056_RX_LNAG_TUNE |
+-						      RADIO_2056_RX1, 0xF0,
+-						      (offtune_val << 8));
+-				}
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_RXIQCAL_TXMUX |
+-						RADIO_2056_TX0, 0x6);
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXIQCAL_RXMUX |
+-						RADIO_2056_RX1, 0x6);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		if (rx_core == PHY_CORE_0) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-			}
+-
+-		} else {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-
+-			} else {
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP,
+-						pi->
+-						tx_rx_cal_radio_saveregs[0]);
+-				write_radio_reg(pi,
+-						RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN,
+-						pi->
+-						tx_rx_cal_radio_saveregs[1]);
+-			}
+-		}
+-
+-	} else {
+-		if (rx_core == PHY_CORE_0) {
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_RXIQCAL_TXMUX |
+-					RADIO_2056_TX1,
+-					pi->tx_rx_cal_radio_saveregs[0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_RX_RXIQCAL_RXMUX |
+-					RADIO_2056_RX0,
+-					pi->tx_rx_cal_radio_saveregs[1]);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXSPARE2 |
+-						RADIO_2056_RX0,
+-						pi->
+-						tx_rx_cal_radio_saveregs[2]);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TXSPARE2 |
+-						RADIO_2056_TX1,
+-						pi->
+-						tx_rx_cal_radio_saveregs[3]);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_TUNE
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_TUNE
+-							| RADIO_2056_RX0,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			}
+-
+-		} else {
+-			write_radio_reg(pi,
+-					RADIO_2056_TX_RXIQCAL_TXMUX |
+-					RADIO_2056_TX0,
+-					pi->tx_rx_cal_radio_saveregs[0]);
+-
+-			write_radio_reg(pi,
+-					RADIO_2056_RX_RXIQCAL_RXMUX |
+-					RADIO_2056_RX1,
+-					pi->tx_rx_cal_radio_saveregs[1]);
+-
+-			if (pi->pubpi.radiorev >= 5) {
+-				write_radio_reg(pi,
+-						RADIO_2056_RX_RXSPARE2 |
+-						RADIO_2056_RX1,
+-						pi->
+-						tx_rx_cal_radio_saveregs[2]);
+-
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TXSPARE2 |
+-						RADIO_2056_TX0,
+-						pi->
+-						tx_rx_cal_radio_saveregs[3]);
+-			}
+-
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_MASTER
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAA_TUNE
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			} else {
+-				if (pi->pubpi.radiorev >= 5) {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_MASTER
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				} else {
+-					write_radio_reg(pi,
+-							RADIO_2056_RX_LNAG_TUNE
+-							| RADIO_2056_RX1,
+-							pi->
+-							tx_rx_cal_radio_saveregs
+-							[4]);
+-				}
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-	u8 tx_core;
+-	u16 rx_antval, tx_antval;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		tx_core = rx_core;
+-	} else {
+-		tx_core = (rx_core == PHY_CORE_0) ? 1 : 0;
+-	}
+-
+-	pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2);
+-	pi->tx_rx_cal_phy_saveregs[1] =
+-	    read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7);
+-	pi->tx_rx_cal_phy_saveregs[2] =
+-	    read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5);
+-	pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91);
+-	pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92);
+-	pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a);
+-	pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d);
+-	pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7);
+-	pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342);
+-		pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343);
+-		pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346);
+-		pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347);
+-	}
+-
+-	pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297);
+-	pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b);
+-	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (0) << 0);
+-
+-	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (0) << 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12);
+-
+-	} else {
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-		mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4);
+-		mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8);
+-	}
+-
+-	mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0);
+-	mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+-		    (0x1 << 2), (0x1 << 2));
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 0) | (0x1 << 1), 0);
+-		mod_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-			    0x8f : 0xa5,
+-			    (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1));
+-	}
+-
+-	wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0,
+-					 RADIO_MIMO_CORESEL_CORE1 |
+-					 RADIO_MIMO_CORESEL_CORE2);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		if (CHSPEC_IS40(pi->radio_chanspec)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  2, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi,
+-							  (0x1 << 7),
+-							  0, 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-						  0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0);
+-	}
+-
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 0x1, rx_core + 1);
+-	} else {
+-
+-		if (rx_core == PHY_CORE_0) {
+-			rx_antval = 0x1;
+-			tx_antval = 0x8;
+-		} else {
+-			rx_antval = 0x4;
+-			tx_antval = 0x2;
+-		}
+-
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 rx_antval, rx_core + 1);
+-		wlc_phy_rfctrlintc_override_nphy(pi,
+-						 NPHY_RfctrlIntc_override_TRSW,
+-						 tx_antval, tx_core + 1);
+-	}
+-}
+-
+-static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core)
+-{
+-
+-	write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]);
+-	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7,
+-		      pi->tx_rx_cal_phy_saveregs[1]);
+-	write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5,
+-		      pi->tx_rx_cal_phy_saveregs[2]);
+-	write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]);
+-	write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]);
+-
+-	write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]);
+-	write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]);
+-	write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]);
+-	write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]);
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]);
+-		write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]);
+-		write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]);
+-		write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]);
+-	}
+-
+-	write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]);
+-	write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]);
+-}
+-
+-static void
+-wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core,
+-				 u16 *rxgain, u8 cal_type)
+-{
+-
+-	u16 num_samps;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	u8 tx_core;
+-	nphy_iq_comp_t save_comp, zero_comp;
+-	u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr =
+-	    10000;
+-	s16 desired_log2_pwr, actual_log2_pwr, delta_pwr;
+-	bool gainctrl_done = false;
+-	u8 mix_tia_gain = 3;
+-	s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0;
+-	s8 curr_gaintbl_index = 3;
+-	u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT;
+-	nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl;
+-	u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1;
+-	int fine_gain_idx;
+-	s8 txpwrindex;
+-	u16 nphy_rxcal_txgain[2];
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		tx_core = rx_core;
+-	} else {
+-		tx_core = 1 - rx_core;
+-	}
+-
+-	num_samps = 1024;
+-	desired_log2_pwr = (cal_type == 0) ? 13 : 13;
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp);
+-	zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0;
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp);
+-
+-	if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			mix_tia_gain = 3;
+-		} else if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-			mix_tia_gain = 4;
+-		} else {
+-			mix_tia_gain = 6;
+-		}
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7;
+-		} else {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz;
+-		}
+-	} else {
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7;
+-		} else {
+-			nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz;
+-		}
+-	}
+-
+-	do {
+-
+-		hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ?
+-		    0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga;
+-		lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1;
+-		lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0;
+-		lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2;
+-		lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1;
+-		txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-							     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-							     ((lpf_biq1 << 12) |
+-							      (lpf_biq0 << 8) |
+-							      (mix_tia_gain <<
+-							       4) | (lna2 << 2)
+-							      | lna1), 0x3, 0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+-						     ((hpvga << 12) |
+-						      (lpf_biq1 << 10) |
+-						      (lpf_biq0 << 8) |
+-						      (mix_tia_gain << 4) |
+-						      (lna2 << 2) | lna1), 0x3,
+-						     0);
+-		}
+-
+-		pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex;
+-
+-		if (txpwrindex == -1) {
+-			nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval;
+-			nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval;
+-			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ,
+-						 2, 0x110, 16,
+-						 nphy_rxcal_txgain);
+-		} else {
+-			wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex,
+-						 false);
+-		}
+-
+-		wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ?
+-				     NPHY_RXCAL_TONEFREQ_40MHz :
+-				     NPHY_RXCAL_TONEFREQ_20MHz,
+-				     NPHY_RXCAL_TONEAMP, 0, cal_type, false);
+-
+-		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-		i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps;
+-		q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps;
+-		curr_pwr = i_pwr + q_pwr;
+-
+-		switch (gainctrl_dirn) {
+-		case NPHY_RXCAL_GAIN_INIT:
+-			if (curr_pwr > thresh_pwr) {
+-				gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN;
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index--;
+-			} else {
+-				gainctrl_dirn = NPHY_RXCAL_GAIN_UP;
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index++;
+-			}
+-			break;
+-
+-		case NPHY_RXCAL_GAIN_UP:
+-			if (curr_pwr > thresh_pwr) {
+-				gainctrl_done = true;
+-				optim_pwr = prev_pwr;
+-				optim_gaintbl_index = prev_gaintbl_index;
+-			} else {
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index++;
+-			}
+-			break;
+-
+-		case NPHY_RXCAL_GAIN_DOWN:
+-			if (curr_pwr > thresh_pwr) {
+-				prev_gaintbl_index = curr_gaintbl_index;
+-				curr_gaintbl_index--;
+-			} else {
+-				gainctrl_done = true;
+-				optim_pwr = curr_pwr;
+-				optim_gaintbl_index = curr_gaintbl_index;
+-			}
+-			break;
+-
+-		default:
+-			break;
+-		}
+-
+-		if ((curr_gaintbl_index < 0) ||
+-		    (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) {
+-			gainctrl_done = true;
+-			optim_pwr = curr_pwr;
+-			optim_gaintbl_index = prev_gaintbl_index;
+-		} else {
+-			prev_pwr = curr_pwr;
+-		}
+-
+-		wlc_phy_stopplayback_nphy(pi);
+-	} while (!gainctrl_done);
+-
+-	hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga;
+-	lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1;
+-	lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0;
+-	lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2;
+-	lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1;
+-	txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex;
+-
+-	actual_log2_pwr = wlc_phy_nbits(optim_pwr);
+-	delta_pwr = desired_log2_pwr - actual_log2_pwr;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		fine_gain_idx = (int)lpf_biq1 + delta_pwr;
+-
+-		if (fine_gain_idx + (int)lpf_biq0 > 10) {
+-			lpf_biq1 = 10 - lpf_biq0;
+-		} else {
+-			lpf_biq1 = (u16) max(fine_gain_idx, 0);
+-		}
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-						     ((lpf_biq1 << 12) |
+-						      (lpf_biq0 << 8) |
+-						      (mix_tia_gain << 4) |
+-						      (lna2 << 2) | lna1), 0x3,
+-						     0);
+-	} else {
+-		hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12),
+-					     ((hpvga << 12) | (lpf_biq1 << 10) |
+-					      (lpf_biq0 << 8) | (mix_tia_gain <<
+-								 4) | (lna2 <<
+-								       2) |
+-					      lna1), 0x3, 0);
+-
+-	}
+-
+-	if (rxgain != NULL) {
+-		*rxgain++ = lna1;
+-		*rxgain++ = lna2;
+-		*rxgain++ = mix_tia_gain;
+-		*rxgain++ = lpf_biq0;
+-		*rxgain++ = lpf_biq1;
+-		*rxgain = hpvga;
+-	}
+-
+-	wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp);
+-}
+-
+-static void
+-wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, u8 rx_core, u16 *rxgain,
+-			    u8 cal_type)
+-{
+-	wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type);
+-}
+-
+-static u8
+-wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type)
+-{
+-	u32 target_bws[2] = { 9500, 21000 };
+-	u32 ref_tones[2] = { 3000, 6000 };
+-	u32 target_bw, ref_tone;
+-
+-	u32 target_pwr_ratios[2] = { 28606, 18468 };
+-	u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0;
+-
+-	u16 start_rccal_ovr_val = 128;
+-	u16 txlpf_rccal_lpc_ovr_val = 128;
+-	u16 rxlpf_rccal_hpc_ovr_val = 159;
+-
+-	u16 orig_txlpf_rccal_lpc_ovr_val;
+-	u16 orig_rxlpf_rccal_hpc_ovr_val;
+-	u16 radio_addr_offset_rx;
+-	u16 radio_addr_offset_tx;
+-	u16 orig_dcBypass;
+-	u16 orig_RxStrnFilt40Num[6];
+-	u16 orig_RxStrnFilt40Den[4];
+-	u16 orig_rfctrloverride[2];
+-	u16 orig_rfctrlauxreg[2];
+-	u16 orig_rfctrlrssiothers;
+-	u16 tx_lpf_bw = 4;
+-
+-	u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 };
+-	u16 lpf_hpc = 7, hpvga_hpc = 7;
+-
+-	s8 rccal_stepsize;
+-	u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0;
+-	u32 ref_iq_vals = 0, target_iq_vals = 0;
+-	u16 num_samps, log_num_samps = 10;
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		return 0;
+-	}
+-
+-	num_samps = (1 << log_num_samps);
+-
+-	if (CHSPEC_IS40(pi->radio_chanspec)) {
+-		target_bw = target_bws[1];
+-		target_pwr_ratio = target_pwr_ratios[1];
+-		ref_tone = ref_tones[1];
+-		rx_lpf_bw = rx_lpf_bws[1];
+-	} else {
+-		target_bw = target_bws[0];
+-		target_pwr_ratio = target_pwr_ratios[0];
+-		ref_tone = ref_tones[0];
+-		rx_lpf_bw = rx_lpf_bws[0];
+-	}
+-
+-	if (core_idx == 0) {
+-		radio_addr_offset_rx = RADIO_2056_RX0;
+-		radio_addr_offset_tx =
+-		    (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1;
+-	} else {
+-		radio_addr_offset_rx = RADIO_2056_RX1;
+-		radio_addr_offset_tx =
+-		    (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0;
+-	}
+-
+-	orig_txlpf_rccal_lpc_ovr_val =
+-	    read_radio_reg(pi,
+-			   (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx));
+-	orig_rxlpf_rccal_hpc_ovr_val =
+-	    read_radio_reg(pi,
+-			   (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+-			    radio_addr_offset_rx));
+-
+-	orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1);
+-
+-	orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267);
+-	orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268);
+-	orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269);
+-	orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a);
+-	orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b);
+-	orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c);
+-	orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d);
+-	orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e);
+-	orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f);
+-	orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270);
+-
+-	orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7);
+-	orig_rfctrloverride[1] = read_phy_reg(pi, 0xec);
+-	orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8);
+-	orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa);
+-	orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d);
+-
+-	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+-			txlpf_rccal_lpc_ovr_val);
+-
+-	write_radio_reg(pi,
+-			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+-			rxlpf_rccal_hpc_ovr_val);
+-
+-	mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8));
+-
+-	write_phy_reg(pi, 0x267, 0x02d4);
+-	write_phy_reg(pi, 0x268, 0x0000);
+-	write_phy_reg(pi, 0x269, 0x0000);
+-	write_phy_reg(pi, 0x26a, 0x0000);
+-	write_phy_reg(pi, 0x26b, 0x0000);
+-	write_phy_reg(pi, 0x26c, 0x02d4);
+-	write_phy_reg(pi, 0x26d, 0x0000);
+-	write_phy_reg(pi, 0x26e, 0x0000);
+-	write_phy_reg(pi, 0x26f, 0x0000);
+-	write_phy_reg(pi, 0x270, 0x0000);
+-
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9));
+-	or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10));
+-
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8,
+-		    (0x7 << 10), (tx_lpf_bw << 10));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+-		    (0x7 << 0), (hpvga_hpc << 0));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa,
+-		    (0x7 << 4), (lpf_hpc << 4));
+-	mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d,
+-		    (0x7 << 8), (rx_lpf_bw << 8));
+-
+-	rccal_stepsize = 16;
+-	rccal_val = start_rccal_ovr_val + rccal_stepsize;
+-
+-	while (rccal_stepsize >= 0) {
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-				 radio_addr_offset_rx), rccal_val);
+-
+-		if (rccal_stepsize == 16) {
+-
+-			wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP,
+-					     0, 1, false);
+-			udelay(2);
+-
+-			wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-
+-			if (core_idx == 0) {
+-				ref_iq_vals =
+-				    max_t(u32, (est[0].i_pwr +
+-					 est[0].q_pwr) >> (log_num_samps + 1),
+-					1);
+-			} else {
+-				ref_iq_vals =
+-				    max_t(u32, (est[1].i_pwr +
+-					 est[1].q_pwr) >> (log_num_samps + 1),
+-					1);
+-			}
+-
+-			wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP,
+-					     0, 1, false);
+-			udelay(2);
+-		}
+-
+-		wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0);
+-
+-		if (core_idx == 0) {
+-			target_iq_vals =
+-			    (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps +
+-							      1);
+-		} else {
+-			target_iq_vals =
+-			    (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps +
+-							      1);
+-		}
+-		pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals);
+-
+-		if (rccal_stepsize == 0) {
+-			rccal_stepsize--;
+-		} else if (rccal_stepsize == 1) {
+-			last_rccal_val = rccal_val;
+-			rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1;
+-			last_pwr_ratio = pwr_ratio;
+-			rccal_stepsize--;
+-		} else {
+-			rccal_stepsize = (rccal_stepsize >> 1);
+-			rccal_val += ((pwr_ratio > target_pwr_ratio) ?
+-				      rccal_stepsize : (-rccal_stepsize));
+-		}
+-
+-		if (rccal_stepsize == -1) {
+-			best_rccal_val =
+-			    (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) <
+-			     ABS((int)pwr_ratio -
+-				 (int)target_pwr_ratio)) ? last_rccal_val :
+-			    rccal_val;
+-
+-			if (CHSPEC_IS40(pi->radio_chanspec)) {
+-				if ((best_rccal_val > 140)
+-				    || (best_rccal_val < 135)) {
+-					best_rccal_val = 138;
+-				}
+-			} else {
+-				if ((best_rccal_val > 142)
+-				    || (best_rccal_val < 137)) {
+-					best_rccal_val = 140;
+-				}
+-			}
+-
+-			write_radio_reg(pi,
+-					(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-					 radio_addr_offset_rx), best_rccal_val);
+-		}
+-	}
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx),
+-			orig_txlpf_rccal_lpc_ovr_val);
+-	write_radio_reg(pi,
+-			(RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx),
+-			orig_rxlpf_rccal_hpc_ovr_val);
+-
+-	mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8));
+-
+-	write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]);
+-	write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]);
+-	write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]);
+-	write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]);
+-	write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]);
+-	write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]);
+-	write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]);
+-	write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]);
+-	write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]);
+-	write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]);
+-
+-	write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]);
+-	write_phy_reg(pi, 0xec, orig_rfctrloverride[1]);
+-	write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]);
+-	write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]);
+-	write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers);
+-
+-	pi->nphy_anarxlpf_adjusted = false;
+-
+-	return best_rccal_val - 0x80;
+-}
+-
+-#define WAIT_FOR_SCOPE	4000
+-static int
+-wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain,
+-			   u8 cal_type, bool debug)
+-{
+-	u16 orig_BBConfig;
+-	u8 core_no, rx_core;
+-	u8 best_rccal[2];
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u8 rxcore_state;
+-	s8 rxlpf_rccal_hpc, txlpf_rccal_lpc;
+-	s8 txlpf_idac;
+-	bool phyhang_avoid_state = false;
+-	bool skip_rxiqcal = false;
+-
+-	orig_BBConfig = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		phyhang_avoid_state = pi->phyhang_avoid;
+-		pi->phyhang_avoid = false;
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi);
+-
+-	for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+-
+-		skip_rxiqcal =
+-		    ((rxcore_state & (1 << rx_core)) == 0) ? true : false;
+-
+-		wlc_phy_rxcal_physetup_nphy(pi, rx_core);
+-
+-		wlc_phy_rxcal_radio_setup_nphy(pi, rx_core);
+-
+-		if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) {
+-
+-			wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0);
+-
+-			wlc_phy_tx_tone_nphy(pi,
+-					     (CHSPEC_IS40(pi->radio_chanspec)) ?
+-					     NPHY_RXCAL_TONEFREQ_40MHz :
+-					     NPHY_RXCAL_TONEFREQ_20MHz,
+-					     NPHY_RXCAL_TONEAMP, 0, cal_type,
+-					     false);
+-
+-			if (debug)
+-				mdelay(WAIT_FOR_SCOPE);
+-
+-			wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1);
+-			wlc_phy_stopplayback_nphy(pi);
+-		}
+-
+-		if (((cal_type == 1) || (cal_type == 2))
+-		    && NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-			if (rx_core == PHY_CORE_1) {
+-
+-				if (rxcore_state == 1) {
+-					wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+-								      *) pi, 3);
+-				}
+-
+-				wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL,
+-							    1);
+-
+-				best_rccal[rx_core] =
+-				    wlc_phy_rc_sweep_nphy(pi, rx_core, 1);
+-				pi->nphy_rccal_value = best_rccal[rx_core];
+-
+-				if (rxcore_state == 1) {
+-					wlc_phy_rxcore_setstate_nphy((wlc_phy_t
+-								      *) pi,
+-								     rxcore_state);
+-				}
+-			}
+-		}
+-
+-		wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core);
+-
+-		wlc_phy_rxcal_phycleanup_nphy(pi, rx_core);
+-		wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-	}
+-
+-	if ((cal_type == 1) || (cal_type == 2)) {
+-
+-		best_rccal[0] = best_rccal[1];
+-		write_radio_reg(pi,
+-				(RADIO_2056_RX_RXLPF_RCCAL_LPC |
+-				 RADIO_2056_RX0), (best_rccal[0] | 0x80));
+-
+-		for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) {
+-			rxlpf_rccal_hpc =
+-			    (((int)best_rccal[rx_core] - 12) >> 1) + 10;
+-			txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10;
+-
+-			if (PHY_IPA(pi)) {
+-				txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12;
+-				txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13;
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core,
+-						 TXLPF_IDAC_4, txlpf_idac);
+-			}
+-
+-			rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0);
+-			txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0);
+-
+-			write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC |
+-					     ((rx_core ==
+-					       PHY_CORE_0) ? RADIO_2056_RX0 :
+-					      RADIO_2056_RX1)),
+-					(rxlpf_rccal_hpc | 0x80));
+-
+-			write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL |
+-					     ((rx_core ==
+-					       PHY_CORE_0) ? RADIO_2056_TX0 :
+-					      RADIO_2056_TX1)),
+-					(txlpf_rccal_lpc | 0x80));
+-		}
+-	}
+-
+-	write_phy_reg(pi, 0x01, orig_BBConfig);
+-
+-	wlc_phy_resetcca_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_rxgain,
+-						     0, 0x3, 1);
+-	} else {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+-	}
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 4)) {
+-		pi->phyhang_avoid = phyhang_avoid_state;
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return 0;
+-}
+-
+-static int
+-wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain,
+-			   bool debug)
+-{
+-	phy_iq_est_t est[PHY_CORE_MAX];
+-	u8 core_num, rx_core, tx_core;
+-	u16 lna_vals[] = { 0x3, 0x3, 0x1 };
+-	u16 hpf1_vals[] = { 0x7, 0x2, 0x0 };
+-	u16 hpf2_vals[] = { 0x2, 0x0, 0x0 };
+-	s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna;
+-	s16 desired_log2_pwr, actual_log2_pwr, hpf_change;
+-	u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride;
+-	u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx;
+-	u16 num_samps;
+-	u32 i_pwr, q_pwr, tot_pwr[3];
+-	u8 gain_pass, use_hpf_num;
+-	u16 mask, val1, val2;
+-	u16 core_no;
+-	u16 gain_save[2];
+-	u16 cal_gain[2];
+-	nphy_iqcal_params_t cal_params[2];
+-	u8 phy_bw;
+-	int bcmerror = 0;
+-	bool first_playtone = true;
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-		wlc_phy_reapply_txcal_coeffs_nphy(pi);
+-	}
+-
+-	wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save);
+-
+-	for (core_no = 0; core_no <= 1; core_no++) {
+-		wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain,
+-					      &cal_params[core_no]);
+-		cal_gain[core_no] = cal_params[core_no].cal_gain;
+-	}
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain);
+-
+-	num_samps = 1024;
+-	desired_log2_pwr = 13;
+-
+-	for (core_num = 0; core_num < 2; core_num++) {
+-
+-		rx_core = core_num;
+-		tx_core = 1 - core_num;
+-
+-		orig_RfseqCoreActv = read_phy_reg(pi, 0xa2);
+-		orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-						0xa6 : 0xa7);
+-		orig_AfectrlOverride = read_phy_reg(pi, 0xa5);
+-		orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ?
+-						 0x91 : 0x92);
+-		orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ?
+-						 0x91 : 0x92);
+-
+-		mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12);
+-		mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0);
+-
+-		or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			   ((0x1 << 1) | (0x1 << 2)));
+-		or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2)));
+-
+-		if (((pi->nphy_rxcalparams) & 0xff000000)) {
+-
+-			write_phy_reg(pi,
+-				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-				      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 :
+-				       0x110));
+-		} else {
+-
+-			write_phy_reg(pi,
+-				      (rx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-				      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 :
+-				       0x120));
+-		}
+-
+-		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92,
+-			      (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 :
+-			       0x114));
+-
+-		mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK;
+-		if (rx_core == PHY_CORE_0) {
+-			val1 = RADIO_2055_COUPLE_RX_MASK;
+-			val2 = RADIO_2055_COUPLE_TX_MASK;
+-		} else {
+-			val1 = RADIO_2055_COUPLE_TX_MASK;
+-			val2 = RADIO_2055_COUPLE_RX_MASK;
+-		}
+-
+-		if ((pi->nphy_rxcalparams & 0x10000)) {
+-			mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask,
+-				      val1);
+-			mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask,
+-				      val2);
+-		}
+-
+-		for (gain_pass = 0; gain_pass < 4; gain_pass++) {
+-
+-			if (debug)
+-				mdelay(WAIT_FOR_SCOPE);
+-
+-			if (gain_pass < 3) {
+-				curr_lna = lna_vals[gain_pass];
+-				curr_hpf1 = hpf1_vals[gain_pass];
+-				curr_hpf2 = hpf2_vals[gain_pass];
+-			} else {
+-
+-				if (tot_pwr[1] > 10000) {
+-					curr_lna = lna_vals[2];
+-					curr_hpf1 = hpf1_vals[2];
+-					curr_hpf2 = hpf2_vals[2];
+-					use_hpf_num = 1;
+-					curr_hpf = curr_hpf1;
+-					actual_log2_pwr =
+-					    wlc_phy_nbits(tot_pwr[2]);
+-				} else {
+-					if (tot_pwr[0] > 10000) {
+-						curr_lna = lna_vals[1];
+-						curr_hpf1 = hpf1_vals[1];
+-						curr_hpf2 = hpf2_vals[1];
+-						use_hpf_num = 1;
+-						curr_hpf = curr_hpf1;
+-						actual_log2_pwr =
+-						    wlc_phy_nbits(tot_pwr[1]);
+-					} else {
+-						curr_lna = lna_vals[0];
+-						curr_hpf1 = hpf1_vals[0];
+-						curr_hpf2 = hpf2_vals[0];
+-						use_hpf_num = 2;
+-						curr_hpf = curr_hpf2;
+-						actual_log2_pwr =
+-						    wlc_phy_nbits(tot_pwr[0]);
+-					}
+-				}
+-
+-				hpf_change = desired_log2_pwr - actual_log2_pwr;
+-				curr_hpf += hpf_change;
+-				curr_hpf = max(min_t(u16, curr_hpf, 10), 0);
+-				if (use_hpf_num == 1) {
+-					curr_hpf1 = curr_hpf;
+-				} else {
+-					curr_hpf2 = curr_hpf;
+-				}
+-			}
+-
+-			wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10),
+-						     ((curr_hpf2 << 8) |
+-						      (curr_hpf1 << 4) |
+-						      (curr_lna << 2)), 0x3, 0);
+-			wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-			wlc_phy_stopplayback_nphy(pi);
+-
+-			if (first_playtone) {
+-				bcmerror = wlc_phy_tx_tone_nphy(pi, 4000,
+-								(u16) (pi->
+-									  nphy_rxcalparams
+-									  &
+-									  0xffff),
+-								0, 0, true);
+-				first_playtone = false;
+-			} else {
+-				phy_bw =
+-				    (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20;
+-				wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff,
+-							0, 0, 0, true);
+-			}
+-
+-			if (bcmerror == 0) {
+-				if (gain_pass < 3) {
+-
+-					wlc_phy_rx_iq_est_nphy(pi, est,
+-							       num_samps, 32,
+-							       0);
+-					i_pwr =
+-					    (est[rx_core].i_pwr +
+-					     num_samps / 2) / num_samps;
+-					q_pwr =
+-					    (est[rx_core].q_pwr +
+-					     num_samps / 2) / num_samps;
+-					tot_pwr[gain_pass] = i_pwr + q_pwr;
+-				} else {
+-
+-					wlc_phy_calc_rx_iq_comp_nphy(pi,
+-								     (1 <<
+-								      rx_core));
+-				}
+-
+-				wlc_phy_stopplayback_nphy(pi);
+-			}
+-
+-			if (bcmerror != 0)
+-				break;
+-		}
+-
+-		and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask);
+-		and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask);
+-
+-		write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 :
+-			      0x92, orig_RfctrlIntcTx);
+-		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 :
+-			      0x92, orig_RfctrlIntcRx);
+-		write_phy_reg(pi, 0xa5, orig_AfectrlOverride);
+-		write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 :
+-			      0xa7, orig_AfectrlCore);
+-		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
+-
+-		if (bcmerror != 0)
+-			break;
+-	}
+-
+-	wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1);
+-	wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16,
+-				 gain_save);
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	return bcmerror;
+-}
+-
+-int
+-wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain,
+-		      u8 cal_type, bool debug)
+-{
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		cal_type = 0;
+-	}
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type,
+-						  debug);
+-	} else {
+-		return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug);
+-	}
+-}
+-
+-static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j, type = 2;
+-	u16 addr_offset = 0x2c5;
+-
+-	for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-		write_phy_reg(pi, addr_offset + j,
+-			      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+-	}
+-}
+-
+-static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j, type;
+-	u16 addr_offset[] = { 0x186, 0x195,
+-		0x2c5
+-	};
+-
+-	for (type = 0; type < 3; type++) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, addr_offset[type] + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]);
+-		}
+-	}
+-
+-	if (IS40MHZ(pi)) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x186 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+-		}
+-	} else {
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, 0x186 + j,
+-					      NPHY_IPA_REV4_txdigi_filtcoeffs[5]
+-					      [j]);
+-			}
+-		}
+-
+-		if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
+-			for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-				write_phy_reg(pi, 0x2c5 + j,
+-					      NPHY_IPA_REV4_txdigi_filtcoeffs[6]
+-					      [j]);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi)
+-{
+-	int j;
+-
+-	if (IS40MHZ(pi)) {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x195 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]);
+-		}
+-	} else {
+-		for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) {
+-			write_phy_reg(pi, 0x186 + j,
+-				      NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]);
+-		}
+-	}
+-}
+-
+-static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi)
+-{
+-	u16 m0m1;
+-
+-	wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1);
+-
+-	return m0m1;
+-}
+-
+-static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1)
+-{
+-	u16 m0m1 = (u16) ((m0 << 8) | m1);
+-
+-	wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1);
+-	wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1);
+-}
+-
+-static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi)
+-{
+-	u32 *tx_pwrctrl_tbl = NULL;
+-
+-	if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-			if ((pi->pubpi.radiorev == 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev4n6;
+-			} else if (pi->pubpi.radiorev == 3) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev3;
+-			} else if (pi->pubpi.radiorev == 5) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev5;
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_2g_2057rev7;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6;
+-			if (pi->sh->chip == BCM47162_CHIP_ID) {
+-
+-				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+-			}
+-
+-		} else if (NREV_IS(pi->pubpi.phy_rev, 5)) {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5;
+-		} else {
+-
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa;
+-		}
+-
+-	} else {
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057;
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				tx_pwrctrl_tbl =
+-				    nphy_tpc_txgain_ipa_5g_2057rev7;
+-			}
+-
+-		} else {
+-			tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g;
+-		}
+-	}
+-
+-	return tx_pwrctrl_tbl;
+-}
+-
+-static void
+-wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state,
+-			    u8 core)
+-{
+-	s32 tone_freq;
+-	u8 off_core;
+-	u16 mixgain = 0;
+-
+-	off_core = core ^ 0x1;
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7),
+-							  wlc_phy_read_lpf_bw_ctl_nphy
+-							  (pi, 0), 0, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->pubpi.radiorev == 5) {
+-				mixgain = (core == 0) ? 0x20 : 0x00;
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				mixgain = 0x00;
+-
+-			} else if ((pi->pubpi.radiorev <= 4)
+-				   || (pi->pubpi.radiorev == 6)) {
+-
+-				mixgain = 0x00;
+-			}
+-
+-		} else {
+-			if ((pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				mixgain = 0x50;
+-			} else if ((pi->pubpi.radiorev == 3)
+-				   || (pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				mixgain = 0x0;
+-			}
+-		}
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11),
+-						  mixgain, (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+-						     1, (1 << core), 0);
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_tx_pu,
+-						     0, (1 << off_core), 0);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5),
+-						  0, (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0,
+-						  (1 << core), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xa6 : 0xa7);
+-		state->afeoverride[core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+-		state->afectrl[off_core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6);
+-		state->afeoverride[off_core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f);
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 2), 0);
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-				 0xa5), (0x1 << 2), (0x1 << 2));
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6),
+-			    (0x1 << 2), (0x1 << 2));
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 :
+-				 0x8f), (0x1 << 2), (0x1 << 2));
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			state->pwrup[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_2G_PWRUP);
+-			state->atten[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_2G_ATTEN);
+-			state->pwrup[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_2G_PWRUP);
+-			state->atten[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_2G_ATTEN);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TXRXCOUPLE_2G_PWRUP, 0xc);
+-
+-			if ((pi->pubpi.radiorev == 3) ||
+-			    (pi->pubpi.radiorev == 4) ||
+-			    (pi->pubpi.radiorev == 6)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN, 0xf0);
+-
+-			} else if (pi->pubpi.radiorev == 5) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN,
+-						 (core == 0) ? 0xf7 : 0xf2);
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN, 0xf0);
+-
+-			}
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_2G_PWRUP, 0x0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_2G_ATTEN, 0xff);
+-
+-		} else {
+-			state->pwrup[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_5G_PWRUP);
+-			state->atten[core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					    TXRXCOUPLE_5G_ATTEN);
+-			state->pwrup[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_5G_PWRUP);
+-			state->atten[off_core] =
+-			    READ_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					    TXRXCOUPLE_5G_ATTEN);
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-					 TXRXCOUPLE_5G_PWRUP, 0xc);
+-
+-			if ((pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN, 0xf4);
+-
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN, 0xf0);
+-			}
+-
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_5G_PWRUP, 0x0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
+-					 TXRXCOUPLE_5G_ATTEN, 0xff);
+-		}
+-
+-		tone_freq = 4000;
+-
+-		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (1) << 13);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-	} else {
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0);
+-
+-		state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ?
+-						    0xa6 : 0xa7);
+-		state->afeoverride[core] =
+-		    read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5);
+-
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7),
+-			    (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0);
+-		mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-				 0xa5),
+-			    (0x1 << 0) |
+-			    (0x1 << 1) |
+-			    (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2));
+-
+-		state->vga_master[core] =
+-		    READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER);
+-		WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b);
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			state->fbmix[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+-					    TXFBMIX_G);
+-			state->intpa_master[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					    INTPAG_MASTER);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G,
+-					 0x03);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAG_MASTER, 0x04);
+-		} else {
+-			state->fbmix[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, RX, core,
+-					    TXFBMIX_A);
+-			state->intpa_master[core] =
+-			    READ_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					    INTPAA_MASTER);
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A,
+-					 0x03);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-					 INTPAA_MASTER, 0x04);
+-
+-		}
+-
+-		tone_freq = 4000;
+-
+-		wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+-	}
+-}
+-
+-static void
+-wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state)
+-{
+-	u8 core;
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_PWRUP, 0);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_2G_ATTEN,
+-						 state->atten[core]);
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_PWRUP, 0);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TXRXCOUPLE_5G_ATTEN,
+-						 state->atten[core]);
+-			}
+-		}
+-
+-		if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  1, 0x3, 0,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		} else {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2),
+-							  0, 0x3, 1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		}
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1),
+-						  0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID2);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xa6 : 0xa7, state->afectrl[core]);
+-			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+-				      0xa5, state->afeoverride[core]);
+-		}
+-
+-		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+-					    (state->mm & 0xff));
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 7)
+-		    || NREV_GE(pi->pubpi.phy_rev, 8)) {
+-			wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0,
+-							  1,
+-							  NPHY_REV7_RFCTRLOVERRIDE_ID1);
+-		}
+-	} else {
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1);
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-			WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER,
+-					 state->vga_master[core]);
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+-						 TXFBMIX_G, state->fbmix[core]);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAG_MASTER,
+-						 state->intpa_master[core]);
+-			} else {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, RX, core,
+-						 TXFBMIX_A, state->fbmix[core]);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 INTPAA_MASTER,
+-						 state->intpa_master[core]);
+-			}
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xa6 : 0xa7, state->afectrl[core]);
+-			write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f :
+-				      0xa5, state->afeoverride[core]);
+-		}
+-
+-		wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff,
+-					    (state->mm & 0xff));
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1);
+-	}
+-}
+-
+-static void
+-wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start,
+-		u32 end)
+-{
+-	u32 *buf, *src, *dst, sz;
+-
+-	sz = end - start + 1;
+-
+-	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
+-	if (NULL == buf) {
+-		return;
+-	}
+-
+-	src = buf;
+-	dst = buf + NPHY_PAPD_EPS_TBL_SIZE;
+-
+-	wlc_phy_table_read_nphy(pi,
+-				(core ==
+-				 PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 :
+-				 NPHY_TBL_ID_EPSILONTBL1),
+-				NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src);
+-
+-	do {
+-		u32 phy_a1, phy_a2;
+-		s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7;
+-
+-		phy_a1 = end - min(end, (winsz >> 1));
+-		phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1));
+-		phy_a3 = phy_a2 - phy_a1 + 1;
+-		phy_a6 = 0;
+-		phy_a7 = 0;
+-
+-		do {
+-			wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4,
+-						    &phy_a5);
+-			phy_a6 += phy_a4;
+-			phy_a7 += phy_a5;
+-		} while (phy_a2-- != phy_a1);
+-
+-		phy_a6 /= phy_a3;
+-		phy_a7 /= phy_a3;
+-		dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff);
+-	} while (end-- != start);
+-
+-	wlc_phy_table_write_nphy(pi,
+-				 (core ==
+-				  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 :
+-				 NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst);
+-
+-	kfree(buf);
+-}
+-
+-static void
+-wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains,
+-		phy_cal_mode_t cal_mode, u8 core)
+-{
+-	u16 phy_a1, phy_a2, phy_a3;
+-	u16 phy_a4, phy_a5;
+-	bool phy_a6;
+-	u8 phy_a7, m[2];
+-	u32 phy_a8 = 0;
+-	nphy_txgains_t phy_a9;
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 3))
+-		return;
+-
+-	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
+-
+-	phy_a6 = ((cal_mode == CAL_GCTRL)
+-		  || (cal_mode == CAL_SOFT)) ? true : false;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		phy_a9 = wlc_phy_get_tx_gain_nphy(pi);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			phy_a5 = ((phy_a9.txlpf[core] << 15) |
+-				  (phy_a9.txgm[core] << 12) |
+-				  (phy_a9.pga[core] << 8) |
+-				  (txgains->gains.pad[core] << 3) |
+-				  (phy_a9.ipa[core]));
+-		} else {
+-			phy_a5 = ((phy_a9.txlpf[core] << 15) |
+-				  (phy_a9.txgm[core] << 12) |
+-				  (txgains->gains.pga[core] << 8) |
+-				  (phy_a9.pad[core] << 3) | (phy_a9.ipa[core]));
+-		}
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_txgain,
+-						     phy_a5, (1 << core), 0);
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if ((pi->pubpi.radiorev <= 4)
+-			    || (pi->pubpi.radiorev == 6)) {
+-
+-				m[core] = IS40MHZ(pi) ? 60 : 79;
+-			} else {
+-
+-				m[core] = IS40MHZ(pi) ? 45 : 64;
+-			}
+-
+-		} else {
+-			m[core] = IS40MHZ(pi) ? 75 : 107;
+-		}
+-
+-		m[phy_a7] = 0;
+-		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+-
+-		phy_a2 = 63;
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->sh->chip == BCM6362_CHIP_ID) {
+-				phy_a1 = 35;
+-				phy_a3 = 35;
+-			} else if ((pi->pubpi.radiorev == 4)
+-				   || (pi->pubpi.radiorev == 6)) {
+-				phy_a1 = 30;
+-				phy_a3 = 30;
+-			} else {
+-				phy_a1 = 25;
+-				phy_a3 = 25;
+-			}
+-		} else {
+-			if ((pi->pubpi.radiorev == 5)
+-			    || (pi->pubpi.radiorev == 7)
+-			    || (pi->pubpi.radiorev == 8)) {
+-				phy_a1 = 25;
+-				phy_a3 = 25;
+-			} else {
+-				phy_a1 = 35;
+-				phy_a3 = 35;
+-			}
+-		}
+-
+-		if (cal_mode == CAL_GCTRL) {
+-			if ((pi->pubpi.radiorev == 5)
+-			    && (CHSPEC_IS2G(pi->radio_chanspec))) {
+-				phy_a1 = 55;
+-			} else if (((pi->pubpi.radiorev == 7) &&
+-				    (CHSPEC_IS2G(pi->radio_chanspec))) ||
+-				   ((pi->pubpi.radiorev == 8) &&
+-				    (CHSPEC_IS2G(pi->radio_chanspec)))) {
+-				phy_a1 = 60;
+-			} else {
+-				phy_a1 = 63;
+-			}
+-
+-		} else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) {
+-
+-			phy_a1 = 35;
+-			phy_a3 = 35;
+-		}
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (1) << 13);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-		write_phy_reg(pi, 0x2a1, 0x80);
+-		write_phy_reg(pi, 0x2a2, 0x100);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 4), (11) << 4);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 8), (11) << 8);
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x7 << 0), (0x3) << 0);
+-
+-		write_phy_reg(pi, 0x2e5, 0x20);
+-
+-		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  1, ((core == 0) ? 1 : 2), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, ((core == 0) ? 2 : 1), 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		write_phy_reg(pi, 0x2be, 1);
+-		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+-
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-
+-		wlc_phy_table_write_nphy(pi,
+-					 (core ==
+-					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+-					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+-					 32, &phy_a8);
+-
+-		if (cal_mode != CAL_GCTRL) {
+-			if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-				wlc_phy_a1_nphy(pi, core, 5, 0, 35);
+-			}
+-		}
+-
+-		wlc_phy_rfctrl_override_1tomany_nphy(pi,
+-						     NPHY_REV7_RfctrlOverride_cmd_txgain,
+-						     phy_a5, (1 << core), 1);
+-
+-	} else {
+-
+-		if (txgains) {
+-			if (txgains->useindex) {
+-				phy_a4 = 15 - ((txgains->index) >> 3);
+-				if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-					if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-						phy_a5 = 0x00f7 | (phy_a4 << 8);
+-
+-						if (pi->sh->chip ==
+-						    BCM47162_CHIP_ID) {
+-							phy_a5 =
+-							    0x10f7 | (phy_a4 <<
+-								      8);
+-						}
+-					} else
+-					    if (NREV_IS(pi->pubpi.phy_rev, 5))
+-						phy_a5 = 0x10f7 | (phy_a4 << 8);
+-					else
+-						phy_a5 = 0x50f7 | (phy_a4 << 8);
+-				} else {
+-					phy_a5 = 0x70f7 | (phy_a4 << 8);
+-				}
+-				wlc_phy_rfctrl_override_nphy(pi,
+-							     (0x1 << 13),
+-							     phy_a5,
+-							     (1 << core), 0);
+-			} else {
+-				wlc_phy_rfctrl_override_nphy(pi,
+-							     (0x1 << 13),
+-							     0x5bf7,
+-							     (1 << core), 0);
+-			}
+-		}
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			m[core] = IS40MHZ(pi) ? 45 : 64;
+-		} else {
+-			m[core] = IS40MHZ(pi) ? 75 : 107;
+-		}
+-
+-		m[phy_a7] = 0;
+-		wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]);
+-
+-		phy_a2 = 63;
+-
+-		if (cal_mode == CAL_FULL) {
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		} else if (cal_mode == CAL_SOFT) {
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		} else if (cal_mode == CAL_GCTRL) {
+-			phy_a1 = 63;
+-			phy_a3 = 25;
+-		} else {
+-
+-			phy_a1 = 25;
+-			phy_a3 = 25;
+-		}
+-
+-		mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (1) << 0);
+-
+-		mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 :
+-			    0x29b, (0x1 << 0), (0) << 0);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 13), (1) << 13);
+-
+-			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 13), (0) << 13);
+-
+-			write_phy_reg(pi, 0x2a1, 0x20);
+-			write_phy_reg(pi, 0x2a2, 0x60);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 4), (9) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 8), (9) << 8);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0xf << 0), (0x2) << 0);
+-
+-			write_phy_reg(pi, 0x2e5, 0x20);
+-		} else {
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 11), (1) << 11);
+-
+-			mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x1 << 11), (0) << 11);
+-
+-			write_phy_reg(pi, 0x2a1, 0x80);
+-			write_phy_reg(pi, 0x2a2, 0x600);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 4), (0) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 8), (0) << 8);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 :
+-				    0x2a4, (0x7 << 0), (0x3) << 0);
+-
+-			mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8);
+-
+-		}
+-
+-		mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0);
+-
+-		mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0);
+-
+-		write_phy_reg(pi, 0x2be, 1);
+-		SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000);
+-
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0);
+-
+-		wlc_phy_table_write_nphy(pi,
+-					 (core ==
+-					  PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0
+-					 : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3,
+-					 32, &phy_a8);
+-
+-		if (cal_mode != CAL_GCTRL) {
+-			wlc_phy_a1_nphy(pi, core, 5, 0, 40);
+-		}
+-	}
+-}
+-
+-static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core)
+-{
+-	int phy_a1;
+-	int phy_a2;
+-	bool phy_a3;
+-	nphy_ipa_txcalgains_t phy_a4;
+-	bool phy_a5 = false;
+-	bool phy_a6 = true;
+-	s32 phy_a7, phy_a8;
+-	u32 phy_a9;
+-	int phy_a10;
+-	bool phy_a11 = false;
+-	int phy_a12;
+-	u8 phy_a13 = 0;
+-	u8 phy_a14;
+-	u8 *phy_a15 = NULL;
+-
+-	phy_a4.useindex = true;
+-	phy_a12 = start_gain;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-
+-		phy_a2 = 20;
+-		phy_a1 = 1;
+-
+-		if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-			if (pi->pubpi.radiorev == 5) {
+-
+-				phy_a15 = pad_gain_codes_used_2057rev5;
+-				phy_a13 = sizeof(pad_gain_codes_used_2057rev5) /
+-				    sizeof(pad_gain_codes_used_2057rev5[0]) - 1;
+-
+-			} else if ((pi->pubpi.radiorev == 7)
+-				   || (pi->pubpi.radiorev == 8)) {
+-
+-				phy_a15 = pad_gain_codes_used_2057rev7;
+-				phy_a13 = sizeof(pad_gain_codes_used_2057rev7) /
+-				    sizeof(pad_gain_codes_used_2057rev7[0]) - 1;
+-
+-			} else {
+-
+-				phy_a15 = pad_all_gain_codes_2057;
+-				phy_a13 = sizeof(pad_all_gain_codes_2057) /
+-				    sizeof(pad_all_gain_codes_2057[0]) - 1;
+-			}
+-
+-		} else {
+-
+-			phy_a15 = pga_all_gain_codes_2057;
+-			phy_a13 = sizeof(pga_all_gain_codes_2057) /
+-			    sizeof(pga_all_gain_codes_2057[0]) - 1;
+-		}
+-
+-		phy_a14 = 0;
+-
+-		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_a4.gains.pad[core] =
+-				    (u16) phy_a15[phy_a12];
+-			} else {
+-				phy_a4.gains.pga[core] =
+-				    (u16) phy_a15[phy_a12];
+-			}
+-
+-			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+-
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_EPSILONTBL0 :
+-						 NPHY_TBL_ID_EPSILONTBL1), 1,
+-						63, 32, &phy_a9);
+-
+-			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+-
+-			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+-				  (phy_a8 == 4095) || (phy_a8 == -4096));
+-
+-			if (!phy_a6 && (phy_a3 != phy_a5)) {
+-				if (!phy_a3) {
+-					phy_a12 -= (u8) phy_a1;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			if (phy_a3)
+-				phy_a12 += (u8) phy_a1;
+-			else
+-				phy_a12 -= (u8) phy_a1;
+-
+-			if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) {
+-				if (phy_a12 < phy_a14) {
+-					phy_a12 = phy_a14;
+-				} else {
+-					phy_a12 = phy_a13;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			phy_a6 = false;
+-			phy_a5 = phy_a3;
+-		}
+-
+-	} else {
+-		phy_a2 = 10;
+-		phy_a1 = 8;
+-		for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) {
+-			phy_a4.index = (u8) phy_a12;
+-			wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core);
+-
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_EPSILONTBL0 :
+-						 NPHY_TBL_ID_EPSILONTBL1), 1,
+-						63, 32, &phy_a9);
+-
+-			wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8);
+-
+-			phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) ||
+-				  (phy_a8 == 4095) || (phy_a8 == -4096));
+-
+-			if (!phy_a6 && (phy_a3 != phy_a5)) {
+-				if (!phy_a3) {
+-					phy_a12 -= (u8) phy_a1;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			if (phy_a3)
+-				phy_a12 += (u8) phy_a1;
+-			else
+-				phy_a12 -= (u8) phy_a1;
+-
+-			if ((phy_a12 < 0) || (phy_a12 > 127)) {
+-				if (phy_a12 < 0) {
+-					phy_a12 = 0;
+-				} else {
+-					phy_a12 = 127;
+-				}
+-				phy_a11 = true;
+-				break;
+-			}
+-
+-			phy_a6 = false;
+-			phy_a5 = phy_a3;
+-		}
+-
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		return (u8) phy_a15[phy_a12];
+-	} else {
+-		return (u8) phy_a12;
+-	}
+-
+-}
+-
+-static void wlc_phy_a4(phy_info_t *pi, bool full_cal)
+-{
+-	nphy_ipa_txcalgains_t phy_b1[2];
+-	nphy_papd_restore_state phy_b2;
+-	bool phy_b3;
+-	u8 phy_b4;
+-	u8 phy_b5;
+-	s16 phy_b6, phy_b7, phy_b8;
+-	u16 phy_b9;
+-	s16 phy_b10, phy_b11, phy_b12;
+-
+-	phy_b11 = 0;
+-	phy_b12 = 0;
+-	phy_b7 = 0;
+-	phy_b8 = 0;
+-	phy_b6 = 0;
+-
+-	if (pi->nphy_papd_skip == 1)
+-		return;
+-
+-	phy_b3 =
+-	    (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
+-	if (!phy_b3) {
+-		wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	pi->nphy_force_papd_cal = false;
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++)
+-		pi->nphy_papd_tx_gain_at_last_cal[phy_b5] =
+-		    wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5);
+-
+-	pi->nphy_papd_last_cal = pi->sh->now;
+-	pi->nphy_papd_recal_counter++;
+-
+-	if (NORADIO_ENAB(pi->pubpi))
+-		return;
+-
+-	phy_b4 = pi->nphy_txpwrctrl;
+-	wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32,
+-				 nphy_papd_scaltbl);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32,
+-				 nphy_papd_scaltbl);
+-
+-	phy_b9 = read_phy_reg(pi, 0x01);
+-	mod_phy_reg(pi, 0x01, (0x1 << 15), 0);
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		s32 i, val = 0;
+-		for (i = 0; i < 64; i++) {
+-			wlc_phy_table_write_nphy(pi,
+-						 ((phy_b5 ==
+-						   PHY_CORE_0) ?
+-						  NPHY_TBL_ID_EPSILONTBL0 :
+-						  NPHY_TBL_ID_EPSILONTBL1), 1,
+-						 i, 32, &val);
+-		}
+-	}
+-
+-	wlc_phy_ipa_restore_tx_digi_filts_nphy(pi);
+-
+-	phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi);
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-
+-				if ((pi->pubpi.radiorev == 3)
+-				    || (pi->pubpi.radiorev == 4)
+-				    || (pi->pubpi.radiorev == 6)) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    23;
+-
+-				} else if (pi->pubpi.radiorev == 5) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    0;
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    wlc_phy_a3_nphy(pi,
+-							    pi->
+-							    nphy_papd_cal_gain_index
+-							    [phy_b5], phy_b5);
+-
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    0;
+-					pi->nphy_papd_cal_gain_index[phy_b5] =
+-					    wlc_phy_a3_nphy(pi,
+-							    pi->
+-							    nphy_papd_cal_gain_index
+-							    [phy_b5], phy_b5);
+-
+-				}
+-
+-				phy_b1[phy_b5].gains.pad[phy_b5] =
+-				    pi->nphy_papd_cal_gain_index[phy_b5];
+-
+-			} else {
+-				pi->nphy_papd_cal_gain_index[phy_b5] = 0;
+-				pi->nphy_papd_cal_gain_index[phy_b5] =
+-				    wlc_phy_a3_nphy(pi,
+-						    pi->
+-						    nphy_papd_cal_gain_index
+-						    [phy_b5], phy_b5);
+-				phy_b1[phy_b5].gains.pga[phy_b5] =
+-				    pi->nphy_papd_cal_gain_index[phy_b5];
+-			}
+-		} else {
+-			phy_b1[phy_b5].useindex = true;
+-			phy_b1[phy_b5].index = 16;
+-			phy_b1[phy_b5].index =
+-			    wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5);
+-
+-			pi->nphy_papd_cal_gain_index[phy_b5] =
+-			    15 - ((phy_b1[phy_b5].index) >> 3);
+-		}
+-
+-		switch (pi->nphy_papd_cal_type) {
+-		case 0:
+-			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5);
+-			break;
+-		case 1:
+-			wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5);
+-			break;
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+-		}
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2);
+-	}
+-
+-	for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) {
+-		int eps_offset = 0;
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				if (pi->pubpi.radiorev == 3) {
+-					eps_offset = -2;
+-				} else if (pi->pubpi.radiorev == 5) {
+-					eps_offset = 3;
+-				} else {
+-					eps_offset = -1;
+-				}
+-			} else {
+-				eps_offset = 2;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5];
+-				phy_b10 = 0;
+-				if ((pi->pubpi.radiorev == 3) ||
+-				    (pi->pubpi.radiorev == 4) ||
+-				    (pi->pubpi.radiorev == 6)) {
+-					phy_b12 =
+-					    -
+-					    (nphy_papd_padgain_dlt_2g_2057rev3n4
+-					     [phy_b8]
+-					     + 1) / 2;
+-					phy_b10 = -1;
+-				} else if (pi->pubpi.radiorev == 5) {
+-					phy_b12 =
+-					    -(nphy_papd_padgain_dlt_2g_2057rev5
+-					      [phy_b8]
+-					      + 1) / 2;
+-				} else if ((pi->pubpi.radiorev == 7) ||
+-					   (pi->pubpi.radiorev == 8)) {
+-					phy_b12 =
+-					    -(nphy_papd_padgain_dlt_2g_2057rev7
+-					      [phy_b8]
+-					      + 1) / 2;
+-				}
+-			} else {
+-				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
+-				if ((pi->pubpi.radiorev == 3) ||
+-				    (pi->pubpi.radiorev == 4) ||
+-				    (pi->pubpi.radiorev == 6)) {
+-					phy_b11 =
+-					    -(nphy_papd_pgagain_dlt_5g_2057
+-					      [phy_b7]
+-					      + 1) / 2;
+-				} else if ((pi->pubpi.radiorev == 7)
+-					   || (pi->pubpi.radiorev == 8)) {
+-					phy_b11 =
+-					    -(nphy_papd_pgagain_dlt_5g_2057rev7
+-					      [phy_b7]
+-					      + 1) / 2;
+-				}
+-
+-				phy_b10 = -9;
+-			}
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b6 =
+-				    -60 + 27 + eps_offset + phy_b12 + phy_b10;
+-			} else {
+-				phy_b6 =
+-				    -60 + 27 + eps_offset + phy_b11 + phy_b10;
+-			}
+-
+-			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7), (phy_b6) << 7);
+-
+-			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+-		} else {
+-			if (NREV_LT(pi->pubpi.phy_rev, 5)) {
+-				eps_offset = 4;
+-			} else {
+-				eps_offset = 2;
+-			}
+-
+-			phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				phy_b11 =
+-				    -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] +
+-				      1) / 2;
+-				phy_b10 = 0;
+-			} else {
+-				phy_b11 =
+-				    -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] +
+-				      1) / 2;
+-				phy_b10 = -9;
+-			}
+-
+-			phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10;
+-
+-			mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 :
+-				    0x29c, (0x1ff << 7), (phy_b6) << 7);
+-
+-			pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6;
+-		}
+-	}
+-
+-	mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-	mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-		    0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 6)) {
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 13), (0) << 13);
+-
+-	} else {
+-		mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 11), (0) << 11);
+-
+-		mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 :
+-			    0x2a4, (0x1 << 11), (0) << 11);
+-
+-	}
+-	pi->nphy_papdcomp = NPHY_PAPD_COMP_ON;
+-
+-	write_phy_reg(pi, 0x01, phy_b9);
+-
+-	wlc_phy_ipa_set_tx_digi_filts_nphy(pi);
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4);
+-	if (phy_b4 == PHY_TPC_HW_OFF) {
+-		wlc_phy_txpwr_index_nphy(pi, (1 << 0),
+-					 (s8) (pi->nphy_txpwrindex[0].
+-						 index_internal), false);
+-		wlc_phy_txpwr_index_nphy(pi, (1 << 1),
+-					 (s8) (pi->nphy_txpwrindex[1].
+-						 index_internal), false);
+-	}
+-
+-	wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-
+-	if (!phy_b3) {
+-		wlapi_enable_mac(pi->sh->physhim);
+-	}
+-}
+-
+-void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi)
+-{
+-	uint core;
+-	u32 txgain;
+-	u16 rad_gain, dac_gain, bbmult, m1m2;
+-	u8 txpi[2], chan_freq_range;
+-	s32 rfpwr_offset;
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	if (pi->sh->sromrev < 4) {
+-		txpi[0] = txpi[1] = 72;
+-	} else {
+-
+-		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-		switch (chan_freq_range) {
+-		case WL_CHAN_FREQ_RANGE_2G:
+-			txpi[0] = pi->nphy_txpid2g[0];
+-			txpi[1] = pi->nphy_txpid2g[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GL:
+-			txpi[0] = pi->nphy_txpid5gl[0];
+-			txpi[1] = pi->nphy_txpid5gl[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GM:
+-			txpi[0] = pi->nphy_txpid5g[0];
+-			txpi[1] = pi->nphy_txpid5g[1];
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GH:
+-			txpi[0] = pi->nphy_txpid5gh[0];
+-			txpi[1] = pi->nphy_txpid5gh[1];
+-			break;
+-		default:
+-			txpi[0] = txpi[1] = 91;
+-			break;
+-		}
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		txpi[0] = txpi[1] = 30;
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		txpi[0] = txpi[1] = 40;
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 7)) {
+-
+-		if ((txpi[0] < 40) || (txpi[0] > 100) ||
+-		    (txpi[1] < 40) || (txpi[1] > 100))
+-			txpi[0] = txpi[1] = 91;
+-	}
+-
+-	pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0];
+-	pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1];
+-	pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0];
+-	pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1];
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if (PHY_IPA(pi)) {
+-				u32 *tx_gaintbl =
+-				    wlc_phy_get_ipa_gaintbl_nphy(pi);
+-				txgain = tx_gaintbl[txpi[core]];
+-			} else {
+-				if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-					if NREV_IS
+-						(pi->pubpi.phy_rev, 3) {
+-						txgain =
+-						    nphy_tpc_5GHz_txgain_rev3
+-						    [txpi[core]];
+-					} else if NREV_IS
+-						(pi->pubpi.phy_rev, 4) {
+-						txgain =
+-						    (pi->srom_fem5g.extpagain ==
+-						     3) ?
+-						    nphy_tpc_5GHz_txgain_HiPwrEPA
+-						    [txpi[core]] :
+-						    nphy_tpc_5GHz_txgain_rev4
+-						    [txpi[core]];
+-					} else {
+-						txgain =
+-						    nphy_tpc_5GHz_txgain_rev5
+-						    [txpi[core]];
+-					}
+-				} else {
+-					if (NREV_GE(pi->pubpi.phy_rev, 5) &&
+-					    (pi->srom_fem2g.extpagain == 3)) {
+-						txgain =
+-						    nphy_tpc_txgain_HiPwrEPA
+-						    [txpi[core]];
+-					} else {
+-						txgain =
+-						    nphy_tpc_txgain_rev3[txpi
+-									 [core]];
+-					}
+-				}
+-			}
+-		} else {
+-			txgain = nphy_tpc_txgain[txpi[core]];
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+-		} else {
+-			rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1);
+-		} else {
+-			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+-		}
+-		bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-					 0xa5), (0x1 << 8), (0x1 << 8));
+-		} else {
+-			mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+-		}
+-		write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain);
+-
+-		wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-					 &rad_gain);
+-
+-		wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-		m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-		m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+-		wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-		if (PHY_IPA(pi)) {
+-			wlc_phy_table_read_nphy(pi,
+-						(core ==
+-						 PHY_CORE_0 ?
+-						 NPHY_TBL_ID_CORE1TXPWRCTL :
+-						 NPHY_TBL_ID_CORE2TXPWRCTL), 1,
+-						576 + txpi[core], 32,
+-						&rfpwr_offset);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1ff << 4),
+-				    ((s16) rfpwr_offset) << 4);
+-
+-			mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (1) << 2);
+-
+-		}
+-	}
+-
+-	and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0)));
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void
+-wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset,
+-				u8 tmp_max_pwr, u8 rate_start,
+-				u8 rate_end)
+-{
+-	u8 rate;
+-	u8 word_num, nibble_num;
+-	u8 tmp_nibble;
+-
+-	for (rate = rate_start; rate <= rate_end; rate++) {
+-		word_num = (rate - rate_start) >> 2;
+-		nibble_num = (rate - rate_start) & 0x3;
+-		tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf;
+-
+-		srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble;
+-	}
+-}
+-
+-static void
+-wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset,
+-			    u8 rate_start, u8 rate_end)
+-{
+-	u8 rate;
+-
+-	for (rate = rate_start; rate <= rate_end; rate++) {
+-		srom_max[rate] -= 2 * pwr_offset;
+-	}
+-}
+-
+-void
+-wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start,
+-				u8 rate_mcs_end, u8 rate_ofdm_start)
+-{
+-	u8 rate1, rate2;
+-
+-	rate2 = rate_ofdm_start;
+-	for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) {
+-		power[rate1] = power[rate2];
+-		rate2 += (rate1 == rate_mcs_start) ? 2 : 1;
+-	}
+-	power[rate_mcs_end] = power[rate_mcs_end - 1];
+-}
+-
+-void
+-wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start,
+-				u8 rate_ofdm_end, u8 rate_mcs_start)
+-{
+-	u8 rate1, rate2;
+-
+-	for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start;
+-	     rate1 <= rate_ofdm_end; rate1++, rate2++) {
+-		power[rate1] = power[rate2];
+-		if (rate1 == rate_ofdm_start)
+-			power[++rate1] = power[rate2];
+-	}
+-}
+-
+-void wlc_phy_txpwr_apply_nphy(phy_info_t *pi)
+-{
+-	uint rate1, rate2, band_num;
+-	u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0;
+-	u8 tmp_max_pwr = 0;
+-	u16 pwr_offsets1[2], *pwr_offsets2 = NULL;
+-	u8 *tx_srom_max_rate = NULL;
+-
+-	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+-		switch (band_num) {
+-		case 0:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_2g);
+-
+-			pwr_offsets1[0] = pi->cck2gpo;
+-			wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g,
+-							pwr_offsets1,
+-							tmp_max_pwr,
+-							TXP_FIRST_CCK,
+-							TXP_LAST_CCK);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm2gpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs2gpo;
+-
+-			tmp_cddpo = pi->cdd2gpo;
+-			tmp_stbcpo = pi->stbc2gpo;
+-			tmp_bw40po = pi->bw402gpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_2g;
+-			break;
+-		case 1:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gm);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5gpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5gpo;
+-
+-			tmp_cddpo = pi->cdd5gpo;
+-			tmp_stbcpo = pi->stbc5gpo;
+-			tmp_bw40po = pi->bw405gpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid;
+-			break;
+-		case 2:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gl);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5glpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5glpo;
+-
+-			tmp_cddpo = pi->cdd5glpo;
+-			tmp_stbcpo = pi->stbc5glpo;
+-			tmp_bw40po = pi->bw405glpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_low;
+-			break;
+-		case 3:
+-
+-			tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh,
+-					  pi->nphy_pwrctrl_info[1].max_pwr_5gh);
+-
+-			pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff);
+-			pwr_offsets1[1] =
+-			    (u16) (pi->ofdm5ghpo >> 16) & 0xffff;
+-
+-			pwr_offsets2 = pi->mcs5ghpo;
+-
+-			tmp_cddpo = pi->cdd5ghpo;
+-			tmp_stbcpo = pi->stbc5ghpo;
+-			tmp_bw40po = pi->bw405ghpo;
+-
+-			tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi;
+-			break;
+-		}
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1,
+-						tmp_max_pwr, TXP_FIRST_OFDM,
+-						TXP_LAST_OFDM);
+-
+-		wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate,
+-						TXP_FIRST_MCS_20_SISO,
+-						TXP_LAST_MCS_20_SISO,
+-						TXP_FIRST_OFDM);
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+-						tmp_max_pwr,
+-						TXP_FIRST_MCS_20_CDD,
+-						TXP_LAST_MCS_20_CDD);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+-						    TXP_FIRST_MCS_20_CDD,
+-						    TXP_LAST_MCS_20_CDD);
+-		}
+-
+-		wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-						TXP_FIRST_OFDM_20_CDD,
+-						TXP_LAST_OFDM_20_CDD,
+-						TXP_FIRST_MCS_20_CDD);
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2,
+-						tmp_max_pwr,
+-						TXP_FIRST_MCS_20_STBC,
+-						TXP_LAST_MCS_20_STBC);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_stbcpo,
+-						    TXP_FIRST_MCS_20_STBC,
+-						    TXP_LAST_MCS_20_STBC);
+-		}
+-
+-		wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-						&pwr_offsets2[2], tmp_max_pwr,
+-						TXP_FIRST_MCS_20_SDM,
+-						TXP_LAST_MCS_20_SDM);
+-
+-		if (NPHY_IS_SROM_REINTERPRET) {
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_SISO,
+-							TXP_LAST_MCS_40_SISO);
+-
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-							TXP_FIRST_OFDM_40_SISO,
+-							TXP_LAST_OFDM_40_SISO,
+-							TXP_FIRST_MCS_40_SISO);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_CDD,
+-							TXP_LAST_MCS_40_CDD);
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo,
+-						    TXP_FIRST_MCS_40_CDD,
+-						    TXP_LAST_MCS_40_CDD);
+-
+-			wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate,
+-							TXP_FIRST_OFDM_40_CDD,
+-							TXP_LAST_OFDM_40_CDD,
+-							TXP_FIRST_MCS_40_CDD);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[4],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_STBC,
+-							TXP_LAST_MCS_40_STBC);
+-
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_stbcpo,
+-						    TXP_FIRST_MCS_40_STBC,
+-						    TXP_LAST_MCS_40_STBC);
+-
+-			wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate,
+-							&pwr_offsets2[6],
+-							tmp_max_pwr,
+-							TXP_FIRST_MCS_40_SDM,
+-							TXP_LAST_MCS_40_SDM);
+-		} else {
+-
+-			for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 =
+-			     TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM;
+-			     rate1++, rate2++)
+-				tx_srom_max_rate[rate1] =
+-				    tx_srom_max_rate[rate2];
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate,
+-						    tmp_bw40po,
+-						    TXP_FIRST_OFDM_40_SISO,
+-						    TXP_LAST_MCS_40_SDM);
+-		}
+-
+-		tx_srom_max_rate[TXP_MCS_32] =
+-		    tx_srom_max_rate[TXP_FIRST_MCS_40_CDD];
+-	}
+-
+-	return;
+-}
+-
+-static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi)
+-{
+-	u16 bw40po, cddpo, stbcpo, bwduppo;
+-	uint band_num;
+-
+-	if (pi->sh->sromrev >= 9) {
+-
+-		return;
+-	}
+-
+-	bw40po = (u16) PHY_GETINTVAR(pi, "bw40po");
+-	pi->bw402gpo = bw40po & 0xf;
+-	pi->bw405gpo = (bw40po & 0xf0) >> 4;
+-	pi->bw405glpo = (bw40po & 0xf00) >> 8;
+-	pi->bw405ghpo = (bw40po & 0xf000) >> 12;
+-
+-	cddpo = (u16) PHY_GETINTVAR(pi, "cddpo");
+-	pi->cdd2gpo = cddpo & 0xf;
+-	pi->cdd5gpo = (cddpo & 0xf0) >> 4;
+-	pi->cdd5glpo = (cddpo & 0xf00) >> 8;
+-	pi->cdd5ghpo = (cddpo & 0xf000) >> 12;
+-
+-	stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo");
+-	pi->stbc2gpo = stbcpo & 0xf;
+-	pi->stbc5gpo = (stbcpo & 0xf0) >> 4;
+-	pi->stbc5glpo = (stbcpo & 0xf00) >> 8;
+-	pi->stbc5ghpo = (stbcpo & 0xf000) >> 12;
+-
+-	bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo");
+-	pi->bwdup2gpo = bwduppo & 0xf;
+-	pi->bwdup5gpo = (bwduppo & 0xf0) >> 4;
+-	pi->bwdup5glpo = (bwduppo & 0xf00) >> 8;
+-	pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12;
+-
+-	for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) {
+-		switch (band_num) {
+-		case 0:
+-
+-			pi->nphy_txpid2g[PHY_CORE_0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid2ga0");
+-			pi->nphy_txpid2g[PHY_CORE_1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid2ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g =
+-			    (s8) PHY_GETINTVAR(pi, "maxp2ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g =
+-			    (s8) PHY_GETINTVAR(pi, "maxp2ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw0a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw0a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw1a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw1a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw2a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa2gw2a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g =
+-			    (s8) PHY_GETINTVAR(pi, "itt2ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g =
+-			    (s8) PHY_GETINTVAR(pi, "itt2ga1");
+-
+-			pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo");
+-
+-			pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo");
+-
+-			pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0");
+-			pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1");
+-			pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2");
+-			pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3");
+-			pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4");
+-			pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5");
+-			pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6");
+-			pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7");
+-			break;
+-		case 1:
+-
+-			pi->nphy_txpid5g[PHY_CORE_0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5ga0");
+-			pi->nphy_txpid5g[PHY_CORE_1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5ga1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw0a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw0a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw1a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw1a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw2a0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5gw2a1");
+-			pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "itt5ga0");
+-			pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm =
+-			    (s8) PHY_GETINTVAR(pi, "itt5ga1");
+-
+-			pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo");
+-
+-			pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0");
+-			pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1");
+-			pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2");
+-			pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3");
+-			pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4");
+-			pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5");
+-			pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6");
+-			pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7");
+-			break;
+-		case 2:
+-
+-			pi->nphy_txpid5gl[0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gla0");
+-			pi->nphy_txpid5gl[1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gla1");
+-			pi->nphy_pwrctrl_info[0].max_pwr_5gl =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gla0");
+-			pi->nphy_pwrctrl_info[1].max_pwr_5gl =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gla1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw0a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw0a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw1a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw1a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw2a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5glw2a1");
+-			pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0;
+-			pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0;
+-
+-			pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo");
+-
+-			pi->mcs5glpo[0] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo0");
+-			pi->mcs5glpo[1] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo1");
+-			pi->mcs5glpo[2] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo2");
+-			pi->mcs5glpo[3] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo3");
+-			pi->mcs5glpo[4] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo4");
+-			pi->mcs5glpo[5] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo5");
+-			pi->mcs5glpo[6] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo6");
+-			pi->mcs5glpo[7] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5glpo7");
+-			break;
+-		case 3:
+-
+-			pi->nphy_txpid5gh[0] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gha0");
+-			pi->nphy_txpid5gh[1] =
+-			    (u8) PHY_GETINTVAR(pi, "txpid5gha1");
+-			pi->nphy_pwrctrl_info[0].max_pwr_5gh =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gha0");
+-			pi->nphy_pwrctrl_info[1].max_pwr_5gh =
+-			    (s8) PHY_GETINTVAR(pi, "maxp5gha1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw0a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw0a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw1a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw1a1");
+-			pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw2a0");
+-			pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 =
+-			    (s16) PHY_GETINTVAR(pi, "pa5ghw2a1");
+-			pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0;
+-			pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0;
+-
+-			pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo");
+-
+-			pi->mcs5ghpo[0] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo0");
+-			pi->mcs5ghpo[1] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo1");
+-			pi->mcs5ghpo[2] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo2");
+-			pi->mcs5ghpo[3] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo3");
+-			pi->mcs5ghpo[4] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo4");
+-			pi->mcs5ghpo[5] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo5");
+-			pi->mcs5ghpo[6] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo6");
+-			pi->mcs5ghpo[7] =
+-			    (u16) PHY_GETINTVAR(pi, "mcs5ghpo7");
+-			break;
+-		}
+-	}
+-
+-	wlc_phy_txpwr_apply_nphy(pi);
+-}
+-
+-static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi)
+-{
+-
+-	pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch");
+-	pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g");
+-	pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g");
+-
+-	pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g");
+-	pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g");
+-	pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g");
+-	pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g");
+-	pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g");
+-
+-	pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g");
+-	pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g");
+-	pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g");
+-	pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g");
+-	if (PHY_GETVAR(pi, "antswctl5g")) {
+-
+-		pi->srom_fem5g.antswctrllut =
+-		    (u8) PHY_GETINTVAR(pi, "antswctl5g");
+-	} else {
+-
+-		pi->srom_fem5g.antswctrllut =
+-		    (u8) PHY_GETINTVAR(pi, "antswctl2g");
+-	}
+-
+-	wlc_phy_txpower_ipa_upd(pi);
+-
+-	pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh");
+-	if (pi->phy_txcore_disable_temp == 0) {
+-		pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP;
+-	}
+-
+-	pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset");
+-	if (pi->phy_tempsense_offset != 0) {
+-		if (pi->phy_tempsense_offset >
+-		    (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) {
+-			pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET;
+-		} else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT +
+-						    NPHY_SROM_MINTEMPOFFSET)) {
+-			pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET;
+-		} else {
+-			pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT;
+-		}
+-	}
+-
+-	pi->phy_txcore_enable_temp =
+-	    pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP;
+-
+-	pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta");
+-	if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) {
+-		pi->phycal_tempdelta = 0;
+-	}
+-
+-	wlc_phy_txpwr_srom_read_ppr_nphy(pi);
+-
+-	return true;
+-}
+-
+-void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi)
+-{
+-	u8 tx_pwr_ctrl_state;
+-	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+-	wlc_phy_txpwrctrl_pwr_setup_nphy(pi);
+-
+-	tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-}
+-
+-static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi)
+-{
+-	u32 idx;
+-	u16 iqloCalbuf[7];
+-	u32 iqcomp, locomp, curr_locomp;
+-	s8 locomp_i, locomp_q;
+-	s8 curr_locomp_i, curr_locomp_q;
+-	u32 tbl_id, tbl_len, tbl_offset;
+-	u32 regval[128];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf);
+-
+-	tbl_len = 128;
+-	tbl_offset = 320;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-		iqcomp =
+-		    (tbl_id ==
+-		     26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) |
+-		    (iqloCalbuf[1] & 0x3ff)
+-		    : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) |
+-		    (iqloCalbuf[3] & 0x3ff);
+-
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			regval[idx] = iqcomp;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	tbl_offset = 448;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-
+-		locomp =
+-		    (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]);
+-		locomp_i = (s8) ((locomp >> 8) & 0xff);
+-		locomp_q = (s8) ((locomp) & 0xff);
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				curr_locomp_i = locomp_i;
+-				curr_locomp_q = locomp_q;
+-			} else {
+-				curr_locomp_i = (s8) ((locomp_i *
+-							 nphy_tpc_loscale[idx] +
+-							 128) >> 8);
+-				curr_locomp_q =
+-				    (s8) ((locomp_q * nphy_tpc_loscale[idx] +
+-					     128) >> 8);
+-			}
+-			curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8);
+-			curr_locomp |= (u32) (curr_locomp_q & 0xff);
+-			regval[idx] = curr_locomp;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	if (NREV_LT(pi->pubpi.phy_rev, 2)) {
+-
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF);
+-		wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi)
+-{
+-	u8 core;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x5);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MUX, 0xe);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIA, 0);
+-
+-				if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIG, 0x1);
+-				} else {
+-
+-					WRITE_RADIO_REG3(pi, RADIO_2057, TX,
+-							 core, TSSIG, 0x31);
+-				}
+-			} else {
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MASTER, 0x9);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TX_SSI_MUX, 0xc);
+-				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
+-						 TSSIG, 0);
+-
+-				if (pi->pubpi.radiorev != 5) {
+-					if (!NREV_IS(pi->pubpi.phy_rev, 7)) {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x1);
+-					} else {
+-
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TSSIA, 0x31);
+-					}
+-				}
+-			}
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG,
+-					 0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC,
+-					 0);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM,
+-					 0x3);
+-			WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1,
+-					 0x0);
+-		}
+-	} else {
+-		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31,
+-				(CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 :
+-				0x80);
+-		WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0);
+-		WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29);
+-
+-		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM,
+-					 0x3);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1,
+-					 0x8);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2,
+-					 0x0);
+-			WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3,
+-					 0x0);
+-
+-			if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MASTER, 0x5);
+-
+-				if (pi->pubpi.radiorev != 5)
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIA, 0x0);
+-				if (NREV_GE(pi->pubpi.phy_rev, 5)) {
+-
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIG, 0x31);
+-				} else {
+-					WRITE_RADIO_REG2(pi, RADIO_2056, TX,
+-							 core, TSSIG, 0x11);
+-				}
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MUX, 0xe);
+-			} else {
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MASTER, 0x9);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TSSIA, 0x31);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TSSIG, 0x0);
+-				WRITE_RADIO_REG2(pi, RADIO_2056, TX, core,
+-						 TX_SSI_MUX, 0xc);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi)
+-{
+-	s32 rssi_buf[4];
+-	s32 int_val;
+-
+-	if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi))
+-
+-		return;
+-
+-	if (PHY_IPA(pi)) {
+-		wlc_phy_ipa_internal_tssi_setup_nphy(pi);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-						  0, 0x3, 0,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0);
+-	}
+-
+-	wlc_phy_stopplayback_nphy(pi);
+-
+-	wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false);
+-
+-	udelay(20);
+-	int_val =
+-	    wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf,
+-				   1);
+-	wlc_phy_stopplayback_nphy(pi);
+-	wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0);
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12),
+-						  0, 0x3, 1,
+-						  NPHY_REV7_RFCTRLOVERRIDE_ID0);
+-	} else if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-	} else {
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g =
+-		    (u8) ((int_val >> 24) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g =
+-		    (u8) ((int_val >> 8) & 0xff);
+-
+-		pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g =
+-		    (u8) ((int_val >> 16) & 0xff);
+-		pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g =
+-		    (u8) ((int_val) & 0xff);
+-	}
+-
+-}
+-
+-static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi)
+-{
+-	u32 idx;
+-	s16 a1[2], b0[2], b1[2];
+-	s8 target_pwr_qtrdbm[2];
+-	s32 num, den, pwr_est;
+-	u8 chan_freq_range;
+-	u8 idle_tssi[2];
+-	u32 tbl_id, tbl_len, tbl_offset;
+-	u32 regval[64];
+-	u8 core;
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	or_phy_reg(pi, 0x122, (0x1 << 0));
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15)));
+-	} else {
+-
+-		or_phy_reg(pi, 0x1e7, (0x1 << 15));
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-
+-	if (pi->sh->sromrev < 4) {
+-		idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-		idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-		target_pwr_qtrdbm[0] = 13 * 4;
+-		target_pwr_qtrdbm[1] = 13 * 4;
+-		a1[0] = -424;
+-		a1[1] = -424;
+-		b0[0] = 5612;
+-		b0[1] = 5612;
+-		b1[1] = -1393;
+-		b1[0] = -1393;
+-	} else {
+-
+-		chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0);
+-		switch (chan_freq_range) {
+-		case WL_CHAN_FREQ_RANGE_2G:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_2g;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_2g;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GL:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gl;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gl;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GM:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gm;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gm;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1;
+-			break;
+-		case WL_CHAN_FREQ_RANGE_5GH:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
+-			target_pwr_qtrdbm[0] =
+-			    pi->nphy_pwrctrl_info[0].max_pwr_5gh;
+-			target_pwr_qtrdbm[1] =
+-			    pi->nphy_pwrctrl_info[1].max_pwr_5gh;
+-			a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
+-			a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
+-			b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
+-			b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0;
+-			b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1;
+-			b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1;
+-			break;
+-		default:
+-			idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
+-			idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
+-			target_pwr_qtrdbm[0] = 13 * 4;
+-			target_pwr_qtrdbm[1] = 13 * 4;
+-			a1[0] = -424;
+-			a1[1] = -424;
+-			b0[0] = 5612;
+-			b0[1] = 5612;
+-			b1[1] = -1393;
+-			b1[0] = -1393;
+-			break;
+-		}
+-	}
+-
+-	target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
+-	target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-		if (pi->srom_fem2g.tssipos) {
+-			or_phy_reg(pi, 0x1e9, (0x1 << 14));
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-			for (core = 0; core <= 1; core++) {
+-				if (PHY_IPA(pi)) {
+-
+-					if (CHSPEC_IS2G(pi->radio_chanspec)) {
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TX_SSI_MUX,
+-								 0xe);
+-					} else {
+-						WRITE_RADIO_REG3(pi, RADIO_2057,
+-								 TX, core,
+-								 TX_SSI_MUX,
+-								 0xc);
+-					}
+-				} else {
+-				}
+-			}
+-		} else {
+-			if (PHY_IPA(pi)) {
+-
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX0,
+-						(CHSPEC_IS5G
+-						 (pi->
+-						  radio_chanspec)) ? 0xc : 0xe);
+-				write_radio_reg(pi,
+-						RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX1,
+-						(CHSPEC_IS5G
+-						 (pi->
+-						  radio_chanspec)) ? 0xc : 0xe);
+-			} else {
+-
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX0, 0x11);
+-				write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX |
+-						RADIO_2056_TX1, 0x11);
+-			}
+-		}
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
+-		(void)R_REG(&pi->regs->maccontrol);
+-		udelay(1);
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+-	} else {
+-		mod_phy_reg(pi, 0x1e7, (0x7f << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+-	}
+-
+-	if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-		mod_phy_reg(pi, 0x222, (0xff << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0));
+-	} else if (NREV_GT(pi->pubpi.phy_rev, 1)) {
+-		mod_phy_reg(pi, 0x222, (0xff << 0),
+-			    (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0));
+-	}
+-
+-	if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12))
+-		wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0);
+-
+-	write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0));
+-
+-	write_phy_reg(pi, 0x1e9,
+-		      (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8));
+-
+-	write_phy_reg(pi, 0x1ea,
+-		      (target_pwr_qtrdbm[0] << 0) |
+-		      (target_pwr_qtrdbm[1] << 8));
+-
+-	tbl_len = 64;
+-	tbl_offset = 0;
+-	for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL;
+-	     tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) {
+-
+-		for (idx = 0; idx < tbl_len; idx++) {
+-			num =
+-			    8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx);
+-			den = 32768 + a1[tbl_id - 26] * idx;
+-			pwr_est = max(((4 * num + den / 2) / den), -8);
+-			if (NREV_LT(pi->pubpi.phy_rev, 3)) {
+-				if (idx <=
+-				    (uint) (31 - idle_tssi[tbl_id - 26] + 1))
+-					pwr_est =
+-					    max(pwr_est,
+-						target_pwr_qtrdbm[tbl_id - 26] +
+-						1);
+-			}
+-			regval[idx] = (u32) pwr_est;
+-		}
+-		wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32,
+-					 regval);
+-	}
+-
+-	wlc_phy_txpwr_limit_to_tbl_nphy(pi);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8,
+-				 pi->adj_pwr_tbl_nphy);
+-	wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8,
+-				 pi->adj_pwr_tbl_nphy);
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi)
+-{
+-	return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) |
+-					     (0x1 << 14) | (0x1 << 13));
+-}
+-
+-static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core)
+-{
+-	u16 tmp;
+-	tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee));
+-
+-	tmp = (tmp & (0x7f << 8)) >> 8;
+-	return (u8) tmp;
+-}
+-
+-static void
+-wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1)
+-{
+-	mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0);
+-
+-	if (NREV_GT(pi->pubpi.phy_rev, 1))
+-		mod_phy_reg(pi, 0x222, (0xff << 0), idx1);
+-}
+-
+-u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi)
+-{
+-	u16 tmp;
+-	u16 pwr_idx[2];
+-
+-	if (wlc_phy_txpwr_ison_nphy(pi)) {
+-		pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0);
+-		pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1);
+-
+-		tmp = (pwr_idx[0] << 8) | pwr_idx[1];
+-	} else {
+-		tmp =
+-		    ((pi->nphy_txpwrindex[PHY_CORE_0].
+-		      index_internal & 0xff) << 8) | (pi->
+-						      nphy_txpwrindex
+-						      [PHY_CORE_1].
+-						      index_internal & 0xff);
+-	}
+-
+-	return tmp;
+-}
+-
+-void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi)
+-{
+-	if (PHY_IPA(pi)
+-	    && (pi->nphy_force_papd_cal
+-		|| (wlc_phy_txpwr_ison_nphy(pi)
+-		    &&
+-		    (((u32)
+-		      ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) -
+-			  pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4)
+-		     || ((u32)
+-			 ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) -
+-			     pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) {
+-		wlc_phy_a4(pi, true);
+-	}
+-}
+-
+-void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type)
+-{
+-	u16 mask = 0, val = 0, ishw = 0;
+-	u8 ctr;
+-	uint core;
+-	u32 tbl_offset;
+-	u32 tbl_len;
+-	u16 regval[84];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	switch (ctrl_type) {
+-	case PHY_TPC_HW_OFF:
+-	case PHY_TPC_HW_ON:
+-		pi->nphy_txpwrctrl = ctrl_type;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	if (ctrl_type == PHY_TPC_HW_OFF) {
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			if (wlc_phy_txpwr_ison_nphy(pi)) {
+-				for (core = 0; core < pi->pubpi.phy_corenum;
+-				     core++)
+-					pi->nphy_txpwr_idx[core] =
+-					    wlc_phy_txpwr_idx_cur_get_nphy(pi,
+-									   (u8)
+-									   core);
+-			}
+-
+-		}
+-
+-		tbl_len = 84;
+-		tbl_offset = 64;
+-		for (ctr = 0; ctr < tbl_len; ctr++) {
+-			regval[ctr] = 0;
+-		}
+-		wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16,
+-					 regval);
+-		wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16,
+-					 regval);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-
+-			and_phy_reg(pi, 0x1e7,
+-				    (u16) (~((0x1 << 15) |
+-						(0x1 << 14) | (0x1 << 13))));
+-		} else {
+-			and_phy_reg(pi, 0x1e7,
+-				    (u16) (~((0x1 << 14) | (0x1 << 13))));
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			or_phy_reg(pi, 0x8f, (0x1 << 8));
+-			or_phy_reg(pi, 0xa5, (0x1 << 8));
+-		} else {
+-			or_phy_reg(pi, 0xa5, (0x1 << 14));
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x53);
+-		else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+-				       MHF1_IQSWAP_WAR, WLC_BAND_ALL);
+-
+-	} else {
+-
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64,
+-					 8, pi->adj_pwr_tbl_nphy);
+-		wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64,
+-					 8, pi->adj_pwr_tbl_nphy);
+-
+-		ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0;
+-		mask = (0x1 << 14) | (0x1 << 13);
+-		val = (ishw << 14) | (ishw << 13);
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			mask |= (0x1 << 15);
+-			val |= (ishw << 15);
+-		}
+-
+-		mod_phy_reg(pi, 0x1e7, mask, val);
+-
+-		if (CHSPEC_IS5G(pi->radio_chanspec)) {
+-			if (NREV_GE(pi->pubpi.phy_rev, 7)) {
+-				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32);
+-				mod_phy_reg(pi, 0x222, (0xff << 0), 0x32);
+-			} else {
+-				mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64);
+-				if (NREV_GT(pi->pubpi.phy_rev, 1))
+-					mod_phy_reg(pi, 0x222,
+-						    (0xff << 0), 0x64);
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			if ((pi->nphy_txpwr_idx[0] != 128)
+-			    && (pi->nphy_txpwr_idx[1] != 128)) {
+-				wlc_phy_txpwr_idx_cur_set_nphy(pi,
+-							       pi->
+-							       nphy_txpwr_idx
+-							       [0],
+-							       pi->
+-							       nphy_txpwr_idx
+-							       [1]);
+-			}
+-		}
+-
+-		if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-			and_phy_reg(pi, 0x8f, ~(0x1 << 8));
+-			and_phy_reg(pi, 0xa5, ~(0x1 << 8));
+-		} else {
+-			and_phy_reg(pi, 0xa5, ~(0x1 << 14));
+-		}
+-
+-		if (NREV_IS(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b);
+-		else if (NREV_LT(pi->pubpi.phy_rev, 2))
+-			mod_phy_reg(pi, 0xdc, 0x00ff, 0x40);
+-
+-		if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi))
+-			wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR,
+-				       0x0, WLC_BAND_ALL);
+-
+-		if (PHY_IPA(pi)) {
+-			mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (0) << 2);
+-
+-			mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 :
+-				    0x29b, (0x1 << 2), (0) << 2);
+-
+-		}
+-
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void
+-wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex,
+-			 bool restore_cals)
+-{
+-	u8 core, txpwrctl_tbl;
+-	u16 tx_ind0, iq_ind0, lo_ind0;
+-	u16 m1m2;
+-	u32 txgain;
+-	u16 rad_gain, dac_gain;
+-	u8 bbmult;
+-	u32 iqcomp;
+-	u16 iqcomp_a, iqcomp_b;
+-	u32 locomp;
+-	u16 tmpval;
+-	u8 tx_pwr_ctrl_state;
+-	s32 rfpwr_offset;
+-	u16 regval[2];
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-
+-	tx_ind0 = 192;
+-	iq_ind0 = 320;
+-	lo_ind0 = 448;
+-
+-	for (core = 0; core < pi->pubpi.phy_corenum; core++) {
+-
+-		if ((core_mask & (1 << core)) == 0) {
+-			continue;
+-		}
+-
+-		txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27;
+-
+-		if (txpwrindex < 0) {
+-			if (pi->nphy_txpwrindex[core].index < 0) {
+-
+-				continue;
+-			}
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				mod_phy_reg(pi, 0x8f,
+-					    (0x1 << 8),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-				mod_phy_reg(pi, 0xa5, (0x1 << 8),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-			} else {
+-				mod_phy_reg(pi, 0xa5,
+-					    (0x1 << 14),
+-					    pi->nphy_txpwrindex[core].
+-					    AfectrlOverride);
+-			}
+-
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xaa : 0xab,
+-				      pi->nphy_txpwrindex[core].AfeCtrlDacGain);
+-
+-			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-						 &pi->nphy_txpwrindex[core].
+-						 rad_gain);
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-			m1m2 |= ((core == PHY_CORE_0) ?
+-				 (pi->nphy_txpwrindex[core].bbmult << 8) :
+-				 (pi->nphy_txpwrindex[core].bbmult << 0));
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-			if (restore_cals) {
+-
+-				wlc_phy_table_write_nphy(pi, 15, 2,
+-							 (80 + 2 * core), 16,
+-							 (void *)&pi->
+-							 nphy_txpwrindex[core].
+-							 iqcomp_a);
+-
+-				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+-							 16,
+-							 &pi->
+-							 nphy_txpwrindex[core].
+-							 locomp);
+-				wlc_phy_table_write_nphy(pi, 15, 1, (93 + core),
+-							 16,
+-							 (void *)&pi->
+-							 nphy_txpwrindex[core].
+-							 locomp);
+-			}
+-
+-			wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl);
+-
+-			pi->nphy_txpwrindex[core].index_internal =
+-			    pi->nphy_txpwrindex[core].index_internal_save;
+-		} else {
+-
+-			if (pi->nphy_txpwrindex[core].index < 0) {
+-
+-				if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-					mod_phy_reg(pi, 0x8f,
+-						    (0x1 << 8),
+-						    pi->nphy_txpwrindex[core].
+-						    AfectrlOverride);
+-					mod_phy_reg(pi, 0xa5, (0x1 << 8),
+-						    pi->nphy_txpwrindex[core].
+-						    AfectrlOverride);
+-				} else {
+-					pi->nphy_txpwrindex[core].
+-					    AfectrlOverride =
+-					    read_phy_reg(pi, 0xa5);
+-				}
+-
+-				pi->nphy_txpwrindex[core].AfeCtrlDacGain =
+-				    read_phy_reg(pi,
+-						 (core ==
+-						  PHY_CORE_0) ? 0xaa : 0xab);
+-
+-				wlc_phy_table_read_nphy(pi, 7, 1,
+-							(0x110 + core), 16,
+-							&pi->
+-							nphy_txpwrindex[core].
+-							rad_gain);
+-
+-				wlc_phy_table_read_nphy(pi, 15, 1, 87, 16,
+-							&tmpval);
+-				tmpval >>= ((core == PHY_CORE_0) ? 8 : 0);
+-				tmpval &= 0xff;
+-				pi->nphy_txpwrindex[core].bbmult =
+-				    (u8) tmpval;
+-
+-				wlc_phy_table_read_nphy(pi, 15, 2,
+-							(80 + 2 * core), 16,
+-							(void *)&pi->
+-							nphy_txpwrindex[core].
+-							iqcomp_a);
+-
+-				wlc_phy_table_read_nphy(pi, 15, 1, (85 + core),
+-							16,
+-							(void *)&pi->
+-							nphy_txpwrindex[core].
+-							locomp);
+-
+-				pi->nphy_txpwrindex[core].index_internal_save =
+-				    pi->nphy_txpwrindex[core].index_internal;
+-			}
+-
+-			tx_pwr_ctrl_state = pi->nphy_txpwrctrl;
+-			wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF);
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 1))
+-				wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(tx_ind0 + txpwrindex), 32,
+-						&txgain);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				rad_gain =
+-				    (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1);
+-			} else {
+-				rad_gain =
+-				    (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1);
+-			}
+-			dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1);
+-			bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1);
+-
+-			if (NREV_GE(pi->pubpi.phy_rev, 3)) {
+-				mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f :
+-						 0xa5), (0x1 << 8), (0x1 << 8));
+-			} else {
+-				mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14));
+-			}
+-			write_phy_reg(pi, (core == PHY_CORE_0) ?
+-				      0xaa : 0xab, dac_gain);
+-
+-			wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16,
+-						 &rad_gain);
+-
+-			wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2);
+-			m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00);
+-			m1m2 |=
+-			    ((core ==
+-			      PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0));
+-
+-			wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2);
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(iq_ind0 + txpwrindex), 32,
+-						&iqcomp);
+-			iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1);
+-			iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1);
+-
+-			if (restore_cals) {
+-				regval[0] = (u16) iqcomp_a;
+-				regval[1] = (u16) iqcomp_b;
+-				wlc_phy_table_write_nphy(pi, 15, 2,
+-							 (80 + 2 * core), 16,
+-							 regval);
+-			}
+-
+-			wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1,
+-						(lo_ind0 + txpwrindex), 32,
+-						&locomp);
+-			if (restore_cals) {
+-				wlc_phy_table_write_nphy(pi, 15, 1, (85 + core),
+-							 16, &locomp);
+-			}
+-
+-			if (NREV_IS(pi->pubpi.phy_rev, 1))
+-				wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF);
+-
+-			if (PHY_IPA(pi)) {
+-				wlc_phy_table_read_nphy(pi,
+-							(core ==
+-							 PHY_CORE_0 ?
+-							 NPHY_TBL_ID_CORE1TXPWRCTL
+-							 :
+-							 NPHY_TBL_ID_CORE2TXPWRCTL),
+-							1, 576 + txpwrindex, 32,
+-							&rfpwr_offset);
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-					    0x29b, (0x1ff << 4),
+-					    ((s16) rfpwr_offset) << 4);
+-
+-				mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 :
+-					    0x29b, (0x1 << 2), (1) << 2);
+-
+-			}
+-
+-			wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state);
+-		}
+-
+-		pi->nphy_txpwrindex[core].index = txpwrindex;
+-	}
+-
+-	if (pi->phyhang_avoid)
+-		wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-}
+-
+-void
+-wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr,
+-				   u8 txp_rate_idx)
+-{
+-	u8 chan_freq_range;
+-
+-	chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan);
+-	switch (chan_freq_range) {
+-	case WL_CHAN_FREQ_RANGE_2G:
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GM:
+-		*max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GL:
+-		*max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx];
+-		break;
+-	case WL_CHAN_FREQ_RANGE_5GH:
+-		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
+-		break;
+-	default:
+-		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
+-		break;
+-	}
+-
+-	return;
+-}
+-
+-void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable)
+-{
+-	u16 clip_off[] = { 0xffff, 0xffff };
+-
+-	if (enable) {
+-		if (pi->nphy_deaf_count == 0) {
+-			pi->classifier_state =
+-			    wlc_phy_classifier_nphy(pi, 0, 0);
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0), 4);
+-			wlc_phy_clip_det_nphy(pi, 0, pi->clip_state);
+-			wlc_phy_clip_det_nphy(pi, 1, clip_off);
+-		}
+-
+-		pi->nphy_deaf_count++;
+-
+-		wlc_phy_resetcca_nphy(pi);
+-
+-	} else {
+-		pi->nphy_deaf_count--;
+-
+-		if (pi->nphy_deaf_count == 0) {
+-			wlc_phy_classifier_nphy(pi, (0x7 << 0),
+-						pi->classifier_state);
+-			wlc_phy_clip_det_nphy(pi, 1, pi->clip_state);
+-		}
+-	}
+-}
+-
+-void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode)
+-{
+-	wlapi_suspend_mac_and_wait(pi->sh->physhim);
+-
+-	if (mode) {
+-		if (pi->nphy_deaf_count == 0)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, true);
+-	} else {
+-		if (pi->nphy_deaf_count > 0)
+-			wlc_phy_stay_in_carriersearch_nphy(pi, false);
+-	}
+-	wlapi_enable_mac(pi->sh->physhim);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
+deleted file mode 100644
+index c98176f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
++++ /dev/null
+@@ -1,296 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-
+-#include "wlc_phy_qmath.h"
+-
+-/*
+-Description: This function make 16 bit unsigned multiplication. To fit the output into
+-16 bits the 32 bit multiplication result is right shifted by 16 bits.
+-*/
+-u16 qm_mulu16(u16 op1, u16 op2)
+-{
+-	return (u16) (((u32) op1 * (u32) op2) >> 16);
+-}
+-
+-/*
+-Description: This function make 16 bit multiplication and return the result in 16 bits.
+-To fit the multiplication result into 16 bits the multiplication result is right shifted by
+-15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
+-due to the multiplication.
+-When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
+-*/
+-s16 qm_muls16(s16 op1, s16 op2)
+-{
+-	s32 result;
+-	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
+-		result = 0x7fffffff;
+-	} else {
+-		result = ((s32) (op1) * (s32) (op2));
+-	}
+-	return (s16) (result >> 15);
+-}
+-
+-/*
+-Description: This function add two 32 bit numbers and return the 32bit result.
+-If the result overflow 32 bits, the output will be saturated to 32bits.
+-*/
+-s32 qm_add32(s32 op1, s32 op2)
+-{
+-	s32 result;
+-	result = op1 + op2;
+-	if (op1 < 0 && op2 < 0 && result > 0) {
+-		result = 0x80000000;
+-	} else if (op1 > 0 && op2 > 0 && result < 0) {
+-		result = 0x7fffffff;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function add two 16 bit numbers and return the 16bit result.
+-If the result overflow 16 bits, the output will be saturated to 16bits.
+-*/
+-s16 qm_add16(s16 op1, s16 op2)
+-{
+-	s16 result;
+-	s32 temp = (s32) op1 + (s32) op2;
+-	if (temp > (s32) 0x7fff) {
+-		result = (s16) 0x7fff;
+-	} else if (temp < (s32) 0xffff8000) {
+-		result = (s16) 0xffff8000;
+-	} else {
+-		result = (s16) temp;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make 16 bit subtraction and return the 16bit result.
+-If the result overflow 16 bits, the output will be saturated to 16bits.
+-*/
+-s16 qm_sub16(s16 op1, s16 op2)
+-{
+-	s16 result;
+-	s32 temp = (s32) op1 - (s32) op2;
+-	if (temp > (s32) 0x7fff) {
+-		result = (s16) 0x7fff;
+-	} else if (temp < (s32) 0xffff8000) {
+-		result = (s16) 0xffff8000;
+-	} else {
+-		result = (s16) temp;
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 32 bit saturated left shift when the specified shift
+-is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
+-This function return the result after shifting operation.
+-*/
+-s32 qm_shl32(s32 op, int shift)
+-{
+-	int i;
+-	s32 result;
+-	result = op;
+-	if (shift > 31)
+-		shift = 31;
+-	else if (shift < -31)
+-		shift = -31;
+-	if (shift >= 0) {
+-		for (i = 0; i < shift; i++) {
+-			result = qm_add32(result, result);
+-		}
+-	} else {
+-		result = result >> (-shift);
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 16 bit saturated left shift when the specified shift
+-is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
+-This function return the result after shifting operation.
+-*/
+-s16 qm_shl16(s16 op, int shift)
+-{
+-	int i;
+-	s16 result;
+-	result = op;
+-	if (shift > 15)
+-		shift = 15;
+-	else if (shift < -15)
+-		shift = -15;
+-	if (shift > 0) {
+-		for (i = 0; i < shift; i++) {
+-			result = qm_add16(result, result);
+-		}
+-	} else {
+-		result = result >> (-shift);
+-	}
+-	return result;
+-}
+-
+-/*
+-Description: This function make a 16 bit right shift when shift is +ve.
+-This function make a 16 bit saturated left shift when shift is -ve. This function
+-return the result of the shift operation.
+-*/
+-s16 qm_shr16(s16 op, int shift)
+-{
+-	return qm_shl16(op, -shift);
+-}
+-
+-/*
+-Description: This function return the number of redundant sign bits in a 32 bit number.
+-Example: qm_norm32(0x00000080) = 23
+-*/
+-s16 qm_norm32(s32 op)
+-{
+-	u16 u16extraSignBits;
+-	if (op == 0) {
+-		return 31;
+-	} else {
+-		u16extraSignBits = 0;
+-		while ((op >> 31) == (op >> 30)) {
+-			u16extraSignBits++;
+-			op = op << 1;
+-		}
+-	}
+-	return u16extraSignBits;
+-}
+-
+-/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
+-static const s16 log_table[] = {
+-	0,
+-	1455,
+-	2866,
+-	4236,
+-	5568,
+-	6863,
+-	8124,
+-	9352,
+-	10549,
+-	11716,
+-	12855,
+-	13968,
+-	15055,
+-	16117,
+-	17156,
+-	18173,
+-	19168,
+-	20143,
+-	21098,
+-	22034,
+-	22952,
+-	23852,
+-	24736,
+-	25604,
+-	26455,
+-	27292,
+-	28114,
+-	28922,
+-	29717,
+-	30498,
+-	31267,
+-	32024
+-};
+-
+-#define LOG_TABLE_SIZE 32	/* log_table size */
+-#define LOG2_LOG_TABLE_SIZE 5	/* log2(log_table size) */
+-#define Q_LOG_TABLE 15		/* qformat of log_table */
+-#define LOG10_2		19728	/* log10(2) in q.16 */
+-
+-/*
+-Description:
+-This routine takes the input number N and its q format qN and compute
+-the log10(N). This routine first normalizes the input no N.	Then N is in mag*(2^x) format.
+-mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
+-From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
+-This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
+-As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
+-Next 16 MSBs are used for interpolation.
+-Inputs:
+-N - number to which log10 has to be found.
+-qN - q format of N
+-log10N - address where log10(N) will be written.
+-qLog10N - address where log10N qformat will be written.
+-Note/Problem:
+-For accurate results input should be in normalized or near normalized form.
+-*/
+-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
+-{
+-	s16 s16norm, s16tableIndex, s16errorApproximation;
+-	u16 u16offset;
+-	s32 s32log;
+-
+-	/* normalize the N. */
+-	s16norm = qm_norm32(N);
+-	N = N << s16norm;
+-
+-	/* The qformat of N after normalization.
+-	 * -30 is added to treat the no as between 1.0 to 2.0
+-	 * i.e. after adding the -30 to the qformat the decimal point will be
+-	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
+-	 * at the right side of 30th bit.
+-	 */
+-	qN = qN + s16norm - 30;
+-
+-	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
+-	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
+-
+-	/* remove the MSB. the MSB is always 1 after normalization. */
+-	s16tableIndex =
+-	    s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
+-
+-	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
+-	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
+-
+-	/* take the offset as the 16 MSBS after table index.
+-	 */
+-	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
+-
+-	/* look the log value in the table. */
+-	s32log = log_table[s16tableIndex];	/* q.15 format */
+-
+-	/* interpolate using the offset. */
+-	s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex]));	/* q.15 */
+-
+-	s32log = qm_add16((s16) s32log, s16errorApproximation);	/* q.15 format */
+-
+-	/* adjust for the qformat of the N as
+-	 * log2(mag * 2^x) = log2(mag) + x
+-	 */
+-	s32log = qm_add32(s32log, ((s32) -qN) << 15);	/* q.15 format */
+-
+-	/* normalize the result. */
+-	s16norm = qm_norm32(s32log);
+-
+-	/* bring all the important bits into lower 16 bits */
+-	s32log = qm_shl32(s32log, s16norm - 16);	/* q.15+s16norm-16 format */
+-
+-	/* compute the log10(N) by multiplying log2(N) with log10(2).
+-	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
+-	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
+-	 */
+-	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
+-
+-	/* write the q format of the result. */
+-	*qLog10N = 15 + s16norm - 16 + 1;
+-
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
+deleted file mode 100644
+index 3dcee1c..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef __QMATH_H__
+-#define __QMATH_H__
+-
+-u16 qm_mulu16(u16 op1, u16 op2);
+-
+-s16 qm_muls16(s16 op1, s16 op2);
+-
+-s32 qm_add32(s32 op1, s32 op2);
+-
+-s16 qm_add16(s16 op1, s16 op2);
+-
+-s16 qm_sub16(s16 op1, s16 op2);
+-
+-s32 qm_shl32(s32 op, int shift);
+-
+-s16 qm_shl16(s16 op, int shift);
+-
+-s16 qm_shr16(s16 op, int shift);
+-
+-s16 qm_norm32(s32 op);
+-
+-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
+-
+-#endif				/* #ifndef __QMATH_H__ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
+deleted file mode 100644
+index 72176ae..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h
++++ /dev/null
+@@ -1,1533 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_BCM20XX_H
+-#define	_BCM20XX_H
+-
+-#define	RADIO_IDCODE			0x01
+-
+-#define RADIO_DEFAULT_CORE		0
+-
+-#define	RXC0_RSSI_RST			0x80
+-#define	RXC0_MODE_RSSI			0x40
+-#define	RXC0_MODE_OFF			0x20
+-#define	RXC0_MODE_CM			0x10
+-#define	RXC0_LAN_LOAD			0x08
+-#define	RXC0_OFF_ADJ_MASK		0x07
+-
+-#define	TXC0_MODE_TXLPF			0x04
+-#define	TXC0_PA_TSSI_EN			0x02
+-#define	TXC0_TSSI_EN			0x01
+-
+-#define	TXC1_PA_GAIN_MASK		0x60
+-#define	TXC1_PA_GAIN_3DB		0x40
+-#define	TXC1_PA_GAIN_2DB		0x20
+-#define	TXC1_TX_MIX_GAIN		0x10
+-#define	TXC1_OFF_I_MASK			0x0c
+-#define	TXC1_OFF_Q_MASK			0x03
+-
+-#define	RADIO_2055_READ_OFF		0x100
+-#define	RADIO_2057_READ_OFF		0x200
+-
+-#define RADIO_2055_GEN_SPARE		0x00
+-#define RADIO_2055_SP_PIN_PD		0x02
+-#define RADIO_2055_SP_RSSI_CORE1	0x03
+-#define RADIO_2055_SP_PD_MISC_CORE1	0x04
+-#define RADIO_2055_SP_RSSI_CORE2	0x05
+-#define RADIO_2055_SP_PD_MISC_CORE2	0x06
+-#define RADIO_2055_SP_RX_GC1_CORE1	0x07
+-#define RADIO_2055_SP_RX_GC2_CORE1	0x08
+-#define RADIO_2055_SP_RX_GC1_CORE2	0x09
+-#define RADIO_2055_SP_RX_GC2_CORE2	0x0a
+-#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b
+-#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c
+-#define RADIO_2055_SP_TX_GC1_CORE1	0x0d
+-#define RADIO_2055_SP_TX_GC2_CORE1	0x0e
+-#define RADIO_2055_SP_TX_GC1_CORE2	0x0f
+-#define RADIO_2055_SP_TX_GC2_CORE2	0x10
+-#define RADIO_2055_MASTER_CNTRL1	0x11
+-#define RADIO_2055_MASTER_CNTRL2	0x12
+-#define RADIO_2055_PD_LGEN		0x13
+-#define RADIO_2055_PD_PLL_TS		0x14
+-#define RADIO_2055_PD_CORE1_LGBUF	0x15
+-#define RADIO_2055_PD_CORE1_TX		0x16
+-#define RADIO_2055_PD_CORE1_RXTX	0x17
+-#define RADIO_2055_PD_CORE1_RSSI_MISC	0x18
+-#define RADIO_2055_PD_CORE2_LGBUF	0x19
+-#define RADIO_2055_PD_CORE2_TX		0x1a
+-#define RADIO_2055_PD_CORE2_RXTX	0x1b
+-#define RADIO_2055_PD_CORE2_RSSI_MISC	0x1c
+-#define RADIO_2055_PWRDET_LGEN		0x1d
+-#define RADIO_2055_PWRDET_LGBUF_CORE1	0x1e
+-#define RADIO_2055_PWRDET_RXTX_CORE1	0x1f
+-#define RADIO_2055_PWRDET_LGBUF_CORE2	0x20
+-#define RADIO_2055_PWRDET_RXTX_CORE2	0x21
+-#define RADIO_2055_RRCCAL_CNTRL_SPARE	0x22
+-#define RADIO_2055_RRCCAL_N_OPT_SEL	0x23
+-#define RADIO_2055_CAL_MISC		0x24
+-#define RADIO_2055_CAL_COUNTER_OUT	0x25
+-#define RADIO_2055_CAL_COUNTER_OUT2	0x26
+-#define RADIO_2055_CAL_CVAR_CNTRL	0x27
+-#define RADIO_2055_CAL_RVAR_CNTRL	0x28
+-#define RADIO_2055_CAL_LPO_CNTRL	0x29
+-#define RADIO_2055_CAL_TS		0x2a
+-#define RADIO_2055_CAL_RCCAL_READ_TS	0x2b
+-#define RADIO_2055_CAL_RCAL_READ_TS	0x2c
+-#define RADIO_2055_PAD_DRIVER		0x2d
+-#define RADIO_2055_XO_CNTRL1		0x2e
+-#define RADIO_2055_XO_CNTRL2		0x2f
+-#define RADIO_2055_XO_REGULATOR		0x30
+-#define RADIO_2055_XO_MISC		0x31
+-#define RADIO_2055_PLL_LF_C1		0x32
+-#define RADIO_2055_PLL_CAL_VTH		0x33
+-#define RADIO_2055_PLL_LF_C2		0x34
+-#define RADIO_2055_PLL_REF		0x35
+-#define RADIO_2055_PLL_LF_R1		0x36
+-#define RADIO_2055_PLL_PFD_CP		0x37
+-#define RADIO_2055_PLL_IDAC_CPOPAMP	0x38
+-#define RADIO_2055_PLL_CP_REGULATOR	0x39
+-#define RADIO_2055_PLL_RCAL		0x3a
+-#define RADIO_2055_RF_PLL_MOD0		0x3b
+-#define RADIO_2055_RF_PLL_MOD1		0x3c
+-#define RADIO_2055_RF_MMD_IDAC1		0x3d
+-#define RADIO_2055_RF_MMD_IDAC0		0x3e
+-#define RADIO_2055_RF_MMD_SPARE		0x3f
+-#define RADIO_2055_VCO_CAL1		0x40
+-#define RADIO_2055_VCO_CAL2		0x41
+-#define RADIO_2055_VCO_CAL3		0x42
+-#define RADIO_2055_VCO_CAL4		0x43
+-#define RADIO_2055_VCO_CAL5		0x44
+-#define RADIO_2055_VCO_CAL6		0x45
+-#define RADIO_2055_VCO_CAL7		0x46
+-#define RADIO_2055_VCO_CAL8		0x47
+-#define RADIO_2055_VCO_CAL9		0x48
+-#define RADIO_2055_VCO_CAL10		0x49
+-#define RADIO_2055_VCO_CAL11		0x4a
+-#define RADIO_2055_VCO_CAL12		0x4b
+-#define RADIO_2055_VCO_CAL13		0x4c
+-#define RADIO_2055_VCO_CAL14		0x4d
+-#define RADIO_2055_VCO_CAL15		0x4e
+-#define RADIO_2055_VCO_CAL16		0x4f
+-#define RADIO_2055_VCO_KVCO		0x50
+-#define RADIO_2055_VCO_CAP_TAIL		0x51
+-#define RADIO_2055_VCO_IDAC_VCO		0x52
+-#define RADIO_2055_VCO_REGULATOR	0x53
+-#define RADIO_2055_PLL_RF_VTH		0x54
+-#define RADIO_2055_LGBUF_CEN_BUF	0x55
+-#define RADIO_2055_LGEN_TUNE1		0x56
+-#define RADIO_2055_LGEN_TUNE2		0x57
+-#define RADIO_2055_LGEN_IDAC1		0x58
+-#define RADIO_2055_LGEN_IDAC2		0x59
+-#define RADIO_2055_LGEN_BIAS_CNT	0x5a
+-#define RADIO_2055_LGEN_BIAS_IDAC	0x5b
+-#define RADIO_2055_LGEN_RCAL		0x5c
+-#define RADIO_2055_LGEN_DIV		0x5d
+-#define RADIO_2055_LGEN_SPARE2		0x5e
+-#define RADIO_2055_CORE1_LGBUF_A_TUNE	0x5f
+-#define RADIO_2055_CORE1_LGBUF_G_TUNE	0x60
+-#define RADIO_2055_CORE1_LGBUF_DIV	0x61
+-#define RADIO_2055_CORE1_LGBUF_A_IDAC	0x62
+-#define RADIO_2055_CORE1_LGBUF_G_IDAC	0x63
+-#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64
+-#define RADIO_2055_CORE1_LGBUF_SPARE	0x65
+-#define RADIO_2055_CORE1_RXRF_SPC1	0x66
+-#define RADIO_2055_CORE1_RXRF_REG1	0x67
+-#define RADIO_2055_CORE1_RXRF_REG2	0x68
+-#define RADIO_2055_CORE1_RXRF_RCAL	0x69
+-#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a
+-#define RADIO_2055_CORE1_RXBB_LPF	0x6b
+-#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c
+-#define RADIO_2055_CORE1_RXBB_VGA1_IDAC	0x6d
+-#define RADIO_2055_CORE1_RXBB_VGA2_IDAC	0x6e
+-#define RADIO_2055_CORE1_RXBB_VGA3_IDAC	0x6f
+-#define RADIO_2055_CORE1_RXBB_BUFO_CTRL	0x70
+-#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75
+-#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76
+-#define RADIO_2055_CORE1_RXBB_REGULATOR	0x77
+-#define RADIO_2055_CORE1_RXBB_SPARE1	0x78
+-#define RADIO_2055_CORE1_RXTXBB_RCAL	0x79
+-#define RADIO_2055_CORE1_TXRF_SGM_PGA	0x7a
+-#define RADIO_2055_CORE1_TXRF_SGM_PAD	0x7b
+-#define RADIO_2055_CORE1_TXRF_CNTR_PGA1	0x7c
+-#define RADIO_2055_CORE1_TXRF_CNTR_PAD1	0x7d
+-#define RADIO_2055_CORE1_TX_RFPGA_IDAC	0x7e
+-#define RADIO_2055_CORE1_TX_PGA_PAD_TN	0x7f
+-#define RADIO_2055_CORE1_TX_PAD_IDAC1	0x80
+-#define RADIO_2055_CORE1_TX_PAD_IDAC2	0x81
+-#define RADIO_2055_CORE1_TX_MX_BGTRIM	0x82
+-#define RADIO_2055_CORE1_TXRF_RCAL	0x83
+-#define RADIO_2055_CORE1_TXRF_PAD_TSSI1	0x84
+-#define RADIO_2055_CORE1_TXRF_PAD_TSSI2	0x85
+-#define RADIO_2055_CORE1_TX_RF_SPARE	0x86
+-#define RADIO_2055_CORE1_TXRF_IQCAL1	0x87
+-#define RADIO_2055_CORE1_TXRF_IQCAL2	0x88
+-#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89
+-#define RADIO_2055_CORE1_TXBB_LPF1	0x8a
+-#define RADIO_2055_CORE1_TX_VOS_CNCL	0x8b
+-#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c
+-#define RADIO_2055_CORE1_TX_BB_MXGM	0x8d
+-#define RADIO_2055_CORE2_LGBUF_A_TUNE	0x8e
+-#define RADIO_2055_CORE2_LGBUF_G_TUNE	0x8f
+-#define RADIO_2055_CORE2_LGBUF_DIV	0x90
+-#define RADIO_2055_CORE2_LGBUF_A_IDAC	0x91
+-#define RADIO_2055_CORE2_LGBUF_G_IDAC	0x92
+-#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93
+-#define RADIO_2055_CORE2_LGBUF_SPARE	0x94
+-#define RADIO_2055_CORE2_RXRF_SPC1	0x95
+-#define RADIO_2055_CORE2_RXRF_REG1	0x96
+-#define RADIO_2055_CORE2_RXRF_REG2	0x97
+-#define RADIO_2055_CORE2_RXRF_RCAL	0x98
+-#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99
+-#define RADIO_2055_CORE2_RXBB_LPF	0x9a
+-#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b
+-#define RADIO_2055_CORE2_RXBB_VGA1_IDAC	0x9c
+-#define RADIO_2055_CORE2_RXBB_VGA2_IDAC	0x9d
+-#define RADIO_2055_CORE2_RXBB_VGA3_IDAC	0x9e
+-#define RADIO_2055_CORE2_RXBB_BUFO_CTRL	0x9f
+-#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4
+-#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5
+-#define RADIO_2055_CORE2_RXBB_REGULATOR	0xa6
+-#define RADIO_2055_CORE2_RXBB_SPARE1	0xa7
+-#define RADIO_2055_CORE2_RXTXBB_RCAL	0xa8
+-#define RADIO_2055_CORE2_TXRF_SGM_PGA	0xa9
+-#define RADIO_2055_CORE2_TXRF_SGM_PAD	0xaa
+-#define RADIO_2055_CORE2_TXRF_CNTR_PGA1	0xab
+-#define RADIO_2055_CORE2_TXRF_CNTR_PAD1	0xac
+-#define RADIO_2055_CORE2_TX_RFPGA_IDAC	0xad
+-#define RADIO_2055_CORE2_TX_PGA_PAD_TN	0xae
+-#define RADIO_2055_CORE2_TX_PAD_IDAC1	0xaf
+-#define RADIO_2055_CORE2_TX_PAD_IDAC2	0xb0
+-#define RADIO_2055_CORE2_TX_MX_BGTRIM	0xb1
+-#define RADIO_2055_CORE2_TXRF_RCAL	0xb2
+-#define RADIO_2055_CORE2_TXRF_PAD_TSSI1	0xb3
+-#define RADIO_2055_CORE2_TXRF_PAD_TSSI2	0xb4
+-#define RADIO_2055_CORE2_TX_RF_SPARE	0xb5
+-#define RADIO_2055_CORE2_TXRF_IQCAL1	0xb6
+-#define RADIO_2055_CORE2_TXRF_IQCAL2	0xb7
+-#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8
+-#define RADIO_2055_CORE2_TXBB_LPF1	0xb9
+-#define RADIO_2055_CORE2_TX_VOS_CNCL	0xba
+-#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb
+-#define RADIO_2055_CORE2_TX_BB_MXGM	0xbc
+-#define RADIO_2055_PRG_GC_HPVGA23_21	0xbd
+-#define RADIO_2055_PRG_GC_HPVGA23_22	0xbe
+-#define RADIO_2055_PRG_GC_HPVGA23_23	0xbf
+-#define RADIO_2055_PRG_GC_HPVGA23_24	0xc0
+-#define RADIO_2055_PRG_GC_HPVGA23_25	0xc1
+-#define RADIO_2055_PRG_GC_HPVGA23_26	0xc2
+-#define RADIO_2055_PRG_GC_HPVGA23_27	0xc3
+-#define RADIO_2055_PRG_GC_HPVGA23_28	0xc4
+-#define RADIO_2055_PRG_GC_HPVGA23_29	0xc5
+-#define RADIO_2055_PRG_GC_HPVGA23_30	0xc6
+-#define RADIO_2055_CORE1_LNA_GAINBST	0xcd
+-#define RADIO_2055_CORE1_B0_NBRSSI_VCM	0xd2
+-#define RADIO_2055_CORE1_GEN_SPARE2		0xd6
+-#define RADIO_2055_CORE2_LNA_GAINBST	0xd9
+-#define RADIO_2055_CORE2_B0_NBRSSI_VCM	0xde
+-#define RADIO_2055_CORE2_GEN_SPARE2		0xe2
+-
+-#define RADIO_2055_GAINBST_GAIN_DB	6
+-#define RADIO_2055_GAINBST_CODE		0x6
+-
+-#define RADIO_2055_JTAGCTRL_MASK	0x04
+-#define RADIO_2055_JTAGSYNC_MASK	0x08
+-#define RADIO_2055_RRCAL_START		0x40
+-#define RADIO_2055_RRCAL_RST_N		0x01
+-#define RADIO_2055_CAL_LPO_ENABLE	0x80
+-#define RADIO_2055_RCAL_DONE		0x80
+-#define RADIO_2055_NBRSSI_VCM_I_MASK	0x03
+-#define RADIO_2055_NBRSSI_VCM_I_SHIFT	0x00
+-#define RADIO_2055_NBRSSI_VCM_Q_MASK	0x03
+-#define RADIO_2055_NBRSSI_VCM_Q_SHIFT	0x00
+-#define RADIO_2055_WBRSSI_VCM_IQ_MASK	0x0c
+-#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT	0x02
+-#define RADIO_2055_NBRSSI_PD		0x01
+-#define RADIO_2055_WBRSSI_G1_PD		0x04
+-#define RADIO_2055_WBRSSI_G2_PD		0x02
+-#define RADIO_2055_NBRSSI_SEL		0x01
+-#define RADIO_2055_WBRSSI_G1_SEL	0x04
+-#define RADIO_2055_WBRSSI_G2_SEL	0x02
+-#define RADIO_2055_COUPLE_RX_MASK	0x01
+-#define RADIO_2055_COUPLE_TX_MASK	0x02
+-#define RADIO_2055_GAINBST_DISABLE	0x02
+-#define RADIO_2055_GAINBST_VAL_MASK	0x07
+-#define RADIO_2055_RXMX_GC_MASK		0x0c
+-
+-#define RADIO_MIMO_CORESEL_OFF		0x0
+-#define RADIO_MIMO_CORESEL_CORE1	0x1
+-#define RADIO_MIMO_CORESEL_CORE2	0x2
+-#define RADIO_MIMO_CORESEL_CORE3	0x3
+-#define RADIO_MIMO_CORESEL_CORE4	0x4
+-#define RADIO_MIMO_CORESEL_ALLRX	0x5
+-#define RADIO_MIMO_CORESEL_ALLTX	0x6
+-#define RADIO_MIMO_CORESEL_ALLRXTX	0x7
+-
+-#define	RADIO_2064_READ_OFF		0x200
+-
+-#define RADIO_2064_REG000               0x0
+-#define RADIO_2064_REG001               0x1
+-#define RADIO_2064_REG002               0x2
+-#define RADIO_2064_REG003               0x3
+-#define RADIO_2064_REG004               0x4
+-#define RADIO_2064_REG005               0x5
+-#define RADIO_2064_REG006               0x6
+-#define RADIO_2064_REG007               0x7
+-#define RADIO_2064_REG008               0x8
+-#define RADIO_2064_REG009               0x9
+-#define RADIO_2064_REG00A               0xa
+-#define RADIO_2064_REG00B               0xb
+-#define RADIO_2064_REG00C               0xc
+-#define RADIO_2064_REG00D               0xd
+-#define RADIO_2064_REG00E               0xe
+-#define RADIO_2064_REG00F               0xf
+-#define RADIO_2064_REG010               0x10
+-#define RADIO_2064_REG011               0x11
+-#define RADIO_2064_REG012               0x12
+-#define RADIO_2064_REG013               0x13
+-#define RADIO_2064_REG014               0x14
+-#define RADIO_2064_REG015               0x15
+-#define RADIO_2064_REG016               0x16
+-#define RADIO_2064_REG017               0x17
+-#define RADIO_2064_REG018               0x18
+-#define RADIO_2064_REG019               0x19
+-#define RADIO_2064_REG01A               0x1a
+-#define RADIO_2064_REG01B               0x1b
+-#define RADIO_2064_REG01C               0x1c
+-#define RADIO_2064_REG01D               0x1d
+-#define RADIO_2064_REG01E               0x1e
+-#define RADIO_2064_REG01F               0x1f
+-#define RADIO_2064_REG020               0x20
+-#define RADIO_2064_REG021               0x21
+-#define RADIO_2064_REG022               0x22
+-#define RADIO_2064_REG023               0x23
+-#define RADIO_2064_REG024               0x24
+-#define RADIO_2064_REG025               0x25
+-#define RADIO_2064_REG026               0x26
+-#define RADIO_2064_REG027               0x27
+-#define RADIO_2064_REG028               0x28
+-#define RADIO_2064_REG029               0x29
+-#define RADIO_2064_REG02A               0x2a
+-#define RADIO_2064_REG02B               0x2b
+-#define RADIO_2064_REG02C               0x2c
+-#define RADIO_2064_REG02D               0x2d
+-#define RADIO_2064_REG02E               0x2e
+-#define RADIO_2064_REG02F               0x2f
+-#define RADIO_2064_REG030               0x30
+-#define RADIO_2064_REG031               0x31
+-#define RADIO_2064_REG032               0x32
+-#define RADIO_2064_REG033               0x33
+-#define RADIO_2064_REG034               0x34
+-#define RADIO_2064_REG035               0x35
+-#define RADIO_2064_REG036               0x36
+-#define RADIO_2064_REG037               0x37
+-#define RADIO_2064_REG038               0x38
+-#define RADIO_2064_REG039               0x39
+-#define RADIO_2064_REG03A               0x3a
+-#define RADIO_2064_REG03B               0x3b
+-#define RADIO_2064_REG03C               0x3c
+-#define RADIO_2064_REG03D               0x3d
+-#define RADIO_2064_REG03E               0x3e
+-#define RADIO_2064_REG03F               0x3f
+-#define RADIO_2064_REG040               0x40
+-#define RADIO_2064_REG041               0x41
+-#define RADIO_2064_REG042               0x42
+-#define RADIO_2064_REG043               0x43
+-#define RADIO_2064_REG044               0x44
+-#define RADIO_2064_REG045               0x45
+-#define RADIO_2064_REG046               0x46
+-#define RADIO_2064_REG047               0x47
+-#define RADIO_2064_REG048               0x48
+-#define RADIO_2064_REG049               0x49
+-#define RADIO_2064_REG04A               0x4a
+-#define RADIO_2064_REG04B               0x4b
+-#define RADIO_2064_REG04C               0x4c
+-#define RADIO_2064_REG04D               0x4d
+-#define RADIO_2064_REG04E               0x4e
+-#define RADIO_2064_REG04F               0x4f
+-#define RADIO_2064_REG050               0x50
+-#define RADIO_2064_REG051               0x51
+-#define RADIO_2064_REG052               0x52
+-#define RADIO_2064_REG053               0x53
+-#define RADIO_2064_REG054               0x54
+-#define RADIO_2064_REG055               0x55
+-#define RADIO_2064_REG056               0x56
+-#define RADIO_2064_REG057               0x57
+-#define RADIO_2064_REG058               0x58
+-#define RADIO_2064_REG059               0x59
+-#define RADIO_2064_REG05A               0x5a
+-#define RADIO_2064_REG05B               0x5b
+-#define RADIO_2064_REG05C               0x5c
+-#define RADIO_2064_REG05D               0x5d
+-#define RADIO_2064_REG05E               0x5e
+-#define RADIO_2064_REG05F               0x5f
+-#define RADIO_2064_REG060               0x60
+-#define RADIO_2064_REG061               0x61
+-#define RADIO_2064_REG062               0x62
+-#define RADIO_2064_REG063               0x63
+-#define RADIO_2064_REG064               0x64
+-#define RADIO_2064_REG065               0x65
+-#define RADIO_2064_REG066               0x66
+-#define RADIO_2064_REG067               0x67
+-#define RADIO_2064_REG068               0x68
+-#define RADIO_2064_REG069               0x69
+-#define RADIO_2064_REG06A               0x6a
+-#define RADIO_2064_REG06B               0x6b
+-#define RADIO_2064_REG06C               0x6c
+-#define RADIO_2064_REG06D               0x6d
+-#define RADIO_2064_REG06E               0x6e
+-#define RADIO_2064_REG06F               0x6f
+-#define RADIO_2064_REG070               0x70
+-#define RADIO_2064_REG071               0x71
+-#define RADIO_2064_REG072               0x72
+-#define RADIO_2064_REG073               0x73
+-#define RADIO_2064_REG074               0x74
+-#define RADIO_2064_REG075               0x75
+-#define RADIO_2064_REG076               0x76
+-#define RADIO_2064_REG077               0x77
+-#define RADIO_2064_REG078               0x78
+-#define RADIO_2064_REG079               0x79
+-#define RADIO_2064_REG07A               0x7a
+-#define RADIO_2064_REG07B               0x7b
+-#define RADIO_2064_REG07C               0x7c
+-#define RADIO_2064_REG07D               0x7d
+-#define RADIO_2064_REG07E               0x7e
+-#define RADIO_2064_REG07F               0x7f
+-#define RADIO_2064_REG080               0x80
+-#define RADIO_2064_REG081               0x81
+-#define RADIO_2064_REG082               0x82
+-#define RADIO_2064_REG083               0x83
+-#define RADIO_2064_REG084               0x84
+-#define RADIO_2064_REG085               0x85
+-#define RADIO_2064_REG086               0x86
+-#define RADIO_2064_REG087               0x87
+-#define RADIO_2064_REG088               0x88
+-#define RADIO_2064_REG089               0x89
+-#define RADIO_2064_REG08A               0x8a
+-#define RADIO_2064_REG08B               0x8b
+-#define RADIO_2064_REG08C               0x8c
+-#define RADIO_2064_REG08D               0x8d
+-#define RADIO_2064_REG08E               0x8e
+-#define RADIO_2064_REG08F               0x8f
+-#define RADIO_2064_REG090               0x90
+-#define RADIO_2064_REG091               0x91
+-#define RADIO_2064_REG092               0x92
+-#define RADIO_2064_REG093               0x93
+-#define RADIO_2064_REG094               0x94
+-#define RADIO_2064_REG095               0x95
+-#define RADIO_2064_REG096               0x96
+-#define RADIO_2064_REG097               0x97
+-#define RADIO_2064_REG098               0x98
+-#define RADIO_2064_REG099               0x99
+-#define RADIO_2064_REG09A               0x9a
+-#define RADIO_2064_REG09B               0x9b
+-#define RADIO_2064_REG09C               0x9c
+-#define RADIO_2064_REG09D               0x9d
+-#define RADIO_2064_REG09E               0x9e
+-#define RADIO_2064_REG09F               0x9f
+-#define RADIO_2064_REG0A0               0xa0
+-#define RADIO_2064_REG0A1               0xa1
+-#define RADIO_2064_REG0A2               0xa2
+-#define RADIO_2064_REG0A3               0xa3
+-#define RADIO_2064_REG0A4               0xa4
+-#define RADIO_2064_REG0A5               0xa5
+-#define RADIO_2064_REG0A6               0xa6
+-#define RADIO_2064_REG0A7               0xa7
+-#define RADIO_2064_REG0A8               0xa8
+-#define RADIO_2064_REG0A9               0xa9
+-#define RADIO_2064_REG0AA               0xaa
+-#define RADIO_2064_REG0AB               0xab
+-#define RADIO_2064_REG0AC               0xac
+-#define RADIO_2064_REG0AD               0xad
+-#define RADIO_2064_REG0AE               0xae
+-#define RADIO_2064_REG0AF               0xaf
+-#define RADIO_2064_REG0B0               0xb0
+-#define RADIO_2064_REG0B1               0xb1
+-#define RADIO_2064_REG0B2               0xb2
+-#define RADIO_2064_REG0B3               0xb3
+-#define RADIO_2064_REG0B4               0xb4
+-#define RADIO_2064_REG0B5               0xb5
+-#define RADIO_2064_REG0B6               0xb6
+-#define RADIO_2064_REG0B7               0xb7
+-#define RADIO_2064_REG0B8               0xb8
+-#define RADIO_2064_REG0B9               0xb9
+-#define RADIO_2064_REG0BA               0xba
+-#define RADIO_2064_REG0BB               0xbb
+-#define RADIO_2064_REG0BC               0xbc
+-#define RADIO_2064_REG0BD               0xbd
+-#define RADIO_2064_REG0BE               0xbe
+-#define RADIO_2064_REG0BF               0xbf
+-#define RADIO_2064_REG0C0               0xc0
+-#define RADIO_2064_REG0C1               0xc1
+-#define RADIO_2064_REG0C2               0xc2
+-#define RADIO_2064_REG0C3               0xc3
+-#define RADIO_2064_REG0C4               0xc4
+-#define RADIO_2064_REG0C5               0xc5
+-#define RADIO_2064_REG0C6               0xc6
+-#define RADIO_2064_REG0C7               0xc7
+-#define RADIO_2064_REG0C8               0xc8
+-#define RADIO_2064_REG0C9               0xc9
+-#define RADIO_2064_REG0CA               0xca
+-#define RADIO_2064_REG0CB               0xcb
+-#define RADIO_2064_REG0CC               0xcc
+-#define RADIO_2064_REG0CD               0xcd
+-#define RADIO_2064_REG0CE               0xce
+-#define RADIO_2064_REG0CF               0xcf
+-#define RADIO_2064_REG0D0               0xd0
+-#define RADIO_2064_REG0D1               0xd1
+-#define RADIO_2064_REG0D2               0xd2
+-#define RADIO_2064_REG0D3               0xd3
+-#define RADIO_2064_REG0D4               0xd4
+-#define RADIO_2064_REG0D5               0xd5
+-#define RADIO_2064_REG0D6               0xd6
+-#define RADIO_2064_REG0D7               0xd7
+-#define RADIO_2064_REG0D8               0xd8
+-#define RADIO_2064_REG0D9               0xd9
+-#define RADIO_2064_REG0DA               0xda
+-#define RADIO_2064_REG0DB               0xdb
+-#define RADIO_2064_REG0DC               0xdc
+-#define RADIO_2064_REG0DD               0xdd
+-#define RADIO_2064_REG0DE               0xde
+-#define RADIO_2064_REG0DF               0xdf
+-#define RADIO_2064_REG0E0               0xe0
+-#define RADIO_2064_REG0E1               0xe1
+-#define RADIO_2064_REG0E2               0xe2
+-#define RADIO_2064_REG0E3               0xe3
+-#define RADIO_2064_REG0E4               0xe4
+-#define RADIO_2064_REG0E5               0xe5
+-#define RADIO_2064_REG0E6               0xe6
+-#define RADIO_2064_REG0E7               0xe7
+-#define RADIO_2064_REG0E8               0xe8
+-#define RADIO_2064_REG0E9               0xe9
+-#define RADIO_2064_REG0EA               0xea
+-#define RADIO_2064_REG0EB               0xeb
+-#define RADIO_2064_REG0EC               0xec
+-#define RADIO_2064_REG0ED               0xed
+-#define RADIO_2064_REG0EE               0xee
+-#define RADIO_2064_REG0EF               0xef
+-#define RADIO_2064_REG0F0               0xf0
+-#define RADIO_2064_REG0F1               0xf1
+-#define RADIO_2064_REG0F2               0xf2
+-#define RADIO_2064_REG0F3               0xf3
+-#define RADIO_2064_REG0F4               0xf4
+-#define RADIO_2064_REG0F5               0xf5
+-#define RADIO_2064_REG0F6               0xf6
+-#define RADIO_2064_REG0F7               0xf7
+-#define RADIO_2064_REG0F8               0xf8
+-#define RADIO_2064_REG0F9               0xf9
+-#define RADIO_2064_REG0FA               0xfa
+-#define RADIO_2064_REG0FB               0xfb
+-#define RADIO_2064_REG0FC               0xfc
+-#define RADIO_2064_REG0FD               0xfd
+-#define RADIO_2064_REG0FE               0xfe
+-#define RADIO_2064_REG0FF               0xff
+-#define RADIO_2064_REG100               0x100
+-#define RADIO_2064_REG101               0x101
+-#define RADIO_2064_REG102               0x102
+-#define RADIO_2064_REG103               0x103
+-#define RADIO_2064_REG104               0x104
+-#define RADIO_2064_REG105               0x105
+-#define RADIO_2064_REG106               0x106
+-#define RADIO_2064_REG107               0x107
+-#define RADIO_2064_REG108               0x108
+-#define RADIO_2064_REG109               0x109
+-#define RADIO_2064_REG10A               0x10a
+-#define RADIO_2064_REG10B               0x10b
+-#define RADIO_2064_REG10C               0x10c
+-#define RADIO_2064_REG10D               0x10d
+-#define RADIO_2064_REG10E               0x10e
+-#define RADIO_2064_REG10F               0x10f
+-#define RADIO_2064_REG110               0x110
+-#define RADIO_2064_REG111               0x111
+-#define RADIO_2064_REG112               0x112
+-#define RADIO_2064_REG113               0x113
+-#define RADIO_2064_REG114               0x114
+-#define RADIO_2064_REG115               0x115
+-#define RADIO_2064_REG116               0x116
+-#define RADIO_2064_REG117               0x117
+-#define RADIO_2064_REG118               0x118
+-#define RADIO_2064_REG119               0x119
+-#define RADIO_2064_REG11A               0x11a
+-#define RADIO_2064_REG11B               0x11b
+-#define RADIO_2064_REG11C               0x11c
+-#define RADIO_2064_REG11D               0x11d
+-#define RADIO_2064_REG11E               0x11e
+-#define RADIO_2064_REG11F               0x11f
+-#define RADIO_2064_REG120               0x120
+-#define RADIO_2064_REG121               0x121
+-#define RADIO_2064_REG122               0x122
+-#define RADIO_2064_REG123               0x123
+-#define RADIO_2064_REG124               0x124
+-#define RADIO_2064_REG125               0x125
+-#define RADIO_2064_REG126               0x126
+-#define RADIO_2064_REG127               0x127
+-#define RADIO_2064_REG128               0x128
+-#define RADIO_2064_REG129               0x129
+-#define RADIO_2064_REG12A               0x12a
+-#define RADIO_2064_REG12B               0x12b
+-#define RADIO_2064_REG12C               0x12c
+-#define RADIO_2064_REG12D               0x12d
+-#define RADIO_2064_REG12E               0x12e
+-#define RADIO_2064_REG12F               0x12f
+-#define RADIO_2064_REG130               0x130
+-
+-#define RADIO_2056_SYN                           (0x0 << 12)
+-#define RADIO_2056_TX0                           (0x2 << 12)
+-#define RADIO_2056_TX1                           (0x3 << 12)
+-#define RADIO_2056_RX0                           (0x6 << 12)
+-#define RADIO_2056_RX1                           (0x7 << 12)
+-#define RADIO_2056_ALLTX                         (0xe << 12)
+-#define RADIO_2056_ALLRX                         (0xf << 12)
+-
+-#define RADIO_2056_SYN_RESERVED_ADDR0            0x0
+-#define RADIO_2056_SYN_IDCODE                    0x1
+-#define RADIO_2056_SYN_RESERVED_ADDR2            0x2
+-#define RADIO_2056_SYN_RESERVED_ADDR3            0x3
+-#define RADIO_2056_SYN_RESERVED_ADDR4            0x4
+-#define RADIO_2056_SYN_RESERVED_ADDR5            0x5
+-#define RADIO_2056_SYN_RESERVED_ADDR6            0x6
+-#define RADIO_2056_SYN_RESERVED_ADDR7            0x7
+-#define RADIO_2056_SYN_COM_CTRL                  0x8
+-#define RADIO_2056_SYN_COM_PU                    0x9
+-#define RADIO_2056_SYN_COM_OVR                   0xa
+-#define RADIO_2056_SYN_COM_RESET                 0xb
+-#define RADIO_2056_SYN_COM_RCAL                  0xc
+-#define RADIO_2056_SYN_COM_RC_RXLPF              0xd
+-#define RADIO_2056_SYN_COM_RC_TXLPF              0xe
+-#define RADIO_2056_SYN_COM_RC_RXHPF              0xf
+-#define RADIO_2056_SYN_RESERVED_ADDR16           0x10
+-#define RADIO_2056_SYN_RESERVED_ADDR17           0x11
+-#define RADIO_2056_SYN_RESERVED_ADDR18           0x12
+-#define RADIO_2056_SYN_RESERVED_ADDR19           0x13
+-#define RADIO_2056_SYN_RESERVED_ADDR20           0x14
+-#define RADIO_2056_SYN_RESERVED_ADDR21           0x15
+-#define RADIO_2056_SYN_RESERVED_ADDR22           0x16
+-#define RADIO_2056_SYN_RESERVED_ADDR23           0x17
+-#define RADIO_2056_SYN_RESERVED_ADDR24           0x18
+-#define RADIO_2056_SYN_RESERVED_ADDR25           0x19
+-#define RADIO_2056_SYN_RESERVED_ADDR26           0x1a
+-#define RADIO_2056_SYN_RESERVED_ADDR27           0x1b
+-#define RADIO_2056_SYN_RESERVED_ADDR28           0x1c
+-#define RADIO_2056_SYN_RESERVED_ADDR29           0x1d
+-#define RADIO_2056_SYN_RESERVED_ADDR30           0x1e
+-#define RADIO_2056_SYN_RESERVED_ADDR31           0x1f
+-#define RADIO_2056_SYN_GPIO_MASTER1              0x20
+-#define RADIO_2056_SYN_GPIO_MASTER2              0x21
+-#define RADIO_2056_SYN_TOPBIAS_MASTER            0x22
+-#define RADIO_2056_SYN_TOPBIAS_RCAL              0x23
+-#define RADIO_2056_SYN_AFEREG                    0x24
+-#define RADIO_2056_SYN_TEMPPROCSENSE             0x25
+-#define RADIO_2056_SYN_TEMPPROCSENSEIDAC         0x26
+-#define RADIO_2056_SYN_TEMPPROCSENSERCAL         0x27
+-#define RADIO_2056_SYN_LPO                       0x28
+-#define RADIO_2056_SYN_VDDCAL_MASTER             0x29
+-#define RADIO_2056_SYN_VDDCAL_IDAC               0x2a
+-#define RADIO_2056_SYN_VDDCAL_STATUS             0x2b
+-#define RADIO_2056_SYN_RCAL_MASTER               0x2c
+-#define RADIO_2056_SYN_RCAL_CODE_OUT             0x2d
+-#define RADIO_2056_SYN_RCCAL_CTRL0               0x2e
+-#define RADIO_2056_SYN_RCCAL_CTRL1               0x2f
+-#define RADIO_2056_SYN_RCCAL_CTRL2               0x30
+-#define RADIO_2056_SYN_RCCAL_CTRL3               0x31
+-#define RADIO_2056_SYN_RCCAL_CTRL4               0x32
+-#define RADIO_2056_SYN_RCCAL_CTRL5               0x33
+-#define RADIO_2056_SYN_RCCAL_CTRL6               0x34
+-#define RADIO_2056_SYN_RCCAL_CTRL7               0x35
+-#define RADIO_2056_SYN_RCCAL_CTRL8               0x36
+-#define RADIO_2056_SYN_RCCAL_CTRL9               0x37
+-#define RADIO_2056_SYN_RCCAL_CTRL10              0x38
+-#define RADIO_2056_SYN_RCCAL_CTRL11              0x39
+-#define RADIO_2056_SYN_ZCAL_SPARE1               0x3a
+-#define RADIO_2056_SYN_ZCAL_SPARE2               0x3b
+-#define RADIO_2056_SYN_PLL_MAST1                 0x3c
+-#define RADIO_2056_SYN_PLL_MAST2                 0x3d
+-#define RADIO_2056_SYN_PLL_MAST3                 0x3e
+-#define RADIO_2056_SYN_PLL_BIAS_RESET            0x3f
+-#define RADIO_2056_SYN_PLL_XTAL0                 0x40
+-#define RADIO_2056_SYN_PLL_XTAL1                 0x41
+-#define RADIO_2056_SYN_PLL_XTAL3                 0x42
+-#define RADIO_2056_SYN_PLL_XTAL4                 0x43
+-#define RADIO_2056_SYN_PLL_XTAL5                 0x44
+-#define RADIO_2056_SYN_PLL_XTAL6                 0x45
+-#define RADIO_2056_SYN_PLL_REFDIV                0x46
+-#define RADIO_2056_SYN_PLL_PFD                   0x47
+-#define RADIO_2056_SYN_PLL_CP1                   0x48
+-#define RADIO_2056_SYN_PLL_CP2                   0x49
+-#define RADIO_2056_SYN_PLL_CP3                   0x4a
+-#define RADIO_2056_SYN_PLL_LOOPFILTER1           0x4b
+-#define RADIO_2056_SYN_PLL_LOOPFILTER2           0x4c
+-#define RADIO_2056_SYN_PLL_LOOPFILTER3           0x4d
+-#define RADIO_2056_SYN_PLL_LOOPFILTER4           0x4e
+-#define RADIO_2056_SYN_PLL_LOOPFILTER5           0x4f
+-#define RADIO_2056_SYN_PLL_MMD1                  0x50
+-#define RADIO_2056_SYN_PLL_MMD2                  0x51
+-#define RADIO_2056_SYN_PLL_VCO1                  0x52
+-#define RADIO_2056_SYN_PLL_VCO2                  0x53
+-#define RADIO_2056_SYN_PLL_MONITOR1              0x54
+-#define RADIO_2056_SYN_PLL_MONITOR2              0x55
+-#define RADIO_2056_SYN_PLL_VCOCAL1               0x56
+-#define RADIO_2056_SYN_PLL_VCOCAL2               0x57
+-#define RADIO_2056_SYN_PLL_VCOCAL4               0x58
+-#define RADIO_2056_SYN_PLL_VCOCAL5               0x59
+-#define RADIO_2056_SYN_PLL_VCOCAL6               0x5a
+-#define RADIO_2056_SYN_PLL_VCOCAL7               0x5b
+-#define RADIO_2056_SYN_PLL_VCOCAL8               0x5c
+-#define RADIO_2056_SYN_PLL_VCOCAL9               0x5d
+-#define RADIO_2056_SYN_PLL_VCOCAL10              0x5e
+-#define RADIO_2056_SYN_PLL_VCOCAL11              0x5f
+-#define RADIO_2056_SYN_PLL_VCOCAL12              0x60
+-#define RADIO_2056_SYN_PLL_VCOCAL13              0x61
+-#define RADIO_2056_SYN_PLL_VREG                  0x62
+-#define RADIO_2056_SYN_PLL_STATUS1               0x63
+-#define RADIO_2056_SYN_PLL_STATUS2               0x64
+-#define RADIO_2056_SYN_PLL_STATUS3               0x65
+-#define RADIO_2056_SYN_LOGEN_PU0                 0x66
+-#define RADIO_2056_SYN_LOGEN_PU1                 0x67
+-#define RADIO_2056_SYN_LOGEN_PU2                 0x68
+-#define RADIO_2056_SYN_LOGEN_PU3                 0x69
+-#define RADIO_2056_SYN_LOGEN_PU5                 0x6a
+-#define RADIO_2056_SYN_LOGEN_PU6                 0x6b
+-#define RADIO_2056_SYN_LOGEN_PU7                 0x6c
+-#define RADIO_2056_SYN_LOGEN_PU8                 0x6d
+-#define RADIO_2056_SYN_LOGEN_BIAS_RESET          0x6e
+-#define RADIO_2056_SYN_LOGEN_RCCR1               0x6f
+-#define RADIO_2056_SYN_LOGEN_VCOBUF1             0x70
+-#define RADIO_2056_SYN_LOGEN_MIXER1              0x71
+-#define RADIO_2056_SYN_LOGEN_MIXER2              0x72
+-#define RADIO_2056_SYN_LOGEN_BUF1                0x73
+-#define RADIO_2056_SYN_LOGENBUF2                 0x74
+-#define RADIO_2056_SYN_LOGEN_BUF3                0x75
+-#define RADIO_2056_SYN_LOGEN_BUF4                0x76
+-#define RADIO_2056_SYN_LOGEN_DIV1                0x77
+-#define RADIO_2056_SYN_LOGEN_DIV2                0x78
+-#define RADIO_2056_SYN_LOGEN_DIV3                0x79
+-#define RADIO_2056_SYN_LOGEN_ACL1                0x7a
+-#define RADIO_2056_SYN_LOGEN_ACL2                0x7b
+-#define RADIO_2056_SYN_LOGEN_ACL3                0x7c
+-#define RADIO_2056_SYN_LOGEN_ACL4                0x7d
+-#define RADIO_2056_SYN_LOGEN_ACL5                0x7e
+-#define RADIO_2056_SYN_LOGEN_ACL6                0x7f
+-#define RADIO_2056_SYN_LOGEN_ACLOUT              0x80
+-#define RADIO_2056_SYN_LOGEN_ACLCAL1             0x81
+-#define RADIO_2056_SYN_LOGEN_ACLCAL2             0x82
+-#define RADIO_2056_SYN_LOGEN_ACLCAL3             0x83
+-#define RADIO_2056_SYN_CALEN                     0x84
+-#define RADIO_2056_SYN_LOGEN_PEAKDET1            0x85
+-#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR        0x86
+-#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR     0x87
+-#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR     0x88
+-#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR     0x89
+-#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR     0x8a
+-#define RADIO_2056_SYN_LOGEN_VCOBUF2             0x8b
+-#define RADIO_2056_SYN_LOGEN_MIXER3              0x8c
+-#define RADIO_2056_SYN_LOGEN_BUF5                0x8d
+-#define RADIO_2056_SYN_LOGEN_BUF6                0x8e
+-#define RADIO_2056_SYN_LOGEN_CBUFRX1             0x8f
+-#define RADIO_2056_SYN_LOGEN_CBUFRX2             0x90
+-#define RADIO_2056_SYN_LOGEN_CBUFRX3             0x91
+-#define RADIO_2056_SYN_LOGEN_CBUFRX4             0x92
+-#define RADIO_2056_SYN_LOGEN_CBUFTX1             0x93
+-#define RADIO_2056_SYN_LOGEN_CBUFTX2             0x94
+-#define RADIO_2056_SYN_LOGEN_CBUFTX3             0x95
+-#define RADIO_2056_SYN_LOGEN_CBUFTX4             0x96
+-#define RADIO_2056_SYN_LOGEN_CMOSRX1             0x97
+-#define RADIO_2056_SYN_LOGEN_CMOSRX2             0x98
+-#define RADIO_2056_SYN_LOGEN_CMOSRX3             0x99
+-#define RADIO_2056_SYN_LOGEN_CMOSRX4             0x9a
+-#define RADIO_2056_SYN_LOGEN_CMOSTX1             0x9b
+-#define RADIO_2056_SYN_LOGEN_CMOSTX2             0x9c
+-#define RADIO_2056_SYN_LOGEN_CMOSTX3             0x9d
+-#define RADIO_2056_SYN_LOGEN_CMOSTX4             0x9e
+-#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL      0x9f
+-#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL       0xa0
+-#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL         0xa1
+-#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL         0xa2
+-#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL      0xa3
+-#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL      0xa4
+-#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL      0xa5
+-#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL      0xa6
+-#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL      0xa7
+-#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL      0xa8
+-#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL      0xa9
+-#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL      0xaa
+-#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL      0xab
+-#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL      0xac
+-#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL      0xad
+-#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL      0xae
+-#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL      0xaf
+-#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL      0xb0
+-#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL      0xb1
+-#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL      0xb2
+-#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT         0xb3
+-#define RADIO_2056_SYN_LOGEN_CORE_CALVALID       0xb4
+-#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID    0xb5
+-#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID       0xb6
+-
+-#define RADIO_2056_TX_RESERVED_ADDR0             0x0
+-#define RADIO_2056_TX_IDCODE                     0x1
+-#define RADIO_2056_TX_RESERVED_ADDR2             0x2
+-#define RADIO_2056_TX_RESERVED_ADDR3             0x3
+-#define RADIO_2056_TX_RESERVED_ADDR4             0x4
+-#define RADIO_2056_TX_RESERVED_ADDR5             0x5
+-#define RADIO_2056_TX_RESERVED_ADDR6             0x6
+-#define RADIO_2056_TX_RESERVED_ADDR7             0x7
+-#define RADIO_2056_TX_COM_CTRL                   0x8
+-#define RADIO_2056_TX_COM_PU                     0x9
+-#define RADIO_2056_TX_COM_OVR                    0xa
+-#define RADIO_2056_TX_COM_RESET                  0xb
+-#define RADIO_2056_TX_COM_RCAL                   0xc
+-#define RADIO_2056_TX_COM_RC_RXLPF               0xd
+-#define RADIO_2056_TX_COM_RC_TXLPF               0xe
+-#define RADIO_2056_TX_COM_RC_RXHPF               0xf
+-#define RADIO_2056_TX_RESERVED_ADDR16            0x10
+-#define RADIO_2056_TX_RESERVED_ADDR17            0x11
+-#define RADIO_2056_TX_RESERVED_ADDR18            0x12
+-#define RADIO_2056_TX_RESERVED_ADDR19            0x13
+-#define RADIO_2056_TX_RESERVED_ADDR20            0x14
+-#define RADIO_2056_TX_RESERVED_ADDR21            0x15
+-#define RADIO_2056_TX_RESERVED_ADDR22            0x16
+-#define RADIO_2056_TX_RESERVED_ADDR23            0x17
+-#define RADIO_2056_TX_RESERVED_ADDR24            0x18
+-#define RADIO_2056_TX_RESERVED_ADDR25            0x19
+-#define RADIO_2056_TX_RESERVED_ADDR26            0x1a
+-#define RADIO_2056_TX_RESERVED_ADDR27            0x1b
+-#define RADIO_2056_TX_RESERVED_ADDR28            0x1c
+-#define RADIO_2056_TX_RESERVED_ADDR29            0x1d
+-#define RADIO_2056_TX_RESERVED_ADDR30            0x1e
+-#define RADIO_2056_TX_RESERVED_ADDR31            0x1f
+-#define RADIO_2056_TX_IQCAL_GAIN_BW              0x20
+-#define RADIO_2056_TX_LOFT_FINE_I                0x21
+-#define RADIO_2056_TX_LOFT_FINE_Q                0x22
+-#define RADIO_2056_TX_LOFT_COARSE_I              0x23
+-#define RADIO_2056_TX_LOFT_COARSE_Q              0x24
+-#define RADIO_2056_TX_TX_COM_MASTER1             0x25
+-#define RADIO_2056_TX_TX_COM_MASTER2             0x26
+-#define RADIO_2056_TX_RXIQCAL_TXMUX              0x27
+-#define RADIO_2056_TX_TX_SSI_MASTER              0x28
+-#define RADIO_2056_TX_IQCAL_VCM_HG               0x29
+-#define RADIO_2056_TX_IQCAL_IDAC                 0x2a
+-#define RADIO_2056_TX_TSSI_VCM                   0x2b
+-#define RADIO_2056_TX_TX_AMP_DET                 0x2c
+-#define RADIO_2056_TX_TX_SSI_MUX                 0x2d
+-#define RADIO_2056_TX_TSSIA                      0x2e
+-#define RADIO_2056_TX_TSSIG                      0x2f
+-#define RADIO_2056_TX_TSSI_MISC1                 0x30
+-#define RADIO_2056_TX_TSSI_MISC2                 0x31
+-#define RADIO_2056_TX_TSSI_MISC3                 0x32
+-#define RADIO_2056_TX_PA_SPARE1                  0x33
+-#define RADIO_2056_TX_PA_SPARE2                  0x34
+-#define RADIO_2056_TX_INTPAA_MASTER              0x35
+-#define RADIO_2056_TX_INTPAA_GAIN                0x36
+-#define RADIO_2056_TX_INTPAA_BOOST_TUNE          0x37
+-#define RADIO_2056_TX_INTPAA_IAUX_STAT           0x38
+-#define RADIO_2056_TX_INTPAA_IAUX_DYN            0x39
+-#define RADIO_2056_TX_INTPAA_IMAIN_STAT          0x3a
+-#define RADIO_2056_TX_INTPAA_IMAIN_DYN           0x3b
+-#define RADIO_2056_TX_INTPAA_CASCBIAS            0x3c
+-#define RADIO_2056_TX_INTPAA_PASLOPE             0x3d
+-#define RADIO_2056_TX_INTPAA_PA_MISC             0x3e
+-#define RADIO_2056_TX_INTPAG_MASTER              0x3f
+-#define RADIO_2056_TX_INTPAG_GAIN                0x40
+-#define RADIO_2056_TX_INTPAG_BOOST_TUNE          0x41
+-#define RADIO_2056_TX_INTPAG_IAUX_STAT           0x42
+-#define RADIO_2056_TX_INTPAG_IAUX_DYN            0x43
+-#define RADIO_2056_TX_INTPAG_IMAIN_STAT          0x44
+-#define RADIO_2056_TX_INTPAG_IMAIN_DYN           0x45
+-#define RADIO_2056_TX_INTPAG_CASCBIAS            0x46
+-#define RADIO_2056_TX_INTPAG_PASLOPE             0x47
+-#define RADIO_2056_TX_INTPAG_PA_MISC             0x48
+-#define RADIO_2056_TX_PADA_MASTER                0x49
+-#define RADIO_2056_TX_PADA_IDAC                  0x4a
+-#define RADIO_2056_TX_PADA_CASCBIAS              0x4b
+-#define RADIO_2056_TX_PADA_GAIN                  0x4c
+-#define RADIO_2056_TX_PADA_BOOST_TUNE            0x4d
+-#define RADIO_2056_TX_PADA_SLOPE                 0x4e
+-#define RADIO_2056_TX_PADG_MASTER                0x4f
+-#define RADIO_2056_TX_PADG_IDAC                  0x50
+-#define RADIO_2056_TX_PADG_CASCBIAS              0x51
+-#define RADIO_2056_TX_PADG_GAIN                  0x52
+-#define RADIO_2056_TX_PADG_BOOST_TUNE            0x53
+-#define RADIO_2056_TX_PADG_SLOPE                 0x54
+-#define RADIO_2056_TX_PGAA_MASTER                0x55
+-#define RADIO_2056_TX_PGAA_IDAC                  0x56
+-#define RADIO_2056_TX_PGAA_GAIN                  0x57
+-#define RADIO_2056_TX_PGAA_BOOST_TUNE            0x58
+-#define RADIO_2056_TX_PGAA_SLOPE                 0x59
+-#define RADIO_2056_TX_PGAA_MISC                  0x5a
+-#define RADIO_2056_TX_PGAG_MASTER                0x5b
+-#define RADIO_2056_TX_PGAG_IDAC                  0x5c
+-#define RADIO_2056_TX_PGAG_GAIN                  0x5d
+-#define RADIO_2056_TX_PGAG_BOOST_TUNE            0x5e
+-#define RADIO_2056_TX_PGAG_SLOPE                 0x5f
+-#define RADIO_2056_TX_PGAG_MISC                  0x60
+-#define RADIO_2056_TX_MIXA_MASTER                0x61
+-#define RADIO_2056_TX_MIXA_BOOST_TUNE            0x62
+-#define RADIO_2056_TX_MIXG                       0x63
+-#define RADIO_2056_TX_MIXG_BOOST_TUNE            0x64
+-#define RADIO_2056_TX_BB_GM_MASTER               0x65
+-#define RADIO_2056_TX_GMBB_GM                    0x66
+-#define RADIO_2056_TX_GMBB_IDAC                  0x67
+-#define RADIO_2056_TX_TXLPF_MASTER               0x68
+-#define RADIO_2056_TX_TXLPF_RCCAL                0x69
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF0           0x6a
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF1           0x6b
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF2           0x6c
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF3           0x6d
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF4           0x6e
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF5           0x6f
+-#define RADIO_2056_TX_TXLPF_RCCAL_OFF6           0x70
+-#define RADIO_2056_TX_TXLPF_BW                   0x71
+-#define RADIO_2056_TX_TXLPF_GAIN                 0x72
+-#define RADIO_2056_TX_TXLPF_IDAC                 0x73
+-#define RADIO_2056_TX_TXLPF_IDAC_0               0x74
+-#define RADIO_2056_TX_TXLPF_IDAC_1               0x75
+-#define RADIO_2056_TX_TXLPF_IDAC_2               0x76
+-#define RADIO_2056_TX_TXLPF_IDAC_3               0x77
+-#define RADIO_2056_TX_TXLPF_IDAC_4               0x78
+-#define RADIO_2056_TX_TXLPF_IDAC_5               0x79
+-#define RADIO_2056_TX_TXLPF_IDAC_6               0x7a
+-#define RADIO_2056_TX_TXLPF_OPAMP_IDAC           0x7b
+-#define RADIO_2056_TX_TXLPF_MISC                 0x7c
+-#define RADIO_2056_TX_TXSPARE1                   0x7d
+-#define RADIO_2056_TX_TXSPARE2                   0x7e
+-#define RADIO_2056_TX_TXSPARE3                   0x7f
+-#define RADIO_2056_TX_TXSPARE4                   0x80
+-#define RADIO_2056_TX_TXSPARE5                   0x81
+-#define RADIO_2056_TX_TXSPARE6                   0x82
+-#define RADIO_2056_TX_TXSPARE7                   0x83
+-#define RADIO_2056_TX_TXSPARE8                   0x84
+-#define RADIO_2056_TX_TXSPARE9                   0x85
+-#define RADIO_2056_TX_TXSPARE10                  0x86
+-#define RADIO_2056_TX_TXSPARE11                  0x87
+-#define RADIO_2056_TX_TXSPARE12                  0x88
+-#define RADIO_2056_TX_TXSPARE13                  0x89
+-#define RADIO_2056_TX_TXSPARE14                  0x8a
+-#define RADIO_2056_TX_TXSPARE15                  0x8b
+-#define RADIO_2056_TX_TXSPARE16                  0x8c
+-#define RADIO_2056_TX_STATUS_INTPA_GAIN          0x8d
+-#define RADIO_2056_TX_STATUS_PAD_GAIN            0x8e
+-#define RADIO_2056_TX_STATUS_PGA_GAIN            0x8f
+-#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN       0x90
+-#define RADIO_2056_TX_STATUS_TXLPF_BW            0x91
+-#define RADIO_2056_TX_STATUS_TXLPF_RC            0x92
+-#define RADIO_2056_TX_GMBB_IDAC0                 0x93
+-#define RADIO_2056_TX_GMBB_IDAC1                 0x94
+-#define RADIO_2056_TX_GMBB_IDAC2                 0x95
+-#define RADIO_2056_TX_GMBB_IDAC3                 0x96
+-#define RADIO_2056_TX_GMBB_IDAC4                 0x97
+-#define RADIO_2056_TX_GMBB_IDAC5                 0x98
+-#define RADIO_2056_TX_GMBB_IDAC6                 0x99
+-#define RADIO_2056_TX_GMBB_IDAC7                 0x9a
+-
+-#define RADIO_2056_RX_RESERVED_ADDR0             0x0
+-#define RADIO_2056_RX_IDCODE                     0x1
+-#define RADIO_2056_RX_RESERVED_ADDR2             0x2
+-#define RADIO_2056_RX_RESERVED_ADDR3             0x3
+-#define RADIO_2056_RX_RESERVED_ADDR4             0x4
+-#define RADIO_2056_RX_RESERVED_ADDR5             0x5
+-#define RADIO_2056_RX_RESERVED_ADDR6             0x6
+-#define RADIO_2056_RX_RESERVED_ADDR7             0x7
+-#define RADIO_2056_RX_COM_CTRL                   0x8
+-#define RADIO_2056_RX_COM_PU                     0x9
+-#define RADIO_2056_RX_COM_OVR                    0xa
+-#define RADIO_2056_RX_COM_RESET                  0xb
+-#define RADIO_2056_RX_COM_RCAL                   0xc
+-#define RADIO_2056_RX_COM_RC_RXLPF               0xd
+-#define RADIO_2056_RX_COM_RC_TXLPF               0xe
+-#define RADIO_2056_RX_COM_RC_RXHPF               0xf
+-#define RADIO_2056_RX_RESERVED_ADDR16            0x10
+-#define RADIO_2056_RX_RESERVED_ADDR17            0x11
+-#define RADIO_2056_RX_RESERVED_ADDR18            0x12
+-#define RADIO_2056_RX_RESERVED_ADDR19            0x13
+-#define RADIO_2056_RX_RESERVED_ADDR20            0x14
+-#define RADIO_2056_RX_RESERVED_ADDR21            0x15
+-#define RADIO_2056_RX_RESERVED_ADDR22            0x16
+-#define RADIO_2056_RX_RESERVED_ADDR23            0x17
+-#define RADIO_2056_RX_RESERVED_ADDR24            0x18
+-#define RADIO_2056_RX_RESERVED_ADDR25            0x19
+-#define RADIO_2056_RX_RESERVED_ADDR26            0x1a
+-#define RADIO_2056_RX_RESERVED_ADDR27            0x1b
+-#define RADIO_2056_RX_RESERVED_ADDR28            0x1c
+-#define RADIO_2056_RX_RESERVED_ADDR29            0x1d
+-#define RADIO_2056_RX_RESERVED_ADDR30            0x1e
+-#define RADIO_2056_RX_RESERVED_ADDR31            0x1f
+-#define RADIO_2056_RX_RXIQCAL_RXMUX              0x20
+-#define RADIO_2056_RX_RSSI_PU                    0x21
+-#define RADIO_2056_RX_RSSI_SEL                   0x22
+-#define RADIO_2056_RX_RSSI_GAIN                  0x23
+-#define RADIO_2056_RX_RSSI_NB_IDAC               0x24
+-#define RADIO_2056_RX_RSSI_WB2I_IDAC_1           0x25
+-#define RADIO_2056_RX_RSSI_WB2I_IDAC_2           0x26
+-#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1           0x27
+-#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2           0x28
+-#define RADIO_2056_RX_RSSI_POLE                  0x29
+-#define RADIO_2056_RX_RSSI_WB1_IDAC              0x2a
+-#define RADIO_2056_RX_RSSI_MISC                  0x2b
+-#define RADIO_2056_RX_LNAA_MASTER                0x2c
+-#define RADIO_2056_RX_LNAA_TUNE                  0x2d
+-#define RADIO_2056_RX_LNAA_GAIN                  0x2e
+-#define RADIO_2056_RX_LNA_A_SLOPE                0x2f
+-#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC        0x30
+-#define RADIO_2056_RX_LNAA2_IDAC                 0x31
+-#define RADIO_2056_RX_LNA1A_MISC                 0x32
+-#define RADIO_2056_RX_LNAG_MASTER                0x33
+-#define RADIO_2056_RX_LNAG_TUNE                  0x34
+-#define RADIO_2056_RX_LNAG_GAIN                  0x35
+-#define RADIO_2056_RX_LNA_G_SLOPE                0x36
+-#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC        0x37
+-#define RADIO_2056_RX_LNAG2_IDAC                 0x38
+-#define RADIO_2056_RX_LNA1G_MISC                 0x39
+-#define RADIO_2056_RX_MIXA_MASTER                0x3a
+-#define RADIO_2056_RX_MIXA_VCM                   0x3b
+-#define RADIO_2056_RX_MIXA_CTRLPTAT              0x3c
+-#define RADIO_2056_RX_MIXA_LOB_BIAS              0x3d
+-#define RADIO_2056_RX_MIXA_CORE_IDAC             0x3e
+-#define RADIO_2056_RX_MIXA_CMFB_IDAC             0x3f
+-#define RADIO_2056_RX_MIXA_BIAS_AUX              0x40
+-#define RADIO_2056_RX_MIXA_BIAS_MAIN             0x41
+-#define RADIO_2056_RX_MIXA_BIAS_MISC             0x42
+-#define RADIO_2056_RX_MIXA_MAST_BIAS             0x43
+-#define RADIO_2056_RX_MIXG_MASTER                0x44
+-#define RADIO_2056_RX_MIXG_VCM                   0x45
+-#define RADIO_2056_RX_MIXG_CTRLPTAT              0x46
+-#define RADIO_2056_RX_MIXG_LOB_BIAS              0x47
+-#define RADIO_2056_RX_MIXG_CORE_IDAC             0x48
+-#define RADIO_2056_RX_MIXG_CMFB_IDAC             0x49
+-#define RADIO_2056_RX_MIXG_BIAS_AUX              0x4a
+-#define RADIO_2056_RX_MIXG_BIAS_MAIN             0x4b
+-#define RADIO_2056_RX_MIXG_BIAS_MISC             0x4c
+-#define RADIO_2056_RX_MIXG_MAST_BIAS             0x4d
+-#define RADIO_2056_RX_TIA_MASTER                 0x4e
+-#define RADIO_2056_RX_TIA_IOPAMP                 0x4f
+-#define RADIO_2056_RX_TIA_QOPAMP                 0x50
+-#define RADIO_2056_RX_TIA_IMISC                  0x51
+-#define RADIO_2056_RX_TIA_QMISC                  0x52
+-#define RADIO_2056_RX_TIA_GAIN                   0x53
+-#define RADIO_2056_RX_TIA_SPARE1                 0x54
+-#define RADIO_2056_RX_TIA_SPARE2                 0x55
+-#define RADIO_2056_RX_BB_LPF_MASTER              0x56
+-#define RADIO_2056_RX_AACI_MASTER                0x57
+-#define RADIO_2056_RX_RXLPF_IDAC                 0x58
+-#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ       0x59
+-#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ      0x5a
+-#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL        0x5b
+-#define RADIO_2056_RX_RXLPF_OUTVCM               0x5c
+-#define RADIO_2056_RX_RXLPF_INVCM_BODY           0x5d
+-#define RADIO_2056_RX_RXLPF_CC_OP                0x5e
+-#define RADIO_2056_RX_RXLPF_GAIN                 0x5f
+-#define RADIO_2056_RX_RXLPF_Q_BW                 0x60
+-#define RADIO_2056_RX_RXLPF_HP_CORNER_BW         0x61
+-#define RADIO_2056_RX_RXLPF_RCCAL_HPC            0x62
+-#define RADIO_2056_RX_RXHPF_OFF0                 0x63
+-#define RADIO_2056_RX_RXHPF_OFF1                 0x64
+-#define RADIO_2056_RX_RXHPF_OFF2                 0x65
+-#define RADIO_2056_RX_RXHPF_OFF3                 0x66
+-#define RADIO_2056_RX_RXHPF_OFF4                 0x67
+-#define RADIO_2056_RX_RXHPF_OFF5                 0x68
+-#define RADIO_2056_RX_RXHPF_OFF6                 0x69
+-#define RADIO_2056_RX_RXHPF_OFF7                 0x6a
+-#define RADIO_2056_RX_RXLPF_RCCAL_LPC            0x6b
+-#define RADIO_2056_RX_RXLPF_OFF_0                0x6c
+-#define RADIO_2056_RX_RXLPF_OFF_1                0x6d
+-#define RADIO_2056_RX_RXLPF_OFF_2                0x6e
+-#define RADIO_2056_RX_RXLPF_OFF_3                0x6f
+-#define RADIO_2056_RX_RXLPF_OFF_4                0x70
+-#define RADIO_2056_RX_UNUSED                     0x71
+-#define RADIO_2056_RX_VGA_MASTER                 0x72
+-#define RADIO_2056_RX_VGA_BIAS                   0x73
+-#define RADIO_2056_RX_VGA_BIAS_DCCANCEL          0x74
+-#define RADIO_2056_RX_VGA_GAIN                   0x75
+-#define RADIO_2056_RX_VGA_HP_CORNER_BW           0x76
+-#define RADIO_2056_RX_VGABUF_BIAS                0x77
+-#define RADIO_2056_RX_VGABUF_GAIN_BW             0x78
+-#define RADIO_2056_RX_TXFBMIX_A                  0x79
+-#define RADIO_2056_RX_TXFBMIX_G                  0x7a
+-#define RADIO_2056_RX_RXSPARE1                   0x7b
+-#define RADIO_2056_RX_RXSPARE2                   0x7c
+-#define RADIO_2056_RX_RXSPARE3                   0x7d
+-#define RADIO_2056_RX_RXSPARE4                   0x7e
+-#define RADIO_2056_RX_RXSPARE5                   0x7f
+-#define RADIO_2056_RX_RXSPARE6                   0x80
+-#define RADIO_2056_RX_RXSPARE7                   0x81
+-#define RADIO_2056_RX_RXSPARE8                   0x82
+-#define RADIO_2056_RX_RXSPARE9                   0x83
+-#define RADIO_2056_RX_RXSPARE10                  0x84
+-#define RADIO_2056_RX_RXSPARE11                  0x85
+-#define RADIO_2056_RX_RXSPARE12                  0x86
+-#define RADIO_2056_RX_RXSPARE13                  0x87
+-#define RADIO_2056_RX_RXSPARE14                  0x88
+-#define RADIO_2056_RX_RXSPARE15                  0x89
+-#define RADIO_2056_RX_RXSPARE16                  0x8a
+-#define RADIO_2056_RX_STATUS_LNAA_GAIN           0x8b
+-#define RADIO_2056_RX_STATUS_LNAG_GAIN           0x8c
+-#define RADIO_2056_RX_STATUS_MIXTIA_GAIN         0x8d
+-#define RADIO_2056_RX_STATUS_RXLPF_GAIN          0x8e
+-#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN        0x8f
+-#define RADIO_2056_RX_STATUS_RXLPF_Q             0x90
+-#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW        0x91
+-#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC       0x92
+-#define RADIO_2056_RX_STATUS_RXLPF_RC            0x93
+-#define RADIO_2056_RX_STATUS_HPC_RC              0x94
+-
+-#define RADIO_2056_LNA1_A_PU		0x01
+-#define RADIO_2056_LNA2_A_PU		0x02
+-#define RADIO_2056_LNA1_G_PU		0x01
+-#define RADIO_2056_LNA2_G_PU		0x02
+-#define RADIO_2056_MIXA_PU_I		0x01
+-#define RADIO_2056_MIXA_PU_Q		0x02
+-#define RADIO_2056_MIXA_PU_GM		0x10
+-#define RADIO_2056_MIXG_PU_I		0x01
+-#define RADIO_2056_MIXG_PU_Q		0x02
+-#define RADIO_2056_MIXG_PU_GM		0x10
+-#define RADIO_2056_TIA_PU			0x01
+-#define RADIO_2056_BB_LPF_PU		0x20
+-#define RADIO_2056_W1_PU			0x02
+-#define RADIO_2056_W2_PU			0x04
+-#define RADIO_2056_NB_PU			0x08
+-#define RADIO_2056_RSSI_W1_SEL		0x02
+-#define RADIO_2056_RSSI_W2_SEL		0x04
+-#define RADIO_2056_RSSI_NB_SEL		0x08
+-#define RADIO_2056_VCM_MASK			0x1c
+-#define RADIO_2056_RSSI_VCM_SHIFT	0x02
+-
+-#define RADIO_2057_DACBUF_VINCM_CORE0            0x0
+-#define RADIO_2057_IDCODE                        0x1
+-#define RADIO_2057_RCCAL_MASTER                  0x2
+-#define RADIO_2057_RCCAL_CAP_SIZE                0x3
+-#define RADIO_2057_RCAL_CONFIG                   0x4
+-#define RADIO_2057_GPAIO_CONFIG                  0x5
+-#define RADIO_2057_GPAIO_SEL1                    0x6
+-#define RADIO_2057_GPAIO_SEL0                    0x7
+-#define RADIO_2057_CLPO_CONFIG                   0x8
+-#define RADIO_2057_BANDGAP_CONFIG                0x9
+-#define RADIO_2057_BANDGAP_RCAL_TRIM             0xa
+-#define RADIO_2057_AFEREG_CONFIG                 0xb
+-#define RADIO_2057_TEMPSENSE_CONFIG              0xc
+-#define RADIO_2057_XTAL_CONFIG1                  0xd
+-#define RADIO_2057_XTAL_ICORE_SIZE               0xe
+-#define RADIO_2057_XTAL_BUF_SIZE                 0xf
+-#define RADIO_2057_XTAL_PULLCAP_SIZE             0x10
+-#define RADIO_2057_RFPLL_MASTER                  0x11
+-#define RADIO_2057_VCOMONITOR_VTH_L              0x12
+-#define RADIO_2057_VCOMONITOR_VTH_H              0x13
+-#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14
+-#define RADIO_2057_VCO_VARCSIZE_IDAC             0x15
+-#define RADIO_2057_VCOCAL_COUNTVAL0              0x16
+-#define RADIO_2057_VCOCAL_COUNTVAL1              0x17
+-#define RADIO_2057_VCOCAL_INTCLK_COUNT           0x18
+-#define RADIO_2057_VCOCAL_MASTER                 0x19
+-#define RADIO_2057_VCOCAL_NUMCAPCHANGE           0x1a
+-#define RADIO_2057_VCOCAL_WINSIZE                0x1b
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH    0x1c
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP  0x1d
+-#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP   0x1e
+-#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP  0x1f
+-#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1      0x20
+-#define RADIO_2057_VCO_FORCECAP0                 0x21
+-#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22
+-#define RADIO_2057_RFPLL_PFD_RESET_PW            0x23
+-#define RADIO_2057_RFPLL_LOOPFILTER_R2           0x24
+-#define RADIO_2057_RFPLL_LOOPFILTER_R1           0x25
+-#define RADIO_2057_RFPLL_LOOPFILTER_C3           0x26
+-#define RADIO_2057_RFPLL_LOOPFILTER_C2           0x27
+-#define RADIO_2057_RFPLL_LOOPFILTER_C1           0x28
+-#define RADIO_2057_CP_KPD_IDAC                   0x29
+-#define RADIO_2057_RFPLL_IDACS                   0x2a
+-#define RADIO_2057_RFPLL_MISC_EN                 0x2b
+-#define RADIO_2057_RFPLL_MMD0                    0x2c
+-#define RADIO_2057_RFPLL_MMD1                    0x2d
+-#define RADIO_2057_RFPLL_MISC_CAL_RESETN         0x2e
+-#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES  0x2f
+-#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE     0x30
+-#define RADIO_2057_VCOCAL_READCAP0               0x31
+-#define RADIO_2057_VCOCAL_READCAP1               0x32
+-#define RADIO_2057_VCOCAL_STATUS                 0x33
+-#define RADIO_2057_LOGEN_PUS                     0x34
+-#define RADIO_2057_LOGEN_PTAT_RESETS             0x35
+-#define RADIO_2057_VCOBUF_IDACS                  0x36
+-#define RADIO_2057_VCOBUF_TUNE                   0x37
+-#define RADIO_2057_CMOSBUF_TX2GQ_IDACS           0x38
+-#define RADIO_2057_CMOSBUF_TX2GI_IDACS           0x39
+-#define RADIO_2057_CMOSBUF_TX5GQ_IDACS           0x3a
+-#define RADIO_2057_CMOSBUF_TX5GI_IDACS           0x3b
+-#define RADIO_2057_CMOSBUF_RX2GQ_IDACS           0x3c
+-#define RADIO_2057_CMOSBUF_RX2GI_IDACS           0x3d
+-#define RADIO_2057_CMOSBUF_RX5GQ_IDACS           0x3e
+-#define RADIO_2057_CMOSBUF_RX5GI_IDACS           0x3f
+-#define RADIO_2057_LOGEN_MX2G_IDACS              0x40
+-#define RADIO_2057_LOGEN_MX2G_TUNE               0x41
+-#define RADIO_2057_LOGEN_MX5G_IDACS              0x42
+-#define RADIO_2057_LOGEN_MX5G_TUNE               0x43
+-#define RADIO_2057_LOGEN_MX5G_RCCR               0x44
+-#define RADIO_2057_LOGEN_INDBUF2G_IDAC           0x45
+-#define RADIO_2057_LOGEN_INDBUF2G_IBOOST         0x46
+-#define RADIO_2057_LOGEN_INDBUF2G_TUNE           0x47
+-#define RADIO_2057_LOGEN_INDBUF5G_IDAC           0x48
+-#define RADIO_2057_LOGEN_INDBUF5G_IBOOST         0x49
+-#define RADIO_2057_LOGEN_INDBUF5G_TUNE           0x4a
+-#define RADIO_2057_CMOSBUF_TX_RCCR               0x4b
+-#define RADIO_2057_CMOSBUF_RX_RCCR               0x4c
+-#define RADIO_2057_LOGEN_SEL_PKDET               0x4d
+-#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT          0x4e
+-#define RADIO_2057_RXTXBIAS_CONFIG_CORE0         0x4f
+-#define RADIO_2057_TXGM_TXRF_PUS_CORE0           0x50
+-#define RADIO_2057_TXGM_IDAC_BLEED_CORE0         0x51
+-#define RADIO_2057_TXGM_GAIN_CORE0               0x56
+-#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0        0x57
+-#define RADIO_2057_PAD2G_PTATS_CORE0             0x58
+-#define RADIO_2057_PAD2G_IDACS_CORE0             0x59
+-#define RADIO_2057_PAD2G_BOOST_PU_CORE0          0x5a
+-#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0        0x5b
+-#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0   0x5c
+-#define RADIO_2057_TXMIX2G_LODC_CORE0            0x5d
+-#define RADIO_2057_PAD2G_TUNE_PUS_CORE0          0x5e
+-#define RADIO_2057_IPA2G_GAIN_CORE0              0x5f
+-#define RADIO_2057_TSSI2G_SPARE1_CORE0           0x60
+-#define RADIO_2057_TSSI2G_SPARE2_CORE0           0x61
+-#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0  0x62
+-#define RADIO_2057_IPA2G_IMAIN_CORE0             0x63
+-#define RADIO_2057_IPA2G_CASCONV_CORE0           0x64
+-#define RADIO_2057_IPA2G_CASCOFFV_CORE0          0x65
+-#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0       0x66
+-#define RADIO_2057_TX5G_PKDET_CORE0              0x69
+-#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0      0x6a
+-#define RADIO_2057_PAD5G_PTATS1_CORE0            0x6b
+-#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0      0x6c
+-#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0     0x6d
+-#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0       0x6e
+-#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f
+-#define RADIO_2057_PGA_BOOST_TUNE_CORE0          0x70
+-#define RADIO_2057_PGA_GAIN_CORE0                0x71
+-#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72
+-#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0      0x73
+-#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0     0x74
+-#define RADIO_2057_IPA5G_IAUX_CORE0              0x75
+-#define RADIO_2057_IPA5G_GAIN_CORE0              0x76
+-#define RADIO_2057_TSSI5G_SPARE1_CORE0           0x77
+-#define RADIO_2057_TSSI5G_SPARE2_CORE0           0x78
+-#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0       0x79
+-#define RADIO_2057_IPA5G_PTAT_CORE0              0x7a
+-#define RADIO_2057_IPA5G_IMAIN_CORE0             0x7b
+-#define RADIO_2057_IPA5G_CASCONV_CORE0           0x7c
+-#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0       0x7d
+-#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0     0x80
+-#define RADIO_2057_TR2G_CONFIG1_CORE0_NU         0x81
+-#define RADIO_2057_TR2G_CONFIG2_CORE0_NU         0x82
+-#define RADIO_2057_LNA5G_RFEN_CORE0              0x83
+-#define RADIO_2057_TR5G_CONFIG2_CORE0_NU         0x84
+-#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0      0x85
+-#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86
+-#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0  0x87
+-#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0   0x88
+-#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0      0x89
+-#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0      0x8a
+-#define RADIO_2057_LNA2_IAUX_PTAT_CORE0          0x8b
+-#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0      0x8c
+-#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d
+-#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0        0x8e
+-#define RADIO_2057_TIA_CONFIG_CORE0              0x8f
+-#define RADIO_2057_TIA_IQGAIN_CORE0              0x90
+-#define RADIO_2057_TIA_IBIAS2_CORE0              0x91
+-#define RADIO_2057_TIA_IBIAS1_CORE0              0x92
+-#define RADIO_2057_TIA_SPARE_Q_CORE0             0x93
+-#define RADIO_2057_TIA_SPARE_I_CORE0             0x94
+-#define RADIO_2057_RXMIX2G_PUS_CORE0             0x95
+-#define RADIO_2057_RXMIX2G_VCMREFS_CORE0         0x96
+-#define RADIO_2057_RXMIX2G_LODC_QI_CORE0         0x97
+-#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0       0x98
+-#define RADIO_2057_LNA2G_GAIN_CORE0              0x99
+-#define RADIO_2057_LNA2G_TUNE_CORE0              0x9a
+-#define RADIO_2057_RXMIX5G_PUS_CORE0             0x9b
+-#define RADIO_2057_RXMIX5G_VCMREFS_CORE0         0x9c
+-#define RADIO_2057_RXMIX5G_LODC_QI_CORE0         0x9d
+-#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0       0x9e
+-#define RADIO_2057_LNA5G_GAIN_CORE0              0x9f
+-#define RADIO_2057_LNA5G_TUNE_CORE0              0xa0
+-#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0    0xa1
+-#define RADIO_2057_RXBB_BIAS_MASTER_CORE0        0xa2
+-#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0       0xa3
+-#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4
+-#define RADIO_2057_TXBUF_VINCM_CORE0             0xa5
+-#define RADIO_2057_TXBUF_IDACS_CORE0             0xa6
+-#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0       0xa7
+-#define RADIO_2057_RXBB_CC_CORE0                 0xa8
+-#define RADIO_2057_RXBB_SPARE3_CORE0             0xa9
+-#define RADIO_2057_RXBB_RCCAL_HPC_CORE0          0xaa
+-#define RADIO_2057_LPF_IDACS_CORE0               0xab
+-#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0  0xac
+-#define RADIO_2057_TXBUF_GAIN_CORE0              0xad
+-#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0   0xae
+-#define RADIO_2057_RXBUF_DEGEN_CORE0             0xaf
+-#define RADIO_2057_RXBB_SPARE2_CORE0             0xb0
+-#define RADIO_2057_RXBB_SPARE1_CORE0             0xb1
+-#define RADIO_2057_RSSI_MASTER_CORE0             0xb2
+-#define RADIO_2057_W2_MASTER_CORE0               0xb3
+-#define RADIO_2057_NB_MASTER_CORE0               0xb4
+-#define RADIO_2057_W2_IDACS0_Q_CORE0             0xb5
+-#define RADIO_2057_W2_IDACS1_Q_CORE0             0xb6
+-#define RADIO_2057_W2_IDACS0_I_CORE0             0xb7
+-#define RADIO_2057_W2_IDACS1_I_CORE0             0xb8
+-#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0  0xb9
+-#define RADIO_2057_NB_IDACS_Q_CORE0              0xba
+-#define RADIO_2057_NB_IDACS_I_CORE0              0xbb
+-#define RADIO_2057_BACKUP4_CORE0                 0xc1
+-#define RADIO_2057_BACKUP3_CORE0                 0xc2
+-#define RADIO_2057_BACKUP2_CORE0                 0xc3
+-#define RADIO_2057_BACKUP1_CORE0                 0xc4
+-#define RADIO_2057_SPARE16_CORE0                 0xc5
+-#define RADIO_2057_SPARE15_CORE0                 0xc6
+-#define RADIO_2057_SPARE14_CORE0                 0xc7
+-#define RADIO_2057_SPARE13_CORE0                 0xc8
+-#define RADIO_2057_SPARE12_CORE0                 0xc9
+-#define RADIO_2057_SPARE11_CORE0                 0xca
+-#define RADIO_2057_TX2G_BIAS_RESETS_CORE0        0xcb
+-#define RADIO_2057_TX5G_BIAS_RESETS_CORE0        0xcc
+-#define RADIO_2057_IQTEST_SEL_PU                 0xcd
+-#define RADIO_2057_XTAL_CONFIG2                  0xce
+-#define RADIO_2057_BUFS_MISC_LPFBW_CORE0         0xcf
+-#define RADIO_2057_TXLPF_RCCAL_CORE0             0xd0
+-#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1
+-#define RADIO_2057_LPF_GAIN_CORE0                0xd2
+-#define RADIO_2057_DACBUF_IDACS_BW_CORE0         0xd3
+-#define RADIO_2057_RXTXBIAS_CONFIG_CORE1         0xd4
+-#define RADIO_2057_TXGM_TXRF_PUS_CORE1           0xd5
+-#define RADIO_2057_TXGM_IDAC_BLEED_CORE1         0xd6
+-#define RADIO_2057_TXGM_GAIN_CORE1               0xdb
+-#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1        0xdc
+-#define RADIO_2057_PAD2G_PTATS_CORE1             0xdd
+-#define RADIO_2057_PAD2G_IDACS_CORE1             0xde
+-#define RADIO_2057_PAD2G_BOOST_PU_CORE1          0xdf
+-#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1        0xe0
+-#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1   0xe1
+-#define RADIO_2057_TXMIX2G_LODC_CORE1            0xe2
+-#define RADIO_2057_PAD2G_TUNE_PUS_CORE1          0xe3
+-#define RADIO_2057_IPA2G_GAIN_CORE1              0xe4
+-#define RADIO_2057_TSSI2G_SPARE1_CORE1           0xe5
+-#define RADIO_2057_TSSI2G_SPARE2_CORE1           0xe6
+-#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1  0xe7
+-#define RADIO_2057_IPA2G_IMAIN_CORE1             0xe8
+-#define RADIO_2057_IPA2G_CASCONV_CORE1           0xe9
+-#define RADIO_2057_IPA2G_CASCOFFV_CORE1          0xea
+-#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1       0xeb
+-#define RADIO_2057_TX5G_PKDET_CORE1              0xee
+-#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1      0xef
+-#define RADIO_2057_PAD5G_PTATS1_CORE1            0xf0
+-#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1      0xf1
+-#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1     0xf2
+-#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1       0xf3
+-#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4
+-#define RADIO_2057_PGA_BOOST_TUNE_CORE1          0xf5
+-#define RADIO_2057_PGA_GAIN_CORE1                0xf6
+-#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7
+-#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1      0xf8
+-#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1     0xf9
+-#define RADIO_2057_IPA5G_IAUX_CORE1              0xfa
+-#define RADIO_2057_IPA5G_GAIN_CORE1              0xfb
+-#define RADIO_2057_TSSI5G_SPARE1_CORE1           0xfc
+-#define RADIO_2057_TSSI5G_SPARE2_CORE1           0xfd
+-#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1       0xfe
+-#define RADIO_2057_IPA5G_PTAT_CORE1              0xff
+-#define RADIO_2057_IPA5G_IMAIN_CORE1             0x100
+-#define RADIO_2057_IPA5G_CASCONV_CORE1           0x101
+-#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1       0x102
+-#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1     0x105
+-#define RADIO_2057_TR2G_CONFIG1_CORE1_NU         0x106
+-#define RADIO_2057_TR2G_CONFIG2_CORE1_NU         0x107
+-#define RADIO_2057_LNA5G_RFEN_CORE1              0x108
+-#define RADIO_2057_TR5G_CONFIG2_CORE1_NU         0x109
+-#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1      0x10a
+-#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b
+-#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1  0x10c
+-#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1   0x10d
+-#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1      0x10e
+-#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1      0x10f
+-#define RADIO_2057_LNA2_IAUX_PTAT_CORE1          0x110
+-#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1      0x111
+-#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112
+-#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1        0x113
+-#define RADIO_2057_TIA_CONFIG_CORE1              0x114
+-#define RADIO_2057_TIA_IQGAIN_CORE1              0x115
+-#define RADIO_2057_TIA_IBIAS2_CORE1              0x116
+-#define RADIO_2057_TIA_IBIAS1_CORE1              0x117
+-#define RADIO_2057_TIA_SPARE_Q_CORE1             0x118
+-#define RADIO_2057_TIA_SPARE_I_CORE1             0x119
+-#define RADIO_2057_RXMIX2G_PUS_CORE1             0x11a
+-#define RADIO_2057_RXMIX2G_VCMREFS_CORE1         0x11b
+-#define RADIO_2057_RXMIX2G_LODC_QI_CORE1         0x11c
+-#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1       0x11d
+-#define RADIO_2057_LNA2G_GAIN_CORE1              0x11e
+-#define RADIO_2057_LNA2G_TUNE_CORE1              0x11f
+-#define RADIO_2057_RXMIX5G_PUS_CORE1             0x120
+-#define RADIO_2057_RXMIX5G_VCMREFS_CORE1         0x121
+-#define RADIO_2057_RXMIX5G_LODC_QI_CORE1         0x122
+-#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1       0x123
+-#define RADIO_2057_LNA5G_GAIN_CORE1              0x124
+-#define RADIO_2057_LNA5G_TUNE_CORE1              0x125
+-#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1    0x126
+-#define RADIO_2057_RXBB_BIAS_MASTER_CORE1        0x127
+-#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1       0x128
+-#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129
+-#define RADIO_2057_TXBUF_VINCM_CORE1             0x12a
+-#define RADIO_2057_TXBUF_IDACS_CORE1             0x12b
+-#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1       0x12c
+-#define RADIO_2057_RXBB_CC_CORE1                 0x12d
+-#define RADIO_2057_RXBB_SPARE3_CORE1             0x12e
+-#define RADIO_2057_RXBB_RCCAL_HPC_CORE1          0x12f
+-#define RADIO_2057_LPF_IDACS_CORE1               0x130
+-#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1  0x131
+-#define RADIO_2057_TXBUF_GAIN_CORE1              0x132
+-#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1   0x133
+-#define RADIO_2057_RXBUF_DEGEN_CORE1             0x134
+-#define RADIO_2057_RXBB_SPARE2_CORE1             0x135
+-#define RADIO_2057_RXBB_SPARE1_CORE1             0x136
+-#define RADIO_2057_RSSI_MASTER_CORE1             0x137
+-#define RADIO_2057_W2_MASTER_CORE1               0x138
+-#define RADIO_2057_NB_MASTER_CORE1               0x139
+-#define RADIO_2057_W2_IDACS0_Q_CORE1             0x13a
+-#define RADIO_2057_W2_IDACS1_Q_CORE1             0x13b
+-#define RADIO_2057_W2_IDACS0_I_CORE1             0x13c
+-#define RADIO_2057_W2_IDACS1_I_CORE1             0x13d
+-#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1  0x13e
+-#define RADIO_2057_NB_IDACS_Q_CORE1              0x13f
+-#define RADIO_2057_NB_IDACS_I_CORE1              0x140
+-#define RADIO_2057_BACKUP4_CORE1                 0x146
+-#define RADIO_2057_BACKUP3_CORE1                 0x147
+-#define RADIO_2057_BACKUP2_CORE1                 0x148
+-#define RADIO_2057_BACKUP1_CORE1                 0x149
+-#define RADIO_2057_SPARE16_CORE1                 0x14a
+-#define RADIO_2057_SPARE15_CORE1                 0x14b
+-#define RADIO_2057_SPARE14_CORE1                 0x14c
+-#define RADIO_2057_SPARE13_CORE1                 0x14d
+-#define RADIO_2057_SPARE12_CORE1                 0x14e
+-#define RADIO_2057_SPARE11_CORE1                 0x14f
+-#define RADIO_2057_TX2G_BIAS_RESETS_CORE1        0x150
+-#define RADIO_2057_TX5G_BIAS_RESETS_CORE1        0x151
+-#define RADIO_2057_SPARE8_CORE1                  0x152
+-#define RADIO_2057_SPARE7_CORE1                  0x153
+-#define RADIO_2057_BUFS_MISC_LPFBW_CORE1         0x154
+-#define RADIO_2057_TXLPF_RCCAL_CORE1             0x155
+-#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
+-#define RADIO_2057_LPF_GAIN_CORE1                0x157
+-#define RADIO_2057_DACBUF_IDACS_BW_CORE1         0x158
+-#define RADIO_2057_DACBUF_VINCM_CORE1            0x159
+-#define RADIO_2057_RCCAL_START_R1_Q1_P1          0x15a
+-#define RADIO_2057_RCCAL_X1                      0x15b
+-#define RADIO_2057_RCCAL_TRC0                    0x15c
+-#define RADIO_2057_RCCAL_TRC1                    0x15d
+-#define RADIO_2057_RCCAL_DONE_OSCCAP             0x15e
+-#define RADIO_2057_RCCAL_N0_0                    0x15f
+-#define RADIO_2057_RCCAL_N0_1                    0x160
+-#define RADIO_2057_RCCAL_N1_0                    0x161
+-#define RADIO_2057_RCCAL_N1_1                    0x162
+-#define RADIO_2057_RCAL_STATUS                   0x163
+-#define RADIO_2057_XTALPUOVR_PINCTRL             0x164
+-#define RADIO_2057_OVR_REG0                      0x165
+-#define RADIO_2057_OVR_REG1                      0x166
+-#define RADIO_2057_OVR_REG2                      0x167
+-#define RADIO_2057_OVR_REG3                      0x168
+-#define RADIO_2057_OVR_REG4                      0x169
+-#define RADIO_2057_RCCAL_SCAP_VAL                0x16a
+-#define RADIO_2057_RCCAL_BCAP_VAL                0x16b
+-#define RADIO_2057_RCCAL_HPC_VAL                 0x16c
+-#define RADIO_2057_RCCAL_OVERRIDES               0x16d
+-#define RADIO_2057_TX0_IQCAL_GAIN_BW             0x170
+-#define RADIO_2057_TX0_LOFT_FINE_I               0x171
+-#define RADIO_2057_TX0_LOFT_FINE_Q               0x172
+-#define RADIO_2057_TX0_LOFT_COARSE_I             0x173
+-#define RADIO_2057_TX0_LOFT_COARSE_Q             0x174
+-#define RADIO_2057_TX0_TX_SSI_MASTER             0x175
+-#define RADIO_2057_TX0_IQCAL_VCM_HG              0x176
+-#define RADIO_2057_TX0_IQCAL_IDAC                0x177
+-#define RADIO_2057_TX0_TSSI_VCM                  0x178
+-#define RADIO_2057_TX0_TX_SSI_MUX                0x179
+-#define RADIO_2057_TX0_TSSIA                     0x17a
+-#define RADIO_2057_TX0_TSSIG                     0x17b
+-#define RADIO_2057_TX0_TSSI_MISC1                0x17c
+-#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN       0x17d
+-#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP       0x17e
+-#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN       0x17f
+-#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP       0x180
+-#define RADIO_2057_TX1_IQCAL_GAIN_BW             0x190
+-#define RADIO_2057_TX1_LOFT_FINE_I               0x191
+-#define RADIO_2057_TX1_LOFT_FINE_Q               0x192
+-#define RADIO_2057_TX1_LOFT_COARSE_I             0x193
+-#define RADIO_2057_TX1_LOFT_COARSE_Q             0x194
+-#define RADIO_2057_TX1_TX_SSI_MASTER             0x195
+-#define RADIO_2057_TX1_IQCAL_VCM_HG              0x196
+-#define RADIO_2057_TX1_IQCAL_IDAC                0x197
+-#define RADIO_2057_TX1_TSSI_VCM                  0x198
+-#define RADIO_2057_TX1_TX_SSI_MUX                0x199
+-#define RADIO_2057_TX1_TSSIA                     0x19a
+-#define RADIO_2057_TX1_TSSIG                     0x19b
+-#define RADIO_2057_TX1_TSSI_MISC1                0x19c
+-#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN       0x19d
+-#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP       0x19e
+-#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN       0x19f
+-#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP       0x1a0
+-#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0      0x1a1
+-#define RADIO_2057_AFE_SET_VCM_I_CORE0           0x1a2
+-#define RADIO_2057_AFE_SET_VCM_Q_CORE0           0x1a3
+-#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0    0x1a4
+-#define RADIO_2057_AFE_STATUS_VCM_I_CORE0        0x1a5
+-#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0        0x1a6
+-#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1      0x1a7
+-#define RADIO_2057_AFE_SET_VCM_I_CORE1           0x1a8
+-#define RADIO_2057_AFE_SET_VCM_Q_CORE1           0x1a9
+-#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1    0x1aa
+-#define RADIO_2057_AFE_STATUS_VCM_I_CORE1        0x1ab
+-#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1        0x1ac
+-
+-#define RADIO_2057v7_DACBUF_VINCM_CORE0          0x1ad
+-#define RADIO_2057v7_RCCAL_MASTER                0x1ae
+-#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU       0x1af
+-#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU       0x1b0
+-#define RADIO_2057v7_LOGEN_PUS1                  0x1b1
+-#define RADIO_2057v7_OVR_REG5                    0x1b2
+-#define RADIO_2057v7_OVR_REG6                    0x1b3
+-#define RADIO_2057v7_OVR_REG7                    0x1b4
+-#define RADIO_2057v7_OVR_REG8                    0x1b5
+-#define RADIO_2057v7_OVR_REG9                    0x1b6
+-#define RADIO_2057v7_OVR_REG10                   0x1b7
+-#define RADIO_2057v7_OVR_REG11                   0x1b8
+-#define RADIO_2057v7_OVR_REG12                   0x1b9
+-#define RADIO_2057v7_OVR_REG13                   0x1ba
+-#define RADIO_2057v7_OVR_REG14                   0x1bb
+-#define RADIO_2057v7_OVR_REG15                   0x1bc
+-#define RADIO_2057v7_OVR_REG16                   0x1bd
+-#define RADIO_2057v7_OVR_REG1                    0x1be
+-#define RADIO_2057v7_OVR_REG18                   0x1bf
+-#define RADIO_2057v7_OVR_REG19                   0x1c0
+-#define RADIO_2057v7_OVR_REG20                   0x1c1
+-#define RADIO_2057v7_OVR_REG21                   0x1c2
+-#define RADIO_2057v7_OVR_REG2                    0x1c3
+-#define RADIO_2057v7_OVR_REG23                   0x1c4
+-#define RADIO_2057v7_OVR_REG24                   0x1c5
+-#define RADIO_2057v7_OVR_REG25                   0x1c6
+-#define RADIO_2057v7_OVR_REG26                   0x1c7
+-#define RADIO_2057v7_OVR_REG27                   0x1c8
+-#define RADIO_2057v7_OVR_REG28                   0x1c9
+-#define RADIO_2057v7_IQTEST_SEL_PU2              0x1ca
+-
+-#define RADIO_2057_VCM_MASK			 0x7
+-
+-#endif				/* _BCM20XX_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
+deleted file mode 100644
+index 211bc3a..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define NPHY_TBL_ID_GAIN1		0
+-#define NPHY_TBL_ID_GAIN2		1
+-#define NPHY_TBL_ID_GAINBITS1		2
+-#define NPHY_TBL_ID_GAINBITS2		3
+-#define NPHY_TBL_ID_GAINLIMIT		4
+-#define NPHY_TBL_ID_WRSSIGainLimit	5
+-#define NPHY_TBL_ID_RFSEQ		7
+-#define NPHY_TBL_ID_AFECTRL		8
+-#define NPHY_TBL_ID_ANTSWCTRLLUT	9
+-#define NPHY_TBL_ID_IQLOCAL		15
+-#define NPHY_TBL_ID_NOISEVAR		16
+-#define NPHY_TBL_ID_SAMPLEPLAY		17
+-#define NPHY_TBL_ID_CORE1TXPWRCTL	26
+-#define NPHY_TBL_ID_CORE2TXPWRCTL	27
+-#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL	30
+-
+-#define NPHY_TBL_ID_EPSILONTBL0   31
+-#define NPHY_TBL_ID_SCALARTBL0    32
+-#define NPHY_TBL_ID_EPSILONTBL1   33
+-#define NPHY_TBL_ID_SCALARTBL1    34
+-
+-#define	NPHY_TO_BPHY_OFF	0xc00
+-
+-#define NPHY_BandControl_currentBand			0x0001
+-#define RFCC_CHIP0_PU			0x0400
+-#define RFCC_POR_FORCE			0x0040
+-#define RFCC_OE_POR_FORCE		0x0080
+-#define NPHY_RfctrlIntc_override_OFF			0
+-#define NPHY_RfctrlIntc_override_TRSW			1
+-#define NPHY_RfctrlIntc_override_PA				2
+-#define NPHY_RfctrlIntc_override_EXT_LNA_PU		3
+-#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN	4
+-#define RIFS_ENABLE			0x80
+-#define BPHY_BAND_SEL_UP20		0x10
+-#define NPHY_MLenable			0x02
+-
+-#define NPHY_RfseqMode_CoreActv_override 0x0001
+-#define NPHY_RfseqMode_Trigger_override	0x0002
+-#define NPHY_RfseqCoreActv_TxRxChain0	(0x11)
+-#define NPHY_RfseqCoreActv_TxRxChain1	(0x22)
+-
+-#define NPHY_RfseqTrigger_rx2tx		0x0001
+-#define NPHY_RfseqTrigger_tx2rx		0x0002
+-#define NPHY_RfseqTrigger_updategainh	0x0004
+-#define NPHY_RfseqTrigger_updategainl	0x0008
+-#define NPHY_RfseqTrigger_updategainu	0x0010
+-#define NPHY_RfseqTrigger_reset2rx	0x0020
+-#define NPHY_RfseqStatus_rx2tx		0x0001
+-#define NPHY_RfseqStatus_tx2rx		0x0002
+-#define NPHY_RfseqStatus_updategainh	0x0004
+-#define NPHY_RfseqStatus_updategainl	0x0008
+-#define NPHY_RfseqStatus_updategainu	0x0010
+-#define NPHY_RfseqStatus_reset2rx	0x0020
+-#define NPHY_ClassifierCtrl_cck_en	0x1
+-#define NPHY_ClassifierCtrl_ofdm_en	0x2
+-#define NPHY_ClassifierCtrl_waited_en	0x4
+-#define NPHY_IQFlip_ADC1		0x0001
+-#define NPHY_IQFlip_ADC2		0x0010
+-#define NPHY_sampleCmd_STOP		0x0002
+-
+-#define RX_GF_OR_MM			0x0004
+-#define RX_GF_MM_AUTO			0x0100
+-
+-#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN	0x8000
+-
+-#define NPHY_IqestCmd_iqstart		0x1
+-#define NPHY_IqestCmd_iqMode		0x2
+-
+-#define NPHY_TxPwrCtrlCmd_pwrIndex_init		0x40
+-#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7	0x19
+-
+-#define PRIM_SEL_UP20		0x8000
+-
+-#define NPHY_RFSEQ_RX2TX		0x0
+-#define NPHY_RFSEQ_TX2RX		0x1
+-#define NPHY_RFSEQ_RESET2RX		0x2
+-#define NPHY_RFSEQ_UPDATEGAINH		0x3
+-#define NPHY_RFSEQ_UPDATEGAINL		0x4
+-#define NPHY_RFSEQ_UPDATEGAINU		0x5
+-
+-#define NPHY_RFSEQ_CMD_NOP		0x0
+-#define NPHY_RFSEQ_CMD_RXG_FBW		0x1
+-#define NPHY_RFSEQ_CMD_TR_SWITCH	0x2
+-#define NPHY_RFSEQ_CMD_EXT_PA		0x3
+-#define NPHY_RFSEQ_CMD_RXPD_TXPD	0x4
+-#define NPHY_RFSEQ_CMD_TX_GAIN		0x5
+-#define NPHY_RFSEQ_CMD_RX_GAIN		0x6
+-#define NPHY_RFSEQ_CMD_SET_HPF_BW	0x7
+-#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS	0x8
+-#define NPHY_RFSEQ_CMD_END		0xf
+-
+-#define NPHY_REV3_RFSEQ_CMD_NOP		0x0
+-#define NPHY_REV3_RFSEQ_CMD_RXG_FBW	0x1
+-#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH	0x2
+-#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU	0x3
+-#define NPHY_REV3_RFSEQ_CMD_EXT_PA	0x4
+-#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD	0x5
+-#define NPHY_REV3_RFSEQ_CMD_TX_GAIN	0x6
+-#define NPHY_REV3_RFSEQ_CMD_RX_GAIN	0x7
+-#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS	0x8
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC	0x9
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC	0xa
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC	0xb
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC	0xc
+-#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC	0xd
+-#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC	0xe
+-#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS	0xf
+-#define NPHY_REV3_RFSEQ_CMD_END		0x1f
+-
+-#define NPHY_RSSI_SEL_W1 		0x0
+-#define NPHY_RSSI_SEL_W2 		0x1
+-#define NPHY_RSSI_SEL_NB 		0x2
+-#define NPHY_RSSI_SEL_IQ 		0x3
+-#define NPHY_RSSI_SEL_TSSI_2G 		0x4
+-#define NPHY_RSSI_SEL_TSSI_5G 		0x5
+-#define NPHY_RSSI_SEL_TBD 		0x6
+-
+-#define NPHY_RAIL_I			0x0
+-#define NPHY_RAIL_Q			0x1
+-
+-#define NPHY_FORCESIG_DECODEGATEDCLKS	0x8
+-
+-#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
+-#define NPHY_REV7_RfctrlOverride_cmd_rx_pu   0x1
+-#define NPHY_REV7_RfctrlOverride_cmd_tx_pu   0x2
+-#define NPHY_REV7_RfctrlOverride_cmd_rxgain  0x3
+-#define NPHY_REV7_RfctrlOverride_cmd_txgain  0x4
+-
+-#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
+-#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK  0x0ff00
+-#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
+-
+-#define NPHY_REV7_TXGAINCODE_TGAIN_MASK     0x7fff
+-#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK   0x8000
+-#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
+-
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
+-#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
+-
+-#define NPHY_IqestIqAccLo(core)  ((core == 0) ? 0x12c : 0x134)
+-
+-#define NPHY_IqestIqAccHi(core)  ((core == 0) ? 0x12d : 0x135)
+-
+-#define NPHY_IqestipwrAccLo(core)  ((core == 0) ? 0x12e : 0x136)
+-
+-#define NPHY_IqestipwrAccHi(core)  ((core == 0) ? 0x12f : 0x137)
+-
+-#define NPHY_IqestqpwrAccLo(core)  ((core == 0) ? 0x130 : 0x138)
+-
+-#define NPHY_IqestqpwrAccHi(core)  ((core == 0) ? 0x131 : 0x139)
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
+deleted file mode 100644
+index 81c59b0..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c
++++ /dev/null
+@@ -1,3639 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <sbhnddma.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phytbl_lcn.h>
+-
+-const u32 dot11lcn_gain_tbl_rev0[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000004,
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x000000cd,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x000000d3,
+-	0x00000113,
+-	0x00000513,
+-	0x00000913,
+-	0x00000953,
+-	0x00000d53,
+-	0x00001153,
+-	0x00001193,
+-	0x00005193,
+-	0x00009193,
+-	0x0000d193,
+-	0x00011193,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000004,
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x000000cd,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x000000d3,
+-	0x00000113,
+-	0x00000513,
+-	0x00000913,
+-	0x00000953,
+-	0x00000d53,
+-	0x00001153,
+-	0x00005153,
+-	0x00009153,
+-	0x0000d153,
+-	0x00011153,
+-	0x00015153,
+-	0x00019153,
+-	0x0001d153,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 dot11lcn_gain_tbl_rev1[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000D,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x000000d1,
+-	0x00000053,
+-	0x00000093,
+-	0x000000d3,
+-	0x000000d7,
+-	0x00000117,
+-	0x00000517,
+-	0x00000917,
+-	0x00000957,
+-	0x00000d57,
+-	0x00001157,
+-	0x00001197,
+-	0x00005197,
+-	0x00009197,
+-	0x0000d197,
+-	0x00011197,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000D,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x00000011,
+-	0x00000051,
+-	0x00000091,
+-	0x000000d1,
+-	0x00000053,
+-	0x00000093,
+-	0x000000d3,
+-	0x000000d7,
+-	0x00000117,
+-	0x00000517,
+-	0x00000917,
+-	0x00000957,
+-	0x00000d57,
+-	0x00001157,
+-	0x00005157,
+-	0x00009157,
+-	0x0000d157,
+-	0x00011157,
+-	0x00015157,
+-	0x00019157,
+-	0x0001d157,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = {
+-	0x0401,
+-	0x0402,
+-	0x0403,
+-	0x0404,
+-	0x0405,
+-	0x0406,
+-	0x0407,
+-	0x0408,
+-	0x0409,
+-	0x040a,
+-	0x058b,
+-	0x058c,
+-	0x058d,
+-	0x058e,
+-	0x058f,
+-	0x0090,
+-	0x0091,
+-	0x0092,
+-	0x0193,
+-	0x0194,
+-	0x0195,
+-	0x0196,
+-	0x0197,
+-	0x0198,
+-	0x0199,
+-	0x019a,
+-	0x019b,
+-	0x019c,
+-	0x019d,
+-	0x019e,
+-	0x019f,
+-	0x01a0,
+-	0x01a1,
+-	0x01a2,
+-	0x01a3,
+-	0x01a4,
+-	0x01a5,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_rev0[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x20000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000000,
+-	0x40000000,
+-	0x00000000,
+-	0x50000000,
+-	0x00000000,
+-	0x60000000,
+-	0x00000000,
+-	0x70000000,
+-	0x00000000,
+-	0x80000000,
+-	0x00000000,
+-	0x90000000,
+-	0x00000008,
+-	0xa0000000,
+-	0x00000008,
+-	0xb0000000,
+-	0x00000008,
+-	0xc0000000,
+-	0x00000008,
+-	0xd0000000,
+-	0x00000008,
+-	0xe0000000,
+-	0x00000008,
+-	0xf0000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000009,
+-	0x10000000,
+-	0x00000009,
+-	0x20000000,
+-	0x00000019,
+-	0x30000000,
+-	0x00000019,
+-	0x40000000,
+-	0x00000019,
+-	0x50000000,
+-	0x00000019,
+-	0x60000000,
+-	0x00000019,
+-	0x70000000,
+-	0x00000019,
+-	0x80000000,
+-	0x00000019,
+-	0x90000000,
+-	0x00000019,
+-	0xa0000000,
+-	0x00000019,
+-	0xb0000000,
+-	0x00000019,
+-	0xc0000000,
+-	0x00000019,
+-	0xd0000000,
+-	0x00000019,
+-	0xe0000000,
+-	0x00000019,
+-	0xf0000000,
+-	0x00000019,
+-	0x00000000,
+-	0x0000001a,
+-	0x10000000,
+-	0x0000001a,
+-	0x20000000,
+-	0x0000001a,
+-	0x30000000,
+-	0x0000001a,
+-	0x40000000,
+-	0x0000001a,
+-	0x50000000,
+-	0x00000002,
+-	0x60000000,
+-	0x00000002,
+-	0x70000000,
+-	0x00000002,
+-	0x80000000,
+-	0x00000002,
+-	0x90000000,
+-	0x00000002,
+-	0xa0000000,
+-	0x00000002,
+-	0xb0000000,
+-	0x00000002,
+-	0xc0000000,
+-	0x0000000a,
+-	0xd0000000,
+-	0x0000000a,
+-	0xe0000000,
+-	0x0000000a,
+-	0xf0000000,
+-	0x0000000a,
+-	0x00000000,
+-	0x0000000b,
+-	0x10000000,
+-	0x0000000b,
+-	0x20000000,
+-	0x0000000b,
+-	0x30000000,
+-	0x0000000b,
+-	0x40000000,
+-	0x0000000b,
+-	0x50000000,
+-	0x0000001b,
+-	0x60000000,
+-	0x0000001b,
+-	0x70000000,
+-	0x0000001b,
+-	0x80000000,
+-	0x0000001b,
+-	0x90000000,
+-	0x0000001b,
+-	0xa0000000,
+-	0x0000001b,
+-	0xb0000000,
+-	0x0000001b,
+-	0xc0000000,
+-	0x0000001b,
+-	0xd0000000,
+-	0x0000001b,
+-	0xe0000000,
+-	0x0000001b,
+-	0xf0000000,
+-	0x0000001b,
+-	0x00000000,
+-	0x0000001c,
+-	0x10000000,
+-	0x0000001c,
+-	0x20000000,
+-	0x0000001c,
+-	0x30000000,
+-	0x0000001c,
+-	0x40000000,
+-	0x0000001c,
+-	0x50000000,
+-	0x0000001c,
+-	0x60000000,
+-	0x0000001c,
+-	0x70000000,
+-	0x0000001c,
+-	0x80000000,
+-	0x0000001c,
+-	0x90000000,
+-	0x0000001c,
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_2G[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0001,
+-	0x0080,
+-	0x0081,
+-	0x0100,
+-	0x0101,
+-	0x0180,
+-	0x0181,
+-	0x0182,
+-	0x0183,
+-	0x0184,
+-	0x0185,
+-	0x0186,
+-	0x0187,
+-	0x0188,
+-	0x0285,
+-	0x0289,
+-	0x028a,
+-	0x028b,
+-	0x028c,
+-	0x028d,
+-	0x028e,
+-	0x028f,
+-	0x0290,
+-	0x0291,
+-	0x0292,
+-	0x0293,
+-	0x0294,
+-	0x0295,
+-	0x0296,
+-	0x0297,
+-	0x0298,
+-	0x0299,
+-	0x029a,
+-	0x0000
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_2G[] = {
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x00,
+-	0x0c,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_2G[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x10000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000010,
+-	0x10000000,
+-	0x00000010,
+-	0x00000000,
+-	0x00000018,
+-	0x10000000,
+-	0x00000018,
+-	0x20000000,
+-	0x00000018,
+-	0x30000000,
+-	0x00000018,
+-	0x40000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000018,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000028,
+-	0x90000000,
+-	0x00000028,
+-	0xa0000000,
+-	0x00000028,
+-	0xb0000000,
+-	0x00000028,
+-	0xc0000000,
+-	0x00000028,
+-	0xd0000000,
+-	0x00000028,
+-	0xe0000000,
+-	0x00000028,
+-	0xf0000000,
+-	0x00000028,
+-	0x00000000,
+-	0x00000029,
+-	0x10000000,
+-	0x00000029,
+-	0x20000000,
+-	0x00000029,
+-	0x30000000,
+-	0x00000029,
+-	0x40000000,
+-	0x00000029,
+-	0x50000000,
+-	0x00000029,
+-	0x60000000,
+-	0x00000029,
+-	0x70000000,
+-	0x00000029,
+-	0x80000000,
+-	0x00000029,
+-	0x90000000,
+-	0x00000029,
+-	0xa0000000,
+-	0x00000029,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000008,
+-	0x10000000,
+-	0x00000008,
+-	0x00000000,
+-	0x00000010,
+-	0x10000000,
+-	0x00000010,
+-	0x00000000,
+-	0x00000018,
+-	0x10000000,
+-	0x00000018,
+-	0x20000000,
+-	0x00000018,
+-	0x30000000,
+-	0x00000018,
+-	0x40000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000018,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x50000000,
+-	0x00000028,
+-	0x90000000,
+-	0x00000028,
+-	0xa0000000,
+-	0x00000028,
+-	0xb0000000,
+-	0x00000028,
+-	0xc0000000,
+-	0x00000028,
+-	0xd0000000,
+-	0x00000028,
+-	0xe0000000,
+-	0x00000028,
+-	0xf0000000,
+-	0x00000028,
+-	0x00000000,
+-	0x00000029,
+-	0x10000000,
+-	0x00000029,
+-	0x20000000,
+-	0x00000029,
+-	0x30000000,
+-	0x00000029,
+-	0x40000000,
+-	0x00000029,
+-	0x50000000,
+-	0x00000029,
+-	0x60000000,
+-	0x00000029,
+-	0x70000000,
+-	0x00000029,
+-	0x80000000,
+-	0x00000029,
+-	0x90000000,
+-	0x00000029,
+-	0xa0000000,
+-	0x00000029,
+-	0xb0000000,
+-	0x00000029,
+-	0xc0000000,
+-	0x00000029,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_2G[] = {
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x0000004d,
+-	0x0000008d,
+-	0x00000049,
+-	0x00000089,
+-	0x000000c9,
+-	0x0000004b,
+-	0x0000008b,
+-	0x000000cb,
+-	0x000000cf,
+-	0x0000010f,
+-	0x0000050f,
+-	0x0000090f,
+-	0x0000094f,
+-	0x00000d4f,
+-	0x0000114f,
+-	0x0000118f,
+-	0x0000518f,
+-	0x0000918f,
+-	0x0000d18f,
+-	0x0001118f,
+-	0x0001518f,
+-	0x0001918f,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_extlna_2G[] = {
+-	0x00000000,
+-	0x00000004,
+-	0x00000008,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x00000003,
+-	0x00000007,
+-	0x0000000b,
+-	0x0000000f,
+-	0x0000004f,
+-	0x0000008f,
+-	0x000000cf,
+-	0x0000010f,
+-	0x0000014f,
+-	0x0000018f,
+-	0x0000058f,
+-	0x0000098f,
+-	0x00000d8f,
+-	0x00008000,
+-	0x00008004,
+-	0x00008008,
+-	0x00008001,
+-	0x00008005,
+-	0x00008009,
+-	0x0000800d,
+-	0x00008003,
+-	0x00008007,
+-	0x0000800b,
+-	0x0000800f,
+-	0x0000804f,
+-	0x0000808f,
+-	0x000080cf,
+-	0x0000810f,
+-	0x0000814f,
+-	0x0000818f,
+-	0x0000858f,
+-	0x0000898f,
+-	0x00008d8f,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = {
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0400,
+-	0x0401,
+-	0x0402,
+-	0x0403,
+-	0x0404,
+-	0x0483,
+-	0x0484,
+-	0x0485,
+-	0x0486,
+-	0x0583,
+-	0x0584,
+-	0x0585,
+-	0x0587,
+-	0x0588,
+-	0x0589,
+-	0x058a,
+-	0x0687,
+-	0x0688,
+-	0x0689,
+-	0x068a,
+-	0x068b,
+-	0x068c,
+-	0x068d,
+-	0x068e,
+-	0x068f,
+-	0x0690,
+-	0x0691,
+-	0x0692,
+-	0x0693,
+-	0x0000
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_extlna_2G[] = {
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x02,
+-	0x08,
+-	0x0e,
+-	0x13,
+-	0x1b,
+-	0xfc,
+-	0x00,
+-	0x0f,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = {
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x00000000,
+-	0x00000040,
+-	0x10000000,
+-	0x00000040,
+-	0x20000000,
+-	0x00000040,
+-	0x30000000,
+-	0x00000040,
+-	0x40000000,
+-	0x00000040,
+-	0x30000000,
+-	0x00000048,
+-	0x40000000,
+-	0x00000048,
+-	0x50000000,
+-	0x00000048,
+-	0x60000000,
+-	0x00000048,
+-	0x30000000,
+-	0x00000058,
+-	0x40000000,
+-	0x00000058,
+-	0x50000000,
+-	0x00000058,
+-	0x70000000,
+-	0x00000058,
+-	0x80000000,
+-	0x00000058,
+-	0x90000000,
+-	0x00000058,
+-	0xa0000000,
+-	0x00000058,
+-	0x70000000,
+-	0x00000068,
+-	0x80000000,
+-	0x00000068,
+-	0x90000000,
+-	0x00000068,
+-	0xa0000000,
+-	0x00000068,
+-	0xb0000000,
+-	0x00000068,
+-	0xc0000000,
+-	0x00000068,
+-	0xd0000000,
+-	0x00000068,
+-	0xe0000000,
+-	0x00000068,
+-	0xf0000000,
+-	0x00000068,
+-	0x00000000,
+-	0x00000069,
+-	0x10000000,
+-	0x00000069,
+-	0x20000000,
+-	0x00000069,
+-	0x30000000,
+-	0x00000069,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x40000000,
+-	0x00000041,
+-	0x50000000,
+-	0x00000041,
+-	0x60000000,
+-	0x00000041,
+-	0x70000000,
+-	0x00000041,
+-	0x80000000,
+-	0x00000041,
+-	0x70000000,
+-	0x00000049,
+-	0x80000000,
+-	0x00000049,
+-	0x90000000,
+-	0x00000049,
+-	0xa0000000,
+-	0x00000049,
+-	0x70000000,
+-	0x00000059,
+-	0x80000000,
+-	0x00000059,
+-	0x90000000,
+-	0x00000059,
+-	0xb0000000,
+-	0x00000059,
+-	0xc0000000,
+-	0x00000059,
+-	0xd0000000,
+-	0x00000059,
+-	0xe0000000,
+-	0x00000059,
+-	0xb0000000,
+-	0x00000069,
+-	0xc0000000,
+-	0x00000069,
+-	0xd0000000,
+-	0x00000069,
+-	0xe0000000,
+-	0x00000069,
+-	0xf0000000,
+-	0x00000069,
+-	0x00000000,
+-	0x0000006a,
+-	0x10000000,
+-	0x0000006a,
+-	0x20000000,
+-	0x0000006a,
+-	0x30000000,
+-	0x0000006a,
+-	0x40000000,
+-	0x0000006a,
+-	0x50000000,
+-	0x0000006a,
+-	0x60000000,
+-	0x0000006a,
+-	0x70000000,
+-	0x0000006a,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_aux_gain_idx_tbl_5G[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0001,
+-	0x0002,
+-	0x0003,
+-	0x0004,
+-	0x0083,
+-	0x0084,
+-	0x0085,
+-	0x0086,
+-	0x0087,
+-	0x0186,
+-	0x0187,
+-	0x0188,
+-	0x0189,
+-	0x018a,
+-	0x018b,
+-	0x018c,
+-	0x018d,
+-	0x018e,
+-	0x018f,
+-	0x0190,
+-	0x0191,
+-	0x0192,
+-	0x0193,
+-	0x0194,
+-	0x0195,
+-	0x0196,
+-	0x0197,
+-	0x0198,
+-	0x0199,
+-	0x019a,
+-	0x019b,
+-	0x019c,
+-	0x019d,
+-	0x0000
+-};
+-
+-const u32 dot11lcn_gain_val_tbl_5G[] = {
+-	0xf7,
+-	0xfd,
+-	0x00,
+-	0x04,
+-	0x04,
+-	0x04,
+-	0xf7,
+-	0xfd,
+-	0x00,
+-	0x04,
+-	0x04,
+-	0x04,
+-	0xf6,
+-	0x00,
+-	0x0c,
+-	0x03,
+-	0xeb,
+-	0xfe,
+-	0x06,
+-	0x0a,
+-	0x10,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00
+-};
+-
+-const u32 dot11lcn_gain_idx_tbl_5G[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x10000000,
+-	0x00000000,
+-	0x20000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000000,
+-	0x40000000,
+-	0x00000000,
+-	0x30000000,
+-	0x00000008,
+-	0x40000000,
+-	0x00000008,
+-	0x50000000,
+-	0x00000008,
+-	0x60000000,
+-	0x00000008,
+-	0x70000000,
+-	0x00000008,
+-	0x60000000,
+-	0x00000018,
+-	0x70000000,
+-	0x00000018,
+-	0x80000000,
+-	0x00000018,
+-	0x90000000,
+-	0x00000018,
+-	0xa0000000,
+-	0x00000018,
+-	0xb0000000,
+-	0x00000018,
+-	0xc0000000,
+-	0x00000018,
+-	0xd0000000,
+-	0x00000018,
+-	0xe0000000,
+-	0x00000018,
+-	0xf0000000,
+-	0x00000018,
+-	0x00000000,
+-	0x00000019,
+-	0x10000000,
+-	0x00000019,
+-	0x20000000,
+-	0x00000019,
+-	0x30000000,
+-	0x00000019,
+-	0x40000000,
+-	0x00000019,
+-	0x50000000,
+-	0x00000019,
+-	0x60000000,
+-	0x00000019,
+-	0x70000000,
+-	0x00000019,
+-	0x80000000,
+-	0x00000019,
+-	0x90000000,
+-	0x00000019,
+-	0xa0000000,
+-	0x00000019,
+-	0xb0000000,
+-	0x00000019,
+-	0xc0000000,
+-	0x00000019,
+-	0xd0000000,
+-	0x00000019,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const u32 dot11lcn_gain_tbl_5G[] = {
+-	0x00000000,
+-	0x00000040,
+-	0x00000080,
+-	0x00000001,
+-	0x00000005,
+-	0x00000009,
+-	0x0000000d,
+-	0x00000011,
+-	0x00000015,
+-	0x00000055,
+-	0x00000095,
+-	0x00000017,
+-	0x0000001b,
+-	0x0000005b,
+-	0x0000009b,
+-	0x000000db,
+-	0x0000011b,
+-	0x0000015b,
+-	0x0000019b,
+-	0x0000059b,
+-	0x0000099b,
+-	0x00000d9b,
+-	0x0000119b,
+-	0x0000519b,
+-	0x0000919b,
+-	0x0000d19b,
+-	0x0001119b,
+-	0x0001519b,
+-	0x0001919b,
+-	0x0001d19b,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = {
+-	{&dot11lcn_gain_tbl_rev0,
+-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = {
+-	{&dot11lcn_gain_tbl_rev1,
+-	 sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = {
+-	{&dot11lcn_gain_tbl_2G,
+-	 sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_2G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_2G,
+-	 sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_2G,
+-	 sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]),
+-	 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = {
+-	{&dot11lcn_gain_tbl_5G,
+-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_5G,
+-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+-	 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = {
+-	{&dot11lcn_gain_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_extlna_2G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_extlna_2G,
+-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G) /
+-	 sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8}
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = {
+-	{&dot11lcn_gain_tbl_5G,
+-	 sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0,
+-	 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_gain_idx_tbl_5G,
+-	 sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]),
+-	 13, 0, 32}
+-	,
+-	{&dot11lcn_gain_val_tbl_5G,
+-	 sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]),
+-	 17, 0, 8}
+-};
+-
+-const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 =
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev0) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 =
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev1) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz =
+-    sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]);
+-
+-const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz =
+-    sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) /
+-    sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]);
+-
+-const u16 dot11lcn_min_sig_sq_tbl_rev0[] = {
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-	0x014d,
+-};
+-
+-const u16 dot11lcn_noise_scale_tbl_rev0[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = {
+-	0x000141f8,
+-	0x000021f8,
+-	0x000021fb,
+-	0x000041fb,
+-	0x0001fe4b,
+-	0x0000217b,
+-	0x00002133,
+-	0x000040eb,
+-	0x0001fea3,
+-	0x0000024b,
+-};
+-
+-const u32 dot11lcn_ps_ctrl_tbl_rev0[] = {
+-	0x00100001,
+-	0x00200010,
+-	0x00300001,
+-	0x00400010,
+-	0x00500022,
+-	0x00600122,
+-	0x00700222,
+-	0x00800322,
+-	0x00900422,
+-	0x00a00522,
+-	0x00b00622,
+-	0x00c00722,
+-	0x00d00822,
+-	0x00f00922,
+-	0x00100a22,
+-	0x00200b22,
+-	0x00300c22,
+-	0x00400d22,
+-	0x00500e22,
+-	0x00600f22,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = {
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x0007,
+-	0x0005,
+-	0x0006,
+-	0x0004,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-	0x000b,
+-	0x000b,
+-	0x000a,
+-	0x000a,
+-
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = {
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0005,
+-	0x0002,
+-	0x0000,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-	0x0007,
+-	0x0007,
+-	0x0002,
+-	0x0002,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-	0x0002,
+-	0x0008,
+-	0x0004,
+-	0x0001,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-	0x000a,
+-	0x0009,
+-	0x0006,
+-	0x0005,
+-};
+-
+-const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-	0x0004,
+-	0x0004,
+-	0x0002,
+-	0x0002,
+-};
+-
+-const u8 dot11lcn_nf_table_rev0[] = {
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-	0x5f,
+-	0x36,
+-	0x29,
+-	0x1f,
+-};
+-
+-const u8 dot11lcn_gain_val_tbl_rev0[] = {
+-	0x09,
+-	0x0f,
+-	0x14,
+-	0x18,
+-	0xfe,
+-	0x07,
+-	0x0b,
+-	0x0f,
+-	0xfb,
+-	0xfe,
+-	0x01,
+-	0x05,
+-	0x08,
+-	0x0b,
+-	0x0e,
+-	0x11,
+-	0x14,
+-	0x17,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0x06,
+-	0x09,
+-	0x0c,
+-	0x0f,
+-	0x12,
+-	0x15,
+-	0x18,
+-	0x1b,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x03,
+-	0xeb,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 dot11lcn_spur_tbl_rev0[] = {
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x02,
+-	0x03,
+-	0x01,
+-	0x03,
+-	0x02,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x02,
+-	0x03,
+-	0x01,
+-	0x03,
+-	0x02,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-	0x01,
+-};
+-
+-const u16 dot11lcn_unsup_mcs_tbl_rev0[] = {
+-	0x001a,
+-	0x0034,
+-	0x004e,
+-	0x0068,
+-	0x009c,
+-	0x00d0,
+-	0x00ea,
+-	0x0104,
+-	0x0034,
+-	0x0068,
+-	0x009c,
+-	0x00d0,
+-	0x0138,
+-	0x01a0,
+-	0x01d4,
+-	0x0208,
+-	0x004e,
+-	0x009c,
+-	0x00ea,
+-	0x0138,
+-	0x01d4,
+-	0x0270,
+-	0x02be,
+-	0x030c,
+-	0x0068,
+-	0x00d0,
+-	0x0138,
+-	0x01a0,
+-	0x0270,
+-	0x0340,
+-	0x03a8,
+-	0x0410,
+-	0x0018,
+-	0x009c,
+-	0x00d0,
+-	0x0104,
+-	0x00ea,
+-	0x0138,
+-	0x0186,
+-	0x00d0,
+-	0x0104,
+-	0x0104,
+-	0x0138,
+-	0x016c,
+-	0x016c,
+-	0x01a0,
+-	0x0138,
+-	0x0186,
+-	0x0186,
+-	0x01d4,
+-	0x0222,
+-	0x0222,
+-	0x0270,
+-	0x0104,
+-	0x0138,
+-	0x016c,
+-	0x0138,
+-	0x016c,
+-	0x01a0,
+-	0x01d4,
+-	0x01a0,
+-	0x01d4,
+-	0x0208,
+-	0x0208,
+-	0x023c,
+-	0x0186,
+-	0x01d4,
+-	0x0222,
+-	0x01d4,
+-	0x0222,
+-	0x0270,
+-	0x02be,
+-	0x0270,
+-	0x02be,
+-	0x030c,
+-	0x030c,
+-	0x035a,
+-	0x0036,
+-	0x006c,
+-	0x00a2,
+-	0x00d8,
+-	0x0144,
+-	0x01b0,
+-	0x01e6,
+-	0x021c,
+-	0x006c,
+-	0x00d8,
+-	0x0144,
+-	0x01b0,
+-	0x0288,
+-	0x0360,
+-	0x03cc,
+-	0x0438,
+-	0x00a2,
+-	0x0144,
+-	0x01e6,
+-	0x0288,
+-	0x03cc,
+-	0x0510,
+-	0x05b2,
+-	0x0654,
+-	0x00d8,
+-	0x01b0,
+-	0x0288,
+-	0x0360,
+-	0x0510,
+-	0x06c0,
+-	0x0798,
+-	0x0870,
+-	0x0018,
+-	0x0144,
+-	0x01b0,
+-	0x021c,
+-	0x01e6,
+-	0x0288,
+-	0x032a,
+-	0x01b0,
+-	0x021c,
+-	0x021c,
+-	0x0288,
+-	0x02f4,
+-	0x02f4,
+-	0x0360,
+-	0x0288,
+-	0x032a,
+-	0x032a,
+-	0x03cc,
+-	0x046e,
+-	0x046e,
+-	0x0510,
+-	0x021c,
+-	0x0288,
+-	0x02f4,
+-	0x0288,
+-	0x02f4,
+-	0x0360,
+-	0x03cc,
+-	0x0360,
+-	0x03cc,
+-	0x0438,
+-	0x0438,
+-	0x04a4,
+-	0x032a,
+-	0x03cc,
+-	0x046e,
+-	0x03cc,
+-	0x046e,
+-	0x0510,
+-	0x05b2,
+-	0x0510,
+-	0x05b2,
+-	0x0654,
+-	0x0654,
+-	0x06f6,
+-};
+-
+-const u16 dot11lcn_iq_local_tbl_rev0[] = {
+-	0x0200,
+-	0x0300,
+-	0x0400,
+-	0x0600,
+-	0x0800,
+-	0x0b00,
+-	0x1000,
+-	0x1001,
+-	0x1002,
+-	0x1003,
+-	0x1004,
+-	0x1005,
+-	0x1006,
+-	0x1007,
+-	0x1707,
+-	0x2007,
+-	0x2d07,
+-	0x4007,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0200,
+-	0x0300,
+-	0x0400,
+-	0x0600,
+-	0x0800,
+-	0x0b00,
+-	0x1000,
+-	0x1001,
+-	0x1002,
+-	0x1003,
+-	0x1004,
+-	0x1005,
+-	0x1006,
+-	0x1007,
+-	0x1707,
+-	0x2007,
+-	0x2d07,
+-	0x4007,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x4000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u32 dot11lcn_papd_compdelta_tbl_rev0[] = {
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-	0x00080000,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = {
+-	{&dot11lcn_min_sig_sq_tbl_rev0,
+-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0) /
+-	 sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16}
+-	,
+-	{&dot11lcn_noise_scale_tbl_rev0,
+-	 sizeof(dot11lcn_noise_scale_tbl_rev0) /
+-	 sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16}
+-	,
+-	{&dot11lcn_fltr_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32}
+-	,
+-	{&dot11lcn_ps_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32}
+-	,
+-	{&dot11lcn_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32}
+-	,
+-	{&dot11lcn_aux_gain_idx_tbl_rev0,
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0) /
+-	 sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16}
+-	,
+-	{&dot11lcn_sw_ctrl_tbl_rev0,
+-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0) /
+-	 sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16}
+-	,
+-	{&dot11lcn_nf_table_rev0,
+-	 sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16,
+-	 0, 8}
+-	,
+-	{&dot11lcn_gain_val_tbl_rev0,
+-	 sizeof(dot11lcn_gain_val_tbl_rev0) /
+-	 sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8}
+-	,
+-	{&dot11lcn_gain_tbl_rev0,
+-	 sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18,
+-	 0, 32}
+-	,
+-	{&dot11lcn_spur_tbl_rev0,
+-	 sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20,
+-	 0, 8}
+-	,
+-	{&dot11lcn_unsup_mcs_tbl_rev0,
+-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0) /
+-	 sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16}
+-	,
+-	{&dot11lcn_iq_local_tbl_rev0,
+-	 sizeof(dot11lcn_iq_local_tbl_rev0) /
+-	 sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16}
+-	,
+-	{&dot11lcn_papd_compdelta_tbl_rev0,
+-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0) /
+-	 sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32}
+-	,
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = {
+-	&dot11lcn_sw_ctrl_tbl_4313_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = {
+-	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = {
+-	&dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16
+-};
+-
+-const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = {
+-	&dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0,
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) /
+-	    sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16
+-};
+-
+-const u32 dot11lcnphytbl_info_sz_rev0 =
+-    sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]);
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = {
+-	{3, 0, 31, 0, 72,}
+-	,
+-	{3, 0, 31, 0, 70,}
+-	,
+-	{3, 0, 31, 0, 68,}
+-	,
+-	{3, 0, 30, 0, 67,}
+-	,
+-	{3, 0, 29, 0, 68,}
+-	,
+-	{3, 0, 28, 0, 68,}
+-	,
+-	{3, 0, 27, 0, 69,}
+-	,
+-	{3, 0, 26, 0, 70,}
+-	,
+-	{3, 0, 25, 0, 70,}
+-	,
+-	{3, 0, 24, 0, 71,}
+-	,
+-	{3, 0, 23, 0, 72,}
+-	,
+-	{3, 0, 23, 0, 70,}
+-	,
+-	{3, 0, 22, 0, 71,}
+-	,
+-	{3, 0, 21, 0, 72,}
+-	,
+-	{3, 0, 21, 0, 70,}
+-	,
+-	{3, 0, 21, 0, 68,}
+-	,
+-	{3, 0, 21, 0, 66,}
+-	,
+-	{3, 0, 21, 0, 64,}
+-	,
+-	{3, 0, 21, 0, 63,}
+-	,
+-	{3, 0, 20, 0, 64,}
+-	,
+-	{3, 0, 19, 0, 65,}
+-	,
+-	{3, 0, 19, 0, 64,}
+-	,
+-	{3, 0, 18, 0, 65,}
+-	,
+-	{3, 0, 18, 0, 64,}
+-	,
+-	{3, 0, 17, 0, 65,}
+-	,
+-	{3, 0, 17, 0, 64,}
+-	,
+-	{3, 0, 16, 0, 65,}
+-	,
+-	{3, 0, 16, 0, 64,}
+-	,
+-	{3, 0, 16, 0, 62,}
+-	,
+-	{3, 0, 16, 0, 60,}
+-	,
+-	{3, 0, 16, 0, 58,}
+-	,
+-	{3, 0, 15, 0, 61,}
+-	,
+-	{3, 0, 15, 0, 59,}
+-	,
+-	{3, 0, 14, 0, 61,}
+-	,
+-	{3, 0, 14, 0, 60,}
+-	,
+-	{3, 0, 14, 0, 58,}
+-	,
+-	{3, 0, 13, 0, 60,}
+-	,
+-	{3, 0, 13, 0, 59,}
+-	,
+-	{3, 0, 12, 0, 62,}
+-	,
+-	{3, 0, 12, 0, 60,}
+-	,
+-	{3, 0, 12, 0, 58,}
+-	,
+-	{3, 0, 11, 0, 62,}
+-	,
+-	{3, 0, 11, 0, 60,}
+-	,
+-	{3, 0, 11, 0, 59,}
+-	,
+-	{3, 0, 11, 0, 57,}
+-	,
+-	{3, 0, 10, 0, 61,}
+-	,
+-	{3, 0, 10, 0, 59,}
+-	,
+-	{3, 0, 10, 0, 57,}
+-	,
+-	{3, 0, 9, 0, 62,}
+-	,
+-	{3, 0, 9, 0, 60,}
+-	,
+-	{3, 0, 9, 0, 58,}
+-	,
+-	{3, 0, 9, 0, 57,}
+-	,
+-	{3, 0, 8, 0, 62,}
+-	,
+-	{3, 0, 8, 0, 60,}
+-	,
+-	{3, 0, 8, 0, 58,}
+-	,
+-	{3, 0, 8, 0, 57,}
+-	,
+-	{3, 0, 8, 0, 55,}
+-	,
+-	{3, 0, 7, 0, 61,}
+-	,
+-	{3, 0, 7, 0, 60,}
+-	,
+-	{3, 0, 7, 0, 58,}
+-	,
+-	{3, 0, 7, 0, 56,}
+-	,
+-	{3, 0, 7, 0, 55,}
+-	,
+-	{3, 0, 6, 0, 62,}
+-	,
+-	{3, 0, 6, 0, 60,}
+-	,
+-	{3, 0, 6, 0, 58,}
+-	,
+-	{3, 0, 6, 0, 57,}
+-	,
+-	{3, 0, 6, 0, 55,}
+-	,
+-	{3, 0, 6, 0, 54,}
+-	,
+-	{3, 0, 6, 0, 52,}
+-	,
+-	{3, 0, 5, 0, 61,}
+-	,
+-	{3, 0, 5, 0, 59,}
+-	,
+-	{3, 0, 5, 0, 57,}
+-	,
+-	{3, 0, 5, 0, 56,}
+-	,
+-	{3, 0, 5, 0, 54,}
+-	,
+-	{3, 0, 5, 0, 53,}
+-	,
+-	{3, 0, 5, 0, 51,}
+-	,
+-	{3, 0, 4, 0, 62,}
+-	,
+-	{3, 0, 4, 0, 60,}
+-	,
+-	{3, 0, 4, 0, 58,}
+-	,
+-	{3, 0, 4, 0, 57,}
+-	,
+-	{3, 0, 4, 0, 55,}
+-	,
+-	{3, 0, 4, 0, 54,}
+-	,
+-	{3, 0, 4, 0, 52,}
+-	,
+-	{3, 0, 4, 0, 51,}
+-	,
+-	{3, 0, 4, 0, 49,}
+-	,
+-	{3, 0, 4, 0, 48,}
+-	,
+-	{3, 0, 4, 0, 46,}
+-	,
+-	{3, 0, 3, 0, 60,}
+-	,
+-	{3, 0, 3, 0, 58,}
+-	,
+-	{3, 0, 3, 0, 57,}
+-	,
+-	{3, 0, 3, 0, 55,}
+-	,
+-	{3, 0, 3, 0, 54,}
+-	,
+-	{3, 0, 3, 0, 52,}
+-	,
+-	{3, 0, 3, 0, 51,}
+-	,
+-	{3, 0, 3, 0, 49,}
+-	,
+-	{3, 0, 3, 0, 48,}
+-	,
+-	{3, 0, 3, 0, 46,}
+-	,
+-	{3, 0, 3, 0, 45,}
+-	,
+-	{3, 0, 3, 0, 44,}
+-	,
+-	{3, 0, 3, 0, 43,}
+-	,
+-	{3, 0, 3, 0, 41,}
+-	,
+-	{3, 0, 2, 0, 61,}
+-	,
+-	{3, 0, 2, 0, 59,}
+-	,
+-	{3, 0, 2, 0, 57,}
+-	,
+-	{3, 0, 2, 0, 56,}
+-	,
+-	{3, 0, 2, 0, 54,}
+-	,
+-	{3, 0, 2, 0, 53,}
+-	,
+-	{3, 0, 2, 0, 51,}
+-	,
+-	{3, 0, 2, 0, 50,}
+-	,
+-	{3, 0, 2, 0, 48,}
+-	,
+-	{3, 0, 2, 0, 47,}
+-	,
+-	{3, 0, 2, 0, 46,}
+-	,
+-	{3, 0, 2, 0, 44,}
+-	,
+-	{3, 0, 2, 0, 43,}
+-	,
+-	{3, 0, 2, 0, 42,}
+-	,
+-	{3, 0, 2, 0, 41,}
+-	,
+-	{3, 0, 2, 0, 39,}
+-	,
+-	{3, 0, 2, 0, 38,}
+-	,
+-	{3, 0, 2, 0, 37,}
+-	,
+-	{3, 0, 2, 0, 36,}
+-	,
+-	{3, 0, 2, 0, 35,}
+-	,
+-	{3, 0, 2, 0, 34,}
+-	,
+-	{3, 0, 2, 0, 33,}
+-	,
+-	{3, 0, 2, 0, 32,}
+-	,
+-	{3, 0, 1, 0, 63,}
+-	,
+-	{3, 0, 1, 0, 61,}
+-	,
+-	{3, 0, 1, 0, 59,}
+-	,
+-	{3, 0, 1, 0, 57,}
+-	,
+-};
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = {
+-	{7, 0, 31, 0, 72,}
+-	,
+-	{7, 0, 31, 0, 70,}
+-	,
+-	{7, 0, 31, 0, 68,}
+-	,
+-	{7, 0, 30, 0, 67,}
+-	,
+-	{7, 0, 29, 0, 68,}
+-	,
+-	{7, 0, 28, 0, 68,}
+-	,
+-	{7, 0, 27, 0, 69,}
+-	,
+-	{7, 0, 26, 0, 70,}
+-	,
+-	{7, 0, 25, 0, 70,}
+-	,
+-	{7, 0, 24, 0, 71,}
+-	,
+-	{7, 0, 23, 0, 72,}
+-	,
+-	{7, 0, 23, 0, 70,}
+-	,
+-	{7, 0, 22, 0, 71,}
+-	,
+-	{7, 0, 21, 0, 72,}
+-	,
+-	{7, 0, 21, 0, 70,}
+-	,
+-	{7, 0, 21, 0, 68,}
+-	,
+-	{7, 0, 21, 0, 66,}
+-	,
+-	{7, 0, 21, 0, 64,}
+-	,
+-	{7, 0, 21, 0, 63,}
+-	,
+-	{7, 0, 20, 0, 64,}
+-	,
+-	{7, 0, 19, 0, 65,}
+-	,
+-	{7, 0, 19, 0, 64,}
+-	,
+-	{7, 0, 18, 0, 65,}
+-	,
+-	{7, 0, 18, 0, 64,}
+-	,
+-	{7, 0, 17, 0, 65,}
+-	,
+-	{7, 0, 17, 0, 64,}
+-	,
+-	{7, 0, 16, 0, 65,}
+-	,
+-	{7, 0, 16, 0, 64,}
+-	,
+-	{7, 0, 16, 0, 62,}
+-	,
+-	{7, 0, 16, 0, 60,}
+-	,
+-	{7, 0, 16, 0, 58,}
+-	,
+-	{7, 0, 15, 0, 61,}
+-	,
+-	{7, 0, 15, 0, 59,}
+-	,
+-	{7, 0, 14, 0, 61,}
+-	,
+-	{7, 0, 14, 0, 60,}
+-	,
+-	{7, 0, 14, 0, 58,}
+-	,
+-	{7, 0, 13, 0, 60,}
+-	,
+-	{7, 0, 13, 0, 59,}
+-	,
+-	{7, 0, 12, 0, 62,}
+-	,
+-	{7, 0, 12, 0, 60,}
+-	,
+-	{7, 0, 12, 0, 58,}
+-	,
+-	{7, 0, 11, 0, 62,}
+-	,
+-	{7, 0, 11, 0, 60,}
+-	,
+-	{7, 0, 11, 0, 59,}
+-	,
+-	{7, 0, 11, 0, 57,}
+-	,
+-	{7, 0, 10, 0, 61,}
+-	,
+-	{7, 0, 10, 0, 59,}
+-	,
+-	{7, 0, 10, 0, 57,}
+-	,
+-	{7, 0, 9, 0, 62,}
+-	,
+-	{7, 0, 9, 0, 60,}
+-	,
+-	{7, 0, 9, 0, 58,}
+-	,
+-	{7, 0, 9, 0, 57,}
+-	,
+-	{7, 0, 8, 0, 62,}
+-	,
+-	{7, 0, 8, 0, 60,}
+-	,
+-	{7, 0, 8, 0, 58,}
+-	,
+-	{7, 0, 8, 0, 57,}
+-	,
+-	{7, 0, 8, 0, 55,}
+-	,
+-	{7, 0, 7, 0, 61,}
+-	,
+-	{7, 0, 7, 0, 60,}
+-	,
+-	{7, 0, 7, 0, 58,}
+-	,
+-	{7, 0, 7, 0, 56,}
+-	,
+-	{7, 0, 7, 0, 55,}
+-	,
+-	{7, 0, 6, 0, 62,}
+-	,
+-	{7, 0, 6, 0, 60,}
+-	,
+-	{7, 0, 6, 0, 58,}
+-	,
+-	{7, 0, 6, 0, 57,}
+-	,
+-	{7, 0, 6, 0, 55,}
+-	,
+-	{7, 0, 6, 0, 54,}
+-	,
+-	{7, 0, 6, 0, 52,}
+-	,
+-	{7, 0, 5, 0, 61,}
+-	,
+-	{7, 0, 5, 0, 59,}
+-	,
+-	{7, 0, 5, 0, 57,}
+-	,
+-	{7, 0, 5, 0, 56,}
+-	,
+-	{7, 0, 5, 0, 54,}
+-	,
+-	{7, 0, 5, 0, 53,}
+-	,
+-	{7, 0, 5, 0, 51,}
+-	,
+-	{7, 0, 4, 0, 62,}
+-	,
+-	{7, 0, 4, 0, 60,}
+-	,
+-	{7, 0, 4, 0, 58,}
+-	,
+-	{7, 0, 4, 0, 57,}
+-	,
+-	{7, 0, 4, 0, 55,}
+-	,
+-	{7, 0, 4, 0, 54,}
+-	,
+-	{7, 0, 4, 0, 52,}
+-	,
+-	{7, 0, 4, 0, 51,}
+-	,
+-	{7, 0, 4, 0, 49,}
+-	,
+-	{7, 0, 4, 0, 48,}
+-	,
+-	{7, 0, 4, 0, 46,}
+-	,
+-	{7, 0, 3, 0, 60,}
+-	,
+-	{7, 0, 3, 0, 58,}
+-	,
+-	{7, 0, 3, 0, 57,}
+-	,
+-	{7, 0, 3, 0, 55,}
+-	,
+-	{7, 0, 3, 0, 54,}
+-	,
+-	{7, 0, 3, 0, 52,}
+-	,
+-	{7, 0, 3, 0, 51,}
+-	,
+-	{7, 0, 3, 0, 49,}
+-	,
+-	{7, 0, 3, 0, 48,}
+-	,
+-	{7, 0, 3, 0, 46,}
+-	,
+-	{7, 0, 3, 0, 45,}
+-	,
+-	{7, 0, 3, 0, 44,}
+-	,
+-	{7, 0, 3, 0, 43,}
+-	,
+-	{7, 0, 3, 0, 41,}
+-	,
+-	{7, 0, 2, 0, 61,}
+-	,
+-	{7, 0, 2, 0, 59,}
+-	,
+-	{7, 0, 2, 0, 57,}
+-	,
+-	{7, 0, 2, 0, 56,}
+-	,
+-	{7, 0, 2, 0, 54,}
+-	,
+-	{7, 0, 2, 0, 53,}
+-	,
+-	{7, 0, 2, 0, 51,}
+-	,
+-	{7, 0, 2, 0, 50,}
+-	,
+-	{7, 0, 2, 0, 48,}
+-	,
+-	{7, 0, 2, 0, 47,}
+-	,
+-	{7, 0, 2, 0, 46,}
+-	,
+-	{7, 0, 2, 0, 44,}
+-	,
+-	{7, 0, 2, 0, 43,}
+-	,
+-	{7, 0, 2, 0, 42,}
+-	,
+-	{7, 0, 2, 0, 41,}
+-	,
+-	{7, 0, 2, 0, 39,}
+-	,
+-	{7, 0, 2, 0, 38,}
+-	,
+-	{7, 0, 2, 0, 37,}
+-	,
+-	{7, 0, 2, 0, 36,}
+-	,
+-	{7, 0, 2, 0, 35,}
+-	,
+-	{7, 0, 2, 0, 34,}
+-	,
+-	{7, 0, 2, 0, 33,}
+-	,
+-	{7, 0, 2, 0, 32,}
+-	,
+-	{7, 0, 1, 0, 63,}
+-	,
+-	{7, 0, 1, 0, 61,}
+-	,
+-	{7, 0, 1, 0, 59,}
+-	,
+-	{7, 0, 1, 0, 57,}
+-	,
+-};
+-
+-const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = {
+-	{255, 255, 0xf0, 0, 152,}
+-	,
+-	{255, 255, 0xf0, 0, 147,}
+-	,
+-	{255, 255, 0xf0, 0, 143,}
+-	,
+-	{255, 255, 0xf0, 0, 139,}
+-	,
+-	{255, 255, 0xf0, 0, 135,}
+-	,
+-	{255, 255, 0xf0, 0, 131,}
+-	,
+-	{255, 255, 0xf0, 0, 128,}
+-	,
+-	{255, 255, 0xf0, 0, 124,}
+-	,
+-	{255, 255, 0xf0, 0, 121,}
+-	,
+-	{255, 255, 0xf0, 0, 117,}
+-	,
+-	{255, 255, 0xf0, 0, 114,}
+-	,
+-	{255, 255, 0xf0, 0, 111,}
+-	,
+-	{255, 255, 0xf0, 0, 107,}
+-	,
+-	{255, 255, 0xf0, 0, 104,}
+-	,
+-	{255, 255, 0xf0, 0, 101,}
+-	,
+-	{255, 255, 0xf0, 0, 99,}
+-	,
+-	{255, 255, 0xf0, 0, 96,}
+-	,
+-	{255, 255, 0xf0, 0, 93,}
+-	,
+-	{255, 255, 0xf0, 0, 90,}
+-	,
+-	{255, 255, 0xf0, 0, 88,}
+-	,
+-	{255, 255, 0xf0, 0, 85,}
+-	,
+-	{255, 255, 0xf0, 0, 83,}
+-	,
+-	{255, 255, 0xf0, 0, 81,}
+-	,
+-	{255, 255, 0xf0, 0, 78,}
+-	,
+-	{255, 255, 0xf0, 0, 76,}
+-	,
+-	{255, 255, 0xf0, 0, 74,}
+-	,
+-	{255, 255, 0xf0, 0, 72,}
+-	,
+-	{255, 255, 0xf0, 0, 70,}
+-	,
+-	{255, 255, 0xf0, 0, 68,}
+-	,
+-	{255, 255, 0xf0, 0, 66,}
+-	,
+-	{255, 255, 0xf0, 0, 64,}
+-	,
+-	{255, 248, 0xf0, 0, 64,}
+-	,
+-	{255, 241, 0xf0, 0, 64,}
+-	,
+-	{255, 251, 0xe0, 0, 64,}
+-	,
+-	{255, 244, 0xe0, 0, 64,}
+-	,
+-	{255, 254, 0xd0, 0, 64,}
+-	,
+-	{255, 246, 0xd0, 0, 64,}
+-	,
+-	{255, 239, 0xd0, 0, 64,}
+-	,
+-	{255, 249, 0xc0, 0, 64,}
+-	,
+-	{255, 242, 0xc0, 0, 64,}
+-	,
+-	{255, 255, 0xb0, 0, 64,}
+-	,
+-	{255, 248, 0xb0, 0, 64,}
+-	,
+-	{255, 241, 0xb0, 0, 64,}
+-	,
+-	{255, 254, 0xa0, 0, 64,}
+-	,
+-	{255, 246, 0xa0, 0, 64,}
+-	,
+-	{255, 239, 0xa0, 0, 64,}
+-	,
+-	{255, 255, 0x90, 0, 64,}
+-	,
+-	{255, 248, 0x90, 0, 64,}
+-	,
+-	{255, 241, 0x90, 0, 64,}
+-	,
+-	{255, 234, 0x90, 0, 64,}
+-	,
+-	{255, 255, 0x80, 0, 64,}
+-	,
+-	{255, 248, 0x80, 0, 64,}
+-	,
+-	{255, 241, 0x80, 0, 64,}
+-	,
+-	{255, 234, 0x80, 0, 64,}
+-	,
+-	{255, 255, 0x70, 0, 64,}
+-	,
+-	{255, 248, 0x70, 0, 64,}
+-	,
+-	{255, 241, 0x70, 0, 64,}
+-	,
+-	{255, 234, 0x70, 0, 64,}
+-	,
+-	{255, 227, 0x70, 0, 64,}
+-	,
+-	{255, 221, 0x70, 0, 64,}
+-	,
+-	{255, 215, 0x70, 0, 64,}
+-	,
+-	{255, 208, 0x70, 0, 64,}
+-	,
+-	{255, 203, 0x70, 0, 64,}
+-	,
+-	{255, 197, 0x70, 0, 64,}
+-	,
+-	{255, 255, 0x60, 0, 64,}
+-	,
+-	{255, 248, 0x60, 0, 64,}
+-	,
+-	{255, 241, 0x60, 0, 64,}
+-	,
+-	{255, 234, 0x60, 0, 64,}
+-	,
+-	{255, 227, 0x60, 0, 64,}
+-	,
+-	{255, 221, 0x60, 0, 64,}
+-	,
+-	{255, 255, 0x50, 0, 64,}
+-	,
+-	{255, 248, 0x50, 0, 64,}
+-	,
+-	{255, 241, 0x50, 0, 64,}
+-	,
+-	{255, 234, 0x50, 0, 64,}
+-	,
+-	{255, 227, 0x50, 0, 64,}
+-	,
+-	{255, 221, 0x50, 0, 64,}
+-	,
+-	{255, 215, 0x50, 0, 64,}
+-	,
+-	{255, 208, 0x50, 0, 64,}
+-	,
+-	{255, 255, 0x40, 0, 64,}
+-	,
+-	{255, 248, 0x40, 0, 64,}
+-	,
+-	{255, 241, 0x40, 0, 64,}
+-	,
+-	{255, 234, 0x40, 0, 64,}
+-	,
+-	{255, 227, 0x40, 0, 64,}
+-	,
+-	{255, 221, 0x40, 0, 64,}
+-	,
+-	{255, 215, 0x40, 0, 64,}
+-	,
+-	{255, 208, 0x40, 0, 64,}
+-	,
+-	{255, 203, 0x40, 0, 64,}
+-	,
+-	{255, 197, 0x40, 0, 64,}
+-	,
+-	{255, 255, 0x30, 0, 64,}
+-	,
+-	{255, 248, 0x30, 0, 64,}
+-	,
+-	{255, 241, 0x30, 0, 64,}
+-	,
+-	{255, 234, 0x30, 0, 64,}
+-	,
+-	{255, 227, 0x30, 0, 64,}
+-	,
+-	{255, 221, 0x30, 0, 64,}
+-	,
+-	{255, 215, 0x30, 0, 64,}
+-	,
+-	{255, 208, 0x30, 0, 64,}
+-	,
+-	{255, 203, 0x30, 0, 64,}
+-	,
+-	{255, 197, 0x30, 0, 64,}
+-	,
+-	{255, 191, 0x30, 0, 64,}
+-	,
+-	{255, 186, 0x30, 0, 64,}
+-	,
+-	{255, 181, 0x30, 0, 64,}
+-	,
+-	{255, 175, 0x30, 0, 64,}
+-	,
+-	{255, 255, 0x20, 0, 64,}
+-	,
+-	{255, 248, 0x20, 0, 64,}
+-	,
+-	{255, 241, 0x20, 0, 64,}
+-	,
+-	{255, 234, 0x20, 0, 64,}
+-	,
+-	{255, 227, 0x20, 0, 64,}
+-	,
+-	{255, 221, 0x20, 0, 64,}
+-	,
+-	{255, 215, 0x20, 0, 64,}
+-	,
+-	{255, 208, 0x20, 0, 64,}
+-	,
+-	{255, 203, 0x20, 0, 64,}
+-	,
+-	{255, 197, 0x20, 0, 64,}
+-	,
+-	{255, 191, 0x20, 0, 64,}
+-	,
+-	{255, 186, 0x20, 0, 64,}
+-	,
+-	{255, 181, 0x20, 0, 64,}
+-	,
+-	{255, 175, 0x20, 0, 64,}
+-	,
+-	{255, 170, 0x20, 0, 64,}
+-	,
+-	{255, 166, 0x20, 0, 64,}
+-	,
+-	{255, 161, 0x20, 0, 64,}
+-	,
+-	{255, 156, 0x20, 0, 64,}
+-	,
+-	{255, 152, 0x20, 0, 64,}
+-	,
+-	{255, 148, 0x20, 0, 64,}
+-	,
+-	{255, 143, 0x20, 0, 64,}
+-	,
+-	{255, 139, 0x20, 0, 64,}
+-	,
+-	{255, 135, 0x20, 0, 64,}
+-	,
+-	{255, 132, 0x20, 0, 64,}
+-	,
+-	{255, 255, 0x10, 0, 64,}
+-	,
+-	{255, 248, 0x10, 0, 64,}
+-	,
+-};
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
+deleted file mode 100644
+index 5a64a98..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-typedef phytbl_info_t dot11lcnphytbl_info_t;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa;
+-extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[];
+-extern const u32 dot11lcnphytbl_info_sz_rev0;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[];
+-extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
+-
+-extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
+-
+-typedef struct {
+-	unsigned char gm;
+-	unsigned char pga;
+-	unsigned char pad;
+-	unsigned char dac;
+-	unsigned char bb_mult;
+-} lcnphy_tx_gain_tbl_entry;
+-
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
+-
+-extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
+deleted file mode 100644
+index 742df99..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c
++++ /dev/null
+@@ -1,10632 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-
+-#include <sbhnddma.h>
+-#include <wlc_phy_int.h>
+-#include <wlc_phytbl_n.h>
+-
+-const u32 frame_struct_rev0[] = {
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x09804506,
+-	0x00100030,
+-	0x09804507,
+-	0x00100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100004,
+-	0x01000a0d,
+-	0x00100024,
+-	0x0980450e,
+-	0x00100034,
+-	0x0980450f,
+-	0x00100034,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x01800504,
+-	0x00100030,
+-	0x11808505,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x11808504,
+-	0x00100030,
+-	0x3981ca05,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a04,
+-	0x00100000,
+-	0x3981ca05,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100008,
+-	0x01000a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1180850c,
+-	0x00100038,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a0c,
+-	0x00100008,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x02001405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x0200140d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x5b02ca04,
+-	0x00100060,
+-	0x3b01d405,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d404,
+-	0x00100000,
+-	0x3b01d405,
+-	0x00100060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x5002940c,
+-	0x00100010,
+-	0x3201940d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x5b02ca0c,
+-	0x00100070,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d40c,
+-	0x00100010,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x000f4800,
+-	0x62031405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x53028a07,
+-	0x01900060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x000f4808,
+-	0x6203140d,
+-	0x00100048,
+-	0x53028a0e,
+-	0x01900068,
+-	0x53028a0f,
+-	0x01900068,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100004,
+-	0x11008a0d,
+-	0x00100024,
+-	0x1980c50e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x0180c506,
+-	0x00100030,
+-	0x0180c506,
+-	0x00100030,
+-	0x2180c50c,
+-	0x00100030,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x2000ca0c,
+-	0x00100000,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x1980c50e,
+-	0x00100030,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100008,
+-	0x0200140d,
+-	0x00100048,
+-	0x0b004a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x03004a06,
+-	0x01900060,
+-	0x03004a06,
+-	0x01900060,
+-	0x6b030a0c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x6b03140c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x0b004a0e,
+-	0x01900060,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x53028a0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u8 frame_lut_rev0[] = {
+-	0x02,
+-	0x04,
+-	0x14,
+-	0x14,
+-	0x03,
+-	0x05,
+-	0x16,
+-	0x16,
+-	0x0a,
+-	0x0c,
+-	0x1c,
+-	0x1c,
+-	0x0b,
+-	0x0d,
+-	0x1e,
+-	0x1e,
+-	0x06,
+-	0x08,
+-	0x18,
+-	0x18,
+-	0x07,
+-	0x09,
+-	0x1a,
+-	0x1a,
+-	0x0e,
+-	0x10,
+-	0x20,
+-	0x28,
+-	0x0f,
+-	0x11,
+-	0x22,
+-	0x2a,
+-};
+-
+-const u32 tmap_tbl_rev0[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdtrn_tbl_rev0[] = {
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0xfa58fa58,
+-	0xf895043b,
+-	0xff4c09c0,
+-	0xfbc6ffa8,
+-	0xfb84f384,
+-	0x0798f6f9,
+-	0x05760122,
+-	0x058409f6,
+-	0x0b500000,
+-	0x05b7f542,
+-	0x08860432,
+-	0x06ddfee7,
+-	0xfb84f384,
+-	0xf9d90664,
+-	0xf7e8025c,
+-	0x00fff7bd,
+-	0x05a805a8,
+-	0xf7bd00ff,
+-	0x025cf7e8,
+-	0x0664f9d9,
+-	0xf384fb84,
+-	0xfee706dd,
+-	0x04320886,
+-	0xf54205b7,
+-	0x00000b50,
+-	0x09f60584,
+-	0x01220576,
+-	0xf6f90798,
+-	0xf384fb84,
+-	0xffa8fbc6,
+-	0x09c0ff4c,
+-	0x043bf895,
+-	0x02d402d4,
+-	0x07de0270,
+-	0xfc96079c,
+-	0xf90afe94,
+-	0xfe00ff2c,
+-	0x02d4065d,
+-	0x092a0096,
+-	0x0014fbb8,
+-	0xfd2cfd2c,
+-	0x076afb3c,
+-	0x0096f752,
+-	0xf991fd87,
+-	0xfb2c0200,
+-	0xfeb8f960,
+-	0x08e0fc96,
+-	0x049802a8,
+-	0xfd2cfd2c,
+-	0x02a80498,
+-	0xfc9608e0,
+-	0xf960feb8,
+-	0x0200fb2c,
+-	0xfd87f991,
+-	0xf7520096,
+-	0xfb3c076a,
+-	0xfd2cfd2c,
+-	0xfbb80014,
+-	0x0096092a,
+-	0x065d02d4,
+-	0xff2cfe00,
+-	0xfe94f90a,
+-	0x079cfc96,
+-	0x027007de,
+-	0x02d402d4,
+-	0x027007de,
+-	0x079cfc96,
+-	0xfe94f90a,
+-	0xff2cfe00,
+-	0x065d02d4,
+-	0x0096092a,
+-	0xfbb80014,
+-	0xfd2cfd2c,
+-	0xfb3c076a,
+-	0xf7520096,
+-	0xfd87f991,
+-	0x0200fb2c,
+-	0xf960feb8,
+-	0xfc9608e0,
+-	0x02a80498,
+-	0xfd2cfd2c,
+-	0x049802a8,
+-	0x08e0fc96,
+-	0xfeb8f960,
+-	0xfb2c0200,
+-	0xf991fd87,
+-	0x0096f752,
+-	0x076afb3c,
+-	0xfd2cfd2c,
+-	0x0014fbb8,
+-	0x092a0096,
+-	0x02d4065d,
+-	0xfe00ff2c,
+-	0xf90afe94,
+-	0xfc96079c,
+-	0x07de0270,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x061c061c,
+-	0xff30009d,
+-	0xffb21141,
+-	0xfd87fb54,
+-	0xf65dfe59,
+-	0x02eef99e,
+-	0x0166f03c,
+-	0xfff809b6,
+-	0x000008a4,
+-	0x000af42b,
+-	0x00eff577,
+-	0xfa840bf2,
+-	0xfc02ff51,
+-	0x08260f67,
+-	0xfff0036f,
+-	0x0842f9c3,
+-	0x00000000,
+-	0x063df7be,
+-	0xfc910010,
+-	0xf099f7da,
+-	0x00af03fe,
+-	0xf40e057c,
+-	0x0a89ff11,
+-	0x0bd5fff6,
+-	0xf75c0000,
+-	0xf64a0008,
+-	0x0fc4fe9a,
+-	0x0662fd12,
+-	0x01a709a3,
+-	0x04ac0279,
+-	0xeebf004e,
+-	0xff6300d0,
+-	0xf9e4f9e4,
+-	0x00d0ff63,
+-	0x004eeebf,
+-	0x027904ac,
+-	0x09a301a7,
+-	0xfd120662,
+-	0xfe9a0fc4,
+-	0x0008f64a,
+-	0x0000f75c,
+-	0xfff60bd5,
+-	0xff110a89,
+-	0x057cf40e,
+-	0x03fe00af,
+-	0xf7daf099,
+-	0x0010fc91,
+-	0xf7be063d,
+-	0x00000000,
+-	0xf9c30842,
+-	0x036ffff0,
+-	0x0f670826,
+-	0xff51fc02,
+-	0x0bf2fa84,
+-	0xf57700ef,
+-	0xf42b000a,
+-	0x08a40000,
+-	0x09b6fff8,
+-	0xf03c0166,
+-	0xf99e02ee,
+-	0xfe59f65d,
+-	0xfb54fd87,
+-	0x1141ffb2,
+-	0x009dff30,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0xfa58fa58,
+-	0xf8f0fe00,
+-	0x0448073d,
+-	0xfdc9fe46,
+-	0xf9910258,
+-	0x089d0407,
+-	0xfd5cf71a,
+-	0x02affde0,
+-	0x083e0496,
+-	0xff5a0740,
+-	0xff7afd97,
+-	0x00fe01f1,
+-	0x0009082e,
+-	0xfa94ff75,
+-	0xfecdf8ea,
+-	0xffb0f693,
+-	0xfd2cfa58,
+-	0x0433ff16,
+-	0xfba405dd,
+-	0xfa610341,
+-	0x06a606cb,
+-	0x0039fd2d,
+-	0x0677fa97,
+-	0x01fa05e0,
+-	0xf896003e,
+-	0x075a068b,
+-	0x012cfc3e,
+-	0xfa23f98d,
+-	0xfc7cfd43,
+-	0xff90fc0d,
+-	0x01c10982,
+-	0x00c601d6,
+-	0xfd2cfd2c,
+-	0x01d600c6,
+-	0x098201c1,
+-	0xfc0dff90,
+-	0xfd43fc7c,
+-	0xf98dfa23,
+-	0xfc3e012c,
+-	0x068b075a,
+-	0x003ef896,
+-	0x05e001fa,
+-	0xfa970677,
+-	0xfd2d0039,
+-	0x06cb06a6,
+-	0x0341fa61,
+-	0x05ddfba4,
+-	0xff160433,
+-	0xfa58fd2c,
+-	0xf693ffb0,
+-	0xf8eafecd,
+-	0xff75fa94,
+-	0x082e0009,
+-	0x01f100fe,
+-	0xfd97ff7a,
+-	0x0740ff5a,
+-	0x0496083e,
+-	0xfde002af,
+-	0xf71afd5c,
+-	0x0407089d,
+-	0x0258f991,
+-	0xfe46fdc9,
+-	0x073d0448,
+-	0xfe00f8f0,
+-	0xfd2cfd2c,
+-	0xfce00500,
+-	0xfc09fddc,
+-	0xfe680157,
+-	0x04c70571,
+-	0xfc3aff21,
+-	0xfcd70228,
+-	0x056d0277,
+-	0x0200fe00,
+-	0x0022f927,
+-	0xfe3c032b,
+-	0xfc44ff3c,
+-	0x03e9fbdb,
+-	0x04570313,
+-	0x04c9ff5c,
+-	0x000d03b8,
+-	0xfa580000,
+-	0xfbe900d2,
+-	0xf9d0fe0b,
+-	0x0125fdf9,
+-	0x042501bf,
+-	0x0328fa2b,
+-	0xffa902f0,
+-	0xfa250157,
+-	0x0200fe00,
+-	0x03740438,
+-	0xff0405fd,
+-	0x030cfe52,
+-	0x0037fb39,
+-	0xff6904c5,
+-	0x04f8fd23,
+-	0xfd31fc1b,
+-	0xfd2cfd2c,
+-	0xfc1bfd31,
+-	0xfd2304f8,
+-	0x04c5ff69,
+-	0xfb390037,
+-	0xfe52030c,
+-	0x05fdff04,
+-	0x04380374,
+-	0xfe000200,
+-	0x0157fa25,
+-	0x02f0ffa9,
+-	0xfa2b0328,
+-	0x01bf0425,
+-	0xfdf90125,
+-	0xfe0bf9d0,
+-	0x00d2fbe9,
+-	0x0000fa58,
+-	0x03b8000d,
+-	0xff5c04c9,
+-	0x03130457,
+-	0xfbdb03e9,
+-	0xff3cfc44,
+-	0x032bfe3c,
+-	0xf9270022,
+-	0xfe000200,
+-	0x0277056d,
+-	0x0228fcd7,
+-	0xff21fc3a,
+-	0x057104c7,
+-	0x0157fe68,
+-	0xfddcfc09,
+-	0x0500fce0,
+-	0xfd2cfd2c,
+-	0x0500fce0,
+-	0xfddcfc09,
+-	0x0157fe68,
+-	0x057104c7,
+-	0xff21fc3a,
+-	0x0228fcd7,
+-	0x0277056d,
+-	0xfe000200,
+-	0xf9270022,
+-	0x032bfe3c,
+-	0xff3cfc44,
+-	0xfbdb03e9,
+-	0x03130457,
+-	0xff5c04c9,
+-	0x03b8000d,
+-	0x0000fa58,
+-	0x00d2fbe9,
+-	0xfe0bf9d0,
+-	0xfdf90125,
+-	0x01bf0425,
+-	0xfa2b0328,
+-	0x02f0ffa9,
+-	0x0157fa25,
+-	0xfe000200,
+-	0x04380374,
+-	0x05fdff04,
+-	0xfe52030c,
+-	0xfb390037,
+-	0x04c5ff69,
+-	0xfd2304f8,
+-	0xfc1bfd31,
+-	0xfd2cfd2c,
+-	0xfd31fc1b,
+-	0x04f8fd23,
+-	0xff6904c5,
+-	0x0037fb39,
+-	0x030cfe52,
+-	0xff0405fd,
+-	0x03740438,
+-	0x0200fe00,
+-	0xfa250157,
+-	0xffa902f0,
+-	0x0328fa2b,
+-	0x042501bf,
+-	0x0125fdf9,
+-	0xf9d0fe0b,
+-	0xfbe900d2,
+-	0xfa580000,
+-	0x000d03b8,
+-	0x04c9ff5c,
+-	0x04570313,
+-	0x03e9fbdb,
+-	0xfc44ff3c,
+-	0xfe3c032b,
+-	0x0022f927,
+-	0x0200fe00,
+-	0x056d0277,
+-	0xfcd70228,
+-	0xfc3aff21,
+-	0x04c70571,
+-	0xfe680157,
+-	0xfc09fddc,
+-	0xfce00500,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-};
+-
+-const u32 intlv_tbl_rev0[] = {
+-	0x00802070,
+-	0x0671188d,
+-	0x0a60192c,
+-	0x0a300e46,
+-	0x00c1188d,
+-	0x080024d2,
+-	0x00000070,
+-};
+-
+-const u16 pilot_tbl_rev0[] = {
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0xff0a,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xff0a,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xf83f,
+-	0xfa1f,
+-	0xfa97,
+-	0xfab5,
+-	0xf2bd,
+-	0xf0bf,
+-	0xffff,
+-	0xffff,
+-	0xf017,
+-	0xf815,
+-	0xf215,
+-	0xf095,
+-	0xf035,
+-	0xf01d,
+-	0xffff,
+-	0xffff,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xf01f,
+-	0xf817,
+-	0xfa15,
+-	0xf295,
+-	0xf0b5,
+-	0xf03d,
+-	0xffff,
+-	0xffff,
+-	0xf82a,
+-	0xfa0a,
+-	0xfa82,
+-	0xfaa0,
+-	0xf2a8,
+-	0xf0aa,
+-	0xffff,
+-	0xffff,
+-	0xf002,
+-	0xf800,
+-	0xf200,
+-	0xf080,
+-	0xf020,
+-	0xf008,
+-	0xffff,
+-	0xffff,
+-	0xf00a,
+-	0xf802,
+-	0xfa00,
+-	0xf280,
+-	0xf0a0,
+-	0xf028,
+-	0xffff,
+-	0xffff,
+-};
+-
+-const u32 pltlut_tbl_rev0[] = {
+-	0x76540123,
+-	0x62407351,
+-	0x76543201,
+-	0x76540213,
+-	0x76540123,
+-	0x76430521,
+-};
+-
+-const u32 tdi_tbl20_ant0_rev0[] = {
+-	0x00091226,
+-	0x000a1429,
+-	0x000b56ad,
+-	0x000c58b0,
+-	0x000d5ab3,
+-	0x000e9cb6,
+-	0x000f9eba,
+-	0x0000c13d,
+-	0x00020301,
+-	0x00030504,
+-	0x00040708,
+-	0x0005090b,
+-	0x00064b8e,
+-	0x00095291,
+-	0x000a5494,
+-	0x000b9718,
+-	0x000c9927,
+-	0x000d9b2a,
+-	0x000edd2e,
+-	0x000fdf31,
+-	0x000101b4,
+-	0x000243b7,
+-	0x000345bb,
+-	0x000447be,
+-	0x00058982,
+-	0x00068c05,
+-	0x00099309,
+-	0x000a950c,
+-	0x000bd78f,
+-	0x000cd992,
+-	0x000ddb96,
+-	0x000f1d99,
+-	0x00005fa8,
+-	0x0001422c,
+-	0x0002842f,
+-	0x00038632,
+-	0x00048835,
+-	0x0005ca38,
+-	0x0006ccbc,
+-	0x0009d3bf,
+-	0x000b1603,
+-	0x000c1806,
+-	0x000d1a0a,
+-	0x000e1c0d,
+-	0x000f5e10,
+-	0x00008093,
+-	0x00018297,
+-	0x0002c49a,
+-	0x0003c680,
+-	0x0004c880,
+-	0x00060b00,
+-	0x00070d00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl20_ant1_rev0[] = {
+-	0x00014b26,
+-	0x00028d29,
+-	0x000393ad,
+-	0x00049630,
+-	0x0005d833,
+-	0x0006da36,
+-	0x00099c3a,
+-	0x000a9e3d,
+-	0x000bc081,
+-	0x000cc284,
+-	0x000dc488,
+-	0x000f068b,
+-	0x0000488e,
+-	0x00018b91,
+-	0x0002d214,
+-	0x0003d418,
+-	0x0004d6a7,
+-	0x000618aa,
+-	0x00071aae,
+-	0x0009dcb1,
+-	0x000b1eb4,
+-	0x000c0137,
+-	0x000d033b,
+-	0x000e053e,
+-	0x000f4702,
+-	0x00008905,
+-	0x00020c09,
+-	0x0003128c,
+-	0x0004148f,
+-	0x00051712,
+-	0x00065916,
+-	0x00091b19,
+-	0x000a1d28,
+-	0x000b5f2c,
+-	0x000c41af,
+-	0x000d43b2,
+-	0x000e85b5,
+-	0x000f87b8,
+-	0x0000c9bc,
+-	0x00024cbf,
+-	0x00035303,
+-	0x00045506,
+-	0x0005978a,
+-	0x0006998d,
+-	0x00095b90,
+-	0x000a5d93,
+-	0x000b9f97,
+-	0x000c821a,
+-	0x000d8400,
+-	0x000ec600,
+-	0x000fc800,
+-	0x00010a00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant0_rev0[] = {
+-	0x0011a346,
+-	0x00136ccf,
+-	0x0014f5d9,
+-	0x001641e2,
+-	0x0017cb6b,
+-	0x00195475,
+-	0x001b2383,
+-	0x001cad0c,
+-	0x001e7616,
+-	0x0000821f,
+-	0x00020ba8,
+-	0x0003d4b2,
+-	0x00056447,
+-	0x00072dd0,
+-	0x0008b6da,
+-	0x000a02e3,
+-	0x000b8c6c,
+-	0x000d15f6,
+-	0x0011e484,
+-	0x0013ae0d,
+-	0x00153717,
+-	0x00168320,
+-	0x00180ca9,
+-	0x00199633,
+-	0x001b6548,
+-	0x001ceed1,
+-	0x001eb7db,
+-	0x0000c3e4,
+-	0x00024d6d,
+-	0x000416f7,
+-	0x0005a585,
+-	0x00076f0f,
+-	0x0008f818,
+-	0x000a4421,
+-	0x000bcdab,
+-	0x000d9734,
+-	0x00122649,
+-	0x0013efd2,
+-	0x001578dc,
+-	0x0016c4e5,
+-	0x00184e6e,
+-	0x001a17f8,
+-	0x001ba686,
+-	0x001d3010,
+-	0x001ef999,
+-	0x00010522,
+-	0x00028eac,
+-	0x00045835,
+-	0x0005e74a,
+-	0x0007b0d3,
+-	0x00093a5d,
+-	0x000a85e6,
+-	0x000c0f6f,
+-	0x000dd8f9,
+-	0x00126787,
+-	0x00143111,
+-	0x0015ba9a,
+-	0x00170623,
+-	0x00188fad,
+-	0x001a5936,
+-	0x001be84b,
+-	0x001db1d4,
+-	0x001f3b5e,
+-	0x000146e7,
+-	0x00031070,
+-	0x000499fa,
+-	0x00062888,
+-	0x0007f212,
+-	0x00097b9b,
+-	0x000ac7a4,
+-	0x000c50ae,
+-	0x000e1a37,
+-	0x0012a94c,
+-	0x001472d5,
+-	0x0015fc5f,
+-	0x00174868,
+-	0x0018d171,
+-	0x001a9afb,
+-	0x001c2989,
+-	0x001df313,
+-	0x001f7c9c,
+-	0x000188a5,
+-	0x000351af,
+-	0x0004db38,
+-	0x0006aa4d,
+-	0x000833d7,
+-	0x0009bd60,
+-	0x000b0969,
+-	0x000c9273,
+-	0x000e5bfc,
+-	0x00132a8a,
+-	0x0014b414,
+-	0x00163d9d,
+-	0x001789a6,
+-	0x001912b0,
+-	0x001adc39,
+-	0x001c6bce,
+-	0x001e34d8,
+-	0x001fbe61,
+-	0x0001ca6a,
+-	0x00039374,
+-	0x00051cfd,
+-	0x0006ec0b,
+-	0x00087515,
+-	0x0009fe9e,
+-	0x000b4aa7,
+-	0x000cd3b1,
+-	0x000e9d3a,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant1_rev0[] = {
+-	0x001edb36,
+-	0x000129ca,
+-	0x0002b353,
+-	0x00047cdd,
+-	0x0005c8e6,
+-	0x000791ef,
+-	0x00091bf9,
+-	0x000aaa07,
+-	0x000c3391,
+-	0x000dfd1a,
+-	0x00120923,
+-	0x0013d22d,
+-	0x00155c37,
+-	0x0016eacb,
+-	0x00187454,
+-	0x001a3dde,
+-	0x001b89e7,
+-	0x001d12f0,
+-	0x001f1cfa,
+-	0x00016b88,
+-	0x00033492,
+-	0x0004be1b,
+-	0x00060a24,
+-	0x0007d32e,
+-	0x00095d38,
+-	0x000aec4c,
+-	0x000c7555,
+-	0x000e3edf,
+-	0x00124ae8,
+-	0x001413f1,
+-	0x0015a37b,
+-	0x00172c89,
+-	0x0018b593,
+-	0x001a419c,
+-	0x001bcb25,
+-	0x001d942f,
+-	0x001f63b9,
+-	0x0001ad4d,
+-	0x00037657,
+-	0x0004c260,
+-	0x00068be9,
+-	0x000814f3,
+-	0x0009a47c,
+-	0x000b2d8a,
+-	0x000cb694,
+-	0x000e429d,
+-	0x00128c26,
+-	0x001455b0,
+-	0x0015e4ba,
+-	0x00176e4e,
+-	0x0018f758,
+-	0x001a8361,
+-	0x001c0cea,
+-	0x001dd674,
+-	0x001fa57d,
+-	0x0001ee8b,
+-	0x0003b795,
+-	0x0005039e,
+-	0x0006cd27,
+-	0x000856b1,
+-	0x0009e5c6,
+-	0x000b6f4f,
+-	0x000cf859,
+-	0x000e8462,
+-	0x00130deb,
+-	0x00149775,
+-	0x00162603,
+-	0x0017af8c,
+-	0x00193896,
+-	0x001ac49f,
+-	0x001c4e28,
+-	0x001e17b2,
+-	0x0000a6c7,
+-	0x00023050,
+-	0x0003f9da,
+-	0x00054563,
+-	0x00070eec,
+-	0x00089876,
+-	0x000a2704,
+-	0x000bb08d,
+-	0x000d3a17,
+-	0x001185a0,
+-	0x00134f29,
+-	0x0014d8b3,
+-	0x001667c8,
+-	0x0017f151,
+-	0x00197adb,
+-	0x001b0664,
+-	0x001c8fed,
+-	0x001e5977,
+-	0x0000e805,
+-	0x0002718f,
+-	0x00043b18,
+-	0x000586a1,
+-	0x0007502b,
+-	0x0008d9b4,
+-	0x000a68c9,
+-	0x000bf252,
+-	0x000dbbdc,
+-	0x0011c7e5,
+-	0x001390ee,
+-	0x00151a78,
+-	0x0016a906,
+-	0x00183290,
+-	0x0019bc19,
+-	0x001b4822,
+-	0x001cd12c,
+-	0x001e9ab5,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 bdi_tbl_rev0[] = {
+-	0x0070,
+-	0x0126,
+-	0x012c,
+-	0x0246,
+-	0x048d,
+-	0x04d2,
+-};
+-
+-const u32 chanest_tbl_rev0[] = {
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-};
+-
+-const u8 mcs_tbl_rev0[] = {
+-	0x00,
+-	0x08,
+-	0x0a,
+-	0x10,
+-	0x12,
+-	0x19,
+-	0x1a,
+-	0x1c,
+-	0x40,
+-	0x48,
+-	0x4a,
+-	0x50,
+-	0x52,
+-	0x59,
+-	0x5a,
+-	0x5c,
+-	0x80,
+-	0x88,
+-	0x8a,
+-	0x90,
+-	0x92,
+-	0x99,
+-	0x9a,
+-	0x9c,
+-	0xc0,
+-	0xc8,
+-	0xca,
+-	0xd0,
+-	0xd2,
+-	0xd9,
+-	0xda,
+-	0xdc,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x01,
+-	0x02,
+-	0x04,
+-	0x08,
+-	0x09,
+-	0x0a,
+-	0x0c,
+-	0x10,
+-	0x11,
+-	0x12,
+-	0x14,
+-	0x18,
+-	0x19,
+-	0x1a,
+-	0x1c,
+-	0x20,
+-	0x21,
+-	0x22,
+-	0x24,
+-	0x40,
+-	0x41,
+-	0x42,
+-	0x44,
+-	0x48,
+-	0x49,
+-	0x4a,
+-	0x4c,
+-	0x50,
+-	0x51,
+-	0x52,
+-	0x54,
+-	0x58,
+-	0x59,
+-	0x5a,
+-	0x5c,
+-	0x60,
+-	0x61,
+-	0x62,
+-	0x64,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 noise_var_tbl0_rev0[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u32 noise_var_tbl1_rev0[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u8 est_pwr_lut_core0_rev0[] = {
+-	0x50,
+-	0x4f,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3b,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x34,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x30,
+-	0x2f,
+-	0x2e,
+-	0x2d,
+-	0x2c,
+-	0x2b,
+-	0x2a,
+-	0x29,
+-	0x28,
+-	0x27,
+-	0x26,
+-	0x25,
+-	0x24,
+-	0x23,
+-	0x22,
+-	0x21,
+-	0x20,
+-	0x1f,
+-	0x1e,
+-	0x1d,
+-	0x1c,
+-	0x1b,
+-	0x1a,
+-	0x19,
+-	0x18,
+-	0x17,
+-	0x16,
+-	0x15,
+-	0x14,
+-	0x13,
+-	0x12,
+-	0x11,
+-};
+-
+-const u8 est_pwr_lut_core1_rev0[] = {
+-	0x50,
+-	0x4f,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3b,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x34,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x30,
+-	0x2f,
+-	0x2e,
+-	0x2d,
+-	0x2c,
+-	0x2b,
+-	0x2a,
+-	0x29,
+-	0x28,
+-	0x27,
+-	0x26,
+-	0x25,
+-	0x24,
+-	0x23,
+-	0x22,
+-	0x21,
+-	0x20,
+-	0x1f,
+-	0x1e,
+-	0x1d,
+-	0x1c,
+-	0x1b,
+-	0x1a,
+-	0x19,
+-	0x18,
+-	0x17,
+-	0x16,
+-	0x15,
+-	0x14,
+-	0x13,
+-	0x12,
+-	0x11,
+-};
+-
+-const u8 adj_pwr_lut_core0_rev0[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 adj_pwr_lut_core1_rev0[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 gainctrl_lut_core0_rev0[] = {
+-	0x03cc2b44,
+-	0x03cc2b42,
+-	0x03cc2b40,
+-	0x03cc2b3e,
+-	0x03cc2b3d,
+-	0x03cc2b3b,
+-	0x03c82b44,
+-	0x03c82b42,
+-	0x03c82b40,
+-	0x03c82b3e,
+-	0x03c82b3d,
+-	0x03c82b3b,
+-	0x03c82b39,
+-	0x03c82b38,
+-	0x03c82b36,
+-	0x03c82b34,
+-	0x03c42b44,
+-	0x03c42b42,
+-	0x03c42b40,
+-	0x03c42b3e,
+-	0x03c42b3d,
+-	0x03c42b3b,
+-	0x03c42b39,
+-	0x03c42b38,
+-	0x03c42b36,
+-	0x03c42b34,
+-	0x03c42b33,
+-	0x03c42b32,
+-	0x03c42b30,
+-	0x03c42b2f,
+-	0x03c42b2d,
+-	0x03c02b44,
+-	0x03c02b42,
+-	0x03c02b40,
+-	0x03c02b3e,
+-	0x03c02b3d,
+-	0x03c02b3b,
+-	0x03c02b39,
+-	0x03c02b38,
+-	0x03c02b36,
+-	0x03c02b34,
+-	0x03b02b44,
+-	0x03b02b42,
+-	0x03b02b40,
+-	0x03b02b3e,
+-	0x03b02b3d,
+-	0x03b02b3b,
+-	0x03b02b39,
+-	0x03b02b38,
+-	0x03b02b36,
+-	0x03b02b34,
+-	0x03b02b33,
+-	0x03b02b32,
+-	0x03b02b30,
+-	0x03b02b2f,
+-	0x03b02b2d,
+-	0x03a02b44,
+-	0x03a02b42,
+-	0x03a02b40,
+-	0x03a02b3e,
+-	0x03a02b3d,
+-	0x03a02b3b,
+-	0x03a02b39,
+-	0x03a02b38,
+-	0x03a02b36,
+-	0x03a02b34,
+-	0x03902b44,
+-	0x03902b42,
+-	0x03902b40,
+-	0x03902b3e,
+-	0x03902b3d,
+-	0x03902b3b,
+-	0x03902b39,
+-	0x03902b38,
+-	0x03902b36,
+-	0x03902b34,
+-	0x03902b33,
+-	0x03902b32,
+-	0x03902b30,
+-	0x03802b44,
+-	0x03802b42,
+-	0x03802b40,
+-	0x03802b3e,
+-	0x03802b3d,
+-	0x03802b3b,
+-	0x03802b39,
+-	0x03802b38,
+-	0x03802b36,
+-	0x03802b34,
+-	0x03802b33,
+-	0x03802b32,
+-	0x03802b30,
+-	0x03802b2f,
+-	0x03802b2d,
+-	0x03802b2c,
+-	0x03802b2b,
+-	0x03802b2a,
+-	0x03802b29,
+-	0x03802b27,
+-	0x03802b26,
+-	0x03802b25,
+-	0x03802b24,
+-	0x03802b23,
+-	0x03802b22,
+-	0x03802b21,
+-	0x03802b20,
+-	0x03802b1f,
+-	0x03802b1e,
+-	0x03802b1e,
+-	0x03802b1d,
+-	0x03802b1c,
+-	0x03802b1b,
+-	0x03802b1a,
+-	0x03802b1a,
+-	0x03802b19,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x00002b00,
+-};
+-
+-const u32 gainctrl_lut_core1_rev0[] = {
+-	0x03cc2b44,
+-	0x03cc2b42,
+-	0x03cc2b40,
+-	0x03cc2b3e,
+-	0x03cc2b3d,
+-	0x03cc2b3b,
+-	0x03c82b44,
+-	0x03c82b42,
+-	0x03c82b40,
+-	0x03c82b3e,
+-	0x03c82b3d,
+-	0x03c82b3b,
+-	0x03c82b39,
+-	0x03c82b38,
+-	0x03c82b36,
+-	0x03c82b34,
+-	0x03c42b44,
+-	0x03c42b42,
+-	0x03c42b40,
+-	0x03c42b3e,
+-	0x03c42b3d,
+-	0x03c42b3b,
+-	0x03c42b39,
+-	0x03c42b38,
+-	0x03c42b36,
+-	0x03c42b34,
+-	0x03c42b33,
+-	0x03c42b32,
+-	0x03c42b30,
+-	0x03c42b2f,
+-	0x03c42b2d,
+-	0x03c02b44,
+-	0x03c02b42,
+-	0x03c02b40,
+-	0x03c02b3e,
+-	0x03c02b3d,
+-	0x03c02b3b,
+-	0x03c02b39,
+-	0x03c02b38,
+-	0x03c02b36,
+-	0x03c02b34,
+-	0x03b02b44,
+-	0x03b02b42,
+-	0x03b02b40,
+-	0x03b02b3e,
+-	0x03b02b3d,
+-	0x03b02b3b,
+-	0x03b02b39,
+-	0x03b02b38,
+-	0x03b02b36,
+-	0x03b02b34,
+-	0x03b02b33,
+-	0x03b02b32,
+-	0x03b02b30,
+-	0x03b02b2f,
+-	0x03b02b2d,
+-	0x03a02b44,
+-	0x03a02b42,
+-	0x03a02b40,
+-	0x03a02b3e,
+-	0x03a02b3d,
+-	0x03a02b3b,
+-	0x03a02b39,
+-	0x03a02b38,
+-	0x03a02b36,
+-	0x03a02b34,
+-	0x03902b44,
+-	0x03902b42,
+-	0x03902b40,
+-	0x03902b3e,
+-	0x03902b3d,
+-	0x03902b3b,
+-	0x03902b39,
+-	0x03902b38,
+-	0x03902b36,
+-	0x03902b34,
+-	0x03902b33,
+-	0x03902b32,
+-	0x03902b30,
+-	0x03802b44,
+-	0x03802b42,
+-	0x03802b40,
+-	0x03802b3e,
+-	0x03802b3d,
+-	0x03802b3b,
+-	0x03802b39,
+-	0x03802b38,
+-	0x03802b36,
+-	0x03802b34,
+-	0x03802b33,
+-	0x03802b32,
+-	0x03802b30,
+-	0x03802b2f,
+-	0x03802b2d,
+-	0x03802b2c,
+-	0x03802b2b,
+-	0x03802b2a,
+-	0x03802b29,
+-	0x03802b27,
+-	0x03802b26,
+-	0x03802b25,
+-	0x03802b24,
+-	0x03802b23,
+-	0x03802b22,
+-	0x03802b21,
+-	0x03802b20,
+-	0x03802b1f,
+-	0x03802b1e,
+-	0x03802b1e,
+-	0x03802b1d,
+-	0x03802b1c,
+-	0x03802b1b,
+-	0x03802b1a,
+-	0x03802b1a,
+-	0x03802b19,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x03802b18,
+-	0x00002b00,
+-};
+-
+-const u32 iq_lut_core0_rev0[] = {
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-};
+-
+-const u32 iq_lut_core1_rev0[] = {
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-	0x0000007f,
+-};
+-
+-const u16 loft_lut_core0_rev0[] = {
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-};
+-
+-const u16 loft_lut_core1_rev0[] = {
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-	0x0000,
+-	0x0101,
+-	0x0002,
+-	0x0103,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = {
+-	{&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0,
+-	 16}
+-	,
+-	{&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]),
+-	 20, 0, 32}
+-	,
+-	{&gainctrl_lut_core0_rev0,
+-	 sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev0,
+-	 sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]),
+-	 27, 192, 32}
+-	,
+-
+-	{&est_pwr_lut_core0_rev0,
+-	 sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev0,
+-	 sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev0,
+-	 sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev0,
+-	 sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27,
+-	 64, 8}
+-	,
+-	{&iq_lut_core0_rev0,
+-	 sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev0,
+-	 sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev0,
+-	 sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev0,
+-	 sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev0[] = {
+-	{&frame_struct_rev0,
+-	 sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32}
+-	,
+-	{&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]),
+-	 24, 0, 8}
+-	,
+-	{&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12,
+-	 0, 32}
+-	,
+-	{&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]),
+-	 14, 0, 32}
+-	,
+-	{&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]),
+-	 13, 0, 32}
+-	,
+-	{&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]),
+-	 11, 0, 16}
+-	,
+-	{&tdi_tbl20_ant0_rev0,
+-	 sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev0,
+-	 sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev0,
+-	 sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev0,
+-	 sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768,
+-	 32}
+-	,
+-	{&chanest_tbl_rev0,
+-	 sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32}
+-	,
+-	{&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8}
+-	,
+-	{&noise_var_tbl0_rev0,
+-	 sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0,
+-	 32}
+-	,
+-	{&noise_var_tbl1_rev0,
+-	 sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128,
+-	 32}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev0 =
+-    sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]);
+-const u32 mimophytbl_info_sz_rev0_volatile =
+-    sizeof(mimophytbl_info_rev0_volatile) /
+-    sizeof(mimophytbl_info_rev0_volatile[0]);
+-
+-const u16 ant_swctrl_tbl_rev3[] = {
+-	0x0082,
+-	0x0082,
+-	0x0211,
+-	0x0222,
+-	0x0328,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0144,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0188,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0082,
+-	0x0082,
+-	0x0211,
+-	0x0222,
+-	0x0328,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0144,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0188,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_1[] = {
+-	0x0022,
+-	0x0022,
+-	0x0011,
+-	0x0022,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0011,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0022,
+-	0x0011,
+-	0x0022,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0011,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0022,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_2[] = {
+-	0x0088,
+-	0x0088,
+-	0x0044,
+-	0x0088,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0044,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0088,
+-	0x0044,
+-	0x0088,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0044,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0088,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 ant_swctrl_tbl_rev3_3[] = {
+-	0x022,
+-	0x022,
+-	0x011,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x011,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x3cc,
+-	0x022,
+-	0x022,
+-	0x011,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x011,
+-	0x000,
+-	0x000,
+-	0x000,
+-	0x022,
+-	0x000,
+-	0x000,
+-	0x3cc
+-};
+-
+-const u32 frame_struct_rev3[] = {
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x09804506,
+-	0x00100030,
+-	0x09804507,
+-	0x00100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100004,
+-	0x01000a0d,
+-	0x00100024,
+-	0x0980450e,
+-	0x00100034,
+-	0x0980450f,
+-	0x00100034,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x01800504,
+-	0x00100030,
+-	0x11808505,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000a04,
+-	0x00100000,
+-	0x11008a05,
+-	0x00100020,
+-	0x21810506,
+-	0x00100030,
+-	0x21810506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x1980c506,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x11808504,
+-	0x00100030,
+-	0x3981ca05,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a04,
+-	0x00100000,
+-	0x3981ca05,
+-	0x00100030,
+-	0x1980c506,
+-	0x00100030,
+-	0x29814507,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a0c,
+-	0x00100008,
+-	0x01000a0d,
+-	0x00100028,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x1180850c,
+-	0x00100038,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x10008a0c,
+-	0x00100008,
+-	0x3981ca0d,
+-	0x00100038,
+-	0x1980c50e,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x02001405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x13008a06,
+-	0x01900060,
+-	0x13008a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x0200140d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x0b004a06,
+-	0x01900060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x5b02ca04,
+-	0x00100060,
+-	0x3b01d405,
+-	0x00100060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d404,
+-	0x00100000,
+-	0x3b01d405,
+-	0x00100060,
+-	0x0b004a06,
+-	0x01900060,
+-	0x23010a07,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x5002940c,
+-	0x00100010,
+-	0x3201940d,
+-	0x00100050,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x5b02ca0c,
+-	0x00100070,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x5802d40c,
+-	0x00100010,
+-	0x3b01d40d,
+-	0x00100070,
+-	0x0b004a0e,
+-	0x01900070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x000f4800,
+-	0x62031405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x53028a07,
+-	0x01900060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x000f4808,
+-	0x6203140d,
+-	0x00100048,
+-	0x53028a0e,
+-	0x01900068,
+-	0x53028a0f,
+-	0x01900068,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100004,
+-	0x11008a0d,
+-	0x00100024,
+-	0x1980c50e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x2181050e,
+-	0x00100034,
+-	0x0180050c,
+-	0x00100038,
+-	0x1180850d,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000a0c,
+-	0x00100008,
+-	0x11008a0d,
+-	0x00100028,
+-	0x2181050e,
+-	0x00100038,
+-	0x2181050e,
+-	0x00100038,
+-	0x1181850d,
+-	0x00100038,
+-	0x2981450f,
+-	0x01100038,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x08004a04,
+-	0x00100000,
+-	0x01000a05,
+-	0x00100020,
+-	0x0180c506,
+-	0x00100030,
+-	0x0180c506,
+-	0x00100030,
+-	0x2180c50c,
+-	0x00100030,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x2000ca0c,
+-	0x00100000,
+-	0x49820a0d,
+-	0x0016a130,
+-	0x1980c50e,
+-	0x00100030,
+-	0x41824a0d,
+-	0x0016a130,
+-	0x2981450f,
+-	0x01100030,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100008,
+-	0x0200140d,
+-	0x00100048,
+-	0x0b004a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x13008a0e,
+-	0x01900068,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x13008a0e,
+-	0x01900070,
+-	0x13008a0e,
+-	0x01900070,
+-	0x1b014a0d,
+-	0x00100070,
+-	0x23010a0f,
+-	0x01500070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x50029404,
+-	0x00100000,
+-	0x32019405,
+-	0x00100040,
+-	0x03004a06,
+-	0x01900060,
+-	0x03004a06,
+-	0x01900060,
+-	0x6b030a0c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x6b03140c,
+-	0x00100060,
+-	0x4b02140d,
+-	0x0016a160,
+-	0x0b004a0e,
+-	0x01900060,
+-	0x4302540d,
+-	0x0016a160,
+-	0x23010a0f,
+-	0x01500060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x53028a06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x43020a04,
+-	0x00100060,
+-	0x1b00ca05,
+-	0x00100060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x53028a0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x43020a0c,
+-	0x00100070,
+-	0x1b00ca0d,
+-	0x00100070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x40021404,
+-	0x00100000,
+-	0x1a00d405,
+-	0x00100040,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x5b02ca06,
+-	0x01900060,
+-	0x53028a07,
+-	0x0190c060,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x4002140c,
+-	0x00100010,
+-	0x1a00d40d,
+-	0x00100050,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x5b02ca0e,
+-	0x01900070,
+-	0x53028a0f,
+-	0x0190c070,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 pilot_tbl_rev3[] = {
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0xff08,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0x80d5,
+-	0xff0a,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xff82,
+-	0xffa0,
+-	0xff28,
+-	0xff0a,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xffff,
+-	0xf83f,
+-	0xfa1f,
+-	0xfa97,
+-	0xfab5,
+-	0xf2bd,
+-	0xf0bf,
+-	0xffff,
+-	0xffff,
+-	0xf017,
+-	0xf815,
+-	0xf215,
+-	0xf095,
+-	0xf035,
+-	0xf01d,
+-	0xffff,
+-	0xffff,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xff08,
+-	0xff02,
+-	0xff80,
+-	0xff20,
+-	0xf01f,
+-	0xf817,
+-	0xfa15,
+-	0xf295,
+-	0xf0b5,
+-	0xf03d,
+-	0xffff,
+-	0xffff,
+-	0xf82a,
+-	0xfa0a,
+-	0xfa82,
+-	0xfaa0,
+-	0xf2a8,
+-	0xf0aa,
+-	0xffff,
+-	0xffff,
+-	0xf002,
+-	0xf800,
+-	0xf200,
+-	0xf080,
+-	0xf020,
+-	0xf008,
+-	0xffff,
+-	0xffff,
+-	0xf00a,
+-	0xf802,
+-	0xfa00,
+-	0xf280,
+-	0xf0a0,
+-	0xf028,
+-	0xffff,
+-	0xffff,
+-};
+-
+-const u32 tmap_tbl_rev3[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 intlv_tbl_rev3[] = {
+-	0x00802070,
+-	0x0671188d,
+-	0x0a60192c,
+-	0x0a300e46,
+-	0x00c1188d,
+-	0x080024d2,
+-	0x00000070,
+-};
+-
+-const u32 tdtrn_tbl_rev3[] = {
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x061c061c,
+-	0x0050ee68,
+-	0xf592fe36,
+-	0xfe5212f6,
+-	0x00000c38,
+-	0xfe5212f6,
+-	0xf592fe36,
+-	0x0050ee68,
+-	0x061c061c,
+-	0xee680050,
+-	0xfe36f592,
+-	0x12f6fe52,
+-	0x0c380000,
+-	0x12f6fe52,
+-	0xfe36f592,
+-	0xee680050,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0x05e305e3,
+-	0x004def0c,
+-	0xf5f3fe47,
+-	0xfe611246,
+-	0x00000bc7,
+-	0xfe611246,
+-	0xf5f3fe47,
+-	0x004def0c,
+-	0x05e305e3,
+-	0xef0c004d,
+-	0xfe47f5f3,
+-	0x1246fe61,
+-	0x0bc70000,
+-	0x1246fe61,
+-	0xfe47f5f3,
+-	0xef0c004d,
+-	0xfa58fa58,
+-	0xf895043b,
+-	0xff4c09c0,
+-	0xfbc6ffa8,
+-	0xfb84f384,
+-	0x0798f6f9,
+-	0x05760122,
+-	0x058409f6,
+-	0x0b500000,
+-	0x05b7f542,
+-	0x08860432,
+-	0x06ddfee7,
+-	0xfb84f384,
+-	0xf9d90664,
+-	0xf7e8025c,
+-	0x00fff7bd,
+-	0x05a805a8,
+-	0xf7bd00ff,
+-	0x025cf7e8,
+-	0x0664f9d9,
+-	0xf384fb84,
+-	0xfee706dd,
+-	0x04320886,
+-	0xf54205b7,
+-	0x00000b50,
+-	0x09f60584,
+-	0x01220576,
+-	0xf6f90798,
+-	0xf384fb84,
+-	0xffa8fbc6,
+-	0x09c0ff4c,
+-	0x043bf895,
+-	0x02d402d4,
+-	0x07de0270,
+-	0xfc96079c,
+-	0xf90afe94,
+-	0xfe00ff2c,
+-	0x02d4065d,
+-	0x092a0096,
+-	0x0014fbb8,
+-	0xfd2cfd2c,
+-	0x076afb3c,
+-	0x0096f752,
+-	0xf991fd87,
+-	0xfb2c0200,
+-	0xfeb8f960,
+-	0x08e0fc96,
+-	0x049802a8,
+-	0xfd2cfd2c,
+-	0x02a80498,
+-	0xfc9608e0,
+-	0xf960feb8,
+-	0x0200fb2c,
+-	0xfd87f991,
+-	0xf7520096,
+-	0xfb3c076a,
+-	0xfd2cfd2c,
+-	0xfbb80014,
+-	0x0096092a,
+-	0x065d02d4,
+-	0xff2cfe00,
+-	0xfe94f90a,
+-	0x079cfc96,
+-	0x027007de,
+-	0x02d402d4,
+-	0x027007de,
+-	0x079cfc96,
+-	0xfe94f90a,
+-	0xff2cfe00,
+-	0x065d02d4,
+-	0x0096092a,
+-	0xfbb80014,
+-	0xfd2cfd2c,
+-	0xfb3c076a,
+-	0xf7520096,
+-	0xfd87f991,
+-	0x0200fb2c,
+-	0xf960feb8,
+-	0xfc9608e0,
+-	0x02a80498,
+-	0xfd2cfd2c,
+-	0x049802a8,
+-	0x08e0fc96,
+-	0xfeb8f960,
+-	0xfb2c0200,
+-	0xf991fd87,
+-	0x0096f752,
+-	0x076afb3c,
+-	0xfd2cfd2c,
+-	0x0014fbb8,
+-	0x092a0096,
+-	0x02d4065d,
+-	0xfe00ff2c,
+-	0xf90afe94,
+-	0xfc96079c,
+-	0x07de0270,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x062a0000,
+-	0xfefa0759,
+-	0x08b80908,
+-	0xf396fc2d,
+-	0xf9d6045c,
+-	0xfc4ef608,
+-	0xf748f596,
+-	0x07b207bf,
+-	0x062a062a,
+-	0xf84ef841,
+-	0xf748f596,
+-	0x03b209f8,
+-	0xf9d6045c,
+-	0x0c6a03d3,
+-	0x08b80908,
+-	0x0106f8a7,
+-	0x062a0000,
+-	0xfefaf8a7,
+-	0x08b8f6f8,
+-	0xf39603d3,
+-	0xf9d6fba4,
+-	0xfc4e09f8,
+-	0xf7480a6a,
+-	0x07b2f841,
+-	0x062af9d6,
+-	0xf84e07bf,
+-	0xf7480a6a,
+-	0x03b2f608,
+-	0xf9d6fba4,
+-	0x0c6afc2d,
+-	0x08b8f6f8,
+-	0x01060759,
+-	0x061c061c,
+-	0xff30009d,
+-	0xffb21141,
+-	0xfd87fb54,
+-	0xf65dfe59,
+-	0x02eef99e,
+-	0x0166f03c,
+-	0xfff809b6,
+-	0x000008a4,
+-	0x000af42b,
+-	0x00eff577,
+-	0xfa840bf2,
+-	0xfc02ff51,
+-	0x08260f67,
+-	0xfff0036f,
+-	0x0842f9c3,
+-	0x00000000,
+-	0x063df7be,
+-	0xfc910010,
+-	0xf099f7da,
+-	0x00af03fe,
+-	0xf40e057c,
+-	0x0a89ff11,
+-	0x0bd5fff6,
+-	0xf75c0000,
+-	0xf64a0008,
+-	0x0fc4fe9a,
+-	0x0662fd12,
+-	0x01a709a3,
+-	0x04ac0279,
+-	0xeebf004e,
+-	0xff6300d0,
+-	0xf9e4f9e4,
+-	0x00d0ff63,
+-	0x004eeebf,
+-	0x027904ac,
+-	0x09a301a7,
+-	0xfd120662,
+-	0xfe9a0fc4,
+-	0x0008f64a,
+-	0x0000f75c,
+-	0xfff60bd5,
+-	0xff110a89,
+-	0x057cf40e,
+-	0x03fe00af,
+-	0xf7daf099,
+-	0x0010fc91,
+-	0xf7be063d,
+-	0x00000000,
+-	0xf9c30842,
+-	0x036ffff0,
+-	0x0f670826,
+-	0xff51fc02,
+-	0x0bf2fa84,
+-	0xf57700ef,
+-	0xf42b000a,
+-	0x08a40000,
+-	0x09b6fff8,
+-	0xf03c0166,
+-	0xf99e02ee,
+-	0xfe59f65d,
+-	0xfb54fd87,
+-	0x1141ffb2,
+-	0x009dff30,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0x05e30000,
+-	0xff060705,
+-	0x085408a0,
+-	0xf425fc59,
+-	0xfa1d042a,
+-	0xfc78f67a,
+-	0xf7acf60e,
+-	0x075a0766,
+-	0x05e305e3,
+-	0xf8a6f89a,
+-	0xf7acf60e,
+-	0x03880986,
+-	0xfa1d042a,
+-	0x0bdb03a7,
+-	0x085408a0,
+-	0x00faf8fb,
+-	0x05e30000,
+-	0xff06f8fb,
+-	0x0854f760,
+-	0xf42503a7,
+-	0xfa1dfbd6,
+-	0xfc780986,
+-	0xf7ac09f2,
+-	0x075af89a,
+-	0x05e3fa1d,
+-	0xf8a60766,
+-	0xf7ac09f2,
+-	0x0388f67a,
+-	0xfa1dfbd6,
+-	0x0bdbfc59,
+-	0x0854f760,
+-	0x00fa0705,
+-	0xfa58fa58,
+-	0xf8f0fe00,
+-	0x0448073d,
+-	0xfdc9fe46,
+-	0xf9910258,
+-	0x089d0407,
+-	0xfd5cf71a,
+-	0x02affde0,
+-	0x083e0496,
+-	0xff5a0740,
+-	0xff7afd97,
+-	0x00fe01f1,
+-	0x0009082e,
+-	0xfa94ff75,
+-	0xfecdf8ea,
+-	0xffb0f693,
+-	0xfd2cfa58,
+-	0x0433ff16,
+-	0xfba405dd,
+-	0xfa610341,
+-	0x06a606cb,
+-	0x0039fd2d,
+-	0x0677fa97,
+-	0x01fa05e0,
+-	0xf896003e,
+-	0x075a068b,
+-	0x012cfc3e,
+-	0xfa23f98d,
+-	0xfc7cfd43,
+-	0xff90fc0d,
+-	0x01c10982,
+-	0x00c601d6,
+-	0xfd2cfd2c,
+-	0x01d600c6,
+-	0x098201c1,
+-	0xfc0dff90,
+-	0xfd43fc7c,
+-	0xf98dfa23,
+-	0xfc3e012c,
+-	0x068b075a,
+-	0x003ef896,
+-	0x05e001fa,
+-	0xfa970677,
+-	0xfd2d0039,
+-	0x06cb06a6,
+-	0x0341fa61,
+-	0x05ddfba4,
+-	0xff160433,
+-	0xfa58fd2c,
+-	0xf693ffb0,
+-	0xf8eafecd,
+-	0xff75fa94,
+-	0x082e0009,
+-	0x01f100fe,
+-	0xfd97ff7a,
+-	0x0740ff5a,
+-	0x0496083e,
+-	0xfde002af,
+-	0xf71afd5c,
+-	0x0407089d,
+-	0x0258f991,
+-	0xfe46fdc9,
+-	0x073d0448,
+-	0xfe00f8f0,
+-	0xfd2cfd2c,
+-	0xfce00500,
+-	0xfc09fddc,
+-	0xfe680157,
+-	0x04c70571,
+-	0xfc3aff21,
+-	0xfcd70228,
+-	0x056d0277,
+-	0x0200fe00,
+-	0x0022f927,
+-	0xfe3c032b,
+-	0xfc44ff3c,
+-	0x03e9fbdb,
+-	0x04570313,
+-	0x04c9ff5c,
+-	0x000d03b8,
+-	0xfa580000,
+-	0xfbe900d2,
+-	0xf9d0fe0b,
+-	0x0125fdf9,
+-	0x042501bf,
+-	0x0328fa2b,
+-	0xffa902f0,
+-	0xfa250157,
+-	0x0200fe00,
+-	0x03740438,
+-	0xff0405fd,
+-	0x030cfe52,
+-	0x0037fb39,
+-	0xff6904c5,
+-	0x04f8fd23,
+-	0xfd31fc1b,
+-	0xfd2cfd2c,
+-	0xfc1bfd31,
+-	0xfd2304f8,
+-	0x04c5ff69,
+-	0xfb390037,
+-	0xfe52030c,
+-	0x05fdff04,
+-	0x04380374,
+-	0xfe000200,
+-	0x0157fa25,
+-	0x02f0ffa9,
+-	0xfa2b0328,
+-	0x01bf0425,
+-	0xfdf90125,
+-	0xfe0bf9d0,
+-	0x00d2fbe9,
+-	0x0000fa58,
+-	0x03b8000d,
+-	0xff5c04c9,
+-	0x03130457,
+-	0xfbdb03e9,
+-	0xff3cfc44,
+-	0x032bfe3c,
+-	0xf9270022,
+-	0xfe000200,
+-	0x0277056d,
+-	0x0228fcd7,
+-	0xff21fc3a,
+-	0x057104c7,
+-	0x0157fe68,
+-	0xfddcfc09,
+-	0x0500fce0,
+-	0xfd2cfd2c,
+-	0x0500fce0,
+-	0xfddcfc09,
+-	0x0157fe68,
+-	0x057104c7,
+-	0xff21fc3a,
+-	0x0228fcd7,
+-	0x0277056d,
+-	0xfe000200,
+-	0xf9270022,
+-	0x032bfe3c,
+-	0xff3cfc44,
+-	0xfbdb03e9,
+-	0x03130457,
+-	0xff5c04c9,
+-	0x03b8000d,
+-	0x0000fa58,
+-	0x00d2fbe9,
+-	0xfe0bf9d0,
+-	0xfdf90125,
+-	0x01bf0425,
+-	0xfa2b0328,
+-	0x02f0ffa9,
+-	0x0157fa25,
+-	0xfe000200,
+-	0x04380374,
+-	0x05fdff04,
+-	0xfe52030c,
+-	0xfb390037,
+-	0x04c5ff69,
+-	0xfd2304f8,
+-	0xfc1bfd31,
+-	0xfd2cfd2c,
+-	0xfd31fc1b,
+-	0x04f8fd23,
+-	0xff6904c5,
+-	0x0037fb39,
+-	0x030cfe52,
+-	0xff0405fd,
+-	0x03740438,
+-	0x0200fe00,
+-	0xfa250157,
+-	0xffa902f0,
+-	0x0328fa2b,
+-	0x042501bf,
+-	0x0125fdf9,
+-	0xf9d0fe0b,
+-	0xfbe900d2,
+-	0xfa580000,
+-	0x000d03b8,
+-	0x04c9ff5c,
+-	0x04570313,
+-	0x03e9fbdb,
+-	0xfc44ff3c,
+-	0xfe3c032b,
+-	0x0022f927,
+-	0x0200fe00,
+-	0x056d0277,
+-	0xfcd70228,
+-	0xfc3aff21,
+-	0x04c70571,
+-	0xfe680157,
+-	0xfc09fddc,
+-	0xfce00500,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-	0x05a80000,
+-	0xff1006be,
+-	0x0800084a,
+-	0xf49cfc7e,
+-	0xfa580400,
+-	0xfc9cf6da,
+-	0xf800f672,
+-	0x0710071c,
+-	0x05a805a8,
+-	0xf8f0f8e4,
+-	0xf800f672,
+-	0x03640926,
+-	0xfa580400,
+-	0x0b640382,
+-	0x0800084a,
+-	0x00f0f942,
+-	0x05a80000,
+-	0xff10f942,
+-	0x0800f7b6,
+-	0xf49c0382,
+-	0xfa58fc00,
+-	0xfc9c0926,
+-	0xf800098e,
+-	0x0710f8e4,
+-	0x05a8fa58,
+-	0xf8f0071c,
+-	0xf800098e,
+-	0x0364f6da,
+-	0xfa58fc00,
+-	0x0b64fc7e,
+-	0x0800f7b6,
+-	0x00f006be,
+-};
+-
+-const u32 noise_var_tbl_rev3[] = {
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-	0x02110211,
+-	0x0000014d,
+-};
+-
+-const u16 mcs_tbl_rev3[] = {
+-	0x0000,
+-	0x0008,
+-	0x000a,
+-	0x0010,
+-	0x0012,
+-	0x0019,
+-	0x001a,
+-	0x001c,
+-	0x0080,
+-	0x0088,
+-	0x008a,
+-	0x0090,
+-	0x0092,
+-	0x0099,
+-	0x009a,
+-	0x009c,
+-	0x0100,
+-	0x0108,
+-	0x010a,
+-	0x0110,
+-	0x0112,
+-	0x0119,
+-	0x011a,
+-	0x011c,
+-	0x0180,
+-	0x0188,
+-	0x018a,
+-	0x0190,
+-	0x0192,
+-	0x0199,
+-	0x019a,
+-	0x019c,
+-	0x0000,
+-	0x0098,
+-	0x00a0,
+-	0x00a8,
+-	0x009a,
+-	0x00a2,
+-	0x00aa,
+-	0x0120,
+-	0x0128,
+-	0x0128,
+-	0x0130,
+-	0x0138,
+-	0x0138,
+-	0x0140,
+-	0x0122,
+-	0x012a,
+-	0x012a,
+-	0x0132,
+-	0x013a,
+-	0x013a,
+-	0x0142,
+-	0x01a8,
+-	0x01b0,
+-	0x01b8,
+-	0x01b0,
+-	0x01b8,
+-	0x01c0,
+-	0x01c8,
+-	0x01c0,
+-	0x01c8,
+-	0x01d0,
+-	0x01d0,
+-	0x01d8,
+-	0x01aa,
+-	0x01b2,
+-	0x01ba,
+-	0x01b2,
+-	0x01ba,
+-	0x01c2,
+-	0x01ca,
+-	0x01c2,
+-	0x01ca,
+-	0x01d2,
+-	0x01d2,
+-	0x01da,
+-	0x0001,
+-	0x0002,
+-	0x0004,
+-	0x0009,
+-	0x000c,
+-	0x0011,
+-	0x0014,
+-	0x0018,
+-	0x0020,
+-	0x0021,
+-	0x0022,
+-	0x0024,
+-	0x0081,
+-	0x0082,
+-	0x0084,
+-	0x0089,
+-	0x008c,
+-	0x0091,
+-	0x0094,
+-	0x0098,
+-	0x00a0,
+-	0x00a1,
+-	0x00a2,
+-	0x00a4,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-	0x0007,
+-};
+-
+-const u32 tdi_tbl20_ant0_rev3[] = {
+-	0x00091226,
+-	0x000a1429,
+-	0x000b56ad,
+-	0x000c58b0,
+-	0x000d5ab3,
+-	0x000e9cb6,
+-	0x000f9eba,
+-	0x0000c13d,
+-	0x00020301,
+-	0x00030504,
+-	0x00040708,
+-	0x0005090b,
+-	0x00064b8e,
+-	0x00095291,
+-	0x000a5494,
+-	0x000b9718,
+-	0x000c9927,
+-	0x000d9b2a,
+-	0x000edd2e,
+-	0x000fdf31,
+-	0x000101b4,
+-	0x000243b7,
+-	0x000345bb,
+-	0x000447be,
+-	0x00058982,
+-	0x00068c05,
+-	0x00099309,
+-	0x000a950c,
+-	0x000bd78f,
+-	0x000cd992,
+-	0x000ddb96,
+-	0x000f1d99,
+-	0x00005fa8,
+-	0x0001422c,
+-	0x0002842f,
+-	0x00038632,
+-	0x00048835,
+-	0x0005ca38,
+-	0x0006ccbc,
+-	0x0009d3bf,
+-	0x000b1603,
+-	0x000c1806,
+-	0x000d1a0a,
+-	0x000e1c0d,
+-	0x000f5e10,
+-	0x00008093,
+-	0x00018297,
+-	0x0002c49a,
+-	0x0003c680,
+-	0x0004c880,
+-	0x00060b00,
+-	0x00070d00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl20_ant1_rev3[] = {
+-	0x00014b26,
+-	0x00028d29,
+-	0x000393ad,
+-	0x00049630,
+-	0x0005d833,
+-	0x0006da36,
+-	0x00099c3a,
+-	0x000a9e3d,
+-	0x000bc081,
+-	0x000cc284,
+-	0x000dc488,
+-	0x000f068b,
+-	0x0000488e,
+-	0x00018b91,
+-	0x0002d214,
+-	0x0003d418,
+-	0x0004d6a7,
+-	0x000618aa,
+-	0x00071aae,
+-	0x0009dcb1,
+-	0x000b1eb4,
+-	0x000c0137,
+-	0x000d033b,
+-	0x000e053e,
+-	0x000f4702,
+-	0x00008905,
+-	0x00020c09,
+-	0x0003128c,
+-	0x0004148f,
+-	0x00051712,
+-	0x00065916,
+-	0x00091b19,
+-	0x000a1d28,
+-	0x000b5f2c,
+-	0x000c41af,
+-	0x000d43b2,
+-	0x000e85b5,
+-	0x000f87b8,
+-	0x0000c9bc,
+-	0x00024cbf,
+-	0x00035303,
+-	0x00045506,
+-	0x0005978a,
+-	0x0006998d,
+-	0x00095b90,
+-	0x000a5d93,
+-	0x000b9f97,
+-	0x000c821a,
+-	0x000d8400,
+-	0x000ec600,
+-	0x000fc800,
+-	0x00010a00,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant0_rev3[] = {
+-	0x0011a346,
+-	0x00136ccf,
+-	0x0014f5d9,
+-	0x001641e2,
+-	0x0017cb6b,
+-	0x00195475,
+-	0x001b2383,
+-	0x001cad0c,
+-	0x001e7616,
+-	0x0000821f,
+-	0x00020ba8,
+-	0x0003d4b2,
+-	0x00056447,
+-	0x00072dd0,
+-	0x0008b6da,
+-	0x000a02e3,
+-	0x000b8c6c,
+-	0x000d15f6,
+-	0x0011e484,
+-	0x0013ae0d,
+-	0x00153717,
+-	0x00168320,
+-	0x00180ca9,
+-	0x00199633,
+-	0x001b6548,
+-	0x001ceed1,
+-	0x001eb7db,
+-	0x0000c3e4,
+-	0x00024d6d,
+-	0x000416f7,
+-	0x0005a585,
+-	0x00076f0f,
+-	0x0008f818,
+-	0x000a4421,
+-	0x000bcdab,
+-	0x000d9734,
+-	0x00122649,
+-	0x0013efd2,
+-	0x001578dc,
+-	0x0016c4e5,
+-	0x00184e6e,
+-	0x001a17f8,
+-	0x001ba686,
+-	0x001d3010,
+-	0x001ef999,
+-	0x00010522,
+-	0x00028eac,
+-	0x00045835,
+-	0x0005e74a,
+-	0x0007b0d3,
+-	0x00093a5d,
+-	0x000a85e6,
+-	0x000c0f6f,
+-	0x000dd8f9,
+-	0x00126787,
+-	0x00143111,
+-	0x0015ba9a,
+-	0x00170623,
+-	0x00188fad,
+-	0x001a5936,
+-	0x001be84b,
+-	0x001db1d4,
+-	0x001f3b5e,
+-	0x000146e7,
+-	0x00031070,
+-	0x000499fa,
+-	0x00062888,
+-	0x0007f212,
+-	0x00097b9b,
+-	0x000ac7a4,
+-	0x000c50ae,
+-	0x000e1a37,
+-	0x0012a94c,
+-	0x001472d5,
+-	0x0015fc5f,
+-	0x00174868,
+-	0x0018d171,
+-	0x001a9afb,
+-	0x001c2989,
+-	0x001df313,
+-	0x001f7c9c,
+-	0x000188a5,
+-	0x000351af,
+-	0x0004db38,
+-	0x0006aa4d,
+-	0x000833d7,
+-	0x0009bd60,
+-	0x000b0969,
+-	0x000c9273,
+-	0x000e5bfc,
+-	0x00132a8a,
+-	0x0014b414,
+-	0x00163d9d,
+-	0x001789a6,
+-	0x001912b0,
+-	0x001adc39,
+-	0x001c6bce,
+-	0x001e34d8,
+-	0x001fbe61,
+-	0x0001ca6a,
+-	0x00039374,
+-	0x00051cfd,
+-	0x0006ec0b,
+-	0x00087515,
+-	0x0009fe9e,
+-	0x000b4aa7,
+-	0x000cd3b1,
+-	0x000e9d3a,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 tdi_tbl40_ant1_rev3[] = {
+-	0x001edb36,
+-	0x000129ca,
+-	0x0002b353,
+-	0x00047cdd,
+-	0x0005c8e6,
+-	0x000791ef,
+-	0x00091bf9,
+-	0x000aaa07,
+-	0x000c3391,
+-	0x000dfd1a,
+-	0x00120923,
+-	0x0013d22d,
+-	0x00155c37,
+-	0x0016eacb,
+-	0x00187454,
+-	0x001a3dde,
+-	0x001b89e7,
+-	0x001d12f0,
+-	0x001f1cfa,
+-	0x00016b88,
+-	0x00033492,
+-	0x0004be1b,
+-	0x00060a24,
+-	0x0007d32e,
+-	0x00095d38,
+-	0x000aec4c,
+-	0x000c7555,
+-	0x000e3edf,
+-	0x00124ae8,
+-	0x001413f1,
+-	0x0015a37b,
+-	0x00172c89,
+-	0x0018b593,
+-	0x001a419c,
+-	0x001bcb25,
+-	0x001d942f,
+-	0x001f63b9,
+-	0x0001ad4d,
+-	0x00037657,
+-	0x0004c260,
+-	0x00068be9,
+-	0x000814f3,
+-	0x0009a47c,
+-	0x000b2d8a,
+-	0x000cb694,
+-	0x000e429d,
+-	0x00128c26,
+-	0x001455b0,
+-	0x0015e4ba,
+-	0x00176e4e,
+-	0x0018f758,
+-	0x001a8361,
+-	0x001c0cea,
+-	0x001dd674,
+-	0x001fa57d,
+-	0x0001ee8b,
+-	0x0003b795,
+-	0x0005039e,
+-	0x0006cd27,
+-	0x000856b1,
+-	0x0009e5c6,
+-	0x000b6f4f,
+-	0x000cf859,
+-	0x000e8462,
+-	0x00130deb,
+-	0x00149775,
+-	0x00162603,
+-	0x0017af8c,
+-	0x00193896,
+-	0x001ac49f,
+-	0x001c4e28,
+-	0x001e17b2,
+-	0x0000a6c7,
+-	0x00023050,
+-	0x0003f9da,
+-	0x00054563,
+-	0x00070eec,
+-	0x00089876,
+-	0x000a2704,
+-	0x000bb08d,
+-	0x000d3a17,
+-	0x001185a0,
+-	0x00134f29,
+-	0x0014d8b3,
+-	0x001667c8,
+-	0x0017f151,
+-	0x00197adb,
+-	0x001b0664,
+-	0x001c8fed,
+-	0x001e5977,
+-	0x0000e805,
+-	0x0002718f,
+-	0x00043b18,
+-	0x000586a1,
+-	0x0007502b,
+-	0x0008d9b4,
+-	0x000a68c9,
+-	0x000bf252,
+-	0x000dbbdc,
+-	0x0011c7e5,
+-	0x001390ee,
+-	0x00151a78,
+-	0x0016a906,
+-	0x00183290,
+-	0x0019bc19,
+-	0x001b4822,
+-	0x001cd12c,
+-	0x001e9ab5,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 pltlut_tbl_rev3[] = {
+-	0x76540213,
+-	0x62407351,
+-	0x76543210,
+-	0x76540213,
+-	0x76540213,
+-	0x76430521,
+-};
+-
+-const u32 chanest_tbl_rev3[] = {
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x44444444,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-	0x10101010,
+-};
+-
+-const u8 frame_lut_rev3[] = {
+-	0x02,
+-	0x04,
+-	0x14,
+-	0x14,
+-	0x03,
+-	0x05,
+-	0x16,
+-	0x16,
+-	0x0a,
+-	0x0c,
+-	0x1c,
+-	0x1c,
+-	0x0b,
+-	0x0d,
+-	0x1e,
+-	0x1e,
+-	0x06,
+-	0x08,
+-	0x18,
+-	0x18,
+-	0x07,
+-	0x09,
+-	0x1a,
+-	0x1a,
+-	0x0e,
+-	0x10,
+-	0x20,
+-	0x28,
+-	0x0f,
+-	0x11,
+-	0x22,
+-	0x2a,
+-};
+-
+-const u8 est_pwr_lut_core0_rev3[] = {
+-	0x55,
+-	0x54,
+-	0x54,
+-	0x53,
+-	0x52,
+-	0x52,
+-	0x51,
+-	0x51,
+-	0x50,
+-	0x4f,
+-	0x4f,
+-	0x4e,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x2f,
+-	0x2e,
+-	0x2c,
+-	0x2b,
+-	0x29,
+-	0x27,
+-	0x25,
+-	0x23,
+-	0x21,
+-	0x1f,
+-	0x1d,
+-	0x1a,
+-	0x18,
+-	0x15,
+-	0x12,
+-	0x0e,
+-	0x0b,
+-	0x07,
+-	0x02,
+-	0xfd,
+-};
+-
+-const u8 est_pwr_lut_core1_rev3[] = {
+-	0x55,
+-	0x54,
+-	0x54,
+-	0x53,
+-	0x52,
+-	0x52,
+-	0x51,
+-	0x51,
+-	0x50,
+-	0x4f,
+-	0x4f,
+-	0x4e,
+-	0x4e,
+-	0x4d,
+-	0x4c,
+-	0x4c,
+-	0x4b,
+-	0x4a,
+-	0x49,
+-	0x49,
+-	0x48,
+-	0x47,
+-	0x46,
+-	0x46,
+-	0x45,
+-	0x44,
+-	0x43,
+-	0x42,
+-	0x41,
+-	0x40,
+-	0x40,
+-	0x3f,
+-	0x3e,
+-	0x3d,
+-	0x3c,
+-	0x3a,
+-	0x39,
+-	0x38,
+-	0x37,
+-	0x36,
+-	0x35,
+-	0x33,
+-	0x32,
+-	0x31,
+-	0x2f,
+-	0x2e,
+-	0x2c,
+-	0x2b,
+-	0x29,
+-	0x27,
+-	0x25,
+-	0x23,
+-	0x21,
+-	0x1f,
+-	0x1d,
+-	0x1a,
+-	0x18,
+-	0x15,
+-	0x12,
+-	0x0e,
+-	0x0b,
+-	0x07,
+-	0x02,
+-	0xfd,
+-};
+-
+-const u8 adj_pwr_lut_core0_rev3[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u8 adj_pwr_lut_core1_rev3[] = {
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-	0x00,
+-};
+-
+-const u32 gainctrl_lut_core0_rev3[] = {
+-	0x5bf70044,
+-	0x5bf70042,
+-	0x5bf70040,
+-	0x5bf7003e,
+-	0x5bf7003c,
+-	0x5bf7003b,
+-	0x5bf70039,
+-	0x5bf70037,
+-	0x5bf70036,
+-	0x5bf70034,
+-	0x5bf70033,
+-	0x5bf70031,
+-	0x5bf70030,
+-	0x5ba70044,
+-	0x5ba70042,
+-	0x5ba70040,
+-	0x5ba7003e,
+-	0x5ba7003c,
+-	0x5ba7003b,
+-	0x5ba70039,
+-	0x5ba70037,
+-	0x5ba70036,
+-	0x5ba70034,
+-	0x5ba70033,
+-	0x5b770044,
+-	0x5b770042,
+-	0x5b770040,
+-	0x5b77003e,
+-	0x5b77003c,
+-	0x5b77003b,
+-	0x5b770039,
+-	0x5b770037,
+-	0x5b770036,
+-	0x5b770034,
+-	0x5b770033,
+-	0x5b770031,
+-	0x5b770030,
+-	0x5b77002f,
+-	0x5b77002d,
+-	0x5b77002c,
+-	0x5b470044,
+-	0x5b470042,
+-	0x5b470040,
+-	0x5b47003e,
+-	0x5b47003c,
+-	0x5b47003b,
+-	0x5b470039,
+-	0x5b470037,
+-	0x5b470036,
+-	0x5b470034,
+-	0x5b470033,
+-	0x5b470031,
+-	0x5b470030,
+-	0x5b47002f,
+-	0x5b47002d,
+-	0x5b47002c,
+-	0x5b47002b,
+-	0x5b47002a,
+-	0x5b270044,
+-	0x5b270042,
+-	0x5b270040,
+-	0x5b27003e,
+-	0x5b27003c,
+-	0x5b27003b,
+-	0x5b270039,
+-	0x5b270037,
+-	0x5b270036,
+-	0x5b270034,
+-	0x5b270033,
+-	0x5b270031,
+-	0x5b270030,
+-	0x5b27002f,
+-	0x5b170044,
+-	0x5b170042,
+-	0x5b170040,
+-	0x5b17003e,
+-	0x5b17003c,
+-	0x5b17003b,
+-	0x5b170039,
+-	0x5b170037,
+-	0x5b170036,
+-	0x5b170034,
+-	0x5b170033,
+-	0x5b170031,
+-	0x5b170030,
+-	0x5b17002f,
+-	0x5b17002d,
+-	0x5b17002c,
+-	0x5b17002b,
+-	0x5b17002a,
+-	0x5b170028,
+-	0x5b170027,
+-	0x5b170026,
+-	0x5b170025,
+-	0x5b170024,
+-	0x5b170023,
+-	0x5b070044,
+-	0x5b070042,
+-	0x5b070040,
+-	0x5b07003e,
+-	0x5b07003c,
+-	0x5b07003b,
+-	0x5b070039,
+-	0x5b070037,
+-	0x5b070036,
+-	0x5b070034,
+-	0x5b070033,
+-	0x5b070031,
+-	0x5b070030,
+-	0x5b07002f,
+-	0x5b07002d,
+-	0x5b07002c,
+-	0x5b07002b,
+-	0x5b07002a,
+-	0x5b070028,
+-	0x5b070027,
+-	0x5b070026,
+-	0x5b070025,
+-	0x5b070024,
+-	0x5b070023,
+-	0x5b070022,
+-	0x5b070021,
+-	0x5b070020,
+-	0x5b07001f,
+-	0x5b07001e,
+-	0x5b07001d,
+-	0x5b07001d,
+-	0x5b07001c,
+-};
+-
+-const u32 gainctrl_lut_core1_rev3[] = {
+-	0x5bf70044,
+-	0x5bf70042,
+-	0x5bf70040,
+-	0x5bf7003e,
+-	0x5bf7003c,
+-	0x5bf7003b,
+-	0x5bf70039,
+-	0x5bf70037,
+-	0x5bf70036,
+-	0x5bf70034,
+-	0x5bf70033,
+-	0x5bf70031,
+-	0x5bf70030,
+-	0x5ba70044,
+-	0x5ba70042,
+-	0x5ba70040,
+-	0x5ba7003e,
+-	0x5ba7003c,
+-	0x5ba7003b,
+-	0x5ba70039,
+-	0x5ba70037,
+-	0x5ba70036,
+-	0x5ba70034,
+-	0x5ba70033,
+-	0x5b770044,
+-	0x5b770042,
+-	0x5b770040,
+-	0x5b77003e,
+-	0x5b77003c,
+-	0x5b77003b,
+-	0x5b770039,
+-	0x5b770037,
+-	0x5b770036,
+-	0x5b770034,
+-	0x5b770033,
+-	0x5b770031,
+-	0x5b770030,
+-	0x5b77002f,
+-	0x5b77002d,
+-	0x5b77002c,
+-	0x5b470044,
+-	0x5b470042,
+-	0x5b470040,
+-	0x5b47003e,
+-	0x5b47003c,
+-	0x5b47003b,
+-	0x5b470039,
+-	0x5b470037,
+-	0x5b470036,
+-	0x5b470034,
+-	0x5b470033,
+-	0x5b470031,
+-	0x5b470030,
+-	0x5b47002f,
+-	0x5b47002d,
+-	0x5b47002c,
+-	0x5b47002b,
+-	0x5b47002a,
+-	0x5b270044,
+-	0x5b270042,
+-	0x5b270040,
+-	0x5b27003e,
+-	0x5b27003c,
+-	0x5b27003b,
+-	0x5b270039,
+-	0x5b270037,
+-	0x5b270036,
+-	0x5b270034,
+-	0x5b270033,
+-	0x5b270031,
+-	0x5b270030,
+-	0x5b27002f,
+-	0x5b170044,
+-	0x5b170042,
+-	0x5b170040,
+-	0x5b17003e,
+-	0x5b17003c,
+-	0x5b17003b,
+-	0x5b170039,
+-	0x5b170037,
+-	0x5b170036,
+-	0x5b170034,
+-	0x5b170033,
+-	0x5b170031,
+-	0x5b170030,
+-	0x5b17002f,
+-	0x5b17002d,
+-	0x5b17002c,
+-	0x5b17002b,
+-	0x5b17002a,
+-	0x5b170028,
+-	0x5b170027,
+-	0x5b170026,
+-	0x5b170025,
+-	0x5b170024,
+-	0x5b170023,
+-	0x5b070044,
+-	0x5b070042,
+-	0x5b070040,
+-	0x5b07003e,
+-	0x5b07003c,
+-	0x5b07003b,
+-	0x5b070039,
+-	0x5b070037,
+-	0x5b070036,
+-	0x5b070034,
+-	0x5b070033,
+-	0x5b070031,
+-	0x5b070030,
+-	0x5b07002f,
+-	0x5b07002d,
+-	0x5b07002c,
+-	0x5b07002b,
+-	0x5b07002a,
+-	0x5b070028,
+-	0x5b070027,
+-	0x5b070026,
+-	0x5b070025,
+-	0x5b070024,
+-	0x5b070023,
+-	0x5b070022,
+-	0x5b070021,
+-	0x5b070020,
+-	0x5b07001f,
+-	0x5b07001e,
+-	0x5b07001d,
+-	0x5b07001d,
+-	0x5b07001c,
+-};
+-
+-const u32 iq_lut_core0_rev3[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 iq_lut_core1_rev3[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u16 loft_lut_core0_rev3[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 loft_lut_core1_rev3[] = {
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-	0x0000,
+-};
+-
+-const u16 papd_comp_rfpwr_tbl_core0_rev3[] = {
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-};
+-
+-const u16 papd_comp_rfpwr_tbl_core1_rev3[] = {
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x0036,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x002a,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x001e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x000e,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01fc,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01ee,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-	0x01d6,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core0_rev3[] = {
+-	0x00000000,
+-	0x00001fa0,
+-	0x00019f78,
+-	0x0001df7e,
+-	0x03fa9f86,
+-	0x03fd1f90,
+-	0x03fe5f8a,
+-	0x03fb1f94,
+-	0x03fd9fa0,
+-	0x00009f98,
+-	0x03fd1fac,
+-	0x03ff9fa2,
+-	0x03fe9fae,
+-	0x00001fae,
+-	0x03fddfb4,
+-	0x03ff1fb8,
+-	0x03ff9fbc,
+-	0x03ffdfbe,
+-	0x03fe9fc2,
+-	0x03fedfc6,
+-	0x03fedfc6,
+-	0x03ff9fc8,
+-	0x03ff5fc6,
+-	0x03fedfc2,
+-	0x03ff9fc0,
+-	0x03ff5fac,
+-	0x03ff5fac,
+-	0x03ff9fa2,
+-	0x03ff9fa6,
+-	0x03ff9faa,
+-	0x03ff5fb0,
+-	0x03ff5fb4,
+-	0x03ff1fca,
+-	0x03ff5fce,
+-	0x03fcdfdc,
+-	0x03fb4006,
+-	0x00000030,
+-	0x03ff808a,
+-	0x03ff80da,
+-	0x0000016c,
+-	0x03ff8318,
+-	0x03ff063a,
+-	0x03fd8bd6,
+-	0x00014ffe,
+-	0x00034ffe,
+-	0x00034ffe,
+-	0x0003cffe,
+-	0x00040ffe,
+-	0x00040ffe,
+-	0x0003cffe,
+-	0x0003cffe,
+-	0x00020ffe,
+-	0x03fe0ffe,
+-	0x03fdcffe,
+-	0x03f94ffe,
+-	0x03f54ffe,
+-	0x03f44ffe,
+-	0x03ef8ffe,
+-	0x03ee0ffe,
+-	0x03ebcffe,
+-	0x03e8cffe,
+-	0x03e74ffe,
+-	0x03e4cffe,
+-	0x03e38ffe,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core0_rev3[] = {
+-	0x05af005a,
+-	0x0571005e,
+-	0x05040066,
+-	0x04bd006c,
+-	0x047d0072,
+-	0x04430078,
+-	0x03f70081,
+-	0x03cb0087,
+-	0x03870091,
+-	0x035e0098,
+-	0x032e00a1,
+-	0x030300aa,
+-	0x02d800b4,
+-	0x02ae00bf,
+-	0x028900ca,
+-	0x026400d6,
+-	0x024100e3,
+-	0x022200f0,
+-	0x020200ff,
+-	0x01e5010e,
+-	0x01ca011e,
+-	0x01b0012f,
+-	0x01990140,
+-	0x01830153,
+-	0x016c0168,
+-	0x0158017d,
+-	0x01450193,
+-	0x013301ab,
+-	0x012101c5,
+-	0x011101e0,
+-	0x010201fc,
+-	0x00f4021a,
+-	0x00e6011d,
+-	0x00d9012e,
+-	0x00cd0140,
+-	0x00c20153,
+-	0x00b70167,
+-	0x00ac017c,
+-	0x00a30193,
+-	0x009a01ab,
+-	0x009101c4,
+-	0x008901df,
+-	0x008101fb,
+-	0x007a0219,
+-	0x00730239,
+-	0x006d025b,
+-	0x0067027e,
+-	0x006102a4,
+-	0x005c02cc,
+-	0x005602f6,
+-	0x00520323,
+-	0x004d0353,
+-	0x00490385,
+-	0x004503bb,
+-	0x004103f3,
+-	0x003d042f,
+-	0x003a046f,
+-	0x003704b2,
+-	0x003404f9,
+-	0x00310545,
+-	0x002e0596,
+-	0x002b05f5,
+-	0x00290640,
+-	0x002606a4,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core1_rev3[] = {
+-	0x00000000,
+-	0x00001fa0,
+-	0x00019f78,
+-	0x0001df7e,
+-	0x03fa9f86,
+-	0x03fd1f90,
+-	0x03fe5f8a,
+-	0x03fb1f94,
+-	0x03fd9fa0,
+-	0x00009f98,
+-	0x03fd1fac,
+-	0x03ff9fa2,
+-	0x03fe9fae,
+-	0x00001fae,
+-	0x03fddfb4,
+-	0x03ff1fb8,
+-	0x03ff9fbc,
+-	0x03ffdfbe,
+-	0x03fe9fc2,
+-	0x03fedfc6,
+-	0x03fedfc6,
+-	0x03ff9fc8,
+-	0x03ff5fc6,
+-	0x03fedfc2,
+-	0x03ff9fc0,
+-	0x03ff5fac,
+-	0x03ff5fac,
+-	0x03ff9fa2,
+-	0x03ff9fa6,
+-	0x03ff9faa,
+-	0x03ff5fb0,
+-	0x03ff5fb4,
+-	0x03ff1fca,
+-	0x03ff5fce,
+-	0x03fcdfdc,
+-	0x03fb4006,
+-	0x00000030,
+-	0x03ff808a,
+-	0x03ff80da,
+-	0x0000016c,
+-	0x03ff8318,
+-	0x03ff063a,
+-	0x03fd8bd6,
+-	0x00014ffe,
+-	0x00034ffe,
+-	0x00034ffe,
+-	0x0003cffe,
+-	0x00040ffe,
+-	0x00040ffe,
+-	0x0003cffe,
+-	0x0003cffe,
+-	0x00020ffe,
+-	0x03fe0ffe,
+-	0x03fdcffe,
+-	0x03f94ffe,
+-	0x03f54ffe,
+-	0x03f44ffe,
+-	0x03ef8ffe,
+-	0x03ee0ffe,
+-	0x03ebcffe,
+-	0x03e8cffe,
+-	0x03e74ffe,
+-	0x03e4cffe,
+-	0x03e38ffe,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core1_rev3[] = {
+-	0x05af005a,
+-	0x0571005e,
+-	0x05040066,
+-	0x04bd006c,
+-	0x047d0072,
+-	0x04430078,
+-	0x03f70081,
+-	0x03cb0087,
+-	0x03870091,
+-	0x035e0098,
+-	0x032e00a1,
+-	0x030300aa,
+-	0x02d800b4,
+-	0x02ae00bf,
+-	0x028900ca,
+-	0x026400d6,
+-	0x024100e3,
+-	0x022200f0,
+-	0x020200ff,
+-	0x01e5010e,
+-	0x01ca011e,
+-	0x01b0012f,
+-	0x01990140,
+-	0x01830153,
+-	0x016c0168,
+-	0x0158017d,
+-	0x01450193,
+-	0x013301ab,
+-	0x012101c5,
+-	0x011101e0,
+-	0x010201fc,
+-	0x00f4021a,
+-	0x00e6011d,
+-	0x00d9012e,
+-	0x00cd0140,
+-	0x00c20153,
+-	0x00b70167,
+-	0x00ac017c,
+-	0x00a30193,
+-	0x009a01ab,
+-	0x009101c4,
+-	0x008901df,
+-	0x008101fb,
+-	0x007a0219,
+-	0x00730239,
+-	0x006d025b,
+-	0x0067027e,
+-	0x006102a4,
+-	0x005c02cc,
+-	0x005602f6,
+-	0x00520323,
+-	0x004d0353,
+-	0x00490385,
+-	0x004503bb,
+-	0x004103f3,
+-	0x003d042f,
+-	0x003a046f,
+-	0x003704b2,
+-	0x003404f9,
+-	0x00310545,
+-	0x002e0596,
+-	0x002b05f5,
+-	0x00290640,
+-	0x002606a4,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile[] = {
+-	{&ant_swctrl_tbl_rev3,
+-	 sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = {
+-	{&ant_swctrl_tbl_rev3_1,
+-	 sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = {
+-	{&ant_swctrl_tbl_rev3_2,
+-	 sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = {
+-	{&ant_swctrl_tbl_rev3_3,
+-	 sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0,
+-	 16}
+-	,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev3[] = {
+-	{&frame_struct_rev3,
+-	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+-	,
+-	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+-	 11, 0, 16}
+-	,
+-	{&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12,
+-	 0, 32}
+-	,
+-	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+-	 13, 0, 32}
+-	,
+-	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+-	 14, 0, 32}
+-	,
+-	{&noise_var_tbl_rev3,
+-	 sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32}
+-	,
+-	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+-	 16}
+-	,
+-	{&tdi_tbl20_ant0_rev3,
+-	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev3,
+-	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev3,
+-	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev3,
+-	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+-	 32}
+-	,
+-	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+-	 20, 0, 32}
+-	,
+-	{&chanest_tbl_rev3,
+-	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+-	,
+-	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+-	 24, 0, 8}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-};
+-
+-const u32 mimophytbl_info_sz_rev3 =
+-    sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile =
+-    sizeof(mimophytbl_info_rev3_volatile) /
+-    sizeof(mimophytbl_info_rev3_volatile[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile1 =
+-    sizeof(mimophytbl_info_rev3_volatile1) /
+-    sizeof(mimophytbl_info_rev3_volatile1[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile2 =
+-    sizeof(mimophytbl_info_rev3_volatile2) /
+-    sizeof(mimophytbl_info_rev3_volatile2[0]);
+-const u32 mimophytbl_info_sz_rev3_volatile3 =
+-    sizeof(mimophytbl_info_rev3_volatile3) /
+-    sizeof(mimophytbl_info_rev3_volatile3[0]);
+-
+-const u32 tmap_tbl_rev7[] = {
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00011111,
+-	0x11110000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00088aaa,
+-	0xaaaa0000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xaaa8aaa0,
+-	0x8aaa8aaa,
+-	0xaa8a8a8a,
+-	0x000aaa88,
+-	0x8aaa0000,
+-	0xaaa8a888,
+-	0x8aa88a8a,
+-	0x8a88a888,
+-	0x08080a00,
+-	0x0a08080a,
+-	0x080a0a08,
+-	0x00080808,
+-	0x080a0000,
+-	0x080a0808,
+-	0x080a0808,
+-	0x0a0a0a08,
+-	0xa0a0a0a0,
+-	0x80a0a080,
+-	0x8080a0a0,
+-	0x00008080,
+-	0x80a00000,
+-	0x80a080a0,
+-	0xa080a0a0,
+-	0x8080a0a0,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x99999000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x22000000,
+-	0x2222b222,
+-	0x22222222,
+-	0x222222b2,
+-	0xb2222220,
+-	0x22222222,
+-	0x22d22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333b333,
+-	0x33333333,
+-	0x333333b3,
+-	0xb3333330,
+-	0x33333333,
+-	0x33d33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222a222,
+-	0x22222222,
+-	0x222222a2,
+-	0xa2222220,
+-	0x22222222,
+-	0x22c22222,
+-	0x00000222,
+-	0x99b99b00,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb99,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x22222200,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0x22222222,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x11111111,
+-	0xf1111111,
+-	0x11111111,
+-	0x11f11111,
+-	0x01111111,
+-	0xbb9bb900,
+-	0xb9b9bb99,
+-	0xb99bbbbb,
+-	0xbbbb9b9b,
+-	0xb9bb99bb,
+-	0xb99999b9,
+-	0xb9b9b99b,
+-	0x00000bbb,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88aa,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x0a888aaa,
+-	0xaa000000,
+-	0xa8a8aa88,
+-	0xa88aaaaa,
+-	0xaaaa8a8a,
+-	0xa8aa88a0,
+-	0xa88888a8,
+-	0xa8a8a88a,
+-	0x00000aaa,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0xbbbbbb00,
+-	0x999bbbbb,
+-	0x9bb99b9b,
+-	0xb9b9b9bb,
+-	0xb9b99bbb,
+-	0xb9b9b9bb,
+-	0xb9bb9b99,
+-	0x00000999,
+-	0x8a000000,
+-	0xaa88a888,
+-	0xa88888aa,
+-	0xa88a8a88,
+-	0xa88aa88a,
+-	0x88a8aaaa,
+-	0xa8aa8aaa,
+-	0x0888a88a,
+-	0x0b0b0b00,
+-	0x090b0b0b,
+-	0x0b090b0b,
+-	0x0909090b,
+-	0x09090b0b,
+-	0x09090b0b,
+-	0x09090b09,
+-	0x00000909,
+-	0x0a000000,
+-	0x0a080808,
+-	0x080a080a,
+-	0x080a0a08,
+-	0x080a080a,
+-	0x0808080a,
+-	0x0a0a0a08,
+-	0x0808080a,
+-	0xb0b0b000,
+-	0x9090b0b0,
+-	0x90b09090,
+-	0xb0b0b090,
+-	0xb0b090b0,
+-	0x90b0b0b0,
+-	0xb0b09090,
+-	0x00000090,
+-	0x80000000,
+-	0xa080a080,
+-	0xa08080a0,
+-	0xa0808080,
+-	0xa080a080,
+-	0x80a0a0a0,
+-	0xa0a080a0,
+-	0x00a0a0a0,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x11000000,
+-	0x1111f111,
+-	0x11111111,
+-	0x111111f1,
+-	0xf1111110,
+-	0x11111111,
+-	0x11f11111,
+-	0x00000111,
+-	0x33000000,
+-	0x3333f333,
+-	0x33333333,
+-	0x333333f3,
+-	0xf3333330,
+-	0x33333333,
+-	0x33f33333,
+-	0x00000333,
+-	0x22000000,
+-	0x2222f222,
+-	0x22222222,
+-	0x222222f2,
+-	0xf2222220,
+-	0x22222222,
+-	0x22f22222,
+-	0x00000222,
+-	0x99000000,
+-	0x9b9b99bb,
+-	0x9bb99999,
+-	0x9999b9b9,
+-	0x9b99bb90,
+-	0x9bbbbb9b,
+-	0x9b9b9bb9,
+-	0x00000999,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88888000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00aaa888,
+-	0x88a88a00,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x000aa888,
+-	0x88880000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa88,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x08aaa888,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x11000000,
+-	0x1111a111,
+-	0x11111111,
+-	0x111111a1,
+-	0xa1111110,
+-	0x11111111,
+-	0x11c11111,
+-	0x00000111,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x88000000,
+-	0x8a8a88aa,
+-	0x8aa88888,
+-	0x8888a8a8,
+-	0x8a88aa80,
+-	0x8aaaaa8a,
+-	0x8a8a8aa8,
+-	0x00000888,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-	0x00000000,
+-};
+-
+-const u32 noise_var_tbl_rev7[] = {
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-	0x020c020c,
+-	0x0000014d,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core0_rev7[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00016023,
+-	0x00006028,
+-	0x00034036,
+-	0x0003402e,
+-	0x0007203c,
+-	0x0006e037,
+-	0x00070030,
+-	0x0009401f,
+-	0x0009a00f,
+-	0x000b600d,
+-	0x000c8007,
+-	0x000ce007,
+-	0x00101fff,
+-	0x00121ff9,
+-	0x0012e004,
+-	0x0014dffc,
+-	0x0016dff6,
+-	0x0018dfe9,
+-	0x001b3fe5,
+-	0x001c5fd0,
+-	0x001ddfc2,
+-	0x001f1fb6,
+-	0x00207fa4,
+-	0x00219f8f,
+-	0x0022ff7d,
+-	0x00247f6c,
+-	0x0024df5b,
+-	0x00267f4b,
+-	0x0027df3b,
+-	0x0029bf3b,
+-	0x002b5f2f,
+-	0x002d3f2e,
+-	0x002f5f2a,
+-	0x002fff15,
+-	0x00315f0b,
+-	0x0032defa,
+-	0x0033beeb,
+-	0x0034fed9,
+-	0x00353ec5,
+-	0x00361eb0,
+-	0x00363e9b,
+-	0x0036be87,
+-	0x0036be70,
+-	0x0038fe67,
+-	0x0044beb2,
+-	0x00513ef3,
+-	0x00595f11,
+-	0x00669f3d,
+-	0x0078dfdf,
+-	0x00a143aa,
+-	0x01642fff,
+-	0x0162afff,
+-	0x01620fff,
+-	0x0160cfff,
+-	0x015f0fff,
+-	0x015dafff,
+-	0x015bcfff,
+-	0x015bcfff,
+-	0x015b4fff,
+-	0x015acfff,
+-	0x01590fff,
+-	0x0156cfff,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core0_rev7[] = {
+-	0x0b5e002d,
+-	0x0ae2002f,
+-	0x0a3b0032,
+-	0x09a70035,
+-	0x09220038,
+-	0x08ab003b,
+-	0x081f003f,
+-	0x07a20043,
+-	0x07340047,
+-	0x06d2004b,
+-	0x067a004f,
+-	0x06170054,
+-	0x05bf0059,
+-	0x0571005e,
+-	0x051e0064,
+-	0x04d3006a,
+-	0x04910070,
+-	0x044c0077,
+-	0x040f007e,
+-	0x03d90085,
+-	0x03a1008d,
+-	0x036f0095,
+-	0x033d009e,
+-	0x030b00a8,
+-	0x02e000b2,
+-	0x02b900bc,
+-	0x029200c7,
+-	0x026d00d3,
+-	0x024900e0,
+-	0x022900ed,
+-	0x020a00fb,
+-	0x01ec010a,
+-	0x01d20119,
+-	0x01b7012a,
+-	0x019e013c,
+-	0x0188014e,
+-	0x01720162,
+-	0x015d0177,
+-	0x0149018e,
+-	0x013701a5,
+-	0x012601be,
+-	0x011501d8,
+-	0x010601f4,
+-	0x00f70212,
+-	0x00e90231,
+-	0x00dc0253,
+-	0x00d00276,
+-	0x00c4029b,
+-	0x00b902c3,
+-	0x00af02ed,
+-	0x00a50319,
+-	0x009c0348,
+-	0x0093037a,
+-	0x008b03af,
+-	0x008303e6,
+-	0x007c0422,
+-	0x00750460,
+-	0x006e04a3,
+-	0x006804e9,
+-	0x00620533,
+-	0x005d0582,
+-	0x005805d6,
+-	0x0053062e,
+-	0x004e068c,
+-};
+-
+-const u32 papd_comp_epsilon_tbl_core1_rev7[] = {
+-	0x00000000,
+-	0x00000000,
+-	0x00016023,
+-	0x00006028,
+-	0x00034036,
+-	0x0003402e,
+-	0x0007203c,
+-	0x0006e037,
+-	0x00070030,
+-	0x0009401f,
+-	0x0009a00f,
+-	0x000b600d,
+-	0x000c8007,
+-	0x000ce007,
+-	0x00101fff,
+-	0x00121ff9,
+-	0x0012e004,
+-	0x0014dffc,
+-	0x0016dff6,
+-	0x0018dfe9,
+-	0x001b3fe5,
+-	0x001c5fd0,
+-	0x001ddfc2,
+-	0x001f1fb6,
+-	0x00207fa4,
+-	0x00219f8f,
+-	0x0022ff7d,
+-	0x00247f6c,
+-	0x0024df5b,
+-	0x00267f4b,
+-	0x0027df3b,
+-	0x0029bf3b,
+-	0x002b5f2f,
+-	0x002d3f2e,
+-	0x002f5f2a,
+-	0x002fff15,
+-	0x00315f0b,
+-	0x0032defa,
+-	0x0033beeb,
+-	0x0034fed9,
+-	0x00353ec5,
+-	0x00361eb0,
+-	0x00363e9b,
+-	0x0036be87,
+-	0x0036be70,
+-	0x0038fe67,
+-	0x0044beb2,
+-	0x00513ef3,
+-	0x00595f11,
+-	0x00669f3d,
+-	0x0078dfdf,
+-	0x00a143aa,
+-	0x01642fff,
+-	0x0162afff,
+-	0x01620fff,
+-	0x0160cfff,
+-	0x015f0fff,
+-	0x015dafff,
+-	0x015bcfff,
+-	0x015bcfff,
+-	0x015b4fff,
+-	0x015acfff,
+-	0x01590fff,
+-	0x0156cfff,
+-};
+-
+-const u32 papd_cal_scalars_tbl_core1_rev7[] = {
+-	0x0b5e002d,
+-	0x0ae2002f,
+-	0x0a3b0032,
+-	0x09a70035,
+-	0x09220038,
+-	0x08ab003b,
+-	0x081f003f,
+-	0x07a20043,
+-	0x07340047,
+-	0x06d2004b,
+-	0x067a004f,
+-	0x06170054,
+-	0x05bf0059,
+-	0x0571005e,
+-	0x051e0064,
+-	0x04d3006a,
+-	0x04910070,
+-	0x044c0077,
+-	0x040f007e,
+-	0x03d90085,
+-	0x03a1008d,
+-	0x036f0095,
+-	0x033d009e,
+-	0x030b00a8,
+-	0x02e000b2,
+-	0x02b900bc,
+-	0x029200c7,
+-	0x026d00d3,
+-	0x024900e0,
+-	0x022900ed,
+-	0x020a00fb,
+-	0x01ec010a,
+-	0x01d20119,
+-	0x01b7012a,
+-	0x019e013c,
+-	0x0188014e,
+-	0x01720162,
+-	0x015d0177,
+-	0x0149018e,
+-	0x013701a5,
+-	0x012601be,
+-	0x011501d8,
+-	0x010601f4,
+-	0x00f70212,
+-	0x00e90231,
+-	0x00dc0253,
+-	0x00d00276,
+-	0x00c4029b,
+-	0x00b902c3,
+-	0x00af02ed,
+-	0x00a50319,
+-	0x009c0348,
+-	0x0093037a,
+-	0x008b03af,
+-	0x008303e6,
+-	0x007c0422,
+-	0x00750460,
+-	0x006e04a3,
+-	0x006804e9,
+-	0x00620533,
+-	0x005d0582,
+-	0x005805d6,
+-	0x0053062e,
+-	0x004e068c,
+-};
+-
+-const mimophytbl_info_t mimophytbl_info_rev7[] = {
+-	{&frame_struct_rev3,
+-	 sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32}
+-	,
+-	{&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]),
+-	 11, 0, 16}
+-	,
+-	{&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12,
+-	 0, 32}
+-	,
+-	{&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]),
+-	 13, 0, 32}
+-	,
+-	{&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]),
+-	 14, 0, 32}
+-	,
+-	{&noise_var_tbl_rev7,
+-	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+-	,
+-	{&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0,
+-	 16}
+-	,
+-	{&tdi_tbl20_ant0_rev3,
+-	 sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128,
+-	 32}
+-	,
+-	{&tdi_tbl20_ant1_rev3,
+-	 sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant0_rev3,
+-	 sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640,
+-	 32}
+-	,
+-	{&tdi_tbl40_ant1_rev3,
+-	 sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768,
+-	 32}
+-	,
+-	{&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]),
+-	 20, 0, 32}
+-	,
+-	{&chanest_tbl_rev3,
+-	 sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32}
+-	,
+-	{&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]),
+-	 24, 0, 8}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-	,
+-	{&papd_comp_rfpwr_tbl_core0_rev3,
+-	 sizeof(papd_comp_rfpwr_tbl_core0_rev3) /
+-	 sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16}
+-	,
+-	{&papd_comp_rfpwr_tbl_core1_rev3,
+-	 sizeof(papd_comp_rfpwr_tbl_core1_rev3) /
+-	 sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16}
+-	,
+-	{&papd_comp_epsilon_tbl_core0_rev7,
+-	 sizeof(papd_comp_epsilon_tbl_core0_rev7) /
+-	 sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32}
+-	,
+-	{&papd_cal_scalars_tbl_core0_rev7,
+-	 sizeof(papd_cal_scalars_tbl_core0_rev7) /
+-	 sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32}
+-	,
+-	{&papd_comp_epsilon_tbl_core1_rev7,
+-	 sizeof(papd_comp_epsilon_tbl_core1_rev7) /
+-	 sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32}
+-	,
+-	{&papd_cal_scalars_tbl_core1_rev7,
+-	 sizeof(papd_cal_scalars_tbl_core1_rev7) /
+-	 sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev7 =
+-    sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]);
+-
+-const mimophytbl_info_t mimophytbl_info_rev16[] = {
+-	{&noise_var_tbl_rev7,
+-	 sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32}
+-	,
+-	{&est_pwr_lut_core0_rev3,
+-	 sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26,
+-	 0, 8}
+-	,
+-	{&est_pwr_lut_core1_rev3,
+-	 sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27,
+-	 0, 8}
+-	,
+-	{&adj_pwr_lut_core0_rev3,
+-	 sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26,
+-	 64, 8}
+-	,
+-	{&adj_pwr_lut_core1_rev3,
+-	 sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27,
+-	 64, 8}
+-	,
+-	{&gainctrl_lut_core0_rev3,
+-	 sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]),
+-	 26, 192, 32}
+-	,
+-	{&gainctrl_lut_core1_rev3,
+-	 sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]),
+-	 27, 192, 32}
+-	,
+-	{&iq_lut_core0_rev3,
+-	 sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32}
+-	,
+-	{&iq_lut_core1_rev3,
+-	 sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32}
+-	,
+-	{&loft_lut_core0_rev3,
+-	 sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448,
+-	 16}
+-	,
+-	{&loft_lut_core1_rev3,
+-	 sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448,
+-	 16}
+-	,
+-};
+-
+-const u32 mimophytbl_info_sz_rev16 =
+-    sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]);
+diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
+deleted file mode 100644
+index 396122f..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h
++++ /dev/null
+@@ -1,39 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define ANT_SWCTRL_TBL_REV3_IDX (0)
+-
+-typedef phytbl_info_t mimophytbl_info_t;
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev0[],
+-    mimophytbl_info_rev0_volatile[];
+-extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile;
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev3[],
+-    mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[],
+-    mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[];
+-extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile,
+-    mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2,
+-    mimophytbl_info_sz_rev3_volatile3;
+-
+-extern const u32 noise_var_tbl_rev3[];
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev7[];
+-extern const u32 mimophytbl_info_sz_rev7;
+-extern const u32 noise_var_tbl_rev7[];
+-
+-extern const mimophytbl_info_t mimophytbl_info_rev16[];
+-extern const u32 mimophytbl_info_sz_rev16;
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h
+deleted file mode 100644
+index 5582de3..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h
++++ /dev/null
+@@ -1,92 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_dbg_h_
+-#define _wl_dbg_h_
+-
+-#include <linux/device.h>			/* dev_err() */
+-
+-/* wl_msg_level is a bit vector with defs in wlioctl.h */
+-extern u32 wl_msg_level;
+-
+-#define BCMMSG(dev, fmt, args...)		\
+-do {						\
+-	if (wl_msg_level & WL_TRACE_VAL)	\
+-		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
+-} while (0)
+-
+-#ifdef BCMDBG
+-
+-
+-/* Extra message control for AMPDU debugging */
+-#define   WL_AMPDU_UPDN_VAL	0x00000001	/* Config up/down related  */
+-#define   WL_AMPDU_ERR_VAL	0x00000002	/* Calls to beaocn update  */
+-#define   WL_AMPDU_TX_VAL	0x00000004	/* Transmit data path */
+-#define   WL_AMPDU_RX_VAL	0x00000008	/* Receive data path  */
+-#define   WL_AMPDU_CTL_VAL	0x00000010	/* TSF-related items  */
+-#define   WL_AMPDU_HW_VAL       0x00000020	/* AMPDU_HW */
+-#define   WL_AMPDU_HWTXS_VAL    0x00000040	/* AMPDU_HWTXS */
+-#define   WL_AMPDU_HWDBG_VAL    0x00000080	/* AMPDU_DBG */
+-
+-extern u32 wl_ampdu_dbg;
+-
+-#define WL_AMPDU_PRINT(level, fmt, args...)	\
+-do {						\
+-	if (wl_ampdu_dbg & level) {		\
+-		WL_AMPDU(fmt, ##args);		\
+-	}					\
+-} while (0)
+-
+-#define WL_AMPDU_UPDN(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args)
+-#define WL_AMPDU_RX(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args)
+-#define WL_AMPDU_ERR(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args)
+-#define WL_AMPDU_TX(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args)
+-#define WL_AMPDU_CTL(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args)
+-#define WL_AMPDU_HW(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args)
+-#define WL_AMPDU_HWTXS(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args)
+-#define WL_AMPDU_HWDBG(fmt, args...)			\
+-	WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args)
+-#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL)
+-#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL)
+-#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL)
+-
+-#else				/* BCMDBG */
+-
+-
+-#define WL_AMPDU_UPDN(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_RX(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_ERR(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_TX(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_CTL(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HW(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HWTXS(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_HWDBG(fmt, args...)	no_printk(fmt, ##args)
+-#define WL_AMPDU_ERR_ON()       0
+-#define WL_AMPDU_HW_ON()        0
+-#define WL_AMPDU_HWTXS_ON()     0
+-
+-#endif				/* BCMDBG */
+-
+-#define WL_ERROR_ON()		(wl_msg_level & WL_ERROR_VAL)
+-
+-#endif				/* _wl_dbg_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h
+deleted file mode 100644
+index 0fe0b24..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_export.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_export_h_
+-#define _wl_export_h_
+-
+-/* misc callbacks */
+-struct wl_info;
+-struct wl_if;
+-struct wlc_if;
+-extern void wl_init(struct wl_info *wl);
+-extern uint wl_reset(struct wl_info *wl);
+-extern void wl_intrson(struct wl_info *wl);
+-extern u32 wl_intrsoff(struct wl_info *wl);
+-extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask);
+-extern int wl_up(struct wl_info *wl);
+-extern void wl_down(struct wl_info *wl);
+-extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+-			     int prio);
+-extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth);
+-extern bool wl_rfkill_set_hw_state(struct wl_info *wl);
+-
+-/* timer functions */
+-struct wl_timer;
+-extern struct wl_timer *wl_init_timer(struct wl_info *wl,
+-				      void (*fn) (void *arg), void *arg,
+-				      const char *name);
+-extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer);
+-extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
+-			 int periodic);
+-extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
+-extern void wl_msleep(struct wl_info *wl, uint ms);
+-
+-#endif				/* _wl_export_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
+deleted file mode 100644
+index aa0d127..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
++++ /dev/null
+@@ -1,1942 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define __UNDEF_NO_VERSION__
+-
+-#include <linux/kernel.h>
+-#include <linux/etherdevice.h>
+-#include <linux/types.h>
+-#include <linux/pci_ids.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/sched.h>
+-#include <linux/firmware.h>
+-#include <net/mac80211.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmwifi.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <pcicfg.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "phy/wlc_phy_int.h"
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "phy/phy_version.h"
+-#include "wlc_key.h"
+-#include "wlc_channel.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wl_dbg.h"
+-#include "wl_export.h"
+-#include "wl_ucode.h"
+-#include "wl_mac80211.h"
+-
+-#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
+-
+-static void wl_timer(unsigned long data);
+-static void _wl_timer(struct wl_timer *t);
+-
+-
+-static int ieee_hw_init(struct ieee80211_hw *hw);
+-static int ieee_hw_rate_init(struct ieee80211_hw *hw);
+-
+-static int wl_linux_watchdog(void *ctx);
+-
+-/* Flags we support */
+-#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
+-	FIF_ALLMULTI | \
+-	FIF_FCSFAIL | \
+-	FIF_PLCPFAIL | \
+-	FIF_CONTROL | \
+-	FIF_OTHER_BSS | \
+-	FIF_BCN_PRBRESP_PROMISC)
+-
+-static int wl_found;
+-
+-#define WL_DEV_IF(dev)		((struct wl_if *)netdev_priv(dev))
+-#define	WL_INFO(dev)		((struct wl_info *)(WL_DEV_IF(dev)->wl))
+-static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev);
+-static void wl_release_fw(struct wl_info *wl);
+-
+-/* local prototypes */
+-static void wl_dpc(unsigned long data);
+-static irqreturn_t wl_isr(int irq, void *dev_id);
+-
+-static int __devinit wl_pci_probe(struct pci_dev *pdev,
+-				  const struct pci_device_id *ent);
+-static void wl_remove(struct pci_dev *pdev);
+-static void wl_free(struct wl_info *wl);
+-static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br);
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-/* recognized PCI IDs */
+-static struct pci_device_id wl_id_table[] = {
+-	{PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 43225 2G */
+-	{PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 43224 DUAL */
+-	{PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 4313 DUAL */
+-	{0}
+-};
+-
+-MODULE_DEVICE_TABLE(pci, wl_id_table);
+-
+-#ifdef BCMDBG
+-static int msglevel = 0xdeadbeef;
+-module_param(msglevel, int, 0);
+-static int phymsglevel = 0xdeadbeef;
+-module_param(phymsglevel, int, 0);
+-#endif				/* BCMDBG */
+-
+-#define HW_TO_WL(hw)	 (hw->priv)
+-#define WL_TO_HW(wl)	  (wl->pub->ieee_hw)
+-
+-/* MAC80211 callback functions */
+-static int wl_ops_start(struct ieee80211_hw *hw);
+-static void wl_ops_stop(struct ieee80211_hw *hw);
+-static int wl_ops_add_interface(struct ieee80211_hw *hw,
+-				struct ieee80211_vif *vif);
+-static void wl_ops_remove_interface(struct ieee80211_hw *hw,
+-				    struct ieee80211_vif *vif);
+-static int wl_ops_config(struct ieee80211_hw *hw, u32 changed);
+-static void wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+-				    struct ieee80211_vif *vif,
+-				    struct ieee80211_bss_conf *info,
+-				    u32 changed);
+-static void wl_ops_configure_filter(struct ieee80211_hw *hw,
+-				    unsigned int changed_flags,
+-				    unsigned int *total_flags, u64 multicast);
+-static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+-			  bool set);
+-static void wl_ops_sw_scan_start(struct ieee80211_hw *hw);
+-static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw);
+-static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
+-static int wl_ops_get_stats(struct ieee80211_hw *hw,
+-			    struct ieee80211_low_level_stats *stats);
+-static void wl_ops_sta_notify(struct ieee80211_hw *hw,
+-			      struct ieee80211_vif *vif,
+-			      enum sta_notify_cmd cmd,
+-			      struct ieee80211_sta *sta);
+-static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+-			  const struct ieee80211_tx_queue_params *params);
+-static u64 wl_ops_get_tsf(struct ieee80211_hw *hw);
+-static int wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		      struct ieee80211_sta *sta);
+-static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-			 struct ieee80211_sta *sta);
+-static int wl_ops_ampdu_action(struct ieee80211_hw *hw,
+-			       struct ieee80211_vif *vif,
+-			       enum ieee80211_ampdu_mlme_action action,
+-			       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-			       u8 buf_size);
+-static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
+-static void wl_ops_flush(struct ieee80211_hw *hw, bool drop);
+-
+-static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+-{
+-	struct wl_info *wl = hw->priv;
+-
+-	WL_LOCK(wl);
+-	if (!wl->pub->up) {
+-		wiphy_err(wl->wiphy, "ops->tx called while down\n");
+-		kfree_skb(skb);
+-		goto done;
+-	}
+-	wlc_sendpkt_mac80211(wl->wlc, skb, hw);
+- done:
+-	WL_UNLOCK(wl);
+-}
+-
+-static int wl_ops_start(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	bool blocked;
+-	/*
+-	  struct ieee80211_channel *curchan = hw->conf.channel;
+-	*/
+-
+-	ieee80211_wake_queues(hw);
+-	WL_LOCK(wl);
+-	blocked = wl_rfkill_set_hw_state(wl);
+-	WL_UNLOCK(wl);
+-	if (!blocked)
+-		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
+-
+-	return 0;
+-}
+-
+-static void wl_ops_stop(struct ieee80211_hw *hw)
+-{
+-	ieee80211_stop_queues(hw);
+-}
+-
+-static int
+-wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+-{
+-	struct wl_info *wl;
+-	int err;
+-
+-	/* Just STA for now */
+-	if (vif->type != NL80211_IFTYPE_AP &&
+-	    vif->type != NL80211_IFTYPE_MESH_POINT &&
+-	    vif->type != NL80211_IFTYPE_STATION &&
+-	    vif->type != NL80211_IFTYPE_WDS &&
+-	    vif->type != NL80211_IFTYPE_ADHOC) {
+-		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
+-			  " STA for now\n", __func__, vif->type);
+-		return -EOPNOTSUPP;
+-	}
+-
+-	wl = HW_TO_WL(hw);
+-	WL_LOCK(wl);
+-	err = wl_up(wl);
+-	WL_UNLOCK(wl);
+-
+-	if (err != 0) {
+-		wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__,
+-			  err);
+-	}
+-	return err;
+-}
+-
+-static void
+-wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+-{
+-	struct wl_info *wl;
+-
+-	wl = HW_TO_WL(hw);
+-
+-	/* put driver in down state */
+-	WL_LOCK(wl);
+-	wl_down(wl);
+-	WL_UNLOCK(wl);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-static int
+-ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
+-		 enum nl80211_channel_type type)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int err = 0;
+-
+-	switch (type) {
+-	case NL80211_CHAN_HT20:
+-	case NL80211_CHAN_NO_HT:
+-		err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
+-		break;
+-	case NL80211_CHAN_HT40MINUS:
+-	case NL80211_CHAN_HT40PLUS:
+-		wiphy_err(hw->wiphy,
+-			  "%s: Need to implement 40 Mhz Channels!\n", __func__);
+-		err = 1;
+-		break;
+-	}
+-
+-	if (err)
+-		return -EIO;
+-	return err;
+-}
+-
+-static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
+-{
+-	struct ieee80211_conf *conf = &hw->conf;
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int err = 0;
+-	int new_int;
+-	struct wiphy *wiphy = hw->wiphy;
+-
+-	WL_LOCK(wl);
+-	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+-		if (wlc_iovar_setint
+-		    (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
+-			wiphy_err(wiphy, "%s: Error setting listen_interval\n",
+-				  __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
+-		wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
+-			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
+-			  "true" : "false");
+-	if (changed & IEEE80211_CONF_CHANGE_PS)
+-		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
+-			  __func__, conf->flags & IEEE80211_CONF_PS ?
+-			  "true" : "false");
+-
+-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+-		if (wlc_iovar_setint
+-		    (wl->wlc, "qtxpower", conf->power_level * 4)) {
+-			wiphy_err(wiphy, "%s: Error setting power_level\n",
+-				  __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
+-		if (new_int != (conf->power_level * 4))
+-			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
+-				  "\n", __func__, conf->power_level * 4,
+-				  new_int);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+-		err = ieee_set_channel(hw, conf->channel, conf->channel_type);
+-	}
+-	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+-		if (wlc_set
+-		    (wl->wlc, WLC_SET_SRL,
+-		     conf->short_frame_max_tx_count) < 0) {
+-			wiphy_err(wiphy, "%s: Error setting srl\n", __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-		if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
+-		    < 0) {
+-			wiphy_err(wiphy, "%s: Error setting lrl\n", __func__);
+-			err = -EIO;
+-			goto config_out;
+-		}
+-	}
+-
+- config_out:
+-	WL_UNLOCK(wl);
+-	return err;
+-}
+-
+-static void
+-wl_ops_bss_info_changed(struct ieee80211_hw *hw,
+-			struct ieee80211_vif *vif,
+-			struct ieee80211_bss_conf *info, u32 changed)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	struct wiphy *wiphy = hw->wiphy;
+-	int val;
+-
+-	if (changed & BSS_CHANGED_ASSOC) {
+-		/* association status changed (associated/disassociated)
+-		 * also implies a change in the AID.
+-		 */
+-		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
+-			  __func__, info->assoc ? "" : "dis");
+-		WL_LOCK(wl);
+-		wlc_associate_upd(wl->wlc, info->assoc);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_ERP_SLOT) {
+-		/* slot timing changed */
+-		if (info->use_short_slot)
+-			val = 1;
+-		else
+-			val = 0;
+-		WL_LOCK(wl);
+-		wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
+-		WL_UNLOCK(wl);
+-	}
+-
+-	if (changed & BSS_CHANGED_HT) {
+-		/* 802.11n parameters changed */
+-		u16 mode = info->ht_operation_mode;
+-
+-		WL_LOCK(wl);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG,
+-			mode & IEEE80211_HT_OP_MODE_PROTECTION);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF,
+-			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+-		wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS,
+-			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BASIC_RATES) {
+-		struct ieee80211_supported_band *bi;
+-		u32 br_mask, i;
+-		u16 rate;
+-		struct wl_rateset rs;
+-		int error;
+-
+-		/* retrieve the current rates */
+-		WL_LOCK(wl);
+-		error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET,
+-				  &rs, sizeof(rs), NULL);
+-		WL_UNLOCK(wl);
+-		if (error) {
+-			wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n",
+-				  __func__, error);
+-			return;
+-		}
+-		br_mask = info->basic_rates;
+-		bi = hw->wiphy->bands[wlc_get_curband(wl->wlc)];
+-		for (i = 0; i < bi->n_bitrates; i++) {
+-			/* convert to internal rate value */
+-			rate = (bi->bitrates[i].bitrate << 1) / 10;
+-
+-			/* set/clear basic rate flag */
+-			wl_set_basic_rate(&rs, rate, br_mask & 1);
+-			br_mask >>= 1;
+-		}
+-
+-		/* update the rate set */
+-		WL_LOCK(wl);
+-		wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BEACON_INT) {
+-		/* Beacon interval changed */
+-		WL_LOCK(wl);
+-		wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BSSID) {
+-		/* BSSID changed, for whatever reason (IBSS and managed mode) */
+-		WL_LOCK(wl);
+-		wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
+-				  info->bssid);
+-		WL_UNLOCK(wl);
+-	}
+-	if (changed & BSS_CHANGED_BEACON) {
+-		/* Beacon data changed, retrieve new beacon (beaconing modes) */
+-		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
+-	}
+-	if (changed & BSS_CHANGED_BEACON_ENABLED) {
+-		/* Beaconing should be enabled/disabled (beaconing modes) */
+-		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
+-			  info->enable_beacon ? "true" : "false");
+-	}
+-	if (changed & BSS_CHANGED_CQM) {
+-		/* Connection quality monitor config changed */
+-		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
+-			  " (implement)\n", __func__, info->cqm_rssi_thold,
+-			  info->cqm_rssi_hyst);
+-	}
+-	if (changed & BSS_CHANGED_IBSS) {
+-		/* IBSS join status changed */
+-		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
+-			  info->ibss_joined ? "true" : "false");
+-	}
+-	if (changed & BSS_CHANGED_ARP_FILTER) {
+-		/* Hardware ARP filter address list or state changed */
+-		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
+-			  " (implement)\n", __func__, info->arp_filter_enabled ?
+-			  "true" : "false", info->arp_addr_cnt);
+-	}
+-	if (changed & BSS_CHANGED_QOS) {
+-		/*
+-		 * QoS for this association was enabled/disabled.
+-		 * Note that it is only ever disabled for station mode.
+-		 */
+-		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
+-			  info->qos ? "true" : "false");
+-	}
+-	return;
+-}
+-
+-static void
+-wl_ops_configure_filter(struct ieee80211_hw *hw,
+-			unsigned int changed_flags,
+-			unsigned int *total_flags, u64 multicast)
+-{
+-	struct wl_info *wl = hw->priv;
+-	struct wiphy *wiphy = hw->wiphy;
+-
+-	changed_flags &= MAC_FILTERS;
+-	*total_flags &= MAC_FILTERS;
+-	if (changed_flags & FIF_PROMISC_IN_BSS)
+-		wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
+-	if (changed_flags & FIF_ALLMULTI)
+-		wiphy_err(wiphy, "FIF_ALLMULTI\n");
+-	if (changed_flags & FIF_FCSFAIL)
+-		wiphy_err(wiphy, "FIF_FCSFAIL\n");
+-	if (changed_flags & FIF_PLCPFAIL)
+-		wiphy_err(wiphy, "FIF_PLCPFAIL\n");
+-	if (changed_flags & FIF_CONTROL)
+-		wiphy_err(wiphy, "FIF_CONTROL\n");
+-	if (changed_flags & FIF_OTHER_BSS)
+-		wiphy_err(wiphy, "FIF_OTHER_BSS\n");
+-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+-		WL_LOCK(wl);
+-		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
+-			wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
+-			wlc_mac_bcn_promisc_change(wl->wlc, 1);
+-		} else {
+-			wlc_mac_bcn_promisc_change(wl->wlc, 0);
+-			wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
+-		}
+-		WL_UNLOCK(wl);
+-	}
+-	return;
+-}
+-
+-static int
+-wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+-{
+-	return 0;
+-}
+-
+-static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	WL_LOCK(wl);
+-	wlc_scan_start(wl->wlc);
+-	WL_UNLOCK(wl);
+-	return;
+-}
+-
+-static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = hw->priv;
+-	WL_LOCK(wl);
+-	wlc_scan_stop(wl->wlc);
+-	WL_UNLOCK(wl);
+-	return;
+-}
+-
+-static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+-{
+-	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
+-	return;
+-}
+-
+-static int
+-wl_ops_get_stats(struct ieee80211_hw *hw,
+-		 struct ieee80211_low_level_stats *stats)
+-{
+-	struct wl_info *wl = hw->priv;
+-	struct wl_cnt *cnt;
+-
+-	WL_LOCK(wl);
+-	cnt = wl->pub->_cnt;
+-	stats->dot11ACKFailureCount = 0;
+-	stats->dot11RTSFailureCount = 0;
+-	stats->dot11FCSErrorCount = 0;
+-	stats->dot11RTSSuccessCount = 0;
+-	WL_UNLOCK(wl);
+-	return 0;
+-}
+-
+-static void
+-wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		  enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
+-{
+-	switch (cmd) {
+-	default:
+-		wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__,
+-			  cmd);
+-		break;
+-	}
+-	return;
+-}
+-
+-static int
+-wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
+-	       const struct ieee80211_tx_queue_params *params)
+-{
+-	struct wl_info *wl = hw->priv;
+-
+-	WL_LOCK(wl);
+-	wlc_wme_setparams(wl->wlc, queue, params, true);
+-	WL_UNLOCK(wl);
+-
+-	return 0;
+-}
+-
+-static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
+-{
+-	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
+-	return 0;
+-}
+-
+-static int
+-wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-	       struct ieee80211_sta *sta)
+-{
+-	struct scb *scb;
+-
+-	int i;
+-	struct wl_info *wl = hw->priv;
+-
+-	/* Init the scb */
+-	scb = (struct scb *)sta->drv_priv;
+-	memset(scb, 0, sizeof(struct scb));
+-	for (i = 0; i < NUMPRIO; i++)
+-		scb->seqctl[i] = 0xFFFF;
+-	scb->seqctl_nonqos = 0xFFFF;
+-	scb->magic = SCB_MAGIC;
+-
+-	wl->pub->global_scb = scb;
+-	wl->pub->global_ampdu = &(scb->scb_ampdu);
+-	wl->pub->global_ampdu->scb = scb;
+-	wl->pub->global_ampdu->max_pdu = 16;
+-	bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
+-		  AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
+-
+-	sta->ht_cap.ht_supported = true;
+-	sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+-	sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
+-	sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
+-	    IEEE80211_HT_CAP_SGI_20 |
+-	    IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+-
+-	/* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
+-	return 0;
+-}
+-
+-static int
+-wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+-		  struct ieee80211_sta *sta)
+-{
+-	return 0;
+-}
+-
+-static int
+-wl_ops_ampdu_action(struct ieee80211_hw *hw,
+-		    struct ieee80211_vif *vif,
+-		    enum ieee80211_ampdu_mlme_action action,
+-		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+-		    u8 buf_size)
+-{
+-	struct scb *scb = (struct scb *)sta->drv_priv;
+-	struct wl_info *wl = hw->priv;
+-	int status;
+-
+-	if (WARN_ON(scb->magic != SCB_MAGIC))
+-		return -EIDRM;
+-	switch (action) {
+-	case IEEE80211_AMPDU_RX_START:
+-		break;
+-	case IEEE80211_AMPDU_RX_STOP:
+-		break;
+-	case IEEE80211_AMPDU_TX_START:
+-		WL_LOCK(wl);
+-		status = wlc_aggregatable(wl->wlc, tid);
+-		WL_UNLOCK(wl);
+-		if (!status) {
+-			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
+-				  tid);
+-			return -EINVAL;
+-		}
+-		/* XXX: Use the starting sequence number provided ... */
+-		*ssn = 0;
+-		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+-		break;
+-
+-	case IEEE80211_AMPDU_TX_STOP:
+-		WL_LOCK(wl);
+-		wlc_ampdu_flush(wl->wlc, sta, tid);
+-		WL_UNLOCK(wl);
+-		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+-		break;
+-	case IEEE80211_AMPDU_TX_OPERATIONAL:
+-		/* Not sure what to do here */
+-		/* Power save wakeup */
+-		break;
+-	default:
+-		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
+-			  __func__);
+-	}
+-
+-	return 0;
+-}
+-
+-static void wl_ops_rfkill_poll(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	bool blocked;
+-
+-	WL_LOCK(wl);
+-	blocked = wlc_check_radio_disabled(wl->wlc);
+-	WL_UNLOCK(wl);
+-
+-	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
+-}
+-
+-static void wl_ops_flush(struct ieee80211_hw *hw, bool drop)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-
+-	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
+-
+-	/* wait for packet queue and dma fifos to run empty */
+-	WL_LOCK(wl);
+-	wlc_wait_for_tx_completion(wl->wlc, drop);
+-	WL_UNLOCK(wl);
+-}
+-
+-static const struct ieee80211_ops wl_ops = {
+-	.tx = wl_ops_tx,
+-	.start = wl_ops_start,
+-	.stop = wl_ops_stop,
+-	.add_interface = wl_ops_add_interface,
+-	.remove_interface = wl_ops_remove_interface,
+-	.config = wl_ops_config,
+-	.bss_info_changed = wl_ops_bss_info_changed,
+-	.configure_filter = wl_ops_configure_filter,
+-	.set_tim = wl_ops_set_tim,
+-	.sw_scan_start = wl_ops_sw_scan_start,
+-	.sw_scan_complete = wl_ops_sw_scan_complete,
+-	.set_tsf = wl_ops_set_tsf,
+-	.get_stats = wl_ops_get_stats,
+-	.sta_notify = wl_ops_sta_notify,
+-	.conf_tx = wl_ops_conf_tx,
+-	.get_tsf = wl_ops_get_tsf,
+-	.sta_add = wl_ops_sta_add,
+-	.sta_remove = wl_ops_sta_remove,
+-	.ampdu_action = wl_ops_ampdu_action,
+-	.rfkill_poll = wl_ops_rfkill_poll,
+-	.flush = wl_ops_flush,
+-};
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int wl_set_hint(struct wl_info *wl, char *abbrev)
+-{
+-	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
+-}
+-
+-/**
+- * attach to the WL device.
+- *
+- * Attach to the WL device identified by vendor and device parameters.
+- * regs is a host accessible memory address pointing to WL device registers.
+- *
+- * wl_attach is not defined as static because in the case where no bus
+- * is defined, wl_attach will never be called, and thus, gcc will issue
+- * a warning that this function is defined but not used if we declare
+- * it as static.
+- *
+- *
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
+-			    uint bustype, void *btparam, uint irq)
+-{
+-	struct wl_info *wl = NULL;
+-	int unit, err;
+-
+-	unsigned long base_addr;
+-	struct ieee80211_hw *hw;
+-	u8 perm[ETH_ALEN];
+-
+-	unit = wl_found;
+-	err = 0;
+-
+-	if (unit < 0) {
+-		return NULL;
+-	}
+-
+-	/* allocate private info */
+-	hw = pci_get_drvdata(btparam);	/* btparam == pdev */
+-	if (hw != NULL)
+-		wl = hw->priv;
+-	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
+-		return NULL;
+-	wl->wiphy = hw->wiphy;
+-
+-	atomic_set(&wl->callbacks, 0);
+-
+-	/* setup the bottom half handler */
+-	tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);
+-
+-
+-
+-	base_addr = regs;
+-
+-	if (bustype == PCI_BUS) {
+-		wl->piomode = false;
+-	} else if (bustype == RPC_BUS) {
+-		/* Do nothing */
+-	} else {
+-		bustype = PCI_BUS;
+-		BCMMSG(wl->wiphy, "force to PCI\n");
+-	}
+-	wl->bcm_bustype = bustype;
+-
+-	wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
+-	if (wl->regsva == NULL) {
+-		wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
+-		goto fail;
+-	}
+-	spin_lock_init(&wl->lock);
+-	spin_lock_init(&wl->isr_lock);
+-
+-	/* prepare ucode */
+-	if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) {
+-		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
+-			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
+-		wl_release_fw(wl);
+-		wl_remove((struct pci_dev *)btparam);
+-		return NULL;
+-	}
+-
+-	/* common load-time initialization */
+-	wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode,
+-			     wl->regsva, wl->bcm_bustype, btparam, &err);
+-	wl_release_fw(wl);
+-	if (!wl->wlc) {
+-		wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n",
+-			  KBUILD_MODNAME, err);
+-		goto fail;
+-	}
+-	wl->pub = wlc_pub(wl->wlc);
+-
+-	wl->pub->ieee_hw = hw;
+-
+-	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+-		wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n",
+-			  unit);
+-	}
+-
+-	/* register our interrupt handler */
+-	if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
+-		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
+-		goto fail;
+-	}
+-	wl->irq = irq;
+-
+-	/* register module */
+-	wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
+-			    NULL);
+-
+-	if (ieee_hw_init(hw)) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
+-			  __func__);
+-		goto fail;
+-	}
+-
+-	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
+-	if (WARN_ON(!is_valid_ether_addr(perm)))
+-		goto fail;
+-	SET_IEEE80211_PERM_ADDR(hw, perm);
+-
+-	err = ieee80211_register_hw(hw);
+-	if (err) {
+-		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
+-			  "%d\n", __func__, err);
+-	}
+-
+-	if (wl->pub->srom_ccode[0])
+-		err = wl_set_hint(wl, wl->pub->srom_ccode);
+-	else
+-		err = wl_set_hint(wl, "US");
+-	if (err) {
+-		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
+-			  __func__, err);
+-	}
+-
+-	wl_found++;
+-	return wl;
+-
+-fail:
+-	wl_free(wl);
+-	return NULL;
+-}
+-
+-
+-
+-#define CHAN2GHZ(channel, freqency, chflags)  { \
+-	.band = IEEE80211_BAND_2GHZ, \
+-	.center_freq = (freqency), \
+-	.hw_value = (channel), \
+-	.flags = chflags, \
+-	.max_antenna_gain = 0, \
+-	.max_power = 19, \
+-}
+-
+-static struct ieee80211_channel wl_2ghz_chantable[] = {
+-	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN2GHZ(5, 2432, 0),
+-	CHAN2GHZ(6, 2437, 0),
+-	CHAN2GHZ(7, 2442, 0),
+-	CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(12, 2467,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(13, 2472,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN2GHZ(14, 2484,
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+-};
+-
+-#define CHAN5GHZ(channel, chflags)  { \
+-	.band = IEEE80211_BAND_5GHZ, \
+-	.center_freq = 5000 + 5*(channel), \
+-	.hw_value = (channel), \
+-	.flags = chflags, \
+-	.max_antenna_gain = 0, \
+-	.max_power = 21, \
+-}
+-
+-static struct ieee80211_channel wl_5ghz_nphy_chantable[] = {
+-	/* UNII-1 */
+-	CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
+-	/* UNII-2 */
+-	CHAN5GHZ(52,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(56,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(60,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(64,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	/* MID */
+-	CHAN5GHZ(100,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(104,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(108,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(112,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(116,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(120,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(124,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(128,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(132,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(136,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(140,
+-		 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
+-		 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
+-		 IEEE80211_CHAN_NO_HT40MINUS),
+-	/* UNII-3 */
+-	CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
+-	CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
+-	CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+-};
+-
+-#define RATE(rate100m, _flags) { \
+-	.bitrate = (rate100m), \
+-	.flags = (_flags), \
+-	.hw_value = (rate100m / 5), \
+-}
+-
+-static struct ieee80211_rate wl_legacy_ratetable[] = {
+-	RATE(10, 0),
+-	RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
+-	RATE(60, 0),
+-	RATE(90, 0),
+-	RATE(120, 0),
+-	RATE(180, 0),
+-	RATE(240, 0),
+-	RATE(360, 0),
+-	RATE(480, 0),
+-	RATE(540, 0),
+-};
+-
+-static struct ieee80211_supported_band wl_band_2GHz_nphy = {
+-	.band = IEEE80211_BAND_2GHZ,
+-	.channels = wl_2ghz_chantable,
+-	.n_channels = ARRAY_SIZE(wl_2ghz_chantable),
+-	.bitrates = wl_legacy_ratetable,
+-	.n_bitrates = ARRAY_SIZE(wl_legacy_ratetable),
+-	.ht_cap = {
+-		   /* from include/linux/ieee80211.h */
+-		   .cap = IEEE80211_HT_CAP_GRN_FLD |
+-		   IEEE80211_HT_CAP_SGI_20 |
+-		   IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
+-		   .ht_supported = true,
+-		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+-		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+-		   .mcs = {
+-			   /* placeholders for now */
+-			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+-			   .rx_highest = 500,
+-			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+-		   }
+-};
+-
+-static struct ieee80211_supported_band wl_band_5GHz_nphy = {
+-	.band = IEEE80211_BAND_5GHZ,
+-	.channels = wl_5ghz_nphy_chantable,
+-	.n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable),
+-	.bitrates = wl_legacy_ratetable + 4,
+-	.n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4,
+-	.ht_cap = {
+-		   /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
+-		   .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,	/* No 40 mhz yet */
+-		   .ht_supported = true,
+-		   .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
+-		   .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
+-		   .mcs = {
+-			   /* placeholders for now */
+-			   .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
+-			   .rx_highest = 500,
+-			   .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
+-		   }
+-};
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int ieee_hw_rate_init(struct ieee80211_hw *hw)
+-{
+-	struct wl_info *wl = HW_TO_WL(hw);
+-	int has_5g;
+-	char phy_list[4];
+-
+-	has_5g = 0;
+-
+-	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+-	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+-
+-	if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
+-		wiphy_err(hw->wiphy, "Phy list failed\n");
+-	}
+-
+-	if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+-		if (phy_list[0] == 'c') {
+-			/* Single stream */
+-			wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
+-			wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
+-		}
+-		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
+-	} else {
+-		return -EPERM;
+-	}
+-
+-	/* Assume all bands use the same phy.  True for 11n devices. */
+-	if (NBANDS_PUB(wl->pub) > 1) {
+-		has_5g++;
+-		if (phy_list[0] == 'n' || phy_list[0] == 'c') {
+-			hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+-			    &wl_band_5GHz_nphy;
+-		} else {
+-			return -EPERM;
+-		}
+-	}
+-	return 0;
+-}
+-
+-/*
+- * is called in wl_pci_probe() context, therefore no locking required.
+- */
+-static int ieee_hw_init(struct ieee80211_hw *hw)
+-{
+-	hw->flags = IEEE80211_HW_SIGNAL_DBM
+-	    /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
+-	    | IEEE80211_HW_REPORTS_TX_ACK_STATUS
+-	    | IEEE80211_HW_AMPDU_AGGREGATION;
+-
+-	hw->extra_tx_headroom = wlc_get_header_len();
+-	hw->queues = N_TX_QUEUES;
+-	/* FIXME: this doesn't seem to be used properly in minstrel_ht.
+-	 * mac80211/status.c:ieee80211_tx_status() checks this value,
+-	 * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
+-	 * appears to always set 3 rates
+-	 */
+-	hw->max_rates = 2;	/* Primary rate and 1 fallback rate */
+-
+-	hw->channel_change_time = 7 * 1000;	/* channel change time is dependent on chip and band  */
+-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+-
+-	hw->rate_control_algorithm = "minstrel_ht";
+-
+-	hw->sta_data_size = sizeof(struct scb);
+-	return ieee_hw_rate_init(hw);
+-}
+-
+-/**
+- * determines if a device is a WL device, and if so, attaches it.
+- *
+- * This function determines if a device pointed to by pdev is a WL device,
+- * and if so, performs a wl_attach() on it.
+- *
+- * Perimeter lock is initialized in the course of this function.
+- */
+-static int __devinit
+-wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+-{
+-	int rc;
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	u32 val;
+-
+-	dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
+-	       pdev->bus->number, PCI_SLOT(pdev->devfn),
+-	       PCI_FUNC(pdev->devfn), pdev->irq);
+-
+-	if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
+-	    (((pdev->device & 0xff00) != 0x4300) &&
+-	     ((pdev->device & 0xff00) != 0x4700) &&
+-	     ((pdev->device < 43000) || (pdev->device > 43999))))
+-		return -ENODEV;
+-
+-	rc = pci_enable_device(pdev);
+-	if (rc) {
+-		pr_err("%s: Cannot enable device %d-%d_%d\n",
+-		       __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
+-		       PCI_FUNC(pdev->devfn));
+-		return -ENODEV;
+-	}
+-	pci_set_master(pdev);
+-
+-	pci_read_config_dword(pdev, 0x40, &val);
+-	if ((val & 0x0000ff00) != 0)
+-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+-
+-	hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops);
+-	if (!hw) {
+-		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
+-		return -ENOMEM;
+-	}
+-
+-	SET_IEEE80211_DEV(hw, &pdev->dev);
+-
+-	pci_set_drvdata(pdev, hw);
+-
+-	memset(hw->priv, 0, sizeof(*wl));
+-
+-	wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
+-		       PCI_BUS, pdev, pdev->irq);
+-
+-	if (!wl) {
+-		pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME,
+-		       __func__);
+-		return -ENODEV;
+-	}
+-	return 0;
+-}
+-
+-static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		wiphy_err(wl->wiphy,
+-			  "wl_suspend: pci_get_drvdata failed\n");
+-		return -ENODEV;
+-	}
+-
+-	/* only need to flag hw is down for proper resume */
+-	WL_LOCK(wl);
+-	wl->pub->hw_up = false;
+-	WL_UNLOCK(wl);
+-
+-	pci_save_state(pdev);
+-	pci_disable_device(pdev);
+-	return pci_set_power_state(pdev, PCI_D3hot);
+-}
+-
+-static int wl_resume(struct pci_dev *pdev)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	int err = 0;
+-	u32 val;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		wiphy_err(wl->wiphy,
+-			  "wl: wl_resume: pci_get_drvdata failed\n");
+-		return -ENODEV;
+-	}
+-
+-	err = pci_set_power_state(pdev, PCI_D0);
+-	if (err)
+-		return err;
+-
+-	pci_restore_state(pdev);
+-
+-	err = pci_enable_device(pdev);
+-	if (err)
+-		return err;
+-
+-	pci_set_master(pdev);
+-
+-	pci_read_config_dword(pdev, 0x40, &val);
+-	if ((val & 0x0000ff00) != 0)
+-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+-
+-	/*
+-	*  done. driver will be put in up state
+-	*  in wl_ops_add_interface() call.
+-	*/
+-	return err;
+-}
+-
+-/*
+-* called from both kernel as from wl_*()
+-* precondition: perimeter lock is not acquired.
+-*/
+-static void wl_remove(struct pci_dev *pdev)
+-{
+-	struct wl_info *wl;
+-	struct ieee80211_hw *hw;
+-	int status;
+-
+-	hw = pci_get_drvdata(pdev);
+-	wl = HW_TO_WL(hw);
+-	if (!wl) {
+-		pr_err("wl: wl_remove: pci_get_drvdata failed\n");
+-		return;
+-	}
+-
+-	WL_LOCK(wl);
+-	status = wlc_chipmatch(pdev->vendor, pdev->device);
+-	WL_UNLOCK(wl);
+-	if (!status) {
+-		wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n");
+-		return;
+-	}
+-	if (wl->wlc) {
+-		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
+-		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
+-		ieee80211_unregister_hw(hw);
+-		WL_LOCK(wl);
+-		wl_down(wl);
+-		WL_UNLOCK(wl);
+-	}
+-	pci_disable_device(pdev);
+-
+-	wl_free(wl);
+-
+-	pci_set_drvdata(pdev, NULL);
+-	ieee80211_free_hw(hw);
+-}
+-
+-static struct pci_driver wl_pci_driver = {
+-	.name     = KBUILD_MODNAME,
+-	.probe    = wl_pci_probe,
+-	.suspend  = wl_suspend,
+-	.resume   = wl_resume,
+-	.remove   = __devexit_p(wl_remove),
+-	.id_table = wl_id_table,
+-};
+-
+-/**
+- * This is the main entry point for the WL driver.
+- *
+- * This function determines if a device pointed to by pdev is a WL device,
+- * and if so, performs a wl_attach() on it.
+- *
+- */
+-static int __init wl_module_init(void)
+-{
+-	int error = -ENODEV;
+-
+-#ifdef BCMDBG
+-	if (msglevel != 0xdeadbeef)
+-		wl_msg_level = msglevel;
+-	else {
+-		char *var = getvar(NULL, "wl_msglevel");
+-		if (var) {
+-			unsigned long value;
+-
+-			(void)strict_strtoul(var, 0, &value);
+-			wl_msg_level = value;
+-		}
+-	}
+-	if (phymsglevel != 0xdeadbeef)
+-		phyhal_msg_level = phymsglevel;
+-	else {
+-		char *var = getvar(NULL, "phy_msglevel");
+-		if (var) {
+-			unsigned long value;
+-
+-			(void)strict_strtoul(var, 0, &value);
+-			phyhal_msg_level = value;
+-		}
+-	}
+-#endif				/* BCMDBG */
+-
+-	error = pci_register_driver(&wl_pci_driver);
+-	if (!error)
+-		return 0;
+-
+-
+-
+-	return error;
+-}
+-
+-/**
+- * This function unloads the WL driver from the system.
+- *
+- * This function unconditionally unloads the WL driver module from the
+- * system.
+- *
+- */
+-static void __exit wl_module_exit(void)
+-{
+-	pci_unregister_driver(&wl_pci_driver);
+-
+-}
+-
+-module_init(wl_module_init);
+-module_exit(wl_module_exit);
+-
+-/**
+- * This function frees the WL per-device resources.
+- *
+- * This function frees resources owned by the WL device pointed to
+- * by the wl parameter.
+- *
+- * precondition: can both be called locked and unlocked
+- *
+- */
+-static void wl_free(struct wl_info *wl)
+-{
+-	struct wl_timer *t, *next;
+-
+-	/* free ucode data */
+-	if (wl->fw.fw_cnt)
+-		wl_ucode_data_free();
+-	if (wl->irq)
+-		free_irq(wl->irq, wl);
+-
+-	/* kill dpc */
+-	tasklet_kill(&wl->tasklet);
+-
+-	if (wl->pub) {
+-		wlc_module_unregister(wl->pub, "linux", wl);
+-	}
+-
+-	/* free common resources */
+-	if (wl->wlc) {
+-		wlc_detach(wl->wlc);
+-		wl->wlc = NULL;
+-		wl->pub = NULL;
+-	}
+-
+-	/* virtual interface deletion is deferred so we cannot spinwait */
+-
+-	/* wait for all pending callbacks to complete */
+-	while (atomic_read(&wl->callbacks) > 0)
+-		schedule();
+-
+-	/* free timers */
+-	for (t = wl->timers; t; t = next) {
+-		next = t->next;
+-#ifdef BCMDBG
+-		kfree(t->name);
+-#endif
+-		kfree(t);
+-	}
+-
+-	/*
+-	 * unregister_netdev() calls get_stats() which may read chip registers
+-	 * so we cannot unmap the chip registers until after calling unregister_netdev() .
+-	 */
+-	if (wl->regsva && wl->bcm_bustype != SDIO_BUS &&
+-	    wl->bcm_bustype != JTAG_BUS) {
+-		iounmap((void *)wl->regsva);
+-	}
+-	wl->regsva = NULL;
+-}
+-
+-/* flags the given rate in rateset as requested */
+-static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br)
+-{
+-	u32 i;
+-
+-	for (i = 0; i < rs->count; i++) {
+-		if (rate != (rs->rates[i] & 0x7f))
+-			continue;
+-
+-		if (is_br)
+-			rs->rates[i] |= WLC_RATE_FLAG;
+-		else
+-			rs->rates[i] &= WLC_RATE_MASK;
+-		return;
+-	}
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+-		      int prio)
+-{
+-	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_init(struct wl_info *wl)
+-{
+-	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
+-	wl_reset(wl);
+-
+-	wlc_init(wl->wlc);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-uint wl_reset(struct wl_info *wl)
+-{
+-	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
+-	wlc_reset(wl->wlc);
+-
+-	/* dpc will not be rescheduled */
+-	wl->resched = 0;
+-
+-	return 0;
+-}
+-
+-/*
+- * These are interrupt on/off entry points. Disable interrupts
+- * during interrupt state transition.
+- */
+-void wl_intrson(struct wl_info *wl)
+-{
+-	unsigned long flags;
+-
+-	INT_LOCK(wl, flags);
+-	wlc_intrson(wl->wlc);
+-	INT_UNLOCK(wl, flags);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth)
+-{
+-	return true;
+-}
+-
+-u32 wl_intrsoff(struct wl_info *wl)
+-{
+-	unsigned long flags;
+-	u32 status;
+-
+-	INT_LOCK(wl, flags);
+-	status = wlc_intrsoff(wl->wlc);
+-	INT_UNLOCK(wl, flags);
+-	return status;
+-}
+-
+-void wl_intrsrestore(struct wl_info *wl, u32 macintmask)
+-{
+-	unsigned long flags;
+-
+-	INT_LOCK(wl, flags);
+-	wlc_intrsrestore(wl->wlc, macintmask);
+-	INT_UNLOCK(wl, flags);
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-int wl_up(struct wl_info *wl)
+-{
+-	int error = 0;
+-
+-	if (wl->pub->up)
+-		return 0;
+-
+-	error = wlc_up(wl->wlc);
+-
+-	return error;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_down(struct wl_info *wl)
+-{
+-	uint callbacks, ret_val = 0;
+-
+-	/* call common down function */
+-	ret_val = wlc_down(wl->wlc);
+-	callbacks = atomic_read(&wl->callbacks) - ret_val;
+-
+-	/* wait for down callbacks to complete */
+-	WL_UNLOCK(wl);
+-
+-	/* For HIGH_only driver, it's important to actually schedule other work,
+-	 * not just spin wait since everything runs at schedule level
+-	 */
+-	SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
+-
+-	WL_LOCK(wl);
+-}
+-
+-static irqreturn_t wl_isr(int irq, void *dev_id)
+-{
+-	struct wl_info *wl;
+-	bool ours, wantdpc;
+-	unsigned long flags;
+-
+-	wl = (struct wl_info *) dev_id;
+-
+-	WL_ISRLOCK(wl, flags);
+-
+-	/* call common first level interrupt handler */
+-	ours = wlc_isr(wl->wlc, &wantdpc);
+-	if (ours) {
+-		/* if more to do... */
+-		if (wantdpc) {
+-
+-			/* ...and call the second level interrupt handler */
+-			/* schedule dpc */
+-			tasklet_schedule(&wl->tasklet);
+-		}
+-	}
+-
+-	WL_ISRUNLOCK(wl, flags);
+-
+-	return IRQ_RETVAL(ours);
+-}
+-
+-static void wl_dpc(unsigned long data)
+-{
+-	struct wl_info *wl;
+-
+-	wl = (struct wl_info *) data;
+-
+-	WL_LOCK(wl);
+-
+-	/* call the common second level interrupt handler */
+-	if (wl->pub->up) {
+-		if (wl->resched) {
+-			unsigned long flags;
+-
+-			INT_LOCK(wl, flags);
+-			wlc_intrsupd(wl->wlc);
+-			INT_UNLOCK(wl, flags);
+-		}
+-
+-		wl->resched = wlc_dpc(wl->wlc, true);
+-	}
+-
+-	/* wlc_dpc() may bring the driver down */
+-	if (!wl->pub->up)
+-		goto done;
+-
+-	/* re-schedule dpc */
+-	if (wl->resched)
+-		tasklet_schedule(&wl->tasklet);
+-	else {
+-		/* re-enable interrupts */
+-		wl_intrson(wl);
+-	}
+-
+- done:
+-	WL_UNLOCK(wl);
+-}
+-
+-/*
+- * is called by the kernel from software irq context
+- */
+-static void wl_timer(unsigned long data)
+-{
+-	_wl_timer((struct wl_timer *) data);
+-}
+-
+-/*
+-* precondition: perimeter lock is not acquired
+- */
+-static void _wl_timer(struct wl_timer *t)
+-{
+-	WL_LOCK(t->wl);
+-
+-	if (t->set) {
+-		if (t->periodic) {
+-			t->timer.expires = jiffies + t->ms * HZ / 1000;
+-			atomic_inc(&t->wl->callbacks);
+-			add_timer(&t->timer);
+-			t->set = true;
+-		} else
+-			t->set = false;
+-
+-		t->fn(t->arg);
+-	}
+-
+-	atomic_dec(&t->wl->callbacks);
+-
+-	WL_UNLOCK(t->wl);
+-}
+-
+-/*
+- * Adds a timer to the list. Caller supplies a timer function.
+- * Is called from wlc.
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg),
+-			       void *arg, const char *name)
+-{
+-	struct wl_timer *t;
+-
+-	t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC);
+-	if (!t) {
+-		wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n",
+-			  wl->pub->unit);
+-		return 0;
+-	}
+-
+-	init_timer(&t->timer);
+-	t->timer.data = (unsigned long) t;
+-	t->timer.function = wl_timer;
+-	t->wl = wl;
+-	t->fn = fn;
+-	t->arg = arg;
+-	t->next = wl->timers;
+-	wl->timers = t;
+-
+-#ifdef BCMDBG
+-	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
+-	if (t->name)
+-		strcpy(t->name, name);
+-#endif
+-
+-	return t;
+-}
+-
+-/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
+- * as well as it's easier to make it periodic
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic)
+-{
+-#ifdef BCMDBG
+-	if (t->set) {
+-		wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
+-			  __func__, t->name, periodic);
+-	}
+-#endif
+-	t->ms = ms;
+-	t->periodic = (bool) periodic;
+-	t->set = true;
+-	t->timer.expires = jiffies + ms * HZ / 1000;
+-
+-	atomic_inc(&wl->callbacks);
+-	add_timer(&t->timer);
+-}
+-
+-/*
+- * return true if timer successfully deleted, false if still pending
+- *
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_del_timer(struct wl_info *wl, struct wl_timer *t)
+-{
+-	if (t->set) {
+-		t->set = false;
+-		if (!del_timer(&t->timer)) {
+-			return false;
+-		}
+-		atomic_dec(&wl->callbacks);
+-	}
+-
+-	return true;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_free_timer(struct wl_info *wl, struct wl_timer *t)
+-{
+-	struct wl_timer *tmp;
+-
+-	/* delete the timer in case it is active */
+-	wl_del_timer(wl, t);
+-
+-	if (wl->timers == t) {
+-		wl->timers = wl->timers->next;
+-#ifdef BCMDBG
+-		kfree(t->name);
+-#endif
+-		kfree(t);
+-		return;
+-
+-	}
+-
+-	tmp = wl->timers;
+-	while (tmp) {
+-		if (tmp->next == t) {
+-			tmp->next = t->next;
+-#ifdef BCMDBG
+-			kfree(t->name);
+-#endif
+-			kfree(t);
+-			return;
+-		}
+-		tmp = tmp->next;
+-	}
+-
+-}
+-
+-/*
+- * runs in software irq context
+- *
+- * precondition: perimeter lock is not acquired
+- */
+-static int wl_linux_watchdog(void *ctx)
+-{
+-	return 0;
+-}
+-
+-struct wl_fw_hdr {
+-	u32 offset;
+-	u32 len;
+-	u32 idx;
+-};
+-
+-char *wl_firmwares[WL_MAX_FW] = {
+-	"brcm/bcm43xx",
+-	NULL
+-};
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx)
+-{
+-	int i, entry;
+-	const u8 *pdata;
+-	struct wl_fw_hdr *hdr;
+-	for (i = 0; i < wl->fw.fw_cnt; i++) {
+-		hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+-		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+-		     entry++, hdr++) {
+-			if (hdr->idx == idx) {
+-				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+-				*pbuf = kmalloc(hdr->len, GFP_ATOMIC);
+-				if (*pbuf == NULL) {
+-					wiphy_err(wl->wiphy, "fail to alloc %d"
+-						  " bytes\n", hdr->len);
+-					goto fail;
+-				}
+-				memcpy(*pbuf, pdata, hdr->len);
+-				return 0;
+-			}
+-		}
+-	}
+-	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
+-		  idx);
+-	*pbuf = NULL;
+-fail:
+-	return -ENODATA;
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
+-{
+-	int i, entry;
+-	const u8 *pdata;
+-	struct wl_fw_hdr *hdr;
+-	for (i = 0; i < wl->fw.fw_cnt; i++) {
+-		hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
+-		for (entry = 0; entry < wl->fw.hdr_num_entries[i];
+-		     entry++, hdr++) {
+-			if (hdr->idx == idx) {
+-				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
+-				if (hdr->len != 4) {
+-					wiphy_err(wl->wiphy,
+-						  "ERROR: fw hdr len\n");
+-					return -ENOMSG;
+-				}
+-				*data = *((u32 *) pdata);
+-				return 0;
+-			}
+-		}
+-	}
+-	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
+-	return -ENOMSG;
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev)
+-{
+-	int status;
+-	struct device *device = &pdev->dev;
+-	char fw_name[100];
+-	int i;
+-
+-	memset((void *)&wl->fw, 0, sizeof(struct wl_firmware));
+-	for (i = 0; i < WL_MAX_FW; i++) {
+-		if (wl_firmwares[i] == NULL)
+-			break;
+-		sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
+-			UCODE_LOADER_API_VER);
+-		status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
+-		if (status) {
+-			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+-				  KBUILD_MODNAME, fw_name);
+-			return status;
+-		}
+-		sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
+-			UCODE_LOADER_API_VER);
+-		status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
+-		if (status) {
+-			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+-				  KBUILD_MODNAME, fw_name);
+-			return status;
+-		}
+-		wl->fw.hdr_num_entries[i] =
+-		    wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
+-	}
+-	wl->fw.fw_cnt = i;
+-	return wl_ucode_data_init(wl);
+-}
+-
+-/*
+- * precondition: can both be called locked and unlocked
+- */
+-void wl_ucode_free_buf(void *p)
+-{
+-	kfree(p);
+-}
+-
+-/*
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-static void wl_release_fw(struct wl_info *wl)
+-{
+-	int i;
+-	for (i = 0; i < WL_MAX_FW; i++) {
+-		release_firmware(wl->fw.fw_bin[i]);
+-		release_firmware(wl->fw.fw_hdr[i]);
+-	}
+-}
+-
+-
+-/*
+- * checks validity of all firmware images loaded from user space
+- *
+- * Precondition: Since this function is called in wl_pci_probe() context,
+- * no locking is required.
+- */
+-int wl_check_firmwares(struct wl_info *wl)
+-{
+-	int i;
+-	int entry;
+-	int rc = 0;
+-	const struct firmware *fw;
+-	const struct firmware *fw_hdr;
+-	struct wl_fw_hdr *ucode_hdr;
+-	for (i = 0; i < WL_MAX_FW && rc == 0; i++) {
+-		fw =  wl->fw.fw_bin[i];
+-		fw_hdr = wl->fw.fw_hdr[i];
+-		if (fw == NULL && fw_hdr == NULL) {
+-			break;
+-		} else if (fw == NULL || fw_hdr == NULL) {
+-			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
+-				  __func__);
+-			rc = -EBADF;
+-		} else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) {
+-			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
+-				"size %zu/%zu\n", __func__, fw_hdr->size,
+-				sizeof(struct wl_fw_hdr));
+-			rc = -EBADF;
+-		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
+-			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
+-				  "%zu\n", __func__, fw->size);
+-			rc = -EBADF;
+-		} else {
+-			/* check if ucode section overruns firmware image */
+-			ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data;
+-			for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
+-			     !rc; entry++, ucode_hdr++) {
+-				if (ucode_hdr->offset + ucode_hdr->len >
+-				    fw->size) {
+-					wiphy_err(wl->wiphy,
+-						  "%s: conflicting bin/hdr\n",
+-						  __func__);
+-					rc = -EBADF;
+-				}
+-			}
+-		}
+-	}
+-	if (rc == 0 && wl->fw.fw_cnt != i) {
+-		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
+-			wl->fw.fw_cnt);
+-		rc = -EBADF;
+-	}
+-	return rc;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-bool wl_rfkill_set_hw_state(struct wl_info *wl)
+-{
+-	bool blocked = wlc_check_radio_disabled(wl->wlc);
+-
+-	WL_UNLOCK(wl);
+-	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
+-	if (blocked)
+-		wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
+-	WL_LOCK(wl);
+-	return blocked;
+-}
+-
+-/*
+- * precondition: perimeter lock has been acquired
+- */
+-void wl_msleep(struct wl_info *wl, uint ms)
+-{
+-	WL_UNLOCK(wl);
+-	msleep(ms);
+-	WL_LOCK(wl);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
+deleted file mode 100644
+index e703d8b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
++++ /dev/null
+@@ -1,85 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wl_mac80211_h_
+-#define _wl_mac80211_h_
+-
+-/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and
+- * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be
+- * submitted to workqueue instead of being on kernel timer
+- */
+-struct wl_timer {
+-	struct timer_list timer;
+-	struct wl_info *wl;
+-	void (*fn) (void *);
+-	void *arg;		/* argument to fn */
+-	uint ms;
+-	bool periodic;
+-	bool set;
+-	struct wl_timer *next;
+-#ifdef BCMDBG
+-	char *name;		/* Description of the timer */
+-#endif
+-};
+-
+-struct wl_if {
+-	uint subunit;		/* WDS/BSS unit */
+-	struct pci_dev *pci_dev;
+-};
+-
+-#define WL_MAX_FW		4
+-struct wl_firmware {
+-	u32 fw_cnt;
+-	const struct firmware *fw_bin[WL_MAX_FW];
+-	const struct firmware *fw_hdr[WL_MAX_FW];
+-	u32 hdr_num_entries[WL_MAX_FW];
+-};
+-
+-struct wl_info {
+-	struct wlc_pub *pub;		/* pointer to public wlc state */
+-	void *wlc;		/* pointer to private common os-independent data */
+-	u32 magic;
+-
+-	int irq;
+-
+-	spinlock_t lock;	/* per-device perimeter lock */
+-	spinlock_t isr_lock;	/* per-device ISR synchronization lock */
+-	uint bcm_bustype;	/* bus type */
+-	bool piomode;		/* set from insmod argument */
+-	void *regsva;		/* opaque chip registers virtual address */
+-	atomic_t callbacks;	/* # outstanding callback functions */
+-	struct wl_timer *timers;	/* timer cleanup queue */
+-	struct tasklet_struct tasklet;	/* dpc tasklet */
+-	bool resched;		/* dpc needs to be and is rescheduled */
+-#ifdef LINUXSTA_PS
+-	u32 pci_psstate[16];	/* pci ps-state save/restore */
+-#endif
+-	struct wl_firmware fw;
+-	struct wiphy *wiphy;
+-};
+-
+-#define WL_LOCK(wl)	spin_lock_bh(&(wl)->lock)
+-#define WL_UNLOCK(wl)	spin_unlock_bh(&(wl)->lock)
+-
+-/* locking from inside wl_isr */
+-#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0)
+-#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0)
+-
+-/* locking under WL_LOCK() to synchronize with wl_isr */
+-#define INT_LOCK(wl, flags)	spin_lock_irqsave(&(wl)->isr_lock, flags)
+-#define INT_UNLOCK(wl, flags)	spin_unlock_irqrestore(&(wl)->isr_lock, flags)
+-
+-#endif				/* _wl_mac80211_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h
+deleted file mode 100644
+index 6933fda..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h
++++ /dev/null
+@@ -1,49 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#define MIN_FW_SIZE 40000	/* minimum firmware file size in bytes */
+-#define MAX_FW_SIZE 150000
+-
+-#define UCODE_LOADER_API_VER 0
+-
+-struct d11init {
+-	u16 addr;
+-	u16 size;
+-	u32 value;
+-};
+-
+-extern struct d11init *d11lcn0bsinitvals24;
+-extern struct d11init *d11lcn0initvals24;
+-extern struct d11init *d11lcn1bsinitvals24;
+-extern struct d11init *d11lcn1initvals24;
+-extern struct d11init *d11lcn2bsinitvals24;
+-extern struct d11init *d11lcn2initvals24;
+-extern struct d11init *d11n0absinitvals16;
+-extern struct d11init *d11n0bsinitvals16;
+-extern struct d11init *d11n0initvals16;
+-extern u32 *bcm43xx_16_mimo;
+-extern u32 bcm43xx_16_mimosz;
+-extern u32 *bcm43xx_24_lcn;
+-extern u32 bcm43xx_24_lcnsz;
+-
+-extern int wl_ucode_data_init(struct wl_info *wl);
+-extern void wl_ucode_data_free(void);
+-
+-extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx);
+-extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data,
+-			      unsigned int idx);
+-extern void wl_ucode_free_buf(void *);
+-extern int  wl_check_firmwares(struct wl_info *wl);
+diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
+deleted file mode 100644
+index cc00dd1..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c
++++ /dev/null
+@@ -1,111 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/types.h>
+-#include <bcmdefs.h>
+-#include <wl_ucode.h>
+-
+-enum {
+-	D11UCODE_NAMETAG_START = 0,
+-	D11LCN0BSINITVALS24,
+-	D11LCN0INITVALS24,
+-	D11LCN1BSINITVALS24,
+-	D11LCN1INITVALS24,
+-	D11LCN2BSINITVALS24,
+-	D11LCN2INITVALS24,
+-	D11N0ABSINITVALS16,
+-	D11N0BSINITVALS16,
+-	D11N0INITVALS16,
+-	D11UCODE_OVERSIGHT16_MIMO,
+-	D11UCODE_OVERSIGHT16_MIMOSZ,
+-	D11UCODE_OVERSIGHT24_LCN,
+-	D11UCODE_OVERSIGHT24_LCNSZ,
+-	D11UCODE_OVERSIGHT_BOMMAJOR,
+-	D11UCODE_OVERSIGHT_BOMMINOR
+-};
+-
+-struct d11init *d11lcn0bsinitvals24;
+-struct d11init *d11lcn0initvals24;
+-struct d11init *d11lcn1bsinitvals24;
+-struct d11init *d11lcn1initvals24;
+-struct d11init *d11lcn2bsinitvals24;
+-struct d11init *d11lcn2initvals24;
+-struct d11init *d11n0absinitvals16;
+-struct d11init *d11n0bsinitvals16;
+-struct d11init *d11n0initvals16;
+-u32 *bcm43xx_16_mimo;
+-u32 bcm43xx_16_mimosz;
+-u32 *bcm43xx_24_lcn;
+-u32 bcm43xx_24_lcnsz;
+-u32 *bcm43xx_bommajor;
+-u32 *bcm43xx_bomminor;
+-
+-int wl_ucode_data_init(struct wl_info *wl)
+-{
+-	int rc;
+-	rc = wl_check_firmwares(wl);
+-
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
+-					     D11LCN0BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24,
+-					     D11LCN0INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
+-					     D11LCN1BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24,
+-					     D11LCN1INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
+-					     D11LCN2BSINITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24,
+-					     D11LCN2INITVALS24);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16,
+-					     D11N0ABSINITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16,
+-					     D11N0BSINITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16,
+-					     D11N0INITVALS16);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
+-					     D11UCODE_OVERSIGHT16_MIMO);
+-	rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz,
+-					      D11UCODE_OVERSIGHT16_MIMOSZ);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
+-					     D11UCODE_OVERSIGHT24_LCN);
+-	rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz,
+-					      D11UCODE_OVERSIGHT24_LCNSZ);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
+-					     D11UCODE_OVERSIGHT_BOMMAJOR);
+-	rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
+-					     D11UCODE_OVERSIGHT_BOMMINOR);
+-	return rc;
+-}
+-
+-void wl_ucode_data_free(void)
+-{
+-	wl_ucode_free_buf((void *)d11lcn0bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn0initvals24);
+-	wl_ucode_free_buf((void *)d11lcn1bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn1initvals24);
+-	wl_ucode_free_buf((void *)d11lcn2bsinitvals24);
+-	wl_ucode_free_buf((void *)d11lcn2initvals24);
+-	wl_ucode_free_buf((void *)d11n0absinitvals16);
+-	wl_ucode_free_buf((void *)d11n0bsinitvals16);
+-	wl_ucode_free_buf((void *)d11n0initvals16);
+-	wl_ucode_free_buf((void *)bcm43xx_16_mimo);
+-	wl_ucode_free_buf((void *)bcm43xx_24_lcn);
+-	wl_ucode_free_buf((void *)bcm43xx_bommajor);
+-	wl_ucode_free_buf((void *)bcm43xx_bomminor);
+-
+-	return;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
+deleted file mode 100644
+index 82c64cd..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
++++ /dev/null
+@@ -1,300 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-#include "wlc_rate.h"
+-#include "wlc_bsscfg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-
+-static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit);
+-static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg);
+-static struct wlc_pub *wlc_pub_malloc(uint unit,
+-				      uint *err, uint devid);
+-static void wlc_pub_mfree(struct wlc_pub *pub);
+-static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid);
+-
+-static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
+-{
+-	tunables->ntxd = NTXD;
+-	tunables->nrxd = NRXD;
+-	tunables->rxbufsz = RXBUFSZ;
+-	tunables->nrxbufpost = NRXBUFPOST;
+-	tunables->maxscb = MAXSCB;
+-	tunables->ampdunummpdu = AMPDU_NUM_MPDU;
+-	tunables->maxpktcb = MAXPKTCB;
+-	tunables->maxucodebss = WLC_MAX_UCODE_BSS;
+-	tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4;
+-	tunables->maxbss = MAXBSS;
+-	tunables->datahiwat = WLC_DATAHIWAT;
+-	tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT;
+-	tunables->rxbnd = RXBND;
+-	tunables->txsbnd = TXSBND;
+-}
+-
+-static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid)
+-{
+-	struct wlc_pub *pub;
+-
+-	pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC);
+-	if (pub == NULL) {
+-		*err = 1001;
+-		goto fail;
+-	}
+-
+-	pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC);
+-	if (pub->tunables == NULL) {
+-		*err = 1028;
+-		goto fail;
+-	}
+-
+-	/* need to init the tunables now */
+-	wlc_tunables_init(pub->tunables, devid);
+-
+-	pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
+-	if (pub->multicast == NULL) {
+-		*err = 1003;
+-		goto fail;
+-	}
+-
+-	return pub;
+-
+- fail:
+-	wlc_pub_mfree(pub);
+-	return NULL;
+-}
+-
+-static void wlc_pub_mfree(struct wlc_pub *pub)
+-{
+-	if (pub == NULL)
+-		return;
+-
+-	kfree(pub->multicast);
+-	kfree(pub->tunables);
+-	kfree(pub);
+-}
+-
+-static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit)
+-{
+-	struct wlc_bsscfg *cfg;
+-
+-	cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC);
+-	if (cfg == NULL)
+-		goto fail;
+-
+-	cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
+-	if (cfg->current_bss == NULL)
+-		goto fail;
+-
+-	return cfg;
+-
+- fail:
+-	wlc_bsscfg_mfree(cfg);
+-	return NULL;
+-}
+-
+-static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg)
+-{
+-	if (cfg == NULL)
+-		return;
+-
+-	kfree(cfg->maclist);
+-	kfree(cfg->current_bss);
+-	kfree(cfg);
+-}
+-
+-static void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
+-				 struct wlc_bsscfg *bsscfg)
+-{
+-	bsscfg->ID = wlc->next_bsscfg_ID;
+-	wlc->next_bsscfg_ID++;
+-}
+-
+-/*
+- * The common driver entry routine. Error codes should be unique
+- */
+-struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid)
+-{
+-	struct wlc_info *wlc;
+-
+-	wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC);
+-	if (wlc == NULL) {
+-		*err = 1002;
+-		goto fail;
+-	}
+-
+-	wlc->hwrxoff = WL_HWRXOFF;
+-
+-	/* allocate struct wlc_pub state structure */
+-	wlc->pub = wlc_pub_malloc(unit, err, devid);
+-	if (wlc->pub == NULL) {
+-		*err = 1003;
+-		goto fail;
+-	}
+-	wlc->pub->wlc = wlc;
+-
+-	/* allocate struct wlc_hw_info state structure */
+-
+-	wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC);
+-	if (wlc->hw == NULL) {
+-		*err = 1005;
+-		goto fail;
+-	}
+-	wlc->hw->wlc = wlc;
+-
+-	wlc->hw->bandstate[0] =
+-		kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC);
+-	if (wlc->hw->bandstate[0] == NULL) {
+-		*err = 1006;
+-		goto fail;
+-	} else {
+-		int i;
+-
+-		for (i = 1; i < MAXBANDS; i++) {
+-			wlc->hw->bandstate[i] = (struct wlc_hwband *)
+-			    ((unsigned long)wlc->hw->bandstate[0] +
+-			     (sizeof(struct wlc_hwband) * i));
+-		}
+-	}
+-
+-	wlc->modulecb =
+-		kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC);
+-	if (wlc->modulecb == NULL) {
+-		*err = 1009;
+-		goto fail;
+-	}
+-
+-	wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
+-	if (wlc->default_bss == NULL) {
+-		*err = 1010;
+-		goto fail;
+-	}
+-
+-	wlc->cfg = wlc_bsscfg_malloc(unit);
+-	if (wlc->cfg == NULL) {
+-		*err = 1011;
+-		goto fail;
+-	}
+-	wlc_bsscfg_ID_assign(wlc, wlc->cfg);
+-
+-	wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) *
+-				    (wlc->pub->tunables->maxpktcb + 1),
+-				    GFP_ATOMIC);
+-	if (wlc->pkt_callback == NULL) {
+-		*err = 1013;
+-		goto fail;
+-	}
+-
+-	wlc->wsec_def_keys[0] =
+-		kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC);
+-	if (wlc->wsec_def_keys[0] == NULL) {
+-		*err = 1015;
+-		goto fail;
+-	} else {
+-		int i;
+-		for (i = 1; i < WLC_DEFAULT_KEYS; i++) {
+-			wlc->wsec_def_keys[i] = (wsec_key_t *)
+-			    ((unsigned long)wlc->wsec_def_keys[0] +
+-			     (sizeof(wsec_key_t) * i));
+-		}
+-	}
+-
+-	wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC);
+-	if (wlc->protection == NULL) {
+-		*err = 1016;
+-		goto fail;
+-	}
+-
+-	wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC);
+-	if (wlc->stf == NULL) {
+-		*err = 1017;
+-		goto fail;
+-	}
+-
+-	wlc->bandstate[0] =
+-		kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC);
+-	if (wlc->bandstate[0] == NULL) {
+-		*err = 1025;
+-		goto fail;
+-	} else {
+-		int i;
+-
+-		for (i = 1; i < MAXBANDS; i++) {
+-			wlc->bandstate[i] =
+-			    (struct wlcband *) ((unsigned long)wlc->bandstate[0]
+-			    + (sizeof(struct wlcband)*i));
+-		}
+-	}
+-
+-	wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC);
+-	if (wlc->corestate == NULL) {
+-		*err = 1026;
+-		goto fail;
+-	}
+-
+-	wlc->corestate->macstat_snapshot =
+-		kzalloc(sizeof(macstat_t), GFP_ATOMIC);
+-	if (wlc->corestate->macstat_snapshot == NULL) {
+-		*err = 1027;
+-		goto fail;
+-	}
+-
+-	return wlc;
+-
+- fail:
+-	wlc_detach_mfree(wlc);
+-	return NULL;
+-}
+-
+-void wlc_detach_mfree(struct wlc_info *wlc)
+-{
+-	if (wlc == NULL)
+-		return;
+-
+-	wlc_bsscfg_mfree(wlc->cfg);
+-	wlc_pub_mfree(wlc->pub);
+-	kfree(wlc->modulecb);
+-	kfree(wlc->default_bss);
+-	kfree(wlc->pkt_callback);
+-	kfree(wlc->wsec_def_keys[0]);
+-	kfree(wlc->protection);
+-	kfree(wlc->stf);
+-	kfree(wlc->bandstate[0]);
+-	kfree(wlc->corestate->macstat_snapshot);
+-	kfree(wlc->corestate);
+-	kfree(wlc->hw->bandstate[0]);
+-	kfree(wlc->hw);
+-
+-	/* free the wlc */
+-	kfree(wlc);
+-	wlc = NULL;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
+deleted file mode 100644
+index 95f951e..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
++++ /dev/null
+@@ -1,18 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid);
+-extern void wlc_detach_mfree(struct wlc_info *wlc);
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+deleted file mode 100644
+index 85ad700..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
++++ /dev/null
+@@ -1,1253 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <net/mac80211.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-#include <d11.h>
+-
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_antsel.h"
+-#include "wl_export.h"
+-#include "wl_dbg.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_ampdu.h"
+-
+-#define AMPDU_MAX_MPDU		32	/* max number of mpdus in an ampdu */
+-#define AMPDU_NUM_MPDU_LEGACY	16	/* max number of mpdus in an ampdu to a legacy */
+-#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
+-#define AMPDU_TX_BA_DEF_WSIZE	64	/* default Tx ba window size (in pdu) */
+-#define AMPDU_RX_BA_DEF_WSIZE   64	/* max Rx ba window size (in pdu) */
+-#define AMPDU_RX_BA_MAX_WSIZE   64	/* default Rx ba window size (in pdu) */
+-#define	AMPDU_MAX_DUR		5	/* max dur of tx ampdu (in msec) */
+-#define AMPDU_DEF_RETRY_LIMIT	5	/* default tx retry limit */
+-#define AMPDU_DEF_RR_RETRY_LIMIT	2	/* default tx retry limit at reg rate */
+-#define AMPDU_DEF_TXPKT_WEIGHT	2	/* default weight of ampdu in txfifo */
+-#define AMPDU_DEF_FFPLD_RSVD	2048	/* default ffpld reserved bytes */
+-#define AMPDU_INI_FREE		10	/* # of inis to be freed on detach */
+-#define	AMPDU_SCB_MAX_RELEASE	20	/* max # of mpdus released at a time */
+-
+-#define NUM_FFPLD_FIFO 4	/* number of fifo concerned by pre-loading */
+-#define FFPLD_TX_MAX_UNFL   200	/* default value of the average number of ampdu
+-				 * without underflows
+-				 */
+-#define FFPLD_MPDU_SIZE 1800	/* estimate of maximum mpdu size */
+-#define FFPLD_MAX_MCS 23	/* we don't deal with mcs 32 */
+-#define FFPLD_PLD_INCR 1000	/* increments in bytes */
+-#define FFPLD_MAX_AMPDU_CNT 5000	/* maximum number of ampdu we
+-					 * accumulate between resets.
+-					 */
+-
+-#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
+-
+-/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
+-#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
+-	AMPDU_DELIMITER_LEN + 3\
+-	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
+-
+-/* structure to hold tx fifo information and pre-loading state
+- * counters specific to tx underflows of ampdus
+- * some counters might be redundant with the ones in wlc or ampdu structures.
+- * This allows to maintain a specific state independently of
+- * how often and/or when the wlc counters are updated.
+- */
+-typedef struct wlc_fifo_info {
+-	u16 ampdu_pld_size;	/* number of bytes to be pre-loaded */
+-	u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];	/* per-mcs max # of mpdus in an ampdu */
+-	u16 prev_txfunfl;	/* num of underflows last read from the HW macstats counter */
+-	u32 accum_txfunfl;	/* num of underflows since we modified pld params */
+-	u32 accum_txampdu;	/* num of tx ampdu since we modified pld params  */
+-	u32 prev_txampdu;	/* previous reading of tx ampdu */
+-	u32 dmaxferrate;	/* estimated dma avg xfer rate in kbits/sec */
+-} wlc_fifo_info_t;
+-
+-/* AMPDU module specific state */
+-struct ampdu_info {
+-	struct wlc_info *wlc;	/* pointer to main wlc structure */
+-	int scb_handle;		/* scb cubby handle to retrieve data from scb */
+-	u8 ini_enable[AMPDU_MAX_SCB_TID];	/* per-tid initiator enable/disable of ampdu */
+-	u8 ba_tx_wsize;	/* Tx ba window size (in pdu) */
+-	u8 ba_rx_wsize;	/* Rx ba window size (in pdu) */
+-	u8 retry_limit;	/* mpdu transmit retry limit */
+-	u8 rr_retry_limit;	/* mpdu transmit retry limit at regular rate */
+-	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];	/* per-tid mpdu transmit retry limit */
+-	/* per-tid mpdu transmit retry limit at regular rate */
+-	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
+-	u8 mpdu_density;	/* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */
+-	s8 max_pdu;		/* max pdus allowed in ampdu */
+-	u8 dur;		/* max duration of an ampdu (in msec) */
+-	u8 txpkt_weight;	/* weight of ampdu in txfifo; reduces rate lag */
+-	u8 rx_factor;	/* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */
+-	u32 ffpld_rsvd;	/* number of bytes to reserve for preload */
+-	u32 max_txlen[MCS_TABLE_SIZE][2][2];	/* max size of ampdu per mcs, bw and sgi */
+-	void *ini_free[AMPDU_INI_FREE];	/* array of ini's to be freed on detach */
+-	bool mfbr;		/* enable multiple fallback rate */
+-	u32 tx_max_funl;	/* underflows should be kept such that
+-				 * (tx_max_funfl*underflows) < tx frames
+-				 */
+-	wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO];	/* table of fifo infos  */
+-
+-};
+-
+-/* used for flushing ampdu packets */
+-struct cb_del_ampdu_pars {
+-	struct ieee80211_sta *sta;
+-	u16 tid;
+-};
+-
+-#define AMPDU_CLEANUPFLAG_RX   (0x1)
+-#define AMPDU_CLEANUPFLAG_TX   (0x2)
+-
+-#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu))
+-#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid]))
+-
+-static void wlc_ffpld_init(struct ampdu_info *ampdu);
+-static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f);
+-static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
+-
+-static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
+-						   scb_ampdu_t *scb_ampdu,
+-						   u8 tid, bool override);
+-static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur);
+-static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb);
+-static void scb_ampdu_update_config_all(struct ampdu_info *ampdu);
+-
+-#define wlc_ampdu_txflowcontrol(a, b, c)	do {} while (0)
+-
+-static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu,
+-					  struct scb *scb,
+-					  struct sk_buff *p, tx_status_t *txs,
+-					  u32 frmtxstatus, u32 frmtxstatus2);
+-static bool wlc_ampdu_cap(struct ampdu_info *ampdu);
+-static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on);
+-
+-struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc)
+-{
+-	struct ampdu_info *ampdu;
+-	int i;
+-
+-	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
+-	if (!ampdu) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n",
+-			  wlc->pub->unit);
+-		return NULL;
+-	}
+-	ampdu->wlc = wlc;
+-
+-	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
+-		ampdu->ini_enable[i] = true;
+-	/* Disable ampdu for VO by default */
+-	ampdu->ini_enable[PRIO_8021D_VO] = false;
+-	ampdu->ini_enable[PRIO_8021D_NC] = false;
+-
+-	/* Disable ampdu for BK by default since not enough fifo space */
+-	ampdu->ini_enable[PRIO_8021D_NONE] = false;
+-	ampdu->ini_enable[PRIO_8021D_BK] = false;
+-
+-	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
+-	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
+-	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
+-	ampdu->max_pdu = AUTO;
+-	ampdu->dur = AMPDU_MAX_DUR;
+-	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
+-
+-	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
+-	/* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */
+-	if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
+-		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
+-	else
+-		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
+-	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
+-	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
+-
+-	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
+-		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
+-		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
+-	}
+-
+-	ampdu_update_max_txlen(ampdu, ampdu->dur);
+-	ampdu->mfbr = false;
+-	/* try to set ampdu to the default value */
+-	wlc_ampdu_set(ampdu, wlc->pub->_ampdu);
+-
+-	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
+-	wlc_ffpld_init(ampdu);
+-
+-	return ampdu;
+-}
+-
+-void wlc_ampdu_detach(struct ampdu_info *ampdu)
+-{
+-	int i;
+-
+-	if (!ampdu)
+-		return;
+-
+-	/* free all ini's which were to be freed on callbacks which were never called */
+-	for (i = 0; i < AMPDU_INI_FREE; i++) {
+-		kfree(ampdu->ini_free[i]);
+-	}
+-
+-	wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu);
+-	kfree(ampdu);
+-}
+-
+-static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb)
+-{
+-	scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	int i;
+-
+-	scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu;
+-
+-	/* go back to legacy size if some preloading is occurring */
+-	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
+-		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
+-			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
+-	}
+-
+-	/* apply user override */
+-	if (ampdu->max_pdu != AUTO)
+-		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
+-
+-	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE);
+-
+-	if (scb_ampdu->max_rxlen)
+-		scb_ampdu->release =
+-		    min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600);
+-
+-	scb_ampdu->release = min(scb_ampdu->release,
+-				 ampdu->fifo_tb[TX_AC_BE_FIFO].
+-				 mcs2ampdu_table[FFPLD_MAX_MCS]);
+-}
+-
+-static void scb_ampdu_update_config_all(struct ampdu_info *ampdu)
+-{
+-	scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
+-}
+-
+-static void wlc_ffpld_init(struct ampdu_info *ampdu)
+-{
+-	int i, j;
+-	wlc_fifo_info_t *fifo;
+-
+-	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
+-		fifo = (ampdu->fifo_tb + j);
+-		fifo->ampdu_pld_size = 0;
+-		for (i = 0; i <= FFPLD_MAX_MCS; i++)
+-			fifo->mcs2ampdu_table[i] = 255;
+-		fifo->dmaxferrate = 0;
+-		fifo->accum_txampdu = 0;
+-		fifo->prev_txfunfl = 0;
+-		fifo->accum_txfunfl = 0;
+-
+-	}
+-}
+-
+-/* evaluate the dma transfer rate using the tx underflows as feedback.
+- * If necessary, increase tx fifo preloading. If not enough,
+- * decrease maximum ampdu size for each mcs till underflows stop
+- * Return 1 if pre-loading not active, -1 if not an underflow event,
+- * 0 if pre-loading module took care of the event.
+- */
+-static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid)
+-{
+-	struct ampdu_info *ampdu = wlc->ampdu;
+-	u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
+-	u32 txunfl_ratio;
+-	u8 max_mpdu;
+-	u32 current_ampdu_cnt = 0;
+-	u16 max_pld_size;
+-	u32 new_txunfl;
+-	wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid);
+-	uint xmtfifo_sz;
+-	u16 cur_txunfl;
+-
+-	/* return if we got here for a different reason than underflows */
+-	cur_txunfl =
+-	    wlc_read_shm(wlc,
+-			 M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid]));
+-	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
+-	if (new_txunfl == 0) {
+-		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
+-		return -1;
+-	}
+-	fifo->prev_txfunfl = cur_txunfl;
+-
+-	if (!ampdu->tx_max_funl)
+-		return 1;
+-
+-	/* check if fifo is big enough */
+-	if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) {
+-		return -1;
+-	}
+-
+-	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
+-		return 1;
+-
+-	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
+-	fifo->accum_txfunfl += new_txunfl;
+-
+-	/* we need to wait for at least 10 underflows */
+-	if (fifo->accum_txfunfl < 10)
+-		return 0;
+-
+-	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
+-		current_ampdu_cnt, fifo->accum_txfunfl);
+-
+-	/*
+-	   compute the current ratio of tx unfl per ampdu.
+-	   When the current ampdu count becomes too
+-	   big while the ratio remains small, we reset
+-	   the current count in order to not
+-	   introduce too big of a latency in detecting a
+-	   large amount of tx underflows later.
+-	 */
+-
+-	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
+-
+-	if (txunfl_ratio > ampdu->tx_max_funl) {
+-		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) {
+-			fifo->accum_txfunfl = 0;
+-		}
+-		return 0;
+-	}
+-	max_mpdu =
+-	    min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+-
+-	/* In case max value max_pdu is already lower than
+-	   the fifo depth, there is nothing more we can do.
+-	 */
+-
+-	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
+-		fifo->accum_txfunfl = 0;
+-		return 0;
+-	}
+-
+-	if (fifo->ampdu_pld_size < max_pld_size) {
+-
+-		/* increment by TX_FIFO_PLD_INC bytes */
+-		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
+-		if (fifo->ampdu_pld_size > max_pld_size)
+-			fifo->ampdu_pld_size = max_pld_size;
+-
+-		/* update scb release size */
+-		scb_ampdu_update_config_all(ampdu);
+-
+-		/*
+-		   compute a new dma xfer rate for max_mpdu @ max mcs.
+-		   This is the minimum dma rate that
+-		   can achieve no underflow condition for the current mpdu size.
+-		 */
+-		/* note : we divide/multiply by 100 to avoid integer overflows */
+-		fifo->dmaxferrate =
+-		    (((phy_rate / 100) *
+-		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+-		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+-
+-		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
+-			"pre-load size %d\n",
+-			fifo->dmaxferrate, fifo->ampdu_pld_size);
+-	} else {
+-
+-		/* decrease ampdu size */
+-		if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
+-			if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
+-				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
+-				    AMPDU_NUM_MPDU_LEGACY - 1;
+-			else
+-				fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
+-
+-			/* recompute the table */
+-			wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid);
+-
+-			/* update scb release size */
+-			scb_ampdu_update_config_all(ampdu);
+-		}
+-	}
+-	fifo->accum_txfunfl = 0;
+-	return 0;
+-}
+-
+-static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
+-{
+-	int i;
+-	u32 phy_rate, dma_rate, tmp;
+-	u8 max_mpdu;
+-	wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f);
+-
+-	/* recompute the dma rate */
+-	/* note : we divide/multiply by 100 to avoid integer overflows */
+-	max_mpdu =
+-	    min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY);
+-	phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false);
+-	dma_rate =
+-	    (((phy_rate / 100) *
+-	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
+-	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
+-	fifo->dmaxferrate = dma_rate;
+-
+-	/* fill up the mcs2ampdu table; do not recalc the last mcs */
+-	dma_rate = dma_rate >> 7;
+-	for (i = 0; i < FFPLD_MAX_MCS; i++) {
+-		/* shifting to keep it within integer range */
+-		phy_rate = MCS_RATE(i, true, false) >> 7;
+-		if (phy_rate > dma_rate) {
+-			tmp = ((fifo->ampdu_pld_size * phy_rate) /
+-			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
+-			tmp = min_t(u32, tmp, 255);
+-			fifo->mcs2ampdu_table[i] = (u8) tmp;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
+-	      uint prec)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 tid = (u8) (p->priority);
+-
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-
+-	/* initialize initiator on first packet; sends addba req */
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	if (ini->magic != INI_MAGIC) {
+-		ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
+-	}
+-	return;
+-}
+-
+-int
+-wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
+-	      struct sk_buff **pdu, int prec)
+-{
+-	struct wlc_info *wlc;
+-	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
+-	u8 tid, ndelim;
+-	int err = 0;
+-	u8 preamble_type = WLC_GF_PREAMBLE;
+-	u8 fbr_preamble_type = WLC_GF_PREAMBLE;
+-	u8 rts_preamble_type = WLC_LONG_PREAMBLE;
+-	u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE;
+-
+-	bool rr = true, fbr = false;
+-	uint i, count = 0, fifo, seg_cnt = 0;
+-	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
+-	u32 ampdu_len, maxlen = 0;
+-	d11txh_t *txh = NULL;
+-	u8 *plcp;
+-	struct ieee80211_hdr *h;
+-	struct scb *scb;
+-	scb_ampdu_t *scb_ampdu;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 mcs = 0;
+-	bool use_rts = false, use_cts = false;
+-	ratespec_t rspec = 0, rspec_fallback = 0;
+-	ratespec_t rts_rspec = 0, rts_rspec_fallback = 0;
+-	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+-	struct ieee80211_rts *rts;
+-	u8 rr_retry_limit;
+-	wlc_fifo_info_t *f;
+-	bool fbr_iscck;
+-	struct ieee80211_tx_info *tx_info;
+-	u16 qlen;
+-	struct wiphy *wiphy;
+-
+-	wlc = ampdu->wlc;
+-	wiphy = wlc->wiphy;
+-	p = *pdu;
+-
+-	tid = (u8) (p->priority);
+-
+-	f = ampdu->fifo_tb + prio2fifo[tid];
+-
+-	scb = wlc->pub->global_scb;
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	ini = &scb_ampdu->ini[tid];
+-
+-	/* Let pressure continue to build ... */
+-	qlen = pktq_plen(&qi->q, prec);
+-	if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
+-		return -EBUSY;
+-	}
+-
+-	wlc_ampdu_agg(ampdu, scb, p, tid);
+-
+-	if (wlc->block_datafifo) {
+-		wiphy_err(wiphy, "%s: Fifo blocked\n", __func__);
+-		return -EBUSY;
+-	}
+-	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+-	ampdu_len = 0;
+-	dma_len = 0;
+-	while (p) {
+-		struct ieee80211_tx_rate *txrate;
+-
+-		tx_info = IEEE80211_SKB_CB(p);
+-		txrate = tx_info->status.rates;
+-
+-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-			err = wlc_prep_pdu(wlc, p, &fifo);
+-		} else {
+-			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
+-			*pdu = NULL;
+-			err = 0;
+-			break;
+-		}
+-
+-		if (err) {
+-			if (err == -EBUSY) {
+-				wiphy_err(wiphy, "wl%d: wlc_sendampdu: "
+-					  "prep_xdu retry; seq 0x%x\n",
+-					  wlc->pub->unit, seq);
+-				*pdu = p;
+-				break;
+-			}
+-
+-			/* error in the packet; reject it */
+-			wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu "
+-				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
+-			*pdu = NULL;
+-			break;
+-		}
+-
+-		/* pkt is good to be aggregated */
+-		txh = (d11txh_t *) p->data;
+-		plcp = (u8 *) (txh + 1);
+-		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
+-		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
+-		index = TX_SEQ_TO_INDEX(seq);
+-
+-		/* check mcl fields and test whether it can be agg'd */
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		mcl &= ~TXC_AMPDU_MASK;
+-		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
+-		txh->PreloadSize = 0;	/* always default to 0 */
+-
+-		/*  Handle retry limits */
+-		if (txrate[0].count <= rr_retry_limit) {
+-			txrate[0].count++;
+-			rr = true;
+-			fbr = false;
+-		} else {
+-			fbr = true;
+-			rr = false;
+-			txrate[1].count++;
+-		}
+-
+-		/* extract the length info */
+-		len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+-		    : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+-
+-		/* retrieve null delimiter count */
+-		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+-		seg_cnt += 1;
+-
+-		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
+-			wlc->pub->unit, count, len);
+-
+-		/*
+-		 * aggregateable mpdu. For ucode/hw agg,
+-		 * test whether need to break or change the epoch
+-		 */
+-		if (count == 0) {
+-			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
+-			/* refill the bits since might be a retx mpdu */
+-			mcl |= TXC_STARTMSDU;
+-			rts = (struct ieee80211_rts *)&txh->rts_frame;
+-
+-			if (ieee80211_is_rts(rts->frame_control)) {
+-				mcl |= TXC_SENDRTS;
+-				use_rts = true;
+-			}
+-			if (ieee80211_is_cts(rts->frame_control)) {
+-				mcl |= TXC_SENDCTS;
+-				use_cts = true;
+-			}
+-		} else {
+-			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
+-			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
+-		}
+-
+-		len = roundup(len, 4);
+-		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
+-
+-		dma_len += (u16) bcm_pkttotlen(p);
+-
+-		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
+-			" seg_cnt %d null delim %d\n",
+-			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
+-
+-		txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-		/* this packet is added */
+-		pkt[count++] = p;
+-
+-		/* patch the first MPDU */
+-		if (count == 1) {
+-			u8 plcp0, plcp3, is40, sgi;
+-			struct ieee80211_sta *sta;
+-
+-			sta = tx_info->control.sta;
+-
+-			if (rr) {
+-				plcp0 = plcp[0];
+-				plcp3 = plcp[3];
+-			} else {
+-				plcp0 = txh->FragPLCPFallback[0];
+-				plcp3 = txh->FragPLCPFallback[3];
+-
+-			}
+-			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
+-			sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
+-			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
+-			maxlen =
+-			    min(scb_ampdu->max_rxlen,
+-				ampdu->max_txlen[mcs][is40][sgi]);
+-
+-			/* XXX Fix me to honor real max_rxlen */
+-			/* can fix this as soon as ampdu_action() in mac80211.h
+-			 * gets extra u8buf_size par */
+-			maxlen = 64 * 1024;
+-
+-			if (is40)
+-				mimo_ctlchbw =
+-				    CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+-				    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+-
+-			/* rebuild the rspec and rspec_fallback */
+-			rspec = RSPEC_MIMORATE;
+-			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
+-			if (plcp[0] & MIMO_PLCP_40MHZ)
+-				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+-
+-			if (fbr_iscck)	/* CCK */
+-				rspec_fallback =
+-				    CCK_RSPEC(CCK_PHY2MAC_RATE
+-					      (txh->FragPLCPFallback[0]));
+-			else {	/* MIMO */
+-				rspec_fallback = RSPEC_MIMORATE;
+-				rspec_fallback |=
+-				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
+-				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
+-					rspec_fallback |=
+-					    (PHY_TXC1_BW_40MHZ <<
+-					     RSPEC_BW_SHIFT);
+-			}
+-
+-			if (use_rts || use_cts) {
+-				rts_rspec =
+-				    wlc_rspec_to_rts_rspec(wlc, rspec, false,
+-							   mimo_ctlchbw);
+-				rts_rspec_fallback =
+-				    wlc_rspec_to_rts_rspec(wlc, rspec_fallback,
+-							   false, mimo_ctlchbw);
+-			}
+-		}
+-
+-		/* if (first mpdu for host agg) */
+-		/* test whether to add more */
+-		if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) &&
+-		    (count == f->mcs2ampdu_table[mcs])) {
+-			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
+-				" ampdu at %d for mcs %d\n",
+-				wlc->pub->unit, count, mcs);
+-			break;
+-		}
+-
+-		if (count == scb_ampdu->max_pdu) {
+-			break;
+-		}
+-
+-		/* check to see if the next pkt is a candidate for aggregation */
+-		p = pktq_ppeek(&qi->q, prec);
+-		tx_info = IEEE80211_SKB_CB(p);	/* tx_info must be checked with current p */
+-
+-		if (p) {
+-			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
+-			    ((u8) (p->priority) == tid)) {
+-
+-				plen =
+-				    bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD;
+-				plen = max(scb_ampdu->min_len, plen);
+-
+-				if ((plen + ampdu_len) > maxlen) {
+-					p = NULL;
+-					wiphy_err(wiphy, "%s: Bogus plen #1\n",
+-						__func__);
+-					continue;
+-				}
+-
+-				/* check if there are enough descriptors available */
+-				if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) {
+-					wiphy_err(wiphy, "%s: No fifo space  "
+-						  "!!\n", __func__);
+-					p = NULL;
+-					continue;
+-				}
+-				p = bcm_pktq_pdeq(&qi->q, prec);
+-			} else {
+-				p = NULL;
+-			}
+-		}
+-	}			/* end while(p) */
+-
+-	ini->tx_in_transit += count;
+-
+-	if (count) {
+-		/* patch up the last txh */
+-		txh = (d11txh_t *) pkt[count - 1]->data;
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		mcl &= ~TXC_AMPDU_MASK;
+-		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
+-		txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-		/* remove the null delimiter after last mpdu */
+-		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
+-		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
+-		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
+-
+-		/* remove the pad len from last mpdu */
+-		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
+-		len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
+-		    : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
+-		ampdu_len -= roundup(len, 4) - len;
+-
+-		/* patch up the first txh & plcp */
+-		txh = (d11txh_t *) pkt[0]->data;
+-		plcp = (u8 *) (txh + 1);
+-
+-		WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
+-		/* mark plcp to indicate ampdu */
+-		WLC_SET_MIMO_PLCP_AMPDU(plcp);
+-
+-		/* reset the mixed mode header durations */
+-		if (txh->MModeLen) {
+-			u16 mmodelen =
+-			    wlc_calc_lsig_len(wlc, rspec, ampdu_len);
+-			txh->MModeLen = cpu_to_le16(mmodelen);
+-			preamble_type = WLC_MM_PREAMBLE;
+-		}
+-		if (txh->MModeFbrLen) {
+-			u16 mmfbrlen =
+-			    wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len);
+-			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
+-			fbr_preamble_type = WLC_MM_PREAMBLE;
+-		}
+-
+-		/* set the preload length */
+-		if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) {
+-			dma_len = min(dma_len, f->ampdu_pld_size);
+-			txh->PreloadSize = cpu_to_le16(dma_len);
+-		} else
+-			txh->PreloadSize = 0;
+-
+-		mch = le16_to_cpu(txh->MacTxControlHigh);
+-
+-		/* update RTS dur fields */
+-		if (use_rts || use_cts) {
+-			u16 durid;
+-			rts = (struct ieee80211_rts *)&txh->rts_frame;
+-			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
+-			    TXC_PREAMBLE_RTS_MAIN_SHORT)
+-				rts_preamble_type = WLC_SHORT_PREAMBLE;
+-
+-			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
+-			    TXC_PREAMBLE_RTS_FB_SHORT)
+-				rts_fbr_preamble_type = WLC_SHORT_PREAMBLE;
+-
+-			durid =
+-			    wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec,
+-						   rspec, rts_preamble_type,
+-						   preamble_type, ampdu_len,
+-						   true);
+-			rts->duration = cpu_to_le16(durid);
+-			durid = wlc_compute_rtscts_dur(wlc, use_cts,
+-						       rts_rspec_fallback,
+-						       rspec_fallback,
+-						       rts_fbr_preamble_type,
+-						       fbr_preamble_type,
+-						       ampdu_len, true);
+-			txh->RTSDurFallback = cpu_to_le16(durid);
+-			/* set TxFesTimeNormal */
+-			txh->TxFesTimeNormal = rts->duration;
+-			/* set fallback rate version of TxFesTimeNormal */
+-			txh->TxFesTimeFallback = txh->RTSDurFallback;
+-		}
+-
+-		/* set flag and plcp for fallback rate */
+-		if (fbr) {
+-			mch |= TXC_AMPDU_FBR;
+-			txh->MacTxControlHigh = cpu_to_le16(mch);
+-			WLC_SET_MIMO_PLCP_AMPDU(plcp);
+-			WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
+-		}
+-
+-		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
+-			wlc->pub->unit, count, ampdu_len);
+-
+-		/* inform rate_sel if it this is a rate probe pkt */
+-		frameid = le16_to_cpu(txh->TxFrameID);
+-		if (frameid & TXFID_RATE_PROBE_MASK) {
+-			wiphy_err(wiphy, "%s: XXX what to do with "
+-				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
+-		}
+-		for (i = 0; i < count; i++)
+-			wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1),
+-				   ampdu->txpkt_weight);
+-
+-	}
+-	/* endif (count) */
+-	return err;
+-}
+-
+-void
+-wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
+-		     struct sk_buff *p, tx_status_t *txs)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	struct wlc_info *wlc = ampdu->wlc;
+-	scb_ampdu_tid_ini_t *ini;
+-	u32 s1 = 0, s2 = 0;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	tx_info = IEEE80211_SKB_CB(p);
+-
+-	/* BMAC_NOTE: For the split driver, second level txstatus comes later
+-	 * So if the ACK was received then wait for the second level else just
+-	 * call the first one
+-	 */
+-	if (txs->status & TX_STATUS_ACK_RCV) {
+-		u8 status_delay = 0;
+-
+-		/* wait till the next 8 bytes of txstatus is available */
+-		while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) {
+-			udelay(1);
+-			status_delay++;
+-			if (status_delay > 10) {
+-				return; /* error condition */
+-			}
+-		}
+-
+-		s2 = R_REG(&wlc->regs->frmtxstatus2);
+-	}
+-
+-	if (likely(scb)) {
+-		scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-		ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
+-		wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
+-	} else {
+-		/* loop through all pkts and free */
+-		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
+-		d11txh_t *txh;
+-		u16 mcl;
+-		while (p) {
+-			tx_info = IEEE80211_SKB_CB(p);
+-			txh = (d11txh_t *) p->data;
+-			mcl = le16_to_cpu(txh->MacTxControlLow);
+-			bcm_pkt_buf_free_skb(p);
+-			/* break out if last packet of ampdu */
+-			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
+-			    TXC_AMPDU_LAST)
+-				break;
+-			p = GETNEXTTXP(wlc, queue);
+-		}
+-		wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+-	}
+-	wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
+-}
+-
+-static void
+-rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info,
+-	    tx_status_t *txs, u8 mcs)
+-{
+-	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
+-	int i;
+-
+-	/* clear the rest of the rates */
+-	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+-		txrate[i].idx = -1;
+-		txrate[i].count = 0;
+-	}
+-}
+-
+-#define SHORTNAME "AMPDU status"
+-
+-static void
+-wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
+-			      struct sk_buff *p, tx_status_t *txs,
+-			      u32 s1, u32 s2)
+-{
+-	scb_ampdu_t *scb_ampdu;
+-	struct wlc_info *wlc = ampdu->wlc;
+-	scb_ampdu_tid_ini_t *ini;
+-	u8 bitmap[8], queue, tid;
+-	d11txh_t *txh;
+-	u8 *plcp;
+-	struct ieee80211_hdr *h;
+-	u16 seq, start_seq = 0, bindex, index, mcl;
+-	u8 mcs = 0;
+-	bool ba_recd = false, ack_recd = false;
+-	u8 suc_mpdu = 0, tot_mpdu = 0;
+-	uint supr_status;
+-	bool update_rate = true, retry = true, tx_error = false;
+-	u16 mimoantsel = 0;
+-	u8 antselid = 0;
+-	u8 retry_limit, rr_retry_limit;
+-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-#ifdef BCMDBG
+-	u8 hole[AMPDU_MAX_MPDU];
+-	memset(hole, 0, sizeof(hole));
+-#endif
+-
+-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
+-	tid = (u8) (p->priority);
+-
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	retry_limit = ampdu->retry_limit_tid[tid];
+-	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
+-	memset(bitmap, 0, sizeof(bitmap));
+-	queue = txs->frameid & TXFID_QUEUE_MASK;
+-	supr_status = txs->status & TX_STATUS_SUPR_MASK;
+-
+-	if (txs->status & TX_STATUS_ACK_RCV) {
+-		if (TX_STATUS_SUPR_UF == supr_status) {
+-			update_rate = false;
+-		}
+-
+-		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
+-		start_seq = txs->sequence >> SEQNUM_SHIFT;
+-		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
+-		    TX_STATUS_BA_BMAP03_SHIFT;
+-
+-		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
+-		WARN_ON(!(s1 & TX_STATUS_AMPDU));
+-
+-		bitmap[0] |=
+-		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
+-		    TX_STATUS_BA_BMAP47_SHIFT;
+-		bitmap[1] = (s1 >> 8) & 0xff;
+-		bitmap[2] = (s1 >> 16) & 0xff;
+-		bitmap[3] = (s1 >> 24) & 0xff;
+-
+-		bitmap[4] = s2 & 0xff;
+-		bitmap[5] = (s2 >> 8) & 0xff;
+-		bitmap[6] = (s2 >> 16) & 0xff;
+-		bitmap[7] = (s2 >> 24) & 0xff;
+-
+-		ba_recd = true;
+-	} else {
+-		if (supr_status) {
+-			update_rate = false;
+-			if (supr_status == TX_STATUS_SUPR_BADCH) {
+-				wiphy_err(wiphy, "%s: Pkt tx suppressed, "
+-					  "illegal channel possibly %d\n",
+-					  __func__, CHSPEC_CHANNEL(
+-					  wlc->default_bss->chanspec));
+-			} else {
+-				if (supr_status != TX_STATUS_SUPR_FRAG)
+-					wiphy_err(wiphy, "%s: wlc_ampdu_dotx"
+-						  "status:supr_status 0x%x\n",
+-						 __func__, supr_status);
+-			}
+-			/* no need to retry for badch; will fail again */
+-			if (supr_status == TX_STATUS_SUPR_BADCH ||
+-			    supr_status == TX_STATUS_SUPR_EXPTIME) {
+-				retry = false;
+-			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
+-				/* TX underflow : try tuning pre-loading or ampdu size */
+-			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
+-				/* if there were underflows, but pre-loading is not active,
+-				   notify rate adaptation.
+-				 */
+-				if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid])
+-				    > 0) {
+-					tx_error = true;
+-				}
+-			}
+-		} else if (txs->phyerr) {
+-			update_rate = false;
+-			wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy "
+-				  "error (0x%x)\n", wlc->pub->unit,
+-				  txs->phyerr);
+-
+-			if (WL_ERROR_ON()) {
+-				bcm_prpkt("txpkt (AMPDU)", p);
+-				wlc_print_txdesc((d11txh_t *) p->data);
+-			}
+-			wlc_print_txstatus(txs);
+-		}
+-	}
+-
+-	/* loop through all pkts and retry if not acked */
+-	while (p) {
+-		tx_info = IEEE80211_SKB_CB(p);
+-		txh = (d11txh_t *) p->data;
+-		mcl = le16_to_cpu(txh->MacTxControlLow);
+-		plcp = (u8 *) (txh + 1);
+-		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
+-		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
+-
+-		if (tot_mpdu == 0) {
+-			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
+-			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
+-		}
+-
+-		index = TX_SEQ_TO_INDEX(seq);
+-		ack_recd = false;
+-		if (ba_recd) {
+-			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
+-			BCMMSG(wlc->wiphy, "tid %d seq %d,"
+-				" start_seq %d, bindex %d set %d, index %d\n",
+-				tid, seq, start_seq, bindex,
+-				isset(bitmap, bindex), index);
+-			/* if acked then clear bit and free packet */
+-			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
+-			    && isset(bitmap, bindex)) {
+-				ini->tx_in_transit--;
+-				ini->txretry[index] = 0;
+-
+-				/* ampdu_ack_len: number of acked aggregated frames */
+-				/* ampdu_len: number of aggregated frames */
+-				rate_status(wlc, tx_info, txs, mcs);
+-				tx_info->flags |= IEEE80211_TX_STAT_ACK;
+-				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+-				tx_info->status.ampdu_ack_len =
+-					tx_info->status.ampdu_len = 1;
+-
+-				skb_pull(p, D11_PHY_HDR_LEN);
+-				skb_pull(p, D11_TXH_LEN);
+-
+-				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+-							    p);
+-				ack_recd = true;
+-				suc_mpdu++;
+-			}
+-		}
+-		/* either retransmit or send bar if ack not recd */
+-		if (!ack_recd) {
+-			struct ieee80211_tx_rate *txrate =
+-			    tx_info->status.rates;
+-			if (retry && (txrate[0].count < (int)retry_limit)) {
+-				ini->txretry[index]++;
+-				ini->tx_in_transit--;
+-				/* Use high prededence for retransmit to give some punch */
+-				/* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */
+-				wlc_txq_enq(wlc, scb, p,
+-					    WLC_PRIO_TO_HI_PREC(tid));
+-			} else {
+-				/* Retry timeout */
+-				ini->tx_in_transit--;
+-				ieee80211_tx_info_clear_status(tx_info);
+-				tx_info->status.ampdu_ack_len = 0;
+-				tx_info->status.ampdu_len = 1;
+-				tx_info->flags |=
+-				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
+-				skb_pull(p, D11_PHY_HDR_LEN);
+-				skb_pull(p, D11_TXH_LEN);
+-				wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
+-					"transit %d\n", SHORTNAME, seq,
+-					ini->tx_in_transit);
+-				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
+-							    p);
+-			}
+-		}
+-		tot_mpdu++;
+-
+-		/* break out if last packet of ampdu */
+-		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
+-		    TXC_AMPDU_LAST)
+-			break;
+-
+-		p = GETNEXTTXP(wlc, queue);
+-	}
+-	wlc_send_q(wlc);
+-
+-	/* update rate state */
+-	antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
+-
+-	wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
+-}
+-
+-/* initialize the initiator code for tid */
+-static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
+-						   scb_ampdu_t *scb_ampdu,
+-						   u8 tid, bool override)
+-{
+-	scb_ampdu_tid_ini_t *ini;
+-
+-	/* check for per-tid control of ampdu */
+-	if (!ampdu->ini_enable[tid]) {
+-		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
+-			  __func__, tid);
+-		return NULL;
+-	}
+-
+-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
+-	ini->tid = tid;
+-	ini->scb = scb_ampdu->scb;
+-	ini->magic = INI_MAGIC;
+-	return ini;
+-}
+-
+-static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on)
+-{
+-	struct wlc_info *wlc = ampdu->wlc;
+-
+-	wlc->pub->_ampdu = false;
+-
+-	if (on) {
+-		if (!N_ENAB(wlc->pub)) {
+-			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
+-				"nmode enabled\n", wlc->pub->unit);
+-			return -ENOTSUPP;
+-		}
+-		if (!wlc_ampdu_cap(ampdu)) {
+-			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
+-				"ampdu capable\n", wlc->pub->unit);
+-			return -ENOTSUPP;
+-		}
+-		wlc->pub->_ampdu = on;
+-	}
+-
+-	return 0;
+-}
+-
+-static bool wlc_ampdu_cap(struct ampdu_info *ampdu)
+-{
+-	if (WLC_PHY_11N_CAP(ampdu->wlc->band))
+-		return true;
+-	else
+-		return false;
+-}
+-
+-static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
+-{
+-	u32 rate, mcs;
+-
+-	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
+-		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
+-		/* 20MHz, No SGI */
+-		rate = MCS_RATE(mcs, false, false);
+-		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
+-		/* 40 MHz, No SGI */
+-		rate = MCS_RATE(mcs, true, false);
+-		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
+-		/* 20MHz, SGI */
+-		rate = MCS_RATE(mcs, false, true);
+-		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
+-		/* 40 MHz, SGI */
+-		rate = MCS_RATE(mcs, true, true);
+-		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
+-	}
+-}
+-
+-void wlc_ampdu_macaddr_upd(struct wlc_info *wlc)
+-{
+-	char template[T_RAM_ACCESS_SZ * 2];
+-
+-	/* driver needs to write the ta in the template; ta is at offset 16 */
+-	memset(template, 0, sizeof(template));
+-	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
+-	wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2),
+-			       template);
+-}
+-
+-bool wlc_aggregatable(struct wlc_info *wlc, u8 tid)
+-{
+-	return wlc->ampdu->ini_enable[tid];
+-}
+-
+-void wlc_ampdu_shm_upd(struct ampdu_info *ampdu)
+-{
+-	struct wlc_info *wlc = ampdu->wlc;
+-
+-	/* Extend ucode internal watchdog timer to match larger received frames */
+-	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
+-	    IEEE80211_HT_MAX_AMPDU_64K) {
+-		wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
+-		wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
+-	} else {
+-		wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
+-		wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
+-	}
+-}
+-
+-/*
+- * callback function that helps flushing ampdu packets from a priority queue
+- */
+-static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
+-{
+-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
+-	struct cb_del_ampdu_pars *ampdu_pars =
+-				 (struct cb_del_ampdu_pars *)arg_a;
+-	bool rc;
+-
+-	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
+-	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
+-		    tx_info->control.sta == ampdu_pars->sta);
+-	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
+-	return rc;
+-}
+-
+-/*
+- * callback function that helps invalidating ampdu packets in a DMA queue
+- */
+-static void dma_cb_fn_ampdu(void *txi, void *arg_a)
+-{
+-	struct ieee80211_sta *sta = arg_a;
+-	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
+-
+-	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
+-	    (tx_info->control.sta == sta || sta == NULL))
+-		tx_info->control.sta = NULL;
+-}
+-
+-/*
+- * When a remote party is no longer available for ampdu communication, any
+- * pending tx ampdu packets in the driver have to be flushed.
+- */
+-void wlc_ampdu_flush(struct wlc_info *wlc,
+-		     struct ieee80211_sta *sta, u16 tid)
+-{
+-	struct wlc_txq_info *qi = wlc->pkt_queue;
+-	struct pktq *pq = &qi->q;
+-	int prec;
+-	struct cb_del_ampdu_pars ampdu_pars;
+-
+-	ampdu_pars.sta = sta;
+-	ampdu_pars.tid = tid;
+-	for (prec = 0; prec < pq->num_prec; prec++) {
+-		bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
+-			    (void *)&ampdu_pars);
+-	}
+-	wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
+deleted file mode 100644
+index 63d403b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_ampdu_h_
+-#define _wlc_ampdu_h_
+-
+-extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc);
+-extern void wlc_ampdu_detach(struct ampdu_info *ampdu);
+-extern int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
+-			 struct sk_buff **aggp, int prec);
+-extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
+-				 struct sk_buff *p, tx_status_t *txs);
+-extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc);
+-extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu);
+-
+-#endif				/* _wlc_ampdu_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
+deleted file mode 100644
+index 111ef32..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
++++ /dev/null
+@@ -1,320 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <wlc_cfg.h>
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <bcmdevs.h>
+-#include <sbhnddma.h>
+-#include <wlioctl.h>
+-
+-#include "d11.h"
+-#include "wlc_rate.h"
+-#include "wlc_key.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wl_dbg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_bmac.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wlc_phy_shim.h"
+-#include "wlc_antsel.h"
+-
+-/* useful macros */
+-#define WLC_ANTSEL_11N_0(ant)	((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
+-#define WLC_ANTSEL_11N_1(ant)	(((ant) & ANT_SELCFG_MASK) & 0xf)
+-#define WLC_ANTIDX_11N(ant)	(((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant)))
+-#define WLC_ANT_ISAUTO_11N(ant)	(((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
+-#define WLC_ANTSEL_11N(ant)	((ant) & ANT_SELCFG_MASK)
+-
+-/* antenna switch */
+-/* defines for no boardlevel antenna diversity */
+-#define ANT_SELCFG_DEF_2x2	0x01	/* default antenna configuration */
+-
+-/* 2x3 antdiv defines and tables for GPIO communication */
+-#define ANT_SELCFG_NUM_2x3	3
+-#define ANT_SELCFG_DEF_2x3	0x01	/* default antenna configuration */
+-
+-/* 2x4 antdiv rev4 defines and tables for GPIO communication */
+-#define ANT_SELCFG_NUM_2x4	4
+-#define ANT_SELCFG_DEF_2x4	0x02	/* default antenna configuration */
+-
+-/* static functions */
+-static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel);
+-static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id);
+-static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg);
+-static void wlc_antsel_init_cfg(struct antsel_info *asi,
+-				wlc_antselcfg_t *antsel,
+-				bool auto_sel);
+-
+-const u16 mimo_2x4_div_antselpat_tbl[] = {
+-	0, 0, 0x9, 0xa,		/* ant0: 0 ant1: 2,3 */
+-	0, 0, 0x5, 0x6,		/* ant0: 1 ant1: 2,3 */
+-	0, 0, 0, 0,		/* n.a.              */
+-	0, 0, 0, 0		/* n.a.              */
+-};
+-
+-const u8 mimo_2x4_div_antselid_tbl[16] = {
+-	0, 0, 0, 0, 0, 2, 3, 0,
+-	0, 0, 1, 0, 0, 0, 0, 0	/* pat to antselid */
+-};
+-
+-const u16 mimo_2x3_div_antselpat_tbl[] = {
+-	16, 0, 1, 16,		/* ant0: 0 ant1: 1,2 */
+-	16, 16, 16, 16,		/* n.a.              */
+-	16, 2, 16, 16,		/* ant0: 2 ant1: 1   */
+-	16, 16, 16, 16		/* n.a.              */
+-};
+-
+-const u8 mimo_2x3_div_antselid_tbl[16] = {
+-	0, 1, 2, 0, 0, 0, 0, 0,
+-	0, 0, 0, 0, 0, 0, 0, 0	/* pat to antselid */
+-};
+-
+-struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc)
+-{
+-	struct antsel_info *asi;
+-
+-	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
+-	if (!asi) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n",
+-			  wlc->pub->unit);
+-		return NULL;
+-	}
+-
+-	asi->wlc = wlc;
+-	asi->pub = wlc->pub;
+-	asi->antsel_type = ANTSEL_NA;
+-	asi->antsel_avail = false;
+-	asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch");
+-
+-	if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
+-		switch (asi->antsel_antswitch) {
+-		case ANTSWITCH_TYPE_1:
+-		case ANTSWITCH_TYPE_2:
+-		case ANTSWITCH_TYPE_3:
+-			/* 4321/2 board with 2x3 switch logic */
+-			asi->antsel_type = ANTSEL_2x3;
+-			/* Antenna selection availability */
+-			if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) ||
+-			    ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) {
+-				asi->antsel_avail = true;
+-			} else
+-			    if (((u16) getintvar(asi->pub->vars, "aa2g") ==
+-				 3)
+-				|| ((u16) getintvar(asi->pub->vars, "aa5g")
+-				    == 3)) {
+-				asi->antsel_avail = false;
+-			} else {
+-				asi->antsel_avail = false;
+-				wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 "
+-					  "board cfg invalid\n");
+-			}
+-			break;
+-		default:
+-			break;
+-		}
+-	} else if ((asi->pub->sromrev == 4) &&
+-		   ((u16) getintvar(asi->pub->vars, "aa2g") == 7) &&
+-		   ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) {
+-		/* hack to match old 4321CB2 cards with 2of3 antenna switch */
+-		asi->antsel_type = ANTSEL_2x3;
+-		asi->antsel_avail = true;
+-	} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
+-		asi->antsel_type = ANTSEL_2x4;
+-		asi->antsel_avail = true;
+-	}
+-
+-	/* Set the antenna selection type for the low driver */
+-	wlc_bmac_antsel_type_set(wlc->hw, asi->antsel_type);
+-
+-	/* Init (auto/manual) antenna selection */
+-	wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true);
+-	wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true);
+-
+-	return asi;
+-}
+-
+-void wlc_antsel_detach(struct antsel_info *asi)
+-{
+-	kfree(asi);
+-}
+-
+-void wlc_antsel_init(struct antsel_info *asi)
+-{
+-	if ((asi->antsel_type == ANTSEL_2x3) ||
+-	    (asi->antsel_type == ANTSEL_2x4))
+-		wlc_antsel_cfgupd(asi, &asi->antcfg_11n);
+-}
+-
+-/* boardlevel antenna selection: init antenna selection structure */
+-static void
+-wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel,
+-		    bool auto_sel)
+-{
+-	if (asi->antsel_type == ANTSEL_2x3) {
+-		u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
+-		    ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
+-		antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x4) {
+-
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
+-		antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
+-
+-	} else {		/* no antenna selection available */
+-
+-		antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
+-		antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
+-		antsel->num_antcfg = 0;
+-	}
+-}
+-
+-void
+-wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
+-		      u8 antselid, u8 fbantselid, u8 *antcfg,
+-		      u8 *fbantcfg)
+-{
+-	u8 ant;
+-
+-	/* if use default, assign it and return */
+-	if (usedef) {
+-		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
+-		*fbantcfg = *antcfg;
+-		return;
+-	}
+-
+-	if (!sel) {
+-		*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-		*fbantcfg = *antcfg;
+-
+-	} else {
+-		ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-		if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
+-			*antcfg = wlc_antsel_id2antcfg(asi, antselid);
+-			*fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid);
+-		} else {
+-			*antcfg =
+-			    asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
+-			*fbantcfg = *antcfg;
+-		}
+-	}
+-	return;
+-}
+-
+-/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
+-u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
+-{
+-	u8 antselid = 0;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
+-		return antselid;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
+-		return antselid;
+-	}
+-
+-	return antselid;
+-}
+-
+-/* boardlevel antenna selection: convert id to ant_cfg */
+-static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id)
+-{
+-	u8 antcfg = ANT_SELCFG_DEF_2x2;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
+-		return antcfg;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
+-		return antcfg;
+-	}
+-
+-	return antcfg;
+-}
+-
+-/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */
+-static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
+-{
+-	u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg));
+-	u16 mimo_antsel = 0;
+-
+-	if (asi->antsel_type == ANTSEL_2x4) {
+-		/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
+-		mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
+-		return mimo_antsel;
+-
+-	} else if (asi->antsel_type == ANTSEL_2x3) {
+-		/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
+-		mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
+-		return mimo_antsel;
+-	}
+-
+-	return mimo_antsel;
+-}
+-
+-/* boardlevel antenna selection: ucode interface control */
+-static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel)
+-{
+-	struct wlc_info *wlc = asi->wlc;
+-	u8 ant_cfg;
+-	u16 mimo_antsel;
+-
+-	/* 1) Update TX antconfig for all frames that are not unicast data
+-	 *    (aka default TX)
+-	 */
+-	ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
+-	mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+-	wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
+-	/* Update driver stats for currently selected default tx/rx antenna config */
+-	asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
+-
+-	/* 2) Update RX antconfig for all frames that are not unicast data
+-	 *    (aka default RX)
+-	 */
+-	ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
+-	mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg);
+-	wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
+-	/* Update driver stats for currently selected default tx/rx antenna config */
+-	asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
+-
+-	return 0;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
+deleted file mode 100644
+index 2470c73..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_antsel_h_
+-#define _wlc_antsel_h_
+-
+-extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc);
+-extern void wlc_antsel_detach(struct antsel_info *asi);
+-extern void wlc_antsel_init(struct antsel_info *asi);
+-extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
+-				  bool sel,
+-				  u8 id, u8 fbid, u8 *antcfg,
+-				  u8 *fbantcfg);
+-extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
+-
+-#endif /* _wlc_antsel_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
+deleted file mode 100644
+index 934e7f9..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
++++ /dev/null
+@@ -1,3602 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmwifi.h>
+-#include <aiutils.h>
+-#include <bcmsrom.h>
+-#include <bcmotp.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <wlioctl.h>
+-#include <sbconfig.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#include "wlc_types.h"
+-#include "wlc_pmu.h"
+-#include "d11.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_phy_shim.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wl_ucode.h"
+-#include "wlc_antsel.h"
+-#include "pcie_core.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-#include "wlc_bmac.h"
+-
+-#define	TIMER_INTERVAL_WATCHDOG_BMAC	1000	/* watchdog timer, in unit of ms */
+-
+-#define	SYNTHPU_DLY_APHY_US	3700	/* a phy synthpu_dly time in us */
+-#define	SYNTHPU_DLY_BPHY_US	1050	/* b/g phy synthpu_dly time in us, default */
+-#define	SYNTHPU_DLY_NPHY_US	2048	/* n phy REV3 synthpu_dly time in us, default */
+-#define	SYNTHPU_DLY_LPPHY_US	300	/* lpphy synthpu_dly time in us */
+-
+-#define	SYNTHPU_DLY_PHY_US_QT	100	/* QT synthpu_dly time in us */
+-
+-#ifndef BMAC_DUP_TO_REMOVE
+-#define WLC_RM_WAIT_TX_SUSPEND		4	/* Wait Tx Suspend */
+-
+-#define	ANTCNT			10	/* vanilla M_MAX_ANTCNT value */
+-
+-#endif				/* BMAC_DUP_TO_REMOVE */
+-
+-#define DMAREG(wlc_hw, direction, fifonum) \
+-	((direction == DMA_TX) ? \
+-		(void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \
+-		(void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv))
+-
+-/*
+- * The following table lists the buffer memory allocated to xmt fifos in HW.
+- * the size is in units of 256bytes(one block), total size is HW dependent
+- * ucode has default fifo partition, sw can overwrite if necessary
+- *
+- * This is documented in twiki under the topic UcodeTxFifo. Please ensure
+- * the twiki is updated before making changes.
+- */
+-
+-#define XMTFIFOTBL_STARTREV	20	/* Starting corerev for the fifo size table */
+-
+-static u16 xmtfifo_sz[][NFIFO] = {
+-	{20, 192, 192, 21, 17, 5},	/* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{9, 58, 22, 14, 14, 5},	/* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */
+-	{20, 192, 192, 21, 17, 5},	/* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{20, 192, 192, 21, 17, 5},	/* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */
+-	{9, 58, 22, 14, 14, 5},	/* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */
+-};
+-
+-static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode);
+-static void wlc_coreinit(struct wlc_info *wlc);
+-
+-/* used by wlc_wakeucode_init() */
+-static void wlc_write_inits(struct wlc_hw_info *wlc_hw,
+-			    const struct d11init *inits);
+-static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[],
+-			    const uint nbytes);
+-static void wlc_ucode_download(struct wlc_hw_info *wlc);
+-static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw);
+-
+-/* used by wlc_dpc() */
+-static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs,
+-				u32 s2);
+-static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal);
+-static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound);
+-
+-/* used by wlc_down() */
+-static void wlc_flushqueues(struct wlc_info *wlc);
+-
+-static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs);
+-static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw);
+-static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw);
+-static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw,
+-				       uint tx_fifo);
+-static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo);
+-static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo);
+-
+-/* Low Level Prototypes */
+-static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw);
+-static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw);
+-static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want);
+-static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				   u32 sel);
+-static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				  u16 v, u32 sel);
+-static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk);
+-static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme);
+-static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw);
+-static bool wlc_validboardtype(struct wlc_hw_info *wlc);
+-static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw);
+-static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw);
+-static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw);
+-static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init);
+-static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw);
+-static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw);
+-static u32 wlc_wlintrsoff(struct wlc_info *wlc);
+-static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask);
+-static void wlc_gpio_init(struct wlc_info *wlc);
+-static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn,
+-				      int len);
+-static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn,
+-				      int len);
+-static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec);
+-static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit);
+-static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit,
+-			     chanspec_t chanspec);
+-static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw,
+-					bool shortslot);
+-static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw);
+-static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw,
+-					     u8 rate);
+-
+-/* === Low Level functions === */
+-
+-void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot)
+-{
+-	wlc_hw->shortslot = shortslot;
+-
+-	if (BAND_2G(wlc_bmac_bandtype(wlc_hw)) && wlc_hw->up) {
+-		wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-		wlc_bmac_update_slot_timing(wlc_hw, shortslot);
+-		wlc_enable_mac(wlc_hw->wlc);
+-	}
+-}
+-
+-/*
+- * Update the slot timing for standard 11b/g (20us slots)
+- * or shortslot 11g (9us slots)
+- * The PSM needs to be suspended for this call.
+- */
+-static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw,
+-					bool shortslot)
+-{
+-	d11regs_t *regs;
+-
+-	regs = wlc_hw->regs;
+-
+-	if (shortslot) {
+-		/* 11g short slot: 11a timing */
+-		W_REG(&regs->ifs_slot, 0x0207);	/* APHY_SLOT_TIME */
+-		wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME);
+-	} else {
+-		/* 11g long slot: 11b timing */
+-		W_REG(&regs->ifs_slot, 0x0212);	/* BPHY_SLOT_TIME */
+-		wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw)
+-{
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	/* init microcode host flags */
+-	wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs);
+-
+-	/* do band-specific ucode IHR, SHM, and SCR inits */
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			wlc_write_inits(wlc_hw, d11n0bsinitvals16);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-		}
+-	} else {
+-		if (D11REV_IS(wlc_hw->corerev, 24)) {
+-			if (WLCISLCNPHY(wlc_hw->band)) {
+-				wlc_write_inits(wlc_hw, d11lcn0bsinitvals24);
+-			} else
+-				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
+-					  " core rev %d\n", __func__,
+-					  wlc_hw->unit, wlc_hw->corerev);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+-				__func__, wlc_hw->unit, wlc_hw->corerev);
+-		}
+-	}
+-}
+-
+-/* switch to new band but leave it inactive */
+-static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintmask;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
+-
+-	/* disable interrupts */
+-	macintmask = wl_intrsoff(wlc->wl);
+-
+-	/* radio off */
+-	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+-
+-	wlc_bmac_core_phy_clk(wlc_hw, OFF);
+-
+-	wlc_setxband(wlc_hw, bandunit);
+-
+-	return macintmask;
+-}
+-
+-/* Process received frames */
+-/*
+- * Return true if more frames need to be processed. false otherwise.
+- * Param 'bound' indicates max. # frames to process before break out.
+- */
+-static bool
+-wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
+-{
+-	struct sk_buff *p;
+-	struct sk_buff *head = NULL;
+-	struct sk_buff *tail = NULL;
+-	uint n = 0;
+-	uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
+-	wlc_d11rxhdr_t *wlc_rxhdr = NULL;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-	/* gather received frames */
+-	while ((p = dma_rx(wlc_hw->di[fifo]))) {
+-
+-		if (!tail)
+-			head = tail = p;
+-		else {
+-			tail->prev = p;
+-			tail = p;
+-		}
+-
+-		/* !give others some time to run! */
+-		if (++n >= bound_limit)
+-			break;
+-	}
+-
+-	/* post more rbufs */
+-	dma_rxfill(wlc_hw->di[fifo]);
+-
+-	/* process each frame */
+-	while ((p = head) != NULL) {
+-		head = head->prev;
+-		p->prev = NULL;
+-
+-		wlc_rxhdr = (wlc_d11rxhdr_t *) p->data;
+-
+-		/* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
+-		wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
+-
+-		wlc_recv(wlc_hw->wlc, p);
+-	}
+-
+-	return n >= bound_limit;
+-}
+-
+-/* second-level interrupt processing
+- *   Return true if another dpc needs to be re-scheduled. false otherwise.
+- *   Param 'bounded' indicates if applicable loops should be bounded.
+- */
+-bool wlc_dpc(struct wlc_info *wlc, bool bounded)
+-{
+-	u32 macintstatus;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	bool fatal = false;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return false;
+-	}
+-
+-	/* grab and clear the saved software intstatus bits */
+-	macintstatus = wlc->macintstatus;
+-	wlc->macintstatus = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
+-	       wlc_hw->unit, macintstatus);
+-
+-	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
+-
+-	/* BCN template is available */
+-	/* ZZZ: Use AP_ACTIVE ? */
+-	if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated)
+-	    && (macintstatus & MI_BCNTPL)) {
+-		wlc_update_beacon(wlc);
+-	}
+-
+-	/* PMQ entry addition */
+-	if (macintstatus & MI_PMQ) {
+-	}
+-
+-	/* tx status */
+-	if (macintstatus & MI_TFS) {
+-		if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal))
+-			wlc->macintstatus |= MI_TFS;
+-		if (fatal) {
+-			wiphy_err(wiphy, "MI_TFS: fatal\n");
+-			goto fatal;
+-		}
+-	}
+-
+-	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
+-		wlc_tbtt(wlc, regs);
+-
+-	/* ATIM window end */
+-	if (macintstatus & MI_ATIMWINEND) {
+-		BCMMSG(wlc->wiphy, "end of ATIM window\n");
+-		OR_REG(&regs->maccommand, wlc->qvalid);
+-		wlc->qvalid = 0;
+-	}
+-
+-	/* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
+-	if (macintstatus & MI_DMAINT) {
+-		if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) {
+-			wlc->macintstatus |= MI_DMAINT;
+-		}
+-	}
+-
+-	/* TX FIFO suspend/flush completion */
+-	if (macintstatus & MI_TXSTOP) {
+-		if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) {
+-			/* wiphy_err(wiphy, "dpc: fifo_suspend_comlete\n"); */
+-		}
+-	}
+-
+-	/* noise sample collected */
+-	if (macintstatus & MI_BG_NOISE) {
+-		wlc_phy_noise_sample_intr(wlc_hw->band->pi);
+-	}
+-
+-	if (macintstatus & MI_GP0) {
+-		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
+-			"(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
+-
+-		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
+-					__func__, wlc_hw->sih->chip,
+-					wlc_hw->sih->chiprev);
+-		/* big hammer */
+-		wl_init(wlc->wl);
+-	}
+-
+-	/* gptimer timeout */
+-	if (macintstatus & MI_TO) {
+-		W_REG(&regs->gptimer, 0);
+-	}
+-
+-	if (macintstatus & MI_RFDISABLE) {
+-		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
+-		       " RF Disable Input\n", wlc_hw->unit);
+-		wl_rfkill_set_hw_state(wlc->wl);
+-	}
+-
+-	/* send any enq'd tx packets. Just makes sure to jump start tx */
+-	if (!pktq_empty(&wlc->pkt_queue->q))
+-		wlc_send_q(wlc);
+-
+-	/* it isn't done and needs to be resched if macintstatus is non-zero */
+-	return wlc->macintstatus != 0;
+-
+- fatal:
+-	wl_init(wlc->wl);
+-	return wlc->macintstatus != 0;
+-}
+-
+-/* common low-level watchdog code */
+-void wlc_bmac_watchdog(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return;
+-
+-	/* increment second count */
+-	wlc_hw->now++;
+-
+-	/* Check for FIFO error interrupts */
+-	wlc_bmac_fifoerrors(wlc_hw);
+-
+-	/* make sure RX dma has buffers */
+-	dma_rxfill(wlc->hw->di[RX_FIFO]);
+-
+-	wlc_phy_watchdog(wlc_hw->band->pi);
+-}
+-
+-void
+-wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-		      bool mute, struct txpwr_limits *txpwr)
+-{
+-	uint bandunit;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
+-
+-	wlc_hw->chanspec = chanspec;
+-
+-	/* Switch bands if necessary */
+-	if (NBANDS_HW(wlc_hw) > 1) {
+-		bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+-		if (wlc_hw->band->bandunit != bandunit) {
+-			/* wlc_bmac_setband disables other bandunit,
+-			 *  use light band switch if not up yet
+-			 */
+-			if (wlc_hw->up) {
+-				wlc_phy_chanspec_radio_set(wlc_hw->
+-							   bandstate[bandunit]->
+-							   pi, chanspec);
+-				wlc_bmac_setband(wlc_hw, bandunit, chanspec);
+-			} else {
+-				wlc_setxband(wlc_hw, bandunit);
+-			}
+-		}
+-	}
+-
+-	wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
+-
+-	if (!wlc_hw->up) {
+-		if (wlc_hw->clk)
+-			wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr,
+-						  chanspec);
+-		wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+-	} else {
+-		wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec);
+-		wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
+-
+-		/* Update muting of the channel */
+-		wlc_bmac_mute(wlc_hw, mute, 0);
+-	}
+-}
+-
+-int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state)
+-{
+-	state->machwcap = wlc_hw->machwcap;
+-
+-	return 0;
+-}
+-
+-static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme)
+-{
+-	uint i;
+-	char name[8];
+-	/* ucode host flag 2 needed for pio mode, independent of band and fifo */
+-	u16 pio_mhf2 = 0;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	uint unit = wlc_hw->unit;
+-	wlc_tunables_t *tune = wlc->pub->tunables;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	/* name and offsets for dma_attach */
+-	snprintf(name, sizeof(name), "wl%d", unit);
+-
+-	if (wlc_hw->di[0] == 0) {	/* Init FIFOs */
+-		uint addrwidth;
+-		int dma_attach_err = 0;
+-		/* Find out the DMA addressing capability and let OS know
+-		 * All the channels within one DMA core have 'common-minimum' same
+-		 * capability
+-		 */
+-		addrwidth =
+-		    dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0));
+-
+-		if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) {
+-			wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_"
+-				  "resources failed\n", unit);
+-			return false;
+-		}
+-
+-		/*
+-		 * FIFO 0
+-		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
+-		 * RX: RX_FIFO (RX data packets)
+-		 */
+-		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
+-					   (wme ? DMAREG(wlc_hw, DMA_TX, 0) :
+-					    NULL), DMAREG(wlc_hw, DMA_RX, 0),
+-					   (wme ? tune->ntxd : 0), tune->nrxd,
+-					   tune->rxbufsz, -1, tune->nrxbufpost,
+-					   WL_HWRXOFF, &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[0]);
+-
+-		/*
+-		 * FIFO 1
+-		 * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets)
+-		 *   (legacy) TX_DATA_FIFO (TX data packets)
+-		 * RX: UNUSED
+-		 */
+-		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 1), NULL,
+-					   tune->ntxd, 0, 0, -1, 0, 0,
+-					   &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[1]);
+-
+-		/*
+-		 * FIFO 2
+-		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
+-		 * RX: UNUSED
+-		 */
+-		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 2), NULL,
+-					   tune->ntxd, 0, 0, -1, 0, 0,
+-					   &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[2]);
+-		/*
+-		 * FIFO 3
+-		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
+-		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
+-		 */
+-		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
+-					   DMAREG(wlc_hw, DMA_TX, 3),
+-					   NULL, tune->ntxd, 0, 0, -1,
+-					   0, 0, &wl_msg_level);
+-		dma_attach_err |= (NULL == wlc_hw->di[3]);
+-/* Cleaner to leave this as if with AP defined */
+-
+-		if (dma_attach_err) {
+-			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
+-				  "\n", unit);
+-			return false;
+-		}
+-
+-		/* get pointer to dma engine tx flow control variable */
+-		for (i = 0; i < NFIFO; i++)
+-			if (wlc_hw->di[i])
+-				wlc_hw->txavail[i] =
+-				    (uint *) dma_getvar(wlc_hw->di[i],
+-							"&txavail");
+-	}
+-
+-	/* initial ucode host flags */
+-	wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2);
+-
+-	return true;
+-}
+-
+-static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw)
+-{
+-	uint j;
+-
+-	for (j = 0; j < NFIFO; j++) {
+-		if (wlc_hw->di[j]) {
+-			dma_detach(wlc_hw->di[j]);
+-			wlc_hw->di[j] = NULL;
+-		}
+-	}
+-}
+-
+-/* low level attach
+- *    run backplane attach, init nvram
+- *    run phy attach
+- *    initialize software state for each core and band
+- *    put the whole chip in reset(driver down state), no clock
+- */
+-int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit,
+-		    bool piomode, void *regsva, uint bustype, void *btparam)
+-{
+-	struct wlc_hw_info *wlc_hw;
+-	d11regs_t *regs;
+-	char *macaddr = NULL;
+-	char *vars;
+-	uint err = 0;
+-	uint j;
+-	bool wme = false;
+-	shared_phy_params_t sha_params;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
+-		device);
+-
+-	wme = true;
+-
+-	wlc_hw = wlc->hw;
+-	wlc_hw->wlc = wlc;
+-	wlc_hw->unit = unit;
+-	wlc_hw->band = wlc_hw->bandstate[0];
+-	wlc_hw->_piomode = piomode;
+-
+-	/* populate struct wlc_hw_info with default values  */
+-	wlc_bmac_info_init(wlc_hw);
+-
+-	/*
+-	 * Do the hardware portion of the attach.
+-	 * Also initialize software state that depends on the particular hardware
+-	 * we are running.
+-	 */
+-	wlc_hw->sih = ai_attach((uint) device, regsva, bustype, btparam,
+-				&wlc_hw->vars, &wlc_hw->vars_size);
+-	if (wlc_hw->sih == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: si_attach failed\n",
+-			  unit);
+-		err = 11;
+-		goto fail;
+-	}
+-	vars = wlc_hw->vars;
+-
+-	/*
+-	 * Get vendid/devid nvram overwrites, which could be different
+-	 * than those the BIOS recognizes for devices on PCMCIA_BUS,
+-	 * SDIO_BUS, and SROMless devices on PCI_BUS.
+-	 */
+-#ifdef BCMBUSTYPE
+-	bustype = BCMBUSTYPE;
+-#endif
+-	if (bustype != SI_BUS) {
+-		char *var;
+-
+-		var = getvar(vars, "vendid");
+-		if (var) {
+-			vendor = (u16) simple_strtoul(var, NULL, 0);
+-			wiphy_err(wiphy, "Overriding vendor id = 0x%x\n",
+-				  vendor);
+-		}
+-		var = getvar(vars, "devid");
+-		if (var) {
+-			u16 devid = (u16) simple_strtoul(var, NULL, 0);
+-			if (devid != 0xffff) {
+-				device = devid;
+-				wiphy_err(wiphy, "Overriding device id = 0x%x"
+-					  "\n", device);
+-			}
+-		}
+-
+-		/* verify again the device is supported */
+-		if (!wlc_chipmatch(vendor, device)) {
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported "
+-				"vendor/device (0x%x/0x%x)\n",
+-				 unit, vendor, device);
+-			err = 12;
+-			goto fail;
+-		}
+-	}
+-
+-	wlc_hw->vendorid = vendor;
+-	wlc_hw->deviceid = device;
+-
+-	/* set bar0 window to point at D11 core */
+-	wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
+-	wlc_hw->corerev = ai_corerev(wlc_hw->sih);
+-
+-	regs = wlc_hw->regs;
+-
+-	wlc->regs = wlc_hw->regs;
+-
+-	/* validate chip, chiprev and corerev */
+-	if (!wlc_isgoodchip(wlc_hw)) {
+-		err = 13;
+-		goto fail;
+-	}
+-
+-	/* initialize power control registers */
+-	ai_clkctl_init(wlc_hw->sih);
+-
+-	/* request fastclock and force fastclock for the rest of attach
+-	 * bring the d11 core out of reset.
+-	 *   For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false;
+-	 *   But it will be called again inside wlc_corereset, after d11 is out of reset.
+-	 */
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	if (!wlc_bmac_validate_chip_access(wlc_hw)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: validate_chip_access "
+-			"failed\n", unit);
+-		err = 14;
+-		goto fail;
+-	}
+-
+-	/* get the board rev, used just below */
+-	j = getintvar(vars, "boardrev");
+-	/* promote srom boardrev of 0xFF to 1 */
+-	if (j == BOARDREV_PROMOTABLE)
+-		j = BOARDREV_PROMOTED;
+-	wlc_hw->boardrev = (u16) j;
+-	if (!wlc_validboardtype(wlc_hw)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported Broadcom "
+-			"board type (0x%x)" " or revision level (0x%x)\n",
+-			 unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
+-		err = 15;
+-		goto fail;
+-	}
+-	wlc_hw->sromrev = (u8) getintvar(vars, "sromrev");
+-	wlc_hw->boardflags = (u32) getintvar(vars, "boardflags");
+-	wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2");
+-
+-	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
+-		wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED);
+-
+-	if ((wlc_hw->sih->bustype == PCI_BUS)
+-	    && (ai_pci_war16165(wlc_hw->sih)))
+-		wlc->war16165 = true;
+-
+-	/* check device id(srom, nvram etc.) to set bands */
+-	if (wlc_hw->deviceid == BCM43224_D11N_ID) {
+-		/* Dualband boards */
+-		wlc_hw->_nbands = 2;
+-	} else
+-		wlc_hw->_nbands = 1;
+-
+-	if ((wlc_hw->sih->chip == BCM43225_CHIP_ID))
+-		wlc_hw->_nbands = 1;
+-
+-	/* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the
+-	 * init of these values
+-	 */
+-	wlc->vendorid = wlc_hw->vendorid;
+-	wlc->deviceid = wlc_hw->deviceid;
+-	wlc->pub->sih = wlc_hw->sih;
+-	wlc->pub->corerev = wlc_hw->corerev;
+-	wlc->pub->sromrev = wlc_hw->sromrev;
+-	wlc->pub->boardrev = wlc_hw->boardrev;
+-	wlc->pub->boardflags = wlc_hw->boardflags;
+-	wlc->pub->boardflags2 = wlc_hw->boardflags2;
+-	wlc->pub->_nbands = wlc_hw->_nbands;
+-
+-	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
+-
+-	if (wlc_hw->physhim == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_shim_attach "
+-			"failed\n", unit);
+-		err = 25;
+-		goto fail;
+-	}
+-
+-	/* pass all the parameters to wlc_phy_shared_attach in one struct */
+-	sha_params.sih = wlc_hw->sih;
+-	sha_params.physhim = wlc_hw->physhim;
+-	sha_params.unit = unit;
+-	sha_params.corerev = wlc_hw->corerev;
+-	sha_params.vars = vars;
+-	sha_params.vid = wlc_hw->vendorid;
+-	sha_params.did = wlc_hw->deviceid;
+-	sha_params.chip = wlc_hw->sih->chip;
+-	sha_params.chiprev = wlc_hw->sih->chiprev;
+-	sha_params.chippkg = wlc_hw->sih->chippkg;
+-	sha_params.sromrev = wlc_hw->sromrev;
+-	sha_params.boardtype = wlc_hw->sih->boardtype;
+-	sha_params.boardrev = wlc_hw->boardrev;
+-	sha_params.boardvendor = wlc_hw->sih->boardvendor;
+-	sha_params.boardflags = wlc_hw->boardflags;
+-	sha_params.boardflags2 = wlc_hw->boardflags2;
+-	sha_params.bustype = wlc_hw->sih->bustype;
+-	sha_params.buscorerev = wlc_hw->sih->buscorerev;
+-
+-	/* alloc and save pointer to shared phy state area */
+-	wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params);
+-	if (!wlc_hw->phy_sh) {
+-		err = 16;
+-		goto fail;
+-	}
+-
+-	/* initialize software state for each core and band */
+-	for (j = 0; j < NBANDS_HW(wlc_hw); j++) {
+-		/*
+-		 * band0 is always 2.4Ghz
+-		 * band1, if present, is 5Ghz
+-		 */
+-
+-		/* So if this is a single band 11a card, use band 1 */
+-		if (IS_SINGLEBAND_5G(wlc_hw->deviceid))
+-			j = BAND_5G_INDEX;
+-
+-		wlc_setxband(wlc_hw, j);
+-
+-		wlc_hw->band->bandunit = j;
+-		wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+-		wlc->band->bandunit = j;
+-		wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
+-		wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
+-
+-		wlc_hw->machwcap = R_REG(&regs->machwcap);
+-		wlc_hw->machwcap_backup = wlc_hw->machwcap;
+-
+-		/* init tx fifo size */
+-		wlc_hw->xmtfifo_sz =
+-		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
+-
+-		/* Get a phy for this band */
+-		wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh,
+-			(void *)regs, wlc_bmac_bandtype(wlc_hw), vars,
+-			wlc->wiphy);
+-		if (wlc_hw->band->pi == NULL) {
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_"
+-				  "attach failed\n", unit);
+-			err = 17;
+-			goto fail;
+-		}
+-
+-		wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap);
+-
+-		wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype,
+-				       &wlc_hw->band->phyrev,
+-				       &wlc_hw->band->radioid,
+-				       &wlc_hw->band->radiorev);
+-		wlc_hw->band->abgphy_encore =
+-		    wlc_phy_get_encore(wlc_hw->band->pi);
+-		wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi);
+-		wlc_hw->band->core_flags =
+-		    wlc_phy_get_coreflags(wlc_hw->band->pi);
+-
+-		/* verify good phy_type & supported phy revision */
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			if (NCONF_HAS(wlc_hw->band->phyrev))
+-				goto good_phy;
+-			else
+-				goto bad_phy;
+-		} else if (WLCISLCNPHY(wlc_hw->band)) {
+-			if (LCNCONF_HAS(wlc_hw->band->phyrev))
+-				goto good_phy;
+-			else
+-				goto bad_phy;
+-		} else {
+- bad_phy:
+-			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: unsupported "
+-				  "phy type/rev (%d/%d)\n", unit,
+-				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
+-			err = 18;
+-			goto fail;
+-		}
+-
+- good_phy:
+-		/* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the
+-		 * high level attach. However we can not make that change until all low level access
+-		 * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping
+-		 * wlc_hw->band->pi as well for incremental update of low level fns, and cut over
+-		 * low only init when all fns updated.
+-		 */
+-		wlc->band->pi = wlc_hw->band->pi;
+-		wlc->band->phytype = wlc_hw->band->phytype;
+-		wlc->band->phyrev = wlc_hw->band->phyrev;
+-		wlc->band->radioid = wlc_hw->band->radioid;
+-		wlc->band->radiorev = wlc_hw->band->radiorev;
+-
+-		/* default contention windows size limits */
+-		wlc_hw->band->CWmin = APHY_CWMIN;
+-		wlc_hw->band->CWmax = PHY_CWMAX;
+-
+-		if (!wlc_bmac_attach_dmapio(wlc, j, wme)) {
+-			err = 19;
+-			goto fail;
+-		}
+-	}
+-
+-	/* disable core to match driver "down" state */
+-	wlc_coredisable(wlc_hw);
+-
+-	/* Match driver "down" state */
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_down(wlc_hw->sih);
+-
+-	/* register sb interrupt callback functions */
+-	ai_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff,
+-				  (void *)wlc_wlintrsrestore, NULL, wlc);
+-
+-	/* turn off pll and xtal to match driver "down" state */
+-	wlc_bmac_xtal(wlc_hw, OFF);
+-
+-	/* *********************************************************************
+-	 * The hardware is in the DOWN state at this point. D11 core
+-	 * or cores are in reset with clocks off, and the board PLLs
+-	 * are off if possible.
+-	 *
+-	 * Beyond this point, wlc->sbclk == false and chip registers
+-	 * should not be touched.
+-	 *********************************************************************
+-	 */
+-
+-	/* init etheraddr state variables */
+-	macaddr = wlc_get_macaddr(wlc_hw);
+-	if (macaddr == NULL) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: macaddr not found\n",
+-			  unit);
+-		err = 21;
+-		goto fail;
+-	}
+-	bcm_ether_atoe(macaddr, wlc_hw->etheraddr);
+-	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
+-	    is_zero_ether_addr(wlc_hw->etheraddr)) {
+-		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n",
+-			  unit, macaddr);
+-		err = 22;
+-		goto fail;
+-	}
+-
+-	BCMMSG(wlc->wiphy,
+-		 "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
+-		 wlc_hw->deviceid, wlc_hw->_nbands,
+-		 wlc_hw->sih->boardtype, macaddr);
+-
+-	return err;
+-
+- fail:
+-	wiphy_err(wiphy, "wl%d: wlc_bmac_attach: failed with err %d\n", unit,
+-		  err);
+-	return err;
+-}
+-
+-/*
+- * Initialize wlc_info default values ...
+- * may get overrides later in this function
+- *  BMAC_NOTES, move low out and resolve the dangling ones
+- */
+-static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw)
+-{
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-
+-	/* set default sw macintmask value */
+-	wlc->defmacintmask = DEF_MACINTMASK;
+-
+-	/* various 802.11g modes */
+-	wlc_hw->shortslot = false;
+-
+-	wlc_hw->SFBL = RETRY_SHORT_FB;
+-	wlc_hw->LFBL = RETRY_LONG_FB;
+-
+-	/* default mac retry limits */
+-	wlc_hw->SRL = RETRY_SHORT_DEF;
+-	wlc_hw->LRL = RETRY_LONG_DEF;
+-	wlc_hw->chanspec = CH20MHZ_CHSPEC(1);
+-}
+-
+-/*
+- * low level detach
+- */
+-int wlc_bmac_detach(struct wlc_info *wlc)
+-{
+-	uint i;
+-	struct wlc_hwband *band;
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	int callbacks;
+-
+-	callbacks = 0;
+-
+-	if (wlc_hw->sih) {
+-		/* detach interrupt sync mechanism since interrupt is disabled and per-port
+-		 * interrupt object may has been freed. this must be done before sb core switch
+-		 */
+-		ai_deregister_intr_callback(wlc_hw->sih);
+-
+-		if (wlc_hw->sih->bustype == PCI_BUS)
+-			ai_pci_sleep(wlc_hw->sih);
+-	}
+-
+-	wlc_bmac_detach_dmapio(wlc_hw);
+-
+-	band = wlc_hw->band;
+-	for (i = 0; i < NBANDS_HW(wlc_hw); i++) {
+-		if (band->pi) {
+-			/* Detach this band's phy */
+-			wlc_phy_detach(band->pi);
+-			band->pi = NULL;
+-		}
+-		band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)];
+-	}
+-
+-	/* Free shared phy state */
+-	wlc_phy_shared_detach(wlc_hw->phy_sh);
+-
+-	wlc_phy_shim_detach(wlc_hw->physhim);
+-
+-	/* free vars */
+-	kfree(wlc_hw->vars);
+-	wlc_hw->vars = NULL;
+-
+-	if (wlc_hw->sih) {
+-		ai_detach(wlc_hw->sih);
+-		wlc_hw->sih = NULL;
+-	}
+-
+-	return callbacks;
+-
+-}
+-
+-void wlc_bmac_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* reset the core */
+-	if (!DEVICEREMOVED(wlc_hw->wlc))
+-		wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	/* purge the dma rings */
+-	wlc_flushqueues(wlc_hw->wlc);
+-
+-	wlc_reset_bmac_done(wlc_hw->wlc);
+-}
+-
+-void
+-wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-			  bool mute) {
+-	u32 macintmask;
+-	bool fastclk;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* request FAST clock if not on */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/* disable interrupts */
+-	macintmask = wl_intrsoff(wlc->wl);
+-
+-	/* set up the specified band and chanspec */
+-	wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec));
+-	wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec);
+-
+-	/* do one-time phy inits and calibration */
+-	wlc_phy_cal_init(wlc_hw->band->pi);
+-
+-	/* core-specific initialization */
+-	wlc_coreinit(wlc);
+-
+-	/* suspend the tx fifos and mute the phy for preism cac time */
+-	if (mute)
+-		wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
+-
+-	/* band-specific inits */
+-	wlc_bmac_bsinit(wlc, chanspec);
+-
+-	/* restore macintmask */
+-	wl_intrsrestore(wlc->wl, macintmask);
+-
+-	/* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended
+-	 * and wlc_enable_mac() will clear this override bit.
+-	 */
+-	mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-
+-	/*
+-	 * initialize mac_suspend_depth to 1 to match ucode initial suspended state
+-	 */
+-	wlc_hw->mac_suspend_depth = 1;
+-
+-	/* restore the clk */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw)
+-{
+-	uint coremask;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/*
+-	 * Enable pll and xtal, initialize the power control registers,
+-	 * and force fastclock for the remainder of wlc_up().
+-	 */
+-	wlc_bmac_xtal(wlc_hw, ON);
+-	ai_clkctl_init(wlc_hw->sih);
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/*
+-	 * Configure pci/pcmcia here instead of in wlc_attach()
+-	 * to allow mfg hotswap:  down, hotswap (chip power cycle), up.
+-	 */
+-	coremask = (1 << wlc_hw->wlc->core->coreidx);
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_setup(wlc_hw->sih, coremask);
+-
+-	/*
+-	 * Need to read the hwradio status here to cover the case where the system
+-	 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+-	 */
+-	if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) {
+-		/* put SB PCI in down state again */
+-		if (wlc_hw->sih->bustype == PCI_BUS)
+-			ai_pci_down(wlc_hw->sih);
+-		wlc_bmac_xtal(wlc_hw, OFF);
+-		return -ENOMEDIUM;
+-	}
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS)
+-		ai_pci_up(wlc_hw->sih);
+-
+-	/* reset the d11 core */
+-	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
+-
+-	return 0;
+-}
+-
+-int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	wlc_hw->up = true;
+-	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
+-
+-	/* FULLY enable dynamic power control and d11 core interrupt */
+-	wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-	wl_intrson(wlc_hw->wlc->wl);
+-	return 0;
+-}
+-
+-int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw)
+-{
+-	bool dev_gone;
+-	uint callbacks = 0;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return callbacks;
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	/* disable interrupts */
+-	if (dev_gone)
+-		wlc_hw->wlc->macintmask = 0;
+-	else {
+-		/* now disable interrupts */
+-		wl_intrsoff(wlc_hw->wlc->wl);
+-
+-		/* ensure we're running on the pll clock again */
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-	}
+-	/* down phy at the last of this stage */
+-	callbacks += wlc_phy_down(wlc_hw->band->pi);
+-
+-	return callbacks;
+-}
+-
+-int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw)
+-{
+-	uint callbacks = 0;
+-	bool dev_gone;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (!wlc_hw->up)
+-		return callbacks;
+-
+-	wlc_hw->up = false;
+-	wlc_phy_hw_state_upd(wlc_hw->band->pi, false);
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	if (dev_gone) {
+-		wlc_hw->sbclk = false;
+-		wlc_hw->clk = false;
+-		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-
+-		/* reclaim any posted packets */
+-		wlc_flushqueues(wlc_hw->wlc);
+-	} else {
+-
+-		/* Reset and disable the core */
+-		if (ai_iscoreup(wlc_hw->sih)) {
+-			if (R_REG(&wlc_hw->regs->maccontrol) &
+-			    MCTL_EN_MAC)
+-				wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-			callbacks += wl_reset(wlc_hw->wlc->wl);
+-			wlc_coredisable(wlc_hw);
+-		}
+-
+-		/* turn off primary xtal and pll */
+-		if (!wlc_hw->noreset) {
+-			if (wlc_hw->sih->bustype == PCI_BUS)
+-				ai_pci_down(wlc_hw->sih);
+-			wlc_bmac_xtal(wlc_hw, OFF);
+-		}
+-	}
+-
+-	return callbacks;
+-}
+-
+-void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw)
+-{
+-	/* delay before first read of ucode state */
+-	udelay(40);
+-
+-	/* wait until ucode is no longer asleep */
+-	SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) ==
+-		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
+-}
+-
+-void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea)
+-{
+-	memcpy(ea, wlc_hw->etheraddr, ETH_ALEN);
+-}
+-
+-static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw)
+-{
+-	return wlc_hw->band->bandtype;
+-}
+-
+-/* control chip clock to save power, enable dynamic clock or force fast clock */
+-static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode)
+-{
+-	if (PMUCTL_ENAB(wlc_hw->sih)) {
+-		/* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane,
+-		 *  but mac core will still run on ALP(not HT) when it enters powersave mode,
+-		 *      which means the FCA bit may not be set.
+-		 *      should wakeup mac if driver wants it to run on HT.
+-		 */
+-
+-		if (wlc_hw->clk) {
+-			if (mode == CLK_FAST) {
+-				OR_REG(&wlc_hw->regs->clk_ctl_st,
+-				       CCS_FORCEHT);
+-
+-				udelay(64);
+-
+-				SPINWAIT(((R_REG
+-					   (&wlc_hw->regs->
+-					    clk_ctl_st) & CCS_HTAVAIL) == 0),
+-					 PMU_MAX_TRANSITION_DLY);
+-				WARN_ON(!(R_REG
+-					  (&wlc_hw->regs->
+-					   clk_ctl_st) & CCS_HTAVAIL));
+-			} else {
+-				if ((wlc_hw->sih->pmurev == 0) &&
+-				    (R_REG
+-				     (&wlc_hw->regs->
+-				      clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ)))
+-					SPINWAIT(((R_REG
+-						   (&wlc_hw->regs->
+-						    clk_ctl_st) & CCS_HTAVAIL)
+-						  == 0),
+-						 PMU_MAX_TRANSITION_DLY);
+-				AND_REG(&wlc_hw->regs->clk_ctl_st,
+-					~CCS_FORCEHT);
+-			}
+-		}
+-		wlc_hw->forcefastclk = (mode == CLK_FAST);
+-	} else {
+-
+-		/* old chips w/o PMU, force HT through cc,
+-		 * then use FCA to verify mac is running fast clock
+-		 */
+-
+-		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
+-
+-		/* check fast clock is available (if core is not in reset) */
+-		if (wlc_hw->forcefastclk && wlc_hw->clk)
+-			WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
+-				  SISF_FCLKA));
+-
+-		/* keep the ucode wake bit on if forcefastclk is on
+-		 * since we do not want ucode to put us back to slow clock
+-		 * when it dozes for PM mode.
+-		 * Code below matches the wake override bit with current forcefastclk state
+-		 * Only setting bit in wake_override instead of waking ucode immediately
+-		 * since old code (wlc.c 1.4499) had this behavior. Older code set
+-		 * wlc->forcefastclk but only had the wake happen if the wakup_ucode work
+-		 * (protected by an up check) was executed just below.
+-		 */
+-		if (wlc_hw->forcefastclk)
+-			mboolset(wlc_hw->wake_override,
+-				 WLC_WAKE_OVERRIDE_FORCEFAST);
+-		else
+-			mboolclr(wlc_hw->wake_override,
+-				 WLC_WAKE_OVERRIDE_FORCEFAST);
+-	}
+-}
+-
+-/* set initial host flags value */
+-static void
+-wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	memset(mhfs, 0, MHFMAX * sizeof(u16));
+-
+-	mhfs[MHF2] |= mhf2_init;
+-
+-	/* prohibit use of slowclock on multifunction boards */
+-	if (wlc_hw->boardflags & BFL_NOPLLDOWN)
+-		mhfs[MHF1] |= MHF1_FORCEFASTCLK;
+-
+-	if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) {
+-		mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR;
+-		mhfs[MHF1] |= MHF1_IQSWAP_WAR;
+-	}
+-}
+-
+-/* set or clear ucode host flag bits
+- * it has an optimization for no-change write
+- * it only writes through shared memory when the core has clock;
+- * pre-CLK changes should use wlc_write_mhf to get around the optimization
+- *
+- *
+- * bands values are: WLC_BAND_AUTO <--- Current band only
+- *                   WLC_BAND_5G   <--- 5G band only
+- *                   WLC_BAND_2G   <--- 2G band only
+- *                   WLC_BAND_ALL  <--- All bands
+- */
+-void
+-wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val,
+-	     int bands)
+-{
+-	u16 save;
+-	u16 addr[MHFMAX] = {
+-		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+-		M_HOST_FLAGS5
+-	};
+-	struct wlc_hwband *band;
+-
+-	if ((val & ~mask) || idx >= MHFMAX)
+-		return; /* error condition */
+-
+-	switch (bands) {
+-		/* Current band only or all bands,
+-		 * then set the band to current band
+-		 */
+-	case WLC_BAND_AUTO:
+-	case WLC_BAND_ALL:
+-		band = wlc_hw->band;
+-		break;
+-	case WLC_BAND_5G:
+-		band = wlc_hw->bandstate[BAND_5G_INDEX];
+-		break;
+-	case WLC_BAND_2G:
+-		band = wlc_hw->bandstate[BAND_2G_INDEX];
+-		break;
+-	default:
+-		band = NULL;	/* error condition */
+-	}
+-
+-	if (band) {
+-		save = band->mhfs[idx];
+-		band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val;
+-
+-		/* optimization: only write through if changed, and
+-		 * changed band is the current band
+-		 */
+-		if (wlc_hw->clk && (band->mhfs[idx] != save)
+-		    && (band == wlc_hw->band))
+-			wlc_bmac_write_shm(wlc_hw, addr[idx],
+-					   (u16) band->mhfs[idx]);
+-	}
+-
+-	if (bands == WLC_BAND_ALL) {
+-		wlc_hw->bandstate[0]->mhfs[idx] =
+-		    (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val;
+-		wlc_hw->bandstate[1]->mhfs[idx] =
+-		    (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val;
+-	}
+-}
+-
+-u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands)
+-{
+-	struct wlc_hwband *band;
+-
+-	if (idx >= MHFMAX)
+-		return 0; /* error condition */
+-	switch (bands) {
+-	case WLC_BAND_AUTO:
+-		band = wlc_hw->band;
+-		break;
+-	case WLC_BAND_5G:
+-		band = wlc_hw->bandstate[BAND_5G_INDEX];
+-		break;
+-	case WLC_BAND_2G:
+-		band = wlc_hw->bandstate[BAND_2G_INDEX];
+-		break;
+-	default:
+-		band = NULL;		/* error condition */
+-	}
+-
+-	if (!band)
+-		return 0;
+-
+-	return band->mhfs[idx];
+-}
+-
+-static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs)
+-{
+-	u8 idx;
+-	u16 addr[] = {
+-		M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4,
+-		M_HOST_FLAGS5
+-	};
+-
+-	for (idx = 0; idx < MHFMAX; idx++) {
+-		wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]);
+-	}
+-}
+-
+-/* set the maccontrol register to desired reset state and
+- * initialize the sw cache of the register
+- */
+-static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	/* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */
+-	wlc_hw->maccontrol = 0;
+-	wlc_hw->suspended_fifos = 0;
+-	wlc_hw->wake_override = 0;
+-	wlc_hw->mute_override = 0;
+-	wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE);
+-}
+-
+-/* set or clear maccontrol bits */
+-void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val)
+-{
+-	u32 maccontrol;
+-	u32 new_maccontrol;
+-
+-	if (val & ~mask)
+-		return; /* error condition */
+-	maccontrol = wlc_hw->maccontrol;
+-	new_maccontrol = (maccontrol & ~mask) | val;
+-
+-	/* if the new maccontrol value is the same as the old, nothing to do */
+-	if (new_maccontrol == maccontrol)
+-		return;
+-
+-	/* something changed, cache the new value */
+-	wlc_hw->maccontrol = new_maccontrol;
+-
+-	/* write the new values with overrides applied */
+-	wlc_mctrl_write(wlc_hw);
+-}
+-
+-/* write the software state of maccontrol and overrides to the maccontrol register */
+-static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw)
+-{
+-	u32 maccontrol = wlc_hw->maccontrol;
+-
+-	/* OR in the wake bit if overridden */
+-	if (wlc_hw->wake_override)
+-		maccontrol |= MCTL_WAKE;
+-
+-	/* set AP and INFRA bits for mute if needed */
+-	if (wlc_hw->mute_override) {
+-		maccontrol &= ~(MCTL_AP);
+-		maccontrol |= MCTL_INFRA;
+-	}
+-
+-	W_REG(&wlc_hw->regs->maccontrol, maccontrol);
+-}
+-
+-void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit)
+-{
+-	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
+-		mboolset(wlc_hw->wake_override, override_bit);
+-		return;
+-	}
+-
+-	mboolset(wlc_hw->wake_override, override_bit);
+-
+-	wlc_mctrl_write(wlc_hw);
+-	wlc_bmac_wait_for_wake(wlc_hw);
+-
+-	return;
+-}
+-
+-void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit)
+-{
+-	mboolclr(wlc_hw->wake_override, override_bit);
+-
+-	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-
+-	return;
+-}
+-
+-/* When driver needs ucode to stop beaconing, it has to make sure that
+- * MCTL_AP is clear and MCTL_INFRA is set
+- * Mode           MCTL_AP        MCTL_INFRA
+- * AP                1              1
+- * STA               0              1 <--- This will ensure no beacons
+- * IBSS              0              0
+- */
+-static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw)
+-{
+-	wlc_hw->mute_override = 1;
+-
+-	/* if maccontrol already has AP == 0 and INFRA == 1 without this
+-	 * override, then there is no change to write
+-	 */
+-	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-
+-	return;
+-}
+-
+-/* Clear the override on AP and INFRA bits */
+-static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw)
+-{
+-	if (wlc_hw->mute_override == 0)
+-		return;
+-
+-	wlc_hw->mute_override = 0;
+-
+-	/* if maccontrol already has AP == 0 and INFRA == 1 without this
+-	 * override, then there is no change to write
+-	 */
+-	if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA)
+-		return;
+-
+-	wlc_mctrl_write(wlc_hw);
+-}
+-
+-/*
+- * Write a MAC address to the given match reg offset in the RXE match engine.
+- */
+-void
+-wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset,
+-		       const u8 *addr)
+-{
+-	d11regs_t *regs;
+-	u16 mac_l;
+-	u16 mac_m;
+-	u16 mac_h;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: wlc_bmac_set_addrmatch\n",
+-		 wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-	mac_l = addr[0] | (addr[1] << 8);
+-	mac_m = addr[2] | (addr[3] << 8);
+-	mac_h = addr[4] | (addr[5] << 8);
+-
+-	/* enter the MAC addr into the RXE match registers */
+-	W_REG(&regs->rcm_ctl, RCM_INC_DATA | match_reg_offset);
+-	W_REG(&regs->rcm_mat_data, mac_l);
+-	W_REG(&regs->rcm_mat_data, mac_m);
+-	W_REG(&regs->rcm_mat_data, mac_h);
+-
+-}
+-
+-void
+-wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len,
+-			    void *buf)
+-{
+-	d11regs_t *regs;
+-	u32 word;
+-	bool be_bit;
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-	W_REG(&regs->tplatewrptr, offset);
+-
+-	/* if MCTL_BIGEND bit set in mac control register,
+-	 * the chip swaps data in fifo, as well as data in
+-	 * template ram
+-	 */
+-	be_bit = (R_REG(&regs->maccontrol) & MCTL_BIGEND) != 0;
+-
+-	while (len > 0) {
+-		memcpy(&word, buf, sizeof(u32));
+-
+-		if (be_bit)
+-			word = cpu_to_be32(word);
+-		else
+-			word = cpu_to_le32(word);
+-
+-		W_REG(&regs->tplatewrdata, word);
+-
+-		buf = (u8 *) buf + sizeof(u32);
+-		len -= sizeof(u32);
+-	}
+-}
+-
+-void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin)
+-{
+-	wlc_hw->band->CWmin = newmin;
+-
+-	W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN);
+-	(void)R_REG(&wlc_hw->regs->objaddr);
+-	W_REG(&wlc_hw->regs->objdata, newmin);
+-}
+-
+-void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax)
+-{
+-	wlc_hw->band->CWmax = newmax;
+-
+-	W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX);
+-	(void)R_REG(&wlc_hw->regs->objaddr);
+-	W_REG(&wlc_hw->regs->objdata, newmax);
+-}
+-
+-void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw)
+-{
+-	bool fastclk;
+-
+-	/* request FAST clock if not on */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
+-
+-	wlc_bmac_phy_reset(wlc_hw);
+-	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
+-
+-	/* restore the clk */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-static void
+-wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
+-				    bcn);
+-	/* write beacon length to SCR */
+-	wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
+-	/* mark beacon0 valid */
+-	OR_REG(&regs->maccommand, MCMD_BCN0VLD);
+-}
+-
+-static void
+-wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
+-				    bcn);
+-	/* write beacon length to SCR */
+-	wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
+-	/* mark beacon1 valid */
+-	OR_REG(&regs->maccommand, MCMD_BCN1VLD);
+-}
+-
+-/* mac is assumed to be suspended at this point */
+-void
+-wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len,
+-			       bool both)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	if (both) {
+-		wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+-		wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+-	} else {
+-		/* bcn 0 */
+-		if (!(R_REG(&regs->maccommand) & MCMD_BCN0VLD))
+-			wlc_write_hw_bcntemplate0(wlc_hw, bcn, len);
+-		/* bcn 1 */
+-		else if (!
+-			 (R_REG(&regs->maccommand) & MCMD_BCN1VLD))
+-			wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
+-	}
+-}
+-
+-static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw)
+-{
+-	u16 v;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	/* update SYNTHPU_DLY */
+-
+-	if (WLCISLCNPHY(wlc->band)) {
+-		v = SYNTHPU_DLY_LPPHY_US;
+-	} else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) {
+-		v = SYNTHPU_DLY_NPHY_US;
+-	} else {
+-		v = SYNTHPU_DLY_BPHY_US;
+-	}
+-
+-	wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v);
+-}
+-
+-/* band-specific init */
+-static void
+-WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc_hw->band->bandunit);
+-
+-	wlc_ucode_bsinit(wlc_hw);
+-
+-	wlc_phy_init(wlc_hw->band->pi, chanspec);
+-
+-	wlc_ucode_txant_set(wlc_hw);
+-
+-	/* cwmin is band-specific, update hardware with value for current band */
+-	wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin);
+-	wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax);
+-
+-	wlc_bmac_update_slot_timing(wlc_hw,
+-				    BAND_5G(wlc_hw->band->
+-					    bandtype) ? true : wlc_hw->
+-				    shortslot);
+-
+-	/* write phytype and phyvers */
+-	wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype);
+-	wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev);
+-
+-	/* initialize the txphyctl1 rate table since shmem is shared between bands */
+-	wlc_upd_ofdm_pctl1_table(wlc_hw);
+-
+-	wlc_bmac_upd_synthpu(wlc_hw);
+-}
+-
+-static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
+-
+-	wlc_hw->phyclk = clk;
+-
+-	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
+-
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
+-			       (SICF_PRST | SICF_FGC));
+-		udelay(1);
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
+-		udelay(1);
+-
+-	} else {		/* take phy out of reset */
+-
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
+-		udelay(1);
+-		ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
+-		udelay(1);
+-
+-	}
+-}
+-
+-/* Perform a soft reset of the PHY PLL */
+-void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_addr), ~0, 0);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 4);
+-	udelay(1);
+-	ai_corereg(wlc_hw->sih, SI_CC_IDX,
+-		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
+-	udelay(1);
+-}
+-
+-/* light way to turn on phy clock without reset for NPHY only
+- *  refer to wlc_bmac_core_phy_clk for full version
+- */
+-void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	/* support(necessary for NPHY and HYPHY) only */
+-	if (!WLCISNPHY(wlc_hw->band))
+-		return;
+-
+-	if (ON == clk)
+-		ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
+-	else
+-		ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
+-
+-}
+-
+-void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk)
+-{
+-	if (ON == clk)
+-		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
+-	else
+-		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
+-}
+-
+-void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw)
+-{
+-	wlc_phy_t *pih = wlc_hw->band->pi;
+-	u32 phy_bw_clkbits;
+-	bool phy_in_reset = false;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	if (pih == NULL)
+-		return;
+-
+-	phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi);
+-
+-	/* Specific reset sequence required for NPHY rev 3 and 4 */
+-	if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
+-	    NREV_LE(wlc_hw->band->phyrev, 4)) {
+-		/* Set the PHY bandwidth */
+-		ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
+-
+-		udelay(1);
+-
+-		/* Perform a soft reset of the PHY PLL */
+-		wlc_bmac_core_phypll_reset(wlc_hw);
+-
+-		/* reset the PHY */
+-		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
+-			       (SICF_PRST | SICF_PCLKE));
+-		phy_in_reset = true;
+-	} else {
+-
+-		ai_core_cflags(wlc_hw->sih,
+-			       (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
+-			       (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
+-	}
+-
+-	udelay(2);
+-	wlc_bmac_core_phy_clk(wlc_hw, ON);
+-
+-	if (pih)
+-		wlc_phy_anacore(pih, ON);
+-}
+-
+-/* switch to and initialize new band */
+-static void
+-WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit,
+-				chanspec_t chanspec) {
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	u32 macintmask;
+-
+-	/* Enable the d11 core before accessing it */
+-	if (!ai_iscoreup(wlc_hw->sih)) {
+-		ai_core_reset(wlc_hw->sih, 0, 0);
+-		wlc_mctrl_reset(wlc_hw);
+-	}
+-
+-	macintmask = wlc_setband_inact(wlc, bandunit);
+-
+-	if (!wlc_hw->up)
+-		return;
+-
+-	wlc_bmac_core_phy_clk(wlc_hw, ON);
+-
+-	/* band-specific initializations */
+-	wlc_bmac_bsinit(wlc, chanspec);
+-
+-	/*
+-	 * If there are any pending software interrupt bits,
+-	 * then replace these with a harmless nonzero value
+-	 * so wlc_dpc() will re-enable interrupts when done.
+-	 */
+-	if (wlc->macintstatus)
+-		wlc->macintstatus = MI_DMAINT;
+-
+-	/* restore macintmask */
+-	wl_intrsrestore(wlc->wl, macintmask);
+-
+-	/* ucode should still be suspended.. */
+-	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
+-}
+-
+-/* low-level band switch utility routine */
+-void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		bandunit);
+-
+-	wlc_hw->band = wlc_hw->bandstate[bandunit];
+-
+-	/* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */
+-	wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit];
+-
+-	/* set gmode core flag */
+-	if (wlc_hw->sbclk && !wlc_hw->noreset) {
+-		ai_core_cflags(wlc_hw->sih, SICF_GMODE,
+-			       ((bandunit == 0) ? SICF_GMODE : 0));
+-	}
+-}
+-
+-static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw)
+-{
+-
+-	/* reject unsupported corerev */
+-	if (!VALID_COREREV(wlc_hw->corerev)) {
+-		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
+-			  wlc_hw->corerev);
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw)
+-{
+-	bool goodboard = true;
+-	uint boardrev = wlc_hw->boardrev;
+-
+-	if (boardrev == 0)
+-		goodboard = false;
+-	else if (boardrev > 0xff) {
+-		uint brt = (boardrev & 0xf000) >> 12;
+-		uint b0 = (boardrev & 0xf00) >> 8;
+-		uint b1 = (boardrev & 0xf0) >> 4;
+-		uint b2 = boardrev & 0xf;
+-
+-		if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9)
+-		    || (b2 > 9))
+-			goodboard = false;
+-	}
+-
+-	if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
+-		return goodboard;
+-
+-	return goodboard;
+-}
+-
+-static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw)
+-{
+-	const char *varname = "macaddr";
+-	char *macaddr;
+-
+-	/* If macaddr exists, use it (Sromrev4, CIS, ...). */
+-	macaddr = getvar(wlc_hw->vars, varname);
+-	if (macaddr != NULL)
+-		return macaddr;
+-
+-	if (NBANDS_HW(wlc_hw) > 1)
+-		varname = "et1macaddr";
+-	else
+-		varname = "il0macaddr";
+-
+-	macaddr = getvar(wlc_hw->vars, varname);
+-	if (macaddr == NULL) {
+-		wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
+-			  "getvar(%s) not found\n", wlc_hw->unit, varname);
+-	}
+-
+-	return macaddr;
+-}
+-
+-/*
+- * Return true if radio is disabled, otherwise false.
+- * hw radio disable signal is an external pin, users activate it asynchronously
+- * this function could be called when driver is down and w/o clock
+- * it operates on different registers depending on corerev and boardflag.
+- */
+-bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw)
+-{
+-	bool v, clk, xtal;
+-	u32 resetbits = 0, flags = 0;
+-
+-	xtal = wlc_hw->sbclk;
+-	if (!xtal)
+-		wlc_bmac_xtal(wlc_hw, ON);
+-
+-	/* may need to take core out of reset first */
+-	clk = wlc_hw->clk;
+-	if (!clk) {
+-		/*
+-		 * mac no longer enables phyclk automatically when driver
+-		 * accesses phyreg throughput mac. This can be skipped since
+-		 * only mac reg is accessed below
+-		 */
+-		flags |= SICF_PCLKE;
+-
+-		/* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+-		if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
+-			wlc_hw->regs =
+-			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
+-						     0);
+-		ai_core_reset(wlc_hw->sih, flags, resetbits);
+-		wlc_mctrl_reset(wlc_hw);
+-	}
+-
+-	v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0);
+-
+-	/* put core back into reset */
+-	if (!clk)
+-		ai_core_disable(wlc_hw->sih, 0);
+-
+-	if (!xtal)
+-		wlc_bmac_xtal(wlc_hw, OFF);
+-
+-	return v;
+-}
+-
+-/* Initialize just the hardware when coming out of POR or S3/S5 system states */
+-void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw)
+-{
+-	if (wlc_hw->wlc->pub->hw_up)
+-		return;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/*
+-	 * Enable pll and xtal, initialize the power control registers,
+-	 * and force fastclock for the remainder of wlc_up().
+-	 */
+-	wlc_bmac_xtal(wlc_hw, ON);
+-	ai_clkctl_init(wlc_hw->sih);
+-	wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	if (wlc_hw->sih->bustype == PCI_BUS) {
+-		ai_pci_fixcfg(wlc_hw->sih);
+-
+-		/* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
+-		if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
+-		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
+-			wlc_hw->regs =
+-			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
+-						     0);
+-	}
+-
+-	/* Inform phy that a POR reset has occurred so it does a complete phy init */
+-	wlc_phy_por_inform(wlc_hw->band->pi);
+-
+-	wlc_hw->ucode_loaded = false;
+-	wlc_hw->wlc->pub->hw_up = true;
+-
+-	if ((wlc_hw->boardflags & BFL_FEM)
+-	    && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
+-		if (!
+-		    (wlc_hw->boardrev >= 0x1250
+-		     && (wlc_hw->boardflags & BFL_FEM_BT)))
+-			ai_epa_4313war(wlc_hw->sih);
+-	}
+-}
+-
+-static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo)
+-{
+-	struct hnddma_pub *di = wlc_hw->di[fifo];
+-	return dma_rxreset(di);
+-}
+-
+-/* d11 core reset
+- *   ensure fask clock during reset
+- *   reset dma
+- *   reset d11(out of reset)
+- *   reset phy(out of reset)
+- *   clear software macintstatus for fresh new start
+- * one testing hack wlc_hw->noreset will bypass the d11/phy reset
+- */
+-void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags)
+-{
+-	d11regs_t *regs;
+-	uint i;
+-	bool fastclk;
+-	u32 resetbits = 0;
+-
+-	if (flags == WLC_USE_COREFLAGS)
+-		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-
+-	/* request FAST clock if not on  */
+-	fastclk = wlc_hw->forcefastclk;
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	/* reset the dma engines except first time thru */
+-	if (ai_iscoreup(wlc_hw->sih)) {
+-		for (i = 0; i < NFIFO; i++)
+-			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
+-					  "dma_txreset[%d]: cannot stop dma\n",
+-					   wlc_hw->unit, __func__, i);
+-			}
+-
+-		if ((wlc_hw->di[RX_FIFO])
+-		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) {
+-			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
+-				  "[%d]: cannot stop dma\n",
+-				  wlc_hw->unit, __func__, RX_FIFO);
+-		}
+-	}
+-	/* if noreset, just stop the psm and return */
+-	if (wlc_hw->noreset) {
+-		wlc_hw->wlc->macintstatus = 0;	/* skip wl_dpc after down */
+-		wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0);
+-		return;
+-	}
+-
+-	/*
+-	 * mac no longer enables phyclk automatically when driver accesses
+-	 * phyreg throughput mac, AND phy_reset is skipped at early stage when
+-	 * band->pi is invalid. need to enable PHY CLK
+-	 */
+-	flags |= SICF_PCLKE;
+-
+-	/* reset the core
+-	 * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which
+-	 *  is cleared by the core_reset. have to re-request it.
+-	 *  This adds some delay and we can optimize it by also requesting fastclk through
+-	 *  chipcommon during this period if necessary. But that has to work coordinate
+-	 *  with other driver like mips/arm since they may touch chipcommon as well.
+-	 */
+-	wlc_hw->clk = false;
+-	ai_core_reset(wlc_hw->sih, flags, resetbits);
+-	wlc_hw->clk = true;
+-	if (wlc_hw->band && wlc_hw->band->pi)
+-		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
+-
+-	wlc_mctrl_reset(wlc_hw);
+-
+-	if (PMUCTL_ENAB(wlc_hw->sih))
+-		wlc_clkctl_clk(wlc_hw, CLK_FAST);
+-
+-	wlc_bmac_phy_reset(wlc_hw);
+-
+-	/* turn on PHY_PLL */
+-	wlc_bmac_core_phypll_ctl(wlc_hw, true);
+-
+-	/* clear sw intstatus */
+-	wlc_hw->wlc->macintstatus = 0;
+-
+-	/* restore the clk setting */
+-	if (!fastclk)
+-		wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
+-}
+-
+-/* txfifo sizes needs to be modified(increased) since the newer cores
+- * have more memory.
+- */
+-static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	u16 fifo_nu;
+-	u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk;
+-	u16 txfifo_def, txfifo_def1;
+-	u16 txfifo_cmd;
+-
+-	/* tx fifos start at TXFIFO_START_BLK from the Base address */
+-	txfifo_startblk = TXFIFO_START_BLK;
+-
+-	/* sequence of operations:  reset fifo, set fifo size, reset fifo */
+-	for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) {
+-
+-		txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu];
+-		txfifo_def = (txfifo_startblk & 0xff) |
+-		    (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT);
+-		txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) |
+-		    ((((txfifo_endblk -
+-			1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT);
+-		txfifo_cmd =
+-		    TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT);
+-
+-		W_REG(&regs->xmtfifocmd, txfifo_cmd);
+-		W_REG(&regs->xmtfifodef, txfifo_def);
+-		W_REG(&regs->xmtfifodef1, txfifo_def1);
+-
+-		W_REG(&regs->xmtfifocmd, txfifo_cmd);
+-
+-		txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu];
+-	}
+-	/*
+-	 * need to propagate to shm location to be in sync since ucode/hw won't
+-	 * do this
+-	 */
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0,
+-			   wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]);
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1,
+-			   wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]);
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2,
+-			   ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw->
+-			    xmtfifo_sz[TX_AC_BK_FIFO]));
+-	wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3,
+-			   ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw->
+-			    xmtfifo_sz[TX_BCMC_FIFO]));
+-}
+-
+-/* d11 core init
+- *   reset PSM
+- *   download ucode/PCM
+- *   let ucode run to suspended
+- *   download ucode inits
+- *   config other core registers
+- *   init dma
+- */
+-static void wlc_coreinit(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs;
+-	u32 sflags;
+-	uint bcnint_us;
+-	uint i = 0;
+-	bool fifosz_fixup = false;
+-	int err = 0;
+-	u16 buf[NFIFO];
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	regs = wlc_hw->regs;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	/* reset PSM */
+-	wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
+-
+-	wlc_ucode_download(wlc_hw);
+-	/*
+-	 * FIFOSZ fixup. driver wants to controls the fifo allocation.
+-	 */
+-	fifosz_fixup = true;
+-
+-	/* let the PSM run to the suspended state, set mode to BSS STA */
+-	W_REG(&regs->macintstatus, -1);
+-	wlc_bmac_mctrl(wlc_hw, ~0,
+-		       (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE));
+-
+-	/* wait for ucode to self-suspend after auto-init */
+-	SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
+-		 1000 * 1000);
+-	if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
+-		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
+-			  "suspend!\n", wlc_hw->unit);
+-
+-	wlc_gpio_init(wlc);
+-
+-	sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
+-
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band))
+-			wlc_write_inits(wlc_hw, d11n0initvals16);
+-		else
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
+-		if (WLCISLCNPHY(wlc_hw->band)) {
+-			wlc_write_inits(wlc_hw, d11lcn0initvals24);
+-		} else {
+-			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+-				  " %d\n", __func__, wlc_hw->unit,
+-				  wlc_hw->corerev);
+-		}
+-	} else {
+-		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+-			  __func__, wlc_hw->unit, wlc_hw->corerev);
+-	}
+-
+-	/* For old ucode, txfifo sizes needs to be modified(increased) */
+-	if (fifosz_fixup == true) {
+-		wlc_corerev_fifofixup(wlc_hw);
+-	}
+-
+-	/* check txfifo allocations match between ucode and driver */
+-	buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0);
+-	if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) {
+-		i = TX_AC_BE_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1);
+-	if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) {
+-		i = TX_AC_VI_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2);
+-	buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff;
+-	buf[TX_AC_BK_FIFO] &= 0xff;
+-	if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) {
+-		i = TX_AC_BK_FIFO;
+-		err = -1;
+-	}
+-	if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) {
+-		i = TX_AC_VO_FIFO;
+-		err = -1;
+-	}
+-	buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3);
+-	buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff;
+-	buf[TX_BCMC_FIFO] &= 0xff;
+-	if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) {
+-		i = TX_BCMC_FIFO;
+-		err = -1;
+-	}
+-	if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) {
+-		i = TX_ATIM_FIFO;
+-		err = -1;
+-	}
+-	if (err != 0) {
+-		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
+-			  " driver size %d index %d\n", buf[i],
+-			  wlc_hw->xmtfifo_sz[i], i);
+-	}
+-
+-	/* make sure we can still talk to the mac */
+-	WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
+-
+-	/* band-specific inits done by wlc_bsinit() */
+-
+-	/* Set up frame burst size and antenna swap threshold init values */
+-	wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST);
+-	wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT);
+-
+-	/* enable one rx interrupt per received frame */
+-	W_REG(&regs->intrcvlazy[0], (1 << IRL_FC_SHIFT));
+-
+-	/* set the station mode (BSS STA) */
+-	wlc_bmac_mctrl(wlc_hw,
+-		       (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP),
+-		       (MCTL_INFRA | MCTL_DISCARD_PMQ));
+-
+-	/* set up Beacon interval */
+-	bcnint_us = 0x8000 << 10;
+-	W_REG(&regs->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT));
+-	W_REG(&regs->tsf_cfpstart, bcnint_us);
+-	W_REG(&regs->macintstatus, MI_GP1);
+-
+-	/* write interrupt mask */
+-	W_REG(&regs->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK);
+-
+-	/* allow the MAC to control the PHY clock (dynamic on/off) */
+-	wlc_bmac_macphyclk_set(wlc_hw, ON);
+-
+-	/* program dynamic clock control fast powerup delay register */
+-	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
+-	W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
+-
+-	/* tell the ucode the corerev */
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev);
+-
+-	/* tell the ucode MAC capabilities */
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L,
+-			   (u16) (wlc_hw->machwcap & 0xffff));
+-	wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H,
+-			   (u16) ((wlc_hw->
+-				      machwcap >> 16) & 0xffff));
+-
+-	/* write retry limits to SCR, this done after PSM init */
+-	W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, wlc_hw->SRL);
+-	W_REG(&regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, wlc_hw->LRL);
+-
+-	/* write rate fallback retry limits */
+-	wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL);
+-	wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL);
+-
+-	AND_REG(&regs->ifs_ctl, 0x0FFF);
+-	W_REG(&regs->ifs_aifsn, EDCF_AIFSN_MIN);
+-
+-	/* dma initializations */
+-	wlc->txpend16165war = 0;
+-
+-	/* init the tx dma engines */
+-	for (i = 0; i < NFIFO; i++) {
+-		if (wlc_hw->di[i])
+-			dma_txinit(wlc_hw->di[i]);
+-	}
+-
+-	/* init the rx dma engine(s) and post receive buffers */
+-	dma_rxinit(wlc_hw->di[RX_FIFO]);
+-	dma_rxfill(wlc_hw->di[RX_FIFO]);
+-}
+-
+-/* This function is used for changing the tsf frac register
+- * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz
+- * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz
+- * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz
+- * HTPHY Formula is 2^26/freq(MHz) e.g.
+- * For spuron2 - 126MHz -> 2^26/126 = 532610.0
+- *  - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082
+- * For spuron: 123MHz -> 2^26/123    = 545600.5
+- *  - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341
+- * For spur off: 120MHz -> 2^26/120    = 559240.5
+- *  - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889
+- */
+-
+-void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode)
+-{
+-	d11regs_t *regs;
+-	regs = wlc_hw->regs;
+-
+-	if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
+-	    (wlc_hw->sih->chip == BCM43225_CHIP_ID)) {
+-		if (spurmode == WL_SPURAVOID_ON2) {	/* 126Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x2082);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		} else if (spurmode == WL_SPURAVOID_ON1) {	/* 123Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x5341);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		} else {	/* 120Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x8889);
+-			W_REG(&regs->tsf_clk_frac_h, 0x8);
+-		}
+-	} else if (WLCISLCNPHY(wlc_hw->band)) {
+-		if (spurmode == WL_SPURAVOID_ON1) {	/* 82Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0x7CE0);
+-			W_REG(&regs->tsf_clk_frac_h, 0xC);
+-		} else {	/* 80Mhz */
+-			W_REG(&regs->tsf_clk_frac_l, 0xCCCD);
+-			W_REG(&regs->tsf_clk_frac_h, 0xC);
+-		}
+-	}
+-}
+-
+-/* Initialize GPIOs that are controlled by D11 core */
+-static void wlc_gpio_init(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs;
+-	u32 gc, gm;
+-
+-	regs = wlc_hw->regs;
+-
+-	/* use GPIO select 0 to get all gpio signals from the gpio out reg */
+-	wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0);
+-
+-	/*
+-	 * Common GPIO setup:
+-	 *      G0 = LED 0 = WLAN Activity
+-	 *      G1 = LED 1 = WLAN 2.4 GHz Radio State
+-	 *      G2 = LED 2 = WLAN 5 GHz Radio State
+-	 *      G4 = radio disable input (HI enabled, LO disabled)
+-	 */
+-
+-	gc = gm = 0;
+-
+-	/* Allocate GPIOs for mimo antenna diversity feature */
+-	if (wlc_hw->antsel_type == ANTSEL_2x3) {
+-		/* Enable antenna diversity, use 2x3 mode */
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+-			     MHF3_ANTSEL_EN, WLC_BAND_ALL);
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE,
+-			     MHF3_ANTSEL_MODE, WLC_BAND_ALL);
+-
+-		/* init superswitch control */
+-		wlc_phy_antsel_init(wlc_hw->band->pi, false);
+-
+-	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
+-		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
+-		/*
+-		 * The board itself is powered by these GPIOs
+-		 * (when not sending pattern) so set them high
+-		 */
+-		OR_REG(&regs->psm_gpio_oe,
+-		       (BOARD_GPIO_12 | BOARD_GPIO_13));
+-		OR_REG(&regs->psm_gpio_out,
+-		       (BOARD_GPIO_12 | BOARD_GPIO_13));
+-
+-		/* Enable antenna diversity, use 2x4 mode */
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN,
+-			     MHF3_ANTSEL_EN, WLC_BAND_ALL);
+-		wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0,
+-			     WLC_BAND_ALL);
+-
+-		/* Configure the desired clock to be 4Mhz */
+-		wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV,
+-				   ANTSEL_CLKDIV_4MHZ);
+-	}
+-
+-	/* gpio 9 controls the PA.  ucode is responsible for wiggling out and oe */
+-	if (wlc_hw->boardflags & BFL_PACTRL)
+-		gm |= gc |= BOARD_GPIO_PACTRL;
+-
+-	/* apply to gpiocontrol register */
+-	ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
+-}
+-
+-static void wlc_ucode_download(struct wlc_hw_info *wlc_hw)
+-{
+-	struct wlc_info *wlc;
+-	wlc = wlc_hw->wlc;
+-
+-	if (wlc_hw->ucode_loaded)
+-		return;
+-
+-	if (D11REV_IS(wlc_hw->corerev, 23)) {
+-		if (WLCISNPHY(wlc_hw->band)) {
+-			wlc_ucode_write(wlc_hw, bcm43xx_16_mimo,
+-					bcm43xx_16_mimosz);
+-			wlc_hw->ucode_loaded = true;
+-		} else
+-			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+-				  "corerev %d\n",
+-				  __func__, wlc_hw->unit, wlc_hw->corerev);
+-	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
+-		if (WLCISLCNPHY(wlc_hw->band)) {
+-			wlc_ucode_write(wlc_hw, bcm43xx_24_lcn,
+-					bcm43xx_24_lcnsz);
+-			wlc_hw->ucode_loaded = true;
+-		} else {
+-			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+-				  "corerev %d\n",
+-				  __func__, wlc_hw->unit, wlc_hw->corerev);
+-		}
+-	}
+-}
+-
+-static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[],
+-			      const uint nbytes) {
+-	d11regs_t *regs = wlc_hw->regs;
+-	uint i;
+-	uint count;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	count = (nbytes / sizeof(u32));
+-
+-	W_REG(&regs->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL));
+-	(void)R_REG(&regs->objaddr);
+-	for (i = 0; i < count; i++)
+-		W_REG(&regs->objdata, ucode[i]);
+-}
+-
+-static void wlc_write_inits(struct wlc_hw_info *wlc_hw,
+-			    const struct d11init *inits)
+-{
+-	int i;
+-	volatile u8 *base;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	base = (volatile u8 *)wlc_hw->regs;
+-
+-	for (i = 0; inits[i].addr != 0xffff; i++) {
+-		if (inits[i].size == 2)
+-			W_REG((u16 *)(base + inits[i].addr),
+-			      inits[i].value);
+-		else if (inits[i].size == 4)
+-			W_REG((u32 *)(base + inits[i].addr),
+-			      inits[i].value);
+-	}
+-}
+-
+-static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw)
+-{
+-	u16 phyctl;
+-	u16 phytxant = wlc_hw->bmac_phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* set the Probe Response frame phy control word */
+-	phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl);
+-
+-	/* set the Response (ACK/CTS) frame phy control word */
+-	phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl);
+-}
+-
+-void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant)
+-{
+-	/* update sw state */
+-	wlc_hw->bmac_phytxant = phytxant;
+-
+-	/* push to ucode if up */
+-	if (!wlc_hw->up)
+-		return;
+-	wlc_ucode_txant_set(wlc_hw);
+-
+-}
+-
+-u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw)
+-{
+-	return (u16) wlc_hw->wlc->stf->txant;
+-}
+-
+-void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type)
+-{
+-	wlc_hw->antsel_type = antsel_type;
+-
+-	/* Update the antsel type for phy module to use */
+-	wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type);
+-}
+-
+-void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw)
+-{
+-	bool fatal = false;
+-	uint unit;
+-	uint intstatus, idx;
+-	d11regs_t *regs = wlc_hw->regs;
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	unit = wlc_hw->unit;
+-
+-	for (idx = 0; idx < NFIFO; idx++) {
+-		/* read intstatus register and ignore any non-error bits */
+-		intstatus =
+-		    R_REG(&regs->intctrlregs[idx].intstatus) & I_ERRORS;
+-		if (!intstatus)
+-			continue;
+-
+-		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
+-			unit, idx, intstatus);
+-
+-		if (intstatus & I_RO) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
+-				  "overflow\n", unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_PC) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
+-				 unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_PD) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
+-				  idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_DE) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
+-				  "error\n", unit, idx);
+-			fatal = true;
+-		}
+-
+-		if (intstatus & I_RU) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
+-				  "underflow\n", idx, unit);
+-		}
+-
+-		if (intstatus & I_XU) {
+-			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
+-				  "underflow\n", idx, unit);
+-			fatal = true;
+-		}
+-
+-		if (fatal) {
+-			wlc_fatal_error(wlc_hw->wlc);	/* big hammer */
+-			break;
+-		} else
+-			W_REG(&regs->intctrlregs[idx].intstatus,
+-			      intstatus);
+-	}
+-}
+-
+-void wlc_intrson(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	wlc->macintmask = wlc->defmacintmask;
+-	W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
+-}
+-
+-/* callback for siutils.c, which has only wlc handler, no wl
+- * they both check up, not only because there is no need to off/restore d11 interrupt
+- *  but also because per-port code may require sync with valid interrupt.
+- */
+-
+-static u32 wlc_wlintrsoff(struct wlc_info *wlc)
+-{
+-	if (!wlc->hw->up)
+-		return 0;
+-
+-	return wl_intrsoff(wlc->wl);
+-}
+-
+-static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask)
+-{
+-	if (!wlc->hw->up)
+-		return;
+-
+-	wl_intrsrestore(wlc->wl, macintmask);
+-}
+-
+-u32 wlc_intrsoff(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintmask;
+-
+-	if (!wlc_hw->clk)
+-		return 0;
+-
+-	macintmask = wlc->macintmask;	/* isr can still happen */
+-
+-	W_REG(&wlc_hw->regs->macintmask, 0);
+-	(void)R_REG(&wlc_hw->regs->macintmask);	/* sync readback */
+-	udelay(1);		/* ensure int line is no longer driven */
+-	wlc->macintmask = 0;
+-
+-	/* return previous macintmask; resolve race between us and our isr */
+-	return wlc->macintstatus ? 0 : macintmask;
+-}
+-
+-void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	if (!wlc_hw->clk)
+-		return;
+-
+-	wlc->macintmask = macintmask;
+-	W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
+-}
+-
+-void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags)
+-{
+-	u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
+-
+-	if (on) {
+-		/* suspend tx fifos */
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO);
+-		wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO);
+-
+-		/* zero the address match register so we do not send ACKs */
+-		wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+-				       null_ether_addr);
+-	} else {
+-		/* resume tx fifos */
+-		if (!wlc_hw->wlc->tx_suspended) {
+-			wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO);
+-		}
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO);
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO);
+-		wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO);
+-
+-		/* Restore address */
+-		wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET,
+-				       wlc_hw->etheraddr);
+-	}
+-
+-	wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
+-
+-	if (on)
+-		wlc_ucode_mute_override_set(wlc_hw);
+-	else
+-		wlc_ucode_mute_override_clear(wlc_hw);
+-}
+-
+-int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks)
+-{
+-	if (fifo >= NFIFO)
+-		return -EINVAL;
+-
+-	*blocks = wlc_hw->xmtfifo_sz[fifo];
+-
+-	return 0;
+-}
+-
+-/* wlc_bmac_tx_fifo_suspended:
+- * Check the MAC's tx suspend status for a tx fifo.
+- *
+- * When the MAC acknowledges a tx suspend, it indicates that no more
+- * packets will be transmitted out the radio. This is independent of
+- * DMA channel suspension---the DMA may have finished suspending, or may still
+- * be pulling data into a tx fifo, by the time the MAC acks the suspend
+- * request.
+- */
+-static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	/* check that a suspend has been requested and is no longer pending */
+-
+-	/*
+-	 * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine,
+-	 * and the tx fifo suspend at the lower end of the MAC is acknowledged in the
+-	 * chnstatus register.
+-	 * The tx fifo suspend completion is independent of the DMA suspend completion and
+-	 *   may be acked before or after the DMA is suspended.
+-	 */
+-	if (dma_txsuspended(wlc_hw->di[tx_fifo]) &&
+-	    (R_REG(&wlc_hw->regs->chnstatus) &
+-	     (1 << tx_fifo)) == 0)
+-		return true;
+-
+-	return false;
+-}
+-
+-static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	u8 fifo = 1 << tx_fifo;
+-
+-	/* Two clients of this code, 11h Quiet period and scanning. */
+-
+-	/* only suspend if not already suspended */
+-	if ((wlc_hw->suspended_fifos & fifo) == fifo)
+-		return;
+-
+-	/* force the core awake only if not already */
+-	if (wlc_hw->suspended_fifos == 0)
+-		wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO);
+-
+-	wlc_hw->suspended_fifos |= fifo;
+-
+-	if (wlc_hw->di[tx_fifo]) {
+-		/* Suspending AMPDU transmissions in the middle can cause underflow
+-		 * which may result in mismatch between ucode and driver
+-		 * so suspend the mac before suspending the FIFO
+-		 */
+-		if (WLC_PHY_11N_CAP(wlc_hw->band))
+-			wlc_suspend_mac_and_wait(wlc_hw->wlc);
+-
+-		dma_txsuspend(wlc_hw->di[tx_fifo]);
+-
+-		if (WLC_PHY_11N_CAP(wlc_hw->band))
+-			wlc_enable_mac(wlc_hw->wlc);
+-	}
+-}
+-
+-static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo)
+-{
+-	/* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done
+-	 * here for PIO otherwise the watchdog will catch the inconsistency and fire
+-	 */
+-	/* Two clients of this code, 11h Quiet period and scanning. */
+-	if (wlc_hw->di[tx_fifo])
+-		dma_txresume(wlc_hw->di[tx_fifo]);
+-
+-	/* allow core to sleep again */
+-	if (wlc_hw->suspended_fifos == 0)
+-		return;
+-	else {
+-		wlc_hw->suspended_fifos &= ~(1 << tx_fifo);
+-		if (wlc_hw->suspended_fifos == 0)
+-			wlc_ucode_wake_override_clear(wlc_hw,
+-						      WLC_WAKE_OVERRIDE_TXFIFO);
+-	}
+-}
+-
+-/*
+- * Read and clear macintmask and macintstatus and intstatus registers.
+- * This routine should be called with interrupts off
+- * Return:
+- *   -1 if DEVICEREMOVED(wlc) evaluates to true;
+- *   0 if the interrupt is not for us, or we are in some special cases;
+- *   device interrupt status bits otherwise.
+- */
+-static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 macintstatus;
+-
+-	/* macintstatus includes a DMA interrupt summary bit */
+-	macintstatus = R_REG(&regs->macintstatus);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
+-		 macintstatus);
+-
+-	/* detect cardbus removed, in power down(suspend) and in reset */
+-	if (DEVICEREMOVED(wlc))
+-		return -1;
+-
+-	/* DEVICEREMOVED succeeds even when the core is still resetting,
+-	 * handle that case here.
+-	 */
+-	if (macintstatus == 0xffffffff)
+-		return 0;
+-
+-	/* defer unsolicited interrupts */
+-	macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask);
+-
+-	/* if not for us */
+-	if (macintstatus == 0)
+-		return 0;
+-
+-	/* interrupts are already turned off for CFE build
+-	 * Caution: For CFE Turning off the interrupts again has some undesired
+-	 * consequences
+-	 */
+-	/* turn off the interrupts */
+-	W_REG(&regs->macintmask, 0);
+-	(void)R_REG(&regs->macintmask);	/* sync readback */
+-	wlc->macintmask = 0;
+-
+-	/* clear device interrupts */
+-	W_REG(&regs->macintstatus, macintstatus);
+-
+-	/* MI_DMAINT is indication of non-zero intstatus */
+-	if (macintstatus & MI_DMAINT) {
+-		/*
+-		 * only fifo interrupt enabled is I_RI in
+-		 * RX_FIFO. If MI_DMAINT is set, assume it
+-		 * is set and clear the interrupt.
+-		 */
+-		W_REG(&regs->intctrlregs[RX_FIFO].intstatus,
+-		      DEF_RXINTMASK);
+-	}
+-
+-	return macintstatus;
+-}
+-
+-/* Update wlc->macintstatus and wlc->intstatus[]. */
+-/* Return true if they are updated successfully. false otherwise */
+-bool wlc_intrsupd(struct wlc_info *wlc)
+-{
+-	u32 macintstatus;
+-
+-	/* read and clear macintstatus and intstatus registers */
+-	macintstatus = wlc_intstatus(wlc, false);
+-
+-	/* device is removed */
+-	if (macintstatus == 0xffffffff)
+-		return false;
+-
+-	/* update interrupt status in software */
+-	wlc->macintstatus |= macintstatus;
+-
+-	return true;
+-}
+-
+-/*
+- * First-level interrupt processing.
+- * Return true if this was our interrupt, false otherwise.
+- * *wantdpc will be set to true if further wlc_dpc() processing is required,
+- * false otherwise.
+- */
+-bool wlc_isr(struct wlc_info *wlc, bool *wantdpc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	u32 macintstatus;
+-
+-	*wantdpc = false;
+-
+-	if (!wlc_hw->up || !wlc->macintmask)
+-		return false;
+-
+-	/* read and clear macintstatus and intstatus registers */
+-	macintstatus = wlc_intstatus(wlc, true);
+-
+-	if (macintstatus == 0xffffffff)
+-		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
+-			  " path\n");
+-
+-	/* it is not for us */
+-	if (macintstatus == 0)
+-		return false;
+-
+-	*wantdpc = true;
+-
+-	/* save interrupt status bits */
+-	wlc->macintstatus = macintstatus;
+-
+-	return true;
+-
+-}
+-
+-static bool
+-wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2)
+-{
+-	/* discard intermediate indications for ucode with one legitimate case:
+-	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+-	 *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+-	 *   transmission count)
+-	 */
+-	if (!(txs->status & TX_STATUS_AMPDU)
+-	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
+-		return false;
+-	}
+-
+-	return wlc_dotxstatus(wlc_hw->wlc, txs, s2);
+-}
+-
+-/* process tx completion events in BMAC
+- * Return true if more tx status need to be processed. false otherwise.
+- */
+-static bool
+-wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal)
+-{
+-	bool morepending = false;
+-	struct wlc_info *wlc = wlc_hw->wlc;
+-	d11regs_t *regs;
+-	tx_status_t txstatus, *txs;
+-	u32 s1, s2;
+-	uint n = 0;
+-	/*
+-	 * Param 'max_tx_num' indicates max. # tx status to process before
+-	 * break out.
+-	 */
+-	uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	txs = &txstatus;
+-	regs = wlc_hw->regs;
+-	while (!(*fatal)
+-	       && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
+-
+-		if (s1 == 0xffffffff) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
+-				wlc_hw->unit, __func__);
+-			return morepending;
+-		}
+-
+-			s2 = R_REG(&regs->frmtxstatus2);
+-
+-		txs->status = s1 & TXS_STATUS_MASK;
+-		txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
+-		txs->sequence = s2 & TXS_SEQ_MASK;
+-		txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT;
+-		txs->lasttxtime = 0;
+-
+-		*fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2);
+-
+-		/* !give others some time to run! */
+-		if (++n >= max_tx_num)
+-			break;
+-	}
+-
+-	if (*fatal)
+-		return 0;
+-
+-	if (n >= max_tx_num)
+-		morepending = true;
+-
+-	if (!pktq_empty(&wlc->pkt_queue->q))
+-		wlc_send_q(wlc);
+-
+-	return morepending;
+-}
+-
+-void wlc_suspend_mac_and_wait(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 mc, mi;
+-	struct wiphy *wiphy = wlc->wiphy;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc_hw->band->bandunit);
+-
+-	/*
+-	 * Track overlapping suspend requests
+-	 */
+-	wlc_hw->mac_suspend_depth++;
+-	if (wlc_hw->mac_suspend_depth > 1)
+-		return;
+-
+-	/* force the core awake */
+-	wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-
+-	mc = R_REG(&regs->maccontrol);
+-
+-	if (mc == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-	WARN_ON(!(mc & MCTL_EN_MAC));
+-
+-	mi = R_REG(&regs->macintstatus);
+-	if (mi == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mi & MI_MACSSPNDD);
+-
+-	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0);
+-
+-	SPINWAIT(!(R_REG(&regs->macintstatus) & MI_MACSSPNDD),
+-		 WLC_MAX_MAC_SUSPEND);
+-
+-	if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
+-		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
+-			  " and MI_MACSSPNDD is still not on.\n",
+-			  wlc_hw->unit, WLC_MAX_MAC_SUSPEND);
+-		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
+-			  "psm_brc 0x%04x\n", wlc_hw->unit,
+-			  R_REG(&regs->psmdebug),
+-			  R_REG(&regs->phydebug),
+-			  R_REG(&regs->psm_brc));
+-	}
+-
+-	mc = R_REG(&regs->maccontrol);
+-	if (mc == 0xffffffff) {
+-		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-	WARN_ON(mc & MCTL_EN_MAC);
+-}
+-
+-void wlc_enable_mac(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	d11regs_t *regs = wlc_hw->regs;
+-	u32 mc, mi;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+-		wlc->band->bandunit);
+-
+-	/*
+-	 * Track overlapping suspend requests
+-	 */
+-	wlc_hw->mac_suspend_depth--;
+-	if (wlc_hw->mac_suspend_depth > 0)
+-		return;
+-
+-	mc = R_REG(&regs->maccontrol);
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(mc & MCTL_EN_MAC);
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-
+-	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
+-	W_REG(&regs->macintstatus, MI_MACSSPNDD);
+-
+-	mc = R_REG(&regs->maccontrol);
+-	WARN_ON(mc & MCTL_PSM_JMP_0);
+-	WARN_ON(!(mc & MCTL_EN_MAC));
+-	WARN_ON(!(mc & MCTL_PSM_RUN));
+-
+-	mi = R_REG(&regs->macintstatus);
+-	WARN_ON(mi & MI_MACSSPNDD);
+-
+-	wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
+-}
+-
+-static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw)
+-{
+-	u8 rate;
+-	u8 rates[8] = {
+-		WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M,
+-		WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M
+-	};
+-	u16 entry_ptr;
+-	u16 pctl1;
+-	uint i;
+-
+-	if (!WLC_PHY_11N_CAP(wlc_hw->band))
+-		return;
+-
+-	/* walk the phy rate table and update the entries */
+-	for (i = 0; i < ARRAY_SIZE(rates); i++) {
+-		rate = rates[i];
+-
+-		entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate);
+-
+-		/* read the SHM Rate Table entry OFDM PCTL1 values */
+-		pctl1 =
+-		    wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS);
+-
+-		/* modify the value */
+-		pctl1 &= ~PHY_TXC1_MODE_MASK;
+-		pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT);
+-
+-		/* Update the SHM Rate Table entry OFDM PCTL1 values */
+-		wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS,
+-				   pctl1);
+-	}
+-}
+-
+-static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate)
+-{
+-	uint i;
+-	u8 plcp_rate = 0;
+-	struct plcp_signal_rate_lookup {
+-		u8 rate;
+-		u8 signal_rate;
+-	};
+-	/* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */
+-	const struct plcp_signal_rate_lookup rate_lookup[] = {
+-		{WLC_RATE_6M, 0xB},
+-		{WLC_RATE_9M, 0xF},
+-		{WLC_RATE_12M, 0xA},
+-		{WLC_RATE_18M, 0xE},
+-		{WLC_RATE_24M, 0x9},
+-		{WLC_RATE_36M, 0xD},
+-		{WLC_RATE_48M, 0x8},
+-		{WLC_RATE_54M, 0xC}
+-	};
+-
+-	for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) {
+-		if (rate == rate_lookup[i].rate) {
+-			plcp_rate = rate_lookup[i].signal_rate;
+-			break;
+-		}
+-	}
+-
+-	/* Find the SHM pointer to the rate table entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2));
+-}
+-
+-void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode)
+-{
+-	wlc_hw->hw_stf_ss_opmode = stf_mode;
+-
+-	if (wlc_hw->clk)
+-		wlc_upd_ofdm_pctl1_table(wlc_hw);
+-}
+-
+-void
+-wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr,
+-		  u32 *tsf_h_ptr)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-
+-	/* read the tsf timer low, then high to get an atomic read */
+-	*tsf_l_ptr = R_REG(&regs->tsf_timerlow);
+-	*tsf_h_ptr = R_REG(&regs->tsf_timerhigh);
+-
+-	return;
+-}
+-
+-static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw)
+-{
+-	d11regs_t *regs;
+-	u32 w, val;
+-	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+-
+-	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	regs = wlc_hw->regs;
+-
+-	/* Validate dchip register access */
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	w = R_REG(&regs->objdata);
+-
+-	/* Can we write and read back a 32bit register? */
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, (u32) 0xaa5555aa);
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	val = R_REG(&regs->objdata);
+-	if (val != (u32) 0xaa5555aa) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+-			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
+-		return false;
+-	}
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, (u32) 0x55aaaa55);
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	val = R_REG(&regs->objdata);
+-	if (val != (u32) 0x55aaaa55) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+-			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
+-		return false;
+-	}
+-
+-	W_REG(&regs->objaddr, OBJADDR_SHM_SEL | 0);
+-	(void)R_REG(&regs->objaddr);
+-	W_REG(&regs->objdata, w);
+-
+-	/* clear CFPStart */
+-	W_REG(&regs->tsf_cfpstart, 0);
+-
+-	w = R_REG(&regs->maccontrol);
+-	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
+-	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
+-		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
+-			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
+-			  (MCTL_IHR_EN | MCTL_WAKE),
+-			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
+-		return false;
+-	}
+-
+-	return true;
+-}
+-
+-#define PHYPLL_WAIT_US	100000
+-
+-void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on)
+-{
+-	d11regs_t *regs;
+-	u32 tmp;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	tmp = 0;
+-	regs = wlc_hw->regs;
+-
+-	if (on) {
+-		if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) {
+-			OR_REG(&regs->clk_ctl_st,
+-			       (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL |
+-				CCS_ERSRC_REQ_PHYPLL));
+-			SPINWAIT((R_REG(&regs->clk_ctl_st) &
+-				  (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT),
+-				 PHYPLL_WAIT_US);
+-
+-			tmp = R_REG(&regs->clk_ctl_st);
+-			if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
+-			    (CCS_ERSRC_AVAIL_HT)) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
+-					  " PLL failed\n", __func__);
+-			}
+-		} else {
+-			OR_REG(&regs->clk_ctl_st,
+-			       (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL));
+-			SPINWAIT((R_REG(&regs->clk_ctl_st) &
+-				  (CCS_ERSRC_AVAIL_D11PLL |
+-				   CCS_ERSRC_AVAIL_PHYPLL)) !=
+-				 (CCS_ERSRC_AVAIL_D11PLL |
+-				  CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US);
+-
+-			tmp = R_REG(&regs->clk_ctl_st);
+-			if ((tmp &
+-			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
+-			    !=
+-			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) {
+-				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
+-					  "PHY PLL failed\n", __func__);
+-			}
+-		}
+-	} else {
+-		/* Since the PLL may be shared, other cores can still be requesting it;
+-		 * so we'll deassert the request but not wait for status to comply.
+-		 */
+-		AND_REG(&regs->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL);
+-		tmp = R_REG(&regs->clk_ctl_st);
+-	}
+-}
+-
+-void wlc_coredisable(struct wlc_hw_info *wlc_hw)
+-{
+-	bool dev_gone;
+-
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
+-
+-	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
+-
+-	if (dev_gone)
+-		return;
+-
+-	if (wlc_hw->noreset)
+-		return;
+-
+-	/* radio off */
+-	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
+-
+-	/* turn off analog core */
+-	wlc_phy_anacore(wlc_hw->band->pi, OFF);
+-
+-	/* turn off PHYPLL to save power */
+-	wlc_bmac_core_phypll_ctl(wlc_hw, false);
+-
+-	/* No need to set wlc->pub->radio_active = OFF
+-	 * because this function needs down capability and
+-	 * radio_active is designed for BCMNODOWN.
+-	 */
+-
+-	/* remove gpio controls */
+-	if (wlc_hw->ucode_dbgsel)
+-		ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
+-
+-	wlc_hw->clk = false;
+-	ai_core_disable(wlc_hw->sih, 0);
+-	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-}
+-
+-/* power both the pll and external oscillator on/off */
+-static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
+-
+-	/* dont power down if plldown is false or we must poll hw radio disable */
+-	if (!want && wlc_hw->pllreq)
+-		return;
+-
+-	if (wlc_hw->sih)
+-		ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
+-
+-	wlc_hw->sbclk = want;
+-	if (!wlc_hw->sbclk) {
+-		wlc_hw->clk = false;
+-		if (wlc_hw->band && wlc_hw->band->pi)
+-			wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
+-	}
+-}
+-
+-static void wlc_flushqueues(struct wlc_info *wlc)
+-{
+-	struct wlc_hw_info *wlc_hw = wlc->hw;
+-	uint i;
+-
+-	wlc->txpend16165war = 0;
+-
+-	/* free any posted tx packets */
+-	for (i = 0; i < NFIFO; i++)
+-		if (wlc_hw->di[i]) {
+-			dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL);
+-			TXPKTPENDCLR(wlc, i);
+-			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
+-		}
+-
+-	/* free any posted rx packets */
+-	dma_rxreclaim(wlc_hw->di[RX_FIFO]);
+-}
+-
+-u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset)
+-{
+-	return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL);
+-}
+-
+-void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v)
+-{
+-	wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
+-}
+-
+-static u16
+-wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
+-	volatile u16 *objdata_hi = objdata_lo + 1;
+-	u16 v;
+-
+-	W_REG(&regs->objaddr, sel | (offset >> 2));
+-	(void)R_REG(&regs->objaddr);
+-	if (offset & 2) {
+-		v = R_REG(objdata_hi);
+-	} else {
+-		v = R_REG(objdata_lo);
+-	}
+-
+-	return v;
+-}
+-
+-static void
+-wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel)
+-{
+-	d11regs_t *regs = wlc_hw->regs;
+-	volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
+-	volatile u16 *objdata_hi = objdata_lo + 1;
+-
+-	W_REG(&regs->objaddr, sel | (offset >> 2));
+-	(void)R_REG(&regs->objaddr);
+-	if (offset & 2) {
+-		W_REG(objdata_hi, v);
+-	} else {
+-		W_REG(objdata_lo, v);
+-	}
+-}
+-
+-/* Copy a buffer to shared memory of specified type .
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- * 'sel' selects the type of memory
+- */
+-void
+-wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf,
+-		       int len, u32 sel)
+-{
+-	u16 v;
+-	const u8 *p = (const u8 *)buf;
+-	int i;
+-
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	for (i = 0; i < len; i += 2) {
+-		v = p[i] | (p[i + 1] << 8);
+-		wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel);
+-	}
+-}
+-
+-/* Copy a piece of shared memory of specified type to a buffer .
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- * 'sel' selects the type of memory
+- */
+-void
+-wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf,
+-			 int len, u32 sel)
+-{
+-	u16 v;
+-	u8 *p = (u8 *) buf;
+-	int i;
+-
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	for (i = 0; i < len; i += 2) {
+-		v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel);
+-		p[i] = v & 0xFF;
+-		p[i + 1] = (v >> 8) & 0xFF;
+-	}
+-}
+-
+-void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len)
+-{
+-	BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n",
+-		wlc_hw->vars_size);
+-
+-	*buf = wlc_hw->vars;
+-	*len = wlc_hw->vars_size;
+-}
+-
+-void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL)
+-{
+-	wlc_hw->SRL = SRL;
+-	wlc_hw->LRL = LRL;
+-
+-	/* write retry limit to SCR, shouldn't need to suspend */
+-	if (wlc_hw->up) {
+-		W_REG(&wlc_hw->regs->objaddr,
+-		      OBJADDR_SCR_SEL | S_DOT11_SRC_LMT);
+-		(void)R_REG(&wlc_hw->regs->objaddr);
+-		W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL);
+-		W_REG(&wlc_hw->regs->objaddr,
+-		      OBJADDR_SCR_SEL | S_DOT11_LRC_LMT);
+-		(void)R_REG(&wlc_hw->regs->objaddr);
+-		W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL);
+-	}
+-}
+-
+-void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit)
+-{
+-	if (set) {
+-		if (mboolisset(wlc_hw->pllreq, req_bit))
+-			return;
+-
+-		mboolset(wlc_hw->pllreq, req_bit);
+-
+-		if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+-			if (!wlc_hw->sbclk) {
+-				wlc_bmac_xtal(wlc_hw, ON);
+-			}
+-		}
+-	} else {
+-		if (!mboolisset(wlc_hw->pllreq, req_bit))
+-			return;
+-
+-		mboolclr(wlc_hw->pllreq, req_bit);
+-
+-		if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) {
+-			if (wlc_hw->sbclk) {
+-				wlc_bmac_xtal(wlc_hw, OFF);
+-			}
+-		}
+-	}
+-
+-	return;
+-}
+-
+-u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate)
+-{
+-	u16 table_ptr;
+-	u8 phy_rate, index;
+-
+-	/* get the phy specific rate encoding for the PLCP SIGNAL field */
+-	/* XXX4321 fixup needed ? */
+-	if (IS_OFDM(rate))
+-		table_ptr = M_RT_DIRMAP_A;
+-	else
+-		table_ptr = M_RT_DIRMAP_B;
+-
+-	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
+-	 * the index into the rate table.
+-	 */
+-	phy_rate = rate_info[rate] & WLC_RATE_MASK;
+-	index = phy_rate & 0xf;
+-
+-	/* Find the SHM pointer to the rate table entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2));
+-}
+-
+-void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail)
+-{
+-	wlc_hw->antsel_avail = antsel_avail;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
+deleted file mode 100644
+index a2a4e73..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
++++ /dev/null
+@@ -1,179 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#ifndef _wlc_bmac_h_
+-#define _wlc_bmac_h_
+-
+-/* XXXXX this interface is under wlc.c by design
+- * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign
+- *
+- *        high driver files(e.g. wlc_ampdu.c etc)
+- *             wlc.h/wlc.c
+- *         wlc_bmac.h/wlc_bmac.c
+- *
+- *  So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c
+- *  create wrappers in wlc.c if needed
+- */
+-
+-/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info)
+-   driver */
+-typedef struct wlc_bmac_state {
+-	u32 machwcap;	/* mac hw capibility */
+-	u32 preamble_ovr;	/* preamble override */
+-} wlc_bmac_state_t;
+-
+-enum {
+-	IOV_BMAC_DIAG,
+-	IOV_BMAC_SBGPIOTIMERVAL,
+-	IOV_BMAC_SBGPIOOUT,
+-	IOV_BMAC_CCGPIOCTRL,	/* CC GPIOCTRL REG */
+-	IOV_BMAC_CCGPIOOUT,	/* CC GPIOOUT REG */
+-	IOV_BMAC_CCGPIOOUTEN,	/* CC GPIOOUTEN REG */
+-	IOV_BMAC_CCGPIOIN,	/* CC GPIOIN REG */
+-	IOV_BMAC_WPSGPIO,	/* WPS push button GPIO pin */
+-	IOV_BMAC_OTPDUMP,
+-	IOV_BMAC_OTPSTAT,
+-	IOV_BMAC_PCIEASPM,	/* obfuscation clkreq/aspm control */
+-	IOV_BMAC_PCIEADVCORRMASK,	/* advanced correctable error mask */
+-	IOV_BMAC_PCIECLKREQ,	/* PCIE 1.1 clockreq enab support */
+-	IOV_BMAC_PCIELCREG,	/* PCIE LCREG */
+-	IOV_BMAC_SBGPIOTIMERMASK,
+-	IOV_BMAC_RFDISABLEDLY,
+-	IOV_BMAC_PCIEREG,	/* PCIE REG */
+-	IOV_BMAC_PCICFGREG,	/* PCI Config register */
+-	IOV_BMAC_PCIESERDESREG,	/* PCIE SERDES REG (dev, 0}offset) */
+-	IOV_BMAC_PCIEGPIOOUT,	/* PCIEOUT REG */
+-	IOV_BMAC_PCIEGPIOOUTEN,	/* PCIEOUTEN REG */
+-	IOV_BMAC_PCIECLKREQENCTRL,	/* clkreqenctrl REG (PCIE REV > 6.0 */
+-	IOV_BMAC_DMALPBK,
+-	IOV_BMAC_CCREG,
+-	IOV_BMAC_COREREG,
+-	IOV_BMAC_SDCIS,
+-	IOV_BMAC_SDIO_DRIVE,
+-	IOV_BMAC_OTPW,
+-	IOV_BMAC_NVOTPW,
+-	IOV_BMAC_SROM,
+-	IOV_BMAC_SRCRC,
+-	IOV_BMAC_CIS_SOURCE,
+-	IOV_BMAC_CISVAR,
+-	IOV_BMAC_OTPLOCK,
+-	IOV_BMAC_OTP_CHIPID,
+-	IOV_BMAC_CUSTOMVAR1,
+-	IOV_BMAC_BOARDFLAGS,
+-	IOV_BMAC_BOARDFLAGS2,
+-	IOV_BMAC_WPSLED,
+-	IOV_BMAC_NVRAM_SOURCE,
+-	IOV_BMAC_OTP_RAW_READ,
+-	IOV_BMAC_LAST
+-};
+-
+-extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device,
+-			   uint unit, bool piomode, void *regsva, uint bustype,
+-			   void *btparam);
+-extern int wlc_bmac_detach(struct wlc_info *wlc);
+-extern void wlc_bmac_watchdog(void *arg);
+-
+-/* up/down, reset, clk */
+-extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw,
+-				   uint offset, const void *buf, int len,
+-				   u32 sel);
+-extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset,
+-				     void *buf, int len, u32 sel);
+-#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len)                 \
+-	wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+-#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len)                   \
+-	wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL)
+-
+-extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on);
+-extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk);
+-extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk);
+-extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags);
+-extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags);
+-extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec,
+-			  bool mute);
+-extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw);
+-extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode);
+-
+-/* chanspec, ucode interface */
+-extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw,
+-				  chanspec_t chanspec,
+-				  bool mute, struct txpwr_limits *txpwr);
+-
+-extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo,
+-				   uint *blocks);
+-extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask,
+-			 u16 val, int bands);
+-extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val);
+-extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands);
+-extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant);
+-extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw,
+-				     u8 antsel_type);
+-extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw,
+-			      wlc_bmac_state_t *state);
+-extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v);
+-extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset);
+-extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset,
+-					int len, void *buf);
+-extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf,
+-				   uint *len);
+-
+-extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw,
+-				  u8 *ea);
+-
+-extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw);
+-extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot);
+-extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode);
+-
+-extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw);
+-
+-extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw,
+-					u32 override_bit);
+-extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw,
+-					  u32 override_bit);
+-
+-extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw,
+-				   int match_reg_offset,
+-				   const u8 *addr);
+-extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw,
+-					   void *bcn, int len, bool both);
+-
+-extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr,
+-			      u32 *tsf_h_ptr);
+-extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin);
+-extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax);
+-
+-extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL,
+-				    u16 LRL);
+-
+-extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw);
+-
+-
+-/* API for BMAC driver (e.g. wlc_phy.c etc) */
+-
+-extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw);
+-extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set,
+-			    mbool req_bit);
+-extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw);
+-extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate);
+-extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail);
+-
+-#endif /* _wlc_bmac_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
+deleted file mode 100644
+index 2572541..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
++++ /dev/null
+@@ -1,135 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_BSSCFG_H_
+-#define _WLC_BSSCFG_H_
+-
+-/* Check if a particular BSS config is AP or STA */
+-#define BSSCFG_AP(cfg)		(0)
+-#define BSSCFG_STA(cfg)		(1)
+-
+-#define BSSCFG_IBSS(cfg)	(!(cfg)->BSS)
+-
+-#define NTXRATE			64	/* # tx MPDUs rate is reported for */
+-#define MAXMACLIST		64	/* max # source MAC matches */
+-#define BCN_TEMPLATE_COUNT 	2
+-
+-/* Iterator for "associated" STA bss configs:
+-   (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */
+-#define FOREACH_AS_STA(wlc, idx, cfg) \
+-	for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+-		if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated)
+-
+-/* As above for all non-NULL BSS configs */
+-#define FOREACH_BSS(wlc, idx, cfg) \
+-	for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \
+-		if ((cfg = (wlc)->bsscfg[idx]))
+-
+-/* BSS configuration state */
+-struct wlc_bsscfg {
+-	struct wlc_info *wlc;	/* wlc to which this bsscfg belongs to. */
+-	bool up;		/* is this configuration up operational */
+-	bool enable;		/* is this configuration enabled */
+-	bool associated;	/* is BSS in ASSOCIATED state */
+-	bool BSS;		/* infraustructure or adhac */
+-	bool dtim_programmed;
+-
+-	u8 SSID_len;		/* the length of SSID */
+-	u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */
+-	struct scb *bcmc_scb[MAXBANDS];	/* one bcmc_scb per band */
+-	s8 _idx;		/* the index of this bsscfg,
+-				 * assigned at wlc_bsscfg_alloc()
+-				 */
+-	/* MAC filter */
+-	uint nmac;		/* # of entries on maclist array */
+-	int macmode;		/* allow/deny stations on maclist array */
+-	struct ether_addr *maclist;	/* list of source MAC addrs to match */
+-
+-	/* security */
+-	u32 wsec;		/* wireless security bitvec */
+-	s16 auth;		/* 802.11 authentication: Open, Shared Key, WPA */
+-	s16 openshared;	/* try Open auth first, then Shared Key */
+-	bool wsec_restrict;	/* drop unencrypted packets if wsec is enabled */
+-	bool eap_restrict;	/* restrict data until 802.1X auth succeeds */
+-	u16 WPA_auth;	/* WPA: authenticated key management */
+-	bool wpa2_preauth;	/* default is true, wpa_cap sets value */
+-	bool wsec_portopen;	/* indicates keys are plumbed */
+-	wsec_iv_t wpa_none_txiv;	/* global txiv for WPA_NONE, tkip and aes */
+-	int wsec_index;		/* 0-3: default tx key, -1: not set */
+-	wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS];	/* default key storage */
+-
+-	/* TKIP countermeasures */
+-	bool tkip_countermeasures;	/* flags TKIP no-assoc period */
+-	u32 tk_cm_dt;	/* detect timer */
+-	u32 tk_cm_bt;	/* blocking timer */
+-	u32 tk_cm_bt_tmstmp;	/* Timestamp when TKIP BT is activated */
+-	bool tk_cm_activate;	/* activate countermeasures after EAPOL-Key sent */
+-
+-	u8 BSSID[ETH_ALEN];	/* BSSID (associated) */
+-	u8 cur_etheraddr[ETH_ALEN];	/* h/w address */
+-	u16 bcmc_fid;	/* the last BCMC FID queued to TX_BCMC_FIFO */
+-	u16 bcmc_fid_shm;	/* the last BCMC FID written to shared mem */
+-
+-	u32 flags;		/* WLC_BSSCFG flags; see below */
+-
+-	u8 *bcn;		/* AP beacon */
+-	uint bcn_len;		/* AP beacon length */
+-	bool ar_disassoc;	/* disassociated in associated recreation */
+-
+-	int auth_atmptd;	/* auth type (open/shared) attempted */
+-
+-	pmkid_cand_t pmkid_cand[MAXPMKID];	/* PMKID candidate list */
+-	uint npmkid_cand;	/* num PMKID candidates */
+-	pmkid_t pmkid[MAXPMKID];	/* PMKID cache */
+-	uint npmkid;		/* num cached PMKIDs */
+-
+-	wlc_bss_info_t *current_bss;	/* BSS parms in ASSOCIATED state */
+-
+-	/* PM states */
+-	bool PMawakebcn;	/* bcn recvd during current waking state */
+-	bool PMpending;		/* waiting for tx status with PM indicated set */
+-	bool priorPMstate;	/* Detecting PM state transitions */
+-	bool PSpoll;		/* whether there is an outstanding PS-Poll frame */
+-
+-	/* BSSID entry in RCMTA, use the wsec key management infrastructure to
+-	 * manage the RCMTA entries.
+-	 */
+-	wsec_key_t *rcmta;
+-
+-	/* 'unique' ID of this bsscfg, assigned at bsscfg allocation */
+-	u16 ID;
+-
+-	uint txrspecidx;	/* index into tx rate circular buffer */
+-	ratespec_t txrspec[NTXRATE][2];	/* circular buffer of prev MPDUs tx rates */
+-};
+-
+-#define WLC_BSSCFG_11N_DISABLE	0x1000	/* Do not advertise .11n IEs for this BSS */
+-#define WLC_BSSCFG_HW_BCN	0x20	/* The BSS is generating beacons in HW */
+-
+-#define HWBCN_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0)
+-#define HWPRB_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0)
+-
+-/* Extend N_ENAB to per-BSS */
+-#define BSS_N_ENAB(wlc, cfg) \
+-	(N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE))
+-
+-#define MBSS_BCN_ENAB(cfg)       0
+-#define MBSS_PRB_ENAB(cfg)       0
+-#define SOFTBCN_ENAB(pub)    (0)
+-#define SOFTPRB_ENAB(pub)    (0)
+-#define wlc_bsscfg_tx_check(a) do { } while (0);
+-
+-#endif				/* _WLC_BSSCFG_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
+deleted file mode 100644
+index 85fbd06..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h
++++ /dev/null
+@@ -1,280 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_cfg_h_
+-#define _wlc_cfg_h_
+-
+-#define NBANDS(wlc) ((wlc)->pub->_nbands)
+-#define NBANDS_PUB(pub) ((pub)->_nbands)
+-#define NBANDS_HW(hw) ((hw)->_nbands)
+-
+-#define IS_SINGLEBAND_5G(device)	0
+-
+-/* **** Core type/rev defaults **** */
+-#define D11_DEFAULT	0x0fffffb0	/* Supported  D11 revs: 4, 5, 7-27
+-					 * also need to update wlc.h MAXCOREREV
+-					 */
+-
+-#define NPHY_DEFAULT	0x000001ff	/* Supported nphy revs:
+-					 *      0       4321a0
+-					 *      1       4321a1
+-					 *      2       4321b0/b1/c0/c1
+-					 *      3       4322a0
+-					 *      4       4322a1
+-					 *      5       4716a0
+-					 *      6       43222a0, 43224a0
+-					 *      7       43226a0
+-					 *      8       5357a0, 43236a0
+-					 */
+-
+-#define LCNPHY_DEFAULT	0x00000007	/* Supported lcnphy revs:
+-					 *      0       4313a0, 4336a0, 4330a0
+-					 *      1
+-					 *      2       4330a0
+-					 */
+-
+-#define SSLPNPHY_DEFAULT 0x0000000f	/* Supported sslpnphy revs:
+-					 *      0       4329a0/k0
+-					 *      1       4329b0/4329C0
+-					 *      2       4319a0
+-					 *      3       5356a0
+-					 */
+-
+-
+-/* For undefined values, use defaults */
+-#ifndef D11CONF
+-#define D11CONF	D11_DEFAULT
+-#endif
+-#ifndef NCONF
+-#define NCONF	NPHY_DEFAULT
+-#endif
+-#ifndef LCNCONF
+-#define LCNCONF	LCNPHY_DEFAULT
+-#endif
+-
+-#ifndef SSLPNCONF
+-#define SSLPNCONF	SSLPNPHY_DEFAULT
+-#endif
+-
+-/********************************************************************
+- * Phy/Core Configuration.  Defines macros to to check core phy/rev *
+- * compile-time configuration.  Defines default core support.       *
+- * ******************************************************************
+- */
+-
+-/* Basic macros to check a configuration bitmask */
+-
+-#define CONF_HAS(config, val)	((config) & (1 << (val)))
+-#define CONF_MSK(config, mask)	((config) & (mask))
+-#define MSK_RANGE(low, hi)	((1 << ((hi)+1)) - (1 << (low)))
+-#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high)))
+-
+-#define CONF_IS(config, val)	((config) == (1 << (val)))
+-#define CONF_GE(config, val)	((config) & (0-(1 << (val))))
+-#define CONF_GT(config, val)	((config) & (0-2*(1 << (val))))
+-#define CONF_LT(config, val)	((config) & ((1 << (val))-1))
+-#define CONF_LE(config, val)	((config) & (2*(1 << (val))-1))
+-
+-/* Wrappers for some of the above, specific to config constants */
+-
+-#define NCONF_HAS(val)	CONF_HAS(NCONF, val)
+-#define NCONF_MSK(mask)	CONF_MSK(NCONF, mask)
+-#define NCONF_IS(val)	CONF_IS(NCONF, val)
+-#define NCONF_GE(val)	CONF_GE(NCONF, val)
+-#define NCONF_GT(val)	CONF_GT(NCONF, val)
+-#define NCONF_LT(val)	CONF_LT(NCONF, val)
+-#define NCONF_LE(val)	CONF_LE(NCONF, val)
+-
+-#define LCNCONF_HAS(val)	CONF_HAS(LCNCONF, val)
+-#define LCNCONF_MSK(mask)	CONF_MSK(LCNCONF, mask)
+-#define LCNCONF_IS(val)		CONF_IS(LCNCONF, val)
+-#define LCNCONF_GE(val)		CONF_GE(LCNCONF, val)
+-#define LCNCONF_GT(val)		CONF_GT(LCNCONF, val)
+-#define LCNCONF_LT(val)		CONF_LT(LCNCONF, val)
+-#define LCNCONF_LE(val)		CONF_LE(LCNCONF, val)
+-
+-#define D11CONF_HAS(val) CONF_HAS(D11CONF, val)
+-#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask)
+-#define D11CONF_IS(val)	CONF_IS(D11CONF, val)
+-#define D11CONF_GE(val)	CONF_GE(D11CONF, val)
+-#define D11CONF_GT(val)	CONF_GT(D11CONF, val)
+-#define D11CONF_LT(val)	CONF_LT(D11CONF, val)
+-#define D11CONF_LE(val)	CONF_LE(D11CONF, val)
+-
+-#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val)
+-#define PHYCONF_IS(val)	CONF_IS(PHYTYPE, val)
+-
+-#define NREV_IS(var, val)	(NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val))))
+-#define NREV_GE(var, val)	(NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val))))
+-#define NREV_GT(var, val)	(NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val))))
+-#define NREV_LT(var, val)	(NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val))))
+-#define NREV_LE(var, val)	(NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val))))
+-
+-#define LCNREV_IS(var, val)	(LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val))))
+-#define LCNREV_GE(var, val)	(LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val))))
+-#define LCNREV_GT(var, val)	(LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val))))
+-#define LCNREV_LT(var, val)	(LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val))))
+-#define LCNREV_LE(var, val)	(LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val))))
+-
+-#define D11REV_IS(var, val)	(D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val))))
+-#define D11REV_GE(var, val)	(D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val))))
+-#define D11REV_GT(var, val)	(D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val))))
+-#define D11REV_LT(var, val)	(D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val))))
+-#define D11REV_LE(var, val)	(D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val))))
+-
+-#define PHYTYPE_IS(var, val)	(PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val))))
+-
+-/* Finally, early-exit from switch case if anyone wants it... */
+-
+-#define CASECHECK(config, val)	if (!(CONF_HAS(config, val))) break
+-#define CASEMSK(config, mask)	if (!(CONF_MSK(config, mask))) break
+-
+-#if (D11CONF ^ (D11CONF & D11_DEFAULT))
+-#error "Unsupported MAC revision configured"
+-#endif
+-#if (NCONF ^ (NCONF & NPHY_DEFAULT))
+-#error "Unsupported NPHY revision configured"
+-#endif
+-#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT))
+-#error "Unsupported LPPHY revision configured"
+-#endif
+-
+-/* *** Consistency checks *** */
+-#if !D11CONF
+-#error "No MAC revisions configured!"
+-#endif
+-
+-#if !NCONF && !LCNCONF && !SSLPNCONF
+-#error "No PHY configured!"
+-#endif
+-
+-/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */
+-
+-#define _PHYCONF_N (1 << PHY_TYPE_N)
+-
+-#if LCNCONF
+-#define _PHYCONF_LCN (1 << PHY_TYPE_LCN)
+-#else
+-#define _PHYCONF_LCN 0
+-#endif				/* LCNCONF */
+-
+-#if SSLPNCONF
+-#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN)
+-#else
+-#define _PHYCONF_SSLPN 0
+-#endif				/* SSLPNCONF */
+-
+-#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN)
+-
+-/* Utility macro to identify 802.11n (HT) capable PHYs */
+-#define PHYTYPE_11N_CAP(phytype) \
+-	(PHYTYPE_IS(phytype, PHY_TYPE_N) ||	\
+-	 PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \
+-	 PHYTYPE_IS(phytype, PHY_TYPE_SSN))
+-
+-/* Last but not least: shorter wlc-specific var checks */
+-#define WLCISNPHY(band)		PHYTYPE_IS((band)->phytype, PHY_TYPE_N)
+-#define WLCISLCNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN)
+-#define WLCISSSLPNPHY(band)	PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN)
+-
+-#define WLC_PHY_11N_CAP(band)	PHYTYPE_11N_CAP((band)->phytype)
+-
+-/**********************************************************************
+- * ------------- End of Core phy/rev configuration. ----------------- *
+- * ********************************************************************
+- */
+-
+-/*************************************************
+- * Defaults for tunables (e.g. sizing constants)
+- *
+- * For each new tunable, add a member to the end
+- * of wlc_tunables_t in wlc_pub.h to enable
+- * runtime checks of tunable values. (Directly
+- * using the macros in code invalidates ROM code)
+- *
+- * ***********************************************
+- */
+-#ifndef NTXD
+-#define NTXD		256	/* Max # of entries in Tx FIFO based on 4kb page size */
+-#endif				/* NTXD */
+-#ifndef NRXD
+-#define NRXD		256	/* Max # of entries in Rx FIFO based on 4kb page size */
+-#endif				/* NRXD */
+-
+-#ifndef NRXBUFPOST
+-#define	NRXBUFPOST	32	/* try to keep this # rbufs posted to the chip */
+-#endif				/* NRXBUFPOST */
+-
+-#ifndef MAXSCB			/* station control blocks in cache */
+-#define MAXSCB		32	/* Maximum SCBs in cache for STA */
+-#endif				/* MAXSCB */
+-
+-#ifndef AMPDU_NUM_MPDU
+-#define AMPDU_NUM_MPDU		16	/* max allowed number of mpdus in an ampdu (2 streams) */
+-#endif				/* AMPDU_NUM_MPDU */
+-
+-#ifndef AMPDU_NUM_MPDU_3STREAMS
+-#define AMPDU_NUM_MPDU_3STREAMS	32	/* max allowed number of mpdus in an ampdu for 3+ streams */
+-#endif				/* AMPDU_NUM_MPDU_3STREAMS */
+-
+-/* Count of packet callback structures. either of following
+- * 1. Set to the number of SCBs since a STA
+- * can queue up a rate callback for each IBSS STA it knows about, and an AP can
+- * queue up an "are you there?" Null Data callback for each associated STA
+- * 2. controlled by tunable config file
+- */
+-#ifndef MAXPKTCB
+-#define MAXPKTCB	MAXSCB	/* Max number of packet callbacks */
+-#endif				/* MAXPKTCB */
+-
+-#ifndef CTFPOOLSZ
+-#define CTFPOOLSZ       128
+-#endif				/* CTFPOOLSZ */
+-
+-/* NetBSD also needs to keep track of this */
+-#define WLC_MAX_UCODE_BSS	(16)	/* Number of BSS handled in ucode bcn/prb */
+-#define WLC_MAX_UCODE_BSS4	(4)	/* Number of BSS handled in sw bcn/prb */
+-#ifndef WLC_MAXBSSCFG
+-#define WLC_MAXBSSCFG		(1)	/* max # BSS configs */
+-#endif				/* WLC_MAXBSSCFG */
+-
+-#ifndef MAXBSS
+-#define MAXBSS		64	/* max # available networks */
+-#endif				/* MAXBSS */
+-
+-#ifndef WLC_DATAHIWAT
+-#define WLC_DATAHIWAT		50	/* data msg txq hiwat mark */
+-#endif				/* WLC_DATAHIWAT */
+-
+-#ifndef WLC_AMPDUDATAHIWAT
+-#define WLC_AMPDUDATAHIWAT 255
+-#endif				/* WLC_AMPDUDATAHIWAT */
+-
+-/* bounded rx loops */
+-#ifndef RXBND
+-#define RXBND		8	/* max # frames to process in wlc_recv() */
+-#endif				/* RXBND */
+-#ifndef TXSBND
+-#define TXSBND		8	/* max # tx status to process in wlc_txstatus() */
+-#endif				/* TXSBND */
+-
+-#define BAND_5G(bt)	((bt) == WLC_BAND_5G)
+-#define BAND_2G(bt)	((bt) == WLC_BAND_2G)
+-
+-#define WLBANDINITDATA(_data)	_data
+-#define WLBANDINITFN(_fn)	_fn
+-
+-#endif				/* _wlc_cfg_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c
+deleted file mode 100644
+index a3a2bf9..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c
++++ /dev/null
+@@ -1,1557 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <sbhnddma.h>
+-#include <wlioctl.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_bmac.h"
+-#include "wlc_rate.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_stf.h"
+-#include "wl_dbg.h"
+-
+-#define	VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val)
+-#define	VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \
+-	wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val)
+-#define	VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val)
+-
+-typedef struct wlc_cm_band {
+-	u8 locale_flags;	/* locale_info_t flags */
+-	chanvec_t valid_channels;	/* List of valid channels in the country */
+-	const chanvec_t *restricted_channels;	/* List of restricted use channels */
+-	const chanvec_t *radar_channels;	/* List of radar sensitive channels */
+-	u8 PAD[8];
+-} wlc_cm_band_t;
+-
+-struct wlc_cm_info {
+-	struct wlc_pub *pub;
+-	struct wlc_info *wlc;
+-	char srom_ccode[WLC_CNTRY_BUF_SZ];	/* Country Code in SROM */
+-	uint srom_regrev;	/* Regulatory Rev for the SROM ccode */
+-	const country_info_t *country;	/* current country def */
+-	char ccode[WLC_CNTRY_BUF_SZ];	/* current internal Country Code */
+-	uint regrev;		/* current Regulatory Revision */
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];	/* current advertised ccode */
+-	wlc_cm_band_t bandstate[MAXBANDS];	/* per-band state (one per phy/radio) */
+-	/* quiet channels currently for radar sensitivity or 11h support */
+-	chanvec_t quiet_channels;	/* channels on which we cannot transmit */
+-};
+-
+-static int wlc_channels_init(wlc_cm_info_t *wlc_cm,
+-			     const country_info_t *country);
+-static void wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+-				   const char *country_abbrev,
+-				   const char *ccode, uint regrev,
+-				   const country_info_t *country);
+-static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode);
+-static int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+-				   const char *country_abbrev,
+-				   const char *ccode, int regrev);
+-static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+-				     char *mapped_ccode, uint *mapped_regrev);
+-static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+-						       uint regrev);
+-static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+-						 const char *ccode,
+-						 char *mapped_ccode,
+-						 uint *mapped_regrev);
+-static void wlc_channels_commit(wlc_cm_info_t *wlc_cm);
+-static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm);
+-static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+-static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val);
+-static bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit,
+-					uint val);
+-static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val);
+-static const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+-						const char *ccode);
+-static void wlc_locale_get_channels(const locale_info_t *locale,
+-				    chanvec_t *valid_channels);
+-static const locale_info_t *wlc_get_locale_2g(u8 locale_idx);
+-static const locale_info_t *wlc_get_locale_5g(u8 locale_idx);
+-static bool wlc_japan(struct wlc_info *wlc);
+-static bool wlc_japan_ccode(const char *ccode);
+-static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *
+-								 wlc_cm,
+-								 struct
+-								 txpwr_limits
+-								 *txpwr,
+-								 u8
+-								 local_constraint_qdbm);
+-static void wlc_locale_add_channels(chanvec_t *target,
+-				    const chanvec_t *channels);
+-static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx);
+-static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx);
+-
+-/* QDB() macro takes a dB value and converts to a quarter dB value */
+-#ifdef QDB
+-#undef QDB
+-#endif
+-#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR)
+-
+-/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */
+-
+-/*
+- * Some common channel sets
+- */
+-
+-/* No channels */
+-static const chanvec_t chanvec_none = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* All 2.4 GHz HW channels */
+-const chanvec_t chanvec_all_2G = {
+-	{0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* All 5 GHz HW channels */
+-const chanvec_t chanvec_all_5G = {
+-	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11,
+-	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,
+-	 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11,
+-	 0x11, 0x11, 0x11, 0x01}
+-};
+-
+-/*
+- * Radar channel sets
+- */
+-
+-/* No radar */
+-#define radar_set_none chanvec_none
+-
+-static const chanvec_t radar_set1 = {	/* Channels 52 - 64, 100 - 140 */
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,	/* 52 - 60 */
+-	 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11,	/* 64, 100 - 124 */
+-	 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 128 - 140 */
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/*
+- * Restricted channel sets
+- */
+-
+-#define restricted_set_none chanvec_none
+-
+-/* Channels 34, 38, 42, 46 */
+-static const chanvec_t restricted_set_japan_legacy = {
+-	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 12, 13 */
+-static const chanvec_t restricted_set_2g_short = {
+-	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channel 165 */
+-static const chanvec_t restricted_chan_165 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 36 - 48 & 149 - 165 */
+-static const chanvec_t restricted_low_hi = {
+-	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Channels 12 - 14 */
+-static const chanvec_t restricted_set_12_13_14 = {
+-	{0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-#define  LOCALE_CHAN_01_11	 (1<<0)
+-#define  LOCALE_CHAN_12_13	 (1<<1)
+-#define  LOCALE_CHAN_14		 (1<<2)
+-#define  LOCALE_SET_5G_LOW_JP1   (1<<3)	/* 34-48, step 2 */
+-#define  LOCALE_SET_5G_LOW_JP2   (1<<4)	/* 34-46, step 4 */
+-#define  LOCALE_SET_5G_LOW1      (1<<5)	/* 36-48, step 4 */
+-#define  LOCALE_SET_5G_LOW2      (1<<6)	/* 52 */
+-#define  LOCALE_SET_5G_LOW3      (1<<7)	/* 56-64, step 4 */
+-#define  LOCALE_SET_5G_MID1      (1<<8)	/* 100-116, step 4 */
+-#define  LOCALE_SET_5G_MID2	 (1<<9)	/* 120-124, step 4 */
+-#define  LOCALE_SET_5G_MID3      (1<<10)	/* 128 */
+-#define  LOCALE_SET_5G_HIGH1     (1<<11)	/* 132-140, step 4 */
+-#define  LOCALE_SET_5G_HIGH2     (1<<12)	/* 149-161, step 4 */
+-#define  LOCALE_SET_5G_HIGH3     (1<<13)	/* 165 */
+-#define  LOCALE_CHAN_52_140_ALL  (1<<14)
+-#define  LOCALE_SET_5G_HIGH4     (1<<15)	/* 184-216 */
+-
+-#define  LOCALE_CHAN_36_64       (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+-#define  LOCALE_CHAN_52_64       (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3)
+-#define  LOCALE_CHAN_100_124	 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2)
+-#define  LOCALE_CHAN_100_140     \
+-	(LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1)
+-#define  LOCALE_CHAN_149_165     (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3)
+-#define  LOCALE_CHAN_184_216     LOCALE_SET_5G_HIGH4
+-
+-#define  LOCALE_CHAN_01_14	(LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14)
+-
+-#define  LOCALE_RADAR_SET_NONE		  0
+-#define  LOCALE_RADAR_SET_1		  1
+-
+-#define  LOCALE_RESTRICTED_NONE		  0
+-#define  LOCALE_RESTRICTED_SET_2G_SHORT   1
+-#define  LOCALE_RESTRICTED_CHAN_165       2
+-#define  LOCALE_CHAN_ALL_5G		  3
+-#define  LOCALE_RESTRICTED_JAPAN_LEGACY   4
+-#define  LOCALE_RESTRICTED_11D_2G	  5
+-#define  LOCALE_RESTRICTED_11D_5G	  6
+-#define  LOCALE_RESTRICTED_LOW_HI	  7
+-#define  LOCALE_RESTRICTED_12_13_14	  8
+-
+-/* global memory to provide working buffer for expanded locale */
+-
+-static const chanvec_t *g_table_radar_set[] = {
+-	&chanvec_none,
+-	&radar_set1
+-};
+-
+-static const chanvec_t *g_table_restricted_chan[] = {
+-	&chanvec_none,		/* restricted_set_none */
+-	&restricted_set_2g_short,
+-	&restricted_chan_165,
+-	&chanvec_all_5G,
+-	&restricted_set_japan_legacy,
+-	&chanvec_all_2G,	/* restricted_set_11d_2G */
+-	&chanvec_all_5G,	/* restricted_set_11d_5G */
+-	&restricted_low_hi,
+-	&restricted_set_12_13_14
+-};
+-
+-static const chanvec_t locale_2g_01_11 = {
+-	{0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_2g_12_13 = {
+-	{0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_2g_14 = {
+-	{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW_JP1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW_JP2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_LOW3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_MID3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH1 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH2 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH3 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_52_140_ALL = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11,
+-	 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+-	 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static const chanvec_t locale_5g_HIGH4 = {
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+-	 0x11, 0x11, 0x11, 0x11}
+-};
+-
+-static const chanvec_t *g_table_locale_base[] = {
+-	&locale_2g_01_11,
+-	&locale_2g_12_13,
+-	&locale_2g_14,
+-	&locale_5g_LOW_JP1,
+-	&locale_5g_LOW_JP2,
+-	&locale_5g_LOW1,
+-	&locale_5g_LOW2,
+-	&locale_5g_LOW3,
+-	&locale_5g_MID1,
+-	&locale_5g_MID2,
+-	&locale_5g_MID3,
+-	&locale_5g_HIGH1,
+-	&locale_5g_HIGH2,
+-	&locale_5g_HIGH3,
+-	&locale_5g_52_140_ALL,
+-	&locale_5g_HIGH4
+-};
+-
+-static void wlc_locale_add_channels(chanvec_t *target,
+-				    const chanvec_t *channels)
+-{
+-	u8 i;
+-	for (i = 0; i < sizeof(chanvec_t); i++) {
+-		target->vec[i] |= channels->vec[i];
+-	}
+-}
+-
+-static void wlc_locale_get_channels(const locale_info_t *locale,
+-				    chanvec_t *channels)
+-{
+-	u8 i;
+-
+-	memset(channels, 0, sizeof(chanvec_t));
+-
+-	for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) {
+-		if (locale->valid_channels & (1 << i)) {
+-			wlc_locale_add_channels(channels,
+-						g_table_locale_base[i]);
+-		}
+-	}
+-}
+-
+-/*
+- * Locale Definitions - 2.4 GHz
+- */
+-static const locale_info_t locale_i = {	/* locale i. channel 1 - 13 */
+-	LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13,
+-	LOCALE_RADAR_SET_NONE,
+-	LOCALE_RESTRICTED_SET_2G_SHORT,
+-	{QDB(19), QDB(19), QDB(19),
+-	 QDB(19), QDB(19), QDB(19)},
+-	{20, 20, 20, 0},
+-	WLC_EIRP
+-};
+-
+-/*
+- * Locale Definitions - 5 GHz
+- */
+-static const locale_info_t locale_11 = {
+-	/* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */
+-	LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165,
+-	LOCALE_RADAR_SET_1,
+-	LOCALE_RESTRICTED_NONE,
+-	{QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)},
+-	{23, 23, 23, 30, 30},
+-	WLC_EIRP | WLC_DFS_EU
+-};
+-
+-#define LOCALE_2G_IDX_i			0
+-static const locale_info_t *g_locale_2g_table[] = {
+-	&locale_i
+-};
+-
+-#define LOCALE_5G_IDX_11	0
+-static const locale_info_t *g_locale_5g_table[] = {
+-	&locale_11
+-};
+-
+-/*
+- * MIMO Locale Definitions - 2.4 GHz
+- */
+-static const locale_mimo_info_t locale_bn = {
+-	{QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13)},
+-	{0, 0, QDB(13), QDB(13), QDB(13),
+-	 QDB(13), QDB(13), QDB(13), QDB(13), QDB(13),
+-	 QDB(13), 0, 0},
+-	0
+-};
+-
+-/* locale mimo 2g indexes */
+-#define LOCALE_MIMO_IDX_bn			0
+-
+-static const locale_mimo_info_t *g_mimo_2g_table[] = {
+-	&locale_bn
+-};
+-
+-/*
+- * MIMO Locale Definitions - 5 GHz
+- */
+-static const locale_mimo_info_t locale_11n = {
+-	{ /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)},
+-	{QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)},
+-	0
+-};
+-
+-#define LOCALE_MIMO_IDX_11n			0
+-static const locale_mimo_info_t *g_mimo_5g_table[] = {
+-	&locale_11n
+-};
+-
+-#ifdef LC
+-#undef LC
+-#endif
+-#define LC(id)	LOCALE_MIMO_IDX_ ## id
+-
+-#ifdef LC_2G
+-#undef LC_2G
+-#endif
+-#define LC_2G(id)	LOCALE_2G_IDX_ ## id
+-
+-#ifdef LC_5G
+-#undef LC_5G
+-#endif
+-#define LC_5G(id)	LOCALE_5G_IDX_ ## id
+-
+-#define LOCALES(band2, band5, mimo2, mimo5)     {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)}
+-
+-static const struct {
+-	char abbrev[WLC_CNTRY_BUF_SZ];	/* country abbreviation */
+-	country_info_t country;
+-} cntry_locales[] = {
+-	{
+-	"X2", LOCALES(i, 11, bn, 11n)},	/* Worldwide RoW 2 */
+-};
+-
+-#ifdef SUPPORT_40MHZ
+-/* 20MHz channel info for 40MHz pairing support */
+-struct chan20_info {
+-	u8 sb;
+-	u8 adj_sbs;
+-};
+-
+-/* indicates adjacent channels that are allowed for a 40 Mhz channel and
+- * those that permitted by the HT
+- */
+-struct chan20_info chan20_info[] = {
+-	/* 11b/11g */
+-/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)},
+-/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 11 */ {12, (CH_LOWER_SB)},
+-/* 12 */ {13, (CH_LOWER_SB)},
+-/* 13 */ {14, (CH_LOWER_SB)},
+-
+-/* 11a japan high */
+-/* 14 */ {34, (CH_UPPER_SB)},
+-/* 15 */ {38, (CH_LOWER_SB)},
+-/* 16 */ {42, (CH_LOWER_SB)},
+-/* 17 */ {46, (CH_LOWER_SB)},
+-
+-/* 11a usa low */
+-/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)},
+-
+-/* 11a Europe */
+-/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 36 */ {140, (CH_LOWER_SB)},
+-
+-/* 11a usa high, ref5 only */
+-/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */
+-/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)},
+-/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)},
+-/* 41 */ {165, (CH_LOWER_SB)},
+-
+-/* 11a japan */
+-/* 42 */ {184, (CH_UPPER_SB)},
+-/* 43 */ {188, (CH_LOWER_SB)},
+-/* 44 */ {192, (CH_UPPER_SB)},
+-/* 45 */ {196, (CH_LOWER_SB)},
+-/* 46 */ {200, (CH_UPPER_SB)},
+-/* 47 */ {204, (CH_LOWER_SB)},
+-/* 48 */ {208, (CH_UPPER_SB)},
+-/* 49 */ {212, (CH_LOWER_SB)},
+-/* 50 */ {216, (CH_LOWER_SB)}
+-};
+-#endif				/* SUPPORT_40MHZ */
+-
+-static const locale_info_t *wlc_get_locale_2g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) {
+-		return NULL; /* error condition */
+-	}
+-	return g_locale_2g_table[locale_idx];
+-}
+-
+-static const locale_info_t *wlc_get_locale_5g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) {
+-		return NULL; /* error condition */
+-	}
+-	return g_locale_5g_table[locale_idx];
+-}
+-
+-static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) {
+-		return NULL;
+-	}
+-	return g_mimo_2g_table[locale_idx];
+-}
+-
+-static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx)
+-{
+-	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) {
+-		return NULL;
+-	}
+-	return g_mimo_5g_table[locale_idx];
+-}
+-
+-wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc)
+-{
+-	wlc_cm_info_t *wlc_cm;
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	const country_info_t *country;
+-	struct wlc_pub *pub = wlc->pub;
+-	char *ccode;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC);
+-	if (wlc_cm == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit,
+-			  __func__);
+-		return NULL;
+-	}
+-	wlc_cm->pub = pub;
+-	wlc_cm->wlc = wlc;
+-	wlc->cmi = wlc_cm;
+-
+-	/* store the country code for passing up as a regulatory hint */
+-	ccode = getvar(wlc->pub->vars, "ccode");
+-	if (ccode) {
+-		strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+-	}
+-
+-	/* internal country information which must match regulatory constraints in firmware */
+-	memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ);
+-	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
+-	country = wlc_country_lookup(wlc, country_abbrev);
+-
+-	/* save default country for exiting 11d regulatory mode */
+-	strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+-
+-	/* initialize autocountry_default to driver default */
+-	strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1);
+-
+-	wlc_set_countrycode(wlc_cm, country_abbrev);
+-
+-	return wlc_cm;
+-}
+-
+-void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm)
+-{
+-	kfree(wlc_cm);
+-}
+-
+-u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit)
+-{
+-	return wlc_cm->bandstate[bandunit].locale_flags;
+-}
+-
+-/* set the driver's current country and regulatory information using a country code
+- * as the source. Lookup built in country information found with the country code.
+- */
+-static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode)
+-{
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ);
+-	return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1);
+-}
+-
+-static int
+-wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm,
+-			const char *country_abbrev,
+-			const char *ccode, int regrev)
+-{
+-	const country_info_t *country;
+-	char mapped_ccode[WLC_CNTRY_BUF_SZ];
+-	uint mapped_regrev;
+-
+-	/* if regrev is -1, lookup the mapped country code,
+-	 * otherwise use the ccode and regrev directly
+-	 */
+-	if (regrev == -1) {
+-		/* map the country code to a built-in country code, regrev, and country_info */
+-		country =
+-		    wlc_countrycode_map(wlc_cm, ccode, mapped_ccode,
+-					&mapped_regrev);
+-	} else {
+-		/* find the matching built-in country definition */
+-		country = wlc_country_lookup_direct(ccode, regrev);
+-		strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+-		mapped_regrev = regrev;
+-	}
+-
+-	if (country == NULL)
+-		return -EINVAL;
+-
+-	/* set the driver state for the country */
+-	wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
+-			       mapped_regrev, country);
+-
+-	return 0;
+-}
+-
+-/* set the driver's current country and regulatory information using a country code
+- * as the source. Look up built in country information found with the country code.
+- */
+-static void
+-wlc_set_country_common(wlc_cm_info_t *wlc_cm,
+-		       const char *country_abbrev,
+-		       const char *ccode, uint regrev,
+-		       const country_info_t *country)
+-{
+-	const locale_mimo_info_t *li_mimo;
+-	const locale_info_t *locale;
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	char prev_country_abbrev[WLC_CNTRY_BUF_SZ];
+-
+-	/* save current country state */
+-	wlc_cm->country = country;
+-
+-	memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ);
+-	strncpy(prev_country_abbrev, wlc_cm->country_abbrev,
+-		WLC_CNTRY_BUF_SZ - 1);
+-
+-	strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
+-	strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
+-	wlc_cm->regrev = regrev;
+-
+-	/* disable/restore nmode based on country regulations */
+-	li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G);
+-	if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) {
+-		wlc_set_nmode(wlc, OFF);
+-		wlc->stf->no_cddstbc = true;
+-	} else {
+-		wlc->stf->no_cddstbc = false;
+-		if (N_ENAB(wlc->pub) != wlc->protection->nmode_user)
+-			wlc_set_nmode(wlc, wlc->protection->nmode_user);
+-	}
+-
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-	/* set or restore gmode as required by regulatory */
+-	locale = wlc_get_locale_2g(country->locale_2G);
+-	if (locale && (locale->flags & WLC_NO_OFDM)) {
+-		wlc_set_gmode(wlc, GMODE_LEGACY_B, false);
+-	} else {
+-		wlc_set_gmode(wlc, wlc->protection->gmode_user, false);
+-	}
+-
+-	wlc_channels_init(wlc_cm, country);
+-
+-	return;
+-}
+-
+-/* Lookup a country info structure from a null terminated country code
+- * The lookup is case sensitive.
+- */
+-static const country_info_t *wlc_country_lookup(struct wlc_info *wlc,
+-					 const char *ccode)
+-{
+-	const country_info_t *country;
+-	char mapped_ccode[WLC_CNTRY_BUF_SZ];
+-	uint mapped_regrev;
+-
+-	/* map the country code to a built-in country code, regrev, and country_info struct */
+-	country =
+-	    wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev);
+-
+-	return country;
+-}
+-
+-static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm,
+-						 const char *ccode,
+-						 char *mapped_ccode,
+-						 uint *mapped_regrev)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	const country_info_t *country;
+-	uint srom_regrev = wlc_cm->srom_regrev;
+-	const char *srom_ccode = wlc_cm->srom_ccode;
+-	int mapped;
+-
+-	/* check for currently supported ccode size */
+-	if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
+-			  "match\n", wlc->pub->unit, __func__, ccode);
+-		return NULL;
+-	}
+-
+-	/* default mapping is the given ccode and regrev 0 */
+-	strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
+-	*mapped_regrev = 0;
+-
+-	/* If the desired country code matches the srom country code,
+-	 * then the mapped country is the srom regulatory rev.
+-	 * Otherwise look for an aggregate mapping.
+-	 */
+-	if (!strcmp(srom_ccode, ccode)) {
+-		*mapped_regrev = srom_regrev;
+-		mapped = 0;
+-		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
+-	} else {
+-		mapped =
+-		    wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
+-					      mapped_regrev);
+-	}
+-
+-	/* find the matching built-in country definition */
+-	country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+-
+-	/* if there is not an exact rev match, default to rev zero */
+-	if (country == NULL && *mapped_regrev != 0) {
+-		*mapped_regrev = 0;
+-		country =
+-		    wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
+-	}
+-
+-	return country;
+-}
+-
+-static int
+-wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode,
+-			  char *mapped_ccode, uint *mapped_regrev)
+-{
+-	return false;
+-}
+-
+-/* Lookup a country info structure from a null terminated country
+- * abbreviation and regrev directly with no translation.
+- */
+-static const country_info_t *wlc_country_lookup_direct(const char *ccode,
+-						       uint regrev)
+-{
+-	uint size, i;
+-
+-	/* Should just return 0 for single locale driver. */
+-	/* Keep it this way in case we add more locales. (for now anyway) */
+-
+-	/* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */
+-	if (regrev > 0)
+-		return NULL;
+-
+-	/* find matched table entry from country code */
+-	size = ARRAY_SIZE(cntry_locales);
+-	for (i = 0; i < size; i++) {
+-		if (strcmp(ccode, cntry_locales[i].abbrev) == 0) {
+-			return &cntry_locales[i].country;
+-		}
+-	}
+-	return NULL;
+-}
+-
+-static int
+-wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i, j;
+-	struct wlcband *band;
+-	const locale_info_t *li;
+-	chanvec_t sup_chan;
+-	const locale_mimo_info_t *li_mimo;
+-
+-	band = wlc->band;
+-	for (i = 0; i < NBANDS(wlc);
+-	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+-
+-		li = BAND_5G(band->bandtype) ?
+-		    wlc_get_locale_5g(country->locale_5G) :
+-		    wlc_get_locale_2g(country->locale_2G);
+-		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
+-		li_mimo = BAND_5G(band->bandtype) ?
+-		    wlc_get_mimo_5g(country->locale_mimo_5G) :
+-		    wlc_get_mimo_2g(country->locale_mimo_2G);
+-
+-		/* merge the mimo non-mimo locale flags */
+-		wlc_cm->bandstate[band->bandunit].locale_flags |=
+-		    li_mimo->flags;
+-
+-		wlc_cm->bandstate[band->bandunit].restricted_channels =
+-		    g_table_restricted_chan[li->restricted_channels];
+-		wlc_cm->bandstate[band->bandunit].radar_channels =
+-		    g_table_radar_set[li->radar_channels];
+-
+-		/* set the channel availability,
+-		 * masking out the channels that may not be supported on this phy
+-		 */
+-		wlc_phy_chanspec_band_validch(band->pi, band->bandtype,
+-					      &sup_chan);
+-		wlc_locale_get_channels(li,
+-					&wlc_cm->bandstate[band->bandunit].
+-					valid_channels);
+-		for (j = 0; j < sizeof(chanvec_t); j++)
+-			wlc_cm->bandstate[band->bandunit].valid_channels.
+-			    vec[j] &= sup_chan.vec[j];
+-	}
+-
+-	wlc_quiet_channels_reset(wlc_cm);
+-	wlc_channels_commit(wlc_cm);
+-
+-	return 0;
+-}
+-
+-/* Update the radio state (enable/disable) and tx power targets
+- * based on a new set of channel/regulatory information
+- */
+-static void wlc_channels_commit(wlc_cm_info_t *wlc_cm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint chan;
+-	struct txpwr_limits txpwr;
+-
+-	/* search for the existence of any valid channel */
+-	for (chan = 0; chan < MAXCHANNEL; chan++) {
+-		if (VALID_CHANNEL20_DB(wlc, chan)) {
+-			break;
+-		}
+-	}
+-	if (chan == MAXCHANNEL)
+-		chan = INVCHANNEL;
+-
+-	/* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */
+-	if (chan == INVCHANNEL) {
+-		/* country/locale with no valid channels, set the radio disable bit */
+-		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+-		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
+-			  "nbands %d bandlocked %d\n", wlc->pub->unit,
+-			  __func__, wlc_cm->country_abbrev, NBANDS(wlc),
+-			  wlc->bandlocked);
+-	} else
+-	    if (mboolisset(wlc->pub->radio_disabled,
+-		WL_RADIO_COUNTRY_DISABLE)) {
+-		/* country/locale with valid channel, clear the radio disable bit */
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
+-	}
+-
+-	/* Now that the country abbreviation is set, if the radio supports 2G, then
+-	 * set channel 14 restrictions based on the new locale.
+-	 */
+-	if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) {
+-		wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi,
+-						     wlc_japan(wlc) ? true :
+-						     false);
+-	}
+-
+-	if (wlc->pub->up && chan != INVCHANNEL) {
+-		wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr);
+-		wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm,
+-								     &txpwr,
+-								     WLC_TXPWR_MAX);
+-		wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec);
+-	}
+-}
+-
+-/* reset the quiet channels vector to the union of the restricted and radar channel sets */
+-static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i, j;
+-	struct wlcband *band;
+-	const chanvec_t *chanvec;
+-
+-	memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t));
+-
+-	band = wlc->band;
+-	for (i = 0; i < NBANDS(wlc);
+-	     i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) {
+-
+-		/* initialize quiet channels for restricted channels */
+-		chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels;
+-		for (j = 0; j < sizeof(chanvec_t); j++)
+-			wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j];
+-
+-	}
+-}
+-
+-static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+-{
+-	return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ?
+-		(isset
+-		 (wlc_cm->quiet_channels.vec,
+-		  LOWER_20_SB(CHSPEC_CHANNEL(chspec)))
+-		 || isset(wlc_cm->quiet_channels.vec,
+-			  UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm->
+-									quiet_channels.
+-									vec,
+-									CHSPEC_CHANNEL
+-									(chspec));
+-}
+-
+-/* Is the channel valid for the current locale? (but don't consider channels not
+- *   available due to bandlocking)
+- */
+-static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-
+-	return VALID_CHANNEL20(wlc, val) ||
+-		(!wlc->bandlocked
+-		 && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val));
+-}
+-
+-/* Is the channel valid for the current locale and specified band? */
+-static bool
+-wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val)
+-{
+-	return ((val < MAXCHANNEL)
+-		&& isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val));
+-}
+-
+-/* Is the channel valid for the current locale and current band? */
+-static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-
+-	return ((val < MAXCHANNEL) &&
+-		isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec,
+-		      val));
+-}
+-
+-static void
+-wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm,
+-						     struct txpwr_limits *txpwr,
+-						     u8
+-						     local_constraint_qdbm)
+-{
+-	int j;
+-
+-	/* CCK Rates */
+-	for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) {
+-		txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20 MHz Legacy OFDM SISO */
+-	for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) {
+-		txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20 MHz Legacy OFDM CDD */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_cdd[j] =
+-		    min(txpwr->ofdm_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40 MHz Legacy OFDM SISO */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_40_siso[j] =
+-		    min(txpwr->ofdm_40_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40 MHz Legacy OFDM CDD */
+-	for (j = 0; j < WLC_NUM_RATES_OFDM; j++) {
+-		txpwr->ofdm_40_cdd[j] =
+-		    min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 SISO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_siso[j] =
+-		    min(txpwr->mcs_20_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 CDD */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_cdd[j] =
+-		    min(txpwr->mcs_20_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 0-7 STBC */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_20_stbc[j] =
+-		    min(txpwr->mcs_20_stbc[j], local_constraint_qdbm);
+-	}
+-
+-	/* 20MHz MCS 8-15 MIMO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+-		txpwr->mcs_20_mimo[j] =
+-		    min(txpwr->mcs_20_mimo[j], local_constraint_qdbm);
+-
+-	/* 40MHz MCS 0-7 SISO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_siso[j] =
+-		    min(txpwr->mcs_40_siso[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 0-7 CDD */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_cdd[j] =
+-		    min(txpwr->mcs_40_cdd[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 0-7 STBC */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) {
+-		txpwr->mcs_40_stbc[j] =
+-		    min(txpwr->mcs_40_stbc[j], local_constraint_qdbm);
+-	}
+-
+-	/* 40MHz MCS 8-15 MIMO */
+-	for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++)
+-		txpwr->mcs_40_mimo[j] =
+-		    min(txpwr->mcs_40_mimo[j], local_constraint_qdbm);
+-
+-	/* 40MHz MCS 32 */
+-	txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm);
+-
+-}
+-
+-void
+-wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+-			 u8 local_constraint_qdbm)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	struct txpwr_limits txpwr;
+-
+-	wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr);
+-
+-	wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr,
+-							     local_constraint_qdbm);
+-
+-	wlc_bmac_set_chanspec(wlc->hw, chanspec,
+-			      (wlc_quiet_chanspec(wlc_cm, chanspec) != 0),
+-			      &txpwr);
+-}
+-
+-#ifdef POWER_DBG
+-static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr)
+-{
+-	int i;
+-	char buf[80];
+-	char fraction[4][4] = { "   ", ".25", ".5 ", ".75" };
+-
+-	sprintf(buf, "CCK                ");
+-	for (i = 0; i < WLC_NUM_RATES_CCK; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->cck[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz OFDM SISO   ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz OFDM CDD    ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz OFDM SISO   ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz OFDM CDD    ");
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 SISO ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 CDD  ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS0-7 STBC ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "20 MHz MCS8-15 SDM ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 SISO ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 CDD  ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS0-7 STBC ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	sprintf(buf, "40 MHz MCS8-15 SDM ");
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		sprintf(buf[strlen(buf)], " %2d%s",
+-			txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR,
+-			fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]);
+-	}
+-	printk(KERN_DEBUG "%s\n", buf);
+-
+-	printk(KERN_DEBUG "MCS32               %2d%s\n",
+-	       txpwr->mcs32 / WLC_TXPWR_DB_FACTOR,
+-	       fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]);
+-}
+-#endif				/* POWER_DBG */
+-
+-void
+-wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec,
+-		       txpwr_limits_t *txpwr)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	uint i;
+-	uint chan;
+-	int maxpwr;
+-	int delta;
+-	const country_info_t *country;
+-	struct wlcband *band;
+-	const locale_info_t *li;
+-	int conducted_max;
+-	int conducted_ofdm_max;
+-	const locale_mimo_info_t *li_mimo;
+-	int maxpwr20, maxpwr40;
+-	int maxpwr_idx;
+-	uint j;
+-
+-	memset(txpwr, 0, sizeof(txpwr_limits_t));
+-
+-	if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) {
+-		country = wlc_country_lookup(wlc, wlc->autocountry_default);
+-		if (country == NULL)
+-			return;
+-	} else {
+-		country = wlc_cm->country;
+-	}
+-
+-	chan = CHSPEC_CHANNEL(chanspec);
+-	band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)];
+-	li = BAND_5G(band->bandtype) ?
+-	    wlc_get_locale_5g(country->locale_5G) :
+-	    wlc_get_locale_2g(country->locale_2G);
+-
+-	li_mimo = BAND_5G(band->bandtype) ?
+-	    wlc_get_mimo_5g(country->locale_mimo_5G) :
+-	    wlc_get_mimo_2g(country->locale_mimo_2G);
+-
+-	if (li->flags & WLC_EIRP) {
+-		delta = band->antgain;
+-	} else {
+-		delta = 0;
+-		if (band->antgain > QDB(6))
+-			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
+-	}
+-
+-	if (li == &locale_i) {
+-		conducted_max = QDB(22);
+-		conducted_ofdm_max = QDB(22);
+-	}
+-
+-	/* CCK txpwr limits for 2.4G band */
+-	if (BAND_2G(band->bandtype)) {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)];
+-
+-		maxpwr = maxpwr - delta;
+-		maxpwr = max(maxpwr, 0);
+-		maxpwr = min(maxpwr, conducted_max);
+-
+-		for (i = 0; i < WLC_NUM_RATES_CCK; i++)
+-			txpwr->cck[i] = (u8) maxpwr;
+-	}
+-
+-	/* OFDM txpwr limits for 2.4G or 5G bands */
+-	if (BAND_2G(band->bandtype)) {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)];
+-
+-	} else {
+-		maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)];
+-	}
+-
+-	maxpwr = maxpwr - delta;
+-	maxpwr = max(maxpwr, 0);
+-	maxpwr = min(maxpwr, conducted_ofdm_max);
+-
+-	/* Keep OFDM lmit below CCK limit */
+-	if (BAND_2G(band->bandtype))
+-		maxpwr = min_t(int, maxpwr, txpwr->cck[0]);
+-
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		txpwr->ofdm[i] = (u8) maxpwr;
+-	}
+-
+-	for (i = 0; i < WLC_NUM_RATES_OFDM; i++) {
+-		/* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless
+-		 * overriden by the locale specific code. We set this value to 0 as a
+-		 * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value
+-		 * to the 40 MHz value if it wasn't explicitly set.
+-		 */
+-		txpwr->ofdm_40_siso[i] = 0;
+-
+-		txpwr->ofdm_cdd[i] = (u8) maxpwr;
+-
+-		txpwr->ofdm_40_cdd[i] = 0;
+-	}
+-
+-	/* MIMO/HT specific limits */
+-	if (li_mimo->flags & WLC_EIRP) {
+-		delta = band->antgain;
+-	} else {
+-		delta = 0;
+-		if (band->antgain > QDB(6))
+-			delta = band->antgain - QDB(6);	/* Excess over 6 dB */
+-	}
+-
+-	if (BAND_2G(band->bandtype))
+-		maxpwr_idx = (chan - 1);
+-	else
+-		maxpwr_idx = CHANNEL_POWER_IDX_5G(chan);
+-
+-	maxpwr20 = li_mimo->maxpwr20[maxpwr_idx];
+-	maxpwr40 = li_mimo->maxpwr40[maxpwr_idx];
+-
+-	maxpwr20 = maxpwr20 - delta;
+-	maxpwr20 = max(maxpwr20, 0);
+-	maxpwr40 = maxpwr40 - delta;
+-	maxpwr40 = max(maxpwr40, 0);
+-
+-	/* Fill in the MCS 0-7 (SISO) rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-
+-		/* 20 MHz has the same power as the corresponding OFDM rate unless
+-		 * overriden by the locale specific code.
+-		 */
+-		txpwr->mcs_20_siso[i] = txpwr->ofdm[i];
+-		txpwr->mcs_40_siso[i] = 0;
+-	}
+-
+-	/* Fill in the MCS 0-7 CDD rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		txpwr->mcs_20_cdd[i] = (u8) maxpwr20;
+-		txpwr->mcs_40_cdd[i] = (u8) maxpwr40;
+-	}
+-
+-	/* These locales have SISO expressed in the table and override CDD later */
+-	if (li_mimo == &locale_bn) {
+-		if (li_mimo == &locale_bn) {
+-			maxpwr20 = QDB(16);
+-			maxpwr40 = 0;
+-
+-			if (chan >= 3 && chan <= 11) {
+-				maxpwr40 = QDB(16);
+-			}
+-		}
+-
+-		for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-			txpwr->mcs_20_siso[i] = (u8) maxpwr20;
+-			txpwr->mcs_40_siso[i] = (u8) maxpwr40;
+-		}
+-	}
+-
+-	/* Fill in the MCS 0-7 STBC rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		txpwr->mcs_20_stbc[i] = 0;
+-		txpwr->mcs_40_stbc[i] = 0;
+-	}
+-
+-	/* Fill in the MCS 8-15 SDM rates */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) {
+-		txpwr->mcs_20_mimo[i] = (u8) maxpwr20;
+-		txpwr->mcs_40_mimo[i] = (u8) maxpwr40;
+-	}
+-
+-	/* Fill in MCS32 */
+-	txpwr->mcs32 = (u8) maxpwr40;
+-
+-	for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+-		if (txpwr->ofdm_40_cdd[i] == 0)
+-			txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+-		if (i == 0) {
+-			i = i + 1;
+-			if (txpwr->ofdm_40_cdd[i] == 0)
+-				txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j];
+-		}
+-	}
+-
+-	/* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't
+-	 * provided explicitly.
+-	 */
+-
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		if (txpwr->mcs_40_siso[i] == 0)
+-			txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i];
+-	}
+-
+-	for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) {
+-		if (txpwr->ofdm_40_siso[i] == 0)
+-			txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+-		if (i == 0) {
+-			i = i + 1;
+-			if (txpwr->ofdm_40_siso[i] == 0)
+-				txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j];
+-		}
+-	}
+-
+-	/* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't
+-	 * provided explicitly.
+-	 */
+-	for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) {
+-		if (txpwr->mcs_20_stbc[i] == 0)
+-			txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i];
+-
+-		if (txpwr->mcs_40_stbc[i] == 0)
+-			txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i];
+-	}
+-
+-#ifdef POWER_DBG
+-	wlc_phy_txpower_limits_dump(txpwr);
+-#endif
+-	return;
+-}
+-
+-/* Returns true if currently set country is Japan or variant */
+-static bool wlc_japan(struct wlc_info *wlc)
+-{
+-	return wlc_japan_ccode(wlc->cmi->country_abbrev);
+-}
+-
+-/* JP, J1 - J10 are Japan ccodes */
+-static bool wlc_japan_ccode(const char *ccode)
+-{
+-	return (ccode[0] == 'J' &&
+-		(ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9')));
+-}
+-
+-/*
+- * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands
+- * are valid 20MZH channels in this locale and they are also a legal HT combination
+- */
+-static bool
+-wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband)
+-{
+-	struct wlc_info *wlc = wlc_cm->wlc;
+-	u8 channel = CHSPEC_CHANNEL(chspec);
+-
+-	/* check the chanspec */
+-	if (bcm_chspec_malformed(chspec)) {
+-		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
+-			wlc->pub->unit, chspec);
+-		return false;
+-	}
+-
+-	if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) !=
+-	    CHSPEC_WLCBANDUNIT(chspec))
+-		return false;
+-
+-	/* Check a 20Mhz channel */
+-	if (CHSPEC_IS20(chspec)) {
+-		if (dualband)
+-			return VALID_CHANNEL20_DB(wlc_cm->wlc, channel);
+-		else
+-			return VALID_CHANNEL20(wlc_cm->wlc, channel);
+-	}
+-#ifdef SUPPORT_40MHZ
+-	/* We know we are now checking a 40MHZ channel, so we should only be here
+-	 * for NPHYS
+-	 */
+-	if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) {
+-		u8 upper_sideband = 0, idx;
+-		u8 num_ch20_entries =
+-		    sizeof(chan20_info) / sizeof(struct chan20_info);
+-
+-		if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec)))
+-			return false;
+-
+-		if (dualband) {
+-			if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) ||
+-			    !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel)))
+-				return false;
+-		} else {
+-			if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) ||
+-			    !VALID_CHANNEL20(wlc, UPPER_20_SB(channel)))
+-				return false;
+-		}
+-
+-		/* find the lower sideband info in the sideband array */
+-		for (idx = 0; idx < num_ch20_entries; idx++) {
+-			if (chan20_info[idx].sb == LOWER_20_SB(channel))
+-				upper_sideband = chan20_info[idx].adj_sbs;
+-		}
+-		/* check that the lower sideband allows an upper sideband */
+-		if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) ==
+-		    (CH_UPPER_SB | CH_EWA_VALID))
+-			return true;
+-		return false;
+-	}
+-#endif				/* 40 MHZ */
+-
+-	return false;
+-}
+-
+-bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec)
+-{
+-	return wlc_valid_chanspec_ext(wlc_cm, chspec, true);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h
+deleted file mode 100644
+index b8dec5b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h
++++ /dev/null
+@@ -1,120 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_CHANNEL_H_
+-#define _WLC_CHANNEL_H_
+-
+-#define WLC_TXPWR_DB_FACTOR 4	/* conversion for phy txpwr cacluations that use .25 dB units */
+-
+-struct wlc_info;
+-
+-/* maxpwr mapping to 5GHz band channels:
+- * maxpwr[0] - channels [34-48]
+- * maxpwr[1] - channels [52-60]
+- * maxpwr[2] - channels [62-64]
+- * maxpwr[3] - channels [100-140]
+- * maxpwr[4] - channels [149-165]
+- */
+-#define BAND_5G_PWR_LVLS	5	/* 5 power levels for 5G */
+-
+-/* power level in group of 2.4GHz band channels:
+- * maxpwr[0] - CCK  channels [1]
+- * maxpwr[1] - CCK  channels [2-10]
+- * maxpwr[2] - CCK  channels [11-14]
+- * maxpwr[3] - OFDM channels [1]
+- * maxpwr[4] - OFDM channels [2-10]
+- * maxpwr[5] - OFDM channels [11-14]
+- */
+-
+-/* macro to get 2.4 GHz channel group index for tx power */
+-#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2))	/* cck index */
+-#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5))	/* ofdm index */
+-
+-/* macro to get 5 GHz channel group index for tx power */
+-#define CHANNEL_POWER_IDX_5G(c) \
+-	(((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4))))
+-
+-#define WLC_MAXPWR_TBL_SIZE		6	/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */
+-#define WLC_MAXPWR_MIMO_TBL_SIZE	14	/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */
+-
+-/* locale channel and power info. */
+-typedef struct {
+-	u32 valid_channels;
+-	u8 radar_channels;	/* List of radar sensitive channels */
+-	u8 restricted_channels;	/* List of channels used only if APs are detected */
+-	s8 maxpwr[WLC_MAXPWR_TBL_SIZE];	/* Max tx pwr in qdBm for each sub-band */
+-	s8 pub_maxpwr[BAND_5G_PWR_LVLS];	/* Country IE advertised max tx pwr in dBm
+-						 * per sub-band
+-						 */
+-	u8 flags;
+-} locale_info_t;
+-
+-/* bits for locale_info flags */
+-#define WLC_PEAK_CONDUCTED	0x00	/* Peak for locals */
+-#define WLC_EIRP		0x01	/* Flag for EIRP */
+-#define WLC_DFS_TPC		0x02	/* Flag for DFS TPC */
+-#define WLC_NO_OFDM		0x04	/* Flag for No OFDM */
+-#define WLC_NO_40MHZ		0x08	/* Flag for No MIMO 40MHz */
+-#define WLC_NO_MIMO		0x10	/* Flag for No MIMO, 20 or 40 MHz */
+-#define WLC_RADAR_TYPE_EU       0x20	/* Flag for EU */
+-#define WLC_DFS_FCC             WLC_DFS_TPC	/* Flag for DFS FCC */
+-#define WLC_DFS_EU              (WLC_DFS_TPC | WLC_RADAR_TYPE_EU)	/* Flag for DFS EU */
+-
+-#define ISDFS_EU(fl)		(((fl) & WLC_DFS_EU) == WLC_DFS_EU)
+-
+-/* locale per-channel tx power limits for MIMO frames
+- * maxpwr arrays are index by channel for 2.4 GHz limits, and
+- * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel)
+- */
+-typedef struct {
+-	s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE];	/* tx 20 MHz power limits, qdBm units */
+-	s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE];	/* tx 40 MHz power limits, qdBm units */
+-	u8 flags;
+-} locale_mimo_info_t;
+-
+-extern const chanvec_t chanvec_all_2G;
+-extern const chanvec_t chanvec_all_5G;
+-
+-/*
+- * Country names and abbreviations with locale defined from ISO 3166
+- */
+-struct country_info {
+-	const u8 locale_2G;	/* 2.4G band locale */
+-	const u8 locale_5G;	/* 5G band locale */
+-	const u8 locale_mimo_2G;	/* 2.4G mimo info */
+-	const u8 locale_mimo_5G;	/* 5G mimo info */
+-};
+-
+-typedef struct country_info country_info_t;
+-
+-typedef struct wlc_cm_info wlc_cm_info_t;
+-
+-extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc);
+-extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm);
+-
+-extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm,
+-					   uint bandunit);
+-
+-extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec);
+-
+-extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm,
+-				   chanspec_t chanspec,
+-				   struct txpwr_limits *txpwr);
+-extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm,
+-				     chanspec_t chanspec,
+-				     u8 local_constraint_qdbm);
+-
+-#endif				/* _WLC_CHANNEL_H */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h
+deleted file mode 100644
+index cab10c7..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h
++++ /dev/null
+@@ -1,140 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_key_h_
+-#define _wlc_key_h_
+-
+-struct scb;
+-struct wlc_info;
+-struct wlc_bsscfg;
+-/* Maximum # of keys that wl driver supports in S/W.
+- * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS.
+- */
+-#define WSEC_MAX_KEYS		54	/* Max # of keys (50 + 4 default keys) */
+-#define WLC_DEFAULT_KEYS	4	/* Default # of keys */
+-
+-#define WSEC_MAX_WOWL_KEYS 5	/* Max keys in WOWL mode (1 + 4 default keys) */
+-
+-#define WPA2_GTK_MAX	3
+-
+-/*
+-* Max # of keys currently supported:
+-*
+-*     s/w keys if WSEC_SW(wlc->wsec).
+-*     h/w keys otherwise.
+-*/
+-#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS
+-
+-/* number of 802.11 default (non-paired, group keys) */
+-#define WSEC_MAX_DEFAULT_KEYS	4	/* # of default keys */
+-
+-/* Max # of hardware keys supported */
+-#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS
+-
+-/* Max # of hardware TKIP MIC keys supported */
+-#define WLC_MAX_TKMIC_HW_KEYS(wlc) (WSEC_MAX_TKMIC_ENGINE_KEYS)
+-
+-#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \
+-	((((wlc)->machwcap & MCAP_TKIPMIC)) && \
+-	 (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \
+-	 !WSEC_SOFTKEY(wlc, key, bsscfg) && \
+-	WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \
+-	(WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS))
+-
+-/* index of key in key table */
+-#define WSEC_KEY_INDEX(wlc, key)	((key)->idx)
+-
+-#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \
+-	WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc))
+-
+-/* get a key, non-NULL only if key allocated and not clear */
+-#define WSEC_KEY(wlc, i)	(((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \
+-	(wlc)->wsec_keys[i] : NULL)
+-
+-#define WSEC_SCB_KEY_VALID(scb)	(((scb)->key && (scb)->key->len) ? true : false)
+-
+-/* default key */
+-#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \
+-	(struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index])
+-
+-/* Macros for key management in IBSS mode */
+-#define WSEC_IBSS_MAX_PEERS	16	/* Max # of IBSS Peers */
+-#define WSEC_IBSS_RCMTA_INDEX(idx) \
+-	(((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS)
+-
+-/* contiguous # key slots for infrastructure mode STA */
+-#define WSEC_BSS_STA_KEY_GROUP_SIZE	5
+-
+-typedef struct wsec_iv {
+-	u32 hi;		/* upper 32 bits of IV */
+-	u16 lo;		/* lower 16 bits of IV */
+-} wsec_iv_t;
+-
+-#define WLC_NUMRXIVS	16	/* # rx IVs (one per 802.11e TID) */
+-
+-typedef struct wsec_key {
+-	u8 ea[ETH_ALEN];	/* per station */
+-	u8 idx;		/* key index in wsec_keys array */
+-	u8 id;		/* key ID [0-3] */
+-	u8 algo;		/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+-	u8 rcmta;		/* rcmta entry index, same as idx by default */
+-	u16 flags;		/* misc flags */
+-	u8 algo_hw;		/* cache for hw register */
+-	u8 aes_mode;		/* cache for hw register */
+-	s8 iv_len;		/* IV length */
+-	s8 icv_len;		/* ICV length */
+-	u32 len;		/* key length..don't move this var */
+-	/* data is 4byte aligned */
+-	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
+-	wsec_iv_t rxiv[WLC_NUMRXIVS];	/* Rx IV (one per TID) */
+-	wsec_iv_t txiv;		/* Tx IV */
+-
+-} wsec_key_t;
+-
+-#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+-
+-/* For use with wsec_key_t.flags */
+-
+-#define WSEC_BS_UPDATE		(1 << 0)	/* Indicates hw needs key update on BS switch */
+-#define WSEC_PRIMARY_KEY	(1 << 1)	/* Indicates this key is the primary (ie tx) key */
+-#define WSEC_TKIP_ERROR		(1 << 2)	/* Provoke deliberate MIC error */
+-#define WSEC_REPLAY_ERROR	(1 << 3)	/* Provoke deliberate replay */
+-#define WSEC_IBSS_PEER_GROUP_KEY	(1 << 7)	/* Flag: group key for a IBSS PEER */
+-#define WSEC_ICV_ERROR		(1 << 8)	/* Provoke deliberate ICV error */
+-
+-#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (-EBADE)
+-#define wlc_key_update(a, b, c) do {} while (0)
+-#define wlc_key_remove(a, b, c) do {} while (0)
+-#define wlc_key_remove_all(a, b) do {} while (0)
+-#define wlc_key_delete(a, b, c) do {} while (0)
+-#define wlc_scb_key_delete(a, b) do {} while (0)
+-#define wlc_key_lookup(a, b, c, d, e) (NULL)
+-#define wlc_key_hw_init_all(a) do {} while (0)
+-#define wlc_key_hw_init(a, b, c)  do {} while (0)
+-#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0)
+-#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0)
+-#define wlc_key_sw_wowl_create(a, b, c) (-EBADE)
+-#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0)
+-#define wlc_key_iv_init(a, b, c) do {} while (0)
+-#define wlc_key_set_error(a, b, c) (-EBADE)
+-#define wlc_key_dump_hw(a, b) (-EBADE)
+-#define wlc_key_dump_sw(a, b) (-EBADE)
+-#define wlc_key_defkeyflag(a) (0)
+-#define wlc_rcmta_add_bssid(a, b) do {} while (0)
+-#define wlc_rcmta_del_bssid(a, b) do {} while (0)
+-#define wlc_key_scb_delete(a, b) do {} while (0)
+-
+-#endif				/* _wlc_key_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c
+deleted file mode 100644
+index 99250e2..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c
++++ /dev/null
+@@ -1,7537 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/ctype.h>
+-#include <linux/etherdevice.h>
+-#include <linux/pci_ids.h>
+-#include <net/mac80211.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmdevs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-#include <bcmnvram.h>
+-#include <aiutils.h>
+-#include <pcicfg.h>
+-#include <bcmsrom.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-
+-#include "wlc_pmu.h"
+-#include "d11.h"
+-#include "wlc_types.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "wlc_bsscfg.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wlc_bmac.h"
+-#include "wlc_phy_hal.h"
+-#include "wlc_phy_shim.h"
+-#include "wlc_antsel.h"
+-#include "wlc_stf.h"
+-#include "wlc_ampdu.h"
+-#include "wl_export.h"
+-#include "wlc_alloc.h"
+-#include "wl_dbg.h"
+-
+-#include "wl_mac80211.h"
+-
+-/*
+- * WPA(2) definitions
+- */
+-#define RSN_CAP_4_REPLAY_CNTRS		2
+-#define RSN_CAP_16_REPLAY_CNTRS		3
+-
+-#define WPA_CAP_4_REPLAY_CNTRS		RSN_CAP_4_REPLAY_CNTRS
+-#define WPA_CAP_16_REPLAY_CNTRS		RSN_CAP_16_REPLAY_CNTRS
+-
+-/*
+- * Indication for txflowcontrol that all priority bits in
+- * TXQ_STOP_FOR_PRIOFC_MASK are to be considered.
+- */
+-#define ALLPRIO		-1
+-
+-/*
+- * buffer length needed for wlc_format_ssid
+- * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+- */
+-#define SSID_FMT_BUF_LEN	((4 * IEEE80211_MAX_SSID_LEN) + 1)
+-
+-#define	TIMER_INTERVAL_WATCHDOG	1000	/* watchdog timer, in unit of ms */
+-#define	TIMER_INTERVAL_RADIOCHK	800	/* radio monitor timer, in unit of ms */
+-
+-#ifndef WLC_MPC_MAX_DELAYCNT
+-#define	WLC_MPC_MAX_DELAYCNT	10	/* Max MPC timeout, in unit of watchdog */
+-#endif
+-#define	WLC_MPC_MIN_DELAYCNT	1	/* Min MPC timeout, in unit of watchdog */
+-#define	WLC_MPC_THRESHOLD	3	/* MPC count threshold level */
+-
+-#define	BEACON_INTERVAL_DEFAULT	100	/* beacon interval, in unit of 1024TU */
+-#define	DTIM_INTERVAL_DEFAULT	3	/* DTIM interval, in unit of beacon interval */
+-
+-/* Scale down delays to accommodate QT slow speed */
+-#define	BEACON_INTERVAL_DEF_QT	20	/* beacon interval, in unit of 1024TU */
+-#define	DTIM_INTERVAL_DEF_QT	1	/* DTIM interval, in unit of beacon interval */
+-
+-#define	TBTT_ALIGN_LEEWAY_US	100	/* min leeway before first TBTT in us */
+-
+-/*
+- * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft
+- * watchdog) it is not a wall clock and won't increment when driver is in "down" state
+- * this low resolution driver tick can be used for maintenance tasks such as phy
+- * calibration and scb update
+- */
+-
+-/* watchdog trigger mode: OSL timer or TBTT */
+-#define WLC_WATCHDOG_TBTT(wlc) \
+-	(wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt)
+-
+-/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */
+-#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid))
+-
+-#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \
+-				(!AP_ENAB(wlc->pub)) && (wlc->war16165))
+-
+-/* debug/trace */
+-uint wl_msg_level =
+-#if defined(BCMDBG)
+-    WL_ERROR_VAL;
+-#else
+-    0;
+-#endif				/* BCMDBG */
+-
+-/* Find basic rate for a given rate */
+-#define WLC_BASIC_RATE(wlc, rspec)	(IS_MCS(rspec) ? \
+-			(wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \
+-			(wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK])
+-
+-#define FRAMETYPE(r, mimoframe)	(IS_MCS(r) ? mimoframe	: (IS_CCK(r) ? FT_CCK : FT_OFDM))
+-
+-#define RFDISABLE_DEFAULT	10000000	/* rfdisable delay timer 500 ms, runs of ALP clock */
+-
+-#define WLC_TEMPSENSE_PERIOD		10	/* 10 second timeout */
+-
+-#define SCAN_IN_PROGRESS(x)	0
+-
+-#define EPI_VERSION_NUM		0x054b0b00
+-
+-#ifdef BCMDBG
+-/* pointer to most recently allocated wl/wlc */
+-static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL);
+-#endif
+-
+-/* IOVar table */
+-
+-/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars
+- * table and by the wlc_doiovar() function.  No ordering is imposed:
+- * the table is keyed by name, and the function uses a switch.
+- */
+-enum {
+-	IOV_MPC = 1,
+-	IOV_RTSTHRESH,
+-	IOV_QTXPOWER,
+-	IOV_BCN_LI_BCN,		/* Beacon listen interval in # of beacons */
+-	IOV_LAST		/* In case of a need to check max ID number */
+-};
+-
+-const bcm_iovar_t wlc_iovars[] = {
+-	{"mpc", IOV_MPC, (0), IOVT_BOOL, 0},
+-	{"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0},
+-	{"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0},
+-	{"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0},
+-	{NULL, 0, 0, 0, 0}
+-};
+-
+-const u8 prio2fifo[NUMPRIO] = {
+-	TX_AC_BE_FIFO,		/* 0    BE      AC_BE   Best Effort */
+-	TX_AC_BK_FIFO,		/* 1    BK      AC_BK   Background */
+-	TX_AC_BK_FIFO,		/* 2    --      AC_BK   Background */
+-	TX_AC_BE_FIFO,		/* 3    EE      AC_BE   Best Effort */
+-	TX_AC_VI_FIFO,		/* 4    CL      AC_VI   Video */
+-	TX_AC_VI_FIFO,		/* 5    VI      AC_VI   Video */
+-	TX_AC_VO_FIFO,		/* 6    VO      AC_VO   Voice */
+-	TX_AC_VO_FIFO		/* 7    NC      AC_VO   Voice */
+-};
+-
+-/* precedences numbers for wlc queues. These are twice as may levels as
+- * 802.1D priorities.
+- * Odd numbers are used for HI priority traffic at same precedence levels
+- * These constants are used ONLY by wlc_prio2prec_map.  Do not use them elsewhere.
+- */
+-#define	_WLC_PREC_NONE		0	/* None = - */
+-#define	_WLC_PREC_BK		2	/* BK - Background */
+-#define	_WLC_PREC_BE		4	/* BE - Best-effort */
+-#define	_WLC_PREC_EE		6	/* EE - Excellent-effort */
+-#define	_WLC_PREC_CL		8	/* CL - Controlled Load */
+-#define	_WLC_PREC_VI		10	/* Vi - Video */
+-#define	_WLC_PREC_VO		12	/* Vo - Voice */
+-#define	_WLC_PREC_NC		14	/* NC - Network Control */
+-
+-/* 802.1D Priority to precedence queue mapping */
+-const u8 wlc_prio2prec_map[] = {
+-	_WLC_PREC_BE,		/* 0 BE - Best-effort */
+-	_WLC_PREC_BK,		/* 1 BK - Background */
+-	_WLC_PREC_NONE,		/* 2 None = - */
+-	_WLC_PREC_EE,		/* 3 EE - Excellent-effort */
+-	_WLC_PREC_CL,		/* 4 CL - Controlled Load */
+-	_WLC_PREC_VI,		/* 5 Vi - Video */
+-	_WLC_PREC_VO,		/* 6 Vo - Voice */
+-	_WLC_PREC_NC,		/* 7 NC - Network Control */
+-};
+-
+-/* Sanity check for tx_prec_map and fifo synchup
+- * Either there are some packets pending for the fifo, else if fifo is empty then
+- * all the corresponding precmap bits should be set
+- */
+-#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) ||	\
+-	(TXPKTPENDGET((wlc), (fifo)) == 0 && \
+-	((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \
+-	(wlc)->fifo2prec_map[(fifo)]))
+-
+-/* TX FIFO number to WME/802.1E Access Category */
+-const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };
+-
+-/* WME/802.1E Access Category to TX FIFO number */
+-static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };
+-
+-static bool in_send_q = false;
+-
+-/* Shared memory location index for various AC params */
+-#define wme_shmemacindex(ac)	wme_ac2fifo[ac]
+-
+-#ifdef BCMDBG
+-static const char *fifo_names[] = {
+-	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
+-#else
+-static const char fifo_names[6][0];
+-#endif
+-
+-static const u8 acbitmap2maxprio[] = {
+-	PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK,
+-	PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI,
+-	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO,
+-	PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO
+-};
+-
+-/* currently the best mechanism for determining SIFS is the band in use */
+-#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME);
+-
+-/* value for # replay counters currently supported */
+-#define WLC_REPLAY_CNTRS_VALUE	WPA_CAP_16_REPLAY_CNTRS
+-
+-/* local prototypes */
+-static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc,
+-					       struct ieee80211_hw *hw,
+-					       struct sk_buff *p,
+-					       struct scb *scb, uint frag,
+-					       uint nfrags, uint queue,
+-					       uint next_frag_len,
+-					       wsec_key_t *key,
+-					       ratespec_t rspec_override);
+-static void wlc_bss_default_init(struct wlc_info *wlc);
+-static void wlc_ucode_mac_upd(struct wlc_info *wlc);
+-static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc,
+-					 struct wlcband *cur_band, u32 int_val);
+-static void wlc_tx_prec_map_init(struct wlc_info *wlc);
+-static void wlc_watchdog(void *arg);
+-static void wlc_watchdog_by_timer(void *arg);
+-static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate);
+-static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg);
+-static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val,
+-				const bcm_iovar_t *vi);
+-static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc);
+-
+-/* send and receive */
+-static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc);
+-static void wlc_txq_free(struct wlc_info *wlc,
+-			 struct wlc_txq_info *qi);
+-static void wlc_txflowcontrol_signal(struct wlc_info *wlc,
+-				     struct wlc_txq_info *qi,
+-				     bool on, int prio);
+-static void wlc_txflowcontrol_reset(struct wlc_info *wlc);
+-static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rate,
+-				 uint length, u8 *plcp);
+-static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
+-static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
+-static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate,
+-				    u8 preamble_type, uint next_frag_len);
+-static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh);
+-static void wlc_recvctl(struct wlc_info *wlc,
+-			d11rxhdr_t *rxh, struct sk_buff *p);
+-static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate,
+-			       u8 preamble_type, uint dur);
+-static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate,
+-			      u8 preamble_type);
+-static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate,
+-			      u8 preamble_type);
+-/* interrupt, up/down, band */
+-static void wlc_setband(struct wlc_info *wlc, uint bandunit);
+-static chanspec_t wlc_init_chanspec(struct wlc_info *wlc);
+-static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec);
+-static void wlc_bsinit(struct wlc_info *wlc);
+-static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
+-			      bool writeToShm);
+-static void wlc_radio_hwdisable_upd(struct wlc_info *wlc);
+-static bool wlc_radio_monitor_start(struct wlc_info *wlc);
+-static void wlc_radio_timer(void *arg);
+-static void wlc_radio_enable(struct wlc_info *wlc);
+-static void wlc_radio_upd(struct wlc_info *wlc);
+-
+-/* scan, association, BSS */
+-static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate,
+-			     u8 preamble_type);
+-static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap);
+-static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val);
+-static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val);
+-static void wlc_war16165(struct wlc_info *wlc, bool tx);
+-
+-static void wlc_wme_retries_write(struct wlc_info *wlc);
+-static bool wlc_attach_stf_ant_init(struct wlc_info *wlc);
+-static uint wlc_attach_module(struct wlc_info *wlc);
+-static void wlc_detach_module(struct wlc_info *wlc);
+-static void wlc_timers_deinit(struct wlc_info *wlc);
+-static void wlc_down_led_upd(struct wlc_info *wlc);
+-static uint wlc_down_del_timer(struct wlc_info *wlc);
+-static void wlc_ofdm_rateset_war(struct wlc_info *wlc);
+-static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-		      struct wlc_if *wlcif);
+-
+-/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
+- */
+-bool wlc_ps_allowed(struct wlc_info *wlc)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	/* disallow PS when one of the following global conditions meets */
+-	if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override)
+-		return false;
+-
+-	/* disallow PS when one of these meets when not scanning */
+-	if (!wlc->PMblocked) {
+-		if (AP_ACTIVE(wlc) || wlc->monitor)
+-			return false;
+-	}
+-
+-	FOREACH_AS_STA(wlc, idx, cfg) {
+-		/* disallow PS when one of the following bsscfg specific conditions meets */
+-		if (!cfg->BSS || !WLC_PORTOPEN(cfg))
+-			return false;
+-
+-		if (!cfg->dtim_programmed)
+-			return false;
+-	}
+-
+-	return true;
+-}
+-
+-void wlc_reset(struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	wlc->check_for_unaligned_tbtt = false;
+-
+-	/* slurp up hw mac counters before core reset */
+-	wlc_statsupd(wlc);
+-
+-	/* reset our snapshot of macstat counters */
+-	memset((char *)wlc->core->macstat_snapshot, 0,
+-		sizeof(macstat_t));
+-
+-	wlc_bmac_reset(wlc->hw);
+-	wlc->txretried = 0;
+-
+-}
+-
+-void wlc_fatal_error(struct wlc_info *wlc)
+-{
+-	wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
+-		  wlc->pub->unit);
+-	wl_init(wlc->wl);
+-}
+-
+-/* Return the channel the driver should initialize during wlc_init.
+- * the channel may have to be changed from the currently configured channel
+- * if other configurations are in conflict (bandlocked, 11n mode disabled,
+- * invalid channel for current country, etc.)
+- */
+-static chanspec_t wlc_init_chanspec(struct wlc_info *wlc)
+-{
+-	chanspec_t chanspec =
+-	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
+-	    WL_CHANSPEC_BAND_2G;
+-
+-	return chanspec;
+-}
+-
+-struct scb global_scb;
+-
+-static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb)
+-{
+-	int i;
+-	scb->flags = SCB_WMECAP | SCB_HTCAP;
+-	for (i = 0; i < NUMPRIO; i++)
+-		scb->seqnum[i] = 0;
+-}
+-
+-void wlc_init(struct wlc_info *wlc)
+-{
+-	d11regs_t *regs;
+-	chanspec_t chanspec;
+-	int i;
+-	struct wlc_bsscfg *bsscfg;
+-	bool mute = false;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	regs = wlc->regs;
+-
+-	/* This will happen if a big-hammer was executed. In that case, we want to go back
+-	 * to the channel that we were on and not new channel
+-	 */
+-	if (wlc->pub->associated)
+-		chanspec = wlc->home_chanspec;
+-	else
+-		chanspec = wlc_init_chanspec(wlc);
+-
+-	wlc_bmac_init(wlc->hw, chanspec, mute);
+-
+-	wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2;
+-	if (wlc->machwcap & MCAP_TKIPMIC)
+-		wlc->tkmickeys =
+-		    wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2;
+-
+-	/* update beacon listen interval */
+-	wlc_bcn_li_upd(wlc);
+-	wlc->bcn_wait_prd =
+-	    (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10);
+-
+-	/* the world is new again, so is our reported rate */
+-	wlc_reprate_init(wlc);
+-
+-	/* write ethernet address to core */
+-	FOREACH_BSS(wlc, i, bsscfg) {
+-		wlc_set_mac(bsscfg);
+-		wlc_set_bssid(bsscfg);
+-	}
+-
+-	/* Update tsf_cfprep if associated and up */
+-	if (wlc->pub->associated) {
+-		FOREACH_BSS(wlc, i, bsscfg) {
+-			if (bsscfg->up) {
+-				u32 bi;
+-
+-				/* get beacon period and convert to uS */
+-				bi = bsscfg->current_bss->beacon_period << 10;
+-				/*
+-				 * update since init path would reset
+-				 * to default value
+-				 */
+-				W_REG(&regs->tsf_cfprep,
+-				      (bi << CFPREP_CBI_SHIFT));
+-
+-				/* Update maccontrol PM related bits */
+-				wlc_set_ps_ctrl(wlc);
+-
+-				break;
+-			}
+-		}
+-	}
+-
+-	wlc_key_hw_init_all(wlc);
+-
+-	wlc_bandinit_ordered(wlc, chanspec);
+-
+-	wlc_init_scb(wlc, &global_scb);
+-
+-	/* init probe response timeout */
+-	wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout);
+-
+-	/* init max burst txop (framebursting) */
+-	wlc_write_shm(wlc, M_MBURST_TXOP,
+-		      (wlc->
+-		       _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP));
+-
+-	/* initialize maximum allowed duty cycle */
+-	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true);
+-	wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true);
+-
+-	/* Update some shared memory locations related to max AMPDU size allowed to received */
+-	wlc_ampdu_shm_upd(wlc->ampdu);
+-
+-	/* band-specific inits */
+-	wlc_bsinit(wlc);
+-
+-	/* Enable EDCF mode (while the MAC is suspended) */
+-	if (EDCF_ENAB(wlc->pub)) {
+-		OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
+-		wlc_edcf_setparams(wlc, false);
+-	}
+-
+-	/* Init precedence maps for empty FIFOs */
+-	wlc_tx_prec_map_init(wlc);
+-
+-	/* read the ucode version if we have not yet done so */
+-	if (wlc->ucode_rev == 0) {
+-		wlc->ucode_rev =
+-		    wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16);
+-		wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR);
+-	}
+-
+-	/* ..now really unleash hell (allow the MAC out of suspend) */
+-	wlc_enable_mac(wlc);
+-
+-	/* clear tx flow control */
+-	wlc_txflowcontrol_reset(wlc);
+-
+-	/* clear tx data fifo suspends */
+-	wlc->tx_suspended = false;
+-
+-	/* enable the RF Disable Delay timer */
+-	W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
+-
+-	/* initialize mpc delay */
+-	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-
+-	/*
+-	 * Initialize WME parameters; if they haven't been set by some other
+-	 * mechanism (IOVar, etc) then read them from the hardware.
+-	 */
+-	if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) {	/* Uninitialized; read from HW */
+-		int ac;
+-
+-		for (ac = 0; ac < AC_COUNT; ac++) {
+-			wlc->wme_retries[ac] =
+-			    wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
+-		}
+-	}
+-}
+-
+-void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc)
+-{
+-	wlc->bcnmisc_monitor = promisc;
+-	wlc_mac_bcn_promisc(wlc);
+-}
+-
+-void wlc_mac_bcn_promisc(struct wlc_info *wlc)
+-{
+-	if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) ||
+-	    wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor)
+-		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);
+-	else
+-		wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0);
+-}
+-
+-/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */
+-void wlc_mac_promisc(struct wlc_info *wlc)
+-{
+-	u32 promisc_bits = 0;
+-
+-	/* promiscuous mode just sets MCTL_PROMISC
+-	 * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit
+-	 * since all BSS data traffic is directed at the AP
+-	 */
+-	if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet)
+-		promisc_bits |= MCTL_PROMISC;
+-
+-	/* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL
+-	 * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is
+-	 * handled in wlc_mac_bcn_promisc()
+-	 */
+-	if (MONITOR_ENAB(wlc))
+-		promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;
+-
+-	wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
+-}
+-
+-/* push sw hps and wake state through hardware */
+-void wlc_set_ps_ctrl(struct wlc_info *wlc)
+-{
+-	u32 v1, v2;
+-	bool hps;
+-	bool awake_before;
+-
+-	hps = PS_ALLOWED(wlc);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
+-
+-	v1 = R_REG(&wlc->regs->maccontrol);
+-	v2 = MCTL_WAKE;
+-	if (hps)
+-		v2 |= MCTL_HPS;
+-
+-	wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
+-
+-	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
+-
+-	if (!awake_before)
+-		wlc_bmac_wait_for_wake(wlc->hw);
+-
+-}
+-
+-/*
+- * Write this BSS config's MAC address to core.
+- * Updates RXE match engine.
+- */
+-int wlc_set_mac(struct wlc_bsscfg *cfg)
+-{
+-	int err = 0;
+-	struct wlc_info *wlc = cfg->wlc;
+-
+-	if (cfg == wlc->cfg) {
+-		/* enter the MAC addr into the RXE match registers */
+-		wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr);
+-	}
+-
+-	wlc_ampdu_macaddr_upd(wlc);
+-
+-	return err;
+-}
+-
+-/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl).
+- * Updates RXE match engine.
+- */
+-void wlc_set_bssid(struct wlc_bsscfg *cfg)
+-{
+-	struct wlc_info *wlc = cfg->wlc;
+-
+-	/* if primary config, we need to update BSSID in RXE match registers */
+-	if (cfg == wlc->cfg) {
+-		wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID);
+-	}
+-#ifdef SUPPORT_HWKEYS
+-	else if (BSSCFG_STA(cfg) && cfg->BSS) {
+-		wlc_rcmta_add_bssid(wlc, cfg);
+-	}
+-#endif
+-}
+-
+-/*
+- * Suspend the the MAC and update the slot timing
+- * for standard 11b/g (20us slots) or shortslot 11g (9us slots).
+- */
+-void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	/* use the override if it is set */
+-	if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO)
+-		shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON);
+-
+-	if (wlc->shortslot == shortslot)
+-		return;
+-
+-	wlc->shortslot = shortslot;
+-
+-	/* update the capability based on current shortslot mode */
+-	FOREACH_BSS(wlc, idx, cfg) {
+-		if (!cfg->associated)
+-			continue;
+-		cfg->current_bss->capability &=
+-					~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-		if (wlc->shortslot)
+-			cfg->current_bss->capability |=
+-					WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-	}
+-
+-	wlc_bmac_set_shortslot(wlc->hw, shortslot);
+-}
+-
+-static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc)
+-{
+-	u8 local;
+-	s16 local_max;
+-
+-	local = WLC_TXPWR_MAX;
+-	if (wlc->pub->associated &&
+-	    (bcm_chspec_ctlchan(wlc->chanspec) ==
+-	     bcm_chspec_ctlchan(wlc->home_chanspec))) {
+-
+-		/* get the local power constraint if we are on the AP's
+-		 * channel [802.11h, 7.3.2.13]
+-		 */
+-		/* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */
+-		local_max =
+-		    (wlc->txpwr_local_max -
+-		     wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR;
+-		if (local_max > 0 && local_max < WLC_TXPWR_MAX)
+-			return (u8) local_max;
+-		if (local_max < 0)
+-			return 0;
+-	}
+-
+-	return local;
+-}
+-
+-/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */
+-void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	if (wlc->home_chanspec != chanspec) {
+-		int idx;
+-		struct wlc_bsscfg *cfg;
+-
+-		wlc->home_chanspec = chanspec;
+-
+-		FOREACH_BSS(wlc, idx, cfg) {
+-			if (!cfg->associated)
+-				continue;
+-
+-			cfg->current_bss->chanspec = chanspec;
+-		}
+-
+-	}
+-}
+-
+-static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	/* Save our copy of the chanspec */
+-	wlc->chanspec = chanspec;
+-
+-	/* Set the chanspec and power limits for this locale after computing
+-	 * any 11h local tx power constraints.
+-	 */
+-	wlc_channel_set_chanspec(wlc->cmi, chanspec,
+-				 wlc_local_constraint_qdbm(wlc));
+-
+-	if (wlc->stf->ss_algosel_auto)
+-		wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel,
+-					    chanspec);
+-
+-	wlc_stf_ss_update(wlc, wlc->band);
+-
+-}
+-
+-void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	uint bandunit;
+-	bool switchband = false;
+-	chanspec_t old_chanspec = wlc->chanspec;
+-
+-	if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
+-			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
+-		return;
+-	}
+-
+-	/* Switch bands if necessary */
+-	if (NBANDS(wlc) > 1) {
+-		bandunit = CHSPEC_WLCBANDUNIT(chanspec);
+-		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
+-			switchband = true;
+-			if (wlc->bandlocked) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
+-					  "band is locked!\n",
+-					  wlc->pub->unit, __func__,
+-					  CHSPEC_CHANNEL(chanspec));
+-				return;
+-			}
+-			/* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ?
+-			 * if the setband updates (wlc_bsinit) use low level calls to inspect and
+-			 * set state, the state inspected may be from the wrong band, or the
+-			 * following wlc_bmac_set_chanspec() may undo the work.
+-			 */
+-			wlc_setband(wlc, bandunit);
+-		}
+-	}
+-
+-	/* sync up phy/radio chanspec */
+-	wlc_set_phy_chanspec(wlc, chanspec);
+-
+-	/* init antenna selection */
+-	if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) {
+-		wlc_antsel_init(wlc->asi);
+-
+-		/* Fix the hardware rateset based on bw.
+-		 * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz
+-		 */
+-		wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset,
+-					  wlc->band->
+-					  mimo_cap_40 ? CHSPEC_WLC_BW(chanspec)
+-					  : 0);
+-	}
+-
+-	/* update some mac configuration since chanspec changed */
+-	wlc_ucode_mac_upd(wlc);
+-}
+-
+-#if defined(BCMDBG)
+-static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len)
+-{
+-	txpwr_limits_t txpwr;
+-	tx_power_t power;
+-	tx_power_legacy_t *old_power = NULL;
+-	int r, c;
+-	uint qdbm;
+-	bool override;
+-
+-	if (len == sizeof(tx_power_legacy_t))
+-		old_power = (tx_power_legacy_t *) pwr;
+-	else if (len < sizeof(tx_power_t))
+-		return -EOVERFLOW;
+-
+-	memset(&power, 0, sizeof(tx_power_t));
+-
+-	power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC;
+-	if (wlc->pub->associated)
+-		power.local_chanspec = wlc->home_chanspec;
+-
+-	/* Return the user target tx power limits for the various rates.  Note  wlc_phy.c's
+-	 * public interface only implements getting and setting a single value for all of
+-	 * rates, so we need to fill the array ourselves.
+-	 */
+-	wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override);
+-	for (r = 0; r < WL_TX_POWER_RATES; r++) {
+-		power.user_limit[r] = (u8) qdbm;
+-	}
+-
+-	power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR;
+-	power.local_constraint =
+-	    wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR;
+-
+-	power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain;
+-	power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain;
+-
+-	wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr);
+-
+-#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK
+-#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK"
+-#endif
+-
+-	/* CCK tx power limits */
+-	for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM;
+-	     c++, r++)
+-		power.reg_limit[r] = txpwr.cck[c];
+-
+-#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM
+-#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM"
+-#endif
+-
+-	/* 20 MHz OFDM SISO tx power limits */
+-	for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM;
+-	     c++, r++)
+-		power.reg_limit[r] = txpwr.ofdm[c];
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-
+-		/* 20 MHz OFDM CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_cdd[c];
+-
+-		/* 40 MHz OFDM SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_40_siso[c];
+-
+-		/* 40 MHz OFDM CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST;
+-		     c < WL_TX_POWER_OFDM_NUM; c++, r++)
+-			power.reg_limit[r] = txpwr.ofdm_40_cdd[c];
+-
+-#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM
+-#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM"
+-#endif
+-
+-		/* 20MHz MCS0-7 SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_siso[c];
+-
+-		/* 20MHz MCS0-7 CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_cdd[c];
+-
+-		/* 20MHz MCS0-7 STBC tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_stbc[c];
+-
+-		/* 40MHz MCS0-7 SISO tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_siso[c];
+-
+-		/* 40MHz MCS0-7 CDD tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_cdd[c];
+-
+-		/* 40MHz MCS0-7 STBC tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST;
+-		     c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_stbc[c];
+-
+-#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM
+-#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM"
+-#endif
+-
+-		/* 20MHz MCS8-15 SDM tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST;
+-		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_20_mimo[c];
+-
+-		/* 40MHz MCS8-15 SDM tx power limits */
+-		for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST;
+-		     c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++)
+-			power.reg_limit[r] = txpwr.mcs_40_mimo[c];
+-
+-		/* MCS 32 */
+-		power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32;
+-	}
+-
+-	wlc_phy_txpower_get_current(wlc->band->pi, &power,
+-				    CHSPEC_CHANNEL(power.chanspec));
+-
+-	/* copy the tx_power_t struct to the return buffer,
+-	 * or convert to a tx_power_legacy_t struct
+-	 */
+-	if (!old_power) {
+-		memcpy(pwr, &power, sizeof(tx_power_t));
+-	} else {
+-		int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1;
+-
+-		memset(old_power, 0, sizeof(tx_power_legacy_t));
+-
+-		old_power->txpwr_local_max = power.local_max;
+-		old_power->txpwr_local_constraint = power.local_constraint;
+-		if (CHSPEC_IS2G(power.chanspec)) {
+-			old_power->txpwr_chan_reg_max = txpwr.cck[0];
+-			old_power->txpwr_est_Pout[band_idx] =
+-			    power.est_Pout_cck;
+-			old_power->txpwr_est_Pout_gofdm = power.est_Pout[0];
+-		} else {
+-			old_power->txpwr_chan_reg_max = txpwr.ofdm[0];
+-			old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0];
+-		}
+-		old_power->txpwr_antgain[0] = power.antgain[0];
+-		old_power->txpwr_antgain[1] = power.antgain[1];
+-
+-		for (r = 0; r < NUM_PWRCTRL_RATES; r++) {
+-			old_power->txpwr_band_max[r] = power.user_limit[r];
+-			old_power->txpwr_limit[r] = power.reg_limit[r];
+-			old_power->txpwr_target[band_idx][r] = power.target[r];
+-			if (CHSPEC_IS2G(power.chanspec))
+-				old_power->txpwr_bphy_cck_max[r] =
+-				    power.board_limit[r];
+-			else
+-				old_power->txpwr_aphy_max[r] =
+-				    power.board_limit[r];
+-		}
+-	}
+-
+-	return 0;
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc)
+-{
+-	u32 bi;
+-	bi = 2 * wlc->cfg->current_bss->dtim_period *
+-	    wlc->cfg->current_bss->beacon_period;
+-	if (wlc->bcn_li_dtim)
+-		bi *= wlc->bcn_li_dtim;
+-	else if (wlc->bcn_li_bcn)
+-		/* recalculate bi based on bcn_li_bcn */
+-		bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period;
+-
+-	if (bi < 2 * TIMER_INTERVAL_WATCHDOG)
+-		bi = 2 * TIMER_INTERVAL_WATCHDOG;
+-	return bi;
+-}
+-
+-/* Change to run the watchdog either from a periodic timer or from tbtt handler.
+- * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise.
+- */
+-void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt)
+-{
+-	/* make sure changing watchdog driver is allowed */
+-	if (!wlc->pub->up || !wlc->pub->align_wd_tbtt)
+-		return;
+-	if (!tbtt && wlc->WDarmed) {
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wlc->WDarmed = false;
+-	}
+-
+-	/* stop watchdog timer and use tbtt interrupt to drive watchdog */
+-	if (tbtt && wlc->WDarmed) {
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wlc->WDarmed = false;
+-		wlc->WDlast = OSL_SYSUPTIME();
+-	}
+-	/* arm watchdog timer and drive the watchdog there */
+-	else if (!tbtt && !wlc->WDarmed) {
+-		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+-			     true);
+-		wlc->WDarmed = true;
+-	}
+-	if (tbtt && !wlc->WDarmed) {
+-		wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc),
+-			     true);
+-		wlc->WDarmed = true;
+-	}
+-}
+-
+-ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs)
+-{
+-	ratespec_t lowest_basic_rspec;
+-	uint i;
+-
+-	/* Use the lowest basic rate */
+-	lowest_basic_rspec = rs->rates[0] & WLC_RATE_MASK;
+-	for (i = 0; i < rs->count; i++) {
+-		if (rs->rates[i] & WLC_RATE_FLAG) {
+-			lowest_basic_rspec = rs->rates[i] & WLC_RATE_MASK;
+-			break;
+-		}
+-	}
+-#if NCONF
+-	/* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */
+-	if (IS_OFDM(lowest_basic_rspec)) {
+-		lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+-	}
+-#endif
+-
+-	return lowest_basic_rspec;
+-}
+-
+-/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant
+- * setting as per this table:
+- *  ratespec     CCK		ant = wlc->stf->txant
+- *  		OFDM		ant = 3
+- */
+-void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec)
+-{
+-	u16 phyctl;
+-	u16 phytxant = wlc->stf->phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* for non-siso rates or default setting, use the available chains */
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec);
+-	}
+-
+-	phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD);
+-	phyctl = (phyctl & ~mask) | phytxant;
+-	wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl);
+-}
+-
+-/* centralized protection config change function to simplify debugging, no consistency checking
+- * this should be called only on changes to avoid overhead in periodic function
+-*/
+-void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val)
+-{
+-	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
+-
+-	switch (idx) {
+-	case WLC_PROT_G_SPEC:
+-		wlc->protection->_g = (bool) val;
+-		break;
+-	case WLC_PROT_G_OVR:
+-		wlc->protection->g_override = (s8) val;
+-		break;
+-	case WLC_PROT_G_USER:
+-		wlc->protection->gmode_user = (u8) val;
+-		break;
+-	case WLC_PROT_OVERLAP:
+-		wlc->protection->overlap = (s8) val;
+-		break;
+-	case WLC_PROT_N_USER:
+-		wlc->protection->nmode_user = (s8) val;
+-		break;
+-	case WLC_PROT_N_CFG:
+-		wlc->protection->n_cfg = (s8) val;
+-		break;
+-	case WLC_PROT_N_CFG_OVR:
+-		wlc->protection->n_cfg_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_NONGF:
+-		wlc->protection->nongf = (bool) val;
+-		break;
+-	case WLC_PROT_N_NONGF_OVR:
+-		wlc->protection->nongf_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_PAM_OVR:
+-		wlc->protection->n_pam_override = (s8) val;
+-		break;
+-	case WLC_PROT_N_OBSS:
+-		wlc->protection->n_obss = (bool) val;
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-}
+-
+-static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val)
+-{
+-	wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 |
+-					IEEE80211_HT_CAP_SGI_40);
+-	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ?
+-					IEEE80211_HT_CAP_SGI_20 : 0;
+-	wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ?
+-					IEEE80211_HT_CAP_SGI_40 : 0;
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-	}
+-}
+-
+-static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val)
+-{
+-	wlc->stf->ldpc = val;
+-
+-	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING;
+-	if (wlc->stf->ldpc != OFF)
+-		wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-		wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false));
+-	}
+-}
+-
+-/*
+- * ucode, hwmac update
+- *    Channel dependent updates for ucode and hw
+- */
+-static void wlc_ucode_mac_upd(struct wlc_info *wlc)
+-{
+-	/* enable or disable any active IBSSs depending on whether or not
+-	 * we are on the home channel
+-	 */
+-	if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) {
+-		if (wlc->pub->associated) {
+-			/* BMAC_NOTE: This is something that should be fixed in ucode inits.
+-			 * I think that the ucode inits set up the bcn templates and shm values
+-			 * with a bogus beacon. This should not be done in the inits. If ucode needs
+-			 * to set up a beacon for testing, the test routines should write it down,
+-			 * not expect the inits to populate a bogus beacon.
+-			 */
+-			if (WLC_PHY_11N_CAP(wlc->band)) {
+-				wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET,
+-					      wlc->band->bcntsfoff);
+-			}
+-		}
+-	} else {
+-		/* disable an active IBSS if we are not on the home channel */
+-	}
+-
+-	/* update the various promisc bits */
+-	wlc_mac_bcn_promisc(wlc);
+-	wlc_mac_promisc(wlc);
+-}
+-
+-static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec)
+-{
+-	wlc_rateset_t default_rateset;
+-	uint parkband;
+-	uint i, band_order[2];
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-	/*
+-	 * We might have been bandlocked during down and the chip power-cycled (hibernate).
+-	 * figure out the right band to park on
+-	 */
+-	if (wlc->bandlocked || NBANDS(wlc) == 1) {
+-		parkband = wlc->band->bandunit;	/* updated in wlc_bandlock() */
+-		band_order[0] = band_order[1] = parkband;
+-	} else {
+-		/* park on the band of the specified chanspec */
+-		parkband = CHSPEC_WLCBANDUNIT(chanspec);
+-
+-		/* order so that parkband initialize last */
+-		band_order[0] = parkband ^ 1;
+-		band_order[1] = parkband;
+-	}
+-
+-	/* make each band operational, software state init */
+-	for (i = 0; i < NBANDS(wlc); i++) {
+-		uint j = band_order[i];
+-
+-		wlc->band = wlc->bandstate[j];
+-
+-		wlc_default_rateset(wlc, &default_rateset);
+-
+-		/* fill in hw_rate */
+-		wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
+-				   false, WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-				   (bool) N_ENAB(wlc->pub));
+-
+-		/* init basic rate lookup */
+-		wlc_rate_lookup_init(wlc, &default_rateset);
+-	}
+-
+-	/* sync up phy/radio chanspec */
+-	wlc_set_phy_chanspec(wlc, chanspec);
+-}
+-
+-/* band-specific init */
+-static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
+-		 wlc->pub->unit, wlc->band->bandunit);
+-
+-	/* write ucode ACK/CTS rate table */
+-	wlc_set_ratetable(wlc);
+-
+-	/* update some band specific mac configuration */
+-	wlc_ucode_mac_upd(wlc);
+-
+-	/* init antenna selection */
+-	wlc_antsel_init(wlc->asi);
+-
+-}
+-
+-/* switch to and initialize new band */
+-static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit)
+-{
+-	int idx;
+-	struct wlc_bsscfg *cfg;
+-
+-	wlc->band = wlc->bandstate[bandunit];
+-
+-	if (!wlc->pub->up)
+-		return;
+-
+-	/* wait for at least one beacon before entering sleeping state */
+-	wlc->PMawakebcn = true;
+-	FOREACH_AS_STA(wlc, idx, cfg)
+-	    cfg->PMawakebcn = true;
+-	wlc_set_ps_ctrl(wlc);
+-
+-	/* band-specific initializations */
+-	wlc_bsinit(wlc);
+-}
+-
+-/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */
+-void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe)
+-{
+-	static const wme_param_ie_t stadef = {
+-		WME_OUI,
+-		WME_TYPE,
+-		WME_SUBTYPE_PARAM_IE,
+-		WME_VER,
+-		0,
+-		0,
+-		{
+-		 {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_BE_TXOP_STA)},
+-		 {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_BK_TXOP_STA)},
+-		 {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_VI_TXOP_STA)},
+-		 {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA,
+-		  cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
+-		 }
+-	};
+-	memcpy(pe, &stadef, sizeof(*pe));
+-}
+-
+-void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+-		       const struct ieee80211_tx_queue_params *params,
+-		       bool suspend)
+-{
+-	int i;
+-	shm_acparams_t acp_shm;
+-	u16 *shm_entry;
+-
+-	/* Only apply params if the core is out of reset and has clocks */
+-	if (!wlc->clk) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
+-			  __func__);
+-		return;
+-	}
+-
+-	wlc->wme_admctl = 0;
+-
+-	do {
+-		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
+-		/* fill in shm ac params struct */
+-		acp_shm.txop = le16_to_cpu(params->txop);
+-		/* convert from units of 32us to us for ucode */
+-		wlc->edcf_txop[aci & 0x3] = acp_shm.txop =
+-		    EDCF_TXOP2USEC(acp_shm.txop);
+-		acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);
+-
+-		if (aci == AC_VI && acp_shm.txop == 0
+-		    && acp_shm.aifs < EDCF_AIFSN_MAX)
+-			acp_shm.aifs++;
+-
+-		if (acp_shm.aifs < EDCF_AIFSN_MIN
+-		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_edcf_setparams: bad "
+-				  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
+-			continue;
+-		}
+-
+-		acp_shm.cwmin = params->cw_min;
+-		acp_shm.cwmax = params->cw_max;
+-		acp_shm.cwcur = acp_shm.cwmin;
+-		acp_shm.bslots =
+-		    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
+-		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
+-		/* Indicate the new params to the ucode */
+-		acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
+-						    wme_shmemacindex(aci) *
+-						    M_EDCF_QLEN +
+-						    M_EDCF_STATUS_OFF));
+-		acp_shm.status |= WME_STATUS_NEWAC;
+-
+-		/* Fill in shm acparam table */
+-		shm_entry = (u16 *) &acp_shm;
+-		for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2)
+-			wlc_write_shm(wlc,
+-				      M_EDCF_QINFO +
+-				      wme_shmemacindex(aci) * M_EDCF_QLEN + i,
+-				      *shm_entry++);
+-
+-	} while (0);
+-
+-	if (suspend)
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-	if (suspend)
+-		wlc_enable_mac(wlc);
+-
+-}
+-
+-void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend)
+-{
+-	u16 aci;
+-	int i_ac;
+-	edcf_acparam_t *edcf_acp;
+-
+-	struct ieee80211_tx_queue_params txq_pars;
+-	struct ieee80211_tx_queue_params *params = &txq_pars;
+-
+-	/*
+-	 * AP uses AC params from wme_param_ie_ap.
+-	 * AP advertises AC params from wme_param_ie.
+-	 * STA uses AC params from wme_param_ie.
+-	 */
+-
+-	edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0];
+-
+-	for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
+-		/* find out which ac this set of params applies to */
+-		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
+-		/* set the admission control policy for this AC */
+-		if (edcf_acp->ACI & EDCF_ACM_MASK) {
+-			wlc->wme_admctl |= 1 << aci;
+-		}
+-
+-		/* fill in shm ac params struct */
+-		params->txop = edcf_acp->TXOP;
+-		params->aifs = edcf_acp->ACI;
+-
+-		/* CWmin = 2^(ECWmin) - 1 */
+-		params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
+-		/* CWmax = 2^(ECWmax) - 1 */
+-		params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
+-					    >> EDCF_ECWMAX_SHIFT);
+-		wlc_wme_setparams(wlc, aci, params, suspend);
+-	}
+-
+-	if (suspend)
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-	if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, false);
+-	}
+-
+-	if (suspend)
+-		wlc_enable_mac(wlc);
+-
+-}
+-
+-bool wlc_timers_init(struct wlc_info *wlc, int unit)
+-{
+-	wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer,
+-		wlc, "watchdog");
+-	if (!wlc->wdtimer) {
+-		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
+-			  "failed\n", unit);
+-		goto fail;
+-	}
+-
+-	wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer,
+-		wlc, "radio");
+-	if (!wlc->radio_timer) {
+-		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
+-			  "failed\n", unit);
+-		goto fail;
+-	}
+-
+-	return true;
+-
+- fail:
+-	return false;
+-}
+-
+-/*
+- * Initialize wlc_info default values ...
+- * may get overrides later in this function
+- */
+-void wlc_info_init(struct wlc_info *wlc, int unit)
+-{
+-	int i;
+-	/* Assume the device is there until proven otherwise */
+-	wlc->device_present = true;
+-
+-	/* set default power output percentage to 100 percent */
+-	wlc->txpwr_percent = 100;
+-
+-	/* Save our copy of the chanspec */
+-	wlc->chanspec = CH20MHZ_CHSPEC(1);
+-
+-	/* initialize CCK preamble mode to unassociated state */
+-	wlc->shortpreamble = false;
+-
+-	wlc->legacy_probe = true;
+-
+-	/* various 802.11g modes */
+-	wlc->shortslot = false;
+-	wlc->shortslot_override = WLC_SHORTSLOT_AUTO;
+-
+-	wlc->barker_overlap_control = true;
+-	wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED;
+-	wlc->txburst_limit_override = AUTO;
+-
+-	wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false);
+-
+-	wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF);
+-	wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO);
+-	wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false);
+-	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO);
+-
+-	wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP);
+-
+-	/* 802.11g draft 4.0 NonERP elt advertisement */
+-	wlc->include_legacy_erp = true;
+-
+-	wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF;
+-	wlc->stf->txant = ANT_TX_DEF;
+-
+-	wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT;
+-
+-	wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN;
+-	for (i = 0; i < NFIFO; i++)
+-		wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN;
+-	wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN;
+-
+-	/* default rate fallback retry limits */
+-	wlc->SFBL = RETRY_SHORT_FB;
+-	wlc->LFBL = RETRY_LONG_FB;
+-
+-	/* default mac retry limits */
+-	wlc->SRL = RETRY_SHORT_DEF;
+-	wlc->LRL = RETRY_LONG_DEF;
+-
+-	/* init PM state */
+-	wlc->PM = PM_OFF;	/* User's setting of PM mode through IOCTL */
+-	wlc->PM_override = false;	/* Prevents from going to PM if our AP is 'ill' */
+-	wlc->PMenabled = false;	/* Current PM state */
+-	wlc->PMpending = false;	/* Tracks whether STA indicated PM in the last attempt */
+-	wlc->PMblocked = false;	/* To allow blocking going into PM during RM and scans */
+-
+-	/* In WMM Auto mode, PM is allowed if association is a UAPSD association */
+-	wlc->WME_PM_blocked = false;
+-
+-	/* Init wme queuing method */
+-	wlc->wme_prec_queuing = false;
+-
+-	/* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */
+-	wlc->wake = false;
+-	/* Are we waiting for a response to PS-Poll that we sent */
+-	wlc->PSpoll = false;
+-
+-	/* APSD defaults */
+-	wlc->wme_apsd = true;
+-	wlc->apsd_sta_usp = false;
+-	wlc->apsd_trigger_timeout = 0;	/* disable the trigger timer */
+-	wlc->apsd_trigger_ac = AC_BITMAP_ALL;
+-
+-	/* Set flag to indicate that hw keys should be used when available. */
+-	wlc->wsec_swkeys = false;
+-
+-	/* init the 4 static WEP default keys */
+-	for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+-		wlc->wsec_keys[i] = wlc->wsec_def_keys[i];
+-		wlc->wsec_keys[i]->idx = (u8) i;
+-	}
+-
+-	wlc->_regulatory_domain = false;	/* 802.11d */
+-
+-	/* WME QoS mode is Auto by default */
+-	wlc->pub->_wme = AUTO;
+-
+-#ifdef BCMSDIODEV_ENABLED
+-	wlc->pub->_priofc = true;	/* enable priority flow control for sdio dongle */
+-#endif
+-
+-	wlc->pub->_ampdu = AMPDU_AGG_HOST;
+-	wlc->pub->bcmerror = 0;
+-	wlc->ibss_allowed = true;
+-	wlc->ibss_coalesce_allowed = true;
+-	wlc->pub->_coex = ON;
+-
+-	/* initialize mpc delay */
+-	wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-
+-	wlc->pr80838_war = true;
+-}
+-
+-static bool wlc_state_bmac_sync(struct wlc_info *wlc)
+-{
+-	wlc_bmac_state_t state_bmac;
+-
+-	if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0)
+-		return false;
+-
+-	wlc->machwcap = state_bmac.machwcap;
+-	wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR,
+-			   (s8) state_bmac.preamble_ovr);
+-
+-	return true;
+-}
+-
+-static uint wlc_attach_module(struct wlc_info *wlc)
+-{
+-	uint err = 0;
+-	uint unit;
+-	unit = wlc->pub->unit;
+-
+-	wlc->asi = wlc_antsel_attach(wlc);
+-	if (wlc->asi == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_antsel_attach "
+-			  "failed\n", unit);
+-		err = 44;
+-		goto fail;
+-	}
+-
+-	wlc->ampdu = wlc_ampdu_attach(wlc);
+-	if (wlc->ampdu == NULL) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_ampdu_attach "
+-			  "failed\n", unit);
+-		err = 50;
+-		goto fail;
+-	}
+-
+-	if ((wlc_stf_attach(wlc) != 0)) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_stf_attach "
+-			  "failed\n", unit);
+-		err = 68;
+-		goto fail;
+-	}
+- fail:
+-	return err;
+-}
+-
+-struct wlc_pub *wlc_pub(void *wlc)
+-{
+-	return ((struct wlc_info *) wlc)->pub;
+-}
+-
+-#define CHIP_SUPPORTS_11N(wlc) 	1
+-
+-/*
+- * The common driver entry routine. Error codes should be unique
+- */
+-void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
+-		 bool piomode, void *regsva, uint bustype, void *btparam,
+-		 uint *perr)
+-{
+-	struct wlc_info *wlc;
+-	uint err = 0;
+-	uint j;
+-	struct wlc_pub *pub;
+-	uint n_disabled;
+-
+-	/* allocate struct wlc_info state and its substructures */
+-	wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device);
+-	if (wlc == NULL)
+-		goto fail;
+-	wlc->wiphy = wl->wiphy;
+-	pub = wlc->pub;
+-
+-#if defined(BCMDBG)
+-	wlc_info_dbg = wlc;
+-#endif
+-
+-	wlc->band = wlc->bandstate[0];
+-	wlc->core = wlc->corestate;
+-	wlc->wl = wl;
+-	pub->unit = unit;
+-	wlc->btparam = btparam;
+-	pub->_piomode = piomode;
+-	wlc->bandinit_pending = false;
+-	/* By default restrict TKIP associations from 11n STA's */
+-	wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT;
+-
+-	/* populate struct wlc_info with default values  */
+-	wlc_info_init(wlc, unit);
+-
+-	/* update sta/ap related parameters */
+-	wlc_ap_upd(wlc);
+-
+-	/* 11n_disable nvram */
+-	n_disabled = getintvar(pub->vars, "11n_disable");
+-
+-	/* register a module (to handle iovars) */
+-	wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc,
+-			    wlc_doiovar, NULL, NULL);
+-
+-	/*
+-	 * low level attach steps(all hw accesses go
+-	 * inside, no more in rest of the attach)
+-	 */
+-	err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, regsva,
+-			      bustype, btparam);
+-	if (err)
+-		goto fail;
+-
+-	/* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split,
+-	 * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver
+-	 */
+-	if (!wlc_state_bmac_sync(wlc)) {
+-		err = 20;
+-		goto fail;
+-	}
+-
+-	pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band);
+-
+-	/* propagate *vars* from BMAC driver to high driver */
+-	wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size);
+-
+-
+-	/* set maximum allowed duty cycle */
+-	wlc->tx_duty_cycle_ofdm =
+-	    (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm");
+-	wlc->tx_duty_cycle_cck =
+-	    (u16) getintvar(pub->vars, "tx_duty_cycle_cck");
+-
+-	wlc_stf_phy_chain_calc(wlc);
+-
+-	/* txchain 1: txant 0, txchain 2: txant 1 */
+-	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+-		wlc->stf->txant = wlc->stf->hw_txchain - 1;
+-
+-	/* push to BMAC driver */
+-	wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain,
+-			       wlc->stf->hw_rxchain);
+-
+-	/* pull up some info resulting from the low attach */
+-	{
+-		int i;
+-		for (i = 0; i < NFIFO; i++)
+-			wlc->core->txavail[i] = wlc->hw->txavail[i];
+-	}
+-
+-	wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr);
+-
+-	memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN);
+-
+-	for (j = 0; j < NBANDS(wlc); j++) {
+-		/* Use band 1 for single band 11a */
+-		if (IS_SINGLEBAND_5G(wlc->deviceid))
+-			j = BAND_5G_INDEX;
+-
+-		wlc->band = wlc->bandstate[j];
+-
+-		if (!wlc_attach_stf_ant_init(wlc)) {
+-			err = 24;
+-			goto fail;
+-		}
+-
+-		/* default contention windows size limits */
+-		wlc->band->CWmin = APHY_CWMIN;
+-		wlc->band->CWmax = PHY_CWMAX;
+-
+-		/* init gmode value */
+-		if (BAND_2G(wlc->band->bandtype)) {
+-			wlc->band->gmode = GMODE_AUTO;
+-			wlc_protection_upd(wlc, WLC_PROT_G_USER,
+-					   wlc->band->gmode);
+-		}
+-
+-		/* init _n_enab supported mode */
+-		if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) {
+-			if (n_disabled & WLFEATURE_DISABLE_11N) {
+-				pub->_n_enab = OFF;
+-				wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF);
+-			} else {
+-				pub->_n_enab = SUPPORT_11N;
+-				wlc_protection_upd(wlc, WLC_PROT_N_USER,
+-						   ((pub->_n_enab ==
+-						     SUPPORT_11N) ? WL_11N_2x2 :
+-						    WL_11N_3x3));
+-			}
+-		}
+-
+-		/* init per-band default rateset, depend on band->gmode */
+-		wlc_default_rateset(wlc, &wlc->band->defrateset);
+-
+-		/* fill in hw_rateset (used early by WLC_SET_RATESET) */
+-		wlc_rateset_filter(&wlc->band->defrateset,
+-				   &wlc->band->hw_rateset, false,
+-				   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-				   (bool) N_ENAB(wlc->pub));
+-	}
+-
+-	/* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */
+-	wlc_stf_phy_txant_upd(wlc);
+-
+-	/* attach each modules */
+-	err = wlc_attach_module(wlc);
+-	if (err != 0)
+-		goto fail;
+-
+-	if (!wlc_timers_init(wlc, unit)) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: wlc_init_timer failed\n", unit,
+-			  __func__);
+-		err = 32;
+-		goto fail;
+-	}
+-
+-	/* depend on rateset, gmode */
+-	wlc->cmi = wlc_channel_mgr_attach(wlc);
+-	if (!wlc->cmi) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: wlc_channel_mgr_attach failed"
+-			  "\n", unit, __func__);
+-		err = 33;
+-		goto fail;
+-	}
+-
+-	/* init default when all parameters are ready, i.e. ->rateset */
+-	wlc_bss_default_init(wlc);
+-
+-	/*
+-	 * Complete the wlc default state initializations..
+-	 */
+-
+-	/* allocate our initial queue */
+-	wlc->pkt_queue = wlc_txq_alloc(wlc);
+-	if (wlc->pkt_queue == NULL) {
+-		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
+-			  unit, __func__);
+-		err = 100;
+-		goto fail;
+-	}
+-
+-	wlc->bsscfg[0] = wlc->cfg;
+-	wlc->cfg->_idx = 0;
+-	wlc->cfg->wlc = wlc;
+-	pub->txmaxpkts = MAXTXPKTS;
+-
+-	wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie);
+-
+-	wlc->mimoft = FT_HT;
+-	wlc->ht_cap.cap_info = HT_CAP;
+-	if (HT_ENAB(wlc->pub))
+-		wlc->stf->ldpc = AUTO;
+-
+-	wlc->mimo_40txbw = AUTO;
+-	wlc->ofdm_40txbw = AUTO;
+-	wlc->cck_40txbw = AUTO;
+-	wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G);
+-
+-	/* Enable setting the RIFS Mode bit by default in HT Info IE */
+-	wlc->rifs_advert = AUTO;
+-
+-	/* Set default values of SGI */
+-	if (WLC_SGI_CAP_PHY(wlc)) {
+-		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+-		wlc->sgi_tx = AUTO;
+-	} else if (WLCISSSLPNPHY(wlc->band)) {
+-		wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40));
+-		wlc->sgi_tx = AUTO;
+-	} else {
+-		wlc_ht_update_sgi_rx(wlc, 0);
+-		wlc->sgi_tx = OFF;
+-	}
+-
+-	/* *******nvram 11n config overrides Start ********* */
+-
+-	/* apply the sgi override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX)
+-		wlc->sgi_tx = OFF;
+-
+-	if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX)
+-		wlc_ht_update_sgi_rx(wlc, 0);
+-
+-	/* apply the stbc override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) {
+-		wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+-		wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
+-	}
+-	if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX)
+-		wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO);
+-
+-	/* apply the GF override from nvram conf */
+-	if (n_disabled & WLFEATURE_DISABLE_11N_GF)
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD;
+-
+-	/* initialize radio_mpc_disable according to wlc->mpc */
+-	wlc_radio_mpc_upd(wlc);
+-
+-	if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) {
+-		if ((getintvar(wlc->pub->vars, "aa2g") == 7) ||
+-		    (getintvar(wlc->pub->vars, "aa5g") == 7)) {
+-			wlc_bmac_antsel_set(wlc->hw, 1);
+-		}
+-	} else {
+-		wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail);
+-	}
+-
+-	if (perr)
+-		*perr = 0;
+-
+-	return (void *)wlc;
+-
+- fail:
+-	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
+-		  unit, __func__, err);
+-	if (wlc)
+-		wlc_detach(wlc);
+-
+-	if (perr)
+-		*perr = err;
+-	return NULL;
+-}
+-
+-static void wlc_attach_antgain_init(struct wlc_info *wlc)
+-{
+-	uint unit;
+-	unit = wlc->pub->unit;
+-
+-	if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
+-		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
+-		wlc->band->antgain = 8;
+-	} else if (wlc->band->antgain == -1) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+-			  " srom, using 2dB\n", unit, __func__);
+-		wlc->band->antgain = 8;
+-	} else {
+-		s8 gain, fract;
+-		/* Older sroms specified gain in whole dbm only.  In order
+-		 * be able to specify qdbm granularity and remain backward compatible
+-		 * the whole dbms are now encoded in only low 6 bits and remaining qdbms
+-		 * are encoded in the hi 2 bits. 6 bit signed number ranges from
+-		 * -32 - 31. Examples: 0x1 = 1 db,
+-		 * 0xc1 = 1.75 db (1 + 3 quarters),
+-		 * 0x3f = -1 (-1 + 0 quarters),
+-		 * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm.
+-		 * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm.
+-		 */
+-		gain = wlc->band->antgain & 0x3f;
+-		gain <<= 2;	/* Sign extend */
+-		gain >>= 2;
+-		fract = (wlc->band->antgain & 0xc0) >> 6;
+-		wlc->band->antgain = 4 * gain + fract;
+-	}
+-}
+-
+-static bool wlc_attach_stf_ant_init(struct wlc_info *wlc)
+-{
+-	int aa;
+-	uint unit;
+-	char *vars;
+-	int bandtype;
+-
+-	unit = wlc->pub->unit;
+-	vars = wlc->pub->vars;
+-	bandtype = wlc->band->bandtype;
+-
+-	/* get antennas available */
+-	aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g"));
+-	if (aa == 0)
+-		aa = (s8) getintvar(vars,
+-				      (BAND_5G(bandtype) ? "aa1" : "aa0"));
+-	if ((aa < 1) || (aa > 15)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+-			  " srom (0x%x), using 3\n", unit, __func__, aa);
+-		aa = 3;
+-	}
+-
+-	/* reset the defaults if we have a single antenna */
+-	if (aa == 1) {
+-		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0;
+-		wlc->stf->txant = ANT_TX_FORCE_0;
+-	} else if (aa == 2) {
+-		wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1;
+-		wlc->stf->txant = ANT_TX_FORCE_1;
+-	} else {
+-	}
+-
+-	/* Compute Antenna Gain */
+-	wlc->band->antgain =
+-	    (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0"));
+-	wlc_attach_antgain_init(wlc);
+-
+-	return true;
+-}
+-
+-
+-static void wlc_timers_deinit(struct wlc_info *wlc)
+-{
+-	/* free timer state */
+-	if (wlc->wdtimer) {
+-		wl_free_timer(wlc->wl, wlc->wdtimer);
+-		wlc->wdtimer = NULL;
+-	}
+-	if (wlc->radio_timer) {
+-		wl_free_timer(wlc->wl, wlc->radio_timer);
+-		wlc->radio_timer = NULL;
+-	}
+-}
+-
+-static void wlc_detach_module(struct wlc_info *wlc)
+-{
+-	if (wlc->asi) {
+-		wlc_antsel_detach(wlc->asi);
+-		wlc->asi = NULL;
+-	}
+-
+-	if (wlc->ampdu) {
+-		wlc_ampdu_detach(wlc->ampdu);
+-		wlc->ampdu = NULL;
+-	}
+-
+-	wlc_stf_detach(wlc);
+-}
+-
+-/*
+- * Return a count of the number of driver callbacks still pending.
+- *
+- * General policy is that wlc_detach can only dealloc/free software states. It can NOT
+- *  touch hardware registers since the d11core may be in reset and clock may not be available.
+- *    One exception is sb register access, which is possible if crystal is turned on
+- * After "down" state, driver should avoid software timer with the exception of radio_monitor.
+- */
+-uint wlc_detach(struct wlc_info *wlc)
+-{
+-	uint callbacks = 0;
+-
+-	if (wlc == NULL)
+-		return 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	callbacks += wlc_bmac_detach(wlc);
+-
+-	/* delete software timers */
+-	if (!wlc_radio_monitor_stop(wlc))
+-		callbacks++;
+-
+-	wlc_channel_mgr_detach(wlc->cmi);
+-
+-	wlc_timers_deinit(wlc);
+-
+-	wlc_detach_module(wlc);
+-
+-	/* free other state */
+-
+-
+-#ifdef BCMDBG
+-	kfree(wlc->country_ie_override);
+-	wlc->country_ie_override = NULL;
+-#endif				/* BCMDBG */
+-
+-	{
+-		/* free dumpcb list */
+-		struct dumpcb_s *prev, *ptr;
+-		prev = ptr = wlc->dumpcb_head;
+-		while (ptr) {
+-			ptr = prev->next;
+-			kfree(prev);
+-			prev = ptr;
+-		}
+-		wlc->dumpcb_head = NULL;
+-	}
+-
+-	/* Detach from iovar manager */
+-	wlc_module_unregister(wlc->pub, "wlc_iovars", wlc);
+-
+-	while (wlc->tx_queues != NULL)
+-		wlc_txq_free(wlc, wlc->tx_queues);
+-
+-	wlc_detach_mfree(wlc);
+-	return callbacks;
+-}
+-
+-/* update state that depends on the current value of "ap" */
+-void wlc_ap_upd(struct wlc_info *wlc)
+-{
+-	if (AP_ENAB(wlc->pub))
+-		wlc->PLCPHdr_override = WLC_PLCP_AUTO;	/* AP: short not allowed, but not enforced */
+-	else
+-		wlc->PLCPHdr_override = WLC_PLCP_SHORT;	/* STA-BSS; short capable */
+-
+-	/* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */
+-	wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO;
+-
+-	/* fixup mpc */
+-	wlc->mpc = true;
+-}
+-
+-/* read hwdisable state and propagate to wlc flag */
+-static void wlc_radio_hwdisable_upd(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off)
+-		return;
+-
+-	if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) {
+-		mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+-	} else {
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
+-	}
+-}
+-
+-/* return true if Minimum Power Consumption should be entered, false otherwise */
+-bool wlc_is_non_delay_mpc(struct wlc_info *wlc)
+-{
+-	return false;
+-}
+-
+-bool wlc_ismpc(struct wlc_info *wlc)
+-{
+-	return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc));
+-}
+-
+-void wlc_radio_mpc_upd(struct wlc_info *wlc)
+-{
+-	bool mpc_radio, radio_state;
+-
+-	/*
+-	 * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
+-	 * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
+-	 * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
+-	 * the radio is going down.
+-	 */
+-	if (!wlc->mpc) {
+-		if (!wlc->pub->radio_disabled)
+-			return;
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+-		wlc_radio_upd(wlc);
+-		if (!wlc->pub->radio_disabled)
+-			wlc_radio_monitor_stop(wlc);
+-		return;
+-	}
+-
+-	/*
+-	 * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled
+-	 * to go ON, always call radio_upd synchronously
+-	 * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog)
+-	 */
+-	radio_state =
+-	    (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF :
+-	     ON);
+-	mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON;
+-
+-	if (radio_state == ON && mpc_radio == OFF)
+-		wlc->mpc_delay_off = wlc->mpc_dlycnt;
+-	else if (radio_state == OFF && mpc_radio == ON) {
+-		mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
+-		wlc_radio_upd(wlc);
+-		if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) {
+-			wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT;
+-		} else
+-			wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT;
+-		wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts;
+-	}
+-	/* Below logic is meant to capture the transition from mpc off to mpc on for reasons
+-	 * other than wlc->mpc_delay_off keeping the mpc off. In that case reset
+-	 * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off
+-	 */
+-	if ((wlc->prev_non_delay_mpc == false) &&
+-	    (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) {
+-		wlc->mpc_delay_off = wlc->mpc_dlycnt;
+-	}
+-	wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc);
+-}
+-
+-/*
+- * centralized radio disable/enable function,
+- * invoke radio enable/disable after updating hwradio status
+- */
+-static void wlc_radio_upd(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->radio_disabled) {
+-		wlc_radio_disable(wlc);
+-	} else {
+-		wlc_radio_enable(wlc);
+-	}
+-}
+-
+-/* maintain LED behavior in down state */
+-static void wlc_down_led_upd(struct wlc_info *wlc)
+-{
+-	/* maintain LEDs while in down state, turn on sbclk if not available yet */
+-	/* turn on sbclk if necessary */
+-	if (!AP_ENAB(wlc->pub)) {
+-		wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP);
+-
+-		wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP);
+-	}
+-}
+-
+-/* update hwradio status and return it */
+-bool wlc_check_radio_disabled(struct wlc_info *wlc)
+-{
+-	wlc_radio_hwdisable_upd(wlc);
+-
+-	return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false;
+-}
+-
+-void wlc_radio_disable(struct wlc_info *wlc)
+-{
+-	if (!wlc->pub->up) {
+-		wlc_down_led_upd(wlc);
+-		return;
+-	}
+-
+-	wlc_radio_monitor_start(wlc);
+-	wl_down(wlc->wl);
+-}
+-
+-static void wlc_radio_enable(struct wlc_info *wlc)
+-{
+-	if (wlc->pub->up)
+-		return;
+-
+-	if (DEVICEREMOVED(wlc))
+-		return;
+-
+-	if (!wlc->down_override) {	/* imposed by wl down/out ioctl */
+-		wl_up(wlc->wl);
+-	}
+-}
+-
+-/* periodical query hw radio button while driver is "down" */
+-static void wlc_radio_timer(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			__func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-
+-	/* cap mpc off count */
+-	if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT)
+-		wlc->mpc_offcnt++;
+-
+-	wlc_radio_hwdisable_upd(wlc);
+-	wlc_radio_upd(wlc);
+-}
+-
+-static bool wlc_radio_monitor_start(struct wlc_info *wlc)
+-{
+-	/* Don't start the timer if HWRADIO feature is disabled */
+-	if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO))
+-		return true;
+-
+-	wlc->radio_monitor = true;
+-	wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON);
+-	wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
+-	return true;
+-}
+-
+-bool wlc_radio_monitor_stop(struct wlc_info *wlc)
+-{
+-	if (!wlc->radio_monitor)
+-		return true;
+-
+-	wlc->radio_monitor = false;
+-	wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON);
+-	return wl_del_timer(wlc->wl, wlc->radio_timer);
+-}
+-
+-static void wlc_watchdog_by_timer(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	wlc_watchdog(arg);
+-	if (WLC_WATCHDOG_TBTT(wlc)) {
+-		/* set to normal osl watchdog period */
+-		wl_del_timer(wlc->wl, wlc->wdtimer);
+-		wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG,
+-			     true);
+-	}
+-}
+-
+-/* common watchdog code */
+-static void wlc_watchdog(void *arg)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) arg;
+-	int i;
+-	struct wlc_bsscfg *cfg;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	if (!wlc->pub->up)
+-		return;
+-
+-	if (DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return;
+-	}
+-
+-	/* increment second count */
+-	wlc->pub->now++;
+-
+-	/* delay radio disable */
+-	if (wlc->mpc_delay_off) {
+-		if (--wlc->mpc_delay_off == 0) {
+-			mboolset(wlc->pub->radio_disabled,
+-				 WL_RADIO_MPC_DISABLE);
+-			if (wlc->mpc && wlc_ismpc(wlc))
+-				wlc->mpc_offcnt = 0;
+-			wlc->mpc_laston_ts = OSL_SYSUPTIME();
+-		}
+-	}
+-
+-	/* mpc sync */
+-	wlc_radio_mpc_upd(wlc);
+-	/* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
+-	wlc_radio_hwdisable_upd(wlc);
+-	wlc_radio_upd(wlc);
+-	/* if radio is disable, driver may be down, quit here */
+-	if (wlc->pub->radio_disabled)
+-		return;
+-
+-	wlc_bmac_watchdog(wlc);
+-
+-	/* occasionally sample mac stat counters to detect 16-bit counter wrap */
+-	if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0)
+-		wlc_statsupd(wlc);
+-
+-	/* Manage TKIP countermeasures timers */
+-	FOREACH_BSS(wlc, i, cfg) {
+-		if (cfg->tk_cm_dt) {
+-			cfg->tk_cm_dt--;
+-		}
+-		if (cfg->tk_cm_bt) {
+-			cfg->tk_cm_bt--;
+-		}
+-	}
+-
+-	/* Call any registered watchdog handlers */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].watchdog_fn)
+-			wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl);
+-	}
+-
+-	if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable &&
+-	    ((wlc->pub->now - wlc->tempsense_lasttime) >=
+-	     WLC_TEMPSENSE_PERIOD)) {
+-		wlc->tempsense_lasttime = wlc->pub->now;
+-		wlc_tempsense_upd(wlc);
+-	}
+-}
+-
+-/* make interface operational */
+-int wlc_up(struct wlc_info *wlc)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* HW is turned off so don't try to access it */
+-	if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
+-		return -ENOMEDIUM;
+-
+-	if (!wlc->pub->hw_up) {
+-		wlc_bmac_hw_up(wlc->hw);
+-		wlc->pub->hw_up = true;
+-	}
+-
+-	if ((wlc->pub->boardflags & BFL_FEM)
+-	    && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) {
+-		if (wlc->pub->boardrev >= 0x1250
+-		    && (wlc->pub->boardflags & BFL_FEM_BT)) {
+-			wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL,
+-				MHF5_4313_GPIOCTRL, WLC_BAND_ALL);
+-		} else {
+-			wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE,
+-				WLC_BAND_ALL);
+-		}
+-	}
+-
+-	/*
+-	 * Need to read the hwradio status here to cover the case where the system
+-	 * is loaded with the hw radio disabled. We do not want to bring the driver up in this case.
+-	 * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
+-	 * don't call radio_update to avoid looping wlc_up.
+-	 *
+-	 * wlc_bmac_up_prep() returns either 0 or -BCME_RADIOOFF only
+-	 */
+-	if (!wlc->pub->radio_disabled) {
+-		int status = wlc_bmac_up_prep(wlc->hw);
+-		if (status == -ENOMEDIUM) {
+-			if (!mboolisset
+-			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
+-				int idx;
+-				struct wlc_bsscfg *bsscfg;
+-				mboolset(wlc->pub->radio_disabled,
+-					 WL_RADIO_HW_DISABLE);
+-
+-				FOREACH_BSS(wlc, idx, bsscfg) {
+-					if (!BSSCFG_STA(bsscfg)
+-					    || !bsscfg->enable || !bsscfg->BSS)
+-						continue;
+-					wiphy_err(wlc->wiphy, "wl%d.%d: wlc_up"
+-						  ": rfdisable -> "
+-						  "wlc_bsscfg_disable()\n",
+-						   wlc->pub->unit, idx);
+-				}
+-			}
+-		}
+-	}
+-
+-	if (wlc->pub->radio_disabled) {
+-		wlc_radio_monitor_start(wlc);
+-		return 0;
+-	}
+-
+-	/* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */
+-	wlc->clk = true;
+-
+-	wlc_radio_monitor_stop(wlc);
+-
+-	/* Set EDCF hostflags */
+-	if (EDCF_ENAB(wlc->pub)) {
+-		wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL);
+-	} else {
+-		wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL);
+-	}
+-
+-	if (WLC_WAR16165(wlc))
+-		wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR,
+-			WLC_BAND_ALL);
+-
+-	wl_init(wlc->wl);
+-	wlc->pub->up = true;
+-
+-	if (wlc->bandinit_pending) {
+-		wlc_suspend_mac_and_wait(wlc);
+-		wlc_set_chanspec(wlc, wlc->default_bss->chanspec);
+-		wlc->bandinit_pending = false;
+-		wlc_enable_mac(wlc);
+-	}
+-
+-	wlc_bmac_up_finish(wlc->hw);
+-
+-	/* other software states up after ISR is running */
+-	/* start APs that were to be brought up but are not up  yet */
+-	/* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */
+-
+-	/* Program the TX wme params with the current settings */
+-	wlc_wme_retries_write(wlc);
+-
+-	/* start one second watchdog timer */
+-	wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
+-	wlc->WDarmed = true;
+-
+-	/* ensure antenna config is up to date */
+-	wlc_stf_phy_txant_upd(wlc);
+-	/* ensure LDPC config is in sync */
+-	wlc_ht_update_ldpc(wlc, wlc->stf->ldpc);
+-
+-	return 0;
+-}
+-
+-/* Initialize the base precedence map for dequeueing from txq based on WME settings */
+-static void wlc_tx_prec_map_init(struct wlc_info *wlc)
+-{
+-	wlc->tx_prec_map = WLC_PREC_BMP_ALL;
+-	memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16));
+-
+-	/* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences
+-	 * if either is full.
+-	 */
+-	if (!EDCF_ENAB(wlc->pub)) {
+-		wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL;
+-		wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL;
+-	} else {
+-		wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK;
+-		wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE;
+-		wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI;
+-		wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO;
+-	}
+-}
+-
+-static uint wlc_down_del_timer(struct wlc_info *wlc)
+-{
+-	uint callbacks = 0;
+-
+-	return callbacks;
+-}
+-
+-/*
+- * Mark the interface nonoperational, stop the software mechanisms,
+- * disable the hardware, free any transient buffer state.
+- * Return a count of the number of driver callbacks still pending.
+- */
+-uint wlc_down(struct wlc_info *wlc)
+-{
+-
+-	uint callbacks = 0;
+-	int i;
+-	bool dev_gone = false;
+-	struct wlc_txq_info *qi;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* check if we are already in the going down path */
+-	if (wlc->going_down) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
+-			  "\n", wlc->pub->unit, __func__);
+-		return 0;
+-	}
+-	if (!wlc->pub->up)
+-		return callbacks;
+-
+-	/* in between, mpc could try to bring down again.. */
+-	wlc->going_down = true;
+-
+-	callbacks += wlc_bmac_down_prep(wlc->hw);
+-
+-	dev_gone = DEVICEREMOVED(wlc);
+-
+-	/* Call any registered down handlers */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].down_fn)
+-			callbacks +=
+-			    wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl);
+-	}
+-
+-	/* cancel the watchdog timer */
+-	if (wlc->WDarmed) {
+-		if (!wl_del_timer(wlc->wl, wlc->wdtimer))
+-			callbacks++;
+-		wlc->WDarmed = false;
+-	}
+-	/* cancel all other timers */
+-	callbacks += wlc_down_del_timer(wlc);
+-
+-	wlc->pub->up = false;
+-
+-	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
+-
+-	/* clear txq flow control */
+-	wlc_txflowcontrol_reset(wlc);
+-
+-	/* flush tx queues */
+-	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+-		bcm_pktq_flush(&qi->q, true, NULL, NULL);
+-	}
+-
+-	callbacks += wlc_bmac_down_finish(wlc->hw);
+-
+-	/* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */
+-	wlc->clk = false;
+-
+-	wlc->going_down = false;
+-	return callbacks;
+-}
+-
+-/* Set the current gmode configuration */
+-int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config)
+-{
+-	int ret = 0;
+-	uint i;
+-	wlc_rateset_t rs;
+-	/* Default to 54g Auto */
+-	s8 shortslot = WLC_SHORTSLOT_AUTO;	/* Advertise and use shortslot (-1/0/1 Auto/Off/On) */
+-	bool shortslot_restrict = false;	/* Restrict association to stations that support shortslot
+-						 */
+-	bool ignore_bcns = true;	/* Ignore legacy beacons on the same channel */
+-	bool ofdm_basic = false;	/* Make 6, 12, and 24 basic rates */
+-	int preamble = WLC_PLCP_LONG;	/* Advertise and use short preambles (-1/0/1 Auto/Off/On) */
+-	bool preamble_restrict = false;	/* Restrict association to stations that support short
+-					 * preambles
+-					 */
+-	struct wlcband *band;
+-
+-	/* if N-support is enabled, allow Gmode set as long as requested
+-	 * Gmode is not GMODE_LEGACY_B
+-	 */
+-	if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
+-		return -ENOTSUPP;
+-
+-	/* verify that we are dealing with 2G band and grab the band pointer */
+-	if (wlc->band->bandtype == WLC_BAND_2G)
+-		band = wlc->band;
+-	else if ((NBANDS(wlc) > 1) &&
+-		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G))
+-		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+-	else
+-		return -EINVAL;
+-
+-	/* Legacy or bust when no OFDM is supported by regulatory */
+-	if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
+-	     WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B))
+-		return -EINVAL;
+-
+-	/* update configuration value */
+-	if (config == true)
+-		wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode);
+-
+-	/* Clear supported rates filter */
+-	memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t));
+-
+-	/* Clear rateset override */
+-	memset(&rs, 0, sizeof(wlc_rateset_t));
+-
+-	switch (gmode) {
+-	case GMODE_LEGACY_B:
+-		shortslot = WLC_SHORTSLOT_OFF;
+-		wlc_rateset_copy(&gphy_legacy_rates, &rs);
+-
+-		break;
+-
+-	case GMODE_LRS:
+-		if (AP_ENAB(wlc->pub))
+-			wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override);
+-		break;
+-
+-	case GMODE_AUTO:
+-		/* Accept defaults */
+-		break;
+-
+-	case GMODE_ONLY:
+-		ofdm_basic = true;
+-		preamble = WLC_PLCP_SHORT;
+-		preamble_restrict = true;
+-		break;
+-
+-	case GMODE_PERFORMANCE:
+-		if (AP_ENAB(wlc->pub))	/* Put all rates into the Supported Rates element */
+-			wlc_rateset_copy(&cck_ofdm_rates,
+-					 &wlc->sup_rates_override);
+-
+-		shortslot = WLC_SHORTSLOT_ON;
+-		shortslot_restrict = true;
+-		ofdm_basic = true;
+-		preamble = WLC_PLCP_SHORT;
+-		preamble_restrict = true;
+-		break;
+-
+-	default:
+-		/* Error */
+-		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
+-			  wlc->pub->unit, __func__, gmode);
+-		return -ENOTSUPP;
+-	}
+-
+-	/*
+-	 * If we are switching to gmode == GMODE_LEGACY_B,
+-	 * clean up rate info that may refer to OFDM rates.
+-	 */
+-	if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) {
+-		band->gmode = gmode;
+-		if (band->rspec_override && !IS_CCK(band->rspec_override)) {
+-			band->rspec_override = 0;
+-			wlc_reprate_init(wlc);
+-		}
+-		if (band->mrspec_override && !IS_CCK(band->mrspec_override)) {
+-			band->mrspec_override = 0;
+-		}
+-	}
+-
+-	band->gmode = gmode;
+-
+-	wlc->ignore_bcns = ignore_bcns;
+-
+-	wlc->shortslot_override = shortslot;
+-
+-	if (AP_ENAB(wlc->pub)) {
+-		/* wlc->ap->shortslot_restrict = shortslot_restrict; */
+-		wlc->PLCPHdr_override =
+-		    (preamble !=
+-		     WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO;
+-	}
+-
+-	if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG)
+-	    || preamble == WLC_PLCP_SHORT)
+-		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+-	else
+-		wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE;
+-
+-	/* Update shortslot capability bit for AP and IBSS */
+-	if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) ||
+-	    shortslot == WLC_SHORTSLOT_ON)
+-		wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-	else
+-		wlc->default_bss->capability &=
+-					~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+-
+-	/* Use the default 11g rateset */
+-	if (!rs.count)
+-		wlc_rateset_copy(&cck_ofdm_rates, &rs);
+-
+-	if (ofdm_basic) {
+-		for (i = 0; i < rs.count; i++) {
+-			if (rs.rates[i] == WLC_RATE_6M
+-			    || rs.rates[i] == WLC_RATE_12M
+-			    || rs.rates[i] == WLC_RATE_24M)
+-				rs.rates[i] |= WLC_RATE_FLAG;
+-		}
+-	}
+-
+-	/* Set default bss rateset */
+-	wlc->default_bss->rateset.count = rs.count;
+-	memcpy(wlc->default_bss->rateset.rates, rs.rates, 
+-	       sizeof(wlc->default_bss->rateset.rates));
+-
+-	return ret;
+-}
+-
+-static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode)
+-{
+-	int err = 0;
+-
+-	switch (nmode) {
+-
+-	case OFF:
+-		break;
+-
+-	case AUTO:
+-	case WL_11N_2x2:
+-	case WL_11N_3x3:
+-		if (!(WLC_PHY_11N_CAP(wlc->band)))
+-			err = -EINVAL;
+-		break;
+-
+-	default:
+-		err = -EINVAL;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-int wlc_set_nmode(struct wlc_info *wlc, s32 nmode)
+-{
+-	uint i;
+-	int err;
+-
+-	err = wlc_nmode_validate(wlc, nmode);
+-	if (err)
+-		return err;
+-
+-	switch (nmode) {
+-	case OFF:
+-		wlc->pub->_n_enab = OFF;
+-		wlc->default_bss->flags &= ~WLC_BSS_HT;
+-		/* delete the mcs rates from the default and hw ratesets */
+-		wlc_rateset_mcs_clear(&wlc->default_bss->rateset);
+-		for (i = 0; i < NBANDS(wlc); i++) {
+-			memset(wlc->bandstate[i]->hw_rateset.mcs, 0,
+-			       MCSSET_LEN);
+-			if (IS_MCS(wlc->band->rspec_override)) {
+-				wlc->bandstate[i]->rspec_override = 0;
+-				wlc_reprate_init(wlc);
+-			}
+-			if (IS_MCS(wlc->band->mrspec_override))
+-				wlc->bandstate[i]->mrspec_override = 0;
+-		}
+-		break;
+-
+-	case AUTO:
+-		if (wlc->stf->txstreams == WL_11N_3x3)
+-			nmode = WL_11N_3x3;
+-		else
+-			nmode = WL_11N_2x2;
+-	case WL_11N_2x2:
+-	case WL_11N_3x3:
+-		/* force GMODE_AUTO if NMODE is ON */
+-		wlc_set_gmode(wlc, GMODE_AUTO, true);
+-		if (nmode == WL_11N_3x3)
+-			wlc->pub->_n_enab = SUPPORT_HT;
+-		else
+-			wlc->pub->_n_enab = SUPPORT_11N;
+-		wlc->default_bss->flags |= WLC_BSS_HT;
+-		/* add the mcs rates to the default and hw ratesets */
+-		wlc_rateset_mcs_build(&wlc->default_bss->rateset,
+-				      wlc->stf->txstreams);
+-		for (i = 0; i < NBANDS(wlc); i++)
+-			memcpy(wlc->bandstate[i]->hw_rateset.mcs,
+-			       wlc->default_bss->rateset.mcs, MCSSET_LEN);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg)
+-{
+-	wlc_rateset_t rs, new;
+-	uint bandunit;
+-
+-	memcpy(&rs, rs_arg, sizeof(wlc_rateset_t));
+-
+-	/* check for bad count value */
+-	if ((rs.count == 0) || (rs.count > WLC_NUMRATES))
+-		return -EINVAL;
+-
+-	/* try the current band */
+-	bandunit = wlc->band->bandunit;
+-	memcpy(&new, &rs, sizeof(wlc_rateset_t));
+-	if (wlc_rate_hwrs_filter_sort_validate
+-	    (&new, &wlc->bandstate[bandunit]->hw_rateset, true,
+-	     wlc->stf->txstreams))
+-		goto good;
+-
+-	/* try the other band */
+-	if (IS_MBAND_UNLOCKED(wlc)) {
+-		bandunit = OTHERBANDUNIT(wlc);
+-		memcpy(&new, &rs, sizeof(wlc_rateset_t));
+-		if (wlc_rate_hwrs_filter_sort_validate(&new,
+-						       &wlc->
+-						       bandstate[bandunit]->
+-						       hw_rateset, true,
+-						       wlc->stf->txstreams))
+-			goto good;
+-	}
+-
+-	return -EBADE;
+-
+- good:
+-	/* apply new rateset */
+-	memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t));
+-	memcpy(&wlc->bandstate[bandunit]->defrateset, &new,
+-	       sizeof(wlc_rateset_t));
+-	return 0;
+-}
+-
+-/* simplified integer set interface for common ioctl handler */
+-int wlc_set(struct wlc_info *wlc, int cmd, int arg)
+-{
+-	return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL);
+-}
+-
+-/* simplified integer get interface for common ioctl handler */
+-int wlc_get(struct wlc_info *wlc, int cmd, int *arg)
+-{
+-	return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL);
+-}
+-
+-static void wlc_ofdm_rateset_war(struct wlc_info *wlc)
+-{
+-	u8 r;
+-	bool war = false;
+-
+-	if (wlc->cfg->associated)
+-		r = wlc->cfg->current_bss->rateset.rates[0];
+-	else
+-		r = wlc->default_bss->rateset.rates[0];
+-
+-	wlc_phy_ofdm_rateset_war(wlc->band->pi, war);
+-
+-	return;
+-}
+-
+-int
+-wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-	  struct wlc_if *wlcif)
+-{
+-	return _wlc_ioctl(wlc, cmd, arg, len, wlcif);
+-}
+-
+-/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */
+-static int
+-_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-	   struct wlc_if *wlcif)
+-{
+-	int val, *pval;
+-	bool bool_val;
+-	int bcmerror;
+-	d11regs_t *regs;
+-	uint i;
+-	struct scb *nextscb;
+-	bool ta_ok;
+-	uint band;
+-	rw_reg_t *r;
+-	struct wlc_bsscfg *bsscfg;
+-	wlc_bss_info_t *current_bss;
+-
+-	/* update bsscfg pointer */
+-	bsscfg = wlc->cfg;
+-	current_bss = bsscfg->current_bss;
+-
+-	/* initialize the following to get rid of compiler warning */
+-	nextscb = NULL;
+-	ta_ok = false;
+-	band = 0;
+-	r = NULL;
+-
+-	/* If the device is turned off, then it's not "removed" */
+-	if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+-			  __func__);
+-		wl_down(wlc->wl);
+-		return -EBADE;
+-	}
+-
+-	/* default argument is generic integer */
+-	pval = arg ? (int *)arg:NULL;
+-
+-	/* This will prevent the misaligned access */
+-	if (pval && (u32) len >= sizeof(val))
+-		memcpy(&val, pval, sizeof(val));
+-	else
+-		val = 0;
+-
+-	/* bool conversion to avoid duplication below */
+-	bool_val = val != 0;
+-	bcmerror = 0;
+-	regs = wlc->regs;
+-
+-	/* A few commands don't need any arguments; all the others do. */
+-	switch (cmd) {
+-	case WLC_UP:
+-	case WLC_OUT:
+-	case WLC_DOWN:
+-	case WLC_DISASSOC:
+-	case WLC_RESTART:
+-	case WLC_REBOOT:
+-	case WLC_START_CHANNEL_QA:
+-	case WLC_INIT:
+-		break;
+-
+-	default:
+-		if ((arg == NULL) || (len <= 0)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs "
+-				  "arguments\n",
+-				  wlc->pub->unit, __func__, cmd);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	}
+-
+-	switch (cmd) {
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_MSGLEVEL:
+-		*pval = wl_msg_level;
+-		break;
+-
+-	case WLC_SET_MSGLEVEL:
+-		wl_msg_level = val;
+-		break;
+-#endif
+-
+-	case WLC_GET_INSTANCE:
+-		*pval = wlc->pub->unit;
+-		break;
+-
+-	case WLC_GET_CHANNEL:{
+-			channel_info_t *ci = (channel_info_t *) arg;
+-
+-			if (len <= (int)sizeof(ci)) {
+-				bcmerror = EOVERFLOW;
+-				goto done;
+-			}
+-
+-			ci->hw_channel =
+-			    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC);
+-			ci->target_channel =
+-			    CHSPEC_CHANNEL(wlc->default_bss->chanspec);
+-			ci->scan_channel = 0;
+-
+-			break;
+-		}
+-
+-	case WLC_SET_CHANNEL:{
+-			chanspec_t chspec = CH20MHZ_CHSPEC(val);
+-
+-			if (val < 0 || val > MAXCHANNEL) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) {
+-				if (wlc->band->bandunit !=
+-				    CHSPEC_WLCBANDUNIT(chspec))
+-					wlc->bandinit_pending = true;
+-				else
+-					wlc->bandinit_pending = false;
+-			}
+-
+-			wlc->default_bss->chanspec = chspec;
+-			/* wlc_BSSinit() will sanitize the rateset before using it.. */
+-			if (wlc->pub->up &&
+-			    (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) {
+-				wlc_set_home_chanspec(wlc, chspec);
+-				wlc_suspend_mac_and_wait(wlc);
+-				wlc_set_chanspec(wlc, chspec);
+-				wlc_enable_mac(wlc);
+-			}
+-			break;
+-		}
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_UCFLAGS:
+-		if (!wlc->pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val >= MHFMAX) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		*pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO);
+-		break;
+-
+-	case WLC_SET_UCFLAGS:
+-		if (!wlc->pub->up) {
+-			bcmerror = -ENOLINK;
+-			break;
+-		}
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		i = (u16) val;
+-		if (i >= MHFMAX) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)),
+-			WLC_BAND_AUTO);
+-		break;
+-
+-	case WLC_GET_SHMEM:
+-		ta_ok = true;
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val & 1) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		*pval = wlc_read_shm(wlc, (u16) val);
+-		break;
+-
+-	case WLC_SET_SHMEM:
+-		ta_ok = true;
+-
+-		/* optional band is stored in the second integer of incoming buffer */
+-		band =
+-		    (len <
+-		     (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1];
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (val & 1) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_write_shm(wlc, (u16) val,
+-			      (u16) (val >> NBITS(u16)));
+-		break;
+-
+-	case WLC_R_REG:	/* MAC registers */
+-		ta_ok = true;
+-		r = (rw_reg_t *) arg;
+-		band = WLC_BAND_AUTO;
+-
+-		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-
+-		if (len >= (int)sizeof(rw_reg_t))
+-			band = r->band;
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if ((r->byteoff + r->size) > sizeof(d11regs_t)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (r->size == sizeof(u32))
+-			r->val =
+-			    R_REG((u32 *)((unsigned char *)(unsigned long)regs +
+-					      r->byteoff));
+-		else if (r->size == sizeof(u16))
+-			r->val =
+-			    R_REG((u16 *)((unsigned char *)(unsigned long)regs +
+-					      r->byteoff));
+-		else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_W_REG:
+-		ta_ok = true;
+-		r = (rw_reg_t *) arg;
+-		band = WLC_BAND_AUTO;
+-
+-		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-
+-		if (len >= (int)sizeof(rw_reg_t))
+-			band = r->band;
+-
+-		/* bcmerror checking */
+-		bcmerror = wlc_iocregchk(wlc, band);
+-		if (bcmerror)
+-			break;
+-
+-		if (r->byteoff + r->size > sizeof(d11regs_t)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (r->size == sizeof(u32))
+-			W_REG((u32 *)((unsigned char *)(unsigned long) regs +
+-					  r->byteoff), r->val);
+-		else if (r->size == sizeof(u16))
+-			W_REG((u16 *)((unsigned char *)(unsigned long) regs +
+-					  r->byteoff), r->val);
+-		else
+-			bcmerror = -EINVAL;
+-		break;
+-#endif				/* BCMDBG */
+-
+-	case WLC_GET_TXANT:
+-		*pval = wlc->stf->txant;
+-		break;
+-
+-	case WLC_SET_TXANT:
+-		bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val);
+-		if (bcmerror < 0)
+-			break;
+-
+-		wlc->stf->txant = (s8) val;
+-
+-		/* if down, we are done */
+-		if (!wlc->pub->up)
+-			break;
+-
+-		wlc_suspend_mac_and_wait(wlc);
+-
+-		wlc_stf_phy_txant_upd(wlc);
+-		wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+-
+-		wlc_enable_mac(wlc);
+-
+-		break;
+-
+-	case WLC_GET_ANTDIV:{
+-			u8 phy_antdiv;
+-
+-			/* return configured value if core is down */
+-			if (!wlc->pub->up) {
+-				*pval = wlc->stf->ant_rx_ovr;
+-
+-			} else {
+-				if (wlc_phy_ant_rxdiv_get
+-				    (wlc->band->pi, &phy_antdiv))
+-					*pval = (int)phy_antdiv;
+-				else
+-					*pval = (int)wlc->stf->ant_rx_ovr;
+-			}
+-
+-			break;
+-		}
+-	case WLC_SET_ANTDIV:
+-		/* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */
+-		if ((val < -1) || (val > 3)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		if (val == -1)
+-			val = ANT_RX_DIV_DEF;
+-
+-		wlc->stf->ant_rx_ovr = (u8) val;
+-		wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val);
+-		break;
+-
+-	case WLC_GET_RX_ANT:{	/* get latest used rx antenna */
+-			u16 rxstatus;
+-
+-			if (!wlc->pub->up) {
+-				bcmerror = -ENOLINK;
+-				break;
+-			}
+-
+-			rxstatus = R_REG(&wlc->regs->phyrxstatus0);
+-			if (rxstatus == 0xdead || rxstatus == (u16) -1) {
+-				bcmerror = -EBADE;
+-				break;
+-			}
+-			*pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
+-			break;
+-		}
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_UCANTDIV:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		*pval =
+-		    (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) &
+-		     MHF1_ANTDIV);
+-		break;
+-
+-	case WLC_SET_UCANTDIV:{
+-			if (!wlc->pub->up) {
+-				bcmerror = -ENOLINK;
+-				break;
+-			}
+-
+-			/* if multiband, band must be locked */
+-			if (IS_MBAND_UNLOCKED(wlc)) {
+-				bcmerror = -ENOMEDIUM;
+-				break;
+-			}
+-
+-			wlc_mhf(wlc, MHF1, MHF1_ANTDIV,
+-				(val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO);
+-			break;
+-		}
+-#endif				/* defined(BCMDBG) */
+-
+-	case WLC_GET_SRL:
+-		*pval = wlc->SRL;
+-		break;
+-
+-	case WLC_SET_SRL:
+-		if (val >= 1 && val <= RETRY_SHORT_MAX) {
+-			int ac;
+-			wlc->SRL = (u16) val;
+-
+-			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+-
+-			for (ac = 0; ac < AC_COUNT; ac++) {
+-				WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL);
+-			}
+-			wlc_wme_retries_write(wlc);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_LRL:
+-		*pval = wlc->LRL;
+-		break;
+-
+-	case WLC_SET_LRL:
+-		if (val >= 1 && val <= 255) {
+-			int ac;
+-			wlc->LRL = (u16) val;
+-
+-			wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);
+-
+-			for (ac = 0; ac < AC_COUNT; ac++) {
+-				WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL);
+-			}
+-			wlc_wme_retries_write(wlc);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_CWMIN:
+-		*pval = wlc->band->CWmin;
+-		break;
+-
+-	case WLC_SET_CWMIN:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		if (val >= 1 && val <= 255) {
+-			wlc_set_cwmin(wlc, (u16) val);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_CWMAX:
+-		*pval = wlc->band->CWmax;
+-		break;
+-
+-	case WLC_SET_CWMAX:
+-		if (!wlc->clk) {
+-			bcmerror = -EIO;
+-			break;
+-		}
+-
+-		if (val >= 255 && val <= 2047) {
+-			wlc_set_cwmax(wlc, (u16) val);
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_RADIO:	/* use mask if don't want to expose some internal bits */
+-		*pval = wlc->pub->radio_disabled;
+-		break;
+-
+-	case WLC_SET_RADIO:{	/* 32 bits input, higher 16 bits are mask, lower 16 bits are value to
+-				 * set
+-				 */
+-			u16 radiomask, radioval;
+-			uint validbits =
+-			    WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE;
+-			mbool new = 0;
+-
+-			radiomask = (val & 0xffff0000) >> 16;
+-			radioval = val & 0x0000ffff;
+-
+-			if ((radiomask == 0) || (radiomask & ~validbits)
+-			    || (radioval & ~validbits)
+-			    || ((radioval & ~radiomask) != 0)) {
+-				wiphy_err(wlc->wiphy, "SET_RADIO with wrong "
+-					  "bits 0x%x\n", val);
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			new =
+-			    (wlc->pub->radio_disabled & ~radiomask) | radioval;
+-			wlc->pub->radio_disabled = new;
+-
+-			wlc_radio_hwdisable_upd(wlc);
+-			wlc_radio_upd(wlc);
+-			break;
+-		}
+-
+-	case WLC_GET_PHYTYPE:
+-		*pval = WLC_PHYTYPE(wlc->band->phytype);
+-		break;
+-
+-#if defined(BCMDBG)
+-	case WLC_GET_KEY:
+-		if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) {
+-			wl_wsec_key_t key;
+-
+-			wsec_key_t *src_key = wlc->wsec_keys[val];
+-
+-			if (len < (int)sizeof(key)) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			memset((char *)&key, 0, sizeof(key));
+-			if (src_key) {
+-				key.index = src_key->id;
+-				key.len = src_key->len;
+-				memcpy(key.data, src_key->data, key.len);
+-				key.algo = src_key->algo;
+-				if (WSEC_SOFTKEY(wlc, src_key, bsscfg))
+-					key.flags |= WL_SOFT_KEY;
+-				if (src_key->flags & WSEC_PRIMARY_KEY)
+-					key.flags |= WL_PRIMARY_KEY;
+-
+-				memcpy(key.ea, src_key->ea, ETH_ALEN);
+-			}
+-
+-			memcpy(arg, &key, sizeof(key));
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-#endif				/* defined(BCMDBG) */
+-
+-	case WLC_SET_KEY:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_GET_KEY_SEQ:{
+-			wsec_key_t *key;
+-
+-			if (len < DOT11_WPA_KEY_RSC_LEN) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Return the key's tx iv as an EAPOL sequence counter.
+-			 * This will be used to supply the RSC value to a supplicant.
+-			 * The format is 8 bytes, with least significant in seq[0].
+-			 */
+-
+-			key = WSEC_KEY(wlc, val);
+-			if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) &&
+-				(key != NULL)) {
+-				u8 seq[DOT11_WPA_KEY_RSC_LEN];
+-				u16 lo;
+-				u32 hi;
+-				/* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */
+-				if ((bsscfg->WPA_auth & WPA_AUTH_NONE) &&
+-				    is_zero_ether_addr(key->ea)) {
+-					lo = bsscfg->wpa_none_txiv.lo;
+-					hi = bsscfg->wpa_none_txiv.hi;
+-				} else {
+-					lo = key->txiv.lo;
+-					hi = key->txiv.hi;
+-				}
+-
+-				/* format the buffer, low to high */
+-				seq[0] = lo & 0xff;
+-				seq[1] = (lo >> 8) & 0xff;
+-				seq[2] = hi & 0xff;
+-				seq[3] = (hi >> 8) & 0xff;
+-				seq[4] = (hi >> 16) & 0xff;
+-				seq[5] = (hi >> 24) & 0xff;
+-				seq[6] = 0;
+-				seq[7] = 0;
+-
+-				memcpy(arg, seq, sizeof(seq));
+-			} else {
+-				bcmerror = -EINVAL;
+-			}
+-			break;
+-		}
+-
+-	case WLC_GET_CURR_RATESET:{
+-			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+-			wlc_rateset_t *rs;
+-
+-			if (wlc->pub->associated)
+-				rs = &current_bss->rateset;
+-			else
+-				rs = &wlc->default_bss->rateset;
+-
+-			if (len < (int)(rs->count + sizeof(rs->count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Copy only legacy rateset section */
+-			ret_rs->count = rs->count;
+-			memcpy(&ret_rs->rates, &rs->rates, rs->count);
+-			break;
+-		}
+-
+-	case WLC_GET_RATESET:{
+-			wlc_rateset_t rs;
+-			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
+-
+-			memset(&rs, 0, sizeof(wlc_rateset_t));
+-			wlc_default_rateset(wlc, (wlc_rateset_t *) &rs);
+-
+-			if (len < (int)(rs.count + sizeof(rs.count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			/* Copy only legacy rateset section */
+-			ret_rs->count = rs.count;
+-			memcpy(&ret_rs->rates, &rs.rates, rs.count);
+-			break;
+-		}
+-
+-	case WLC_SET_RATESET:{
+-			wlc_rateset_t rs;
+-			wl_rateset_t *in_rs = (wl_rateset_t *) arg;
+-
+-			if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			if (in_rs->count > WLC_NUMRATES) {
+-				bcmerror = -ENOBUFS;
+-				break;
+-			}
+-
+-			memset(&rs, 0, sizeof(wlc_rateset_t));
+-
+-			/* Copy only legacy rateset section */
+-			rs.count = in_rs->count;
+-			memcpy(&rs.rates, &in_rs->rates, rs.count);
+-
+-			/* merge rateset coming in with the current mcsset */
+-			if (N_ENAB(wlc->pub)) {
+-				if (bsscfg->associated)
+-					memcpy(rs.mcs,
+-					       &current_bss->rateset.mcs[0],
+-					       MCSSET_LEN);
+-				else
+-					memcpy(rs.mcs,
+-					       &wlc->default_bss->rateset.mcs[0],
+-					       MCSSET_LEN);
+-			}
+-
+-			bcmerror = wlc_set_rateset(wlc, &rs);
+-
+-			if (!bcmerror)
+-				wlc_ofdm_rateset_war(wlc);
+-
+-			break;
+-		}
+-
+-	case WLC_GET_BCNPRD:
+-		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+-			*pval = current_bss->beacon_period;
+-		else
+-			*pval = wlc->default_bss->beacon_period;
+-		break;
+-
+-	case WLC_SET_BCNPRD:
+-		/* range [1, 0xffff] */
+-		if (val >= DOT11_MIN_BEACON_PERIOD
+-		    && val <= DOT11_MAX_BEACON_PERIOD) {
+-			wlc->default_bss->beacon_period = (u16) val;
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-	case WLC_GET_DTIMPRD:
+-		if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated)
+-			*pval = current_bss->dtim_period;
+-		else
+-			*pval = wlc->default_bss->dtim_period;
+-		break;
+-
+-	case WLC_SET_DTIMPRD:
+-		/* range [1, 0xff] */
+-		if (val >= DOT11_MIN_DTIM_PERIOD
+-		    && val <= DOT11_MAX_DTIM_PERIOD) {
+-			wlc->default_bss->dtim_period = (u8) val;
+-		} else
+-			bcmerror = -EINVAL;
+-		break;
+-
+-#ifdef SUPPORT_PS
+-	case WLC_GET_PM:
+-		*pval = wlc->PM;
+-		break;
+-
+-	case WLC_SET_PM:
+-		if ((val >= PM_OFF) && (val <= PM_MAX)) {
+-			wlc->PM = (u8) val;
+-			if (wlc->pub->up) {
+-			}
+-			/* Change watchdog driver to align watchdog with tbtt if possible */
+-			wlc_watchdog_upd(wlc, PS_ALLOWED(wlc));
+-		} else
+-			bcmerror = -EBADE;
+-		break;
+-#endif				/* SUPPORT_PS */
+-
+-#ifdef SUPPORT_PS
+-#ifdef BCMDBG
+-	case WLC_GET_WAKE:
+-		if (AP_ENAB(wlc->pub)) {
+-			bcmerror = -BCME_NOTSTA;
+-			break;
+-		}
+-		*pval = wlc->wake;
+-		break;
+-
+-	case WLC_SET_WAKE:
+-		if (AP_ENAB(wlc->pub)) {
+-			bcmerror = -BCME_NOTSTA;
+-			break;
+-		}
+-
+-		wlc->wake = val ? true : false;
+-
+-		/* if down, we're done */
+-		if (!wlc->pub->up)
+-			break;
+-
+-		/* apply to the mac */
+-		wlc_set_ps_ctrl(wlc);
+-		break;
+-#endif				/* BCMDBG */
+-#endif				/* SUPPORT_PS */
+-
+-	case WLC_GET_REVINFO:
+-		bcmerror = wlc_get_revision_info(wlc, arg, (uint) len);
+-		break;
+-
+-	case WLC_GET_AP:
+-		*pval = (int)AP_ENAB(wlc->pub);
+-		break;
+-
+-	case WLC_GET_ATIM:
+-		if (bsscfg->associated)
+-			*pval = (int)current_bss->atim_window;
+-		else
+-			*pval = (int)wlc->default_bss->atim_window;
+-		break;
+-
+-	case WLC_SET_ATIM:
+-		wlc->default_bss->atim_window = (u32) val;
+-		break;
+-
+-#ifdef SUPPORT_HWKEY
+-	case WLC_GET_WSEC:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_SET_WSEC:
+-		bcmerror =
+-		    wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET,
+-				 wlcif);
+-		break;
+-
+-	case WLC_GET_WPA_AUTH:
+-		*pval = (int)bsscfg->WPA_auth;
+-		break;
+-
+-	case WLC_SET_WPA_AUTH:
+-		/* change of WPA_Auth modifies the PS_ALLOWED state */
+-		if (BSSCFG_STA(bsscfg)) {
+-			bsscfg->WPA_auth = (u16) val;
+-		} else
+-			bsscfg->WPA_auth = (u16) val;
+-		break;
+-#endif				/* SUPPORT_HWKEY */
+-
+-	case WLC_GET_BANDLIST:
+-		/* count of number of bands, followed by each band type */
+-		*pval++ = NBANDS(wlc);
+-		*pval++ = wlc->band->bandtype;
+-		if (NBANDS(wlc) > 1)
+-			*pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype;
+-		break;
+-
+-	case WLC_GET_BAND:
+-		*pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO;
+-		break;
+-
+-	case WLC_GET_PHYLIST:
+-		{
+-			unsigned char *cp = arg;
+-			if (len < 3) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-
+-			if (WLCISNPHY(wlc->band)) {
+-				*cp++ = 'n';
+-			} else if (WLCISLCNPHY(wlc->band)) {
+-				*cp++ = 'c';
+-			} else if (WLCISSSLPNPHY(wlc->band)) {
+-				*cp++ = 's';
+-			}
+-			*cp = '\0';
+-			break;
+-		}
+-
+-	case WLC_GET_SHORTSLOT:
+-		*pval = wlc->shortslot;
+-		break;
+-
+-	case WLC_GET_SHORTSLOT_OVERRIDE:
+-		*pval = wlc->shortslot_override;
+-		break;
+-
+-	case WLC_SET_SHORTSLOT_OVERRIDE:
+-		if ((val != WLC_SHORTSLOT_AUTO) &&
+-		    (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc->shortslot_override = (s8) val;
+-
+-		/* shortslot is an 11g feature, so no more work if we are
+-		 * currently on the 5G band
+-		 */
+-		if (BAND_5G(wlc->band->bandtype))
+-			break;
+-
+-		if (wlc->pub->up && wlc->pub->associated) {
+-			/* let watchdog or beacon processing update shortslot */
+-		} else if (wlc->pub->up) {
+-			/* unassociated shortslot is off */
+-			wlc_switch_shortslot(wlc, false);
+-		} else {
+-			/* driver is down, so just update the wlc_info value */
+-			if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) {
+-				wlc->shortslot = false;
+-			} else {
+-				wlc->shortslot =
+-				    (wlc->shortslot_override ==
+-				     WLC_SHORTSLOT_ON);
+-			}
+-		}
+-
+-		break;
+-
+-	case WLC_GET_LEGACY_ERP:
+-		*pval = wlc->include_legacy_erp;
+-		break;
+-
+-	case WLC_SET_LEGACY_ERP:
+-		if (wlc->include_legacy_erp == bool_val)
+-			break;
+-
+-		wlc->include_legacy_erp = bool_val;
+-
+-		if (AP_ENAB(wlc->pub) && wlc->clk) {
+-			wlc_update_beacon(wlc);
+-			wlc_update_probe_resp(wlc, true);
+-		}
+-		break;
+-
+-	case WLC_GET_GMODE:
+-		if (wlc->band->bandtype == WLC_BAND_2G)
+-			*pval = wlc->band->gmode;
+-		else if (NBANDS(wlc) > 1)
+-			*pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode;
+-		break;
+-
+-	case WLC_SET_GMODE:
+-		if (!wlc->pub->associated)
+-			bcmerror = wlc_set_gmode(wlc, (u8) val, true);
+-		else {
+-			bcmerror = -EISCONN;
+-			break;
+-		}
+-		break;
+-
+-	case WLC_GET_GMODE_PROTECTION:
+-		*pval = wlc->protection->_g;
+-		break;
+-
+-	case WLC_GET_PROTECTION_CONTROL:
+-		*pval = wlc->protection->overlap;
+-		break;
+-
+-	case WLC_SET_PROTECTION_CONTROL:
+-		if ((val != WLC_PROTECTION_CTL_OFF) &&
+-		    (val != WLC_PROTECTION_CTL_LOCAL) &&
+-		    (val != WLC_PROTECTION_CTL_OVERLAP)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val);
+-
+-		/* Current g_protection will sync up to the specified control alg in watchdog
+-		 * if the driver is up and associated.
+-		 * If the driver is down or not associated, the control setting has no effect.
+-		 */
+-		break;
+-
+-	case WLC_GET_GMODE_PROTECTION_OVERRIDE:
+-		*pval = wlc->protection->g_override;
+-		break;
+-
+-	case WLC_SET_GMODE_PROTECTION_OVERRIDE:
+-		if ((val != WLC_PROTECTION_AUTO) &&
+-		    (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) {
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-
+-		wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val);
+-
+-		break;
+-
+-	case WLC_SET_SUP_RATESET_OVERRIDE:{
+-			wlc_rateset_t rs, new;
+-
+-			/* copyin */
+-			if (len < (int)sizeof(wlc_rateset_t)) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-			memcpy(&rs, arg, sizeof(wlc_rateset_t));
+-
+-			/* check for bad count value */
+-			if (rs.count > WLC_NUMRATES) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* this command is only appropriate for gmode operation */
+-			if (!(wlc->band->gmode ||
+-			      ((NBANDS(wlc) > 1)
+-			       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+-				/* gmode only command when not in gmode */
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* check for an empty rateset to clear the override */
+-			if (rs.count == 0) {
+-				memset(&wlc->sup_rates_override, 0,
+-				      sizeof(wlc_rateset_t));
+-				break;
+-			}
+-
+-			/*
+-			 * validate rateset by comparing pre and
+-			 * post sorted against 11g hw rates
+-			 */
+-			wlc_rateset_filter(&rs, &new, false,
+-					   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+-					   BSS_N_ENAB(wlc, bsscfg));
+-			wlc_rate_hwrs_filter_sort_validate(&new,
+-							   &cck_ofdm_rates,
+-							   false,
+-							   wlc->stf->txstreams);
+-			if (rs.count != new.count) {
+-				bcmerror = -EINVAL;
+-				break;
+-			}
+-
+-			/* apply new rateset to the override */
+-			memcpy(&wlc->sup_rates_override, &new,
+-			      sizeof(wlc_rateset_t));
+-
+-			/* update bcn and probe resp if needed */
+-			if (wlc->pub->up && AP_ENAB(wlc->pub)
+-			    && wlc->pub->associated) {
+-				wlc_update_beacon(wlc);
+-				wlc_update_probe_resp(wlc, true);
+-			}
+-			break;
+-		}
+-
+-	case WLC_GET_SUP_RATESET_OVERRIDE:
+-		/* this command is only appropriate for gmode operation */
+-		if (!(wlc->band->gmode ||
+-		      ((NBANDS(wlc) > 1)
+-		       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
+-			/* gmode only command when not in gmode */
+-			bcmerror = -EINVAL;
+-			break;
+-		}
+-		if (len < (int)sizeof(wlc_rateset_t)) {
+-			bcmerror = -EOVERFLOW;
+-			break;
+-		}
+-		memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t));
+-
+-		break;
+-
+-	case WLC_GET_PRB_RESP_TIMEOUT:
+-		*pval = wlc->prb_resp_timeout;
+-		break;
+-
+-	case WLC_SET_PRB_RESP_TIMEOUT:
+-		if (wlc->pub->up) {
+-			bcmerror = -EISCONN;
+-			break;
+-		}
+-		if (val < 0 || val >= 0xFFFF) {
+-			bcmerror = -EINVAL;	/* bad value */
+-			break;
+-		}
+-		wlc->prb_resp_timeout = (u16) val;
+-		break;
+-
+-	case WLC_GET_KEY_PRIMARY:{
+-			wsec_key_t *key;
+-
+-			/* treat the 'val' parm as the key id */
+-			key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+-			if (key != NULL) {
+-				*pval = key->id == val ? true : false;
+-			} else {
+-				bcmerror = -EINVAL;
+-			}
+-			break;
+-		}
+-
+-	case WLC_SET_KEY_PRIMARY:{
+-			wsec_key_t *key, *old_key;
+-
+-			bcmerror = -EINVAL;
+-
+-			/* treat the 'val' parm as the key id */
+-			for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
+-				key = bsscfg->bss_def_keys[i];
+-				if (key != NULL && key->id == val) {
+-					old_key = WSEC_BSS_DEFAULT_KEY(bsscfg);
+-					if (old_key != NULL)
+-						old_key->flags &=
+-						    ~WSEC_PRIMARY_KEY;
+-					key->flags |= WSEC_PRIMARY_KEY;
+-					bsscfg->wsec_index = i;
+-					bcmerror = 0;
+-				}
+-			}
+-			break;
+-		}
+-
+-#ifdef BCMDBG
+-	case WLC_INIT:
+-		wl_init(wlc->wl);
+-		break;
+-#endif
+-
+-	case WLC_SET_VAR:
+-	case WLC_GET_VAR:{
+-			char *name;
+-			/* validate the name value */
+-			name = (char *)arg;
+-			for (i = 0; i < (uint) len && *name != '\0';
+-			     i++, name++)
+-				;
+-
+-			if (i == (uint) len) {
+-				bcmerror = -EOVERFLOW;
+-				break;
+-			}
+-			i++;	/* include the null in the string length */
+-
+-			if (cmd == WLC_GET_VAR) {
+-				bcmerror =
+-				    wlc_iovar_op(wlc, arg,
+-						 (void *)((s8 *) arg + i),
+-						 len - i, arg, len, IOV_GET,
+-						 wlcif);
+-			} else
+-				bcmerror =
+-				    wlc_iovar_op(wlc, arg, NULL, 0,
+-						 (void *)((s8 *) arg + i),
+-						 len - i, IOV_SET, wlcif);
+-
+-			break;
+-		}
+-
+-	case WLC_SET_WSEC_PMK:
+-		bcmerror = -ENOTSUPP;
+-		break;
+-
+-#if defined(BCMDBG)
+-	case WLC_CURRENT_PWR:
+-		if (!wlc->pub->up)
+-			bcmerror = -ENOLINK;
+-		else
+-			bcmerror = wlc_get_current_txpwr(wlc, arg, len);
+-		break;
+-#endif
+-
+-	case WLC_LAST:
+-		wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__);
+-	}
+- done:
+-
+-	if (bcmerror)
+-		wlc->pub->bcmerror = bcmerror;
+-
+-	return bcmerror;
+-}
+-
+-#if defined(BCMDBG)
+-/* consolidated register access ioctl error checking */
+-int wlc_iocregchk(struct wlc_info *wlc, uint band)
+-{
+-	/* if band is specified, it must be the current band */
+-	if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype))
+-		return -EINVAL;
+-
+-	/* if multiband and band is not specified, band must be locked */
+-	if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc))
+-		return -ENOMEDIUM;
+-
+-	/* must have core clocks */
+-	if (!wlc->clk)
+-		return -EIO;
+-
+-	return 0;
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-/* Look up the given var name in the given table */
+-static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table,
+-					   const char *name)
+-{
+-	const bcm_iovar_t *vi;
+-	const char *lookup_name;
+-
+-	/* skip any ':' delimited option prefixes */
+-	lookup_name = strrchr(name, ':');
+-	if (lookup_name != NULL)
+-		lookup_name++;
+-	else
+-		lookup_name = name;
+-
+-	for (vi = table; vi->name; vi++) {
+-		if (!strcmp(vi->name, lookup_name))
+-			return vi;
+-	}
+-	/* ran to end of table */
+-
+-	return NULL;		/* var name not found */
+-}
+-
+-/* simplified integer get interface for common WLC_GET_VAR ioctl handler */
+-int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg)
+-{
+-	return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET,
+-			    NULL);
+-}
+-
+-/* simplified integer set interface for common WLC_SET_VAR ioctl handler */
+-int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg)
+-{
+-	return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg),
+-			    IOV_SET, NULL);
+-}
+-
+-/*
+- * register iovar table, watchdog and down handlers.
+- * calling function must keep 'iovars' until wlc_module_unregister is called.
+- * 'iovar' must have the last entry's name field being NULL as terminator.
+- */
+-int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars,
+-			const char *name, void *hdl, iovar_fn_t i_fn,
+-			watchdog_fn_t w_fn, down_fn_t d_fn)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int i;
+-
+-	/* find an empty entry and just add, no duplication check! */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (wlc->modulecb[i].name[0] == '\0') {
+-			strncpy(wlc->modulecb[i].name, name,
+-				sizeof(wlc->modulecb[i].name) - 1);
+-			wlc->modulecb[i].iovars = iovars;
+-			wlc->modulecb[i].hdl = hdl;
+-			wlc->modulecb[i].iovar_fn = i_fn;
+-			wlc->modulecb[i].watchdog_fn = w_fn;
+-			wlc->modulecb[i].down_fn = d_fn;
+-			return 0;
+-		}
+-	}
+-
+-	return -ENOSR;
+-}
+-
+-/* unregister module callbacks */
+-int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int i;
+-
+-	if (wlc == NULL)
+-		return -ENODATA;
+-
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (!strcmp(wlc->modulecb[i].name, name) &&
+-		    (wlc->modulecb[i].hdl == hdl)) {
+-			memset(&wlc->modulecb[i], 0, sizeof(struct modulecb));
+-			return 0;
+-		}
+-	}
+-
+-	/* table not found! */
+-	return -ENODATA;
+-}
+-
+-/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
+-static void wlc_wme_retries_write(struct wlc_info *wlc)
+-{
+-	int ac;
+-
+-	/* Need clock to do this */
+-	if (!wlc->clk)
+-		return;
+-
+-	for (ac = 0; ac < AC_COUNT; ac++) {
+-		wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]);
+-	}
+-}
+-
+-/* Get or set an iovar.  The params/p_len pair specifies any additional
+- * qualifying parameters (e.g. an "element index") for a get, while the
+- * arg/len pair is the buffer for the value to be set or retrieved.
+- * Operation (get/set) is specified by the last argument.
+- * interface context provided by wlcif
+- *
+- * All pointers may point into the same buffer.
+- */
+-int
+-wlc_iovar_op(struct wlc_info *wlc, const char *name,
+-	     void *params, int p_len, void *arg, int len,
+-	     bool set, struct wlc_if *wlcif)
+-{
+-	int err = 0;
+-	int val_size;
+-	const bcm_iovar_t *vi = NULL;
+-	u32 actionid;
+-	int i;
+-
+-	if (!set && (len == sizeof(int)) &&
+-	    !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s unaligned get ptr for %s\n",
+-			  wlc->pub->unit, __func__, name);
+-		return -ENOTSUPP;
+-	}
+-
+-	/* find the given iovar name */
+-	for (i = 0; i < WLC_MAXMODULES; i++) {
+-		if (!wlc->modulecb[i].iovars)
+-			continue;
+-		vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name);
+-		if (vi)
+-			break;
+-	}
+-	/* iovar name not found */
+-	if (i >= WLC_MAXMODULES) {
+-		return -ENOTSUPP;
+-	}
+-
+-	/* set up 'params' pointer in case this is a set command so that
+-	 * the convenience int and bool code can be common to set and get
+-	 */
+-	if (params == NULL) {
+-		params = arg;
+-		p_len = len;
+-	}
+-
+-	if (vi->type == IOVT_VOID)
+-		val_size = 0;
+-	else if (vi->type == IOVT_BUFFER)
+-		val_size = len;
+-	else
+-		/* all other types are integer sized */
+-		val_size = sizeof(int);
+-
+-	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+-
+-	/* Do the actual parameter implementation */
+-	err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid,
+-					name, params, p_len, arg, len, val_size,
+-					wlcif);
+-	return err;
+-}
+-
+-int
+-wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len,
+-		bool set)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
+-	int err = 0;
+-	s32 int_val = 0;
+-
+-	/* check generic condition flags */
+-	if (set) {
+-		if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) ||
+-		    ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) {
+-			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
+-		} else if ((vi->flags & IOVF_SET_BAND)
+-			   && IS_MBAND_UNLOCKED(wlc)) {
+-			err = -ENOMEDIUM;
+-		} else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) {
+-			err = -EIO;
+-		}
+-	} else {
+-		if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) ||
+-		    ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) {
+-			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
+-		} else if ((vi->flags & IOVF_GET_BAND)
+-			   && IS_MBAND_UNLOCKED(wlc)) {
+-			err = -ENOMEDIUM;
+-		} else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) {
+-			err = -EIO;
+-		}
+-	}
+-
+-	if (err)
+-		goto exit;
+-
+-	/* length check on io buf */
+-	err = bcm_iovar_lencheck(vi, arg, len, set);
+-	if (err)
+-		goto exit;
+-
+-	/* On set, check value ranges for integer types */
+-	if (set) {
+-		switch (vi->type) {
+-		case IOVT_BOOL:
+-		case IOVT_INT8:
+-		case IOVT_INT16:
+-		case IOVT_INT32:
+-		case IOVT_UINT8:
+-		case IOVT_UINT16:
+-		case IOVT_UINT32:
+-			memcpy(&int_val, arg, sizeof(int));
+-			err = wlc_iovar_rangecheck(wlc, int_val, vi);
+-			break;
+-		}
+-	}
+- exit:
+-	return err;
+-}
+-
+-/* handler for iovar table wlc_iovars */
+-/*
+- * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each
+- * iovar case, the switch statement maps the iovar id into separate get
+- * and set values.  If you add a new iovar to the switch you MUST use
+- * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with
+- * another case.
+- * Please use params for additional qualifying parameters.
+- */
+-int
+-wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid,
+-	    const char *name, void *params, uint p_len, void *arg, int len,
+-	    int val_size, struct wlc_if *wlcif)
+-{
+-	struct wlc_info *wlc = hdl;
+-	struct wlc_bsscfg *bsscfg;
+-	int err = 0;
+-	s32 int_val = 0;
+-	s32 int_val2 = 0;
+-	s32 *ret_int_ptr;
+-	bool bool_val;
+-	bool bool_val2;
+-	wlc_bss_info_t *current_bss;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	bsscfg = NULL;
+-	current_bss = NULL;
+-
+-	err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid));
+-	if (err != 0)
+-		return err;
+-
+-	/* convenience int and bool vals for first 8 bytes of buffer */
+-	if (p_len >= (int)sizeof(int_val))
+-		memcpy(&int_val, params, sizeof(int_val));
+-
+-	if (p_len >= (int)sizeof(int_val) * 2)
+-		memcpy(&int_val2,
+-		       (void *)((unsigned long)params + sizeof(int_val)),
+-		       sizeof(int_val));
+-
+-	/* convenience int ptr for 4-byte gets (requires int aligned arg) */
+-	ret_int_ptr = (s32 *) arg;
+-
+-	bool_val = (int_val != 0) ? true : false;
+-	bool_val2 = (int_val2 != 0) ? true : false;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: id %d\n", wlc->pub->unit, IOV_ID(actionid));
+-	/* Do the actual parameter implementation */
+-	switch (actionid) {
+-	case IOV_SVAL(IOV_RTSTHRESH):
+-		wlc->RTSThresh = int_val;
+-		break;
+-
+-	case IOV_GVAL(IOV_QTXPOWER):{
+-			uint qdbm;
+-			bool override;
+-
+-			err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
+-				&override);
+-			if (err != 0)
+-				return err;
+-
+-			/* Return qdbm units */
+-			*ret_int_ptr =
+-			    qdbm | (override ? WL_TXPWR_OVERRIDE : 0);
+-			break;
+-		}
+-
+-		/* As long as override is false, this only sets the *user* targets.
+-		   User can twiddle this all he wants with no harm.
+-		   wlc_phy_txpower_set() explicitly sets override to false if
+-		   not internal or test.
+-		 */
+-	case IOV_SVAL(IOV_QTXPOWER):{
+-			u8 qdbm;
+-			bool override;
+-
+-			/* Remove override bit and clip to max qdbm value */
+-			qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff);
+-			/* Extract override setting */
+-			override = (int_val & WL_TXPWR_OVERRIDE) ? true : false;
+-			err =
+-			    wlc_phy_txpower_set(wlc->band->pi, qdbm, override);
+-			break;
+-		}
+-
+-	case IOV_GVAL(IOV_MPC):
+-		*ret_int_ptr = (s32) wlc->mpc;
+-		break;
+-
+-	case IOV_SVAL(IOV_MPC):
+-		wlc->mpc = bool_val;
+-		wlc_radio_mpc_upd(wlc);
+-
+-		break;
+-
+-	case IOV_GVAL(IOV_BCN_LI_BCN):
+-		*ret_int_ptr = wlc->bcn_li_bcn;
+-		break;
+-
+-	case IOV_SVAL(IOV_BCN_LI_BCN):
+-		wlc->bcn_li_bcn = (u8) int_val;
+-		if (wlc->pub->up)
+-			wlc_bcn_li_upd(wlc);
+-		break;
+-
+-	default:
+-		wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n",
+-			  wlc->pub->unit, __func__);
+-		err = -ENOTSUPP;
+-		break;
+-	}
+-
+-	goto exit;		/* avoid unused label warning */
+-
+- exit:
+-	return err;
+-}
+-
+-static int
+-wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi)
+-{
+-	int err = 0;
+-	u32 min_val = 0;
+-	u32 max_val = 0;
+-
+-	/* Only ranged integers are checked */
+-	switch (vi->type) {
+-	case IOVT_INT32:
+-		max_val |= 0x7fffffff;
+-		/* fall through */
+-	case IOVT_INT16:
+-		max_val |= 0x00007fff;
+-		/* fall through */
+-	case IOVT_INT8:
+-		max_val |= 0x0000007f;
+-		min_val = ~max_val;
+-		if (vi->flags & IOVF_NTRL)
+-			min_val = 1;
+-		else if (vi->flags & IOVF_WHL)
+-			min_val = 0;
+-		/* Signed values are checked against max_val and min_val */
+-		if ((s32) val < (s32) min_val
+-		    || (s32) val > (s32) max_val)
+-			err = -EINVAL;
+-		break;
+-
+-	case IOVT_UINT32:
+-		max_val |= 0xffffffff;
+-		/* fall through */
+-	case IOVT_UINT16:
+-		max_val |= 0x0000ffff;
+-		/* fall through */
+-	case IOVT_UINT8:
+-		max_val |= 0x000000ff;
+-		if (vi->flags & IOVF_NTRL)
+-			min_val = 1;
+-		if ((val < min_val) || (val > max_val))
+-			err = -EINVAL;
+-		break;
+-	}
+-
+-	return err;
+-}
+-
+-#ifdef BCMDBG
+-static const char *supr_reason[] = {
+-	"None", "PMQ Entry", "Flush request",
+-	"Previous frag failure", "Channel mismatch",
+-	"Lifetime Expiry", "Underflow"
+-};
+-
+-static void wlc_print_txs_status(u16 s)
+-{
+-	printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
+-	       (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
+-	printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
+-	       (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
+-	printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
+-	       ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
+-	printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
+-	       ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
+-	printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
+-	       (s & TX_STATUS_AMPDU) ? 1 : 0);
+-	printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
+-	       ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
+-	       supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
+-	printk(KERN_DEBUG "    [1]  %d  acked\n",
+-	       ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
+-}
+-#endif				/* BCMDBG */
+-
+-void wlc_print_txstatus(tx_status_t *txs)
+-{
+-#if defined(BCMDBG)
+-	u16 s = txs->status;
+-	u16 ackphyrxsh = txs->ackphyrxsh;
+-
+-	printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
+-
+-	printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
+-	printk(KERN_DEBUG "TxStatus: %04x", s);
+-	printk(KERN_DEBUG "\n");
+-
+-	wlc_print_txs_status(s);
+-
+-	printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
+-	printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
+-	printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
+-	printk(KERN_DEBUG "RxAckRSSI: %04x ",
+-	       (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
+-	printk(KERN_DEBUG "RxAckSQ: %04x",
+-	       (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
+-	printk(KERN_DEBUG "\n");
+-#endif				/* defined(BCMDBG) */
+-}
+-
+-void wlc_statsupd(struct wlc_info *wlc)
+-{
+-	int i;
+-	macstat_t macstats;
+-#ifdef BCMDBG
+-	u16 delta;
+-	u16 rxf0ovfl;
+-	u16 txfunfl[NFIFO];
+-#endif				/* BCMDBG */
+-
+-	/* if driver down, make no sense to update stats */
+-	if (!wlc->pub->up)
+-		return;
+-
+-#ifdef BCMDBG
+-	/* save last rx fifo 0 overflow count */
+-	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
+-
+-	/* save last tx fifo  underflow count */
+-	for (i = 0; i < NFIFO; i++)
+-		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
+-#endif				/* BCMDBG */
+-
+-	/* Read mac stats from contiguous shared memory */
+-	wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
+-			      &macstats, sizeof(macstat_t));
+-
+-#ifdef BCMDBG
+-	/* check for rx fifo 0 overflow */
+-	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
+-	if (delta)
+-		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
+-			  wlc->pub->unit, delta);
+-
+-	/* check for tx fifo underflows */
+-	for (i = 0; i < NFIFO; i++) {
+-		delta =
+-		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
+-			      txfunfl[i]);
+-		if (delta)
+-			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
+-				  "\n", wlc->pub->unit, delta, i);
+-	}
+-#endif				/* BCMDBG */
+-
+-	/* merge counters from dma module */
+-	for (i = 0; i < NFIFO; i++) {
+-		if (wlc->hw->di[i]) {
+-			dma_counterreset(wlc->hw->di[i]);
+-		}
+-	}
+-}
+-
+-bool wlc_chipmatch(u16 vendor, u16 device)
+-{
+-	if (vendor != PCI_VENDOR_ID_BROADCOM) {
+-		pr_err("wlc_chipmatch: unknown vendor id %04x\n", vendor);
+-		return false;
+-	}
+-
+-	if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID))
+-		return true;
+-
+-	if (device == BCM4313_D11N2G_ID)
+-		return true;
+-	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
+-		return true;
+-
+-	pr_err("wlc_chipmatch: unknown device id %04x\n", device);
+-	return false;
+-}
+-
+-#if defined(BCMDBG)
+-void wlc_print_txdesc(d11txh_t *txh)
+-{
+-	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
+-	u16 mtch = le16_to_cpu(txh->MacTxControlHigh);
+-	u16 mfc = le16_to_cpu(txh->MacFrameControl);
+-	u16 tfest = le16_to_cpu(txh->TxFesTimeNormal);
+-	u16 ptcw = le16_to_cpu(txh->PhyTxControlWord);
+-	u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1);
+-	u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr);
+-	u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts);
+-	u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts);
+-	u16 mainrates = le16_to_cpu(txh->MainRates);
+-	u16 xtraft = le16_to_cpu(txh->XtraFrameTypes);
+-	u8 *iv = txh->IV;
+-	u8 *ra = txh->TxFrameRA;
+-	u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback);
+-	u8 *rtspfb = txh->RTSPLCPFallback;
+-	u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback);
+-	u8 *fragpfb = txh->FragPLCPFallback;
+-	u16 fragdfb = le16_to_cpu(txh->FragDurFallback);
+-	u16 mmodelen = le16_to_cpu(txh->MModeLen);
+-	u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen);
+-	u16 tfid = le16_to_cpu(txh->TxFrameID);
+-	u16 txs = le16_to_cpu(txh->TxStatus);
+-	u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus);
+-	u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT);
+-	u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR);
+-	u16 mmbyte = le16_to_cpu(txh->MinMBytes);
+-
+-	u8 *rtsph = txh->RTSPhyHeader;
+-	struct ieee80211_rts rts = txh->rts_frame;
+-	char hexbuf[256];
+-
+-	/* add plcp header along with txh descriptor */
+-	printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
+-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+-			     txh, sizeof(d11txh_t) + 48);
+-
+-	printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
+-	printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
+-	printk(KERN_DEBUG "FC: %04x ", mfc);
+-	printk(KERN_DEBUG "FES Time: %04x\n", tfest);
+-	printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
+-	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
+-	printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
+-	printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
+-	printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
+-	printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
+-	printk(KERN_DEBUG "MainRates: %04x ", mainrates);
+-	printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
+-	printk(KERN_DEBUG "\n");
+-
+-	bcm_format_hex(hexbuf, iv, sizeof(txh->IV));
+-	printk(KERN_DEBUG "SecIV:       %s\n", hexbuf);
+-	bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA));
+-	printk(KERN_DEBUG "RA:          %s\n", hexbuf);
+-
+-	printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
+-	bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback));
+-	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
+-	printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
+-	bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback));
+-	printk(KERN_DEBUG "PLCP: %s ", hexbuf);
+-	printk(KERN_DEBUG "DUR: %04x", fragdfb);
+-	printk(KERN_DEBUG "\n");
+-
+-	printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
+-	printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
+-
+-	printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
+-	printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
+-
+-	printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
+-	printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
+-	printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
+-	printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
+-
+-	bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader));
+-	printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf);
+-	bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame));
+-	printk(KERN_DEBUG "RTS Frame: %s", hexbuf);
+-	printk(KERN_DEBUG "\n");
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-#if defined(BCMDBG)
+-void wlc_print_rxh(d11rxhdr_t *rxh)
+-{
+-	u16 len = rxh->RxFrameSize;
+-	u16 phystatus_0 = rxh->PhyRxStatus_0;
+-	u16 phystatus_1 = rxh->PhyRxStatus_1;
+-	u16 phystatus_2 = rxh->PhyRxStatus_2;
+-	u16 phystatus_3 = rxh->PhyRxStatus_3;
+-	u16 macstatus1 = rxh->RxStatus1;
+-	u16 macstatus2 = rxh->RxStatus2;
+-	char flagstr[64];
+-	char lenbuf[20];
+-	static const bcm_bit_desc_t macstat_flags[] = {
+-		{RXS_FCSERR, "FCSErr"},
+-		{RXS_RESPFRAMETX, "Reply"},
+-		{RXS_PBPRES, "PADDING"},
+-		{RXS_DECATMPT, "DeCr"},
+-		{RXS_DECERR, "DeCrErr"},
+-		{RXS_BCNSENT, "Bcn"},
+-		{0, NULL}
+-	};
+-
+-	printk(KERN_DEBUG "Raw RxDesc:\n");
+-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(d11rxhdr_t));
+-
+-	bcm_format_flags(macstat_flags, macstatus1, flagstr, 64);
+-
+-	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
+-
+-	printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
+-	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
+-	printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
+-	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
+-	printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
+-	printk(KERN_DEBUG "RXMACaggtype:    %x\n",
+-	       (macstatus2 & RXS_AGGTYPE_MASK));
+-	printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-#if defined(BCMDBG)
+-int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len)
+-{
+-	uint i, c;
+-	char *p = buf;
+-	char *endp = buf + SSID_FMT_BUF_LEN;
+-
+-	if (ssid_len > IEEE80211_MAX_SSID_LEN)
+-		ssid_len = IEEE80211_MAX_SSID_LEN;
+-
+-	for (i = 0; i < ssid_len; i++) {
+-		c = (uint) ssid[i];
+-		if (c == '\\') {
+-			*p++ = '\\';
+-			*p++ = '\\';
+-		} else if (isprint((unsigned char) c)) {
+-			*p++ = (char)c;
+-		} else {
+-			p += snprintf(p, (endp - p), "\\x%02X", c);
+-		}
+-	}
+-	*p = '\0';
+-	return (int)(p - buf);
+-}
+-#endif				/* defined(BCMDBG) */
+-
+-static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate)
+-{
+-	return wlc_bmac_rate_shm_offset(wlc->hw, rate);
+-}
+-
+-/* Callback for device removed */
+-
+-/*
+- * Attempts to queue a packet onto a multiple-precedence queue,
+- * if necessary evicting a lower precedence packet from the queue.
+- *
+- * 'prec' is the precedence number that has already been mapped
+- * from the packet priority.
+- *
+- * Returns true if packet consumed (queued), false if not.
+- */
+-bool
+-wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec)
+-{
+-	return wlc_prec_enq_head(wlc, q, pkt, prec, false);
+-}
+-
+-bool
+-wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt,
+-		  int prec, bool head)
+-{
+-	struct sk_buff *p;
+-	int eprec = -1;		/* precedence to evict from */
+-
+-	/* Determine precedence from which to evict packet, if any */
+-	if (pktq_pfull(q, prec))
+-		eprec = prec;
+-	else if (pktq_full(q)) {
+-		p = bcm_pktq_peek_tail(q, &eprec);
+-		if (eprec > prec) {
+-			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
+-				  "\n", __func__, eprec, prec);
+-			return false;
+-		}
+-	}
+-
+-	/* Evict if needed */
+-	if (eprec >= 0) {
+-		bool discard_oldest;
+-
+-		discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
+-
+-		/* Refuse newer packet unless configured to discard oldest */
+-		if (eprec == prec && !discard_oldest) {
+-			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
+-				  "\n", __func__, prec);
+-			return false;
+-		}
+-
+-		/* Evict packet according to discard policy */
+-		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+-			bcm_pktq_pdeq_tail(q, eprec);
+-		bcm_pkt_buf_free_skb(p);
+-	}
+-
+-	/* Enqueue */
+-	if (head)
+-		p = bcm_pktq_penq_head(q, prec, pkt);
+-	else
+-		p = bcm_pktq_penq(q, prec, pkt);
+-
+-	return true;
+-}
+-
+-void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
+-			     uint prec)
+-{
+-	struct wlc_info *wlc = (struct wlc_info *) ctx;
+-	struct wlc_txq_info *qi = wlc->pkt_queue;	/* Check me */
+-	struct pktq *q = &qi->q;
+-	int prio;
+-
+-	prio = sdu->priority;
+-
+-	if (!wlc_prec_enq(wlc, q, sdu, prec)) {
+-		if (!EDCF_ENAB(wlc->pub)
+-		    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_txq_enq: txq overflow"
+-				  "\n", wlc->pub->unit);
+-
+-		/*
+-		 * XXX we might hit this condtion in case
+-		 * packet flooding from mac80211 stack
+-		 */
+-		bcm_pkt_buf_free_skb(sdu);
+-	}
+-
+-	/* Check if flow control needs to be turned on after enqueuing the packet
+-	 *   Don't turn on flow control if EDCF is enabled. Driver would make the decision on what
+-	 *   to drop instead of relying on stack to make the right decision
+-	 */
+-	if (!EDCF_ENAB(wlc->pub)
+-	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+-		if (pktq_len(q) >= wlc->pub->tunables->datahiwat) {
+-			wlc_txflowcontrol(wlc, qi, ON, ALLPRIO);
+-		}
+-	} else if (wlc->pub->_priofc) {
+-		if (pktq_plen(q, wlc_prio2prec_map[prio]) >=
+-		    wlc->pub->tunables->datahiwat) {
+-			wlc_txflowcontrol(wlc, qi, ON, prio);
+-		}
+-	}
+-}
+-
+-bool
+-wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
+-		     struct ieee80211_hw *hw)
+-{
+-	u8 prio;
+-	uint fifo;
+-	void *pkt;
+-	struct scb *scb = &global_scb;
+-	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
+-
+-	/* 802.11 standard requires management traffic to go at highest priority */
+-	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
+-		MAXPRIO;
+-	fifo = prio2fifo[prio];
+-	pkt = sdu;
+-	if (unlikely
+-	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
+-		return -EINVAL;
+-	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
+-	wlc_send_q(wlc);
+-	return 0;
+-}
+-
+-void wlc_send_q(struct wlc_info *wlc)
+-{
+-	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
+-	int prec;
+-	u16 prec_map;
+-	int err = 0, i, count;
+-	uint fifo;
+-	struct wlc_txq_info *qi = wlc->pkt_queue;
+-	struct pktq *q = &qi->q;
+-	struct ieee80211_tx_info *tx_info;
+-
+-	if (in_send_q)
+-		return;
+-	else
+-		in_send_q = true;
+-
+-	prec_map = wlc->tx_prec_map;
+-
+-	/* Send all the enq'd pkts that we can.
+-	 * Dequeue packets with precedence with empty HW fifo only
+-	 */
+-	while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) {
+-		tx_info = IEEE80211_SKB_CB(pkt[0]);
+-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-			err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec);
+-		} else {
+-			count = 1;
+-			err = wlc_prep_pdu(wlc, pkt[0], &fifo);
+-			if (!err) {
+-				for (i = 0; i < count; i++) {
+-					wlc_txfifo(wlc, fifo, pkt[i], true, 1);
+-				}
+-			}
+-		}
+-
+-		if (err == -EBUSY) {
+-			bcm_pktq_penq_head(q, prec, pkt[0]);
+-			/* If send failed due to any other reason than a change in
+-			 * HW FIFO condition, quit. Otherwise, read the new prec_map!
+-			 */
+-			if (prec_map == wlc->tx_prec_map)
+-				break;
+-			prec_map = wlc->tx_prec_map;
+-		}
+-	}
+-
+-	/* Check if flow control needs to be turned off after sending the packet */
+-	if (!EDCF_ENAB(wlc->pub)
+-	    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) {
+-		if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO)
+-		    && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) {
+-			wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO);
+-		}
+-	} else if (wlc->pub->_priofc) {
+-		int prio;
+-		for (prio = MAXPRIO; prio >= 0; prio--) {
+-			if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) &&
+-			    (pktq_plen(q, wlc_prio2prec_map[prio]) <
+-			     wlc->pub->tunables->datahiwat / 2)) {
+-				wlc_txflowcontrol(wlc, qi, OFF, prio);
+-			}
+-		}
+-	}
+-	in_send_q = false;
+-}
+-
+-/*
+- * bcmc_fid_generate:
+- * Generate frame ID for a BCMC packet.  The frag field is not used
+- * for MC frames so is used as part of the sequence number.
+- */
+-static inline u16
+-bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg,
+-		  d11txh_t *txh)
+-{
+-	u16 frameid;
+-
+-	frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK |
+-						  TXFID_QUEUE_MASK);
+-	frameid |=
+-	    (((wlc->
+-	       mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+-	    TX_BCMC_FIFO;
+-
+-	return frameid;
+-}
+-
+-void
+-wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit,
+-	   s8 txpktpend)
+-{
+-	u16 frameid = INVALIDFID;
+-	d11txh_t *txh;
+-
+-	txh = (d11txh_t *) (p->data);
+-
+-	/* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
+-	 * ucode or BSS info as appropriate.
+-	 */
+-	if (fifo == TX_BCMC_FIFO) {
+-		frameid = le16_to_cpu(txh->TxFrameID);
+-
+-	}
+-
+-	if (WLC_WAR16165(wlc))
+-		wlc_war16165(wlc, true);
+-
+-
+-	/* Bump up pending count for if not using rpc. If rpc is used, this will be handled
+-	 * in wlc_bmac_txfifo()
+-	 */
+-	if (commit) {
+-		TXPKTPENDINC(wlc, fifo, txpktpend);
+-		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
+-			 txpktpend, TXPKTPENDGET(wlc, fifo));
+-	}
+-
+-	/* Commit BCMC sequence number in the SHM frame ID location */
+-	if (frameid != INVALIDFID)
+-		BCMCFID(wlc, frameid);
+-
+-	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
+-		wiphy_err(wlc->wiphy, "wlc_txfifo: fatal, toss frames !!!\n");
+-	}
+-}
+-
+-void
+-wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp)
+-{
+-	if (IS_MCS(rspec)) {
+-		wlc_compute_mimo_plcp(rspec, length, plcp);
+-	} else if (IS_OFDM(rspec)) {
+-		wlc_compute_ofdm_plcp(rspec, length, plcp);
+-	} else {
+-		wlc_compute_cck_plcp(wlc, rspec, length, plcp);
+-	}
+-	return;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
+-{
+-	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
+-	plcp[0] = mcs;
+-	if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
+-		plcp[0] |= MIMO_PLCP_40MHZ;
+-	WLC_SET_MIMO_PLCP_LEN(plcp, length);
+-	plcp[3] = RSPEC_MIMOPLCP3(rspec);	/* rspec already holds this byte */
+-	plcp[3] |= 0x7;		/* set smoothing, not sounding ppdu & reserved */
+-	plcp[4] = 0;		/* number of extension spatial streams bit 0 & 1 */
+-	plcp[5] = 0;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void
+-wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
+-{
+-	u8 rate_signal;
+-	u32 tmp = 0;
+-	int rate = RSPEC2RATE(rspec);
+-
+-	/* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
+-	rate_signal = rate_info[rate] & WLC_RATE_MASK;
+-	memset(plcp, 0, D11_PHY_HDR_LEN);
+-	D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal);
+-
+-	tmp = (length & 0xfff) << 5;
+-	plcp[2] |= (tmp >> 16) & 0xff;
+-	plcp[1] |= (tmp >> 8) & 0xff;
+-	plcp[0] |= tmp & 0xff;
+-
+-	return;
+-}
+-
+-/*
+- * Compute PLCP, but only requires actual rate and length of pkt.
+- * Rate is given in the driver standard multiple of 500 kbps.
+- * le is set for 11 Mbps rate if necessary.
+- * Broken out for PRQ.
+- */
+-
+-static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length,
+-			     u8 *plcp)
+-{
+-	u16 usec = 0;
+-	u8 le = 0;
+-
+-	switch (rate_500) {
+-	case WLC_RATE_1M:
+-		usec = length << 3;
+-		break;
+-	case WLC_RATE_2M:
+-		usec = length << 2;
+-		break;
+-	case WLC_RATE_5M5:
+-		usec = (length << 4) / 11;
+-		if ((length << 4) - (usec * 11) > 0)
+-			usec++;
+-		break;
+-	case WLC_RATE_11M:
+-		usec = (length << 3) / 11;
+-		if ((length << 3) - (usec * 11) > 0) {
+-			usec++;
+-			if ((usec * 11) - (length << 3) >= 8)
+-				le = D11B_PLCP_SIGNAL_LE;
+-		}
+-		break;
+-
+-	default:
+-		wiphy_err(wlc->wiphy, "wlc_cck_plcp_set: unsupported rate %d"
+-			  "\n", rate_500);
+-		rate_500 = WLC_RATE_1M;
+-		usec = length << 3;
+-		break;
+-	}
+-	/* PLCP signal byte */
+-	plcp[0] = rate_500 * 5;	/* r (500kbps) * 5 == r (100kbps) */
+-	/* PLCP service byte */
+-	plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED);
+-	/* PLCP length u16, little endian */
+-	plcp[2] = usec & 0xff;
+-	plcp[3] = (usec >> 8) & 0xff;
+-	/* PLCP CRC16 */
+-	plcp[4] = 0;
+-	plcp[5] = 0;
+-}
+-
+-/* Rate: 802.11 rate code, length: PSDU length in octets */
+-static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec,
+-				 uint length, u8 *plcp)
+-{
+-	int rate = RSPEC2RATE(rspec);
+-
+-	wlc_cck_plcp_set(wlc, rate, length, plcp);
+-}
+-
+-/* wlc_compute_frame_dur()
+- *
+- * Calculate the 802.11 MAC header DUR field for MPDU
+- * DUR for a single frame = 1 SIFS + 1 ACK
+- * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time
+- *
+- * rate			MPDU rate in unit of 500kbps
+- * next_frag_len	next MPDU length in bytes
+- * preamble_type	use short/GF or long/MM PLCP header
+- */
+-static u16
+-wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type,
+-		      uint next_frag_len)
+-{
+-	u16 dur, sifs;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	dur = sifs;
+-	dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type);
+-
+-	if (next_frag_len) {
+-		/* Double the current DUR to get 2 SIFS + 2 ACKs */
+-		dur *= 2;
+-		/* add another SIFS and the frag time */
+-		dur += sifs;
+-		dur +=
+-		    (u16) wlc_calc_frame_time(wlc, rate, preamble_type,
+-						 next_frag_len);
+-	}
+-	return dur;
+-}
+-
+-/* wlc_compute_rtscts_dur()
+- *
+- * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame
+- * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK
+- * DUR for CTS-TO-SELF w/ frame    = 2 SIFS         + next frame time + 1 ACK
+- *
+- * cts			cts-to-self or rts/cts
+- * rts_rate		rts or cts rate in unit of 500kbps
+- * rate			next MPDU rate in unit of 500kbps
+- * frame_len		next MPDU frame length in bytes
+- */
+-u16
+-wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate,
+-		       ratespec_t frame_rate, u8 rts_preamble_type,
+-		       u8 frame_preamble_type, uint frame_len, bool ba)
+-{
+-	u16 dur, sifs;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	if (!cts_only) {	/* RTS/CTS */
+-		dur = 3 * sifs;
+-		dur +=
+-		    (u16) wlc_calc_cts_time(wlc, rts_rate,
+-					       rts_preamble_type);
+-	} else {		/* CTS-TO-SELF */
+-		dur = 2 * sifs;
+-	}
+-
+-	dur +=
+-	    (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type,
+-					 frame_len);
+-	if (ba)
+-		dur +=
+-		    (u16) wlc_calc_ba_time(wlc, frame_rate,
+-					      WLC_SHORT_PREAMBLE);
+-	else
+-		dur +=
+-		    (u16) wlc_calc_ack_time(wlc, frame_rate,
+-					       frame_preamble_type);
+-	return dur;
+-}
+-
+-u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phyctl1 = 0;
+-	u16 bw;
+-
+-	if (WLCISLCNPHY(wlc->band)) {
+-		bw = PHY_TXC1_BW_20MHZ;
+-	} else {
+-		bw = RSPEC_GET_BW(rspec);
+-		/* 10Mhz is not supported yet */
+-		if (bw < PHY_TXC1_BW_20MHZ) {
+-			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: bw %d is "
+-				  "not supported yet, set to 20L\n", bw);
+-			bw = PHY_TXC1_BW_20MHZ;
+-		}
+-	}
+-
+-	if (IS_MCS(rspec)) {
+-		uint mcs = rspec & RSPEC_RATE_MASK;
+-
+-		/* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */
+-		phyctl1 = RSPEC_PHYTXBYTE2(rspec);
+-		/* set the upper byte of phyctl1 */
+-		phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8);
+-	} else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band)
+-		   && !WLCISSSLPNPHY(wlc->band)) {
+-		/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+-		/* Eventually MIMOPHY would also be converted to this format */
+-		/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+-		phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+-	} else {		/* legacy OFDM/CCK */
+-		s16 phycfg;
+-		/* get the phyctl byte from rate phycfg table */
+-		phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec));
+-		if (phycfg == -1) {
+-			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: wrong "
+-				  "legacy OFDM/CCK rate\n");
+-			phycfg = 0;
+-		}
+-		/* set the upper byte of phyctl1 */
+-		phyctl1 =
+-		    (bw | (phycfg << 8) |
+-		     (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
+-	}
+-	return phyctl1;
+-}
+-
+-ratespec_t
+-wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec,
+-		       u16 mimo_ctlchbw)
+-{
+-	ratespec_t rts_rspec = 0;
+-
+-	if (use_rspec) {
+-		/* use frame rate as rts rate */
+-		rts_rspec = rspec;
+-
+-	} else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) {
+-		/* Use 11Mbps as the g protection RTS target rate and fallback.
+-		 * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the
+-		 * target in case 11 Mbps is not Basic.
+-		 * 6 and 9 Mbps are not usually selected by rate selection, but even
+-		 * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust.
+-		 */
+-		rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M);
+-	} else {
+-		/* calculate RTS rate and fallback rate based on the frame rate
+-		 * RTS must be sent at a basic rate since it is a
+-		 * control frame, sec 9.6 of 802.11 spec
+-		 */
+-		rts_rspec = WLC_BASIC_RATE(wlc, rspec);
+-	}
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		/* set rts txbw to correct side band */
+-		rts_rspec &= ~RSPEC_BW_MASK;
+-
+-		/* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel
+-		 * (DUP), otherwise send RTS on control channel
+-		 */
+-		if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec))
+-			rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT);
+-		else
+-			rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+-
+-		/* pick siso/cdd as default for ofdm */
+-		if (IS_OFDM(rts_rspec)) {
+-			rts_rspec &= ~RSPEC_STF_MASK;
+-			rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT);
+-		}
+-	}
+-	return rts_rspec;
+-}
+-
+-/*
+- * Add d11txh_t, cck_phy_hdr_t.
+- *
+- * 'p' data must start with 802.11 MAC header
+- * 'p' must allow enough bytes of local headers to be "pushed" onto the packet
+- *
+- * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
+- *
+- */
+-static u16
+-wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw,
+-		     struct sk_buff *p, struct scb *scb, uint frag,
+-		     uint nfrags, uint queue, uint next_frag_len,
+-		     wsec_key_t *key, ratespec_t rspec_override)
+-{
+-	struct ieee80211_hdr *h;
+-	d11txh_t *txh;
+-	u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN];
+-	int len, phylen, rts_phylen;
+-	u16 mch, phyctl, xfts, mainrates;
+-	u16 seq = 0, mcl = 0, status = 0, frameid = 0;
+-	ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = {
+-	WLC_RATE_1M, WLC_RATE_1M};
+-	bool use_rts = false;
+-	bool use_cts = false;
+-	bool use_rifs = false;
+-	bool short_preamble[2] = { false, false };
+-	u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+-	u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE };
+-	u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN];
+-	struct ieee80211_rts *rts = NULL;
+-	bool qos;
+-	uint ac;
+-	u32 rate_val[2];
+-	bool hwtkmic = false;
+-	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
+-#define ANTCFG_NONE 0xFF
+-	u8 antcfg = ANTCFG_NONE;
+-	u8 fbantcfg = ANTCFG_NONE;
+-	uint phyctl1_stf = 0;
+-	u16 durid = 0;
+-	struct ieee80211_tx_rate *txrate[2];
+-	int k;
+-	struct ieee80211_tx_info *tx_info;
+-	bool is_mcs[2];
+-	u16 mimo_txbw;
+-	u8 mimo_preamble_type;
+-
+-	/* locate 802.11 MAC header */
+-	h = (struct ieee80211_hdr *)(p->data);
+-	qos = ieee80211_is_data_qos(h->frame_control);
+-
+-	/* compute length of frame in bytes for use in PLCP computations */
+-	len = bcm_pkttotlen(p);
+-	phylen = len + FCS_LEN;
+-
+-	/* If WEP enabled, add room in phylen for the additional bytes of
+-	 * ICV which MAC generates.  We do NOT add the additional bytes to
+-	 * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN
+-	 * in this case
+-	 */
+-	if (key) {
+-		phylen += key->icv_len;
+-	}
+-
+-	/* Get tx_info */
+-	tx_info = IEEE80211_SKB_CB(p);
+-
+-	/* add PLCP */
+-	plcp = skb_push(p, D11_PHY_HDR_LEN);
+-
+-	/* add Broadcom tx descriptor header */
+-	txh = (d11txh_t *) skb_push(p, D11_TXH_LEN);
+-	memset(txh, 0, D11_TXH_LEN);
+-
+-	/* setup frameid */
+-	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+-		/* non-AP STA should never use BCMC queue */
+-		if (queue == TX_BCMC_FIFO) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
+-				  "TX_BCMC!\n", WLCWLUNIT(wlc), __func__);
+-			frameid = bcmc_fid_generate(wlc, NULL, txh);
+-		} else {
+-			/* Increment the counter for first fragment */
+-			if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+-				SCB_SEQNUM(scb, p->priority)++;
+-			}
+-
+-			/* extract fragment number from frame first */
+-			seq = le16_to_cpu(seq) & FRAGNUM_MASK;
+-			seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT);
+-			h->seq_ctrl = cpu_to_le16(seq);
+-
+-			frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) |
+-			    (queue & TXFID_QUEUE_MASK);
+-		}
+-	}
+-	frameid |= queue & TXFID_QUEUE_MASK;
+-
+-	/* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */
+-	if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
+-		mcl |= TXC_IGNOREPMQ;
+-
+-	txrate[0] = tx_info->control.rates;
+-	txrate[1] = txrate[0] + 1;
+-
+-	/* if rate control algorithm didn't give us a fallback rate, use the primary rate */
+-	if (txrate[1]->idx < 0) {
+-		txrate[1] = txrate[0];
+-	}
+-
+-	for (k = 0; k < hw->max_rates; k++) {
+-		is_mcs[k] =
+-		    txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
+-		if (!is_mcs[k]) {
+-			if ((txrate[k]->idx >= 0)
+-			    && (txrate[k]->idx <
+-				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
+-				rate_val[k] =
+-				    hw->wiphy->bands[tx_info->band]->
+-				    bitrates[txrate[k]->idx].hw_value;
+-				short_preamble[k] =
+-				    txrate[k]->
+-				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
+-				    true : false;
+-			} else {
+-				rate_val[k] = WLC_RATE_1M;
+-			}
+-		} else {
+-			rate_val[k] = txrate[k]->idx;
+-		}
+-		/* Currently only support same setting for primay and fallback rates.
+-		 * Unify flags for each rate into a single value for the frame
+-		 */
+-		use_rts |=
+-		    txrate[k]->
+-		    flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false;
+-		use_cts |=
+-		    txrate[k]->
+-		    flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false;
+-
+-		if (is_mcs[k])
+-			rate_val[k] |= NRATE_MCS_INUSE;
+-
+-		rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]);
+-
+-		/* (1) RATE: determine and validate primary rate and fallback rates */
+-		if (!RSPEC_ACTIVE(rspec[k])) {
+-			rspec[k] = WLC_RATE_1M;
+-		} else {
+-			if (!is_multicast_ether_addr(h->addr1)) {
+-				/* set tx antenna config */
+-				wlc_antsel_antcfg_get(wlc->asi, false, false, 0,
+-						      0, &antcfg, &fbantcfg);
+-			}
+-		}
+-	}
+-
+-	phyctl1_stf = wlc->stf->ss_opmode;
+-
+-	if (N_ENAB(wlc->pub)) {
+-		for (k = 0; k < hw->max_rates; k++) {
+-			/* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */
+-			if (((IS_MCS(rspec[k]) &&
+-			      IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) ||
+-			     IS_OFDM(rspec[k]))
+-			    && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY)
+-				|| !(rspec[k] & RSPEC_OVERRIDE))) {
+-				rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK);
+-
+-				/* For SISO MCS use STBC if possible */
+-				if (IS_MCS(rspec[k])
+-				    && WLC_STF_SS_STBC_TX(wlc, scb)) {
+-					u8 stc;
+-
+-					stc = 1;	/* Nss for single stream is always 1 */
+-					rspec[k] |=
+-					    (PHY_TXC1_MODE_STBC <<
+-					     RSPEC_STF_SHIFT) | (stc <<
+-								 RSPEC_STC_SHIFT);
+-				} else
+-					rspec[k] |=
+-					    (phyctl1_stf << RSPEC_STF_SHIFT);
+-			}
+-
+-			/* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */
+-			if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) {
+-				/* default txbw is 20in40 SB */
+-				mimo_ctlchbw = mimo_txbw =
+-				    CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC)
+-				    ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
+-
+-				if (IS_MCS(rspec[k])) {
+-					/* mcs 32 must be 40b/w DUP */
+-					if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+-						mimo_txbw =
+-						    PHY_TXC1_BW_40MHZ_DUP;
+-						/* use override */
+-					} else if (wlc->mimo_40txbw != AUTO)
+-						mimo_txbw = wlc->mimo_40txbw;
+-					/* else check if dst is using 40 Mhz */
+-					else if (scb->flags & SCB_IS40)
+-						mimo_txbw = PHY_TXC1_BW_40MHZ;
+-				} else if (IS_OFDM(rspec[k])) {
+-					if (wlc->ofdm_40txbw != AUTO)
+-						mimo_txbw = wlc->ofdm_40txbw;
+-				} else {
+-					if (wlc->cck_40txbw != AUTO)
+-						mimo_txbw = wlc->cck_40txbw;
+-				}
+-			} else {
+-				/* mcs32 is 40 b/w only.
+-				 * This is possible for probe packets on a STA during SCAN
+-				 */
+-				if ((rspec[k] & RSPEC_RATE_MASK) == 32) {
+-					/* mcs 0 */
+-					rspec[k] = RSPEC_MIMORATE;
+-				}
+-				mimo_txbw = PHY_TXC1_BW_20MHZ;
+-			}
+-
+-			/* Set channel width */
+-			rspec[k] &= ~RSPEC_BW_MASK;
+-			if ((k == 0) || ((k > 0) && IS_MCS(rspec[k])))
+-				rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT);
+-			else
+-				rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT);
+-
+-			/* Set Short GI */
+-#ifdef NOSGIYET
+-			if (IS_MCS(rspec[k])
+-			    && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+-				rspec[k] |= RSPEC_SHORT_GI;
+-			else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI))
+-				rspec[k] &= ~RSPEC_SHORT_GI;
+-#else
+-			rspec[k] &= ~RSPEC_SHORT_GI;
+-#endif
+-
+-			mimo_preamble_type = WLC_MM_PREAMBLE;
+-			if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD)
+-				mimo_preamble_type = WLC_GF_PREAMBLE;
+-
+-			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
+-			    && (!IS_MCS(rspec[k]))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
+-					  "RC_MCS != IS_MCS(rspec)\n",
+-					  WLCWLUNIT(wlc), __func__);
+-			}
+-
+-			if (IS_MCS(rspec[k])) {
+-				preamble_type[k] = mimo_preamble_type;
+-
+-				/* if SGI is selected, then forced mm for single stream */
+-				if ((rspec[k] & RSPEC_SHORT_GI)
+-				    && IS_SINGLE_STREAM(rspec[k] &
+-							RSPEC_RATE_MASK)) {
+-					preamble_type[k] = WLC_MM_PREAMBLE;
+-				}
+-			}
+-
+-			/* should be better conditionalized */
+-			if (!IS_MCS(rspec[0])
+-			    && (tx_info->control.rates[0].
+-				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
+-				preamble_type[k] = WLC_SHORT_PREAMBLE;
+-		}
+-	} else {
+-		for (k = 0; k < hw->max_rates; k++) {
+-			/* Set ctrlchbw as 20Mhz */
+-			rspec[k] &= ~RSPEC_BW_MASK;
+-			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
+-
+-			/* for nphy, stf of ofdm frames must follow policies */
+-			if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) {
+-				rspec[k] &= ~RSPEC_STF_MASK;
+-				rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT;
+-			}
+-		}
+-	}
+-
+-	/* Reset these for use with AMPDU's */
+-	txrate[0]->count = 0;
+-	txrate[1]->count = 0;
+-
+-	/* (2) PROTECTION, may change rspec */
+-	if ((ieee80211_is_data(h->frame_control) ||
+-	    ieee80211_is_mgmt(h->frame_control)) &&
+-	    (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1))
+-		use_rts = true;
+-
+-	/* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */
+-	wlc_compute_plcp(wlc, rspec[0], phylen, plcp);
+-	wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback);
+-	memcpy(&txh->FragPLCPFallback,
+-	       plcp_fallback, sizeof(txh->FragPLCPFallback));
+-
+-	/* Length field now put in CCK FBR CRC field */
+-	if (IS_CCK(rspec[1])) {
+-		txh->FragPLCPFallback[4] = phylen & 0xff;
+-		txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8;
+-	}
+-
+-	/* MIMO-RATE: need validation ?? */
+-	mainrates =
+-	    IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) :
+-	    plcp[0];
+-
+-	/* DUR field for main rate */
+-	if (!ieee80211_is_pspoll(h->frame_control) &&
+-	    !is_multicast_ether_addr(h->addr1) && !use_rifs) {
+-		durid =
+-		    wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0],
+-					  next_frag_len);
+-		h->duration_id = cpu_to_le16(durid);
+-	} else if (use_rifs) {
+-		/* NAV protect to end of next max packet size */
+-		durid =
+-		    (u16) wlc_calc_frame_time(wlc, rspec[0],
+-						 preamble_type[0],
+-						 DOT11_MAX_FRAG_LEN);
+-		durid += RIFS_11N_TIME;
+-		h->duration_id = cpu_to_le16(durid);
+-	}
+-
+-	/* DUR field for fallback rate */
+-	if (ieee80211_is_pspoll(h->frame_control))
+-		txh->FragDurFallback = h->duration_id;
+-	else if (is_multicast_ether_addr(h->addr1) || use_rifs)
+-		txh->FragDurFallback = 0;
+-	else {
+-		durid = wlc_compute_frame_dur(wlc, rspec[1],
+-					      preamble_type[1], next_frag_len);
+-		txh->FragDurFallback = cpu_to_le16(durid);
+-	}
+-
+-	/* (4) MAC-HDR: MacTxControlLow */
+-	if (frag == 0)
+-		mcl |= TXC_STARTMSDU;
+-
+-	if (!is_multicast_ether_addr(h->addr1))
+-		mcl |= TXC_IMMEDACK;
+-
+-	if (BAND_5G(wlc->band->bandtype))
+-		mcl |= TXC_FREQBAND_5G;
+-
+-	if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC))
+-		mcl |= TXC_BW_40;
+-
+-	/* set AMIC bit if using hardware TKIP MIC */
+-	if (hwtkmic)
+-		mcl |= TXC_AMIC;
+-
+-	txh->MacTxControlLow = cpu_to_le16(mcl);
+-
+-	/* MacTxControlHigh */
+-	mch = 0;
+-
+-	/* Set fallback rate preamble type */
+-	if ((preamble_type[1] == WLC_SHORT_PREAMBLE) ||
+-	    (preamble_type[1] == WLC_GF_PREAMBLE)) {
+-		if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M)
+-			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
+-	}
+-
+-	/* MacFrameControl */
+-	memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16));
+-	txh->TxFesTimeNormal = cpu_to_le16(0);
+-
+-	txh->TxFesTimeFallback = cpu_to_le16(0);
+-
+-	/* TxFrameRA */
+-	memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN);
+-
+-	/* TxFrameID */
+-	txh->TxFrameID = cpu_to_le16(frameid);
+-
+-	/* TxStatus, Note the case of recreating the first frag of a suppressed frame
+-	 * then we may need to reset the retry cnt's via the status reg
+-	 */
+-	txh->TxStatus = cpu_to_le16(status);
+-
+-	/* extra fields for ucode AMPDU aggregation, the new fields are added to
+-	 * the END of previous structure so that it's compatible in driver.
+-	 */
+-	txh->MaxNMpdus = cpu_to_le16(0);
+-	txh->MaxABytes_MRT = cpu_to_le16(0);
+-	txh->MaxABytes_FBR = cpu_to_le16(0);
+-	txh->MinMBytes = cpu_to_le16(0);
+-
+-	/* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */
+-	/* RTS PLCP header and RTS frame */
+-	if (use_rts || use_cts) {
+-		if (use_rts && use_cts)
+-			use_cts = false;
+-
+-		for (k = 0; k < 2; k++) {
+-			rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k],
+-							      false,
+-							      mimo_ctlchbw);
+-		}
+-
+-		if (!IS_OFDM(rts_rspec[0]) &&
+-		    !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) ||
+-		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+-			rts_preamble_type[0] = WLC_SHORT_PREAMBLE;
+-			mch |= TXC_PREAMBLE_RTS_MAIN_SHORT;
+-		}
+-
+-		if (!IS_OFDM(rts_rspec[1]) &&
+-		    !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) ||
+-		      (wlc->PLCPHdr_override == WLC_PLCP_LONG))) {
+-			rts_preamble_type[1] = WLC_SHORT_PREAMBLE;
+-			mch |= TXC_PREAMBLE_RTS_FB_SHORT;
+-		}
+-
+-		/* RTS/CTS additions to MacTxControlLow */
+-		if (use_cts) {
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS);
+-		} else {
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS);
+-			txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME);
+-		}
+-
+-		/* RTS PLCP header */
+-		rts_plcp = txh->RTSPhyHeader;
+-		if (use_cts)
+-			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
+-		else
+-			rts_phylen = DOT11_RTS_LEN + FCS_LEN;
+-
+-		wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp);
+-
+-		/* fallback rate version of RTS PLCP header */
+-		wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen,
+-				 rts_plcp_fallback);
+-		memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback,
+-		       sizeof(txh->RTSPLCPFallback));
+-
+-		/* RTS frame fields... */
+-		rts = (struct ieee80211_rts *)&txh->rts_frame;
+-
+-		durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0],
+-					       rspec[0], rts_preamble_type[0],
+-					       preamble_type[0], phylen, false);
+-		rts->duration = cpu_to_le16(durid);
+-		/* fallback rate version of RTS DUR field */
+-		durid = wlc_compute_rtscts_dur(wlc, use_cts,
+-					       rts_rspec[1], rspec[1],
+-					       rts_preamble_type[1],
+-					       preamble_type[1], phylen, false);
+-		txh->RTSDurFallback = cpu_to_le16(durid);
+-
+-		if (use_cts) {
+-			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+-							 IEEE80211_STYPE_CTS);
+-
+-			memcpy(&rts->ra, &h->addr2, ETH_ALEN);
+-		} else {
+-			rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+-							 IEEE80211_STYPE_RTS);
+-
+-			memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN);
+-		}
+-
+-		/* mainrate
+-		 *    low 8 bits: main frag rate/mcs,
+-		 *    high 8 bits: rts/cts rate/mcs
+-		 */
+-		mainrates |= (IS_OFDM(rts_rspec[0]) ?
+-			      D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) :
+-			      rts_plcp[0]) << 8;
+-	} else {
+-		memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN);
+-		memset((char *)&txh->rts_frame, 0,
+-			sizeof(struct ieee80211_rts));
+-		memset((char *)txh->RTSPLCPFallback, 0,
+-		      sizeof(txh->RTSPLCPFallback));
+-		txh->RTSDurFallback = 0;
+-	}
+-
+-#ifdef SUPPORT_40MHZ
+-	/* add null delimiter count */
+-	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) {
+-		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] =
+-		    wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen);
+-	}
+-#endif
+-
+-	/* Now that RTS/RTS FB preamble types are updated, write the final value */
+-	txh->MacTxControlHigh = cpu_to_le16(mch);
+-
+-	/* MainRates (both the rts and frag plcp rates have been calculated now) */
+-	txh->MainRates = cpu_to_le16(mainrates);
+-
+-	/* XtraFrameTypes */
+-	xfts = FRAMETYPE(rspec[1], wlc->mimoft);
+-	xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT);
+-	xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT);
+-	xfts |=
+-	    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT;
+-	txh->XtraFrameTypes = cpu_to_le16(xfts);
+-
+-	/* PhyTxControlWord */
+-	phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
+-	if ((preamble_type[0] == WLC_SHORT_PREAMBLE) ||
+-	    (preamble_type[0] == WLC_GF_PREAMBLE)) {
+-		if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
+-			phyctl |= PHY_TXC_SHORT_HDR;
+-	}
+-
+-	/* phytxant is properly bit shifted */
+-	phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]);
+-	txh->PhyTxControlWord = cpu_to_le16(phyctl);
+-
+-	/* PhyTxControlWord_1 */
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		u16 phyctl1 = 0;
+-
+-		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]);
+-		txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1);
+-		phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]);
+-		txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1);
+-
+-		if (use_rts || use_cts) {
+-			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]);
+-			txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1);
+-			phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]);
+-			txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1);
+-		}
+-
+-		/*
+-		 * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set,
+-		 * fill in non-zero MModeLen and/or MModeFbrLen
+-		 *  it will be unnecessary if they are separated
+-		 */
+-		if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) {
+-			u16 mmodelen =
+-			    wlc_calc_lsig_len(wlc, rspec[0], phylen);
+-			txh->MModeLen = cpu_to_le16(mmodelen);
+-		}
+-
+-		if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) {
+-			u16 mmodefbrlen =
+-			    wlc_calc_lsig_len(wlc, rspec[1], phylen);
+-			txh->MModeFbrLen = cpu_to_le16(mmodefbrlen);
+-		}
+-	}
+-
+-	ac = skb_get_queue_mapping(p);
+-	if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
+-		uint frag_dur, dur, dur_fallback;
+-
+-		/* WME: Update TXOP threshold */
+-		if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
+-			frag_dur =
+-			    wlc_calc_frame_time(wlc, rspec[0], preamble_type[0],
+-						phylen);
+-
+-			if (rts) {
+-				/* 1 RTS or CTS-to-self frame */
+-				dur =
+-				    wlc_calc_cts_time(wlc, rts_rspec[0],
+-						      rts_preamble_type[0]);
+-				dur_fallback =
+-				    wlc_calc_cts_time(wlc, rts_rspec[1],
+-						      rts_preamble_type[1]);
+-				/* (SIFS + CTS) + SIFS + frame + SIFS + ACK */
+-				dur += le16_to_cpu(rts->duration);
+-				dur_fallback +=
+-					le16_to_cpu(txh->RTSDurFallback);
+-			} else if (use_rifs) {
+-				dur = frag_dur;
+-				dur_fallback = 0;
+-			} else {
+-				/* frame + SIFS + ACK */
+-				dur = frag_dur;
+-				dur +=
+-				    wlc_compute_frame_dur(wlc, rspec[0],
+-							  preamble_type[0], 0);
+-
+-				dur_fallback =
+-				    wlc_calc_frame_time(wlc, rspec[1],
+-							preamble_type[1],
+-							phylen);
+-				dur_fallback +=
+-				    wlc_compute_frame_dur(wlc, rspec[1],
+-							  preamble_type[1], 0);
+-			}
+-			/* NEED to set TxFesTimeNormal (hard) */
+-			txh->TxFesTimeNormal = cpu_to_le16((u16) dur);
+-			/* NEED to set fallback rate version of TxFesTimeNormal (hard) */
+-			txh->TxFesTimeFallback =
+-				cpu_to_le16((u16) dur_fallback);
+-
+-			/* update txop byte threshold (txop minus intraframe overhead) */
+-			if (wlc->edcf_txop[ac] >= (dur - frag_dur)) {
+-				{
+-					uint newfragthresh;
+-
+-					newfragthresh =
+-					    wlc_calc_frame_len(wlc, rspec[0],
+-							       preamble_type[0],
+-							       (wlc->
+-								edcf_txop[ac] -
+-								(dur -
+-								 frag_dur)));
+-					/* range bound the fragthreshold */
+-					if (newfragthresh < DOT11_MIN_FRAG_LEN)
+-						newfragthresh =
+-						    DOT11_MIN_FRAG_LEN;
+-					else if (newfragthresh >
+-						 wlc->usr_fragthresh)
+-						newfragthresh =
+-						    wlc->usr_fragthresh;
+-					/* update the fragthresh and do txc update */
+-					if (wlc->fragthresh[queue] !=
+-					    (u16) newfragthresh) {
+-						wlc->fragthresh[queue] =
+-						    (u16) newfragthresh;
+-					}
+-				}
+-			} else
+-				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
+-					  "for rate %d\n",
+-					  wlc->pub->unit, fifo_names[queue],
+-					  RSPEC2RATE(rspec[0]));
+-
+-			if (dur > wlc->edcf_txop[ac])
+-				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
+-					  "exceeded phylen %d/%d dur %d/%d\n",
+-					  wlc->pub->unit, __func__,
+-					  fifo_names[queue],
+-					  phylen, wlc->fragthresh[queue],
+-					  dur, wlc->edcf_txop[ac]);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs)
+-{
+-	struct wlc_bsscfg *cfg = wlc->cfg;
+-
+-	if (BSSCFG_STA(cfg)) {
+-		/* run watchdog here if the watchdog timer is not armed */
+-		if (WLC_WATCHDOG_TBTT(wlc)) {
+-			u32 cur, delta;
+-			if (wlc->WDarmed) {
+-				wl_del_timer(wlc->wl, wlc->wdtimer);
+-				wlc->WDarmed = false;
+-			}
+-
+-			cur = OSL_SYSUPTIME();
+-			delta = cur > wlc->WDlast ? cur - wlc->WDlast :
+-			    (u32) ~0 - wlc->WDlast + cur + 1;
+-			if (delta >= TIMER_INTERVAL_WATCHDOG) {
+-				wlc_watchdog((void *)wlc);
+-				wlc->WDlast = cur;
+-			}
+-
+-			wl_add_timer(wlc->wl, wlc->wdtimer,
+-				     wlc_watchdog_backup_bi(wlc), true);
+-			wlc->WDarmed = true;
+-		}
+-	}
+-
+-	if (!cfg->BSS) {
+-		/* DirFrmQ is now valid...defer setting until end of ATIM window */
+-		wlc->qvalid |= MCMD_DIRFRMQVAL;
+-	}
+-}
+-
+-static void wlc_war16165(struct wlc_info *wlc, bool tx)
+-{
+-	if (tx) {
+-		/* the post-increment is used in STAY_AWAKE macro */
+-		if (wlc->txpend16165war++ == 0)
+-			wlc_set_ps_ctrl(wlc);
+-	} else {
+-		wlc->txpend16165war--;
+-		if (wlc->txpend16165war == 0)
+-			wlc_set_ps_ctrl(wlc);
+-	}
+-}
+-
+-/* process an individual tx_status_t */
+-/* WLC_HIGH_API */
+-bool
+-wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
+-{
+-	struct sk_buff *p;
+-	uint queue;
+-	d11txh_t *txh;
+-	struct scb *scb = NULL;
+-	bool free_pdu;
+-	int tx_rts, tx_frame_count, tx_rts_count;
+-	uint totlen, supr_status;
+-	bool lastframe;
+-	struct ieee80211_hdr *h;
+-	u16 mcl;
+-	struct ieee80211_tx_info *tx_info;
+-	struct ieee80211_tx_rate *txrate;
+-	int i;
+-
+-	(void)(frm_tx2);	/* Compiler reference to avoid unused variable warning */
+-
+-	/* discard intermediate indications for ucode with one legitimate case:
+-	 *   e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent
+-	 *   tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts
+-	 *   transmission count)
+-	 */
+-	if (!(txs->status & TX_STATUS_AMPDU)
+-	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
+-		wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
+-			  __func__);
+-		return false;
+-	}
+-
+-	queue = txs->frameid & TXFID_QUEUE_MASK;
+-	if (queue >= NFIFO) {
+-		p = NULL;
+-		goto fatal;
+-	}
+-
+-	p = GETNEXTTXP(wlc, queue);
+-	if (WLC_WAR16165(wlc))
+-		wlc_war16165(wlc, false);
+-	if (p == NULL)
+-		goto fatal;
+-
+-	txh = (d11txh_t *) (p->data);
+-	mcl = le16_to_cpu(txh->MacTxControlLow);
+-
+-	if (txs->phyerr) {
+-		if (WL_ERROR_ON()) {
+-			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
+-				  txs->phyerr, txh->MainRates);
+-			wlc_print_txdesc(txh);
+-		}
+-		wlc_print_txstatus(txs);
+-	}
+-
+-	if (txs->frameid != cpu_to_le16(txh->TxFrameID))
+-		goto fatal;
+-	tx_info = IEEE80211_SKB_CB(p);
+-	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
+-
+-	if (tx_info->control.sta)
+-		scb = (struct scb *)tx_info->control.sta->drv_priv;
+-
+-	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+-		wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
+-		return false;
+-	}
+-
+-	supr_status = txs->status & TX_STATUS_SUPR_MASK;
+-	if (supr_status == TX_STATUS_SUPR_BADCH)
+-		BCMMSG(wlc->wiphy,
+-		       "%s: Pkt tx suppressed, possibly channel %d\n",
+-		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+-
+-	tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
+-	tx_frame_count =
+-	    (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT;
+-	tx_rts_count =
+-	    (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT;
+-
+-	lastframe = !ieee80211_has_morefrags(h->frame_control);
+-
+-	if (!lastframe) {
+-		wiphy_err(wlc->wiphy, "Not last frame!\n");
+-	} else {
+-		u16 sfbl, lfbl;
+-		ieee80211_tx_info_clear_status(tx_info);
+-		if (queue < AC_COUNT) {
+-			sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]);
+-			lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]);
+-		} else {
+-			sfbl = wlc->SFBL;
+-			lfbl = wlc->LFBL;
+-		}
+-
+-		txrate = tx_info->status.rates;
+-		/* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */
+-		if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) {
+-			/* rate selection requested a fallback rate and we used it */
+-			txrate->count = lfbl;
+-			txrate[1].count = tx_frame_count - lfbl;
+-		} else {
+-			/* rate selection did not request fallback rate, or we didn't need it */
+-			txrate->count = tx_frame_count;
+-			/* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */
+-			txrate[1].idx = -1;
+-			txrate[1].count = 0;
+-		}
+-
+-		/* clear the rest of the rates */
+-		for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
+-			txrate[i].idx = -1;
+-			txrate[i].count = 0;
+-		}
+-
+-		if (txs->status & TX_STATUS_ACK_RCV)
+-			tx_info->flags |= IEEE80211_TX_STAT_ACK;
+-	}
+-
+-	totlen = bcm_pkttotlen(p);
+-	free_pdu = true;
+-
+-	wlc_txfifo_complete(wlc, queue, 1);
+-
+-	if (lastframe) {
+-		p->next = NULL;
+-		p->prev = NULL;
+-		wlc->txretried = 0;
+-		/* remove PLCP & Broadcom tx descriptor header */
+-		skb_pull(p, D11_PHY_HDR_LEN);
+-		skb_pull(p, D11_TXH_LEN);
+-		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
+-	} else {
+-		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
+-			  "tx_status\n", __func__);
+-	}
+-
+-	return false;
+-
+- fatal:
+-	if (p)
+-		bcm_pkt_buf_free_skb(p);
+-
+-	return true;
+-
+-}
+-
+-void
+-wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend)
+-{
+-	TXPKTPENDDEC(wlc, fifo, txpktpend);
+-	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
+-		TXPKTPENDGET(wlc, fifo));
+-
+-	/* There is more room; mark precedences related to this FIFO sendable */
+-	WLC_TX_FIFO_ENAB(wlc, fifo);
+-
+-	if (!TXPKTPENDTOT(wlc)) {
+-		if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR)
+-			wlc_bsscfg_tx_check(wlc);
+-	}
+-
+-	/* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */
+-	if (AP_ENAB(wlc->pub) &&
+-	    wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) {
+-		wlc->bcmcfifo_drain = false;
+-		wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO);
+-	}
+-
+-	/* figure out which bsscfg is being worked on... */
+-}
+-
+-/* Update beacon listen interval in shared memory */
+-void wlc_bcn_li_upd(struct wlc_info *wlc)
+-{
+-	if (AP_ENAB(wlc->pub))
+-		return;
+-
+-	/* wake up every DTIM is the default */
+-	if (wlc->bcn_li_dtim == 1)
+-		wlc_write_shm(wlc, M_BCN_LI, 0);
+-	else
+-		wlc_write_shm(wlc, M_BCN_LI,
+-			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
+-}
+-
+-/*
+- * recover 64bit TSF value from the 16bit TSF value in the rx header
+- * given the assumption that the TSF passed in header is within 65ms
+- * of the current tsf.
+- *
+- * 6       5       4       4       3       2       1
+- * 3.......6.......8.......0.......2.......4.......6.......8......0
+- * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
+- *
+- * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
+- * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the
+- * receive call sequence after rx interrupt. Only the higher 16 bits
+- * are used. Finally, the tsf_h is read from the tsf register.
+- */
+-static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh)
+-{
+-	u32 tsf_h, tsf_l;
+-	u16 rx_tsf_0_15, rx_tsf_16_31;
+-
+-	wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h);
+-
+-	rx_tsf_16_31 = (u16)(tsf_l >> 16);
+-	rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
+-
+-	/*
+-	 * a greater tsf time indicates the low 16 bits of
+-	 * tsf_l wrapped, so decrement the high 16 bits.
+-	 */
+-	if ((u16)tsf_l < rx_tsf_0_15) {
+-		rx_tsf_16_31 -= 1;
+-		if (rx_tsf_16_31 == 0xffff)
+-			tsf_h -= 1;
+-	}
+-
+-	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
+-}
+-
+-static void
+-prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p,
+-		     struct ieee80211_rx_status *rx_status)
+-{
+-	wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
+-	int preamble;
+-	int channel;
+-	ratespec_t rspec;
+-	unsigned char *plcp;
+-
+-	/* fill in TSF and flag its presence */
+-	rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh);
+-	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+-
+-	channel = WLC_CHAN_CHANNEL(rxh->RxChan);
+-
+-	if (channel > 14) {
+-		rx_status->band = IEEE80211_BAND_5GHZ;
+-		rx_status->freq = ieee80211_ofdm_chan_to_freq(
+-					WF_CHAN_FACTOR_5_G/2, channel);
+-
+-	} else {
+-		rx_status->band = IEEE80211_BAND_2GHZ;
+-		rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
+-	}
+-
+-	rx_status->signal = wlc_rxh->rssi;	/* signal */
+-
+-	/* noise */
+-	/* qual */
+-	rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;	/* ant */
+-
+-	plcp = p->data;
+-
+-	rspec = wlc_compute_rspec(rxh, plcp);
+-	if (IS_MCS(rspec)) {
+-		rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
+-		rx_status->flag |= RX_FLAG_HT;
+-		if (RSPEC_IS40MHZ(rspec))
+-			rx_status->flag |= RX_FLAG_40MHZ;
+-	} else {
+-		switch (RSPEC2RATE(rspec)) {
+-		case WLC_RATE_1M:
+-			rx_status->rate_idx = 0;
+-			break;
+-		case WLC_RATE_2M:
+-			rx_status->rate_idx = 1;
+-			break;
+-		case WLC_RATE_5M5:
+-			rx_status->rate_idx = 2;
+-			break;
+-		case WLC_RATE_11M:
+-			rx_status->rate_idx = 3;
+-			break;
+-		case WLC_RATE_6M:
+-			rx_status->rate_idx = 4;
+-			break;
+-		case WLC_RATE_9M:
+-			rx_status->rate_idx = 5;
+-			break;
+-		case WLC_RATE_12M:
+-			rx_status->rate_idx = 6;
+-			break;
+-		case WLC_RATE_18M:
+-			rx_status->rate_idx = 7;
+-			break;
+-		case WLC_RATE_24M:
+-			rx_status->rate_idx = 8;
+-			break;
+-		case WLC_RATE_36M:
+-			rx_status->rate_idx = 9;
+-			break;
+-		case WLC_RATE_48M:
+-			rx_status->rate_idx = 10;
+-			break;
+-		case WLC_RATE_54M:
+-			rx_status->rate_idx = 11;
+-			break;
+-		default:
+-			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
+-		}
+-
+-		/* Determine short preamble and rate_idx */
+-		preamble = 0;
+-		if (IS_CCK(rspec)) {
+-			if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
+-				rx_status->flag |= RX_FLAG_SHORTPRE;
+-		} else if (IS_OFDM(rspec)) {
+-			rx_status->flag |= RX_FLAG_SHORTPRE;
+-		} else {
+-			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
+-				  __func__);
+-		}
+-	}
+-
+-	if (PLCP3_ISSGI(plcp[3]))
+-		rx_status->flag |= RX_FLAG_SHORT_GI;
+-
+-	if (rxh->RxStatus1 & RXS_DECERR) {
+-		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+-		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
+-			  __func__);
+-	}
+-	if (rxh->RxStatus1 & RXS_FCSERR) {
+-		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+-		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
+-			  __func__);
+-	}
+-}
+-
+-static void
+-wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p)
+-{
+-	int len_mpdu;
+-	struct ieee80211_rx_status rx_status;
+-	struct ieee80211_hdr *hdr;
+-
+-	memset(&rx_status, 0, sizeof(rx_status));
+-	prep_mac80211_status(wlc, rxh, p, &rx_status);
+-
+-	/* mac header+body length, exclude CRC and plcp header */
+-	len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN;
+-	skb_pull(p, D11_PHY_HDR_LEN);
+-	__skb_trim(p, len_mpdu);
+-
+-	/* unmute transmit */
+-	if (wlc->hw->suspended_fifos) {
+-		hdr = (struct ieee80211_hdr *)p->data;
+-		if (ieee80211_is_beacon(hdr->frame_control))
+-			wlc_bmac_mute(wlc->hw, false, 0);
+-	}
+-
+-	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
+-	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
+-	return;
+-}
+-
+-/* Process received frames */
+-/*
+- * Return true if more frames need to be processed. false otherwise.
+- * Param 'bound' indicates max. # frames to process before break out.
+- */
+-/* WLC_HIGH_API */
+-void wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
+-{
+-	d11rxhdr_t *rxh;
+-	struct ieee80211_hdr *h;
+-	uint len;
+-	bool is_amsdu;
+-
+-	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
+-
+-	/* frame starts with rxhdr */
+-	rxh = (d11rxhdr_t *) (p->data);
+-
+-	/* strip off rxhdr */
+-	skb_pull(p, wlc->hwrxoff);
+-
+-	/* fixup rx header endianness */
+-	rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize);
+-	rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0);
+-	rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1);
+-	rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2);
+-	rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3);
+-	rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4);
+-	rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5);
+-	rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1);
+-	rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2);
+-	rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime);
+-	rxh->RxChan = le16_to_cpu(rxh->RxChan);
+-
+-	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
+-	if (rxh->RxStatus1 & RXS_PBPRES) {
+-		if (p->len < 2) {
+-			wiphy_err(wlc->wiphy, "wl%d: wlc_recv: rcvd runt of "
+-				  "len %d\n", wlc->pub->unit, p->len);
+-			goto toss;
+-		}
+-		skb_pull(p, 2);
+-	}
+-
+-	h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN);
+-	len = p->len;
+-
+-	if (rxh->RxStatus1 & RXS_FCSERR) {
+-		if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
+-			wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
+-				  " tossing\n");
+-			goto toss;
+-		} else {
+-			wiphy_err(wlc->wiphy, "RCSERR!!!\n");
+-			goto toss;
+-		}
+-	}
+-
+-	/* check received pkt has at least frame control field */
+-	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
+-		goto toss;
+-	}
+-
+-	is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK;
+-
+-	/* explicitly test bad src address to avoid sending bad deauth */
+-	if (!is_amsdu) {
+-		/* CTS and ACK CTL frames are w/o a2 */
+-
+-		if (ieee80211_is_data(h->frame_control) ||
+-		    ieee80211_is_mgmt(h->frame_control)) {
+-			if ((is_zero_ether_addr(h->addr2) ||
+-			     is_multicast_ether_addr(h->addr2))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
+-					  "frame with invalid src mac address,"
+-					  " a2: %pM\n",
+-					 wlc->pub->unit, __func__, h->addr2);
+-				goto toss;
+-			}
+-		}
+-	}
+-
+-	/* due to sheer numbers, toss out probe reqs for now */
+-	if (ieee80211_is_probe_req(h->frame_control))
+-		goto toss;
+-
+-	if (is_amsdu)
+-		goto toss;
+-
+-	wlc_recvctl(wlc, rxh, p);
+-	return;
+-
+- toss:
+-	bcm_pkt_buf_free_skb(p);
+-}
+-
+-/* calculate frame duration for Mixed-mode L-SIG spoofing, return
+- * number of bytes goes in the length field
+- *
+- * Formula given by HT PHY Spec v 1.13
+- *   len = 3(nsyms + nstream + 3) - 3
+- */
+-u16
+-wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len)
+-{
+-	uint nsyms, len = 0, kNdps;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
+-		 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		/* MCS_TXS(mcs) returns num tx streams - 1 */
+-		int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
+-
+-		/* the payload duration calculation matches that of regular ofdm */
+-		/* 1000Ndbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-
+-		if (RSPEC_STC(ratespec) == 0)
+-			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-			nsyms =
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, kNdps);
+-		else
+-			/* STBC needs to have even number of symbols */
+-			nsyms =
+-			    2 *
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+-
+-		nsyms += (tot_streams + 3);	/* (+3) account for HT-SIG(2) and HT-STF(1) */
+-		/* 3 bytes/symbol @ legacy 6Mbps rate */
+-		len = (3 * nsyms) - 3;	/* (-3) excluding service bits and tail bits */
+-	}
+-
+-	return (u16) len;
+-}
+-
+-/* calculate frame duration of a given rate and length, return time in usec unit */
+-uint
+-wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
+-		    uint mac_len)
+-{
+-	uint nsyms, dur = 0, Ndps, kNdps;
+-	uint rate = RSPEC2RATE(ratespec);
+-
+-	if (rate == 0) {
+-		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
+-			  wlc->pub->unit);
+-		rate = WLC_RATE_1M;
+-	}
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
+-		 wlc->pub->unit, ratespec, preamble_type, mac_len);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+-
+-		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+-		if (preamble_type == WLC_MM_PREAMBLE)
+-			dur += PREN_MM_EXT;
+-		/* 1000Ndbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-
+-		if (RSPEC_STC(ratespec) == 0)
+-			/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-			nsyms =
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, kNdps);
+-		else
+-			/* STBC needs to have even number of symbols */
+-			nsyms =
+-			    2 *
+-			    CEIL((APHY_SERVICE_NBITS + 8 * mac_len +
+-				  APHY_TAIL_NBITS) * 1000, 2 * kNdps);
+-
+-		dur += APHY_SYMBOL_TIME * nsyms;
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur += DOT11_OFDM_SIGNAL_EXTENSION;
+-	} else if (IS_OFDM(rate)) {
+-		dur = APHY_PREAMBLE_TIME;
+-		dur += APHY_SIGNAL_TIME;
+-		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+-		Ndps = rate * 2;
+-		/* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */
+-		nsyms =
+-		    CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS),
+-			 Ndps);
+-		dur += APHY_SYMBOL_TIME * nsyms;
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur += DOT11_OFDM_SIGNAL_EXTENSION;
+-	} else {
+-		/* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */
+-		mac_len = mac_len * 8 * 2;
+-		/* calc ceiling of bits/rate = microseconds of air time */
+-		dur = (mac_len + rate - 1) / rate;
+-		if (preamble_type & WLC_SHORT_PREAMBLE)
+-			dur += BPHY_PLCP_SHORT_TIME;
+-		else
+-			dur += BPHY_PLCP_TIME;
+-	}
+-	return dur;
+-}
+-
+-/* The opposite of wlc_calc_frame_time */
+-static uint
+-wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
+-		   uint dur)
+-{
+-	uint nsyms, mac_len, Ndps, kNdps;
+-	uint rate = RSPEC2RATE(ratespec);
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
+-		 wlc->pub->unit, ratespec, preamble_type, dur);
+-
+-	if (IS_MCS(ratespec)) {
+-		uint mcs = ratespec & RSPEC_RATE_MASK;
+-		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
+-		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
+-		/* payload calculation matches that of regular ofdm */
+-		if (BAND_2G(wlc->band->bandtype))
+-			dur -= DOT11_OFDM_SIGNAL_EXTENSION;
+-		/* kNdbps = kbps * 4 */
+-		kNdps =
+-		    MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec),
+-			     RSPEC_ISSGI(ratespec)) * 4;
+-		nsyms = dur / APHY_SYMBOL_TIME;
+-		mac_len =
+-		    ((nsyms * kNdps) -
+-		     ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000;
+-	} else if (IS_OFDM(ratespec)) {
+-		dur -= APHY_PREAMBLE_TIME;
+-		dur -= APHY_SIGNAL_TIME;
+-		/* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */
+-		Ndps = rate * 2;
+-		nsyms = dur / APHY_SYMBOL_TIME;
+-		mac_len =
+-		    ((nsyms * Ndps) -
+-		     (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8;
+-	} else {
+-		if (preamble_type & WLC_SHORT_PREAMBLE)
+-			dur -= BPHY_PLCP_SHORT_TIME;
+-		else
+-			dur -= BPHY_PLCP_TIME;
+-		mac_len = dur * rate;
+-		/* divide out factor of 2 in rate (1/2 mbps) */
+-		mac_len = mac_len / 8 / 2;
+-	}
+-	return mac_len;
+-}
+-
+-static uint
+-wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
+-		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
+-	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+-	 * or equal to the rate of the immediately previous frame in the FES
+-	 */
+-	rspec = WLC_BASIC_RATE(wlc, rspec);
+-	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
+-	return wlc_calc_frame_time(wlc, rspec, preamble_type,
+-				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
+-				    FCS_LEN));
+-}
+-
+-static uint
+-wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	uint dur = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
+-		wlc->pub->unit, rspec, preamble_type);
+-	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
+-	 * or equal to the rate of the immediately previous frame in the FES
+-	 */
+-	rspec = WLC_BASIC_RATE(wlc, rspec);
+-	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
+-	dur =
+-	    wlc_calc_frame_time(wlc, rspec, preamble_type,
+-				(DOT11_ACK_LEN + FCS_LEN));
+-	return dur;
+-}
+-
+-static uint
+-wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
+-		wlc->pub->unit, rspec, preamble_type);
+-	return wlc_calc_ack_time(wlc, rspec, preamble_type);
+-}
+-
+-/* derive wlc->band->basic_rate[] table from 'rateset' */
+-void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset)
+-{
+-	u8 rate;
+-	u8 mandatory;
+-	u8 cck_basic = 0;
+-	u8 ofdm_basic = 0;
+-	u8 *br = wlc->band->basic_rate;
+-	uint i;
+-
+-	/* incoming rates are in 500kbps units as in 802.11 Supported Rates */
+-	memset(br, 0, WLC_MAXRATE + 1);
+-
+-	/* For each basic rate in the rates list, make an entry in the
+-	 * best basic lookup.
+-	 */
+-	for (i = 0; i < rateset->count; i++) {
+-		/* only make an entry for a basic rate */
+-		if (!(rateset->rates[i] & WLC_RATE_FLAG))
+-			continue;
+-
+-		/* mask off basic bit */
+-		rate = (rateset->rates[i] & WLC_RATE_MASK);
+-
+-		if (rate > WLC_MAXRATE) {
+-			wiphy_err(wlc->wiphy, "wlc_rate_lookup_init: invalid "
+-				  "rate 0x%X in rate set\n",
+-				  rateset->rates[i]);
+-			continue;
+-		}
+-
+-		br[rate] = rate;
+-	}
+-
+-	/* The rate lookup table now has non-zero entries for each
+-	 * basic rate, equal to the basic rate: br[basicN] = basicN
+-	 *
+-	 * To look up the best basic rate corresponding to any
+-	 * particular rate, code can use the basic_rate table
+-	 * like this
+-	 *
+-	 * basic_rate = wlc->band->basic_rate[tx_rate]
+-	 *
+-	 * Make sure there is a best basic rate entry for
+-	 * every rate by walking up the table from low rates
+-	 * to high, filling in holes in the lookup table
+-	 */
+-
+-	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
+-		rate = wlc->band->hw_rateset.rates[i];
+-
+-		if (br[rate] != 0) {
+-			/* This rate is a basic rate.
+-			 * Keep track of the best basic rate so far by
+-			 * modulation type.
+-			 */
+-			if (IS_OFDM(rate))
+-				ofdm_basic = rate;
+-			else
+-				cck_basic = rate;
+-
+-			continue;
+-		}
+-
+-		/* This rate is not a basic rate so figure out the
+-		 * best basic rate less than this rate and fill in
+-		 * the hole in the table
+-		 */
+-
+-		br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic;
+-
+-		if (br[rate] != 0)
+-			continue;
+-
+-		if (IS_OFDM(rate)) {
+-			/* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */
+-			if (rate >= WLC_RATE_24M)
+-				mandatory = WLC_RATE_24M;
+-			else if (rate >= WLC_RATE_12M)
+-				mandatory = WLC_RATE_12M;
+-			else
+-				mandatory = WLC_RATE_6M;
+-		} else {
+-			/* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */
+-			mandatory = rate;
+-		}
+-
+-		br[rate] = mandatory;
+-	}
+-}
+-
+-static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate)
+-{
+-	u8 phy_rate, index;
+-	u8 basic_phy_rate, basic_index;
+-	u16 dir_table, basic_table;
+-	u16 basic_ptr;
+-
+-	/* Shared memory address for the table we are reading */
+-	dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B;
+-
+-	/* Shared memory address for the table we are writing */
+-	basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B;
+-
+-	/*
+-	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
+-	 * the index into the rate table.
+-	 */
+-	phy_rate = rate_info[rate] & WLC_RATE_MASK;
+-	basic_phy_rate = rate_info[basic_rate] & WLC_RATE_MASK;
+-	index = phy_rate & 0xf;
+-	basic_index = basic_phy_rate & 0xf;
+-
+-	/* Find the SHM pointer to the ACK rate entry by looking in the
+-	 * Direct-map Table
+-	 */
+-	basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2));
+-
+-	/* Update the SHM BSS-basic-rate-set mapping table with the pointer
+-	 * to the correct basic rate for the given incoming rate
+-	 */
+-	wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr);
+-}
+-
+-static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		if (BAND_5G(wlc->band->bandtype))
+-			rs_dflt = &ofdm_mimo_rates;
+-		else
+-			rs_dflt = &cck_ofdm_mimo_rates;
+-	} else if (wlc->band->gmode)
+-		rs_dflt = &cck_ofdm_rates;
+-	else
+-		rs_dflt = &cck_rates;
+-
+-	return rs_dflt;
+-}
+-
+-void wlc_set_ratetable(struct wlc_info *wlc)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs;
+-	u8 rate, basic_rate;
+-	uint i;
+-
+-	rs_dflt = wlc_rateset_get_hwrs(wlc);
+-
+-	wlc_rateset_copy(rs_dflt, &rs);
+-	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+-
+-	/* walk the phy rate table and update SHM basic rate lookup table */
+-	for (i = 0; i < rs.count; i++) {
+-		rate = rs.rates[i] & WLC_RATE_MASK;
+-
+-		/* for a given rate WLC_BASIC_RATE returns the rate at
+-		 * which a response ACK/CTS should be sent.
+-		 */
+-		basic_rate = WLC_BASIC_RATE(wlc, rate);
+-		if (basic_rate == 0) {
+-			/* This should only happen if we are using a
+-			 * restricted rateset.
+-			 */
+-			basic_rate = rs.rates[0] & WLC_RATE_MASK;
+-		}
+-
+-		wlc_write_rate_shm(wlc, rate, basic_rate);
+-	}
+-}
+-
+-/*
+- * Return true if the specified rate is supported by the specified band.
+- * WLC_BAND_AUTO indicates the current band.
+- */
+-bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band,
+-		    bool verbose)
+-{
+-	wlc_rateset_t *hw_rateset;
+-	uint i;
+-
+-	if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) {
+-		hw_rateset = &wlc->band->hw_rateset;
+-	} else if (NBANDS(wlc) > 1) {
+-		hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset;
+-	} else {
+-		/* other band specified and we are a single band device */
+-		return false;
+-	}
+-
+-	/* check if this is a mimo rate */
+-	if (IS_MCS(rspec)) {
+-		if (!VALID_MCS((rspec & RSPEC_RATE_MASK)))
+-			goto error;
+-
+-		return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK));
+-	}
+-
+-	for (i = 0; i < hw_rateset->count; i++)
+-		if (hw_rateset->rates[i] == RSPEC2RATE(rspec))
+-			return true;
+- error:
+-	if (verbose) {
+-		wiphy_err(wlc->wiphy, "wl%d: wlc_valid_rate: rate spec 0x%x "
+-			  "not in hw_rateset\n", wlc->pub->unit, rspec);
+-	}
+-
+-	return false;
+-}
+-
+-static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap)
+-{
+-	uint i;
+-	struct wlcband *band;
+-
+-	for (i = 0; i < NBANDS(wlc); i++) {
+-		if (IS_SINGLEBAND_5G(wlc->deviceid))
+-			i = BAND_5G_INDEX;
+-		band = wlc->bandstate[i];
+-		if (band->bandtype == WLC_BAND_5G) {
+-			if ((bwcap == WLC_N_BW_40ALL)
+-			    || (bwcap == WLC_N_BW_20IN2G_40IN5G))
+-				band->mimo_cap_40 = true;
+-			else
+-				band->mimo_cap_40 = false;
+-		} else {
+-			if (bwcap == WLC_N_BW_40ALL)
+-				band->mimo_cap_40 = true;
+-			else
+-				band->mimo_cap_40 = false;
+-		}
+-	}
+-
+-	wlc->mimo_band_bwcap = bwcap;
+-}
+-
+-void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs;
+-	u8 rate;
+-	u16 entry_ptr;
+-	u8 plcp[D11_PHY_HDR_LEN];
+-	u16 dur, sifs;
+-	uint i;
+-
+-	sifs = SIFS(wlc->band);
+-
+-	rs_dflt = wlc_rateset_get_hwrs(wlc);
+-
+-	wlc_rateset_copy(rs_dflt, &rs);
+-	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
+-
+-	/* walk the phy rate table and update MAC core SHM basic rate table entries */
+-	for (i = 0; i < rs.count; i++) {
+-		rate = rs.rates[i] & WLC_RATE_MASK;
+-
+-		entry_ptr = wlc_rate_shm_offset(wlc, rate);
+-
+-		/* Calculate the Probe Response PLCP for the given rate */
+-		wlc_compute_plcp(wlc, rate, frame_len, plcp);
+-
+-		/* Calculate the duration of the Probe Response frame plus SIFS for the MAC */
+-		dur =
+-		    (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE,
+-						 frame_len);
+-		dur += sifs;
+-
+-		/* Update the SHM Rate Table entry Probe Response values */
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS,
+-			      (u16) (plcp[0] + (plcp[1] << 8)));
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2,
+-			      (u16) (plcp[2] + (plcp[3] << 8)));
+-		wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur);
+-	}
+-}
+-
+-/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
+- *
+- *	PLCP header is 6 bytes.
+- *	802.11 A3 header is 24 bytes.
+- *	Max beacon frame body template length is 112 bytes.
+- *	Max probe resp frame body template length is 110 bytes.
+- *
+- *      *len on input contains the max length of the packet available.
+- *
+- *	The *len value is set to the number of bytes in buf used, and starts with the PLCP
+- *	and included up to, but not including, the 4 byte FCS.
+- */
+-static void
+-wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec,
+-		     struct wlc_bsscfg *cfg, u16 *buf, int *len)
+-{
+-	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
+-	cck_phy_hdr_t *plcp;
+-	struct ieee80211_mgmt *h;
+-	int hdr_len, body_len;
+-
+-	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
+-		hdr_len = DOT11_MAC_HDR_LEN;
+-	else
+-		hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
+-	body_len = *len - hdr_len;	/* calc buffer size provided for frame body */
+-
+-	*len = hdr_len + body_len;	/* return actual size */
+-
+-	/* format PHY and MAC headers */
+-	memset((char *)buf, 0, hdr_len);
+-
+-	plcp = (cck_phy_hdr_t *) buf;
+-
+-	/* PLCP for Probe Response frames are filled in from core's rate table */
+-	if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) {
+-		/* fill in PLCP */
+-		wlc_compute_plcp(wlc, bcn_rspec,
+-				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
+-				 (u8 *) plcp);
+-
+-	}
+-	/* "Regular" and 16 MBSS but not for 4 MBSS */
+-	/* Update the phytxctl for the beacon based on the rspec */
+-	if (!SOFTBCN_ENAB(cfg))
+-		wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
+-
+-	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
+-		h = (struct ieee80211_mgmt *)&plcp[0];
+-	else
+-		h = (struct ieee80211_mgmt *)&plcp[1];
+-
+-	/* fill in 802.11 header */
+-	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
+-
+-	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
+-	/* A1 filled in by MAC for prb resp, broadcast for bcn */
+-	if (type == IEEE80211_STYPE_BEACON)
+-		memcpy(&h->da, &ether_bcast, ETH_ALEN);
+-	memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN);
+-	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
+-
+-	/* SEQ filled in by MAC */
+-
+-	return;
+-}
+-
+-int wlc_get_header_len()
+-{
+-	return TXOFF;
+-}
+-
+-/* Update a beacon for a particular BSS
+- * For MBSS, this updates the software template and sets "latest" to the index of the
+- * template updated.
+- * Otherwise, it updates the hardware template.
+- */
+-void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
+-{
+-	int len = BCN_TMPL_LEN;
+-
+-	/* Clear the soft intmask */
+-	wlc->defmacintmask &= ~MI_BCNTPL;
+-
+-	if (!cfg->up) {		/* Only allow updates on an UP bss */
+-		return;
+-	}
+-
+-	/* Optimize:  Some of if/else could be combined */
+-	if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) {
+-		/* Hardware beaconing for this config */
+-		u16 bcn[BCN_TMPL_LEN / 2];
+-		u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD;
+-		d11regs_t *regs = wlc->regs;
+-
+-		/* Check if both templates are in use, if so sched. an interrupt
+-		 *      that will call back into this routine
+-		 */
+-		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
+-			/* clear any previous status */
+-			W_REG(&regs->macintstatus, MI_BCNTPL);
+-		}
+-		/* Check that after scheduling the interrupt both of the
+-		 *      templates are still busy. if not clear the int. & remask
+-		 */
+-		if ((R_REG(&regs->maccommand) & both_valid) == both_valid) {
+-			wlc->defmacintmask |= MI_BCNTPL;
+-			return;
+-		}
+-
+-		wlc->bcn_rspec =
+-		    wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
+-		/* update the template and ucode shm */
+-		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
+-				     wlc->bcn_rspec, cfg, bcn, &len);
+-		wlc_write_hw_bcntemplates(wlc, bcn, len, false);
+-	}
+-}
+-
+-/*
+- * Update all beacons for the system.
+- */
+-void wlc_update_beacon(struct wlc_info *wlc)
+-{
+-	int idx;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	/* update AP or IBSS beacons */
+-	FOREACH_BSS(wlc, idx, bsscfg) {
+-		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+-			wlc_bss_update_beacon(wlc, bsscfg);
+-	}
+-}
+-
+-/* Write ssid into shared memory */
+-void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg)
+-{
+-	u8 *ssidptr = cfg->SSID;
+-	u16 base = M_SSID;
+-	u8 ssidbuf[IEEE80211_MAX_SSID_LEN];
+-
+-	/* padding the ssid with zero and copy it into shm */
+-	memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN);
+-	memcpy(ssidbuf, ssidptr, cfg->SSID_len);
+-
+-	wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN);
+-
+-	if (!MBSS_BCN_ENAB(cfg))
+-		wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len);
+-}
+-
+-void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend)
+-{
+-	int idx;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	/* update AP or IBSS probe responses */
+-	FOREACH_BSS(wlc, idx, bsscfg) {
+-		if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS))
+-			wlc_bss_update_probe_resp(wlc, bsscfg, suspend);
+-	}
+-}
+-
+-void
+-wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg,
+-			  bool suspend)
+-{
+-	u16 prb_resp[BCN_TMPL_LEN / 2];
+-	int len = BCN_TMPL_LEN;
+-
+-	/* write the probe response to hardware, or save in the config structure */
+-	if (!MBSS_PRB_ENAB(cfg)) {
+-
+-		/* create the probe response template */
+-		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg,
+-				     prb_resp, &len);
+-
+-		if (suspend)
+-			wlc_suspend_mac_and_wait(wlc);
+-
+-		/* write the probe response into the template region */
+-		wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
+-					    (len + 3) & ~3, prb_resp);
+-
+-		/* write the length of the probe response frame (+PLCP/-FCS) */
+-		wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len);
+-
+-		/* write the SSID and SSID length */
+-		wlc_shm_ssid_upd(wlc, cfg);
+-
+-		/*
+-		 * Write PLCP headers and durations for probe response frames at all rates.
+-		 * Use the actual frame length covered by the PLCP header for the call to
+-		 * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS.
+-		 */
+-		len += (-D11_PHY_HDR_LEN + FCS_LEN);
+-		wlc_mod_prb_rsp_rate_table(wlc, (u16) len);
+-
+-		if (suspend)
+-			wlc_enable_mac(wlc);
+-	} else {		/* Generating probe resp in sw; update local template */
+-		/* error: No software probe response support without MBSS */
+-	}
+-}
+-
+-/* prepares pdu for transmission. returns BCM error codes */
+-int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop)
+-{
+-	uint fifo;
+-	d11txh_t *txh;
+-	struct ieee80211_hdr *h;
+-	struct scb *scb;
+-
+-	txh = (d11txh_t *) (pdu->data);
+-	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
+-
+-	/* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */
+-	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
+-
+-	scb = NULL;
+-
+-	*fifop = fifo;
+-
+-	/* return if insufficient dma resources */
+-	if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
+-		/* Mark precedences related to this FIFO, unsendable */
+-		WLC_TX_FIFO_CLEAR(wlc, fifo);
+-		return -EBUSY;
+-	}
+-	return 0;
+-}
+-
+-/* init tx reported rate mechanism */
+-void wlc_reprate_init(struct wlc_info *wlc)
+-{
+-	int i;
+-	struct wlc_bsscfg *bsscfg;
+-
+-	FOREACH_BSS(wlc, i, bsscfg) {
+-		wlc_bsscfg_reprate_init(bsscfg);
+-	}
+-}
+-
+-/* per bsscfg init tx reported rate mechanism */
+-void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg)
+-{
+-	bsscfg->txrspecidx = 0;
+-	memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec));
+-}
+-
+-/* Retrieve a consolidated set of revision information,
+- * typically for the WLC_GET_REVINFO ioctl
+- */
+-int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len)
+-{
+-	wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf;
+-
+-	if (len < WL_REV_INFO_LEGACY_LENGTH)
+-		return -EOVERFLOW;
+-
+-	rinfo->vendorid = wlc->vendorid;
+-	rinfo->deviceid = wlc->deviceid;
+-	rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) |
+-	    (wlc->band->radioid << IDCODE_ID_SHIFT);
+-	rinfo->chiprev = wlc->pub->sih->chiprev;
+-	rinfo->corerev = wlc->pub->corerev;
+-	rinfo->boardid = wlc->pub->sih->boardtype;
+-	rinfo->boardvendor = wlc->pub->sih->boardvendor;
+-	rinfo->boardrev = wlc->pub->boardrev;
+-	rinfo->ucoderev = wlc->ucode_rev;
+-	rinfo->driverrev = EPI_VERSION_NUM;
+-	rinfo->bus = wlc->pub->sih->bustype;
+-	rinfo->chipnum = wlc->pub->sih->chip;
+-
+-	if (len >= (offsetof(wlc_rev_info_t, chippkg))) {
+-		rinfo->phytype = wlc->band->phytype;
+-		rinfo->phyrev = wlc->band->phyrev;
+-		rinfo->anarev = 0;	/* obsolete stuff, suppress */
+-	}
+-
+-	if (len >= sizeof(*rinfo)) {
+-		rinfo->chippkg = wlc->pub->sih->chippkg;
+-	}
+-
+-	return 0;
+-}
+-
+-void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs)
+-{
+-	wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype,
+-			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+-			    CHSPEC_WLC_BW(wlc->default_bss->chanspec),
+-			    wlc->stf->txstreams);
+-}
+-
+-static void wlc_bss_default_init(struct wlc_info *wlc)
+-{
+-	chanspec_t chanspec;
+-	struct wlcband *band;
+-	wlc_bss_info_t *bi = wlc->default_bss;
+-
+-	/* init default and target BSS with some sane initial values */
+-	memset((char *)(bi), 0, sizeof(wlc_bss_info_t));
+-	bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT :
+-	    BEACON_INTERVAL_DEFAULT;
+-	bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT :
+-	    DTIM_INTERVAL_DEFAULT;
+-
+-	/* fill the default channel as the first valid channel
+-	 * starting from the 2G channels
+-	 */
+-	chanspec = CH20MHZ_CHSPEC(1);
+-	wlc->home_chanspec = bi->chanspec = chanspec;
+-
+-	/* find the band of our default channel */
+-	band = wlc->band;
+-	if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec))
+-		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
+-
+-	/* init bss rates to the band specific default rate set */
+-	wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype,
+-			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+-			    CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams);
+-
+-	if (N_ENAB(wlc->pub))
+-		bi->flags |= WLC_BSS_HT;
+-}
+-
+-static ratespec_t
+-mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band,
+-		       u32 int_val)
+-{
+-	u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT;
+-	u8 rate = int_val & NRATE_RATE_MASK;
+-	ratespec_t rspec;
+-	bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE);
+-	bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT);
+-	bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY)
+-				  == NRATE_OVERRIDE_MCS_ONLY);
+-	int bcmerror = 0;
+-
+-	if (!ismcs) {
+-		return (ratespec_t) rate;
+-	}
+-
+-	/* validate the combination of rate/mcs/stf is allowed */
+-	if (N_ENAB(wlc->pub) && ismcs) {
+-		/* mcs only allowed when nmode */
+-		if (stf > PHY_TXC1_MODE_SDM) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
+-				 WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-
+-		/* mcs 32 is a special case, DUP mode 40 only */
+-		if (rate == 32) {
+-			if (!CHSPEC_IS40(wlc->home_chanspec) ||
+-			    ((stf != PHY_TXC1_MODE_SISO)
+-			     && (stf != PHY_TXC1_MODE_CDD))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
+-					  "32\n", WLCWLUNIT(wlc), __func__);
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-			/* mcs > 7 must use stf SDM */
+-		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
+-			/* mcs > 7 must use stf SDM */
+-			if (stf != PHY_TXC1_MODE_SDM) {
+-				BCMMSG(wlc->wiphy, "wl%d: enabling "
+-					 "SDM mode for mcs %d\n",
+-					 WLCWLUNIT(wlc), rate);
+-				stf = PHY_TXC1_MODE_SDM;
+-			}
+-		} else {
+-			/* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */
+-			if ((stf > PHY_TXC1_MODE_STBC) ||
+-			    (!WLC_STBC_CAP_PHY(wlc)
+-			     && (stf == PHY_TXC1_MODE_STBC))) {
+-				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
+-					  "\n", WLCWLUNIT(wlc), __func__);
+-				bcmerror = -EINVAL;
+-				goto done;
+-			}
+-		}
+-	} else if (IS_OFDM(rate)) {
+-		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
+-				  WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	} else if (IS_CCK(rate)) {
+-		if ((cur_band->bandtype != WLC_BAND_2G)
+-		    || (stf != PHY_TXC1_MODE_SISO)) {
+-			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
+-				  WLCWLUNIT(wlc), __func__);
+-			bcmerror = -EINVAL;
+-			goto done;
+-		}
+-	} else {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
+-			  WLCWLUNIT(wlc), __func__);
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-	/* make sure multiple antennae are available for non-siso rates */
+-	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
+-		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
+-			  "request\n", WLCWLUNIT(wlc), __func__);
+-		bcmerror = -EINVAL;
+-		goto done;
+-	}
+-
+-	rspec = rate;
+-	if (ismcs) {
+-		rspec |= RSPEC_MIMORATE;
+-		/* For STBC populate the STC field of the ratespec */
+-		if (stf == PHY_TXC1_MODE_STBC) {
+-			u8 stc;
+-			stc = 1;	/* Nss for single stream is always 1 */
+-			rspec |= (stc << RSPEC_STC_SHIFT);
+-		}
+-	}
+-
+-	rspec |= (stf << RSPEC_STF_SHIFT);
+-
+-	if (override_mcs_only)
+-		rspec |= RSPEC_OVERRIDE_MCS_ONLY;
+-
+-	if (issgi)
+-		rspec |= RSPEC_SHORT_GI;
+-
+-	if ((rate != 0)
+-	    && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) {
+-		return rate;
+-	}
+-
+-	return rspec;
+-done:
+-	return rate;
+-}
+-
+-/* formula:  IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */
+-static int
+-wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM,
+-		   bool writeToShm)
+-{
+-	int idle_busy_ratio_x_16 = 0;
+-	uint offset =
+-	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
+-	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
+-	if (duty_cycle > 100 || duty_cycle < 0) {
+-		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
+-			  wlc->pub->unit);
+-		return -EINVAL;
+-	}
+-	if (duty_cycle)
+-		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
+-	/* Only write to shared memory  when wl is up */
+-	if (writeToShm)
+-		wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16);
+-
+-	if (isOFDM)
+-		wlc->tx_duty_cycle_ofdm = (u16) duty_cycle;
+-	else
+-		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
+-
+-	return 0;
+-}
+-
+-/* Read a single u16 from shared memory.
+- * SHM 'offset' needs to be an even address
+- */
+-u16 wlc_read_shm(struct wlc_info *wlc, uint offset)
+-{
+-	return wlc_bmac_read_shm(wlc->hw, offset);
+-}
+-
+-/* Write a single u16 to shared memory.
+- * SHM 'offset' needs to be an even address
+- */
+-void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v)
+-{
+-	wlc_bmac_write_shm(wlc->hw, offset, v);
+-}
+-
+-/* Copy a buffer to shared memory.
+- * SHM 'offset' needs to be an even address and
+- * Buffer length 'len' must be an even number of bytes
+- */
+-void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len)
+-{
+-	/* offset and len need to be even */
+-	if (len <= 0 || (offset & 1) || (len & 1))
+-		return;
+-
+-	wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
+-
+-}
+-
+-/* wrapper BMAC functions to for HIGH driver access */
+-void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val)
+-{
+-	wlc_bmac_mctrl(wlc->hw, mask, val);
+-}
+-
+-void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands)
+-{
+-	wlc_bmac_mhf(wlc->hw, idx, mask, val, bands);
+-}
+-
+-int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks)
+-{
+-	return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks);
+-}
+-
+-void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len,
+-			    void *buf)
+-{
+-	wlc_bmac_write_template_ram(wlc->hw, offset, len, buf);
+-}
+-
+-void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
+-			       bool both)
+-{
+-	wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both);
+-}
+-
+-void
+-wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
+-		  const u8 *addr)
+-{
+-	wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr);
+-	if (match_reg_offset == RCM_BSSID_OFFSET)
+-		memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
+-}
+-
+-void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin)
+-{
+-	wlc->band->CWmin = newmin;
+-	wlc_bmac_set_cwmin(wlc->hw, newmin);
+-}
+-
+-void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax)
+-{
+-	wlc->band->CWmax = newmax;
+-	wlc_bmac_set_cwmax(wlc->hw, newmax);
+-}
+-
+-/* Search mem rw utilities */
+-
+-void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit)
+-{
+-	wlc_bmac_pllreq(wlc->hw, set, req_bit);
+-}
+-
+-void wlc_reset_bmac_done(struct wlc_info *wlc)
+-{
+-}
+-
+-/* check for the particular priority flow control bit being set */
+-bool
+-wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q,
+-			     int prio)
+-{
+-	uint prio_mask;
+-
+-	if (prio == ALLPRIO) {
+-		prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
+-	} else {
+-		prio_mask = NBITVAL(prio);
+-	}
+-
+-	return (q->stopped & prio_mask) == prio_mask;
+-}
+-
+-/* propagate the flow control to all interfaces using the given tx queue */
+-void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-		       bool on, int prio)
+-{
+-	uint prio_bits;
+-	uint cur_bits;
+-
+-	BCMMSG(wlc->wiphy, "flow control kicks in\n");
+-
+-	if (prio == ALLPRIO) {
+-		prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
+-	} else {
+-		prio_bits = NBITVAL(prio);
+-	}
+-
+-	cur_bits = qi->stopped & prio_bits;
+-
+-	/* Check for the case of no change and return early
+-	 * Otherwise update the bit and continue
+-	 */
+-	if (on) {
+-		if (cur_bits == prio_bits) {
+-			return;
+-		}
+-		mboolset(qi->stopped, prio_bits);
+-	} else {
+-		if (cur_bits == 0) {
+-			return;
+-		}
+-		mboolclr(qi->stopped, prio_bits);
+-	}
+-
+-	/* If there is a flow control override we will not change the external
+-	 * flow control state.
+-	 */
+-	if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) {
+-		return;
+-	}
+-
+-	wlc_txflowcontrol_signal(wlc, qi, on, prio);
+-}
+-
+-void
+-wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-			   bool on, uint override)
+-{
+-	uint prev_override;
+-
+-	prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
+-
+-	/* Update the flow control bits and do an early return if there is
+-	 * no change in the external flow control state.
+-	 */
+-	if (on) {
+-		mboolset(qi->stopped, override);
+-		/* if there was a previous override bit on, then setting this
+-		 * makes no difference.
+-		 */
+-		if (prev_override) {
+-			return;
+-		}
+-
+-		wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO);
+-	} else {
+-		mboolclr(qi->stopped, override);
+-		/* clearing an override bit will only make a difference for
+-		 * flow control if it was the only bit set. For any other
+-		 * override setting, just return
+-		 */
+-		if (prev_override != override) {
+-			return;
+-		}
+-
+-		if (qi->stopped == 0) {
+-			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+-		} else {
+-			int prio;
+-
+-			for (prio = MAXPRIO; prio >= 0; prio--) {
+-				if (!mboolisset(qi->stopped, NBITVAL(prio)))
+-					wlc_txflowcontrol_signal(wlc, qi, OFF,
+-								 prio);
+-			}
+-		}
+-	}
+-}
+-
+-static void wlc_txflowcontrol_reset(struct wlc_info *wlc)
+-{
+-	struct wlc_txq_info *qi;
+-
+-	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
+-		if (qi->stopped) {
+-			wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO);
+-			qi->stopped = 0;
+-		}
+-	}
+-}
+-
+-static void
+-wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on,
+-			 int prio)
+-{
+-	struct wlc_if *wlcif;
+-
+-	for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) {
+-		if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED)
+-			wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio);
+-	}
+-}
+-
+-static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc)
+-{
+-	struct wlc_txq_info *qi, *p;
+-
+-	qi = kzalloc(sizeof(struct wlc_txq_info), GFP_ATOMIC);
+-	if (qi != NULL) {
+-		/*
+-		 * Have enough room for control packets along with HI watermark
+-		 * Also, add room to txq for total psq packets if all the SCBs
+-		 * leave PS mode. The watermark for flowcontrol to OS packets
+-		 * will remain the same
+-		 */
+-		bcm_pktq_init(&qi->q, WLC_PREC_COUNT,
+-			  (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
+-			  + wlc->pub->psq_pkts_total);
+-
+-		/* add this queue to the the global list */
+-		p = wlc->tx_queues;
+-		if (p == NULL) {
+-			wlc->tx_queues = qi;
+-		} else {
+-			while (p->next != NULL)
+-				p = p->next;
+-			p->next = qi;
+-		}
+-	}
+-	return qi;
+-}
+-
+-static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi)
+-{
+-	struct wlc_txq_info *p;
+-
+-	if (qi == NULL)
+-		return;
+-
+-	/* remove the queue from the linked list */
+-	p = wlc->tx_queues;
+-	if (p == qi)
+-		wlc->tx_queues = p->next;
+-	else {
+-		while (p != NULL && p->next != qi)
+-			p = p->next;
+-		if (p != NULL)
+-			p->next = p->next->next;
+-	}
+-
+-	kfree(qi);
+-}
+-
+-/*
+- * Flag 'scan in progress' to withhold dynamic phy calibration
+- */
+-void wlc_scan_start(struct wlc_info *wlc)
+-{
+-	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true);
+-}
+-
+-void wlc_scan_stop(struct wlc_info *wlc)
+-{
+-	wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false);
+-}
+-
+-void wlc_associate_upd(struct wlc_info *wlc, bool state)
+-{
+-	wlc->pub->associated = state;
+-	wlc->cfg->associated = state;
+-}
+-
+-/*
+- * When a remote STA/AP is removed by Mac80211, or when it can no longer accept
+- * AMPDU traffic, packets pending in hardware have to be invalidated so that
+- * when later on hardware releases them, they can be handled appropriately.
+- */
+-void wlc_inval_dma_pkts(struct wlc_hw_info *hw,
+-			       struct ieee80211_sta *sta,
+-			       void (*dma_callback_fn))
+-{
+-	struct hnddma_pub *dmah;
+-	int i;
+-	for (i = 0; i < NFIFO; i++) {
+-		dmah = hw->di[i];
+-		if (dmah != NULL)
+-			dma_walk_packets(dmah, dma_callback_fn, sta);
+-	}
+-}
+-
+-int wlc_get_curband(struct wlc_info *wlc)
+-{
+-	return wlc->band->bandunit;
+-}
+-
+-void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
+-{
+-	/* flush packet queue when requested */
+-	if (drop)
+-		bcm_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+-
+-	/* wait for queue and DMA fifos to run dry */
+-	while (!pktq_empty(&wlc->pkt_queue->q) ||
+-	       TXPKTPENDTOT(wlc) > 0) {
+-		wl_msleep(wlc->wl, 1);
+-	}
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h
+deleted file mode 100644
+index fb48dfc..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h
++++ /dev/null
+@@ -1,939 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_h_
+-#define _wlc_h_
+-
+-#define MA_WINDOW_SZ		8	/* moving average window size */
+-#define	WL_HWRXOFF		38	/* chip rx buffer offset */
+-#define	INVCHANNEL		255	/* invalid channel */
+-#define	MAXCOREREV		28	/* max # supported core revisions (0 .. MAXCOREREV - 1) */
+-#define WLC_MAXMODULES		22	/* max #  wlc_module_register() calls */
+-
+-#define WLC_BITSCNT(x)	bcm_bitcount((u8 *)&(x), sizeof(u8))
+-
+-/* Maximum wait time for a MAC suspend */
+-#define	WLC_MAX_MAC_SUSPEND	83000	/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
+-
+-/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable
+- */
+-#define WLC_PRB_RESP_TIMEOUT	0	/* Disable probe response timeout */
+-
+-/* transmit buffer max headroom for protocol headers */
+-#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
+-
+-/* For managing scan result lists */
+-struct wlc_bss_list {
+-	uint count;
+-	bool beacon;		/* set for beacon, cleared for probe response */
+-	wlc_bss_info_t *ptrs[MAXBSS];
+-};
+-
+-#define	SW_TIMER_MAC_STAT_UPD		30	/* periodic MAC stats update */
+-
+-/* Double check that unsupported cores are not enabled */
+-#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
+-#error "Configuration for D11CONF includes unsupported versions."
+-#endif				/* Bad versions */
+-
+-#define	VALID_COREREV(corerev)	CONF_HAS(D11CONF, corerev)
+-
+-/* values for shortslot_override */
+-#define WLC_SHORTSLOT_AUTO	-1	/* Driver will manage Shortslot setting */
+-#define WLC_SHORTSLOT_OFF	0	/* Turn off short slot */
+-#define WLC_SHORTSLOT_ON	1	/* Turn on short slot */
+-
+-/* value for short/long and mixmode/greenfield preamble */
+-
+-#define WLC_LONG_PREAMBLE	(0)
+-#define WLC_SHORT_PREAMBLE	(1 << 0)
+-#define WLC_GF_PREAMBLE		(1 << 1)
+-#define WLC_MM_PREAMBLE		(1 << 2)
+-#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE))
+-
+-/* values for barker_preamble */
+-#define WLC_BARKER_SHORT_ALLOWED	0	/* Short pre-amble allowed */
+-
+-/* A fifo is full. Clear precedences related to that FIFO */
+-#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo])
+-
+-/* Fifo is NOT full. Enable precedences for that FIFO */
+-#define WLC_TX_FIFO_ENAB(wlc, fifo)  ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo])
+-
+-/* TxFrameID */
+-/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
+-/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
+-#define TXFID_QUEUE_MASK	0x0007	/* Bits 0-2 */
+-#define TXFID_SEQ_MASK		0x7FE0	/* Bits 5-15 */
+-#define TXFID_SEQ_SHIFT		5	/* Number of bit shifts */
+-#define	TXFID_RATE_PROBE_MASK	0x8000	/* Bit 15 for rate probe */
+-#define TXFID_RATE_MASK		0x0018	/* Mask for bits 3 and 4 */
+-#define TXFID_RATE_SHIFT	3	/* Shift 3 bits for rate mask */
+-
+-/* promote boardrev */
+-#define BOARDREV_PROMOTABLE	0xFF	/* from */
+-#define BOARDREV_PROMOTED	1	/* to */
+-
+-/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true
+- */
+-#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+-#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \
+-	((bsscfg)->wsec & WSEC_SWFLAG)))
+-
+-#define WLC_PORTOPEN(cfg) \
+-	(((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \
+-	(cfg)->wsec_portopen : true)
+-
+-#define PS_ALLOWED(wlc)	wlc_ps_allowed(wlc)
+-
+-#define DATA_BLOCK_TX_SUPR	(1 << 4)
+-
+-/* 802.1D Priority to TX FIFO number for wme */
+-extern const u8 prio2fifo[];
+-
+-/* Ucode MCTL_WAKE override bits */
+-#define WLC_WAKE_OVERRIDE_CLKCTL	0x01
+-#define WLC_WAKE_OVERRIDE_PHYREG	0x02
+-#define WLC_WAKE_OVERRIDE_MACSUSPEND	0x04
+-#define WLC_WAKE_OVERRIDE_TXFIFO	0x08
+-#define WLC_WAKE_OVERRIDE_FORCEFAST	0x10
+-
+-/* stuff pulled in from wlc.c */
+-
+-/* Interrupt bit error summary.  Don't include I_RU: we refill DMA at other
+- * times; and if we run out, constant I_RU interrupts may cause lockup.  We
+- * will still get error counts from rx0ovfl.
+- */
+-#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RO | I_XU)
+-/* default software intmasks */
+-#define	DEF_RXINTMASK	(I_RI)	/* enable rx int on rxfifo only */
+-#define	DEF_MACINTMASK	(MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
+-			 MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
+-			 MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
+-
+-#define	RETRY_SHORT_DEF			7	/* Default Short retry Limit */
+-#define	RETRY_SHORT_MAX			255	/* Maximum Short retry Limit */
+-#define	RETRY_LONG_DEF			4	/* Default Long retry count */
+-#define	RETRY_SHORT_FB			3	/* Short retry count for fallback rate */
+-#define	RETRY_LONG_FB			2	/* Long retry count for fallback rate */
+-
+-#define	MAXTXPKTS		6	/* max # pkts pending */
+-
+-/* frameburst */
+-#define	MAXTXFRAMEBURST		8	/* vanilla xpress mode: max frames/burst */
+-#define	MAXFRAMEBURST_TXOP	10000	/* Frameburst TXOP in usec */
+-
+-/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */
+-#define EDCF_SHORT_S            0
+-#define EDCF_SFB_S              4
+-#define EDCF_LONG_S             8
+-#define EDCF_LFB_S              12
+-#define EDCF_SHORT_M            BITFIELD_MASK(4)
+-#define EDCF_SFB_M              BITFIELD_MASK(4)
+-#define EDCF_LONG_M             BITFIELD_MASK(4)
+-#define EDCF_LFB_M              BITFIELD_MASK(4)
+-
+-#define WLC_WME_RETRY_SHORT_GET(wlc, ac)    GFIELD(wlc->wme_retries[ac], EDCF_SHORT)
+-#define WLC_WME_RETRY_SFB_GET(wlc, ac)      GFIELD(wlc->wme_retries[ac], EDCF_SFB)
+-#define WLC_WME_RETRY_LONG_GET(wlc, ac)     GFIELD(wlc->wme_retries[ac], EDCF_LONG)
+-#define WLC_WME_RETRY_LFB_GET(wlc, ac)      GFIELD(wlc->wme_retries[ac], EDCF_LFB)
+-
+-#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val))
+-#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val))
+-#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val))
+-#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \
+-	(wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val))
+-
+-/* PLL requests */
+-#define WLC_PLLREQ_SHARED	0x1	/* pll is shared on old chips */
+-#define WLC_PLLREQ_RADIO_MON	0x2	/* hold pll for radio monitor register checking */
+-#define WLC_PLLREQ_FLIP		0x4	/* hold/release pll for some short operation */
+-
+-/*
+- * Macros to check if AP or STA is active.
+- * AP Active means more than just configured: driver and BSS are "up";
+- * that is, we are beaconing/responding as an AP (aps_associated).
+- * STA Active similarly means the driver is up and a configured STA BSS
+- * is up: either associated (stas_associated) or trying.
+- *
+- * Macro definitions vary as per AP/STA ifdefs, allowing references to
+- * ifdef'd structure fields and constant values (0) for optimization.
+- * Make sure to enclose blocks of code such that any routines they
+- * reference can also be unused and optimized out by the linker.
+- */
+-/* NOTE: References structure fields defined in wlc.h */
+-#define AP_ACTIVE(wlc)	(0)
+-
+-/*
+- * Detect Card removed.
+- * Even checking an sbconfig register read will not false trigger when the core is in reset.
+- * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy
+- * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern
+- * (some platforms return all 0).
+- * If clocks are present, call the sb routine which will figure out if the device is removed.
+- */
+-#define DEVICEREMOVED(wlc)      \
+-	((wlc->hw->clk) ?   \
+-	((R_REG(&wlc->hw->regs->maccontrol) & \
+-	(MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \
+-	(ai_deviceremoved(wlc->hw->sih)))
+-
+-#define WLCWLUNIT(wlc)		((wlc)->pub->unit)
+-
+-struct wlc_protection {
+-	bool _g;		/* use g spec protection, driver internal */
+-	s8 g_override;	/* override for use of g spec protection */
+-	u8 gmode_user;	/* user config gmode, operating band->gmode is different */
+-	s8 overlap;		/* Overlap BSS/IBSS protection for both 11g and 11n */
+-	s8 nmode_user;	/* user config nmode, operating pub->nmode is different */
+-	s8 n_cfg;		/* use OFDM protection on MIMO frames */
+-	s8 n_cfg_override;	/* override for use of N protection */
+-	bool nongf;		/* non-GF present protection */
+-	s8 nongf_override;	/* override for use of GF protection */
+-	s8 n_pam_override;	/* override for preamble: MM or GF */
+-	bool n_obss;		/* indicated OBSS Non-HT STA present */
+-
+-	uint longpre_detect_timeout;	/* #sec until long preamble bcns gone */
+-	uint barker_detect_timeout;	/* #sec until bcns signaling Barker long preamble */
+-	/* only is gone */
+-	uint ofdm_ibss_timeout;	/* #sec until ofdm IBSS beacons gone */
+-	uint ofdm_ovlp_timeout;	/* #sec until ofdm overlapping BSS bcns gone */
+-	uint nonerp_ibss_timeout;	/* #sec until nonerp IBSS beacons gone */
+-	uint nonerp_ovlp_timeout;	/* #sec until nonerp overlapping BSS bcns gone */
+-	uint g_ibss_timeout;	/* #sec until bcns signaling Use_Protection gone */
+-	uint n_ibss_timeout;	/* #sec until bcns signaling Use_OFDM_Protection gone */
+-	uint ht20in40_ovlp_timeout;	/* #sec until 20MHz overlapping OPMODE gone */
+-	uint ht20in40_ibss_timeout;	/* #sec until 20MHz-only HT station bcns gone */
+-	uint non_gf_ibss_timeout;	/* #sec until non-GF bcns gone */
+-};
+-
+-/* anything affects the single/dual streams/antenna operation */
+-struct wlc_stf {
+-	u8 hw_txchain;	/* HW txchain bitmap cfg */
+-	u8 txchain;		/* txchain bitmap being used */
+-	u8 txstreams;	/* number of txchains being used */
+-
+-	u8 hw_rxchain;	/* HW rxchain bitmap cfg */
+-	u8 rxchain;		/* rxchain bitmap being used */
+-	u8 rxstreams;	/* number of rxchains being used */
+-
+-	u8 ant_rx_ovr;	/* rx antenna override */
+-	s8 txant;		/* userTx antenna setting */
+-	u16 phytxant;	/* phyTx antenna setting in txheader */
+-
+-	u8 ss_opmode;	/* singlestream Operational mode, 0:siso; 1:cdd */
+-	bool ss_algosel_auto;	/* if true, use wlc->stf->ss_algo_channel; */
+-	/* else use wlc->band->stf->ss_mode_band; */
+-	u16 ss_algo_channel;	/* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */
+-	u8 no_cddstbc;	/* stf override, 1: no CDD (or STBC) allowed */
+-
+-	u8 rxchain_restore_delay;	/* delay time to restore default rxchain */
+-
+-	s8 ldpc;		/* AUTO/ON/OFF ldpc cap supported */
+-	u8 txcore[MAX_STREAMS_SUPPORTED + 1];	/* bitmap of selected core for each Nsts */
+-	s8 spatial_policy;
+-};
+-
+-#define WLC_STF_SS_STBC_TX(wlc, scb) \
+-	(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \
+-	 (SCB_STBC_CAP((scb)) &&					\
+-	  (wlc)->band->band_stf_stbc_tx == AUTO &&			\
+-	  isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
+-
+-#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3))
+-
+-#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \
+-	WLCISLCNPHY(wlc->band))
+-
+-#define WLC_CHAN_PHYTYPE(x)     (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT)
+-#define WLC_CHAN_CHANNEL(x)     (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT)
+-#define WLC_RX_CHANNEL(rxh)	(WLC_CHAN_CHANNEL((rxh)->RxChan))
+-
+-/* wlc_bss_info flag bit values */
+-#define WLC_BSS_HT		0x0020	/* BSS is HT (MIMO) capable */
+-
+-/* Flags used in wlc_txq_info.stopped */
+-#define TXQ_STOP_FOR_PRIOFC_MASK	0x000000FF	/* per prio flow control bits */
+-#define TXQ_STOP_FOR_PKT_DRAIN		0x00000100	/* stop txq enqueue for packet drain */
+-#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL	0x00000200	/* stop txq enqueue for ampdu flow control */
+-
+-#define WLC_HT_WEP_RESTRICT	0x01	/* restrict HT with WEP */
+-#define WLC_HT_TKIP_RESTRICT	0x02	/* restrict HT with TKIP */
+-
+-/*
+- * core state (mac)
+- */
+-struct wlccore {
+-	uint coreidx;		/* # sb enumerated core */
+-
+-	/* fifo */
+-	uint *txavail[NFIFO];	/* # tx descriptors available */
+-	s16 txpktpend[NFIFO];	/* tx admission control */
+-
+-	macstat_t *macstat_snapshot;	/* mac hw prev read values */
+-};
+-
+-/*
+- * band state (phy+ana+radio)
+- */
+-struct wlcband {
+-	int bandtype;		/* WLC_BAND_2G, WLC_BAND_5G */
+-	uint bandunit;		/* bandstate[] index */
+-
+-	u16 phytype;		/* phytype */
+-	u16 phyrev;
+-	u16 radioid;
+-	u16 radiorev;
+-	wlc_phy_t *pi;		/* pointer to phy specific information */
+-	bool abgphy_encore;
+-
+-	u8 gmode;		/* currently active gmode (see wlioctl.h) */
+-
+-	struct scb *hwrs_scb;	/* permanent scb for hw rateset */
+-
+-	wlc_rateset_t defrateset;	/* band-specific copy of default_bss.rateset */
+-
+-	ratespec_t rspec_override;	/* 802.11 rate override */
+-	ratespec_t mrspec_override;	/* multicast rate override */
+-	u8 band_stf_ss_mode;	/* Configured STF type, 0:siso; 1:cdd */
+-	s8 band_stf_stbc_tx;	/* STBC TX 0:off; 1:force on; -1:auto */
+-	wlc_rateset_t hw_rateset;	/* rates supported by chip (phy-specific) */
+-	u8 basic_rate[WLC_MAXRATE + 1];	/* basic rates indexed by rate */
+-	bool mimo_cap_40;	/* 40 MHz cap enabled on this band */
+-	s8 antgain;		/* antenna gain from srom */
+-
+-	u16 CWmin;		/* The minimum size of contention window, in unit of aSlotTime */
+-	u16 CWmax;		/* The maximum size of contention window, in unit of aSlotTime */
+-	u16 bcntsfoff;	/* beacon tsf offset */
+-};
+-
+-/* tx completion callback takes 3 args */
+-typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg);
+-
+-struct pkt_cb {
+-	pkcb_fn_t fn;		/* function to call when tx frame completes */
+-	void *arg;		/* void arg for fn */
+-	u8 nextidx;		/* index of next call back if threading */
+-	bool entered;		/* recursion check */
+-};
+-
+-/* module control blocks */
+-struct modulecb {
+-	char name[32];		/* module name : NULL indicates empty array member */
+-	const bcm_iovar_t *iovars;	/* iovar table */
+-	void *hdl;		/* handle passed when handler 'doiovar' is called */
+-	watchdog_fn_t watchdog_fn;	/* watchdog handler */
+-	iovar_fn_t iovar_fn;	/* iovar handler */
+-	down_fn_t down_fn;	/* down handler. Note: the int returned
+-				 * by the down function is a count of the
+-				 * number of timers that could not be
+-				 * freed.
+-				 */
+-};
+-
+-/* dump control blocks */
+-struct dumpcb_s {
+-	const char *name;	/* dump name */
+-	dump_fn_t dump_fn;	/* 'wl dump' handler */
+-	void *dump_fn_arg;
+-	struct dumpcb_s *next;
+-};
+-
+-/* virtual interface */
+-struct wlc_if {
+-	struct wlc_if *next;
+-	u8 type;		/* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */
+-	u8 index;		/* assigned in wl_add_if(), index of the wlif if any,
+-				 * not necessarily corresponding to bsscfg._idx or
+-				 * AID2PVBMAP(scb).
+-				 */
+-	u8 flags;		/* flags for the interface */
+-	struct wl_if *wlif;		/* pointer to wlif */
+-	struct wlc_txq_info *qi;	/* pointer to associated tx queue */
+-	union {
+-		struct scb *scb;	/* pointer to scb if WLC_IFTYPE_WDS */
+-		struct wlc_bsscfg *bsscfg;	/* pointer to bsscfg if WLC_IFTYPE_BSS */
+-	} u;
+-};
+-
+-/* flags for the interface */
+-#define WLC_IF_LINKED		0x02	/* this interface is linked to a wl_if */
+-
+-struct wlc_hwband {
+-	int bandtype;		/* WLC_BAND_2G, WLC_BAND_5G */
+-	uint bandunit;		/* bandstate[] index */
+-	u16 mhfs[MHFMAX];	/* MHF array shadow */
+-	u8 bandhw_stf_ss_mode;	/* HW configured STF type, 0:siso; 1:cdd */
+-	u16 CWmin;
+-	u16 CWmax;
+-	u32 core_flags;
+-
+-	u16 phytype;		/* phytype */
+-	u16 phyrev;
+-	u16 radioid;
+-	u16 radiorev;
+-	wlc_phy_t *pi;		/* pointer to phy specific information */
+-	bool abgphy_encore;
+-};
+-
+-struct wlc_hw_info {
+-	bool _piomode;		/* true if pio mode */
+-	struct wlc_info *wlc;
+-
+-	/* fifo */
+-	struct hnddma_pub *di[NFIFO];	/* hnddma handles, per fifo */
+-
+-	uint unit;		/* device instance number */
+-
+-	/* version info */
+-	u16 vendorid;	/* PCI vendor id */
+-	u16 deviceid;	/* PCI device id */
+-	uint corerev;		/* core revision */
+-	u8 sromrev;		/* version # of the srom */
+-	u16 boardrev;	/* version # of particular board */
+-	u32 boardflags;	/* Board specific flags from srom */
+-	u32 boardflags2;	/* More board flags if sromrev >= 4 */
+-	u32 machwcap;	/* MAC capabilities */
+-	u32 machwcap_backup;	/* backup of machwcap */
+-	u16 ucode_dbgsel;	/* dbgsel for ucode debug(config gpio) */
+-
+-	si_t *sih;		/* SB handle (cookie for siutils calls) */
+-	char *vars;		/* "environment" name=value */
+-	uint vars_size;		/* size of vars, free vars on detach */
+-	d11regs_t *regs;	/* pointer to device registers */
+-	void *physhim;		/* phy shim layer handler */
+-	void *phy_sh;		/* pointer to shared phy state */
+-	struct wlc_hwband *band;/* pointer to active per-band state */
+-	struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */
+-	u16 bmac_phytxant;	/* cache of high phytxant state */
+-	bool shortslot;		/* currently using 11g ShortSlot timing */
+-	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
+-	u16 LRL;		/* 802.11 dot11LongRetryLimit */
+-	u16 SFBL;		/* Short Frame Rate Fallback Limit */
+-	u16 LFBL;		/* Long Frame Rate Fallback Limit */
+-
+-	bool up;		/* d11 hardware up and running */
+-	uint now;		/* # elapsed seconds */
+-	uint _nbands;		/* # bands supported */
+-	chanspec_t chanspec;	/* bmac chanspec shadow */
+-
+-	uint *txavail[NFIFO];	/* # tx descriptors available */
+-	u16 *xmtfifo_sz;	/* fifo size in 256B for each xmt fifo */
+-
+-	mbool pllreq;		/* pll requests to keep PLL on */
+-
+-	u8 suspended_fifos;	/* Which TX fifo to remain awake for */
+-	u32 maccontrol;	/* Cached value of maccontrol */
+-	uint mac_suspend_depth;	/* current depth of mac_suspend levels */
+-	u32 wake_override;	/* Various conditions to force MAC to WAKE mode */
+-	u32 mute_override;	/* Prevent ucode from sending beacons */
+-	u8 etheraddr[ETH_ALEN];	/* currently configured ethernet address */
+-	u32 led_gpio_mask;	/* LED GPIO Mask */
+-	bool noreset;		/* true= do not reset hw, used by WLC_OUT */
+-	bool forcefastclk;	/* true if the h/w is forcing the use of fast clk */
+-	bool clk;		/* core is out of reset and has clock */
+-	bool sbclk;		/* sb has clock */
+-	struct bmac_pmq *bmac_pmq; /*  bmac PM states derived from ucode PMQ */
+-	bool phyclk;		/* phy is out of reset and has clock */
+-	bool dma_lpbk;		/* core is in DMA loopback */
+-
+-	bool ucode_loaded;	/* true after ucode downloaded */
+-
+-
+-	u8 hw_stf_ss_opmode;	/* STF single stream operation mode */
+-	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
+-				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+-				 */
+-	u32 antsel_avail;	/*
+-				 * put struct antsel_info here if more info is
+-				 * needed
+-				 */
+-};
+-
+-/* TX Queue information
+- *
+- * Each flow of traffic out of the device has a TX Queue with independent
+- * flow control. Several interfaces may be associated with a single TX Queue
+- * if they belong to the same flow of traffic from the device. For multi-channel
+- * operation there are independent TX Queues for each channel.
+- */
+-struct wlc_txq_info {
+-	struct wlc_txq_info *next;
+-	struct pktq q;
+-	uint stopped;		/* tx flow control bits */
+-};
+-
+-/*
+- * Principal common (os-independent) software data structure.
+- */
+-struct wlc_info {
+-	struct wlc_pub *pub;		/* pointer to wlc public state */
+-	struct wl_info *wl;	/* pointer to os-specific private state */
+-	d11regs_t *regs;	/* pointer to device registers */
+-
+-	struct wlc_hw_info *hw;	/* HW related state used primarily by BMAC */
+-
+-	/* clock */
+-	int clkreq_override;	/* setting for clkreq for PCIE : Auto, 0, 1 */
+-	u16 fastpwrup_dly;	/* time in us needed to bring up d11 fast clock */
+-
+-	/* interrupt */
+-	u32 macintstatus;	/* bit channel between isr and dpc */
+-	u32 macintmask;	/* sw runtime master macintmask value */
+-	u32 defmacintmask;	/* default "on" macintmask value */
+-
+-	/* up and down */
+-	bool device_present;	/* (removable) device is present */
+-
+-	bool clk;		/* core is out of reset and has clock */
+-
+-	/* multiband */
+-	struct wlccore *core;	/* pointer to active io core */
+-	struct wlcband *band;	/* pointer to active per-band state */
+-	struct wlccore *corestate;	/* per-core state (one per hw core) */
+-	/* per-band state (one per phy/radio): */
+-	struct wlcband *bandstate[MAXBANDS];
+-
+-	bool war16165;		/* PCI slow clock 16165 war flag */
+-
+-	bool tx_suspended;	/* data fifos need to remain suspended */
+-
+-	uint txpend16165war;
+-
+-	/* packet queue */
+-	uint qvalid;		/* DirFrmQValid and BcMcFrmQValid */
+-
+-	/* Regulatory power limits */
+-	s8 txpwr_local_max;	/* regulatory local txpwr max */
+-	u8 txpwr_local_constraint;	/* local power contraint in dB */
+-
+-
+-	struct ampdu_info *ampdu;	/* ampdu module handler */
+-	struct antsel_info *asi;	/* antsel module handler */
+-	wlc_cm_info_t *cmi;	/* channel manager module handler */
+-
+-	void *btparam;		/* bus type specific cookie */
+-
+-	uint vars_size;		/* size of vars, free vars on detach */
+-
+-	u16 vendorid;	/* PCI vendor id */
+-	u16 deviceid;	/* PCI device id */
+-	uint ucode_rev;		/* microcode revision */
+-
+-	u32 machwcap;	/* MAC capabilities, BMAC shadow */
+-
+-	u8 perm_etheraddr[ETH_ALEN];	/* original sprom local ethernet address */
+-
+-	bool bandlocked;	/* disable auto multi-band switching */
+-	bool bandinit_pending;	/* track band init in auto band */
+-
+-	bool radio_monitor;	/* radio timer is running */
+-	bool down_override;	/* true=down */
+-	bool going_down;	/* down path intermediate variable */
+-
+-	bool mpc;		/* enable minimum power consumption */
+-	u8 mpc_dlycnt;	/* # of watchdog cnt before turn disable radio */
+-	u8 mpc_offcnt;	/* # of watchdog cnt that radio is disabled */
+-	u8 mpc_delay_off;	/* delay radio disable by # of watchdog cnt */
+-	u8 prev_non_delay_mpc;	/* prev state wlc_is_non_delay_mpc */
+-
+-	/* timer */
+-	struct wl_timer *wdtimer;	/* timer for watchdog routine */
+-	uint fast_timer;	/* Periodic timeout for 'fast' timer */
+-	uint slow_timer;	/* Periodic timeout for 'slow' timer */
+-	uint glacial_timer;	/* Periodic timeout for 'glacial' timer */
+-	uint phycal_mlo;	/* last time measurelow calibration was done */
+-	uint phycal_txpower;	/* last time txpower calibration was done */
+-
+-	struct wl_timer *radio_timer;	/* timer for hw radio button monitor routine */
+-	struct wl_timer *pspoll_timer;	/* periodic pspoll timer */
+-
+-	/* promiscuous */
+-	bool monitor;		/* monitor (MPDU sniffing) mode */
+-	bool bcnmisc_ibss;	/* bcns promisc mode override for IBSS */
+-	bool bcnmisc_scan;	/* bcns promisc mode override for scan */
+-	bool bcnmisc_monitor;	/* bcns promisc mode override for monitor */
+-
+-	u8 bcn_wait_prd;	/* max waiting period (for beacon) in 1024TU */
+-
+-	/* driver feature */
+-	bool _rifs;		/* enable per-packet rifs */
+-	s32 rifs_advert;	/* RIFS mode advertisement */
+-	s8 sgi_tx;		/* sgi tx */
+-	bool wet;		/* true if wireless ethernet bridging mode */
+-
+-	/* AP-STA synchronization, power save */
+-	bool check_for_unaligned_tbtt;	/* check unaligned tbtt flag */
+-	bool PM_override;	/* no power-save flag, override PM(user input) */
+-	bool PMenabled;		/* current power-management state (CAM or PS) */
+-	bool PMpending;		/* waiting for tx status with PM indicated set */
+-	bool PMblocked;		/* block any PSPolling in PS mode, used to buffer
+-				 * AP traffic, also used to indicate in progress
+-				 * of scan, rm, etc. off home channel activity.
+-				 */
+-	bool PSpoll;		/* whether there is an outstanding PS-Poll frame */
+-	u8 PM;		/* power-management mode (CAM, PS or FASTPS) */
+-	bool PMawakebcn;	/* bcn recvd during current waking state */
+-
+-	bool WME_PM_blocked;	/* Can STA go to PM when in WME Auto mode */
+-	bool wake;		/* host-specified PS-mode sleep state */
+-	u8 pspoll_prd;	/* pspoll interval in milliseconds */
+-	u8 bcn_li_bcn;	/* beacon listen interval in # beacons */
+-	u8 bcn_li_dtim;	/* beacon listen interval in # dtims */
+-
+-	bool WDarmed;		/* watchdog timer is armed */
+-	u32 WDlast;		/* last time wlc_watchdog() was called */
+-
+-	/* WME */
+-	ac_bitmap_t wme_dp;	/* Discard (oldest first) policy per AC */
+-	bool wme_apsd;		/* enable Advanced Power Save Delivery */
+-	ac_bitmap_t wme_admctl;	/* bit i set if AC i under admission control */
+-	u16 edcf_txop[AC_COUNT];	/* current txop for each ac */
+-	wme_param_ie_t wme_param_ie;	/* WME parameter info element, which on STA
+-					 * contains parameters in use locally, and on
+-					 * AP contains parameters advertised to STA
+-					 * in beacons and assoc responses.
+-					 */
+-	bool wme_prec_queuing;	/* enable/disable non-wme STA prec queuing */
+-	u16 wme_retries[AC_COUNT];	/* per-AC retry limits */
+-
+-	int vlan_mode;		/* OK to use 802.1Q Tags (ON, OFF, AUTO) */
+-	u16 tx_prec_map;	/* Precedence map based on HW FIFO space */
+-	u16 fifo2prec_map[NFIFO];	/* pointer to fifo2_prec map based on WME */
+-
+-	/*
+-	 * BSS Configurations set of BSS configurations, idx 0 is default and
+-	 * always valid
+-	 */
+-	struct wlc_bsscfg *bsscfg[WLC_MAXBSSCFG];
+-	struct wlc_bsscfg *cfg;	/* the primary bsscfg (can be AP or STA) */
+-	u8 stas_associated;	/* count of ASSOCIATED STA bsscfgs */
+-	u8 aps_associated;	/* count of UP AP bsscfgs */
+-	u8 block_datafifo;	/* prohibit posting frames to data fifos */
+-	bool bcmcfifo_drain;	/* TX_BCMC_FIFO is set to drain */
+-
+-	/* tx queue */
+-	struct wlc_txq_info *tx_queues;	/* common TX Queue list */
+-
+-	/* security */
+-	wsec_key_t *wsec_keys[WSEC_MAX_KEYS];	/* dynamic key storage */
+-	wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS];	/* default key storage */
+-	bool wsec_swkeys;	/* indicates that all keys should be
+-				 * treated as sw keys (used for debugging)
+-				 */
+-	struct modulecb *modulecb;
+-	struct dumpcb_s *dumpcb_head;
+-
+-	u8 mimoft;		/* SIGN or 11N */
+-	u8 mimo_band_bwcap;	/* bw cap per band type */
+-	s8 txburst_limit_override;	/* tx burst limit override */
+-	u16 txburst_limit;	/* tx burst limit value */
+-	s8 cck_40txbw;	/* 11N, cck tx b/w override when in 40MHZ mode */
+-	s8 ofdm_40txbw;	/* 11N, ofdm tx b/w override when in 40MHZ mode */
+-	s8 mimo_40txbw;	/* 11N, mimo tx b/w override when in 40MHZ mode */
+-	/* HT CAP IE being advertised by this node: */
+-	struct ieee80211_ht_cap ht_cap;
+-
+-	uint seckeys;		/* 54 key table shm address */
+-	uint tkmickeys;		/* 12 TKIP MIC key table shm address */
+-
+-	wlc_bss_info_t *default_bss;	/* configured BSS parameters */
+-
+-	u16 AID;		/* association ID */
+-	u16 counter;		/* per-sdu monotonically increasing counter */
+-	u16 mc_fid_counter;	/* BC/MC FIFO frame ID counter */
+-
+-	bool ibss_allowed;	/* false, all IBSS will be ignored during a scan
+-				 * and the driver will not allow the creation of
+-				 * an IBSS network
+-				 */
+-	bool ibss_coalesce_allowed;
+-
+-	char country_default[WLC_CNTRY_BUF_SZ];	/* saved country for leaving 802.11d
+-						 * auto-country mode
+-						 */
+-	char autocountry_default[WLC_CNTRY_BUF_SZ];	/* initial country for 802.11d
+-							 * auto-country mode
+-							 */
+-#ifdef BCMDBG
+-	bcm_tlv_t *country_ie_override;	/* debug override of announced Country IE */
+-#endif
+-
+-	u16 prb_resp_timeout;	/* do not send prb resp if request older than this,
+-					 * 0 = disable
+-					 */
+-
+-	wlc_rateset_t sup_rates_override;	/* use only these rates in 11g supported rates if
+-						 * specifed
+-						 */
+-
+-	chanspec_t home_chanspec;	/* shared home chanspec */
+-
+-	/* PHY parameters */
+-	chanspec_t chanspec;	/* target operational channel */
+-	u16 usr_fragthresh;	/* user configured fragmentation threshold */
+-	u16 fragthresh[NFIFO];	/* per-fifo fragmentation thresholds */
+-	u16 RTSThresh;	/* 802.11 dot11RTSThreshold */
+-	u16 SRL;		/* 802.11 dot11ShortRetryLimit */
+-	u16 LRL;		/* 802.11 dot11LongRetryLimit */
+-	u16 SFBL;		/* Short Frame Rate Fallback Limit */
+-	u16 LFBL;		/* Long Frame Rate Fallback Limit */
+-
+-	/* network config */
+-	bool shortpreamble;	/* currently operating with CCK ShortPreambles */
+-	bool shortslot;		/* currently using 11g ShortSlot timing */
+-	s8 barker_preamble;	/* current Barker Preamble Mode */
+-	s8 shortslot_override;	/* 11g ShortSlot override */
+-	bool include_legacy_erp;	/* include Legacy ERP info elt ID 47 as well as g ID 42 */
+-	bool barker_overlap_control;	/* true: be aware of overlapping BSSs for barker */
+-	bool ignore_bcns;	/* override: ignore non shortslot bcns in a 11g network */
+-	bool legacy_probe;	/* restricts probe requests to CCK rates */
+-
+-	struct wlc_protection *protection;
+-	s8 PLCPHdr_override;	/* 802.11b Preamble Type override */
+-
+-	struct wlc_stf *stf;
+-
+-	struct pkt_cb *pkt_callback;	/* tx completion callback handlers */
+-
+-	u32 txretried;	/* tx retried number in one msdu */
+-
+-	ratespec_t bcn_rspec;	/* save bcn ratespec purpose */
+-
+-	bool apsd_sta_usp;	/* Unscheduled Service Period in progress on STA */
+-	struct wl_timer *apsd_trigger_timer;	/* timer for wme apsd trigger frames */
+-	u32 apsd_trigger_timeout;	/* timeout value for apsd_trigger_timer (in ms)
+-					 * 0 == disable
+-					 */
+-	ac_bitmap_t apsd_trigger_ac;	/* Permissible Access Category in which APSD Null
+-					 * Trigger frames can be send
+-					 */
+-	u8 htphy_membership;	/* HT PHY membership */
+-
+-	bool _regulatory_domain;	/* 802.11d enabled? */
+-
+-	u8 mimops_PM;
+-
+-	u8 txpwr_percent;	/* power output percentage */
+-
+-	u8 ht_wsec_restriction;	/* the restriction of HT with TKIP or WEP */
+-
+-	uint tempsense_lasttime;
+-
+-	u16 tx_duty_cycle_ofdm;	/* maximum allowed duty cycle for OFDM */
+-	u16 tx_duty_cycle_cck;	/* maximum allowed duty cycle for CCK */
+-
+-	u16 next_bsscfg_ID;
+-
+-	struct wlc_if *wlcif_list;	/* linked list of wlc_if structs */
+-	struct wlc_txq_info *pkt_queue; /* txq for transmit packets */
+-	u32 mpc_dur;		/* total time (ms) in mpc mode except for the
+-				 * portion since radio is turned off last time
+-				 */
+-	u32 mpc_laston_ts;	/* timestamp (ms) when radio is turned off last
+-				 * time
+-				 */
+-	bool pr80838_war;
+-	uint hwrxoff;
+-	struct wiphy *wiphy;
+-};
+-
+-/* antsel module specific state */
+-struct antsel_info {
+-	struct wlc_info *wlc;	/* pointer to main wlc structure */
+-	struct wlc_pub *pub;		/* pointer to public fn */
+-	u8 antsel_type;	/* Type of boardlevel mimo antenna switch-logic
+-				 * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
+-				 */
+-	u8 antsel_antswitch;	/* board level antenna switch type */
+-	bool antsel_avail;	/* Ant selection availability (SROM based) */
+-	wlc_antselcfg_t antcfg_11n;	/* antenna configuration */
+-	wlc_antselcfg_t antcfg_cur;	/* current antenna config (auto) */
+-};
+-
+-#define	CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
+-#define	OTHERBANDUNIT(wlc)	((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
+-
+-#define IS_MBAND_UNLOCKED(wlc) \
+-	((NBANDS(wlc) > 1) && !(wlc)->bandlocked)
+-
+-#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi)
+-
+-/* sum the individual fifo tx pending packet counts */
+-#define	TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \
+-	(wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3])
+-#define TXPKTPENDGET(wlc, fifo)		((wlc)->core->txpktpend[(fifo)])
+-#define TXPKTPENDINC(wlc, fifo, val)	((wlc)->core->txpktpend[(fifo)] += (val))
+-#define TXPKTPENDDEC(wlc, fifo, val)	((wlc)->core->txpktpend[(fifo)] -= (val))
+-#define TXPKTPENDCLR(wlc, fifo)		((wlc)->core->txpktpend[(fifo)] = 0)
+-#define TXAVAIL(wlc, fifo)		(*(wlc)->core->txavail[(fifo)])
+-#define GETNEXTTXP(wlc, _queue)								\
+-		dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED)
+-
+-#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \
+-	((len1 == len2) && !memcmp(ssid1, ssid2, len1))
+-
+-extern void wlc_fatal_error(struct wlc_info *wlc);
+-extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc);
+-extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p);
+-extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2);
+-extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p,
+-		       bool commit, s8 txpktpend);
+-extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend);
+-extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
+-			uint prec);
+-extern void wlc_info_init(struct wlc_info *wlc, int unit);
+-extern void wlc_print_txstatus(tx_status_t *txs);
+-extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks);
+-extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len,
+-				   void *buf);
+-extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
+-				      bool both);
+-extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin);
+-extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax);
+-extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit);
+-extern void wlc_reset_bmac_done(struct wlc_info *wlc);
+-
+-#if defined(BCMDBG)
+-extern void wlc_print_rxh(d11rxhdr_t *rxh);
+-extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame,
+-			   d11txh_t *txh, d11rxhdr_t *rxh, uint len);
+-extern void wlc_print_txdesc(d11txh_t *txh);
+-#else
+-#define wlc_print_txdesc(a)
+-#endif
+-#if defined(BCMDBG)
+-extern void wlc_print_dot11_mac_hdr(u8 *buf, int len);
+-#endif
+-
+-extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit);
+-extern void wlc_coredisable(struct wlc_hw_info *wlc_hw);
+-
+-extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band,
+-			   bool verbose);
+-extern void wlc_ap_upd(struct wlc_info *wlc);
+-
+-/* helper functions */
+-extern void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg);
+-extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config);
+-
+-extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc);
+-extern void wlc_mac_bcn_promisc(struct wlc_info *wlc);
+-extern void wlc_mac_promisc(struct wlc_info *wlc);
+-extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi,
+-			      bool on, int prio);
+-extern void wlc_txflowcontrol_override(struct wlc_info *wlc,
+-				       struct wlc_txq_info *qi,
+-				       bool on, uint override);
+-extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc,
+-					 struct wlc_txq_info *qi, int prio);
+-extern void wlc_send_q(struct wlc_info *wlc);
+-extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo);
+-
+-extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec,
+-				uint mac_len);
+-extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec,
+-					 bool use_rspec, u16 mimo_ctlchbw);
+-extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only,
+-				     ratespec_t rts_rate, ratespec_t frame_rate,
+-				     u8 rts_preamble_type,
+-				     u8 frame_preamble_type, uint frame_len,
+-				     bool ba);
+-
+-extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs);
+-extern void wlc_inval_dma_pkts(struct wlc_hw_info *hw,
+-			       struct ieee80211_sta *sta,
+-			       void (*dma_callback_fn));
+-
+-#if defined(BCMDBG)
+-extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie,
+-			struct bcmstrbuf *b);
+-#endif
+-
+-extern void wlc_reprate_init(struct wlc_info *wlc);
+-extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg);
+-
+-/* Shared memory access */
+-extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v);
+-extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset);
+-extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf,
+-			   int len);
+-
+-extern void wlc_update_beacon(struct wlc_info *wlc);
+-extern void wlc_bss_update_beacon(struct wlc_info *wlc,
+-				  struct wlc_bsscfg *bsscfg);
+-
+-extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend);
+-extern void wlc_bss_update_probe_resp(struct wlc_info *wlc,
+-				      struct wlc_bsscfg *cfg, bool suspend);
+-
+-extern bool wlc_ismpc(struct wlc_info *wlc);
+-extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc);
+-extern void wlc_radio_mpc_upd(struct wlc_info *wlc);
+-extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt,
+-			 int prec);
+-extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q,
+-			      struct sk_buff *pkt, int prec, bool head);
+-extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec);
+-extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length,
+-			     u8 *plcp);
+-extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec,
+-				u8 preamble_type, uint mac_len);
+-
+-extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec);
+-
+-extern bool wlc_timers_init(struct wlc_info *wlc, int unit);
+-
+-extern const bcm_iovar_t wlc_iovars[];
+-
+-extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid,
+-		       const char *name, void *params, uint p_len, void *arg,
+-		       int len, int val_size, struct wlc_if *wlcif);
+-
+-#if defined(BCMDBG)
+-extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len);
+-#endif
+-
+-extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode);
+-extern void wlc_mimops_action_ht_send(struct wlc_info *wlc,
+-				      struct wlc_bsscfg *bsscfg,
+-				      u8 mimops_mode);
+-
+-extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot);
+-extern void wlc_set_bssid(struct wlc_bsscfg *cfg);
+-extern void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend);
+-
+-extern void wlc_set_ratetable(struct wlc_info *wlc);
+-extern int wlc_set_mac(struct wlc_bsscfg *cfg);
+-extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc,
+-					  ratespec_t bcn_rate);
+-extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len);
+-extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc,
+-					 wlc_rateset_t *rs);
+-extern void wlc_radio_disable(struct wlc_info *wlc);
+-extern void wlc_bcn_li_upd(struct wlc_info *wlc);
+-
+-extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len);
+-extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec);
+-extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt);
+-extern bool wlc_ps_allowed(struct wlc_info *wlc);
+-extern bool wlc_stay_awake(struct wlc_info *wlc);
+-extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe);
+-
+-#endif				/* _wlc_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
+deleted file mode 100644
+index 16fea02..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
++++ /dev/null
+@@ -1,243 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-/*
+- * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer.
+- *   WL driver can optinally call this translation layer to do some preprocessing, then reach PHY.
+- *   On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the
+- *   access to wlc_hw pointer.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbconfig.h>
+-#include <sbchipc.h>
+-#include <pcicfg.h>
+-#include <sbhnddma.h>
+-#include <hnddma.h>
+-#include <wlc_pmu.h>
+-
+-#include "wlc_types.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "d11.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "bcmsrom.h"
+-#include "wlc_key.h"
+-#include "wlc_bmac.h"
+-#include "wlc_phy_hal.h"
+-#include "wl_export.h"
+-#include "wlc_main.h"
+-#include "wlc_phy_shim.h"
+-
+-/* PHY SHIM module specific state */
+-struct wlc_phy_shim_info {
+-	struct wlc_hw_info *wlc_hw;	/* pointer to main wlc_hw structure */
+-	void *wlc;		/* pointer to main wlc structure */
+-	void *wl;		/* pointer to os-specific private state */
+-};
+-
+-wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw,
+-						       void *wl, void *wlc) {
+-	wlc_phy_shim_info_t *physhim = NULL;
+-
+-	physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC);
+-	if (!physhim) {
+-		wiphy_err(wlc_hw->wlc->wiphy,
+-			  "wl%d: wlc_phy_shim_attach: out of mem\n",
+-			  wlc_hw->unit);
+-		return NULL;
+-	}
+-	physhim->wlc_hw = wlc_hw;
+-	physhim->wlc = wlc;
+-	physhim->wl = wl;
+-
+-	return physhim;
+-}
+-
+-void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim)
+-{
+-	kfree(physhim);
+-}
+-
+-struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+-				     void (*fn) (void *arg), void *arg,
+-				     const char *name)
+-{
+-	return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name);
+-}
+-
+-void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+-{
+-	wl_free_timer(physhim->wl, (struct wl_timer *)t);
+-}
+-
+-void
+-wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms,
+-		int periodic)
+-{
+-	wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic);
+-}
+-
+-bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t)
+-{
+-	return wl_del_timer(physhim->wl, (struct wl_timer *)t);
+-}
+-
+-void wlapi_intrson(wlc_phy_shim_info_t *physhim)
+-{
+-	wl_intrson(physhim->wl);
+-}
+-
+-u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim)
+-{
+-	return wl_intrsoff(physhim->wl);
+-}
+-
+-void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask)
+-{
+-	wl_intrsrestore(physhim->wl, macintmask);
+-}
+-
+-void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v)
+-{
+-	wlc_bmac_write_shm(physhim->wlc_hw, offset, v);
+-}
+-
+-u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset)
+-{
+-	return wlc_bmac_read_shm(physhim->wlc_hw, offset);
+-}
+-
+-void
+-wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask,
+-	       u16 val, int bands)
+-{
+-	wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands);
+-}
+-
+-void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags)
+-{
+-	wlc_bmac_corereset(physhim->wlc_hw, flags);
+-}
+-
+-void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_suspend_mac_and_wait(physhim->wlc);
+-}
+-
+-void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode)
+-{
+-	wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode);
+-}
+-
+-void wlapi_enable_mac(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_enable_mac(physhim->wlc);
+-}
+-
+-void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val)
+-{
+-	wlc_bmac_mctrl(physhim->wlc_hw, mask, val);
+-}
+-
+-void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_bmac_phy_reset(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw)
+-{
+-	wlc_bmac_bw_set(physhim->wlc_hw, bw);
+-}
+-
+-u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim)
+-{
+-	return wlc_bmac_get_txant(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk)
+-{
+-	wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk);
+-}
+-
+-void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk)
+-{
+-	wlc_bmac_macphyclk_set(physhim->wlc_hw, clk);
+-}
+-
+-void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on)
+-{
+-	wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on);
+-}
+-
+-void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_bmac_core_phypll_reset(physhim->wlc_hw);
+-}
+-
+-void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG);
+-}
+-
+-void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim)
+-{
+-	wlc_ucode_wake_override_clear(physhim->wlc_hw,
+-				      WLC_WAKE_OVERRIDE_PHYREG);
+-}
+-
+-void
+-wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset,
+-			      int len, void *buf)
+-{
+-	wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf);
+-}
+-
+-u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate)
+-{
+-	return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate);
+-}
+-
+-void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim)
+-{
+-}
+-
+-void
+-wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf,
+-		      int len, u32 sel)
+-{
+-	wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
+-}
+-
+-void
+-wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf,
+-		    int l, u32 sel)
+-{
+-	wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
+deleted file mode 100644
+index c151a5d..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h
++++ /dev/null
+@@ -1,112 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_phy_shim_h_
+-#define _wlc_phy_shim_h_
+-
+-#define RADAR_TYPE_NONE		0	/* Radar type None */
+-#define RADAR_TYPE_ETSI_1	1	/* ETSI 1 Radar type */
+-#define RADAR_TYPE_ETSI_2	2	/* ETSI 2 Radar type */
+-#define RADAR_TYPE_ETSI_3	3	/* ETSI 3 Radar type */
+-#define RADAR_TYPE_ITU_E	4	/* ITU E Radar type */
+-#define RADAR_TYPE_ITU_K	5	/* ITU K Radar type */
+-#define RADAR_TYPE_UNCLASSIFIED	6	/* Unclassified Radar type  */
+-#define RADAR_TYPE_BIN5		7	/* long pulse radar type */
+-#define RADAR_TYPE_STG2 	8	/* staggered-2 radar */
+-#define RADAR_TYPE_STG3 	9	/* staggered-3 radar */
+-#define RADAR_TYPE_FRA		10	/* French radar */
+-
+-/* French radar pulse widths */
+-#define FRA_T1_20MHZ	52770
+-#define FRA_T2_20MHZ	61538
+-#define FRA_T3_20MHZ	66002
+-#define FRA_T1_40MHZ	105541
+-#define FRA_T2_40MHZ	123077
+-#define FRA_T3_40MHZ	132004
+-#define FRA_ERR_20MHZ	60
+-#define FRA_ERR_40MHZ	120
+-
+-#define ANTSEL_NA		0	/* No boardlevel selection available */
+-#define ANTSEL_2x4		1	/* 2x4 boardlevel selection available */
+-#define ANTSEL_2x3		2	/* 2x3 CB2 boardlevel selection available */
+-
+-/* Rx Antenna diversity control values */
+-#define	ANT_RX_DIV_FORCE_0		0	/* Use antenna 0 */
+-#define	ANT_RX_DIV_FORCE_1		1	/* Use antenna 1 */
+-#define	ANT_RX_DIV_START_1		2	/* Choose starting with 1 */
+-#define	ANT_RX_DIV_START_0		3	/* Choose starting with 0 */
+-#define	ANT_RX_DIV_ENABLE		3	/* APHY bbConfig Enable RX Diversity */
+-#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0	/* default antdiv setting */
+-
+-/* Forward declarations */
+-struct wlc_hw_info;
+-typedef struct wlc_phy_shim_info wlc_phy_shim_info_t;
+-
+-extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw,
+-						void *wl, void *wlc);
+-extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim);
+-
+-/* PHY to WL utility functions */
+-struct wlapi_timer;
+-extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim,
+-					    void (*fn) (void *arg), void *arg,
+-					    const char *name);
+-extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim,
+-			     struct wlapi_timer *t);
+-extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim,
+-			    struct wlapi_timer *t, uint ms, int periodic);
+-extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim,
+-			    struct wlapi_timer *t);
+-extern void wlapi_intrson(wlc_phy_shim_info_t *physhim);
+-extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim,
+-			       u32 macintmask);
+-
+-extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset,
+-				 u16 v);
+-extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset);
+-extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx,
+-			   u16 mask, u16 val, int bands);
+-extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags);
+-extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode);
+-extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask,
+-			     u32 val);
+-extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw);
+-extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk);
+-extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk);
+-extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on);
+-extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *
+-						      physhim);
+-extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *
+-							physhim);
+-extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o,
+-					  int len, void *buf);
+-extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim,
+-					 u8 rate);
+-extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim);
+-extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint,
+-				  void *buf, int, u32 sel);
+-extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint,
+-				const void *buf, int, u32);
+-
+-extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim,
+-				       u32 phy_mode);
+-extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim);
+-#endif				/* _wlc_phy_shim_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
+deleted file mode 100644
+index 82986bd..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
++++ /dev/null
+@@ -1,1929 +0,0 @@
+-/*
+- * Copyright (c) 2011 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/types.h>
+-#include <linux/delay.h>
+-#include <linux/io.h>
+-
+-#include <bcmdevs.h>
+-#include <sbchipc.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include "wlc_pmu.h"
+-
+-/*
+- * d11 slow to fast clock transition time in slow clock cycles
+- */
+-#define D11SCC_SLOW2FAST_TRANSITION	2
+-
+-/*
+- * external LPO crystal frequency
+- */
+-#define EXT_ILP_HZ 32768
+-
+-/*
+- * Duration for ILP clock frequency measurment in milliseconds
+- *
+- * remark: 1000 must be an integer multiple of this duration
+- */
+-#define ILP_CALC_DUR	10
+-
+-/*
+- * FVCO frequency
+- */
+-#define FVCO_880	880000	/* 880MHz */
+-#define FVCO_1760	1760000	/* 1760MHz */
+-#define FVCO_1440	1440000	/* 1440MHz */
+-#define FVCO_960	960000	/* 960MHz */
+-
+-/*
+- * PMU crystal table indices for 1440MHz fvco
+- */
+-#define PMU1_XTALTAB0_1440_12000K	0
+-#define PMU1_XTALTAB0_1440_13000K	1
+-#define PMU1_XTALTAB0_1440_14400K	2
+-#define PMU1_XTALTAB0_1440_15360K	3
+-#define PMU1_XTALTAB0_1440_16200K	4
+-#define PMU1_XTALTAB0_1440_16800K	5
+-#define PMU1_XTALTAB0_1440_19200K	6
+-#define PMU1_XTALTAB0_1440_19800K	7
+-#define PMU1_XTALTAB0_1440_20000K	8
+-#define PMU1_XTALTAB0_1440_25000K	9
+-#define PMU1_XTALTAB0_1440_26000K	10
+-#define PMU1_XTALTAB0_1440_30000K	11
+-#define PMU1_XTALTAB0_1440_37400K	12
+-#define PMU1_XTALTAB0_1440_38400K	13
+-#define PMU1_XTALTAB0_1440_40000K	14
+-#define PMU1_XTALTAB0_1440_48000K	15
+-
+-/*
+- * PMU crystal table indices for 960MHz fvco
+- */
+-#define PMU1_XTALTAB0_960_12000K	0
+-#define PMU1_XTALTAB0_960_13000K	1
+-#define PMU1_XTALTAB0_960_14400K	2
+-#define PMU1_XTALTAB0_960_15360K	3
+-#define PMU1_XTALTAB0_960_16200K	4
+-#define PMU1_XTALTAB0_960_16800K	5
+-#define PMU1_XTALTAB0_960_19200K	6
+-#define PMU1_XTALTAB0_960_19800K	7
+-#define PMU1_XTALTAB0_960_20000K	8
+-#define PMU1_XTALTAB0_960_25000K	9
+-#define PMU1_XTALTAB0_960_26000K	10
+-#define PMU1_XTALTAB0_960_30000K	11
+-#define PMU1_XTALTAB0_960_37400K	12
+-#define PMU1_XTALTAB0_960_38400K	13
+-#define PMU1_XTALTAB0_960_40000K	14
+-#define PMU1_XTALTAB0_960_48000K	15
+-
+-/*
+- * PMU crystal table indices for 880MHz fvco
+- */
+-#define PMU1_XTALTAB0_880_12000K	0
+-#define PMU1_XTALTAB0_880_13000K	1
+-#define PMU1_XTALTAB0_880_14400K	2
+-#define PMU1_XTALTAB0_880_15360K	3
+-#define PMU1_XTALTAB0_880_16200K	4
+-#define PMU1_XTALTAB0_880_16800K	5
+-#define PMU1_XTALTAB0_880_19200K	6
+-#define PMU1_XTALTAB0_880_19800K	7
+-#define PMU1_XTALTAB0_880_20000K	8
+-#define PMU1_XTALTAB0_880_24000K	9
+-#define PMU1_XTALTAB0_880_25000K	10
+-#define PMU1_XTALTAB0_880_26000K	11
+-#define PMU1_XTALTAB0_880_30000K	12
+-#define PMU1_XTALTAB0_880_37400K	13
+-#define PMU1_XTALTAB0_880_38400K	14
+-#define PMU1_XTALTAB0_880_40000K	15
+-
+-/*
+- * crystal frequency values
+- */
+-#define XTAL_FREQ_24000MHZ		24000
+-#define XTAL_FREQ_30000MHZ		30000
+-#define XTAL_FREQ_37400MHZ		37400
+-#define XTAL_FREQ_48000MHZ		48000
+-
+-/*
+- * Resource dependancies mask change action
+- *
+- * @RES_DEPEND_SET: Override the dependancies mask
+- * @RES_DEPEND_ADD: Add to the  dependancies mask
+- * @RES_DEPEND_REMOVE: Remove from the dependancies mask
+- */
+-#define RES_DEPEND_SET		0
+-#define RES_DEPEND_ADD		1
+-#define RES_DEPEND_REMOVE	-1
+-
+-/* d11 slow to fast clock transition time in slow clock cycles */
+-#define D11SCC_SLOW2FAST_TRANSITION	2
+-
+-/* Setup resource up/down timers */
+-typedef struct {
+-	u8 resnum;
+-	u16 updown;
+-} pmu_res_updown_t;
+-
+-/* Change resource dependancies masks */
+-typedef struct {
+-	u32 res_mask;	/* resources (chip specific) */
+-	s8 action;		/* action */
+-	u32 depend_mask;	/* changes to the dependancies mask */
+-	 bool(*filter) (si_t *sih);	/* action is taken when filter is NULL or return true */
+-} pmu_res_depend_t;
+-
+-/* setup pll and query clock speed */
+-typedef struct {
+-	u16 fref;
+-	u8 xf;
+-	u8 p1div;
+-	u8 p2div;
+-	u8 ndiv_int;
+-	u32 ndiv_frac;
+-} pmu1_xtaltab0_t;
+-
+-/*
+- * prototypes used in resource tables
+- */
+-static bool si_pmu_res_depfltr_bb(si_t *sih);
+-static bool si_pmu_res_depfltr_ncb(si_t *sih);
+-static bool si_pmu_res_depfltr_paldo(si_t *sih);
+-static bool si_pmu_res_depfltr_npaldo(si_t *sih);
+-
+-static const pmu_res_updown_t bcm4328a0_res_updown[] = {
+-	{
+-	RES4328_EXT_SWITCHER_PWM, 0x0101}, {
+-	RES4328_BB_SWITCHER_PWM, 0x1f01}, {
+-	RES4328_BB_SWITCHER_BURST, 0x010f}, {
+-	RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
+-	RES4328_ILP_REQUEST, 0x0202}, {
+-	RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
+-	RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
+-	RES4328_ROM_SWITCH, 0x0101}, {
+-	RES4328_PA_REF_LDO, 0x0f01}, {
+-	RES4328_RADIO_LDO, 0x0f01}, {
+-	RES4328_AFE_LDO, 0x0f01}, {
+-	RES4328_PLL_LDO, 0x0f01}, {
+-	RES4328_BG_FILTBYP, 0x0101}, {
+-	RES4328_TX_FILTBYP, 0x0101}, {
+-	RES4328_RX_FILTBYP, 0x0101}, {
+-	RES4328_XTAL_PU, 0x0101}, {
+-	RES4328_XTAL_EN, 0xa001}, {
+-	RES4328_BB_PLL_FILTBYP, 0x0101}, {
+-	RES4328_RF_PLL_FILTBYP, 0x0101}, {
+-	RES4328_BB_PLL_PU, 0x0701}
+-};
+-
+-static const pmu_res_depend_t bcm4328a0_res_depend[] = {
+-	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
+-	{
+-	PMURES_BIT(RES4328_ILP_REQUEST),
+-		    RES_DEPEND_SET,
+-		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
+-		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
+-	{
+-	RES4325_HT_AVAIL, 0x0300}, {
+-	RES4325_BBPLL_PWRSW_PU, 0x0101}, {
+-	RES4325_RFPLL_PWRSW_PU, 0x0101}, {
+-	RES4325_ALP_AVAIL, 0x0100}, {
+-	RES4325_XTAL_PU, 0x1000}, {
+-	RES4325_LNLDO1_PU, 0x0800}, {
+-	RES4325_CLDO_CBUCK_PWM, 0x0101}, {
+-	RES4325_CBUCK_PWM, 0x0803}
+-};
+-
+-static const pmu_res_updown_t bcm4325a0_res_updown[] = {
+-	{
+-	RES4325_XTAL_PU, 0x1501}
+-};
+-
+-static const pmu_res_depend_t bcm4325a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - remove BB BURST */
+-	{
+-	PMURES_BIT(RES4325_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
+-	    /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
+-	{
+-	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
+-		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4325_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
+-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+-	{
+-	PMURES_BIT(RES4325_ILP_REQUEST) |
+-		    PMURES_BIT(RES4325_ABUCK_BURST) |
+-		    PMURES_BIT(RES4325_ABUCK_PWM) |
+-		    PMURES_BIT(RES4325_LNLDO1_PU) |
+-		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
+-		    PMURES_BIT(RES4325_XTAL_PU) |
+-		    PMURES_BIT(RES4325_ALP_AVAIL) |
+-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
+-		    PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+-};
+-
+-static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
+-	{
+-	RES4315_HT_AVAIL, 0x0101}, {
+-	RES4315_XTAL_PU, 0x0100}, {
+-	RES4315_LNLDO1_PU, 0x0100}, {
+-	RES4315_PALDO_PU, 0x0100}, {
+-	RES4315_CLDO_PU, 0x0100}, {
+-	RES4315_CBUCK_PWM, 0x0100}, {
+-	RES4315_CBUCK_BURST, 0x0100}, {
+-	RES4315_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4315a0_res_updown[] = {
+-	{
+-	RES4315_XTAL_PU, 0x2501}
+-};
+-
+-static const pmu_res_depend_t bcm4315a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+-	{
+-	PMURES_BIT(RES4315_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
+-	    /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
+-	{
+-	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4315_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
+-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+-	{
+-	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
+-		    PMURES_BIT(RES4315_LNLDO1_PU) |
+-		    PMURES_BIT(RES4315_OTP_PU) |
+-		    PMURES_BIT(RES4315_LNLDO2_PU) |
+-		    PMURES_BIT(RES4315_XTAL_PU) |
+-		    PMURES_BIT(RES4315_ALP_AVAIL) |
+-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4315_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4315_CBUCK_BURST) |
+-		    PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+-};
+-
+-	/* 4329 specific. needs to come back this issue later */
+-static const pmu_res_updown_t bcm4329_res_updown[] = {
+-	{
+-	RES4329_XTAL_PU, 0x1501}
+-};
+-
+-static const pmu_res_depend_t bcm4329_res_depend[] = {
+-	/* Adjust HT Avail resource dependencies */
+-	{
+-	PMURES_BIT(RES4329_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4329_CBUCK_BURST) |
+-		    PMURES_BIT(RES4329_CBUCK_PWM) |
+-		    PMURES_BIT(RES4329_CLDO_PU) |
+-		    PMURES_BIT(RES4329_PALDO_PU) |
+-		    PMURES_BIT(RES4329_LNLDO1_PU) |
+-		    PMURES_BIT(RES4329_XTAL_PU) |
+-		    PMURES_BIT(RES4329_ALP_AVAIL) |
+-		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
+-		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
+-	{
+-	RES4319_HT_AVAIL, 0x0101}, {
+-	RES4319_XTAL_PU, 0x0100}, {
+-	RES4319_LNLDO1_PU, 0x0100}, {
+-	RES4319_PALDO_PU, 0x0100}, {
+-	RES4319_CLDO_PU, 0x0100}, {
+-	RES4319_CBUCK_PWM, 0x0100}, {
+-	RES4319_CBUCK_BURST, 0x0100}, {
+-	RES4319_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4319a0_res_updown[] = {
+-	{
+-	RES4319_XTAL_PU, 0x3f01}
+-};
+-
+-static const pmu_res_depend_t bcm4319a0_res_depend[] = {
+-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+-	{
+-	PMURES_BIT(RES4319_OTP_PU),
+-		    RES_DEPEND_REMOVE,
+-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
+-	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
+-	{
+-	PMURES_BIT(RES4319_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
+-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+-	{
+-	PMURES_BIT(RES4319_HT_AVAIL),
+-		    RES_DEPEND_ADD,
+-		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
+-		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
+-	{
+-	RES4336_HT_AVAIL, 0x0101}, {
+-	RES4336_XTAL_PU, 0x0100}, {
+-	RES4336_CLDO_PU, 0x0100}, {
+-	RES4336_CBUCK_PWM, 0x0100}, {
+-	RES4336_CBUCK_BURST, 0x0100}, {
+-	RES4336_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4336a0_res_updown[] = {
+-	{
+-	RES4336_HT_AVAIL, 0x0D01}
+-};
+-
+-static const pmu_res_depend_t bcm4336a0_res_depend[] = {
+-	/* Just a dummy entry for now */
+-	{
+-	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
+-};
+-
+-static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
+-	{
+-	RES4330_HT_AVAIL, 0x0101}, {
+-	RES4330_XTAL_PU, 0x0100}, {
+-	RES4330_CLDO_PU, 0x0100}, {
+-	RES4330_CBUCK_PWM, 0x0100}, {
+-	RES4330_CBUCK_BURST, 0x0100}, {
+-	RES4330_CBUCK_LPOM, 0x0100}
+-};
+-
+-static const pmu_res_updown_t bcm4330a0_res_updown[] = {
+-	{
+-	RES4330_HT_AVAIL, 0x0e02}
+-};
+-
+-static const pmu_res_depend_t bcm4330a0_res_depend[] = {
+-	/* Just a dummy entry for now */
+-	{
+-	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
+-};
+-
+-/* the following table is based on 1440Mhz fvco */
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
+-	{
+-	12000, 1, 1, 1, 0x78, 0x0}, {
+-	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
+-	14400, 3, 1, 1, 0x64, 0x0}, {
+-	15360, 4, 1, 1, 0x5D, 0xC00000}, {
+-	16200, 5, 1, 1, 0x58, 0xE38E38}, {
+-	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
+-	19200, 7, 1, 1, 0x4B, 0}, {
+-	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
+-	20000, 9, 1, 1, 0x48, 0x0}, {
+-	25000, 10, 1, 1, 0x39, 0x999999}, {
+-	26000, 11, 1, 1, 0x37, 0x627627}, {
+-	30000, 12, 1, 1, 0x30, 0x0}, {
+-	37400, 13, 2, 1, 0x4D, 0x15E76}, {
+-	38400, 13, 2, 1, 0x4B, 0x0}, {
+-	40000, 14, 2, 1, 0x48, 0x0}, {
+-	48000, 15, 2, 1, 0x3c, 0x0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
+-	{
+-	12000, 1, 1, 1, 0x50, 0x0}, {
+-	13000, 2, 1, 1, 0x49, 0xD89D89}, {
+-	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
+-	15360, 4, 1, 1, 0x3E, 0x800000}, {
+-	16200, 5, 1, 1, 0x39, 0x425ED0}, {
+-	16800, 6, 1, 1, 0x39, 0x249249}, {
+-	19200, 7, 1, 1, 0x32, 0x0}, {
+-	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
+-	20000, 9, 1, 1, 0x30, 0x0}, {
+-	25000, 10, 1, 1, 0x26, 0x666666}, {
+-	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
+-	30000, 12, 1, 1, 0x20, 0x0}, {
+-	37400, 13, 2, 1, 0x33, 0x563EF9}, {
+-	38400, 14, 2, 1, 0x32, 0x0}, {
+-	40000, 15, 2, 1, 0x30, 0x0}, {
+-	48000, 16, 2, 1, 0x28, 0x0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
+-	{
+-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+-	13000, 2, 1, 6, 0xb, 0x483483}, {
+-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+-	15360, 4, 1, 5, 0xb, 0x755555}, {
+-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+-	19200, 7, 1, 4, 0xb, 0x755555}, {
+-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+-	20000, 9, 1, 11, 0x4, 0x0}, {
+-	24000, 10, 3, 11, 0xa, 0x0}, {
+-	25000, 11, 5, 16, 0xb, 0x0}, {
+-	26000, 12, 1, 1, 0x21, 0xD89D89}, {
+-	30000, 13, 3, 8, 0xb, 0x0}, {
+-	37400, 14, 3, 1, 0x46, 0x969696}, {
+-	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
+-	40000, 16, 1, 2, 0xb, 0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-/* the following table is based on 880Mhz fvco */
+-static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
+-	{
+-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+-	13000, 2, 1, 6, 0xb, 0x483483}, {
+-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+-	15360, 4, 1, 5, 0xb, 0x755555}, {
+-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+-	19200, 7, 1, 4, 0xb, 0x755555}, {
+-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+-	20000, 9, 1, 11, 0x4, 0x0}, {
+-	24000, 10, 3, 11, 0xa, 0x0}, {
+-	25000, 11, 5, 16, 0xb, 0x0}, {
+-	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
+-	30000, 13, 3, 8, 0xb, 0x0}, {
+-	33600, 14, 1, 2, 0xd, 0x186186}, {
+-	38400, 15, 1, 2, 0xb, 0x755555}, {
+-	40000, 16, 1, 2, 0xb, 0}, {
+-	0, 0, 0, 0, 0, 0}
+-};
+-
+-/* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
+-static bool si_pmu_res_depfltr_bb(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_BUCKBOOST) != 0;
+-}
+-
+-/* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
+-static bool si_pmu_res_depfltr_ncb(si_t *sih)
+-{
+-
+-	return (sih->boardflags & BFL_NOCBUCK) != 0;
+-}
+-
+-/* true if the power topology uses the PALDO */
+-static bool si_pmu_res_depfltr_paldo(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_PALDO) != 0;
+-}
+-
+-/* true if the power topology doesn't use the PALDO */
+-static bool si_pmu_res_depfltr_npaldo(si_t *sih)
+-{
+-	return (sih->boardflags & BFL_PALDO) == 0;
+-}
+-
+-/* Return dependancies (direct or all/indirect) for the given resources */
+-static u32
+-si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
+-		bool all)
+-{
+-	u32 deps = 0;
+-	u32 i;
+-
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(rsrcs & PMURES_BIT(i)))
+-			continue;
+-		W_REG(&cc->res_table_sel, i);
+-		deps |= R_REG(&cc->res_dep_mask);
+-	}
+-
+-	return !all ? deps : (deps
+-			      ? (deps |
+-				 si_pmu_res_deps(sih, cc, deps,
+-						 true)) : 0);
+-}
+-
+-/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
+-static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
+-{
+-	u32 min_mask = 0, max_mask = 0;
+-	uint rsrcs;
+-	char *val;
+-
+-	/* # resources */
+-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+-
+-	/* determine min/max rsrc masks */
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		/* ??? */
+-		break;
+-
+-	case BCM4329_CHIP_ID:
+-		/* 4329 spedific issue. Needs to come back this issue later */
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4329_CLDO_PU);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0x3ff63e;
+-		break;
+-	case BCM4319_CHIP_ID:
+-		/* We only need a few resources to be kept on all the time */
+-		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
+-		    PMURES_BIT(RES4319_CLDO_PU);
+-
+-		/* Allow everything else to be turned on upon requests */
+-		max_mask = ~(~0 << rsrcs);
+-		break;
+-	case BCM4336_CHIP_ID:
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
+-		    | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
+-		    | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0x1ffffff;
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* Down to save the power. */
+-		min_mask =
+-		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
+-		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
+-		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
+-		/* Allow (but don't require) PLL to turn on */
+-		max_mask = 0xfffffff;
+-		break;
+-
+-	case BCM4313_CHIP_ID:
+-		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
+-		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
+-		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
+-		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
+-		max_mask = 0xffff;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Apply nvram override to min mask */
+-	val = getvar(NULL, "rmin");
+-	if (val != NULL) {
+-		min_mask = (u32) simple_strtoul(val, NULL, 0);
+-	}
+-	/* Apply nvram override to max mask */
+-	val = getvar(NULL, "rmax");
+-	if (val != NULL) {
+-		max_mask = (u32) simple_strtoul(val, NULL, 0);
+-	}
+-
+-	*pmin = min_mask;
+-	*pmax = max_mask;
+-}
+-
+-/* Return up time in ILP cycles for the given resource. */
+-static uint
+-si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
+-	u32 deps;
+-	uint up, i, dup, dmax;
+-	u32 min_mask = 0, max_mask = 0;
+-
+-	/* uptime of resource 'rsrc' */
+-	W_REG(&cc->res_table_sel, rsrc);
+-	up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
+-
+-	/* direct dependancies of resource 'rsrc' */
+-	deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(deps & PMURES_BIT(i)))
+-			continue;
+-		deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
+-	}
+-	si_pmu_res_masks(sih, &min_mask, &max_mask);
+-	deps &= ~min_mask;
+-
+-	/* max uptime of direct dependancies */
+-	dmax = 0;
+-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+-		if (!(deps & PMURES_BIT(i)))
+-			continue;
+-		dup = si_pmu_res_uptime(sih, cc, (u8) i);
+-		if (dmax < dup)
+-			dmax = dup;
+-	}
+-
+-	return up + dmax + PMURES_UP_TRANSITION;
+-}
+-
+-static void
+-si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
+-{
+-	u32 tmp = 0;
+-	u8 phypll_offset = 0;
+-	u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
+-	u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
+-
+-	switch (sih->chip) {
+-	case BCM5357_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-
+-		/*
+-		 * BCM5357 needs to touch PLL1_PLLCTL[02],
+-		 * so offset PLL0_PLLCTL[02] by 6
+-		 */
+-		phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
+-
+-		/* RMW only the P1 divider */
+-		W_REG(&cc->pllcontrol_addr,
+-		      PMU1_PLL0_PLLCTL0 + phypll_offset);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
+-		tmp |=
+-		    (bcm5357_bcm43236_p1div[spuravoid] <<
+-		     PMU1_PLL0_PC0_P1DIV_SHIFT);
+-		W_REG(&cc->pllcontrol_data, tmp);
+-
+-		/* RMW only the int feedback divider */
+-		W_REG(&cc->pllcontrol_addr,
+-		      PMU1_PLL0_PLLCTL2 + phypll_offset);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
+-		tmp |=
+-		    (bcm5357_bcm43236_ndiv[spuravoid]) <<
+-		    PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM4331_CHIP_ID:
+-		if (spuravoid == 2) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0FC00a08);
+-		} else if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100014);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000a08);
+-		}
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500010);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x000C0C06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x2001E920);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100010);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x000c0c06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000a08);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x200005c0);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		}
+-		tmp = 1 << 10;
+-		break;
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x11100008);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x0c000c06);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-		W_REG(&cc->pllcontrol_data, 0x03000a08);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-		W_REG(&cc->pllcontrol_data, 0x00000000);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		W_REG(&cc->pllcontrol_data, 0x200005c0);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888855);
+-
+-		tmp = 1 << 10;
+-		break;
+-
+-	case BCM4716_CHIP_ID:
+-	case BCM4748_CHIP_ID:
+-	case BCM47162_CHIP_ID:
+-		if (spuravoid == 1) {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11500060);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x080C0C06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x0F600000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x2001E924);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		} else {
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-			W_REG(&cc->pllcontrol_data, 0x11100060);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-			W_REG(&cc->pllcontrol_data, 0x080c0c06);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x03000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-			W_REG(&cc->pllcontrol_data, 0x00000000);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-			W_REG(&cc->pllcontrol_data, 0x200005c0);
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-			W_REG(&cc->pllcontrol_data, 0x88888815);
+-		}
+-
+-		tmp = 3 << 9;
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x11100070);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x1014140a);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888854);
+-
+-		if (spuravoid == 1) {
+-			/* spur_avoid ON, so enable 41/82/164Mhz clock mode */
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x05201828);
+-		} else {
+-			/* enable 40/80/160Mhz clock mode */
+-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-			W_REG(&cc->pllcontrol_data, 0x05001828);
+-		}
+-		break;
+-	case BCM4336_CHIP_ID:
+-		/* Looks like these are only for default xtal freq 26MHz */
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-		W_REG(&cc->pllcontrol_data, 0x02100020);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-		W_REG(&cc->pllcontrol_data, 0x01240C0C);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		W_REG(&cc->pllcontrol_data, 0x202C2820);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		W_REG(&cc->pllcontrol_data, 0x88888825);
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-		if (spuravoid == 1)
+-			W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
+-		else
+-			W_REG(&cc->pllcontrol_data, 0x00762762);
+-
+-		tmp = PCTL_PLL_PLLCTL_UPD;
+-		break;
+-
+-	default:
+-		/* bail out */
+-		return;
+-	}
+-
+-	tmp |= R_REG(&cc->pmucontrol);
+-	W_REG(&cc->pmucontrol, tmp);
+-}
+-
+-/* select default xtal frequency for each chip */
+-static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Default to 38400Khz */
+-		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
+-	case BCM4319_CHIP_ID:
+-		/* Default to 30000Khz */
+-		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
+-	case BCM4336_CHIP_ID:
+-		/* Default to 26000Khz */
+-		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
+-	case BCM4330_CHIP_ID:
+-		/* Default to 37400Khz */
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
+-		else
+-			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
+-	default:
+-		break;
+-	}
+-	return NULL;
+-}
+-
+-/* select xtal table for each chip */
+-static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return pmu1_xtaltab0_880_4329;
+-	case BCM4319_CHIP_ID:
+-		return pmu1_xtaltab0_1440;
+-	case BCM4336_CHIP_ID:
+-		return pmu1_xtaltab0_960;
+-	case BCM4330_CHIP_ID:
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return pmu1_xtaltab0_960;
+-		else
+-			return pmu1_xtaltab0_1440;
+-	default:
+-		break;
+-	}
+-	return NULL;
+-}
+-
+-/* query alp/xtal clock frequency */
+-static u32
+-si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
+-{
+-	const pmu1_xtaltab0_t *xt;
+-	u32 xf;
+-
+-	/* Find the frequency in the table */
+-	xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+-	    PCTL_XTALFREQ_SHIFT;
+-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+-		if (xt->xf == xf)
+-			break;
+-	/* Could not find it so assign a default value */
+-	if (xt == NULL || xt->fref == 0)
+-		xt = si_pmu1_xtaldef0(sih);
+-	return xt->fref * 1000;
+-}
+-
+-/* select default pll fvco for each chip */
+-static u32 si_pmu1_pllfvco0(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		return FVCO_880;
+-	case BCM4319_CHIP_ID:
+-		return FVCO_1440;
+-	case BCM4336_CHIP_ID:
+-		return FVCO_960;
+-	case BCM4330_CHIP_ID:
+-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-			return FVCO_960;
+-		else
+-			return FVCO_1440;
+-	default:
+-		break;
+-	}
+-	return 0;
+-}
+-
+-static void si_pmu_set_4330_plldivs(si_t *sih)
+-{
+-	u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
+-	u32 m1div, m2div, m3div, m4div, m5div, m6div;
+-	u32 pllc1, pllc2;
+-
+-	m2div = m3div = m4div = m6div = FVCO / 80;
+-	m5div = FVCO / 160;
+-
+-	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+-		m1div = FVCO / 80;
+-	else
+-		m1div = FVCO / 90;
+-	pllc1 =
+-	    (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
+-						    PMU1_PLL0_PC1_M2DIV_SHIFT) |
+-	    (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
+-						    PMU1_PLL0_PC1_M4DIV_SHIFT);
+-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
+-
+-	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
+-	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
+-	pllc2 |=
+-	    ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
+-	     (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
+-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
+-}
+-
+-/* Set up PLL registers in the PMU as per the crystal speed.
+- * XtalFreq field in pmucontrol register being 0 indicates the PLL
+- * is not programmed and the h/w default is assumed to work, in which
+- * case the xtal frequency is unknown to the s/w so we need to call
+- * si_pmu1_xtaldef0() wherever it is needed to return a default value.
+- */
+-static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
+-{
+-	const pmu1_xtaltab0_t *xt;
+-	u32 tmp;
+-	u32 buf_strength = 0;
+-	u8 ndiv_mode = 1;
+-
+-	/* Use h/w default PLL config */
+-	if (xtal == 0) {
+-		return;
+-	}
+-
+-	/* Find the frequency in the table */
+-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+-		if (xt->fref == xtal)
+-			break;
+-
+-	/* Check current PLL state, bail out if it has been programmed or
+-	 * we don't know how to program it.
+-	 */
+-	if (xt == NULL || xt->fref == 0) {
+-		return;
+-	}
+-	/* for 4319 bootloader already programs the PLL but bootloader does not
+-	 * program the PLL4 and PLL5. So Skip this check for 4319
+-	 */
+-	if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+-	      PCTL_XTALFREQ_SHIFT) == xt->xf) &&
+-	    !((sih->chip == BCM4319_CHIP_ID)
+-	      || (sih->chip == BCM4330_CHIP_ID)))
+-		return;
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Change the BBPLL drive strength to 8 for all channels */
+-		buf_strength = 0x888888;
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+-			  PMURES_BIT(RES4329_HT_AVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+-			  PMURES_BIT(RES4329_HT_AVAIL)));
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		if (xt->fref == 38400)
+-			tmp = 0x200024C0;
+-		else if (xt->fref == 37400)
+-			tmp = 0x20004500;
+-		else if (xt->fref == 26000)
+-			tmp = 0x200024C0;
+-		else
+-			tmp = 0x200005C0;	/* Chip Dflt Settings */
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		tmp =
+-		    R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
+-		if ((xt->fref == 38400) || (xt->fref == 37400)
+-		    || (xt->fref == 26000))
+-			tmp |= 0x15;
+-		else
+-			tmp |= 0x25;	/* Chip Dflt Settings */
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		/* Change the BBPLL drive strength to 2 for all channels */
+-		buf_strength = 0x222222;
+-
+-		/* Make sure the PLL is off */
+-		/* WAR65104: Disable the HT_AVAIL resource first and then
+-		 * after a delay (more than downtime for HT_AVAIL) remove the
+-		 * BBPLL resource; backplane clock moves to ALP from HT.
+-		 */
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4319_HT_AVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4319_HT_AVAIL)));
+-
+-		udelay(100);
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+-
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+-		tmp = 0x200005c0;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-		break;
+-
+-	case BCM4336_CHIP_ID:
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4336_HT_AVAIL) |
+-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4336_HT_AVAIL) |
+-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		AND_REG(&cc->min_res_mask,
+-			~(PMURES_BIT(RES4330_HT_AVAIL) |
+-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+-		AND_REG(&cc->max_res_mask,
+-			~(PMURES_BIT(RES4330_HT_AVAIL) |
+-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+-		udelay(100);
+-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+-			 PMU_MAX_TRANSITION_DLY);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	/* Write p1div and p2div to pllcontrol[0] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+-	tmp = R_REG(&cc->pllcontrol_data) &
+-	    ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
+-	tmp |=
+-	    ((xt->
+-	      p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
+-	    ((xt->
+-	      p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	if ((sih->chip == BCM4330_CHIP_ID))
+-		si_pmu_set_4330_plldivs(sih);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID)
+-	    && (sih->chiprev == 0)) {
+-
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+-		tmp = R_REG(&cc->pllcontrol_data);
+-		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
+-		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
+-		W_REG(&cc->pllcontrol_data, tmp);
+-	}
+-	if ((sih->chip == BCM4319_CHIP_ID) ||
+-	    (sih->chip == BCM4336_CHIP_ID) ||
+-	    (sih->chip == BCM4330_CHIP_ID))
+-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
+-	else
+-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
+-
+-	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+-	tmp = R_REG(&cc->pllcontrol_data) &
+-	    ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
+-	tmp |=
+-	    ((xt->
+-	      ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
+-	     PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
+-					      PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
+-					     PMU1_PLL0_PC2_NDIV_MODE_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	/* Write ndiv_frac to pllcontrol[3] */
+-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+-	tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
+-	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
+-		PMU1_PLL0_PC3_NDIV_FRAC_MASK);
+-	W_REG(&cc->pllcontrol_data, tmp);
+-
+-	/* Write clock driving strength to pllcontrol[5] */
+-	if (buf_strength) {
+-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+-		tmp =
+-		    R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
+-		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
+-		W_REG(&cc->pllcontrol_data, tmp);
+-	}
+-
+-	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
+-	 * to be updated.
+-	 */
+-	if ((sih->chip == BCM4319_CHIP_ID)
+-	    && (xt->fref != XTAL_FREQ_30000MHZ)) {
+-		W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
+-		tmp =
+-		    R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
+-		if (xt->fref == XTAL_FREQ_24000MHZ) {
+-			tmp |=
+-			    (CCTL_4319USB_24MHZ_PLL_SEL <<
+-			     CCTL_4319USB_XTAL_SEL_SHIFT);
+-		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
+-			tmp |=
+-			    (CCTL_4319USB_48MHZ_PLL_SEL <<
+-			     CCTL_4319USB_XTAL_SEL_SHIFT);
+-		}
+-		W_REG(&cc->chipcontrol_data, tmp);
+-	}
+-
+-	/* Flush deferred pll control registers writes */
+-	if (sih->pmurev >= 2)
+-		OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
+-
+-	/* Write XtalFreq. Set the divisor also. */
+-	tmp = R_REG(&cc->pmucontrol) &
+-	    ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
+-	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+-		PCTL_ILP_DIV_MASK) |
+-	    ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID)
+-	    && sih->chiprev == 0) {
+-		/* clear the htstretch before clearing HTReqEn */
+-		AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
+-		tmp &= ~PCTL_HT_REQ_EN;
+-	}
+-
+-	W_REG(&cc->pmucontrol, tmp);
+-}
+-
+-u32 si_pmu_ilp_clock(si_t *sih)
+-{
+-	static u32 ilpcycles_per_sec;
+-
+-	if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
+-		return ILP_CLOCK;
+-
+-	if (ilpcycles_per_sec == 0) {
+-		u32 start, end, delta;
+-		u32 origidx = ai_coreidx(sih);
+-		chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
+-		start = R_REG(&cc->pmutimer);
+-		mdelay(ILP_CALC_DUR);
+-		end = R_REG(&cc->pmutimer);
+-		delta = end - start;
+-		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
+-		ai_setcoreidx(sih, origidx);
+-	}
+-
+-	return ilpcycles_per_sec;
+-}
+-
+-void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
+-{
+-	u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
+-	u8 addr = 0;
+-
+-	switch (sih->chip) {
+-	case BCM4336_CHIP_ID:
+-		switch (ldo) {
+-		case SET_LDO_VOLTAGE_CLDO_PWM:
+-			addr = 4;
+-			rc_shift = 1;
+-			mask = 0xf;
+-			break;
+-		case SET_LDO_VOLTAGE_CLDO_BURST:
+-			addr = 4;
+-			rc_shift = 5;
+-			mask = 0xf;
+-			break;
+-		case SET_LDO_VOLTAGE_LNLDO1:
+-			addr = 4;
+-			rc_shift = 17;
+-			mask = 0xf;
+-			break;
+-		default:
+-			return;
+-		}
+-		break;
+-	case BCM4330_CHIP_ID:
+-		switch (ldo) {
+-		case SET_LDO_VOLTAGE_CBUCK_PWM:
+-			addr = 3;
+-			rc_shift = 0;
+-			mask = 0x1f;
+-			break;
+-		default:
+-			return;
+-		}
+-		break;
+-	default:
+-		return;
+-	}
+-
+-	shift = sr_cntl_shift + rc_shift;
+-
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
+-		   ~0, addr);
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
+-		   mask << shift, (voltage & mask) << shift);
+-}
+-
+-u16 si_pmu_fast_pwrup_delay(si_t *sih)
+-{
+-	uint delay = PMU_MAX_TRANSITION_DLY;
+-	chipcregs_t *cc;
+-	uint origidx;
+-#ifdef BCMDBG
+-	char chn[8];
+-	chn[0] = 0;		/* to suppress compile error */
+-#endif
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-	case BCM4313_CHIP_ID:
+-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+-		break;
+-	case BCM4329_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	case BCM4319_CHIP_ID:
+-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+-		break;
+-	case BCM4336_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	case BCM4330_CHIP_ID:
+-		if (ISSIM_ENAB(sih))
+-			delay = 70;
+-		else {
+-			u32 ilp = si_pmu_ilp_clock(sih);
+-			delay =
+-			    (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
+-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+-							      1) / ilp);
+-			delay = (11 * delay) / 10;
+-		}
+-		break;
+-	default:
+-		break;
+-	}
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-
+-	return (u16) delay;
+-}
+-
+-void si_pmu_sprom_enable(si_t *sih, bool enable)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* Read/write a chipcontrol reg */
+-u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, chipcontrol_data), mask, val);
+-}
+-
+-/* Read/write a regcontrol reg */
+-u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, regcontrol_data), mask, val);
+-}
+-
+-/* Read/write a pllcontrol reg */
+-u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
+-		   reg);
+-	return ai_corereg(sih, SI_CC_IDX,
+-			  offsetof(chipcregs_t, pllcontrol_data), mask, val);
+-}
+-
+-/* PMU PLL update */
+-void si_pmu_pllupd(si_t *sih)
+-{
+-	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
+-		   PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
+-}
+-
+-/* query alp/xtal clock frequency */
+-u32 si_pmu_alp_clock(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 clock = ALP_CLOCK;
+-
+-	/* bail out with default */
+-	if (!PMUCTL_ENAB(sih))
+-		return clock;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-	case BCM4716_CHIP_ID:
+-	case BCM4748_CHIP_ID:
+-	case BCM47162_CHIP_ID:
+-	case BCM4313_CHIP_ID:
+-	case BCM5357_CHIP_ID:
+-		/* always 20Mhz */
+-		clock = 20000 * 1000;
+-		break;
+-	case BCM4329_CHIP_ID:
+-	case BCM4319_CHIP_ID:
+-	case BCM4336_CHIP_ID:
+-	case BCM4330_CHIP_ID:
+-
+-		clock = si_pmu1_alpclk0(sih, cc);
+-		break;
+-	case BCM5356_CHIP_ID:
+-		/* always 25Mhz */
+-		clock = 25000 * 1000;
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-	return clock;
+-}
+-
+-void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
+-{
+-	chipcregs_t *cc;
+-	uint origidx, intr_val;
+-	u32 tmp = 0;
+-
+-	/* Remember original core before switch to chipc */
+-	cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
+-					    &intr_val);
+-
+-	/* force the HT off  */
+-	if (sih->chip == BCM4336_CHIP_ID) {
+-		tmp = R_REG(&cc->max_res_mask);
+-		tmp &= ~RES4336_HT_AVAIL;
+-		W_REG(&cc->max_res_mask, tmp);
+-		/* wait for the ht to really go away */
+-		SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
+-			 10000);
+-	}
+-
+-	/* update the pll changes */
+-	si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
+-
+-	/* enable HT back on  */
+-	if (sih->chip == BCM4336_CHIP_ID) {
+-		tmp = R_REG(&cc->max_res_mask);
+-		tmp |= RES4336_HT_AVAIL;
+-		W_REG(&cc->max_res_mask, tmp);
+-	}
+-
+-	/* Return to original core */
+-	ai_restore_core(sih, origidx, intr_val);
+-}
+-
+-/* initialize PMU */
+-void si_pmu_init(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	if (sih->pmurev == 1)
+-		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
+-	else if (sih->pmurev >= 2)
+-		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
+-
+-	if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
+-		/* Fix for 4329b0 bad LPOM state. */
+-		W_REG(&cc->regcontrol_addr, 2);
+-		OR_REG(&cc->regcontrol_data, 0x100);
+-
+-		W_REG(&cc->regcontrol_addr, 3);
+-		OR_REG(&cc->regcontrol_data, 0x4);
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU chip controls and other chip level stuff */
+-void si_pmu_chip_init(si_t *sih)
+-{
+-	uint origidx;
+-
+-	/* Gate off SPROM clock and chip select signals */
+-	si_pmu_sprom_enable(sih, false);
+-
+-	/* Remember original core */
+-	origidx = ai_coreidx(sih);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU switch/regulators */
+-void si_pmu_swreg_init(si_t *sih)
+-{
+-	switch (sih->chip) {
+-	case BCM4336_CHIP_ID:
+-		/* Reduce CLDO PWM output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
+-		/* Reduce CLDO BURST output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
+-				       0xe);
+-		/* Reduce LNLDO1 output voltage to 1.2V */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
+-		if (sih->chiprev == 0)
+-			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
+-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
+-		break;
+-	default:
+-		break;
+-	}
+-}
+-
+-/* initialize PLL */
+-void si_pmu_pll_init(si_t *sih, uint xtalfreq)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		if (xtalfreq == 0)
+-			xtalfreq = 38400;
+-		si_pmu1_pllinit0(sih, cc, xtalfreq);
+-		break;
+-	case BCM4313_CHIP_ID:
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-	case BCM4331_CHIP_ID:
+-	case BCM6362_CHIP_ID:
+-		/* ??? */
+-		break;
+-	case BCM4319_CHIP_ID:
+-	case BCM4336_CHIP_ID:
+-	case BCM4330_CHIP_ID:
+-		si_pmu1_pllinit0(sih, cc, xtalfreq);
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-/* initialize PMU resources */
+-void si_pmu_res_init(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	const pmu_res_updown_t *pmu_res_updown_table = NULL;
+-	uint pmu_res_updown_table_sz = 0;
+-	const pmu_res_depend_t *pmu_res_depend_table = NULL;
+-	uint pmu_res_depend_table_sz = 0;
+-	u32 min_mask = 0, max_mask = 0;
+-	char name[8], *val;
+-	uint i, rsrcs;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = NULL;
+-			pmu_res_updown_table_sz = 0;
+-		} else {
+-			pmu_res_updown_table = bcm4329_res_updown;
+-			pmu_res_updown_table_sz =
+-				ARRAY_SIZE(bcm4329_res_updown);
+-		}
+-		/* Optimize resources dependencies */
+-		pmu_res_depend_table = bcm4329_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
+-		break;
+-
+-	case BCM4319_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4319a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4319a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4319a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4319a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4319a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
+-		break;
+-
+-	case BCM4336_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4336a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4336a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4336a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4336a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4336a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
+-		break;
+-
+-	case BCM4330_CHIP_ID:
+-		/* Optimize resources up/down timers */
+-		if (ISSIM_ENAB(sih)) {
+-			pmu_res_updown_table = bcm4330a0_res_updown_qt;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4330a0_res_updown_qt);
+-		} else {
+-			pmu_res_updown_table = bcm4330a0_res_updown;
+-			pmu_res_updown_table_sz =
+-			    ARRAY_SIZE(bcm4330a0_res_updown);
+-		}
+-		/* Optimize resources dependancies masks */
+-		pmu_res_depend_table = bcm4330a0_res_depend;
+-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
+-		break;
+-
+-	default:
+-		break;
+-	}
+-
+-	/* # resources */
+-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+-
+-	/* Program up/down timers */
+-	while (pmu_res_updown_table_sz--) {
+-		W_REG(&cc->res_table_sel,
+-		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
+-		W_REG(&cc->res_updn_timer,
+-		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
+-	}
+-	/* Apply nvram overrides to up/down timers */
+-	for (i = 0; i < rsrcs; i++) {
+-		snprintf(name, sizeof(name), "r%dt", i);
+-		val = getvar(NULL, name);
+-		if (val == NULL)
+-			continue;
+-		W_REG(&cc->res_table_sel, (u32) i);
+-		W_REG(&cc->res_updn_timer,
+-		      (u32) simple_strtoul(val, NULL, 0));
+-	}
+-
+-	/* Program resource dependencies table */
+-	while (pmu_res_depend_table_sz--) {
+-		if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
+-		    && !(pmu_res_depend_table[pmu_res_depend_table_sz].
+-			 filter) (sih))
+-			continue;
+-		for (i = 0; i < rsrcs; i++) {
+-			if ((pmu_res_depend_table[pmu_res_depend_table_sz].
+-			     res_mask & PMURES_BIT(i)) == 0)
+-				continue;
+-			W_REG(&cc->res_table_sel, i);
+-			switch (pmu_res_depend_table[pmu_res_depend_table_sz].
+-				action) {
+-			case RES_DEPEND_SET:
+-				W_REG(&cc->res_dep_mask,
+-				      pmu_res_depend_table
+-				      [pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			case RES_DEPEND_ADD:
+-				OR_REG(&cc->res_dep_mask,
+-				       pmu_res_depend_table
+-				       [pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			case RES_DEPEND_REMOVE:
+-				AND_REG(&cc->res_dep_mask,
+-					~pmu_res_depend_table
+-					[pmu_res_depend_table_sz].depend_mask);
+-				break;
+-			default:
+-				break;
+-			}
+-		}
+-	}
+-	/* Apply nvram overrides to dependancies masks */
+-	for (i = 0; i < rsrcs; i++) {
+-		snprintf(name, sizeof(name), "r%dd", i);
+-		val = getvar(NULL, name);
+-		if (val == NULL)
+-			continue;
+-		W_REG(&cc->res_table_sel, (u32) i);
+-		W_REG(&cc->res_dep_mask,
+-		      (u32) simple_strtoul(val, NULL, 0));
+-	}
+-
+-	/* Determine min/max rsrc masks */
+-	si_pmu_res_masks(sih, &min_mask, &max_mask);
+-
+-	/* It is required to program max_mask first and then min_mask */
+-
+-	/* Program max resource mask */
+-
+-	if (max_mask)
+-		W_REG(&cc->max_res_mask, max_mask);
+-
+-	/* Program min resource mask */
+-
+-	if (min_mask)
+-		W_REG(&cc->min_res_mask, min_mask);
+-
+-	/* Add some delay; allow resources to come up and settle. */
+-	mdelay(2);
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+-
+-u32 si_pmu_measure_alpclk(si_t *sih)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 alp_khz;
+-
+-	if (sih->pmurev < 10)
+-		return 0;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
+-		u32 ilp_ctr, alp_hz;
+-
+-		/*
+-		 * Enable the reg to measure the freq,
+-		 * in case it was disabled before
+-		 */
+-		W_REG(&cc->pmu_xtalfreq,
+-		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
+-
+-		/* Delay for well over 4 ILP clocks */
+-		udelay(1000);
+-
+-		/* Read the latched number of ALP ticks per 4 ILP ticks */
+-		ilp_ctr =
+-		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
+-
+-		/*
+-		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
+-		 * bit to save power
+-		 */
+-		W_REG(&cc->pmu_xtalfreq, 0);
+-
+-		/* Calculate ALP frequency */
+-		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
+-
+-		/*
+-		 * Round to nearest 100KHz, and at
+-		 * the same time convert to KHz
+-		 */
+-		alp_khz = (alp_hz + 50000) / 100000 * 100;
+-	} else
+-		alp_khz = 0;
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-
+-	return alp_khz;
+-}
+-
+-bool si_pmu_is_otp_powered(si_t *sih)
+-{
+-	uint idx;
+-	chipcregs_t *cc;
+-	bool st;
+-
+-	/* Remember original core before switch to chipc */
+-	idx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4319_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4336_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
+-		    != 0;
+-		break;
+-	case BCM4330_CHIP_ID:
+-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
+-		    != 0;
+-		break;
+-
+-		/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
+-		 * Use OTP_INIT command to reset/refresh state.
+-		 */
+-	case BCM43224_CHIP_ID:
+-	case BCM43225_CHIP_ID:
+-	case BCM43421_CHIP_ID:
+-	case BCM43236_CHIP_ID:
+-	case BCM43235_CHIP_ID:
+-	case BCM43238_CHIP_ID:
+-		st = true;
+-		break;
+-	default:
+-		st = true;
+-		break;
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, idx);
+-	return st;
+-}
+-
+-/* power up/down OTP through PMU resources */
+-void si_pmu_otp_power(si_t *sih, bool on)
+-{
+-	chipcregs_t *cc;
+-	uint origidx;
+-	u32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
+-
+-	/* Don't do anything if OTP is disabled */
+-	if (ai_is_otp_disabled(sih))
+-		return;
+-
+-	/* Remember original core before switch to chipc */
+-	origidx = ai_coreidx(sih);
+-	cc = ai_setcoreidx(sih, SI_CC_IDX);
+-
+-	switch (sih->chip) {
+-	case BCM4329_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4329_OTP_PU);
+-		break;
+-	case BCM4319_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4319_OTP_PU);
+-		break;
+-	case BCM4336_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4336_OTP_PU);
+-		break;
+-	case BCM4330_CHIP_ID:
+-		rsrcs = PMURES_BIT(RES4330_OTP_PU);
+-		break;
+-	default:
+-		break;
+-	}
+-
+-	if (rsrcs != 0) {
+-		u32 otps;
+-
+-		/* Figure out the dependancies (exclude min_res_mask) */
+-		u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
+-		u32 min_mask = 0, max_mask = 0;
+-		si_pmu_res_masks(sih, &min_mask, &max_mask);
+-		deps &= ~min_mask;
+-		/* Turn on/off the power */
+-		if (on) {
+-			OR_REG(&cc->min_res_mask, (rsrcs | deps));
+-			SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
+-				 PMU_MAX_TRANSITION_DLY);
+-		} else {
+-			AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
+-		}
+-
+-		SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
+-			  (on ? OTPS_READY : 0)), 100);
+-	}
+-
+-	/* Return to original core */
+-	ai_setcoreidx(sih, origidx);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
+deleted file mode 100644
+index bd5b809b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
++++ /dev/null
+@@ -1,58 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-
+-#ifndef WLC_PMU_H_
+-#define WLC_PMU_H_
+-
+-#include <linux/types.h>
+-
+-#include <aiutils.h>
+-
+-/*
+- * LDO selections used in si_pmu_set_ldo_voltage
+- */
+-#define SET_LDO_VOLTAGE_LDO1	1
+-#define SET_LDO_VOLTAGE_LDO2	2
+-#define SET_LDO_VOLTAGE_LDO3	3
+-#define SET_LDO_VOLTAGE_PAREF	4
+-#define SET_LDO_VOLTAGE_CLDO_PWM	5
+-#define SET_LDO_VOLTAGE_CLDO_BURST	6
+-#define SET_LDO_VOLTAGE_CBUCK_PWM	7
+-#define SET_LDO_VOLTAGE_CBUCK_BURST	8
+-#define SET_LDO_VOLTAGE_LNLDO1	9
+-#define SET_LDO_VOLTAGE_LNLDO2_SEL	10
+-
+-extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage);
+-extern u16 si_pmu_fast_pwrup_delay(si_t *sih);
+-extern void si_pmu_sprom_enable(si_t *sih, bool enable);
+-extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern u32 si_pmu_ilp_clock(si_t *sih);
+-extern u32 si_pmu_alp_clock(si_t *sih);
+-extern void si_pmu_pllupd(si_t *sih);
+-extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid);
+-extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+-extern void si_pmu_init(si_t *sih);
+-extern void si_pmu_chip_init(si_t *sih);
+-extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq);
+-extern void si_pmu_res_init(si_t *sih);
+-extern void si_pmu_swreg_init(si_t *sih);
+-extern u32 si_pmu_measure_alpclk(si_t *sih);
+-extern bool si_pmu_is_otp_powered(si_t *sih);
+-extern void si_pmu_otp_power(si_t *sih, bool on);
+-
+-#endif /* WLC_PMU_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
+deleted file mode 100644
+index 9334dea..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
++++ /dev/null
+@@ -1,584 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_pub_h_
+-#define _wlc_pub_h_
+-
+-#define	WLC_NUMRATES	16	/* max # of rates in a rateset */
+-#define	MAXMULTILIST	32	/* max # multicast addresses */
+-#define	D11_PHY_HDR_LEN	6	/* Phy header length - 6 bytes */
+-
+-/* phy types */
+-#define	PHY_TYPE_A	0	/* Phy type A */
+-#define	PHY_TYPE_G	2	/* Phy type G */
+-#define	PHY_TYPE_N	4	/* Phy type N */
+-#define	PHY_TYPE_LP	5	/* Phy type Low Power A/B/G */
+-#define	PHY_TYPE_SSN	6	/* Phy type Single Stream N */
+-#define	PHY_TYPE_LCN	8	/* Phy type Single Stream N */
+-#define	PHY_TYPE_LCNXN	9	/* Phy type 2-stream N */
+-#define	PHY_TYPE_HT	7	/* Phy type 3-Stream N */
+-
+-/* bw */
+-#define WLC_10_MHZ	10	/* 10Mhz nphy channel bandwidth */
+-#define WLC_20_MHZ	20	/* 20Mhz nphy channel bandwidth */
+-#define WLC_40_MHZ	40	/* 40Mhz nphy channel bandwidth */
+-
+-#define CHSPEC_WLC_BW(chanspec)	(CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \
+-				 CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \
+-							 WLC_10_MHZ)
+-
+-#define	WLC_RSSI_MINVAL		-200	/* Low value, e.g. for forcing roam */
+-#define	WLC_RSSI_NO_SIGNAL	-91	/* NDIS RSSI link quality cutoffs */
+-#define	WLC_RSSI_VERY_LOW	-80	/* Very low quality cutoffs */
+-#define	WLC_RSSI_LOW		-70	/* Low quality cutoffs */
+-#define	WLC_RSSI_GOOD		-68	/* Good quality cutoffs */
+-#define	WLC_RSSI_VERY_GOOD	-58	/* Very good quality cutoffs */
+-#define	WLC_RSSI_EXCELLENT	-57	/* Excellent quality cutoffs */
+-
+-#define WLC_PHYTYPE(_x) (_x)	/* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */
+-
+-#define MA_WINDOW_SZ		8	/* moving average window size */
+-
+-#define WLC_SNR_INVALID		0	/* invalid SNR value */
+-
+-/* a large TX Power as an init value to factor out of min() calculations,
+- * keep low enough to fit in an s8, units are .25 dBm
+- */
+-#define WLC_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
+-
+-/* rate related definitions */
+-#define	WLC_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
+-#define	WLC_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
+-
+-/* legacy rx Antenna diversity for SISO rates */
+-#define	ANT_RX_DIV_FORCE_0		0	/* Use antenna 0 */
+-#define	ANT_RX_DIV_FORCE_1		1	/* Use antenna 1 */
+-#define	ANT_RX_DIV_START_1		2	/* Choose starting with 1 */
+-#define	ANT_RX_DIV_START_0		3	/* Choose starting with 0 */
+-#define	ANT_RX_DIV_ENABLE		3	/* APHY bbConfig Enable RX Diversity */
+-#define ANT_RX_DIV_DEF		ANT_RX_DIV_START_0	/* default antdiv setting */
+-
+-/* legacy rx Antenna diversity for SISO rates */
+-#define ANT_TX_FORCE_0		0	/* Tx on antenna 0, "legacy term Main" */
+-#define ANT_TX_FORCE_1		1	/* Tx on antenna 1, "legacy term Aux" */
+-#define ANT_TX_LAST_RX		3	/* Tx on phy's last good Rx antenna */
+-#define ANT_TX_DEF			3	/* driver's default tx antenna setting */
+-
+-#define TXCORE_POLICY_ALL	0x1	/* use all available core for transmit */
+-
+-/* Tx Chain values */
+-#define TXCHAIN_DEF		0x1	/* def bitmap of txchain */
+-#define TXCHAIN_DEF_NPHY	0x3	/* default bitmap of tx chains for nphy */
+-#define TXCHAIN_DEF_HTPHY	0x7	/* default bitmap of tx chains for nphy */
+-#define RXCHAIN_DEF		0x1	/* def bitmap of rxchain */
+-#define RXCHAIN_DEF_NPHY	0x3	/* default bitmap of rx chains for nphy */
+-#define RXCHAIN_DEF_HTPHY	0x7	/* default bitmap of rx chains for nphy */
+-#define ANTSWITCH_NONE		0	/* no antenna switch */
+-#define ANTSWITCH_TYPE_1	1	/* antenna switch on 4321CB2, 2of3 */
+-#define ANTSWITCH_TYPE_2	2	/* antenna switch on 4321MPCI, 2of3 */
+-#define ANTSWITCH_TYPE_3	3	/* antenna switch on 4322, 2of3 */
+-
+-#define RXBUFSZ		PKTBUFSZ
+-#ifndef AIDMAPSZ
+-#define AIDMAPSZ	(roundup(MAXSCB, NBBY)/NBBY)	/* aid bitmap size in bytes */
+-#endif				/* AIDMAPSZ */
+-
+-struct ieee80211_tx_queue_params;
+-
+-typedef struct wlc_tunables {
+-	int ntxd;		/* size of tx descriptor table */
+-	int nrxd;		/* size of rx descriptor table */
+-	int rxbufsz;		/* size of rx buffers to post */
+-	int nrxbufpost;		/* # of rx buffers to post */
+-	int maxscb;		/* # of SCBs supported */
+-	int ampdunummpdu;	/* max number of mpdu in an ampdu */
+-	int maxpktcb;		/* max # of packet callbacks */
+-	int maxucodebss;	/* max # of BSS handled in ucode bcn/prb */
+-	int maxucodebss4;	/* max # of BSS handled in sw bcn/prb */
+-	int maxbss;		/* max # of bss info elements in scan list */
+-	int datahiwat;		/* data msg txq hiwat mark */
+-	int ampdudatahiwat;	/* AMPDU msg txq hiwat mark */
+-	int rxbnd;		/* max # of rx bufs to process before deferring to dpc */
+-	int txsbnd;		/* max # tx status to process in wlc_txstatus() */
+-	int memreserved;	/* memory reserved for BMAC's USB dma rx */
+-} wlc_tunables_t;
+-
+-typedef struct wlc_rateset {
+-	uint count;		/* number of rates in rates[] */
+-	u8 rates[WLC_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-	u8 htphy_membership;	/* HT PHY Membership */
+-	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
+-} wlc_rateset_t;
+-
+-struct rsn_parms {
+-	u8 flags;		/* misc booleans (e.g., supported) */
+-	u8 multicast;	/* multicast cipher */
+-	u8 ucount;		/* count of unicast ciphers */
+-	u8 unicast[4];	/* unicast ciphers */
+-	u8 acount;		/* count of auth modes */
+-	u8 auth[4];		/* Authentication modes */
+-	u8 PAD[4];		/* padding for future growth */
+-};
+-
+-/*
+- * buffer length needed for wlc_format_ssid
+- * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL.
+- */
+-#define SSID_FMT_BUF_LEN	((4 * IEEE80211_MAX_SSID_LEN) + 1)
+-
+-#define RSN_FLAGS_SUPPORTED		0x1	/* Flag for rsn_params */
+-#define RSN_FLAGS_PREAUTH		0x2	/* Flag for WPA2 rsn_params */
+-
+-/* All the HT-specific default advertised capabilities (including AMPDU)
+- * should be grouped here at one place
+- */
+-#define AMPDU_DEF_MPDU_DENSITY	6	/* default mpdu density (110 ==> 4us) */
+-
+-/* defaults for the HT (MIMO) bss */
+-#define HT_CAP	(IEEE80211_HT_CAP_SM_PS |\
+-	IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\
+-	IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40)
+-
+-/* wlc internal bss_info, wl external one is in wlioctl.h */
+-typedef struct wlc_bss_info {
+-	u8 BSSID[ETH_ALEN];	/* network BSSID */
+-	u16 flags;		/* flags for internal attributes */
+-	u8 SSID_len;		/* the length of SSID */
+-	u8 SSID[32];		/* SSID string */
+-	s16 RSSI;		/* receive signal strength (in dBm) */
+-	s16 SNR;		/* receive signal SNR in dB */
+-	u16 beacon_period;	/* units are Kusec */
+-	u16 atim_window;	/* units are Kusec */
+-	chanspec_t chanspec;	/* Channel num, bw, ctrl_sb and band */
+-	s8 infra;		/* 0=IBSS, 1=infrastructure, 2=unknown */
+-	wlc_rateset_t rateset;	/* supported rates */
+-	u8 dtim_period;	/* DTIM period */
+-	s8 phy_noise;		/* noise right after tx (in dBm) */
+-	u16 capability;	/* Capability information */
+-	u8 wme_qosinfo;	/* QoS Info from WME IE; valid if WLC_BSS_WME flag set */
+-	struct rsn_parms wpa;
+-	struct rsn_parms wpa2;
+-	u16 qbss_load_aac;	/* qbss load available admission capacity */
+-	/* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */
+-	u8 qbss_load_chan_free;	/* indicates how free the channel is */
+-	u8 mcipher;		/* multicast cipher */
+-	u8 wpacfg;		/* wpa config index */
+-} wlc_bss_info_t;
+-
+-/* forward declarations */
+-struct wlc_if;
+-
+-/* wlc_ioctl error codes */
+-#define WLC_ENOIOCTL	1	/* No such Ioctl */
+-#define WLC_EINVAL	2	/* Invalid value */
+-#define WLC_ETOOSMALL	3	/* Value too small */
+-#define WLC_ETOOBIG	4	/* Value too big */
+-#define WLC_ERANGE	5	/* Out of range */
+-#define WLC_EDOWN	6	/* Down */
+-#define WLC_EUP		7	/* Up */
+-#define WLC_ENOMEM	8	/* No Memory */
+-#define WLC_EBUSY	9	/* Busy */
+-
+-/* IOVar flags for common error checks */
+-#define IOVF_MFG	(1<<3)	/* flag for mfgtest iovars */
+-#define IOVF_WHL	(1<<4)	/* value must be whole (0-max) */
+-#define IOVF_NTRL	(1<<5)	/* value must be natural (1-max) */
+-
+-#define IOVF_SET_UP	(1<<6)	/* set requires driver be up */
+-#define IOVF_SET_DOWN	(1<<7)	/* set requires driver be down */
+-#define IOVF_SET_CLK	(1<<8)	/* set requires core clock */
+-#define IOVF_SET_BAND	(1<<9)	/* set requires fixed band */
+-
+-#define IOVF_GET_UP	(1<<10)	/* get requires driver be up */
+-#define IOVF_GET_DOWN	(1<<11)	/* get requires driver be down */
+-#define IOVF_GET_CLK	(1<<12)	/* get requires core clock */
+-#define IOVF_GET_BAND	(1<<13)	/* get requires fixed band */
+-#define IOVF_OPEN_ALLOW	(1<<14)	/* set allowed iovar for opensrc */
+-
+-/* watchdog down and dump callback function proto's */
+-typedef int (*watchdog_fn_t) (void *handle);
+-typedef int (*down_fn_t) (void *handle);
+-typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b);
+-
+-/* IOVar handler
+- *
+- * handle - a pointer value registered with the function
+- * vi - iovar_info that was looked up
+- * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid.
+- * name - the actual iovar name
+- * params/plen - parameters and length for a get, input only.
+- * arg/len - buffer and length for value to be set or retrieved, input or output.
+- * vsize - value size, valid for integer type only.
+- * wlcif - interface context (wlc_if pointer)
+- *
+- * All pointers may point into the same buffer.
+- */
+-typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi,
+-			   u32 actionid, const char *name, void *params,
+-			   uint plen, void *arg, int alen, int vsize,
+-			   struct wlc_if *wlcif);
+-
+-#define MAC80211_PROMISC_BCNS	(1 << 0)
+-#define MAC80211_SCAN		(1 << 1)
+-
+-/*
+- * Public portion of "common" os-independent state structure.
+- * The wlc handle points at this.
+- */
+-struct wlc_pub {
+-	void *wlc;
+-
+-	struct ieee80211_hw *ieee_hw;
+-	struct scb *global_scb;
+-	scb_ampdu_t *global_ampdu;
+-	uint mac80211_state;
+-	uint unit;		/* device instance number */
+-	uint corerev;		/* core revision */
+-	si_t *sih;		/* SB handle (cookie for siutils calls) */
+-	char *vars;		/* "environment" name=value */
+-	bool up;		/* interface up and running */
+-	bool hw_off;		/* HW is off */
+-	wlc_tunables_t *tunables;	/* tunables: ntxd, nrxd, maxscb, etc. */
+-	bool hw_up;		/* one time hw up/down(from boot or hibernation) */
+-	bool _piomode;		/* true if pio mode *//* BMAC_NOTE: NEED In both */
+-	uint _nbands;		/* # bands supported */
+-	uint now;		/* # elapsed seconds */
+-
+-	bool promisc;		/* promiscuous destination address */
+-	bool delayed_down;	/* down delayed */
+-	bool _ap;		/* AP mode enabled */
+-	bool _apsta;		/* simultaneous AP/STA mode enabled */
+-	bool _assoc_recreate;	/* association recreation on up transitions */
+-	int _wme;		/* WME QoS mode */
+-	u8 _mbss;		/* MBSS mode on */
+-	bool allmulti;		/* enable all multicasts */
+-	bool associated;	/* true:part of [I]BSS, false: not */
+-	/* (union of stas_associated, aps_associated) */
+-	bool phytest_on;	/* whether a PHY test is running */
+-	bool bf_preempt_4306;	/* True to enable 'darwin' mode */
+-	bool _ampdu;		/* ampdu enabled or not */
+-	bool _cac;		/* 802.11e CAC enabled */
+-	u8 _n_enab;		/* bitmap of 11N + HT support */
+-	bool _n_reqd;		/* N support required for clients */
+-
+-	s8 _coex;		/* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */
+-	bool _priofc;		/* Priority-based flowcontrol */
+-
+-	u8 cur_etheraddr[ETH_ALEN];	/* our local ethernet address */
+-
+-	u8 *multicast;	/* ptr to list of multicast addresses */
+-	uint nmulticast;	/* # enabled multicast addresses */
+-
+-	u32 wlfeatureflag;	/* Flags to control sw features from registry */
+-	int psq_pkts_total;	/* total num of ps pkts */
+-
+-	u16 txmaxpkts;	/* max number of large pkts allowed to be pending */
+-
+-	/* s/w decryption counters */
+-	u32 swdecrypt;	/* s/w decrypt attempts */
+-
+-	int bcmerror;		/* last bcm error */
+-
+-	mbool radio_disabled;	/* bit vector for radio disabled reasons */
+-	bool radio_active;	/* radio on/off state */
+-	u16 roam_time_thresh;	/* Max. # secs. of not hearing beacons
+-					 * before roaming.
+-					 */
+-	bool align_wd_tbtt;	/* Align watchdog with tbtt indication
+-				 * handling. This flag is cleared by default
+-				 * and is set by per port code explicitly and
+-				 * you need to make sure the OSL_SYSUPTIME()
+-				 * is implemented properly in osl of that port
+-				 * when it enables this Power Save feature.
+-				 */
+-
+-	u16 boardrev;	/* version # of particular board */
+-	u8 sromrev;		/* version # of the srom */
+-	char srom_ccode[WLC_CNTRY_BUF_SZ];	/* Country Code in SROM */
+-	u32 boardflags;	/* Board specific flags from srom */
+-	u32 boardflags2;	/* More board flags if sromrev >= 4 */
+-	bool tempsense_disable;	/* disable periodic tempsense check */
+-
+-	bool _lmac;		/* lmac module included and enabled */
+-	bool _lmacproto;	/* lmac protocol module included and enabled */
+-	bool phy_11ncapable;	/* the PHY/HW is capable of 802.11N */
+-	bool _ampdumac;		/* mac assist ampdu enabled or not */
+-
+-	struct wl_cnt *_cnt;	/* low-level counters in driver */
+-};
+-
+-/* wl_monitor rx status per packet */
+-typedef struct wl_rxsts {
+-	uint pkterror;		/* error flags per pkt */
+-	uint phytype;		/* 802.11 A/B/G ... */
+-	uint channel;		/* channel */
+-	uint datarate;		/* rate in 500kbps */
+-	uint antenna;		/* antenna pkts received on */
+-	uint pktlength;		/* pkt length minus bcm phy hdr */
+-	u32 mactime;		/* time stamp from mac, count per 1us */
+-	uint sq;		/* signal quality */
+-	s32 signal;		/* in dbm */
+-	s32 noise;		/* in dbm */
+-	uint preamble;		/* Unknown, short, long */
+-	uint encoding;		/* Unknown, CCK, PBCC, OFDM */
+-	uint nfrmtype;		/* special 802.11n frames(AMPDU, AMSDU) */
+-	struct wl_if *wlif;	/* wl interface */
+-} wl_rxsts_t;
+-
+-/* status per error RX pkt */
+-#define WL_RXS_CRC_ERROR		0x00000001	/* CRC Error in packet */
+-#define WL_RXS_RUNT_ERROR		0x00000002	/* Runt packet */
+-#define WL_RXS_ALIGN_ERROR		0x00000004	/* Misaligned packet */
+-#define WL_RXS_OVERSIZE_ERROR		0x00000008	/* packet bigger than RX_LENGTH (usually 1518) */
+-#define WL_RXS_WEP_ICV_ERROR		0x00000010	/* Integrity Check Value error */
+-#define WL_RXS_WEP_ENCRYPTED		0x00000020	/* Encrypted with WEP */
+-#define WL_RXS_PLCP_SHORT		0x00000040	/* Short PLCP error */
+-#define WL_RXS_DECRYPT_ERR		0x00000080	/* Decryption error */
+-#define WL_RXS_OTHER_ERR		0x80000000	/* Other errors */
+-
+-/* phy type */
+-#define WL_RXS_PHY_A			0x00000000	/* A phy type */
+-#define WL_RXS_PHY_B			0x00000001	/* B phy type */
+-#define WL_RXS_PHY_G			0x00000002	/* G phy type */
+-#define WL_RXS_PHY_N			0x00000004	/* N phy type */
+-
+-/* encoding */
+-#define WL_RXS_ENCODING_CCK		0x00000000	/* CCK encoding */
+-#define WL_RXS_ENCODING_OFDM		0x00000001	/* OFDM encoding */
+-
+-/* preamble */
+-#define WL_RXS_UNUSED_STUB		0x0	/* stub to match with wlc_ethereal.h */
+-#define WL_RXS_PREAMBLE_SHORT		0x00000001	/* Short preamble */
+-#define WL_RXS_PREAMBLE_LONG		0x00000002	/* Long preamble */
+-#define WL_RXS_PREAMBLE_MIMO_MM		0x00000003	/* MIMO mixed mode preamble */
+-#define WL_RXS_PREAMBLE_MIMO_GF		0x00000004	/* MIMO green field preamble */
+-
+-#define WL_RXS_NFRM_AMPDU_FIRST		0x00000001	/* first MPDU in A-MPDU */
+-#define WL_RXS_NFRM_AMPDU_SUB		0x00000002	/* subsequent MPDU(s) in A-MPDU */
+-#define WL_RXS_NFRM_AMSDU_FIRST		0x00000004	/* first MSDU in A-MSDU */
+-#define WL_RXS_NFRM_AMSDU_SUB		0x00000008	/* subsequent MSDU(s) in A-MSDU */
+-
+-/* forward declare and use the struct notation so we don't have to
+- * have it defined if not necessary.
+- */
+-struct wlc_info;
+-struct wlc_hw_info;
+-struct wlc_bsscfg;
+-struct wlc_if;
+-
+-/***********************************************
+- * Feature-related macros to optimize out code *
+- * *********************************************
+- */
+-
+-/* AP Support (versus STA) */
+-#define	AP_ENAB(pub)	(0)
+-
+-/* Macro to check if APSTA mode enabled */
+-#define APSTA_ENAB(pub)	(0)
+-
+-/* Some useful combinations */
+-#define STA_ONLY(pub)	(!AP_ENAB(pub))
+-#define AP_ONLY(pub)	(AP_ENAB(pub) && !APSTA_ENAB(pub))
+-
+-#define ENAB_1x1	0x01
+-#define ENAB_2x2	0x02
+-#define ENAB_3x3	0x04
+-#define ENAB_4x4	0x08
+-#define SUPPORT_11N	(ENAB_1x1|ENAB_2x2)
+-#define SUPPORT_HT	(ENAB_1x1|ENAB_2x2|ENAB_3x3)
+-/* WL11N Support */
+-#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \
+-	(defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0)))
+-#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N)
+-#define N_REQD(pub) ((pub)->_n_reqd)
+-#else
+-#define N_ENAB(pub)	0
+-#define N_REQD(pub)	0
+-#endif
+-
+-#if (defined(HTCONF) && (HTCONF != 0))
+-#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT)
+-#else
+-#define HT_ENAB(pub) 0
+-#endif
+-
+-#define AMPDU_AGG_HOST	1
+-#define AMPDU_ENAB(pub) ((pub)->_ampdu)
+-
+-#define EDCF_ENAB(pub) (WME_ENAB(pub))
+-#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub))
+-
+-#define MONITOR_ENAB(wlc)	((wlc)->monitor)
+-
+-#define PROMISC_ENAB(wlc)	((wlc)->promisc)
+-
+-#define	WLC_PREC_COUNT		16	/* Max precedence level implemented */
+-
+-/* pri is priority encoded in the packet. This maps the Packet priority to
+- * enqueue precedence as defined in wlc_prec_map
+- */
+-extern const u8 wlc_prio2prec_map[];
+-#define WLC_PRIO_TO_PREC(pri)	wlc_prio2prec_map[(pri) & 7]
+-
+-/* This maps priority to one precedence higher - Used by PS-Poll response packets to
+- * simulate enqueue-at-head operation, but still maintain the order on the queue
+- */
+-#define WLC_PRIO_TO_HI_PREC(pri)	min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1)
+-
+-extern const u8 wme_fifo2ac[];
+-#define WME_PRIO2AC(prio)	wme_fifo2ac[prio2fifo[(prio)]]
+-
+-/* Mask to describe all precedence levels */
+-#define WLC_PREC_BMP_ALL		MAXBITVAL(WLC_PREC_COUNT)
+-
+-/* Define a bitmap of precedences comprised by each AC */
+-#define WLC_PREC_BMP_AC_BE	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE)))
+-#define WLC_PREC_BMP_AC_BK	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE)))
+-#define WLC_PREC_BMP_AC_VI	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI)))
+-#define WLC_PREC_BMP_AC_VO	(NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) |	\
+-				NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) |	\
+-				NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC)))
+-
+-/* WME Support */
+-#define WME_ENAB(pub) ((pub)->_wme != OFF)
+-#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO)
+-
+-#define WLC_USE_COREFLAGS	0xffffffff	/* invalid core flags, use the saved coreflags */
+-
+-
+-/* network protection config */
+-#define	WLC_PROT_G_SPEC		1	/* SPEC g protection */
+-#define	WLC_PROT_G_OVR		2	/* SPEC g prot override */
+-#define	WLC_PROT_G_USER		3	/* gmode specified by user */
+-#define	WLC_PROT_OVERLAP	4	/* overlap */
+-#define	WLC_PROT_N_USER		10	/* nmode specified by user */
+-#define	WLC_PROT_N_CFG		11	/* n protection */
+-#define	WLC_PROT_N_CFG_OVR	12	/* n protection override */
+-#define	WLC_PROT_N_NONGF	13	/* non-GF protection */
+-#define	WLC_PROT_N_NONGF_OVR	14	/* non-GF protection override */
+-#define	WLC_PROT_N_PAM_OVR	15	/* n preamble override */
+-#define	WLC_PROT_N_OBSS		16	/* non-HT OBSS present */
+-
+-/* common functions for every port */
+-extern void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
+-			bool piomode, void *regsva, uint bustype, void *btparam,
+-			uint *perr);
+-extern uint wlc_detach(struct wlc_info *wlc);
+-extern int wlc_up(struct wlc_info *wlc);
+-extern uint wlc_down(struct wlc_info *wlc);
+-
+-extern int wlc_set(struct wlc_info *wlc, int cmd, int arg);
+-extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg);
+-extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg);
+-extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg);
+-extern bool wlc_chipmatch(u16 vendor, u16 device);
+-extern void wlc_init(struct wlc_info *wlc);
+-extern void wlc_reset(struct wlc_info *wlc);
+-
+-extern void wlc_intrson(struct wlc_info *wlc);
+-extern u32 wlc_intrsoff(struct wlc_info *wlc);
+-extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask);
+-extern bool wlc_intrsupd(struct wlc_info *wlc);
+-extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc);
+-extern bool wlc_dpc(struct wlc_info *wlc, bool bounded);
+-extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
+-				 struct ieee80211_hw *hw);
+-extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params,
+-			int p_len, void *arg, int len, bool set,
+-			struct wlc_if *wlcif);
+-extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
+-		     struct wlc_if *wlcif);
+-extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid);
+-
+-/* helper functions */
+-extern void wlc_statsupd(struct wlc_info *wlc);
+-extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val);
+-extern int wlc_get_header_len(void);
+-extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc);
+-extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
+-			      const u8 *addr);
+-extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+-			      const struct ieee80211_tx_queue_params *arg,
+-			      bool suspend);
+-extern struct wlc_pub *wlc_pub(void *wlc);
+-
+-/* common functions for every port */
+-extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val,
+-		    int bands);
+-extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset);
+-extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs);
+-
+-struct ieee80211_sta;
+-extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta,
+-			    u16 tid);
+-
+-/* wlc_phy.c helper functions */
+-extern void wlc_set_ps_ctrl(struct wlc_info *wlc);
+-extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val);
+-
+-/* ioctl */
+-extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi,
+-			   void *arg,
+-			   int len, bool set);
+-
+-extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars,
+-			       const char *name, void *hdl, iovar_fn_t iovar_fn,
+-			       watchdog_fn_t watchdog_fn, down_fn_t down_fn);
+-extern int wlc_module_unregister(struct wlc_pub *pub, const char *name,
+-				 void *hdl);
+-extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc);
+-extern void wlc_enable_mac(struct wlc_info *wlc);
+-extern void wlc_associate_upd(struct wlc_info *wlc, bool state);
+-extern void wlc_scan_start(struct wlc_info *wlc);
+-extern void wlc_scan_stop(struct wlc_info *wlc);
+-extern int wlc_get_curband(struct wlc_info *wlc);
+-extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop);
+-
+-#if defined(BCMDBG)
+-extern int wlc_iocregchk(struct wlc_info *wlc, uint band);
+-#endif
+-
+-/* helper functions */
+-extern bool wlc_check_radio_disabled(struct wlc_info *wlc);
+-extern bool wlc_radio_monitor_stop(struct wlc_info *wlc);
+-
+-#if defined(BCMDBG)
+-extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len);
+-#endif
+-
+-#define	MAXBANDS		2	/* Maximum #of bands */
+-/* bandstate array indices */
+-#define BAND_2G_INDEX		0	/* wlc->bandstate[x] index */
+-#define BAND_5G_INDEX		1	/* wlc->bandstate[x] index */
+-
+-#define BAND_2G_NAME		"2.4G"
+-#define BAND_5G_NAME		"5G"
+-
+-/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */
+-#define WLC_RPCTX_PARAMS		32
+-
+-#endif				/* _wlc_pub_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c
+deleted file mode 100644
+index 87b252d..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c
++++ /dev/null
+@@ -1,499 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-
+-#include <proto/802.11.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_rate.h"
+-
+-/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */
+-const u8 rate_info[WLC_MAXRATE + 1] = {
+-	/*  0     1     2     3     4     5     6     7     8     9 */
+-/*   0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00,
+-/*  20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
+-/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00,
+-/*  50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-/*  90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
+-/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c
+-};
+-
+-/* rates are in units of Kbps */
+-const mcs_info_t mcs_table[MCS_TABLE_SIZE] = {
+-	/* MCS  0: SS 1, MOD: BPSK,  CR 1/2 */
+-	{6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00,
+-	 WLC_RATE_6M},
+-	/* MCS  1: SS 1, MOD: QPSK,  CR 1/2 */
+-	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08,
+-	 WLC_RATE_12M},
+-	/* MCS  2: SS 1, MOD: QPSK,  CR 3/4 */
+-	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A,
+-	 WLC_RATE_18M},
+-	/* MCS  3: SS 1, MOD: 16QAM, CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10,
+-	 WLC_RATE_24M},
+-	/* MCS  4: SS 1, MOD: 16QAM, CR 3/4 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12,
+-	 WLC_RATE_36M},
+-	/* MCS  5: SS 1, MOD: 64QAM, CR 2/3 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19,
+-	 WLC_RATE_48M},
+-	/* MCS  6: SS 1, MOD: 64QAM, CR 3/4 */
+-	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A,
+-	 WLC_RATE_54M},
+-	/* MCS  7: SS 1, MOD: 64QAM, CR 5/6 */
+-	{65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C,
+-	 WLC_RATE_54M},
+-	/* MCS  8: SS 2, MOD: BPSK,  CR 1/2 */
+-	{13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40,
+-	 WLC_RATE_6M},
+-	/* MCS  9: SS 2, MOD: QPSK,  CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48,
+-	 WLC_RATE_12M},
+-	/* MCS 10: SS 2, MOD: QPSK,  CR 3/4 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A,
+-	 WLC_RATE_18M},
+-	/* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50,
+-	 WLC_RATE_24M},
+-	/* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52,
+-	 WLC_RATE_36M},
+-	/* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */
+-	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59,
+-	 WLC_RATE_48M},
+-	/* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */
+-	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A,
+-	 WLC_RATE_54M},
+-	/* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */
+-	{130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C,
+-	 WLC_RATE_54M},
+-	/* MCS 16: SS 3, MOD: BPSK,  CR 1/2 */
+-	{19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80,
+-	 WLC_RATE_6M},
+-	/* MCS 17: SS 3, MOD: QPSK,  CR 1/2 */
+-	{39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88,
+-	 WLC_RATE_12M},
+-	/* MCS 18: SS 3, MOD: QPSK,  CR 3/4 */
+-	{58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A,
+-	 WLC_RATE_18M},
+-	/* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90,
+-	 WLC_RATE_24M},
+-	/* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */
+-	{117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92,
+-	 WLC_RATE_36M},
+-	/* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */
+-	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99,
+-	 WLC_RATE_48M},
+-	/* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */
+-	{175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A,
+-	 WLC_RATE_54M},
+-	/* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */
+-	{195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B,
+-	 WLC_RATE_54M},
+-	/* MCS 24: SS 4, MOD: BPSK,  CR 1/2 */
+-	{26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0,
+-	 WLC_RATE_6M},
+-	/* MCS 25: SS 4, MOD: QPSK,  CR 1/2 */
+-	{52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8,
+-	 WLC_RATE_12M},
+-	/* MCS 26: SS 4, MOD: QPSK,  CR 3/4 */
+-	{78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA,
+-	 WLC_RATE_18M},
+-	/* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */
+-	{104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0,
+-	 WLC_RATE_24M},
+-	/* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */
+-	{156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2,
+-	 WLC_RATE_36M},
+-	/* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */
+-	{208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9,
+-	 WLC_RATE_48M},
+-	/* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */
+-	{234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA,
+-	 WLC_RATE_54M},
+-	/* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */
+-	{260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB,
+-	 WLC_RATE_54M},
+-	/* MCS 32: SS 1, MOD: BPSK,  CR 1/2 */
+-	{0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M},
+-};
+-
+-/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams
+- *   Number of spatial streams: always 1
+- *   other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard
+- */
+-typedef struct legacy_phycfg {
+-	u32 rate_ofdm;	/* ofdm mac rate */
+-	u8 tx_phy_ctl3;	/* phy ctl byte 3, code rate, modulation type, # of streams */
+-} legacy_phycfg_t;
+-
+-#define LEGACY_PHYCFG_TABLE_SIZE	12	/* Number of legacy_rate_cfg entries in the table */
+-
+-/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */
+-/* Eventually MIMOPHY would also be converted to this format */
+-/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */
+-static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = {
+-	{WLC_RATE_1M, 0x00},	/* CCK  1Mbps,  data rate  0 */
+-	{WLC_RATE_2M, 0x08},	/* CCK  2Mbps,  data rate  1 */
+-	{WLC_RATE_5M5, 0x10},	/* CCK  5.5Mbps,  data rate  2 */
+-	{WLC_RATE_11M, 0x18},	/* CCK  11Mbps,  data rate   3 */
+-	{WLC_RATE_6M, 0x00},	/* OFDM  6Mbps,  code rate 1/2, BPSK,   1 spatial stream */
+-	{WLC_RATE_9M, 0x02},	/* OFDM  9Mbps,  code rate 3/4, BPSK,   1 spatial stream */
+-	{WLC_RATE_12M, 0x08},	/* OFDM  12Mbps, code rate 1/2, QPSK,   1 spatial stream */
+-	{WLC_RATE_18M, 0x0A},	/* OFDM  18Mbps, code rate 3/4, QPSK,   1 spatial stream */
+-	{WLC_RATE_24M, 0x10},	/* OFDM  24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */
+-	{WLC_RATE_36M, 0x12},	/* OFDM  36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */
+-	{WLC_RATE_48M, 0x19},	/* OFDM  48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */
+-	{WLC_RATE_54M, 0x1A},	/* OFDM  54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */
+-};
+-
+-/* Hardware rates (also encodes default basic rates) */
+-
+-const wlc_rateset_t cck_ofdm_mimo_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_mimo_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-/* Default ratesets that include MCS32 for 40BW channels */
+-const wlc_rateset_t cck_ofdm_40bw_mimo_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_40bw_mimo_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t cck_ofdm_rates = {
+-	12,
+-	{			/*    1b,   2b,   5.5b, 6,    9,    11b,  12,   18,   24,   36,   48,   54 Mbps */
+-	 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60,
+-	 0x6c},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t gphy_legacy_rates = {
+-	4,
+-	{			/*    1b,   2b,   5.5b,  11b Mbps */
+-	 0x82, 0x84, 0x8b, 0x96},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t ofdm_rates = {
+-	8,
+-	{			/*    6b,   9,    12b,  18,   24b,  36,   48,   54 Mbps */
+-	 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-const wlc_rateset_t cck_rates = {
+-	4,
+-	{			/*    1b,   2b,   5.5,  11 Mbps */
+-	 0x82, 0x84, 0x0b, 0x16},
+-	0x00,
+-	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-	 0x00, 0x00, 0x00, 0x00}
+-};
+-
+-static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate);
+-
+-/* check if rateset is valid.
+- * if check_brate is true, rateset without a basic rate is considered NOT valid.
+- */
+-static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate)
+-{
+-	uint idx;
+-
+-	if (!rs->count)
+-		return false;
+-
+-	if (!check_brate)
+-		return true;
+-
+-	/* error if no basic rates */
+-	for (idx = 0; idx < rs->count; idx++) {
+-		if (rs->rates[idx] & WLC_RATE_FLAG)
+-			return true;
+-	}
+-	return false;
+-}
+-
+-void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams)
+-{
+-	int i;
+-	for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++)
+-		rs->mcs[i] = 0;
+-}
+-
+-/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved,
+- * and check if resulting rateset is valid.
+-*/
+-bool
+-wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs,
+-				   const wlc_rateset_t *hw_rs,
+-				   bool check_brate, u8 txstreams)
+-{
+-	u8 rateset[WLC_MAXRATE + 1];
+-	u8 r;
+-	uint count;
+-	uint i;
+-
+-	memset(rateset, 0, sizeof(rateset));
+-	count = rs->count;
+-
+-	for (i = 0; i < count; i++) {
+-		/* mask off "basic rate" bit, WLC_RATE_FLAG */
+-		r = (int)rs->rates[i] & WLC_RATE_MASK;
+-		if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) {
+-			continue;
+-		}
+-		rateset[r] = rs->rates[i];	/* preserve basic bit! */
+-	}
+-
+-	/* fill out the rates in order, looking at only supported rates */
+-	count = 0;
+-	for (i = 0; i < hw_rs->count; i++) {
+-		r = hw_rs->rates[i] & WLC_RATE_MASK;
+-		if (rateset[r])
+-			rs->rates[count++] = rateset[r];
+-	}
+-
+-	rs->count = count;
+-
+-	/* only set the mcs rate bit if the equivalent hw mcs bit is set */
+-	for (i = 0; i < MCSSET_LEN; i++)
+-		rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]);
+-
+-	if (wlc_rateset_valid(rs, check_brate))
+-		return true;
+-	else
+-		return false;
+-}
+-
+-/* calculate the rate of a rx'd frame and return it as a ratespec */
+-ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp)
+-{
+-	int phy_type;
+-	ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
+-
+-	phy_type =
+-	    ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT);
+-
+-	if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) ||
+-	    (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) {
+-		switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) {
+-		case PRXS0_CCK:
+-			rspec =
+-			    CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+-			break;
+-		case PRXS0_OFDM:
+-			rspec =
+-			    OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->
+-					      rlpt[0]);
+-			break;
+-		case PRXS0_PREN:
+-			rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE;
+-			if (plcp[0] & MIMO_PLCP_40MHZ) {
+-				/* indicate rspec is for 40 MHz mode */
+-				rspec &= ~RSPEC_BW_MASK;
+-				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
+-			}
+-			break;
+-		case PRXS0_STDN:
+-			/* fallthru */
+-		default:
+-			/* not supported, error condition */
+-			break;
+-		}
+-		if (PLCP3_ISSGI(plcp[3]))
+-			rspec |= RSPEC_SHORT_GI;
+-	} else
+-	    if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM))
+-		rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]);
+-	else
+-		rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal);
+-
+-	return rspec;
+-}
+-
+-/* copy rateset src to dst as-is (no masking or sorting) */
+-void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst)
+-{
+-	memcpy(dst, src, sizeof(wlc_rateset_t));
+-}
+-
+-/*
+- * Copy and selectively filter one rateset to another.
+- * 'basic_only' means only copy basic rates.
+- * 'rates' indicates cck (11b) and ofdm rates combinations.
+- *    - 0: cck and ofdm
+- *    - 1: cck only
+- *    - 2: ofdm only
+- * 'xmask' is the copy mask (typically 0x7f or 0xff).
+- */
+-void
+-wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only,
+-		   u8 rates, uint xmask, bool mcsallow)
+-{
+-	uint i;
+-	uint r;
+-	uint count;
+-
+-	count = 0;
+-	for (i = 0; i < src->count; i++) {
+-		r = src->rates[i];
+-		if (basic_only && !(r & WLC_RATE_FLAG))
+-			continue;
+-		if ((rates == WLC_RATES_CCK) && IS_OFDM((r & WLC_RATE_MASK)))
+-			continue;
+-		if ((rates == WLC_RATES_OFDM) && IS_CCK((r & WLC_RATE_MASK)))
+-			continue;
+-		dst->rates[count++] = r & xmask;
+-	}
+-	dst->count = count;
+-	dst->htphy_membership = src->htphy_membership;
+-
+-	if (mcsallow && rates != WLC_RATES_CCK)
+-		memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN);
+-	else
+-		wlc_rateset_mcs_clear(dst);
+-}
+-
+-/* select rateset for a given phy_type and bandtype and filter it, sort it
+- * and fill rs_tgt with result
+- */
+-void
+-wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw,
+-		    uint phy_type, int bandtype, bool cck_only, uint rate_mask,
+-		    bool mcsallow, u8 bw, u8 txstreams)
+-{
+-	const wlc_rateset_t *rs_dflt;
+-	wlc_rateset_t rs_sel;
+-	if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_N)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) ||
+-	    (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) {
+-		if (BAND_5G(bandtype)) {
+-			rs_dflt = (bw == WLC_20_MHZ ?
+-				   &ofdm_mimo_rates : &ofdm_40bw_mimo_rates);
+-		} else {
+-			rs_dflt = (bw == WLC_20_MHZ ?
+-				   &cck_ofdm_mimo_rates :
+-				   &cck_ofdm_40bw_mimo_rates);
+-		}
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) {
+-		rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates;
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) {
+-		rs_dflt = &ofdm_rates;
+-	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
+-		rs_dflt = &cck_ofdm_rates;
+-	} else {
+-		/* should not happen, error condition */
+-		rs_dflt = &cck_rates;	/* force cck */
+-	}
+-
+-	/* if hw rateset is not supplied, assign selected rateset to it */
+-	if (!rs_hw)
+-		rs_hw = rs_dflt;
+-
+-	wlc_rateset_copy(rs_dflt, &rs_sel);
+-	wlc_rateset_mcs_upd(&rs_sel, txstreams);
+-	wlc_rateset_filter(&rs_sel, rs_tgt, false,
+-			   cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM,
+-			   rate_mask, mcsallow);
+-	wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false,
+-					   mcsallow ? txstreams : 1);
+-}
+-
+-s16 wlc_rate_legacy_phyctl(uint rate)
+-{
+-	uint i;
+-	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
+-		if (rate == legacy_phycfg_table[i].rate_ofdm)
+-			return legacy_phycfg_table[i].tx_phy_ctl3;
+-
+-	return -1;
+-}
+-
+-void wlc_rateset_mcs_clear(wlc_rateset_t *rateset)
+-{
+-	uint i;
+-	for (i = 0; i < MCSSET_LEN; i++)
+-		rateset->mcs[i] = 0;
+-}
+-
+-void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams)
+-{
+-	memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN);
+-	wlc_rateset_mcs_upd(rateset, txstreams);
+-}
+-
+-/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */
+-void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw)
+-{
+-	if (bw == WLC_40_MHZ)
+-		setbit(rateset->mcs, 32);
+-	else
+-		clrbit(rateset->mcs, 32);
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h
+deleted file mode 100644
+index 5575e83..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h
++++ /dev/null
+@@ -1,169 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _WLC_RATE_H_
+-#define _WLC_RATE_H_
+-
+-extern const u8 rate_info[];
+-extern const struct wlc_rateset cck_ofdm_mimo_rates;
+-extern const struct wlc_rateset ofdm_mimo_rates;
+-extern const struct wlc_rateset cck_ofdm_rates;
+-extern const struct wlc_rateset ofdm_rates;
+-extern const struct wlc_rateset cck_rates;
+-extern const struct wlc_rateset gphy_legacy_rates;
+-extern const struct wlc_rateset wlc_lrs_rates;
+-extern const struct wlc_rateset rate_limit_1_2;
+-
+-typedef struct mcs_info {
+-	u32 phy_rate_20;	/* phy rate in kbps [20Mhz] */
+-	u32 phy_rate_40;	/* phy rate in kbps [40Mhz] */
+-	u32 phy_rate_20_sgi;	/* phy rate in kbps [20Mhz] with SGI */
+-	u32 phy_rate_40_sgi;	/* phy rate in kbps [40Mhz] with SGI */
+-	u8 tx_phy_ctl3;	/* phy ctl byte 3, code rate, modulation type, # of streams */
+-	u8 leg_ofdm;		/* matching legacy ofdm rate in 500bkps */
+-} mcs_info_t;
+-
+-#define WLC_MAXMCS	32	/* max valid mcs index */
+-#define MCS_TABLE_SIZE	33	/* Number of mcs entries in the table */
+-extern const mcs_info_t mcs_table[];
+-
+-#define MCS_INVALID	0xFF
+-#define MCS_CR_MASK	0x07	/* Code Rate bit mask */
+-#define MCS_MOD_MASK	0x38	/* Modulation bit shift */
+-#define MCS_MOD_SHIFT	3	/* MOdulation bit shift */
+-#define MCS_TXS_MASK	0xc0	/* num tx streams - 1 bit mask */
+-#define MCS_TXS_SHIFT	6	/* num tx streams - 1 bit shift */
+-#define MCS_CR(_mcs)	(mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK)
+-#define MCS_MOD(_mcs)	((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT)
+-#define MCS_TXS(_mcs)	((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT)
+-#define MCS_RATE(_mcs, _is40, _sgi)	(_sgi ? \
+-	(_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \
+-	(_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
+-#define VALID_MCS(_mcs)	((_mcs < MCS_TABLE_SIZE))
+-
+-/* Macro to use the rate_info table */
+-#define	WLC_RATE_MASK_FULL 0xff	/* Rate value mask with basic rate flag */
+-
+-#define WLC_RATE_500K_TO_BPS(rate)	((rate) * 500000)	/* convert 500kbps to bps */
+-
+-/* rate spec : holds rate and mode specific information required to generate a tx frame. */
+-/* Legacy CCK and OFDM information is held in the same manner as was done in the past    */
+-/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information        */
+-typedef u32 ratespec_t;
+-
+-/* rate spec bit fields */
+-#define RSPEC_RATE_MASK		0x0000007F	/* Either 500Kbps units or MIMO MCS idx */
+-#define RSPEC_MIMORATE		0x08000000	/* mimo MCS is stored in RSPEC_RATE_MASK */
+-#define RSPEC_BW_MASK		0x00000700	/* mimo bw mask */
+-#define RSPEC_BW_SHIFT		8	/* mimo bw shift */
+-#define RSPEC_STF_MASK		0x00003800	/* mimo Space/Time/Frequency mode mask */
+-#define RSPEC_STF_SHIFT		11	/* mimo Space/Time/Frequency mode shift */
+-#define RSPEC_CT_MASK		0x0000C000	/* mimo coding type mask */
+-#define RSPEC_CT_SHIFT		14	/* mimo coding type shift */
+-#define RSPEC_STC_MASK		0x00300000	/* mimo num STC streams per PLCP defn. */
+-#define RSPEC_STC_SHIFT		20	/* mimo num STC streams per PLCP defn. */
+-#define RSPEC_LDPC_CODING	0x00400000	/* mimo bit indicates adv coding in use */
+-#define RSPEC_SHORT_GI		0x00800000	/* mimo bit indicates short GI in use */
+-#define RSPEC_OVERRIDE		0x80000000	/* bit indicates override both rate & mode */
+-#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000	/* bit indicates override rate only */
+-
+-#define WLC_HTPHY		127	/* HT PHY Membership */
+-
+-#define RSPEC_ACTIVE(rspec)	(rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE))
+-#define RSPEC2RATE(rspec)      	((rspec & RSPEC_MIMORATE) ? \
+-	MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \
+-	(rspec & RSPEC_RATE_MASK))
+-/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */
+-#define RSPEC2RATE500K(rspec)	((rspec & RSPEC_MIMORATE) ? \
+-		MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \
+-		(rspec & RSPEC_RATE_MASK))
+-#define CRSPEC2RATE500K(rspec)	((rspec & RSPEC_MIMORATE) ? \
+-		MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\
+-		(rspec & RSPEC_RATE_MASK))
+-
+-#define RSPEC2KBPS(rspec)	(IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500)
+-#define RSPEC_PHYTXBYTE2(rspec)	((rspec & 0xff00) >> 8)
+-#define RSPEC_GET_BW(rspec)	((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT)
+-#define RSPEC_IS40MHZ(rspec)	((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \
+-				PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \
+-				RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP))
+-#define RSPEC_ISSGI(rspec)	((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI)
+-#define RSPEC_MIMOPLCP3(rspec)	((rspec & 0xf00000) >> 16)
+-#define PLCP3_ISSGI(plcp)	(plcp & (RSPEC_SHORT_GI >> 16))
+-#define RSPEC_STC(rspec)	((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT)
+-#define RSPEC_STF(rspec)	((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT)
+-#define PLCP3_ISSTBC(plcp)	((plcp & (RSPEC_STC_MASK) >> 16) == 0x10)
+-#define PLCP3_STC_MASK          0x30
+-#define PLCP3_STC_SHIFT         4
+-
+-/* Rate info table; takes a legacy rate or ratespec_t */
+-#define	IS_MCS(r)     	(r & RSPEC_MIMORATE)
+-#define	IS_OFDM(r)     	(!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG))
+-#define	IS_CCK(r)	(!IS_MCS(r) && ( \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_1M || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_2M || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_5M5 || \
+-			 ((r) & WLC_RATE_MASK) == WLC_RATE_11M))
+-#define IS_SINGLE_STREAM(mcs)	(((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
+-#define CCK_RSPEC(cck)		((cck) & RSPEC_RATE_MASK)
+-#define OFDM_RSPEC(ofdm)	(((ofdm) & RSPEC_RATE_MASK) |\
+-	(PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT))
+-#define LEGACY_RSPEC(rate)	(IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate))
+-
+-#define MCS_RSPEC(mcs)		(((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \
+-	(IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \
+-	(PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT)))
+-
+-/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */
+-extern const u8 ofdm_rate_lookup[];
+-#define OFDM_PHY2MAC_RATE(rlpt)		(ofdm_rate_lookup[rlpt & 0x7])
+-#define CCK_PHY2MAC_RATE(signal)	(signal/5)
+-
+-/* Rates specified in wlc_rateset_filter() */
+-#define WLC_RATES_CCK_OFDM	0
+-#define WLC_RATES_CCK		1
+-#define WLC_RATES_OFDM		2
+-
+-/* use the stuct form instead of typedef to fix dependency problems */
+-struct wlc_rateset;
+-
+-/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */
+-extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs,
+-					       const struct wlc_rateset *hw_rs,
+-					       bool check_brate,
+-					       u8 txstreams);
+-/* copy rateset src to dst as-is (no masking or sorting) */
+-extern void wlc_rateset_copy(const struct wlc_rateset *src,
+-			     struct wlc_rateset *dst);
+-
+-/* would be nice to have these documented ... */
+-extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp);
+-
+-extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst,
+-			       bool basic_only, u8 rates, uint xmask,
+-			       bool mcsallow);
+-extern void wlc_rateset_default(struct wlc_rateset *rs_tgt,
+-				const struct wlc_rateset *rs_hw, uint phy_type,
+-				int bandtype, bool cck_only, uint rate_mask,
+-				bool mcsallow, u8 bw, u8 txstreams);
+-extern s16 wlc_rate_legacy_phyctl(uint rate);
+-
+-extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams);
+-extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset);
+-extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams);
+-extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw);
+-
+-#endif				/* _WLC_RATE_H_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h
+deleted file mode 100644
+index f07a891..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h
++++ /dev/null
+@@ -1,80 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_scb_h_
+-#define _wlc_scb_h_
+-
+-#define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
+-/* structure to store per-tid state for the ampdu initiator */
+-typedef struct scb_ampdu_tid_ini {
+-	u32 magic;
+-	u8 tx_in_transit;	/* number of pending mpdus in transit in driver */
+-	u8 tid;		/* initiator tid for easy lookup */
+-	u8 txretry[AMPDU_TX_BA_MAX_WSIZE];	/* tx retry count; indexed by seq modulo */
+-	struct scb *scb;	/* backptr for easy lookup */
+-} scb_ampdu_tid_ini_t;
+-
+-#define AMPDU_MAX_SCB_TID	NUMPRIO
+-
+-typedef struct scb_ampdu {
+-	struct scb *scb;	/* back pointer for easy reference */
+-	u8 mpdu_density;	/* mpdu density */
+-	u8 max_pdu;		/* max pdus allowed in ampdu */
+-	u8 release;		/* # of mpdus released at a time */
+-	u16 min_len;		/* min mpdu len to support the density */
+-	u32 max_rxlen;	/* max ampdu rcv length; 8k, 16k, 32k, 64k */
+-	struct pktq txq;	/* sdu transmit queue pending aggregation */
+-
+-	/* This could easily be a ini[] pointer and we keep this info in wl itself instead
+-	 * of having mac80211 hold it for us.  Also could be made dynamic per tid instead of
+-	 * static.
+-	 */
+-	scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID];	/* initiator info - per tid (NUMPRIO) */
+-} scb_ampdu_t;
+-
+-#define SCB_MAGIC 	0xbeefcafe
+-#define INI_MAGIC 	0xabcd1234
+-
+-/* station control block - one per remote MAC address */
+-struct scb {
+-	u32 magic;
+-	u32 flags;		/* various bit flags as defined below */
+-	u32 flags2;		/* various bit flags2 as defined below */
+-	u8 state;		/* current state bitfield of auth/assoc process */
+-	u8 ea[ETH_ALEN];	/* station address */
+-	void *fragbuf[NUMPRIO];	/* defragmentation buffer per prio */
+-	uint fragresid[NUMPRIO];	/* #bytes unused in frag buffer per prio */
+-
+-	u16 seqctl[NUMPRIO];	/* seqctl of last received frame (for dups) */
+-	u16 seqctl_nonqos;	/* seqctl of last received frame (for dups) for
+-				 * non-QoS data and management
+-				 */
+-	u16 seqnum[NUMPRIO];	/* WME: driver maintained sw seqnum per priority */
+-
+-	scb_ampdu_t scb_ampdu;	/* AMPDU state including per tid info */
+-};
+-
+-/* scb flags */
+-#define SCB_WMECAP		0x0040	/* may ONLY be set if WME_ENAB(wlc) */
+-#define SCB_HTCAP		0x10000	/* HT (MIMO) capable device */
+-#define SCB_IS40		0x80000	/* 40MHz capable */
+-#define SCB_STBCCAP		0x40000000	/* STBC Capable */
+-#define SCB_WME(a)		((a)->flags & SCB_WMECAP)/* implies WME_ENAB */
+-#define SCB_SEQNUM(scb, prio)	((scb)->seqnum[(prio)])
+-#define SCB_PS(a)		NULL
+-#define SCB_STBC_CAP(a)		((a)->flags & SCB_STBCCAP)
+-#define SCB_AMPDU(a)		true
+-#endif				/* _wlc_scb_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c
+deleted file mode 100644
+index c4f5817..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c
++++ /dev/null
+@@ -1,523 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-
+-#include <proto/802.11.h>
+-
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <aiutils.h>
+-#include <wlioctl.h>
+-#include <bcmwifi.h>
+-#include <bcmnvram.h>
+-#include <sbhnddma.h>
+-
+-#include "wlc_types.h"
+-#include "d11.h"
+-#include "wl_dbg.h"
+-#include "wlc_cfg.h"
+-#include "wlc_rate.h"
+-#include "wlc_scb.h"
+-#include "wlc_pub.h"
+-#include "wlc_key.h"
+-#include "phy/wlc_phy_hal.h"
+-#include "wlc_channel.h"
+-#include "wlc_main.h"
+-#include "wl_export.h"
+-#include "wlc_bmac.h"
+-#include "wlc_stf.h"
+-
+-#define MIN_SPATIAL_EXPANSION	0
+-#define MAX_SPATIAL_EXPANSION	1
+-
+-#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \
+-	NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6))
+-
+-static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val);
+-static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val);
+-static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val);
+-static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val);
+-
+-static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec);
+-
+-#define NSTS_1	1
+-#define NSTS_2	2
+-#define NSTS_3	3
+-#define NSTS_4	4
+-const u8 txcore_default[5] = {
+-	(0),			/* bitmap of the core enabled */
+-	(0x01),			/* For Nsts = 1, enable core 1 */
+-	(0x03),			/* For Nsts = 2, enable core 1 & 2 */
+-	(0x07),			/* For Nsts = 3, enable core 1, 2 & 3 */
+-	(0x0f)			/* For Nsts = 4, enable all cores */
+-};
+-
+-static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val)
+-{
+-	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
+-	if (WLC_STF_SS_STBC_RX(wlc)) {
+-		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
+-			return;
+-	}
+-
+-	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_RX_STBC;
+-	wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+-
+-	if (wlc->pub->up) {
+-		wlc_update_beacon(wlc);
+-		wlc_update_probe_resp(wlc, true);
+-	}
+-}
+-
+-/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */
+-void wlc_tempsense_upd(struct wlc_info *wlc)
+-{
+-	wlc_phy_t *pi = wlc->band->pi;
+-	uint active_chains, txchain;
+-
+-	/* Check if the chip is too hot. Disable one Tx chain, if it is */
+-	/* high 4 bits are for Rx chain, low 4 bits are  for Tx chain */
+-	active_chains = wlc_phy_stf_chain_active_get(pi);
+-	txchain = active_chains & 0xf;
+-
+-	if (wlc->stf->txchain == wlc->stf->hw_txchain) {
+-		if (txchain && (txchain < wlc->stf->hw_txchain)) {
+-			/* turn off 1 tx chain */
+-			wlc_stf_txchain_set(wlc, txchain, true);
+-		}
+-	} else if (wlc->stf->txchain < wlc->stf->hw_txchain) {
+-		if (txchain == wlc->stf->hw_txchain) {
+-			/* turn back on txchain */
+-			wlc_stf_txchain_set(wlc, txchain, true);
+-		}
+-	}
+-}
+-
+-void
+-wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel,
+-			    chanspec_t chanspec)
+-{
+-	tx_power_t power;
+-	u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id;
+-
+-	/* Clear previous settings */
+-	*ss_algo_channel = 0;
+-
+-	if (!wlc->pub->up) {
+-		*ss_algo_channel = (u16) -1;
+-		return;
+-	}
+-
+-	wlc_phy_txpower_get_current(wlc->band->pi, &power,
+-				    CHSPEC_CHANNEL(chanspec));
+-
+-	siso_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST;
+-	cdd_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST;
+-	stbc_mcs_id = (CHSPEC_IS40(chanspec)) ?
+-	    WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST;
+-
+-	/* criteria to choose stf mode */
+-
+-	/* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs
+-	 * on both chains
+-	 */
+-	if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12))
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_SISO);
+-	else
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_CDD);
+-
+-	/* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check
+-	 * so cannot be default mode of operation. One of SISO, CDD have to be set
+-	 */
+-	if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12))
+-		setbit(ss_algo_channel, PHY_TXC1_MODE_STBC);
+-}
+-
+-static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val)
+-{
+-	if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) {
+-		return false;
+-	}
+-
+-	if ((int_val == ON) && (wlc->stf->txstreams == 1))
+-		return false;
+-
+-	if ((int_val == OFF) || (wlc->stf->txstreams == 1)
+-	    || !WLC_STBC_CAP_PHY(wlc))
+-		wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC;
+-	else
+-		wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC;
+-
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val;
+-
+-	return true;
+-}
+-
+-bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val)
+-{
+-	if ((int_val != HT_CAP_RX_STBC_NO)
+-	    && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) {
+-		return false;
+-	}
+-
+-	if (WLC_STF_SS_STBC_RX(wlc)) {
+-		if ((int_val != HT_CAP_RX_STBC_NO)
+-		    && (wlc->stf->rxstreams == 1))
+-			return false;
+-	}
+-
+-	wlc_stf_stbc_rx_ht_update(wlc, int_val);
+-	return true;
+-}
+-
+-static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask)
+-{
+-	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
+-		 wlc->pub->unit, Nsts, core_mask);
+-
+-	if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) {
+-		core_mask = 0;
+-	}
+-
+-	if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) &&
+-	    ((core_mask & ~wlc->stf->txchain)
+-	     || !(core_mask & wlc->stf->txchain))) {
+-		core_mask = wlc->stf->txchain;
+-	}
+-
+-	wlc->stf->txcore[Nsts] = core_mask;
+-	/* Nsts = 1..4, txcore index = 1..4 */
+-	if (Nsts == 1) {
+-		/* Needs to update beacon and ucode generated response
+-		 * frames when 1 stream core map changed
+-		 */
+-		wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT;
+-		wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+-		if (wlc->clk) {
+-			wlc_suspend_mac_and_wait(wlc);
+-			wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec);
+-			wlc_enable_mac(wlc);
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val)
+-{
+-	int i;
+-	u8 core_mask = 0;
+-
+-	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
+-
+-	wlc->stf->spatial_policy = (s8) val;
+-	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
+-		core_mask = (val == MAX_SPATIAL_EXPANSION) ?
+-		    wlc->stf->txchain : txcore_default[i];
+-		wlc_stf_txcore_set(wlc, (u8) i, core_mask);
+-	}
+-	return 0;
+-}
+-
+-int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force)
+-{
+-	u8 txchain = (u8) int_val;
+-	u8 txstreams;
+-	uint i;
+-
+-	if (wlc->stf->txchain == txchain)
+-		return 0;
+-
+-	if ((txchain & ~wlc->stf->hw_txchain)
+-	    || !(txchain & wlc->stf->hw_txchain))
+-		return -EINVAL;
+-
+-	/* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
+-	txstreams = (u8) WLC_BITSCNT(txchain);
+-	if (txstreams > MAX_STREAMS_SUPPORTED)
+-		return -EINVAL;
+-
+-	if (txstreams == 1) {
+-		for (i = 0; i < NBANDS(wlc); i++)
+-			if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) !=
+-			     PHY_TXC1_MODE_SISO)
+-			    || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
+-				PHY_TXC1_MODE_SISO)) {
+-				if (!force)
+-					return -EBADE;
+-
+-				/* over-write the override rspec */
+-				if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
+-				    != PHY_TXC1_MODE_SISO) {
+-					wlc->bandstate[i]->rspec_override = 0;
+-					wiphy_err(wlc->wiphy, "%s(): temp "
+-						  "sense override non-SISO "
+-						  "rspec_override\n",
+-						  __func__);
+-				}
+-				if (RSPEC_STF
+-				    (wlc->bandstate[i]->mrspec_override) !=
+-				    PHY_TXC1_MODE_SISO) {
+-					wlc->bandstate[i]->mrspec_override = 0;
+-					wiphy_err(wlc->wiphy, "%s(): temp "
+-						  "sense override non-SISO "
+-						  "mrspec_override\n",
+-						  __func__);
+-				}
+-			}
+-	}
+-
+-	wlc->stf->txchain = txchain;
+-	wlc->stf->txstreams = txstreams;
+-	wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-	wlc->stf->txant =
+-	    (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF;
+-	_wlc_stf_phy_txant_upd(wlc);
+-
+-	wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain,
+-			      wlc->stf->rxchain);
+-
+-	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
+-		wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
+-
+-	return 0;
+-}
+-
+-/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
+-int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band)
+-{
+-	int ret_code = 0;
+-	u8 prev_stf_ss;
+-	u8 upd_stf_ss;
+-
+-	prev_stf_ss = wlc->stf->ss_opmode;
+-
+-	/* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */
+-	if (WLC_STBC_CAP_PHY(wlc) &&
+-	    wlc->stf->ss_algosel_auto
+-	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
+-		upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
+-			      || isset(&wlc->stf->ss_algo_channel,
+-				       PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
+-		    : PHY_TXC1_MODE_CDD;
+-	} else {
+-		if (wlc->band != band)
+-			return ret_code;
+-		upd_stf_ss = (wlc->stf->no_cddstbc
+-			      || (wlc->stf->txstreams ==
+-				  1)) ? PHY_TXC1_MODE_SISO : band->
+-		    band_stf_ss_mode;
+-	}
+-	if (prev_stf_ss != upd_stf_ss) {
+-		wlc->stf->ss_opmode = upd_stf_ss;
+-		wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss);
+-	}
+-
+-	return ret_code;
+-}
+-
+-int wlc_stf_attach(struct wlc_info *wlc)
+-{
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD;
+-
+-	if (WLCISNPHY(wlc->band) &&
+-	    (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON))
+-		wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode =
+-		    PHY_TXC1_MODE_CDD;
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]);
+-	wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]);
+-
+-	wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO);
+-	wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF;
+-	wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF;
+-
+-	if (WLC_STBC_CAP_PHY(wlc)) {
+-		wlc->stf->ss_algosel_auto = true;
+-		wlc->stf->ss_algo_channel = (u16) -1;	/* Init the default value */
+-	}
+-	return 0;
+-}
+-
+-void wlc_stf_detach(struct wlc_info *wlc)
+-{
+-}
+-
+-int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val)
+-{
+-	int bcmerror = 0;
+-
+-	/* when there is only 1 tx_streams, don't allow to change the txant */
+-	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
+-		return ((val == wlc->stf->txant) ? bcmerror : -EINVAL);
+-
+-	switch (val) {
+-	case -1:
+-		val = ANT_TX_DEF;
+-		break;
+-	case 0:
+-		val = ANT_TX_FORCE_0;
+-		break;
+-	case 1:
+-		val = ANT_TX_FORCE_1;
+-		break;
+-	case 3:
+-		val = ANT_TX_LAST_RX;
+-		break;
+-	default:
+-		bcmerror = -EINVAL;
+-		break;
+-	}
+-
+-	if (bcmerror == 0)
+-		wlc->stf->txant = (s8) val;
+-
+-	return bcmerror;
+-
+-}
+-
+-/*
+- * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain
+- *  change
+- *
+- * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to
+- *   achieve various tx/rx antenna selection schemes
+- *
+- * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx)
+- * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+- *    do tx-antenna selection for SISO transmissions
+- * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and
+- *    do tx-antenna selection for SISO transmissions
+- * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active
+-*/
+-static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc)
+-{
+-	s8 txant;
+-
+-	txant = (s8) wlc->stf->txant;
+-	if (WLC_PHY_11N_CAP(wlc->band)) {
+-		if (txant == ANT_TX_FORCE_0) {
+-			wlc->stf->phytxant = PHY_TXC_ANT_0;
+-		} else if (txant == ANT_TX_FORCE_1) {
+-			wlc->stf->phytxant = PHY_TXC_ANT_1;
+-
+-			if (WLCISNPHY(wlc->band) &&
+-			    NREV_GE(wlc->band->phyrev, 3)
+-			    && NREV_LT(wlc->band->phyrev, 7)) {
+-				wlc->stf->phytxant = PHY_TXC_ANT_2;
+-			}
+-		} else {
+-			if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band))
+-				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
+-			else {
+-				/* catch out of sync wlc->stf->txcore */
+-				WARN_ON(wlc->stf->txchain <= 0);
+-				wlc->stf->phytxant =
+-				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-			}
+-		}
+-	} else {
+-		if (txant == ANT_TX_FORCE_0)
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_0;
+-		else if (txant == ANT_TX_FORCE_1)
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_1;
+-		else
+-			wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST;
+-	}
+-
+-	wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant);
+-}
+-
+-void wlc_stf_phy_txant_upd(struct wlc_info *wlc)
+-{
+-	_wlc_stf_phy_txant_upd(wlc);
+-}
+-
+-void wlc_stf_phy_chain_calc(struct wlc_info *wlc)
+-{
+-	/* get available rx/tx chains */
+-	wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain");
+-	wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain");
+-
+-	/* these parameter are intended to be used for all PHY types */
+-	if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) {
+-		if (WLCISNPHY(wlc->band)) {
+-			wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY;
+-		} else {
+-			wlc->stf->hw_txchain = TXCHAIN_DEF;
+-		}
+-	}
+-
+-	wlc->stf->txchain = wlc->stf->hw_txchain;
+-	wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain);
+-
+-	if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) {
+-		if (WLCISNPHY(wlc->band)) {
+-			wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY;
+-		} else {
+-			wlc->stf->hw_rxchain = RXCHAIN_DEF;
+-		}
+-	}
+-
+-	wlc->stf->rxchain = wlc->stf->hw_rxchain;
+-	wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain);
+-
+-	/* initialize the txcore table */
+-	memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore));
+-
+-	/* default spatial_policy */
+-	wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION;
+-	wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION);
+-}
+-
+-static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phytxant = wlc->stf->phytxant;
+-
+-	if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
+-		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-	} else if (wlc->stf->txant == ANT_TX_DEF)
+-		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
+-	phytxant &= PHY_TXC_ANT_MASK;
+-	return phytxant;
+-}
+-
+-u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	return _wlc_stf_phytxchain_sel(wlc, rspec);
+-}
+-
+-u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec)
+-{
+-	u16 phytxant = wlc->stf->phytxant;
+-	u16 mask = PHY_TXC_ANT_MASK;
+-
+-	/* for non-siso rates or default setting, use the available chains */
+-	if (WLCISNPHY(wlc->band)) {
+-		phytxant = _wlc_stf_phytxchain_sel(wlc, rspec);
+-		mask = PHY_TXC_HTANT_MASK;
+-	}
+-	phytxant |= phytxant & mask;
+-	return phytxant;
+-}
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h
+deleted file mode 100644
+index 2b1180b..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_stf_h_
+-#define _wlc_stf_h_
+-
+-extern int wlc_stf_attach(struct wlc_info *wlc);
+-extern void wlc_stf_detach(struct wlc_info *wlc);
+-
+-extern void wlc_tempsense_upd(struct wlc_info *wlc);
+-extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc,
+-					u16 *ss_algo_channel,
+-					chanspec_t chanspec);
+-extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band);
+-extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force);
+-extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val);
+-
+-extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val);
+-extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc);
+-extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc);
+-extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec);
+-extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec);
+-
+-#endif				/* _wlc_stf_h_ */
+diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/wlc_types.h
+deleted file mode 100644
+index df6e04c..0000000
+--- a/drivers/staging/brcm80211/brcmsmac/wlc_types.h
++++ /dev/null
+@@ -1,37 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlc_types_h_
+-#define _wlc_types_h_
+-
+-/* forward declarations */
+-
+-struct wlc_info;
+-struct wlc_hw_info;
+-struct wlc_if;
+-struct wl_if;
+-struct ampdu_info;
+-struct antsel_info;
+-struct bmac_pmq;
+-
+-struct d11init;
+-
+-#ifndef _hnddma_pub_
+-#define _hnddma_pub_
+-struct hnddma_pub;
+-#endif				/* _hnddma_pub_ */
+-
+-#endif				/* _wlc_types_h_ */
+diff --git a/drivers/staging/brcm80211/include/aidmp.h b/drivers/staging/brcm80211/include/aidmp.h
+deleted file mode 100644
+index 7e0ce8f..0000000
+--- a/drivers/staging/brcm80211/include/aidmp.h
++++ /dev/null
+@@ -1,374 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_AIDMP_H
+-#define	_AIDMP_H
+-
+-/* Manufacturer Ids */
+-#define	MFGID_ARM		0x43b
+-#define	MFGID_BRCM		0x4bf
+-#define	MFGID_MIPS		0x4a7
+-
+-/* Component Classes */
+-#define	CC_SIM			0
+-#define	CC_EROM			1
+-#define	CC_CORESIGHT		9
+-#define	CC_VERIF		0xb
+-#define	CC_OPTIMO		0xd
+-#define	CC_GEN			0xe
+-#define	CC_PRIMECELL		0xf
+-
+-/* Enumeration ROM registers */
+-#define	ER_EROMENTRY		0x000
+-#define	ER_REMAPCONTROL		0xe00
+-#define	ER_REMAPSELECT		0xe04
+-#define	ER_MASTERSELECT		0xe10
+-#define	ER_ITCR			0xf00
+-#define	ER_ITIP			0xf04
+-
+-/* Erom entries */
+-#define	ER_TAG			0xe
+-#define	ER_TAG1			0x6
+-#define	ER_VALID		1
+-#define	ER_CI			0
+-#define	ER_MP			2
+-#define	ER_ADD			4
+-#define	ER_END			0xe
+-#define	ER_BAD			0xffffffff
+-
+-/* EROM CompIdentA */
+-#define	CIA_MFG_MASK		0xfff00000
+-#define	CIA_MFG_SHIFT		20
+-#define	CIA_CID_MASK		0x000fff00
+-#define	CIA_CID_SHIFT		8
+-#define	CIA_CCL_MASK		0x000000f0
+-#define	CIA_CCL_SHIFT		4
+-
+-/* EROM CompIdentB */
+-#define	CIB_REV_MASK		0xff000000
+-#define	CIB_REV_SHIFT		24
+-#define	CIB_NSW_MASK		0x00f80000
+-#define	CIB_NSW_SHIFT		19
+-#define	CIB_NMW_MASK		0x0007c000
+-#define	CIB_NMW_SHIFT		14
+-#define	CIB_NSP_MASK		0x00003e00
+-#define	CIB_NSP_SHIFT		9
+-#define	CIB_NMP_MASK		0x000001f0
+-#define	CIB_NMP_SHIFT		4
+-
+-/* EROM MasterPortDesc */
+-#define	MPD_MUI_MASK		0x0000ff00
+-#define	MPD_MUI_SHIFT		8
+-#define	MPD_MP_MASK		0x000000f0
+-#define	MPD_MP_SHIFT		4
+-
+-/* EROM AddrDesc */
+-#define	AD_ADDR_MASK		0xfffff000
+-#define	AD_SP_MASK		0x00000f00
+-#define	AD_SP_SHIFT		8
+-#define	AD_ST_MASK		0x000000c0
+-#define	AD_ST_SHIFT		6
+-#define	AD_ST_SLAVE		0x00000000
+-#define	AD_ST_BRIDGE		0x00000040
+-#define	AD_ST_SWRAP		0x00000080
+-#define	AD_ST_MWRAP		0x000000c0
+-#define	AD_SZ_MASK		0x00000030
+-#define	AD_SZ_SHIFT		4
+-#define	AD_SZ_4K		0x00000000
+-#define	AD_SZ_8K		0x00000010
+-#define	AD_SZ_16K		0x00000020
+-#define	AD_SZ_SZD		0x00000030
+-#define	AD_AG32			0x00000008
+-#define	AD_ADDR_ALIGN		0x00000fff
+-#define	AD_SZ_BASE		0x00001000	/* 4KB */
+-
+-/* EROM SizeDesc */
+-#define	SD_SZ_MASK		0xfffff000
+-#define	SD_SG32			0x00000008
+-#define	SD_SZ_ALIGN		0x00000fff
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-typedef volatile struct _aidmp {
+-	u32 oobselina30;	/* 0x000 */
+-	u32 oobselina74;	/* 0x004 */
+-	u32 PAD[6];
+-	u32 oobselinb30;	/* 0x020 */
+-	u32 oobselinb74;	/* 0x024 */
+-	u32 PAD[6];
+-	u32 oobselinc30;	/* 0x040 */
+-	u32 oobselinc74;	/* 0x044 */
+-	u32 PAD[6];
+-	u32 oobselind30;	/* 0x060 */
+-	u32 oobselind74;	/* 0x064 */
+-	u32 PAD[38];
+-	u32 oobselouta30;	/* 0x100 */
+-	u32 oobselouta74;	/* 0x104 */
+-	u32 PAD[6];
+-	u32 oobseloutb30;	/* 0x120 */
+-	u32 oobseloutb74;	/* 0x124 */
+-	u32 PAD[6];
+-	u32 oobseloutc30;	/* 0x140 */
+-	u32 oobseloutc74;	/* 0x144 */
+-	u32 PAD[6];
+-	u32 oobseloutd30;	/* 0x160 */
+-	u32 oobseloutd74;	/* 0x164 */
+-	u32 PAD[38];
+-	u32 oobsynca;	/* 0x200 */
+-	u32 oobseloutaen;	/* 0x204 */
+-	u32 PAD[6];
+-	u32 oobsyncb;	/* 0x220 */
+-	u32 oobseloutben;	/* 0x224 */
+-	u32 PAD[6];
+-	u32 oobsyncc;	/* 0x240 */
+-	u32 oobseloutcen;	/* 0x244 */
+-	u32 PAD[6];
+-	u32 oobsyncd;	/* 0x260 */
+-	u32 oobseloutden;	/* 0x264 */
+-	u32 PAD[38];
+-	u32 oobaextwidth;	/* 0x300 */
+-	u32 oobainwidth;	/* 0x304 */
+-	u32 oobaoutwidth;	/* 0x308 */
+-	u32 PAD[5];
+-	u32 oobbextwidth;	/* 0x320 */
+-	u32 oobbinwidth;	/* 0x324 */
+-	u32 oobboutwidth;	/* 0x328 */
+-	u32 PAD[5];
+-	u32 oobcextwidth;	/* 0x340 */
+-	u32 oobcinwidth;	/* 0x344 */
+-	u32 oobcoutwidth;	/* 0x348 */
+-	u32 PAD[5];
+-	u32 oobdextwidth;	/* 0x360 */
+-	u32 oobdinwidth;	/* 0x364 */
+-	u32 oobdoutwidth;	/* 0x368 */
+-	u32 PAD[37];
+-	u32 ioctrlset;	/* 0x400 */
+-	u32 ioctrlclear;	/* 0x404 */
+-	u32 ioctrl;		/* 0x408 */
+-	u32 PAD[61];
+-	u32 iostatus;	/* 0x500 */
+-	u32 PAD[127];
+-	u32 ioctrlwidth;	/* 0x700 */
+-	u32 iostatuswidth;	/* 0x704 */
+-	u32 PAD[62];
+-	u32 resetctrl;	/* 0x800 */
+-	u32 resetstatus;	/* 0x804 */
+-	u32 resetreadid;	/* 0x808 */
+-	u32 resetwriteid;	/* 0x80c */
+-	u32 PAD[60];
+-	u32 errlogctrl;	/* 0x900 */
+-	u32 errlogdone;	/* 0x904 */
+-	u32 errlogstatus;	/* 0x908 */
+-	u32 errlogaddrlo;	/* 0x90c */
+-	u32 errlogaddrhi;	/* 0x910 */
+-	u32 errlogid;	/* 0x914 */
+-	u32 errloguser;	/* 0x918 */
+-	u32 errlogflags;	/* 0x91c */
+-	u32 PAD[56];
+-	u32 intstatus;	/* 0xa00 */
+-	u32 PAD[127];
+-	u32 config;		/* 0xe00 */
+-	u32 PAD[63];
+-	u32 itcr;		/* 0xf00 */
+-	u32 PAD[3];
+-	u32 itipooba;	/* 0xf10 */
+-	u32 itipoobb;	/* 0xf14 */
+-	u32 itipoobc;	/* 0xf18 */
+-	u32 itipoobd;	/* 0xf1c */
+-	u32 PAD[4];
+-	u32 itipoobaout;	/* 0xf30 */
+-	u32 itipoobbout;	/* 0xf34 */
+-	u32 itipoobcout;	/* 0xf38 */
+-	u32 itipoobdout;	/* 0xf3c */
+-	u32 PAD[4];
+-	u32 itopooba;	/* 0xf50 */
+-	u32 itopoobb;	/* 0xf54 */
+-	u32 itopoobc;	/* 0xf58 */
+-	u32 itopoobd;	/* 0xf5c */
+-	u32 PAD[4];
+-	u32 itopoobain;	/* 0xf70 */
+-	u32 itopoobbin;	/* 0xf74 */
+-	u32 itopoobcin;	/* 0xf78 */
+-	u32 itopoobdin;	/* 0xf7c */
+-	u32 PAD[4];
+-	u32 itopreset;	/* 0xf90 */
+-	u32 PAD[15];
+-	u32 peripherialid4;	/* 0xfd0 */
+-	u32 peripherialid5;	/* 0xfd4 */
+-	u32 peripherialid6;	/* 0xfd8 */
+-	u32 peripherialid7;	/* 0xfdc */
+-	u32 peripherialid0;	/* 0xfe0 */
+-	u32 peripherialid1;	/* 0xfe4 */
+-	u32 peripherialid2;	/* 0xfe8 */
+-	u32 peripherialid3;	/* 0xfec */
+-	u32 componentid0;	/* 0xff0 */
+-	u32 componentid1;	/* 0xff4 */
+-	u32 componentid2;	/* 0xff8 */
+-	u32 componentid3;	/* 0xffc */
+-} aidmp_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* Out-of-band Router registers */
+-#define	OOB_BUSCONFIG		0x020
+-#define	OOB_STATUSA		0x100
+-#define	OOB_STATUSB		0x104
+-#define	OOB_STATUSC		0x108
+-#define	OOB_STATUSD		0x10c
+-#define	OOB_ENABLEA0		0x200
+-#define	OOB_ENABLEA1		0x204
+-#define	OOB_ENABLEA2		0x208
+-#define	OOB_ENABLEA3		0x20c
+-#define	OOB_ENABLEB0		0x280
+-#define	OOB_ENABLEB1		0x284
+-#define	OOB_ENABLEB2		0x288
+-#define	OOB_ENABLEB3		0x28c
+-#define	OOB_ENABLEC0		0x300
+-#define	OOB_ENABLEC1		0x304
+-#define	OOB_ENABLEC2		0x308
+-#define	OOB_ENABLEC3		0x30c
+-#define	OOB_ENABLED0		0x380
+-#define	OOB_ENABLED1		0x384
+-#define	OOB_ENABLED2		0x388
+-#define	OOB_ENABLED3		0x38c
+-#define	OOB_ITCR		0xf00
+-#define	OOB_ITIPOOBA		0xf10
+-#define	OOB_ITIPOOBB		0xf14
+-#define	OOB_ITIPOOBC		0xf18
+-#define	OOB_ITIPOOBD		0xf1c
+-#define	OOB_ITOPOOBA		0xf30
+-#define	OOB_ITOPOOBB		0xf34
+-#define	OOB_ITOPOOBC		0xf38
+-#define	OOB_ITOPOOBD		0xf3c
+-
+-/* DMP wrapper registers */
+-#define	AI_OOBSELINA30		0x000
+-#define	AI_OOBSELINA74		0x004
+-#define	AI_OOBSELINB30		0x020
+-#define	AI_OOBSELINB74		0x024
+-#define	AI_OOBSELINC30		0x040
+-#define	AI_OOBSELINC74		0x044
+-#define	AI_OOBSELIND30		0x060
+-#define	AI_OOBSELIND74		0x064
+-#define	AI_OOBSELOUTA30		0x100
+-#define	AI_OOBSELOUTA74		0x104
+-#define	AI_OOBSELOUTB30		0x120
+-#define	AI_OOBSELOUTB74		0x124
+-#define	AI_OOBSELOUTC30		0x140
+-#define	AI_OOBSELOUTC74		0x144
+-#define	AI_OOBSELOUTD30		0x160
+-#define	AI_OOBSELOUTD74		0x164
+-#define	AI_OOBSYNCA		0x200
+-#define	AI_OOBSELOUTAEN		0x204
+-#define	AI_OOBSYNCB		0x220
+-#define	AI_OOBSELOUTBEN		0x224
+-#define	AI_OOBSYNCC		0x240
+-#define	AI_OOBSELOUTCEN		0x244
+-#define	AI_OOBSYNCD		0x260
+-#define	AI_OOBSELOUTDEN		0x264
+-#define	AI_OOBAEXTWIDTH		0x300
+-#define	AI_OOBAINWIDTH		0x304
+-#define	AI_OOBAOUTWIDTH		0x308
+-#define	AI_OOBBEXTWIDTH		0x320
+-#define	AI_OOBBINWIDTH		0x324
+-#define	AI_OOBBOUTWIDTH		0x328
+-#define	AI_OOBCEXTWIDTH		0x340
+-#define	AI_OOBCINWIDTH		0x344
+-#define	AI_OOBCOUTWIDTH		0x348
+-#define	AI_OOBDEXTWIDTH		0x360
+-#define	AI_OOBDINWIDTH		0x364
+-#define	AI_OOBDOUTWIDTH		0x368
+-
+-#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
+-/* Selective swapped defines for those registers we need in
+- * big-endian code.
+- */
+-#define	AI_IOCTRLSET		0x404
+-#define	AI_IOCTRLCLEAR		0x400
+-#define	AI_IOCTRL		0x40c
+-#define	AI_IOSTATUS		0x504
+-#define	AI_RESETCTRL		0x804
+-#define	AI_RESETSTATUS		0x800
+-
+-#else				/* !__BIG_ENDIAN || !BCMHND74K */
+-
+-#define	AI_IOCTRLSET		0x400
+-#define	AI_IOCTRLCLEAR		0x404
+-#define	AI_IOCTRL		0x408
+-#define	AI_IOSTATUS		0x500
+-#define	AI_RESETCTRL		0x800
+-#define	AI_RESETSTATUS		0x804
+-
+-#endif				/* __BIG_ENDIAN && BCMHND74K */
+-
+-#define	AI_IOCTRLWIDTH		0x700
+-#define	AI_IOSTATUSWIDTH	0x704
+-
+-#define	AI_RESETREADID		0x808
+-#define	AI_RESETWRITEID		0x80c
+-#define	AI_ERRLOGCTRL		0xa00
+-#define	AI_ERRLOGDONE		0xa04
+-#define	AI_ERRLOGSTATUS		0xa08
+-#define	AI_ERRLOGADDRLO		0xa0c
+-#define	AI_ERRLOGADDRHI		0xa10
+-#define	AI_ERRLOGID		0xa14
+-#define	AI_ERRLOGUSER		0xa18
+-#define	AI_ERRLOGFLAGS		0xa1c
+-#define	AI_INTSTATUS		0xa00
+-#define	AI_CONFIG		0xe00
+-#define	AI_ITCR			0xf00
+-#define	AI_ITIPOOBA		0xf10
+-#define	AI_ITIPOOBB		0xf14
+-#define	AI_ITIPOOBC		0xf18
+-#define	AI_ITIPOOBD		0xf1c
+-#define	AI_ITIPOOBAOUT		0xf30
+-#define	AI_ITIPOOBBOUT		0xf34
+-#define	AI_ITIPOOBCOUT		0xf38
+-#define	AI_ITIPOOBDOUT		0xf3c
+-#define	AI_ITOPOOBA		0xf50
+-#define	AI_ITOPOOBB		0xf54
+-#define	AI_ITOPOOBC		0xf58
+-#define	AI_ITOPOOBD		0xf5c
+-#define	AI_ITOPOOBAIN		0xf70
+-#define	AI_ITOPOOBBIN		0xf74
+-#define	AI_ITOPOOBCIN		0xf78
+-#define	AI_ITOPOOBDIN		0xf7c
+-#define	AI_ITOPRESET		0xf90
+-#define	AI_PERIPHERIALID4	0xfd0
+-#define	AI_PERIPHERIALID5	0xfd4
+-#define	AI_PERIPHERIALID6	0xfd8
+-#define	AI_PERIPHERIALID7	0xfdc
+-#define	AI_PERIPHERIALID0	0xfe0
+-#define	AI_PERIPHERIALID1	0xfe4
+-#define	AI_PERIPHERIALID2	0xfe8
+-#define	AI_PERIPHERIALID3	0xfec
+-#define	AI_COMPONENTID0		0xff0
+-#define	AI_COMPONENTID1		0xff4
+-#define	AI_COMPONENTID2		0xff8
+-#define	AI_COMPONENTID3		0xffc
+-
+-/* resetctrl */
+-#define	AIRC_RESET		1
+-
+-/* config */
+-#define	AICFG_OOB		0x00000020
+-#define	AICFG_IOS		0x00000010
+-#define	AICFG_IOC		0x00000008
+-#define	AICFG_TO		0x00000004
+-#define	AICFG_ERRL		0x00000002
+-#define	AICFG_RST		0x00000001
+-
+-#endif				/* _AIDMP_H */
+diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h
+deleted file mode 100644
+index 55631f3..0000000
+--- a/drivers/staging/brcm80211/include/bcmdefs.h
++++ /dev/null
+@@ -1,150 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmdefs_h_
+-#define	_bcmdefs_h_
+-
+-#define	SI_BUS			0
+-#define	PCI_BUS			1
+-#define	PCMCIA_BUS		2
+-#define SDIO_BUS		3
+-#define JTAG_BUS		4
+-#define USB_BUS			5
+-#define SPI_BUS			6
+-
+-
+-#ifndef OFF
+-#define	OFF	0
+-#endif
+-
+-#ifndef ON
+-#define	ON	1		/* ON = 1 */
+-#endif
+-
+-#define	AUTO	(-1)		/* Auto = -1 */
+-
+-/* Bus types */
+-#define	SI_BUS			0	/* SOC Interconnect */
+-#define	PCI_BUS			1	/* PCI target */
+-#define SDIO_BUS		3	/* SDIO target */
+-#define JTAG_BUS		4	/* JTAG */
+-#define USB_BUS			5	/* USB (does not support R/W REG) */
+-#define SPI_BUS			6	/* gSPI target */
+-#define RPC_BUS			7	/* RPC target */
+-
+-
+-/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
+-#define DMADDR_MASK_32 0x0	/* Address mask for 32-bits */
+-#define DMADDR_MASK_30 0xc0000000	/* Address mask for 30-bits */
+-#define DMADDR_MASK_0  0xffffffff	/* Address mask for 0-bits (hi-part) */
+-
+-#define	DMADDRWIDTH_30  30	/* 30-bit addressing capability */
+-#define	DMADDRWIDTH_32  32	/* 32-bit addressing capability */
+-#define	DMADDRWIDTH_63  63	/* 64-bit addressing capability */
+-#define	DMADDRWIDTH_64  64	/* 64-bit addressing capability */
+-
+-#ifdef BCMDMA64OSL
+-typedef struct {
+-	u32 loaddr;
+-	u32 hiaddr;
+-} dma64addr_t;
+-
+-typedef dma64addr_t dmaaddr_t;
+-#define PHYSADDRHI(_pa) ((_pa).hiaddr)
+-#define PHYSADDRHISET(_pa, _val) \
+-	do { \
+-		(_pa).hiaddr = (_val);		\
+-	} while (0)
+-#define PHYSADDRLO(_pa) ((_pa).loaddr)
+-#define PHYSADDRLOSET(_pa, _val) \
+-	do { \
+-		(_pa).loaddr = (_val);		\
+-	} while (0)
+-
+-#else
+-typedef unsigned long dmaaddr_t;
+-#define PHYSADDRHI(_pa) (0)
+-#define PHYSADDRHISET(_pa, _val)
+-#define PHYSADDRLO(_pa) ((_pa))
+-#define PHYSADDRLOSET(_pa, _val) \
+-	do { \
+-		(_pa) = (_val);			\
+-	} while (0)
+-#endif				/* BCMDMA64OSL */
+-
+-/* One physical DMA segment */
+-typedef struct {
+-	dmaaddr_t addr;
+-	u32 length;
+-} hnddma_seg_t;
+-
+-#define MAX_DMA_SEGS 4
+-
+-typedef struct {
+-	void *oshdmah;		/* Opaque handle for OSL to store its information */
+-	uint origsize;		/* Size of the virtual packet */
+-	uint nsegs;
+-	hnddma_seg_t segs[MAX_DMA_SEGS];
+-} hnddma_seg_map_t;
+-
+-/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF).
+- * By doing, we avoid the need  to allocate an extra buffer for the header when bridging to WL.
+- * There is a compile time check in wlc.c which ensure that this value is at least as big
+- * as TXOFF. This value is used in dma_rxfill (hnddma.c).
+- */
+-
+-#define BCMEXTRAHDROOM 172
+-
+-/* Macros for doing definition and get/set of bitfields
+- * Usage example, e.g. a three-bit field (bits 4-6):
+- *    #define <NAME>_M	BITFIELD_MASK(3)
+- *    #define <NAME>_S	4
+- * ...
+- *    regval = R_REG(osh, &regs->regfoo);
+- *    field = GFIELD(regval, <NAME>);
+- *    regval = SFIELD(regval, <NAME>, 1);
+- *    W_REG(osh, &regs->regfoo, regval);
+- */
+-#define BITFIELD_MASK(width) \
+-		(((unsigned)1 << (width)) - 1)
+-#define GFIELD(val, field) \
+-		(((val) >> field ## _S) & field ## _M)
+-#define SFIELD(val, field, bits) \
+-		(((val) & (~(field ## _M << field ## _S))) | \
+-		 ((unsigned)(bits) << field ## _S))
+-
+-/*
+- * Priority definitions according 802.1D
+- */
+-#define	PRIO_8021D_NONE		2
+-#define	PRIO_8021D_BK		1
+-#define	PRIO_8021D_BE		0
+-#define	PRIO_8021D_EE		3
+-#define	PRIO_8021D_CL		4
+-#define	PRIO_8021D_VI		5
+-#define	PRIO_8021D_VO		6
+-#define	PRIO_8021D_NC		7
+-#define	MAXPRIO			7
+-#define NUMPRIO			(MAXPRIO + 1)
+-
+-/* Max. nvram variable table size */
+-#define	MAXSZ_NVRAM_VARS	4096
+-
+-/* handle forward declaration */
+-struct wl_info;
+-struct wlc_bsscfg;
+-
+-#endif				/* _bcmdefs_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h
+deleted file mode 100644
+index 26947ef..0000000
+--- a/drivers/staging/brcm80211/include/bcmdevs.h
++++ /dev/null
+@@ -1,124 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_BCMDEVS_H
+-#define	_BCMDEVS_H
+-
+-#define	BCM4325_D11DUAL_ID	0x431b
+-#define	BCM4325_D11G_ID		0x431c
+-#define	BCM4325_D11A_ID		0x431d
+-
+-#define BCM4329_D11N2G_ID	0x432f	/* 4329 802.11n 2.4G device */
+-#define BCM4329_D11N5G_ID	0x4330	/* 4329 802.11n 5G device */
+-#define BCM4329_D11NDUAL_ID	0x432e
+-
+-#define BCM4319_D11N_ID		0x4337	/* 4319 802.11n dualband device */
+-#define BCM4319_D11N2G_ID	0x4338	/* 4319 802.11n 2.4G device */
+-#define BCM4319_D11N5G_ID	0x4339	/* 4319 802.11n 5G device */
+-
+-#define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
+-
+-#define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
+-
+-#define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
+-#define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
+-
+-#define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
+-
+-/* Chip IDs */
+-#define BCM4313_CHIP_ID		0x4313	/* 4313 chip id */
+-#define	BCM4319_CHIP_ID		0x4319	/* 4319 chip id */
+-
+-#define	BCM43224_CHIP_ID	43224	/* 43224 chipcommon chipid */
+-#define	BCM43225_CHIP_ID	43225	/* 43225 chipcommon chipid */
+-#define	BCM43421_CHIP_ID	43421	/* 43421 chipcommon chipid */
+-#define	BCM43235_CHIP_ID	43235	/* 43235 chipcommon chipid */
+-#define	BCM43236_CHIP_ID	43236	/* 43236 chipcommon chipid */
+-#define	BCM43238_CHIP_ID	43238	/* 43238 chipcommon chipid */
+-#define	BCM4329_CHIP_ID		0x4329	/* 4329 chipcommon chipid */
+-#define	BCM4325_CHIP_ID		0x4325	/* 4325 chipcommon chipid */
+-#define	BCM4331_CHIP_ID		0x4331	/* 4331 chipcommon chipid */
+-#define BCM4336_CHIP_ID		0x4336	/* 4336 chipcommon chipid */
+-#define BCM4330_CHIP_ID		0x4330	/* 4330 chipcommon chipid */
+-#define BCM6362_CHIP_ID		0x6362	/* 6362 chipcommon chipid */
+-
+-/* these are router chips */
+-#define	BCM4716_CHIP_ID		0x4716	/* 4716 chipcommon chipid */
+-#define	BCM47162_CHIP_ID	47162	/* 47162 chipcommon chipid */
+-#define	BCM4748_CHIP_ID		0x4748	/* 4716 chipcommon chipid (OTP, RBBU) */
+-#define	BCM5356_CHIP_ID		0x5356	/* 5356 chipcommon chipid */
+-#define	BCM5357_CHIP_ID		0x5357	/* 5357 chipcommon chipid */
+-
+-/* Package IDs */
+-#define BCM4329_289PIN_PKG_ID	0	/* 4329 289-pin package id */
+-#define BCM4329_182PIN_PKG_ID	1	/* 4329N 182-pin package id */
+-#define	BCM4717_PKG_ID		9	/* 4717 package id */
+-#define	BCM4718_PKG_ID		10	/* 4718 package id */
+-#define HDLSIM_PKG_ID		14	/* HDL simulator package id */
+-#define HWSIM_PKG_ID		15	/* Hardware simulator package id */
+-#define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
+-
+-/* boardflags */
+-#define	BFL_PACTRL		0x00000002	/* Board has gpio 9 controlling the PA */
+-#define	BFL_NOPLLDOWN		0x00000020	/* Not ok to power down the chip pll and oscillator */
+-#define BFL_FEM			0x00000800	/* Board supports the Front End Module */
+-#define BFL_EXTLNA		0x00001000	/* Board has an external LNA in 2.4GHz band */
+-#define BFL_NOPA		0x00010000	/* Board has no PA */
+-#define BFL_BUCKBOOST		0x00200000	/* Power topology uses BUCKBOOST */
+-#define BFL_FEM_BT		0x00400000	/* Board has FEM and switch to share antenna w/ BT */
+-#define BFL_NOCBUCK		0x00800000	/* Power topology doesn't use CBUCK */
+-#define BFL_PALDO		0x02000000	/* Power topology uses PALDO */
+-#define BFL_EXTLNA_5GHz		0x10000000	/* Board has an external LNA in 5GHz band */
+-
+-/* boardflags2 */
+-#define BFL2_RXBB_INT_REG_DIS	0x00000001	/* Board has an external rxbb regulator */
+-#define BFL2_APLL_WAR		0x00000002	/* Flag to implement alternative A-band PLL settings */
+-#define BFL2_TXPWRCTRL_EN	0x00000004	/* Board permits enabling TX Power Control */
+-#define BFL2_2X4_DIV		0x00000008	/* Board supports the 2X4 diversity switch */
+-#define BFL2_5G_PWRGAIN		0x00000010	/* Board supports 5G band power gain */
+-#define BFL2_PCIEWAR_OVR	0x00000020	/* Board overrides ASPM and Clkreq settings */
+-#define BFL2_LEGACY		0x00000080
+-#define BFL2_SKWRKFEM_BRD	0x00000100	/* 4321mcm93 board uses Skyworks FEM */
+-#define BFL2_SPUR_WAR		0x00000200	/* Board has a WAR for clock-harmonic spurs */
+-#define BFL2_GPLL_WAR		0x00000400	/* Flag to narrow G-band PLL loop b/w */
+-#define BFL2_SINGLEANT_CCK	0x00001000	/* Tx CCK pkts on Ant 0 only */
+-#define BFL2_2G_SPUR_WAR	0x00002000	/* WAR to reduce and avoid clock-harmonic spurs in 2G */
+-#define BFL2_GPLL_WAR2	        0x00010000	/* Flag to widen G-band PLL loop b/w */
+-#define BFL2_IPALVLSHIFT_3P3    0x00020000
+-#define BFL2_INTERNDET_TXIQCAL  0x00040000	/* Use internal envelope detector for TX IQCAL */
+-#define BFL2_XTALBUFOUTEN       0x00080000	/* Keep the buffered Xtal output from radio "ON"
+-						 * Most drivers will turn it off without this flag
+-						 * to save power.
+-						 */
+-
+-/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
+-#define	BOARD_GPIO_PACTRL	0x200	/* bit 9 controls the PA on new 4306 boards */
+-#define BOARD_GPIO_12		0x1000	/* gpio 12 */
+-#define BOARD_GPIO_13		0x2000	/* gpio 13 */
+-
+-#define	PCI_CFG_GPIO_SCS	0x10	/* PCI config space bit 4 for 4306c0 slow clock source */
+-#define PCI_CFG_GPIO_XTAL	0x40	/* PCI config space GPIO 14 for Xtal power-up */
+-#define PCI_CFG_GPIO_PLL	0x80	/* PCI config space GPIO 15 for PLL power-down */
+-
+-/* power control defines */
+-#define PLL_DELAY		150	/* us pll on delay */
+-#define FREF_DELAY		200	/* us fref change delay */
+-#define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
+-
+-/* Reference board types */
+-#define	SPI_BOARD		0x0402
+-
+-#endif				/* _BCMDEVS_H */
+diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h
+deleted file mode 100644
+index 12645dd..0000000
+--- a/drivers/staging/brcm80211/include/bcmnvram.h
++++ /dev/null
+@@ -1,153 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _bcmnvram_h_
+-#define _bcmnvram_h_
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-#include <bcmdefs.h>
+-
+-struct nvram_header {
+-	u32 magic;
+-	u32 len;
+-	u32 crc_ver_init;	/* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+-	u32 config_refresh;	/* 0:15 sdram_config, 16:31 sdram_refresh */
+-	u32 config_ncdl;	/* ncdl values for memc */
+-};
+-
+-/*
+- * Initialize NVRAM access. May be unnecessary or undefined on certain
+- * platforms.
+- */
+-extern int nvram_init(void);
+-
+-/*
+- * Append a chunk of nvram variables to the global list
+- */
+-extern int nvram_append(char *vars, uint varsz);
+-
+-/*
+- * Check for reset button press for restoring factory defaults.
+- */
+-extern int nvram_reset(void);
+-
+-/*
+- * Disable NVRAM access. May be unnecessary or undefined on certain
+- * platforms.
+- */
+-extern void nvram_exit(void);
+-
+-/*
+- * Get the value of an NVRAM variable. The pointer returned may be
+- * invalid after a set.
+- * @param	name	name of variable to get
+- * @return	value of variable or NULL if undefined
+- */
+-extern char *nvram_get(const char *name);
+-
+-/*
+- * Get the value of an NVRAM variable.
+- * @param	name	name of variable to get
+- * @return	value of variable or NUL if undefined
+- */
+-#define nvram_safe_get(name) (nvram_get(name) ? : "")
+-
+-/*
+- * Match an NVRAM variable.
+- * @param	name	name of variable to match
+- * @param	match	value to compare against value of variable
+- * @return	true if variable is defined and its value is string equal
+- *		to match or false otherwise
+- */
+-static inline int nvram_match(char *name, char *match)
+-{
+-	const char *value = nvram_get(name);
+-	return value && !strcmp(value, match);
+-}
+-
+-/*
+- * Inversely match an NVRAM variable.
+- * @param	name	name of variable to match
+- * @param	match	value to compare against value of variable
+- * @return	true if variable is defined and its value is not string
+- *		equal to invmatch or false otherwise
+- */
+-static inline int nvram_invmatch(char *name, char *invmatch)
+-{
+-	const char *value = nvram_get(name);
+-	return value && strcmp(value, invmatch);
+-}
+-
+-/*
+- * Set the value of an NVRAM variable. The name and value strings are
+- * copied into private storage. Pointers to previously set values
+- * may become invalid. The new value may be immediately
+- * retrieved but will not be permanently stored until a commit.
+- * @param	name	name of variable to set
+- * @param	value	value of variable
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_set(const char *name, const char *value);
+-
+-/*
+- * Unset an NVRAM variable. Pointers to previously set values
+- * remain valid until a set.
+- * @param	name	name of variable to unset
+- * @return	0 on success and errno on failure
+- * NOTE: use nvram_commit to commit this change to flash.
+- */
+-extern int nvram_unset(const char *name);
+-
+-/*
+- * Commit NVRAM variables to permanent storage. All pointers to values
+- * may be invalid after a commit.
+- * NVRAM values are undefined after a commit.
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_commit(void);
+-
+-/*
+- * Get all NVRAM variables (format name=value\0 ... \0\0).
+- * @param	buf	buffer to store variables
+- * @param	count	size of buffer in bytes
+- * @return	0 on success and errno on failure
+- */
+-extern int nvram_getall(char *nvram_buf, int count);
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* variable access */
+-extern char *getvar(char *vars, const char *name);
+-extern int getintvar(char *vars, const char *name);
+-
+-/* The NVRAM version number stored as an NVRAM variable */
+-#define NVRAM_SOFTWARE_VERSION	"1"
+-
+-#define NVRAM_MAGIC		0x48534C46	/* 'FLSH' */
+-#define NVRAM_CLEAR_MAGIC	0x0
+-#define NVRAM_INVALID_MAGIC	0xFFFFFFFF
+-#define NVRAM_VERSION		1
+-#define NVRAM_HEADER_SIZE	20
+-#define NVRAM_SPACE		0x8000
+-
+-#define NVRAM_MAX_VALUE_LEN 255
+-#define NVRAM_MAX_PARAM_LEN 64
+-
+-#define NVRAM_CRC_START_POSITION	9	/* magic, len, crc8 to be skipped */
+-#define NVRAM_CRC_VER_MASK	0xffffff00	/* for crc_ver_init */
+-
+-#endif				/* _bcmnvram_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmotp.h b/drivers/staging/brcm80211/include/bcmotp.h
+deleted file mode 100644
+index 5803acc..0000000
+--- a/drivers/staging/brcm80211/include/bcmotp.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmotp_h_
+-#define	_bcmotp_h_
+-
+-/* OTP regions */
+-#define OTP_HW_RGN	1
+-#define OTP_SW_RGN	2
+-#define OTP_CI_RGN	4
+-#define OTP_FUSE_RGN	8
+-#define OTP_ALL_RGN	0xf	/* From h/w region to end of OTP including checksum */
+-
+-/* OTP Size */
+-#define OTP_SZ_MAX		(6144/8)	/* maximum bytes in one CIS */
+-
+-/* Fixed size subregions sizes in words */
+-#define OTPGU_CI_SZ		2
+-
+-/* OTP usage */
+-#define OTP4325_FM_DISABLED_OFFSET	188
+-
+-/* Exported functions */
+-extern int otp_status(void *oh);
+-extern int otp_size(void *oh);
+-extern u16 otp_read_bit(void *oh, uint offset);
+-extern void *otp_init(si_t *sih);
+-extern int otp_read_region(si_t *sih, int region, u16 *data, uint *wlen);
+-extern int otp_nvread(void *oh, char *data, uint *len);
+-
+-#endif				/* _bcmotp_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h
+deleted file mode 100644
+index 3b57dc1..0000000
+--- a/drivers/staging/brcm80211/include/bcmsdh.h
++++ /dev/null
+@@ -1,205 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsdh_h_
+-#define	_bcmsdh_h_
+-
+-#include <linux/skbuff.h>
+-#define BCMSDH_ERROR_VAL	0x0001	/* Error */
+-#define BCMSDH_INFO_VAL		0x0002	/* Info */
+-extern const uint bcmsdh_msglevel;
+-
+-#ifdef BCMDBG
+-#define BCMSDH_ERROR(x) \
+-	do { \
+-		if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#define BCMSDH_INFO(x)	\
+-	do { \
+-		if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) \
+-			printk x; \
+-	} while (0)
+-#else				/* BCMDBG */
+-#define BCMSDH_ERROR(x)
+-#define BCMSDH_INFO(x)
+-#endif				/* BCMDBG */
+-
+-/* forward declarations */
+-typedef struct bcmsdh_info bcmsdh_info_t;
+-typedef void (*bcmsdh_cb_fn_t) (void *);
+-
+-/* Attach and build an interface to the underlying SD host driver.
+- *  - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh.
+- *  - Returns the bcmsdh handle and virtual address base for register access.
+- *    The returned handle should be used in all subsequent calls, but the bcmsh
+- *    implementation may maintain a single "default" handle (e.g. the first or
+- *    most recent one) to enable single-instance implementations to pass NULL.
+- */
+-extern bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq);
+-
+-/* Detach - freeup resources allocated in attach */
+-extern int bcmsdh_detach(void *sdh);
+-
+-/* Query if SD device interrupts are enabled */
+-extern bool bcmsdh_intr_query(void *sdh);
+-
+-/* Enable/disable SD interrupt */
+-extern int bcmsdh_intr_enable(void *sdh);
+-extern int bcmsdh_intr_disable(void *sdh);
+-
+-/* Register/deregister device interrupt handler. */
+-extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+-extern int bcmsdh_intr_dereg(void *sdh);
+-
+-#if defined(DHD_DEBUG)
+-/* Query pending interrupt status from the host controller */
+-extern bool bcmsdh_intr_pending(void *sdh);
+-#endif
+-extern int bcmsdh_claim_host_and_lock(void *sdh);
+-extern int bcmsdh_release_host_and_unlock(void *sdh);
+-
+-/* Register a callback to be called if and when bcmsdh detects
+- * device removal. No-op in the case of non-removable/hardwired devices.
+- */
+-extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh);
+-
+-/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
+- *   fn:   function number
+- *   addr: unmodified SDIO-space address
+- *   data: data byte to write
+- *   err:  pointer to error code (or NULL)
+- */
+-extern u8 bcmsdh_cfg_read(void *sdh, uint func, u32 addr, int *err);
+-extern void bcmsdh_cfg_write(void *sdh, uint func, u32 addr, u8 data,
+-			     int *err);
+-
+-/* Read/Write 4bytes from/to cfg space */
+-extern u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr,
+-				   int *err);
+-extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr,
+-				  u32 data, int *err);
+-
+-/* Read CIS content for specified function.
+- *   fn:     function whose CIS is being requested (0 is common CIS)
+- *   cis:    pointer to memory location to place results
+- *   length: number of bytes to read
+- * Internally, this routine uses the values from the cis base regs (0x9-0xB)
+- * to form an SDIO-space address to read the data from.
+- */
+-extern int bcmsdh_cis_read(void *sdh, uint func, u8 *cis, uint length);
+-
+-/* Synchronous access to device (client) core registers via CMD53 to F1.
+- *   addr: backplane address (i.e. >= regsva from attach)
+- *   size: register width in bytes (2 or 4)
+- *   data: data for register write
+- */
+-extern u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size);
+-extern u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data);
+-
+-/* Indicate if last reg read/write failed */
+-extern bool bcmsdh_regfail(void *sdh);
+-
+-/* Buffer transfer to/from device (client) core via cmd53.
+- *   fn:       function number
+- *   addr:     backplane address (i.e. >= regsva from attach)
+- *   flags:    backplane width, address increment, sync/async
+- *   buf:      pointer to memory data buffer
+- *   nbytes:   number of bytes to transfer to/from buf
+- *   pkt:      pointer to packet associated with buf (if any)
+- *   complete: callback function for command completion (async only)
+- *   handle:   handle for completion callback (first arg in callback)
+- * Returns 0 or error code.
+- * NOTE: Async operation is not currently supported.
+- */
+-typedef void (*bcmsdh_cmplt_fn_t) (void *handle, int status, bool sync_waiting);
+-extern int bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags,
+-			   u8 *buf, uint nbytes, void *pkt,
+-			   bcmsdh_cmplt_fn_t complete, void *handle);
+-extern int bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags,
+-			   u8 *buf, uint nbytes, struct sk_buff *pkt,
+-			   bcmsdh_cmplt_fn_t complete, void *handle);
+-
+-/* Flags bits */
+-#define SDIO_REQ_4BYTE	0x1	/* Four-byte target (backplane) width (vs. two-byte) */
+-#define SDIO_REQ_FIXED	0x2	/* Fixed address (FIFO) (vs. incrementing address) */
+-#define SDIO_REQ_ASYNC	0x4	/* Async request (vs. sync request) */
+-
+-/* Pending (non-error) return code */
+-#define BCME_PENDING	1
+-
+-/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
+- *   rw:       read or write (0/1)
+- *   addr:     direct SDIO address
+- *   buf:      pointer to memory data buffer
+- *   nbytes:   number of bytes to transfer to/from buf
+- * Returns 0 or error code.
+- */
+-extern int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf,
+-			 uint nbytes);
+-
+-/* Issue an abort to the specified function */
+-extern int bcmsdh_abort(void *sdh, uint fn);
+-
+-/* Start SDIO Host Controller communication */
+-extern int bcmsdh_start(void *sdh, int stage);
+-
+-/* Stop SDIO Host Controller communication */
+-extern int bcmsdh_stop(void *sdh);
+-
+-/* Returns the "Device ID" of target device on the SDIO bus. */
+-extern int bcmsdh_query_device(void *sdh);
+-
+-/* Returns the number of IO functions reported by the device */
+-extern uint bcmsdh_query_iofnum(void *sdh);
+-
+-/* Miscellaneous knob tweaker. */
+-extern int bcmsdh_iovar_op(void *sdh, const char *name,
+-			   void *params, int plen, void *arg, int len,
+-			   bool set);
+-
+-/* Reset and reinitialize the device */
+-extern int bcmsdh_reset(bcmsdh_info_t *sdh);
+-
+-/* helper functions */
+-
+-extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh);
+-
+-/* callback functions */
+-typedef struct {
+-	/* attach to device */
+-	void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot,
+-			 u16 func, uint bustype, void *regsva, void *param);
+-	/* detach from device */
+-	void (*detach) (void *ch);
+-} bcmsdh_driver_t;
+-
+-/* platform specific/high level functions */
+-extern int bcmsdh_register(bcmsdh_driver_t *driver);
+-extern void bcmsdh_unregister(void);
+-extern bool bcmsdh_chipmatch(u16 vendor, u16 device);
+-extern void bcmsdh_device_remove(void *sdh);
+-
+-/* Function to pass device-status bits to DHD. */
+-extern u32 bcmsdh_get_dstatus(void *sdh);
+-
+-/* Function to return current window addr */
+-extern u32 bcmsdh_cur_sbwad(void *sdh);
+-
+-/* Function to pass chipid and rev to lower layers for controlling pr's */
+-extern void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev);
+-
+-#endif				/* _bcmsdh_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsdpcm.h b/drivers/staging/brcm80211/include/bcmsdpcm.h
+deleted file mode 100644
+index 5175e67..0000000
+--- a/drivers/staging/brcm80211/include/bcmsdpcm.h
++++ /dev/null
+@@ -1,208 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsdpcm_h_
+-#define	_bcmsdpcm_h_
+-
+-/*
+- * Software allocation of To SB Mailbox resources
+- */
+-
+-/* intstatus bits */
+-#define I_SMB_NAK	I_SMB_SW0	/* To SB Mailbox Frame NAK */
+-#define I_SMB_INT_ACK	I_SMB_SW1	/* To SB Mailbox Host Interrupt ACK */
+-#define I_SMB_USE_OOB	I_SMB_SW2	/* To SB Mailbox Use OOB Wakeup */
+-#define I_SMB_DEV_INT	I_SMB_SW3	/* To SB Mailbox Miscellaneous Interrupt */
+-
+-#define I_TOSBMAIL      (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT)
+-
+-/* tosbmailbox bits corresponding to intstatus bits */
+-#define SMB_NAK		(1 << 0)	/* To SB Mailbox Frame NAK */
+-#define SMB_INT_ACK	(1 << 1)	/* To SB Mailbox Host Interrupt ACK */
+-#define SMB_USE_OOB	(1 << 2)	/* To SB Mailbox Use OOB Wakeup */
+-#define SMB_DEV_INT	(1 << 3)	/* To SB Mailbox Miscellaneous Interrupt */
+-#define SMB_MASK	0x0000000f	/* To SB Mailbox Mask */
+-
+-/* tosbmailboxdata */
+-#define SMB_DATA_VERSION_MASK	0x00ff0000	/* host protocol version (sent with F2 enable) */
+-#define SMB_DATA_VERSION_SHIFT	16	/* host protocol version (sent with F2 enable) */
+-
+-/*
+- * Software allocation of To Host Mailbox resources
+- */
+-
+-/* intstatus bits */
+-#define I_HMB_FC_STATE	I_HMB_SW0	/* To Host Mailbox Flow Control State */
+-#define I_HMB_FC_CHANGE	I_HMB_SW1	/* To Host Mailbox Flow Control State Changed */
+-#define I_HMB_FRAME_IND	I_HMB_SW2	/* To Host Mailbox Frame Indication */
+-#define I_HMB_HOST_INT	I_HMB_SW3	/* To Host Mailbox Miscellaneous Interrupt */
+-
+-#define I_TOHOSTMAIL    (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT)
+-
+-/* tohostmailbox bits corresponding to intstatus bits */
+-#define HMB_FC_ON	(1 << 0)	/* To Host Mailbox Flow Control State */
+-#define HMB_FC_CHANGE	(1 << 1)	/* To Host Mailbox Flow Control State Changed */
+-#define HMB_FRAME_IND	(1 << 2)	/* To Host Mailbox Frame Indication */
+-#define HMB_HOST_INT	(1 << 3)	/* To Host Mailbox Miscellaneous Interrupt */
+-#define HMB_MASK	0x0000000f	/* To Host Mailbox Mask */
+-
+-/* tohostmailboxdata */
+-#define HMB_DATA_NAKHANDLED	1	/* we're ready to retransmit NAK'd frame to host */
+-#define HMB_DATA_DEVREADY	2	/* we're ready to to talk to host after enable */
+-#define HMB_DATA_FC		4	/* per prio flowcontrol update flag to host */
+-#define HMB_DATA_FWREADY	8	/* firmware is ready for protocol activity */
+-
+-#define HMB_DATA_FCDATA_MASK	0xff000000	/* per prio flowcontrol data */
+-#define HMB_DATA_FCDATA_SHIFT	24	/* per prio flowcontrol data */
+-
+-#define HMB_DATA_VERSION_MASK	0x00ff0000	/* device protocol version (with devready) */
+-#define HMB_DATA_VERSION_SHIFT	16	/* device protocol version (with devready) */
+-
+-/*
+- * Software-defined protocol header
+- */
+-
+-/* Current protocol version */
+-#define SDPCM_PROT_VERSION	4
+-
+-/* SW frame header */
+-#define SDPCM_SEQUENCE_MASK		0x000000ff	/* Sequence Number Mask */
+-#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)	/* p starts w/SW Header */
+-
+-#define SDPCM_CHANNEL_MASK		0x00000f00	/* Channel Number Mask */
+-#define SDPCM_CHANNEL_SHIFT		8	/* Channel Number Shift */
+-#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)	/* p starts w/SW Header */
+-
+-#define SDPCM_FLAGS_MASK		0x0000f000	/* Mask of flag bits */
+-#define SDPCM_FLAGS_SHIFT		12	/* Flag bits shift */
+-#define SDPCM_PACKET_FLAGS(p) ((((u8 *)p)[1] & 0xf0) >> 4)	/* p starts w/SW Header */
+-
+-/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */
+-#define SDPCM_NEXTLEN_MASK		0x00ff0000	/* Next Read Len Mask */
+-#define SDPCM_NEXTLEN_SHIFT		16	/* Next Read Len Shift */
+-#define SDPCM_NEXTLEN_VALUE(p) ((((u8 *)p)[2] & 0xff) << 4)	/* p starts w/SW Header */
+-#define SDPCM_NEXTLEN_OFFSET		2
+-
+-/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
+-#define SDPCM_DOFFSET_OFFSET		3	/* Data Offset */
+-#define SDPCM_DOFFSET_VALUE(p) 		(((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
+-#define SDPCM_DOFFSET_MASK		0xff000000
+-#define SDPCM_DOFFSET_SHIFT		24
+-
+-#define SDPCM_FCMASK_OFFSET		4	/* Flow control */
+-#define SDPCM_FCMASK_VALUE(p)		(((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
+-#define SDPCM_WINDOW_OFFSET		5	/* Credit based fc */
+-#define SDPCM_WINDOW_VALUE(p)		(((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
+-#define SDPCM_VERSION_OFFSET		6	/* Version # */
+-#define SDPCM_VERSION_VALUE(p)		(((u8 *)p)[SDPCM_VERSION_OFFSET] & 0xff)
+-#define SDPCM_UNUSED_OFFSET		7	/* Spare */
+-#define SDPCM_UNUSED_VALUE(p)		(((u8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff)
+-
+-#define SDPCM_SWHEADER_LEN	8	/* SW header is 64 bits */
+-
+-/* logical channel numbers */
+-#define SDPCM_CONTROL_CHANNEL	0	/* Control Request/Response Channel Id */
+-#define SDPCM_EVENT_CHANNEL	1	/* Asyc Event Indication Channel Id */
+-#define SDPCM_DATA_CHANNEL	2	/* Data Xmit/Recv Channel Id */
+-#define SDPCM_GLOM_CHANNEL	3	/* For coalesced packets (superframes) */
+-#define SDPCM_TEST_CHANNEL	15	/* Reserved for test/debug packets */
+-#define SDPCM_MAX_CHANNEL	15
+-
+-#define SDPCM_SEQUENCE_WRAP	256	/* wrap-around val for eight-bit frame seq number */
+-
+-#define SDPCM_FLAG_RESVD0	0x01
+-#define SDPCM_FLAG_RESVD1	0x02
+-#define SDPCM_FLAG_GSPI_TXENAB	0x04
+-#define SDPCM_FLAG_GLOMDESC	0x08	/* Superframe descriptor mask */
+-
+-/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */
+-#define SDPCM_GLOMDESC_FLAG	(SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT)
+-
+-#define SDPCM_GLOMDESC(p)	(((u8 *)p)[1] & 0x80)
+-
+-/* For TEST_CHANNEL packets, define another 4-byte header */
+-#define SDPCM_TEST_HDRLEN	4	/* Generally: Cmd(1), Ext(1), Len(2);
+-					 * Semantics of Ext byte depend on command.
+-					 * Len is current or requested frame length, not
+-					 * including test header; sent little-endian.
+-					 */
+-#define SDPCM_TEST_DISCARD	0x01	/* Receiver discards. Ext is a pattern id. */
+-#define SDPCM_TEST_ECHOREQ	0x02	/* Echo request. Ext is a pattern id. */
+-#define SDPCM_TEST_ECHORSP	0x03	/* Echo response. Ext is a pattern id. */
+-#define SDPCM_TEST_BURST	0x04	/* Receiver to send a burst. Ext is a frame count */
+-#define SDPCM_TEST_SEND		0x05	/* Receiver sets send mode. Ext is boolean on/off */
+-
+-/* Handy macro for filling in datagen packets with a pattern */
+-#define SDPCM_TEST_FILL(byteno, id)	((u8)(id + byteno))
+-
+-/*
+- * Software counters (first part matches hardware counters)
+- */
+-
+-typedef volatile struct {
+-	u32 cmd52rd;		/* Cmd52RdCount, SDIO: cmd52 reads */
+-	u32 cmd52wr;		/* Cmd52WrCount, SDIO: cmd52 writes */
+-	u32 cmd53rd;		/* Cmd53RdCount, SDIO: cmd53 reads */
+-	u32 cmd53wr;		/* Cmd53WrCount, SDIO: cmd53 writes */
+-	u32 abort;		/* AbortCount, SDIO: aborts */
+-	u32 datacrcerror;	/* DataCrcErrorCount, SDIO: frames w/CRC error */
+-	u32 rdoutofsync;	/* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */
+-	u32 wroutofsync;	/* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */
+-	u32 writebusy;	/* WriteBusyCount, SDIO: device asserted "busy" */
+-	u32 readwait;	/* ReadWaitCount, SDIO: no data ready for a read cmd */
+-	u32 readterm;	/* ReadTermCount, SDIO: read frame termination cmds */
+-	u32 writeterm;	/* WriteTermCount, SDIO: write frames termination cmds */
+-	u32 rxdescuflo;	/* receive descriptor underflows */
+-	u32 rxfifooflo;	/* receive fifo overflows */
+-	u32 txfifouflo;	/* transmit fifo underflows */
+-	u32 runt;		/* runt (too short) frames recv'd from bus */
+-	u32 badlen;		/* frame's rxh len does not match its hw tag len */
+-	u32 badcksum;	/* frame's hw tag chksum doesn't agree with len value */
+-	u32 seqbreak;	/* break in sequence # space from one rx frame to the next */
+-	u32 rxfcrc;		/* frame rx header indicates crc error */
+-	u32 rxfwoos;		/* frame rx header indicates write out of sync */
+-	u32 rxfwft;		/* frame rx header indicates write frame termination */
+-	u32 rxfabort;	/* frame rx header indicates frame aborted */
+-	u32 woosint;		/* write out of sync interrupt */
+-	u32 roosint;		/* read out of sync interrupt */
+-	u32 rftermint;	/* read frame terminate interrupt */
+-	u32 wftermint;	/* write frame terminate interrupt */
+-} sdpcmd_cnt_t;
+-
+-/*
+- * Shared structure between dongle and the host.
+- * The structure contains pointers to trap or assert information.
+- */
+-#define SDPCM_SHARED_VERSION       0x0002
+-#define SDPCM_SHARED_VERSION_MASK  0x00FF
+-#define SDPCM_SHARED_ASSERT_BUILT  0x0100
+-#define SDPCM_SHARED_ASSERT        0x0200
+-#define SDPCM_SHARED_TRAP          0x0400
+-
+-typedef struct {
+-	u32 flags;
+-	u32 trap_addr;
+-	u32 assert_exp_addr;
+-	u32 assert_file_addr;
+-	u32 assert_line;
+-	u32 console_addr;	/* Address of hndrte_cons_t */
+-	u32 msgtrace_addr;
+-	u8 tag[32];
+-} sdpcm_shared_t;
+-
+-extern sdpcm_shared_t sdpcm_shared;
+-
+-#endif				/* _bcmsdpcm_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/include/bcmsrom.h
+deleted file mode 100644
+index b2dc895..0000000
+--- a/drivers/staging/brcm80211/include/bcmsrom.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_h_
+-#define	_bcmsrom_h_
+-
+-#include <bcmsrom_fmt.h>
+-
+-/* Prototypes */
+-extern int srom_var_init(si_t *sih, uint bus, void *curmap,
+-			 char **vars, uint *count);
+-
+-extern int srom_read(si_t *sih, uint bus, void *curmap,
+-		     uint byteoff, uint nbytes, u16 *buf, bool check_crc);
+-
+-/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP
+- *   and extract from it into name=value pairs
+- */
+-extern int srom_parsecis(u8 **pcis, uint ciscnt,
+-			 char **vars, uint *count);
+-#endif				/* _bcmsrom_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h
+deleted file mode 100644
+index 4666afd..0000000
+--- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h
++++ /dev/null
+@@ -1,367 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmsrom_fmt_h_
+-#define	_bcmsrom_fmt_h_
+-
+-/* Maximum srom: 6 Kilobits == 768 bytes */
+-#define	SROM_MAX		768
+-#define SROM_MAXW		384
+-#define VARS_MAX		4096
+-
+-/* PCI fields */
+-#define PCI_F0DEVID		48
+-
+-#define	SROM_WORDS		64
+-
+-#define SROM3_SWRGN_OFF		28	/* s/w region offset in words */
+-
+-#define	SROM_SSID		2
+-
+-#define	SROM_WL1LHMAXP		29
+-
+-#define	SROM_WL1LPAB0		30
+-#define	SROM_WL1LPAB1		31
+-#define	SROM_WL1LPAB2		32
+-
+-#define	SROM_WL1HPAB0		33
+-#define	SROM_WL1HPAB1		34
+-#define	SROM_WL1HPAB2		35
+-
+-#define	SROM_MACHI_IL0		36
+-#define	SROM_MACMID_IL0		37
+-#define	SROM_MACLO_IL0		38
+-#define	SROM_MACHI_ET0		39
+-#define	SROM_MACMID_ET0		40
+-#define	SROM_MACLO_ET0		41
+-#define	SROM_MACHI_ET1		42
+-#define	SROM_MACMID_ET1		43
+-#define	SROM_MACLO_ET1		44
+-#define	SROM3_MACHI		37
+-#define	SROM3_MACMID		38
+-#define	SROM3_MACLO		39
+-
+-#define	SROM_BXARSSI2G		40
+-#define	SROM_BXARSSI5G		41
+-
+-#define	SROM_TRI52G		42
+-#define	SROM_TRI5GHL		43
+-
+-#define	SROM_RXPO52G		45
+-
+-#define	SROM2_ENETPHY		45
+-
+-#define	SROM_AABREV		46
+-/* Fields in AABREV */
+-#define	SROM_BR_MASK		0x00ff
+-#define	SROM_CC_MASK		0x0f00
+-#define	SROM_CC_SHIFT		8
+-#define	SROM_AA0_MASK		0x3000
+-#define	SROM_AA0_SHIFT		12
+-#define	SROM_AA1_MASK		0xc000
+-#define	SROM_AA1_SHIFT		14
+-
+-#define	SROM_WL0PAB0		47
+-#define	SROM_WL0PAB1		48
+-#define	SROM_WL0PAB2		49
+-
+-#define	SROM_LEDBH10		50
+-#define	SROM_LEDBH32		51
+-
+-#define	SROM_WL10MAXP		52
+-
+-#define	SROM_WL1PAB0		53
+-#define	SROM_WL1PAB1		54
+-#define	SROM_WL1PAB2		55
+-
+-#define	SROM_ITT		56
+-
+-#define	SROM_BFL		57
+-#define	SROM_BFL2		28
+-#define	SROM3_BFL2		61
+-
+-#define	SROM_AG10		58
+-
+-#define	SROM_CCODE		59
+-
+-#define	SROM_OPO		60
+-
+-#define	SROM3_LEDDC		62
+-
+-#define	SROM_CRCREV		63
+-
+-/* SROM Rev 4: Reallocate the software part of the srom to accommodate
+- * MIMO features. It assumes up to two PCIE functions and 440 bytes
+- * of usable srom i.e. the usable storage in chips with OTP that
+- * implements hardware redundancy.
+- */
+-
+-#define	SROM4_WORDS		220
+-
+-#define	SROM4_SIGN		32
+-#define	SROM4_SIGNATURE		0x5372
+-
+-#define	SROM4_BREV		33
+-
+-#define	SROM4_BFL0		34
+-#define	SROM4_BFL1		35
+-#define	SROM4_BFL2		36
+-#define	SROM4_BFL3		37
+-#define	SROM5_BFL0		37
+-#define	SROM5_BFL1		38
+-#define	SROM5_BFL2		39
+-#define	SROM5_BFL3		40
+-
+-#define	SROM4_MACHI		38
+-#define	SROM4_MACMID		39
+-#define	SROM4_MACLO		40
+-#define	SROM5_MACHI		41
+-#define	SROM5_MACMID		42
+-#define	SROM5_MACLO		43
+-
+-#define	SROM4_CCODE		41
+-#define	SROM4_REGREV		42
+-#define	SROM5_CCODE		34
+-#define	SROM5_REGREV		35
+-
+-#define	SROM4_LEDBH10		43
+-#define	SROM4_LEDBH32		44
+-#define	SROM5_LEDBH10		59
+-#define	SROM5_LEDBH32		60
+-
+-#define	SROM4_LEDDC		45
+-#define	SROM5_LEDDC		45
+-
+-#define	SROM4_AA		46
+-#define	SROM4_AA2G_MASK		0x00ff
+-#define	SROM4_AA2G_SHIFT	0
+-#define	SROM4_AA5G_MASK		0xff00
+-#define	SROM4_AA5G_SHIFT	8
+-
+-#define	SROM4_AG10		47
+-#define	SROM4_AG32		48
+-
+-#define	SROM4_TXPID2G		49
+-#define	SROM4_TXPID5G		51
+-#define	SROM4_TXPID5GL		53
+-#define	SROM4_TXPID5GH		55
+-
+-#define SROM4_TXRXC		61
+-#define SROM4_TXCHAIN_MASK	0x000f
+-#define SROM4_TXCHAIN_SHIFT	0
+-#define SROM4_RXCHAIN_MASK	0x00f0
+-#define SROM4_RXCHAIN_SHIFT	4
+-#define SROM4_SWITCH_MASK	0xff00
+-#define SROM4_SWITCH_SHIFT	8
+-
+-/* Per-path fields */
+-#define	MAX_PATH_SROM		4
+-#define	SROM4_PATH0		64
+-#define	SROM4_PATH1		87
+-#define	SROM4_PATH2		110
+-#define	SROM4_PATH3		133
+-
+-#define	SROM4_2G_ITT_MAXP	0
+-#define	SROM4_2G_PA		1
+-#define	SROM4_5G_ITT_MAXP	5
+-#define	SROM4_5GLH_MAXP		6
+-#define	SROM4_5G_PA		7
+-#define	SROM4_5GL_PA		11
+-#define	SROM4_5GH_PA		15
+-
+-/* Fields in the ITT_MAXP and 5GLH_MAXP words */
+-#define	B2G_MAXP_MASK		0xff
+-#define	B2G_ITT_SHIFT		8
+-#define	B5G_MAXP_MASK		0xff
+-#define	B5G_ITT_SHIFT		8
+-#define	B5GH_MAXP_MASK		0xff
+-#define	B5GL_MAXP_SHIFT		8
+-
+-/* All the miriad power offsets */
+-#define	SROM4_2G_CCKPO		156
+-#define	SROM4_2G_OFDMPO		157
+-#define	SROM4_5G_OFDMPO		159
+-#define	SROM4_5GL_OFDMPO	161
+-#define	SROM4_5GH_OFDMPO	163
+-#define	SROM4_2G_MCSPO		165
+-#define	SROM4_5G_MCSPO		173
+-#define	SROM4_5GL_MCSPO		181
+-#define	SROM4_5GH_MCSPO		189
+-#define	SROM4_CDDPO		197
+-#define	SROM4_STBCPO		198
+-#define	SROM4_BW40PO		199
+-#define	SROM4_BWDUPPO		200
+-
+-#define	SROM4_CRCREV		219
+-
+-/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
+- * This is acombined srom for both MIMO and SISO boards, usable in
+- * the .130 4Kilobit OTP with hardware redundancy.
+- */
+-
+-#define	SROM8_SIGN		64
+-
+-#define	SROM8_BREV		65
+-
+-#define	SROM8_BFL0		66
+-#define	SROM8_BFL1		67
+-#define	SROM8_BFL2		68
+-#define	SROM8_BFL3		69
+-
+-#define	SROM8_MACHI		70
+-#define	SROM8_MACMID		71
+-#define	SROM8_MACLO		72
+-
+-#define	SROM8_CCODE		73
+-#define	SROM8_REGREV		74
+-
+-#define	SROM8_LEDBH10		75
+-#define	SROM8_LEDBH32		76
+-
+-#define	SROM8_LEDDC		77
+-
+-#define	SROM8_AA		78
+-
+-#define	SROM8_AG10		79
+-#define	SROM8_AG32		80
+-
+-#define	SROM8_TXRXC		81
+-
+-#define	SROM8_BXARSSI2G		82
+-#define	SROM8_BXARSSI5G		83
+-#define	SROM8_TRI52G		84
+-#define	SROM8_TRI5GHL		85
+-#define	SROM8_RXPO52G		86
+-
+-#define SROM8_FEM2G		87
+-#define SROM8_FEM5G		88
+-#define SROM8_FEM_ANTSWLUT_MASK		0xf800
+-#define SROM8_FEM_ANTSWLUT_SHIFT	11
+-#define SROM8_FEM_TR_ISO_MASK		0x0700
+-#define SROM8_FEM_TR_ISO_SHIFT		8
+-#define SROM8_FEM_PDET_RANGE_MASK	0x00f8
+-#define SROM8_FEM_PDET_RANGE_SHIFT	3
+-#define SROM8_FEM_EXTPA_GAIN_MASK	0x0006
+-#define SROM8_FEM_EXTPA_GAIN_SHIFT	1
+-#define SROM8_FEM_TSSIPOS_MASK		0x0001
+-#define SROM8_FEM_TSSIPOS_SHIFT		0
+-
+-#define SROM8_THERMAL		89
+-
+-/* Temp sense related entries */
+-#define SROM8_MPWR_RAWTS		90
+-#define SROM8_TS_SLP_OPT_CORRX	91
+-/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
+-#define SROM8_FOC_HWIQ_IQSWP	92
+-
+-/* Temperature delta for PHY calibration */
+-#define SROM8_PHYCAL_TEMPDELTA	93
+-
+-/* Per-path offsets & fields */
+-#define	SROM8_PATH0		96
+-#define	SROM8_PATH1		112
+-#define	SROM8_PATH2		128
+-#define	SROM8_PATH3		144
+-
+-#define	SROM8_2G_ITT_MAXP	0
+-#define	SROM8_2G_PA		1
+-#define	SROM8_5G_ITT_MAXP	4
+-#define	SROM8_5GLH_MAXP		5
+-#define	SROM8_5G_PA		6
+-#define	SROM8_5GL_PA		9
+-#define	SROM8_5GH_PA		12
+-
+-/* All the miriad power offsets */
+-#define	SROM8_2G_CCKPO		160
+-
+-#define	SROM8_2G_OFDMPO		161
+-#define	SROM8_5G_OFDMPO		163
+-#define	SROM8_5GL_OFDMPO	165
+-#define	SROM8_5GH_OFDMPO	167
+-
+-#define	SROM8_2G_MCSPO		169
+-#define	SROM8_5G_MCSPO		177
+-#define	SROM8_5GL_MCSPO		185
+-#define	SROM8_5GH_MCSPO		193
+-
+-#define	SROM8_CDDPO		201
+-#define	SROM8_STBCPO		202
+-#define	SROM8_BW40PO		203
+-#define	SROM8_BWDUPPO		204
+-
+-/* SISO PA parameters are in the path0 spaces */
+-#define	SROM8_SISO		96
+-
+-/* Legacy names for SISO PA paramters */
+-#define	SROM8_W0_ITTMAXP	(SROM8_SISO + SROM8_2G_ITT_MAXP)
+-#define	SROM8_W0_PAB0		(SROM8_SISO + SROM8_2G_PA)
+-#define	SROM8_W0_PAB1		(SROM8_SISO + SROM8_2G_PA + 1)
+-#define	SROM8_W0_PAB2		(SROM8_SISO + SROM8_2G_PA + 2)
+-#define	SROM8_W1_ITTMAXP	(SROM8_SISO + SROM8_5G_ITT_MAXP)
+-#define	SROM8_W1_MAXP_LCHC	(SROM8_SISO + SROM8_5GLH_MAXP)
+-#define	SROM8_W1_PAB0		(SROM8_SISO + SROM8_5G_PA)
+-#define	SROM8_W1_PAB1		(SROM8_SISO + SROM8_5G_PA + 1)
+-#define	SROM8_W1_PAB2		(SROM8_SISO + SROM8_5G_PA + 2)
+-#define	SROM8_W1_PAB0_LC	(SROM8_SISO + SROM8_5GL_PA)
+-#define	SROM8_W1_PAB1_LC	(SROM8_SISO + SROM8_5GL_PA + 1)
+-#define	SROM8_W1_PAB2_LC	(SROM8_SISO + SROM8_5GL_PA + 2)
+-#define	SROM8_W1_PAB0_HC	(SROM8_SISO + SROM8_5GH_PA)
+-#define	SROM8_W1_PAB1_HC	(SROM8_SISO + SROM8_5GH_PA + 1)
+-#define	SROM8_W1_PAB2_HC	(SROM8_SISO + SROM8_5GH_PA + 2)
+-
+-#define	SROM8_CRCREV		219
+-
+-/* SROM REV 9 */
+-#define SROM9_2GPO_CCKBW20	160
+-#define SROM9_2GPO_CCKBW20UL	161
+-#define SROM9_2GPO_LOFDMBW20	162
+-#define SROM9_2GPO_LOFDMBW20UL	164
+-
+-#define SROM9_5GLPO_LOFDMBW20	166
+-#define SROM9_5GLPO_LOFDMBW20UL	168
+-#define SROM9_5GMPO_LOFDMBW20	170
+-#define SROM9_5GMPO_LOFDMBW20UL	172
+-#define SROM9_5GHPO_LOFDMBW20	174
+-#define SROM9_5GHPO_LOFDMBW20UL	176
+-
+-#define SROM9_2GPO_MCSBW20	178
+-#define SROM9_2GPO_MCSBW20UL	180
+-#define SROM9_2GPO_MCSBW40	182
+-
+-#define SROM9_5GLPO_MCSBW20	184
+-#define SROM9_5GLPO_MCSBW20UL	186
+-#define SROM9_5GLPO_MCSBW40	188
+-#define SROM9_5GMPO_MCSBW20	190
+-#define SROM9_5GMPO_MCSBW20UL	192
+-#define SROM9_5GMPO_MCSBW40	194
+-#define SROM9_5GHPO_MCSBW20	196
+-#define SROM9_5GHPO_MCSBW20UL	198
+-#define SROM9_5GHPO_MCSBW40	200
+-
+-#define SROM9_PO_MCS32		202
+-#define SROM9_PO_LOFDM40DUP	203
+-
+-#define SROM9_REV_CRC		219
+-
+-typedef struct {
+-	u8 tssipos;		/* TSSI positive slope, 1: positive, 0: negative */
+-	u8 extpagain;	/* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
+-	u8 pdetrange;	/* support 32 combinations of different Pdet dynamic ranges */
+-	u8 triso;		/* TR switch isolation */
+-	u8 antswctrllut;	/* antswctrl lookup table configuration: 32 possible choices */
+-} srom_fem_t;
+-
+-#endif				/* _bcmsrom_fmt_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h
+deleted file mode 100644
+index 17683f2..0000000
+--- a/drivers/staging/brcm80211/include/bcmutils.h
++++ /dev/null
+@@ -1,500 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmutils_h_
+-#define	_bcmutils_h_
+-
+-/* Buffer structure for collecting string-formatted data
+-* using bcm_bprintf() API.
+-* Use bcm_binit() to initialize before use
+-*/
+-
+-	struct bcmstrbuf {
+-		char *buf;	/* pointer to current position in origbuf */
+-		unsigned int size;	/* current (residual) size in bytes */
+-		char *origbuf;	/* unmodified pointer to orignal buffer */
+-		unsigned int origsize;	/* unmodified orignal buffer size in bytes */
+-	};
+-
+-/* ** driver-only section ** */
+-
+-#define GPIO_PIN_NOTDEFINED 	0x20	/* Pin not defined */
+-
+-/*
+- * Spin at most 'us' microseconds while 'exp' is true.
+- * Caller should explicitly test 'exp' when this completes
+- * and take appropriate error action if 'exp' is still true.
+- */
+-#define SPINWAIT(exp, us) { \
+-	uint countdown = (us) + 9; \
+-	while ((exp) && (countdown >= 10)) {\
+-		udelay(10); \
+-		countdown -= 10; \
+-	} \
+-}
+-
+-/* osl multi-precedence packet queue */
+-#ifndef PKTQ_LEN_DEFAULT
+-#define PKTQ_LEN_DEFAULT        128	/* Max 128 packets */
+-#endif
+-#ifndef PKTQ_MAX_PREC
+-#define PKTQ_MAX_PREC           16	/* Maximum precedence levels */
+-#endif
+-
+-	struct pktq_prec {
+-		struct sk_buff *head;	/* first packet to dequeue */
+-		struct sk_buff *tail;	/* last packet to dequeue */
+-		u16 len;		/* number of queued packets */
+-		u16 max;		/* maximum number of queued packets */
+-	};
+-
+-/* multi-priority pkt queue */
+-	struct pktq {
+-		u16 num_prec;	/* number of precedences in use */
+-		u16 hi_prec;	/* rapid dequeue hint (>= highest non-empty prec) */
+-		u16 max;	/* total max packets */
+-		u16 len;	/* total number of packets */
+-		/* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */
+-		struct pktq_prec q[PKTQ_MAX_PREC];
+-	};
+-
+-#define PKTQ_PREC_ITER(pq, prec)        for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
+-
+-/* fn(pkt, arg).  return true if pkt belongs to if */
+-typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *);
+-
+-/* operations on a specific precedence in packet queue */
+-
+-#define pktq_psetmax(pq, prec, _max)    ((pq)->q[prec].max = (_max))
+-#define pktq_plen(pq, prec)             ((pq)->q[prec].len)
+-#define pktq_pavail(pq, prec)           ((pq)->q[prec].max - (pq)->q[prec].len)
+-#define pktq_pfull(pq, prec)            ((pq)->q[prec].len >= (pq)->q[prec].max)
+-#define pktq_pempty(pq, prec)           ((pq)->q[prec].len == 0)
+-
+-#define pktq_ppeek(pq, prec)            ((pq)->q[prec].head)
+-#define pktq_ppeek_tail(pq, prec)       ((pq)->q[prec].tail)
+-
+-extern struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
+-				 struct sk_buff *p);
+-extern struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
+-				      struct sk_buff *p);
+-extern struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec);
+-extern struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec);
+-
+-/* packet primitives */
+-extern struct sk_buff *bcm_pkt_buf_get_skb(uint len);
+-extern void bcm_pkt_buf_free_skb(struct sk_buff *skb);
+-
+-/* Empty the queue at particular precedence level */
+-extern void bcm_pktq_pflush(struct pktq *pq, int prec,
+-	bool dir, ifpkt_cb_t fn, void *arg);
+-
+-/* operations on a set of precedences in packet queue */
+-
+-extern int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp);
+-extern struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
+-	int *prec_out);
+-
+-/* operations on packet queue as a whole */
+-
+-#define pktq_len(pq)                    ((int)(pq)->len)
+-#define pktq_max(pq)                    ((int)(pq)->max)
+-#define pktq_avail(pq)                  ((int)((pq)->max - (pq)->len))
+-#define pktq_full(pq)                   ((pq)->len >= (pq)->max)
+-#define pktq_empty(pq)                  ((pq)->len == 0)
+-
+-/* operations for single precedence queues */
+-#define pktenq(pq, p)		bcm_pktq_penq(((struct pktq *)pq), 0, (p))
+-#define pktenq_head(pq, p)	bcm_pktq_penq_head(((struct pktq *)pq), 0, (p))
+-#define pktdeq(pq)		bcm_pktq_pdeq(((struct pktq *)pq), 0)
+-#define pktdeq_tail(pq)		bcm_pktq_pdeq_tail(((struct pktq *)pq), 0)
+-#define pktqinit(pq, len)	bcm_pktq_init(((struct pktq *)pq), 1, len)
+-
+-extern void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len);
+-/* prec_out may be NULL if caller is not interested in return value */
+-extern struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out);
+-extern void bcm_pktq_flush(struct pktq *pq, bool dir,
+-	ifpkt_cb_t fn, void *arg);
+-
+-/* externs */
+-/* packet */
+-extern uint bcm_pktfrombuf(struct sk_buff *p,
+-	uint offset, int len, unsigned char *buf);
+-extern uint bcm_pkttotlen(struct sk_buff *p);
+-
+-/* ethernet address */
+-extern int bcm_ether_atoe(char *p, u8 *ea);
+-
+-/* ip address */
+-	struct ipv4_addr;
+-	extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
+-
+-#ifdef BCMDBG
+-extern void bcm_prpkt(const char *msg, struct sk_buff *p0);
+-#else
+-#define bcm_prpkt(a, b)
+-#endif				/* BCMDBG */
+-
+-#define bcm_perf_enable()
+-#define	bcmlog(fmt, a1, a2)
+-#define	bcmdumplog(buf, size)	(*buf = '\0')
+-#define	bcmdumplogent(buf, idx)	-1
+-
+-#define bcmtslog(tstamp, fmt, a1, a2)
+-#define bcmprinttslogs()
+-#define bcmprinttstamp(us)
+-
+-/* Support for sharing code across in-driver iovar implementations.
+- * The intent is that a driver use this structure to map iovar names
+- * to its (private) iovar identifiers, and the lookup function to
+- * find the entry.  Macros are provided to map ids and get/set actions
+- * into a single number space for a switch statement.
+- */
+-
+-/* iovar structure */
+-	typedef struct bcm_iovar {
+-		const char *name;	/* name for lookup and display */
+-		u16 varid;	/* id for switch */
+-		u16 flags;	/* driver-specific flag bits */
+-		u16 type;	/* base type of argument */
+-		u16 minlen;	/* min length for buffer vars */
+-	} bcm_iovar_t;
+-
+-/* varid definitions are per-driver, may use these get/set bits */
+-
+-/* IOVar action bits for id mapping */
+-#define IOV_GET 0		/* Get an iovar */
+-#define IOV_SET 1		/* Set an iovar */
+-
+-/* Varid to actionid mapping */
+-#define IOV_GVAL(id)		((id)*2)
+-#define IOV_SVAL(id)		(((id)*2)+IOV_SET)
+-#define IOV_ISSET(actionid)	((actionid & IOV_SET) == IOV_SET)
+-#define IOV_ID(actionid)	(actionid >> 1)
+-
+-/* flags are per-driver based on driver attributes */
+-
+-	extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table,
+-						   const char *name);
+-	extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg,
+-				      int len, bool set);
+-
+-/* Base type definitions */
+-#define IOVT_VOID	0	/* no value (implictly set only) */
+-#define IOVT_BOOL	1	/* any value ok (zero/nonzero) */
+-#define IOVT_INT8	2	/* integer values are range-checked */
+-#define IOVT_UINT8	3	/* unsigned int 8 bits */
+-#define IOVT_INT16	4	/* int 16 bits */
+-#define IOVT_UINT16	5	/* unsigned int 16 bits */
+-#define IOVT_INT32	6	/* int 32 bits */
+-#define IOVT_UINT32	7	/* unsigned int 32 bits */
+-#define IOVT_BUFFER	8	/* buffer is size-checked as per minlen */
+-#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER)
+-
+-/* Initializer for IOV type strings */
+-#define BCM_IOV_TYPE_INIT { \
+-	"void", \
+-	"bool", \
+-	"s8", \
+-	"u8", \
+-	"s16", \
+-	"u16", \
+-	"s32", \
+-	"u32", \
+-	"buffer", \
+-	"" }
+-
+-#define BCM_IOVT_IS_INT(type) (\
+-	(type == IOVT_BOOL) || \
+-	(type == IOVT_INT8) || \
+-	(type == IOVT_UINT8) || \
+-	(type == IOVT_INT16) || \
+-	(type == IOVT_UINT16) || \
+-	(type == IOVT_INT32) || \
+-	(type == IOVT_UINT32))
+-
+-/* ** driver/apps-shared section ** */
+-
+-#define BCME_STRLEN 		64	/* Max string length for BCM errors */
+-
+-#ifndef ABS
+-#define	ABS(a)			(((a) < 0) ? -(a) : (a))
+-#endif				/* ABS */
+-
+-#define CEIL(x, y)		(((x) + ((y)-1)) / (y))
+-#define	ISPOWEROF2(x)		((((x)-1)&(x)) == 0)
+-
+-/* map physical to virtual I/O */
+-#if !defined(CONFIG_MMC_MSM7X00A)
+-#define REG_MAP(pa, size)       ioremap_nocache((unsigned long)(pa), \
+-					(unsigned long)(size))
+-#else
+-#define REG_MAP(pa, size)       (void *)(0)
+-#endif
+-
+-/* register access macros */
+-#if defined(BCMSDIO)
+-#ifdef BRCM_FULLMAC
+-#include <bcmsdh.h>
+-#endif
+-#define OSL_WRITE_REG(r, v) \
+-		(bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v)))
+-#define OSL_READ_REG(r) \
+-		(bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r))))
+-#endif
+-
+-#if defined(BCMSDIO)
+-#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op
+-#define SELECT_BUS_READ(mmap_op, bus_op) bus_op
+-#else
+-#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op
+-#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op
+-#endif
+-
+-/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
+-#define	PKTBUFSZ	2048
+-
+-#define OSL_SYSUPTIME()		((u32)jiffies * (1000 / HZ))
+-#ifdef BRCM_FULLMAC
+-#include <linux/kernel.h>	/* for vsn/printf's */
+-#include <linux/string.h>	/* for mem*, str* */
+-#endif
+-/* bcopy's: Linux kernel doesn't provide these (anymore) */
+-#define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
+-
+-/* register access macros */
+-#ifndef __BIG_ENDIAN
+-#ifndef __mips__
+-#define R_REG(r) (\
+-	SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \
+-	readb((volatile u8*)(r)) : \
+-	sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \
+-	readl((volatile u32*)(r)), OSL_READ_REG(r)) \
+-)
+-#else				/* __mips__ */
+-#define R_REG(r) (\
+-	SELECT_BUS_READ( \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			__asm__ __volatile__("sync"); \
+-			switch (sizeof(*(r))) { \
+-			case sizeof(u8): \
+-				__osl_v = readb((volatile u8*)(r)); \
+-				break; \
+-			case sizeof(u16): \
+-				__osl_v = readw((volatile u16*)(r)); \
+-				break; \
+-			case sizeof(u32): \
+-				__osl_v = \
+-				readl((volatile u32*)(r)); \
+-				break; \
+-			} \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v; \
+-		}), \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v = OSL_READ_REG(r); \
+-			__asm__ __volatile__("sync"); \
+-			__osl_v; \
+-		})) \
+-)
+-#endif				/* __mips__ */
+-
+-#define W_REG(r, v) do { \
+-	SELECT_BUS_WRITE( \
+-		switch (sizeof(*(r))) { \
+-		case sizeof(u8): \
+-			writeb((u8)(v), (volatile u8*)(r)); break; \
+-		case sizeof(u16): \
+-			writew((u16)(v), (volatile u16*)(r)); break; \
+-		case sizeof(u32): \
+-			writel((u32)(v), (volatile u32*)(r)); break; \
+-		}, \
+-		(OSL_WRITE_REG(r, v))); \
+-	} while (0)
+-#else				/* __BIG_ENDIAN */
+-#define R_REG(r) (\
+-	SELECT_BUS_READ( \
+-		({ \
+-			__typeof(*(r)) __osl_v; \
+-			switch (sizeof(*(r))) { \
+-			case sizeof(u8): \
+-				__osl_v = \
+-				readb((volatile u8*)((r)^3)); \
+-				break; \
+-			case sizeof(u16): \
+-				__osl_v = \
+-				readw((volatile u16*)((r)^2)); \
+-				break; \
+-			case sizeof(u32): \
+-				__osl_v = readl((volatile u32*)(r)); \
+-				break; \
+-			} \
+-			__osl_v; \
+-		}), \
+-		OSL_READ_REG(r)) \
+-)
+-#define W_REG(r, v) do { \
+-	SELECT_BUS_WRITE( \
+-		switch (sizeof(*(r))) { \
+-		case sizeof(u8):	\
+-			writeb((u8)(v), \
+-			(volatile u8*)((r)^3)); break; \
+-		case sizeof(u16):	\
+-			writew((u16)(v), \
+-			(volatile u16*)((r)^2)); break; \
+-		case sizeof(u32):	\
+-			writel((u32)(v), \
+-			(volatile u32*)(r)); break; \
+-		}, \
+-		(OSL_WRITE_REG(r, v))); \
+-	} while (0)
+-#endif				/* __BIG_ENDIAN */
+-
+-#define AND_REG(r, v)	W_REG((r), R_REG(r) & (v))
+-#define OR_REG(r, v)	W_REG((r), R_REG(r) | (v))
+-
+-#define SET_REG(r, mask, val) \
+-		W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
+-
+-#ifndef setbit
+-#ifndef NBBY			/* the BSD family defines NBBY */
+-#define	NBBY	8		/* 8 bits per byte */
+-#endif				/* #ifndef NBBY */
+-#define	setbit(a, i)	(((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
+-#define	clrbit(a, i)	(((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+-#define	isset(a, i)	(((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
+-#define	isclr(a, i)	((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+-#endif				/* setbit */
+-
+-#define	NBITS(type)	(sizeof(type) * 8)
+-#define NBITVAL(nbits)	(1 << (nbits))
+-#define MAXBITVAL(nbits)	((1 << (nbits)) - 1)
+-#define	NBITMASK(nbits)	MAXBITVAL(nbits)
+-#define MAXNBVAL(nbyte)	MAXBITVAL((nbyte) * 8)
+-
+-/* basic mux operation - can be optimized on several architectures */
+-#define MUX(pred, true, false) ((pred) ? (true) : (false))
+-
+-/* modulo inc/dec - assumes x E [0, bound - 1] */
+-#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1)
+-#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1)
+-
+-/* modulo inc/dec, bound = 2^k */
+-#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1))
+-#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1))
+-
+-/* modulo add/sub - assumes x, y E [0, bound - 1] */
+-#define MODADD(x, y, bound) \
+-    MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y))
+-#define MODSUB(x, y, bound) \
+-    MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y))
+-
+-/* module add/sub, bound = 2^k */
+-#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
+-#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
+-
+-/* crc defines */
+-#define CRC8_INIT_VALUE  0xff	/* Initial CRC8 checksum value */
+-#define CRC8_GOOD_VALUE  0x9f	/* Good final CRC8 checksum value */
+-#define CRC16_INIT_VALUE 0xffff	/* Initial CRC16 checksum value */
+-#define CRC16_GOOD_VALUE 0xf0b8	/* Good final CRC16 checksum value */
+-
+-/* bcm_format_flags() bit description structure */
+-	typedef struct bcm_bit_desc {
+-		u32 bit;
+-		const char *name;
+-	} bcm_bit_desc_t;
+-
+-/* tag_ID/length/value_buffer tuple */
+-	typedef struct bcm_tlv {
+-		u8 id;
+-		u8 len;
+-		u8 data[1];
+-	} bcm_tlv_t;
+-
+-/* Check that bcm_tlv_t fits into the given buflen */
+-#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
+-
+-#define ETHER_ADDR_STR_LEN	18	/* 18-bytes of Ethernet address buffer length */
+-
+-/* crypto utility function */
+-/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */
+-	static inline void
+-	 xor_128bit_block(const u8 *src1, const u8 *src2, u8 *dst) {
+-		if (
+-#ifdef __i386__
+-			   1 ||
+-#endif
+-			   (((unsigned long) src1 | (unsigned long) src2 | (unsigned long) dst) &
+-			    3) == 0) {
+-			/* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */
+-			/* x86 supports unaligned.  This version runs 6x-9x faster on x86. */
+-			((u32 *) dst)[0] =
+-			    ((const u32 *)src1)[0] ^ ((const u32 *)
+-							 src2)[0];
+-			((u32 *) dst)[1] =
+-			    ((const u32 *)src1)[1] ^ ((const u32 *)
+-							 src2)[1];
+-			((u32 *) dst)[2] =
+-			    ((const u32 *)src1)[2] ^ ((const u32 *)
+-							 src2)[2];
+-			((u32 *) dst)[3] =
+-			    ((const u32 *)src1)[3] ^ ((const u32 *)
+-							 src2)[3];
+-		} else {
+-			/* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */
+-			int k;
+-			for (k = 0; k < 16; k++)
+-				dst[k] = src1[k] ^ src2[k];
+-		}
+-	}
+-
+-/* externs */
+-/* crc */
+-extern u8 bcm_crc8(u8 *p, uint nbytes, u8 crc);
+-/* format/print */
+-#if defined(BCMDBG)
+-	extern int bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags,
+-				    char *buf, int len);
+-	extern int bcm_format_hex(char *str, const void *bytes, int len);
+-#endif
+-	extern char *bcm_chipname(uint chipid, char *buf, uint len);
+-
+-	extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen,
+-						    uint key);
+-
+-/* multi-bool data type: set of bools, mbool is true if any is set */
+-	typedef u32 mbool;
+-#define mboolset(mb, bit)		((mb) |= (bit))	/* set one bool */
+-#define mboolclr(mb, bit)		((mb) &= ~(bit))	/* clear one bool */
+-#define mboolisset(mb, bit)		(((mb) & (bit)) != 0)	/* true if one bool is set */
+-#define	mboolmaskset(mb, mask, val)	((mb) = (((mb) & ~(mask)) | (val)))
+-
+-/* power conversion */
+-	extern u16 bcm_qdbm_to_mw(u8 qdbm);
+-	extern u8 bcm_mw_to_qdbm(u16 mw);
+-
+-	extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size);
+-	extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...);
+-
+-	extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf,
+-				uint len);
+-	extern uint bcm_bitcount(u8 *bitmap, uint bytelength);
+-
+-#endif				/* _bcmutils_h_ */
+diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h
+deleted file mode 100644
+index a573ebf..0000000
+--- a/drivers/staging/brcm80211/include/bcmwifi.h
++++ /dev/null
+@@ -1,167 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_bcmwifi_h_
+-#define	_bcmwifi_h_
+-
+-/* A chanspec holds the channel number, band, bandwidth and control sideband */
+-typedef u16 chanspec_t;
+-
+-/* channel defines */
+-#define CH_UPPER_SB			0x01
+-#define CH_LOWER_SB			0x02
+-#define CH_EWA_VALID			0x04
+-#define CH_20MHZ_APART			4
+-#define CH_10MHZ_APART			2
+-#define CH_5MHZ_APART			1	/* 2G band channels are 5 Mhz apart */
+-#define CH_MAX_2G_CHANNEL		14	/* Max channel in 2G band */
+-#define WLC_MAX_2G_CHANNEL		CH_MAX_2G_CHANNEL	/* legacy define */
+-#define	MAXCHANNEL		224	/* max # supported channels. The max channel no is 216,
+-					 * this is that + 1 rounded up to a multiple of NBBY (8).
+-					 * DO NOT MAKE it > 255: channels are u8's all over
+-					 */
+-
+-#define WL_CHANSPEC_CHAN_MASK		0x00ff
+-#define WL_CHANSPEC_CHAN_SHIFT		0
+-
+-#define WL_CHANSPEC_CTL_SB_MASK		0x0300
+-#define WL_CHANSPEC_CTL_SB_SHIFT	     8
+-#define WL_CHANSPEC_CTL_SB_LOWER	0x0100
+-#define WL_CHANSPEC_CTL_SB_UPPER	0x0200
+-#define WL_CHANSPEC_CTL_SB_NONE		0x0300
+-
+-#define WL_CHANSPEC_BW_MASK		0x0C00
+-#define WL_CHANSPEC_BW_SHIFT		    10
+-#define WL_CHANSPEC_BW_10		0x0400
+-#define WL_CHANSPEC_BW_20		0x0800
+-#define WL_CHANSPEC_BW_40		0x0C00
+-
+-#define WL_CHANSPEC_BAND_MASK		0xf000
+-#define WL_CHANSPEC_BAND_SHIFT		12
+-#define WL_CHANSPEC_BAND_5G		0x1000
+-#define WL_CHANSPEC_BAND_2G		0x2000
+-#define INVCHANSPEC			255
+-
+-/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
+-#define WF_CHAN_FACTOR_2_4_G		4814	/* 2.4 GHz band, 2407 MHz */
+-#define WF_CHAN_FACTOR_5_G		10000	/* 5   GHz band, 5000 MHz */
+-#define WF_CHAN_FACTOR_4_G		8000	/* 4.9 GHz band for Japan */
+-
+-/* channel defines */
+-#define LOWER_20_SB(channel)	(((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0)
+-#define UPPER_20_SB(channel)	(((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
+-				((channel) + CH_10MHZ_APART) : 0)
+-#define CHSPEC_WLCBANDUNIT(chspec)	(CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
+-#define CH20MHZ_CHSPEC(channel)	(chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
+-				WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
+-				WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
+-#define NEXT_20MHZ_CHAN(channel)	(((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
+-					((channel) + CH_20MHZ_APART) : 0)
+-#define CH40MHZ_CHSPEC(channel, ctlsb)	(chanspec_t) \
+-					((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
+-					((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
+-					WL_CHANSPEC_BAND_5G))
+-#define CHSPEC_CHANNEL(chspec)	((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
+-#define CHSPEC_BAND(chspec)	((chspec) & WL_CHANSPEC_BAND_MASK)
+-
+-#ifdef WL11N_20MHZONLY
+-
+-#define CHSPEC_CTL_SB(chspec)	WL_CHANSPEC_CTL_SB_NONE
+-#define CHSPEC_BW(chspec)	WL_CHANSPEC_BW_20
+-#define CHSPEC_IS10(chspec)	0
+-#define CHSPEC_IS20(chspec)	1
+-#ifndef CHSPEC_IS40
+-#define CHSPEC_IS40(chspec)	0
+-#endif
+-
+-#else				/* !WL11N_20MHZONLY */
+-
+-#define CHSPEC_CTL_SB(chspec)	((chspec) & WL_CHANSPEC_CTL_SB_MASK)
+-#define CHSPEC_BW(chspec)	((chspec) & WL_CHANSPEC_BW_MASK)
+-#define CHSPEC_IS10(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
+-#define CHSPEC_IS20(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
+-#ifndef CHSPEC_IS40
+-#define CHSPEC_IS40(chspec)	(((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
+-#endif
+-
+-#endif				/* !WL11N_20MHZONLY */
+-
+-#define CHSPEC_IS5G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
+-#define CHSPEC_IS2G(chspec)	(((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
+-#define CHSPEC_SB_NONE(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE)
+-#define CHSPEC_SB_UPPER(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER)
+-#define CHSPEC_SB_LOWER(chspec)	(((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER)
+-#define CHSPEC_CTL_CHAN(chspec)  ((CHSPEC_SB_LOWER(chspec)) ? \
+-				  (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \
+-				  (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))))
+-#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
+-
+-#define CHANSPEC_STR_LEN    8
+-
+-/* defined rate in 500kbps */
+-#define WLC_MAXRATE	108	/* in 500kbps units */
+-#define WLC_RATE_1M	2	/* in 500kbps units */
+-#define WLC_RATE_2M	4	/* in 500kbps units */
+-#define WLC_RATE_5M5	11	/* in 500kbps units */
+-#define WLC_RATE_11M	22	/* in 500kbps units */
+-#define WLC_RATE_6M	12	/* in 500kbps units */
+-#define WLC_RATE_9M	18	/* in 500kbps units */
+-#define WLC_RATE_12M	24	/* in 500kbps units */
+-#define WLC_RATE_18M	36	/* in 500kbps units */
+-#define WLC_RATE_24M	48	/* in 500kbps units */
+-#define WLC_RATE_36M	72	/* in 500kbps units */
+-#define WLC_RATE_48M	96	/* in 500kbps units */
+-#define WLC_RATE_54M	108	/* in 500kbps units */
+-
+-#define WLC_2G_25MHZ_OFFSET		5	/* 2.4GHz band channel offset */
+-
+-/*
+- * Verify the chanspec is using a legal set of parameters, i.e. that the
+- * chanspec specified a band, bw, ctl_sb and channel and that the
+- * combination could be legal given any set of circumstances.
+- * RETURNS: true is the chanspec is malformed, false if it looks good.
+- */
+-extern bool bcm_chspec_malformed(chanspec_t chanspec);
+-
+-/*
+- * This function returns the channel number that control traffic is being sent on, for legacy
+- * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+- * sideband depending on the chanspec selected
+- */
+-extern u8 bcm_chspec_ctlchan(chanspec_t chspec);
+-
+-/*
+- * Return the channel number for a given frequency and base frequency.
+- * The returned channel number is relative to the given base frequency.
+- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+- *
+- * Frequency is specified in MHz.
+- * The base frequency is specified as (start_factor * 500 kHz).
+- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+- * 2.4 GHz and 5 GHz bands.
+- *
+- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+- * and [0, 200] otherwise.
+- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+- *
+- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+- */
+-extern int bcm_mhz2channel(uint freq, uint start_factor);
+-
+-#endif				/* _bcmwifi_h_ */
+diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h
+deleted file mode 100644
+index fbbcb9b..0000000
+--- a/drivers/staging/brcm80211/include/hnddma.h
++++ /dev/null
+@@ -1,226 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_hnddma_h_
+-#define	_hnddma_h_
+-
+-#ifndef _hnddma_pub_
+-#define _hnddma_pub_
+-struct hnddma_pub;
+-#endif				/* _hnddma_pub_ */
+-
+-/* map/unmap direction */
+-#define	DMA_TX	1		/* TX direction for DMA */
+-#define	DMA_RX	2		/* RX direction for DMA */
+-#define BUS_SWAP32(v)		(v)
+-
+-/* range param for dma_getnexttxp() and dma_txreclaim */
+-typedef enum txd_range {
+-	HNDDMA_RANGE_ALL = 1,
+-	HNDDMA_RANGE_TRANSMITTED,
+-	HNDDMA_RANGE_TRANSFERED
+-} txd_range_t;
+-
+-/* dma function type */
+-typedef void (*di_detach_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txreset_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxreset_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxidle_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txinit_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txenabled_t) (struct hnddma_pub *dmah);
+-typedef void (*di_rxinit_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txsuspend_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txresume_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txsuspended_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txsuspendedidle_t) (struct hnddma_pub *dmah);
+-typedef int (*di_txfast_t) (struct hnddma_pub *dmah, struct sk_buff *p,
+-			    bool commit);
+-typedef int (*di_txunframed_t) (struct hnddma_pub *dmah, void *p, uint len,
+-				bool commit);
+-typedef void *(*di_getpos_t) (struct hnddma_pub *di, bool direction);
+-typedef void (*di_fifoloopbackenable_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_txstopped_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxstopped_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxenable_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxenabled_t) (struct hnddma_pub *dmah);
+-typedef void *(*di_rx_t) (struct hnddma_pub *dmah);
+-typedef bool(*di_rxfill_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txreclaim_t) (struct hnddma_pub *dmah, txd_range_t range);
+-typedef void (*di_rxreclaim_t) (struct hnddma_pub *dmah);
+-typedef unsigned long (*di_getvar_t) (struct hnddma_pub *dmah,
+-				      const char *name);
+-typedef void *(*di_getnexttxp_t) (struct hnddma_pub *dmah, txd_range_t range);
+-typedef void *(*di_getnextrxp_t) (struct hnddma_pub *dmah, bool forceall);
+-typedef void *(*di_peeknexttxp_t) (struct hnddma_pub *dmah);
+-typedef void *(*di_peeknextrxp_t) (struct hnddma_pub *dmah);
+-typedef void (*di_rxparam_get_t) (struct hnddma_pub *dmah, u16 *rxoffset,
+-				  u16 *rxbufsize);
+-typedef void (*di_txblock_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txunblock_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txactive_t) (struct hnddma_pub *dmah);
+-typedef void (*di_txrotate_t) (struct hnddma_pub *dmah);
+-typedef void (*di_counterreset_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_ctrlflags_t) (struct hnddma_pub *dmah, uint mask, uint flags);
+-typedef char *(*di_dump_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			    bool dumpring);
+-typedef char *(*di_dumptx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			      bool dumpring);
+-typedef char *(*di_dumprx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b,
+-			      bool dumpring);
+-typedef uint(*di_rxactive_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txpending_t) (struct hnddma_pub *dmah);
+-typedef uint(*di_txcommitted_t) (struct hnddma_pub *dmah);
+-
+-/* dma opsvec */
+-typedef struct di_fcn_s {
+-	di_detach_t detach;
+-	di_txinit_t txinit;
+-	di_txreset_t txreset;
+-	di_txenabled_t txenabled;
+-	di_txsuspend_t txsuspend;
+-	di_txresume_t txresume;
+-	di_txsuspended_t txsuspended;
+-	di_txsuspendedidle_t txsuspendedidle;
+-	di_txfast_t txfast;
+-	di_txunframed_t txunframed;
+-	di_getpos_t getpos;
+-	di_txstopped_t txstopped;
+-	di_txreclaim_t txreclaim;
+-	di_getnexttxp_t getnexttxp;
+-	di_peeknexttxp_t peeknexttxp;
+-	di_txblock_t txblock;
+-	di_txunblock_t txunblock;
+-	di_txactive_t txactive;
+-	di_txrotate_t txrotate;
+-
+-	di_rxinit_t rxinit;
+-	di_rxreset_t rxreset;
+-	di_rxidle_t rxidle;
+-	di_rxstopped_t rxstopped;
+-	di_rxenable_t rxenable;
+-	di_rxenabled_t rxenabled;
+-	di_rx_t rx;
+-	di_rxfill_t rxfill;
+-	di_rxreclaim_t rxreclaim;
+-	di_getnextrxp_t getnextrxp;
+-	di_peeknextrxp_t peeknextrxp;
+-	di_rxparam_get_t rxparam_get;
+-
+-	di_fifoloopbackenable_t fifoloopbackenable;
+-	di_getvar_t d_getvar;
+-	di_counterreset_t counterreset;
+-	di_ctrlflags_t ctrlflags;
+-	di_dump_t dump;
+-	di_dumptx_t dumptx;
+-	di_dumprx_t dumprx;
+-	di_rxactive_t rxactive;
+-	di_txpending_t txpending;
+-	di_txcommitted_t txcommitted;
+-	uint endnum;
+-} di_fcn_t;
+-
+-/*
+- * Exported data structure (read-only)
+- */
+-/* export structure */
+-struct hnddma_pub {
+-	const di_fcn_t *di_fn;	/* DMA function pointers */
+-	uint txavail;		/* # free tx descriptors */
+-	uint dmactrlflags;	/* dma control flags */
+-
+-	/* rx error counters */
+-	uint rxgiants;		/* rx giant frames */
+-	uint rxnobuf;		/* rx out of dma descriptors */
+-	/* tx error counters */
+-	uint txnobuf;		/* tx out of dma descriptors */
+-};
+-
+-extern struct hnddma_pub *dma_attach(char *name, si_t *sih,
+-			    void *dmaregstx, void *dmaregsrx, uint ntxd,
+-			    uint nrxd, uint rxbufsize, int rxextheadroom,
+-			    uint nrxpost, uint rxoffset, uint *msg_level);
+-
+-extern const di_fcn_t dma64proc;
+-
+-#define dma_detach(di)			(dma64proc.detach(di))
+-#define dma_txreset(di)			(dma64proc.txreset(di))
+-#define dma_rxreset(di)			(dma64proc.rxreset(di))
+-#define dma_rxidle(di)			(dma64proc.rxidle(di))
+-#define dma_txinit(di)                  (dma64proc.txinit(di))
+-#define dma_txenabled(di)               (dma64proc.txenabled(di))
+-#define dma_rxinit(di)                  (dma64proc.rxinit(di))
+-#define dma_txsuspend(di)               (dma64proc.txsuspend(di))
+-#define dma_txresume(di)                (dma64proc.txresume(di))
+-#define dma_txsuspended(di)             (dma64proc.txsuspended(di))
+-#define dma_txsuspendedidle(di)         (dma64proc.txsuspendedidle(di))
+-#define dma_txfast(di, p, commit)	(dma64proc.txfast(di, p, commit))
+-#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit))
+-#define dma_getpos(di, dir)		(dma64proc.getpos(di, dir))
+-#define dma_fifoloopbackenable(di)      (dma64proc.fifoloopbackenable(di))
+-#define dma_txstopped(di)               (dma64proc.txstopped(di))
+-#define dma_rxstopped(di)               (dma64proc.rxstopped(di))
+-#define dma_rxenable(di)                (dma64proc.rxenable(di))
+-#define dma_rxenabled(di)               (dma64proc.rxenabled(di))
+-#define dma_rx(di)                      (dma64proc.rx(di))
+-#define dma_rxfill(di)                  (dma64proc.rxfill(di))
+-#define dma_txreclaim(di, range)	(dma64proc.txreclaim(di, range))
+-#define dma_rxreclaim(di)               (dma64proc.rxreclaim(di))
+-#define dma_getvar(di, name)		(dma64proc.d_getvar(di, name))
+-#define dma_getnexttxp(di, range)	(dma64proc.getnexttxp(di, range))
+-#define dma_getnextrxp(di, forceall)    (dma64proc.getnextrxp(di, forceall))
+-#define dma_peeknexttxp(di)             (dma64proc.peeknexttxp(di))
+-#define dma_peeknextrxp(di)             (dma64proc.peeknextrxp(di))
+-#define dma_rxparam_get(di, off, bufs)	(dma64proc.rxparam_get(di, off, bufs))
+-
+-#define dma_txblock(di)                 (dma64proc.txblock(di))
+-#define dma_txunblock(di)               (dma64proc.txunblock(di))
+-#define dma_txactive(di)                (dma64proc.txactive(di))
+-#define dma_rxactive(di)                (dma64proc.rxactive(di))
+-#define dma_txrotate(di)                (dma64proc.txrotate(di))
+-#define dma_counterreset(di)            (dma64proc.counterreset(di))
+-#define dma_ctrlflags(di, mask, flags)  (dma64proc.ctrlflags((di), (mask), (flags)))
+-#define dma_txpending(di)		(dma64proc.txpending(di))
+-#define dma_txcommitted(di)		(dma64proc.txcommitted(di))
+-
+-
+-/* return addresswidth allowed
+- * This needs to be done after SB attach but before dma attach.
+- * SB attach provides ability to probe backplane and dma core capabilities
+- * This info is needed by DMA_ALLOC_CONSISTENT in dma attach
+- */
+-extern uint dma_addrwidth(si_t *sih, void *dmaregs);
+-void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
+-		      (void *pkt, void *arg_a), void *arg_a);
+-
+-/*
+- * DMA(Bug) on some chips seems to declare that the packet is ready, but the
+- * packet length is not updated yet (by DMA) on the expected time.
+- * Workaround is to hold processor till DMA updates the length, and stay off
+- * the bus to allow DMA update the length in buffer
+- */
+-static inline void dma_spin_for_len(uint len, struct sk_buff *head)
+-{
+-#if defined(__mips__)
+-	if (!len) {
+-		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
+-			udelay(1);
+-
+-		*(u16 *) (head->data) = cpu_to_le16((u16) len);
+-	}
+-#endif				/* defined(__mips__) */
+-}
+-
+-#endif				/* _hnddma_h_ */
+diff --git a/drivers/staging/brcm80211/include/hndsoc.h b/drivers/staging/brcm80211/include/hndsoc.h
+deleted file mode 100644
+index 6435686..0000000
+--- a/drivers/staging/brcm80211/include/hndsoc.h
++++ /dev/null
+@@ -1,199 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_HNDSOC_H
+-#define	_HNDSOC_H
+-
+-/* Include the soci specific files */
+-#include <sbconfig.h>
+-#include <aidmp.h>
+-
+-/*
+- * SOC Interconnect Address Map.
+- * All regions may not exist on all chips.
+- */
+-#define SI_SDRAM_BASE		0x00000000	/* Physical SDRAM */
+-#define SI_PCI_MEM		0x08000000	/* Host Mode sb2pcitranslation0 (64 MB) */
+-#define SI_PCI_MEM_SZ		(64 * 1024 * 1024)
+-#define SI_PCI_CFG		0x0c000000	/* Host Mode sb2pcitranslation1 (64 MB) */
+-#define	SI_SDRAM_SWAPPED	0x10000000	/* Byteswapped Physical SDRAM */
+-#define SI_SDRAM_R2		0x80000000	/* Region 2 for sdram (512 MB) */
+-
+-#ifdef SI_ENUM_BASE_VARIABLE
+-#define SI_ENUM_BASE		(sii->pub.si_enum_base)
+-#else
+-#define SI_ENUM_BASE    	0x18000000	/* Enumeration space base */
+-#endif				/* SI_ENUM_BASE_VARIABLE */
+-
+-#define SI_WRAP_BASE    	0x18100000	/* Wrapper space base */
+-#define SI_CORE_SIZE    	0x1000	/* each core gets 4Kbytes for registers */
+-#define	SI_MAXCORES		16	/* Max cores (this is arbitrary, for software
+-					 * convenience and could be changed if we
+-					 * make any larger chips
+-					 */
+-
+-#define	SI_FASTRAM		0x19000000	/* On-chip RAM on chips that also have DDR */
+-#define	SI_FASTRAM_SWAPPED	0x19800000
+-
+-#define	SI_FLASH2		0x1c000000	/* Flash Region 2 (region 1 shadowed here) */
+-#define	SI_FLASH2_SZ		0x02000000	/* Size of Flash Region 2 */
+-#define	SI_ARMCM3_ROM		0x1e000000	/* ARM Cortex-M3 ROM */
+-#define	SI_FLASH1		0x1fc00000	/* MIPS Flash Region 1 */
+-#define	SI_FLASH1_SZ		0x00400000	/* MIPS Size of Flash Region 1 */
+-#define	SI_ARM7S_ROM		0x20000000	/* ARM7TDMI-S ROM */
+-#define	SI_ARMCM3_SRAM2		0x60000000	/* ARM Cortex-M3 SRAM Region 2 */
+-#define	SI_ARM7S_SRAM2		0x80000000	/* ARM7TDMI-S SRAM Region 2 */
+-#define	SI_ARM_FLASH1		0xffff0000	/* ARM Flash Region 1 */
+-#define	SI_ARM_FLASH1_SZ	0x00010000	/* ARM Size of Flash Region 1 */
+-
+-#define SI_PCI_DMA		0x40000000	/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA2		0x80000000	/* Client Mode sb2pcitranslation2 (1 GB) */
+-#define SI_PCI_DMA_SZ		0x40000000	/* Client Mode sb2pcitranslation2 size in bytes */
+-#define SI_PCIE_DMA_L32		0x00000000	/* PCIE Client Mode sb2pcitranslation2
+-						 * (2 ZettaBytes), low 32 bits
+-						 */
+-#define SI_PCIE_DMA_H32		0x80000000	/* PCIE Client Mode sb2pcitranslation2
+-						 * (2 ZettaBytes), high 32 bits
+-						 */
+-
+-/* core codes */
+-#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
+-#define	CC_CORE_ID		0x800	/* chipcommon core */
+-#define	ILINE20_CORE_ID		0x801	/* iline20 core */
+-#define	SRAM_CORE_ID		0x802	/* sram core */
+-#define	SDRAM_CORE_ID		0x803	/* sdram core */
+-#define	PCI_CORE_ID		0x804	/* pci core */
+-#define	MIPS_CORE_ID		0x805	/* mips core */
+-#define	ENET_CORE_ID		0x806	/* enet mac core */
+-#define	CODEC_CORE_ID		0x807	/* v90 codec core */
+-#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
+-#define	ADSL_CORE_ID		0x809	/* ADSL core */
+-#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
+-#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
+-#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
+-#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
+-#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
+-#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
+-#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
+-#define	EXTIF_CORE_ID		0x811	/* external interface core */
+-#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
+-#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
+-#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
+-#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
+-#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
+-#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
+-#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
+-#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
+-#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
+-#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
+-#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
+-#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
+-#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
+-#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
+-#define	PCIE_CORE_ID		0x820	/* pci express core */
+-#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
+-#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
+-#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
+-#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
+-#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
+-#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
+-#define	PMU_CORE_ID		0x827	/* PMU core */
+-#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
+-#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
+-#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
+-#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
+-#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
+-#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
+-#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
+-#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
+-#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
+-#define	SC_CORE_ID		0x831	/* shared common core */
+-#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
+-#define	SPIH_CORE_ID		0x833	/* SPI host core */
+-#define	I2S_CORE_ID		0x834	/* I2S core */
+-#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
+-#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
+-#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
+-#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it maps all
+-					 * unused address ranges
+-					 */
+-
+-/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+- * and chipcommon being the first core:
+- */
+-#define	SI_CC_IDX		0
+-
+-/* SOC Interconnect types (aka chip types) */
+-#define	SOCI_AI			1
+-
+-/* Common core control flags */
+-#define	SICF_BIST_EN		0x8000
+-#define	SICF_PME_EN		0x4000
+-#define	SICF_CORE_BITS		0x3ffc
+-#define	SICF_FGC		0x0002
+-#define	SICF_CLOCK_EN		0x0001
+-
+-/* Common core status flags */
+-#define	SISF_BIST_DONE		0x8000
+-#define	SISF_BIST_ERROR		0x4000
+-#define	SISF_GATED_CLK		0x2000
+-#define	SISF_DMA64		0x1000
+-#define	SISF_CORE_BITS		0x0fff
+-
+-/* A register that is common to all cores to
+- * communicate w/PMU regarding clock control.
+- */
+-#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
+-
+-/* clk_ctl_st register */
+-#define	CCS_FORCEALP		0x00000001	/* force ALP request */
+-#define	CCS_FORCEHT		0x00000002	/* force HT request */
+-#define	CCS_FORCEILP		0x00000004	/* force ILP request */
+-#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
+-#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
+-#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
+-#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
+-#define CCS_ERSRC_REQ_SHIFT	8
+-#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
+-#define	CCS_HTAVAIL		0x00020000	/* HT is available */
+-#define CCS_BP_ON_APL		0x00040000	/* RO: Backplane is running on ALP clock */
+-#define CCS_BP_ON_HT		0x00080000	/* RO: Backplane is running on HT clock */
+-#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
+-#define CCS_ERSRC_STS_SHIFT	24
+-
+-#define	CCS0_HTAVAIL		0x00010000	/* HT avail in chipc and pcmcia on 4328a0 */
+-#define	CCS0_ALPAVAIL		0x00020000	/* ALP avail in chipc and pcmcia on 4328a0 */
+-
+-/* Not really related to SOC Interconnect, but a couple of software
+- * conventions for the use the flash space:
+- */
+-
+-/* Minimum amount of flash we support */
+-#define FLASH_MIN		0x00020000	/* Minimum flash size */
+-
+-/* A boot/binary may have an embedded block that describes its size  */
+-#define	BISZ_OFFSET		0x3e0	/* At this offset into the binary */
+-#define	BISZ_MAGIC		0x4249535a	/* Marked with this value: 'BISZ' */
+-#define	BISZ_MAGIC_IDX		0	/* Word 0: magic */
+-#define	BISZ_TXTST_IDX		1	/*      1: text start */
+-#define	BISZ_TXTEND_IDX		2	/*      2: text end */
+-#define	BISZ_DATAST_IDX		3	/*      3: data start */
+-#define	BISZ_DATAEND_IDX	4	/*      4: data end */
+-#define	BISZ_BSSST_IDX		5	/*      5: bss start */
+-#define	BISZ_BSSEND_IDX		6	/*      6: bss end */
+-#define BISZ_SIZE		7	/* descriptor size in 32-bit integers */
+-
+-#endif				/* _HNDSOC_H */
+diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h
+deleted file mode 100644
+index 30321eb..0000000
+--- a/drivers/staging/brcm80211/include/nicpci.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_NICPCI_H
+-#define	_NICPCI_H
+-
+-#if defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS))
+-#define pcicore_find_pci_capability(a, b, c, d) (0)
+-#define pcie_readreg(a, b, c, d) (0)
+-#define pcie_writereg(a, b, c, d, e) (0)
+-
+-#define pcie_clkreq(a, b, c)	(0)
+-#define pcie_lcreg(a, b, c)	(0)
+-
+-#define pcicore_init(a, b, c) (0x0dadbeef)
+-#define pcicore_deinit(a)	do { } while (0)
+-#define pcicore_attach(a, b, c)	do { } while (0)
+-#define pcicore_hwup(a)		do { } while (0)
+-#define pcicore_up(a, b)	do { } while (0)
+-#define pcicore_sleep(a)	do { } while (0)
+-#define pcicore_down(a, b)	do { } while (0)
+-
+-#define pcie_war_ovr_aspm_update(a, b)	do { } while (0)
+-
+-#define pcicore_pcieserdesreg(a, b, c, d, e) (0)
+-#define pcicore_pciereg(a, b, c, d, e) (0)
+-
+-#define pcicore_pmecap_fast(a)	(false)
+-#define pcicore_pmeen(a)	do { } while (0)
+-#define pcicore_pmeclr(a)	do { } while (0)
+-#define pcicore_pmestat(a)	(false)
+-#else
+-struct sbpcieregs;
+-
+-extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id,
+-					 unsigned char *buf, u32 *buflen);
+-extern uint pcie_readreg(struct sbpcieregs *pcieregs,
+-			 uint addrtype, uint offset);
+-extern uint pcie_writereg(struct sbpcieregs *pcieregs,
+-			  uint addrtype, uint offset, uint val);
+-
+-extern u8 pcie_clkreq(void *pch, u32 mask, u32 val);
+-extern u32 pcie_lcreg(void *pch, u32 mask, u32 val);
+-
+-extern void *pcicore_init(si_t *sih, void *pdev, void *regs);
+-extern void pcicore_deinit(void *pch);
+-extern void pcicore_attach(void *pch, char *pvars, int state);
+-extern void pcicore_hwup(void *pch);
+-extern void pcicore_up(void *pch, int state);
+-extern void pcicore_sleep(void *pch);
+-extern void pcicore_down(void *pch, int state);
+-
+-extern void pcie_war_ovr_aspm_update(void *pch, u8 aspm);
+-extern u32 pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset,
+-				    u32 mask, u32 val);
+-
+-extern u32 pcicore_pciereg(void *pch, u32 offset, u32 mask,
+-			      u32 val, uint type);
+-
+-extern bool pcicore_pmecap_fast(void *pch);
+-extern void pcicore_pmeen(void *pch);
+-extern void pcicore_pmeclr(void *pch);
+-extern bool pcicore_pmestat(void *pch);
+-#endif /* defined(BCMSDIO)||(defined(BCMBUSTYPE) && (BCMBUSTYPE==SI_BUS)) */
+-
+-#endif				/* _NICPCI_H */
+diff --git a/drivers/staging/brcm80211/include/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h
+deleted file mode 100644
+index 9153dcb..0000000
+--- a/drivers/staging/brcm80211/include/pci_core.h
++++ /dev/null
+@@ -1,122 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_PCI_CORE_H_
+-#define	_PCI_CORE_H_
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* Sonics side: PCI core and host control registers */
+-struct sbpciregs {
+-	u32 control;		/* PCI control */
+-	u32 PAD[3];
+-	u32 arbcontrol;	/* PCI arbiter control */
+-	u32 clkrun;		/* Clkrun Control (>=rev11) */
+-	u32 PAD[2];
+-	u32 intstatus;	/* Interrupt status */
+-	u32 intmask;		/* Interrupt mask */
+-	u32 sbtopcimailbox;	/* Sonics to PCI mailbox */
+-	u32 PAD[9];
+-	u32 bcastaddr;	/* Sonics broadcast address */
+-	u32 bcastdata;	/* Sonics broadcast data */
+-	u32 PAD[2];
+-	u32 gpioin;		/* ro: gpio input (>=rev2) */
+-	u32 gpioout;		/* rw: gpio output (>=rev2) */
+-	u32 gpioouten;	/* rw: gpio output enable (>= rev2) */
+-	u32 gpiocontrol;	/* rw: gpio control (>= rev2) */
+-	u32 PAD[36];
+-	u32 sbtopci0;	/* Sonics to PCI translation 0 */
+-	u32 sbtopci1;	/* Sonics to PCI translation 1 */
+-	u32 sbtopci2;	/* Sonics to PCI translation 2 */
+-	u32 PAD[189];
+-	u32 pcicfg[4][64];	/* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
+-	u16 sprom[36];	/* SPROM shadow Area */
+-	u32 PAD[46];
+-};
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* PCI control */
+-#define PCI_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
+-#define PCI_RST		0x02	/* Value driven out to pin */
+-#define PCI_CLK_OE	0x04	/* When set, drives clock as gated by PCI_CLK out to pin */
+-#define PCI_CLK		0x08	/* Gate for clock driven out to pin */
+-
+-/* PCI arbiter control */
+-#define PCI_INT_ARB	0x01	/* When set, use an internal arbiter */
+-#define PCI_EXT_ARB	0x02	/* When set, use an external arbiter */
+-/* ParkID - for PCI corerev >= 8 */
+-#define PCI_PARKID_MASK		0x1c	/* Selects which agent is parked on an idle bus */
+-#define PCI_PARKID_SHIFT	2
+-#define PCI_PARKID_EXT0		0	/* External master 0 */
+-#define PCI_PARKID_EXT1		1	/* External master 1 */
+-#define PCI_PARKID_EXT2		2	/* External master 2 */
+-#define PCI_PARKID_EXT3		3	/* External master 3 (rev >= 11) */
+-#define PCI_PARKID_INT		3	/* Internal master (rev < 11) */
+-#define PCI11_PARKID_INT	4	/* Internal master (rev >= 11) */
+-#define PCI_PARKID_LAST		4	/* Last active master (rev < 11) */
+-#define PCI11_PARKID_LAST	5	/* Last active master (rev >= 11) */
+-
+-#define PCI_CLKRUN_DSBL	0x8000	/* Bit 15 forceClkrun */
+-
+-/* Interrupt status/mask */
+-#define PCI_INTA	0x01	/* PCI INTA# is asserted */
+-#define PCI_INTB	0x02	/* PCI INTB# is asserted */
+-#define PCI_SERR	0x04	/* PCI SERR# has been asserted (write one to clear) */
+-#define PCI_PERR	0x08	/* PCI PERR# has been asserted (write one to clear) */
+-#define PCI_PME		0x10	/* PCI PME# is asserted */
+-
+-/* (General) PCI/SB mailbox interrupts, two bits per pci function */
+-#define	MAILBOX_F0_0	0x100	/* function 0, int 0 */
+-#define	MAILBOX_F0_1	0x200	/* function 0, int 1 */
+-#define	MAILBOX_F1_0	0x400	/* function 1, int 0 */
+-#define	MAILBOX_F1_1	0x800	/* function 1, int 1 */
+-#define	MAILBOX_F2_0	0x1000	/* function 2, int 0 */
+-#define	MAILBOX_F2_1	0x2000	/* function 2, int 1 */
+-#define	MAILBOX_F3_0	0x4000	/* function 3, int 0 */
+-#define	MAILBOX_F3_1	0x8000	/* function 3, int 1 */
+-
+-/* Sonics broadcast address */
+-#define BCAST_ADDR_MASK	0xff	/* Broadcast register address */
+-
+-/* Sonics to PCI translation types */
+-#define SBTOPCI0_MASK	0xfc000000
+-#define SBTOPCI1_MASK	0xfc000000
+-#define SBTOPCI2_MASK	0xc0000000
+-#define SBTOPCI_MEM	0
+-#define SBTOPCI_IO	1
+-#define SBTOPCI_CFG0	2
+-#define SBTOPCI_CFG1	3
+-#define	SBTOPCI_PREF	0x4	/* prefetch enable */
+-#define	SBTOPCI_BURST	0x8	/* burst enable */
+-#define	SBTOPCI_RC_MASK		0x30	/* read command (>= rev11) */
+-#define	SBTOPCI_RC_READ		0x00	/* memory read */
+-#define	SBTOPCI_RC_READLINE	0x10	/* memory read line */
+-#define	SBTOPCI_RC_READMULTI	0x20	/* memory read multiple */
+-
+-/* PCI core index in SROM shadow area */
+-#define SRSH_PI_OFFSET	0	/* first word */
+-#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
+-#define SRSH_PI_SHIFT	12	/* bit 15:12 */
+-
+-#endif				/* _PCI_CORE_H_ */
+diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h
+deleted file mode 100644
+index d0c617a..0000000
+--- a/drivers/staging/brcm80211/include/pcicfg.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_h_pcicfg_
+-#define	_h_pcicfg_
+-
+-#include <linux/pci_regs.h>
+-
+-/* PCI configuration address space size */
+-#define PCI_SZPCR		256
+-
+-/* Everything below is BRCM HND proprietary */
+-
+-/* Brcm PCI configuration registers */
+-#define PCI_BAR0_WIN		0x80	/* backplane address space accessed by BAR0 */
+-#define PCI_SPROM_CONTROL	0x88	/* sprom property control */
+-#define PCI_INT_MASK		0x94	/* mask of PCI and other cores interrupts */
+-#define  PCI_SBIM_SHIFT		8	/* backplane core interrupt mask bits offset */
+-#define PCI_BAR0_WIN2		0xac	/* backplane address space accessed by second 4KB of BAR0 */
+-#define PCI_GPIO_IN		0xb0	/* pci config space gpio input (>=rev3) */
+-#define PCI_GPIO_OUT		0xb4	/* pci config space gpio output (>=rev3) */
+-#define PCI_GPIO_OUTEN		0xb8	/* pci config space gpio output enable (>=rev3) */
+-
+-#define PCI_BAR0_SPROM_OFFSET	(4 * 1024)	/* bar0 + 4K accesses external sprom */
+-#define PCI_BAR0_PCIREGS_OFFSET	(6 * 1024)	/* bar0 + 6K accesses pci core registers */
+-#define PCI_BAR0_PCISBR_OFFSET	(4 * 1024)	/* pci core SB registers are at the end of the
+-						 * 8KB window, so their address is the "regular"
+-						 * address plus 4K
+-						 */
+-#define PCI_BAR0_WINSZ		(16 * 1024)	/* bar0 window size Match with corerev 13 */
+-/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
+-#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)	/* bar0 + 8K accesses pci/pcie core registers */
+-#define PCI_16KB0_CCREGS_OFFSET	(12 * 1024)	/* bar0 + 12K accesses chipc core registers */
+-
+-#define PCI_SBIM_STATUS_SERR	0x4	/* backplane SBErr interrupt status */
+-
+-#endif				/* _h_pcicfg_ */
+diff --git a/drivers/staging/brcm80211/include/pcie_core.h b/drivers/staging/brcm80211/include/pcie_core.h
+deleted file mode 100644
+index cd54ddc..0000000
+--- a/drivers/staging/brcm80211/include/pcie_core.h
++++ /dev/null
+@@ -1,299 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_PCIE_CORE_H
+-#define	_PCIE_CORE_H
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* PCIE Enumeration space offsets */
+-#define  PCIE_CORE_CONFIG_OFFSET	0x0
+-#define  PCIE_FUNC0_CONFIG_OFFSET	0x400
+-#define  PCIE_FUNC1_CONFIG_OFFSET	0x500
+-#define  PCIE_FUNC2_CONFIG_OFFSET	0x600
+-#define  PCIE_FUNC3_CONFIG_OFFSET	0x700
+-#define  PCIE_SPROM_SHADOW_OFFSET	0x800
+-#define  PCIE_SBCONFIG_OFFSET		0xE00
+-
+-/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */
+-#define PCIE_DEV_BAR0_SIZE		0x4000
+-#define PCIE_BAR0_WINMAPCORE_OFFSET	0x0
+-#define PCIE_BAR0_EXTSPROM_OFFSET	0x1000
+-#define PCIE_BAR0_PCIECORE_OFFSET	0x2000
+-#define PCIE_BAR0_CCCOREREG_OFFSET	0x3000
+-
+-/* different register spaces to access thr'u pcie indirect access */
+-#define PCIE_CONFIGREGS 	1	/* Access to config space */
+-#define PCIE_PCIEREGS 		2	/* Access to pcie registers */
+-
+-/* SB side: PCIE core and host control registers */
+-typedef struct sbpcieregs {
+-	u32 control;		/* host mode only */
+-	u32 PAD[2];
+-	u32 biststatus;	/* bist Status: 0x00C */
+-	u32 gpiosel;		/* PCIE gpio sel: 0x010 */
+-	u32 gpioouten;	/* PCIE gpio outen: 0x14 */
+-	u32 PAD[2];
+-	u32 intstatus;	/* Interrupt status: 0x20 */
+-	u32 intmask;		/* Interrupt mask: 0x24 */
+-	u32 sbtopcimailbox;	/* sb to pcie mailbox: 0x028 */
+-	u32 PAD[53];
+-	u32 sbtopcie0;	/* sb to pcie translation 0: 0x100 */
+-	u32 sbtopcie1;	/* sb to pcie translation 1: 0x104 */
+-	u32 sbtopcie2;	/* sb to pcie translation 2: 0x108 */
+-	u32 PAD[5];
+-
+-	/* pcie core supports in direct access to config space */
+-	u32 configaddr;	/* pcie config space access: Address field: 0x120 */
+-	u32 configdata;	/* pcie config space access: Data field: 0x124 */
+-
+-	/* mdio access to serdes */
+-	u32 mdiocontrol;	/* controls the mdio access: 0x128 */
+-	u32 mdiodata;	/* Data to the mdio access: 0x12c */
+-
+-	/* pcie protocol phy/dllp/tlp register indirect access mechanism */
+-	u32 pcieindaddr;	/* indirect access to the internal register: 0x130 */
+-	u32 pcieinddata;	/* Data to/from the internal regsiter: 0x134 */
+-
+-	u32 clkreqenctrl;	/* >= rev 6, Clkreq rdma control : 0x138 */
+-	u32 PAD[177];
+-	u32 pciecfg[4][64];	/* 0x400 - 0x7FF, PCIE Cfg Space */
+-	u16 sprom[64];	/* SPROM shadow Area */
+-} sbpcieregs_t;
+-
+-/* PCI control */
+-#define PCIE_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
+-#define PCIE_RST	0x02	/* Value driven out to pin */
+-
+-#define	PCIE_CFGADDR	0x120	/* offsetof(configaddr) */
+-#define	PCIE_CFGDATA	0x124	/* offsetof(configdata) */
+-
+-/* Interrupt status/mask */
+-#define PCIE_INTA	0x01	/* PCIE INTA message is received */
+-#define PCIE_INTB	0x02	/* PCIE INTB message is received */
+-#define PCIE_INTFATAL	0x04	/* PCIE INTFATAL message is received */
+-#define PCIE_INTNFATAL	0x08	/* PCIE INTNONFATAL message is received */
+-#define PCIE_INTCORR	0x10	/* PCIE INTCORR message is received */
+-#define PCIE_INTPME	0x20	/* PCIE INTPME message is received */
+-
+-/* SB to PCIE translation masks */
+-#define SBTOPCIE0_MASK	0xfc000000
+-#define SBTOPCIE1_MASK	0xfc000000
+-#define SBTOPCIE2_MASK	0xc0000000
+-
+-/* Access type bits (0:1) */
+-#define SBTOPCIE_MEM	0
+-#define SBTOPCIE_IO	1
+-#define SBTOPCIE_CFG0	2
+-#define SBTOPCIE_CFG1	3
+-
+-/* Prefetch enable bit 2 */
+-#define SBTOPCIE_PF		4
+-
+-/* Write Burst enable for memory write bit 3 */
+-#define SBTOPCIE_WR_BURST	8
+-
+-/* config access */
+-#define CONFIGADDR_FUNC_MASK	0x7000
+-#define CONFIGADDR_FUNC_SHF	12
+-#define CONFIGADDR_REG_MASK	0x0FFF
+-#define CONFIGADDR_REG_SHF	0
+-
+-#define PCIE_CONFIG_INDADDR(f, r)	\
+-	((((f) & CONFIGADDR_FUNC_MASK) << CONFIGADDR_FUNC_SHF) | \
+-	(((r) & CONFIGADDR_REG_MASK) << CONFIGADDR_REG_SHF))
+-
+-/* PCIE protocol regs Indirect Address */
+-#define PCIEADDR_PROT_MASK	0x300
+-#define PCIEADDR_PROT_SHF	8
+-#define PCIEADDR_PL_TLP		0
+-#define PCIEADDR_PL_DLLP	1
+-#define PCIEADDR_PL_PLP		2
+-
+-/* PCIE protocol PHY diagnostic registers */
+-#define	PCIE_PLP_MODEREG		0x200	/* Mode */
+-#define	PCIE_PLP_STATUSREG		0x204	/* Status */
+-#define PCIE_PLP_LTSSMCTRLREG		0x208	/* LTSSM control */
+-#define PCIE_PLP_LTLINKNUMREG		0x20c	/* Link Training Link number */
+-#define PCIE_PLP_LTLANENUMREG		0x210	/* Link Training Lane number */
+-#define PCIE_PLP_LTNFTSREG		0x214	/* Link Training N_FTS */
+-#define PCIE_PLP_ATTNREG		0x218	/* Attention */
+-#define PCIE_PLP_ATTNMASKREG		0x21C	/* Attention Mask */
+-#define PCIE_PLP_RXERRCTR		0x220	/* Rx Error */
+-#define PCIE_PLP_RXFRMERRCTR		0x224	/* Rx Framing Error */
+-#define PCIE_PLP_RXERRTHRESHREG		0x228	/* Rx Error threshold */
+-#define PCIE_PLP_TESTCTRLREG		0x22C	/* Test Control reg */
+-#define PCIE_PLP_SERDESCTRLOVRDREG	0x230	/* SERDES Control Override */
+-#define PCIE_PLP_TIMINGOVRDREG		0x234	/* Timing param override */
+-#define PCIE_PLP_RXTXSMDIAGREG		0x238	/* RXTX State Machine Diag */
+-#define PCIE_PLP_LTSSMDIAGREG		0x23C	/* LTSSM State Machine Diag */
+-
+-/* PCIE protocol DLLP diagnostic registers */
+-#define PCIE_DLLP_LCREG			0x100	/* Link Control */
+-#define PCIE_DLLP_LSREG			0x104	/* Link Status */
+-#define PCIE_DLLP_LAREG			0x108	/* Link Attention */
+-#define PCIE_DLLP_LAMASKREG		0x10C	/* Link Attention Mask */
+-#define PCIE_DLLP_NEXTTXSEQNUMREG	0x110	/* Next Tx Seq Num */
+-#define PCIE_DLLP_ACKEDTXSEQNUMREG	0x114	/* Acked Tx Seq Num */
+-#define PCIE_DLLP_PURGEDTXSEQNUMREG	0x118	/* Purged Tx Seq Num */
+-#define PCIE_DLLP_RXSEQNUMREG		0x11C	/* Rx Sequence Number */
+-#define PCIE_DLLP_LRREG			0x120	/* Link Replay */
+-#define PCIE_DLLP_LACKTOREG		0x124	/* Link Ack Timeout */
+-#define PCIE_DLLP_PMTHRESHREG		0x128	/* Power Management Threshold */
+-#define PCIE_DLLP_RTRYWPREG		0x12C	/* Retry buffer write ptr */
+-#define PCIE_DLLP_RTRYRPREG		0x130	/* Retry buffer Read ptr */
+-#define PCIE_DLLP_RTRYPPREG		0x134	/* Retry buffer Purged ptr */
+-#define PCIE_DLLP_RTRRWREG		0x138	/* Retry buffer Read/Write */
+-#define PCIE_DLLP_ECTHRESHREG		0x13C	/* Error Count Threshold */
+-#define PCIE_DLLP_TLPERRCTRREG		0x140	/* TLP Error Counter */
+-#define PCIE_DLLP_ERRCTRREG		0x144	/* Error Counter */
+-#define PCIE_DLLP_NAKRXCTRREG		0x148	/* NAK Received Counter */
+-#define PCIE_DLLP_TESTREG		0x14C	/* Test */
+-#define PCIE_DLLP_PKTBIST		0x150	/* Packet BIST */
+-#define PCIE_DLLP_PCIE11		0x154	/* DLLP PCIE 1.1 reg */
+-
+-#define PCIE_DLLP_LSREG_LINKUP		(1 << 16)
+-
+-/* PCIE protocol TLP diagnostic registers */
+-#define PCIE_TLP_CONFIGREG		0x000	/* Configuration */
+-#define PCIE_TLP_WORKAROUNDSREG		0x004	/* TLP Workarounds */
+-#define PCIE_TLP_WRDMAUPPER		0x010	/* Write DMA Upper Address */
+-#define PCIE_TLP_WRDMALOWER		0x014	/* Write DMA Lower Address */
+-#define PCIE_TLP_WRDMAREQ_LBEREG	0x018	/* Write DMA Len/ByteEn Req */
+-#define PCIE_TLP_RDDMAUPPER		0x01C	/* Read DMA Upper Address */
+-#define PCIE_TLP_RDDMALOWER		0x020	/* Read DMA Lower Address */
+-#define PCIE_TLP_RDDMALENREG		0x024	/* Read DMA Len Req */
+-#define PCIE_TLP_MSIDMAUPPER		0x028	/* MSI DMA Upper Address */
+-#define PCIE_TLP_MSIDMALOWER		0x02C	/* MSI DMA Lower Address */
+-#define PCIE_TLP_MSIDMALENREG		0x030	/* MSI DMA Len Req */
+-#define PCIE_TLP_SLVREQLENREG		0x034	/* Slave Request Len */
+-#define PCIE_TLP_FCINPUTSREQ		0x038	/* Flow Control Inputs */
+-#define PCIE_TLP_TXSMGRSREQ		0x03C	/* Tx StateMachine and Gated Req */
+-#define PCIE_TLP_ADRACKCNTARBLEN	0x040	/* Address Ack XferCnt and ARB Len */
+-#define PCIE_TLP_DMACPLHDR0		0x044	/* DMA Completion Hdr 0 */
+-#define PCIE_TLP_DMACPLHDR1		0x048	/* DMA Completion Hdr 1 */
+-#define PCIE_TLP_DMACPLHDR2		0x04C	/* DMA Completion Hdr 2 */
+-#define PCIE_TLP_DMACPLMISC0		0x050	/* DMA Completion Misc0 */
+-#define PCIE_TLP_DMACPLMISC1		0x054	/* DMA Completion Misc1 */
+-#define PCIE_TLP_DMACPLMISC2		0x058	/* DMA Completion Misc2 */
+-#define PCIE_TLP_SPTCTRLLEN		0x05C	/* Split Controller Req len */
+-#define PCIE_TLP_SPTCTRLMSIC0		0x060	/* Split Controller Misc 0 */
+-#define PCIE_TLP_SPTCTRLMSIC1		0x064	/* Split Controller Misc 1 */
+-#define PCIE_TLP_BUSDEVFUNC		0x068	/* Bus/Device/Func */
+-#define PCIE_TLP_RESETCTR		0x06C	/* Reset Counter */
+-#define PCIE_TLP_RTRYBUF		0x070	/* Retry Buffer value */
+-#define PCIE_TLP_TGTDEBUG1		0x074	/* Target Debug Reg1 */
+-#define PCIE_TLP_TGTDEBUG2		0x078	/* Target Debug Reg2 */
+-#define PCIE_TLP_TGTDEBUG3		0x07C	/* Target Debug Reg3 */
+-#define PCIE_TLP_TGTDEBUG4		0x080	/* Target Debug Reg4 */
+-
+-/* MDIO control */
+-#define MDIOCTL_DIVISOR_MASK		0x7f	/* clock to be used on MDIO */
+-#define MDIOCTL_DIVISOR_VAL		0x2
+-#define MDIOCTL_PREAM_EN		0x80	/* Enable preamble sequnce */
+-#define MDIOCTL_ACCESS_DONE		0x100	/* Tranaction complete */
+-
+-/* MDIO Data */
+-#define MDIODATA_MASK			0x0000ffff	/* data 2 bytes */
+-#define MDIODATA_TA			0x00020000	/* Turnaround */
+-#define MDIODATA_REGADDR_SHF_OLD	18	/* Regaddr shift (rev < 10) */
+-#define MDIODATA_REGADDR_MASK_OLD	0x003c0000	/* Regaddr Mask (rev < 10) */
+-#define MDIODATA_DEVADDR_SHF_OLD	22	/* Physmedia devaddr shift (rev < 10) */
+-#define MDIODATA_DEVADDR_MASK_OLD	0x0fc00000	/* Physmedia devaddr Mask (rev < 10) */
+-#define MDIODATA_REGADDR_SHF		18	/* Regaddr shift */
+-#define MDIODATA_REGADDR_MASK		0x007c0000	/* Regaddr Mask */
+-#define MDIODATA_DEVADDR_SHF		23	/* Physmedia devaddr shift */
+-#define MDIODATA_DEVADDR_MASK		0x0f800000	/* Physmedia devaddr Mask */
+-#define MDIODATA_WRITE			0x10000000	/* write Transaction */
+-#define MDIODATA_READ			0x20000000	/* Read Transaction */
+-#define MDIODATA_START			0x40000000	/* start of Transaction */
+-
+-#define MDIODATA_DEV_ADDR		0x0	/* dev address for serdes */
+-#define	MDIODATA_BLK_ADDR		0x1F	/* blk address for serdes */
+-
+-/* MDIO devices (SERDES modules)
+- *  unlike old pcie cores (rev < 10), rev10 pcie serde organizes registers into a few blocks.
+- *  two layers mapping (blockidx, register offset) is required
+- */
+-#define MDIO_DEV_IEEE0		0x000
+-#define MDIO_DEV_IEEE1		0x001
+-#define MDIO_DEV_BLK0		0x800
+-#define MDIO_DEV_BLK1		0x801
+-#define MDIO_DEV_BLK2		0x802
+-#define MDIO_DEV_BLK3		0x803
+-#define MDIO_DEV_BLK4		0x804
+-#define MDIO_DEV_TXPLL		0x808	/* TXPLL register block idx */
+-#define MDIO_DEV_TXCTRL0	0x820
+-#define MDIO_DEV_SERDESID	0x831
+-#define MDIO_DEV_RXCTRL0	0x840
+-
+-/* serdes regs (rev < 10) */
+-#define MDIODATA_DEV_PLL       		0x1d	/* SERDES PLL Dev */
+-#define MDIODATA_DEV_TX        		0x1e	/* SERDES TX Dev */
+-#define MDIODATA_DEV_RX        		0x1f	/* SERDES RX Dev */
+-	/* SERDES RX registers */
+-#define SERDES_RX_CTRL			1	/* Rx cntrl */
+-#define SERDES_RX_TIMER1		2	/* Rx Timer1 */
+-#define SERDES_RX_CDR			6	/* CDR */
+-#define SERDES_RX_CDRBW			7	/* CDR BW */
+-
+-	/* SERDES RX control register */
+-#define SERDES_RX_CTRL_FORCE		0x80	/* rxpolarity_force */
+-#define SERDES_RX_CTRL_POLARITY		0x40	/* rxpolarity_value */
+-
+-	/* SERDES PLL registers */
+-#define SERDES_PLL_CTRL                 1	/* PLL control reg */
+-#define PLL_CTRL_FREQDET_EN             0x4000	/* bit 14 is FREQDET on */
+-
+-/* Power management threshold */
+-#define PCIE_L0THRESHOLDTIME_MASK       0xFF00	/* bits 0 - 7 */
+-#define PCIE_L1THRESHOLDTIME_MASK       0xFF00	/* bits 8 - 15 */
+-#define PCIE_L1THRESHOLDTIME_SHIFT      8	/* PCIE_L1THRESHOLDTIME_SHIFT */
+-#define PCIE_L1THRESHOLD_WARVAL         0x72	/* WAR value */
+-#define PCIE_ASPMTIMER_EXTEND		0x01000000	/* > rev7: enable extend ASPM timer */
+-
+-/* SPROM offsets */
+-#define SRSH_ASPM_OFFSET		4	/* word 4 */
+-#define SRSH_ASPM_ENB			0x18	/* bit 3, 4 */
+-#define SRSH_ASPM_L1_ENB		0x10	/* bit 4 */
+-#define SRSH_ASPM_L0s_ENB		0x8	/* bit 3 */
+-#define SRSH_PCIE_MISC_CONFIG		5	/* word 5 */
+-#define SRSH_L23READY_EXIT_NOPERST	0x8000	/* bit 15 */
+-#define SRSH_CLKREQ_OFFSET_REV5		20	/* word 20 for srom rev <= 5 */
+-#define SRSH_CLKREQ_OFFSET_REV8		52	/* word 52 for srom rev 8 */
+-#define SRSH_CLKREQ_ENB			0x0800	/* bit 11 */
+-#define SRSH_BD_OFFSET                  6	/* word 6 */
+-#define SRSH_AUTOINIT_OFFSET            18	/* auto initialization enable */
+-
+-/* Linkcontrol reg offset in PCIE Cap */
+-#define PCIE_CAP_LINKCTRL_OFFSET	16	/* linkctrl offset in pcie cap */
+-#define PCIE_CAP_LCREG_ASPML0s		0x01	/* ASPM L0s in linkctrl */
+-#define PCIE_CAP_LCREG_ASPML1		0x02	/* ASPM L1 in linkctrl */
+-#define PCIE_CLKREQ_ENAB		0x100	/* CLKREQ Enab in linkctrl */
+-
+-#define PCIE_ASPM_ENAB			3	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_L1_ENAB		2	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_L0s_ENAB		1	/* ASPM L0s & L1 in linkctrl */
+-#define PCIE_ASPM_DISAB			0	/* ASPM L0s & L1 in linkctrl */
+-
+-/* Status reg PCIE_PLP_STATUSREG */
+-#define PCIE_PLP_POLARITYINV_STAT	0x10
+-#endif				/* _PCIE_CORE_H */
+diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h
+deleted file mode 100644
+index 374125d..0000000
+--- a/drivers/staging/brcm80211/include/proto/802.11.h
++++ /dev/null
+@@ -1,200 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _802_11_H_
+-#define _802_11_H_
+-
+-#include <linux/if_ether.h>
+-
+-#define DOT11_A3_HDR_LEN		24
+-#define DOT11_A4_HDR_LEN		30
+-#define DOT11_MAC_HDR_LEN		DOT11_A3_HDR_LEN
+-#define DOT11_ICV_AES_LEN		8
+-#define DOT11_QOS_LEN			2
+-
+-#define DOT11_IV_MAX_LEN		8
+-
+-#define DOT11_DEFAULT_RTS_LEN		2347
+-
+-#define DOT11_MIN_FRAG_LEN		256
+-#define DOT11_MAX_FRAG_LEN		2346
+-#define DOT11_DEFAULT_FRAG_LEN		2346
+-
+-#define DOT11_MIN_BEACON_PERIOD		1
+-#define DOT11_MAX_BEACON_PERIOD		0xFFFF
+-
+-#define DOT11_MIN_DTIM_PERIOD		1
+-#define DOT11_MAX_DTIM_PERIOD		0xFF
+-
+-#define DOT11_OUI_LEN			3
+-
+-#define	DOT11_RTS_LEN		16
+-#define	DOT11_CTS_LEN		10
+-#define	DOT11_ACK_LEN		10
+-
+-#define DOT11_BA_BITMAP_LEN		128
+-#define DOT11_BA_LEN		4
+-
+-#define WME_OUI			"\x00\x50\xf2"
+-#define WME_VER			1
+-#define WME_TYPE		2
+-#define WME_SUBTYPE_PARAM_IE	1
+-
+-#define AC_BE			0
+-#define AC_BK			1
+-#define AC_VI			2
+-#define AC_VO			3
+-#define AC_COUNT		4
+-
+-typedef u8 ac_bitmap_t;
+-
+-#define AC_BITMAP_ALL		0xf
+-#define AC_BITMAP_TST(ab, ac)	(((ab) & (1 << (ac))) != 0)
+-
+-struct edcf_acparam {
+-	u8 ACI;
+-	u8 ECW;
+-	u16 TXOP;
+-} __attribute__((packed));
+-typedef struct edcf_acparam edcf_acparam_t;
+-
+-struct wme_param_ie {
+-	u8 oui[3];
+-	u8 type;
+-	u8 subtype;
+-	u8 version;
+-	u8 qosinfo;
+-	u8 rsvd;
+-	edcf_acparam_t acparam[AC_COUNT];
+-} __attribute__((packed));
+-typedef struct wme_param_ie wme_param_ie_t;
+-#define WME_PARAM_IE_LEN            24
+-
+-#define EDCF_AIFSN_MIN               1
+-#define EDCF_AIFSN_MAX               15
+-#define EDCF_AIFSN_MASK              0x0f
+-#define EDCF_ACM_MASK                0x10
+-#define EDCF_ACI_MASK                0x60
+-#define EDCF_ACI_SHIFT               5
+-
+-#define EDCF_ECW2CW(exp)             ((1 << (exp)) - 1)
+-#define EDCF_ECWMIN_MASK             0x0f
+-#define EDCF_ECWMAX_MASK             0xf0
+-#define EDCF_ECWMAX_SHIFT            4
+-
+-#define EDCF_TXOP2USEC(txop)         ((txop) << 5)
+-
+-#define EDCF_AC_BE_ACI_STA           0x03
+-#define EDCF_AC_BE_ECW_STA           0xA4
+-#define EDCF_AC_BE_TXOP_STA          0x0000
+-#define EDCF_AC_BK_ACI_STA           0x27
+-#define EDCF_AC_BK_ECW_STA           0xA4
+-#define EDCF_AC_BK_TXOP_STA          0x0000
+-#define EDCF_AC_VI_ACI_STA           0x42
+-#define EDCF_AC_VI_ECW_STA           0x43
+-#define EDCF_AC_VI_TXOP_STA          0x005e
+-#define EDCF_AC_VO_ACI_STA           0x62
+-#define EDCF_AC_VO_ECW_STA           0x32
+-#define EDCF_AC_VO_TXOP_STA          0x002f
+-
+-#define EDCF_AC_VO_TXOP_AP           0x002f
+-
+-#define SEQNUM_SHIFT		4
+-#define SEQNUM_MAX		0x1000
+-#define FRAGNUM_MASK		0xF
+-
+-#define DOT11_MNG_RSN_ID			48
+-#define DOT11_MNG_WPA_ID			221
+-#define DOT11_MNG_VS_ID				221
+-
+-#define DOT11_BSSTYPE_INFRASTRUCTURE		0
+-#define DOT11_BSSTYPE_ANY			2
+-#define DOT11_SCANTYPE_ACTIVE			0
+-
+-#define PREN_PREAMBLE		24
+-#define PREN_MM_EXT		12
+-#define PREN_PREAMBLE_EXT	4
+-
+-#define RIFS_11N_TIME		2
+-
+-#define APHY_SLOT_TIME		9
+-#define APHY_SIFS_TIME		16
+-#define APHY_PREAMBLE_TIME	16
+-#define APHY_SIGNAL_TIME	4
+-#define APHY_SYMBOL_TIME	4
+-#define APHY_SERVICE_NBITS	16
+-#define APHY_TAIL_NBITS		6
+-#define	APHY_CWMIN		15
+-
+-#define BPHY_SLOT_TIME		20
+-#define BPHY_SIFS_TIME		10
+-#define BPHY_PLCP_TIME		192
+-#define BPHY_PLCP_SHORT_TIME	96
+-
+-#define DOT11_OFDM_SIGNAL_EXTENSION	6
+-
+-#define PHY_CWMAX		1023
+-
+-#define	DOT11_MAXNUMFRAGS	16
+-
+-typedef struct d11cnt {
+-	u32 txfrag;
+-	u32 txmulti;
+-	u32 txfail;
+-	u32 txretry;
+-	u32 txretrie;
+-	u32 rxdup;
+-	u32 txrts;
+-	u32 txnocts;
+-	u32 txnoack;
+-	u32 rxfrag;
+-	u32 rxmulti;
+-	u32 rxcrc;
+-	u32 txfrmsnt;
+-	u32 rxundec;
+-} d11cnt_t;
+-
+-#define MCSSET_LEN	16
+-
+-#define HT_CAP_IE_LEN		26
+-
+-#define HT_CAP_RX_STBC_NO		0x0
+-#define HT_CAP_RX_STBC_ONE_STREAM	0x1
+-
+-#define AMPDU_MAX_MPDU_DENSITY	IEEE80211_HT_MPDU_DENSITY_16
+-
+-#define AMPDU_DELIMITER_LEN	4
+-
+-#define DOT11N_TXBURST		0x0008
+-
+-#define WPA_VERSION		1
+-#define WPA_OUI			"\x00\x50\xF2"
+-
+-#define WFA_OUI			"\x00\x50\xF2"
+-#define WFA_OUI_LEN	3
+-
+-#define WFA_OUI_TYPE_WPA	1
+-
+-#define RSN_AKM_NONE		0
+-#define RSN_AKM_UNSPECIFIED	1
+-#define RSN_AKM_PSK		2
+-
+-#define DOT11_MAX_DEFAULT_KEYS	4
+-#define DOT11_WPA_KEY_RSC_LEN   8
+-
+-#define BRCM_OUI		"\x00\x10\x18"
+-
+-#endif				/* _802_11_H_ */
+diff --git a/drivers/staging/brcm80211/include/proto/bcmeth.h b/drivers/staging/brcm80211/include/proto/bcmeth.h
+deleted file mode 100644
+index e98ee65..0000000
+--- a/drivers/staging/brcm80211/include/proto/bcmeth.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _BCMETH_H_
+-#define _BCMETH_H_
+-
+-#define	BCMILCP_SUBTYPE_RATE		1
+-#define	BCMILCP_SUBTYPE_LINK		2
+-#define	BCMILCP_SUBTYPE_CSA		3
+-#define	BCMILCP_SUBTYPE_LARQ		4
+-#define BCMILCP_SUBTYPE_VENDOR		5
+-#define	BCMILCP_SUBTYPE_FLH		17
+-#define BCMILCP_SUBTYPE_VENDOR_LONG	32769
+-#define BCMILCP_SUBTYPE_CERT		32770
+-#define BCMILCP_SUBTYPE_SES		32771
+-#define BCMILCP_BCM_SUBTYPE_RESERVED		0
+-#define BCMILCP_BCM_SUBTYPE_EVENT		1
+-#define BCMILCP_BCM_SUBTYPE_SES			2
+-#define BCMILCP_BCM_SUBTYPE_DPT			4
+-#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH	8
+-#define BCMILCP_BCM_SUBTYPEHDR_VERSION		0
+-
+-typedef  struct bcmeth_hdr {
+-	u16 subtype;
+-	u16 length;
+-	u8 version;
+-	u8 oui[3];
+-	u16 usr_subtype;
+-} __attribute__((packed)) bcmeth_hdr_t;
+-
+-#endif				/* _BCMETH_H_ */
+diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h
+deleted file mode 100644
+index 1b60789..0000000
+--- a/drivers/staging/brcm80211/include/proto/bcmevent.h
++++ /dev/null
+@@ -1,207 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _BCMEVENT_H_
+-#define _BCMEVENT_H_
+-
+-#include <linux/if_ether.h>
+-
+-#define BCM_EVENT_MSG_VERSION		1
+-#define BCM_MSG_IFNAME_MAX		16
+-
+-#define WLC_EVENT_MSG_LINK		0x01
+-#define WLC_EVENT_MSG_FLUSHTXQ		0x02
+-#define WLC_EVENT_MSG_GROUP		0x04
+-
+-typedef struct {
+-	u16 version;
+-	u16 flags;
+-	u32 event_type;
+-	u32 status;
+-	u32 reason;
+-	u32 auth_type;
+-	u32 datalen;
+-	u8 addr[ETH_ALEN];
+-	char ifname[BCM_MSG_IFNAME_MAX];
+-} __attribute__((packed)) wl_event_msg_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct bcm_event {
+-	struct ethhdr eth;
+-	bcmeth_hdr_t		bcm_hdr;
+-	wl_event_msg_t		event;
+-} __attribute__((packed)) bcm_event_t;
+-#endif
+-#define BCM_MSG_LEN	(sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - \
+-	sizeof(struct ether_header))
+-
+-#define WLC_E_SET_SSID		0
+-#define WLC_E_JOIN		1
+-#define WLC_E_START		2
+-#define WLC_E_AUTH		3
+-#define WLC_E_AUTH_IND		4
+-#define WLC_E_DEAUTH		5
+-#define WLC_E_DEAUTH_IND	6
+-#define WLC_E_ASSOC		7
+-#define WLC_E_ASSOC_IND		8
+-#define WLC_E_REASSOC		9
+-#define WLC_E_REASSOC_IND	10
+-#define WLC_E_DISASSOC		11
+-#define WLC_E_DISASSOC_IND	12
+-#define WLC_E_QUIET_START	13
+-#define WLC_E_QUIET_END		14
+-#define WLC_E_BEACON_RX		15
+-#define WLC_E_LINK		16
+-#define WLC_E_MIC_ERROR		17
+-#define WLC_E_NDIS_LINK		18
+-#define WLC_E_ROAM		19
+-#define WLC_E_TXFAIL		20
+-#define WLC_E_PMKID_CACHE	21
+-#define WLC_E_RETROGRADE_TSF	22
+-#define WLC_E_PRUNE		23
+-#define WLC_E_AUTOAUTH		24
+-#define WLC_E_EAPOL_MSG		25
+-#define WLC_E_SCAN_COMPLETE	26
+-#define WLC_E_ADDTS_IND		27
+-#define WLC_E_DELTS_IND		28
+-#define WLC_E_BCNSENT_IND	29
+-#define WLC_E_BCNRX_MSG		30
+-#define WLC_E_BCNLOST_MSG	31
+-#define WLC_E_ROAM_PREP		32
+-#define WLC_E_PFN_NET_FOUND	33
+-#define WLC_E_PFN_NET_LOST	34
+-#define WLC_E_RESET_COMPLETE	35
+-#define WLC_E_JOIN_START	36
+-#define WLC_E_ROAM_START	37
+-#define WLC_E_ASSOC_START	38
+-#define WLC_E_IBSS_ASSOC	39
+-#define WLC_E_RADIO		40
+-#define WLC_E_PSM_WATCHDOG	41
+-#define WLC_E_PROBREQ_MSG       44
+-#define WLC_E_SCAN_CONFIRM_IND  45
+-#define WLC_E_PSK_SUP		46
+-#define WLC_E_COUNTRY_CODE_CHANGED 47
+-#define	WLC_E_EXCEEDED_MEDIUM_TIME 48
+-#define WLC_E_ICV_ERROR		49
+-#define WLC_E_UNICAST_DECODE_ERROR 50
+-#define WLC_E_MULTICAST_DECODE_ERROR 51
+-#define WLC_E_TRACE		52
+-#define WLC_E_IF		54
+-#define WLC_E_RSSI		56
+-#define WLC_E_PFN_SCAN_COMPLETE	57
+-#define WLC_E_EXTLOG_MSG	58
+-#define WLC_E_ACTION_FRAME      59
+-#define WLC_E_ACTION_FRAME_COMPLETE 60
+-#define WLC_E_PRE_ASSOC_IND	61
+-#define WLC_E_PRE_REASSOC_IND	62
+-#define WLC_E_CHANNEL_ADOPTED	63
+-#define WLC_E_AP_STARTED	64
+-#define WLC_E_DFS_AP_STOP	65
+-#define WLC_E_DFS_AP_RESUME	66
+-#define WLC_E_RESERVED1		67
+-#define WLC_E_RESERVED2		68
+-#define WLC_E_ESCAN_RESULT 	69
+-#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 	70
+-#define WLC_E_DCS_REQUEST 73
+-
+-#define WLC_E_FIFO_CREDIT_MAP	74
+-
+-#define WLC_E_LAST		75
+-
+-typedef struct {
+-	uint event;
+-	const char *name;
+-} bcmevent_name_t;
+-
+-extern const bcmevent_name_t bcmevent_names[];
+-extern const int bcmevent_names_size;
+-
+-#define WLC_E_STATUS_SUCCESS		0
+-#define WLC_E_STATUS_FAIL		1
+-#define WLC_E_STATUS_TIMEOUT		2
+-#define WLC_E_STATUS_NO_NETWORKS	3
+-#define WLC_E_STATUS_ABORT		4
+-#define WLC_E_STATUS_NO_ACK		5
+-#define WLC_E_STATUS_UNSOLICITED	6
+-#define WLC_E_STATUS_ATTEMPT		7
+-#define WLC_E_STATUS_PARTIAL		8
+-#define WLC_E_STATUS_NEWSCAN		9
+-#define WLC_E_STATUS_NEWASSOC		10
+-#define WLC_E_STATUS_11HQUIET		11
+-#define WLC_E_STATUS_SUPPRESS		12
+-#define WLC_E_STATUS_NOCHANS		13
+-#define WLC_E_STATUS_CS_ABORT		15
+-#define WLC_E_STATUS_ERROR		16
+-
+-#define WLC_E_REASON_INITIAL_ASSOC	0
+-#define WLC_E_REASON_LOW_RSSI		1
+-#define WLC_E_REASON_DEAUTH		2
+-#define WLC_E_REASON_DISASSOC		3
+-#define WLC_E_REASON_BCNS_LOST		4
+-#define WLC_E_REASON_MINTXRATE		9
+-#define WLC_E_REASON_TXFAIL		10
+-
+-#define WLC_E_REASON_FAST_ROAM_FAILED	5
+-#define WLC_E_REASON_DIRECTED_ROAM	6
+-#define WLC_E_REASON_TSPEC_REJECTED	7
+-#define WLC_E_REASON_BETTER_AP		8
+-
+-#define WLC_E_PRUNE_ENCR_MISMATCH	1
+-#define WLC_E_PRUNE_BCAST_BSSID		2
+-#define WLC_E_PRUNE_MAC_DENY		3
+-#define WLC_E_PRUNE_MAC_NA		4
+-#define WLC_E_PRUNE_REG_PASSV		5
+-#define WLC_E_PRUNE_SPCT_MGMT		6
+-#define WLC_E_PRUNE_RADAR		7
+-#define WLC_E_RSN_MISMATCH		8
+-#define WLC_E_PRUNE_NO_COMMON_RATES	9
+-#define WLC_E_PRUNE_BASIC_RATES		10
+-#define WLC_E_PRUNE_CIPHER_NA		12
+-#define WLC_E_PRUNE_KNOWN_STA		13
+-#define WLC_E_PRUNE_WDS_PEER		15
+-#define WLC_E_PRUNE_QBSS_LOAD		16
+-#define WLC_E_PRUNE_HOME_AP		17
+-
+-#define WLC_E_SUP_OTHER			0
+-#define WLC_E_SUP_DECRYPT_KEY_DATA	1
+-#define WLC_E_SUP_BAD_UCAST_WEP128	2
+-#define WLC_E_SUP_BAD_UCAST_WEP40	3
+-#define WLC_E_SUP_UNSUP_KEY_LEN		4
+-#define WLC_E_SUP_PW_KEY_CIPHER		5
+-#define WLC_E_SUP_MSG3_TOO_MANY_IE	6
+-#define WLC_E_SUP_MSG3_IE_MISMATCH	7
+-#define WLC_E_SUP_NO_INSTALL_FLAG	8
+-#define WLC_E_SUP_MSG3_NO_GTK		9
+-#define WLC_E_SUP_GRP_KEY_CIPHER	10
+-#define WLC_E_SUP_GRP_MSG1_NO_GTK	11
+-#define WLC_E_SUP_GTK_DECRYPT_FAIL	12
+-#define WLC_E_SUP_SEND_FAIL		13
+-#define WLC_E_SUP_DEAUTH		14
+-
+-#define WLC_E_IF_ADD		1
+-#define WLC_E_IF_DEL		2
+-#define WLC_E_IF_CHANGE		3
+-
+-#define WLC_E_IF_ROLE_STA		0
+-#define WLC_E_IF_ROLE_AP		1
+-#define WLC_E_IF_ROLE_WDS		2
+-
+-#define WLC_E_LINK_BCN_LOSS	1
+-#define WLC_E_LINK_DISASSOC	2
+-#define WLC_E_LINK_ASSOC_REC	3
+-#define WLC_E_LINK_BSSCFG_DIS	4
+-
+-#endif				/* _BCMEVENT_H_ */
+diff --git a/drivers/staging/brcm80211/include/sbchipc.h b/drivers/staging/brcm80211/include/sbchipc.h
+deleted file mode 100644
+index 8c01c63..0000000
+--- a/drivers/staging/brcm80211/include/sbchipc.h
++++ /dev/null
+@@ -1,1588 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBCHIPC_H
+-#define	_SBCHIPC_H
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif				/* PAD */
+-
+-typedef volatile struct {
+-	u32 chipid;		/* 0x0 */
+-	u32 capabilities;
+-	u32 corecontrol;	/* corerev >= 1 */
+-	u32 bist;
+-
+-	/* OTP */
+-	u32 otpstatus;	/* 0x10, corerev >= 10 */
+-	u32 otpcontrol;
+-	u32 otpprog;
+-	u32 otplayout;	/* corerev >= 23 */
+-
+-	/* Interrupt control */
+-	u32 intstatus;	/* 0x20 */
+-	u32 intmask;
+-
+-	/* Chip specific regs */
+-	u32 chipcontrol;	/* 0x28, rev >= 11 */
+-	u32 chipstatus;	/* 0x2c, rev >= 11 */
+-
+-	/* Jtag Master */
+-	u32 jtagcmd;		/* 0x30, rev >= 10 */
+-	u32 jtagir;
+-	u32 jtagdr;
+-	u32 jtagctrl;
+-
+-	/* serial flash interface registers */
+-	u32 flashcontrol;	/* 0x40 */
+-	u32 flashaddress;
+-	u32 flashdata;
+-	u32 PAD[1];
+-
+-	/* Silicon backplane configuration broadcast control */
+-	u32 broadcastaddress;	/* 0x50 */
+-	u32 broadcastdata;
+-
+-	/* gpio - cleared only by power-on-reset */
+-	u32 gpiopullup;	/* 0x58, corerev >= 20 */
+-	u32 gpiopulldown;	/* 0x5c, corerev >= 20 */
+-	u32 gpioin;		/* 0x60 */
+-	u32 gpioout;		/* 0x64 */
+-	u32 gpioouten;	/* 0x68 */
+-	u32 gpiocontrol;	/* 0x6C */
+-	u32 gpiointpolarity;	/* 0x70 */
+-	u32 gpiointmask;	/* 0x74 */
+-
+-	/* GPIO events corerev >= 11 */
+-	u32 gpioevent;
+-	u32 gpioeventintmask;
+-
+-	/* Watchdog timer */
+-	u32 watchdog;	/* 0x80 */
+-
+-	/* GPIO events corerev >= 11 */
+-	u32 gpioeventintpolarity;
+-
+-	/* GPIO based LED powersave registers corerev >= 16 */
+-	u32 gpiotimerval;	/* 0x88 */
+-	u32 gpiotimeroutmask;
+-
+-	/* clock control */
+-	u32 clockcontrol_n;	/* 0x90 */
+-	u32 clockcontrol_sb;	/* aka m0 */
+-	u32 clockcontrol_pci;	/* aka m1 */
+-	u32 clockcontrol_m2;	/* mii/uart/mipsref */
+-	u32 clockcontrol_m3;	/* cpu */
+-	u32 clkdiv;		/* corerev >= 3 */
+-	u32 gpiodebugsel;	/* corerev >= 28 */
+-	u32 capabilities_ext;	/* 0xac  */
+-
+-	/* pll delay registers (corerev >= 4) */
+-	u32 pll_on_delay;	/* 0xb0 */
+-	u32 fref_sel_delay;
+-	u32 slow_clk_ctl;	/* 5 < corerev < 10 */
+-	u32 PAD;
+-
+-	/* Instaclock registers (corerev >= 10) */
+-	u32 system_clk_ctl;	/* 0xc0 */
+-	u32 clkstatestretch;
+-	u32 PAD[2];
+-
+-	/* Indirect backplane access (corerev >= 22) */
+-	u32 bp_addrlow;	/* 0xd0 */
+-	u32 bp_addrhigh;
+-	u32 bp_data;
+-	u32 PAD;
+-	u32 bp_indaccess;
+-	u32 PAD[3];
+-
+-	/* More clock dividers (corerev >= 32) */
+-	u32 clkdiv2;
+-	u32 PAD[2];
+-
+-	/* In AI chips, pointer to erom */
+-	u32 eromptr;		/* 0xfc */
+-
+-	/* ExtBus control registers (corerev >= 3) */
+-	u32 pcmcia_config;	/* 0x100 */
+-	u32 pcmcia_memwait;
+-	u32 pcmcia_attrwait;
+-	u32 pcmcia_iowait;
+-	u32 ide_config;
+-	u32 ide_memwait;
+-	u32 ide_attrwait;
+-	u32 ide_iowait;
+-	u32 prog_config;
+-	u32 prog_waitcount;
+-	u32 flash_config;
+-	u32 flash_waitcount;
+-	u32 SECI_config;	/* 0x130 SECI configuration */
+-	u32 PAD[3];
+-
+-	/* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */
+-	u32 eci_output;	/* 0x140 */
+-	u32 eci_control;
+-	u32 eci_inputlo;
+-	u32 eci_inputmi;
+-	u32 eci_inputhi;
+-	u32 eci_inputintpolaritylo;
+-	u32 eci_inputintpolaritymi;
+-	u32 eci_inputintpolarityhi;
+-	u32 eci_intmasklo;
+-	u32 eci_intmaskmi;
+-	u32 eci_intmaskhi;
+-	u32 eci_eventlo;
+-	u32 eci_eventmi;
+-	u32 eci_eventhi;
+-	u32 eci_eventmasklo;
+-	u32 eci_eventmaskmi;
+-	u32 eci_eventmaskhi;
+-	u32 PAD[3];
+-
+-	/* SROM interface (corerev >= 32) */
+-	u32 sromcontrol;	/* 0x190 */
+-	u32 sromaddress;
+-	u32 sromdata;
+-	u32 PAD[17];
+-
+-	/* Clock control and hardware workarounds (corerev >= 20) */
+-	u32 clk_ctl_st;	/* 0x1e0 */
+-	u32 hw_war;
+-	u32 PAD[70];
+-
+-	/* UARTs */
+-	u8 uart0data;	/* 0x300 */
+-	u8 uart0imr;
+-	u8 uart0fcr;
+-	u8 uart0lcr;
+-	u8 uart0mcr;
+-	u8 uart0lsr;
+-	u8 uart0msr;
+-	u8 uart0scratch;
+-	u8 PAD[248];		/* corerev >= 1 */
+-
+-	u8 uart1data;	/* 0x400 */
+-	u8 uart1imr;
+-	u8 uart1fcr;
+-	u8 uart1lcr;
+-	u8 uart1mcr;
+-	u8 uart1lsr;
+-	u8 uart1msr;
+-	u8 uart1scratch;
+-	u32 PAD[126];
+-
+-	/* PMU registers (corerev >= 20) */
+-	u32 pmucontrol;	/* 0x600 */
+-	u32 pmucapabilities;
+-	u32 pmustatus;
+-	u32 res_state;
+-	u32 res_pending;
+-	u32 pmutimer;
+-	u32 min_res_mask;
+-	u32 max_res_mask;
+-	u32 res_table_sel;
+-	u32 res_dep_mask;
+-	u32 res_updn_timer;
+-	u32 res_timer;
+-	u32 clkstretch;
+-	u32 pmuwatchdog;
+-	u32 gpiosel;		/* 0x638, rev >= 1 */
+-	u32 gpioenable;	/* 0x63c, rev >= 1 */
+-	u32 res_req_timer_sel;
+-	u32 res_req_timer;
+-	u32 res_req_mask;
+-	u32 PAD;
+-	u32 chipcontrol_addr;	/* 0x650 */
+-	u32 chipcontrol_data;	/* 0x654 */
+-	u32 regcontrol_addr;
+-	u32 regcontrol_data;
+-	u32 pllcontrol_addr;
+-	u32 pllcontrol_data;
+-	u32 pmustrapopt;	/* 0x668, corerev >= 28 */
+-	u32 pmu_xtalfreq;	/* 0x66C, pmurev >= 10 */
+-	u32 PAD[100];
+-	u16 sromotp[768];
+-} chipcregs_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
+-/* Selective swapped defines for those registers we need in
+- * big-endian code.
+- */
+-#define	CC_CHIPID		4
+-#define	CC_CAPABILITIES		0
+-#define	CC_CHIPST		0x28
+-#define	CC_EROMPTR		0xf8
+-
+-#else				/* !__BIG_ENDIAN || !BCMHND74K */
+-
+-#define	CC_CHIPID		0
+-#define	CC_CAPABILITIES		4
+-#define	CC_CHIPST		0x2c
+-#define	CC_EROMPTR		0xfc
+-
+-#endif				/* __BIG_ENDIAN && BCMHND74K */
+-
+-#define CC_OTPST		0x10
+-#define	CC_JTAGCMD		0x30
+-#define	CC_JTAGIR		0x34
+-#define	CC_JTAGDR		0x38
+-#define	CC_JTAGCTRL		0x3c
+-#define	CC_GPIOPU		0x58
+-#define	CC_GPIOPD		0x5c
+-#define	CC_GPIOIN		0x60
+-#define	CC_GPIOOUT		0x64
+-#define	CC_GPIOOUTEN		0x68
+-#define	CC_GPIOCTRL		0x6c
+-#define	CC_GPIOPOL		0x70
+-#define	CC_GPIOINTM		0x74
+-#define	CC_WATCHDOG		0x80
+-#define	CC_CLKC_N		0x90
+-#define	CC_CLKC_M0		0x94
+-#define	CC_CLKC_M1		0x98
+-#define	CC_CLKC_M2		0x9c
+-#define	CC_CLKC_M3		0xa0
+-#define	CC_CLKDIV		0xa4
+-#define	CC_SYS_CLK_CTL		0xc0
+-#define	CC_CLK_CTL_ST		SI_CLK_CTL_ST
+-#define	PMU_CTL			0x600
+-#define	PMU_CAP			0x604
+-#define	PMU_ST			0x608
+-#define PMU_RES_STATE		0x60c
+-#define PMU_TIMER		0x614
+-#define	PMU_MIN_RES_MASK	0x618
+-#define	PMU_MAX_RES_MASK	0x61c
+-#define CC_CHIPCTL_ADDR         0x650
+-#define CC_CHIPCTL_DATA         0x654
+-#define PMU_REG_CONTROL_ADDR	0x658
+-#define PMU_REG_CONTROL_DATA	0x65C
+-#define PMU_PLL_CONTROL_ADDR 	0x660
+-#define PMU_PLL_CONTROL_DATA 	0x664
+-#define	CC_SROM_OTP		0x800	/* SROM/OTP address space */
+-
+-/* chipid */
+-#define	CID_ID_MASK		0x0000ffff	/* Chip Id mask */
+-#define	CID_REV_MASK		0x000f0000	/* Chip Revision mask */
+-#define	CID_REV_SHIFT		16	/* Chip Revision shift */
+-#define	CID_PKG_MASK		0x00f00000	/* Package Option mask */
+-#define	CID_PKG_SHIFT		20	/* Package Option shift */
+-#define	CID_CC_MASK		0x0f000000	/* CoreCount (corerev >= 4) */
+-#define CID_CC_SHIFT		24
+-#define	CID_TYPE_MASK		0xf0000000	/* Chip Type */
+-#define CID_TYPE_SHIFT		28
+-
+-/* capabilities */
+-#define	CC_CAP_UARTS_MASK	0x00000003	/* Number of UARTs */
+-#define CC_CAP_MIPSEB		0x00000004	/* MIPS is in big-endian mode */
+-#define CC_CAP_UCLKSEL		0x00000018	/* UARTs clock select */
+-#define CC_CAP_UINTCLK		0x00000008	/* UARTs are driven by internal divided clock */
+-#define CC_CAP_UARTGPIO		0x00000020	/* UARTs own GPIOs 15:12 */
+-#define CC_CAP_EXTBUS_MASK	0x000000c0	/* External bus mask */
+-#define CC_CAP_EXTBUS_NONE	0x00000000	/* No ExtBus present */
+-#define CC_CAP_EXTBUS_FULL	0x00000040	/* ExtBus: PCMCIA, IDE & Prog */
+-#define CC_CAP_EXTBUS_PROG	0x00000080	/* ExtBus: ProgIf only */
+-#define	CC_CAP_FLASH_MASK	0x00000700	/* Type of flash */
+-#define	CC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
+-#define CC_CAP_PWR_CTL		0x00040000	/* Power control */
+-#define CC_CAP_OTPSIZE		0x00380000	/* OTP Size (0 = none) */
+-#define CC_CAP_OTPSIZE_SHIFT	19	/* OTP Size shift */
+-#define CC_CAP_OTPSIZE_BASE	5	/* OTP Size base */
+-#define CC_CAP_JTAGP		0x00400000	/* JTAG Master Present */
+-#define CC_CAP_ROM		0x00800000	/* Internal boot rom active */
+-#define CC_CAP_BKPLN64		0x08000000	/* 64-bit backplane */
+-#define	CC_CAP_PMU		0x10000000	/* PMU Present, rev >= 20 */
+-#define	CC_CAP_SROM		0x40000000	/* Srom Present, rev >= 32 */
+-#define	CC_CAP_NFLASH		0x80000000	/* Nand flash present, rev >= 35 */
+-
+-#define	CC_CAP2_SECI		0x00000001	/* SECI Present, rev >= 36 */
+-#define	CC_CAP2_GSIO		0x00000002	/* GSIO (spi/i2c) present, rev >= 37 */
+-
+-/* PLL type */
+-#define PLL_NONE		0x00000000
+-#define PLL_TYPE1		0x00010000	/* 48MHz base, 3 dividers */
+-#define PLL_TYPE2		0x00020000	/* 48MHz, 4 dividers */
+-#define PLL_TYPE3		0x00030000	/* 25MHz, 2 dividers */
+-#define PLL_TYPE4		0x00008000	/* 48MHz, 4 dividers */
+-#define PLL_TYPE5		0x00018000	/* 25MHz, 4 dividers */
+-#define PLL_TYPE6		0x00028000	/* 100/200 or 120/240 only */
+-#define PLL_TYPE7		0x00038000	/* 25MHz, 4 dividers */
+-
+-/* ILP clock */
+-#define	ILP_CLOCK		32000
+-
+-/* ALP clock on pre-PMU chips */
+-#define	ALP_CLOCK		20000000
+-
+-/* HT clock */
+-#define	HT_CLOCK		80000000
+-
+-/* corecontrol */
+-#define CC_UARTCLKO		0x00000001	/* Drive UART with internal clock */
+-#define	CC_SE			0x00000002	/* sync clk out enable (corerev >= 3) */
+-#define CC_UARTCLKEN		0x00000008	/* enable UART Clock (corerev > = 21 */
+-
+-/* chipcontrol */
+-#define CHIPCTRL_4321A0_DEFAULT	0x3a4
+-#define CHIPCTRL_4321A1_DEFAULT	0x0a4
+-#define CHIPCTRL_4321_PLL_DOWN	0x800000	/* serdes PLL down override */
+-
+-/* Fields in the otpstatus register in rev >= 21 */
+-#define OTPS_OL_MASK		0x000000ff
+-#define OTPS_OL_MFG		0x00000001	/* manuf row is locked */
+-#define OTPS_OL_OR1		0x00000002	/* otp redundancy row 1 is locked */
+-#define OTPS_OL_OR2		0x00000004	/* otp redundancy row 2 is locked */
+-#define OTPS_OL_GU		0x00000008	/* general use region is locked */
+-#define OTPS_GUP_MASK		0x00000f00
+-#define OTPS_GUP_SHIFT		8
+-#define OTPS_GUP_HW		0x00000100	/* h/w subregion is programmed */
+-#define OTPS_GUP_SW		0x00000200	/* s/w subregion is programmed */
+-#define OTPS_GUP_CI		0x00000400	/* chipid/pkgopt subregion is programmed */
+-#define OTPS_GUP_FUSE		0x00000800	/* fuse subregion is programmed */
+-#define OTPS_READY		0x00001000
+-#define OTPS_RV(x)		(1 << (16 + (x)))	/* redundancy entry valid */
+-#define OTPS_RV_MASK		0x0fff0000
+-
+-/* Fields in the otpcontrol register in rev >= 21 */
+-#define OTPC_PROGSEL		0x00000001
+-#define OTPC_PCOUNT_MASK	0x0000000e
+-#define OTPC_PCOUNT_SHIFT	1
+-#define OTPC_VSEL_MASK		0x000000f0
+-#define OTPC_VSEL_SHIFT		4
+-#define OTPC_TMM_MASK		0x00000700
+-#define OTPC_TMM_SHIFT		8
+-#define OTPC_ODM		0x00000800
+-#define OTPC_PROGEN		0x80000000
+-
+-/* Fields in otpprog in rev >= 21 and HND OTP */
+-#define OTPP_COL_MASK		0x000000ff
+-#define OTPP_COL_SHIFT		0
+-#define OTPP_ROW_MASK		0x0000ff00
+-#define OTPP_ROW_SHIFT		8
+-#define OTPP_OC_MASK		0x0f000000
+-#define OTPP_OC_SHIFT		24
+-#define OTPP_READERR		0x10000000
+-#define OTPP_VALUE_MASK		0x20000000
+-#define OTPP_VALUE_SHIFT	29
+-#define OTPP_START_BUSY		0x80000000
+-#define	OTPP_READ		0x40000000	/* HND OTP */
+-
+-/* otplayout reg corerev >= 36 */
+-#define OTP_CISFORMAT_NEW	0x80000000
+-
+-/* Opcodes for OTPP_OC field */
+-#define OTPPOC_READ		0
+-#define OTPPOC_BIT_PROG		1
+-#define OTPPOC_VERIFY		3
+-#define OTPPOC_INIT		4
+-#define OTPPOC_SET		5
+-#define OTPPOC_RESET		6
+-#define OTPPOC_OCST		7
+-#define OTPPOC_ROW_LOCK		8
+-#define OTPPOC_PRESCN_TEST	9
+-
+-/* Jtagm characteristics that appeared at a given corerev */
+-#define	JTAGM_CREV_OLD		10	/* Old command set, 16bit max IR */
+-#define	JTAGM_CREV_IRP		22	/* Able to do pause-ir */
+-#define	JTAGM_CREV_RTI		28	/* Able to do return-to-idle */
+-
+-/* jtagcmd */
+-#define JCMD_START		0x80000000
+-#define JCMD_BUSY		0x80000000
+-#define JCMD_STATE_MASK		0x60000000
+-#define JCMD_STATE_TLR		0x00000000	/* Test-logic-reset */
+-#define JCMD_STATE_PIR		0x20000000	/* Pause IR */
+-#define JCMD_STATE_PDR		0x40000000	/* Pause DR */
+-#define JCMD_STATE_RTI		0x60000000	/* Run-test-idle */
+-#define JCMD0_ACC_MASK		0x0000f000
+-#define JCMD0_ACC_IRDR		0x00000000
+-#define JCMD0_ACC_DR		0x00001000
+-#define JCMD0_ACC_IR		0x00002000
+-#define JCMD0_ACC_RESET		0x00003000
+-#define JCMD0_ACC_IRPDR		0x00004000
+-#define JCMD0_ACC_PDR		0x00005000
+-#define JCMD0_IRW_MASK		0x00000f00
+-#define JCMD_ACC_MASK		0x000f0000	/* Changes for corerev 11 */
+-#define JCMD_ACC_IRDR		0x00000000
+-#define JCMD_ACC_DR		0x00010000
+-#define JCMD_ACC_IR		0x00020000
+-#define JCMD_ACC_RESET		0x00030000
+-#define JCMD_ACC_IRPDR		0x00040000
+-#define JCMD_ACC_PDR		0x00050000
+-#define JCMD_ACC_PIR		0x00060000
+-#define JCMD_ACC_IRDR_I		0x00070000	/* rev 28: return to run-test-idle */
+-#define JCMD_ACC_DR_I		0x00080000	/* rev 28: return to run-test-idle */
+-#define JCMD_IRW_MASK		0x00001f00
+-#define JCMD_IRW_SHIFT		8
+-#define JCMD_DRW_MASK		0x0000003f
+-
+-/* jtagctrl */
+-#define JCTRL_FORCE_CLK		4	/* Force clock */
+-#define JCTRL_EXT_EN		2	/* Enable external targets */
+-#define JCTRL_EN		1	/* Enable Jtag master */
+-
+-/* Fields in clkdiv */
+-#define	CLKD_SFLASH		0x0f000000
+-#define	CLKD_SFLASH_SHIFT	24
+-#define	CLKD_OTP		0x000f0000
+-#define	CLKD_OTP_SHIFT		16
+-#define	CLKD_JTAG		0x00000f00
+-#define	CLKD_JTAG_SHIFT		8
+-#define	CLKD_UART		0x000000ff
+-
+-#define	CLKD2_SROM		0x00000003
+-
+-/* intstatus/intmask */
+-#define	CI_GPIO			0x00000001	/* gpio intr */
+-#define	CI_EI			0x00000002	/* extif intr (corerev >= 3) */
+-#define	CI_TEMP			0x00000004	/* temp. ctrl intr (corerev >= 15) */
+-#define	CI_SIRQ			0x00000008	/* serial IRQ intr (corerev >= 15) */
+-#define	CI_PMU			0x00000020	/* pmu intr (corerev >= 21) */
+-#define	CI_UART			0x00000040	/* uart intr (corerev >= 21) */
+-#define	CI_WDRESET		0x80000000	/* watchdog reset occurred */
+-
+-/* slow_clk_ctl */
+-#define SCC_SS_MASK		0x00000007	/* slow clock source mask */
+-#define	SCC_SS_LPO		0x00000000	/* source of slow clock is LPO */
+-#define	SCC_SS_XTAL		0x00000001	/* source of slow clock is crystal */
+-#define	SCC_SS_PCI		0x00000002	/* source of slow clock is PCI */
+-#define SCC_LF			0x00000200	/* LPOFreqSel, 1: 160Khz, 0: 32KHz */
+-#define SCC_LP			0x00000400	/* LPOPowerDown, 1: LPO is disabled,
+-						 * 0: LPO is enabled
+-						 */
+-#define SCC_FS			0x00000800	/* ForceSlowClk, 1: sb/cores running on slow clock,
+-						 * 0: power logic control
+-						 */
+-#define SCC_IP			0x00001000	/* IgnorePllOffReq, 1/0: power logic ignores/honors
+-						 * PLL clock disable requests from core
+-						 */
+-#define SCC_XC			0x00002000	/* XtalControlEn, 1/0: power logic does/doesn't
+-						 * disable crystal when appropriate
+-						 */
+-#define SCC_XP			0x00004000	/* XtalPU (RO), 1/0: crystal running/disabled */
+-#define SCC_CD_MASK		0xffff0000	/* ClockDivider (SlowClk = 1/(4+divisor)) */
+-#define SCC_CD_SHIFT		16
+-
+-/* system_clk_ctl */
+-#define	SYCC_IE			0x00000001	/* ILPen: Enable Idle Low Power */
+-#define	SYCC_AE			0x00000002	/* ALPen: Enable Active Low Power */
+-#define	SYCC_FP			0x00000004	/* ForcePLLOn */
+-#define	SYCC_AR			0x00000008	/* Force ALP (or HT if ALPen is not set */
+-#define	SYCC_HR			0x00000010	/* Force HT */
+-#define SYCC_CD_MASK		0xffff0000	/* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
+-#define SYCC_CD_SHIFT		16
+-
+-/* Indirect backplane access */
+-#define	BPIA_BYTEEN		0x0000000f
+-#define	BPIA_SZ1		0x00000001
+-#define	BPIA_SZ2		0x00000003
+-#define	BPIA_SZ4		0x00000007
+-#define	BPIA_SZ8		0x0000000f
+-#define	BPIA_WRITE		0x00000100
+-#define	BPIA_START		0x00000200
+-#define	BPIA_BUSY		0x00000200
+-#define	BPIA_ERROR		0x00000400
+-
+-/* pcmcia/prog/flash_config */
+-#define	CF_EN			0x00000001	/* enable */
+-#define	CF_EM_MASK		0x0000000e	/* mode */
+-#define	CF_EM_SHIFT		1
+-#define	CF_EM_FLASH		0	/* flash/asynchronous mode */
+-#define	CF_EM_SYNC		2	/* synchronous mode */
+-#define	CF_EM_PCMCIA		4	/* pcmcia mode */
+-#define	CF_DS			0x00000010	/* destsize:  0=8bit, 1=16bit */
+-#define	CF_BS			0x00000020	/* byteswap */
+-#define	CF_CD_MASK		0x000000c0	/* clock divider */
+-#define	CF_CD_SHIFT		6
+-#define	CF_CD_DIV2		0x00000000	/* backplane/2 */
+-#define	CF_CD_DIV3		0x00000040	/* backplane/3 */
+-#define	CF_CD_DIV4		0x00000080	/* backplane/4 */
+-#define	CF_CE			0x00000100	/* clock enable */
+-#define	CF_SB			0x00000200	/* size/bytestrobe (synch only) */
+-
+-/* pcmcia_memwait */
+-#define	PM_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PM_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PM_W1_SHIFT		8
+-#define	PM_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PM_W2_SHIFT		16
+-#define	PM_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PM_W3_SHIFT		24
+-
+-/* pcmcia_attrwait */
+-#define	PA_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PA_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PA_W1_SHIFT		8
+-#define	PA_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PA_W2_SHIFT		16
+-#define	PA_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PA_W3_SHIFT		24
+-
+-/* pcmcia_iowait */
+-#define	PI_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	PI_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PI_W1_SHIFT		8
+-#define	PI_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PI_W2_SHIFT		16
+-#define	PI_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PI_W3_SHIFT		24
+-
+-/* prog_waitcount */
+-#define	PW_W0_MASK		0x0000001f	/* waitcount0 */
+-#define	PW_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	PW_W1_SHIFT		8
+-#define	PW_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	PW_W2_SHIFT		16
+-#define	PW_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	PW_W3_SHIFT		24
+-
+-#define PW_W0       		0x0000000c
+-#define PW_W1       		0x00000a00
+-#define PW_W2       		0x00020000
+-#define PW_W3       		0x01000000
+-
+-/* flash_waitcount */
+-#define	FW_W0_MASK		0x0000003f	/* waitcount0 */
+-#define	FW_W1_MASK		0x00001f00	/* waitcount1 */
+-#define	FW_W1_SHIFT		8
+-#define	FW_W2_MASK		0x001f0000	/* waitcount2 */
+-#define	FW_W2_SHIFT		16
+-#define	FW_W3_MASK		0x1f000000	/* waitcount3 */
+-#define	FW_W3_SHIFT		24
+-
+-/* When Srom support present, fields in sromcontrol */
+-#define	SRC_START		0x80000000
+-#define	SRC_BUSY		0x80000000
+-#define	SRC_OPCODE		0x60000000
+-#define	SRC_OP_READ		0x00000000
+-#define	SRC_OP_WRITE		0x20000000
+-#define	SRC_OP_WRDIS		0x40000000
+-#define	SRC_OP_WREN		0x60000000
+-#define	SRC_OTPSEL		0x00000010
+-#define	SRC_LOCK		0x00000008
+-#define	SRC_SIZE_MASK		0x00000006
+-#define	SRC_SIZE_1K		0x00000000
+-#define	SRC_SIZE_4K		0x00000002
+-#define	SRC_SIZE_16K		0x00000004
+-#define	SRC_SIZE_SHIFT		1
+-#define	SRC_PRESENT		0x00000001
+-
+-/* Fields in pmucontrol */
+-#define	PCTL_ILP_DIV_MASK	0xffff0000
+-#define	PCTL_ILP_DIV_SHIFT	16
+-#define PCTL_PLL_PLLCTL_UPD	0x00000400	/* rev 2 */
+-#define PCTL_NOILP_ON_WAIT	0x00000200	/* rev 1 */
+-#define	PCTL_HT_REQ_EN		0x00000100
+-#define	PCTL_ALP_REQ_EN		0x00000080
+-#define	PCTL_XTALFREQ_MASK	0x0000007c
+-#define	PCTL_XTALFREQ_SHIFT	2
+-#define	PCTL_ILP_DIV_EN		0x00000002
+-#define	PCTL_LPO_SEL		0x00000001
+-
+-/* Fields in clkstretch */
+-#define CSTRETCH_HT		0xffff0000
+-#define CSTRETCH_ALP		0x0000ffff
+-
+-/* gpiotimerval */
+-#define GPIO_ONTIME_SHIFT	16
+-
+-/* clockcontrol_n */
+-#define	CN_N1_MASK		0x3f	/* n1 control */
+-#define	CN_N2_MASK		0x3f00	/* n2 control */
+-#define	CN_N2_SHIFT		8
+-#define	CN_PLLC_MASK		0xf0000	/* pll control */
+-#define	CN_PLLC_SHIFT		16
+-
+-/* clockcontrol_sb/pci/uart */
+-#define	CC_M1_MASK		0x3f	/* m1 control */
+-#define	CC_M2_MASK		0x3f00	/* m2 control */
+-#define	CC_M2_SHIFT		8
+-#define	CC_M3_MASK		0x3f0000	/* m3 control */
+-#define	CC_M3_SHIFT		16
+-#define	CC_MC_MASK		0x1f000000	/* mux control */
+-#define	CC_MC_SHIFT		24
+-
+-/* N3M Clock control magic field values */
+-#define	CC_F6_2			0x02	/* A factor of 2 in */
+-#define	CC_F6_3			0x03	/* 6-bit fields like */
+-#define	CC_F6_4			0x05	/* N1, M1 or M3 */
+-#define	CC_F6_5			0x09
+-#define	CC_F6_6			0x11
+-#define	CC_F6_7			0x21
+-
+-#define	CC_F5_BIAS		5	/* 5-bit fields get this added */
+-
+-#define	CC_MC_BYPASS		0x08
+-#define	CC_MC_M1		0x04
+-#define	CC_MC_M1M2		0x02
+-#define	CC_MC_M1M2M3		0x01
+-#define	CC_MC_M1M3		0x11
+-
+-/* Type 2 Clock control magic field values */
+-#define	CC_T2_BIAS		2	/* n1, n2, m1 & m3 bias */
+-#define	CC_T2M2_BIAS		3	/* m2 bias */
+-
+-#define	CC_T2MC_M1BYP		1
+-#define	CC_T2MC_M2BYP		2
+-#define	CC_T2MC_M3BYP		4
+-
+-/* Type 6 Clock control magic field values */
+-#define	CC_T6_MMASK		1	/* bits of interest in m */
+-#define	CC_T6_M0		120000000	/* sb clock for m = 0 */
+-#define	CC_T6_M1		100000000	/* sb clock for m = 1 */
+-#define	SB2MIPS_T6(sb)		(2 * (sb))
+-
+-/* Common clock base */
+-#define	CC_CLOCK_BASE1		24000000	/* Half the clock freq */
+-#define CC_CLOCK_BASE2		12500000	/* Alternate crystal on some PLLs */
+-
+-/* Clock control values for 200MHz in 5350 */
+-#define	CLKC_5350_N		0x0311
+-#define	CLKC_5350_M		0x04020009
+-
+-/* Flash types in the chipcommon capabilities register */
+-#define FLASH_NONE		0x000	/* No flash */
+-#define SFLASH_ST		0x100	/* ST serial flash */
+-#define SFLASH_AT		0x200	/* Atmel serial flash */
+-#define	PFLASH			0x700	/* Parallel flash */
+-
+-/* Bits in the ExtBus config registers */
+-#define	CC_CFG_EN		0x0001	/* Enable */
+-#define	CC_CFG_EM_MASK		0x000e	/* Extif Mode */
+-#define	CC_CFG_EM_ASYNC		0x0000	/*   Async/Parallel flash */
+-#define	CC_CFG_EM_SYNC		0x0002	/*   Synchronous */
+-#define	CC_CFG_EM_PCMCIA	0x0004	/*   PCMCIA */
+-#define	CC_CFG_EM_IDE		0x0006	/*   IDE */
+-#define	CC_CFG_DS		0x0010	/* Data size, 0=8bit, 1=16bit */
+-#define	CC_CFG_CD_MASK		0x00e0	/* Sync: Clock divisor, rev >= 20 */
+-#define	CC_CFG_CE		0x0100	/* Sync: Clock enable, rev >= 20 */
+-#define	CC_CFG_SB		0x0200	/* Sync: Size/Bytestrobe, rev >= 20 */
+-#define	CC_CFG_IS		0x0400	/* Extif Sync Clk Select, rev >= 20 */
+-
+-/* ExtBus address space */
+-#define	CC_EB_BASE		0x1a000000	/* Chipc ExtBus base address */
+-#define	CC_EB_PCMCIA_MEM	0x1a000000	/* PCMCIA 0 memory base address */
+-#define	CC_EB_PCMCIA_IO		0x1a200000	/* PCMCIA 0 I/O base address */
+-#define	CC_EB_PCMCIA_CFG	0x1a400000	/* PCMCIA 0 config base address */
+-#define	CC_EB_IDE		0x1a800000	/* IDE memory base */
+-#define	CC_EB_PCMCIA1_MEM	0x1a800000	/* PCMCIA 1 memory base address */
+-#define	CC_EB_PCMCIA1_IO	0x1aa00000	/* PCMCIA 1 I/O base address */
+-#define	CC_EB_PCMCIA1_CFG	0x1ac00000	/* PCMCIA 1 config base address */
+-#define	CC_EB_PROGIF		0x1b000000	/* ProgIF Async/Sync base address */
+-
+-/* Start/busy bit in flashcontrol */
+-#define SFLASH_OPCODE		0x000000ff
+-#define SFLASH_ACTION		0x00000700
+-#define	SFLASH_CS_ACTIVE	0x00001000	/* Chip Select Active, rev >= 20 */
+-#define SFLASH_START		0x80000000
+-#define SFLASH_BUSY		SFLASH_START
+-
+-/* flashcontrol action codes */
+-#define	SFLASH_ACT_OPONLY	0x0000	/* Issue opcode only */
+-#define	SFLASH_ACT_OP1D		0x0100	/* opcode + 1 data byte */
+-#define	SFLASH_ACT_OP3A		0x0200	/* opcode + 3 addr bytes */
+-#define	SFLASH_ACT_OP3A1D	0x0300	/* opcode + 3 addr & 1 data bytes */
+-#define	SFLASH_ACT_OP3A4D	0x0400	/* opcode + 3 addr & 4 data bytes */
+-#define	SFLASH_ACT_OP3A4X4D	0x0500	/* opcode + 3 addr, 4 don't care & 4 data bytes */
+-#define	SFLASH_ACT_OP3A1X4D	0x0700	/* opcode + 3 addr, 1 don't care & 4 data bytes */
+-
+-/* flashcontrol action+opcodes for ST flashes */
+-#define SFLASH_ST_WREN		0x0006	/* Write Enable */
+-#define SFLASH_ST_WRDIS		0x0004	/* Write Disable */
+-#define SFLASH_ST_RDSR		0x0105	/* Read Status Register */
+-#define SFLASH_ST_WRSR		0x0101	/* Write Status Register */
+-#define SFLASH_ST_READ		0x0303	/* Read Data Bytes */
+-#define SFLASH_ST_PP		0x0302	/* Page Program */
+-#define SFLASH_ST_SE		0x02d8	/* Sector Erase */
+-#define SFLASH_ST_BE		0x00c7	/* Bulk Erase */
+-#define SFLASH_ST_DP		0x00b9	/* Deep Power-down */
+-#define SFLASH_ST_RES		0x03ab	/* Read Electronic Signature */
+-#define SFLASH_ST_CSA		0x1000	/* Keep chip select asserted */
+-#define SFLASH_ST_SSE		0x0220	/* Sub-sector Erase */
+-
+-/* Status register bits for ST flashes */
+-#define SFLASH_ST_WIP		0x01	/* Write In Progress */
+-#define SFLASH_ST_WEL		0x02	/* Write Enable Latch */
+-#define SFLASH_ST_BP_MASK	0x1c	/* Block Protect */
+-#define SFLASH_ST_BP_SHIFT	2
+-#define SFLASH_ST_SRWD		0x80	/* Status Register Write Disable */
+-
+-/* flashcontrol action+opcodes for Atmel flashes */
+-#define SFLASH_AT_READ				0x07e8
+-#define SFLASH_AT_PAGE_READ			0x07d2
+-#define SFLASH_AT_BUF1_READ
+-#define SFLASH_AT_BUF2_READ
+-#define SFLASH_AT_STATUS			0x01d7
+-#define SFLASH_AT_BUF1_WRITE			0x0384
+-#define SFLASH_AT_BUF2_WRITE			0x0387
+-#define SFLASH_AT_BUF1_ERASE_PROGRAM		0x0283
+-#define SFLASH_AT_BUF2_ERASE_PROGRAM		0x0286
+-#define SFLASH_AT_BUF1_PROGRAM			0x0288
+-#define SFLASH_AT_BUF2_PROGRAM			0x0289
+-#define SFLASH_AT_PAGE_ERASE			0x0281
+-#define SFLASH_AT_BLOCK_ERASE			0x0250
+-#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM	0x0382
+-#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM	0x0385
+-#define SFLASH_AT_BUF1_LOAD			0x0253
+-#define SFLASH_AT_BUF2_LOAD			0x0255
+-#define SFLASH_AT_BUF1_COMPARE			0x0260
+-#define SFLASH_AT_BUF2_COMPARE			0x0261
+-#define SFLASH_AT_BUF1_REPROGRAM		0x0258
+-#define SFLASH_AT_BUF2_REPROGRAM		0x0259
+-
+-/* Status register bits for Atmel flashes */
+-#define SFLASH_AT_READY				0x80
+-#define SFLASH_AT_MISMATCH			0x40
+-#define SFLASH_AT_ID_MASK			0x38
+-#define SFLASH_AT_ID_SHIFT			3
+-
+-/*
+- * These are the UART port assignments, expressed as offsets from the base
+- * register.  These assignments should hold for any serial port based on
+- * a 8250, 16450, or 16550(A).
+- */
+-
+-#define UART_RX		0	/* In:  Receive buffer (DLAB=0) */
+-#define UART_TX		0	/* Out: Transmit buffer (DLAB=0) */
+-#define UART_DLL	0	/* Out: Divisor Latch Low (DLAB=1) */
+-#define UART_IER	1	/* In/Out: Interrupt Enable Register (DLAB=0) */
+-#define UART_DLM	1	/* Out: Divisor Latch High (DLAB=1) */
+-#define UART_IIR	2	/* In: Interrupt Identity Register  */
+-#define UART_FCR	2	/* Out: FIFO Control Register */
+-#define UART_LCR	3	/* Out: Line Control Register */
+-#define UART_MCR	4	/* Out: Modem Control Register */
+-#define UART_LSR	5	/* In:  Line Status Register */
+-#define UART_MSR	6	/* In:  Modem Status Register */
+-#define UART_SCR	7	/* I/O: Scratch Register */
+-#define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
+-#define UART_LCR_WLEN8	0x03	/* Word length: 8 bits */
+-#define UART_MCR_OUT2	0x08	/* MCR GPIO out 2 */
+-#define UART_MCR_LOOP	0x10	/* Enable loopback test mode */
+-#define UART_LSR_RX_FIFO 	0x80	/* Receive FIFO error */
+-#define UART_LSR_TDHR		0x40	/* Data-hold-register empty */
+-#define UART_LSR_THRE		0x20	/* Transmit-hold-register empty */
+-#define UART_LSR_BREAK		0x10	/* Break interrupt */
+-#define UART_LSR_FRAMING	0x08	/* Framing error */
+-#define UART_LSR_PARITY		0x04	/* Parity error */
+-#define UART_LSR_OVERRUN	0x02	/* Overrun error */
+-#define UART_LSR_RXRDY		0x01	/* Receiver ready */
+-#define UART_FCR_FIFO_ENABLE 1	/* FIFO control register bit controlling FIFO enable/disable */
+-
+-/* Interrupt Identity Register (IIR) bits */
+-#define UART_IIR_FIFO_MASK	0xc0	/* IIR FIFO disable/enabled mask */
+-#define UART_IIR_INT_MASK	0xf	/* IIR interrupt ID source */
+-#define UART_IIR_MDM_CHG	0x0	/* Modem status changed */
+-#define UART_IIR_NOINT		0x1	/* No interrupt pending */
+-#define UART_IIR_THRE		0x2	/* THR empty */
+-#define UART_IIR_RCVD_DATA	0x4	/* Received data available */
+-#define UART_IIR_RCVR_STATUS 	0x6	/* Receiver status */
+-#define UART_IIR_CHAR_TIME 	0xc	/* Character time */
+-
+-/* Interrupt Enable Register (IER) bits */
+-#define UART_IER_EDSSI	8	/* enable modem status interrupt */
+-#define UART_IER_ELSI	4	/* enable receiver line status interrupt */
+-#define UART_IER_ETBEI  2	/* enable transmitter holding register empty interrupt */
+-#define UART_IER_ERBFI	1	/* enable data available interrupt */
+-
+-/* pmustatus */
+-#define PST_EXTLPOAVAIL	0x0100
+-#define PST_WDRESET	0x0080
+-#define	PST_INTPEND	0x0040
+-#define	PST_SBCLKST	0x0030
+-#define	PST_SBCLKST_ILP	0x0010
+-#define	PST_SBCLKST_ALP	0x0020
+-#define	PST_SBCLKST_HT	0x0030
+-#define	PST_ALPAVAIL	0x0008
+-#define	PST_HTAVAIL	0x0004
+-#define	PST_RESINIT	0x0003
+-
+-/* pmucapabilities */
+-#define PCAP_REV_MASK	0x000000ff
+-#define PCAP_RC_MASK	0x00001f00
+-#define PCAP_RC_SHIFT	8
+-#define PCAP_TC_MASK	0x0001e000
+-#define PCAP_TC_SHIFT	13
+-#define PCAP_PC_MASK	0x001e0000
+-#define PCAP_PC_SHIFT	17
+-#define PCAP_VC_MASK	0x01e00000
+-#define PCAP_VC_SHIFT	21
+-#define PCAP_CC_MASK	0x1e000000
+-#define PCAP_CC_SHIFT	25
+-#define PCAP5_PC_MASK	0x003e0000	/* PMU corerev >= 5 */
+-#define PCAP5_PC_SHIFT	17
+-#define PCAP5_VC_MASK	0x07c00000
+-#define PCAP5_VC_SHIFT	22
+-#define PCAP5_CC_MASK	0xf8000000
+-#define PCAP5_CC_SHIFT	27
+-
+-/* PMU Resource Request Timer registers */
+-/* This is based on PmuRev0 */
+-#define	PRRT_TIME_MASK	0x03ff
+-#define	PRRT_INTEN	0x0400
+-#define	PRRT_REQ_ACTIVE	0x0800
+-#define	PRRT_ALP_REQ	0x1000
+-#define	PRRT_HT_REQ	0x2000
+-
+-/* PMU resource bit position */
+-#define PMURES_BIT(bit)	(1 << (bit))
+-
+-/* PMU resource number limit */
+-#define PMURES_MAX_RESNUM	30
+-
+-/* PMU chip control0 register */
+-#define	PMU_CHIPCTL0		0
+-
+-/* PMU chip control1 register */
+-#define	PMU_CHIPCTL1			1
+-#define	PMU_CC1_RXC_DLL_BYPASS		0x00010000
+-
+-#define PMU_CC1_IF_TYPE_MASK   		0x00000030
+-#define PMU_CC1_IF_TYPE_RMII    	0x00000000
+-#define PMU_CC1_IF_TYPE_MII     	0x00000010
+-#define PMU_CC1_IF_TYPE_RGMII   	0x00000020
+-
+-#define PMU_CC1_SW_TYPE_MASK    	0x000000c0
+-#define PMU_CC1_SW_TYPE_EPHY    	0x00000000
+-#define PMU_CC1_SW_TYPE_EPHYMII 	0x00000040
+-#define PMU_CC1_SW_TYPE_EPHYRMII	0x00000080
+-#define PMU_CC1_SW_TYPE_RGMII   	0x000000c0
+-
+-/* PMU corerev and chip specific PLL controls.
+- * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
+- * to differentiate different PLLs controlled by the same PMU rev.
+- */
+-/* pllcontrol registers */
+-/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
+-#define	PMU0_PLL0_PLLCTL0		0
+-#define	PMU0_PLL0_PC0_PDIV_MASK		1
+-#define	PMU0_PLL0_PC0_PDIV_FREQ		25000
+-#define PMU0_PLL0_PC0_DIV_ARM_MASK	0x00000038
+-#define PMU0_PLL0_PC0_DIV_ARM_SHIFT	3
+-#define PMU0_PLL0_PC0_DIV_ARM_BASE	8
+-
+-/* PC0_DIV_ARM for PLLOUT_ARM */
+-#define PMU0_PLL0_PC0_DIV_ARM_110MHZ	0
+-#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ	1
+-#define PMU0_PLL0_PC0_DIV_ARM_88MHZ	2
+-#define PMU0_PLL0_PC0_DIV_ARM_80MHZ	3	/* Default */
+-#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ	4
+-#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ	5
+-#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ	6
+-#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ	7
+-
+-/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
+-#define	PMU0_PLL0_PLLCTL1		1
+-#define	PMU0_PLL0_PC1_WILD_INT_MASK	0xf0000000
+-#define	PMU0_PLL0_PC1_WILD_INT_SHIFT	28
+-#define	PMU0_PLL0_PC1_WILD_FRAC_MASK	0x0fffff00
+-#define	PMU0_PLL0_PC1_WILD_FRAC_SHIFT	8
+-#define	PMU0_PLL0_PC1_STOP_MOD		0x00000040
+-
+-/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
+-#define	PMU0_PLL0_PLLCTL2		2
+-#define	PMU0_PLL0_PC2_WILD_INT_MASK	0xf
+-#define	PMU0_PLL0_PC2_WILD_INT_SHIFT	4
+-
+-/* pllcontrol registers */
+-/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+-#define PMU1_PLL0_PLLCTL0		0
+-#define PMU1_PLL0_PC0_P1DIV_MASK	0x00f00000
+-#define PMU1_PLL0_PC0_P1DIV_SHIFT	20
+-#define PMU1_PLL0_PC0_P2DIV_MASK	0x0f000000
+-#define PMU1_PLL0_PC0_P2DIV_SHIFT	24
+-
+-/* m<x>div */
+-#define PMU1_PLL0_PLLCTL1		1
+-#define PMU1_PLL0_PC1_M1DIV_MASK	0x000000ff
+-#define PMU1_PLL0_PC1_M1DIV_SHIFT	0
+-#define PMU1_PLL0_PC1_M2DIV_MASK	0x0000ff00
+-#define PMU1_PLL0_PC1_M2DIV_SHIFT	8
+-#define PMU1_PLL0_PC1_M3DIV_MASK	0x00ff0000
+-#define PMU1_PLL0_PC1_M3DIV_SHIFT	16
+-#define PMU1_PLL0_PC1_M4DIV_MASK	0xff000000
+-#define PMU1_PLL0_PC1_M4DIV_SHIFT	24
+-
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+-#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL  (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
+-
+-/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+-#define PMU1_PLL0_PLLCTL2		2
+-#define PMU1_PLL0_PC2_M5DIV_MASK	0x000000ff
+-#define PMU1_PLL0_PC2_M5DIV_SHIFT	0
+-#define PMU1_PLL0_PC2_M6DIV_MASK	0x0000ff00
+-#define PMU1_PLL0_PC2_M6DIV_SHIFT	8
+-#define PMU1_PLL0_PC2_NDIV_MODE_MASK	0x000e0000
+-#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT	17
+-#define PMU1_PLL0_PC2_NDIV_MODE_MASH	1
+-#define PMU1_PLL0_PC2_NDIV_MODE_MFB	2	/* recommended for 4319 */
+-#define PMU1_PLL0_PC2_NDIV_INT_MASK	0x1ff00000
+-#define PMU1_PLL0_PC2_NDIV_INT_SHIFT	20
+-
+-/* ndiv_frac */
+-#define PMU1_PLL0_PLLCTL3		3
+-#define PMU1_PLL0_PC3_NDIV_FRAC_MASK	0x00ffffff
+-#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT	0
+-
+-/* pll_ctrl */
+-#define PMU1_PLL0_PLLCTL4		4
+-
+-/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+-#define PMU1_PLL0_PLLCTL5		5
+-#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
+-#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
+-
+-/* PMU rev 2 control words */
+-#define PMU2_PHY_PLL_PLLCTL		4
+-#define PMU2_SI_PLL_PLLCTL		10
+-
+-/* PMU rev 2 */
+-/* pllcontrol registers */
+-/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
+-#define PMU2_PLL_PLLCTL0		0
+-#define PMU2_PLL_PC0_P1DIV_MASK 	0x00f00000
+-#define PMU2_PLL_PC0_P1DIV_SHIFT	20
+-#define PMU2_PLL_PC0_P2DIV_MASK 	0x0f000000
+-#define PMU2_PLL_PC0_P2DIV_SHIFT	24
+-
+-/* m<x>div */
+-#define PMU2_PLL_PLLCTL1		1
+-#define PMU2_PLL_PC1_M1DIV_MASK 	0x000000ff
+-#define PMU2_PLL_PC1_M1DIV_SHIFT	0
+-#define PMU2_PLL_PC1_M2DIV_MASK 	0x0000ff00
+-#define PMU2_PLL_PC1_M2DIV_SHIFT	8
+-#define PMU2_PLL_PC1_M3DIV_MASK 	0x00ff0000
+-#define PMU2_PLL_PC1_M3DIV_SHIFT	16
+-#define PMU2_PLL_PC1_M4DIV_MASK 	0xff000000
+-#define PMU2_PLL_PC1_M4DIV_SHIFT	24
+-
+-/* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
+-#define PMU2_PLL_PLLCTL2		2
+-#define PMU2_PLL_PC2_M5DIV_MASK 	0x000000ff
+-#define PMU2_PLL_PC2_M5DIV_SHIFT	0
+-#define PMU2_PLL_PC2_M6DIV_MASK 	0x0000ff00
+-#define PMU2_PLL_PC2_M6DIV_SHIFT	8
+-#define PMU2_PLL_PC2_NDIV_MODE_MASK	0x000e0000
+-#define PMU2_PLL_PC2_NDIV_MODE_SHIFT	17
+-#define PMU2_PLL_PC2_NDIV_INT_MASK	0x1ff00000
+-#define PMU2_PLL_PC2_NDIV_INT_SHIFT	20
+-
+-/* ndiv_frac */
+-#define PMU2_PLL_PLLCTL3		3
+-#define PMU2_PLL_PC3_NDIV_FRAC_MASK	0x00ffffff
+-#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT	0
+-
+-/* pll_ctrl */
+-#define PMU2_PLL_PLLCTL4		4
+-
+-/* pll_ctrl, vco_rng, clkdrive_ch<x> */
+-#define PMU2_PLL_PLLCTL5		5
+-#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK	0x00000f00
+-#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT	8
+-#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK	0x0000f000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT	12
+-#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK	0x000f0000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT	16
+-#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK	0x00f00000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT	20
+-#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK	0x0f000000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT	24
+-#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK	0xf0000000
+-#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT	28
+-
+-/* PMU rev 5 (& 6) */
+-#define	PMU5_PLL_P1P2_OFF		0
+-#define	PMU5_PLL_P1_MASK		0x0f000000
+-#define	PMU5_PLL_P1_SHIFT		24
+-#define	PMU5_PLL_P2_MASK		0x00f00000
+-#define	PMU5_PLL_P2_SHIFT		20
+-#define	PMU5_PLL_M14_OFF		1
+-#define	PMU5_PLL_MDIV_MASK		0x000000ff
+-#define	PMU5_PLL_MDIV_WIDTH		8
+-#define	PMU5_PLL_NM5_OFF		2
+-#define	PMU5_PLL_NDIV_MASK		0xfff00000
+-#define	PMU5_PLL_NDIV_SHIFT		20
+-#define	PMU5_PLL_NDIV_MODE_MASK		0x000e0000
+-#define	PMU5_PLL_NDIV_MODE_SHIFT	17
+-#define	PMU5_PLL_FMAB_OFF		3
+-#define	PMU5_PLL_MRAT_MASK		0xf0000000
+-#define	PMU5_PLL_MRAT_SHIFT		28
+-#define	PMU5_PLL_ABRAT_MASK		0x08000000
+-#define	PMU5_PLL_ABRAT_SHIFT		27
+-#define	PMU5_PLL_FDIV_MASK		0x07ffffff
+-#define	PMU5_PLL_PLLCTL_OFF		4
+-#define	PMU5_PLL_PCHI_OFF		5
+-#define	PMU5_PLL_PCHI_MASK		0x0000003f
+-
+-/* pmu XtalFreqRatio */
+-#define	PMU_XTALFREQ_REG_ILPCTR_MASK	0x00001FFF
+-#define	PMU_XTALFREQ_REG_MEASURE_MASK	0x80000000
+-#define	PMU_XTALFREQ_REG_MEASURE_SHIFT	31
+-
+-/* Divider allocation in 4716/47162/5356/5357 */
+-#define	PMU5_MAINPLL_CPU		1
+-#define	PMU5_MAINPLL_MEM		2
+-#define	PMU5_MAINPLL_SI			3
+-
+-#define PMU7_PLL_PLLCTL7                7
+-#define PMU7_PLL_PLLCTL8                8
+-#define PMU7_PLL_PLLCTL11		11
+-
+-/* PLL usage in 4716/47162 */
+-#define	PMU4716_MAINPLL_PLL0		12
+-
+-/* PLL usage in 5356/5357 */
+-#define	PMU5356_MAINPLL_PLL0		0
+-#define	PMU5357_MAINPLL_PLL0		0
+-
+-/* 4716/47162 resources */
+-#define RES4716_PROC_PLL_ON		0x00000040
+-#define RES4716_PROC_HT_AVAIL		0x00000080
+-
+-/* 4716/4717/4718 Chip specific ChipControl register bits */
+-#define CCTRL471X_I2S_PINS_ENABLE          0x0080	/* I2S pins off by default, shared with pflash */
+-
+-/* 5354 resources */
+-#define RES5354_EXT_SWITCHER_PWM	0	/* 0x00001 */
+-#define RES5354_BB_SWITCHER_PWM		1	/* 0x00002 */
+-#define RES5354_BB_SWITCHER_BURST	2	/* 0x00004 */
+-#define RES5354_BB_EXT_SWITCHER_BURST	3	/* 0x00008 */
+-#define RES5354_ILP_REQUEST		4	/* 0x00010 */
+-#define RES5354_RADIO_SWITCHER_PWM	5	/* 0x00020 */
+-#define RES5354_RADIO_SWITCHER_BURST	6	/* 0x00040 */
+-#define RES5354_ROM_SWITCH		7	/* 0x00080 */
+-#define RES5354_PA_REF_LDO		8	/* 0x00100 */
+-#define RES5354_RADIO_LDO		9	/* 0x00200 */
+-#define RES5354_AFE_LDO			10	/* 0x00400 */
+-#define RES5354_PLL_LDO			11	/* 0x00800 */
+-#define RES5354_BG_FILTBYP		12	/* 0x01000 */
+-#define RES5354_TX_FILTBYP		13	/* 0x02000 */
+-#define RES5354_RX_FILTBYP		14	/* 0x04000 */
+-#define RES5354_XTAL_PU			15	/* 0x08000 */
+-#define RES5354_XTAL_EN			16	/* 0x10000 */
+-#define RES5354_BB_PLL_FILTBYP		17	/* 0x20000 */
+-#define RES5354_RF_PLL_FILTBYP		18	/* 0x40000 */
+-#define RES5354_BB_PLL_PU		19	/* 0x80000 */
+-
+-/* 5357 Chip specific ChipControl register bits */
+-#define CCTRL5357_EXTPA                 (1<<14)	/* extPA in ChipControl 1, bit 14 */
+-#define CCTRL5357_ANT_MUX_2o3		(1<<15)	/* 2o3 in ChipControl 1, bit 15 */
+-
+-/* 4328 resources */
+-#define RES4328_EXT_SWITCHER_PWM	0	/* 0x00001 */
+-#define RES4328_BB_SWITCHER_PWM		1	/* 0x00002 */
+-#define RES4328_BB_SWITCHER_BURST	2	/* 0x00004 */
+-#define RES4328_BB_EXT_SWITCHER_BURST	3	/* 0x00008 */
+-#define RES4328_ILP_REQUEST		4	/* 0x00010 */
+-#define RES4328_RADIO_SWITCHER_PWM	5	/* 0x00020 */
+-#define RES4328_RADIO_SWITCHER_BURST	6	/* 0x00040 */
+-#define RES4328_ROM_SWITCH		7	/* 0x00080 */
+-#define RES4328_PA_REF_LDO		8	/* 0x00100 */
+-#define RES4328_RADIO_LDO		9	/* 0x00200 */
+-#define RES4328_AFE_LDO			10	/* 0x00400 */
+-#define RES4328_PLL_LDO			11	/* 0x00800 */
+-#define RES4328_BG_FILTBYP		12	/* 0x01000 */
+-#define RES4328_TX_FILTBYP		13	/* 0x02000 */
+-#define RES4328_RX_FILTBYP		14	/* 0x04000 */
+-#define RES4328_XTAL_PU			15	/* 0x08000 */
+-#define RES4328_XTAL_EN			16	/* 0x10000 */
+-#define RES4328_BB_PLL_FILTBYP		17	/* 0x20000 */
+-#define RES4328_RF_PLL_FILTBYP		18	/* 0x40000 */
+-#define RES4328_BB_PLL_PU		19	/* 0x80000 */
+-
+-/* 4325 A0/A1 resources */
+-#define RES4325_BUCK_BOOST_BURST	0	/* 0x00000001 */
+-#define RES4325_CBUCK_BURST		1	/* 0x00000002 */
+-#define RES4325_CBUCK_PWM		2	/* 0x00000004 */
+-#define RES4325_CLDO_CBUCK_BURST	3	/* 0x00000008 */
+-#define RES4325_CLDO_CBUCK_PWM		4	/* 0x00000010 */
+-#define RES4325_BUCK_BOOST_PWM		5	/* 0x00000020 */
+-#define RES4325_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4325_ABUCK_BURST		7	/* 0x00000080 */
+-#define RES4325_ABUCK_PWM		8	/* 0x00000100 */
+-#define RES4325_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4325_OTP_PU			10	/* 0x00000400 */
+-#define RES4325_LNLDO3_PU		11	/* 0x00000800 */
+-#define RES4325_LNLDO4_PU		12	/* 0x00001000 */
+-#define RES4325_XTAL_PU			13	/* 0x00002000 */
+-#define RES4325_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4325_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4325_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4325_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4325_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4325_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4325_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4325_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4325 B0/C0 resources */
+-#define RES4325B0_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4325B0_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4325B0_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4325B0_CLDO_PU		4	/* 0x00000010 */
+-
+-/* 4325 C1 resources */
+-#define RES4325C1_LNLDO2_PU		12	/* 0x00001000 */
+-
+-/* 4325 chip-specific ChipStatus register bits */
+-#define CST4325_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4325_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4325_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4325_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4325_OTP_PWRDN		3	/* OTP is powered down, SPROM is present */
+-#define CST4325_SDIO_USB_MODE_MASK	0x00000004
+-#define CST4325_SDIO_USB_MODE_SHIFT	2
+-#define CST4325_RCAL_VALID_MASK		0x00000008
+-#define CST4325_RCAL_VALID_SHIFT	3
+-#define CST4325_RCAL_VALUE_MASK		0x000001f0
+-#define CST4325_RCAL_VALUE_SHIFT	4
+-#define CST4325_PMUTOP_2B_MASK 		0x00000200	/* 1 for 2b, 0 for to 2a */
+-#define CST4325_PMUTOP_2B_SHIFT   	9
+-
+-#define RES4329_RESERVED0		0	/* 0x00000001 */
+-#define RES4329_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4329_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4329_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4329_CLDO_PU			4	/* 0x00000010 */
+-#define RES4329_PALDO_PU		5	/* 0x00000020 */
+-#define RES4329_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4329_RESERVED7		7	/* 0x00000080 */
+-#define RES4329_RESERVED8		8	/* 0x00000100 */
+-#define RES4329_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4329_OTP_PU			10	/* 0x00000400 */
+-#define RES4329_RESERVED11		11	/* 0x00000800 */
+-#define RES4329_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4329_XTAL_PU			13	/* 0x00002000 */
+-#define RES4329_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4329_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4329_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4329_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4329_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4329_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4329_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4329_HT_AVAIL		21	/* 0x00200000 */
+-
+-#define CST4329_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4329_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4329_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4329_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4329_OTP_PWRDN		3	/* OTP is powered down, SPROM is present */
+-#define CST4329_SPI_SDIO_MODE_MASK	0x00000004
+-#define CST4329_SPI_SDIO_MODE_SHIFT	2
+-
+-/* 4312 chip-specific ChipStatus register bits */
+-#define CST4312_SPROM_OTP_SEL_MASK	0x00000003
+-#define CST4312_DEFCIS_SEL		0	/* OTP is powered up, use def. CIS, no SPROM */
+-#define CST4312_SPROM_SEL		1	/* OTP is powered up, SPROM is present */
+-#define CST4312_OTP_SEL			2	/* OTP is powered up, no SPROM */
+-#define CST4312_OTP_BAD			3	/* OTP is broken, SPROM is present */
+-
+-/* 4312 resources (all PMU chips with little memory constraint) */
+-#define RES4312_SWITCHER_BURST		0	/* 0x00000001 */
+-#define RES4312_SWITCHER_PWM    	1	/* 0x00000002 */
+-#define RES4312_PA_REF_LDO		2	/* 0x00000004 */
+-#define RES4312_CORE_LDO_BURST		3	/* 0x00000008 */
+-#define RES4312_CORE_LDO_PWM		4	/* 0x00000010 */
+-#define RES4312_RADIO_LDO		5	/* 0x00000020 */
+-#define RES4312_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4312_BG_FILTBYP		7	/* 0x00000080 */
+-#define RES4312_TX_FILTBYP		8	/* 0x00000100 */
+-#define RES4312_RX_FILTBYP		9	/* 0x00000200 */
+-#define RES4312_XTAL_PU			10	/* 0x00000400 */
+-#define RES4312_ALP_AVAIL		11	/* 0x00000800 */
+-#define RES4312_BB_PLL_FILTBYP		12	/* 0x00001000 */
+-#define RES4312_RF_PLL_FILTBYP		13	/* 0x00002000 */
+-#define RES4312_HT_AVAIL		14	/* 0x00004000 */
+-
+-/* 4322 resources */
+-#define RES4322_RF_LDO			0
+-#define RES4322_ILP_REQUEST		1
+-#define RES4322_XTAL_PU			2
+-#define RES4322_ALP_AVAIL		3
+-#define RES4322_SI_PLL_ON		4
+-#define RES4322_HT_SI_AVAIL		5
+-#define RES4322_PHY_PLL_ON		6
+-#define RES4322_HT_PHY_AVAIL		7
+-#define RES4322_OTP_PU			8
+-
+-/* 4322 chip-specific ChipStatus register bits */
+-#define CST4322_XTAL_FREQ_20_40MHZ	0x00000020
+-#define CST4322_SPROM_OTP_SEL_MASK	0x000000c0
+-#define CST4322_SPROM_OTP_SEL_SHIFT	6
+-#define CST4322_NO_SPROM_OTP		0	/* no OTP, no SPROM */
+-#define CST4322_SPROM_PRESENT		1	/* SPROM is present */
+-#define CST4322_OTP_PRESENT		2	/* OTP is present */
+-#define CST4322_PCI_OR_USB		0x00000100
+-#define CST4322_BOOT_MASK		0x00000600
+-#define CST4322_BOOT_SHIFT		9
+-#define CST4322_BOOT_FROM_SRAM		0	/* boot from SRAM, ARM in reset */
+-#define CST4322_BOOT_FROM_ROM		1	/* boot from ROM */
+-#define CST4322_BOOT_FROM_FLASH		2	/* boot from FLASH */
+-#define CST4322_BOOT_FROM_INVALID	3
+-#define CST4322_ILP_DIV_EN		0x00000800
+-#define CST4322_FLASH_TYPE_MASK		0x00001000
+-#define CST4322_FLASH_TYPE_SHIFT	12
+-#define CST4322_FLASH_TYPE_SHIFT_ST	0	/* ST serial FLASH */
+-#define CST4322_FLASH_TYPE_SHIFT_ATMEL	1	/* ATMEL flash */
+-#define CST4322_ARM_TAP_SEL		0x00002000
+-#define CST4322_RES_INIT_MODE_MASK	0x0000c000
+-#define CST4322_RES_INIT_MODE_SHIFT	14
+-#define CST4322_RES_INIT_MODE_ILPAVAIL	0	/* resinitmode: ILP available */
+-#define CST4322_RES_INIT_MODE_ILPREQ	1	/* resinitmode: ILP request */
+-#define CST4322_RES_INIT_MODE_ALPAVAIL	2	/* resinitmode: ALP available */
+-#define CST4322_RES_INIT_MODE_HTAVAIL	3	/* resinitmode: HT available */
+-#define CST4322_PCIPLLCLK_GATING	0x00010000
+-#define CST4322_CLK_SWITCH_PCI_TO_ALP	0x00020000
+-#define CST4322_PCI_CARDBUS_MODE	0x00040000
+-
+-/* 43224 chip-specific ChipControl register bits */
+-#define CCTRL43224_GPIO_TOGGLE          0x8000
+-#define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0	/* 12 mA drive strength */
+-#define CCTRL_43224B0_12MA_LED_DRIVE    0xF0	/* 12 mA drive strength for later 43224s */
+-
+-/* 43236 resources */
+-#define RES43236_REGULATOR		0
+-#define RES43236_ILP_REQUEST		1
+-#define RES43236_XTAL_PU		2
+-#define RES43236_ALP_AVAIL		3
+-#define RES43236_SI_PLL_ON		4
+-#define RES43236_HT_SI_AVAIL		5
+-
+-/* 43236 chip-specific ChipControl register bits */
+-#define CCTRL43236_BT_COEXIST		(1<<0)	/* 0 disable */
+-#define CCTRL43236_SECI			(1<<1)	/* 0 SECI is disabled (JATG functional) */
+-#define CCTRL43236_EXT_LNA		(1<<2)	/* 0 disable */
+-#define CCTRL43236_ANT_MUX_2o3          (1<<3)	/* 2o3 mux, chipcontrol bit 3 */
+-#define CCTRL43236_GSIO			(1<<4)	/* 0 disable */
+-
+-/* 43236 Chip specific ChipStatus register bits */
+-#define CST43236_SFLASH_MASK		0x00000040
+-#define CST43236_OTP_MASK		0x00000080
+-#define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
+-#define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
+-#define CST43236_BOOT_MASK		0x00001800
+-#define CST43236_BOOT_SHIFT		11
+-#define CST43236_BOOT_FROM_SRAM		0	/* boot from SRAM, ARM in reset */
+-#define CST43236_BOOT_FROM_ROM		1	/* boot from ROM */
+-#define CST43236_BOOT_FROM_FLASH	2	/* boot from FLASH */
+-#define CST43236_BOOT_FROM_INVALID	3
+-
+-/* 4331 resources */
+-#define RES4331_REGULATOR		0
+-#define RES4331_ILP_REQUEST		1
+-#define RES4331_XTAL_PU			2
+-#define RES4331_ALP_AVAIL		3
+-#define RES4331_SI_PLL_ON		4
+-#define RES4331_HT_SI_AVAIL		5
+-
+-/* 4331 chip-specific ChipControl register bits */
+-#define CCTRL4331_BT_COEXIST		(1<<0)	/* 0 disable */
+-#define CCTRL4331_SECI			(1<<1)	/* 0 SECI is disabled (JATG functional) */
+-#define CCTRL4331_EXT_LNA		(1<<2)	/* 0 disable */
+-#define CCTRL4331_SPROM_GPIO13_15       (1<<3)	/* sprom/gpio13-15 mux */
+-#define CCTRL4331_EXTPA_EN		(1<<4)	/* 0 ext pa disable, 1 ext pa enabled */
+-#define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)	/* set drive out GPIO_CLK on sprom_cs pin */
+-#define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)	/* use sprom_cs pin as PCIE mdio interface */
+-#define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)	/* aband extpa will be at gpio2/5 and sprom_dout */
+-#define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)	/* override core control on pipe_AuxClkEnable */
+-#define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)	/* override core control on pipe_AuxPowerDown */
+-#define CCTRL4331_PCIE_AUXCLKEN		(1<<10)	/* pcie_auxclkenable */
+-#define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)	/* pcie_pipe_pllpowerdown */
+-#define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)	/* enable bt_shd0 at gpio4 */
+-#define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)	/* enable bt_shd1 at gpio5 */
+-
+-/* 4331 Chip specific ChipStatus register bits */
+-#define	CST4331_XTAL_FREQ		0x00000001	/* crystal frequency 20/40Mhz */
+-#define	CST4331_SPROM_PRESENT		0x00000002
+-#define	CST4331_OTP_PRESENT		0x00000004
+-#define	CST4331_LDO_RF			0x00000008
+-#define	CST4331_LDO_PAR			0x00000010
+-
+-/* 4315 resources */
+-#define RES4315_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4315_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4315_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4315_CLDO_PU			4	/* 0x00000010 */
+-#define RES4315_PALDO_PU		5	/* 0x00000020 */
+-#define RES4315_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4315_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4315_OTP_PU			10	/* 0x00000400 */
+-#define RES4315_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4315_XTAL_PU			13	/* 0x00002000 */
+-#define RES4315_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4315_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4315_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4315_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4315_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4315_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4315_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4315_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4315 chip-specific ChipStatus register bits */
+-#define CST4315_SPROM_OTP_SEL_MASK	0x00000003	/* gpio [7:6], SDIO CIS selection */
+-#define CST4315_DEFCIS_SEL		0x00000000	/* use default CIS, OTP is powered up */
+-#define CST4315_SPROM_SEL		0x00000001	/* use SPROM, OTP is powered up */
+-#define CST4315_OTP_SEL			0x00000002	/* use OTP, OTP is powered up */
+-#define CST4315_OTP_PWRDN		0x00000003	/* use SPROM, OTP is powered down */
+-#define CST4315_SDIO_MODE		0x00000004	/* gpio [8], sdio/usb mode */
+-#define CST4315_RCAL_VALID		0x00000008
+-#define CST4315_RCAL_VALUE_MASK		0x000001f0
+-#define CST4315_RCAL_VALUE_SHIFT	4
+-#define CST4315_PALDO_EXTPNP		0x00000200	/* PALDO is configured with external PNP */
+-#define CST4315_CBUCK_MODE_MASK		0x00000c00
+-#define CST4315_CBUCK_MODE_BURST	0x00000400
+-#define CST4315_CBUCK_MODE_LPBURST	0x00000c00
+-
+-/* 4319 resources */
+-#define RES4319_CBUCK_LPOM		1	/* 0x00000002 */
+-#define RES4319_CBUCK_BURST		2	/* 0x00000004 */
+-#define RES4319_CBUCK_PWM		3	/* 0x00000008 */
+-#define RES4319_CLDO_PU			4	/* 0x00000010 */
+-#define RES4319_PALDO_PU		5	/* 0x00000020 */
+-#define RES4319_ILP_REQUEST		6	/* 0x00000040 */
+-#define RES4319_LNLDO1_PU		9	/* 0x00000200 */
+-#define RES4319_OTP_PU			10	/* 0x00000400 */
+-#define RES4319_LNLDO2_PU		12	/* 0x00001000 */
+-#define RES4319_XTAL_PU			13	/* 0x00002000 */
+-#define RES4319_ALP_AVAIL		14	/* 0x00004000 */
+-#define RES4319_RX_PWRSW_PU		15	/* 0x00008000 */
+-#define RES4319_TX_PWRSW_PU		16	/* 0x00010000 */
+-#define RES4319_RFPLL_PWRSW_PU		17	/* 0x00020000 */
+-#define RES4319_LOGEN_PWRSW_PU		18	/* 0x00040000 */
+-#define RES4319_AFE_PWRSW_PU		19	/* 0x00080000 */
+-#define RES4319_BBPLL_PWRSW_PU		20	/* 0x00100000 */
+-#define RES4319_HT_AVAIL		21	/* 0x00200000 */
+-
+-/* 4319 chip-specific ChipStatus register bits */
+-#define	CST4319_SPI_CPULESSUSB		0x00000001
+-#define	CST4319_SPI_CLK_POL		0x00000002
+-#define	CST4319_SPI_CLK_PH		0x00000008
+-#define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0	/* gpio [7:6], SDIO CIS selection */
+-#define	CST4319_SPROM_OTP_SEL_SHIFT	6
+-#define	CST4319_DEFCIS_SEL		0x00000000	/* use default CIS, OTP is powered up */
+-#define	CST4319_SPROM_SEL		0x00000040	/* use SPROM, OTP is powered up */
+-#define	CST4319_OTP_SEL			0x00000080	/* use OTP, OTP is powered up */
+-#define	CST4319_OTP_PWRDN		0x000000c0	/* use SPROM, OTP is powered down */
+-#define	CST4319_SDIO_USB_MODE		0x00000100	/* gpio [8], sdio/usb mode */
+-#define	CST4319_REMAP_SEL_MASK		0x00000600
+-#define	CST4319_ILPDIV_EN		0x00000800
+-#define	CST4319_XTAL_PD_POL		0x00001000
+-#define	CST4319_LPO_SEL			0x00002000
+-#define	CST4319_RES_INIT_MODE		0x0000c000
+-#define	CST4319_PALDO_EXTPNP		0x00010000	/* PALDO is configured with external PNP */
+-#define	CST4319_CBUCK_MODE_MASK		0x00060000
+-#define CST4319_CBUCK_MODE_BURST	0x00020000
+-#define CST4319_CBUCK_MODE_LPBURST	0x00060000
+-#define	CST4319_RCAL_VALID		0x01000000
+-#define	CST4319_RCAL_VALUE_MASK		0x3e000000
+-#define	CST4319_RCAL_VALUE_SHIFT	25
+-
+-#define PMU1_PLL0_CHIPCTL0		0
+-#define PMU1_PLL0_CHIPCTL1		1
+-#define PMU1_PLL0_CHIPCTL2		2
+-#define CCTL_4319USB_XTAL_SEL_MASK	0x00180000
+-#define CCTL_4319USB_XTAL_SEL_SHIFT	19
+-#define CCTL_4319USB_48MHZ_PLL_SEL	1
+-#define CCTL_4319USB_24MHZ_PLL_SEL	2
+-
+-/* PMU resources for 4336 */
+-#define	RES4336_CBUCK_LPOM		0
+-#define	RES4336_CBUCK_BURST		1
+-#define	RES4336_CBUCK_LP_PWM		2
+-#define	RES4336_CBUCK_PWM		3
+-#define	RES4336_CLDO_PU			4
+-#define	RES4336_DIS_INT_RESET_PD	5
+-#define	RES4336_ILP_REQUEST		6
+-#define	RES4336_LNLDO_PU		7
+-#define	RES4336_LDO3P3_PU		8
+-#define	RES4336_OTP_PU			9
+-#define	RES4336_XTAL_PU			10
+-#define	RES4336_ALP_AVAIL		11
+-#define	RES4336_RADIO_PU		12
+-#define	RES4336_BG_PU			13
+-#define	RES4336_VREG1p4_PU_PU		14
+-#define	RES4336_AFE_PWRSW_PU		15
+-#define	RES4336_RX_PWRSW_PU		16
+-#define	RES4336_TX_PWRSW_PU		17
+-#define	RES4336_BB_PWRSW_PU		18
+-#define	RES4336_SYNTH_PWRSW_PU		19
+-#define	RES4336_MISC_PWRSW_PU		20
+-#define	RES4336_LOGEN_PWRSW_PU		21
+-#define	RES4336_BBPLL_PWRSW_PU		22
+-#define	RES4336_MACPHY_CLKAVAIL		23
+-#define	RES4336_HT_AVAIL		24
+-#define	RES4336_RSVD			25
+-
+-/* 4336 chip-specific ChipStatus register bits */
+-#define	CST4336_SPI_MODE_MASK		0x00000001
+-#define	CST4336_SPROM_PRESENT		0x00000002
+-#define	CST4336_OTP_PRESENT		0x00000004
+-#define	CST4336_ARMREMAP_0		0x00000008
+-#define	CST4336_ILPDIV_EN_MASK		0x00000010
+-#define	CST4336_ILPDIV_EN_SHIFT		4
+-#define	CST4336_XTAL_PD_POL_MASK	0x00000020
+-#define	CST4336_XTAL_PD_POL_SHIFT	5
+-#define	CST4336_LPO_SEL_MASK		0x00000040
+-#define	CST4336_LPO_SEL_SHIFT		6
+-#define	CST4336_RES_INIT_MODE_MASK	0x00000180
+-#define	CST4336_RES_INIT_MODE_SHIFT	7
+-#define	CST4336_CBUCK_MODE_MASK		0x00000600
+-#define	CST4336_CBUCK_MODE_SHIFT	9
+-
+-/* 4330 resources */
+-#define	RES4330_CBUCK_LPOM		0
+-#define	RES4330_CBUCK_BURST		1
+-#define	RES4330_CBUCK_LP_PWM		2
+-#define	RES4330_CBUCK_PWM		3
+-#define	RES4330_CLDO_PU			4
+-#define	RES4330_DIS_INT_RESET_PD	5
+-#define	RES4330_ILP_REQUEST		6
+-#define	RES4330_LNLDO_PU		7
+-#define	RES4330_LDO3P3_PU		8
+-#define	RES4330_OTP_PU			9
+-#define	RES4330_XTAL_PU			10
+-#define	RES4330_ALP_AVAIL		11
+-#define	RES4330_RADIO_PU		12
+-#define	RES4330_BG_PU			13
+-#define	RES4330_VREG1p4_PU_PU		14
+-#define	RES4330_AFE_PWRSW_PU		15
+-#define	RES4330_RX_PWRSW_PU		16
+-#define	RES4330_TX_PWRSW_PU		17
+-#define	RES4330_BB_PWRSW_PU		18
+-#define	RES4330_SYNTH_PWRSW_PU		19
+-#define	RES4330_MISC_PWRSW_PU		20
+-#define	RES4330_LOGEN_PWRSW_PU		21
+-#define	RES4330_BBPLL_PWRSW_PU		22
+-#define	RES4330_MACPHY_CLKAVAIL		23
+-#define	RES4330_HT_AVAIL		24
+-#define	RES4330_5gRX_PWRSW_PU		25
+-#define	RES4330_5gTX_PWRSW_PU		26
+-#define	RES4330_5g_LOGEN_PWRSW_PU	27
+-
+-/* 4330 chip-specific ChipStatus register bits */
+-#define CST4330_CHIPMODE_SDIOD(cs)	(((cs) & 0x7) < 6)	/* SDIO || gSPI */
+-#define CST4330_CHIPMODE_USB20D(cs)	(((cs) & 0x7) >= 6)	/* USB || USBDA */
+-#define CST4330_CHIPMODE_SDIO(cs)	(((cs) & 0x4) == 0)	/* SDIO */
+-#define CST4330_CHIPMODE_GSPI(cs)	(((cs) & 0x6) == 4)	/* gSPI */
+-#define CST4330_CHIPMODE_USB(cs)	(((cs) & 0x7) == 6)	/* USB packet-oriented */
+-#define CST4330_CHIPMODE_USBDA(cs)	(((cs) & 0x7) == 7)	/* USB Direct Access */
+-#define	CST4330_OTP_PRESENT		0x00000010
+-#define	CST4330_LPO_AUTODET_EN		0x00000020
+-#define	CST4330_ARMREMAP_0		0x00000040
+-#define	CST4330_SPROM_PRESENT		0x00000080	/* takes priority over OTP if both set */
+-#define	CST4330_ILPDIV_EN		0x00000100
+-#define	CST4330_LPO_SEL			0x00000200
+-#define	CST4330_RES_INIT_MODE_SHIFT	10
+-#define	CST4330_RES_INIT_MODE_MASK	0x00000c00
+-#define CST4330_CBUCK_MODE_SHIFT	12
+-#define CST4330_CBUCK_MODE_MASK		0x00003000
+-#define	CST4330_CBUCK_POWER_OK		0x00004000
+-#define	CST4330_BB_PLL_LOCKED		0x00008000
+-#define SOCDEVRAM_4330_BP_ADDR		0x1E000000
+-#define SOCDEVRAM_4330_ARM_ADDR		0x00800000
+-
+-/* 4313 resources */
+-#define	RES4313_BB_PU_RSRC		0
+-#define	RES4313_ILP_REQ_RSRC		1
+-#define	RES4313_XTAL_PU_RSRC		2
+-#define	RES4313_ALP_AVAIL_RSRC		3
+-#define	RES4313_RADIO_PU_RSRC		4
+-#define	RES4313_BG_PU_RSRC		5
+-#define	RES4313_VREG1P4_PU_RSRC		6
+-#define	RES4313_AFE_PWRSW_RSRC		7
+-#define	RES4313_RX_PWRSW_RSRC		8
+-#define	RES4313_TX_PWRSW_RSRC		9
+-#define	RES4313_BB_PWRSW_RSRC		10
+-#define	RES4313_SYNTH_PWRSW_RSRC	11
+-#define	RES4313_MISC_PWRSW_RSRC		12
+-#define	RES4313_BB_PLL_PWRSW_RSRC	13
+-#define	RES4313_HT_AVAIL_RSRC		14
+-#define	RES4313_MACPHY_CLK_AVAIL_RSRC	15
+-
+-/* 4313 chip-specific ChipStatus register bits */
+-#define	CST4313_SPROM_PRESENT			1
+-#define	CST4313_OTP_PRESENT			2
+-#define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
+-#define	CST4313_SPROM_OTP_SEL_SHIFT		0
+-
+-/* 4313 Chip specific ChipControl register bits */
+-#define CCTRL_4313_12MA_LED_DRIVE    0x00000007	/* 12 mA drive strengh for later 4313 */
+-
+-/* 43228 resources */
+-#define RES43228_NOT_USED		0
+-#define RES43228_ILP_REQUEST		1
+-#define RES43228_XTAL_PU		2
+-#define RES43228_ALP_AVAIL		3
+-#define RES43228_PLL_EN			4
+-#define RES43228_HT_PHY_AVAIL		5
+-
+-/* 43228 chipstatus  reg bits */
+-#define CST43228_ILP_DIV_EN		0x1
+-#define	CST43228_OTP_PRESENT		0x2
+-#define	CST43228_SERDES_REFCLK_PADSEL	0x4
+-#define	CST43228_SDIO_MODE		0x8
+-
+-#define	CST43228_SDIO_OTP_PRESENT	0x10
+-#define	CST43228_SDIO_RESET		0x20
+-
+-/*
+-* Maximum delay for the PMU state transition in us.
+-* This is an upper bound intended for spinwaits etc.
+-*/
+-#define PMU_MAX_TRANSITION_DLY	15000
+-
+-/* PMU resource up transition time in ILP cycles */
+-#define PMURES_UP_TRANSITION	2
+-
+-/*
+-* Register eci_inputlo bitfield values.
+-* - BT packet type information bits [7:0]
+-*/
+-/*  [3:0] - Task (link) type */
+-#define BT_ACL				0x00
+-#define BT_SCO				0x01
+-#define BT_eSCO				0x02
+-#define BT_A2DP				0x03
+-#define BT_SNIFF			0x04
+-#define BT_PAGE_SCAN			0x05
+-#define BT_INQUIRY_SCAN			0x06
+-#define BT_PAGE				0x07
+-#define BT_INQUIRY			0x08
+-#define BT_MSS				0x09
+-#define BT_PARK				0x0a
+-#define BT_RSSISCAN			0x0b
+-#define BT_MD_ACL			0x0c
+-#define BT_MD_eSCO			0x0d
+-#define BT_SCAN_WITH_SCO_LINK		0x0e
+-#define BT_SCAN_WITHOUT_SCO_LINK	0x0f
+-/* [7:4] = packet duration code */
+-/* [8] - Master / Slave */
+-#define BT_MASTER			0
+-#define BT_SLAVE			1
+-/* [11:9] - multi-level priority */
+-#define BT_LOWEST_PRIO			0x0
+-#define BT_HIGHEST_PRIO			0x3
+-
+-/* WLAN - number of antenna */
+-#define WLAN_NUM_ANT1 TXANT_0
+-#define WLAN_NUM_ANT2 TXANT_1
+-
+-#endif				/* _SBCHIPC_H */
+diff --git a/drivers/staging/brcm80211/include/sbconfig.h b/drivers/staging/brcm80211/include/sbconfig.h
+deleted file mode 100644
+index 5247f01..0000000
+--- a/drivers/staging/brcm80211/include/sbconfig.h
++++ /dev/null
+@@ -1,272 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBCONFIG_H
+-#define	_SBCONFIG_H
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif
+-
+-/* enumeration in SB is based on the premise that cores are contiguos in the
+- * enumeration space.
+- */
+-#define SB_BUS_SIZE		0x10000	/* Each bus gets 64Kbytes for cores */
+-#define SB_BUS_BASE(b)		(SI_ENUM_BASE + (b) * SB_BUS_SIZE)
+-#define	SB_BUS_MAXCORES		(SB_BUS_SIZE / SI_CORE_SIZE)	/* Max cores per bus */
+-
+-/*
+- * Sonics Configuration Space Registers.
+- */
+-#define	SBCONFIGOFF		0xf00	/* core sbconfig regs are top 256bytes of regs */
+-#define	SBCONFIGSIZE		256	/* sizeof (sbconfig_t) */
+-
+-#define SBIPSFLAG		0x08
+-#define SBTPSFLAG		0x18
+-#define	SBTMERRLOGA		0x48	/* sonics >= 2.3 */
+-#define	SBTMERRLOG		0x50	/* sonics >= 2.3 */
+-#define SBADMATCH3		0x60
+-#define SBADMATCH2		0x68
+-#define SBADMATCH1		0x70
+-#define SBIMSTATE		0x90
+-#define SBINTVEC		0x94
+-#define SBTMSTATELOW		0x98
+-#define SBTMSTATEHIGH		0x9c
+-#define SBBWA0			0xa0
+-#define SBIMCONFIGLOW		0xa8
+-#define SBIMCONFIGHIGH		0xac
+-#define SBADMATCH0		0xb0
+-#define SBTMCONFIGLOW		0xb8
+-#define SBTMCONFIGHIGH		0xbc
+-#define SBBCONFIG		0xc0
+-#define SBBSTATE		0xc8
+-#define SBACTCNFG		0xd8
+-#define	SBFLAGST		0xe8
+-#define SBIDLOW			0xf8
+-#define SBIDHIGH		0xfc
+-
+-/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have
+- * a few registers *below* that line. I think it would be very confusing to try
+- * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here,
+- */
+-
+-#define SBIMERRLOGA		0xea8
+-#define SBIMERRLOG		0xeb0
+-#define SBTMPORTCONNID0		0xed8
+-#define SBTMPORTLOCK0		0xef8
+-
+-#ifndef _LANGUAGE_ASSEMBLY
+-
+-typedef volatile struct _sbconfig {
+-	u32 PAD[2];
+-	u32 sbipsflag;	/* initiator port ocp slave flag */
+-	u32 PAD[3];
+-	u32 sbtpsflag;	/* target port ocp slave flag */
+-	u32 PAD[11];
+-	u32 sbtmerrloga;	/* (sonics >= 2.3) */
+-	u32 PAD;
+-	u32 sbtmerrlog;	/* (sonics >= 2.3) */
+-	u32 PAD[3];
+-	u32 sbadmatch3;	/* address match3 */
+-	u32 PAD;
+-	u32 sbadmatch2;	/* address match2 */
+-	u32 PAD;
+-	u32 sbadmatch1;	/* address match1 */
+-	u32 PAD[7];
+-	u32 sbimstate;	/* initiator agent state */
+-	u32 sbintvec;	/* interrupt mask */
+-	u32 sbtmstatelow;	/* target state */
+-	u32 sbtmstatehigh;	/* target state */
+-	u32 sbbwa0;		/* bandwidth allocation table0 */
+-	u32 PAD;
+-	u32 sbimconfiglow;	/* initiator configuration */
+-	u32 sbimconfighigh;	/* initiator configuration */
+-	u32 sbadmatch0;	/* address match0 */
+-	u32 PAD;
+-	u32 sbtmconfiglow;	/* target configuration */
+-	u32 sbtmconfighigh;	/* target configuration */
+-	u32 sbbconfig;	/* broadcast configuration */
+-	u32 PAD;
+-	u32 sbbstate;	/* broadcast state */
+-	u32 PAD[3];
+-	u32 sbactcnfg;	/* activate configuration */
+-	u32 PAD[3];
+-	u32 sbflagst;	/* current sbflags */
+-	u32 PAD[3];
+-	u32 sbidlow;		/* identification */
+-	u32 sbidhigh;	/* identification */
+-} sbconfig_t;
+-
+-#endif				/* _LANGUAGE_ASSEMBLY */
+-
+-/* sbipsflag */
+-#define	SBIPS_INT1_MASK		0x3f	/* which sbflags get routed to mips interrupt 1 */
+-#define	SBIPS_INT1_SHIFT	0
+-#define	SBIPS_INT2_MASK		0x3f00	/* which sbflags get routed to mips interrupt 2 */
+-#define	SBIPS_INT2_SHIFT	8
+-#define	SBIPS_INT3_MASK		0x3f0000	/* which sbflags get routed to mips interrupt 3 */
+-#define	SBIPS_INT3_SHIFT	16
+-#define	SBIPS_INT4_MASK		0x3f000000	/* which sbflags get routed to mips interrupt 4 */
+-#define	SBIPS_INT4_SHIFT	24
+-
+-/* sbtpsflag */
+-#define	SBTPS_NUM0_MASK		0x3f	/* interrupt sbFlag # generated by this core */
+-#define	SBTPS_F0EN0		0x40	/* interrupt is always sent on the backplane */
+-
+-/* sbtmerrlog */
+-#define	SBTMEL_CM		0x00000007	/* command */
+-#define	SBTMEL_CI		0x0000ff00	/* connection id */
+-#define	SBTMEL_EC		0x0f000000	/* error code */
+-#define	SBTMEL_ME		0x80000000	/* multiple error */
+-
+-/* sbimstate */
+-#define	SBIM_PC			0xf	/* pipecount */
+-#define	SBIM_AP_MASK		0x30	/* arbitration policy */
+-#define	SBIM_AP_BOTH		0x00	/* use both timeslaces and token */
+-#define	SBIM_AP_TS		0x10	/* use timesliaces only */
+-#define	SBIM_AP_TK		0x20	/* use token only */
+-#define	SBIM_AP_RSV		0x30	/* reserved */
+-#define	SBIM_IBE		0x20000	/* inbanderror */
+-#define	SBIM_TO			0x40000	/* timeout */
+-#define	SBIM_BY			0x01800000	/* busy (sonics >= 2.3) */
+-#define	SBIM_RJ			0x02000000	/* reject (sonics >= 2.3) */
+-
+-/* sbtmstatelow */
+-#define	SBTML_RESET		0x0001	/* reset */
+-#define	SBTML_REJ_MASK		0x0006	/* reject field */
+-#define	SBTML_REJ		0x0002	/* reject */
+-#define	SBTML_TMPREJ		0x0004	/* temporary reject, for error recovery */
+-
+-#define	SBTML_SICF_SHIFT	16	/* Shift to locate the SI control flags in sbtml */
+-
+-/* sbtmstatehigh */
+-#define	SBTMH_SERR		0x0001	/* serror */
+-#define	SBTMH_INT		0x0002	/* interrupt */
+-#define	SBTMH_BUSY		0x0004	/* busy */
+-#define	SBTMH_TO		0x0020	/* timeout (sonics >= 2.3) */
+-
+-#define	SBTMH_SISF_SHIFT	16	/* Shift to locate the SI status flags in sbtmh */
+-
+-/* sbbwa0 */
+-#define	SBBWA_TAB0_MASK		0xffff	/* lookup table 0 */
+-#define	SBBWA_TAB1_MASK		0xffff	/* lookup table 1 */
+-#define	SBBWA_TAB1_SHIFT	16
+-
+-/* sbimconfiglow */
+-#define	SBIMCL_STO_MASK		0x7	/* service timeout */
+-#define	SBIMCL_RTO_MASK		0x70	/* request timeout */
+-#define	SBIMCL_RTO_SHIFT	4
+-#define	SBIMCL_CID_MASK		0xff0000	/* connection id */
+-#define	SBIMCL_CID_SHIFT	16
+-
+-/* sbimconfighigh */
+-#define	SBIMCH_IEM_MASK		0xc	/* inband error mode */
+-#define	SBIMCH_TEM_MASK		0x30	/* timeout error mode */
+-#define	SBIMCH_TEM_SHIFT	4
+-#define	SBIMCH_BEM_MASK		0xc0	/* bus error mode */
+-#define	SBIMCH_BEM_SHIFT	6
+-
+-/* sbadmatch0 */
+-#define	SBAM_TYPE_MASK		0x3	/* address type */
+-#define	SBAM_AD64		0x4	/* reserved */
+-#define	SBAM_ADINT0_MASK	0xf8	/* type0 size */
+-#define	SBAM_ADINT0_SHIFT	3
+-#define	SBAM_ADINT1_MASK	0x1f8	/* type1 size */
+-#define	SBAM_ADINT1_SHIFT	3
+-#define	SBAM_ADINT2_MASK	0x1f8	/* type2 size */
+-#define	SBAM_ADINT2_SHIFT	3
+-#define	SBAM_ADEN		0x400	/* enable */
+-#define	SBAM_ADNEG		0x800	/* negative decode */
+-#define	SBAM_BASE0_MASK		0xffffff00	/* type0 base address */
+-#define	SBAM_BASE0_SHIFT	8
+-#define	SBAM_BASE1_MASK		0xfffff000	/* type1 base address for the core */
+-#define	SBAM_BASE1_SHIFT	12
+-#define	SBAM_BASE2_MASK		0xffff0000	/* type2 base address for the core */
+-#define	SBAM_BASE2_SHIFT	16
+-
+-/* sbtmconfiglow */
+-#define	SBTMCL_CD_MASK		0xff	/* clock divide */
+-#define	SBTMCL_CO_MASK		0xf800	/* clock offset */
+-#define	SBTMCL_CO_SHIFT		11
+-#define	SBTMCL_IF_MASK		0xfc0000	/* interrupt flags */
+-#define	SBTMCL_IF_SHIFT		18
+-#define	SBTMCL_IM_MASK		0x3000000	/* interrupt mode */
+-#define	SBTMCL_IM_SHIFT		24
+-
+-/* sbtmconfighigh */
+-#define	SBTMCH_BM_MASK		0x3	/* busy mode */
+-#define	SBTMCH_RM_MASK		0x3	/* retry mode */
+-#define	SBTMCH_RM_SHIFT		2
+-#define	SBTMCH_SM_MASK		0x30	/* stop mode */
+-#define	SBTMCH_SM_SHIFT		4
+-#define	SBTMCH_EM_MASK		0x300	/* sb error mode */
+-#define	SBTMCH_EM_SHIFT		8
+-#define	SBTMCH_IM_MASK		0xc00	/* int mode */
+-#define	SBTMCH_IM_SHIFT		10
+-
+-/* sbbconfig */
+-#define	SBBC_LAT_MASK		0x3	/* sb latency */
+-#define	SBBC_MAX0_MASK		0xf0000	/* maxccntr0 */
+-#define	SBBC_MAX0_SHIFT		16
+-#define	SBBC_MAX1_MASK		0xf00000	/* maxccntr1 */
+-#define	SBBC_MAX1_SHIFT		20
+-
+-/* sbbstate */
+-#define	SBBS_SRD		0x1	/* st reg disable */
+-#define	SBBS_HRD		0x2	/* hold reg disable */
+-
+-/* sbidlow */
+-#define	SBIDL_CS_MASK		0x3	/* config space */
+-#define	SBIDL_AR_MASK		0x38	/* # address ranges supported */
+-#define	SBIDL_AR_SHIFT		3
+-#define	SBIDL_SYNCH		0x40	/* sync */
+-#define	SBIDL_INIT		0x80	/* initiator */
+-#define	SBIDL_MINLAT_MASK	0xf00	/* minimum backplane latency */
+-#define	SBIDL_MINLAT_SHIFT	8
+-#define	SBIDL_MAXLAT		0xf000	/* maximum backplane latency */
+-#define	SBIDL_MAXLAT_SHIFT	12
+-#define	SBIDL_FIRST		0x10000	/* this initiator is first */
+-#define	SBIDL_CW_MASK		0xc0000	/* cycle counter width */
+-#define	SBIDL_CW_SHIFT		18
+-#define	SBIDL_TP_MASK		0xf00000	/* target ports */
+-#define	SBIDL_TP_SHIFT		20
+-#define	SBIDL_IP_MASK		0xf000000	/* initiator ports */
+-#define	SBIDL_IP_SHIFT		24
+-#define	SBIDL_RV_MASK		0xf0000000	/* sonics backplane revision code */
+-#define	SBIDL_RV_SHIFT		28
+-#define	SBIDL_RV_2_2		0x00000000	/* version 2.2 or earlier */
+-#define	SBIDL_RV_2_3		0x10000000	/* version 2.3 */
+-
+-/* sbidhigh */
+-#define	SBIDH_RC_MASK		0x000f	/* revision code */
+-#define	SBIDH_RCE_MASK		0x7000	/* revision code extension field */
+-#define	SBIDH_RCE_SHIFT		8
+-#define	SBCOREREV(sbidh) \
+-	((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
+-#define	SBIDH_CC_MASK		0x8ff0	/* core code */
+-#define	SBIDH_CC_SHIFT		4
+-#define	SBIDH_VC_MASK		0xffff0000	/* vendor code */
+-#define	SBIDH_VC_SHIFT		16
+-
+-#define	SB_COMMIT		0xfd8	/* update buffered registers value */
+-
+-/* vendor codes */
+-#define	SB_VEND_BCM		0x4243	/* Broadcom's SB vendor code */
+-
+-#endif				/* _SBCONFIG_H */
+diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h
+deleted file mode 100644
+index 08cb7f6..0000000
+--- a/drivers/staging/brcm80211/include/sbhnddma.h
++++ /dev/null
+@@ -1,315 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sbhnddma_h_
+-#define	_sbhnddma_h_
+-
+-/* DMA structure:
+- *  support two DMA engines: 32 bits address or 64 bit addressing
+- *  basic DMA register set is per channel(transmit or receive)
+- *  a pair of channels is defined for convenience
+- */
+-
+-/* 32 bits addressing */
+-
+-/* dma registers per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 control;		/* enable, et al */
+-	u32 addr;		/* descriptor ring base address (4K aligned) */
+-	u32 ptr;		/* last descriptor posted to chip */
+-	u32 status;		/* current active descriptor, et al */
+-} dma32regs_t;
+-
+-typedef volatile struct {
+-	dma32regs_t xmt;	/* dma tx channel */
+-	dma32regs_t rcv;	/* dma rx channel */
+-} dma32regp_t;
+-
+-typedef volatile struct {	/* diag access */
+-	u32 fifoaddr;	/* diag address */
+-	u32 fifodatalow;	/* low 32bits of data */
+-	u32 fifodatahigh;	/* high 32bits of data */
+-	u32 pad;		/* reserved */
+-} dma32diag_t;
+-
+-/*
+- * DMA Descriptor
+- * Descriptors are only read by the hardware, never written back.
+- */
+-typedef volatile struct {
+-	u32 ctrl;		/* misc control bits & bufcount */
+-	u32 addr;		/* data buffer address */
+-} dma32dd_t;
+-
+-/*
+- * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
+- */
+-#define	D32RINGALIGN_BITS	12
+-#define	D32MAXRINGSZ		(1 << D32RINGALIGN_BITS)
+-#define	D32RINGALIGN		(1 << D32RINGALIGN_BITS)
+-
+-#define	D32MAXDD	(D32MAXRINGSZ / sizeof (dma32dd_t))
+-
+-/* transmit channel control */
+-#define	XC_XE		((u32)1 << 0)	/* transmit enable */
+-#define	XC_SE		((u32)1 << 1)	/* transmit suspend request */
+-#define	XC_LE		((u32)1 << 2)	/* loopback enable */
+-#define	XC_FL		((u32)1 << 4)	/* flush request */
+-#define	XC_PD		((u32)1 << 11)	/* parity check disable */
+-#define	XC_AE		((u32)3 << 16)	/* address extension bits */
+-#define	XC_AE_SHIFT	16
+-
+-/* transmit descriptor table pointer */
+-#define	XP_LD_MASK	0xfff	/* last valid descriptor */
+-
+-/* transmit channel status */
+-#define	XS_CD_MASK	0x0fff	/* current descriptor pointer */
+-#define	XS_XS_MASK	0xf000	/* transmit state */
+-#define	XS_XS_SHIFT	12
+-#define	XS_XS_DISABLED	0x0000	/* disabled */
+-#define	XS_XS_ACTIVE	0x1000	/* active */
+-#define	XS_XS_IDLE	0x2000	/* idle wait */
+-#define	XS_XS_STOPPED	0x3000	/* stopped */
+-#define	XS_XS_SUSP	0x4000	/* suspend pending */
+-#define	XS_XE_MASK	0xf0000	/* transmit errors */
+-#define	XS_XE_SHIFT	16
+-#define	XS_XE_NOERR	0x00000	/* no error */
+-#define	XS_XE_DPE	0x10000	/* descriptor protocol error */
+-#define	XS_XE_DFU	0x20000	/* data fifo underrun */
+-#define	XS_XE_BEBR	0x30000	/* bus error on buffer read */
+-#define	XS_XE_BEDA	0x40000	/* bus error on descriptor access */
+-#define	XS_AD_MASK	0xfff00000	/* active descriptor */
+-#define	XS_AD_SHIFT	20
+-
+-/* receive channel control */
+-#define	RC_RE		((u32)1 << 0)	/* receive enable */
+-#define	RC_RO_MASK	0xfe	/* receive frame offset */
+-#define	RC_RO_SHIFT	1
+-#define	RC_FM		((u32)1 << 8)	/* direct fifo receive (pio) mode */
+-#define	RC_SH		((u32)1 << 9)	/* separate rx header descriptor enable */
+-#define	RC_OC		((u32)1 << 10)	/* overflow continue */
+-#define	RC_PD		((u32)1 << 11)	/* parity check disable */
+-#define	RC_AE		((u32)3 << 16)	/* address extension bits */
+-#define	RC_AE_SHIFT	16
+-
+-/* receive descriptor table pointer */
+-#define	RP_LD_MASK	0xfff	/* last valid descriptor */
+-
+-/* receive channel status */
+-#define	RS_CD_MASK	0x0fff	/* current descriptor pointer */
+-#define	RS_RS_MASK	0xf000	/* receive state */
+-#define	RS_RS_SHIFT	12
+-#define	RS_RS_DISABLED	0x0000	/* disabled */
+-#define	RS_RS_ACTIVE	0x1000	/* active */
+-#define	RS_RS_IDLE	0x2000	/* idle wait */
+-#define	RS_RS_STOPPED	0x3000	/* reserved */
+-#define	RS_RE_MASK	0xf0000	/* receive errors */
+-#define	RS_RE_SHIFT	16
+-#define	RS_RE_NOERR	0x00000	/* no error */
+-#define	RS_RE_DPE	0x10000	/* descriptor protocol error */
+-#define	RS_RE_DFO	0x20000	/* data fifo overflow */
+-#define	RS_RE_BEBW	0x30000	/* bus error on buffer write */
+-#define	RS_RE_BEDA	0x40000	/* bus error on descriptor access */
+-#define	RS_AD_MASK	0xfff00000	/* active descriptor */
+-#define	RS_AD_SHIFT	20
+-
+-/* fifoaddr */
+-#define	FA_OFF_MASK	0xffff	/* offset */
+-#define	FA_SEL_MASK	0xf0000	/* select */
+-#define	FA_SEL_SHIFT	16
+-#define	FA_SEL_XDD	0x00000	/* transmit dma data */
+-#define	FA_SEL_XDP	0x10000	/* transmit dma pointers */
+-#define	FA_SEL_RDD	0x40000	/* receive dma data */
+-#define	FA_SEL_RDP	0x50000	/* receive dma pointers */
+-#define	FA_SEL_XFD	0x80000	/* transmit fifo data */
+-#define	FA_SEL_XFP	0x90000	/* transmit fifo pointers */
+-#define	FA_SEL_RFD	0xc0000	/* receive fifo data */
+-#define	FA_SEL_RFP	0xd0000	/* receive fifo pointers */
+-#define	FA_SEL_RSD	0xe0000	/* receive frame status data */
+-#define	FA_SEL_RSP	0xf0000	/* receive frame status pointers */
+-
+-/* descriptor control flags */
+-#define	CTRL_BC_MASK	0x00001fff	/* buffer byte count, real data len must <= 4KB */
+-#define	CTRL_AE		((u32)3 << 16)	/* address extension bits */
+-#define	CTRL_AE_SHIFT	16
+-#define	CTRL_PARITY	((u32)3 << 18)	/* parity bit */
+-#define	CTRL_EOT	((u32)1 << 28)	/* end of descriptor table */
+-#define	CTRL_IOC	((u32)1 << 29)	/* interrupt on completion */
+-#define	CTRL_EOF	((u32)1 << 30)	/* end of frame */
+-#define	CTRL_SOF	((u32)1 << 31)	/* start of frame */
+-
+-/* control flags in the range [27:20] are core-specific and not defined here */
+-#define	CTRL_CORE_MASK	0x0ff00000
+-
+-/* 64 bits addressing */
+-
+-/* dma registers per channel(xmt or rcv) */
+-typedef volatile struct {
+-	u32 control;		/* enable, et al */
+-	u32 ptr;		/* last descriptor posted to chip */
+-	u32 addrlow;		/* descriptor ring base address low 32-bits (8K aligned) */
+-	u32 addrhigh;	/* descriptor ring base address bits 63:32 (8K aligned) */
+-	u32 status0;		/* current descriptor, xmt state */
+-	u32 status1;		/* active descriptor, xmt error */
+-} dma64regs_t;
+-
+-typedef volatile struct {
+-	dma64regs_t tx;		/* dma64 tx channel */
+-	dma64regs_t rx;		/* dma64 rx channel */
+-} dma64regp_t;
+-
+-typedef volatile struct {	/* diag access */
+-	u32 fifoaddr;	/* diag address */
+-	u32 fifodatalow;	/* low 32bits of data */
+-	u32 fifodatahigh;	/* high 32bits of data */
+-	u32 pad;		/* reserved */
+-} dma64diag_t;
+-
+-/*
+- * DMA Descriptor
+- * Descriptors are only read by the hardware, never written back.
+- */
+-typedef volatile struct {
+-	u32 ctrl1;		/* misc control bits & bufcount */
+-	u32 ctrl2;		/* buffer count and address extension */
+-	u32 addrlow;		/* memory address of the date buffer, bits 31:0 */
+-	u32 addrhigh;	/* memory address of the date buffer, bits 63:32 */
+-} dma64dd_t;
+-
+-/*
+- * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address.
+- */
+-#define D64RINGALIGN_BITS	13
+-#define	D64MAXRINGSZ		(1 << D64RINGALIGN_BITS)
+-#define	D64RINGALIGN		(1 << D64RINGALIGN_BITS)
+-
+-#define	D64MAXDD	(D64MAXRINGSZ / sizeof (dma64dd_t))
+-
+-/* transmit channel control */
+-#define	D64_XC_XE		0x00000001	/* transmit enable */
+-#define	D64_XC_SE		0x00000002	/* transmit suspend request */
+-#define	D64_XC_LE		0x00000004	/* loopback enable */
+-#define	D64_XC_FL		0x00000010	/* flush request */
+-#define	D64_XC_PD		0x00000800	/* parity check disable */
+-#define	D64_XC_AE		0x00030000	/* address extension bits */
+-#define	D64_XC_AE_SHIFT		16
+-
+-/* transmit descriptor table pointer */
+-#define	D64_XP_LD_MASK		0x00000fff	/* last valid descriptor */
+-
+-/* transmit channel status */
+-#define	D64_XS0_CD_MASK		0x00001fff	/* current descriptor pointer */
+-#define	D64_XS0_XS_MASK		0xf0000000	/* transmit state */
+-#define	D64_XS0_XS_SHIFT		28
+-#define	D64_XS0_XS_DISABLED	0x00000000	/* disabled */
+-#define	D64_XS0_XS_ACTIVE	0x10000000	/* active */
+-#define	D64_XS0_XS_IDLE		0x20000000	/* idle wait */
+-#define	D64_XS0_XS_STOPPED	0x30000000	/* stopped */
+-#define	D64_XS0_XS_SUSP		0x40000000	/* suspend pending */
+-
+-#define	D64_XS1_AD_MASK		0x00001fff	/* active descriptor */
+-#define	D64_XS1_XE_MASK		0xf0000000	/* transmit errors */
+-#define	D64_XS1_XE_SHIFT		28
+-#define	D64_XS1_XE_NOERR	0x00000000	/* no error */
+-#define	D64_XS1_XE_DPE		0x10000000	/* descriptor protocol error */
+-#define	D64_XS1_XE_DFU		0x20000000	/* data fifo underrun */
+-#define	D64_XS1_XE_DTE		0x30000000	/* data transfer error */
+-#define	D64_XS1_XE_DESRE	0x40000000	/* descriptor read error */
+-#define	D64_XS1_XE_COREE	0x50000000	/* core error */
+-
+-/* receive channel control */
+-#define	D64_RC_RE		0x00000001	/* receive enable */
+-#define	D64_RC_RO_MASK		0x000000fe	/* receive frame offset */
+-#define	D64_RC_RO_SHIFT		1
+-#define	D64_RC_FM		0x00000100	/* direct fifo receive (pio) mode */
+-#define	D64_RC_SH		0x00000200	/* separate rx header descriptor enable */
+-#define	D64_RC_OC		0x00000400	/* overflow continue */
+-#define	D64_RC_PD		0x00000800	/* parity check disable */
+-#define	D64_RC_AE		0x00030000	/* address extension bits */
+-#define	D64_RC_AE_SHIFT		16
+-
+-/* flags for dma controller */
+-#define DMA_CTRL_PEN		(1 << 0)	/* partity enable */
+-#define DMA_CTRL_ROC		(1 << 1)	/* rx overflow continue */
+-#define DMA_CTRL_RXMULTI	(1 << 2)	/* allow rx scatter to multiple descriptors */
+-#define DMA_CTRL_UNFRAMED	(1 << 3)	/* Unframed Rx/Tx data */
+-
+-/* receive descriptor table pointer */
+-#define	D64_RP_LD_MASK		0x00000fff	/* last valid descriptor */
+-
+-/* receive channel status */
+-#define	D64_RS0_CD_MASK		0x00001fff	/* current descriptor pointer */
+-#define	D64_RS0_RS_MASK		0xf0000000	/* receive state */
+-#define	D64_RS0_RS_SHIFT		28
+-#define	D64_RS0_RS_DISABLED	0x00000000	/* disabled */
+-#define	D64_RS0_RS_ACTIVE	0x10000000	/* active */
+-#define	D64_RS0_RS_IDLE		0x20000000	/* idle wait */
+-#define	D64_RS0_RS_STOPPED	0x30000000	/* stopped */
+-#define	D64_RS0_RS_SUSP		0x40000000	/* suspend pending */
+-
+-#define	D64_RS1_AD_MASK		0x0001ffff	/* active descriptor */
+-#define	D64_RS1_RE_MASK		0xf0000000	/* receive errors */
+-#define	D64_RS1_RE_SHIFT		28
+-#define	D64_RS1_RE_NOERR	0x00000000	/* no error */
+-#define	D64_RS1_RE_DPO		0x10000000	/* descriptor protocol error */
+-#define	D64_RS1_RE_DFU		0x20000000	/* data fifo overflow */
+-#define	D64_RS1_RE_DTE		0x30000000	/* data transfer error */
+-#define	D64_RS1_RE_DESRE	0x40000000	/* descriptor read error */
+-#define	D64_RS1_RE_COREE	0x50000000	/* core error */
+-
+-/* fifoaddr */
+-#define	D64_FA_OFF_MASK		0xffff	/* offset */
+-#define	D64_FA_SEL_MASK		0xf0000	/* select */
+-#define	D64_FA_SEL_SHIFT	16
+-#define	D64_FA_SEL_XDD		0x00000	/* transmit dma data */
+-#define	D64_FA_SEL_XDP		0x10000	/* transmit dma pointers */
+-#define	D64_FA_SEL_RDD		0x40000	/* receive dma data */
+-#define	D64_FA_SEL_RDP		0x50000	/* receive dma pointers */
+-#define	D64_FA_SEL_XFD		0x80000	/* transmit fifo data */
+-#define	D64_FA_SEL_XFP		0x90000	/* transmit fifo pointers */
+-#define	D64_FA_SEL_RFD		0xc0000	/* receive fifo data */
+-#define	D64_FA_SEL_RFP		0xd0000	/* receive fifo pointers */
+-#define	D64_FA_SEL_RSD		0xe0000	/* receive frame status data */
+-#define	D64_FA_SEL_RSP		0xf0000	/* receive frame status pointers */
+-
+-/* descriptor control flags 1 */
+-#define D64_CTRL_COREFLAGS	0x0ff00000	/* core specific flags */
+-#define	D64_CTRL1_EOT		((u32)1 << 28)	/* end of descriptor table */
+-#define	D64_CTRL1_IOC		((u32)1 << 29)	/* interrupt on completion */
+-#define	D64_CTRL1_EOF		((u32)1 << 30)	/* end of frame */
+-#define	D64_CTRL1_SOF		((u32)1 << 31)	/* start of frame */
+-
+-/* descriptor control flags 2 */
+-#define	D64_CTRL2_BC_MASK	0x00007fff	/* buffer byte count. real data len must <= 16KB */
+-#define	D64_CTRL2_AE		0x00030000	/* address extension bits */
+-#define	D64_CTRL2_AE_SHIFT	16
+-#define D64_CTRL2_PARITY	0x00040000	/* parity bit */
+-
+-/* control flags in the range [27:20] are core-specific and not defined here */
+-#define	D64_CTRL_CORE_MASK	0x0ff00000
+-
+-#define D64_RX_FRM_STS_LEN	0x0000ffff	/* frame length mask */
+-#define D64_RX_FRM_STS_OVFL	0x00800000	/* RxOverFlow */
+-#define D64_RX_FRM_STS_DSCRCNT	0x0f000000  /* no. of descriptors used - 1 */
+-#define D64_RX_FRM_STS_DATATYPE	0xf0000000	/* core-dependent data type */
+-
+-/* receive frame status */
+-typedef volatile struct {
+-	u16 len;
+-	u16 flags;
+-} dma_rxh_t;
+-
+-#endif				/* _sbhnddma_h_ */
+diff --git a/drivers/staging/brcm80211/include/sbsdio.h b/drivers/staging/brcm80211/include/sbsdio.h
+deleted file mode 100644
+index c7facd3..0000000
+--- a/drivers/staging/brcm80211/include/sbsdio.h
++++ /dev/null
+@@ -1,152 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SBSDIO_H
+-#define	_SBSDIO_H
+-
+-#define SBSDIO_NUM_FUNCTION		3	/* as of sdiod rev 0, supports 3 functions */
+-
+-/* function 1 miscellaneous registers */
+-#define SBSDIO_SPROM_CS			0x10000	/* sprom command and status */
+-#define SBSDIO_SPROM_INFO		0x10001	/* sprom info register */
+-#define SBSDIO_SPROM_DATA_LOW		0x10002	/* sprom indirect access data byte 0 */
+-#define SBSDIO_SPROM_DATA_HIGH		0x10003	/* sprom indirect access data byte 1 */
+-#define SBSDIO_SPROM_ADDR_LOW		0x10004	/* sprom indirect access addr byte 0 */
+-#define SBSDIO_SPROM_ADDR_HIGH		0x10005	/* sprom indirect access addr byte 0 */
+-#define SBSDIO_CHIP_CTRL_DATA		0x10006	/* xtal_pu (gpio) output */
+-#define SBSDIO_CHIP_CTRL_EN		0x10007	/* xtal_pu (gpio) enable */
+-#define SBSDIO_WATERMARK		0x10008	/* rev < 7, watermark for sdio device */
+-#define SBSDIO_DEVICE_CTL		0x10009	/* control busy signal generation */
+-
+-/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */
+-#define SBSDIO_FUNC1_SBADDRLOW		0x1000A	/* SB Address Window Low (b15) */
+-#define SBSDIO_FUNC1_SBADDRMID		0x1000B	/* SB Address Window Mid (b23:b16) */
+-#define SBSDIO_FUNC1_SBADDRHIGH		0x1000C	/* SB Address Window High (b31:b24)    */
+-#define SBSDIO_FUNC1_FRAMECTRL		0x1000D	/* Frame Control (frame term/abort) */
+-#define SBSDIO_FUNC1_CHIPCLKCSR		0x1000E	/* ChipClockCSR (ALP/HT ctl/status) */
+-#define SBSDIO_FUNC1_SDIOPULLUP 	0x1000F	/* SdioPullUp (on cmd, d0-d2) */
+-#define SBSDIO_FUNC1_WFRAMEBCLO		0x10019	/* Write Frame Byte Count Low */
+-#define SBSDIO_FUNC1_WFRAMEBCHI		0x1001A	/* Write Frame Byte Count High */
+-#define SBSDIO_FUNC1_RFRAMEBCLO		0x1001B	/* Read Frame Byte Count Low */
+-#define SBSDIO_FUNC1_RFRAMEBCHI		0x1001C	/* Read Frame Byte Count High */
+-
+-#define SBSDIO_FUNC1_MISC_REG_START	0x10000	/* f1 misc register start */
+-#define SBSDIO_FUNC1_MISC_REG_LIMIT	0x1001C	/* f1 misc register end */
+-
+-/* SBSDIO_SPROM_CS */
+-#define SBSDIO_SPROM_IDLE		0
+-#define SBSDIO_SPROM_WRITE		1
+-#define SBSDIO_SPROM_READ		2
+-#define SBSDIO_SPROM_WEN		4
+-#define SBSDIO_SPROM_WDS		7
+-#define SBSDIO_SPROM_DONE		8
+-
+-/* SBSDIO_SPROM_INFO */
+-#define SROM_SZ_MASK			0x03	/* SROM size, 1: 4k, 2: 16k */
+-#define SROM_BLANK			0x04	/* depreciated in corerev 6 */
+-#define	SROM_OTP			0x80	/* OTP present */
+-
+-/* SBSDIO_CHIP_CTRL */
+-#define SBSDIO_CHIP_CTRL_XTAL		0x01	/* or'd with onchip xtal_pu,
+-						 * 1: power on oscillator
+-						 * (for 4318 only)
+-						 */
+-/* SBSDIO_WATERMARK */
+-#define SBSDIO_WATERMARK_MASK		0x7f	/* number of words - 1 for sd device
+-						 * to wait before sending data to host
+-						 */
+-
+-/* SBSDIO_DEVICE_CTL */
+-#define SBSDIO_DEVCTL_SETBUSY		0x01	/* 1: device will assert busy signal when
+-						 * receiving CMD53
+-						 */
+-#define SBSDIO_DEVCTL_SPI_INTR_SYNC	0x02	/* 1: assertion of sdio interrupt is
+-						 * synchronous to the sdio clock
+-						 */
+-#define SBSDIO_DEVCTL_CA_INT_ONLY	0x04	/* 1: mask all interrupts to host
+-						 * except the chipActive (rev 8)
+-						 */
+-#define SBSDIO_DEVCTL_PADS_ISO		0x08	/* 1: isolate internal sdio signals, put
+-						 * external pads in tri-state; requires
+-						 * sdio bus power cycle to clear (rev 9)
+-						 */
+-#define SBSDIO_DEVCTL_SB_RST_CTL	0x30	/* Force SD->SB reset mapping (rev 11) */
+-#define SBSDIO_DEVCTL_RST_CORECTL	0x00	/*   Determined by CoreControl bit */
+-#define SBSDIO_DEVCTL_RST_BPRESET	0x10	/*   Force backplane reset */
+-#define SBSDIO_DEVCTL_RST_NOBPRESET	0x20	/*   Force no backplane reset */
+-
+-/* SBSDIO_FUNC1_CHIPCLKCSR */
+-#define SBSDIO_FORCE_ALP		0x01	/* Force ALP request to backplane */
+-#define SBSDIO_FORCE_HT			0x02	/* Force HT request to backplane */
+-#define SBSDIO_FORCE_ILP		0x04	/* Force ILP request to backplane */
+-#define SBSDIO_ALP_AVAIL_REQ		0x08	/* Make ALP ready (power up xtal) */
+-#define SBSDIO_HT_AVAIL_REQ		0x10	/* Make HT ready (power up PLL) */
+-#define SBSDIO_FORCE_HW_CLKREQ_OFF	0x20	/* Squelch clock requests from HW */
+-#define SBSDIO_ALP_AVAIL		0x40	/* Status: ALP is ready */
+-#define SBSDIO_HT_AVAIL			0x80	/* Status: HT is ready */
+-/* In rev8, actual avail bits followed original docs */
+-#define SBSDIO_Rev8_HT_AVAIL		0x40
+-#define SBSDIO_Rev8_ALP_AVAIL		0x80
+-
+-#define SBSDIO_AVBITS			(SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)
+-#define SBSDIO_ALPAV(regval)		((regval) & SBSDIO_AVBITS)
+-#define SBSDIO_HTAV(regval)		(((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
+-#define SBSDIO_ALPONLY(regval)		(SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval))
+-#define SBSDIO_CLKAV(regval, alponly)	(SBSDIO_ALPAV(regval) && \
+-					(alponly ? 1 : SBSDIO_HTAV(regval)))
+-
+-/* SBSDIO_FUNC1_SDIOPULLUP */
+-#define SBSDIO_PULLUP_D0		0x01	/* Enable D0/MISO pullup */
+-#define SBSDIO_PULLUP_D1		0x02	/* Enable D1/INT# pullup */
+-#define SBSDIO_PULLUP_D2		0x04	/* Enable D2 pullup */
+-#define SBSDIO_PULLUP_CMD		0x08	/* Enable CMD/MOSI pullup */
+-#define SBSDIO_PULLUP_ALL		0x0f	/* All valid bits */
+-
+-/* function 1 OCP space */
+-#define SBSDIO_SB_OFT_ADDR_MASK		0x07FFF	/* sb offset addr is <= 15 bits, 32k */
+-#define SBSDIO_SB_OFT_ADDR_LIMIT	0x08000
+-#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x08000	/* with b15, maps to 32-bit SB access */
+-
+-/* some duplication with sbsdpcmdev.h here */
+-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+-#define SBSDIO_SBADDRLOW_MASK		0x80	/* Valid bits in SBADDRLOW */
+-#define SBSDIO_SBADDRMID_MASK		0xff	/* Valid bits in SBADDRMID */
+-#define SBSDIO_SBADDRHIGH_MASK		0xffU	/* Valid bits in SBADDRHIGH */
+-#define SBSDIO_SBWINDOW_MASK		0xffff8000	/* Address bits from SBADDR regs */
+-
+-/* direct(mapped) cis space */
+-#define SBSDIO_CIS_BASE_COMMON		0x1000	/* MAPPED common CIS address */
+-#define SBSDIO_CIS_SIZE_LIMIT		0x200	/* maximum bytes in one CIS */
+-#define SBSDIO_OTP_CIS_SIZE_LIMIT       0x078	/* maximum bytes OTP CIS */
+-
+-#define SBSDIO_CIS_OFT_ADDR_MASK	0x1FFFF	/* cis offset addr is < 17 bits */
+-
+-#define SBSDIO_CIS_MANFID_TUPLE_LEN	6	/* manfid tuple length, include tuple,
+-						 * link bytes
+-						 */
+-
+-/* indirect cis access (in sprom) */
+-#define SBSDIO_SPROM_CIS_OFFSET		0x8	/* 8 control bytes first, CIS starts from
+-						 * 8th byte
+-						 */
+-
+-#define SBSDIO_BYTEMODE_DATALEN_MAX	64	/* sdio byte mode: maximum length of one
+-						 * data command
+-						 */
+-
+-#define SBSDIO_CORE_ADDR_MASK		0x1FFFF	/* sdio core function one address mask */
+-
+-#endif				/* _SBSDIO_H */
+diff --git a/drivers/staging/brcm80211/include/sbsdpcmdev.h b/drivers/staging/brcm80211/include/sbsdpcmdev.h
+deleted file mode 100644
+index afd3581..0000000
+--- a/drivers/staging/brcm80211/include/sbsdpcmdev.h
++++ /dev/null
+@@ -1,281 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_sbsdpcmdev_h_
+-#define	_sbsdpcmdev_h_
+-
+-/* cpp contortions to concatenate w/arg prescan */
+-#ifndef PAD
+-#define	_PADLINE(line)	pad ## line
+-#define	_XSTR(line)	_PADLINE(line)
+-#define	PAD		_XSTR(__LINE__)
+-#endif				/* PAD */
+-
+-typedef volatile struct {
+-	dma64regs_t xmt;	/* dma tx */
+-	u32 PAD[2];
+-	dma64regs_t rcv;	/* dma rx */
+-	u32 PAD[2];
+-} dma64p_t;
+-
+-/* dma64 sdiod corerev >= 1 */
+-typedef volatile struct {
+-	dma64p_t dma64regs[2];
+-	dma64diag_t dmafifo;	/* DMA Diagnostic Regs, 0x280-0x28c */
+-	u32 PAD[92];
+-} sdiodma64_t;
+-
+-/* dma32 sdiod corerev == 0 */
+-typedef volatile struct {
+-	dma32regp_t dma32regs[2];	/* dma tx & rx, 0x200-0x23c */
+-	dma32diag_t dmafifo;	/* DMA Diagnostic Regs, 0x240-0x24c */
+-	u32 PAD[108];
+-} sdiodma32_t;
+-
+-/* dma32 regs for pcmcia core */
+-typedef volatile struct {
+-	dma32regp_t dmaregs;	/* DMA Regs, 0x200-0x21c, rev8 */
+-	dma32diag_t dmafifo;	/* DMA Diagnostic Regs, 0x220-0x22c */
+-	u32 PAD[116];
+-} pcmdma32_t;
+-
+-/* core registers */
+-typedef volatile struct {
+-	u32 corecontrol;	/* CoreControl, 0x000, rev8 */
+-	u32 corestatus;	/* CoreStatus, 0x004, rev8  */
+-	u32 PAD[1];
+-	u32 biststatus;	/* BistStatus, 0x00c, rev8  */
+-
+-	/* PCMCIA access */
+-	u16 pcmciamesportaladdr;	/* PcmciaMesPortalAddr, 0x010, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciamesportalmask;	/* PcmciaMesPortalMask, 0x014, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciawrframebc;	/* PcmciaWrFrameBC, 0x018, rev8   */
+-	u16 PAD[1];
+-	u16 pcmciaunderflowtimer;	/* PcmciaUnderflowTimer, 0x01c, rev8   */
+-	u16 PAD[1];
+-
+-	/* interrupt */
+-	u32 intstatus;	/* IntStatus, 0x020, rev8   */
+-	u32 hostintmask;	/* IntHostMask, 0x024, rev8   */
+-	u32 intmask;		/* IntSbMask, 0x028, rev8   */
+-	u32 sbintstatus;	/* SBIntStatus, 0x02c, rev8   */
+-	u32 sbintmask;	/* SBIntMask, 0x030, rev8   */
+-	u32 funcintmask;	/* SDIO Function Interrupt Mask, SDIO rev4 */
+-	u32 PAD[2];
+-	u32 tosbmailbox;	/* ToSBMailbox, 0x040, rev8   */
+-	u32 tohostmailbox;	/* ToHostMailbox, 0x044, rev8   */
+-	u32 tosbmailboxdata;	/* ToSbMailboxData, 0x048, rev8   */
+-	u32 tohostmailboxdata;	/* ToHostMailboxData, 0x04c, rev8   */
+-
+-	/* synchronized access to registers in SDIO clock domain */
+-	u32 sdioaccess;	/* SdioAccess, 0x050, rev8   */
+-	u32 PAD[3];
+-
+-	/* PCMCIA frame control */
+-	u8 pcmciaframectrl;	/* pcmciaFrameCtrl, 0x060, rev8   */
+-	u8 PAD[3];
+-	u8 pcmciawatermark;	/* pcmciaWaterMark, 0x064, rev8   */
+-	u8 PAD[155];
+-
+-	/* interrupt batching control */
+-	u32 intrcvlazy;	/* IntRcvLazy, 0x100, rev8 */
+-	u32 PAD[3];
+-
+-	/* counters */
+-	u32 cmd52rd;		/* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */
+-	u32 cmd52wr;		/* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */
+-	u32 cmd53rd;		/* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */
+-	u32 cmd53wr;		/* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */
+-	u32 abort;		/* AbortCount, 0x120, rev8, SDIO: aborts */
+-	u32 datacrcerror;	/* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */
+-	u32 rdoutofsync;	/* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */
+-	u32 wroutofsync;	/* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */
+-	u32 writebusy;	/* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */
+-	u32 readwait;	/* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */
+-	u32 readterm;	/* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */
+-	u32 writeterm;	/* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */
+-	u32 PAD[40];
+-	u32 clockctlstatus;	/* ClockCtlStatus, 0x1e0, rev8 */
+-	u32 PAD[7];
+-
+-	/* DMA engines */
+-	volatile union {
+-		pcmdma32_t pcm32;
+-		sdiodma32_t sdiod32;
+-		sdiodma64_t sdiod64;
+-	} dma;
+-
+-	/* SDIO/PCMCIA CIS region */
+-	char cis[512];		/* 512 byte CIS, 0x400-0x5ff, rev6 */
+-
+-	/* PCMCIA function control registers */
+-	char pcmciafcr[256];	/* PCMCIA FCR, 0x600-6ff, rev6 */
+-	u16 PAD[55];
+-
+-	/* PCMCIA backplane access */
+-	u16 backplanecsr;	/* BackplaneCSR, 0x76E, rev6 */
+-	u16 backplaneaddr0;	/* BackplaneAddr0, 0x770, rev6 */
+-	u16 backplaneaddr1;	/* BackplaneAddr1, 0x772, rev6 */
+-	u16 backplaneaddr2;	/* BackplaneAddr2, 0x774, rev6 */
+-	u16 backplaneaddr3;	/* BackplaneAddr3, 0x776, rev6 */
+-	u16 backplanedata0;	/* BackplaneData0, 0x778, rev6 */
+-	u16 backplanedata1;	/* BackplaneData1, 0x77a, rev6 */
+-	u16 backplanedata2;	/* BackplaneData2, 0x77c, rev6 */
+-	u16 backplanedata3;	/* BackplaneData3, 0x77e, rev6 */
+-	u16 PAD[31];
+-
+-	/* sprom "size" & "blank" info */
+-	u16 spromstatus;	/* SPROMStatus, 0x7BE, rev2 */
+-	u32 PAD[464];
+-
+-	/* Sonics SiliconBackplane registers */
+-	sbconfig_t sbconfig;	/* SbConfig Regs, 0xf00-0xfff, rev8 */
+-} sdpcmd_regs_t;
+-
+-/* corecontrol */
+-#define CC_CISRDY		(1 << 0)	/* CIS Ready */
+-#define CC_BPRESEN		(1 << 1)	/* CCCR RES signal causes backplane reset */
+-#define CC_F2RDY		(1 << 2)	/* set CCCR IOR2 bit */
+-#define CC_CLRPADSISO		(1 << 3)	/* clear SDIO pads isolation bit (rev 11) */
+-#define CC_XMTDATAAVAIL_MODE	(1 << 4)	/* data avail generates an interrupt */
+-#define CC_XMTDATAAVAIL_CTRL	(1 << 5)	/* data avail interrupt ctrl */
+-
+-/* corestatus */
+-#define CS_PCMCIAMODE	(1 << 0)	/* Device Mode; 0=SDIO, 1=PCMCIA */
+-#define CS_SMARTDEV	(1 << 1)	/* 1=smartDev enabled */
+-#define CS_F2ENABLED	(1 << 2)	/* 1=host has enabled the device */
+-
+-#define PCMCIA_MES_PA_MASK	0x7fff	/* PCMCIA Message Portal Address Mask */
+-#define PCMCIA_MES_PM_MASK	0x7fff	/* PCMCIA Message Portal Mask Mask */
+-#define PCMCIA_WFBC_MASK	0xffff	/* PCMCIA Write Frame Byte Count Mask */
+-#define PCMCIA_UT_MASK		0x07ff	/* PCMCIA Underflow Timer Mask */
+-
+-/* intstatus */
+-#define I_SMB_SW0	(1 << 0)	/* To SB Mail S/W interrupt 0 */
+-#define I_SMB_SW1	(1 << 1)	/* To SB Mail S/W interrupt 1 */
+-#define I_SMB_SW2	(1 << 2)	/* To SB Mail S/W interrupt 2 */
+-#define I_SMB_SW3	(1 << 3)	/* To SB Mail S/W interrupt 3 */
+-#define I_SMB_SW_MASK	0x0000000f	/* To SB Mail S/W interrupts mask */
+-#define I_SMB_SW_SHIFT	0	/* To SB Mail S/W interrupts shift */
+-#define I_HMB_SW0	(1 << 4)	/* To Host Mail S/W interrupt 0 */
+-#define I_HMB_SW1	(1 << 5)	/* To Host Mail S/W interrupt 1 */
+-#define I_HMB_SW2	(1 << 6)	/* To Host Mail S/W interrupt 2 */
+-#define I_HMB_SW3	(1 << 7)	/* To Host Mail S/W interrupt 3 */
+-#define I_HMB_SW_MASK	0x000000f0	/* To Host Mail S/W interrupts mask */
+-#define I_HMB_SW_SHIFT	4	/* To Host Mail S/W interrupts shift */
+-#define I_WR_OOSYNC	(1 << 8)	/* Write Frame Out Of Sync */
+-#define I_RD_OOSYNC	(1 << 9)	/* Read Frame Out Of Sync */
+-#define	I_PC		(1 << 10)	/* descriptor error */
+-#define	I_PD		(1 << 11)	/* data error */
+-#define	I_DE		(1 << 12)	/* Descriptor protocol Error */
+-#define	I_RU		(1 << 13)	/* Receive descriptor Underflow */
+-#define	I_RO		(1 << 14)	/* Receive fifo Overflow */
+-#define	I_XU		(1 << 15)	/* Transmit fifo Underflow */
+-#define	I_RI		(1 << 16)	/* Receive Interrupt */
+-#define I_BUSPWR	(1 << 17)	/* SDIO Bus Power Change (rev 9) */
+-#define I_XMTDATA_AVAIL (1 << 23)	/* bits in fifo */
+-#define	I_XI		(1 << 24)	/* Transmit Interrupt */
+-#define I_RF_TERM	(1 << 25)	/* Read Frame Terminate */
+-#define I_WF_TERM	(1 << 26)	/* Write Frame Terminate */
+-#define I_PCMCIA_XU	(1 << 27)	/* PCMCIA Transmit FIFO Underflow */
+-#define I_SBINT		(1 << 28)	/* sbintstatus Interrupt */
+-#define I_CHIPACTIVE	(1 << 29)	/* chip transitioned from doze to active state */
+-#define I_SRESET	(1 << 30)	/* CCCR RES interrupt */
+-#define I_IOE2		(1U << 31)	/* CCCR IOE2 Bit Changed */
+-#define	I_ERRORS	(I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)	/* DMA Errors */
+-#define I_DMA		(I_RI | I_XI | I_ERRORS)
+-
+-/* sbintstatus */
+-#define I_SB_SERR	(1 << 8)	/* Backplane SError (write) */
+-#define I_SB_RESPERR	(1 << 9)	/* Backplane Response Error (read) */
+-#define I_SB_SPROMERR	(1 << 10)	/* Error accessing the sprom */
+-
+-/* sdioaccess */
+-#define SDA_DATA_MASK	0x000000ff	/* Read/Write Data Mask */
+-#define SDA_ADDR_MASK	0x000fff00	/* Read/Write Address Mask */
+-#define SDA_ADDR_SHIFT	8	/* Read/Write Address Shift */
+-#define SDA_WRITE	0x01000000	/* Write bit  */
+-#define SDA_READ	0x00000000	/* Write bit cleared for Read */
+-#define SDA_BUSY	0x80000000	/* Busy bit */
+-
+-/* sdioaccess-accessible register address spaces */
+-#define SDA_CCCR_SPACE		0x000	/* sdioAccess CCCR register space */
+-#define SDA_F1_FBR_SPACE	0x100	/* sdioAccess F1 FBR register space */
+-#define SDA_F2_FBR_SPACE	0x200	/* sdioAccess F2 FBR register space */
+-#define SDA_F1_REG_SPACE	0x300	/* sdioAccess F1 core-specific register space */
+-
+-/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */
+-#define SDA_CHIPCONTROLDATA	0x006	/* ChipControlData */
+-#define SDA_CHIPCONTROLENAB	0x007	/* ChipControlEnable */
+-#define SDA_F2WATERMARK		0x008	/* Function 2 Watermark */
+-#define SDA_DEVICECONTROL	0x009	/* DeviceControl */
+-#define SDA_SBADDRLOW		0x00a	/* SbAddrLow */
+-#define SDA_SBADDRMID		0x00b	/* SbAddrMid */
+-#define SDA_SBADDRHIGH		0x00c	/* SbAddrHigh */
+-#define SDA_FRAMECTRL		0x00d	/* FrameCtrl */
+-#define SDA_CHIPCLOCKCSR	0x00e	/* ChipClockCSR */
+-#define SDA_SDIOPULLUP		0x00f	/* SdioPullUp */
+-#define SDA_SDIOWRFRAMEBCLOW	0x019	/* SdioWrFrameBCLow */
+-#define SDA_SDIOWRFRAMEBCHIGH	0x01a	/* SdioWrFrameBCHigh */
+-#define SDA_SDIORDFRAMEBCLOW	0x01b	/* SdioRdFrameBCLow */
+-#define SDA_SDIORDFRAMEBCHIGH	0x01c	/* SdioRdFrameBCHigh */
+-
+-/* SDA_F2WATERMARK */
+-#define SDA_F2WATERMARK_MASK	0x7f	/* F2Watermark Mask */
+-
+-/* SDA_SBADDRLOW */
+-#define SDA_SBADDRLOW_MASK	0x80	/* SbAddrLow Mask */
+-
+-/* SDA_SBADDRMID */
+-#define SDA_SBADDRMID_MASK	0xff	/* SbAddrMid Mask */
+-
+-/* SDA_SBADDRHIGH */
+-#define SDA_SBADDRHIGH_MASK	0xff	/* SbAddrHigh Mask */
+-
+-/* SDA_FRAMECTRL */
+-#define SFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
+-#define SFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
+-#define SFC_CRC4WOOS	(1 << 2)	/* HW reports CRC error for write out of sync */
+-#define SFC_ABORTALL	(1 << 3)	/* Abort cancels all in-progress frames */
+-
+-/* pcmciaframectrl */
+-#define PFC_RF_TERM	(1 << 0)	/* Read Frame Terminate */
+-#define PFC_WF_TERM	(1 << 1)	/* Write Frame Terminate */
+-
+-/* intrcvlazy */
+-#define	IRL_TO_MASK	0x00ffffff	/* timeout */
+-#define	IRL_FC_MASK	0xff000000	/* frame count */
+-#define	IRL_FC_SHIFT	24	/* frame count */
+-
+-/* rx header */
+-typedef volatile struct {
+-	u16 len;
+-	u16 flags;
+-} sdpcmd_rxh_t;
+-
+-/* rx header flags */
+-#define RXF_CRC		0x0001	/* CRC error detected */
+-#define RXF_WOOS	0x0002	/* write frame out of sync */
+-#define RXF_WF_TERM	0x0004	/* write frame terminated */
+-#define RXF_ABORT	0x0008	/* write frame aborted */
+-#define RXF_DISCARD	(RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT)	/* bad frame */
+-
+-/* HW frame tag */
+-#define SDPCM_FRAMETAG_LEN	4	/* HW frametag: 2 bytes len, 2 bytes check val */
+-
+-#endif				/* _sbsdpcmdev_h_ */
+diff --git a/drivers/staging/brcm80211/include/sdio.h b/drivers/staging/brcm80211/include/sdio.h
+deleted file mode 100644
+index 670e379..0000000
+--- a/drivers/staging/brcm80211/include/sdio.h
++++ /dev/null
+@@ -1,552 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef	_SDIO_H
+-#define	_SDIO_H
+-
+-#ifdef BCMSDIO
+-
+-/* CCCR structure for function 0 */
+-typedef volatile struct {
+-	u8 cccr_sdio_rev;	/* RO, cccr and sdio revision */
+-	u8 sd_rev;		/* RO, sd spec revision */
+-	u8 io_en;		/* I/O enable */
+-	u8 io_rdy;		/* I/O ready reg */
+-	u8 intr_ctl;		/* Master and per function interrupt enable control */
+-	u8 intr_status;	/* RO, interrupt pending status */
+-	u8 io_abort;		/* read/write abort or reset all functions */
+-	u8 bus_inter;	/* bus interface control */
+-	u8 capability;	/* RO, card capability */
+-
+-	u8 cis_base_low;	/* 0x9 RO, common CIS base address, LSB */
+-	u8 cis_base_mid;
+-	u8 cis_base_high;	/* 0xB RO, common CIS base address, MSB */
+-
+-	/* suspend/resume registers */
+-	u8 bus_suspend;	/* 0xC */
+-	u8 func_select;	/* 0xD */
+-	u8 exec_flag;	/* 0xE */
+-	u8 ready_flag;	/* 0xF */
+-
+-	u8 fn0_blk_size[2];	/* 0x10(LSB), 0x11(MSB) */
+-
+-	u8 power_control;	/* 0x12 (SDIO version 1.10) */
+-
+-	u8 speed_control;	/* 0x13 */
+-} sdio_regs_t;
+-
+-/* SDIO Device CCCR offsets */
+-#define SDIOD_CCCR_REV			0x00
+-#define SDIOD_CCCR_SDREV		0x01
+-#define SDIOD_CCCR_IOEN			0x02
+-#define SDIOD_CCCR_IORDY		0x03
+-#define SDIOD_CCCR_INTEN		0x04
+-#define SDIOD_CCCR_INTPEND		0x05
+-#define SDIOD_CCCR_IOABORT		0x06
+-#define SDIOD_CCCR_BICTRL		0x07
+-#define SDIOD_CCCR_CAPABLITIES		0x08
+-#define SDIOD_CCCR_CISPTR_0		0x09
+-#define SDIOD_CCCR_CISPTR_1		0x0A
+-#define SDIOD_CCCR_CISPTR_2		0x0B
+-#define SDIOD_CCCR_BUSSUSP		0x0C
+-#define SDIOD_CCCR_FUNCSEL		0x0D
+-#define SDIOD_CCCR_EXECFLAGS		0x0E
+-#define SDIOD_CCCR_RDYFLAGS		0x0F
+-#define SDIOD_CCCR_BLKSIZE_0		0x10
+-#define SDIOD_CCCR_BLKSIZE_1		0x11
+-#define SDIOD_CCCR_POWER_CONTROL	0x12
+-#define SDIOD_CCCR_SPEED_CONTROL	0x13
+-
+-/* Broadcom extensions (corerev >= 1) */
+-#define SDIOD_CCCR_BRCM_SEPINT		0xf2
+-
+-/* cccr_sdio_rev */
+-#define SDIO_REV_SDIOID_MASK	0xf0	/* SDIO spec revision number */
+-#define SDIO_REV_CCCRID_MASK	0x0f	/* CCCR format version number */
+-
+-/* sd_rev */
+-#define SD_REV_PHY_MASK		0x0f	/* SD format version number */
+-
+-/* io_en */
+-#define SDIO_FUNC_ENABLE_1	0x02	/* function 1 I/O enable */
+-#define SDIO_FUNC_ENABLE_2	0x04	/* function 2 I/O enable */
+-
+-/* io_rdys */
+-#define SDIO_FUNC_READY_1	0x02	/* function 1 I/O ready */
+-#define SDIO_FUNC_READY_2	0x04	/* function 2 I/O ready */
+-
+-/* intr_ctl */
+-#define INTR_CTL_MASTER_EN	0x1	/* interrupt enable master */
+-#define INTR_CTL_FUNC1_EN	0x2	/* interrupt enable for function 1 */
+-#define INTR_CTL_FUNC2_EN	0x4	/* interrupt enable for function 2 */
+-
+-/* intr_status */
+-#define INTR_STATUS_FUNC1	0x2	/* interrupt pending for function 1 */
+-#define INTR_STATUS_FUNC2	0x4	/* interrupt pending for function 2 */
+-
+-/* io_abort */
+-#define IO_ABORT_RESET_ALL	0x08	/* I/O card reset */
+-#define IO_ABORT_FUNC_MASK	0x07	/* abort selction: function x */
+-
+-/* bus_inter */
+-#define BUS_CARD_DETECT_DIS	0x80	/* Card Detect disable */
+-#define BUS_SPI_CONT_INTR_CAP	0x40	/* support continuous SPI interrupt */
+-#define BUS_SPI_CONT_INTR_EN	0x20	/* continuous SPI interrupt enable */
+-#define BUS_SD_DATA_WIDTH_MASK	0x03	/* bus width mask */
+-#define BUS_SD_DATA_WIDTH_4BIT	0x02	/* bus width 4-bit mode */
+-#define BUS_SD_DATA_WIDTH_1BIT	0x00	/* bus width 1-bit mode */
+-
+-/* capability */
+-#define SDIO_CAP_4BLS		0x80	/* 4-bit support for low speed card */
+-#define SDIO_CAP_LSC		0x40	/* low speed card */
+-#define SDIO_CAP_E4MI		0x20	/* enable interrupt between block of data in 4-bit mode */
+-#define SDIO_CAP_S4MI		0x10	/* support interrupt between block of data in 4-bit mode */
+-#define SDIO_CAP_SBS		0x08	/* support suspend/resume */
+-#define SDIO_CAP_SRW		0x04	/* support read wait */
+-#define SDIO_CAP_SMB		0x02	/* support multi-block transfer */
+-#define SDIO_CAP_SDC		0x01	/* Support Direct commands during multi-byte transfer */
+-
+-/* power_control */
+-#define SDIO_POWER_SMPC		0x01	/* supports master power control (RO) */
+-#define SDIO_POWER_EMPC		0x02	/* enable master power control (allow > 200mA) (RW) */
+-
+-/* speed_control (control device entry into high-speed clocking mode) */
+-#define SDIO_SPEED_SHS		0x01	/* supports high-speed [clocking] mode (RO) */
+-#define SDIO_SPEED_EHS		0x02	/* enable high-speed [clocking] mode (RW) */
+-
+-/* brcm sepint */
+-#define SDIO_SEPINT_MASK	0x01	/* route sdpcmdev intr onto separate pad (chip-specific) */
+-#define SDIO_SEPINT_OE		0x02	/* 1 asserts output enable for above pad */
+-#define SDIO_SEPINT_ACT_HI	0x04	/* use active high interrupt level instead of active low */
+-
+-/* FBR structure for function 1-7, FBR addresses and register offsets */
+-typedef volatile struct {
+-	u8 devctr;		/* device interface, CSA control */
+-	u8 ext_dev;		/* extended standard I/O device type code */
+-	u8 pwr_sel;		/* power selection support */
+-	u8 PAD[6];		/* reserved */
+-
+-	u8 cis_low;		/* CIS LSB */
+-	u8 cis_mid;
+-	u8 cis_high;		/* CIS MSB */
+-	u8 csa_low;		/* code storage area, LSB */
+-	u8 csa_mid;
+-	u8 csa_high;		/* code storage area, MSB */
+-	u8 csa_dat_win;	/* data access window to function */
+-
+-	u8 fnx_blk_size[2];	/* block size, little endian */
+-} sdio_fbr_t;
+-
+-/* Maximum number of I/O funcs */
+-#define SDIOD_MAX_IOFUNCS		7
+-
+-/* SDIO Device FBR Start Address  */
+-#define SDIOD_FBR_STARTADDR		0x100
+-
+-/* SDIO Device FBR Size */
+-#define SDIOD_FBR_SIZE			0x100
+-
+-/* Macro to calculate FBR register base */
+-#define SDIOD_FBR_BASE(n)		((n) * 0x100)
+-
+-/* Function register offsets */
+-#define SDIOD_FBR_DEVCTR		0x00	/* basic info for function */
+-#define SDIOD_FBR_EXT_DEV		0x01	/* extended I/O device code */
+-#define SDIOD_FBR_PWR_SEL		0x02	/* power selection bits */
+-
+-/* SDIO Function CIS ptr offset */
+-#define SDIOD_FBR_CISPTR_0		0x09
+-#define SDIOD_FBR_CISPTR_1		0x0A
+-#define SDIOD_FBR_CISPTR_2		0x0B
+-
+-/* Code Storage Area pointer */
+-#define SDIOD_FBR_CSA_ADDR_0		0x0C
+-#define SDIOD_FBR_CSA_ADDR_1		0x0D
+-#define SDIOD_FBR_CSA_ADDR_2		0x0E
+-#define SDIOD_FBR_CSA_DATA		0x0F
+-
+-/* SDIO Function I/O Block Size */
+-#define SDIOD_FBR_BLKSIZE_0		0x10
+-#define SDIOD_FBR_BLKSIZE_1		0x11
+-
+-/* devctr */
+-#define SDIOD_FBR_DEVCTR_DIC	0x0f	/* device interface code */
+-#define SDIOD_FBR_DECVTR_CSA	0x40	/* CSA support flag */
+-#define SDIOD_FBR_DEVCTR_CSA_EN	0x80	/* CSA enabled */
+-/* interface codes */
+-#define SDIOD_DIC_NONE		0	/* SDIO standard interface is not supported */
+-#define SDIOD_DIC_UART		1
+-#define SDIOD_DIC_BLUETOOTH_A	2
+-#define SDIOD_DIC_BLUETOOTH_B	3
+-#define SDIOD_DIC_GPS		4
+-#define SDIOD_DIC_CAMERA	5
+-#define SDIOD_DIC_PHS		6
+-#define SDIOD_DIC_WLAN		7
+-#define SDIOD_DIC_EXT		0xf	/* extended device interface, read ext_dev register */
+-
+-/* pwr_sel */
+-#define SDIOD_PWR_SEL_SPS	0x01	/* supports power selection */
+-#define SDIOD_PWR_SEL_EPS	0x02	/* enable power selection (low-current mode) */
+-
+-/* misc defines */
+-#define SDIO_FUNC_0		0
+-#define SDIO_FUNC_1		1
+-#define SDIO_FUNC_2		2
+-#define SDIO_FUNC_3		3
+-#define SDIO_FUNC_4		4
+-#define SDIO_FUNC_5		5
+-#define SDIO_FUNC_6		6
+-#define SDIO_FUNC_7		7
+-
+-#define SD_CARD_TYPE_UNKNOWN	0	/* bad type or unrecognized */
+-#define SD_CARD_TYPE_IO		1	/* IO only card */
+-#define SD_CARD_TYPE_MEMORY	2	/* memory only card */
+-#define SD_CARD_TYPE_COMBO	3	/* IO and memory combo card */
+-
+-#define SDIO_MAX_BLOCK_SIZE	2048	/* maximum block size for block mode operation */
+-#define SDIO_MIN_BLOCK_SIZE	1	/* minimum block size for block mode operation */
+-
+-/* Card registers: status bit position */
+-#define CARDREG_STATUS_BIT_OUTOFRANGE		31
+-#define CARDREG_STATUS_BIT_COMCRCERROR		23
+-#define CARDREG_STATUS_BIT_ILLEGALCOMMAND	22
+-#define CARDREG_STATUS_BIT_ERROR		19
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE3	12
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE2	11
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE1	10
+-#define CARDREG_STATUS_BIT_IOCURRENTSTATE0	9
+-#define CARDREG_STATUS_BIT_FUN_NUM_ERROR	4
+-
+-#define SD_CMD_GO_IDLE_STATE		0	/* mandatory for SDIO */
+-#define SD_CMD_SEND_OPCOND		1
+-#define SD_CMD_MMC_SET_RCA		3
+-#define SD_CMD_IO_SEND_OP_COND		5	/* mandatory for SDIO */
+-#define SD_CMD_SELECT_DESELECT_CARD	7
+-#define SD_CMD_SEND_CSD			9
+-#define SD_CMD_SEND_CID			10
+-#define SD_CMD_STOP_TRANSMISSION	12
+-#define SD_CMD_SEND_STATUS		13
+-#define SD_CMD_GO_INACTIVE_STATE	15
+-#define SD_CMD_SET_BLOCKLEN		16
+-#define SD_CMD_READ_SINGLE_BLOCK	17
+-#define SD_CMD_READ_MULTIPLE_BLOCK	18
+-#define SD_CMD_WRITE_BLOCK		24
+-#define SD_CMD_WRITE_MULTIPLE_BLOCK	25
+-#define SD_CMD_PROGRAM_CSD		27
+-#define SD_CMD_SET_WRITE_PROT		28
+-#define SD_CMD_CLR_WRITE_PROT		29
+-#define SD_CMD_SEND_WRITE_PROT		30
+-#define SD_CMD_ERASE_WR_BLK_START	32
+-#define SD_CMD_ERASE_WR_BLK_END		33
+-#define SD_CMD_ERASE			38
+-#define SD_CMD_LOCK_UNLOCK		42
+-#define SD_CMD_IO_RW_DIRECT		52	/* mandatory for SDIO */
+-#define SD_CMD_IO_RW_EXTENDED		53	/* mandatory for SDIO */
+-#define SD_CMD_APP_CMD			55
+-#define SD_CMD_GEN_CMD			56
+-#define SD_CMD_READ_OCR			58
+-#define SD_CMD_CRC_ON_OFF		59	/* mandatory for SDIO */
+-#define SD_ACMD_SD_STATUS		13
+-#define SD_ACMD_SEND_NUM_WR_BLOCKS	22
+-#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT	23
+-#define SD_ACMD_SD_SEND_OP_COND		41
+-#define SD_ACMD_SET_CLR_CARD_DETECT	42
+-#define SD_ACMD_SEND_SCR		51
+-
+-/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */
+-#define SD_IO_OP_READ		0	/* Read_Write: Read */
+-#define SD_IO_OP_WRITE		1	/* Read_Write: Write */
+-#define SD_IO_RW_NORMAL		0	/* no RAW */
+-#define SD_IO_RW_RAW		1	/* RAW */
+-#define SD_IO_BYTE_MODE		0	/* Byte Mode */
+-#define SD_IO_BLOCK_MODE	1	/* BlockMode */
+-#define SD_IO_FIXED_ADDRESS	0	/* fix Address */
+-#define SD_IO_INCREMENT_ADDRESS	1	/* IncrementAddress */
+-
+-/* build SD_CMD_IO_RW_DIRECT Argument */
+-#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \
+-	((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \
+-	 (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF))
+-
+-/* build SD_CMD_IO_RW_EXTENDED Argument */
+-#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \
+-	((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \
+-	 (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF))
+-
+-/* SDIO response parameters */
+-#define SD_RSP_NO_NONE			0
+-#define SD_RSP_NO_1			1
+-#define SD_RSP_NO_2			2
+-#define SD_RSP_NO_3			3
+-#define SD_RSP_NO_4			4
+-#define SD_RSP_NO_5			5
+-#define SD_RSP_NO_6			6
+-
+-	/* Modified R6 response (to CMD3) */
+-#define SD_RSP_MR6_COM_CRC_ERROR	0x8000
+-#define SD_RSP_MR6_ILLEGAL_COMMAND	0x4000
+-#define SD_RSP_MR6_ERROR		0x2000
+-
+-	/* Modified R1 in R4 Response (to CMD5) */
+-#define SD_RSP_MR1_SBIT			0x80
+-#define SD_RSP_MR1_PARAMETER_ERROR	0x40
+-#define SD_RSP_MR1_RFU5			0x20
+-#define SD_RSP_MR1_FUNC_NUM_ERROR	0x10
+-#define SD_RSP_MR1_COM_CRC_ERROR	0x08
+-#define SD_RSP_MR1_ILLEGAL_COMMAND	0x04
+-#define SD_RSP_MR1_RFU1			0x02
+-#define SD_RSP_MR1_IDLE_STATE		0x01
+-
+-	/* R5 response (to CMD52 and CMD53) */
+-#define SD_RSP_R5_COM_CRC_ERROR		0x80
+-#define SD_RSP_R5_ILLEGAL_COMMAND	0x40
+-#define SD_RSP_R5_IO_CURRENTSTATE1	0x20
+-#define SD_RSP_R5_IO_CURRENTSTATE0	0x10
+-#define SD_RSP_R5_ERROR			0x08
+-#define SD_RSP_R5_RFU			0x04
+-#define SD_RSP_R5_FUNC_NUM_ERROR	0x02
+-#define SD_RSP_R5_OUT_OF_RANGE		0x01
+-
+-#define SD_RSP_R5_ERRBITS		0xCB
+-
+-/* ------------------------------------------------
+- *  SDIO Commands and responses
+- *
+- *  I/O only commands are:
+- *      CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+- * ------------------------------------------------
+- */
+-
+-/* SDIO Commands */
+-#define SDIOH_CMD_0		0
+-#define SDIOH_CMD_3		3
+-#define SDIOH_CMD_5		5
+-#define SDIOH_CMD_7		7
+-#define SDIOH_CMD_15		15
+-#define SDIOH_CMD_52		52
+-#define SDIOH_CMD_53		53
+-#define SDIOH_CMD_59		59
+-
+-/* SDIO Command Responses */
+-#define SDIOH_RSP_NONE		0
+-#define SDIOH_RSP_R1		1
+-#define SDIOH_RSP_R2		2
+-#define SDIOH_RSP_R3		3
+-#define SDIOH_RSP_R4		4
+-#define SDIOH_RSP_R5		5
+-#define SDIOH_RSP_R6		6
+-
+-/*
+- *  SDIO Response Error flags
+- */
+-#define SDIOH_RSP5_ERROR_FLAGS	0xCB
+-
+-/* ------------------------------------------------
+- * SDIO Command structures. I/O only commands are:
+- *
+- * 	CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53
+- * ------------------------------------------------
+- */
+-
+-#define CMD5_OCR_M		BITFIELD_MASK(24)
+-#define CMD5_OCR_S		0
+-
+-#define CMD7_RCA_M		BITFIELD_MASK(16)
+-#define CMD7_RCA_S		16
+-
+-#define CMD_15_RCA_M		BITFIELD_MASK(16)
+-#define CMD_15_RCA_S		16
+-
+-#define CMD52_DATA_M		BITFIELD_MASK(8)	/* Bits [7:0]    - Write Data/Stuff bits of CMD52
+-							 */
+-#define CMD52_DATA_S		0
+-#define CMD52_REG_ADDR_M	BITFIELD_MASK(17)	/* Bits [25:9]   - register address */
+-#define CMD52_REG_ADDR_S	9
+-#define CMD52_RAW_M		BITFIELD_MASK(1)	/* Bit  27       - Read after Write flag */
+-#define CMD52_RAW_S		27
+-#define CMD52_FUNCTION_M	BITFIELD_MASK(3)	/* Bits [30:28]  - Function number */
+-#define CMD52_FUNCTION_S	28
+-#define CMD52_RW_FLAG_M		BITFIELD_MASK(1)	/* Bit  31       - R/W flag */
+-#define CMD52_RW_FLAG_S		31
+-
+-#define CMD53_BYTE_BLK_CNT_M	BITFIELD_MASK(9)	/* Bits [8:0]     - Byte/Block Count of CMD53 */
+-#define CMD53_BYTE_BLK_CNT_S	0
+-#define CMD53_REG_ADDR_M	BITFIELD_MASK(17)	/* Bits [25:9]   - register address */
+-#define CMD53_REG_ADDR_S	9
+-#define CMD53_OP_CODE_M		BITFIELD_MASK(1)	/* Bit  26       - R/W Operation Code */
+-#define CMD53_OP_CODE_S		26
+-#define CMD53_BLK_MODE_M	BITFIELD_MASK(1)	/* Bit  27       - Block Mode */
+-#define CMD53_BLK_MODE_S	27
+-#define CMD53_FUNCTION_M	BITFIELD_MASK(3)	/* Bits [30:28]  - Function number */
+-#define CMD53_FUNCTION_S	28
+-#define CMD53_RW_FLAG_M		BITFIELD_MASK(1)	/* Bit  31       - R/W flag */
+-#define CMD53_RW_FLAG_S		31
+-
+-/* ------------------------------------------------------
+- * SDIO Command Response structures for SD1 and SD4 modes
+- *  -----------------------------------------------------
+- */
+-#define RSP4_IO_OCR_M		BITFIELD_MASK(24)	/* Bits [23:0]  - Card's OCR Bits [23:0] */
+-#define RSP4_IO_OCR_S		0
+-#define RSP4_STUFF_M		BITFIELD_MASK(3)	/* Bits [26:24] - Stuff bits */
+-#define RSP4_STUFF_S		24
+-#define RSP4_MEM_PRESENT_M	BITFIELD_MASK(1)	/* Bit  27      - Memory present */
+-#define RSP4_MEM_PRESENT_S	27
+-#define RSP4_NUM_FUNCS_M	BITFIELD_MASK(3)	/* Bits [30:28] - Number of I/O funcs */
+-#define RSP4_NUM_FUNCS_S	28
+-#define RSP4_CARD_READY_M	BITFIELD_MASK(1)	/* Bit  31      - SDIO card ready */
+-#define RSP4_CARD_READY_S	31
+-
+-#define RSP6_STATUS_M		BITFIELD_MASK(16)	/* Bits [15:0]  - Card status bits [19,22,23,12:0]
+-							 */
+-#define RSP6_STATUS_S		0
+-#define RSP6_IO_RCA_M		BITFIELD_MASK(16)	/* Bits [31:16] - RCA bits[31-16] */
+-#define RSP6_IO_RCA_S		16
+-
+-#define RSP1_AKE_SEQ_ERROR_M	BITFIELD_MASK(1)	/* Bit 3       - Authentication seq error */
+-#define RSP1_AKE_SEQ_ERROR_S	3
+-#define RSP1_APP_CMD_M		BITFIELD_MASK(1)	/* Bit 5       - Card expects ACMD */
+-#define RSP1_APP_CMD_S		5
+-#define RSP1_READY_FOR_DATA_M	BITFIELD_MASK(1)	/* Bit 8       - Ready for data (buff empty) */
+-#define RSP1_READY_FOR_DATA_S	8
+-#define RSP1_CURR_STATE_M	BITFIELD_MASK(4)	/* Bits [12:9] - State of card
+-							 * when Cmd was received
+-							 */
+-#define RSP1_CURR_STATE_S	9
+-#define RSP1_EARSE_RESET_M	BITFIELD_MASK(1)	/* Bit 13   - Erase seq cleared */
+-#define RSP1_EARSE_RESET_S	13
+-#define RSP1_CARD_ECC_DISABLE_M	BITFIELD_MASK(1)	/* Bit 14   - Card ECC disabled */
+-#define RSP1_CARD_ECC_DISABLE_S	14
+-#define RSP1_WP_ERASE_SKIP_M	BITFIELD_MASK(1)	/* Bit 15   - Partial blocks erased due to W/P */
+-#define RSP1_WP_ERASE_SKIP_S	15
+-#define RSP1_CID_CSD_OVERW_M	BITFIELD_MASK(1)	/* Bit 16   - Illegal write to CID or R/O bits
+-							 * of CSD
+-							 */
+-#define RSP1_CID_CSD_OVERW_S	16
+-#define RSP1_ERROR_M		BITFIELD_MASK(1)	/* Bit 19   - General/Unknown error */
+-#define RSP1_ERROR_S		19
+-#define RSP1_CC_ERROR_M		BITFIELD_MASK(1)	/* Bit 20   - Internal Card Control error */
+-#define RSP1_CC_ERROR_S		20
+-#define RSP1_CARD_ECC_FAILED_M	BITFIELD_MASK(1)	/* Bit 21   - Card internal ECC failed
+-							 * to correct data
+-							 */
+-#define RSP1_CARD_ECC_FAILED_S	21
+-#define RSP1_ILLEGAL_CMD_M	BITFIELD_MASK(1)	/* Bit 22   - Cmd not legal for the card state */
+-#define RSP1_ILLEGAL_CMD_S	22
+-#define RSP1_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit 23   - CRC check of previous command failed
+-							 */
+-#define RSP1_COM_CRC_ERROR_S	23
+-#define RSP1_LOCK_UNLOCK_FAIL_M	BITFIELD_MASK(1)	/* Bit 24   - Card lock-unlock Cmd Seq error */
+-#define RSP1_LOCK_UNLOCK_FAIL_S	24
+-#define RSP1_CARD_LOCKED_M	BITFIELD_MASK(1)	/* Bit 25   - Card locked by the host */
+-#define RSP1_CARD_LOCKED_S	25
+-#define RSP1_WP_VIOLATION_M	BITFIELD_MASK(1)	/* Bit 26   - Attempt to program
+-							 * write-protected blocks
+-							 */
+-#define RSP1_WP_VIOLATION_S	26
+-#define RSP1_ERASE_PARAM_M	BITFIELD_MASK(1)	/* Bit 27   - Invalid erase blocks */
+-#define RSP1_ERASE_PARAM_S	27
+-#define RSP1_ERASE_SEQ_ERR_M	BITFIELD_MASK(1)	/* Bit 28   - Erase Cmd seq error */
+-#define RSP1_ERASE_SEQ_ERR_S	28
+-#define RSP1_BLK_LEN_ERR_M	BITFIELD_MASK(1)	/* Bit 29   - Block length error */
+-#define RSP1_BLK_LEN_ERR_S	29
+-#define RSP1_ADDR_ERR_M		BITFIELD_MASK(1)	/* Bit 30   - Misaligned address */
+-#define RSP1_ADDR_ERR_S		30
+-#define RSP1_OUT_OF_RANGE_M	BITFIELD_MASK(1)	/* Bit 31   - Cmd arg was out of range */
+-#define RSP1_OUT_OF_RANGE_S	31
+-
+-#define RSP5_DATA_M		BITFIELD_MASK(8)	/* Bits [0:7]   - data */
+-#define RSP5_DATA_S		0
+-#define RSP5_FLAGS_M		BITFIELD_MASK(8)	/* Bit  [15:8]  - Rsp flags */
+-#define RSP5_FLAGS_S		8
+-#define RSP5_STUFF_M		BITFIELD_MASK(16)	/* Bits [31:16] - Stuff bits */
+-#define RSP5_STUFF_S		16
+-
+-/* ----------------------------------------------
+- * SDIO Command Response structures for SPI mode
+- * ----------------------------------------------
+- */
+-#define SPIRSP4_IO_OCR_M	BITFIELD_MASK(16)	/* Bits [15:0]    - Card's OCR Bits [23:8] */
+-#define SPIRSP4_IO_OCR_S	0
+-#define SPIRSP4_STUFF_M		BITFIELD_MASK(3)	/* Bits [18:16]   - Stuff bits */
+-#define SPIRSP4_STUFF_S		16
+-#define SPIRSP4_MEM_PRESENT_M	BITFIELD_MASK(1)	/* Bit  19        - Memory present */
+-#define SPIRSP4_MEM_PRESENT_S	19
+-#define SPIRSP4_NUM_FUNCS_M	BITFIELD_MASK(3)	/* Bits [22:20]   - Number of I/O funcs */
+-#define SPIRSP4_NUM_FUNCS_S	20
+-#define SPIRSP4_CARD_READY_M	BITFIELD_MASK(1)	/* Bit  23        - SDIO card ready */
+-#define SPIRSP4_CARD_READY_S	23
+-#define SPIRSP4_IDLE_STATE_M	BITFIELD_MASK(1)	/* Bit  24        - idle state */
+-#define SPIRSP4_IDLE_STATE_S	24
+-#define SPIRSP4_ILLEGAL_CMD_M	BITFIELD_MASK(1)	/* Bit  26        - Illegal Cmd error */
+-#define SPIRSP4_ILLEGAL_CMD_S	26
+-#define SPIRSP4_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit  27        - COM CRC error */
+-#define SPIRSP4_COM_CRC_ERROR_S	27
+-#define SPIRSP4_FUNC_NUM_ERROR_M	BITFIELD_MASK(1)	/* Bit  28        - Function number error
+-								 */
+-#define SPIRSP4_FUNC_NUM_ERROR_S	28
+-#define SPIRSP4_PARAM_ERROR_M	BITFIELD_MASK(1)	/* Bit  30        - Parameter Error Bit */
+-#define SPIRSP4_PARAM_ERROR_S	30
+-#define SPIRSP4_START_BIT_M	BITFIELD_MASK(1)	/* Bit  31        - Start Bit */
+-#define SPIRSP4_START_BIT_S	31
+-
+-#define SPIRSP5_DATA_M			BITFIELD_MASK(8)	/* Bits [23:16]   - R/W Data */
+-#define SPIRSP5_DATA_S			16
+-#define SPIRSP5_IDLE_STATE_M		BITFIELD_MASK(1)	/* Bit  24        - Idle state */
+-#define SPIRSP5_IDLE_STATE_S		24
+-#define SPIRSP5_ILLEGAL_CMD_M		BITFIELD_MASK(1)	/* Bit  26        - Illegal Cmd error */
+-#define SPIRSP5_ILLEGAL_CMD_S		26
+-#define SPIRSP5_COM_CRC_ERROR_M		BITFIELD_MASK(1)	/* Bit  27        - COM CRC error */
+-#define SPIRSP5_COM_CRC_ERROR_S		27
+-#define SPIRSP5_FUNC_NUM_ERROR_M	BITFIELD_MASK(1)	/* Bit  28        - Function number error
+-								 */
+-#define SPIRSP5_FUNC_NUM_ERROR_S	28
+-#define SPIRSP5_PARAM_ERROR_M		BITFIELD_MASK(1)	/* Bit  30        - Parameter Error Bit */
+-#define SPIRSP5_PARAM_ERROR_S		30
+-#define SPIRSP5_START_BIT_M		BITFIELD_MASK(1)	/* Bit  31        - Start Bit */
+-#define SPIRSP5_START_BIT_S		31
+-
+-/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */
+-#define RSP6STAT_AKE_SEQ_ERROR_M	BITFIELD_MASK(1)	/* Bit 3      - Authentication seq error
+-								 */
+-#define RSP6STAT_AKE_SEQ_ERROR_S	3
+-#define RSP6STAT_APP_CMD_M		BITFIELD_MASK(1)	/* Bit 5      - Card expects ACMD */
+-#define RSP6STAT_APP_CMD_S		5
+-#define RSP6STAT_READY_FOR_DATA_M	BITFIELD_MASK(1)	/* Bit 8      - Ready for data
+-								 * (buff empty)
+-								 */
+-#define RSP6STAT_READY_FOR_DATA_S	8
+-#define RSP6STAT_CURR_STATE_M		BITFIELD_MASK(4)	/* Bits [12:9] - Card state at
+-								 * Cmd reception
+-								 */
+-#define RSP6STAT_CURR_STATE_S		9
+-#define RSP6STAT_ERROR_M		BITFIELD_MASK(1)	/* Bit 13  - General/Unknown error Bit 19
+-								 */
+-#define RSP6STAT_ERROR_S		13
+-#define RSP6STAT_ILLEGAL_CMD_M		BITFIELD_MASK(1)	/* Bit 14  - Illegal cmd for
+-								 * card state Bit 22
+-								 */
+-#define RSP6STAT_ILLEGAL_CMD_S		14
+-#define RSP6STAT_COM_CRC_ERROR_M	BITFIELD_MASK(1)	/* Bit 15  - CRC previous command
+-								 * failed Bit 23
+-								 */
+-#define RSP6STAT_COM_CRC_ERROR_S	15
+-
+-#define SDIOH_XFER_TYPE_READ    SD_IO_OP_READ
+-#define SDIOH_XFER_TYPE_WRITE   SD_IO_OP_WRITE
+-
+-#endif				/* def BCMSDIO */
+-#endif				/* _SDIO_H */
+diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h
+deleted file mode 100644
+index 2876bd9..0000000
+--- a/drivers/staging/brcm80211/include/wlioctl.h
++++ /dev/null
+@@ -1,1365 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#ifndef _wlioctl_h_
+-#define	_wlioctl_h_
+-
+-#include <linux/ieee80211.h>
+-#ifdef BRCM_FULLMAC
+-#include <proto/bcmeth.h>
+-#endif
+-#include <proto/bcmevent.h>
+-#include <proto/802.11.h>
+-#include <bcmwifi.h>
+-
+-#ifndef INTF_NAME_SIZ
+-#define INTF_NAME_SIZ	16
+-#endif
+-
+-#ifdef BRCM_FULLMAC
+-
+-#define	WL_BSS_INFO_VERSION	108	/* current ver of wl_bss_info struct */
+-
+-/* BSS info structure
+- * Applications MUST CHECK ie_offset field and length field to access IEs and
+- * next bss_info structure in a vector (in wl_scan_results_t)
+- */
+-typedef struct wl_bss_info {
+-	u32 version;		/* version field */
+-	u32 length;		/* byte length of data in this record,
+-				 * starting at version and including IEs
+-				 */
+-	u8 BSSID[ETH_ALEN];
+-	u16 beacon_period;	/* units are Kusec */
+-	u16 capability;	/* Capability information */
+-	u8 SSID_len;
+-	u8 SSID[32];
+-	struct {
+-		uint count;	/* # rates in this set */
+-		u8 rates[16];	/* rates in 500kbps units w/hi bit set if basic */
+-	} rateset;		/* supported rates */
+-	chanspec_t chanspec;	/* chanspec for bss */
+-	u16 atim_window;	/* units are Kusec */
+-	u8 dtim_period;	/* DTIM period */
+-	s16 RSSI;		/* receive signal strength (in dBm) */
+-	s8 phy_noise;		/* noise (in dBm) */
+-
+-	u8 n_cap;		/* BSS is 802.11N Capable */
+-	u32 nbss_cap;	/* 802.11N BSS Capabilities (based on HT_CAP_*) */
+-	u8 ctl_ch;		/* 802.11N BSS control channel number */
+-	u32 reserved32[1];	/* Reserved for expansion of BSS properties */
+-	u8 flags;		/* flags */
+-	u8 reserved[3];	/* Reserved for expansion of BSS properties */
+-	u8 basic_mcs[MCSSET_LEN];	/* 802.11N BSS required MCS set */
+-
+-	u16 ie_offset;	/* offset at which IEs start, from beginning */
+-	u32 ie_length;	/* byte length of Information Elements */
+-	s16 SNR;		/* average SNR of during frame reception */
+-	/* Add new fields here */
+-	/* variable length Information Elements */
+-} wl_bss_info_t;
+-#endif /* BRCM_FULLMAC */
+-
+-typedef struct wlc_ssid {
+-	u32 SSID_len;
+-	unsigned char SSID[32];
+-} wlc_ssid_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct chan_scandata {
+-	u8 txpower;
+-	u8 pad;
+-	chanspec_t channel;	/* Channel num, bw, ctrl_sb and band */
+-	u32 channel_mintime;
+-	u32 channel_maxtime;
+-} chan_scandata_t;
+-
+-typedef enum wl_scan_type {
+-	EXTDSCAN_FOREGROUND_SCAN,
+-	EXTDSCAN_BACKGROUND_SCAN,
+-	EXTDSCAN_FORCEDBACKGROUND_SCAN
+-} wl_scan_type_t;
+-
+-#define WLC_EXTDSCAN_MAX_SSID		5
+-
+-#define WL_BSS_FLAGS_FROM_BEACON	0x01	/* bss_info derived from beacon */
+-#define WL_BSS_FLAGS_FROM_CACHE		0x02	/* bss_info collected from cache */
+-#define WL_BSS_FLAGS_RSSI_ONCHANNEL     0x04	/* rssi info was received on channel (vs offchannel) */
+-
+-typedef struct wl_extdscan_params {
+-	s8 nprobes;		/* 0, passive, otherwise active */
+-	s8 split_scan;	/* split scan */
+-	s8 band;		/* band */
+-	s8 pad;
+-	wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID];	/* ssid list */
+-	u32 tx_rate;		/* in 500ksec units */
+-	wl_scan_type_t scan_type;	/* enum */
+-	s32 channel_num;
+-	chan_scandata_t channel_list[1];	/* list of chandata structs */
+-} wl_extdscan_params_t;
+-
+-#define WL_EXTDSCAN_PARAMS_FIXED_SIZE 	(sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t))
+-
+-#define WL_BSSTYPE_INFRA 1
+-#define WL_BSSTYPE_INDEP 0
+-#define WL_BSSTYPE_ANY   2
+-
+-/* Bitmask for scan_type */
+-#define WL_SCANFLAGS_PASSIVE 0x01	/* force passive scan */
+-#define WL_SCANFLAGS_RESERVED 0x02	/* Reserved */
+-#define WL_SCANFLAGS_PROHIBITED 0x04	/* allow scanning prohibited channels */
+-
+-typedef struct wl_scan_params {
+-	wlc_ssid_t ssid;	/* default: {0, ""} */
+-	u8 bssid[ETH_ALEN];	/* default: bcast */
+-	s8 bss_type;		/* default: any,
+-				 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
+-				 */
+-	u8 scan_type;	/* flags, 0 use default */
+-	s32 nprobes;		/* -1 use default, number of probes per channel */
+-	s32 active_time;	/* -1 use default, dwell time per channel for
+-				 * active scanning
+-				 */
+-	s32 passive_time;	/* -1 use default, dwell time per channel
+-				 * for passive scanning
+-				 */
+-	s32 home_time;	/* -1 use default, dwell time for the home channel
+-				 * between channel scans
+-				 */
+-	s32 channel_num;	/* count of channels and ssids that follow
+-				 *
+-				 * low half is count of channels in channel_list, 0
+-				 * means default (use all available channels)
+-				 *
+-				 * high half is entries in wlc_ssid_t array that
+-				 * follows channel_list, aligned for s32 (4 bytes)
+-				 * meaning an odd channel count implies a 2-byte pad
+-				 * between end of channel_list and first ssid
+-				 *
+-				 * if ssid count is zero, single ssid in the fixed
+-				 * parameter portion is assumed, otherwise ssid in
+-				 * the fixed portion is ignored
+-				 */
+-	u16 channel_list[1];	/* list of chanspecs */
+-} wl_scan_params_t;
+-
+-/* size of wl_scan_params not including variable length array */
+-#define WL_SCAN_PARAMS_FIXED_SIZE 64
+-
+-/* masks for channel and ssid count */
+-#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff
+-#define WL_SCAN_PARAMS_NSSID_SHIFT 16
+-
+-#define WL_SCAN_ACTION_START      1
+-#define WL_SCAN_ACTION_CONTINUE   2
+-#define WL_SCAN_ACTION_ABORT      3
+-
+-#define ISCAN_REQ_VERSION 1
+-
+-/* incremental scan struct */
+-typedef struct wl_iscan_params {
+-	u32 version;
+-	u16 action;
+-	u16 scan_duration;
+-	wl_scan_params_t params;
+-} wl_iscan_params_t;
+-
+-/* 3 fields + size of wl_scan_params, not including variable length array */
+-#define WL_ISCAN_PARAMS_FIXED_SIZE (offsetof(wl_iscan_params_t, params) + sizeof(wlc_ssid_t))
+-
+-typedef struct wl_scan_results {
+-	u32 buflen;
+-	u32 version;
+-	u32 count;
+-	wl_bss_info_t bss_info[1];
+-} wl_scan_results_t;
+-
+-/* size of wl_scan_results not including variable length array */
+-#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t))
+-
+-/* wl_iscan_results status values */
+-#define WL_SCAN_RESULTS_SUCCESS	0
+-#define WL_SCAN_RESULTS_PARTIAL	1
+-#define WL_SCAN_RESULTS_PENDING	2
+-#define WL_SCAN_RESULTS_ABORTED	3
+-#define WL_SCAN_RESULTS_NO_MEM	4
+-
+-#define ESCAN_REQ_VERSION 1
+-
+-typedef struct wl_escan_params {
+-	u32 version;
+-	u16 action;
+-	u16 sync_id;
+-	wl_scan_params_t params;
+-} wl_escan_params_t;
+-
+-#define WL_ESCAN_PARAMS_FIXED_SIZE (offsetof(wl_escan_params_t, params) + sizeof(wlc_ssid_t))
+-
+-typedef struct wl_escan_result {
+-	u32 buflen;
+-	u32 version;
+-	u16 sync_id;
+-	u16 bss_count;
+-	wl_bss_info_t bss_info[1];
+-} wl_escan_result_t;
+-
+-#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t))
+-
+-/* incremental scan results struct */
+-typedef struct wl_iscan_results {
+-	u32 status;
+-	wl_scan_results_t results;
+-} wl_iscan_results_t;
+-
+-/* size of wl_iscan_results not including variable length array */
+-#define WL_ISCAN_RESULTS_FIXED_SIZE \
+-	(WL_SCAN_RESULTS_FIXED_SIZE + offsetof(wl_iscan_results_t, results))
+-
+-typedef struct wl_probe_params {
+-	wlc_ssid_t ssid;
+-	u8 bssid[ETH_ALEN];
+-	u8 mac[ETH_ALEN];
+-} wl_probe_params_t;
+-#endif /* BRCM_FULLMAC */
+-
+-#define WL_NUMRATES		16	/* max # of rates in a rateset */
+-typedef struct wl_rateset {
+-	u32 count;		/* # rates in this set */
+-	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-} wl_rateset_t;
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct wl_rateset_args {
+-	u32 count;		/* # rates in this set */
+-	u8 rates[WL_NUMRATES];	/* rates in 500kbps units w/hi bit set if basic */
+-	u8 mcs[MCSSET_LEN];	/* supported mcs index bit map */
+-} wl_rateset_args_t;
+-
+-/* u32 list */
+-typedef struct wl_u32_list {
+-	/* in - # of elements, out - # of entries */
+-	u32 count;
+-	/* variable length u32 list */
+-	u32 element[1];
+-} wl_u32_list_t;
+-
+-/* used for association with a specific BSSID and chanspec list */
+-typedef struct wl_assoc_params {
+-	u8 bssid[ETH_ALEN];	/* 00:00:00:00:00:00: broadcast scan */
+-	u16 bssid_cnt;
+-	s32 chanspec_num;	/* 0: all available channels,
+-				 * otherwise count of chanspecs in chanspec_list
+-				 */
+-	chanspec_t chanspec_list[1];	/* list of chanspecs */
+-} wl_assoc_params_t;
+-#define WL_ASSOC_PARAMS_FIXED_SIZE 	(sizeof(wl_assoc_params_t) - sizeof(chanspec_t))
+-
+-/* used for reassociation/roam to a specific BSSID and channel */
+-typedef wl_assoc_params_t wl_reassoc_params_t;
+-#define WL_REASSOC_PARAMS_FIXED_SIZE	WL_ASSOC_PARAMS_FIXED_SIZE
+-
+-/* used for join with or without a specific bssid and channel list */
+-typedef struct wl_join_params {
+-	wlc_ssid_t ssid;
+-	wl_assoc_params_t params;	/* optional field, but it must include the fixed portion
+-					 * of the wl_assoc_params_t struct when it does present.
+-					 */
+-} wl_join_params_t;
+-#define WL_JOIN_PARAMS_FIXED_SIZE 	(sizeof(wl_join_params_t) - sizeof(chanspec_t))
+-
+-#endif /* BRCM_FULLMAC */
+-
+-/* defines used by the nrate iovar */
+-#define NRATE_MCS_INUSE	0x00000080	/* MSC in use,indicates b0-6 holds an mcs */
+-#define NRATE_RATE_MASK 0x0000007f	/* rate/mcs value */
+-#define NRATE_STF_MASK	0x0000ff00	/* stf mode mask: siso, cdd, stbc, sdm */
+-#define NRATE_STF_SHIFT	8	/* stf mode shift */
+-#define NRATE_OVERRIDE	0x80000000	/* bit indicates override both rate & mode */
+-#define NRATE_OVERRIDE_MCS_ONLY 0x40000000	/* bit indicate to override mcs only */
+-#define NRATE_SGI_MASK  0x00800000	/* sgi mode */
+-#define NRATE_SGI_SHIFT 23	/* sgi mode */
+-#define NRATE_LDPC_CODING 0x00400000	/* bit indicates adv coding in use */
+-#define NRATE_LDPC_SHIFT 22	/* ldpc shift */
+-
+-#define NRATE_STF_SISO	0	/* stf mode SISO */
+-#define NRATE_STF_CDD	1	/* stf mode CDD */
+-#define NRATE_STF_STBC	2	/* stf mode STBC */
+-#define NRATE_STF_SDM	3	/* stf mode SDM */
+-
+-#define ANTENNA_NUM_1	1	/* total number of antennas to be used */
+-#define ANTENNA_NUM_2	2
+-#define ANTENNA_NUM_3	3
+-#define ANTENNA_NUM_4	4
+-
+-#define ANT_SELCFG_AUTO		0x80	/* bit indicates antenna sel AUTO */
+-#define ANT_SELCFG_MASK		0x33	/* antenna configuration mask */
+-#define ANT_SELCFG_MAX		4	/* max number of antenna configurations */
+-#define ANT_SELCFG_TX_UNICAST	0	/* unicast tx antenna configuration */
+-#define ANT_SELCFG_RX_UNICAST	1	/* unicast rx antenna configuration */
+-#define ANT_SELCFG_TX_DEF	2	/* default tx antenna configuration */
+-#define ANT_SELCFG_RX_DEF	3	/* default rx antenna configuration */
+-
+-#define MAX_STREAMS_SUPPORTED	4	/* max number of streams supported */
+-
+-typedef struct {
+-	u8 ant_config[ANT_SELCFG_MAX];	/* antenna configuration */
+-	u8 num_antcfg;	/* number of available antenna configurations */
+-} wlc_antselcfg_t;
+-
+-#define HIGHEST_SINGLE_STREAM_MCS	7	/* MCS values greater than this enable multiple streams */
+-
+-#ifdef BRCM_FULLMAC
+-#define MAX_CCA_CHANNELS 38	/* Max number of 20 Mhz wide channels */
+-#define MAX_CCA_SECS     60	/* CCA keeps this many seconds history */
+-
+-#define IBSS_MED        15	/* Mediom in-bss congestion percentage */
+-#define IBSS_HI         25	/* Hi in-bss congestion percentage */
+-#define OBSS_MED        12
+-#define OBSS_HI         25
+-#define INTERFER_MED    5
+-#define INTERFER_HI     10
+-
+-#define  CCA_FLAG_2G_ONLY		0x01	/* Return a channel from 2.4 Ghz band */
+-#define  CCA_FLAG_5G_ONLY		0x02	/* Return a channel from 2.4 Ghz band */
+-#define  CCA_FLAG_IGNORE_DURATION	0x04	/* Ignore dwell time for each channel */
+-#define  CCA_FLAGS_PREFER_1_6_11	0x10
+-#define  CCA_FLAG_IGNORE_INTERFER 	0x20	/* do not exlude channel based on interfer level */
+-
+-#define CCA_ERRNO_BAND 		1	/* After filtering for band pref, no choices left */
+-#define CCA_ERRNO_DURATION	2	/* After filtering for duration, no choices left */
+-#define CCA_ERRNO_PREF_CHAN	3	/* After filtering for chan pref, no choices left */
+-#define CCA_ERRNO_INTERFER	4	/* After filtering for interference, no choices left */
+-#define CCA_ERRNO_TOO_FEW	5	/* Only 1 channel was input */
+-
+-typedef struct {
+-	u32 duration;	/* millisecs spent sampling this channel */
+-	u32 congest_ibss;	/* millisecs in our bss (presumably this traffic will */
+-	/*  move if cur bss moves channels) */
+-	u32 congest_obss;	/* traffic not in our bss */
+-	u32 interference;	/* millisecs detecting a non 802.11 interferer. */
+-	u32 timestamp;	/* second timestamp */
+-} cca_congest_t;
+-
+-typedef struct {
+-	chanspec_t chanspec;	/* Which channel? */
+-	u8 num_secs;		/* How many secs worth of data */
+-	cca_congest_t secs[1];	/* Data */
+-} cca_congest_channel_req_t;
+-
+-#endif /* BRCM_FULLMAC */
+-
+-#define WLC_CNTRY_BUF_SZ	4	/* Country string is 3 bytes + NUL */
+-
+-#ifdef BRCM_FULLMAC
+-typedef struct wl_country {
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];	/* nul-terminated country code used in
+-						 * the Country IE
+-						 */
+-	s32 rev;		/* revision specifier for ccode
+-				 * on set, -1 indicates unspecified.
+-				 * on get, rev >= 0
+-				 */
+-	char ccode[WLC_CNTRY_BUF_SZ];	/* nul-terminated built-in country code.
+-					 * variable length, but fixed size in
+-					 * struct allows simple allocation for
+-					 * expected country strings <= 3 chars.
+-					 */
+-} wl_country_t;
+-
+-typedef struct wl_channels_in_country {
+-	u32 buflen;
+-	u32 band;
+-	char country_abbrev[WLC_CNTRY_BUF_SZ];
+-	u32 count;
+-	u32 channel[1];
+-} wl_channels_in_country_t;
+-
+-typedef struct wl_country_list {
+-	u32 buflen;
+-	u32 band_set;
+-	u32 band;
+-	u32 count;
+-	char country_abbrev[1];
+-} wl_country_list_t;
+-
+-#define WL_NUM_RPI_BINS		8
+-#define WL_RM_TYPE_BASIC	1
+-#define WL_RM_TYPE_CCA		2
+-#define WL_RM_TYPE_RPI		3
+-
+-#define WL_RM_FLAG_PARALLEL	(1<<0)
+-
+-#define WL_RM_FLAG_LATE		(1<<1)
+-#define WL_RM_FLAG_INCAPABLE	(1<<2)
+-#define WL_RM_FLAG_REFUSED	(1<<3)
+-
+-typedef struct wl_rm_req_elt {
+-	s8 type;
+-	s8 flags;
+-	chanspec_t chanspec;
+-	u32 token;		/* token for this measurement */
+-	u32 tsf_h;		/* TSF high 32-bits of Measurement start time */
+-	u32 tsf_l;		/* TSF low 32-bits */
+-	u32 dur;		/* TUs */
+-} wl_rm_req_elt_t;
+-
+-typedef struct wl_rm_req {
+-	u32 token;		/* overall measurement set token */
+-	u32 count;		/* number of measurement requests */
+-	void *cb;		/* completion callback function: may be NULL */
+-	void *cb_arg;		/* arg to completion callback function */
+-	wl_rm_req_elt_t req[1];	/* variable length block of requests */
+-} wl_rm_req_t;
+-#define WL_RM_REQ_FIXED_LEN	offsetof(wl_rm_req_t, req)
+-
+-typedef struct wl_rm_rep_elt {
+-	s8 type;
+-	s8 flags;
+-	chanspec_t chanspec;
+-	u32 token;		/* token for this measurement */
+-	u32 tsf_h;		/* TSF high 32-bits of Measurement start time */
+-	u32 tsf_l;		/* TSF low 32-bits */
+-	u32 dur;		/* TUs */
+-	u32 len;		/* byte length of data block */
+-	u8 data[1];		/* variable length data block */
+-} wl_rm_rep_elt_t;
+-#define WL_RM_REP_ELT_FIXED_LEN	24	/* length excluding data block */
+-
+-#define WL_RPI_REP_BIN_NUM 8
+-typedef struct wl_rm_rpi_rep {
+-	u8 rpi[WL_RPI_REP_BIN_NUM];
+-	s8 rpi_max[WL_RPI_REP_BIN_NUM];
+-} wl_rm_rpi_rep_t;
+-
+-typedef struct wl_rm_rep {
+-	u32 token;		/* overall measurement set token */
+-	u32 len;		/* length of measurement report block */
+-	wl_rm_rep_elt_t rep[1];	/* variable length block of reports */
+-} wl_rm_rep_t;
+-#define WL_RM_REP_FIXED_LEN	8
+-#endif /* BRCM_FULLMAC */
+-
+-/* Enumerate crypto algorithms */
+-#define	CRYPTO_ALGO_OFF			0
+-#define	CRYPTO_ALGO_WEP1		1
+-#define	CRYPTO_ALGO_TKIP		2
+-#define	CRYPTO_ALGO_WEP128		3
+-#define CRYPTO_ALGO_AES_CCM		4
+-#define CRYPTO_ALGO_AES_RESERVED1	5
+-#define CRYPTO_ALGO_AES_RESERVED2	6
+-#define CRYPTO_ALGO_NALG		7
+-
+-#define WSEC_GEN_MIC_ERROR	0x0001
+-#define WSEC_GEN_REPLAY		0x0002
+-#define WSEC_GEN_ICV_ERROR	0x0004
+-
+-#define WL_SOFT_KEY	(1 << 0)	/* Indicates this key is using soft encrypt */
+-#define WL_PRIMARY_KEY	(1 << 1)	/* Indicates this key is the primary (ie tx) key */
+-#define WL_KF_RES_4	(1 << 4)	/* Reserved for backward compat */
+-#define WL_KF_RES_5	(1 << 5)	/* Reserved for backward compat */
+-#define WL_IBSS_PEER_GROUP_KEY	(1 << 6)	/* Indicates a group key for a IBSS PEER */
+-
+-typedef struct wl_wsec_key {
+-	u32 index;		/* key index */
+-	u32 len;		/* key length */
+-	u8 data[WLAN_MAX_KEY_LEN];	/* key data */
+-	u32 pad_1[18];
+-	u32 algo;		/* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
+-	u32 flags;		/* misc flags */
+-	u32 pad_2[2];
+-	int pad_3;
+-	int iv_initialized;	/* has IV been initialized already? */
+-	int pad_4;
+-	/* Rx IV */
+-	struct {
+-		u32 hi;	/* upper 32 bits of IV */
+-		u16 lo;	/* lower 16 bits of IV */
+-	} rxiv;
+-	u32 pad_5[2];
+-	u8 ea[ETH_ALEN];	/* per station */
+-} wl_wsec_key_t;
+-
+-#define WSEC_MIN_PSK_LEN	8
+-#define WSEC_MAX_PSK_LEN	64
+-
+-/* Flag for key material needing passhash'ing */
+-#define WSEC_PASSPHRASE		(1<<0)
+-
+-/* receptacle for WLC_SET_WSEC_PMK parameter */
+-typedef struct {
+-	unsigned short key_len;		/* octets in key material */
+-	unsigned short flags;		/* key handling qualification */
+-	u8 key[WSEC_MAX_PSK_LEN];	/* PMK material */
+-} wsec_pmk_t;
+-
+-/* wireless security bitvec */
+-#define WEP_ENABLED		0x0001
+-#define TKIP_ENABLED		0x0002
+-#define AES_ENABLED		0x0004
+-#define WSEC_SWFLAG		0x0008
+-#define SES_OW_ENABLED		0x0040	/* to go into transition mode without setting wep */
+-
+-/* WPA authentication mode bitvec */
+-#define WPA_AUTH_DISABLED	0x0000	/* Legacy (i.e., non-WPA) */
+-#define WPA_AUTH_NONE		0x0001	/* none (IBSS) */
+-#define WPA_AUTH_UNSPECIFIED	0x0002	/* over 802.1x */
+-#define WPA_AUTH_PSK		0x0004	/* Pre-shared key */
+-#define WPA_AUTH_RESERVED1	0x0008
+-#define WPA_AUTH_RESERVED2	0x0010
+-					/* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */
+-#define WPA2_AUTH_RESERVED1	0x0020
+-#define WPA2_AUTH_UNSPECIFIED	0x0040	/* over 802.1x */
+-#define WPA2_AUTH_PSK		0x0080	/* Pre-shared key */
+-#define WPA2_AUTH_RESERVED3	0x0200
+-#define WPA2_AUTH_RESERVED4	0x0400
+-#define WPA2_AUTH_RESERVED5	0x0800
+-
+-/* pmkid */
+-#define	MAXPMKID		16
+-
+-typedef struct _pmkid {
+-	u8 BSSID[ETH_ALEN];
+-	u8 PMKID[WLAN_PMKID_LEN];
+-} pmkid_t;
+-
+-typedef struct _pmkid_list {
+-	u32 npmkid;
+-	pmkid_t pmkid[1];
+-} pmkid_list_t;
+-
+-typedef struct _pmkid_cand {
+-	u8 BSSID[ETH_ALEN];
+-	u8 preauth;
+-} pmkid_cand_t;
+-
+-typedef struct _pmkid_cand_list {
+-	u32 npmkid_cand;
+-	pmkid_cand_t pmkid_cand[1];
+-} pmkid_cand_list_t;
+-
+-typedef struct wl_led_info {
+-	u32 index;		/* led index */
+-	u32 behavior;
+-	u8 activehi;
+-} wl_led_info_t;
+-
+-/* R_REG and W_REG struct passed through ioctl */
+-typedef struct {
+-	u32 byteoff;		/* byte offset of the field in d11regs_t */
+-	u32 val;		/* read/write value of the field */
+-	u32 size;		/* sizeof the field */
+-	uint band;		/* band (optional) */
+-} rw_reg_t;
+-
+-
+-#ifdef BRCM_FULLMAC
+-/* Used to get specific STA parameters */
+-typedef struct {
+-	u32 val;
+-	u8 ea[ETH_ALEN];
+-} scb_val_t;
+-#endif /* BRCM_FULLMAC */
+-
+-/* channel encoding */
+-typedef struct channel_info {
+-	int hw_channel;
+-	int target_channel;
+-	int scan_channel;
+-} channel_info_t;
+-
+-/* For ioctls that take a list of MAC addresses */
+-struct maclist {
+-	uint count;		/* number of MAC addresses */
+-	u8 ea[1][ETH_ALEN];	/* variable length array of MAC addresses */
+-};
+-
+-#ifdef BRCM_FULLMAC
+-/* Linux network driver ioctl encoding */
+-typedef struct wl_ioctl {
+-	uint cmd;		/* common ioctl definition */
+-	void *buf;		/* pointer to user buffer */
+-	uint len;		/* length of user buffer */
+-	u8 set;		/* get or set request (optional) */
+-	uint used;		/* bytes read or written (optional) */
+-	uint needed;		/* bytes needed (optional) */
+-} wl_ioctl_t;
+-#endif /* BRCM_FULLMAC */
+-
+-
+-/*
+- * Structure for passing hardware and software
+- * revision info up from the driver.
+- */
+-typedef struct wlc_rev_info {
+-	uint vendorid;		/* PCI vendor id */
+-	uint deviceid;		/* device id of chip */
+-	uint radiorev;		/* radio revision */
+-	uint chiprev;		/* chip revision */
+-	uint corerev;		/* core revision */
+-	uint boardid;		/* board identifier (usu. PCI sub-device id) */
+-	uint boardvendor;	/* board vendor (usu. PCI sub-vendor id) */
+-	uint boardrev;		/* board revision */
+-	uint driverrev;		/* driver version */
+-	uint ucoderev;		/* microcode version */
+-	uint bus;		/* bus type */
+-	uint chipnum;		/* chip number */
+-	uint phytype;		/* phy type */
+-	uint phyrev;		/* phy revision */
+-	uint anarev;		/* anacore rev */
+-	uint chippkg;		/* chip package info */
+-} wlc_rev_info_t;
+-
+-#define WL_REV_INFO_LEGACY_LENGTH	48
+-
+-#ifdef BRCM_FULLMAC
+-#define	WLC_IOCTL_SMLEN			256	/* "small" length ioctl buffer required */
+-#define WLC_IOCTL_MEDLEN		1536	/* "med" length ioctl buffer required */
+-#define	WLC_IOCTL_MAXLEN	8192
+-#endif
+-
+-/* common ioctl definitions */
+-#define WLC_GET_MAGIC				0
+-#define WLC_GET_VERSION				1
+-#define WLC_UP					2
+-#define WLC_DOWN				3
+-#define WLC_GET_LOOP				4
+-#define WLC_SET_LOOP				5
+-#define WLC_DUMP				6
+-#define WLC_GET_MSGLEVEL			7
+-#define WLC_SET_MSGLEVEL			8
+-#define WLC_GET_PROMISC				9
+-#define WLC_SET_PROMISC				10
+-#define WLC_OVERLAY_IOCTL			11
+-#define WLC_GET_RATE				12
+-						      /* #define WLC_SET_RATE				13 *//* no longer supported */
+-#define WLC_GET_INSTANCE			14
+-						      /* #define WLC_GET_FRAG				15 *//* no longer supported */
+-						      /* #define WLC_SET_FRAG				16 *//* no longer supported */
+-						      /* #define WLC_GET_RTS				17 *//* no longer supported */
+-						      /* #define WLC_SET_RTS				18 *//* no longer supported */
+-#define WLC_GET_INFRA				19
+-#define WLC_SET_INFRA				20
+-#define WLC_GET_AUTH				21
+-#define WLC_SET_AUTH				22
+-#define WLC_GET_BSSID				23
+-#define WLC_SET_BSSID				24
+-#define WLC_GET_SSID				25
+-#define WLC_SET_SSID				26
+-#define WLC_RESTART				27
+-						      /* #define WLC_DUMP_SCB				28 *//* no longer supported */
+-#define WLC_GET_CHANNEL				29
+-#define WLC_SET_CHANNEL				30
+-#define WLC_GET_SRL				31
+-#define WLC_SET_SRL				32
+-#define WLC_GET_LRL				33
+-#define WLC_SET_LRL				34
+-#define WLC_GET_PLCPHDR				35
+-#define WLC_SET_PLCPHDR				36
+-#define WLC_GET_RADIO				37
+-#define WLC_SET_RADIO				38
+-#define WLC_GET_PHYTYPE				39
+-#define WLC_DUMP_RATE				40
+-#define WLC_SET_RATE_PARAMS			41
+-#define WLC_GET_FIXRATE				42
+-#define WLC_SET_FIXRATE				43
+-						      /* #define WLC_GET_WEP				42 *//* no longer supported */
+-						      /* #define WLC_SET_WEP				43 *//* no longer supported */
+-#define WLC_GET_KEY				44
+-#define WLC_SET_KEY				45
+-#define WLC_GET_REGULATORY			46
+-#define WLC_SET_REGULATORY			47
+-#define WLC_GET_PASSIVE_SCAN			48
+-#define WLC_SET_PASSIVE_SCAN			49
+-#define WLC_SCAN				50
+-#define WLC_SCAN_RESULTS			51
+-#define WLC_DISASSOC				52
+-#define WLC_REASSOC				53
+-#define WLC_GET_ROAM_TRIGGER			54
+-#define WLC_SET_ROAM_TRIGGER			55
+-#define WLC_GET_ROAM_DELTA			56
+-#define WLC_SET_ROAM_DELTA			57
+-#define WLC_GET_ROAM_SCAN_PERIOD		58
+-#define WLC_SET_ROAM_SCAN_PERIOD		59
+-#define WLC_EVM					60	/* diag */
+-#define WLC_GET_TXANT				61
+-#define WLC_SET_TXANT				62
+-#define WLC_GET_ANTDIV				63
+-#define WLC_SET_ANTDIV				64
+-						      /* #define WLC_GET_TXPWR			65 *//* no longer supported */
+-						      /* #define WLC_SET_TXPWR			66 *//* no longer supported */
+-#define WLC_GET_CLOSED				67
+-#define WLC_SET_CLOSED				68
+-#define WLC_GET_MACLIST				69
+-#define WLC_SET_MACLIST				70
+-#define WLC_GET_RATESET				71
+-#define WLC_SET_RATESET				72
+-						      /* #define WLC_GET_LOCALE			73 *//* no longer supported */
+-#define WLC_LONGTRAIN				74
+-#define WLC_GET_BCNPRD				75
+-#define WLC_SET_BCNPRD				76
+-#define WLC_GET_DTIMPRD				77
+-#define WLC_SET_DTIMPRD				78
+-#define WLC_GET_SROM				79
+-#define WLC_SET_SROM				80
+-#define WLC_GET_WEP_RESTRICT			81
+-#define WLC_SET_WEP_RESTRICT			82
+-#define WLC_GET_COUNTRY				83
+-#define WLC_SET_COUNTRY				84
+-#define WLC_GET_PM				85
+-#define WLC_SET_PM				86
+-#define WLC_GET_WAKE				87
+-#define WLC_SET_WAKE				88
+-						      /* #define WLC_GET_D11CNTS			89 *//* -> "counters" iovar */
+-#define WLC_GET_FORCELINK			90	/* ndis only */
+-#define WLC_SET_FORCELINK			91	/* ndis only */
+-#define WLC_FREQ_ACCURACY			92	/* diag */
+-#define WLC_CARRIER_SUPPRESS			93	/* diag */
+-#define WLC_GET_PHYREG				94
+-#define WLC_SET_PHYREG				95
+-#define WLC_GET_RADIOREG			96
+-#define WLC_SET_RADIOREG			97
+-#define WLC_GET_REVINFO				98
+-#define WLC_GET_UCANTDIV			99
+-#define WLC_SET_UCANTDIV			100
+-#define WLC_R_REG				101
+-#define WLC_W_REG				102
+-/* #define WLC_DIAG_LOOPBACK			103	old tray diag */
+-						       /* #define WLC_RESET_D11CNTS			104 *//* -> "reset_d11cnts" iovar */
+-#define WLC_GET_MACMODE				105
+-#define WLC_SET_MACMODE				106
+-#define WLC_GET_MONITOR				107
+-#define WLC_SET_MONITOR				108
+-#define WLC_GET_GMODE				109
+-#define WLC_SET_GMODE				110
+-#define WLC_GET_LEGACY_ERP			111
+-#define WLC_SET_LEGACY_ERP			112
+-#define WLC_GET_RX_ANT				113
+-#define WLC_GET_CURR_RATESET			114	/* current rateset */
+-#define WLC_GET_SCANSUPPRESS			115
+-#define WLC_SET_SCANSUPPRESS			116
+-#define WLC_GET_AP				117
+-#define WLC_SET_AP				118
+-#define WLC_GET_EAP_RESTRICT			119
+-#define WLC_SET_EAP_RESTRICT			120
+-#define WLC_SCB_AUTHORIZE			121
+-#define WLC_SCB_DEAUTHORIZE			122
+-#define WLC_GET_WDSLIST				123
+-#define WLC_SET_WDSLIST				124
+-#define WLC_GET_ATIM				125
+-#define WLC_SET_ATIM				126
+-#define WLC_GET_RSSI				127
+-#define WLC_GET_PHYANTDIV			128
+-#define WLC_SET_PHYANTDIV			129
+-#define WLC_AP_RX_ONLY				130
+-#define WLC_GET_TX_PATH_PWR			131
+-#define WLC_SET_TX_PATH_PWR			132
+-#define WLC_GET_WSEC				133
+-#define WLC_SET_WSEC				134
+-#define WLC_GET_PHY_NOISE			135
+-#define WLC_GET_BSS_INFO			136
+-#define WLC_GET_PKTCNTS				137
+-#define WLC_GET_LAZYWDS				138
+-#define WLC_SET_LAZYWDS				139
+-#define WLC_GET_BANDLIST			140
+-#define WLC_GET_BAND				141
+-#define WLC_SET_BAND				142
+-#define WLC_SCB_DEAUTHENTICATE			143
+-#define WLC_GET_SHORTSLOT			144
+-#define WLC_GET_SHORTSLOT_OVERRIDE		145
+-#define WLC_SET_SHORTSLOT_OVERRIDE		146
+-#define WLC_GET_SHORTSLOT_RESTRICT		147
+-#define WLC_SET_SHORTSLOT_RESTRICT		148
+-#define WLC_GET_GMODE_PROTECTION		149
+-#define WLC_GET_GMODE_PROTECTION_OVERRIDE	150
+-#define WLC_SET_GMODE_PROTECTION_OVERRIDE	151
+-#define WLC_UPGRADE				152
+-						       /* #define WLC_GET_MRATE			153 *//* no longer supported */
+-						       /* #define WLC_SET_MRATE			154 *//* no longer supported */
+-#define WLC_GET_IGNORE_BCNS			155
+-#define WLC_SET_IGNORE_BCNS			156
+-#define WLC_GET_SCB_TIMEOUT			157
+-#define WLC_SET_SCB_TIMEOUT			158
+-#define WLC_GET_ASSOCLIST			159
+-#define WLC_GET_CLK				160
+-#define WLC_SET_CLK				161
+-#define WLC_GET_UP				162
+-#define WLC_OUT					163
+-#define WLC_GET_WPA_AUTH			164
+-#define WLC_SET_WPA_AUTH			165
+-#define WLC_GET_UCFLAGS				166
+-#define WLC_SET_UCFLAGS				167
+-#define WLC_GET_PWRIDX				168
+-#define WLC_SET_PWRIDX				169
+-#define WLC_GET_TSSI				170
+-#define WLC_GET_SUP_RATESET_OVERRIDE		171
+-#define WLC_SET_SUP_RATESET_OVERRIDE		172
+-						       /* #define WLC_SET_FAST_TIMER			173 *//* no longer supported */
+-						       /* #define WLC_GET_FAST_TIMER			174 *//* no longer supported */
+-						       /* #define WLC_SET_SLOW_TIMER			175 *//* no longer supported */
+-						       /* #define WLC_GET_SLOW_TIMER			176 *//* no longer supported */
+-						       /* #define WLC_DUMP_PHYREGS			177 *//* no longer supported */
+-#define WLC_GET_PROTECTION_CONTROL		178
+-#define WLC_SET_PROTECTION_CONTROL		179
+-#define WLC_GET_PHYLIST				180
+-#define WLC_ENCRYPT_STRENGTH			181	/* ndis only */
+-#define WLC_DECRYPT_STATUS			182	/* ndis only */
+-#define WLC_GET_KEY_SEQ				183
+-#define WLC_GET_SCAN_CHANNEL_TIME		184
+-#define WLC_SET_SCAN_CHANNEL_TIME		185
+-#define WLC_GET_SCAN_UNASSOC_TIME		186
+-#define WLC_SET_SCAN_UNASSOC_TIME		187
+-#define WLC_GET_SCAN_HOME_TIME			188
+-#define WLC_SET_SCAN_HOME_TIME			189
+-#define WLC_GET_SCAN_NPROBES			190
+-#define WLC_SET_SCAN_NPROBES			191
+-#define WLC_GET_PRB_RESP_TIMEOUT		192
+-#define WLC_SET_PRB_RESP_TIMEOUT		193
+-#define WLC_GET_ATTEN				194
+-#define WLC_SET_ATTEN				195
+-#define WLC_GET_SHMEM				196	/* diag */
+-#define WLC_SET_SHMEM				197	/* diag */
+-						       /* #define WLC_GET_GMODE_PROTECTION_CTS		198 *//* no longer supported */
+-						       /* #define WLC_SET_GMODE_PROTECTION_CTS		199 *//* no longer supported */
+-#define WLC_SET_WSEC_TEST			200
+-#define WLC_SCB_DEAUTHENTICATE_FOR_REASON	201
+-#define WLC_TKIP_COUNTERMEASURES		202
+-#define WLC_GET_PIOMODE				203
+-#define WLC_SET_PIOMODE				204
+-#define WLC_SET_ASSOC_PREFER			205
+-#define WLC_GET_ASSOC_PREFER			206
+-#define WLC_SET_ROAM_PREFER			207
+-#define WLC_GET_ROAM_PREFER			208
+-#define WLC_SET_LED				209
+-#define WLC_GET_LED				210
+-#define WLC_RESERVED6				211
+-#define WLC_RESERVED7				212
+-#define WLC_GET_CHANNEL_QA			213
+-#define WLC_START_CHANNEL_QA			214
+-#define WLC_GET_CHANNEL_SEL			215
+-#define WLC_START_CHANNEL_SEL			216
+-#define WLC_GET_VALID_CHANNELS			217
+-#define WLC_GET_FAKEFRAG			218
+-#define WLC_SET_FAKEFRAG			219
+-#define WLC_GET_PWROUT_PERCENTAGE		220
+-#define WLC_SET_PWROUT_PERCENTAGE		221
+-#define WLC_SET_BAD_FRAME_PREEMPT		222
+-#define WLC_GET_BAD_FRAME_PREEMPT		223
+-#define WLC_SET_LEAP_LIST			224
+-#define WLC_GET_LEAP_LIST			225
+-#define WLC_GET_CWMIN				226
+-#define WLC_SET_CWMIN				227
+-#define WLC_GET_CWMAX				228
+-#define WLC_SET_CWMAX				229
+-#define WLC_GET_WET				230
+-#define WLC_SET_WET				231
+-#define WLC_GET_PUB				232
+-						       /* #define WLC_SET_GLACIAL_TIMER		233 *//* no longer supported */
+-						       /* #define WLC_GET_GLACIAL_TIMER		234 *//* no longer supported */
+-#define WLC_GET_KEY_PRIMARY			235
+-#define WLC_SET_KEY_PRIMARY			236
+-						       /* #define WLC_DUMP_RADIOREGS			237 *//* no longer supported */
+-#define WLC_RESERVED4				238
+-#define WLC_RESERVED5				239
+-#define WLC_UNSET_CALLBACK			240
+-#define WLC_SET_CALLBACK			241
+-#define WLC_GET_RADAR				242
+-#define WLC_SET_RADAR				243
+-#define WLC_SET_SPECT_MANAGMENT			244
+-#define WLC_GET_SPECT_MANAGMENT			245
+-#define WLC_WDS_GET_REMOTE_HWADDR		246	/* handled in wl_linux.c/wl_vx.c */
+-#define WLC_WDS_GET_WPA_SUP			247
+-#define WLC_SET_CS_SCAN_TIMER			248
+-#define WLC_GET_CS_SCAN_TIMER			249
+-#define WLC_MEASURE_REQUEST			250
+-#define WLC_INIT				251
+-#define WLC_SEND_QUIET				252
+-#define WLC_KEEPALIVE			253
+-#define WLC_SEND_PWR_CONSTRAINT			254
+-#define WLC_UPGRADE_STATUS			255
+-#define WLC_CURRENT_PWR				256
+-#define WLC_GET_SCAN_PASSIVE_TIME		257
+-#define WLC_SET_SCAN_PASSIVE_TIME		258
+-#define WLC_LEGACY_LINK_BEHAVIOR		259
+-#define WLC_GET_CHANNELS_IN_COUNTRY		260
+-#define WLC_GET_COUNTRY_LIST			261
+-#define WLC_GET_VAR				262	/* get value of named variable */
+-#define WLC_SET_VAR				263	/* set named variable to value */
+-#define WLC_NVRAM_GET				264	/* deprecated */
+-#define WLC_NVRAM_SET				265
+-#define WLC_NVRAM_DUMP				266
+-#define WLC_REBOOT				267
+-#define WLC_SET_WSEC_PMK			268
+-#define WLC_GET_AUTH_MODE			269
+-#define WLC_SET_AUTH_MODE			270
+-#define WLC_GET_WAKEENTRY			271
+-#define WLC_SET_WAKEENTRY			272
+-#define WLC_NDCONFIG_ITEM			273	/* currently handled in wl_oid.c */
+-#define WLC_NVOTPW				274
+-#define WLC_OTPW				275
+-#define WLC_IOV_BLOCK_GET			276
+-#define WLC_IOV_MODULES_GET			277
+-#define WLC_SOFT_RESET				278
+-#define WLC_GET_ALLOW_MODE			279
+-#define WLC_SET_ALLOW_MODE			280
+-#define WLC_GET_DESIRED_BSSID			281
+-#define WLC_SET_DESIRED_BSSID			282
+-#define	WLC_DISASSOC_MYAP			283
+-#define WLC_GET_RESERVED10			284
+-#define WLC_GET_RESERVED11			285
+-#define WLC_GET_RESERVED12			286
+-#define WLC_GET_RESERVED13			287
+-#define WLC_GET_RESERVED14			288
+-#define WLC_SET_RESERVED15			289
+-#define WLC_SET_RESERVED16			290
+-#define WLC_GET_RESERVED17			291
+-#define WLC_GET_RESERVED18			292
+-#define WLC_GET_RESERVED19			293
+-#define WLC_SET_RESERVED1A			294
+-#define WLC_GET_RESERVED1B			295
+-#define WLC_GET_RESERVED1C			296
+-#define WLC_GET_RESERVED1D			297
+-#define WLC_SET_RESERVED1E			298
+-#define WLC_GET_RESERVED1F			299
+-#define WLC_GET_RESERVED20			300
+-#define WLC_GET_RESERVED21			301
+-#define WLC_GET_RESERVED22			302
+-#define WLC_GET_RESERVED23			303
+-#define WLC_GET_RESERVED24			304
+-#define WLC_SET_RESERVED25			305
+-#define WLC_GET_RESERVED26			306
+-#define WLC_NPHY_SAMPLE_COLLECT			307	/* Nphy sample collect mode */
+-#define WLC_UM_PRIV				308	/* for usermode driver private ioctl */
+-#define WLC_GET_CMD				309
+-							/* #define WLC_LAST				310 *//* Never used - can be reused */
+-#define WLC_RESERVED8				311
+-#define WLC_RESERVED9				312
+-#define WLC_RESERVED1				313
+-#define WLC_RESERVED2				314
+-#define WLC_RESERVED3				315
+-#define WLC_LAST				316
+-
+-#ifndef EPICTRL_COOKIE
+-#define EPICTRL_COOKIE		0xABADCEDE
+-#endif
+-
+-#define WL_DECRYPT_STATUS_SUCCESS	1
+-#define WL_DECRYPT_STATUS_FAILURE	2
+-#define WL_DECRYPT_STATUS_UNKNOWN	3
+-
+-/* allows user-mode app to poll the status of USB image upgrade */
+-#define WLC_UPGRADE_SUCCESS			0
+-#define WLC_UPGRADE_PENDING			1
+-
+-/* WLC_GET_AUTH, WLC_SET_AUTH values */
+-#define WL_AUTH_OPEN_SYSTEM		0	/* d11 open authentication */
+-#define WL_AUTH_SHARED_KEY		1	/* d11 shared authentication */
+-#define WL_AUTH_OPEN_SHARED		2	/* try open, then shared if open failed w/rc 13 */
+-
+-/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
+-#define WL_RADIO_SW_DISABLE		(1<<0)
+-#define WL_RADIO_HW_DISABLE		(1<<1)
+-#define WL_RADIO_MPC_DISABLE		(1<<2)
+-#define WL_RADIO_COUNTRY_DISABLE	(1<<3)	/* some countries don't support any channel */
+-
+-#define	WL_SPURAVOID_OFF	0
+-#define	WL_SPURAVOID_ON1	1
+-#define	WL_SPURAVOID_ON2	2
+-
+-/* Override bit for WLC_SET_TXPWR.  if set, ignore other level limits */
+-#define WL_TXPWR_OVERRIDE	(1U<<31)
+-
+-#define WL_PHY_PAVARS_LEN	6	/* Phy type, Band range, chain, a1, b0, b1 */
+-
+-typedef struct wl_po {
+-	u16 phy_type;	/* Phy type */
+-	u16 band;
+-	u16 cckpo;
+-	u32 ofdmpo;
+-	u16 mcspo[8];
+-} wl_po_t;
+-
+-/* a large TX Power as an init value to factor out of min() calculations,
+- * keep low enough to fit in an s8, units are .25 dBm
+- */
+-#define WLC_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
+-
+-/* "diag" iovar argument and error code */
+-#define WL_DIAG_INTERRUPT			1	/* d11 loopback interrupt test */
+-#define WL_DIAG_LOOPBACK			2	/* d11 loopback data test */
+-#define WL_DIAG_MEMORY				3	/* d11 memory test */
+-#define WL_DIAG_LED				4	/* LED test */
+-#define WL_DIAG_REG				5	/* d11/phy register test */
+-#define WL_DIAG_SROM				6	/* srom read/crc test */
+-#define WL_DIAG_DMA				7	/* DMA test */
+-
+-#define WL_DIAGERR_SUCCESS			0
+-#define WL_DIAGERR_FAIL_TO_RUN			1	/* unable to run requested diag */
+-#define WL_DIAGERR_NOT_SUPPORTED		2	/* diag requested is not supported */
+-#define WL_DIAGERR_INTERRUPT_FAIL		3	/* loopback interrupt test failed */
+-#define WL_DIAGERR_LOOPBACK_FAIL		4	/* loopback data test failed */
+-#define WL_DIAGERR_SROM_FAIL			5	/* srom read failed */
+-#define WL_DIAGERR_SROM_BADCRC			6	/* srom crc failed */
+-#define WL_DIAGERR_REG_FAIL			7	/* d11/phy register test failed */
+-#define WL_DIAGERR_MEMORY_FAIL			8	/* d11 memory test failed */
+-#define WL_DIAGERR_NOMEM			9	/* diag test failed due to no memory */
+-#define WL_DIAGERR_DMA_FAIL			10	/* DMA test failed */
+-
+-#define WL_DIAGERR_MEMORY_TIMEOUT		11	/* d11 memory test didn't finish in time */
+-#define WL_DIAGERR_MEMORY_BADPATTERN		12	/* d11 memory test result in bad pattern */
+-
+-/* band types */
+-#define	WLC_BAND_AUTO		0	/* auto-select */
+-#define	WLC_BAND_5G		1	/* 5 Ghz */
+-#define	WLC_BAND_2G		2	/* 2.4 Ghz */
+-#define	WLC_BAND_ALL		3	/* all bands */
+-
+-/* band range returned by band_range iovar */
+-#define WL_CHAN_FREQ_RANGE_2G      0
+-#define WL_CHAN_FREQ_RANGE_5GL     1
+-#define WL_CHAN_FREQ_RANGE_5GM     2
+-#define WL_CHAN_FREQ_RANGE_5GH     3
+-
+-/* phy types (returned by WLC_GET_PHYTPE) */
+-#define	WLC_PHY_TYPE_A		0
+-#define	WLC_PHY_TYPE_B		1
+-#define	WLC_PHY_TYPE_G		2
+-#define	WLC_PHY_TYPE_N		4
+-#define	WLC_PHY_TYPE_LP		5
+-#define	WLC_PHY_TYPE_SSN	6
+-#define	WLC_PHY_TYPE_HT		7
+-#define	WLC_PHY_TYPE_LCN	8
+-#define	WLC_PHY_TYPE_NULL	0xf
+-
+-/* MAC list modes */
+-#define WLC_MACMODE_DISABLED	0	/* MAC list disabled */
+-#define WLC_MACMODE_DENY	1	/* Deny specified (i.e. allow unspecified) */
+-#define WLC_MACMODE_ALLOW	2	/* Allow specified (i.e. deny unspecified) */
+-
+-/*
+- * 54g modes (basic bits may still be overridden)
+- *
+- * GMODE_LEGACY_B			Rateset: 1b, 2b, 5.5, 11
+- *					Preamble: Long
+- *					Shortslot: Off
+- * GMODE_AUTO				Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+- *					Extended Rateset: 6, 9, 12, 48
+- *					Preamble: Long
+- *					Shortslot: Auto
+- * GMODE_ONLY				Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54
+- *					Extended Rateset: 6b, 9, 12b, 48
+- *					Preamble: Short required
+- *					Shortslot: Auto
+- * GMODE_B_DEFERRED			Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54
+- *					Extended Rateset: 6, 9, 12, 48
+- *					Preamble: Long
+- *					Shortslot: On
+- * GMODE_PERFORMANCE			Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54
+- *					Preamble: Short required
+- *					Shortslot: On and required
+- * GMODE_LRS				Rateset: 1b, 2b, 5.5b, 11b
+- *					Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54
+- *					Preamble: Long
+- *					Shortslot: Auto
+- */
+-#define GMODE_LEGACY_B		0
+-#define GMODE_AUTO		1
+-#define GMODE_ONLY		2
+-#define GMODE_B_DEFERRED	3
+-#define GMODE_PERFORMANCE	4
+-#define GMODE_LRS		5
+-#define GMODE_MAX		6
+-
+-/* values for PLCPHdr_override */
+-#define WLC_PLCP_AUTO	-1
+-#define WLC_PLCP_SHORT	0
+-#define WLC_PLCP_LONG	1
+-
+-/* values for g_protection_override and n_protection_override */
+-#define WLC_PROTECTION_AUTO		-1
+-#define WLC_PROTECTION_OFF		0
+-#define WLC_PROTECTION_ON		1
+-#define WLC_PROTECTION_MMHDR_ONLY	2
+-#define WLC_PROTECTION_CTS_ONLY		3
+-
+-/* values for g_protection_control and n_protection_control */
+-#define WLC_PROTECTION_CTL_OFF		0
+-#define WLC_PROTECTION_CTL_LOCAL	1
+-#define WLC_PROTECTION_CTL_OVERLAP	2
+-
+-/* values for n_protection */
+-#define WLC_N_PROTECTION_OFF		0
+-#define WLC_N_PROTECTION_OPTIONAL	1
+-#define WLC_N_PROTECTION_20IN40		2
+-#define WLC_N_PROTECTION_MIXEDMODE	3
+-
+-/* values for n_preamble_type */
+-#define WLC_N_PREAMBLE_MIXEDMODE	0
+-#define WLC_N_PREAMBLE_GF		1
+-#define WLC_N_PREAMBLE_GF_BRCM          2
+-
+-/* values for band specific 40MHz capabilities */
+-#define WLC_N_BW_20ALL			0
+-#define WLC_N_BW_40ALL			1
+-#define WLC_N_BW_20IN2G_40IN5G		2
+-
+-/* values to force tx/rx chain */
+-#define WLC_N_TXRX_CHAIN0		0
+-#define WLC_N_TXRX_CHAIN1		1
+-
+-/* bitflags for SGI support (sgi_rx iovar) */
+-#define WLC_N_SGI_20			0x01
+-#define WLC_N_SGI_40			0x02
+-
+-/* Values for PM */
+-#define PM_OFF	0
+-#define PM_MAX	1
+-
+-/* interference mitigation options */
+-#define	INTERFERE_OVRRIDE_OFF	-1	/* interference override off */
+-#define	INTERFERE_NONE	0	/* off */
+-#define	NON_WLAN	1	/* foreign/non 802.11 interference, no auto detect */
+-#define	WLAN_MANUAL	2	/* ACI: no auto detection */
+-#define	WLAN_AUTO	3	/* ACI: auto detect */
+-#define	WLAN_AUTO_W_NOISE	4	/* ACI: auto - detect and non 802.11 interference */
+-#define	AUTO_ACTIVE	(1 << 7)	/* Auto is currently active */
+-
+-#define WL_RSSI_ANT_VERSION	1	/* current version of wl_rssi_ant_t */
+-#define WL_ANT_RX_MAX		2	/* max 2 receive antennas */
+-#define WL_ANT_HT_RX_MAX	3	/* max 3 receive antennas/cores */
+-#define WL_ANT_IDX_1		0	/* antenna index 1 */
+-#define WL_ANT_IDX_2		1	/* antenna index 2 */
+-
+-#ifndef WL_RSSI_ANT_MAX
+-#define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
+-#elif WL_RSSI_ANT_MAX != 4
+-#error "WL_RSSI_ANT_MAX does not match"
+-#endif
+-
+-/* RSSI per antenna */
+-typedef struct {
+-	u32 version;		/* version field */
+-	u32 count;		/* number of valid antenna rssi */
+-	s8 rssi_ant[WL_RSSI_ANT_MAX];	/* rssi per antenna */
+-} wl_rssi_ant_t;
+-
+-#define NUM_PWRCTRL_RATES 12
+-
+-typedef struct {
+-	u8 txpwr_band_max[NUM_PWRCTRL_RATES];	/* User set target */
+-	u8 txpwr_limit[NUM_PWRCTRL_RATES];	/* reg and local power limit */
+-	u8 txpwr_local_max;	/* local max according to the AP */
+-	u8 txpwr_local_constraint;	/* local constraint according to the AP */
+-	u8 txpwr_chan_reg_max;	/* Regulatory max for this channel */
+-	u8 txpwr_target[2][NUM_PWRCTRL_RATES];	/* Latest target for 2.4 and 5 Ghz */
+-	u8 txpwr_est_Pout[2];	/* Latest estimate for 2.4 and 5 Ghz */
+-	u8 txpwr_opo[NUM_PWRCTRL_RATES];	/* On G phy, OFDM power offset */
+-	u8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES];	/* Max CCK power for this band (SROM) */
+-	u8 txpwr_bphy_ofdm_max;	/* Max OFDM power for this band (SROM) */
+-	u8 txpwr_aphy_max[NUM_PWRCTRL_RATES];	/* Max power for A band (SROM) */
+-	s8 txpwr_antgain[2];	/* Ant gain for each band - from SROM */
+-	u8 txpwr_est_Pout_gofdm;	/* Pwr estimate for 2.4 OFDM */
+-} tx_power_legacy_t;
+-
+-#define WL_TX_POWER_RATES_LEGACY	45
+-#define WL_TX_POWER_MCS20_FIRST	        12
+-#define WL_TX_POWER_MCS20_NUM	        16
+-#define WL_TX_POWER_MCS40_FIRST	        28
+-#define WL_TX_POWER_MCS40_NUM	        17
+-
+-
+-#define WL_TX_POWER_RATES	       101
+-#define WL_TX_POWER_CCK_FIRST	       0
+-#define WL_TX_POWER_CCK_NUM	       4
+-#define WL_TX_POWER_OFDM_FIRST	       4	/* Index for first 20MHz OFDM SISO rate */
+-#define WL_TX_POWER_OFDM20_CDD_FIRST   12	/* Index for first 20MHz OFDM CDD rate */
+-#define WL_TX_POWER_OFDM40_SISO_FIRST  52	/* Index for first 40MHz OFDM SISO rate */
+-#define WL_TX_POWER_OFDM40_CDD_FIRST   60	/* Index for first 40MHz OFDM CDD rate */
+-#define WL_TX_POWER_OFDM_NUM	       8
+-#define WL_TX_POWER_MCS20_SISO_FIRST   20	/* Index for first 20MHz MCS SISO rate */
+-#define WL_TX_POWER_MCS20_CDD_FIRST    28	/* Index for first 20MHz MCS CDD rate */
+-#define WL_TX_POWER_MCS20_STBC_FIRST   36	/* Index for first 20MHz MCS STBC rate */
+-#define WL_TX_POWER_MCS20_SDM_FIRST    44	/* Index for first 20MHz MCS SDM rate */
+-#define WL_TX_POWER_MCS40_SISO_FIRST   68	/* Index for first 40MHz MCS SISO rate */
+-#define WL_TX_POWER_MCS40_CDD_FIRST    76	/* Index for first 40MHz MCS CDD rate */
+-#define WL_TX_POWER_MCS40_STBC_FIRST   84	/* Index for first 40MHz MCS STBC rate */
+-#define WL_TX_POWER_MCS40_SDM_FIRST    92	/* Index for first 40MHz MCS SDM rate */
+-#define WL_TX_POWER_MCS_1_STREAM_NUM   8
+-#define WL_TX_POWER_MCS_2_STREAM_NUM   8
+-#define WL_TX_POWER_MCS_32	       100	/* Index for 40MHz rate MCS 32 */
+-#define WL_TX_POWER_MCS_32_NUM	       1
+-
+-/* sslpnphy specifics */
+-#define WL_TX_POWER_MCS20_SISO_FIRST_SSN   12	/* Index for first 20MHz MCS SISO rate */
+-
+-/* tx_power_t.flags bits */
+-#define WL_TX_POWER_F_ENABLED	1
+-#define WL_TX_POWER_F_HW	2
+-#define WL_TX_POWER_F_MIMO	4
+-#define WL_TX_POWER_F_SISO	8
+-
+-typedef struct {
+-	u32 flags;
+-	chanspec_t chanspec;	/* txpwr report for this channel */
+-	chanspec_t local_chanspec;	/* channel on which we are associated */
+-	u8 local_max;	/* local max according to the AP */
+-	u8 local_constraint;	/* local constraint according to the AP */
+-	s8 antgain[2];	/* Ant gain for each band - from SROM */
+-	u8 rf_cores;		/* count of RF Cores being reported */
+-	u8 est_Pout[4];	/* Latest tx power out estimate per RF chain */
+-	u8 est_Pout_act[4];	/* Latest tx power out estimate per RF chain
+-				 * without adjustment
+-				 */
+-	u8 est_Pout_cck;	/* Latest CCK tx power out estimate */
+-	u8 tx_power_max[4];	/* Maximum target power among all rates */
+-	u8 tx_power_max_rate_ind[4];	/* Index of the rate with the max target power */
+-	u8 user_limit[WL_TX_POWER_RATES];	/* User limit */
+-	u8 reg_limit[WL_TX_POWER_RATES];	/* Regulatory power limit */
+-	u8 board_limit[WL_TX_POWER_RATES];	/* Max power board can support (SROM) */
+-	u8 target[WL_TX_POWER_RATES];	/* Latest target power */
+-} tx_power_t;
+-
+-typedef struct tx_inst_power {
+-	u8 txpwr_est_Pout[2];	/* Latest estimate for 2.4 and 5 Ghz */
+-	u8 txpwr_est_Pout_gofdm;	/* Pwr estimate for 2.4 OFDM */
+-} tx_inst_power_t;
+-
+-/* Message levels */
+-#define WL_ERROR_VAL		0x00000001
+-#define WL_TRACE_VAL		0x00000002
+-
+-/* maximum channels returned by the get valid channels iovar */
+-#define WL_NUMCHANNELS		64
+-#define WL_NUMCHANSPECS		100
+-
+-struct tsinfo_arg {
+-	u8 octets[3];
+-};
+-
+-#define	NFIFO			6	/* # tx/rx fifopairs */
+-
+-struct wl_msglevel2 {
+-	u32 low;
+-	u32 high;
+-};
+-
+-/* structure for per-tid ampdu control */
+-struct ampdu_tid_control {
+-	u8 tid;		/* tid */
+-	u8 enable;		/* enable/disable */
+-};
+-
+-/* structure for identifying ea/tid for sending addba/delba */
+-struct ampdu_ea_tid {
+-	u8 ea[ETH_ALEN];	/* Station address */
+-	u8 tid;		/* tid */
+-};
+-/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */
+-struct ampdu_retry_tid {
+-	u8 tid;		/* tid */
+-	u8 retry;		/* retry value */
+-};
+-
+-
+-/* Software feature flag defines used by wlfeatureflag */
+-#define WL_SWFL_NOHWRADIO	0x0004
+-#define WL_SWFL_FLOWCONTROL     0x0008	/* Enable backpressure to OS stack */
+-#define WL_SWFL_WLBSSSORT	0x0010	/* Per-port supports sorting of BSS */
+-
+-#define WL_LIFETIME_MAX 0xFFFF	/* Max value in ms */
+-
+-
+-/* Pattern matching filter. Specifies an offset within received packets to
+- * start matching, the pattern to match, the size of the pattern, and a bitmask
+- * that indicates which bits within the pattern should be matched.
+- */
+-typedef struct wl_pkt_filter_pattern {
+-	u32 offset;		/* Offset within received packet to start pattern matching.
+-				 * Offset '0' is the first byte of the ethernet header.
+-				 */
+-	u32 size_bytes;	/* Size of the pattern.  Bitmask must be the same size. */
+-	u8 mask_and_pattern[1];	/* Variable length mask and pattern data.  mask starts
+-					 * at offset 0.  Pattern immediately follows mask.
+-					 */
+-} wl_pkt_filter_pattern_t;
+-
+-/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
+-typedef struct wl_pkt_filter {
+-	u32 id;		/* Unique filter id, specified by app. */
+-	u32 type;		/* Filter type (WL_PKT_FILTER_TYPE_xxx). */
+-	u32 negate_match;	/* Negate the result of filter matches */
+-	union {			/* Filter definitions */
+-		wl_pkt_filter_pattern_t pattern;	/* Pattern matching filter */
+-	} u;
+-} wl_pkt_filter_t;
+-
+-#define WL_PKT_FILTER_FIXED_LEN		  offsetof(wl_pkt_filter_t, u)
+-#define WL_PKT_FILTER_PATTERN_FIXED_LEN	  offsetof(wl_pkt_filter_pattern_t, mask_and_pattern)
+-
+-/* IOVAR "pkt_filter_enable" parameter. */
+-typedef struct wl_pkt_filter_enable {
+-	u32 id;		/* Unique filter id */
+-	u32 enable;		/* Enable/disable bool */
+-} wl_pkt_filter_enable_t;
+-
+-
+-#define	WLC_RSSI_INVALID	 0	/* invalid RSSI value */
+-
+-/* n-mode support capability */
+-/* 2x2 includes both 1x1 & 2x2 devices
+- * reserved #define 2 for future when we want to separate 1x1 & 2x2 and
+- * control it independently
+- */
+-#define WL_11N_2x2			1
+-#define WL_11N_3x3			3
+-#define WL_11N_4x4			4
+-
+-/* define 11n feature disable flags */
+-#define WLFEATURE_DISABLE_11N		0x00000001
+-#define WLFEATURE_DISABLE_11N_STBC_TX	0x00000002
+-#define WLFEATURE_DISABLE_11N_STBC_RX	0x00000004
+-#define WLFEATURE_DISABLE_11N_SGI_TX	0x00000008
+-#define WLFEATURE_DISABLE_11N_SGI_RX	0x00000010
+-#define WLFEATURE_DISABLE_11N_AMPDU_TX	0x00000020
+-#define WLFEATURE_DISABLE_11N_AMPDU_RX	0x00000040
+-#define WLFEATURE_DISABLE_11N_GF	0x00000080
+-
+-#define WL_EVENTING_MASK_LEN	16
+-
+-#define TOE_TX_CSUM_OL		0x00000001
+-#define TOE_RX_CSUM_OL		0x00000002
+-
+-#define PM_OFF	0
+-#define PM_MAX	1
+-#define PM_FAST 2
+-
+-typedef enum sup_auth_status {
+-	WLC_SUP_DISCONNECTED = 0,
+-	WLC_SUP_CONNECTING,
+-	WLC_SUP_IDREQUIRED,
+-	WLC_SUP_AUTHENTICATING,
+-	WLC_SUP_AUTHENTICATED,
+-	WLC_SUP_KEYXCHANGE,
+-	WLC_SUP_KEYED,
+-	WLC_SUP_TIMEOUT,
+-	WLC_SUP_LAST_BASIC_STATE,
+-	WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED,
+-	WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE,
+-	WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE,
+-	WLC_SUP_KEYXCHANGE_PREP_M4,
+-	WLC_SUP_KEYXCHANGE_WAIT_G1,
+-	WLC_SUP_KEYXCHANGE_PREP_G2
+-} sup_auth_status_t;
+-#endif				/* _wlioctl_h_ */
+diff --git a/drivers/staging/brcm80211/util/Makefile b/drivers/staging/brcm80211/util/Makefile
+deleted file mode 100644
+index f9b36ca..0000000
+--- a/drivers/staging/brcm80211/util/Makefile
++++ /dev/null
+@@ -1,29 +0,0 @@
+-#
+-# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
+-#
+-# Copyright (c) 2011 Broadcom Corporation
+-#
+-# Permission to use, copy, modify, and/or distribute this software for any
+-# purpose with or without fee is hereby granted, provided that the above
+-# copyright notice and this permission notice appear in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+-# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+-# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-ccflags-y :=				\
+-	-Idrivers/staging/brcm80211/util \
+-	-Idrivers/staging/brcm80211/include
+-
+-BRCMUTIL_OFILES := \
+-	bcmutils.o \
+-	bcmwifi.o
+-
+-MODULEPFX := brcmutil
+-
+-obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
+-$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
+diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c
+deleted file mode 100644
+index 43e5bb3..0000000
+--- a/drivers/staging/brcm80211/util/bcmutils.c
++++ /dev/null
+@@ -1,796 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include <linux/ctype.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/module.h>
+-#include <linux/pci.h>
+-#include <linux/netdevice.h>
+-#include <linux/sched.h>
+-#include <linux/printk.h>
+-#include <bcmdefs.h>
+-#include <stdarg.h>
+-#include <bcmutils.h>
+-#include <bcmnvram.h>
+-#include <bcmdevs.h>
+-#include <proto/802.11.h>
+-
+-MODULE_AUTHOR("Broadcom Corporation");
+-MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
+-MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+-MODULE_LICENSE("Dual BSD/GPL");
+-
+-struct sk_buff *bcm_pkt_buf_get_skb(uint len)
+-{
+-	struct sk_buff *skb;
+-
+-	skb = dev_alloc_skb(len);
+-	if (skb) {
+-		skb_put(skb, len);
+-		skb->priority = 0;
+-	}
+-
+-	return skb;
+-}
+-EXPORT_SYMBOL(bcm_pkt_buf_get_skb);
+-
+-/* Free the driver packet. Free the tag if present */
+-void bcm_pkt_buf_free_skb(struct sk_buff *skb)
+-{
+-	struct sk_buff *nskb;
+-	int nest = 0;
+-
+-	/* perversion: we use skb->next to chain multi-skb packets */
+-	while (skb) {
+-		nskb = skb->next;
+-		skb->next = NULL;
+-
+-		if (skb->destructor)
+-			/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
+-			 * destructor exists
+-			 */
+-			dev_kfree_skb_any(skb);
+-		else
+-			/* can free immediately (even in_irq()) if destructor
+-			 * does not exist
+-			 */
+-			dev_kfree_skb(skb);
+-
+-		nest++;
+-		skb = nskb;
+-	}
+-}
+-EXPORT_SYMBOL(bcm_pkt_buf_free_skb);
+-
+-
+-/* copy a buffer into a pkt buffer chain */
+-uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len,
+-		unsigned char *buf)
+-{
+-	uint n, ret = 0;
+-
+-	/* skip 'offset' bytes */
+-	for (; p && offset; p = p->next) {
+-		if (offset < (uint) (p->len))
+-			break;
+-		offset -= p->len;
+-	}
+-
+-	if (!p)
+-		return 0;
+-
+-	/* copy the data */
+-	for (; p && len; p = p->next) {
+-		n = min((uint) (p->len) - offset, (uint) len);
+-		memcpy(p->data + offset, buf, n);
+-		buf += n;
+-		len -= n;
+-		ret += n;
+-		offset = 0;
+-	}
+-
+-	return ret;
+-}
+-EXPORT_SYMBOL(bcm_pktfrombuf);
+-
+-/* return total length of buffer chain */
+-uint bcm_pkttotlen(struct sk_buff *p)
+-{
+-	uint total;
+-
+-	total = 0;
+-	for (; p; p = p->next)
+-		total += p->len;
+-	return total;
+-}
+-EXPORT_SYMBOL(bcm_pkttotlen);
+-
+-/*
+- * osl multiple-precedence packet queue
+- * hi_prec is always >= the number of the highest non-empty precedence
+- */
+-struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
+-				      struct sk_buff *p)
+-{
+-	struct pktq_prec *q;
+-
+-	if (pktq_full(pq) || pktq_pfull(pq, prec))
+-		return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	if (q->head)
+-		q->tail->prev = p;
+-	else
+-		q->head = p;
+-
+-	q->tail = p;
+-	q->len++;
+-
+-	pq->len++;
+-
+-	if (pq->hi_prec < prec)
+-		pq->hi_prec = (u8) prec;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_penq);
+-
+-struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
+-					   struct sk_buff *p)
+-{
+-	struct pktq_prec *q;
+-
+-	if (pktq_full(pq) || pktq_pfull(pq, prec))
+-		return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	if (q->head == NULL)
+-		q->tail = p;
+-
+-	p->prev = q->head;
+-	q->head = p;
+-	q->len++;
+-
+-	pq->len++;
+-
+-	if (pq->hi_prec < prec)
+-		pq->hi_prec = (u8) prec;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_penq_head);
+-
+-struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	q->head = p->prev;
+-	if (q->head == NULL)
+-		q->tail = NULL;
+-
+-	q->len--;
+-
+-	pq->len--;
+-
+-	p->prev = NULL;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_pdeq);
+-
+-struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p, *prev;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	for (prev = NULL; p != q->tail; p = p->prev)
+-		prev = p;
+-
+-	if (prev)
+-		prev->prev = NULL;
+-	else
+-		q->head = NULL;
+-
+-	q->tail = prev;
+-	q->len--;
+-
+-	pq->len--;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_pdeq_tail);
+-
+-void
+-bcm_pktq_pflush(struct pktq *pq, int prec, bool dir,
+-	    ifpkt_cb_t fn, void *arg)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p, *prev = NULL;
+-
+-	q = &pq->q[prec];
+-	p = q->head;
+-	while (p) {
+-		if (fn == NULL || (*fn) (p, arg)) {
+-			bool head = (p == q->head);
+-			if (head)
+-				q->head = p->prev;
+-			else
+-				prev->prev = p->prev;
+-			p->prev = NULL;
+-			bcm_pkt_buf_free_skb(p);
+-			q->len--;
+-			pq->len--;
+-			p = (head ? q->head : prev->prev);
+-		} else {
+-			prev = p;
+-			p = p->prev;
+-		}
+-	}
+-
+-	if (q->head == NULL) {
+-		q->tail = NULL;
+-	}
+-}
+-EXPORT_SYMBOL(bcm_pktq_pflush);
+-
+-void bcm_pktq_flush(struct pktq *pq, bool dir,
+-		ifpkt_cb_t fn, void *arg)
+-{
+-	int prec;
+-	for (prec = 0; prec < pq->num_prec; prec++)
+-		bcm_pktq_pflush(pq, prec, dir, fn, arg);
+-}
+-EXPORT_SYMBOL(bcm_pktq_flush);
+-
+-void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len)
+-{
+-	int prec;
+-
+-	/* pq is variable size; only zero out what's requested */
+-	memset(pq, 0,
+-	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
+-
+-	pq->num_prec = (u16) num_prec;
+-
+-	pq->max = (u16) max_len;
+-
+-	for (prec = 0; prec < num_prec; prec++)
+-		pq->q[prec].max = pq->max;
+-}
+-EXPORT_SYMBOL(bcm_pktq_init);
+-
+-struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out)
+-{
+-	int prec;
+-
+-	if (pq->len == 0)
+-		return NULL;
+-
+-	for (prec = 0; prec < pq->hi_prec; prec++)
+-		if (pq->q[prec].head)
+-			break;
+-
+-	if (prec_out)
+-		*prec_out = prec;
+-
+-	return pq->q[prec].tail;
+-}
+-EXPORT_SYMBOL(bcm_pktq_peek_tail);
+-
+-/* Return sum of lengths of a specific set of precedences */
+-int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp)
+-{
+-	int prec, len;
+-
+-	len = 0;
+-
+-	for (prec = 0; prec <= pq->hi_prec; prec++)
+-		if (prec_bmp & (1 << prec))
+-			len += pq->q[prec].len;
+-
+-	return len;
+-}
+-EXPORT_SYMBOL(bcm_pktq_mlen);
+-
+-/* Priority dequeue from a specific set of precedences */
+-struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
+-				      int *prec_out)
+-{
+-	struct pktq_prec *q;
+-	struct sk_buff *p;
+-	int prec;
+-
+-	if (pq->len == 0)
+-		return NULL;
+-
+-	while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
+-		pq->hi_prec--;
+-
+-	while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
+-		if (prec-- == 0)
+-			return NULL;
+-
+-	q = &pq->q[prec];
+-
+-	p = q->head;
+-	if (p == NULL)
+-		return NULL;
+-
+-	q->head = p->prev;
+-	if (q->head == NULL)
+-		q->tail = NULL;
+-
+-	q->len--;
+-
+-	if (prec_out)
+-		*prec_out = prec;
+-
+-	pq->len--;
+-
+-	p->prev = NULL;
+-
+-	return p;
+-}
+-EXPORT_SYMBOL(bcm_pktq_mdeq);
+-
+-/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+-int bcm_ether_atoe(char *p, u8 *ea)
+-{
+-	int i = 0;
+-
+-	for (;;) {
+-		ea[i++] = (char)simple_strtoul(p, &p, 16);
+-		if (!*p++ || i == 6)
+-			break;
+-	}
+-
+-	return i == 6;
+-}
+-EXPORT_SYMBOL(bcm_ether_atoe);
+-
+-#if defined(BCMDBG)
+-/* pretty hex print a pkt buffer chain */
+-void bcm_prpkt(const char *msg, struct sk_buff *p0)
+-{
+-	struct sk_buff *p;
+-
+-	if (msg && (msg[0] != '\0'))
+-		printk(KERN_DEBUG "%s:\n", msg);
+-
+-	for (p = p0; p; p = p->next)
+-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
+-}
+-EXPORT_SYMBOL(bcm_prpkt);
+-#endif				/* defined(BCMDBG) */
+-
+-/* iovar table lookup */
+-const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
+-{
+-	const bcm_iovar_t *vi;
+-	const char *lookup_name;
+-
+-	/* skip any ':' delimited option prefixes */
+-	lookup_name = strrchr(name, ':');
+-	if (lookup_name != NULL)
+-		lookup_name++;
+-	else
+-		lookup_name = name;
+-
+-	for (vi = table; vi->name; vi++) {
+-		if (!strcmp(vi->name, lookup_name))
+-			return vi;
+-	}
+-	/* ran to end of table */
+-
+-	return NULL;		/* var name not found */
+-}
+-EXPORT_SYMBOL(bcm_iovar_lookup);
+-
+-int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
+-{
+-	int bcmerror = 0;
+-
+-	/* length check on io buf */
+-	switch (vi->type) {
+-	case IOVT_BOOL:
+-	case IOVT_INT8:
+-	case IOVT_INT16:
+-	case IOVT_INT32:
+-	case IOVT_UINT8:
+-	case IOVT_UINT16:
+-	case IOVT_UINT32:
+-		/* all integers are s32 sized args at the ioctl interface */
+-		if (len < (int)sizeof(int)) {
+-			bcmerror = -EOVERFLOW;
+-		}
+-		break;
+-
+-	case IOVT_BUFFER:
+-		/* buffer must meet minimum length requirement */
+-		if (len < vi->minlen) {
+-			bcmerror = -EOVERFLOW;
+-		}
+-		break;
+-
+-	case IOVT_VOID:
+-		if (!set) {
+-			/* Cannot return nil... */
+-			bcmerror = -ENOTSUPP;
+-		} else if (len) {
+-			/* Set is an action w/o parameters */
+-			bcmerror = -ENOBUFS;
+-		}
+-		break;
+-
+-	default:
+-		/* unknown type for length check in iovar info */
+-		bcmerror = -ENOTSUPP;
+-	}
+-
+-	return bcmerror;
+-}
+-EXPORT_SYMBOL(bcm_iovar_lencheck);
+-
+-/*******************************************************************************
+- * crc8
+- *
+- * Computes a crc8 over the input data using the polynomial:
+- *
+- *       x^8 + x^7 +x^6 + x^4 + x^2 + 1
+- *
+- * The caller provides the initial value (either CRC8_INIT_VALUE
+- * or the previous returned value) to allow for processing of
+- * discontiguous blocks of data.  When generating the CRC the
+- * caller is responsible for complementing the final return value
+- * and inserting it into the byte stream.  When checking, a final
+- * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+- *
+- * Reference: Dallas Semiconductor Application Note 27
+- *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+- *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+- *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+- *
+- * ****************************************************************************
+- */
+-
+-static const u8 crc8_table[256] = {
+-	0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+-	0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+-	0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+-	0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+-	0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+-	0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+-	0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+-	0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+-	0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+-	0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+-	0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+-	0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+-	0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+-	0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+-	0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+-	0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+-	0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+-	0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+-	0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+-	0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+-	0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+-	0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+-	0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+-	0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+-	0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+-	0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+-	0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+-	0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+-	0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+-	0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+-	0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+-	0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+-};
+-
+-u8 bcm_crc8(u8 *pdata,	/* pointer to array of data to process */
+-			 uint nbytes,	/* number of input data bytes to process */
+-			 u8 crc	/* either CRC8_INIT_VALUE or previous return value */
+-    ) {
+-	/* loop over the buffer data */
+-	while (nbytes-- > 0)
+-		crc = crc8_table[(crc ^ *pdata++) & 0xff];
+-
+-	return crc;
+-}
+-EXPORT_SYMBOL(bcm_crc8);
+-
+-/*
+- * Traverse a string of 1-byte tag/1-byte length/variable-length value
+- * triples, returning a pointer to the substring whose first element
+- * matches tag
+- */
+-bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key)
+-{
+-	bcm_tlv_t *elt;
+-	int totlen;
+-
+-	elt = (bcm_tlv_t *) buf;
+-	totlen = buflen;
+-
+-	/* find tagged parameter */
+-	while (totlen >= 2) {
+-		int len = elt->len;
+-
+-		/* validate remaining totlen */
+-		if ((elt->id == key) && (totlen >= (len + 2)))
+-			return elt;
+-
+-		elt = (bcm_tlv_t *) ((u8 *) elt + (len + 2));
+-		totlen -= (len + 2);
+-	}
+-
+-	return NULL;
+-}
+-EXPORT_SYMBOL(bcm_parse_tlvs);
+-
+-
+-#if defined(BCMDBG)
+-int
+-bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, char *buf, int len)
+-{
+-	int i;
+-	char *p = buf;
+-	char hexstr[16];
+-	int slen = 0, nlen = 0;
+-	u32 bit;
+-	const char *name;
+-
+-	if (len < 2 || !buf)
+-		return 0;
+-
+-	buf[0] = '\0';
+-
+-	for (i = 0; flags != 0; i++) {
+-		bit = bd[i].bit;
+-		name = bd[i].name;
+-		if (bit == 0 && flags != 0) {
+-			/* print any unnamed bits */
+-			snprintf(hexstr, 16, "0x%X", flags);
+-			name = hexstr;
+-			flags = 0;	/* exit loop */
+-		} else if ((flags & bit) == 0)
+-			continue;
+-		flags &= ~bit;
+-		nlen = strlen(name);
+-		slen += nlen;
+-		/* count btwn flag space */
+-		if (flags != 0)
+-			slen += 1;
+-		/* need NULL char as well */
+-		if (len <= slen)
+-			break;
+-		/* copy NULL char but don't count it */
+-		strncpy(p, name, nlen + 1);
+-		p += nlen;
+-		/* copy btwn flag space and NULL char */
+-		if (flags != 0)
+-			p += snprintf(p, 2, " ");
+-		len -= slen;
+-	}
+-
+-	/* indicate the str was too short */
+-	if (flags != 0) {
+-		if (len < 2)
+-			p -= 2 - len;	/* overwrite last char */
+-		p += snprintf(p, 2, ">");
+-	}
+-
+-	return (int)(p - buf);
+-}
+-EXPORT_SYMBOL(bcm_format_flags);
+-
+-/* print bytes formatted as hex to a string. return the resulting string length */
+-int bcm_format_hex(char *str, const void *bytes, int len)
+-{
+-	int i;
+-	char *p = str;
+-	const u8 *src = (const u8 *)bytes;
+-
+-	for (i = 0; i < len; i++) {
+-		p += snprintf(p, 3, "%02X", *src);
+-		src++;
+-	}
+-	return (int)(p - str);
+-}
+-EXPORT_SYMBOL(bcm_format_hex);
+-#endif				/* defined(BCMDBG) */
+-
+-char *bcm_chipname(uint chipid, char *buf, uint len)
+-{
+-	const char *fmt;
+-
+-	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+-	snprintf(buf, len, fmt, chipid);
+-	return buf;
+-}
+-EXPORT_SYMBOL(bcm_chipname);
+-
+-uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
+-{
+-	uint len;
+-
+-	len = strlen(name) + 1;
+-
+-	if ((len + datalen) > buflen)
+-		return 0;
+-
+-	strncpy(buf, name, buflen);
+-
+-	/* append data onto the end of the name string */
+-	memcpy(&buf[len], data, datalen);
+-	len += datalen;
+-
+-	return len;
+-}
+-EXPORT_SYMBOL(bcm_mkiovar);
+-
+-/* Quarter dBm units to mW
+- * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+- * Table is offset so the last entry is largest mW value that fits in
+- * a u16.
+- */
+-
+-#define QDBM_OFFSET 153		/* Offset for first entry */
+-#define QDBM_TABLE_LEN 40	/* Table size */
+-
+-/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+- * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+- */
+-#define QDBM_TABLE_LOW_BOUND 6493	/* Low bound */
+-
+-/* Largest mW value that will round down to the last table entry,
+- * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+- * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
+- * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+- */
+-#define QDBM_TABLE_HIGH_BOUND 64938	/* High bound */
+-
+-static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+-/* qdBm: 	+0 	+1 	+2 	+3 	+4 	+5 	+6 	+7 */
+-/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+-/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+-/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+-/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+-/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+-};
+-
+-u16 bcm_qdbm_to_mw(u8 qdbm)
+-{
+-	uint factor = 1;
+-	int idx = qdbm - QDBM_OFFSET;
+-
+-	if (idx >= QDBM_TABLE_LEN) {
+-		/* clamp to max u16 mW value */
+-		return 0xFFFF;
+-	}
+-
+-	/* scale the qdBm index up to the range of the table 0-40
+-	 * where an offset of 40 qdBm equals a factor of 10 mW.
+-	 */
+-	while (idx < 0) {
+-		idx += 40;
+-		factor *= 10;
+-	}
+-
+-	/* return the mW value scaled down to the correct factor of 10,
+-	 * adding in factor/2 to get proper rounding.
+-	 */
+-	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+-}
+-EXPORT_SYMBOL(bcm_qdbm_to_mw);
+-
+-u8 bcm_mw_to_qdbm(u16 mw)
+-{
+-	u8 qdbm;
+-	int offset;
+-	uint mw_uint = mw;
+-	uint boundary;
+-
+-	/* handle boundary case */
+-	if (mw_uint <= 1)
+-		return 0;
+-
+-	offset = QDBM_OFFSET;
+-
+-	/* move mw into the range of the table */
+-	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+-		mw_uint *= 10;
+-		offset -= 40;
+-	}
+-
+-	for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+-		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+-						    nqdBm_to_mW_map[qdbm]) / 2;
+-		if (mw_uint < boundary)
+-			break;
+-	}
+-
+-	qdbm += (u8) offset;
+-
+-	return qdbm;
+-}
+-EXPORT_SYMBOL(bcm_mw_to_qdbm);
+-
+-uint bcm_bitcount(u8 *bitmap, uint length)
+-{
+-	uint bitcount = 0, i;
+-	u8 tmp;
+-	for (i = 0; i < length; i++) {
+-		tmp = bitmap[i];
+-		while (tmp) {
+-			bitcount++;
+-			tmp &= (tmp - 1);
+-		}
+-	}
+-	return bitcount;
+-}
+-EXPORT_SYMBOL(bcm_bitcount);
+-
+-/* Initialization of bcmstrbuf structure */
+-void bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
+-{
+-	b->origsize = b->size = size;
+-	b->origbuf = b->buf = buf;
+-}
+-EXPORT_SYMBOL(bcm_binit);
+-
+-/* Buffer sprintf wrapper to guard against buffer overflow */
+-int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
+-{
+-	va_list ap;
+-	int r;
+-
+-	va_start(ap, fmt);
+-	r = vsnprintf(b->buf, b->size, fmt, ap);
+-
+-	/* Non Ansi C99 compliant returns -1,
+-	 * Ansi compliant return r >= b->size,
+-	 * bcmstdlib returns 0, handle all
+-	 */
+-	if ((r == -1) || (r >= (int)b->size) || (r == 0)) {
+-		b->size = 0;
+-	} else {
+-		b->size -= r;
+-		b->buf += r;
+-	}
+-
+-	va_end(ap);
+-
+-	return r;
+-}
+-EXPORT_SYMBOL(bcm_bprintf);
+diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c
+deleted file mode 100644
+index 955a3ab..0000000
+--- a/drivers/staging/brcm80211/util/bcmwifi.c
++++ /dev/null
+@@ -1,137 +0,0 @@
+-/*
+- * Copyright (c) 2010 Broadcom Corporation
+- *
+- * Permission to use, copy, modify, and/or distribute this software for any
+- * purpose with or without fee is hereby granted, provided that the above
+- * copyright notice and this permission notice appear in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-#include <linux/ctype.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <bcmdefs.h>
+-#include <bcmutils.h>
+-#include <bcmwifi.h>
+-
+-/*
+- * Verify the chanspec is using a legal set of parameters, i.e. that the
+- * chanspec specified a band, bw, ctl_sb and channel and that the
+- * combination could be legal given any set of circumstances.
+- * RETURNS: true is the chanspec is malformed, false if it looks good.
+- */
+-bool bcm_chspec_malformed(chanspec_t chanspec)
+-{
+-	/* must be 2G or 5G band */
+-	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
+-		return true;
+-	/* must be 20 or 40 bandwidth */
+-	if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec))
+-		return true;
+-
+-	/* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */
+-	if (CHSPEC_IS20(chanspec)) {
+-		if (!CHSPEC_SB_NONE(chanspec))
+-			return true;
+-	} else {
+-		if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec))
+-			return true;
+-	}
+-
+-	return false;
+-}
+-EXPORT_SYMBOL(bcm_chspec_malformed);
+-
+-/*
+- * This function returns the channel number that control traffic is being sent on, for legacy
+- * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
+- * sideband depending on the chanspec selected
+- */
+-u8 bcm_chspec_ctlchan(chanspec_t chspec)
+-{
+-	u8 ctl_chan;
+-
+-	/* Is there a sideband ? */
+-	if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) {
+-		return CHSPEC_CHANNEL(chspec);
+-	} else {
+-		/* we only support 40MHZ with sidebands */
+-		/* chanspec channel holds the centre frequency, use that and the
+-		 * side band information to reconstruct the control channel number
+-		 */
+-		if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) {
+-			/* control chan is the upper 20 MHZ SB of the 40MHZ channel */
+-			ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
+-		} else {
+-			/* control chan is the lower 20 MHZ SB of the 40MHZ channel */
+-			ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+-		}
+-	}
+-
+-	return ctl_chan;
+-}
+-EXPORT_SYMBOL(bcm_chspec_ctlchan);
+-
+-/*
+- * Return the channel number for a given frequency and base frequency.
+- * The returned channel number is relative to the given base frequency.
+- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
+- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
+- *
+- * Frequency is specified in MHz.
+- * The base frequency is specified as (start_factor * 500 kHz).
+- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
+- * 2.4 GHz and 5 GHz bands.
+- *
+- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
+- * and [0, 200] otherwise.
+- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
+- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
+- *
+- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
+- */
+-int bcm_mhz2channel(uint freq, uint start_factor)
+-{
+-	int ch = -1;
+-	uint base;
+-	int offset;
+-
+-	/* take the default channel start frequency */
+-	if (start_factor == 0) {
+-		if (freq >= 2400 && freq <= 2500)
+-			start_factor = WF_CHAN_FACTOR_2_4_G;
+-		else if (freq >= 5000 && freq <= 6000)
+-			start_factor = WF_CHAN_FACTOR_5_G;
+-	}
+-
+-	if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G)
+-		return 14;
+-
+-	base = start_factor / 2;
+-
+-	/* check that the frequency is in 1GHz range of the base */
+-	if ((freq < base) || (freq > base + 1000))
+-		return -1;
+-
+-	offset = freq - base;
+-	ch = offset / 5;
+-
+-	/* check that frequency is a 5MHz multiple from the base */
+-	if (offset != (ch * 5))
+-		return -1;
+-
+-	/* restricted channel range check for 2.4G */
+-	if (start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 13))
+-		return -1;
+-
+-	return ch;
+-}
+-EXPORT_SYMBOL(bcm_mhz2channel);
+-
+-- 
+1.7.9.5
+
diff --git a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
index cbc3c34..1657ea1 100644
--- a/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
+++ b/recipes-kernel/linux/linux-imx-3.0.35/wandboard-dual/defconfig
@@ -1024,6 +1024,12 @@ CONFIG_ATH_COMMON=m
 # CONFIG_ATH_DEBUG is not set
 CONFIG_ATH6KL=m
 # CONFIG_ATH6KL_DEBUG is not set
+CONFIG_BRCMUTIL=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_SDIO=y
+# CONFIG_BRCMFMAC_SDIO_OOB is not set
+# CONFIG_BRCMFMAC_USB is not set
+CONFIG_BRCMDBG=y
 CONFIG_HOSTAP=y
 # CONFIG_HOSTAP_FIRMWARE is not set
 # CONFIG_IWM is not set
diff --git a/recipes-kernel/linux/linux-imx_3.0.35.bbappend b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
index 0466e67..34e96eb 100644
--- a/recipes-kernel/linux/linux-imx_3.0.35.bbappend
+++ b/recipes-kernel/linux/linux-imx_3.0.35.bbappend
@@ -1,11 +1,13 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
 
-PRINC := "${@int(PRINC) + 2}"
+PRINC := "${@int(PRINC) + 3}"
 
 # Wandboard-specific patches
 SRC_URI_append_wandboard-dual = " \
    file://wandboard-dual/0001-Linux-3.0.35-Add-wandboard-dual-support.patch \
    file://wandboard-dual/0002-wandboard-dual-fix-sdhc-platform-data.patch \
+   file://wandboard-dual/0003-linux-imx-3.0.35-Add-brcm80211-driver-backported-fro.patch \
+   file://wandboard-dual/0003-linux-imx-3.0.35-remove-brcm80211-staging-driver.patch \
 "
 # Add support for the Congatec qmx6 board
 SRC_URI_append_cgtqmx6 = " file://cgtqmx6/cgtqmx6.patch"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 3/5] linux-firmware: Add bbappend to include Broadcom wifi drivers
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 2/5] linux-imx (3.0.35): wandboard: replace brcm80211 driver John Weber
@ 2013-03-18 20:25   ` John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 4/5] wandboard-wifi-support: add nvram file and create firmware links John Weber
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

This recipe adds files for split packages to support the bcm4329, bcm4330,
and bcm4334.

They are installed in /lib/firmware/brcm/brcmfmac43<N>.bin where <N> is
the last two digits of the device product number.

Note: The wifi driver for these devices expects the firmware file to be
named brcmfmac-sdio.bin, and so a link must be created named
brcmfmac-sdio.bin to the appropriate file.  Ultimately, this could be
done with update-alternatives in this recipe but it could also be
accomplished in another recipe which RDEPENDS on linux-firmware-bcm43<N>

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 .../linux-firmware/linux-firmware_git.bbappend     |   24 ++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 recipes-kernel/linux-firmware/linux-firmware_git.bbappend

diff --git a/recipes-kernel/linux-firmware/linux-firmware_git.bbappend b/recipes-kernel/linux-firmware/linux-firmware_git.bbappend
new file mode 100644
index 0000000..b854cca
--- /dev/null
+++ b/recipes-kernel/linux-firmware/linux-firmware_git.bbappend
@@ -0,0 +1,24 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}"
+
+LIC_FILES_CHKSUM += "file://LICENCE.broadcom_bcm43xx;md5=3160c14df7228891b868060e1951dfbc\
+"
+
+PACKAGES =+ "${PN}-bcm4329 ${PN}-bcm4330 ${PN}-bcm4334"
+
+LICENSE_${PN}-bcm4329 = "Firmware-bcm4329"
+FILES_${PN}-bcm4329 = " \
+  /lib/firmware/brcm/brcmfmac4329.bin \
+  /lib/firmware/LICENCE.broadcom_bcm43xx \
+"
+
+LICENSE_${PN}-bcm4330 = "Firmware-bcm4330"
+FILES_${PN}-bcm4330 = " \
+  /lib/firmware/brcm/brcmfmac4330.bin \
+  /lib/firmware/LICENCE.broadcom_bcm43xx \
+"
+
+LICENSE_${PN}-bcm4334 = "Firmware-bcm4334"
+FILES_${PN}-bcm4334 = " \
+  /lib/firmware/brcm/brcmfmac4334.bin \
+  /lib/firmware/LICENCE.broadcom_bcm43xx \
+"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 4/5] wandboard-wifi-support: add nvram file and create firmware links
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
                     ` (2 preceding siblings ...)
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 3/5] linux-firmware: Add bbappend to include Broadcom wifi drivers John Weber
@ 2013-03-18 20:25   ` John Weber
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 5/5] wandboard-dual: Add wandboard-wifi-support to machine John Weber
  2013-03-22  3:05   ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual Otavio Salvador
  5 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

This recipe provides the nvram file required by the BCM4329 on Wandboard
Dual.  It also creates links named brcmfrac-sdio.bin to the firmware
binary brcmfmac4329.bin (provided by linux-firmware-bcm4329) and creates
a link named brcmfmac-sdio.txt to the provided nvram.txt file for Wandboard

All files are installed on the rootfs at /lib/firmware/brcm

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 .../files/LICENCE.broadcom_bcm43xx                 |   65 ++++++++++++++++++
 .../files/wandboard-brcmfmac-nvram.txt             |   70 ++++++++++++++++++++
 .../wandboard-wifi-support.bb                      |   41 ++++++++++++
 3 files changed, 176 insertions(+)
 create mode 100644 recipes-bsp/wandboard-wifi-support/files/LICENCE.broadcom_bcm43xx
 create mode 100644 recipes-bsp/wandboard-wifi-support/files/wandboard-brcmfmac-nvram.txt
 create mode 100644 recipes-bsp/wandboard-wifi-support/wandboard-wifi-support.bb

diff --git a/recipes-bsp/wandboard-wifi-support/files/LICENCE.broadcom_bcm43xx b/recipes-bsp/wandboard-wifi-support/files/LICENCE.broadcom_bcm43xx
new file mode 100644
index 0000000..ff26fdd
--- /dev/null
+++ b/recipes-bsp/wandboard-wifi-support/files/LICENCE.broadcom_bcm43xx
@@ -0,0 +1,65 @@
+SOFTWARE LICENSE AGREEMENT
+
+The accompanying software in binary code form (“Software”), is licensed to you,
+or, if you are accepting on behalf of an entity, the entity and its affiliates
+exercising rights hereunder (“Licensee”) subject to the terms of this software
+license agreement (“Agreement”), unless Licensee and Broadcom Corporation
+(“Broadcom”) execute a separate written software license agreement governing
+use of the Software. ANY USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE
+CONSTITUTES LICENSEE’S ACCEPTANCE OF THIS AGREEMENT.
+
+1.	License. Subject to the terms and conditions of this Agreement,
+Broadcom hereby grants to Licensee a limited, non-exclusive, non-transferable,
+royalty-free license: (i) to use and integrate the Software with any other
+software; and (ii) to reproduce and distribute the Software complete,
+unmodified, and as provided by Broadcom, solely for use with Broadcom
+proprietary integrated circuit product(s) sold by Broadcom with which the
+Software was designed to be used, or their successors.
+
+2.	Restrictions. Licensee shall distribute Software with a copy of this
+Agreement. Licensee shall not remove, efface or obscure any copyright or
+trademark notices from the Software. Reproductions of the Broadcom copyright
+notice shall be included with each copy of the Software, except where such
+Software is embedded in a manner not readily accessible to the end user.
+Licensee shall not: (i) use, license, sell or otherwise distribute the Software
+except as provided in this Agreement; (ii) attempt to modify in any way,
+reverse engineer, decompile or disassemble any portion of the Software; or
+(iii) use the Software or other material in violation of any applicable law or
+regulation, including but not limited to any regulatory agency. This Agreement
+shall automatically terminate upon Licensee’s failure to comply with any of the
+terms of this Agreement. In such event, Licensee will destroy all copies of the
+Software and its component parts.
+
+3.	Ownership. The Software is licensed and not sold.  Title to and
+ownership of the Software, including all intellectual property rights thereto,
+and any portion thereof remain with Broadcom or its licensors. Licensee hereby
+covenants that it will not assert any claim that the Software created by or for
+Broadcom infringe any intellectual property right owned or controlled by
+Licensee.
+
+4.     	Disclaimer. THE SOFTWARE IS OFFERED “AS IS,” AND BROADCOM PROVIDES AND
+GRANTS AND LICENSEE RECEIVES NO SUPPORT AND NO WARRANTIES OF ANY KIND, EXPRESS
+OR IMPLIED, BY STATUTE, COMMUNICATION OR CONDUCT WITH LICENSEE, OR OTHERWISE.
+BROADCOM SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A SPECIFIC PURPOSE, OR NONINFRINGEMENT CONCERNING THE SOFTWARE OR
+ANY UPGRADES TO OR DOCUMENTATION FOR THE SOFTWARE. WITHOUT LIMITATION OF THE
+ABOVE, BROADCOM GRANTS NO WARRANTY THAT THE SOFTWARE IS ERROR-FREE OR WILL
+OPERATE WITHOUT INTERRUPTION, AND GRANTS NO WARRANTY REGARDING ITS USE OR THE
+RESULTS THEREFROM INCLUDING, WITHOUT LIMITATION, ITS CORRECTNESS, ACCURACY, OR
+RELIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM
+OR ANY OF ITS LICENSORS HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER FOR BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR
+OTHERWISE, ARISING OUT OF THIS AGREEMENT OR USE, REPRODUCTION, OR DISTRIBUTION
+OF THE SOFTWARE, INCLUDING BUT NOT LIMITED TO LOSS OF DATA AND LOSS OF PROFITS,
+EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE
+LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
+LIMITED REMEDY.
+
+5. 	Export Laws.  LICENSEE UNDERSTANDS AND AGREES THAT THE SOFTWARE IS
+SUBJECT TO UNITED STATES AND OTHER APPLICABLE EXPORT-RELATED LAWS AND
+REGULATIONS AND THAT LICENSEE MAY NOT EXPORT, RE-EXPORT OR TRANSFER THE
+SOFTWARE OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER THOSE
+LAWS. WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT, OR TRANSFER OF THE
+SOFTWARE TO CUBA, IRAN, NORTH KOREA, SUDAN, AND SYRIA IS PROHIBITED.
+
diff --git a/recipes-bsp/wandboard-wifi-support/files/wandboard-brcmfmac-nvram.txt b/recipes-bsp/wandboard-wifi-support/files/wandboard-brcmfmac-nvram.txt
new file mode 100644
index 0000000..53e4bba
--- /dev/null
+++ b/recipes-bsp/wandboard-wifi-support/files/wandboard-brcmfmac-nvram.txt
@@ -0,0 +1,70 @@
+# bcm4329 NVRAM file for Wandboard Dual
+# $Copyright (C) 2008 Broadcom Corporation$
+# $id$
+
+sromrev=3
+vendid=0x14e4
+devid=0x432f
+boardtype=0x53e
+
+boardrev=0x41
+
+#boardflags=0x1200
+boardflags=0x200
+
+# Specify the xtalfreq if it is otherthan 38.4MHz
+xtalfreq=37400
+
+aa2g=3
+aa5g=0
+
+ag0=255
+#tri2g=0x64
+
+# 11g paparams
+pa0b0=5542,5542,5542
+pa0b1=64244,64244,64244
+pa0b2=65202,65202,65202
+
+pa0itssit=62
+pa0maxpwr=74
+opo=0
+mcs2gpo0=0x6666
+mcs2gpo1=0x6666
+
+# 11g rssi params
+rssismf2g=0xa,0xa,0xa
+rssismc2g=0xb,0xb,0xb
+rssisav2g=0x3,0x3,0x3
+bxa2g=0
+
+# country code
+ccode=ALL
+cctl=0x0
+cckdigfilttype=0
+ofdmdigfilttype=1
+
+rxpo2g=0
+
+boardnum=1
+macaddr=00:90:4c:c5:00:34
+
+# xtal pu and pd time control variable
+# pu time is driver default (0x1501)
+#r13t=0x1501
+
+#######
+nocrc=1
+
+#for mfgc
+otpimagesize=182
+
+# sdio extra configs
+hwhdr=0x05ffff031030031003100000
+
+#This generates empty F1, F2 and F3 tuple chains, and may be used if the host SDIO stack does not require the standard tuples.
+#RAW1=80 02 fe ff
+
+#This includes the standard FUNCID and FUNCE tuples in the F1, F2, F3 and common CIS.
+RAW1=80 32 fe 21 02 0c 00 22 2a 01 01 00 00 c5 0 e6 00 00 00 00 00 40 00 00 ff ff 80 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 20 04 D0 2 29 43 21 02 0c 00 22 04 00 20 00 5A
+nvramver=4.218.214.0
diff --git a/recipes-bsp/wandboard-wifi-support/wandboard-wifi-support.bb b/recipes-bsp/wandboard-wifi-support/wandboard-wifi-support.bb
new file mode 100644
index 0000000..8b8bfbb
--- /dev/null
+++ b/recipes-bsp/wandboard-wifi-support/wandboard-wifi-support.bb
@@ -0,0 +1,41 @@
+DESCRIPTION = "Firmware support for on-board wifi on Wandboard dual"
+SECTION = "kernel"
+
+# Notes:
+# Provides nvram file for the BCM4329 on Wandboard Dual.  Depends on 
+# update-alternatives to create links with correct filenames.
+
+LICENSE = "Proprietary"
+LIC_FILES_CHKSUM = "file://LICENCE.broadcom_bcm43xx;md5=3160c14df7228891b868060e1951dfbc"
+
+RDEPENDS_${PN} = "linux-firmware-bcm4329"
+
+inherit update-alternatives
+
+SRC_URI = " \
+   file://wandboard-brcmfmac-nvram.txt \
+   file://LICENCE.broadcom_bcm43xx \
+"
+
+S = "${WORKDIR}"
+
+do_install() {
+	# Broadcom BCM4329 SDIO nvram file for Wandboard Dual
+        install -d  ${D}/lib/firmware/brcm
+
+	cp -r ${WORKDIR}/wandboard-brcmfmac-nvram.txt \ 
+              ${D}/lib/firmware/brcm/
+	ln -sf ./wandboard-brcmfmac-nvram.txt \
+               ${D}/lib/firmware/brcm/brcmfmac-sdio.txt
+        ln -sf ./brcmfmac4329.bin \
+               ${D}/lib/firmware/brcm/brcmfmac-sdio.bin
+
+}
+
+FILES_${PN} = " \
+  /lib/firmware/brcm/wandboard-brcmfmac-nvram.txt \
+  /lib/firmware/brcm/brcmfmac-sdio.txt \
+  /lib/firmware/brcm/brcmfmac-sdio.bin \
+"
+
+COMPATIBLE_MACHINE = "(wandboard-dual)"
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [meta-fsl-arm-extra][PATCH v2 5/5] wandboard-dual: Add wandboard-wifi-support to machine
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
                     ` (3 preceding siblings ...)
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 4/5] wandboard-wifi-support: add nvram file and create firmware links John Weber
@ 2013-03-18 20:25   ` John Weber
  2013-03-22  3:05   ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual Otavio Salvador
  5 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-18 20:25 UTC (permalink / raw)
  To: meta-freescale

Adds a line MACHINE_EXTRA_RRECOMMENDS for wandboard-wifi-support which
provides firmware files for the wifi chip (BCM4329) on Wandboard Dual.

Signed-off-by: John Weber <rjohnweber@gmail.com>
---
 conf/machine/wandboard-dual.conf |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/conf/machine/wandboard-dual.conf b/conf/machine/wandboard-dual.conf
index f827be7..bc5ae5e 100644
--- a/conf/machine/wandboard-dual.conf
+++ b/conf/machine/wandboard-dual.conf
@@ -18,3 +18,6 @@ UBOOT_PADDING = "2"
 SERIAL_CONSOLE = "115200 ttymxc0"
 
 MACHINE_FEATURES += " pci wifi bluetooth"
+
+MACHINE_EXTRA_RRECOMMENDS += " wandboard-wifi-support"
+
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
                     ` (4 preceding siblings ...)
  2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 5/5] wandboard-dual: Add wandboard-wifi-support to machine John Weber
@ 2013-03-22  3:05   ` Otavio Salvador
  2013-03-22  8:13     ` Eric Bénard
  5 siblings, 1 reply; 716+ messages in thread
From: Otavio Salvador @ 2013-03-22  3:05 UTC (permalink / raw)
  To: John Weber; +Cc: meta-freescale

On Mon, Mar 18, 2013 at 5:25 PM, John Weber <rjohnweber@gmail.com> wrote:
> This patchset provides fixes and wifi support for Wandboard-Dual.
>
>   Fixes ESDHC platform data in kernel board init
>
>   Replaces old wifi driver in drivers/staging with a backported driver from
>   kernel v3.5
>
>   Adds a recipe to install wifi chip firmware (linux-firmware bbappend)
>
>   Adds a recipe (wandboard-wifi-support) to provide the nvram file for
>   the chip and to create appropriate symlinks for the firmware files.
>
>   Adds a dependency in the wandboard-dual machine conf to integrate
>   the wandboard-wifi-support recipe.

I merged the kernel backport and fix but did not merge the rest.

The firmware changes I've reworked and sent to OE-Core for merge and
rest has been kept for rework after it. You can use a package for
nvram.txt only and avoid it  being wandboard specific for now.

--
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-22  3:05   ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual Otavio Salvador
@ 2013-03-22  8:13     ` Eric Bénard
  2013-03-22 12:30       ` Otavio Salvador
  0 siblings, 1 reply; 716+ messages in thread
From: Eric Bénard @ 2013-03-22  8:13 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

Hi Otavio,

Le Fri, 22 Mar 2013 00:05:44 -0300,
Otavio Salvador <otavio@ossystems.com.br> a écrit :
> The firmware changes I've reworked and sent to OE-Core for merge and
> rest has been kept for rework after it. You can use a package for
> nvram.txt only and avoid it  being wandboard specific for now.
> 
the nvram.txt is board specif, check its header which gives the
following details :

+# bcm4329 NVRAM file for Wandboard Dual
+# $Copyright (C) 2008 Broadcom Corporation$

Eric


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-22  8:13     ` Eric Bénard
@ 2013-03-22 12:30       ` Otavio Salvador
  2013-03-22 14:17         ` Eric Bénard
  2013-03-22 14:23         ` Eric Bénard
  0 siblings, 2 replies; 716+ messages in thread
From: Otavio Salvador @ 2013-03-22 12:30 UTC (permalink / raw)
  To: Eric Bénard; +Cc: meta-freescale

On Fri, Mar 22, 2013 at 5:13 AM, Eric Bénard <eric@eukrea.com> wrote:
> Hi Otavio,
>
> Le Fri, 22 Mar 2013 00:05:44 -0300,
> Otavio Salvador <otavio@ossystems.com.br> a écrit :
>> The firmware changes I've reworked and sent to OE-Core for merge and
>> rest has been kept for rework after it. You can use a package for
>> nvram.txt only and avoid it  being wandboard specific for now.
>>
> the nvram.txt is board specif, check its header which gives the
> following details :
>
> +# bcm4329 NVRAM file for Wandboard Dual
> +# $Copyright (C) 2008 Broadcom Corporation$

Yes the idea is to provide one which has the nvram by file.

--
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-22 12:30       ` Otavio Salvador
@ 2013-03-22 14:17         ` Eric Bénard
  2013-03-22 14:23         ` Eric Bénard
  1 sibling, 0 replies; 716+ messages in thread
From: Eric Bénard @ 2013-03-22 14:17 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

Le Fri, 22 Mar 2013 09:30:22 -0300,
Otavio Salvador <otavio@ossystems.com.br> a écrit :

> On Fri, Mar 22, 2013 at 5:13 AM, Eric Bénard <eric@eukrea.com> wrote:
> > Hi Otavio,
> >
> > Le Fri, 22 Mar 2013 00:05:44 -0300,
> > Otavio Salvador <otavio@ossystems.com.br> a écrit :
> >> The firmware changes I've reworked and sent to OE-Core for merge and
> >> rest has been kept for rework after it. You can use a package for
> >> nvram.txt only and ".
> >>
> > the nvram.txt is board specif, check its header which gives the
> > following details :
> >
> > +# bcm4329 NVRAM file for Wandboard Dual
> > +# $Copyright (C) 2008 Broadcom Corporation$
> 
> Yes the idea is to provide one which has the nvram by file.
> 
sorry I don't understand what you mean here.

Eric


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-22 12:30       ` Otavio Salvador
  2013-03-22 14:17         ` Eric Bénard
@ 2013-03-22 14:23         ` Eric Bénard
  2013-03-23 15:44           ` Otavio Salvador
  1 sibling, 1 reply; 716+ messages in thread
From: Eric Bénard @ 2013-03-22 14:23 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

Hi Otavio,

Le Fri, 22 Mar 2013 09:30:22 -0300,
Otavio Salvador <otavio@ossystems.com.br> a écrit :

> On Fri, Mar 22, 2013 at 5:13 AM, Eric Bénard <eric@eukrea.com> wrote:
> > Hi Otavio,
> >
> > Le Fri, 22 Mar 2013 00:05:44 -0300,
> > Otavio Salvador <otavio@ossystems.com.br> a écrit :
> >> The firmware changes I've reworked and sent to OE-Core for merge and
> >> rest has been kept for rework after it. You can use a package for
> >> nvram.txt only and avoid it  being wandboard specific for now.
> >>
> > the nvram.txt is board specif, check its header which gives the
> > following details :
> >
> > +# bcm4329 NVRAM file for Wandboard Dual
> > +# $Copyright (C) 2008 Broadcom Corporation$
> 
> Yes the idea is to provide one which has the nvram by file.
> 
OK having seen the new patch from John, I now understand. Sorry for the
noise.

Eric


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-22 14:23         ` Eric Bénard
@ 2013-03-23 15:44           ` Otavio Salvador
  2013-03-25  2:18             ` Fabio Estevam
  0 siblings, 1 reply; 716+ messages in thread
From: Otavio Salvador @ 2013-03-23 15:44 UTC (permalink / raw)
  To: Eric Bénard; +Cc: meta-freescale

On Fri, Mar 22, 2013 at 11:23 AM, Eric Bénard <eric@eukrea.com> wrote:
> Hi Otavio,
>
> Le Fri, 22 Mar 2013 09:30:22 -0300,
> Otavio Salvador <otavio@ossystems.com.br> a écrit :
>
>> On Fri, Mar 22, 2013 at 5:13 AM, Eric Bénard <eric@eukrea.com> wrote:
>> > Hi Otavio,
>> >
>> > Le Fri, 22 Mar 2013 00:05:44 -0300,
>> > Otavio Salvador <otavio@ossystems.com.br> a écrit :
>> >> The firmware changes I've reworked and sent to OE-Core for merge and
>> >> rest has been kept for rework after it. You can use a package for
>> >> nvram.txt only and avoid it  being wandboard specific for now.
>> >>
>> > the nvram.txt is board specif, check its header which gives the
>> > following details :
>> >
>> > +# bcm4329 NVRAM file for Wandboard Dual
>> > +# $Copyright (C) 2008 Broadcom Corporation$
>>
>> Yes the idea is to provide one which has the nvram by file.
>>
> OK having seen the new patch from John, I now understand. Sorry for the
> noise.

I have merged the missing patches now as linux-firmware patch got merged.

--
Otavio Salvador                             O.S. Systems
E-mail: otavio@ossystems.com.br  http://www.ossystems.com.br
Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-23 15:44           ` Otavio Salvador
@ 2013-03-25  2:18             ` Fabio Estevam
  2013-03-25  2:20               ` John Weber
  0 siblings, 1 reply; 716+ messages in thread
From: Fabio Estevam @ 2013-03-25  2:18 UTC (permalink / raw)
  To: Otavio Salvador; +Cc: meta-freescale

On Sat, Mar 23, 2013 at 12:44 PM, Otavio Salvador
<otavio@ossystems.com.br> wrote:

> I have merged the missing patches now as linux-firmware patch got merged.

Is this OE linux-firmware tree or the official linux-firmware git?


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual
  2013-03-25  2:18             ` Fabio Estevam
@ 2013-03-25  2:20               ` John Weber
  0 siblings, 0 replies; 716+ messages in thread
From: John Weber @ 2013-03-25  2:20 UTC (permalink / raw)
  To: meta-freescale

A patch to the OE linux-firmware recipe that pulls from the linux-firmware git.

Wandboard makes use of this patch to bring in the bcm4329 firmware.

On 3/24/13 9:18 PM, Fabio Estevam wrote:
> On Sat, Mar 23, 2013 at 12:44 PM, Otavio Salvador
> <otavio@ossystems.com.br> wrote:
>
>> I have merged the missing patches now as linux-firmware patch got merged.
>
> Is this OE linux-firmware tree or the official linux-firmware git?
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-freescale
>


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 00/11] ARM:STixxxx: Add STixxxx platform and board support
       [not found] <yes>
@ 2013-06-10  9:17   ` Srinivas KANDAGATLA
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:17 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Here is new patch-set incorporating all the review comments.

This patch-set adds basic support for STMicroelectronics STixxxx SOCs
which includes STiH415 and STiH416 with B2000 and B2020 board support.

STiH415 and STiH416 are dual-core ARM Cortex-A9 CPU, designed for use in
Set-top-boxes. The SOC support is available in mach-stixxxx which contains
support code for STiH415, STiH416 SOCs including the generic board support.

Only device drivers included in this patch set are UART and pinctrl, other
drivers will be added in future.

The reason for adding two SOCs at this patch set is to show that no new
C code is required for second SOC(STiH416) support.

Thankyou all for reviewing the first set of RFC patches.
I would appreciate any feedback on these patches.

Changes since RFC:
 - st-asc Serial driver:
	- modified kconfig to remove default y
	- removed all the forward declaration.
	- use dynamic major numbering.
	- merge header-file in to driver.

 - ARM Global timer:
	- moved to drivers/clocksource.
	- added revision check in driver.
	- removed unused header file.
	- moved to u64 from union gt_counter
	- comments added in get_counter
	- removed leftover debug code.
	- moved code to use __raw_readl/writel.
	- used DIV_ROUND_CLOSEST
	- added check in interrupt handler.
	- expanded CE and CS acronyms usage.
	- Fixed minimum clock ticks value.
	- move to use clocksource_register_hz
	- added arch sched_clock support.
	- added ERRATA 740657 workaround.

 - ST-System Configuration Registers:
	- moved from syscon usage to st specific driver.

 - ST Pinctrl support:
	- fixed few typos in the documentation.
	- moved some of the retime offset information to driver.
	
 - STixxxx Support:
	- all the SOC support code is moved to mach-stixxxx
	- seperated DEBUG_LL code to new patch.
	- removed unnecessary #interrupt-cells
	- renamed uart to serial
	- moved to multi_v7_defconfig
	- used menuconfig in mach-stixxx/Kconfig
	- removed of_platform_populate as generic code does it for you.
	- scu address is ioremaped.

Thanks,
srini

Srinivas Kandagatla (10):
  serial:st-asc: Add ST ASC driver.
  regmap: Add regmap_field APIs
  mfd:stixxxx-syscfg: Add ST System Configuration support.
  pinctrl:stixxxx: Add pinctrl and pinconf support.
  ARM:stixxxx: Add STiH415 SOC support
  ARM:stixxxx: Add STiH416 SOC support
  ARM:stixxxx: Add DEBUG_LL console support
  ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  ARM:stih41x: Add B2000 board support
  ARM:stih41x: Add B2020 board support

Stuart Menefy (1):
  clocksource:global_timer: Add ARM global timer support.

 Documentation/arm/stixxxx/overview.txt             |   33 +
 Documentation/arm/stixxxx/stih415-overview.txt     |   12 +
 Documentation/arm/stixxxx/stih416-overview.txt     |   12 +
 .../devicetree/bindings/arm/global_timer.txt       |   21 +
 .../devicetree/bindings/mfd/stixxxx-syscfg.txt     |   18 +
 .../bindings/pinctrl/pinctrl-stixxxx.txt           |  116 ++
 .../devicetree/bindings/tty/serial/st-asc.txt      |   18 +
 MAINTAINERS                                        |   11 +
 arch/arm/Kconfig                                   |    2 +
 arch/arm/Kconfig.debug                             |   38 +
 arch/arm/Makefile                                  |    1 +
 arch/arm/boot/dts/Makefile                         |    4 +
 arch/arm/boot/dts/stih415-b2000.dts                |   15 +
 arch/arm/boot/dts/stih415-b2020.dts                |   15 +
 arch/arm/boot/dts/stih415-clock.dtsi               |   38 +
 arch/arm/boot/dts/stih415-pinctrl.dtsi             |  326 ++++++
 arch/arm/boot/dts/stih415.dtsi                     |  102 ++
 arch/arm/boot/dts/stih416-b2000.dts                |   16 +
 arch/arm/boot/dts/stih416-b2020.dts                |   16 +
 arch/arm/boot/dts/stih416-clock.dtsi               |   41 +
 arch/arm/boot/dts/stih416-pinctrl.dtsi             |  377 ++++++
 arch/arm/boot/dts/stih416.dtsi                     |  111 ++
 arch/arm/boot/dts/stih41x-b2000.dtsi               |   41 +
 arch/arm/boot/dts/stih41x-b2020.dtsi               |   42 +
 arch/arm/boot/dts/stih41x.dtsi                     |   38 +
 arch/arm/boot/dts/stixxxx-pincfg.h                 |   94 ++
 arch/arm/configs/multi_v7_defconfig                |   32 +-
 arch/arm/include/debug/stixxxx.S                   |   61 +
 arch/arm/mach-stixxxx/Kconfig                      |   45 +
 arch/arm/mach-stixxxx/Makefile                     |    2 +
 arch/arm/mach-stixxxx/board-dt.c                   |   50 +
 arch/arm/mach-stixxxx/headsmp.S                    |   44 +
 arch/arm/mach-stixxxx/platsmp.c                    |  117 ++
 arch/arm/mach-stixxxx/smp.h                        |   19 +
 drivers/base/regmap/internal.h                     |    8 +
 drivers/base/regmap/regmap.c                       |  104 ++
 drivers/clocksource/Kconfig                        |   13 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/arm_global_timer.c             |  368 ++++++
 drivers/mfd/Kconfig                                |   10 +
 drivers/mfd/Makefile                               |    1 +
 drivers/mfd/stixxxx-syscfg.c                       |  168 +++
 drivers/pinctrl/Kconfig                            |   11 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-stixxxx.c                  | 1212 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-stixxxx.h                  |  197 ++++
 drivers/tty/serial/Kconfig                         |   16 +
 drivers/tty/serial/Makefile                        |    1 +
 drivers/tty/serial/st-asc.c                        |  911 +++++++++++++++
 include/linux/mfd/stixxxx-syscfg.h                 |   15 +
 include/linux/regmap.h                             |   42 +
 include/uapi/linux/serial_core.h                   |    3 +
 52 files changed, 4993 insertions(+), 17 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih415-overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih416-overview.txt
 create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
 create mode 100644 Documentation/devicetree/bindings/tty/serial/st-asc.txt
 create mode 100644 arch/arm/boot/dts/stih415-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih415-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih415-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih415-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih415.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih416-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih416.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x-b2000.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x-b2020.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x.dtsi
 create mode 100644 arch/arm/boot/dts/stixxxx-pincfg.h
 create mode 100644 arch/arm/include/debug/stixxxx.S
 create mode 100644 arch/arm/mach-stixxxx/Kconfig
 create mode 100644 arch/arm/mach-stixxxx/Makefile
 create mode 100644 arch/arm/mach-stixxxx/board-dt.c
 create mode 100644 arch/arm/mach-stixxxx/headsmp.S
 create mode 100644 arch/arm/mach-stixxxx/platsmp.c
 create mode 100644 arch/arm/mach-stixxxx/smp.h
 create mode 100644 drivers/clocksource/arm_global_timer.c
 create mode 100644 drivers/mfd/stixxxx-syscfg.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.h
 create mode 100644 drivers/tty/serial/st-asc.c
 create mode 100644 include/linux/mfd/stixxxx-syscfg.h

-- 
1.7.6.5


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 00/11] ARM:STixxxx: Add STixxxx platform and board support
@ 2013-06-10  9:17   ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Here is new patch-set incorporating all the review comments.

This patch-set adds basic support for STMicroelectronics STixxxx SOCs
which includes STiH415 and STiH416 with B2000 and B2020 board support.

STiH415 and STiH416 are dual-core ARM Cortex-A9 CPU, designed for use in
Set-top-boxes. The SOC support is available in mach-stixxxx which contains
support code for STiH415, STiH416 SOCs including the generic board support.

Only device drivers included in this patch set are UART and pinctrl, other
drivers will be added in future.

The reason for adding two SOCs at this patch set is to show that no new
C code is required for second SOC(STiH416) support.

Thankyou all for reviewing the first set of RFC patches.
I would appreciate any feedback on these patches.

Changes since RFC:
 - st-asc Serial driver:
	- modified kconfig to remove default y
	- removed all the forward declaration.
	- use dynamic major numbering.
	- merge header-file in to driver.

 - ARM Global timer:
	- moved to drivers/clocksource.
	- added revision check in driver.
	- removed unused header file.
	- moved to u64 from union gt_counter
	- comments added in get_counter
	- removed leftover debug code.
	- moved code to use __raw_readl/writel.
	- used DIV_ROUND_CLOSEST
	- added check in interrupt handler.
	- expanded CE and CS acronyms usage.
	- Fixed minimum clock ticks value.
	- move to use clocksource_register_hz
	- added arch sched_clock support.
	- added ERRATA 740657 workaround.

 - ST-System Configuration Registers:
	- moved from syscon usage to st specific driver.

 - ST Pinctrl support:
	- fixed few typos in the documentation.
	- moved some of the retime offset information to driver.
	
 - STixxxx Support:
	- all the SOC support code is moved to mach-stixxxx
	- seperated DEBUG_LL code to new patch.
	- removed unnecessary #interrupt-cells
	- renamed uart to serial
	- moved to multi_v7_defconfig
	- used menuconfig in mach-stixxx/Kconfig
	- removed of_platform_populate as generic code does it for you.
	- scu address is ioremaped.

Thanks,
srini

Srinivas Kandagatla (10):
  serial:st-asc: Add ST ASC driver.
  regmap: Add regmap_field APIs
  mfd:stixxxx-syscfg: Add ST System Configuration support.
  pinctrl:stixxxx: Add pinctrl and pinconf support.
  ARM:stixxxx: Add STiH415 SOC support
  ARM:stixxxx: Add STiH416 SOC support
  ARM:stixxxx: Add DEBUG_LL console support
  ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  ARM:stih41x: Add B2000 board support
  ARM:stih41x: Add B2020 board support

Stuart Menefy (1):
  clocksource:global_timer: Add ARM global timer support.

 Documentation/arm/stixxxx/overview.txt             |   33 +
 Documentation/arm/stixxxx/stih415-overview.txt     |   12 +
 Documentation/arm/stixxxx/stih416-overview.txt     |   12 +
 .../devicetree/bindings/arm/global_timer.txt       |   21 +
 .../devicetree/bindings/mfd/stixxxx-syscfg.txt     |   18 +
 .../bindings/pinctrl/pinctrl-stixxxx.txt           |  116 ++
 .../devicetree/bindings/tty/serial/st-asc.txt      |   18 +
 MAINTAINERS                                        |   11 +
 arch/arm/Kconfig                                   |    2 +
 arch/arm/Kconfig.debug                             |   38 +
 arch/arm/Makefile                                  |    1 +
 arch/arm/boot/dts/Makefile                         |    4 +
 arch/arm/boot/dts/stih415-b2000.dts                |   15 +
 arch/arm/boot/dts/stih415-b2020.dts                |   15 +
 arch/arm/boot/dts/stih415-clock.dtsi               |   38 +
 arch/arm/boot/dts/stih415-pinctrl.dtsi             |  326 ++++++
 arch/arm/boot/dts/stih415.dtsi                     |  102 ++
 arch/arm/boot/dts/stih416-b2000.dts                |   16 +
 arch/arm/boot/dts/stih416-b2020.dts                |   16 +
 arch/arm/boot/dts/stih416-clock.dtsi               |   41 +
 arch/arm/boot/dts/stih416-pinctrl.dtsi             |  377 ++++++
 arch/arm/boot/dts/stih416.dtsi                     |  111 ++
 arch/arm/boot/dts/stih41x-b2000.dtsi               |   41 +
 arch/arm/boot/dts/stih41x-b2020.dtsi               |   42 +
 arch/arm/boot/dts/stih41x.dtsi                     |   38 +
 arch/arm/boot/dts/stixxxx-pincfg.h                 |   94 ++
 arch/arm/configs/multi_v7_defconfig                |   32 +-
 arch/arm/include/debug/stixxxx.S                   |   61 +
 arch/arm/mach-stixxxx/Kconfig                      |   45 +
 arch/arm/mach-stixxxx/Makefile                     |    2 +
 arch/arm/mach-stixxxx/board-dt.c                   |   50 +
 arch/arm/mach-stixxxx/headsmp.S                    |   44 +
 arch/arm/mach-stixxxx/platsmp.c                    |  117 ++
 arch/arm/mach-stixxxx/smp.h                        |   19 +
 drivers/base/regmap/internal.h                     |    8 +
 drivers/base/regmap/regmap.c                       |  104 ++
 drivers/clocksource/Kconfig                        |   13 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/arm_global_timer.c             |  368 ++++++
 drivers/mfd/Kconfig                                |   10 +
 drivers/mfd/Makefile                               |    1 +
 drivers/mfd/stixxxx-syscfg.c                       |  168 +++
 drivers/pinctrl/Kconfig                            |   11 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-stixxxx.c                  | 1212 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-stixxxx.h                  |  197 ++++
 drivers/tty/serial/Kconfig                         |   16 +
 drivers/tty/serial/Makefile                        |    1 +
 drivers/tty/serial/st-asc.c                        |  911 +++++++++++++++
 include/linux/mfd/stixxxx-syscfg.h                 |   15 +
 include/linux/regmap.h                             |   42 +
 include/uapi/linux/serial_core.h                   |    3 +
 52 files changed, 4993 insertions(+), 17 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih415-overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih416-overview.txt
 create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
 create mode 100644 Documentation/devicetree/bindings/tty/serial/st-asc.txt
 create mode 100644 arch/arm/boot/dts/stih415-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih415-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih415-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih415-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih415.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih416-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih416.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x-b2000.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x-b2020.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x.dtsi
 create mode 100644 arch/arm/boot/dts/stixxxx-pincfg.h
 create mode 100644 arch/arm/include/debug/stixxxx.S
 create mode 100644 arch/arm/mach-stixxxx/Kconfig
 create mode 100644 arch/arm/mach-stixxxx/Makefile
 create mode 100644 arch/arm/mach-stixxxx/board-dt.c
 create mode 100644 arch/arm/mach-stixxxx/headsmp.S
 create mode 100644 arch/arm/mach-stixxxx/platsmp.c
 create mode 100644 arch/arm/mach-stixxxx/smp.h
 create mode 100644 drivers/clocksource/arm_global_timer.c
 create mode 100644 drivers/mfd/stixxxx-syscfg.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.h
 create mode 100644 drivers/tty/serial/st-asc.c
 create mode 100644 include/linux/mfd/stixxxx-syscfg.h

-- 
1.7.6.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

This patch adds support to ASC (asynchronous serial controller)
driver, which is basically a standard serial driver. This IP is common
across all the ST parts for settop box platforms.

ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
It support all industry standard baud rates.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 .../devicetree/bindings/tty/serial/st-asc.txt      |   18 +
 drivers/tty/serial/Kconfig                         |   16 +
 drivers/tty/serial/Makefile                        |    1 +
 drivers/tty/serial/st-asc.c                        |  911 ++++++++++++++++++++
 include/uapi/linux/serial_core.h                   |    3 +
 5 files changed, 949 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/tty/serial/st-asc.txt
 create mode 100644 drivers/tty/serial/st-asc.c

diff --git a/Documentation/devicetree/bindings/tty/serial/st-asc.txt b/Documentation/devicetree/bindings/tty/serial/st-asc.txt
new file mode 100644
index 0000000..75d877f
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/st-asc.txt
@@ -0,0 +1,18 @@
+*st-asc(Serial Port)
+
+Required properties:
+- compatible : Should be "st,asc".
+- reg, reg-names, interrupts, interrupt-names	: Standard way to define device
+			resources with names. look in
+			Documentation/devicetree/bindings/resource-names.txt
+
+Optional properties:
+- st,hw-flow-ctrl	bool flag to enable hardware flow control.
+- st,force-m1		bool flat to force asc to be in Mode-1 recommeded
+			for high bit rates (above 19.2K)
+Example:
+serial@fe440000{
+    compatible    = "st,asc";
+    reg         = <0xfe440000 0x2c>;
+    interrupts     =  <0 209 0>;
+};
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 7e7006f..0c6ddf6 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1484,6 +1484,22 @@ config SERIAL_RP2_NR_UARTS
 	  If multiple cards are present, the default limit of 32 ports may
 	  need to be increased.
 
+config SERIAL_ST_ASC
+	tristate "ST ASC serial port support"
+	select SERIAL_CORE
+	help
+	  This driver is for the on-chip Asychronous Serial Controller on
+	  STMicroelectronics STixxxx SoCs.
+	  ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
+	  It support all industry standard baud rates.
+
+	  If unsure, say N.
+
+config SERIAL_ST_ASC_CONSOLE
+	bool "Support for console on ST ASC"
+	depends on SERIAL_ST_ASC=y
+	select SERIAL_CORE_CONSOLE
+
 endmenu
 
 endif # TTY
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index eedfec4..536ccc7 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
+obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o
 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
 obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
new file mode 100644
index 0000000..6592c04
--- /dev/null
+++ b/drivers/tty/serial/st-asc.c
@@ -0,0 +1,911 @@
+/*
+ * st-asc.c: ST Asynchronous serial controller (ASC) driver
+ *
+ * Copyright (C) 2003-2013 STMicroelectronics (R&D) Limited
+ *
+ * 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.
+ *
+ */
+
+#if defined(CONFIG_SERIAL_ST_ASC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+
+#define DRIVER_NAME "st-asc"
+#define ASC_SERIAL_NAME "ttyAS"
+#define ASC_FIFO_SIZE 16
+#define ASC_MAX_PORTS 8
+
+struct asc_port {
+	struct uart_port port;
+	struct clk *clk;
+	unsigned int hw_flow_control:1;
+	unsigned int check_parity:1;
+	unsigned int force_m1:1;
+};
+
+static struct asc_port asc_ports[ASC_MAX_PORTS];
+static struct uart_driver asc_uart_driver;
+
+/*---- UART Register definitions ------------------------------*/
+
+/* Register offsets */
+
+#define ASC_BAUDRATE			0x00
+#define ASC_TXBUF			0x04
+#define ASC_RXBUF			0x08
+#define ASC_CTL				0x0C
+#define ASC_INTEN			0x10
+#define ASC_STA				0x14
+#define ASC_GUARDTIME			0x18
+#define ASC_TIMEOUT			0x1C
+#define ASC_TXRESET			0x20
+#define ASC_RXRESET			0x24
+#define ASC_RETRIES			0x28
+
+/* ASC_RXBUF */
+#define ASC_RXBUF_PE			0x100
+#define ASC_RXBUF_FE			0x200
+
+/* ASC_CTL */
+
+#define ASC_CTL_MODE_MSK		0x0007
+#define  ASC_CTL_MODE_8BIT		0x0001
+#define  ASC_CTL_MODE_7BIT_PAR		0x0003
+#define  ASC_CTL_MODE_9BIT		0x0004
+#define  ASC_CTL_MODE_8BIT_WKUP		0x0005
+#define  ASC_CTL_MODE_8BIT_PAR		0x0007
+#define ASC_CTL_STOP_MSK		0x0018
+#define  ASC_CTL_STOP_HALFBIT		0x0000
+#define  ASC_CTL_STOP_1BIT		0x0008
+#define  ASC_CTL_STOP_1_HALFBIT		0x0010
+#define  ASC_CTL_STOP_2BIT		0x0018
+#define ASC_CTL_PARITYODD		0x0020
+#define ASC_CTL_LOOPBACK		0x0040
+#define ASC_CTL_RUN			0x0080
+#define ASC_CTL_RXENABLE		0x0100
+#define ASC_CTL_SCENABLE		0x0200
+#define ASC_CTL_FIFOENABLE		0x0400
+#define ASC_CTL_CTSENABLE		0x0800
+#define ASC_CTL_BAUDMODE		0x1000
+
+/* ASC_GUARDTIME */
+
+#define ASC_GUARDTIME_MSK		0x00FF
+
+/* ASC_INTEN */
+
+#define ASC_INTEN_RBE			0x0001
+#define ASC_INTEN_TE			0x0002
+#define ASC_INTEN_THE			0x0004
+#define ASC_INTEN_PE			0x0008
+#define ASC_INTEN_FE			0x0010
+#define ASC_INTEN_OE			0x0020
+#define ASC_INTEN_TNE			0x0040
+#define ASC_INTEN_TOI			0x0080
+#define ASC_INTEN_RHF			0x0100
+
+/* ASC_RETRIES */
+
+#define ASC_RETRIES_MSK			0x00FF
+
+/* ASC_RXBUF */
+
+#define ASC_RXBUF_MSK			0x03FF
+
+/* ASC_STA */
+
+#define ASC_STA_RBF			0x0001
+#define ASC_STA_TE			0x0002
+#define ASC_STA_THE			0x0004
+#define ASC_STA_PE			0x0008
+#define ASC_STA_FE			0x0010
+#define ASC_STA_OE			0x0020
+#define ASC_STA_TNE			0x0040
+#define ASC_STA_TOI			0x0080
+#define ASC_STA_RHF			0x0100
+#define ASC_STA_TF			0x0200
+#define ASC_STA_NKD			0x0400
+
+/* ASC_TIMEOUT */
+
+#define ASC_TIMEOUT_MSK			0x00FF
+
+/* ASC_TXBUF */
+
+#define ASC_TXBUF_MSK			0x01FF
+
+/*---- Inline function definitions ---------------------------*/
+
+static inline struct asc_port *to_asc_port(struct uart_port *port)
+{
+	return container_of(port, struct asc_port, port);
+}
+
+static inline u32 asc_in(struct uart_port *port, u32 offset)
+{
+	return readl(port->membase + offset);
+}
+
+static inline void asc_out(struct uart_port *port, u32 offset, u32 value)
+{
+	writel(value, port->membase + offset);
+}
+
+/*
+ * Some simple utility functions to enable and disable interrupts.
+ * Note that these need to be called with interrupts disabled.
+ */
+static inline void asc_disable_tx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_THE;
+	asc_out(port, ASC_INTEN, intenable);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+}
+
+static inline void asc_enable_tx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_THE;
+	asc_out(port, ASC_INTEN, intenable);
+}
+
+static inline void asc_disable_rx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_RBE;
+	asc_out(port, ASC_INTEN, intenable);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+}
+
+static inline void asc_enable_rx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_RBE;
+	asc_out(port, ASC_INTEN, intenable);
+}
+
+static inline u32 asc_txfifo_is_empty(struct uart_port *port)
+{
+	return asc_in(port, ASC_STA) & ASC_STA_TE;
+}
+
+static inline int asc_txfifo_is_full(struct uart_port *port)
+{
+	return asc_in(port, ASC_STA) & ASC_STA_TF;
+}
+
+static inline const char *asc_port_name(struct uart_port *port)
+{
+	return to_platform_device(port->dev)->name;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * This section contains code to support the use of the ASC as a
+ * generic serial port.
+ */
+
+static inline unsigned asc_hw_txroom(struct uart_port *port)
+{
+	u32 status = asc_in(port, ASC_STA);
+
+	if (status & ASC_STA_THE)
+		return port->fifosize / 2;
+	else if (!(status & ASC_STA_TF))
+		return 1;
+
+	return 0;
+}
+
+/*
+ * Start transmitting chars.
+ * This is called from both interrupt and task level.
+ * Either way interrupts are disabled.
+ */
+static void asc_transmit_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+	int txroom;
+	unsigned char c;
+
+	txroom = asc_hw_txroom(port);
+
+	if ((txroom != 0) && port->x_char) {
+		c = port->x_char;
+		port->x_char = 0;
+		asc_out(port, ASC_TXBUF, c);
+		port->icount.tx++;
+		txroom = asc_hw_txroom(port);
+	}
+
+	if (uart_tx_stopped(port)) {
+		/*
+		 * We should try and stop the hardware here, but I
+		 * don't think the ASC has any way to do that.
+		 */
+		asc_disable_tx_interrupts(port);
+		return;
+	}
+
+	if (uart_circ_empty(xmit)) {
+		asc_disable_tx_interrupts(port);
+		return;
+	}
+
+	if (txroom == 0)
+		return;
+
+	do {
+		c = xmit->buf[xmit->tail];
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		asc_out(port, ASC_TXBUF, c);
+		port->icount.tx++;
+		txroom--;
+	} while ((txroom > 0) && (!uart_circ_empty(xmit)));
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		asc_disable_tx_interrupts(port);
+}
+
+static void asc_receive_chars(struct uart_port *port)
+{
+	int count;
+	struct asc_port *ascport = to_asc_port(port);
+	struct tty_port *tport = &port->state->port;
+	int copied = 0;
+	unsigned long status;
+	unsigned long c = 0;
+	char flag;
+	int overrun;
+
+	if (port->irq_wake)
+		pm_wakeup_event(tport->tty->dev, 0);
+
+	while (1) {
+		status = asc_in(port, ASC_STA);
+		if (status & ASC_STA_RHF)
+			count = port->fifosize / 2;
+		else if (status & ASC_STA_RBF)
+			count = 1;
+		else
+			break;
+
+		/*
+		 * Check for overrun before reading any data from the
+		 * RX FIFO, as this clears the overflow error condition.
+		 */
+		overrun = status & ASC_STA_OE;
+
+		for (; count != 0; count--) {
+			c = asc_in(port, ASC_RXBUF);
+			flag = TTY_NORMAL;
+			port->icount.rx++;
+
+			if (unlikely(c & ASC_RXBUF_FE)) {
+				if (c == ASC_RXBUF_FE) {
+					port->icount.brk++;
+					if (uart_handle_break(port))
+						continue;
+					flag = TTY_BREAK;
+				} else {
+					port->icount.frame++;
+					flag = TTY_FRAME;
+				}
+			} else if (ascport->check_parity &&
+				   unlikely(c & ASC_RXBUF_PE)) {
+				port->icount.parity++;
+				flag = TTY_PARITY;
+			}
+
+			if (uart_handle_sysrq_char(port, c))
+				continue;
+			tty_insert_flip_char(tport, c & 0xff, flag);
+		}
+		if (overrun) {
+			port->icount.overrun++;
+			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
+		}
+
+		copied = 1;
+	}
+
+	if (copied) {
+		/* Tell the rest of the system the news. New characters! */
+		tty_flip_buffer_push(tport);
+	}
+}
+
+static irqreturn_t asc_interrupt(int irq, void *ptr)
+{
+	struct uart_port *port = ptr;
+	u32 status;
+
+	spin_lock(&port->lock);
+
+	status = asc_in(port, ASC_STA);
+
+	if (status & ASC_STA_RBF) {
+		/* Receive FIFO not empty */
+		asc_receive_chars(port);
+	}
+
+	if ((status & ASC_STA_THE) &&
+	    (asc_in(port, ASC_INTEN) & ASC_INTEN_THE)) {
+		/* Transmitter FIFO at least half empty */
+		asc_transmit_chars(port);
+	}
+
+	spin_unlock(&port->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * UART Functions
+ */
+
+static unsigned int asc_tx_empty(struct uart_port *port)
+{
+	return asc_txfifo_is_empty(port) ? TIOCSER_TEMT : 0;
+}
+
+static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/*
+	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
+	 * We use ASC's hardware for CTS/RTS, so don't need any for that.
+	 * Some boards have DTR and DCD implemented using PIO pins,
+	 * code to do this should be hooked in here.
+	 */
+}
+
+static unsigned int asc_get_mctrl(struct uart_port *port)
+{
+	/*
+	 * This routine is used for geting signals of: DTR, DCD, DSR, RI,
+	 * and CTS/RTS
+	 */
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+/* There are probably characters waiting to be transmitted. */
+static void asc_start_tx(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+
+	if (!uart_circ_empty(xmit))
+		asc_enable_tx_interrupts(port);
+}
+
+/* Transmit stop */
+static void asc_stop_tx(struct uart_port *port)
+{
+	asc_disable_tx_interrupts(port);
+}
+
+/* Receive stop */
+static void asc_stop_rx(struct uart_port *port)
+{
+	asc_disable_rx_interrupts(port);
+}
+
+/* Force modem status interrupts on */
+static void asc_enable_ms(struct uart_port *port)
+{
+	/* Nothing here yet .. */
+}
+
+/* Handle breaks - ignored by us */
+static void asc_break_ctl(struct uart_port *port, int break_state)
+{
+	/* Nothing here yet .. */
+}
+
+/*
+ * Enable port for reception.
+ */
+static int asc_startup(struct uart_port *port)
+{
+	if (request_irq(port->irq, asc_interrupt, IRQF_NO_SUSPEND,
+			asc_port_name(port), port)) {
+		dev_err(port->dev, "cannot allocate irq.\n");
+		return -ENODEV;
+	}
+
+	asc_transmit_chars(port);
+	asc_enable_rx_interrupts(port);
+
+	return 0;
+}
+
+static void asc_shutdown(struct uart_port *port)
+{
+	asc_disable_tx_interrupts(port);
+	asc_disable_rx_interrupts(port);
+	free_irq(port->irq, port);
+}
+
+static void asc_pm(struct uart_port *port, unsigned int state,
+		unsigned int oldstate)
+{
+	struct asc_port *ascport = to_asc_port(port);
+	unsigned long flags = 0;
+	u32 ctl;
+
+	switch (state) {
+	case UART_PM_STATE_ON:
+		clk_prepare_enable(ascport->clk);
+		break;
+	case UART_PM_STATE_OFF:
+		/*
+		 * Disable the ASC baud rate generator, which is as close as
+		 * we can come to turning it off. Note this is not called with
+		 * the port spinlock held.
+		 */
+		spin_lock_irqsave(&port->lock, flags);
+		ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN;
+		asc_out(port, ASC_CTL, ctl);
+		spin_unlock_irqrestore(&port->lock, flags);
+		clk_disable_unprepare(ascport->clk);
+		break;
+	}
+}
+
+static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
+			    struct ktermios *old)
+{
+	struct asc_port *ascport = to_asc_port(port);
+	unsigned int baud;
+	u32 ctrl_val;
+	tcflag_t cflag;
+	unsigned long flags;
+
+	port->uartclk = clk_get_rate(ascport->clk);
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	cflag = termios->c_cflag;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* read control register */
+	ctrl_val = asc_in(port, ASC_CTL);
+
+	/* stop serial port and reset value */
+	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
+	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
+
+	/* reset fifo rx & tx */
+	asc_out(port, ASC_TXRESET, 1);
+	asc_out(port, ASC_RXRESET, 1);
+
+	/* set character length */
+	if ((cflag & CSIZE) == CS7) {
+		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
+	} else {
+		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
+						ASC_CTL_MODE_8BIT;
+	}
+
+	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
+
+	/* set stop bit */
+	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
+
+	/* odd parity */
+	if (cflag & PARODD)
+		ctrl_val |= ASC_CTL_PARITYODD;
+
+	/* hardware flow control */
+	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
+		ctrl_val |= ASC_CTL_CTSENABLE;
+
+	if ((baud < 19200) && !ascport->force_m1) {
+		asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud)));
+	} else {
+		/*
+		 * MODE 1: recommended for high bit rates (above 19.2K)
+		 *
+		 *                   baudrate * 16 * 2^16
+		 * ASCBaudRate =   ------------------------
+		 *                          inputclock
+		 *
+		 * However to keep the maths inside 32bits we divide top and
+		 * bottom by 64. The +1 is to avoid a divide by zero if the
+		 * input clock rate is something unexpected.
+		 */
+		u32 counter = (baud * 16384) / ((port->uartclk / 64) + 1);
+		asc_out(port, ASC_BAUDRATE, counter);
+		ctrl_val |= ASC_CTL_BAUDMODE;
+	}
+
+	uart_update_timeout(port, cflag, baud);
+
+	/* Set the timeout */
+	asc_out(port, ASC_TIMEOUT, 20);
+
+	/* write final value and enable port */
+	asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *asc_type(struct uart_port *port)
+{
+	return (port->type == PORT_ASC) ? DRIVER_NAME : NULL;
+}
+
+static void asc_release_port(struct uart_port *port)
+{
+}
+
+static int asc_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+/*
+ * Called when the port is opened, and UPF_BOOT_AUTOCONF flag is set
+ * Set type field if successful
+ */
+static void asc_config_port(struct uart_port *port, int flags)
+{
+	if ((flags & UART_CONFIG_TYPE))
+		port->type = PORT_ASC;
+}
+
+static int
+asc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	/* No user changeable parameters */
+	return -EINVAL;
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context (i.e. kgdb).
+ */
+
+static int asc_get_poll_char(struct uart_port *port)
+{
+	if (!(asc_in(port, ASC_STA) & ASC_STA_RBF))
+		return NO_POLL_CHAR;
+
+	return asc_in(port, ASC_RXBUF);
+}
+
+static void asc_put_poll_char(struct uart_port *port, unsigned char c)
+{
+	while (asc_txfifo_is_full(port))
+		cpu_relax();
+	asc_out(port, ASC_TXBUF, c);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
+/*---------------------------------------------------------------------*/
+
+static struct uart_ops asc_uart_ops = {
+	.tx_empty	= asc_tx_empty,
+	.set_mctrl	= asc_set_mctrl,
+	.get_mctrl	= asc_get_mctrl,
+	.start_tx	= asc_start_tx,
+	.stop_tx	= asc_stop_tx,
+	.stop_rx	= asc_stop_rx,
+	.enable_ms	= asc_enable_ms,
+	.break_ctl	= asc_break_ctl,
+	.startup	= asc_startup,
+	.shutdown	= asc_shutdown,
+	.set_termios	= asc_set_termios,
+	.type		= asc_type,
+	.release_port	= asc_release_port,
+	.request_port	= asc_request_port,
+	.config_port	= asc_config_port,
+	.verify_port	= asc_verify_port,
+	.pm		= asc_pm,
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_get_char = asc_get_poll_char,
+	.poll_put_char = asc_put_poll_char,
+#endif /* CONFIG_CONSOLE_POLL */
+};
+
+static int asc_init_port(struct asc_port *ascport,
+			  struct platform_device *pdev)
+{
+	struct uart_port *port = &ascport->port;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_err(&pdev->dev, "Unable to get io resource\n");
+		return -ENODEV;
+	}
+
+	port->iotype	= UPIO_MEM;
+	port->flags	= UPF_BOOT_AUTOCONF;
+	port->ops	= &asc_uart_ops;
+	port->fifosize	= ASC_FIFO_SIZE;
+	port->dev	= &pdev->dev;
+	port->mapbase	= res->start;
+	port->irq	= platform_get_irq(pdev, 0);
+
+	port->membase = devm_request_and_ioremap(&pdev->dev, res);
+	if (!port->membase) {
+		dev_err(&pdev->dev, "Unable to request io memory\n");
+		return -ENODEV;
+	}
+
+	spin_lock_init(&port->lock);
+
+	ascport->clk = devm_clk_get(&pdev->dev, NULL);
+
+	if (WARN_ON(IS_ERR(ascport->clk)))
+		return -EINVAL;
+	/* ensure that clk rate is correct by enabling the clk */
+	clk_prepare_enable(ascport->clk);
+	ascport->port.uartclk = clk_get_rate(ascport->clk);
+	WARN_ON(ascport->port.uartclk == 0);
+	clk_disable_unprepare(ascport->clk);
+
+	return 0;
+}
+
+static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int id;
+
+	if (!np)
+		return NULL;
+
+	id = of_alias_get_id(np, ASC_SERIAL_NAME);
+	if (WARN_ON(id >= ASC_MAX_PORTS))
+		return NULL;
+
+	asc_ports[id].hw_flow_control = of_property_read_bool(np,
+							"st,hw-flow-control");
+	asc_ports[id].force_m1 =  of_property_read_bool(np, "st,force_m1");
+	asc_ports[id].port.line = id;
+	return &asc_ports[id];
+}
+
+static struct of_device_id asc_match[] = {
+	{ .compatible = "st,asc", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, asc_match);
+
+static int asc_serial_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct asc_port *ascport;
+
+	ascport = asc_of_get_asc_port(pdev);
+	if (!ascport)
+		return -ENODEV;
+
+	ret = asc_init_port(ascport, pdev);
+	if (ret)
+		return ret;
+
+	ret = uart_add_one_port(&asc_uart_driver, &ascport->port);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, &ascport->port);
+
+	return 0;
+}
+
+static int asc_serial_remove(struct platform_device *pdev)
+{
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	return uart_remove_one_port(&asc_uart_driver, port);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int asc_serial_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	return uart_suspend_port(&asc_uart_driver, port);
+}
+
+static int asc_serial_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	if (pdev->dev.pins->default_state) {
+		if (pinctrl_select_state(pdev->dev.pins->p,
+					 pdev->dev.pins->default_state) < 0)
+			return -EBUSY;
+	}
+
+	return uart_resume_port(&asc_uart_driver, port);
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_SERIAL_ST_ASC_CONSOLE
+static void asc_console_putchar(struct uart_port *port, int ch)
+{
+	unsigned int timeout = 1000000;
+
+	/* Wait for upto 1 second in case flow control is stopping us. */
+	while (--timeout && asc_txfifo_is_full(port))
+		udelay(1);
+
+	asc_out(port, ASC_TXBUF, ch);
+}
+
+/*
+ *  Print a string to the serial port trying not to disturb
+ *  any possible real use of the port...
+ */
+
+static void asc_console_write(struct console *co, const char *s, unsigned count)
+{
+	struct uart_port *port = &asc_ports[co->index].port;
+	unsigned long flags;
+	unsigned long timeout = 1000000;
+	int locked = 1;
+	u32 intenable;
+
+	local_irq_save(flags);
+	if (port->sysrq)
+		locked = 0; /* asc_interrupt has already claimed the lock */
+	else if (oops_in_progress)
+		locked = spin_trylock(&port->lock);
+	else
+		spin_lock(&port->lock);
+
+	/*
+	 * Disable interrupts so we don't get the IRQ line bouncing
+	 * up and down while interrupts are disabled.
+	 */
+	intenable = asc_in(port, ASC_INTEN);
+	asc_out(port, ASC_INTEN, 0);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+
+	uart_console_write(port, s, count, asc_console_putchar);
+
+	while (--timeout && !asc_txfifo_is_empty(port))
+		udelay(1);
+
+	asc_out(port, ASC_INTEN, intenable);
+
+	if (locked)
+		spin_unlock(&port->lock);
+	local_irq_restore(flags);
+}
+
+static int asc_console_setup(struct console *co, char *options)
+{
+	struct asc_port *ascport;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index >= ASC_MAX_PORTS)
+		return -ENODEV;
+
+	ascport = &asc_ports[co->index];
+
+	/*
+	 * This driver does not support early console initialization
+	 * (use ARM early printk support instead), so we only expect
+	 * this to be called during the uart port registration when the
+	 * driver gets probed and the port should be mapped at that point.
+	 */
+	BUG_ON(ascport->port.mapbase == 0 || ascport->port.membase == NULL);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&ascport->port, co, baud, parity, bits, flow);
+}
+
+static struct console asc_console = {
+	.name		= ASC_SERIAL_NAME,
+	.device		= uart_console_device,
+	.write		= asc_console_write,
+	.setup		= asc_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &asc_uart_driver,
+};
+
+#define ASC_SERIAL_CONSOLE (&asc_console)
+
+#else
+#define ASC_SERIAL_CONSOLE NULL
+#endif /* CONFIG_SERIAL_ST_ASC_CONSOLE */
+
+static struct uart_driver asc_uart_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= DRIVER_NAME,
+	.dev_name	= ASC_SERIAL_NAME,
+	.major		= 0,
+	.minor		= 0,
+	.nr		= ASC_MAX_PORTS,
+	.cons		= ASC_SERIAL_CONSOLE,
+};
+
+static const struct dev_pm_ops asc_serial_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(asc_serial_suspend, asc_serial_resume)
+};
+
+static struct platform_driver asc_serial_driver = {
+	.probe		= asc_serial_probe,
+	.remove		= asc_serial_remove,
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.pm	= &asc_serial_pm_ops,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(asc_match),
+	},
+};
+
+static int __init asc_init(void)
+{
+	int ret;
+	static char banner[] __initdata =
+		KERN_INFO "STMicroelectronics ASC driver initialized\n";
+
+	printk(banner);
+
+	ret = uart_register_driver(&asc_uart_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&asc_serial_driver);
+	if (ret)
+		uart_unregister_driver(&asc_uart_driver);
+
+	return ret;
+}
+
+static void __exit asc_exit(void)
+{
+	platform_driver_unregister(&asc_serial_driver);
+	uart_unregister_driver(&asc_uart_driver);
+}
+
+module_init(asc_init);
+module_exit(asc_exit);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("STMicroelectronics (R&D) Limited");
+MODULE_DESCRIPTION("STMicroelectronics ASC serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 74c2bf7..ec80e01 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -226,4 +226,7 @@
 /* Rocketport EXPRESS/INFINITY */
 #define PORT_RP2	102
 
+/* ST ASC type numbers */
+#define PORT_ASC       103
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support to ASC (asynchronous serial controller)
driver, which is basically a standard serial driver. This IP is common
across all the ST parts for settop box platforms.

ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
It support all industry standard baud rates.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 .../devicetree/bindings/tty/serial/st-asc.txt      |   18 +
 drivers/tty/serial/Kconfig                         |   16 +
 drivers/tty/serial/Makefile                        |    1 +
 drivers/tty/serial/st-asc.c                        |  911 ++++++++++++++++++++
 include/uapi/linux/serial_core.h                   |    3 +
 5 files changed, 949 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/tty/serial/st-asc.txt
 create mode 100644 drivers/tty/serial/st-asc.c

diff --git a/Documentation/devicetree/bindings/tty/serial/st-asc.txt b/Documentation/devicetree/bindings/tty/serial/st-asc.txt
new file mode 100644
index 0000000..75d877f
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/st-asc.txt
@@ -0,0 +1,18 @@
+*st-asc(Serial Port)
+
+Required properties:
+- compatible : Should be "st,asc".
+- reg, reg-names, interrupts, interrupt-names	: Standard way to define device
+			resources with names. look in
+			Documentation/devicetree/bindings/resource-names.txt
+
+Optional properties:
+- st,hw-flow-ctrl	bool flag to enable hardware flow control.
+- st,force-m1		bool flat to force asc to be in Mode-1 recommeded
+			for high bit rates (above 19.2K)
+Example:
+serial at fe440000{
+    compatible    = "st,asc";
+    reg         = <0xfe440000 0x2c>;
+    interrupts     =  <0 209 0>;
+};
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 7e7006f..0c6ddf6 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1484,6 +1484,22 @@ config SERIAL_RP2_NR_UARTS
 	  If multiple cards are present, the default limit of 32 ports may
 	  need to be increased.
 
+config SERIAL_ST_ASC
+	tristate "ST ASC serial port support"
+	select SERIAL_CORE
+	help
+	  This driver is for the on-chip Asychronous Serial Controller on
+	  STMicroelectronics STixxxx SoCs.
+	  ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
+	  It support all industry standard baud rates.
+
+	  If unsure, say N.
+
+config SERIAL_ST_ASC_CONSOLE
+	bool "Support for console on ST ASC"
+	depends on SERIAL_ST_ASC=y
+	select SERIAL_CORE_CONSOLE
+
 endmenu
 
 endif # TTY
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index eedfec4..536ccc7 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
 obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
+obj-$(CONFIG_SERIAL_ST_ASC) += st-asc.o
 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
 obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
new file mode 100644
index 0000000..6592c04
--- /dev/null
+++ b/drivers/tty/serial/st-asc.c
@@ -0,0 +1,911 @@
+/*
+ * st-asc.c: ST Asynchronous serial controller (ASC) driver
+ *
+ * Copyright (C) 2003-2013 STMicroelectronics (R&D) Limited
+ *
+ * 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.
+ *
+ */
+
+#if defined(CONFIG_SERIAL_ST_ASC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+
+#define DRIVER_NAME "st-asc"
+#define ASC_SERIAL_NAME "ttyAS"
+#define ASC_FIFO_SIZE 16
+#define ASC_MAX_PORTS 8
+
+struct asc_port {
+	struct uart_port port;
+	struct clk *clk;
+	unsigned int hw_flow_control:1;
+	unsigned int check_parity:1;
+	unsigned int force_m1:1;
+};
+
+static struct asc_port asc_ports[ASC_MAX_PORTS];
+static struct uart_driver asc_uart_driver;
+
+/*---- UART Register definitions ------------------------------*/
+
+/* Register offsets */
+
+#define ASC_BAUDRATE			0x00
+#define ASC_TXBUF			0x04
+#define ASC_RXBUF			0x08
+#define ASC_CTL				0x0C
+#define ASC_INTEN			0x10
+#define ASC_STA				0x14
+#define ASC_GUARDTIME			0x18
+#define ASC_TIMEOUT			0x1C
+#define ASC_TXRESET			0x20
+#define ASC_RXRESET			0x24
+#define ASC_RETRIES			0x28
+
+/* ASC_RXBUF */
+#define ASC_RXBUF_PE			0x100
+#define ASC_RXBUF_FE			0x200
+
+/* ASC_CTL */
+
+#define ASC_CTL_MODE_MSK		0x0007
+#define  ASC_CTL_MODE_8BIT		0x0001
+#define  ASC_CTL_MODE_7BIT_PAR		0x0003
+#define  ASC_CTL_MODE_9BIT		0x0004
+#define  ASC_CTL_MODE_8BIT_WKUP		0x0005
+#define  ASC_CTL_MODE_8BIT_PAR		0x0007
+#define ASC_CTL_STOP_MSK		0x0018
+#define  ASC_CTL_STOP_HALFBIT		0x0000
+#define  ASC_CTL_STOP_1BIT		0x0008
+#define  ASC_CTL_STOP_1_HALFBIT		0x0010
+#define  ASC_CTL_STOP_2BIT		0x0018
+#define ASC_CTL_PARITYODD		0x0020
+#define ASC_CTL_LOOPBACK		0x0040
+#define ASC_CTL_RUN			0x0080
+#define ASC_CTL_RXENABLE		0x0100
+#define ASC_CTL_SCENABLE		0x0200
+#define ASC_CTL_FIFOENABLE		0x0400
+#define ASC_CTL_CTSENABLE		0x0800
+#define ASC_CTL_BAUDMODE		0x1000
+
+/* ASC_GUARDTIME */
+
+#define ASC_GUARDTIME_MSK		0x00FF
+
+/* ASC_INTEN */
+
+#define ASC_INTEN_RBE			0x0001
+#define ASC_INTEN_TE			0x0002
+#define ASC_INTEN_THE			0x0004
+#define ASC_INTEN_PE			0x0008
+#define ASC_INTEN_FE			0x0010
+#define ASC_INTEN_OE			0x0020
+#define ASC_INTEN_TNE			0x0040
+#define ASC_INTEN_TOI			0x0080
+#define ASC_INTEN_RHF			0x0100
+
+/* ASC_RETRIES */
+
+#define ASC_RETRIES_MSK			0x00FF
+
+/* ASC_RXBUF */
+
+#define ASC_RXBUF_MSK			0x03FF
+
+/* ASC_STA */
+
+#define ASC_STA_RBF			0x0001
+#define ASC_STA_TE			0x0002
+#define ASC_STA_THE			0x0004
+#define ASC_STA_PE			0x0008
+#define ASC_STA_FE			0x0010
+#define ASC_STA_OE			0x0020
+#define ASC_STA_TNE			0x0040
+#define ASC_STA_TOI			0x0080
+#define ASC_STA_RHF			0x0100
+#define ASC_STA_TF			0x0200
+#define ASC_STA_NKD			0x0400
+
+/* ASC_TIMEOUT */
+
+#define ASC_TIMEOUT_MSK			0x00FF
+
+/* ASC_TXBUF */
+
+#define ASC_TXBUF_MSK			0x01FF
+
+/*---- Inline function definitions ---------------------------*/
+
+static inline struct asc_port *to_asc_port(struct uart_port *port)
+{
+	return container_of(port, struct asc_port, port);
+}
+
+static inline u32 asc_in(struct uart_port *port, u32 offset)
+{
+	return readl(port->membase + offset);
+}
+
+static inline void asc_out(struct uart_port *port, u32 offset, u32 value)
+{
+	writel(value, port->membase + offset);
+}
+
+/*
+ * Some simple utility functions to enable and disable interrupts.
+ * Note that these need to be called with interrupts disabled.
+ */
+static inline void asc_disable_tx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_THE;
+	asc_out(port, ASC_INTEN, intenable);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+}
+
+static inline void asc_enable_tx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_THE;
+	asc_out(port, ASC_INTEN, intenable);
+}
+
+static inline void asc_disable_rx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) & ~ASC_INTEN_RBE;
+	asc_out(port, ASC_INTEN, intenable);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+}
+
+static inline void asc_enable_rx_interrupts(struct uart_port *port)
+{
+	u32 intenable = asc_in(port, ASC_INTEN) | ASC_INTEN_RBE;
+	asc_out(port, ASC_INTEN, intenable);
+}
+
+static inline u32 asc_txfifo_is_empty(struct uart_port *port)
+{
+	return asc_in(port, ASC_STA) & ASC_STA_TE;
+}
+
+static inline int asc_txfifo_is_full(struct uart_port *port)
+{
+	return asc_in(port, ASC_STA) & ASC_STA_TF;
+}
+
+static inline const char *asc_port_name(struct uart_port *port)
+{
+	return to_platform_device(port->dev)->name;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * This section contains code to support the use of the ASC as a
+ * generic serial port.
+ */
+
+static inline unsigned asc_hw_txroom(struct uart_port *port)
+{
+	u32 status = asc_in(port, ASC_STA);
+
+	if (status & ASC_STA_THE)
+		return port->fifosize / 2;
+	else if (!(status & ASC_STA_TF))
+		return 1;
+
+	return 0;
+}
+
+/*
+ * Start transmitting chars.
+ * This is called from both interrupt and task level.
+ * Either way interrupts are disabled.
+ */
+static void asc_transmit_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+	int txroom;
+	unsigned char c;
+
+	txroom = asc_hw_txroom(port);
+
+	if ((txroom != 0) && port->x_char) {
+		c = port->x_char;
+		port->x_char = 0;
+		asc_out(port, ASC_TXBUF, c);
+		port->icount.tx++;
+		txroom = asc_hw_txroom(port);
+	}
+
+	if (uart_tx_stopped(port)) {
+		/*
+		 * We should try and stop the hardware here, but I
+		 * don't think the ASC has any way to do that.
+		 */
+		asc_disable_tx_interrupts(port);
+		return;
+	}
+
+	if (uart_circ_empty(xmit)) {
+		asc_disable_tx_interrupts(port);
+		return;
+	}
+
+	if (txroom == 0)
+		return;
+
+	do {
+		c = xmit->buf[xmit->tail];
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		asc_out(port, ASC_TXBUF, c);
+		port->icount.tx++;
+		txroom--;
+	} while ((txroom > 0) && (!uart_circ_empty(xmit)));
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		asc_disable_tx_interrupts(port);
+}
+
+static void asc_receive_chars(struct uart_port *port)
+{
+	int count;
+	struct asc_port *ascport = to_asc_port(port);
+	struct tty_port *tport = &port->state->port;
+	int copied = 0;
+	unsigned long status;
+	unsigned long c = 0;
+	char flag;
+	int overrun;
+
+	if (port->irq_wake)
+		pm_wakeup_event(tport->tty->dev, 0);
+
+	while (1) {
+		status = asc_in(port, ASC_STA);
+		if (status & ASC_STA_RHF)
+			count = port->fifosize / 2;
+		else if (status & ASC_STA_RBF)
+			count = 1;
+		else
+			break;
+
+		/*
+		 * Check for overrun before reading any data from the
+		 * RX FIFO, as this clears the overflow error condition.
+		 */
+		overrun = status & ASC_STA_OE;
+
+		for (; count != 0; count--) {
+			c = asc_in(port, ASC_RXBUF);
+			flag = TTY_NORMAL;
+			port->icount.rx++;
+
+			if (unlikely(c & ASC_RXBUF_FE)) {
+				if (c == ASC_RXBUF_FE) {
+					port->icount.brk++;
+					if (uart_handle_break(port))
+						continue;
+					flag = TTY_BREAK;
+				} else {
+					port->icount.frame++;
+					flag = TTY_FRAME;
+				}
+			} else if (ascport->check_parity &&
+				   unlikely(c & ASC_RXBUF_PE)) {
+				port->icount.parity++;
+				flag = TTY_PARITY;
+			}
+
+			if (uart_handle_sysrq_char(port, c))
+				continue;
+			tty_insert_flip_char(tport, c & 0xff, flag);
+		}
+		if (overrun) {
+			port->icount.overrun++;
+			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
+		}
+
+		copied = 1;
+	}
+
+	if (copied) {
+		/* Tell the rest of the system the news. New characters! */
+		tty_flip_buffer_push(tport);
+	}
+}
+
+static irqreturn_t asc_interrupt(int irq, void *ptr)
+{
+	struct uart_port *port = ptr;
+	u32 status;
+
+	spin_lock(&port->lock);
+
+	status = asc_in(port, ASC_STA);
+
+	if (status & ASC_STA_RBF) {
+		/* Receive FIFO not empty */
+		asc_receive_chars(port);
+	}
+
+	if ((status & ASC_STA_THE) &&
+	    (asc_in(port, ASC_INTEN) & ASC_INTEN_THE)) {
+		/* Transmitter FIFO at least half empty */
+		asc_transmit_chars(port);
+	}
+
+	spin_unlock(&port->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * UART Functions
+ */
+
+static unsigned int asc_tx_empty(struct uart_port *port)
+{
+	return asc_txfifo_is_empty(port) ? TIOCSER_TEMT : 0;
+}
+
+static void asc_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/*
+	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
+	 * We use ASC's hardware for CTS/RTS, so don't need any for that.
+	 * Some boards have DTR and DCD implemented using PIO pins,
+	 * code to do this should be hooked in here.
+	 */
+}
+
+static unsigned int asc_get_mctrl(struct uart_port *port)
+{
+	/*
+	 * This routine is used for geting signals of: DTR, DCD, DSR, RI,
+	 * and CTS/RTS
+	 */
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+/* There are probably characters waiting to be transmitted. */
+static void asc_start_tx(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+
+	if (!uart_circ_empty(xmit))
+		asc_enable_tx_interrupts(port);
+}
+
+/* Transmit stop */
+static void asc_stop_tx(struct uart_port *port)
+{
+	asc_disable_tx_interrupts(port);
+}
+
+/* Receive stop */
+static void asc_stop_rx(struct uart_port *port)
+{
+	asc_disable_rx_interrupts(port);
+}
+
+/* Force modem status interrupts on */
+static void asc_enable_ms(struct uart_port *port)
+{
+	/* Nothing here yet .. */
+}
+
+/* Handle breaks - ignored by us */
+static void asc_break_ctl(struct uart_port *port, int break_state)
+{
+	/* Nothing here yet .. */
+}
+
+/*
+ * Enable port for reception.
+ */
+static int asc_startup(struct uart_port *port)
+{
+	if (request_irq(port->irq, asc_interrupt, IRQF_NO_SUSPEND,
+			asc_port_name(port), port)) {
+		dev_err(port->dev, "cannot allocate irq.\n");
+		return -ENODEV;
+	}
+
+	asc_transmit_chars(port);
+	asc_enable_rx_interrupts(port);
+
+	return 0;
+}
+
+static void asc_shutdown(struct uart_port *port)
+{
+	asc_disable_tx_interrupts(port);
+	asc_disable_rx_interrupts(port);
+	free_irq(port->irq, port);
+}
+
+static void asc_pm(struct uart_port *port, unsigned int state,
+		unsigned int oldstate)
+{
+	struct asc_port *ascport = to_asc_port(port);
+	unsigned long flags = 0;
+	u32 ctl;
+
+	switch (state) {
+	case UART_PM_STATE_ON:
+		clk_prepare_enable(ascport->clk);
+		break;
+	case UART_PM_STATE_OFF:
+		/*
+		 * Disable the ASC baud rate generator, which is as close as
+		 * we can come to turning it off. Note this is not called with
+		 * the port spinlock held.
+		 */
+		spin_lock_irqsave(&port->lock, flags);
+		ctl = asc_in(port, ASC_CTL) & ~ASC_CTL_RUN;
+		asc_out(port, ASC_CTL, ctl);
+		spin_unlock_irqrestore(&port->lock, flags);
+		clk_disable_unprepare(ascport->clk);
+		break;
+	}
+}
+
+static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
+			    struct ktermios *old)
+{
+	struct asc_port *ascport = to_asc_port(port);
+	unsigned int baud;
+	u32 ctrl_val;
+	tcflag_t cflag;
+	unsigned long flags;
+
+	port->uartclk = clk_get_rate(ascport->clk);
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	cflag = termios->c_cflag;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* read control register */
+	ctrl_val = asc_in(port, ASC_CTL);
+
+	/* stop serial port and reset value */
+	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
+	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
+
+	/* reset fifo rx & tx */
+	asc_out(port, ASC_TXRESET, 1);
+	asc_out(port, ASC_RXRESET, 1);
+
+	/* set character length */
+	if ((cflag & CSIZE) == CS7) {
+		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
+	} else {
+		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
+						ASC_CTL_MODE_8BIT;
+	}
+
+	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
+
+	/* set stop bit */
+	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
+
+	/* odd parity */
+	if (cflag & PARODD)
+		ctrl_val |= ASC_CTL_PARITYODD;
+
+	/* hardware flow control */
+	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
+		ctrl_val |= ASC_CTL_CTSENABLE;
+
+	if ((baud < 19200) && !ascport->force_m1) {
+		asc_out(port, ASC_BAUDRATE, (port->uartclk / (16 * baud)));
+	} else {
+		/*
+		 * MODE 1: recommended for high bit rates (above 19.2K)
+		 *
+		 *                   baudrate * 16 * 2^16
+		 * ASCBaudRate =   ------------------------
+		 *                          inputclock
+		 *
+		 * However to keep the maths inside 32bits we divide top and
+		 * bottom by 64. The +1 is to avoid a divide by zero if the
+		 * input clock rate is something unexpected.
+		 */
+		u32 counter = (baud * 16384) / ((port->uartclk / 64) + 1);
+		asc_out(port, ASC_BAUDRATE, counter);
+		ctrl_val |= ASC_CTL_BAUDMODE;
+	}
+
+	uart_update_timeout(port, cflag, baud);
+
+	/* Set the timeout */
+	asc_out(port, ASC_TIMEOUT, 20);
+
+	/* write final value and enable port */
+	asc_out(port, ASC_CTL, (ctrl_val | ASC_CTL_RUN));
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *asc_type(struct uart_port *port)
+{
+	return (port->type == PORT_ASC) ? DRIVER_NAME : NULL;
+}
+
+static void asc_release_port(struct uart_port *port)
+{
+}
+
+static int asc_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+/*
+ * Called when the port is opened, and UPF_BOOT_AUTOCONF flag is set
+ * Set type field if successful
+ */
+static void asc_config_port(struct uart_port *port, int flags)
+{
+	if ((flags & UART_CONFIG_TYPE))
+		port->type = PORT_ASC;
+}
+
+static int
+asc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	/* No user changeable parameters */
+	return -EINVAL;
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context (i.e. kgdb).
+ */
+
+static int asc_get_poll_char(struct uart_port *port)
+{
+	if (!(asc_in(port, ASC_STA) & ASC_STA_RBF))
+		return NO_POLL_CHAR;
+
+	return asc_in(port, ASC_RXBUF);
+}
+
+static void asc_put_poll_char(struct uart_port *port, unsigned char c)
+{
+	while (asc_txfifo_is_full(port))
+		cpu_relax();
+	asc_out(port, ASC_TXBUF, c);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
+/*---------------------------------------------------------------------*/
+
+static struct uart_ops asc_uart_ops = {
+	.tx_empty	= asc_tx_empty,
+	.set_mctrl	= asc_set_mctrl,
+	.get_mctrl	= asc_get_mctrl,
+	.start_tx	= asc_start_tx,
+	.stop_tx	= asc_stop_tx,
+	.stop_rx	= asc_stop_rx,
+	.enable_ms	= asc_enable_ms,
+	.break_ctl	= asc_break_ctl,
+	.startup	= asc_startup,
+	.shutdown	= asc_shutdown,
+	.set_termios	= asc_set_termios,
+	.type		= asc_type,
+	.release_port	= asc_release_port,
+	.request_port	= asc_request_port,
+	.config_port	= asc_config_port,
+	.verify_port	= asc_verify_port,
+	.pm		= asc_pm,
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_get_char = asc_get_poll_char,
+	.poll_put_char = asc_put_poll_char,
+#endif /* CONFIG_CONSOLE_POLL */
+};
+
+static int asc_init_port(struct asc_port *ascport,
+			  struct platform_device *pdev)
+{
+	struct uart_port *port = &ascport->port;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_err(&pdev->dev, "Unable to get io resource\n");
+		return -ENODEV;
+	}
+
+	port->iotype	= UPIO_MEM;
+	port->flags	= UPF_BOOT_AUTOCONF;
+	port->ops	= &asc_uart_ops;
+	port->fifosize	= ASC_FIFO_SIZE;
+	port->dev	= &pdev->dev;
+	port->mapbase	= res->start;
+	port->irq	= platform_get_irq(pdev, 0);
+
+	port->membase = devm_request_and_ioremap(&pdev->dev, res);
+	if (!port->membase) {
+		dev_err(&pdev->dev, "Unable to request io memory\n");
+		return -ENODEV;
+	}
+
+	spin_lock_init(&port->lock);
+
+	ascport->clk = devm_clk_get(&pdev->dev, NULL);
+
+	if (WARN_ON(IS_ERR(ascport->clk)))
+		return -EINVAL;
+	/* ensure that clk rate is correct by enabling the clk */
+	clk_prepare_enable(ascport->clk);
+	ascport->port.uartclk = clk_get_rate(ascport->clk);
+	WARN_ON(ascport->port.uartclk == 0);
+	clk_disable_unprepare(ascport->clk);
+
+	return 0;
+}
+
+static struct asc_port *asc_of_get_asc_port(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int id;
+
+	if (!np)
+		return NULL;
+
+	id = of_alias_get_id(np, ASC_SERIAL_NAME);
+	if (WARN_ON(id >= ASC_MAX_PORTS))
+		return NULL;
+
+	asc_ports[id].hw_flow_control = of_property_read_bool(np,
+							"st,hw-flow-control");
+	asc_ports[id].force_m1 =  of_property_read_bool(np, "st,force_m1");
+	asc_ports[id].port.line = id;
+	return &asc_ports[id];
+}
+
+static struct of_device_id asc_match[] = {
+	{ .compatible = "st,asc", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, asc_match);
+
+static int asc_serial_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct asc_port *ascport;
+
+	ascport = asc_of_get_asc_port(pdev);
+	if (!ascport)
+		return -ENODEV;
+
+	ret = asc_init_port(ascport, pdev);
+	if (ret)
+		return ret;
+
+	ret = uart_add_one_port(&asc_uart_driver, &ascport->port);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, &ascport->port);
+
+	return 0;
+}
+
+static int asc_serial_remove(struct platform_device *pdev)
+{
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	return uart_remove_one_port(&asc_uart_driver, port);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int asc_serial_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	return uart_suspend_port(&asc_uart_driver, port);
+}
+
+static int asc_serial_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	if (pdev->dev.pins->default_state) {
+		if (pinctrl_select_state(pdev->dev.pins->p,
+					 pdev->dev.pins->default_state) < 0)
+			return -EBUSY;
+	}
+
+	return uart_resume_port(&asc_uart_driver, port);
+}
+
+#endif /* CONFIG_PM_SLEEP */
+
+/*----------------------------------------------------------------------*/
+
+#ifdef CONFIG_SERIAL_ST_ASC_CONSOLE
+static void asc_console_putchar(struct uart_port *port, int ch)
+{
+	unsigned int timeout = 1000000;
+
+	/* Wait for upto 1 second in case flow control is stopping us. */
+	while (--timeout && asc_txfifo_is_full(port))
+		udelay(1);
+
+	asc_out(port, ASC_TXBUF, ch);
+}
+
+/*
+ *  Print a string to the serial port trying not to disturb
+ *  any possible real use of the port...
+ */
+
+static void asc_console_write(struct console *co, const char *s, unsigned count)
+{
+	struct uart_port *port = &asc_ports[co->index].port;
+	unsigned long flags;
+	unsigned long timeout = 1000000;
+	int locked = 1;
+	u32 intenable;
+
+	local_irq_save(flags);
+	if (port->sysrq)
+		locked = 0; /* asc_interrupt has already claimed the lock */
+	else if (oops_in_progress)
+		locked = spin_trylock(&port->lock);
+	else
+		spin_lock(&port->lock);
+
+	/*
+	 * Disable interrupts so we don't get the IRQ line bouncing
+	 * up and down while interrupts are disabled.
+	 */
+	intenable = asc_in(port, ASC_INTEN);
+	asc_out(port, ASC_INTEN, 0);
+	(void)asc_in(port, ASC_INTEN);	/* Defeat bus write posting */
+
+	uart_console_write(port, s, count, asc_console_putchar);
+
+	while (--timeout && !asc_txfifo_is_empty(port))
+		udelay(1);
+
+	asc_out(port, ASC_INTEN, intenable);
+
+	if (locked)
+		spin_unlock(&port->lock);
+	local_irq_restore(flags);
+}
+
+static int asc_console_setup(struct console *co, char *options)
+{
+	struct asc_port *ascport;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index >= ASC_MAX_PORTS)
+		return -ENODEV;
+
+	ascport = &asc_ports[co->index];
+
+	/*
+	 * This driver does not support early console initialization
+	 * (use ARM early printk support instead), so we only expect
+	 * this to be called during the uart port registration when the
+	 * driver gets probed and the port should be mapped at that point.
+	 */
+	BUG_ON(ascport->port.mapbase == 0 || ascport->port.membase == NULL);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&ascport->port, co, baud, parity, bits, flow);
+}
+
+static struct console asc_console = {
+	.name		= ASC_SERIAL_NAME,
+	.device		= uart_console_device,
+	.write		= asc_console_write,
+	.setup		= asc_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &asc_uart_driver,
+};
+
+#define ASC_SERIAL_CONSOLE (&asc_console)
+
+#else
+#define ASC_SERIAL_CONSOLE NULL
+#endif /* CONFIG_SERIAL_ST_ASC_CONSOLE */
+
+static struct uart_driver asc_uart_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= DRIVER_NAME,
+	.dev_name	= ASC_SERIAL_NAME,
+	.major		= 0,
+	.minor		= 0,
+	.nr		= ASC_MAX_PORTS,
+	.cons		= ASC_SERIAL_CONSOLE,
+};
+
+static const struct dev_pm_ops asc_serial_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(asc_serial_suspend, asc_serial_resume)
+};
+
+static struct platform_driver asc_serial_driver = {
+	.probe		= asc_serial_probe,
+	.remove		= asc_serial_remove,
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.pm	= &asc_serial_pm_ops,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(asc_match),
+	},
+};
+
+static int __init asc_init(void)
+{
+	int ret;
+	static char banner[] __initdata =
+		KERN_INFO "STMicroelectronics ASC driver initialized\n";
+
+	printk(banner);
+
+	ret = uart_register_driver(&asc_uart_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&asc_serial_driver);
+	if (ret)
+		uart_unregister_driver(&asc_uart_driver);
+
+	return ret;
+}
+
+static void __exit asc_exit(void)
+{
+	platform_driver_unregister(&asc_serial_driver);
+	uart_unregister_driver(&asc_uart_driver);
+}
+
+module_init(asc_init);
+module_exit(asc_exit);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("STMicroelectronics (R&D) Limited");
+MODULE_DESCRIPTION("STMicroelectronics ASC serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 74c2bf7..ec80e01 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -226,4 +226,7 @@
 /* Rocketport EXPRESS/INFINITY */
 #define PORT_RP2	102
 
+/* ST ASC type numbers */
+#define PORT_ASC       103
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk,
	Rob Herring, Will Deacon

From: Stuart Menefy <stuart.menefy@st.com>

This is a simple driver for the global timer module found in the Cortex
A9-MP cores from revision r1p0 onwards. This should be able to perform
the functions of the system timer and the local timer in an SMP system.

The global timer has the following features:
    The global timer is a 64-bit incrementing counter with an
auto-incrementing feature. It continues incrementing after sending
interrupts. The global timer is memory mapped in the private memory
region.
    The global timer is accessible to all Cortex-A9 processors in the
cluster. Each Cortex-A9 processor has a private 64-bit comparator that
is used to assert a private interrupt when the global timer has reached
the comparator value. All the Cortex-A9 processors in a design use the
banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
Controller as a Private Peripheral Interrupt. The global timer is
clocked by PERIPHCLK.

Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Rob Herring <robherring2@gmail.com>
CC: Linus Walleij <linus.walleij@linaro.org>
CC: Will Deacon <will.deacon@arm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
---
 .../devicetree/bindings/arm/global_timer.txt       |   21 ++
 drivers/clocksource/Kconfig                        |   13 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/arm_global_timer.c             |  368 ++++++++++++++++++++
 4 files changed, 403 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
 create mode 100644 drivers/clocksource/arm_global_timer.c

diff --git a/Documentation/devicetree/bindings/arm/global_timer.txt b/Documentation/devicetree/bindings/arm/global_timer.txt
new file mode 100644
index 0000000..b64abac
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/global_timer.txt
@@ -0,0 +1,21 @@
+
+* ARM Global Timer
+	Cortex-A9 are often associated with a per-core Global timer.
+
+** Timer node required properties:
+
+- compatible : Should be "arm,cortex-a9-global-timer"
+		Driver supports versions r2p0 and above.
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the GT timer
+	register window.
+
+Example:
+
+	timer@2c000600 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x2c000600 0x20>;
+		interrupts = <1 13 0xf01>;
+	};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index f151c6c..b0c4c42 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -67,6 +67,19 @@ config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
 
+config ARM_GLOBAL_TIMER
+	bool
+	select CLKSRC_OF if OF
+	help
+	  This options enables support for the ARM global timer unit
+
+config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	bool
+	depends on ARM_GLOBAL_TIMER
+	default y
+	help
+	 Use ARM global timer clock source as sched_clock
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8d979c7..b2363cb 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
+obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
new file mode 100644
index 0000000..e4bc4fe
--- /dev/null
+++ b/drivers/clocksource/arm_global_timer.c
@@ -0,0 +1,368 @@
+/*
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include <asm/sched_clock.h>
+#include <asm/mach/irq.h>
+#include <asm/cputype.h>
+#include <asm/localtimer.h>
+
+#define GT_COUNTER0	0x00
+#define GT_COUNTER1	0x04
+
+#define GT_CONTROL	0x08
+#define GT_CONTROL_TIMER_ENABLE		BIT(0)  /* this bit is NOT banked */
+#define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
+#define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
+#define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
+
+#define GT_INT_STATUS	0x0c
+#define GT_INT_STATUS_EVENT_FLAG	BIT(0)
+
+#define GT_COMP0	0x10
+#define GT_COMP1	0x14
+#define GT_AUTO_INC	0x18
+
+/*
+ * We are expecting to be clocked by the ARM peripheral clock.
+ *
+ * Note: it is assumed we are using a prescaler value of zero, so this is
+ * the units for all operations.
+ */
+static void __iomem *gt_base;
+static unsigned long gt_clk_rate;
+static int gt_ppi;
+static struct clock_event_device __percpu **gt_evt;
+static DEFINE_PER_CPU(bool, percpu_init_called);
+static DEFINE_PER_CPU(struct clock_event_device, gt_clockevent);
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static u64 gt_counter_read(void)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+
+	upper = __raw_readl(gt_base + GT_COUNTER1);
+	do {
+		old_upper = upper;
+		lower = __raw_readl(gt_base + GT_COUNTER0);
+		upper = __raw_readl(gt_base + GT_COUNTER1);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return counter;
+}
+
+/**
+ * To ensure that updates to comparator value register do not set the
+ * Interrupt Status Register proceed as follows:
+ * 1. Clear the Comp Enable bit in the Timer Control Register.
+ * 2. Write the lower 32-bit Comparator Value Register.
+ * 3. Write the upper 32-bit Comparator Value Register.
+ * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit.
+ */
+static void gt_compare_set(unsigned long delta, int periodic)
+{
+	u64 counter = gt_counter_read();
+	unsigned long ctrl = __raw_readl(gt_base + GT_CONTROL);
+
+	counter += delta;
+	ctrl &=  ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE);
+
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+	__raw_writel(lower_32_bits(counter), gt_base + GT_COMP0);
+	__raw_writel(upper_32_bits(counter), gt_base + GT_COMP1);
+
+	if (periodic) {
+		__raw_writel(delta, gt_base + GT_AUTO_INC);
+		ctrl |= GT_CONTROL_AUTO_INC;
+	}
+
+	ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+}
+
+static void gt_clockevent_set_mode(enum clock_event_mode mode,
+				   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+
+	ctrl = __raw_readl(gt_base + GT_CONTROL);
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		ctrl &= ~(GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	/* Can not shut down it as enable bit is not banked */
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
+				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	default:
+		break;
+	}
+}
+
+static int gt_clockevent_set_next_event(unsigned long evt,
+					struct clock_event_device *unused)
+{
+	gt_compare_set(evt, 0);
+	return 0;
+}
+
+static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+
+	if (__raw_readl(gt_base + GT_INT_STATUS) & GT_INT_STATUS_EVENT_FLAG) {
+		/**
+		 * ERRATA 740657( Global Timer can send 2 interrupts for
+		 * the same event in single-shot mode)
+		 * Workaround:
+		 *	Either disable single-shot mode.
+		 *	Or
+		 *	Modify the Interrupt Handler to avoid the
+		 *	offending sequence. This is achieved by clearing
+		 *	the Global Timer flag _after_ having incremented
+		 *	the Comparator register	value to a higher value.
+		 */
+		if (!(__raw_readl(gt_base + GT_CONTROL) & GT_CONTROL_AUTO_INC))
+			gt_compare_set(ULONG_MAX, 0);
+
+		__raw_writel(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
+
+		evt->event_handler(evt);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
+{
+	struct clock_event_device **this_cpu_clk;
+	int cpu = smp_processor_id();
+
+	clk->name = "ARM global timer clock event";
+	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	clk->set_mode = gt_clockevent_set_mode;
+	clk->set_next_event = gt_clockevent_set_next_event;
+	this_cpu_clk = __this_cpu_ptr(gt_evt);
+	*this_cpu_clk = clk;
+	clk->cpumask = cpumask_of(cpu);
+	clk->irq = gt_ppi;
+	clockevents_config_and_register(clk, gt_clk_rate,
+					0, 0xffffffff);
+	per_cpu(percpu_init_called, cpu) = true;
+	enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
+	return 0;
+}
+
+static void gt_clockevents_stop(struct clock_event_device *clk)
+{
+	gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+	disable_percpu_irq(clk->irq);
+}
+
+static int __cpuinit gt_clockevents_setup(struct clock_event_device *clk)
+{
+	/* Use existing clock_event for boot cpu */
+	if (per_cpu(percpu_init_called, smp_processor_id()))
+		return 0;
+
+	/* already enabled in gt_clocksource_init. */
+	return gt_clockevents_init(clk);
+}
+
+static cycle_t gt_clocksource_read(struct clocksource *cs)
+{
+	return gt_counter_read();
+}
+
+static struct clocksource gt_clocksource = {
+	.name	= "ARM global timer clock source",
+	.rating	= 300,
+	.read	= gt_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(64),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+static u32 gt_sched_clock_read(void)
+{
+	if (!gt_base)
+		return 0;
+
+	return gt_counter_read();
+}
+#endif
+
+static void __init gt_clocksource_init(void)
+{
+	__raw_writel(0, gt_base + GT_CONTROL);
+	__raw_writel(0, gt_base + GT_COUNTER0);
+	__raw_writel(0, gt_base + GT_COUNTER1);
+	/* enables timer on all the cores */
+	__raw_writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate);
+#endif
+	clocksource_register_hz(&gt_clocksource, gt_clk_rate);
+}
+
+static struct clk *gt_get_clock(void)
+{
+	struct clk *clk;
+	int err;
+
+	clk = clk_get_sys("gt", NULL);
+	if (IS_ERR(clk)) {
+		pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
+		return clk;
+	}
+
+	err = clk_prepare_enable(clk);
+	if (err) {
+		pr_err("global-timer: clock prepare+enable failed: %d\n", err);
+		clk_put(clk);
+		return ERR_PTR(err);
+	}
+
+	return clk;
+}
+
+static struct local_timer_ops gt_lt_ops __cpuinitdata = {
+	.setup	= gt_clockevents_setup,
+	.stop	= gt_clockevents_stop,
+};
+
+int __init global_timer_init(void __iomem *base, unsigned int timer_irq)
+{
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(gt_clockevent, cpu);
+	int err = 0;
+	struct clk *gt_clk;
+
+	if (gt_base) {
+		pr_warn("global-timer: invalid base address\n");
+		return -EINVAL;
+	}
+
+	gt_clk = gt_get_clock();
+	if (IS_ERR(gt_clk)) {
+		pr_warn("global-timer: clk not found\n");
+		return -EINVAL;
+	}
+
+	gt_evt = alloc_percpu(struct clock_event_device *);
+	if (!gt_evt) {
+		pr_warn("global-timer: can't allocate memory\n");
+		return -ENOMEM;
+	}
+
+	err = request_percpu_irq(timer_irq, gt_clockevent_interrupt,
+				 "gt", gt_evt);
+	if (err) {
+		pr_warn("global-timer: can't register interrupt %d (%d)\n",
+			timer_irq, err);
+		goto out_free;
+	}
+
+	gt_base = base;
+	gt_clk_rate = clk_get_rate(gt_clk);
+	gt_ppi = timer_irq;
+	gt_clocksource_init();
+	gt_clockevents_init(evt);
+#ifdef CONFIG_LOCAL_TIMERS
+	err =  local_timer_register(&gt_lt_ops);
+	if (err) {
+		pr_warn("global-timer: unable to register local timer.\n");
+		goto out_irq;
+	}
+#endif
+	return 0;
+
+out_irq:
+	free_percpu_irq(timer_irq, gt_evt);
+out_free:
+	free_percpu(gt_evt);
+	return err;
+}
+
+#ifdef CONFIG_OF
+static void __init global_timer_of_register(struct device_node *np)
+{
+	struct clk *clk;
+	int err = 0;
+	int gt_ppi;
+	static void __iomem *gt_base;
+
+	/*
+	 * In r2p0 the comparators for each processor with the global timer
+	 * fire when the timer value is greater than or equal to. In previous
+	 * revisions the comparators fired when the timer value was equal to.
+	 */
+	if ((read_cpuid_id() & 0xf0000f) < 0x200000)
+		goto out;
+
+	gt_ppi = irq_of_parse_and_map(np, 0);
+	if (!gt_ppi) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	gt_base = of_iomap(np, 0);
+	if (!gt_base) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk))
+		clk_register_clkdev(clk, NULL, "gt");
+
+	global_timer_init(gt_base, gt_ppi);
+
+out:
+	WARN(err, "Global timer register failed (%d)\n", err);
+}
+
+/* Only tested on r2p2 and r3p0  */
+CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer",
+			global_timer_of_register);
+#endif
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Will Deacon, linux-lFZ/pmaqli7XmaaqVzeoHQ, Samuel Ortiz,
	Srinivas Kandagatla, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

From: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>

This is a simple driver for the global timer module found in the Cortex
A9-MP cores from revision r1p0 onwards. This should be able to perform
the functions of the system timer and the local timer in an SMP system.

The global timer has the following features:
    The global timer is a 64-bit incrementing counter with an
auto-incrementing feature. It continues incrementing after sending
interrupts. The global timer is memory mapped in the private memory
region.
    The global timer is accessible to all Cortex-A9 processors in the
cluster. Each Cortex-A9 processor has a private 64-bit comparator that
is used to assert a private interrupt when the global timer has reached
the comparator value. All the Cortex-A9 processors in a design use the
banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
Controller as a Private Peripheral Interrupt. The global timer is
clocked by PERIPHCLK.

Signed-off-by: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
CC: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
CC: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
CC: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
---
 .../devicetree/bindings/arm/global_timer.txt       |   21 ++
 drivers/clocksource/Kconfig                        |   13 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/arm_global_timer.c             |  368 ++++++++++++++++++++
 4 files changed, 403 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
 create mode 100644 drivers/clocksource/arm_global_timer.c

diff --git a/Documentation/devicetree/bindings/arm/global_timer.txt b/Documentation/devicetree/bindings/arm/global_timer.txt
new file mode 100644
index 0000000..b64abac
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/global_timer.txt
@@ -0,0 +1,21 @@
+
+* ARM Global Timer
+	Cortex-A9 are often associated with a per-core Global timer.
+
+** Timer node required properties:
+
+- compatible : Should be "arm,cortex-a9-global-timer"
+		Driver supports versions r2p0 and above.
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the GT timer
+	register window.
+
+Example:
+
+	timer@2c000600 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x2c000600 0x20>;
+		interrupts = <1 13 0xf01>;
+	};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index f151c6c..b0c4c42 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -67,6 +67,19 @@ config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
 
+config ARM_GLOBAL_TIMER
+	bool
+	select CLKSRC_OF if OF
+	help
+	  This options enables support for the ARM global timer unit
+
+config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	bool
+	depends on ARM_GLOBAL_TIMER
+	default y
+	help
+	 Use ARM global timer clock source as sched_clock
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8d979c7..b2363cb 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
+obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
new file mode 100644
index 0000000..e4bc4fe
--- /dev/null
+++ b/drivers/clocksource/arm_global_timer.c
@@ -0,0 +1,368 @@
+/*
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include <asm/sched_clock.h>
+#include <asm/mach/irq.h>
+#include <asm/cputype.h>
+#include <asm/localtimer.h>
+
+#define GT_COUNTER0	0x00
+#define GT_COUNTER1	0x04
+
+#define GT_CONTROL	0x08
+#define GT_CONTROL_TIMER_ENABLE		BIT(0)  /* this bit is NOT banked */
+#define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
+#define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
+#define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
+
+#define GT_INT_STATUS	0x0c
+#define GT_INT_STATUS_EVENT_FLAG	BIT(0)
+
+#define GT_COMP0	0x10
+#define GT_COMP1	0x14
+#define GT_AUTO_INC	0x18
+
+/*
+ * We are expecting to be clocked by the ARM peripheral clock.
+ *
+ * Note: it is assumed we are using a prescaler value of zero, so this is
+ * the units for all operations.
+ */
+static void __iomem *gt_base;
+static unsigned long gt_clk_rate;
+static int gt_ppi;
+static struct clock_event_device __percpu **gt_evt;
+static DEFINE_PER_CPU(bool, percpu_init_called);
+static DEFINE_PER_CPU(struct clock_event_device, gt_clockevent);
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static u64 gt_counter_read(void)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+
+	upper = __raw_readl(gt_base + GT_COUNTER1);
+	do {
+		old_upper = upper;
+		lower = __raw_readl(gt_base + GT_COUNTER0);
+		upper = __raw_readl(gt_base + GT_COUNTER1);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return counter;
+}
+
+/**
+ * To ensure that updates to comparator value register do not set the
+ * Interrupt Status Register proceed as follows:
+ * 1. Clear the Comp Enable bit in the Timer Control Register.
+ * 2. Write the lower 32-bit Comparator Value Register.
+ * 3. Write the upper 32-bit Comparator Value Register.
+ * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit.
+ */
+static void gt_compare_set(unsigned long delta, int periodic)
+{
+	u64 counter = gt_counter_read();
+	unsigned long ctrl = __raw_readl(gt_base + GT_CONTROL);
+
+	counter += delta;
+	ctrl &=  ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE);
+
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+	__raw_writel(lower_32_bits(counter), gt_base + GT_COMP0);
+	__raw_writel(upper_32_bits(counter), gt_base + GT_COMP1);
+
+	if (periodic) {
+		__raw_writel(delta, gt_base + GT_AUTO_INC);
+		ctrl |= GT_CONTROL_AUTO_INC;
+	}
+
+	ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+}
+
+static void gt_clockevent_set_mode(enum clock_event_mode mode,
+				   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+
+	ctrl = __raw_readl(gt_base + GT_CONTROL);
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		ctrl &= ~(GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	/* Can not shut down it as enable bit is not banked */
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
+				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	default:
+		break;
+	}
+}
+
+static int gt_clockevent_set_next_event(unsigned long evt,
+					struct clock_event_device *unused)
+{
+	gt_compare_set(evt, 0);
+	return 0;
+}
+
+static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+
+	if (__raw_readl(gt_base + GT_INT_STATUS) & GT_INT_STATUS_EVENT_FLAG) {
+		/**
+		 * ERRATA 740657( Global Timer can send 2 interrupts for
+		 * the same event in single-shot mode)
+		 * Workaround:
+		 *	Either disable single-shot mode.
+		 *	Or
+		 *	Modify the Interrupt Handler to avoid the
+		 *	offending sequence. This is achieved by clearing
+		 *	the Global Timer flag _after_ having incremented
+		 *	the Comparator register	value to a higher value.
+		 */
+		if (!(__raw_readl(gt_base + GT_CONTROL) & GT_CONTROL_AUTO_INC))
+			gt_compare_set(ULONG_MAX, 0);
+
+		__raw_writel(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
+
+		evt->event_handler(evt);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
+{
+	struct clock_event_device **this_cpu_clk;
+	int cpu = smp_processor_id();
+
+	clk->name = "ARM global timer clock event";
+	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	clk->set_mode = gt_clockevent_set_mode;
+	clk->set_next_event = gt_clockevent_set_next_event;
+	this_cpu_clk = __this_cpu_ptr(gt_evt);
+	*this_cpu_clk = clk;
+	clk->cpumask = cpumask_of(cpu);
+	clk->irq = gt_ppi;
+	clockevents_config_and_register(clk, gt_clk_rate,
+					0, 0xffffffff);
+	per_cpu(percpu_init_called, cpu) = true;
+	enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
+	return 0;
+}
+
+static void gt_clockevents_stop(struct clock_event_device *clk)
+{
+	gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+	disable_percpu_irq(clk->irq);
+}
+
+static int __cpuinit gt_clockevents_setup(struct clock_event_device *clk)
+{
+	/* Use existing clock_event for boot cpu */
+	if (per_cpu(percpu_init_called, smp_processor_id()))
+		return 0;
+
+	/* already enabled in gt_clocksource_init. */
+	return gt_clockevents_init(clk);
+}
+
+static cycle_t gt_clocksource_read(struct clocksource *cs)
+{
+	return gt_counter_read();
+}
+
+static struct clocksource gt_clocksource = {
+	.name	= "ARM global timer clock source",
+	.rating	= 300,
+	.read	= gt_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(64),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+static u32 gt_sched_clock_read(void)
+{
+	if (!gt_base)
+		return 0;
+
+	return gt_counter_read();
+}
+#endif
+
+static void __init gt_clocksource_init(void)
+{
+	__raw_writel(0, gt_base + GT_CONTROL);
+	__raw_writel(0, gt_base + GT_COUNTER0);
+	__raw_writel(0, gt_base + GT_COUNTER1);
+	/* enables timer on all the cores */
+	__raw_writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate);
+#endif
+	clocksource_register_hz(&gt_clocksource, gt_clk_rate);
+}
+
+static struct clk *gt_get_clock(void)
+{
+	struct clk *clk;
+	int err;
+
+	clk = clk_get_sys("gt", NULL);
+	if (IS_ERR(clk)) {
+		pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
+		return clk;
+	}
+
+	err = clk_prepare_enable(clk);
+	if (err) {
+		pr_err("global-timer: clock prepare+enable failed: %d\n", err);
+		clk_put(clk);
+		return ERR_PTR(err);
+	}
+
+	return clk;
+}
+
+static struct local_timer_ops gt_lt_ops __cpuinitdata = {
+	.setup	= gt_clockevents_setup,
+	.stop	= gt_clockevents_stop,
+};
+
+int __init global_timer_init(void __iomem *base, unsigned int timer_irq)
+{
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(gt_clockevent, cpu);
+	int err = 0;
+	struct clk *gt_clk;
+
+	if (gt_base) {
+		pr_warn("global-timer: invalid base address\n");
+		return -EINVAL;
+	}
+
+	gt_clk = gt_get_clock();
+	if (IS_ERR(gt_clk)) {
+		pr_warn("global-timer: clk not found\n");
+		return -EINVAL;
+	}
+
+	gt_evt = alloc_percpu(struct clock_event_device *);
+	if (!gt_evt) {
+		pr_warn("global-timer: can't allocate memory\n");
+		return -ENOMEM;
+	}
+
+	err = request_percpu_irq(timer_irq, gt_clockevent_interrupt,
+				 "gt", gt_evt);
+	if (err) {
+		pr_warn("global-timer: can't register interrupt %d (%d)\n",
+			timer_irq, err);
+		goto out_free;
+	}
+
+	gt_base = base;
+	gt_clk_rate = clk_get_rate(gt_clk);
+	gt_ppi = timer_irq;
+	gt_clocksource_init();
+	gt_clockevents_init(evt);
+#ifdef CONFIG_LOCAL_TIMERS
+	err =  local_timer_register(&gt_lt_ops);
+	if (err) {
+		pr_warn("global-timer: unable to register local timer.\n");
+		goto out_irq;
+	}
+#endif
+	return 0;
+
+out_irq:
+	free_percpu_irq(timer_irq, gt_evt);
+out_free:
+	free_percpu(gt_evt);
+	return err;
+}
+
+#ifdef CONFIG_OF
+static void __init global_timer_of_register(struct device_node *np)
+{
+	struct clk *clk;
+	int err = 0;
+	int gt_ppi;
+	static void __iomem *gt_base;
+
+	/*
+	 * In r2p0 the comparators for each processor with the global timer
+	 * fire when the timer value is greater than or equal to. In previous
+	 * revisions the comparators fired when the timer value was equal to.
+	 */
+	if ((read_cpuid_id() & 0xf0000f) < 0x200000)
+		goto out;
+
+	gt_ppi = irq_of_parse_and_map(np, 0);
+	if (!gt_ppi) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	gt_base = of_iomap(np, 0);
+	if (!gt_base) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk))
+		clk_register_clkdev(clk, NULL, "gt");
+
+	global_timer_init(gt_base, gt_ppi);
+
+out:
+	WARN(err, "Global timer register failed (%d)\n", err);
+}
+
+/* Only tested on r2p2 and r3p0  */
+CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer",
+			global_timer_of_register);
+#endif
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

From: Stuart Menefy <stuart.menefy@st.com>

This is a simple driver for the global timer module found in the Cortex
A9-MP cores from revision r1p0 onwards. This should be able to perform
the functions of the system timer and the local timer in an SMP system.

The global timer has the following features:
    The global timer is a 64-bit incrementing counter with an
auto-incrementing feature. It continues incrementing after sending
interrupts. The global timer is memory mapped in the private memory
region.
    The global timer is accessible to all Cortex-A9 processors in the
cluster. Each Cortex-A9 processor has a private 64-bit comparator that
is used to assert a private interrupt when the global timer has reached
the comparator value. All the Cortex-A9 processors in a design use the
banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
Controller as a Private Peripheral Interrupt. The global timer is
clocked by PERIPHCLK.

Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Rob Herring <robherring2@gmail.com>
CC: Linus Walleij <linus.walleij@linaro.org>
CC: Will Deacon <will.deacon@arm.com>
CC: Thomas Gleixner <tglx@linutronix.de>
---
 .../devicetree/bindings/arm/global_timer.txt       |   21 ++
 drivers/clocksource/Kconfig                        |   13 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/arm_global_timer.c             |  368 ++++++++++++++++++++
 4 files changed, 403 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/global_timer.txt
 create mode 100644 drivers/clocksource/arm_global_timer.c

diff --git a/Documentation/devicetree/bindings/arm/global_timer.txt b/Documentation/devicetree/bindings/arm/global_timer.txt
new file mode 100644
index 0000000..b64abac
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/global_timer.txt
@@ -0,0 +1,21 @@
+
+* ARM Global Timer
+	Cortex-A9 are often associated with a per-core Global timer.
+
+** Timer node required properties:
+
+- compatible : Should be "arm,cortex-a9-global-timer"
+		Driver supports versions r2p0 and above.
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the GT timer
+	register window.
+
+Example:
+
+	timer at 2c000600 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x2c000600 0x20>;
+		interrupts = <1 13 0xf01>;
+	};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index f151c6c..b0c4c42 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -67,6 +67,19 @@ config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
 
+config ARM_GLOBAL_TIMER
+	bool
+	select CLKSRC_OF if OF
+	help
+	  This options enables support for the ARM global timer unit
+
+config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	bool
+	depends on ARM_GLOBAL_TIMER
+	default y
+	help
+	 Use ARM global timer clock source as sched_clock
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8d979c7..b2363cb 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
+obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
new file mode 100644
index 0000000..e4bc4fe
--- /dev/null
+++ b/drivers/clocksource/arm_global_timer.c
@@ -0,0 +1,368 @@
+/*
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+
+#include <asm/sched_clock.h>
+#include <asm/mach/irq.h>
+#include <asm/cputype.h>
+#include <asm/localtimer.h>
+
+#define GT_COUNTER0	0x00
+#define GT_COUNTER1	0x04
+
+#define GT_CONTROL	0x08
+#define GT_CONTROL_TIMER_ENABLE		BIT(0)  /* this bit is NOT banked */
+#define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
+#define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
+#define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
+
+#define GT_INT_STATUS	0x0c
+#define GT_INT_STATUS_EVENT_FLAG	BIT(0)
+
+#define GT_COMP0	0x10
+#define GT_COMP1	0x14
+#define GT_AUTO_INC	0x18
+
+/*
+ * We are expecting to be clocked by the ARM peripheral clock.
+ *
+ * Note: it is assumed we are using a prescaler value of zero, so this is
+ * the units for all operations.
+ */
+static void __iomem *gt_base;
+static unsigned long gt_clk_rate;
+static int gt_ppi;
+static struct clock_event_device __percpu **gt_evt;
+static DEFINE_PER_CPU(bool, percpu_init_called);
+static DEFINE_PER_CPU(struct clock_event_device, gt_clockevent);
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static u64 gt_counter_read(void)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+
+	upper = __raw_readl(gt_base + GT_COUNTER1);
+	do {
+		old_upper = upper;
+		lower = __raw_readl(gt_base + GT_COUNTER0);
+		upper = __raw_readl(gt_base + GT_COUNTER1);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return counter;
+}
+
+/**
+ * To ensure that updates to comparator value register do not set the
+ * Interrupt Status Register proceed as follows:
+ * 1. Clear the Comp Enable bit in the Timer Control Register.
+ * 2. Write the lower 32-bit Comparator Value Register.
+ * 3. Write the upper 32-bit Comparator Value Register.
+ * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit.
+ */
+static void gt_compare_set(unsigned long delta, int periodic)
+{
+	u64 counter = gt_counter_read();
+	unsigned long ctrl = __raw_readl(gt_base + GT_CONTROL);
+
+	counter += delta;
+	ctrl &=  ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE);
+
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+	__raw_writel(lower_32_bits(counter), gt_base + GT_COMP0);
+	__raw_writel(upper_32_bits(counter), gt_base + GT_COMP1);
+
+	if (periodic) {
+		__raw_writel(delta, gt_base + GT_AUTO_INC);
+		ctrl |= GT_CONTROL_AUTO_INC;
+	}
+
+	ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
+	__raw_writel(ctrl, gt_base + GT_CONTROL);
+}
+
+static void gt_clockevent_set_mode(enum clock_event_mode mode,
+				   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+
+	ctrl = __raw_readl(gt_base + GT_CONTROL);
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		ctrl &= ~(GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	/* Can not shut down it as enable bit is not banked */
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
+				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
+		__raw_writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	default:
+		break;
+	}
+}
+
+static int gt_clockevent_set_next_event(unsigned long evt,
+					struct clock_event_device *unused)
+{
+	gt_compare_set(evt, 0);
+	return 0;
+}
+
+static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+
+	if (__raw_readl(gt_base + GT_INT_STATUS) & GT_INT_STATUS_EVENT_FLAG) {
+		/**
+		 * ERRATA 740657( Global Timer can send 2 interrupts for
+		 * the same event in single-shot mode)
+		 * Workaround:
+		 *	Either disable single-shot mode.
+		 *	Or
+		 *	Modify the Interrupt Handler to avoid the
+		 *	offending sequence. This is achieved by clearing
+		 *	the Global Timer flag _after_ having incremented
+		 *	the Comparator register	value to a higher value.
+		 */
+		if (!(__raw_readl(gt_base + GT_CONTROL) & GT_CONTROL_AUTO_INC))
+			gt_compare_set(ULONG_MAX, 0);
+
+		__raw_writel(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
+
+		evt->event_handler(evt);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
+{
+	struct clock_event_device **this_cpu_clk;
+	int cpu = smp_processor_id();
+
+	clk->name = "ARM global timer clock event";
+	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	clk->set_mode = gt_clockevent_set_mode;
+	clk->set_next_event = gt_clockevent_set_next_event;
+	this_cpu_clk = __this_cpu_ptr(gt_evt);
+	*this_cpu_clk = clk;
+	clk->cpumask = cpumask_of(cpu);
+	clk->irq = gt_ppi;
+	clockevents_config_and_register(clk, gt_clk_rate,
+					0, 0xffffffff);
+	per_cpu(percpu_init_called, cpu) = true;
+	enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
+	return 0;
+}
+
+static void gt_clockevents_stop(struct clock_event_device *clk)
+{
+	gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+	disable_percpu_irq(clk->irq);
+}
+
+static int __cpuinit gt_clockevents_setup(struct clock_event_device *clk)
+{
+	/* Use existing clock_event for boot cpu */
+	if (per_cpu(percpu_init_called, smp_processor_id()))
+		return 0;
+
+	/* already enabled in gt_clocksource_init. */
+	return gt_clockevents_init(clk);
+}
+
+static cycle_t gt_clocksource_read(struct clocksource *cs)
+{
+	return gt_counter_read();
+}
+
+static struct clocksource gt_clocksource = {
+	.name	= "ARM global timer clock source",
+	.rating	= 300,
+	.read	= gt_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(64),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+static u32 gt_sched_clock_read(void)
+{
+	if (!gt_base)
+		return 0;
+
+	return gt_counter_read();
+}
+#endif
+
+static void __init gt_clocksource_init(void)
+{
+	__raw_writel(0, gt_base + GT_CONTROL);
+	__raw_writel(0, gt_base + GT_COUNTER0);
+	__raw_writel(0, gt_base + GT_COUNTER1);
+	/* enables timer on all the cores */
+	__raw_writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate);
+#endif
+	clocksource_register_hz(&gt_clocksource, gt_clk_rate);
+}
+
+static struct clk *gt_get_clock(void)
+{
+	struct clk *clk;
+	int err;
+
+	clk = clk_get_sys("gt", NULL);
+	if (IS_ERR(clk)) {
+		pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
+		return clk;
+	}
+
+	err = clk_prepare_enable(clk);
+	if (err) {
+		pr_err("global-timer: clock prepare+enable failed: %d\n", err);
+		clk_put(clk);
+		return ERR_PTR(err);
+	}
+
+	return clk;
+}
+
+static struct local_timer_ops gt_lt_ops __cpuinitdata = {
+	.setup	= gt_clockevents_setup,
+	.stop	= gt_clockevents_stop,
+};
+
+int __init global_timer_init(void __iomem *base, unsigned int timer_irq)
+{
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(gt_clockevent, cpu);
+	int err = 0;
+	struct clk *gt_clk;
+
+	if (gt_base) {
+		pr_warn("global-timer: invalid base address\n");
+		return -EINVAL;
+	}
+
+	gt_clk = gt_get_clock();
+	if (IS_ERR(gt_clk)) {
+		pr_warn("global-timer: clk not found\n");
+		return -EINVAL;
+	}
+
+	gt_evt = alloc_percpu(struct clock_event_device *);
+	if (!gt_evt) {
+		pr_warn("global-timer: can't allocate memory\n");
+		return -ENOMEM;
+	}
+
+	err = request_percpu_irq(timer_irq, gt_clockevent_interrupt,
+				 "gt", gt_evt);
+	if (err) {
+		pr_warn("global-timer: can't register interrupt %d (%d)\n",
+			timer_irq, err);
+		goto out_free;
+	}
+
+	gt_base = base;
+	gt_clk_rate = clk_get_rate(gt_clk);
+	gt_ppi = timer_irq;
+	gt_clocksource_init();
+	gt_clockevents_init(evt);
+#ifdef CONFIG_LOCAL_TIMERS
+	err =  local_timer_register(&gt_lt_ops);
+	if (err) {
+		pr_warn("global-timer: unable to register local timer.\n");
+		goto out_irq;
+	}
+#endif
+	return 0;
+
+out_irq:
+	free_percpu_irq(timer_irq, gt_evt);
+out_free:
+	free_percpu(gt_evt);
+	return err;
+}
+
+#ifdef CONFIG_OF
+static void __init global_timer_of_register(struct device_node *np)
+{
+	struct clk *clk;
+	int err = 0;
+	int gt_ppi;
+	static void __iomem *gt_base;
+
+	/*
+	 * In r2p0 the comparators for each processor with the global timer
+	 * fire when the timer value is greater than or equal to. In previous
+	 * revisions the comparators fired when the timer value was equal to.
+	 */
+	if ((read_cpuid_id() & 0xf0000f) < 0x200000)
+		goto out;
+
+	gt_ppi = irq_of_parse_and_map(np, 0);
+	if (!gt_ppi) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	gt_base = of_iomap(np, 0);
+	if (!gt_base) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk))
+		clk_register_clkdev(clk, NULL, "gt");
+
+	global_timer_init(gt_base, gt_ppi);
+
+out:
+	WARN(err, "Global timer register failed (%d)\n", err);
+}
+
+/* Only tested on r2p2 and r3p0  */
+CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer",
+			global_timer_of_register);
+#endif
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk,
	Alexander Shiyan, Lars-Peter Clausen

It is common to access regmap registers at bit level, using
regmap_update_bits or regmap_read functions, however the end user has to
take care of a mask or shifting. This becomes overhead when such use
cases are high. Having a common function to do this is much convenient
and less error prone.

The idea of regmap_field is simple, regmap_field gives a logical
structure to bits of the regmap register, and the driver can use this
logical entity without the knowledge of the bit postions and masks all
over the code. This way code looks much neat and it need not handle the
masks, shifts every time it access the those entities.

With this new regmap_field_read/write apis the end user can setup a
regmap field using regmap_field_init and use the return regmap_field to
read write the register field without worrying about the masks or
shifts.

Also this apis will be usefull for drivers which are based on regmaps,
like some clocks or pinctrls which can work on the regmap_fields
directly without having to worry about bit positions.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Mark Brown <broonie@kernel.org>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Alexander Shiyan <shc_work@mail.ru>
CC: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/base/regmap/internal.h |    8 +++
 drivers/base/regmap/regmap.c   |  104 ++++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h         |   42 ++++++++++++++++
 3 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index c130536..c5f6ebd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -174,6 +174,14 @@ struct regmap_range_node {
 	unsigned int window_len;
 };
 
+struct regmap_field {
+	struct regmap *regmap;
+	unsigned int mask;
+	/* lsb */
+	unsigned int shift;
+	unsigned int reg;
+};
+
 #ifdef CONFIG_DEBUG_FS
 extern void regmap_debugfs_initcall(void);
 extern void regmap_debugfs_init(struct regmap *map, const char *name);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a941dcf..8d967cc 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -801,6 +801,67 @@ struct regmap *devm_regmap_init(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_regmap_init);
 
+static void regmap_field_init(struct regmap_field *rm_field,
+	struct regmap *regmap, struct reg_field reg_field)
+{
+	int field_bits = reg_field.msb - reg_field.lsb + 1;
+	rm_field->regmap = regmap;
+	rm_field->reg = reg_field.reg;
+	rm_field->shift = reg_field.lsb;
+	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+}
+
+/**
+ * devm_regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @dev: Device that will be interacted with
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field will be automatically freed
+ * by the device management code.
+ */
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = devm_kzalloc(dev,
+					sizeof(*rm_field), GFP_KERNEL);
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+
+}
+EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
+/**
+ * regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field should be freed by the
+ * user once its finished working with it using regmap_field_free().
+ */
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
+
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+}
+EXPORT_SYMBOL_GPL(regmap_field_alloc);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
@@ -1249,6 +1310,23 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(regmap_raw_write);
 
+/**
+ * regmap_field_write(): Write a value to a single register field
+ *
+ * @field: Register field to write to
+ * @val: Value to be written
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_write(struct regmap_field *field, unsigned int val)
+{
+	return regmap_update_bits(field->regmap, field->reg,
+				field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1532,6 +1610,32 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 EXPORT_SYMBOL_GPL(regmap_raw_read);
 
 /**
+ * regmap_field_read(): Read a value to a single register field
+ *
+ * @field: Register field to read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+	ret = regmap_read(field->regmap, field->reg, &reg_val);
+	if (ret != 0)
+		return ret;
+
+	reg_val &= field->mask;
+	reg_val >>= field->shift;
+	*val = reg_val;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_field_read);
+
+/**
  * regmap_bulk_read(): Read multiple registers from the device
  *
  * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 02d84e2..557a54e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -15,6 +15,8 @@
 
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include <linux/device.h>
+#include <linux/slab.h>
 
 struct module;
 struct device;
@@ -23,6 +25,7 @@ struct irq_domain;
 struct spi_device;
 struct regmap;
 struct regmap_range_cfg;
+struct regmap_field;
 
 /* An enum of all the supported cache types */
 enum regcache_type {
@@ -412,6 +415,45 @@ bool regmap_reg_in_ranges(unsigned int reg,
 			  unsigned int nranges);
 
 /**
+ * Description of an register field
+ *
+ * @reg: Offset of the register within the regmap bank
+ * @lsb: lsb of the register field.
+ * @reg: msb of the register field.
+ */
+struct reg_field {
+	unsigned int reg;
+	unsigned int lsb;
+	unsigned int msb;
+};
+
+#define REG_FIELD(_reg, _lsb, _msb) {		\
+				.reg = _reg,	\
+				.lsb = _lsb,	\
+				.msb = _msb,	\
+				}
+
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field);
+
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field);
+
+static inline void regmap_field_free(struct regmap_field *field)
+{
+	kfree(field);
+}
+
+static inline void devm_regmap_field_free(struct device *dev,
+	struct regmap_field *field)
+{
+	devm_kfree(dev, field);
+}
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val);
+int regmap_field_write(struct regmap_field *field, unsigned int val);
+
+/**
  * Description of an IRQ for the generic regmap irq_chip.
  *
  * @reg_offset: Offset of the status/mask register within the bank
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Lars-Peter Clausen, linux-lFZ/pmaqli7XmaaqVzeoHQ, Samuel Ortiz,
	Alexander Shiyan, Srinivas Kandagatla, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

It is common to access regmap registers at bit level, using
regmap_update_bits or regmap_read functions, however the end user has to
take care of a mask or shifting. This becomes overhead when such use
cases are high. Having a common function to do this is much convenient
and less error prone.

The idea of regmap_field is simple, regmap_field gives a logical
structure to bits of the regmap register, and the driver can use this
logical entity without the knowledge of the bit postions and masks all
over the code. This way code looks much neat and it need not handle the
masks, shifts every time it access the those entities.

With this new regmap_field_read/write apis the end user can setup a
regmap field using regmap_field_init and use the return regmap_field to
read write the register field without worrying about the masks or
shifts.

Also this apis will be usefull for drivers which are based on regmaps,
like some clocks or pinctrls which can work on the regmap_fields
directly without having to worry about bit positions.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
CC: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
CC: Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org>
CC: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
---
 drivers/base/regmap/internal.h |    8 +++
 drivers/base/regmap/regmap.c   |  104 ++++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h         |   42 ++++++++++++++++
 3 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index c130536..c5f6ebd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -174,6 +174,14 @@ struct regmap_range_node {
 	unsigned int window_len;
 };
 
+struct regmap_field {
+	struct regmap *regmap;
+	unsigned int mask;
+	/* lsb */
+	unsigned int shift;
+	unsigned int reg;
+};
+
 #ifdef CONFIG_DEBUG_FS
 extern void regmap_debugfs_initcall(void);
 extern void regmap_debugfs_init(struct regmap *map, const char *name);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a941dcf..8d967cc 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -801,6 +801,67 @@ struct regmap *devm_regmap_init(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_regmap_init);
 
+static void regmap_field_init(struct regmap_field *rm_field,
+	struct regmap *regmap, struct reg_field reg_field)
+{
+	int field_bits = reg_field.msb - reg_field.lsb + 1;
+	rm_field->regmap = regmap;
+	rm_field->reg = reg_field.reg;
+	rm_field->shift = reg_field.lsb;
+	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+}
+
+/**
+ * devm_regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @dev: Device that will be interacted with
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field will be automatically freed
+ * by the device management code.
+ */
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = devm_kzalloc(dev,
+					sizeof(*rm_field), GFP_KERNEL);
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+
+}
+EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
+/**
+ * regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field should be freed by the
+ * user once its finished working with it using regmap_field_free().
+ */
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
+
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+}
+EXPORT_SYMBOL_GPL(regmap_field_alloc);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
@@ -1249,6 +1310,23 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(regmap_raw_write);
 
+/**
+ * regmap_field_write(): Write a value to a single register field
+ *
+ * @field: Register field to write to
+ * @val: Value to be written
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_write(struct regmap_field *field, unsigned int val)
+{
+	return regmap_update_bits(field->regmap, field->reg,
+				field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1532,6 +1610,32 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 EXPORT_SYMBOL_GPL(regmap_raw_read);
 
 /**
+ * regmap_field_read(): Read a value to a single register field
+ *
+ * @field: Register field to read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+	ret = regmap_read(field->regmap, field->reg, &reg_val);
+	if (ret != 0)
+		return ret;
+
+	reg_val &= field->mask;
+	reg_val >>= field->shift;
+	*val = reg_val;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_field_read);
+
+/**
  * regmap_bulk_read(): Read multiple registers from the device
  *
  * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 02d84e2..557a54e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -15,6 +15,8 @@
 
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include <linux/device.h>
+#include <linux/slab.h>
 
 struct module;
 struct device;
@@ -23,6 +25,7 @@ struct irq_domain;
 struct spi_device;
 struct regmap;
 struct regmap_range_cfg;
+struct regmap_field;
 
 /* An enum of all the supported cache types */
 enum regcache_type {
@@ -412,6 +415,45 @@ bool regmap_reg_in_ranges(unsigned int reg,
 			  unsigned int nranges);
 
 /**
+ * Description of an register field
+ *
+ * @reg: Offset of the register within the regmap bank
+ * @lsb: lsb of the register field.
+ * @reg: msb of the register field.
+ */
+struct reg_field {
+	unsigned int reg;
+	unsigned int lsb;
+	unsigned int msb;
+};
+
+#define REG_FIELD(_reg, _lsb, _msb) {		\
+				.reg = _reg,	\
+				.lsb = _lsb,	\
+				.msb = _msb,	\
+				}
+
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field);
+
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field);
+
+static inline void regmap_field_free(struct regmap_field *field)
+{
+	kfree(field);
+}
+
+static inline void devm_regmap_field_free(struct device *dev,
+	struct regmap_field *field)
+{
+	devm_kfree(dev, field);
+}
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val);
+int regmap_field_write(struct regmap_field *field, unsigned int val);
+
+/**
  * Description of an IRQ for the generic regmap irq_chip.
  *
  * @reg_offset: Offset of the status/mask register within the bank
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-10  9:21     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

It is common to access regmap registers at bit level, using
regmap_update_bits or regmap_read functions, however the end user has to
take care of a mask or shifting. This becomes overhead when such use
cases are high. Having a common function to do this is much convenient
and less error prone.

The idea of regmap_field is simple, regmap_field gives a logical
structure to bits of the regmap register, and the driver can use this
logical entity without the knowledge of the bit postions and masks all
over the code. This way code looks much neat and it need not handle the
masks, shifts every time it access the those entities.

With this new regmap_field_read/write apis the end user can setup a
regmap field using regmap_field_init and use the return regmap_field to
read write the register field without worrying about the masks or
shifts.

Also this apis will be usefull for drivers which are based on regmaps,
like some clocks or pinctrls which can work on the regmap_fields
directly without having to worry about bit positions.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Mark Brown <broonie@kernel.org>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Alexander Shiyan <shc_work@mail.ru>
CC: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/base/regmap/internal.h |    8 +++
 drivers/base/regmap/regmap.c   |  104 ++++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h         |   42 ++++++++++++++++
 3 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index c130536..c5f6ebd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -174,6 +174,14 @@ struct regmap_range_node {
 	unsigned int window_len;
 };
 
+struct regmap_field {
+	struct regmap *regmap;
+	unsigned int mask;
+	/* lsb */
+	unsigned int shift;
+	unsigned int reg;
+};
+
 #ifdef CONFIG_DEBUG_FS
 extern void regmap_debugfs_initcall(void);
 extern void regmap_debugfs_init(struct regmap *map, const char *name);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a941dcf..8d967cc 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -801,6 +801,67 @@ struct regmap *devm_regmap_init(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_regmap_init);
 
+static void regmap_field_init(struct regmap_field *rm_field,
+	struct regmap *regmap, struct reg_field reg_field)
+{
+	int field_bits = reg_field.msb - reg_field.lsb + 1;
+	rm_field->regmap = regmap;
+	rm_field->reg = reg_field.reg;
+	rm_field->shift = reg_field.lsb;
+	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+}
+
+/**
+ * devm_regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @dev: Device that will be interacted with
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field will be automatically freed
+ * by the device management code.
+ */
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = devm_kzalloc(dev,
+					sizeof(*rm_field), GFP_KERNEL);
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+
+}
+EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
+/**
+ * regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field should be freed by the
+ * user once its finished working with it using regmap_field_free().
+ */
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
+
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+}
+EXPORT_SYMBOL_GPL(regmap_field_alloc);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
@@ -1249,6 +1310,23 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(regmap_raw_write);
 
+/**
+ * regmap_field_write(): Write a value to a single register field
+ *
+ * @field: Register field to write to
+ * @val: Value to be written
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_write(struct regmap_field *field, unsigned int val)
+{
+	return regmap_update_bits(field->regmap, field->reg,
+				field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1532,6 +1610,32 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 EXPORT_SYMBOL_GPL(regmap_raw_read);
 
 /**
+ * regmap_field_read(): Read a value to a single register field
+ *
+ * @field: Register field to read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+	ret = regmap_read(field->regmap, field->reg, &reg_val);
+	if (ret != 0)
+		return ret;
+
+	reg_val &= field->mask;
+	reg_val >>= field->shift;
+	*val = reg_val;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_field_read);
+
+/**
  * regmap_bulk_read(): Read multiple registers from the device
  *
  * @map: Register map to write to
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 02d84e2..557a54e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -15,6 +15,8 @@
 
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include <linux/device.h>
+#include <linux/slab.h>
 
 struct module;
 struct device;
@@ -23,6 +25,7 @@ struct irq_domain;
 struct spi_device;
 struct regmap;
 struct regmap_range_cfg;
+struct regmap_field;
 
 /* An enum of all the supported cache types */
 enum regcache_type {
@@ -412,6 +415,45 @@ bool regmap_reg_in_ranges(unsigned int reg,
 			  unsigned int nranges);
 
 /**
+ * Description of an register field
+ *
+ * @reg: Offset of the register within the regmap bank
+ * @lsb: lsb of the register field.
+ * @reg: msb of the register field.
+ */
+struct reg_field {
+	unsigned int reg;
+	unsigned int lsb;
+	unsigned int msb;
+};
+
+#define REG_FIELD(_reg, _lsb, _msb) {		\
+				.reg = _reg,	\
+				.lsb = _lsb,	\
+				.msb = _msb,	\
+				}
+
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field);
+
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field);
+
+static inline void regmap_field_free(struct regmap_field *field)
+{
+	kfree(field);
+}
+
+static inline void devm_regmap_field_free(struct device *dev,
+	struct regmap_field *field)
+{
+	devm_kfree(dev, field);
+}
+
+int regmap_field_read(struct regmap_field *field, unsigned int *val);
+int regmap_field_write(struct regmap_field *field, unsigned int val);
+
+/**
  * Description of an IRQ for the generic regmap irq_chip.
  *
  * @reg_offset: Offset of the status/mask register within the bank
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:22     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:22 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

System configuration(aka syscfg) registers are very basic configuration
registers arranged in groups across ST Settop Box parts.

The SOCs are assembled from existing IP blocks, which don't change very
often. However these blocks are assembled in different configurations to
meet the device requirements. So most IP blocks as well as having a bus
interface through which their own registers are accessible, will also
have a number of bristles(wires) which are signals that are going in and
out of the IP for configuration and status. To make these signals
accessible to software they are wired to "System Configuration
Registers".

Drivers target the IP blocks, which don't change much. Where as the
mapping of IP specific bristles(wires) to "System Configuration
Registers" do change per each SOC, and therefore we do not want this
information to be part of the driver.

Having a System Configuration infrastructure gives much flexibility and
abstraction to drivers to configure them. Typically in a SOC there will
be more than hundreds of these registers, which are again divided into
groups. The IP related config registers tend to much regular in latest
ST SOCs, so having a common place for configuring these registers makes
sense and avoid lot of code duplication.

This mfd driver provides higher level inialization routines for various
IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
get to syscfg registers via standard regmap api which is usefull for
drivers like pinctrl.

This patch adds support to ST System Configuration registers, which can
be configured by the drivers.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Linus Walleij <linus.walleij@linaro.org>
CC: Mark Brown <broonie@kernel.org>
---
 .../devicetree/bindings/mfd/stixxxx-syscfg.txt     |   18 ++
 drivers/mfd/Kconfig                                |   10 ++
 drivers/mfd/Makefile                               |    1 +
 drivers/mfd/stixxxx-syscfg.c                       |  168 ++++++++++++++++++++
 include/linux/mfd/stixxxx-syscfg.h                 |   15 ++
 5 files changed, 212 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
 create mode 100644 drivers/mfd/stixxxx-syscfg.c
 create mode 100644 include/linux/mfd/stixxxx-syscfg.h

diff --git a/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt b/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
new file mode 100644
index 0000000..428c751
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
@@ -0,0 +1,18 @@
+*STixxxx SYSCFG
+
+- compatible : should be "st,<SOC>-syscfg" like "st,stih415-syscfg"
+			or "st,stih416-syscfg".
+- reg, reg-names, interrupts, interrupt-names	: Standard way to define device
+			resources with names. look in
+			Documentation/devicetree/bindings/resource-names.txt
+- syscfg-range <start size> : Should be syscfg number range for this bank.
+- syscfg-name		    : Should be name of the syscfg, will be used in debugfs.
+
+Example of a SBC_SYSCFG bank node:
+
+syscfg_sbc: syscfg@fe600000{
+	compatible      = "st,stih415-syscfg";
+	reg		= <0xfe600000 0xb4>;
+	syscfg-range	= <0 44>;
+	syscfg-name	= "SYSCFG_SBC";
+};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d54e985..af49b58 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -649,6 +649,16 @@ config MFD_STA2X11
 	select MFD_CORE
 	select REGMAP_MMIO
 
+config MFD_STIXXXX_SYSCFG
+	bool "ST System Configuration Registers(aka syscfg) via regmap"
+	select REGMAP_MMIO
+	help
+	  Select this option to enable accessing STMicroelectronics
+	  System Configuration Registers via standard regmap apis with
+	  lookup helper functions.
+
+	  If unsure, say N.
+
 config MFD_SYSCON
 	bool "System Controller Register R/W Based on Regmap"
 	select REGMAP_MMIO
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 718e94a..c1f6570 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -150,6 +150,7 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
+obj-$(CONFIG_MFD_STIXXXX_SYSCFG)	+= stixxxx-syscfg.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
 obj-$(CONFIG_MFD_LM3533)	+= lm3533-core.o lm3533-ctrlbank.o
 obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o vexpress-sysreg.o
diff --git a/drivers/mfd/stixxxx-syscfg.c b/drivers/mfd/stixxxx-syscfg.c
new file mode 100644
index 0000000..10ea4e4
--- /dev/null
+++ b/drivers/mfd/stixxxx-syscfg.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Syscfg driver is used to configure various devices like Ethernet,
+ * USB, PCIE, SATA and so on.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/mfd/stixxxx-syscfg.h>
+
+#define DRIVER_NAME "stixxxx-syscfg"
+
+static struct platform_driver syscfg_driver;
+struct syscfg {
+	void __iomem *base;
+	struct regmap *regmap;
+	int	start, end;
+	const char *name;
+	struct device_node *of_node;
+};
+
+static int syscfg_match_name(struct device *dev, void *data)
+{
+	struct syscfg *syscfg = dev_get_drvdata(dev);
+
+	if (syscfg)
+		if (!strcmp(syscfg->name, (const char *)data))
+			return 1;
+	return 0;
+}
+
+struct regmap *syscfg_regmap_lookup_by_name(const char *name)
+{
+	struct syscfg *syscfg;
+	struct device *dev;
+
+	dev = driver_find_device(&syscfg_driver.driver, NULL, (void *)name,
+				 syscfg_match_name);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	syscfg = dev_get_drvdata(dev);
+
+	return syscfg->regmap;
+}
+
+static int syscfg_match_node(struct device *dev, void *data)
+{
+	struct device_node *dn = data;
+
+	return (dev->of_node == dn) ? 1 : 0;
+}
+
+struct regmap *syscfg_node_to_regmap(struct device_node *np)
+{
+	struct syscfg *syscfg;
+	struct device *dev;
+
+	dev = driver_find_device(&syscfg_driver.driver, NULL, np,
+				 syscfg_match_node);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	syscfg = dev_get_drvdata(dev);
+
+	return syscfg->regmap;
+}
+EXPORT_SYMBOL_GPL(syscfg_node_to_regmap);
+
+struct regmap *syscfg_regmap_lookup_by_phandle(struct device_node *np,
+					const char *property)
+{
+	struct device_node *syscfg_np;
+	struct regmap *regmap;
+
+	syscfg_np = of_parse_phandle(np, property, 0);
+	if (!syscfg_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = syscfg_node_to_regmap(syscfg_np);
+	of_node_put(syscfg_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(syscfg_regmap_lookup_by_phandle);
+
+static struct regmap_config syscfg_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static int syscfg_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct syscfg *syscfg;
+	struct resource *res;
+	u32 range[2];
+
+	if (!np)
+		return -EINVAL;
+
+	syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL);
+	if (!syscfg)
+		return -ENOMEM;
+
+	syscfg->of_node = np;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	syscfg->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!syscfg->base) {
+		dev_err(&pdev->dev, "Unable to ioremap registers|\n");
+		return -ENODATA;
+	}
+
+	of_property_read_u32_array(np, "syscfg-range", (u32 *)&range, 2);
+	syscfg->start = range[0];
+	syscfg->end = range[0] + range[1];
+	of_property_read_string(np, "syscfg-name", &syscfg->name);
+
+	syscfg_regmap_config.name = kasprintf(GFP_KERNEL, "%s", syscfg->name);
+	syscfg_regmap_config.max_register = res->end - res->start - 3;
+	syscfg->regmap = devm_regmap_init_mmio(&pdev->dev, syscfg->base,
+					&syscfg_regmap_config);
+	if (IS_ERR(syscfg->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(syscfg->regmap);
+	}
+
+	platform_set_drvdata(pdev, syscfg);
+	dev_info(&pdev->dev,
+		"%s[%d - %d] sucessfully intialized\n",
+		syscfg->name, syscfg->start, syscfg->end);
+	return 0;
+}
+
+static struct of_device_id syscfg_match[] = {
+	{ .compatible = "st,stih415-syscfg", },
+	{ .compatible = "st,stih416-syscfg", },
+	{},
+};
+
+static struct platform_driver syscfg_driver = {
+	.probe		= syscfg_probe,
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(syscfg_match),
+	},
+};
+
+static int __init syscfg_init(void)
+{
+	return platform_driver_register(&syscfg_driver);
+}
+postcore_initcall(syscfg_init);
diff --git a/include/linux/mfd/stixxxx-syscfg.h b/include/linux/mfd/stixxxx-syscfg.h
new file mode 100644
index 0000000..18ed6da7
--- /dev/null
+++ b/include/linux/mfd/stixxxx-syscfg.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ */
+
+#ifndef __LINUX_MFD_STIXXXX_SYSCFG_H
+#define __LINUX_MFD_STIXXXX_SYSCFG_H
+
+struct regmap *syscfg_regmap_lookup_by_phandle(struct device_node *np,
+					const char *property);
+struct regmap *syscfg_regmap_lookup_by_name(const char *name);
+
+#endif /* __LINUX_MFD_STIXXXX_SYSCFG_H */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10  9:22     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

System configuration(aka syscfg) registers are very basic configuration
registers arranged in groups across ST Settop Box parts.

The SOCs are assembled from existing IP blocks, which don't change very
often. However these blocks are assembled in different configurations to
meet the device requirements. So most IP blocks as well as having a bus
interface through which their own registers are accessible, will also
have a number of bristles(wires) which are signals that are going in and
out of the IP for configuration and status. To make these signals
accessible to software they are wired to "System Configuration
Registers".

Drivers target the IP blocks, which don't change much. Where as the
mapping of IP specific bristles(wires) to "System Configuration
Registers" do change per each SOC, and therefore we do not want this
information to be part of the driver.

Having a System Configuration infrastructure gives much flexibility and
abstraction to drivers to configure them. Typically in a SOC there will
be more than hundreds of these registers, which are again divided into
groups. The IP related config registers tend to much regular in latest
ST SOCs, so having a common place for configuring these registers makes
sense and avoid lot of code duplication.

This mfd driver provides higher level inialization routines for various
IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
get to syscfg registers via standard regmap api which is usefull for
drivers like pinctrl.

This patch adds support to ST System Configuration registers, which can
be configured by the drivers.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Linus Walleij <linus.walleij@linaro.org>
CC: Mark Brown <broonie@kernel.org>
---
 .../devicetree/bindings/mfd/stixxxx-syscfg.txt     |   18 ++
 drivers/mfd/Kconfig                                |   10 ++
 drivers/mfd/Makefile                               |    1 +
 drivers/mfd/stixxxx-syscfg.c                       |  168 ++++++++++++++++++++
 include/linux/mfd/stixxxx-syscfg.h                 |   15 ++
 5 files changed, 212 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
 create mode 100644 drivers/mfd/stixxxx-syscfg.c
 create mode 100644 include/linux/mfd/stixxxx-syscfg.h

diff --git a/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt b/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
new file mode 100644
index 0000000..428c751
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stixxxx-syscfg.txt
@@ -0,0 +1,18 @@
+*STixxxx SYSCFG
+
+- compatible : should be "st,<SOC>-syscfg" like "st,stih415-syscfg"
+			or "st,stih416-syscfg".
+- reg, reg-names, interrupts, interrupt-names	: Standard way to define device
+			resources with names. look in
+			Documentation/devicetree/bindings/resource-names.txt
+- syscfg-range <start size> : Should be syscfg number range for this bank.
+- syscfg-name		    : Should be name of the syscfg, will be used in debugfs.
+
+Example of a SBC_SYSCFG bank node:
+
+syscfg_sbc: syscfg at fe600000{
+	compatible      = "st,stih415-syscfg";
+	reg		= <0xfe600000 0xb4>;
+	syscfg-range	= <0 44>;
+	syscfg-name	= "SYSCFG_SBC";
+};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d54e985..af49b58 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -649,6 +649,16 @@ config MFD_STA2X11
 	select MFD_CORE
 	select REGMAP_MMIO
 
+config MFD_STIXXXX_SYSCFG
+	bool "ST System Configuration Registers(aka syscfg) via regmap"
+	select REGMAP_MMIO
+	help
+	  Select this option to enable accessing STMicroelectronics
+	  System Configuration Registers via standard regmap apis with
+	  lookup helper functions.
+
+	  If unsure, say N.
+
 config MFD_SYSCON
 	bool "System Controller Register R/W Based on Regmap"
 	select REGMAP_MMIO
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 718e94a..c1f6570 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -150,6 +150,7 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
+obj-$(CONFIG_MFD_STIXXXX_SYSCFG)	+= stixxxx-syscfg.o
 obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
 obj-$(CONFIG_MFD_LM3533)	+= lm3533-core.o lm3533-ctrlbank.o
 obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o vexpress-sysreg.o
diff --git a/drivers/mfd/stixxxx-syscfg.c b/drivers/mfd/stixxxx-syscfg.c
new file mode 100644
index 0000000..10ea4e4
--- /dev/null
+++ b/drivers/mfd/stixxxx-syscfg.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Syscfg driver is used to configure various devices like Ethernet,
+ * USB, PCIE, SATA and so on.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/mfd/stixxxx-syscfg.h>
+
+#define DRIVER_NAME "stixxxx-syscfg"
+
+static struct platform_driver syscfg_driver;
+struct syscfg {
+	void __iomem *base;
+	struct regmap *regmap;
+	int	start, end;
+	const char *name;
+	struct device_node *of_node;
+};
+
+static int syscfg_match_name(struct device *dev, void *data)
+{
+	struct syscfg *syscfg = dev_get_drvdata(dev);
+
+	if (syscfg)
+		if (!strcmp(syscfg->name, (const char *)data))
+			return 1;
+	return 0;
+}
+
+struct regmap *syscfg_regmap_lookup_by_name(const char *name)
+{
+	struct syscfg *syscfg;
+	struct device *dev;
+
+	dev = driver_find_device(&syscfg_driver.driver, NULL, (void *)name,
+				 syscfg_match_name);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	syscfg = dev_get_drvdata(dev);
+
+	return syscfg->regmap;
+}
+
+static int syscfg_match_node(struct device *dev, void *data)
+{
+	struct device_node *dn = data;
+
+	return (dev->of_node == dn) ? 1 : 0;
+}
+
+struct regmap *syscfg_node_to_regmap(struct device_node *np)
+{
+	struct syscfg *syscfg;
+	struct device *dev;
+
+	dev = driver_find_device(&syscfg_driver.driver, NULL, np,
+				 syscfg_match_node);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	syscfg = dev_get_drvdata(dev);
+
+	return syscfg->regmap;
+}
+EXPORT_SYMBOL_GPL(syscfg_node_to_regmap);
+
+struct regmap *syscfg_regmap_lookup_by_phandle(struct device_node *np,
+					const char *property)
+{
+	struct device_node *syscfg_np;
+	struct regmap *regmap;
+
+	syscfg_np = of_parse_phandle(np, property, 0);
+	if (!syscfg_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = syscfg_node_to_regmap(syscfg_np);
+	of_node_put(syscfg_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(syscfg_regmap_lookup_by_phandle);
+
+static struct regmap_config syscfg_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static int syscfg_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct syscfg *syscfg;
+	struct resource *res;
+	u32 range[2];
+
+	if (!np)
+		return -EINVAL;
+
+	syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL);
+	if (!syscfg)
+		return -ENOMEM;
+
+	syscfg->of_node = np;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	syscfg->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!syscfg->base) {
+		dev_err(&pdev->dev, "Unable to ioremap registers|\n");
+		return -ENODATA;
+	}
+
+	of_property_read_u32_array(np, "syscfg-range", (u32 *)&range, 2);
+	syscfg->start = range[0];
+	syscfg->end = range[0] + range[1];
+	of_property_read_string(np, "syscfg-name", &syscfg->name);
+
+	syscfg_regmap_config.name = kasprintf(GFP_KERNEL, "%s", syscfg->name);
+	syscfg_regmap_config.max_register = res->end - res->start - 3;
+	syscfg->regmap = devm_regmap_init_mmio(&pdev->dev, syscfg->base,
+					&syscfg_regmap_config);
+	if (IS_ERR(syscfg->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(syscfg->regmap);
+	}
+
+	platform_set_drvdata(pdev, syscfg);
+	dev_info(&pdev->dev,
+		"%s[%d - %d] sucessfully intialized\n",
+		syscfg->name, syscfg->start, syscfg->end);
+	return 0;
+}
+
+static struct of_device_id syscfg_match[] = {
+	{ .compatible = "st,stih415-syscfg", },
+	{ .compatible = "st,stih416-syscfg", },
+	{},
+};
+
+static struct platform_driver syscfg_driver = {
+	.probe		= syscfg_probe,
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(syscfg_match),
+	},
+};
+
+static int __init syscfg_init(void)
+{
+	return platform_driver_register(&syscfg_driver);
+}
+postcore_initcall(syscfg_init);
diff --git a/include/linux/mfd/stixxxx-syscfg.h b/include/linux/mfd/stixxxx-syscfg.h
new file mode 100644
index 0000000..18ed6da7
--- /dev/null
+++ b/include/linux/mfd/stixxxx-syscfg.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ */
+
+#ifndef __LINUX_MFD_STIXXXX_SYSCFG_H
+#define __LINUX_MFD_STIXXXX_SYSCFG_H
+
+struct regmap *syscfg_regmap_lookup_by_phandle(struct device_node *np,
+					const char *property);
+struct regmap *syscfg_regmap_lookup_by_name(const char *name);
+
+#endif /* __LINUX_MFD_STIXXXX_SYSCFG_H */
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:22     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:22 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

This patch add pinctrl support to ST SoCs.

About hardware:
ST Set-Top-Box parts have two blocks called PIO and PIO-mux which handle
pin configurations.

Each multi-function pin is controlled, driven and routed through the PIO
multiplexing block. Each pin supports GPIO functionality (ALT0) and
multiple alternate functions(ALT1 - ALTx) that directly connect the pin
to different hardware blocks. When a pin is in GPIO mode, Output Enable
(OE), Open Drain(OD), and Pull Up (PU) are driven by the related PIO
block. Otherwise the PIO multiplexing block configures these parameters
and retiming the signal.

About driver:
This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
pinconf, pinmux, gpio subsystems. All the pinctrl related config
information can only come from device trees.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 .../bindings/pinctrl/pinctrl-stixxxx.txt           |  116 ++
 drivers/pinctrl/Kconfig                            |   11 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-stixxxx.c                  | 1212 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-stixxxx.h                  |  197 ++++
 5 files changed, 1537 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.h

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
new file mode 100644
index 0000000..ac69dca
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
@@ -0,0 +1,116 @@
+*ST pin controller.
+
+Each multi-function pin is controlled, driven and routed through the
+PIO multiplexing block. Each pin supports GPIO functionality (ALT0)
+and multiple alternate functions(ALT1 - ALTx) that directly connect
+the pin to different hardware blocks.
+
+When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and
+Pull Up (PU) are driven by the related PIO block.
+
+ST pinctrl driver controls PIO multiplexing block and also interacts with
+gpio driver to configure a pin.
+
+Required properties: (PIO multiplexing block)
+- compatible	: should be "st,stixxxx-pinctrl"
+			each subnode should set "st,stixxxx-gpio"
+			as compatible for each gpio-controller bank.
+- gpio-controller : Indicates this device is a GPIO controller
+- #gpio-cells	  : Should be one. The first cell is the pin number.
+- st,retime-in-delay	: Should be array of delays in nsecs.
+- st,retime-out-delay	: Should be array of delays in nsecs.
+- st,retime-pin-mask	: Should be mask to specify which pins can be retimed.
+- st,bank-name		: Should be a name string for this bank.
+- st,syscfg		: phandle of the syscfg node.
+- st,syscfg-offsets	: Should be a 5 cell entry which represent offset of altfunc,
+	output-enable, pull-up , open drain and retime registers in the syscfg bank
+
+Example:
+	pin-controller {
+		compatible = "st,stixxxx-pinctrl", "simple-bus";
+		st,retime-in-delay = <0 500 1000 1500>;
+		st,retime-out-delay = <0 1000 2000 3000>;
+		st,syscfg		= <&syscfg_front>;
+		st,syscfg-offsets	= <0 8 10 12 16>;
+		ranges;
+		PIO0: pinctrl@fe610000 {
+			gpio-controller;
+			#gpio-cells = <1>;
+			compatible = "st,stixxxx-gpio";
+			reg = <0xfe610000 0x100>;
+			st,bank-name  = "PIO0";
+		};
+		...
+		pin-functions nodes follow...
+	};
+
+
+Contents of function subnode node:
+----------------------
+Required properties for pin configuration node:
+- st,function	: Should be alternate function number associated
+		with this set of pins. Use same numbers from datasheet.
+
+- st,pins	: Child node with list of pins with configuration.
+
+Below is the format of how each pin conf should look like.
+
+<bank offset mode rt_type rt_delay rt_clk>
+
+Every PIO is represented with 4-7 parameters depending on retime configuration.
+Each parameter is explained as below.
+
+-bank		: Should be bank phandle to which this PIO belongs.
+-offset		: Offset in the PIO bank.
+-mode		:pin configuration is selected from one of the below values.
+		IN
+		IN_PU
+		OUT
+		BIDIR
+		BIDIR_PU
+
+-rt_type	Retiming Configuration for the pin.
+		Possible retime configuration are:
+
+		-------		-------------
+		value		args
+		-------		-------------
+		NICLK		<delay> <clk>
+		ICLK_IO		<delay> <clk>
+		BYPASS		<delay>
+		DE_IO		<delay> <clk>
+		SE_ICLK_IO	<delay> <clk>
+		SE_NICLK_IO	<delay> <clk>
+
+- delay	is retime delay in pico seconds.
+		Possible values are: refer to retime-in/out-delays
+
+- rt_clk	:clk to be use for retime.
+		Possible values are:
+		CLK_A
+		CLK_B
+		CLK_C
+		CLK_D
+
+Example of mmcclk pin which is a bi-direction pull pu with retime config
+as non inverted clock retimed with CLK_B and delay of 0 pico seconds:
+
+pin-controller {
+	...
+	mmc0 {
+		pinctrl_mmc: mmc {
+			st,function = <ALT4>;
+			st,pins {
+				mmcclk = <&PIO13 4 BIDIR_PU NICLK  0  CLK_B>;
+				...
+			};
+		};
+	...
+	};
+};
+
+sdhci0:sdhci@fe810000{
+	...
+	pinctrl-names = "default";
+	pinctrl-0	= <&pinctrl_mmc>;
+};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f66924..0c040a3 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -169,6 +169,17 @@ config PINCTRL_SUNXI
 	select PINMUX
 	select GENERIC_PINCONF
 
+config PINCTRL_STIXXXX
+	bool "ST Microelectronics pin controller driver for STixxxx SoCs"
+	select PINMUX
+	select PINCONF
+	help
+	  Say yes here to support pinctrl interface on STixxxx SOCs.
+	  This driver is used to control both PIO block and PIO-mux
+	  block to configure a pin.
+
+	  If unsure, say N.
+
 config PINCTRL_TEGRA
 	bool
 	select PINMUX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 9bdaeb8..0e035bb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o
 obj-$(CONFIG_PINCTRL_S3C64XX)	+= pinctrl-s3c64xx.o
 obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
+obj-$(CONFIG_PINCTRL_STIXXXX) 	+= pinctrl-stixxxx.o
 
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh-pfc/
diff --git a/drivers/pinctrl/pinctrl-stixxxx.c b/drivers/pinctrl/pinctrl-stixxxx.c
new file mode 100644
index 0000000..da4e3d7
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stixxxx.c
@@ -0,0 +1,1212 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Authors:
+ *	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/stixxxx-syscfg.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/platform_device.h>
+#include "core.h"
+#include "pinctrl-stixxxx.h"
+
+struct stixxxx_pinconf {
+	int		pin;
+	const char	*name;
+	unsigned long	config;
+};
+
+struct stixxxx_pmx_func {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct stixxxx_pctl_group {
+	const char		*name;
+	unsigned int		*pins;
+	unsigned		npins;
+	int			altfunc;
+	struct stixxxx_pinconf	*pin_conf;
+};
+
+#define to_stixxxx_gpio_port(chip) \
+		container_of(chip, struct stixxxx_gpio_port, gpio_chip)
+
+struct stixxxx_gpio_port {
+	struct gpio_chip	gpio_chip;
+	struct pinctrl_gpio_range range;
+	void __iomem		*base;
+	struct device_node	*of_node;
+	const char		*bank_name;
+};
+
+static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];
+
+struct stixxxx_pinctrl {
+	struct device			*dev;
+	struct pinctrl_dev		*pctl;
+	int				nbanks;
+	struct stixxxx_pmx_func		*functions;
+	int				nfunctions;
+	struct stixxxx_pctl_group	*groups;
+	int				ngroups;
+	struct stixxxx_pio_control	*pio_controls;
+	struct pinctrl_gpio_range	**gpio_ranges;
+	struct regmap			*regmap;
+};
+
+/* Low level functions.. */
+static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
+				int pin_id, unsigned long config)
+{
+	struct regmap_field *output_enable;
+	struct regmap_field *pull_up;
+	struct regmap_field *open_drain;
+	unsigned int oe_value, pu_value, od_value;
+	unsigned long mask;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	output_enable = pc->oe;
+	pull_up = pc->pu;
+	open_drain = pc->od;
+
+	mask = BIT(pin);
+
+	regmap_field_read(output_enable, &oe_value);
+	regmap_field_read(pull_up, &pu_value);
+	regmap_field_read(open_drain, &od_value);
+
+	/* Clear old values */
+	oe_value &= ~mask;
+	pu_value &= ~mask;
+	od_value &= ~mask;
+
+	if (config & STIXXXX_PINCONF_OE)
+		oe_value |= mask;
+	if (config & STIXXXX_PINCONF_PU)
+		pu_value |= mask;
+	if (config & STIXXXX_PINCONF_OD)
+		od_value |= mask;
+
+	regmap_field_write(output_enable, oe_value);
+	regmap_field_write(pull_up, pu_value);
+	regmap_field_write(open_drain, od_value);
+}
+
+static void stixxxx_pctl_set_function(struct stixxxx_pio_control *pc,
+				int pin_id, int function)
+{
+	struct regmap_field *selector;
+	int offset;
+	unsigned int val;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	selector = pc->alt;
+	offset = pin * 4;
+	regmap_field_read(selector, &val);
+	val &= ~(0xf << offset);
+	val |= function << offset;
+	regmap_field_write(selector, val);
+}
+
+static unsigned long stixxxx_pinconf_delay_to_bit(unsigned int delay,
+		const struct stixxxx_retime_params *rt_params,
+		unsigned long config)
+{
+	unsigned int *delay_times;
+	int num_delay_times, i, closest_index = -1;
+	unsigned int closest_divergence = UINT_MAX;
+
+	if (STIXXXX_PINCONF_UNPACK_OE(config)) {
+		delay_times = rt_params->delay_times_out;
+		num_delay_times = rt_params->num_delay_times_out;
+	} else {
+		delay_times = rt_params->delay_times_in;
+		num_delay_times = rt_params->num_delay_times_in;
+	}
+
+	for (i = 0; i < num_delay_times; i++) {
+		unsigned int divergence = abs(delay - delay_times[i]);
+
+		if (divergence == 0)
+			return i;
+
+		if (divergence < closest_divergence) {
+			closest_divergence = divergence;
+			closest_index = i;
+		}
+	}
+
+	pr_warn("Attempt to set delay %d, closest available %d\n",
+	     delay, delay_times[closest_index]);
+
+	return closest_index;
+}
+
+static unsigned long stixxxx_pinconf_bit_to_delay(unsigned int index,
+		const struct stixxxx_retime_params *rt_params,
+		unsigned long output)
+{
+	unsigned int *delay_times;
+	int num_delay_times;
+
+	if (output) {
+		delay_times = rt_params->delay_times_out;
+		num_delay_times = rt_params->num_delay_times_out;
+	} else {
+		delay_times = rt_params->delay_times_in;
+		num_delay_times = rt_params->num_delay_times_in;
+	}
+
+	if (index < num_delay_times) {
+		return delay_times[index];
+	} else {
+		pr_warn("Delay not found in/out delay list\n");
+		return 0;
+	}
+}
+
+static void stixxxx_pinconf_set_retime_packed(
+		struct stixxxx_pio_control *pc,
+		unsigned long config, int pin)
+{
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
+	struct regmap_field **regs;
+	unsigned int values[2];
+	unsigned long mask;
+	int i, j;
+	int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
+	int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
+	int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
+	int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
+	int retime = STIXXXX_PINCONF_UNPACK_RT(config);
+	unsigned long delay = stixxxx_pinconf_delay_to_bit(
+			STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
+			pc->rt_params, config);
+
+	unsigned long rt_cfg =
+		((clk		& 1) << offset->clk1notclk0_offset) |
+		((clknotdata	& 1) << offset->clknotdata_offset) |
+		((delay		& 1) << offset->delay_lsb_offset) |
+		(((delay >> 1)  & 1) << offset->delay_msb_offset) |
+		((double_edge	& 1) << offset->double_edge_offset) |
+		((invertclk	& 1) << offset->invertclk_offset) |
+		((retime	& 1) << offset->retime_offset);
+
+	regs = pc->retiming;
+	regmap_field_read(regs[0], &values[0]);
+	regmap_field_read(regs[1], &values[1]);
+
+	for (i = 0; i < 2; i++) {
+		mask = BIT(pin);
+		for (j = 0; j < 4; j++) {
+			if (rt_cfg & 1)
+				values[i] |= mask;
+			else
+				values[i] &= ~mask;
+			mask <<= 8;
+			rt_cfg >>= 1;
+		}
+	}
+
+	regmap_field_write(regs[0], values[0]);
+	regmap_field_write(regs[1], values[1]);
+}
+
+static void stixxxx_pinconf_set_retime_dedicated(
+	struct stixxxx_pio_control *pc,
+	unsigned long config, int pin)
+{
+	struct regmap_field *reg;
+	int input = STIXXXX_PINCONF_UNPACK_OE(config) ? 0 : 1;
+	int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
+	int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
+	int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
+	int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
+	int retime = STIXXXX_PINCONF_UNPACK_RT(config);
+	unsigned long delay = stixxxx_pinconf_delay_to_bit(
+			STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
+			pc->rt_params, config);
+
+	unsigned long retime_config =
+		((clk		& 0x3) << 0) |
+		((clknotdata	& 0x1) << 2) |
+		((delay		& 0xf) << 3) |
+		((input		& 0x1) << 7) |
+		((double_edge	& 0x1) << 8) |
+		((invertclk	& 0x1) << 9) |
+		((retime	& 0x1) << 10);
+
+	reg = pc->retiming[pin];
+	regmap_field_write(reg, retime_config);
+}
+
+static void stixxxx_pinconf_get_direction(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long *config)
+{
+	unsigned int oe_value, pu_value, od_value;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	regmap_field_read(pc->oe, &oe_value);
+	regmap_field_read(pc->pu, &pu_value);
+	regmap_field_read(pc->od, &od_value);
+
+	oe_value = (oe_value >> pin) & 1;
+	pu_value = (pu_value >> pin) & 1;
+	od_value = (od_value >> pin) & 1;
+
+	STIXXXX_PINCONF_PACK_OE(*config, oe_value);
+	STIXXXX_PINCONF_PACK_PU(*config, pu_value);
+	STIXXXX_PINCONF_PACK_OD(*config, od_value);
+}
+
+static int stixxxx_pinconf_get_retime_packed(
+		struct stixxxx_pio_control *pc,
+		int pin, unsigned long *config)
+{
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
+	unsigned long delay_bits, delay, rt_reduced;
+	unsigned int rt_value[2];
+	int i, j;
+	int output = STIXXXX_PINCONF_UNPACK_OE(*config);
+
+	regmap_field_read(pc->retiming[0], &rt_value[0]);
+	regmap_field_read(pc->retiming[1], &rt_value[1]);
+
+	rt_reduced = 0;
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 4; j++) {
+			if (rt_value[i] & (1<<((8*j)+pin)))
+				rt_reduced |= 1 << ((i*4)+j);
+		}
+	}
+
+	STIXXXX_PINCONF_PACK_RT(*config,
+			(rt_reduced >> offset->retime_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_CLK(*config,
+			(rt_reduced >> offset->clk1notclk0_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
+			(rt_reduced >> offset->clknotdata_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
+			(rt_reduced >> offset->double_edge_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
+			(rt_reduced >> offset->invertclk_offset) & 1);
+
+	delay_bits =  (((rt_reduced >> offset->delay_msb_offset) & 1)<<1) |
+			((rt_reduced >> offset->delay_lsb_offset) & 1);
+	delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
+	STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
+	return 0;
+}
+
+static int stixxxx_pinconf_get_retime_dedicated(
+		struct stixxxx_pio_control *pc,
+		int pin, unsigned long *config)
+{
+	unsigned int value;
+	unsigned long delay_bits, delay;
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	int output = STIXXXX_PINCONF_UNPACK_OE(*config);
+
+	regmap_field_read(pc->retiming[pin], &value);
+	STIXXXX_PINCONF_PACK_RT_CLK(*config, ((value >> 0) & 0x3));
+	STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config, ((value >> 2) & 0x1));
+	delay_bits = ((value >> 3) & 0xf);
+	delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
+	STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
+	STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config, ((value >> 8) & 0x1));
+	STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config, ((value >> 9) & 0x1));
+	STIXXXX_PINCONF_PACK_RT(*config, ((value >> 10) & 0x1));
+
+	return 0;
+}
+
+/* GPIO related functions */
+
+static inline void __stixxxx_gpio_set(struct stixxxx_gpio_port *port,
+	unsigned offset, int value)
+{
+	if (value)
+		writel(BIT(offset), port->base + REG_PIO_SET_POUT);
+	else
+		writel(BIT(offset), port->base + REG_PIO_CLR_POUT);
+}
+
+static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
+{
+	int port_num = stixxxx_gpio_port(gpio);
+	int offset = stixxxx_gpio_pin(gpio);
+	struct stixxxx_gpio_port *port  = gpio_ports[port_num];
+	int i = 0;
+
+	for (i = 0; i <= 2; i++) {
+		if (direction & BIT(i))
+			writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
+		else
+			writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
+	}
+}
+
+static int stixxxx_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void stixxxx_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+
+	return (readl(port->base + REG_PIO_PIN) >> offset) & 1;
+}
+
+static void stixxxx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+	__stixxxx_gpio_set(port, offset, value);
+}
+
+static int stixxxx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_gpio_direction_input(chip->base + offset);
+	return 0;
+}
+
+static int stixxxx_gpio_direction_output(struct gpio_chip *chip,
+	unsigned offset, int value)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+
+	__stixxxx_gpio_set(port, offset, value);
+	pinctrl_gpio_direction_output(chip->base + offset);
+
+	return 0;
+}
+
+static int stixxxx_gpio_xlate(struct gpio_chip *gc,
+			const struct of_phandle_args *gpiospec, u32 *flags)
+{
+	if (WARN_ON(gc->of_gpio_n_cells < 1))
+		return -EINVAL;
+
+	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
+		return -EINVAL;
+
+	if (gpiospec->args[0] > gc->ngpio)
+		return -EINVAL;
+
+	return gpiospec->args[0];
+}
+
+/* Pinctrl Groups */
+static int stixxxx_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *stixxxx_pctl_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int stixxxx_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+	unsigned selector, const unsigned **pins, unsigned *npins)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static const inline struct stixxxx_pctl_group *stixxxx_pctl_find_group_by_name(
+	const struct stixxxx_pinctrl *info, const char *name)
+{
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name))
+			return &info->groups[i];
+	}
+
+	return NULL;
+}
+
+static int stixxxx_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
+	struct device_node *np, struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct stixxxx_pctl_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num, i;
+
+	grp = stixxxx_pctl_find_group_by_name(info, np->name);
+	if (!grp) {
+		dev_err(info->dev, "unable to find group for node %s\n",
+			np->name);
+		return -EINVAL;
+	}
+
+	map_num = grp->npins + 1;
+	new_map = devm_kzalloc(pctldev->dev,
+				sizeof(*new_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	*map = new_map;
+	*num_maps = map_num;
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	/* create config map per pin */
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin =
+				pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = &grp->pin_conf[i].config;
+		new_map[i].data.configs.num_configs = 1;
+	}
+	dev_info(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, grp->name, map_num);
+
+	return 0;
+}
+
+static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
+				struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static struct pinctrl_ops stixxxx_pctlops = {
+	.get_groups_count	= stixxxx_pctl_get_groups_count,
+	.get_group_pins		= stixxxx_pctl_get_group_pins,
+	.get_group_name		= stixxxx_pctl_get_group_name,
+	.dt_node_to_map		= stixxxx_pctl_dt_node_to_map,
+	.dt_free_map		= stixxxx_pctl_dt_free_map,
+};
+
+/* Pinmux */
+static int stixxxx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+const char *stixxxx_pmx_get_fname(struct pinctrl_dev *pctldev,
+	unsigned selector)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int stixxxx_pmx_get_groups(struct pinctrl_dev *pctldev,
+	unsigned selector, const char * const **grps, unsigned * const ngrps)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	*grps = info->functions[selector].groups;
+	*ngrps = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static struct stixxxx_pio_control *stixxxx_get_pio_control(
+			struct stixxxx_pinctrl *info, int pin_id)
+{
+	int index = stixxxx_gpio_port(pin_id) - info->gpio_ranges[0]->id;
+	return &info->pio_controls[index];
+}
+
+static int stixxxx_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
+		unsigned group)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pinconf *conf = info->groups[group].pin_conf;
+	struct stixxxx_pio_control *pc;
+	int i;
+
+	for (i = 0; i < info->groups[group].npins; i++) {
+		pc = stixxxx_get_pio_control(info, conf[i].pin);
+		stixxxx_pctl_set_function(pc, conf[i].pin,
+					info->groups[group].altfunc);
+	}
+
+	return 0;
+}
+
+static void stixxxx_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
+		unsigned group)
+{
+}
+
+static int stixxxx_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range, unsigned gpio,
+			bool input)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	int offset = range->id - info->gpio_ranges[0]->id;
+	struct stixxxx_pio_control *pc = &info->pio_controls[offset];
+	/*
+	 * When a PIO port is used in its primary function mode (altfunc = 0)
+	 * Output Enable (OE), Open Drain(OD), and Pull Up (PU)
+	 * for the primary PIO functions are driven by the related PIO block
+	 */
+	stixxxx_pctl_set_function(pc, gpio, 0);
+	stixxxx_gpio_direction(gpio, input ?
+		STIXXXX_GPIO_DIRECTION_IN : STIXXXX_GPIO_DIRECTION_OUT);
+
+	return 0;
+}
+
+static struct pinmux_ops stixxxx_pmxops = {
+	.get_functions_count	= stixxxx_pmx_get_funcs_count,
+	.get_function_name	= stixxxx_pmx_get_fname,
+	.get_function_groups	= stixxxx_pmx_get_groups,
+	.enable			= stixxxx_pmx_enable,
+	.disable		= stixxxx_pmx_disable,
+	.gpio_set_direction	= stixxxx_pmx_set_gpio_direction,
+};
+
+/* Pinconf  */
+static void stixxxx_pinconf_get_retime(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long *config)
+{
+	int pin = stixxxx_gpio_pin(pin_id);
+	if (pc->rt_style == stixxxx_retime_style_packed)
+		stixxxx_pinconf_get_retime_packed(pc, pin, config);
+	else if (pc->rt_style == stixxxx_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			stixxxx_pinconf_get_retime_dedicated(pc, pin, config);
+}
+
+static void stixxxx_pinconf_set_retime(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long config)
+{
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	if (pc->rt_style == stixxxx_retime_style_packed)
+		stixxxx_pinconf_set_retime_packed(pc, config, pin);
+	else if (pc->rt_style == stixxxx_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			stixxxx_pinconf_set_retime_dedicated(pc, config, pin);
+}
+
+static int stixxxx_pinconf_set(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long config)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pio_control *pc = stixxxx_get_pio_control(info, pin_id);
+
+	stixxxx_pinconf_set_direction(pc, pin_id, config);
+	stixxxx_pinconf_set_retime(pc, pin_id, config);
+	return 0;
+}
+
+static int stixxxx_pinconf_get(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long *config)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pio_control *pc = stixxxx_get_pio_control(info, pin_id);
+
+	*config = 0;
+	stixxxx_pinconf_get_direction(pc, pin_id, config);
+	stixxxx_pinconf_get_retime(pc, pin_id, config);
+
+	return 0;
+}
+
+static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				   struct seq_file *s, unsigned pin_id)
+{
+	unsigned long config;
+	stixxxx_pinconf_get(pctldev, pin_id, &config);
+
+	seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
+		"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
+		"de:%ld,rt-clk:%ld,rt-delay:%ld]",
+		STIXXXX_PINCONF_UNPACK_OE(config),
+		STIXXXX_PINCONF_UNPACK_PU(config),
+		STIXXXX_PINCONF_UNPACK_OD(config),
+		STIXXXX_PINCONF_UNPACK_RT(config),
+		STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
+		STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
+		STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
+		STIXXXX_PINCONF_UNPACK_RT_CLK(config),
+		STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
+}
+
+static struct pinconf_ops stixxxx_confops = {
+	.pin_config_get		= stixxxx_pinconf_get,
+	.pin_config_set		= stixxxx_pinconf_set,
+	.pin_config_dbg_show	= stixxxx_pinconf_dbg_show,
+};
+
+static int stixxxx_pinconf_dt_parse_rt_params(struct stixxxx_pinctrl *info,
+	struct device_node *np,	struct stixxxx_retime_params *params)
+{
+	struct stixxxx_retime_offset *rt_offset;
+	int delay_count = 0;
+	int len;
+	if (of_find_property(np, "st,retime-in-delay", &len))
+		delay_count = len/sizeof(__be32);
+	else
+		dev_err(info->dev, "No delays found\n");
+
+	params->num_delay_times_out = delay_count;
+	params->num_delay_times_in = delay_count;
+	params->delay_times_in = devm_kzalloc(info->dev,
+				sizeof(u32) * delay_count, GFP_KERNEL);
+	params->delay_times_out = devm_kzalloc(info->dev,
+				sizeof(u32) * delay_count, GFP_KERNEL);
+
+	if (!params->delay_times_in || !params->delay_times_out)
+		return -ENOMEM;
+
+	of_property_read_u32_array(np, "st,retime-in-delay",
+				(u32 *)params->delay_times_in, delay_count);
+	of_property_read_u32_array(np, "st,retime-out-delay",
+				(u32 *)params->delay_times_out, delay_count);
+
+	if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
+		rt_offset = devm_kzalloc(info->dev,
+			sizeof(*rt_offset), GFP_KERNEL);
+
+		if (!rt_offset)
+			return -ENOMEM;
+
+		rt_offset->clk1notclk0_offset = 0;
+		rt_offset->delay_lsb_offset = 2;
+		rt_offset->delay_msb_offset = 3;
+		rt_offset->invertclk_offset = 4;
+		rt_offset->retime_offset = 5;
+		rt_offset->clknotdata_offset = 6;
+		rt_offset->double_edge_offset = 7;
+		params->retime_offset = rt_offset;
+	}
+
+	return 0;
+}
+
+static const char *gpio_compat = "st,stixxxx-gpio";
+
+static void stixxxx_pctl_dt_child_count(struct stixxxx_pinctrl *info,
+				     struct device_node *np)
+{
+	struct device_node *child;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			info->nbanks++;
+		} else {
+			info->nfunctions++;
+			info->ngroups += of_get_child_count(child);
+		}
+	}
+}
+
+static int stixxxx_pctl_dt_get_retime_conf(struct stixxxx_pinctrl *info,
+	struct stixxxx_pio_control *pc, u32 *syscfg)
+{
+	unsigned int j;
+	int rt_syscfg = *syscfg;
+	struct device_node *np = info->dev->of_node;
+
+	if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
+		pc->rt_style = stixxxx_retime_style_packed;
+		for (j = 0; j < 2; j++) {
+			struct reg_field rt_reg =
+					REG_FIELD(4 * rt_syscfg ++, 0, 31);
+			pc->retiming[j] = devm_regmap_field_alloc(info->dev,
+						info->regmap, rt_reg);
+			if (IS_ERR(pc->retiming[j]))
+				return -ENODATA;
+		}
+	} else if (of_device_is_compatible(np, "st,stih416-pinctrl")) {
+		pc->rt_style = stixxxx_retime_style_dedicated;
+		for (j = 0; j < 8; j++) {
+			if ((1<<j) & pc->rt_pin_mask) {
+				struct reg_field rt_reg =
+					REG_FIELD(4 * rt_syscfg ++, 0, 31);
+				pc->retiming[j] = devm_regmap_field_alloc(
+					info->dev, info->regmap, rt_reg);
+				if (IS_ERR(pc->retiming[j]))
+					return -ENODATA;
+			}
+		}
+	} else {
+		pc->rt_style = stixxxx_retime_style_none;
+	}
+
+	*syscfg = rt_syscfg;
+	return 0;
+}
+
+static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
+			struct device_node *np)
+{
+	struct stixxxx_pio_control *pc;
+	struct stixxxx_retime_params *rt_params;
+	struct device *dev = info->dev;
+	struct regmap *regmap;
+	unsigned int i = 0;
+	struct device_node *child = NULL;
+	u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
+	u32 syscfg_offsets[5];
+	u32 msb, lsb;
+
+	pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
+	rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
+
+	if (!pc || !rt_params)
+		return -ENOMEM;
+
+	regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (!regmap) {
+		dev_err(dev, "No syscfg phandle specified\n");
+		return -ENOMEM;
+	}
+	info->regmap = regmap;
+	info->pio_controls = pc;
+	if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
+		return -ENOMEM;
+
+	if (of_property_read_u32_array(np, "st,syscfg-offsets",
+				syscfg_offsets, 5)) {
+		dev_err(dev, "Syscfg offsets not found\n");
+		return -EINVAL;
+	}
+	alt_syscfg = syscfg_offsets[0];
+	oe_syscfg = syscfg_offsets[1];
+	pu_syscfg = syscfg_offsets[2];
+	od_syscfg = syscfg_offsets[3];
+	rt_syscfg = syscfg_offsets[4];
+
+	lsb = 0;
+	msb = 7;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			struct reg_field alt_reg =
+					REG_FIELD(4 * alt_syscfg++, 0, 31);
+			struct reg_field oe_reg =
+					REG_FIELD(4 * oe_syscfg, lsb, msb);
+			struct reg_field pu_reg =
+					REG_FIELD(4 * pu_syscfg, lsb, msb);
+			struct reg_field od_reg =
+					REG_FIELD(4 * od_syscfg, lsb, msb);
+			pc[i].rt_params = rt_params;
+
+			pc[i].alt = devm_regmap_field_alloc(dev,
+							regmap, alt_reg);
+			pc[i].oe = devm_regmap_field_alloc(dev,
+							regmap, oe_reg);
+			pc[i].pu = devm_regmap_field_alloc(dev,
+							regmap, pu_reg);
+			pc[i].od = devm_regmap_field_alloc(dev,
+							regmap, od_reg);
+
+			if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
+				|| IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
+				goto failed;
+
+			of_property_read_u32(child, "st,retime-pin-mask",
+						&pc[i].rt_pin_mask);
+
+			stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
+							&rt_syscfg);
+			i++;
+			if (msb  == 31) {
+				oe_syscfg++;
+				pu_syscfg++;
+				od_syscfg++;
+				lsb = 0;
+				msb = 7;
+			} else {
+				lsb += 8;
+				msb += 8;
+			}
+		}
+	}
+
+	return 0;
+failed:
+	dev_err(dev, "Unable to allocate syscfgs\n");
+	return -ENOMEM;
+}
+
+#define OF_GPIO_ARGS_MIN	(3)
+/*
+ * Each pin is represented in of the below forms.
+ * <bank offset direction func rt_type rt_delay rt_clk>
+ */
+static int stixxxx_pctl_dt_parse_groups(struct device_node *np,
+	struct stixxxx_pctl_group *grp, struct stixxxx_pinctrl *info, int idx)
+{
+	/* bank pad direction val altfunction */
+	const __be32 *list;
+	struct property *pp;
+	struct stixxxx_pinconf *conf;
+	phandle phandle;
+	struct device_node *pins;
+	u32 pin;
+	int i = 0, npins = 0, nr_props;
+
+	pins = of_get_child_by_name(np, "st,pins");
+	if (!pins)
+		return -ENODATA;
+
+	for_each_property_of_node(pins, pp) {
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name"))
+			continue;
+
+		if (pp  && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
+			npins++;
+		} else {
+			pr_warn("Invalid st,pins in %s node\n", np->name);
+			return -EINVAL;
+		}
+	}
+
+	grp->npins = npins;
+	grp->name = np->name;
+	grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL);
+	grp->pin_conf = devm_kzalloc(info->dev,
+					npins * sizeof(*conf), GFP_KERNEL);
+	of_property_read_u32(np, "st,function", &grp->altfunc);
+
+	if (!grp->pins || !grp->pin_conf)
+		return -ENOMEM;
+
+	/* <bank offset direction rt_type rt_delay rt_clk> */
+	for_each_property_of_node(pins, pp) {
+		if (!strcmp(pp->name, "name"))
+			continue;
+		nr_props = pp->length/sizeof(u32);
+		list = pp->value;
+		conf = &grp->pin_conf[i];
+
+		/* bank & offset */
+		phandle = be32_to_cpup(list++);
+		pin = be32_to_cpup(list++);
+		conf->pin = of_get_named_gpio(pins, pp->name, 0);
+		conf->name = pp->name;
+		grp->pins[i] = conf->pin;
+
+		conf->config = 0;
+		/* direction */
+		conf->config |= be32_to_cpup(list++);
+		/* rt_type rt_delay rt_clk */
+		if (nr_props >= OF_GPIO_ARGS_MIN + 2) {
+			/* rt_type */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_delay */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_clk */
+			if (nr_props > OF_GPIO_ARGS_MIN + 2)
+				conf->config |= be32_to_cpup(list++);
+		}
+		i++;
+	}
+	of_node_put(pins);
+
+	return 0;
+}
+
+static int stixxxx_pctl_parse_functions(struct device_node *np,
+			struct stixxxx_pinctrl *info, u32 index, int *grp_index)
+{
+	struct device_node *child;
+	struct stixxxx_pmx_func *func;
+	struct stixxxx_pctl_group *grp;
+	int ret, i;
+
+	func = &info->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups <= 0) {
+		dev_err(info->dev, "No groups defined\n");
+		return -EINVAL;
+	}
+	func->groups = devm_kzalloc(info->dev,
+			func->ngroups * sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[*grp_index];
+		*grp_index += 1;
+		ret = stixxxx_pctl_dt_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+	dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n",
+				index, func->name, func->ngroups);
+
+	return 0;
+}
+
+static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
+{
+	int i;
+	for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
+		if (gpio_ports[i]->of_node == np)
+			return &gpio_ports[i]->range;
+
+	return NULL;
+}
+
+static int stixxxx_pctl_probe_dt(struct platform_device *pdev,
+	struct pinctrl_desc *pctl_desc, struct stixxxx_pinctrl *info)
+{
+	int ret = 0;
+	int i = 0, j = 0, k = 0, bank;
+	struct pinctrl_pin_desc *pdesc;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	int grp_index = 0;
+
+	stixxxx_pctl_dt_child_count(info, np);
+	if (info->nbanks < 1) {
+		dev_err(&pdev->dev, "you need atleast one gpio bank\n");
+		return -EINVAL;
+	}
+
+	ret = stixxxx_pctl_dt_init(info, np);
+	if (ret)
+		return ret;
+
+	dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks);
+	dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+	dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups);
+	info->functions = devm_kzalloc(&pdev->dev,
+		info->nfunctions * sizeof(*info->functions), GFP_KERNEL);
+
+	info->groups = devm_kzalloc(&pdev->dev,
+		info->ngroups * sizeof(*info->groups) ,	GFP_KERNEL);
+
+	info->gpio_ranges = devm_kzalloc(&pdev->dev,
+		info->nbanks * sizeof(*info->gpio_ranges), GFP_KERNEL);
+
+	if (!info->functions || !info->groups)
+		return -ENOMEM;
+
+	pctl_desc->npins = info->nbanks * STIXXXX_GPIO_PINS_PER_PORT;
+	pdesc =	devm_kzalloc(&pdev->dev,
+			sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!pdesc)
+		return -ENOMEM;
+
+	pctl_desc->pins = pdesc;
+
+	bank = 0;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			info->gpio_ranges[bank] = find_gpio_range(child);
+			k = info->gpio_ranges[bank]->pin_base;
+			for (j = 0; j < STIXXXX_GPIO_PINS_PER_PORT; j++, k++) {
+				const char *port_name = NULL;
+				pdesc->number = k;
+				of_property_read_string(child, "st,bank-name",
+							&port_name);
+				pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]",
+							port_name ? : "PIO",
+							port_name ? j : k);
+				pdesc++;
+			}
+			bank++;
+		} else {
+			ret = stixxxx_pctl_parse_functions(child, info,
+							i++, &grp_index);
+			if (ret) {
+				dev_err(&pdev->dev, "No functions found.\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int stixxxx_pctl_probe(struct platform_device *pdev)
+{
+	struct stixxxx_pinctrl *info;
+	struct pinctrl_desc *pctl_desc;
+	int ret, i;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "device node not found.\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = &pdev->dev;
+	platform_set_drvdata(pdev, info);
+	ret = stixxxx_pctl_probe_dt(pdev, pctl_desc, info);
+	if (ret)
+		return ret;
+
+	pctl_desc->owner	= THIS_MODULE,
+	pctl_desc->pctlops	= &stixxxx_pctlops,
+	pctl_desc->pmxops	= &stixxxx_pmxops,
+	pctl_desc->confops	= &stixxxx_confops,
+	pctl_desc->name		= dev_name(&pdev->dev);
+
+	info->pctl = pinctrl_register(pctl_desc, &pdev->dev, info);
+	if (IS_ERR(info->pctl)) {
+		dev_err(&pdev->dev, "Failed pinctrl registration\n");
+		return PTR_ERR(info->pctl);
+	}
+
+	for (i = 0; i < info->nbanks; i++)
+		pinctrl_add_gpio_range(info->pctl, info->gpio_ranges[i]);
+
+	return 0;
+}
+
+static struct gpio_chip stixxxx_gpio_template = {
+	.request		= stixxxx_gpio_request,
+	.free			= stixxxx_gpio_free,
+	.get			= stixxxx_gpio_get,
+	.set			= stixxxx_gpio_set,
+	.direction_input	= stixxxx_gpio_direction_input,
+	.direction_output	= stixxxx_gpio_direction_output,
+	.ngpio			= STIXXXX_GPIO_PINS_PER_PORT,
+	.of_gpio_n_cells	= 1,
+	.of_xlate		= stixxxx_gpio_xlate,
+};
+
+static int stixxxx_gpio_probe(struct platform_device *pdev)
+{
+	struct stixxxx_gpio_port *port;
+	struct pinctrl_gpio_range *range;
+	struct device_node *np  = pdev->dev.of_node;
+	int port_num = of_alias_get_id(np, "gpio");
+	struct resource *res;
+	int err;
+
+	port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	port->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!port->base) {
+		dev_err(&pdev->dev, "Can't get IO memory mapping!\n");
+		return -ENODEV;
+	}
+
+	of_property_read_string(np, "st,bank-name", &port->bank_name);
+	port->of_node = np;
+
+	port->gpio_chip = stixxxx_gpio_template;
+	port->gpio_chip.base = port_num * STIXXXX_GPIO_PINS_PER_PORT;
+	port->gpio_chip.ngpio = STIXXXX_GPIO_PINS_PER_PORT;
+	port->gpio_chip.of_node = np;
+	port->gpio_chip.label = dev_name(&pdev->dev);
+
+	dev_set_drvdata(&pdev->dev, port);
+	range = &port->range;
+	range->name = port->gpio_chip.label;
+	range->id = port_num;
+	range->pin_base = range->base = range->id * STIXXXX_GPIO_PINS_PER_PORT;
+	range->npins = port->gpio_chip.ngpio;
+	range->gc = &port->gpio_chip;
+	gpio_ports[port_num] = port;
+	err  = gpiochip_add(&port->gpio_chip);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to add gpiochip(%d)!\n", port_num);
+		return err;
+	}
+	dev_info(&pdev->dev, "gpioport[%s] Added as bank%d\n",
+				port->bank_name, port_num);
+	return 0;
+}
+
+static struct of_device_id stixxxx_gpio_of_match[] = {
+	{ .compatible = "st,stixxxx-gpio", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver stixxxx_gpio_driver = {
+	.driver = {
+		.name = "st-gpio",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(stixxxx_gpio_of_match),
+	},
+	.probe = stixxxx_gpio_probe,
+};
+
+static struct of_device_id stixxxx_pctl_of_match[] = {
+	{ .compatible = "st,stixxxx-pinctrl",},
+	{ .compatible = "st,stih415-pinctrl",},
+	{ .compatible = "st,stih416-pinctrl",},
+	{ /* sentinel */ }
+};
+
+static struct platform_driver stixxxx_pctl_driver = {
+	.driver = {
+		.name = "st-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(stixxxx_pctl_of_match),
+	},
+	.probe = stixxxx_pctl_probe,
+};
+
+static int __init stixxxx_pctl_init(void)
+{
+	int ret = platform_driver_register(&stixxxx_gpio_driver);
+	if (ret)
+		return ret;
+	return platform_driver_register(&stixxxx_pctl_driver);
+}
+arch_initcall(stixxxx_pctl_init);
diff --git a/drivers/pinctrl/pinctrl-stixxxx.h b/drivers/pinctrl/pinctrl-stixxxx.h
new file mode 100644
index 0000000..e88ab09
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stixxxx.h
@@ -0,0 +1,197 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Authors:
+ *	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
+#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
+
+enum stixxxx_retime_style {
+	stixxxx_retime_style_none,
+	stixxxx_retime_style_packed,
+	stixxxx_retime_style_dedicated,
+};
+
+/* Byte positions in 2 syscon words, starts from 0 */
+struct stixxxx_retime_offset {
+	int retime_offset;
+	int clk1notclk0_offset;
+	int clknotdata_offset;
+	int double_edge_offset;
+	int invertclk_offset;
+	int delay_lsb_offset;
+	int delay_msb_offset;
+};
+
+struct stixxxx_retime_params {
+	const struct stixxxx_retime_offset *retime_offset;
+	unsigned int *delay_times_in;
+	int num_delay_times_in;
+	unsigned int *delay_times_out;
+	int num_delay_times_out;
+};
+
+struct stixxxx_pio_control {
+	enum stixxxx_retime_style rt_style;
+	u32 rt_pin_mask;
+	const struct stixxxx_retime_params *rt_params;
+	struct regmap_field *alt;
+	struct regmap_field *oe, *pu, *od;
+	struct regmap_field *retiming[8];
+};
+
+/* PIO Block registers */
+/* PIO output */
+#define REG_PIO_POUT			0x00
+/* Set bits of POUT */
+#define REG_PIO_SET_POUT		0x04
+/* Clear bits of POUT */
+#define REG_PIO_CLR_POUT		0x08
+/* PIO input */
+#define REG_PIO_PIN			0x10
+/* PIO configuration */
+#define REG_PIO_PC(n)			(0x20 + (n) * 0x10)
+/* Set bits of PC[2:0] */
+#define REG_PIO_SET_PC(n)		(0x24 + (n) * 0x10)
+/* Clear bits of PC[2:0] */
+#define REG_PIO_CLR_PC(n)		(0x28 + (n) * 0x10)
+/* PIO input comparison */
+#define REG_PIO_PCOMP			0x50
+/* Set bits of PCOMP */
+#define REG_PIO_SET_PCOMP		0x54
+/* Clear bits of PCOMP */
+#define REG_PIO_CLR_PCOMP		0x58
+/* PIO input comparison mask */
+#define REG_PIO_PMASK			0x60
+/* Set bits of PMASK */
+#define REG_PIO_SET_PMASK		0x64
+/* Clear bits of PMASK */
+#define REG_PIO_CLR_PMASK		0x68
+
+#define STIXXXX_MAX_GPIO_BANKS		32
+
+#define STIXXXX_GPIO_DIRECTION_BIDIR	0x1
+#define STIXXXX_GPIO_DIRECTION_OUT	0x2
+#define STIXXXX_GPIO_DIRECTION_IN	0x4
+
+#define STIXXXX_GPIO_PINS_PER_PORT	8
+#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
+#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)
+
+/* pinconf */
+/*
+ * Pinconf is represented in an opaque unsigned long variable.
+ * Below is the bit allocation details for each possible configuration.
+ * All the bit fields can be encapsulated into four variables
+ * (direction, retime-type, retime-clk, retime-delay)
+ *
+ *	 +----------------+
+ *[31:28]| reserved-3     |
+ *	 +----------------+-------------
+ *[27]   |	oe	  |		|
+ *	 +----------------+		v
+ *[26]   |	pu	  |	[Direction	]
+ *	 +----------------+		^
+ *[25]   |	od	  |		|
+ *	 +----------------+-------------
+ *[24]   | reserved-2     |
+ *	 +----------------+-------------
+ *[23]   |    retime      |		|
+ *	 +----------------+		|
+ *[22]   | retime-invclk  |		|
+ *	 +----------------+		v
+ *[21]   |retime-clknotdat|	[Retime-type	]
+ *	 +----------------+		^
+ *[20]   | retime-de      |		|
+ *	 +----------------+-------------
+ *[19:18]| retime-clk     |------>[Retime-Clk	]
+ *	 +----------------+
+ *[17:16]|  reserved-1    |
+ *	 +----------------+
+ *[15..0]| retime-delay   |------>[Retime Delay]
+ *	 +----------------+
+ */
+
+#define STIXXXX_PINCONF_UNPACK(conf, param)\
+				((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
+				& STIXXXX_PINCONF_ ##param ##_MASK)
+
+#define STIXXXX_PINCONF_PACK(conf, val, param)	(conf |=\
+				((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
+					STIXXXX_PINCONF_ ##param ##_SHIFT))
+
+/* Output enable */
+#define STIXXXX_PINCONF_OE_MASK		0x1
+#define STIXXXX_PINCONF_OE_SHIFT	27
+#define STIXXXX_PINCONF_OE		BIT(27)
+#define STIXXXX_PINCONF_UNPACK_OE(conf)	STIXXXX_PINCONF_UNPACK(conf, OE)
+#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)
+
+/* Pull Up */
+#define STIXXXX_PINCONF_PU_MASK		0x1
+#define STIXXXX_PINCONF_PU_SHIFT	26
+#define STIXXXX_PINCONF_PU		BIT(26)
+#define STIXXXX_PINCONF_UNPACK_PU(conf)	STIXXXX_PINCONF_UNPACK(conf, PU)
+#define STIXXXX_PINCONF_PACK_PU(conf, val) STIXXXX_PINCONF_PACK(conf, val, PU)
+
+/* Open Drain */
+#define STIXXXX_PINCONF_OD_MASK		0x1
+#define STIXXXX_PINCONF_OD_SHIFT	25
+#define STIXXXX_PINCONF_OD		BIT(25)
+#define STIXXXX_PINCONF_UNPACK_OD(conf)	STIXXXX_PINCONF_UNPACK(conf, OD)
+#define STIXXXX_PINCONF_PACK_OD(conf, val) STIXXXX_PINCONF_PACK(conf, val, OD)
+
+#define STIXXXX_PINCONF_RT_MASK		0x1
+#define STIXXXX_PINCONF_RT_SHIFT	23
+#define STIXXXX_PINCONF_RT		BIT(23)
+#define STIXXXX_PINCONF_UNPACK_RT(conf)	STIXXXX_PINCONF_UNPACK(conf, RT)
+#define STIXXXX_PINCONF_PACK_RT(conf, val) STIXXXX_PINCONF_PACK(conf, val, RT)
+
+#define STIXXXX_PINCONF_RT_INVERTCLK_MASK	0x1
+#define STIXXXX_PINCONF_RT_INVERTCLK_SHIFT	22
+#define STIXXXX_PINCONF_RT_INVERTCLK		BIT(22)
+#define STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(conf) \
+			STIXXXX_PINCONF_UNPACK(conf, RT_INVERTCLK)
+#define STIXXXX_PINCONF_PACK_RT_INVERTCLK(conf, val) \
+			STIXXXX_PINCONF_PACK(conf, val, RT_INVERTCLK)
+
+#define STIXXXX_PINCONF_RT_CLKNOTDATA_MASK	0x1
+#define STIXXXX_PINCONF_RT_CLKNOTDATA_SHIFT	21
+#define STIXXXX_PINCONF_RT_CLKNOTDATA		BIT(21)
+#define STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(conf)	\
+				STIXXXX_PINCONF_UNPACK(conf, RT_CLKNOTDATA)
+#define STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_CLKNOTDATA)
+
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_MASK	0x1
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_SHIFT	20
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE		BIT(20)
+#define STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \
+				STIXXXX_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE)
+#define STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_DOUBLE_EDGE)
+
+#define STIXXXX_PINCONF_RT_CLK_MASK		0x3
+#define STIXXXX_PINCONF_RT_CLK_SHIFT		18
+#define STIXXXX_PINCONF_RT_CLK			BIT(18)
+#define STIXXXX_PINCONF_UNPACK_RT_CLK(conf)	\
+			STIXXXX_PINCONF_UNPACK(conf, RT_CLK)
+#define STIXXXX_PINCONF_PACK_RT_CLK(conf, val) \
+			STIXXXX_PINCONF_PACK(conf, val, RT_CLK)
+
+/* RETIME_DELAY in Pico Secs */
+#define STIXXXX_PINCONF_RT_DELAY_MASK		0xffff
+#define STIXXXX_PINCONF_RT_DELAY_SHIFT		0
+#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
+				STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
+#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)
+
+#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
@ 2013-06-10  9:22     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

This patch add pinctrl support to ST SoCs.

About hardware:
ST Set-Top-Box parts have two blocks called PIO and PIO-mux which handle
pin configurations.

Each multi-function pin is controlled, driven and routed through the PIO
multiplexing block. Each pin supports GPIO functionality (ALT0) and
multiple alternate functions(ALT1 - ALTx) that directly connect the pin
to different hardware blocks. When a pin is in GPIO mode, Output Enable
(OE), Open Drain(OD), and Pull Up (PU) are driven by the related PIO
block. Otherwise the PIO multiplexing block configures these parameters
and retiming the signal.

About driver:
This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
pinconf, pinmux, gpio subsystems. All the pinctrl related config
information can only come from device trees.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 .../bindings/pinctrl/pinctrl-stixxxx.txt           |  116 ++
 drivers/pinctrl/Kconfig                            |   11 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-stixxxx.c                  | 1212 ++++++++++++++++++++
 drivers/pinctrl/pinctrl-stixxxx.h                  |  197 ++++
 5 files changed, 1537 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.c
 create mode 100644 drivers/pinctrl/pinctrl-stixxxx.h

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
new file mode 100644
index 0000000..ac69dca
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
@@ -0,0 +1,116 @@
+*ST pin controller.
+
+Each multi-function pin is controlled, driven and routed through the
+PIO multiplexing block. Each pin supports GPIO functionality (ALT0)
+and multiple alternate functions(ALT1 - ALTx) that directly connect
+the pin to different hardware blocks.
+
+When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and
+Pull Up (PU) are driven by the related PIO block.
+
+ST pinctrl driver controls PIO multiplexing block and also interacts with
+gpio driver to configure a pin.
+
+Required properties: (PIO multiplexing block)
+- compatible	: should be "st,stixxxx-pinctrl"
+			each subnode should set "st,stixxxx-gpio"
+			as compatible for each gpio-controller bank.
+- gpio-controller : Indicates this device is a GPIO controller
+- #gpio-cells	  : Should be one. The first cell is the pin number.
+- st,retime-in-delay	: Should be array of delays in nsecs.
+- st,retime-out-delay	: Should be array of delays in nsecs.
+- st,retime-pin-mask	: Should be mask to specify which pins can be retimed.
+- st,bank-name		: Should be a name string for this bank.
+- st,syscfg		: phandle of the syscfg node.
+- st,syscfg-offsets	: Should be a 5 cell entry which represent offset of altfunc,
+	output-enable, pull-up , open drain and retime registers in the syscfg bank
+
+Example:
+	pin-controller {
+		compatible = "st,stixxxx-pinctrl", "simple-bus";
+		st,retime-in-delay = <0 500 1000 1500>;
+		st,retime-out-delay = <0 1000 2000 3000>;
+		st,syscfg		= <&syscfg_front>;
+		st,syscfg-offsets	= <0 8 10 12 16>;
+		ranges;
+		PIO0: pinctrl at fe610000 {
+			gpio-controller;
+			#gpio-cells = <1>;
+			compatible = "st,stixxxx-gpio";
+			reg = <0xfe610000 0x100>;
+			st,bank-name  = "PIO0";
+		};
+		...
+		pin-functions nodes follow...
+	};
+
+
+Contents of function subnode node:
+----------------------
+Required properties for pin configuration node:
+- st,function	: Should be alternate function number associated
+		with this set of pins. Use same numbers from datasheet.
+
+- st,pins	: Child node with list of pins with configuration.
+
+Below is the format of how each pin conf should look like.
+
+<bank offset mode rt_type rt_delay rt_clk>
+
+Every PIO is represented with 4-7 parameters depending on retime configuration.
+Each parameter is explained as below.
+
+-bank		: Should be bank phandle to which this PIO belongs.
+-offset		: Offset in the PIO bank.
+-mode		:pin configuration is selected from one of the below values.
+		IN
+		IN_PU
+		OUT
+		BIDIR
+		BIDIR_PU
+
+-rt_type	Retiming Configuration for the pin.
+		Possible retime configuration are:
+
+		-------		-------------
+		value		args
+		-------		-------------
+		NICLK		<delay> <clk>
+		ICLK_IO		<delay> <clk>
+		BYPASS		<delay>
+		DE_IO		<delay> <clk>
+		SE_ICLK_IO	<delay> <clk>
+		SE_NICLK_IO	<delay> <clk>
+
+- delay	is retime delay in pico seconds.
+		Possible values are: refer to retime-in/out-delays
+
+- rt_clk	:clk to be use for retime.
+		Possible values are:
+		CLK_A
+		CLK_B
+		CLK_C
+		CLK_D
+
+Example of mmcclk pin which is a bi-direction pull pu with retime config
+as non inverted clock retimed with CLK_B and delay of 0 pico seconds:
+
+pin-controller {
+	...
+	mmc0 {
+		pinctrl_mmc: mmc {
+			st,function = <ALT4>;
+			st,pins {
+				mmcclk = <&PIO13 4 BIDIR_PU NICLK  0  CLK_B>;
+				...
+			};
+		};
+	...
+	};
+};
+
+sdhci0:sdhci at fe810000{
+	...
+	pinctrl-names = "default";
+	pinctrl-0	= <&pinctrl_mmc>;
+};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f66924..0c040a3 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -169,6 +169,17 @@ config PINCTRL_SUNXI
 	select PINMUX
 	select GENERIC_PINCONF
 
+config PINCTRL_STIXXXX
+	bool "ST Microelectronics pin controller driver for STixxxx SoCs"
+	select PINMUX
+	select PINCONF
+	help
+	  Say yes here to support pinctrl interface on STixxxx SOCs.
+	  This driver is used to control both PIO block and PIO-mux
+	  block to configure a pin.
+
+	  If unsure, say N.
+
 config PINCTRL_TEGRA
 	bool
 	select PINMUX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 9bdaeb8..0e035bb 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o
 obj-$(CONFIG_PINCTRL_S3C64XX)	+= pinctrl-s3c64xx.o
 obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
+obj-$(CONFIG_PINCTRL_STIXXXX) 	+= pinctrl-stixxxx.o
 
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh-pfc/
diff --git a/drivers/pinctrl/pinctrl-stixxxx.c b/drivers/pinctrl/pinctrl-stixxxx.c
new file mode 100644
index 0000000..da4e3d7
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stixxxx.c
@@ -0,0 +1,1212 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Authors:
+ *	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/stixxxx-syscfg.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/platform_device.h>
+#include "core.h"
+#include "pinctrl-stixxxx.h"
+
+struct stixxxx_pinconf {
+	int		pin;
+	const char	*name;
+	unsigned long	config;
+};
+
+struct stixxxx_pmx_func {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct stixxxx_pctl_group {
+	const char		*name;
+	unsigned int		*pins;
+	unsigned		npins;
+	int			altfunc;
+	struct stixxxx_pinconf	*pin_conf;
+};
+
+#define to_stixxxx_gpio_port(chip) \
+		container_of(chip, struct stixxxx_gpio_port, gpio_chip)
+
+struct stixxxx_gpio_port {
+	struct gpio_chip	gpio_chip;
+	struct pinctrl_gpio_range range;
+	void __iomem		*base;
+	struct device_node	*of_node;
+	const char		*bank_name;
+};
+
+static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];
+
+struct stixxxx_pinctrl {
+	struct device			*dev;
+	struct pinctrl_dev		*pctl;
+	int				nbanks;
+	struct stixxxx_pmx_func		*functions;
+	int				nfunctions;
+	struct stixxxx_pctl_group	*groups;
+	int				ngroups;
+	struct stixxxx_pio_control	*pio_controls;
+	struct pinctrl_gpio_range	**gpio_ranges;
+	struct regmap			*regmap;
+};
+
+/* Low level functions.. */
+static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
+				int pin_id, unsigned long config)
+{
+	struct regmap_field *output_enable;
+	struct regmap_field *pull_up;
+	struct regmap_field *open_drain;
+	unsigned int oe_value, pu_value, od_value;
+	unsigned long mask;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	output_enable = pc->oe;
+	pull_up = pc->pu;
+	open_drain = pc->od;
+
+	mask = BIT(pin);
+
+	regmap_field_read(output_enable, &oe_value);
+	regmap_field_read(pull_up, &pu_value);
+	regmap_field_read(open_drain, &od_value);
+
+	/* Clear old values */
+	oe_value &= ~mask;
+	pu_value &= ~mask;
+	od_value &= ~mask;
+
+	if (config & STIXXXX_PINCONF_OE)
+		oe_value |= mask;
+	if (config & STIXXXX_PINCONF_PU)
+		pu_value |= mask;
+	if (config & STIXXXX_PINCONF_OD)
+		od_value |= mask;
+
+	regmap_field_write(output_enable, oe_value);
+	regmap_field_write(pull_up, pu_value);
+	regmap_field_write(open_drain, od_value);
+}
+
+static void stixxxx_pctl_set_function(struct stixxxx_pio_control *pc,
+				int pin_id, int function)
+{
+	struct regmap_field *selector;
+	int offset;
+	unsigned int val;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	selector = pc->alt;
+	offset = pin * 4;
+	regmap_field_read(selector, &val);
+	val &= ~(0xf << offset);
+	val |= function << offset;
+	regmap_field_write(selector, val);
+}
+
+static unsigned long stixxxx_pinconf_delay_to_bit(unsigned int delay,
+		const struct stixxxx_retime_params *rt_params,
+		unsigned long config)
+{
+	unsigned int *delay_times;
+	int num_delay_times, i, closest_index = -1;
+	unsigned int closest_divergence = UINT_MAX;
+
+	if (STIXXXX_PINCONF_UNPACK_OE(config)) {
+		delay_times = rt_params->delay_times_out;
+		num_delay_times = rt_params->num_delay_times_out;
+	} else {
+		delay_times = rt_params->delay_times_in;
+		num_delay_times = rt_params->num_delay_times_in;
+	}
+
+	for (i = 0; i < num_delay_times; i++) {
+		unsigned int divergence = abs(delay - delay_times[i]);
+
+		if (divergence == 0)
+			return i;
+
+		if (divergence < closest_divergence) {
+			closest_divergence = divergence;
+			closest_index = i;
+		}
+	}
+
+	pr_warn("Attempt to set delay %d, closest available %d\n",
+	     delay, delay_times[closest_index]);
+
+	return closest_index;
+}
+
+static unsigned long stixxxx_pinconf_bit_to_delay(unsigned int index,
+		const struct stixxxx_retime_params *rt_params,
+		unsigned long output)
+{
+	unsigned int *delay_times;
+	int num_delay_times;
+
+	if (output) {
+		delay_times = rt_params->delay_times_out;
+		num_delay_times = rt_params->num_delay_times_out;
+	} else {
+		delay_times = rt_params->delay_times_in;
+		num_delay_times = rt_params->num_delay_times_in;
+	}
+
+	if (index < num_delay_times) {
+		return delay_times[index];
+	} else {
+		pr_warn("Delay not found in/out delay list\n");
+		return 0;
+	}
+}
+
+static void stixxxx_pinconf_set_retime_packed(
+		struct stixxxx_pio_control *pc,
+		unsigned long config, int pin)
+{
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
+	struct regmap_field **regs;
+	unsigned int values[2];
+	unsigned long mask;
+	int i, j;
+	int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
+	int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
+	int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
+	int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
+	int retime = STIXXXX_PINCONF_UNPACK_RT(config);
+	unsigned long delay = stixxxx_pinconf_delay_to_bit(
+			STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
+			pc->rt_params, config);
+
+	unsigned long rt_cfg =
+		((clk		& 1) << offset->clk1notclk0_offset) |
+		((clknotdata	& 1) << offset->clknotdata_offset) |
+		((delay		& 1) << offset->delay_lsb_offset) |
+		(((delay >> 1)  & 1) << offset->delay_msb_offset) |
+		((double_edge	& 1) << offset->double_edge_offset) |
+		((invertclk	& 1) << offset->invertclk_offset) |
+		((retime	& 1) << offset->retime_offset);
+
+	regs = pc->retiming;
+	regmap_field_read(regs[0], &values[0]);
+	regmap_field_read(regs[1], &values[1]);
+
+	for (i = 0; i < 2; i++) {
+		mask = BIT(pin);
+		for (j = 0; j < 4; j++) {
+			if (rt_cfg & 1)
+				values[i] |= mask;
+			else
+				values[i] &= ~mask;
+			mask <<= 8;
+			rt_cfg >>= 1;
+		}
+	}
+
+	regmap_field_write(regs[0], values[0]);
+	regmap_field_write(regs[1], values[1]);
+}
+
+static void stixxxx_pinconf_set_retime_dedicated(
+	struct stixxxx_pio_control *pc,
+	unsigned long config, int pin)
+{
+	struct regmap_field *reg;
+	int input = STIXXXX_PINCONF_UNPACK_OE(config) ? 0 : 1;
+	int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
+	int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
+	int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
+	int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
+	int retime = STIXXXX_PINCONF_UNPACK_RT(config);
+	unsigned long delay = stixxxx_pinconf_delay_to_bit(
+			STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
+			pc->rt_params, config);
+
+	unsigned long retime_config =
+		((clk		& 0x3) << 0) |
+		((clknotdata	& 0x1) << 2) |
+		((delay		& 0xf) << 3) |
+		((input		& 0x1) << 7) |
+		((double_edge	& 0x1) << 8) |
+		((invertclk	& 0x1) << 9) |
+		((retime	& 0x1) << 10);
+
+	reg = pc->retiming[pin];
+	regmap_field_write(reg, retime_config);
+}
+
+static void stixxxx_pinconf_get_direction(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long *config)
+{
+	unsigned int oe_value, pu_value, od_value;
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	regmap_field_read(pc->oe, &oe_value);
+	regmap_field_read(pc->pu, &pu_value);
+	regmap_field_read(pc->od, &od_value);
+
+	oe_value = (oe_value >> pin) & 1;
+	pu_value = (pu_value >> pin) & 1;
+	od_value = (od_value >> pin) & 1;
+
+	STIXXXX_PINCONF_PACK_OE(*config, oe_value);
+	STIXXXX_PINCONF_PACK_PU(*config, pu_value);
+	STIXXXX_PINCONF_PACK_OD(*config, od_value);
+}
+
+static int stixxxx_pinconf_get_retime_packed(
+		struct stixxxx_pio_control *pc,
+		int pin, unsigned long *config)
+{
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
+	unsigned long delay_bits, delay, rt_reduced;
+	unsigned int rt_value[2];
+	int i, j;
+	int output = STIXXXX_PINCONF_UNPACK_OE(*config);
+
+	regmap_field_read(pc->retiming[0], &rt_value[0]);
+	regmap_field_read(pc->retiming[1], &rt_value[1]);
+
+	rt_reduced = 0;
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 4; j++) {
+			if (rt_value[i] & (1<<((8*j)+pin)))
+				rt_reduced |= 1 << ((i*4)+j);
+		}
+	}
+
+	STIXXXX_PINCONF_PACK_RT(*config,
+			(rt_reduced >> offset->retime_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_CLK(*config,
+			(rt_reduced >> offset->clk1notclk0_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
+			(rt_reduced >> offset->clknotdata_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
+			(rt_reduced >> offset->double_edge_offset) & 1);
+	STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
+			(rt_reduced >> offset->invertclk_offset) & 1);
+
+	delay_bits =  (((rt_reduced >> offset->delay_msb_offset) & 1)<<1) |
+			((rt_reduced >> offset->delay_lsb_offset) & 1);
+	delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
+	STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
+	return 0;
+}
+
+static int stixxxx_pinconf_get_retime_dedicated(
+		struct stixxxx_pio_control *pc,
+		int pin, unsigned long *config)
+{
+	unsigned int value;
+	unsigned long delay_bits, delay;
+	const struct stixxxx_retime_params *rt_params = pc->rt_params;
+	int output = STIXXXX_PINCONF_UNPACK_OE(*config);
+
+	regmap_field_read(pc->retiming[pin], &value);
+	STIXXXX_PINCONF_PACK_RT_CLK(*config, ((value >> 0) & 0x3));
+	STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config, ((value >> 2) & 0x1));
+	delay_bits = ((value >> 3) & 0xf);
+	delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
+	STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
+	STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config, ((value >> 8) & 0x1));
+	STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config, ((value >> 9) & 0x1));
+	STIXXXX_PINCONF_PACK_RT(*config, ((value >> 10) & 0x1));
+
+	return 0;
+}
+
+/* GPIO related functions */
+
+static inline void __stixxxx_gpio_set(struct stixxxx_gpio_port *port,
+	unsigned offset, int value)
+{
+	if (value)
+		writel(BIT(offset), port->base + REG_PIO_SET_POUT);
+	else
+		writel(BIT(offset), port->base + REG_PIO_CLR_POUT);
+}
+
+static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
+{
+	int port_num = stixxxx_gpio_port(gpio);
+	int offset = stixxxx_gpio_pin(gpio);
+	struct stixxxx_gpio_port *port  = gpio_ports[port_num];
+	int i = 0;
+
+	for (i = 0; i <= 2; i++) {
+		if (direction & BIT(i))
+			writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
+		else
+			writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
+	}
+}
+
+static int stixxxx_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void stixxxx_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+
+	return (readl(port->base + REG_PIO_PIN) >> offset) & 1;
+}
+
+static void stixxxx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+	__stixxxx_gpio_set(port, offset, value);
+}
+
+static int stixxxx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_gpio_direction_input(chip->base + offset);
+	return 0;
+}
+
+static int stixxxx_gpio_direction_output(struct gpio_chip *chip,
+	unsigned offset, int value)
+{
+	struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
+
+	__stixxxx_gpio_set(port, offset, value);
+	pinctrl_gpio_direction_output(chip->base + offset);
+
+	return 0;
+}
+
+static int stixxxx_gpio_xlate(struct gpio_chip *gc,
+			const struct of_phandle_args *gpiospec, u32 *flags)
+{
+	if (WARN_ON(gc->of_gpio_n_cells < 1))
+		return -EINVAL;
+
+	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
+		return -EINVAL;
+
+	if (gpiospec->args[0] > gc->ngpio)
+		return -EINVAL;
+
+	return gpiospec->args[0];
+}
+
+/* Pinctrl Groups */
+static int stixxxx_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *stixxxx_pctl_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int stixxxx_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+	unsigned selector, const unsigned **pins, unsigned *npins)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static const inline struct stixxxx_pctl_group *stixxxx_pctl_find_group_by_name(
+	const struct stixxxx_pinctrl *info, const char *name)
+{
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name))
+			return &info->groups[i];
+	}
+
+	return NULL;
+}
+
+static int stixxxx_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
+	struct device_node *np, struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct stixxxx_pctl_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num, i;
+
+	grp = stixxxx_pctl_find_group_by_name(info, np->name);
+	if (!grp) {
+		dev_err(info->dev, "unable to find group for node %s\n",
+			np->name);
+		return -EINVAL;
+	}
+
+	map_num = grp->npins + 1;
+	new_map = devm_kzalloc(pctldev->dev,
+				sizeof(*new_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	*map = new_map;
+	*num_maps = map_num;
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	/* create config map per pin */
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin =
+				pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = &grp->pin_conf[i].config;
+		new_map[i].data.configs.num_configs = 1;
+	}
+	dev_info(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, grp->name, map_num);
+
+	return 0;
+}
+
+static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
+				struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static struct pinctrl_ops stixxxx_pctlops = {
+	.get_groups_count	= stixxxx_pctl_get_groups_count,
+	.get_group_pins		= stixxxx_pctl_get_group_pins,
+	.get_group_name		= stixxxx_pctl_get_group_name,
+	.dt_node_to_map		= stixxxx_pctl_dt_node_to_map,
+	.dt_free_map		= stixxxx_pctl_dt_free_map,
+};
+
+/* Pinmux */
+static int stixxxx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+const char *stixxxx_pmx_get_fname(struct pinctrl_dev *pctldev,
+	unsigned selector)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int stixxxx_pmx_get_groups(struct pinctrl_dev *pctldev,
+	unsigned selector, const char * const **grps, unsigned * const ngrps)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	*grps = info->functions[selector].groups;
+	*ngrps = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static struct stixxxx_pio_control *stixxxx_get_pio_control(
+			struct stixxxx_pinctrl *info, int pin_id)
+{
+	int index = stixxxx_gpio_port(pin_id) - info->gpio_ranges[0]->id;
+	return &info->pio_controls[index];
+}
+
+static int stixxxx_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
+		unsigned group)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pinconf *conf = info->groups[group].pin_conf;
+	struct stixxxx_pio_control *pc;
+	int i;
+
+	for (i = 0; i < info->groups[group].npins; i++) {
+		pc = stixxxx_get_pio_control(info, conf[i].pin);
+		stixxxx_pctl_set_function(pc, conf[i].pin,
+					info->groups[group].altfunc);
+	}
+
+	return 0;
+}
+
+static void stixxxx_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
+		unsigned group)
+{
+}
+
+static int stixxxx_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range, unsigned gpio,
+			bool input)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	int offset = range->id - info->gpio_ranges[0]->id;
+	struct stixxxx_pio_control *pc = &info->pio_controls[offset];
+	/*
+	 * When a PIO port is used in its primary function mode (altfunc = 0)
+	 * Output Enable (OE), Open Drain(OD), and Pull Up (PU)
+	 * for the primary PIO functions are driven by the related PIO block
+	 */
+	stixxxx_pctl_set_function(pc, gpio, 0);
+	stixxxx_gpio_direction(gpio, input ?
+		STIXXXX_GPIO_DIRECTION_IN : STIXXXX_GPIO_DIRECTION_OUT);
+
+	return 0;
+}
+
+static struct pinmux_ops stixxxx_pmxops = {
+	.get_functions_count	= stixxxx_pmx_get_funcs_count,
+	.get_function_name	= stixxxx_pmx_get_fname,
+	.get_function_groups	= stixxxx_pmx_get_groups,
+	.enable			= stixxxx_pmx_enable,
+	.disable		= stixxxx_pmx_disable,
+	.gpio_set_direction	= stixxxx_pmx_set_gpio_direction,
+};
+
+/* Pinconf  */
+static void stixxxx_pinconf_get_retime(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long *config)
+{
+	int pin = stixxxx_gpio_pin(pin_id);
+	if (pc->rt_style == stixxxx_retime_style_packed)
+		stixxxx_pinconf_get_retime_packed(pc, pin, config);
+	else if (pc->rt_style == stixxxx_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			stixxxx_pinconf_get_retime_dedicated(pc, pin, config);
+}
+
+static void stixxxx_pinconf_set_retime(struct stixxxx_pio_control *pc,
+	int pin_id, unsigned long config)
+{
+	int pin = stixxxx_gpio_pin(pin_id);
+
+	if (pc->rt_style == stixxxx_retime_style_packed)
+		stixxxx_pinconf_set_retime_packed(pc, config, pin);
+	else if (pc->rt_style == stixxxx_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			stixxxx_pinconf_set_retime_dedicated(pc, config, pin);
+}
+
+static int stixxxx_pinconf_set(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long config)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pio_control *pc = stixxxx_get_pio_control(info, pin_id);
+
+	stixxxx_pinconf_set_direction(pc, pin_id, config);
+	stixxxx_pinconf_set_retime(pc, pin_id, config);
+	return 0;
+}
+
+static int stixxxx_pinconf_get(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long *config)
+{
+	struct stixxxx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stixxxx_pio_control *pc = stixxxx_get_pio_control(info, pin_id);
+
+	*config = 0;
+	stixxxx_pinconf_get_direction(pc, pin_id, config);
+	stixxxx_pinconf_get_retime(pc, pin_id, config);
+
+	return 0;
+}
+
+static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				   struct seq_file *s, unsigned pin_id)
+{
+	unsigned long config;
+	stixxxx_pinconf_get(pctldev, pin_id, &config);
+
+	seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
+		"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
+		"de:%ld,rt-clk:%ld,rt-delay:%ld]",
+		STIXXXX_PINCONF_UNPACK_OE(config),
+		STIXXXX_PINCONF_UNPACK_PU(config),
+		STIXXXX_PINCONF_UNPACK_OD(config),
+		STIXXXX_PINCONF_UNPACK_RT(config),
+		STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
+		STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
+		STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
+		STIXXXX_PINCONF_UNPACK_RT_CLK(config),
+		STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
+}
+
+static struct pinconf_ops stixxxx_confops = {
+	.pin_config_get		= stixxxx_pinconf_get,
+	.pin_config_set		= stixxxx_pinconf_set,
+	.pin_config_dbg_show	= stixxxx_pinconf_dbg_show,
+};
+
+static int stixxxx_pinconf_dt_parse_rt_params(struct stixxxx_pinctrl *info,
+	struct device_node *np,	struct stixxxx_retime_params *params)
+{
+	struct stixxxx_retime_offset *rt_offset;
+	int delay_count = 0;
+	int len;
+	if (of_find_property(np, "st,retime-in-delay", &len))
+		delay_count = len/sizeof(__be32);
+	else
+		dev_err(info->dev, "No delays found\n");
+
+	params->num_delay_times_out = delay_count;
+	params->num_delay_times_in = delay_count;
+	params->delay_times_in = devm_kzalloc(info->dev,
+				sizeof(u32) * delay_count, GFP_KERNEL);
+	params->delay_times_out = devm_kzalloc(info->dev,
+				sizeof(u32) * delay_count, GFP_KERNEL);
+
+	if (!params->delay_times_in || !params->delay_times_out)
+		return -ENOMEM;
+
+	of_property_read_u32_array(np, "st,retime-in-delay",
+				(u32 *)params->delay_times_in, delay_count);
+	of_property_read_u32_array(np, "st,retime-out-delay",
+				(u32 *)params->delay_times_out, delay_count);
+
+	if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
+		rt_offset = devm_kzalloc(info->dev,
+			sizeof(*rt_offset), GFP_KERNEL);
+
+		if (!rt_offset)
+			return -ENOMEM;
+
+		rt_offset->clk1notclk0_offset = 0;
+		rt_offset->delay_lsb_offset = 2;
+		rt_offset->delay_msb_offset = 3;
+		rt_offset->invertclk_offset = 4;
+		rt_offset->retime_offset = 5;
+		rt_offset->clknotdata_offset = 6;
+		rt_offset->double_edge_offset = 7;
+		params->retime_offset = rt_offset;
+	}
+
+	return 0;
+}
+
+static const char *gpio_compat = "st,stixxxx-gpio";
+
+static void stixxxx_pctl_dt_child_count(struct stixxxx_pinctrl *info,
+				     struct device_node *np)
+{
+	struct device_node *child;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			info->nbanks++;
+		} else {
+			info->nfunctions++;
+			info->ngroups += of_get_child_count(child);
+		}
+	}
+}
+
+static int stixxxx_pctl_dt_get_retime_conf(struct stixxxx_pinctrl *info,
+	struct stixxxx_pio_control *pc, u32 *syscfg)
+{
+	unsigned int j;
+	int rt_syscfg = *syscfg;
+	struct device_node *np = info->dev->of_node;
+
+	if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
+		pc->rt_style = stixxxx_retime_style_packed;
+		for (j = 0; j < 2; j++) {
+			struct reg_field rt_reg =
+					REG_FIELD(4 * rt_syscfg ++, 0, 31);
+			pc->retiming[j] = devm_regmap_field_alloc(info->dev,
+						info->regmap, rt_reg);
+			if (IS_ERR(pc->retiming[j]))
+				return -ENODATA;
+		}
+	} else if (of_device_is_compatible(np, "st,stih416-pinctrl")) {
+		pc->rt_style = stixxxx_retime_style_dedicated;
+		for (j = 0; j < 8; j++) {
+			if ((1<<j) & pc->rt_pin_mask) {
+				struct reg_field rt_reg =
+					REG_FIELD(4 * rt_syscfg ++, 0, 31);
+				pc->retiming[j] = devm_regmap_field_alloc(
+					info->dev, info->regmap, rt_reg);
+				if (IS_ERR(pc->retiming[j]))
+					return -ENODATA;
+			}
+		}
+	} else {
+		pc->rt_style = stixxxx_retime_style_none;
+	}
+
+	*syscfg = rt_syscfg;
+	return 0;
+}
+
+static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
+			struct device_node *np)
+{
+	struct stixxxx_pio_control *pc;
+	struct stixxxx_retime_params *rt_params;
+	struct device *dev = info->dev;
+	struct regmap *regmap;
+	unsigned int i = 0;
+	struct device_node *child = NULL;
+	u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
+	u32 syscfg_offsets[5];
+	u32 msb, lsb;
+
+	pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
+	rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
+
+	if (!pc || !rt_params)
+		return -ENOMEM;
+
+	regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (!regmap) {
+		dev_err(dev, "No syscfg phandle specified\n");
+		return -ENOMEM;
+	}
+	info->regmap = regmap;
+	info->pio_controls = pc;
+	if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
+		return -ENOMEM;
+
+	if (of_property_read_u32_array(np, "st,syscfg-offsets",
+				syscfg_offsets, 5)) {
+		dev_err(dev, "Syscfg offsets not found\n");
+		return -EINVAL;
+	}
+	alt_syscfg = syscfg_offsets[0];
+	oe_syscfg = syscfg_offsets[1];
+	pu_syscfg = syscfg_offsets[2];
+	od_syscfg = syscfg_offsets[3];
+	rt_syscfg = syscfg_offsets[4];
+
+	lsb = 0;
+	msb = 7;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			struct reg_field alt_reg =
+					REG_FIELD(4 * alt_syscfg++, 0, 31);
+			struct reg_field oe_reg =
+					REG_FIELD(4 * oe_syscfg, lsb, msb);
+			struct reg_field pu_reg =
+					REG_FIELD(4 * pu_syscfg, lsb, msb);
+			struct reg_field od_reg =
+					REG_FIELD(4 * od_syscfg, lsb, msb);
+			pc[i].rt_params = rt_params;
+
+			pc[i].alt = devm_regmap_field_alloc(dev,
+							regmap, alt_reg);
+			pc[i].oe = devm_regmap_field_alloc(dev,
+							regmap, oe_reg);
+			pc[i].pu = devm_regmap_field_alloc(dev,
+							regmap, pu_reg);
+			pc[i].od = devm_regmap_field_alloc(dev,
+							regmap, od_reg);
+
+			if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
+				|| IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
+				goto failed;
+
+			of_property_read_u32(child, "st,retime-pin-mask",
+						&pc[i].rt_pin_mask);
+
+			stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
+							&rt_syscfg);
+			i++;
+			if (msb  == 31) {
+				oe_syscfg++;
+				pu_syscfg++;
+				od_syscfg++;
+				lsb = 0;
+				msb = 7;
+			} else {
+				lsb += 8;
+				msb += 8;
+			}
+		}
+	}
+
+	return 0;
+failed:
+	dev_err(dev, "Unable to allocate syscfgs\n");
+	return -ENOMEM;
+}
+
+#define OF_GPIO_ARGS_MIN	(3)
+/*
+ * Each pin is represented in of the below forms.
+ * <bank offset direction func rt_type rt_delay rt_clk>
+ */
+static int stixxxx_pctl_dt_parse_groups(struct device_node *np,
+	struct stixxxx_pctl_group *grp, struct stixxxx_pinctrl *info, int idx)
+{
+	/* bank pad direction val altfunction */
+	const __be32 *list;
+	struct property *pp;
+	struct stixxxx_pinconf *conf;
+	phandle phandle;
+	struct device_node *pins;
+	u32 pin;
+	int i = 0, npins = 0, nr_props;
+
+	pins = of_get_child_by_name(np, "st,pins");
+	if (!pins)
+		return -ENODATA;
+
+	for_each_property_of_node(pins, pp) {
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name"))
+			continue;
+
+		if (pp  && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
+			npins++;
+		} else {
+			pr_warn("Invalid st,pins in %s node\n", np->name);
+			return -EINVAL;
+		}
+	}
+
+	grp->npins = npins;
+	grp->name = np->name;
+	grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL);
+	grp->pin_conf = devm_kzalloc(info->dev,
+					npins * sizeof(*conf), GFP_KERNEL);
+	of_property_read_u32(np, "st,function", &grp->altfunc);
+
+	if (!grp->pins || !grp->pin_conf)
+		return -ENOMEM;
+
+	/* <bank offset direction rt_type rt_delay rt_clk> */
+	for_each_property_of_node(pins, pp) {
+		if (!strcmp(pp->name, "name"))
+			continue;
+		nr_props = pp->length/sizeof(u32);
+		list = pp->value;
+		conf = &grp->pin_conf[i];
+
+		/* bank & offset */
+		phandle = be32_to_cpup(list++);
+		pin = be32_to_cpup(list++);
+		conf->pin = of_get_named_gpio(pins, pp->name, 0);
+		conf->name = pp->name;
+		grp->pins[i] = conf->pin;
+
+		conf->config = 0;
+		/* direction */
+		conf->config |= be32_to_cpup(list++);
+		/* rt_type rt_delay rt_clk */
+		if (nr_props >= OF_GPIO_ARGS_MIN + 2) {
+			/* rt_type */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_delay */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_clk */
+			if (nr_props > OF_GPIO_ARGS_MIN + 2)
+				conf->config |= be32_to_cpup(list++);
+		}
+		i++;
+	}
+	of_node_put(pins);
+
+	return 0;
+}
+
+static int stixxxx_pctl_parse_functions(struct device_node *np,
+			struct stixxxx_pinctrl *info, u32 index, int *grp_index)
+{
+	struct device_node *child;
+	struct stixxxx_pmx_func *func;
+	struct stixxxx_pctl_group *grp;
+	int ret, i;
+
+	func = &info->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups <= 0) {
+		dev_err(info->dev, "No groups defined\n");
+		return -EINVAL;
+	}
+	func->groups = devm_kzalloc(info->dev,
+			func->ngroups * sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[*grp_index];
+		*grp_index += 1;
+		ret = stixxxx_pctl_dt_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+	dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n",
+				index, func->name, func->ngroups);
+
+	return 0;
+}
+
+static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
+{
+	int i;
+	for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
+		if (gpio_ports[i]->of_node == np)
+			return &gpio_ports[i]->range;
+
+	return NULL;
+}
+
+static int stixxxx_pctl_probe_dt(struct platform_device *pdev,
+	struct pinctrl_desc *pctl_desc, struct stixxxx_pinctrl *info)
+{
+	int ret = 0;
+	int i = 0, j = 0, k = 0, bank;
+	struct pinctrl_pin_desc *pdesc;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	int grp_index = 0;
+
+	stixxxx_pctl_dt_child_count(info, np);
+	if (info->nbanks < 1) {
+		dev_err(&pdev->dev, "you need atleast one gpio bank\n");
+		return -EINVAL;
+	}
+
+	ret = stixxxx_pctl_dt_init(info, np);
+	if (ret)
+		return ret;
+
+	dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks);
+	dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+	dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups);
+	info->functions = devm_kzalloc(&pdev->dev,
+		info->nfunctions * sizeof(*info->functions), GFP_KERNEL);
+
+	info->groups = devm_kzalloc(&pdev->dev,
+		info->ngroups * sizeof(*info->groups) ,	GFP_KERNEL);
+
+	info->gpio_ranges = devm_kzalloc(&pdev->dev,
+		info->nbanks * sizeof(*info->gpio_ranges), GFP_KERNEL);
+
+	if (!info->functions || !info->groups)
+		return -ENOMEM;
+
+	pctl_desc->npins = info->nbanks * STIXXXX_GPIO_PINS_PER_PORT;
+	pdesc =	devm_kzalloc(&pdev->dev,
+			sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!pdesc)
+		return -ENOMEM;
+
+	pctl_desc->pins = pdesc;
+
+	bank = 0;
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat)) {
+			info->gpio_ranges[bank] = find_gpio_range(child);
+			k = info->gpio_ranges[bank]->pin_base;
+			for (j = 0; j < STIXXXX_GPIO_PINS_PER_PORT; j++, k++) {
+				const char *port_name = NULL;
+				pdesc->number = k;
+				of_property_read_string(child, "st,bank-name",
+							&port_name);
+				pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]",
+							port_name ? : "PIO",
+							port_name ? j : k);
+				pdesc++;
+			}
+			bank++;
+		} else {
+			ret = stixxxx_pctl_parse_functions(child, info,
+							i++, &grp_index);
+			if (ret) {
+				dev_err(&pdev->dev, "No functions found.\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int stixxxx_pctl_probe(struct platform_device *pdev)
+{
+	struct stixxxx_pinctrl *info;
+	struct pinctrl_desc *pctl_desc;
+	int ret, i;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "device node not found.\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = &pdev->dev;
+	platform_set_drvdata(pdev, info);
+	ret = stixxxx_pctl_probe_dt(pdev, pctl_desc, info);
+	if (ret)
+		return ret;
+
+	pctl_desc->owner	= THIS_MODULE,
+	pctl_desc->pctlops	= &stixxxx_pctlops,
+	pctl_desc->pmxops	= &stixxxx_pmxops,
+	pctl_desc->confops	= &stixxxx_confops,
+	pctl_desc->name		= dev_name(&pdev->dev);
+
+	info->pctl = pinctrl_register(pctl_desc, &pdev->dev, info);
+	if (IS_ERR(info->pctl)) {
+		dev_err(&pdev->dev, "Failed pinctrl registration\n");
+		return PTR_ERR(info->pctl);
+	}
+
+	for (i = 0; i < info->nbanks; i++)
+		pinctrl_add_gpio_range(info->pctl, info->gpio_ranges[i]);
+
+	return 0;
+}
+
+static struct gpio_chip stixxxx_gpio_template = {
+	.request		= stixxxx_gpio_request,
+	.free			= stixxxx_gpio_free,
+	.get			= stixxxx_gpio_get,
+	.set			= stixxxx_gpio_set,
+	.direction_input	= stixxxx_gpio_direction_input,
+	.direction_output	= stixxxx_gpio_direction_output,
+	.ngpio			= STIXXXX_GPIO_PINS_PER_PORT,
+	.of_gpio_n_cells	= 1,
+	.of_xlate		= stixxxx_gpio_xlate,
+};
+
+static int stixxxx_gpio_probe(struct platform_device *pdev)
+{
+	struct stixxxx_gpio_port *port;
+	struct pinctrl_gpio_range *range;
+	struct device_node *np  = pdev->dev.of_node;
+	int port_num = of_alias_get_id(np, "gpio");
+	struct resource *res;
+	int err;
+
+	port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	port->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!port->base) {
+		dev_err(&pdev->dev, "Can't get IO memory mapping!\n");
+		return -ENODEV;
+	}
+
+	of_property_read_string(np, "st,bank-name", &port->bank_name);
+	port->of_node = np;
+
+	port->gpio_chip = stixxxx_gpio_template;
+	port->gpio_chip.base = port_num * STIXXXX_GPIO_PINS_PER_PORT;
+	port->gpio_chip.ngpio = STIXXXX_GPIO_PINS_PER_PORT;
+	port->gpio_chip.of_node = np;
+	port->gpio_chip.label = dev_name(&pdev->dev);
+
+	dev_set_drvdata(&pdev->dev, port);
+	range = &port->range;
+	range->name = port->gpio_chip.label;
+	range->id = port_num;
+	range->pin_base = range->base = range->id * STIXXXX_GPIO_PINS_PER_PORT;
+	range->npins = port->gpio_chip.ngpio;
+	range->gc = &port->gpio_chip;
+	gpio_ports[port_num] = port;
+	err  = gpiochip_add(&port->gpio_chip);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to add gpiochip(%d)!\n", port_num);
+		return err;
+	}
+	dev_info(&pdev->dev, "gpioport[%s] Added as bank%d\n",
+				port->bank_name, port_num);
+	return 0;
+}
+
+static struct of_device_id stixxxx_gpio_of_match[] = {
+	{ .compatible = "st,stixxxx-gpio", },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver stixxxx_gpio_driver = {
+	.driver = {
+		.name = "st-gpio",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(stixxxx_gpio_of_match),
+	},
+	.probe = stixxxx_gpio_probe,
+};
+
+static struct of_device_id stixxxx_pctl_of_match[] = {
+	{ .compatible = "st,stixxxx-pinctrl",},
+	{ .compatible = "st,stih415-pinctrl",},
+	{ .compatible = "st,stih416-pinctrl",},
+	{ /* sentinel */ }
+};
+
+static struct platform_driver stixxxx_pctl_driver = {
+	.driver = {
+		.name = "st-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(stixxxx_pctl_of_match),
+	},
+	.probe = stixxxx_pctl_probe,
+};
+
+static int __init stixxxx_pctl_init(void)
+{
+	int ret = platform_driver_register(&stixxxx_gpio_driver);
+	if (ret)
+		return ret;
+	return platform_driver_register(&stixxxx_pctl_driver);
+}
+arch_initcall(stixxxx_pctl_init);
diff --git a/drivers/pinctrl/pinctrl-stixxxx.h b/drivers/pinctrl/pinctrl-stixxxx.h
new file mode 100644
index 0000000..e88ab09
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stixxxx.h
@@ -0,0 +1,197 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Authors:
+ *	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
+#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
+
+enum stixxxx_retime_style {
+	stixxxx_retime_style_none,
+	stixxxx_retime_style_packed,
+	stixxxx_retime_style_dedicated,
+};
+
+/* Byte positions in 2 syscon words, starts from 0 */
+struct stixxxx_retime_offset {
+	int retime_offset;
+	int clk1notclk0_offset;
+	int clknotdata_offset;
+	int double_edge_offset;
+	int invertclk_offset;
+	int delay_lsb_offset;
+	int delay_msb_offset;
+};
+
+struct stixxxx_retime_params {
+	const struct stixxxx_retime_offset *retime_offset;
+	unsigned int *delay_times_in;
+	int num_delay_times_in;
+	unsigned int *delay_times_out;
+	int num_delay_times_out;
+};
+
+struct stixxxx_pio_control {
+	enum stixxxx_retime_style rt_style;
+	u32 rt_pin_mask;
+	const struct stixxxx_retime_params *rt_params;
+	struct regmap_field *alt;
+	struct regmap_field *oe, *pu, *od;
+	struct regmap_field *retiming[8];
+};
+
+/* PIO Block registers */
+/* PIO output */
+#define REG_PIO_POUT			0x00
+/* Set bits of POUT */
+#define REG_PIO_SET_POUT		0x04
+/* Clear bits of POUT */
+#define REG_PIO_CLR_POUT		0x08
+/* PIO input */
+#define REG_PIO_PIN			0x10
+/* PIO configuration */
+#define REG_PIO_PC(n)			(0x20 + (n) * 0x10)
+/* Set bits of PC[2:0] */
+#define REG_PIO_SET_PC(n)		(0x24 + (n) * 0x10)
+/* Clear bits of PC[2:0] */
+#define REG_PIO_CLR_PC(n)		(0x28 + (n) * 0x10)
+/* PIO input comparison */
+#define REG_PIO_PCOMP			0x50
+/* Set bits of PCOMP */
+#define REG_PIO_SET_PCOMP		0x54
+/* Clear bits of PCOMP */
+#define REG_PIO_CLR_PCOMP		0x58
+/* PIO input comparison mask */
+#define REG_PIO_PMASK			0x60
+/* Set bits of PMASK */
+#define REG_PIO_SET_PMASK		0x64
+/* Clear bits of PMASK */
+#define REG_PIO_CLR_PMASK		0x68
+
+#define STIXXXX_MAX_GPIO_BANKS		32
+
+#define STIXXXX_GPIO_DIRECTION_BIDIR	0x1
+#define STIXXXX_GPIO_DIRECTION_OUT	0x2
+#define STIXXXX_GPIO_DIRECTION_IN	0x4
+
+#define STIXXXX_GPIO_PINS_PER_PORT	8
+#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
+#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)
+
+/* pinconf */
+/*
+ * Pinconf is represented in an opaque unsigned long variable.
+ * Below is the bit allocation details for each possible configuration.
+ * All the bit fields can be encapsulated into four variables
+ * (direction, retime-type, retime-clk, retime-delay)
+ *
+ *	 +----------------+
+ *[31:28]| reserved-3     |
+ *	 +----------------+-------------
+ *[27]   |	oe	  |		|
+ *	 +----------------+		v
+ *[26]   |	pu	  |	[Direction	]
+ *	 +----------------+		^
+ *[25]   |	od	  |		|
+ *	 +----------------+-------------
+ *[24]   | reserved-2     |
+ *	 +----------------+-------------
+ *[23]   |    retime      |		|
+ *	 +----------------+		|
+ *[22]   | retime-invclk  |		|
+ *	 +----------------+		v
+ *[21]   |retime-clknotdat|	[Retime-type	]
+ *	 +----------------+		^
+ *[20]   | retime-de      |		|
+ *	 +----------------+-------------
+ *[19:18]| retime-clk     |------>[Retime-Clk	]
+ *	 +----------------+
+ *[17:16]|  reserved-1    |
+ *	 +----------------+
+ *[15..0]| retime-delay   |------>[Retime Delay]
+ *	 +----------------+
+ */
+
+#define STIXXXX_PINCONF_UNPACK(conf, param)\
+				((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
+				& STIXXXX_PINCONF_ ##param ##_MASK)
+
+#define STIXXXX_PINCONF_PACK(conf, val, param)	(conf |=\
+				((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
+					STIXXXX_PINCONF_ ##param ##_SHIFT))
+
+/* Output enable */
+#define STIXXXX_PINCONF_OE_MASK		0x1
+#define STIXXXX_PINCONF_OE_SHIFT	27
+#define STIXXXX_PINCONF_OE		BIT(27)
+#define STIXXXX_PINCONF_UNPACK_OE(conf)	STIXXXX_PINCONF_UNPACK(conf, OE)
+#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)
+
+/* Pull Up */
+#define STIXXXX_PINCONF_PU_MASK		0x1
+#define STIXXXX_PINCONF_PU_SHIFT	26
+#define STIXXXX_PINCONF_PU		BIT(26)
+#define STIXXXX_PINCONF_UNPACK_PU(conf)	STIXXXX_PINCONF_UNPACK(conf, PU)
+#define STIXXXX_PINCONF_PACK_PU(conf, val) STIXXXX_PINCONF_PACK(conf, val, PU)
+
+/* Open Drain */
+#define STIXXXX_PINCONF_OD_MASK		0x1
+#define STIXXXX_PINCONF_OD_SHIFT	25
+#define STIXXXX_PINCONF_OD		BIT(25)
+#define STIXXXX_PINCONF_UNPACK_OD(conf)	STIXXXX_PINCONF_UNPACK(conf, OD)
+#define STIXXXX_PINCONF_PACK_OD(conf, val) STIXXXX_PINCONF_PACK(conf, val, OD)
+
+#define STIXXXX_PINCONF_RT_MASK		0x1
+#define STIXXXX_PINCONF_RT_SHIFT	23
+#define STIXXXX_PINCONF_RT		BIT(23)
+#define STIXXXX_PINCONF_UNPACK_RT(conf)	STIXXXX_PINCONF_UNPACK(conf, RT)
+#define STIXXXX_PINCONF_PACK_RT(conf, val) STIXXXX_PINCONF_PACK(conf, val, RT)
+
+#define STIXXXX_PINCONF_RT_INVERTCLK_MASK	0x1
+#define STIXXXX_PINCONF_RT_INVERTCLK_SHIFT	22
+#define STIXXXX_PINCONF_RT_INVERTCLK		BIT(22)
+#define STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(conf) \
+			STIXXXX_PINCONF_UNPACK(conf, RT_INVERTCLK)
+#define STIXXXX_PINCONF_PACK_RT_INVERTCLK(conf, val) \
+			STIXXXX_PINCONF_PACK(conf, val, RT_INVERTCLK)
+
+#define STIXXXX_PINCONF_RT_CLKNOTDATA_MASK	0x1
+#define STIXXXX_PINCONF_RT_CLKNOTDATA_SHIFT	21
+#define STIXXXX_PINCONF_RT_CLKNOTDATA		BIT(21)
+#define STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(conf)	\
+				STIXXXX_PINCONF_UNPACK(conf, RT_CLKNOTDATA)
+#define STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_CLKNOTDATA)
+
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_MASK	0x1
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_SHIFT	20
+#define STIXXXX_PINCONF_RT_DOUBLE_EDGE		BIT(20)
+#define STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \
+				STIXXXX_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE)
+#define STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_DOUBLE_EDGE)
+
+#define STIXXXX_PINCONF_RT_CLK_MASK		0x3
+#define STIXXXX_PINCONF_RT_CLK_SHIFT		18
+#define STIXXXX_PINCONF_RT_CLK			BIT(18)
+#define STIXXXX_PINCONF_UNPACK_RT_CLK(conf)	\
+			STIXXXX_PINCONF_UNPACK(conf, RT_CLK)
+#define STIXXXX_PINCONF_PACK_RT_CLK(conf, val) \
+			STIXXXX_PINCONF_PACK(conf, val, RT_CLK)
+
+/* RETIME_DELAY in Pico Secs */
+#define STIXXXX_PINCONF_RT_DELAY_MASK		0xffff
+#define STIXXXX_PINCONF_RT_DELAY_SHIFT		0
+#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
+				STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
+#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
+				STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)
+
+#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?=
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:26     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 28873 bytes --]

The STiH415 is the next generation of HD, AVC set-top box processors for
satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
1.0 GHz, dual-core CPU.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/arm/stixxxx/overview.txt         |   33 +++
 Documentation/arm/stixxxx/stih415-overview.txt |   12 +
 MAINTAINERS                                    |   11 +
 arch/arm/Kconfig                               |    2 +
 arch/arm/Makefile                              |    1 +
 arch/arm/boot/dts/stih415-clock.dtsi           |   38 +++
 arch/arm/boot/dts/stih415-pinctrl.dtsi         |  326 ++++++++++++++++++++++++
 arch/arm/boot/dts/stih415.dtsi                 |  102 ++++++++
 arch/arm/boot/dts/stih41x.dtsi                 |   38 +++
 arch/arm/boot/dts/stixxxx-pincfg.h             |   94 +++++++
 arch/arm/mach-stixxxx/Kconfig                  |   45 ++++
 arch/arm/mach-stixxxx/Makefile                 |    2 +
 arch/arm/mach-stixxxx/board-dt.c               |   47 ++++
 arch/arm/mach-stixxxx/headsmp.S                |   44 ++++
 arch/arm/mach-stixxxx/platsmp.c                |  117 +++++++++
 arch/arm/mach-stixxxx/smp.h                    |   19 ++
 16 files changed, 931 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih415-overview.txt
 create mode 100644 arch/arm/boot/dts/stih415-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih415-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih415.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x.dtsi
 create mode 100644 arch/arm/boot/dts/stixxxx-pincfg.h
 create mode 100644 arch/arm/mach-stixxxx/Kconfig
 create mode 100644 arch/arm/mach-stixxxx/Makefile
 create mode 100644 arch/arm/mach-stixxxx/board-dt.c
 create mode 100644 arch/arm/mach-stixxxx/headsmp.S
 create mode 100644 arch/arm/mach-stixxxx/platsmp.c
 create mode 100644 arch/arm/mach-stixxxx/smp.h

diff --git a/Documentation/arm/stixxxx/overview.txt b/Documentation/arm/stixxxx/overview.txt
new file mode 100644
index 0000000..a2f6390
--- /dev/null
+++ b/Documentation/arm/stixxxx/overview.txt
@@ -0,0 +1,33 @@
+			STixxxx ARM Linux Overview
+			==========================
+
+Introduction
+------------
+
+  The ST Microelectronics Multimedia and Application Processors range of
+  CortexA9 System-on-Chip are supported by the 'STixxxx' platform of
+  ARM Linux. Currently STiH415, STiH416 SOCs are supported with both
+  B2000 and B2020 Reference boards.
+
+
+  configuration
+  -------------
+
+  A generic configuration is provided for both STiH415/416, and can be used as the
+  default by
+	make stih41x_defconfig
+
+  Layout
+  ------
+  All the files for multiple machine families (STiH415, STiH416, and STiG125)
+  are located in the platform code contained in arch/arm/mach-stixxxx
+
+  There is a generic board board-dt.c in the mach folder which support
+  Flattened Device Tree, which means, It works with any compatible board with
+  Device Trees.
+
+
+  Document Author
+  ---------------
+
+  Srinivas Kandagatla <srinivas.kandagatla@st.com>, (c) 2013 ST Microelectronics
diff --git a/Documentation/arm/stixxxx/stih415-overview.txt b/Documentation/arm/stixxxx/stih415-overview.txt
new file mode 100644
index 0000000..1c264b7
--- /dev/null
+++ b/Documentation/arm/stixxxx/stih415-overview.txt
@@ -0,0 +1,12 @@
+			STiH415 Overview
+			================
+
+Introduction
+------------
+
+    The STiH415 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.0 GHz, dual-core CPU
+    - SATA2×2,USB 2.0×3, PCIe, Gbit Ethernet MAC×2
diff --git a/MAINTAINERS b/MAINTAINERS
index 250dc97..2aca7d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1201,6 +1201,17 @@ M:	Dinh Nguyen <dinguyen@altera.com>
 S:	Maintained
 F:	drivers/clk/socfpga/
 
+ARM/STIXXXX ARCHITECTURE
+M:	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+M:	Stuart Menefy <stuart.menefy@st.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W:	http://www.stlinux.com
+S:	Maintained
+F:	arch/arm/mach-stixxxx/
+F:	drivers/pinctrl/pinctrl-stixxxx*
+F:	drivers/mfd/stixxxx-syscfg*
+F:	drivers/clocksource/global_timer.c
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993c..790e321 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -989,6 +989,8 @@ source "arch/arm/mach-socfpga/Kconfig"
 
 source "arch/arm/mach-spear/Kconfig"
 
+source "arch/arm/mach-stixxxx/Kconfig"
+
 source "arch/arm/mach-s3c24xx/Kconfig"
 
 if ARCH_S3C64XX
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1ba358b..c876e0a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -191,6 +191,7 @@ machine-$(CONFIG_ARCH_W90X900)		+= w90x900
 machine-$(CONFIG_FOOTBRIDGE)		+= footbridge
 machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
 machine-$(CONFIG_PLAT_SPEAR)		+= spear
+machine-$(CONFIG_ARCH_STIXXXX)		+= stixxxx
 machine-$(CONFIG_ARCH_VIRT)		+= virt
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
new file mode 100644
index 0000000..174c799
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-clock.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator input to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <500000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLKS_ICN_REG_0: CLKS_ICN_REG_0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi
new file mode 100644
index 0000000..c510f11
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stixxxx-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO5;
+		gpio6	= &PIO6;
+		gpio7	= &PIO7;
+		gpio8	= &PIO8;
+		gpio9	= &PIO9;
+		gpio10	= &PIO10;
+		gpio11	= &PIO11;
+		gpio12	= &PIO12;
+		gpio13	= &PIO13;
+		gpio14	= &PIO14;
+		gpio15	= &PIO15;
+		gpio16	= &PIO16;
+		gpio17	= &PIO17;
+		gpio18	= &PIO18;
+		gpio19	= &PIO100;
+		gpio20	= &PIO101;
+		gpio21	= &PIO102;
+		gpio22	= &PIO103;
+		gpio23	= &PIO104;
+		gpio24	= &PIO105;
+		gpio25	= &PIO106;
+		gpio26	= &PIO107;
+	};
+
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_sbc>;
+			st,syscfg-offsets	= <0 5 7 9 16>;
+			ranges;
+
+			PIO0: pinctrl@fe610000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe610000 0x100>;
+				st,bank-name	= "PIO0";
+			};
+
+			PIO1: pinctrl@fe611000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe611000 0x100>;
+				st,bank-name	= "PIO1";
+			};
+
+			PIO2: pinctrl@fe612000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe612000 0x100>;
+				st,bank-name	= "PIO2";
+			};
+
+			PIO3: pinctrl@fe613000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe613000 0x100>;
+				st,bank-name	= "PIO3";
+
+			};
+
+			PIO4: pinctrl@fe614000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe614000 0x100>;
+				st,bank-name	= "PIO4";
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1:sbc_serial1 {
+					st,function = <ALT3>;
+					st,pins {
+						tx	= <&PIO2 6 OUT>;
+						rx	= <&PIO2 7 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_front>;
+			st,syscfg-offsets	= <0 8 10 12 16>;
+			ranges;
+
+			PIO5: pinctrl@fee00000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee00000 0x100>;
+				st,bank-name	= "PIO5";
+			};
+			PIO6: pinctrl@fee01000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee01000 0x100>;
+				st,bank-name	= "PIO6";
+			};
+
+			PIO7: pinctrl@fee02000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee02000 0x100>;
+				st,bank-name	= "PIO7";
+			};
+			PIO8: pinctrl@fee03000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee03000 0x100>;
+				st,bank-name	= "PIO8";
+			};
+			PIO9: pinctrl@fee04000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee04000 0x100>;
+				st,bank-name	= "PIO9";
+			};
+			PIO10: pinctrl@fee05000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee05000 0x100>;
+				st,bank-name	= "PIO10";
+			};
+			PIO11: pinctrl@fee06000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee06000 0x100>;
+				st,bank-name	= "PIO11";
+			};
+			PIO12: pinctrl@fee07000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee07000 0x100>;
+				st,bank-name	= "PIO12";
+			};
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_rear>;
+			st,syscfg-offsets	= <0 6 8 10 38>;
+			ranges;
+
+			PIO13: pinctrl@fe820000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe820000 0x100>;
+				st,bank-name	= "PIO13";
+			};
+			PIO14: pinctrl@fe821000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe821000 0x100>;
+				st,bank-name	= "PIO14";
+			};
+			PIO15: pinctrl@fe822000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe822000 0x100>;
+				st,bank-name	= "PIO15";
+			};
+			PIO16: pinctrl@fe823000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe823000 0x100>;
+				st,bank-name	= "PIO16";
+
+			};
+			PIO17: pinctrl@fe824000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe824000 0x100>;
+				st,bank-name	= "PIO17";
+
+			};
+			PIO18: pinctrl@fe825000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe825000 0x100>;
+				st,bank-name	= "PIO18";
+
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,function = <ALT2>;
+					st,pins {
+						tx	= <&PIO17 4 OUT>;
+						rx	= <&PIO17 5 IN>;
+					};
+				};
+			};
+
+		};
+
+		pin-controller-left {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_left>;
+			st,syscfg-offsets	= <0 3 4 5 6>;
+			ranges;
+
+			PIO100: pinctrl@fd6b0000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b0000 0x100>;
+				st,bank-name	= "PIO100";
+			};
+			PIO101: pinctrl@fd6b1000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b1000 0x100>;
+				st,bank-name	= "PIO101";
+
+			};
+			PIO102: pinctrl@fd6b2000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b2000 0x100>;
+				st,bank-name	= "PIO102";
+
+			};
+
+		};
+
+		pin-controller-right {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_right>;
+			st,syscfg-offsets	= <0 5 7 9 11>;
+			ranges;
+
+			PIO103: pinctrl@fd330000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd330000 0x100>;
+				st,bank-name	= "PIO103";
+			};
+			PIO104: pinctrl@fd331000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd331000 0x100>;
+				st,bank-name	= "PIO104";
+			};
+			PIO105: pinctrl@fd332000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd332000 0x100>;
+				st,bank-name	= "PIO105";
+			};
+			PIO106: pinctrl@fd333000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd333000 0x100>;
+				st,bank-name	= "PIO106";
+			};
+			PIO107: pinctrl@fd334000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd334000 0x100>;
+				st,bank-name	= "PIO107";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
new file mode 100644
index 0000000..6dcf5b4
--- /dev/null
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih415-clock.dtsi"
+#include "stih415-pinctrl.dtsi"
+/ {
+
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 2 2>;
+		arm,tag-latency = <1 1 1>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc: syscfg@fe600000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe600000 0xb4>;
+			syscfg-range	= <0 44>;
+			syscfg-name	= "SYSCFG_SBC";
+		};
+
+		syscfg_front: syscfg@fee10000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfee10000 0x194>;
+			syscfg-range	= <100 100>;
+			syscfg-name	= "SYSCFG_FRONT";
+		};
+
+		syscfg_rear: syscfg@fe830000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe830000 0x190>;
+			syscfg-range	= <300 99>;
+			syscfg-name	= "SYSCFG_REAR";
+		};
+
+		/* MPE syscfgs */
+		syscfg_left: syscfg@fd690000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfd690000 0x78>;
+			syscfg-range 	= <400 29>;
+			syscfg-name	= "SYSCFG_LEFT";
+		};
+
+		syscfg_right: syscfg@fd320000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfd320000 0x180>;
+			syscfg-range	= <500 95>;
+			syscfg-name	= "SYSCFG_RIGHT";
+		};
+
+		syscfg_system: syscfg@fdde0000  {
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfdde0000 0x15c>;
+			syscfg-range	= <600 86>;
+			syscfg-name	= "SYSCFG_SYSTEM";
+		};
+
+		syscfg_lpm: syscfg@fe4b5100{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe4b5100 0x08>;
+			syscfg-range	= <0 10>;
+			syscfg-name	= "LPM_CFG_REGS";
+		};
+
+		serial2: serial@fed32000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2>;
+			clocks		= <&CLKS_ICN_REG_0>;
+		};
+
+		/* SBC comms block ASCs in SASG1 */
+		sbc_serial1: serial@fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			clocks		= <&CLK_SYSIN>;
+			pinctrl-names 	= "default";
+			pinctrl-0	= <&pinctrl_sbc_serial1>;
+		};
+
+	};
+};
diff --git a/arch/arm/boot/dts/stih41x.dtsi b/arch/arm/boot/dts/stih41x.dtsi
new file mode 100644
index 0000000..7321403
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x.dtsi
@@ -0,0 +1,38 @@
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+		cpu@1 {
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	intc: interrupt-controller@fffe1000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xfffe1000 0x1000>,
+		      <0xfffe0100 0x100>;
+	};
+
+	scu@fffe0000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0xfffe0000 0x1000>;
+	};
+
+	timer@fffe0200 {
+		interrupt-parent = <&intc>;
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0xfffe0200 0x100>;
+		interrupts = <1 11 0x04>;
+		clocks = <&arm_periph_clk>;
+	};
+};
diff --git a/arch/arm/boot/dts/stixxxx-pincfg.h b/arch/arm/boot/dts/stixxxx-pincfg.h
new file mode 100644
index 0000000..0dfaba0
--- /dev/null
+++ b/arch/arm/boot/dts/stixxxx-pincfg.h
@@ -0,0 +1,94 @@
+#ifndef _STIXXXX_PINCFG_H_
+#define _STIXXXX_PINCFG_H_
+
+/* Alternate functions */
+#define ALT1	1
+#define ALT2	2
+#define ALT3	3
+#define ALT4	4
+#define ALT5	5
+#define ALT6	6
+#define ALT7	7
+
+/* Output enable */
+#define OE_MASK			0x1
+#define OE_SHIFT		27
+#define OE			(1 << OE_SHIFT)
+
+/* Pull Up */
+#define PU_MASK			0x1
+#define PU_SHIFT		26
+#define PU			(1 << PU_SHIFT)
+
+/* Open Drain */
+#define OD_MASK			0x1
+#define OD_SHIFT		25
+#define OD			(1 << OD_SHIFT)
+
+#define RT_MASK			0x1
+#define RT_SHIFT		23
+#define RT			(1 << RT_SHIFT)
+
+#define INVERTCLK_MASK		0x1
+#define INVERTCLK_SHIFT		22
+#define INVERTCLK		(1 << INVERTCLK_SHIFT)
+
+#define CLKNOTDATA_MASK		0x1
+#define CLKNOTDATA_SHIFT	21
+#define CLKNOTDATA		(1 << CLKNOTDATA_SHIFT)
+
+#define DOUBLE_EDGE_MASK	 0x1
+#define DOUBLE_EDGE_SHIFT	 20
+#define DOUBLE_EDGE		(1 << DOUBLE_EDGE_SHIFT)
+
+#define CLK_MASK		0x3
+#define CLK_SHIFT		18
+#define CLK_A			(0 << CLK_SHIFT)
+#define CLK_B			(1 << CLK_SHIFT)
+#define CLK_C			(2 << CLK_SHIFT)
+#define CLK_D			(3 << CLK_SHIFT)
+
+/* User-frendly defines for Pin Direction */
+		/* oe = 0, pu = 0, od = 0 */
+#define IN			(0)
+		/* oe = 0, pu = 1, od = 0 */
+#define IN_PU			(PU)
+		/* oe = 1, pu = 0, od = 0 */
+#define OUT			(OE)
+		/* oe = 1, pu = 0, od = 1 */
+#define BIDIR			(OE | OD)
+		/* oe = 1, pu = 1, od = 1 */
+#define BIDIR_PU		(OE | PU | OD)
+
+/* RETIME_TYPE */
+/*
+ * B Mode
+ * Bypass retime with optional delay parameter
+ */
+#define BYPASS		(0)
+/*
+ * R0, R1, R0D, R1D modes
+ * single-edge data non inverted clock, retime data with clk
+ */
+#define SE_NICLK_IO	(RT)
+/*
+ * RIV0, RIV1, RIV0D, RIV1D modes
+ * single-edge data inverted clock, retime data with clk
+ */
+#define SE_ICLK_IO	(RT | INVERTCLK)
+/*
+ * R0E, R1E, R0ED, R1ED modes
+ * double-edge data, retime data with clk
+ */
+#define DE_IO		(RT | DOUBLE_EDGE)
+/*
+ * CIV0, CIV1 modes with inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define ICLK		(RT | CLKNOTDATA | INVERTCLK)
+/*
+ * CLK0, CLK1 modes with non-inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define NICLK		(RT | CLKNOTDATA)
+#endif /* _STIXXXX_PINCFG_H_ */
diff --git a/arch/arm/mach-stixxxx/Kconfig b/arch/arm/mach-stixxxx/Kconfig
new file mode 100644
index 0000000..278d938
--- /dev/null
+++ b/arch/arm/mach-stixxxx/Kconfig
@@ -0,0 +1,45 @@
+menuconfig ARCH_STIXXXX
+	bool "STMicroelectronics Consumer Electronics SOCs with Device Trees" if ARCH_MULTI_V7
+	select GENERIC_CLOCKEVENTS
+	select CLKDEV_LOOKUP
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select MFD_STIXXXX_SYSCFG
+	select PINCTRL
+	select PINCTRL_STIXXXX
+	select MIGHT_HAVE_CACHE_L2X0
+	select HAVE_SMP
+	select HAVE_ARM_SCU if SMP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_ERRATA_720789
+	select ARM_ERRATA_754322
+	select PL310_ERRATA_753970
+	select PL310_ERRATA_769419
+	help
+	  Include support for STiH41x SOCs like STiH415/416 using the device tree
+	  for discovery
+	  More information at Documentation/arm/STiH41x and
+	  at Documentation/devicetree
+
+
+if ARCH_STIXXXX
+
+config SOC_STIH415
+	bool "STiH415 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH415 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattned Device
+	  Trees.
+
+config SOC_STIH416
+	bool "STiH416 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH416 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattened Device
+	  Trees.
+
+endif
diff --git a/arch/arm/mach-stixxxx/Makefile b/arch/arm/mach-stixxxx/Makefile
new file mode 100644
index 0000000..50bf128
--- /dev/null
+++ b/arch/arm/mach-stixxxx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
+obj-$(CONFIG_ARCH_STIXXXX) 		+= board-dt.o
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
new file mode 100644
index 0000000..52ce665
--- /dev/null
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author(s): Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irq.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+
+#include "smp.h"
+
+void __init stih41x_l2x0_init(void)
+{
+	u32 way_size = 0x4;
+	u32 aux_ctrl;
+
+	aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
+		(way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+
+	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+}
+
+static void __init stih41x_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+	stih41x_l2x0_init();
+}
+
+static const char *stih41x_dt_match[] __initdata = {
+	"st,stih415",
+	NULL
+};
+
+DT_MACHINE_START(STM, "STiH415 SoC with Flattened Device Tree")
+	.init_time	= stih41x_timer_init,
+	.smp		= smp_ops(stixxxx_smp_ops),
+	.dt_compat	= stih41x_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-stixxxx/headsmp.S b/arch/arm/mach-stixxxx/headsmp.S
new file mode 100644
index 0000000..3dd5c04
--- /dev/null
+++ b/arch/arm/mach-stixxxx/headsmp.S
@@ -0,0 +1,44 @@
+/*
+ *  arch/arm/plat-stixxxx/headsmp.S
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * ST specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(stixxxx_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-stixxxx/platsmp.c b/arch/arm/mach-stixxxx/platsmp.c
new file mode 100644
index 0000000..ffc40c0
--- /dev/null
+++ b/arch/arm/mach-stixxxx/platsmp.c
@@ -0,0 +1,117 @@
+/*
+ *  arch/arm/plat-stixxxx/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "smp.h"
+
+static void __cpuinit write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit stixxxx_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit stixxxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu_logical_map(cpu));
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * it to jump to the secondary entrypoint.
+	 */
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+void __init stixxxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+	void __iomem *scu_base = NULL;
+	struct device_node *np = of_find_compatible_node(
+					NULL, NULL, "arm,cortex-a9-scu");
+	if (np) {
+		scu_base = of_iomap(np, 0);
+		scu_enable(scu_base);
+		of_node_put(np);
+	}
+}
+
+struct smp_operations __initdata stixxxx_smp_ops = {
+	.smp_prepare_cpus	= stixxxx_smp_prepare_cpus,
+	.smp_secondary_init	= stixxxx_secondary_init,
+	.smp_boot_secondary	= stixxxx_boot_secondary,
+};
diff --git a/arch/arm/mach-stixxxx/smp.h b/arch/arm/mach-stixxxx/smp.h
new file mode 100644
index 0000000..c3e3d40
--- /dev/null
+++ b/arch/arm/mach-stixxxx/smp.h
@@ -0,0 +1,19 @@
+/*
+ *  arch/arm/plat-stixxxx/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_SMP_H
+#define __PLAT_SMP_H
+
+extern struct smp_operations	stixxxx_smp_ops;
+extern void __iomem *stixxxx_scu_base_addr;
+extern void stixxxx_secondary_startup(void);
+
+#endif
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?=
@ 2013-06-10  9:26     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 30159 bytes --]

The STiH415 is the next generation of HD, AVC set-top box processors for
satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
1.0 GHz, dual-core CPU.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/arm/stixxxx/overview.txt         |   33 +++
 Documentation/arm/stixxxx/stih415-overview.txt |   12 +
 MAINTAINERS                                    |   11 +
 arch/arm/Kconfig                               |    2 +
 arch/arm/Makefile                              |    1 +
 arch/arm/boot/dts/stih415-clock.dtsi           |   38 +++
 arch/arm/boot/dts/stih415-pinctrl.dtsi         |  326 ++++++++++++++++++++++++
 arch/arm/boot/dts/stih415.dtsi                 |  102 ++++++++
 arch/arm/boot/dts/stih41x.dtsi                 |   38 +++
 arch/arm/boot/dts/stixxxx-pincfg.h             |   94 +++++++
 arch/arm/mach-stixxxx/Kconfig                  |   45 ++++
 arch/arm/mach-stixxxx/Makefile                 |    2 +
 arch/arm/mach-stixxxx/board-dt.c               |   47 ++++
 arch/arm/mach-stixxxx/headsmp.S                |   44 ++++
 arch/arm/mach-stixxxx/platsmp.c                |  117 +++++++++
 arch/arm/mach-stixxxx/smp.h                    |   19 ++
 16 files changed, 931 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/overview.txt
 create mode 100644 Documentation/arm/stixxxx/stih415-overview.txt
 create mode 100644 arch/arm/boot/dts/stih415-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih415-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih415.dtsi
 create mode 100644 arch/arm/boot/dts/stih41x.dtsi
 create mode 100644 arch/arm/boot/dts/stixxxx-pincfg.h
 create mode 100644 arch/arm/mach-stixxxx/Kconfig
 create mode 100644 arch/arm/mach-stixxxx/Makefile
 create mode 100644 arch/arm/mach-stixxxx/board-dt.c
 create mode 100644 arch/arm/mach-stixxxx/headsmp.S
 create mode 100644 arch/arm/mach-stixxxx/platsmp.c
 create mode 100644 arch/arm/mach-stixxxx/smp.h

diff --git a/Documentation/arm/stixxxx/overview.txt b/Documentation/arm/stixxxx/overview.txt
new file mode 100644
index 0000000..a2f6390
--- /dev/null
+++ b/Documentation/arm/stixxxx/overview.txt
@@ -0,0 +1,33 @@
+			STixxxx ARM Linux Overview
+			==========================
+
+Introduction
+------------
+
+  The ST Microelectronics Multimedia and Application Processors range of
+  CortexA9 System-on-Chip are supported by the 'STixxxx' platform of
+  ARM Linux. Currently STiH415, STiH416 SOCs are supported with both
+  B2000 and B2020 Reference boards.
+
+
+  configuration
+  -------------
+
+  A generic configuration is provided for both STiH415/416, and can be used as the
+  default by
+	make stih41x_defconfig
+
+  Layout
+  ------
+  All the files for multiple machine families (STiH415, STiH416, and STiG125)
+  are located in the platform code contained in arch/arm/mach-stixxxx
+
+  There is a generic board board-dt.c in the mach folder which support
+  Flattened Device Tree, which means, It works with any compatible board with
+  Device Trees.
+
+
+  Document Author
+  ---------------
+
+  Srinivas Kandagatla <srinivas.kandagatla@st.com>, (c) 2013 ST Microelectronics
diff --git a/Documentation/arm/stixxxx/stih415-overview.txt b/Documentation/arm/stixxxx/stih415-overview.txt
new file mode 100644
index 0000000..1c264b7
--- /dev/null
+++ b/Documentation/arm/stixxxx/stih415-overview.txt
@@ -0,0 +1,12 @@
+			STiH415 Overview
+			================
+
+Introduction
+------------
+
+    The STiH415 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.0 GHz, dual-core CPU
+    - SATA2×2,USB 2.0×3, PCIe, Gbit Ethernet MAC×2
diff --git a/MAINTAINERS b/MAINTAINERS
index 250dc97..2aca7d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1201,6 +1201,17 @@ M:	Dinh Nguyen <dinguyen@altera.com>
 S:	Maintained
 F:	drivers/clk/socfpga/
 
+ARM/STIXXXX ARCHITECTURE
+M:	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+M:	Stuart Menefy <stuart.menefy@st.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W:	http://www.stlinux.com
+S:	Maintained
+F:	arch/arm/mach-stixxxx/
+F:	drivers/pinctrl/pinctrl-stixxxx*
+F:	drivers/mfd/stixxxx-syscfg*
+F:	drivers/clocksource/global_timer.c
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 49d993c..790e321 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -989,6 +989,8 @@ source "arch/arm/mach-socfpga/Kconfig"
 
 source "arch/arm/mach-spear/Kconfig"
 
+source "arch/arm/mach-stixxxx/Kconfig"
+
 source "arch/arm/mach-s3c24xx/Kconfig"
 
 if ARCH_S3C64XX
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1ba358b..c876e0a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -191,6 +191,7 @@ machine-$(CONFIG_ARCH_W90X900)		+= w90x900
 machine-$(CONFIG_FOOTBRIDGE)		+= footbridge
 machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
 machine-$(CONFIG_PLAT_SPEAR)		+= spear
+machine-$(CONFIG_ARCH_STIXXXX)		+= stixxxx
 machine-$(CONFIG_ARCH_VIRT)		+= virt
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
diff --git a/arch/arm/boot/dts/stih415-clock.dtsi b/arch/arm/boot/dts/stih415-clock.dtsi
new file mode 100644
index 0000000..174c799
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-clock.dtsi
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator input to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <500000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLKS_ICN_REG_0: CLKS_ICN_REG_0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi
new file mode 100644
index 0000000..c510f11
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stixxxx-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO5;
+		gpio6	= &PIO6;
+		gpio7	= &PIO7;
+		gpio8	= &PIO8;
+		gpio9	= &PIO9;
+		gpio10	= &PIO10;
+		gpio11	= &PIO11;
+		gpio12	= &PIO12;
+		gpio13	= &PIO13;
+		gpio14	= &PIO14;
+		gpio15	= &PIO15;
+		gpio16	= &PIO16;
+		gpio17	= &PIO17;
+		gpio18	= &PIO18;
+		gpio19	= &PIO100;
+		gpio20	= &PIO101;
+		gpio21	= &PIO102;
+		gpio22	= &PIO103;
+		gpio23	= &PIO104;
+		gpio24	= &PIO105;
+		gpio25	= &PIO106;
+		gpio26	= &PIO107;
+	};
+
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_sbc>;
+			st,syscfg-offsets	= <0 5 7 9 16>;
+			ranges;
+
+			PIO0: pinctrl@fe610000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe610000 0x100>;
+				st,bank-name	= "PIO0";
+			};
+
+			PIO1: pinctrl@fe611000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe611000 0x100>;
+				st,bank-name	= "PIO1";
+			};
+
+			PIO2: pinctrl@fe612000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe612000 0x100>;
+				st,bank-name	= "PIO2";
+			};
+
+			PIO3: pinctrl@fe613000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe613000 0x100>;
+				st,bank-name	= "PIO3";
+
+			};
+
+			PIO4: pinctrl@fe614000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe614000 0x100>;
+				st,bank-name	= "PIO4";
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1:sbc_serial1 {
+					st,function = <ALT3>;
+					st,pins {
+						tx	= <&PIO2 6 OUT>;
+						rx	= <&PIO2 7 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_front>;
+			st,syscfg-offsets	= <0 8 10 12 16>;
+			ranges;
+
+			PIO5: pinctrl@fee00000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee00000 0x100>;
+				st,bank-name	= "PIO5";
+			};
+			PIO6: pinctrl@fee01000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee01000 0x100>;
+				st,bank-name	= "PIO6";
+			};
+
+			PIO7: pinctrl@fee02000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee02000 0x100>;
+				st,bank-name	= "PIO7";
+			};
+			PIO8: pinctrl@fee03000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee03000 0x100>;
+				st,bank-name	= "PIO8";
+			};
+			PIO9: pinctrl@fee04000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee04000 0x100>;
+				st,bank-name	= "PIO9";
+			};
+			PIO10: pinctrl@fee05000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee05000 0x100>;
+				st,bank-name	= "PIO10";
+			};
+			PIO11: pinctrl@fee06000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee06000 0x100>;
+				st,bank-name	= "PIO11";
+			};
+			PIO12: pinctrl@fee07000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfee07000 0x100>;
+				st,bank-name	= "PIO12";
+			};
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_rear>;
+			st,syscfg-offsets	= <0 6 8 10 38>;
+			ranges;
+
+			PIO13: pinctrl@fe820000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe820000 0x100>;
+				st,bank-name	= "PIO13";
+			};
+			PIO14: pinctrl@fe821000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe821000 0x100>;
+				st,bank-name	= "PIO14";
+			};
+			PIO15: pinctrl@fe822000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe822000 0x100>;
+				st,bank-name	= "PIO15";
+			};
+			PIO16: pinctrl@fe823000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe823000 0x100>;
+				st,bank-name	= "PIO16";
+
+			};
+			PIO17: pinctrl@fe824000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe824000 0x100>;
+				st,bank-name	= "PIO17";
+
+			};
+			PIO18: pinctrl@fe825000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfe825000 0x100>;
+				st,bank-name	= "PIO18";
+
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,function = <ALT2>;
+					st,pins {
+						tx	= <&PIO17 4 OUT>;
+						rx	= <&PIO17 5 IN>;
+					};
+				};
+			};
+
+		};
+
+		pin-controller-left {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_left>;
+			st,syscfg-offsets	= <0 3 4 5 6>;
+			ranges;
+
+			PIO100: pinctrl@fd6b0000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b0000 0x100>;
+				st,bank-name	= "PIO100";
+			};
+			PIO101: pinctrl@fd6b1000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b1000 0x100>;
+				st,bank-name	= "PIO101";
+
+			};
+			PIO102: pinctrl@fd6b2000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd6b2000 0x100>;
+				st,bank-name	= "PIO102";
+
+			};
+
+		};
+
+		pin-controller-right {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 500 1000 1500>;
+			st,retime-out-delay	= <0 1000 2000 3000>;
+			st,syscfg		= <&syscfg_right>;
+			st,syscfg-offsets	= <0 5 7 9 11>;
+			ranges;
+
+			PIO103: pinctrl@fd330000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd330000 0x100>;
+				st,bank-name	= "PIO103";
+			};
+			PIO104: pinctrl@fd331000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd331000 0x100>;
+				st,bank-name	= "PIO104";
+			};
+			PIO105: pinctrl@fd332000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd332000 0x100>;
+				st,bank-name	= "PIO105";
+			};
+			PIO106: pinctrl@fd333000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd333000 0x100>;
+				st,bank-name	= "PIO106";
+			};
+			PIO107: pinctrl@fd334000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				reg	= <0xfd334000 0x100>;
+				st,bank-name	= "PIO107";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
new file mode 100644
index 0000000..6dcf5b4
--- /dev/null
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih415-clock.dtsi"
+#include "stih415-pinctrl.dtsi"
+/ {
+
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 2 2>;
+		arm,tag-latency = <1 1 1>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc: syscfg@fe600000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe600000 0xb4>;
+			syscfg-range	= <0 44>;
+			syscfg-name	= "SYSCFG_SBC";
+		};
+
+		syscfg_front: syscfg@fee10000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfee10000 0x194>;
+			syscfg-range	= <100 100>;
+			syscfg-name	= "SYSCFG_FRONT";
+		};
+
+		syscfg_rear: syscfg@fe830000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe830000 0x190>;
+			syscfg-range	= <300 99>;
+			syscfg-name	= "SYSCFG_REAR";
+		};
+
+		/* MPE syscfgs */
+		syscfg_left: syscfg@fd690000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfd690000 0x78>;
+			syscfg-range 	= <400 29>;
+			syscfg-name	= "SYSCFG_LEFT";
+		};
+
+		syscfg_right: syscfg@fd320000{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfd320000 0x180>;
+			syscfg-range	= <500 95>;
+			syscfg-name	= "SYSCFG_RIGHT";
+		};
+
+		syscfg_system: syscfg@fdde0000  {
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfdde0000 0x15c>;
+			syscfg-range	= <600 86>;
+			syscfg-name	= "SYSCFG_SYSTEM";
+		};
+
+		syscfg_lpm: syscfg@fe4b5100{
+			compatible      = "st,stih415-syscfg";
+			reg		= <0xfe4b5100 0x08>;
+			syscfg-range	= <0 10>;
+			syscfg-name	= "LPM_CFG_REGS";
+		};
+
+		serial2: serial@fed32000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2>;
+			clocks		= <&CLKS_ICN_REG_0>;
+		};
+
+		/* SBC comms block ASCs in SASG1 */
+		sbc_serial1: serial@fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			clocks		= <&CLK_SYSIN>;
+			pinctrl-names 	= "default";
+			pinctrl-0	= <&pinctrl_sbc_serial1>;
+		};
+
+	};
+};
diff --git a/arch/arm/boot/dts/stih41x.dtsi b/arch/arm/boot/dts/stih41x.dtsi
new file mode 100644
index 0000000..7321403
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x.dtsi
@@ -0,0 +1,38 @@
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+		cpu@1 {
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	intc: interrupt-controller@fffe1000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xfffe1000 0x1000>,
+		      <0xfffe0100 0x100>;
+	};
+
+	scu@fffe0000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0xfffe0000 0x1000>;
+	};
+
+	timer@fffe0200 {
+		interrupt-parent = <&intc>;
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0xfffe0200 0x100>;
+		interrupts = <1 11 0x04>;
+		clocks = <&arm_periph_clk>;
+	};
+};
diff --git a/arch/arm/boot/dts/stixxxx-pincfg.h b/arch/arm/boot/dts/stixxxx-pincfg.h
new file mode 100644
index 0000000..0dfaba0
--- /dev/null
+++ b/arch/arm/boot/dts/stixxxx-pincfg.h
@@ -0,0 +1,94 @@
+#ifndef _STIXXXX_PINCFG_H_
+#define _STIXXXX_PINCFG_H_
+
+/* Alternate functions */
+#define ALT1	1
+#define ALT2	2
+#define ALT3	3
+#define ALT4	4
+#define ALT5	5
+#define ALT6	6
+#define ALT7	7
+
+/* Output enable */
+#define OE_MASK			0x1
+#define OE_SHIFT		27
+#define OE			(1 << OE_SHIFT)
+
+/* Pull Up */
+#define PU_MASK			0x1
+#define PU_SHIFT		26
+#define PU			(1 << PU_SHIFT)
+
+/* Open Drain */
+#define OD_MASK			0x1
+#define OD_SHIFT		25
+#define OD			(1 << OD_SHIFT)
+
+#define RT_MASK			0x1
+#define RT_SHIFT		23
+#define RT			(1 << RT_SHIFT)
+
+#define INVERTCLK_MASK		0x1
+#define INVERTCLK_SHIFT		22
+#define INVERTCLK		(1 << INVERTCLK_SHIFT)
+
+#define CLKNOTDATA_MASK		0x1
+#define CLKNOTDATA_SHIFT	21
+#define CLKNOTDATA		(1 << CLKNOTDATA_SHIFT)
+
+#define DOUBLE_EDGE_MASK	 0x1
+#define DOUBLE_EDGE_SHIFT	 20
+#define DOUBLE_EDGE		(1 << DOUBLE_EDGE_SHIFT)
+
+#define CLK_MASK		0x3
+#define CLK_SHIFT		18
+#define CLK_A			(0 << CLK_SHIFT)
+#define CLK_B			(1 << CLK_SHIFT)
+#define CLK_C			(2 << CLK_SHIFT)
+#define CLK_D			(3 << CLK_SHIFT)
+
+/* User-frendly defines for Pin Direction */
+		/* oe = 0, pu = 0, od = 0 */
+#define IN			(0)
+		/* oe = 0, pu = 1, od = 0 */
+#define IN_PU			(PU)
+		/* oe = 1, pu = 0, od = 0 */
+#define OUT			(OE)
+		/* oe = 1, pu = 0, od = 1 */
+#define BIDIR			(OE | OD)
+		/* oe = 1, pu = 1, od = 1 */
+#define BIDIR_PU		(OE | PU | OD)
+
+/* RETIME_TYPE */
+/*
+ * B Mode
+ * Bypass retime with optional delay parameter
+ */
+#define BYPASS		(0)
+/*
+ * R0, R1, R0D, R1D modes
+ * single-edge data non inverted clock, retime data with clk
+ */
+#define SE_NICLK_IO	(RT)
+/*
+ * RIV0, RIV1, RIV0D, RIV1D modes
+ * single-edge data inverted clock, retime data with clk
+ */
+#define SE_ICLK_IO	(RT | INVERTCLK)
+/*
+ * R0E, R1E, R0ED, R1ED modes
+ * double-edge data, retime data with clk
+ */
+#define DE_IO		(RT | DOUBLE_EDGE)
+/*
+ * CIV0, CIV1 modes with inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define ICLK		(RT | CLKNOTDATA | INVERTCLK)
+/*
+ * CLK0, CLK1 modes with non-inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define NICLK		(RT | CLKNOTDATA)
+#endif /* _STIXXXX_PINCFG_H_ */
diff --git a/arch/arm/mach-stixxxx/Kconfig b/arch/arm/mach-stixxxx/Kconfig
new file mode 100644
index 0000000..278d938
--- /dev/null
+++ b/arch/arm/mach-stixxxx/Kconfig
@@ -0,0 +1,45 @@
+menuconfig ARCH_STIXXXX
+	bool "STMicroelectronics Consumer Electronics SOCs with Device Trees" if ARCH_MULTI_V7
+	select GENERIC_CLOCKEVENTS
+	select CLKDEV_LOOKUP
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select MFD_STIXXXX_SYSCFG
+	select PINCTRL
+	select PINCTRL_STIXXXX
+	select MIGHT_HAVE_CACHE_L2X0
+	select HAVE_SMP
+	select HAVE_ARM_SCU if SMP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_ERRATA_720789
+	select ARM_ERRATA_754322
+	select PL310_ERRATA_753970
+	select PL310_ERRATA_769419
+	help
+	  Include support for STiH41x SOCs like STiH415/416 using the device tree
+	  for discovery
+	  More information at Documentation/arm/STiH41x and
+	  at Documentation/devicetree
+
+
+if ARCH_STIXXXX
+
+config SOC_STIH415
+	bool "STiH415 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH415 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattned Device
+	  Trees.
+
+config SOC_STIH416
+	bool "STiH416 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH416 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattened Device
+	  Trees.
+
+endif
diff --git a/arch/arm/mach-stixxxx/Makefile b/arch/arm/mach-stixxxx/Makefile
new file mode 100644
index 0000000..50bf128
--- /dev/null
+++ b/arch/arm/mach-stixxxx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
+obj-$(CONFIG_ARCH_STIXXXX) 		+= board-dt.o
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
new file mode 100644
index 0000000..52ce665
--- /dev/null
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author(s): Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irq.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+
+#include "smp.h"
+
+void __init stih41x_l2x0_init(void)
+{
+	u32 way_size = 0x4;
+	u32 aux_ctrl;
+
+	aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
+		(way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+
+	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+}
+
+static void __init stih41x_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+	stih41x_l2x0_init();
+}
+
+static const char *stih41x_dt_match[] __initdata = {
+	"st,stih415",
+	NULL
+};
+
+DT_MACHINE_START(STM, "STiH415 SoC with Flattened Device Tree")
+	.init_time	= stih41x_timer_init,
+	.smp		= smp_ops(stixxxx_smp_ops),
+	.dt_compat	= stih41x_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-stixxxx/headsmp.S b/arch/arm/mach-stixxxx/headsmp.S
new file mode 100644
index 0000000..3dd5c04
--- /dev/null
+++ b/arch/arm/mach-stixxxx/headsmp.S
@@ -0,0 +1,44 @@
+/*
+ *  arch/arm/plat-stixxxx/headsmp.S
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * ST specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(stixxxx_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-stixxxx/platsmp.c b/arch/arm/mach-stixxxx/platsmp.c
new file mode 100644
index 0000000..ffc40c0
--- /dev/null
+++ b/arch/arm/mach-stixxxx/platsmp.c
@@ -0,0 +1,117 @@
+/*
+ *  arch/arm/plat-stixxxx/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "smp.h"
+
+static void __cpuinit write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit stixxxx_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit stixxxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu_logical_map(cpu));
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * it to jump to the secondary entrypoint.
+	 */
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+void __init stixxxx_smp_prepare_cpus(unsigned int max_cpus)
+{
+	void __iomem *scu_base = NULL;
+	struct device_node *np = of_find_compatible_node(
+					NULL, NULL, "arm,cortex-a9-scu");
+	if (np) {
+		scu_base = of_iomap(np, 0);
+		scu_enable(scu_base);
+		of_node_put(np);
+	}
+}
+
+struct smp_operations __initdata stixxxx_smp_ops = {
+	.smp_prepare_cpus	= stixxxx_smp_prepare_cpus,
+	.smp_secondary_init	= stixxxx_secondary_init,
+	.smp_boot_secondary	= stixxxx_boot_secondary,
+};
diff --git a/arch/arm/mach-stixxxx/smp.h b/arch/arm/mach-stixxxx/smp.h
new file mode 100644
index 0000000..c3e3d40
--- /dev/null
+++ b/arch/arm/mach-stixxxx/smp.h
@@ -0,0 +1,19 @@
+/*
+ *  arch/arm/plat-stixxxx/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_SMP_H
+#define __PLAT_SMP_H
+
+extern struct smp_operations	stixxxx_smp_ops;
+extern void __iomem *stixxxx_scu_base_addr;
+extern void stixxxx_secondary_startup(void);
+
+#endif
-- 
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

The STiH416 is advanced HD AVC processor with 3D graphics acceleration
and 1.2-GHz ARM Cortex-A9 SMP CPU.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/arm/stixxxx/stih416-overview.txt |   12 +
 arch/arm/boot/dts/stih416-clock.dtsi           |   41 +++
 arch/arm/boot/dts/stih416-pinctrl.dtsi         |  377 ++++++++++++++++++++++++
 arch/arm/boot/dts/stih416.dtsi                 |  111 +++++++
 arch/arm/mach-stixxxx/board-dt.c               |    3 +-
 5 files changed, 543 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/stih416-overview.txt
 create mode 100644 arch/arm/boot/dts/stih416-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih416.dtsi

diff --git a/Documentation/arm/stixxxx/stih416-overview.txt b/Documentation/arm/stixxxx/stih416-overview.txt
new file mode 100644
index 0000000..e060867
--- /dev/null
+++ b/Documentation/arm/stixxxx/stih416-overview.txt
@@ -0,0 +1,12 @@
+			STiH416 Overview
+			================
+
+Introduction
+------------
+
+    The STiH416 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.2 GHz dual core CPU
+    - SATA2×2,USB 2.0×3, PCIe, Gbit Ethernet MAC×2
diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
new file mode 100644
index 0000000..7026bf1
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-clock.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ * <stlinux-devel@stlinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator inputs to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+			clock-output-names = "CLK_SYSIN";
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <600000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLK_S_ICN_REG_0: clockgenA0@4 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+			clock-output-names = "CLK_S_ICN_REG_0";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi
new file mode 100644
index 0000000..15843a9
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi
@@ -0,0 +1,377 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stixxxx-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO40;
+		gpio6	= &PIO5;
+		gpio7	= &PIO6;
+		gpio8	= &PIO7;
+		gpio9	= &PIO8;
+		gpio10	= &PIO9;
+		gpio11	= &PIO10;
+		gpio12	= &PIO11;
+		gpio13	= &PIO12;
+		gpio14	= &PIO30;
+		gpio15	= &PIO31;
+		gpio16	= &PIO13;
+		gpio17	= &PIO14;
+		gpio18	= &PIO15;
+		gpio19	= &PIO16;
+		gpio20	= &PIO17;
+		gpio21	= &PIO18;
+		gpio22	= &PIO100;
+		gpio23	= &PIO101;
+		gpio24	= &PIO102;
+		gpio25	= &PIO103;
+		gpio26	= &PIO104;
+		gpio27	= &PIO105;
+		gpio28	= &PIO106;
+		gpio29	= &PIO107;
+	};
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_sbc>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+			PIO0: pinctrl@fe610000 {
+				#gpio-cells = <1>;
+				compatible = "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe610000 0x100>;
+				st,bank-name  = "PIO0";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO1: pinctrl@fe611000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe611000 0x100>;
+				st,bank-name  = "PIO1";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO2: pinctrl@fe612000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe612000 0x100>;
+				st,bank-name  = "PIO2";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO3: pinctrl@fe613000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe613000 0x100>;
+				st,bank-name  = "PIO3";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO4: pinctrl@fe614000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe614000 0x100>;
+				st,bank-name  = "PIO4";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO40: pinctrl@fe615000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe615000 0x100>;
+				st,bank-name  = "PIO40";
+				st,retime-pin-mask = <0x7f>;
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1: sbc_serial1 {
+					st,function = <ALT3>;
+					st,pins {
+						tx	= <&PIO2 6 OUT>;
+						rx	= <&PIO2 7 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_front>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO5: pinctrl@fee00000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee00000 0x100>;
+				st,bank-name  = "PIO5";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO6: pinctrl@fee01000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee01000 0x100>;
+				st,bank-name  = "PIO6";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO7: pinctrl@fee02000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee02000 0x100>;
+				st,bank-name  = "PIO7";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO8: pinctrl@fee03000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee03000 0x100>;
+				st,bank-name  = "PIO8";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO9: pinctrl@fee04000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee04000 0x100>;
+				st,bank-name  = "PIO9";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO10: pinctrl@fee05000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee05000 0x100>;
+				st,bank-name  = "PIO10";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO11: pinctrl@fee06000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee06000 0x100>;
+				st,bank-name  = "PIO11";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO12: pinctrl@fee07000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee07000 0x100>;
+				st,bank-name  = "PIO12";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO30: pinctrl@fee08000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee08000 0x100>;
+				st,bank-name  = "PIO30";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO31: pinctrl@fee09000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee09000 0x100>;
+				st,bank-name  = "PIO31";
+				st,retime-pin-mask = <0xff>;
+			};
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_rear>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO13: pinctrl@fe820000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe820000 0x100>;
+				st,bank-name  = "PIO13";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO14: pinctrl@fe821000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe821000 0x100>;
+				st,bank-name  = "PIO14";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO15: pinctrl@fe822000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe822000 0x100>;
+				st,bank-name  = "PIO15";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO16: pinctrl@fe823000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe823000 0x100>;
+				st,bank-name  = "PIO16";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO17: pinctrl@fe824000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe824000 0x100>;
+				st,bank-name  = "PIO17";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO18: pinctrl@fe825000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe825000 0x100>;
+				st,bank-name  = "PIO18";
+				st,retime-pin-mask = <0xf>;
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,function = <ALT2>;
+					st,pins {
+						tx	= <&PIO17 4 OUT>;
+						rx	= <&PIO17 5 IN>;
+						output-enable	= <&PIO11 3 OUT>;
+					};
+				};
+			};
+		};
+
+		pin-controller-fvdp-fe {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_fvdp_fe>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO100: pinctrl@fd6b0000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b0000 0x100>;
+				st,bank-name  = "PIO100";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO101: pinctrl@fd6b1000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b1000 0x100>;
+				st,bank-name  = "PIO101";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO102: pinctrl@fd6b2000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b2000 0x100>;
+				st,bank-name  = "PIO102";
+				st,retime-pin-mask = <0xff>;
+			};
+		};
+
+		pin-controller-fvdp-lite {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_fvdp_lite>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO103: pinctrl@fd330000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd330000 0x100>;
+				st,bank-name  = "PIO103";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO104: pinctrl@fd331000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd331000 0x100>;
+				st,bank-name  = "PIO104";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO105: pinctrl@fd332000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd332000 0x100>;
+				st,bank-name  = "PIO105";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO106: pinctrl@fd333000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd333000 0x100>;
+				st,bank-name  = "PIO106";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO107: pinctrl@fd334000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd334000 0x100>;
+				st,bank-name  = "PIO107";
+				st,retime-pin-mask = <0xf>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
new file mode 100644
index 0000000..7dbe450
--- /dev/null
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih416-clock.dtsi"
+#include "stih416-pinctrl.dtsi"
+/ {
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 3 3>;
+		arm,tag-latency = <2 2 2>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc:syscfg@fe600000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe600000 0x1000>;
+			syscfg-range	= <0 999>;
+			syscfg-name	= "SYSCFG_SBC";
+		};
+		syscfg_front:syscfg@fee10000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfee10000 0x1000>;
+			syscfg-range	= <1000 999>;
+			syscfg-name	= "SYSCFG_FRONT";
+		};
+		syscfg_rear:syscfg@fe830000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe830000 0x1000>;
+			syscfg-range	= <2000 999>;
+			syscfg-name	= "SYSCFG_REAR";
+		};
+
+		/* MPE */
+		syscfg_fvdp_fe:syscfg@fddf0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfddf0000 0x1000>;
+			syscfg-range	= <5000 999>;
+			syscfg-name	= "SYSCFG_FVDP_FE";
+		};
+		syscfg_fvdp_lite:syscfg@fd6a0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd6a0000 0x1000>;
+			syscfg-range	= <6000 999>;
+			syscfg-name	= "SYSCFG_FVDP_LITE";
+		};
+
+		syscfg_cpu:syscfg@fdde0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfdde0000 0x1000>;
+			syscfg-range	= <7000 999>;
+			syscfg-name	= "SYSCFG_CPU";
+		};
+
+		syscfg_compo:syscfg@fd320000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd320000 0x1000>;
+			syscfg-range	= <8000 999>;
+			syscfg-name	= "SYSCFG_COMPO";
+		};
+
+		syscfg_transport:syscfg@fd690000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd690000 0x1000>;
+			syscfg-range	= <9000 999>;
+			syscfg-name	= "SYSCFG_TRANSPORT";
+		};
+
+		syscfg_lpm:syscfg@fe4b5100{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe4b5100 0x8>;
+			syscfg-range	= <0 10>;
+			syscfg-name	= "LPM_CFG_REGS";
+		};
+
+		serial2: serial@fed32000{
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			clocks          = <&CLK_S_ICN_REG_0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2>;
+		};
+
+		/* SBC_UART1 */
+		sbc_serial1: serial@fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_sbc_serial1>;
+			clocks          = <&CLK_SYSIN>;
+		};
+	};
+};
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
index 52ce665..2b2552e 100644
--- a/arch/arm/mach-stixxxx/board-dt.c
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -37,10 +37,11 @@ static void __init stih41x_timer_init(void)
 
 static const char *stih41x_dt_match[] __initdata = {
 	"st,stih415",
+	"st,stih416",
 	NULL
 };
 
-DT_MACHINE_START(STM, "STiH415 SoC with Flattened Device Tree")
+DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
 	.init_time	= stih41x_timer_init,
 	.smp		= smp_ops(stixxxx_smp_ops),
 	.dt_compat	= stih41x_dt_match,
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

The STiH416 is advanced HD AVC processor with 3D graphics acceleration
and 1.2-GHz ARM Cortex-A9 SMP CPU.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Linus Walleij <linus.walleij@linaro.org>
---
 Documentation/arm/stixxxx/stih416-overview.txt |   12 +
 arch/arm/boot/dts/stih416-clock.dtsi           |   41 +++
 arch/arm/boot/dts/stih416-pinctrl.dtsi         |  377 ++++++++++++++++++++++++
 arch/arm/boot/dts/stih416.dtsi                 |  111 +++++++
 arch/arm/mach-stixxxx/board-dt.c               |    3 +-
 5 files changed, 543 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/arm/stixxxx/stih416-overview.txt
 create mode 100644 arch/arm/boot/dts/stih416-clock.dtsi
 create mode 100644 arch/arm/boot/dts/stih416-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/stih416.dtsi

diff --git a/Documentation/arm/stixxxx/stih416-overview.txt b/Documentation/arm/stixxxx/stih416-overview.txt
new file mode 100644
index 0000000..e060867
--- /dev/null
+++ b/Documentation/arm/stixxxx/stih416-overview.txt
@@ -0,0 +1,12 @@
+			STiH416 Overview
+			================
+
+Introduction
+------------
+
+    The STiH416 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.2 GHz dual core CPU
+    - SATA2?2,USB 2.0?3, PCIe, Gbit Ethernet MAC?2
diff --git a/arch/arm/boot/dts/stih416-clock.dtsi b/arch/arm/boot/dts/stih416-clock.dtsi
new file mode 100644
index 0000000..7026bf1
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-clock.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ * <stlinux-devel@stlinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator inputs to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+			clock-output-names = "CLK_SYSIN";
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <600000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLK_S_ICN_REG_0: clockgenA0 at 4 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+			clock-output-names = "CLK_S_ICN_REG_0";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi
new file mode 100644
index 0000000..15843a9
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi
@@ -0,0 +1,377 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stixxxx-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO40;
+		gpio6	= &PIO5;
+		gpio7	= &PIO6;
+		gpio8	= &PIO7;
+		gpio9	= &PIO8;
+		gpio10	= &PIO9;
+		gpio11	= &PIO10;
+		gpio12	= &PIO11;
+		gpio13	= &PIO12;
+		gpio14	= &PIO30;
+		gpio15	= &PIO31;
+		gpio16	= &PIO13;
+		gpio17	= &PIO14;
+		gpio18	= &PIO15;
+		gpio19	= &PIO16;
+		gpio20	= &PIO17;
+		gpio21	= &PIO18;
+		gpio22	= &PIO100;
+		gpio23	= &PIO101;
+		gpio24	= &PIO102;
+		gpio25	= &PIO103;
+		gpio26	= &PIO104;
+		gpio27	= &PIO105;
+		gpio28	= &PIO106;
+		gpio29	= &PIO107;
+	};
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_sbc>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+			PIO0: pinctrl at fe610000 {
+				#gpio-cells = <1>;
+				compatible = "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe610000 0x100>;
+				st,bank-name  = "PIO0";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO1: pinctrl at fe611000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe611000 0x100>;
+				st,bank-name  = "PIO1";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO2: pinctrl at fe612000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe612000 0x100>;
+				st,bank-name  = "PIO2";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO3: pinctrl at fe613000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe613000 0x100>;
+				st,bank-name  = "PIO3";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO4: pinctrl at fe614000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe614000 0x100>;
+				st,bank-name  = "PIO4";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO40: pinctrl at fe615000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe615000 0x100>;
+				st,bank-name  = "PIO40";
+				st,retime-pin-mask = <0x7f>;
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1: sbc_serial1 {
+					st,function = <ALT3>;
+					st,pins {
+						tx	= <&PIO2 6 OUT>;
+						rx	= <&PIO2 7 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_front>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO5: pinctrl at fee00000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee00000 0x100>;
+				st,bank-name  = "PIO5";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO6: pinctrl at fee01000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee01000 0x100>;
+				st,bank-name  = "PIO6";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO7: pinctrl at fee02000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee02000 0x100>;
+				st,bank-name  = "PIO7";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO8: pinctrl at fee03000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee03000 0x100>;
+				st,bank-name  = "PIO8";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO9: pinctrl at fee04000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee04000 0x100>;
+				st,bank-name  = "PIO9";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO10: pinctrl at fee05000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee05000 0x100>;
+				st,bank-name  = "PIO10";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO11: pinctrl at fee06000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee06000 0x100>;
+				st,bank-name  = "PIO11";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO12: pinctrl at fee07000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee07000 0x100>;
+				st,bank-name  = "PIO12";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO30: pinctrl at fee08000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee08000 0x100>;
+				st,bank-name  = "PIO30";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO31: pinctrl at fee09000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfee09000 0x100>;
+				st,bank-name  = "PIO31";
+				st,retime-pin-mask = <0xff>;
+			};
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_rear>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO13: pinctrl at fe820000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe820000 0x100>;
+				st,bank-name  = "PIO13";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO14: pinctrl at fe821000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe821000 0x100>;
+				st,bank-name  = "PIO14";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO15: pinctrl at fe822000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe822000 0x100>;
+				st,bank-name  = "PIO15";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO16: pinctrl at fe823000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe823000 0x100>;
+				st,bank-name  = "PIO16";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO17: pinctrl at fe824000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe824000 0x100>;
+				st,bank-name  = "PIO17";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO18: pinctrl at fe825000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfe825000 0x100>;
+				st,bank-name  = "PIO18";
+				st,retime-pin-mask = <0xf>;
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,function = <ALT2>;
+					st,pins {
+						tx	= <&PIO17 4 OUT>;
+						rx	= <&PIO17 5 IN>;
+						output-enable	= <&PIO11 3 OUT>;
+					};
+				};
+			};
+		};
+
+		pin-controller-fvdp-fe {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_fvdp_fe>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO100: pinctrl at fd6b0000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b0000 0x100>;
+				st,bank-name  = "PIO100";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO101: pinctrl at fd6b1000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b1000 0x100>;
+				st,bank-name  = "PIO101";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO102: pinctrl at fd6b2000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd6b2000 0x100>;
+				st,bank-name  = "PIO102";
+				st,retime-pin-mask = <0xff>;
+			};
+		};
+
+		pin-controller-fvdp-lite {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-pinctrl", "simple-bus";
+			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
+			st,syscfg		= <&syscfg_fvdp_lite>;
+			st,syscfg-offsets	= <0 40 50 60 100>;
+			ranges;
+
+			PIO103: pinctrl at fd330000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd330000 0x100>;
+				st,bank-name  = "PIO103";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO104: pinctrl at fd331000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd331000 0x100>;
+				st,bank-name  = "PIO104";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO105: pinctrl at fd332000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd332000 0x100>;
+				st,bank-name  = "PIO105";
+				st,retime-pin-mask = <0xff>;
+			};
+			PIO106: pinctrl at fd333000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd333000 0x100>;
+				st,bank-name  = "PIO106";
+				st,retime-pin-mask = <0xff>;
+			};
+
+			PIO107: pinctrl at fd334000 {
+				#gpio-cells	= <1>;
+				compatible	= "st,stixxxx-gpio";
+				gpio-controller;
+				reg = <0xfd334000 0x100>;
+				st,bank-name  = "PIO107";
+				st,retime-pin-mask = <0xf>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
new file mode 100644
index 0000000..7dbe450
--- /dev/null
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih416-clock.dtsi"
+#include "stih416-pinctrl.dtsi"
+/ {
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 3 3>;
+		arm,tag-latency = <2 2 2>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc:syscfg at fe600000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe600000 0x1000>;
+			syscfg-range	= <0 999>;
+			syscfg-name	= "SYSCFG_SBC";
+		};
+		syscfg_front:syscfg at fee10000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfee10000 0x1000>;
+			syscfg-range	= <1000 999>;
+			syscfg-name	= "SYSCFG_FRONT";
+		};
+		syscfg_rear:syscfg at fe830000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe830000 0x1000>;
+			syscfg-range	= <2000 999>;
+			syscfg-name	= "SYSCFG_REAR";
+		};
+
+		/* MPE */
+		syscfg_fvdp_fe:syscfg at fddf0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfddf0000 0x1000>;
+			syscfg-range	= <5000 999>;
+			syscfg-name	= "SYSCFG_FVDP_FE";
+		};
+		syscfg_fvdp_lite:syscfg at fd6a0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd6a0000 0x1000>;
+			syscfg-range	= <6000 999>;
+			syscfg-name	= "SYSCFG_FVDP_LITE";
+		};
+
+		syscfg_cpu:syscfg at fdde0000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfdde0000 0x1000>;
+			syscfg-range	= <7000 999>;
+			syscfg-name	= "SYSCFG_CPU";
+		};
+
+		syscfg_compo:syscfg at fd320000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd320000 0x1000>;
+			syscfg-range	= <8000 999>;
+			syscfg-name	= "SYSCFG_COMPO";
+		};
+
+		syscfg_transport:syscfg at fd690000{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfd690000 0x1000>;
+			syscfg-range	= <9000 999>;
+			syscfg-name	= "SYSCFG_TRANSPORT";
+		};
+
+		syscfg_lpm:syscfg at fe4b5100{
+			compatible	= "st,stih416-syscfg";
+			reg		= <0xfe4b5100 0x8>;
+			syscfg-range	= <0 10>;
+			syscfg-name	= "LPM_CFG_REGS";
+		};
+
+		serial2: serial at fed32000{
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			clocks          = <&CLK_S_ICN_REG_0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2>;
+		};
+
+		/* SBC_UART1 */
+		sbc_serial1: serial at fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_sbc_serial1>;
+			clocks          = <&CLK_SYSIN>;
+		};
+	};
+};
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
index 52ce665..2b2552e 100644
--- a/arch/arm/mach-stixxxx/board-dt.c
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -37,10 +37,11 @@ static void __init stih41x_timer_init(void)
 
 static const char *stih41x_dt_match[] __initdata = {
 	"st,stih415",
+	"st,stih416",
 	NULL
 };
 
-DT_MACHINE_START(STM, "STiH415 SoC with Flattened Device Tree")
+DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
 	.init_time	= stih41x_timer_init,
 	.smp		= smp_ops(stixxxx_smp_ops),
 	.dt_compat	= stih41x_dt_match,
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 08/11] ARM:stixxxx: Add DEBUG_LL console support
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

This patch adds low level debug uart support to stixxxx based SOCs.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/Kconfig.debug           |   38 +++++++++++++++++++++++
 arch/arm/include/debug/stixxxx.S |   61 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-stixxxx/board-dt.c |    2 +
 3 files changed, 101 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/debug/stixxxx.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1d41908..cc98ef3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -483,6 +483,16 @@ choice
 		  This option selects UART0 on VIA/Wondermedia System-on-a-chip
 		  devices, including VT8500, WM8505, WM8650 and WM8850.
 
+	config DEBUG_STIXXXX_UART
+		depends on ARCH_STIXXXX
+		bool "Use StiH415/416 ASC for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on StiH415/416 based platforms like B2000, B2020.
+		  It support UART2 and SBC_UART1.
+
+		  If unsure, say N.
+
 	config DEBUG_LL_UART_NONE
 		bool "No low-level debugging UART"
 		depends on !ARCH_MULTIPLATFORM
@@ -617,6 +627,33 @@ choice
 
 endchoice
 
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_STIXXXX_UART
+
+	config STIH41X_DEBUG_ASC2
+		bool "ASC2 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2000, which has
+		  default UART wired up to ASC2.
+
+		  If unsure, say N.
+
+	config STIH41X_DEBUG_SBC_ASC1
+		bool "SBC ASC1 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2020. which has
+		  default UART wired up to SBC ASC1.
+
+		  If unsure, say N.
+
+endchoice
+
+
+
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/bcm2835.S" if DEBUG_BCM2835
@@ -641,6 +678,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_MMP_UART3
 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
+	default "debug/stixxxx.S" if DEBUG_STIXXXX_UART
 	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/tegra.S" if DEBUG_TEGRA_UART
 	default "debug/ux500.S" if DEBUG_UX500_UART
diff --git a/arch/arm/include/debug/stixxxx.S b/arch/arm/include/debug/stixxxx.S
new file mode 100644
index 0000000..7bc02a7
--- /dev/null
+++ b/arch/arm/include/debug/stixxxx.S
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/debug/stixxxx.S
+ *
+ * Debugging macro include header
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define STIH41X_COMMS_BASE              0xfed00000
+#define STIH41X_ASC2_BASE               (STIH41X_COMMS_BASE+0x32000)
+
+#define STIH41X_SBC_LPM_BASE            0xfe400000
+#define STIH41X_SBC_COMMS_BASE          (STIH41X_SBC_LPM_BASE + 0x100000)
+#define STIH41X_SBC_ASC1_BASE           (STIH41X_SBC_COMMS_BASE + 0x31000)
+
+
+#define VIRT_ADDRESS(x)		(x - 0x1000000)
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_ASC2)
+#define DEBUG_LL_UART_BASE	STIH41X_ASC2_BASE
+#endif
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_SBC_ASC1)
+#define DEBUG_LL_UART_BASE	STIH41X_SBC_ASC1_BASE
+#endif
+
+#ifndef DEBUG_LL_UART_BASE
+#error "DEBUG UART is not Configured"
+#endif
+
+#define ASC_TX_BUF_OFF  0x04
+#define ASC_CTRL_OFF    0x0c
+#define ASC_STA_OFF     0x14
+
+#define ASC_STA_TX_FULL         (1<<9)
+#define ASC_STA_TX_EMPTY        (1<<1)
+
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp,      =DEBUG_LL_UART_BASE	@ physical base
+		ldr	\rv,      =VIRT_ADDRESS(DEBUG_LL_UART_BASE) @ virt base
+		.endm
+
+                .macro  senduart,rd,rx
+                strb    \rd, [\rx, #ASC_TX_BUF_OFF]
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_FULL
+                bne     1001b
+                .endm
+
+                .macro  busyuart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_EMPTY
+                beq     1001b
+                .endm
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
index 2b2552e..2482d139 100644
--- a/arch/arm/mach-stixxxx/board-dt.c
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -11,6 +11,7 @@
 #include <linux/clocksource.h>
 #include <linux/irq.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 
 #include "smp.h"
@@ -42,6 +43,7 @@ static const char *stih41x_dt_match[] __initdata = {
 };
 
 DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
+	.map_io		= debug_ll_io_init,
 	.init_time	= stih41x_timer_init,
 	.smp		= smp_ops(stixxxx_smp_ops),
 	.dt_compat	= stih41x_dt_match,
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 08/11] ARM:stixxxx: Add DEBUG_LL console support
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, linux-serial-u79uwXL29TY76Z2rM5mHXA,
	Grant Likely, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Rob Herring, Stuart Menefy, Mark Brown, John Stultz,
	Thomas Gleixner, Greg Kroah-Hartman,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew Morton,
	David S. Miller

This patch adds low level debug uart support to stixxxx based SOCs.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
 arch/arm/Kconfig.debug           |   38 +++++++++++++++++++++++
 arch/arm/include/debug/stixxxx.S |   61 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-stixxxx/board-dt.c |    2 +
 3 files changed, 101 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/debug/stixxxx.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1d41908..cc98ef3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -483,6 +483,16 @@ choice
 		  This option selects UART0 on VIA/Wondermedia System-on-a-chip
 		  devices, including VT8500, WM8505, WM8650 and WM8850.
 
+	config DEBUG_STIXXXX_UART
+		depends on ARCH_STIXXXX
+		bool "Use StiH415/416 ASC for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on StiH415/416 based platforms like B2000, B2020.
+		  It support UART2 and SBC_UART1.
+
+		  If unsure, say N.
+
 	config DEBUG_LL_UART_NONE
 		bool "No low-level debugging UART"
 		depends on !ARCH_MULTIPLATFORM
@@ -617,6 +627,33 @@ choice
 
 endchoice
 
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_STIXXXX_UART
+
+	config STIH41X_DEBUG_ASC2
+		bool "ASC2 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2000, which has
+		  default UART wired up to ASC2.
+
+		  If unsure, say N.
+
+	config STIH41X_DEBUG_SBC_ASC1
+		bool "SBC ASC1 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2020. which has
+		  default UART wired up to SBC ASC1.
+
+		  If unsure, say N.
+
+endchoice
+
+
+
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/bcm2835.S" if DEBUG_BCM2835
@@ -641,6 +678,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_MMP_UART3
 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
+	default "debug/stixxxx.S" if DEBUG_STIXXXX_UART
 	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/tegra.S" if DEBUG_TEGRA_UART
 	default "debug/ux500.S" if DEBUG_UX500_UART
diff --git a/arch/arm/include/debug/stixxxx.S b/arch/arm/include/debug/stixxxx.S
new file mode 100644
index 0000000..7bc02a7
--- /dev/null
+++ b/arch/arm/include/debug/stixxxx.S
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/debug/stixxxx.S
+ *
+ * Debugging macro include header
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define STIH41X_COMMS_BASE              0xfed00000
+#define STIH41X_ASC2_BASE               (STIH41X_COMMS_BASE+0x32000)
+
+#define STIH41X_SBC_LPM_BASE            0xfe400000
+#define STIH41X_SBC_COMMS_BASE          (STIH41X_SBC_LPM_BASE + 0x100000)
+#define STIH41X_SBC_ASC1_BASE           (STIH41X_SBC_COMMS_BASE + 0x31000)
+
+
+#define VIRT_ADDRESS(x)		(x - 0x1000000)
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_ASC2)
+#define DEBUG_LL_UART_BASE	STIH41X_ASC2_BASE
+#endif
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_SBC_ASC1)
+#define DEBUG_LL_UART_BASE	STIH41X_SBC_ASC1_BASE
+#endif
+
+#ifndef DEBUG_LL_UART_BASE
+#error "DEBUG UART is not Configured"
+#endif
+
+#define ASC_TX_BUF_OFF  0x04
+#define ASC_CTRL_OFF    0x0c
+#define ASC_STA_OFF     0x14
+
+#define ASC_STA_TX_FULL         (1<<9)
+#define ASC_STA_TX_EMPTY        (1<<1)
+
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp,      =DEBUG_LL_UART_BASE	@ physical base
+		ldr	\rv,      =VIRT_ADDRESS(DEBUG_LL_UART_BASE) @ virt base
+		.endm
+
+                .macro  senduart,rd,rx
+                strb    \rd, [\rx, #ASC_TX_BUF_OFF]
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_FULL
+                bne     1001b
+                .endm
+
+                .macro  busyuart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_EMPTY
+                beq     1001b
+                .endm
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
index 2b2552e..2482d139 100644
--- a/arch/arm/mach-stixxxx/board-dt.c
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -11,6 +11,7 @@
 #include <linux/clocksource.h>
 #include <linux/irq.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 
 #include "smp.h"
@@ -42,6 +43,7 @@ static const char *stih41x_dt_match[] __initdata = {
 };
 
 DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
+	.map_io		= debug_ll_io_init,
 	.init_time	= stih41x_timer_init,
 	.smp		= smp_ops(stixxxx_smp_ops),
 	.dt_compat	= stih41x_dt_match,
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 08/11] ARM:stixxxx: Add DEBUG_LL console support
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds low level debug uart support to stixxxx based SOCs.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/Kconfig.debug           |   38 +++++++++++++++++++++++
 arch/arm/include/debug/stixxxx.S |   61 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-stixxxx/board-dt.c |    2 +
 3 files changed, 101 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/debug/stixxxx.S

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 1d41908..cc98ef3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -483,6 +483,16 @@ choice
 		  This option selects UART0 on VIA/Wondermedia System-on-a-chip
 		  devices, including VT8500, WM8505, WM8650 and WM8850.
 
+	config DEBUG_STIXXXX_UART
+		depends on ARCH_STIXXXX
+		bool "Use StiH415/416 ASC for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on StiH415/416 based platforms like B2000, B2020.
+		  It support UART2 and SBC_UART1.
+
+		  If unsure, say N.
+
 	config DEBUG_LL_UART_NONE
 		bool "No low-level debugging UART"
 		depends on !ARCH_MULTIPLATFORM
@@ -617,6 +627,33 @@ choice
 
 endchoice
 
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_STIXXXX_UART
+
+	config STIH41X_DEBUG_ASC2
+		bool "ASC2 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2000, which has
+		  default UART wired up to ASC2.
+
+		  If unsure, say N.
+
+	config STIH41X_DEBUG_SBC_ASC1
+		bool "SBC ASC1 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2020. which has
+		  default UART wired up to SBC ASC1.
+
+		  If unsure, say N.
+
+endchoice
+
+
+
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/bcm2835.S" if DEBUG_BCM2835
@@ -641,6 +678,7 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_MMP_UART3
 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
+	default "debug/stixxxx.S" if DEBUG_STIXXXX_UART
 	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/tegra.S" if DEBUG_TEGRA_UART
 	default "debug/ux500.S" if DEBUG_UX500_UART
diff --git a/arch/arm/include/debug/stixxxx.S b/arch/arm/include/debug/stixxxx.S
new file mode 100644
index 0000000..7bc02a7
--- /dev/null
+++ b/arch/arm/include/debug/stixxxx.S
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/debug/stixxxx.S
+ *
+ * Debugging macro include header
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define STIH41X_COMMS_BASE              0xfed00000
+#define STIH41X_ASC2_BASE               (STIH41X_COMMS_BASE+0x32000)
+
+#define STIH41X_SBC_LPM_BASE            0xfe400000
+#define STIH41X_SBC_COMMS_BASE          (STIH41X_SBC_LPM_BASE + 0x100000)
+#define STIH41X_SBC_ASC1_BASE           (STIH41X_SBC_COMMS_BASE + 0x31000)
+
+
+#define VIRT_ADDRESS(x)		(x - 0x1000000)
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_ASC2)
+#define DEBUG_LL_UART_BASE	STIH41X_ASC2_BASE
+#endif
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_SBC_ASC1)
+#define DEBUG_LL_UART_BASE	STIH41X_SBC_ASC1_BASE
+#endif
+
+#ifndef DEBUG_LL_UART_BASE
+#error "DEBUG UART is not Configured"
+#endif
+
+#define ASC_TX_BUF_OFF  0x04
+#define ASC_CTRL_OFF    0x0c
+#define ASC_STA_OFF     0x14
+
+#define ASC_STA_TX_FULL         (1<<9)
+#define ASC_STA_TX_EMPTY        (1<<1)
+
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp,      =DEBUG_LL_UART_BASE	@ physical base
+		ldr	\rv,      =VIRT_ADDRESS(DEBUG_LL_UART_BASE) @ virt base
+		.endm
+
+                .macro  senduart,rd,rx
+                strb    \rd, [\rx, #ASC_TX_BUF_OFF]
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_FULL
+                bne     1001b
+                .endm
+
+                .macro  busyuart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_EMPTY
+                beq     1001b
+                .endm
diff --git a/arch/arm/mach-stixxxx/board-dt.c b/arch/arm/mach-stixxxx/board-dt.c
index 2b2552e..2482d139 100644
--- a/arch/arm/mach-stixxxx/board-dt.c
+++ b/arch/arm/mach-stixxxx/board-dt.c
@@ -11,6 +11,7 @@
 #include <linux/clocksource.h>
 #include <linux/irq.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
 #include <asm/mach/arch.h>
 
 #include "smp.h"
@@ -42,6 +43,7 @@ static const char *stih41x_dt_match[] __initdata = {
 };
 
 DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
+	.map_io		= debug_ll_io_init,
 	.init_time	= stih41x_timer_init,
 	.smp		= smp_ops(stixxxx_smp_ops),
 	.dt_compat	= stih41x_dt_match,
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

This patch adds stih415 and stih416 support to multi_v7_defconfig.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/configs/multi_v7_defconfig |   32 +++++++++++++++-----------------
 1 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2e67a27..8a5cd5c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -1,23 +1,20 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
-CONFIG_ARCH_SIRF=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_HIGHBANK=y
 CONFIG_ARCH_SOCFPGA=y
-CONFIG_ARCH_SUNXI=y
-CONFIG_ARCH_WM8850=y
-# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
-CONFIG_ARCH_ZYNQ=y
-CONFIG_ARM_ERRATA_754322=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR13XX=y
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
+CONFIG_ARCH_STIXXXX=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SIRF=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARCH_ZYNQ=y
 CONFIG_SMP=y
-CONFIG_ARM_ARCH_TIMER=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
@@ -25,27 +22,30 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_NET=y
+CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_SATA_HIGHBANK=y
 CONFIG_SATA_MV=y
-CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_CALXEDA_XGMAC=y
 CONFIG_SMSC911X=y
 CONFIG_STMMAC_ETH=y
+CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
-CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_SIRFSOC=y
 CONFIG_SERIAL_SIRFSOC_CONSOLE=y
 CONFIG_SERIAL_VT8500=y
 CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_ST_ASC=y
+CONFIG_SERIAL_ST_ASC_CONSOLE=y
 CONFIG_IPMI_HANDLER=y
 CONFIG_IPMI_SI=y
 CONFIG_I2C=y
@@ -54,7 +54,6 @@ CONFIG_I2C_SIRF=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_SIRF=y
-CONFIG_GPIO_PL061=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FB_WM8505=y
@@ -67,7 +66,6 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_SPEAR=y
-CONFIG_MMC_WMT=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_HIGHBANK_MC=y
@@ -75,9 +73,9 @@ CONFIG_EDAC_HIGHBANK_L2=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_VT8500=y
-CONFIG_PWM=y
-CONFIG_PWM_VT8500=y
 CONFIG_DMADEVICES=y
-CONFIG_PL330_DMA=y
-CONFIG_SIRF_DMA=y
 CONFIG_DW_DMAC=y
+CONFIG_SIRF_DMA=y
+CONFIG_PL330_DMA=y
+CONFIG_PWM=y
+CONFIG_PWM_VT8500=y
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10  9:27     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds stih415 and stih416 support to multi_v7_defconfig.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/configs/multi_v7_defconfig |   32 +++++++++++++++-----------------
 1 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 2e67a27..8a5cd5c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -1,23 +1,20 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
-CONFIG_ARCH_SIRF=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_ARCH_HIGHBANK=y
 CONFIG_ARCH_SOCFPGA=y
-CONFIG_ARCH_SUNXI=y
-CONFIG_ARCH_WM8850=y
-# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
-CONFIG_ARCH_ZYNQ=y
-CONFIG_ARM_ERRATA_754322=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR13XX=y
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
+CONFIG_ARCH_STIXXXX=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SIRF=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARCH_ZYNQ=y
 CONFIG_SMP=y
-CONFIG_ARM_ARCH_TIMER=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
@@ -25,27 +22,30 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_NET=y
+CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_SATA_HIGHBANK=y
 CONFIG_SATA_MV=y
-CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_CALXEDA_XGMAC=y
 CONFIG_SMSC911X=y
 CONFIG_STMMAC_ETH=y
+CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
-CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_SIRFSOC=y
 CONFIG_SERIAL_SIRFSOC_CONSOLE=y
 CONFIG_SERIAL_VT8500=y
 CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_ST_ASC=y
+CONFIG_SERIAL_ST_ASC_CONSOLE=y
 CONFIG_IPMI_HANDLER=y
 CONFIG_IPMI_SI=y
 CONFIG_I2C=y
@@ -54,7 +54,6 @@ CONFIG_I2C_SIRF=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_SIRF=y
-CONFIG_GPIO_PL061=y
 CONFIG_FB=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FB_WM8505=y
@@ -67,7 +66,6 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_SPEAR=y
-CONFIG_MMC_WMT=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_HIGHBANK_MC=y
@@ -75,9 +73,9 @@ CONFIG_EDAC_HIGHBANK_L2=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_VT8500=y
-CONFIG_PWM=y
-CONFIG_PWM_VT8500=y
 CONFIG_DMADEVICES=y
-CONFIG_PL330_DMA=y
-CONFIG_SIRF_DMA=y
 CONFIG_DW_DMAC=y
+CONFIG_SIRF_DMA=y
+CONFIG_PL330_DMA=y
+CONFIG_PWM=y
+CONFIG_PWM_VT8500=y
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 10/11] ARM:stih41x: Add B2000 board support
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

B2000 board is reference board for STIH415/416 SOCs, it has
2 x UART, 4x USB, 2 x Ethernet, 1 x SATA, 1 x PCIe, and 1GB RAM.

This patch add initial support to b2000 with STiH415/416 with UART2 as
console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/Makefile           |    2 +
 arch/arm/boot/dts/stih415-b2000.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2000.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2000.dtsi |   41 ++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2000.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f0895c5..d4615fd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -177,6 +177,8 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
+	stih416-b2000.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2000.dts b/arch/arm/boot/dts/stih415-b2000.dts
new file mode 100644
index 0000000..d4af531
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2000.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+	model = "STiH415 B2000 Board";
+	compatible = "st,stih415", "st,stih415-b2000";
+};
diff --git a/arch/arm/boot/dts/stih416-b2000.dts b/arch/arm/boot/dts/stih416-b2000.dts
new file mode 100644
index 0000000..a5eb6ee
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2000.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2000.dtsi"
+
+/ {
+	compatible = "st,stih416", "st,stih416-b2000";
+	model = "STiH416 B2000";
+};
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi
new file mode 100644
index 0000000..8e694d2
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2000.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+
+	memory{
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &serial2;
+	};
+
+	aliases {
+		ttyAS0 = &serial2;
+	};
+
+	soc {
+		serial2: serial@fed32000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			fp_led {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO105 7>;
+				linux,default-trigger	= "heartbeat";
+			};
+		};
+
+	};
+};
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 10/11] ARM:stih41x: Add B2000 board support
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-lFZ/pmaqli7XmaaqVzeoHQ, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, linux-serial-u79uwXL29TY76Z2rM5mHXA,
	Grant Likely, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Rob Herring, Stuart Menefy, Mark Brown, John Stultz,
	Thomas Gleixner, Greg Kroah-Hartman,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew Morton,
	David S. Miller

B2000 board is reference board for STIH415/416 SOCs, it has
2 x UART, 4x USB, 2 x Ethernet, 1 x SATA, 1 x PCIe, and 1GB RAM.

This patch add initial support to b2000 with STiH415/416 with UART2 as
console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
CC: Stephen Gallimore <stephen.gallimore-qxv4g6HH51o@public.gmane.org>
CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
 arch/arm/boot/dts/Makefile           |    2 +
 arch/arm/boot/dts/stih415-b2000.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2000.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2000.dtsi |   41 ++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2000.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f0895c5..d4615fd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -177,6 +177,8 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
+	stih416-b2000.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2000.dts b/arch/arm/boot/dts/stih415-b2000.dts
new file mode 100644
index 0000000..d4af531
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2000.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+	model = "STiH415 B2000 Board";
+	compatible = "st,stih415", "st,stih415-b2000";
+};
diff --git a/arch/arm/boot/dts/stih416-b2000.dts b/arch/arm/boot/dts/stih416-b2000.dts
new file mode 100644
index 0000000..a5eb6ee
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2000.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2000.dtsi"
+
+/ {
+	compatible = "st,stih416", "st,stih416-b2000";
+	model = "STiH416 B2000";
+};
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi
new file mode 100644
index 0000000..8e694d2
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2000.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+
+	memory{
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &serial2;
+	};
+
+	aliases {
+		ttyAS0 = &serial2;
+	};
+
+	soc {
+		serial2: serial@fed32000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			fp_led {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO105 7>;
+				linux,default-trigger	= "heartbeat";
+			};
+		};
+
+	};
+};
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 10/11] ARM:stih41x: Add B2000 board support
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

B2000 board is reference board for STIH415/416 SOCs, it has
2 x UART, 4x USB, 2 x Ethernet, 1 x SATA, 1 x PCIe, and 1GB RAM.

This patch add initial support to b2000 with STiH415/416 with UART2 as
console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/Makefile           |    2 +
 arch/arm/boot/dts/stih415-b2000.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2000.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2000.dtsi |   41 ++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2000.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2000.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f0895c5..d4615fd 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -177,6 +177,8 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
+	stih416-b2000.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2000.dts b/arch/arm/boot/dts/stih415-b2000.dts
new file mode 100644
index 0000000..d4af531
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2000.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+	model = "STiH415 B2000 Board";
+	compatible = "st,stih415", "st,stih415-b2000";
+};
diff --git a/arch/arm/boot/dts/stih416-b2000.dts b/arch/arm/boot/dts/stih416-b2000.dts
new file mode 100644
index 0000000..a5eb6ee
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2000.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2000.dtsi"
+
+/ {
+	compatible = "st,stih416", "st,stih416-b2000";
+	model = "STiH416 B2000";
+};
diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi
new file mode 100644
index 0000000..8e694d2
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2000.dtsi
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+
+	memory{
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &serial2;
+	};
+
+	aliases {
+		ttyAS0 = &serial2;
+	};
+
+	soc {
+		serial2: serial at fed32000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			fp_led {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO105 7>;
+				linux,default-trigger	= "heartbeat";
+			};
+		};
+
+	};
+};
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 11/11] ARM:stih41x: Add B2020 board support
  2013-06-10  9:17   ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Srinivas Kandagatla,
	Stephen Gallimore, Stuart Menefy, Thomas Gleixner, Tony Prisk

B2020 ADI board is reference board for STIH415/416 SOCs, it has 2 x
UART, 4x USB, 1 x Ethernet, 1 x SATA, 1 x PCIe, and 2GB RAM  with
standard set-top box IPs.

This patch adds initial support to B2020 with STiH415/416 with SBC_UART1
as console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/Makefile           |    4 ++-
 arch/arm/boot/dts/stih415-b2020.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2020.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2020.dtsi |   42 ++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2020.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d4615fd..0d24c95 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -178,7 +178,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
 dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
-	stih416-b2000.dtb
+	stih416-b2000.dtb \
+	stih415-b2020.dtb \
+	stih416-b2020.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2020.dts b/arch/arm/boot/dts/stih415-b2020.dts
new file mode 100644
index 0000000..442b019
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2020.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH415 B2020 Board";
+	compatible = "st,stih415", "st,stih415-b2020";
+};
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
new file mode 100644
index 0000000..276f28d
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH416 B2020";
+	compatible = "st,stih416", "st,stih416-b2020";
+
+};
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi
new file mode 100644
index 0000000..133e181
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2020.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+	memory{
+		device_type = "memory";
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &sbc_serial1;
+	};
+
+	aliases {
+		ttyAS0 = &sbc_serial1;
+	};
+	soc {
+		sbc_serial1: serial@fe531000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			red {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO4 1>;
+				linux,default-trigger	= "heartbeat";
+			};
+			green {
+				gpios	= <&PIO4 7>;
+				default-state = "off";
+			};
+		};
+	};
+};
-- 
1.7.6.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 11/11] ARM:stih41x: Add B2020 board support
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mauro Carvalho Chehab, linux-doc, Linus Walleij, linux,
	Samuel Ortiz, Srinivas Kandagatla, Stephen Gallimore,
	linux-serial, Grant Likely, Arnd Bergmann, devicetree-discuss,
	Rob Herring, Stuart Menefy, Mark Brown, John Stultz,
	Thomas Gleixner, Greg Kroah-Hartman, linux-kernel, Rob Landley,
	Olof Johansson, Andrew Morton, David S. Miller

B2020 ADI board is reference board for STIH415/416 SOCs, it has 2 x
UART, 4x USB, 1 x Ethernet, 1 x SATA, 1 x PCIe, and 2GB RAM  with
standard set-top box IPs.

This patch adds initial support to B2020 with STiH415/416 with SBC_UART1
as console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/Makefile           |    4 ++-
 arch/arm/boot/dts/stih415-b2020.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2020.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2020.dtsi |   42 ++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2020.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d4615fd..0d24c95 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -178,7 +178,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
 dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
-	stih416-b2000.dtb
+	stih416-b2000.dtb \
+	stih415-b2020.dtb \
+	stih416-b2020.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2020.dts b/arch/arm/boot/dts/stih415-b2020.dts
new file mode 100644
index 0000000..442b019
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2020.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH415 B2020 Board";
+	compatible = "st,stih415", "st,stih415-b2020";
+};
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
new file mode 100644
index 0000000..276f28d
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH416 B2020";
+	compatible = "st,stih416", "st,stih416-b2020";
+
+};
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi
new file mode 100644
index 0000000..133e181
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2020.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+	memory{
+		device_type = "memory";
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &sbc_serial1;
+	};
+
+	aliases {
+		ttyAS0 = &sbc_serial1;
+	};
+	soc {
+		sbc_serial1: serial@fe531000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			red {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO4 1>;
+				linux,default-trigger	= "heartbeat";
+			};
+			green {
+				gpios	= <&PIO4 7>;
+				default-state = "off";
+			};
+		};
+	};
+};
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 11/11] ARM:stih41x: Add B2020 board support
@ 2013-06-10  9:28     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

B2020 ADI board is reference board for STIH415/416 SOCs, it has 2 x
UART, 4x USB, 1 x Ethernet, 1 x SATA, 1 x PCIe, and 2GB RAM  with
standard set-top box IPs.

This patch adds initial support to B2020 with STiH415/416 with SBC_UART1
as console and a heard beat LED.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
CC: Stephen Gallimore <stephen.gallimore@st.com>
CC: Stuart Menefy <stuart.menefy@st.com>
CC: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/boot/dts/Makefile           |    4 ++-
 arch/arm/boot/dts/stih415-b2020.dts  |   15 ++++++++++++
 arch/arm/boot/dts/stih416-b2020.dts  |   16 +++++++++++++
 arch/arm/boot/dts/stih41x-b2020.dtsi |   42 ++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih415-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih416-b2020.dts
 create mode 100644 arch/arm/boot/dts/stih41x-b2020.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d4615fd..0d24c95 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -178,7 +178,9 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
 dtb-$(CONFIG_ARCH_STIXXXX)+= stih415-b2000.dtb \
-	stih416-b2000.dtb
+	stih416-b2000.dtb \
+	stih415-b2020.dtb \
+	stih416-b2020.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
diff --git a/arch/arm/boot/dts/stih415-b2020.dts b/arch/arm/boot/dts/stih415-b2020.dts
new file mode 100644
index 0000000..442b019
--- /dev/null
+++ b/arch/arm/boot/dts/stih415-b2020.dts
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH415 B2020 Board";
+	compatible = "st,stih415", "st,stih415-b2020";
+};
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
new file mode 100644
index 0000000..276f28d
--- /dev/null
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH416 B2020";
+	compatible = "st,stih416", "st,stih416-b2020";
+
+};
diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi
new file mode 100644
index 0000000..133e181
--- /dev/null
+++ b/arch/arm/boot/dts/stih41x-b2020.dtsi
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+	memory{
+		device_type = "memory";
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &sbc_serial1;
+	};
+
+	aliases {
+		ttyAS0 = &sbc_serial1;
+	};
+	soc {
+		sbc_serial1: serial at fe531000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			red {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO4 1>;
+				linux,default-trigger	= "heartbeat";
+			};
+			green {
+				gpios	= <&PIO4 7>;
+				default-state = "off";
+			};
+		};
+	};
+};
-- 
1.7.6.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
  2013-06-10  9:21     ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10  9:35       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10  9:35 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On Mon, Jun 10, 2013 at 10:21:00AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds support to ASC (asynchronous serial controller)
> driver, which is basically a standard serial driver. This IP is common
> across all the ST parts for settop box platforms.
> 
> ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
> It support all industry standard baud rates.

Your driver is not POSIX compliant.

> +		for (; count != 0; count--) {
> +			c = asc_in(port, ASC_RXBUF);
> +			flag = TTY_NORMAL;
> +			port->icount.rx++;
> +
> +			if (unlikely(c & ASC_RXBUF_FE)) {
> +				if (c == ASC_RXBUF_FE) {
> +					port->icount.brk++;
> +					if (uart_handle_break(port))
> +						continue;
> +					flag = TTY_BREAK;
> +				} else {
> +					port->icount.frame++;
> +					flag = TTY_FRAME;
> +				}
> +			} else if (ascport->check_parity &&
> +				   unlikely(c & ASC_RXBUF_PE)) {
> +				port->icount.parity++;
> +				flag = TTY_PARITY;
> +			}
> +
> +			if (uart_handle_sysrq_char(port, c))
> +				continue;
> +			tty_insert_flip_char(tport, c & 0xff, flag);
> +		}
> +		if (overrun) {
> +			port->icount.overrun++;
> +			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
> +		}

No support for ignoring error conditions.  No support for ignoring all
input... and:

> +static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
> +			    struct ktermios *old)
> +{
> +	struct asc_port *ascport = to_asc_port(port);
> +	unsigned int baud;
> +	u32 ctrl_val;
> +	tcflag_t cflag;
> +	unsigned long flags;
> +
> +	port->uartclk = clk_get_rate(ascport->clk);
> +
> +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
> +	cflag = termios->c_cflag;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +
> +	/* read control register */
> +	ctrl_val = asc_in(port, ASC_CTL);
> +
> +	/* stop serial port and reset value */
> +	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
> +	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
> +
> +	/* reset fifo rx & tx */
> +	asc_out(port, ASC_TXRESET, 1);
> +	asc_out(port, ASC_RXRESET, 1);
> +
> +	/* set character length */
> +	if ((cflag & CSIZE) == CS7) {
> +		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
> +	} else {
> +		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
> +						ASC_CTL_MODE_8BIT;
> +	}
> +
> +	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
> +
> +	/* set stop bit */
> +	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
> +
> +	/* odd parity */
> +	if (cflag & PARODD)
> +		ctrl_val |= ASC_CTL_PARITYODD;
> +
> +	/* hardware flow control */
> +	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
> +		ctrl_val |= ASC_CTL_CTSENABLE;

This doesn't reflect those facts back into the termios structure to
indicate that they aren't supported.

Consider using uart_port's ignore and read status masks to implement
the break, framing, parity and overrun checking in your interrupt
handler using the same methodology as drivers like 8250, amba-pl011
etc.  That will help you get these code sequences correct.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
@ 2013-06-10  9:35       ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10  9:35 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc, Linus Walleij, Samuel Ortiz,
	Stephen Gallimore, linux-serial, Grant Likely, Arnd Bergmann,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Rob Landley, Olof Johansson,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 10:21:00AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds support to ASC (asynchronous serial controller)
> driver, which is basically a standard serial driver. This IP is common
> across all the ST parts for settop box platforms.
> 
> ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
> It support all industry standard baud rates.

Your driver is not POSIX compliant.

> +		for (; count != 0; count--) {
> +			c = asc_in(port, ASC_RXBUF);
> +			flag = TTY_NORMAL;
> +			port->icount.rx++;
> +
> +			if (unlikely(c & ASC_RXBUF_FE)) {
> +				if (c == ASC_RXBUF_FE) {
> +					port->icount.brk++;
> +					if (uart_handle_break(port))
> +						continue;
> +					flag = TTY_BREAK;
> +				} else {
> +					port->icount.frame++;
> +					flag = TTY_FRAME;
> +				}
> +			} else if (ascport->check_parity &&
> +				   unlikely(c & ASC_RXBUF_PE)) {
> +				port->icount.parity++;
> +				flag = TTY_PARITY;
> +			}
> +
> +			if (uart_handle_sysrq_char(port, c))
> +				continue;
> +			tty_insert_flip_char(tport, c & 0xff, flag);
> +		}
> +		if (overrun) {
> +			port->icount.overrun++;
> +			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
> +		}

No support for ignoring error conditions.  No support for ignoring all
input... and:

> +static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
> +			    struct ktermios *old)
> +{
> +	struct asc_port *ascport = to_asc_port(port);
> +	unsigned int baud;
> +	u32 ctrl_val;
> +	tcflag_t cflag;
> +	unsigned long flags;
> +
> +	port->uartclk = clk_get_rate(ascport->clk);
> +
> +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
> +	cflag = termios->c_cflag;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +
> +	/* read control register */
> +	ctrl_val = asc_in(port, ASC_CTL);
> +
> +	/* stop serial port and reset value */
> +	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
> +	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
> +
> +	/* reset fifo rx & tx */
> +	asc_out(port, ASC_TXRESET, 1);
> +	asc_out(port, ASC_RXRESET, 1);
> +
> +	/* set character length */
> +	if ((cflag & CSIZE) == CS7) {
> +		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
> +	} else {
> +		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
> +						ASC_CTL_MODE_8BIT;
> +	}
> +
> +	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
> +
> +	/* set stop bit */
> +	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
> +
> +	/* odd parity */
> +	if (cflag & PARODD)
> +		ctrl_val |= ASC_CTL_PARITYODD;
> +
> +	/* hardware flow control */
> +	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
> +		ctrl_val |= ASC_CTL_CTSENABLE;

This doesn't reflect those facts back into the termios structure to
indicate that they aren't supported.

Consider using uart_port's ignore and read status masks to implement
the break, framing, parity and overrun checking in your interrupt
handler using the same methodology as drivers like 8250, amba-pl011
etc.  That will help you get these code sequences correct.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
@ 2013-06-10  9:35       ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 10:21:00AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds support to ASC (asynchronous serial controller)
> driver, which is basically a standard serial driver. This IP is common
> across all the ST parts for settop box platforms.
> 
> ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
> It support all industry standard baud rates.

Your driver is not POSIX compliant.

> +		for (; count != 0; count--) {
> +			c = asc_in(port, ASC_RXBUF);
> +			flag = TTY_NORMAL;
> +			port->icount.rx++;
> +
> +			if (unlikely(c & ASC_RXBUF_FE)) {
> +				if (c == ASC_RXBUF_FE) {
> +					port->icount.brk++;
> +					if (uart_handle_break(port))
> +						continue;
> +					flag = TTY_BREAK;
> +				} else {
> +					port->icount.frame++;
> +					flag = TTY_FRAME;
> +				}
> +			} else if (ascport->check_parity &&
> +				   unlikely(c & ASC_RXBUF_PE)) {
> +				port->icount.parity++;
> +				flag = TTY_PARITY;
> +			}
> +
> +			if (uart_handle_sysrq_char(port, c))
> +				continue;
> +			tty_insert_flip_char(tport, c & 0xff, flag);
> +		}
> +		if (overrun) {
> +			port->icount.overrun++;
> +			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
> +		}

No support for ignoring error conditions.  No support for ignoring all
input... and:

> +static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
> +			    struct ktermios *old)
> +{
> +	struct asc_port *ascport = to_asc_port(port);
> +	unsigned int baud;
> +	u32 ctrl_val;
> +	tcflag_t cflag;
> +	unsigned long flags;
> +
> +	port->uartclk = clk_get_rate(ascport->clk);
> +
> +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
> +	cflag = termios->c_cflag;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +
> +	/* read control register */
> +	ctrl_val = asc_in(port, ASC_CTL);
> +
> +	/* stop serial port and reset value */
> +	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
> +	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
> +
> +	/* reset fifo rx & tx */
> +	asc_out(port, ASC_TXRESET, 1);
> +	asc_out(port, ASC_RXRESET, 1);
> +
> +	/* set character length */
> +	if ((cflag & CSIZE) == CS7) {
> +		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
> +	} else {
> +		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
> +						ASC_CTL_MODE_8BIT;
> +	}
> +
> +	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
> +
> +	/* set stop bit */
> +	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
> +
> +	/* odd parity */
> +	if (cflag & PARODD)
> +		ctrl_val |= ASC_CTL_PARITYODD;
> +
> +	/* hardware flow control */
> +	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
> +		ctrl_val |= ASC_CTL_CTSENABLE;

This doesn't reflect those facts back into the termios structure to
indicate that they aren't supported.

Consider using uart_port's ignore and read status masks to implement
the break, framing, parity and overrun checking in your interrupt
handler using the same methodology as drivers like 8250, amba-pl011
etc.  That will help you get these code sequences correct.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10  9:26     ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
@ 2013-06-10  9:55       ` Michal Simek
  -1 siblings, 0 replies; 716+ messages in thread
From: Michal Simek @ 2013-06-10  9:55 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 2 bytes --]



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10  9:55       ` Michal Simek
  0 siblings, 0 replies; 716+ messages in thread
From: Michal Simek @ 2013-06-10  9:55 UTC (permalink / raw)
  To: linux-arm-kernel


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130610/317ae450/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-10  9:27     ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10 10:40       ` Mark Rutland
  -1 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 10:40 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Mauro Carvalho Chehab, linux-doc, linux,
	Samuel Ortiz, Stephen Gallimore, linux-serial, grant.likely,
	devicetree-discuss, rob.herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, Greg Kroah-Hartman, linux-kernel,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds stih415 and stih416 support to multi_v7_defconfig.

This seems to drop a few options also:

CONFIG_ARM_ARCH_TIMER
CONFIG_ARM_ERRATA_754322
CONFIG_EXPERIMENTAL
CONFIG_GPIO_PL061
CONFIG_MMC_WMT

I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
ARM_ERRATA_754322 are left unselected.

Thanks,
Mark.

> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> ---
>  arch/arm/configs/multi_v7_defconfig |   32 +++++++++++++++-----------------
>  1 files changed, 15 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 2e67a27..8a5cd5c 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -1,23 +1,20 @@
> -CONFIG_EXPERIMENTAL=y
>  CONFIG_NO_HZ=y
>  CONFIG_HIGH_RES_TIMERS=y
>  CONFIG_ARCH_MVEBU=y
>  CONFIG_MACH_ARMADA_370=y
> -CONFIG_ARCH_SIRF=y
>  CONFIG_MACH_ARMADA_XP=y
>  CONFIG_ARCH_HIGHBANK=y
>  CONFIG_ARCH_SOCFPGA=y
> -CONFIG_ARCH_SUNXI=y
> -CONFIG_ARCH_WM8850=y
> -# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
> -CONFIG_ARCH_ZYNQ=y
> -CONFIG_ARM_ERRATA_754322=y
>  CONFIG_PLAT_SPEAR=y
>  CONFIG_ARCH_SPEAR13XX=y
>  CONFIG_MACH_SPEAR1310=y
>  CONFIG_MACH_SPEAR1340=y
> +CONFIG_ARCH_STIXXXX=y
> +CONFIG_ARCH_SUNXI=y
> +CONFIG_ARCH_SIRF=y
> +CONFIG_ARCH_WM8850=y
> +CONFIG_ARCH_ZYNQ=y
>  CONFIG_SMP=y
> -CONFIG_ARM_ARCH_TIMER=y
>  CONFIG_AEABI=y
>  CONFIG_HIGHMEM=y
>  CONFIG_HIGHPTE=y
> @@ -25,27 +22,30 @@ CONFIG_ARM_APPENDED_DTB=y
>  CONFIG_VFP=y
>  CONFIG_NEON=y
>  CONFIG_NET=y
> +CONFIG_DEVTMPFS=y
>  CONFIG_BLK_DEV_SD=y
>  CONFIG_ATA=y
> +CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_SATA_HIGHBANK=y
>  CONFIG_SATA_MV=y
> -CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_NETDEVICES=y
>  CONFIG_NET_CALXEDA_XGMAC=y
>  CONFIG_SMSC911X=y
>  CONFIG_STMMAC_ETH=y
> +CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIO_AMBAKMI=y
>  CONFIG_SERIAL_8250=y
>  CONFIG_SERIAL_8250_CONSOLE=y
>  CONFIG_SERIAL_8250_DW=y
> -CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIAL_AMBA_PL011=y
>  CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
> -CONFIG_SERIAL_OF_PLATFORM=y
>  CONFIG_SERIAL_SIRFSOC=y
>  CONFIG_SERIAL_SIRFSOC_CONSOLE=y
>  CONFIG_SERIAL_VT8500=y
>  CONFIG_SERIAL_VT8500_CONSOLE=y
> +CONFIG_SERIAL_OF_PLATFORM=y
> +CONFIG_SERIAL_ST_ASC=y
> +CONFIG_SERIAL_ST_ASC_CONSOLE=y
>  CONFIG_IPMI_HANDLER=y
>  CONFIG_IPMI_SI=y
>  CONFIG_I2C=y
> @@ -54,7 +54,6 @@ CONFIG_I2C_SIRF=y
>  CONFIG_SPI=y
>  CONFIG_SPI_PL022=y
>  CONFIG_SPI_SIRF=y
> -CONFIG_GPIO_PL061=y
>  CONFIG_FB=y
>  CONFIG_FB_ARMCLCD=y
>  CONFIG_FB_WM8505=y
> @@ -67,7 +66,6 @@ CONFIG_MMC_ARMMMCI=y
>  CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_SDHCI_SPEAR=y
> -CONFIG_MMC_WMT=y
>  CONFIG_EDAC=y
>  CONFIG_EDAC_MM_EDAC=y
>  CONFIG_EDAC_HIGHBANK_MC=y
> @@ -75,9 +73,9 @@ CONFIG_EDAC_HIGHBANK_L2=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_PL031=y
>  CONFIG_RTC_DRV_VT8500=y
> -CONFIG_PWM=y
> -CONFIG_PWM_VT8500=y
>  CONFIG_DMADEVICES=y
> -CONFIG_PL330_DMA=y
> -CONFIG_SIRF_DMA=y
>  CONFIG_DW_DMAC=y
> +CONFIG_SIRF_DMA=y
> +CONFIG_PL330_DMA=y
> +CONFIG_PWM=y
> +CONFIG_PWM_VT8500=y
> -- 
> 1.7.6.5
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 10:40       ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 10:40 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Mauro Carvalho Chehab, linux-doc, linux,
	Samuel Ortiz, Stephen Gallimore, linux-serial, grant.likely,
	devicetree-discuss, rob.herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, Greg Kroah-Hartman, linux-kernel,
	Andrew Morton, David

On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds stih415 and stih416 support to multi_v7_defconfig.

This seems to drop a few options also:

CONFIG_ARM_ARCH_TIMER
CONFIG_ARM_ERRATA_754322
CONFIG_EXPERIMENTAL
CONFIG_GPIO_PL061
CONFIG_MMC_WMT

I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
ARM_ERRATA_754322 are left unselected.

Thanks,
Mark.

> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> ---
>  arch/arm/configs/multi_v7_defconfig |   32 +++++++++++++++-----------------
>  1 files changed, 15 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 2e67a27..8a5cd5c 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -1,23 +1,20 @@
> -CONFIG_EXPERIMENTAL=y
>  CONFIG_NO_HZ=y
>  CONFIG_HIGH_RES_TIMERS=y
>  CONFIG_ARCH_MVEBU=y
>  CONFIG_MACH_ARMADA_370=y
> -CONFIG_ARCH_SIRF=y
>  CONFIG_MACH_ARMADA_XP=y
>  CONFIG_ARCH_HIGHBANK=y
>  CONFIG_ARCH_SOCFPGA=y
> -CONFIG_ARCH_SUNXI=y
> -CONFIG_ARCH_WM8850=y
> -# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
> -CONFIG_ARCH_ZYNQ=y
> -CONFIG_ARM_ERRATA_754322=y
>  CONFIG_PLAT_SPEAR=y
>  CONFIG_ARCH_SPEAR13XX=y
>  CONFIG_MACH_SPEAR1310=y
>  CONFIG_MACH_SPEAR1340=y
> +CONFIG_ARCH_STIXXXX=y
> +CONFIG_ARCH_SUNXI=y
> +CONFIG_ARCH_SIRF=y
> +CONFIG_ARCH_WM8850=y
> +CONFIG_ARCH_ZYNQ=y
>  CONFIG_SMP=y
> -CONFIG_ARM_ARCH_TIMER=y
>  CONFIG_AEABI=y
>  CONFIG_HIGHMEM=y
>  CONFIG_HIGHPTE=y
> @@ -25,27 +22,30 @@ CONFIG_ARM_APPENDED_DTB=y
>  CONFIG_VFP=y
>  CONFIG_NEON=y
>  CONFIG_NET=y
> +CONFIG_DEVTMPFS=y
>  CONFIG_BLK_DEV_SD=y
>  CONFIG_ATA=y
> +CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_SATA_HIGHBANK=y
>  CONFIG_SATA_MV=y
> -CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_NETDEVICES=y
>  CONFIG_NET_CALXEDA_XGMAC=y
>  CONFIG_SMSC911X=y
>  CONFIG_STMMAC_ETH=y
> +CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIO_AMBAKMI=y
>  CONFIG_SERIAL_8250=y
>  CONFIG_SERIAL_8250_CONSOLE=y
>  CONFIG_SERIAL_8250_DW=y
> -CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIAL_AMBA_PL011=y
>  CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
> -CONFIG_SERIAL_OF_PLATFORM=y
>  CONFIG_SERIAL_SIRFSOC=y
>  CONFIG_SERIAL_SIRFSOC_CONSOLE=y
>  CONFIG_SERIAL_VT8500=y
>  CONFIG_SERIAL_VT8500_CONSOLE=y
> +CONFIG_SERIAL_OF_PLATFORM=y
> +CONFIG_SERIAL_ST_ASC=y
> +CONFIG_SERIAL_ST_ASC_CONSOLE=y
>  CONFIG_IPMI_HANDLER=y
>  CONFIG_IPMI_SI=y
>  CONFIG_I2C=y
> @@ -54,7 +54,6 @@ CONFIG_I2C_SIRF=y
>  CONFIG_SPI=y
>  CONFIG_SPI_PL022=y
>  CONFIG_SPI_SIRF=y
> -CONFIG_GPIO_PL061=y
>  CONFIG_FB=y
>  CONFIG_FB_ARMCLCD=y
>  CONFIG_FB_WM8505=y
> @@ -67,7 +66,6 @@ CONFIG_MMC_ARMMMCI=y
>  CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_SDHCI_SPEAR=y
> -CONFIG_MMC_WMT=y
>  CONFIG_EDAC=y
>  CONFIG_EDAC_MM_EDAC=y
>  CONFIG_EDAC_HIGHBANK_MC=y
> @@ -75,9 +73,9 @@ CONFIG_EDAC_HIGHBANK_L2=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_PL031=y
>  CONFIG_RTC_DRV_VT8500=y
> -CONFIG_PWM=y
> -CONFIG_PWM_VT8500=y
>  CONFIG_DMADEVICES=y
> -CONFIG_PL330_DMA=y
> -CONFIG_SIRF_DMA=y
>  CONFIG_DW_DMAC=y
> +CONFIG_SIRF_DMA=y
> +CONFIG_PL330_DMA=y
> +CONFIG_PWM=y
> +CONFIG_PWM_VT8500=y
> -- 
> 1.7.6.5
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 10:40       ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> This patch adds stih415 and stih416 support to multi_v7_defconfig.

This seems to drop a few options also:

CONFIG_ARM_ARCH_TIMER
CONFIG_ARM_ERRATA_754322
CONFIG_EXPERIMENTAL
CONFIG_GPIO_PL061
CONFIG_MMC_WMT

I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
ARM_ERRATA_754322 are left unselected.

Thanks,
Mark.

> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> ---
>  arch/arm/configs/multi_v7_defconfig |   32 +++++++++++++++-----------------
>  1 files changed, 15 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index 2e67a27..8a5cd5c 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -1,23 +1,20 @@
> -CONFIG_EXPERIMENTAL=y
>  CONFIG_NO_HZ=y
>  CONFIG_HIGH_RES_TIMERS=y
>  CONFIG_ARCH_MVEBU=y
>  CONFIG_MACH_ARMADA_370=y
> -CONFIG_ARCH_SIRF=y
>  CONFIG_MACH_ARMADA_XP=y
>  CONFIG_ARCH_HIGHBANK=y
>  CONFIG_ARCH_SOCFPGA=y
> -CONFIG_ARCH_SUNXI=y
> -CONFIG_ARCH_WM8850=y
> -# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
> -CONFIG_ARCH_ZYNQ=y
> -CONFIG_ARM_ERRATA_754322=y
>  CONFIG_PLAT_SPEAR=y
>  CONFIG_ARCH_SPEAR13XX=y
>  CONFIG_MACH_SPEAR1310=y
>  CONFIG_MACH_SPEAR1340=y
> +CONFIG_ARCH_STIXXXX=y
> +CONFIG_ARCH_SUNXI=y
> +CONFIG_ARCH_SIRF=y
> +CONFIG_ARCH_WM8850=y
> +CONFIG_ARCH_ZYNQ=y
>  CONFIG_SMP=y
> -CONFIG_ARM_ARCH_TIMER=y
>  CONFIG_AEABI=y
>  CONFIG_HIGHMEM=y
>  CONFIG_HIGHPTE=y
> @@ -25,27 +22,30 @@ CONFIG_ARM_APPENDED_DTB=y
>  CONFIG_VFP=y
>  CONFIG_NEON=y
>  CONFIG_NET=y
> +CONFIG_DEVTMPFS=y
>  CONFIG_BLK_DEV_SD=y
>  CONFIG_ATA=y
> +CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_SATA_HIGHBANK=y
>  CONFIG_SATA_MV=y
> -CONFIG_SATA_AHCI_PLATFORM=y
>  CONFIG_NETDEVICES=y
>  CONFIG_NET_CALXEDA_XGMAC=y
>  CONFIG_SMSC911X=y
>  CONFIG_STMMAC_ETH=y
> +CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIO_AMBAKMI=y
>  CONFIG_SERIAL_8250=y
>  CONFIG_SERIAL_8250_CONSOLE=y
>  CONFIG_SERIAL_8250_DW=y
> -CONFIG_KEYBOARD_SPEAR=y
>  CONFIG_SERIAL_AMBA_PL011=y
>  CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
> -CONFIG_SERIAL_OF_PLATFORM=y
>  CONFIG_SERIAL_SIRFSOC=y
>  CONFIG_SERIAL_SIRFSOC_CONSOLE=y
>  CONFIG_SERIAL_VT8500=y
>  CONFIG_SERIAL_VT8500_CONSOLE=y
> +CONFIG_SERIAL_OF_PLATFORM=y
> +CONFIG_SERIAL_ST_ASC=y
> +CONFIG_SERIAL_ST_ASC_CONSOLE=y
>  CONFIG_IPMI_HANDLER=y
>  CONFIG_IPMI_SI=y
>  CONFIG_I2C=y
> @@ -54,7 +54,6 @@ CONFIG_I2C_SIRF=y
>  CONFIG_SPI=y
>  CONFIG_SPI_PL022=y
>  CONFIG_SPI_SIRF=y
> -CONFIG_GPIO_PL061=y
>  CONFIG_FB=y
>  CONFIG_FB_ARMCLCD=y
>  CONFIG_FB_WM8505=y
> @@ -67,7 +66,6 @@ CONFIG_MMC_ARMMMCI=y
>  CONFIG_MMC_SDHCI=y
>  CONFIG_MMC_SDHCI_PLTFM=y
>  CONFIG_MMC_SDHCI_SPEAR=y
> -CONFIG_MMC_WMT=y
>  CONFIG_EDAC=y
>  CONFIG_EDAC_MM_EDAC=y
>  CONFIG_EDAC_HIGHBANK_MC=y
> @@ -75,9 +73,9 @@ CONFIG_EDAC_HIGHBANK_L2=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_PL031=y
>  CONFIG_RTC_DRV_VT8500=y
> -CONFIG_PWM=y
> -CONFIG_PWM_VT8500=y
>  CONFIG_DMADEVICES=y
> -CONFIG_PL330_DMA=y
> -CONFIG_SIRF_DMA=y
>  CONFIG_DW_DMAC=y
> +CONFIG_SIRF_DMA=y
> +CONFIG_PL330_DMA=y
> +CONFIG_PWM=y
> +CONFIG_PWM_VT8500=y
> -- 
> 1.7.6.5
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-10 10:40       ` Mark Rutland
  (?)
@ 2013-06-10 10:58         ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 10:58 UTC (permalink / raw)
  To: Mark Rutland
  Cc: David S. Miller, linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	rob.herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, grant.likely, Thomas Gleixner,
	Andrew Morton, linux-arm-kernel, Mauro Carvalho Chehab

Thanks for testing...
On 10/06/13 11:40, Mark Rutland wrote:
> On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
>> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> This seems to drop a few options also:
> 
> CONFIG_ARM_ARCH_TIMER

Same as last comment 2:
> CONFIG_ARM_ERRATA_754322
ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
it disappears, Should the mach level Kconfig select that?

> CONFIG_EXPERIMENTAL
> CONFIG_GPIO_PL061
> CONFIG_MMC_WMT

Comment 2: Without any modifications to multi_v7_defconfig if I run
savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
Which suggests that these options seems to be selected by another
kconfigs or mach level. And since then the multi_v7_defconfig was not
run with savedefconfig.


Thanks,
srini
> 
> I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
> It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
> ARM_ERRATA_754322 are left unselected.
> 
> Thanks,
> Mark.
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 10:58         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 10:58 UTC (permalink / raw)
  To: Mark Rutland
  Cc: David S. Miller, linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	rob.herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, grant.likely, Thomas Gleixner,
	Andrew Morton, linux-arm-kernel, Mauro

Thanks for testing...
On 10/06/13 11:40, Mark Rutland wrote:
> On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
>> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> This seems to drop a few options also:
> 
> CONFIG_ARM_ARCH_TIMER

Same as last comment 2:
> CONFIG_ARM_ERRATA_754322
ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
it disappears, Should the mach level Kconfig select that?

> CONFIG_EXPERIMENTAL
> CONFIG_GPIO_PL061
> CONFIG_MMC_WMT

Comment 2: Without any modifications to multi_v7_defconfig if I run
savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
Which suggests that these options seems to be selected by another
kconfigs or mach level. And since then the multi_v7_defconfig was not
run with savedefconfig.


Thanks,
srini
> 
> I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
> It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
> ARM_ERRATA_754322 are left unselected.
> 
> Thanks,
> Mark.
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 10:58         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 10:58 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for testing...
On 10/06/13 11:40, Mark Rutland wrote:
> On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
>> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> This seems to drop a few options also:
> 
> CONFIG_ARM_ARCH_TIMER

Same as last comment 2:
> CONFIG_ARM_ERRATA_754322
ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
it disappears, Should the mach level Kconfig select that?

> CONFIG_EXPERIMENTAL
> CONFIG_GPIO_PL061
> CONFIG_MMC_WMT

Comment 2: Without any modifications to multi_v7_defconfig if I run
savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
Which suggests that these options seems to be selected by another
kconfigs or mach level. And since then the multi_v7_defconfig was not
run with savedefconfig.


Thanks,
srini
> 
> I just applied this to v3.10-rc5, and ran `make ARCH=arm multi_v7_defconfig`.
> It seems MMC_WMT and GPIO_PL061 get selected elsewhere, but ARM_ARCH_TIMER and
> ARM_ERRATA_754322 are left unselected.
> 
> Thanks,
> Mark.
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10  9:26     ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
@ 2013-06-10 11:08       ` Michal Simek
  -1 siblings, 0 replies; 716+ messages in thread
From: Michal Simek @ 2013-06-10 11:08 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 2 bytes --]



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 11:08       ` Michal Simek
  0 siblings, 0 replies; 716+ messages in thread
From: Michal Simek @ 2013-06-10 11:08 UTC (permalink / raw)
  To: linux-arm-kernel


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130610/caf5687e/attachment.sig>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
       [not found]     ` <CAHTX3d+dk3W_9b7SVUokWq4KYXnj=Z1=WPj5zJ-gUvJqqwE=+Q@mail.gmail.com>
  2013-06-10 11:46         ` Srinivas KANDAGATLA
@ 2013-06-10 11:46         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 11:46 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-arm, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, Russell King, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On 10/06/13 12:15, Michal Simek wrote:

Thankyou for your comments,
> Hi,
> 
> hmm - that's a nice bug that thunderbird is not able to send this email. :-(
> Let's comment it again via gmail.
>     diff --git a/arch/arm/boot/dts/stih415.dtsi
>     b/arch/arm/boot/dts/stih415.dtsi
>     new file mode 100644
>     index 0000000..6dcf5b4
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih415.dtsi
...
>     +
>     +       soc {
>     +               #address-cells = <1>;
>     +               #size-cells = <1>;
>     +               interrupt-parent = <&intc>;
>     +               ranges;
>     +               compatible      = "simple-bus";
> 
> 
> 
> Rob and Grant: what's the purpose of SoC node.
> It seems to me odd that SoC is compatible with simple-bus.

All the drivers on this SOC are based on platform bus, so we use
simple-bus, here.

>     diff --git a/arch/arm/boot/dts/stih41x.dtsi
>     b/arch/arm/boot/dts/stih41x.dtsi
>     new file mode 100644
>     index 0000000..7321403
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih41x.dtsi
>     @@ -0,0 +1,38 @@
>     +/ {
>     +       #address-cells = <1>;
>     +       #size-cells = <1>;
>     +
>     +       cpus {
>     +               #address-cells = <1>;
>     +               #size-cells = <0>;
>     +               cpu@0 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <0>;
>     +               };
>     +               cpu@1 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <1>;
>     +               };
>     +       };
>     +
> 
> 
> I believe your SoC also has a bus here.

It does but there is no active driver to manage it.

>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/board-dt.c
>     @@ -0,0 +1,47 @@

>     +
>     +void __init stih41x_l2x0_init(void)
>     +{
>     +       u32 way_size = 0x4;
>     +       u32 aux_ctrl;
>     +
>     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> 
> 
> 
> #include <linux/bitops.h>
> Linus Walleij would write use  BIT() here

I will use BIT() macro.

>     diff --git a/arch/arm/mach-stixxxx/headsmp.S
>     b/arch/arm/mach-stixxxx/headsmp.S
>     new file mode 100644
>     index 0000000..3dd5c04
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/headsmp.S
>     @@ -0,0 +1,44 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/headsmp.S
> 

>     +       .long   pen_release
> 
> 
> check that your SoC has no option to start/reset cpus separately.
> If yes, then you shouldn't use pen_release.
> We discussed this with Russel some days ago.
No, stih41x series can't reset the cores separately.
>  
> 
>     diff --git a/arch/arm/mach-stixxxx/platsmp.c
>     b/arch/arm/mach-stixxxx/platsmp.c
>     new file mode 100644
>     index 0000000..ffc40c0
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/platsmp.c
>     @@ -0,0 +1,117 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> wrong.

Left over, will clean it up in next version.

>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> incorrect.
Left over, will clean it up in next version.
>  
>     +extern struct smp_operations   stixxxx_smp_ops;
>     +extern void __iomem *stixxxx_scu_base_addr;
> 
> 
> Unused variable in this patch.
yes, I will remove stixxxx_scu_base_addr.

thanks,
srini



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 11:46         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 11:46 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-arm, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, Russell King, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony

On 10/06/13 12:15, Michal Simek wrote:

Thankyou for your comments,
> Hi,
> 
> hmm - that's a nice bug that thunderbird is not able to send this email. :-(
> Let's comment it again via gmail.
>     diff --git a/arch/arm/boot/dts/stih415.dtsi
>     b/arch/arm/boot/dts/stih415.dtsi
>     new file mode 100644
>     index 0000000..6dcf5b4
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih415.dtsi
...
>     +
>     +       soc {
>     +               #address-cells = <1>;
>     +               #size-cells = <1>;
>     +               interrupt-parent = <&intc>;
>     +               ranges;
>     +               compatible      = "simple-bus";
> 
> 
> 
> Rob and Grant: what's the purpose of SoC node.
> It seems to me odd that SoC is compatible with simple-bus.

All the drivers on this SOC are based on platform bus, so we use
simple-bus, here.

>     diff --git a/arch/arm/boot/dts/stih41x.dtsi
>     b/arch/arm/boot/dts/stih41x.dtsi
>     new file mode 100644
>     index 0000000..7321403
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih41x.dtsi
>     @@ -0,0 +1,38 @@
>     +/ {
>     +       #address-cells = <1>;
>     +       #size-cells = <1>;
>     +
>     +       cpus {
>     +               #address-cells = <1>;
>     +               #size-cells = <0>;
>     +               cpu@0 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <0>;
>     +               };
>     +               cpu@1 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <1>;
>     +               };
>     +       };
>     +
> 
> 
> I believe your SoC also has a bus here.

It does but there is no active driver to manage it.

>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/board-dt.c
>     @@ -0,0 +1,47 @@

>     +
>     +void __init stih41x_l2x0_init(void)
>     +{
>     +       u32 way_size = 0x4;
>     +       u32 aux_ctrl;
>     +
>     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> 
> 
> 
> #include <linux/bitops.h>
> Linus Walleij would write use  BIT() here

I will use BIT() macro.

>     diff --git a/arch/arm/mach-stixxxx/headsmp.S
>     b/arch/arm/mach-stixxxx/headsmp.S
>     new file mode 100644
>     index 0000000..3dd5c04
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/headsmp.S
>     @@ -0,0 +1,44 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/headsmp.S
> 

>     +       .long   pen_release
> 
> 
> check that your SoC has no option to start/reset cpus separately.
> If yes, then you shouldn't use pen_release.
> We discussed this with Russel some days ago.
No, stih41x series can't reset the cores separately.
>  
> 
>     diff --git a/arch/arm/mach-stixxxx/platsmp.c
>     b/arch/arm/mach-stixxxx/platsmp.c
>     new file mode 100644
>     index 0000000..ffc40c0
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/platsmp.c
>     @@ -0,0 +1,117 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> wrong.

Left over, will clean it up in next version.

>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> incorrect.
Left over, will clean it up in next version.
>  
>     +extern struct smp_operations   stixxxx_smp_ops;
>     +extern void __iomem *stixxxx_scu_base_addr;
> 
> 
> Unused variable in this patch.
yes, I will remove stixxxx_scu_base_addr.

thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 11:46         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 12:15, Michal Simek wrote:

Thankyou for your comments,
> Hi,
> 
> hmm - that's a nice bug that thunderbird is not able to send this email. :-(
> Let's comment it again via gmail.
>     diff --git a/arch/arm/boot/dts/stih415.dtsi
>     b/arch/arm/boot/dts/stih415.dtsi
>     new file mode 100644
>     index 0000000..6dcf5b4
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih415.dtsi
...
>     +
>     +       soc {
>     +               #address-cells = <1>;
>     +               #size-cells = <1>;
>     +               interrupt-parent = <&intc>;
>     +               ranges;
>     +               compatible      = "simple-bus";
> 
> 
> 
> Rob and Grant: what's the purpose of SoC node.
> It seems to me odd that SoC is compatible with simple-bus.

All the drivers on this SOC are based on platform bus, so we use
simple-bus, here.

>     diff --git a/arch/arm/boot/dts/stih41x.dtsi
>     b/arch/arm/boot/dts/stih41x.dtsi
>     new file mode 100644
>     index 0000000..7321403
>     --- /dev/null
>     +++ b/arch/arm/boot/dts/stih41x.dtsi
>     @@ -0,0 +1,38 @@
>     +/ {
>     +       #address-cells = <1>;
>     +       #size-cells = <1>;
>     +
>     +       cpus {
>     +               #address-cells = <1>;
>     +               #size-cells = <0>;
>     +               cpu at 0 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <0>;
>     +               };
>     +               cpu at 1 {
>     +                       compatible = "arm,cortex-a9";
>     +                       reg = <1>;
>     +               };
>     +       };
>     +
> 
> 
> I believe your SoC also has a bus here.

It does but there is no active driver to manage it.

>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/board-dt.c
>     @@ -0,0 +1,47 @@

>     +
>     +void __init stih41x_l2x0_init(void)
>     +{
>     +       u32 way_size = 0x4;
>     +       u32 aux_ctrl;
>     +
>     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> 
> 
> 
> #include <linux/bitops.h>
> Linus Walleij would write use  BIT() here

I will use BIT() macro.

>     diff --git a/arch/arm/mach-stixxxx/headsmp.S
>     b/arch/arm/mach-stixxxx/headsmp.S
>     new file mode 100644
>     index 0000000..3dd5c04
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/headsmp.S
>     @@ -0,0 +1,44 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/headsmp.S
> 

>     +       .long   pen_release
> 
> 
> check that your SoC has no option to start/reset cpus separately.
> If yes, then you shouldn't use pen_release.
> We discussed this with Russel some days ago.
No, stih41x series can't reset the cores separately.
>  
> 
>     diff --git a/arch/arm/mach-stixxxx/platsmp.c
>     b/arch/arm/mach-stixxxx/platsmp.c
>     new file mode 100644
>     index 0000000..ffc40c0
>     --- /dev/null
>     +++ b/arch/arm/mach-stixxxx/platsmp.c
>     @@ -0,0 +1,117 @@
>     +/*
>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> wrong.

Left over, will clean it up in next version.

>     + *  arch/arm/plat-stixxxx/platsmp.c
> 
> 
> incorrect.
Left over, will clean it up in next version.
>  
>     +extern struct smp_operations   stixxxx_smp_ops;
>     +extern void __iomem *stixxxx_scu_base_addr;
> 
> 
> Unused variable in this patch.
yes, I will remove stixxxx_scu_base_addr.

thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
  2013-06-10  9:35       ` Russell King - ARM Linux
@ 2013-06-10 11:53         ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 11:53 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

Thankyou for your comment and suggestion,
I will fix the POSIX compliant issue.

On 10/06/13 10:35, Russell King - ARM Linux wrote:
> On Mon, Jun 10, 2013 at 10:21:00AM +0100, Srinivas KANDAGATLA wrote:
>> This patch adds support to ASC (asynchronous serial controller)
>> driver, which is basically a standard serial driver. This IP is common
>> across all the ST parts for settop box platforms.
>>
>> ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
>> It support all industry standard baud rates.
> 
> Your driver is not POSIX compliant.
> 
>> +		for (; count != 0; count--) {
>> +			c = asc_in(port, ASC_RXBUF);
>> +			flag = TTY_NORMAL;
>> +			port->icount.rx++;
>> +
>> +			if (unlikely(c & ASC_RXBUF_FE)) {
>> +				if (c == ASC_RXBUF_FE) {
>> +					port->icount.brk++;
>> +					if (uart_handle_break(port))
>> +						continue;
>> +					flag = TTY_BREAK;
>> +				} else {
>> +					port->icount.frame++;
>> +					flag = TTY_FRAME;
>> +				}
>> +			} else if (ascport->check_parity &&
>> +				   unlikely(c & ASC_RXBUF_PE)) {
>> +				port->icount.parity++;
>> +				flag = TTY_PARITY;
>> +			}
>> +
>> +			if (uart_handle_sysrq_char(port, c))
>> +				continue;
>> +			tty_insert_flip_char(tport, c & 0xff, flag);
>> +		}
>> +		if (overrun) {
>> +			port->icount.overrun++;
>> +			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
>> +		}
> 
> No support for ignoring error conditions.  No support for ignoring all
> input... and:
> 
>> +static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
>> +			    struct ktermios *old)
>> +{
>> +	struct asc_port *ascport = to_asc_port(port);
>> +	unsigned int baud;
>> +	u32 ctrl_val;
>> +	tcflag_t cflag;
>> +	unsigned long flags;
>> +
>> +	port->uartclk = clk_get_rate(ascport->clk);
>> +
>> +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
>> +	cflag = termios->c_cflag;
>> +
>> +	spin_lock_irqsave(&port->lock, flags);
>> +
>> +	/* read control register */
>> +	ctrl_val = asc_in(port, ASC_CTL);
>> +
>> +	/* stop serial port and reset value */
>> +	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
>> +	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
>> +
>> +	/* reset fifo rx & tx */
>> +	asc_out(port, ASC_TXRESET, 1);
>> +	asc_out(port, ASC_RXRESET, 1);
>> +
>> +	/* set character length */
>> +	if ((cflag & CSIZE) == CS7) {
>> +		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
>> +	} else {
>> +		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
>> +						ASC_CTL_MODE_8BIT;
>> +	}
>> +
>> +	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
>> +
>> +	/* set stop bit */
>> +	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
>> +
>> +	/* odd parity */
>> +	if (cflag & PARODD)
>> +		ctrl_val |= ASC_CTL_PARITYODD;
>> +
>> +	/* hardware flow control */
>> +	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
>> +		ctrl_val |= ASC_CTL_CTSENABLE;
> 
> This doesn't reflect those facts back into the termios structure to
> indicate that they aren't supported.
> 
> Consider using uart_port's ignore and read status masks to implement
> the break, framing, parity and overrun checking in your interrupt
> handler using the same methodology as drivers like 8250, amba-pl011
> etc.  That will help you get these code sequences correct.
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 01/11] serial:st-asc: Add ST ASC driver.
@ 2013-06-10 11:53         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 11:53 UTC (permalink / raw)
  To: linux-arm-kernel

Thankyou for your comment and suggestion,
I will fix the POSIX compliant issue.

On 10/06/13 10:35, Russell King - ARM Linux wrote:
> On Mon, Jun 10, 2013 at 10:21:00AM +0100, Srinivas KANDAGATLA wrote:
>> This patch adds support to ASC (asynchronous serial controller)
>> driver, which is basically a standard serial driver. This IP is common
>> across all the ST parts for settop box platforms.
>>
>> ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality.
>> It support all industry standard baud rates.
> 
> Your driver is not POSIX compliant.
> 
>> +		for (; count != 0; count--) {
>> +			c = asc_in(port, ASC_RXBUF);
>> +			flag = TTY_NORMAL;
>> +			port->icount.rx++;
>> +
>> +			if (unlikely(c & ASC_RXBUF_FE)) {
>> +				if (c == ASC_RXBUF_FE) {
>> +					port->icount.brk++;
>> +					if (uart_handle_break(port))
>> +						continue;
>> +					flag = TTY_BREAK;
>> +				} else {
>> +					port->icount.frame++;
>> +					flag = TTY_FRAME;
>> +				}
>> +			} else if (ascport->check_parity &&
>> +				   unlikely(c & ASC_RXBUF_PE)) {
>> +				port->icount.parity++;
>> +				flag = TTY_PARITY;
>> +			}
>> +
>> +			if (uart_handle_sysrq_char(port, c))
>> +				continue;
>> +			tty_insert_flip_char(tport, c & 0xff, flag);
>> +		}
>> +		if (overrun) {
>> +			port->icount.overrun++;
>> +			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
>> +		}
> 
> No support for ignoring error conditions.  No support for ignoring all
> input... and:
> 
>> +static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
>> +			    struct ktermios *old)
>> +{
>> +	struct asc_port *ascport = to_asc_port(port);
>> +	unsigned int baud;
>> +	u32 ctrl_val;
>> +	tcflag_t cflag;
>> +	unsigned long flags;
>> +
>> +	port->uartclk = clk_get_rate(ascport->clk);
>> +
>> +	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
>> +	cflag = termios->c_cflag;
>> +
>> +	spin_lock_irqsave(&port->lock, flags);
>> +
>> +	/* read control register */
>> +	ctrl_val = asc_in(port, ASC_CTL);
>> +
>> +	/* stop serial port and reset value */
>> +	asc_out(port, ASC_CTL, (ctrl_val & ~ASC_CTL_RUN));
>> +	ctrl_val = ASC_CTL_RXENABLE | ASC_CTL_FIFOENABLE;
>> +
>> +	/* reset fifo rx & tx */
>> +	asc_out(port, ASC_TXRESET, 1);
>> +	asc_out(port, ASC_RXRESET, 1);
>> +
>> +	/* set character length */
>> +	if ((cflag & CSIZE) == CS7) {
>> +		ctrl_val |= ASC_CTL_MODE_7BIT_PAR;
>> +	} else {
>> +		ctrl_val |= (cflag & PARENB) ?  ASC_CTL_MODE_8BIT_PAR :
>> +						ASC_CTL_MODE_8BIT;
>> +	}
>> +
>> +	ascport->check_parity = (cflag & PARENB) ? 1 : 0;
>> +
>> +	/* set stop bit */
>> +	ctrl_val |= (cflag & CSTOPB) ? ASC_CTL_STOP_2BIT : ASC_CTL_STOP_1BIT;
>> +
>> +	/* odd parity */
>> +	if (cflag & PARODD)
>> +		ctrl_val |= ASC_CTL_PARITYODD;
>> +
>> +	/* hardware flow control */
>> +	if ((cflag & CRTSCTS) && ascport->hw_flow_control)
>> +		ctrl_val |= ASC_CTL_CTSENABLE;
> 
> This doesn't reflect those facts back into the termios structure to
> indicate that they aren't supported.
> 
> Consider using uart_port's ignore and read status masks to implement
> the break, framing, parity and overrun checking in your interrupt
> handler using the same methodology as drivers like 8250, amba-pl011
> etc.  That will help you get these code sequences correct.
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10  9:26     ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
@ 2013-06-10 12:43         ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 12:43 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 11:26 AM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

> The STiH415 is the next generation of HD, AVC set-top box processors for
> satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
> 1.0 GHz, dual-core CPU.
(...)
> +       soc {
> +               pin-controller-sbc {
> +                       #address-cells  = <1>;
> +                       #size-cells     = <1>;
> +                       compatible      = "st,stih415-pinctrl", "simple-bus";

Why is the pin controller be a simple bus?

Maybe obvious, I'm not 100% familiar with when we use this...

> +               pin-controller-front {
(...)
> +               pin-controller-rear {
(...)
> +               pin-controller-left {
(...)
> +               pin-controller-right {

Please explain these orientations in some comment in the device
tree, I'm half-guessing that it's about the edges around the chip so
the PIO* names are actually pad names.

I would suggest you use the names north/south/west/east
if this is the case since left and right etc are relative measures.
(This terminology is used on e.g. dance mats for console games...)

If these names are from the datasheets by all means keep them.

> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
> @@ -0,0 +1,94 @@
> +#ifndef _STIXXXX_PINCFG_H_
> +#define _STIXXXX_PINCFG_H_
> +
> +/* Alternate functions */
> +#define ALT1   1
> +#define ALT2   2
> +#define ALT3   3
> +#define ALT4   4
> +#define ALT5   5
> +#define ALT6   6
> +#define ALT7   7

Why is this part of the DT definitions? In the pinctrl world this
is an intrinsic detail on how groups and functions are associated,
not something that you hard-code into the device tree. The
device tree should state how to combine functions with groups
and those will be strings, not numerals.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 12:43         ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 11:26 AM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

> The STiH415 is the next generation of HD, AVC set-top box processors for
> satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
> 1.0 GHz, dual-core CPU.
(...)
> +       soc {
> +               pin-controller-sbc {
> +                       #address-cells  = <1>;
> +                       #size-cells     = <1>;
> +                       compatible      = "st,stih415-pinctrl", "simple-bus";

Why is the pin controller be a simple bus?

Maybe obvious, I'm not 100% familiar with when we use this...

> +               pin-controller-front {
(...)
> +               pin-controller-rear {
(...)
> +               pin-controller-left {
(...)
> +               pin-controller-right {

Please explain these orientations in some comment in the device
tree, I'm half-guessing that it's about the edges around the chip so
the PIO* names are actually pad names.

I would suggest you use the names north/south/west/east
if this is the case since left and right etc are relative measures.
(This terminology is used on e.g. dance mats for console games...)

If these names are from the datasheets by all means keep them.

> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
> @@ -0,0 +1,94 @@
> +#ifndef _STIXXXX_PINCFG_H_
> +#define _STIXXXX_PINCFG_H_
> +
> +/* Alternate functions */
> +#define ALT1   1
> +#define ALT2   2
> +#define ALT3   3
> +#define ALT4   4
> +#define ALT5   5
> +#define ALT6   6
> +#define ALT7   7

Why is this part of the DT definitions? In the pinctrl world this
is an intrinsic detail on how groups and functions are associated,
not something that you hard-code into the device tree. The
device tree should state how to combine functions with groups
and those will be strings, not numerals.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
  2013-06-10  9:21     ` Srinivas KANDAGATLA
@ 2013-06-10 13:13         ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 13:13 UTC (permalink / raw)
  To: Srinivas KANDAGATLA, Mike Turquette
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Will Deacon, Russell King - ARM Linux, Samuel Ortiz,
	Stephen Gallimore, linux-serial-u79uwXL29TY76Z2rM5mHXA,
	Grant Likely, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Rob Herring, Stuart Menefy, Mark Brown, John Stultz,
	Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David

On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

> From: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
>
> This is a simple driver for the global timer module found in the Cortex
> A9-MP cores from revision r1p0 onwards. This should be able to perform
> the functions of the system timer and the local timer in an SMP system.
>
> The global timer has the following features:
>     The global timer is a 64-bit incrementing counter with an
> auto-incrementing feature. It continues incrementing after sending
> interrupts. The global timer is memory mapped in the private memory
> region.
>     The global timer is accessible to all Cortex-A9 processors in the
> cluster. Each Cortex-A9 processor has a private 64-bit comparator that
> is used to assert a private interrupt when the global timer has reached
> the comparator value. All the Cortex-A9 processors in a design use the
> banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
> Controller as a Private Peripheral Interrupt. The global timer is
> clocked by PERIPHCLK.
>
> Signed-off-by: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
> CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
> CC: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> CC: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
> CC: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>

This is starting to look very good!

(...)
> +static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
> +{
> +       struct clock_event_device **this_cpu_clk;
> +       int cpu = smp_processor_id();
> +
> +       clk->name = "ARM global timer clock event";
> +       clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
> +       clk->set_mode = gt_clockevent_set_mode;
> +       clk->set_next_event = gt_clockevent_set_next_event;
> +       this_cpu_clk = __this_cpu_ptr(gt_evt);
> +       *this_cpu_clk = clk;
> +       clk->cpumask = cpumask_of(cpu);
> +       clk->irq = gt_ppi;
> +       clockevents_config_and_register(clk, gt_clk_rate,
> +                                       0, 0xffffffff);

What do you mean with being able to set event on
0?

This should most probably be:


clockevents_config_and_register(clk, gt_clk_rate,
                                      1, 0xffffffff);

(...)
> +static struct clk *gt_get_clock(void)
> +{
> +       struct clk *clk;
> +       int err;
> +
> +       clk = clk_get_sys("gt", NULL);
> +       if (IS_ERR(clk)) {
> +               pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
> +               return clk;
> +       }
(...)
> +       clk = of_clk_get(np, 0);
> +       if (!IS_ERR(clk))
> +               clk_register_clkdev(clk, NULL, "gt");

Well that was clever.

Isn't it better to pass a struct device_node *np around and have that as
NULL in the non-DT boot path?

(Maybe somebody in the community asked you to do this, then I
will live with it.)

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-10 13:13         ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

> From: Stuart Menefy <stuart.menefy@st.com>
>
> This is a simple driver for the global timer module found in the Cortex
> A9-MP cores from revision r1p0 onwards. This should be able to perform
> the functions of the system timer and the local timer in an SMP system.
>
> The global timer has the following features:
>     The global timer is a 64-bit incrementing counter with an
> auto-incrementing feature. It continues incrementing after sending
> interrupts. The global timer is memory mapped in the private memory
> region.
>     The global timer is accessible to all Cortex-A9 processors in the
> cluster. Each Cortex-A9 processor has a private 64-bit comparator that
> is used to assert a private interrupt when the global timer has reached
> the comparator value. All the Cortex-A9 processors in a design use the
> banked ID, ID27, for this interrupt. ID27 is sent to the Interrupt
> Controller as a Private Peripheral Interrupt. The global timer is
> clocked by PERIPHCLK.
>
> Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> CC: Rob Herring <robherring2@gmail.com>
> CC: Linus Walleij <linus.walleij@linaro.org>
> CC: Will Deacon <will.deacon@arm.com>
> CC: Thomas Gleixner <tglx@linutronix.de>

This is starting to look very good!

(...)
> +static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
> +{
> +       struct clock_event_device **this_cpu_clk;
> +       int cpu = smp_processor_id();
> +
> +       clk->name = "ARM global timer clock event";
> +       clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
> +       clk->set_mode = gt_clockevent_set_mode;
> +       clk->set_next_event = gt_clockevent_set_next_event;
> +       this_cpu_clk = __this_cpu_ptr(gt_evt);
> +       *this_cpu_clk = clk;
> +       clk->cpumask = cpumask_of(cpu);
> +       clk->irq = gt_ppi;
> +       clockevents_config_and_register(clk, gt_clk_rate,
> +                                       0, 0xffffffff);

What do you mean with being able to set event on
0?

This should most probably be:


clockevents_config_and_register(clk, gt_clk_rate,
                                      1, 0xffffffff);

(...)
> +static struct clk *gt_get_clock(void)
> +{
> +       struct clk *clk;
> +       int err;
> +
> +       clk = clk_get_sys("gt", NULL);
> +       if (IS_ERR(clk)) {
> +               pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
> +               return clk;
> +       }
(...)
> +       clk = of_clk_get(np, 0);
> +       if (!IS_ERR(clk))
> +               clk_register_clkdev(clk, NULL, "gt");

Well that was clever.

Isn't it better to pass a struct device_node *np around and have that as
NULL in the non-DT boot path?

(Maybe somebody in the community asked you to do this, then I
will live with it.)

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-10 10:58         ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10 13:15           ` Mark Rutland
  -1 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 13:15 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: David S. Miller, linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	rob.herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, grant.likely, Thomas Gleixner,
	Andrew Morton, linux-arm-kernel, Mauro Carvalho Chehab

On Mon, Jun 10, 2013 at 11:58:38AM +0100, Srinivas KANDAGATLA wrote:
> Thanks for testing...
> On 10/06/13 11:40, Mark Rutland wrote:
> > On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> >> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> > This seems to drop a few options also:
> > 
> > CONFIG_ARM_ARCH_TIMER
> 
> Same as last comment 2:
> > CONFIG_ARM_ERRATA_754322
> ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
> it disappears, Should the mach level Kconfig select that?
> 

I couldn't find the patch adding mach-stixxxx's Kconfig, though I seem to be
missing patch 6 of the series. As long as CONFIG_ARM_ERRATA_754322 appears in
the resulting .config, it should be fine.

> > CONFIG_EXPERIMENTAL
> > CONFIG_GPIO_PL061
> > CONFIG_MMC_WMT
> 
> Comment 2: Without any modifications to multi_v7_defconfig if I run
> savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
> CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
> Which suggests that these options seems to be selected by another
> kconfigs or mach level. And since then the multi_v7_defconfig was not
> run with savedefconfig.

CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
CONFIG_MMC_WMT get selected elsewhere, so that's fine.

It looks like the architected timer deselection is fallout of my own making,
the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
ARM_ARCH_TIMER.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 13:15           ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 13:15 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: David S. Miller, linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	rob.herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, grant.likely, Thomas Gleixner,
	Andrew Morton, linux-arm-kernel, Mauro

On Mon, Jun 10, 2013 at 11:58:38AM +0100, Srinivas KANDAGATLA wrote:
> Thanks for testing...
> On 10/06/13 11:40, Mark Rutland wrote:
> > On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> >> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> > This seems to drop a few options also:
> > 
> > CONFIG_ARM_ARCH_TIMER
> 
> Same as last comment 2:
> > CONFIG_ARM_ERRATA_754322
> ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
> it disappears, Should the mach level Kconfig select that?
> 

I couldn't find the patch adding mach-stixxxx's Kconfig, though I seem to be
missing patch 6 of the series. As long as CONFIG_ARM_ERRATA_754322 appears in
the resulting .config, it should be fine.

> > CONFIG_EXPERIMENTAL
> > CONFIG_GPIO_PL061
> > CONFIG_MMC_WMT
> 
> Comment 2: Without any modifications to multi_v7_defconfig if I run
> savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
> CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
> Which suggests that these options seems to be selected by another
> kconfigs or mach level. And since then the multi_v7_defconfig was not
> run with savedefconfig.

CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
CONFIG_MMC_WMT get selected elsewhere, so that's fine.

It looks like the architected timer deselection is fallout of my own making,
the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
ARM_ARCH_TIMER.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-10 13:15           ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-10 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 11:58:38AM +0100, Srinivas KANDAGATLA wrote:
> Thanks for testing...
> On 10/06/13 11:40, Mark Rutland wrote:
> > On Mon, Jun 10, 2013 at 10:27:57AM +0100, Srinivas KANDAGATLA wrote:
> >> > This patch adds stih415 and stih416 support to multi_v7_defconfig.
> > This seems to drop a few options also:
> > 
> > CONFIG_ARM_ARCH_TIMER
> 
> Same as last comment 2:
> > CONFIG_ARM_ERRATA_754322
> ARM_ERRATA_754322 gets selected by the mach level Kconfig of stixxxx, so
> it disappears, Should the mach level Kconfig select that?
> 

I couldn't find the patch adding mach-stixxxx's Kconfig, though I seem to be
missing patch 6 of the series. As long as CONFIG_ARM_ERRATA_754322 appears in
the resulting .config, it should be fine.

> > CONFIG_EXPERIMENTAL
> > CONFIG_GPIO_PL061
> > CONFIG_MMC_WMT
> 
> Comment 2: Without any modifications to multi_v7_defconfig if I run
> savedefconfig CONFIG_ARM_ARCH_TIMER, CONFIG_EXPERIMENTAL,
> CONFIG_GPIO_PL061 and CONFIG_MMC_WMT disappears.
> Which suggests that these options seems to be selected by another
> kconfigs or mach level. And since then the multi_v7_defconfig was not
> run with savedefconfig.

CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
CONFIG_MMC_WMT get selected elsewhere, so that's fine.

It looks like the architected timer deselection is fallout of my own making,
the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
ARM_ARCH_TIMER.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10  9:22     ` Srinivas KANDAGATLA
@ 2013-06-10 13:16         ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 13:16 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

> This mfd driver provides higher level inialization routines for various
> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
> get to syscfg registers via standard regmap api which is usefull for
> drivers like pinctrl.
>
> This patch adds support to ST System Configuration registers, which can
> be configured by the drivers.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
> CC: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
> CC: Stephen Gallimore <stephen.gallimore-qxv4g6HH51o@public.gmane.org>
> CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> CC: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

What is this driver doing that drivers/mfd/syscon.c is not already
doing?

I just get the feeling that you're reinventing the wheel here.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 13:16         ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-10 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

> This mfd driver provides higher level inialization routines for various
> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
> get to syscfg registers via standard regmap api which is usefull for
> drivers like pinctrl.
>
> This patch adds support to ST System Configuration registers, which can
> be configured by the drivers.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> CC: Stuart Menefy <stuart.menefy@st.com>
> CC: Stephen Gallimore <stephen.gallimore@st.com>
> CC: Linus Walleij <linus.walleij@linaro.org>
> CC: Mark Brown <broonie@kernel.org>

What is this driver doing that drivers/mfd/syscon.c is not already
doing?

I just get the feeling that you're reinventing the wheel here.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
  2013-06-10 13:13         ` Linus Walleij
@ 2013-06-10 13:41             ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 13:41 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Will Deacon, Mike Turquette, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Russell King - ARM Linux,
	Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew

On 10/06/13 14:13, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

>>
>> Signed-off-by: Stuart Menefy <stuart.menefy-qxv4g6HH51o@public.gmane.org>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
>> CC: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
>> CC: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> CC: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> CC: Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>
>> CC: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> 
> This is starting to look very good!
> 
> (...)
Thankyou.
>> +static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
>> +{
>> +       struct clock_event_device **this_cpu_clk;
>> +       int cpu = smp_processor_id();
>> +
>> +       clk->name = "ARM global timer clock event";
>> +       clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
>> +       clk->set_mode = gt_clockevent_set_mode;
>> +       clk->set_next_event = gt_clockevent_set_next_event;
>> +       this_cpu_clk = __this_cpu_ptr(gt_evt);
>> +       *this_cpu_clk = clk;
>> +       clk->cpumask = cpumask_of(cpu);
>> +       clk->irq = gt_ppi;
>> +       clockevents_config_and_register(clk, gt_clk_rate,
>> +                                       0, 0xffffffff);
> 
> What do you mean with being able to set event on
> 0?
Its a bit of over do from me.. I will change it to what you suggested...

> 
> This should most probably be:
> 
> 
> clockevents_config_and_register(clk, gt_clk_rate,
>                                       1, 0xffffffff);
> 
> (...)
>> +static struct clk *gt_get_clock(void)
>> +{
>> +       struct clk *clk;
>> +       int err;
>> +
>> +       clk = clk_get_sys("gt", NULL);
>> +       if (IS_ERR(clk)) {
>> +               pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
>> +               return clk;
>> +       }
> (...)
>> +       clk = of_clk_get(np, 0);
>> +       if (!IS_ERR(clk))
>> +               clk_register_clkdev(clk, NULL, "gt");
> 
> Well that was clever.
> 
> Isn't it better to pass a struct device_node *np around and have that as
> NULL in the non-DT boot path?
I will try it and see how it will look.

Thanks,
srini
> 
> (Maybe somebody in the community asked you to do this, then I
> will live with it.)

> 
> Yours,
> Linus Walleij
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-10 13:41             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 14:13, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:

>>
>> Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> CC: Arnd Bergmann <arnd@arndb.de>
>> CC: Rob Herring <robherring2@gmail.com>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> CC: Will Deacon <will.deacon@arm.com>
>> CC: Thomas Gleixner <tglx@linutronix.de>
> 
> This is starting to look very good!
> 
> (...)
Thankyou.
>> +static int __cpuinit gt_clockevents_init(struct clock_event_device *clk)
>> +{
>> +       struct clock_event_device **this_cpu_clk;
>> +       int cpu = smp_processor_id();
>> +
>> +       clk->name = "ARM global timer clock event";
>> +       clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
>> +       clk->set_mode = gt_clockevent_set_mode;
>> +       clk->set_next_event = gt_clockevent_set_next_event;
>> +       this_cpu_clk = __this_cpu_ptr(gt_evt);
>> +       *this_cpu_clk = clk;
>> +       clk->cpumask = cpumask_of(cpu);
>> +       clk->irq = gt_ppi;
>> +       clockevents_config_and_register(clk, gt_clk_rate,
>> +                                       0, 0xffffffff);
> 
> What do you mean with being able to set event on
> 0?
Its a bit of over do from me.. I will change it to what you suggested...

> 
> This should most probably be:
> 
> 
> clockevents_config_and_register(clk, gt_clk_rate,
>                                       1, 0xffffffff);
> 
> (...)
>> +static struct clk *gt_get_clock(void)
>> +{
>> +       struct clk *clk;
>> +       int err;
>> +
>> +       clk = clk_get_sys("gt", NULL);
>> +       if (IS_ERR(clk)) {
>> +               pr_err("global-timer: clock not found: %ld\n", PTR_ERR(clk));
>> +               return clk;
>> +       }
> (...)
>> +       clk = of_clk_get(np, 0);
>> +       if (!IS_ERR(clk))
>> +               clk_register_clkdev(clk, NULL, "gt");
> 
> Well that was clever.
> 
> Isn't it better to pass a struct device_node *np around and have that as
> NULL in the non-DT boot path?
I will try it and see how it will look.

Thanks,
srini
> 
> (Maybe somebody in the community asked you to do this, then I
> will live with it.)

> 
> Yours,
> Linus Walleij
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
  2013-06-10  9:27     ` Srinivas KANDAGATLA
@ 2013-06-10 13:52       ` Arnd Bergmann
  -1 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-06-10 13:52 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Andrew Morton, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:

> +	soc {
> +		pin-controller-sbc {
> +			#address-cells	= <1>;
> +			#size-cells	= <1>;
> +			compatible	= "st,stih416-pinctrl", "simple-bus";

Why is this both its own device with a compatible string and a
"simple-bus" at the same time? Wouldn't it be simpler to just
scan the child device nodes from the "st,stih416-pinctrl"
driver instead of having a separate platform_driver for them?

> +			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
> +			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
> +			st,syscfg		= <&syscfg_sbc>;
> +			st,syscfg-offsets	= <0 40 50 60 100>;
> +			ranges;
> +			PIO0: pinctrl@fe610000 {
> +				#gpio-cells = <1>;
> +				compatible = "st,stixxxx-gpio";
> +				gpio-controller;
> +				reg = <0xfe610000 0x100>;
> +				st,bank-name  = "PIO0";
> +				st,retime-pin-mask = <0xff>;
> +			};
> +			PIO1: pinctrl@fe611000 {
> +				#gpio-cells	= <1>;
> +				compatible	= "st,stixxxx-gpio";
> +				gpio-controller;
> +				reg = <0xfe611000 0x100>;
> +				st,bank-name  = "PIO1";
> +				st,retime-pin-mask = <0xff>;
> +			};

What is in the ranges between these registers? It seems you have
256 bytes for each pinctrl node, with 4kb spacing. I wonder if
it would make sense to declare the entire range to belong to a single
pinctrl device. At least since all of the registers are in a single
range, you could add a property like

	ranges = <0 0xfe610000 0x10000>;

and use relative addresses in the sub-nodes.

Please don't use identifiers with 'xxx' in them. Instead use numbers
of actual chips, ideally using the first one that this is compatible
with.

> +		syscfg_sbc:syscfg@fe600000{
> +			compatible	= "st,stih416-syscfg";
> +			reg		= <0xfe600000 0x1000>;
> +			syscfg-range	= <0 999>;
> +			syscfg-name	= "SYSCFG_SBC";
> +		};
> +		syscfg_front:syscfg@fee10000{
> +			compatible	= "st,stih416-syscfg";
> +			reg		= <0xfee10000 0x1000>;
> +			syscfg-range	= <1000 999>;
> +			syscfg-name	= "SYSCFG_FRONT";
> +		};

Did you mean to declare ranges excluding 1000 and 2000 here?
Normally I would expect inclusive ranges like syscfg-range=<0 1000>;

What is the idea of the 'syscfg-name'? If the nodes are all different,
I would expect them to have distinct "compatible" values and not
need them.

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
@ 2013-06-10 13:52       ` Arnd Bergmann
  0 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-06-10 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:

> +	soc {
> +		pin-controller-sbc {
> +			#address-cells	= <1>;
> +			#size-cells	= <1>;
> +			compatible	= "st,stih416-pinctrl", "simple-bus";

Why is this both its own device with a compatible string and a
"simple-bus" at the same time? Wouldn't it be simpler to just
scan the child device nodes from the "st,stih416-pinctrl"
driver instead of having a separate platform_driver for them?

> +			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
> +			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
> +			st,syscfg		= <&syscfg_sbc>;
> +			st,syscfg-offsets	= <0 40 50 60 100>;
> +			ranges;
> +			PIO0: pinctrl at fe610000 {
> +				#gpio-cells = <1>;
> +				compatible = "st,stixxxx-gpio";
> +				gpio-controller;
> +				reg = <0xfe610000 0x100>;
> +				st,bank-name  = "PIO0";
> +				st,retime-pin-mask = <0xff>;
> +			};
> +			PIO1: pinctrl at fe611000 {
> +				#gpio-cells	= <1>;
> +				compatible	= "st,stixxxx-gpio";
> +				gpio-controller;
> +				reg = <0xfe611000 0x100>;
> +				st,bank-name  = "PIO1";
> +				st,retime-pin-mask = <0xff>;
> +			};

What is in the ranges between these registers? It seems you have
256 bytes for each pinctrl node, with 4kb spacing. I wonder if
it would make sense to declare the entire range to belong to a single
pinctrl device. At least since all of the registers are in a single
range, you could add a property like

	ranges = <0 0xfe610000 0x10000>;

and use relative addresses in the sub-nodes.

Please don't use identifiers with 'xxx' in them. Instead use numbers
of actual chips, ideally using the first one that this is compatible
with.

> +		syscfg_sbc:syscfg at fe600000{
> +			compatible	= "st,stih416-syscfg";
> +			reg		= <0xfe600000 0x1000>;
> +			syscfg-range	= <0 999>;
> +			syscfg-name	= "SYSCFG_SBC";
> +		};
> +		syscfg_front:syscfg at fee10000{
> +			compatible	= "st,stih416-syscfg";
> +			reg		= <0xfee10000 0x1000>;
> +			syscfg-range	= <1000 999>;
> +			syscfg-name	= "SYSCFG_FRONT";
> +		};

Did you mean to declare ranges excluding 1000 and 2000 here?
Normally I would expect inclusive ranges like syscfg-range=<0 1000>;

What is the idea of the 'syscfg-name'? If the nodes are all different,
I would expect them to have distinct "compatible" values and not
need them.

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10 13:16         ` Linus Walleij
  (?)
@ 2013-06-10 13:52           ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 13:52 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc, Russell King - ARM Linux,
	Samuel Ortiz, Stephen Gallimore, linux-serial, Grant Likely,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Andrew Morton, David S. Miller

On 10/06/13 14:16, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> This mfd driver provides higher level inialization routines for various
>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>> get to syscfg registers via standard regmap api which is usefull for
>> drivers like pinctrl.
>>
>> This patch adds support to ST System Configuration registers, which can
>> be configured by the drivers.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> CC: Stuart Menefy <stuart.menefy@st.com>
>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> CC: Mark Brown <broonie@kernel.org>
> 
> What is this driver doing that drivers/mfd/syscon.c is not already
> doing?
As of now, the driver is very much similar to syscon + some additional
functionality, but we are planning to use this file to add higher level
functions to configure different IPs like ethernet, usb, power, reset
and so on which are very much specific to ST System Configuration Registers.

Thanks,
srini
> 
> I just get the feeling that you're reinventing the wheel here.
> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 13:52           ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 13:52 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc, Russell King - ARM Linux,
	Samuel Ortiz, Stephen Gallimore, linux-serial, Grant Likely,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Andrew Morton, David S. Miller

On 10/06/13 14:16, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> This mfd driver provides higher level inialization routines for various
>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>> get to syscfg registers via standard regmap api which is usefull for
>> drivers like pinctrl.
>>
>> This patch adds support to ST System Configuration registers, which can
>> be configured by the drivers.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> CC: Stuart Menefy <stuart.menefy@st.com>
>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> CC: Mark Brown <broonie@kernel.org>
> 
> What is this driver doing that drivers/mfd/syscon.c is not already
> doing?
As of now, the driver is very much similar to syscon + some additional
functionality, but we are planning to use this file to add higher level
functions to configure different IPs like ethernet, usb, power, reset
and so on which are very much specific to ST System Configuration Registers.

Thanks,
srini
> 
> I just get the feeling that you're reinventing the wheel here.
> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 13:52           ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 14:16, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> This mfd driver provides higher level inialization routines for various
>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>> get to syscfg registers via standard regmap api which is usefull for
>> drivers like pinctrl.
>>
>> This patch adds support to ST System Configuration registers, which can
>> be configured by the drivers.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> CC: Stuart Menefy <stuart.menefy@st.com>
>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> CC: Mark Brown <broonie@kernel.org>
> 
> What is this driver doing that drivers/mfd/syscon.c is not already
> doing?
As of now, the driver is very much similar to syscon + some additional
functionality, but we are planning to use this file to add higher level
functions to configure different IPs like ethernet, usb, power, reset
and so on which are very much specific to ST System Configuration Registers.

Thanks,
srini
> 
> I just get the feeling that you're reinventing the wheel here.
> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10 13:52           ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10 14:02             ` Arnd Bergmann
  -1 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-06-10 14:02 UTC (permalink / raw)
  To: linux-arm-kernel, srinivas.kandagatla
  Cc: Linus Walleij, David S. Miller, Russell King - ARM Linux,
	Samuel Ortiz, linux-doc, Greg Kroah-Hartman, devicetree-discuss,
	Stephen Gallimore, Rob Herring, linux-kernel, Stuart Menefy,
	Mark Brown, John Stultz, linux-serial, Grant Likely,
	Thomas Gleixner, Andrew Morton, Mauro Carvalho Chehab

On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
> On 10/06/13 14:16, Linus Walleij wrote:
> > On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> > <srinivas.kandagatla@st.com> wrote:
> > 
> >> This mfd driver provides higher level inialization routines for various
> >> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
> >> get to syscfg registers via standard regmap api which is usefull for
> >> drivers like pinctrl.
> >>
> >> This patch adds support to ST System Configuration registers, which can
> >> be configured by the drivers.
> >>
> >> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> >> CC: Stuart Menefy <stuart.menefy@st.com>
> >> CC: Stephen Gallimore <stephen.gallimore@st.com>
> >> CC: Linus Walleij <linus.walleij@linaro.org>
> >> CC: Mark Brown <broonie@kernel.org>
> > 
> > What is this driver doing that drivers/mfd/syscon.c is not already
> > doing?
>
> As of now, the driver is very much similar to syscon + some additional
> functionality, but we are planning to use this file to add higher level
> functions to configure different IPs like ethernet, usb, power, reset
> and so on which are very much specific to ST System Configuration Registers.

I was expecting that you'd actually interface with the syscon code and
build on top, rather than copy it.

There are multiple ways of doing that, e.g. you could export a function
from syscon.c that you call to register the device node and then import
the regmap from syscon into your high-level driver again.

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 14:02             ` Arnd Bergmann
  0 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-06-10 14:02 UTC (permalink / raw)
  To: linux-arm-kernel, srinivas.kandagatla
  Cc: Linus Walleij, David S. Miller, Russell King - ARM Linux,
	Samuel Ortiz, linux-doc, Greg Kroah-Hartman, devicetree-discuss,
	Stephen Gallimore, Rob Herring, linux-kernel, Stuart Menefy,
	Mark Brown, John Stultz, linux-serial, Grant Likely,
	Thomas Gleixner, Andrew Morton, Mauro Carvalho Chehab

On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
> On 10/06/13 14:16, Linus Walleij wrote:
> > On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> > <srinivas.kandagatla@st.com> wrote:
> > 
> >> This mfd driver provides higher level inialization routines for various
> >> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
> >> get to syscfg registers via standard regmap api which is usefull for
> >> drivers like pinctrl.
> >>
> >> This patch adds support to ST System Configuration registers, which can
> >> be configured by the drivers.
> >>
> >> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> >> CC: Stuart Menefy <stuart.menefy@st.com>
> >> CC: Stephen Gallimore <stephen.gallimore@st.com>
> >> CC: Linus Walleij <linus.walleij@linaro.org>
> >> CC: Mark Brown <broonie@kernel.org>
> > 
> > What is this driver doing that drivers/mfd/syscon.c is not already
> > doing?
>
> As of now, the driver is very much similar to syscon + some additional
> functionality, but we are planning to use this file to add higher level
> functions to configure different IPs like ethernet, usb, power, reset
> and so on which are very much specific to ST System Configuration Registers.

I was expecting that you'd actually interface with the syscon code and
build on top, rather than copy it.

There are multiple ways of doing that, e.g. you could export a function
from syscon.c that you call to register the device node and then import
the regmap from syscon into your high-level driver again.

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 14:02             ` Arnd Bergmann
  0 siblings, 0 replies; 716+ messages in thread
From: Arnd Bergmann @ 2013-06-10 14:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
> On 10/06/13 14:16, Linus Walleij wrote:
> > On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> > <srinivas.kandagatla@st.com> wrote:
> > 
> >> This mfd driver provides higher level inialization routines for various
> >> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
> >> get to syscfg registers via standard regmap api which is usefull for
> >> drivers like pinctrl.
> >>
> >> This patch adds support to ST System Configuration registers, which can
> >> be configured by the drivers.
> >>
> >> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
> >> CC: Stuart Menefy <stuart.menefy@st.com>
> >> CC: Stephen Gallimore <stephen.gallimore@st.com>
> >> CC: Linus Walleij <linus.walleij@linaro.org>
> >> CC: Mark Brown <broonie@kernel.org>
> > 
> > What is this driver doing that drivers/mfd/syscon.c is not already
> > doing?
>
> As of now, the driver is very much similar to syscon + some additional
> functionality, but we are planning to use this file to add higher level
> functions to configure different IPs like ethernet, usb, power, reset
> and so on which are very much specific to ST System Configuration Registers.

I was expecting that you'd actually interface with the syscon code and
build on top, rather than copy it.

There are multiple ways of doing that, e.g. you could export a function
from syscon.c that you call to register the device node and then import
the regmap from syscon into your high-level driver again.

	Arnd

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10 14:02             ` Arnd Bergmann
  (?)
@ 2013-06-10 15:51               ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 15:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Linus Walleij, David S. Miller,
	Russell King - ARM Linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	Rob Herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, Grant Likely, Thomas Gleixner,
	Andrew Morton, Mauro Carvalho Chehab

Thanks for the comments.
On 10/06/13 15:02, Arnd Bergmann wrote:
> On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
>> On 10/06/13 14:16, Linus Walleij wrote:
>>> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
>>> <srinivas.kandagatla@st.com> wrote:
>>>
>>>> This mfd driver provides higher level inialization routines for various
>>>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>>>> get to syscfg registers via standard regmap api which is usefull for
>>>> drivers like pinctrl.
>>>>
>>>> This patch adds support to ST System Configuration registers, which can
>>>> be configured by the drivers.
>>>>
>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>>>> CC: Stuart Menefy <stuart.menefy@st.com>
>>>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>>>> CC: Linus Walleij <linus.walleij@linaro.org>
>>>> CC: Mark Brown <broonie@kernel.org>
>>>
>>> What is this driver doing that drivers/mfd/syscon.c is not already
>>> doing?
>>
>> As of now, the driver is very much similar to syscon + some additional
>> functionality, but we are planning to use this file to add higher level
>> functions to configure different IPs like ethernet, usb, power, reset
>> and so on which are very much specific to ST System Configuration Registers.
> 
> I was expecting that you'd actually interface with the syscon code and
> build on top, rather than copy it.
> 
I did not like the copying either, on the other hand I don't want to
pollute the syscon code.

As you said, I will make use of existing syscon and build "System
configuration interface" on top of it and see how it look like. It will
definitely get rid of lot of code duplication.

Thanks,
srini

> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.

> 
> 	Arnd
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 15:51               ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 15:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Linus Walleij, David S. Miller,
	Russell King - ARM Linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	Rob Herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, Grant Likely, Thomas Gleixner,
	Andrew Morton, Mauro Carvalho Chehab

Thanks for the comments.
On 10/06/13 15:02, Arnd Bergmann wrote:
> On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
>> On 10/06/13 14:16, Linus Walleij wrote:
>>> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
>>> <srinivas.kandagatla@st.com> wrote:
>>>
>>>> This mfd driver provides higher level inialization routines for various
>>>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>>>> get to syscfg registers via standard regmap api which is usefull for
>>>> drivers like pinctrl.
>>>>
>>>> This patch adds support to ST System Configuration registers, which can
>>>> be configured by the drivers.
>>>>
>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>>>> CC: Stuart Menefy <stuart.menefy@st.com>
>>>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>>>> CC: Linus Walleij <linus.walleij@linaro.org>
>>>> CC: Mark Brown <broonie@kernel.org>
>>>
>>> What is this driver doing that drivers/mfd/syscon.c is not already
>>> doing?
>>
>> As of now, the driver is very much similar to syscon + some additional
>> functionality, but we are planning to use this file to add higher level
>> functions to configure different IPs like ethernet, usb, power, reset
>> and so on which are very much specific to ST System Configuration Registers.
> 
> I was expecting that you'd actually interface with the syscon code and
> build on top, rather than copy it.
> 
I did not like the copying either, on the other hand I don't want to
pollute the syscon code.

As you said, I will make use of existing syscon and build "System
configuration interface" on top of it and see how it look like. It will
definitely get rid of lot of code duplication.

Thanks,
srini

> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.

> 
> 	Arnd
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-10 15:51               ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 15:51 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the comments.
On 10/06/13 15:02, Arnd Bergmann wrote:
> On Monday 10 June 2013 14:52:38 Srinivas KANDAGATLA wrote:
>> On 10/06/13 14:16, Linus Walleij wrote:
>>> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
>>> <srinivas.kandagatla@st.com> wrote:
>>>
>>>> This mfd driver provides higher level inialization routines for various
>>>> IPs like Ethernet, USB, PCIE, SATA and so on. Also it provides way to
>>>> get to syscfg registers via standard regmap api which is usefull for
>>>> drivers like pinctrl.
>>>>
>>>> This patch adds support to ST System Configuration registers, which can
>>>> be configured by the drivers.
>>>>
>>>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>>>> CC: Stuart Menefy <stuart.menefy@st.com>
>>>> CC: Stephen Gallimore <stephen.gallimore@st.com>
>>>> CC: Linus Walleij <linus.walleij@linaro.org>
>>>> CC: Mark Brown <broonie@kernel.org>
>>>
>>> What is this driver doing that drivers/mfd/syscon.c is not already
>>> doing?
>>
>> As of now, the driver is very much similar to syscon + some additional
>> functionality, but we are planning to use this file to add higher level
>> functions to configure different IPs like ethernet, usb, power, reset
>> and so on which are very much specific to ST System Configuration Registers.
> 
> I was expecting that you'd actually interface with the syscon code and
> build on top, rather than copy it.
> 
I did not like the copying either, on the other hand I don't want to
pollute the syscon code.

As you said, I will make use of existing syscon and build "System
configuration interface" on top of it and see how it look like. It will
definitely get rid of lot of code duplication.

Thanks,
srini

> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.

> 
> 	Arnd
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
  2013-06-10 13:52       ` Arnd Bergmann
@ 2013-06-10 16:17         ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 16:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mauro Carvalho Chehab, linux-doc, linux, Samuel Ortiz,
	Stephen Gallimore, linux-serial, Grant Likely,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Andrew Morton, David S. Miller

Thankyou for your comments.
On 10/06/13 14:52, Arnd Bergmann wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
> 
>> +	soc {
>> +		pin-controller-sbc {
>> +			#address-cells	= <1>;
>> +			#size-cells	= <1>;
>> +			compatible	= "st,stih416-pinctrl", "simple-bus";
> 
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?
Am happy to get rid of gpio platform_driver, But looking at the existing
pinctrl drivers like at91, they do it exactly like this.

Also having a gpio platform driver ties the resources to driver in a
neat way.

> 
>> +			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
>> +			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
>> +			st,syscfg		= <&syscfg_sbc>;
>> +			st,syscfg-offsets	= <0 40 50 60 100>;
>> +			ranges;
>> +			PIO0: pinctrl@fe610000 {
>> +				#gpio-cells = <1>;
>> +				compatible = "st,stixxxx-gpio";
>> +				gpio-controller;
>> +				reg = <0xfe610000 0x100>;
>> +				st,bank-name  = "PIO0";
>> +				st,retime-pin-mask = <0xff>;
>> +			};
>> +			PIO1: pinctrl@fe611000 {
>> +				#gpio-cells	= <1>;
>> +				compatible	= "st,stixxxx-gpio";
>> +				gpio-controller;
>> +				reg = <0xfe611000 0x100>;
>> +				st,bank-name  = "PIO1";
>> +				st,retime-pin-mask = <0xff>;
>> +			};
> 
> What is in the ranges between these registers? It seems you have
> 256 bytes for each pinctrl node, with 4kb spacing. I wonder if
> it would make sense to declare the entire range to belong to a single
> pinctrl device. At least since all of the registers are in a single
> range, you could add a property like
> 
> 	ranges = <0 0xfe610000 0x10000>;
> 
> and use relative addresses in the sub-nodes.
> 
OK, I will change to use ranges.
> Please don't use identifiers with 'xxx' in them. Instead use numbers
> of actual chips, ideally using the first one that this is compatible
> with.

Ok, I will change st,stixxxx-gpio to st,stih415-gpio.

> 
>> +		syscfg_sbc:syscfg@fe600000{
>> +			compatible	= "st,stih416-syscfg";
>> +			reg		= <0xfe600000 0x1000>;
>> +			syscfg-range	= <0 999>;
>> +			syscfg-name	= "SYSCFG_SBC";
>> +		};
>> +		syscfg_front:syscfg@fee10000{
>> +			compatible	= "st,stih416-syscfg";
>> +			reg		= <0xfee10000 0x1000>;
>> +			syscfg-range	= <1000 999>;
>> +			syscfg-name	= "SYSCFG_FRONT";
>> +		};
> 
> Did you mean to declare ranges excluding 1000 and 2000 here?
> Normally I would expect inclusive ranges like syscfg-range=<0 1000>;
> 
These numbers are from data sheet so I used it as it is.

> What is the idea of the 'syscfg-name'? If the nodes are all different,
The idea of having syscfg-name is to lookup any sysconf bank(regmap)
from code which do not have reference to phandle from device trees.

> I would expect them to have distinct "compatible" values and not
> need them.
Yes, If we have distinct compatible we would not need them, but there
will be 5-10 compatibility list for each SOC.
It looks like its going to be much neater Am going to try this change
and see how it looks like.
> 
> 	Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
@ 2013-06-10 16:17         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 16:17 UTC (permalink / raw)
  To: linux-arm-kernel

Thankyou for your comments.
On 10/06/13 14:52, Arnd Bergmann wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
> 
>> +	soc {
>> +		pin-controller-sbc {
>> +			#address-cells	= <1>;
>> +			#size-cells	= <1>;
>> +			compatible	= "st,stih416-pinctrl", "simple-bus";
> 
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?
Am happy to get rid of gpio platform_driver, But looking at the existing
pinctrl drivers like at91, they do it exactly like this.

Also having a gpio platform driver ties the resources to driver in a
neat way.

> 
>> +			st,retime-in-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
>> +			st,retime-out-delay	= <0 300 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 3250>;
>> +			st,syscfg		= <&syscfg_sbc>;
>> +			st,syscfg-offsets	= <0 40 50 60 100>;
>> +			ranges;
>> +			PIO0: pinctrl at fe610000 {
>> +				#gpio-cells = <1>;
>> +				compatible = "st,stixxxx-gpio";
>> +				gpio-controller;
>> +				reg = <0xfe610000 0x100>;
>> +				st,bank-name  = "PIO0";
>> +				st,retime-pin-mask = <0xff>;
>> +			};
>> +			PIO1: pinctrl at fe611000 {
>> +				#gpio-cells	= <1>;
>> +				compatible	= "st,stixxxx-gpio";
>> +				gpio-controller;
>> +				reg = <0xfe611000 0x100>;
>> +				st,bank-name  = "PIO1";
>> +				st,retime-pin-mask = <0xff>;
>> +			};
> 
> What is in the ranges between these registers? It seems you have
> 256 bytes for each pinctrl node, with 4kb spacing. I wonder if
> it would make sense to declare the entire range to belong to a single
> pinctrl device. At least since all of the registers are in a single
> range, you could add a property like
> 
> 	ranges = <0 0xfe610000 0x10000>;
> 
> and use relative addresses in the sub-nodes.
> 
OK, I will change to use ranges.
> Please don't use identifiers with 'xxx' in them. Instead use numbers
> of actual chips, ideally using the first one that this is compatible
> with.

Ok, I will change st,stixxxx-gpio to st,stih415-gpio.

> 
>> +		syscfg_sbc:syscfg at fe600000{
>> +			compatible	= "st,stih416-syscfg";
>> +			reg		= <0xfe600000 0x1000>;
>> +			syscfg-range	= <0 999>;
>> +			syscfg-name	= "SYSCFG_SBC";
>> +		};
>> +		syscfg_front:syscfg at fee10000{
>> +			compatible	= "st,stih416-syscfg";
>> +			reg		= <0xfee10000 0x1000>;
>> +			syscfg-range	= <1000 999>;
>> +			syscfg-name	= "SYSCFG_FRONT";
>> +		};
> 
> Did you mean to declare ranges excluding 1000 and 2000 here?
> Normally I would expect inclusive ranges like syscfg-range=<0 1000>;
> 
These numbers are from data sheet so I used it as it is.

> What is the idea of the 'syscfg-name'? If the nodes are all different,
The idea of having syscfg-name is to lookup any sysconf bank(regmap)
from code which do not have reference to phandle from device trees.

> I would expect them to have distinct "compatible" values and not
> need them.
Yes, If we have distinct compatible we would not need them, but there
will be 5-10 compatibility list for each SOC.
It looks like its going to be much neater Am going to try this change
and see how it looks like.
> 
> 	Arnd
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10 12:43         ` Linus Walleij
@ 2013-06-10 16:38             ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 16:38 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On 10/06/13 13:43, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:26 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:
> 
>> The STiH415 is the next generation of HD, AVC set-top box processors for
>> satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
>> 1.0 GHz, dual-core CPU.
> (...)
>> +       soc {
>> +               pin-controller-sbc {
>> +                       #address-cells  = <1>;
>> +                       #size-cells     = <1>;
>> +                       compatible      = "st,stih415-pinctrl", "simple-bus";
> 
> Why is the pin controller be a simple bus?
As gpio banks are children of this node, the gpio driver associated with
these banks can only be probed if the parent of the node has simple bus
compatible string.

> 
> Maybe obvious, I'm not 100% familiar with when we use this...
> 
>> +               pin-controller-front {
> (...)
>> +               pin-controller-rear {
> (...)
>> +               pin-controller-left {
> (...)
>> +               pin-controller-right {
> 
> Please explain these orientations in some comment in the device
> tree, I'm half-guessing that it's about the edges around the chip so
> the PIO* names are actually pad names.
> 
> I would suggest you use the names north/south/west/east
> if this is the case since left and right etc are relative measures.
> (This terminology is used on e.g. dance mats for console games...)
> 
> If these names are from the datasheets by all means keep them.

I will add more comments in this area, the naming comes from
data-sheets. I have no choice.
> 
>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>> @@ -0,0 +1,94 @@
>> +#ifndef _STIXXXX_PINCFG_H_
>> +#define _STIXXXX_PINCFG_H_
>> +
>> +/* Alternate functions */
>> +#define ALT1   1
>> +#define ALT2   2
>> +#define ALT3   3
>> +#define ALT4   4
>> +#define ALT5   5
>> +#define ALT6   6
>> +#define ALT7   7
> 
> Why is this part of the DT definitions? In the pinctrl world this
> is an intrinsic detail on how groups and functions are associated,
> not something that you hard-code into the device tree. The
> device tree should state how to combine functions with groups
> and those will be strings, not numerals.
If this is wrong way to do things, I would like to fix this.
Functions in ST are alt-functions which are generally from alt0-alt7.
I use this property in the pinctrl group as shown in this simple example:

pinctrl_sbc_serial1:sbc_serial1 {
       st,function = <ALT3>;
       st,pins {
              tx      = <&PIO2 6 OUT>;
              rx      = <&PIO2 7 IN>;
       };
};

To configure the group in alternate function 3.
You suggest that this should be
st,function = "alt3"; it does not look any different to what I have.

Looking at some of existing pinctrl nodes, I can see like:
                samsung,pin-function = <2>;
or
		brcm,function = <4>; /* alt0 */

Sorry ...Am I missing some thing?

Thanks,
srini
> 
> Yours,
> Linus Walleij
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 16:38             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-10 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 13:43, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:26 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> The STiH415 is the next generation of HD, AVC set-top box processors for
>> satellite, cable, terrestrial and IP-STB markets. It is an ARM Cortex-A9
>> 1.0 GHz, dual-core CPU.
> (...)
>> +       soc {
>> +               pin-controller-sbc {
>> +                       #address-cells  = <1>;
>> +                       #size-cells     = <1>;
>> +                       compatible      = "st,stih415-pinctrl", "simple-bus";
> 
> Why is the pin controller be a simple bus?
As gpio banks are children of this node, the gpio driver associated with
these banks can only be probed if the parent of the node has simple bus
compatible string.

> 
> Maybe obvious, I'm not 100% familiar with when we use this...
> 
>> +               pin-controller-front {
> (...)
>> +               pin-controller-rear {
> (...)
>> +               pin-controller-left {
> (...)
>> +               pin-controller-right {
> 
> Please explain these orientations in some comment in the device
> tree, I'm half-guessing that it's about the edges around the chip so
> the PIO* names are actually pad names.
> 
> I would suggest you use the names north/south/west/east
> if this is the case since left and right etc are relative measures.
> (This terminology is used on e.g. dance mats for console games...)
> 
> If these names are from the datasheets by all means keep them.

I will add more comments in this area, the naming comes from
data-sheets. I have no choice.
> 
>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>> @@ -0,0 +1,94 @@
>> +#ifndef _STIXXXX_PINCFG_H_
>> +#define _STIXXXX_PINCFG_H_
>> +
>> +/* Alternate functions */
>> +#define ALT1   1
>> +#define ALT2   2
>> +#define ALT3   3
>> +#define ALT4   4
>> +#define ALT5   5
>> +#define ALT6   6
>> +#define ALT7   7
> 
> Why is this part of the DT definitions? In the pinctrl world this
> is an intrinsic detail on how groups and functions are associated,
> not something that you hard-code into the device tree. The
> device tree should state how to combine functions with groups
> and those will be strings, not numerals.
If this is wrong way to do things, I would like to fix this.
Functions in ST are alt-functions which are generally from alt0-alt7.
I use this property in the pinctrl group as shown in this simple example:

pinctrl_sbc_serial1:sbc_serial1 {
       st,function = <ALT3>;
       st,pins {
              tx      = <&PIO2 6 OUT>;
              rx      = <&PIO2 7 IN>;
       };
};

To configure the group in alternate function 3.
You suggest that this should be
st,function = "alt3"; it does not look any different to what I have.

Looking at some of existing pinctrl nodes, I can see like:
                samsung,pin-function = <2>;
or
		brcm,function = <4>; /* alt0 */

Sorry ...Am I missing some thing?

Thanks,
srini
> 
> Yours,
> Linus Walleij
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10 11:46         ` Srinivas KANDAGATLA
  (?)
@ 2013-06-10 23:19           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10 23:19 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Michal Simek, linux-arm, Andrew Morton, Arnd Bergmann,
	David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, Linus Walleij, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> > 
> > 
> > 
> > #include <linux/bitops.h>
> > Linus Walleij would write use  BIT() here
> 
> I will use BIT() macro.

Without checking those fields... BIT() is only appropriate if you're
really talking about single bits.  If you have a field of more than a
single bit which you happen to be setting to '1' then it's not
appropriate to use BIT().

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 23:19           ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10 23:19 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc, Linus Walleij, Samuel Ortiz,
	Stephen Gallimore, linux-serial, Grant Likely, Arnd Bergmann,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm, Michal Simek,
	Greg Kroah-Hartman, LKML, Rob Landley, Olof Johansson,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> > 
> > 
> > 
> > #include <linux/bitops.h>
> > Linus Walleij would write use  BIT() here
> 
> I will use BIT() macro.

Without checking those fields... BIT() is only appropriate if you're
really talking about single bits.  If you have a field of more than a
single bit which you happen to be setting to '1' then it's not
appropriate to use BIT().

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-10 23:19           ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-10 23:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
> > 
> > 
> > 
> > #include <linux/bitops.h>
> > Linus Walleij would write use  BIT() here
> 
> I will use BIT() macro.

Without checking those fields... BIT() is only appropriate if you're
really talking about single bits.  If you have a field of more than a
single bit which you happen to be setting to '1' then it's not
appropriate to use BIT().

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10 23:19           ` Russell King - ARM Linux
  (?)
@ 2013-06-11  6:50             ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  6:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Michal Simek, linux-arm, Andrew Morton, Arnd Bergmann,
	David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, Linus Walleij, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On 11/06/13 00:19, Russell King - ARM Linux wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>>> > >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>>> > >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>>> > > 
>>> > > 
>>> > > 
>>> > > #include <linux/bitops.h>
>>> > > Linus Walleij would write use  BIT() here
>> > 
>> > I will use BIT() macro.
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().
> 
> 
You are right, It does not make sense to use BIT() macro for field which
has more than 1 bit. I think using mix of both BIT() and the old style
will make code look bit confusing to reader, Also no other mach code in
the kernel use BIT while configuring L2 controller. So am going to drop
the idea of using BIT here and leave the code as it is.

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-11  6:50             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  6:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Michal Simek, linux-arm, Andrew Morton, Arnd Bergmann,
	David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, Linus Walleij, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner

On 11/06/13 00:19, Russell King - ARM Linux wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>>> > >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>>> > >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>>> > > 
>>> > > 
>>> > > 
>>> > > #include <linux/bitops.h>
>>> > > Linus Walleij would write use  BIT() here
>> > 
>> > I will use BIT() macro.
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().
> 
> 
You are right, It does not make sense to use BIT() macro for field which
has more than 1 bit. I think using mix of both BIT() and the old style
will make code look bit confusing to reader, Also no other mach code in
the kernel use BIT while configuring L2 controller. So am going to drop
the idea of using BIT here and leave the code as it is.

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-11  6:50             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  6:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/06/13 00:19, Russell King - ARM Linux wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>>> > >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>>> > >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>>> > >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>>> > > 
>>> > > 
>>> > > 
>>> > > #include <linux/bitops.h>
>>> > > Linus Walleij would write use  BIT() here
>> > 
>> > I will use BIT() macro.
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().
> 
> 
You are right, It does not make sense to use BIT() macro for field which
has more than 1 bit. I think using mix of both BIT() and the old style
will make code look bit confusing to reader, Also no other mach code in
the kernel use BIT while configuring L2 controller. So am going to drop
the idea of using BIT here and leave the code as it is.

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
  2013-06-10 14:02             ` Arnd Bergmann
  (?)
@ 2013-06-11  7:41               ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  7:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Linus Walleij, David S. Miller,
	Russell King - ARM Linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	Rob Herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, Grant Likely, Thomas Gleixner,
	Andrew Morton, Mauro Carvalho Chehab

On 10/06/13 15:02, Arnd Bergmann wrote:
> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.
> 

Hi Arnd/Linus,

Thankyou for your comments,
I did try using the full sysconf names in compatible and make use of
syscon driver, with this change the nodes look much neater.

The nodes changes to:

syscfg_sbc:syscfg@fe600000{
    compatible      = "st,stih416-sbc-syscfg", "syscon";
    reg             = <0xfe600000 0x1000>;
};

From:
syscfg_sbc:syscfg@fe600000{
         compatible      = "st,stih416-syscfg";
         reg             = <0xfe600000 0x1000>;
         syscfg-range    = <0 999>;
         syscfg-name     = "SYSCFG_SBC";
};


Also I got rid of the drivers/mfd/stixxxx-syscfg.c driver all together
for this basic support patch series, I will add this once there are new
high level functions.
Additional compatible string will allow code to get to regmap via syscon
apis.

I will get rid of this driver in next version for this series.

Thanks,
srini

> 	Arnd
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-11  7:41               ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  7:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Linus Walleij, David S. Miller,
	Russell King - ARM Linux, Samuel Ortiz, linux-doc,
	Greg Kroah-Hartman, devicetree-discuss, Stephen Gallimore,
	Rob Herring, linux-kernel, Stuart Menefy, Mark Brown,
	John Stultz, linux-serial, Grant Likely, Thomas Gleixner,
	Andrew Morton, Mauro Carvalho Chehab

On 10/06/13 15:02, Arnd Bergmann wrote:
> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.
> 

Hi Arnd/Linus,

Thankyou for your comments,
I did try using the full sysconf names in compatible and make use of
syscon driver, with this change the nodes look much neater.

The nodes changes to:

syscfg_sbc:syscfg@fe600000{
    compatible      = "st,stih416-sbc-syscfg", "syscon";
    reg             = <0xfe600000 0x1000>;
};

From:
syscfg_sbc:syscfg@fe600000{
         compatible      = "st,stih416-syscfg";
         reg             = <0xfe600000 0x1000>;
         syscfg-range    = <0 999>;
         syscfg-name     = "SYSCFG_SBC";
};


Also I got rid of the drivers/mfd/stixxxx-syscfg.c driver all together
for this basic support patch series, I will add this once there are new
high level functions.
Additional compatible string will allow code to get to regmap via syscon
apis.

I will get rid of this driver in next version for this series.

Thanks,
srini

> 	Arnd
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support.
@ 2013-06-11  7:41               ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 15:02, Arnd Bergmann wrote:
> There are multiple ways of doing that, e.g. you could export a function
> from syscon.c that you call to register the device node and then import
> the regmap from syscon into your high-level driver again.
> 

Hi Arnd/Linus,

Thankyou for your comments,
I did try using the full sysconf names in compatible and make use of
syscon driver, with this change the nodes look much neater.

The nodes changes to:

syscfg_sbc:syscfg at fe600000{
    compatible      = "st,stih416-sbc-syscfg", "syscon";
    reg             = <0xfe600000 0x1000>;
};

From:
syscfg_sbc:syscfg at fe600000{
         compatible      = "st,stih416-syscfg";
         reg             = <0xfe600000 0x1000>;
         syscfg-range    = <0 999>;
         syscfg-name     = "SYSCFG_SBC";
};


Also I got rid of the drivers/mfd/stixxxx-syscfg.c driver all together
for this basic support patch series, I will add this once there are new
high level functions.
Additional compatible string will allow code to get to regmap via syscon
apis.

I will get rid of this driver in next version for this series.

Thanks,
srini

> 	Arnd
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-11 10:48       ` Mark Brown
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Brown @ 2013-06-11 10:48 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux-arm-kernel, Andrew Morton, Arnd Bergmann, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mauro Carvalho Chehab, Olof Johansson, Rob Herring,
	Rob Landley, Samuel Ortiz, Stephen Gallimore, Stuart Menefy,
	Thomas Gleixner, Tony Prisk, Alexander Shiyan,
	Lars-Peter Clausen

[-- Attachment #1: Type: text/plain, Size: 1168 bytes --]

On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
> It is common to access regmap registers at bit level, using
> regmap_update_bits or regmap_read functions, however the end user has to
> take care of a mask or shifting. This becomes overhead when such use
> cases are high. Having a common function to do this is much convenient
> and less error prone.

So this looks basically good.  A couple of smallish nits below, if you
could respin I'll apply this on a branch so it can be pulled in as
dependency for the other things that use it.

> +	regmap_field_init(rm_field, regmap, reg_field);
> +
> +	return rm_field;
> +
> +}
> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
> +/**
> + * regmap_field_alloc(): Allocate and initialise a register field

Needs a blank line between the two functions.

> +#include <linux/device.h>
> +#include <linux/slab.h>

> +static inline void regmap_field_free(struct regmap_field *field)
> +{
> +	kfree(field);
> +}

> +static inline void devm_regmap_field_free(struct device *dev,
> +	struct regmap_field *field)
> +{
> +	devm_kfree(dev, field);
> +}

Probably not worth inlining these, just put them in the code.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-11 10:48       ` Mark Brown
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Brown @ 2013-06-11 10:48 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Lars-Peter Clausen, linux-lFZ/pmaqli7XmaaqVzeoHQ, Samuel Ortiz,
	Alexander Shiyan, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller


[-- Attachment #1.1: Type: text/plain, Size: 1168 bytes --]

On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
> It is common to access regmap registers at bit level, using
> regmap_update_bits or regmap_read functions, however the end user has to
> take care of a mask or shifting. This becomes overhead when such use
> cases are high. Having a common function to do this is much convenient
> and less error prone.

So this looks basically good.  A couple of smallish nits below, if you
could respin I'll apply this on a branch so it can be pulled in as
dependency for the other things that use it.

> +	regmap_field_init(rm_field, regmap, reg_field);
> +
> +	return rm_field;
> +
> +}
> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
> +/**
> + * regmap_field_alloc(): Allocate and initialise a register field

Needs a blank line between the two functions.

> +#include <linux/device.h>
> +#include <linux/slab.h>

> +static inline void regmap_field_free(struct regmap_field *field)
> +{
> +	kfree(field);
> +}

> +static inline void devm_regmap_field_free(struct device *dev,
> +	struct regmap_field *field)
> +{
> +	devm_kfree(dev, field);
> +}

Probably not worth inlining these, just put them in the code.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-11 10:48       ` Mark Brown
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Brown @ 2013-06-11 10:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
> It is common to access regmap registers at bit level, using
> regmap_update_bits or regmap_read functions, however the end user has to
> take care of a mask or shifting. This becomes overhead when such use
> cases are high. Having a common function to do this is much convenient
> and less error prone.

So this looks basically good.  A couple of smallish nits below, if you
could respin I'll apply this on a branch so it can be pulled in as
dependency for the other things that use it.

> +	regmap_field_init(rm_field, regmap, reg_field);
> +
> +	return rm_field;
> +
> +}
> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
> +/**
> + * regmap_field_alloc(): Allocate and initialise a register field

Needs a blank line between the two functions.

> +#include <linux/device.h>
> +#include <linux/slab.h>

> +static inline void regmap_field_free(struct regmap_field *field)
> +{
> +	kfree(field);
> +}

> +static inline void devm_regmap_field_free(struct device *dev,
> +	struct regmap_field *field)
> +{
> +	devm_kfree(dev, field);
> +}

Probably not worth inlining these, just put them in the code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130611/ebc65022/attachment.sig>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 03/11] regmap: Add regmap_field APIs
  2013-06-11 10:48       ` Mark Brown
  (?)
@ 2013-06-11 11:36         ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11 11:36 UTC (permalink / raw)
  To: Mark Brown
  Cc: Mauro Carvalho Chehab, linux-doc, Lars-Peter Clausen, linux,
	Samuel Ortiz, Alexander Shiyan, Stephen Gallimore, linux-serial,
	Grant Likely, devicetree-discuss, Rob Herring, Stuart Menefy,
	John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Andrew Morton, David S. Miller

On 11/06/13 11:48, Mark Brown wrote:
> On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
>> It is common to access regmap registers at bit level, using
>> regmap_update_bits or regmap_read functions, however the end user has to
>> take care of a mask or shifting. This becomes overhead when such use
>> cases are high. Having a common function to do this is much convenient
>> and less error prone.
> 
> So this looks basically good.  A couple of smallish nits below, if you
> could respin I'll apply this on a branch so it can be pulled in as
> dependency for the other things that use it.
> 
Thankyou for the comments,
I will fix it and send a v3 patch.

>> +	regmap_field_init(rm_field, regmap, reg_field);
>> +
>> +	return rm_field;
>> +
>> +}
>> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
>> +/**
>> + * regmap_field_alloc(): Allocate and initialise a register field
> 
> Needs a blank line between the two functions.
> 
>> +#include <linux/device.h>
>> +#include <linux/slab.h>
> 
>> +static inline void regmap_field_free(struct regmap_field *field)
>> +{
>> +	kfree(field);
>> +}
> 
>> +static inline void devm_regmap_field_free(struct device *dev,
>> +	struct regmap_field *field)
>> +{
>> +	devm_kfree(dev, field);
>> +}
> 
> Probably not worth inlining these, just put them in the code.
> 
> 
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-11 11:36         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11 11:36 UTC (permalink / raw)
  To: Mark Brown
  Cc: Lars-Peter Clausen, linux, Samuel Ortiz, Alexander Shiyan,
	linux-doc, Greg Kroah-Hartman, devicetree-discuss,
	Stephen Gallimore, Rob Herring, linux-kernel, Stuart Menefy,
	David S. Miller, John Stultz, linux-serial, Grant Likely,
	Thomas Gleixner, Andrew Morton, linux-arm-kernel,
	Mauro Carvalho Chehab

On 11/06/13 11:48, Mark Brown wrote:
> On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
>> It is common to access regmap registers at bit level, using
>> regmap_update_bits or regmap_read functions, however the end user has to
>> take care of a mask or shifting. This becomes overhead when such use
>> cases are high. Having a common function to do this is much convenient
>> and less error prone.
> 
> So this looks basically good.  A couple of smallish nits below, if you
> could respin I'll apply this on a branch so it can be pulled in as
> dependency for the other things that use it.
> 
Thankyou for the comments,
I will fix it and send a v3 patch.

>> +	regmap_field_init(rm_field, regmap, reg_field);
>> +
>> +	return rm_field;
>> +
>> +}
>> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
>> +/**
>> + * regmap_field_alloc(): Allocate and initialise a register field
> 
> Needs a blank line between the two functions.
> 
>> +#include <linux/device.h>
>> +#include <linux/slab.h>
> 
>> +static inline void regmap_field_free(struct regmap_field *field)
>> +{
>> +	kfree(field);
>> +}
> 
>> +static inline void devm_regmap_field_free(struct device *dev,
>> +	struct regmap_field *field)
>> +{
>> +	devm_kfree(dev, field);
>> +}
> 
> Probably not worth inlining these, just put them in the code.
> 
> 
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 03/11] regmap: Add regmap_field APIs
@ 2013-06-11 11:36         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11 11:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/06/13 11:48, Mark Brown wrote:
> On Mon, Jun 10, 2013 at 10:21:58AM +0100, Srinivas KANDAGATLA wrote:
>> It is common to access regmap registers at bit level, using
>> regmap_update_bits or regmap_read functions, however the end user has to
>> take care of a mask or shifting. This becomes overhead when such use
>> cases are high. Having a common function to do this is much convenient
>> and less error prone.
> 
> So this looks basically good.  A couple of smallish nits below, if you
> could respin I'll apply this on a branch so it can be pulled in as
> dependency for the other things that use it.
> 
Thankyou for the comments,
I will fix it and send a v3 patch.

>> +	regmap_field_init(rm_field, regmap, reg_field);
>> +
>> +	return rm_field;
>> +
>> +}
>> +EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
>> +/**
>> + * regmap_field_alloc(): Allocate and initialise a register field
> 
> Needs a blank line between the two functions.
> 
>> +#include <linux/device.h>
>> +#include <linux/slab.h>
> 
>> +static inline void regmap_field_free(struct regmap_field *field)
>> +{
>> +	kfree(field);
>> +}
> 
>> +static inline void devm_regmap_field_free(struct device *dev,
>> +	struct regmap_field *field)
>> +{
>> +	devm_kfree(dev, field);
>> +}
> 
> Probably not worth inlining these, just put them in the code.
> 
> 
> 
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
  2013-06-10 13:41             ` Srinivas KANDAGATLA
@ 2013-06-11 14:05               ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11 14:05 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, srinivas.kandagatla, Will Deacon,
	Mike Turquette, Samuel Ortiz, linux-doc, Stephen Gallimore,
	linux-serial, Grant Likely, Arnd Bergmann, devicetree-discuss,
	Rob Herring, Stuart Menefy, Mark Brown, John Stultz,
	Russell King - ARM Linux, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel

On 10/06/13 14:41, Srinivas Kandagatla wrote:
> On 10/06/13 14:13, Linus Walleij wrote:
>> On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
>> Isn't it better to pass a struct device_node *np around and have that as
>> NULL in the non-DT boot path?
> I will try it and see how it will look.

I did try the change you suggested regarding passing struct device_node
*np around for both DT and non-DT boot paths.

Doing this is not adding any value to the driver, because
 1. Currently the driver only support DT boot paths, in my previous RFC
patches, Arnd suggested to get rid of the header as all platforms are DT
now.
 2. Passing device_node around is not adding any value w.r.t reducing
code or any thing.

So, I think I will stay with what is there originally, unless you have a
strong reason.

Thanks,
srini

> 
> Thanks,
> srini
>>
>> (Maybe somebody in the community asked you to do this, then I
>> will live with it.)
> 
>>
>> Yours,
>> Linus Walleij
>>
>>
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-11 14:05               ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-11 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 14:41, Srinivas Kandagatla wrote:
> On 10/06/13 14:13, Linus Walleij wrote:
>> On Mon, Jun 10, 2013 at 11:21 AM, Srinivas KANDAGATLA
>> Isn't it better to pass a struct device_node *np around and have that as
>> NULL in the non-DT boot path?
> I will try it and see how it will look.

I did try the change you suggested regarding passing struct device_node
*np around for both DT and non-DT boot paths.

Doing this is not adding any value to the driver, because
 1. Currently the driver only support DT boot paths, in my previous RFC
patches, Arnd suggested to get rid of the header as all platforms are DT
now.
 2. Passing device_node around is not adding any value w.r.t reducing
code or any thing.

So, I think I will stay with what is there originally, unless you have a
strong reason.

Thanks,
srini

> 
> Thanks,
> srini
>>
>> (Maybe somebody in the community asked you to do this, then I
>> will live with it.)
> 
>>
>> Yours,
>> Linus Walleij
>>
>>
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
  2013-06-11 14:05               ` Srinivas KANDAGATLA
@ 2013-06-11 20:13                   ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-11 20:13 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Will Deacon, Mike Turquette, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Russell King - ARM Linux,
	Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew

On Tue, Jun 11, 2013 at 4:05 PM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

> Doing this is not adding any value to the driver, because
>  1. Currently the driver only support DT boot paths, in my previous RFC
> patches, Arnd suggested to get rid of the header as all platforms are DT
> now.

In that case why do you have the separate global_timer_init()
at all? Just move that code into global_timer_of_register() and
also remove the #ifdef around CONFIG_OF and make the driver
depend on CONFIG_OF in Kconfig.

After this you realize that all that business with
clk_register_clkdev() / clk_get_sys() is just pure surplus
baggade, you just use of_clk_get() and that's it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-11 20:13                   ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-11 20:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 11, 2013 at 4:05 PM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

> Doing this is not adding any value to the driver, because
>  1. Currently the driver only support DT boot paths, in my previous RFC
> patches, Arnd suggested to get rid of the header as all platforms are DT
> now.

In that case why do you have the separate global_timer_init()
at all? Just move that code into global_timer_of_register() and
also remove the #ifdef around CONFIG_OF and make the driver
depend on CONFIG_OF in Kconfig.

After this you realize that all that business with
clk_register_clkdev() / clk_get_sys() is just pure surplus
baggade, you just use of_clk_get() and that's it.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
  2013-06-11 20:13                   ` Linus Walleij
  (?)
@ 2013-06-12 10:45                     ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-12 10:45 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc, Will Deacon, Mike Turquette,
	Samuel Ortiz, Stephen Gallimore, linux-serial, Grant Likely,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Russell King - ARM Linux, Thomas Gleixner,
	linux-arm-kernel, Greg Kroah-Hartman, linux-kernel,
	Andrew Morton, David S. Miller

On 11/06/13 21:13, Linus Walleij wrote:
> On Tue, Jun 11, 2013 at 4:05 PM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> Doing this is not adding any value to the driver, because
>>  1. Currently the driver only support DT boot paths, in my previous RFC
>> patches, Arnd suggested to get rid of the header as all platforms are DT
>> now.
> 
> In that case why do you have the separate global_timer_init()
> at all? Just move that code into global_timer_of_register() and
> also remove the #ifdef around CONFIG_OF and make the driver
> depend on CONFIG_OF in Kconfig.
> 
> After this you realize that all that business with
> clk_register_clkdev() / clk_get_sys() is just pure surplus
> baggade, you just use of_clk_get() and that's it.

It makes sense to move all the code into global_timer_of_register().
This will also get rid of un-used code. I will do this in the next spin.

Thanks,
srini

> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-12 10:45                     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-12 10:45 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc, Will Deacon, Mike Turquette,
	Samuel Ortiz, Stephen Gallimore, linux-serial, Grant Likely,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Russell King - ARM Linux, Thomas Gleixner,
	linux-arm-kernel, Greg Kroah-Hartman, linux-kernel, Andrew

On 11/06/13 21:13, Linus Walleij wrote:
> On Tue, Jun 11, 2013 at 4:05 PM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> Doing this is not adding any value to the driver, because
>>  1. Currently the driver only support DT boot paths, in my previous RFC
>> patches, Arnd suggested to get rid of the header as all platforms are DT
>> now.
> 
> In that case why do you have the separate global_timer_init()
> at all? Just move that code into global_timer_of_register() and
> also remove the #ifdef around CONFIG_OF and make the driver
> depend on CONFIG_OF in Kconfig.
> 
> After this you realize that all that business with
> clk_register_clkdev() / clk_get_sys() is just pure surplus
> baggade, you just use of_clk_get() and that's it.

It makes sense to move all the code into global_timer_of_register().
This will also get rid of un-used code. I will do this in the next spin.

Thanks,
srini

> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support.
@ 2013-06-12 10:45                     ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-12 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 11/06/13 21:13, Linus Walleij wrote:
> On Tue, Jun 11, 2013 at 4:05 PM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> Doing this is not adding any value to the driver, because
>>  1. Currently the driver only support DT boot paths, in my previous RFC
>> patches, Arnd suggested to get rid of the header as all platforms are DT
>> now.
> 
> In that case why do you have the separate global_timer_init()
> at all? Just move that code into global_timer_of_register() and
> also remove the #ifdef around CONFIG_OF and make the driver
> depend on CONFIG_OF in Kconfig.
> 
> After this you realize that all that business with
> clk_register_clkdev() / clk_get_sys() is just pure surplus
> baggade, you just use of_clk_get() and that's it.

It makes sense to move all the code into global_timer_of_register().
This will also get rid of un-used code. I will do this in the next spin.

Thanks,
srini

> 
> Yours,
> Linus Walleij
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
  2013-02-07 17:34     ` manjunath.goudar at linaro.org
@ 2013-06-12 11:53       ` Jean-Christophe PLAGNIOL-VILLARD
  -1 siblings, 0 replies; 716+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-12 11:53 UTC (permalink / raw)
  To: manjunath.goudar
  Cc: linux-usb, linux-arm-kernel, patches, stern, arnd, gregkh,
	Greg KH, Grant Likely, Rob Herring, Andrew Victor, Nicolas Ferre,
	linux-kernel

On 23:04 Thu 07 Feb     , manjunath.goudar@linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> Separate the Atmel host controller driver from ehci-hcd host code
> into its own driver module.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Greg KH <greg@kroah.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Andrew Victor <linux@maxim.org.za>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: linux-usb@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

Best Regards,
J.
> ---
>  drivers/usb/host/Kconfig      |    7 ++++
>  drivers/usb/host/Makefile     |    1 +
>  drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
>  drivers/usb/host/ehci-hcd.c   |    6 +---
>  4 files changed, 51 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 3689b7b..5a13f9d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
>          ---help---
>            Enables support for the on-chip EHCI controller on
>            Morvell Orion chips.
> +config USB_EHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip EHCI USB controller"
> +        depends on USB_EHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip EHCI controller on
> +          Atmel chips.
>  
>  config USB_EHCI_MSM
>  	bool "Support for MSM on-chip EHCI USB controller"
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 23b07dd..96b4839 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
>  obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
>  obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
>  obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
> +obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
>  obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
>  obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
>  obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
> diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
> index 27639487..2f06711 100644
> --- a/drivers/usb/host/ehci-atmel.c
> +++ b/drivers/usb/host/ehci-atmel.c
> @@ -15,6 +15,19 @@
>  #include <linux/platform_device.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +#include <linux/io.h>
> +#include <linux/dma-mapping.h>
> +
> +#include "ehci.h"
> +
> +#define DRIVER_DESC "EHCI atmel driver"
> +
> +static const char hcd_name[] = "ehci-atmel";
> +static struct hc_driver __read_mostly ehci_atmel_hc_driver;
>  
>  /* interface and function clocks */
>  static struct clk *iclk, *fclk;
> @@ -60,41 +73,6 @@ static int ehci_atmel_setup(struct usb_hcd *hcd)
>  	return ehci_setup(hcd);
>  }
>  
> -static const struct hc_driver ehci_atmel_hc_driver = {
> -	.description		= hcd_name,
> -	.product_desc		= "Atmel EHCI UHP HS",
> -	.hcd_priv_size		= sizeof(struct ehci_hcd),
> -
> -	/* generic hardware linkage */
> -	.irq			= ehci_irq,
> -	.flags			= HCD_MEMORY | HCD_USB2,
> -
> -	/* basic lifecycle operations */
> -	.reset			= ehci_atmel_setup,
> -	.start			= ehci_run,
> -	.stop			= ehci_stop,
> -	.shutdown		= ehci_shutdown,
> -
> -	/* managing i/o requests and associated device resources */
> -	.urb_enqueue		= ehci_urb_enqueue,
> -	.urb_dequeue		= ehci_urb_dequeue,
> -	.endpoint_disable	= ehci_endpoint_disable,
> -	.endpoint_reset		= ehci_endpoint_reset,
> -
> -	/* scheduling support */
> -	.get_frame_number	= ehci_get_frame,
> -
> -	/* root hub support */
> -	.hub_status_data	= ehci_hub_status_data,
> -	.hub_control		= ehci_hub_control,
> -	.bus_suspend		= ehci_bus_suspend,
> -	.bus_resume		= ehci_bus_resume,
> -	.relinquish_port	= ehci_relinquish_port,
> -	.port_handed_over	= ehci_port_handed_over,
> -
> -	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
> -};
> -
>  static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
>  
>  static int ehci_atmel_drv_probe(struct platform_device *pdev)
> @@ -210,7 +188,35 @@ static struct platform_driver ehci_atmel_driver = {
>  	.remove		= ehci_atmel_drv_remove,
>  	.shutdown	= usb_hcd_platform_shutdown,
>  	.driver		= {
> -		.name	= "atmel-ehci",
> +		.name	= hcd_name,
>  		.of_match_table	= of_match_ptr(atmel_ehci_dt_ids),
>  	},
>  };
> +
> +static const struct ehci_driver_overrides atmel_overrides __initdata = {
> +	.reset = ehci_atmel_setup,
> +};
> +
> +static int __init ehci_atmel_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ehci_init_driver(&ehci_atmel_hc_driver, &atmel_overrides);
> +	return platform_driver_register(&ehci_atmel_driver);
> +}
> +module_init(ehci_atmel_init);
> +
> +static void __exit ehci_atmel_cleanup(void)
> +{
> +	platform_driver_unregister(&ehci_atmel_driver);
> +}
> +module_exit(ehci_atmel_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> +MODULE_ALIAS("platform:ehci-atmel");
> +MODULE_AUTHOR("Nicolas Ferre");
> +MODULE_LICENSE("GPL");
> +
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 5a19a57..628ed139 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -1272,11 +1272,6 @@ MODULE_LICENSE ("GPL");
>  #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
>  #endif
>  
> -#ifdef CONFIG_ARCH_AT91
> -#include "ehci-atmel.c"
> -#define	PLATFORM_DRIVER		ehci_atmel_driver
> -#endif
> -
>  #ifdef CONFIG_USB_OCTEON_EHCI
>  #include "ehci-octeon.c"
>  #define PLATFORM_DRIVER		ehci_octeon_driver
> @@ -1334,6 +1329,7 @@ MODULE_LICENSE ("GPL");
>  	!defined(PLATFORM_DRIVER) && \
>  	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
>  	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
> +	!IS_ENABLED(CONFIG_ARCH_AT91) && \
>  	!defined(PS3_SYSTEM_BUS_DRIVER) && \
>  	!defined(OF_PLATFORM_DRIVER) && \
>  	!defined(XILINX_OF_PLATFORM_DRIVER)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 05/10] USB: EHCI: make ehci-atmel a separate driver
@ 2013-06-12 11:53       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 716+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-06-12 11:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 23:04 Thu 07 Feb     , manjunath.goudar at linaro.org wrote:
> From: Manjunath Goudar <manjunath.goudar@linaro.org>
> 
> Separate the Atmel host controller driver from ehci-hcd host code
> into its own driver module.
> 
> Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Cc: Greg KH <greg@kroah.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Andrew Victor <linux@maxim.org.za>
> Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: linux-usb at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>

Best Regards,
J.
> ---
>  drivers/usb/host/Kconfig      |    7 ++++
>  drivers/usb/host/Makefile     |    1 +
>  drivers/usb/host/ehci-atmel.c |   78 ++++++++++++++++++++++-------------------
>  drivers/usb/host/ehci-hcd.c   |    6 +---
>  4 files changed, 51 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 3689b7b..5a13f9d 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -176,6 +176,13 @@ config USB_EHCI_HCD_ORION
>          ---help---
>            Enables support for the on-chip EHCI controller on
>            Morvell Orion chips.
> +config USB_EHCI_HCD_AT91
> +        tristate  "Support for Atmel on-chip EHCI USB controller"
> +        depends on USB_EHCI_HCD && ARCH_AT91
> +        default y
> +        ---help---
> +          Enables support for the on-chip EHCI controller on
> +          Atmel chips.
>  
>  config USB_EHCI_MSM
>  	bool "Support for MSM on-chip EHCI USB controller"
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 23b07dd..96b4839 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -31,6 +31,7 @@ obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
>  obj-$(CONFIG_USB_EHCI_HCD_SPEAR)+= ehci-spear.o
>  obj-$(CONFIG_USB_EHCI_HCD_ORION)+= ehci-orion.o
>  obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o
> +obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
>  obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
>  obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o
>  obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
> diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
> index 27639487..2f06711 100644
> --- a/drivers/usb/host/ehci-atmel.c
> +++ b/drivers/usb/host/ehci-atmel.c
> @@ -15,6 +15,19 @@
>  #include <linux/platform_device.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/usb.h>
> +#include <linux/usb/hcd.h>
> +#include <linux/io.h>
> +#include <linux/dma-mapping.h>
> +
> +#include "ehci.h"
> +
> +#define DRIVER_DESC "EHCI atmel driver"
> +
> +static const char hcd_name[] = "ehci-atmel";
> +static struct hc_driver __read_mostly ehci_atmel_hc_driver;
>  
>  /* interface and function clocks */
>  static struct clk *iclk, *fclk;
> @@ -60,41 +73,6 @@ static int ehci_atmel_setup(struct usb_hcd *hcd)
>  	return ehci_setup(hcd);
>  }
>  
> -static const struct hc_driver ehci_atmel_hc_driver = {
> -	.description		= hcd_name,
> -	.product_desc		= "Atmel EHCI UHP HS",
> -	.hcd_priv_size		= sizeof(struct ehci_hcd),
> -
> -	/* generic hardware linkage */
> -	.irq			= ehci_irq,
> -	.flags			= HCD_MEMORY | HCD_USB2,
> -
> -	/* basic lifecycle operations */
> -	.reset			= ehci_atmel_setup,
> -	.start			= ehci_run,
> -	.stop			= ehci_stop,
> -	.shutdown		= ehci_shutdown,
> -
> -	/* managing i/o requests and associated device resources */
> -	.urb_enqueue		= ehci_urb_enqueue,
> -	.urb_dequeue		= ehci_urb_dequeue,
> -	.endpoint_disable	= ehci_endpoint_disable,
> -	.endpoint_reset		= ehci_endpoint_reset,
> -
> -	/* scheduling support */
> -	.get_frame_number	= ehci_get_frame,
> -
> -	/* root hub support */
> -	.hub_status_data	= ehci_hub_status_data,
> -	.hub_control		= ehci_hub_control,
> -	.bus_suspend		= ehci_bus_suspend,
> -	.bus_resume		= ehci_bus_resume,
> -	.relinquish_port	= ehci_relinquish_port,
> -	.port_handed_over	= ehci_port_handed_over,
> -
> -	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
> -};
> -
>  static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32);
>  
>  static int ehci_atmel_drv_probe(struct platform_device *pdev)
> @@ -210,7 +188,35 @@ static struct platform_driver ehci_atmel_driver = {
>  	.remove		= ehci_atmel_drv_remove,
>  	.shutdown	= usb_hcd_platform_shutdown,
>  	.driver		= {
> -		.name	= "atmel-ehci",
> +		.name	= hcd_name,
>  		.of_match_table	= of_match_ptr(atmel_ehci_dt_ids),
>  	},
>  };
> +
> +static const struct ehci_driver_overrides atmel_overrides __initdata = {
> +	.reset = ehci_atmel_setup,
> +};
> +
> +static int __init ehci_atmel_init(void)
> +{
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
> +	ehci_init_driver(&ehci_atmel_hc_driver, &atmel_overrides);
> +	return platform_driver_register(&ehci_atmel_driver);
> +}
> +module_init(ehci_atmel_init);
> +
> +static void __exit ehci_atmel_cleanup(void)
> +{
> +	platform_driver_unregister(&ehci_atmel_driver);
> +}
> +module_exit(ehci_atmel_cleanup);
> +
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +
> +MODULE_ALIAS("platform:ehci-atmel");
> +MODULE_AUTHOR("Nicolas Ferre");
> +MODULE_LICENSE("GPL");
> +
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 5a19a57..628ed139 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -1272,11 +1272,6 @@ MODULE_LICENSE ("GPL");
>  #define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver
>  #endif
>  
> -#ifdef CONFIG_ARCH_AT91
> -#include "ehci-atmel.c"
> -#define	PLATFORM_DRIVER		ehci_atmel_driver
> -#endif
> -
>  #ifdef CONFIG_USB_OCTEON_EHCI
>  #include "ehci-octeon.c"
>  #define PLATFORM_DRIVER		ehci_octeon_driver
> @@ -1334,6 +1329,7 @@ MODULE_LICENSE ("GPL");
>  	!defined(PLATFORM_DRIVER) && \
>  	!IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
>  	!IS_ENABLED(CONFIG_PLAT_SPEAR) && \
> +	!IS_ENABLED(CONFIG_ARCH_AT91) && \
>  	!defined(PS3_SYSTEM_BUS_DRIVER) && \
>  	!defined(OF_PLATFORM_DRIVER) && \
>  	!defined(XILINX_OF_PLATFORM_DRIVER)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-10 13:15           ` Mark Rutland
  (?)
@ 2013-06-13  9:24             ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13  9:24 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux, Samuel Ortiz, linux-doc, Greg Kroah-Hartman,
	devicetree-discuss, Stephen Gallimore, rob.herring, linux-kernel,
	Andrew Morton, Stuart Menefy, Mark Brown, John Stultz,
	linux-serial, grant.likely, Thomas Gleixner, David S. Miller,
	linux-arm-kernel, Mauro Carvalho Chehab

On 10/06/13 14:15, Mark Rutland wrote:
> CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> 

Am planning to send a patch to clean this up, so that any new platform
addition to the multi_v7_defconfig will not under go this discussion again..

> It looks like the architected timer deselection is fallout of my own making,
> the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> ARM_ARCH_TIMER.
Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
The only reason I see for de-selection is because none of the platforms
in the multi_v7 defconfig selects it.

Looks like there is no platform in mulit_v7 config which requires this
support. If there is one I think it should select it.

Am I correct?

Thanks,
srini


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-13  9:24             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13  9:24 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux, Samuel Ortiz, linux-doc, Greg Kroah-Hartman,
	devicetree-discuss, Stephen Gallimore, rob.herring, linux-kernel,
	Andrew Morton, Stuart Menefy, Mark Brown, John Stultz,
	linux-serial, grant.likely, Thomas Gleixner, David S. Miller,
	linux-arm-kernel, Mauro

On 10/06/13 14:15, Mark Rutland wrote:
> CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> 

Am planning to send a patch to clean this up, so that any new platform
addition to the multi_v7_defconfig will not under go this discussion again..

> It looks like the architected timer deselection is fallout of my own making,
> the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> ARM_ARCH_TIMER.
Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
The only reason I see for de-selection is because none of the platforms
in the multi_v7 defconfig selects it.

Looks like there is no platform in mulit_v7 config which requires this
support. If there is one I think it should select it.

Am I correct?

Thanks,
srini


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-13  9:24             ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 14:15, Mark Rutland wrote:
> CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> 

Am planning to send a patch to clean this up, so that any new platform
addition to the multi_v7_defconfig will not under go this discussion again..

> It looks like the architected timer deselection is fallout of my own making,
> the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> ARM_ARCH_TIMER.
Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
The only reason I see for de-selection is because none of the platforms
in the multi_v7 defconfig selects it.

Looks like there is no platform in mulit_v7 config which requires this
support. If there is one I think it should select it.

Am I correct?

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-11  6:50             ` Srinivas KANDAGATLA
  (?)
@ 2013-06-13 11:56               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-13 11:56 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Michal Simek, linux-arm, Andrew Morton, Arnd Bergmann,
	David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, Linus Walleij, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
> You are right, It does not make sense to use BIT() macro for field which
> has more than 1 bit. I think using mix of both BIT() and the old style
> will make code look bit confusing to reader, Also no other mach code in
> the kernel use BIT while configuring L2 controller. So am going to drop
> the idea of using BIT here and leave the code as it is.

I'd suggest putting a comment in the code to that effect.  With the way
"cleanups" get done, I wouldn't be surprised if this attracts a lot of
people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.

One of the problems of open source is that you can say "no" to a patch
like that until you're blue in the face, but it will eventually make
its way in via some path.

Just one of the reasons I consider BIT() to be evil and an inappropriate
macro.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 11:56               ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-13 11:56 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc, Linus Walleij, Samuel Ortiz,
	Stephen Gallimore, linux-serial, Grant Likely, Arnd Bergmann,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm, Michal Simek,
	Greg Kroah-Hartman, LKML, Rob Landley, Olof Johansson,
	Andrew Morton, David S. Miller

On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
> You are right, It does not make sense to use BIT() macro for field which
> has more than 1 bit. I think using mix of both BIT() and the old style
> will make code look bit confusing to reader, Also no other mach code in
> the kernel use BIT while configuring L2 controller. So am going to drop
> the idea of using BIT here and leave the code as it is.

I'd suggest putting a comment in the code to that effect.  With the way
"cleanups" get done, I wouldn't be surprised if this attracts a lot of
people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.

One of the problems of open source is that you can say "no" to a patch
like that until you're blue in the face, but it will eventually make
its way in via some path.

Just one of the reasons I consider BIT() to be evil and an inappropriate
macro.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 11:56               ` Russell King - ARM Linux
  0 siblings, 0 replies; 716+ messages in thread
From: Russell King - ARM Linux @ 2013-06-13 11:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
> You are right, It does not make sense to use BIT() macro for field which
> has more than 1 bit. I think using mix of both BIT() and the old style
> will make code look bit confusing to reader, Also no other mach code in
> the kernel use BIT while configuring L2 controller. So am going to drop
> the idea of using BIT here and leave the code as it is.

I'd suggest putting a comment in the code to that effect.  With the way
"cleanups" get done, I wouldn't be surprised if this attracts a lot of
people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.

One of the problems of open source is that you can say "no" to a patch
like that until you're blue in the face, but it will eventually make
its way in via some path.

Just one of the reasons I consider BIT() to be evil and an inappropriate
macro.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-13 11:56               ` Russell King - ARM Linux
  (?)
@ 2013-06-13 12:41                 ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13 12:41 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Michal Simek, linux-arm, Andrew Morton, Arnd Bergmann,
	David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, Linus Walleij, linux-doc, LKML,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On 13/06/13 12:56, Russell King - ARM Linux wrote:
> On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
>> You are right, It does not make sense to use BIT() macro for field which
>> has more than 1 bit. I think using mix of both BIT() and the old style
>> will make code look bit confusing to reader, Also no other mach code in
>> the kernel use BIT while configuring L2 controller. So am going to drop
>> the idea of using BIT here and leave the code as it is.
> 
> I'd suggest putting a comment in the code to that effect.  With the way
> "cleanups" get done, I wouldn't be surprised if this attracts a lot of
> people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.
Hmm... I can add a comment for them.

> 
> One of the problems of open source is that you can say "no" to a patch
> like that until you're blue in the face, but it will eventually make
> its way in via some path.
> 
> Just one of the reasons I consider BIT() to be evil and an inappropriate
> macro.
> 
> 


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 12:41                 ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13 12:41 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Mauro Carvalho Chehab, linux-doc, Linus Walleij, Samuel Ortiz,
	Stephen Gallimore, linux-serial, Grant Likely, Arnd Bergmann,
	devicetree-discuss, Rob Herring, Stuart Menefy, Mark Brown,
	John Stultz, Thomas Gleixner, linux-arm, Michal Simek,
	Greg Kroah-Hartman, LKML, Rob Landley, Olof Johansson,
	Andrew Morton, David S. Miller

On 13/06/13 12:56, Russell King - ARM Linux wrote:
> On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
>> You are right, It does not make sense to use BIT() macro for field which
>> has more than 1 bit. I think using mix of both BIT() and the old style
>> will make code look bit confusing to reader, Also no other mach code in
>> the kernel use BIT while configuring L2 controller. So am going to drop
>> the idea of using BIT here and leave the code as it is.
> 
> I'd suggest putting a comment in the code to that effect.  With the way
> "cleanups" get done, I wouldn't be surprised if this attracts a lot of
> people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.
Hmm... I can add a comment for them.

> 
> One of the problems of open source is that you can say "no" to a patch
> like that until you're blue in the face, but it will eventually make
> its way in via some path.
> 
> Just one of the reasons I consider BIT() to be evil and an inappropriate
> macro.
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 12:41                 ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-13 12:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/06/13 12:56, Russell King - ARM Linux wrote:
> On Tue, Jun 11, 2013 at 07:50:31AM +0100, Srinivas KANDAGATLA wrote:
>> You are right, It does not make sense to use BIT() macro for field which
>> has more than 1 bit. I think using mix of both BIT() and the old style
>> will make code look bit confusing to reader, Also no other mach code in
>> the kernel use BIT while configuring L2 controller. So am going to drop
>> the idea of using BIT here and leave the code as it is.
> 
> I'd suggest putting a comment in the code to that effect.  With the way
> "cleanups" get done, I wouldn't be surprised if this attracts a lot of
> people wanting to do a trivial "1 << bit" -> "BIT(bit)" conversions.
Hmm... I can add a comment for them.

> 
> One of the problems of open source is that you can say "no" to a patch
> like that until you're blue in the face, but it will eventually make
> its way in via some path.
> 
> Just one of the reasons I consider BIT() to be evil and an inappropriate
> macro.
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10 23:19           ` Russell King - ARM Linux
  (?)
@ 2013-06-13 12:47             ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-13 12:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Srinivas KANDAGATLA, Michal Simek, linux-arm, Andrew Morton,
	Arnd Bergmann, David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, linux-doc, LKML, linux-serial,
	Mark Brown, Mauro Carvalho Chehab, Olof Johansson, Rob Herring,
	Rob Landley, Samuel Ortiz, Stephen Gallimore, Stuart Menefy,
	Thomas Gleixner, Tony Prisk

On Tue, Jun 11, 2013 at 1:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>> >
>> >
>> >
>> > #include <linux/bitops.h>
>> > Linus Walleij would write use  BIT() here
>>
>> I will use BIT() macro.
>
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().

This is true. Luckily I didn't push for it myself this time.

However, on a related key we have this hidden away in MFD
drivers/mfd/dbx500-prcmu-regs.h:

#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))

It's used like so:

#define PRCM_PLL_FREQ_D_MASK    BITS(0, 7)

So you can define an multi-bit mask with a macro like that.

If there is interest in a construct like this I can make a patch to
move this thing to <linux/bitops.h>.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 12:47             ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-13 12:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Srinivas KANDAGATLA, Michal Simek, linux-arm, Andrew Morton,
	Arnd Bergmann, David S. Miller, devicetree-discuss, Grant Likely,
	Greg Kroah-Hartman, John Stultz, linux-doc, LKML, linux-serial,
	Mark Brown, Mauro Carvalho Chehab, Olof Johansson, Rob Herring,
	Rob Landley, Samuel Ortiz, Stephen Gallimore, Stuart Menefy

On Tue, Jun 11, 2013 at 1:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>> >
>> >
>> >
>> > #include <linux/bitops.h>
>> > Linus Walleij would write use  BIT() here
>>
>> I will use BIT() macro.
>
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().

This is true. Luckily I didn't push for it myself this time.

However, on a related key we have this hidden away in MFD
drivers/mfd/dbx500-prcmu-regs.h:

#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))

It's used like so:

#define PRCM_PLL_FREQ_D_MASK    BITS(0, 7)

So you can define an multi-bit mask with a macro like that.

If there is interest in a construct like this I can make a patch to
move this thing to <linux/bitops.h>.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-13 12:47             ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-13 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 11, 2013 at 1:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Jun 10, 2013 at 12:46:59PM +0100, Srinivas KANDAGATLA wrote:
>> >     +       aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
>> >     +               (0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
>> >     +               (way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
>> >
>> >
>> >
>> > #include <linux/bitops.h>
>> > Linus Walleij would write use  BIT() here
>>
>> I will use BIT() macro.
>
> Without checking those fields... BIT() is only appropriate if you're
> really talking about single bits.  If you have a field of more than a
> single bit which you happen to be setting to '1' then it's not
> appropriate to use BIT().

This is true. Luckily I didn't push for it myself this time.

However, on a related key we have this hidden away in MFD
drivers/mfd/dbx500-prcmu-regs.h:

#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))

It's used like so:

#define PRCM_PLL_FREQ_D_MASK    BITS(0, 7)

So you can define an multi-bit mask with a macro like that.

If there is interest in a construct like this I can make a patch to
move this thing to <linux/bitops.h>.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
  2013-06-10 13:52       ` Arnd Bergmann
@ 2013-06-14  7:12         ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-14  7:12 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Andrew Morton, David S. Miller,
	devicetree-discuss, Grant Likely, Greg Kroah-Hartman,
	John Stultz, Linus Walleij, linux, linux-doc, linux-kernel,
	linux-serial, Mark Brown, Mauro Carvalho Chehab, Olof Johansson,
	Rob Herring, Rob Landley, Samuel Ortiz, Stephen Gallimore,
	Stuart Menefy, Thomas Gleixner, Tony Prisk

On 10/06/13 14:52, Arnd Bergmann wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
> 
>> > +	soc {
>> > +		pin-controller-sbc {
>> > +			#address-cells	= <1>;
>> > +			#size-cells	= <1>;
>> > +			compatible	= "st,stih416-pinctrl", "simple-bus";
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?
> 
I did try this suggestion, and it simplified driver too, I will do this
change in next version.

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
@ 2013-06-14  7:12         ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-14  7:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 14:52, Arnd Bergmann wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
> 
>> > +	soc {
>> > +		pin-controller-sbc {
>> > +			#address-cells	= <1>;
>> > +			#size-cells	= <1>;
>> > +			compatible	= "st,stih416-pinctrl", "simple-bus";
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?
> 
I did try this suggestion, and it simplified driver too, I will do this
change in next version.

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-10 16:38             ` Srinivas KANDAGATLA
@ 2013-06-14  7:31                 ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-14  7:31 UTC (permalink / raw)
  To: srinivas.kandagatla-qxv4g6HH51o
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On 10/06/13 17:38, Srinivas Kandagatla wrote:
>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>> >> @@ -0,0 +1,94 @@
>> >> +#ifndef _STIXXXX_PINCFG_H_
>> >> +#define _STIXXXX_PINCFG_H_
>> >> +
>> >> +/* Alternate functions */
>> >> +#define ALT1   1
>> >> +#define ALT2   2
>> >> +#define ALT3   3
>> >> +#define ALT4   4
>> >> +#define ALT5   5
>> >> +#define ALT6   6
>> >> +#define ALT7   7
>> 
>> Why is this part of the DT definitions? In the pinctrl world this
>> is an intrinsic detail on how groups and functions are associated,
>> not something that you hard-code into the device tree. The
>> device tree should state how to combine functions with groups
>> and those will be strings, not numerals.

Hi Linus,
I would like to get correct understanding of the point your raised here.
I use these ALT function values in "st,function" property for pinctrl
group as shown in this simple example:

pinctrl_sbc_serial1:sbc_serial1 {
       st,function = <ALT3>;
       st,pins {
              tx      = <&PIO2 6 OUT>;
              rx      = <&PIO2 7 IN>;
       };
};

If I do something like what rockchip pinctrl did the pinctrl group will
look like.

pinctrl_sbc_serial1:sbc_serial1 {
       st,pins {
              tx      = <&PIO2 6 OUT ALT3>;
              rx      = <&PIO2 7 IN ALT3>;
       };
};

Is this the right way to do it?

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-14  7:31                 ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-14  7:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/06/13 17:38, Srinivas Kandagatla wrote:
>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>> >> @@ -0,0 +1,94 @@
>> >> +#ifndef _STIXXXX_PINCFG_H_
>> >> +#define _STIXXXX_PINCFG_H_
>> >> +
>> >> +/* Alternate functions */
>> >> +#define ALT1   1
>> >> +#define ALT2   2
>> >> +#define ALT3   3
>> >> +#define ALT4   4
>> >> +#define ALT5   5
>> >> +#define ALT6   6
>> >> +#define ALT7   7
>> 
>> Why is this part of the DT definitions? In the pinctrl world this
>> is an intrinsic detail on how groups and functions are associated,
>> not something that you hard-code into the device tree. The
>> device tree should state how to combine functions with groups
>> and those will be strings, not numerals.

Hi Linus,
I would like to get correct understanding of the point your raised here.
I use these ALT function values in "st,function" property for pinctrl
group as shown in this simple example:

pinctrl_sbc_serial1:sbc_serial1 {
       st,function = <ALT3>;
       st,pins {
              tx      = <&PIO2 6 OUT>;
              rx      = <&PIO2 7 IN>;
       };
};

If I do something like what rockchip pinctrl did the pinctrl group will
look like.

pinctrl_sbc_serial1:sbc_serial1 {
       st,pins {
              tx      = <&PIO2 6 OUT ALT3>;
              rx      = <&PIO2 7 IN ALT3>;
       };
};

Is this the right way to do it?

Thanks,
srini

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
  2013-06-10  9:22     ` Srinivas KANDAGATLA
@ 2013-06-16 12:17         ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-16 12:17 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

> About driver:
> This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
> pinconf, pinmux, gpio subsystems. All the pinctrl related config
> information can only come from device trees.

OK that's a good approach!

> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
> @@ -0,0 +1,116 @@
> +*ST pin controller.
> +
> +Each multi-function pin is controlled, driven and routed through the
> +PIO multiplexing block. Each pin supports GPIO functionality (ALT0)
> +and multiple alternate functions(ALT1 - ALTx) that directly connect
> +the pin to different hardware blocks.
> +
> +When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and
> +Pull Up (PU) are driven by the related PIO block.
> +
> +ST pinctrl driver controls PIO multiplexing block and also interacts with
> +gpio driver to configure a pin.
> +
> +Required properties: (PIO multiplexing block)
> +- compatible   : should be "st,stixxxx-pinctrl"
> +                       each subnode should set "st,stixxxx-gpio"
> +                       as compatible for each gpio-controller bank.
> +- gpio-controller : Indicates this device is a GPIO controller
> +- #gpio-cells    : Should be one. The first cell is the pin number.
> +- st,retime-in-delay   : Should be array of delays in nsecs.
> +- st,retime-out-delay  : Should be array of delays in nsecs.

Please explain more verbosely what is meant by these
delays. in-delay of what? out-delay of what?

> +- st,retime-pin-mask   : Should be mask to specify which pins can be retimed.

Explain what this "retimed" means.

> +- st,bank-name         : Should be a name string for this bank.

Usually we only use an identifier, like a number for this, but
maybe you need this, so won't judge on it.

> +- st,syscfg            : phandle of the syscfg node.

This is pretty clever.

> +- st,syscfg-offsets    : Should be a 5 cell entry which represent offset of altfunc,
> +       output-enable, pull-up , open drain and retime registers in the syscfg bank

No please. Use the compatible string to determine which version of the
hardware this is and encode a register offset table into the driver instead.
We do not store register offsets in the device tree, it is not a datasheet
XML container you know...

(...)
> +Contents of function subnode node:
(...)
> +- st,pins      : Child node with list of pins with configuration.
(...)
> +Every PIO is represented with 4-7 parameters depending on retime configuration.
> +Each parameter is explained as below.
> +
> +-bank          : Should be bank phandle to which this PIO belongs.
> +-offset                : Offset in the PIO bank.
> +-mode          :pin configuration is selected from one of the below values.
> +               IN
> +               IN_PU
> +               OUT
> +               BIDIR
> +               BIDIR_PU

This looks like it could use our new generic pinconfig API.
Please follow the discussions on the mailing list and read the
latest commits to the pinctrl devel branch on this subject.

Please explain what "bidir(ectional)" actually means here:
does this mean the same as HighZ/tristate or something
else?

> +-rt_type       Retiming Configuration for the pin.
> +               Possible retime configuration are:
> +
> +               -------         -------------
> +               value           args
> +               -------         -------------
> +               NICLK           <delay> <clk>
> +               ICLK_IO         <delay> <clk>
> +               BYPASS          <delay>
> +               DE_IO           <delay> <clk>
> +               SE_ICLK_IO      <delay> <clk>
> +               SE_NICLK_IO     <delay> <clk>
> +
> +- delay        is retime delay in pico seconds.
> +               Possible values are: refer to retime-in/out-delays

Earlier it was given in nanoseconds.

And I still have no clue what "retiming" means.

I'm suspecting you cannot actually use generic pinconfig
due to all this retiming esoterica but atleast give it a thought.

> +- rt_clk       :clk to be use for retime.
> +               Possible values are:
> +               CLK_A
> +               CLK_B
> +               CLK_C
> +               CLK_D

So this is selecting one of four available clock lines?

Should this not interact with some clk bindings for your
clock tree?

> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 8f66924..0c040a3 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -169,6 +169,17 @@ config PINCTRL_SUNXI
>         select PINMUX
>         select GENERIC_PINCONF
>
> +config PINCTRL_STIXXXX

As mentioned elsewhere STIXXXX is a bit too much X:es in.
Please come up with some better naming if possible.

> +       bool "ST Microelectronics pin controller driver for STixxxx SoCs"

Add:
depends on OF

> +       select PINMUX
> +       select PINCONF
> +       help
> +         Say yes here to support pinctrl interface on STixxxx SOCs.
> +         This driver is used to control both PIO block and PIO-mux
> +         block to configure a pin.
> +
> +         If unsure, say N.

(...)
> +++ b/drivers/pinctrl/pinctrl-stixxxx.c

Same naming problem. Repeat again for all identifiers in the code.
Won't mention it again.

(...)
> +#define to_stixxxx_gpio_port(chip) \
> +               container_of(chip, struct stixxxx_gpio_port, gpio_chip)
> +
> +struct stixxxx_gpio_port {
> +       struct gpio_chip        gpio_chip;
> +       struct pinctrl_gpio_range range;
> +       void __iomem            *base;
> +       struct device_node      *of_node;

Why do you need this? The struct gpio_chip above can contain
the of_node can it not?

> +       const char              *bank_name;
> +};

> +static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];

This is complicating things. Can't you just store the array of GPIO ports
*inside* the struct stixxxx_pinctrl container or something?

(...)
> +/* Low level functions.. */
> +static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
> +                               int pin_id, unsigned long config)

Why is this function called "*_set_direction" when it is also
messing with PU and OD?

_set_config would be more appropriate.

(The code looks fine.)

(...)
> +static void stixxxx_pinconf_set_retime_packed(
> +               struct stixxxx_pio_control *pc,
> +               unsigned long config, int pin)
> +{
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
> +       struct regmap_field **regs;
> +       unsigned int values[2];
> +       unsigned long mask;
> +       int i, j;
> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
> +                       pc->rt_params, config);

As you can see it's a bit excess of "X" above. Hard to read.

Then it seems like some of these should be bool, because:

> +       unsigned long rt_cfg =
> +               ((clk           & 1) << offset->clk1notclk0_offset) |
> +               ((clknotdata    & 1) << offset->clknotdata_offset) |
> +               ((delay         & 1) << offset->delay_lsb_offset) |
> +               (((delay >> 1)  & 1) << offset->delay_msb_offset) |
> +               ((double_edge   & 1) << offset->double_edge_offset) |
> +               ((invertclk     & 1) << offset->invertclk_offset) |
> +               ((retime        & 1) << offset->retime_offset);

This is looking strange. Just strange.
Comments are needed I think. For example why
arey >> 1 on delay all of a sudden?

I would try to make clk, clknotdata, delay etc into bools.

Then it could be more readable like this:

#include <linux/bitops.h>

unsigned long rt_cfg = 0;

if (clk)
    rt_cfg |= BIT(offset->clk1notclk0_offset);
if (clknotdata)
    rt_cfg |= BIT(offset->clknotdata_offset);

etc.

> +       regs = pc->retiming;
> +       regmap_field_read(regs[0], &values[0]);
> +       regmap_field_read(regs[1], &values[1]);
> +
> +       for (i = 0; i < 2; i++) {
> +               mask = BIT(pin);
> +               for (j = 0; j < 4; j++) {
> +                       if (rt_cfg & 1)
> +                               values[i] |= mask;
> +                       else
> +                               values[i] &= ~mask;
> +                       mask <<= 8;
> +                       rt_cfg >>= 1;
> +               }
> +       }

2? 4? 8? Not quite readable with so many magic constants.
Is this "8" identical to STIXXXX_GPIO_PINS_PER_PORT?

> +       regmap_field_write(regs[0], values[0]);
> +       regmap_field_write(regs[1], values[1]);
> +}

(...)
> +static void stixxxx_pinconf_set_retime_dedicated(
> +       struct stixxxx_pio_control *pc,
> +       unsigned long config, int pin)
> +{
> +       struct regmap_field *reg;
> +       int input = STIXXXX_PINCONF_UNPACK_OE(config) ? 0 : 1;
> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
> +                       pc->rt_params, config);
> +
> +       unsigned long retime_config =
> +               ((clk           & 0x3) << 0) |
> +               ((clknotdata    & 0x1) << 2) |
> +               ((delay         & 0xf) << 3) |
> +               ((input         & 0x1) << 7) |
> +               ((double_edge   & 0x1) << 8) |
> +               ((invertclk     & 0x1) << 9) |
> +               ((retime        & 0x1) << 10);

Same comments as above.

(...)
> +static void stixxxx_pinconf_get_direction(struct stixxxx_pio_control *pc,
> +       int pin_id, unsigned long *config)
> +{
> +       unsigned int oe_value, pu_value, od_value;
> +       int pin = stixxxx_gpio_pin(pin_id);
> +
> +       regmap_field_read(pc->oe, &oe_value);
> +       regmap_field_read(pc->pu, &pu_value);
> +       regmap_field_read(pc->od, &od_value);
> +
> +       oe_value = (oe_value >> pin) & 1;
> +       pu_value = (pu_value >> pin) & 1;
> +       od_value = (od_value >> pin) & 1;
> +
> +       STIXXXX_PINCONF_PACK_OE(*config, oe_value);
> +       STIXXXX_PINCONF_PACK_PU(*config, pu_value);
> +       STIXXXX_PINCONF_PACK_OD(*config, od_value);
> +}

However that's quite readable actually, this part I
understand.

> +static int stixxxx_pinconf_get_retime_packed(
> +               struct stixxxx_pio_control *pc,
> +               int pin, unsigned long *config)
> +{
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
> +       unsigned long delay_bits, delay, rt_reduced;
> +       unsigned int rt_value[2];
> +       int i, j;
> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
> +
> +       regmap_field_read(pc->retiming[0], &rt_value[0]);
> +       regmap_field_read(pc->retiming[1], &rt_value[1]);
> +
> +       rt_reduced = 0;
> +       for (i = 0; i < 2; i++) {
> +               for (j = 0; j < 4; j++) {
> +                       if (rt_value[i] & (1<<((8*j)+pin)))
> +                               rt_reduced |= 1 << ((i*4)+j);
> +               }
> +       }

Urgh 2, 4, 8??

What is happening here ... atleast a big comment
explaining the logic would be helpful. Some kind of
matrix traversal seem to be involved.

> +       STIXXXX_PINCONF_PACK_RT(*config,
> +                       (rt_reduced >> offset->retime_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_CLK(*config,
> +                       (rt_reduced >> offset->clk1notclk0_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
> +                       (rt_reduced >> offset->clknotdata_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
> +                       (rt_reduced >> offset->double_edge_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
> +                       (rt_reduced >> offset->invertclk_offset) & 1);

I would rewrite this like

if ((rt_reduced >> offset->retime_offset) & 1)
   STIXXXX_PINCONF_PACK_RT(*config, 1);

See further comments on these macros below.

I prefer if they are only used to set bits to 1, then it just becomes:

if ((rt_reduced >> offset->retime_offset) & 1)
   STIXXXX_PINCONF_PACK_RT(*config);

Simpler.

> +       delay_bits =  (((rt_reduced >> offset->delay_msb_offset) & 1)<<1) |
> +                       ((rt_reduced >> offset->delay_lsb_offset) & 1);
> +       delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
> +       STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);

This looks OK though.

(...)
> +static int stixxxx_pinconf_get_retime_dedicated(
> +               struct stixxxx_pio_control *pc,
> +               int pin, unsigned long *config)
> +{
> +       unsigned int value;
> +       unsigned long delay_bits, delay;
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
> +
> +       regmap_field_read(pc->retiming[pin], &value);
> +       STIXXXX_PINCONF_PACK_RT_CLK(*config, ((value >> 0) & 0x3));
> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config, ((value >> 2) & 0x1));
> +       delay_bits = ((value >> 3) & 0xf);

0x03? 2? 3? lots of magic constants here, can they be defined?

> +       delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
> +       STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config, ((value >> 8) & 0x1));

8?

> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config, ((value >> 9) & 0x1));

9?

> +       STIXXXX_PINCONF_PACK_RT(*config, ((value >> 10) & 0x1));

10?

Can these be #defines?

(...)
> +static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
> +{
> +       int port_num = stixxxx_gpio_port(gpio);
> +       int offset = stixxxx_gpio_pin(gpio);
> +       struct stixxxx_gpio_port *port  = gpio_ports[port_num];
> +       int i = 0;
> +
> +       for (i = 0; i <= 2; i++) {
> +               if (direction & BIT(i))
> +                       writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
> +               else
> +                       writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
> +       }

Can you explain here in a comment why the loop has to hit
bits 0, 1 and 2 in this register?

(...)
> +static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
> +{
> +       struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
> +
> +       return (readl(port->base + REG_PIO_PIN) >> offset) & 1;

Usually we do this with the double-bang idiom:

return !!(readl(port->base + REG_PIO_PIN) & BIT(offset));

> +static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
> +                               struct pinctrl_map *map, unsigned num_maps)
> +{
> +}

Isn't this optional? And don't you need to free this?

(...)
> +static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
> +                                  struct seq_file *s, unsigned pin_id)
> +{
> +       unsigned long config;
> +       stixxxx_pinconf_get(pctldev, pin_id, &config);
> +
> +       seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
> +               "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
> +               "de:%ld,rt-clk:%ld,rt-delay:%ld]",
> +               STIXXXX_PINCONF_UNPACK_OE(config),
> +               STIXXXX_PINCONF_UNPACK_PU(config),
> +               STIXXXX_PINCONF_UNPACK_OD(config),
> +               STIXXXX_PINCONF_UNPACK_RT(config),
> +               STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
> +               STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
> +               STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
> +               STIXXXX_PINCONF_UNPACK_RT_CLK(config),
> +               STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
> +}

This looks real nice, but is the output human-friendly?
Well maybe the format needs to be compact like this...

> +       if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
> +               rt_offset = devm_kzalloc(info->dev,
> +                       sizeof(*rt_offset), GFP_KERNEL);
> +
> +               if (!rt_offset)
> +                       return -ENOMEM;
> +
> +               rt_offset->clk1notclk0_offset = 0;
> +               rt_offset->delay_lsb_offset = 2;
> +               rt_offset->delay_msb_offset = 3;
> +               rt_offset->invertclk_offset = 4;
> +               rt_offset->retime_offset = 5;
> +               rt_offset->clknotdata_offset = 6;
> +               rt_offset->double_edge_offset = 7;

This looks awkward and complicated.

Why not just #define these offsets and use them
directly in the code?

> +static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
> +                       struct device_node *np)
> +{
> +       struct stixxxx_pio_control *pc;
> +       struct stixxxx_retime_params *rt_params;
> +       struct device *dev = info->dev;
> +       struct regmap *regmap;
> +       unsigned int i = 0;
> +       struct device_node *child = NULL;
> +       u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
> +       u32 syscfg_offsets[5];
> +       u32 msb, lsb;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
> +       rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
> +
> +       if (!pc || !rt_params)
> +               return -ENOMEM;
> +
> +       regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
> +       if (!regmap) {
> +               dev_err(dev, "No syscfg phandle specified\n");
> +               return -ENOMEM;
> +       }
> +       info->regmap = regmap;
> +       info->pio_controls = pc;
> +       if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
> +               return -ENOMEM;
> +
> +       if (of_property_read_u32_array(np, "st,syscfg-offsets",
> +                               syscfg_offsets, 5)) {
> +               dev_err(dev, "Syscfg offsets not found\n");
> +               return -EINVAL;
> +       }
> +       alt_syscfg = syscfg_offsets[0];
> +       oe_syscfg = syscfg_offsets[1];
> +       pu_syscfg = syscfg_offsets[2];
> +       od_syscfg = syscfg_offsets[3];
> +       rt_syscfg = syscfg_offsets[4];

This isn't looking any fun either.

#defining the offsets avoid all this strange boilerplate.

> +       lsb = 0;
> +       msb = 7;

And this.

> +       for_each_child_of_node(np, child) {
> +               if (of_device_is_compatible(child, gpio_compat)) {
> +                       struct reg_field alt_reg =
> +                                       REG_FIELD(4 * alt_syscfg++, 0, 31);
> +                       struct reg_field oe_reg =
> +                                       REG_FIELD(4 * oe_syscfg, lsb, msb);
> +                       struct reg_field pu_reg =
> +                                       REG_FIELD(4 * pu_syscfg, lsb, msb);
> +                       struct reg_field od_reg =
> +                                       REG_FIELD(4 * od_syscfg, lsb, msb);
> +                       pc[i].rt_params = rt_params;
> +
> +                       pc[i].alt = devm_regmap_field_alloc(dev,
> +                                                       regmap, alt_reg);
> +                       pc[i].oe = devm_regmap_field_alloc(dev,
> +                                                       regmap, oe_reg);
> +                       pc[i].pu = devm_regmap_field_alloc(dev,
> +                                                       regmap, pu_reg);
> +                       pc[i].od = devm_regmap_field_alloc(dev,
> +                                                       regmap, od_reg);
> +
> +                       if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
> +                               || IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
> +                               goto failed;
> +
> +                       of_property_read_u32(child, "st,retime-pin-mask",
> +                                               &pc[i].rt_pin_mask);
> +
> +                       stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
> +                                                       &rt_syscfg);
> +                       i++;
> +                       if (msb  == 31) {
> +                               oe_syscfg++;
> +                               pu_syscfg++;
> +                               od_syscfg++;
> +                               lsb = 0;
> +                               msb = 7;
> +                       } else {
> +                               lsb += 8;
> +                               msb += 8;
> +                       }

Can you explain with a comment what is happening here.

> +static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
> +{
> +       int i;
> +       for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
> +               if (gpio_ports[i]->of_node == np)
> +                       return &gpio_ports[i]->range;
> +
> +       return NULL;
> +}

This looks a bit like it's duplicating pinctrl_find_gpio_range_from_pin()
or similar already available from the pinctrl core. But it seems you
may need it here in this case.

> +static int stixxxx_pctl_probe(struct platform_device *pdev)
(...)
> +static int stixxxx_gpio_probe(struct platform_device *pdev)
(...)
> +static struct of_device_id stixxxx_gpio_of_match[] = {
> +       { .compatible = "st,stixxxx-gpio", },
> +       { /* sentinel */ }
> +};
> +
> +static struct platform_driver stixxxx_gpio_driver = {
> +       .driver = {
> +               .name = "st-gpio",
> +               .owner = THIS_MODULE,
> +               .of_match_table = of_match_ptr(stixxxx_gpio_of_match),
> +       },
> +       .probe = stixxxx_gpio_probe,
> +};
> +
> +static struct of_device_id stixxxx_pctl_of_match[] = {
> +       { .compatible = "st,stixxxx-pinctrl",},
> +       { .compatible = "st,stih415-pinctrl",},
> +       { .compatible = "st,stih416-pinctrl",},
> +       { /* sentinel */ }
> +};
> +
> +static struct platform_driver stixxxx_pctl_driver = {
> +       .driver = {
> +               .name = "st-pinctrl",
> +               .owner = THIS_MODULE,
> +               .of_match_table = of_match_ptr(stixxxx_pctl_of_match),
> +       },
> +       .probe = stixxxx_pctl_probe,
> +};


Why do you need separate nodes and probe functions for the
pinctrl and GPIO? Can't you just have a single pinctrl node?

> +static int __init stixxxx_pctl_init(void)
> +{
> +       int ret = platform_driver_register(&stixxxx_gpio_driver);
> +       if (ret)
> +               return ret;
> +       return platform_driver_register(&stixxxx_pctl_driver);
> +}

Especially since you're just registering them after each other.

Maybe you could have the GPIO nodes as children inside  the
pinctrl node and iterate over with for_each_child_of_node()?

I'm not requiring you rewrite this, just that you give it a thought.

(...)
> +++ b/drivers/pinctrl/pinctrl-stixxxx.h
> @@ -0,0 +1,197 @@
> +
> +/*
> + * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
> + * Authors:
> + *     Srinivas Kandagatla <srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
> +#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
> +
> +enum stixxxx_retime_style {
> +       stixxxx_retime_style_none,
> +       stixxxx_retime_style_packed,
> +       stixxxx_retime_style_dedicated,
> +};
> +
> +/* Byte positions in 2 syscon words, starts from 0 */
> +struct stixxxx_retime_offset {
> +       int retime_offset;
> +       int clk1notclk0_offset;
> +       int clknotdata_offset;
> +       int double_edge_offset;
> +       int invertclk_offset;
> +       int delay_lsb_offset;
> +       int delay_msb_offset;
> +};
> +
> +struct stixxxx_retime_params {
> +       const struct stixxxx_retime_offset *retime_offset;
> +       unsigned int *delay_times_in;
> +       int num_delay_times_in;
> +       unsigned int *delay_times_out;
> +       int num_delay_times_out;
> +};
> +
> +struct stixxxx_pio_control {
> +       enum stixxxx_retime_style rt_style;
> +       u32 rt_pin_mask;
> +       const struct stixxxx_retime_params *rt_params;
> +       struct regmap_field *alt;
> +       struct regmap_field *oe, *pu, *od;
> +       struct regmap_field *retiming[8];
> +};

Are these used outside of the driver? If not, move it into the
driver .c file.


> +/* PIO Block registers */
> +/* PIO output */
> +#define REG_PIO_POUT                   0x00
> +/* Set bits of POUT */
> +#define REG_PIO_SET_POUT               0x04
> +/* Clear bits of POUT */
> +#define REG_PIO_CLR_POUT               0x08
> +/* PIO input */
> +#define REG_PIO_PIN                    0x10
> +/* PIO configuration */
> +#define REG_PIO_PC(n)                  (0x20 + (n) * 0x10)
> +/* Set bits of PC[2:0] */
> +#define REG_PIO_SET_PC(n)              (0x24 + (n) * 0x10)
> +/* Clear bits of PC[2:0] */
> +#define REG_PIO_CLR_PC(n)              (0x28 + (n) * 0x10)
> +/* PIO input comparison */
> +#define REG_PIO_PCOMP                  0x50
> +/* Set bits of PCOMP */
> +#define REG_PIO_SET_PCOMP              0x54
> +/* Clear bits of PCOMP */
> +#define REG_PIO_CLR_PCOMP              0x58
> +/* PIO input comparison mask */
> +#define REG_PIO_PMASK                  0x60
> +/* Set bits of PMASK */
> +#define REG_PIO_SET_PMASK              0x64
> +/* Clear bits of PMASK */
> +#define REG_PIO_CLR_PMASK              0x68
> +
> +#define STIXXXX_MAX_GPIO_BANKS         32
> +
> +#define STIXXXX_GPIO_DIRECTION_BIDIR   0x1
> +#define STIXXXX_GPIO_DIRECTION_OUT     0x2
> +#define STIXXXX_GPIO_DIRECTION_IN      0x4

> +#define STIXXXX_GPIO_PINS_PER_PORT     8


Does *any* of this have to be in the header file? If not, move it
into the driver instead, so the reader don't have to shift between several
files when reading the driver code.

> +#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
> +#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)

Move these three #defines into the driver and convert the
two last ones to static inlines instead. Easier to maintain.

> +
> +/* pinconf */
> +/*
> + * Pinconf is represented in an opaque unsigned long variable.
> + * Below is the bit allocation details for each possible configuration.
> + * All the bit fields can be encapsulated into four variables
> + * (direction, retime-type, retime-clk, retime-delay)
> + *
> + *      +----------------+
> + *[31:28]| reserved-3     |
> + *      +----------------+-------------
> + *[27]   |     oe        |             |
> + *      +----------------+             v
> + *[26]   |     pu        |     [Direction      ]
> + *      +----------------+             ^
> + *[25]   |     od        |             |
> + *      +----------------+-------------
> + *[24]   | reserved-2     |
> + *      +----------------+-------------
> + *[23]   |    retime      |            |
> + *      +----------------+             |
> + *[22]   | retime-invclk  |            |
> + *      +----------------+             v
> + *[21]   |retime-clknotdat|    [Retime-type    ]
> + *      +----------------+             ^
> + *[20]   | retime-de      |            |
> + *      +----------------+-------------
> + *[19:18]| retime-clk     |------>[Retime-Clk  ]
> + *      +----------------+
> + *[17:16]|  reserved-1    |
> + *      +----------------+
> + *[15..0]| retime-delay   |------>[Retime Delay]
> + *      +----------------+
> + */
> +
> +#define STIXXXX_PINCONF_UNPACK(conf, param)\
> +                               ((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
> +                               & STIXXXX_PINCONF_ ##param ##_MASK)
> +
> +#define STIXXXX_PINCONF_PACK(conf, val, param) (conf |=\
> +                               ((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
> +                                       STIXXXX_PINCONF_ ##param ##_SHIFT))
> +
> +/* Output enable */
> +#define STIXXXX_PINCONF_OE_MASK                0x1
> +#define STIXXXX_PINCONF_OE_SHIFT       27
> +#define STIXXXX_PINCONF_OE             BIT(27)
> +#define STIXXXX_PINCONF_UNPACK_OE(conf)        STIXXXX_PINCONF_UNPACK(conf, OE)
> +#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)

For all of these macros: why are you suppying an argument that can only
be 0 or 1?

Just alter PACK like this:

#define STIXXXX_PINCONF_PACK_OE(conf)  STIXXXX_PINCONF_PACK(conf, 1, OE)

And only call it if you want to enable the feature, else avoid calling it.
There is no point of setting bits to zero with so much adoo.


> +/* Pull Up */
> +#define STIXXXX_PINCONF_PU_MASK                0x1
> +#define STIXXXX_PINCONF_PU_SHIFT       26
> +#define STIXXXX_PINCONF_PU             BIT(26)
> +#define STIXXXX_PINCONF_UNPACK_PU(conf)        STIXXXX_PINCONF_UNPACK(conf, PU)
> +#define STIXXXX_PINCONF_PACK_PU(conf, val) STIXXXX_PINCONF_PACK(conf, val, PU)

Dito.

> +/* Open Drain */
> +#define STIXXXX_PINCONF_OD_MASK                0x1
> +#define STIXXXX_PINCONF_OD_SHIFT       25
> +#define STIXXXX_PINCONF_OD             BIT(25)
> +#define STIXXXX_PINCONF_UNPACK_OD(conf)        STIXXXX_PINCONF_UNPACK(conf, OD)
> +#define STIXXXX_PINCONF_PACK_OD(conf, val) STIXXXX_PINCONF_PACK(conf, val, OD)

Dito.

> +#define STIXXXX_PINCONF_RT_MASK                0x1
> +#define STIXXXX_PINCONF_RT_SHIFT       23
> +#define STIXXXX_PINCONF_RT             BIT(23)
> +#define STIXXXX_PINCONF_UNPACK_RT(conf)        STIXXXX_PINCONF_UNPACK(conf, RT)
> +#define STIXXXX_PINCONF_PACK_RT(conf, val) STIXXXX_PINCONF_PACK(conf, val, RT)

Dito.

> +#define STIXXXX_PINCONF_RT_INVERTCLK_MASK      0x1
> +#define STIXXXX_PINCONF_RT_INVERTCLK_SHIFT     22
> +#define STIXXXX_PINCONF_RT_INVERTCLK           BIT(22)
> +#define STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(conf) \
> +                       STIXXXX_PINCONF_UNPACK(conf, RT_INVERTCLK)
> +#define STIXXXX_PINCONF_PACK_RT_INVERTCLK(conf, val) \
> +                       STIXXXX_PINCONF_PACK(conf, val, RT_INVERTCLK)

Dito.

> +#define STIXXXX_PINCONF_RT_CLKNOTDATA_MASK     0x1
> +#define STIXXXX_PINCONF_RT_CLKNOTDATA_SHIFT    21
> +#define STIXXXX_PINCONF_RT_CLKNOTDATA          BIT(21)
> +#define STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(conf)     \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_CLKNOTDATA)
> +#define STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_CLKNOTDATA)

Dito.

> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_MASK    0x1
> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_SHIFT   20
> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE         BIT(20)
> +#define STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE)
> +#define STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DOUBLE_EDGE)

Dito.

> +#define STIXXXX_PINCONF_RT_CLK_MASK            0x3
> +#define STIXXXX_PINCONF_RT_CLK_SHIFT           18
> +#define STIXXXX_PINCONF_RT_CLK                 BIT(18)
> +#define STIXXXX_PINCONF_UNPACK_RT_CLK(conf)    \
> +                       STIXXXX_PINCONF_UNPACK(conf, RT_CLK)
> +#define STIXXXX_PINCONF_PACK_RT_CLK(conf, val) \
> +                       STIXXXX_PINCONF_PACK(conf, val, RT_CLK)

Dito.

> +/* RETIME_DELAY in Pico Secs */
> +#define STIXXXX_PINCONF_RT_DELAY_MASK          0xffff
> +#define STIXXXX_PINCONF_RT_DELAY_SHIFT         0
> +#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
> +#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)

But here you need the special packed val to be passed,
so this looks good.

> +#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */

Move the entire header into the drivers main .c file. Why complicate things?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
@ 2013-06-16 12:17         ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-16 12:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

> About driver:
> This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
> pinconf, pinmux, gpio subsystems. All the pinctrl related config
> information can only come from device trees.

OK that's a good approach!

> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stixxxx.txt
> @@ -0,0 +1,116 @@
> +*ST pin controller.
> +
> +Each multi-function pin is controlled, driven and routed through the
> +PIO multiplexing block. Each pin supports GPIO functionality (ALT0)
> +and multiple alternate functions(ALT1 - ALTx) that directly connect
> +the pin to different hardware blocks.
> +
> +When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and
> +Pull Up (PU) are driven by the related PIO block.
> +
> +ST pinctrl driver controls PIO multiplexing block and also interacts with
> +gpio driver to configure a pin.
> +
> +Required properties: (PIO multiplexing block)
> +- compatible   : should be "st,stixxxx-pinctrl"
> +                       each subnode should set "st,stixxxx-gpio"
> +                       as compatible for each gpio-controller bank.
> +- gpio-controller : Indicates this device is a GPIO controller
> +- #gpio-cells    : Should be one. The first cell is the pin number.
> +- st,retime-in-delay   : Should be array of delays in nsecs.
> +- st,retime-out-delay  : Should be array of delays in nsecs.

Please explain more verbosely what is meant by these
delays. in-delay of what? out-delay of what?

> +- st,retime-pin-mask   : Should be mask to specify which pins can be retimed.

Explain what this "retimed" means.

> +- st,bank-name         : Should be a name string for this bank.

Usually we only use an identifier, like a number for this, but
maybe you need this, so won't judge on it.

> +- st,syscfg            : phandle of the syscfg node.

This is pretty clever.

> +- st,syscfg-offsets    : Should be a 5 cell entry which represent offset of altfunc,
> +       output-enable, pull-up , open drain and retime registers in the syscfg bank

No please. Use the compatible string to determine which version of the
hardware this is and encode a register offset table into the driver instead.
We do not store register offsets in the device tree, it is not a datasheet
XML container you know...

(...)
> +Contents of function subnode node:
(...)
> +- st,pins      : Child node with list of pins with configuration.
(...)
> +Every PIO is represented with 4-7 parameters depending on retime configuration.
> +Each parameter is explained as below.
> +
> +-bank          : Should be bank phandle to which this PIO belongs.
> +-offset                : Offset in the PIO bank.
> +-mode          :pin configuration is selected from one of the below values.
> +               IN
> +               IN_PU
> +               OUT
> +               BIDIR
> +               BIDIR_PU

This looks like it could use our new generic pinconfig API.
Please follow the discussions on the mailing list and read the
latest commits to the pinctrl devel branch on this subject.

Please explain what "bidir(ectional)" actually means here:
does this mean the same as HighZ/tristate or something
else?

> +-rt_type       Retiming Configuration for the pin.
> +               Possible retime configuration are:
> +
> +               -------         -------------
> +               value           args
> +               -------         -------------
> +               NICLK           <delay> <clk>
> +               ICLK_IO         <delay> <clk>
> +               BYPASS          <delay>
> +               DE_IO           <delay> <clk>
> +               SE_ICLK_IO      <delay> <clk>
> +               SE_NICLK_IO     <delay> <clk>
> +
> +- delay        is retime delay in pico seconds.
> +               Possible values are: refer to retime-in/out-delays

Earlier it was given in nanoseconds.

And I still have no clue what "retiming" means.

I'm suspecting you cannot actually use generic pinconfig
due to all this retiming esoterica but atleast give it a thought.

> +- rt_clk       :clk to be use for retime.
> +               Possible values are:
> +               CLK_A
> +               CLK_B
> +               CLK_C
> +               CLK_D

So this is selecting one of four available clock lines?

Should this not interact with some clk bindings for your
clock tree?

> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 8f66924..0c040a3 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -169,6 +169,17 @@ config PINCTRL_SUNXI
>         select PINMUX
>         select GENERIC_PINCONF
>
> +config PINCTRL_STIXXXX

As mentioned elsewhere STIXXXX is a bit too much X:es in.
Please come up with some better naming if possible.

> +       bool "ST Microelectronics pin controller driver for STixxxx SoCs"

Add:
depends on OF

> +       select PINMUX
> +       select PINCONF
> +       help
> +         Say yes here to support pinctrl interface on STixxxx SOCs.
> +         This driver is used to control both PIO block and PIO-mux
> +         block to configure a pin.
> +
> +         If unsure, say N.

(...)
> +++ b/drivers/pinctrl/pinctrl-stixxxx.c

Same naming problem. Repeat again for all identifiers in the code.
Won't mention it again.

(...)
> +#define to_stixxxx_gpio_port(chip) \
> +               container_of(chip, struct stixxxx_gpio_port, gpio_chip)
> +
> +struct stixxxx_gpio_port {
> +       struct gpio_chip        gpio_chip;
> +       struct pinctrl_gpio_range range;
> +       void __iomem            *base;
> +       struct device_node      *of_node;

Why do you need this? The struct gpio_chip above can contain
the of_node can it not?

> +       const char              *bank_name;
> +};

> +static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];

This is complicating things. Can't you just store the array of GPIO ports
*inside* the struct stixxxx_pinctrl container or something?

(...)
> +/* Low level functions.. */
> +static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
> +                               int pin_id, unsigned long config)

Why is this function called "*_set_direction" when it is also
messing with PU and OD?

_set_config would be more appropriate.

(The code looks fine.)

(...)
> +static void stixxxx_pinconf_set_retime_packed(
> +               struct stixxxx_pio_control *pc,
> +               unsigned long config, int pin)
> +{
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
> +       struct regmap_field **regs;
> +       unsigned int values[2];
> +       unsigned long mask;
> +       int i, j;
> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
> +                       pc->rt_params, config);

As you can see it's a bit excess of "X" above. Hard to read.

Then it seems like some of these should be bool, because:

> +       unsigned long rt_cfg =
> +               ((clk           & 1) << offset->clk1notclk0_offset) |
> +               ((clknotdata    & 1) << offset->clknotdata_offset) |
> +               ((delay         & 1) << offset->delay_lsb_offset) |
> +               (((delay >> 1)  & 1) << offset->delay_msb_offset) |
> +               ((double_edge   & 1) << offset->double_edge_offset) |
> +               ((invertclk     & 1) << offset->invertclk_offset) |
> +               ((retime        & 1) << offset->retime_offset);

This is looking strange. Just strange.
Comments are needed I think. For example why
arey >> 1 on delay all of a sudden?

I would try to make clk, clknotdata, delay etc into bools.

Then it could be more readable like this:

#include <linux/bitops.h>

unsigned long rt_cfg = 0;

if (clk)
    rt_cfg |= BIT(offset->clk1notclk0_offset);
if (clknotdata)
    rt_cfg |= BIT(offset->clknotdata_offset);

etc.

> +       regs = pc->retiming;
> +       regmap_field_read(regs[0], &values[0]);
> +       regmap_field_read(regs[1], &values[1]);
> +
> +       for (i = 0; i < 2; i++) {
> +               mask = BIT(pin);
> +               for (j = 0; j < 4; j++) {
> +                       if (rt_cfg & 1)
> +                               values[i] |= mask;
> +                       else
> +                               values[i] &= ~mask;
> +                       mask <<= 8;
> +                       rt_cfg >>= 1;
> +               }
> +       }

2? 4? 8? Not quite readable with so many magic constants.
Is this "8" identical to STIXXXX_GPIO_PINS_PER_PORT?

> +       regmap_field_write(regs[0], values[0]);
> +       regmap_field_write(regs[1], values[1]);
> +}

(...)
> +static void stixxxx_pinconf_set_retime_dedicated(
> +       struct stixxxx_pio_control *pc,
> +       unsigned long config, int pin)
> +{
> +       struct regmap_field *reg;
> +       int input = STIXXXX_PINCONF_UNPACK_OE(config) ? 0 : 1;
> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
> +                       pc->rt_params, config);
> +
> +       unsigned long retime_config =
> +               ((clk           & 0x3) << 0) |
> +               ((clknotdata    & 0x1) << 2) |
> +               ((delay         & 0xf) << 3) |
> +               ((input         & 0x1) << 7) |
> +               ((double_edge   & 0x1) << 8) |
> +               ((invertclk     & 0x1) << 9) |
> +               ((retime        & 0x1) << 10);

Same comments as above.

(...)
> +static void stixxxx_pinconf_get_direction(struct stixxxx_pio_control *pc,
> +       int pin_id, unsigned long *config)
> +{
> +       unsigned int oe_value, pu_value, od_value;
> +       int pin = stixxxx_gpio_pin(pin_id);
> +
> +       regmap_field_read(pc->oe, &oe_value);
> +       regmap_field_read(pc->pu, &pu_value);
> +       regmap_field_read(pc->od, &od_value);
> +
> +       oe_value = (oe_value >> pin) & 1;
> +       pu_value = (pu_value >> pin) & 1;
> +       od_value = (od_value >> pin) & 1;
> +
> +       STIXXXX_PINCONF_PACK_OE(*config, oe_value);
> +       STIXXXX_PINCONF_PACK_PU(*config, pu_value);
> +       STIXXXX_PINCONF_PACK_OD(*config, od_value);
> +}

However that's quite readable actually, this part I
understand.

> +static int stixxxx_pinconf_get_retime_packed(
> +               struct stixxxx_pio_control *pc,
> +               int pin, unsigned long *config)
> +{
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
> +       unsigned long delay_bits, delay, rt_reduced;
> +       unsigned int rt_value[2];
> +       int i, j;
> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
> +
> +       regmap_field_read(pc->retiming[0], &rt_value[0]);
> +       regmap_field_read(pc->retiming[1], &rt_value[1]);
> +
> +       rt_reduced = 0;
> +       for (i = 0; i < 2; i++) {
> +               for (j = 0; j < 4; j++) {
> +                       if (rt_value[i] & (1<<((8*j)+pin)))
> +                               rt_reduced |= 1 << ((i*4)+j);
> +               }
> +       }

Urgh 2, 4, 8??

What is happening here ... atleast a big comment
explaining the logic would be helpful. Some kind of
matrix traversal seem to be involved.

> +       STIXXXX_PINCONF_PACK_RT(*config,
> +                       (rt_reduced >> offset->retime_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_CLK(*config,
> +                       (rt_reduced >> offset->clk1notclk0_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
> +                       (rt_reduced >> offset->clknotdata_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
> +                       (rt_reduced >> offset->double_edge_offset) & 1);
> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
> +                       (rt_reduced >> offset->invertclk_offset) & 1);

I would rewrite this like

if ((rt_reduced >> offset->retime_offset) & 1)
   STIXXXX_PINCONF_PACK_RT(*config, 1);

See further comments on these macros below.

I prefer if they are only used to set bits to 1, then it just becomes:

if ((rt_reduced >> offset->retime_offset) & 1)
   STIXXXX_PINCONF_PACK_RT(*config);

Simpler.

> +       delay_bits =  (((rt_reduced >> offset->delay_msb_offset) & 1)<<1) |
> +                       ((rt_reduced >> offset->delay_lsb_offset) & 1);
> +       delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
> +       STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);

This looks OK though.

(...)
> +static int stixxxx_pinconf_get_retime_dedicated(
> +               struct stixxxx_pio_control *pc,
> +               int pin, unsigned long *config)
> +{
> +       unsigned int value;
> +       unsigned long delay_bits, delay;
> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
> +
> +       regmap_field_read(pc->retiming[pin], &value);
> +       STIXXXX_PINCONF_PACK_RT_CLK(*config, ((value >> 0) & 0x3));
> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config, ((value >> 2) & 0x1));
> +       delay_bits = ((value >> 3) & 0xf);

0x03? 2? 3? lots of magic constants here, can they be defined?

> +       delay =  stixxxx_pinconf_bit_to_delay(delay_bits, rt_params, output);
> +       STIXXXX_PINCONF_PACK_RT_DELAY(*config, delay);
> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config, ((value >> 8) & 0x1));

8?

> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config, ((value >> 9) & 0x1));

9?

> +       STIXXXX_PINCONF_PACK_RT(*config, ((value >> 10) & 0x1));

10?

Can these be #defines?

(...)
> +static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
> +{
> +       int port_num = stixxxx_gpio_port(gpio);
> +       int offset = stixxxx_gpio_pin(gpio);
> +       struct stixxxx_gpio_port *port  = gpio_ports[port_num];
> +       int i = 0;
> +
> +       for (i = 0; i <= 2; i++) {
> +               if (direction & BIT(i))
> +                       writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
> +               else
> +                       writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
> +       }

Can you explain here in a comment why the loop has to hit
bits 0, 1 and 2 in this register?

(...)
> +static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
> +{
> +       struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
> +
> +       return (readl(port->base + REG_PIO_PIN) >> offset) & 1;

Usually we do this with the double-bang idiom:

return !!(readl(port->base + REG_PIO_PIN) & BIT(offset));

> +static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
> +                               struct pinctrl_map *map, unsigned num_maps)
> +{
> +}

Isn't this optional? And don't you need to free this?

(...)
> +static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
> +                                  struct seq_file *s, unsigned pin_id)
> +{
> +       unsigned long config;
> +       stixxxx_pinconf_get(pctldev, pin_id, &config);
> +
> +       seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
> +               "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
> +               "de:%ld,rt-clk:%ld,rt-delay:%ld]",
> +               STIXXXX_PINCONF_UNPACK_OE(config),
> +               STIXXXX_PINCONF_UNPACK_PU(config),
> +               STIXXXX_PINCONF_UNPACK_OD(config),
> +               STIXXXX_PINCONF_UNPACK_RT(config),
> +               STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
> +               STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
> +               STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
> +               STIXXXX_PINCONF_UNPACK_RT_CLK(config),
> +               STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
> +}

This looks real nice, but is the output human-friendly?
Well maybe the format needs to be compact like this...

> +       if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
> +               rt_offset = devm_kzalloc(info->dev,
> +                       sizeof(*rt_offset), GFP_KERNEL);
> +
> +               if (!rt_offset)
> +                       return -ENOMEM;
> +
> +               rt_offset->clk1notclk0_offset = 0;
> +               rt_offset->delay_lsb_offset = 2;
> +               rt_offset->delay_msb_offset = 3;
> +               rt_offset->invertclk_offset = 4;
> +               rt_offset->retime_offset = 5;
> +               rt_offset->clknotdata_offset = 6;
> +               rt_offset->double_edge_offset = 7;

This looks awkward and complicated.

Why not just #define these offsets and use them
directly in the code?

> +static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
> +                       struct device_node *np)
> +{
> +       struct stixxxx_pio_control *pc;
> +       struct stixxxx_retime_params *rt_params;
> +       struct device *dev = info->dev;
> +       struct regmap *regmap;
> +       unsigned int i = 0;
> +       struct device_node *child = NULL;
> +       u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
> +       u32 syscfg_offsets[5];
> +       u32 msb, lsb;
> +
> +       pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
> +       rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
> +
> +       if (!pc || !rt_params)
> +               return -ENOMEM;
> +
> +       regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
> +       if (!regmap) {
> +               dev_err(dev, "No syscfg phandle specified\n");
> +               return -ENOMEM;
> +       }
> +       info->regmap = regmap;
> +       info->pio_controls = pc;
> +       if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
> +               return -ENOMEM;
> +
> +       if (of_property_read_u32_array(np, "st,syscfg-offsets",
> +                               syscfg_offsets, 5)) {
> +               dev_err(dev, "Syscfg offsets not found\n");
> +               return -EINVAL;
> +       }
> +       alt_syscfg = syscfg_offsets[0];
> +       oe_syscfg = syscfg_offsets[1];
> +       pu_syscfg = syscfg_offsets[2];
> +       od_syscfg = syscfg_offsets[3];
> +       rt_syscfg = syscfg_offsets[4];

This isn't looking any fun either.

#defining the offsets avoid all this strange boilerplate.

> +       lsb = 0;
> +       msb = 7;

And this.

> +       for_each_child_of_node(np, child) {
> +               if (of_device_is_compatible(child, gpio_compat)) {
> +                       struct reg_field alt_reg =
> +                                       REG_FIELD(4 * alt_syscfg++, 0, 31);
> +                       struct reg_field oe_reg =
> +                                       REG_FIELD(4 * oe_syscfg, lsb, msb);
> +                       struct reg_field pu_reg =
> +                                       REG_FIELD(4 * pu_syscfg, lsb, msb);
> +                       struct reg_field od_reg =
> +                                       REG_FIELD(4 * od_syscfg, lsb, msb);
> +                       pc[i].rt_params = rt_params;
> +
> +                       pc[i].alt = devm_regmap_field_alloc(dev,
> +                                                       regmap, alt_reg);
> +                       pc[i].oe = devm_regmap_field_alloc(dev,
> +                                                       regmap, oe_reg);
> +                       pc[i].pu = devm_regmap_field_alloc(dev,
> +                                                       regmap, pu_reg);
> +                       pc[i].od = devm_regmap_field_alloc(dev,
> +                                                       regmap, od_reg);
> +
> +                       if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
> +                               || IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
> +                               goto failed;
> +
> +                       of_property_read_u32(child, "st,retime-pin-mask",
> +                                               &pc[i].rt_pin_mask);
> +
> +                       stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
> +                                                       &rt_syscfg);
> +                       i++;
> +                       if (msb  == 31) {
> +                               oe_syscfg++;
> +                               pu_syscfg++;
> +                               od_syscfg++;
> +                               lsb = 0;
> +                               msb = 7;
> +                       } else {
> +                               lsb += 8;
> +                               msb += 8;
> +                       }

Can you explain with a comment what is happening here.

> +static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
> +{
> +       int i;
> +       for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
> +               if (gpio_ports[i]->of_node == np)
> +                       return &gpio_ports[i]->range;
> +
> +       return NULL;
> +}

This looks a bit like it's duplicating pinctrl_find_gpio_range_from_pin()
or similar already available from the pinctrl core. But it seems you
may need it here in this case.

> +static int stixxxx_pctl_probe(struct platform_device *pdev)
(...)
> +static int stixxxx_gpio_probe(struct platform_device *pdev)
(...)
> +static struct of_device_id stixxxx_gpio_of_match[] = {
> +       { .compatible = "st,stixxxx-gpio", },
> +       { /* sentinel */ }
> +};
> +
> +static struct platform_driver stixxxx_gpio_driver = {
> +       .driver = {
> +               .name = "st-gpio",
> +               .owner = THIS_MODULE,
> +               .of_match_table = of_match_ptr(stixxxx_gpio_of_match),
> +       },
> +       .probe = stixxxx_gpio_probe,
> +};
> +
> +static struct of_device_id stixxxx_pctl_of_match[] = {
> +       { .compatible = "st,stixxxx-pinctrl",},
> +       { .compatible = "st,stih415-pinctrl",},
> +       { .compatible = "st,stih416-pinctrl",},
> +       { /* sentinel */ }
> +};
> +
> +static struct platform_driver stixxxx_pctl_driver = {
> +       .driver = {
> +               .name = "st-pinctrl",
> +               .owner = THIS_MODULE,
> +               .of_match_table = of_match_ptr(stixxxx_pctl_of_match),
> +       },
> +       .probe = stixxxx_pctl_probe,
> +};


Why do you need separate nodes and probe functions for the
pinctrl and GPIO? Can't you just have a single pinctrl node?

> +static int __init stixxxx_pctl_init(void)
> +{
> +       int ret = platform_driver_register(&stixxxx_gpio_driver);
> +       if (ret)
> +               return ret;
> +       return platform_driver_register(&stixxxx_pctl_driver);
> +}

Especially since you're just registering them after each other.

Maybe you could have the GPIO nodes as children inside  the
pinctrl node and iterate over with for_each_child_of_node()?

I'm not requiring you rewrite this, just that you give it a thought.

(...)
> +++ b/drivers/pinctrl/pinctrl-stixxxx.h
> @@ -0,0 +1,197 @@
> +
> +/*
> + * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
> + * Authors:
> + *     Srinivas Kandagatla <srinivas.kandagatla@st.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
> +#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
> +
> +enum stixxxx_retime_style {
> +       stixxxx_retime_style_none,
> +       stixxxx_retime_style_packed,
> +       stixxxx_retime_style_dedicated,
> +};
> +
> +/* Byte positions in 2 syscon words, starts from 0 */
> +struct stixxxx_retime_offset {
> +       int retime_offset;
> +       int clk1notclk0_offset;
> +       int clknotdata_offset;
> +       int double_edge_offset;
> +       int invertclk_offset;
> +       int delay_lsb_offset;
> +       int delay_msb_offset;
> +};
> +
> +struct stixxxx_retime_params {
> +       const struct stixxxx_retime_offset *retime_offset;
> +       unsigned int *delay_times_in;
> +       int num_delay_times_in;
> +       unsigned int *delay_times_out;
> +       int num_delay_times_out;
> +};
> +
> +struct stixxxx_pio_control {
> +       enum stixxxx_retime_style rt_style;
> +       u32 rt_pin_mask;
> +       const struct stixxxx_retime_params *rt_params;
> +       struct regmap_field *alt;
> +       struct regmap_field *oe, *pu, *od;
> +       struct regmap_field *retiming[8];
> +};

Are these used outside of the driver? If not, move it into the
driver .c file.


> +/* PIO Block registers */
> +/* PIO output */
> +#define REG_PIO_POUT                   0x00
> +/* Set bits of POUT */
> +#define REG_PIO_SET_POUT               0x04
> +/* Clear bits of POUT */
> +#define REG_PIO_CLR_POUT               0x08
> +/* PIO input */
> +#define REG_PIO_PIN                    0x10
> +/* PIO configuration */
> +#define REG_PIO_PC(n)                  (0x20 + (n) * 0x10)
> +/* Set bits of PC[2:0] */
> +#define REG_PIO_SET_PC(n)              (0x24 + (n) * 0x10)
> +/* Clear bits of PC[2:0] */
> +#define REG_PIO_CLR_PC(n)              (0x28 + (n) * 0x10)
> +/* PIO input comparison */
> +#define REG_PIO_PCOMP                  0x50
> +/* Set bits of PCOMP */
> +#define REG_PIO_SET_PCOMP              0x54
> +/* Clear bits of PCOMP */
> +#define REG_PIO_CLR_PCOMP              0x58
> +/* PIO input comparison mask */
> +#define REG_PIO_PMASK                  0x60
> +/* Set bits of PMASK */
> +#define REG_PIO_SET_PMASK              0x64
> +/* Clear bits of PMASK */
> +#define REG_PIO_CLR_PMASK              0x68
> +
> +#define STIXXXX_MAX_GPIO_BANKS         32
> +
> +#define STIXXXX_GPIO_DIRECTION_BIDIR   0x1
> +#define STIXXXX_GPIO_DIRECTION_OUT     0x2
> +#define STIXXXX_GPIO_DIRECTION_IN      0x4

> +#define STIXXXX_GPIO_PINS_PER_PORT     8


Does *any* of this have to be in the header file? If not, move it
into the driver instead, so the reader don't have to shift between several
files when reading the driver code.

> +#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
> +#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)

Move these three #defines into the driver and convert the
two last ones to static inlines instead. Easier to maintain.

> +
> +/* pinconf */
> +/*
> + * Pinconf is represented in an opaque unsigned long variable.
> + * Below is the bit allocation details for each possible configuration.
> + * All the bit fields can be encapsulated into four variables
> + * (direction, retime-type, retime-clk, retime-delay)
> + *
> + *      +----------------+
> + *[31:28]| reserved-3     |
> + *      +----------------+-------------
> + *[27]   |     oe        |             |
> + *      +----------------+             v
> + *[26]   |     pu        |     [Direction      ]
> + *      +----------------+             ^
> + *[25]   |     od        |             |
> + *      +----------------+-------------
> + *[24]   | reserved-2     |
> + *      +----------------+-------------
> + *[23]   |    retime      |            |
> + *      +----------------+             |
> + *[22]   | retime-invclk  |            |
> + *      +----------------+             v
> + *[21]   |retime-clknotdat|    [Retime-type    ]
> + *      +----------------+             ^
> + *[20]   | retime-de      |            |
> + *      +----------------+-------------
> + *[19:18]| retime-clk     |------>[Retime-Clk  ]
> + *      +----------------+
> + *[17:16]|  reserved-1    |
> + *      +----------------+
> + *[15..0]| retime-delay   |------>[Retime Delay]
> + *      +----------------+
> + */
> +
> +#define STIXXXX_PINCONF_UNPACK(conf, param)\
> +                               ((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
> +                               & STIXXXX_PINCONF_ ##param ##_MASK)
> +
> +#define STIXXXX_PINCONF_PACK(conf, val, param) (conf |=\
> +                               ((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
> +                                       STIXXXX_PINCONF_ ##param ##_SHIFT))
> +
> +/* Output enable */
> +#define STIXXXX_PINCONF_OE_MASK                0x1
> +#define STIXXXX_PINCONF_OE_SHIFT       27
> +#define STIXXXX_PINCONF_OE             BIT(27)
> +#define STIXXXX_PINCONF_UNPACK_OE(conf)        STIXXXX_PINCONF_UNPACK(conf, OE)
> +#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)

For all of these macros: why are you suppying an argument that can only
be 0 or 1?

Just alter PACK like this:

#define STIXXXX_PINCONF_PACK_OE(conf)  STIXXXX_PINCONF_PACK(conf, 1, OE)

And only call it if you want to enable the feature, else avoid calling it.
There is no point of setting bits to zero with so much adoo.


> +/* Pull Up */
> +#define STIXXXX_PINCONF_PU_MASK                0x1
> +#define STIXXXX_PINCONF_PU_SHIFT       26
> +#define STIXXXX_PINCONF_PU             BIT(26)
> +#define STIXXXX_PINCONF_UNPACK_PU(conf)        STIXXXX_PINCONF_UNPACK(conf, PU)
> +#define STIXXXX_PINCONF_PACK_PU(conf, val) STIXXXX_PINCONF_PACK(conf, val, PU)

Dito.

> +/* Open Drain */
> +#define STIXXXX_PINCONF_OD_MASK                0x1
> +#define STIXXXX_PINCONF_OD_SHIFT       25
> +#define STIXXXX_PINCONF_OD             BIT(25)
> +#define STIXXXX_PINCONF_UNPACK_OD(conf)        STIXXXX_PINCONF_UNPACK(conf, OD)
> +#define STIXXXX_PINCONF_PACK_OD(conf, val) STIXXXX_PINCONF_PACK(conf, val, OD)

Dito.

> +#define STIXXXX_PINCONF_RT_MASK                0x1
> +#define STIXXXX_PINCONF_RT_SHIFT       23
> +#define STIXXXX_PINCONF_RT             BIT(23)
> +#define STIXXXX_PINCONF_UNPACK_RT(conf)        STIXXXX_PINCONF_UNPACK(conf, RT)
> +#define STIXXXX_PINCONF_PACK_RT(conf, val) STIXXXX_PINCONF_PACK(conf, val, RT)

Dito.

> +#define STIXXXX_PINCONF_RT_INVERTCLK_MASK      0x1
> +#define STIXXXX_PINCONF_RT_INVERTCLK_SHIFT     22
> +#define STIXXXX_PINCONF_RT_INVERTCLK           BIT(22)
> +#define STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(conf) \
> +                       STIXXXX_PINCONF_UNPACK(conf, RT_INVERTCLK)
> +#define STIXXXX_PINCONF_PACK_RT_INVERTCLK(conf, val) \
> +                       STIXXXX_PINCONF_PACK(conf, val, RT_INVERTCLK)

Dito.

> +#define STIXXXX_PINCONF_RT_CLKNOTDATA_MASK     0x1
> +#define STIXXXX_PINCONF_RT_CLKNOTDATA_SHIFT    21
> +#define STIXXXX_PINCONF_RT_CLKNOTDATA          BIT(21)
> +#define STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(conf)     \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_CLKNOTDATA)
> +#define STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_CLKNOTDATA)

Dito.

> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_MASK    0x1
> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE_SHIFT   20
> +#define STIXXXX_PINCONF_RT_DOUBLE_EDGE         BIT(20)
> +#define STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE)
> +#define STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DOUBLE_EDGE)

Dito.

> +#define STIXXXX_PINCONF_RT_CLK_MASK            0x3
> +#define STIXXXX_PINCONF_RT_CLK_SHIFT           18
> +#define STIXXXX_PINCONF_RT_CLK                 BIT(18)
> +#define STIXXXX_PINCONF_UNPACK_RT_CLK(conf)    \
> +                       STIXXXX_PINCONF_UNPACK(conf, RT_CLK)
> +#define STIXXXX_PINCONF_PACK_RT_CLK(conf, val) \
> +                       STIXXXX_PINCONF_PACK(conf, val, RT_CLK)

Dito.

> +/* RETIME_DELAY in Pico Secs */
> +#define STIXXXX_PINCONF_RT_DELAY_MASK          0xffff
> +#define STIXXXX_PINCONF_RT_DELAY_SHIFT         0
> +#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
> +#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)

But here you need the special packed val to be passed,
so this looks good.

> +#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */

Move the entire header into the drivers main .c file. Why complicate things?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
  2013-06-13  9:24             ` Srinivas KANDAGATLA
  (?)
@ 2013-06-17  9:32               ` Mark Rutland
  -1 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-17  9:32 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux, Samuel Ortiz, linux-doc, Greg Kroah-Hartman,
	devicetree-discuss, Stephen Gallimore, rob.herring, linux-kernel,
	Andrew Morton, Stuart Menefy, Mark Brown, John Stultz,
	linux-serial, grant.likely, Thomas Gleixner, David S. Miller,
	linux-arm-kernel, Mauro Carvalho Chehab

On Thu, Jun 13, 2013 at 10:24:45AM +0100, Srinivas KANDAGATLA wrote:
> On 10/06/13 14:15, Mark Rutland wrote:
> > CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> > CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> > CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> > 
> 
> Am planning to send a patch to clean this up, so that any new platform
> addition to the multi_v7_defconfig will not under go this discussion again..
> 
> > It looks like the architected timer deselection is fallout of my own making,
> > the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> > ARM_ARCH_TIMER.
> Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
> The only reason I see for de-selection is because none of the platforms
> in the multi_v7 defconfig selects it.
> 
> Looks like there is no platform in mulit_v7 config which requires this
> support. If there is one I think it should select it.
> 
> Am I correct?

You're right, I agree that the selection should be moved down into the
platforms requiring it. I'll put together patches to fix up those platforms.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-17  9:32               ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-17  9:32 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: linux, Samuel Ortiz, linux-doc, Greg Kroah-Hartman,
	devicetree-discuss, Stephen Gallimore, rob.herring, linux-kernel,
	Andrew Morton, Stuart Menefy, Mark Brown, John Stultz,
	linux-serial, grant.likely, Thomas Gleixner, David S. Miller,
	linux-arm-kernel, Mauro

On Thu, Jun 13, 2013 at 10:24:45AM +0100, Srinivas KANDAGATLA wrote:
> On 10/06/13 14:15, Mark Rutland wrote:
> > CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> > CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> > CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> > 
> 
> Am planning to send a patch to clean this up, so that any new platform
> addition to the multi_v7_defconfig will not under go this discussion again..
> 
> > It looks like the architected timer deselection is fallout of my own making,
> > the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> > ARM_ARCH_TIMER.
> Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
> The only reason I see for de-selection is because none of the platforms
> in the multi_v7 defconfig selects it.
> 
> Looks like there is no platform in mulit_v7 config which requires this
> support. If there is one I think it should select it.
> 
> Am I correct?

You're right, I agree that the selection should be moved down into the
platforms requiring it. I'll put together patches to fix up those platforms.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig
@ 2013-06-17  9:32               ` Mark Rutland
  0 siblings, 0 replies; 716+ messages in thread
From: Mark Rutland @ 2013-06-17  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 13, 2013 at 10:24:45AM +0100, Srinivas KANDAGATLA wrote:
> On 10/06/13 14:15, Mark Rutland wrote:
> > CONFIG_EXPERIMENTAL's gone as of 3d374d09f1: "final removal of
> > CONFIG_EXPERIMENTAL", so that's fine to go. CONFIG_GPIO_PL061 and
> > CONFIG_MMC_WMT get selected elsewhere, so that's fine.
> > 
> 
> Am planning to send a patch to clean this up, so that any new platform
> addition to the multi_v7_defconfig will not under go this discussion again..
> 
> > It looks like the architected timer deselection is fallout of my own making,
> > the multi_v7_defconfig should now contain HAVE_ARM_ARCH_TIMER rather than
> > ARM_ARCH_TIMER.
> Why should it even contain HAVE_ARM_ARCH_TIMER/ARM_ARCH_TIMER?
> The only reason I see for de-selection is because none of the platforms
> in the multi_v7 defconfig selects it.
> 
> Looks like there is no platform in mulit_v7 config which requires this
> support. If there is one I think it should select it.
> 
> Am I correct?

You're right, I agree that the selection should be moved down into the
platforms requiring it. I'll put together patches to fix up those platforms.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
  2013-06-16 12:17         ` Linus Walleij
@ 2013-06-17 13:31           ` Srinivas KANDAGATLA
  -1 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-17 13:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mauro Carvalho Chehab, linux-doc, Russell King - ARM Linux,
	Samuel Ortiz, Stephen Gallimore, linux-serial, Grant Likely,
	Arnd Bergmann, devicetree-discuss, Rob Herring, Stuart Menefy,
	Mark Brown, John Stultz, Thomas Gleixner, linux-arm-kernel,
	Greg Kroah-Hartman, linux-kernel, Rob Landley, Olof Johansson

Thankyou very much for the comments.

On 16/06/13 13:17, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> About driver:
>> This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
>> pinconf, pinmux, gpio subsystems. All the pinctrl related config
>> information can only come from device trees.
> 
> OK that's a good approach!
Thankyou
>> +- #gpio-cells    : Should be one. The first cell is the pin number.
>> +- st,retime-in-delay   : Should be array of delays in nsecs.
>> +- st,retime-out-delay  : Should be array of delays in nsecs.
> 
> Please explain more verbosely what is meant by these
> delays. in-delay of what? out-delay of what?
> 

Am moving this to the driver too, as these tend to be constant per given
SOC.

>> +- st,retime-pin-mask   : Should be mask to specify which pins can be retimed.
> 
> Explain what this "retimed" means.
I will explain this bit in more detail.

> 
>> +- st,bank-name         : Should be a name string for this bank.
> 
> Usually we only use an identifier, like a number for this, but
> maybe you need this, so won't judge on it.

It's used for maintaining consistency with pin names from data sheet to
the pinctrl_pin_desc.

> 
>> +- st,syscfg            : phandle of the syscfg node.
> 
> This is pretty clever.
Thankyou.
> 
>> +- st,syscfg-offsets    : Should be a 5 cell entry which represent offset of altfunc,
>> +       output-enable, pull-up , open drain and retime registers in the syscfg bank
> 
> No please. Use the compatible string to determine which version of the
> hardware this is and encode a register offset table into the driver instead.
> We do not store register offsets in the device tree, it is not a datasheet
> XML container you know...

Got it, I already moved this to the driver now. And its looking good.

> 
>> +- delay        is retime delay in pico seconds.
>> +               Possible values are: refer to retime-in/out-delays
> 
> Earlier it was given in nanoseconds.
> 
 I will fix this.

> And I still have no clue what "retiming" means.
> 
> I'm suspecting you cannot actually use generic pinconfig
> due to all this retiming esoterica but atleast give it a thought.
> 
>> +- rt_clk       :clk to be use for retime.
>> +               Possible values are:
>> +               CLK_A
>> +               CLK_B
>> +               CLK_C
>> +               CLK_D
> 
> So this is selecting one of four available clock lines?
> 
No, It's not related to driver clocks.
It's to do with the retiming. This part configures which clock to retime
output/input data to. CLK_A means retime output data to clkout[0] and
input data on clkin[0].

Will add more documentation on re-timing in general.


> Should this not interact with some clk bindings for your
> clock tree?
> 
>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>> index 8f66924..0c040a3 100644
>> --- a/drivers/pinctrl/Kconfig
>> +++ b/drivers/pinctrl/Kconfig
>> @@ -169,6 +169,17 @@ config PINCTRL_SUNXI
>>         select PINMUX
>>         select GENERIC_PINCONF
>>
>> +config PINCTRL_STIXXXX
> 
> As mentioned elsewhere STIXXXX is a bit too much X:es in.
> Please come up with some better naming if possible.

Are you OK if I use pinctrl-st.c?

> 
>> +       bool "ST Microelectronics pin controller driver for STixxxx SoCs"
> 
> Add:
> depends on OF

Ok, Will add it.
> 
>> +       select PINMUX
>> +       select PINCONF
>> +       help
>> +         Say yes here to support pinctrl interface on STixxxx SOCs.
>> +         This driver is used to control both PIO block and PIO-mux
>> +         block to configure a pin.
>> +
>> +         If unsure, say N.
> 
> (...)
>> +++ b/drivers/pinctrl/pinctrl-stixxxx.c

>> +struct stixxxx_gpio_port {
>> +       struct gpio_chip        gpio_chip;
>> +       struct pinctrl_gpio_range range;
>> +       void __iomem            *base;
>> +       struct device_node      *of_node;
> 
> Why do you need this? The struct gpio_chip above can contain
> the of_node can it not?

I remove the of_node as part of "simple-bus" cleanup from the pinctrl node.

> 
>> +       const char              *bank_name;
>> +};
> 
>> +static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];
> 
> This is complicating things. Can't you just store the array of GPIO ports
> *inside* the struct stixxxx_pinctrl container or something?

Already taken care from previous comment.

> 
> (...)
>> +/* Low level functions.. */
>> +static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
>> +                               int pin_id, unsigned long config)
> 
> Why is this function called "*_set_direction" when it is also
> messing with PU and OD?
> 
> _set_config would be more appropriate.

Yes, I will rename it.
> 
> (The code looks fine.)
> 
> (...)
>> +static void stixxxx_pinconf_set_retime_packed(
>> +               struct stixxxx_pio_control *pc,
>> +               unsigned long config, int pin)
>> +{
>> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
>> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
>> +       struct regmap_field **regs;
>> +       unsigned int values[2];
>> +       unsigned long mask;
>> +       int i, j;
>> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
>> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
>> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
>> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
>> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
>> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
>> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
>> +                       pc->rt_params, config);
> 
> As you can see it's a bit excess of "X" above. Hard to read.
> 
> Then it seems like some of these should be bool, because:

Ok, Will make it bool.

> 
>> +       unsigned long rt_cfg =
>> +               ((clk           & 1) << offset->clk1notclk0_offset) |
>> +               ((clknotdata    & 1) << offset->clknotdata_offset) |
>> +               ((delay         & 1) << offset->delay_lsb_offset) |
>> +               (((delay >> 1)  & 1) << offset->delay_msb_offset) |
>> +               ((double_edge   & 1) << offset->double_edge_offset) |
>> +               ((invertclk     & 1) << offset->invertclk_offset) |
>> +               ((retime        & 1) << offset->retime_offset);
> 
> This is looking strange. Just strange.
> Comments are needed I think. For example why
> arey >> 1 on delay all of a sudden?
> 
> I would try to make clk, clknotdata, delay etc into bools.
> 
> Then it could be more readable like this:
> 
> #include <linux/bitops.h>
> 
> unsigned long rt_cfg = 0;
> 
> if (clk)
>     rt_cfg |= BIT(offset->clk1notclk0_offset);
> if (clknotdata)
>     rt_cfg |= BIT(offset->clknotdata_offset);
> 
> etc.

Yes, Looks sensible, I will try these changes and see how it turns up.

> 
>> +       regs = pc->retiming;
>> +       regmap_field_read(regs[0], &values[0]);
>> +       regmap_field_read(regs[1], &values[1]);
>> +
>> +       for (i = 0; i < 2; i++) {
>> +               mask = BIT(pin);
>> +               for (j = 0; j < 4; j++) {
>> +                       if (rt_cfg & 1)
>> +                               values[i] |= mask;
>> +                       else
>> +                               values[i] &= ~mask;
>> +                       mask <<= 8;
>> +                       rt_cfg >>= 1;
>> +               }
>> +       }
> 
> 2? 4? 8? Not quite readable with so many magic constants.
> Is this "8" identical to STIXXXX_GPIO_PINS_PER_PORT?
> 
I agree, all these constants should be #defined in a readable way, and I
will do it. (for all the comments related to constants ...)

> 
>> +static int stixxxx_pinconf_get_retime_packed(
>> +               struct stixxxx_pio_control *pc,
>> +               int pin, unsigned long *config)
>> +{
>> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
>> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
>> +       unsigned long delay_bits, delay, rt_reduced;
>> +       unsigned int rt_value[2];
>> +       int i, j;
>> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
>> +
>> +       regmap_field_read(pc->retiming[0], &rt_value[0]);
>> +       regmap_field_read(pc->retiming[1], &rt_value[1]);
>> +
>> +       rt_reduced = 0;
>> +       for (i = 0; i < 2; i++) {
>> +               for (j = 0; j < 4; j++) {
>> +                       if (rt_value[i] & (1<<((8*j)+pin)))
>> +                               rt_reduced |= 1 << ((i*4)+j);
>> +               }
>> +       }
> 
> Urgh 2, 4, 8??
> 
> What is happening here ... atleast a big comment
> explaining the logic would be helpful. Some kind of
> matrix traversal seem to be involved.

Yes, I will add a decent comment here.

> 
>> +       STIXXXX_PINCONF_PACK_RT(*config,
>> +                       (rt_reduced >> offset->retime_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_CLK(*config,
>> +                       (rt_reduced >> offset->clk1notclk0_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
>> +                       (rt_reduced >> offset->clknotdata_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
>> +                       (rt_reduced >> offset->double_edge_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
>> +                       (rt_reduced >> offset->invertclk_offset) & 1);
> 
> I would rewrite this like
> 
> if ((rt_reduced >> offset->retime_offset) & 1)
>    STIXXXX_PINCONF_PACK_RT(*config, 1);
> 
> See further comments on these macros below.
> 
> I prefer if they are only used to set bits to 1, then it just becomes:
> 
> if ((rt_reduced >> offset->retime_offset) & 1)
>    STIXXXX_PINCONF_PACK_RT(*config);
> 
> Simpler.

I will do it.
> 
> 
> (...)
>> +static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
>> +{
>> +       int port_num = stixxxx_gpio_port(gpio);
>> +       int offset = stixxxx_gpio_pin(gpio);
>> +       struct stixxxx_gpio_port *port  = gpio_ports[port_num];
>> +       int i = 0;
>> +
>> +       for (i = 0; i <= 2; i++) {
>> +               if (direction & BIT(i))
>> +                       writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
>> +               else
>> +                       writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
>> +       }
> 
> Can you explain here in a comment why the loop has to hit
> bits 0, 1 and 2 in this register?

Yes, I will add the comments behind the logic of this.

> 
> (...)
>> +static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
>> +{
>> +       struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
>> +
>> +       return (readl(port->base + REG_PIO_PIN) >> offset) & 1;
> 
> Usually we do this with the double-bang idiom:
> 
> return !!(readl(port->base + REG_PIO_PIN) & BIT(offset));

Interesting and very neat.

> 
>> +static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
>> +                               struct pinctrl_map *map, unsigned num_maps)
>> +{
>> +}
> 
> Isn't this optional? And don't you need to free this?
> 
Its not optional because pinctrl_check_ops returns -EINVAL if set to NULL.

I don't need to free it because its a devm_kzalloc.

> (...)
>> +static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
>> +                                  struct seq_file *s, unsigned pin_id)
>> +{
>> +       unsigned long config;
>> +       stixxxx_pinconf_get(pctldev, pin_id, &config);
>> +
>> +       seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
>> +               "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
>> +               "de:%ld,rt-clk:%ld,rt-delay:%ld]",
>> +               STIXXXX_PINCONF_UNPACK_OE(config),
>> +               STIXXXX_PINCONF_UNPACK_PU(config),
>> +               STIXXXX_PINCONF_UNPACK_OD(config),
>> +               STIXXXX_PINCONF_UNPACK_RT(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_CLK(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
>> +}
> 
> This looks real nice, but is the output human-friendly?

I will see, If I can come up with a better format.

> Well maybe the format needs to be compact like this...
> 
>> +       if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
>> +               rt_offset = devm_kzalloc(info->dev,
>> +                       sizeof(*rt_offset), GFP_KERNEL);
>> +
>> +               if (!rt_offset)
>> +                       return -ENOMEM;
>> +
>> +               rt_offset->clk1notclk0_offset = 0;
>> +               rt_offset->delay_lsb_offset = 2;
>> +               rt_offset->delay_msb_offset = 3;
>> +               rt_offset->invertclk_offset = 4;
>> +               rt_offset->retime_offset = 5;
>> +               rt_offset->clknotdata_offset = 6;
>> +               rt_offset->double_edge_offset = 7;
> 
> This looks awkward and complicated.
> 
> Why not just #define these offsets and use them
> directly in the code?

This is more specific to a SOC.
This information now comes as part of the SOC specific compatible node data.

Like this:

const struct stixxxx_retime_offset stih415_retime_offset = {
	.clk1notclk0_offset	= 0,
	.delay_lsb_offset	= 2,
	.delay_msb_offset	= 3,
	.invertclk_offset	= 4,
	.retime_offset		= 5,
	.clknotdata_offset	= 6,
	.double_edge_offset	= 7,
};

unsigned int stih415_input_delays[] = {0, 500, 1000, 1500};
unsigned int stih415_output_delays[] = {0, 1000, 2000, 3000};

static const struct stixxxx_pctl_data  stih415_sbc_data = {
	.rt_style 	= stixxxx_retime_style_packed,
	.rt_offset 	= &stih415_retime_offset,
	.input_delays 	= stih415_input_delays,
	.ninput_delays	= 4,
	.output_delays = stih415_output_delays,
	.noutput_delays = 4,
	.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 16,
};
static struct of_device_id stixxxx_pctl_of_match[] = {
	{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data },
	};

> 
>> +static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
>> +                       struct device_node *np)
>> +{
>> +       struct stixxxx_pio_control *pc;
>> +       struct stixxxx_retime_params *rt_params;
>> +       struct device *dev = info->dev;
>> +       struct regmap *regmap;
>> +       unsigned int i = 0;
>> +       struct device_node *child = NULL;
>> +       u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
>> +       u32 syscfg_offsets[5];
>> +       u32 msb, lsb;
>> +
>> +       pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
>> +       rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
>> +
>> +       if (!pc || !rt_params)
>> +               return -ENOMEM;
>> +
>> +       regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
>> +       if (!regmap) {
>> +               dev_err(dev, "No syscfg phandle specified\n");
>> +               return -ENOMEM;
>> +       }
>> +       info->regmap = regmap;
>> +       info->pio_controls = pc;
>> +       if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
>> +               return -ENOMEM;
>> +
>> +       if (of_property_read_u32_array(np, "st,syscfg-offsets",
>> +                               syscfg_offsets, 5)) {
>> +               dev_err(dev, "Syscfg offsets not found\n");
>> +               return -EINVAL;
>> +       }
>> +       alt_syscfg = syscfg_offsets[0];
>> +       oe_syscfg = syscfg_offsets[1];
>> +       pu_syscfg = syscfg_offsets[2];
>> +       od_syscfg = syscfg_offsets[3];
>> +       rt_syscfg = syscfg_offsets[4];
> 
> This isn't looking any fun either.
> 
> #defining the offsets avoid all this strange boilerplate.
> 
>> +       lsb = 0;
>> +       msb = 7;
> 
> And this.
> 
>> +       for_each_child_of_node(np, child) {
>> +               if (of_device_is_compatible(child, gpio_compat)) {
>> +                       struct reg_field alt_reg =
>> +                                       REG_FIELD(4 * alt_syscfg++, 0, 31);
>> +                       struct reg_field oe_reg =
>> +                                       REG_FIELD(4 * oe_syscfg, lsb, msb);
>> +                       struct reg_field pu_reg =
>> +                                       REG_FIELD(4 * pu_syscfg, lsb, msb);
>> +                       struct reg_field od_reg =
>> +                                       REG_FIELD(4 * od_syscfg, lsb, msb);
>> +                       pc[i].rt_params = rt_params;
>> +
>> +                       pc[i].alt = devm_regmap_field_alloc(dev,
>> +                                                       regmap, alt_reg);
>> +                       pc[i].oe = devm_regmap_field_alloc(dev,
>> +                                                       regmap, oe_reg);
>> +                       pc[i].pu = devm_regmap_field_alloc(dev,
>> +                                                       regmap, pu_reg);
>> +                       pc[i].od = devm_regmap_field_alloc(dev,
>> +                                                       regmap, od_reg);
>> +
>> +                       if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
>> +                               || IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
>> +                               goto failed;
>> +
>> +                       of_property_read_u32(child, "st,retime-pin-mask",
>> +                                               &pc[i].rt_pin_mask);
>> +
>> +                       stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
>> +                                                       &rt_syscfg);
>> +                       i++;
>> +                       if (msb  == 31) {
>> +                               oe_syscfg++;
>> +                               pu_syscfg++;
>> +                               od_syscfg++;
>> +                               lsb = 0;
>> +                               msb = 7;
>> +                       } else {
>> +                               lsb += 8;
>> +                               msb += 8;
>> +                       }
> 
> Can you explain with a comment what is happening here.

Most of this code disappeared as part of merging gpio and pinctrl
platformdriver in to one.
However I will make sure I add more comments in this area.

> 
>> +static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
>> +{
>> +       int i;
>> +       for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
>> +               if (gpio_ports[i]->of_node == np)
>> +                       return &gpio_ports[i]->range;
>> +
>> +       return NULL;
>> +}
> 
> This looks a bit like it's duplicating pinctrl_find_gpio_range_from_pin()
> or similar already available from the pinctrl core. But it seems you
> may need it here in this case.
You are right, I should have used pinctrl_find_gpio_range_from_pin.

This code disappeared too as part of  merging gpio and pinctrl platform
driver in to one.


> 
>> +static int stixxxx_pctl_probe(struct platform_device *pdev)
> (...)
>> +static int stixxxx_gpio_probe(struct platform_device *pdev)
> (...)
>> +static struct of_device_id stixxxx_gpio_of_match[] = {
>> +       { .compatible = "st,stixxxx-gpio", },
>> +       { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver stixxxx_gpio_driver = {
>> +       .driver = {
>> +               .name = "st-gpio",
>> +               .owner = THIS_MODULE,
>> +               .of_match_table = of_match_ptr(stixxxx_gpio_of_match),
>> +       },
>> +       .probe = stixxxx_gpio_probe,
>> +};
>> +
>> +static struct of_device_id stixxxx_pctl_of_match[] = {
>> +       { .compatible = "st,stixxxx-pinctrl",},
>> +       { .compatible = "st,stih415-pinctrl",},
>> +       { .compatible = "st,stih416-pinctrl",},
>> +       { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver stixxxx_pctl_driver = {
>> +       .driver = {
>> +               .name = "st-pinctrl",
>> +               .owner = THIS_MODULE,
>> +               .of_match_table = of_match_ptr(stixxxx_pctl_of_match),
>> +       },
>> +       .probe = stixxxx_pctl_probe,
>> +};
> 
> 
> Why do you need separate nodes and probe functions for the
> pinctrl and GPIO? Can't you just have a single pinctrl node?
> 
>> +static int __init stixxxx_pctl_init(void)
>> +{
>> +       int ret = platform_driver_register(&stixxxx_gpio_driver);
>> +       if (ret)
>> +               return ret;
>> +       return platform_driver_register(&stixxxx_pctl_driver);
>> +}
> 
> Especially since you're just registering them after each other.
> 
> Maybe you could have the GPIO nodes as children inside  the
> pinctrl node and iterate over with for_each_child_of_node()?
> 
> I'm not requiring you rewrite this, just that you give it a thought.

Arnd suggested the same thing, and I have already done this change and
it did clean up lot of code and device tree too.
Now the device tree for pinctrl looks much simple.

	pin-controller-sbc {
			#address-cells	= <1>;
			#size-cells	= <1>;
			compatible	= "st,stih415-sbc-pinctrl";
			st,syscfg	= <&syscfg_sbc>;
			ranges 		= <0 0xfe610000 0x5000>;

			PIO0: gpio@fe610000 {
				gpio-controller;
				#gpio-cells	= <1>;
				reg		= <0 0x100>;
				st,bank-name	= "PIO0";
			};

			...
	};


> 
> (...)
>> +++ b/drivers/pinctrl/pinctrl-stixxxx.h
>> @@ -0,0 +1,197 @@
>> +
>> +/*
>> + * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
>> + * Authors:
>> + *     Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + */
>> +
>> +#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
>> +#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
>> +
>> +enum stixxxx_retime_style {
>> +       stixxxx_retime_style_none,
>> +       stixxxx_retime_style_packed,
>> +       stixxxx_retime_style_dedicated,
>> +};
>> +
>> +/* Byte positions in 2 syscon words, starts from 0 */
>> +struct stixxxx_retime_offset {
>> +       int retime_offset;
>> +       int clk1notclk0_offset;
>> +       int clknotdata_offset;
>> +       int double_edge_offset;
>> +       int invertclk_offset;
>> +       int delay_lsb_offset;
>> +       int delay_msb_offset;
>> +};
>> +
>> +struct stixxxx_retime_params {
>> +       const struct stixxxx_retime_offset *retime_offset;
>> +       unsigned int *delay_times_in;
>> +       int num_delay_times_in;
>> +       unsigned int *delay_times_out;
>> +       int num_delay_times_out;
>> +};
>> +
>> +struct stixxxx_pio_control {
>> +       enum stixxxx_retime_style rt_style;
>> +       u32 rt_pin_mask;
>> +       const struct stixxxx_retime_params *rt_params;
>> +       struct regmap_field *alt;
>> +       struct regmap_field *oe, *pu, *od;
>> +       struct regmap_field *retiming[8];
>> +};
> 
> Are these used outside of the driver? If not, move it into the
> driver .c file.

Yes, I will move this to driver.
> 
>
> 
>> +#define STIXXXX_GPIO_PINS_PER_PORT     8
> 
> 
> Does *any* of this have to be in the header file? If not, move it
> into the driver instead, so the reader don't have to shift between several
> files when reading the driver code.
> 
>> +#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
>> +#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)
> 
> Move these three #defines into the driver and convert the
> two last ones to static inlines instead. Easier to maintain.

Ok, I will do it.

>> +#define STIXXXX_PINCONF_UNPACK(conf, param)\
>> +                               ((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
>> +                               & STIXXXX_PINCONF_ ##param ##_MASK)
>> +
>> +#define STIXXXX_PINCONF_PACK(conf, val, param) (conf |=\
>> +                               ((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
>> +                                       STIXXXX_PINCONF_ ##param ##_SHIFT))
>> +
>> +/* Output enable */
>> +#define STIXXXX_PINCONF_OE_MASK                0x1
>> +#define STIXXXX_PINCONF_OE_SHIFT       27
>> +#define STIXXXX_PINCONF_OE             BIT(27)
>> +#define STIXXXX_PINCONF_UNPACK_OE(conf)        STIXXXX_PINCONF_UNPACK(conf, OE)
>> +#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)
> 
> For all of these macros: why are you suppying an argument that can only
> be 0 or 1?
> 
> Just alter PACK like this:
> 
> #define STIXXXX_PINCONF_PACK_OE(conf)  STIXXXX_PINCONF_PACK(conf, 1, OE)
> 
> And only call it if you want to enable the feature, else avoid calling it.
> There is no point of setting bits to zero with so much adoo.
> 
> 
Yes, I will try this and see how it will look like.

>> +/* RETIME_DELAY in Pico Secs */
>> +#define STIXXXX_PINCONF_RT_DELAY_MASK          0xffff
>> +#define STIXXXX_PINCONF_RT_DELAY_SHIFT         0
>> +#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
>> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
>> +#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
>> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)
> 
> But here you need the special packed val to be passed,
> so this looks good.
> 
>> +#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */
> 
> Move the entire header into the drivers main .c file. Why complicate things?
yes, I will move the full header contents to c file.

Thanks,
srini
> 
> Yours,
> Linus Walleij
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
@ 2013-06-17 13:31           ` Srinivas KANDAGATLA
  0 siblings, 0 replies; 716+ messages in thread
From: Srinivas KANDAGATLA @ 2013-06-17 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

Thankyou very much for the comments.

On 16/06/13 13:17, Linus Walleij wrote:
> On Mon, Jun 10, 2013 at 11:22 AM, Srinivas KANDAGATLA
> <srinivas.kandagatla@st.com> wrote:
> 
>> About driver:
>> This pinctrl driver manages both PIO and PIO-mux block using pinctrl,
>> pinconf, pinmux, gpio subsystems. All the pinctrl related config
>> information can only come from device trees.
> 
> OK that's a good approach!
Thankyou
>> +- #gpio-cells    : Should be one. The first cell is the pin number.
>> +- st,retime-in-delay   : Should be array of delays in nsecs.
>> +- st,retime-out-delay  : Should be array of delays in nsecs.
> 
> Please explain more verbosely what is meant by these
> delays. in-delay of what? out-delay of what?
> 

Am moving this to the driver too, as these tend to be constant per given
SOC.

>> +- st,retime-pin-mask   : Should be mask to specify which pins can be retimed.
> 
> Explain what this "retimed" means.
I will explain this bit in more detail.

> 
>> +- st,bank-name         : Should be a name string for this bank.
> 
> Usually we only use an identifier, like a number for this, but
> maybe you need this, so won't judge on it.

It's used for maintaining consistency with pin names from data sheet to
the pinctrl_pin_desc.

> 
>> +- st,syscfg            : phandle of the syscfg node.
> 
> This is pretty clever.
Thankyou.
> 
>> +- st,syscfg-offsets    : Should be a 5 cell entry which represent offset of altfunc,
>> +       output-enable, pull-up , open drain and retime registers in the syscfg bank
> 
> No please. Use the compatible string to determine which version of the
> hardware this is and encode a register offset table into the driver instead.
> We do not store register offsets in the device tree, it is not a datasheet
> XML container you know...

Got it, I already moved this to the driver now. And its looking good.

> 
>> +- delay        is retime delay in pico seconds.
>> +               Possible values are: refer to retime-in/out-delays
> 
> Earlier it was given in nanoseconds.
> 
 I will fix this.

> And I still have no clue what "retiming" means.
> 
> I'm suspecting you cannot actually use generic pinconfig
> due to all this retiming esoterica but atleast give it a thought.
> 
>> +- rt_clk       :clk to be use for retime.
>> +               Possible values are:
>> +               CLK_A
>> +               CLK_B
>> +               CLK_C
>> +               CLK_D
> 
> So this is selecting one of four available clock lines?
> 
No, It's not related to driver clocks.
It's to do with the retiming. This part configures which clock to retime
output/input data to. CLK_A means retime output data to clkout[0] and
input data on clkin[0].

Will add more documentation on re-timing in general.


> Should this not interact with some clk bindings for your
> clock tree?
> 
>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>> index 8f66924..0c040a3 100644
>> --- a/drivers/pinctrl/Kconfig
>> +++ b/drivers/pinctrl/Kconfig
>> @@ -169,6 +169,17 @@ config PINCTRL_SUNXI
>>         select PINMUX
>>         select GENERIC_PINCONF
>>
>> +config PINCTRL_STIXXXX
> 
> As mentioned elsewhere STIXXXX is a bit too much X:es in.
> Please come up with some better naming if possible.

Are you OK if I use pinctrl-st.c?

> 
>> +       bool "ST Microelectronics pin controller driver for STixxxx SoCs"
> 
> Add:
> depends on OF

Ok, Will add it.
> 
>> +       select PINMUX
>> +       select PINCONF
>> +       help
>> +         Say yes here to support pinctrl interface on STixxxx SOCs.
>> +         This driver is used to control both PIO block and PIO-mux
>> +         block to configure a pin.
>> +
>> +         If unsure, say N.
> 
> (...)
>> +++ b/drivers/pinctrl/pinctrl-stixxxx.c

>> +struct stixxxx_gpio_port {
>> +       struct gpio_chip        gpio_chip;
>> +       struct pinctrl_gpio_range range;
>> +       void __iomem            *base;
>> +       struct device_node      *of_node;
> 
> Why do you need this? The struct gpio_chip above can contain
> the of_node can it not?

I remove the of_node as part of "simple-bus" cleanup from the pinctrl node.

> 
>> +       const char              *bank_name;
>> +};
> 
>> +static struct stixxxx_gpio_port *gpio_ports[STIXXXX_MAX_GPIO_BANKS];
> 
> This is complicating things. Can't you just store the array of GPIO ports
> *inside* the struct stixxxx_pinctrl container or something?

Already taken care from previous comment.

> 
> (...)
>> +/* Low level functions.. */
>> +static void stixxxx_pinconf_set_direction(struct stixxxx_pio_control *pc,
>> +                               int pin_id, unsigned long config)
> 
> Why is this function called "*_set_direction" when it is also
> messing with PU and OD?
> 
> _set_config would be more appropriate.

Yes, I will rename it.
> 
> (The code looks fine.)
> 
> (...)
>> +static void stixxxx_pinconf_set_retime_packed(
>> +               struct stixxxx_pio_control *pc,
>> +               unsigned long config, int pin)
>> +{
>> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
>> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
>> +       struct regmap_field **regs;
>> +       unsigned int values[2];
>> +       unsigned long mask;
>> +       int i, j;
>> +       int clk = STIXXXX_PINCONF_UNPACK_RT_CLK(config);
>> +       int clknotdata = STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config);
>> +       int double_edge = STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
>> +       int invertclk = STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config);
>> +       int retime = STIXXXX_PINCONF_UNPACK_RT(config);
>> +       unsigned long delay = stixxxx_pinconf_delay_to_bit(
>> +                       STIXXXX_PINCONF_UNPACK_RT_DELAY(config),
>> +                       pc->rt_params, config);
> 
> As you can see it's a bit excess of "X" above. Hard to read.
> 
> Then it seems like some of these should be bool, because:

Ok, Will make it bool.

> 
>> +       unsigned long rt_cfg =
>> +               ((clk           & 1) << offset->clk1notclk0_offset) |
>> +               ((clknotdata    & 1) << offset->clknotdata_offset) |
>> +               ((delay         & 1) << offset->delay_lsb_offset) |
>> +               (((delay >> 1)  & 1) << offset->delay_msb_offset) |
>> +               ((double_edge   & 1) << offset->double_edge_offset) |
>> +               ((invertclk     & 1) << offset->invertclk_offset) |
>> +               ((retime        & 1) << offset->retime_offset);
> 
> This is looking strange. Just strange.
> Comments are needed I think. For example why
> arey >> 1 on delay all of a sudden?
> 
> I would try to make clk, clknotdata, delay etc into bools.
> 
> Then it could be more readable like this:
> 
> #include <linux/bitops.h>
> 
> unsigned long rt_cfg = 0;
> 
> if (clk)
>     rt_cfg |= BIT(offset->clk1notclk0_offset);
> if (clknotdata)
>     rt_cfg |= BIT(offset->clknotdata_offset);
> 
> etc.

Yes, Looks sensible, I will try these changes and see how it turns up.

> 
>> +       regs = pc->retiming;
>> +       regmap_field_read(regs[0], &values[0]);
>> +       regmap_field_read(regs[1], &values[1]);
>> +
>> +       for (i = 0; i < 2; i++) {
>> +               mask = BIT(pin);
>> +               for (j = 0; j < 4; j++) {
>> +                       if (rt_cfg & 1)
>> +                               values[i] |= mask;
>> +                       else
>> +                               values[i] &= ~mask;
>> +                       mask <<= 8;
>> +                       rt_cfg >>= 1;
>> +               }
>> +       }
> 
> 2? 4? 8? Not quite readable with so many magic constants.
> Is this "8" identical to STIXXXX_GPIO_PINS_PER_PORT?
> 
I agree, all these constants should be #defined in a readable way, and I
will do it. (for all the comments related to constants ...)

> 
>> +static int stixxxx_pinconf_get_retime_packed(
>> +               struct stixxxx_pio_control *pc,
>> +               int pin, unsigned long *config)
>> +{
>> +       const struct stixxxx_retime_params *rt_params = pc->rt_params;
>> +       const struct stixxxx_retime_offset *offset = rt_params->retime_offset;
>> +       unsigned long delay_bits, delay, rt_reduced;
>> +       unsigned int rt_value[2];
>> +       int i, j;
>> +       int output = STIXXXX_PINCONF_UNPACK_OE(*config);
>> +
>> +       regmap_field_read(pc->retiming[0], &rt_value[0]);
>> +       regmap_field_read(pc->retiming[1], &rt_value[1]);
>> +
>> +       rt_reduced = 0;
>> +       for (i = 0; i < 2; i++) {
>> +               for (j = 0; j < 4; j++) {
>> +                       if (rt_value[i] & (1<<((8*j)+pin)))
>> +                               rt_reduced |= 1 << ((i*4)+j);
>> +               }
>> +       }
> 
> Urgh 2, 4, 8??
> 
> What is happening here ... atleast a big comment
> explaining the logic would be helpful. Some kind of
> matrix traversal seem to be involved.

Yes, I will add a decent comment here.

> 
>> +       STIXXXX_PINCONF_PACK_RT(*config,
>> +                       (rt_reduced >> offset->retime_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_CLK(*config,
>> +                       (rt_reduced >> offset->clk1notclk0_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_CLKNOTDATA(*config,
>> +                       (rt_reduced >> offset->clknotdata_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_DOUBLE_EDGE(*config,
>> +                       (rt_reduced >> offset->double_edge_offset) & 1);
>> +       STIXXXX_PINCONF_PACK_RT_INVERTCLK(*config,
>> +                       (rt_reduced >> offset->invertclk_offset) & 1);
> 
> I would rewrite this like
> 
> if ((rt_reduced >> offset->retime_offset) & 1)
>    STIXXXX_PINCONF_PACK_RT(*config, 1);
> 
> See further comments on these macros below.
> 
> I prefer if they are only used to set bits to 1, then it just becomes:
> 
> if ((rt_reduced >> offset->retime_offset) & 1)
>    STIXXXX_PINCONF_PACK_RT(*config);
> 
> Simpler.

I will do it.
> 
> 
> (...)
>> +static void stixxxx_gpio_direction(unsigned int gpio, unsigned int direction)
>> +{
>> +       int port_num = stixxxx_gpio_port(gpio);
>> +       int offset = stixxxx_gpio_pin(gpio);
>> +       struct stixxxx_gpio_port *port  = gpio_ports[port_num];
>> +       int i = 0;
>> +
>> +       for (i = 0; i <= 2; i++) {
>> +               if (direction & BIT(i))
>> +                       writel(BIT(offset), port->base + REG_PIO_SET_PC(i));
>> +               else
>> +                       writel(BIT(offset), port->base + REG_PIO_CLR_PC(i));
>> +       }
> 
> Can you explain here in a comment why the loop has to hit
> bits 0, 1 and 2 in this register?

Yes, I will add the comments behind the logic of this.

> 
> (...)
>> +static int stixxxx_gpio_get(struct gpio_chip *chip, unsigned offset)
>> +{
>> +       struct stixxxx_gpio_port *port = to_stixxxx_gpio_port(chip);
>> +
>> +       return (readl(port->base + REG_PIO_PIN) >> offset) & 1;
> 
> Usually we do this with the double-bang idiom:
> 
> return !!(readl(port->base + REG_PIO_PIN) & BIT(offset));

Interesting and very neat.

> 
>> +static void stixxxx_pctl_dt_free_map(struct pinctrl_dev *pctldev,
>> +                               struct pinctrl_map *map, unsigned num_maps)
>> +{
>> +}
> 
> Isn't this optional? And don't you need to free this?
> 
Its not optional because pinctrl_check_ops returns -EINVAL if set to NULL.

I don't need to free it because its a devm_kzalloc.

> (...)
>> +static void stixxxx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
>> +                                  struct seq_file *s, unsigned pin_id)
>> +{
>> +       unsigned long config;
>> +       stixxxx_pinconf_get(pctldev, pin_id, &config);
>> +
>> +       seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
>> +               "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
>> +               "de:%ld,rt-clk:%ld,rt-delay:%ld]",
>> +               STIXXXX_PINCONF_UNPACK_OE(config),
>> +               STIXXXX_PINCONF_UNPACK_PU(config),
>> +               STIXXXX_PINCONF_UNPACK_OD(config),
>> +               STIXXXX_PINCONF_UNPACK_RT(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_INVERTCLK(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_CLKNOTDATA(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_CLK(config),
>> +               STIXXXX_PINCONF_UNPACK_RT_DELAY(config));
>> +}
> 
> This looks real nice, but is the output human-friendly?

I will see, If I can come up with a better format.

> Well maybe the format needs to be compact like this...
> 
>> +       if (of_device_is_compatible(np, "st,stih415-pinctrl")) {
>> +               rt_offset = devm_kzalloc(info->dev,
>> +                       sizeof(*rt_offset), GFP_KERNEL);
>> +
>> +               if (!rt_offset)
>> +                       return -ENOMEM;
>> +
>> +               rt_offset->clk1notclk0_offset = 0;
>> +               rt_offset->delay_lsb_offset = 2;
>> +               rt_offset->delay_msb_offset = 3;
>> +               rt_offset->invertclk_offset = 4;
>> +               rt_offset->retime_offset = 5;
>> +               rt_offset->clknotdata_offset = 6;
>> +               rt_offset->double_edge_offset = 7;
> 
> This looks awkward and complicated.
> 
> Why not just #define these offsets and use them
> directly in the code?

This is more specific to a SOC.
This information now comes as part of the SOC specific compatible node data.

Like this:

const struct stixxxx_retime_offset stih415_retime_offset = {
	.clk1notclk0_offset	= 0,
	.delay_lsb_offset	= 2,
	.delay_msb_offset	= 3,
	.invertclk_offset	= 4,
	.retime_offset		= 5,
	.clknotdata_offset	= 6,
	.double_edge_offset	= 7,
};

unsigned int stih415_input_delays[] = {0, 500, 1000, 1500};
unsigned int stih415_output_delays[] = {0, 1000, 2000, 3000};

static const struct stixxxx_pctl_data  stih415_sbc_data = {
	.rt_style 	= stixxxx_retime_style_packed,
	.rt_offset 	= &stih415_retime_offset,
	.input_delays 	= stih415_input_delays,
	.ninput_delays	= 4,
	.output_delays = stih415_output_delays,
	.noutput_delays = 4,
	.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 16,
};
static struct of_device_id stixxxx_pctl_of_match[] = {
	{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data },
	};

> 
>> +static int stixxxx_pctl_dt_init(struct stixxxx_pinctrl *info,
>> +                       struct device_node *np)
>> +{
>> +       struct stixxxx_pio_control *pc;
>> +       struct stixxxx_retime_params *rt_params;
>> +       struct device *dev = info->dev;
>> +       struct regmap *regmap;
>> +       unsigned int i = 0;
>> +       struct device_node *child = NULL;
>> +       u32 alt_syscfg, oe_syscfg, pu_syscfg, od_syscfg, rt_syscfg;
>> +       u32 syscfg_offsets[5];
>> +       u32 msb, lsb;
>> +
>> +       pc = devm_kzalloc(dev, sizeof(*pc) * info->nbanks, GFP_KERNEL);
>> +       rt_params = devm_kzalloc(dev, sizeof(*rt_params), GFP_KERNEL);
>> +
>> +       if (!pc || !rt_params)
>> +               return -ENOMEM;
>> +
>> +       regmap = syscfg_regmap_lookup_by_phandle(np, "st,syscfg");
>> +       if (!regmap) {
>> +               dev_err(dev, "No syscfg phandle specified\n");
>> +               return -ENOMEM;
>> +       }
>> +       info->regmap = regmap;
>> +       info->pio_controls = pc;
>> +       if (stixxxx_pinconf_dt_parse_rt_params(info, np, rt_params))
>> +               return -ENOMEM;
>> +
>> +       if (of_property_read_u32_array(np, "st,syscfg-offsets",
>> +                               syscfg_offsets, 5)) {
>> +               dev_err(dev, "Syscfg offsets not found\n");
>> +               return -EINVAL;
>> +       }
>> +       alt_syscfg = syscfg_offsets[0];
>> +       oe_syscfg = syscfg_offsets[1];
>> +       pu_syscfg = syscfg_offsets[2];
>> +       od_syscfg = syscfg_offsets[3];
>> +       rt_syscfg = syscfg_offsets[4];
> 
> This isn't looking any fun either.
> 
> #defining the offsets avoid all this strange boilerplate.
> 
>> +       lsb = 0;
>> +       msb = 7;
> 
> And this.
> 
>> +       for_each_child_of_node(np, child) {
>> +               if (of_device_is_compatible(child, gpio_compat)) {
>> +                       struct reg_field alt_reg =
>> +                                       REG_FIELD(4 * alt_syscfg++, 0, 31);
>> +                       struct reg_field oe_reg =
>> +                                       REG_FIELD(4 * oe_syscfg, lsb, msb);
>> +                       struct reg_field pu_reg =
>> +                                       REG_FIELD(4 * pu_syscfg, lsb, msb);
>> +                       struct reg_field od_reg =
>> +                                       REG_FIELD(4 * od_syscfg, lsb, msb);
>> +                       pc[i].rt_params = rt_params;
>> +
>> +                       pc[i].alt = devm_regmap_field_alloc(dev,
>> +                                                       regmap, alt_reg);
>> +                       pc[i].oe = devm_regmap_field_alloc(dev,
>> +                                                       regmap, oe_reg);
>> +                       pc[i].pu = devm_regmap_field_alloc(dev,
>> +                                                       regmap, pu_reg);
>> +                       pc[i].od = devm_regmap_field_alloc(dev,
>> +                                                       regmap, od_reg);
>> +
>> +                       if (IS_ERR(pc[i].alt) || IS_ERR(pc[i].oe)
>> +                               || IS_ERR(pc[i].pu) || IS_ERR(pc[i].od))
>> +                               goto failed;
>> +
>> +                       of_property_read_u32(child, "st,retime-pin-mask",
>> +                                               &pc[i].rt_pin_mask);
>> +
>> +                       stixxxx_pctl_dt_get_retime_conf(info, &pc[i],
>> +                                                       &rt_syscfg);
>> +                       i++;
>> +                       if (msb  == 31) {
>> +                               oe_syscfg++;
>> +                               pu_syscfg++;
>> +                               od_syscfg++;
>> +                               lsb = 0;
>> +                               msb = 7;
>> +                       } else {
>> +                               lsb += 8;
>> +                               msb += 8;
>> +                       }
> 
> Can you explain with a comment what is happening here.

Most of this code disappeared as part of merging gpio and pinctrl
platformdriver in to one.
However I will make sure I add more comments in this area.

> 
>> +static struct pinctrl_gpio_range *find_gpio_range(struct device_node *np)
>> +{
>> +       int i;
>> +       for (i = 0; i < STIXXXX_MAX_GPIO_BANKS; i++)
>> +               if (gpio_ports[i]->of_node == np)
>> +                       return &gpio_ports[i]->range;
>> +
>> +       return NULL;
>> +}
> 
> This looks a bit like it's duplicating pinctrl_find_gpio_range_from_pin()
> or similar already available from the pinctrl core. But it seems you
> may need it here in this case.
You are right, I should have used pinctrl_find_gpio_range_from_pin.

This code disappeared too as part of  merging gpio and pinctrl platform
driver in to one.


> 
>> +static int stixxxx_pctl_probe(struct platform_device *pdev)
> (...)
>> +static int stixxxx_gpio_probe(struct platform_device *pdev)
> (...)
>> +static struct of_device_id stixxxx_gpio_of_match[] = {
>> +       { .compatible = "st,stixxxx-gpio", },
>> +       { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver stixxxx_gpio_driver = {
>> +       .driver = {
>> +               .name = "st-gpio",
>> +               .owner = THIS_MODULE,
>> +               .of_match_table = of_match_ptr(stixxxx_gpio_of_match),
>> +       },
>> +       .probe = stixxxx_gpio_probe,
>> +};
>> +
>> +static struct of_device_id stixxxx_pctl_of_match[] = {
>> +       { .compatible = "st,stixxxx-pinctrl",},
>> +       { .compatible = "st,stih415-pinctrl",},
>> +       { .compatible = "st,stih416-pinctrl",},
>> +       { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver stixxxx_pctl_driver = {
>> +       .driver = {
>> +               .name = "st-pinctrl",
>> +               .owner = THIS_MODULE,
>> +               .of_match_table = of_match_ptr(stixxxx_pctl_of_match),
>> +       },
>> +       .probe = stixxxx_pctl_probe,
>> +};
> 
> 
> Why do you need separate nodes and probe functions for the
> pinctrl and GPIO? Can't you just have a single pinctrl node?
> 
>> +static int __init stixxxx_pctl_init(void)
>> +{
>> +       int ret = platform_driver_register(&stixxxx_gpio_driver);
>> +       if (ret)
>> +               return ret;
>> +       return platform_driver_register(&stixxxx_pctl_driver);
>> +}
> 
> Especially since you're just registering them after each other.
> 
> Maybe you could have the GPIO nodes as children inside  the
> pinctrl node and iterate over with for_each_child_of_node()?
> 
> I'm not requiring you rewrite this, just that you give it a thought.

Arnd suggested the same thing, and I have already done this change and
it did clean up lot of code and device tree too.
Now the device tree for pinctrl looks much simple.

	pin-controller-sbc {
			#address-cells	= <1>;
			#size-cells	= <1>;
			compatible	= "st,stih415-sbc-pinctrl";
			st,syscfg	= <&syscfg_sbc>;
			ranges 		= <0 0xfe610000 0x5000>;

			PIO0: gpio at fe610000 {
				gpio-controller;
				#gpio-cells	= <1>;
				reg		= <0 0x100>;
				st,bank-name	= "PIO0";
			};

			...
	};


> 
> (...)
>> +++ b/drivers/pinctrl/pinctrl-stixxxx.h
>> @@ -0,0 +1,197 @@
>> +
>> +/*
>> + * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
>> + * Authors:
>> + *     Srinivas Kandagatla <srinivas.kandagatla@st.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + */
>> +
>> +#ifndef __LINUX_DRIVERS_PINCTRL_STIXXXX_H
>> +#define __LINUX_DRIVERS_PINCTRL_STIXXXX_H
>> +
>> +enum stixxxx_retime_style {
>> +       stixxxx_retime_style_none,
>> +       stixxxx_retime_style_packed,
>> +       stixxxx_retime_style_dedicated,
>> +};
>> +
>> +/* Byte positions in 2 syscon words, starts from 0 */
>> +struct stixxxx_retime_offset {
>> +       int retime_offset;
>> +       int clk1notclk0_offset;
>> +       int clknotdata_offset;
>> +       int double_edge_offset;
>> +       int invertclk_offset;
>> +       int delay_lsb_offset;
>> +       int delay_msb_offset;
>> +};
>> +
>> +struct stixxxx_retime_params {
>> +       const struct stixxxx_retime_offset *retime_offset;
>> +       unsigned int *delay_times_in;
>> +       int num_delay_times_in;
>> +       unsigned int *delay_times_out;
>> +       int num_delay_times_out;
>> +};
>> +
>> +struct stixxxx_pio_control {
>> +       enum stixxxx_retime_style rt_style;
>> +       u32 rt_pin_mask;
>> +       const struct stixxxx_retime_params *rt_params;
>> +       struct regmap_field *alt;
>> +       struct regmap_field *oe, *pu, *od;
>> +       struct regmap_field *retiming[8];
>> +};
> 
> Are these used outside of the driver? If not, move it into the
> driver .c file.

Yes, I will move this to driver.
> 
>
> 
>> +#define STIXXXX_GPIO_PINS_PER_PORT     8
> 
> 
> Does *any* of this have to be in the header file? If not, move it
> into the driver instead, so the reader don't have to shift between several
> files when reading the driver code.
> 
>> +#define stixxxx_gpio_port(gpio) ((gpio) / STIXXXX_GPIO_PINS_PER_PORT)
>> +#define stixxxx_gpio_pin(gpio) ((gpio) % STIXXXX_GPIO_PINS_PER_PORT)
> 
> Move these three #defines into the driver and convert the
> two last ones to static inlines instead. Easier to maintain.

Ok, I will do it.

>> +#define STIXXXX_PINCONF_UNPACK(conf, param)\
>> +                               ((conf >> STIXXXX_PINCONF_ ##param ##_SHIFT) \
>> +                               & STIXXXX_PINCONF_ ##param ##_MASK)
>> +
>> +#define STIXXXX_PINCONF_PACK(conf, val, param) (conf |=\
>> +                               ((val & STIXXXX_PINCONF_ ##param ##_MASK) << \
>> +                                       STIXXXX_PINCONF_ ##param ##_SHIFT))
>> +
>> +/* Output enable */
>> +#define STIXXXX_PINCONF_OE_MASK                0x1
>> +#define STIXXXX_PINCONF_OE_SHIFT       27
>> +#define STIXXXX_PINCONF_OE             BIT(27)
>> +#define STIXXXX_PINCONF_UNPACK_OE(conf)        STIXXXX_PINCONF_UNPACK(conf, OE)
>> +#define STIXXXX_PINCONF_PACK_OE(conf, val)  STIXXXX_PINCONF_PACK(conf, val, OE)
> 
> For all of these macros: why are you suppying an argument that can only
> be 0 or 1?
> 
> Just alter PACK like this:
> 
> #define STIXXXX_PINCONF_PACK_OE(conf)  STIXXXX_PINCONF_PACK(conf, 1, OE)
> 
> And only call it if you want to enable the feature, else avoid calling it.
> There is no point of setting bits to zero with so much adoo.
> 
> 
Yes, I will try this and see how it will look like.

>> +/* RETIME_DELAY in Pico Secs */
>> +#define STIXXXX_PINCONF_RT_DELAY_MASK          0xffff
>> +#define STIXXXX_PINCONF_RT_DELAY_SHIFT         0
>> +#define STIXXXX_PINCONF_UNPACK_RT_DELAY(conf) \
>> +                               STIXXXX_PINCONF_UNPACK(conf, RT_DELAY)
>> +#define STIXXXX_PINCONF_PACK_RT_DELAY(conf, val) \
>> +                               STIXXXX_PINCONF_PACK(conf, val, RT_DELAY)
> 
> But here you need the special packed val to be passed,
> so this looks good.
> 
>> +#endif /* __LINUX_DRIVERS_PINCTRL_STIXXXX_H */
> 
> Move the entire header into the drivers main .c file. Why complicate things?
yes, I will move the full header contents to c file.

Thanks,
srini
> 
> Yours,
> Linus Walleij
> 
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
  2013-06-17 13:31           ` Srinivas KANDAGATLA
@ 2013-06-17 16:27               ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-17 16:27 UTC (permalink / raw)
  To: Srinivas KANDAGATLA
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On Mon, Jun 17, 2013 at 3:31 PM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:

>>> +config PINCTRL_STIXXXX
>>
>> As mentioned elsewhere STIXXXX is a bit too much X:es in.
>> Please come up with some better naming if possible.
>
> Are you OK if I use pinctrl-st.c?

It seems to no be taken so OK :-)

The best choice is just the name of the IP block,
something unique. I would consider trying to ask the
hardware engineer writing that pinctrl block what name
s/he prefer on it, if not possible just go with pinctrl-st.c.

The rest seems to be addressed nicely, waiting for the
next iteration!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support.
@ 2013-06-17 16:27               ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-17 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 17, 2013 at 3:31 PM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:

>>> +config PINCTRL_STIXXXX
>>
>> As mentioned elsewhere STIXXXX is a bit too much X:es in.
>> Please come up with some better naming if possible.
>
> Are you OK if I use pinctrl-st.c?

It seems to no be taken so OK :-)

The best choice is just the name of the IP block,
something unique. I would consider trying to ask the
hardware engineer writing that pinctrl block what name
s/he prefer on it, if not possible just go with pinctrl-st.c.

The rest seems to be addressed nicely, waiting for the
next iteration!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
  2013-06-10 13:52       ` Arnd Bergmann
@ 2013-06-19 18:34         ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-19 18:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Mauro Carvalho Chehab, Srinivas KANDAGATLA,
	Russell King - ARM Linux, Samuel Ortiz,
	linux-doc-u79uwXL29TY76Z2rM5mHXA, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton

On Mon, Jun 10, 2013 at 3:52 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
>
>> +     soc {
>> +             pin-controller-sbc {
>> +                     #address-cells  = <1>;
>> +                     #size-cells     = <1>;
>> +                     compatible      = "st,stih416-pinctrl", "simple-bus";
>
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?

I think that in my comments to the pinctrl driver I had some
similar comment, so it's probably a good idea to look into
this.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 07/11] ARM:stixxxx: Add STiH416 SOC support
@ 2013-06-19 18:34         ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-19 18:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 10, 2013 at 3:52 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 10 June 2013 10:27:05 Srinivas KANDAGATLA wrote:
>
>> +     soc {
>> +             pin-controller-sbc {
>> +                     #address-cells  = <1>;
>> +                     #size-cells     = <1>;
>> +                     compatible      = "st,stih416-pinctrl", "simple-bus";
>
> Why is this both its own device with a compatible string and a
> "simple-bus" at the same time? Wouldn't it be simpler to just
> scan the child device nodes from the "st,stih416-pinctrl"
> driver instead of having a separate platform_driver for them?

I think that in my comments to the pinctrl driver I had some
similar comment, so it's probably a good idea to look into
this.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
  2013-06-14  7:31                 ` Srinivas KANDAGATLA
@ 2013-06-19 18:59                     ` Linus Walleij
  -1 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-19 18:59 UTC (permalink / raw)
  To: Srinivas KANDAGATLA, Maxime Ripard
  Cc: Mauro Carvalho Chehab, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	Russell King - ARM Linux, Samuel Ortiz, Stephen Gallimore,
	linux-serial-u79uwXL29TY76Z2rM5mHXA, Grant Likely,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring,
	Stuart Menefy, Mark Brown, John Stultz, Thomas Gleixner,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Greg Kroah-Hartman, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Andrew Morton, David S. Miller

On Fri, Jun 14, 2013 at 9:31 AM, Srinivas KANDAGATLA
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:
> On 10/06/13 17:38, Srinivas Kandagatla wrote:
>>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>>> >> @@ -0,0 +1,94 @@
>>> >> +#ifndef _STIXXXX_PINCFG_H_
>>> >> +#define _STIXXXX_PINCFG_H_
>>> >> +
>>> >> +/* Alternate functions */
>>> >> +#define ALT1   1
>>> >> +#define ALT2   2
>>> >> +#define ALT3   3
>>> >> +#define ALT4   4
>>> >> +#define ALT5   5
>>> >> +#define ALT6   6
>>> >> +#define ALT7   7
>>>
>>> Why is this part of the DT definitions? In the pinctrl world this
>>> is an intrinsic detail on how groups and functions are associated,
>>> not something that you hard-code into the device tree. The
>>> device tree should state how to combine functions with groups
>>> and those will be strings, not numerals.
>
> Hi Linus,
> I would like to get correct understanding of the point your raised here.
> I use these ALT function values in "st,function" property for pinctrl
> group as shown in this simple example:
>
> pinctrl_sbc_serial1:sbc_serial1 {
>        st,function = <ALT3>;
>        st,pins {
>               tx      = <&PIO2 6 OUT>;
>               rx      = <&PIO2 7 IN>;
>        };
> };
>
> If I do something like what rockchip pinctrl did the pinctrl group will
> look like.
>
> pinctrl_sbc_serial1:sbc_serial1 {
>        st,pins {
>               tx      = <&PIO2 6 OUT ALT3>;
>               rx      = <&PIO2 7 IN ALT3>;
>        };
> };
>
> Is this the right way to do it?

Basically there is no right way to do it since we haven't been able
to agree on a common way to represent pin controllers in the
device tree.

Those I have looked closer at tend to encode the selected
function/group as a string rather than a numeral though.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support
@ 2013-06-19 18:59                     ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2013-06-19 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 14, 2013 at 9:31 AM, Srinivas KANDAGATLA
<srinivas.kandagatla@st.com> wrote:
> On 10/06/13 17:38, Srinivas Kandagatla wrote:
>>> +++ b/arch/arm/boot/dts/stixxxx-pincfg.h
>>> >> @@ -0,0 +1,94 @@
>>> >> +#ifndef _STIXXXX_PINCFG_H_
>>> >> +#define _STIXXXX_PINCFG_H_
>>> >> +
>>> >> +/* Alternate functions */
>>> >> +#define ALT1   1
>>> >> +#define ALT2   2
>>> >> +#define ALT3   3
>>> >> +#define ALT4   4
>>> >> +#define ALT5   5
>>> >> +#define ALT6   6
>>> >> +#define ALT7   7
>>>
>>> Why is this part of the DT definitions? In the pinctrl world this
>>> is an intrinsic detail on how groups and functions are associated,
>>> not something that you hard-code into the device tree. The
>>> device tree should state how to combine functions with groups
>>> and those will be strings, not numerals.
>
> Hi Linus,
> I would like to get correct understanding of the point your raised here.
> I use these ALT function values in "st,function" property for pinctrl
> group as shown in this simple example:
>
> pinctrl_sbc_serial1:sbc_serial1 {
>        st,function = <ALT3>;
>        st,pins {
>               tx      = <&PIO2 6 OUT>;
>               rx      = <&PIO2 7 IN>;
>        };
> };
>
> If I do something like what rockchip pinctrl did the pinctrl group will
> look like.
>
> pinctrl_sbc_serial1:sbc_serial1 {
>        st,pins {
>               tx      = <&PIO2 6 OUT ALT3>;
>               rx      = <&PIO2 7 IN ALT3>;
>        };
> };
>
> Is this the right way to do it?

Basically there is no right way to do it since we haven't been able
to agree on a common way to represent pin controllers in the
device tree.

Those I have looked closer at tend to encode the selected
function/group as a string rather than a numeral though.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 0/1] ideas to improve the write performance of cluster dm-raid1
       [not found] <yes>
                   ` (71 preceding siblings ...)
  2013-06-10  9:17   ` Srinivas KANDAGATLA
@ 2013-09-10  9:25 ` dongmao zhang
  2013-09-10  9:25   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
  2013-09-12  8:42 ` [PATCH 1/1] OMAPDSS: Return right error during connector probe Sathya Prakash M R
                   ` (18 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: dongmao zhang @ 2013-09-10  9:25 UTC (permalink / raw)
  To: dm-devel; +Cc: dongmao zhang

Dear list,

Based on my test result, the cluster raid1 writes loss 80% performance. I found
that the most time is occupied by the function userspace_flush.

Usually userspace_flush needs three stages(mark, clear, flush)to communicate with cmirrord.
From the cmirrord's perspective, mark and flush functions run cluster_send first and then return to 
the kernel. And we can ignore the clear request which is fast.

In other words, the requests of mark_region and flush in userspace_flush 
at least require a cluster_send period to finish. this is the root cause
of bad performance.

The idea is to merge flush and mark request together in both cmirrord and dm-log-userspace.

A simple patch for cmirrord could be like this:

--- lvm2-2_02_98.orig/daemons/cmirrord/functions.c
+++ lvm2-2_02_98/daemons/cmirrord/functions.c
@@ -1720,7 +1720,8 @@ int do_request(struct clog_request *rq,
		r = clog_flush(&rq->u_rq, server);
		break;
	case DM_ULOG_MARK_REGION:
-   r = clog_mark_region(&rq->u_rq, rq->originator);
+   if (clog_mark_region(&rq->u_rq, rq->originator) == 0)
+     r = clog_flush(&rq->u_rq, server);
		break;
	case DM_ULOG_CLEAR_REGION:
		r = clog_clear_region(&rq->u_rq, rq->originator);

We run clog_flush directly after clog_mark_region. So the userspace_flush do not 
have to request flush again after requesting mark_region.  Moreover, I think the flush 
of clear region could be delayed. If we have both mark and clear region, only sending 
a mark_region request is OK, because clog_flush will automatically run.(ignore the clean_region 
time). It only takes one cluster_send period. If we have only mark region, 
a mark_region request is also OK, it takes one cluster_send period. If we have only 
clear_region, we could delay the flush of cleared_region for 3 seconds.

Overall, before the patch, mark_region require approximately two cluster_send
period(mark_region and flush), after the patch, mark_region only needs one 
cluster_send period. Based on my test, the performance is as twice as before.

So above are my some ideas to improve the performence. I have not tested it
in some node failure situation. If I am wrong ,please correct me.


dongmao zhang (1):
  improve the performance of dm-log-userspace

 drivers/md/dm-log-userspace-base.c |   57 ++++++++++++++++++++++++++++++++---
 1 files changed, 52 insertions(+), 5 deletions(-)

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/1] improve the performance of dm-log-userspace
  2013-09-10  9:25 ` [PATCH 0/1] ideas to improve the write performance of cluster dm-raid1 dongmao zhang
@ 2013-09-10  9:25   ` dongmao zhang
  0 siblings, 0 replies; 716+ messages in thread
From: dongmao zhang @ 2013-09-10  9:25 UTC (permalink / raw)
  To: dm-devel; +Cc: dongmao zhang

In the cluster evironment, cluster write has poor performance.
Because userspace_flush has to access userspace program(cmirrord)
for clear/mark/flush request. But the mark and flush requests
require cmirrord send message to  all the cluster nodes. This behave
is realy slow. So the idea is merging mark and flush
request together and to reduce the kernel-userspace-kernel time.
Moreover, when only sending clear request, the flush request could
be delayed. Added a workqueue to run delayed flush request.

Signed-off-by: dongmao zhang <dmzhang@suse.com>
---
 drivers/md/dm-log-userspace-base.c |   57 ++++++++++++++++++++++++++++++++---
 1 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 9429159..d9dcfac 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -11,6 +11,7 @@
 #include <linux/dm-log-userspace.h>
 #include <linux/module.h>
 
+#include <linux/workqueue.h>
 #include "dm-log-userspace-transfer.h"
 
 #define DM_LOG_USERSPACE_VSN "1.1.0"
@@ -58,6 +59,11 @@ struct log_c {
 	spinlock_t flush_lock;
 	struct list_head mark_list;
 	struct list_head clear_list;
+
+	/*work queue for flush clear region*/
+	struct workqueue_struct *dmlog_wq;
+	struct delayed_work flush_log_work;
+	atomic_t sched_flush;
 };
 
 static mempool_t *flush_entry_pool;
@@ -234,6 +240,17 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	lc->region_size = (uint32_t)rdata;
 	lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
 
+	lc->dmlog_wq =  alloc_workqueue("dmlogd",
+			WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
+	if (!lc->dmlog_wq) {
+		DMERR("couldn't start dmlogd");
+		r = -ENOMEM;
+		goto out;
+	}
+
+	INIT_DELAYED_WORK(&lc->flush_log_work, do_flush);
+	atomic_set(&lc->sched_flush, 0);
+
 	if (devices_rdata_size) {
 		if (devices_rdata[devices_rdata_size - 1] != '\0') {
 			DMERR("DM_ULOG_CTR device return string not properly terminated");
@@ -264,6 +281,13 @@ static void userspace_dtr(struct dm_dirty_log *log)
 {
 	struct log_c *lc = log->context;
 
+	/*flush workqueue*/
+	if (atomic_read(&lc->sched_flush))
+		flush_delayed_work(&lc->flush_log_work);
+
+	flush_workqueue(lc->dmlog_wq);
+	destroy_workqueue(lc->dmlog_wq);
+
 	(void) dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
 				 NULL, 0,
 				 NULL, NULL);
@@ -282,6 +306,10 @@ static int userspace_presuspend(struct dm_dirty_log *log)
 	int r;
 	struct log_c *lc = log->context;
 
+	/*run planed flush*/
+	if (atomic_read(&lc->sched_flush))
+		flush_delayed_work(&lc->flush_log_work);
+
 	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND,
 				 NULL, 0,
 				 NULL, NULL);
@@ -294,6 +322,9 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
 	int r;
 	struct log_c *lc = log->context;
 
+	if (atomic_read(&lc->sched_flush))
+		flush_delayed_work(&lc->flush_log_work);
+
 	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
 				 NULL, 0,
 				 NULL, NULL);
@@ -474,6 +505,8 @@ static int userspace_flush(struct dm_dirty_log *log)
 	int r = 0;
 	unsigned long flags;
 	struct log_c *lc = log->context;
+	int is_mark_list_empty;
+	int is_clear_list_empty;
 	LIST_HEAD(mark_list);
 	LIST_HEAD(clear_list);
 	struct flush_entry *fe, *tmp_fe;
@@ -483,19 +516,33 @@ static int userspace_flush(struct dm_dirty_log *log)
 	list_splice_init(&lc->clear_list, &clear_list);
 	spin_unlock_irqrestore(&lc->flush_lock, flags);
 
-	if (list_empty(&mark_list) && list_empty(&clear_list))
+	is_mark_list_empty = list_empty(&mark_list);
+	is_clear_list_empty = list_empty(&clear_list);
+
+	if (is_mark_list_empty && is_clear_list_empty)
 		return 0;
 
-	r = flush_by_group(lc, &mark_list);
+
+	r = flush_by_group(lc, &clear_list);
 	if (r)
 		goto fail;
 
-	r = flush_by_group(lc, &clear_list);
+	r = flush_by_group(lc, &mark_list);
 	if (r)
 		goto fail;
 
-	r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
-				 NULL, 0, NULL, NULL);
+	if (!is_clear_list_empty && is_mark_list_empty
+				 && !atomic_read(&lc->sched_flush)) {
+		/* plan a flush */
+		queue_delayed_work(lc->dmlog_wq, &lc->flush_log_work , 3 * HZ);
+		atomic_set(&lc->sched_flush, 1);
+	} else {
+		/* cancel pending flush because already flushed in mark_region*/
+		cancel_delayed_work(&lc->flush_log_work);
+		atomic_set(&lc->sched_flush, 0);
+	}
+
+
 
 fail:
 	/*
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 1/1] OMAPDSS: Return right error during connector probe
       [not found] <yes>
                   ` (72 preceding siblings ...)
  2013-09-10  9:25 ` [PATCH 0/1] ideas to improve the write performance of cluster dm-raid1 dongmao zhang
@ 2013-09-12  8:42 ` Sathya Prakash M R
  2013-09-16  9:41   ` Tomi Valkeinen
  2013-10-28 10:07 ` [PATCH 0/1] patches to improve cluster raid1 performance [V3] dongmao zhang
                   ` (17 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Sathya Prakash M R @ 2013-09-12  8:42 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Sathya Prakash M R

While using HDMI connector driver with sil9022 encoder
came across issue where connector driver is probed first.
This resulted in error. A deffered probe solved this.
Most connector drivers need a encoder driver as their
video source. This patch ensures we do a probe defferal
if video source is not present for connector drivers.

Signed-off-by: Sathya Prakash M R <sathyap@ti.com>
---
 .../video/omap2/displays-new/connector-analog-tv.c |    2 +-
 drivers/video/omap2/displays-new/connector-dvi.c   |    2 +-
 drivers/video/omap2/displays-new/connector-hdmi.c  |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c
index 5338f36..547a604 100644
--- a/drivers/video/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/omap2/displays-new/connector-analog-tv.c
@@ -177,7 +177,7 @@ static int tvc_probe_pdata(struct platform_device *pdev)
 	in = omap_dss_find_output(pdata->source);
 	if (in == NULL) {
 		dev_err(&pdev->dev, "Failed to find video source\n");
-		return -ENODEV;
+		return -EPROBE_DEFER;
 	}
 
 	ddata->in = in;
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/omap2/displays-new/connector-dvi.c
index bc5f8ce..63d88ee 100644
--- a/drivers/video/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/omap2/displays-new/connector-dvi.c
@@ -263,7 +263,7 @@ static int dvic_probe_pdata(struct platform_device *pdev)
 	in = omap_dss_find_output(pdata->source);
 	if (in == NULL) {
 		dev_err(&pdev->dev, "Failed to find video source\n");
-		return -ENODEV;
+		return -EPROBE_DEFER;
 	}
 
 	ddata->in = in;
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/omap2/displays-new/connector-hdmi.c
index c582671..9abe2c0 100644
--- a/drivers/video/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/omap2/displays-new/connector-hdmi.c
@@ -290,7 +290,7 @@ static int hdmic_probe_pdata(struct platform_device *pdev)
 	in = omap_dss_find_output(pdata->source);
 	if (in == NULL) {
 		dev_err(&pdev->dev, "Failed to find video source\n");
-		return -ENODEV;
+		return -EPROBE_DEFER;
 	}
 
 	ddata->in = in;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/1] OMAPDSS: Return right error during connector probe
  2013-09-12  8:42 ` [PATCH 1/1] OMAPDSS: Return right error during connector probe Sathya Prakash M R
@ 2013-09-16  9:41   ` Tomi Valkeinen
  0 siblings, 0 replies; 716+ messages in thread
From: Tomi Valkeinen @ 2013-09-16  9:41 UTC (permalink / raw)
  To: Sathya Prakash M R; +Cc: linux-omap

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

On 12/09/13 11:42, Sathya Prakash M R wrote:
> While using HDMI connector driver with sil9022 encoder
> came across issue where connector driver is probed first.
> This resulted in error. A deffered probe solved this.
> Most connector drivers need a encoder driver as their
> video source. This patch ensures we do a probe defferal
> if video source is not present for connector drivers.
> 
> Signed-off-by: Sathya Prakash M R <sathyap@ti.com>

Thanks, applying to 3.12 fixes.

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 0/1] patches to improve cluster raid1 performance [V3]
       [not found] <yes>
                   ` (73 preceding siblings ...)
  2013-09-12  8:42 ` [PATCH 1/1] OMAPDSS: Return right error during connector probe Sathya Prakash M R
@ 2013-10-28 10:07 ` dongmao zhang
  2013-10-28 10:07   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
  2013-10-28 10:17 ` [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3] dongmao zhang
                   ` (16 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: dongmao zhang @ 2013-10-28 10:07 UTC (permalink / raw)
  To: dm-devel

use DM_INTEGRATED_FLUSH to indicate the new option of flush request.
when using DM_INTEGRATED_FLUSH, the payload of flush request is the 
same as mark region request.

'X' means we have this kind of request, while '0' means none.

mark request :     X               X               0

clear request:     X               0               X

flush method:    payload_flush   payload_flush   delayed flush

dongmao zhang (1):
  improve the performance of dm-log-userspace

 drivers/md/dm-log-userspace-base.c    |  133 +++++++++++++++++++++++++++++----
 include/uapi/linux/dm-log-userspace.h |    6 +-
 2 files changed, 121 insertions(+), 18 deletions(-)

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/1] improve the performance of dm-log-userspace
  2013-10-28 10:07 ` [PATCH 0/1] patches to improve cluster raid1 performance [V3] dongmao zhang
@ 2013-10-28 10:07   ` dongmao zhang
  2013-10-30  1:35     ` Brassow Jonathan
  0 siblings, 1 reply; 716+ messages in thread
From: dongmao zhang @ 2013-10-28 10:07 UTC (permalink / raw)
  To: dm-devel

In the cluster evironment, cluster write has poor performance.
Because userspace_flush has to contact userspace program(cmirrord)
in clear/mark/flush request. But both mark and flush requests
require cmirrord to circle message to all the cluster nodes in each
flush call.  This behave is realy slow. So the idea is merging
mark and flush request together to reduce the kernel-userspace-kernel
time. Add a new flag DM_INTEGRATED_FLUSH to tell userspace application
that kernel has a flush with mark_region data. Besides, when only sending
clear request, the flush request could be delayed.
Added a workqueue to run delayed flush request.

Signed-off-by: dongmao zhang <dmzhang@suse.com>
---
 drivers/md/dm-log-userspace-base.c    |  133 +++++++++++++++++++++++++++++----
 include/uapi/linux/dm-log-userspace.h |    6 +-
 2 files changed, 121 insertions(+), 18 deletions(-)

diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 9429159..d22949f 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -11,9 +11,10 @@
 #include <linux/dm-log-userspace.h>
 #include <linux/module.h>
 
+#include <linux/workqueue.h>
 #include "dm-log-userspace-transfer.h"
 
-#define DM_LOG_USERSPACE_VSN "1.1.0"
+#define DM_LOG_USERSPACE_VSN "1.2.0"
 
 struct flush_entry {
 	int type;
@@ -29,6 +30,8 @@ struct flush_entry {
  */
 #define MAX_FLUSH_GROUP_COUNT 32
 
+#define DM_INTEGRATED_FLUSH "integrated_flush"
+
 struct log_c {
 	struct dm_target *ti;
 	struct dm_dev *log_dev;
@@ -58,6 +61,12 @@ struct log_c {
 	spinlock_t flush_lock;
 	struct list_head mark_list;
 	struct list_head clear_list;
+
+	/*work queue for flush clear region*/
+	struct workqueue_struct *dmlog_wq;
+	struct delayed_work flush_log_work;
+	atomic_t sched_flush;
+	uint32_t integrated_flush;
 };
 
 static mempool_t *flush_entry_pool;
@@ -141,6 +150,19 @@ static int build_constructor_string(struct dm_target *ti,
 	return str_size;
 }
 
+static void do_flush(struct delayed_work *work)
+{
+	int r;
+	struct log_c *lc = container_of(work, struct log_c, flush_log_work);
+	r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
+						 NULL, 0, NULL, NULL);
+	atomic_set(&lc->sched_flush, 0);
+	if (r)
+		dm_table_event(lc->ti->table);
+}
+
+
+
 /*
  * userspace_ctr
  *
@@ -164,7 +186,11 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	uint64_t rdata;
 	size_t rdata_size = sizeof(rdata);
 	char *devices_rdata = NULL;
-	size_t devices_rdata_size = DM_NAME_LEN;
+
+	char *logdev = NULL;
+	char *integrated_flush_string = NULL;
+
+	size_t devices_rdata_size = DM_NAME_LEN + sizeof(DM_INTEGRATED_FLUSH);
 
 	if (argc < 3) {
 		DMWARN("Too few arguments to userspace dirty log");
@@ -234,18 +260,43 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 	lc->region_size = (uint32_t)rdata;
 	lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
 
+
+	lc->integrated_flush = 0;
+
 	if (devices_rdata_size) {
 		if (devices_rdata[devices_rdata_size - 1] != '\0') {
 			DMERR("DM_ULOG_CTR device return string not properly terminated");
 			r = -EINVAL;
 			goto out;
 		}
-		r = dm_get_device(ti, devices_rdata,
+
+		logdev = strsep(&devices_rdata, " ");
+		integrated_flush_string = strsep(&devices_rdata, " ");
+
+		if (integrated_flush_string &&
+			!strcmp(integrated_flush_string, DM_INTEGRATED_FLUSH))
+			lc->integrated_flush = 1;
+
+		r = dm_get_device(ti, logdev,
 				  dm_table_get_mode(ti->table), &lc->log_dev);
 		if (r)
 			DMERR("Failed to register %s with device-mapper",
-			      devices_rdata);
+			      logdev);
+	}
+
+	if (lc->integrated_flush) {
+		lc->dmlog_wq =  alloc_workqueue("dmlogd",
+				WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
+		if (!lc->dmlog_wq) {
+			DMERR("couldn't start dmlogd");
+			r = -ENOMEM;
+			goto out;
+		}
+
+		INIT_DELAYED_WORK(&lc->flush_log_work, do_flush);
+		atomic_set(&lc->sched_flush, 0);
 	}
+
 out:
 	kfree(devices_rdata);
 	if (r) {
@@ -264,6 +315,15 @@ static void userspace_dtr(struct dm_dirty_log *log)
 {
 	struct log_c *lc = log->context;
 
+	if (lc->integrated_flush) {
+		/*flush workqueue*/
+		if (atomic_read(&lc->sched_flush))
+			flush_delayed_work(&lc->flush_log_work);
+
+		flush_workqueue(lc->dmlog_wq);
+		destroy_workqueue(lc->dmlog_wq);
+	}
+
 	(void) dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
 				 NULL, 0,
 				 NULL, NULL);
@@ -294,6 +354,10 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
 	int r;
 	struct log_c *lc = log->context;
 
+	/*run planed flush earlier*/
+	if (lc->integrated_flush && atomic_read(&lc->sched_flush))
+		flush_delayed_work(&lc->flush_log_work);
+
 	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
 				 NULL, 0,
 				 NULL, NULL);
@@ -405,7 +469,8 @@ static int flush_one_by_one(struct log_c *lc, struct list_head *flush_list)
 	return r;
 }
 
-static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
+static int flush_by_group(struct log_c *lc, struct list_head *flush_list,
+		int flush_with_payload)
 {
 	int r = 0;
 	int count;
@@ -431,10 +496,21 @@ static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
 				break;
 		}
 
-		r = userspace_do_request(lc, lc->uuid, type,
-					 (char *)(group),
-					 count * sizeof(uint64_t),
-					 NULL, NULL);
+		if (flush_with_payload) {
+			r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
+						 (char *)(group),
+						 count * sizeof(uint64_t),
+						 NULL, NULL);
+			/* integrated flush failed */
+			if (r)
+				return r;
+		}
+		else
+			r = userspace_do_request(lc, lc->uuid, type,
+						 (char *)(group),
+						 count * sizeof(uint64_t),
+						 NULL, NULL);
+
 		if (r) {
 			/* Group send failed.  Attempt one-by-one. */
 			list_splice_init(&tmp_list, flush_list);
@@ -452,6 +528,7 @@ static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
 	return r;
 }
 
+
 /*
  * userspace_flush
  *
@@ -474,6 +551,8 @@ static int userspace_flush(struct dm_dirty_log *log)
 	int r = 0;
 	unsigned long flags;
 	struct log_c *lc = log->context;
+	int is_mark_list_empty;
+	int is_clear_list_empty;
 	LIST_HEAD(mark_list);
 	LIST_HEAD(clear_list);
 	struct flush_entry *fe, *tmp_fe;
@@ -483,19 +562,41 @@ static int userspace_flush(struct dm_dirty_log *log)
 	list_splice_init(&lc->clear_list, &clear_list);
 	spin_unlock_irqrestore(&lc->flush_lock, flags);
 
-	if (list_empty(&mark_list) && list_empty(&clear_list))
+	is_mark_list_empty = list_empty(&mark_list);
+	is_clear_list_empty = list_empty(&clear_list);
+
+	if (is_mark_list_empty && is_clear_list_empty)
 		return 0;
 
-	r = flush_by_group(lc, &mark_list);
-	if (r)
-		goto fail;
+	r = flush_by_group(lc, &clear_list, 0);
 
-	r = flush_by_group(lc, &clear_list);
 	if (r)
 		goto fail;
 
-	r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
-				 NULL, 0, NULL, NULL);
+	if (lc->integrated_flush) {
+		/* send flush request with mark_list as payload*/
+		r = flush_by_group(lc, &mark_list, 1);
+	} else {
+		r = flush_by_group(lc, &mark_list, 0);
+		if (r)
+			goto fail;
+		r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
+					NULL, 0, NULL, NULL);
+	}
+
+
+	/* when only has clear region,we plan a flush in the furture */
+	if (!is_clear_list_empty && is_mark_list_empty
+				 && !atomic_read(&lc->sched_flush)) {
+		queue_delayed_work(lc->dmlog_wq, &lc->flush_log_work , 3 * HZ);
+		atomic_set(&lc->sched_flush, 1);
+	/* cancel pending flush because we have already flushed in mark_region*/
+	} else {
+		cancel_delayed_work(&lc->flush_log_work);
+		atomic_set(&lc->sched_flush, 0);
+	}
+
+
 
 fail:
 	/*
diff --git a/include/uapi/linux/dm-log-userspace.h b/include/uapi/linux/dm-log-userspace.h
index 0678c2a..e91014e 100644
--- a/include/uapi/linux/dm-log-userspace.h
+++ b/include/uapi/linux/dm-log-userspace.h
@@ -201,7 +201,9 @@
  * int (*flush)(struct dm_dirty_log *log);
  *
  * Payload-to-userspace:
- *	None.
+ *	if DM_INTEGRATED_FLUSH is set, payload is as same as DM_ULOG_MARK_REGION
+ *	uint64_t [] - region(s) to mark
+ *	else None
  * Payload-to-kernel:
  *	None.
  *
@@ -386,7 +388,7 @@
  *	            device name that is to be registered with DM via
  *	            'dm_get_device'.
  */
-#define DM_ULOG_REQUEST_VERSION 2
+#define DM_ULOG_REQUEST_VERSION 3
 
 struct dm_ulog_request {
 	/*
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3]
       [not found] <yes>
                   ` (74 preceding siblings ...)
  2013-10-28 10:07 ` [PATCH 0/1] patches to improve cluster raid1 performance [V3] dongmao zhang
@ 2013-10-28 10:17 ` dongmao zhang
  2013-10-28 10:17   ` [PATCH 1/2] add integrated_flush support to device-mapper dongmao zhang
  2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
                   ` (15 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: dongmao zhang @ 2013-10-28 10:17 UTC (permalink / raw)
  To: lvm-devel

These patches work with dm-log-userspace enhancement.
LVM, device-mapper and cmirrord begin to support
merging mark/flush request(if DM_INTEGRATED_FLUSH is set)
This would increase the write throughput of cluster raid1 
based on my own test.


dongmao zhang (2):
  add integrated_flush support to device-mapper
  cmirrord support DM_INTEGRATED_FLUSH

 daemons/cmirrord/functions.c |   62 +++++++++++++++++++++++++++++++++---------
 daemons/cmirrord/local.c     |    9 +++++-
 lib/mirror/mirrored.c        |    4 +++
 libdm/libdevmapper.h         |    3 ++
 libdm/libdm-deptree.c        |    8 +++++
 5 files changed, 72 insertions(+), 14 deletions(-)

-- 
1.7.3.4



^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/2] add integrated_flush support to device-mapper
  2013-10-28 10:17 ` [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3] dongmao zhang
@ 2013-10-28 10:17   ` dongmao zhang
  2013-10-28 10:17     ` [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH dongmao zhang
  2013-10-30  1:47     ` [PATCH 1/2] add integrated_flush support to device-mapper Brassow Jonathan
  0 siblings, 2 replies; 716+ messages in thread
From: dongmao zhang @ 2013-10-28 10:17 UTC (permalink / raw)
  To: lvm-devel

---
 lib/mirror/mirrored.c |    4 ++++
 libdm/libdevmapper.h  |    3 +++
 libdm/libdm-deptree.c |    8 ++++++++
 3 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index c3eb27b..572f87e 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -378,6 +378,10 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
 	if (_block_on_error_available && !(seg->status & PVMOVE))
 		log_flags |= DM_BLOCK_ON_ERROR;
 
+	/*clustered log support delay flush*/
+	if(clustered)
+		log_flags |= DM_INTEGRATED_FLUSH;
+
 	return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count, log_flags);
 }
 
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index b287eef..e88a318 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -667,6 +667,9 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
 #define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
 #define DM_CORELOG		0x00000008	/* In-memory log */
 
+/*for cluster raid1, use integrated flush to improve performance*/
+#define DM_INTEGRATED_FLUSH		0x00000010
+
 int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
 					  uint32_t region_size,
 					  unsigned clustered,
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 752a44b..0a93028 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -2054,6 +2054,7 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
 				     char *params, size_t paramsize)
 {
 	int block_on_error = 0;
+	int integrated_flush = 0;
 	int handle_errors = 0;
 	int dm_log_userspace = 0;
 	struct utsname uts;
@@ -2107,6 +2108,9 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
 		 */
 		if (KERNEL_VERSION(kmaj, kmin, krel) >= KERNEL_VERSION(2, 6, 31))
 			dm_log_userspace = 1;
+
+		if(seg->flags & DM_INTEGRATED_FLUSH)
+			integrated_flush = 1;
 	}
 
 	/* Region size */
@@ -2164,6 +2168,10 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
 	if (block_on_error)
 		EMIT_PARAMS(pos, " block_on_error");
 
+	if (dm_log_userspace && DM_INTEGRATED_FLUSH)
+		EMIT_PARAMS(pos, " integrated_flush");
+
+
 	EMIT_PARAMS(pos, " %u ", seg->mirror_area_count);
 
 	if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
-- 
1.7.3.4



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH
  2013-10-28 10:17   ` [PATCH 1/2] add integrated_flush support to device-mapper dongmao zhang
@ 2013-10-28 10:17     ` dongmao zhang
  2013-10-30  1:48       ` Brassow Jonathan
  2013-10-30  1:47     ` [PATCH 1/2] add integrated_flush support to device-mapper Brassow Jonathan
  1 sibling, 1 reply; 716+ messages in thread
From: dongmao zhang @ 2013-10-28 10:17 UTC (permalink / raw)
  To: lvm-devel

if integrated_flush is set. cmirrord will check the payload
of FLUSH request.
---
 daemons/cmirrord/functions.c |   62 +++++++++++++++++++++++++++++++++---------
 daemons/cmirrord/local.c     |    9 +++++-
 lib/mirror/mirrored.c        |    2 +-
 3 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/daemons/cmirrord/functions.c b/daemons/cmirrord/functions.c
index f6e0918..c534136 100644
--- a/daemons/cmirrord/functions.c
+++ b/daemons/cmirrord/functions.c
@@ -75,6 +75,7 @@ struct log_c {
                 FORCESYNC,      /* Force a sync to happen */
         } sync;
 
+	uint32_t integrated_flush;
 	uint32_t state;         /* current operational state of the log */
 
 	struct dm_list mark_list;
@@ -362,7 +363,7 @@ static int find_disk_path(char *major_minor_str, char *path_rtn, int *unlink_pat
 	// return r ? -errno : 0;
 }
 
-static int _clog_ctr(char *uuid, uint64_t luid,
+static int _clog_ctr(char *uuid, uint64_t luid, uint32_t version,
 		     int argc, char **argv, uint64_t device_size)
 {
 	int i;
@@ -373,6 +374,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
 	struct log_c *lc = NULL;
 	enum sync log_sync = DEFAULTSYNC;
 	uint32_t block_on_error = 0;
+	uint32_t integrated_flush = 0;
 
 	int disk_log;
 	char disk_path[128];
@@ -431,6 +433,8 @@ static int _clog_ctr(char *uuid, uint64_t luid,
 			log_sync = NOSYNC;
 		else if (!strcmp(argv[i], "block_on_error"))
 			block_on_error = 1;
+		else if (!strcmp(argv[i], "integrated_flush") && version > 2)
+			integrated_flush = 1;
 	}
 
 	lc = dm_zalloc(sizeof(*lc));
@@ -451,6 +455,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
 	lc->log_dev_failed = 0;
 	strncpy(lc->uuid, uuid, DM_UUID_LEN);
 	lc->luid = luid;
+	lc->integrated_flush = integrated_flush;
 
 	if (get_log(lc->uuid, lc->luid) ||
 	    get_pending_log(lc->uuid, lc->luid)) {
@@ -552,6 +557,8 @@ static int clog_ctr(struct dm_ulog_request *rq)
 	char *dev_size_str;
 	uint64_t device_size;
 
+	struct log_c *tmplc = NULL;
+
 	/* Sanity checks */
 	if (!rq->data_size) {
 		LOG_ERROR("Received constructor request with no data");
@@ -594,14 +601,17 @@ static int clog_ctr(struct dm_ulog_request *rq)
 		return -EINVAL;
 	}
 
-	r = _clog_ctr(rq->uuid, rq->luid, argc - 1, argv + 1, device_size);
+	r = _clog_ctr(rq->uuid, rq->luid, rq->version, argc - 1, argv + 1, device_size);
 
 	/* We join the CPG when we resume */
 
 	/* No returning data */
-	if ((rq->version > 1) && !strcmp(argv[0], "clustered-disk"))
-		rq->data_size = sprintf(rq->data, "%s", argv[1]) + 1;
-	else
+	if ((rq->version > 1) && !strcmp(argv[0], "clustered-disk")) {
+		rq->data_size = sprintf(rq->data, "%s", argv[1]);
+		tmplc = get_pending_log(rq->uuid, rq->luid);
+		if (tmplc && tmplc->integrated_flush)
+			rq->data_size += sprintf(rq->data + rq->data_size, " %s", "integrated_flush") + 1;
+	} else
 		rq->data_size = 0;
 
 	if (r) {
@@ -1027,14 +1037,17 @@ static int clog_in_sync(struct dm_ulog_request *rq)
 }
 
 /*
- * clog_flush
- * @rq
+ * _clog_flush
+ * @lc
+ * @server
+ *
+ * real flush
  *
+ * Returns: 0 on success, -EXXX on error
  */
-static int clog_flush(struct dm_ulog_request *rq, int server)
+static int _clog_flush(struct log_c *lc, int server)
 {
 	int r = 0;
-	struct log_c *lc = get_log(rq->uuid, rq->luid);
 
 	if (!lc)
 		return -EINVAL;
@@ -1047,10 +1060,10 @@ static int clog_flush(struct dm_ulog_request *rq, int server)
 	 * if we are the server.
 	 */
 	if (server && (lc->disk_fd >= 0)) {
-		r = rq->error = write_log(lc);
+		r = write_log(lc);
 		if (r)
 			LOG_ERROR("[%s] Error writing to disk log",
-				  SHORT_UUID(lc->uuid));
+				SHORT_UUID(lc->uuid));
 		else 
 			LOG_DBG("[%s] Disk log written", SHORT_UUID(lc->uuid));
 	}
@@ -1058,6 +1071,21 @@ static int clog_flush(struct dm_ulog_request *rq, int server)
 	lc->touched = 0;
 
 	return r;
+}
+
+
+/*
+ * clog_flush
+ * @rq
+ *
+ */
+static int clog_flush(struct dm_ulog_request *rq, int server)
+{
+	int r = 0;
+	struct log_c *lc = get_log(rq->uuid, rq->luid);
+
+	r = rq->error = _clog_flush(lc, server);
+	return r;
 
 }
 
@@ -1113,7 +1141,7 @@ static int mark_region(struct log_c *lc, uint64_t region, uint32_t who)
  *
  * Returns: 0 on success, -EXXX on failure
  */
-static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator)
+static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator, int server)
 {
 	int r;
 	int count;
@@ -1139,6 +1167,14 @@ static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator)
 
 	rq->data_size = 0;
 
+	/* 
+	 * if kernel support integrate flush, after marking region, 
+	 * cmirrord should execute clog_flush automatically.
+	 */
+
+	if(lc->integrated_flush)
+		return _clog_flush(lc, server);
+
 	return 0;
 }
 
@@ -1676,7 +1712,7 @@ int do_request(struct clog_request *rq, int server)
 		r = clog_flush(&rq->u_rq, server);
 		break;
 	case DM_ULOG_MARK_REGION:
-		r = clog_mark_region(&rq->u_rq, rq->originator);
+		r = clog_mark_region(&rq->u_rq, rq->originator, server);
 		break;
 	case DM_ULOG_CLEAR_REGION:
 		r = clog_clear_region(&rq->u_rq, rq->originator);
diff --git a/daemons/cmirrord/local.c b/daemons/cmirrord/local.c
index 500f6dc..8b52556 100644
--- a/daemons/cmirrord/local.c
+++ b/daemons/cmirrord/local.c
@@ -267,8 +267,15 @@ static int do_local_work(void *data __attribute__((unused)))
 			break;
 		}
 		/* ELSE, fall through */
-	case DM_ULOG_IS_CLEAN:
 	case DM_ULOG_FLUSH:
+		/*
+		 * if it has payload, it must be a integrated flush.
+		 * change the request_type to MARK_REGION. the clog_mark_region
+		 * will flush automatically in the futhure
+		 */
+		if (rq->u_rq.data_size > 0)
+			rq->u_rq.request_type = DM_ULOG_MARK_REGION;
+	case DM_ULOG_IS_CLEAN:
 	case DM_ULOG_MARK_REGION:
 	case DM_ULOG_GET_RESYNC_WORK:
 	case DM_ULOG_SET_REGION_SYNC:
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index 572f87e..4015116 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -378,7 +378,7 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
 	if (_block_on_error_available && !(seg->status & PVMOVE))
 		log_flags |= DM_BLOCK_ON_ERROR;
 
-	/*clustered log support delay flush*/
+	/*clustered log support integrated flush*/
 	if(clustered)
 		log_flags |= DM_INTEGRATED_FLUSH;
 
-- 
1.7.3.4



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 1/1] improve the performance of dm-log-userspace
  2013-10-28 10:07   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
@ 2013-10-30  1:35     ` Brassow Jonathan
  0 siblings, 0 replies; 716+ messages in thread
From: Brassow Jonathan @ 2013-10-30  1:35 UTC (permalink / raw)
  To: device-mapper development; +Cc: dongmao zhang

Dongmao,

I like what's going on here.  I makes a lot more sense to me.  A few more tweaks and corrections and I'll ack it.

Please see the in-line comments I've made to the patch below.  Before getting to that though, I'd like to talk about how all this is going to work in terms of compatibility:

1) New kernel + New userspace
This obviously will work fine.  I think it can be simplified though.  DEFINITELY bump the version number of DM_ULOG_REQUEST_VERSION to 3.  However, I don't think you need much other complexity - like changing what the userspace CTR returns.  Userspace should send the extra parameter "integrated_flush" and the kernel should 'strstr' for that to turn it on in the kernel, but the kernel should then just pass on the CTR string to userspace and that should be the end of it.

2) Old kernel + New userspace
Userspace will attempt to pass down the "integrated_flush" parameter, but the kernel will not be checking for it.  Therefore, old kernels will obviously not turn on the feature and will pass along the CTR string without altering it.  The new userspace should be capable of handling flushes with and without a payload and can tell which is which by whether they have that payload or not.  So, userspace can handle both old and new kernels and this scenario should work just fine.

3) New kernel + Old userspace
Old userspace will never send down a "integrated_flush" parameter.  Therefore, it will never be turned on in the kernel and this scenario should work just fine.

I think we can simplify the patches quite a bit by understanding the compatibility issues and methods above.  Keep them in mind for this kernel patch and the upcoming userspace patches.

 brassow


On Oct 28, 2013, at 5:07 AM, dongmao zhang wrote:

> In the cluster evironment, cluster write has poor performance.
> Because userspace_flush has to contact userspace program(cmirrord)
> in clear/mark/flush request. But both mark and flush requests
> require cmirrord to circle message to all the cluster nodes in each
> flush call.  This behave is realy slow. So the idea is merging
> mark and flush request together to reduce the kernel-userspace-kernel
> time. Add a new flag DM_INTEGRATED_FLUSH to tell userspace application
> that kernel has a flush with mark_region data. Besides, when only sending
> clear request, the flush request could be delayed.
> Added a workqueue to run delayed flush request.
> 
> Signed-off-by: dongmao zhang <dmzhang@suse.com>
> ---
> drivers/md/dm-log-userspace-base.c    |  133 +++++++++++++++++++++++++++++----
> include/uapi/linux/dm-log-userspace.h |    6 +-
> 2 files changed, 121 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
> index 9429159..d22949f 100644
> --- a/drivers/md/dm-log-userspace-base.c
> +++ b/drivers/md/dm-log-userspace-base.c
> @@ -11,9 +11,10 @@
> #include <linux/dm-log-userspace.h>
> #include <linux/module.h>
> 
> +#include <linux/workqueue.h>
> #include "dm-log-userspace-transfer.h"
> 
> -#define DM_LOG_USERSPACE_VSN "1.1.0"
> +#define DM_LOG_USERSPACE_VSN "1.2.0"
> 
> struct flush_entry {
> 	int type;
> @@ -29,6 +30,8 @@ struct flush_entry {
>  */
> #define MAX_FLUSH_GROUP_COUNT 32
> 
> +#define DM_INTEGRATED_FLUSH "integrated_flush"
> +

Don't need this define, I don't think.

> struct log_c {
> 	struct dm_target *ti;
> 	struct dm_dev *log_dev;
> @@ -58,6 +61,12 @@ struct log_c {
> 	spinlock_t flush_lock;
> 	struct list_head mark_list;
> 	struct list_head clear_list;
> +
> +	/*work queue for flush clear region*/
> +	struct workqueue_struct *dmlog_wq;
> +	struct delayed_work flush_log_work;
> +	atomic_t sched_flush;
> +	uint32_t integrated_flush;
> };
> 
> static mempool_t *flush_entry_pool;
> @@ -141,6 +150,19 @@ static int build_constructor_string(struct dm_target *ti,
> 	return str_size;
> }
> 
> +static void do_flush(struct delayed_work *work)
> +{
> +	int r;
> +	struct log_c *lc = container_of(work, struct log_c, flush_log_work);
> +	r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
> +						 NULL, 0, NULL, NULL);

bad indent.

> +	atomic_set(&lc->sched_flush, 0);
> +	if (r)
> +		dm_table_event(lc->ti->table);
> +}
> +
> +
> +

2 unnecessary newlines?  There are other places below that include unnecessary whitespace.  I will mark them as 'SP'.  In general, there is no need for 2 newlines in a row.  Don't over-add whitespace.

> /*
>  * userspace_ctr
>  *
> @@ -164,7 +186,11 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
> 	uint64_t rdata;
> 	size_t rdata_size = sizeof(rdata);
> 	char *devices_rdata = NULL;
> -	size_t devices_rdata_size = DM_NAME_LEN;
> +
> +	char *logdev = NULL;
> +	char *integrated_flush_string = NULL;

won't need these variables soon.

> +
> +	size_t devices_rdata_size = DM_NAME_LEN + sizeof(DM_INTEGRATED_FLUSH);

2xSP - don't need newlines between variable declarations/init.


> 
> 	if (argc < 3) {
> 		DMWARN("Too few arguments to userspace dirty log");
> @@ -234,18 +260,43 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
> 	lc->region_size = (uint32_t)rdata;
> 	lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
> 
> +

SP

> +	lc->integrated_flush = 0;
> +
> 	if (devices_rdata_size) {
> 		if (devices_rdata[devices_rdata_size - 1] != '\0') {
> 			DMERR("DM_ULOG_CTR device return string not properly terminated");
> 			r = -EINVAL;
> 			goto out;
> 		}
> -		r = dm_get_device(ti, devices_rdata,
> +
> +		logdev = strsep(&devices_rdata, " ");
> +		integrated_flush_string = strsep(&devices_rdata, " ");

Don't make userspace return this.  Just check the CTR string for "integrated_flush" as it is being passed through to the log server.

> +
> +		if (integrated_flush_string &&
> +			!strcmp(integrated_flush_string, DM_INTEGRATED_FLUSH))

bad indent?

> +			lc->integrated_flush = 1;
> +
> +		r = dm_get_device(ti, logdev,
> 				  dm_table_get_mode(ti->table), &lc->log_dev);
> 		if (r)
> 			DMERR("Failed to register %s with device-mapper",
> -			      devices_rdata);
> +			      logdev);
> +	}
> +
> +	if (lc->integrated_flush) {
> +		lc->dmlog_wq =  alloc_workqueue("dmlogd",
> +				WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);

bad indent?

> +		if (!lc->dmlog_wq) {
> +			DMERR("couldn't start dmlogd");
> +			r = -ENOMEM;
> +			goto out;
> +		}
> +
> +		INIT_DELAYED_WORK(&lc->flush_log_work, do_flush);
> +		atomic_set(&lc->sched_flush, 0);
> 	}
> +
> out:
> 	kfree(devices_rdata);
> 	if (r) {
> @@ -264,6 +315,15 @@ static void userspace_dtr(struct dm_dirty_log *log)
> {
> 	struct log_c *lc = log->context;
> 
> +	if (lc->integrated_flush) {
> +		/*flush workqueue*/
> +		if (atomic_read(&lc->sched_flush))
> +			flush_delayed_work(&lc->flush_log_work);
> +
> +		flush_workqueue(lc->dmlog_wq);
> +		destroy_workqueue(lc->dmlog_wq);
> +	}
> +
> 	(void) dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
> 				 NULL, 0,
> 				 NULL, NULL);
> @@ -294,6 +354,10 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
> 	int r;
> 	struct log_c *lc = log->context;
> 
> +	/*run planed flush earlier*/

space between comment markers and words?  like, /* run ... earlier */

> +	if (lc->integrated_flush && atomic_read(&lc->sched_flush))
> +		flush_delayed_work(&lc->flush_log_work);
> +
> 	r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
> 				 NULL, 0,
> 				 NULL, NULL);
> @@ -405,7 +469,8 @@ static int flush_one_by_one(struct log_c *lc, struct list_head *flush_list)
> 	return r;
> }
> 
> -static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
> +static int flush_by_group(struct log_c *lc, struct list_head *flush_list,
> +		int flush_with_payload)
> {
> 	int r = 0;
> 	int count;
> @@ -431,10 +496,21 @@ static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
> 				break;
> 		}
> 
> -		r = userspace_do_request(lc, lc->uuid, type,
> -					 (char *)(group),
> -					 count * sizeof(uint64_t),
> -					 NULL, NULL);
> +		if (flush_with_payload) {
> +			r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
> +						 (char *)(group),
> +						 count * sizeof(uint64_t),
> +						 NULL, NULL);
> +			/* integrated flush failed */
> +			if (r)
> +				return r;
> +		}
> +		else
> +			r = userspace_do_request(lc, lc->uuid, type,
> +						 (char *)(group),
> +						 count * sizeof(uint64_t),
> +						 NULL, NULL);
> +
> 		if (r) {
> 			/* Group send failed.  Attempt one-by-one. */
> 			list_splice_init(&tmp_list, flush_list);

If group send fails, I don't think the fallback 'flush_one_by_one' will perform a flush - I think you need something in that function.


> @@ -452,6 +528,7 @@ static int flush_by_group(struct log_c *lc, struct list_head *flush_list)
> 	return r;
> }
> 
> +

SP

> /*
>  * userspace_flush
>  *
> @@ -474,6 +551,8 @@ static int userspace_flush(struct dm_dirty_log *log)
> 	int r = 0;
> 	unsigned long flags;
> 	struct log_c *lc = log->context;
> +	int is_mark_list_empty;
> +	int is_clear_list_empty;
> 	LIST_HEAD(mark_list);
> 	LIST_HEAD(clear_list);
> 	struct flush_entry *fe, *tmp_fe;
> @@ -483,19 +562,41 @@ static int userspace_flush(struct dm_dirty_log *log)
> 	list_splice_init(&lc->clear_list, &clear_list);
> 	spin_unlock_irqrestore(&lc->flush_lock, flags);
> 
> -	if (list_empty(&mark_list) && list_empty(&clear_list))
> +	is_mark_list_empty = list_empty(&mark_list);
> +	is_clear_list_empty = list_empty(&clear_list);
> +
> +	if (is_mark_list_empty && is_clear_list_empty)
> 		return 0;
> 
> -	r = flush_by_group(lc, &mark_list);
> -	if (r)
> -		goto fail;
> +	r = flush_by_group(lc, &clear_list, 0);
> 
> -	r = flush_by_group(lc, &clear_list);
> 	if (r)
> 		goto fail;
> 
> -	r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
> -				 NULL, 0, NULL, NULL);
> +	if (lc->integrated_flush) {
> +		/* send flush request with mark_list as payload*/
> +		r = flush_by_group(lc, &mark_list, 1);
> +	} else {
> +		r = flush_by_group(lc, &mark_list, 0);
> +		if (r)
> +			goto fail;
> +		r = userspace_do_request(lc, lc->uuid, DM_ULOG_FLUSH,
> +					NULL, 0, NULL, NULL);

bad indent?

> +	}
> +
> +

Take the following block...
> +	/* when only has clear region,we plan a flush in the furture */
> +	if (!is_clear_list_empty && is_mark_list_empty
> +				 && !atomic_read(&lc->sched_flush)) {

'&&' goes on previous line and !atomic_read lines up with !is_clear_list_empty.

> +		queue_delayed_work(lc->dmlog_wq, &lc->flush_log_work , 3 * HZ);
> +		atomic_set(&lc->sched_flush, 1);
> +	/* cancel pending flush because we have already flushed in mark_region*/
> +	} else {
> +		cancel_delayed_work(&lc->flush_log_work);
> +		atomic_set(&lc->sched_flush, 0);
> +	}

... and push it into the (lc->integrated_flush) condition above, like you mentioned.

> +
> +

2xSP

> 
> fail:
> 	/*
> diff --git a/include/uapi/linux/dm-log-userspace.h b/include/uapi/linux/dm-log-userspace.h
> index 0678c2a..e91014e 100644
> --- a/include/uapi/linux/dm-log-userspace.h
> +++ b/include/uapi/linux/dm-log-userspace.h
> @@ -201,7 +201,9 @@
>  * int (*flush)(struct dm_dirty_log *log);
>  *
>  * Payload-to-userspace:
> - *	None.
> + *	if DM_INTEGRATED_FLUSH is set, payload is as same as DM_ULOG_MARK_REGION
> + *	uint64_t [] - region(s) to mark
> + *	else None
>  * Payload-to-kernel:
>  *	None.
>  *

There are other things that must be adjusted in this comment block, like:
"No incoming or outgoing payload" - that is no longer true.

> @@ -386,7 +388,7 @@
>  *	            device name that is to be registered with DM via
>  *	            'dm_get_device'.
>  */
> -#define DM_ULOG_REQUEST_VERSION 2
> +#define DM_ULOG_REQUEST_VERSION 3

You should adjust the comment to show what 'version 3' supports - as was done for 1 and 2.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/2] add integrated_flush support to device-mapper
  2013-10-28 10:17   ` [PATCH 1/2] add integrated_flush support to device-mapper dongmao zhang
  2013-10-28 10:17     ` [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH dongmao zhang
@ 2013-10-30  1:47     ` Brassow Jonathan
  1 sibling, 0 replies; 716+ messages in thread
From: Brassow Jonathan @ 2013-10-30  1:47 UTC (permalink / raw)
  To: lvm-devel

Dongmao,

I don't think we need to change as much code as you have here.  There is no way to switch off this obvious improvement and no need to.  So, if you are going to hard-code it in, simply add "integrated_flush" if the log is clustered.  This patch could boil down to one or two extra lines that simply say "if clustered, emit 'integrated_flush'".  At that point, you might as well fold it into the other patch.

 brassow

P.S.  Since you will likely fold what's left of this patch into the other, this next statement is only useful as an FYI.  I think the order of these two userspace patches should have been reverse, because you add the functionality with the other one and you enable using it here.  Patches should build on each other - you don't want to enable something that you haven't coded for yet.


On Oct 28, 2013, at 5:17 AM, dongmao zhang wrote:

> ---
> lib/mirror/mirrored.c |    4 ++++
> libdm/libdevmapper.h  |    3 +++
> libdm/libdm-deptree.c |    8 ++++++++
> 3 files changed, 15 insertions(+), 0 deletions(-)
> 
> diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
> index c3eb27b..572f87e 100644
> --- a/lib/mirror/mirrored.c
> +++ b/lib/mirror/mirrored.c
> @@ -378,6 +378,10 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
> 	if (_block_on_error_available && !(seg->status & PVMOVE))
> 		log_flags |= DM_BLOCK_ON_ERROR;
> 
> +	/*clustered log support delay flush*/
> +	if(clustered)
> +		log_flags |= DM_INTEGRATED_FLUSH;
> +
> 	return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count, log_flags);
> }
> 
> diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
> index b287eef..e88a318 100644
> --- a/libdm/libdevmapper.h
> +++ b/libdm/libdevmapper.h
> @@ -667,6 +667,9 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
> #define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
> #define DM_CORELOG		0x00000008	/* In-memory log */
> 
> +/*for cluster raid1, use integrated flush to improve performance*/
> +#define DM_INTEGRATED_FLUSH		0x00000010
> +
> int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
> 					  uint32_t region_size,
> 					  unsigned clustered,
> diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
> index 752a44b..0a93028 100644
> --- a/libdm/libdm-deptree.c
> +++ b/libdm/libdm-deptree.c
> @@ -2054,6 +2054,7 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
> 				     char *params, size_t paramsize)
> {
> 	int block_on_error = 0;
> +	int integrated_flush = 0;
> 	int handle_errors = 0;
> 	int dm_log_userspace = 0;
> 	struct utsname uts;
> @@ -2107,6 +2108,9 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
> 		 */
> 		if (KERNEL_VERSION(kmaj, kmin, krel) >= KERNEL_VERSION(2, 6, 31))
> 			dm_log_userspace = 1;
> +
> +		if(seg->flags & DM_INTEGRATED_FLUSH)
> +			integrated_flush = 1;
> 	}
> 
> 	/* Region size */
> @@ -2164,6 +2168,10 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
> 	if (block_on_error)
> 		EMIT_PARAMS(pos, " block_on_error");
> 
> +	if (dm_log_userspace && DM_INTEGRATED_FLUSH)
> +		EMIT_PARAMS(pos, " integrated_flush");
> +
> +
> 	EMIT_PARAMS(pos, " %u ", seg->mirror_area_count);
> 
> 	if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
> -- 
> 1.7.3.4
> 
> --
> lvm-devel mailing list
> lvm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/lvm-devel




^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH
  2013-10-28 10:17     ` [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH dongmao zhang
@ 2013-10-30  1:48       ` Brassow Jonathan
  0 siblings, 0 replies; 716+ messages in thread
From: Brassow Jonathan @ 2013-10-30  1:48 UTC (permalink / raw)
  To: lvm-devel

Dongmao,

See in-line comments.

 brassow


On Oct 28, 2013, at 5:17 AM, dongmao zhang wrote:

> if integrated_flush is set. cmirrord will check the payload
> of FLUSH request.

No.  Who cares if 'integrated_flush' is set.  Just check if the kernel has sent you a flush that is integrated (i.e. has a payload) and do the appropriate thing.

> ---
> daemons/cmirrord/functions.c |   62 +++++++++++++++++++++++++++++++++---------
> daemons/cmirrord/local.c     |    9 +++++-
> lib/mirror/mirrored.c        |    2 +-
> 3 files changed, 58 insertions(+), 15 deletions(-)
> 
> diff --git a/daemons/cmirrord/functions.c b/daemons/cmirrord/functions.c
> index f6e0918..c534136 100644
> --- a/daemons/cmirrord/functions.c
> +++ b/daemons/cmirrord/functions.c
> @@ -75,6 +75,7 @@ struct log_c {
>                 FORCESYNC,      /* Force a sync to happen */
>         } sync;
> 
> +	uint32_t integrated_flush;

No need for 'integrated_flush'?

> 	uint32_t state;         /* current operational state of the log */
> 
> 	struct dm_list mark_list;
> @@ -362,7 +363,7 @@ static int find_disk_path(char *major_minor_str, char *path_rtn, int *unlink_pat
> 	// return r ? -errno : 0;
> }
> 
> -static int _clog_ctr(char *uuid, uint64_t luid,
> +static int _clog_ctr(char *uuid, uint64_t luid, uint32_t version,
> 		     int argc, char **argv, uint64_t device_size)

No need to change '_clog_ctr' (except to ignore the "integrated_flush" parameter).  As stated in my response to the kernel patch, you will not be sending back the additional string.

> {
> 	int i;
> @@ -373,6 +374,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
> 	struct log_c *lc = NULL;
> 	enum sync log_sync = DEFAULTSYNC;
> 	uint32_t block_on_error = 0;
> +	uint32_t integrated_flush = 0;
> 
> 	int disk_log;
> 	char disk_path[128];
> @@ -431,6 +433,8 @@ static int _clog_ctr(char *uuid, uint64_t luid,
> 			log_sync = NOSYNC;
> 		else if (!strcmp(argv[i], "block_on_error"))
> 			block_on_error = 1;
> +		else if (!strcmp(argv[i], "integrated_flush") && version > 2)
> +			integrated_flush = 1;

Yes, check for "integrated_flush" here because it is a valid parameter, but you don't actually need to set anything or do anything with it.  It was more for the kernel's benefit.

> 	}
> 
> 	lc = dm_zalloc(sizeof(*lc));
> @@ -451,6 +455,7 @@ static int _clog_ctr(char *uuid, uint64_t luid,
> 	lc->log_dev_failed = 0;
> 	strncpy(lc->uuid, uuid, DM_UUID_LEN);
> 	lc->luid = luid;
> +	lc->integrated_flush = integrated_flush;
> 
> 	if (get_log(lc->uuid, lc->luid) ||
> 	    get_pending_log(lc->uuid, lc->luid)) {
> @@ -552,6 +557,8 @@ static int clog_ctr(struct dm_ulog_request *rq)
> 	char *dev_size_str;
> 	uint64_t device_size;
> 
> +	struct log_c *tmplc = NULL;
> +
> 	/* Sanity checks */
> 	if (!rq->data_size) {
> 		LOG_ERROR("Received constructor request with no data");
> @@ -594,14 +601,17 @@ static int clog_ctr(struct dm_ulog_request *rq)
> 		return -EINVAL;
> 	}
> 
> -	r = _clog_ctr(rq->uuid, rq->luid, argc - 1, argv + 1, device_size);
> +	r = _clog_ctr(rq->uuid, rq->luid, rq->version, argc - 1, argv + 1, device_size);
> 
> 	/* We join the CPG when we resume */
> 
> 	/* No returning data */
> -	if ((rq->version > 1) && !strcmp(argv[0], "clustered-disk"))
> -		rq->data_size = sprintf(rq->data, "%s", argv[1]) + 1;
> -	else
> +	if ((rq->version > 1) && !strcmp(argv[0], "clustered-disk")) {
> +		rq->data_size = sprintf(rq->data, "%s", argv[1]);
> +		tmplc = get_pending_log(rq->uuid, rq->luid);
> +		if (tmplc && tmplc->integrated_flush)
> +			rq->data_size += sprintf(rq->data + rq->data_size, " %s", "integrated_flush") + 1;
> +	} else
> 		rq->data_size = 0;
> 
> 	if (r) {
> @@ -1027,14 +1037,17 @@ static int clog_in_sync(struct dm_ulog_request *rq)
> }
> 
> /*
> - * clog_flush
> - * @rq
> + * _clog_flush
> + * @lc
> + * @server
> + *
> + * real flush
>  *
> + * Returns: 0 on success, -EXXX on error
>  */
> -static int clog_flush(struct dm_ulog_request *rq, int server)
> +static int _clog_flush(struct log_c *lc, int server)
> {
> 	int r = 0;
> -	struct log_c *lc = get_log(rq->uuid, rq->luid);
> 
> 	if (!lc)
> 		return -EINVAL;
> @@ -1047,10 +1060,10 @@ static int clog_flush(struct dm_ulog_request *rq, int server)
> 	 * if we are the server.
> 	 */
> 	if (server && (lc->disk_fd >= 0)) {
> -		r = rq->error = write_log(lc);
> +		r = write_log(lc);
> 		if (r)
> 			LOG_ERROR("[%s] Error writing to disk log",
> -				  SHORT_UUID(lc->uuid));
> +				SHORT_UUID(lc->uuid));
> 		else 
> 			LOG_DBG("[%s] Disk log written", SHORT_UUID(lc->uuid));
> 	}
> @@ -1058,6 +1071,21 @@ static int clog_flush(struct dm_ulog_request *rq, int server)
> 	lc->touched = 0;
> 
> 	return r;
> +}
> +
> +
> +/*
> + * clog_flush
> + * @rq
> + *
> + */
> +static int clog_flush(struct dm_ulog_request *rq, int server)
> +{
> +	int r = 0;
> +	struct log_c *lc = get_log(rq->uuid, rq->luid);
> +
> +	r = rq->error = _clog_flush(lc, server);
> +	return r;
> 
> }
> 
> @@ -1113,7 +1141,7 @@ static int mark_region(struct log_c *lc, uint64_t region, uint32_t who)
>  *
>  * Returns: 0 on success, -EXXX on failure
>  */
> -static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator)
> +static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator, int server)
> {
> 	int r;
> 	int count;
> @@ -1139,6 +1167,14 @@ static int clog_mark_region(struct dm_ulog_request *rq, uint32_t originator)
> 
> 	rq->data_size = 0;
> 
> +	/* 
> +	 * if kernel support integrate flush, after marking region, 
> +	 * cmirrord should execute clog_flush automatically.
> +	 */
> +
> +	if(lc->integrated_flush)
> +		return _clog_flush(lc, server);
> +
> 	return 0;
> }
> 
> @@ -1676,7 +1712,7 @@ int do_request(struct clog_request *rq, int server)
> 		r = clog_flush(&rq->u_rq, server);
> 		break;
> 	case DM_ULOG_MARK_REGION:
> -		r = clog_mark_region(&rq->u_rq, rq->originator);
> +		r = clog_mark_region(&rq->u_rq, rq->originator, server);
> 		break;
> 	case DM_ULOG_CLEAR_REGION:
> 		r = clog_clear_region(&rq->u_rq, rq->originator);
> diff --git a/daemons/cmirrord/local.c b/daemons/cmirrord/local.c
> index 500f6dc..8b52556 100644
> --- a/daemons/cmirrord/local.c
> +++ b/daemons/cmirrord/local.c
> @@ -267,8 +267,15 @@ static int do_local_work(void *data __attribute__((unused)))
> 			break;
> 		}
> 		/* ELSE, fall through */
> -	case DM_ULOG_IS_CLEAN:
> 	case DM_ULOG_FLUSH:
> +		/*
> +		 * if it has payload, it must be a integrated flush.
> +		 * change the request_type to MARK_REGION. the clog_mark_region
> +		 * will flush automatically in the futhure
> +		 */
> +		if (rq->u_rq.data_size > 0)
> +			rq->u_rq.request_type = DM_ULOG_MARK_REGION;

Don't change the FLUSH into a MARK and have the MARK perform the FLUSH.  Instead, make the flush function determine if there is a payload and if so pass the payload along to mark.  Always perform the flush in the flush function.  This way, the code will handle old and new kernels automatically without having to check if 'integrated_flush' was set.  Additionally, it will handle failure conditions from the kernel (like, flush_one_by_one()) better.

> +	case DM_ULOG_IS_CLEAN:
> 	case DM_ULOG_MARK_REGION:
> 	case DM_ULOG_GET_RESYNC_WORK:
> 	case DM_ULOG_SET_REGION_SYNC:
> diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
> index 572f87e..4015116 100644
> --- a/lib/mirror/mirrored.c
> +++ b/lib/mirror/mirrored.c
> @@ -378,7 +378,7 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
> 	if (_block_on_error_available && !(seg->status & PVMOVE))
> 		log_flags |= DM_BLOCK_ON_ERROR;
> 
> -	/*clustered log support delay flush*/
> +	/*clustered log support integrated flush*/
> 	if(clustered)
> 		log_flags |= DM_INTEGRATED_FLUSH;
> 




^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 0/2] Optimization on intel HDMI detect and get_modes
       [not found] <yes>
                   ` (75 preceding siblings ...)
  2013-10-28 10:17 ` [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3] dongmao zhang
@ 2014-01-13  6:51 ` Ramalingam C
  2014-01-13  6:51   ` [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status Ramalingam C
                     ` (2 more replies)
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                   ` (14 subsequent siblings)
  91 siblings, 3 replies; 716+ messages in thread
From: Ramalingam C @ 2014-01-13  6:51 UTC (permalink / raw)
  To: intel-gfx, shashank.sharma

On slow HDMI hotplug out, because of the physical interface design,
DDC remains active for short duration even when HPD live status is
indicating the disconnect state. Because of this on VLV and HSW,
slow hotplug out events are not captured.

Hence this change uses the HPD pins live status to identify the
HDMI connector status.

Multiple forced detect and read modes calls come from
user space for different connectors, which can be handled
with connector status and previous detect event's cached EDID.
With this approach for hot pluggable displays, EDID retrieval
is required only when there is a real hot-plug events.

This change also includes:
1. A logic to optimize those multiple calls, by re-using
   cached data from previous detect and get_mode calls.
2. Store HDMI EDID, and re-use it in read modes.
3. Read live status reg to suppress spurious interrupts

These two changes will optimize the access to the DDC and also the
CPU cycles burned by intel_hdmi_detect and intel_hdmi_get_modes.

Ramalingam C (1):
  drm/i915: HDMI detection based on HPD pin live status

Shashank Sharma (1):
  drm/i915: Optimize EDID retrival on detect and get_modes

 drivers/gpu/drm/i915/intel_drv.h  |   12 +++
 drivers/gpu/drm/i915/intel_hdmi.c |  149 ++++++++++++++++++++++++++++++++-----
 2 files changed, 144 insertions(+), 17 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status
  2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
@ 2014-01-13  6:51   ` Ramalingam C
  2014-01-13  6:51   ` [PATCH 2/2] drm/i915: Optimize EDID retrival on detect and get_modes Ramalingam C
  2014-01-13  7:29   ` [PATCH 0/2] Optimization on intel HDMI " Daniel Vetter
  2 siblings, 0 replies; 716+ messages in thread
From: Ramalingam C @ 2014-01-13  6:51 UTC (permalink / raw)
  To: intel-gfx, shashank.sharma

This change uses the HPD pins live status bit from
South Display Engine(SDE) to identify the HDMI hotplug state.

On Soft HPD events (on automated test cases) only HPD pin will be
toggled to notify the HDMI state change. But physical DDC will
be alive. Similarly on slow HDMI hotplug out, because of the physical
interface design, DDC remains active for short duration even when
HPD live status is indicating the disconnect state. Because of this
on VLV and HSW, slow hotplug out events and soft HPDs are not captured.

Hence this patch uses the HPD pins live status to identify the
HDMI connector status and allows EDID retrival only when live status
is up.

Change-Id: I958b57fa139e52b45c8b349c861cb8eab7b67ae5
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |   10 +++++
 drivers/gpu/drm/i915/intel_hdmi.c |   87 ++++++++++++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 46aea6c..0f7d94b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -444,6 +444,16 @@ struct cxsr_latency {
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
 #define to_intel_plane(x) container_of(x, struct intel_plane, base)
 
+/* DisplayPort/HDMI Hotplug line status bit mask */
+#define VLV_HDMIB_HOTPLUG_LIVE_STATUS   (1 << 29)
+#define VLV_HDMIC_HOTPLUG_LIVE_STATUS   (1 << 28)
+#define VLV_HDMID_HOTPLUG_LIVE_STATUS   (1 << 27)
+
+/* DisplayPort/HDMI/DVI Hotplug line status bit mask */
+#define CORE_HDMIB_HOTPLUG_LIVE_STATUS  (1 << 21)
+#define CORE_HDMIC_HOTPLUG_LIVE_STATUS  (1 << 22)
+#define CORE_HDMID_HOTPLUG_LIVE_STATUS  (1 << 23)
+
 struct intel_hdmi {
 	u32 hdmi_reg;
 	int ddc_bus;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 6db0d9d..faeae3a 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -924,6 +924,61 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	return true;
 }
 
+static int get_hdmi_hotplug_live_status(struct drm_device *dev,
+					struct intel_hdmi *intel_hdmi)
+{
+	uint32_t bit, reg;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *intel_dig_port =
+				hdmi_to_dig_port(intel_hdmi);
+
+	DRM_DEBUG_KMS("Reading Live status");
+
+	/* Live status is available from Gen 6 onwards */
+	if (INTEL_INFO(dev)->gen < 6)
+		return connector_status_connected;
+
+	if (IS_VALLEYVIEW(dev)) {
+		switch (intel_dig_port->port) {
+		case PORT_B:
+			bit = VLV_HDMIB_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_C:
+			bit = VLV_HDMIC_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_D:
+			bit = VLV_HDMID_HOTPLUG_LIVE_STATUS;
+			break;
+		default:
+			DRM_ERROR("Unrecognized port is encountered\n");
+			return connector_status_unknown;
+		}
+		reg = I915_READ(PORT_HOTPLUG_STAT);
+
+	} else {
+		switch (intel_dig_port->port) {
+		case PORT_B:
+			bit = CORE_HDMIB_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_C:
+			bit = CORE_HDMIC_HOTPLUG_LIVE_STATUS;
+			break;
+		case PORT_D:
+			bit = CORE_HDMID_HOTPLUG_LIVE_STATUS;
+			break;
+		default:
+			DRM_ERROR("Unrecognized port is encountered\n");
+			return connector_status_unknown;
+		}
+
+		reg = I915_READ(SDEISR);
+	}
+
+	/* Return connector status */
+	return ((reg & bit) ?
+		connector_status_connected : connector_status_disconnected);
+}
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector, bool force)
 {
@@ -939,24 +994,32 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, drm_get_connector_name(connector));
 
+	status = get_hdmi_hotplug_live_status(dev, intel_hdmi);
+
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
 	intel_hdmi->rgb_quant_range_selectable = false;
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-						    intel_hdmi->ddc_bus));
 
-	if (edid) {
-		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
-			status = connector_status_connected;
-			if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI)
-				intel_hdmi->has_hdmi_sink =
+	if (status == connector_status_connected) {
+		edid = drm_get_edid(connector,
+				intel_gmbus_get_adapter(dev_priv,
+						intel_hdmi->ddc_bus));
+		if (edid) {
+			if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+				status = connector_status_connected;
+				if (intel_hdmi->force_audio !=
+							HDMI_AUDIO_OFF_DVI)
+					intel_hdmi->has_hdmi_sink =
 						drm_detect_hdmi_monitor(edid);
-			intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
-			intel_hdmi->rgb_quant_range_selectable =
-				drm_rgb_quant_range_selectable(edid);
+				intel_hdmi->has_audio =
+						drm_detect_monitor_audio(edid);
+				intel_hdmi->rgb_quant_range_selectable =
+					drm_rgb_quant_range_selectable(edid);
+			}
+			kfree(edid);
+		} else {
+			status = connector_status_disconnected;
 		}
-		kfree(edid);
 	}
 
 	if (status == connector_status_connected) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH 2/2] drm/i915: Optimize EDID retrival on detect and get_modes
  2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
  2014-01-13  6:51   ` [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status Ramalingam C
@ 2014-01-13  6:51   ` Ramalingam C
  2014-01-13  7:29   ` [PATCH 0/2] Optimization on intel HDMI " Daniel Vetter
  2 siblings, 0 replies; 716+ messages in thread
From: Ramalingam C @ 2014-01-13  6:51 UTC (permalink / raw)
  To: intel-gfx, shashank.sharma

From: Shashank Sharma <shashank.sharma@intel.com>

Multiple forced detect and read modes calls come from
user space for different connectors, which can be handled
with connector status and previous detect event's cached EDID.
With this approach for hot pluggable displays, EDID retrieval
is required only when there is a real hot-plug events.

This approach optimizes access to the DDC interface and also the
CPU cycles burned by intel_hdmi_detect and intel_hdmi_get_modes.

This patch contains:
1. A logic to optimize those multiple calls, by re-using
   cached data from previous detect and get_mode calls.
2. Store HDMI EDID, and re-use it in read modes.
3. Read live status reg to suppress spurious interrupts

Change-Id: Ia46cbe346dcc18ef11381eabcb157c5bcfd51322
Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |    2 ++
 drivers/gpu/drm/i915/intel_hdmi.c |   66 +++++++++++++++++++++++++++++++++----
 2 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0f7d94b..4f7f81f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -463,6 +463,8 @@ struct intel_hdmi {
 	bool has_audio;
 	enum hdmi_force_audio force_audio;
 	bool rgb_quant_range_selectable;
+	struct edid *edid;
+	uint32_t edid_mode_count;
 	void (*write_infoframe)(struct drm_encoder *encoder,
 				enum hdmi_infoframe_type type,
 				const void *frame, ssize_t len);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index faeae3a..2d008b7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -994,7 +994,14 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
 		      connector->base.id, drm_get_connector_name(connector));
 
+	/* If its forced detect call, dont read EDID again */
+	if (force && intel_hdmi->edid)
+		return connector->status;
+
 	status = get_hdmi_hotplug_live_status(dev, intel_hdmi);
+	/* Suppress spurious IRQ, if current status is same as live status*/
+	if (connector->status == status)
+		return connector->status;
 
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
@@ -1015,11 +1022,22 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 						drm_detect_monitor_audio(edid);
 				intel_hdmi->rgb_quant_range_selectable =
 					drm_rgb_quant_range_selectable(edid);
+
+				/* Free previously saved EDID and save new one
+				   for read modes. */
+				kfree(intel_hdmi->edid);
+				intel_hdmi->edid = edid;
+			} else {
+				kfree(edid);
+				DRM_ERROR("EDID is not in digital form ?\n");
 			}
-			kfree(edid);
 		} else {
-			status = connector_status_disconnected;
+			DRM_DEBUG_KMS("EDID read failed\n");
 		}
+
+		if (intel_hdmi->edid == NULL)
+			status = connector_status_disconnected;
+
 	}
 
 	if (status == connector_status_connected) {
@@ -1027,6 +1045,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
 			intel_hdmi->has_audio =
 				(intel_hdmi->force_audio == HDMI_AUDIO_ON);
 		intel_encoder->type = INTEL_OUTPUT_HDMI;
+	} else {
+		kfree(intel_hdmi->edid);
+		intel_hdmi->edid = NULL;
 	}
 
 	return status;
@@ -1036,14 +1057,44 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct drm_i915_private *dev_priv = connector->dev->dev_private;
+	struct edid *edid = intel_hdmi->edid;
+	struct drm_display_mode *mode = NULL;
+	int count = 0;
 
-	/* We should parse the EDID data and find out if it's an HDMI sink so
-	 * we can send audio to it.
-	 */
+	/* No need to read modes if panel is not connected */
+	if (connector->status != connector_status_connected)
+		return 0;
 
-	return intel_ddc_get_modes(connector,
+	/* Need not read modes again if previously read modes are
+	   available and display is consistent */
+	if (intel_hdmi->edid) {
+		list_for_each_entry(mode, &connector->modes, head) {
+			if (mode) {
+				/* Setting the MODE_OK for all sanitized modes*/
+				mode->status = MODE_OK;
+				count++;
+			}
+		}
+		/* If modes are availlable, no need to read again */
+		if (count)
+			goto out;
+	}
+
+	/* EDID was saved in detect, re-use that if available, avoid
+	   reading EDID everytime */
+	if (edid) {
+		drm_mode_connector_update_edid_property(connector, edid);
+		count = drm_add_edid_modes(connector, edid);
+		drm_edid_to_eld(connector, edid);
+	} else {
+		count = intel_ddc_get_modes(connector,
 				   intel_gmbus_get_adapter(dev_priv,
-							   intel_hdmi->ddc_bus));
+						   intel_hdmi->ddc_bus));
+	}
+
+out:
+	intel_hdmi->edid_mode_count = count;
+	return count;
 }
 
 static bool
@@ -1381,6 +1432,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
 
 	intel_dig_port->port = port;
 	intel_dig_port->hdmi.hdmi_reg = hdmi_reg;
+	intel_dig_port->hdmi.edid = NULL;
 	intel_dig_port->dp.output_reg = 0;
 
 	intel_hdmi_init_connector(intel_dig_port, intel_connector);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
  2014-01-13  6:51   ` [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status Ramalingam C
  2014-01-13  6:51   ` [PATCH 2/2] drm/i915: Optimize EDID retrival on detect and get_modes Ramalingam C
@ 2014-01-13  7:29   ` Daniel Vetter
  2014-01-13  9:39     ` Sharma, Shashank
  2 siblings, 1 reply; 716+ messages in thread
From: Daniel Vetter @ 2014-01-13  7:29 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, shashank.sharma

On Mon, Jan 13, 2014 at 12:21:52PM +0530, Ramalingam C wrote:
> On slow HDMI hotplug out, because of the physical interface design,
> DDC remains active for short duration even when HPD live status is
> indicating the disconnect state. Because of this on VLV and HSW,
> slow hotplug out events are not captured.
> 
> Hence this change uses the HPD pins live status to identify the
> HDMI connector status.
> 
> Multiple forced detect and read modes calls come from
> user space for different connectors, which can be handled
> with connector status and previous detect event's cached EDID.
> With this approach for hot pluggable displays, EDID retrieval
> is required only when there is a real hot-plug events.
> 
> This change also includes:
> 1. A logic to optimize those multiple calls, by re-using
>    cached data from previous detect and get_mode calls.
> 2. Store HDMI EDID, and re-use it in read modes.
> 3. Read live status reg to suppress spurious interrupts
> 
> These two changes will optimize the access to the DDC and also the
> CPU cycles burned by intel_hdmi_detect and intel_hdmi_get_modes.
> 
> Ramalingam C (1):
>   drm/i915: HDMI detection based on HPD pin live status
> 
> Shashank Sharma (1):
>   drm/i915: Optimize EDID retrival on detect and get_modes
> 
>  drivers/gpu/drm/i915/intel_drv.h  |   12 +++
>  drivers/gpu/drm/i915/intel_hdmi.c |  149 ++++++++++++++++++++++++++++++++-----
>  2 files changed, 144 insertions(+), 17 deletions(-)

Nak.

We've had code to use the hpd live status register on all platforms, but
had to take it out again on all platforms due to broken hardware: The live
status simply doesn't work sometimes, resulting in angry users reporting
black screens. So as-is patch 1 can't go into upstream. I know that it'd
be really useful if we could rely on the hpd live status but, but thus far
I couldn't come up with a good idea to make it work. Git history should
have all the details.

Also note that machines with noisy interrupt lines (see the interrupt
storm handling code in i915_irq.c) complicate this further.

This means that patch 2 is also a no-go since we really can't rely upon
the hpd stuff for hdmi detection. But we can save EDID caching if we
automatically invalidate the cached edid after 1-2 seconds or the next hpd
interrupt (whichever is first). 1-2 seconds should be long enough for
userspace to read the EDID a few times and change the output
configuration, but not long enough for users to get pissed. Note that the
caching interval should be shorter than the polling interval, which we use
as a fallback if the hpd lines are noise and atm is at 10 seconds.

Also this EDID caching and invalidation code should imo be a generic
helper with data structures (for the invalidation work and cached edid) in
struct intel_output. That way we can also wire it up for e.g. VGA or any
other output that'll benefit from EDID caching.

Aside: On DP the hpd pins seem to be reliable thus far, but I'm not sure
whether that's just lack of test coverage (since DP screens are less
common) or because it actually works ...

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-01-13  7:29   ` [PATCH 0/2] Optimization on intel HDMI " Daniel Vetter
@ 2014-01-13  9:39     ` Sharma, Shashank
  2014-01-13 13:26       ` Daniel Vetter
  0 siblings, 1 reply; 716+ messages in thread
From: Sharma, Shashank @ 2014-01-13  9:39 UTC (permalink / raw)
  To: Daniel Vetter, C, Ramalingam; +Cc: intel-gfx

Hello Daniel

Thanks a lot for your time, for reviewing the changes, and giving us some pointers. 
Both me and Ramalingam are designing this together, and we discussed about these changes and your suggestions. 
There are few things we would like to discuss about. Please correct us if some of our understanding is not proper. 

Those two patches provide two solution. 
1. Support for soft HPD, and slow removal of HDMI (when the DDC channel can still get the EDID).    
2. Try to reduce the EDID reads over DDC channel for get connector and fill mode calls, by caching EDID, and using it until next HPD comes.

Patch 2: Reduce the EDID read over DDC channel
We are caching the EDID at every HPD up, on HDMI detect calls, and we are freeing it on subsequent HDMI disconnect calls.

The design philosophy here is, to maintain a state machine of HDMI connector status, and differentiate between IOCTL detect calls and HPD detect calls. 
If there is a detect() or get_modes() call due to any of the IOCTL, which makes sure that input variable force=1, we just use the cached EDID, to serve this calls. 
But if the detect call is coming from HPD work function, due to a HPD plug-out, we remove/invalidate the old cached EDID, and cache the new EDID, on subsequent HDMI plug-in. 
>From here, the same state machine follows. 

Can you please let us know, why do you think that we should invalidate the cached EDID after 1-2 seconds ?

Note: In this same patch, there is additional optimization, which you pointed out, where we check if the connector->status is same as live status. 
This can be removed independently, as you suggested.   

About patch 1: 
We have done some local experiments and we came to know that for VLV and HSW boards, we can rely on the live status, if we give it some time to settle (~300ms). 
Probably, we need to modify this patch, as you suggested, until it becomes handy to be used reliably. We are on it, and will send another patch soon.
 
But if somehow we are able to get some consistent results from live status, do you think it would be worth accepting this change, so that it can handle soft HPDs and automation testing. 
Because I believe we will face this problem whenever we are trying to test something from automation, where the physical device is not removed, and DDC channel is up always. 

Regards
Shashank 

-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Monday, January 13, 2014 12:59 PM
To: C, Ramalingam
Cc: intel-gfx@lists.freedesktop.org; Sharma, Shashank
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

On Mon, Jan 13, 2014 at 12:21:52PM +0530, Ramalingam C wrote:
> On slow HDMI hotplug out, because of the physical interface design, 
> DDC remains active for short duration even when HPD live status is 
> indicating the disconnect state. Because of this on VLV and HSW, slow 
> hotplug out events are not captured.
> 
> Hence this change uses the HPD pins live status to identify the HDMI 
> connector status.
> 
> Multiple forced detect and read modes calls come from user space for 
> different connectors, which can be handled with connector status and 
> previous detect event's cached EDID.
> With this approach for hot pluggable displays, EDID retrieval is 
> required only when there is a real hot-plug events.
> 
> This change also includes:
> 1. A logic to optimize those multiple calls, by re-using
>    cached data from previous detect and get_mode calls.
> 2. Store HDMI EDID, and re-use it in read modes.
> 3. Read live status reg to suppress spurious interrupts
> 
> These two changes will optimize the access to the DDC and also the CPU 
> cycles burned by intel_hdmi_detect and intel_hdmi_get_modes.
> 
> Ramalingam C (1):
>   drm/i915: HDMI detection based on HPD pin live status
> 
> Shashank Sharma (1):
>   drm/i915: Optimize EDID retrival on detect and get_modes
> 
>  drivers/gpu/drm/i915/intel_drv.h  |   12 +++
>  drivers/gpu/drm/i915/intel_hdmi.c |  149 
> ++++++++++++++++++++++++++++++++-----
>  2 files changed, 144 insertions(+), 17 deletions(-)

Nak.

We've had code to use the hpd live status register on all platforms, but had to take it out again on all platforms due to broken hardware: The live status simply doesn't work sometimes, resulting in angry users reporting black screens. So as-is patch 1 can't go into upstream. I know that it'd be really useful if we could rely on the hpd live status but, but thus far I couldn't come up with a good idea to make it work. Git history should have all the details.

Also note that machines with noisy interrupt lines (see the interrupt storm handling code in i915_irq.c) complicate this further.

This means that patch 2 is also a no-go since we really can't rely upon the hpd stuff for hdmi detection. But we can save EDID caching if we automatically invalidate the cached edid after 1-2 seconds or the next hpd interrupt (whichever is first). 1-2 seconds should be long enough for userspace to read the EDID a few times and change the output configuration, but not long enough for users to get pissed. Note that the caching interval should be shorter than the polling interval, which we use as a fallback if the hpd lines are noise and atm is at 10 seconds.

Also this EDID caching and invalidation code should imo be a generic helper with data structures (for the invalidation work and cached edid) in struct intel_output. That way we can also wire it up for e.g. VGA or any other output that'll benefit from EDID caching.

Aside: On DP the hpd pins seem to be reliable thus far, but I'm not sure whether that's just lack of test coverage (since DP screens are less
common) or because it actually works ...

Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-01-13  9:39     ` Sharma, Shashank
@ 2014-01-13 13:26       ` Daniel Vetter
  2014-01-13 17:19         ` Sharma, Shashank
  0 siblings, 1 reply; 716+ messages in thread
From: Daniel Vetter @ 2014-01-13 13:26 UTC (permalink / raw)
  To: Sharma, Shashank; +Cc: intel-gfx

On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank
<shashank.sharma@intel.com> wrote:
> Thanks a lot for your time, for reviewing the changes, and giving us some pointers.
> Both me and Ramalingam are designing this together, and we discussed about these changes and your suggestions.
> There are few things we would like to discuss about. Please correct us if some of our understanding is not proper.

First something I've forgotten in the original mail: Overall your
patches look really nice and the commit messages and cover letter have
been excellent. Unfortunately you've run into one of the nastier cases
of "reality just wont agree with the spec" :(

> Those two patches provide two solution.
> 1. Support for soft HPD, and slow removal of HDMI (when the DDC channel can still get the EDID).
> 2. Try to reduce the EDID reads over DDC channel for get connector and fill mode calls, by caching EDID, and using it until next HPD comes.
>
> Patch 2: Reduce the EDID read over DDC channel
> We are caching the EDID at every HPD up, on HDMI detect calls, and we are freeing it on subsequent HDMI disconnect calls.
>
> The design philosophy here is, to maintain a state machine of HDMI connector status, and differentiate between IOCTL detect calls and HPD detect calls.
> If there is a detect() or get_modes() call due to any of the IOCTL, which makes sure that input variable force=1, we just use the cached EDID, to serve this calls.
> But if the detect call is coming from HPD work function, due to a HPD plug-out, we remove/invalidate the old cached EDID, and cache the new EDID, on subsequent HDMI plug-in.
> From here, the same state machine follows.
>
> Can you please let us know, why do you think that we should invalidate the cached EDID after 1-2 seconds ?

Because there are machines out there where hpd never happens. So if
you keep onto the cached value forever userspace will never notice a
change in output configuration. Of course hotplug handling won't work,
but at least users can still manually probe outputs. By
unconditionally using the cached edid from ioctls you break this use
case. Yes, such machines are broken, but we need to keep them working
anyway.

Also in my experience all machines are affected, we have examples
covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet
since we don't rely on the hpd bits any more (and so won't see bug
reports any more).

Generally if you use the hpd stuff your code must be designed under
the assumption that hpd is completely unreliably. We've seen anything
from random noise, flat-out not-working at all, stuck bits and
unstable hpd values that occasionally flip-flop. So you can't rely on
it at all.

> Note: In this same patch, there is additional optimization, which you pointed out, where we check if the connector->status is same as live status.
> This can be removed independently, as you suggested.

Hm, where have I pointed this out? Some other mail on internal discussions?

> About patch 1:
> We have done some local experiments and we came to know that for VLV and HSW boards, we can rely on the live status, if we give it some time to settle (~300ms).
> Probably, we need to modify this patch, as you suggested, until it becomes handy to be used reliably. We are on it, and will send another patch soon.
>
> But if somehow we are able to get some consistent results from live status, do you think it would be worth accepting this change, so that it can handle soft HPDs and automation testing.
> Because I believe we will face this problem whenever we are trying to test something from automation, where the physical device is not removed, and DDC channel is up always.

It's very well possible that all the platforms you have, but
experience says that some OEM will horrible screw this up. At least
they've consistently botched this in the past on occasional machines.

Now the ghost hdmi detection on slow removal is obviously not great,
but we can't use the hpd bits to fix this. One approach would be.
1. Upon hpd interrupt do an immediate probe of the connector. This way
we'll have good userspace experience if the unplug happens quickly and
the hw works.
2. Re-probe with a 1s delay to catch slow-uplugs. The current output
probing helpers are clever enough already that if a state-change
happens to be detected a uevent will be generate, irrespective of the
source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).

Note that we already track the hpd interrupts on a per-source basis,
so doing the re-poll shouldn't be costly. Maybe do the re-poll as part
of the EDID invalidation to avoid stalling userspace.

But you can't rely upon the hpd pins unfortunately :(

This way we should be able to implement the 2 features you want, even
on unreliable hw.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-01-13 13:26       ` Daniel Vetter
@ 2014-01-13 17:19         ` Sharma, Shashank
  2014-04-09  6:19           ` Wang, Quanxian
  0 siblings, 1 reply; 716+ messages in thread
From: Sharma, Shashank @ 2014-01-13 17:19 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Thanks again for this explanation Daniel. 
We will work on your suggestions and come up with a new patch. 

Regards
Shashank  / Ramalingam
-----Original Message-----
From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Monday, January 13, 2014 6:57 PM
To: Sharma, Shashank
Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank <shashank.sharma@intel.com> wrote:
> Thanks a lot for your time, for reviewing the changes, and giving us some pointers.
> Both me and Ramalingam are designing this together, and we discussed about these changes and your suggestions.
> There are few things we would like to discuss about. Please correct us if some of our understanding is not proper.

First something I've forgotten in the original mail: Overall your patches look really nice and the commit messages and cover letter have been excellent. Unfortunately you've run into one of the nastier cases of "reality just wont agree with the spec" :(

> Those two patches provide two solution.
> 1. Support for soft HPD, and slow removal of HDMI (when the DDC channel can still get the EDID).
> 2. Try to reduce the EDID reads over DDC channel for get connector and fill mode calls, by caching EDID, and using it until next HPD comes.
>
> Patch 2: Reduce the EDID read over DDC channel We are caching the EDID 
> at every HPD up, on HDMI detect calls, and we are freeing it on subsequent HDMI disconnect calls.
>
> The design philosophy here is, to maintain a state machine of HDMI connector status, and differentiate between IOCTL detect calls and HPD detect calls.
> If there is a detect() or get_modes() call due to any of the IOCTL, which makes sure that input variable force=1, we just use the cached EDID, to serve this calls.
> But if the detect call is coming from HPD work function, due to a HPD plug-out, we remove/invalidate the old cached EDID, and cache the new EDID, on subsequent HDMI plug-in.
> From here, the same state machine follows.
>
> Can you please let us know, why do you think that we should invalidate the cached EDID after 1-2 seconds ?

Because there are machines out there where hpd never happens. So if you keep onto the cached value forever userspace will never notice a change in output configuration. Of course hotplug handling won't work, but at least users can still manually probe outputs. By unconditionally using the cached edid from ioctls you break this use case. Yes, such machines are broken, but we need to keep them working anyway.

Also in my experience all machines are affected, we have examples covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet since we don't rely on the hpd bits any more (and so won't see bug reports any more).

Generally if you use the hpd stuff your code must be designed under the assumption that hpd is completely unreliably. We've seen anything from random noise, flat-out not-working at all, stuck bits and unstable hpd values that occasionally flip-flop. So you can't rely on it at all.

> Note: In this same patch, there is additional optimization, which you pointed out, where we check if the connector->status is same as live status.
> This can be removed independently, as you suggested.

Hm, where have I pointed this out? Some other mail on internal discussions?

> About patch 1:
> We have done some local experiments and we came to know that for VLV and HSW boards, we can rely on the live status, if we give it some time to settle (~300ms).
> Probably, we need to modify this patch, as you suggested, until it becomes handy to be used reliably. We are on it, and will send another patch soon.
>
> But if somehow we are able to get some consistent results from live status, do you think it would be worth accepting this change, so that it can handle soft HPDs and automation testing.
> Because I believe we will face this problem whenever we are trying to test something from automation, where the physical device is not removed, and DDC channel is up always.

It's very well possible that all the platforms you have, but experience says that some OEM will horrible screw this up. At least they've consistently botched this in the past on occasional machines.

Now the ghost hdmi detection on slow removal is obviously not great, but we can't use the hpd bits to fix this. One approach would be.
1. Upon hpd interrupt do an immediate probe of the connector. This way we'll have good userspace experience if the unplug happens quickly and the hw works.
2. Re-probe with a 1s delay to catch slow-uplugs. The current output probing helpers are clever enough already that if a state-change happens to be detected a uevent will be generate, irrespective of the source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).

Note that we already track the hpd interrupts on a per-source basis, so doing the re-poll shouldn't be costly. Maybe do the re-poll as part of the EDID invalidation to avoid stalling userspace.

But you can't rely upon the hpd pins unfortunately :(

This way we should be able to implement the 2 features you want, even on unreliable hw.

Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
       [not found] <yes>
                   ` (76 preceding siblings ...)
  2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
@ 2014-02-07 23:23 ` Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
                     ` (7 more replies)
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                   ` (13 subsequent siblings)
  91 siblings, 8 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

 - Resending since I missed some in the CC

This patch series add support for keystone2 SoC and K2HK EVM.

Following patches were reviewed before in this list and v1 of the
same is send with review comments incorporated:-
  - tools: mkimage: add support for gpimage format
  - arm: add support for arch timer
  - NAND: DaVinci: allow forced disable of subpage writes

The patch below is added as a seperate patch based on comments:-
   - tools: sort the entries in Makefile

Murali Karicheri (5):
  tools: sort the entries in Makefile
  tools: mkimage: add support for gpimage format
  NAND: DaVinci: allow forced disable of subpage writes
  k2hk: add support for k2hk SOC and EVM
  keystone2: net: add keystone ethernet driver

Vitaly Andrianov (2):
  fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  arm: add support for arch timer

 Makefile                                           |   19 +
 README                                             |    5 +
 arch/arm/cpu/armv7/keystone/Makefile               |   19 +
 arch/arm/cpu/armv7/keystone/aemif.c                |   79 ++
 arch/arm/cpu/armv7/keystone/clock-k2hk.c           |  106 +++
 arch/arm/cpu/armv7/keystone/clock.c                |  200 +++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  139 ++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 +++
 arch/arm/cpu/armv7/keystone/config.mk              |   14 +
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++
 arch/arm/cpu/armv7/keystone/init.c                 |   49 ++
 arch/arm/cpu/armv7/keystone/keystone_nav.c         |  377 +++++++++
 arch/arm/cpu/armv7/keystone/lowlevel_init.S        |   13 +
 arch/arm/cpu/armv7/keystone/msmc.c                 |   69 ++
 arch/arm/cpu/armv7/keystone/psc.c                  |  240 ++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 +
 arch/arm/include/asm/arch-keystone/clock_defs.h    |   97 +++
 arch/arm/include/asm/arch-keystone/emac_defs.h     |  255 ++++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   75 ++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  143 ++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  174 ++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   86 ++
 arch/arm/include/asm/arch-keystone/keystone_nav.h  |  194 +++++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 +
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   91 +++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 arch/arm/lib/Makefile                              |    1 +
 arch/arm/lib/arch_timer.c                          |   58 ++
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |   56 ++
 board/ti/k2hk_evm/board.c                          |  311 +++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 ++++++
 boards.cfg                                         |    1 +
 common/image-fdt.c                                 |    5 +
 common/image.c                                     |    1 +
 drivers/i2c/Makefile                               |    1 +
 drivers/i2c/keystone_i2c.c                         |  372 +++++++++
 drivers/mtd/nand/davinci_nand.c                    |    3 +
 drivers/net/Makefile                               |    1 +
 drivers/net/keystone_net.c                         |  857 ++++++++++++++++++++
 drivers/serial/ns16550.c                           |    8 +
 include/configs/k2hk_evm.h                         |  259 ++++++
 include/fdt_support.h                              |    1 +
 include/image.h                                    |    1 +
 tools/Makefile                                     |   20 +-
 tools/gpheader.h                                   |   40 +
 tools/gpimage-common.c                             |   80 ++
 tools/gpimage.c                                    |   77 ++
 tools/imagetool.c                                  |    2 +
 tools/imagetool.h                                  |    1 +
 tools/omapimage.c                                  |  104 +--
 tools/omapimage.h                                  |    5 -
 54 files changed, 5295 insertions(+), 100 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock-k2hk.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c
 create mode 100644 arch/arm/cpu/armv7/keystone/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 arch/arm/lib/arch_timer.c
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 drivers/i2c/keystone_i2c.c
 create mode 100644 drivers/net/keystone_net.c
 create mode 100644 include/configs/k2hk_evm.h
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-10 21:25     ` Tom Rini
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 2/7] tools: sort the entries in Makefile Murali Karicheri
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

The keystone2 SOC requires to fix all 32 bit aliased addresses
to their 36 physical format. This has to happen after all fdt
nodes are added or modified.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 - Resending with some more in cc
 common/image-fdt.c    |    5 +++++
 include/fdt_support.h |    1 +
 2 files changed, 6 insertions(+)

diff --git a/common/image-fdt.c b/common/image-fdt.c
index 6f9ce7d..ee4dd6f 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
 	if (!ft_verify_fdt(blob))
 		return -1;
 
+#ifdef CONFIG_SOC_K2HK
+	if (IMAAGE_OF_BOARD_SETUP)
+		ft_board_setup_ex(blob, gd->bd);
+#endif
+
 	return 0;
 }
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 9871e2f..4c1416d 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
 #endif
 
 void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);
 void ft_cpu_setup(void *blob, bd_t *bd);
 void ft_pci_setup(void *blob, bd_t *bd);
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 2/7] tools: sort the entries in Makefile
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 3/7 v1] tools: mkimage: add support for gpimage format Murali Karicheri
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

The NOPED_OBJ_FILES, dumpimage and mkimage object file
entries are to be kept sorted. This patch fix this issue.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - Resend with some more in cc
 - As per review comments
 tools/Makefile |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/Makefile b/tools/Makefile
index 328cea3..3c719b3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,10 +77,10 @@ NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
 NOPED_OBJ_FILES-y += dumpimage.o
 NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += image-host.o
 NOPED_OBJ_FILES-y += imximage.o
 NOPED_OBJ_FILES-y += kwbimage.o
-NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
 NOPED_OBJ_FILES-y += mxsimage.o
@@ -88,8 +88,8 @@ NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += os_support.o
 NOPED_OBJ_FILES-y += pblimage.o
 NOPED_OBJ_FILES-y += proftool.o
-NOPED_OBJ_FILES-y += ublimage.o
 NOPED_OBJ_FILES-y += relocate-rela.o
+NOPED_OBJ_FILES-y += ublimage.o
 OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
 OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
 OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
@@ -209,14 +209,14 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(FIT_SIG_OBJS) \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
+			$(obj)dumpimage.o \
 			$(obj)fit_image.o \
-			$(obj)image-fit.o \
 			$(obj)image.o \
-			$(obj)image-host.o \
 			$(obj)imagetool.o \
+			$(obj)image-fit.o \
+			$(obj)image-host.o \
 			$(obj)imximage.o \
 			$(obj)kwbimage.o \
-			$(obj)dumpimage.o \
 			$(obj)md5.o \
 			$(obj)mxsimage.o \
 			$(obj)omapimage.o \
@@ -239,10 +239,10 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
 			$(obj)fit_image.o \
-			$(obj)image-fit.o \
-			$(obj)image-host.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
+			$(obj)image-host.o \
+			$(obj)image-fit.o \
 			$(obj)imximage.o \
 			$(obj)kwbimage.o \
 			$(obj)md5.o \
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 3/7 v1] tools: mkimage: add support for gpimage format
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 2/7] tools: sort the entries in Makefile Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 4/7 v1] arm: add support for arch timer Murali Karicheri
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

This patch add support for gpimage format as a preparatory
patch for porting u-boot for keystone2 devices and is
based on omapimage format. It re-uses gph header to store the
size and loadaddr as done in omapimage.c

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - Resending with some more in cc
 - Addressed review comments against initial version
 - refactored the code to avoid redundant code
 common/image.c         |    1 +
 include/image.h        |    1 +
 tools/Makefile         |    6 +++
 tools/gpheader.h       |   40 +++++++++++++++++++
 tools/gpimage-common.c |   80 +++++++++++++++++++++++++++++++++++++
 tools/gpimage.c        |   77 +++++++++++++++++++++++++++++++++++
 tools/imagetool.c      |    2 +
 tools/imagetool.h      |    1 +
 tools/omapimage.c      |  104 ++++++++----------------------------------------
 tools/omapimage.h      |    5 ---
 10 files changed, 224 insertions(+), 93 deletions(-)
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c

diff --git a/common/image.c b/common/image.c
index ae95c3f..cb5c656 100644
--- a/common/image.c
+++ b/common/image.c
@@ -124,6 +124,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
 	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
 	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
+	{	IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
 	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
 	{	IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
 	{	IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
diff --git a/include/image.h b/include/image.h
index 7de2bb2..0a3d346 100644
--- a/include/image.h
+++ b/include/image.h
@@ -214,6 +214,7 @@ struct lmb;
 #define IH_TYPE_KERNEL_NOLOAD	14	/* OS Kernel Image, can run from any load address */
 #define IH_TYPE_PBLIMAGE	15	/* Freescale PBL Boot Image	*/
 #define IH_TYPE_MXSIMAGE	16	/* Freescale MXSBoot Image	*/
+#define IH_TYPE_GPIMAGE		17	/* TI Keystone GPHeader Image	*/
 
 /*
  * Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index 3c719b3..421aba5 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,6 +77,8 @@ NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
 NOPED_OBJ_FILES-y += dumpimage.o
 NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += gpimage.o
+NOPED_OBJ_FILES-y += gpimage-common.o
 NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += image-host.o
 NOPED_OBJ_FILES-y += imximage.o
@@ -211,6 +213,8 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(obj)default_image.o \
 			$(obj)dumpimage.o \
 			$(obj)fit_image.o \
+			$(obj)gpimage.o \
+			$(obj)gpimage-common.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
 			$(obj)image-fit.o \
@@ -239,6 +243,8 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
 			$(obj)fit_image.o \
+			$(obj)gpimage.o \
+			$(obj)gpimage-common.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
 			$(obj)image-host.o \
diff --git a/tools/gpheader.h b/tools/gpheader.h
new file mode 100644
index 0000000..63a28a2
--- /dev/null
+++ b/tools/gpheader.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c. Include this common
+ * header file
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GPIMAGE_H_
+#define _GPIMAGE_H_
+
+/* common headers for gpimage and omapimage formats */
+struct gp_header {
+	uint32_t size;
+	uint32_t load_addr;
+};
+#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header))
+
+/* common functions across gpimage and omapimage handlers */
+int valid_gph_size(uint32_t size);
+int valid_gph_load_addr(uint32_t load_addr);
+int gph_verify_header(struct gp_header *gph, int be);
+void gph_print_header(const struct gp_header *gph, int be);
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+			int be);
+int gpimage_check_params(struct image_tool_params *params);
+#endif
diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c
new file mode 100644
index 0000000..b343a3a
--- /dev/null
+++ b/tools/gpimage-common.c
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c.
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+/* Helper to convert size and load_addr to big endian */
+void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
+{
+	*gph_size = cpu_to_be32(*gph_size);
+	*gph_load_addr = cpu_to_be32(*gph_load_addr);
+}
+
+int gph_verify_header(struct gp_header *gph, int be)
+{
+	uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+	if (be)
+		to_be32(&gph_size, &gph_load_addr);
+
+	if (!gph_size || !gph_load_addr)
+		return -1;
+
+	return 0;
+}
+
+void gph_print_header(const struct gp_header *gph, int be)
+{
+	uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+	if (be)
+		to_be32(&gph_size, &gph_load_addr);
+
+	if (!gph_size) {
+		fprintf(stderr, "Error: invalid image size %x\n", gph_size);
+		exit(EXIT_FAILURE);
+	}
+
+	if (!gph_load_addr) {
+		fprintf(stderr, "Error: invalid image load address %x\n",
+			gph_load_addr);
+		exit(EXIT_FAILURE);
+	}
+	printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+}
+
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+	int be)
+{
+	gph->size = size;
+	gph->load_addr = load_addr;
+	if (be)
+		to_be32(&gph->size, &gph->load_addr);
+}
+
+int gpimage_check_params(struct image_tool_params *params)
+{
+	return	(params->dflag && (params->fflag || params->lflag)) ||
+		(params->fflag && (params->dflag || params->lflag)) ||
+		(params->lflag && (params->dflag || params->fflag));
+}
diff --git a/tools/gpimage.c b/tools/gpimage.c
new file mode 100644
index 0000000..1cabb5b
--- /dev/null
+++ b/tools/gpimage.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Add gpimage format for keystone devices to format spl image. This is
+ * Based on omapimage.c
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+static uint8_t gpimage_header[GPIMAGE_HDR_SIZE];
+
+/* to be in keystone gpimage */
+static int gpimage_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_GPIMAGE)
+		return EXIT_SUCCESS;
+	return EXIT_FAILURE;
+}
+
+static int gpimage_verify_header(unsigned char *ptr, int image_size,
+			struct image_tool_params *params)
+{
+	struct gp_header *gph = (struct gp_header *)ptr;
+
+	return gph_verify_header(gph, 1);
+}
+
+static void gpimage_print_header(const void *ptr)
+{
+	const struct gp_header *gph = (struct gp_header *)ptr;
+
+	gph_print_header(gph, 1);
+}
+
+static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct image_tool_params *params)
+{
+	struct gp_header *gph = (struct gp_header *)ptr;
+
+	gph_set_header(gph, sbuf->st_size - GPIMAGE_HDR_SIZE, params->addr, 1);
+}
+
+/*
+ * gpimage parameters
+ */
+static struct image_type_params gpimage_params = {
+	.name		= "TI KeyStone GP Image support",
+	.header_size	= GPIMAGE_HDR_SIZE,
+	.hdr		= (void *)&gpimage_header,
+	.check_image_type = gpimage_check_image_types,
+	.verify_header	= gpimage_verify_header,
+	.print_header	= gpimage_print_header,
+	.set_header	= gpimage_set_header,
+	.check_params	= gpimage_check_params,
+};
+
+void init_gpimage_type(void)
+{
+	register_image_type(&gpimage_params);
+}
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 29d2189..da72115 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register)
 	init_ubl_image_type();
 	/* Init Davinci AIS support */
 	init_ais_image_type();
+	/* Init TI Keystone boot image generation/list support */
+	init_gpimage_type();
 }
 
 /*
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c2c9aea..a3e9d30 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -167,6 +167,7 @@ void init_mxs_image_type(void);
 void init_fit_image_type(void);
 void init_ubl_image_type(void);
 void init_omap_image_type(void);
+void init_gpimage_type(void);
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
 
diff --git a/tools/omapimage.c b/tools/omapimage.c
index d59bc4d..1e0c164 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -15,57 +15,24 @@
  */
 
 #include "imagetool.h"
+#include <compiler.h>
 #include <image.h>
+#include "gpheader.h"
 #include "omapimage.h"
 
 /* Header size is CH header rounded up to 512 bytes plus GP header */
 #define OMAP_CH_HDR_SIZE 512
-#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
-#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
+#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)
 
 static int do_swap32 = 0;
 
-static uint32_t omapimage_swap32(uint32_t data)
-{
-	uint32_t result = 0;
-	result  = (data & 0xFF000000) >> 24;
-	result |= (data & 0x00FF0000) >> 8;
-	result |= (data & 0x0000FF00) << 8;
-	result |= (data & 0x000000FF) << 24;
-	return result;
-}
-
 static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
 
 static int omapimage_check_image_types(uint8_t type)
 {
 	if (type == IH_TYPE_OMAPIMAGE)
 		return EXIT_SUCCESS;
-	else {
-		return EXIT_FAILURE;
-	}
-}
-
-/*
- * Only the simplest image type is currently supported:
- * TOC pointing to CHSETTINGS
- * TOC terminator
- * CHSETTINGS
- *
- * padding to OMAP_CH_HDR_SIZE bytes
- *
- * gp header
- *   size
- *   load_addr
- */
-static int valid_gph_size(uint32_t size)
-{
-	return size;
-}
-
-static int valid_gph_load_addr(uint32_t load_addr)
-{
-	return load_addr;
+	return EXIT_FAILURE;
 }
 
 static int omapimage_verify_header(unsigned char *ptr, int image_size,
@@ -73,13 +40,13 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
 {
 	struct ch_toc *toc = (struct ch_toc *)ptr;
 	struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
-	uint32_t offset, size, gph_size, gph_load_addr;
+	uint32_t offset, size;
 
 	while (toc->section_offset != 0xffffffff
 			&& toc->section_size != 0xffffffff) {
 		if (do_swap32) {
-			offset = omapimage_swap32(toc->section_offset);
-			size = omapimage_swap32(toc->section_size);
+			offset = cpu_to_be32(toc->section_offset);
+			size = cpu_to_be32(toc->section_size);
 		} else {
 			offset = toc->section_offset;
 			size = toc->section_size;
@@ -92,20 +59,7 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
 		toc++;
 	}
 
-	if (do_swap32) {
-		gph_size = omapimage_swap32(gph->size);
-		gph_load_addr = omapimage_swap32(gph->load_addr);
-	} else {
-		gph_size = gph->size;
-		gph_load_addr = gph->load_addr;
-	}
-
-	if (!valid_gph_size(gph_size))
-		return -1;
-	if (!valid_gph_load_addr(gph_load_addr))
-		return -1;
-
-	return 0;
+	return gph_verify_header(gph, do_swap32);
 }
 
 static void omapimage_print_section(struct ch_settings *chs)
@@ -135,13 +89,13 @@ static void omapimage_print_header(const void *ptr)
 	const struct ch_toc *toc = (struct ch_toc *)ptr;
 	const struct gp_header *gph =
 			(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
-	uint32_t offset, size, gph_size, gph_load_addr;
+	uint32_t offset, size;
 
 	while (toc->section_offset != 0xffffffff
 			&& toc->section_size != 0xffffffff) {
 		if (do_swap32) {
-			offset = omapimage_swap32(toc->section_offset);
-			size = omapimage_swap32(toc->section_size);
+			offset = cpu_to_be32(toc->section_offset);
+			size = cpu_to_be32(toc->section_size);
 		} else {
 			offset = toc->section_offset;
 			size = toc->section_size;
@@ -160,26 +114,7 @@ static void omapimage_print_header(const void *ptr)
 		toc++;
 	}
 
-	if (do_swap32) {
-		gph_size = omapimage_swap32(gph->size);
-		gph_load_addr = omapimage_swap32(gph->load_addr);
-	} else {
-		gph_size = gph->size;
-		gph_load_addr = gph->load_addr;
-	}
-
-	if (!valid_gph_size(gph_size)) {
-		fprintf(stderr, "Error: invalid image size %x\n", gph_size);
-		exit(EXIT_FAILURE);
-	}
-
-	if (!valid_gph_load_addr(gph_load_addr)) {
-		fprintf(stderr, "Error: invalid image load address %x\n",
-				gph_load_addr);
-		exit(EXIT_FAILURE);
-	}
-
-	printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+	gph_print_header(gph, do_swap32);
 }
 
 static int toc_offset(void *hdr, void *member)
@@ -208,8 +143,8 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	toc++;
 	memset(toc, 0xff, sizeof(*toc));
 
-	gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
-	gph->load_addr = params->addr;
+	gph_set_header(gph, sbuf->st_size - OMAP_FILE_HDR_SIZE,
+		       params->addr, 0);
 
 	if (strncmp(params->imagename, "byteswap", 8) == 0) {
 		do_swap32 = 1;
@@ -217,20 +152,13 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 		uint32_t *data = (uint32_t *)ptr;
 
 		while (swapped <= (sbuf->st_size / sizeof(uint32_t))) {
-			*data = omapimage_swap32(*data);
+			*data = cpu_to_be32(*data);
 			swapped++;
 			data++;
 		}
 	}
 }
 
-int omapimage_check_params(struct image_tool_params *params)
-{
-	return	(params->dflag && (params->fflag || params->lflag)) ||
-		(params->fflag && (params->dflag || params->lflag)) ||
-		(params->lflag && (params->dflag || params->fflag));
-}
-
 /*
  * omapimage parameters
  */
@@ -242,7 +170,7 @@ static struct image_type_params omapimage_params = {
 	.verify_header	= omapimage_verify_header,
 	.print_header	= omapimage_print_header,
 	.set_header	= omapimage_set_header,
-	.check_params	= omapimage_check_params,
+	.check_params	= gpimage_check_params,
 };
 
 void init_omap_image_type(void)
diff --git a/tools/omapimage.h b/tools/omapimage.h
index 45d14ea..8744ae7 100644
--- a/tools/omapimage.h
+++ b/tools/omapimage.h
@@ -25,10 +25,5 @@ struct ch_settings {
 	uint32_t flags;
 };
 
-struct gp_header {
-	uint32_t size;
-	uint32_t load_addr;
-};
-
 #define KEY_CHSETTINGS 0xC0C0C0C1
 #endif /* _OMAPIMAGE_H_ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 4/7 v1] arm: add support for arch timer
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                     ` (2 preceding siblings ...)
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 3/7 v1] tools: mkimage: add support for gpimage format Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 5/7 v1] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

This patch add basic support for the architecture timer found on recent
ARMv7 based SoCs.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - Resending with some more in cc
 - Resending the patch along with SoC/board patch
 arch/arm/lib/Makefile     |    1 +
 arch/arm/lib/arch_timer.c |   58 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 arch/arm/lib/arch_timer.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 321997c..726f229 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
 else
 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
 endif
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
 
 ifdef CONFIG_ARM64
 obj-y	+= interrupts_64.o
diff --git a/arch/arm/lib/arch_timer.c b/arch/arm/lib/arch_timer.c
new file mode 100644
index 0000000..0588e2b
--- /dev/null
+++ b/arch/arm/lib/arch_timer.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int timer_init(void)
+{
+	gd->arch.tbl = 0;
+	gd->arch.tbu = 0;
+
+	gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ;
+
+	return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+	ulong nowl, nowu;
+
+	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
+
+	gd->arch.tbl = nowl;
+	gd->arch.tbu = nowu;
+
+	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+
+ulong get_timer(ulong base)
+{
+	return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+	unsigned long long endtime;
+
+	endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
+			1000UL);
+
+	endtime += get_ticks();
+
+	while (get_ticks() < endtime)
+		;
+}
+
+ulong get_tbclk(void)
+{
+	return gd->arch.timer_rate_hz;
+}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 5/7 v1] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                     ` (3 preceding siblings ...)
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 4/7 v1] arm: add support for arch timer Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM Murali Karicheri
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

This patch introduces a configurable mechanism to disable
subpage writes in the DaVinci NAND driver.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - Resend with some more in cc
 - Updated README to include the option as per review comments
 README                          |    5 +++++
 drivers/mtd/nand/davinci_nand.c |    3 +++
 2 files changed, 8 insertions(+)

diff --git a/README b/README
index aea82be..caf60a2 100644
--- a/README
+++ b/README
@@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
 - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
 		Enables the RTC32K OSC on AM33xx based plattforms
 
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+		Option to disable subpage write in NAND driver
+		Example driver that use this:
+		drivers/mtd/nand/davinci_nand.c
+
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
 
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 5b17d7b..75b03a7 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
 	nand->bbt_options	  |= NAND_BBT_USE_FLASH;
 #endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+	nand->options	  |= NAND_NO_SUBPAGE_WRITE;
+#endif
 #ifdef CONFIG_SYS_NAND_HW_ECC
 	nand->ecc.mode = NAND_ECC_HW;
 	nand->ecc.size = 512;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                     ` (4 preceding siblings ...)
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 5/7 v1] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
@ 2014-02-07 23:23   ` Murali Karicheri
  2014-02-10 21:25     ` Tom Rini
  2014-02-10  8:32   ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Albert ARIBAUD
  2014-02-10 21:23   ` Tom Rini
  7 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-07 23:23 UTC (permalink / raw)
  To: u-boot

k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
refer the ti/k2hk_evm/README for details on the board, build and other
information.

This patch add support for keystone architecture and k2hk evm.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
---
 - Resend with some more in cc
 Makefile                                           |   19 +
 arch/arm/cpu/armv7/keystone/Makefile               |   18 +
 arch/arm/cpu/armv7/keystone/aemif.c                |   79 +++++
 arch/arm/cpu/armv7/keystone/clock-k2hk.c           |  106 ++++++
 arch/arm/cpu/armv7/keystone/clock.c                |  200 +++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  139 ++++++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 +++++++
 arch/arm/cpu/armv7/keystone/config.mk              |   14 +
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++++
 arch/arm/cpu/armv7/keystone/init.c                 |   49 +++
 arch/arm/cpu/armv7/keystone/lowlevel_init.S        |   13 +
 arch/arm/cpu/armv7/keystone/msmc.c                 |   69 ++++
 arch/arm/cpu/armv7/keystone/psc.c                  |  240 +++++++++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 ++++++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 +
 arch/arm/include/asm/arch-keystone/clock_defs.h    |   97 +++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   75 ++++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  143 ++++++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  174 +++++++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   86 +++++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 ++
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   91 +++++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |   56 +++
 board/ti/k2hk_evm/board.c                          |  246 +++++++++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 ++++++++++++++
 boards.cfg                                         |    1 +
 drivers/i2c/Makefile                               |    1 +
 drivers/i2c/keystone_i2c.c                         |  372 ++++++++++++++++++++
 drivers/serial/ns16550.c                           |    8 +
 include/configs/k2hk_evm.h                         |  221 ++++++++++++
 33 files changed, 3203 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock-k2hk.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 drivers/i2c/keystone_i2c.c
 create mode 100644 include/configs/k2hk_evm.h

diff --git a/Makefile b/Makefile
index 47a03e3..ea2a387 100644
--- a/Makefile
+++ b/Makefile
@@ -491,6 +491,23 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
 		cat $(obj)u-boot.img >> $@
 
+$(obj)u-boot-spi.gph:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+			-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
+		$(OBJCOPY) ${OBJCFLAGS} -I binary \
+			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
+			$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
+		cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+
+$(obj)u-boot-nand.gph:	$(obj)u-boot.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+			-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
+		@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
+		@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
+		@rm $(obj)zero.bin
+
 ifneq ($(CONFIG_TEGRA),)
 $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
@@ -841,12 +858,14 @@ clobber:	tidy
 	@rm -f $(obj)u-boot.dtb
 	@rm -f $(obj)u-boot.sb
 	@rm -f $(obj)u-boot.spr
+	@rm -f $(obj)u-boot-*.gph
 	@rm -f $(obj)nand_spl/{u-boot.{lds,lst},System.map}
 	@rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map}
 	@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map}
 	@rm -f $(obj)spl/u-boot-spl.lds
 	@rm -f $(obj)tpl/{u-boot-tpl,u-boot-tpl.bin,u-boot-tpl.map}
 	@rm -f $(obj)tpl/u-boot-spl.lds
+	@rm -f $(obj)spl/{u-boot-spl.gph,u-boot-spl-pad.gph}
 	@rm -f $(obj)MLO MLO.byteswap
 	@rm -f $(obj)SPL
 	@rm -f $(obj)tools/xway-swap-bytes
diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
new file mode 100644
index 0000000..0fd4189
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -0,0 +1,18 @@
+#
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= aemif.o
+obj-y   += init.o
+obj-y   += psc.o
+obj-y   += clock.o
+obj-y   += cmd_clock.o
+obj-y   += cmd_mon.o
+obj-y   += msmc.o
+obj-y   += lowlevel_init.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
+obj-y	+= ddr3.o
+
diff --git a/arch/arm/cpu/armv7/keystone/aemif.c b/arch/arm/cpu/armv7/keystone/aemif.c
new file mode 100644
index 0000000..1063858
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/aemif.c
@@ -0,0 +1,79 @@
+/*
+ * Keystone2: Asynchronous EMIF Configuration
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#ifdef CONFIG_SOC_K2HK
+#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
+#endif
+
+#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
+#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
+#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
+#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)
+
+#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
+#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
+#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
+#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
+#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
+#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
+#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
+#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
+#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
+#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)
+
+#define set_config_field(reg, field, val)			\
+	do {							\
+		if (val != -1) {				\
+			reg &= ~CONFIG_##field(0xffffffff);	\
+			reg |=	CONFIG_##field(val);		\
+		}						\
+	} while (0)
+
+void configure_async_emif(int cs, struct async_emif_config *cfg)
+{
+	unsigned long tmp;
+
+	if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
+		tmp = __raw_readl(ASYNC_EMIF_NAND_CONTROL);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, ASYNC_EMIF_NAND_CONTROL);
+
+	} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
+		tmp = __raw_readl(ASYNC_EMIF_ONENAND_CONTROL);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, ASYNC_EMIF_ONENAND_CONTROL);
+	}
+
+	tmp = __raw_readl(ASYNC_EMIF_CONFIG(cs));
+
+	set_config_field(tmp, SELECT_STROBE,	cfg->select_strobe);
+	set_config_field(tmp, EXTEND_WAIT,	cfg->extend_wait);
+	set_config_field(tmp, WR_SETUP,		cfg->wr_setup);
+	set_config_field(tmp, WR_STROBE,	cfg->wr_strobe);
+	set_config_field(tmp, WR_HOLD,		cfg->wr_hold);
+	set_config_field(tmp, RD_SETUP,		cfg->rd_setup);
+	set_config_field(tmp, RD_STROBE,	cfg->rd_strobe);
+	set_config_field(tmp, RD_HOLD,		cfg->rd_hold);
+	set_config_field(tmp, TURN_AROUND,	cfg->turn_around);
+	set_config_field(tmp, WIDTH,		cfg->width);
+
+	__raw_writel(tmp, ASYNC_EMIF_CONFIG(cs));
+}
+
+void init_async_emif(int num_cs, struct async_emif_config *config)
+{
+	int cs;
+
+	for (cs = 0; cs < num_cs; cs++)
+		configure_async_emif(cs, config + cs);
+}
diff --git a/arch/arm/cpu/armv7/keystone/clock-k2hk.c b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
new file mode 100644
index 0000000..5e404dd
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
@@ -0,0 +1,106 @@
+/*
+ * K2HK: pll clock utilities
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+static const struct pll_regs pll_regs[] = {
+	[CORE_PLL]	= { K2HK_MAINPLLCTL0, K2HK_MAINPLLCTL1},
+	[PASS_PLL]	= { K2HK_PASSPLLCTL0, K2HK_PASSPLLCTL1},
+	[TETRIS_PLL]	= { K2HK_ARMPLLCTL0,  K2HK_ARMPLLCTL1},
+	[DDR3A_PLL]	= { K2HK_DDR3APLLCTL0, K2HK_DDR3APLLCTL1},
+	[DDR3B_PLL]	= { K2HK_DDR3BPLLCTL0, K2HK_DDR3BPLLCTL1},
+};
+
+/* Fout = Fref * NF(mult) / NR(prediv) / OD */
+static unsigned long pll_freq_get(int pll)
+{
+	unsigned long mult = 1, prediv = 1, output_div = 2;
+	unsigned long ret;
+	u32 tmp, reg;
+
+	if (pll == CORE_PLL) {
+		ret = external_clk[sys_clk];
+		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
+			/* PLL mode */
+			tmp = __raw_readl(K2HK_MAINPLLCTL0);
+			prediv = (tmp & 0x3f) + 1;
+			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
+							mult) & 0x3f)) + 1;
+			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
+				      0xf) + 1;
+
+			ret = ret / prediv / output_div * mult;
+		}
+	} else {
+		switch (pll) {
+		case PASS_PLL:
+			ret = external_clk[pa_clk];
+			reg = K2HK_PASSPLLCTL0;
+			break;
+		case TETRIS_PLL:
+			ret = external_clk[tetris_clk];
+			reg = K2HK_ARMPLLCTL0;
+			break;
+		case DDR3A_PLL:
+			ret = external_clk[ddr3a_clk];
+			reg = K2HK_DDR3APLLCTL0;
+			break;
+		case DDR3B_PLL:
+			ret = external_clk[ddr3b_clk];
+			reg = K2HK_DDR3BPLLCTL0;
+			break;
+		default:
+			return 0;
+		}
+
+		tmp = __raw_readl(reg);
+
+		if (!(tmp & 0x00800000)) {
+			/* Bypass disabled */
+			prediv = (tmp & 0x3f) + 1;
+			mult = ((tmp >> 6) & 0x1fff) + 1;
+			output_div = ((tmp >> 19) & 0xf) + 1;
+			ret = ((ret / prediv) * mult) / output_div;
+		}
+	}
+
+	return ret;
+}
+
+
+
+
+unsigned long clk_get_rate(unsigned int clk)
+{
+	switch (clk) {
+	case core_pll_clk:	return pll_freq_get(CORE_PLL);
+	case pass_pll_clk:	return pll_freq_get(PASS_PLL);
+	case tetris_pll_clk:	return pll_freq_get(TETRIS_PLL);
+	case ddr3a_pll_clk:	return pll_freq_get(DDR3A_PLL);
+	case ddr3b_pll_clk:	return pll_freq_get(DDR3B_PLL);
+	case sys_clk0_1_clk:
+	case sys_clk0_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(1);
+	case sys_clk1_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(2);
+	case sys_clk2_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(3);
+	case sys_clk3_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(4);
+	case sys_clk0_2_clk:	return clk_get_rate(sys_clk0_clk) / 2;
+	case sys_clk0_3_clk:	return clk_get_rate(sys_clk0_clk) / 3;
+	case sys_clk0_4_clk:	return clk_get_rate(sys_clk0_clk) / 4;
+	case sys_clk0_6_clk:	return clk_get_rate(sys_clk0_clk) / 6;
+	case sys_clk0_8_clk:	return clk_get_rate(sys_clk0_clk) / 8;
+	case sys_clk0_12_clk:	return clk_get_rate(sys_clk0_clk) / 12;
+	case sys_clk0_24_clk:	return clk_get_rate(sys_clk0_clk) / 24;
+	case sys_clk1_3_clk:	return clk_get_rate(sys_clk1_clk) / 3;
+	case sys_clk1_4_clk:	return clk_get_rate(sys_clk1_clk) / 4;
+	case sys_clk1_6_clk:	return clk_get_rate(sys_clk1_clk) / 6;
+	case sys_clk1_12_clk:	return clk_get_rate(sys_clk1_clk) / 12;
+	default:
+		break;
+	}
+	return 0;
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c
new file mode 100644
index 0000000..70f88ce
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock.c
@@ -0,0 +1,200 @@
+/*
+ * Keystone2: pll initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clock_defs.h>
+
+static void pll_delay(unsigned int loop_count)
+{
+	while (loop_count--)
+		asm("   NOP");
+}
+
+static void wait_for_completion(const struct pll_init_data *data)
+{
+	int i;
+	for (i = 0; i < 100; i++) {
+		pll_delay(300);
+		if ((pllctl_reg_read(data->pll, stat) & 0x00000001) == 0)
+			break;
+	}
+}
+
+struct pll_regs {
+	u32	reg0, reg1;
+};
+
+
+#include "clock-k2hk.c"
+
+void init_pll(const struct pll_init_data *data)
+{
+	u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj;
+
+	pllm = data->pll_m - 1;
+	plld = (data->pll_d - 1) & 0x3f;
+	pllod = (data->pll_od - 1) & 0xf;
+
+	if (data->pll == MAIN_PLL) {
+		pll_delay(140000);
+
+		tmp = pllctl_reg_read(data->pll, secctl);
+
+		if (tmp & (PLLCTL_BYPASS)) {
+			reg_setbits(pll_regs[data->pll].reg1,
+				    BIT(MAIN_ENSAT_OFFSET));
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			pll_delay(225);
+
+			pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS);
+			pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+			pll_delay(14000);
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+		} else {
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			pll_delay(225);
+		}
+
+		pllctl_reg_write(data->pll, mult, pllm & 0x3f);
+
+		reg_rmw(pll_regs[data->pll].reg0, 0x0007F000, (pllm << 6));
+
+		/* Set the BWADJ     (12 bit field)  */
+		tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */
+		reg_rmw(pll_regs[data->pll].reg0, 0xFF000000, (tmp_ctl << 24));
+		reg_rmw(pll_regs[data->pll].reg1, 0x0000000F, (tmp_ctl >> 8));
+
+		/* Set the pll divider (6 bit field)   *
+		 * PLLD[5:0] is located in MAINPLLCTL0 */
+		reg_rmw(pll_regs[data->pll].reg0, 0x0000003F, plld);
+
+		/* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
+		pllctl_reg_rmw(data->pll, secctl, 0x00780000, (pllod << 19));
+		wait_for_completion(data);
+
+		pllctl_reg_write(data->pll, div1, 0x00008000);
+		pllctl_reg_write(data->pll, div2, 0x00008000);
+		pllctl_reg_write(data->pll, div3, 0x00008001);
+		pllctl_reg_write(data->pll, div4, 0x00008004);
+		pllctl_reg_write(data->pll, div5, 0x000080017);
+
+		pllctl_reg_setbits(data->pll, alnctl, 0x1f);
+
+		/* Set GOSET bit in PLLCMD to initiate the GO operation
+		 * to change the divide */
+		pllctl_reg_setbits(data->pll, cmd, 0x1);
+		pll_delay(1000); /* wait for the phase adj */
+		wait_for_completion(data);
+
+		/* Reset PLL */
+		pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+		pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
+		pll_delay(70000);	/* Wait for PLL Lock time (min 50 us) */
+
+		pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS);
+
+		tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
+
+	} else if (data->pll == TETRIS_PLL) {
+		bwadj = pllm >> 1;
+		/* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */
+		reg_setbits(pll_regs[data->pll].reg0,  0x00800000);
+		/* Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
+		 * only applicable for Kepler */
+		reg_clrbits(0x02620c7c, (1<<13));
+		/* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
+		reg_setbits(pll_regs[data->pll].reg1 , (1<<14) | (1 << 6));
+
+		/* 3 Program PLLM and PLLD in PLLCTL0 register
+		 * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in
+		 * PLLCTL1 register. BWADJ value must be set
+		 * to ((PLLM + 1) >> 1) ? 1) */
+		tmp = ((bwadj & 0xff) << 24) | (pllm << 6) |
+			(plld & 0x3f) | (pllod<<19) | 0x00800000;
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(0xf);
+		tmp |= ((bwadj>>8) & 0xf);
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+		/* 5 Wait for at least 5 us based on the reference
+		 * clock (PLL reset time) */
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+
+		/* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
+		reg_clrbits(pll_regs[data->pll].reg1 , (1<<14));
+		/* 7 Wait for@least 500 * REFCLK cycles * (PLLD + 1)
+		 * (PLL lock time) */
+		pll_delay(70000);
+		/* 8 disable bypass */
+		reg_clrbits(pll_regs[data->pll].reg0, 0x00800000);
+		/* 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
+		 * only applicable for Kepler */
+		reg_setbits(0x02620c7c, (1<<13));
+	} else {
+		reg_setbits(pll_regs[data->pll].reg1, 0x00000040);
+		/* process keeps state of Bypass bit while programming
+		 * all other DDR PLL settings */
+		tmp = __raw_readl(pll_regs[data->pll].reg0);
+		tmp &= 0x00800000;	/* clear everything except Bypass */
+
+		/* Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
+		 * bypass disabled */
+		bwadj = pllm >> 1;
+		tmp |= ((bwadj & 0xff) << 24) | (pllm << 6) |
+			(plld & 0x3f) | (pllod<<19);
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(0xf);
+		tmp |= ((bwadj>>8) & 0xf);
+
+		/* set PLL Select (bit 13) for PASS PLL */
+		if (data->pll == PASS_PLL)
+			tmp |= 0x00002000;
+
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+
+		/* Reset bit: bit 14 for both DDR3 & PASS PLL */
+		tmp = 0x00004000;
+		/* Set RESET bit = 1 */
+		reg_setbits(pll_regs[data->pll].reg1, tmp);
+		/* Wait for a minimum of 7 us*/
+		pll_delay(14000);
+		/* Clear RESET bit */
+		reg_clrbits(pll_regs[data->pll].reg1, tmp);
+		pll_delay(70000);
+
+		/* clear BYPASS (Enable PLL Mode) */
+		reg_clrbits(pll_regs[data->pll].reg0, 0x00800000);
+		pll_delay(14000);	/* Wait for a minimum of 7 us*/
+	}
+
+	pll_delay(140000);
+}
+
+void init_plls(int num_pll, struct pll_init_data *config)
+{
+	int i;
+
+	for (i = 0; i < num_pll; i++)
+		init_pll(&config[i]);
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c
new file mode 100644
index 0000000..a18e31b
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
@@ -0,0 +1,139 @@
+/*
+ * keystone2: commands for clocks
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/psc_defs.h>
+
+static u32 atoui(char *pstr)
+{
+	u32 res = 0;
+
+	for (; *pstr != 0; pstr++) {
+		if (*pstr < '0' || *pstr > '9')
+			break;
+
+		res = (res * 10) + (*pstr - '0');
+	}
+
+	return res;
+}
+
+struct pll_init_data cmd_pll_data = {
+	.pll			= MAIN_PLL,
+	.pll_m			= 16,
+	.pll_d			= 1,
+	.pll_od			= 2,
+};
+
+int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 5)
+		goto pll_cmd_usage;
+
+	if (strncmp(argv[1], "pa", 2) == 0)
+		cmd_pll_data.pll = PASS_PLL;
+	else if (strncmp(argv[1], "arm", 3) == 0)
+		cmd_pll_data.pll = TETRIS_PLL;
+	else if (strncmp(argv[1], "ddr3a", 5) == 0)
+		cmd_pll_data.pll = DDR3A_PLL;
+	else if (strncmp(argv[1], "ddr3b", 5) == 0)
+		cmd_pll_data.pll = DDR3B_PLL;
+	else
+		goto pll_cmd_usage;
+
+	cmd_pll_data.pll_m   = atoui(argv[2]);
+	cmd_pll_data.pll_d   = atoui(argv[3]);
+	cmd_pll_data.pll_od  = atoui(argv[4]);
+
+	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
+	       cmd_pll_data.pll, cmd_pll_data.pll_m,
+	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
+	init_pll(&cmd_pll_data);
+
+	return 0;
+
+pll_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	pllset,	5,	0,	do_pll_cmd,
+	"set pll multiplier and pre divider",
+	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
+);
+
+int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned int clk;
+	unsigned int freq;
+
+	if (argc != 2)
+		goto getclk_cmd_usage;
+
+	clk = atoui(argv[1]);
+
+	freq = clk_get_rate(clk);
+	printf("clock index [%d] - frequency %u\n", clk, freq);
+	return 0;
+
+getclk_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	getclk,	2,	0,	do_getclk_cmd,
+	"get clock rate",
+	"<clk index>\n"
+	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
+);
+
+int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int	psc_module;
+	int	res;
+
+	if (argc != 3)
+		goto psc_cmd_usage;
+
+	psc_module = atoui(argv[1]);
+	if (strcmp(argv[2], "en") == 0) {
+		res = psc_enable_module(psc_module);
+		printf("psc_enable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "di") == 0) {
+		res = psc_disable_module(psc_module);
+		printf("psc_disable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "domain") == 0) {
+		res = psc_disable_domain(psc_module);
+		printf("psc_disable_domain(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+psc_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	psc,	3,	0,	do_psc_cmd,
+	"<enable/disable psc module os disable domain>",
+	"<mod/domain index> <en|di|domain>\n"
+	"See the hardware.h for Power and Sleep Controller (PSC) Domains\n"
+);
+
diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c
new file mode 100644
index 0000000..f9f58a3
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_mon.c
@@ -0,0 +1,131 @@
+/*
+ * K2HK: secure kernel command file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+asm(".arch_extension sec\n\t");
+
+static int mon_install(u32 addr, u32 dpsc, u32 freq)
+{
+	int result;
+
+	__asm__ __volatile__ (
+		"stmfd r13!, {lr}\n"
+		"mov r0, %1\n"
+		"mov r1, %2\n"
+		"mov r2, %3\n"
+		"blx r0\n"
+		"ldmfd r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (addr), "r" (dpsc), "r" (freq)
+		: "cc", "r0", "r1", "r2", "memory");
+	return result;
+}
+
+static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	u32 addr, dpsc_base = 0x1E80000, freq;
+	int     rcode = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	freq = clk_get_rate(sys_clk0_6_clk);
+
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	rcode = mon_install(addr, dpsc_base, freq);
+	printf("## installed monitor, freq [%d], status %d\n",
+	       freq, rcode);
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_install, 2, 0, do_mon_install,
+	   "Install boot kernel@'addr'",
+	   ""
+);
+
+static void core_spin(void)
+{
+	while (1)
+		; /* forever */;
+}
+
+int mon_power_on(int core_id, void *ep)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r2, %2\n"
+		"mov r0, #0\n"
+		"smc	#0\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id), "r" (ep)
+		: "cc", "r0", "r1", "r2", "memory");
+	return  result;
+}
+
+int mon_power_off(int core_id)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r0, #1\n"
+		"smc	#1\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id)
+		: "cc", "r0", "r1", "memory");
+	return  result;
+}
+
+int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	int     rcode = 0, core_id, on;
+	void (*fn)(void);
+
+	fn = core_spin;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	core_id = simple_strtoul(argv[1], NULL, 16);
+	on = simple_strtoul(argv[2], NULL, 16);
+
+	if (on)
+		rcode = mon_power_on(core_id, fn);
+	else
+		rcode = mon_power_off(core_id);
+
+	if (on) {
+		if (!rcode)
+			printf("core %d powered on successfully\n", core_id);
+		else
+			printf("core %d power on failure\n", core_id);
+	} else {
+		printf("core %d powered off successfully\n", core_id);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_power, 3, 0, do_mon_power,
+	   "Power On/Off secondary core",
+	   "mon_power <coreid> <oper>\n"
+	   "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n"
+	   ""
+);
diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk
new file mode 100644
index 0000000..18385f4
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/config.mk
@@ -0,0 +1,14 @@
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
+
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
+		    $(call cc-option,-malignment-traps,))
diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
new file mode 100644
index 0000000..4875db7
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/ddr3.c
@@ -0,0 +1,69 @@
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
+{
+	unsigned int tmp;
+
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET)
+		 & 0x00000001) != 0x00000001)
+		;
+
+	__raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET);
+
+	tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET);
+	tmp &= ~(phy_cfg->pgcr1_mask);
+	tmp |= phy_cfg->pgcr1_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET);
+
+	__raw_writel(phy_cfg->ptr0,   base + KS2_DDRPHY_PTR0_OFFSET);
+	__raw_writel(phy_cfg->ptr1,   base + KS2_DDRPHY_PTR1_OFFSET);
+	__raw_writel(phy_cfg->ptr3,  base + KS2_DDRPHY_PTR3_OFFSET);
+	__raw_writel(phy_cfg->ptr4,  base + KS2_DDRPHY_PTR4_OFFSET);
+
+	tmp =  __raw_readl(base + KS2_DDRPHY_DCR_OFFSET);
+	tmp &= ~(phy_cfg->dcr_mask);
+	tmp |= phy_cfg->dcr_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET);
+
+	__raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET);
+	__raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET);
+	__raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET);
+	__raw_writel(phy_cfg->mr0,   base + KS2_DDRPHY_MR0_OFFSET);
+	__raw_writel(phy_cfg->mr1,   base + KS2_DDRPHY_MR1_OFFSET);
+	__raw_writel(phy_cfg->mr2,   base + KS2_DDRPHY_MR2_OFFSET);
+	__raw_writel(phy_cfg->dtcr,  base + KS2_DDRPHY_DTCR_OFFSET);
+	__raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET);
+
+	__raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET);
+	__raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET);
+	__raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET);
+
+	__raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+
+	__raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+}
+
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
+{
+	__raw_writel(emif_cfg->sdcfg,  base + KS2_DDR3_SDCFG_OFFSET);
+	__raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET);
+	__raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET);
+	__raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET);
+	__raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET);
+	__raw_writel(emif_cfg->zqcfg,  base + KS2_DDR3_ZQCFG_OFFSET);
+	__raw_writel(emif_cfg->sdrfc,  base + KS2_DDR3_SDRFC_OFFSET);
+}
diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c
new file mode 100644
index 0000000..6d5512e
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/init.c
@@ -0,0 +1,49 @@
+/*
+ * Keystone2: Architecture initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+
+void chip_configuration_unlock(void)
+{
+	__raw_writel(KEYSTONE_KICK0_MAGIC, KEYSTONE_KICK0);
+	__raw_writel(KEYSTONE_KICK1_MAGIC, KEYSTONE_KICK1);
+}
+
+int arch_cpu_init(void)
+{
+	chip_configuration_unlock();
+	icache_enable();
+
+#ifdef CONFIG_SOC_K2HK
+	share_all_segments(8);
+	share_all_segments(9);
+	share_all_segments(10); /* QM PDSP */
+	share_all_segments(11); /* PCIE */
+#endif
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8);
+	u32 tmp;
+
+	tmp = *rstctrl & 0xffff0000;
+	*rstctrl = tmp | 0x5a69;
+
+	*rstctrl &= 0xfffe0000;
+
+	for (;;)
+		;
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/lowlevel_init.S b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
new file mode 100644
index 0000000..ac98472
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
@@ -0,0 +1,13 @@
+/*
+ * Keystone2: Low-level pre-relocation initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+.globl lowlevel_init
+lowlevel_init:
+	/* nothing for now, maybe needed for more exotic boot modes */
+	mov	pc, lr
diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c
new file mode 100644
index 0000000..8f2f324
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/msmc.c
@@ -0,0 +1,69 @@
+/*
+ * MSMC controller utilities
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+struct mpax {
+	u32	mpaxl;
+	u32	mpaxh;
+};
+
+struct msms_regs {
+	u32	pid;
+	u32	_res_04;
+	u32	smcerrar;
+	u32	smcerrxr;
+	u32	smedcc;
+	u32	smcea;
+	u32	smsecc;
+	u32	smpfar;
+	u32	smpfxr;
+	u32	smpfr;
+	u32	smpfcr;
+	u32	_res_2c;
+	u32	sbndc[8];
+	u32	sbndm;
+	u32	sbnde;
+	u32	_res_58;
+	u32	cfglck;
+	u32	cfgulck;
+	u32	cfglckstat;
+	u32	sms_mpax_lck;
+	u32	sms_mpax_ulck;
+	u32	sms_mpax_lckstat;
+	u32	ses_mpax_lck;
+	u32	ses_mpax_ulck;
+	u32	ses_mpax_lckstat;
+	u32	smestat;
+	u32	smirstat;
+	u32	smirc;
+	u32	smiestat;
+	u32	smiec;
+	u32	_res_94_c0[12];
+	u32	smncerrar;
+	u32	smncerrxr;
+	u32	smncea;
+	u32	_res_d0_1fc[76];
+	struct mpax sms[16][8];
+	struct mpax ses[16][8];
+};
+
+
+void share_all_segments(int priv_id)
+{
+	struct msms_regs *msmc = (struct msms_regs *)K2HK_MSMC_CTRL_BASE;
+	int j;
+
+	for (j = 0; j < 8; j++) {
+		msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful;
+		msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful;
+	}
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c
new file mode 100644
index 0000000..9697da6
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/psc.c
@@ -0,0 +1,240 @@
+/*
+ * Keystone: PSC configuration module
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+/*****************************************************************************
+ * FILE PURPOSE: Driver for the PSC module
+ *****************************************************************************
+ * FILE NAME: psc.c
+ *
+ * DESCRIPTION: The boot loader PSC driver
+ *
+ *****************************************************************************/
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/psc_defs.h>
+
+#define DEVICE_REG32_R(addr)			__raw_readl((u32 *)(addr))
+#define DEVICE_REG32_W(addr, val)		__raw_writel(val, (u32 *)(addr))
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSC_BASE				K2HK_PSC_BASE
+#endif
+
+int psc_delay(void)
+{
+	udelay(10);
+	return 10;
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Wait for end of transitional state
+ ******************************************************************************
+ * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
+ *              to be complete.
+ *
+ *              Since this is boot loader code it is *ASSUMED* that interrupts
+ *              are disabled and no other core is mucking around with the psc
+ *              at the same time.
+ *
+ *              Returns 0 when the domain is free. Returns -1 if a timeout
+ *              occurred waiting for the completion.
+ *****************************************************************************/
+int psc_wait(u32 domain_num)
+{
+	u32 retry;
+	u32 ptstat;
+
+	/* Do nothing if the power domain is in transition. This should never
+	 * happen since the boot code is the only software accesses psc.
+	 * It's still remotely possible that the hardware state machines
+	 * initiate transitions.
+	 * Don't trap if the domain (or a module in this domain) is
+	 * stuck in transition.  */
+	retry = 0;
+
+	do {
+		ptstat = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PSTAT);
+		ptstat = ptstat & (1 << domain_num);
+	} while ((ptstat != 0) && ((retry += psc_delay()) <
+		 PSC_PTSTAT_TIMEOUT_LIMIT));
+
+	if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
+		return -1;
+
+	return 0;
+}
+
+u32 psc_get_domain_num(u32 mod_num)
+{
+	u32 domain_num;
+
+	/* Get the power domain associated with the module number */
+	domain_num = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				    PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
+
+	return domain_num;
+}
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Power up/down a module
+ *****************************************************************************
+ * DESCRIPTION: Powers up/down the requested module and the associated power
+ *		domain if required. No action is taken it the module is
+ *		already powered up/down.
+ *
+ *              This only controls modules. The domain in which the module
+ *              resides will be left in the power on state. Multiple modules
+ *              can exist in a power domain, so powering down the domain based
+ *              on a single module is not done.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ *****************************************************************************/
+int psc_set_state(u32 mod_num, u32 state)
+{
+	u32 domain_num;
+	u32 pdctl;
+	u32 mdctl;
+	u32 ptcmd;
+	u32 reset_iso;
+	u32 v;
+
+	/* Get the power domain associated with the module number, and reset
+	 * isolation functionality */
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(v);
+	reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
+
+	/* Wait for the status of the domain/module to be non-transitional */
+	if (psc_wait(domain_num) != 0)
+		return -1;
+
+	/* Perform configuration even if the current status matches the
+	 * existing state */
+
+	/* Set the next state of the power domain to on. It's OK if the domain
+	 * is always on. This code will not ever power down a domain, so no
+	 * change is made if the new state is power down. */
+	if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
+		pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				       PSC_REG_PDCTL(domain_num));
+		pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
+					       PSC_REG_VAL_PDCTL_NEXT_ON);
+		DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num),
+			       pdctl);
+	}
+
+	/* Set the next state for the module to enabled/disabled */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	/* Trigger the enable */
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1<<domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	/* Wait on the complete */
+	return psc_wait(domain_num);
+}
+
+/*****************************************************************************
+ * FUNCTION PURPOSE: Power up a module
+ *****************************************************************************
+ * DESCRIPTION: Powers up the requested module and the associated power domain
+ *              if required. No action is taken it the module is already
+ *              powered up.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ *****************************************************************************/
+int psc_enable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
+		return 0;
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Power down a module
+ ******************************************************************************
+ * DESCRIPTION: Powers down the requested module.
+ *
+ *              Returns 0 on success, -1 on failure or timeout.
+ ******************************************************************************/
+int psc_disable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == 0)
+		return 0;
+	mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Set the reset isolation bit in mdctl
+ ******************************************************************************
+ * DESCRIPTION: The reset isolation enable bit is set. The state of the module
+ *              is not changed. Returns 0 if the module config showed that
+ *              reset isolation is supported. Returns 1 otherwise. This is not
+ *              an error, but setting the bit in mdctl has no effect.
+ ******************************************************************************/
+int psc_set_reset_iso(u32 mod_num)
+{
+	u32 v;
+	u32 mdctl;
+
+	/* Set the reset isolation bit */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
+		return 0;
+
+	return 1;
+}
+
+/******************************************************************************
+ * FUNCTION PURPOSE: Disable a power domain
+ ******************************************************************************
+ * DESCRIPTION: The power domain is disabled
+ ******************************************************************************/
+int psc_disable_domain(u32 domain_num)
+{
+	u32 pdctl;
+	u32 ptcmd;
+
+	pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num));
+	pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
+	pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num), pdctl);
+
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1 << domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	return psc_wait(domain_num);
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/spl.c b/arch/arm/cpu/armv7/keystone/spl.c
new file mode 100644
index 0000000..e07b64d
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/spl.c
@@ -0,0 +1,45 @@
+/*
+ * common spl init code
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <config.h>
+#include <ns16550.h>
+#include <malloc.h>
+#include <spl.h>
+#include <spi_flash.h>
+
+#include <asm/u-boot.h>
+#include <asm/utils.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct pll_init_data spl_pll_config[] = {
+	CORE_PLL_799,
+	TETRIS_PLL_500,
+};
+
+void spl_init_keystone_plls(void)
+{
+	init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+
+void spl_board_init(void)
+{
+	spl_init_keystone_plls();
+	preloader_console_init();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_LOAD)
+	return BOOT_DEVICE_SPI;
+#else
+	puts("Unknown boot device\n");
+	hang();
+#endif
+}
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
new file mode 100644
index 0000000..6721939
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
@@ -0,0 +1,109 @@
+/*
+ * K2HK: Clock management APIs
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_K2HK_H
+#define __ASM_ARCH_CLOCK_K2HK_H
+
+#include <asm/arch/hardware.h>
+
+#ifndef __ASSEMBLY__
+
+enum ext_clk_e {
+	sys_clk,
+	alt_core_clk,
+	pa_clk,
+	tetris_clk,
+	ddr3a_clk,
+	ddr3b_clk,
+	mcm_clk,
+	pcie_clk,
+	sgmii_srio_clk,
+	xgmii_clk,
+	usb_clk,
+	rp1_clk,
+	ext_clk_count /* number of external clocks */
+};
+
+extern unsigned int external_clk[ext_clk_count];
+
+enum clk_e {
+	core_pll_clk,
+	pass_pll_clk,
+	tetris_pll_clk,
+	ddr3a_pll_clk,
+	ddr3b_pll_clk,
+	sys_clk0_clk,
+	sys_clk0_1_clk,
+	sys_clk0_2_clk,
+	sys_clk0_3_clk,
+	sys_clk0_4_clk,
+	sys_clk0_6_clk,
+	sys_clk0_8_clk,
+	sys_clk0_12_clk,
+	sys_clk0_24_clk,
+	sys_clk1_clk,
+	sys_clk1_3_clk,
+	sys_clk1_4_clk,
+	sys_clk1_6_clk,
+	sys_clk1_12_clk,
+	sys_clk2_clk,
+	sys_clk3_clk
+};
+
+#define K2HK_CLK1_6	sys_clk0_6_clk
+
+/* PLL identifiers */
+enum pll_type_e {
+	CORE_PLL,
+	PASS_PLL,
+	TETRIS_PLL,
+	DDR3A_PLL,
+	DDR3B_PLL,
+};
+#define MAIN_PLL CORE_PLL
+
+/* PLL configuration data */
+struct pll_init_data {
+	int pll;
+	int pll_m;		/* PLL Multiplier */
+	int pll_d;		/* PLL divider */
+	int pll_od;		/* PLL output divider    */
+};
+
+#define CORE_PLL_799	{CORE_PLL,	13,	1,	2}
+#define CORE_PLL_983	{CORE_PLL,	16,	1,	2}
+#define CORE_PLL_1167	{CORE_PLL,	19,	1,	2}
+#define CORE_PLL_1228	{CORE_PLL,	20,	1,	2}
+#define PASS_PLL_1228	{PASS_PLL,	20,	1,	2}
+#define PASS_PLL_983	{PASS_PLL,	16,	1,	2}
+#define PASS_PLL_1050	{PASS_PLL,	205,    12,	2}
+#define TETRIS_PLL_500  {TETRIS_PLL,	8,	1,	2}
+#define TETRIS_PLL_750  {TETRIS_PLL,	12,	1,	2}
+#define TETRIS_PLL_687  {TETRIS_PLL,	11,	1,	2}
+#define TETRIS_PLL_625  {TETRIS_PLL,	10,	1,	2}
+#define TETRIS_PLL_812  {TETRIS_PLL,	13,	1,	2}
+#define TETRIS_PLL_875  {TETRIS_PLL,	14,	1,	2}
+#define TETRIS_PLL_1188 {TETRIS_PLL,	19,	2,	1}
+#define TETRIS_PLL_1200 {TETRIS_PLL,	48,	5,	1}
+#define TETRIS_PLL_1375 {TETRIS_PLL,	22,	2,	1}
+#define TETRIS_PLL_1400 {TETRIS_PLL,	56,	5,	1}
+#define DDR3_PLL_200(x)	{DDR3##x##_PLL,	4,	1,	2}
+#define DDR3_PLL_400(x)	{DDR3##x##_PLL,	16,	1,	4}
+#define DDR3_PLL_800(x)	{DDR3##x##_PLL,	16,	1,	2}
+#define DDR3_PLL_333(x)	{DDR3##x##_PLL,	20,	1,	6}
+
+void init_plls(int num_pll, struct pll_init_data *config);
+void init_pll(const struct pll_init_data *data);
+unsigned long clk_get_rate(unsigned int clk);
+unsigned long clk_round_rate(unsigned int clk, unsigned long hz);
+int clk_set_rate(unsigned int clk, unsigned long hz);
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h
new file mode 100644
index 0000000..324501b
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock.h
@@ -0,0 +1,17 @@
+/*
+ * keystone2: common clock header file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/clock-k2hk.h>
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock_defs.h b/arch/arm/include/asm/arch-keystone/clock_defs.h
new file mode 100644
index 0000000..00e3dfb
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock_defs.h
@@ -0,0 +1,97 @@
+/*
+ * keystone2: common pll clock definitions
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _CLOCK_DEFS_H_
+#define _CLOCK_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+#define BIT(x)			(1 << (x))
+
+/* PLL Control Registers */
+struct pllctl_regs {
+	u32	ctl;		/* 00 */
+	u32	ocsel;		/* 04 */
+	u32	secctl;		/* 08 */
+	u32	__pad0;
+	u32	mult;		/* 10 */
+	u32	prediv;		/* 14 */
+	u32	div1;		/* 18 */
+	u32	div2;		/* 1c */
+	u32	div3;		/* 20 */
+	u32	oscdiv1;	/* 24 */
+	u32	__pad1;		/* 28 */
+	u32	bpdiv;		/* 2c */
+	u32	wakeup;		/* 30 */
+	u32	__pad2;
+	u32	cmd;		/* 38 */
+	u32	stat;		/* 3c */
+	u32	alnctl;		/* 40 */
+	u32	dchange;	/* 44 */
+	u32	cken;		/* 48 */
+	u32	ckstat;		/* 4c */
+	u32	systat;		/* 50 */
+	u32	ckctl;		/* 54 */
+	u32	__pad3[2];
+	u32	div4;		/* 60 */
+	u32	div5;		/* 64 */
+	u32	div6;		/* 68 */
+	u32	div7;		/* 6c */
+	u32	div8;		/* 70 */
+	u32	div9;		/* 74 */
+	u32	div10;		/* 78 */
+	u32	div11;		/* 7c */
+	u32	div12;		/* 80 */
+};
+
+static struct pllctl_regs *pllctl_regs[] = {
+	(struct pllctl_regs *)(CLOCK_BASE + 0x100)
+};
+
+#define pllctl_reg(pll, reg)		(&(pllctl_regs[pll]->reg))
+#define pllctl_reg_read(pll, reg)	__raw_readl(pllctl_reg(pll, reg))
+#define pllctl_reg_write(pll, reg, val)	__raw_writel(val, pllctl_reg(pll, reg))
+
+#define pllctl_reg_rmw(pll, reg, mask, val)			\
+	pllctl_reg_write(pll, reg,				\
+		(pllctl_reg_read(pll, reg) & ~(mask)) | val)
+
+#define pllctl_reg_setbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, 0, mask)
+
+#define pllctl_reg_clrbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, mask, 0)
+
+#define reg_rmw(reg, mask, val) \
+	__raw_writel((__raw_readl((reg)) & ~(mask)) | ((val) & (mask)) , \
+		     (reg));
+
+#define reg_setbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) | (bits)) , (reg));
+
+#define reg_clrbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) & ~(bits)) , (reg));
+
+#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1)
+
+/* PLLCTL Bits */
+#define PLLCTL_BYPASS		BIT(23)
+#define PLLCTL_CLKMODE		BIT(8)
+#define PLLCTL_PLLSELB		BIT(7)
+#define PLLCTL_PLLENSRC		BIT(5)
+#define PLLCTL_PLLDIS		BIT(4)
+#define PLLCTL_PLLRST		BIT(3)
+#define PLLCTL_PLLPWRDN		BIT(1)
+#define PLLCTL_PLLEN		BIT(0)
+
+#define MAIN_ENSAT_OFFSET	6
+
+#define PLLDIV_ENABLE		BIT(15)
+
+
+#endif  /* _CLOCK_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/emif_defs.h b/arch/arm/include/asm/arch-keystone/emif_defs.h
new file mode 100644
index 0000000..fa93321
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emif_defs.h
@@ -0,0 +1,75 @@
+/*
+ * emif definitions to re-use davinci emif driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _EMIF_DEFS_H_
+#define _EMIF_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+struct davinci_emif_regs {
+	u_int32_t	ercsr;
+	u_int32_t	awccr;
+	u_int32_t	sdbcr;
+	u_int32_t	sdrcr;
+	u_int32_t	ab1cr;
+	u_int32_t	ab2cr;
+	u_int32_t	ab3cr;
+	u_int32_t	ab4cr;
+	u_int32_t	sdtimr;
+	u_int32_t	ddrsr;
+	u_int32_t	ddrphycr;
+	u_int32_t	ddrphysr;
+	u_int32_t	totar;
+	u_int32_t	totactr;
+	u_int32_t	ddrphyid_rev;
+	u_int32_t	sdsretr;
+	u_int32_t	eirr;
+	u_int32_t	eimr;
+	u_int32_t	eimsr;
+	u_int32_t	eimcr;
+	u_int32_t	ioctrlr;
+	u_int32_t	iostatr;
+	u_int8_t	rsvd0[8];
+	u_int32_t	nandfcr;
+	u_int32_t	nandfsr;
+	u_int8_t	rsvd1[8];
+	u_int32_t	nandfecc[4];
+	u_int8_t	rsvd2[60];
+	u_int32_t	nand4biteccload;
+	u_int32_t	nand4bitecc[4];
+	u_int32_t	nanderradd1;
+	u_int32_t	nanderradd2;
+	u_int32_t	nanderrval1;
+	u_int32_t	nanderrval2;
+};
+
+#define davinci_emif_regs \
+	((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)
+
+#define DAVINCI_NANDFCR_NAND_ENABLE(n)			(1 << ((n) - 2))
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK		(3 << 4)
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL(n)			(((n) - 2) << 4)
+#define DAVINCI_NANDFCR_1BIT_ECC_START(n)		(1 << (8 + ((n) - 2)))
+#define DAVINCI_NANDFCR_4BIT_ECC_START			(1 << 12)
+#define DAVINCI_NANDFCR_4BIT_CALC_START			(1 << 13)
+
+/* Chip Select setup */
+#define DAVINCI_ABCR_STROBE_SELECT			(1 << 31)
+#define DAVINCI_ABCR_EXT_WAIT				(1 << 30)
+#define DAVINCI_ABCR_WSETUP(n)				((n) << 26)
+#define DAVINCI_ABCR_WSTROBE(n)				((n) << 20)
+#define DAVINCI_ABCR_WHOLD(n)				((n) << 17)
+#define DAVINCI_ABCR_RSETUP(n)				((n) << 13)
+#define DAVINCI_ABCR_RSTROBE(n)				((n) << 7)
+#define DAVINCI_ABCR_RHOLD(n)				((n) << 4)
+#define DAVINCI_ABCR_TA(n)				((n) << 2)
+#define DAVINCI_ABCR_ASIZE_16BIT			1
+#define DAVINCI_ABCR_ASIZE_8BIT				0
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
new file mode 100644
index 0000000..929dc90
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
@@ -0,0 +1,143 @@
+/*
+ * K2HK: SoC definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_K2HK_H
+#define __ASM_ARCH_HARDWARE_K2HK_H
+
+#define K2HK_ASYNC_EMIF_CNTRL_BASE	0x21000a00
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE	K2HK_ASYNC_EMIF_CNTRL_BASE
+#define K2HK_ASYNC_EMIF_DATA_CE0_BASE	0x30000000
+#define K2HK_ASYNC_EMIF_DATA_CE1_BASE	0x34000000
+#define K2HK_ASYNC_EMIF_DATA_CE2_BASE	0x38000000
+#define K2HK_ASYNC_EMIF_DATA_CE3_BASE	0x3c000000
+
+#define K2HK_PLL_CNTRL_BASE		0x02310000
+#define CLOCK_BASE			K2HK_PLL_CNTRL_BASE
+#define K2HK_PSC_BASE			0x02350000
+#define KS2_DEVICE_STATE_CTRL_BASE	0x02620000
+#define JTAG_ID_REG			(KS2_DEVICE_STATE_CTRL_BASE + 0x18)
+#define K2HK_DEVSTAT			(KS2_DEVICE_STATE_CTRL_BASE + 0x20)
+
+#define K2HK_SPI0_BASE			0x21000400
+#define K2HK_SPI1_BASE			0x21000600
+#define K2HK_SPI2_BASE			0x21000800
+#define K2HK_SPI_BASE			K2HK_SPI0_BASE
+
+/* Chip configuration unlock codes and registers */
+#define KEYSTONE_KICK0			(KS2_DEVICE_STATE_CTRL_BASE+0x38)
+#define KEYSTONE_KICK1			(KS2_DEVICE_STATE_CTRL_BASE+0x3c)
+#define KEYSTONE_KICK0_MAGIC		0x83e70b13
+#define KEYSTONE_KICK1_MAGIC		0x95a4f1e0
+
+/* PA SS Registers */
+#define KS2_PASS_BASE			0x02000000
+
+/* PLL control registers */
+#define K2HK_MAINPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x350)
+#define K2HK_MAINPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x354)
+#define K2HK_PASSPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x358)
+#define K2HK_PASSPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x35C)
+#define K2HK_DDR3APLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x360)
+#define K2HK_DDR3APLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x364)
+#define K2HK_DDR3BPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x368)
+#define K2HK_DDR3BPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x36C)
+#define K2HK_ARMPLLCTL0			(KS2_DEVICE_STATE_CTRL_BASE+0x370)
+#define K2HK_ARMPLLCTL1			(KS2_DEVICE_STATE_CTRL_BASE+0x374)
+
+/******************************************************************************/
+/* Power and Sleep Controller (PSC) Domains */
+#define K2HK_LPSC_MOD			0
+#define K2HK_LPSC_DUMMY1		1
+#define K2HK_LPSC_USB			2
+#define K2HK_LPSC_EMIF25_SPI		3
+#define K2HK_LPSC_TSIP			4
+#define K2HK_LPSC_DEBUGSS_TRC		5
+#define K2HK_LPSC_TETB_TRC		6
+#define K2HK_LPSC_PKTPROC		7
+#define KS2_LPSC_PA			K2HK_LPSC_PKTPROC
+#define K2HK_LPSC_SGMII			8
+#define KS2_LPSC_CPGMAC			K2HK_LPSC_SGMII
+#define K2HK_LPSC_CRYPTO		9
+#define K2HK_LPSC_PCIE			10
+#define K2HK_LPSC_SRIO			11
+#define K2HK_LPSC_VUSR0			12
+#define K2HK_LPSC_CHIP_SRSS		13
+#define K2HK_LPSC_MSMC			14
+#define K2HK_LPSC_GEM_0			15
+#define K2HK_LPSC_GEM_1			16
+#define K2HK_LPSC_GEM_2			17
+#define K2HK_LPSC_GEM_3			18
+#define K2HK_LPSC_GEM_4			19
+#define K2HK_LPSC_GEM_5			20
+#define K2HK_LPSC_GEM_6			21
+#define K2HK_LPSC_GEM_7			22
+#define K2HK_LPSC_EMIF4F_DDR3A		23
+#define K2HK_LPSC_EMIF4F_DDR3B		24
+#define K2HK_LPSC_TAC			25
+#define K2HK_LPSC_RAC			26
+#define K2HK_LPSC_RAC_1			27
+#define K2HK_LPSC_FFTC_A		28
+#define K2HK_LPSC_FFTC_B		29
+#define K2HK_LPSC_FFTC_C		30
+#define K2HK_LPSC_FFTC_D		31
+#define K2HK_LPSC_FFTC_E		32
+#define K2HK_LPSC_FFTC_F		33
+#define K2HK_LPSC_AI2			34
+#define K2HK_LPSC_TCP3D_0		35
+#define K2HK_LPSC_TCP3D_1		36
+#define K2HK_LPSC_TCP3D_2		37
+#define K2HK_LPSC_TCP3D_3		38
+#define K2HK_LPSC_VCP2X4_A		39
+#define K2HK_LPSC_CP2X4_B		40
+#define K2HK_LPSC_VCP2X4_C		41
+#define K2HK_LPSC_VCP2X4_D		42
+#define K2HK_LPSC_VCP2X4_E		43
+#define K2HK_LPSC_VCP2X4_F		44
+#define K2HK_LPSC_VCP2X4_G		45
+#define K2HK_LPSC_VCP2X4_H		46
+#define K2HK_LPSC_BCP			47
+#define K2HK_LPSC_DXB			48
+#define K2HK_LPSC_VUSR1			49
+#define K2HK_LPSC_XGE			50
+#define K2HK_LPSC_ARM_SREFLEX		51
+#define K2HK_LPSC_TETRIS		52
+
+
+#define K2HK_UART0_BASE			0x02530c00
+
+/* DDR3A definitions */
+#define K2HK_DDR3A_EMIF_CTRL_BASE	0x21010000
+#define K2HK_DDR3A_EMIF_DATA_BASE	0x80000000
+#define K2HK_DDR3A_DDRPHYC		0x02329000
+/* DDR3B definitions */
+#define K2HK_DDR3B_EMIF_CTRL_BASE	0x21020000
+#define K2HK_DDR3B_EMIF_DATA_BASE	0x60000000
+#define K2HK_DDR3B_DDRPHYC		0x02328000
+
+/* Queue manager */
+#define DEVICE_QM_MANAGER_BASE		0x02a02000
+#define DEVICE_QM_DESC_SETUP_BASE	0x02a03000
+#define DEVICE_QM_MANAGER_QUEUES_BASE	0x02a80000
+#define DEVICE_QM_MANAGER_Q_PROXY_BASE	0x02ac0000
+#define DEVICE_QM_QUEUE_STATUS_BASE	0x02a40000
+#define DEVICE_QM_NUM_LINKRAMS		2
+#define DEVICE_QM_NUM_MEMREGIONS	20
+
+#define DEVICE_PA_CDMA_GLOBAL_CFG_BASE	0x02004000
+#define DEVICE_PA_CDMA_TX_CHAN_CFG_BASE	0x02004400
+#define DEVICE_PA_CDMA_RX_CHAN_CFG_BASE	0x02004800
+#define DEVICE_PA_CDMA_RX_FLOW_CFG_BASE	0x02005000
+
+#define DEVICE_PA_CDMA_RX_NUM_CHANNELS	24
+#define DEVICE_PA_CDMA_RX_NUM_FLOWS	32
+#define DEVICE_PA_CDMA_TX_NUM_CHANNELS	9
+
+/* MSMC control */
+#define K2HK_MSMC_CTRL_BASE		0x0bc00000
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h
new file mode 100644
index 0000000..8d3f97d
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -0,0 +1,174 @@
+/*
+ * Keystone2: Common SoC definitions, structures etc.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/sizes.h>
+#include <asm/io.h>
+
+#define	REG(addr)	(*(volatile unsigned int *)(addr))
+#define REG_P(addr)	((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int	*dv_reg_p;
+
+#define ASYNC_EMIF_NUM_CS		4
+#define ASYNC_EMIF_MODE_NOR		0
+#define ASYNC_EMIF_MODE_NAND		1
+#define ASYNC_EMIF_MODE_ONENAND		2
+#define ASYNC_EMIF_PRESERVE		-1
+
+struct async_emif_config {
+	unsigned mode;
+	unsigned select_strobe;
+	unsigned extend_wait;
+	unsigned wr_setup;
+	unsigned wr_strobe;
+	unsigned wr_hold;
+	unsigned rd_setup;
+	unsigned rd_strobe;
+	unsigned rd_hold;
+	unsigned turn_around;
+	enum {
+		ASYNC_EMIF_8	= 0,
+		ASYNC_EMIF_16	= 1,
+		ASYNC_EMIF_32	= 2,
+	} width;
+};
+
+void init_async_emif(int num_cs, struct async_emif_config *config);
+
+struct ddr3_phy_config {
+	unsigned int pllcr;
+	unsigned int pgcr1_mask;
+	unsigned int pgcr1_val;
+	unsigned int ptr0;
+	unsigned int ptr1;
+	unsigned int ptr2;
+	unsigned int ptr3;
+	unsigned int ptr4;
+	unsigned int dcr_mask;
+	unsigned int dcr_val;
+	unsigned int dtpr0;
+	unsigned int dtpr1;
+	unsigned int dtpr2;
+	unsigned int mr0;
+	unsigned int mr1;
+	unsigned int mr2;
+	unsigned int dtcr;
+	unsigned int pgcr2;
+	unsigned int zq0cr1;
+	unsigned int zq1cr1;
+	unsigned int zq2cr1;
+	unsigned int pir_v1;
+	unsigned int pir_v2;
+};
+
+struct ddr3_emif_config {
+	unsigned int sdcfg;
+	unsigned int sdtim1;
+	unsigned int sdtim2;
+	unsigned int sdtim3;
+	unsigned int sdtim4;
+	unsigned int zqcfg;
+	unsigned int sdrfc;
+};
+
+#endif
+
+#define		BIT(x)	(1 << (x))
+
+#define KS2_DDRPHY_PIR_OFFSET		0x04
+#define KS2_DDRPHY_PGCR0_OFFSET		0x08
+#define KS2_DDRPHY_PGCR1_OFFSET		0x0C
+#define KS2_DDRPHY_PGSR0_OFFSET		0x10
+#define KS2_DDRPHY_PGSR1_OFFSET		0x14
+#define KS2_DDRPHY_PLLCR_OFFSET		0x18
+#define KS2_DDRPHY_PTR0_OFFSET		0x1C
+#define KS2_DDRPHY_PTR1_OFFSET		0x20
+#define KS2_DDRPHY_PTR2_OFFSET		0x24
+#define KS2_DDRPHY_PTR3_OFFSET		0x28
+#define KS2_DDRPHY_PTR4_OFFSET		0x2C
+#define KS2_DDRPHY_DCR_OFFSET		0x44
+
+#define KS2_DDRPHY_DTPR0_OFFSET		0x48
+#define KS2_DDRPHY_DTPR1_OFFSET		0x4C
+#define KS2_DDRPHY_DTPR2_OFFSET		0x50
+
+#define KS2_DDRPHY_MR0_OFFSET		0x54
+#define KS2_DDRPHY_MR1_OFFSET		0x58
+#define KS2_DDRPHY_MR2_OFFSET		0x5C
+#define KS2_DDRPHY_DTCR_OFFSET		0x68
+#define KS2_DDRPHY_PGCR2_OFFSET		0x8C
+
+#define KS2_DDRPHY_ZQ0CR1_OFFSET	0x184
+#define KS2_DDRPHY_ZQ1CR1_OFFSET	0x194
+#define KS2_DDRPHY_ZQ2CR1_OFFSET	0x1A4
+#define KS2_DDRPHY_ZQ3CR1_OFFSET	0x1B4
+
+#define KS2_DDRPHY_DATX8_8_OFFSET	0x3C0
+
+#define IODDRM_MASK			0x00000180
+#define ZCKSEL_MASK			0x01800000
+#define CL_MASK				0x00000072
+#define WR_MASK				0x00000E00
+#define BL_MASK				0x00000003
+#define RRMODE_MASK			0x00040000
+#define UDIMM_MASK			0x20000000
+#define BYTEMASK_MASK			0x0003FC00
+#define MPRDQ_MASK			0x00000080
+#define PDQ_MASK			0x00000070
+#define NOSRA_MASK			0x08000000
+#define ECC_MASK			0x00000001
+
+#define KS2_DDR3_MIDR_OFFSET		0x00
+#define KS2_DDR3_STATUS_OFFSET		0x04
+#define KS2_DDR3_SDCFG_OFFSET		0x08
+#define KS2_DDR3_SDRFC_OFFSET		0x10
+#define KS2_DDR3_SDTIM1_OFFSET		0x18
+#define KS2_DDR3_SDTIM2_OFFSET		0x1C
+#define KS2_DDR3_SDTIM3_OFFSET		0x20
+#define KS2_DDR3_SDTIM4_OFFSET		0x28
+#define KS2_DDR3_PMCTL_OFFSET		0x38
+#define KS2_DDR3_ZQCFG_OFFSET		0xC8
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/hardware-k2hk.h>
+#endif
+
+#ifndef __ASSEMBLY__
+static inline int cpu_is_k2hk(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int part_no	= (jtag_id >> 12) & 0xffff;
+
+	return ((part_no == 0xb981) ? 1 : 0);
+}
+
+static inline int cpu_revision(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int rev	= (jtag_id >> 28) & 0xf;
+
+	return rev;
+}
+
+void share_all_segments(int priv_id);
+int cpu_to_bus(u32 *ptr, u32 length);
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg);
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg);
+void init_ddr3(void);
+
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/i2c_defs.h b/arch/arm/include/asm/arch-keystone/i2c_defs.h
new file mode 100644
index 0000000..bf28626
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/i2c_defs.h
@@ -0,0 +1,86 @@
+/*
+ * keystone: i2c driver definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _KEYSTONE_I2C_H_
+#define _KEYSTONE_I2C_H_
+
+#define I2C_WRITE		0
+#define I2C_READ		1
+
+#define I2C0_BASE		0x02530000
+#define I2C1_BASE		0x02530400
+#define I2C2_BASE		0x02530800
+#define I2C_BASE		I2C0_BASE
+
+struct i2c_regs {
+	u32	i2c_oa;
+	u32	i2c_ie;
+	u32	i2c_stat;
+	u32	i2c_scll;
+	u32	i2c_sclh;
+	u32	i2c_cnt;
+	u32	i2c_drr;
+	u32	i2c_sa;
+	u32	i2c_dxr;
+	u32	i2c_con;
+	u32	i2c_iv;
+	u32	res_2c;
+	u32	i2c_psc;
+};
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE	(1 << 5)	/* Stop condition */
+#define I2C_IE_XRDY_IE	(1 << 4)	/* Transmit data ready */
+#define I2C_IE_RRDY_IE	(1 << 3)	/* Receive data ready */
+#define I2C_IE_ARDY_IE	(1 << 2)	/* Register access ready */
+#define I2C_IE_NACK_IE	(1 << 1)	/* No acknowledgment */
+#define I2C_IE_AL_IE	(1 << 0)	/* Arbitration lost */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB	(1 << 12)	/* Bus busy */
+#define I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
+#define I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
+#define I2C_STAT_AAS	(1 << 9)	/* Address as slave */
+#define I2C_STAT_SCD	(1 << 5)	/* Stop condition detect */
+#define I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
+#define I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
+#define I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
+#define I2C_STAT_NACK	(1 << 1)	/* No acknowledgment */
+#define I2C_STAT_AL	(1 << 0)	/* Arbitration lost */
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK	7
+#define I2C_INTCODE_NONE	0
+#define I2C_INTCODE_AL		1	/* Arbitration lost */
+#define I2C_INTCODE_NAK		2	/* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY	3	/* Register access ready */
+#define I2C_INTCODE_RRDY	4	/* Rcv data ready */
+#define I2C_INTCODE_XRDY	5	/* Xmit data ready */
+#define I2C_INTCODE_SCD		6	/* Stop condition detect */
+
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN	(1 << 5)	/* I2C module enable */
+#define I2C_CON_STB	(1 << 4)	/* Start byte mode (master mode only) */
+#define I2C_CON_MST	(1 << 10)	/* Master/slave mode */
+#define I2C_CON_TRX	(1 << 9)	/* Transmitter/receiver mode
+					   (master mode only) */
+#define I2C_CON_XA	(1 << 8)	/* Expand address */
+#define I2C_CON_STP	(1 << 11)	/* Stop condition (master mode only) */
+#define I2C_CON_STT	(1 << 13)	/* Start condition (master mode only) */
+#define I2C_CON_FREE	(1 << 14)	/* Free run on emulation */
+
+#define I2C_TIMEOUT	0xffff0000	/* Timeout mask for poll_i2c_irq() */
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/nand_defs.h b/arch/arm/include/asm/arch-keystone/nand_defs.h
new file mode 100644
index 0000000..6d6f846
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/nand_defs.h
@@ -0,0 +1,25 @@
+/*
+ * nand driver definitions to re-use davinci nand driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <linux/mtd/nand.h>
+
+#define	MASK_CLE	0x4000
+#define	MASK_ALE	0x2000
+
+#define NAND_READ_START		0x00
+#define NAND_READ_END		0x30
+#define NAND_STATUS		0x70
+
+extern void davinci_nand_init(struct nand_chip *nand);
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/psc_defs.h b/arch/arm/include/asm/arch-keystone/psc_defs.h
new file mode 100644
index 0000000..edba256
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/psc_defs.h
@@ -0,0 +1,91 @@
+/*
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _PSC_DEFS_H_
+#define _PSC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+/******************************************************************************
+ * FILE PURPOSE: Local Power Sleep Controller definitions
+ ******************************************************************************
+ * FILE NAME: psc_defs.h
+ *
+ * DESCRIPTION: Provides local definitions for the power saver controller
+ *
+ *****************************************************************************/
+
+/* Register offsets */
+#define PSC_REG_PTCMD		0x120
+#define PSC_REG_PSTAT	        0x128
+#define PSC_REG_PDSTAT(x)	(0x200 + (4*(x)))
+#define PSC_REG_PDCTL(x)	(0x300 + (4*(x)))
+#define PSC_REG_MDCFG(x)	(0x600 + (4*(x)))
+#define PSC_REG_MDSTAT(x)	(0x800 + (4*(x)))
+#define PSC_REG_MDCTL(x)	(0xa00 + (4*(x)))
+
+#define BOOTBITMASK(x, y)	((((((u32)1 << (((u32)x)-((u32)y)+(u32)1)) - \
+				  (u32)1)) << ((u32)y)))
+
+#define BOOT_READ_BITFIELD(z, x, y)	(((u32)z) & BOOTBITMASK(x, y)) >> (y)
+#define BOOT_SET_BITFIELD(z, f, x, y)	(((u32)z) & ~BOOTBITMASK(x, y)) | \
+					 ((((u32)f) << (y)) & BOOTBITMASK(x, y))
+
+/* Macros to access register fields */
+/* PDCTL */
+#define PSC_REG_PDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 0, 0)
+#define PSC_REG_PDCTL_SET_PDMODE(x, y)	BOOT_SET_BITFIELD((x), (y), 15, 12)
+
+/* PDSTAT */
+#define PSC_REG_PDSTAT_GET_STATE(x)	BOOT_READ_BITFIELD((x), 4, 0)
+
+/* MDCFG */
+#define PSC_REG_MDCFG_GET_PD(x)		BOOT_READ_BITFIELD((x), 20, 16)
+#define PSC_REG_MDCFG_GET_RESET_ISO(x)	BOOT_READ_BITFIELD((x), 14, 14)
+
+/* MDCTL */
+#define PSC_REG_MDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 4, 0)
+#define PSC_REG_MDCTL_SET_LRSTZ(x, y)	BOOT_SET_BITFIELD((x), (y), 8, 8)
+#define PSC_REG_MDCTL_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDCTL_SET_RESET_ISO(x, y)	BOOT_SET_BITFIELD((x), (y), \
+								  12, 12)
+
+/* MDSTAT */
+#define PSC_REG_MDSTAT_GET_STATUS(x)	BOOT_READ_BITFIELD((x), 5, 0)
+#define PSC_REG_MDSTAT_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDSTAT_GET_LRSTDONE(x)	BOOT_READ_BITFIELD((x), 9, 9)
+
+/* PDCTL states */
+#define PSC_REG_VAL_PDCTL_NEXT_ON		1
+#define PSC_REG_VAL_PDCTL_NEXT_OFF		0
+
+#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP		0
+
+/* MDCTL states */
+#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE	0
+#define PSC_REG_VAL_MDCTL_NEXT_OFF		2
+#define PSC_REG_VAL_MDCTL_NEXT_ON		3
+
+
+/* MDSTAT states */
+#define PSC_REG_VAL_MDSTAT_STATE_ON		3
+#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG	0x24
+#define PSC_REG_VAL_MDSTAT_STATE_OFF		2
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1	0x20
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2	0x21
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3	0x22
+
+
+/* Timeout limit on checking PTSTAT. This is the number of times the
+ * wait function will be called before giving up. */
+#define PSC_PTSTAT_TIMEOUT_LIMIT    100
+
+u32 psc_get_domain_num(u32 mod_num);
+int psc_enable_module(u32 mod_num);
+int psc_disable_module(u32 mod_num);
+int psc_disable_domain(u32 domain_num);
+
+#endif /* _PSC_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/spl.h b/arch/arm/include/asm/arch-keystone/spl.h
new file mode 100644
index 0000000..eb0b3ed
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/spl.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef	_ASM_ARCH_SPL_H_
+#define	_ASM_SPL_H_
+
+#define BOOT_DEVICE_SPI		2
+
+#endif
diff --git a/board/ti/k2hk_evm/Makefile b/board/ti/k2hk_evm/Makefile
new file mode 100644
index 0000000..3645f2f
--- /dev/null
+++ b/board/ti/k2hk_evm/Makefile
@@ -0,0 +1,9 @@
+#
+# K2HK-EVM: board Makefile
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= board.o
+obj-y	+= ddr3.o
diff --git a/board/ti/k2hk_evm/README b/board/ti/k2hk_evm/README
new file mode 100644
index 0000000..6ab660b
--- /dev/null
+++ b/board/ti/k2hk_evm/README
@@ -0,0 +1,56 @@
+U-Boot port for Texas Instruments XTCIEVMK2X
+============================================
+
+Author: Murali Karicheri <m-karicheri2@ti.com>
+
+This README has information on the u-boot port for XTCIEVMK2X EVM board.
+Documentation for this board can be found at
+  http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx
+
+The board is based on Texas Instruments Keystone2 family of SoCs : K2H, K2K.
+More details on these SoCs are available at company websites
+ K2K: http://www.ti.com/product/tci6638k2k
+ K2H: http://www.ti.com/product/tci6638k2h
+
+Board configuration:
+====================
+
+Some of the peripherals that are configured by u-boot are:-
+
+1. 2GB DDR3 (can support 8GB SO DIMM as well)
+2. 512M NAND (over ti emif16 bus)
+3. 6MB MSM SRAM (part of the SoC)
+4. two 1GBit Ethernet ports (SoC supports upto 4)
+5. two UART ports
+6. three i2c interfaces
+7. three spi interfaces (only 1 interface supported in driver)
+
+There are seperate PLLs to drive clocks to Tetris ARM and Peripherals.
+To bring up SMP Linux on this board, there is a boot monitor
+code that will be installed in MSMC SRAM. There is command available
+to install this image from u-boot.
+
+The port related files can be found at following folders
+ keystone2 SoC related files: arch/arm/cpu/armv7/keystone/
+ K2HK evm board files: board/ti/k2hk_evm/
+
+board configuration file: include/configs/k2hk_evm.h
+
+Supported boot modes:
+ - SPI NOR boot
+
+Supported image formats:-
+ - u-boot.bin: for loading and running u-boot.bin through Texas instruments
+               code composure studio (CCS)
+ - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot
+
+Build instructions:
+===================
+
+To build u-boot.bin
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
+
+To build u-boot-spi.gph
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
new file mode 100644
index 0000000..0ab3aef
--- /dev/null
+++ b/board/ti/k2hk_evm/board.c
@@ -0,0 +1,246 @@
+/*
+ * K2HK EVM : Board initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <exports.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/nand_defs.h>
+#include <asm/arch/psc_defs.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 device_big_endian;
+
+unsigned int external_clk[ext_clk_count] = {
+	[sys_clk]	=	122880000,
+	[alt_core_clk]	=	125000000,
+	[pa_clk]	=	122880000,
+	[tetris_clk]	=	125000000,
+	[ddr3a_clk]	=	100000000,
+	[ddr3b_clk]	=	100000000,
+	[mcm_clk]	=	312500000,
+	[pcie_clk]	=	100000000,
+	[sgmii_srio_clk] =	156250000,
+	[xgmii_clk]	=	156250000,
+	[usb_clk]	=	100000000,
+	[rp1_clk]	=	123456789    /* TODO: cannot find
+						what is that */
+};
+
+static struct async_emif_config async_emif_config[ASYNC_EMIF_NUM_CS] = {
+	{			/* CS0 */
+		.mode		= ASYNC_EMIF_MODE_NAND,
+		.wr_setup	= 0xf,
+		.wr_strobe	= 0x3f,
+		.wr_hold	= 7,
+		.rd_setup	= 0xf,
+		.rd_strobe	= 0x3f,
+		.rd_hold	= 7,
+		.turn_around	= 3,
+		.width		= ASYNC_EMIF_8,
+	},
+
+};
+
+static struct pll_init_data pll_config[] = {
+	CORE_PLL_1228,
+	PASS_PLL_983,
+	TETRIS_PLL_1200,
+};
+
+int dram_init(void)
+{
+	init_ddr3();
+
+	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+				    CONFIG_MAX_RAM_BANK_SIZE);
+	init_async_emif(ARRAY_SIZE(async_emif_config), async_emif_config);
+	return 0;
+}
+
+/* Byte swap the 32-bit data if the device is BE */
+int cpu_to_bus(u32 *ptr, u32 length)
+{
+	u32 i;
+
+	if (device_big_endian)
+		for (i = 0; i < length; i++, ptr++)
+			*ptr = __swab32(*ptr);
+
+	return 0;
+}
+
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+int board_early_init_f(void)
+{
+	init_plls(ARRAY_SIZE(pll_config), pll_config);
+	return 0;
+}
+#endif
+
+int board_init(void)
+{
+	gd->bd->bi_arch_number = -1;
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	return 0;
+}
+
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+#endif
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+#define K2_DDR3_START_ADDR 0x80000000
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	u64 start[2];
+	u64 size[2];
+	char name[32], *env, *endp;
+	int lpae, nodeoffset;
+	u32 ddr3a_size;
+	int nbanks;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	ddr3a_size = 0;
+	if (lpae) {
+		env = getenv("ddr3a_size");
+		if (env)
+			ddr3a_size = simple_strtol(env, NULL, 10);
+		if ((ddr3a_size != 8) && (ddr3a_size != 4))
+			ddr3a_size = 0;
+	}
+
+	nbanks = 1;
+	start[0] = bd->bi_dram[0].start;
+	size[0]  = bd->bi_dram[0].size;
+
+	/* adjust memory start address for LPAE */
+	if (lpae) {
+		start[0] -= K2_DDR3_START_ADDR;
+		start[0] += CONFIG_SYS_LPAE_SDRAM_BASE;
+	}
+
+	if ((size[0] == 0x80000000) && (ddr3a_size != 0)) {
+		size[1] = ((u64)ddr3a_size - 2) << 30;
+		start[1] = 0x880000000;
+		nbanks++;
+	}
+
+	/* reserve memory@start of bank */
+	sprintf(name, "mem_reserve_head");
+	env = getenv(name);
+	if (env) {
+		start[0] += ustrtoul(env, &endp, 0);
+		size[0] -= ustrtoul(env, &endp, 0);
+	}
+
+	sprintf(name, "mem_reserve");
+	env = getenv(name);
+	if (env)
+		size[0] -= ustrtoul(env, &endp, 0);
+
+	fdt_fixup_memory_banks(blob, start, size, nbanks);
+
+	/* Fix up the initrd */
+	if (lpae) {
+		u64 initrd_start, initrd_end;
+		u32 *prop1, *prop2;
+		int err;
+		nodeoffset = fdt_path_offset(blob, "/chosen");
+		if (nodeoffset >= 0) {
+			prop1 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-start", NULL);
+			prop2 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-end", NULL);
+			if (prop1 && prop2) {
+				initrd_start = __be32_to_cpu(*prop1);
+				initrd_start -= K2_DDR3_START_ADDR;
+				initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_start = __cpu_to_be64(initrd_start);
+				initrd_end = __be32_to_cpu(*prop2);
+				initrd_end -= K2_DDR3_START_ADDR;
+				initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_end = __cpu_to_be64(initrd_end);
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-start");
+				if (err < 0)
+					printf("error deleting linux,initrd-start\n");
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-end");
+				if (err < 0)
+					printf("error deleting linux,initrd-end\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-start",
+						  &initrd_start,
+						  sizeof(initrd_start));
+				if (err < 0)
+					printf("error adding linux,initrd-start\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-end",
+						  &initrd_end,
+						  sizeof(initrd_end));
+				if (err < 0)
+					printf("error adding linux,initrd-end\n");
+			}
+		}
+	}
+}
+
+void ft_board_setup_ex(void *blob, bd_t *bd)
+{
+	int	lpae;
+	char	*env;
+	u64	*reserve_start, size;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	if (lpae) {
+		/*
+		 * the initrd and other reserved memory areas are
+		 * embedded in in the DTB itslef. fix up these addresses
+		 * to 36 bit format
+		 */
+		reserve_start = (u64 *)((char *)blob +
+				       fdt_off_mem_rsvmap(blob));
+		while (1) {
+			*reserve_start = __cpu_to_be64(*reserve_start);
+			size = __cpu_to_be64(*(reserve_start + 1));
+			if (size) {
+				*reserve_start -= K2_DDR3_START_ADDR;
+				*reserve_start +=
+					CONFIG_SYS_LPAE_SDRAM_BASE;
+				*reserve_start =
+					__cpu_to_be64(*reserve_start);
+			} else {
+				break;
+			}
+			reserve_start += 2;
+		}
+	}
+}
+#endif
diff --git a/board/ti/k2hk_evm/ddr3.c b/board/ti/k2hk_evm/ddr3.c
new file mode 100644
index 0000000..973c35d
--- /dev/null
+++ b/board/ti/k2hk_evm/ddr3.c
@@ -0,0 +1,269 @@
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <i2c.h>
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1600_64A = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_64 = {
+	.sdcfg		= 0x6200CE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1600_32 = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_32 = {
+	.sdcfg		= 0x6200DE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0x70073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64A = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_64 = {
+	.sdcfg		= 0x62008C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1333_32 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_32 = {
+	.sdcfg		= 0x62009C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xf0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+/******************************************************/
+int get_dimm_params(char *dimm_name)
+{
+	u8 spd_params[256];
+	int ret;
+	int old_bus;
+
+	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	old_bus = i2c_get_bus_num();
+	i2c_set_bus_num(1);
+
+	ret = i2c_read(0x53, 0, 1, spd_params, 256);
+
+	i2c_set_bus_num(old_bus);
+
+	dimm_name[0] = '\0';
+
+	if (ret) {
+		puts("Cannot read DIMM params\n");
+		return 1;
+	}
+
+	/*
+	 * We need to convert spd data to dimm parameters
+	 * and to DDR3 EMIF and PHY regirsters values.
+	 * For now we just return DIMM type string value.
+	 * Caller may use this value to choose appropriate
+	 * a pre-set DDR3 configuration
+	 */
+
+	strncpy(dimm_name, (char *)&spd_params[0x80], 18);
+	dimm_name[18] = '\0';
+
+	return 0;
+}
+
+struct pll_init_data ddr3a_333 = DDR3_PLL_333(A);
+struct pll_init_data ddr3b_333 = DDR3_PLL_333(B);
+struct pll_init_data ddr3a_400 = DDR3_PLL_400(A);
+struct pll_init_data ddr3b_400 = DDR3_PLL_400(B);
+
+void init_ddr3(void)
+{
+	char dimm_name[32];
+
+	get_dimm_params(dimm_name);
+
+	printf("Detected SO-DIMM [%s]\n", dimm_name);
+
+	if (!strcmp(dimm_name, "18KSF1G72HZ-1G6E2 ")) {
+		init_pll(&ddr3a_400);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_64);
+			printf("DRAM:  Capacity 8 GiB (includes reported below)\n");
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_32);
+			printf("DRAM:  Capacity 4 GiB (includes reported below)\n");
+		}
+	} else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) {
+		init_pll(&ddr3a_333);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_64);
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_32);
+		}
+	} else {
+		printf("Unknown SO-DIMM. Cannot configure DDR3\n");
+		while (1)
+			;
+	}
+
+	init_pll(&ddr3b_333);
+	init_ddrphy(K2HK_DDR3B_DDRPHYC, &ddr3phy_1333_64);
+	init_ddremif(K2HK_DDR3B_EMIF_CTRL_BASE, &ddr3_1333_64);
+}
+
diff --git a/boards.cfg b/boards.cfg
index a8336cc..1690315 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -362,6 +362,7 @@ Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_microzed			-
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm010			zynq_zc770:ZC770_XM010                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm012			zynq_zc770:ZC770_XM012                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm013			zynq_zc770:ZC770_XM013                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
+Active  arm         armv7          keystone    ti              k2hk_evm            k2hk_evm                             -                                                                                                                                 Vitaly Andrianov <vitalya@ti.com>
 Active  arm         armv7:arm720t  tegra114    nvidia          dalmore             dalmore                              -                                                                                                                                 Tom Warren <twarren@nvidia.com>
 Active  arm         armv7:arm720t  tegra20     avionic-design  medcom-wide         medcom-wide                          -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
 Active  arm         armv7:arm720t  tegra20     avionic-design  plutux              plutux                               -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index fa3a875..996a8f2 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 obj-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
+obj-$(CONFIG_DRIVER_KEYSTONE_I2C) += keystone_i2c.o
 obj-$(CONFIG_DW_I2C) += designware_i2c.o
 obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
 obj-$(CONFIG_I2C_MV) += mv_i2c.o
diff --git a/drivers/i2c/keystone_i2c.c b/drivers/i2c/keystone_i2c.c
new file mode 100644
index 0000000..e2093c1
--- /dev/null
+++ b/drivers/i2c/keystone_i2c.c
@@ -0,0 +1,372 @@
+/*
+ * TI Keystone i2c driver
+ * Based on TI DaVinci (TMS320DM644x) I2C driver.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/i2c_defs.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+						(struct i2c_regs *)I2C_BASE;
+
+static unsigned int __attribute__((section(".data")))
+		bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 };
+static unsigned int __attribute__((section(".data"))) current_bus;
+
+#define CHECK_NACK() \
+	do {\
+		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
+			REG(&(i2c_base->i2c_con)) = 0;\
+			return 1;\
+		} \
+	} while (0)
+
+static int wait_for_bus(void)
+{
+	int	stat, timeout;
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		stat = REG(&(i2c_base->i2c_stat));
+		if (!((stat) & I2C_STAT_BB)) {
+			REG(&(i2c_base->i2c_stat)) = 0xffff;
+			return 0;
+		}
+
+		REG(&(i2c_base->i2c_stat)) = stat;
+		udelay(50000);
+	}
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return 1;
+}
+
+
+static int poll_i2c_irq(int mask)
+{
+	int	stat, timeout;
+
+	for (timeout = 0; timeout < 10; timeout++) {
+		udelay(1000);
+		stat = REG(&(i2c_base->i2c_stat));
+		if (stat & mask)
+			return stat;
+	}
+
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return stat | I2C_TIMEOUT;
+}
+
+
+void flush_rx(void)
+{
+	while (1) {
+		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
+			break;
+
+		REG(&(i2c_base->i2c_drr));
+		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
+		udelay(1000);
+	}
+}
+
+
+void i2c_init(int speed, int slaveadd)
+{
+	u_int32_t	div, psc;
+
+	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		udelay(50000);
+	}
+
+	psc = 2;
+	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
+	REG(&(i2c_base->i2c_psc)) = psc;
+	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100;
+	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
+
+	REG(&(i2c_base->i2c_oa)) = slaveadd;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+
+	/* Interrupts must be enabled or I2C module won't work */
+	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
+
+	/* Now enable I2C controller (get it out of reset) */
+	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
+
+	udelay(1000);
+
+	if (gd->flags & GD_FLG_RELOC)
+		bus_initialized[current_bus] = 1;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+	return 0;
+}
+
+int i2c_probe(u_int8_t chip)
+{
+	int	rc = 1;
+
+	if (chip == REG(&(i2c_base->i2c_oa)))
+		return rc;
+
+	REG(&(i2c_base->i2c_con)) = 0;
+	if (wait_for_bus())
+		return 1;
+
+	/* try to read one byte from current (or only) address */
+	REG(&(i2c_base->i2c_cnt)) = 1;
+	REG(&(i2c_base->i2c_sa))  = chip;
+	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+				     I2C_CON_STP);
+	udelay(50000);
+
+	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
+		rc = 0;
+		flush_rx();
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+	} else {
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
+		udelay(20000);
+		if (wait_for_bus())
+			return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	return rc;
+}
+
+
+int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
+	}
+
+	if (wait_for_bus())
+		return 1;
+
+	if (alen != 0) {
+		/* Start address phase */
+		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
+		REG(&(i2c_base->i2c_cnt)) = alen;
+		REG(&(i2c_base->i2c_sa)) = chip;
+		REG(&(i2c_base->i2c_con)) = tmp;
+
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		switch (alen) {
+		case 2:
+			/* Send address MSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK |
+					   I2C_STAT_ARDY);
+
+			CHECK_NACK();
+
+			if (!(tmp & I2C_STAT_ARDY)) {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+		}
+	}
+
+	/* Address phase is over, now read 'len' bytes and stop */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK |
+				   I2C_STAT_ROVR);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_RRDY) {
+			buf[i] = REG(&(i2c_base->i2c_drr));
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+
+int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
+{
+	u_int32_t	tmp;
+	int		i;
+
+	if ((alen < 0) || (alen > 2)) {
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
+	}
+	if (len < 0) {
+		printf("%s(): bogus length %x\n", __func__, len);
+		return 1;
+	}
+
+	if (wait_for_bus())
+		return 1;
+
+	/* Start address phase */
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+		I2C_CON_TRX | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
+		len & 0xffff : (len & 0xffff) + alen;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
+
+	switch (alen) {
+	case 2:
+		/* Send address MSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+		/* No break, fall through */
+	case 1:
+		/* Send address LSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+	}
+
+	for (i = 0; i < len; i++) {
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+		CHECK_NACK();
+
+		if (tmp & I2C_STAT_XRDY)
+			REG(&(i2c_base->i2c_dxr)) = buf[i];
+		else
+			return 1;
+	}
+
+	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
+
+	CHECK_NACK();
+
+	if (!(tmp & I2C_STAT_SCD)) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
+	}
+
+	flush_rx();
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	switch (bus) {
+#if I2C_BUS_MAX == 3
+	case 2:
+		i2c_base = (struct i2c_regs *)I2C2_BASE;
+		break;
+#endif
+#if I2C_BUS_MAX >= 2
+	case 1:
+		i2c_base = (struct i2c_regs *)I2C1_BASE;
+		break;
+#endif
+	default:
+		i2c_base = (struct i2c_regs *)I2C0_BASE;
+		bus = 0;
+	}
+
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return (int) current_bus;
+}
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index fbc37b2..8a13454 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -30,6 +30,11 @@
 #define serial_in(y)		readb(y)
 #endif
 
+#if defined(CONFIG_K2HK_EVM)
+#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE   0
+#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0))
+#endif
+
 #ifndef CONFIG_SYS_NS16550_IER
 #define CONFIG_SYS_NS16550_IER  0x00
 #endif /* CONFIG_SYS_NS16550_IER */
@@ -77,6 +82,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 	/* /16 is proper to hit 115200 with 48MHz */
 	serial_out(0, &com_port->mdr1);
 #endif /* CONFIG_OMAP */
+#if defined(CONFIG_K2HK_EVM)
+	serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC);
+#endif
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
new file mode 100644
index 0000000..a43318a
--- /dev/null
+++ b/include/configs/k2hk_evm.h
@@ -0,0 +1,221 @@
+/*
+ * Configuration header file for TI's k2hk-evm
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* Platform type */
+#define CONFIG_SOC_K2HK
+#define CONFIG_K2HK_EVM
+
+/* U-Boot Build Configuration */
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is a 2nd stage loader */
+#define CONFIG_SYS_NO_FLASH		/* that is, no *NOR* flash */
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_SYS_THUMB_BUILD
+
+/* SoC Configuration */
+#define CONFIG_ARMV7
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_TEXT_BASE		0x0c001000
+#define CONFIG_OF_LIBFDT		1
+#define CONFIG_OF_BOARD_SETUP
+#define CONFIG_SYS_DCACHE_OFF
+
+/* Memory Configuration */
+#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_LPAE_SDRAM_BASE	0x800000000
+#define CONFIG_MAX_RAM_BANK_SIZE	(2 << 30)	/* 2GB */
+#define CONFIG_STACKSIZE		(512 << 10)	/* 512 KiB */
+#define CONFIG_SYS_MALLOC_LEN		(1024 << 10)	/* 1 MiB */
+#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + 32 << 20)
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE -	\
+					 GENERATED_GBL_DATA_SIZE)
+
+/* SPL SPI Loader Configuration */
+#define CONFIG_SPL_TEXT_BASE		0x0c200000
+#define CONFIG_SPL_PAD_TO		65536
+#define CONFIG_SPL_MAX_SIZE		(CONFIG_SPL_PAD_TO - 8)
+#define CONFIG_SPL_BSS_START_ADDR	(CONFIG_SPL_TEXT_BASE +		\
+					 CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE		(32 * 1024)
+#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR +	\
+					 CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)
+#define CONFIG_SPL_STACK_SIZE		(8 * 1024)
+#define CONFIG_SPL_STACK		(CONFIG_SYS_SPL_MALLOC_START +	\
+					 CONFIG_SYS_SPL_MALLOC_SIZE +	\
+					 CONFIG_SPL_STACK_SIZE - 4)
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_BUS		0
+#define CONFIG_SPL_SPI_CS		0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	CONFIG_SPL_PAD_TO
+#define CONFIG_SPL_FRAMEWORK
+
+/* UART Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_COM1		K2HK_UART0_BASE
+#define CONFIG_SYS_NS16550_CLK		clk_get_rate(K2HK_CLK1_6)
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+
+/* SPI Configuration */
+#define CONFIG_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI_BASE		K2HK_SPI_BASE
+#define CONFIG_SYS_SPI_CLK		clk_get_rate(K2HK_LPSC_EMIF25_SPI)
+#define CONFIG_SF_DEFAULT_SPEED		30000000
+#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+
+/* I2C Configuration */
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_KEYSTONE_I2C
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0x10	/* SMBus host address */
+#define CONFIG_I2C_MULTI_BUS		1
+#define I2C_BUS_MAX			3
+
+/* EEPROM definitions */
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         2
+#define CONFIG_SYS_I2C_EEPROM_ADDR             0x50
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      6
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+
+/* NAND Configuration */
+#define CONFIG_NAND_DAVINCI
+#define CONFIG_SYS_NAND_CS		2
+#define CONFIG_SYS_NAND_USE_FLASH_BBT
+#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
+#define CONFIG_SYS_NAND_PAGE_2K
+
+#define CONFIG_SYS_NAND_LARGEPAGE
+#define CONFIG_SYS_NAND_BASE_LIST	{ 0x30000000, }
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_MAX_CHIPS	1
+#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+#define CONFIG_ENV_SIZE			(256 << 10)	/* 256 KiB */
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET		0x100000
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define MTDIDS_DEFAULT			"nand0=davinci_nand.0"
+#define PART_BOOT			"1024k(bootloader)ro,"
+#define PART_PARAMS			"512k(params)ro,"
+#define PART_UBI			"-(ubifs)"
+#define MTDPARTS_DEFAULT		"mtdparts=davinci_nand.0:"	\
+					PART_BOOT PART_PARAMS PART_UBI
+
+/* U-Boot command configuration */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_EEPROM
+
+/* U-Boot general configuration */
+#define CONFIG_SYS_PROMPT		"K2HK EVM # "
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SYS_PBSIZE		2048
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_TIMESTAMP
+
+#define CONFIG_BOOTDELAY		3
+#define CONFIG_BOOTFILE			"uImage"
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"boot=ramfs\0"							\
+	"tftp_root=/\0"							\
+	"nfs_root=/export\0"						\
+	"mem_lpae=1\0"							\
+	"mem_reserve=512M\0"						\
+	"addr_fdt=0x87000000\0"						\
+	"addr_kern=0x88000000\0"					\
+	"addr_mon=0x0c5f0000\0"						\
+	"addr_uboot=0x87000000\0"					\
+	"addr_fs=0x82000000\0"						\
+	"addr_ubi=0x82000000\0"						\
+	"fdt_high=0xffffffff\0"						\
+	"run_mon=mon_install ${addr_mon}\0"				\
+	"run_kern=bootm ${addr_kern} - ${addr_fdt}\0"			\
+	"init_ubi=run args_all args_ubi; "				\
+		"ubi part ubifs; ubifsmount boot\0"			\
+	"get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0"		\
+	"get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0"		\
+	"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0"		\
+	"burn_uboot=sf probe; sf erase 0 0x100000; "			\
+		"sf write ${addr_uboot} 0 ${filesize}\0"		\
+	"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0"	\
+	"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "	\
+		"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0"	\
+	"burn_ubi=nand erase.part ubifs; "				\
+		"nand write ${addr_ubi} ubifs ${filesize}\0"		\
+	"init_ramfs=run args_all args_ramfs get_fs_ramfs\0"		\
+	"args_ramfs=setenv bootargs ${bootargs} earlyprintk "		\
+		"rdinit=/sbin/init rw root=/dev/ram0 "			\
+		"initrd=0x802000000,9M\0"				\
+	"mtdparts=mtdparts=davinci_nand.0:"				\
+		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
+#define CONFIG_BOOTCOMMAND						\
+	"run init_${boot} get_fdt_${boot} get_mon_${boot} "		\
+		"get_kern_${boot} run_mon run_kern"
+#define CONFIG_BOOTARGS							\
+
+/* Linux interfacing */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_SYS_BARGSIZE		1024
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x08000000)
+#define LINUX_BOOT_PARAM_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x100)
+
+#define CONFIG_SUPPORT_RAW_INITRD
+
+/* we may include files below only after all above definitions */
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#define CONFIG_SYS_HZ_CLOCK		clk_get_rate(K2HK_CLK1_6)
+
+#endif /* __CONFIG_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                     ` (5 preceding siblings ...)
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM Murali Karicheri
@ 2014-02-10  8:32   ` Albert ARIBAUD
  2014-02-10 17:22     ` Murali Karicheri
  2014-02-10 21:23   ` Tom Rini
  7 siblings, 1 reply; 716+ messages in thread
From: Albert ARIBAUD @ 2014-02-10  8:32 UTC (permalink / raw)
  To: u-boot

Hi Murali,

On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
<m-karicheri2@ti.com> wrote:

>  - Resending since I missed some in the CC
> 
> This patch series add support for keystone2 SoC and K2HK EVM.
> 
> Following patches were reviewed before in this list and v1 of the
> same is send with review comments incorporated:-
>   - tools: mkimage: add support for gpimage format
>   - arm: add support for arch timer
>   - NAND: DaVinci: allow forced disable of subpage writes
> 
> The patch below is added as a seperate patch based on comments:-
>    - tools: sort the entries in Makefile
> 
> Murali Karicheri (5):
>   tools: sort the entries in Makefile

>   tools: mkimage: add support for gpimage format

Is this image format required? Can't one of the existing image formats
be used?

>   NAND: DaVinci: allow forced disable of subpage writes
>   k2hk: add support for k2hk SOC and EVM
>   keystone2: net: add keystone ethernet driver

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-10  8:32   ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Albert ARIBAUD
@ 2014-02-10 17:22     ` Murali Karicheri
  2014-02-10 18:01       ` Albert ARIBAUD
  0 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-10 17:22 UTC (permalink / raw)
  To: u-boot

On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> Hi Murali,
>
> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> <m-karicheri2@ti.com> wrote:
>
>>   - Resending since I missed some in the CC
>>
>> This patch series add support for keystone2 SoC and K2HK EVM.
>>
>> Following patches were reviewed before in this list and v1 of the
>> same is send with review comments incorporated:-
>>    - tools: mkimage: add support for gpimage format
>>    - arm: add support for arch timer
>>    - NAND: DaVinci: allow forced disable of subpage writes
>>
>> The patch below is added as a seperate patch based on comments:-
>>     - tools: sort the entries in Makefile
>>
>> Murali Karicheri (5):
>>    tools: sort the entries in Makefile
>>    tools: mkimage: add support for gpimage format
> Is this image format required? Can't one of the existing image formats
> be used?
Alebert,

Thanks for your response.

We are actually re-using part of the OMAP image format by factoring out 
the common code
and re-using.  So this is not a new format. Please review the code.

Murali
>>    NAND: DaVinci: allow forced disable of subpage writes
>>    k2hk: add support for k2hk SOC and EVM
>>    keystone2: net: add keystone ethernet driver
> Amicalement,

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-10 17:22     ` Murali Karicheri
@ 2014-02-10 18:01       ` Albert ARIBAUD
  2014-02-10 19:42         ` Murali Karicheri
  0 siblings, 1 reply; 716+ messages in thread
From: Albert ARIBAUD @ 2014-02-10 18:01 UTC (permalink / raw)
  To: u-boot

Hi Murali,

On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
<m-karicheri2@ti.com> wrote:

> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> > Hi Murali,
> >
> > On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> > <m-karicheri2@ti.com> wrote:
> >
> >>   - Resending since I missed some in the CC
> >>
> >> This patch series add support for keystone2 SoC and K2HK EVM.
> >>
> >> Following patches were reviewed before in this list and v1 of the
> >> same is send with review comments incorporated:-
> >>    - tools: mkimage: add support for gpimage format
> >>    - arm: add support for arch timer
> >>    - NAND: DaVinci: allow forced disable of subpage writes
> >>
> >> The patch below is added as a seperate patch based on comments:-
> >>     - tools: sort the entries in Makefile
> >>
> >> Murali Karicheri (5):
> >>    tools: sort the entries in Makefile
> >>    tools: mkimage: add support for gpimage format
> > Is this image format required? Can't one of the existing image formats
> > be used?
> Alebert,
> 
> Thanks for your response.
> 
> We are actually re-using part of the OMAP image format by factoring out 
> the common code
> and re-using.  So this is not a new format. Please review the code.

Thanks. This describes what you do and how you do it, but it does not
tell me why you are doing it and why you can't do otherwise. Let me
rephrase my question since you're mentioning branching off the OMAP
image format: why branch off? Why not simply use the existing OMAP image
format? Or another one?

> Murali

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-10 18:01       ` Albert ARIBAUD
@ 2014-02-10 19:42         ` Murali Karicheri
  2014-02-10 19:58           ` Albert ARIBAUD
  0 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-10 19:42 UTC (permalink / raw)
  To: u-boot

On 2/10/2014 1:01 PM, Albert ARIBAUD wrote:
> Hi Murali,
>
> On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
> <m-karicheri2@ti.com> wrote:
>
>> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
>>> Hi Murali,
>>>
>>> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
>>> <m-karicheri2@ti.com> wrote:
>>>
>>>>    - Resending since I missed some in the CC
>>>>
>>>> This patch series add support for keystone2 SoC and K2HK EVM.
>>>>
>>>> Following patches were reviewed before in this list and v1 of the
>>>> same is send with review comments incorporated:-
>>>>     - tools: mkimage: add support for gpimage format
>>>>     - arm: add support for arch timer
>>>>     - NAND: DaVinci: allow forced disable of subpage writes
>>>>
>>>> The patch below is added as a seperate patch based on comments:-
>>>>      - tools: sort the entries in Makefile
>>>>
>>>> Murali Karicheri (5):
>>>>     tools: sort the entries in Makefile
>>>>     tools: mkimage: add support for gpimage format
>>> Is this image format required? Can't one of the existing image formats
>>> be used?
>> Alebert,
>>
>> Thanks for your response.
>>
>> We are actually re-using part of the OMAP image format by factoring out
>> the common code
>> and re-using.  So this is not a new format. Please review the code.
> Thanks. This describes what you do and how you do it, but it does not
> tell me why you are doing it and why you can't do otherwise. Let me
> rephrase my question since you're mentioning branching off the OMAP
> image format: why branch off? Why not simply use the existing OMAP image
> format? Or another one?
Because the ROM bootloader in our platform (keystone2) expect the header 
to be in
the following format :-

<size - 4 byte> <load addr- 4 byte> <data>

OMAP uses different format
<omap header 512 bytes> <size - 4 byte> <load addr - 4 bytes>

gp header (size, loadaddr)  is common between the two image formats. So that
is factored out and used in our platform. Hope this is clear now.

Regards,

Murali
>> Murali
> Amicalement,

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-10 19:42         ` Murali Karicheri
@ 2014-02-10 19:58           ` Albert ARIBAUD
  0 siblings, 0 replies; 716+ messages in thread
From: Albert ARIBAUD @ 2014-02-10 19:58 UTC (permalink / raw)
  To: u-boot

Hi Murali,

On Mon, 10 Feb 2014 14:42:14 -0500, Murali Karicheri
<m-karicheri2@ti.com> wrote:

> On 2/10/2014 1:01 PM, Albert ARIBAUD wrote:
> > Hi Murali,
> >
> > On Mon, 10 Feb 2014 12:22:53 -0500, Murali Karicheri
> > <m-karicheri2@ti.com> wrote:
> >
> >> On 2/10/2014 3:32 AM, Albert ARIBAUD wrote:
> >>> Hi Murali,
> >>>
> >>> On Fri, 7 Feb 2014 18:23:07 -0500, Murali Karicheri
> >>> <m-karicheri2@ti.com> wrote:
> >>>
> >>>>    - Resending since I missed some in the CC
> >>>>
> >>>> This patch series add support for keystone2 SoC and K2HK EVM.
> >>>>
> >>>> Following patches were reviewed before in this list and v1 of the
> >>>> same is send with review comments incorporated:-
> >>>>     - tools: mkimage: add support for gpimage format
> >>>>     - arm: add support for arch timer
> >>>>     - NAND: DaVinci: allow forced disable of subpage writes
> >>>>
> >>>> The patch below is added as a seperate patch based on comments:-
> >>>>      - tools: sort the entries in Makefile
> >>>>
> >>>> Murali Karicheri (5):
> >>>>     tools: sort the entries in Makefile
> >>>>     tools: mkimage: add support for gpimage format
> >>> Is this image format required? Can't one of the existing image formats
> >>> be used?
> >> Alebert,
> >>
> >> Thanks for your response.
> >>
> >> We are actually re-using part of the OMAP image format by factoring out
> >> the common code
> >> and re-using.  So this is not a new format. Please review the code.
> > Thanks. This describes what you do and how you do it, but it does not
> > tell me why you are doing it and why you can't do otherwise. Let me
> > rephrase my question since you're mentioning branching off the OMAP
> > image format: why branch off? Why not simply use the existing OMAP image
> > format? Or another one?
> Because the ROM bootloader in our platform (keystone2) expect the header 
> to be in
> the following format :-
> 
> <size - 4 byte> <load addr- 4 byte> <data>
> 
> OMAP uses different format
> <omap header 512 bytes> <size - 4 byte> <load addr - 4 bytes>
> 
> gp header (size, loadaddr)  is common between the two image formats. So that
> is factored out and used in our platform. Hope this is clear now.

Ok, thanks.

> Regards,
> 
> Murali

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
                     ` (6 preceding siblings ...)
  2014-02-10  8:32   ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Albert ARIBAUD
@ 2014-02-10 21:23   ` Tom Rini
  7 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-10 21:23 UTC (permalink / raw)
  To: u-boot

On Fri, Feb 07, 2014 at 06:23:07PM -0500, Murali Karicheri wrote:

>  - Resending since I missed some in the CC
> 
> This patch series add support for keystone2 SoC and K2HK EVM.
> 
> Following patches were reviewed before in this list and v1 of the
> same is send with review comments incorporated:-
>   - tools: mkimage: add support for gpimage format
>   - arm: add support for arch timer
>   - NAND: DaVinci: allow forced disable of subpage writes
> 
> The patch below is added as a seperate patch based on comments:-
>    - tools: sort the entries in Makefile
> 
> Murali Karicheri (5):
>   tools: sort the entries in Makefile
>   tools: mkimage: add support for gpimage format
>   NAND: DaVinci: allow forced disable of subpage writes
>   k2hk: add support for k2hk SOC and EVM
>   keystone2: net: add keystone ethernet driver
> 
> Vitaly Andrianov (2):
>   fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
>   arm: add support for arch timer

For the next go-round, you shouldn't need to give git send-email
anything more than --subject-prefix='PATCH v3' to get the subject
correct and shorter.

In general:
- 7/7 got lost?  Or did I just miss it?
- There's a lot of what looks like copy/paste from davinci drivers, we
  need to better re-use the code in place (and move to common locations
  as needed).

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/e605d9fb/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
@ 2014-02-10 21:25     ` Tom Rini
  2014-02-11  1:05       ` Vitaly Andrianov
  0 siblings, 1 reply; 716+ messages in thread
From: Tom Rini @ 2014-02-10 21:25 UTC (permalink / raw)
  To: u-boot

On Fri, Feb 07, 2014 at 06:23:08PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> The keystone2 SOC requires to fix all 32 bit aliased addresses
> to their 36 physical format. This has to happen after all fdt
> nodes are added or modified.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>

Why can't this be done with the existing CONFIG_OF_BOARD_SETUP and 'fdt
boardsetup' command?

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/e1d775a1/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM Murali Karicheri
@ 2014-02-10 21:25     ` Tom Rini
  2014-02-11  1:44       ` Vitaly Andrianov
  2014-02-17 21:19       ` Andrianov, Vitaly
  0 siblings, 2 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-10 21:25 UTC (permalink / raw)
  To: u-boot

On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:

> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
> refer the ti/k2hk_evm/README for details on the board, build and other
> information.
> 
> This patch add support for keystone architecture and k2hk evm.

Globally, only use
/*
 * Multiline comments like this
 */

> +++ b/arch/arm/cpu/armv7/keystone/Makefile
> @@ -0,0 +1,18 @@
> +#
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y	+= aemif.o
> +obj-y   += init.o
> +obj-y   += psc.o
> +obj-y   += clock.o
> +obj-y   += cmd_clock.o
> +obj-y   += cmd_mon.o
> +obj-y   += msmc.o
> +obj-y   += lowlevel_init.o
> +obj-$(CONFIG_SPL_BUILD) += spl.o
> +obj-y	+= ddr3.o

Mix of space and tab, just tab it all out to line up please.

> +++ b/arch/arm/cpu/armv7/keystone/aemif.c
> @@ -0,0 +1,79 @@
> +/*
> + * Keystone2: Asynchronous EMIF Configuration
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +
> +#ifdef CONFIG_SOC_K2HK
> +#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
> +#endif

So, does Keystone 1 have this in a different location?

> +#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
> +#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
> +#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
> +#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)

Register access is done over structs not define of base + offset, please
rework.

> +#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
> +#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
> +#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
> +#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
> +#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
> +#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
> +#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
> +#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
> +#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
> +#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)

To avoid confusion please do AEMIF_CONFIG_... or AEMIF_CFG_... or maybe
just CFG_...

> +++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
[snip]
> +			prediv = (tmp & 0x3f) + 1;
> +			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
> +							mult) & 0x3f)) + 1;
> +			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
> +				      0xf) + 1;

Please define magic numbers, check globally.

> +	return ret;
> +}
> +
> +
> +
> +
> +unsigned long clk_get_rate(unsigned int clk)

Extra empty lines.

> +++ b/arch/arm/cpu/armv7/keystone/clock.c
[snip]
> +static void pll_delay(unsigned int loop_count)
> +{
> +	while (loop_count--)
> +		asm("   NOP");
> +}

If we cannot use udelay yet use sdelay.

> +#include "clock-k2hk.c"

Please use function prototypes, header files and then build the right
SoC clock file itself.

> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c

We just added a generic

> @@ -0,0 +1,139 @@
> +/*
> + * keystone2: commands for clocks
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <asm/arch/hardware.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/psc_defs.h>
> +
> +static u32 atoui(char *pstr)
> +{
> +	u32 res = 0;
> +
> +	for (; *pstr != 0; pstr++) {
> +		if (*pstr < '0' || *pstr > '9')
> +			break;
> +
> +		res = (res * 10) + (*pstr - '0');
> +	}
> +
> +	return res;
> +}
> +
> +struct pll_init_data cmd_pll_data = {
> +	.pll			= MAIN_PLL,
> +	.pll_m			= 16,
> +	.pll_d			= 1,
> +	.pll_od			= 2,
> +};
> +
> +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	if (argc != 5)
> +		goto pll_cmd_usage;
> +
> +	if (strncmp(argv[1], "pa", 2) == 0)
> +		cmd_pll_data.pll = PASS_PLL;
> +	else if (strncmp(argv[1], "arm", 3) == 0)
> +		cmd_pll_data.pll = TETRIS_PLL;
> +	else if (strncmp(argv[1], "ddr3a", 5) == 0)
> +		cmd_pll_data.pll = DDR3A_PLL;
> +	else if (strncmp(argv[1], "ddr3b", 5) == 0)
> +		cmd_pll_data.pll = DDR3B_PLL;
> +	else
> +		goto pll_cmd_usage;
> +
> +	cmd_pll_data.pll_m   = atoui(argv[2]);
> +	cmd_pll_data.pll_d   = atoui(argv[3]);
> +	cmd_pll_data.pll_od  = atoui(argv[4]);

Why not simple_strtoul(argv[n], NULL, 10) ?

> +
> +	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
> +	       cmd_pll_data.pll, cmd_pll_data.pll_m,
> +	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
> +	init_pll(&cmd_pll_data);
> +
> +	return 0;
> +
> +pll_cmd_usage:
> +	return cmd_usage(cmdtp);
> +}
> +
> +U_BOOT_CMD(
> +	pllset,	5,	0,	do_pll_cmd,
> +	"set pll multiplier and pre divider",
> +	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
> +);

Wolfgang, if we add another command that takes decimal not hexidecimal
inputs, you're going to hit me with a ruler, aren't you?  Even for a
clock command?

> +U_BOOT_CMD(
> +	getclk,	2,	0,	do_getclk_cmd,
> +	"get clock rate",
> +	"<clk index>\n"
> +	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
> +);

This would fit with the generic clk command and 'dump' which we just
added.

> +++ b/arch/arm/cpu/armv7/keystone/config.mk
> @@ -0,0 +1,14 @@
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
> +
> +# =========================================================================
> +#
> +# Supply options according to compiler version
> +#
> +# =========================================================================
> +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
> +		    $(call cc-option,-malignment-traps,))

You need to do this as:
PF_CPPFLAGS_SLB := ...
PLATFORM_RELFALGS += $(PF_CPPFLAGS_SLB)

The way you have it causes an evaluation per file and the above is a one
time evaluation.

> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
> new file mode 100644
> index 0000000..4875db7
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c

Part of me wonders just how close/far this is from the omap-common
EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
you don't have some corner-case bugs around not setting shadow registers
and initially setting some of the values to max, then setting them
optimally due to which bits cause a refresh cycle).

> +++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S

Is there a reason you don't use arch/arm/cpu/armv7/lowlevel_init.S and
the s_init calling sequence?

> +++ b/board/ti/k2hk_evm/board.c
[snip]
> +/* Byte swap the 32-bit data if the device is BE */
> +int cpu_to_bus(u32 *ptr, u32 length)
> +{
> +	u32 i;
> +
> +	if (device_big_endian)
> +		for (i = 0; i < length; i++, ptr++)
> +			*ptr = __swab32(*ptr);
> +
> +	return 0;
> +}

cpu_to_be32() ?

> +int board_init(void)
> +{
> +	gd->bd->bi_arch_number = -1;

Just don't set it?

> +void enable_caches(void)
> +{
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +	/* Enable D-cache. I-cache is already enabled in start.S */
> +	dcache_enable();
> +#endif
> +}

This belongs in one of the arch/arm/cpu/armv7/keystone/ files

> +++ b/drivers/i2c/keystone_i2c.c
> @@ -0,0 +1,372 @@
> +/*
> + * TI Keystone i2c driver
> + * Based on TI DaVinci (TMS320DM644x) I2C driver.

And how different is it really?  Can we not reuse the davinci driver?

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140210/a45b7e91/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  2014-02-10 21:25     ` Tom Rini
@ 2014-02-11  1:05       ` Vitaly Andrianov
  0 siblings, 0 replies; 716+ messages in thread
From: Vitaly Andrianov @ 2014-02-11  1:05 UTC (permalink / raw)
  To: u-boot

On 02/10/2014 04:25 PM, Tom Rini wrote:
> On Fri, Feb 07, 2014 at 06:23:08PM -0500, Murali Karicheri wrote:
>
>> From: Vitaly Andrianov <vitalya@ti.com>
>>
>> The keystone2 SOC requires to fix all 32 bit aliased addresses
>> to their 36 physical format. This has to happen after all fdt
>> nodes are added or modified.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Why can't this be done with the existing CONFIG_OF_BOARD_SETUP and 'fdt
> boardsetup' command?
>
Hi Tom,

The fdt_board_setup() is called at the beginning of the 
image_setup_libfdt().
After that fdt can be updated by fdt_resize(), fdt_initrd() etc. All 
those updates
have to be fixed. That is why we have to call the ft_board_setup_ex() at 
the end
of the image_setup_libfdt().

Thanks,
Vitaly Andrianov.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-10 21:25     ` Tom Rini
@ 2014-02-11  1:44       ` Vitaly Andrianov
  2014-02-12 12:53         ` Tom Rini
  2014-02-17 21:19       ` Andrianov, Vitaly
  1 sibling, 1 reply; 716+ messages in thread
From: Vitaly Andrianov @ 2014-02-11  1:44 UTC (permalink / raw)
  To: u-boot

On 02/10/2014 04:25 PM, Tom Rini wrote:
> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>
>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
>> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
>> refer the ti/k2hk_evm/README for details on the board, build and other
>> information.
>>
>> This patch add support for keystone architecture and k2hk evm.
> Globally, only use
> /*
>   * Multiline comments like this
>   */
I'll fix this.
>> +++ b/arch/arm/cpu/armv7/keystone/Makefile
>> @@ -0,0 +1,18 @@
>> +#
>> +# (C) Copyright 2012-2014
>> +#     Texas Instruments Incorporated, <www.ti.com>
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +obj-y	+= aemif.o
>> +obj-y   += init.o
>> +obj-y   += psc.o
>> +obj-y   += clock.o
>> +obj-y   += cmd_clock.o
>> +obj-y   += cmd_mon.o
>> +obj-y   += msmc.o
>> +obj-y   += lowlevel_init.o
>> +obj-$(CONFIG_SPL_BUILD) += spl.o
>> +obj-y	+= ddr3.o
> Mix of space and tab, just tab it all out to line up please.
Will fix.

>> +++ b/arch/arm/cpu/armv7/keystone/aemif.c
>> @@ -0,0 +1,79 @@
>> +/*
>> + * Keystone2: Asynchronous EMIF Configuration
>> + *
>> + * (C) Copyright 2012-2014
>> + *     Texas Instruments Incorporated, <www.ti.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/io.h>
>> +#include <asm/arch/clock.h>
>> +
>> +#ifdef CONFIG_SOC_K2HK
>> +#define ASYNC_EMIF_BASE			K2HK_ASYNC_EMIF_CNTRL_BASE
>> +#endif
> So, does Keystone 1 have this in a different location?
That is not for Keystone1. K2HK is for Hawking and Kepler SoC.
The ASYNC_EMIF_BASE may be different for other SOC of the Keystone2 family.
>> +#define ASYNC_EMIF_CONFIG(cs)		(ASYNC_EMIF_BASE+0x10+(cs)*4)
>> +#define ASYNC_EMIF_ONENAND_CONTROL	(ASYNC_EMIF_BASE+0x5c)
>> +#define ASYNC_EMIF_NAND_CONTROL		(ASYNC_EMIF_BASE+0x60)
>> +#define ASYNC_EMIF_WAITCYCLE_CONFIG	(ASYNC_EMIF_BASE+0x4)
> Register access is done over structs not define of base + offset, please
> rework.
This style was taken form Davinci code. Shall we rework it?
>> +#define CONFIG_SELECT_STROBE(v)		((v) ? 1 << 31 : 0)
>> +#define CONFIG_EXTEND_WAIT(v)		((v) ? 1 << 30 : 0)
>> +#define CONFIG_WR_SETUP(v)		(((v) & 0x0f) << 26)
>> +#define CONFIG_WR_STROBE(v)		(((v) & 0x3f) << 20)
>> +#define CONFIG_WR_HOLD(v)		(((v) & 0x07) << 17)
>> +#define CONFIG_RD_SETUP(v)		(((v) & 0x0f) << 13)
>> +#define CONFIG_RD_STROBE(v)		(((v) & 0x3f) << 7)
>> +#define CONFIG_RD_HOLD(v)		(((v) & 0x07) << 4)
>> +#define CONFIG_TURN_AROUND(v)		(((v) & 0x03) << 2)
>> +#define CONFIG_WIDTH(v)			(((v) & 0x03) << 0)
> To avoid confusion please do AEMIF_CONFIG_... or AEMIF_CFG_... or maybe
> just CFG_...
Agree and will change.

>> +++ b/arch/arm/cpu/armv7/keystone/clock-k2hk.c
> [snip]
>> +			prediv = (tmp & 0x3f) + 1;
>> +			mult = (((tmp & 0x7f000) >> 6) | (pllctl_reg_read(pll,
>> +							mult) & 0x3f)) + 1;
>> +			output_div = ((pllctl_reg_read(pll, secctl) >> 19) &
>> +				      0xf) + 1;
> Please define magic numbers, check globally.
OK
>
>> +	return ret;
>> +}
>> +
>> +
>> +
>> +
>> +unsigned long clk_get_rate(unsigned int clk)
> Extra empty lines.
Will remove.

>> +++ b/arch/arm/cpu/armv7/keystone/clock.c
> [snip]
>> +static void pll_delay(unsigned int loop_count)
>> +{
>> +	while (loop_count--)
>> +		asm("   NOP");
>> +}
> If we cannot use udelay yet use sdelay.
>
>> +#include "clock-k2hk.c"
> Please use function prototypes, header files and then build the right
> SoC clock file itself.
The idea was to have common clock.h for all Keystone2 family and include 
in to
it a specific for each SoC include file. Are you asking to remove that 
specific include
from the clock.h?

>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> We just added a generic
I'll check it out.

>> @@ -0,0 +1,139 @@
>> +/*
>> + * keystone2: commands for clocks
>> + *
>> + * (C) Copyright 2012-2014
>> + *     Texas Instruments Incorporated, <www.ti.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <command.h>
>> +#include <asm/arch/hardware.h>
>> +#include <asm/arch/clock.h>
>> +#include <asm/arch/psc_defs.h>
>> +
>> +static u32 atoui(char *pstr)
>> +{
>> +	u32 res = 0;
>> +
>> +	for (; *pstr != 0; pstr++) {
>> +		if (*pstr < '0' || *pstr > '9')
>> +			break;
>> +
>> +		res = (res * 10) + (*pstr - '0');
>> +	}
>> +
>> +	return res;
>> +}
>> +
>> +struct pll_init_data cmd_pll_data = {
>> +	.pll			= MAIN_PLL,
>> +	.pll_m			= 16,
>> +	.pll_d			= 1,
>> +	.pll_od			= 2,
>> +};
>> +
>> +int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +	if (argc != 5)
>> +		goto pll_cmd_usage;
>> +
>> +	if (strncmp(argv[1], "pa", 2) == 0)
>> +		cmd_pll_data.pll = PASS_PLL;
>> +	else if (strncmp(argv[1], "arm", 3) == 0)
>> +		cmd_pll_data.pll = TETRIS_PLL;
>> +	else if (strncmp(argv[1], "ddr3a", 5) == 0)
>> +		cmd_pll_data.pll = DDR3A_PLL;
>> +	else if (strncmp(argv[1], "ddr3b", 5) == 0)
>> +		cmd_pll_data.pll = DDR3B_PLL;
>> +	else
>> +		goto pll_cmd_usage;
>> +
>> +	cmd_pll_data.pll_m   = atoui(argv[2]);
>> +	cmd_pll_data.pll_d   = atoui(argv[3]);
>> +	cmd_pll_data.pll_od  = atoui(argv[4]);
> Why not simple_strtoul(argv[n], NULL, 10) ?
>
>> +
>> +	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
>> +	       cmd_pll_data.pll, cmd_pll_data.pll_m,
>> +	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
>> +	init_pll(&cmd_pll_data);
>> +
>> +	return 0;
>> +
>> +pll_cmd_usage:
>> +	return cmd_usage(cmdtp);
>> +}
>> +
>> +U_BOOT_CMD(
>> +	pllset,	5,	0,	do_pll_cmd,
>> +	"set pll multiplier and pre divider",
>> +	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
>> +);
> Wolfgang, if we add another command that takes decimal not hexidecimal
> inputs, you're going to hit me with a ruler, aren't you?  Even for a
> clock command?
>
>> +U_BOOT_CMD(
>> +	getclk,	2,	0,	do_getclk_cmd,
>> +	"get clock rate",
>> +	"<clk index>\n"
>> +	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
>> +);
> This would fit with the generic clk command and 'dump' which we just
> added.
>
>> +++ b/arch/arm/cpu/armv7/keystone/config.mk
>> @@ -0,0 +1,14 @@
>> +# (C) Copyright 2012-2014
>> +#     Texas Instruments Incorporated, <www.ti.com>
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
>> +
>> +# =========================================================================
>> +#
>> +# Supply options according to compiler version
>> +#
>> +# =========================================================================
>> +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
>> +		    $(call cc-option,-malignment-traps,))
> You need to do this as:
> PF_CPPFLAGS_SLB := ...
> PLATFORM_RELFALGS += $(PF_CPPFLAGS_SLB)
>
> The way you have it causes an evaluation per file and the above is a one
> time evaluation.
>
>> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
>> new file mode 100644
>> index 0000000..4875db7
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c
> Part of me wonders just how close/far this is from the omap-common
> EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
> you don't have some corner-case bugs around not setting shadow registers
> and initially setting some of the values to max, then setting them
> optimally due to which bits cause a refresh cycle).
This code is based on AVV test code and is very specific to SOC DDR3 
controller,
which as I know is different from OMAP.

>> +++ b/arch/arm/cpu/armv7/keystone/lowlevel_init.S
> Is there a reason you don't use arch/arm/cpu/armv7/lowlevel_init.S and
> the s_init calling sequence?
>
>> +++ b/board/ti/k2hk_evm/board.c
> [snip]
>> +/* Byte swap the 32-bit data if the device is BE */
>> +int cpu_to_bus(u32 *ptr, u32 length)
>> +{
>> +	u32 i;
>> +
>> +	if (device_big_endian)
>> +		for (i = 0; i < length; i++, ptr++)
>> +			*ptr = __swab32(*ptr);
>> +
>> +	return 0;
>> +}
> cpu_to_be32() ?
>
>> +int board_init(void)
>> +{
>> +	gd->bd->bi_arch_number = -1;
> Just don't set it?
>
>> +void enable_caches(void)
>> +{
>> +#ifndef CONFIG_SYS_DCACHE_OFF
>> +	/* Enable D-cache. I-cache is already enabled in start.S */
>> +	dcache_enable();
>> +#endif
>> +}
> This belongs in one of the arch/arm/cpu/armv7/keystone/ files
>
>> +++ b/drivers/i2c/keystone_i2c.c
>> @@ -0,0 +1,372 @@
>> +/*
>> + * TI Keystone i2c driver
>> + * Based on TI DaVinci (TMS320DM644x) I2C driver.
> And how different is it really?  Can we not reuse the davinci driver?
>
It is reworked a little bit and also supports multiple ports, while 
davinci driver
supports only one.

I'll check out other comment as well.

Thanks,
Vitaly

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-11  1:44       ` Vitaly Andrianov
@ 2014-02-12 12:53         ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-12 12:53 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/10/2014 08:44 PM, Vitaly Andrianov wrote:
> On 02/10/2014 04:25 PM, Tom Rini wrote:
>> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>>
>>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
>>> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
>>> refer the ti/k2hk_evm/README for details on the board, build and other
>>> information.
[snip]
>>> +#ifdef CONFIG_SOC_K2HK
>>> +#define ASYNC_EMIF_BASE            K2HK_ASYNC_EMIF_CNTRL_BASE
>>> +#endif
>> So, does Keystone 1 have this in a different location?
> That is not for Keystone1. K2HK is for Hawking and Kepler SoC.
> The ASYNC_EMIF_BASE may be different for other SOC of the Keystone2 family.

That seems pretty unlikely, unless you've seen actual plans to the
contrary, so lets assume the base won't change for this family at least.

>>> +#define ASYNC_EMIF_CONFIG(cs)        (ASYNC_EMIF_BASE+0x10+(cs)*4)
>>> +#define ASYNC_EMIF_ONENAND_CONTROL    (ASYNC_EMIF_BASE+0x5c)
>>> +#define ASYNC_EMIF_NAND_CONTROL        (ASYNC_EMIF_BASE+0x60)
>>> +#define ASYNC_EMIF_WAITCYCLE_CONFIG    (ASYNC_EMIF_BASE+0x4)
>> Register access is done over structs not define of base + offset, please
>> rework.
> This style was taken form Davinci code. Shall we rework it?

Yes.

[snip]
>>> +++ b/arch/arm/cpu/armv7/keystone/clock.c
>> [snip]
>>> +static void pll_delay(unsigned int loop_count)
>>> +{
>>> +    while (loop_count--)
>>> +        asm("   NOP");
>>> +}
>> If we cannot use udelay yet use sdelay.
>>
>>> +#include "clock-k2hk.c"
>> Please use function prototypes, header files and then build the right
>> SoC clock file itself.
> The idea was to have common clock.h for all Keystone2 family and include
> in to
> it a specific for each SoC include file. Are you asking to remove that
> specific include
> from the clock.h?

I'm saying we can't include a c file from another c file.  See
arch/arm/cpu/armv7/am33xx/ (and asm/arch-am33xx/) for how we support
different clocks in similar-but-different families.

[snip]
>>> diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c
>>> b/arch/arm/cpu/armv7/keystone/ddr3.c
>>> new file mode 100644
>>> index 0000000..4875db7
>>> --- /dev/null
>>> +++ b/arch/arm/cpu/armv7/keystone/ddr3.c
>> Part of me wonders just how close/far this is from the omap-common
>> EMIF/DDR code.  Some parts look pretty familiar (and makes me wonder if
>> you don't have some corner-case bugs around not setting shadow registers
>> and initially setting some of the values to max, then setting them
>> optimally due to which bits cause a refresh cycle).
> This code is based on AVV test code and is very specific to SOC DDR3
> controller,
> which as I know is different from OMAP.

I'm not going to push this too hard since I don't have all the low level
knowledge (nor contacts) about just how the block was re-used, but it's
not 100% different from the rest of the EMIF parts TI uses.  We should
revisit this later (and once I've got the right docs for keystone parts
around).

[snip]
>>> +++ b/drivers/i2c/keystone_i2c.c
>>> @@ -0,0 +1,372 @@
>>> +/*
>>> + * TI Keystone i2c driver
>>> + * Based on TI DaVinci (TMS320DM644x) I2C driver.
>> And how different is it really?  Can we not reuse the davinci driver?
>>
> It is reworked a little bit and also supports multiple ports, while
> davinci driver supports only one.

Right, so lets enhance the existing driver.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJS+27JAAoJENk4IS6UOR1W/FAP/iUgQQf7q1NiGMwF4HfJqeZe
PsrO3ElN3TPPrnFQ5PgqXk3t8RSAFy7EVIetLjs8ZSh+JZvH48/YH9RCVm0err/I
LQVeQbklHNiV5kNtxMWQlwGmG/ySG3S7DiZ9wS2GyTbrJV0v4Zl9P6qjdxyc5vAl
O6aWDHv7IvqG5GXY8tSsptb8oN6H71foniufSLref5qQWeDxJtXpS31f0g0R9h4e
r76o7eQ4iNpUoCu5eKz4XzOUEV9ve1zQP1Iv5d2JGxV0FXkSyZ32STAkkdf6zglP
vnrK+dzk7B67hc1EQb2V0y3oY3yEmY+Z3aXkf3ws+5BY7R7SfZ8WfLxg1i7NJBZs
CFwFPVV91A05Tq4yRMnniCs6mOCpG08IwyxEz5SmEoG52H/onNHd1HnYhBEiuwRI
ENKm7IxdYFuWBVSd+FLaU6IQQdL8WnzL9YVkBuYdA+hPEAbcPVEWGFTVGo9fJP9r
SoWXzI8ue+fUiJxvVJdcwJ8AJrq7Ci4FBFjMDtxe+8e9wgUp0ZVeFPOW6kEml7I2
O8HkgtMB0MdMDdESB9m/neFs0E3Va7EX3tlVPAcfqlQjjkFS0v9OmlGZG23bs9HP
emejngR267JKcmJjuimf12IhIRWc62QtJBPXx+8WmEUy53CjkFhUfD7EKEzHT/52
CKaOAhmNc1EZAZkZcaBv
=anbB
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-10 21:25     ` Tom Rini
  2014-02-11  1:44       ` Vitaly Andrianov
@ 2014-02-17 21:19       ` Andrianov, Vitaly
  2014-02-17 21:57         ` Tom Rini
  1 sibling, 1 reply; 716+ messages in thread
From: Andrianov, Vitaly @ 2014-02-17 21:19 UTC (permalink / raw)
  To: u-boot

> -----Original Message-----
> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
> Sent: Monday, February 10, 2014 4:26 PM
> To: Karicheri, Muralidharan
> Cc: u-boot at lists.denx.de; Sandeep at theia.denx.de; Kwok, WingMan; Nair,
> Sandeep; Andrianov, Vitaly
> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
> k2hk SOC and EVM
> 
> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
> 
> > k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
> > Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
> the
> > ti/k2hk_evm/README for details on the board, build and other
> > information.
> >
> > This patch add support for keystone architecture and k2hk evm.

[snip]
 
> 
> > +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> 
> We just added a generic
> 

Tom,
Where can I see this generic implementation?

Thanks,
Vitaly 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-17 21:19       ` Andrianov, Vitaly
@ 2014-02-17 21:57         ` Tom Rini
  2014-02-20 17:27           ` Andrianov, Vitaly
  0 siblings, 1 reply; 716+ messages in thread
From: Tom Rini @ 2014-02-17 21:57 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/17/2014 04:19 PM, Andrianov, Vitaly wrote:
>> -----Original Message-----
>> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
>> Sent: Monday, February 10, 2014 4:26 PM
>> To: Karicheri, Muralidharan
>> Cc: u-boot at lists.denx.de; Sandeep at theia.denx.de; Kwok, WingMan; Nair,
>> Sandeep; Andrianov, Vitaly
>> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
>> k2hk SOC and EVM
>>
>> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
>>
>>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
>>> Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
>> the
>>> ti/k2hk_evm/README for details on the board, build and other
>>> information.
>>>
>>> This patch add support for keystone architecture and k2hk evm.
> 
> [snip]
>  
>>
>>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
>>
>> We just added a generic
>>
> 
> Tom,
> Where can I see this generic implementation?

Start poking at common/cmd_clk.c

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTAoXUAAoJENk4IS6UOR1WbQIQALPc/cIk4WTGLjV4lZQ+j2XH
0LzIel0Crx4TT3XPSfepxfQM0GqDseO92ujrGM5uqG043UIji8F/KmcJR2ILLgji
/07XiGG6fM9HSf/rnCgLFil7kY9DSoru5JLfnSkZISnowkK7/JgwRwrbXsG17rXD
vgyuGbS/Fpi6kt4AfjF1FtmDs/l9e28nh5ds9MUjQKBiWEVeSZdBDid6mq2kyY7e
6asozG0qIbaNS+o2F7HSbaQs8Ar78CLkM36Bsu3cjpHO+JZLtqaOvvlm6U8kbj5a
DK77Of6zQ9ToGOVtFFxVvMFinf/BRgZ+M9cyntKWlZ12uClPGXgOW3EyDrrW2VE8
3cXRqOlfBfUoJevtg6SQu837EeLrVOYKP8bs6A6IQ3etNGc+OhsXZnNhkmfHjtuw
2n7sOqOdC4Hpw0rjWfY1UaWPEPHoq+HPSqJHN6VaVkopKzPX5bWqDBxT+MtMxp5q
o196auSdfyW+z3A4MIpSWpEhB5Q7afr6v/VPs9wqkehuj/QdcFm8N2nD3s6Pg5NS
reuqTEZZbbQ5RORgjFDBqhnpgUaHx3OGM+HsCr5Msz/QRjtiljFYI9DtLdkn0XZw
jTbvUkEob8hVGaoptdppwUj90Cw6sJ5r15TGTHohJLkxzQfBkXeTK0fUXYSfPCMJ
Iyf9nPf1+D1AMKzIM14q
=Bk7g
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM
  2014-02-17 21:57         ` Tom Rini
@ 2014-02-20 17:27           ` Andrianov, Vitaly
  0 siblings, 0 replies; 716+ messages in thread
From: Andrianov, Vitaly @ 2014-02-20 17:27 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Rini, Tom
> Sent: Monday, February 17, 2014 4:58 PM
> To: Andrianov, Vitaly
> Cc: Karicheri, Muralidharan; u-boot at lists.denx.de;
> Sandeep at theia.denx.de; Kwok, WingMan; Nair, Sandeep
> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for
> k2hk SOC and EVM
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On 02/17/2014 04:19 PM, Andrianov, Vitaly wrote:
> >> -----Original Message-----
> >> From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
> >> Sent: Monday, February 10, 2014 4:26 PM
> >> To: Karicheri, Muralidharan
> >> Cc: u-boot at lists.denx.de; Sandeep at theia.denx.de; Kwok, WingMan;
> Nair,
> >> Sandeep; Andrianov, Vitaly
> >> Subject: Re: [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support
> >> for k2hk SOC and EVM
> >>
> >> On Fri, Feb 07, 2014 at 06:23:13PM -0500, Murali Karicheri wrote:
> >>
> >>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC.
> >>> Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
> >> the
> >>> ti/k2hk_evm/README for details on the board, build and other
> >>> information.
> >>>
> >>> This patch add support for keystone architecture and k2hk evm.
> >
> > [snip]
> >
> >>
> >>> +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
> >>
> >> We just added a generic
> >>
> >
> > Tom,
> > Where can I see this generic implementation?
> 
> Start poking at common/cmd_clk.c
> 

The command in that file just dump all clocks. We need to have a command
to display one particular clock. So, for now we will continue to use
the keystone2 specific implementation and change it later when the
generic will support one clock only.

> - --
> Tom
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (GNU/Linux)
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
> 
> iQIcBAEBAgAGBQJTAoXUAAoJENk4IS6UOR1WbQIQALPc/cIk4WTGLjV4lZQ+j2XH
> 0LzIel0Crx4TT3XPSfepxfQM0GqDseO92ujrGM5uqG043UIji8F/KmcJR2ILLgji
> /07XiGG6fM9HSf/rnCgLFil7kY9DSoru5JLfnSkZISnowkK7/JgwRwrbXsG17rXD
> vgyuGbS/Fpi6kt4AfjF1FtmDs/l9e28nh5ds9MUjQKBiWEVeSZdBDid6mq2kyY7e
> 6asozG0qIbaNS+o2F7HSbaQs8Ar78CLkM36Bsu3cjpHO+JZLtqaOvvlm6U8kbj5a
> DK77Of6zQ9ToGOVtFFxVvMFinf/BRgZ+M9cyntKWlZ12uClPGXgOW3EyDrrW2VE8
> 3cXRqOlfBfUoJevtg6SQu837EeLrVOYKP8bs6A6IQ3etNGc+OhsXZnNhkmfHjtuw
> 2n7sOqOdC4Hpw0rjWfY1UaWPEPHoq+HPSqJHN6VaVkopKzPX5bWqDBxT+MtMxp5q
> o196auSdfyW+z3A4MIpSWpEhB5Q7afr6v/VPs9wqkehuj/QdcFm8N2nD3s6Pg5NS
> reuqTEZZbbQ5RORgjFDBqhnpgUaHx3OGM+HsCr5Msz/QRjtiljFYI9DtLdkn0XZw
> jTbvUkEob8hVGaoptdppwUj90Cw6sJ5r15TGTHohJLkxzQfBkXeTK0fUXYSfPCMJ
> Iyf9nPf1+D1AMKzIM14q
> =Bk7g
> -----END PGP SIGNATURE-----

Thanks,
Vitaly
 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
       [not found] <yes>
                   ` (77 preceding siblings ...)
  2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
@ 2014-02-20 17:55 ` Murali Karicheri
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
                     ` (13 more replies)
  2014-08-12  6:40   ` Sanjeev Sharma
                   ` (12 subsequent siblings)
  91 siblings, 14 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

This patch series add support for keystone2 SoC and K2HK EVM

Change history:
	v2
	 - Review comments incorporated. Following are major comments
	   addressed
		- split network driver to navigator driver + ethernet
		  driver
	 	- replaced register base + offset implemenation with struct
	   		based register access implementation
	 	- Added Readme for NAND no subpage write option
	 	- re-use code for davinci i2c driver on keystone2 with updates
		- clock-k2hk.c merged to clock.c
		- currently keeping board specific getclk() command. See the thread
		  for the rational.
	 - Added update to davinci spi driver to re-use on keystone

	v1
	 - added separate patch for sorting tools/Makefile entries
	 - reworked gpimage patch to allow more re-use across omapimage/gpimage
	 - dropped patch related to ubifs file size
	 - added keystone SoC and K2HK EVM support

	v0
	 - preparatory patch for keystone

Murali Karicheri (5):
  tools: sort the entries in Makefile
  tools: mkimage: add support for gpimage format
  NAND: DaVinci: allow forced disable of subpage writes
  i2c, davinci: move i2c_defs.h to the drivers/i2c directory
  k2hk-evm: add configuration for spi1 and spi2 support

Rex Chang (1):
  spi: davinci: add support for multiple bus and chip select

Vitaly Andrianov (6):
  fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  arm: add support for arch timer
  i2c, davinci: add support for multiple i2c buses
  k2hk: add support for k2hk SOC and EVM
  keystone2: add keystone multicore navigator driver
  keystone2: net: add keystone ethernet driver

 Makefile                                           |   19 +
 README                                             |    5 +
 arch/arm/cpu/armv7/keystone/Makefile               |   18 +
 arch/arm/cpu/armv7/keystone/aemif.c                |   71 ++
 arch/arm/cpu/armv7/keystone/clock.c                |  313 +++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 +++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 +++
 arch/arm/cpu/armv7/keystone/config.mk              |   15 +
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++
 arch/arm/cpu/armv7/keystone/init.c                 |   56 ++
 arch/arm/cpu/armv7/keystone/keystone_nav.c         |  376 +++++++++
 arch/arm/cpu/armv7/keystone/msmc.c                 |   68 ++
 arch/arm/cpu/armv7/keystone/psc.c                  |  238 ++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +
 arch/arm/include/asm/arch-davinci/i2c_defs.h       |   71 +-
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 +
 arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 +++
 arch/arm/include/asm/arch-keystone/emac_defs.h     |  250 ++++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 ++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  145 ++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  175 ++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 +
 arch/arm/include/asm/arch-keystone/keystone_nav.h  |  193 +++++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 +
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 arch/arm/lib/Makefile                              |    1 +
 arch/arm/lib/arch_timer.c                          |   58 ++
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |   56 ++
 board/ti/k2hk_evm/board.c                          |  301 +++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 ++++++
 boards.cfg                                         |    1 +
 common/image-fdt.c                                 |    5 +
 common/image.c                                     |    1 +
 drivers/i2c/davinci_i2c.c                          |  345 ++++----
 drivers/i2c/davinci_i2c.h                          |   78 ++
 drivers/mtd/nand/davinci_nand.c                    |    3 +
 drivers/net/Makefile                               |    1 +
 drivers/net/keystone_net.c                         |  859 ++++++++++++++++++++
 drivers/serial/ns16550.c                           |    8 +
 drivers/spi/davinci_spi.c                          |   62 +-
 drivers/spi/davinci_spi.h                          |   33 +
 include/configs/k2hk_evm.h                         |  268 ++++++
 include/fdt_support.h                              |    1 +
 include/image.h                                    |    1 +
 tools/Makefile                                     |   20 +-
 tools/gpheader.h                                   |   40 +
 tools/gpimage-common.c                             |   80 ++
 tools/gpimage.c                                    |   77 ++
 tools/imagetool.c                                  |    2 +
 tools/imagetool.h                                  |    1 +
 tools/omapimage.c                                  |  104 +--
 tools/omapimage.h                                  |    5 -
 55 files changed, 5222 insertions(+), 313 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 arch/arm/lib/arch_timer.c
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 drivers/i2c/davinci_i2c.h
 create mode 100644 drivers/net/keystone_net.c
 create mode 100644 include/configs/k2hk_evm.h
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:10     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile Murali Karicheri
                     ` (12 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

The keystone2 SOC requires to fix all 32 bit aliased addresses
to their 36 physical format. This has to happen after all fdt
nodes are added or modified.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 - no update since v1
 common/image-fdt.c    |    5 +++++
 include/fdt_support.h |    1 +
 2 files changed, 6 insertions(+)

diff --git a/common/image-fdt.c b/common/image-fdt.c
index 6f9ce7d..ee4dd6f 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
 	if (!ft_verify_fdt(blob))
 		return -1;
 
+#ifdef CONFIG_SOC_K2HK
+	if (IMAAGE_OF_BOARD_SETUP)
+		ft_board_setup_ex(blob, gd->bd);
+#endif
+
 	return 0;
 }
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 9871e2f..4c1416d 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose);
 #endif
 
 void ft_board_setup(void *blob, bd_t *bd);
+void ft_board_setup_ex(void *blob, bd_t *bd);
 void ft_cpu_setup(void *blob, bd_t *bd);
 void ft_pci_setup(void *blob, bd_t *bd);
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:10     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format Murali Karicheri
                     ` (11 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

The NOPED_OBJ_FILES, dumpimage and mkimage object file
entries are to be kept sorted. This patch fix this issue.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - No update since v1
 tools/Makefile |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/tools/Makefile b/tools/Makefile
index 328cea3..3c719b3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,10 +77,10 @@ NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
 NOPED_OBJ_FILES-y += dumpimage.o
 NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += image-host.o
 NOPED_OBJ_FILES-y += imximage.o
 NOPED_OBJ_FILES-y += kwbimage.o
-NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
 NOPED_OBJ_FILES-y += mxsimage.o
@@ -88,8 +88,8 @@ NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += os_support.o
 NOPED_OBJ_FILES-y += pblimage.o
 NOPED_OBJ_FILES-y += proftool.o
-NOPED_OBJ_FILES-y += ublimage.o
 NOPED_OBJ_FILES-y += relocate-rela.o
+NOPED_OBJ_FILES-y += ublimage.o
 OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
 OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
 OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
@@ -209,14 +209,14 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(FIT_SIG_OBJS) \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
+			$(obj)dumpimage.o \
 			$(obj)fit_image.o \
-			$(obj)image-fit.o \
 			$(obj)image.o \
-			$(obj)image-host.o \
 			$(obj)imagetool.o \
+			$(obj)image-fit.o \
+			$(obj)image-host.o \
 			$(obj)imximage.o \
 			$(obj)kwbimage.o \
-			$(obj)dumpimage.o \
 			$(obj)md5.o \
 			$(obj)mxsimage.o \
 			$(obj)omapimage.o \
@@ -239,10 +239,10 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
 			$(obj)fit_image.o \
-			$(obj)image-fit.o \
-			$(obj)image-host.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
+			$(obj)image-host.o \
+			$(obj)image-fit.o \
 			$(obj)imximage.o \
 			$(obj)kwbimage.o \
 			$(obj)md5.o \
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer Murali Karicheri
                     ` (10 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

This patch add support for gpimage format as a preparatory
patch for porting u-boot for keystone2 devices and is
based on omapimage format. It re-uses gph header to store the
size and loadaddr as done in omapimage.c

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - No update since v1
 common/image.c         |    1 +
 include/image.h        |    1 +
 tools/Makefile         |    6 +++
 tools/gpheader.h       |   40 +++++++++++++++++++
 tools/gpimage-common.c |   80 +++++++++++++++++++++++++++++++++++++
 tools/gpimage.c        |   77 +++++++++++++++++++++++++++++++++++
 tools/imagetool.c      |    2 +
 tools/imagetool.h      |    1 +
 tools/omapimage.c      |  104 ++++++++----------------------------------------
 tools/omapimage.h      |    5 ---
 10 files changed, 224 insertions(+), 93 deletions(-)
 create mode 100644 tools/gpheader.h
 create mode 100644 tools/gpimage-common.c
 create mode 100644 tools/gpimage.c

diff --git a/common/image.c b/common/image.c
index ae95c3f..cb5c656 100644
--- a/common/image.c
+++ b/common/image.c
@@ -124,6 +124,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
 	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
 	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
+	{	IH_TYPE_GPIMAGE,    "gpimage",    "TI Keystone SPL Image",},
 	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
 	{	IH_TYPE_KERNEL_NOLOAD, "kernel_noload",  "Kernel Image (no loading done)", },
 	{	IH_TYPE_KWBIMAGE,   "kwbimage",   "Kirkwood Boot Image",},
diff --git a/include/image.h b/include/image.h
index 7de2bb2..0a3d346 100644
--- a/include/image.h
+++ b/include/image.h
@@ -214,6 +214,7 @@ struct lmb;
 #define IH_TYPE_KERNEL_NOLOAD	14	/* OS Kernel Image, can run from any load address */
 #define IH_TYPE_PBLIMAGE	15	/* Freescale PBL Boot Image	*/
 #define IH_TYPE_MXSIMAGE	16	/* Freescale MXSBoot Image	*/
+#define IH_TYPE_GPIMAGE		17	/* TI Keystone GPHeader Image	*/
 
 /*
  * Compression Types
diff --git a/tools/Makefile b/tools/Makefile
index 3c719b3..421aba5 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -77,6 +77,8 @@ NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
 NOPED_OBJ_FILES-y += dumpimage.o
 NOPED_OBJ_FILES-y += fit_image.o
+NOPED_OBJ_FILES-y += gpimage.o
+NOPED_OBJ_FILES-y += gpimage-common.o
 NOPED_OBJ_FILES-y += imagetool.o
 NOPED_OBJ_FILES-y += image-host.o
 NOPED_OBJ_FILES-y += imximage.o
@@ -211,6 +213,8 @@ $(obj)dumpimage$(SFX):	$(obj)aisimage.o \
 			$(obj)default_image.o \
 			$(obj)dumpimage.o \
 			$(obj)fit_image.o \
+			$(obj)gpimage.o \
+			$(obj)gpimage-common.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
 			$(obj)image-fit.o \
@@ -239,6 +243,8 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)crc32.o \
 			$(obj)default_image.o \
 			$(obj)fit_image.o \
+			$(obj)gpimage.o \
+			$(obj)gpimage-common.o \
 			$(obj)image.o \
 			$(obj)imagetool.o \
 			$(obj)image-host.o \
diff --git a/tools/gpheader.h b/tools/gpheader.h
new file mode 100644
index 0000000..63a28a2
--- /dev/null
+++ b/tools/gpheader.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c. Include this common
+ * header file
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GPIMAGE_H_
+#define _GPIMAGE_H_
+
+/* common headers for gpimage and omapimage formats */
+struct gp_header {
+	uint32_t size;
+	uint32_t load_addr;
+};
+#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header))
+
+/* common functions across gpimage and omapimage handlers */
+int valid_gph_size(uint32_t size);
+int valid_gph_load_addr(uint32_t load_addr);
+int gph_verify_header(struct gp_header *gph, int be);
+void gph_print_header(const struct gp_header *gph, int be);
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+			int be);
+int gpimage_check_params(struct image_tool_params *params);
+#endif
diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c
new file mode 100644
index 0000000..b343a3a
--- /dev/null
+++ b/tools/gpimage-common.c
@@ -0,0 +1,80 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Refactored common functions in to gpimage-common.c.
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+/* Helper to convert size and load_addr to big endian */
+void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
+{
+	*gph_size = cpu_to_be32(*gph_size);
+	*gph_load_addr = cpu_to_be32(*gph_load_addr);
+}
+
+int gph_verify_header(struct gp_header *gph, int be)
+{
+	uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+	if (be)
+		to_be32(&gph_size, &gph_load_addr);
+
+	if (!gph_size || !gph_load_addr)
+		return -1;
+
+	return 0;
+}
+
+void gph_print_header(const struct gp_header *gph, int be)
+{
+	uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+
+	if (be)
+		to_be32(&gph_size, &gph_load_addr);
+
+	if (!gph_size) {
+		fprintf(stderr, "Error: invalid image size %x\n", gph_size);
+		exit(EXIT_FAILURE);
+	}
+
+	if (!gph_load_addr) {
+		fprintf(stderr, "Error: invalid image load address %x\n",
+			gph_load_addr);
+		exit(EXIT_FAILURE);
+	}
+	printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+}
+
+void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr,
+	int be)
+{
+	gph->size = size;
+	gph->load_addr = load_addr;
+	if (be)
+		to_be32(&gph->size, &gph->load_addr);
+}
+
+int gpimage_check_params(struct image_tool_params *params)
+{
+	return	(params->dflag && (params->fflag || params->lflag)) ||
+		(params->fflag && (params->dflag || params->lflag)) ||
+		(params->lflag && (params->dflag || params->fflag));
+}
diff --git a/tools/gpimage.c b/tools/gpimage.c
new file mode 100644
index 0000000..1cabb5b
--- /dev/null
+++ b/tools/gpimage.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2014
+ * Texas Instruments Incorporated
+ * Add gpimage format for keystone devices to format spl image. This is
+ * Based on omapimage.c
+ *
+ * (C) Copyright 2010
+ * Linaro LTD, www.linaro.org
+ * Author: John Rigby <john.rigby@linaro.org>
+ * Based on TI's signGP.c
+ *
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic at denx.de.
+ *
+ * (C) Copyright 2008
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include <compiler.h>
+#include <image.h>
+#include "gpheader.h"
+
+static uint8_t gpimage_header[GPIMAGE_HDR_SIZE];
+
+/* to be in keystone gpimage */
+static int gpimage_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_GPIMAGE)
+		return EXIT_SUCCESS;
+	return EXIT_FAILURE;
+}
+
+static int gpimage_verify_header(unsigned char *ptr, int image_size,
+			struct image_tool_params *params)
+{
+	struct gp_header *gph = (struct gp_header *)ptr;
+
+	return gph_verify_header(gph, 1);
+}
+
+static void gpimage_print_header(const void *ptr)
+{
+	const struct gp_header *gph = (struct gp_header *)ptr;
+
+	gph_print_header(gph, 1);
+}
+
+static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct image_tool_params *params)
+{
+	struct gp_header *gph = (struct gp_header *)ptr;
+
+	gph_set_header(gph, sbuf->st_size - GPIMAGE_HDR_SIZE, params->addr, 1);
+}
+
+/*
+ * gpimage parameters
+ */
+static struct image_type_params gpimage_params = {
+	.name		= "TI KeyStone GP Image support",
+	.header_size	= GPIMAGE_HDR_SIZE,
+	.hdr		= (void *)&gpimage_header,
+	.check_image_type = gpimage_check_image_types,
+	.verify_header	= gpimage_verify_header,
+	.print_header	= gpimage_print_header,
+	.set_header	= gpimage_set_header,
+	.check_params	= gpimage_check_params,
+};
+
+void init_gpimage_type(void)
+{
+	register_image_type(&gpimage_params);
+}
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 29d2189..da72115 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register)
 	init_ubl_image_type();
 	/* Init Davinci AIS support */
 	init_ais_image_type();
+	/* Init TI Keystone boot image generation/list support */
+	init_gpimage_type();
 }
 
 /*
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c2c9aea..a3e9d30 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -167,6 +167,7 @@ void init_mxs_image_type(void);
 void init_fit_image_type(void);
 void init_ubl_image_type(void);
 void init_omap_image_type(void);
+void init_gpimage_type(void);
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
 
diff --git a/tools/omapimage.c b/tools/omapimage.c
index d59bc4d..1e0c164 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -15,57 +15,24 @@
  */
 
 #include "imagetool.h"
+#include <compiler.h>
 #include <image.h>
+#include "gpheader.h"
 #include "omapimage.h"
 
 /* Header size is CH header rounded up to 512 bytes plus GP header */
 #define OMAP_CH_HDR_SIZE 512
-#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
-#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
+#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)
 
 static int do_swap32 = 0;
 
-static uint32_t omapimage_swap32(uint32_t data)
-{
-	uint32_t result = 0;
-	result  = (data & 0xFF000000) >> 24;
-	result |= (data & 0x00FF0000) >> 8;
-	result |= (data & 0x0000FF00) << 8;
-	result |= (data & 0x000000FF) << 24;
-	return result;
-}
-
 static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
 
 static int omapimage_check_image_types(uint8_t type)
 {
 	if (type == IH_TYPE_OMAPIMAGE)
 		return EXIT_SUCCESS;
-	else {
-		return EXIT_FAILURE;
-	}
-}
-
-/*
- * Only the simplest image type is currently supported:
- * TOC pointing to CHSETTINGS
- * TOC terminator
- * CHSETTINGS
- *
- * padding to OMAP_CH_HDR_SIZE bytes
- *
- * gp header
- *   size
- *   load_addr
- */
-static int valid_gph_size(uint32_t size)
-{
-	return size;
-}
-
-static int valid_gph_load_addr(uint32_t load_addr)
-{
-	return load_addr;
+	return EXIT_FAILURE;
 }
 
 static int omapimage_verify_header(unsigned char *ptr, int image_size,
@@ -73,13 +40,13 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
 {
 	struct ch_toc *toc = (struct ch_toc *)ptr;
 	struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
-	uint32_t offset, size, gph_size, gph_load_addr;
+	uint32_t offset, size;
 
 	while (toc->section_offset != 0xffffffff
 			&& toc->section_size != 0xffffffff) {
 		if (do_swap32) {
-			offset = omapimage_swap32(toc->section_offset);
-			size = omapimage_swap32(toc->section_size);
+			offset = cpu_to_be32(toc->section_offset);
+			size = cpu_to_be32(toc->section_size);
 		} else {
 			offset = toc->section_offset;
 			size = toc->section_size;
@@ -92,20 +59,7 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size,
 		toc++;
 	}
 
-	if (do_swap32) {
-		gph_size = omapimage_swap32(gph->size);
-		gph_load_addr = omapimage_swap32(gph->load_addr);
-	} else {
-		gph_size = gph->size;
-		gph_load_addr = gph->load_addr;
-	}
-
-	if (!valid_gph_size(gph_size))
-		return -1;
-	if (!valid_gph_load_addr(gph_load_addr))
-		return -1;
-
-	return 0;
+	return gph_verify_header(gph, do_swap32);
 }
 
 static void omapimage_print_section(struct ch_settings *chs)
@@ -135,13 +89,13 @@ static void omapimage_print_header(const void *ptr)
 	const struct ch_toc *toc = (struct ch_toc *)ptr;
 	const struct gp_header *gph =
 			(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
-	uint32_t offset, size, gph_size, gph_load_addr;
+	uint32_t offset, size;
 
 	while (toc->section_offset != 0xffffffff
 			&& toc->section_size != 0xffffffff) {
 		if (do_swap32) {
-			offset = omapimage_swap32(toc->section_offset);
-			size = omapimage_swap32(toc->section_size);
+			offset = cpu_to_be32(toc->section_offset);
+			size = cpu_to_be32(toc->section_size);
 		} else {
 			offset = toc->section_offset;
 			size = toc->section_size;
@@ -160,26 +114,7 @@ static void omapimage_print_header(const void *ptr)
 		toc++;
 	}
 
-	if (do_swap32) {
-		gph_size = omapimage_swap32(gph->size);
-		gph_load_addr = omapimage_swap32(gph->load_addr);
-	} else {
-		gph_size = gph->size;
-		gph_load_addr = gph->load_addr;
-	}
-
-	if (!valid_gph_size(gph_size)) {
-		fprintf(stderr, "Error: invalid image size %x\n", gph_size);
-		exit(EXIT_FAILURE);
-	}
-
-	if (!valid_gph_load_addr(gph_load_addr)) {
-		fprintf(stderr, "Error: invalid image load address %x\n",
-				gph_load_addr);
-		exit(EXIT_FAILURE);
-	}
-
-	printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
+	gph_print_header(gph, do_swap32);
 }
 
 static int toc_offset(void *hdr, void *member)
@@ -208,8 +143,8 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	toc++;
 	memset(toc, 0xff, sizeof(*toc));
 
-	gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
-	gph->load_addr = params->addr;
+	gph_set_header(gph, sbuf->st_size - OMAP_FILE_HDR_SIZE,
+		       params->addr, 0);
 
 	if (strncmp(params->imagename, "byteswap", 8) == 0) {
 		do_swap32 = 1;
@@ -217,20 +152,13 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 		uint32_t *data = (uint32_t *)ptr;
 
 		while (swapped <= (sbuf->st_size / sizeof(uint32_t))) {
-			*data = omapimage_swap32(*data);
+			*data = cpu_to_be32(*data);
 			swapped++;
 			data++;
 		}
 	}
 }
 
-int omapimage_check_params(struct image_tool_params *params)
-{
-	return	(params->dflag && (params->fflag || params->lflag)) ||
-		(params->fflag && (params->dflag || params->lflag)) ||
-		(params->lflag && (params->dflag || params->fflag));
-}
-
 /*
  * omapimage parameters
  */
@@ -242,7 +170,7 @@ static struct image_type_params omapimage_params = {
 	.verify_header	= omapimage_verify_header,
 	.print_header	= omapimage_print_header,
 	.set_header	= omapimage_set_header,
-	.check_params	= omapimage_check_params,
+	.check_params	= gpimage_check_params,
 };
 
 void init_omap_image_type(void)
diff --git a/tools/omapimage.h b/tools/omapimage.h
index 45d14ea..8744ae7 100644
--- a/tools/omapimage.h
+++ b/tools/omapimage.h
@@ -25,10 +25,5 @@ struct ch_settings {
 	uint32_t flags;
 };
 
-struct gp_header {
-	uint32_t size;
-	uint32_t load_addr;
-};
-
 #define KEY_CHSETTINGS 0xC0C0C0C1
 #endif /* _OMAPIMAGE_H_ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (2 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
                     ` (9 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

This patch add basic support for the architecture timer found on recent
ARMv7 based SoCs.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - No update since v1
 arch/arm/lib/Makefile     |    1 +
 arch/arm/lib/arch_timer.c |   58 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 arch/arm/lib/arch_timer.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 321997c..726f229 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
 else
 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
 endif
+obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
 
 ifdef CONFIG_ARM64
 obj-y	+= interrupts_64.o
diff --git a/arch/arm/lib/arch_timer.c b/arch/arm/lib/arch_timer.c
new file mode 100644
index 0000000..0588e2b
--- /dev/null
+++ b/arch/arm/lib/arch_timer.c
@@ -0,0 +1,58 @@
+/*
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int timer_init(void)
+{
+	gd->arch.tbl = 0;
+	gd->arch.tbu = 0;
+
+	gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ;
+
+	return 0;
+}
+
+unsigned long long get_ticks(void)
+{
+	ulong nowl, nowu;
+
+	asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu));
+
+	gd->arch.tbl = nowl;
+	gd->arch.tbu = nowu;
+
+	return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+
+ulong get_timer(ulong base)
+{
+	return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+	unsigned long long endtime;
+
+	endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz,
+			1000UL);
+
+	endtime += get_ticks();
+
+	while (get_ticks() < endtime)
+		;
+}
+
+ulong get_tbclk(void)
+{
+	return gd->arch.timer_rate_hz;
+}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (3 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-26  4:01     ` Scott Wood
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
                     ` (8 subsequent siblings)
  13 siblings, 2 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

This patch introduces a configurable mechanism to disable
subpage writes in the DaVinci NAND driver.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 - Added README
 README                          |    5 +++++
 drivers/mtd/nand/davinci_nand.c |    3 +++
 2 files changed, 8 insertions(+)

diff --git a/README b/README
index aea82be..caf60a2 100644
--- a/README
+++ b/README
@@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
 - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
 		Enables the RTC32K OSC on AM33xx based plattforms
 
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+		Option to disable subpage write in NAND driver
+		Example driver that use this:
+		drivers/mtd/nand/davinci_nand.c
+
 Freescale QE/FMAN Firmware Support:
 -----------------------------------
 
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 5b17d7b..75b03a7 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand)
 #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
 	nand->bbt_options	  |= NAND_BBT_USE_FLASH;
 #endif
+#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+	nand->options	  |= NAND_NO_SUBPAGE_WRITE;
+#endif
 #ifdef CONFIG_SYS_NAND_HW_ECC
 	nand->ecc.mode = NAND_ECC_HW;
 	nand->ecc.size = 512;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (4 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses Murali Karicheri
                     ` (7 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

This patch moves the davinci i2c_defs.h file to drivers.i2c directory.
It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.

Not used "git mv" command to move the file because small part of
it with definitions specific for Davinci SOCs has to remain in the
arch/arm/include/asm/arch-davinci.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 - updated based on review comments
 arch/arm/include/asm/arch-davinci/i2c_defs.h |   71 ++----------------------
 drivers/i2c/davinci_i2c.c                    |    1 +
 drivers/i2c/davinci_i2c.h                    |   75 ++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 68 deletions(-)
 create mode 100644 drivers/i2c/davinci_i2c.h

diff --git a/arch/arm/include/asm/arch-davinci/i2c_defs.h b/arch/arm/include/asm/arch-davinci/i2c_defs.h
index c388dc0..06da894 100644
--- a/arch/arm/include/asm/arch-davinci/i2c_defs.h
+++ b/arch/arm/include/asm/arch-davinci/i2c_defs.h
@@ -1,16 +1,13 @@
 /*
- * (C) Copyright 2004
+ * (C) Copyright 2004-2014
  * Texas Instruments, <www.ti.com>
  *
  * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
-#ifndef _DAVINCI_I2C_H_
-#define _DAVINCI_I2C_H_
-
-#define I2C_WRITE		0
-#define I2C_READ		1
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_
 
 #ifndef CONFIG_SOC_DA8XX
 #define I2C_BASE		0x01c21000
@@ -18,66 +15,4 @@
 #define I2C_BASE		0x01c22000
 #endif
 
-#define	I2C_OA			(I2C_BASE + 0x00)
-#define I2C_IE			(I2C_BASE + 0x04)
-#define I2C_STAT		(I2C_BASE + 0x08)
-#define I2C_SCLL		(I2C_BASE + 0x0c)
-#define I2C_SCLH		(I2C_BASE + 0x10)
-#define I2C_CNT			(I2C_BASE + 0x14)
-#define I2C_DRR			(I2C_BASE + 0x18)
-#define I2C_SA			(I2C_BASE + 0x1c)
-#define I2C_DXR			(I2C_BASE + 0x20)
-#define I2C_CON			(I2C_BASE + 0x24)
-#define I2C_IV			(I2C_BASE + 0x28)
-#define I2C_PSC			(I2C_BASE + 0x30)
-
-/* I2C masks */
-
-/* I2C Interrupt Enable Register (I2C_IE): */
-#define I2C_IE_SCD_IE	(1 << 5)	/* Stop condition detect interrupt enable */
-#define I2C_IE_XRDY_IE	(1 << 4)	/* Transmit data ready interrupt enable */
-#define I2C_IE_RRDY_IE	(1 << 3)	/* Receive data ready interrupt enable */
-#define I2C_IE_ARDY_IE	(1 << 2)	/* Register access ready interrupt enable */
-#define I2C_IE_NACK_IE	(1 << 1)	/* No acknowledgment interrupt enable */
-#define I2C_IE_AL_IE	(1 << 0)	/* Arbitration lost interrupt enable */
-
-/* I2C Status Register (I2C_STAT): */
-
-#define I2C_STAT_BB	(1 << 12)	/* Bus busy */
-#define I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
-#define I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
-#define I2C_STAT_AAS	(1 << 9)	/* Address as slave */
-#define I2C_STAT_SCD	(1 << 5)	/* Stop condition detect */
-#define I2C_STAT_XRDY	(1 << 4)	/* Transmit data ready */
-#define I2C_STAT_RRDY	(1 << 3)	/* Receive data ready */
-#define I2C_STAT_ARDY	(1 << 2)	/* Register access ready */
-#define I2C_STAT_NACK	(1 << 1)	/* No acknowledgment interrupt enable */
-#define I2C_STAT_AL	(1 << 0)	/* Arbitration lost interrupt enable */
-
-
-/* I2C Interrupt Code Register (I2C_INTCODE): */
-
-#define I2C_INTCODE_MASK	7
-#define I2C_INTCODE_NONE	0
-#define I2C_INTCODE_AL		1	/* Arbitration lost */
-#define I2C_INTCODE_NAK		2	/* No acknowledgement/general call */
-#define I2C_INTCODE_ARDY	3	/* Register access ready */
-#define I2C_INTCODE_RRDY	4	/* Rcv data ready */
-#define I2C_INTCODE_XRDY	5	/* Xmit data ready */
-#define I2C_INTCODE_SCD		6	/* Stop condition detect */
-
-
-/* I2C Configuration Register (I2C_CON): */
-
-#define I2C_CON_EN	(1 << 5)	/* I2C module enable */
-#define I2C_CON_STB	(1 << 4)	/* Start byte mode (master mode only) */
-#define I2C_CON_MST	(1 << 10)	/* Master/slave mode */
-#define I2C_CON_TRX	(1 << 9)	/* Transmitter/receiver mode (master mode only) */
-#define I2C_CON_XA	(1 << 8)	/* Expand address */
-#define I2C_CON_STP	(1 << 11)	/* Stop condition (master mode only) */
-#define I2C_CON_STT	(1 << 13)	/* Start condition (master mode only) */
-#define I2C_CON_FREE	(1 << 14)	/* Free run on emulation */
-
-#define I2C_TIMEOUT	0xffff0000	/* Timeout mask for poll_i2c_irq() */
-
 #endif
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index e56fe75..6e5260c 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -12,6 +12,7 @@
 #include <i2c.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/i2c_defs.h>
+#include "davinci_i2c.h"
 
 #define CHECK_NACK() \
 	do {\
diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h
new file mode 100644
index 0000000..79ff7a3
--- /dev/null
+++ b/drivers/i2c/davinci_i2c.h
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2004-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * Some changes copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef _DAVINCI_I2C_H_
+#define _DAVINCI_I2C_H_
+
+#define I2C_WRITE		0
+#define I2C_READ		1
+
+#define	I2C_OA			(I2C_BASE + 0x00)
+#define I2C_IE			(I2C_BASE + 0x04)
+#define I2C_STAT		(I2C_BASE + 0x08)
+#define I2C_SCLL		(I2C_BASE + 0x0c)
+#define I2C_SCLH		(I2C_BASE + 0x10)
+#define I2C_CNT			(I2C_BASE + 0x14)
+#define I2C_DRR			(I2C_BASE + 0x18)
+#define I2C_SA			(I2C_BASE + 0x1c)
+#define I2C_DXR			(I2C_BASE + 0x20)
+#define I2C_CON			(I2C_BASE + 0x24)
+#define I2C_IV			(I2C_BASE + 0x28)
+#define I2C_PSC			(I2C_BASE + 0x30)
+
+/* I2C masks */
+
+/* I2C Interrupt Enable Register (I2C_IE): */
+#define I2C_IE_SCD_IE	(1 << 5)  /* Stop condition detect interrupt enable */
+#define I2C_IE_XRDY_IE	(1 << 4)  /* Transmit data ready interrupt enable */
+#define I2C_IE_RRDY_IE	(1 << 3)  /* Receive data ready interrupt enable */
+#define I2C_IE_ARDY_IE	(1 << 2)  /* Register access ready interrupt enable */
+#define I2C_IE_NACK_IE	(1 << 1)  /* No acknowledgment interrupt enable */
+#define I2C_IE_AL_IE	(1 << 0)  /* Arbitration lost interrupt enable */
+
+/* I2C Status Register (I2C_STAT): */
+
+#define I2C_STAT_BB	(1 << 12) /* Bus busy */
+#define I2C_STAT_ROVR	(1 << 11) /* Receive overrun */
+#define I2C_STAT_XUDF	(1 << 10) /* Transmit underflow */
+#define I2C_STAT_AAS	(1 << 9)  /* Address as slave */
+#define I2C_STAT_SCD	(1 << 5)  /* Stop condition detect */
+#define I2C_STAT_XRDY	(1 << 4)  /* Transmit data ready */
+#define I2C_STAT_RRDY	(1 << 3)  /* Receive data ready */
+#define I2C_STAT_ARDY	(1 << 2)  /* Register access ready */
+#define I2C_STAT_NACK	(1 << 1)  /* No acknowledgment interrupt enable */
+#define I2C_STAT_AL	(1 << 0)  /* Arbitration lost interrupt enable */
+
+/* I2C Interrupt Code Register (I2C_INTCODE): */
+
+#define I2C_INTCODE_MASK	7
+#define I2C_INTCODE_NONE	0
+#define I2C_INTCODE_AL		1 /* Arbitration lost */
+#define I2C_INTCODE_NAK		2 /* No acknowledgement/general call */
+#define I2C_INTCODE_ARDY	3 /* Register access ready */
+#define I2C_INTCODE_RRDY	4 /* Rcv data ready */
+#define I2C_INTCODE_XRDY	5 /* Xmit data ready */
+#define I2C_INTCODE_SCD		6 /* Stop condition detect */
+
+/* I2C Configuration Register (I2C_CON): */
+
+#define I2C_CON_EN	(1 << 5)   /* I2C module enable */
+#define I2C_CON_STB	(1 << 4)   /* Start byte mode (master mode only) */
+#define I2C_CON_MST	(1 << 10)  /* Master/slave mode */
+#define I2C_CON_TRX	(1 << 9)   /* Tx/Rx mode (master mode only) */
+#define I2C_CON_XA	(1 << 8)   /* Expand address */
+#define I2C_CON_STP	(1 << 11)  /* Stop condition (master mode only) */
+#define I2C_CON_STT	(1 << 13)  /* Start condition (master mode only) */
+#define I2C_CON_FREE	(1 << 14)  /* Free run on emulation */
+
+#define I2C_TIMEOUT	0xffff0000 /* Timeout mask for poll_i2c_irq() */
+
+#endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (5 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM Murali Karicheri
                     ` (6 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
---
 drivers/i2c/davinci_i2c.c |  344 ++++++++++++++++++++++++++-------------------
 drivers/i2c/davinci_i2c.h |   27 ++--
 2 files changed, 218 insertions(+), 153 deletions(-)

diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index 6e5260c..c584a11 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -1,25 +1,37 @@
 /*
  * TI DaVinci (TMS320DM644x) I2C driver.
  *
- * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
  *
- * --------------------------------------------------------
- *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier:     GPL-2.0+
  */
 
 #include <common.h>
 #include <i2c.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/i2c_defs.h>
+#include <asm/io.h>
 #include "davinci_i2c.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
+						(struct i2c_regs *)I2C_BASE;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+static unsigned int __attribute__((section(".data")))
+		bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 };
+static unsigned int __attribute__((section(".data"))) current_bus;
+#endif
+
 #define CHECK_NACK() \
 	do {\
 		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
-			REG(I2C_CON) = 0;\
-			return(1);\
-		}\
+			REG(&(i2c_base->i2c_con)) = 0;\
+			return 1;\
+		} \
 	} while (0)
 
 
@@ -27,20 +39,21 @@ static int wait_for_bus(void)
 {
 	int	stat, timeout;
 
-	REG(I2C_STAT) = 0xffff;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
 
 	for (timeout = 0; timeout < 10; timeout++) {
-		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
-			REG(I2C_STAT) = 0xffff;
-			return(0);
+		stat = REG(&(i2c_base->i2c_stat));
+		if (!((stat) & I2C_STAT_BB)) {
+			REG(&(i2c_base->i2c_stat)) = 0xffff;
+			return 0;
 		}
 
-		REG(I2C_STAT) = stat;
+		REG(&(i2c_base->i2c_stat)) = stat;
 		udelay(50000);
 	}
 
-	REG(I2C_STAT) = 0xffff;
-	return(1);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return 1;
 }
 
 
@@ -50,25 +63,24 @@ static int poll_i2c_irq(int mask)
 
 	for (timeout = 0; timeout < 10; timeout++) {
 		udelay(1000);
-		stat = REG(I2C_STAT);
-		if (stat & mask) {
-			return(stat);
-		}
+		stat = REG(&(i2c_base->i2c_stat));
+		if (stat & mask)
+			return stat;
 	}
 
-	REG(I2C_STAT) = 0xffff;
-	return(stat | I2C_TIMEOUT);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	return stat | I2C_TIMEOUT;
 }
 
 
 void flush_rx(void)
 {
 	while (1) {
-		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
+		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
 			break;
 
-		REG(I2C_DRR);
-		REG(I2C_STAT) = I2C_STAT_RRDY;
+		REG(&(i2c_base->i2c_drr));
+		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
 		udelay(1000);
 	}
 }
@@ -78,28 +90,33 @@ void i2c_init(int speed, int slaveadd)
 {
 	u_int32_t	div, psc;
 
-	if (REG(I2C_CON) & I2C_CON_EN) {
-		REG(I2C_CON) = 0;
-		udelay (50000);
+	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
+		REG(&(i2c_base->i2c_con)) = 0;
+		udelay(50000);
 	}
 
 	psc = 2;
-	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
-	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
-	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
-	REG(I2C_SCLH) = div - REG(I2C_SCLL);
+	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
+	REG(&(i2c_base->i2c_psc)) = psc;
+	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100;
+	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
 
-	REG(I2C_OA) = slaveadd;
-	REG(I2C_CNT) = 0;
+	REG(&(i2c_base->i2c_oa)) = slaveadd;
+	REG(&(i2c_base->i2c_cnt)) = 0;
 
 	/* Interrupts must be enabled or I2C module won't work */
-	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
+	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
 		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
 
 	/* Now enable I2C controller (get it out of reset) */
-	REG(I2C_CON) = I2C_CON_EN;
+	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
 
 	udelay(1000);
+
+#ifdef CONFIG_I2C_MULTI_BUS
+	if (gd->flags & GD_FLG_RELOC)
+		bus_initialized[current_bus] = 1;
+#endif
 }
 
 int i2c_set_bus_speed(unsigned int speed)
@@ -112,34 +129,36 @@ int i2c_probe(u_int8_t chip)
 {
 	int	rc = 1;
 
-	if (chip == REG(I2C_OA)) {
-		return(rc);
-	}
+	if (chip == REG(&(i2c_base->i2c_oa)))
+		return rc;
 
-	REG(I2C_CON) = 0;
-	if (wait_for_bus()) {return(1);}
+	REG(&(i2c_base->i2c_con)) = 0;
+	if (wait_for_bus())
+		return 1;
 
 	/* try to read one byte from current (or only) address */
-	REG(I2C_CNT) = 1;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
-	udelay (50000);
+	REG(&(i2c_base->i2c_cnt)) = 1;
+	REG(&(i2c_base->i2c_sa))  = chip;
+	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+				     I2C_CON_STP);
+	udelay(50000);
 
-	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
+	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
 		rc = 0;
 		flush_rx();
-		REG(I2C_STAT) = 0xffff;
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
 	} else {
-		REG(I2C_STAT) = 0xffff;
-		REG(I2C_CON) |= I2C_CON_STP;
+		REG(&(i2c_base->i2c_stat)) = 0xffff;
+		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
 		udelay(20000);
-		if (wait_for_bus()) {return(1);}
+		if (wait_for_bus())
+			return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	return(rc);
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	return rc;
 }
 
 
@@ -149,73 +168,76 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	int		i;
 
 	if ((alen < 0) || (alen > 2)) {
-		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
-		return(1);
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
 	}
 
-	if (wait_for_bus()) {return(1);}
+	if (wait_for_bus())
+		return 1;
 
 	if (alen != 0) {
 		/* Start address phase */
 		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
-		REG(I2C_CNT) = alen;
-		REG(I2C_SA) = chip;
-		REG(I2C_CON) = tmp;
+		REG(&(i2c_base->i2c_cnt)) = alen;
+		REG(&(i2c_base->i2c_sa)) = chip;
+		REG(&(i2c_base->i2c_con)) = tmp;
 
 		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
 		CHECK_NACK();
 
 		switch (alen) {
-			case 2:
-				/* Send address MSByte */
-				if (tmp & I2C_STAT_XRDY) {
-					REG(I2C_DXR) = (addr >> 8) & 0xff;
-				} else {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
-
-				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
-
-				CHECK_NACK();
-				/* No break, fall through */
-			case 1:
-				/* Send address LSByte */
-				if (tmp & I2C_STAT_XRDY) {
-					REG(I2C_DXR) = addr & 0xff;
-				} else {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
-
-				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);
-
-				CHECK_NACK();
-
-				if (!(tmp & I2C_STAT_ARDY)) {
-					REG(I2C_CON) = 0;
-					return(1);
-				}
+		case 2:
+			/* Send address MSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+
+			CHECK_NACK();
+			/* No break, fall through */
+		case 1:
+			/* Send address LSByte */
+			if (tmp & I2C_STAT_XRDY) {
+				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+			} else {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
+
+			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK |
+					   I2C_STAT_ARDY);
+
+			CHECK_NACK();
+
+			if (!(tmp & I2C_STAT_ARDY)) {
+				REG(&(i2c_base->i2c_con)) = 0;
+				return 1;
+			}
 		}
 	}
 
 	/* Address phase is over, now read 'len' bytes and stop */
 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
-	REG(I2C_CNT) = len & 0xffff;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = tmp;
+	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
 
 	for (i = 0; i < len; i++) {
-		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);
+		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK |
+				   I2C_STAT_ROVR);
 
 		CHECK_NACK();
 
 		if (tmp & I2C_STAT_RRDY) {
-			buf[i] = REG(I2C_DRR);
+			buf[i] = REG(&(i2c_base->i2c_drr));
 		} else {
-			REG(I2C_CON) = 0;
-			return(1);
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
 		}
 	}
 
@@ -224,16 +246,16 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	CHECK_NACK();
 
 	if (!(tmp & I2C_STAT_SCD)) {
-		REG(I2C_CON) = 0;
-		return(1);
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	REG(I2C_CON) = 0;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
 
-	return(0);
+	return 0;
 }
 
 
@@ -243,48 +265,51 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	int		i;
 
 	if ((alen < 0) || (alen > 2)) {
-		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
-		return(1);
+		printf("%s(): bogus address length %x\n", __func__, alen);
+		return 1;
 	}
 	if (len < 0) {
-		printf("%s(): bogus length %x\n", __FUNCTION__, len);
-		return(1);
+		printf("%s(): bogus length %x\n", __func__, len);
+		return 1;
 	}
 
-	if (wait_for_bus()) {return(1);}
+	if (wait_for_bus())
+		return 1;
 
 	/* Start address phase */
-	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
-	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
-	REG(I2C_SA) = chip;
-	REG(I2C_CON) = tmp;
+	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+		I2C_CON_TRX | I2C_CON_STP;
+	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
+		len & 0xffff : (len & 0xffff) + alen;
+	REG(&(i2c_base->i2c_sa)) = chip;
+	REG(&(i2c_base->i2c_con)) = tmp;
 
 	switch (alen) {
-		case 2:
-			/* Send address MSByte */
-			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+	case 2:
+		/* Send address MSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
-			CHECK_NACK();
+		CHECK_NACK();
 
-			if (tmp & I2C_STAT_XRDY) {
-				REG(I2C_DXR) = (addr >> 8) & 0xff;
-			} else {
-				REG(I2C_CON) = 0;
-				return(1);
-			}
-			/* No break, fall through */
-		case 1:
-			/* Send address LSByte */
-			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
+		/* No break, fall through */
+	case 1:
+		/* Send address LSByte */
+		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
 
-			CHECK_NACK();
+		CHECK_NACK();
 
-			if (tmp & I2C_STAT_XRDY) {
-				REG(I2C_DXR) = addr & 0xff;
-			} else {
-				REG(I2C_CON) = 0;
-				return(1);
-			}
+		if (tmp & I2C_STAT_XRDY) {
+			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
+		} else {
+			REG(&(i2c_base->i2c_con)) = 0;
+			return 1;
+		}
 	}
 
 	for (i = 0; i < len; i++) {
@@ -292,11 +317,10 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 
 		CHECK_NACK();
 
-		if (tmp & I2C_STAT_XRDY) {
-			REG(I2C_DXR) = buf[i];
-		} else {
-			return(1);
-		}
+		if (tmp & I2C_STAT_XRDY)
+			REG(&(i2c_base->i2c_dxr)) = buf[i];
+		else
+			return 1;
 	}
 
 	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);
@@ -304,14 +328,52 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
 	CHECK_NACK();
 
 	if (!(tmp & I2C_STAT_SCD)) {
-		REG(I2C_CON) = 0;
-		return(1);
+		REG(&(i2c_base->i2c_con)) = 0;
+		return 1;
 	}
 
 	flush_rx();
-	REG(I2C_STAT) = 0xffff;
-	REG(I2C_CNT) = 0;
-	REG(I2C_CON) = 0;
+	REG(&(i2c_base->i2c_stat)) = 0xffff;
+	REG(&(i2c_base->i2c_cnt)) = 0;
+	REG(&(i2c_base->i2c_con)) = 0;
+
+	return 0;
+}
+
+#ifdef CONFIG_I2C_MULTI_BUS
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
 
-	return(0);
+	switch (bus) {
+#if I2C_BUS_MAX == 3
+	case 2:
+		i2c_base = (struct i2c_regs *)I2C2_BASE;
+		break;
+#endif
+#if I2C_BUS_MAX >= 2
+	case 1:
+		i2c_base = (struct i2c_regs *)I2C1_BASE;
+		break;
+#endif
+	default:
+		i2c_base = (struct i2c_regs *)I2C0_BASE;
+		bus = 0;
+	}
+
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return (int) current_bus;
 }
+#endif
diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h
index 79ff7a3..20d4342 100644
--- a/drivers/i2c/davinci_i2c.h
+++ b/drivers/i2c/davinci_i2c.h
@@ -12,18 +12,21 @@
 #define I2C_WRITE		0
 #define I2C_READ		1
 
-#define	I2C_OA			(I2C_BASE + 0x00)
-#define I2C_IE			(I2C_BASE + 0x04)
-#define I2C_STAT		(I2C_BASE + 0x08)
-#define I2C_SCLL		(I2C_BASE + 0x0c)
-#define I2C_SCLH		(I2C_BASE + 0x10)
-#define I2C_CNT			(I2C_BASE + 0x14)
-#define I2C_DRR			(I2C_BASE + 0x18)
-#define I2C_SA			(I2C_BASE + 0x1c)
-#define I2C_DXR			(I2C_BASE + 0x20)
-#define I2C_CON			(I2C_BASE + 0x24)
-#define I2C_IV			(I2C_BASE + 0x28)
-#define I2C_PSC			(I2C_BASE + 0x30)
+struct i2c_regs {
+	u32	i2c_oa;
+	u32	i2c_ie;
+	u32	i2c_stat;
+	u32	i2c_scll;
+	u32	i2c_sclh;
+	u32	i2c_cnt;
+	u32	i2c_drr;
+	u32	i2c_sa;
+	u32	i2c_dxr;
+	u32	i2c_con;
+	u32	i2c_iv;
+	u32	res_2c;
+	u32	i2c_psc;
+};
 
 /* I2C masks */
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (6 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver Murali Karicheri
                     ` (5 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
refer the ti/k2hk_evm/README for details on the board, build and other
information.

This patch add support for keystone architecture and k2hk evm.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
---
 - Updated based on review comments
 Makefile                                           |   19 ++
 arch/arm/cpu/armv7/keystone/Makefile               |   17 ++
 arch/arm/cpu/armv7/keystone/aemif.c                |   71 +++++
 arch/arm/cpu/armv7/keystone/clock.c                |  313 ++++++++++++++++++++
 arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 ++++++++
 arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 ++++++++
 arch/arm/cpu/armv7/keystone/config.mk              |   15 +
 arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 +++++
 arch/arm/cpu/armv7/keystone/init.c                 |   56 ++++
 arch/arm/cpu/armv7/keystone/msmc.c                 |   68 +++++
 arch/arm/cpu/armv7/keystone/psc.c                  |  238 +++++++++++++++
 arch/arm/cpu/armv7/keystone/spl.c                  |   45 +++
 arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++++++
 arch/arm/include/asm/arch-keystone/clock.h         |   17 ++
 arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 ++++++++
 arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 +++++
 arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  145 +++++++++
 arch/arm/include/asm/arch-keystone/hardware.h      |  175 +++++++++++
 arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 ++
 arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 ++
 arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++++++
 arch/arm/include/asm/arch-keystone/spl.h           |   12 +
 board/ti/k2hk_evm/Makefile                         |    9 +
 board/ti/k2hk_evm/README                           |   56 ++++
 board/ti/k2hk_evm/board.c                          |  236 +++++++++++++++
 board/ti/k2hk_evm/ddr3.c                           |  269 +++++++++++++++++
 boards.cfg                                         |    1 +
 drivers/serial/ns16550.c                           |    8 +
 include/configs/k2hk_evm.h                         |  221 ++++++++++++++
 29 files changed, 2750 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/Makefile
 create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
 create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
 create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
 create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
 create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
 create mode 100644 arch/arm/cpu/armv7/keystone/init.c
 create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/psc.c
 create mode 100644 arch/arm/cpu/armv7/keystone/spl.c
 create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
 create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
 create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
 create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
 create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
 create mode 100644 board/ti/k2hk_evm/Makefile
 create mode 100644 board/ti/k2hk_evm/README
 create mode 100644 board/ti/k2hk_evm/board.c
 create mode 100644 board/ti/k2hk_evm/ddr3.c
 create mode 100644 include/configs/k2hk_evm.h

diff --git a/Makefile b/Makefile
index 47a03e3..ea2a387 100644
--- a/Makefile
+++ b/Makefile
@@ -491,6 +491,23 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
 		cat $(obj)u-boot.img >> $@
 
+$(obj)u-boot-spi.gph:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+			-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
+		$(OBJCOPY) ${OBJCFLAGS} -I binary \
+			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
+			$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
+		cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+
+$(obj)u-boot-nand.gph:	$(obj)u-boot.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+			-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
+		@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
+		@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
+		@rm $(obj)zero.bin
+
 ifneq ($(CONFIG_TEGRA),)
 $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
 		$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin
@@ -841,12 +858,14 @@ clobber:	tidy
 	@rm -f $(obj)u-boot.dtb
 	@rm -f $(obj)u-boot.sb
 	@rm -f $(obj)u-boot.spr
+	@rm -f $(obj)u-boot-*.gph
 	@rm -f $(obj)nand_spl/{u-boot.{lds,lst},System.map}
 	@rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map}
 	@rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map}
 	@rm -f $(obj)spl/u-boot-spl.lds
 	@rm -f $(obj)tpl/{u-boot-tpl,u-boot-tpl.bin,u-boot-tpl.map}
 	@rm -f $(obj)tpl/u-boot-spl.lds
+	@rm -f $(obj)spl/{u-boot-spl.gph,u-boot-spl-pad.gph}
 	@rm -f $(obj)MLO MLO.byteswap
 	@rm -f $(obj)SPL
 	@rm -f $(obj)tools/xway-swap-bytes
diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
new file mode 100644
index 0000000..7924cfa
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= aemif.o
+obj-y	+= init.o
+obj-y	+= psc.o
+obj-y	+= clock.o
+obj-y	+= cmd_clock.o
+obj-y	+= cmd_mon.o
+obj-y	+= msmc.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
+obj-y	+= ddr3.o
+
diff --git a/arch/arm/cpu/armv7/keystone/aemif.c b/arch/arm/cpu/armv7/keystone/aemif.c
new file mode 100644
index 0000000..9b26886
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/aemif.c
@@ -0,0 +1,71 @@
+/*
+ * Keystone2: Asynchronous EMIF Configuration
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/emif_defs.h>
+
+#define AEMIF_CFG_SELECT_STROBE(v)	((v) ? 1 << 31 : 0)
+#define AEMIF_CFG_EXTEND_WAIT(v)	((v) ? 1 << 30 : 0)
+#define AEMIF_CFG_WR_SETUP(v)		(((v) & 0x0f) << 26)
+#define AEMIF_CFG_WR_STROBE(v)		(((v) & 0x3f) << 20)
+#define AEMIF_CFG_WR_HOLD(v)		(((v) & 0x07) << 17)
+#define AEMIF_CFG_RD_SETUP(v)		(((v) & 0x0f) << 13)
+#define AEMIF_CFG_RD_STROBE(v)		(((v) & 0x3f) << 7)
+#define AEMIF_CFG_RD_HOLD(v)		(((v) & 0x07) << 4)
+#define AEMIF_CFG_TURN_AROUND(v)	(((v) & 0x03) << 2)
+#define AEMIF_CFG_WIDTH(v)		(((v) & 0x03) << 0)
+
+#define set_config_field(reg, field, val)			\
+	do {							\
+		if (val != -1) {				\
+			reg &= ~AEMIF_CFG_##field(0xffffffff);	\
+			reg |=	AEMIF_CFG_##field(val);		\
+		}						\
+	} while (0)
+
+void configure_async_emif(int cs, struct async_emif_config *cfg)
+{
+	unsigned long tmp;
+
+	if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
+		tmp = __raw_readl(&davinci_emif_regs->nandfcr);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, &davinci_emif_regs->nandfcr);
+
+	} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
+		tmp = __raw_readl(&davinci_emif_regs->one_nand_cr);
+		tmp |= (1 << cs);
+		__raw_writel(tmp, &davinci_emif_regs->one_nand_cr);
+	}
+
+	tmp = __raw_readl(&davinci_emif_regs->abncr[cs]);
+
+	set_config_field(tmp, SELECT_STROBE,	cfg->select_strobe);
+	set_config_field(tmp, EXTEND_WAIT,	cfg->extend_wait);
+	set_config_field(tmp, WR_SETUP,		cfg->wr_setup);
+	set_config_field(tmp, WR_STROBE,	cfg->wr_strobe);
+	set_config_field(tmp, WR_HOLD,		cfg->wr_hold);
+	set_config_field(tmp, RD_SETUP,		cfg->rd_setup);
+	set_config_field(tmp, RD_STROBE,	cfg->rd_strobe);
+	set_config_field(tmp, RD_HOLD,		cfg->rd_hold);
+	set_config_field(tmp, TURN_AROUND,	cfg->turn_around);
+	set_config_field(tmp, WIDTH,		cfg->width);
+
+	__raw_writel(tmp, &davinci_emif_regs->abncr[cs]);
+}
+
+void init_async_emif(int num_cs, struct async_emif_config *config)
+{
+	int cs;
+
+	for (cs = 0; cs < num_cs; cs++)
+		configure_async_emif(cs, config + cs);
+}
diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c
new file mode 100644
index 0000000..87d7c7f
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/clock.c
@@ -0,0 +1,313 @@
+/*
+ * Keystone2: pll initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clock_defs.h>
+
+static void wait_for_completion(const struct pll_init_data *data)
+{
+	int i;
+	for (i = 0; i < 100; i++) {
+		sdelay(450);
+		if ((pllctl_reg_read(data->pll, stat) & PLLSTAT_GO) == 0)
+			break;
+	}
+}
+
+struct pll_regs {
+	u32	reg0, reg1;
+};
+
+static const struct pll_regs pll_regs[] = {
+	[CORE_PLL]	= { K2HK_MAINPLLCTL0, K2HK_MAINPLLCTL1},
+	[PASS_PLL]	= { K2HK_PASSPLLCTL0, K2HK_PASSPLLCTL1},
+	[TETRIS_PLL]	= { K2HK_ARMPLLCTL0,  K2HK_ARMPLLCTL1},
+	[DDR3A_PLL]	= { K2HK_DDR3APLLCTL0, K2HK_DDR3APLLCTL1},
+	[DDR3B_PLL]	= { K2HK_DDR3BPLLCTL0, K2HK_DDR3BPLLCTL1},
+};
+
+/* Fout = Fref * NF(mult) / NR(prediv) / OD */
+static unsigned long pll_freq_get(int pll)
+{
+	unsigned long mult = 1, prediv = 1, output_div = 2;
+	unsigned long ret;
+	u32 tmp, reg;
+
+	if (pll == CORE_PLL) {
+		ret = external_clk[sys_clk];
+		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) {
+			/* PLL mode */
+			tmp = __raw_readl(K2HK_MAINPLLCTL0);
+			prediv = (tmp & PLL_DIV_MASK) + 1;
+			mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) |
+				(pllctl_reg_read(pll, mult) &
+				 PLLM_MULT_LO_MASK)) + 1;
+			output_div = ((pllctl_reg_read(pll, secctl) >>
+				       PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1;
+
+			ret = ret / prediv / output_div * mult;
+		}
+	} else {
+		switch (pll) {
+		case PASS_PLL:
+			ret = external_clk[pa_clk];
+			reg = K2HK_PASSPLLCTL0;
+			break;
+		case TETRIS_PLL:
+			ret = external_clk[tetris_clk];
+			reg = K2HK_ARMPLLCTL0;
+			break;
+		case DDR3A_PLL:
+			ret = external_clk[ddr3a_clk];
+			reg = K2HK_DDR3APLLCTL0;
+			break;
+		case DDR3B_PLL:
+			ret = external_clk[ddr3b_clk];
+			reg = K2HK_DDR3BPLLCTL0;
+			break;
+		default:
+			return 0;
+		}
+
+		tmp = __raw_readl(reg);
+
+		if (!(tmp & PLLCTL_BYPASS)) {
+			/* Bypass disabled */
+			prediv = (tmp & PLL_DIV_MASK) + 1;
+			mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1;
+			output_div = ((tmp >> PLL_CLKOD_SHIFT) &
+				      PLL_CLKOD_MASK) + 1;
+			ret = ((ret / prediv) * mult) / output_div;
+		}
+	}
+
+	return ret;
+}
+
+unsigned long clk_get_rate(unsigned int clk)
+{
+	switch (clk) {
+	case core_pll_clk:	return pll_freq_get(CORE_PLL);
+	case pass_pll_clk:	return pll_freq_get(PASS_PLL);
+	case tetris_pll_clk:	return pll_freq_get(TETRIS_PLL);
+	case ddr3a_pll_clk:	return pll_freq_get(DDR3A_PLL);
+	case ddr3b_pll_clk:	return pll_freq_get(DDR3B_PLL);
+	case sys_clk0_1_clk:
+	case sys_clk0_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(1);
+	case sys_clk1_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(2);
+	case sys_clk2_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(3);
+	case sys_clk3_clk:	return pll_freq_get(CORE_PLL) / pll0div_read(4);
+	case sys_clk0_2_clk:	return clk_get_rate(sys_clk0_clk) / 2;
+	case sys_clk0_3_clk:	return clk_get_rate(sys_clk0_clk) / 3;
+	case sys_clk0_4_clk:	return clk_get_rate(sys_clk0_clk) / 4;
+	case sys_clk0_6_clk:	return clk_get_rate(sys_clk0_clk) / 6;
+	case sys_clk0_8_clk:	return clk_get_rate(sys_clk0_clk) / 8;
+	case sys_clk0_12_clk:	return clk_get_rate(sys_clk0_clk) / 12;
+	case sys_clk0_24_clk:	return clk_get_rate(sys_clk0_clk) / 24;
+	case sys_clk1_3_clk:	return clk_get_rate(sys_clk1_clk) / 3;
+	case sys_clk1_4_clk:	return clk_get_rate(sys_clk1_clk) / 4;
+	case sys_clk1_6_clk:	return clk_get_rate(sys_clk1_clk) / 6;
+	case sys_clk1_12_clk:	return clk_get_rate(sys_clk1_clk) / 12;
+	default:
+		break;
+	}
+	return 0;
+}
+
+void init_pll(const struct pll_init_data *data)
+{
+	u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj;
+
+	pllm = data->pll_m - 1;
+	plld = (data->pll_d - 1) & PLL_DIV_MASK;
+	pllod = (data->pll_od - 1) & PLL_CLKOD_MASK;
+
+	if (data->pll == MAIN_PLL) {
+		sdelay(210000);
+
+		tmp = pllctl_reg_read(data->pll, secctl);
+
+		if (tmp & (PLLCTL_BYPASS)) {
+			reg_setbits(pll_regs[data->pll].reg1,
+				    BIT(MAIN_ENSAT_OFFSET));
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			sdelay(340);
+
+			pllctl_reg_setbits(data->pll, secctl, PLLCTL_BYPASS);
+			pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+			sdelay(21000);
+
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
+		} else {
+			pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN |
+					   PLLCTL_PLLENSRC);
+			sdelay(340);
+		}
+
+		pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);
+
+		reg_rmw(pll_regs[data->pll].reg0, PLLM_MULT_HI_SMASK,
+			(pllm << 6));
+
+		/* Set the BWADJ     (12 bit field)  */
+		tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */
+		reg_rmw(pll_regs[data->pll].reg0, PLL_BWADJ_LO_SMASK,
+			(tmp_ctl << PLL_BWADJ_LO_SHIFT));
+		reg_rmw(pll_regs[data->pll].reg1, PLL_BWADJ_HI_MASK,
+			(tmp_ctl >> 8));
+
+		/*
+		 * Set the pll divider (6 bit field) *
+		 * PLLD[5:0] is located in MAINPLLCTL0
+		 */
+		reg_rmw(pll_regs[data->pll].reg0, PLL_DIV_MASK, plld);
+
+		/* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
+		pllctl_reg_rmw(data->pll, secctl, PLL_CLKOD_SMASK,
+			       (pllod << PLL_CLKOD_SHIFT));
+		wait_for_completion(data);
+
+		pllctl_reg_write(data->pll, div1, PLLM_RATIO_DIV1);
+		pllctl_reg_write(data->pll, div2, PLLM_RATIO_DIV2);
+		pllctl_reg_write(data->pll, div3, PLLM_RATIO_DIV3);
+		pllctl_reg_write(data->pll, div4, PLLM_RATIO_DIV4);
+		pllctl_reg_write(data->pll, div5, PLLM_RATIO_DIV5);
+
+		pllctl_reg_setbits(data->pll, alnctl, 0x1f);
+
+		/*
+		 * Set GOSET bit in PLLCMD to initiate the GO operation
+		 * to change the divide
+		 */
+		pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GO);
+		sdelay(1500); /* wait for the phase adj */
+		wait_for_completion(data);
+
+		/* Reset PLL */
+		pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
+		sdelay(21000);	/* Wait for a minimum of 7 us*/
+		pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
+		sdelay(105000);	/* Wait for PLL Lock time (min 50 us) */
+
+		pllctl_reg_clrbits(data->pll, secctl, PLLCTL_BYPASS);
+
+		tmp = pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
+
+	} else if (data->pll == TETRIS_PLL) {
+		bwadj = pllm >> 1;
+		/* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */
+		reg_setbits(pll_regs[data->pll].reg0,  PLLCTL_BYPASS);
+		/*
+		 * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
+		 * only applicable for Kepler
+		 */
+		reg_clrbits(K2HK_MISC_CTRL, ARM_PLL_EN);
+		/* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
+		reg_setbits(pll_regs[data->pll].reg1 ,
+			    PLL_PLLRST | PLLCTL_ENSAT);
+
+		/*
+		 * 3 Program PLLM and PLLD in PLLCTL0 register
+		 * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in
+		 * PLLCTL1 register. BWADJ value must be set
+		 * to ((PLLM + 1) >> 1) ? 1)
+		 */
+		tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) |
+			(pllm << 6) |
+			(plld & PLL_DIV_MASK) |
+			(pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS;
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(PLL_BWADJ_HI_MASK);
+		tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK);
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+		/*
+		 * 5 Wait for at least 5 us based on the reference
+		 * clock (PLL reset time)
+		 */
+		sdelay(21000);	/* Wait for a minimum of 7 us*/
+
+		/* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
+		reg_clrbits(pll_regs[data->pll].reg1, PLL_PLLRST);
+		/*
+		 * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1)
+		 * (PLL lock time)
+		 */
+		sdelay(105000);
+		/* 8 disable bypass */
+		reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
+		/*
+		 * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
+		 * only applicable for Kepler
+		 */
+		reg_setbits(K2HK_MISC_CTRL, ARM_PLL_EN);
+	} else {
+		reg_setbits(pll_regs[data->pll].reg1, PLLCTL_ENSAT);
+		/*
+		 * process keeps state of Bypass bit while programming
+		 * all other DDR PLL settings
+		 */
+		tmp = __raw_readl(pll_regs[data->pll].reg0);
+		tmp &= PLLCTL_BYPASS;	/* clear everything except Bypass */
+
+		/*
+		 * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
+		 * bypass disabled
+		 */
+		bwadj = pllm >> 1;
+		tmp |= ((bwadj & PLL_BWADJ_LO_SHIFT) << PLL_BWADJ_LO_SHIFT) |
+			(pllm << PLL_MULT_SHIFT) |
+			(plld & PLL_DIV_MASK) |
+			(pllod << PLL_CLKOD_SHIFT);
+		__raw_writel(tmp, pll_regs[data->pll].reg0);
+
+		/* Set BWADJ[11:8] bits */
+		tmp = __raw_readl(pll_regs[data->pll].reg1);
+		tmp &= ~(PLL_BWADJ_HI_MASK);
+		tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK);
+
+		/* set PLL Select (bit 13) for PASS PLL */
+		if (data->pll == PASS_PLL)
+			tmp |= PLLCTL_PAPLL;
+
+		__raw_writel(tmp, pll_regs[data->pll].reg1);
+
+		/* Reset bit: bit 14 for both DDR3 & PASS PLL */
+		tmp = PLL_PLLRST;
+		/* Set RESET bit = 1 */
+		reg_setbits(pll_regs[data->pll].reg1, tmp);
+		/* Wait for a minimum of 7 us*/
+		sdelay(21000);
+		/* Clear RESET bit */
+		reg_clrbits(pll_regs[data->pll].reg1, tmp);
+		sdelay(105000);
+
+		/* clear BYPASS (Enable PLL Mode) */
+		reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS);
+		sdelay(21000);	/* Wait for a minimum of 7 us*/
+	}
+
+	sdelay(210000);
+}
+
+void init_plls(int num_pll, struct pll_init_data *config)
+{
+	int i;
+
+	for (i = 0; i < num_pll; i++)
+		init_pll(&config[i]);
+}
diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c
new file mode 100644
index 0000000..afd30f3
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c
@@ -0,0 +1,124 @@
+/*
+ * keystone2: commands for clocks
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/psc_defs.h>
+
+struct pll_init_data cmd_pll_data = {
+	.pll			= MAIN_PLL,
+	.pll_m			= 16,
+	.pll_d			= 1,
+	.pll_od			= 2,
+};
+
+int do_pll_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	if (argc != 5)
+		goto pll_cmd_usage;
+
+	if (strncmp(argv[1], "pa", 2) == 0)
+		cmd_pll_data.pll = PASS_PLL;
+	else if (strncmp(argv[1], "arm", 3) == 0)
+		cmd_pll_data.pll = TETRIS_PLL;
+	else if (strncmp(argv[1], "ddr3a", 5) == 0)
+		cmd_pll_data.pll = DDR3A_PLL;
+	else if (strncmp(argv[1], "ddr3b", 5) == 0)
+		cmd_pll_data.pll = DDR3B_PLL;
+	else
+		goto pll_cmd_usage;
+
+	cmd_pll_data.pll_m   = simple_strtoul(argv[2], NULL, 10);
+	cmd_pll_data.pll_d   = simple_strtoul(argv[3], NULL, 10);
+	cmd_pll_data.pll_od  = simple_strtoul(argv[4], NULL, 10);
+
+	printf("Trying to set pll %d; mult %d; div %d; OD %d\n",
+	       cmd_pll_data.pll, cmd_pll_data.pll_m,
+	       cmd_pll_data.pll_d, cmd_pll_data.pll_od);
+	init_pll(&cmd_pll_data);
+
+	return 0;
+
+pll_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	pllset,	5,	0,	do_pll_cmd,
+	"set pll multiplier and pre divider",
+	"<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\n"
+);
+
+int do_getclk_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned int clk;
+	unsigned int freq;
+
+	if (argc != 2)
+		goto getclk_cmd_usage;
+
+	clk = simple_strtoul(argv[1], NULL, 10);
+
+	freq = clk_get_rate(clk);
+	printf("clock index [%d] - frequency %u\n", clk, freq);
+	return 0;
+
+getclk_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	getclk,	2,	0,	do_getclk_cmd,
+	"get clock rate",
+	"<clk index>\n"
+	"See the 'enum clk_e' in the k2hk clock.h for clk indexes\n"
+);
+
+int do_psc_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int	psc_module;
+	int	res;
+
+	if (argc != 3)
+		goto psc_cmd_usage;
+
+	psc_module = simple_strtoul(argv[1], NULL, 10);
+	if (strcmp(argv[2], "en") == 0) {
+		res = psc_enable_module(psc_module);
+		printf("psc_enable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "di") == 0) {
+		res = psc_disable_module(psc_module);
+		printf("psc_disable_module(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+	if (strcmp(argv[2], "domain") == 0) {
+		res = psc_disable_domain(psc_module);
+		printf("psc_disable_domain(%d) - %s\n", psc_module,
+		       (res) ? "ERROR" : "OK");
+		return 0;
+	}
+
+psc_cmd_usage:
+	return cmd_usage(cmdtp);
+}
+
+U_BOOT_CMD(
+	psc,	3,	0,	do_psc_cmd,
+	"<enable/disable psc module os disable domain>",
+	"<mod/domain index> <en|di|domain>\n"
+	"See the hardware.h for Power and Sleep Controller (PSC) Domains\n"
+);
diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c
new file mode 100644
index 0000000..f9f58a3
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/cmd_mon.c
@@ -0,0 +1,131 @@
+/*
+ * K2HK: secure kernel command file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+asm(".arch_extension sec\n\t");
+
+static int mon_install(u32 addr, u32 dpsc, u32 freq)
+{
+	int result;
+
+	__asm__ __volatile__ (
+		"stmfd r13!, {lr}\n"
+		"mov r0, %1\n"
+		"mov r1, %2\n"
+		"mov r2, %3\n"
+		"blx r0\n"
+		"ldmfd r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (addr), "r" (dpsc), "r" (freq)
+		: "cc", "r0", "r1", "r2", "memory");
+	return result;
+}
+
+static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	u32 addr, dpsc_base = 0x1E80000, freq;
+	int     rcode = 0;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	freq = clk_get_rate(sys_clk0_6_clk);
+
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	rcode = mon_install(addr, dpsc_base, freq);
+	printf("## installed monitor, freq [%d], status %d\n",
+	       freq, rcode);
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_install, 2, 0, do_mon_install,
+	   "Install boot kernel@'addr'",
+	   ""
+);
+
+static void core_spin(void)
+{
+	while (1)
+		; /* forever */;
+}
+
+int mon_power_on(int core_id, void *ep)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r2, %2\n"
+		"mov r0, #0\n"
+		"smc	#0\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id), "r" (ep)
+		: "cc", "r0", "r1", "r2", "memory");
+	return  result;
+}
+
+int mon_power_off(int core_id)
+{
+	int result;
+
+	asm volatile (
+		"stmfd  r13!, {lr}\n"
+		"mov r1, %1\n"
+		"mov r0, #1\n"
+		"smc	#1\n"
+		"ldmfd  r13!, {lr}\n"
+		: "=&r" (result)
+		: "r" (core_id)
+		: "cc", "r0", "r1", "memory");
+	return  result;
+}
+
+int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	int     rcode = 0, core_id, on;
+	void (*fn)(void);
+
+	fn = core_spin;
+
+	if (argc < 3)
+		return CMD_RET_USAGE;
+
+	core_id = simple_strtoul(argv[1], NULL, 16);
+	on = simple_strtoul(argv[2], NULL, 16);
+
+	if (on)
+		rcode = mon_power_on(core_id, fn);
+	else
+		rcode = mon_power_off(core_id);
+
+	if (on) {
+		if (!rcode)
+			printf("core %d powered on successfully\n", core_id);
+		else
+			printf("core %d power on failure\n", core_id);
+	} else {
+		printf("core %d powered off successfully\n", core_id);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(mon_power, 3, 0, do_mon_power,
+	   "Power On/Off secondary core",
+	   "mon_power <coreid> <oper>\n"
+	   "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n"
+	   ""
+);
diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk
new file mode 100644
index 0000000..1c8769c
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/config.mk
@@ -0,0 +1,15 @@
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
+
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PF_CPPFLAGS_SLB +=$(call cc-option,-mshort-load-bytes,\
+		    $(call cc-option,-malignment-traps,))
+PLATFORM_RELFLAGS += $(PF_CPPFLAGS_SLB)
diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c
new file mode 100644
index 0000000..4875db7
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/ddr3.c
@@ -0,0 +1,69 @@
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg)
+{
+	unsigned int tmp;
+
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET)
+		 & 0x00000001) != 0x00000001)
+		;
+
+	__raw_writel(phy_cfg->pllcr, base + KS2_DDRPHY_PLLCR_OFFSET);
+
+	tmp = __raw_readl(base + KS2_DDRPHY_PGCR1_OFFSET);
+	tmp &= ~(phy_cfg->pgcr1_mask);
+	tmp |= phy_cfg->pgcr1_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_PGCR1_OFFSET);
+
+	__raw_writel(phy_cfg->ptr0,   base + KS2_DDRPHY_PTR0_OFFSET);
+	__raw_writel(phy_cfg->ptr1,   base + KS2_DDRPHY_PTR1_OFFSET);
+	__raw_writel(phy_cfg->ptr3,  base + KS2_DDRPHY_PTR3_OFFSET);
+	__raw_writel(phy_cfg->ptr4,  base + KS2_DDRPHY_PTR4_OFFSET);
+
+	tmp =  __raw_readl(base + KS2_DDRPHY_DCR_OFFSET);
+	tmp &= ~(phy_cfg->dcr_mask);
+	tmp |= phy_cfg->dcr_val;
+	__raw_writel(tmp, base + KS2_DDRPHY_DCR_OFFSET);
+
+	__raw_writel(phy_cfg->dtpr0, base + KS2_DDRPHY_DTPR0_OFFSET);
+	__raw_writel(phy_cfg->dtpr1, base + KS2_DDRPHY_DTPR1_OFFSET);
+	__raw_writel(phy_cfg->dtpr2, base + KS2_DDRPHY_DTPR2_OFFSET);
+	__raw_writel(phy_cfg->mr0,   base + KS2_DDRPHY_MR0_OFFSET);
+	__raw_writel(phy_cfg->mr1,   base + KS2_DDRPHY_MR1_OFFSET);
+	__raw_writel(phy_cfg->mr2,   base + KS2_DDRPHY_MR2_OFFSET);
+	__raw_writel(phy_cfg->dtcr,  base + KS2_DDRPHY_DTCR_OFFSET);
+	__raw_writel(phy_cfg->pgcr2, base + KS2_DDRPHY_PGCR2_OFFSET);
+
+	__raw_writel(phy_cfg->zq0cr1, base + KS2_DDRPHY_ZQ0CR1_OFFSET);
+	__raw_writel(phy_cfg->zq1cr1, base + KS2_DDRPHY_ZQ1CR1_OFFSET);
+	__raw_writel(phy_cfg->zq2cr1, base + KS2_DDRPHY_ZQ2CR1_OFFSET);
+
+	__raw_writel(phy_cfg->pir_v1, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+
+	__raw_writel(phy_cfg->pir_v2, base + KS2_DDRPHY_PIR_OFFSET);
+	while ((__raw_readl(base + KS2_DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1)
+		;
+}
+
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg)
+{
+	__raw_writel(emif_cfg->sdcfg,  base + KS2_DDR3_SDCFG_OFFSET);
+	__raw_writel(emif_cfg->sdtim1, base + KS2_DDR3_SDTIM1_OFFSET);
+	__raw_writel(emif_cfg->sdtim2, base + KS2_DDR3_SDTIM2_OFFSET);
+	__raw_writel(emif_cfg->sdtim3, base + KS2_DDR3_SDTIM3_OFFSET);
+	__raw_writel(emif_cfg->sdtim4, base + KS2_DDR3_SDTIM4_OFFSET);
+	__raw_writel(emif_cfg->zqcfg,  base + KS2_DDR3_ZQCFG_OFFSET);
+	__raw_writel(emif_cfg->sdrfc,  base + KS2_DDR3_SDRFC_OFFSET);
+}
diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c
new file mode 100644
index 0000000..1b7e52a
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/init.c
@@ -0,0 +1,56 @@
+/*
+ * Keystone2: Architecture initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+
+void chip_configuration_unlock(void)
+{
+	__raw_writel(KEYSTONE_KICK0_MAGIC, KEYSTONE_KICK0);
+	__raw_writel(KEYSTONE_KICK1_MAGIC, KEYSTONE_KICK1);
+}
+
+int arch_cpu_init(void)
+{
+	chip_configuration_unlock();
+	icache_enable();
+
+#ifdef CONFIG_SOC_K2HK
+	share_all_segments(8);
+	share_all_segments(9);
+	share_all_segments(10); /* QM PDSP */
+	share_all_segments(11); /* PCIE */
+#endif
+
+	return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+	volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8);
+	u32 tmp;
+
+	tmp = *rstctrl & 0xffff0000;
+	*rstctrl = tmp | 0x5a69;
+
+	*rstctrl &= 0xfffe0000;
+
+	for (;;)
+		;
+}
+
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_DCACHE_OFF
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+#endif
+}
diff --git a/arch/arm/cpu/armv7/keystone/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c
new file mode 100644
index 0000000..f3f1621
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/msmc.c
@@ -0,0 +1,68 @@
+/*
+ * MSMC controller utilities
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+
+struct mpax {
+	u32	mpaxl;
+	u32	mpaxh;
+};
+
+struct msms_regs {
+	u32	pid;
+	u32	_res_04;
+	u32	smcerrar;
+	u32	smcerrxr;
+	u32	smedcc;
+	u32	smcea;
+	u32	smsecc;
+	u32	smpfar;
+	u32	smpfxr;
+	u32	smpfr;
+	u32	smpfcr;
+	u32	_res_2c;
+	u32	sbndc[8];
+	u32	sbndm;
+	u32	sbnde;
+	u32	_res_58;
+	u32	cfglck;
+	u32	cfgulck;
+	u32	cfglckstat;
+	u32	sms_mpax_lck;
+	u32	sms_mpax_ulck;
+	u32	sms_mpax_lckstat;
+	u32	ses_mpax_lck;
+	u32	ses_mpax_ulck;
+	u32	ses_mpax_lckstat;
+	u32	smestat;
+	u32	smirstat;
+	u32	smirc;
+	u32	smiestat;
+	u32	smiec;
+	u32	_res_94_c0[12];
+	u32	smncerrar;
+	u32	smncerrxr;
+	u32	smncea;
+	u32	_res_d0_1fc[76];
+	struct mpax sms[16][8];
+	struct mpax ses[16][8];
+};
+
+
+void share_all_segments(int priv_id)
+{
+	struct msms_regs *msmc = (struct msms_regs *)K2HK_MSMC_CTRL_BASE;
+	int j;
+
+	for (j = 0; j < 8; j++) {
+		msmc->sms[priv_id][j].mpaxh &= 0xffffff7ful;
+		msmc->ses[priv_id][j].mpaxh &= 0xffffff7ful;
+	}
+}
diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c
new file mode 100644
index 0000000..fecf918
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/psc.c
@@ -0,0 +1,238 @@
+/*
+ * Keystone: PSC configuration module
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm-generic/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/psc_defs.h>
+
+#define DEVICE_REG32_R(addr)			__raw_readl((u32 *)(addr))
+#define DEVICE_REG32_W(addr, val)		__raw_writel(val, (u32 *)(addr))
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSC_BASE				K2HK_PSC_BASE
+#endif
+
+int psc_delay(void)
+{
+	udelay(10);
+	return 10;
+}
+
+/*
+ * FUNCTION PURPOSE: Wait for end of transitional state
+ *
+ * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
+ *              to be complete.
+ *
+ *              Since this is boot loader code it is *ASSUMED* that interrupts
+ *              are disabled and no other core is mucking around with the psc
+ *              at the same time.
+ *
+ *              Returns 0 when the domain is free. Returns -1 if a timeout
+ *              occurred waiting for the completion.
+ */
+int psc_wait(u32 domain_num)
+{
+	u32 retry;
+	u32 ptstat;
+
+	/*
+	 * Do nothing if the power domain is in transition. This should never
+	 * happen since the boot code is the only software accesses psc.
+	 * It's still remotely possible that the hardware state machines
+	 * initiate transitions.
+	 * Don't trap if the domain (or a module in this domain) is
+	 * stuck in transition.
+	 */
+	retry = 0;
+
+	do {
+		ptstat = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PSTAT);
+		ptstat = ptstat & (1 << domain_num);
+	} while ((ptstat != 0) && ((retry += psc_delay()) <
+		 PSC_PTSTAT_TIMEOUT_LIMIT));
+
+	if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
+		return -1;
+
+	return 0;
+}
+
+u32 psc_get_domain_num(u32 mod_num)
+{
+	u32 domain_num;
+
+	/* Get the power domain associated with the module number */
+	domain_num = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				    PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
+
+	return domain_num;
+}
+
+/*
+ * FUNCTION PURPOSE: Power up/down a module
+ *
+ * DESCRIPTION: Powers up/down the requested module and the associated power
+ *		domain if required. No action is taken it the module is
+ *		already powered up/down.
+ *
+ *              This only controls modules. The domain in which the module
+ *              resides will be left in the power on state. Multiple modules
+ *              can exist in a power domain, so powering down the domain based
+ *              on a single module is not done.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ */
+int psc_set_state(u32 mod_num, u32 state)
+{
+	u32 domain_num;
+	u32 pdctl;
+	u32 mdctl;
+	u32 ptcmd;
+	u32 reset_iso;
+	u32 v;
+
+	/*
+	 * Get the power domain associated with the module number, and reset
+	 * isolation functionality
+	 */
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	domain_num = PSC_REG_MDCFG_GET_PD(v);
+	reset_iso  = PSC_REG_MDCFG_GET_RESET_ISO(v);
+
+	/* Wait for the status of the domain/module to be non-transitional */
+	if (psc_wait(domain_num) != 0)
+		return -1;
+
+	/*
+	 * Perform configuration even if the current status matches the
+	 * existing state
+	 *
+	 * Set the next state of the power domain to on. It's OK if the domain
+	 * is always on. This code will not ever power down a domain, so no
+	 * change is made if the new state is power down.
+	 */
+	if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
+		pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE +
+				       PSC_REG_PDCTL(domain_num));
+		pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
+					       PSC_REG_VAL_PDCTL_NEXT_ON);
+		DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num),
+			       pdctl);
+	}
+
+	/* Set the next state for the module to enabled/disabled */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	/* Trigger the enable */
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1<<domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	/* Wait on the complete */
+	return psc_wait(domain_num);
+}
+
+/*
+ * FUNCTION PURPOSE: Power up a module
+ *
+ * DESCRIPTION: Powers up the requested module and the associated power domain
+ *              if required. No action is taken it the module is already
+ *              powered up.
+ *
+ *              Returns 0 on success, -1 if the module can't be powered up, or
+ *              if there is a timeout waiting for the transition.
+ */
+int psc_enable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
+		return 0;
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
+}
+
+/*
+ * FUNCTION PURPOSE: Power down a module
+ *
+ * DESCRIPTION: Powers down the requested module.
+ *
+ *              Returns 0 on success, -1 on failure or timeout.
+ */
+int psc_disable_module(u32 mod_num)
+{
+	u32 mdctl;
+
+	/* Set the bit to apply reset */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	if ((mdctl & 0x3f) == 0)
+		return 0;
+	mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
+}
+
+/*
+ * FUNCTION PURPOSE: Set the reset isolation bit in mdctl
+ *
+ * DESCRIPTION: The reset isolation enable bit is set. The state of the module
+ *              is not changed. Returns 0 if the module config showed that
+ *              reset isolation is supported. Returns 1 otherwise. This is not
+ *              an error, but setting the bit in mdctl has no effect.
+ */
+int psc_set_reset_iso(u32 mod_num)
+{
+	u32 v;
+	u32 mdctl;
+
+	/* Set the reset isolation bit */
+	mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num));
+	mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl);
+
+	v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num));
+	if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
+		return 0;
+
+	return 1;
+}
+
+/*
+ * FUNCTION PURPOSE: Disable a power domain
+ *
+ * DESCRIPTION: The power domain is disabled
+ */
+int psc_disable_domain(u32 domain_num)
+{
+	u32 pdctl;
+	u32 ptcmd;
+
+	pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num));
+	pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
+	pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num), pdctl);
+
+	ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD);
+	ptcmd |= (u32)(1 << domain_num);
+	DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd);
+
+	return psc_wait(domain_num);
+}
+
diff --git a/arch/arm/cpu/armv7/keystone/spl.c b/arch/arm/cpu/armv7/keystone/spl.c
new file mode 100644
index 0000000..e07b64d
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/spl.c
@@ -0,0 +1,45 @@
+/*
+ * common spl init code
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <config.h>
+#include <ns16550.h>
+#include <malloc.h>
+#include <spl.h>
+#include <spi_flash.h>
+
+#include <asm/u-boot.h>
+#include <asm/utils.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct pll_init_data spl_pll_config[] = {
+	CORE_PLL_799,
+	TETRIS_PLL_500,
+};
+
+void spl_init_keystone_plls(void)
+{
+	init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config);
+}
+
+void spl_board_init(void)
+{
+	spl_init_keystone_plls();
+	preloader_console_init();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_LOAD)
+	return BOOT_DEVICE_SPI;
+#else
+	puts("Unknown boot device\n");
+	hang();
+#endif
+}
diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
new file mode 100644
index 0000000..6721939
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h
@@ -0,0 +1,109 @@
+/*
+ * K2HK: Clock management APIs
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_K2HK_H
+#define __ASM_ARCH_CLOCK_K2HK_H
+
+#include <asm/arch/hardware.h>
+
+#ifndef __ASSEMBLY__
+
+enum ext_clk_e {
+	sys_clk,
+	alt_core_clk,
+	pa_clk,
+	tetris_clk,
+	ddr3a_clk,
+	ddr3b_clk,
+	mcm_clk,
+	pcie_clk,
+	sgmii_srio_clk,
+	xgmii_clk,
+	usb_clk,
+	rp1_clk,
+	ext_clk_count /* number of external clocks */
+};
+
+extern unsigned int external_clk[ext_clk_count];
+
+enum clk_e {
+	core_pll_clk,
+	pass_pll_clk,
+	tetris_pll_clk,
+	ddr3a_pll_clk,
+	ddr3b_pll_clk,
+	sys_clk0_clk,
+	sys_clk0_1_clk,
+	sys_clk0_2_clk,
+	sys_clk0_3_clk,
+	sys_clk0_4_clk,
+	sys_clk0_6_clk,
+	sys_clk0_8_clk,
+	sys_clk0_12_clk,
+	sys_clk0_24_clk,
+	sys_clk1_clk,
+	sys_clk1_3_clk,
+	sys_clk1_4_clk,
+	sys_clk1_6_clk,
+	sys_clk1_12_clk,
+	sys_clk2_clk,
+	sys_clk3_clk
+};
+
+#define K2HK_CLK1_6	sys_clk0_6_clk
+
+/* PLL identifiers */
+enum pll_type_e {
+	CORE_PLL,
+	PASS_PLL,
+	TETRIS_PLL,
+	DDR3A_PLL,
+	DDR3B_PLL,
+};
+#define MAIN_PLL CORE_PLL
+
+/* PLL configuration data */
+struct pll_init_data {
+	int pll;
+	int pll_m;		/* PLL Multiplier */
+	int pll_d;		/* PLL divider */
+	int pll_od;		/* PLL output divider    */
+};
+
+#define CORE_PLL_799	{CORE_PLL,	13,	1,	2}
+#define CORE_PLL_983	{CORE_PLL,	16,	1,	2}
+#define CORE_PLL_1167	{CORE_PLL,	19,	1,	2}
+#define CORE_PLL_1228	{CORE_PLL,	20,	1,	2}
+#define PASS_PLL_1228	{PASS_PLL,	20,	1,	2}
+#define PASS_PLL_983	{PASS_PLL,	16,	1,	2}
+#define PASS_PLL_1050	{PASS_PLL,	205,    12,	2}
+#define TETRIS_PLL_500  {TETRIS_PLL,	8,	1,	2}
+#define TETRIS_PLL_750  {TETRIS_PLL,	12,	1,	2}
+#define TETRIS_PLL_687  {TETRIS_PLL,	11,	1,	2}
+#define TETRIS_PLL_625  {TETRIS_PLL,	10,	1,	2}
+#define TETRIS_PLL_812  {TETRIS_PLL,	13,	1,	2}
+#define TETRIS_PLL_875  {TETRIS_PLL,	14,	1,	2}
+#define TETRIS_PLL_1188 {TETRIS_PLL,	19,	2,	1}
+#define TETRIS_PLL_1200 {TETRIS_PLL,	48,	5,	1}
+#define TETRIS_PLL_1375 {TETRIS_PLL,	22,	2,	1}
+#define TETRIS_PLL_1400 {TETRIS_PLL,	56,	5,	1}
+#define DDR3_PLL_200(x)	{DDR3##x##_PLL,	4,	1,	2}
+#define DDR3_PLL_400(x)	{DDR3##x##_PLL,	16,	1,	4}
+#define DDR3_PLL_800(x)	{DDR3##x##_PLL,	16,	1,	2}
+#define DDR3_PLL_333(x)	{DDR3##x##_PLL,	20,	1,	6}
+
+void init_plls(int num_pll, struct pll_init_data *config);
+void init_pll(const struct pll_init_data *data);
+unsigned long clk_get_rate(unsigned int clk);
+unsigned long clk_round_rate(unsigned int clk, unsigned long hz);
+int clk_set_rate(unsigned int clk, unsigned long hz);
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h
new file mode 100644
index 0000000..324501b
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock.h
@@ -0,0 +1,17 @@
+/*
+ * keystone2: common clock header file
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/clock-k2hk.h>
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/clock_defs.h b/arch/arm/include/asm/arch-keystone/clock_defs.h
new file mode 100644
index 0000000..61b6b62
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/clock_defs.h
@@ -0,0 +1,121 @@
+/*
+ * keystone2: common pll clock definitions
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _CLOCK_DEFS_H_
+#define _CLOCK_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+#define BIT(x)			(1 << (x))
+
+/* PLL Control Registers */
+struct pllctl_regs {
+	u32	ctl;		/* 00 */
+	u32	ocsel;		/* 04 */
+	u32	secctl;		/* 08 */
+	u32	__pad0;
+	u32	mult;		/* 10 */
+	u32	prediv;		/* 14 */
+	u32	div1;		/* 18 */
+	u32	div2;		/* 1c */
+	u32	div3;		/* 20 */
+	u32	oscdiv1;	/* 24 */
+	u32	__pad1;		/* 28 */
+	u32	bpdiv;		/* 2c */
+	u32	wakeup;		/* 30 */
+	u32	__pad2;
+	u32	cmd;		/* 38 */
+	u32	stat;		/* 3c */
+	u32	alnctl;		/* 40 */
+	u32	dchange;	/* 44 */
+	u32	cken;		/* 48 */
+	u32	ckstat;		/* 4c */
+	u32	systat;		/* 50 */
+	u32	ckctl;		/* 54 */
+	u32	__pad3[2];
+	u32	div4;		/* 60 */
+	u32	div5;		/* 64 */
+	u32	div6;		/* 68 */
+	u32	div7;		/* 6c */
+	u32	div8;		/* 70 */
+	u32	div9;		/* 74 */
+	u32	div10;		/* 78 */
+	u32	div11;		/* 7c */
+	u32	div12;		/* 80 */
+};
+
+static struct pllctl_regs *pllctl_regs[] = {
+	(struct pllctl_regs *)(CLOCK_BASE + 0x100)
+};
+
+#define pllctl_reg(pll, reg)		(&(pllctl_regs[pll]->reg))
+#define pllctl_reg_read(pll, reg)	__raw_readl(pllctl_reg(pll, reg))
+#define pllctl_reg_write(pll, reg, val)	__raw_writel(val, pllctl_reg(pll, reg))
+
+#define pllctl_reg_rmw(pll, reg, mask, val)			\
+	pllctl_reg_write(pll, reg,				\
+		(pllctl_reg_read(pll, reg) & ~(mask)) | val)
+
+#define pllctl_reg_setbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, 0, mask)
+
+#define pllctl_reg_clrbits(pll, reg, mask)			\
+	pllctl_reg_rmw(pll, reg, mask, 0)
+
+#define reg_rmw(reg, mask, val) \
+	__raw_writel((__raw_readl((reg)) & ~(mask)) | ((val) & (mask)) , \
+		     (reg));
+
+#define reg_setbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) | (bits)) , (reg));
+
+#define reg_clrbits(reg, bits)	\
+	__raw_writel((__raw_readl(reg) & ~(bits)) , (reg));
+
+#define pll0div_read(N) ((pllctl_reg_read(CORE_PLL, div##N) & 0xff) + 1)
+
+/* PLLCTL Bits */
+#define PLLCTL_BYPASS		BIT(23)
+#define PLL_PLLRST		BIT(14)
+#define PLLCTL_PAPLL		BIT(13)
+#define PLLCTL_CLKMODE		BIT(8)
+#define PLLCTL_PLLSELB		BIT(7)
+#define PLLCTL_ENSAT		BIT(6)
+#define PLLCTL_PLLENSRC		BIT(5)
+#define PLLCTL_PLLDIS		BIT(4)
+#define PLLCTL_PLLRST		BIT(3)
+#define PLLCTL_PLLPWRDN		BIT(1)
+#define PLLCTL_PLLEN		BIT(0)
+#define PLLSTAT_GO		BIT(0)
+
+#define MAIN_ENSAT_OFFSET	6
+
+#define PLLDIV_ENABLE		BIT(15)
+
+#define PLL_DIV_MASK		0x3f
+#define PLL_MULT_MASK		0x1fff
+#define PLL_MULT_SHIFT		6
+#define PLLM_MULT_HI_MASK	0x7f
+#define PLLM_MULT_HI_SHIFT	12
+#define PLLM_MULT_HI_SMASK	(PLLM_MULT_HI_MASK << PLLM_MULT_HI_SHIFT)
+#define PLLM_MULT_LO_MASK	0x3f
+#define PLL_CLKOD_MASK		0xf
+#define PLL_CLKOD_SHIFT		19
+#define PLL_CLKOD_SMASK		(PLL_CLKOD_MASK << PLL_CLKOD_SHIFT)
+#define PLL_BWADJ_LO_MASK	0xff
+#define PLL_BWADJ_LO_SHIFT	24
+#define PLL_BWADJ_LO_SMASK	(PLL_BWADJ_LO_MASK << PLL_BWADJ_LO_SHIFT)
+#define PLL_BWADJ_HI_MASK	0xf
+
+#define PLLM_RATIO_DIV1		(PLLDIV_ENABLE | 0)
+#define PLLM_RATIO_DIV2		(PLLDIV_ENABLE | 0)
+#define PLLM_RATIO_DIV3		(PLLDIV_ENABLE | 1)
+#define PLLM_RATIO_DIV4		(PLLDIV_ENABLE | 4)
+#define PLLM_RATIO_DIV5		(PLLDIV_ENABLE | 17)
+
+#endif  /* _CLOCK_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/emif_defs.h b/arch/arm/include/asm/arch-keystone/emif_defs.h
new file mode 100644
index 0000000..4e88ae6
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emif_defs.h
@@ -0,0 +1,73 @@
+/*
+ * emif definitions to re-use davinci emif driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _EMIF_DEFS_H_
+#define _EMIF_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+struct davinci_emif_regs {
+	u_int32_t	ercsr;
+	u_int32_t	awccr;
+	u_int32_t	sdbcr;
+	u_int32_t	sdrcr;
+	u_int32_t	abncr[4];
+	u_int32_t	sdtimr;
+	u_int32_t	ddrsr;
+	u_int32_t	ddrphycr;
+	u_int32_t	ddrphysr;
+	u_int32_t	totar;
+	u_int32_t	totactr;
+	u_int32_t	ddrphyid_rev;
+	u_int32_t	sdsretr;
+	u_int32_t	eirr;
+	u_int32_t	eimr;
+	u_int32_t	eimsr;
+	u_int32_t	eimcr;
+	u_int32_t	ioctrlr;
+	u_int32_t	iostatr;
+	u_int32_t	rsvd0;
+	u_int32_t	one_nand_cr;
+	u_int32_t	nandfcr;
+	u_int32_t	nandfsr;
+	u_int32_t	rsvd1[2];
+	u_int32_t	nandfecc[4];
+	u_int32_t	rsvd2[15];
+	u_int32_t	nand4biteccload;
+	u_int32_t	nand4bitecc[4];
+	u_int32_t	nanderradd1;
+	u_int32_t	nanderradd2;
+	u_int32_t	nanderrval1;
+	u_int32_t	nanderrval2;
+};
+
+#define davinci_emif_regs \
+	((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE)
+
+#define DAVINCI_NANDFCR_NAND_ENABLE(n)			(1 << ((n) - 2))
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK		(3 << 4)
+#define DAVINCI_NANDFCR_4BIT_ECC_SEL(n)			(((n) - 2) << 4)
+#define DAVINCI_NANDFCR_1BIT_ECC_START(n)		(1 << (8 + ((n) - 2)))
+#define DAVINCI_NANDFCR_4BIT_ECC_START			(1 << 12)
+#define DAVINCI_NANDFCR_4BIT_CALC_START			(1 << 13)
+
+/* Chip Select setup */
+#define DAVINCI_ABCR_STROBE_SELECT			(1 << 31)
+#define DAVINCI_ABCR_EXT_WAIT				(1 << 30)
+#define DAVINCI_ABCR_WSETUP(n)				((n) << 26)
+#define DAVINCI_ABCR_WSTROBE(n)				((n) << 20)
+#define DAVINCI_ABCR_WHOLD(n)				((n) << 17)
+#define DAVINCI_ABCR_RSETUP(n)				((n) << 13)
+#define DAVINCI_ABCR_RSTROBE(n)				((n) << 7)
+#define DAVINCI_ABCR_RHOLD(n)				((n) << 4)
+#define DAVINCI_ABCR_TA(n)				((n) << 2)
+#define DAVINCI_ABCR_ASIZE_16BIT			1
+#define DAVINCI_ABCR_ASIZE_8BIT				0
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
new file mode 100644
index 0000000..034b655
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
@@ -0,0 +1,145 @@
+/*
+ * K2HK: SoC definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_K2HK_H
+#define __ASM_ARCH_HARDWARE_K2HK_H
+
+#define K2HK_ASYNC_EMIF_CNTRL_BASE	0x21000a00
+#define DAVINCI_ASYNC_EMIF_CNTRL_BASE	K2HK_ASYNC_EMIF_CNTRL_BASE
+#define K2HK_ASYNC_EMIF_DATA_CE0_BASE	0x30000000
+#define K2HK_ASYNC_EMIF_DATA_CE1_BASE	0x34000000
+#define K2HK_ASYNC_EMIF_DATA_CE2_BASE	0x38000000
+#define K2HK_ASYNC_EMIF_DATA_CE3_BASE	0x3c000000
+
+#define K2HK_PLL_CNTRL_BASE		0x02310000
+#define CLOCK_BASE			K2HK_PLL_CNTRL_BASE
+#define K2HK_PSC_BASE			0x02350000
+#define KS2_DEVICE_STATE_CTRL_BASE	0x02620000
+#define JTAG_ID_REG			(KS2_DEVICE_STATE_CTRL_BASE + 0x18)
+#define K2HK_DEVSTAT			(KS2_DEVICE_STATE_CTRL_BASE + 0x20)
+
+#define K2HK_MISC_CTRL			(KS2_DEVICE_STATE_CTRL_BASE + 0xc7c)
+
+#define ARM_PLL_EN			BIT(13)
+
+#define K2HK_SPI0_BASE			0x21000400
+#define K2HK_SPI1_BASE			0x21000600
+#define K2HK_SPI2_BASE			0x21000800
+#define K2HK_SPI_BASE			K2HK_SPI0_BASE
+
+/* Chip configuration unlock codes and registers */
+#define KEYSTONE_KICK0			(KS2_DEVICE_STATE_CTRL_BASE+0x38)
+#define KEYSTONE_KICK1			(KS2_DEVICE_STATE_CTRL_BASE+0x3c)
+#define KEYSTONE_KICK0_MAGIC		0x83e70b13
+#define KEYSTONE_KICK1_MAGIC		0x95a4f1e0
+
+/* PA SS Registers */
+#define KS2_PASS_BASE			0x02000000
+
+/* PLL control registers */
+#define K2HK_MAINPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x350)
+#define K2HK_MAINPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x354)
+#define K2HK_PASSPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x358)
+#define K2HK_PASSPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x35C)
+#define K2HK_DDR3APLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x360)
+#define K2HK_DDR3APLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x364)
+#define K2HK_DDR3BPLLCTL0		(KS2_DEVICE_STATE_CTRL_BASE+0x368)
+#define K2HK_DDR3BPLLCTL1		(KS2_DEVICE_STATE_CTRL_BASE+0x36C)
+#define K2HK_ARMPLLCTL0			(KS2_DEVICE_STATE_CTRL_BASE+0x370)
+#define K2HK_ARMPLLCTL1			(KS2_DEVICE_STATE_CTRL_BASE+0x374)
+
+/* Power and Sleep Controller (PSC) Domains */
+#define K2HK_LPSC_MOD			0
+#define K2HK_LPSC_DUMMY1		1
+#define K2HK_LPSC_USB			2
+#define K2HK_LPSC_EMIF25_SPI		3
+#define K2HK_LPSC_TSIP			4
+#define K2HK_LPSC_DEBUGSS_TRC		5
+#define K2HK_LPSC_TETB_TRC		6
+#define K2HK_LPSC_PKTPROC		7
+#define KS2_LPSC_PA			K2HK_LPSC_PKTPROC
+#define K2HK_LPSC_SGMII			8
+#define KS2_LPSC_CPGMAC			K2HK_LPSC_SGMII
+#define K2HK_LPSC_CRYPTO		9
+#define K2HK_LPSC_PCIE			10
+#define K2HK_LPSC_SRIO			11
+#define K2HK_LPSC_VUSR0			12
+#define K2HK_LPSC_CHIP_SRSS		13
+#define K2HK_LPSC_MSMC			14
+#define K2HK_LPSC_GEM_0			15
+#define K2HK_LPSC_GEM_1			16
+#define K2HK_LPSC_GEM_2			17
+#define K2HK_LPSC_GEM_3			18
+#define K2HK_LPSC_GEM_4			19
+#define K2HK_LPSC_GEM_5			20
+#define K2HK_LPSC_GEM_6			21
+#define K2HK_LPSC_GEM_7			22
+#define K2HK_LPSC_EMIF4F_DDR3A		23
+#define K2HK_LPSC_EMIF4F_DDR3B		24
+#define K2HK_LPSC_TAC			25
+#define K2HK_LPSC_RAC			26
+#define K2HK_LPSC_RAC_1			27
+#define K2HK_LPSC_FFTC_A		28
+#define K2HK_LPSC_FFTC_B		29
+#define K2HK_LPSC_FFTC_C		30
+#define K2HK_LPSC_FFTC_D		31
+#define K2HK_LPSC_FFTC_E		32
+#define K2HK_LPSC_FFTC_F		33
+#define K2HK_LPSC_AI2			34
+#define K2HK_LPSC_TCP3D_0		35
+#define K2HK_LPSC_TCP3D_1		36
+#define K2HK_LPSC_TCP3D_2		37
+#define K2HK_LPSC_TCP3D_3		38
+#define K2HK_LPSC_VCP2X4_A		39
+#define K2HK_LPSC_CP2X4_B		40
+#define K2HK_LPSC_VCP2X4_C		41
+#define K2HK_LPSC_VCP2X4_D		42
+#define K2HK_LPSC_VCP2X4_E		43
+#define K2HK_LPSC_VCP2X4_F		44
+#define K2HK_LPSC_VCP2X4_G		45
+#define K2HK_LPSC_VCP2X4_H		46
+#define K2HK_LPSC_BCP			47
+#define K2HK_LPSC_DXB			48
+#define K2HK_LPSC_VUSR1			49
+#define K2HK_LPSC_XGE			50
+#define K2HK_LPSC_ARM_SREFLEX		51
+#define K2HK_LPSC_TETRIS		52
+
+#define K2HK_UART0_BASE			0x02530c00
+
+/* DDR3A definitions */
+#define K2HK_DDR3A_EMIF_CTRL_BASE	0x21010000
+#define K2HK_DDR3A_EMIF_DATA_BASE	0x80000000
+#define K2HK_DDR3A_DDRPHYC		0x02329000
+/* DDR3B definitions */
+#define K2HK_DDR3B_EMIF_CTRL_BASE	0x21020000
+#define K2HK_DDR3B_EMIF_DATA_BASE	0x60000000
+#define K2HK_DDR3B_DDRPHYC		0x02328000
+
+/* Queue manager */
+#define DEVICE_QM_MANAGER_BASE		0x02a02000
+#define DEVICE_QM_DESC_SETUP_BASE	0x02a03000
+#define DEVICE_QM_MANAGER_QUEUES_BASE	0x02a80000
+#define DEVICE_QM_MANAGER_Q_PROXY_BASE	0x02ac0000
+#define DEVICE_QM_QUEUE_STATUS_BASE	0x02a40000
+#define DEVICE_QM_NUM_LINKRAMS		2
+#define DEVICE_QM_NUM_MEMREGIONS	20
+
+#define DEVICE_PA_CDMA_GLOBAL_CFG_BASE	0x02004000
+#define DEVICE_PA_CDMA_TX_CHAN_CFG_BASE	0x02004400
+#define DEVICE_PA_CDMA_RX_CHAN_CFG_BASE	0x02004800
+#define DEVICE_PA_CDMA_RX_FLOW_CFG_BASE	0x02005000
+
+#define DEVICE_PA_CDMA_RX_NUM_CHANNELS	24
+#define DEVICE_PA_CDMA_RX_NUM_FLOWS	32
+#define DEVICE_PA_CDMA_TX_NUM_CHANNELS	9
+
+/* MSMC control */
+#define K2HK_MSMC_CTRL_BASE		0x0bc00000
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h
new file mode 100644
index 0000000..a72686d
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -0,0 +1,175 @@
+/*
+ * Keystone2: Common SoC definitions, structures etc.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <config.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/sizes.h>
+#include <asm/io.h>
+
+#define	REG(addr)	(*(volatile unsigned int *)(addr))
+#define REG_P(addr)	((volatile unsigned int *)(addr))
+
+typedef volatile unsigned int	dv_reg;
+typedef volatile unsigned int	*dv_reg_p;
+
+#define ASYNC_EMIF_NUM_CS		4
+#define ASYNC_EMIF_MODE_NOR		0
+#define ASYNC_EMIF_MODE_NAND		1
+#define ASYNC_EMIF_MODE_ONENAND		2
+#define ASYNC_EMIF_PRESERVE		-1
+
+struct async_emif_config {
+	unsigned mode;
+	unsigned select_strobe;
+	unsigned extend_wait;
+	unsigned wr_setup;
+	unsigned wr_strobe;
+	unsigned wr_hold;
+	unsigned rd_setup;
+	unsigned rd_strobe;
+	unsigned rd_hold;
+	unsigned turn_around;
+	enum {
+		ASYNC_EMIF_8	= 0,
+		ASYNC_EMIF_16	= 1,
+		ASYNC_EMIF_32	= 2,
+	} width;
+};
+
+void init_async_emif(int num_cs, struct async_emif_config *config);
+
+struct ddr3_phy_config {
+	unsigned int pllcr;
+	unsigned int pgcr1_mask;
+	unsigned int pgcr1_val;
+	unsigned int ptr0;
+	unsigned int ptr1;
+	unsigned int ptr2;
+	unsigned int ptr3;
+	unsigned int ptr4;
+	unsigned int dcr_mask;
+	unsigned int dcr_val;
+	unsigned int dtpr0;
+	unsigned int dtpr1;
+	unsigned int dtpr2;
+	unsigned int mr0;
+	unsigned int mr1;
+	unsigned int mr2;
+	unsigned int dtcr;
+	unsigned int pgcr2;
+	unsigned int zq0cr1;
+	unsigned int zq1cr1;
+	unsigned int zq2cr1;
+	unsigned int pir_v1;
+	unsigned int pir_v2;
+};
+
+struct ddr3_emif_config {
+	unsigned int sdcfg;
+	unsigned int sdtim1;
+	unsigned int sdtim2;
+	unsigned int sdtim3;
+	unsigned int sdtim4;
+	unsigned int zqcfg;
+	unsigned int sdrfc;
+};
+
+#endif
+
+#define		BIT(x)	(1 << (x))
+
+#define KS2_DDRPHY_PIR_OFFSET		0x04
+#define KS2_DDRPHY_PGCR0_OFFSET		0x08
+#define KS2_DDRPHY_PGCR1_OFFSET		0x0C
+#define KS2_DDRPHY_PGSR0_OFFSET		0x10
+#define KS2_DDRPHY_PGSR1_OFFSET		0x14
+#define KS2_DDRPHY_PLLCR_OFFSET		0x18
+#define KS2_DDRPHY_PTR0_OFFSET		0x1C
+#define KS2_DDRPHY_PTR1_OFFSET		0x20
+#define KS2_DDRPHY_PTR2_OFFSET		0x24
+#define KS2_DDRPHY_PTR3_OFFSET		0x28
+#define KS2_DDRPHY_PTR4_OFFSET		0x2C
+#define KS2_DDRPHY_DCR_OFFSET		0x44
+
+#define KS2_DDRPHY_DTPR0_OFFSET		0x48
+#define KS2_DDRPHY_DTPR1_OFFSET		0x4C
+#define KS2_DDRPHY_DTPR2_OFFSET		0x50
+
+#define KS2_DDRPHY_MR0_OFFSET		0x54
+#define KS2_DDRPHY_MR1_OFFSET		0x58
+#define KS2_DDRPHY_MR2_OFFSET		0x5C
+#define KS2_DDRPHY_DTCR_OFFSET		0x68
+#define KS2_DDRPHY_PGCR2_OFFSET		0x8C
+
+#define KS2_DDRPHY_ZQ0CR1_OFFSET	0x184
+#define KS2_DDRPHY_ZQ1CR1_OFFSET	0x194
+#define KS2_DDRPHY_ZQ2CR1_OFFSET	0x1A4
+#define KS2_DDRPHY_ZQ3CR1_OFFSET	0x1B4
+
+#define KS2_DDRPHY_DATX8_8_OFFSET	0x3C0
+
+#define IODDRM_MASK			0x00000180
+#define ZCKSEL_MASK			0x01800000
+#define CL_MASK				0x00000072
+#define WR_MASK				0x00000E00
+#define BL_MASK				0x00000003
+#define RRMODE_MASK			0x00040000
+#define UDIMM_MASK			0x20000000
+#define BYTEMASK_MASK			0x0003FC00
+#define MPRDQ_MASK			0x00000080
+#define PDQ_MASK			0x00000070
+#define NOSRA_MASK			0x08000000
+#define ECC_MASK			0x00000001
+
+#define KS2_DDR3_MIDR_OFFSET		0x00
+#define KS2_DDR3_STATUS_OFFSET		0x04
+#define KS2_DDR3_SDCFG_OFFSET		0x08
+#define KS2_DDR3_SDRFC_OFFSET		0x10
+#define KS2_DDR3_SDTIM1_OFFSET		0x18
+#define KS2_DDR3_SDTIM2_OFFSET		0x1C
+#define KS2_DDR3_SDTIM3_OFFSET		0x20
+#define KS2_DDR3_SDTIM4_OFFSET		0x28
+#define KS2_DDR3_PMCTL_OFFSET		0x38
+#define KS2_DDR3_ZQCFG_OFFSET		0xC8
+
+#ifdef CONFIG_SOC_K2HK
+#include <asm/arch/hardware-k2hk.h>
+#endif
+
+#ifndef __ASSEMBLY__
+static inline int cpu_is_k2hk(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int part_no	= (jtag_id >> 12) & 0xffff;
+
+	return ((part_no == 0xb981) ? 1 : 0);
+}
+
+static inline int cpu_revision(void)
+{
+	unsigned int jtag_id	= __raw_readl(JTAG_ID_REG);
+	unsigned int rev	= (jtag_id >> 28) & 0xf;
+
+	return rev;
+}
+
+void share_all_segments(int priv_id);
+int cpu_to_bus(u32 *ptr, u32 length);
+void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg);
+void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg);
+void init_ddr3(void);
+void sdelay(unsigned long);
+
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/i2c_defs.h b/arch/arm/include/asm/arch-keystone/i2c_defs.h
new file mode 100644
index 0000000..d425652
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/i2c_defs.h
@@ -0,0 +1,17 @@
+/*
+ * keystone: i2c driver definitions
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _I2C_DEFS_H_
+#define _I2C_DEFS_H_
+
+#define I2C0_BASE		0x02530000
+#define I2C1_BASE		0x02530400
+#define I2C2_BASE		0x02530800
+#define I2C_BASE		I2C0_BASE
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/nand_defs.h b/arch/arm/include/asm/arch-keystone/nand_defs.h
new file mode 100644
index 0000000..6d6f846
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/nand_defs.h
@@ -0,0 +1,25 @@
+/*
+ * nand driver definitions to re-use davinci nand driver on Keystone2
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _NAND_DEFS_H_
+#define _NAND_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <linux/mtd/nand.h>
+
+#define	MASK_CLE	0x4000
+#define	MASK_ALE	0x2000
+
+#define NAND_READ_START		0x00
+#define NAND_READ_END		0x30
+#define NAND_STATUS		0x70
+
+extern void davinci_nand_init(struct nand_chip *nand);
+
+#endif
diff --git a/arch/arm/include/asm/arch-keystone/psc_defs.h b/arch/arm/include/asm/arch-keystone/psc_defs.h
new file mode 100644
index 0000000..e0095d9
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/psc_defs.h
@@ -0,0 +1,90 @@
+/*
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#ifndef _PSC_DEFS_H_
+#define _PSC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+
+/*
+ * FILE PURPOSE: Local Power Sleep Controller definitions
+ *
+ * FILE NAME: psc_defs.h
+ *
+ * DESCRIPTION: Provides local definitions for the power saver controller
+ *
+ */
+
+/* Register offsets */
+#define PSC_REG_PTCMD		0x120
+#define PSC_REG_PSTAT	        0x128
+#define PSC_REG_PDSTAT(x)	(0x200 + (4*(x)))
+#define PSC_REG_PDCTL(x)	(0x300 + (4*(x)))
+#define PSC_REG_MDCFG(x)	(0x600 + (4*(x)))
+#define PSC_REG_MDSTAT(x)	(0x800 + (4*(x)))
+#define PSC_REG_MDCTL(x)	(0xa00 + (4*(x)))
+
+#define BOOTBITMASK(x, y)	((((((u32)1 << (((u32)x)-((u32)y)+(u32)1)) - \
+				  (u32)1)) << ((u32)y)))
+
+#define BOOT_READ_BITFIELD(z, x, y)	(((u32)z) & BOOTBITMASK(x, y)) >> (y)
+#define BOOT_SET_BITFIELD(z, f, x, y)	(((u32)z) & ~BOOTBITMASK(x, y)) | \
+					 ((((u32)f) << (y)) & BOOTBITMASK(x, y))
+
+/* PDCTL */
+#define PSC_REG_PDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 0, 0)
+#define PSC_REG_PDCTL_SET_PDMODE(x, y)	BOOT_SET_BITFIELD((x), (y), 15, 12)
+
+/* PDSTAT */
+#define PSC_REG_PDSTAT_GET_STATE(x)	BOOT_READ_BITFIELD((x), 4, 0)
+
+/* MDCFG */
+#define PSC_REG_MDCFG_GET_PD(x)		BOOT_READ_BITFIELD((x), 20, 16)
+#define PSC_REG_MDCFG_GET_RESET_ISO(x)	BOOT_READ_BITFIELD((x), 14, 14)
+
+/* MDCTL */
+#define PSC_REG_MDCTL_SET_NEXT(x, y)	BOOT_SET_BITFIELD((x), (y), 4, 0)
+#define PSC_REG_MDCTL_SET_LRSTZ(x, y)	BOOT_SET_BITFIELD((x), (y), 8, 8)
+#define PSC_REG_MDCTL_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDCTL_SET_RESET_ISO(x, y)	BOOT_SET_BITFIELD((x), (y), \
+								  12, 12)
+
+/* MDSTAT */
+#define PSC_REG_MDSTAT_GET_STATUS(x)	BOOT_READ_BITFIELD((x), 5, 0)
+#define PSC_REG_MDSTAT_GET_LRSTZ(x)	BOOT_READ_BITFIELD((x), 8, 8)
+#define PSC_REG_MDSTAT_GET_LRSTDONE(x)	BOOT_READ_BITFIELD((x), 9, 9)
+
+/* PDCTL states */
+#define PSC_REG_VAL_PDCTL_NEXT_ON		1
+#define PSC_REG_VAL_PDCTL_NEXT_OFF		0
+
+#define PSC_REG_VAL_PDCTL_PDMODE_SLEEP		0
+
+/* MDCTL states */
+#define PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE	0
+#define PSC_REG_VAL_MDCTL_NEXT_OFF		2
+#define PSC_REG_VAL_MDCTL_NEXT_ON		3
+
+/* MDSTAT states */
+#define PSC_REG_VAL_MDSTAT_STATE_ON		3
+#define PSC_REG_VAL_MDSTAT_STATE_ENABLE_IN_PROG	0x24
+#define PSC_REG_VAL_MDSTAT_STATE_OFF		2
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG1	0x20
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG2	0x21
+#define PSC_REG_VAL_MDSTAT_STATE_DISABLE_IN_PROG3	0x22
+
+/*
+ * Timeout limit on checking PTSTAT. This is the number of times the
+ * wait function will be called before giving up.
+ */
+#define PSC_PTSTAT_TIMEOUT_LIMIT    100
+
+u32 psc_get_domain_num(u32 mod_num);
+int psc_enable_module(u32 mod_num);
+int psc_disable_module(u32 mod_num);
+int psc_disable_domain(u32 domain_num);
+
+#endif /* _PSC_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-keystone/spl.h b/arch/arm/include/asm/arch-keystone/spl.h
new file mode 100644
index 0000000..eb0b3ed
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/spl.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2012-2014
+ * Texas Instruments, <www.ti.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#ifndef	_ASM_ARCH_SPL_H_
+#define	_ASM_SPL_H_
+
+#define BOOT_DEVICE_SPI		2
+
+#endif
diff --git a/board/ti/k2hk_evm/Makefile b/board/ti/k2hk_evm/Makefile
new file mode 100644
index 0000000..3645f2f
--- /dev/null
+++ b/board/ti/k2hk_evm/Makefile
@@ -0,0 +1,9 @@
+#
+# K2HK-EVM: board Makefile
+# (C) Copyright 2012-2014
+#     Texas Instruments Incorporated, <www.ti.com>
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= board.o
+obj-y	+= ddr3.o
diff --git a/board/ti/k2hk_evm/README b/board/ti/k2hk_evm/README
new file mode 100644
index 0000000..6ab660b
--- /dev/null
+++ b/board/ti/k2hk_evm/README
@@ -0,0 +1,56 @@
+U-Boot port for Texas Instruments XTCIEVMK2X
+============================================
+
+Author: Murali Karicheri <m-karicheri2@ti.com>
+
+This README has information on the u-boot port for XTCIEVMK2X EVM board.
+Documentation for this board can be found at
+  http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx
+
+The board is based on Texas Instruments Keystone2 family of SoCs : K2H, K2K.
+More details on these SoCs are available at company websites
+ K2K: http://www.ti.com/product/tci6638k2k
+ K2H: http://www.ti.com/product/tci6638k2h
+
+Board configuration:
+====================
+
+Some of the peripherals that are configured by u-boot are:-
+
+1. 2GB DDR3 (can support 8GB SO DIMM as well)
+2. 512M NAND (over ti emif16 bus)
+3. 6MB MSM SRAM (part of the SoC)
+4. two 1GBit Ethernet ports (SoC supports upto 4)
+5. two UART ports
+6. three i2c interfaces
+7. three spi interfaces (only 1 interface supported in driver)
+
+There are seperate PLLs to drive clocks to Tetris ARM and Peripherals.
+To bring up SMP Linux on this board, there is a boot monitor
+code that will be installed in MSMC SRAM. There is command available
+to install this image from u-boot.
+
+The port related files can be found at following folders
+ keystone2 SoC related files: arch/arm/cpu/armv7/keystone/
+ K2HK evm board files: board/ti/k2hk_evm/
+
+board configuration file: include/configs/k2hk_evm.h
+
+Supported boot modes:
+ - SPI NOR boot
+
+Supported image formats:-
+ - u-boot.bin: for loading and running u-boot.bin through Texas instruments
+               code composure studio (CCS)
+ - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot
+
+Build instructions:
+===================
+
+To build u-boot.bin
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
+
+To build u-boot-spi.gph
+  >make k2hk_evm_config
+  >make u-boot-spi.gph
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
new file mode 100644
index 0000000..14dc7e4
--- /dev/null
+++ b/board/ti/k2hk_evm/board.c
@@ -0,0 +1,236 @@
+/*
+ * K2HK EVM : Board initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <exports.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/nand_defs.h>
+#include <asm/arch/psc_defs.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 device_big_endian;
+
+unsigned int external_clk[ext_clk_count] = {
+	[sys_clk]	=	122880000,
+	[alt_core_clk]	=	125000000,
+	[pa_clk]	=	122880000,
+	[tetris_clk]	=	125000000,
+	[ddr3a_clk]	=	100000000,
+	[ddr3b_clk]	=	100000000,
+	[mcm_clk]	=	312500000,
+	[pcie_clk]	=	100000000,
+	[sgmii_srio_clk] =	156250000,
+	[xgmii_clk]	=	156250000,
+	[usb_clk]	=	100000000,
+	[rp1_clk]	=	123456789    /* TODO: cannot find
+						what is that */
+};
+
+static struct async_emif_config async_emif_config[ASYNC_EMIF_NUM_CS] = {
+	{			/* CS0 */
+		.mode		= ASYNC_EMIF_MODE_NAND,
+		.wr_setup	= 0xf,
+		.wr_strobe	= 0x3f,
+		.wr_hold	= 7,
+		.rd_setup	= 0xf,
+		.rd_strobe	= 0x3f,
+		.rd_hold	= 7,
+		.turn_around	= 3,
+		.width		= ASYNC_EMIF_8,
+	},
+
+};
+
+static struct pll_init_data pll_config[] = {
+	CORE_PLL_1228,
+	PASS_PLL_983,
+	TETRIS_PLL_1200,
+};
+
+int dram_init(void)
+{
+	init_ddr3();
+
+	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+				    CONFIG_MAX_RAM_BANK_SIZE);
+	init_async_emif(ARRAY_SIZE(async_emif_config), async_emif_config);
+	return 0;
+}
+
+/* Byte swap the 32-bit data if the device is BE */
+int cpu_to_bus(u32 *ptr, u32 length)
+{
+	u32 i;
+
+	if (device_big_endian)
+		for (i = 0; i < length; i++, ptr++)
+			*ptr = __swab32(*ptr);
+
+	return 0;
+}
+
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+int board_early_init_f(void)
+{
+	init_plls(ARRAY_SIZE(pll_config), pll_config);
+	return 0;
+}
+#endif
+
+int board_init(void)
+{
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	return 0;
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+#define K2_DDR3_START_ADDR 0x80000000
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	u64 start[2];
+	u64 size[2];
+	char name[32], *env, *endp;
+	int lpae, nodeoffset;
+	u32 ddr3a_size;
+	int nbanks;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	ddr3a_size = 0;
+	if (lpae) {
+		env = getenv("ddr3a_size");
+		if (env)
+			ddr3a_size = simple_strtol(env, NULL, 10);
+		if ((ddr3a_size != 8) && (ddr3a_size != 4))
+			ddr3a_size = 0;
+	}
+
+	nbanks = 1;
+	start[0] = bd->bi_dram[0].start;
+	size[0]  = bd->bi_dram[0].size;
+
+	/* adjust memory start address for LPAE */
+	if (lpae) {
+		start[0] -= K2_DDR3_START_ADDR;
+		start[0] += CONFIG_SYS_LPAE_SDRAM_BASE;
+	}
+
+	if ((size[0] == 0x80000000) && (ddr3a_size != 0)) {
+		size[1] = ((u64)ddr3a_size - 2) << 30;
+		start[1] = 0x880000000;
+		nbanks++;
+	}
+
+	/* reserve memory@start of bank */
+	sprintf(name, "mem_reserve_head");
+	env = getenv(name);
+	if (env) {
+		start[0] += ustrtoul(env, &endp, 0);
+		size[0] -= ustrtoul(env, &endp, 0);
+	}
+
+	sprintf(name, "mem_reserve");
+	env = getenv(name);
+	if (env)
+		size[0] -= ustrtoul(env, &endp, 0);
+
+	fdt_fixup_memory_banks(blob, start, size, nbanks);
+
+	/* Fix up the initrd */
+	if (lpae) {
+		u64 initrd_start, initrd_end;
+		u32 *prop1, *prop2;
+		int err;
+		nodeoffset = fdt_path_offset(blob, "/chosen");
+		if (nodeoffset >= 0) {
+			prop1 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-start", NULL);
+			prop2 = (u32 *)fdt_getprop(blob, nodeoffset,
+					    "linux,initrd-end", NULL);
+			if (prop1 && prop2) {
+				initrd_start = __be32_to_cpu(*prop1);
+				initrd_start -= K2_DDR3_START_ADDR;
+				initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_start = __cpu_to_be64(initrd_start);
+				initrd_end = __be32_to_cpu(*prop2);
+				initrd_end -= K2_DDR3_START_ADDR;
+				initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
+				initrd_end = __cpu_to_be64(initrd_end);
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-start");
+				if (err < 0)
+					printf("error deleting linux,initrd-start\n");
+
+				err = fdt_delprop(blob, nodeoffset,
+						  "linux,initrd-end");
+				if (err < 0)
+					printf("error deleting linux,initrd-end\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-start",
+						  &initrd_start,
+						  sizeof(initrd_start));
+				if (err < 0)
+					printf("error adding linux,initrd-start\n");
+
+				err = fdt_setprop(blob, nodeoffset,
+						  "linux,initrd-end",
+						  &initrd_end,
+						  sizeof(initrd_end));
+				if (err < 0)
+					printf("error adding linux,initrd-end\n");
+			}
+		}
+	}
+}
+
+void ft_board_setup_ex(void *blob, bd_t *bd)
+{
+	int	lpae;
+	char	*env;
+	u64	*reserve_start, size;
+
+	env = getenv("mem_lpae");
+	lpae = env && simple_strtol(env, NULL, 0);
+
+	if (lpae) {
+		/*
+		 * the initrd and other reserved memory areas are
+		 * embedded in in the DTB itslef. fix up these addresses
+		 * to 36 bit format
+		 */
+		reserve_start = (u64 *)((char *)blob +
+				       fdt_off_mem_rsvmap(blob));
+		while (1) {
+			*reserve_start = __cpu_to_be64(*reserve_start);
+			size = __cpu_to_be64(*(reserve_start + 1));
+			if (size) {
+				*reserve_start -= K2_DDR3_START_ADDR;
+				*reserve_start +=
+					CONFIG_SYS_LPAE_SDRAM_BASE;
+				*reserve_start =
+					__cpu_to_be64(*reserve_start);
+			} else {
+				break;
+			}
+			reserve_start += 2;
+		}
+	}
+}
+#endif
diff --git a/board/ti/k2hk_evm/ddr3.c b/board/ti/k2hk_evm/ddr3.c
new file mode 100644
index 0000000..973c35d
--- /dev/null
+++ b/board/ti/k2hk_evm/ddr3.c
@@ -0,0 +1,269 @@
+/*
+ * Keystone2: DDR3 initialization
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <i2c.h>
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1600_64A = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_64 = {
+	.sdcfg		= 0x6200CE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1600_32 = {
+	.pllcr		= 0x0001C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0D861A80ul,
+	.ptr4		= 0x0C827100ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0xA19DBB66ul,
+	.dtpr1		= 0x12868300ul,
+	.dtpr2		= 0x50035200ul,
+	.mr0		= 0x00001C70ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000018ul,
+	.dtcr		= 0x730035C7ul,
+	.pgcr2		= 0x00F07A12ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1600_32 = {
+	.sdcfg		= 0x6200DE6aul,
+	.sdtim1		= 0x16709C55ul,
+	.sdtim2		= 0x00001D4Aul,
+	.sdtim3		= 0x435DFF54ul,
+	.sdtim4		= 0x553F0CFFul,
+	.zqcfg		= 0x70073200ul,
+	.sdrfc		= 0x00001869ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64A = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_64 = {
+	.sdcfg		= 0x62008C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xF0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+static struct ddr3_phy_config ddr3phy_1333_32 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK |
+			   NOSRA_MASK | UDIMM_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27) | (1 << 29)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+
+static struct ddr3_emif_config ddr3_1333_32 = {
+	.sdcfg		= 0x62009C62ul,
+	.sdtim1		= 0x125C8044ul,
+	.sdtim2		= 0x00001D29ul,
+	.sdtim3		= 0x32CDFF43ul,
+	.sdtim4		= 0x543F0ADFul,
+	.zqcfg		= 0xf0073200ul,
+	.sdrfc		= 0x00001457ul,
+};
+
+/************************* *****************************/
+static struct ddr3_phy_config ddr3phy_1333_64 = {
+	.pllcr		= 0x0005C000ul,
+	.pgcr1_mask	= (IODDRM_MASK | ZCKSEL_MASK),
+	.pgcr1_val	= ((1 << 2) | (1 << 7) | (1 << 23)),
+	.ptr0		= 0x42C21590ul,
+	.ptr1		= 0xD05612C0ul,
+	.ptr2		= 0, /* not set in gel */
+	.ptr3		= 0x0B4515C2ul,
+	.ptr4		= 0x0A6E08B4ul,
+	.dcr_mask	= (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK),
+	.dcr_val	= ((1 << 10) | (1 << 27)),
+	.dtpr0		= 0x8558AA55ul,
+	.dtpr1		= 0x12857280ul,
+	.dtpr2		= 0x5002C200ul,
+	.mr0		= 0x00001A60ul,
+	.mr1		= 0x00000006ul,
+	.mr2		= 0x00000010ul,
+	.dtcr		= 0x710035C7ul,
+	.pgcr2		= 0x00F065B8ul,
+	.zq0cr1		= 0x0000005Dul,
+	.zq1cr1		= 0x0000005Bul,
+	.zq2cr1		= 0x0000005Bul,
+	.pir_v1		= 0x00000033ul,
+	.pir_v2		= 0x0000FF81ul,
+};
+/******************************************************/
+int get_dimm_params(char *dimm_name)
+{
+	u8 spd_params[256];
+	int ret;
+	int old_bus;
+
+	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	old_bus = i2c_get_bus_num();
+	i2c_set_bus_num(1);
+
+	ret = i2c_read(0x53, 0, 1, spd_params, 256);
+
+	i2c_set_bus_num(old_bus);
+
+	dimm_name[0] = '\0';
+
+	if (ret) {
+		puts("Cannot read DIMM params\n");
+		return 1;
+	}
+
+	/*
+	 * We need to convert spd data to dimm parameters
+	 * and to DDR3 EMIF and PHY regirsters values.
+	 * For now we just return DIMM type string value.
+	 * Caller may use this value to choose appropriate
+	 * a pre-set DDR3 configuration
+	 */
+
+	strncpy(dimm_name, (char *)&spd_params[0x80], 18);
+	dimm_name[18] = '\0';
+
+	return 0;
+}
+
+struct pll_init_data ddr3a_333 = DDR3_PLL_333(A);
+struct pll_init_data ddr3b_333 = DDR3_PLL_333(B);
+struct pll_init_data ddr3a_400 = DDR3_PLL_400(A);
+struct pll_init_data ddr3b_400 = DDR3_PLL_400(B);
+
+void init_ddr3(void)
+{
+	char dimm_name[32];
+
+	get_dimm_params(dimm_name);
+
+	printf("Detected SO-DIMM [%s]\n", dimm_name);
+
+	if (!strcmp(dimm_name, "18KSF1G72HZ-1G6E2 ")) {
+		init_pll(&ddr3a_400);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_64);
+			printf("DRAM:  Capacity 8 GiB (includes reported below)\n");
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_32);
+			printf("DRAM:  Capacity 4 GiB (includes reported below)\n");
+		}
+	} else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) {
+		init_pll(&ddr3a_333);
+		if (cpu_revision() > 0) {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_64A);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_64);
+		} else {
+			init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_32);
+			init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_32);
+		}
+	} else {
+		printf("Unknown SO-DIMM. Cannot configure DDR3\n");
+		while (1)
+			;
+	}
+
+	init_pll(&ddr3b_333);
+	init_ddrphy(K2HK_DDR3B_DDRPHYC, &ddr3phy_1333_64);
+	init_ddremif(K2HK_DDR3B_EMIF_CTRL_BASE, &ddr3_1333_64);
+}
+
diff --git a/boards.cfg b/boards.cfg
index a8336cc..1690315 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -362,6 +362,7 @@ Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_microzed			-
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm010			zynq_zc770:ZC770_XM010                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm012			zynq_zc770:ZC770_XM012                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
 Active  arm	    armv7	   zynq	       xilinx	       zynq	   	   zynq_zc770_xm013			zynq_zc770:ZC770_XM013                                                                                                            Michal Simek <monstr@monstr.eu>:Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
+Active  arm         armv7          keystone    ti              k2hk_evm            k2hk_evm                             -                                                                                                                                 Vitaly Andrianov <vitalya@ti.com>
 Active  arm         armv7:arm720t  tegra114    nvidia          dalmore             dalmore                              -                                                                                                                                 Tom Warren <twarren@nvidia.com>
 Active  arm         armv7:arm720t  tegra20     avionic-design  medcom-wide         medcom-wide                          -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
 Active  arm         armv7:arm720t  tegra20     avionic-design  plutux              plutux                               -                                                                                                                                 Alban Bedel <alban.bedel@avionic-design.de>
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index fbc37b2..8a13454 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -30,6 +30,11 @@
 #define serial_in(y)		readb(y)
 #endif
 
+#if defined(CONFIG_K2HK_EVM)
+#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE   0
+#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0))
+#endif
+
 #ifndef CONFIG_SYS_NS16550_IER
 #define CONFIG_SYS_NS16550_IER  0x00
 #endif /* CONFIG_SYS_NS16550_IER */
@@ -77,6 +82,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
 	/* /16 is proper to hit 115200 with 48MHz */
 	serial_out(0, &com_port->mdr1);
 #endif /* CONFIG_OMAP */
+#if defined(CONFIG_K2HK_EVM)
+	serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC);
+#endif
 }
 
 #ifndef CONFIG_NS16550_MIN_FUNCTIONS
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
new file mode 100644
index 0000000..985db8e
--- /dev/null
+++ b/include/configs/k2hk_evm.h
@@ -0,0 +1,221 @@
+/*
+ * Configuration header file for TI's k2hk-evm
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* Platform type */
+#define CONFIG_SOC_K2HK
+#define CONFIG_K2HK_EVM
+
+/* U-Boot Build Configuration */
+#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is a 2nd stage loader */
+#define CONFIG_SYS_NO_FLASH		/* that is, no *NOR* flash */
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_SYS_THUMB_BUILD
+
+/* SoC Configuration */
+#define CONFIG_ARMV7
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_SYS_ARCH_TIMER
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_TEXT_BASE		0x0c001000
+#define CONFIG_OF_LIBFDT		1
+#define CONFIG_OF_BOARD_SETUP
+#define CONFIG_SYS_DCACHE_OFF
+
+/* Memory Configuration */
+#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_LPAE_SDRAM_BASE	0x800000000
+#define CONFIG_MAX_RAM_BANK_SIZE	(2 << 30)	/* 2GB */
+#define CONFIG_STACKSIZE		(512 << 10)	/* 512 KiB */
+#define CONFIG_SYS_MALLOC_LEN		(1024 << 10)	/* 1 MiB */
+#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + 32 << 20)
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE -	\
+					 GENERATED_GBL_DATA_SIZE)
+
+/* SPL SPI Loader Configuration */
+#define CONFIG_SPL_TEXT_BASE		0x0c200000
+#define CONFIG_SPL_PAD_TO		65536
+#define CONFIG_SPL_MAX_SIZE		(CONFIG_SPL_PAD_TO - 8)
+#define CONFIG_SPL_BSS_START_ADDR	(CONFIG_SPL_TEXT_BASE +		\
+					 CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE		(32 * 1024)
+#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR +	\
+					 CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)
+#define CONFIG_SPL_STACK_SIZE		(8 * 1024)
+#define CONFIG_SPL_STACK		(CONFIG_SYS_SPL_MALLOC_START +	\
+					 CONFIG_SYS_SPL_MALLOC_SIZE +	\
+					 CONFIG_SPL_STACK_SIZE - 4)
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_BUS		0
+#define CONFIG_SPL_SPI_CS		0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS	CONFIG_SPL_PAD_TO
+#define CONFIG_SPL_FRAMEWORK
+
+/* UART Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_REG_SIZE	-4
+#define CONFIG_SYS_NS16550_COM1		K2HK_UART0_BASE
+#define CONFIG_SYS_NS16550_CLK		clk_get_rate(K2HK_CLK1_6)
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_CONS_INDEX		1
+#define CONFIG_BAUDRATE			115200
+
+/* SPI Configuration */
+#define CONFIG_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI_BASE		K2HK_SPI_BASE
+#define CONFIG_SYS_SPI_CLK		clk_get_rate(K2HK_LPSC_EMIF25_SPI)
+#define CONFIG_SF_DEFAULT_SPEED		30000000
+#define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
+
+/* I2C Configuration */
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0x10	/* SMBus host address */
+#define CONFIG_I2C_MULTI_BUS		1
+#define I2C_BUS_MAX			3
+
+/* EEPROM definitions */
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         2
+#define CONFIG_SYS_I2C_EEPROM_ADDR             0x50
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      6
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+
+/* NAND Configuration */
+#define CONFIG_NAND_DAVINCI
+#define CONFIG_SYS_NAND_CS		2
+#define CONFIG_SYS_NAND_USE_FLASH_BBT
+#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
+#define CONFIG_SYS_NAND_PAGE_2K
+
+#define CONFIG_SYS_NAND_LARGEPAGE
+#define CONFIG_SYS_NAND_BASE_LIST	{ 0x30000000, }
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_MAX_CHIPS	1
+#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
+#define CONFIG_ENV_SIZE			(256 << 10)	/* 256 KiB */
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET		0x100000
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define MTDIDS_DEFAULT			"nand0=davinci_nand.0"
+#define PART_BOOT			"1024k(bootloader)ro,"
+#define PART_PARAMS			"512k(params)ro,"
+#define PART_UBI			"-(ubifs)"
+#define MTDPARTS_DEFAULT		"mtdparts=davinci_nand.0:"	\
+					PART_BOOT PART_PARAMS PART_UBI
+
+/* U-Boot command configuration */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_EEPROM
+
+/* U-Boot general configuration */
+#define CONFIG_SYS_PROMPT		"K2HK EVM # "
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SYS_PBSIZE		2048
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_TIMESTAMP
+
+#define CONFIG_BOOTDELAY		3
+#define CONFIG_BOOTFILE			"uImage"
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"boot=ramfs\0"							\
+	"tftp_root=/\0"							\
+	"nfs_root=/export\0"						\
+	"mem_lpae=1\0"							\
+	"mem_reserve=512M\0"						\
+	"addr_fdt=0x87000000\0"						\
+	"addr_kern=0x88000000\0"					\
+	"addr_mon=0x0c5f0000\0"						\
+	"addr_uboot=0x87000000\0"					\
+	"addr_fs=0x82000000\0"						\
+	"addr_ubi=0x82000000\0"						\
+	"fdt_high=0xffffffff\0"						\
+	"run_mon=mon_install ${addr_mon}\0"				\
+	"run_kern=bootm ${addr_kern} - ${addr_fdt}\0"			\
+	"init_ubi=run args_all args_ubi; "				\
+		"ubi part ubifs; ubifsmount boot\0"			\
+	"get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0"		\
+	"get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0"		\
+	"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0"		\
+	"burn_uboot=sf probe; sf erase 0 0x100000; "			\
+		"sf write ${addr_uboot} 0 ${filesize}\0"		\
+	"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0"	\
+	"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "	\
+		"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0"	\
+	"burn_ubi=nand erase.part ubifs; "				\
+		"nand write ${addr_ubi} ubifs ${filesize}\0"		\
+	"init_ramfs=run args_all args_ramfs get_fs_ramfs\0"		\
+	"args_ramfs=setenv bootargs ${bootargs} earlyprintk "		\
+		"rdinit=/sbin/init rw root=/dev/ram0 "			\
+		"initrd=0x802000000,9M\0"				\
+	"mtdparts=mtdparts=davinci_nand.0:"				\
+		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
+#define CONFIG_BOOTCOMMAND						\
+	"run init_${boot} get_fdt_${boot} get_mon_${boot} "		\
+		"get_kern_${boot} run_mon run_kern"
+#define CONFIG_BOOTARGS							\
+
+/* Linux interfacing */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_SYS_BARGSIZE		1024
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x08000000)
+#define LINUX_BOOT_PARAM_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x100)
+
+#define CONFIG_SUPPORT_RAW_INITRD
+
+/* we may include files below only after all above definitions */
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#define CONFIG_SYS_HZ_CLOCK		clk_get_rate(K2HK_CLK1_6)
+
+#endif /* __CONFIG_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (7 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:12     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver Murali Karicheri
                     ` (4 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

Multicore navigator consists of Network Coprocessor (NetCP) and
Queue Manager sub system. More details on the hardware can
be obtained from the following links:-

Network Coprocessor: http://www.ti.com/lit/pdf/sprugz6
Multicore Navigator: http://www.ti.com/lit/pdf/sprugr9

Multicore navigator driver implements APIs to configure
the Queue Manager and NetCP Pkt DMA.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
---
 - Updated based on review comments
 arch/arm/cpu/armv7/keystone/Makefile              |    1 +
 arch/arm/cpu/armv7/keystone/keystone_nav.c        |  376 +++++++++++++++++++++
 arch/arm/include/asm/arch-keystone/keystone_nav.h |  193 +++++++++++
 3 files changed, 570 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c
 create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h

diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile
index 7924cfa..7d0374b 100644
--- a/arch/arm/cpu/armv7/keystone/Makefile
+++ b/arch/arm/cpu/armv7/keystone/Makefile
@@ -11,6 +11,7 @@ obj-y	+= psc.o
 obj-y	+= clock.o
 obj-y	+= cmd_clock.o
 obj-y	+= cmd_mon.o
+obj-y	+= keystone_nav.o
 obj-y	+= msmc.o
 obj-$(CONFIG_SPL_BUILD)	+= spl.o
 obj-y	+= ddr3.o
diff --git a/arch/arm/cpu/armv7/keystone/keystone_nav.c b/arch/arm/cpu/armv7/keystone/keystone_nav.c
new file mode 100644
index 0000000..39d6f99
--- /dev/null
+++ b/arch/arm/cpu/armv7/keystone/keystone_nav.c
@@ -0,0 +1,376 @@
+/*
+ * Multicore Navigator driver for TI Keystone 2 devices.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/keystone_nav.h>
+
+static int soc_type =
+#ifdef CONFIG_SOC_K2HK
+	k2hk;
+#endif
+
+struct qm_config k2hk_qm_memmap = {
+	.stat_cfg	= 0x02a40000,
+	.queue		= (struct qm_reg_queue *)0x02a80000,
+	.mngr_vbusm	= 0x23a80000,
+	.i_lram		= 0x00100000,
+	.proxy		= (struct qm_reg_queue *)0x02ac0000,
+	.status_ram	= 0x02a06000,
+	.mngr_cfg	= (struct qm_cfg_reg *)0x02a02000,
+	.intd_cfg	= 0x02a0c000,
+	.desc_mem	= (struct descr_mem_setup_reg *)0x02a03000,
+	.region_num	= 64,
+	.pdsp_cmd	= 0x02a20000,
+	.pdsp_ctl	= 0x02a0f000,
+	.pdsp_iram	= 0x02a10000,
+	.qpool_num	= 4000,
+};
+
+/*
+ * We are going to use only one type of descriptors - host packet
+ * descriptors. We staticaly allocate memory for them here
+ */
+struct qm_host_desc desc_pool[HDESC_NUM] __aligned(sizeof(struct qm_host_desc));
+
+static struct qm_config *qm_cfg;
+
+inline int num_of_desc_to_reg(int num_descr)
+{
+	int j, num;
+
+	for (j = 0, num = 32; j < 15; j++, num *= 2) {
+		if (num_descr <= num)
+			return j;
+	}
+
+	return 15;
+}
+
+static int _qm_init(struct qm_config *cfg)
+{
+	u32	j;
+
+	if (cfg == NULL)
+		return QM_ERR;
+
+	qm_cfg = cfg;
+
+	qm_cfg->mngr_cfg->link_ram_base0	= qm_cfg->i_lram;
+	qm_cfg->mngr_cfg->link_ram_size0	= HDESC_NUM * 8;
+	qm_cfg->mngr_cfg->link_ram_base1	= 0;
+	qm_cfg->mngr_cfg->link_ram_size1	= 0;
+	qm_cfg->mngr_cfg->link_ram_base2	= 0;
+
+	qm_cfg->desc_mem[0].base_addr = (u32)desc_pool;
+	qm_cfg->desc_mem[0].start_idx = 0;
+	qm_cfg->desc_mem[0].desc_reg_size =
+		(((sizeof(struct qm_host_desc) >> 4) - 1) << 16) |
+		num_of_desc_to_reg(HDESC_NUM);
+
+	memset(desc_pool, 0, sizeof(desc_pool));
+	for (j = 0; j < HDESC_NUM; j++)
+		qm_push(&desc_pool[j], qm_cfg->qpool_num);
+
+	return QM_OK;
+}
+
+int qm_init(void)
+{
+	switch (soc_type) {
+	case k2hk:
+		return _qm_init(&k2hk_qm_memmap);
+	}
+
+	return QM_ERR;
+}
+
+void qm_close(void)
+{
+	u32	j;
+
+	if (qm_cfg == NULL)
+		return;
+
+	queue_close(qm_cfg->qpool_num);
+
+	qm_cfg->mngr_cfg->link_ram_base0	= 0;
+	qm_cfg->mngr_cfg->link_ram_size0	= 0;
+	qm_cfg->mngr_cfg->link_ram_base1	= 0;
+	qm_cfg->mngr_cfg->link_ram_size1	= 0;
+	qm_cfg->mngr_cfg->link_ram_base2	= 0;
+
+	for (j = 0; j < qm_cfg->region_num; j++) {
+		qm_cfg->desc_mem[j].base_addr = 0;
+		qm_cfg->desc_mem[j].start_idx = 0;
+		qm_cfg->desc_mem[j].desc_reg_size = 0;
+	}
+
+	qm_cfg = NULL;
+}
+
+void qm_push(struct qm_host_desc *hd, u32 qnum)
+{
+	u32 regd;
+
+	if (!qm_cfg)
+		return;
+
+	cpu_to_bus((u32 *)hd, sizeof(struct qm_host_desc)/4);
+	regd = (u32)hd | ((sizeof(struct qm_host_desc) >> 4) - 1);
+	writel(regd, &qm_cfg->queue[qnum].ptr_size_thresh);
+}
+
+void qm_buff_push(struct qm_host_desc *hd, u32 qnum,
+		    void *buff_ptr, u32 buff_len)
+{
+	hd->orig_buff_len = buff_len;
+	hd->buff_len = buff_len;
+	hd->orig_buff_ptr = (u32)buff_ptr;
+	hd->buff_ptr = (u32)buff_ptr;
+	qm_push(hd, qnum);
+}
+
+struct qm_host_desc *qm_pop(u32 qnum)
+{
+	u32 uhd;
+
+	if (!qm_cfg)
+		return NULL;
+
+	uhd = readl(&qm_cfg->queue[qnum].ptr_size_thresh) & ~0xf;
+	if (uhd)
+		cpu_to_bus((u32 *)uhd, sizeof(struct qm_host_desc)/4);
+
+	return (struct qm_host_desc *)uhd;
+}
+
+struct qm_host_desc *qm_pop_from_free_pool(void)
+{
+	if (!qm_cfg)
+		return NULL;
+
+	return qm_pop(qm_cfg->qpool_num);
+}
+
+void queue_close(u32 qnum)
+{
+	struct qm_host_desc *hd;
+
+	while ((hd = qm_pop(qnum)))
+		;
+}
+
+/*
+ * DMA API
+ */
+
+struct pktdma_cfg k2hk_netcp_pktdma = {
+	.global		= (struct global_ctl_regs *)0x02004000,
+	.tx_ch		= (struct tx_chan_regs *)0x02004400,
+	.tx_ch_num	= 9,
+	.rx_ch		= (struct rx_chan_regs *)0x02004800,
+	.rx_ch_num	= 26,
+	.tx_sched	= (u32 *)0x02004c00,
+	.rx_flows	= (struct rx_flow_regs *)0x02005000,
+	.rx_flow_num	= 32,
+	.rx_free_q	= 4001,
+	.rx_rcv_q	= 4002,
+	.tx_snd_q	= 648,
+};
+
+struct pktdma_cfg *netcp;
+
+static int netcp_rx_disable(void)
+{
+	u32 j, v, k;
+
+	for (j = 0; j < netcp->rx_ch_num; j++) {
+		v = readl(&netcp->rx_ch[j].cfg_a);
+		if (!(v & CPDMA_CHAN_A_ENABLE))
+			continue;
+
+		writel(v | CPDMA_CHAN_A_TDOWN, &netcp->rx_ch[j].cfg_a);
+		for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
+			udelay(100);
+			v = readl(&netcp->rx_ch[j].cfg_a);
+			if (!(v & CPDMA_CHAN_A_ENABLE))
+				continue;
+		}
+		/* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */
+	}
+
+	/* Clear all of the flow registers */
+	for (j = 0; j < netcp->rx_flow_num; j++) {
+		writel(0, &netcp->rx_flows[j].control);
+		writel(0, &netcp->rx_flows[j].tags);
+		writel(0, &netcp->rx_flows[j].tag_sel);
+		writel(0, &netcp->rx_flows[j].fdq_sel[0]);
+		writel(0, &netcp->rx_flows[j].fdq_sel[1]);
+		writel(0, &netcp->rx_flows[j].thresh[0]);
+		writel(0, &netcp->rx_flows[j].thresh[1]);
+		writel(0, &netcp->rx_flows[j].thresh[2]);
+	}
+
+	return QM_OK;
+}
+
+static int netcp_tx_disable(void)
+{
+	u32 j, v, k;
+
+	for (j = 0; j < netcp->tx_ch_num; j++) {
+		v = readl(&netcp->tx_ch[j].cfg_a);
+		if (!(v & CPDMA_CHAN_A_ENABLE))
+			continue;
+
+		writel(v | CPDMA_CHAN_A_TDOWN, &netcp->tx_ch[j].cfg_a);
+		for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) {
+			udelay(100);
+			v = readl(&netcp->tx_ch[j].cfg_a);
+			if (!(v & CPDMA_CHAN_A_ENABLE))
+				continue;
+		}
+		/* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */
+	}
+
+	return QM_OK;
+}
+
+static int _netcp_init(struct pktdma_cfg *netcp_cfg,
+		       struct rx_buff_desc *rx_buffers)
+{
+	u32 j, v;
+	struct qm_host_desc *hd;
+	u8 *rx_ptr;
+
+	if (netcp_cfg == NULL || rx_buffers == NULL ||
+	    rx_buffers->buff_ptr == NULL || qm_cfg == NULL)
+		return QM_ERR;
+
+	netcp = netcp_cfg;
+	netcp->rx_flow = rx_buffers->rx_flow;
+
+	/* init rx queue */
+	rx_ptr = rx_buffers->buff_ptr;
+
+	for (j = 0; j < rx_buffers->num_buffs; j++) {
+		hd = qm_pop(qm_cfg->qpool_num);
+		if (hd == NULL)
+			return QM_ERR;
+
+		qm_buff_push(hd, netcp->rx_free_q,
+			     rx_ptr, rx_buffers->buff_len);
+
+		rx_ptr += rx_buffers->buff_len;
+	}
+
+	netcp_rx_disable();
+
+	/* configure rx channels */
+	v = CPDMA_REG_VAL_MAKE_RX_FLOW_A(1, 1, 0, 0, 0, 0, 0, netcp->rx_rcv_q);
+	writel(v, &netcp->rx_flows[netcp->rx_flow].control);
+	writel(0, &netcp->rx_flows[netcp->rx_flow].tags);
+	writel(0, &netcp->rx_flows[netcp->rx_flow].tag_sel);
+
+	v = CPDMA_REG_VAL_MAKE_RX_FLOW_D(0, netcp->rx_free_q, 0,
+					 netcp->rx_free_q);
+
+	writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[0]);
+	writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[1]);
+	writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[0]);
+	writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[1]);
+	writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[2]);
+
+	for (j = 0; j < netcp->rx_ch_num; j++)
+		writel(CPDMA_CHAN_A_ENABLE, &netcp->rx_ch[j].cfg_a);
+
+	/* configure tx channels */
+	/* Disable loopback in the tx direction */
+	writel(0, &netcp->global->emulation_control);
+
+/* TODO: make it dependend on a soc type variable */
+#ifdef CONFIG_SOC_K2HK
+	/* Set QM base address, only for K2x devices */
+	writel(0x23a80000, &netcp->global->qm_base_addr[0]);
+#endif
+
+	/* Enable all channels. The current state isn't important */
+	for (j = 0; j < netcp->tx_ch_num; j++)  {
+		writel(0, &netcp->tx_ch[j].cfg_b);
+		writel(CPDMA_CHAN_A_ENABLE, &netcp->tx_ch[j].cfg_a);
+	}
+
+	return QM_OK;
+}
+
+int netcp_init(struct rx_buff_desc *rx_buffers)
+{
+	switch (soc_type) {
+	case k2hk:
+		_netcp_init(&k2hk_netcp_pktdma, rx_buffers);
+		return QM_OK;
+	}
+	return QM_ERR;
+}
+
+int netcp_close(void)
+{
+	if (!netcp)
+		return QM_ERR;
+
+	netcp_tx_disable();
+	netcp_rx_disable();
+
+	queue_close(netcp->rx_free_q);
+	queue_close(netcp->rx_rcv_q);
+	queue_close(netcp->tx_snd_q);
+
+	return QM_OK;
+}
+
+int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2)
+{
+	struct qm_host_desc *hd;
+
+	hd = qm_pop(qm_cfg->qpool_num);
+	if (hd == NULL)
+		return QM_ERR;
+
+	hd->desc_info	= num_bytes;
+	hd->swinfo[2]	= swinfo2;
+	hd->packet_info = qm_cfg->qpool_num;
+
+	qm_buff_push(hd, netcp->tx_snd_q, pkt, num_bytes);
+
+	return QM_OK;
+}
+
+void *netcp_recv(u32 **pkt, int *num_bytes)
+{
+	struct qm_host_desc *hd;
+
+	hd = qm_pop(netcp->rx_rcv_q);
+	if (!hd)
+		return NULL;
+
+	*pkt = (u32 *)hd->buff_ptr;
+	*num_bytes = hd->desc_info & 0x3fffff;
+
+	return hd;
+}
+
+void netcp_release_rxhd(void *hd)
+{
+	struct qm_host_desc *_hd = (struct qm_host_desc *)hd;
+
+	_hd->buff_len = _hd->orig_buff_len;
+	_hd->buff_ptr = _hd->orig_buff_ptr;
+
+	qm_push(_hd, netcp->rx_free_q);
+}
diff --git a/arch/arm/include/asm/arch-keystone/keystone_nav.h b/arch/arm/include/asm/arch-keystone/keystone_nav.h
new file mode 100644
index 0000000..d422bff
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/keystone_nav.h
@@ -0,0 +1,193 @@
+/*
+ * Multicore Navigator definitions
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _KEYSTONE_NAV_H_
+#define _KEYSTONE_NAV_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+enum soc_type_t {
+	k2hk
+};
+
+#define QM_OK			0
+#define QM_ERR			-1
+#define QM_DESC_TYPE_HOST	0
+#define QM_DESC_PSINFO_IN_DESCR	0
+#define QM_DESC_DEFAULT_DESCINFO	(QM_DESC_TYPE_HOST << 30) | \
+					(QM_DESC_PSINFO_IN_DESCR << 22)
+
+/* Packet Info */
+#define QM_DESC_PINFO_EPIB		1
+#define QM_DESC_PINFO_RETURN_OWN	1
+#define QM_DESC_DEFAULT_PINFO		(QM_DESC_PINFO_EPIB << 31) | \
+					(QM_DESC_PINFO_RETURN_OWN << 15)
+
+struct qm_cfg_reg {
+	u32	revision;
+	u32	__pad1;
+	u32	divert;
+	u32	link_ram_base0;
+	u32	link_ram_size0;
+	u32	link_ram_base1;
+	u32	link_ram_size1;
+	u32	link_ram_base2;
+	u32	starvation[0];
+};
+
+struct	descr_mem_setup_reg {
+	u32	base_addr;
+	u32	start_idx;
+	u32	desc_reg_size;
+	u32	_res0;
+};
+
+struct qm_reg_queue {
+	u32	entry_count;
+	u32	byte_count;
+	u32	packet_size;
+	u32	ptr_size_thresh;
+};
+
+struct qm_config {
+	/* QM module addresses */
+	u32	stat_cfg;	/* status and config		*/
+	struct qm_reg_queue *queue;	/* management region		*/
+	u32	mngr_vbusm;	/* management region (VBUSM)	*/
+	u32	i_lram;		/* internal linking RAM		*/
+	struct qm_reg_queue *proxy;
+	u32	status_ram;
+	struct qm_cfg_reg *mngr_cfg;
+				/* Queue manager config region	*/
+	u32	intd_cfg;	/* QMSS INTD config region	*/
+	struct	descr_mem_setup_reg *desc_mem;
+				/* descritor memory setup region*/
+	u32	region_num;
+	u32	pdsp_cmd;	/* PDSP1 command interface	*/
+	u32	pdsp_ctl;	/* PDSP1 control registers	*/
+	u32	pdsp_iram;
+	/* QM configuration parameters */
+
+	u32	qpool_num;	/* */
+};
+
+struct qm_host_desc {
+	u32 desc_info;
+	u32 tag_info;
+	u32 packet_info;
+	u32 buff_len;
+	u32 buff_ptr;
+	u32 next_bdptr;
+	u32 orig_buff_len;
+	u32 orig_buff_ptr;
+	u32 timestamp;
+	u32 swinfo[3];
+	u32 ps_data[20];
+};
+
+#define HDESC_NUM	256
+
+int	qm_init(void);
+void	qm_close(void);
+void	qm_push(struct qm_host_desc *hd, u32 qnum);
+struct qm_host_desc *qm_pop(u32 qnum);
+
+void	qm_buff_push(struct qm_host_desc *hd, u32 qnum,
+		     void *buff_ptr, u32 buff_len);
+
+struct	qm_host_desc *qm_pop_from_free_pool(void);
+void	queue_close(u32 qnum);
+
+/*
+ * DMA API
+ */
+#define CPDMA_REG_VAL_MAKE_RX_FLOW_A(einfo, psinfo, rxerr, desc, \
+				     psloc, sopoff, qmgr, qnum) \
+	(((einfo & 1) << 30)  | \
+	 ((psinfo & 1) << 29) | \
+	 ((rxerr & 1) << 28)  | \
+	 ((desc & 3) << 26)   | \
+	 ((psloc & 1) << 25)  | \
+	 ((sopoff & 0x1ff) << 16) | \
+	 ((qmgr & 3) << 12)   | \
+	 ((qnum & 0xfff) << 0))
+
+#define CPDMA_REG_VAL_MAKE_RX_FLOW_D(fd0qm, fd0qnum, fd1qm, fd1qnum) \
+	(((fd0qm & 3) << 28)  | \
+	 ((fd0qnum & 0xfff) << 16) | \
+	 ((fd1qm & 3) << 12)  | \
+	 ((fd1qnum & 0xfff) <<  0))
+
+#define CPDMA_CHAN_A_ENABLE ((u32)1 << 31)
+#define CPDMA_CHAN_A_TDOWN  (1 << 30)
+#define TDOWN_TIMEOUT_COUNT	100
+
+struct global_ctl_regs {
+	u32	revision;
+	u32	perf_control;
+	u32	emulation_control;
+	u32	priority_control;
+	u32	qm_base_addr[4];
+};
+
+struct tx_chan_regs {
+	u32	cfg_a;
+	u32	cfg_b;
+	u32	res[6];
+};
+
+struct rx_chan_regs {
+	u32	cfg_a;
+	u32	res[7];
+};
+
+struct rx_flow_regs {
+	u32	control;
+	u32	tags;
+	u32	tag_sel;
+	u32	fdq_sel[2];
+	u32	thresh[3];
+};
+
+struct pktdma_cfg {
+	struct global_ctl_regs	*global;
+	struct tx_chan_regs	*tx_ch;
+	u32			tx_ch_num;
+	struct rx_chan_regs	*rx_ch;
+	u32			rx_ch_num;
+	u32			*tx_sched;
+	struct rx_flow_regs	*rx_flows;
+	u32			rx_flow_num;
+
+	u32			rx_free_q;
+	u32			rx_rcv_q;
+	u32			tx_snd_q;
+
+	u32			rx_flow; /* flow that is used for RX */
+};
+
+/*
+ * packet dma user allocates memory for rx buffers
+ * and describe it in the following structure
+ */
+struct rx_buff_desc {
+	u8	*buff_ptr;
+	u32	num_buffs;
+	u32	buff_len;
+	u32	rx_flow;
+};
+
+int netcp_close(void);
+int netcp_init(struct rx_buff_desc *rx_buffers);
+int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2);
+void *netcp_recv(u32 **pkt, int *num_bytes);
+void netcp_release_rxhd(void *hd);
+
+#endif  /* _KEYSTONE_NAV_H_ */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (8 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select Murali Karicheri
                     ` (3 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Vitaly Andrianov <vitalya@ti.com>

Ethernet driver configures the CPSW, SGMI and Phy and uses
the the Navigator APIs. The driver supports 4 Ethernet ports and
can work with only one port at a time.

Port configurations are defined in board.c.

Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
---
 - updated based on review comments
 arch/arm/include/asm/arch-keystone/emac_defs.h |  250 +++++++
 board/ti/k2hk_evm/board.c                      |   65 ++
 drivers/net/Makefile                           |    1 +
 drivers/net/keystone_net.c                     |  859 ++++++++++++++++++++++++
 include/configs/k2hk_evm.h                     |   38 ++
 5 files changed, 1213 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
 create mode 100644 drivers/net/keystone_net.c

diff --git a/arch/arm/include/asm/arch-keystone/emac_defs.h b/arch/arm/include/asm/arch-keystone/emac_defs.h
new file mode 100644
index 0000000..9c1c5bc
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/emac_defs.h
@@ -0,0 +1,250 @@
+/*
+ * emac definitions for keystone2 devices
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _EMAC_DEFS_H_
+#define _EMAC_DEFS_H_
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define DEVICE_REG32_R(a)			readl(a)
+#define DEVICE_REG32_W(a, v)			writel(v, a)
+
+/*#define chipLmbd(x,y) _lmbd(x,y) */
+
+#define EMAC_EMACSL_BASE_ADDR		(KS2_PASS_BASE + 0x00090900)
+#define EMAC_MDIO_BASE_ADDR		(KS2_PASS_BASE + 0x00090300)
+#define EMAC_SGMII_BASE_ADDR		(KS2_PASS_BASE + 0x00090100)
+
+#define KEYSTONE2_EMAC_GIG_ENABLE
+
+#define MAC_ID_BASE_ADDR		(KS2_DEVICE_STATE_CTRL_BASE + 0x110)
+
+#ifdef CONFIG_SOC_K2HK
+/* MDIO module input frequency */
+#define EMAC_MDIO_BUS_FREQ		(clk_get_rate(pass_pll_clk))
+/* MDIO clock output frequency */
+#define EMAC_MDIO_CLOCK_FREQ		1000000		/* 1.0 MHz */
+#endif
+
+/* MII Status Register */
+#define MII_STATUS_REG			1
+#define MII_STATUS_LINK_MASK		(0x4)
+
+/* Marvell 88E1111 PHY ID */
+#define PHY_MARVELL_88E1111		(0x01410cc0)
+
+#define MDIO_CONTROL_IDLE		(0x80000000)
+#define MDIO_CONTROL_ENABLE		(0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE	(0x40000)
+#define MDIO_CONTROL_FAULT		(0x80000)
+#define MDIO_USERACCESS0_GO		(0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ	(0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE	(0x40000000)
+#define MDIO_USERACCESS0_ACK		(0x20000000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE		(0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE	(0x1)
+#define EMAC_MACCONTROL_GIGABIT_ENABLE		(1 << 7)
+#define EMAC_MACCONTROL_GIGFORCE		(1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100		(1 << 15)
+
+#define EMAC_MIN_ETHERNET_PKT_SIZE	60
+
+struct mac_sl_cfg {
+	u_int32_t max_rx_len;	/* Maximum receive packet length. */
+	u_int32_t ctl;		/* Control bitfield */
+};
+
+/*
+ * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t
+ */
+#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES       (1 << 24)
+#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES         (1 << 23)
+#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES         (1 << 22)
+#define GMACSL_RX_ENABLE_EXT_CTL                  (1 << 18)
+#define GMACSL_RX_ENABLE_GIG_FORCE                (1 << 17)
+#define GMACSL_RX_ENABLE_IFCTL_B                  (1 << 16)
+#define GMACSL_RX_ENABLE_IFCTL_A                  (1 << 15)
+#define GMACSL_RX_ENABLE_CMD_IDLE                 (1 << 11)
+#define GMACSL_TX_ENABLE_SHORT_GAP                (1 << 10)
+#define GMACSL_ENABLE_GIG_MODE                    (1 <<  7)
+#define GMACSL_TX_ENABLE_PACE                     (1 <<  6)
+#define GMACSL_ENABLE                             (1 <<  5)
+#define GMACSL_TX_ENABLE_FLOW_CTL                 (1 <<  4)
+#define GMACSL_RX_ENABLE_FLOW_CTL                 (1 <<  3)
+#define GMACSL_ENABLE_LOOPBACK                    (1 <<  1)
+#define GMACSL_ENABLE_FULL_DUPLEX                 (1 <<  0)
+
+/*
+ * DEFINTITION: function return values
+ */
+#define GMACSL_RET_OK                        0
+#define GMACSL_RET_INVALID_PORT             -1
+#define GMACSL_RET_WARN_RESET_INCOMPLETE    -2
+#define GMACSL_RET_WARN_MAXLEN_TOO_BIG      -3
+#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4
+
+/* Register offsets */
+#define CPGMACSL_REG_ID         0x00
+#define CPGMACSL_REG_CTL        0x04
+#define CPGMACSL_REG_STATUS     0x08
+#define CPGMACSL_REG_RESET      0x0c
+#define CPGMACSL_REG_MAXLEN     0x10
+#define CPGMACSL_REG_BOFF       0x14
+#define CPGMACSL_REG_RX_PAUSE   0x18
+#define CPGMACSL_REG_TX_PAURSE  0x1c
+#define CPGMACSL_REG_EM_CTL     0x20
+#define CPGMACSL_REG_PRI        0x24
+
+/* Soft reset register values */
+#define CPGMAC_REG_RESET_VAL_RESET_MASK      (1 << 0)
+#define CPGMAC_REG_RESET_VAL_RESET           (1 << 0)
+
+/* Maxlen register values */
+#define CPGMAC_REG_MAXLEN_LEN                0x3fff
+
+/* Control bitfields */
+#define CPSW_CTL_P2_PASS_PRI_TAGGED     (1 << 5)
+#define CPSW_CTL_P1_PASS_PRI_TAGGED     (1 << 4)
+#define CPSW_CTL_P0_PASS_PRI_TAGGED     (1 << 3)
+#define CPSW_CTL_P0_ENABLE              (1 << 2)
+#define CPSW_CTL_VLAN_AWARE             (1 << 1)
+#define CPSW_CTL_FIFO_LOOPBACK          (1 << 0)
+
+#define DEVICE_CPSW_NUM_PORTS       5                    /* 5 switch ports */
+#define DEVICE_CPSW_BASE            (0x02090800)
+#define target_get_switch_ctl()        CPSW_CTL_P0_ENABLE   /* Enable port 0 */
+#define SWITCH_MAX_PKT_SIZE	9000
+
+/* Register offsets */
+#define CPSW_REG_CTL                0x004
+#define CPSW_REG_STAT_PORT_EN       0x00c
+#define CPSW_REG_MAXLEN             0x040
+#define CPSW_REG_ALE_CONTROL        0x608
+#define CPSW_REG_ALE_PORTCTL(x)     (0x640 + (x)*4)
+
+/* Register values */
+#define CPSW_REG_VAL_STAT_ENABLE_ALL             0xf
+#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE	((u_int32_t)0xc0000000)
+#define CPSW_REG_VAL_ALE_CTL_BYPASS		((u_int32_t)0x00000010)
+#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE        0x3
+
+#define SGMII_REG_STATUS_LOCK		BIT(4)
+#define	SGMII_REG_STATUS_LINK		BIT(0)
+#define SGMII_REG_STATUS_AUTONEG	BIT(2)
+#define SGMII_REG_CONTROL_AUTONEG	BIT(0)
+#define SGMII_REG_CONTROL_MASTER	BIT(5)
+#define	SGMII_REG_MR_ADV_ENABLE		BIT(0)
+#define	SGMII_REG_MR_ADV_LINK		BIT(15)
+#define	SGMII_REG_MR_ADV_FULL_DUPLEX	BIT(12)
+#define SGMII_REG_MR_ADV_GIG_MODE	BIT(11)
+
+#define SGMII_LINK_MAC_MAC_AUTONEG	0
+#define SGMII_LINK_MAC_PHY		1
+#define SGMII_LINK_MAC_MAC_FORCED	2
+#define SGMII_LINK_MAC_FIBER		3
+#define SGMII_LINK_MAC_PHY_FORCED	4
+
+#define TARGET_SGMII_BASE		KS2_PASS_BASE + 0x00090100
+#define TARGET_SGMII_BASE_ADDRESSES    {KS2_PASS_BASE+0x00090100, \
+					KS2_PASS_BASE+0x00090200, \
+					KS2_PASS_BASE+0x00090400, \
+					KS2_PASS_BASE+0x00090500  }
+
+#define SGMII_OFFSET(x)	((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100))
+
+/*
+ * SGMII registers
+ */
+#define SGMII_IDVER_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x000)
+#define SGMII_SRESET_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x004)
+#define SGMII_CTL_REG(x)      (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x010)
+#define SGMII_STATUS_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x014)
+#define SGMII_MRADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x018)
+#define SGMII_LPADV_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x020)
+#define SGMII_TXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x030)
+#define SGMII_RXCFG_REG(x)    (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x034)
+#define SGMII_AUXCFG_REG(x)   (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x038)
+
+#define DEVICE_EMACSL_BASE(x)           (KS2_PASS_BASE + 0x00090900 + (x)*0x040)
+#define DEVICE_N_GMACSL_PORTS           4
+#define DEVICE_EMACSL_RESET_POLL_COUNT  100
+
+#define DEVICE_PSTREAM_CFG_REG_ADDR                 (KS2_PASS_BASE + 0x604)
+
+#ifdef CONFIG_SOC_K2HK
+#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI      0x06060606
+#endif
+
+#define hw_config_streaming_switch() \
+	DEVICE_REG32_W(DEVICE_PSTREAM_CFG_REG_ADDR, \
+		       DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI);
+
+/* EMAC MDIO Registers Structure */
+struct mdio_regs {
+	dv_reg		VERSION;
+	dv_reg		CONTROL;
+	dv_reg		ALIVE;
+	dv_reg		LINK;
+	dv_reg		LINKINTRAW;
+	dv_reg		LINKINTMASKED;
+	u_int8_t	RSVD0[8];
+	dv_reg		USERINTRAW;
+	dv_reg		USERINTMASKED;
+	dv_reg		USERINTMASKSET;
+	dv_reg		USERINTMASKCLEAR;
+	u_int8_t	RSVD1[80];
+	dv_reg		USERACCESS0;
+	dv_reg		USERPHYSEL0;
+	dv_reg		USERACCESS1;
+	dv_reg		USERPHYSEL1;
+};
+
+/* Ethernet MAC Registers Structure */
+struct emac_regs {
+	dv_reg		IDVER;
+	dv_reg		MACCONTROL;
+	dv_reg		MACSTATUS;
+	dv_reg		SOFT_RESET;
+	dv_reg		RX_MAXLEN;
+	u32		RSVD0;
+	dv_reg		RX_PAUSE;
+	dv_reg		TX_PAUSE;
+	dv_reg		EMCONTROL;
+	dv_reg		PRI_MAP;
+	u32		RSVD1[6];
+};
+
+struct phy_t {
+	char	name[64];
+	int	(*init)(int phy_addr);
+	int	(*is_phy_connected)(int phy_addr);
+	int	(*get_link_speed)(int phy_addr);
+	int	(*auto_negotiate)(int phy_addr);
+};
+
+#define SGMII_ACCESS(port, reg) \
+	*((volatile unsigned int *)(sgmiis[port] + reg))
+
+struct eth_priv_t {
+	char	int_name[32];
+	int	rx_flow;
+	int	phy_addr;
+	int	slave_port;
+	int	sgmii_link_type;
+};
+
+extern struct eth_priv_t eth_priv_cfg[];
+
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv);
+void sgmii_serdes_setup_156p25mhz(void);
+void sgmii_serdes_shutdown(void);
+
+#endif  /* _EMAC_DEFS_H_ */
diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c
index 14dc7e4..81f5ca4 100644
--- a/board/ti/k2hk_evm/board.c
+++ b/board/ti/k2hk_evm/board.c
@@ -17,6 +17,7 @@
 #include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/arch/nand_defs.h>
+#include <asm/arch/emac_defs.h>
 #include <asm/arch/psc_defs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -70,6 +71,70 @@ int dram_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET
+struct eth_priv_t eth_priv_cfg[] = {
+	{
+		.int_name	= "K2HK_EMAC",
+		.rx_flow	= 22,
+		.phy_addr	= 0,
+		.slave_port	= 1,
+		.sgmii_link_type = SGMII_LINK_MAC_PHY,
+	},
+	{
+		.int_name	= "K2HK_EMAC1",
+		.rx_flow	= 23,
+		.phy_addr	= 1,
+		.slave_port	= 2,
+		.sgmii_link_type = SGMII_LINK_MAC_PHY,
+	},
+	{
+		.int_name	= "K2HK_EMAC2",
+		.rx_flow	= 24,
+		.phy_addr	= 2,
+		.slave_port	= 3,
+		.sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+	},
+	{
+		.int_name	= "K2HK_EMAC3",
+		.rx_flow	= 25,
+		.phy_addr	= 3,
+		.slave_port	= 4,
+		.sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED,
+	},
+};
+
+int get_eth_env_param(char *env_name)
+{
+	char *env;
+	int  res = -1;
+
+	env = getenv(env_name);
+	if (env)
+		res = simple_strtol(env, NULL, 0);
+
+	return res;
+}
+
+int board_eth_init(bd_t *bis)
+{
+	int	j;
+	int	res;
+	char	link_type_name[32];
+
+	for (j = 0; j < (sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t));
+	     j++) {
+		sprintf(link_type_name, "sgmii%d_link_type", j);
+		res = get_eth_env_param(link_type_name);
+		if (res >= 0)
+			eth_priv_cfg[j].sgmii_link_type = res;
+
+		keystone2_emac_initialize(&eth_priv_cfg[j]);
+	}
+
+	return 0;
+}
+#endif
+
 /* Byte swap the 32-bit data if the device is BE */
 int cpu_to_bus(u32 *ptr, u32 length)
 {
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7f9ce90..6005f7e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o
 obj-$(CONFIG_FTMAC100) += ftmac100.o
 obj-$(CONFIG_GRETH) += greth.o
 obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
+obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o
 obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
 obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
 obj-$(CONFIG_LAN91C96) += lan91c96.o
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
new file mode 100644
index 0000000..473a4b1
--- /dev/null
+++ b/drivers/net/keystone_net.c
@@ -0,0 +1,859 @@
+/*
+ * Ethernet driver for TI K2HK EVM.
+ *
+ * (C) Copyright 2012-2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+#include <common.h>
+#include <command.h>
+
+#include <net.h>
+#include <miiphy.h>
+#include <malloc.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/arch/keystone_nav.h>
+
+unsigned int emac_dbg;
+#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)
+
+unsigned int emac_open;
+static unsigned int sys_has_mdio = 1;
+
+#ifdef KEYSTONE2_EMAC_GIG_ENABLE
+#define emac_gigabit_enable(x)	keystone2_eth_gigabit_enable(x)
+#else
+#define emac_gigabit_enable(x)	/* no gigabit to enable */
+#endif
+
+#define RX_BUFF_NUMS	24
+#define RX_BUFF_LEN	1520
+#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN
+
+static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16);
+
+struct rx_buff_desc net_rx_buffs = {
+	.buff_ptr	= rx_buffs,
+	.num_buffs	= RX_BUFF_NUMS,
+	.buff_len	= RX_BUFF_LEN,
+	.rx_flow	= 22,
+};
+
+static void keystone2_eth_mdio_enable(void);
+
+static int gen_init_phy(int phy_addr);
+static int gen_is_phy_connected(int phy_addr);
+static int gen_get_link_speed(int phy_addr);
+static int gen_auto_negotiate(int phy_addr);
+
+static int marvell_88e1111_init_phy(int phy_addr);
+static int marvell_88e1111_is_phy_connected(int phy_addr);
+static int marvell_88e1111_get_link_speed(int phy_addr);
+static int marvell_88e1111_auto_negotiate(int phy_addr);
+
+/* EMAC Addresses */
+static volatile struct emac_regs	*adap_emac =
+	(struct emac_regs *)EMAC_EMACSL_BASE_ADDR;
+static volatile struct mdio_regs	*adap_mdio =
+	(struct mdio_regs *)EMAC_MDIO_BASE_ADDR;
+
+struct phy_t phy;
+
+static void chip_delay(u32 del)
+{
+	volatile unsigned int i;
+
+	for (i = 0; i < (del / 8); i++)
+		;
+}
+
+int keystone2_eth_read_mac_addr(struct eth_device *dev)
+{
+	struct eth_priv_t *eth_priv;
+	u32 maca = 0;
+	u32 macb = 0;
+
+	eth_priv = (struct eth_priv_t *)dev->priv;
+
+	/* Read the e-fuse mac address */
+	if (eth_priv->slave_port == 1) {
+		maca = __raw_readl(MAC_ID_BASE_ADDR);
+		macb = __raw_readl(MAC_ID_BASE_ADDR + 4);
+	}
+
+	dev->enetaddr[0] = (macb >>  8) & 0xff;
+	dev->enetaddr[1] = (macb >>  0) & 0xff;
+	dev->enetaddr[2] = (maca >> 24) & 0xff;
+	dev->enetaddr[3] = (maca >> 16) & 0xff;
+	dev->enetaddr[4] = (maca >>  8) & 0xff;
+	dev->enetaddr[5] = (maca >>  0) & 0xff;
+
+	return 0;
+}
+
+static void keystone2_eth_mdio_enable(void)
+{
+	u_int32_t	clkdiv;
+
+	clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+	writel((clkdiv & 0xffff) |
+	       MDIO_CONTROL_ENABLE |
+	       MDIO_CONTROL_FAULT |
+	       MDIO_CONTROL_FAULT_ENABLE,
+	       &adap_mdio->CONTROL);
+
+	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
+		;
+}
+
+/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
+int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
+{
+	int	tmp;
+
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_READ |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16),
+	       &adap_mdio->USERACCESS0);
+
+	/* Wait for command to complete */
+	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
+		;
+
+	if (tmp & MDIO_USERACCESS0_ACK) {
+		*data = tmp & 0xffff;
+		return 0;
+	}
+
+	*data = -1;
+	return -1;
+}
+
+/*
+ * Write to a PHY register via MDIO inteface.
+ * Blocks until operation is complete.
+ */
+int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
+{
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	writel(MDIO_USERACCESS0_GO |
+	       MDIO_USERACCESS0_WRITE_WRITE |
+	       ((reg_num & 0x1f) << 21) |
+	       ((phy_addr & 0x1f) << 16) |
+	       (data & 0xffff),
+	       &adap_mdio->USERACCESS0);
+
+	/* Wait for command to complete */
+	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
+		;
+
+	return 0;
+}
+
+/* PHY functions for a generic PHY */
+static int __attribute__((unused)) gen_init_phy(int phy_addr)
+{
+	int	ret = -1;
+
+	if (!gen_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = gen_get_link_speed(phy_addr);
+	}
+
+	return ret;
+}
+
+static int __attribute__((unused)) gen_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int gen_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+	    (tmp & 0x04)) {
+		return 0;
+	}
+
+	return -1;
+}
+
+static int __attribute__((unused)) gen_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return -1;
+
+	/* Restart Auto_negotiation  */
+	tmp |= BMCR_ANENABLE;
+	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+		return -1;
+
+	if (!(tmp & BMSR_ANEGCOMPLETE))
+		return 0;
+
+	return gen_get_link_speed(phy_addr);
+}
+
+/* PHY functions for Marvell 88E1111 PHY */
+static int marvell_88e1111_init_phy(int phy_addr)
+{
+	int	ret = -1;
+
+	if (!marvell_88e1111_get_link_speed(phy_addr)) {
+		/* Try another time */
+		ret = marvell_88e1111_get_link_speed(phy_addr);
+	}
+
+	return ret;
+}
+
+static int marvell_88e1111_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+static int marvell_88e1111_get_link_speed(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) &&
+	    (tmp & MII_STATUS_LINK_MASK)) {
+		return 0;
+	}
+
+	return -1;
+}
+
+static int marvell_88e1111_auto_negotiate(int phy_addr)
+{
+	u_int16_t	tmp;
+
+	if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp))
+		return -1;
+
+	/* Restart Auto_negotiation  */
+	tmp |= BMCR_ANENABLE;
+	keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp);
+
+	/*check AutoNegotiate complete */
+	udelay(10000);
+	if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp))
+		return -1;
+
+	if (!(tmp & BMSR_ANEGCOMPLETE))
+		return 0;
+
+	return marvell_88e1111_get_link_speed(phy_addr);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+static int keystone2_mii_phy_read(const char *devname, unsigned char addr,
+				  unsigned char reg, unsigned short *value)
+{
+	return keystone2_eth_phy_read(addr, reg, value) ? -1 : 0;
+}
+
+static int keystone2_mii_phy_write(const char *devname, unsigned char addr,
+				 unsigned char reg, unsigned short value)
+{
+	return keystone2_eth_phy_write(addr, reg, value) ? -1 : 0;
+}
+#endif
+
+static void  __attribute__((unused))
+	keystone2_eth_gigabit_enable(struct eth_device *dev)
+{
+	u_int16_t data;
+	struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+	if (sys_has_mdio) {
+		if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) ||
+		    !(data & (1 << 6))) /* speed selection MSB */
+			return;
+	}
+
+	/*
+	 * Check if link detected is giga-bit
+	 * If Gigabit mode detected, enable gigbit in MAC
+	 */
+	writel(readl(&(adap_emac[eth_priv->slave_port - 1].MACCONTROL)) |
+	       EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE,
+	       &(adap_emac[eth_priv->slave_port - 1].MACCONTROL))
+		;
+}
+
+int keystone_sgmii_link_status(int port)
+{
+	u32 status = 0;
+
+	status = __raw_readl(SGMII_STATUS_REG(port));
+
+	return status & SGMII_REG_STATUS_LINK;
+}
+
+
+int keystone_get_link_status(struct eth_device *dev)
+{
+	struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+	int sgmii_link;
+	int link_state = 0;
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+	int j;
+
+	for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
+	     j++) {
+#endif
+		sgmii_link =
+			keystone_sgmii_link_status(eth_priv->slave_port - 1);
+
+		if (sgmii_link) {
+			link_state = 1;
+
+			if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY)
+				if (phy.get_link_speed(eth_priv->phy_addr))
+					link_state = 0;
+		}
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
+	}
+#endif
+	return link_state;
+}
+
+int keystone_sgmii_config(int port, int interface)
+{
+	unsigned int i, status, mask;
+	unsigned int mr_adv_ability, control;
+
+	switch (interface) {
+	case SGMII_LINK_MAC_MAC_AUTONEG:
+		mr_adv_ability	= (SGMII_REG_MR_ADV_ENABLE |
+				   SGMII_REG_MR_ADV_LINK |
+				   SGMII_REG_MR_ADV_FULL_DUPLEX |
+				   SGMII_REG_MR_ADV_GIG_MODE);
+		control		= (SGMII_REG_CONTROL_MASTER |
+				   SGMII_REG_CONTROL_AUTONEG);
+
+		break;
+	case SGMII_LINK_MAC_PHY:
+	case SGMII_LINK_MAC_PHY_FORCED:
+		mr_adv_ability	= SGMII_REG_MR_ADV_ENABLE;
+		control		= SGMII_REG_CONTROL_AUTONEG;
+
+		break;
+	case SGMII_LINK_MAC_MAC_FORCED:
+		mr_adv_ability	= (SGMII_REG_MR_ADV_ENABLE |
+				   SGMII_REG_MR_ADV_LINK |
+				   SGMII_REG_MR_ADV_FULL_DUPLEX |
+				   SGMII_REG_MR_ADV_GIG_MODE);
+		control		= SGMII_REG_CONTROL_MASTER;
+
+		break;
+	case SGMII_LINK_MAC_FIBER:
+		mr_adv_ability	= 0x20;
+		control		= SGMII_REG_CONTROL_AUTONEG;
+
+		break;
+	default:
+		mr_adv_ability	= SGMII_REG_MR_ADV_ENABLE;
+		control		= SGMII_REG_CONTROL_AUTONEG;
+	}
+
+	__raw_writel(0, SGMII_CTL_REG(port));
+
+	/*
+	 * Wait for the SerDes pll to lock,
+	 * but don't trap if lock is never read
+	 */
+	for (i = 0; i < 1000; i++)  {
+		udelay(2000);
+		status = __raw_readl(SGMII_STATUS_REG(port));
+		if ((status & SGMII_REG_STATUS_LOCK) != 0)
+			break;
+	}
+
+	__raw_writel(mr_adv_ability, SGMII_MRADV_REG(port));
+	__raw_writel(control, SGMII_CTL_REG(port));
+
+
+	mask = SGMII_REG_STATUS_LINK;
+
+	if (control & SGMII_REG_CONTROL_AUTONEG)
+		mask |= SGMII_REG_STATUS_AUTONEG;
+
+	for (i = 0; i < 1000; i++) {
+		status = __raw_readl(SGMII_STATUS_REG(port));
+		if ((status & mask) == mask)
+			break;
+	}
+
+	return 0;
+}
+
+int mac_sl_reset(u32 port)
+{
+	u32 i, v;
+
+	if (port >= DEVICE_N_GMACSL_PORTS)
+		return GMACSL_RET_INVALID_PORT;
+
+	/* Set the soft reset bit */
+	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) +
+		       CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET);
+
+	/* Wait for the bit to clear */
+	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+		v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+				   CPGMACSL_REG_RESET);
+		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+		    CPGMAC_REG_RESET_VAL_RESET)
+			return GMACSL_RET_OK;
+	}
+
+	/* Timeout on the reset */
+	return GMACSL_RET_WARN_RESET_INCOMPLETE;
+}
+
+int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg)
+{
+	u32 v, i;
+	int ret = GMACSL_RET_OK;
+
+	if (port >= DEVICE_N_GMACSL_PORTS)
+		return GMACSL_RET_INVALID_PORT;
+
+	if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) {
+		cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN;
+		ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG;
+	}
+
+	/* Must wait if the device is undergoing reset */
+	for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
+		v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) +
+				   CPGMACSL_REG_RESET);
+		if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) !=
+		    CPGMAC_REG_RESET_VAL_RESET)
+			break;
+	}
+
+	if (i == DEVICE_EMACSL_RESET_POLL_COUNT)
+		return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE;
+
+	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN,
+		       cfg->max_rx_len);
+
+	DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL,
+		       cfg->ctl);
+
+	return ret;
+}
+
+int ethss_config(u32 ctl, u32 max_pkt_size)
+{
+	u32 i;
+
+	/* Max length register */
+	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size);
+
+	/* Control register */
+	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl);
+
+	/* All statistics enabled by default */
+	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN,
+		       CPSW_REG_VAL_STAT_ENABLE_ALL);
+
+	/* Reset and enable the ALE */
+	DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL,
+		       CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE |
+		       CPSW_REG_VAL_ALE_CTL_BYPASS);
+
+	/* All ports put into forward mode */
+	for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++)
+		DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i),
+			       CPSW_REG_VAL_PORTCTL_FORWARD_MODE);
+
+	return 0;
+}
+
+int ethss_start(void)
+{
+	int i;
+	struct mac_sl_cfg cfg;
+
+	cfg.max_rx_len	= MAX_SIZE_STREAM_BUFFER;
+	cfg.ctl		= GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL;
+
+	for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) {
+		mac_sl_reset(i);
+		mac_sl_config(i, &cfg);
+	}
+
+	return 0;
+}
+
+int ethss_stop(void)
+{
+	int i;
+
+	for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++)
+		mac_sl_reset(i);
+
+	return 0;
+}
+
+int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num)
+{
+	if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE)
+		num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE;
+
+	return netcp_send(buffer, num_bytes, (slave_port_num) << 16);
+}
+
+/* Eth device open */
+static int keystone2_eth_open(struct eth_device *dev, bd_t *bis)
+{
+	u_int32_t clkdiv;
+	int link;
+	struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+	debug_emac("+ emac_open\n");
+
+	net_rx_buffs.rx_flow	= eth_priv->rx_flow;
+
+	sys_has_mdio =
+		(eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0;
+
+	psc_enable_module(KS2_LPSC_PA);
+	psc_enable_module(KS2_LPSC_CPGMAC);
+
+	sgmii_serdes_setup_156p25mhz();
+
+	if (sys_has_mdio)
+		keystone2_eth_mdio_enable();
+
+	keystone_sgmii_config(eth_priv->slave_port - 1,
+			      eth_priv->sgmii_link_type);
+
+	udelay(10000);
+
+	/* On chip switch configuration */
+	ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE);
+
+	/* TODO: add error handling code */
+	if (qm_init()) {
+		printf("ERROR: qm_init()\n");
+		return -1;
+	}
+	if (netcp_init(&net_rx_buffs)) {
+		qm_close();
+		printf("ERROR: netcp_init()\n");
+		return -1;
+	}
+
+	/*
+	 * Streaming switch configuration. If not present this
+	 * statement is defined to void in target.h.
+	 * If present this is usually defined to a series of register writes
+	 */
+	hw_config_streaming_switch();
+
+	if (sys_has_mdio) {
+		/* Init MDIO & get link state */
+		clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+		writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE |
+		       MDIO_CONTROL_FAULT, &adap_mdio->CONTROL)
+			;
+
+		/* We need to wait for MDIO to start */
+		udelay(1000);
+
+		link = keystone_get_link_status(dev);
+		if (link == 0) {
+			netcp_close();
+			qm_close();
+			return -1;
+		}
+	}
+
+	emac_gigabit_enable(dev);
+
+	ethss_start();
+
+	debug_emac("- emac_open\n");
+
+	emac_open = 1;
+
+	return 0;
+}
+
+/* Eth device close */
+void keystone2_eth_close(struct eth_device *dev)
+{
+	debug_emac("+ emac_close\n");
+
+	if (!emac_open)
+		return;
+
+	ethss_stop();
+
+	netcp_close();
+	qm_close();
+
+	emac_open = 0;
+
+	debug_emac("- emac_close\n");
+}
+
+static int tx_send_loop;
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int keystone2_eth_send_packet(struct eth_device *dev,
+					void *packet, int length)
+{
+	int ret_status = -1;
+	struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv;
+
+	tx_send_loop = 0;
+
+	if (keystone_get_link_status(dev) == 0)
+		return -1;
+
+	emac_gigabit_enable(dev);
+
+	if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0)
+		return ret_status;
+
+	if (keystone_get_link_status(dev) == 0)
+		return -1;
+
+	emac_gigabit_enable(dev);
+
+	return length;
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int keystone2_eth_rcv_packet(struct eth_device *dev)
+{
+	void *hd;
+	int  pkt_size;
+	u32  *pkt;
+
+	hd = netcp_recv(&pkt, &pkt_size);
+	if (hd == NULL)
+		return 0;
+
+	NetReceive((uchar *)pkt, pkt_size);
+
+	netcp_release_rxhd(hd);
+
+	return pkt_size;
+}
+
+/*
+ * This function initializes the EMAC hardware. It does NOT initialize
+ * EMAC modules power or pin multiplexors, that is done by board_init()
+ * much earlier in bootup process. Returns 1 on success, 0 otherwise.
+ */
+int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
+{
+	struct eth_device *dev;
+	static int phy_registered;
+
+	dev = malloc(sizeof(struct eth_device));
+	if (dev == NULL)
+		return -1;
+
+	memset(dev, 0, sizeof(struct eth_device));
+
+	strcpy(dev->name, eth_priv->int_name);
+	dev->priv = eth_priv;
+
+	keystone2_eth_read_mac_addr(dev);
+
+	dev->iobase		= 0;
+	dev->init		= keystone2_eth_open;
+	dev->halt		= keystone2_eth_close;
+	dev->send		= keystone2_eth_send_packet;
+	dev->recv		= keystone2_eth_rcv_packet;
+
+	eth_register(dev);
+
+	if (sys_has_mdio && !phy_registered) {
+		phy_registered = 1;
+#ifdef CONFIG_ETH_PHY_MARVEL_88E1111
+		sprintf(phy.name, "88E1111");
+		phy.init = marvell_88e1111_init_phy;
+		phy.is_phy_connected = marvell_88e1111_is_phy_connected;
+		phy.get_link_speed = marvell_88e1111_get_link_speed;
+		phy.auto_negotiate = marvell_88e1111_auto_negotiate;
+#else
+		sprintf(phy.name, "GENERIC");
+		phy.init = gen_init_phy;
+		phy.is_phy_connected = gen_is_phy_connected;
+		phy.get_link_speed = gen_get_link_speed;
+		phy.auto_negotiate = gen_auto_negotiate;
+#endif
+		miiphy_register(phy.name, keystone2_mii_phy_read,
+				keystone2_mii_phy_write);
+	}
+
+	return 0;
+}
+
+#define reg_rmw(addr, value, mask) \
+	writel(((readl(addr) & (~(mask))) | (value)), (addr))
+
+void sgmii_serdes_setup_156p25mhz()
+{
+	unsigned int cnt;
+
+	reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
+	reg_rmw(0x0232a014, 0x00008282, 0x0000ffff);
+	reg_rmw(0x0232a060, 0x00142438, 0x00ffffff);
+	reg_rmw(0x0232a064, 0x00c3c700, 0x00ffff00);
+	reg_rmw(0x0232a078, 0x0000c000, 0x0000ff00);
+
+	reg_rmw(0x0232a204, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a208, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a20c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a210, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a214, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a218, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a2ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a22c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a280, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a284, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a404, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a408, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a40c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a410, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a414, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a418, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a4ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a42c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a480, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a484, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a604, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a608, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a60c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a610, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a614, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a618, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a6ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a62c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a680, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a684, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232a804, 0x38000080, 0xff0000ff);
+	reg_rmw(0x0232a808, 0x00000000, 0x000000ff);
+	reg_rmw(0x0232a80c, 0x02000000, 0xff000000);
+	reg_rmw(0x0232a810, 0x1b000000, 0xff000000);
+	reg_rmw(0x0232a814, 0x00006fb8, 0x0000ffff);
+	reg_rmw(0x0232a818, 0x758000e4, 0xffff00ff);
+	reg_rmw(0x0232a8ac, 0x00004400, 0x0000ff00);
+	reg_rmw(0x0232a82c, 0x00200800, 0x00ffff00);
+	reg_rmw(0x0232a880, 0x00820082, 0x00ff00ff);
+	reg_rmw(0x0232a884, 0x1d0f0385, 0xffffffff);
+
+	reg_rmw(0x0232aa00, 0x00000800, 0x0000ff00);
+	reg_rmw(0x0232aa08, 0x38a20000, 0xffff0000);
+	reg_rmw(0x0232aa30, 0x008a8a00, 0x00ffff00);
+	reg_rmw(0x0232aa84, 0x00000600, 0x0000ff00);
+	reg_rmw(0x0232aa94, 0x10000000, 0xff000000);
+	reg_rmw(0x0232aaa0, 0x81000000, 0xff000000);
+	reg_rmw(0x0232aabc, 0xff000000, 0xff000000);
+	reg_rmw(0x0232aac0, 0x0000008b, 0x000000ff);
+	reg_rmw(0x0232ab08, 0x583f0000, 0xffff0000);
+	reg_rmw(0x0232ab0c, 0x0000004e, 0x000000ff);
+	reg_rmw(0x0232a000, 0x00000003, 0x000000ff);
+	reg_rmw(0x0232aa00, 0x0000005f, 0x000000ff);
+
+	reg_rmw(0x0232aa48, 0x00fd8c00, 0x00ffff00);
+	reg_rmw(0x0232aa54, 0x002fec72, 0x00ffffff);
+	reg_rmw(0x0232aa58, 0x00f92100, 0xffffff00);
+	reg_rmw(0x0232aa5c, 0x00040060, 0xffffffff);
+	reg_rmw(0x0232aa60, 0x00008000, 0xffffffff);
+	reg_rmw(0x0232aa64, 0x0c581220, 0xffffffff);
+	reg_rmw(0x0232aa68, 0xe13b0602, 0xffffffff);
+	reg_rmw(0x0232aa6c, 0xb8074cc1, 0xffffffff);
+	reg_rmw(0x0232aa70, 0x3f02e989, 0xffffffff);
+	reg_rmw(0x0232aa74, 0x00000001, 0x000000ff);
+	reg_rmw(0x0232ab20, 0x00370000, 0x00ff0000);
+	reg_rmw(0x0232ab1c, 0x37000000, 0xff000000);
+	reg_rmw(0x0232ab20, 0x0000005d, 0x000000ff);
+
+	/*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/
+	reg_rmw(0x0232a010, 0x00000000, 1 << 28);
+
+	/* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */
+	reg_rmw(0x0232a228, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe0);
+	reg_rmw(0x0232a428, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe4);
+	reg_rmw(0x0232a628, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfe8);
+	reg_rmw(0x0232a828, 0x00000000, 1 << 29);
+	writel(0xF800F8C0, 0x0232bfec);
+
+	/*Enable pll via the pll_ctrl 0x0014*/
+	writel(0xe0000000, 0x0232bff4)
+		;
+
+	/*Waiting for SGMII Serdes PLL lock.*/
+	for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--)
+		;
+
+	for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--)
+		;
+
+	for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--)
+		;
+
+	for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--)
+		;
+
+	chip_delay(45000);
+}
+
+void sgmii_serdes_shutdown()
+{
+	reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320228, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfe4, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320428, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfe8, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320628, 1 << 29, 1 << 29);
+	reg_rmw(0x0232bfec, 0, 3 << 29 | 3 << 13);
+	reg_rmw(0x02320828, 1 << 29, 1 << 29);
+
+	reg_rmw(0x02320034, 0, 3 << 29);
+	reg_rmw(0x02320010, 1 << 28, 1 << 28);
+}
+
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
index 985db8e..33c7551 100644
--- a/include/configs/k2hk_evm.h
+++ b/include/configs/k2hk_evm.h
@@ -106,6 +106,23 @@
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  20
 #define CONFIG_ENV_EEPROM_IS_ON_I2C
 
+/* Network Configuration */
+#define CONFIG_ETH_PHY_MARVEL_88E1111
+
+#define CONFIG_DRIVER_TI_KEYSTONE_NET
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT		32
+#define CONFIG_NET_MULTI
+#define CONFIG_GET_LINK_STATUS_ATTEMPTS 5
+
+#define CONFIG_SYS_SGMII_REFCLK_MHZ	312
+#define CONFIG_SYS_SGMII_LINERATE_MHZ	1250
+#define	CONFIG_SYS_SGMII_RATESCALE	2
+
 /* NAND Configuration */
 #define CONFIG_NAND_DAVINCI
 #define CONFIG_SYS_NAND_CS		2
@@ -179,24 +196,45 @@
 	"addr_fs=0x82000000\0"						\
 	"addr_ubi=0x82000000\0"						\
 	"fdt_high=0xffffffff\0"						\
+	"name_fdt=uImage-k2hk-evm.dtb\0"				\
+	"name_fs=arago-console-image.cpio.gz\0"				\
+	"name_kern=uImage-keystone-evm.bin\0"				\
+	"name_mon=skern-keystone-evm.bin\0"				\
+	"name_uboot=u-boot-spi-keystone-evm.gph\0"			\
+	"name_ubi=keystone-evm-ubifs.ubi\0"				\
 	"run_mon=mon_install ${addr_mon}\0"				\
 	"run_kern=bootm ${addr_kern} - ${addr_fdt}\0"			\
+	"init_net=run args_all args_net\0"				\
 	"init_ubi=run args_all args_ubi; "				\
 		"ubi part ubifs; ubifsmount boot\0"			\
+	"get_fdt_net=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0"	\
 	"get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0"		\
+	"get_kern_net=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0"	\
 	"get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0"		\
+	"get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0"	\
 	"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0"		\
+	"get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0"	\
 	"burn_uboot=sf probe; sf erase 0 0x100000; "			\
 		"sf write ${addr_uboot} 0 ${filesize}\0"		\
 	"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0"	\
 	"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs "	\
 		"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0"	\
+	"args_net=setenv bootargs ${bootargs} rootfstype=nfs "		\
+		"root=/dev/nfs rw nfsroot=${serverip}:${nfs_root},"	\
+		"${nfs_options} ip=dhcp\0"				\
+	"nfs_options=v3,tcp,rsize=4096,wsize=4096\0"			\
+	"get_fdt_ramfs=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0"	\
+	"get_kern_ramfs=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0"	\
+	"get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0"	\
+	"get_fs_ramfs=dhcp ${addr_fs} ${tftp_root}/${name_fs}\0"	\
+	"get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\0"	\
 	"burn_ubi=nand erase.part ubifs; "				\
 		"nand write ${addr_ubi} ubifs ${filesize}\0"		\
 	"init_ramfs=run args_all args_ramfs get_fs_ramfs\0"		\
 	"args_ramfs=setenv bootargs ${bootargs} earlyprintk "		\
 		"rdinit=/sbin/init rw root=/dev/ram0 "			\
 		"initrd=0x802000000,9M\0"				\
+	"no_post=1\0"							\
 	"mtdparts=mtdparts=davinci_nand.0:"				\
 		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
 #define CONFIG_BOOTCOMMAND						\
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (9 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:12     ` Tom Rini
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri
                     ` (2 subsequent siblings)
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

From: Rex Chang <rchang@ti.com>

Currently davinci spi driver supports only bus 0 cs 0.
This patch allows driver to support bus 1 and bus 2 with
configurable number of chip selects. Also defaults are
selected in a way to avoid regression on other platforms
that uses davinci spi driver and has only one spi bus.

Signed-off-by: Rex Chang <rchang@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 drivers/spi/davinci_spi.c |   62 ++++++++++++++++++++++++++++++++++++++++++---
 drivers/spi/davinci_spi.h |   33 ++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index e3fb321..c708a04 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -23,7 +23,7 @@ void spi_init()
 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 			unsigned int max_hz, unsigned int mode)
 {
-	struct davinci_spi_slave	*ds;
+	struct davinci_spi_slave        *ds;
 
 	if (!spi_cs_is_valid(bus, cs))
 		return NULL;
@@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	if (!ds)
 		return NULL;
 
-	ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
+	ds->slave.bus = bus;
+	ds->slave.cs = cs;
+
+	switch (bus) {
+	case SPI0_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+		break;
+#ifdef CONFIG_SYS_SPI1
+	case SPI1_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
+		break;
+#endif
+#ifdef CONFIG_SYS_SPI2
+	case SPI2_BUS:
+		ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
+		break;
+#endif
+	default: /* Invalid bus number */
+		return NULL;
+	}
+
 	ds->freq = max_hz;
 
 	return &ds->slave;
@@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave)
 	writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
 
 	/* CS, CLK, SIMO and SOMI are functional pins */
-	writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
+	writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK |
 		SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
 
 	/* setup format */
@@ -262,9 +282,43 @@ out:
 	return 0;
 }
 
+#ifdef CONFIG_SYS_SPI1
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+	if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS))
+		return 1;
+	return 0;
+}
+#else
+static int bus1_cs_valid(unsigned int bus, unsigned int cs)
+{
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_SPI2
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+	if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS))
+		return 1;
+	return 0;
+}
+#else
+static int bus2_cs_valid(unsigned int bus, unsigned int cs)
+{
+	return 0;
+}
+#endif
+
 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 {
-	return bus == 0 && cs == 0;
+	if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS))
+		return 1;
+	else if (bus1_cs_valid(bus, cs))
+		return 1;
+	else if (bus2_cs_valid(bus, cs))
+		return 1;
+	return 0;
 }
 
 void spi_cs_activate(struct spi_slave *slave)
diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h
index 33f69b5..d4612d3 100644
--- a/drivers/spi/davinci_spi.h
+++ b/drivers/spi/davinci_spi.h
@@ -74,6 +74,39 @@ struct davinci_spi_regs {
 /* SPIDEF */
 #define SPIDEF_CSDEF0_MASK	BIT(0)
 
+#define SPI0_BUS		0
+#define SPI0_BASE		CONFIG_SYS_SPI_BASE
+/*
+ * Define default SPI0_NUM_CS as 1 for existing platforms that uses this
+ * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS
+ * if more than one CS is supported and by defining CONFIG_SYS_SPI0.
+ */
+#ifndef CONFIG_SYS_SPI0
+#define SPI0_NUM_CS		1
+#else
+#define SPI0_NUM_CS		CONFIG_SYS_SPI0_NUM_CS
+#endif
+
+/*
+ * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and
+ * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI1
+#define SPI1_BUS		1
+#define SPI1_NUM_CS		CONFIG_SYS_SPI1_NUM_CS
+#define SPI1_BASE		CONFIG_SYS_SPI1_BASE
+#endif
+
+/*
+ * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and
+ * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus
+ */
+#ifdef CONFIG_SYS_SPI2
+#define SPI2_BUS		2
+#define SPI2_NUM_CS		CONFIG_SYS_SPI2_NUM_CS
+#define SPI2_BASE		CONFIG_SYS_SPI2_BASE
+#endif
+
 struct davinci_spi_slave {
 	struct spi_slave slave;
 	struct davinci_spi_regs *regs;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (10 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select Murali Karicheri
@ 2014-02-20 17:55   ` Murali Karicheri
  2014-02-25 22:12     ` Tom Rini
  2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
  2014-02-25 22:49   ` Karicheri, Muralidharan
  13 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-02-20 17:55 UTC (permalink / raw)
  To: u-boot

currently only spi0 is enabled on k2hk evm. This
configuration update is needed to enable spi1 and spi2.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
 include/configs/k2hk_evm.h |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h
index 33c7551..861010a 100644
--- a/include/configs/k2hk_evm.h
+++ b/include/configs/k2hk_evm.h
@@ -85,7 +85,16 @@
 #define CONFIG_SPI_FLASH
 #define CONFIG_SPI_FLASH_STMICRO
 #define CONFIG_DAVINCI_SPI
+#define CONFIG_SYS_SPI0
 #define CONFIG_SYS_SPI_BASE		K2HK_SPI_BASE
+#define CONFIG_SYS_SPI0_NUM_CS		4
+#define CONFIG_SYS_SPI1
+#define CONFIG_SYS_SPI1_BASE            K2HK_SPI1_BASE
+#define CONFIG_SYS_SPI1_NUM_CS		4
+#define CONFIG_SYS_SPI2
+#define CONFIG_SYS_SPI2_NUM_CS		4
+#define CONFIG_SYS_SPI2_BASE            K2HK_SPI2_BASE
+#define CONFIG_CMD_SPI
 #define CONFIG_SYS_SPI_CLK		clk_get_rate(K2HK_LPSC_EMIF25_SPI)
 #define CONFIG_SF_DEFAULT_SPEED		30000000
 #define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (11 preceding siblings ...)
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri
@ 2014-02-25 22:10   ` Tom Rini
  2014-02-27 16:18     ` Karicheri, Muralidharan
  2014-03-12 19:21     ` Murali Karicheri
  2014-02-25 22:49   ` Karicheri, Muralidharan
  13 siblings, 2 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:10 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:

> This patch series add support for keystone2 SoC and K2HK EVM

In general, you ran checkpatch.pl right?  I see some '#define<tab>'
cases that need manual fixing up as well.  Further comments and acks
coming.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/97d00e35/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
@ 2014-02-25 22:10     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:10 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:03PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> The keystone2 SOC requires to fix all 32 bit aliased addresses
> to their 36 physical format. This has to happen after all fdt
> nodes are added or modified.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/a5326cc6/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile Murali Karicheri
@ 2014-02-25 22:10     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:10 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:04PM -0500, Murali Karicheri wrote:

> The NOPED_OBJ_FILES, dumpimage and mkimage object file
> entries are to be kept sorted. This patch fix this issue.
> 
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/391164dc/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:05PM -0500, Murali Karicheri wrote:

> This patch add support for gpimage format as a preparatory
> patch for porting u-boot for keystone2 devices and is
> based on omapimage format. It re-uses gph header to store the
> size and loadaddr as done in omapimage.c
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/8f948a09/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:06PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> This patch add basic support for the architecture timer found on recent
> ARMv7 based SoCs.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/ea263ed2/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  2014-02-26  4:01     ` Scott Wood
  1 sibling, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:07PM -0500, Murali Karicheri wrote:

> This patch introduces a configurable mechanism to disable
> subpage writes in the DaVinci NAND driver.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/25e8819f/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:08PM -0500, Murali Karicheri wrote:

> This patch moves the davinci i2c_defs.h file to drivers.i2c directory.
> It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.
> 
> Not used "git mv" command to move the file because small part of
> it with definitions specific for Davinci SOCs has to remain in the
> arch/arm/include/asm/arch-davinci.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/6f026da8/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:09PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
[snip]
> - * SPDX-License-Identifier:	GPL-2.0+
> + * SPDX-License-Identifier:     GPL-2.0+

Don't change whitespace.

> +static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
> +						(struct i2c_regs *)I2C_BASE;

So you're going to need the i2c driver in SPL?

[snip]
> -	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
> -	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
> -	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
> -	REG(I2C_SCLH) = div - REG(I2C_SCLL);
> +	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
> +	REG(&(i2c_base->i2c_psc)) = psc;
> +	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100;
> +	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));

Code is equivalent but we lost the comments about what's being done,
please fix.  I think this is the only place but please double check,
thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/4b2f5a76/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  2014-03-03 18:20       ` Murali Karicheri
                         ` (2 more replies)
  0 siblings, 3 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler
> SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please
> refer the ti/k2hk_evm/README for details on the board, build and other
> information.
> 
> This patch add support for keystone architecture and k2hk evm.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
> Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
[snip]
> diff --git a/Makefile b/Makefile
> index 47a03e3..ea2a387 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -491,6 +491,23 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
>  			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
>  		cat $(obj)u-boot.img >> $@
>  
> +$(obj)u-boot-spi.gph:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
> +		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
> +			-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
> +			-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
> +		$(OBJCOPY) ${OBJCFLAGS} -I binary \
> +			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
> +			$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
> +		cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
> +
> +$(obj)u-boot-nand.gph:	$(obj)u-boot.bin
> +		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
> +			-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
> +			-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
> +		@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
> +		@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
> +		@rm $(obj)zero.bin

First, these need re-writing for Kbuild.  Second, we don't ever use
u-boot-nand.gph or talk about it in the README, do we?

[snip]
> +void init_pll(const struct pll_init_data *data)
> +{
> +	u32 tmp, tmp_ctl, pllm, plld, pllod, bwadj;
> +
> +	pllm = data->pll_m - 1;
> +	plld = (data->pll_d - 1) & PLL_DIV_MASK;
> +	pllod = (data->pll_od - 1) & PLL_CLKOD_MASK;
> +
> +	if (data->pll == MAIN_PLL) {
> +		sdelay(210000);

Comments on the delay please.

> diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk
> new file mode 100644
> index 0000000..1c8769c
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/config.mk
> @@ -0,0 +1,15 @@
> +# (C) Copyright 2012-2014
> +#     Texas Instruments Incorporated, <www.ti.com>
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float

This is incorrect and not needed.

> +# =========================================================================
> +#
> +# Supply options according to compiler version
> +#
> +# =========================================================================
> +PF_CPPFLAGS_SLB +=$(call cc-option,-mshort-load-bytes,\
> +		    $(call cc-option,-malignment-traps,))
> +PLATFORM_RELFLAGS += $(PF_CPPFLAGS_SLB)

Also not needed.

> diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c
> new file mode 100644
> index 0000000..1b7e52a
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/keystone/init.c
[snip]
> +void reset_cpu(ulong addr)
> +{
> +	volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8);
> +	u32 tmp;
> +
> +	tmp = *rstctrl & 0xffff0000;
> +	*rstctrl = tmp | 0x5a69;
> +
> +	*rstctrl &= 0xfffe0000;

Comments / define these please.

> +++ b/arch/arm/cpu/armv7/keystone/psc.c
[snip]
> +/*
> + * FUNCTION PURPOSE: Wait for end of transitional state
> + *
> + * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
> + *              to be complete.
> + *
> + *              Since this is boot loader code it is *ASSUMED* that interrupts
> + *              are disabled and no other core is mucking around with the psc
> + *              at the same time.
> + *
> + *              Returns 0 when the domain is free. Returns -1 if a timeout
> + *              occurred waiting for the completion.

Rewrap these lines please, and anywhere else things are too long.

> +++ b/arch/arm/cpu/armv7/keystone/spl.c
[snip]
> +u32 spl_boot_device(void)
> +{
> +#if defined(CONFIG_SPL_SPI_LOAD)
> +	return BOOT_DEVICE_SPI;
> +#else
> +	puts("Unknown boot device\n");
> +	hang();
> +#endif

return -EINVAL (or define and use BOOT_DEVICE_UNKNOWN) and fall back to
the common hang() case please.

> +	u32	__pad0;

General form is resvN.

[snip]
> +struct davinci_emif_regs {
> +	u_int32_t	ercsr;

Generally we do uint32_t

[snip]
> +#define	REG(addr)	(*(volatile unsigned int *)(addr))
> +#define REG_P(addr)	((volatile unsigned int *)(addr))
> +
> +typedef volatile unsigned int	dv_reg;
> +typedef volatile unsigned int	*dv_reg_p;

Where are we using this?  This looks like older davinci drivers that
aren't being proper about using structs to define the hardware and need
to be converted as part of this effort.  I'm not disagreeable with
seeing that be a later part of the initial series, since you'll have to
convert davinci stuff too and I realize you might not have easy access
to the davinci parts for run time testing of the conversion so having K2
work will be important.

> +++ b/board/ti/k2hk_evm/README
[snip]

What's missing here and I'd like to see is flashing instructions.

> +Build instructions:
> +===================
> +
> +To build u-boot.bin
> +  >make k2hk_evm_config
> +  >make u-boot-spi.gph
> +
> +To build u-boot-spi.gph
> +  >make k2hk_evm_config
> +  >make u-boot-spi.gph

We need to use CONFIG_SPL_TARGET so that make all just works.

> +				if (err < 0)
> +					printf("error deleting linux,initrd-start\n");

Here and elsewhere, puts when we aren't using format chars.

> diff --git a/boards.cfg b/boards.cfg
> index a8336cc..1690315 100644
> --- a/boards.cfg
> +++ b/boards.cfg

Please make sure that the entry is correctly sorted, see the top of
boards.cfg.

> +++ b/include/configs/k2hk_evm.h
> @@ -0,0 +1,221 @@
> +/*
> + * Configuration header file for TI's k2hk-evm
> + *
> + * (C) Copyright 2012-2014
> + *     Texas Instruments Incorporated, <www.ti.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#ifndef __CONFIG_H

Please use __CONFIG_K2HK_EVM_H

> +/* Platform type */
> +#define CONFIG_SOC_K2HK
> +#define CONFIG_K2HK_EVM

Make sure we use these.

> +
> +/* U-Boot Build Configuration */
> +#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is a 2nd stage loader */

So there's a level before SPL that is doing a certain amount of init we
don't want to re-do?

> +#define CONFIG_SYS_DCACHE_OFF

Really?

> +#define CONFIG_SYS_MALLOC_LEN		(1024 << 10)	/* 1 MiB */

This is pretty small, especially since we care about UBI.

> +#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
> +#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + 32 << 20)

Please see doc/README.memory-test

> +/* SPL SPI Loader Configuration */
> +#define CONFIG_SPL_TEXT_BASE		0x0c200000
> +#define CONFIG_SPL_PAD_TO		65536
> +#define CONFIG_SPL_MAX_SIZE		(CONFIG_SPL_PAD_TO - 8)

Please explain this a bit more, esp since SPL_PAD_TO should take into
account the header size already...

> +#define CONFIG_SPL_BSS_START_ADDR	(CONFIG_SPL_TEXT_BASE +		\
> +					 CONFIG_SPL_MAX_SIZE)
> +#define CONFIG_SPL_BSS_MAX_SIZE		(32 * 1024)

Do we really want SPL BSS in early ram (I don't want to get the name of
the type wrong) rather than DDR?

> +#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR +	\
> +					 CONFIG_SPL_BSS_MAX_SIZE)
> +#define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)

Same.

> +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }

Please use the default table.

> +#define PART_BOOT			"1024k(bootloader)ro,"
> +#define PART_PARAMS			"512k(params)ro,"
> +#define PART_UBI			"-(ubifs)"
> +#define MTDPARTS_DEFAULT		"mtdparts=davinci_nand.0:"	\
> +					PART_BOOT PART_PARAMS PART_UBI

Please just set these outright.

> +/* U-Boot command configuration */
> +#include <config_cmd_default.h>
> +#undef CONFIG_CMD_BDI

Why?

> +#undef CONFIG_CMD_FLASH

Shouldn't be needed.

> +#undef CONFIG_CMD_FPGA
> +#undef CONFIG_CMD_SETGETDCR

Same.

> +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "

Not needed.

> +	"fdt_high=0xffffffff\0"						\

Please don't do this, set it to the top of kernel low mem.

> +	"mtdparts=mtdparts=davinci_nand.0:"				\
> +		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"

Now you're not using the mtdparts you define, this shouldn't be needed.

> +/* Linux interfacing */
> +#define CONFIG_CMDLINE_TAG
> +#define CONFIG_SETUP_MEMORY_TAGS

OF/FDT things should be down here.

> +#define LINUX_BOOT_PARAM_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x100)

Just use this in the code.

Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/d83ae6bf/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver Murali Karicheri
@ 2014-02-25 22:11     ` Tom Rini
  2014-03-12 19:04       ` Murali Karicheri
  0 siblings, 1 reply; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:11 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> Ethernet driver configures the CPSW, SGMI and Phy and uses
> the the Navigator APIs. The driver supports 4 Ethernet ports and
> can work with only one port at a time.

First, can we just use things in a "dumb" mode and use the existing CPSW
driver?  Or are there use cases we need to worry about here with a
bigger / more robust network driver?

> Port configurations are defined in board.c.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
[snip]
> +/*#define chipLmbd(x,y) _lmbd(x,y) */

Don't add unused code.

> +/* Marvell 88E1111 PHY ID */
> +#define PHY_MARVELL_88E1111		(0x01410cc0)

More on this later.

> +/* EMAC MDIO Registers Structure */
> +struct mdio_regs {
> +	dv_reg		VERSION;
> +	dv_reg		CONTROL;

Why caps?

> +++ b/drivers/net/keystone_net.c

Generic problem, please use phylib.

> +#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)

We have debug() already.

> +#ifdef KEYSTONE2_EMAC_GIG_ENABLE
> +#define emac_gigabit_enable(x)	keystone2_eth_gigabit_enable(x)
> +#else
> +#define emac_gigabit_enable(x)	/* no gigabit to enable */
> +#endif

Do we need to do this?

> +static void chip_delay(u32 del)
> +{
> +	volatile unsigned int i;
> +
> +	for (i = 0; i < (del / 8); i++)
> +		;
> +}

Use one of the generic delays please.

> +/* PHY functions for a generic PHY */
> +static int __attribute__((unused)) gen_init_phy(int phy_addr)

Why are we adding tons of functions that we mark as unused?

> +#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
> +	int j;
> +
> +	for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
> +	     j++) {
> +#endif

New config option, do we really need this as an option?

> +void sgmii_serdes_setup_156p25mhz()
> +{
> +	unsigned int cnt;
> +
> +	reg_rmw(0x0232a000, 0x00800000, 0xffff0000);

Please comment on what we're doing here, and why we aren't using a
struct to describe whatever is at 0x0232a000 ?

> +void sgmii_serdes_shutdown()
> +{
> +	reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);

Same.

Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/a97bd1cf/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select Murali Karicheri
@ 2014-02-25 22:12     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:12 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:13PM -0500, Murali Karicheri wrote:

> From: Rex Chang <rchang@ti.com>
> 
> Currently davinci spi driver supports only bus 0 cs 0.
> This patch allows driver to support bus 1 and bus 2 with
> configurable number of chip selects. Also defaults are
> selected in a way to avoid regression on other platforms
> that uses davinci spi driver and has only one spi bus.
> 
> Signed-off-by: Rex Chang <rchang@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> ---
>  drivers/spi/davinci_spi.c |   62 ++++++++++++++++++++++++++++++++++++++++++---
>  drivers/spi/davinci_spi.h |   33 ++++++++++++++++++++++++
>  2 files changed, 91 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
> index e3fb321..c708a04 100644
> --- a/drivers/spi/davinci_spi.c
> +++ b/drivers/spi/davinci_spi.c
> @@ -23,7 +23,7 @@ void spi_init()
>  struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
>  			unsigned int max_hz, unsigned int mode)
>  {
> -	struct davinci_spi_slave	*ds;
> +	struct davinci_spi_slave        *ds;

Drop this whitespace change please.   Then you can add:

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/2c952e2c/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri
@ 2014-02-25 22:12     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:12 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:14PM -0500, Murali Karicheri wrote:

> currently only spi0 is enabled on k2hk evm. This
> configuration update is needed to enable spi1 and spi2.
> 
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/960b8732/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver Murali Karicheri
@ 2014-02-25 22:12     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:12 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 20, 2014 at 12:55:11PM -0500, Murali Karicheri wrote:

> From: Vitaly Andrianov <vitalya@ti.com>
> 
> Multicore navigator consists of Network Coprocessor (NetCP) and
> Queue Manager sub system. More details on the hardware can
> be obtained from the following links:-
> 
> Network Coprocessor: http://www.ti.com/lit/pdf/sprugz6
> Multicore Navigator: http://www.ti.com/lit/pdf/sprugr9
> 
> Multicore navigator driver implements APIs to configure
> the Queue Manager and NetCP Pkt DMA.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> Signed-off-by: WingMan Kwok <w-kwok2@ti.com>

Acked-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140225/9dceb696/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
                     ` (12 preceding siblings ...)
  2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
@ 2014-02-25 22:49   ` Karicheri, Muralidharan
  2014-02-25 22:51     ` Tom Rini
  13 siblings, 1 reply; 716+ messages in thread
From: Karicheri, Muralidharan @ 2014-02-25 22:49 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Karicheri, Muralidharan
>Sent: Thursday, February 20, 2014 12:55 PM
>To: u-boot at lists.denx.de; Rini, Tom
>Cc: Karicheri, Muralidharan
>Subject: [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
>
>This patch series add support for keystone2 SoC and K2HK EVM
>
>Change history:
>	v2
>	 - Review comments incorporated. Following are major comments
>	   addressed
>		- split network driver to navigator driver + ethernet
>		  driver
>	 	- replaced register base + offset implemenation with struct
>	   		based register access implementation
>	 	- Added Readme for NAND no subpage write option
>	 	- re-use code for davinci i2c driver on keystone2 with updates
>		- clock-k2hk.c merged to clock.c
>		- currently keeping board specific getclk() command. See the thread
>		  for the rational.
>	 - Added update to davinci spi driver to re-use on keystone
>
>	v1
>	 - added separate patch for sorting tools/Makefile entries
>	 - reworked gpimage patch to allow more re-use across omapimage/gpimage
>	 - dropped patch related to ubifs file size
>	 - added keystone SoC and K2HK EVM support
>
>	v0
>	 - preparatory patch for keystone
>
>Murali Karicheri (5):
>  tools: sort the entries in Makefile
>  tools: mkimage: add support for gpimage format
>  NAND: DaVinci: allow forced disable of subpage writes
>  i2c, davinci: move i2c_defs.h to the drivers/i2c directory
>  k2hk-evm: add configuration for spi1 and spi2 support
>
>Rex Chang (1):
>  spi: davinci: add support for multiple bus and chip select
>
>Vitaly Andrianov (6):
>  fdt: call ft_board_setup_ex() at the end of image_setup_libfdt()
>  arm: add support for arch timer
>  i2c, davinci: add support for multiple i2c buses
>  k2hk: add support for k2hk SOC and EVM
>  keystone2: add keystone multicore navigator driver
>  keystone2: net: add keystone ethernet driver
>
> Makefile                                           |   19 +
> README                                             |    5 +
> arch/arm/cpu/armv7/keystone/Makefile               |   18 +
> arch/arm/cpu/armv7/keystone/aemif.c                |   71 ++
> arch/arm/cpu/armv7/keystone/clock.c                |  313 +++++++
> arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124 +++
> arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131 +++
> arch/arm/cpu/armv7/keystone/config.mk              |   15 +
> arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++
> arch/arm/cpu/armv7/keystone/init.c                 |   56 ++
> arch/arm/cpu/armv7/keystone/keystone_nav.c         |  376 +++++++++
> arch/arm/cpu/armv7/keystone/msmc.c                 |   68 ++
> arch/arm/cpu/armv7/keystone/psc.c                  |  238 ++++++
> arch/arm/cpu/armv7/keystone/spl.c                  |   45 +
> arch/arm/include/asm/arch-davinci/i2c_defs.h       |   71 +-
> arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++
> arch/arm/include/asm/arch-keystone/clock.h         |   17 +
> arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 +++
> arch/arm/include/asm/arch-keystone/emac_defs.h     |  250 ++++++
> arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 ++
> arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  145 ++++
> arch/arm/include/asm/arch-keystone/hardware.h      |  175 ++++
> arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 +
> arch/arm/include/asm/arch-keystone/keystone_nav.h  |  193 +++++
> arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 +
> arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++
> arch/arm/include/asm/arch-keystone/spl.h           |   12 +
> arch/arm/lib/Makefile                              |    1 +
> arch/arm/lib/arch_timer.c                          |   58 ++
> board/ti/k2hk_evm/Makefile                         |    9 +
> board/ti/k2hk_evm/README                           |   56 ++
> board/ti/k2hk_evm/board.c                          |  301 +++++++
> board/ti/k2hk_evm/ddr3.c                           |  269 ++++++
> boards.cfg                                         |    1 +
> common/image-fdt.c                                 |    5 +
> common/image.c                                     |    1 +
> drivers/i2c/davinci_i2c.c                          |  345 ++++----
> drivers/i2c/davinci_i2c.h                          |   78 ++
> drivers/mtd/nand/davinci_nand.c                    |    3 +
> drivers/net/Makefile                               |    1 +
> drivers/net/keystone_net.c                         |  859 ++++++++++++++++++++
> drivers/serial/ns16550.c                           |    8 +
> drivers/spi/davinci_spi.c                          |   62 +-
> drivers/spi/davinci_spi.h                          |   33 +
> include/configs/k2hk_evm.h                         |  268 ++++++
> include/fdt_support.h                              |    1 +
> include/image.h                                    |    1 +
> tools/Makefile                                     |   20 +-
> tools/gpheader.h                                   |   40 +
> tools/gpimage-common.c                             |   80 ++
> tools/gpimage.c                                    |   77 ++
> tools/imagetool.c                                  |    2 +
> tools/imagetool.h                                  |    1 +
> tools/omapimage.c                                  |  104 +--
> tools/omapimage.h                                  |    5 -
> 55 files changed, 5222 insertions(+), 313 deletions(-)  create mode 100644
>arch/arm/cpu/armv7/keystone/Makefile
> create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c
> create mode 100644 arch/arm/cpu/armv7/keystone/clock.c
> create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c
> create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c
> create mode 100644 arch/arm/cpu/armv7/keystone/config.mk
> create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c
> create mode 100644 arch/arm/cpu/armv7/keystone/init.c
> create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c
> create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c
> create mode 100644 arch/arm/cpu/armv7/keystone/psc.c  create mode 100644
>arch/arm/cpu/armv7/keystone/spl.c  create mode 100644 arch/arm/include/asm/arch-
>keystone/clock-k2hk.h
> create mode 100644 arch/arm/include/asm/arch-keystone/clock.h
> create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h
> create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h
> create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h
> create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h
> create mode 100644 arch/arm/include/asm/arch-keystone/spl.h
> create mode 100644 arch/arm/lib/arch_timer.c  create mode 100644
>board/ti/k2hk_evm/Makefile  create mode 100644 board/ti/k2hk_evm/README  create
>mode 100644 board/ti/k2hk_evm/board.c  create mode 100644 board/ti/k2hk_evm/ddr3.c
>create mode 100644 drivers/i2c/davinci_i2c.h  create mode 100644
>drivers/net/keystone_net.c  create mode 100644 include/configs/k2hk_evm.h  create
>mode 100644 tools/gpheader.h  create mode 100644 tools/gpimage-common.c  create
>mode 100644 tools/gpimage.c
>
>--
>1.7.9.5

Hi,

Please review when you get a chance.

Thanks

Murali Karicheri
Linux Kernel, Software Development

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-02-25 22:49   ` Karicheri, Muralidharan
@ 2014-02-25 22:51     ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-02-25 22:51 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/25/2014 05:49 PM, Karicheri, Muralidharan wrote:
>> -----Original Message----- From: Karicheri, Muralidharan Sent:
>> Thursday, February 20, 2014 12:55 PM To: u-boot at lists.denx.de;
>> Rini, Tom Cc: Karicheri, Muralidharan Subject: [U-Boot PATCH v2
>> 00/12] Add support for keystone2 SoC and K2HK EVM
>> 
>> This patch series add support for keystone2 SoC and K2HK EVM
>> 
>> Change history: v2 - Review comments incorporated. Following are
>> major comments addressed - split network driver to navigator
>> driver + ethernet driver - replaced register base + offset
>> implemenation with struct based register access implementation -
>> Added Readme for NAND no subpage write option - re-use code for
>> davinci i2c driver on keystone2 with updates - clock-k2hk.c
>> merged to clock.c - currently keeping board specific getclk()
>> command. See the thread for the rational. - Added update to
>> davinci spi driver to re-use on keystone
>> 
>> v1 - added separate patch for sorting tools/Makefile entries -
>> reworked gpimage patch to allow more re-use across
>> omapimage/gpimage - dropped patch related to ubifs file size -
>> added keystone SoC and K2HK EVM support
>> 
>> v0 - preparatory patch for keystone
>> 
>> Murali Karicheri (5): tools: sort the entries in Makefile tools:
>> mkimage: add support for gpimage format NAND: DaVinci: allow
>> forced disable of subpage writes i2c, davinci: move i2c_defs.h to
>> the drivers/i2c directory k2hk-evm: add configuration for spi1
>> and spi2 support
>> 
>> Rex Chang (1): spi: davinci: add support for multiple bus and
>> chip select
>> 
>> Vitaly Andrianov (6): fdt: call ft_board_setup_ex() at the end of
>> image_setup_libfdt() arm: add support for arch timer i2c,
>> davinci: add support for multiple i2c buses k2hk: add support for
>> k2hk SOC and EVM keystone2: add keystone multicore navigator
>> driver keystone2: net: add keystone ethernet driver
>> 
>> Makefile                                           |   19 + 
>> README                                             |    5 + 
>> arch/arm/cpu/armv7/keystone/Makefile               |   18 + 
>> arch/arm/cpu/armv7/keystone/aemif.c                |   71 ++ 
>> arch/arm/cpu/armv7/keystone/clock.c                |  313
>> +++++++ arch/arm/cpu/armv7/keystone/cmd_clock.c            |  124
>> +++ arch/arm/cpu/armv7/keystone/cmd_mon.c              |  131
>> +++ arch/arm/cpu/armv7/keystone/config.mk              |   15 + 
>> arch/arm/cpu/armv7/keystone/ddr3.c                 |   69 ++ 
>> arch/arm/cpu/armv7/keystone/init.c                 |   56 ++ 
>> arch/arm/cpu/armv7/keystone/keystone_nav.c         |  376
>> +++++++++ arch/arm/cpu/armv7/keystone/msmc.c                 |
>> 68 ++ arch/arm/cpu/armv7/keystone/psc.c                  |  238
>> ++++++ arch/arm/cpu/armv7/keystone/spl.c                  |   45
>> + arch/arm/include/asm/arch-davinci/i2c_defs.h       |   71 +- 
>> arch/arm/include/asm/arch-keystone/clock-k2hk.h    |  109 +++ 
>> arch/arm/include/asm/arch-keystone/clock.h         |   17 + 
>> arch/arm/include/asm/arch-keystone/clock_defs.h    |  121 +++ 
>> arch/arm/include/asm/arch-keystone/emac_defs.h     |  250 ++++++ 
>> arch/arm/include/asm/arch-keystone/emif_defs.h     |   73 ++ 
>> arch/arm/include/asm/arch-keystone/hardware-k2hk.h |  145 ++++ 
>> arch/arm/include/asm/arch-keystone/hardware.h      |  175 ++++ 
>> arch/arm/include/asm/arch-keystone/i2c_defs.h      |   17 + 
>> arch/arm/include/asm/arch-keystone/keystone_nav.h  |  193 +++++ 
>> arch/arm/include/asm/arch-keystone/nand_defs.h     |   25 + 
>> arch/arm/include/asm/arch-keystone/psc_defs.h      |   90 ++ 
>> arch/arm/include/asm/arch-keystone/spl.h           |   12 + 
>> arch/arm/lib/Makefile                              |    1 + 
>> arch/arm/lib/arch_timer.c                          |   58 ++ 
>> board/ti/k2hk_evm/Makefile                         |    9 + 
>> board/ti/k2hk_evm/README                           |   56 ++ 
>> board/ti/k2hk_evm/board.c                          |  301
>> +++++++ board/ti/k2hk_evm/ddr3.c                           |  269
>> ++++++ boards.cfg                                         |    1
>> + common/image-fdt.c                                 |    5 + 
>> common/image.c                                     |    1 + 
>> drivers/i2c/davinci_i2c.c                          |  345
>> ++++---- drivers/i2c/davinci_i2c.h                          |
>> 78 ++ drivers/mtd/nand/davinci_nand.c                    |    3
>> + drivers/net/Makefile                               |    1 + 
>> drivers/net/keystone_net.c                         |  859
>> ++++++++++++++++++++ drivers/serial/ns16550.c
>> |    8 + drivers/spi/davinci_spi.c                          |
>> 62 +- drivers/spi/davinci_spi.h                          |   33
>> + include/configs/k2hk_evm.h                         |  268
>> ++++++ include/fdt_support.h                              |    1
>> + include/image.h                                    |    1 + 
>> tools/Makefile                                     |   20 +- 
>> tools/gpheader.h                                   |   40 + 
>> tools/gpimage-common.c                             |   80 ++ 
>> tools/gpimage.c                                    |   77 ++ 
>> tools/imagetool.c                                  |    2 + 
>> tools/imagetool.h                                  |    1 + 
>> tools/omapimage.c                                  |  104 +-- 
>> tools/omapimage.h                                  |    5 - 55
>> files changed, 5222 insertions(+), 313 deletions(-)  create mode
>> 100644 arch/arm/cpu/armv7/keystone/Makefile create mode 100644
>> arch/arm/cpu/armv7/keystone/aemif.c create mode 100644
>> arch/arm/cpu/armv7/keystone/clock.c create mode 100644
>> arch/arm/cpu/armv7/keystone/cmd_clock.c create mode 100644
>> arch/arm/cpu/armv7/keystone/cmd_mon.c create mode 100644
>> arch/arm/cpu/armv7/keystone/config.mk create mode 100644
>> arch/arm/cpu/armv7/keystone/ddr3.c create mode 100644
>> arch/arm/cpu/armv7/keystone/init.c create mode 100644
>> arch/arm/cpu/armv7/keystone/keystone_nav.c create mode 100644
>> arch/arm/cpu/armv7/keystone/msmc.c create mode 100644
>> arch/arm/cpu/armv7/keystone/psc.c  create mode 100644 
>> arch/arm/cpu/armv7/keystone/spl.c  create mode 100644
>> arch/arm/include/asm/arch- keystone/clock-k2hk.h create mode
>> 100644 arch/arm/include/asm/arch-keystone/clock.h create mode
>> 100644 arch/arm/include/asm/arch-keystone/clock_defs.h create
>> mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h create
>> mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h create
>> mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h 
>> create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h 
>> create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h 
>> create mode 100644
>> arch/arm/include/asm/arch-keystone/keystone_nav.h create mode
>> 100644 arch/arm/include/asm/arch-keystone/nand_defs.h create mode
>> 100644 arch/arm/include/asm/arch-keystone/psc_defs.h create mode
>> 100644 arch/arm/include/asm/arch-keystone/spl.h create mode
>> 100644 arch/arm/lib/arch_timer.c  create mode 100644 
>> board/ti/k2hk_evm/Makefile  create mode 100644
>> board/ti/k2hk_evm/README  create mode 100644
>> board/ti/k2hk_evm/board.c  create mode 100644
>> board/ti/k2hk_evm/ddr3.c create mode 100644
>> drivers/i2c/davinci_i2c.h  create mode 100644 
>> drivers/net/keystone_net.c  create mode 100644
>> include/configs/k2hk_evm.h  create mode 100644 tools/gpheader.h
>> create mode 100644 tools/gpimage-common.c  create mode 100644
>> tools/gpimage.c
>> 
>> -- 1.7.9.5
> 
> Hi,
> 
> Please review when you get a chance.

I believe things have crossed in the ether, more or less.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTDR5uAAoJENk4IS6UOR1WLwYP/2ZLO7MI8CaEzmuD+BTgGaPP
D/6M/L9OvAV3ksG+kPxBkl/oNEqd1k94WioE1R3CUk9yH8FRG71H45knAIBvGsxb
tiSnVGX2t2t4w6Bfy9C89+AufTAkG7CpPmEOQxmzF4leZ3C2BY22EdXYYThcjagk
R9GkvWH2+mxYzMuK405acfXvRIYReJwYBqm/OS0HJf5RElUjg7G7Dext7W02to4t
oq0U6jTeU4UzqO28xO80OixE3cKYj3hFvXYP+qLph8GZSyvkxSNxy2c01c/enP9y
ff3Ra/IKsmTTTMT4A2GfqusZDTYjoAU30MsIaYM6T6UXComr0zE2P97TqNQies67
PYdnsiRJ96gSl9N7GGHb6Khd4Wt7I5w6/hpdEVwrdVLiRRaRG2Fi3WTRR9p0zDpE
nDilaSA4QlVuE6TqA33lZHkroOiKMRD1TpU++zPgCZnE6bx/OcTOK9HT0Wl+d7d+
i+le0U9C7ci2nKHaP1N/5z0SNSLVbMNTwkaENTalMyNNxPoYgo1VQA5C1jEzGDrr
Tu7zXc2MaG+cz8h5E+QH3e0Ey2UJGvIp+Uj0c4x90cygTpvw1T8WCwX8TQ+8EBOI
shcGK0QbxeTu0GLVasJNrM4y3XP5FzTDzKKaVuHXfMkmWMheXgCAi+VqItnPf5jT
jaarG+AKZ7rBo8yIpDU9
=fnme
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
  2014-02-25 22:11     ` Tom Rini
@ 2014-02-26  4:01     ` Scott Wood
  2014-02-27 16:38       ` Murali Karicheri
       [not found]       ` <3E54258959B69E4282D79E01AB1F32B7046C27D5@DFLE11.ent.ti.com>
  1 sibling, 2 replies; 716+ messages in thread
From: Scott Wood @ 2014-02-26  4:01 UTC (permalink / raw)
  To: u-boot

On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
> This patch introduces a configurable mechanism to disable
> subpage writes in the DaVinci NAND driver.
> 
> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> ---
>  - Added README
>  README                          |    5 +++++
>  drivers/mtd/nand/davinci_nand.c |    3 +++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/README b/README
> index aea82be..caf60a2 100644
> --- a/README
> +++ b/README
> @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
>  - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
>  		Enables the RTC32K OSC on AM33xx based plattforms
>  
> +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
> +		Option to disable subpage write in NAND driver
> +		Example driver that use this:
> +		drivers/mtd/nand/davinci_nand.c

I'd rather this be a full list of drivers that use it, not an example.

-Scott

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
@ 2014-02-27 16:18     ` Karicheri, Muralidharan
  2014-03-12 19:21     ` Murali Karicheri
  1 sibling, 0 replies; 716+ messages in thread
From: Karicheri, Muralidharan @ 2014-02-27 16:18 UTC (permalink / raw)
  To: u-boot

>-----Original Message-----
>From: Tom Rini [mailto:tom.rini at gmail.com] On Behalf Of Rini, Tom
>Sent: Tuesday, February 25, 2014 5:11 PM
>To: Karicheri, Muralidharan
>Cc: u-boot at lists.denx.de
>Subject: Re: [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK
>EVM
>
>On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
>
>> This patch series add support for keystone2 SoC and K2HK EVM
>
>In general, you ran checkpatch.pl right?  I see some '#define<tab>'
>cases that need manual fixing up as well.  Further comments and acks coming.
>


Errors are fixed. However there are some warnings that doesn't make sense and
are left as is.

Murali
>--
>Tom

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-26  4:01     ` Scott Wood
@ 2014-02-27 16:38       ` Murali Karicheri
       [not found]       ` <3E54258959B69E4282D79E01AB1F32B7046C27D5@DFLE11.ent.ti.com>
  1 sibling, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-27 16:38 UTC (permalink / raw)
  To: u-boot

On 2/25/2014 11:01 PM, Scott Wood wrote:
> On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
>> This patch introduces a configurable mechanism to disable
>> subpage writes in the DaVinci NAND driver.
>>
>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>> ---
>>   - Added README
>>   README                          |    5 +++++
>>   drivers/mtd/nand/davinci_nand.c |    3 +++
>>   2 files changed, 8 insertions(+)
>>
>> diff --git a/README b/README
>> index aea82be..caf60a2 100644
>> --- a/README
>> +++ b/README
>> @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
>>   - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
>>   		Enables the RTC32K OSC on AM33xx based plattforms
>>   
>> +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
>> +		Option to disable subpage write in NAND driver
>> +		Example driver that use this:
>> +		drivers/mtd/nand/davinci_nand.c
> I'd rather this be a full list of drivers that use it, not an example.

There are 3 nand drivers that disable sub page write using NAND_NO_SUBPAGE_WRITE
by default.

nand/docg4.c
nand/fsl_ifc_nand.c
nand/mxs_nand.c

nand/davinci_nand.c is used across many of ti's existing davinci platforms and some of them
do enable sub page write. In Keystone platform, we want to disable this option. So to answer
your question, davinci_nand.c is the only user driver using this configuration option,
but that doesn't prevent anyone from using the option. So I want to keep this configuration
option as a generic option.

Hope this clarifies.

Murali

> -Scott
>
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
       [not found]       ` <3E54258959B69E4282D79E01AB1F32B7046C27D5@DFLE11.ent.ti.com>
@ 2014-02-27 19:21         ` Scott Wood
  2014-02-27 21:20           ` Murali Karicheri
  0 siblings, 1 reply; 716+ messages in thread
From: Scott Wood @ 2014-02-27 19:21 UTC (permalink / raw)
  To: u-boot

On Thu, 2014-02-27 at 16:14 +0000, Karicheri, Muralidharan wrote:
> >-----Original Message-----
> >From: Scott Wood [mailto:scottwood at freescale.com]
> >Sent: Tuesday, February 25, 2014 11:01 PM
> >To: Karicheri, Muralidharan
> >Cc: u-boot at lists.denx.de; Rini, Tom
> >Subject: Re: [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of
> >subpage writes
> >
> >On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
> >> This patch introduces a configurable mechanism to disable subpage
> >> writes in the DaVinci NAND driver.
> >>
> >> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> >> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> >> ---
> >>  - Added README
> >>  README                          |    5 +++++
> >>  drivers/mtd/nand/davinci_nand.c |    3 +++
> >>  2 files changed, 8 insertions(+)
> >>
> >> diff --git a/README b/README
> >> index aea82be..caf60a2 100644
> >> --- a/README
> >> +++ b/README
> >> @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
> >>  - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
> >>  		Enables the RTC32K OSC on AM33xx based plattforms
> >>
> >> +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
> >> +		Option to disable subpage write in NAND driver
> >> +		Example driver that use this:
> >> +		drivers/mtd/nand/davinci_nand.c
> >
> >I'd rather this be a full list of drivers that use it, not an example.
> 
> There are 3 drivers out there that disable sub page write using NAND_NO_SUBPAGE_WRITE
> by default. 
> 
> nand/docg4.c
> nand/fsl_ifc_nand.c
> nand/mxs_nand.c
> 
> nand/davinci_nand.c is used across many of ti's existing davinci platforms and some of them
> do enable sub page write.

And only one of them uses CONFIG_SYS_NAND_NO_SUBPAGE_WRITE, which is a
potentially confusing thing given the generic naming, and thus warrants
clear documentation.

> In Keystone platform, we want to disable this option. So to answer
> your question, davinci_nand.c is the only user driver using this configuration option,
> but that doesn't prevent anyone from using the option. So I want to keep this configuration
> option as a generic option.

That's fine.  My point is just to s/Example driver/Drivers/ so that if
someone adds this to a new driver, they (hopefully) add it to the list
in README, rather than just thinking one example is enough.

-Scott

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes
  2014-02-27 19:21         ` Scott Wood
@ 2014-02-27 21:20           ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-02-27 21:20 UTC (permalink / raw)
  To: u-boot

On 2/27/2014 2:21 PM, Scott Wood wrote:
> On Thu, 2014-02-27 at 16:14 +0000, Karicheri, Muralidharan wrote:
>>> -----Original Message-----
>>> From: Scott Wood [mailto:scottwood at freescale.com]
>>> Sent: Tuesday, February 25, 2014 11:01 PM
>>> To: Karicheri, Muralidharan
>>> Cc: u-boot at lists.denx.de; Rini, Tom
>>> Subject: Re: [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of
>>> subpage writes
>>>
>>> On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
>>>> This patch introduces a configurable mechanism to disable subpage
>>>> writes in the DaVinci NAND driver.
>>>>
>>>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>>>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>>>> ---
>>>>   - Added README
>>>>   README                          |    5 +++++
>>>>   drivers/mtd/nand/davinci_nand.c |    3 +++
>>>>   2 files changed, 8 insertions(+)
>>>>
>>>> diff --git a/README b/README
>>>> index aea82be..caf60a2 100644
>>>> --- a/README
>>>> +++ b/README
>>>> @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
>>>>   - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC:
>>>>   		Enables the RTC32K OSC on AM33xx based plattforms
>>>>
>>>> +- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
>>>> +		Option to disable subpage write in NAND driver
>>>> +		Example driver that use this:
>>>> +		drivers/mtd/nand/davinci_nand.c
>>> I'd rather this be a full list of drivers that use it, not an example.
>> There are 3 drivers out there that disable sub page write using NAND_NO_SUBPAGE_WRITE
>> by default.
>>
>> nand/docg4.c
>> nand/fsl_ifc_nand.c
>> nand/mxs_nand.c
>>
>> nand/davinci_nand.c is used across many of ti's existing davinci platforms and some of them
>> do enable sub page write.
> And only one of them uses CONFIG_SYS_NAND_NO_SUBPAGE_WRITE, which is a
> potentially confusing thing given the generic naming, and thus warrants
> clear documentation.
>
>> In Keystone platform, we want to disable this option. So to answer
>> your question, davinci_nand.c is the only user driver using this configuration option,
>> but that doesn't prevent anyone from using the option. So I want to keep this configuration
>> option as a generic option.
> That's fine.  My point is just to s/Example driver/Drivers/ so that if
> someone adds this to a new driver, they (hopefully) add it to the list
> in README, rather than just thinking one example is enough.
>
> -Scott
>
>
That is fine. I will make the change in v3.

Murali

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-02-25 22:11     ` Tom Rini
@ 2014-03-03 18:20       ` Murali Karicheri
  2014-03-03 18:29         ` Tom Rini
  2014-03-06 19:09       ` Andrianov, Vitaly
  2014-03-07 21:21       ` Murali Karicheri
  2 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-03-03 18:20 UTC (permalink / raw)
  To: u-boot


diff --git a/Makefile b/Makefile
index 47a03e3..ea2a387 100644
--- a/Makefile
+++ b/Makefile
@@ -491,6 +491,23 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
  			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
  		cat $(obj)u-boot.img >> $@
  
+$(obj)u-boot-spi.gph:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+			-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
+		$(OBJCOPY) ${OBJCFLAGS} -I binary \
+			--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
+			$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
+		cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+
+$(obj)u-boot-nand.gph:	$(obj)u-boot.bin
+		$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
+			-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+			-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
+		@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
+		@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
+		@rm $(obj)zero.bin

> First, these need re-writing for Kbuild.  Second, we don't ever use
> u-boot-nand.gph or talk about it in the README, do we?
Tom,

Will remove remove u-boot-nand.gph for time being as we didn't verify 
nand boot in this
series. What you mean by re-writing for kbuild. The u-boot-spi.gph 
target is added similar to
existing u-boot-spr (see just above this target). Could you provide an 
example?

Murali

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-03-03 18:20       ` Murali Karicheri
@ 2014-03-03 18:29         ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-03-03 18:29 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/03/2014 01:20 PM, Murali Karicheri wrote:
> 
> diff --git a/Makefile b/Makefile
> index 47a03e3..ea2a387 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -491,6 +491,23 @@ $(obj)u-boot.spr:    $(obj)u-boot.img
> $(obj)spl/u-boot-spl.bin
>              --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@
>          cat $(obj)u-boot.img >> $@
>  
> +$(obj)u-boot-spi.gph:    $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
> +        $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
> +            -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
> +            -n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
> +        $(OBJCOPY) ${OBJCFLAGS} -I binary \
> +            --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
> +            $(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
> +        cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
> +
> +$(obj)u-boot-nand.gph:    $(obj)u-boot.bin
> +        $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
> +            -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
> +            -n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
> +        @dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
> +        @cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
> +        @rm $(obj)zero.bin
> 
>> First, these need re-writing for Kbuild.  Second, we don't ever use
>> u-boot-nand.gph or talk about it in the README, do we?
> Tom,
> 
> Will remove remove u-boot-nand.gph for time being as we didn't verify
> nand boot in this
> series. What you mean by re-writing for kbuild. The u-boot-spi.gph
> target is added similar to
> existing u-boot-spr (see just above this target). Could you provide an
> example?

Yes, look at how u-boot.spr looks on master now.  Things have changed a
good bit and this needs updating again.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTFMoGAAoJENk4IS6UOR1WlpIP/Rkbl9ejGjmlvUcFQ6klnrNH
ztie7jDThbxqlnGJJJVCALCf5sWgI/W5X/IaiFtBJsAF2JE0h8HaCQjvjBU2r0vq
HSXMzBMfXXURrgbtuU8OcrkG8CUN93rQj06Q3hDNSej2cIQAuZt685G3svQ//Jnw
rvhg3rnnXFK/ypEE20ZT1bETlH76e/RAZXd/V897j53j4rnWzonQisF0P1C9Nguu
DRdH0DPQ4VaDfQ8MHAG9M0L79mSFFaDS6o9fkipEiPJjwYjoI5CNbzcd9jszcWhw
fQtkTl1B7tiD7Aqd48apytOvjO8RSrGyJ1ntdOCvnqlemvACMMO/RoWqJtOnZLD/
6PhPIN4ewYPoWop5Hf8fgSAvaYEQW7s5TnB6KKnk3MTixCtzdFOywoAqAhxZAV6p
eOglTRQ81rR702fHJBT7uNQrUGIjc6DebjtcJkEZmWNoT8TZAvpXXIqLu/3PeFna
U/Ppfq2C4SUyRXf365aODGicKhkEuRi1XseluytvHFHL3/sJZgrkRF32+/g3JBv/
haP/MVw4nGSN4dgsb/UQCBxoLHe6wWfXPktYvHN1ne1QUaXzLbHdi7TM4tejfjjS
ULjMWpaaOuPPgrkQsleAL20Ctx6oY/aArnXf1qjj+CJ0cU1hnYWOxXoOEDVVjYI+
5f9FAQtYTSgSV1uvhX9u
=k4+m
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-02-25 22:11     ` Tom Rini
  2014-03-03 18:20       ` Murali Karicheri
@ 2014-03-06 19:09       ` Andrianov, Vitaly
  2014-03-06 19:29         ` Tom Rini
  2014-03-07 21:21       ` Murali Karicheri
  2 siblings, 1 reply; 716+ messages in thread
From: Andrianov, Vitaly @ 2014-03-06 19:09 UTC (permalink / raw)
  To: u-boot

Hi Tom,

> -----Original Message-----
> From: u-boot-bounces at lists.denx.de [mailto:u-boot-
> bounces at lists.denx.de] On Behalf Of Rini, Tom
> Sent: Tuesday, February 25, 2014 5:12 PM
> To: Karicheri, Muralidharan
> Cc: Kwok, WingMan; u-boot at lists.denx.de; Nair, Sandeep
> Subject: Re: [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for
> k2hk SOC and EVM
> 
> On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:
> 
> > From: Vitaly Andrianov <vitalya@ti.com>
> >
> > k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
> > Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
> the
> > ti/k2hk_evm/README for details on the board, build and other
> > information.
> >
> > This patch add support for keystone architecture and k2hk evm.
> >
> > Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
> > Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
> > Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
> > Signed-off-by: Sandeep Nair <sandeep_n@ti.com>

[snip]
> 
> > +	"fdt_high=0xffffffff\0"						\
> 
> Please don't do this, set it to the top of kernel low mem.
> 

The EVM may have up to 8GB of DDR and u-boot can see the first 2GB
with physical address range 0x80000000-0xffffffff.  
If we don't use the "fdt_high" environment variable, u-boot relocates
the dtb to the end of that memory, which is outside of the lowmem.

Here is the part of bootlog:
-------------------------------------------------------------
## Flattened Device Tree blob at 87000000
   Booting using the fdt blob at 0x87000000
   Loading Kernel Image ... OK
OK
   Loading Device Tree to ffff1000, end fffffcab ... OK
--------------------------------------------------------------

But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That
corresponds to the physical range 0x80000000-0xaf800000.
That is why we have to use the "fdt_high=0xffffffff" environment variable.

Have I missed something I u-boot memory configuration?
Is there a way to tell u-boot to relocate fdt to the end lowmem? 

Thanks,
Vitaly



 
  

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-03-06 19:09       ` Andrianov, Vitaly
@ 2014-03-06 19:29         ` Tom Rini
  2014-03-07 16:41           ` Andrianov, Vitaly
  0 siblings, 1 reply; 716+ messages in thread
From: Tom Rini @ 2014-03-06 19:29 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/06/2014 02:09 PM, Andrianov, Vitaly wrote:
> Hi Tom,
> 
>> -----Original Message-----
>> From: u-boot-bounces at lists.denx.de [mailto:u-boot-
>> bounces at lists.denx.de] On Behalf Of Rini, Tom
>> Sent: Tuesday, February 25, 2014 5:12 PM
>> To: Karicheri, Muralidharan
>> Cc: Kwok, WingMan; u-boot at lists.denx.de; Nair, Sandeep
>> Subject: Re: [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for
>> k2hk SOC and EVM
>>
>> On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:
>>
>>> From: Vitaly Andrianov <vitalya@ti.com>
>>>
>>> k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC.
>>> Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
>> the
>>> ti/k2hk_evm/README for details on the board, build and other
>>> information.
>>>
>>> This patch add support for keystone architecture and k2hk evm.
>>>
>>> Signed-off-by: Vitaly Andrianov <vitalya@ti.com>
>>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>>> Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
>>> Signed-off-by: Sandeep Nair <sandeep_n@ti.com>
> 
> [snip]
>>
>>> +	"fdt_high=0xffffffff\0"						\
>>
>> Please don't do this, set it to the top of kernel low mem.
>>
> 
> The EVM may have up to 8GB of DDR and u-boot can see the first 2GB
> with physical address range 0x80000000-0xffffffff.  
> If we don't use the "fdt_high" environment variable, u-boot relocates
> the dtb to the end of that memory, which is outside of the lowmem.

Right.

> Here is the part of bootlog:
> -------------------------------------------------------------
> ## Flattened Device Tree blob at 87000000
>    Booting using the fdt blob at 0x87000000
>    Loading Kernel Image ... OK
> OK
>    Loading Device Tree to ffff1000, end fffffcab ... OK
> --------------------------------------------------------------
> 
> But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That
> corresponds to the physical range 0x80000000-0xaf800000.
> That is why we have to use the "fdt_high=0xffffffff" environment variable.
> 
> Have I missed something I u-boot memory configuration?
> Is there a way to tell u-boot to relocate fdt to the end lowmem? 

Yes, set fdt_high to 0xaf800000 instead :)

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTGMyjAAoJENk4IS6UOR1WGvwP/0uN28wfBHAY3u6reHUv77H4
Xq5OMMxhtS+fOSvUZORBmV22aliFIX7vckshM65KgWQkmxx0fO8zmuVRxUMdXL9R
rNGa7azCtQVTwJTvuWDxEhVLxQbIJk+9YuBGGajLG1qDpYBhkAVendpGPGt8FflX
YW5pJxMztcRm4bVFZxXZkiqzAwPDc+f/yAYD9VUHnwCImqpTEAcvF7ktUU6QpClr
D1DySfhFyV6v0r3/WRVMzsiCmQq5mOkla/dWW0xPp4fl+4trN2sQeM5fusQXd1kR
qq2M3hmYRSgo++h9mQDjhKbTmpFi/mRLuYiq0nk90tnAOBH6aOTZoKlpFaqFEO3b
/DXq2wUheKs6Y4eE1WtAB99MBkt3u4bLAR1WuVNifdGPgIsUum95WqWQdedKyu4L
nGALiBuceykkn0FvvpCa8F8LnF+3BzXY2OmY/VtfwZ3qhcW7/gzaVwPX7rLs035d
1hTJapU9LtmBcDk7Bme4OlTrQczquAo2zfDwKaR3MnPVrDHnwBfsPJ1mWVcWU4dC
ATvb8kbLM8TBgKrn/Qsx9DARkeVb+R6/WX99c2bzWtorrVU/oO632B8fDlbi02vi
bJVPc/OEMPjB9FHychiDwtBkGCt6pgu3GJ4VVviVmnH50RHKU+sC/DuNg2kmRLmf
pXfAZ0dbyhCs0uPnhbS/
=WBxm
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-03-06 19:29         ` Tom Rini
@ 2014-03-07 16:41           ` Andrianov, Vitaly
  2014-03-07 16:50             ` Tom Rini
  0 siblings, 1 reply; 716+ messages in thread
From: Andrianov, Vitaly @ 2014-03-07 16:41 UTC (permalink / raw)
  To: u-boot

Hi Tom,

[snip]
> >>
> >>> +	"fdt_high=0xffffffff\0"						\
> >>
> >> Please don't do this, set it to the top of kernel low mem.
> >>
> >
> > The EVM may have up to 8GB of DDR and u-boot can see the first 2GB
> > with physical address range 0x80000000-0xffffffff.
> > If we don't use the "fdt_high" environment variable, u-boot relocates
> > the dtb to the end of that memory, which is outside of the lowmem.
> 
[snip]

> > But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That
> > corresponds to the physical range 0x80000000-0xaf800000.
> > That is why we have to use the "fdt_high=0xffffffff" environment
> variable.
> >
> > Have I missed something I u-boot memory configuration?
> > Is there a way to tell u-boot to relocate fdt to the end lowmem?
> 
> Yes, set fdt_high to 0xaf800000 instead :)
> 

I think there is a bug in the lmb_alloc_base() and this approach doesn't
work.

else if (lmbbase < max_addr) {
	base = min(lmbbase + lmbsize, max_addr);
	base = lmb_align_down(base - size, align);
} else

For boards that have DDR@the end of 32 bit address space the
(lmbbase + lmbsize) = 0 which is < max_addr.
So, base becomes 0, and moved to the "end of DDR" - size on the next line.

I tried a quick fix in the __lmb_alloc_base() and got the fdt relocated correctly.
As I'm not sure that is only one buggy place in the lmb.c I don't want to commit
the quick fix. Let's leave the "fdt_high=0xffffffff" in the Keystone2 for awhile      
and change it later when we fix the bug.

Thanks,
Vitaly

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-03-07 16:41           ` Andrianov, Vitaly
@ 2014-03-07 16:50             ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-03-07 16:50 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/07/2014 11:41 AM, Andrianov, Vitaly wrote:
> Hi Tom,
> 
> [snip]
>>>>
>>>>> +	"fdt_high=0xffffffff\0"						\
>>>>
>>>> Please don't do this, set it to the top of kernel low mem.
>>>>
>>>
>>> The EVM may have up to 8GB of DDR and u-boot can see the first 2GB
>>> with physical address range 0x80000000-0xffffffff.
>>> If we don't use the "fdt_high" environment variable, u-boot relocates
>>> the dtb to the end of that memory, which is outside of the lowmem.
>>
> [snip]
> 
>>> But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That
>>> corresponds to the physical range 0x80000000-0xaf800000.
>>> That is why we have to use the "fdt_high=0xffffffff" environment
>> variable.
>>>
>>> Have I missed something I u-boot memory configuration?
>>> Is there a way to tell u-boot to relocate fdt to the end lowmem?
>>
>> Yes, set fdt_high to 0xaf800000 instead :)
>>
> 
> I think there is a bug in the lmb_alloc_base() and this approach doesn't
> work.
> 
> else if (lmbbase < max_addr) {
> 	base = min(lmbbase + lmbsize, max_addr);
> 	base = lmb_align_down(base - size, align);
> } else
> 
> For boards that have DDR at the end of 32 bit address space the
> (lmbbase + lmbsize) = 0 which is < max_addr.
> So, base becomes 0, and moved to the "end of DDR" - size on the next line.
> 
> I tried a quick fix in the __lmb_alloc_base() and got the fdt relocated correctly.
> As I'm not sure that is only one buggy place in the lmb.c I don't want to commit
> the quick fix. Let's leave the "fdt_high=0xffffffff" in the Keystone2 for awhile      
> and change it later when we fix the bug.

If you're committing to look at this later then yes.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTGfjRAAoJENk4IS6UOR1WxBYQAKjH1cWlziYl74cR7FhPINWd
WEn7AtPKYLXs47D8dMYvshjrg9kBgjpy3VqDKf23t3yndBUugmznV5MdmSMlx2IQ
TuNg0ICqnXt/2NxclKwxtmznohIwx2t8gJ355UP9XzGrr17lf1+WglOvBolI0R0m
VjP3eBivHDlfwLHF3MWdLjmCjGn1sVDCng2JuZZIjfoqxGto2UsDllh1CQx2O9js
tOeAY+i5cHCag8b5+6jtujZ6GICwQ0vg2qB5XFXeOYAZWY+XTvlGgQCZ27RaspRF
pBHhlOH7iftUnKOTGt/HauEnB62TSfSPjan9ww48VA861fAkrpeANjtPz9uZQKwh
Hd/Ib0XOHrfKkReerF/C+R2vJjlYBfKeEFCvF+SuZApgIMX6am4gdHWiGgZq45/Q
YemR9Exj+KJ4MYZky/a8y2z8cowck+RsnpZozojFiPlNmuvXS+qXZste42nIYTRX
puZx4+xogoaLL4HHjOuKR6QlnCSQDvyxPvLPMNw5HbrZ3Eof0Uwxu2omnJpUvx2+
v/xl6gsqcxOZ07Mz7g3sGwsG5HWZPevFK8CZd8xDFQwj/DZo4pAJO7XFj4MZTgaM
Tg3bpsvQFugK9yU/F96Uoie0EYCpCsgGPu5moOSPYB4sl8OlkHj0Mw1oq3rpWF77
2bFm9XxAOL/awEM/X2l/
=n9Wd
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-02-25 22:11     ` Tom Rini
  2014-03-03 18:20       ` Murali Karicheri
  2014-03-06 19:09       ` Andrianov, Vitaly
@ 2014-03-07 21:21       ` Murali Karicheri
  2014-03-07 21:27         ` Tom Rini
  2 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-03-07 21:21 UTC (permalink / raw)
  To: u-boot

[snip]
>> +Build instructions:
>> +===================
>> +
>> +To build u-boot.bin
>> +  >make k2hk_evm_config
>> +  >make u-boot-spi.gph
>> +
>> +To build u-boot-spi.gph
>> +  >make k2hk_evm_config
>> +  >make u-boot-spi.gph
> We need to use CONFIG_SPL_TARGET so that make all just works.

I am assuming we need to do

#define CONFIG_SPL_TARGET  "u-boot-spi.gph"

and then

./MAKEALL -a arm

  will build this image as well. Is that right?

Murali
>
>> +				if (err < 0)
>> +					printf("error deleting linux,initrd-start\n");
> Here and elsewhere, puts when we aren't using format chars.
>
>> diff --git a/boards.cfg b/boards.cfg
>> index a8336cc..1690315 100644
>> --- a/boards.cfg
>> +++ b/boards.cfg
> Please make sure that the entry is correctly sorted, see the top of
> boards.cfg.
>
>> +++ b/include/configs/k2hk_evm.h
>> @@ -0,0 +1,221 @@
>> +/*
>> + * Configuration header file for TI's k2hk-evm
>> + *
>> + * (C) Copyright 2012-2014
>> + *     Texas Instruments Incorporated, <www.ti.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0+
>> + */
>> +
>> +#ifndef __CONFIG_H
> Please use __CONFIG_K2HK_EVM_H
>
>> +/* Platform type */
>> +#define CONFIG_SOC_K2HK
>> +#define CONFIG_K2HK_EVM
> Make sure we use these.
>
>> +
>> +/* U-Boot Build Configuration */
>> +#define CONFIG_SKIP_LOWLEVEL_INIT	/* U-Boot is a 2nd stage loader */
> So there's a level before SPL that is doing a certain amount of init we
> don't want to re-do?
>
>> +#define CONFIG_SYS_DCACHE_OFF
> Really?
>
>> +#define CONFIG_SYS_MALLOC_LEN		(1024 << 10)	/* 1 MiB */
> This is pretty small, especially since we care about UBI.
>
>> +#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
>> +#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + 32 << 20)
> Please see doc/README.memory-test
>
>> +/* SPL SPI Loader Configuration */
>> +#define CONFIG_SPL_TEXT_BASE		0x0c200000
>> +#define CONFIG_SPL_PAD_TO		65536
>> +#define CONFIG_SPL_MAX_SIZE		(CONFIG_SPL_PAD_TO - 8)
> Please explain this a bit more, esp since SPL_PAD_TO should take into
> account the header size already...
>
>> +#define CONFIG_SPL_BSS_START_ADDR	(CONFIG_SPL_TEXT_BASE +		\
>> +					 CONFIG_SPL_MAX_SIZE)
>> +#define CONFIG_SPL_BSS_MAX_SIZE		(32 * 1024)
> Do we really want SPL BSS in early ram (I don't want to get the name of
> the type wrong) rather than DDR?
>
>> +#define CONFIG_SYS_SPL_MALLOC_START	(CONFIG_SPL_BSS_START_ADDR +	\
>> +					 CONFIG_SPL_BSS_MAX_SIZE)
>> +#define CONFIG_SYS_SPL_MALLOC_SIZE	(32 * 1024)
> Same.
>
>> +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
> Please use the default table.
>
>> +#define PART_BOOT			"1024k(bootloader)ro,"
>> +#define PART_PARAMS			"512k(params)ro,"
>> +#define PART_UBI			"-(ubifs)"
>> +#define MTDPARTS_DEFAULT		"mtdparts=davinci_nand.0:"	\
>> +					PART_BOOT PART_PARAMS PART_UBI
> Please just set these outright.
>
>> +/* U-Boot command configuration */
>> +#include <config_cmd_default.h>
>> +#undef CONFIG_CMD_BDI
> Why?
>
>> +#undef CONFIG_CMD_FLASH
> Shouldn't be needed.
>
>> +#undef CONFIG_CMD_FPGA
>> +#undef CONFIG_CMD_SETGETDCR
> Same.
>
>> +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
> Not needed.
>
>> +	"fdt_high=0xffffffff\0"						\
> Please don't do this, set it to the top of kernel low mem.
>
>> +	"mtdparts=mtdparts=davinci_nand.0:"				\
>> +		"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
> Now you're not using the mtdparts you define, this shouldn't be needed.
>
>> +/* Linux interfacing */
>> +#define CONFIG_CMDLINE_TAG
>> +#define CONFIG_SETUP_MEMORY_TAGS
> OF/FDT things should be down here.
>
>> +#define LINUX_BOOT_PARAM_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x100)
> Just use this in the code.
>
> Thanks!
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
  2014-03-07 21:21       ` Murali Karicheri
@ 2014-03-07 21:27         ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-03-07 21:27 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/07/2014 04:21 PM, Murali Karicheri wrote:
> [snip]
>>> +Build instructions:
>>> +===================
>>> +
>>> +To build u-boot.bin
>>> +  >make k2hk_evm_config
>>> +  >make u-boot-spi.gph
>>> +
>>> +To build u-boot-spi.gph
>>> +  >make k2hk_evm_config
>>> +  >make u-boot-spi.gph
>> We need to use CONFIG_SPL_TARGET so that make all just works.
> 
> I am assuming we need to do
> 
> #define CONFIG_SPL_TARGET  "u-boot-spi.gph"
> 
> and then
> 
> ./MAKEALL -a arm
> 
>  will build this image as well. Is that right?

Yes.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJTGjnAAAoJENk4IS6UOR1WJyIQAK6bDPHLGoVdi2v+1jktrQ/X
H+QTdFvokX9j4gQim7IOIhWvv106N7oeIX7QrCeNieEDPfav1TDMx9vu40DmIiDc
o3REaoCzGJ7Vo8kdNIXKwjV7y4tUOjB1q+2b9iqf/p4gJ/OjmQNcbioG9APCIeme
cfVZeypANQczMzUfXPGTrZX5GkVOYMFbtkK+pXXckD6XuROWc1CITDXKPjOh1qSt
HUQhJA5JtiR72rQvjWXXDsmuGhcYmmSXUQpml/16bBNhb4zxsZxnPB6skv11f0gr
kKevhfYREiqAIUmHR888NYB8+PyGsXWoEScYUmzzrFSrZmNH+aUu0gy0/NRaPidg
o3dUKun654SbzOXic/Gt/VzFt29ioMmFZAXDHtMwXM+V7V//mhfeQdCDnBgC6ty5
cUtSHsaFmWUuOR3E9IKoeP0Orplf6A8U+wy6swIwmKYPzlEHtI7IL0tweHo/KUyV
CYPPBICjJdPconYAN5cV1rQuem+VeBTKTNwtUdXuy9iYk1kwxM3aLi562DVUHBOa
oWBi2Aynar4ofFvRqNMYMynJM/ASjs9/nny5jFcxpcvrdzEDlPhcU61mpqEMyBWW
9iJyVN5UV5gJEWf9pofVGdokXl9yZ1YPwjLQF6+KZQwY6qeZhD614yx0MnE9553X
7VOJdxzoPPRazEx3azaB
=25vk
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver
  2014-02-25 22:11     ` Tom Rini
@ 2014-03-12 19:04       ` Murali Karicheri
  2014-03-12 20:01         ` Tom Rini
  0 siblings, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-03-12 19:04 UTC (permalink / raw)
  To: u-boot

On 2/25/2014 5:11 PM, Rini, Tom wrote:
> On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:
>
>> From: Vitaly Andrianov <vitalya@ti.com>
>>
>> Ethernet driver configures the CPSW, SGMI and Phy and uses
>> the the Navigator APIs. The driver supports 4 Ethernet ports and
>> can work with only one port at a time.
> First, can we just use things in a "dumb" mode and use the existing CPSW
> driver?  Or are there use cases we need to worry about here with a
> bigger / more robust network driver?

First of all we believe the CPSW driver in u-boot is for  tnetv107x CPSW 
hardware and
keystone CPSW is different and more complex. We need to support 
different modes
such as MAC to PHY, MAC to MAC and MAC to MAC forced. Also we are using 
a SGMII
with up to 8 ports in the newer K2 devices. So we don't think we can 
re-use the CPSW
driver.
>> +++ b/drivers/net/keystone_net.c
> Generic problem, please use phylib.

Vitaly has done some prototyping with phy lib and  found that this adds 
tons of code and
huge time to change the active port.  It doesn't give any advantage of 
using phylib as the
driver make only very few reads from standard generic phy registers.

keystone driver has to support phy-less mode (different modes listed 
above) and using the
phylib just unnecessary complicates the driver.  So

Does phylib based drivers have similar scenario as in keystone? How does 
other platforms
that uses phylib solves the above issues? Mainly delayed tftp and 
handling multiple modes?

We have taken care of all of comments here. So can we go with the 
current version of the
driver and then switch to phylib implementation if the above issues can 
be solved on a
phylib based implementation?

>> +void sgmii_serdes_setup_156p25mhz()
>> +{
>> +	unsigned int cnt;
>> +
>> +	reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
> Please comment on what we're doing here, and why we aren't using a
> struct to describe whatever is at 0x0232a000 ?
>
>> +void sgmii_serdes_shutdown()
>> +{
>> +	reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
> Same.

We will add comment here as we are using third party SERDES IP and the 
register
names are not published by the vendor.
> Thanks!
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
  2014-02-27 16:18     ` Karicheri, Muralidharan
@ 2014-03-12 19:21     ` Murali Karicheri
  2014-03-12 19:35       ` Tom Rini
  1 sibling, 1 reply; 716+ messages in thread
From: Murali Karicheri @ 2014-03-12 19:21 UTC (permalink / raw)
  To: u-boot

On 2/25/2014 5:10 PM, Rini, Tom wrote:
> On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
>
>> This patch series add support for keystone2 SoC and K2HK EVM
> In general, you ran checkpatch.pl right?  I see some '#define<tab>'
> cases that need manual fixing up as well.  Further comments and acks
> coming.
>
Tom,

Just want to check with you what you want me to fix for #define <tab>. 
Generally from
my Linux experience, I have seen #define used with tab. I looked at few 
header files and
that have this tab in #define. So where this restriction come from? I 
looked into the
Documentation/CodingStyle in Linux source tree and can't find any rule 
of not to
use #define <tab>.

Murali

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
  2014-03-12 19:21     ` Murali Karicheri
@ 2014-03-12 19:35       ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-03-12 19:35 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 12, 2014 at 03:21:26PM -0400, Murali Karicheri wrote:
> On 2/25/2014 5:10 PM, Rini, Tom wrote:
> >On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
> >
> >>This patch series add support for keystone2 SoC and K2HK EVM
> >In general, you ran checkpatch.pl right?  I see some '#define<tab>'
> >cases that need manual fixing up as well.  Further comments and acks
> >coming.
> >
> Tom,
> 
> Just want to check with you what you want me to fix for #define
> <tab>. Generally from
> my Linux experience, I have seen #define used with tab. I looked at
> few header files and
> that have this tab in #define. So where this restriction come from?
> I looked into the
> Documentation/CodingStyle in Linux source tree and can't find any
> rule of not to
> use #define <tab>.

It's a thing here at least that yes, '#define<space>' only, and we do
have a few things that need cleaning up.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140312/329c395f/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver
  2014-03-12 19:04       ` Murali Karicheri
@ 2014-03-12 20:01         ` Tom Rini
  0 siblings, 0 replies; 716+ messages in thread
From: Tom Rini @ 2014-03-12 20:01 UTC (permalink / raw)
  To: u-boot

On Wed, Mar 12, 2014 at 03:04:04PM -0400, Murali Karicheri wrote:
> On 2/25/2014 5:11 PM, Rini, Tom wrote:
> >On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:
> >
> >>From: Vitaly Andrianov <vitalya@ti.com>
> >>
> >>Ethernet driver configures the CPSW, SGMI and Phy and uses
> >>the the Navigator APIs. The driver supports 4 Ethernet ports and
> >>can work with only one port at a time.
> >First, can we just use things in a "dumb" mode and use the existing CPSW
> >driver?  Or are there use cases we need to worry about here with a
> >bigger / more robust network driver?
> 
> First of all we believe the CPSW driver in u-boot is for  tnetv107x
> CPSW hardware and

No, it's for the am335x and DRA7xx HW.

> keystone CPSW is different and more complex. We need to support
> different modes
> such as MAC to PHY, MAC to MAC and MAC to MAC forced. Also we are
> using a SGMII
> with up to 8 ports in the newer K2 devices. So we don't think we can
> re-use the CPSW
> driver.

How many of these modes do we actually need to support in U-Boot?  What
usecase(s) do you have for networking in U-Boot?  And I assume you're
having similar conversations upstreaming the kernel networking driver
(which does support am33xx/dra7xx and tnetv107x)..

> >>+++ b/drivers/net/keystone_net.c
> >Generic problem, please use phylib.
> 
> Vitaly has done some prototyping with phy lib and  found that this
> adds tons of code and
> huge time to change the active port.  It doesn't give any advantage
> of using phylib as the
> driver make only very few reads from standard generic phy registers.

OK.

> >>+void sgmii_serdes_setup_156p25mhz()
> >>+{
> >>+	unsigned int cnt;
> >>+
> >>+	reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
> >Please comment on what we're doing here, and why we aren't using a
> >struct to describe whatever is at 0x0232a000 ?
> >
> >>+void sgmii_serdes_shutdown()
> >>+{
> >>+	reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
> >Same.
> 
> We will add comment here as we are using third party SERDES IP and
> the register
> names are not published by the vendor.

Please check what you are and are not allowed to say.  It's usually the
case with NDA'd docs that if you can release code based on the docs it
doesn't have to be heavily obsucred and you can say what you're doing.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140312/df127f8d/attachment.pgp>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-01-13 17:19         ` Sharma, Shashank
@ 2014-04-09  6:19           ` Wang, Quanxian
  2014-04-09  6:50             ` Sharma, Shashank
  0 siblings, 1 reply; 716+ messages in thread
From: Wang, Quanxian @ 2014-04-09  6:19 UTC (permalink / raw)
  To: Sharma, Shashank, Daniel Vetter; +Cc: intel-gfx

Hi, Sharma, Shashank

Is there any following patches to make it happen?

Thanks

Regards

Quanxian Wang

>-----Original Message-----
>From: intel-gfx-bounces@lists.freedesktop.org
>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, Shashank
>Sent: Tuesday, January 14, 2014 1:20 AM
>To: Daniel Vetter
>Cc: intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and
>get_modes
>
>Thanks again for this explanation Daniel.
>We will work on your suggestions and come up with a new patch.
>
>Regards
>Shashank  / Ramalingam
>-----Original Message-----
>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel
>Vetter
>Sent: Monday, January 13, 2014 6:57 PM
>To: Sharma, Shashank
>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and
>get_modes
>
>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank
><shashank.sharma@intel.com> wrote:
>> Thanks a lot for your time, for reviewing the changes, and giving us some
>pointers.
>> Both me and Ramalingam are designing this together, and we discussed about
>these changes and your suggestions.
>> There are few things we would like to discuss about. Please correct us if some of
>our understanding is not proper.
>
>First something I've forgotten in the original mail: Overall your patches look really
>nice and the commit messages and cover letter have been excellent.
>Unfortunately you've run into one of the nastier cases of "reality just wont agree
>with the spec" :(
>
>> Those two patches provide two solution.
>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC channel can
>still get the EDID).
>> 2. Try to reduce the EDID reads over DDC channel for get connector and fill mode
>calls, by caching EDID, and using it until next HPD comes.
>>
>> Patch 2: Reduce the EDID read over DDC channel We are caching the EDID
>> at every HPD up, on HDMI detect calls, and we are freeing it on subsequent
>HDMI disconnect calls.
>>
>> The design philosophy here is, to maintain a state machine of HDMI connector
>status, and differentiate between IOCTL detect calls and HPD detect calls.
>> If there is a detect() or get_modes() call due to any of the IOCTL, which makes
>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>> But if the detect call is coming from HPD work function, due to a HPD plug-out,
>we remove/invalidate the old cached EDID, and cache the new EDID, on
>subsequent HDMI plug-in.
>> From here, the same state machine follows.
>>
>> Can you please let us know, why do you think that we should invalidate the
>cached EDID after 1-2 seconds ?
>
>Because there are machines out there where hpd never happens. So if you keep
>onto the cached value forever userspace will never notice a change in output
>configuration. Of course hotplug handling won't work, but at least users can still
>manually probe outputs. By unconditionally using the cached edid from ioctls you
>break this use case. Yes, such machines are broken, but we need to keep them
>working anyway.
>
>Also in my experience all machines are affected, we have examples covering gm45,
>ilk, snb & ivb. We haven't seen a case for hsw/byt yet since we don't rely on the
>hpd bits any more (and so won't see bug reports any more).
>
>Generally if you use the hpd stuff your code must be designed under the
>assumption that hpd is completely unreliably. We've seen anything from random
>noise, flat-out not-working at all, stuck bits and unstable hpd values that
>occasionally flip-flop. So you can't rely on it at all.
>
>> Note: In this same patch, there is additional optimization, which you pointed out,
>where we check if the connector->status is same as live status.
>> This can be removed independently, as you suggested.
>
>Hm, where have I pointed this out? Some other mail on internal discussions?
>
>> About patch 1:
>> We have done some local experiments and we came to know that for VLV and
>HSW boards, we can rely on the live status, if we give it some time to settle
>(~300ms).
>> Probably, we need to modify this patch, as you suggested, until it becomes
>handy to be used reliably. We are on it, and will send another patch soon.
>>
>> But if somehow we are able to get some consistent results from live status, do
>you think it would be worth accepting this change, so that it can handle soft HPDs
>and automation testing.
>> Because I believe we will face this problem whenever we are trying to test
>something from automation, where the physical device is not removed, and DDC
>channel is up always.
>
>It's very well possible that all the platforms you have, but experience says that
>some OEM will horrible screw this up. At least they've consistently botched this in
>the past on occasional machines.
>
>Now the ghost hdmi detection on slow removal is obviously not great, but we
>can't use the hpd bits to fix this. One approach would be.
>1. Upon hpd interrupt do an immediate probe of the connector. This way we'll
>have good userspace experience if the unplug happens quickly and the hw works.
>2. Re-probe with a 1s delay to catch slow-uplugs. The current output probing
>helpers are clever enough already that if a state-change happens to be detected a
>uevent will be generate, irrespective of the source of the detect call (i.e. hpd,
>kernel poll or ioctl/sysfs).
>
>Note that we already track the hpd interrupts on a per-source basis, so doing the
>re-poll shouldn't be costly. Maybe do the re-poll as part of the EDID invalidation to
>avoid stalling userspace.
>
>But you can't rely upon the hpd pins unfortunately :(
>
>This way we should be able to implement the 2 features you want, even on
>unreliable hw.
>
>Cheers, Daniel
>--
>Daniel Vetter
>Software Engineer, Intel Corporation
>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-09  6:19           ` Wang, Quanxian
@ 2014-04-09  6:50             ` Sharma, Shashank
  2014-04-10  6:46               ` Sharma, Shashank
  0 siblings, 1 reply; 716+ messages in thread
From: Sharma, Shashank @ 2014-04-09  6:50 UTC (permalink / raw)
  To: Wang, Quanxian, Daniel Vetter; +Cc: intel-gfx

Hello Quanxian Wang

This patch is available and working on all MCG tree's (Main, R42B and R44B)
We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design. 

I was working on that, but couldn't finish the activity yet, Thanks for reminding me 
I will update soon. :)

Regards
Shashank   
-----Original Message-----
From: Wang, Quanxian 
Sent: Wednesday, April 09, 2014 11:49 AM
To: Sharma, Shashank; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Hi, Sharma, Shashank

Is there any following patches to make it happen?

Thanks

Regards

Quanxian Wang

>-----Original Message-----
>From: intel-gfx-bounces@lists.freedesktop.org
>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
>Shashank
>Sent: Tuesday, January 14, 2014 1:20 AM
>To: Daniel Vetter
>Cc: intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>Thanks again for this explanation Daniel.
>We will work on your suggestions and come up with a new patch.
>
>Regards
>Shashank  / Ramalingam
>-----Original Message-----
>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
>Of Daniel Vetter
>Sent: Monday, January 13, 2014 6:57 PM
>To: Sharma, Shashank
>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
><shashank.sharma@intel.com> wrote:
>> Thanks a lot for your time, for reviewing the changes, and giving us 
>> some
>pointers.
>> Both me and Ramalingam are designing this together, and we discussed 
>> about
>these changes and your suggestions.
>> There are few things we would like to discuss about. Please correct 
>> us if some of
>our understanding is not proper.
>
>First something I've forgotten in the original mail: Overall your 
>patches look really nice and the commit messages and cover letter have been excellent.
>Unfortunately you've run into one of the nastier cases of "reality just 
>wont agree with the spec" :(
>
>> Those two patches provide two solution.
>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
>> channel can
>still get the EDID).
>> 2. Try to reduce the EDID reads over DDC channel for get connector 
>> and fill mode
>calls, by caching EDID, and using it until next HPD comes.
>>
>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
>> subsequent
>HDMI disconnect calls.
>>
>> The design philosophy here is, to maintain a state machine of HDMI 
>> connector
>status, and differentiate between IOCTL detect calls and HPD detect calls.
>> If there is a detect() or get_modes() call due to any of the IOCTL, 
>> which makes
>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>> But if the detect call is coming from HPD work function, due to a HPD 
>> plug-out,
>we remove/invalidate the old cached EDID, and cache the new EDID, on 
>subsequent HDMI plug-in.
>> From here, the same state machine follows.
>>
>> Can you please let us know, why do you think that we should 
>> invalidate the
>cached EDID after 1-2 seconds ?
>
>Because there are machines out there where hpd never happens. So if you 
>keep onto the cached value forever userspace will never notice a change 
>in output configuration. Of course hotplug handling won't work, but at 
>least users can still manually probe outputs. By unconditionally using 
>the cached edid from ioctls you break this use case. Yes, such machines 
>are broken, but we need to keep them working anyway.
>
>Also in my experience all machines are affected, we have examples 
>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
>
>Generally if you use the hpd stuff your code must be designed under the 
>assumption that hpd is completely unreliably. We've seen anything from 
>random noise, flat-out not-working at all, stuck bits and unstable hpd 
>values that occasionally flip-flop. So you can't rely on it at all.
>
>> Note: In this same patch, there is additional optimization, which you 
>> pointed out,
>where we check if the connector->status is same as live status.
>> This can be removed independently, as you suggested.
>
>Hm, where have I pointed this out? Some other mail on internal discussions?
>
>> About patch 1:
>> We have done some local experiments and we came to know that for VLV 
>> and
>HSW boards, we can rely on the live status, if we give it some time to 
>settle (~300ms).
>> Probably, we need to modify this patch, as you suggested, until it 
>> becomes
>handy to be used reliably. We are on it, and will send another patch soon.
>>
>> But if somehow we are able to get some consistent results from live 
>> status, do
>you think it would be worth accepting this change, so that it can 
>handle soft HPDs and automation testing.
>> Because I believe we will face this problem whenever we are trying to 
>> test
>something from automation, where the physical device is not removed, 
>and DDC channel is up always.
>
>It's very well possible that all the platforms you have, but experience 
>says that some OEM will horrible screw this up. At least they've 
>consistently botched this in the past on occasional machines.
>
>Now the ghost hdmi detection on slow removal is obviously not great, 
>but we can't use the hpd bits to fix this. One approach would be.
>1. Upon hpd interrupt do an immediate probe of the connector. This way 
>we'll have good userspace experience if the unplug happens quickly and the hw works.
>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
>probing helpers are clever enough already that if a state-change 
>happens to be detected a uevent will be generate, irrespective of the 
>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
>
>Note that we already track the hpd interrupts on a per-source basis, so 
>doing the re-poll shouldn't be costly. Maybe do the re-poll as part of 
>the EDID invalidation to avoid stalling userspace.
>
>But you can't rely upon the hpd pins unfortunately :(
>
>This way we should be able to implement the 2 features you want, even 
>on unreliable hw.
>
>Cheers, Daniel
>--
>Daniel Vetter
>Software Engineer, Intel Corporation
>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-09  6:50             ` Sharma, Shashank
@ 2014-04-10  6:46               ` Sharma, Shashank
  2014-04-10  8:08                 ` Daniel Vetter
  2014-04-10 10:42                 ` Wang, Quanxian
  0 siblings, 2 replies; 716+ messages in thread
From: Sharma, Shashank @ 2014-04-10  6:46 UTC (permalink / raw)
  To: Wang, Quanxian, Daniel Vetter; +Cc: intel-gfx

Hi Daniel / Quanxian / All, 

I have one question about the 'force' flag given to connector's detect() functions.
To design new EDID caching solution, I was trying to re-use this flag. As you all know, detect() gets called from few places in DRM and I915 layer, with this flag status:

drm_sysfs.c : status_show (sysfs status check inquire from USP)						force = 1
drm_crtc_helper.c: drm_helper_probe_single_connector_modes (part of get_connector IOCTL) 		force = 1

drm_crtc_helper.c: output_poll_execute(scheduled from poll work)						force = 0
drm_crtc_helper.c: drm_helper_hpd_irq_event (resume hotplug)						force = 0
i915_irq.c: i915_hotplug_work_function (bottom half of hotplug IRQ)						force = 0

What I am seeing is, the places where it's really required to probe the device, like in IRQ handlers or while resuming the device,  the force flag is 0, 
whereas whenever there is a userspace interaction or query for status, the flag is 1.  Please correct me if my understating is not proper, 
but I feel this should be the opposite way. 

Please let me know your opinion about this.

Regards
Shashank  
-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, Shashank
Sent: Wednesday, April 09, 2014 12:20 PM
To: Wang, Quanxian; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Hello Quanxian Wang

This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design. 

I was working on that, but couldn't finish the activity yet, Thanks for reminding me I will update soon. :)

Regards
Shashank   
-----Original Message-----
From: Wang, Quanxian
Sent: Wednesday, April 09, 2014 11:49 AM
To: Sharma, Shashank; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Hi, Sharma, Shashank

Is there any following patches to make it happen?

Thanks

Regards

Quanxian Wang

>-----Original Message-----
>From: intel-gfx-bounces@lists.freedesktop.org
>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
>Shashank
>Sent: Tuesday, January 14, 2014 1:20 AM
>To: Daniel Vetter
>Cc: intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>Thanks again for this explanation Daniel.
>We will work on your suggestions and come up with a new patch.
>
>Regards
>Shashank  / Ramalingam
>-----Original Message-----
>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
>Of Daniel Vetter
>Sent: Monday, January 13, 2014 6:57 PM
>To: Sharma, Shashank
>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
><shashank.sharma@intel.com> wrote:
>> Thanks a lot for your time, for reviewing the changes, and giving us 
>> some
>pointers.
>> Both me and Ramalingam are designing this together, and we discussed 
>> about
>these changes and your suggestions.
>> There are few things we would like to discuss about. Please correct 
>> us if some of
>our understanding is not proper.
>
>First something I've forgotten in the original mail: Overall your 
>patches look really nice and the commit messages and cover letter have been excellent.
>Unfortunately you've run into one of the nastier cases of "reality just 
>wont agree with the spec" :(
>
>> Those two patches provide two solution.
>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
>> channel can
>still get the EDID).
>> 2. Try to reduce the EDID reads over DDC channel for get connector 
>> and fill mode
>calls, by caching EDID, and using it until next HPD comes.
>>
>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
>> subsequent
>HDMI disconnect calls.
>>
>> The design philosophy here is, to maintain a state machine of HDMI 
>> connector
>status, and differentiate between IOCTL detect calls and HPD detect calls.
>> If there is a detect() or get_modes() call due to any of the IOCTL, 
>> which makes
>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>> But if the detect call is coming from HPD work function, due to a HPD 
>> plug-out,
>we remove/invalidate the old cached EDID, and cache the new EDID, on 
>subsequent HDMI plug-in.
>> From here, the same state machine follows.
>>
>> Can you please let us know, why do you think that we should 
>> invalidate the
>cached EDID after 1-2 seconds ?
>
>Because there are machines out there where hpd never happens. So if you 
>keep onto the cached value forever userspace will never notice a change 
>in output configuration. Of course hotplug handling won't work, but at 
>least users can still manually probe outputs. By unconditionally using 
>the cached edid from ioctls you break this use case. Yes, such machines 
>are broken, but we need to keep them working anyway.
>
>Also in my experience all machines are affected, we have examples 
>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
>
>Generally if you use the hpd stuff your code must be designed under the 
>assumption that hpd is completely unreliably. We've seen anything from 
>random noise, flat-out not-working at all, stuck bits and unstable hpd 
>values that occasionally flip-flop. So you can't rely on it at all.
>
>> Note: In this same patch, there is additional optimization, which you 
>> pointed out,
>where we check if the connector->status is same as live status.
>> This can be removed independently, as you suggested.
>
>Hm, where have I pointed this out? Some other mail on internal discussions?
>
>> About patch 1:
>> We have done some local experiments and we came to know that for VLV 
>> and
>HSW boards, we can rely on the live status, if we give it some time to 
>settle (~300ms).
>> Probably, we need to modify this patch, as you suggested, until it 
>> becomes
>handy to be used reliably. We are on it, and will send another patch soon.
>>
>> But if somehow we are able to get some consistent results from live 
>> status, do
>you think it would be worth accepting this change, so that it can 
>handle soft HPDs and automation testing.
>> Because I believe we will face this problem whenever we are trying to 
>> test
>something from automation, where the physical device is not removed, 
>and DDC channel is up always.
>
>It's very well possible that all the platforms you have, but experience 
>says that some OEM will horrible screw this up. At least they've 
>consistently botched this in the past on occasional machines.
>
>Now the ghost hdmi detection on slow removal is obviously not great, 
>but we can't use the hpd bits to fix this. One approach would be.
>1. Upon hpd interrupt do an immediate probe of the connector. This way 
>we'll have good userspace experience if the unplug happens quickly and the hw works.
>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
>probing helpers are clever enough already that if a state-change 
>happens to be detected a uevent will be generate, irrespective of the 
>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
>
>Note that we already track the hpd interrupts on a per-source basis, so 
>doing the re-poll shouldn't be costly. Maybe do the re-poll as part of 
>the EDID invalidation to avoid stalling userspace.
>
>But you can't rely upon the hpd pins unfortunately :(
>
>This way we should be able to implement the 2 features you want, even 
>on unreliable hw.
>
>Cheers, Daniel
>--
>Daniel Vetter
>Software Engineer, Intel Corporation
>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-10  6:46               ` Sharma, Shashank
@ 2014-04-10  8:08                 ` Daniel Vetter
  2014-04-10  8:10                   ` Sharma, Shashank
  2014-04-10 10:42                 ` Wang, Quanxian
  1 sibling, 1 reply; 716+ messages in thread
From: Daniel Vetter @ 2014-04-10  8:08 UTC (permalink / raw)
  To: Sharma, Shashank; +Cc: intel-gfx

On Thu, Apr 10, 2014 at 06:46:58AM +0000, Sharma, Shashank wrote:
> Hi Daniel / Quanxian / All, 
> 
> I have one question about the 'force' flag given to connector's detect() functions.
> To design new EDID caching solution, I was trying to re-use this flag.
> As you all know, detect() gets called from few places in DRM and I915
> layer, with this flag status:
> 
> drm_sysfs.c : status_show (sysfs status check inquire from USP)						force = 1
> drm_crtc_helper.c: drm_helper_probe_single_connector_modes (part of get_connector IOCTL) 		force = 1
> 
> drm_crtc_helper.c: output_poll_execute(scheduled from poll work)						force = 0
> drm_crtc_helper.c: drm_helper_hpd_irq_event (resume hotplug)						force = 0
> i915_irq.c: i915_hotplug_work_function (bottom half of hotplug IRQ)						force = 0
> 
> What I am seeing is, the places where it's really required to probe the
> device, like in IRQ handlers or while resuming the device,  the force
> flag is 0, whereas whenever there is a userspace interaction or query
> for status, the flag is 1.  Please correct me if my understating is not
> proper, 
> but I feel this should be the opposite way. 
> 
> Please let me know your opinion about this.

Force is a bit misnomer, a better name might be non-invasive. Without
force we don't do stuff like load-detect by default since at least when
doing this manually some old crt screens switch on. But this is really
only relevant for gen2/3 and tv-out, so not of any concern on modern
platforms. Essentially force means "userspace asked for this and it's ok
if the screen flickers a bit due to that".

Imo you can do the caching and use the cached version irrespective of
force.
-Daniel

> 
> Regards
> Shashank  
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, Shashank
> Sent: Wednesday, April 09, 2014 12:20 PM
> To: Wang, Quanxian; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
> 
> Hello Quanxian Wang
> 
> This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design. 
> 
> I was working on that, but couldn't finish the activity yet, Thanks for reminding me I will update soon. :)
> 
> Regards
> Shashank   
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Wednesday, April 09, 2014 11:49 AM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
> 
> Hi, Sharma, Shashank
> 
> Is there any following patches to make it happen?
> 
> Thanks
> 
> Regards
> 
> Quanxian Wang
> 
> >-----Original Message-----
> >From: intel-gfx-bounces@lists.freedesktop.org
> >[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
> >Shashank
> >Sent: Tuesday, January 14, 2014 1:20 AM
> >To: Daniel Vetter
> >Cc: intel-gfx@lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> >and get_modes
> >
> >Thanks again for this explanation Daniel.
> >We will work on your suggestions and come up with a new patch.
> >
> >Regards
> >Shashank  / Ramalingam
> >-----Original Message-----
> >From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
> >Of Daniel Vetter
> >Sent: Monday, January 13, 2014 6:57 PM
> >To: Sharma, Shashank
> >Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> >and get_modes
> >
> >On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
> ><shashank.sharma@intel.com> wrote:
> >> Thanks a lot for your time, for reviewing the changes, and giving us 
> >> some
> >pointers.
> >> Both me and Ramalingam are designing this together, and we discussed 
> >> about
> >these changes and your suggestions.
> >> There are few things we would like to discuss about. Please correct 
> >> us if some of
> >our understanding is not proper.
> >
> >First something I've forgotten in the original mail: Overall your 
> >patches look really nice and the commit messages and cover letter have been excellent.
> >Unfortunately you've run into one of the nastier cases of "reality just 
> >wont agree with the spec" :(
> >
> >> Those two patches provide two solution.
> >> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
> >> channel can
> >still get the EDID).
> >> 2. Try to reduce the EDID reads over DDC channel for get connector 
> >> and fill mode
> >calls, by caching EDID, and using it until next HPD comes.
> >>
> >> Patch 2: Reduce the EDID read over DDC channel We are caching the 
> >> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
> >> subsequent
> >HDMI disconnect calls.
> >>
> >> The design philosophy here is, to maintain a state machine of HDMI 
> >> connector
> >status, and differentiate between IOCTL detect calls and HPD detect calls.
> >> If there is a detect() or get_modes() call due to any of the IOCTL, 
> >> which makes
> >sure that input variable force=1, we just use the cached EDID, to serve this calls.
> >> But if the detect call is coming from HPD work function, due to a HPD 
> >> plug-out,
> >we remove/invalidate the old cached EDID, and cache the new EDID, on 
> >subsequent HDMI plug-in.
> >> From here, the same state machine follows.
> >>
> >> Can you please let us know, why do you think that we should 
> >> invalidate the
> >cached EDID after 1-2 seconds ?
> >
> >Because there are machines out there where hpd never happens. So if you 
> >keep onto the cached value forever userspace will never notice a change 
> >in output configuration. Of course hotplug handling won't work, but at 
> >least users can still manually probe outputs. By unconditionally using 
> >the cached edid from ioctls you break this use case. Yes, such machines 
> >are broken, but we need to keep them working anyway.
> >
> >Also in my experience all machines are affected, we have examples 
> >covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
> >since we don't rely on the hpd bits any more (and so won't see bug reports any more).
> >
> >Generally if you use the hpd stuff your code must be designed under the 
> >assumption that hpd is completely unreliably. We've seen anything from 
> >random noise, flat-out not-working at all, stuck bits and unstable hpd 
> >values that occasionally flip-flop. So you can't rely on it at all.
> >
> >> Note: In this same patch, there is additional optimization, which you 
> >> pointed out,
> >where we check if the connector->status is same as live status.
> >> This can be removed independently, as you suggested.
> >
> >Hm, where have I pointed this out? Some other mail on internal discussions?
> >
> >> About patch 1:
> >> We have done some local experiments and we came to know that for VLV 
> >> and
> >HSW boards, we can rely on the live status, if we give it some time to 
> >settle (~300ms).
> >> Probably, we need to modify this patch, as you suggested, until it 
> >> becomes
> >handy to be used reliably. We are on it, and will send another patch soon.
> >>
> >> But if somehow we are able to get some consistent results from live 
> >> status, do
> >you think it would be worth accepting this change, so that it can 
> >handle soft HPDs and automation testing.
> >> Because I believe we will face this problem whenever we are trying to 
> >> test
> >something from automation, where the physical device is not removed, 
> >and DDC channel is up always.
> >
> >It's very well possible that all the platforms you have, but experience 
> >says that some OEM will horrible screw this up. At least they've 
> >consistently botched this in the past on occasional machines.
> >
> >Now the ghost hdmi detection on slow removal is obviously not great, 
> >but we can't use the hpd bits to fix this. One approach would be.
> >1. Upon hpd interrupt do an immediate probe of the connector. This way 
> >we'll have good userspace experience if the unplug happens quickly and the hw works.
> >2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
> >probing helpers are clever enough already that if a state-change 
> >happens to be detected a uevent will be generate, irrespective of the 
> >source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
> >
> >Note that we already track the hpd interrupts on a per-source basis, so 
> >doing the re-poll shouldn't be costly. Maybe do the re-poll as part of 
> >the EDID invalidation to avoid stalling userspace.
> >
> >But you can't rely upon the hpd pins unfortunately :(
> >
> >This way we should be able to implement the 2 features you want, even 
> >on unreliable hw.
> >
> >Cheers, Daniel
> >--
> >Daniel Vetter
> >Software Engineer, Intel Corporation
> >+41 (0) 79 365 57 48 - http://blog.ffwll.ch
> >_______________________________________________
> >Intel-gfx mailing list
> >Intel-gfx@lists.freedesktop.org
> >http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-10  8:08                 ` Daniel Vetter
@ 2014-04-10  8:10                   ` Sharma, Shashank
  0 siblings, 0 replies; 716+ messages in thread
From: Sharma, Shashank @ 2014-04-10  8:10 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Thanks for this clarification. 

Regards
Shashank 
-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Thursday, April 10, 2014 1:39 PM
To: Sharma, Shashank
Cc: Wang, Quanxian; Daniel Vetter; intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

On Thu, Apr 10, 2014 at 06:46:58AM +0000, Sharma, Shashank wrote:
> Hi Daniel / Quanxian / All,
> 
> I have one question about the 'force' flag given to connector's detect() functions.
> To design new EDID caching solution, I was trying to re-use this flag.
> As you all know, detect() gets called from few places in DRM and I915 
> layer, with this flag status:
> 
> drm_sysfs.c : status_show (sysfs status check inquire from USP)						force = 1
> drm_crtc_helper.c: drm_helper_probe_single_connector_modes (part of get_connector IOCTL) 		force = 1
> 
> drm_crtc_helper.c: output_poll_execute(scheduled from poll work)						force = 0
> drm_crtc_helper.c: drm_helper_hpd_irq_event (resume hotplug)						force = 0
> i915_irq.c: i915_hotplug_work_function (bottom half of hotplug IRQ)						force = 0
> 
> What I am seeing is, the places where it's really required to probe 
> the device, like in IRQ handlers or while resuming the device,  the 
> force flag is 0, whereas whenever there is a userspace interaction or 
> query for status, the flag is 1.  Please correct me if my understating 
> is not proper, but I feel this should be the opposite way.
> 
> Please let me know your opinion about this.

Force is a bit misnomer, a better name might be non-invasive. Without force we don't do stuff like load-detect by default since at least when doing this manually some old crt screens switch on. But this is really only relevant for gen2/3 and tv-out, so not of any concern on modern platforms. Essentially force means "userspace asked for this and it's ok if the screen flickers a bit due to that".

Imo you can do the caching and use the cached version irrespective of force.
-Daniel

> 
> Regards
> Shashank
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On 
> Behalf Of Sharma, Shashank
> Sent: Wednesday, April 09, 2014 12:20 PM
> To: Wang, Quanxian; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
> 
> Hello Quanxian Wang
> 
> This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design. 
> 
> I was working on that, but couldn't finish the activity yet, Thanks 
> for reminding me I will update soon. :)
> 
> Regards
> Shashank   
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Wednesday, April 09, 2014 11:49 AM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
> 
> Hi, Sharma, Shashank
> 
> Is there any following patches to make it happen?
> 
> Thanks
> 
> Regards
> 
> Quanxian Wang
> 
> >-----Original Message-----
> >From: intel-gfx-bounces@lists.freedesktop.org
> >[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
> >Shashank
> >Sent: Tuesday, January 14, 2014 1:20 AM
> >To: Daniel Vetter
> >Cc: intel-gfx@lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> >detect and get_modes
> >
> >Thanks again for this explanation Daniel.
> >We will work on your suggestions and come up with a new patch.
> >
> >Regards
> >Shashank  / Ramalingam
> >-----Original Message-----
> >From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On 
> >Behalf Of Daniel Vetter
> >Sent: Monday, January 13, 2014 6:57 PM
> >To: Sharma, Shashank
> >Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
> >Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> >detect and get_modes
> >
> >On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
> ><shashank.sharma@intel.com> wrote:
> >> Thanks a lot for your time, for reviewing the changes, and giving 
> >> us some
> >pointers.
> >> Both me and Ramalingam are designing this together, and we 
> >> discussed about
> >these changes and your suggestions.
> >> There are few things we would like to discuss about. Please correct 
> >> us if some of
> >our understanding is not proper.
> >
> >First something I've forgotten in the original mail: Overall your 
> >patches look really nice and the commit messages and cover letter have been excellent.
> >Unfortunately you've run into one of the nastier cases of "reality 
> >just wont agree with the spec" :(
> >
> >> Those two patches provide two solution.
> >> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
> >> channel can
> >still get the EDID).
> >> 2. Try to reduce the EDID reads over DDC channel for get connector 
> >> and fill mode
> >calls, by caching EDID, and using it until next HPD comes.
> >>
> >> Patch 2: Reduce the EDID read over DDC channel We are caching the 
> >> EDID at every HPD up, on HDMI detect calls, and we are freeing it 
> >> on subsequent
> >HDMI disconnect calls.
> >>
> >> The design philosophy here is, to maintain a state machine of HDMI 
> >> connector
> >status, and differentiate between IOCTL detect calls and HPD detect calls.
> >> If there is a detect() or get_modes() call due to any of the IOCTL, 
> >> which makes
> >sure that input variable force=1, we just use the cached EDID, to serve this calls.
> >> But if the detect call is coming from HPD work function, due to a 
> >> HPD plug-out,
> >we remove/invalidate the old cached EDID, and cache the new EDID, on 
> >subsequent HDMI plug-in.
> >> From here, the same state machine follows.
> >>
> >> Can you please let us know, why do you think that we should 
> >> invalidate the
> >cached EDID after 1-2 seconds ?
> >
> >Because there are machines out there where hpd never happens. So if 
> >you keep onto the cached value forever userspace will never notice a 
> >change in output configuration. Of course hotplug handling won't 
> >work, but at least users can still manually probe outputs. By 
> >unconditionally using the cached edid from ioctls you break this use 
> >case. Yes, such machines are broken, but we need to keep them working anyway.
> >
> >Also in my experience all machines are affected, we have examples 
> >covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
> >since we don't rely on the hpd bits any more (and so won't see bug reports any more).
> >
> >Generally if you use the hpd stuff your code must be designed under 
> >the assumption that hpd is completely unreliably. We've seen anything 
> >from random noise, flat-out not-working at all, stuck bits and 
> >unstable hpd values that occasionally flip-flop. So you can't rely on it at all.
> >
> >> Note: In this same patch, there is additional optimization, which 
> >> you pointed out,
> >where we check if the connector->status is same as live status.
> >> This can be removed independently, as you suggested.
> >
> >Hm, where have I pointed this out? Some other mail on internal discussions?
> >
> >> About patch 1:
> >> We have done some local experiments and we came to know that for 
> >> VLV and
> >HSW boards, we can rely on the live status, if we give it some time 
> >to settle (~300ms).
> >> Probably, we need to modify this patch, as you suggested, until it 
> >> becomes
> >handy to be used reliably. We are on it, and will send another patch soon.
> >>
> >> But if somehow we are able to get some consistent results from live 
> >> status, do
> >you think it would be worth accepting this change, so that it can 
> >handle soft HPDs and automation testing.
> >> Because I believe we will face this problem whenever we are trying 
> >> to test
> >something from automation, where the physical device is not removed, 
> >and DDC channel is up always.
> >
> >It's very well possible that all the platforms you have, but 
> >experience says that some OEM will horrible screw this up. At least 
> >they've consistently botched this in the past on occasional machines.
> >
> >Now the ghost hdmi detection on slow removal is obviously not great, 
> >but we can't use the hpd bits to fix this. One approach would be.
> >1. Upon hpd interrupt do an immediate probe of the connector. This 
> >way we'll have good userspace experience if the unplug happens quickly and the hw works.
> >2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
> >probing helpers are clever enough already that if a state-change 
> >happens to be detected a uevent will be generate, irrespective of the 
> >source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
> >
> >Note that we already track the hpd interrupts on a per-source basis, 
> >so doing the re-poll shouldn't be costly. Maybe do the re-poll as 
> >part of the EDID invalidation to avoid stalling userspace.
> >
> >But you can't rely upon the hpd pins unfortunately :(
> >
> >This way we should be able to implement the 2 features you want, even 
> >on unreliable hw.
> >
> >Cheers, Daniel
> >--
> >Daniel Vetter
> >Software Engineer, Intel Corporation
> >+41 (0) 79 365 57 48 - http://blog.ffwll.ch
> >_______________________________________________
> >Intel-gfx mailing list
> >Intel-gfx@lists.freedesktop.org
> >http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-10  6:46               ` Sharma, Shashank
  2014-04-10  8:08                 ` Daniel Vetter
@ 2014-04-10 10:42                 ` Wang, Quanxian
       [not found]                   ` <FF3DDC77922A8A4BB08A3BC48A1EA8CB01692A7B@BGSMSX101.gar.corp.intel.com>
  1 sibling, 1 reply; 716+ messages in thread
From: Wang, Quanxian @ 2014-04-10 10:42 UTC (permalink / raw)
  To: Sharma, Shashank, Daniel Vetter; +Cc: intel-gfx

Tizen-IVI has one feature will require hdmi edid cache. It will be happy to find your patch pushed into upstream tree.

Regards

Thanks

Quanxian Wang

-----Original Message-----
From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, Shashank
Sent: Wednesday, April 09, 2014 12:20 PM
To: Wang, Quanxian; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Hello Quanxian Wang

This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design. 

I was working on that, but couldn't finish the activity yet, Thanks for reminding me I will update soon. :)

Regards
Shashank   
-----Original Message-----
From: Wang, Quanxian
Sent: Wednesday, April 09, 2014 11:49 AM
To: Sharma, Shashank; Daniel Vetter
Cc: intel-gfx@lists.freedesktop.org
Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Hi, Sharma, Shashank

Is there any following patches to make it happen?

Thanks

Regards

Quanxian Wang

>-----Original Message-----
>From: intel-gfx-bounces@lists.freedesktop.org
>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
>Shashank
>Sent: Tuesday, January 14, 2014 1:20 AM
>To: Daniel Vetter
>Cc: intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>Thanks again for this explanation Daniel.
>We will work on your suggestions and come up with a new patch.
>
>Regards
>Shashank  / Ramalingam
>-----Original Message-----
>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
>Of Daniel Vetter
>Sent: Monday, January 13, 2014 6:57 PM
>To: Sharma, Shashank
>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>and get_modes
>
>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
><shashank.sharma@intel.com> wrote:
>> Thanks a lot for your time, for reviewing the changes, and giving us 
>> some
>pointers.
>> Both me and Ramalingam are designing this together, and we discussed 
>> about
>these changes and your suggestions.
>> There are few things we would like to discuss about. Please correct 
>> us if some of
>our understanding is not proper.
>
>First something I've forgotten in the original mail: Overall your 
>patches look really nice and the commit messages and cover letter have been excellent.
>Unfortunately you've run into one of the nastier cases of "reality just 
>wont agree with the spec" :(
>
>> Those two patches provide two solution.
>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
>> channel can
>still get the EDID).
>> 2. Try to reduce the EDID reads over DDC channel for get connector 
>> and fill mode
>calls, by caching EDID, and using it until next HPD comes.
>>
>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
>> subsequent
>HDMI disconnect calls.
>>
>> The design philosophy here is, to maintain a state machine of HDMI 
>> connector
>status, and differentiate between IOCTL detect calls and HPD detect calls.
>> If there is a detect() or get_modes() call due to any of the IOCTL, 
>> which makes
>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>> But if the detect call is coming from HPD work function, due to a HPD 
>> plug-out,
>we remove/invalidate the old cached EDID, and cache the new EDID, on 
>subsequent HDMI plug-in.
>> From here, the same state machine follows.
>>
>> Can you please let us know, why do you think that we should 
>> invalidate the
>cached EDID after 1-2 seconds ?
>
>Because there are machines out there where hpd never happens. So if you 
>keep onto the cached value forever userspace will never notice a change 
>in output configuration. Of course hotplug handling won't work, but at 
>least users can still manually probe outputs. By unconditionally using 
>the cached edid from ioctls you break this use case. Yes, such machines 
>are broken, but we need to keep them working anyway.
>
>Also in my experience all machines are affected, we have examples 
>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
>
>Generally if you use the hpd stuff your code must be designed under the 
>assumption that hpd is completely unreliably. We've seen anything from 
>random noise, flat-out not-working at all, stuck bits and unstable hpd 
>values that occasionally flip-flop. So you can't rely on it at all.
>
>> Note: In this same patch, there is additional optimization, which you 
>> pointed out,
>where we check if the connector->status is same as live status.
>> This can be removed independently, as you suggested.
>
>Hm, where have I pointed this out? Some other mail on internal discussions?
>
>> About patch 1:
>> We have done some local experiments and we came to know that for VLV 
>> and
>HSW boards, we can rely on the live status, if we give it some time to 
>settle (~300ms).
>> Probably, we need to modify this patch, as you suggested, until it 
>> becomes
>handy to be used reliably. We are on it, and will send another patch soon.
>>
>> But if somehow we are able to get some consistent results from live 
>> status, do
>you think it would be worth accepting this change, so that it can 
>handle soft HPDs and automation testing.
>> Because I believe we will face this problem whenever we are trying to 
>> test
>something from automation, where the physical device is not removed, 
>and DDC channel is up always.
>
>It's very well possible that all the platforms you have, but experience 
>says that some OEM will horrible screw this up. At least they've 
>consistently botched this in the past on occasional machines.
>
>Now the ghost hdmi detection on slow removal is obviously not great, 
>but we can't use the hpd bits to fix this. One approach would be.
>1. Upon hpd interrupt do an immediate probe of the connector. This way 
>we'll have good userspace experience if the unplug happens quickly and the hw works.
>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
>probing helpers are clever enough already that if a state-change 
>happens to be detected a uevent will be generate, irrespective of the 
>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
>
>Note that we already track the hpd interrupts on a per-source basis, so 
>doing the re-poll shouldn't be costly. Maybe do the re-poll as part of 
>the EDID invalidation to avoid stalling userspace.
>
>But you can't rely upon the hpd pins unfortunately :(
>
>This way we should be able to implement the 2 features you want, even 
>on unreliable hw.
>
>Cheers, Daniel
>--
>Daniel Vetter
>Software Engineer, Intel Corporation
>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
       [not found]                   ` <FF3DDC77922A8A4BB08A3BC48A1EA8CB01692A7B@BGSMSX101.gar.corp.intel.com>
@ 2014-04-11 12:58                     ` Daniel Vetter
  2014-04-11 13:23                       ` Sharma, Shashank
  0 siblings, 1 reply; 716+ messages in thread
From: Daniel Vetter @ 2014-04-11 12:58 UTC (permalink / raw)
  To: Sharma, Shashank; +Cc: intel-gfx

Please don't drop the mailing list when discussing patches.

And nope, conditioning this on gen6+ won't help at all, since I have a
gen6 and gen7 machine here which don't have reliable hdmi live status.
Afaik that is _really_ broken across the board and going with the
fancy invalidation scheme and delayed work items is the way forward.

Cheers, Daniel

On Fri, Apr 11, 2014 at 2:51 PM, Sharma, Shashank
<shashank.sharma@intel.com> wrote:
> Hi Daniel,
>
> First of all, sorry for the delay in coming up with the new patch set. I got stuck with some commercial projects :) .
>
> There were few review comments what you gave for the previous optimization patch, those were:
> 1.  This might break the old HWs. Few of them might not even be HPD capable, so its required to handle them.
> 2.  Do not rely on the live_status check, as that HW is not yet proven.
> And you recommended to have a WQ, which will invalidate the cached HDMI EDID after a timeout.
>
> I have written another patch, which is addressing both of the above comments, but doesn't use a WQ.
>
> Before sending this to ML, I wanted to have an opinion from you, if this qualifies the design you were expecting.
> I will be really glad, if you can spare some time, and just have a top level view on the patch, and give your opinion.
>
> If you think that this is still not the way, and making a WQ is a better approach, I would gladly create a patch which applies that.
> Or if you will prefer to have this reviewed in the mailing list only, please accept my apologies for direct contact, and just let me know so. I will publish this in ML.
>
> The patch is (It's also attached):
>
> From e7ec4e4827615c0ff3a4ddb020df35fdf1b0b82f Mon Sep 17 00:00:00 2001
> From: Shashank Sharma <shashank.sharma@intel.com>
> Date: Fri, 11 Apr 2014 18:02:50 +0530
> Subject: [PATCH] drm/i915: Cache HDMI EDID for future reference
>
> This patch contains following changes:
> 1.Cache HDMI EDID and optimize detect() calls, which are
>   frequently called from userspace, causing un-necessary
>   EDID reads.
> 2.This cached EDID will be used for detection of the status of
>   HDMI connector, for Non HPD detect() calls. HPD calls will update
>   cached EDID.
> 3.This optimization is kept for new HW's (Gen6 and +), so that It
>   will not break old HWs who may not be even HPD capable.
>
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h  |    1 +
>  drivers/gpu/drm/i915/intel_hdmi.c |   28 ++++++++++++++++++++++++++--
>  2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 42762b7..b7911df 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -478,6 +478,7 @@ struct intel_hdmi {
>                                 const void *frame, ssize_t len);
>         void (*set_infoframes)(struct drm_encoder *encoder,
>                                struct drm_display_mode *adjusted_mode);
> +       struct edid *edid;
>  };
>
>  #define DP_MAX_DOWNSTREAM_PORTS                0x10
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index b0413e1..33550ca 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -938,7 +938,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>                 hdmi_to_dig_port(intel_hdmi);
>         struct intel_encoder *intel_encoder = &intel_dig_port->base;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct edid *edid;
> +       struct edid *edid = NULL;
>         enum intel_display_power_domain power_domain;
>         enum drm_connector_status status = connector_status_disconnected;
>
> @@ -948,6 +948,21 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>         power_domain = intel_display_port_power_domain(intel_encoder);
>         intel_display_power_get(dev_priv, power_domain);
>
> +       /*
> +       * Support EDID caching only for new architectures
> +       * Let old architectures probe and force read EDID
> +       */
> +       if (INTEL_INFO(dev)->gen >= 6) {
> +               if (force && intel_hdmi->edid &&
> +                       (connector->status != connector_status_unknown)) {
> +                       /* Optimize userspace query, read EDID only
> +                       in case of a real hot plug */
> +                       DRM_DEBUG_KMS("HDMI %s", intel_hdmi->edid ?
> +                               "Connected" : "Disconnected");
> +                       return connector->status;
> +               }
> +       }
> +
>         intel_hdmi->has_hdmi_sink = false;
>         intel_hdmi->has_audio = false;
>         intel_hdmi->rgb_quant_range_selectable = false;
> @@ -964,10 +979,19 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>                         intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
>                         intel_hdmi->rgb_quant_range_selectable =
>                                 drm_rgb_quant_range_selectable(edid);
> +                       DRM_DEBUG_KMS("HDMI Connected\n");
>                 }
> -               kfree(edid);
> +       } else {
> +               /*
> +               * Connector disconnected, free cached EDID
> +               * kfree is NULL protected, so will work for < gen 6 also */
> +               kfree(intel_hdmi->edid);
> +               DRM_DEBUG_KMS("HDMI Disconnected\n");
>         }
>
> +       /* Save latest EDID for further queries */
> +       intel_hdmi->edid = edid;
> +
>         if (status == connector_status_connected) {
>                 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
>                         intel_hdmi->has_audio =
> --
> 1.7.10.4
>
>
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Thursday, April 10, 2014 4:12 PM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
>
> Tizen-IVI has one feature will require hdmi edid cache. It will be happy to find your patch pushed into upstream tree.
>
> Regards
>
> Thanks
>
> Quanxian Wang
>
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, Shashank
> Sent: Wednesday, April 09, 2014 12:20 PM
> To: Wang, Quanxian; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
>
> Hello Quanxian Wang
>
> This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design.
>
> I was working on that, but couldn't finish the activity yet, Thanks for reminding me I will update soon. :)
>
> Regards
> Shashank
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Wednesday, April 09, 2014 11:49 AM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
>
> Hi, Sharma, Shashank
>
> Is there any following patches to make it happen?
>
> Thanks
>
> Regards
>
> Quanxian Wang
>
>>-----Original Message-----
>>From: intel-gfx-bounces@lists.freedesktop.org
>>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma,
>>Shashank
>>Sent: Tuesday, January 14, 2014 1:20 AM
>>To: Daniel Vetter
>>Cc: intel-gfx@lists.freedesktop.org
>>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect
>>and get_modes
>>
>>Thanks again for this explanation Daniel.
>>We will work on your suggestions and come up with a new patch.
>>
>>Regards
>>Shashank  / Ramalingam
>>-----Original Message-----
>>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf
>>Of Daniel Vetter
>>Sent: Monday, January 13, 2014 6:57 PM
>>To: Sharma, Shashank
>>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect
>>and get_modes
>>
>>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank
>><shashank.sharma@intel.com> wrote:
>>> Thanks a lot for your time, for reviewing the changes, and giving us
>>> some
>>pointers.
>>> Both me and Ramalingam are designing this together, and we discussed
>>> about
>>these changes and your suggestions.
>>> There are few things we would like to discuss about. Please correct
>>> us if some of
>>our understanding is not proper.
>>
>>First something I've forgotten in the original mail: Overall your
>>patches look really nice and the commit messages and cover letter have been excellent.
>>Unfortunately you've run into one of the nastier cases of "reality just
>>wont agree with the spec" :(
>>
>>> Those two patches provide two solution.
>>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC
>>> channel can
>>still get the EDID).
>>> 2. Try to reduce the EDID reads over DDC channel for get connector
>>> and fill mode
>>calls, by caching EDID, and using it until next HPD comes.
>>>
>>> Patch 2: Reduce the EDID read over DDC channel We are caching the
>>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on
>>> subsequent
>>HDMI disconnect calls.
>>>
>>> The design philosophy here is, to maintain a state machine of HDMI
>>> connector
>>status, and differentiate between IOCTL detect calls and HPD detect calls.
>>> If there is a detect() or get_modes() call due to any of the IOCTL,
>>> which makes
>>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>>> But if the detect call is coming from HPD work function, due to a HPD
>>> plug-out,
>>we remove/invalidate the old cached EDID, and cache the new EDID, on
>>subsequent HDMI plug-in.
>>> From here, the same state machine follows.
>>>
>>> Can you please let us know, why do you think that we should
>>> invalidate the
>>cached EDID after 1-2 seconds ?
>>
>>Because there are machines out there where hpd never happens. So if you
>>keep onto the cached value forever userspace will never notice a change
>>in output configuration. Of course hotplug handling won't work, but at
>>least users can still manually probe outputs. By unconditionally using
>>the cached edid from ioctls you break this use case. Yes, such machines
>>are broken, but we need to keep them working anyway.
>>
>>Also in my experience all machines are affected, we have examples
>>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet
>>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
>>
>>Generally if you use the hpd stuff your code must be designed under the
>>assumption that hpd is completely unreliably. We've seen anything from
>>random noise, flat-out not-working at all, stuck bits and unstable hpd
>>values that occasionally flip-flop. So you can't rely on it at all.
>>
>>> Note: In this same patch, there is additional optimization, which you
>>> pointed out,
>>where we check if the connector->status is same as live status.
>>> This can be removed independently, as you suggested.
>>
>>Hm, where have I pointed this out? Some other mail on internal discussions?
>>
>>> About patch 1:
>>> We have done some local experiments and we came to know that for VLV
>>> and
>>HSW boards, we can rely on the live status, if we give it some time to
>>settle (~300ms).
>>> Probably, we need to modify this patch, as you suggested, until it
>>> becomes
>>handy to be used reliably. We are on it, and will send another patch soon.
>>>
>>> But if somehow we are able to get some consistent results from live
>>> status, do
>>you think it would be worth accepting this change, so that it can
>>handle soft HPDs and automation testing.
>>> Because I believe we will face this problem whenever we are trying to
>>> test
>>something from automation, where the physical device is not removed,
>>and DDC channel is up always.
>>
>>It's very well possible that all the platforms you have, but experience
>>says that some OEM will horrible screw this up. At least they've
>>consistently botched this in the past on occasional machines.
>>
>>Now the ghost hdmi detection on slow removal is obviously not great,
>>but we can't use the hpd bits to fix this. One approach would be.
>>1. Upon hpd interrupt do an immediate probe of the connector. This way
>>we'll have good userspace experience if the unplug happens quickly and the hw works.
>>2. Re-probe with a 1s delay to catch slow-uplugs. The current output
>>probing helpers are clever enough already that if a state-change
>>happens to be detected a uevent will be generate, irrespective of the
>>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
>>
>>Note that we already track the hpd interrupts on a per-source basis, so
>>doing the re-poll shouldn't be costly. Maybe do the re-poll as part of
>>the EDID invalidation to avoid stalling userspace.
>>
>>But you can't rely upon the hpd pins unfortunately :(
>>
>>This way we should be able to implement the 2 features you want, even
>>on unreliable hw.
>>
>>Cheers, Daniel
>>--
>>Daniel Vetter
>>Software Engineer, Intel Corporation
>>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>>_______________________________________________
>>Intel-gfx mailing list
>>Intel-gfx@lists.freedesktop.org
>>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-11 12:58                     ` Daniel Vetter
@ 2014-04-11 13:23                       ` Sharma, Shashank
  2014-04-11 14:22                         ` Daniel Vetter
  0 siblings, 1 reply; 716+ messages in thread
From: Sharma, Shashank @ 2014-04-11 13:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Thanks for the comments, 
Actually, we are not using live_status at all. 

The check for < gen6 is only for EDID caching. So if the HW is >= gen6 cache_edid.  
Else do not cache EDID, so that we will not block any of the old HW, which might not be HPD capable.

Does it sound ok now :) ?  

Regards
Shashank 
-----Original Message-----
From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Friday, April 11, 2014 6:28 PM
To: Sharma, Shashank
Cc: C, Ramalingam; Wang, Quanxian; intel-gfx
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

Please don't drop the mailing list when discussing patches.

And nope, conditioning this on gen6+ won't help at all, since I have a
gen6 and gen7 machine here which don't have reliable hdmi live status.
Afaik that is _really_ broken across the board and going with the fancy invalidation scheme and delayed work items is the way forward.

Cheers, Daniel

On Fri, Apr 11, 2014 at 2:51 PM, Sharma, Shashank <shashank.sharma@intel.com> wrote:
> Hi Daniel,
>
> First of all, sorry for the delay in coming up with the new patch set. I got stuck with some commercial projects :) .
>
> There were few review comments what you gave for the previous optimization patch, those were:
> 1.  This might break the old HWs. Few of them might not even be HPD capable, so its required to handle them.
> 2.  Do not rely on the live_status check, as that HW is not yet proven.
> And you recommended to have a WQ, which will invalidate the cached HDMI EDID after a timeout.
>
> I have written another patch, which is addressing both of the above comments, but doesn't use a WQ.
>
> Before sending this to ML, I wanted to have an opinion from you, if this qualifies the design you were expecting.
> I will be really glad, if you can spare some time, and just have a top level view on the patch, and give your opinion.
>
> If you think that this is still not the way, and making a WQ is a better approach, I would gladly create a patch which applies that.
> Or if you will prefer to have this reviewed in the mailing list only, please accept my apologies for direct contact, and just let me know so. I will publish this in ML.
>
> The patch is (It's also attached):
>
> From e7ec4e4827615c0ff3a4ddb020df35fdf1b0b82f Mon Sep 17 00:00:00 2001
> From: Shashank Sharma <shashank.sharma@intel.com>
> Date: Fri, 11 Apr 2014 18:02:50 +0530
> Subject: [PATCH] drm/i915: Cache HDMI EDID for future reference
>
> This patch contains following changes:
> 1.Cache HDMI EDID and optimize detect() calls, which are
>   frequently called from userspace, causing un-necessary
>   EDID reads.
> 2.This cached EDID will be used for detection of the status of
>   HDMI connector, for Non HPD detect() calls. HPD calls will update
>   cached EDID.
> 3.This optimization is kept for new HW's (Gen6 and +), so that It
>   will not break old HWs who may not be even HPD capable.
>
> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h  |    1 +
>  drivers/gpu/drm/i915/intel_hdmi.c |   28 ++++++++++++++++++++++++++--
>  2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 42762b7..b7911df 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -478,6 +478,7 @@ struct intel_hdmi {
>                                 const void *frame, ssize_t len);
>         void (*set_infoframes)(struct drm_encoder *encoder,
>                                struct drm_display_mode 
> *adjusted_mode);
> +       struct edid *edid;
>  };
>
>  #define DP_MAX_DOWNSTREAM_PORTS                0x10
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> b/drivers/gpu/drm/i915/intel_hdmi.c
> index b0413e1..33550ca 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -938,7 +938,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>                 hdmi_to_dig_port(intel_hdmi);
>         struct intel_encoder *intel_encoder = &intel_dig_port->base;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct edid *edid;
> +       struct edid *edid = NULL;
>         enum intel_display_power_domain power_domain;
>         enum drm_connector_status status = 
> connector_status_disconnected;
>
> @@ -948,6 +948,21 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>         power_domain = intel_display_port_power_domain(intel_encoder);
>         intel_display_power_get(dev_priv, power_domain);
>
> +       /*
> +       * Support EDID caching only for new architectures
> +       * Let old architectures probe and force read EDID
> +       */
> +       if (INTEL_INFO(dev)->gen >= 6) {
> +               if (force && intel_hdmi->edid &&
> +                       (connector->status != connector_status_unknown)) {
> +                       /* Optimize userspace query, read EDID only
> +                       in case of a real hot plug */
> +                       DRM_DEBUG_KMS("HDMI %s", intel_hdmi->edid ?
> +                               "Connected" : "Disconnected");
> +                       return connector->status;
> +               }
> +       }
> +
>         intel_hdmi->has_hdmi_sink = false;
>         intel_hdmi->has_audio = false;
>         intel_hdmi->rgb_quant_range_selectable = false; @@ -964,10 
> +979,19 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
>                         intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
>                         intel_hdmi->rgb_quant_range_selectable =
>                                 drm_rgb_quant_range_selectable(edid);
> +                       DRM_DEBUG_KMS("HDMI Connected\n");
>                 }
> -               kfree(edid);
> +       } else {
> +               /*
> +               * Connector disconnected, free cached EDID
> +               * kfree is NULL protected, so will work for < gen 6 also */
> +               kfree(intel_hdmi->edid);
> +               DRM_DEBUG_KMS("HDMI Disconnected\n");
>         }
>
> +       /* Save latest EDID for further queries */
> +       intel_hdmi->edid = edid;
> +
>         if (status == connector_status_connected) {
>                 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
>                         intel_hdmi->has_audio =
> --
> 1.7.10.4
>
>
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Thursday, April 10, 2014 4:12 PM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
>
> Tizen-IVI has one feature will require hdmi edid cache. It will be happy to find your patch pushed into upstream tree.
>
> Regards
>
> Thanks
>
> Quanxian Wang
>
> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On 
> Behalf Of Sharma, Shashank
> Sent: Wednesday, April 09, 2014 12:20 PM
> To: Wang, Quanxian; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
>
> Hello Quanxian Wang
>
> This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design.
>
> I was working on that, but couldn't finish the activity yet, Thanks 
> for reminding me I will update soon. :)
>
> Regards
> Shashank
> -----Original Message-----
> From: Wang, Quanxian
> Sent: Wednesday, April 09, 2014 11:49 AM
> To: Sharma, Shashank; Daniel Vetter
> Cc: intel-gfx@lists.freedesktop.org
> Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
>
> Hi, Sharma, Shashank
>
> Is there any following patches to make it happen?
>
> Thanks
>
> Regards
>
> Quanxian Wang
>
>>-----Original Message-----
>>From: intel-gfx-bounces@lists.freedesktop.org
>>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
>>Shashank
>>Sent: Tuesday, January 14, 2014 1:20 AM
>>To: Daniel Vetter
>>Cc: intel-gfx@lists.freedesktop.org
>>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>>and get_modes
>>
>>Thanks again for this explanation Daniel.
>>We will work on your suggestions and come up with a new patch.
>>
>>Regards
>>Shashank  / Ramalingam
>>-----Original Message-----
>>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
>>Of Daniel Vetter
>>Sent: Monday, January 13, 2014 6:57 PM
>>To: Sharma, Shashank
>>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
>>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
>>and get_modes
>>
>>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
>><shashank.sharma@intel.com> wrote:
>>> Thanks a lot for your time, for reviewing the changes, and giving us 
>>> some
>>pointers.
>>> Both me and Ramalingam are designing this together, and we discussed 
>>> about
>>these changes and your suggestions.
>>> There are few things we would like to discuss about. Please correct 
>>> us if some of
>>our understanding is not proper.
>>
>>First something I've forgotten in the original mail: Overall your 
>>patches look really nice and the commit messages and cover letter have been excellent.
>>Unfortunately you've run into one of the nastier cases of "reality 
>>just wont agree with the spec" :(
>>
>>> Those two patches provide two solution.
>>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
>>> channel can
>>still get the EDID).
>>> 2. Try to reduce the EDID reads over DDC channel for get connector 
>>> and fill mode
>>calls, by caching EDID, and using it until next HPD comes.
>>>
>>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
>>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
>>> subsequent
>>HDMI disconnect calls.
>>>
>>> The design philosophy here is, to maintain a state machine of HDMI 
>>> connector
>>status, and differentiate between IOCTL detect calls and HPD detect calls.
>>> If there is a detect() or get_modes() call due to any of the IOCTL, 
>>> which makes
>>sure that input variable force=1, we just use the cached EDID, to serve this calls.
>>> But if the detect call is coming from HPD work function, due to a 
>>> HPD plug-out,
>>we remove/invalidate the old cached EDID, and cache the new EDID, on 
>>subsequent HDMI plug-in.
>>> From here, the same state machine follows.
>>>
>>> Can you please let us know, why do you think that we should 
>>> invalidate the
>>cached EDID after 1-2 seconds ?
>>
>>Because there are machines out there where hpd never happens. So if 
>>you keep onto the cached value forever userspace will never notice a 
>>change in output configuration. Of course hotplug handling won't work, 
>>but at least users can still manually probe outputs. By 
>>unconditionally using the cached edid from ioctls you break this use 
>>case. Yes, such machines are broken, but we need to keep them working anyway.
>>
>>Also in my experience all machines are affected, we have examples 
>>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
>>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
>>
>>Generally if you use the hpd stuff your code must be designed under 
>>the assumption that hpd is completely unreliably. We've seen anything 
>>from random noise, flat-out not-working at all, stuck bits and 
>>unstable hpd values that occasionally flip-flop. So you can't rely on it at all.
>>
>>> Note: In this same patch, there is additional optimization, which 
>>> you pointed out,
>>where we check if the connector->status is same as live status.
>>> This can be removed independently, as you suggested.
>>
>>Hm, where have I pointed this out? Some other mail on internal discussions?
>>
>>> About patch 1:
>>> We have done some local experiments and we came to know that for VLV 
>>> and
>>HSW boards, we can rely on the live status, if we give it some time to 
>>settle (~300ms).
>>> Probably, we need to modify this patch, as you suggested, until it 
>>> becomes
>>handy to be used reliably. We are on it, and will send another patch soon.
>>>
>>> But if somehow we are able to get some consistent results from live 
>>> status, do
>>you think it would be worth accepting this change, so that it can 
>>handle soft HPDs and automation testing.
>>> Because I believe we will face this problem whenever we are trying 
>>> to test
>>something from automation, where the physical device is not removed, 
>>and DDC channel is up always.
>>
>>It's very well possible that all the platforms you have, but 
>>experience says that some OEM will horrible screw this up. At least 
>>they've consistently botched this in the past on occasional machines.
>>
>>Now the ghost hdmi detection on slow removal is obviously not great, 
>>but we can't use the hpd bits to fix this. One approach would be.
>>1. Upon hpd interrupt do an immediate probe of the connector. This way 
>>we'll have good userspace experience if the unplug happens quickly and the hw works.
>>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
>>probing helpers are clever enough already that if a state-change 
>>happens to be detected a uevent will be generate, irrespective of the 
>>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
>>
>>Note that we already track the hpd interrupts on a per-source basis, 
>>so doing the re-poll shouldn't be costly. Maybe do the re-poll as part 
>>of the EDID invalidation to avoid stalling userspace.
>>
>>But you can't rely upon the hpd pins unfortunately :(
>>
>>This way we should be able to implement the 2 features you want, even 
>>on unreliable hw.
>>
>>Cheers, Daniel
>>--
>>Daniel Vetter
>>Software Engineer, Intel Corporation
>>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
>>_______________________________________________
>>Intel-gfx mailing list
>>Intel-gfx@lists.freedesktop.org
>>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-11 13:23                       ` Sharma, Shashank
@ 2014-04-11 14:22                         ` Daniel Vetter
  2014-04-11 14:48                           ` Sharma, Shashank
  0 siblings, 1 reply; 716+ messages in thread
From: Daniel Vetter @ 2014-04-11 14:22 UTC (permalink / raw)
  To: Sharma, Shashank; +Cc: intel-gfx

On Fri, Apr 11, 2014 at 01:23:43PM +0000, Sharma, Shashank wrote:
> Thanks for the comments, 
> Actually, we are not using live_status at all. 
> 
> The check for < gen6 is only for EDID caching. So if the HW is >= gen6 cache_edid.  
> Else do not cache EDID, so that we will not block any of the old HW, which might not be HPD capable.

Oh, I've thought that this is incremental on top of something you already
have.
> 
> Does it sound ok now :) ?  

No. HPD is _NOT_ I repeat _NOT_ reliably. Not even on gen6+. live status
simply reflects the hpd pin, if either doesn't work, then neither does the
other one.

Nacked-with-prejudice-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Cheers, Daniel

> 
> Regards
> Shashank 
> -----Original Message-----
> From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Friday, April 11, 2014 6:28 PM
> To: Sharma, Shashank
> Cc: C, Ramalingam; Wang, Quanxian; intel-gfx
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
> 
> Please don't drop the mailing list when discussing patches.
> 
> And nope, conditioning this on gen6+ won't help at all, since I have a
> gen6 and gen7 machine here which don't have reliable hdmi live status.
> Afaik that is _really_ broken across the board and going with the fancy invalidation scheme and delayed work items is the way forward.
> 
> Cheers, Daniel
> 
> On Fri, Apr 11, 2014 at 2:51 PM, Sharma, Shashank <shashank.sharma@intel.com> wrote:
> > Hi Daniel,
> >
> > First of all, sorry for the delay in coming up with the new patch set. I got stuck with some commercial projects :) .
> >
> > There were few review comments what you gave for the previous optimization patch, those were:
> > 1.  This might break the old HWs. Few of them might not even be HPD capable, so its required to handle them.
> > 2.  Do not rely on the live_status check, as that HW is not yet proven.
> > And you recommended to have a WQ, which will invalidate the cached HDMI EDID after a timeout.
> >
> > I have written another patch, which is addressing both of the above comments, but doesn't use a WQ.
> >
> > Before sending this to ML, I wanted to have an opinion from you, if this qualifies the design you were expecting.
> > I will be really glad, if you can spare some time, and just have a top level view on the patch, and give your opinion.
> >
> > If you think that this is still not the way, and making a WQ is a better approach, I would gladly create a patch which applies that.
> > Or if you will prefer to have this reviewed in the mailing list only, please accept my apologies for direct contact, and just let me know so. I will publish this in ML.
> >
> > The patch is (It's also attached):
> >
> > From e7ec4e4827615c0ff3a4ddb020df35fdf1b0b82f Mon Sep 17 00:00:00 2001
> > From: Shashank Sharma <shashank.sharma@intel.com>
> > Date: Fri, 11 Apr 2014 18:02:50 +0530
> > Subject: [PATCH] drm/i915: Cache HDMI EDID for future reference
> >
> > This patch contains following changes:
> > 1.Cache HDMI EDID and optimize detect() calls, which are
> >   frequently called from userspace, causing un-necessary
> >   EDID reads.
> > 2.This cached EDID will be used for detection of the status of
> >   HDMI connector, for Non HPD detect() calls. HPD calls will update
> >   cached EDID.
> > 3.This optimization is kept for new HW's (Gen6 and +), so that It
> >   will not break old HWs who may not be even HPD capable.
> >
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_drv.h  |    1 +
> >  drivers/gpu/drm/i915/intel_hdmi.c |   28 ++++++++++++++++++++++++++--
> >  2 files changed, 27 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 42762b7..b7911df 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -478,6 +478,7 @@ struct intel_hdmi {
> >                                 const void *frame, ssize_t len);
> >         void (*set_infoframes)(struct drm_encoder *encoder,
> >                                struct drm_display_mode 
> > *adjusted_mode);
> > +       struct edid *edid;
> >  };
> >
> >  #define DP_MAX_DOWNSTREAM_PORTS                0x10
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c 
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index b0413e1..33550ca 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -938,7 +938,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >                 hdmi_to_dig_port(intel_hdmi);
> >         struct intel_encoder *intel_encoder = &intel_dig_port->base;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct edid *edid;
> > +       struct edid *edid = NULL;
> >         enum intel_display_power_domain power_domain;
> >         enum drm_connector_status status = 
> > connector_status_disconnected;
> >
> > @@ -948,6 +948,21 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >         power_domain = intel_display_port_power_domain(intel_encoder);
> >         intel_display_power_get(dev_priv, power_domain);
> >
> > +       /*
> > +       * Support EDID caching only for new architectures
> > +       * Let old architectures probe and force read EDID
> > +       */
> > +       if (INTEL_INFO(dev)->gen >= 6) {
> > +               if (force && intel_hdmi->edid &&
> > +                       (connector->status != connector_status_unknown)) {
> > +                       /* Optimize userspace query, read EDID only
> > +                       in case of a real hot plug */
> > +                       DRM_DEBUG_KMS("HDMI %s", intel_hdmi->edid ?
> > +                               "Connected" : "Disconnected");
> > +                       return connector->status;
> > +               }
> > +       }
> > +
> >         intel_hdmi->has_hdmi_sink = false;
> >         intel_hdmi->has_audio = false;
> >         intel_hdmi->rgb_quant_range_selectable = false; @@ -964,10 
> > +979,19 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >                         intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
> >                         intel_hdmi->rgb_quant_range_selectable =
> >                                 drm_rgb_quant_range_selectable(edid);
> > +                       DRM_DEBUG_KMS("HDMI Connected\n");
> >                 }
> > -               kfree(edid);
> > +       } else {
> > +               /*
> > +               * Connector disconnected, free cached EDID
> > +               * kfree is NULL protected, so will work for < gen 6 also */
> > +               kfree(intel_hdmi->edid);
> > +               DRM_DEBUG_KMS("HDMI Disconnected\n");
> >         }
> >
> > +       /* Save latest EDID for further queries */
> > +       intel_hdmi->edid = edid;
> > +
> >         if (status == connector_status_connected) {
> >                 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
> >                         intel_hdmi->has_audio =
> > --
> > 1.7.10.4
> >
> >
> > -----Original Message-----
> > From: Wang, Quanxian
> > Sent: Thursday, April 10, 2014 4:12 PM
> > To: Sharma, Shashank; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> > and get_modes
> >
> > Tizen-IVI has one feature will require hdmi edid cache. It will be happy to find your patch pushed into upstream tree.
> >
> > Regards
> >
> > Thanks
> >
> > Quanxian Wang
> >
> > -----Original Message-----
> > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On 
> > Behalf Of Sharma, Shashank
> > Sent: Wednesday, April 09, 2014 12:20 PM
> > To: Wang, Quanxian; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> > and get_modes
> >
> > Hello Quanxian Wang
> >
> > This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design.
> >
> > I was working on that, but couldn't finish the activity yet, Thanks 
> > for reminding me I will update soon. :)
> >
> > Regards
> > Shashank
> > -----Original Message-----
> > From: Wang, Quanxian
> > Sent: Wednesday, April 09, 2014 11:49 AM
> > To: Sharma, Shashank; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> > and get_modes
> >
> > Hi, Sharma, Shashank
> >
> > Is there any following patches to make it happen?
> >
> > Thanks
> >
> > Regards
> >
> > Quanxian Wang
> >
> >>-----Original Message-----
> >>From: intel-gfx-bounces@lists.freedesktop.org
> >>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of Sharma, 
> >>Shashank
> >>Sent: Tuesday, January 14, 2014 1:20 AM
> >>To: Daniel Vetter
> >>Cc: intel-gfx@lists.freedesktop.org
> >>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> >>and get_modes
> >>
> >>Thanks again for this explanation Daniel.
> >>We will work on your suggestions and come up with a new patch.
> >>
> >>Regards
> >>Shashank  / Ramalingam
> >>-----Original Message-----
> >>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
> >>Of Daniel Vetter
> >>Sent: Monday, January 13, 2014 6:57 PM
> >>To: Sharma, Shashank
> >>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
> >>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> >>and get_modes
> >>
> >>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
> >><shashank.sharma@intel.com> wrote:
> >>> Thanks a lot for your time, for reviewing the changes, and giving us 
> >>> some
> >>pointers.
> >>> Both me and Ramalingam are designing this together, and we discussed 
> >>> about
> >>these changes and your suggestions.
> >>> There are few things we would like to discuss about. Please correct 
> >>> us if some of
> >>our understanding is not proper.
> >>
> >>First something I've forgotten in the original mail: Overall your 
> >>patches look really nice and the commit messages and cover letter have been excellent.
> >>Unfortunately you've run into one of the nastier cases of "reality 
> >>just wont agree with the spec" :(
> >>
> >>> Those two patches provide two solution.
> >>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
> >>> channel can
> >>still get the EDID).
> >>> 2. Try to reduce the EDID reads over DDC channel for get connector 
> >>> and fill mode
> >>calls, by caching EDID, and using it until next HPD comes.
> >>>
> >>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
> >>> EDID at every HPD up, on HDMI detect calls, and we are freeing it on 
> >>> subsequent
> >>HDMI disconnect calls.
> >>>
> >>> The design philosophy here is, to maintain a state machine of HDMI 
> >>> connector
> >>status, and differentiate between IOCTL detect calls and HPD detect calls.
> >>> If there is a detect() or get_modes() call due to any of the IOCTL, 
> >>> which makes
> >>sure that input variable force=1, we just use the cached EDID, to serve this calls.
> >>> But if the detect call is coming from HPD work function, due to a 
> >>> HPD plug-out,
> >>we remove/invalidate the old cached EDID, and cache the new EDID, on 
> >>subsequent HDMI plug-in.
> >>> From here, the same state machine follows.
> >>>
> >>> Can you please let us know, why do you think that we should 
> >>> invalidate the
> >>cached EDID after 1-2 seconds ?
> >>
> >>Because there are machines out there where hpd never happens. So if 
> >>you keep onto the cached value forever userspace will never notice a 
> >>change in output configuration. Of course hotplug handling won't work, 
> >>but at least users can still manually probe outputs. By 
> >>unconditionally using the cached edid from ioctls you break this use 
> >>case. Yes, such machines are broken, but we need to keep them working anyway.
> >>
> >>Also in my experience all machines are affected, we have examples 
> >>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt yet 
> >>since we don't rely on the hpd bits any more (and so won't see bug reports any more).
> >>
> >>Generally if you use the hpd stuff your code must be designed under 
> >>the assumption that hpd is completely unreliably. We've seen anything 
> >>from random noise, flat-out not-working at all, stuck bits and 
> >>unstable hpd values that occasionally flip-flop. So you can't rely on it at all.
> >>
> >>> Note: In this same patch, there is additional optimization, which 
> >>> you pointed out,
> >>where we check if the connector->status is same as live status.
> >>> This can be removed independently, as you suggested.
> >>
> >>Hm, where have I pointed this out? Some other mail on internal discussions?
> >>
> >>> About patch 1:
> >>> We have done some local experiments and we came to know that for VLV 
> >>> and
> >>HSW boards, we can rely on the live status, if we give it some time to 
> >>settle (~300ms).
> >>> Probably, we need to modify this patch, as you suggested, until it 
> >>> becomes
> >>handy to be used reliably. We are on it, and will send another patch soon.
> >>>
> >>> But if somehow we are able to get some consistent results from live 
> >>> status, do
> >>you think it would be worth accepting this change, so that it can 
> >>handle soft HPDs and automation testing.
> >>> Because I believe we will face this problem whenever we are trying 
> >>> to test
> >>something from automation, where the physical device is not removed, 
> >>and DDC channel is up always.
> >>
> >>It's very well possible that all the platforms you have, but 
> >>experience says that some OEM will horrible screw this up. At least 
> >>they've consistently botched this in the past on occasional machines.
> >>
> >>Now the ghost hdmi detection on slow removal is obviously not great, 
> >>but we can't use the hpd bits to fix this. One approach would be.
> >>1. Upon hpd interrupt do an immediate probe of the connector. This way 
> >>we'll have good userspace experience if the unplug happens quickly and the hw works.
> >>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
> >>probing helpers are clever enough already that if a state-change 
> >>happens to be detected a uevent will be generate, irrespective of the 
> >>source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
> >>
> >>Note that we already track the hpd interrupts on a per-source basis, 
> >>so doing the re-poll shouldn't be costly. Maybe do the re-poll as part 
> >>of the EDID invalidation to avoid stalling userspace.
> >>
> >>But you can't rely upon the hpd pins unfortunately :(
> >>
> >>This way we should be able to implement the 2 features you want, even 
> >>on unreliable hw.
> >>
> >>Cheers, Daniel
> >>--
> >>Daniel Vetter
> >>Software Engineer, Intel Corporation
> >>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
> >>_______________________________________________
> >>Intel-gfx mailing list
> >>Intel-gfx@lists.freedesktop.org
> >>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-11 14:22                         ` Daniel Vetter
@ 2014-04-11 14:48                           ` Sharma, Shashank
  2014-07-16 14:29                             ` Kumar, Shobhit
  0 siblings, 1 reply; 716+ messages in thread
From: Sharma, Shashank @ 2014-04-11 14:48 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

Ok, I will change the implementation. 

Regards
Shashank 
-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Friday, April 11, 2014 7:53 PM
To: Sharma, Shashank
Cc: Daniel Vetter; C, Ramalingam; Wang, Quanxian; intel-gfx
Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes

On Fri, Apr 11, 2014 at 01:23:43PM +0000, Sharma, Shashank wrote:
> Thanks for the comments,
> Actually, we are not using live_status at all. 
> 
> The check for < gen6 is only for EDID caching. So if the HW is >= gen6 cache_edid.  
> Else do not cache EDID, so that we will not block any of the old HW, which might not be HPD capable.

Oh, I've thought that this is incremental on top of something you already have.
> 
> Does it sound ok now :) ?  

No. HPD is _NOT_ I repeat _NOT_ reliably. Not even on gen6+. live status simply reflects the hpd pin, if either doesn't work, then neither does the other one.

Nacked-with-prejudice-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Cheers, Daniel

> 
> Regards
> Shashank
> -----Original Message-----
> From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On Behalf 
> Of Daniel Vetter
> Sent: Friday, April 11, 2014 6:28 PM
> To: Sharma, Shashank
> Cc: C, Ramalingam; Wang, Quanxian; intel-gfx
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect 
> and get_modes
> 
> Please don't drop the mailing list when discussing patches.
> 
> And nope, conditioning this on gen6+ won't help at all, since I have a
> gen6 and gen7 machine here which don't have reliable hdmi live status.
> Afaik that is _really_ broken across the board and going with the fancy invalidation scheme and delayed work items is the way forward.
> 
> Cheers, Daniel
> 
> On Fri, Apr 11, 2014 at 2:51 PM, Sharma, Shashank <shashank.sharma@intel.com> wrote:
> > Hi Daniel,
> >
> > First of all, sorry for the delay in coming up with the new patch set. I got stuck with some commercial projects :) .
> >
> > There were few review comments what you gave for the previous optimization patch, those were:
> > 1.  This might break the old HWs. Few of them might not even be HPD capable, so its required to handle them.
> > 2.  Do not rely on the live_status check, as that HW is not yet proven.
> > And you recommended to have a WQ, which will invalidate the cached HDMI EDID after a timeout.
> >
> > I have written another patch, which is addressing both of the above comments, but doesn't use a WQ.
> >
> > Before sending this to ML, I wanted to have an opinion from you, if this qualifies the design you were expecting.
> > I will be really glad, if you can spare some time, and just have a top level view on the patch, and give your opinion.
> >
> > If you think that this is still not the way, and making a WQ is a better approach, I would gladly create a patch which applies that.
> > Or if you will prefer to have this reviewed in the mailing list only, please accept my apologies for direct contact, and just let me know so. I will publish this in ML.
> >
> > The patch is (It's also attached):
> >
> > From e7ec4e4827615c0ff3a4ddb020df35fdf1b0b82f Mon Sep 17 00:00:00 
> > 2001
> > From: Shashank Sharma <shashank.sharma@intel.com>
> > Date: Fri, 11 Apr 2014 18:02:50 +0530
> > Subject: [PATCH] drm/i915: Cache HDMI EDID for future reference
> >
> > This patch contains following changes:
> > 1.Cache HDMI EDID and optimize detect() calls, which are
> >   frequently called from userspace, causing un-necessary
> >   EDID reads.
> > 2.This cached EDID will be used for detection of the status of
> >   HDMI connector, for Non HPD detect() calls. HPD calls will update
> >   cached EDID.
> > 3.This optimization is kept for new HW's (Gen6 and +), so that It
> >   will not break old HWs who may not be even HPD capable.
> >
> > Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_drv.h  |    1 +
> >  drivers/gpu/drm/i915/intel_hdmi.c |   28 ++++++++++++++++++++++++++--
> >  2 files changed, 27 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 42762b7..b7911df 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -478,6 +478,7 @@ struct intel_hdmi {
> >                                 const void *frame, ssize_t len);
> >         void (*set_infoframes)(struct drm_encoder *encoder,
> >                                struct drm_display_mode 
> > *adjusted_mode);
> > +       struct edid *edid;
> >  };
> >
> >  #define DP_MAX_DOWNSTREAM_PORTS                0x10
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c
> > b/drivers/gpu/drm/i915/intel_hdmi.c
> > index b0413e1..33550ca 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -938,7 +938,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >                 hdmi_to_dig_port(intel_hdmi);
> >         struct intel_encoder *intel_encoder = &intel_dig_port->base;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct edid *edid;
> > +       struct edid *edid = NULL;
> >         enum intel_display_power_domain power_domain;
> >         enum drm_connector_status status = 
> > connector_status_disconnected;
> >
> > @@ -948,6 +948,21 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
> >         power_domain = intel_display_port_power_domain(intel_encoder);
> >         intel_display_power_get(dev_priv, power_domain);
> >
> > +       /*
> > +       * Support EDID caching only for new architectures
> > +       * Let old architectures probe and force read EDID
> > +       */
> > +       if (INTEL_INFO(dev)->gen >= 6) {
> > +               if (force && intel_hdmi->edid &&
> > +                       (connector->status != connector_status_unknown)) {
> > +                       /* Optimize userspace query, read EDID only
> > +                       in case of a real hot plug */
> > +                       DRM_DEBUG_KMS("HDMI %s", intel_hdmi->edid ?
> > +                               "Connected" : "Disconnected");
> > +                       return connector->status;
> > +               }
> > +       }
> > +
> >         intel_hdmi->has_hdmi_sink = false;
> >         intel_hdmi->has_audio = false;
> >         intel_hdmi->rgb_quant_range_selectable = false; @@ -964,10
> > +979,19 @@ intel_hdmi_detect(struct drm_connector *connector, bool 
> > +force)
> >                         intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
> >                         intel_hdmi->rgb_quant_range_selectable =
> >                                 
> > drm_rgb_quant_range_selectable(edid);
> > +                       DRM_DEBUG_KMS("HDMI Connected\n");
> >                 }
> > -               kfree(edid);
> > +       } else {
> > +               /*
> > +               * Connector disconnected, free cached EDID
> > +               * kfree is NULL protected, so will work for < gen 6 also */
> > +               kfree(intel_hdmi->edid);
> > +               DRM_DEBUG_KMS("HDMI Disconnected\n");
> >         }
> >
> > +       /* Save latest EDID for further queries */
> > +       intel_hdmi->edid = edid;
> > +
> >         if (status == connector_status_connected) {
> >                 if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO)
> >                         intel_hdmi->has_audio =
> > --
> > 1.7.10.4
> >
> >
> > -----Original Message-----
> > From: Wang, Quanxian
> > Sent: Thursday, April 10, 2014 4:12 PM
> > To: Sharma, Shashank; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> > detect and get_modes
> >
> > Tizen-IVI has one feature will require hdmi edid cache. It will be happy to find your patch pushed into upstream tree.
> >
> > Regards
> >
> > Thanks
> >
> > Quanxian Wang
> >
> > -----Original Message-----
> > From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On 
> > Behalf Of Sharma, Shashank
> > Sent: Wednesday, April 09, 2014 12:20 PM
> > To: Wang, Quanxian; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> > detect and get_modes
> >
> > Hello Quanxian Wang
> >
> > This patch is available and working on all MCG tree's (Main, R42B and R44B) We were trying to opensource this patch, but due to the dependency on live_status reg, we had to change the design.
> >
> > I was working on that, but couldn't finish the activity yet, Thanks 
> > for reminding me I will update soon. :)
> >
> > Regards
> > Shashank
> > -----Original Message-----
> > From: Wang, Quanxian
> > Sent: Wednesday, April 09, 2014 11:49 AM
> > To: Sharma, Shashank; Daniel Vetter
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: RE: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> > detect and get_modes
> >
> > Hi, Sharma, Shashank
> >
> > Is there any following patches to make it happen?
> >
> > Thanks
> >
> > Regards
> >
> > Quanxian Wang
> >
> >>-----Original Message-----
> >>From: intel-gfx-bounces@lists.freedesktop.org
> >>[mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of 
> >>Sharma, Shashank
> >>Sent: Tuesday, January 14, 2014 1:20 AM
> >>To: Daniel Vetter
> >>Cc: intel-gfx@lists.freedesktop.org
> >>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> >>detect and get_modes
> >>
> >>Thanks again for this explanation Daniel.
> >>We will work on your suggestions and come up with a new patch.
> >>
> >>Regards
> >>Shashank  / Ramalingam
> >>-----Original Message-----
> >>From: daniel.vetter@ffwll.ch [mailto:daniel.vetter@ffwll.ch] On 
> >>Behalf Of Daniel Vetter
> >>Sent: Monday, January 13, 2014 6:57 PM
> >>To: Sharma, Shashank
> >>Cc: C, Ramalingam; intel-gfx@lists.freedesktop.org
> >>Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI 
> >>detect and get_modes
> >>
> >>On Mon, Jan 13, 2014 at 10:39 AM, Sharma, Shashank 
> >><shashank.sharma@intel.com> wrote:
> >>> Thanks a lot for your time, for reviewing the changes, and giving 
> >>> us some
> >>pointers.
> >>> Both me and Ramalingam are designing this together, and we 
> >>> discussed about
> >>these changes and your suggestions.
> >>> There are few things we would like to discuss about. Please 
> >>> correct us if some of
> >>our understanding is not proper.
> >>
> >>First something I've forgotten in the original mail: Overall your 
> >>patches look really nice and the commit messages and cover letter have been excellent.
> >>Unfortunately you've run into one of the nastier cases of "reality 
> >>just wont agree with the spec" :(
> >>
> >>> Those two patches provide two solution.
> >>> 1. Support for soft HPD, and slow removal of HDMI (when the DDC 
> >>> channel can
> >>still get the EDID).
> >>> 2. Try to reduce the EDID reads over DDC channel for get connector 
> >>> and fill mode
> >>calls, by caching EDID, and using it until next HPD comes.
> >>>
> >>> Patch 2: Reduce the EDID read over DDC channel We are caching the 
> >>> EDID at every HPD up, on HDMI detect calls, and we are freeing it 
> >>> on subsequent
> >>HDMI disconnect calls.
> >>>
> >>> The design philosophy here is, to maintain a state machine of HDMI 
> >>> connector
> >>status, and differentiate between IOCTL detect calls and HPD detect calls.
> >>> If there is a detect() or get_modes() call due to any of the 
> >>> IOCTL, which makes
> >>sure that input variable force=1, we just use the cached EDID, to serve this calls.
> >>> But if the detect call is coming from HPD work function, due to a 
> >>> HPD plug-out,
> >>we remove/invalidate the old cached EDID, and cache the new EDID, on 
> >>subsequent HDMI plug-in.
> >>> From here, the same state machine follows.
> >>>
> >>> Can you please let us know, why do you think that we should 
> >>> invalidate the
> >>cached EDID after 1-2 seconds ?
> >>
> >>Because there are machines out there where hpd never happens. So if 
> >>you keep onto the cached value forever userspace will never notice a 
> >>change in output configuration. Of course hotplug handling won't 
> >>work, but at least users can still manually probe outputs. By 
> >>unconditionally using the cached edid from ioctls you break this use 
> >>case. Yes, such machines are broken, but we need to keep them working anyway.
> >>
> >>Also in my experience all machines are affected, we have examples 
> >>covering gm45, ilk, snb & ivb. We haven't seen a case for hsw/byt 
> >>yet since we don't rely on the hpd bits any more (and so won't see bug reports any more).
> >>
> >>Generally if you use the hpd stuff your code must be designed under 
> >>the assumption that hpd is completely unreliably. We've seen 
> >>anything from random noise, flat-out not-working at all, stuck bits 
> >>and unstable hpd values that occasionally flip-flop. So you can't rely on it at all.
> >>
> >>> Note: In this same patch, there is additional optimization, which 
> >>> you pointed out,
> >>where we check if the connector->status is same as live status.
> >>> This can be removed independently, as you suggested.
> >>
> >>Hm, where have I pointed this out? Some other mail on internal discussions?
> >>
> >>> About patch 1:
> >>> We have done some local experiments and we came to know that for 
> >>> VLV and
> >>HSW boards, we can rely on the live status, if we give it some time 
> >>to settle (~300ms).
> >>> Probably, we need to modify this patch, as you suggested, until it 
> >>> becomes
> >>handy to be used reliably. We are on it, and will send another patch soon.
> >>>
> >>> But if somehow we are able to get some consistent results from 
> >>> live status, do
> >>you think it would be worth accepting this change, so that it can 
> >>handle soft HPDs and automation testing.
> >>> Because I believe we will face this problem whenever we are trying 
> >>> to test
> >>something from automation, where the physical device is not removed, 
> >>and DDC channel is up always.
> >>
> >>It's very well possible that all the platforms you have, but 
> >>experience says that some OEM will horrible screw this up. At least 
> >>they've consistently botched this in the past on occasional machines.
> >>
> >>Now the ghost hdmi detection on slow removal is obviously not great, 
> >>but we can't use the hpd bits to fix this. One approach would be.
> >>1. Upon hpd interrupt do an immediate probe of the connector. This 
> >>way we'll have good userspace experience if the unplug happens quickly and the hw works.
> >>2. Re-probe with a 1s delay to catch slow-uplugs. The current output 
> >>probing helpers are clever enough already that if a state-change 
> >>happens to be detected a uevent will be generate, irrespective of 
> >>the source of the detect call (i.e. hpd, kernel poll or ioctl/sysfs).
> >>
> >>Note that we already track the hpd interrupts on a per-source basis, 
> >>so doing the re-poll shouldn't be costly. Maybe do the re-poll as 
> >>part of the EDID invalidation to avoid stalling userspace.
> >>
> >>But you can't rely upon the hpd pins unfortunately :(
> >>
> >>This way we should be able to implement the 2 features you want, 
> >>even on unreliable hw.
> >>
> >>Cheers, Daniel
> >>--
> >>Daniel Vetter
> >>Software Engineer, Intel Corporation
> >>+41 (0) 79 365 57 48 - http://blog.ffwll.ch
> >>_______________________________________________
> >>Intel-gfx mailing list
> >>Intel-gfx@lists.freedesktop.org
> >>http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH 0/2] Optimization on intel HDMI detect and get_modes
  2014-04-11 14:48                           ` Sharma, Shashank
@ 2014-07-16 14:29                             ` Kumar, Shobhit
  0 siblings, 0 replies; 716+ messages in thread
From: Kumar, Shobhit @ 2014-07-16 14:29 UTC (permalink / raw)
  To: Sharma, Shashank, Daniel Vetter; +Cc: intel-gfx

On 4/11/2014 8:18 PM, Sharma, Shashank wrote:
> Ok, I will change the implementation.
>
> Regards
> Shashank
> -----Original Message-----
> From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Friday, April 11, 2014 7:53 PM
> To: Sharma, Shashank
> Cc: Daniel Vetter; C, Ramalingam; Wang, Quanxian; intel-gfx
> Subject: Re: [Intel-gfx] [PATCH 0/2] Optimization on intel HDMI detect and get_modes
>
> On Fri, Apr 11, 2014 at 01:23:43PM +0000, Sharma, Shashank wrote:
>> Thanks for the comments,
>> Actually, we are not using live_status at all.
>>
>> The check for < gen6 is only for EDID caching. So if the HW is >= gen6 cache_edid.
>> Else do not cache EDID, so that we will not block any of the old HW, which might not be HPD capable.
>
> Oh, I've thought that this is incremental on top of something you already have.
>>
>> Does it sound ok now :) ?
>
> No. HPD is _NOT_ I repeat _NOT_ reliably. Not even on gen6+. live status simply reflects the hpd pin, if either doesn't work, then neither does the other one.
>
> Nacked-with-prejudice-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Again re-starting the thread on this. Discussed this with Daniel on IRC 
and want to put the design agreed here for any further comments if any -

On detect call if no edid cached, then read full edid and cache. 
Assumption is that usermode will do the processing within 1s and we can 
just maintain this cache for 1s and clear. This will work also for 
panels which do not reliably assert HPD/Live status and also we get 
benefit of caching.

This will still fail compliance where we should not read any thing on 
ddc if live status is not detected. So plan is to add a compliance mode 
by way of module param which will be by default off. This code path will 
rely on HPD and Live status.

Regards
Shobhit

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
  2014-08-12  6:40   ` Sanjeev Sharma
  (?)
@ 2014-08-12  6:28   ` Hans de Goede
  2014-08-12  6:37     ` Sharma, Sanjeev
  2014-08-19  6:33       ` Sharma, Sanjeev
  -1 siblings, 2 replies; 716+ messages in thread
From: Hans de Goede @ 2014-08-12  6:28 UTC (permalink / raw)
  To: Sanjeev Sharma
  Cc: gregkh, kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi

Hi,

On 08/12/2014 08:40 AM, Sanjeev Sharma wrote:
> on some architecture spin_is_locked() always return false in
> uniprocessor configuration and therefore it would be advise
> to replace with lockdep_assert_held().
> 
> Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma@mentor.com>
> ---
> Changes in v3:
>  incorporated review comment suggested by Greg

Thanks, this is still:

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> 
>  drivers/usb/storage/uas.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
> index 3f42785..05b2d8e 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  
>  	uas_log_cmd_state(cmnd, caller);
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
>  	cmdinfo->state |= COMMAND_ABORTED;
>  	cmdinfo->state &= ~IS_IN_WORK_LIST;
> @@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  	struct uas_dev_info *devinfo = cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	cmdinfo->state |= IS_IN_WORK_LIST;
>  	schedule_work(&devinfo->work);
>  }
> @@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
>  	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>  	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & (COMMAND_INFLIGHT |
>  			      DATA_IN_URB_INFLIGHT |
>  			      DATA_OUT_URB_INFLIGHT |
> @@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
>  	struct urb *urb;
>  	int err;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & SUBMIT_STATUS_URB) {
>  		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
>  		if (!urb)
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
  2014-08-12  6:28   ` Hans de Goede
@ 2014-08-12  6:37     ` Sharma, Sanjeev
  2014-08-19  6:33       ` Sharma, Sanjeev
  1 sibling, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-08-12  6:37 UTC (permalink / raw)
  To: Hans de Goede
  Cc: gregkh, kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi

Yes I have incorporated review comment from Greg.

Regards
Sanjeev Sharma

-----Original Message-----
From: Hans de Goede [mailto:hdegoede@redhat.com] 
Sent: Tuesday, August 12, 2014 11:59 AM
To: Sharma, Sanjeev
Cc: gregkh@linuxfoundation.org; kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

Hi,

On 08/12/2014 08:40 AM, Sanjeev Sharma wrote:
> on some architecture spin_is_locked() always return false in 
> uniprocessor configuration and therefore it would be advise to replace 
> with lockdep_assert_held().
> 
> Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma@mentor.com>
> ---
> Changes in v3:
>  incorporated review comment suggested by Greg

Thanks, this is still:

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> 
>  drivers/usb/storage/uas.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c 
> index 3f42785..05b2d8e 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  
>  	uas_log_cmd_state(cmnd, caller);
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
>  	cmdinfo->state |= COMMAND_ABORTED;
>  	cmdinfo->state &= ~IS_IN_WORK_LIST;
> @@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  	struct uas_dev_info *devinfo = cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	cmdinfo->state |= IS_IN_WORK_LIST;
>  	schedule_work(&devinfo->work);
>  }
> @@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
>  	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>  	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & (COMMAND_INFLIGHT |
>  			      DATA_IN_URB_INFLIGHT |
>  			      DATA_OUT_URB_INFLIGHT |
> @@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
>  	struct urb *urb;
>  	int err;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & SUBMIT_STATUS_URB) {
>  		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
>  		if (!urb)
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
       [not found] <yes>
@ 2014-08-12  6:40   ` Sanjeev Sharma
  2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
                     ` (90 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Sanjeev Sharma @ 2014-08-12  6:40 UTC (permalink / raw)
  To: hdegoede
  Cc: gregkh, kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi,
	Sanjeev Sharma, Sanjeev Sharma

on some architecture spin_is_locked() always return false in
uniprocessor configuration and therefore it would be advise
to replace with lockdep_assert_held().

Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma@mentor.com>
---
Changes in v3:
 incorporated review comment suggested by Greg

 drivers/usb/storage/uas.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 3f42785..05b2d8e 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
 	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
 
 	uas_log_cmd_state(cmnd, caller);
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
 	cmdinfo->state |= COMMAND_ABORTED;
 	cmdinfo->state &= ~IS_IN_WORK_LIST;
@@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
 	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
 	struct uas_dev_info *devinfo = cmnd->device->hostdata;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	cmdinfo->state |= IS_IN_WORK_LIST;
 	schedule_work(&devinfo->work);
 }
@@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	if (cmdinfo->state & (COMMAND_INFLIGHT |
 			      DATA_IN_URB_INFLIGHT |
 			      DATA_OUT_URB_INFLIGHT |
@@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 	struct urb *urb;
 	int err;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	if (cmdinfo->state & SUBMIT_STATUS_URB) {
 		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
 		if (!urb)
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
@ 2014-08-12  6:40   ` Sanjeev Sharma
  0 siblings, 0 replies; 716+ messages in thread
From: Sanjeev Sharma @ 2014-08-12  6:40 UTC (permalink / raw)
  To: hdegoede-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	kraxel-H+wXaHxf7aLQT0dZR+AlfA,
	mdharm-usb-JGfshJpz5UybPZpvUQj5UqxOck334EZe,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA, Sanjeev Sharma,
	Sanjeev Sharma

on some architecture spin_is_locked() always return false in
uniprocessor configuration and therefore it would be advise
to replace with lockdep_assert_held().

Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
---
Changes in v3:
 incorporated review comment suggested by Greg

 drivers/usb/storage/uas.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 3f42785..05b2d8e 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
 	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
 
 	uas_log_cmd_state(cmnd, caller);
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
 	cmdinfo->state |= COMMAND_ABORTED;
 	cmdinfo->state &= ~IS_IN_WORK_LIST;
@@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
 	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
 	struct uas_dev_info *devinfo = cmnd->device->hostdata;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	cmdinfo->state |= IS_IN_WORK_LIST;
 	schedule_work(&devinfo->work);
 }
@@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	if (cmdinfo->state & (COMMAND_INFLIGHT |
 			      DATA_IN_URB_INFLIGHT |
 			      DATA_OUT_URB_INFLIGHT |
@@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 	struct urb *urb;
 	int err;
 
-	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
+	lockdep_assert_held(&devinfo->lock);
 	if (cmdinfo->state & SUBMIT_STATUS_URB) {
 		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
 		if (!urb)
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
  2014-08-12  6:28   ` Hans de Goede
@ 2014-08-19  6:33       ` Sharma, Sanjeev
  2014-08-19  6:33       ` Sharma, Sanjeev
  1 sibling, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-08-19  6:33 UTC (permalink / raw)
  To: gregkh
  Cc: gregkh, kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi,
	Hans de Goede

Hi Greg,

Any feedback on this patch ?

Regards
Sanjeev Sharma

-----Original Message-----
From: Sharma, Sanjeev 
Sent: Tuesday, August 12, 2014 12:07 PM
To: 'Hans de Goede'
Cc: gregkh@linuxfoundation.org; kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org
Subject: RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

Yes I have incorporated review comment from Greg.

Regards
Sanjeev Sharma

-----Original Message-----
From: Hans de Goede [mailto:hdegoede@redhat.com]
Sent: Tuesday, August 12, 2014 11:59 AM
To: Sharma, Sanjeev
Cc: gregkh@linuxfoundation.org; kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

Hi,

On 08/12/2014 08:40 AM, Sanjeev Sharma wrote:
> on some architecture spin_is_locked() always return false in 
> uniprocessor configuration and therefore it would be advise to replace 
> with lockdep_assert_held().
> 
> Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma@mentor.com>
> ---
> Changes in v3:
>  incorporated review comment suggested by Greg

Thanks, this is still:

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> 
>  drivers/usb/storage/uas.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c 
> index 3f42785..05b2d8e 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  
>  	uas_log_cmd_state(cmnd, caller);
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
>  	cmdinfo->state |= COMMAND_ABORTED;
>  	cmdinfo->state &= ~IS_IN_WORK_LIST;
> @@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  	struct uas_dev_info *devinfo = cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	cmdinfo->state |= IS_IN_WORK_LIST;
>  	schedule_work(&devinfo->work);
>  }
> @@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
>  	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>  	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & (COMMAND_INFLIGHT |
>  			      DATA_IN_URB_INFLIGHT |
>  			      DATA_OUT_URB_INFLIGHT |
> @@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
>  	struct urb *urb;
>  	int err;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & SUBMIT_STATUS_URB) {
>  		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
>  		if (!urb)
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
@ 2014-08-19  6:33       ` Sharma, Sanjeev
  0 siblings, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-08-19  6:33 UTC (permalink / raw)
  Cc: gregkh, kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi,
	Hans de Goede

Hi Greg,

Any feedback on this patch ?

Regards
Sanjeev Sharma

-----Original Message-----
From: Sharma, Sanjeev 
Sent: Tuesday, August 12, 2014 12:07 PM
To: 'Hans de Goede'
Cc: gregkh@linuxfoundation.org; kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org
Subject: RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

Yes I have incorporated review comment from Greg.

Regards
Sanjeev Sharma

-----Original Message-----
From: Hans de Goede [mailto:hdegoede@redhat.com]
Sent: Tuesday, August 12, 2014 11:59 AM
To: Sharma, Sanjeev
Cc: gregkh@linuxfoundation.org; kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

Hi,

On 08/12/2014 08:40 AM, Sanjeev Sharma wrote:
> on some architecture spin_is_locked() always return false in 
> uniprocessor configuration and therefore it would be advise to replace 
> with lockdep_assert_held().
> 
> Signed-off-by: Sanjeev Sharma <Sanjeev_Sharma@mentor.com>
> ---
> Changes in v3:
>  incorporated review comment suggested by Greg

Thanks, this is still:

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

> 
>  drivers/usb/storage/uas.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c 
> index 3f42785..05b2d8e 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -154,7 +154,7 @@ static void uas_mark_cmd_dead(struct uas_dev_info *devinfo,
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  
>  	uas_log_cmd_state(cmnd, caller);
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	WARN_ON_ONCE(cmdinfo->state & COMMAND_ABORTED);
>  	cmdinfo->state |= COMMAND_ABORTED;
>  	cmdinfo->state &= ~IS_IN_WORK_LIST;
> @@ -181,7 +181,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
>  	struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp);
>  	struct uas_dev_info *devinfo = cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	cmdinfo->state |= IS_IN_WORK_LIST;
>  	schedule_work(&devinfo->work);
>  }
> @@ -283,7 +283,7 @@ static int uas_try_complete(struct scsi_cmnd *cmnd, const char *caller)
>  	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>  	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & (COMMAND_INFLIGHT |
>  			      DATA_IN_URB_INFLIGHT |
>  			      DATA_OUT_URB_INFLIGHT |
> @@ -622,7 +622,7 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
>  	struct urb *urb;
>  	int err;
>  
> -	WARN_ON_ONCE(!spin_is_locked(&devinfo->lock));
> +	lockdep_assert_held(&devinfo->lock);
>  	if (cmdinfo->state & SUBMIT_STATUS_URB) {
>  		urb = uas_submit_sense_urb(cmnd, gfp, cmdinfo->stream);
>  		if (!urb)
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
  2014-08-19  6:33       ` Sharma, Sanjeev
  (?)
@ 2014-08-19  9:30       ` gregkh
  2014-08-19  9:38           ` Sharma, Sanjeev
  2014-09-04  7:06         ` Sharma, Sanjeev
  -1 siblings, 2 replies; 716+ messages in thread
From: gregkh @ 2014-08-19  9:30 UTC (permalink / raw)
  To: Sharma, Sanjeev
  Cc: kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi, Hans de Goede

On Tue, Aug 19, 2014 at 06:33:04AM +0000, Sharma, Sanjeev wrote:
> Hi Greg,
> 
> Any feedback on this patch ?

The merge window ended 2 days ago, _and_ I'm at the kernel summit this
week, _and_ my queue is currently sitting at:
	$ mdfrm -c ~/mail/todo/
	1317 messages in /home/gregkh/mail/todo/

So please be patient.  I'll get to it in a few weeks.

greg k-h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
@ 2014-08-19  9:38           ` Sharma, Sanjeev
  0 siblings, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-08-19  9:38 UTC (permalink / raw)
  To: gregkh
  Cc: kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi, Hans de Goede

Thanks for letting me know.

Sanjeev Sharma

-----Original Message-----
From: gregkh@linuxfoundation.org [mailto:gregkh@linuxfoundation.org] 
Sent: Tuesday, August 19, 2014 3:01 PM
To: Sharma, Sanjeev
Cc: kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org; Hans de Goede
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

On Tue, Aug 19, 2014 at 06:33:04AM +0000, Sharma, Sanjeev wrote:
> Hi Greg,
> 
> Any feedback on this patch ?

The merge window ended 2 days ago, _and_ I'm at the kernel summit this week, _and_ my queue is currently sitting at:
	$ mdfrm -c ~/mail/todo/
	1317 messages in /home/gregkh/mail/todo/

So please be patient.  I'll get to it in a few weeks.

greg k-h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
@ 2014-08-19  9:38           ` Sharma, Sanjeev
  0 siblings, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-08-19  9:38 UTC (permalink / raw)
  To: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
  Cc: kraxel-H+wXaHxf7aLQT0dZR+AlfA,
	mdharm-usb-JGfshJpz5UybPZpvUQj5UqxOck334EZe,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-scsi-u79uwXL29TY76Z2rM5mHXA, Hans de Goede

Thanks for letting me know.

Sanjeev Sharma

-----Original Message-----
From: gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org [mailto:gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org] 
Sent: Tuesday, August 19, 2014 3:01 PM
To: Sharma, Sanjeev
Cc: kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org; mdharm-usb-JGfshJpz5UybPZpvUQj5UqxOck334EZe@public.gmane.org; linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-scsi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Hans de Goede
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

On Tue, Aug 19, 2014 at 06:33:04AM +0000, Sharma, Sanjeev wrote:
> Hi Greg,
> 
> Any feedback on this patch ?

The merge window ended 2 days ago, _and_ I'm at the kernel summit this week, _and_ my queue is currently sitting at:
	$ mdfrm -c ~/mail/todo/
	1317 messages in /home/gregkh/mail/todo/

So please be patient.  I'll get to it in a few weeks.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 716+ messages in thread

* RE: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()
  2014-08-19  9:30       ` gregkh
  2014-08-19  9:38           ` Sharma, Sanjeev
@ 2014-09-04  7:06         ` Sharma, Sanjeev
  1 sibling, 0 replies; 716+ messages in thread
From: Sharma, Sanjeev @ 2014-09-04  7:06 UTC (permalink / raw)
  To: gregkh
  Cc: kraxel, mdharm-usb, linux-usb, linux-kernel, linux-scsi, Hans de Goede

-----Original Message-----
From: gregkh@linuxfoundation.org [mailto:gregkh@linuxfoundation.org] 
Sent: Tuesday, August 19, 2014 3:01 PM
To: Sharma, Sanjeev
Cc: kraxel@redhat.com; mdharm-usb@one-eyed-alien.net; linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; linux-scsi@vger.kernel.org; Hans de Goede
Subject: Re: [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held()

On Tue, Aug 19, 2014 at 06:33:04AM +0000, Sharma, Sanjeev wrote:
> Hi Greg,
> 
> Any feedback on this patch ?

The merge window ended 2 days ago, _and_ I'm at the kernel summit this week, _and_ my queue is currently sitting at:
	$ mdfrm -c ~/mail/todo/
	1317 messages in /home/gregkh/mail/todo/

So please be patient.  I'll get to it in a few weeks.

Please let me know when this is going to be merged ?

Thanks
Sanjeev

greg k-h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c
       [not found] <yes>
                   ` (79 preceding siblings ...)
  2014-08-12  6:40   ` Sanjeev Sharma
@ 2014-09-04 13:50 ` linux.delve
  2014-09-04 13:51   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool linux.delve
  2014-09-04 14:09 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Chaitra Ramaiah
                   ` (10 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: linux.delve @ 2014-09-04 13:50 UTC (permalink / raw)
  To: gregkh, burzalodowa, anarey, rmfrfs, gdonald, joe
  Cc: devel, linux-kernel, Chaitra Ramaiah

From: Chaitra Ramaiah <linux.delve@gmail.com>

*** BLURB HERE ***

root (1):
  Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c 
       This is a patch to the file r819xU_firmware.c that fixes a brace
    warning found by checkpatch.pl tool

 drivers/staging/rtl8192u/r819xU_firmware.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool
  2014-09-04 13:50 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c linux.delve
@ 2014-09-04 13:51   ` linux.delve
  0 siblings, 0 replies; 716+ messages in thread
From: linux.delve @ 2014-09-04 13:51 UTC (permalink / raw)
  To: gregkh, burzalodowa, anarey, rmfrfs, gdonald, joe
  Cc: devel, linux-kernel, Chaitra Ramaiah

From: root <root@admin1-Lenovo-IdeaPad-Y510P.(none)>

Signed-off-by: Chaitra Ramaiah <linux.delve@gmail.com>
---
 drivers/staging/rtl8192u/r819xU_firmware.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c
index 671cbe6..40e1ef5 100644
--- a/drivers/staging/rtl8192u/r819xU_firmware.c
+++ b/drivers/staging/rtl8192u/r819xU_firmware.c
@@ -153,11 +153,10 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
 			break;
 	}while(check_bootOk_time--);
 
-	if (!(CPU_status&CPU_GEN_BOOT_RDY)) {
+	if (!(CPU_status&CPU_GEN_BOOT_RDY))
 		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
+	else
 		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
-	}
 
 	return rt_status;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c
       [not found] <yes>
                   ` (80 preceding siblings ...)
  2014-09-04 13:50 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c linux.delve
@ 2014-09-04 14:09 ` Chaitra Ramaiah
  2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
  2014-09-04 14:27   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Greg KH
  2014-10-29 20:28   ` Murali Karicheri
                   ` (9 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: Chaitra Ramaiah @ 2014-09-04 14:09 UTC (permalink / raw)
  To: gregkh, burzalodowa, anarey, rmfrfs, gdonald, joe
  Cc: devel, linux-kernel, Chaitra Ramaiah

*** BLURB HERE ***

root (1):
  Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c 
       This is a patch to the file r819xU_firmware.c that fixes a brace
    warning found by checkpatch.pl tool

 drivers/staging/rtl8192u/r819xU_firmware.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool
  2014-09-04 14:09 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Chaitra Ramaiah
@ 2014-09-04 14:09   ` Chaitra Ramaiah
  2014-09-04 14:28     ` Greg KH
  2014-09-04 14:33     ` Dan Carpenter
  2014-09-04 14:27   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Greg KH
  1 sibling, 2 replies; 716+ messages in thread
From: Chaitra Ramaiah @ 2014-09-04 14:09 UTC (permalink / raw)
  To: gregkh, burzalodowa, anarey, rmfrfs, gdonald, joe
  Cc: devel, linux-kernel, Chaitra Ramaiah

From: root <root@admin1-Lenovo-IdeaPad-Y510P.(none)>

Signed-off-by: Chaitra Ramaiah <linux.delve@gmail.com>
---
 drivers/staging/rtl8192u/r819xU_firmware.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c
index 671cbe6..40e1ef5 100644
--- a/drivers/staging/rtl8192u/r819xU_firmware.c
+++ b/drivers/staging/rtl8192u/r819xU_firmware.c
@@ -153,11 +153,10 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
 			break;
 	}while(check_bootOk_time--);
 
-	if (!(CPU_status&CPU_GEN_BOOT_RDY)) {
+	if (!(CPU_status&CPU_GEN_BOOT_RDY))
 		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
+	else
 		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
-	}
 
 	return rt_status;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c
  2014-09-04 14:09 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Chaitra Ramaiah
  2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
@ 2014-09-04 14:27   ` Greg KH
  1 sibling, 0 replies; 716+ messages in thread
From: Greg KH @ 2014-09-04 14:27 UTC (permalink / raw)
  To: Chaitra Ramaiah
  Cc: burzalodowa, anarey, rmfrfs, gdonald, joe, devel, linux-kernel

On Thu, Sep 04, 2014 at 07:39:11PM +0530, Chaitra Ramaiah wrote:
> *** BLURB HERE ***

No blurb???

:)

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool
  2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
@ 2014-09-04 14:28     ` Greg KH
  2014-09-04 14:33     ` Dan Carpenter
  1 sibling, 0 replies; 716+ messages in thread
From: Greg KH @ 2014-09-04 14:28 UTC (permalink / raw)
  To: Chaitra Ramaiah
  Cc: burzalodowa, anarey, rmfrfs, gdonald, joe, devel, linux-kernel

On Thu, Sep 04, 2014 at 07:39:12PM +0530, Chaitra Ramaiah wrote:
> From: root <root@admin1-Lenovo-IdeaPad-Y510P.(none)>

I don't think that is your email address...

ALso, look at your subject, something went wrong here :(

Care to try again?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool
  2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
  2014-09-04 14:28     ` Greg KH
@ 2014-09-04 14:33     ` Dan Carpenter
  1 sibling, 0 replies; 716+ messages in thread
From: Dan Carpenter @ 2014-09-04 14:33 UTC (permalink / raw)
  To: Chaitra Ramaiah
  Cc: gregkh, burzalodowa, anarey, rmfrfs, gdonald, joe, devel, linux-kernel

Read the first paragraph of Documentation/email-clients.txt.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 0/4] Enable PCI controller for Keystone SoCs
       [not found] <yes>
  2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
@ 2014-10-29 20:28   ` Murali Karicheri
  2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
                     ` (89 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Greg Kroah-Hartman,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, devicetree

v2: Some more minor edits based on comments
v1: resend with some minor fix up of the commit description and fixing
    the email ID for Santosh.

CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org

Murali Karicheri (4):
  ARM: keystone: add pcie related options
  ARM: keystone: defconfig: add options to enable PCI controller
  ARM: dts: keystone: add DT bindings for PCI controller for port 0
  ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1

 arch/arm/boot/dts/k2e.dtsi          |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/keystone.dtsi     |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/configs/keystone_defconfig |    3 +++
 arch/arm/mach-keystone/Kconfig      |    2 ++
 4 files changed, 95 insertions(+)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 0/4] Enable PCI controller for Keystone SoCs
@ 2014-10-29 20:28   ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Greg Kroah-Hartman,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Russell King, devicetree

v2: Some more minor edits based on comments
v1: resend with some minor fix up of the commit description and fixing
    the email ID for Santosh.

CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org

Murali Karicheri (4):
  ARM: keystone: add pcie related options
  ARM: keystone: defconfig: add options to enable PCI controller
  ARM: dts: keystone: add DT bindings for PCI controller for port 0
  ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1

 arch/arm/boot/dts/k2e.dtsi          |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/keystone.dtsi     |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/configs/keystone_defconfig |    3 +++
 arch/arm/mach-keystone/Kconfig      |    2 ++
 4 files changed, 95 insertions(+)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 0/4] Enable PCI controller for Keystone SoCs
@ 2014-10-29 20:28   ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

v2: Some more minor edits based on comments
v1: resend with some minor fix up of the commit description and fixing
    the email ID for Santosh.

CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree at vger.kernel.org

Murali Karicheri (4):
  ARM: keystone: add pcie related options
  ARM: keystone: defconfig: add options to enable PCI controller
  ARM: dts: keystone: add DT bindings for PCI controller for port 0
  ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1

 arch/arm/boot/dts/k2e.dtsi          |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/keystone.dtsi     |   45 +++++++++++++++++++++++++++++++++++
 arch/arm/configs/keystone_defconfig |    3 +++
 arch/arm/mach-keystone/Kconfig      |    2 ++
 4 files changed, 95 insertions(+)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 1/4] ARM: keystone: add pcie related options
  2014-10-29 20:28   ` Murali Karicheri
@ 2014-10-29 20:28     ` Murali Karicheri
  -1 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Russell King, Santosh Shilimkar

Now that Keystone PCI controller is merged, add pcie related options
by default for keystone architecture so that driver can be enabled in
the build.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Russell King <linux@arm.linux.org.uk>
CC: Santosh Shilimkar <ssantosh@kernel.org>
---
 - V2 - No change w.r.t v1
 - v1 - No change w.r.t initial version
 arch/arm/mach-keystone/Kconfig |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig
index 98a156a..ea955f6db 100644
--- a/arch/arm/mach-keystone/Kconfig
+++ b/arch/arm/mach-keystone/Kconfig
@@ -9,6 +9,8 @@ config ARCH_KEYSTONE
 	select COMMON_CLK_KEYSTONE
 	select ARCH_SUPPORTS_BIG_ENDIAN
 	select ZONE_DMA if ARM_LPAE
+	select MIGHT_HAVE_PCI
+	select PCI_DOMAINS if PCI
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 1/4] ARM: keystone: add pcie related options
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

Now that Keystone PCI controller is merged, add pcie related options
by default for keystone architecture so that driver can be enabled in
the build.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Russell King <linux@arm.linux.org.uk>
CC: Santosh Shilimkar <ssantosh@kernel.org>
---
 - V2 - No change w.r.t v1
 - v1 - No change w.r.t initial version
 arch/arm/mach-keystone/Kconfig |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig
index 98a156a..ea955f6db 100644
--- a/arch/arm/mach-keystone/Kconfig
+++ b/arch/arm/mach-keystone/Kconfig
@@ -9,6 +9,8 @@ config ARCH_KEYSTONE
 	select COMMON_CLK_KEYSTONE
 	select ARCH_SUPPORTS_BIG_ENDIAN
 	select ZONE_DMA if ARM_LPAE
+	select MIGHT_HAVE_PCI
+	select PCI_DOMAINS if PCI
 	help
 	  Support for boards based on the Texas Instruments Keystone family of
 	  SoCs.
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 2/4] ARM: keystone: defconfig: add options to enable PCI controller
  2014-10-29 20:28   ` Murali Karicheri
@ 2014-10-29 20:28     ` Murali Karicheri
  -1 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Russell King, Greg Kroah-Hartman

This patch enables PCI controller driver for Keystone SoCs by
default.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 v2 - Added a description in the commit log per comment
 v1 - fixed email ID for Santosh
 arch/arm/configs/keystone_defconfig |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 932ae40..40d3e9d 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -20,6 +20,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_ARM_LPAE=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_KEYSTONE=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 2/4] ARM: keystone: defconfig: add options to enable PCI controller
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables PCI controller driver for Keystone SoCs by
default.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 v2 - Added a description in the commit log per comment
 v1 - fixed email ID for Santosh
 arch/arm/configs/keystone_defconfig |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig
index 932ae40..40d3e9d 100644
--- a/arch/arm/configs/keystone_defconfig
+++ b/arch/arm/configs/keystone_defconfig
@@ -20,6 +20,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_ARCH_KEYSTONE=y
 CONFIG_ARM_LPAE=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_KEYSTONE=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 3/4] ARM: dts: keystone: add DT bindings for PCI controller for port 0
  2014-10-29 20:28   ` Murali Karicheri
  (?)
@ 2014-10-29 20:28     ` Murali Karicheri
  -1 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King, devicetree

Add common DT bindings to support PCI controller driver for port 0 on all
of the K2 SoCs that has Synopsis Designware based pcie h/w.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org
---
 v2 - Minor editorial update based on comment
 v1 - fixed email ID for Santosh and reworded the commit description a bit to
      be consistent with the subject.
 arch/arm/boot/dts/keystone.dtsi |   45 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 5d3e83f..c06542b 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -285,5 +285,50 @@
 			#interrupt-cells = <1>;
 			ti,syscon-dev = <&devctrl 0x2a0>;
 		};
+
+		pcie@21800000 {
+			compatible = "ti,keystone-pcie", "snps,dw-pcie";
+			clocks = <&clkpcie>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23250000 0 0x4000
+				0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
+					<0 0 0 2 &pcie_intc0 1>, /* INT B */
+					<0 0 0 3 &pcie_intc0 2>, /* INT C */
+					<0 0 0 4 &pcie_intc0 3>; /* INT D */
+
+			pcie_msi_intc0: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc0: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 3/4] ARM: dts: keystone: add DT bindings for PCI controller for port 0
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King, devicetree

Add common DT bindings to support PCI controller driver for port 0 on all
of the K2 SoCs that has Synopsis Designware based pcie h/w.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org
---
 v2 - Minor editorial update based on comment
 v1 - fixed email ID for Santosh and reworded the commit description a bit to
      be consistent with the subject.
 arch/arm/boot/dts/keystone.dtsi |   45 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 5d3e83f..c06542b 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -285,5 +285,50 @@
 			#interrupt-cells = <1>;
 			ti,syscon-dev = <&devctrl 0x2a0>;
 		};
+
+		pcie@21800000 {
+			compatible = "ti,keystone-pcie", "snps,dw-pcie";
+			clocks = <&clkpcie>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23250000 0 0x4000
+				0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
+					<0 0 0 2 &pcie_intc0 1>, /* INT B */
+					<0 0 0 3 &pcie_intc0 2>, /* INT C */
+					<0 0 0 4 &pcie_intc0 3>; /* INT D */
+
+			pcie_msi_intc0: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc0: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 3/4] ARM: dts: keystone: add DT bindings for PCI controller for port 0
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

Add common DT bindings to support PCI controller driver for port 0 on all
of the K2 SoCs that has Synopsis Designware based pcie h/w.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree at vger.kernel.org
---
 v2 - Minor editorial update based on comment
 v1 - fixed email ID for Santosh and reworded the commit description a bit to
      be consistent with the subject.
 arch/arm/boot/dts/keystone.dtsi |   45 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 5d3e83f..c06542b 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -285,5 +285,50 @@
 			#interrupt-cells = <1>;
 			ti,syscon-dev = <&devctrl 0x2a0>;
 		};
+
+		pcie at 21800000 {
+			compatible = "ti,keystone-pcie", "snps,dw-pcie";
+			clocks = <&clkpcie>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23250000 0 0x4000
+				0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
+					<0 0 0 2 &pcie_intc0 1>, /* INT B */
+					<0 0 0 3 &pcie_intc0 2>, /* INT C */
+					<0 0 0 4 &pcie_intc0 3>; /* INT D */
+
+			pcie_msi_intc0: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc0: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 4/4] ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1
  2014-10-29 20:28   ` Murali Karicheri
  (?)
@ 2014-10-29 20:28     ` Murali Karicheri
  -1 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King, devicetree

K2E SoC has a second PCI port based on Synopsis Designware PCIe h/w.
Add DT bindings to support PCI controller for port 1 for this SoC.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org
---
 v2 - minor ediorial updates based on comments
 v1 - fixed email ID for Santosh and reworded commit description to be
      consistent with the subject.
 arch/arm/boot/dts/k2e.dtsi |   45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
index c358b4b..5fc14683 100644
--- a/arch/arm/boot/dts/k2e.dtsi
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -85,6 +85,51 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x240>;
 		};
+
+		pcie@21020000 {
+			compatible = "ti,keystone-pcie","snps,dw-pcie";
+			clocks = <&clkpcie1>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21021000 0x2000>, <0x21020000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23260000 0x4000 0x4000
+				0x82000000 0 0x60000000 0x60000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc1 0>, /* INT A */
+					<0 0 0 2 &pcie_intc1 1>, /* INT B */
+					<0 0 0 3 &pcie_intc1 2>, /* INT C */
+					<0 0 0 4 &pcie_intc1 3>; /* INT D */
+
+			pcie_msi_intc1: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 378 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 379 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 380 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 381 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 382 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 383 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 384 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc1: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 375 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 4/4] ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: Murali Karicheri, Santosh Shilimkar, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King, devicetree

K2E SoC has a second PCI port based on Synopsis Designware PCIe h/w.
Add DT bindings to support PCI controller for port 1 for this SoC.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree@vger.kernel.org
---
 v2 - minor ediorial updates based on comments
 v1 - fixed email ID for Santosh and reworded commit description to be
      consistent with the subject.
 arch/arm/boot/dts/k2e.dtsi |   45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
index c358b4b..5fc14683 100644
--- a/arch/arm/boot/dts/k2e.dtsi
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -85,6 +85,51 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x240>;
 		};
+
+		pcie@21020000 {
+			compatible = "ti,keystone-pcie","snps,dw-pcie";
+			clocks = <&clkpcie1>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21021000 0x2000>, <0x21020000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23260000 0x4000 0x4000
+				0x82000000 0 0x60000000 0x60000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc1 0>, /* INT A */
+					<0 0 0 2 &pcie_intc1 1>, /* INT B */
+					<0 0 0 3 &pcie_intc1 2>, /* INT C */
+					<0 0 0 4 &pcie_intc1 3>; /* INT D */
+
+			pcie_msi_intc1: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 378 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 379 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 380 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 381 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 382 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 383 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 384 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc1: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 375 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2 4/4] ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1
@ 2014-10-29 20:28     ` Murali Karicheri
  0 siblings, 0 replies; 716+ messages in thread
From: Murali Karicheri @ 2014-10-29 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

K2E SoC has a second PCI port based on Synopsis Designware PCIe h/w.
Add DT bindings to support PCI controller for port 1 for this SoC.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
CC: Santosh Shilimkar <ssantosh@kernel.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Pawel Moll <pawel.moll@arm.com>
CC: Mark Rutland <mark.rutland@arm.com>
CC: Ian Campbell <ijc+devicetree@hellion.org.uk>
CC: Kumar Gala <galak@codeaurora.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: devicetree at vger.kernel.org
---
 v2 - minor ediorial updates based on comments
 v1 - fixed email ID for Santosh and reworded commit description to be
      consistent with the subject.
 arch/arm/boot/dts/k2e.dtsi |   45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
index c358b4b..5fc14683 100644
--- a/arch/arm/boot/dts/k2e.dtsi
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -85,6 +85,51 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x240>;
 		};
+
+		pcie at 21020000 {
+			compatible = "ti,keystone-pcie","snps,dw-pcie";
+			clocks = <&clkpcie1>;
+			clock-names = "pcie";
+			#address-cells = <3>;
+			#size-cells = <2>;
+			reg =  <0x21021000 0x2000>, <0x21020000 0x1000>, <0x02620128 4>;
+			ranges = <0x81000000 0 0 0x23260000 0x4000 0x4000
+				0x82000000 0 0x60000000 0x60000000 0 0x10000000>;
+
+			device_type = "pci";
+			num-lanes = <2>;
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &pcie_intc1 0>, /* INT A */
+					<0 0 0 2 &pcie_intc1 1>, /* INT B */
+					<0 0 0 3 &pcie_intc1 2>, /* INT C */
+					<0 0 0 4 &pcie_intc1 3>; /* INT D */
+
+			pcie_msi_intc1: msi-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 378 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 379 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 380 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 381 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 382 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 383 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 384 IRQ_TYPE_EDGE_RISING>;
+			};
+
+			pcie_intc1: legacy-interrupt-controller {
+				interrupt-controller;
+				#interrupt-cells = <1>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 375 IRQ_TYPE_EDGE_RISING>,
+					<GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
+			};
+		};
 	};
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v2 0/4] Enable PCI controller for Keystone SoCs
  2014-10-29 20:28   ` Murali Karicheri
@ 2014-10-29 21:10     ` santosh shilimkar
  -1 siblings, 0 replies; 716+ messages in thread
From: santosh shilimkar @ 2014-10-29 21:10 UTC (permalink / raw)
  To: Murali Karicheri, linux-arm-kernel, linux-kernel
  Cc: Mark Rutland, devicetree, Russell King, Pawel Moll, Ian Campbell,
	Greg Kroah-Hartman, Kumar Gala, Rob Herring, Santosh Shilimkar

On 10/29/2014 1:28 PM, Murali Karicheri wrote:
> v2: Some more minor edits based on comments

Thanks for quick update. I will queue these up as
mentioned.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2 0/4] Enable PCI controller for Keystone SoCs
@ 2014-10-29 21:10     ` santosh shilimkar
  0 siblings, 0 replies; 716+ messages in thread
From: santosh shilimkar @ 2014-10-29 21:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/29/2014 1:28 PM, Murali Karicheri wrote:
> v2: Some more minor edits based on comments

Thanks for quick update. I will queue these up as
mentioned.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver.
       [not found] <yes>
                   ` (82 preceding siblings ...)
  2014-10-29 20:28   ` Murali Karicheri
@ 2015-02-12  7:56 ` Hongzhou Yang
  2015-02-20 10:04     ` Linus Walleij
  2015-07-27  8:16 ` [PATCH v1] mmc: sprd: add MMC host driver for Spreadtrum SoC Billows Wu
                   ` (7 subsequent siblings)
  91 siblings, 1 reply; 716+ messages in thread
From: Hongzhou Yang @ 2015-02-12  7:56 UTC (permalink / raw)
  To: Rob Herring, Linus Walleij, Matthias Brugger
  Cc: Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Mika Westerberg, Heikki Krogerus, Laurent Pinchart,
	Hongzhou Yang, Sascha Hauer, Shawn Guo, Stefan Agner,
	Stephen Warren, Fabio Estevam, Rickard Strandqvist,
	Martin Fuzzey, Kiran Padwal, Thierry Reding, Wolfram Sang,
	devicetree, linux-kernel, linux-gpio, linux-arm-kernel, linux-sh,
	srv_heupstream, Sascha Hauer, dandan.he, yingjoe.chen,
	alan.cheng, eddie.huang

Since pinconf relate API changes in pinctrl devel branch, a build error happened.
Send this small patch to fix it.

---
Due to pinconf_generic_parse_dt_config() API changes in pinctrl devel branch,
add one parameter to fix build error.

Also fix warning:
drivers/pinctrl/mediatek/pinctrl-mtk-common.c:718:3: warning: too many arguments for format [-Wformat-extra-args]
      dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
      ^

by removing extra parameter when calling dev_err in mtk_pctrl_init.

Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 5d680c8..63df62b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -391,7 +391,8 @@ static int mtk_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 		return -EINVAL;
 	}
 
-	err = pinconf_generic_parse_dt_config(node, &configs, &num_configs);
+	err = pinconf_generic_parse_dt_config(node, pctldev, &configs,
+		&num_configs);
 	if (num_configs)
 		has_config = 1;
 
@@ -715,7 +716,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	prop = of_find_property(np, "pins-are-numbered", NULL);
 	if (!prop) {
-		dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
+		dev_err(&pdev->dev, "only support pins-are-numbered format\n");
 		return -EINVAL;
 	}
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver.
  2015-02-12  7:56 ` [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver Hongzhou Yang
  2015-02-20 10:04     ` Linus Walleij
  (?)
@ 2015-02-20 10:04     ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2015-02-20 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 12, 2015 at 8:56 AM, Hongzhou Yang
<hongzhou.yang@mediatek.com> wrote:

> Since pinconf relate API changes in pinctrl devel branch, a build error happened.
> Send this small patch to fix it.
>
> ---
> Due to pinconf_generic_parse_dt_config() API changes in pinctrl devel branch,
> add one parameter to fix build error.
>
> Also fix warning:
> drivers/pinctrl/mediatek/pinctrl-mtk-common.c:718:3: warning: too many arguments for format [-Wformat-extra-args]
>       dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
>       ^
>
> by removing extra parameter when calling dev_err in mtk_pctrl_init.
>
> Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver.
@ 2015-02-20 10:04     ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2015-02-20 10:04 UTC (permalink / raw)
  To: Hongzhou Yang
  Cc: Rob Herring, Matthias Brugger, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Mika Westerberg, Heikki Krogerus,
	Laurent Pinchart, Sascha Hauer, Shawn Guo, Stefan Agner,
	Stephen Warren, Fabio Estevam, Rickard Strandqvist,
	Martin Fuzzey, Kiran Padwal, Thierry Reding, Wolfram Sang,
	devicetree

On Thu, Feb 12, 2015 at 8:56 AM, Hongzhou Yang
<hongzhou.yang@mediatek.com> wrote:

> Since pinconf relate API changes in pinctrl devel branch, a build error happened.
> Send this small patch to fix it.
>
> ---
> Due to pinconf_generic_parse_dt_config() API changes in pinctrl devel branch,
> add one parameter to fix build error.
>
> Also fix warning:
> drivers/pinctrl/mediatek/pinctrl-mtk-common.c:718:3: warning: too many arguments for format [-Wformat-extra-args]
>       dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
>       ^
>
> by removing extra parameter when calling dev_err in mtk_pctrl_init.
>
> Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver.
@ 2015-02-20 10:04     ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2015-02-20 10:04 UTC (permalink / raw)
  To: Hongzhou Yang
  Cc: Rob Herring, Matthias Brugger, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Mika Westerberg, Heikki Krogerus,
	Laurent Pinchart, Sascha Hauer, Shawn Guo, Stefan Agner,
	Stephen Warren, Fabio Estevam, Rickard Strandqvist,
	Martin Fuzzey, Kiran Padwal, Thierry Reding, Wolfram Sang,
	devicetree, linux-kernel, linux-gpio, linux-arm-kernel, linux-sh,
	srv_heupstream, Sascha Hauer, dandan.he, Yingjoe Chen,
	alan.cheng, huang eddie

On Thu, Feb 12, 2015 at 8:56 AM, Hongzhou Yang
<hongzhou.yang@mediatek.com> wrote:

> Since pinconf relate API changes in pinctrl devel branch, a build error happened.
> Send this small patch to fix it.
>
> ---
> Due to pinconf_generic_parse_dt_config() API changes in pinctrl devel branch,
> add one parameter to fix build error.
>
> Also fix warning:
> drivers/pinctrl/mediatek/pinctrl-mtk-common.c:718:3: warning: too many arguments for format [-Wformat-extra-args]
>       dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
>       ^
>
> by removing extra parameter when calling dev_err in mtk_pctrl_init.
>
> Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver.
@ 2015-02-20 10:04     ` Linus Walleij
  0 siblings, 0 replies; 716+ messages in thread
From: Linus Walleij @ 2015-02-20 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 12, 2015 at 8:56 AM, Hongzhou Yang
<hongzhou.yang@mediatek.com> wrote:

> Since pinconf relate API changes in pinctrl devel branch, a build error happened.
> Send this small patch to fix it.
>
> ---
> Due to pinconf_generic_parse_dt_config() API changes in pinctrl devel branch,
> add one parameter to fix build error.
>
> Also fix warning:
> drivers/pinctrl/mediatek/pinctrl-mtk-common.c:718:3: warning: too many arguments for format [-Wformat-extra-args]
>       dev_err(&pdev->dev, "only support pins-are-numbered format\n", ret);
>       ^
>
> by removing extra parameter when calling dev_err in mtk_pctrl_init.
>
> Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v1] mmc: sprd: add MMC host driver for Spreadtrum SoC
       [not found] <yes>
                   ` (83 preceding siblings ...)
  2015-02-12  7:56 ` [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver Hongzhou Yang
@ 2015-07-27  8:16 ` Billows Wu
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
                   ` (6 subsequent siblings)
  91 siblings, 0 replies; 716+ messages in thread
From: Billows Wu @ 2015-07-27  8:16 UTC (permalink / raw)
  To: linux-mmc; +Cc: Orson.Zhai

From: Billows Wu <wuht06@gmial.com>

the Spreadtrum MMC host driver is used to supply EMMC, SD, and
SDIO types of memory cards

Signed-off-by: Billows Wu <wuht06@gmial.com>
---
 drivers/mmc/host/sprd_sdhost.c         | 1197 ++++++++++++++++++++++++++++++++
 drivers/mmc/host/sprd_sdhost.h         |  592 ++++++++++++++++
 drivers/mmc/host/sprd_sdhost_debugfs.c |  213 ++++++
 drivers/mmc/host/sprd_sdhost_debugfs.h |   27 +
 4 files changed, 2029 insertions(+)
 create mode 100644 drivers/mmc/host/sprd_sdhost.c
 create mode 100644 drivers/mmc/host/sprd_sdhost.h
 create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.c
 create mode 100644 drivers/mmc/host/sprd_sdhost_debugfs.h

diff --git a/drivers/mmc/host/sprd_sdhost.c b/drivers/mmc/host/sprd_sdhost.c
new file mode 100644
index 0000000..f390f42
--- /dev/null
+++ b/drivers/mmc/host/sprd_sdhost.c
@@ -0,0 +1,1197 @@
+/*
+ * linux/drivers/mmc/host/sprd_sdhost.c - Secure Digital Host Controller
+ * Interface driver
+ *
+ * Copyright (C) 2015 Spreadtrum corporation.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+
+#include "sprd_sdhost.h"
+#include "sprd_sdhost_debugfs.h"
+
+#define DRIVER_NAME "sdhost"
+#define SDHOST_CAPS \
+		(MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | \
+		MMC_CAP_ERASE |	 MMC_CAP_UHS_SDR50 | \
+		MMC_CAP_CMD23 | MMC_CAP_HW_RESET)
+
+struct sdhost_caps_data {
+	char *name;
+	u32 ocr_avail;
+	u32 caps;
+	u32 caps2;
+	u32 pm_caps;
+	/* TODO: we will obtain these values from regulator and clock
+	 * phandles after LDO and clock function is OK
+	 */
+	u32 base_clk;
+	u32 signal_default_voltage;
+};
+
+struct sdhost_caps_data caps_info_map[] = {
+	{
+		.name = "sd",
+		.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31,
+		.caps = SDHOST_CAPS,
+		.caps2 = MMC_CAP2_HC_ERASE_SZ,
+		.pm_caps = MMC_PM_WAKE_SDIO_IRQ,
+		.base_clk = 192000000,
+		.signal_default_voltage = 3000000,
+	},
+	{
+		.name = "wifi",
+		.ocr_avail = MMC_VDD_165_195 | MMC_VDD_29_30 |
+			MMC_VDD_30_31 | MMC_VDD_32_33 | MMC_VDD_33_34,
+		.caps = SDHOST_CAPS | MMC_CAP_POWER_OFF_CARD |
+			MMC_CAP_UHS_SDR12,
+		.pm_caps = MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY,
+		.base_clk = 76000000,
+	},
+	{
+		.name = "emmc",
+		.ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31,
+		.caps = SDHOST_CAPS |
+			MMC_CAP_8_BIT_DATA | MMC_CAP_UHS_SDR12 |
+			MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_DDR50 |
+			MMC_CAP_MMC_HIGHSPEED,
+		.caps2 = MMC_CAP2_FULL_PWR_CYCLE | MMC_CAP2_HC_ERASE_SZ,
+		.pm_caps = MMC_PM_WAKE_SDIO_IRQ,
+		.base_clk = 192000000,
+		.signal_default_voltage = 1800000,
+	}
+};
+
+#ifdef CONFIG_PM_RUNTIME
+static void _pm_runtime_setting(struct platform_device *pdev,
+				struct sdhost_host *host);
+#else
+static void _pm_runtime_setting(struct platform_device *pdev,
+				struct sdhost_host *host)
+{
+}
+#endif
+
+static void _reset_ios(struct sdhost_host *host)
+{
+	_sdhost_disable_all_int(host);
+
+	host->ios.clock = 0;
+	host->ios.vdd = 0;
+	/* host->ios.bus_mode    = MMC_BUSMODE_OPENDRAIN; */
+	/* host->ios.chip_select = MMC_CS_DONTCARE; */
+	host->ios.power_mode = MMC_POWER_OFF;
+	host->ios.bus_width = MMC_BUS_WIDTH_1;
+	host->ios.timing = MMC_TIMING_LEGACY;
+	host->ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330;
+	/* host->ios.drv_type    = MMC_SET_DRIVER_TYPE_B; */
+
+	_sdhost_reset(host, _RST_ALL);
+	_sdhost_set_delay(host, host->write_delay,
+			  host->read_pos_delay, host->read_neg_delay);
+}
+
+static int __local_pm_suspend(struct sdhost_host *host)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	_sdhost_disable_all_int(host);
+	_sdhost_all_clk_off(host);
+	/* wake lock */
+	spin_unlock_irqrestore(&host->lock, flags);
+	clk_disable(host->clk);
+	clk_unprepare(host->clk);
+	synchronize_irq(host->irq);
+
+	return 0;
+}
+
+static int __local_pm_resume(struct sdhost_host *host)
+{
+	unsigned long flags;
+
+	clk_prepare(host->clk);
+	clk_enable(host->clk);
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->ios.clock) {
+		_sdhost_sd_clk_off(host);
+		_sdhost_clk_set_and_on(host,
+				       _sdhost_calc_div(host->base_clk,
+							host->ios.clock));
+		_sdhost_sd_clk_on(host);
+	}
+	_sdhost_set_delay(host, host->write_delay,
+			  host->read_pos_delay, host->read_neg_delay);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static void _pm_runtime_setting(struct platform_device *pdev,
+				struct sdhost_host *host)
+{
+	pm_runtime_set_active(&pdev->dev);
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+}
+#endif
+
+static int _runtime_get(struct sdhost_host *host)
+{
+	return pm_runtime_get_sync(host->mmc->parent);
+}
+
+static int _runtime_put(struct sdhost_host *host)
+{
+	pm_runtime_mark_last_busy(host->mmc->parent);
+	return pm_runtime_put_autosuspend(host->mmc->parent);
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int _runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev =
+	    container_of(dev, struct platform_device, dev);
+	struct sdhost_host *host = platform_get_drvdata(pdev);
+
+	return __local_pm_suspend(host);
+}
+
+static int _runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev =
+	    container_of(dev, struct platform_device, dev);
+	struct sdhost_host *host = platform_get_drvdata(pdev);
+
+	return __local_pm_resume(host);
+}
+
+static int _runtime_idle(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int _pm_suspend(struct device *dev)
+{
+	struct platform_device *pdev =
+	    container_of(dev, struct platform_device, dev);
+	struct sdhost_host *host = platform_get_drvdata(pdev);
+
+	_runtime_get(host);
+	host->mmc->pm_flags = host->mmc->pm_caps;
+
+	return __local_pm_suspend(host);
+}
+
+static int _pm_resume(struct device *dev)
+{
+	struct platform_device *pdev =
+	    container_of(dev, struct platform_device, dev);
+	struct sdhost_host *host = platform_get_drvdata(pdev);
+	struct mmc_ios ios;
+
+	__local_pm_resume(host);
+
+	ios = host->mmc->ios;
+	_reset_ios(host);
+	host->mmc->ops->set_ios(host->mmc, &ios);
+	_runtime_put(host);
+
+	return 0;
+}
+#endif
+
+static void __get_rsp(struct sdhost_host *host)
+{
+	u32 i, offset;
+	unsigned int flags = host->cmd->flags;
+	u32 *resp = host->cmd->resp;
+
+	if (!(flags & MMC_RSP_PRESENT))
+		return;
+
+	if (flags & MMC_RSP_136) {
+		/* CRC is stripped so we need to do some shifting. */
+		for (i = 0, offset = 12; i < 3; i++, offset -= 4) {
+			resp[i] =
+			    _sdhost_readl(host,
+					  SDHOST_32_RESPONSE + offset) << 8;
+			resp[i] |=
+			    _sdhost_readb(host,
+					  SDHOST_32_RESPONSE + offset - 1);
+		}
+		resp[3] = _sdhost_readl(host, SDHOST_32_RESPONSE) << 8;
+	} else {
+		resp[0] = _sdhost_readl(host, SDHOST_32_RESPONSE);
+	}
+}
+
+static void _send_cmd(struct sdhost_host *host, struct mmc_command *cmd)
+{
+	struct mmc_data *data = cmd->data;
+	int sg_cnt;
+	u32 flag = 0;
+	u16 rsp_type = 0;
+	int if_has_data = 0;
+	int if_mult = 0;
+	int if_read = 0;
+	int if_dma = 0;
+	u16 auto_cmd = __ACMD_DIS;
+
+	pr_debug("sdhost %s cmd %d, arg 0x%x, flag 0x%x\n",
+	       host->device_name, cmd->opcode, cmd->arg, cmd->flags);
+	if (cmd->data)
+		pr_debug("%s(%s) block size %d, cnt %d\n", __func__,
+		       host->device_name, cmd->data->blksz, cmd->data->blocks);
+
+	_sdhost_disable_all_int(host);
+
+	if (38 == cmd->opcode) {
+		/* if it is erase command , it's busy time will long,
+		 * so we set long timeout value here.
+		 */
+		/* mod_timer(&host->timer, jiffies + msecs_to_jiffies
+			(host->mmc->max_discard_to+1000)); */
+		mod_timer(&host->timer, jiffies + 10 * HZ);
+		_sdhost_writeb(host, __DATA_TIMEOUT_MAX_VAL, SDHOST_8_TIMEOUT);
+	} else {
+		/* mod_timer(&host->timer,
+			jiffies + (SDHOST_MAX_TIMEOUT+1) * HZ); */
+		mod_timer(&host->timer, jiffies + 3 * HZ);
+		_sdhost_writeb(host, host->data_timeout_val, SDHOST_8_TIMEOUT);
+	}
+
+	host->cmd = cmd;
+	if (data) {
+		/* set data param */
+		WARN_ON((data->blksz * data->blocks > 524288) ||
+			(data->blksz > host->mmc->max_blk_size) ||
+			(data->blocks > 65535));
+
+		data->bytes_xfered = 0;
+
+		if_has_data = 1;
+		if_read = (data->flags & MMC_DATA_READ);
+		if_mult = (mmc_op_multi(cmd->opcode) || data->blocks > 1);
+		if (if_read && !if_mult)
+			flag = _DATA_FILTER_RD_SIGLE;
+		else if (if_read && if_mult)
+			flag = _DATA_FILTER_RD_MULTI;
+		else if (!if_read && !if_mult)
+			flag = _DATA_FILTER_WR_SIGLE;
+		else
+			flag = _DATA_FILTER_WR_MULT;
+
+		if (!host->auto_cmd_mode)
+			flag |= _INT_ERR_ACMD;
+
+		if_dma = 1;
+		auto_cmd = host->auto_cmd_mode;
+		_sdhost_set_blk_size(host, data->blksz);
+
+		sg_cnt = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+				    (data->flags & MMC_DATA_READ) ?
+				    DMA_FROM_DEVICE : DMA_TO_DEVICE);
+		if (1 == sg_cnt) {
+			_sdhost_set_dma(host, __SDMA_MOD);
+			_sdhost_set_16_blk_cnt(host, data->blocks);
+			_sdhost_writel(host, sg_dma_address(data->sg),
+				       SDHOST_32_SYS_ADDR);
+		} else {
+			WARN_ON(1);
+			flag |= _INT_ERR_ADMA;
+			_sdhost_set_dma(host, __32ADMA_MOD);
+			_sdhost_set_32_blk_cnt(host, data->blocks);
+			_sdhost_writel(host, sg_dma_address(data->sg),
+				       SDHOST_32_SYS_ADDR);
+		}
+	} else {
+		/* _sdhost_set_trans_mode(host, 0, 0, __ACMD_DIS, 0, 0); */
+	}
+
+	_sdhost_writel(host, cmd->arg, SDHOST_32_ARG);
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_R1B:
+		rsp_type = _RSP1B_5B;
+		flag |= _CMD_FILTER_R1B;
+		break;
+	case MMC_RSP_NONE:
+		rsp_type = _RSP0;
+		flag |= _CMD_FILTER_R0;
+		break;
+	case MMC_RSP_R2:
+		rsp_type = _RSP2;
+		flag |= _CMD_FILTER_R2;
+		break;
+	case MMC_RSP_R4:
+		rsp_type = _RSP3_4;
+		flag |= _CMD_FILTER_R1_R4_R5_R6_R7;
+		break;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1 & ~MMC_RSP_CRC:
+		rsp_type = _RSP1_5_6_7;
+		flag |= _CMD_FILTER_R1_R4_R5_R6_R7;
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	host->int_filter = flag;
+	_sdhost_enable_int(host, flag);
+	pr_debug("sdhost %s CMD%d rsp:0x%x intflag:0x%x\n"
+	       "if_mult:0x%x if_read:0x%x auto_cmd:0x%x if_dma:0x%x\n",
+	       host->device_name, cmd->opcode, mmc_resp_type(cmd),
+	       flag, if_mult, if_read, auto_cmd, if_dma);
+
+	_sdhost_set_trans_and_cmd(host, if_mult, if_read, auto_cmd, if_mult,
+				  if_dma, cmd->opcode, if_has_data, rsp_type);
+}
+
+static irqreturn_t _irq(int irq, void *param)
+{
+	u32 intmask;
+	struct sdhost_host *host = (struct sdhost_host *)param;
+	struct mmc_request *mrq = host->mrq;
+	struct mmc_command *cmd = host->cmd;
+	struct mmc_data *data;
+
+	spin_lock(&host->lock);
+	/* maybe _timeout_func run in one core and _irq run in
+	 * another core, this will panic if access cmd->data
+	 */
+	if ((!mrq) || (!cmd)) {
+		spin_unlock(&host->lock);
+		return IRQ_NONE;
+	}
+	data = cmd->data;
+
+	intmask = _sdhost_readl(host, SDHOST_32_INT_ST);
+	if (!intmask) {
+		spin_unlock(&host->lock);
+		return IRQ_NONE;
+	}
+	pr_debug("%s(%s) CMD%d, intmask 0x%x, filter = 0x%x\n", __func__,
+	       host->device_name, cmd->opcode, intmask, host->int_filter);
+
+	/* disable unused interrupt */
+	_sdhost_clear_int(host, intmask);
+	/* just care about the interrupt that we want */
+	intmask &= host->int_filter;
+
+	while (intmask) {
+		if (_INT_FILTER_ERR & intmask) {
+			/* some error happened in command */
+			if (_INT_FILTER_ERR_CMD & intmask) {
+				if (_INT_ERR_CMD_TIMEOUT & intmask)
+					cmd->error = -ETIMEDOUT;
+				else
+					cmd->error = -EILSEQ;
+			}
+			/* some error happened in data token or command
+			 * with R1B
+			 */
+			if (_INT_FILTER_ERR_DATA & intmask) {
+				if (data) {
+					/* current error is happened in data
+					 * token
+					 */
+					if (_INT_ERR_DATA_TIMEOUT & intmask)
+						data->error = -ETIMEDOUT;
+					else
+						data->error = -EILSEQ;
+				} else {
+					/* current error is happend in response
+					 * with busy
+					 */
+					if (_INT_ERR_DATA_TIMEOUT & intmask)
+						cmd->error = -ETIMEDOUT;
+					else
+						cmd->error = -EILSEQ;
+				}
+			}
+			if (_INT_ERR_ACMD & intmask) {
+				/* Auto cmd12 and cmd23 error is belong to data
+				 * token error
+				 */
+				data->error = -EILSEQ;
+			}
+			if (_INT_ERR_ADMA & intmask)
+				data->error = -EIO;
+
+			pr_debug("sdhost %s int 0x%x\n", host->device_name,
+				 intmask);
+			dump_sdio_reg(host);
+			_sdhost_disable_all_int(host);
+			/* if current error happened in data token,
+			 * we send cmd12 to stop it
+			 */
+			if ((mrq->cmd == cmd) && (mrq->stop)) {
+				_sdhost_reset(host, _RST_CMD | _RST_DATA);
+				_send_cmd(host, mrq->stop);
+			} else {
+				/* request finish with error, so reset it and
+				 * stop the request
+				 */
+				_sdhost_reset(host, _RST_CMD | _RST_DATA);
+				tasklet_schedule(&host->finish_tasklet);
+			}
+			goto out;
+		} else {
+			/* delete irq that wanted in filter */
+			host->int_filter &= ~(_INT_FILTER_NORMAL & intmask);
+			if (_INT_DMA_END & intmask) {
+				_sdhost_writel(host,
+					_sdhost_readl(host, SDHOST_32_SYS_ADDR),
+					SDHOST_32_SYS_ADDR);
+			}
+			if (_INT_CMD_END & intmask) {
+				cmd->error = 0;
+				__get_rsp(host);
+			}
+			if (_INT_TRAN_END & intmask) {
+				if (data) {
+					dma_unmap_sg(mmc_dev(host->mmc),
+						data->sg, data->sg_len,
+						(data->flags & MMC_DATA_READ) ?
+						DMA_FROM_DEVICE :
+						DMA_TO_DEVICE);
+					data->error = 0;
+					data->bytes_xfered =
+					data->blksz * data->blocks;
+				} else {
+					/* R1B also can produce transferComplete
+					 * interrupt
+					 */
+					cmd->error = 0;
+				}
+			}
+			if (!(_INT_FILTER_NORMAL & host->int_filter)) {
+				/* current cmd finished */
+				_sdhost_disable_all_int(host);
+				if (mrq->sbc == cmd) {
+					_send_cmd(host, mrq->cmd);
+				} else if ((mrq->cmd == host->cmd)
+					   && (mrq->stop)) {
+					_send_cmd(host, mrq->stop);
+				} else {
+					/* finish with success and stop the
+					 * request
+					 */
+					tasklet_schedule(&host->finish_tasklet);
+					goto out;
+				}
+			}
+		}
+
+		intmask = _sdhost_readl(host, SDHOST_32_INT_ST);
+		_sdhost_clear_int(host, intmask);
+		intmask &= host->int_filter;
+	};
+
+out:
+	spin_unlock(&host->lock);
+	return IRQ_HANDLED;
+}
+
+static void _tasklet(unsigned long param)
+{
+	struct sdhost_host *host = (struct sdhost_host *)param;
+	unsigned long flags;
+	struct mmc_request *mrq;
+
+	del_timer(&host->timer);
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (!host->mrq) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+	mrq = host->mrq;
+	host->mrq = NULL;
+	host->cmd = NULL;
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	pr_debug("sdhost %s cmd %d data %d\n",
+		 host->device_name, mrq->cmd->error,
+		 ((!!mrq->cmd->data) ? mrq->cmd->data->error : 0));
+	mmc_request_done(host->mmc, mrq);
+	_runtime_put(host);
+}
+
+static void _timeout(unsigned long data)
+{
+	struct sdhost_host *host = (struct sdhost_host *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->mrq) {
+		pr_info("sdhost %s Timeout waiting for hardware interrupt!\n",
+			host->device_name);
+		dump_sdio_reg(host);
+		if (host->cmd->data)
+			host->cmd->data->error = -ETIMEDOUT;
+		else if (host->cmd)
+			host->cmd->error = -ETIMEDOUT;
+		else
+			host->mrq->cmd->error = -ETIMEDOUT;
+
+		_sdhost_disable_all_int(host);
+		_sdhost_reset(host, _RST_CMD | _RST_DATA);
+		tasklet_schedule(&host->finish_tasklet);
+	}
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->mrq = mrq;
+	/* 1 find whether card is still in slot */
+	if (!(host->mmc->caps & MMC_CAP_NONREMOVABLE)) {
+		if (!mmc_gpio_get_cd(host->mmc)) {
+			mrq->cmd->error = -ENOMEDIUM;
+			tasklet_schedule(&host->finish_tasklet);
+			mmiowb();
+			spin_unlock_irqrestore(&host->lock, flags);
+			return;
+		}
+		/* else asume sdcard is present */
+	}
+
+	/*
+	 * in our control we can not use auto cmd12 and auto cmd23 together
+	 * so in following program we use auto cmd23 prior to auto cmd12
+	 */
+	pr_debug("%s(%s) CMD%d request %d %d %d\n",
+		__func__, host->device_name, mrq->cmd->opcode,
+	       !!mrq->sbc, !!mrq->cmd, !!mrq->stop);
+	host->auto_cmd_mode = __ACMD_DIS;
+	if (!mrq->sbc && mrq->stop && SDHOST_FLAG_ENABLE_ACMD12) {
+		host->auto_cmd_mode = __ACMD12;
+		mrq->data->stop = NULL;
+		mrq->stop = NULL;
+	}
+
+	/* 3 send cmd list */
+	if ((mrq->sbc) && SDHOST_FLAG_ENABLE_ACMD23) {
+		host->auto_cmd_mode = __ACMD23;
+		mrq->data->stop = NULL;
+		mrq->stop = NULL;
+		_send_cmd(host, mrq->cmd);
+	} else if (mrq->sbc) {
+		mrq->data->stop = NULL;
+		mrq->stop = NULL;
+		_send_cmd(host, mrq->sbc);
+	} else {
+		_send_cmd(host, mrq->cmd);
+	}
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void _signal_voltage_on_off(struct sdhost_host *host, u32 on_off)
+{
+	if (!host->mmc->supply.vqmmc) {
+		pr_debug("%s(%s) there is no signal voltage!\n",
+			 __func__, host->device_name);
+		return;
+	}
+
+	if (on_off && (!host->sdio_1_8v_signal_enabled)) {
+		if (!regulator_enable(host->mmc->supply.vqmmc) &&
+		    regulator_is_enabled(host->mmc->supply.vqmmc)) {
+			host->sdio_1_8v_signal_enabled = true;
+			pr_debug("%s(%s) signal voltage enable success!\n",
+				 __func__, host->device_name);
+		} else
+			pr_debug("%s(%s) signal voltage enable fail!\n",
+				 __func__, host->device_name);
+
+	} else if (!on_off && host->sdio_1_8v_signal_enabled) {
+		if (!regulator_disable(host->mmc->supply.vqmmc) &&
+		    !regulator_is_enabled(host->mmc->supply.vqmmc)) {
+			host->sdio_1_8v_signal_enabled = false;
+			pr_debug("%s(%s) signal voltage disable success!\n",
+				 __func__, host->device_name);
+		} else
+			pr_debug("%s(%s) signal voltage disable fail\n",
+				 __func__, host->device_name);
+	}
+}
+
+/*
+ * 1 This votage is always poweron
+ * 2 initial votage is 2.7v~3.6v
+ * 3 It can be reconfig to 1.7v~1.95v
+ */
+static int sdhost_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	int err;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (!mmc->supply.vqmmc) {
+		/* there are no 1.8v signal votage. */
+		spin_unlock_irqrestore(&host->lock, flags);
+		_runtime_put(host);
+		/* TODO: we will change this when LDO function is ok */
+		/* err = -EINVAL; */
+		err = 0;
+		pr_debug("sdhost %s There is no signalling voltage\n",
+			 host->device_name);
+		return err;
+	}
+
+	/* I/O power supply */
+	if (ios->signal_voltage == host->ios.signal_voltage) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		_runtime_put(host);
+		return 0;
+	}
+
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_330:
+		err = regulator_set_voltage(mmc->supply.vqmmc,
+					    3000000, 3000000);
+		break;
+	case MMC_SIGNAL_VOLTAGE_180:
+		err = regulator_set_voltage(mmc->supply.vqmmc,
+					    1800000, 1800000);
+		break;
+	case MMC_SIGNAL_VOLTAGE_120:
+		err = regulator_set_voltage(mmc->supply.vqmmc,
+					    1100000, 1300000);
+		break;
+	default:
+		err = -EIO;
+		break;
+	}
+	if (likely(!err))
+		host->ios.signal_voltage = ios->signal_voltage;
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+
+	if (err)
+		WARN(err, "Switching to signalling voltage  failed\n");
+
+	return err;
+}
+
+static void sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	pr_debug("%s(%s) ios:\n"
+		 "sdhost clock = %d-->%d\n"
+		 "sdhost vdd = %d-->%d\n"
+		 "sdhost bus_mode = %d-->%d\n"
+		 "sdhost chip_select = %d-->%d\n"
+		 "sdhost power_mode = %d-->%d\n"
+		 "sdhost bus_width = %d-->%d\n"
+		 "sdhost timing = %d-->%d\n"
+		 "sdhost signal_voltage = %d-->%d\n"
+		 "sdhost drv_type = %d-->%d\n",
+		 __func__, host->device_name,
+		 host->ios.clock, ios->clock,
+		 host->ios.vdd, ios->vdd,
+		 host->ios.bus_mode, ios->bus_mode,
+		 host->ios.chip_select, ios->chip_select,
+		 host->ios.power_mode, ios->power_mode,
+		 host->ios.bus_width, ios->bus_width,
+		 host->ios.timing, ios->timing,
+		 host->ios.signal_voltage, ios->signal_voltage,
+		 host->ios.drv_type, ios->drv_type);
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (0 == ios->clock) {
+		_sdhost_all_clk_off(host);
+		host->ios.clock = 0;
+	} else if (ios->clock != host->ios.clock) {
+		u32 div;
+
+		div = _sdhost_calc_div(host->base_clk, ios->clock);
+		_sdhost_sd_clk_off(host);
+		_sdhost_clk_set_and_on(host, div);
+		_sdhost_sd_clk_on(host);
+		host->ios.clock = ios->clock;
+		host->data_timeout_val =
+		    _sdhost_calc_timeout(host->base_clk, 3);
+	}
+
+	if (ios->power_mode != host->ios.power_mode) {
+		switch (ios->power_mode) {
+		case MMC_POWER_OFF:
+			_signal_voltage_on_off(host, 0);
+			if (mmc->supply.vmmc)
+				mmc_regulator_set_ocr(host->mmc,
+						      mmc->supply.vmmc, 0);
+			mdelay(50);
+			_reset_ios(host);
+			host->ios.power_mode = ios->power_mode;
+			break;
+		case MMC_POWER_ON:
+		case MMC_POWER_UP:
+			if (mmc->supply.vmmc)
+				mmc_regulator_set_ocr(host->mmc,
+						      mmc->supply.vmmc,
+						      ios->vdd);
+			_signal_voltage_on_off(host, 1);
+			mdelay(50);
+			host->ios.power_mode = ios->power_mode;
+			host->ios.vdd = ios->vdd;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* flash power voltage select */
+	if (ios->vdd != host->ios.vdd) {
+		if (mmc->supply.vmmc) {
+			pr_info("sdhost %s 3.0 %d!\n",
+				host->device_name, ios->vdd);
+			mmc_regulator_set_ocr(host->mmc,
+					      mmc->supply.vmmc, ios->vdd);
+			mdelay(50);
+		}
+		host->ios.vdd = ios->vdd;
+	}
+
+	if (ios->bus_width != host->ios.bus_width) {
+		_sdhost_set_buswidth(host, ios->bus_width);
+		host->ios.bus_width = ios->bus_width;
+	}
+
+	if (ios->timing != host->ios.timing) {
+		/* 1 first close SD clock */
+		_sdhost_sd_clk_off(host);
+		/* 2 set timing mode */
+		switch (ios->timing) {	/* timing specification used */
+		case MMC_TIMING_LEGACY:
+			/* basic clock mode */
+			_sdhost_set_uhs_mode(host, __TIMING_MODE_SDR12);
+			break;
+		case MMC_TIMING_MMC_HS:
+		case MMC_TIMING_SD_HS:
+			_sdhost_set_uhs_mode(host, __TIMING_MODE_SDR12);
+			break;
+		case MMC_TIMING_UHS_SDR12:
+		case MMC_TIMING_UHS_SDR25:
+		case MMC_TIMING_UHS_SDR50:
+		case MMC_TIMING_UHS_SDR104:
+		case MMC_TIMING_UHS_DDR50:
+		case MMC_TIMING_MMC_HS200:
+			/* _sdhost_enable_hispd(host); */
+			_sdhost_set_uhs_mode(host, ios->timing -
+					     MMC_TIMING_UHS_SDR12 +
+					     __TIMING_MODE_SDR12);
+			break;
+		default:
+			break;
+		}
+		/* 3 open SD clock */
+		_sdhost_sd_clk_on(host);
+		host->ios.timing = ios->timing;
+	}
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+}
+
+static int sdhost_get_ro(struct mmc_host *mmc)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+	/* read & write */
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+	return 0;
+}
+
+static int sdhost_get_cd(struct mmc_host *mmc)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	int gpio_cd;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->mmc->caps & MMC_CAP_NONREMOVABLE) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		_runtime_put(host);
+		return 1;
+	}
+
+	gpio_cd = mmc_gpio_get_cd(host->mmc);
+	if (IS_ERR_VALUE(gpio_cd))
+		gpio_cd = 1;
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+	return !!gpio_cd;
+}
+
+static int sdhost_card_busy(struct mmc_host *mmc)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	u32 present_state;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	/* Check whether DAT[3:0] is 0000 */
+	present_state = _sdhost_readl(host, SDHOST_32_PRES_STATE);
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+
+	return !(present_state & _DATA_LVL_MASK);
+}
+
+static void sdhost_hw_reset(struct mmc_host *mmc)
+{
+	struct sdhost_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	_runtime_get(host);
+	spin_lock_irqsave(&host->lock, flags);
+
+	/* close LDO and open LDO again. */
+	_signal_voltage_on_off(host, 0);
+	if (mmc->supply.vmmc)
+		mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0);
+	mdelay(50);
+	if (mmc->supply.vmmc)
+		mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc,
+				      host->ios.vdd);
+
+	_signal_voltage_on_off(host, 1);
+	mdelay(50);
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+	_runtime_put(host);
+
+}
+
+static const struct mmc_host_ops sdhost_ops = {
+	.request = sdhost_request,
+	.set_ios = sdhost_set_ios,
+	.get_ro = sdhost_get_ro,
+	.get_cd = sdhost_get_cd,
+
+	.start_signal_voltage_switch = sdhost_set_vqmmc,
+	.card_busy = sdhost_card_busy,
+	.hw_reset = sdhost_hw_reset,
+};
+
+static void get_caps_info(struct sdhost_host *host,
+			  struct sdhost_caps_data *pdata)
+{
+	host->ocr_avail = pdata->ocr_avail;
+	host->caps = pdata->caps;
+	host->caps2 = pdata->caps2;
+	host->pm_caps = pdata->pm_caps;
+	host->base_clk = pdata->base_clk;
+	host->signal_default_voltage = pdata->signal_default_voltage;
+}
+
+static int _get_basic_resource(struct platform_device *pdev,
+			       struct sdhost_host *host)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	u32 sdhost_delay[3];
+	struct sdhost_caps_data *pdata = NULL;
+	int ret;
+	int index;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	host->ioaddr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	host->mapbase = res->start;
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq < 0)
+		return host->irq;
+
+    /* TODO: we will open this macro, when clock function is OK*/
+#if 0
+	host->clk = of_clk_get(np, 0);
+	if (IS_ERR_OR_NULL(host->clk))
+		return PTR_ERR(host->clk);
+
+	host->clk_parent = of_clk_get(np, 1);
+	if (IS_ERR_OR_NULL(host->clk_parent))
+		return PTR_ERR(host->clk_parent);
+#endif
+
+	ret = of_property_read_string(np, "sprd,name", &host->device_name);
+	if (ret)
+		dev_err(&pdev->dev,
+			"can not read the property of sprd name\n");
+
+	for (index = 0; index < sizeof(caps_info_map) /
+		sizeof(struct sdhost_caps_data); index++) {
+		if (strcmp(host->device_name, caps_info_map[index].name) == 0) {
+			pdata = &caps_info_map[index];
+			break;
+		}
+	}
+
+	get_caps_info(host, pdata);
+
+	host->detect_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	if (!gpio_is_valid(host->detect_gpio))
+		host->detect_gpio = -1;
+
+	ret = of_property_read_u32_array(np, "sprd,delay", sdhost_delay, 3);
+	if (!ret) {
+		host->write_delay = sdhost_delay[0];
+		host->read_pos_delay = sdhost_delay[1];
+		host->read_neg_delay = sdhost_delay[2];
+	} else
+		dev_err(&pdev->dev,
+			"can not read the property of sprd delay\n");
+
+	return 0;
+}
+
+static int _get_ext_resource(struct sdhost_host *host)
+{
+	int err;
+	struct mmc_host *mmc = host->mmc;
+
+	host->dma_mask = DMA_BIT_MASK(64);
+	host->data_timeout_val = 0;
+
+	/* 1 LDO */
+	mmc_regulator_get_supply(mmc);
+	if (IS_ERR_OR_NULL(mmc->supply.vmmc)) {
+		pr_err("%s(%s): no vmmc regulator found\n",
+		       __func__, host->device_name);
+		mmc->supply.vmmc = NULL;
+	}
+	if (IS_ERR_OR_NULL(mmc->supply.vqmmc)) {
+		pr_err("%s(%s): no vqmmc regulator found\n",
+		       __func__, host->device_name);
+		mmc->supply.vqmmc = NULL;
+	} else {
+		regulator_is_supported_voltage(mmc->supply.vqmmc,
+					       host->signal_default_voltage,
+					       host->signal_default_voltage);
+		regulator_set_voltage(mmc->supply.vqmmc,
+				      host->signal_default_voltage,
+				      host->signal_default_voltage);
+	}
+	host->mmc = mmc;
+
+    /* TODO: we will open this macro, when clock function is OK*/
+#if 0
+	/* 2 clock */
+	clk_set_parent(host->clk, host->clk_parent);
+	clk_prepare_enable(host->clk);
+#endif
+	/* 3 reset sdio */
+	_reset_ios(host);
+	err = devm_request_irq(&host->pdev->dev, host->irq, _irq,
+			       IRQF_SHARED, mmc_hostname(host->mmc), host);
+	if (err)
+		return err;
+	tasklet_init(&host->finish_tasklet, _tasklet, (unsigned long)host);
+	/* 4 init timer */
+	setup_timer(&host->timer, _timeout, (unsigned long)host);
+
+	return 0;
+}
+
+static int _set_mmc_struct(struct sdhost_host *host, struct mmc_host *mmc)
+{
+	int ret = 0;
+
+	mmc = host->mmc;
+	mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
+	mmc->ops = &sdhost_ops;
+	mmc->f_max = host->base_clk;
+	mmc->f_min = (unsigned int)(host->base_clk / __CLK_MAX_DIV);
+	mmc->max_busy_timeout = (1 << 27) / (host->base_clk / 1000);
+
+	mmc->caps = host->caps;
+	mmc->caps2 = host->caps2;
+	mmc->pm_caps = host->pm_caps;
+	mmc->pm_flags = host->pm_caps;
+	mmc->ocr_avail = host->ocr_avail;
+	mmc->ocr_avail_sdio = host->ocr_avail;
+	mmc->ocr_avail_sd = host->ocr_avail;
+	mmc->ocr_avail_mmc = host->ocr_avail;
+	mmc->max_current_330 = SDHOST_MAX_CUR;
+	mmc->max_current_300 = SDHOST_MAX_CUR;
+	mmc->max_current_180 = SDHOST_MAX_CUR;
+
+	mmc->max_segs = 1;
+	mmc->max_req_size = 524288;	/* 512k */
+	mmc->max_seg_size = mmc->max_req_size;
+
+	mmc->max_blk_size = 512;
+	mmc->max_blk_count = 65535;
+
+	ret = mmc_of_parse(mmc);
+	if (ret) {
+		mmc_free_host(mmc);
+		pr_info("parse sprd %s controller fail\n", host->device_name);
+		return ret;
+	}
+
+	pr_info("%s(%s): ocr avail = 0x%x\n"
+		"base clock = %u, pm_caps = 0x%x\n"
+		"caps: 0x%x, caps2: 0x%x\n",
+		__func__, host->device_name, mmc->ocr_avail,
+		host->base_clk, host->pm_caps, mmc->caps, mmc->caps2);
+
+	return ret;
+}
+
+static int sdhost_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct sdhost_host *host;
+	int ret;
+
+	/* globe resource */
+	mmc = mmc_alloc_host(sizeof(struct sdhost_host), &pdev->dev);
+	if (!mmc) {
+		dev_err(&pdev->dev, "no memory for MMC host\n");
+		return -ENOMEM;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->pdev = pdev;
+	spin_lock_init(&host->lock);
+	platform_set_drvdata(pdev, host);
+
+	/* get sdio irq and sdio iomem */
+	ret = _get_basic_resource(pdev, host);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to get basic resource: %d\n", ret);
+		return ret;
+	}
+
+	ret = _get_ext_resource(host);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to get external resource: %d\n", ret);
+		return ret;
+	}
+
+	ret = _set_mmc_struct(host, mmc);
+	if (ret) {
+		dev_err(&pdev->dev, "fail to set mmc struct: %d\n", ret);
+		return ret;
+	}
+
+	_pm_runtime_setting(pdev, host);
+
+	/* add host */
+	mmiowb();
+	ret = mmc_add_host(mmc);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add mmc host: %d\n", ret);
+		mmc_free_host(mmc);
+	}
+
+	if (-1 != host->detect_gpio) {
+		mmc->caps &= ~MMC_CAP_NONREMOVABLE;
+		mmc_gpio_request_cd(mmc, host->detect_gpio, 0);
+	}
+
+	sdhost_add_debugfs(host);
+
+	dev_info(&pdev->dev,
+		"Spreadtrum %s[%s] host controller at 0x%08lx irq %d\n",
+		host->device_name, mmc_hostname(mmc),
+		host->mapbase, host->irq);
+
+	return ret;
+}
+
+static void sdhost_shutdown(struct platform_device *pdev)
+{
+}
+
+static const struct dev_pm_ops sdhost_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(_pm_suspend, _pm_resume)
+	    SET_RUNTIME_PM_OPS(_runtime_suspend,
+			       _runtime_resume, _runtime_idle)
+};
+
+static const struct of_device_id sdhost_of_match[] = {
+	{.compatible = "sprd,sdhost-3.0"},
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, sdhost_of_match);
+
+static struct platform_driver sdhost_driver = {
+	.probe = sdhost_probe,
+	.shutdown = sdhost_shutdown,
+	.driver = {
+		   .owner = THIS_MODULE,
+		   .pm = &sdhost_dev_pm_ops,
+		   .name = DRIVER_NAME,
+		   .of_match_table = of_match_ptr(sdhost_of_match),
+		   },
+};
+
+module_platform_driver(sdhost_driver);
+
+MODULE_AUTHOR("Jason.Wu(Jishuang.Wu) <jason.wu@spreadtrum.com>");
+MODULE_DESCRIPTION("Spreadtrum sdio host controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sprd_sdhost.h b/drivers/mmc/host/sprd_sdhost.h
new file mode 100644
index 0000000..f94db9a
--- /dev/null
+++ b/drivers/mmc/host/sprd_sdhost.h
@@ -0,0 +1,592 @@
+/*
+ * linux/drivers/mmc/host/sprd_sdhost.h - Secure Digital Host Controller
+ * Interface driver
+ *
+ * Copyright (C) 2015 Spreadtrum corporation.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SDHOST_H_
+#define __SDHOST_H_
+
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+
+/**********************************************************\
+ *
+ * Controller block structure
+ *
+\**********************************************************/
+struct sdhost_host {
+	/* --globe resource--- */
+	spinlock_t lock;
+	struct mmc_host *mmc;
+
+	/*--basic resource-- */
+	void __iomem *ioaddr;
+	int irq;
+	const char *device_name;
+	struct platform_device *pdev;
+	unsigned long mapbase;
+
+	int detect_gpio;
+	u32 ocr_avail;
+	char *clk_name;
+	char *clk_parent_name;
+	u32 base_clk;
+	u32 caps;
+	u32 caps2;
+	u32 pm_caps;
+	u32 write_delay;
+	u32 read_pos_delay;
+	u32 read_neg_delay;
+
+	/* --extern resource getted by base resource-- */
+	uint64_t dma_mask;
+	u8 data_timeout_val;
+	u32 signal_default_voltage;
+	bool sdio_1_8v_signal_enabled;
+	struct clk *clk;
+	struct clk *clk_parent;
+	struct tasklet_struct finish_tasklet;
+	struct timer_list timer;
+
+	/* --runtime param-- */
+	u32 int_filter;
+	struct mmc_ios ios;
+	struct mmc_request *mrq;	/* Current request */
+	struct mmc_command *cmd;	/* Current command */
+	u16 auto_cmd_mode;
+
+	/*--debugfs-- */
+	struct dentry *debugfs_root;
+};
+
+/* Controller flag */
+#define SDHOST_FLAG_ENABLE_ACMD12	0
+#define SDHOST_FLAG_ENABLE_ACMD23	0
+#define SDHOST_FLAG_USE_ADMA		1
+
+/* Controller registers */
+#ifdef SPRD_SDHOST_4_BYTE_ALIGNE
+static inline void __local_writeb(u8 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	u32 addr;
+	u32 value;
+	u32 ofst;
+
+	ofst = (reg & 0x3) << 3;
+	addr = reg & (~((u32) (0x3)));
+	value = readl_relaxed((host->ioaddr + addr));
+	value &= (~(((u32) ((u8) (-1))) << ofst));
+	value |= (((u32) val) << ofst);
+	writel_relaxed(value, (host->ioaddr + addr));
+}
+
+static inline void __local_writew(u16 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	u32 addr;
+	u32 value;
+	u32 ofst;
+
+	ofst = (reg & 0x3) << 3;
+	addr = reg & (~((u32) (0x3)));
+	value = readl_relaxed(host->ioaddr + addr);
+	value &= (~(((u32) ((u16) (-1))) << ofst));
+	value |= (((u32) val) << ofst);
+	writel_relaxed(value, (host->ioaddr + addr));
+}
+
+static inline void __local_writel(u32 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	writel_relaxed(val, (host->ioaddr + reg));
+}
+
+static inline u8 __local_readb(struct sdhost_host *host, u32 reg)
+{
+	u32 addr;
+	u32 value;
+	u32 ofst;
+
+	ofst = (reg & 0x3) << 3;
+	addr = reg & (~((u32) (0x3)));
+	value = readl_relaxed(host->ioaddr + addr);
+	return ((u8) (value >> ofst));
+
+}
+
+static inline u16 __local_readw(struct sdhost_host *host, u32 reg)
+{
+	u32 addr;
+	u32 value;
+	u32 ofst;
+
+	ofst = (reg & 0x3) << 3;
+	addr = reg & (~((u32) (0x3)));
+	value = readl_relaxed(host->ioaddr + addr);
+
+	return ((u16) (value >> ofst));
+
+}
+
+static inline u32 __local_readl(struct sdhsot_host *host, u32 reg)
+{
+	return readl_relaxed(host->ioaddr + reg);
+}
+
+#else
+static inline void __local_writeb(u8 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	writeb_relaxed(val, host->ioaddr + reg);
+}
+
+static inline void __local_writew(u16 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	writew_relaxed(val, host->ioaddr + reg);
+}
+
+static inline void __local_writel(u32 val, struct sdhost_host *host,
+				  u32 reg)
+{
+	writel_relaxed(val, host->ioaddr + reg);
+}
+
+static inline u8 __local_readb(struct sdhost_host *host, u32 reg)
+{
+	return readb_relaxed(host->ioaddr + reg);
+}
+
+static inline u16 __local_readw(struct sdhost_host *host, u32 reg)
+{
+	return readw_relaxed(host->ioaddr + reg);
+}
+
+static inline u32 __local_readl(struct sdhost_host *host, u32 reg)
+{
+	return readl_relaxed(host->ioaddr + reg);
+}
+#endif
+
+static inline void _sdhost_writeb(struct sdhost_host *host, u8 val,
+				  int reg)
+{
+	__local_writeb(val, host, reg);
+}
+
+static inline void _sdhost_writew(struct sdhost_host *host, u16 val,
+				  int reg)
+{
+	__local_writew(val, host, reg);
+}
+
+static inline void _sdhost_writel(struct sdhost_host *host, u32 val,
+				  int reg)
+{
+	__local_writel(val, host, reg);
+}
+
+static inline u8 _sdhost_readb(struct sdhost_host *host, int reg)
+{
+	return __local_readb(host, reg);
+}
+
+static inline u16 _sdhost_readw(struct sdhost_host *host, int reg)
+{
+	return __local_readw(host, reg);
+}
+
+static inline u32 _sdhost_readl(struct sdhost_host *host, int reg)
+{
+	return __local_readl(host, reg);
+}
+
+#define SDHOST_32_SYS_ADDR	0x00
+/* used in cmd23 with ADMA in sdio 3.0 */
+#define SDHOST_32_BLK_CNT	0x00
+#define SDHOST_16_BLK_CNT	0x06
+
+static inline void _sdhost_set_16_blk_cnt(struct sdhost_host *host,
+					  u32 blk_cnt)
+{
+	__local_writew((blk_cnt & 0xFFFF), host, SDHOST_16_BLK_CNT);
+}
+
+static inline void _sdhost_set_32_blk_cnt(struct sdhost_host *host,
+					  u32 blk_cnt)
+{
+	__local_writel((blk_cnt & 0xFFFFFFFF), host, SDHOST_32_BLK_CNT);
+}
+
+#define SDHOST_16_BLK_SIZE	0x04
+
+static inline void _sdhost_set_blk_size(struct sdhost_host *host,
+					u32 blk_size)
+{
+	__local_writew((blk_size & 0xFFF) | 0x7000, host, SDHOST_16_BLK_SIZE);
+}
+
+#define SDHOST_32_ARG			0x08
+#define SDHOST_16_TR_MODE		0x0C
+#define __ACMD_DIS	0x00
+#define __ACMD12	0x01
+#define __ACMD23	0x02
+
+static inline void _sdhost_set_trans_mode(struct sdhost_host *host,
+					  u16 if_mult, u16 if_read,
+					  u16 auto_cmd,
+					  u16 if_blk_cnt, u16 if_dma)
+{
+	__local_writew((((if_mult ? 1 : 0) << 5) |
+			((if_read ? 1 : 0) << 4) |
+			(auto_cmd << 2) |
+			((if_blk_cnt ? 1 : 0) << 1) |
+			((if_dma ? 1 : 0) << 0)), host, SDHOST_16_TR_MODE);
+}
+
+#define SDHOST_16_CMD			0x0E
+#define _CMD_INDEX_CHK			0x0010
+#define _CMD_CRC_CHK			0x0008
+#define _CMD_RSP_NONE			0x0000
+#define _CMD_RSP_136			0x0001
+#define _CMD_RSP_48				0x0002
+#define _CMD_RSP_48_BUSY		0x0003
+#define _RSP0			0
+#define _RSP1_5_6_7 \
+	(_CMD_INDEX_CHK | _CMD_CRC_CHK | _CMD_RSP_48)
+#define _RSP2 \
+	(_CMD_CRC_CHK | _CMD_RSP_136)
+#define _RSP3_4 \
+	_CMD_RSP_48
+#define _RSP1B_5B \
+	(_CMD_INDEX_CHK | _CMD_CRC_CHK | _CMD_RSP_48_BUSY)
+
+static inline void _sdhost_set_cmd(struct sdhost_host *host, u16 cmd,
+				   int if_has_data, u16 rsp_type)
+{
+	__local_writew(((cmd << 8) |
+			((if_has_data ? 1 : 0) << 5) |
+			(rsp_type)), host, SDHOST_16_CMD);
+}
+
+#define SDHOST_32_TR_MODE_AND_CMD		0x0C
+
+static inline void _sdhost_set_trans_and_cmd(struct sdhost_host *host,
+					     int if_mult, int if_read,
+					     u16 auto_cmd, int if_blk_cnt,
+					     int if_dma, u32 cmd,
+					     int if_has_data, u32 rsp_type)
+{
+	__local_writel((((if_mult ? 1 : 0) << 5) |
+			((if_read ? 1 : 0) << 4) |
+			(((u32) auto_cmd) << 2) |
+			((if_blk_cnt ? 1 : 0) << 1) |
+			((if_dma ? 1 : 0) << 0) |
+			(((u32) cmd) << 24) |
+			((if_has_data ? 1 : 0) << 21) |
+			(rsp_type << 16)),
+		       host, SDHOST_32_TR_MODE_AND_CMD);
+}
+
+#define SDHOST_32_RESPONSE	0x10
+#define SDHOST_32_PRES_STATE	0x24
+#define  _DATA_LVL_MASK		0x00F00000
+
+#define SDHOST_8_HOST_CTRL	0x28
+#define __8_BIT_MOD	0x20
+#define __4_BIT_MOD	0x02
+#define __1_BIT_MOD	0x00
+#define __SDMA_MOD		0x00
+#define __32ADMA_MOD	0x10
+#define __64ADMA_MOD	0x18
+#define __HISPD_MOD		0x04
+
+static inline void _sdhost_set_buswidth(struct sdhost_host *host,
+					u32 buswidth)
+{
+	u8 ctrl = 0;
+
+	ctrl = __local_readb(host, SDHOST_8_HOST_CTRL);
+	ctrl &= (~(__8_BIT_MOD | __4_BIT_MOD | __1_BIT_MOD));
+	switch (buswidth) {
+	case MMC_BUS_WIDTH_1:
+		ctrl |= __1_BIT_MOD;
+		break;
+	case MMC_BUS_WIDTH_4:
+		ctrl |= __4_BIT_MOD;
+		break;
+	case MMC_BUS_WIDTH_8:
+		ctrl |= __8_BIT_MOD;
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+	__local_writeb(ctrl, host, SDHOST_8_HOST_CTRL);
+}
+
+static inline void _sdhost_set_dma(struct sdhost_host *host, u8 dma_mode)
+{
+	u8 ctrl = 0;
+
+	ctrl = __local_readb(host, SDHOST_8_HOST_CTRL);
+	ctrl &= (~(__SDMA_MOD | __32ADMA_MOD | __64ADMA_MOD));
+	ctrl |= dma_mode;
+	__local_writeb(ctrl, host, SDHOST_8_HOST_CTRL);
+}
+
+static inline void _sdhost_enable_hispd(struct sdhost_host *host)
+{
+	u8 ctrl = 0;
+
+	ctrl = __local_readb(host, SDHOST_8_HOST_CTRL);
+	ctrl |= __HISPD_MOD;
+	__local_writeb(ctrl, host, SDHOST_8_HOST_CTRL);
+}
+
+/* #define SDHOST_8_PWR_CTRL     0x29 *//* not used */
+#define SDHOST_8_BLK_GAP		0x2A	/* not used */
+#define SDHOST_8_WACKUP_CTRL	0x2B	/* not used */
+
+#define SDHOST_16_CLK_CTRL	0x2C
+#define __CLK_IN_EN		0x0001
+#define __CLK_IN_STABLE	0x0002
+#define __CLK_SD			0x0004
+#define __CLK_MAX_DIV		2046
+
+static inline void _sdhost_all_clk_off(struct sdhost_host *host)
+{
+	__local_writew(0, host, SDHOST_16_CLK_CTRL);
+}
+
+static inline void _sdhost_sd_clk_off(struct sdhost_host *host)
+{
+	u16 ctrl = 0;
+
+	ctrl = __local_readw(host, SDHOST_16_CLK_CTRL);
+	ctrl &= (~__CLK_SD);
+	__local_writew(ctrl, host, SDHOST_16_CLK_CTRL);
+}
+
+static inline void _sdhost_sd_clk_on(struct sdhost_host *host)
+{
+	u16 ctrl = 0;
+
+	ctrl = __local_readw(host, SDHOST_16_CLK_CTRL);
+	ctrl |= __CLK_SD;
+	__local_writew(ctrl, host, SDHOST_16_CLK_CTRL);
+}
+
+static inline u32 _sdhost_calc_div(u32 base_clk, u32 clk)
+{
+	u32 N;
+
+	if (base_clk <= clk)
+		return 0;
+
+	N = (u32) (base_clk / clk);
+	N = (N >> 1);
+	if (N)
+		N--;
+	if ((base_clk / ((N + 1) << 1)) > clk)
+		N++;
+	if (__CLK_MAX_DIV < N)
+		N = __CLK_MAX_DIV;
+
+	return N;
+}
+
+static inline void _sdhost_clk_set_and_on(struct sdhost_host *host,
+					  u32 div)
+{
+	u16 ctrl = 0;
+
+	__local_writew(0, host, SDHOST_16_CLK_CTRL);
+	ctrl |= (u16) (((div & 0x300) >> 2) | ((div & 0xFF) << 8));
+	ctrl |= __CLK_IN_EN;
+	__local_writew(ctrl, host, SDHOST_16_CLK_CTRL);
+	while (!(__CLK_IN_STABLE & __local_readw(host, SDHOST_16_CLK_CTRL)))
+		;
+}
+
+#define SDHOST_8_TIMEOUT		0x2E
+#define __DATA_TIMEOUT_MAX_VAL		0xe
+
+static inline u8 _sdhost_calc_timeout(unsigned int clock,
+					   u8 timeout_value)
+{
+	unsigned target_timeout, current_timeout;
+	u8 count;
+
+	count = 0;
+	current_timeout = 1 << 16;
+	target_timeout = timeout_value * clock;
+
+	while (target_timeout > current_timeout) {
+		count++;
+		current_timeout <<= 1;
+	}
+	count--;
+	if (count >= 0xF)
+		count = 0xE;
+	return count;
+}
+
+#define SDHOST_8_RST	0x2F
+#define  _RST_ALL		0x01
+#define  _RST_CMD		0x02
+#define  _RST_DATA		0x04
+#define  _RST_EMMC		0x08	/* spredtrum define it byself */
+
+static inline void _sdhost_reset(struct sdhost_host *host, u8 mask)
+{
+	__local_writeb((_RST_EMMC | mask), host, SDHOST_8_RST);
+	/* TODO: change to __local_readb?? */
+	while (_sdhost_readb(host, SDHOST_8_RST) & mask)
+		;
+}
+
+/* spredtrum define it byself */
+static inline void _sdhost_reset_emmc(struct sdhost_host *host)
+{
+	__local_writeb(0, host, SDHOST_8_RST);
+	mdelay(2);
+	__local_writeb(_RST_EMMC, host, SDHOST_8_RST);
+}
+
+#define SDHOST_32_INT_ST		0x30
+#define SDHOST_32_INT_ST_EN		0x34
+#define SDHOST_32_INT_SIG_EN	0x38
+#define _INT_CMD_END			0x00000001
+#define _INT_TRAN_END			0x00000002
+#define _INT_DMA_END			0x00000008
+#define _INT_WR_RDY				0x00000010	/* not used */
+#define _INT_RD_RDY				0x00000020	/* not used */
+#define _INT_ERR				0x00008000
+#define _INT_ERR_CMD_TIMEOUT	0x00010000
+#define _INT_ERR_CMD_CRC		0x00020000
+#define _INT_ERR_CMD_END		0x00040000
+#define _INT_ERR_CMD_INDEX		0x00080000
+#define _INT_ERR_DATA_TIMEOUT	0x00100000
+#define _INT_ERR_DATA_CRC		0x00200000
+#define _INT_ERR_DATA_END		0x00400000
+#define _INT_ERR_CUR_LIMIT		0x00800000
+#define _INT_ERR_ACMD			0x01000000
+#define _INT_ERR_ADMA			0x02000000
+
+/* used in irq */
+#define _INT_FILTER_ERR_CMD \
+	(_INT_ERR_CMD_TIMEOUT | _INT_ERR_CMD_CRC | \
+	_INT_ERR_CMD_END | _INT_ERR_CMD_INDEX)
+#define _INT_FILTER_ERR_DATA \
+	(_INT_ERR_DATA_TIMEOUT | _INT_ERR_DATA_CRC | \
+	_INT_ERR_DATA_END)
+#define _INT_FILTER_ERR \
+	(_INT_ERR | _INT_FILTER_ERR_CMD | \
+	_INT_FILTER_ERR_DATA | _INT_ERR_ACMD | \
+	_INT_ERR_ADMA)
+#define _INT_FILTER_NORMAL \
+	(_INT_CMD_END | _INT_TRAN_END)
+
+/* used for setting */
+#define _DATA_FILTER_RD_SIGLE \
+	(_INT_TRAN_END | _INT_DMA_END | \
+	_INT_ERR | _INT_ERR_DATA_TIMEOUT | \
+	_INT_ERR_DATA_CRC | _INT_ERR_DATA_END)
+#define _DATA_FILTER_RD_MULTI \
+	(_INT_TRAN_END | _INT_DMA_END | _INT_ERR | \
+	_INT_ERR_DATA_TIMEOUT | _INT_ERR_DATA_CRC | \
+	_INT_ERR_DATA_END)
+#define _DATA_FILTER_WR_SIGLE \
+	(_INT_TRAN_END | _INT_DMA_END | \
+	_INT_ERR | _INT_ERR_DATA_TIMEOUT | \
+	_INT_ERR_DATA_CRC)
+#define _DATA_FILTER_WR_MULT \
+	(_INT_TRAN_END | _INT_DMA_END | \
+	_INT_ERR | _INT_ERR_DATA_TIMEOUT | \
+	_INT_ERR_DATA_CRC)
+#define _CMD_FILTER_R0 \
+	_INT_CMD_END
+#define _CMD_FILTER_R2 \
+	(_INT_CMD_END | _INT_ERR | \
+	_INT_ERR_CMD_TIMEOUT | _INT_ERR_CMD_CRC | \
+	_INT_ERR_CMD_END)
+#define _CMD_FILTER_R3 \
+	(_INT_CMD_END | _INT_ERR | \
+	_INT_ERR_CMD_TIMEOUT | _INT_ERR_CMD_END)
+#define _CMD_FILTER_R1_R4_R5_R6_R7 \
+	(_INT_CMD_END | _INT_ERR | \
+	_INT_ERR_CMD_TIMEOUT | _INT_ERR_CMD_CRC | \
+	_INT_ERR_CMD_END | _INT_ERR_CMD_INDEX)
+#define _CMD_FILTER_R1B \
+	(_INT_CMD_END | _INT_ERR | \
+	_INT_ERR_CMD_TIMEOUT | _INT_ERR_CMD_CRC | \
+	_INT_ERR_CMD_END | _INT_ERR_CMD_INDEX | \
+	_INT_TRAN_END | _INT_ERR_DATA_TIMEOUT)
+
+static inline void _sdhost_disable_all_int(struct sdhost_host *host)
+{
+	__local_writel(0x0, host, SDHOST_32_INT_SIG_EN);
+	__local_writel(0x0, host, SDHOST_32_INT_ST_EN);
+	__local_writel(0xFFFFFFFF, host, SDHOST_32_INT_ST);
+}
+
+static inline void _sdhost_enable_int(struct sdhost_host *host, u32 mask)
+{
+	__local_writel(mask, host, SDHOST_32_INT_ST_EN);
+	__local_writel(mask, host, SDHOST_32_INT_SIG_EN);
+}
+
+static inline void _sdhost_clear_int(struct sdhost_host *host, u32 mask)
+{
+	__local_writel(mask, host, SDHOST_32_INT_ST);
+}
+
+#define SDHOST_16_ACMD_ERR		0x3C
+
+#define SDHOST_16_HOST_CTRL_2	0x3E
+#define __TIMING_MODE_SDR12		0x0000
+#define __TIMING_MODE_SDR25		0x0001
+#define __TIMING_MODE_SDR50		0x0002
+#define __TIMING_MODE_SDR104	0x0003
+#define __TIMING_MODE_DDR50		0x0004
+#define __TIMING_MODE_SDR200	0x0005
+
+static inline void _sdhost_set_uhs_mode(struct sdhost_host *host, u16 mode)
+{
+	__local_writew(mode, host, SDHOST_16_HOST_CTRL_2);
+}
+
+#define SDHOST_MAX_CUR	1020
+
+/* the following register is defined by spreadtrum self.
+ * It is not standard register of SDIO
+ * */
+static inline void _sdhost_set_delay(struct sdhost_host *host,
+				     u32 write_delay,
+				     u32 read_pos_delay,
+				     u32 read_neg_delay)
+{
+	__local_writel(write_delay, host, 0x80);
+	__local_writel(read_pos_delay, host, 0x84);
+	__local_writel(read_neg_delay, host, 0x88);
+}
+
+#endif /* __SDHOST_H_ */
diff --git a/drivers/mmc/host/sprd_sdhost_debugfs.c b/drivers/mmc/host/sprd_sdhost_debugfs.c
new file mode 100644
index 0000000..1556cd5
--- /dev/null
+++ b/drivers/mmc/host/sprd_sdhost_debugfs.c
@@ -0,0 +1,213 @@
+/*
+ * linux/drivers/mmc/host/sprd_sdhost_debugfs.c - Secure Digital Host
+ * Controller Interface driver
+ *
+ * Copyright (C) 2015 Spreadtrum corporation.
+ *
+ * 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.
+ *
+ */
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+
+#include "sprd_sdhost_debugfs.h"
+
+#define ELEMENT(v) {v, #v}
+#define ELEMENT_NUM	26
+struct {
+	uint32_t bit;
+	char *caps_name;
+} caps_info[3][ELEMENT_NUM] = {
+	{
+		ELEMENT(MMC_CAP_4_BIT_DATA),
+		ELEMENT(MMC_CAP_MMC_HIGHSPEED),
+		ELEMENT(MMC_CAP_SD_HIGHSPEED),
+		ELEMENT(MMC_CAP_SDIO_IRQ),
+		ELEMENT(MMC_CAP_SPI),
+		ELEMENT(MMC_CAP_NEEDS_POLL),
+		ELEMENT(MMC_CAP_8_BIT_DATA),
+		ELEMENT(MMC_CAP_AGGRESSIVE_PM),
+		ELEMENT(MMC_CAP_NONREMOVABLE),
+		ELEMENT(MMC_CAP_WAIT_WHILE_BUSY),
+		ELEMENT(MMC_CAP_ERASE),
+		ELEMENT(MMC_CAP_1_8V_DDR),
+		ELEMENT(MMC_CAP_1_2V_DDR),
+		ELEMENT(MMC_CAP_POWER_OFF_CARD),
+		ELEMENT(MMC_CAP_BUS_WIDTH_TEST),
+		ELEMENT(MMC_CAP_UHS_SDR12),
+		ELEMENT(MMC_CAP_UHS_SDR25),
+		ELEMENT(MMC_CAP_UHS_SDR50),
+		ELEMENT(MMC_CAP_UHS_SDR104),
+		ELEMENT(MMC_CAP_UHS_DDR50),
+		ELEMENT(MMC_CAP_RUNTIME_RESUME),
+		ELEMENT(MMC_CAP_DRIVER_TYPE_A),
+		ELEMENT(MMC_CAP_DRIVER_TYPE_C),
+		ELEMENT(MMC_CAP_DRIVER_TYPE_D),
+		ELEMENT(MMC_CAP_CMD23),
+		ELEMENT(MMC_CAP_HW_RESET)
+	}, {
+		ELEMENT(MMC_CAP2_BOOTPART_NOACC),
+		ELEMENT(MMC_CAP2_FULL_PWR_CYCLE),
+		ELEMENT(MMC_CAP2_HS200_1_8V_SDR),
+		ELEMENT(MMC_CAP2_HS200_1_2V_SDR),
+		ELEMENT(MMC_CAP2_HS200),
+		ELEMENT(MMC_CAP2_HC_ERASE_SZ),
+		ELEMENT(MMC_CAP2_CD_ACTIVE_HIGH),
+		ELEMENT(MMC_CAP2_RO_ACTIVE_HIGH),
+		ELEMENT(MMC_CAP2_PACKED_RD),
+		ELEMENT(MMC_CAP2_PACKED_WR),
+		ELEMENT(MMC_CAP2_PACKED_CMD),
+		ELEMENT(MMC_CAP2_NO_PRESCAN_POWERUP),
+		ELEMENT(MMC_CAP2_HS400_1_8V),
+		ELEMENT(MMC_CAP2_HS400_1_2V),
+		ELEMENT(MMC_CAP2_HS400),
+		ELEMENT(MMC_CAP2_SDIO_IRQ_NOTHREAD)
+	}, {
+		ELEMENT(MMC_PM_KEEP_POWER),
+		ELEMENT(MMC_PM_WAKE_SDIO_IRQ),
+		ELEMENT(MMC_PM_IGNORE_PM_NOTIFY)
+	}
+
+};
+
+static int sdhost_param_show(struct seq_file *s, void *data)
+{
+	struct sdhost_host *host = s->private;
+	uint32_t i;
+
+	seq_printf(s, "\n"
+		   "ioaddr\t= 0x%p\n"
+		   "irq\t= %d\n"
+		   "device_name\t= %s\n"
+		   "detect_gpio\t= %d\n"
+		   "base_clk\t= %d\n"
+		   "write_delay\t= %d\n"
+		   "read_pos_delay\t= %d\n"
+		   "read_neg_delay\t= %d\n",
+		   host->ioaddr, host->irq, host->device_name,
+		   host->detect_gpio, host->base_clk,
+		   host->write_delay, host->read_pos_delay,
+		   host->read_neg_delay);
+	seq_printf(s, "OCR 0x%x\n", host->ocr_avail);
+
+	for (i = 0; i < ELEMENT_NUM; i++) {
+		if ((caps_info[0][i].bit ==
+			(host->caps & caps_info[0][i].bit))
+					&& caps_info[0][i].bit)
+			seq_printf(s, "caps:%s\n", caps_info[0][i].caps_name);
+	}
+	for (i = 0; i < ELEMENT_NUM; i++) {
+		if ((caps_info[1][i].bit ==
+			(host->caps2 & caps_info[1][i].bit))
+						&& caps_info[1][i].bit)
+			seq_printf(s, "caps2:%s\n", caps_info[1][i].caps_name);
+	}
+	for (i = 0; i < ELEMENT_NUM; i++) {
+		if ((caps_info[2][i].bit ==
+				(host->pm_caps & caps_info[2][i].bit))
+							&& caps_info[2][i].bit)
+			seq_printf(s, "pm_caps:%s\n",
+					caps_info[2][i].caps_name);
+	}
+
+	return 0;
+}
+
+static int sdhost_param_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sdhost_param_show, inode->i_private);
+}
+
+static const struct file_operations sdhost_param_fops = {
+	.open = sdhost_param_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+#define SDHOST_ATTR(PARAM_NAME)	\
+	static int sdhost_##PARAM_NAME##_get(void *data, u64 *val)\
+	{ \
+		struct sdhost_host *host = data;\
+		*val = (u64)host->PARAM_NAME;\
+		return 0;\
+	} \
+	static int sdhost_##PARAM_NAME##_set(void *data, u64 val)\
+	{ \
+		struct sdhost_host *host = data;\
+		if (0x7F >= (uint32_t)val) { \
+			host->PARAM_NAME = (uint32_t)val;\
+			_sdhost_set_delay(host, \
+				host->write_delay, \
+				host->read_pos_delay, \
+				host->read_neg_delay);\
+		} \
+		return 0;\
+	} \
+	DEFINE_SIMPLE_ATTRIBUTE(sdhost_##PARAM_NAME##_fops,\
+					sdhost_##PARAM_NAME##_get,\
+					sdhost_##PARAM_NAME##_set,\
+					"%llu\n")
+
+SDHOST_ATTR(write_delay);
+SDHOST_ATTR(read_pos_delay);
+SDHOST_ATTR(read_neg_delay);
+
+void sdhost_add_debugfs(struct sdhost_host *host)
+{
+	struct dentry *root;
+
+	root = debugfs_create_dir(host->device_name, NULL);
+	if (IS_ERR(root))
+		/* Don't complain -- debugfs just isn't enabled */
+		return;
+	if (!root)
+		return;
+
+	host->debugfs_root = root;
+
+	if (!debugfs_create_file("basic_resource", S_IRUSR, root,
+				(void *)host, &sdhost_param_fops))
+		goto err;
+	if (!debugfs_create_file("write_delay", S_IRUSR | S_IWUSR, root,
+				(void *)host, &sdhost_write_delay_fops))
+		goto err;
+	if (!debugfs_create_file("read_pos_delay", S_IRUSR | S_IWUSR, root,
+				(void *)host, &sdhost_read_pos_delay_fops))
+		goto err;
+	if (!debugfs_create_file("read_neg_delay", S_IRUSR | S_IWUSR, root,
+				(void *)host, &sdhost_read_neg_delay_fops))
+		goto err;
+	return;
+
+err:
+	debugfs_remove_recursive(root);
+	host->debugfs_root = 0;
+}
+
+void dump_sdio_reg(struct sdhost_host *host)
+{
+	unsigned int i;
+
+	if (!host->mmc->card)
+		return;
+
+	pr_info("sdhost" ": =========== REGISTER DUMP (%s)========\n",
+		host->device_name);
+
+	for (i = 0; i < 0x09; i++) {
+		pr_info("0x%08x | 0x%08x | 0x%08x | 0x%08x\n\r",
+		       _sdhost_readl(host, 0 + (i << 4)),
+		       _sdhost_readl(host, 4 + (i << 4)),
+		       _sdhost_readl(host, 8 + (i << 4)),
+		       _sdhost_readl(host, 12 + (i << 4))
+		    );
+	}
+
+	pr_info("sdhost" ": ==================================\n");
+	mdelay(100);
+}
diff --git a/drivers/mmc/host/sprd_sdhost_debugfs.h b/drivers/mmc/host/sprd_sdhost_debugfs.h
new file mode 100644
index 0000000..0063e1b
--- /dev/null
+++ b/drivers/mmc/host/sprd_sdhost_debugfs.h
@@ -0,0 +1,27 @@
+/*
+ * linux/drivers/mmc/host/sprd_sdhost_debugfs.h - Secure Digital Host Controller
+ * Interface driver
+ *
+ * Copyright (C) 2015 Spreadtrum corporation.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _SDHOST_DEBUGFS_H_
+#define _SDHOST_DEBUGFS_H_
+
+#include "sprd_sdhost.h"
+
+#ifdef CONFIG_DEBUG_FS
+void sdhost_add_debugfs(struct sdhost_host *host);
+void dump_sdio_reg(struct sdhost_host *host);
+#else
+static inline void sdhost_add_debugfs(struct sdhost_host *host) {}
+static inline void dump_sdio_reg(struct sdhost_host *host) {}
+#endif
+
+#endif
--
1.7.9.5


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
       [not found] <yes>
                   ` (84 preceding siblings ...)
  2015-07-27  8:16 ` [PATCH v1] mmc: sprd: add MMC host driver for Spreadtrum SoC Billows Wu
@ 2015-10-19  2:27 ` ling.ma.program
  2015-10-19  7:58   ` Ingo Molnar
                     ` (3 more replies)
  2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
                   ` (5 subsequent siblings)
  91 siblings, 4 replies; 716+ messages in thread
From: ling.ma.program @ 2015-10-19  2:27 UTC (permalink / raw)
  To: peterz; +Cc: mingo, linux-kernel, Ma Ling

From: Ma Ling <ling.ml@alibaba-inc.com>

All load instructions can run speculatively but they have to follow
memory order rule in multiple cores as below:
_x = _y = 0

Processor 0				Processor 1

mov r1, [ _y]  //M1			mov [ _x], 1  //M3
mov r2, [ _x]  //M2			mov [ _y], 1  //M4

If r1 = 1, r2 must be 1

In order to guarantee above rule, although Processor 0 execute
M1 and M2 instruction out of order, they are kept in ROB,
when load buffer for _x in Processor 0 received the update 
message from Processor 1, Processor 0 need to roll back
from M2 instruction, which will flush the whole pipeline,
the latency is over the penalty from branch prediction miss.

In this patch we use lock cmpxchg instruction to force load
instructions to be serialization, the destination operand
receives a write cycle without regard to the result of
the comparison, which can help us to reduce the penalty
from load instruction roll back.

Our experiment indicates the performance can be improved by 10%~15%
for 2 and 3 threads cases, the conflicts from lock cache line
spend them most of the time.

Thanks
Ling

Signed-off-by: Ma Ling <ling.ml@alibaba-inc.com>
---
 kernel/locking/qspinlock.c |   43 ++++++++++++++++++-------------------------
 1 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
index 87e9ce6..16421f2 100644
--- a/kernel/locking/qspinlock.c
+++ b/kernel/locking/qspinlock.c
@@ -332,25 +332,14 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
 	if (new == _Q_LOCKED_VAL)
 		return;
 
-	/*
-	 * we're pending, wait for the owner to go away.
-	 *
-	 * *,1,1 -> *,1,0
+	/* we're waiting, and get lock owner
 	 *
-	 * this wait loop must be a load-acquire such that we match the
-	 * store-release that clears the locked bit and create lock
-	 * sequentiality; this is because not all clear_pending_set_locked()
-	 * implementations imply full barriers.
+	 * *,1,* -> *,0,1
 	 */
-	while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_MASK)
+	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending,
+		_Q_PENDING_VAL, _Q_LOCKED_VAL) != _Q_PENDING_VAL)
 		cpu_relax();
-
-	/*
-	 * take ownership and clear the pending bit.
-	 *
-	 * *,1,0 -> *,0,1
-	 */
-	clear_pending_set_locked(lock);
+
 	return;
 
 	/*
@@ -399,17 +388,21 @@ queue:
 	 * we're at the head of the waitqueue, wait for the owner & pending to
 	 * go away.
 	 *
-	 * *,x,y -> *,0,0
-	 *
-	 * this wait loop must use a load-acquire such that we match the
-	 * store-release that clears the locked bit and create lock
-	 * sequentiality; this is because the set_locked() function below
-	 * does not imply a full barrier.
-	 *
+	 * *,x,y -> *,0,1
 	 */
 	pv_wait_head(lock, node);
-	while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_PENDING_MASK)
+	next = READ_ONCE(node->next);
+	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending, 0,
+		_Q_LOCKED_VAL) != 0) {
+		next = READ_ONCE(node->next);
 		cpu_relax();
+	}
+
+	if (next)
+		goto next_node;
+
+	val = smp_load_acquire(&lock->val.counter);
+	tail = tail | _Q_LOCKED_VAL;
 
 	/*
 	 * claim the lock:
@@ -423,7 +416,6 @@ queue:
 	 */
 	for (;;) {
 		if (val != tail) {
-			set_locked(lock);
 			break;
 		}
 		old = atomic_cmpxchg(&lock->val, val, _Q_LOCKED_VAL);
@@ -439,6 +431,7 @@ queue:
 	while (!(next = READ_ONCE(node->next)))
 		cpu_relax();
 
+next_node:
 	arch_mcs_spin_unlock_contended(&next->locked);
 	pv_kick_node(lock, next);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
@ 2015-10-19  7:58   ` Ingo Molnar
  2015-10-19  9:34     ` Peter Zijlstra
  2015-10-20  2:57     ` Ling Ma
  2015-10-19  9:33   ` Peter Zijlstra
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 716+ messages in thread
From: Ingo Molnar @ 2015-10-19  7:58 UTC (permalink / raw)
  To: ling.ma.program; +Cc: peterz, mingo, linux-kernel, Ma Ling


* ling.ma.program@gmail.com <ling.ma.program@gmail.com> wrote:

> From: Ma Ling <ling.ml@alibaba-inc.com>
> 
> All load instructions can run speculatively but they have to follow
> memory order rule in multiple cores as below:
> _x = _y = 0
> 
> Processor 0				Processor 1
> 
> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
> 
> If r1 = 1, r2 must be 1
> 
> In order to guarantee above rule, although Processor 0 execute
> M1 and M2 instruction out of order, they are kept in ROB,
> when load buffer for _x in Processor 0 received the update 
> message from Processor 1, Processor 0 need to roll back
> from M2 instruction, which will flush the whole pipeline,
> the latency is over the penalty from branch prediction miss.
> 
> In this patch we use lock cmpxchg instruction to force load
> instructions to be serialization, the destination operand
> receives a write cycle without regard to the result of
> the comparison, which can help us to reduce the penalty
> from load instruction roll back.
> 
> Our experiment indicates the performance can be improved by 10%~15%
> for 2 and 3 threads cases, the conflicts from lock cache line
> spend them most of the time.

So it would be nice to create a new user-space spinlock testing facility, via a 
new 'perf bench spinlock' feature or so. That way others can test and validate 
your results on different hardware as well.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
  2015-10-19  7:58   ` Ingo Molnar
@ 2015-10-19  9:33   ` Peter Zijlstra
  2015-10-19 17:20     ` Waiman Long
  2015-10-20  3:00     ` Ling Ma
  2015-10-19  9:46   ` Peter Zijlstra
  2015-10-19 17:18   ` Waiman Long
  3 siblings, 2 replies; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-19  9:33 UTC (permalink / raw)
  To: ling.ma.program; +Cc: mingo, linux-kernel, Ma Ling, waiman.long

On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
> From: Ma Ling <ling.ml@alibaba-inc.com>
> 
> All load instructions can run speculatively but they have to follow
> memory order rule in multiple cores as below:
> _x = _y = 0
> 
> Processor 0				Processor 1
> 
> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
> 
> If r1 = 1, r2 must be 1
> 
> In order to guarantee above rule, although Processor 0 execute
> M1 and M2 instruction out of order, they are kept in ROB,
> when load buffer for _x in Processor 0 received the update 
> message from Processor 1, Processor 0 need to roll back
> from M2 instruction, which will flush the whole pipeline,
> the latency is over the penalty from branch prediction miss.
> 
> In this patch we use lock cmpxchg instruction to force load
> instructions to be serialization, the destination operand
> receives a write cycle without regard to the result of
> the comparison, which can help us to reduce the penalty
> from load instruction roll back.
> 
> Our experiment indicates the performance can be improved by 10%~15%
> for 2 and 3 threads cases, the conflicts from lock cache line
> spend them most of the time.

On what hardware? Also, you forgot to Cc Waiman, who is a prime author
of this code. Excessive quoting for his benefit.

> Signed-off-by: Ma Ling <ling.ml@alibaba-inc.com>
> ---
>  kernel/locking/qspinlock.c |   43 ++++++++++++++++++-------------------------
>  1 files changed, 18 insertions(+), 25 deletions(-)
> 
> diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
> index 87e9ce6..16421f2 100644
> --- a/kernel/locking/qspinlock.c
> +++ b/kernel/locking/qspinlock.c
> @@ -332,25 +332,14 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
>  	if (new == _Q_LOCKED_VAL)
>  		return;
>  
> -	/*
> -	 * we're pending, wait for the owner to go away.
> -	 *
> -	 * *,1,1 -> *,1,0
> +	/* we're waiting, and get lock owner

That's incorrect coding style

>  	 *
> -	 * this wait loop must be a load-acquire such that we match the
> -	 * store-release that clears the locked bit and create lock
> -	 * sequentiality; this is because not all clear_pending_set_locked()
> -	 * implementations imply full barriers.
> +	 * *,1,* -> *,0,1
>  	 */
> -	while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_MASK)
> +	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending,
> +		_Q_PENDING_VAL, _Q_LOCKED_VAL) != _Q_PENDING_VAL)

That's both horrible coding style and painful, we should not spin-wait
with a cmpxchg instruction like that.

>  		cpu_relax();
> -
> -	/*
> -	 * take ownership and clear the pending bit.
> -	 *
> -	 * *,1,0 -> *,0,1
> -	 */
> -	clear_pending_set_locked(lock);
> +
>  	return;
>  
>  	/*
> @@ -399,17 +388,21 @@ queue:
>  	 * we're at the head of the waitqueue, wait for the owner & pending to
>  	 * go away.
>  	 *
> -	 * *,x,y -> *,0,0
> -	 *
> -	 * this wait loop must use a load-acquire such that we match the
> -	 * store-release that clears the locked bit and create lock
> -	 * sequentiality; this is because the set_locked() function below
> -	 * does not imply a full barrier.
> -	 *
> +	 * *,x,y -> *,0,1
>  	 */
>  	pv_wait_head(lock, node);
> -	while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_PENDING_MASK)
> +	next = READ_ONCE(node->next);
> +	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending, 0,
> +		_Q_LOCKED_VAL) != 0) {

idem

> +		next = READ_ONCE(node->next);
>  		cpu_relax();
> +	}
> +
> +	if (next)
> +		goto next_node;
> +
> +	val = smp_load_acquire(&lock->val.counter);
> +	tail = tail | _Q_LOCKED_VAL;
>  
>  	/*
>  	 * claim the lock:
> @@ -423,7 +416,6 @@ queue:
>  	 */
>  	for (;;) {
>  		if (val != tail) {
> -			set_locked(lock);
>  			break;
>  		}
>  		old = atomic_cmpxchg(&lock->val, val, _Q_LOCKED_VAL);
> @@ -439,6 +431,7 @@ queue:
>  	while (!(next = READ_ONCE(node->next)))
>  		cpu_relax();
>  
> +next_node:
>  	arch_mcs_spin_unlock_contended(&next->locked);
>  	pv_kick_node(lock, next);
>  
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  7:58   ` Ingo Molnar
@ 2015-10-19  9:34     ` Peter Zijlstra
  2015-10-19 11:24       ` Ingo Molnar
  2015-10-20  2:57     ` Ling Ma
  1 sibling, 1 reply; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-19  9:34 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: ling.ma.program, mingo, linux-kernel, Ma Ling

On Mon, Oct 19, 2015 at 09:58:23AM +0200, Ingo Molnar wrote:
> 
> * ling.ma.program@gmail.com <ling.ma.program@gmail.com> wrote:
> 
> > From: Ma Ling <ling.ml@alibaba-inc.com>
> > 
> > All load instructions can run speculatively but they have to follow
> > memory order rule in multiple cores as below:
> > _x = _y = 0
> > 
> > Processor 0				Processor 1
> > 
> > mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> > mov r2, [ _x]  //M2			mov [ _y], 1  //M4
> > 
> > If r1 = 1, r2 must be 1
> > 
> > In order to guarantee above rule, although Processor 0 execute
> > M1 and M2 instruction out of order, they are kept in ROB,
> > when load buffer for _x in Processor 0 received the update 
> > message from Processor 1, Processor 0 need to roll back
> > from M2 instruction, which will flush the whole pipeline,
> > the latency is over the penalty from branch prediction miss.
> > 
> > In this patch we use lock cmpxchg instruction to force load
> > instructions to be serialization, the destination operand
> > receives a write cycle without regard to the result of
> > the comparison, which can help us to reduce the penalty
> > from load instruction roll back.
> > 
> > Our experiment indicates the performance can be improved by 10%~15%
> > for 2 and 3 threads cases, the conflicts from lock cache line
> > spend them most of the time.
> 
> So it would be nice to create a new user-space spinlock testing facility, via a 
> new 'perf bench spinlock' feature or so. That way others can test and validate 
> your results on different hardware as well.

So its trivial to lift this code into userspace -- in fact, I have that
somewhere.

The trouble is going to keep them in sync.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
  2015-10-19  7:58   ` Ingo Molnar
  2015-10-19  9:33   ` Peter Zijlstra
@ 2015-10-19  9:46   ` Peter Zijlstra
  2015-10-20  3:03     ` Ling Ma
  2015-10-20  3:24     ` Ling Ma
  2015-10-19 17:18   ` Waiman Long
  3 siblings, 2 replies; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-19  9:46 UTC (permalink / raw)
  To: ling.ma.program; +Cc: mingo, linux-kernel, Ma Ling, Waiman Long

On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
> From: Ma Ling <ling.ml@alibaba-inc.com>
> 
> All load instructions can run speculatively but they have to follow
> memory order rule in multiple cores as below:
> _x = _y = 0
> 
> Processor 0				Processor 1
> 
> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
> 
> If r1 = 1, r2 must be 1
> 
> In order to guarantee above rule, although Processor 0 execute
> M1 and M2 instruction out of order, they are kept in ROB,
> when load buffer for _x in Processor 0 received the update
> message from Processor 1, Processor 0 need to roll back
> from M2 instruction, which will flush the whole pipeline,
> the latency is over the penalty from branch prediction miss.
> 
> In this patch we use lock cmpxchg instruction to force load

"lock cmpxchg" makes me think you're working on x86.

> instructions to be serialization,

smp_rmb() does that, and that's 'free' on x86. Because x86 doesn't do
read reordering.

> the destination operand
> receives a write cycle without regard to the result of
> the comparison, which can help us to reduce the penalty
> from load instruction roll back.

And that makes me think I'm not understanding what you're getting at. If
you need to force memory order, a "fence" (or smp_mb()) would still be
cheaper than endlessly pulling the line into exclusive state for no
reason, right?

> Our experiment indicates the performance can be improved by 10%~15%
> for 2 and 3 threads cases, the conflicts from lock cache line
> spend them most of the time.

That just doesn't parse, what?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  9:34     ` Peter Zijlstra
@ 2015-10-19 11:24       ` Ingo Molnar
  2015-10-19 17:24         ` Waiman Long
  0 siblings, 1 reply; 716+ messages in thread
From: Ingo Molnar @ 2015-10-19 11:24 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: ling.ma.program, mingo, linux-kernel, Ma Ling,
	Arnaldo Carvalho de Melo, Jiri Olsa


* Peter Zijlstra <peterz@infradead.org> wrote:

> On Mon, Oct 19, 2015 at 09:58:23AM +0200, Ingo Molnar wrote:
> > 
> > * ling.ma.program@gmail.com <ling.ma.program@gmail.com> wrote:
> > 
> > > From: Ma Ling <ling.ml@alibaba-inc.com>
> > > 
> > > All load instructions can run speculatively but they have to follow
> > > memory order rule in multiple cores as below:
> > > _x = _y = 0
> > > 
> > > Processor 0				Processor 1
> > > 
> > > mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> > > mov r2, [ _x]  //M2			mov [ _y], 1  //M4
> > > 
> > > If r1 = 1, r2 must be 1
> > > 
> > > In order to guarantee above rule, although Processor 0 execute
> > > M1 and M2 instruction out of order, they are kept in ROB,
> > > when load buffer for _x in Processor 0 received the update 
> > > message from Processor 1, Processor 0 need to roll back
> > > from M2 instruction, which will flush the whole pipeline,
> > > the latency is over the penalty from branch prediction miss.
> > > 
> > > In this patch we use lock cmpxchg instruction to force load
> > > instructions to be serialization, the destination operand
> > > receives a write cycle without regard to the result of
> > > the comparison, which can help us to reduce the penalty
> > > from load instruction roll back.
> > > 
> > > Our experiment indicates the performance can be improved by 10%~15%
> > > for 2 and 3 threads cases, the conflicts from lock cache line
> > > spend them most of the time.
> > 
> > So it would be nice to create a new user-space spinlock testing facility, via a 
> > new 'perf bench spinlock' feature or so. That way others can test and validate 
> > your results on different hardware as well.
> 
> So its trivial to lift this code into userspace -- in fact, I have that
> somewhere.
> 
> The trouble is going to keep them in sync.

So we can just try this optimistically, and if it keeps breaking, we can use the 
technique perf uses to sync up the rbtree implementation: we copy the kernel 
version into tooling, but run diff against the kernel version and warn at tool 
build time that there's divergence.

I.e. a non-build-fatal force that keeps things in sync.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
                     ` (2 preceding siblings ...)
  2015-10-19  9:46   ` Peter Zijlstra
@ 2015-10-19 17:18   ` Waiman Long
  2015-10-20  3:12     ` Ling Ma
  3 siblings, 1 reply; 716+ messages in thread
From: Waiman Long @ 2015-10-19 17:18 UTC (permalink / raw)
  To: ling.ma.program; +Cc: peterz, mingo, linux-kernel, Ma Ling

On 10/18/2015 10:27 PM, ling.ma.program@gmail.com wrote:
> From: Ma Ling<ling.ml@alibaba-inc.com>
>
> All load instructions can run speculatively but they have to follow
> memory order rule in multiple cores as below:
> _x = _y = 0
>
> Processor 0				Processor 1
>
> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
>
> If r1 = 1, r2 must be 1
>
> In order to guarantee above rule, although Processor 0 execute
> M1 and M2 instruction out of order, they are kept in ROB,
> when load buffer for _x in Processor 0 received the update
> message from Processor 1, Processor 0 need to roll back
> from M2 instruction, which will flush the whole pipeline,
> the latency is over the penalty from branch prediction miss.
>
> In this patch we use lock cmpxchg instruction to force load
> instructions to be serialization, the destination operand
> receives a write cycle without regard to the result of
> the comparison, which can help us to reduce the penalty
> from load instruction roll back.
>
> Our experiment indicates the performance can be improved by 10%~15%
> for 2 and 3 threads cases, the conflicts from lock cache line
> spend them most of the time.

What kind of performance test were you running? With the right timing, 
it is possible that you see some performance gain. However, if the lock 
hold time is longer so that a fair number of cmpxchg instructions have 
to be executed before it can get the lock, you may see a performance 
degradation especially if the lock holder needs to access the lock 
cacheline.

In general, we try to avoid this kind of cmpxchg loop unless we are sure 
that at most a few iterations of the loop may happen.

>
> Thanks
> Ling
>
> Signed-off-by: Ma Ling<ling.ml@alibaba-inc.com>
> ---
>   kernel/locking/qspinlock.c |   43 ++++++++++++++++++-------------------------
>   1 files changed, 18 insertions(+), 25 deletions(-)
>
> diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
> index 87e9ce6..16421f2 100644
> --- a/kernel/locking/qspinlock.c
> +++ b/kernel/locking/qspinlock.c
> @@ -332,25 +332,14 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
>   	if (new == _Q_LOCKED_VAL)
>   		return;
>
> -	/*
> -	 * we're pending, wait for the owner to go away.
> -	 *
> -	 * *,1,1 ->  *,1,0
> +	/* we're waiting, and get lock owner
>   	 *
> -	 * this wait loop must be a load-acquire such that we match the
> -	 * store-release that clears the locked bit and create lock
> -	 * sequentiality; this is because not all clear_pending_set_locked()
> -	 * implementations imply full barriers.
> +	 * *,1,* ->  *,0,1
>   	 */
> -	while ((val = smp_load_acquire(&lock->val.counter))&  _Q_LOCKED_MASK)
> +	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending,
> +		_Q_PENDING_VAL, _Q_LOCKED_VAL) != _Q_PENDING_VAL)
>   		cpu_relax();
> -
> -	/*
> -	 * take ownership and clear the pending bit.
> -	 *
> -	 * *,1,0 ->  *,0,1
> -	 */
> -	clear_pending_set_locked(lock);
> +
>   	return;
>
>   	/*
> @@ -399,17 +388,21 @@ queue:
>   	 * we're at the head of the waitqueue, wait for the owner&  pending to
>   	 * go away.
>   	 *
> -	 * *,x,y ->  *,0,0
> -	 *
> -	 * this wait loop must use a load-acquire such that we match the
> -	 * store-release that clears the locked bit and create lock
> -	 * sequentiality; this is because the set_locked() function below
> -	 * does not imply a full barrier.
> -	 *
> +	 * *,x,y ->  *,0,1
>   	 */
>   	pv_wait_head(lock, node);
> -	while ((val = smp_load_acquire(&lock->val.counter))&  _Q_LOCKED_PENDING_MASK)
> +	next = READ_ONCE(node->next);
> +	while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending, 0,

The locked_pending field isn't valid if _Q_PENDING_BITS != 8. So it 
won't work if NR_CPUS is 16k or more.

> +		_Q_LOCKED_VAL) != 0) {
> +		next = READ_ONCE(node->next);
>   		cpu_relax();
> +	}
> +
> +	if (next)
> +		goto next_node;

I did notice a slight performance benefit by reading the next pointer 
early in light load cases myself. However, it is a very minor 
improvement that I haven't actively pursued it.

> +
> +	val = smp_load_acquire(&lock->val.counter);
> +	tail = tail | _Q_LOCKED_VAL;
>
>   	/*
>   	 * claim the lock:
> @@ -423,7 +416,6 @@ queue:
>   	 */
>   	for (;;) {
>   		if (val != tail) {
> -			set_locked(lock);
>   			break;
>   		}
>   		old = atomic_cmpxchg(&lock->val, val, _Q_LOCKED_VAL);
> @@ -439,6 +431,7 @@ queue:
>   	while (!(next = READ_ONCE(node->next)))
>   		cpu_relax();
>
> +next_node:
>   	arch_mcs_spin_unlock_contended(&next->locked);
>   	pv_kick_node(lock, next);
>


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  9:33   ` Peter Zijlstra
@ 2015-10-19 17:20     ` Waiman Long
  2015-10-20  3:00     ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Waiman Long @ 2015-10-19 17:20 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: ling.ma.program, mingo, linux-kernel, Ma Ling

On 10/19/2015 05:33 AM, Peter Zijlstra wrote:
> On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
>> From: Ma Ling<ling.ml@alibaba-inc.com>
>>
>> All load instructions can run speculatively but they have to follow
>> memory order rule in multiple cores as below:
>> _x = _y = 0
>>
>> Processor 0				Processor 1
>>
>> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
>> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
>>
>> If r1 = 1, r2 must be 1
>>
>> In order to guarantee above rule, although Processor 0 execute
>> M1 and M2 instruction out of order, they are kept in ROB,
>> when load buffer for _x in Processor 0 received the update
>> message from Processor 1, Processor 0 need to roll back
>> from M2 instruction, which will flush the whole pipeline,
>> the latency is over the penalty from branch prediction miss.
>>
>> In this patch we use lock cmpxchg instruction to force load
>> instructions to be serialization, the destination operand
>> receives a write cycle without regard to the result of
>> the comparison, which can help us to reduce the penalty
>> from load instruction roll back.
>>
>> Our experiment indicates the performance can be improved by 10%~15%
>> for 2 and 3 threads cases, the conflicts from lock cache line
>> spend them most of the time.
> On what hardware? Also, you forgot to Cc Waiman, who is a prime author
> of this code. Excessive quoting for his benefit.

Thanks for letting me aware of this patch. I had commented on the patch 
in a separate mail.

Cheers,
Longman


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19 11:24       ` Ingo Molnar
@ 2015-10-19 17:24         ` Waiman Long
  0 siblings, 0 replies; 716+ messages in thread
From: Waiman Long @ 2015-10-19 17:24 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, ling.ma.program, mingo, linux-kernel, Ma Ling,
	Arnaldo Carvalho de Melo, Jiri Olsa

On 10/19/2015 07:24 AM, Ingo Molnar wrote:
> * Peter Zijlstra<peterz@infradead.org>  wrote:
>
>> On Mon, Oct 19, 2015 at 09:58:23AM +0200, Ingo Molnar wrote:
>>> * ling.ma.program@gmail.com<ling.ma.program@gmail.com>  wrote:
>>>
>>>> From: Ma Ling<ling.ml@alibaba-inc.com>
>>>>
>>>> All load instructions can run speculatively but they have to follow
>>>> memory order rule in multiple cores as below:
>>>> _x = _y = 0
>>>>
>>>> Processor 0				Processor 1
>>>>
>>>> mov r1, [ _y]  //M1			mov [ _x], 1  //M3
>>>> mov r2, [ _x]  //M2			mov [ _y], 1  //M4
>>>>
>>>> If r1 = 1, r2 must be 1
>>>>
>>>> In order to guarantee above rule, although Processor 0 execute
>>>> M1 and M2 instruction out of order, they are kept in ROB,
>>>> when load buffer for _x in Processor 0 received the update
>>>> message from Processor 1, Processor 0 need to roll back
>>>> from M2 instruction, which will flush the whole pipeline,
>>>> the latency is over the penalty from branch prediction miss.
>>>>
>>>> In this patch we use lock cmpxchg instruction to force load
>>>> instructions to be serialization, the destination operand
>>>> receives a write cycle without regard to the result of
>>>> the comparison, which can help us to reduce the penalty
>>>> from load instruction roll back.
>>>>
>>>> Our experiment indicates the performance can be improved by 10%~15%
>>>> for 2 and 3 threads cases, the conflicts from lock cache line
>>>> spend them most of the time.
>>> So it would be nice to create a new user-space spinlock testing facility, via a
>>> new 'perf bench spinlock' feature or so. That way others can test and validate
>>> your results on different hardware as well.
>> So its trivial to lift this code into userspace -- in fact, I have that
>> somewhere.
>>
>> The trouble is going to keep them in sync.
> So we can just try this optimistically, and if it keeps breaking, we can use the
> technique perf uses to sync up the rbtree implementation: we copy the kernel
> version into tooling, but run diff against the kernel version and warn at tool
> build time that there's divergence.
>
> I.e. a non-build-fatal force that keeps things in sync.
>
> Thanks,
>
> 	Ingo
>

It is on my to-do list. I just want to wrap up my latest PV qspinlock 
patch before embarking on this adventure.

Cheers,
Longman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  7:58   ` Ingo Molnar
  2015-10-19  9:34     ` Peter Zijlstra
@ 2015-10-20  2:57     ` Ling Ma
  2015-10-20  8:48       ` Ingo Molnar
  2015-10-20  9:15       ` Peter Zijlstra
  1 sibling, 2 replies; 716+ messages in thread
From: Ling Ma @ 2015-10-20  2:57 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: peterz, mingo, linux-kernel, Ma Ling, Waiman.Long

[-- Attachment #1: Type: text/plain, Size: 409 bytes --]

>
> So it would be nice to create a new user-space spinlock testing facility, via a
> new 'perf bench spinlock' feature or so. That way others can test and validate
> your results on different hardware as well.
>
Attached the spinlock test module . Queued spinlock will run very
slowly in user space
because process switch context, it is OK for  spinlock-test
implementation with kernel module ?

Thanks
Ling

[-- Attachment #2: spinlock.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 4152 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  9:33   ` Peter Zijlstra
  2015-10-19 17:20     ` Waiman Long
@ 2015-10-20  3:00     ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2015-10-20  3:00 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, Ma Ling, waiman.long

2015-10-19 17:33 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
> On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
>> From: Ma Ling <ling.ml@alibaba-inc.com>
>>
>> All load instructions can run speculatively but they have to follow
>> memory order rule in multiple cores as below:
>> _x = _y = 0
>>
>> Processor 0                           Processor 1
>>
>> mov r1, [ _y]  //M1                   mov [ _x], 1  //M3
>> mov r2, [ _x]  //M2                   mov [ _y], 1  //M4
>>
>> If r1 = 1, r2 must be 1
>>
>> In order to guarantee above rule, although Processor 0 execute
>> M1 and M2 instruction out of order, they are kept in ROB,
>> when load buffer for _x in Processor 0 received the update
>> message from Processor 1, Processor 0 need to roll back
>> from M2 instruction, which will flush the whole pipeline,
>> the latency is over the penalty from branch prediction miss.
>>
>> In this patch we use lock cmpxchg instruction to force load
>> instructions to be serialization, the destination operand
>> receives a write cycle without regard to the result of
>> the comparison, which can help us to reduce the penalty
>> from load instruction roll back.
>>
>> Our experiment indicates the performance can be improved by 10%~15%
>> for 2 and 3 threads cases, the conflicts from lock cache line
>> spend them most of the time.
>
> On what hardware? Also, you forgot to Cc Waiman, who is a prime author
> of this code. Excessive quoting for his benefit.
>
>> Signed-off-by: Ma Ling <ling.ml@alibaba-inc.com>
>> ---
>>  kernel/locking/qspinlock.c |   43 ++++++++++++++++++-------------------------
>>  1 files changed, 18 insertions(+), 25 deletions(-)
>>
>> diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
>> index 87e9ce6..16421f2 100644
>> --- a/kernel/locking/qspinlock.c
>> +++ b/kernel/locking/qspinlock.c
>> @@ -332,25 +332,14 @@ void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
>>       if (new == _Q_LOCKED_VAL)
>>               return;
>>
>> -     /*
>> -      * we're pending, wait for the owner to go away.
>> -      *
>> -      * *,1,1 -> *,1,0
>> +     /* we're waiting, and get lock owner
>
> That's incorrect coding style
Ok, I will fix, thx.
>
>>        *
>> -      * this wait loop must be a load-acquire such that we match the
>> -      * store-release that clears the locked bit and create lock
>> -      * sequentiality; this is because not all clear_pending_set_locked()
>> -      * implementations imply full barriers.
>> +      * *,1,* -> *,0,1
>>        */
>> -     while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_MASK)
>> +     while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending,
>> +             _Q_PENDING_VAL, _Q_LOCKED_VAL) != _Q_PENDING_VAL)
>
> That's both horrible coding style and painful, we should not spin-wait
> with a cmpxchg instruction like that.
Ok I will fix
>
>>               cpu_relax();
>> -
>> -     /*
>> -      * take ownership and clear the pending bit.
>> -      *
>> -      * *,1,0 -> *,0,1
>> -      */
>> -     clear_pending_set_locked(lock);
>> +
>>       return;
>>
>>       /*
>> @@ -399,17 +388,21 @@ queue:
>>        * we're at the head of the waitqueue, wait for the owner & pending to
>>        * go away.
>>        *
>> -      * *,x,y -> *,0,0
>> -      *
>> -      * this wait loop must use a load-acquire such that we match the
>> -      * store-release that clears the locked bit and create lock
>> -      * sequentiality; this is because the set_locked() function below
>> -      * does not imply a full barrier.
>> -      *
>> +      * *,x,y -> *,0,1
>>        */
>>       pv_wait_head(lock, node);
>> -     while ((val = smp_load_acquire(&lock->val.counter)) & _Q_LOCKED_PENDING_MASK)
>> +     next = READ_ONCE(node->next);
>> +     while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending, 0,
>> +             _Q_LOCKED_VAL) != 0) {
>
> idem
>
>> +             next = READ_ONCE(node->next);
>>               cpu_relax();
>> +     }
>> +
>> +     if (next)
>> +             goto next_node;
>> +
>> +     val = smp_load_acquire(&lock->val.counter);
>> +     tail = tail | _Q_LOCKED_VAL;
>>
>>       /*
>>        * claim the lock:
>> @@ -423,7 +416,6 @@ queue:
>>        */
>>       for (;;) {
>>               if (val != tail) {
>> -                     set_locked(lock);
>>                       break;
>>               }
>>               old = atomic_cmpxchg(&lock->val, val, _Q_LOCKED_VAL);
>> @@ -439,6 +431,7 @@ queue:
>>       while (!(next = READ_ONCE(node->next)))
>>               cpu_relax();
>>
>> +next_node:
>>       arch_mcs_spin_unlock_contended(&next->locked);
>>       pv_kick_node(lock, next);
>>
>> --
>> 1.7.1
>>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  9:46   ` Peter Zijlstra
@ 2015-10-20  3:03     ` Ling Ma
  2015-10-20  3:24     ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2015-10-20  3:03 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, Ma Ling, Waiman Long

2015-10-19 17:46 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
> On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
>> From: Ma Ling <ling.ml@alibaba-inc.com>
>>
>> All load instructions can run speculatively but they have to follow
>> memory order rule in multiple cores as below:
>> _x = _y = 0
>>
>> Processor 0                           Processor 1
>>
>> mov r1, [ _y]  //M1                   mov [ _x], 1  //M3
>> mov r2, [ _x]  //M2                   mov [ _y], 1  //M4
>>
>> If r1 = 1, r2 must be 1
>>
>> In order to guarantee above rule, although Processor 0 execute
>> M1 and M2 instruction out of order, they are kept in ROB,
>> when load buffer for _x in Processor 0 received the update
>> message from Processor 1, Processor 0 need to roll back
>> from M2 instruction, which will flush the whole pipeline,
>> the latency is over the penalty from branch prediction miss.
>>
>> In this patch we use lock cmpxchg instruction to force load
>
> "lock cmpxchg" makes me think you're working on x86.
>
>> instructions to be serialization,
>
> smp_rmb() does that, and that's 'free' on x86. Because x86 doesn't do
> read reordering.
>
>> the destination operand
>> receives a write cycle without regard to the result of
>> the comparison, which can help us to reduce the penalty
>> from load instruction roll back.
>
> And that makes me think I'm not understanding what you're getting at. If
> you need to force memory order, a "fence" (or smp_mb()) would still be
> cheaper than endlessly pulling the line into exclusive state for no
> reason, right?
>
>> Our experiment indicates the performance can be improved by 10%~15%
>> for 2 and 3 threads cases, the conflicts from lock cache line
>> spend them most of the time.
>
> That just doesn't parse, what?
When the thread number is 2 or 3, only lock cache line will generate conflicts,
and cost them the most of the time.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19 17:18   ` Waiman Long
@ 2015-10-20  3:12     ` Ling Ma
  2015-10-20 18:55       ` Waiman Long
  0 siblings, 1 reply; 716+ messages in thread
From: Ling Ma @ 2015-10-20  3:12 UTC (permalink / raw)
  To: Waiman Long; +Cc: Peter Zijlstra, mingo, linux-kernel, Ma Ling

2015-10-20 1:18 GMT+08:00 Waiman Long <waiman.long@hpe.com>:
> On 10/18/2015 10:27 PM, ling.ma.program@gmail.com wrote:
>>
>> From: Ma Ling<ling.ml@alibaba-inc.com>
>>
>> All load instructions can run speculatively but they have to follow
>> memory order rule in multiple cores as below:
>> _x = _y = 0
>>
>> Processor 0                             Processor 1
>>
>> mov r1, [ _y]  //M1                     mov [ _x], 1  //M3
>> mov r2, [ _x]  //M2                     mov [ _y], 1  //M4
>>
>> If r1 = 1, r2 must be 1
>>
>> In order to guarantee above rule, although Processor 0 execute
>> M1 and M2 instruction out of order, they are kept in ROB,
>> when load buffer for _x in Processor 0 received the update
>> message from Processor 1, Processor 0 need to roll back
>> from M2 instruction, which will flush the whole pipeline,
>> the latency is over the penalty from branch prediction miss.
>>
>> In this patch we use lock cmpxchg instruction to force load
>> instructions to be serialization, the destination operand
>> receives a write cycle without regard to the result of
>> the comparison, which can help us to reduce the penalty
>> from load instruction roll back.
>>
>> Our experiment indicates the performance can be improved by 10%~15%
>> for 2 and 3 threads cases, the conflicts from lock cache line
>> spend them most of the time.
>
>
> What kind of performance test were you running? With the right timing, it is
> possible that you see some performance gain. However, if the lock hold time
> is longer so that a fair number of cmpxchg instructions have to be executed
> before it can get the lock, you may see a performance degradation especially
> if the lock holder needs to access the lock cacheline.
>
> In general, we try to avoid this kind of cmpxchg loop unless we are sure
> that at most a few iterations of the loop may happen.

Waiman,

The machine is Haswell (2699 V3, COD off, HT on, 2 sockets)
(we have sent test module in separate email)



A.      Data is located with lock in one cache line On 2 threads cases
(only write struct member data_a)

 1.       Load version test 5 times, the cost time is below:


[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 103904620

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 104351876

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 118599784

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 103064024

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 103389696

Totally cost time is 533310000

2.       Lock cmpxchg version test 5 times, the cost time is below:

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 67081220

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 97640708

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 96439612

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 66699296

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 96464800



Totally cost time is 424325636



Above data shows lock cmpxchg is better about average 25% (533310000/424325636)



B.      Data is located with lock in different cache line On 2 threads
cases(only write struct member data_b)



1.       Load version test 5 times, the cost time is below:



[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 174266128

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 205053924

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 160165124

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 173241552

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 205765008

Totally cost time is 918491736



2.       Lock cmpxchg version test 5 times, the cost time is below:

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 113410044

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 116293104

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 116064256

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 189320876

[root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c



 all cost time is 123735352

Totally cost time is 658823632



Above data shows lock cmpxchg is better about average 39%  (918491736/658823632)




>
>>
>> Thanks
>> Ling
>>
>> Signed-off-by: Ma Ling<ling.ml@alibaba-inc.com>
>> ---
>>   kernel/locking/qspinlock.c |   43
>> ++++++++++++++++++-------------------------
>>   1 files changed, 18 insertions(+), 25 deletions(-)
>>
>> diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
>> index 87e9ce6..16421f2 100644
>> --- a/kernel/locking/qspinlock.c
>> +++ b/kernel/locking/qspinlock.c
>> @@ -332,25 +332,14 @@ void queued_spin_lock_slowpath(struct qspinlock
>> *lock, u32 val)
>>         if (new == _Q_LOCKED_VAL)
>>                 return;
>>
>> -       /*
>> -        * we're pending, wait for the owner to go away.
>> -        *
>> -        * *,1,1 ->  *,1,0
>> +       /* we're waiting, and get lock owner
>>          *
>> -        * this wait loop must be a load-acquire such that we match the
>> -        * store-release that clears the locked bit and create lock
>> -        * sequentiality; this is because not all
>> clear_pending_set_locked()
>> -        * implementations imply full barriers.
>> +        * *,1,* ->  *,0,1
>>          */
>> -       while ((val = smp_load_acquire(&lock->val.counter))&
>> _Q_LOCKED_MASK)
>> +       while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending,
>> +               _Q_PENDING_VAL, _Q_LOCKED_VAL) != _Q_PENDING_VAL)
>>                 cpu_relax();
>> -
>> -       /*
>> -        * take ownership and clear the pending bit.
>> -        *
>> -        * *,1,0 ->  *,0,1
>> -        */
>> -       clear_pending_set_locked(lock);
>> +
>>         return;
>>
>>         /*
>> @@ -399,17 +388,21 @@ queue:
>>          * we're at the head of the waitqueue, wait for the owner&
>> pending to
>>          * go away.
>>          *
>> -        * *,x,y ->  *,0,0
>> -        *
>> -        * this wait loop must use a load-acquire such that we match the
>> -        * store-release that clears the locked bit and create lock
>> -        * sequentiality; this is because the set_locked() function below
>> -        * does not imply a full barrier.
>> -        *
>> +        * *,x,y ->  *,0,1
>>          */
>>         pv_wait_head(lock, node);
>> -       while ((val = smp_load_acquire(&lock->val.counter))&
>> _Q_LOCKED_PENDING_MASK)
>> +       next = READ_ONCE(node->next);
>> +       while (cmpxchg(&((struct __qspinlock *)lock)->locked_pending, 0,
>
>
> The locked_pending field isn't valid if _Q_PENDING_BITS != 8. So it won't
> work if NR_CPUS is 16k or more.
>
>> +               _Q_LOCKED_VAL) != 0) {
>> +               next = READ_ONCE(node->next);
>>                 cpu_relax();
>> +       }
>> +
>> +       if (next)
>> +               goto next_node;
>
>
> I did notice a slight performance benefit by reading the next pointer early
> in light load cases myself. However, it is a very minor improvement that I
> haven't actively pursued it.

We use "next" to avoid smp_load_acquire(&lock->val.counter)
instruction rollback.

>
>> +
>> +       val = smp_load_acquire(&lock->val.counter);
>> +       tail = tail | _Q_LOCKED_VAL;
>>
>>         /*
>>          * claim the lock:
>> @@ -423,7 +416,6 @@ queue:
>>          */
>>         for (;;) {
>>                 if (val != tail) {
>> -                       set_locked(lock);
>>                         break;
>>                 }
>>                 old = atomic_cmpxchg(&lock->val, val, _Q_LOCKED_VAL);
>> @@ -439,6 +431,7 @@ queue:
>>         while (!(next = READ_ONCE(node->next)))
>>                 cpu_relax();
>>
>> +next_node:
>>         arch_mcs_spin_unlock_contended(&next->locked);
>>         pv_kick_node(lock, next);
>>
>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-19  9:46   ` Peter Zijlstra
  2015-10-20  3:03     ` Ling Ma
@ 2015-10-20  3:24     ` Ling Ma
  2015-10-20  9:16       ` Peter Zijlstra
  1 sibling, 1 reply; 716+ messages in thread
From: Ling Ma @ 2015-10-20  3:24 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, Ma Ling, Waiman Long

2015-10-19 17:46 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
> On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
>> From: Ma Ling <ling.ml@alibaba-inc.com>
>>
>> All load instructions can run speculatively but they have to follow
>> memory order rule in multiple cores as below:
>> _x = _y = 0
>>
>> Processor 0                           Processor 1
>>
>> mov r1, [ _y]  //M1                   mov [ _x], 1  //M3
>> mov r2, [ _x]  //M2                   mov [ _y], 1  //M4
>>
>> If r1 = 1, r2 must be 1
>>
>> In order to guarantee above rule, although Processor 0 execute
>> M1 and M2 instruction out of order, they are kept in ROB,
>> when load buffer for _x in Processor 0 received the update
>> message from Processor 1, Processor 0 need to roll back
>> from M2 instruction, which will flush the whole pipeline,
>> the latency is over the penalty from branch prediction miss.
>>
>> In this patch we use lock cmpxchg instruction to force load
>
> "lock cmpxchg" makes me think you're working on x86.
>
>> instructions to be serialization,
>
> smp_rmb() does that, and that's 'free' on x86. Because x86 doesn't do
> read reordering.
>
>> the destination operand
>> receives a write cycle without regard to the result of
>> the comparison, which can help us to reduce the penalty
>> from load instruction roll back.
>
> And that makes me think I'm not understanding what you're getting at. If
> you need to force memory order, a "fence" (or smp_mb()) would still be
> cheaper than endlessly pulling the line into exclusive state for no
> reason, right?

Peter,

we tested instruction lfence, but we hard to see any benefit, lfence
only force load instruction ,
but load instruction still will rollback ,actually cmpxchg behavior is
more like write operation,
so we choose it.

Thanks
Ling
>
>> Our experiment indicates the performance can be improved by 10%~15%
>> for 2 and 3 threads cases, the conflicts from lock cache line
>> spend them most of the time.
>
> That just doesn't parse, what?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  2:57     ` Ling Ma
@ 2015-10-20  8:48       ` Ingo Molnar
  2015-10-21  5:28         ` Ling Ma
  2015-10-20  9:15       ` Peter Zijlstra
  1 sibling, 1 reply; 716+ messages in thread
From: Ingo Molnar @ 2015-10-20  8:48 UTC (permalink / raw)
  To: Ling Ma; +Cc: peterz, mingo, linux-kernel, Ma Ling, Waiman.Long


* Ling Ma <ling.ma.program@gmail.com> wrote:

> > So it would be nice to create a new user-space spinlock testing facility, via 
> > a new 'perf bench spinlock' feature or so. That way others can test and 
> > validate your results on different hardware as well.
>
> Attached the spinlock test module . Queued spinlock will run very slowly in user 
> space because process switch context, it is OK for spinlock-test implementation 
> with kernel module ?

Not sure what you mean by 'because process switch context': if you pin the test 
tasks to individual CPUs and make sure there's nothing else running it should be 
equivalent to kernel-space execution.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  2:57     ` Ling Ma
  2015-10-20  8:48       ` Ingo Molnar
@ 2015-10-20  9:15       ` Peter Zijlstra
  1 sibling, 0 replies; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-20  9:15 UTC (permalink / raw)
  To: Ling Ma; +Cc: Ingo Molnar, mingo, linux-kernel, Ma Ling, Waiman.Long

On Tue, Oct 20, 2015 at 10:57:53AM +0800, Ling Ma wrote:
> >
> > So it would be nice to create a new user-space spinlock testing facility, via a
> > new 'perf bench spinlock' feature or so. That way others can test and validate
> > your results on different hardware as well.
> >
> Attached the spinlock test module . Queued spinlock will run very
> slowly in user space
> because process switch context, it is OK for  spinlock-test
> implementation with kernel module ?

Works just fine in userspace if you pin each thread to a cpu and ensure
there's nothing else running on the system.


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  3:24     ` Ling Ma
@ 2015-10-20  9:16       ` Peter Zijlstra
  2015-10-21  5:30         ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-20  9:16 UTC (permalink / raw)
  To: Ling Ma; +Cc: mingo, linux-kernel, Ma Ling, Waiman Long

On Tue, Oct 20, 2015 at 11:24:02AM +0800, Ling Ma wrote:
> 2015-10-19 17:46 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
> > On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
> >> From: Ma Ling <ling.ml@alibaba-inc.com>
> >>
> >> All load instructions can run speculatively but they have to follow
> >> memory order rule in multiple cores as below:
> >> _x = _y = 0
> >>
> >> Processor 0                           Processor 1
> >>
> >> mov r1, [ _y]  //M1                   mov [ _x], 1  //M3
> >> mov r2, [ _x]  //M2                   mov [ _y], 1  //M4
> >>
> >> If r1 = 1, r2 must be 1
> >>
> >> In order to guarantee above rule, although Processor 0 execute
> >> M1 and M2 instruction out of order, they are kept in ROB,
> >> when load buffer for _x in Processor 0 received the update
> >> message from Processor 1, Processor 0 need to roll back
> >> from M2 instruction, which will flush the whole pipeline,
> >> the latency is over the penalty from branch prediction miss.
> >>
> >> In this patch we use lock cmpxchg instruction to force load
> >
> > "lock cmpxchg" makes me think you're working on x86.
> >
> >> instructions to be serialization,
> >
> > smp_rmb() does that, and that's 'free' on x86. Because x86 doesn't do
> > read reordering.
> >
> >> the destination operand
> >> receives a write cycle without regard to the result of
> >> the comparison, which can help us to reduce the penalty
> >> from load instruction roll back.
> >
> > And that makes me think I'm not understanding what you're getting at. If
> > you need to force memory order, a "fence" (or smp_mb()) would still be
> > cheaper than endlessly pulling the line into exclusive state for no
> > reason, right?
> 
> Peter,
> 
> we tested instruction lfence, but we hard to see any benefit, lfence
> only force load instruction ,
> but load instruction still will rollback ,actually cmpxchg behavior is
> more like write operation,
> so we choose it.

But why? I'm just not getting this.

Also LOCK CMPXCHG is 24 cycles when hot, that's almost as bad as
a pipeline flush, and it can be many times worse when it needs to
actually fetch memory from further than L1.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  3:12     ` Ling Ma
@ 2015-10-20 18:55       ` Waiman Long
  2015-10-21  5:43         ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: Waiman Long @ 2015-10-20 18:55 UTC (permalink / raw)
  To: Ling Ma; +Cc: Peter Zijlstra, mingo, linux-kernel, Ma Ling

On 10/19/2015 11:12 PM, Ling Ma wrote:
> 2015-10-20 1:18 GMT+08:00 Waiman Long<waiman.long@hpe.com>:
>> On 10/18/2015 10:27 PM, ling.ma.program@gmail.com wrote:
>>> From: Ma Ling<ling.ml@alibaba-inc.com>
>>>
>>> All load instructions can run speculatively but they have to follow
>>> memory order rule in multiple cores as below:
>>> _x = _y = 0
>>>
>>> Processor 0                             Processor 1
>>>
>>> mov r1, [ _y]  //M1                     mov [ _x], 1  //M3
>>> mov r2, [ _x]  //M2                     mov [ _y], 1  //M4
>>>
>>> If r1 = 1, r2 must be 1
>>>
>>> In order to guarantee above rule, although Processor 0 execute
>>> M1 and M2 instruction out of order, they are kept in ROB,
>>> when load buffer for _x in Processor 0 received the update
>>> message from Processor 1, Processor 0 need to roll back
>>> from M2 instruction, which will flush the whole pipeline,
>>> the latency is over the penalty from branch prediction miss.
>>>
>>> In this patch we use lock cmpxchg instruction to force load
>>> instructions to be serialization, the destination operand
>>> receives a write cycle without regard to the result of
>>> the comparison, which can help us to reduce the penalty
>>> from load instruction roll back.
>>>
>>> Our experiment indicates the performance can be improved by 10%~15%
>>> for 2 and 3 threads cases, the conflicts from lock cache line
>>> spend them most of the time.
>>
>> What kind of performance test were you running? With the right timing, it is
>> possible that you see some performance gain. However, if the lock hold time
>> is longer so that a fair number of cmpxchg instructions have to be executed
>> before it can get the lock, you may see a performance degradation especially
>> if the lock holder needs to access the lock cacheline.
>>
>> In general, we try to avoid this kind of cmpxchg loop unless we are sure
>> that at most a few iterations of the loop may happen.
> Waiman,
>
> The machine is Haswell (2699 V3, COD off, HT on, 2 sockets)
> (we have sent test module in separate email)
>
>
>
> A.      Data is located with lock in one cache line On 2 threads cases
> (only write struct member data_a)
>
>   1.       Load version test 5 times, the cost time is below:
>
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 103904620
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 104351876
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 118599784
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 103064024
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 103389696
>
> Totally cost time is 533310000
>
> 2.       Lock cmpxchg version test 5 times, the cost time is below:
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 67081220
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 97640708
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 96439612
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 66699296
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 96464800
>
>
>
> Totally cost time is 424325636
>
>
>
> Above data shows lock cmpxchg is better about average 25% (533310000/424325636)
>
>
>
> B.      Data is located with lock in different cache line On 2 threads
> cases(only write struct member data_b)
>
>
>
> 1.       Load version test 5 times, the cost time is below:
>
>
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 174266128
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 205053924
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 160165124
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 173241552
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 205765008
>
> Totally cost time is 918491736
>
>
>
> 2.       Lock cmpxchg version test 5 times, the cost time is below:
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 113410044
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 116293104
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 116064256
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 189320876
>
> [root@localhost spinlock]# insmod dummy.ko; rmmod dummy;dmesg -c
>
>
>
>   all cost time is 123735352
>
> Totally cost time is 658823632
>
>
>
> Above data shows lock cmpxchg is better about average 39%  (918491736/658823632)
>
>

I did see some performance improvement when I used your test program on 
a Haswell-EX system. It seems like the use of cmpxchg has forced the 
changed memory values to be visible to other processors earlier. I also 
ran your test on an older machine with Westmere-EX processors. This 
time, I didn't see any performance improvement. In fact, your change 
actually make it a tiny bit slower. So the benefit of your patch can be 
highly processor sensitive.

As other architectures like ARM & AA64 are going to adopt qspinlock in 
the near future, we will also need to make sure that it won't cause a 
regression there. So I don't see your patch has a big chance of being 
merged upstream unless you can provide a real world workload that can 
benefit from your patch. Even then, proving that it won't cause 
regression in other processors or architectures can be tedious.

Cheers,
Longman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  8:48       ` Ingo Molnar
@ 2015-10-21  5:28         ` Ling Ma
  2015-10-21  7:54           ` Peter Zijlstra
  0 siblings, 1 reply; 716+ messages in thread
From: Ling Ma @ 2015-10-21  5:28 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Peter Zijlstra, mingo, linux-kernel, Ma Ling, Waiman Long

Ok, we will put the spinlock test into the perf bench.

Thanks
Ling

2015-10-20 16:48 GMT+08:00 Ingo Molnar <mingo@kernel.org>:
>
> * Ling Ma <ling.ma.program@gmail.com> wrote:
>
>> > So it would be nice to create a new user-space spinlock testing facility, via
>> > a new 'perf bench spinlock' feature or so. That way others can test and
>> > validate your results on different hardware as well.
>>
>> Attached the spinlock test module . Queued spinlock will run very slowly in user
>> space because process switch context, it is OK for spinlock-test implementation
>> with kernel module ?
>
> Not sure what you mean by 'because process switch context': if you pin the test
> tasks to individual CPUs and make sure there's nothing else running it should be
> equivalent to kernel-space execution.
>
> Thanks,
>
>         Ingo

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20  9:16       ` Peter Zijlstra
@ 2015-10-21  5:30         ` Ling Ma
  0 siblings, 0 replies; 716+ messages in thread
From: Ling Ma @ 2015-10-21  5:30 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: mingo, linux-kernel, Ma Ling, Waiman Long

2015-10-20 17:16 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
> On Tue, Oct 20, 2015 at 11:24:02AM +0800, Ling Ma wrote:
>> 2015-10-19 17:46 GMT+08:00 Peter Zijlstra <peterz@infradead.org>:
>> > On Mon, Oct 19, 2015 at 10:27:22AM +0800, ling.ma.program@gmail.com wrote:
>> >> From: Ma Ling <ling.ml@alibaba-inc.com>
>> >>
>> >> All load instructions can run speculatively but they have to follow
>> >> memory order rule in multiple cores as below:
>> >> _x = _y = 0
>> >>
>> >> Processor 0                           Processor 1
>> >>
>> >> mov r1, [ _y]  //M1                   mov [ _x], 1  //M3
>> >> mov r2, [ _x]  //M2                   mov [ _y], 1  //M4
>> >>
>> >> If r1 = 1, r2 must be 1
>> >>
>> >> In order to guarantee above rule, although Processor 0 execute
>> >> M1 and M2 instruction out of order, they are kept in ROB,
>> >> when load buffer for _x in Processor 0 received the update
>> >> message from Processor 1, Processor 0 need to roll back
>> >> from M2 instruction, which will flush the whole pipeline,
>> >> the latency is over the penalty from branch prediction miss.
>> >>
>> >> In this patch we use lock cmpxchg instruction to force load
>> >
>> > "lock cmpxchg" makes me think you're working on x86.
>> >
>> >> instructions to be serialization,
>> >
>> > smp_rmb() does that, and that's 'free' on x86. Because x86 doesn't do
>> > read reordering.
>> >
>> >> the destination operand
>> >> receives a write cycle without regard to the result of
>> >> the comparison, which can help us to reduce the penalty
>> >> from load instruction roll back.
>> >
>> > And that makes me think I'm not understanding what you're getting at. If
>> > you need to force memory order, a "fence" (or smp_mb()) would still be
>> > cheaper than endlessly pulling the line into exclusive state for no
>> > reason, right?
>>
>> Peter,
>>
>> we tested instruction lfence, but we hard to see any benefit, lfence
>> only force load instruction ,
>> but load instruction still will rollback ,actually cmpxchg behavior is
>> more like write operation,
>> so we choose it.
>
> But why? I'm just not getting this.
>
> Also LOCK CMPXCHG is 24 cycles when hot, that's almost as bad as
> a pipeline flush, and it can be many times worse when it needs to
> actually fetch memory from further than L1.

We will clarify the root cause about this question soon.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-20 18:55       ` Waiman Long
@ 2015-10-21  5:43         ` Ling Ma
  0 siblings, 0 replies; 716+ messages in thread
From: Ling Ma @ 2015-10-21  5:43 UTC (permalink / raw)
  To: Waiman Long; +Cc: Peter Zijlstra, mingo, linux-kernel, Ma Ling

>
> I did see some performance improvement when I used your test program on a
> Haswell-EX system. It seems like the use of cmpxchg has forced the changed
> memory values to be visible to other processors earlier. I also ran your
> test on an older machine with Westmere-EX processors. This time, I didn't
> see any performance improvement. In fact, your change actually make it a
> tiny bit slower. So the benefit of your patch can be highly processor
> sensitive.
>
> As other architectures like ARM & AA64 are going to adopt qspinlock in the
> near future, we will also need to make sure that it won't cause a regression
> there. So I don't see your patch has a big chance of being merged upstream
> unless you can provide a real world workload that can benefit from your
> patch. Even then, proving that it won't cause regression in other processors
> or architectures can be tedious.
>

The optimization will be closely related with CPU arch and cache
coherence implementation.
so we will test it for real world workload on Haswell, and send out the result.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback
  2015-10-21  5:28         ` Ling Ma
@ 2015-10-21  7:54           ` Peter Zijlstra
  0 siblings, 0 replies; 716+ messages in thread
From: Peter Zijlstra @ 2015-10-21  7:54 UTC (permalink / raw)
  To: Ling Ma; +Cc: Ingo Molnar, mingo, linux-kernel, Ma Ling, Waiman Long

[-- Attachment #1: Type: text/plain, Size: 293 bytes --]

On Wed, Oct 21, 2015 at 01:28:04PM +0800, Ling Ma wrote:
> Ok, we will put the spinlock test into the perf bench.

The attached is what I used back when we were doing the initial
qspinlock stuff.

I've not looked at it in quite some time, so it might be out of sync
with the kernel sources.



[-- Attachment #2: spinlocks.tar.bz2 --]
[-- Type: application/octet-stream, Size: 30648 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
       [not found] <yes>
                   ` (85 preceding siblings ...)
  2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
@ 2015-12-31  8:09 ` ling.ma.program
  2016-01-05 18:46   ` Waiman Long
  2016-01-05 21:18   ` Peter Zijlstra
  2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
                   ` (4 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: ling.ma.program @ 2015-12-31  8:09 UTC (permalink / raw)
  To: waiman.long; +Cc: peterz, mingo, linux-kernel, akpm, ling.ml

From: Ma Ling <ling.ml@alibaba-inc.com>

Hi ALL,

Wire-latency(RC delay) dominate modern computer performance,
conventional serialized works cause cache line ping-pong seriously,
the process spend lots of time and power to complete.
specially on multi-core platform.

However if the serialized works are sent to one core and executed
when lock contention happens, that can save much time and power,
because all shared data are located in private cache of one core.
We call the mechanism as Acceleration from Lock Integration
(ali spinlock)

Usually when requests are queued, we have to wait work to submit 
one bye one, in order to improve the whole throughput further,
we introduce LOCK_FREE. So when requests are sent to lock owner,
requester may do other works in parallelism, then ali_spin_is_completed 
function could tell us whether the work has been completed.

The new code is based on qspinlock and implement Lock Integration,
improves performance up to 3X on intel platform with 72 cores(18x2HTx2S HSW),
2X on ARM platform with 96 cores too. And additional trival changes on
Makefile/Kconfig are made to enable compiling of this feature on x86 platform.
(We would like to do further experiments according to your requirement)

Happy New Year 2016!
Ling 

Signed-off-by: Ma Ling <ling.ml@alibaba-inc.com> 
---
 arch/x86/Kconfig             |    1 +
 include/linux/alispinlock.h  |   41 ++++++++++++++++++
 kernel/Kconfig.locks         |    7 +++
 kernel/locking/Makefile      |    1 +
 kernel/locking/alispinlock.c |   97 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 147 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/alispinlock.h
 create mode 100644 kernel/locking/alispinlock.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index db3622f..47d9277 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -42,6 +42,7 @@ config X86
 	select ARCH_USE_CMPXCHG_LOCKREF		if X86_64
 	select ARCH_USE_QUEUED_RWLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS
+	select ARCH_USE_ALI_SPINLOCKS
 	select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP
 	select ARCH_WANTS_DYNAMIC_TASK_STRUCT
 	select ARCH_WANT_FRAME_POINTERS
diff --git a/include/linux/alispinlock.h b/include/linux/alispinlock.h
new file mode 100644
index 0000000..5207c41
--- /dev/null
+++ b/include/linux/alispinlock.h
@@ -0,0 +1,41 @@
+#ifndef ALI_SPINLOCK_H
+#define ALI_SPINLOCK_H
+/*
+ * Acceleration from Lock Integration
+ *
+ * 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.
+ *
+ * Copyright (C) 2015 Alibaba Group.
+ *
+ * Authors: Ma Ling <ling.ml@alibaba-inc.com>
+ *
+ */
+typedef struct ali_spinlock {
+	void  *lock_p;
+} ali_spinlock_t;
+
+struct ali_spinlock_info {
+	struct ali_spinlock_info *next;
+	int flags;
+	int locked;
+	void (*fn)(void *);
+	void *para;
+};
+
+static __always_inline int ali_spin_is_completed(struct ali_spinlock_info *ali)
+{
+	return (READ_ONCE(ali->locked) == 0);
+}
+
+void alispinlock(struct ali_spinlock *lock, struct ali_spinlock_info *ali);
+
+#define ALI_LOCK_FREE 1 
+#endif /* ALI_SPINLOCK_H */
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks
index ebdb004..5130c63 100644
--- a/kernel/Kconfig.locks
+++ b/kernel/Kconfig.locks
@@ -235,6 +235,13 @@ config LOCK_SPIN_ON_OWNER
        def_bool y
        depends on MUTEX_SPIN_ON_OWNER || RWSEM_SPIN_ON_OWNER
 
+config ARCH_USE_ALI_SPINLOCKS
+	bool
+
+config ALI_SPINLOCKS
+	def_bool y if ARCH_USE_ALI_SPINLOCKS
+	depends on SMP
+
 config ARCH_USE_QUEUED_SPINLOCKS
 	bool
 
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile
index 8e96f6c..a4241f8 100644
--- a/kernel/locking/Makefile
+++ b/kernel/locking/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_LOCKDEP) += lockdep.o
 ifeq ($(CONFIG_PROC_FS),y)
 obj-$(CONFIG_LOCKDEP) += lockdep_proc.o
 endif
+obj-$(CONFIG_ALI_SPINLOCKS) += alispinlock.o
 obj-$(CONFIG_SMP) += spinlock.o
 obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o
 obj-$(CONFIG_SMP) += lglock.o
diff --git a/kernel/locking/alispinlock.c b/kernel/locking/alispinlock.c
new file mode 100644
index 0000000..43078b4
--- /dev/null
+++ b/kernel/locking/alispinlock.c
@@ -0,0 +1,97 @@
+/*
+ * Acceleration from Lock Integration
+ *
+ * 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.
+ *
+ * Copyright (C) 2015 Alibaba Group.
+ *
+ * Authors: Ma Ling <ling.ml@alibaba-inc.com>
+ *
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/alispinlock.h>
+/*
+ * Wire-latency(RC delay) dominate modern computer performance,
+ * conventional serialized works cause cache line ping-pong seriously,
+ * the process spend lots of time and power to complete.
+ * specially on multi-core platform.
+ * 
+ * However if the serialized works are sent to one core and executed
+ * when lock contention happens, that can save much time and power,
+ * because all shared data are located in private cache of one core.
+ * We call the mechanism as Acceleration from Lock Integration
+ * (ali spinlock)
+ * 
+ * Usually when requests are queued, we have to wait work to submit 
+ * one bye one, in order to improve the whole throughput further,
+ * we introduce LOCK_FREE. So when requests are sent to lock owner,
+ * requester may do other works in parallelism, then ali_spin_is_completed 
+ * function could tell us whether the work is completed.
+ *
+ */
+void alispinlock(struct ali_spinlock *lock, struct ali_spinlock_info *ali)
+{
+	struct ali_spinlock_info *next, *old;
+
+	ali->next = NULL;
+	ali->locked = 1;
+	old = xchg(&lock->lock_p, ali);
+
+	/* If NULL we are the first one */
+	if (old) {
+		WRITE_ONCE(old->next, ali);
+		if(ali->flags & ALI_LOCK_FREE)
+			return;
+		while((READ_ONCE(ali->locked)))
+			cpu_relax_lowlatency();
+		return;
+	}
+	old = READ_ONCE(lock->lock_p);
+
+	/* Handle all pending works */
+repeat:	
+	if(old == ali)
+		goto end;
+
+	while (!(next = READ_ONCE(ali->next)))
+		cpu_relax();
+	
+	ali->fn(ali->para);
+	ali->locked = 0;
+
+	if(old != next) {
+		while (!(ali = READ_ONCE(next->next)))
+			cpu_relax();
+		next->fn(next->para);
+		next->locked = 0;
+		goto repeat;
+		
+	} else
+		ali = next;
+end:
+	ali->fn(ali->para);
+	/* If we are the last one, clear lock and return */
+	old = cmpxchg(&lock->lock_p, old, 0);
+
+	if(old != ali) {
+		/* There are still some works to do */
+		while (!(next = READ_ONCE(ali->next)))
+			cpu_relax();
+		ali->locked = 0;
+		ali = next;
+		goto repeat;
+	}
+
+	ali->locked = 0;
+	return;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
@ 2016-01-05 18:46   ` Waiman Long
  2016-01-08 22:48     ` Ling Ma
  2016-01-05 21:18   ` Peter Zijlstra
  1 sibling, 1 reply; 716+ messages in thread
From: Waiman Long @ 2016-01-05 18:46 UTC (permalink / raw)
  To: ling.ma.program; +Cc: peterz, mingo, linux-kernel, akpm, ling.ml

On 12/31/2015 03:09 AM, ling.ma.program@gmail.com wrote:
> From: Ma Ling<ling.ml@alibaba-inc.com>
>
> Hi ALL,
>
> Wire-latency(RC delay) dominate modern computer performance,
> conventional serialized works cause cache line ping-pong seriously,
> the process spend lots of time and power to complete.
> specially on multi-core platform.
>
> However if the serialized works are sent to one core and executed
> when lock contention happens, that can save much time and power,
> because all shared data are located in private cache of one core.
> We call the mechanism as Acceleration from Lock Integration
> (ali spinlock)
>
> Usually when requests are queued, we have to wait work to submit
> one bye one, in order to improve the whole throughput further,
> we introduce LOCK_FREE. So when requests are sent to lock owner,
> requester may do other works in parallelism, then ali_spin_is_completed
> function could tell us whether the work has been completed.
>
> The new code is based on qspinlock and implement Lock Integration,
> improves performance up to 3X on intel platform with 72 cores(18x2HTx2S HSW),
> 2X on ARM platform with 96 cores too. And additional trival changes on
> Makefile/Kconfig are made to enable compiling of this feature on x86 platform.
> (We would like to do further experiments according to your requirement)
>
> Happy New Year 2016!
> Ling
>
> Signed-off-by: Ma Ling<ling.ml@alibaba-inc.com>
> ---
>   arch/x86/Kconfig             |    1 +
>   include/linux/alispinlock.h  |   41 ++++++++++++++++++
>   kernel/Kconfig.locks         |    7 +++
>   kernel/locking/Makefile      |    1 +
>   kernel/locking/alispinlock.c |   97 ++++++++++++++++++++++++++++++++++++++++++
>   5 files changed, 147 insertions(+), 0 deletions(-)
>   create mode 100644 include/linux/alispinlock.h
>   create mode 100644 kernel/locking/alispinlock.c
>
>

You should include additional patches that illustrate the possible use 
cases and performance improvement before and after the patches. This 
will allow the reviewers to actually try it out and play with it.

Cheers,
Longman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
  2016-01-05 18:46   ` Waiman Long
@ 2016-01-05 21:18   ` Peter Zijlstra
  2016-01-05 21:42     ` One Thousand Gnomes
  2016-01-08 22:56     ` Ling Ma
  1 sibling, 2 replies; 716+ messages in thread
From: Peter Zijlstra @ 2016-01-05 21:18 UTC (permalink / raw)
  To: ling.ma.program; +Cc: waiman.long, mingo, linux-kernel, akpm, ling.ml

On Thu, Dec 31, 2015 at 04:09:34PM +0800, ling.ma.program@gmail.com wrote:
> +void alispinlock(struct ali_spinlock *lock, struct ali_spinlock_info *ali)
> +{
> +	struct ali_spinlock_info *next, *old;
> +
> +	ali->next = NULL;
> +	ali->locked = 1;
> +	old = xchg(&lock->lock_p, ali);
> +
> +	/* If NULL we are the first one */
> +	if (old) {
> +		WRITE_ONCE(old->next, ali);
> +		if(ali->flags & ALI_LOCK_FREE)
> +			return;
> +		while((READ_ONCE(ali->locked)))
> +			cpu_relax_lowlatency();
> +		return;
> +	}
> +	old = READ_ONCE(lock->lock_p);
> +
> +	/* Handle all pending works */
> +repeat:	
> +	if(old == ali)
> +		goto end;
> +
> +	while (!(next = READ_ONCE(ali->next)))
> +		cpu_relax();
> +	
> +	ali->fn(ali->para);
> +	ali->locked = 0;
> +
> +	if(old != next) {
> +		while (!(ali = READ_ONCE(next->next)))
> +			cpu_relax();
> +		next->fn(next->para);
> +		next->locked = 0;
> +		goto repeat;
> +		
> +	} else
> +		ali = next;

So I have a whole bunch of problems with this thing.. For one I object
to this being called a lock. Its much more like an async work queue like
thing.

It suffers the typical problems all those constructs do; namely it
wrecks accountability.

But here that is compounded by the fact that you inject other people's
work into 'your' lock region, thereby bloating lock hold times. Worse,
afaict (from a quick reading) there really isn't a bound on the amount
of work you inject.

This will completely wreck scheduling latency. At the very least the
callback loop should have a need_resched() test on, but even that will
not work if this has IRQs disabled.


And while its a cute collapse of an MCS lock and lockless list style
work queue (MCS after all is a lockless list), saving a few cycles from
the naive spinlock+llist implementation of the same thing, I really
do not see enough justification for any of this.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-05 21:18   ` Peter Zijlstra
@ 2016-01-05 21:42     ` One Thousand Gnomes
  2016-01-06  8:16       ` Peter Zijlstra
  2016-01-08 23:01       ` Ling Ma
  2016-01-08 22:56     ` Ling Ma
  1 sibling, 2 replies; 716+ messages in thread
From: One Thousand Gnomes @ 2016-01-05 21:42 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: ling.ma.program, waiman.long, mingo, linux-kernel, akpm, ling.ml

> It suffers the typical problems all those constructs do; namely it
> wrecks accountability.

That's "government thinking" ;-) - for most real users throughput is
more important than accountability. With the right API it ought to also
be compile time switchable.

> But here that is compounded by the fact that you inject other people's
> work into 'your' lock region, thereby bloating lock hold times. Worse,
> afaict (from a quick reading) there really isn't a bound on the amount
> of work you inject.

That should be relatively easy to fix but for this kind of lock you
normally get the big wins from stuff that is only a short amount of
executing code. The fairness your trade in the cases it is useful should
be tiny except under extreme load, where the "accountability first"
behaviour would be to fall over in a heap.

If your "lock" involves a lot of work then it probably should be a work
queue or not using this kind of locking.

> And while its a cute collapse of an MCS lock and lockless list style
> work queue (MCS after all is a lockless list), saving a few cycles from
> the naive spinlock+llist implementation of the same thing, I really
> do not see enough justification for any of this.

I've only personally dealt with such locks in the embedded space but
there it was a lot more than a few cycles because you go from


	take lock
						spins
	pull things into cache
	do stuff
	cache lines go write/exclusive
	unlock

						take lock
						move all the cache
						do stuff
						etc

to

	take lock
						queue work
	pull things into cache
	do work 1
	caches line go write/exclusive
	do work 2
	
	unlock
						done

and for the kind of stuff you apply those locks you got big improvements.
Even on crappy little embedded processors cache bouncing hurts. Even
better work merging locks like this tend to improve throughput more the
higher the contention unlike most other lock types.

The claim in the original post is 3x performance but doesn't explain
performance doing what, or which kernel locks were switched and what
patches were used. I don't find the numbers hard to believe for a big big
box, but I'd like to see the actual use case patches so it can be benched
with other workloads and also for latency and the like.

Alan

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-05 21:42     ` One Thousand Gnomes
@ 2016-01-06  8:16       ` Peter Zijlstra
  2016-01-06  8:21         ` Peter Zijlstra
  2016-01-08 23:01       ` Ling Ma
  1 sibling, 1 reply; 716+ messages in thread
From: Peter Zijlstra @ 2016-01-06  8:16 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: ling.ma.program, waiman.long, mingo, linux-kernel, akpm, ling.ml

On Tue, Jan 05, 2016 at 09:42:27PM +0000, One Thousand Gnomes wrote:
> > It suffers the typical problems all those constructs do; namely it
> > wrecks accountability.
> 
> That's "government thinking" ;-) - for most real users throughput is
> more important than accountability. With the right API it ought to also
> be compile time switchable.

Its to do with having been involved with -rt. RT wants to do
accountability for such things because of PI and sorts.

> > But here that is compounded by the fact that you inject other people's
> > work into 'your' lock region, thereby bloating lock hold times. Worse,
> > afaict (from a quick reading) there really isn't a bound on the amount
> > of work you inject.
> 
> That should be relatively easy to fix but for this kind of lock you
> normally get the big wins from stuff that is only a short amount of
> executing code. The fairness your trade in the cases it is useful should
> be tiny except under extreme load, where the "accountability first"
> behaviour would be to fall over in a heap.
> 
> If your "lock" involves a lot of work then it probably should be a work
> queue or not using this kind of locking.

Sure, but the fact that it was not even mentioned/considered doesn't
give me a warm fuzzy feeling.

> > And while its a cute collapse of an MCS lock and lockless list style
> > work queue (MCS after all is a lockless list), saving a few cycles from
> > the naive spinlock+llist implementation of the same thing, I really
> > do not see enough justification for any of this.
> 
> I've only personally dealt with such locks in the embedded space but
> there it was a lot more than a few cycles because you go from

Nah, what I meant was that you can do the same callback style construct
with a llist and a spinlock.

> The claim in the original post is 3x performance but doesn't explain
> performance doing what, or which kernel locks were switched and what
> patches were used. I don't find the numbers hard to believe for a big big
> box, but I'd like to see the actual use case patches so it can be benched
> with other workloads and also for latency and the like.

Very much agreed, those claims need to be substantiated with actual
patches using this thing and independently verified.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-06  8:16       ` Peter Zijlstra
@ 2016-01-06  8:21         ` Peter Zijlstra
  2016-01-06 11:24           ` One Thousand Gnomes
  0 siblings, 1 reply; 716+ messages in thread
From: Peter Zijlstra @ 2016-01-06  8:21 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: ling.ma.program, waiman.long, mingo, linux-kernel, akpm, ling.ml

On Wed, Jan 06, 2016 at 09:16:43AM +0100, Peter Zijlstra wrote:
> On Tue, Jan 05, 2016 at 09:42:27PM +0000, One Thousand Gnomes wrote:
> > > It suffers the typical problems all those constructs do; namely it
> > > wrecks accountability.
> > 
> > That's "government thinking" ;-) - for most real users throughput is
> > more important than accountability. With the right API it ought to also
> > be compile time switchable.
> 
> Its to do with having been involved with -rt. RT wants to do
> accountability for such things because of PI and sorts.

Also, real people really do care about latency too, very bad worst case
spikes to upset things.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-06  8:21         ` Peter Zijlstra
@ 2016-01-06 11:24           ` One Thousand Gnomes
  2016-01-08 22:44             ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: One Thousand Gnomes @ 2016-01-06 11:24 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: ling.ma.program, waiman.long, mingo, linux-kernel, akpm, ling.ml

On Wed, 6 Jan 2016 09:21:06 +0100
Peter Zijlstra <peterz@infradead.org> wrote:

> On Wed, Jan 06, 2016 at 09:16:43AM +0100, Peter Zijlstra wrote:
> > On Tue, Jan 05, 2016 at 09:42:27PM +0000, One Thousand Gnomes wrote:
> > > > It suffers the typical problems all those constructs do; namely it
> > > > wrecks accountability.
> > > 
> > > That's "government thinking" ;-) - for most real users throughput is
> > > more important than accountability. With the right API it ought to also
> > > be compile time switchable.
> > 
> > Its to do with having been involved with -rt. RT wants to do
> > accountability for such things because of PI and sorts.
> 
> Also, real people really do care about latency too, very bad worst case
> spikes to upset things.

Some yes - I'm familiar with the way some of the big financial number
crunching jobs need this. There are also people who instead care a lot
about throughput. Anything like this needs to end up with an external API
which looks the same whether the work is done via one thread or the other.

Alan

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-06 11:24           ` One Thousand Gnomes
@ 2016-01-08 22:44             ` Ling Ma
  2016-01-12 13:50               ` One Thousand Gnomes
  0 siblings, 1 reply; 716+ messages in thread
From: Ling Ma @ 2016-01-08 22:44 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: Peter Zijlstra, Waiman Long, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 1704 bytes --]

The attachment (alispinlock.tar.bz2) includes original spinlock and
alispinlock ,
we compare them on 70 cores based on kernel 4.3, the alispinlock can
improve performance upto 3x.

the link: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1035940.html
indicates when we introduce the idea for real application(user space
application  caused the bottle neck from  kernel spinlock )
the spinlock performance is improved by 1.9x (perf top -d1 also tell
us the spinlock cost time is reduced from 25% to 15%).

Appreciate your comments
Ling

2016-01-06 19:24 GMT+08:00 One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>:
> On Wed, 6 Jan 2016 09:21:06 +0100
> Peter Zijlstra <peterz@infradead.org> wrote:
>
>> On Wed, Jan 06, 2016 at 09:16:43AM +0100, Peter Zijlstra wrote:
>> > On Tue, Jan 05, 2016 at 09:42:27PM +0000, One Thousand Gnomes wrote:
>> > > > It suffers the typical problems all those constructs do; namely it
>> > > > wrecks accountability.
>> > >
>> > > That's "government thinking" ;-) - for most real users throughput is
>> > > more important than accountability. With the right API it ought to also
>> > > be compile time switchable.
>> >
>> > Its to do with having been involved with -rt. RT wants to do
>> > accountability for such things because of PI and sorts.
>>
>> Also, real people really do care about latency too, very bad worst case
>> spikes to upset things.
>
> Some yes - I'm familiar with the way some of the big financial number
> crunching jobs need this. There are also people who instead care a lot
> about throughput. Anything like this needs to end up with an external API
> which looks the same whether the work is done via one thread or the other.
>
> Alan

[-- Attachment #2: alispinlock.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 4529 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-05 18:46   ` Waiman Long
@ 2016-01-08 22:48     ` Ling Ma
  0 siblings, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-01-08 22:48 UTC (permalink / raw)
  To: Waiman Long; +Cc: Peter Zijlstra, mingo, linux-kernel, akpm, Ling

2016-01-06 2:46 GMT+08:00 Waiman Long <waiman.long@hpe.com>:
>
> On 12/31/2015 03:09 AM, ling.ma.program@gmail.com wrote:
>>
>> From: Ma Ling<ling.ml@alibaba-inc.com>
>>
>> Hi ALL,
>>
>> Wire-latency(RC delay) dominate modern computer performance,
>> conventional serialized works cause cache line ping-pong seriously,
>> the process spend lots of time and power to complete.
>> specially on multi-core platform.
>>
>> However if the serialized works are sent to one core and executed
>> when lock contention happens, that can save much time and power,
>> because all shared data are located in private cache of one core.
>> We call the mechanism as Acceleration from Lock Integration
>> (ali spinlock)
>>

> You should include additional patches that illustrate the possible use cases and performance improvement before and after the patches. This will allow the reviewers to actually try it out and play with it.
>
we have sent out in last email.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-05 21:18   ` Peter Zijlstra
  2016-01-05 21:42     ` One Thousand Gnomes
@ 2016-01-08 22:56     ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-01-08 22:56 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Waiman Long, mingo, linux-kernel, akpm, Ling

> So I have a whole bunch of problems with this thing.. For one I object
> to this being called a lock. Its much more like an async work queue like
> thing.
Ok, I will fix it.

> It suffers the typical problems all those constructs do; namely it
> wrecks accountability.
Ok, I will fix it.

> But here that is compounded by the fact that you inject other people's
> work into 'your' lock region, thereby bloating lock hold times. Worse,
> afaict (from a quick reading) there really isn't a bound on the amount
> of work you inject.
>
> This will completely wreck scheduling latency. At the very least the
> callback loop should have a need_resched() test on, but even that will
> not work if this has IRQs disabled.
>
>
> And while its a cute collapse of an MCS lock and lockless list style
> work queue (MCS after all is a lockless list), saving a few cycles from
> the naive spinlock+llist implementation of the same thing, I really
> do not see enough justification for any of this.
we can fix it if we really don't need it.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-05 21:42     ` One Thousand Gnomes
  2016-01-06  8:16       ` Peter Zijlstra
@ 2016-01-08 23:01       ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-01-08 23:01 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: Peter Zijlstra, Waiman Long, mingo, linux-kernel, akpm, Ling

> The claim in the original post is 3x performance but doesn't explain
> performance doing what, or which kernel locks were switched and what
> patches were used. I don't find the numbers hard to believe for a big big
> box, but I'd like to see the actual use case patches so it can be benched
> with other workloads and also for latency and the like.
>

We have sent out in email, please review and test it.

Thanks
Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-08 22:44             ` Ling Ma
@ 2016-01-12 13:50               ` One Thousand Gnomes
  2016-01-14  8:10                 ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: One Thousand Gnomes @ 2016-01-12 13:50 UTC (permalink / raw)
  To: Ling Ma; +Cc: Peter Zijlstra, Waiman Long, mingo, linux-kernel, akpm, Ling

On Sat, 9 Jan 2016 06:44:15 +0800
Ling Ma <ling.ma.program@gmail.com> wrote:

> The attachment (alispinlock.tar.bz2) includes original spinlock and
> alispinlock ,
> we compare them on 70 cores based on kernel 4.3, the alispinlock can
> improve performance upto 3x.
> 
> the link: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1035940.html
> indicates when we introduce the idea for real application(user space
> application  caused the bottle neck from  kernel spinlock )
> the spinlock performance is improved by 1.9x (perf top -d1 also tell
> us the spinlock cost time is reduced from 25% to 15%).
> 
> Appreciate your comments

So this has not been applied to actual real kernel locks (ie converted
some of the hot kernel locks to it) and then benchmarked with a real
world workload. This is just for the theoretical locking overhead ?

Alan

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-12 13:50               ` One Thousand Gnomes
@ 2016-01-14  8:10                 ` Ling Ma
  2016-01-19  8:52                   ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: Ling Ma @ 2016-01-14  8:10 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: Peter Zijlstra, Waiman Long, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 1662 bytes --]

Alan,

The attachment  (alispinlock.tar.bz2) in last email includes our
sample cases for spinlock.
The attachment (lock_test.tar.bz2) in this email includes the patch on
kernel 4.3v ,
which has been applied to actual real kernel locks:
when we run the user space program (thread.c) on 72cores E5-2699v3,
it cause many hot kernel spinlocks from __kmalloc and kfree  respectively
with original spinlock cpu cost 25% and  92715428576 cycles after
lock/unlock 1000000 times
with ali spinlock cpu cost 15% and  48475891244 cycles after
lock/unlock 1000000 times.
So we say in the real world workload the ali spinlock improve
performance by 1.9x
(92715428576 cycles/48475891244 cycles)

Thanks
Ling

the

2016-01-12 21:50 GMT+08:00 One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>:
> On Sat, 9 Jan 2016 06:44:15 +0800
> Ling Ma <ling.ma.program@gmail.com> wrote:
>
>> The attachment (alispinlock.tar.bz2) includes original spinlock and
>> alispinlock ,
>> we compare them on 70 cores based on kernel 4.3, the alispinlock can
>> improve performance upto 3x.
>>
>> the link: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1035940.html
>> indicates when we introduce the idea for real application(user space
>> application  caused the bottle neck from  kernel spinlock )
>> the spinlock performance is improved by 1.9x (perf top -d1 also tell
>> us the spinlock cost time is reduced from 25% to 15%).
>>
>> Appreciate your comments
>
> So this has not been applied to actual real kernel locks (ie converted
> some of the hot kernel locks to it) and then benchmarked with a real
> world workload. This is just for the theoretical locking overhead ?
>
> Alan

[-- Attachment #2: lock_test.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 7447 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-14  8:10                 ` Ling Ma
@ 2016-01-19  8:52                   ` Ling Ma
  2016-01-19 15:36                     ` Waiman Long
  0 siblings, 1 reply; 716+ messages in thread
From: Ling Ma @ 2016-01-19  8:52 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: Peter Zijlstra, Waiman Long, mingo, linux-kernel, akpm, Ling

Is it acceptable for performance improvement or more comments on this patch?

Thanks
Ling

2016-01-14 16:10 GMT+08:00 Ling Ma <ling.ma.program@gmail.com>:
> Alan,
>
> The attachment  (alispinlock.tar.bz2) in last email includes our
> sample cases for spinlock.
> The attachment (lock_test.tar.bz2) in this email includes the patch on
> kernel 4.3v ,
> which has been applied to actual real kernel locks:
> when we run the user space program (thread.c) on 72cores E5-2699v3,
> it cause many hot kernel spinlocks from __kmalloc and kfree  respectively
> with original spinlock cpu cost 25% and  92715428576 cycles after
> lock/unlock 1000000 times
> with ali spinlock cpu cost 15% and  48475891244 cycles after
> lock/unlock 1000000 times.
> So we say in the real world workload the ali spinlock improve
> performance by 1.9x
> (92715428576 cycles/48475891244 cycles)
>
> Thanks
> Ling
>
> the
>
> 2016-01-12 21:50 GMT+08:00 One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>:
>> On Sat, 9 Jan 2016 06:44:15 +0800
>> Ling Ma <ling.ma.program@gmail.com> wrote:
>>
>>> The attachment (alispinlock.tar.bz2) includes original spinlock and
>>> alispinlock ,
>>> we compare them on 70 cores based on kernel 4.3, the alispinlock can
>>> improve performance upto 3x.
>>>
>>> the link: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1035940.html
>>> indicates when we introduce the idea for real application(user space
>>> application  caused the bottle neck from  kernel spinlock )
>>> the spinlock performance is improved by 1.9x (perf top -d1 also tell
>>> us the spinlock cost time is reduced from 25% to 15%).
>>>
>>> Appreciate your comments
>>
>> So this has not been applied to actual real kernel locks (ie converted
>> some of the hot kernel locks to it) and then benchmarked with a real
>> world workload. This is just for the theoretical locking overhead ?
>>
>> Alan

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-19  8:52                   ` Ling Ma
@ 2016-01-19 15:36                     ` Waiman Long
  2016-02-03  4:40                       ` Ling Ma
  0 siblings, 1 reply; 716+ messages in thread
From: Waiman Long @ 2016-01-19 15:36 UTC (permalink / raw)
  To: Ling Ma
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

On 01/19/2016 03:52 AM, Ling Ma wrote:
> Is it acceptable for performance improvement or more comments on this patch?
>
> Thanks
> Ling
>
>

Your alispinlock patchset should also include a use case where the lock 
is used by some code within the kernel with test that can show a 
performance improvement so that the reviewers can independently try it 
out and play around with it. The kernel community will not accept any 
patch without a use case in the kernel.

Your lock_test.tar file is not good enough as it is not a performance 
test of the patch that you sent out.

Cheers,
Longman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-01-19 15:36                     ` Waiman Long
@ 2016-02-03  4:40                       ` Ling Ma
  2016-02-03  6:00                         ` Ling Ma
  2016-02-03 21:42                         ` Waiman Long
  0 siblings, 2 replies; 716+ messages in thread
From: Ling Ma @ 2016-02-03  4:40 UTC (permalink / raw)
  To: Waiman Long
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 1329 bytes --]

Longman,

The attachment include user space code(thread.c), and kernel
patch(ali_work_queue.patch) based on 4.3.0-rc4,
we replaced all original spinlock (list_lock) in slab.h/c  with the
new mechanism.

The thread.c in user space caused lots of hot kernel spinlock from
__kmalloc and kfree,
perf top -d1 shows ~25%  before ali_work_queue.patch,after appending
this patch ,
the synchronous operation consumption from __kmalloc and kfree is
reduced from 25% to ~15% on Intel E5-2699V3
(we also observed the output from user space code (thread.c) is
improved clearly)

Peter, we will send the update version according to your comments.

Thanks
Ling


2016-01-19 23:36 GMT+08:00 Waiman Long <waiman.long@hpe.com>:
> On 01/19/2016 03:52 AM, Ling Ma wrote:
>>
>> Is it acceptable for performance improvement or more comments on this
>> patch?
>>
>> Thanks
>> Ling
>>
>>
>
> Your alispinlock patchset should also include a use case where the lock is
> used by some code within the kernel with test that can show a performance
> improvement so that the reviewers can independently try it out and play
> around with it. The kernel community will not accept any patch without a use
> case in the kernel.
>
> Your lock_test.tar file is not good enough as it is not a performance test
> of the patch that you sent out.
>
> Cheers,
> Longman

[-- Attachment #2: ali_work_queue.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 10512 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-02-03  4:40                       ` Ling Ma
@ 2016-02-03  6:00                         ` Ling Ma
  2016-02-03 21:42                         ` Waiman Long
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-02-03  6:00 UTC (permalink / raw)
  To: Waiman Long
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 2208 bytes --]

The attachment(thread.c) can tell us the new mechanism improve output
from  the user space code (thread,c) by 1.14x (1174810406/1026910602,
kernel spinlock consumption is reduced from 25% to 15%) as below:

  ORG         NEW
38186815 43644156
38340186 43121265
38383155 44087753
38567102 43532586
38027878 43622700
38011581 43396376
37861959 43322857
37963215 43375528
38039247 43618315
37989106 43406187
37916912 44163029
39053184 43138581
37928359 43247866
37967417 43390352
37909796 43218250
37727531 43256009
38032818 43460496
38001860 43536100
38019929 44231331
37846621 43550597
37823231 44229887
38108158 43142689
37771900 43228168
37652536 43901042
37649114 43172690
37591314 43380004
38539678 43435592

Total 1026910602 1174810406

Thanks
Ling

2016-02-03 12:40 GMT+08:00 Ling Ma <ling.ma.program@gmail.com>:
> Longman,
>
> The attachment include user space code(thread.c), and kernel
> patch(ali_work_queue.patch) based on 4.3.0-rc4,
> we replaced all original spinlock (list_lock) in slab.h/c  with the
> new mechanism.
>
> The thread.c in user space caused lots of hot kernel spinlock from
> __kmalloc and kfree,
> perf top -d1 shows ~25%  before ali_work_queue.patch,after appending
> this patch ,
> the synchronous operation consumption from __kmalloc and kfree is
> reduced from 25% to ~15% on Intel E5-2699V3
> (we also observed the output from user space code (thread.c) is
> improved clearly)
>
> Peter, we will send the update version according to your comments.
>
> Thanks
> Ling
>
>
> 2016-01-19 23:36 GMT+08:00 Waiman Long <waiman.long@hpe.com>:
>> On 01/19/2016 03:52 AM, Ling Ma wrote:
>>>
>>> Is it acceptable for performance improvement or more comments on this
>>> patch?
>>>
>>> Thanks
>>> Ling
>>>
>>>
>>
>> Your alispinlock patchset should also include a use case where the lock is
>> used by some code within the kernel with test that can show a performance
>> improvement so that the reviewers can independently try it out and play
>> around with it. The kernel community will not accept any patch without a use
>> case in the kernel.
>>
>> Your lock_test.tar file is not good enough as it is not a performance test
>> of the patch that you sent out.
>>
>> Cheers,
>> Longman

[-- Attachment #2: thread.c --]
[-- Type: text/x-csrc, Size: 2226 bytes --]

/**
	Test Case:
		OpenDir, Get status and close it.
*/
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

#define TEST_DIR "/tmp/thread"
#define MAX_TEST_THREAD (80)
#define MAX_TEST_FILE 5000

static unsigned long *result[MAX_TEST_THREAD];
static int stop = 0;

static void* case_function(void *para)
{
	int id = (int)(long)para;
	DIR *pDir;
	struct stat f_stat;
	struct dirent *entry=NULL;
	char path[256];
	char cmd[512];
	
	int filecnt       = 0;
	int dircnt        = 0;
	int filetotalsize = 0;
	unsigned long myresult = 0;
	int f = 0;
	
	result[id] = &myresult;

	/* Goto my path and construct empty file */
	sprintf(path, "%s/%d", TEST_DIR, id);
	printf("Creating temp file at %s....\n", path);

	sprintf(cmd, "mkdir %s", path);
	system(cmd);
	chdir(path);
	for (f = 0; f < MAX_TEST_FILE; f++)
	{
		char name[256];

		sprintf(name, "%s/%d", path, f);
		int t = open(name,  O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
		if (t != -1)
			close(t);
		else
		{
			printf("Errno = %d.\n", errno);
			exit(errno);
		}		
	}

again:
	if ((pDir = opendir(path)) == NULL)
	{
		printf("打开 %s 错误:没有那个文件或目录\n", TEST_DIR);
		goto err;
	}
	
	while ((entry = readdir(pDir)) != NULL)
	{
		struct stat buf;
		if (entry->d_name[0] == '.')
			continue;
		
		//f = open(entry->d_name, 0);
		f = stat(entry->d_name, &buf);
		
		if (f)
			close(f);
		myresult++;
		
		
		//printf("Filename %s, size %10d",entry->d_name, f_stat.st_size);
	}

	closedir(pDir);
	

	/* Need to stop */
	if (!stop)
		goto again;
	return 0;

err:
	;
}

void main()
{
	int i;
	pthread_t thread;

	system("mkdir "TEST_DIR);
		
	for (i = 0; i < MAX_TEST_THREAD; i++)
	{
		pthread_create(&thread, NULL, case_function, (void*)(long)i);
	}

	while (1)
	{
		sleep(1);
		unsigned long times = 0;
		//printf("Statistics:\n");

		for (i = 0; i < MAX_TEST_THREAD; i++)
		{
			//printf("%d\t", *result[i]);
			times =times +  *result[i];
		}
		printf("%ld\t\n", times);
		for (i = 0; i < MAX_TEST_THREAD; i++)
			*result[i] = 0;
	}
}

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-02-03  4:40                       ` Ling Ma
  2016-02-03  6:00                         ` Ling Ma
@ 2016-02-03 21:42                         ` Waiman Long
  2016-02-04  7:07                           ` Ling Ma
  2016-04-05  3:44                           ` Ling Ma
  1 sibling, 2 replies; 716+ messages in thread
From: Waiman Long @ 2016-02-03 21:42 UTC (permalink / raw)
  To: Ling Ma
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

On 02/02/2016 11:40 PM, Ling Ma wrote:
> Longman,
>
> The attachment include user space code(thread.c), and kernel
> patch(ali_work_queue.patch) based on 4.3.0-rc4,
> we replaced all original spinlock (list_lock) in slab.h/c  with the
> new mechanism.
>
> The thread.c in user space caused lots of hot kernel spinlock from
> __kmalloc and kfree,
> perf top -d1 shows ~25%  before ali_work_queue.patch,after appending
> this patch ,
> the synchronous operation consumption from __kmalloc and kfree is
> reduced from 25% to ~15% on Intel E5-2699V3
> (we also observed the output from user space code (thread.c) is
> improved clearly)

I have 2 major comments here. First of all, you should break up your 
patch into smaller ones. Large patch like the one in the tar ball is 
hard to review. Secondly, you are modifying over 1000 lines of code in 
mm/slab.c with some modest increase in performance. That can be hard to 
justify. Maybe you should find other use cases that involve less 
changes, but still have noticeable performance improvement. That will 
make it easier to be accepted.

Cheers,
Longman

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-02-03 21:42                         ` Waiman Long
@ 2016-02-04  7:07                           ` Ling Ma
  2016-04-05  3:44                           ` Ling Ma
  1 sibling, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-02-04  7:07 UTC (permalink / raw)
  To: Waiman Long
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 3516 bytes --]

> I have 2 major comments here. First of all, you should break up your patch
> into smaller ones. Large patch like the one in the tar ball is hard to
> review.

Ok, we will do it.

>Secondly, you are modifying over 1000 lines of code in mm/slab.c
> with some modest increase in performance. That can be hard to justify. Maybe
> you should find other use cases that involve less changes, but still have
> noticeable performance improvement. That will make it easier to be accepted.

In order to be justified the attachment in this letter include 3 files:

1. user space code (thread.c), which  can cause lots of hot kernel spinlock from
__kmalloc and kfree on multi-core platform

2. ali_work_queue.patch , the kernel patch for 4.3.0-rc4,
when we  run user space code (thread.c) based on the patch,
the synchronous operation consumption from __kmalloc and kfree is
about 15% on Intel E5-2699V3

3. org_spin_lock.patch, which is based on above ali_work_queue.patch,
when we  run user space code thread.c based on the patch,
the synchronous operation consumption from __kmalloc and kfree is
about 25% on Intel E5-2699V3


the main difference between ali_work_queue.patch and
org_spin_lock.patch as below:

diff --git a/mm/slab.h b/mm/slab.h
...
-   ali_spinlock_t list_lock;
+   spinlock_t list_lock;
...

diff --git a/mm/slab.c b/mm/slab.c
...
-   alispinlock(lock, &info);
+   spin_lock((spinlock_t *)lock);
+   fn(para);
+   spin_unlock((spinlock_t *)lock);
...

The above operations remove all performance noise from program modification.

We run  user space code thread.c with ali_work_queue.patch, and
org_spin_lock.patch respectively
 the output from thread.c as below:

ORG         NEW
38923684 43380604
38100464 44163011
37769241 43354266
37908638 43554022
37900994 43457066
38495073 43421394
37340217 43146352
38083979 43506951
37713263 43775215
37749871 43487289
37843224 43366055
38173823 43270225
38303612 43214675
37886717 44083950
37736455 43060728
37529307 44607597
38862690 43541484
37992824 44749925
38013454 43572225
37783135 45240502
37745372 44712540
38721413 43584658
38097842 43235392

            ORG            NEW
TOTAL 874675292 1005486126

So the data tell us the new mechanism can improve performance 14% (
1005486126/874675292) ,
and the operation can be justified fairly.

Thanks
Ling

2016-02-04 5:42 GMT+08:00 Waiman Long <waiman.long@hpe.com>:
> On 02/02/2016 11:40 PM, Ling Ma wrote:
>>
>> Longman,
>>
>> The attachment include user space code(thread.c), and kernel
>> patch(ali_work_queue.patch) based on 4.3.0-rc4,
>> we replaced all original spinlock (list_lock) in slab.h/c  with the
>> new mechanism.
>>
>> The thread.c in user space caused lots of hot kernel spinlock from
>> __kmalloc and kfree,
>> perf top -d1 shows ~25%  before ali_work_queue.patch,after appending
>> this patch ,
>> the synchronous operation consumption from __kmalloc and kfree is
>> reduced from 25% to ~15% on Intel E5-2699V3
>> (we also observed the output from user space code (thread.c) is
>> improved clearly)
>
>
> I have 2 major comments here. First of all, you should break up your patch
> into smaller ones. Large patch like the one in the tar ball is hard to
> review. Secondly, you are modifying over 1000 lines of code in mm/slab.c
> with some modest increase in performance. That can be hard to justify. Maybe
> you should find other use cases that involve less changes, but still have
> noticeable performance improvement. That will make it easier to be accepted.
>
> Cheers,
> Longman
>
>

[-- Attachment #2: ali_work_queue.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 10827 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-02-03 21:42                         ` Waiman Long
  2016-02-04  7:07                           ` Ling Ma
@ 2016-04-05  3:44                           ` Ling Ma
  2016-04-11  8:00                             ` Ling Ma
  1 sibling, 1 reply; 716+ messages in thread
From: Ling Ma @ 2016-04-05  3:44 UTC (permalink / raw)
  To: Waiman Long
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

[-- Attachment #1: Type: text/plain, Size: 916 bytes --]

Hi Longman,

> with some modest increase in performance. That can be hard to justify. Maybe
> you should find other use cases that involve less changes, but still have
> noticeable performance improvement. That will make it easier to be accepted.

The attachment is for other use case with the new lock optimization.
It include two files: main.c (user space workload),
fcntl-lock-opt.patch (kernel patch on 4.3.0-rc4 version)
(The hardware platform is on Intel E5 2699 V3, 72 threads (18core *2Socket *2HT)

1. when we run a.out from main.c on original 4.3.0-rc4 version,
the average throughput from a.out is 1887592( 98% cpu cost from perf top -d1)

2. when we run a.out from main.c with the fcntl-lock-opt.patch ,
the average throughput from a.out is 5277281 (91% cpu cost from perf top -d1)

So we say the new mechanism give us about 2.79x (5277281 / 1887592) improvement.

Appreciate your comments.

Thanks
Ling

[-- Attachment #2: test-lock.tar --]
[-- Type: application/x-tar, Size: 30720 bytes --]

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform
  2016-04-05  3:44                           ` Ling Ma
@ 2016-04-11  8:00                             ` Ling Ma
  0 siblings, 0 replies; 716+ messages in thread
From: Ling Ma @ 2016-04-11  8:00 UTC (permalink / raw)
  To: Waiman Long
  Cc: One Thousand Gnomes, Peter Zijlstra, mingo, linux-kernel, akpm, Ling

Is it acceptable for performance improvement or more comments on this patch?

Thanks
Ling

2016-04-05 11:44 GMT+08:00 Ling Ma <ling.ma.program@gmail.com>:
> Hi Longman,
>
>> with some modest increase in performance. That can be hard to justify. Maybe
>> you should find other use cases that involve less changes, but still have
>> noticeable performance improvement. That will make it easier to be accepted.
>
> The attachment is for other use case with the new lock optimization.
> It include two files: main.c (user space workload),
> fcntl-lock-opt.patch (kernel patch on 4.3.0-rc4 version)
> (The hardware platform is on Intel E5 2699 V3, 72 threads (18core *2Socket *2HT)
>
> 1. when we run a.out from main.c on original 4.3.0-rc4 version,
> the average throughput from a.out is 1887592( 98% cpu cost from perf top -d1)
>
> 2. when we run a.out from main.c with the fcntl-lock-opt.patch ,
> the average throughput from a.out is 5277281 (91% cpu cost from perf top -d1)
>
> So we say the new mechanism give us about 2.79x (5277281 / 1887592) improvement.
>
> Appreciate your comments.
>
> Thanks
> Ling

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH] doc: add meson ut enhancements in prog guide
       [not found] <yes>
                   ` (86 preceding siblings ...)
  2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
@ 2018-12-12 11:35 ` Hari Kumar Vemula
  2019-01-20 12:04   ` Thomas Monjalon
  2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
                   ` (3 subsequent siblings)
  91 siblings, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2018-12-12 11:35 UTC (permalink / raw)
  To: dev; +Cc: john.mcnamara, marko.kovacevic, reshma.pattan, Hari Kumar Vemula

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6296 bytes --]

Add a programmer's guide section for meson ut enhancements

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
 doc/guides/prog_guide/index.rst               |   1 +
 .../prog_guide/meson_ut_enhancements.rst      | 158 ++++++++++++++++++
 2 files changed, 159 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut_enhancements.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index ba8c1f6ad..41971e1cf 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -57,6 +57,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut_enhancements
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut_enhancements.rst b/doc/guides/prog_guide/meson_ut_enhancements.rst
new file mode 100644
index 000000000..328adda28
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut_enhancements.rst
@@ -0,0 +1,158 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2014-2018 Intel Corporation.
+
+.. _Meson_UT_Enhancements:
+
+Meson_UT_Enhancements
+=====================
+
+The meson build support for unit tests is now available and the more enhancements are done to the build system
+to classify unit tests under different categories. The build `test/test/meson.build` file has been
+modified for these enhancements. This document will further down describe the below list.
+
+*  Building and Running the unit tests.
+*  Grouping of testcases.
+*  Parallel and non parallel tests.
+*  Test suites.
+*  How to run different test suites.
+*  Support for skipped tests.
+
+
+Building and Running the unit tests
+-----------------------------------
+
+*  Create the meson build output folder using command.
+
+   ``$meson <build_dir>``
+
+*  Enter into build output folder, which was created by above command.
+
+   ``$cd build``
+
+*  Compile DPDK using `$ninja`.
+   The output file of the build will be available in meson build folder.
+   After successful ninja, binary `dpdk-test` is created in `build/test/test/`.
+
+*  Run the unit testcases.
+
+   ``$ninja test`` (or) ``$meson test``
+
+*  To rebuild the build directory, after any changes to meson.build.
+
+   ``$meson configure``
+
+*   To run specific test case via meson command.
+
+   ``$meson test <test case>`` (or) ``$ninja test <test case>``
+
+
+Grouping of testcases
+---------------------
+
+Testcases has been grouped into below four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+*  fast_parallel_test_names
+*  fast_non_parallel_test_names
+*  perf_test_names
+*  driver_test_names
+*  dump_test_names
+
+Parallel and non parallel tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Unless specified the meson will run all unit tests as parallel by default.
+So the test cases are categorized into parallel and non parallel tests purely
+based test case functionality using `is_parallel` argument of `test()`
+in meson.build. Test cases marked with `is_parallel : true` will run in
+parallel and tests marked with `is_parallel : false` will run in non-parallel.
+While non-parallel test is running, any other test should not be run.
+Parallel and non parallel test cases are grouped under the
+`fast_parallel_test_names` and `fast_non_parallel_test_names`.
+
+Test suites
+~~~~~~~~~~~
+
+Test groups are considered as "suite” in `meson.build` and can be provided
+as argument to `test()` as  `suite ‘project_name:label’`
+
+    Ex: ``suite ‘DPDK:fast-tests’``
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below are commands to run testcases using option `suite`
+
+*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`
+   are run under 10seconds and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:fast-tests``
+
+*  Test cases from the group `perf_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:perf-tests``
+
+*  Test cases from the group `driver_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:driver-tests``
+
+*  Test cases from the group `dump_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:dump-tests``
+
+
+Skipped testcases
+-----------------
+
+Some unit test cases have dependency on external libraries, driver modules or
+config flags, without which the test cases cannot be run, such test cases
+should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
+test cases run user should enable relevant dependencies. Below are the few
+current scenarios when test cases are skipped:
+
+#. External library dependency paths are not set.
+#. Config flag for the dependent library is not enabled.
+#. Dependent driver modules are not installed on the system.
+
+Dependent library paths can be set using below
+
+*  Single path ``export LIBRARY_PATH=path``
+
+*  Multiple paths ``export LIBRARY_PATH=path1:path2:path3``
+
+Dependent library headers path can be exported as below.
+
+*  Single path ``$CFLAGS=-I/path meson build``
+
+*  Multiple paths ``$CFLAGS=-I/path1 -I/path2 meson build``
+
+Below examples shows how to export libraries and their header paths.
+
+To export single library at a time.
+
+        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/``
+        ``$CFLAGS=-I/root/wireless_libs/zuc/include meson build``
+
+To export multiple libraries at a time.
+
+        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
+                                                    ``libsso_kasumi/build/``
+        ``$CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
+                                        ``libsso_kasumi/include meson build``
+
+
+
+Commands to run meson UTs
+-------------------------
+
+*   To run all test cases
+       ``$meson test``
+*   To run specific test
+       ``$meson test testcase_name``
+        Ex:``$meson test acl_autotest``
+*   To run specific test suite
+       ``$meson test --suite DPDK:suite_name``
+        Ex:``$meson test --suite DPDK:fast-tests``
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2] eal: fix core number validation
       [not found] <yes>
                   ` (87 preceding siblings ...)
  2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
@ 2019-01-03 12:28 ` Hari kumar Vemula
  2019-01-03 13:03   ` David Marchand
                     ` (3 more replies)
  2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
                   ` (2 subsequent siblings)
  91 siblings, 4 replies; 716+ messages in thread
From: Hari kumar Vemula @ 2019-01-03 12:28 UTC (permalink / raw)
  To: dev
  Cc: stable, reshma.pattan, ferruh.yigit, david.marchand,
	jananeex.m.parthasarathy, Hari kumar Vemula

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

--
v2: Replace strtoul with strtol
    Modified log message
--

Signed-off-by: Hari kumar Vemula <hari.kumarx.vemula@intel.com>
---
 lib/librte_eal/common/eal_common_options.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..b24668c23 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,7 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -603,6 +603,11 @@ eal_parse_corelist(const char *corelist)
 			max = idx;
 			if (min == RTE_MAX_LCORE)
 				min = idx;
+			if ((unsigned int)idx >= cfg->lcore_count ||
+					(unsigned int)min >= cfg->lcore_count) {
+				return -1;
+			}
+
 			for (idx = min; idx <= max; idx++) {
 				if (cfg->lcore_role[idx] != ROLE_RTE) {
 					cfg->lcore_role[idx] = ROLE_RTE;
@@ -1103,6 +1108,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1151,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"Invalid core number given core range should be(0, %u)\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v2] eal: fix core number validation
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
@ 2019-01-03 13:03   ` David Marchand
  2019-01-07  7:05   ` Hari Kumar Vemula
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 716+ messages in thread
From: David Marchand @ 2019-01-03 13:03 UTC (permalink / raw)
  To: Hari kumar Vemula
  Cc: dev, stable, reshma.pattan, Yigit, Ferruh, jananeex.m.parthasarathy

On Thu, Jan 3, 2019 at 1:28 PM Hari kumar Vemula <
hari.kumarx.vemula@intel.com> wrote:

> When incorrect core value or range provided,
> as part of -l command line option, a crash occurs.
>
> Added valid range checks to fix the crash.
>
> Fixes: d888cb8b9613 ("eal: add core list input format")
> Cc: stable@dpdk.org
>
> --
> v2: Replace strtoul with strtol
>     Modified log message
>

You did not take my other comments into account and the ut updates are
missing.


-- 
David Marchand

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2] eal: fix core number validation
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
  2019-01-03 13:03   ` David Marchand
@ 2019-01-07  7:05   ` Hari Kumar Vemula
  2019-01-07 10:25   ` [PATCH v3] " Hari Kumar Vemula
  2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
  3 siblings, 0 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-07  7:05 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, reshma.pattan, ferruh.yigit,
	jananeex.m.parthasarathy, Hari kumar Vemula, stable

From: Hari kumar Vemula <hari.kumarx.vemula@intel.com>

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Added ut check for negative core values.
Added unit test case for invalid core number range.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

Signed-off-by: Hari kumar Vemula <hari.kumarx.vemula@intel.com>
---
 lib/librte_eal/common/eal_common_options.c | 10 ++++++++--
 test/test/test_eal_flags.c                 | 14 +++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..4a900c548 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
+			if (idx < 0 || idx >= (int)cfg->lcore_count)
+				return -1;
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -603,6 +605,7 @@ eal_parse_corelist(const char *corelist)
 			max = idx;
 			if (min == RTE_MAX_LCORE)
 				min = idx;
 			for (idx = min; idx <= max; idx++) {
 				if (cfg->lcore_role[idx] != ROLE_RTE) {
 					cfg->lcore_role[idx] = ROLE_RTE;
@@ -1103,6 +1106,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1149,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"Invalid core number, core range should be (0, %u)\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 2acab9d69..ec79b2242 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -513,6 +513,16 @@ test_missing_c_flag(void)
 	const char *argv25[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores",
 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
+	/* when core number is negative value*/
+	const char * const argv26[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5" };
+	const char * const argv27[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5-7" };
+	/* when core number is maximum value*/
+	const char * const argv28[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "999999999" };
+	const char * const argv29[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "1-9999999" };
 
 	if (launch_proc(argv2) != 0) {
 		printf("Error - "
@@ -556,7 +566,9 @@ test_missing_c_flag(void)
 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
 	    launch_proc(argv21) == 0 || launch_proc(argv22) == 0 ||
-	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0) {
+	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0 ||
+	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
+	    launch_proc(argv28) == 0 || launch_proc(argv29) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid --lcore flag\n");
 		return -1;
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v3] eal: fix core number validation
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
  2019-01-03 13:03   ` David Marchand
  2019-01-07  7:05   ` Hari Kumar Vemula
@ 2019-01-07 10:25   ` Hari Kumar Vemula
  2019-01-10 10:11     ` David Marchand
  2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
  3 siblings, 1 reply; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-07 10:25 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, reshma.pattan, ferruh.yigit,
	jananeex.m.parthasarathy, Hari Kumar Vemula, stable

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Added ut check for negative core values.
Added unit test case for invalid core number range.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

--
v3: Added unit test cases for invalid core number range
v2: Replace strtoul with strtol
    Modified log message
--

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
 lib/librte_eal/common/eal_common_options.c |  9 +++++++--
 test/test/test_eal_flags.c                 | 14 +++++++++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..9431c024e 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
+			if (idx < 0 || idx >= (int)cfg->lcore_count)
+				return -1;
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -1103,6 +1105,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1148,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"Invalid core number, core range should be (0, %u)\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 2acab9d69..28e68a6c9 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -513,6 +513,16 @@ test_missing_c_flag(void)
 	const char *argv25[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores",
 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
+	/* core number is negative value */
+	const char * const argv26[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5" };
+	const char * const argv27[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5-7" };
+	/* core number is maximum value */
+	const char * const argv28[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "999999999" };
+	const char * const argv29[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "1-9999999" };
 
 	if (launch_proc(argv2) != 0) {
 		printf("Error - "
@@ -556,7 +566,9 @@ test_missing_c_flag(void)
 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
 	    launch_proc(argv21) == 0 || launch_proc(argv22) == 0 ||
-	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0) {
+	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0 ||
+	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
+	    launch_proc(argv28) == 0 || launch_proc(argv29) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid --lcore flag\n");
 		return -1;
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH] net/bonding: fix create bonded device test failure
       [not found] <yes>
                   ` (88 preceding siblings ...)
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
@ 2019-01-07 13:01 ` Hari Kumar Vemula
  2019-01-07 18:44   ` Chas Williams
                     ` (2 more replies)
  2019-12-04  9:36 ` [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform Ani Sinha
       [not found] ` <20220630112644.3682066-1-Shreyas.Karmahe@toshiba-tsip.com>
  91 siblings, 3 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-07 13:01 UTC (permalink / raw)
  To: dev
  Cc: reshma.pattan, declan.doherty, jananeex.m.parthasarathy,
	Hari Kumar Vemula, stable

Create bonded device test is failing due to improper initialisation in
bonded device configuration. which leads to crash while setting up queues.

The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
bonded device which fails.
This is due to "rx_desc_lim" is set to 0 as default value of bonded device
during bond_alloc().
Hence nb_rx_desc (1024) is > 0 and test fails.

Fix is to set the default values of rx_desc_lim of bonded device to
appropriate value.

Fixes: 2efb58cbab ("bond: new link bonding library")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
 drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 44deaf119..e0888e960 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2225,6 +2225,11 @@ static void
 bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
 	struct bond_dev_private *internals = dev->data->dev_private;
+	struct rte_eth_desc_lim bond_lim = {
+		.nb_max = UINT16_MAX,
+		.nb_min = 0,
+		.nb_align = 1,
+	};
 
 	uint16_t max_nb_rx_queues = UINT16_MAX;
 	uint16_t max_nb_tx_queues = UINT16_MAX;
@@ -2263,10 +2268,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	memcpy(&dev_info->default_txconf, &internals->default_txconf,
 	       sizeof(dev_info->default_txconf));
 
-	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
-	       sizeof(dev_info->rx_desc_lim));
-	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
-	       sizeof(dev_info->tx_desc_lim));
+	dev_info->rx_desc_lim = bond_lim;
+	dev_info->tx_desc_lim = bond_lim;
 
 	/**
 	 * If dedicated hw queues enabled for link bonding device in LACP mode
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] net/bonding: fix create bonded device test failure
  2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
@ 2019-01-07 18:44   ` Chas Williams
  2019-01-08 10:27     ` [dpdk-stable] " Ferruh Yigit
  2019-01-08 11:14     ` Vemula, Hari KumarX
  2019-01-15 17:37   ` Pattan, Reshma
  2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
  2 siblings, 2 replies; 716+ messages in thread
From: Chas Williams @ 2019-01-07 18:44 UTC (permalink / raw)
  To: Hari Kumar Vemula, dev
  Cc: reshma.pattan, declan.doherty, jananeex.m.parthasarathy, stable



On 1/7/19 8:01 AM, Hari Kumar Vemula wrote:
> Create bonded device test is failing due to improper initialisation in
> bonded device configuration. which leads to crash while setting up queues.
> 
> The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
> bonded device which fails.
> This is due to "rx_desc_lim" is set to 0 as default value of bonded device
> during bond_alloc().
> Hence nb_rx_desc (1024) is > 0 and test fails.
> 
> Fix is to set the default values of rx_desc_lim of bonded device to
> appropriate value.

The default values for the bond device aren't known until the first
slave is added.  Can you explain your setup?  What PMD are you
using for testing?

> 
> Fixes: 2efb58cbab ("bond: new link bonding library")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
>   drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++----
>   1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 44deaf119..e0888e960 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -2225,6 +2225,11 @@ static void
>   bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>   {
>   	struct bond_dev_private *internals = dev->data->dev_private;
> +	struct rte_eth_desc_lim bond_lim = {
> +		.nb_max = UINT16_MAX,
> +		.nb_min = 0,
> +		.nb_align = 1,
> +	};
>   
>   	uint16_t max_nb_rx_queues = UINT16_MAX;
>   	uint16_t max_nb_tx_queues = UINT16_MAX;
> @@ -2263,10 +2268,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>   	memcpy(&dev_info->default_txconf, &internals->default_txconf,
>   	       sizeof(dev_info->default_txconf));
>   
> -	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
> -	       sizeof(dev_info->rx_desc_lim));
> -	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
> -	       sizeof(dev_info->tx_desc_lim));
> +	dev_info->rx_desc_lim = bond_lim;
> +	dev_info->tx_desc_lim = bond_lim;
>   
>   	/**
>   	 * If dedicated hw queues enabled for link bonding device in LACP mode
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-stable] [PATCH] net/bonding: fix create bonded device test failure
  2019-01-07 18:44   ` Chas Williams
@ 2019-01-08 10:27     ` Ferruh Yigit
  2019-01-08 11:14     ` Vemula, Hari KumarX
  1 sibling, 0 replies; 716+ messages in thread
From: Ferruh Yigit @ 2019-01-08 10:27 UTC (permalink / raw)
  To: Chas Williams, Hari Kumar Vemula, dev
  Cc: reshma.pattan, declan.doherty, jananeex.m.parthasarathy, stable

On 1/7/2019 6:44 PM, Chas Williams wrote:
> 
> 
> On 1/7/19 8:01 AM, Hari Kumar Vemula wrote:
>> Create bonded device test is failing due to improper initialisation in
>> bonded device configuration. which leads to crash while setting up queues.
>>
>> The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
>> bonded device which fails.
>> This is due to "rx_desc_lim" is set to 0 as default value of bonded device
>> during bond_alloc().
>> Hence nb_rx_desc (1024) is > 0 and test fails.
>>
>> Fix is to set the default values of rx_desc_lim of bonded device to
>> appropriate value.
> 
> The default values for the bond device aren't known until the first
> slave is added.  Can you explain your setup?  What PMD are you
> using for testing?

As far as I understand, 'rte_eth_rx_queue_setup()' is failing with bond eth
device since 'nb_rx_desc' should be less than 'dev_info.rx_desc_lim.nb_max' but
bonding sets 0 to 'nb_max'.

But not sure how to handle this from bonding point of view, this patch gives
most permissive values, but should bonding get these values from its slaves?

> 
>>
>> Fixes: 2efb58cbab ("bond: new link bonding library")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
>> ---
>>   drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++----
>>   1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
>> index 44deaf119..e0888e960 100644
>> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
>> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
>> @@ -2225,6 +2225,11 @@ static void
>>   bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>>   {
>>   	struct bond_dev_private *internals = dev->data->dev_private;
>> +	struct rte_eth_desc_lim bond_lim = {
>> +		.nb_max = UINT16_MAX,
>> +		.nb_min = 0,
>> +		.nb_align = 1,
>> +	};
>>   
>>   	uint16_t max_nb_rx_queues = UINT16_MAX;
>>   	uint16_t max_nb_tx_queues = UINT16_MAX;
>> @@ -2263,10 +2268,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>>   	memcpy(&dev_info->default_txconf, &internals->default_txconf,
>>   	       sizeof(dev_info->default_txconf));
>>   
>> -	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
>> -	       sizeof(dev_info->rx_desc_lim));
>> -	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
>> -	       sizeof(dev_info->tx_desc_lim));
>> +	dev_info->rx_desc_lim = bond_lim;
>> +	dev_info->tx_desc_lim = bond_lim;
>>   
>>   	/**
>>   	 * If dedicated hw queues enabled for link bonding device in LACP mode
>>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] net/bonding: fix create bonded device test failure
  2019-01-07 18:44   ` Chas Williams
  2019-01-08 10:27     ` [dpdk-stable] " Ferruh Yigit
@ 2019-01-08 11:14     ` Vemula, Hari KumarX
  1 sibling, 0 replies; 716+ messages in thread
From: Vemula, Hari KumarX @ 2019-01-08 11:14 UTC (permalink / raw)
  To: Chas Williams, dev
  Cc: Pattan, Reshma, Doherty, Declan, Parthasarathy, JananeeX M

Hi Williams,


> -----Original Message-----
> From: Chas Williams [mailto:3chas3@gmail.com]
> Sent: Tuesday, January 8, 2019 12:15 AM
> To: Vemula, Hari KumarX <hari.kumarx.vemula@intel.com>; dev@dpdk.org
> Cc: Pattan, Reshma <reshma.pattan@intel.com>; Doherty, Declan
> <declan.doherty@intel.com>; Parthasarathy, JananeeX M
> <jananeex.m.parthasarathy@intel.com>; stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH] net/bonding: fix create bonded device test
> failure
> 
> 
> 
> On 1/7/19 8:01 AM, Hari Kumar Vemula wrote:
> > Create bonded device test is failing due to improper initialisation in
> > bonded device configuration. which leads to crash while setting up queues.
> >
> > The value of nb_rx_desc is checked if it is not in range of
> > rx_desc_lim of bonded device which fails.
> > This is due to "rx_desc_lim" is set to 0 as default value of bonded
> > device during bond_alloc().
> > Hence nb_rx_desc (1024) is > 0 and test fails.
> >
> > Fix is to set the default values of rx_desc_lim of bonded device to
> > appropriate value.
> 
> The default values for the bond device aren't known until the first slave is
> added.  Can you explain your setup?  What PMD are you using for testing?
> 
We ran link_bonding_autotest in test application and was failing the test_create_bonded_device as in below log.
Slaves are added during test suite setup and then bonded device is created as per ut.

./x86_64-native-linuxapp-clang/app/test -n 1 -c f
RTE>>link_bonding_autotest

+ ------------------------------------------------------- +
 + Test Suite : Link Bonding Unit Test Suite
 + ------------------------------------------------------- +
Invalid value for nb_rx_desc(=1024), should be: <= 0, = 0, and a product of 0
 + TestCase [ 0] : test_create_bonded_device failed

> >
> > Fixes: 2efb58cbab ("bond: new link bonding library")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> > ---
> >   drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++----
> >   1 file changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c
> > b/drivers/net/bonding/rte_eth_bond_pmd.c
> > index 44deaf119..e0888e960 100644
> > --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> > +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> > @@ -2225,6 +2225,11 @@ static void
> >   bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info
> *dev_info)
> >   {
> >   	struct bond_dev_private *internals = dev->data->dev_private;
> > +	struct rte_eth_desc_lim bond_lim = {
> > +		.nb_max = UINT16_MAX,
> > +		.nb_min = 0,
> > +		.nb_align = 1,
> > +	};
> >
> >   	uint16_t max_nb_rx_queues = UINT16_MAX;
> >   	uint16_t max_nb_tx_queues = UINT16_MAX; @@ -2263,10 +2268,8
> @@
> > bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info
> *dev_info)
> >   	memcpy(&dev_info->default_txconf, &internals->default_txconf,
> >   	       sizeof(dev_info->default_txconf));
> >
> > -	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
> > -	       sizeof(dev_info->rx_desc_lim));
> > -	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
> > -	       sizeof(dev_info->tx_desc_lim));
> > +	dev_info->rx_desc_lim = bond_lim;
> > +	dev_info->tx_desc_lim = bond_lim;
> >
> >   	/**
> >   	 * If dedicated hw queues enabled for link bonding device in LACP
> > mode
> >


Thanks,
Hari.
--------------------------------------------------------------
Intel Research and Development Ireland Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263


This e-mail and any attachments may contain confidential material for the sole
use of the intended recipient(s). Any review or distribution by others is
strictly prohibited. If you are not the intended recipient, please contact the
sender and delete all copies.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v3] eal: fix core number validation
  2019-01-07 10:25   ` [PATCH v3] " Hari Kumar Vemula
@ 2019-01-10 10:11     ` David Marchand
  0 siblings, 0 replies; 716+ messages in thread
From: David Marchand @ 2019-01-10 10:11 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, reshma.pattan, Yigit, Ferruh, jananeex.m.parthasarathy, dpdk stable

Hello Hari,

On Mon, Jan 7, 2019 at 11:26 AM Hari Kumar Vemula <
hari.kumarx.vemula@intel.com> wrote:

> When incorrect core value or range provided,
> as part of -l command line option, a crash occurs.
>
> Added valid range checks to fix the crash.
>
> Added ut check for negative core values.
> Added unit test case for invalid core number range.
>
> Fixes: d888cb8b9613 ("eal: add core list input format")
> Cc: stable@dpdk.org
>
> --
> v3: Added unit test cases for invalid core number range
> v2: Replace strtoul with strtol
>     Modified log message
> --
>
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
>  lib/librte_eal/common/eal_common_options.c |  9 +++++++--
>  test/test/test_eal_flags.c                 | 14 +++++++++++++-
>  2 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_common_options.c
> b/lib/librte_eal/common/eal_common_options.c
> index 6e3a83b98..9431c024e 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
>                 if (*corelist == '\0')
>                         return -1;
>                 errno = 0;
> -               idx = strtoul(corelist, &end, 10);
> +               idx = strtol(corelist, &end, 10);
> +                       if (idx < 0 || idx >= (int)cfg->lcore_count)
> +                               return -1;
>                 if (errno || end == NULL)
>                         return -1;
>                 while (isblank(*end))
>

Please fix indentation.


> @@ -1103,6 +1105,7 @@ eal_parse_common_option(int opt, const char *optarg,
>  {
>         static int b_used;
>         static int w_used;
> +       struct rte_config *cfg = rte_eal_get_configuration();
>
>         switch (opt) {
>         /* blacklist */
> @@ -1145,7 +1148,9 @@ eal_parse_common_option(int opt, const char *optarg,
>         /* corelist */
>         case 'l':
>                 if (eal_parse_corelist(optarg) < 0) {
> -                       RTE_LOG(ERR, EAL, "invalid core list\n");
> +                       RTE_LOG(ERR, EAL,
> +                               "Invalid core number, core range should be
> (0, %u)\n",
> +                                       cfg->lcore_count-1);
>                         return -1;
>                 }
>
>
eal_parse_corelist can error for both invalid core number but also for
incorrectly formatted input.
How about "invalid core list, please check core numbers are in [0, %u]
range" ?

diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
> index 2acab9d69..28e68a6c9 100644
> --- a/test/test/test_eal_flags.c
> +++ b/test/test/test_eal_flags.c
> @@ -513,6 +513,16 @@ test_missing_c_flag(void)
>         const char *argv25[] = { prgname, prefix, mp_flag,
>                                  "-n", "3", "--lcores",
>                                  "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
> +       /* core number is negative value */
> +       const char * const argv26[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "-5" };
> +       const char * const argv27[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "-5-7" };
>
+       /* core number is maximum value */
> +       const char * const argv28[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "999999999" };
> +       const char * const argv29[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "1-9999999" };
>

Well, the maximum value is not really "999999999".
Please check against RTE_MAX_LCORE.


-- 
David Marchand

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v4] eal: fix core number validation
  2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
                     ` (2 preceding siblings ...)
  2019-01-07 10:25   ` [PATCH v3] " Hari Kumar Vemula
@ 2019-01-11 14:15   ` Hari Kumar Vemula
  2019-01-11 15:06     ` David Marchand
                       ` (2 more replies)
  3 siblings, 3 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-11 14:15 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, ferruh.yigit, reshma.pattan,
	jananeex.m.parthasarathy, Hari Kumar Vemula, stable

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Added ut check for negative core values.
Added unit test case for invalid core number range.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
--
v4: Used RTE_MAX_LCORE for max core check
v3: Added unit test cases for invalid core number range
v2: Replace strtoul with strtol
    Modified log message
---
 lib/librte_eal/common/eal_common_options.c |  9 +++++++--
 test/test/test_eal_flags.c                 | 15 ++++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..14f40c62c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
+		if (idx < 0 || idx >= (int)cfg->lcore_count)
+			return -1;
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -1103,6 +1105,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1148,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"invalid core list, please check core numbers are in [0, %u] range\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 2acab9d69..fc45bf953 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -18,6 +18,7 @@
 #include <sys/file.h>
 #include <limits.h>
 
+#include <rte_per_lcore.h>
 #include <rte_debug.h>
 #include <rte_string_fns.h>
 
@@ -513,6 +514,16 @@ test_missing_c_flag(void)
 	const char *argv25[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores",
 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
+	/* core number is negative value */
+	const char * const argv26[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5" };
+	const char * const argv27[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "-5-7" };
+	/* core number is maximum value */
+	const char * const argv28[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "RTE_MAX_LCORE+1" };
+	const char * const argv29[] = { prgname, prefix, mp_flag,
+				"-n", "3", "--lcores", "1-(RTE_MAX_LCORE+1)" };
 
 	if (launch_proc(argv2) != 0) {
 		printf("Error - "
@@ -556,7 +567,9 @@ test_missing_c_flag(void)
 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
 	    launch_proc(argv21) == 0 || launch_proc(argv22) == 0 ||
-	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0) {
+	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0 ||
+	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
+	    launch_proc(argv28) == 0 || launch_proc(argv29) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid --lcore flag\n");
 		return -1;
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v4] eal: fix core number validation
  2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
@ 2019-01-11 15:06     ` David Marchand
  2019-01-14 10:28     ` [PATCH v5] " Hari Kumar Vemula
  2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
  2 siblings, 0 replies; 716+ messages in thread
From: David Marchand @ 2019-01-11 15:06 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, Yigit, Ferruh, reshma.pattan, jananeex.m.parthasarathy, dpdk stable

On Fri, Jan 11, 2019 at 3:15 PM Hari Kumar Vemula <
hari.kumarx.vemula@intel.com> wrote:

>
> diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
> index 2acab9d69..fc45bf953 100644
> --- a/test/test/test_eal_flags.c
> +++ b/test/test/test_eal_flags.c
> @@ -18,6 +18,7 @@
>  #include <sys/file.h>
>  #include <limits.h>
>
> +#include <rte_per_lcore.h>
>  #include <rte_debug.h>
>  #include <rte_string_fns.h>
>
> @@ -513,6 +514,16 @@ test_missing_c_flag(void)
>         const char *argv25[] = { prgname, prefix, mp_flag,
>                                  "-n", "3", "--lcores",
>                                  "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
>
+       /* core number is negative value */
> +       const char * const argv26[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "-5" };
> +       const char * const argv27[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "-5-7" };
>

I did not see this before, but you fixed the "-l" eal option, not
"--lcores" option.
So those unit tests are wrong.



> +       /* core number is maximum value */
> +       const char * const argv28[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores", "RTE_MAX_LCORE+1" };
> +       const char * const argv29[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "--lcores",
> "1-(RTE_MAX_LCORE+1)" };
>
>         if (launch_proc(argv2) != 0) {
>                 printf("Error - "
>

Passing "RTE_MAX_LCORE+1" is indeed wrong (be it with "-l" or "--lcores"
options), but I would still prefer to check the formatted value of
RTE_MAX_LCORE (no need for that +1, btw).
So please, in next version, test against "-l", RTE_STR(RTE_MAX_LCORE) and
"-l", "1-" RTE_STR(RTE_MAX_LCORE).


Thanks.

-- 
David Marchand

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v5] eal: fix core number validation
  2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
  2019-01-11 15:06     ` David Marchand
@ 2019-01-14 10:28     ` Hari Kumar Vemula
  2019-01-14 14:39       ` David Marchand
  2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
  2 siblings, 1 reply; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-14 10:28 UTC (permalink / raw)
  To: dev
  Cc: reshma.pattan, david.marchand, ferruh.yigit, Hari Kumar Vemula, stable

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Added ut check for negative core values.
Added unit test case for invalid core number range.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
--
v5: corrected unit test case for -l option
v4: Used RTE_MAX_LCORE for max core check
v3: Added unit test cases for invalid core number range
v2: Replace strtoul with strtol
    Modified log message
---
 lib/librte_eal/common/eal_common_options.c |  9 +++++++--
 test/test/test_eal_flags.c                 | 15 ++++++++++++++-
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..14f40c62c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
+		if (idx < 0 || idx >= (int)cfg->lcore_count)
+			return -1;
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -1103,6 +1105,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1148,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"invalid core list, please check core numbers are in [0, %u] range\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 2acab9d69..4dc22ec36 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -18,6 +18,7 @@
 #include <sys/file.h>
 #include <limits.h>
 
+#include <rte_per_lcore.h>
 #include <rte_debug.h>
 #include <rte_string_fns.h>
 
@@ -513,6 +514,16 @@ test_missing_c_flag(void)
 	const char *argv25[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores",
 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
+	/* core number is negative value */
+	const char * const argv26[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "-5" };
+	const char * const argv27[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "-5-7" };
+	/* core number is maximum value */
+	const char * const argv28[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) };
+	const char * const argv29[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "1-"RTE_STR(RTE_MAX_LCORE) };
 
 	if (launch_proc(argv2) != 0) {
 		printf("Error - "
@@ -556,7 +567,9 @@ test_missing_c_flag(void)
 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
 	    launch_proc(argv21) == 0 || launch_proc(argv22) == 0 ||
-	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0) {
+	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0 ||
+	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
+	    launch_proc(argv28) == 0 || launch_proc(argv29) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid --lcore flag\n");
 		return -1;
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v5] eal: fix core number validation
  2019-01-14 10:28     ` [PATCH v5] " Hari Kumar Vemula
@ 2019-01-14 14:39       ` David Marchand
  0 siblings, 0 replies; 716+ messages in thread
From: David Marchand @ 2019-01-14 14:39 UTC (permalink / raw)
  To: Hari Kumar Vemula; +Cc: dev, reshma.pattan, Yigit, Ferruh, dpdk stable

On Mon, Jan 14, 2019 at 11:31 AM Hari Kumar Vemula <
hari.kumarx.vemula@intel.com> wrote:

> diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
> index 2acab9d69..4dc22ec36 100644
> --- a/test/test/test_eal_flags.c
> +++ b/test/test/test_eal_flags.c
> @@ -18,6 +18,7 @@
>  #include <sys/file.h>
>  #include <limits.h>
>
> +#include <rte_per_lcore.h>
>  #include <rte_debug.h>
>  #include <rte_string_fns.h>
>
> @@ -513,6 +514,16 @@ test_missing_c_flag(void)
>         const char *argv25[] = { prgname, prefix, mp_flag,
>                                  "-n", "3", "--lcores",
>                                  "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
> +       /* core number is negative value */
> +       const char * const argv26[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "-l", "-5" };
> +       const char * const argv27[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "-l", "-5-7" };
> +       /* core number is maximum value */
> +       const char * const argv28[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) };
> +       const char * const argv29[] = { prgname, prefix, mp_flag,
> +                               "-n", "3", "-l",
> "1-"RTE_STR(RTE_MAX_LCORE) };
>

Please move this block with the other "-l" options.
You can add my Reviewed-by tag with this.


Thanks.

-- 
David Marchand

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] net/bonding: fix create bonded device test failure
  2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
  2019-01-07 18:44   ` Chas Williams
@ 2019-01-15 17:37   ` Pattan, Reshma
  2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
  2 siblings, 0 replies; 716+ messages in thread
From: Pattan, Reshma @ 2019-01-15 17:37 UTC (permalink / raw)
  To: Vemula, Hari KumarX, Chas Williams, Doherty, Declan, dev
  Cc: Parthasarathy, JananeeX M, stable



> -----Original Message-----
> From: Vemula, Hari KumarX
> Sent: Monday, January 7, 2019 1:01 PM
> 
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
>  drivers/net/bonding/rte_eth_bond_pmd.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> -	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
> -	       sizeof(dev_info->rx_desc_lim));
> -	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
> -	       sizeof(dev_info->tx_desc_lim));
> +	dev_info->rx_desc_lim = bond_lim;
> +	dev_info->tx_desc_lim = bond_lim;


I relooked into this, these values should be filled from salve data like the way done for max_nb_rx_queues and max_nb_tx_queues
Existing code snippet:
if (slave_info.max_rx_queues < max_nb_rx_queues)
                          max_nb_rx_queues = slave_info.max_rx_queues;

 if (slave_info.max_tx_queues < max_nb_tx_queues)
                        max_nb_tx_queues = slave_info.max_tx_queues;

So, something like below you should add for rx/tx desc limit I guess.

if (slave_info.rx_desc_lim.nb_max < max_rx_desc_lim)
                                max_rx_desc_lim = slave_info.rx_desc_lim.nb_max;

if (slave_info.tx_desc_lim.nb_max < max_tx_desc_lim)
                                max_tx_desc_lim = slave_info.tx_desc_lim.nb_max;

dev_info->rx_desc_lim.nb_max = max_rx_desc_lim;
        dev_info->tx_desc_lim.nb_max = max_tx_desc_lim;

@Williams/Declan: Does this make sense?

Thanks,
Reshma

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v6] eal: fix core number validation
  2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
  2019-01-11 15:06     ` David Marchand
  2019-01-14 10:28     ` [PATCH v5] " Hari Kumar Vemula
@ 2019-01-17 12:13     ` Hari Kumar Vemula
  2019-01-17 12:19       ` Bruce Richardson
  2019-01-17 16:31       ` [dpdk-stable] " Thomas Monjalon
  2 siblings, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-17 12:13 UTC (permalink / raw)
  To: dev
  Cc: david.marchand, reshma.pattan, ferruh.yigit,
	jananeex.m.parthasarathy, Hari Kumar Vemula, stable

When incorrect core value or range provided,
as part of -l command line option, a crash occurs.

Added valid range checks to fix the crash.

Added ut check for negative core values.
Added unit test case for invalid core number range.

Fixes: d888cb8b9613 ("eal: add core list input format")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
--
v6: Changed testcase order
v5: Corrected unit test case for -l option
v4: Used RTE_MAX_LCORE for max core check
v3: Added unit test cases for invalid core number range
v2: Replace strtoul with strtol
    Modified log message
---
 lib/librte_eal/common/eal_common_options.c |  9 +++-
 test/test/test_eal_flags.c                 | 61 ++++++++++++++--------
 2 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6e3a83b98..14f40c62c 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -592,7 +592,9 @@ eal_parse_corelist(const char *corelist)
 		if (*corelist == '\0')
 			return -1;
 		errno = 0;
-		idx = strtoul(corelist, &end, 10);
+		idx = strtol(corelist, &end, 10);
+		if (idx < 0 || idx >= (int)cfg->lcore_count)
+			return -1;
 		if (errno || end == NULL)
 			return -1;
 		while (isblank(*end))
@@ -1103,6 +1105,7 @@ eal_parse_common_option(int opt, const char *optarg,
 {
 	static int b_used;
 	static int w_used;
+	struct rte_config *cfg = rte_eal_get_configuration();
 
 	switch (opt) {
 	/* blacklist */
@@ -1145,7 +1148,9 @@ eal_parse_common_option(int opt, const char *optarg,
 	/* corelist */
 	case 'l':
 		if (eal_parse_corelist(optarg) < 0) {
-			RTE_LOG(ERR, EAL, "invalid core list\n");
+			RTE_LOG(ERR, EAL,
+				"invalid core list, please check core numbers are in [0, %u] range\n",
+					cfg->lcore_count-1);
 			return -1;
 		}
 
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 2acab9d69..e3a60c7ae 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -18,6 +18,7 @@
 #include <sys/file.h>
 #include <limits.h>
 
+#include <rte_per_lcore.h>
 #include <rte_debug.h>
 #include <rte_string_fns.h>
 
@@ -477,40 +478,50 @@ test_missing_c_flag(void)
 				"-n", "3", "-l", "1," };
 	const char *argv10[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "-l", "1#2" };
+	/* core number is negative value */
+	const char * const argv11[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "-5" };
+	const char * const argv12[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "-5-7" };
+	/* core number is maximum value */
+	const char * const argv13[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) };
+	const char * const argv14[] = { prgname, prefix, mp_flag,
+				"-n", "3", "-l", "1-"RTE_STR(RTE_MAX_LCORE) };
 	/* sanity check test - valid corelist value */
-	const char *argv11[] = { prgname, prefix, mp_flag,
+	const char * const argv15[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "-l", "1-2,3" };
 
 	/* --lcores flag but no lcores value */
-	const char *argv12[] = { prgname, prefix, mp_flag,
+	const char * const argv16[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores" };
-	const char *argv13[] = { prgname, prefix, mp_flag,
+	const char * const argv17[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", " " };
 	/* bad lcores value */
-	const char *argv14[] = { prgname, prefix, mp_flag,
+	const char * const argv18[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "1-3-5" };
-	const char *argv15[] = { prgname, prefix, mp_flag,
+	const char * const argv19[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "0-1,,2" };
-	const char *argv16[] = { prgname, prefix, mp_flag,
+	const char * const argv20[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "0-,1" };
-	const char *argv17[] = { prgname, prefix, mp_flag,
+	const char * const argv21[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "(0-,2-4)" };
-	const char *argv18[] = { prgname, prefix, mp_flag,
+	const char * const argv22[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "(-1,2)" };
-	const char *argv19[] = { prgname, prefix, mp_flag,
+	const char * const argv23[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "(2-4)@(2-4-6)" };
-	const char *argv20[] = { prgname, prefix, mp_flag,
+	const char * const argv24[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "(a,2)" };
-	const char *argv21[] = { prgname, prefix, mp_flag,
+	const char * const argv25[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "1-3@(1,3)" };
-	const char *argv22[] = { prgname, prefix, mp_flag,
+	const char * const argv26[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "3@((1,3)" };
-	const char *argv23[] = { prgname, prefix, mp_flag,
+	const char * const argv27[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "(4-7)=(1,3)" };
-	const char *argv24[] = { prgname, prefix, mp_flag,
+	const char * const argv28[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores", "[4-7]@(1,3)" };
 	/* sanity check of tests - valid lcores value */
-	const char *argv25[] = { prgname, prefix, mp_flag,
+	const char * const argv29[] = { prgname, prefix, mp_flag,
 				 "-n", "3", "--lcores",
 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
 
@@ -538,31 +549,35 @@ test_missing_c_flag(void)
 			|| launch_proc(argv7) == 0
 			|| launch_proc(argv8) == 0
 			|| launch_proc(argv9) == 0
-			|| launch_proc(argv10) == 0) {
+			|| launch_proc(argv10) == 0
+			|| launch_proc(argv11) == 0
+			|| launch_proc(argv12) == 0
+			|| launch_proc(argv13) == 0
+			|| launch_proc(argv14) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid -l flag\n");
 		return -1;
 	}
-	if (launch_proc(argv11) != 0) {
+	if (launch_proc(argv15) != 0) {
 		printf("Error - "
 		       "process did not run ok with valid corelist value\n");
 		return -1;
 	}
 
 	/* start --lcores tests */
-	if (launch_proc(argv12) == 0 || launch_proc(argv13) == 0 ||
-	    launch_proc(argv14) == 0 || launch_proc(argv15) == 0 ||
-	    launch_proc(argv16) == 0 || launch_proc(argv17) == 0 ||
+	if (launch_proc(argv16) == 0 || launch_proc(argv17) == 0 ||
 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
-	    launch_proc(argv21) == 0 || launch_proc(argv22) == 0 ||
-	    launch_proc(argv23) == 0 || launch_proc(argv24) == 0) {
+	    launch_proc(argv22) == 0 || launch_proc(argv23) == 0 ||
+	    launch_proc(argv24) == 0 || launch_proc(argv25) == 0 ||
+	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
+	    launch_proc(argv28) == 0) {
 		printf("Error - "
 		       "process ran without error with invalid --lcore flag\n");
 		return -1;
 	}
 
-	if (launch_proc(argv25) != 0) {
+	if (launch_proc(argv29) != 0) {
 		printf("Error - "
 		       "process did not run ok with valid corelist value\n");
 		return -1;
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v6] eal: fix core number validation
  2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
@ 2019-01-17 12:19       ` Bruce Richardson
  2019-01-17 12:32         ` David Marchand
  2019-01-17 16:31       ` [dpdk-stable] " Thomas Monjalon
  1 sibling, 1 reply; 716+ messages in thread
From: Bruce Richardson @ 2019-01-17 12:19 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, david.marchand, reshma.pattan, ferruh.yigit,
	jananeex.m.parthasarathy, stable

On Thu, Jan 17, 2019 at 12:13:12PM +0000, Hari Kumar Vemula wrote:
> When incorrect core value or range provided,
> as part of -l command line option, a crash occurs.
> 
> Added valid range checks to fix the crash.
> 
> Added ut check for negative core values.
> Added unit test case for invalid core number range.
> 
> Fixes: d888cb8b9613 ("eal: add core list input format")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Reviewed-by: David Marchand <david.marchand@redhat.com>
> --
> v6: Changed testcase order
> v5: Corrected unit test case for -l option
> v4: Used RTE_MAX_LCORE for max core check
> v3: Added unit test cases for invalid core number range
> v2: Replace strtoul with strtol
>     Modified log message
> ---
>  lib/librte_eal/common/eal_common_options.c |  9 +++-
>  test/test/test_eal_flags.c                 | 61 ++++++++++++++--------
>  2 files changed, 45 insertions(+), 25 deletions(-)
> 
Is this patch related to, or does it fix Bugzilla #19?

https://bugs.dpdk.org/show_bug.cgi?id=19

/Bruce

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v6] eal: fix core number validation
  2019-01-17 12:19       ` Bruce Richardson
@ 2019-01-17 12:32         ` David Marchand
  0 siblings, 0 replies; 716+ messages in thread
From: David Marchand @ 2019-01-17 12:32 UTC (permalink / raw)
  To: Bruce Richardson
  Cc: Hari Kumar Vemula, dev, reshma.pattan, Yigit, Ferruh,
	jananeex.m.parthasarathy, dpdk stable

On Thu, Jan 17, 2019 at 1:19 PM Bruce Richardson <bruce.richardson@intel.com>
wrote:

> On Thu, Jan 17, 2019 at 12:13:12PM +0000, Hari Kumar Vemula wrote:
> > When incorrect core value or range provided,
> > as part of -l command line option, a crash occurs.
> >
> > Added valid range checks to fix the crash.
> >
> > Added ut check for negative core values.
> > Added unit test case for invalid core number range.
> >
> > Fixes: d888cb8b9613 ("eal: add core list input format")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> > Reviewed-by: David Marchand <david.marchand@redhat.com>
> > --
> > v6: Changed testcase order
> > v5: Corrected unit test case for -l option
> > v4: Used RTE_MAX_LCORE for max core check
> > v3: Added unit test cases for invalid core number range
> > v2: Replace strtoul with strtol
> >     Modified log message
> > ---
> >  lib/librte_eal/common/eal_common_options.c |  9 +++-
> >  test/test/test_eal_flags.c                 | 61 ++++++++++++++--------
> >  2 files changed, 45 insertions(+), 25 deletions(-)
> >
> Is this patch related to, or does it fix Bugzilla #19?
>
> https://bugs.dpdk.org/show_bug.cgi?id=19


Separate issue, from my pov.
I would say the issue happens with a dpdk process that has no cpu available
wrt CONFIG_RTE_MAX_CORES.
eal_auto_detect_cores() then removes all cores from cfg->lcore_role[], then
eal_adjust_config() an incorrect master lcore is chosen at
cfg->master_lcore = rte_get_next_lcore(-1, 0, 0); ?


-- 
David Marchand

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-stable] [PATCH v6] eal: fix core number validation
  2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
  2019-01-17 12:19       ` Bruce Richardson
@ 2019-01-17 16:31       ` Thomas Monjalon
  1 sibling, 0 replies; 716+ messages in thread
From: Thomas Monjalon @ 2019-01-17 16:31 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: stable, dev, david.marchand, reshma.pattan, ferruh.yigit,
	jananeex.m.parthasarathy

17/01/2019 13:13, Hari Kumar Vemula:
> When incorrect core value or range provided,
> as part of -l command line option, a crash occurs.
> 
> Added valid range checks to fix the crash.
> 
> Added ut check for negative core values.
> Added unit test case for invalid core number range.
> 
> Fixes: d888cb8b9613 ("eal: add core list input format")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Reviewed-by: David Marchand <david.marchand@redhat.com>

Applied, thanks

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH] doc: add meson ut enhancements in prog guide
  2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
@ 2019-01-20 12:04   ` Thomas Monjalon
  2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
  1 sibling, 0 replies; 716+ messages in thread
From: Thomas Monjalon @ 2019-01-20 12:04 UTC (permalink / raw)
  To: Hari Kumar Vemula; +Cc: dev, john.mcnamara, marko.kovacevic, reshma.pattan

12/12/2018 12:35, Hari Kumar Vemula:
> --- /dev/null
> +++ b/doc/guides/prog_guide/meson_ut_enhancements.rst
> @@ -0,0 +1,158 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +    Copyright(c) 2014-2018 Intel Corporation.
> +
> +.. _Meson_UT_Enhancements:

No need to add such anchor. The doc can be referred with :doc: syntax.

> +
> +Meson_UT_Enhancements
> +=====================

You should make a doc about how to run the tests with meson,
not how you improved it.
In short, please remove "enhancements" point of view.

> +
> +The meson build support for unit tests is now available and the more enhancements are done to the build system
> +to classify unit tests under different categories. The build `test/test/meson.build` file has been
> +modified for these enhancements. This document will further down describe the below list.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v2] doc: add meson ut info in prog guide
  2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
  2019-01-20 12:04   ` Thomas Monjalon
@ 2019-01-23  6:37   ` Hari Kumar Vemula
  2019-01-23 10:53     ` Bruce Richardson
  2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
  1 sibling, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-23  6:37 UTC (permalink / raw)
  To: dev
  Cc: john.mcnamara, reshma.pattan, marko.kovacevic,
	jananeex.m.parthasarathy, Hari Kumar Vemula

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6077 bytes --]

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
v2: Removed enhancement details
---
 doc/guides/prog_guide/index.rst    |   1 +
 doc/guides/prog_guide/meson_ut.rst | 164 +++++++++++++++++++++++++++++
 2 files changed, 165 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 6726b1e8d..f4274573f 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -58,6 +58,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..ab4adbbe8
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,164 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
+    Copyright(c) 2014-2018 Intel Corporation.
+
+.. _Meson:
+
+Meson_UT
+========
+
+The meson build for unit tests under different categories is supported using 'test/test/meson.build'.
+
+This document describes the below list in detail.
+
+*  Building and Running the unit tests.
+*  Grouping of testcases.
+*  Parallel and non parallel tests.
+*  Test suites.
+*  How to run different test suites.
+*  Support for skipped tests.
+
+
+
+Building and Running the unit tests
+-----------------------------------
+
+*  Create the meson build output folder using command.
+
+   ``$meson <build_dir>``
+
+*  Enter into build output folder, which was created by above command.
+
+   ``$cd build``
+
+*  Compile DPDK using `$ninja`.
+   The output file of the build will be available in meson build folder.
+   After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
+
+*  Run the unit testcases.
+
+   ``$ninja test`` (or) ``$meson test``
+
+*  To rebuild the build directory, after any changes to meson.build.
+
+   ``$meson configure``
+
+*   To run specific test case via meson command.
+
+   ``$meson test <test case>`` (or) ``$ninja test <test case>``
+
+
+
+Grouping of testcases
+---------------------
+
+Testcases has been grouped into below four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+*  fast_parallel_test_names
+*  fast_non_parallel_test_names
+*  perf_test_names
+*  driver_test_names
+*  dump_test_names
+
+Parallel and non parallel tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Unless specified the meson will run all unit tests as parallel by default.
+So the test cases are categorized into parallel and non parallel tests purely
+based on test case functionality using `is_parallel` argument of `test()`
+in meson.build. Test cases marked with `is_parallel : true` will run in
+parallel and tests marked with `is_parallel : false` will run in non-parallel.
+While non-parallel test is running, any other test should not be run.
+Parallel and non parallel test cases are grouped under the
+`fast_parallel_test_names` and `fast_non_parallel_test_names`.
+
+
+
+Test suites
+~~~~~~~~~~~
+
+Test groups are considered as "suite” in `meson.build` and can be provided
+as argument to `test()` as  `suite ‘project_name:label’`
+
+    Ex: ``suite ‘DPDK:fast-tests’``
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below are commands to run testcases using option `suite`
+
+*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`
+   are run under 10seconds and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:fast-tests``
+
+*  Test cases from the group `perf_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:perf-tests``
+
+*  Test cases from the group `driver_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:driver-tests``
+
+*  Test cases from the group `dump_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$meson test --suite DPDK:dump-tests``
+
+
+
+Skipped testcases
+-----------------
+
+Some unit test cases have dependency on external libraries, driver modules or
+config flags, without which the test cases cannot be run, such test cases
+should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
+test cases run user should enable relevant dependencies. Below are the few
+current scenarios when test cases are skipped:
+
+#. External library dependency paths are not set.
+#. Config flag for the dependent library is not enabled.
+#. Dependent driver modules are not installed on the system.
+
+Dependent library paths can be set using below
+
+*  Single path ``export LIBRARY_PATH=path``
+
+*  Multiple paths ``export LIBRARY_PATH=path1:path2:path3``
+
+Dependent library headers path can be exported as below.
+
+*  Single path ``$CFLAGS=-I/path meson build``
+
+*  Multiple paths ``$CFLAGS=-I/path1 -I/path2 meson build``
+
+Below examples shows how to export libraries and their header paths.
+
+To export single library at a time.
+
+        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/``
+        ``$CFLAGS=-I/root/wireless_libs/zuc/include meson build``
+
+To export multiple libraries at a time.
+
+        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
+                                                    ``libsso_kasumi/build/``
+        ``$CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
+                                        ``libsso_kasumi/include meson build``
+
+
+
+Commands to run meson UTs
+-------------------------
+
+*   To run all test cases
+       ``$meson test``
+*   To run specific test
+       ``$meson test testcase_name``
+        Ex:``$meson test acl_autotest``
+*   To run specific test suite
+       ``$meson test --suite DPDK:suite_name``
+        Ex:``$meson test --suite DPDK:fast-tests``
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v2] doc: add meson ut info in prog guide
  2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
@ 2019-01-23 10:53     ` Bruce Richardson
  2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
  1 sibling, 0 replies; 716+ messages in thread
From: Bruce Richardson @ 2019-01-23 10:53 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, john.mcnamara, reshma.pattan, marko.kovacevic,
	jananeex.m.parthasarathy

On Wed, Jan 23, 2019 at 06:37:07AM +0000, Hari Kumar Vemula wrote:
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
> v2: Removed enhancement details
> ---
>  doc/guides/prog_guide/index.rst    |   1 +
>  doc/guides/prog_guide/meson_ut.rst | 164 +++++++++++++++++++++++++++++
>  2 files changed, 165 insertions(+)
>  create mode 100644 doc/guides/prog_guide/meson_ut.rst
> 
> diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
> index 6726b1e8d..f4274573f 100644
> --- a/doc/guides/prog_guide/index.rst
> +++ b/doc/guides/prog_guide/index.rst
> @@ -58,6 +58,7 @@ Programmer's Guide
>      source_org
>      dev_kit_build_system
>      dev_kit_root_make_help
> +    meson_ut
>      extend_dpdk
>      build_app
>      ext_app_lib_make_help
> diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
> new file mode 100644
> index 000000000..ab4adbbe8
> --- /dev/null
> +++ b/doc/guides/prog_guide/meson_ut.rst
> @@ -0,0 +1,164 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +
> +    Copyright(c) 2014-2018 Intel Corporation.
> +
> +.. _Meson:
> +
> +Meson_UT
> +========
> +
> +The meson build for unit tests under different categories is supported using 'test/test/meson.build'.
> +
> +This document describes the below list in detail.
> +
> +*  Building and Running the unit tests.
> +*  Grouping of testcases.
> +*  Parallel and non parallel tests.
> +*  Test suites.
> +*  How to run different test suites.
> +*  Support for skipped tests.
> +
> +
> +
> +Building and Running the unit tests
> +-----------------------------------
> +
> +*  Create the meson build output folder using command.
> +
> +   ``$meson <build_dir>``

Here and with the commands below, leave a space between the '$' and the
command to show that it's the prompt and not the variable '$meson'

> +
> +*  Enter into build output folder, which was created by above command.
> +
> +   ``$cd build``
> +
> +*  Compile DPDK using `$ninja`.
> +   The output file of the build will be available in meson build folder.
> +   After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
> +
> +*  Run the unit testcases.
> +
> +   ``$ninja test`` (or) ``$meson test``
> +
> +*  To rebuild the build directory, after any changes to meson.build.
> +
> +   ``$meson configure``
> +

This should not be necesary. If you make any changes to meson.build then
ninja will automatically detect that and call meson to reconfigure itself
automatically.

Also, I don't think the rebuilding of the software is within the scope of
the section of the document. I'd omit the whole bullet point.

> +*   To run specific test case via meson command.
> +
> +   ``$meson test <test case>`` (or) ``$ninja test <test case>``
> +
> +
> +
> +Grouping of testcases
> +---------------------
> +
> +Testcases has been grouped into below four different groups based on conditions
> +of time duration and performance of the individual testcase.
> +
> +*  fast_parallel_test_names
> +*  fast_non_parallel_test_names
> +*  perf_test_names
> +*  driver_test_names
> +*  dump_test_names
> +
> +Parallel and non parallel tests
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Unless specified the meson will run all unit tests as parallel by default.

"meson" rather than "the meson" sounds better. Comma needed after
"specified". I'd also look to shorten the next sentence and merge it with
the one above, which sounds incomplete.

> +So the test cases are categorized into parallel and non parallel tests purely
> +based on test case functionality using `is_parallel` argument of `test()`
> +in meson.build. Test cases marked with `is_parallel : true` will run in
> +parallel and tests marked with `is_parallel : false` will run in non-parallel.
> +While non-parallel test is running, any other test should not be run.

"any other test should not be run" -> "no other tests should run".

> +Parallel and non parallel test cases are grouped under the
> +`fast_parallel_test_names` and `fast_non_parallel_test_names`.
> +
> +
> +
> +Test suites
> +~~~~~~~~~~~
> +
> +Test groups are considered as "suite??? in `meson.build` and can be provided
> +as argument to `test()` as  `suite ???project_name:label???`
> +
> +    Ex: ``suite ???DPDK:fast-tests???``

Watch out for the use of smart-quotes in the text above. Regular single and
double quotes are recommended.

When passing a suite to the meson to run, you use "--suite", so please
include the "--" prefix to avoid confusion.

> +
> +Running different test suites
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Below are commands to run testcases using option `suite`
> +
> +*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`
> +   are run under 10seconds and below is the meson command to run them.
> +
> +   ``$meson test --suite DPDK:fast-tests``
> +
> +*  Test cases from the group `perf_test_names` are run under 600 seconds
> +   and below is the meson command to run them.
> +
> +   ``$meson test --suite DPDK:perf-tests``
> +
> +*  Test cases from the group `driver_test_names` are run under 600 seconds
> +   and below is the meson command to run them.
> +
> +   ``$meson test --suite DPDK:driver-tests``
> +
> +*  Test cases from the group `dump_test_names` are run under 600 seconds
> +   and below is the meson command to run them.
> +
> +   ``$meson test --suite DPDK:dump-tests``
> +
> +
> +
> +Skipped testcases
> +-----------------
> +
> +Some unit test cases have dependency on external libraries, driver modules or
> +config flags, without which the test cases cannot be run, such test cases

Break the sentence after "run".

> +should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
> +test cases run user should enable relevant dependencies. Below are the few
> +current scenarios when test cases are skipped:
> +
> +#. External library dependency paths are not set.
> +#. Config flag for the dependent library is not enabled.
> +#. Dependent driver modules are not installed on the system.
> +
> +Dependent library paths can be set using below
> +
> +*  Single path ``export LIBRARY_PATH=path``
> +
> +*  Multiple paths ``export LIBRARY_PATH=path1:path2:path3``
> +
> +Dependent library headers path can be exported as below.
> +
> +*  Single path ``$CFLAGS=-I/path meson build``
> +
> +*  Multiple paths ``$CFLAGS=-I/path1 -I/path2 meson build``
> +

Please be consistent with use of "export" or not. Also, consistently (or
not) using "$" for prompt would be good too.

> +Below examples shows how to export libraries and their header paths.
> +
> +To export single library at a time.
> +
> +        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/``
> +        ``$CFLAGS=-I/root/wireless_libs/zuc/include meson build``
> +
> +To export multiple libraries at a time.
> +
> +        ``$export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
> +                                                    ``libsso_kasumi/build/``
> +        ``$CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
> +                                        ``libsso_kasumi/include meson build``
> +
> +
> +
> +Commands to run meson UTs
> +-------------------------
> +

I'd suggest adding "Summary" into the title here - "Summary of Commands ..."

> +*   To run all test cases
> +       ``$meson test``
> +*   To run specific test
> +       ``$meson test testcase_name``
> +        Ex:``$meson test acl_autotest``
> +*   To run specific test suite
> +       ``$meson test --suite DPDK:suite_name``
> +        Ex:``$meson test --suite DPDK:fast-tests``
> -- 
> 2.17.2
>
Regards,
/Bruce 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v3] doc: add meson ut info in prog guide
  2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
  2019-01-23 10:53     ` Bruce Richardson
@ 2019-01-24 13:41     ` Hari Kumar Vemula
  2019-01-24 14:15       ` Richardson, Bruce
  2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
  1 sibling, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-24 13:41 UTC (permalink / raw)
  To: dev
  Cc: john.mcnamara, reshma.pattan, bruce.richardson, marko.kovacevic,
	jananeex.m.parthasarathy, Hari Kumar Vemula

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6031 bytes --]

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
v3: Modified
v2: Removed enhancement details
---
 doc/guides/prog_guide/index.rst    |   1 +
 doc/guides/prog_guide/meson_ut.rst | 159 +++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 6726b1e8d..f4274573f 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -58,6 +58,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..0e59f5526
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,159 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
+    Copyright(c) 2014-2018 Intel Corporation.
+
+.. _Meson:
+
+Meson_UT
+========
+
+The meson build for unit tests under different categories is supported using 'test/test/meson.build'.
+
+This document describes the below list in detail.
+
+*  Building and Running the unit tests.
+*  Grouping of testcases.
+*  Parallel and non parallel tests.
+*  Test suites.
+*  How to run different test suites.
+*  Support for skipped tests.
+
+
+
+Building and Running the unit tests
+-----------------------------------
+
+*  Create the meson build output folder using command.
+
+   ``$ meson <build_dir>``
+
+*  Enter into build output folder, which was created by above command.
+
+   ``$ cd build``
+
+*  Compile DPDK using `$ ninja`.
+   The output file of the build will be available in meson build folder.
+   After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
+
+*  Run the unit testcases.
+
+   ``$ ninja test`` (or) ``$ meson test``
+
+*   To run specific test case via meson command.
+
+   ``$ meson test <test case>`` (or) ``$ ninja test <test case>``
+
+
+
+Grouping of testcases
+---------------------
+
+Testcases has been grouped into below four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+*  fast_parallel_test_names
+*  fast_non_parallel_test_names
+*  perf_test_names
+*  driver_test_names
+*  dump_test_names
+
+Parallel and non parallel tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, meson will run test cases in parallel. However `is_parallel` argument
+of `test()` in meson.build can be used to run tests in parallel or non-parallel
+mode based on its functionality. Test cases marked with `is_parallel : true` will
+run in parallel and tests marked with `is_parallel : false` will run in non-parallel.
+While non-parallel test is running, no other test should run.
+Parallel and non parallel test cases are grouped under the `fast_parallel_test_names`
+and `fast_non_parallel_test_names`.
+
+
+
+Test suites
+~~~~~~~~~~~
+
+Test groups are considered as `--suite` in `meson.build` and can be provided
+as argument to `test()` as  `--suite ‘project_name:label’`.
+
+    Ex: ``$ mesin test --suite ‘DPDK:fast-tests’``
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below are commands to run testcases using option `suite`
+
+*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`
+   are run under 10seconds and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:fast-tests``
+
+*  Test cases from the group `perf_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:perf-tests``
+
+*  Test cases from the group `driver_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:driver-tests``
+
+*  Test cases from the group `dump_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:dump-tests``
+
+
+
+Skipped testcases
+-----------------
+
+Some unit test cases have dependency on external libraries, driver modules or
+config flags, without which the test cases cannot be run. such test cases
+should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
+test cases run user should enable relevant dependencies. Below are the few
+current scenarios when test cases are skipped:
+
+#. External library dependency paths are not set.
+#. Config flag for the dependent library is not enabled.
+#. Dependent driver modules are not installed on the system.
+
+Dependent library paths can be set using below
+
+*  Single path ``$ export LIBRARY_PATH=path``
+
+*  Multiple paths ``$ export LIBRARY_PATH=path1:path2:path3``
+
+Dependent library headers path can be stated as part of meson build command as below.
+
+*  Single path ``$ CFLAGS=-I/path meson build``
+
+*  Multiple paths ``$ CFLAGS=-I/path1 -I/path2 meson build``
+
+Below examples shows how to export libraries and their header paths.
+
+To specify single library at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include meson build``
+
+To specify multiple libraries at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
+                                                    ``libsso_kasumi/build/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
+                                        ``libsso_kasumi/include meson build``
+
+
+
+Summery of Commands to run meson UTs
+------------------------------------
+
+*   To run all test cases
+       ``$ meson test``
+*   To run specific test
+       ``$ meson test testcase_name``
+        Ex:``$ meson test acl_autotest``
+*   To run specific test suite
+       ``$ meson test --suite DPDK:suite_name``
+        Ex:``$ meson test --suite DPDK:fast-tests``
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v3] doc: add meson ut info in prog guide
  2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
@ 2019-01-24 14:15       ` Richardson, Bruce
  2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
  1 sibling, 0 replies; 716+ messages in thread
From: Richardson, Bruce @ 2019-01-24 14:15 UTC (permalink / raw)
  To: Vemula, Hari KumarX, dev
  Cc: Mcnamara, John, Pattan, Reshma, Kovacevic, Marko, Parthasarathy,
	JananeeX M



> -----Original Message-----
> From: Vemula, Hari KumarX
> Sent: Thursday, January 24, 2019 1:42 PM
> To: dev@dpdk.org
> Cc: Mcnamara, John <john.mcnamara@intel.com>; Pattan, Reshma
> <reshma.pattan@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Kovacevic, Marko <marko.kovacevic@intel.com>; Parthasarathy, JananeeX M
> <jananeex.m.parthasarathy@intel.com>; Vemula, Hari KumarX
> <hari.kumarx.vemula@intel.com>
> Subject: [PATCH v3] doc: add meson ut info in prog guide
> 
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
> v3: Modified
> v2: Removed enhancement details
> ---

Some typos and suggested reworking below.

/Bruce

<snip>

> +
> +
> +Test suites
> +~~~~~~~~~~~
> +
> +Test groups are considered as `--suite` in `meson.build` and can be

"Tests are grouped into test suites in meson.build and these suite names can be"

> +provided as argument to `test()` as  `--suite ‘project_name:label’`.

"test()" => "meson test"

> +
> +    Ex: ``$ mesin test --suite ‘DPDK:fast-tests’``

mesin => meson

<snip>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v4] doc: add meson ut info in prog guide
  2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
  2019-01-24 14:15       ` Richardson, Bruce
@ 2019-01-25  6:20       ` Hari Kumar Vemula
  2019-01-31 14:49         ` Bruce Richardson
  2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
  1 sibling, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-25  6:20 UTC (permalink / raw)
  To: dev
  Cc: john.mcnamara, reshma.pattan, bruce.richardson, marko.kovacevic,
	jananeex.m.parthasarathy, Hari Kumar Vemula

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6065 bytes --]

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
v4: Typos corrected
v3: Modified
v2: Removed enhancement details
---
 doc/guides/prog_guide/index.rst    |   1 +
 doc/guides/prog_guide/meson_ut.rst | 159 +++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 6726b1e8d..f4274573f 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -58,6 +58,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..9485b1e63
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,159 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
+    Copyright(c) 2014-2018 Intel Corporation.
+
+.. _Meson:
+
+Meson_UT
+========
+
+The meson build for unit tests under different categories is supported using 'test/test/meson.build'.
+
+This document describes the below list in detail.
+
+*  Building and Running the unit tests.
+*  Grouping of testcases.
+*  Parallel and non parallel tests.
+*  Test suites.
+*  How to run different test suites.
+*  Support for skipped tests.
+
+
+
+Building and Running the unit tests
+-----------------------------------
+
+*  Create the meson build output folder using command.
+
+   ``$ meson <build_dir>``
+
+*  Enter into build output folder, which was created by above command.
+
+   ``$ cd build``
+
+*  Compile DPDK using `$ ninja`.
+   The output file of the build will be available in meson build folder.
+   After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
+
+*  Run the unit testcases.
+
+   ``$ ninja test`` (or) ``$ meson test``
+
+*   To run specific test case via meson command.
+
+   ``$ meson test <test case>`` (or) ``$ ninja test <test case>``
+
+
+
+Grouping of testcases
+---------------------
+
+Testcases has been grouped into below four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+*  fast_parallel_test_names
+*  fast_non_parallel_test_names
+*  perf_test_names
+*  driver_test_names
+*  dump_test_names
+
+Parallel and non parallel tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, meson will run test cases in parallel. However `is_parallel` argument
+of `test()` in meson.build can be used to run tests in parallel or non-parallel
+mode based on its functionality. Test cases marked with `is_parallel : true` will
+run in parallel and tests marked with `is_parallel : false` will run in non-parallel.
+While non-parallel test is running, no other test should run.
+Parallel and non parallel test cases are grouped under the `fast_parallel_test_names`
+and `fast_non_parallel_test_names`.
+
+
+
+Test suites
+~~~~~~~~~~~
+
+Tests are grouped into test suites in meson.build and these suite names can be provided
+as argument to `meson test` as `--suite ‘project_name:label’`.
+
+    Ex: ``$ meson test --suite ‘DPDK:fast-tests’``
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Below are commands to run testcases using option `suite`
+
+*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`
+   are run under 10seconds and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:fast-tests``
+
+*  Test cases from the group `perf_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:perf-tests``
+
+*  Test cases from the group `driver_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:driver-tests``
+
+*  Test cases from the group `dump_test_names` are run under 600 seconds
+   and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:dump-tests``
+
+
+
+Skipped testcases
+-----------------
+
+Some unit test cases have dependency on external libraries, driver modules or
+config flags, without which the test cases cannot be run. Such test cases
+should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
+test cases run user should enable relevant dependencies. Below are the few
+current scenarios when test cases are skipped:
+
+#. External library dependency paths are not set.
+#. Config flag for the dependent library is not enabled.
+#. Dependent driver modules are not installed on the system.
+
+Dependent library paths can be set using below
+
+*  Single path ``$ export LIBRARY_PATH=path``
+
+*  Multiple paths ``$ export LIBRARY_PATH=path1:path2:path3``
+
+Dependent library headers path can be stated as part of meson build command as below.
+
+*  Single path ``$ CFLAGS=-I/path meson build``
+
+*  Multiple paths ``$ CFLAGS=-I/path1 -I/path2 meson build``
+
+Below examples shows how to export libraries and their header paths.
+
+To specify single library at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include meson build``
+
+To specify multiple libraries at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
+                                                    ``libsso_kasumi/build/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
+                                        ``libsso_kasumi/include meson build``
+
+
+
+Summery of Commands to run meson UTs
+------------------------------------
+
+*   To run all test cases
+       ``$ meson test``
+*   To run specific test
+       ``$ meson test testcase_name``
+        Ex:``$ meson test acl_autotest``
+*   To run specific test suite
+       ``$ meson test --suite DPDK:suite_name``
+        Ex:``$ meson test --suite DPDK:fast-tests``
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v2] net/bonding: fix create bonded device test failure
  2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
  2019-01-07 18:44   ` Chas Williams
  2019-01-15 17:37   ` Pattan, Reshma
@ 2019-01-28  7:28   ` Hari Kumar Vemula
  2019-01-31 23:40     ` Chas Williams
  2019-02-05 13:39     ` [PATCH v3] " Hari Kumar Vemula
  2 siblings, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-01-28  7:28 UTC (permalink / raw)
  To: dev
  Cc: declan.doherty, reshma.pattan, jananeex.m.parthasarathy,
	Hari Kumar Vemula, stable

Create bonded device test is failing due to improper initialisation in
bonded device configuration. which leads to crash while setting up queues.

The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
bonded device which fails.
This is due to "rx_desc_lim" is set to 0 as default value of bonded device
during bond_alloc().
Hence nb_rx_desc (1024) is > 0 and test fails.

Fix is to set the default values of rx_desc_lim of bonded device to
appropriate value.

Fixes: 2efb58cbab6e ("bond: new link bonding library")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
v2: bonded device desc_lim values are received from slave configuration
---
 drivers/net/bonding/rte_eth_bond_pmd.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 44deaf119..23cec2549 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2228,6 +2228,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	uint16_t max_nb_rx_queues = UINT16_MAX;
 	uint16_t max_nb_tx_queues = UINT16_MAX;
+	uint16_t max_rx_desc_lim = UINT16_MAX;
+	uint16_t max_tx_desc_lim = UINT16_MAX;
 
 	dev_info->max_mac_addrs = BOND_MAX_MAC_ADDRS;
 
@@ -2252,6 +2254,12 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 			if (slave_info.max_tx_queues < max_nb_tx_queues)
 				max_nb_tx_queues = slave_info.max_tx_queues;
+
+			if (slave_info.rx_desc_lim.nb_max < max_rx_desc_lim)
+				max_rx_desc_lim = slave_info.rx_desc_lim.nb_max;
+
+			if (slave_info.tx_desc_lim.nb_max < max_tx_desc_lim)
+				max_tx_desc_lim = slave_info.tx_desc_lim.nb_max;
 		}
 	}
 
@@ -2263,10 +2271,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	memcpy(&dev_info->default_txconf, &internals->default_txconf,
 	       sizeof(dev_info->default_txconf));
 
-	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
-	       sizeof(dev_info->rx_desc_lim));
-	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
-	       sizeof(dev_info->tx_desc_lim));
+	dev_info->rx_desc_lim.nb_max = max_rx_desc_lim;
+	dev_info->tx_desc_lim.nb_max = max_tx_desc_lim;
 
 	/**
 	 * If dedicated hw queues enabled for link bonding device in LACP mode
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH v4] doc: add meson ut info in prog guide
  2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
@ 2019-01-31 14:49         ` Bruce Richardson
  2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
  1 sibling, 0 replies; 716+ messages in thread
From: Bruce Richardson @ 2019-01-31 14:49 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, john.mcnamara, reshma.pattan, marko.kovacevic,
	jananeex.m.parthasarathy

On Fri, Jan 25, 2019 at 06:20:51AM +0000, Hari Kumar Vemula wrote:
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> ---
> v4: Typos corrected
> v3: Modified
> v2: Removed enhancement details
> ---

Some sections I think need rewording to be written more from an end-user
rather than developer point of view, since this text is focused on running unit
tests rather than on writing them. Some additional spelling/grammar
corrections below also.

NOTE: Since this is in the programmers guide, maybe the intention is to
have it more at the programmer level. In which case, you need more info on
writing tests, and what return values should be used etc. other than
"TEST_SKIPPED", and can skip some of the detail on running tests.

Regards,
/Bruce

>  doc/guides/prog_guide/index.rst    |   1 +
>  doc/guides/prog_guide/meson_ut.rst | 159 +++++++++++++++++++++++++++++
>  2 files changed, 160 insertions(+)
>  create mode 100644 doc/guides/prog_guide/meson_ut.rst
> 
> diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
> index 6726b1e8d..f4274573f 100644
> --- a/doc/guides/prog_guide/index.rst
> +++ b/doc/guides/prog_guide/index.rst
> @@ -58,6 +58,7 @@ Programmer's Guide
>      source_org
>      dev_kit_build_system
>      dev_kit_root_make_help
> +    meson_ut
>      extend_dpdk
>      build_app
>      ext_app_lib_make_help
> diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
> new file mode 100644
> index 000000000..9485b1e63
> --- /dev/null
> +++ b/doc/guides/prog_guide/meson_ut.rst
> @@ -0,0 +1,159 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +
> +    Copyright(c) 2014-2018 Intel Corporation.

Should be just 2019, or 2018-2019, since this doc was not started in 2014.

> +
> +.. _Meson:
> +
> +Meson_UT
> +========
> +
> +The meson build for unit tests under different categories is supported using 'test/test/meson.build'.
> +
This line is not wrong, just probably unnecessary. Consider omitting it, I
think, since this doc is about using the unit tests rather than about the
source code layout or individual files.

> +This document describes the below list in detail.
> +
> +*  Building and Running the unit tests.
> +*  Grouping of testcases.
> +*  Parallel and non parallel tests.
> +*  Test suites.
Are test suites not the same as the grouping of test cases?

> +*  How to run different test suites.
> +*  Support for skipped tests.
> +
> +
> +
> +Building and Running the unit tests
> +-----------------------------------
> +
> +*  Create the meson build output folder using command.
> +
> +   ``$ meson <build_dir>``
> +
> +*  Enter into build output folder, which was created by above command.
> +
> +   ``$ cd build``
> +
> +*  Compile DPDK using `$ ninja`.

Like the other commands above, this should be put on its own line.

> +   The output file of the build will be available in meson build folder.
> +   After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
> +
> +*  Run the unit testcases.
> +
> +   ``$ ninja test`` (or) ``$ meson test``
> +
> +*   To run specific test case via meson command.
> +
> +   ``$ meson test <test case>`` (or) ``$ ninja test <test case>``
> +
> +
> +
> +Grouping of testcases
> +---------------------
> +
> +Testcases has been grouped into below four different groups based on conditions

has -> have.
Remove the word "below" as it's unnecessary.

> +of time duration and performance of the individual testcase.
> +
> +*  fast_parallel_test_names
> +*  fast_non_parallel_test_names
> +*  perf_test_names
> +*  driver_test_names
> +*  dump_test_names

Since you are listing the groups, I think you should just put the groups
without using the official variable names, which looks wrong and doesn't
add any info. Instead the list should be:

* fast tests which can be run in parallel
* fast tests which must run serially
* performance tests
* driver tests
* tests which produce lists of objects as output, and therefore that need manual checking

> +
> +Parallel and non parallel tests
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +By default, meson will run test cases in parallel. However `is_parallel` argument
> +of `test()` in meson.build can be used to run tests in parallel or non-parallel
> +mode based on its functionality. Test cases marked with `is_parallel : true` will
> +run in parallel and tests marked with `is_parallel : false` will run in non-parallel.
> +While non-parallel test is running, no other test should run.
> +Parallel and non parallel test cases are grouped under the `fast_parallel_test_names`
> +and `fast_non_parallel_test_names`.
> +

The above paragraph is too low level. It can probably be dropped or
abbreviated to a single sentence included in the previous section. Again,
this text seems targeted at users, not developers, so variable names in the
meson.build file are irrelevant.

> +
> +
> +Test suites
> +~~~~~~~~~~~
> +
> +Tests are grouped into test suites in meson.build and these suite names can be provided
> +as argument to `meson test` as `--suite ???project_name:label???`.
> +
> +    Ex: ``$ meson test --suite ???DPDK:fast-tests???``
> +
> +Running different test suites
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Below are commands to run testcases using option `suite`
> +
> +*  Test cases from the groups `fast_parallel_test_names` and `fast_non_parallel_test_names`

Again, drop the variable names. Not relevant for users.

> +   are run under 10seconds and below is the meson command to run them.

"are run under 10seconds" -> "should take less than 10 seconds"

> +
> +   ``$ meson test --suite DPDK:fast-tests``
> +
> +*  Test cases from the group `perf_test_names` are run under 600 seconds
> +   and below is the meson command to run them.
> +
> +   ``$ meson test --suite DPDK:perf-tests``
> +
> +*  Test cases from the group `driver_test_names` are run under 600 seconds
> +   and below is the meson command to run them.
> +
> +   ``$ meson test --suite DPDK:driver-tests``
> +
> +*  Test cases from the group `dump_test_names` are run under 600 seconds

Since these just output things, do they really need a 600 second timeout?
Do we even need to mention it?

> +   and below is the meson command to run them.
> +
> +   ``$ meson test --suite DPDK:dump-tests``
> +
> +
> +
> +Skipped testcases
> +-----------------
> +
> +Some unit test cases have dependency on external libraries, driver modules or

"have dependency" -> "have a dependency"

> +config flags, without which the test cases cannot be run. Such test cases
> +should return TEST_SKIPPED when mentioned dependencies are not enabled. To make
> +test cases run user should enable relevant dependencies. Below are the few
> +current scenarios when test cases are skipped:

Needs rewording for a more user-focused point of view, since TEST_SKIPPED
is an internal "magic number" in the code. Something like:
"Such test cases will be reported out as skipped if they cannot run. To
enable those test cases, the user should ensure the required dependencies
are met. Below are a few possible causes why tests may be skipped and how
they may be resolved:"

> +
> +#. External library dependency paths are not set.

The high-level problem is more that the library is not found, not that the
path is unset. The solution is to set the path to the dependency if
necessary.

> +#. Config flag for the dependent library is not enabled.
> +#. Dependent driver modules are not installed on the system.
> +
> +Dependent library paths can be set using below

"To help find missing libraries, the user can specify addition search paths
for those libraries as below:"

> +
> +*  Single path ``$ export LIBRARY_PATH=path``
> +
> +*  Multiple paths ``$ export LIBRARY_PATH=path1:path2:path3``
> +
> +Dependent library headers path can be stated as part of meson build command as below.

"Some functionality may be disabled due to library headers being missed as part of
the build. To specify an addition search path for headers at configuration
time, use one of the commands below:"

> +
> +*  Single path ``$ CFLAGS=-I/path meson build``
> +
> +*  Multiple paths ``$ CFLAGS=-I/path1 -I/path2 meson build``
> +
> +Below examples shows how to export libraries and their header paths.
> +
> +To specify single library at a time.
> +
> +        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/``
> +        ``$ CFLAGS=-I/root/wireless_libs/zuc/include meson build``
> +
> +To specify multiple libraries at a time.
> +
> +        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
> +                                                    ``libsso_kasumi/build/``
> +        ``$ CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
> +                                        ``libsso_kasumi/include meson build``
> +
> +
> +
> +Summery of Commands to run meson UTs

"Summary"

> +------------------------------------
> +
> +*   To run all test cases
> +       ``$ meson test``
> +*   To run specific test
> +       ``$ meson test testcase_name``
> +        Ex:``$ meson test acl_autotest``
> +*   To run specific test suite
> +       ``$ meson test --suite DPDK:suite_name``
> +        Ex:``$ meson test --suite DPDK:fast-tests``
> -- 
> 2.17.2
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v2] net/bonding: fix create bonded device test failure
  2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
@ 2019-01-31 23:40     ` Chas Williams
  2019-02-05 13:39     ` [PATCH v3] " Hari Kumar Vemula
  1 sibling, 0 replies; 716+ messages in thread
From: Chas Williams @ 2019-01-31 23:40 UTC (permalink / raw)
  To: Hari Kumar Vemula, dev
  Cc: declan.doherty, reshma.pattan, jananeex.m.parthasarathy, stable



On 1/28/19 2:28 AM, Hari Kumar Vemula wrote:
> Create bonded device test is failing due to improper initialisation in
> bonded device configuration. which leads to crash while setting up queues.
> 
> The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
> bonded device which fails.
> This is due to "rx_desc_lim" is set to 0 as default value of bonded device
> during bond_alloc().
> Hence nb_rx_desc (1024) is > 0 and test fails.
> 
> Fix is to set the default values of rx_desc_lim of bonded device to
> appropriate value.
> 
> Fixes: 2efb58cbab6e ("bond: new link bonding library")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>

Acked-by: Chas Williams <chas3@att.com>

> ---
> v2: bonded device desc_lim values are received from slave configuration
> ---
>   drivers/net/bonding/rte_eth_bond_pmd.c | 14 ++++++++++----
>   1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 44deaf119..23cec2549 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -2228,6 +2228,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>   
>   	uint16_t max_nb_rx_queues = UINT16_MAX;
>   	uint16_t max_nb_tx_queues = UINT16_MAX;
> +	uint16_t max_rx_desc_lim = UINT16_MAX;
> +	uint16_t max_tx_desc_lim = UINT16_MAX;
>   
>   	dev_info->max_mac_addrs = BOND_MAX_MAC_ADDRS;
>   
> @@ -2252,6 +2254,12 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>   
>   			if (slave_info.max_tx_queues < max_nb_tx_queues)
>   				max_nb_tx_queues = slave_info.max_tx_queues;
> +
> +			if (slave_info.rx_desc_lim.nb_max < max_rx_desc_lim)
> +				max_rx_desc_lim = slave_info.rx_desc_lim.nb_max;
> +
> +			if (slave_info.tx_desc_lim.nb_max < max_tx_desc_lim)
> +				max_tx_desc_lim = slave_info.tx_desc_lim.nb_max;
>   		}
>   	}
>   
> @@ -2263,10 +2271,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>   	memcpy(&dev_info->default_txconf, &internals->default_txconf,
>   	       sizeof(dev_info->default_txconf));
>   
> -	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
> -	       sizeof(dev_info->rx_desc_lim));
> -	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
> -	       sizeof(dev_info->tx_desc_lim));
> +	dev_info->rx_desc_lim.nb_max = max_rx_desc_lim;
> +	dev_info->tx_desc_lim.nb_max = max_tx_desc_lim;
>   
>   	/**
>   	 * If dedicated hw queues enabled for link bonding device in LACP mode
> 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [PATCH v5] doc: add meson ut info in prog guide
  2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
  2019-01-31 14:49         ` Bruce Richardson
@ 2019-02-02 10:28         ` Hari Kumar Vemula
  2019-03-04 17:05           ` Bruce Richardson
                             ` (2 more replies)
  1 sibling, 3 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-02-02 10:28 UTC (permalink / raw)
  To: dev
  Cc: john.mcnamara, reshma.pattan, marko.kovacevic, bruce.richardson,
	jananeex.m.parthasarathy, Hari Kumar Vemula

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 5371 bytes --]

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
---
v5: Modified
v4: Typos corrected
v3: Modified
v2: Removed enhancement details
---
 doc/guides/prog_guide/index.rst    |   1 +
 doc/guides/prog_guide/meson_ut.rst | 143 +++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 6726b1e8d..f4274573f 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -58,6 +58,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..e4b449049
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,143 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
+    Copyright(c) 2018-2019 Intel Corporation.
+
+.. _Meson:
+
+Meson_UT
+========
+
+This document describes the below list in detail.
+
+*  Building and Running the unit tests.
+*  Grouping of testcases.
+*  How to run different test suites.
+*  Support for skipped tests.
+
+
+
+Building and Running the unit tests
+-----------------------------------
+
+*  Create the meson build output folder using command.
+
+   ``$ meson <build_dir>``
+
+*  Enter into build output folder, which was created by above command.
+
+   ``$ cd build``
+
+*  Compile DPDK using command.
+
+  ``$ ninja``
+
+  The output file of the build will be available in meson build folder.
+  After successful ninja command, binary `dpdk-test` is created in `build/test/test/`.
+
+*  Run the unit testcases.
+
+   ``$ ninja test`` (or) ``$ meson test``
+
+*   To run specific test case via meson command.
+
+   ``$ meson test <test case>`` (or) ``$ ninja test <test case>``
+
+
+
+Grouping of testcases
+---------------------
+
+Testcases have been grouped into four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+*  fast tests which can be run in parallel
+*  fast tests which must run serially
+*  performance tests
+*  driver tests
+*  tests which produce lists of objects as output, and therefore that need manual checking
+
+Testcases can be run in parallel or non-parallel mode using the `is_parallel` argument
+of `test()` in meson.build
+
+These tests can be run using the argument to `meson test` as
+`--suite ‘project_name:label’`.
+
+    Ex: ``$ meson test --suite ‘DPDK:fast-tests’``
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Commands to run testcases using option `--suite`
+
+*  Fast Tests should take less than 10 seconds and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:fast-tests``
+
+*  Performance Tests should take less than 600 seconds and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:perf-tests``
+
+*  Driver Tests should take less than 600 seconds and below is the meson command to run them.
+
+   ``$ meson test --suite DPDK:driver-tests``
+
+*  Below is the meson command to run Dump Tests
+
+   ``$ meson test --suite DPDK:dump-tests``
+
+
+
+Skipped testcases
+-----------------
+
+Some unit test cases have a dependency on external libraries, driver modules or
+config flags, without which the test cases cannot be run. Such test cases will be reported
+out as skipped if they cannot run. To enable those test cases,
+the user should ensure the required dependencies are met.
+Below are a few possible causes why tests may be skipped and how they may be resolved:
+
+#. External library is not found.
+#. Config flag for the dependent library is not enabled.
+#. Dependent driver modules are not installed on the system.
+
+To help find missing libraries, the user can specify addition search paths
+for those libraries as below:
+
+*  Single path ``$ export LIBRARY_PATH=path``
+
+*  Multiple paths ``$ export LIBRARY_PATH=path1:path2:path3``
+
+Some functionality may be disabled due to library headers being missed as part of the build.
+To specify an addition search path for headers at configuration time, use one of the commands below:
+
+*  Single path ``$ CFLAGS=-I/path meson build``
+
+*  Multiple paths ``$ CFLAGS=-I/path1 -I/path2 meson build``
+
+Below examples shows how to export libraries and their header paths.
+
+To specify single library at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include meson build``
+
+To specify multiple libraries at a time.
+
+        ``$ export LIBRARY_PATH=/root/wireless_libs/zuc/:/root/wireless_libs/`` \
+                                                    ``libsso_kasumi/build/``
+        ``$ CFLAGS=-I/root/wireless_libs/zuc/include -I/root/wireless_libs/`` \
+                                        ``libsso_kasumi/include meson build``
+
+
+
+Summary
+--------
+
+*   To run all test cases
+       ``$ meson test``
+*   To run specific test
+       ``$ meson test testcase_name``
+        Ex:``$ meson test acl_autotest``
+*   To run specific test suite
+       ``$ meson test --suite DPDK:suite_name``
+        Ex:``$ meson test --suite DPDK:fast-tests``
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH v3] net/bonding: fix create bonded device test failure
  2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
  2019-01-31 23:40     ` Chas Williams
@ 2019-02-05 13:39     ` Hari Kumar Vemula
  2019-02-07 13:34       ` [dpdk-stable] " Ferruh Yigit
  1 sibling, 1 reply; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-02-05 13:39 UTC (permalink / raw)
  To: dev
  Cc: declan.doherty, reshma.pattan, radu.nicolau,
	jananeex.m.parthasarathy, Hari Kumar Vemula, stable

test_create_bonded_device is failing due to improper initialisation in
bonded device configuration. Which leads to crash while setting up queues.

The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
bonded device which fails.
This is due to "rx_desc_lim" is set to 0 as default value of bonded device
during bond_alloc().
Hence nb_rx_desc (1024) is > 0 and test fails.

Fix is to set the default values of rx_desc_lim of bonded device to
appropriate value.
Receive the values from slaves configuration like done for other existing
slave configuration

Fixes: 2efb58cbab6e ("bond: new link bonding library")
Cc: stable@dpdk.org

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
Acked-by: Chas Williams <chas3@att.com>
---
v3: Modified commit message
v2: Bonded device desc_lim values are received from slave configuration
---
 drivers/net/bonding/rte_eth_bond_pmd.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index 44deaf119..23cec2549 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -2228,6 +2228,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 	uint16_t max_nb_rx_queues = UINT16_MAX;
 	uint16_t max_nb_tx_queues = UINT16_MAX;
+	uint16_t max_rx_desc_lim = UINT16_MAX;
+	uint16_t max_tx_desc_lim = UINT16_MAX;
 
 	dev_info->max_mac_addrs = BOND_MAX_MAC_ADDRS;
 
@@ -2252,6 +2254,12 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 
 			if (slave_info.max_tx_queues < max_nb_tx_queues)
 				max_nb_tx_queues = slave_info.max_tx_queues;
+
+			if (slave_info.rx_desc_lim.nb_max < max_rx_desc_lim)
+				max_rx_desc_lim = slave_info.rx_desc_lim.nb_max;
+
+			if (slave_info.tx_desc_lim.nb_max < max_tx_desc_lim)
+				max_tx_desc_lim = slave_info.tx_desc_lim.nb_max;
 		}
 	}
 
@@ -2263,10 +2271,8 @@ bond_ethdev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	memcpy(&dev_info->default_txconf, &internals->default_txconf,
 	       sizeof(dev_info->default_txconf));
 
-	memcpy(&dev_info->rx_desc_lim, &internals->rx_desc_lim,
-	       sizeof(dev_info->rx_desc_lim));
-	memcpy(&dev_info->tx_desc_lim, &internals->tx_desc_lim,
-	       sizeof(dev_info->tx_desc_lim));
+	dev_info->rx_desc_lim.nb_max = max_rx_desc_lim;
+	dev_info->tx_desc_lim.nb_max = max_tx_desc_lim;
 
 	/**
 	 * If dedicated hw queues enabled for link bonding device in LACP mode
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [dpdk-stable] [PATCH v3] net/bonding: fix create bonded device test failure
  2019-02-05 13:39     ` [PATCH v3] " Hari Kumar Vemula
@ 2019-02-07 13:34       ` Ferruh Yigit
  0 siblings, 0 replies; 716+ messages in thread
From: Ferruh Yigit @ 2019-02-07 13:34 UTC (permalink / raw)
  To: Hari Kumar Vemula, dev
  Cc: declan.doherty, reshma.pattan, radu.nicolau,
	jananeex.m.parthasarathy, stable

On 2/5/2019 1:39 PM, Hari Kumar Vemula wrote:
> test_create_bonded_device is failing due to improper initialisation in
> bonded device configuration. Which leads to crash while setting up queues.
> 
> The value of nb_rx_desc is checked if it is not in range of rx_desc_lim of
> bonded device which fails.
> This is due to "rx_desc_lim" is set to 0 as default value of bonded device
> during bond_alloc().
> Hence nb_rx_desc (1024) is > 0 and test fails.
> 
> Fix is to set the default values of rx_desc_lim of bonded device to
> appropriate value.
> Receive the values from slaves configuration like done for other existing
> slave configuration
> 
> Fixes: 2efb58cbab6e ("bond: new link bonding library")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Acked-by: Chas Williams <chas3@att.com>

Applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [PATCH v5] doc: add meson ut info in prog guide
  2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
@ 2019-03-04 17:05           ` Bruce Richardson
  2019-04-22 22:35           ` [dpdk-dev] " Thomas Monjalon
  2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
  2 siblings, 0 replies; 716+ messages in thread
From: Bruce Richardson @ 2019-03-04 17:05 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, john.mcnamara, reshma.pattan, marko.kovacevic,
	jananeex.m.parthasarathy

On Sat, Feb 02, 2019 at 10:28:26AM +0000, Hari Kumar Vemula wrote:
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>

Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v5] doc: add meson ut info in prog guide
  2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
  2019-03-04 17:05           ` Bruce Richardson
@ 2019-04-22 22:35           ` Thomas Monjalon
  2019-05-01 11:39             ` Mcnamara, John
  2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
  2 siblings, 1 reply; 716+ messages in thread
From: Thomas Monjalon @ 2019-04-22 22:35 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, john.mcnamara, reshma.pattan, marko.kovacevic,
	bruce.richardson, jananeex.m.parthasarathy

02/02/2019 11:28, Hari Kumar Vemula:
> --- /dev/null
> +++ b/doc/guides/prog_guide/meson_ut.rst
> @@ -0,0 +1,143 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +
> +    Copyright(c) 2018-2019 Intel Corporation.

Why inserting a blank line between SPDX and Copyright.

> +
> +.. _Meson:
> +
> +Meson_UT
> +========

This is a title. Why having an underscore instead of space?
Why not saying Unit Tests? Or better, "Run Unit Tests with Meson".

> +
> +This document describes the below list in detail.
> +
> +*  Building and Running the unit tests.
> +*  Grouping of testcases.
> +*  How to run different test suites.
> +*  Support for skipped tests.

This list is useless because automatically generated by Sphinx.

Sorry, I stop reading here.
Marko, John, did you try to review this patch?




^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v5] doc: add meson ut info in prog guide
  2019-04-22 22:35           ` [dpdk-dev] " Thomas Monjalon
@ 2019-05-01 11:39             ` Mcnamara, John
  0 siblings, 0 replies; 716+ messages in thread
From: Mcnamara, John @ 2019-05-01 11:39 UTC (permalink / raw)
  To: Thomas Monjalon, Vemula, Hari KumarX
  Cc: dev, Pattan, Reshma, Kovacevic, Marko, Richardson, Bruce,
	Parthasarathy, JananeeX M



> > Sorry, I stop reading here.
> Marko, John, did you try to review this patch?

Yes. I will review offline.

John


^ permalink raw reply	[flat|nested] 716+ messages in thread

* [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
  2019-03-04 17:05           ` Bruce Richardson
  2019-04-22 22:35           ` [dpdk-dev] " Thomas Monjalon
@ 2019-06-06 11:59           ` Hari Kumar Vemula
  2019-07-08 19:40             ` Thomas Monjalon
  2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
  2 siblings, 2 replies; 716+ messages in thread
From: Hari Kumar Vemula @ 2019-06-06 11:59 UTC (permalink / raw)
  To: dev
  Cc: reshma.pattan, john.mcnamara, marko.kovacevic,
	jananeex.m.parthasarathy, Hari Kumar Vemula

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
v6: Updated comments
v5: Modified
v4: Typos corrected
v3: Modified
v2: Removed enhancement details
---
 doc/guides/prog_guide/index.rst    |   1 +
 doc/guides/prog_guide/meson_ut.rst | 151 +++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 692409af8..9465bc8e6 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -60,6 +60,7 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..e0aa15389
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,151 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+
+    Copyright(c) 2018-2019 Intel Corporation.
+
+.. _meson_unit_tests:
+
+Running DPDK Unit Tests with Meson
+==================================
+
+This section describes how to run testcases with the DPDK meson build system.
+
+
+Building and running the unit tests
+-----------------------------------
+
+* Create the meson build output folder using the following command::
+
+      $ meson <build_dir>
+
+* Enter into build output folder, which was created by above command::
+
+      $ cd build
+
+* Compile DPDK using command::
+
+      $ ninja
+
+The output file of the build will be available in meson build folder. After
+a successful ninja command, the binary ``dpdk-test`` is created in
+``build/test/test/``.
+
+* Run the unit testcases::
+
+      $ ninja test
+      # or
+      $ meson test
+
+* To run specific test case via meson::
+
+      $ meson test <test case>
+      # or
+      $ ninja test <test case>
+
+
+Grouping of testcases
+---------------------
+
+Testcases have been grouped into four different groups based on conditions
+of time duration and performance of the individual testcase.
+
+* Fast tests which can be run in parallel.
+* Fast tests which must run serially.
+* Performance tests.
+* Driver tests.
+* Tests which produce lists of objects as output, and therefore that need
+  manual checking.
+
+Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument
+of ``test()`` in meson.build
+
+These tests can be run using the argument to ``meson test`` as
+``--suite project_name:label``.
+
+For example::
+
+    $ meson test --suite DPDK:fast-tests
+
+
+The project name is optional so the following is equivalent to the previous
+command::
+
+
+    $ meson test --suite fast-tests
+
+
+Running different test suites
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following commands are some examples of how to run testcases using option
+``--suite``:
+
+* Fast Tests should take less than 10 seconds. The meson command to run them
+  is::
+
+      $ meson test --suite DPDK:fast-tests
+
+* Performance Tests should take less than 600 seconds. The meson command to
+  run them is::
+
+      $ meson test --suite DPDK:perf-tests
+
+* Driver Tests should take less than 600 seconds. The meson command to run
+  them is::
+
+      $ meson test --suite DPDK:driver-tests
+
+* The meson command to run Dump Tests is::
+
+      $ meson test --suite DPDK:dump-tests
+
+
+Dealing with skipped testcases
+------------------------------
+
+Some unit test cases have a dependency on external libraries, driver modules
+or config flags, without which the test cases cannot be run. Such test cases
+will be reported as skipped if they cannot run. To enable those test cases,
+the user should ensure the required dependencies are met.  Below are a few
+possible causes why tests may be skipped and how they may be resolved:
+
+#. Optional external libraries are not found.
+#. Config flags for the dependent library are not enabled.
+#. Dependent driver modules are not installed on the system.
+
+To help find missing libraries, the user can specify addition search paths
+for those libraries as below:
+
+* Single path::
+
+      $ export LIBRARY_PATH=path
+
+* Multiple paths::
+
+      $ export LIBRARY_PATH=path1:path2:path3
+
+Some functionality may be disabled due to library headers being missed as part
+of the build. To specify an additional search path for headers at
+configuration time, use one of the commands below:
+
+*  Single path::
+
+       $ CFLAGS=-I/path meson build
+
+*  Multiple paths::
+
+       $ CFLAGS=-I/path1 -I/path2 meson build
+
+Below are some examples that show how to export libraries and their header
+paths.
+
+To specify a single library at a time::
+
+    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
+    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
+
+To specify multiple libraries at a time::
+
+    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
+    $ CFLAGS=-I/path/zuc/include \
+             -I/path/libsso_kasumi/include \
+	     meson build
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
@ 2019-07-08 19:40             ` Thomas Monjalon
  2019-07-08 20:18               ` Aaron Conole
  2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
  1 sibling, 1 reply; 716+ messages in thread
From: Thomas Monjalon @ 2019-07-08 19:40 UTC (permalink / raw)
  To: Hari Kumar Vemula
  Cc: dev, reshma.pattan, john.mcnamara, marko.kovacevic,
	jananeex.m.parthasarathy, bruce.richardson, aconole,
	david.marchand

Hi please find some comments below:

06/06/2019 13:59, Hari Kumar Vemula:
> +++ b/doc/guides/prog_guide/meson_ut.rst
> @@ -0,0 +1,151 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +

Useless blank line.

> +    Copyright(c) 2018-2019 Intel Corporation.
> +
> +.. _meson_unit_tests:

Useless anchor. The doc can be referenced with :doc: links.

> +
> +Running DPDK Unit Tests with Meson
> +==================================
> +
> +This section describes how to run testcases with the DPDK meson build system.

Here and below, "testcases" should be split in two words.

> +
> +
> +Building and running the unit tests
> +-----------------------------------
> +
> +* Create the meson build output folder using the following command::
> +
> +      $ meson <build_dir>
> +
> +* Enter into build output folder, which was created by above command::
> +
> +      $ cd build

Should be the same as above: <build_dir>

> +
> +* Compile DPDK using command::
> +
> +      $ ninja

Do we really need to repeat above basic steps?
Would be easier to just reference another guide about meson.
I think doc/build-sdk-meson.txt should be moved to .rst.

> +
> +The output file of the build will be available in meson build folder. After
> +a successful ninja command, the binary ``dpdk-test`` is created in
> +``build/test/test/``.

Again, "build" is an example directory.

> +
> +* Run the unit testcases::
> +
> +      $ ninja test
> +      # or
> +      $ meson test
> +
> +* To run specific test case via meson::
> +
> +      $ meson test <test case>
> +      # or
> +      $ ninja test <test case>

Would be worth to mention why meson or ninja can be used.

> +
> +
> +Grouping of testcases
> +---------------------
> +
> +Testcases have been grouped into four different groups based on conditions
> +of time duration and performance of the individual testcase.

Grouping has changed recently.
This part should be updated please.

> +
> +* Fast tests which can be run in parallel.
> +* Fast tests which must run serially.
> +* Performance tests.
> +* Driver tests.
> +* Tests which produce lists of objects as output, and therefore that need
> +  manual checking.
> +
> +Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument
> +of ``test()`` in meson.build
> +
> +These tests can be run using the argument to ``meson test`` as
> +``--suite project_name:label``.
> +
> +For example::
> +
> +    $ meson test --suite DPDK:fast-tests
> +
> +
> +The project name is optional so the following is equivalent to the previous
> +command::
> +
> +
> +    $ meson test --suite fast-tests
> +
> +
> +Running different test suites
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The following commands are some examples of how to run testcases using option
> +``--suite``:
> +
> +* Fast Tests should take less than 10 seconds. The meson command to run them
> +  is::
> +
> +      $ meson test --suite DPDK:fast-tests
> +
> +* Performance Tests should take less than 600 seconds. The meson command to
> +  run them is::
> +
> +      $ meson test --suite DPDK:perf-tests
> +
> +* Driver Tests should take less than 600 seconds. The meson command to run
> +  them is::
> +
> +      $ meson test --suite DPDK:driver-tests
> +
> +* The meson command to run Dump Tests is::
> +
> +      $ meson test --suite DPDK:dump-tests

Would be simpler to just list the suites.

> +
> +
> +Dealing with skipped testcases
> +------------------------------
> +
> +Some unit test cases have a dependency on external libraries, driver modules
> +or config flags, without which the test cases cannot be run. Such test cases
> +will be reported as skipped if they cannot run. To enable those test cases,
> +the user should ensure the required dependencies are met.  Below are a few
> +possible causes why tests may be skipped and how they may be resolved:
> +
> +#. Optional external libraries are not found.
> +#. Config flags for the dependent library are not enabled.
> +#. Dependent driver modules are not installed on the system.
> +
> +To help find missing libraries, the user can specify addition search paths

addition -> additional ?

> +for those libraries as below:
> +
> +* Single path::
> +
> +      $ export LIBRARY_PATH=path
> +
> +* Multiple paths::
> +
> +      $ export LIBRARY_PATH=path1:path2:path3
> +
> +Some functionality may be disabled due to library headers being missed as part
> +of the build. To specify an additional search path for headers at
> +configuration time, use one of the commands below:
> +
> +*  Single path::
> +
> +       $ CFLAGS=-I/path meson build
> +
> +*  Multiple paths::
> +
> +       $ CFLAGS=-I/path1 -I/path2 meson build

Some quotes are missing to set multiple paths.

> +
> +Below are some examples that show how to export libraries and their header
> +paths.
> +
> +To specify a single library at a time::
> +
> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> +
> +To specify multiple libraries at a time::
> +
> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> +    $ CFLAGS=-I/path/zuc/include \
> +             -I/path/libsso_kasumi/include \
> +	     meson build

Why export is used for LIBRARY_PATH and not CFLAGS?
I think both variables can be exported or prepend the meson command?



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-08 19:40             ` Thomas Monjalon
@ 2019-07-08 20:18               ` Aaron Conole
  2019-07-09 18:57                 ` Michael Santana Francisco
  0 siblings, 1 reply; 716+ messages in thread
From: Aaron Conole @ 2019-07-08 20:18 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Hari Kumar Vemula, dev, reshma.pattan, john.mcnamara,
	marko.kovacevic, jananeex.m.parthasarathy, bruce.richardson,
	david.marchand

Thomas Monjalon <thomas@monjalon.net> writes:

> Hi please find some comments below:
>
> 06/06/2019 13:59, Hari Kumar Vemula:
>> +++ b/doc/guides/prog_guide/meson_ut.rst
>> @@ -0,0 +1,151 @@
>> +..  SPDX-License-Identifier: BSD-3-Clause
>> +
>
> Useless blank line.
>
>> +    Copyright(c) 2018-2019 Intel Corporation.
>> +
>> +.. _meson_unit_tests:
>
> Useless anchor. The doc can be referenced with :doc: links.
>
>> +
>> +Running DPDK Unit Tests with Meson
>> +==================================
>> +
>> +This section describes how to run testcases with the DPDK meson build system.
>
> Here and below, "testcases" should be split in two words.
>
>> +
>> +
>> +Building and running the unit tests
>> +-----------------------------------
>> +
>> +* Create the meson build output folder using the following command::
>> +
>> +      $ meson <build_dir>
>> +
>> +* Enter into build output folder, which was created by above command::
>> +
>> +      $ cd build
>
> Should be the same as above: <build_dir>
>
>> +
>> +* Compile DPDK using command::
>> +
>> +      $ ninja
>
> Do we really need to repeat above basic steps?
> Would be easier to just reference another guide about meson.
> I think doc/build-sdk-meson.txt should be moved to .rst.

+1

>> +
>> +The output file of the build will be available in meson build folder. After
>> +a successful ninja command, the binary ``dpdk-test`` is created in
>> +``build/test/test/``.
>
> Again, "build" is an example directory.
>
>> +
>> +* Run the unit testcases::
>> +
>> +      $ ninja test
>> +      # or
>> +      $ meson test
>> +
>> +* To run specific test case via meson::
>> +
>> +      $ meson test <test case>
>> +      # or
>> +      $ ninja test <test case>
>
> Would be worth to mention why meson or ninja can be used.
>
>> +
>> +
>> +Grouping of testcases
>> +---------------------
>> +
>> +Testcases have been grouped into four different groups based on conditions
>> +of time duration and performance of the individual testcase.
>
> Grouping has changed recently.
> This part should be updated please.
>
>> +
>> +* Fast tests which can be run in parallel.
>> +* Fast tests which must run serially.
>> +* Performance tests.
>> +* Driver tests.
>> +* Tests which produce lists of objects as output, and therefore that need
>> +  manual checking.
>> +
>> +Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument
>> +of ``test()`` in meson.build
>> +
>> +These tests can be run using the argument to ``meson test`` as
>> +``--suite project_name:label``.
>> +
>> +For example::
>> +
>> +    $ meson test --suite DPDK:fast-tests
>> +
>> +
>> +The project name is optional so the following is equivalent to the previous
>> +command::
>> +
>> +
>> +    $ meson test --suite fast-tests
>> +
>> +
>> +Running different test suites
>> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> +
>> +The following commands are some examples of how to run testcases using option
>> +``--suite``:

The following section is a bit misleading.  The limitation on run time
is per-test.  So 600 seconds in perf-tests is 600 seconds PER TEST.  IE:
if there are 10 tests, you'll be waiting up to 50 minutes.

>> +* Fast Tests should take less than 10 seconds. The meson command to run them
>> +  is::
>> +
>> +      $ meson test --suite DPDK:fast-tests
>> +
>> +* Performance Tests should take less than 600 seconds. The meson command to
>> +  run them is::
>> +
>> +      $ meson test --suite DPDK:perf-tests
>> +
>> +* Driver Tests should take less than 600 seconds. The meson command to run
>> +  them is::
>> +
>> +      $ meson test --suite DPDK:driver-tests
>> +
>> +* The meson command to run Dump Tests is::
>> +
>> +      $ meson test --suite DPDK:dump-tests
>
> Would be simpler to just list the suites.

Even better would be to provide a 1-liner that would dump the suites so
that new test suites wouldn't need to update the documentation.

>> +
>> +
>> +Dealing with skipped testcases
>> +------------------------------
>> +
>> +Some unit test cases have a dependency on external libraries, driver modules
>> +or config flags, without which the test cases cannot be run. Such test cases
>> +will be reported as skipped if they cannot run. To enable those test cases,
>> +the user should ensure the required dependencies are met.  Below are a few
>> +possible causes why tests may be skipped and how they may be resolved:
>> +
>> +#. Optional external libraries are not found.
>> +#. Config flags for the dependent library are not enabled.
>> +#. Dependent driver modules are not installed on the system.
>> +
>> +To help find missing libraries, the user can specify addition search paths
>
> addition -> additional ?
>
>> +for those libraries as below:
>> +
>> +* Single path::
>> +
>> +      $ export LIBRARY_PATH=path
>> +
>> +* Multiple paths::
>> +
>> +      $ export LIBRARY_PATH=path1:path2:path3
>> +
>> +Some functionality may be disabled due to library headers being missed as part
>> +of the build. To specify an additional search path for headers at
>> +configuration time, use one of the commands below:
>> +
>> +*  Single path::
>> +
>> +       $ CFLAGS=-I/path meson build
>> +
>> +*  Multiple paths::
>> +
>> +       $ CFLAGS=-I/path1 -I/path2 meson build
>
> Some quotes are missing to set multiple paths.
>
>> +
>> +Below are some examples that show how to export libraries and their header
>> +paths.
>> +
>> +To specify a single library at a time::
>> +
>> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
>> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
>> +
>> +To specify multiple libraries at a time::
>> +
>> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
>> +    $ CFLAGS=-I/path/zuc/include \
>> +             -I/path/libsso_kasumi/include \
>> +	     meson build
>
> Why export is used for LIBRARY_PATH and not CFLAGS?
> I think both variables can be exported or prepend the meson command?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-08 20:18               ` Aaron Conole
@ 2019-07-09 18:57                 ` Michael Santana Francisco
  2019-07-22 12:39                   ` Parthasarathy, JananeeX M
  0 siblings, 1 reply; 716+ messages in thread
From: Michael Santana Francisco @ 2019-07-09 18:57 UTC (permalink / raw)
  To: Aaron Conole
  Cc: Thomas Monjalon, Hari Kumar Vemula, dev, reshma.pattan,
	john.mcnamara, marko.kovacevic, JananeeX M Parthasarathy,
	Bruce Richardson, David Marchand

On Mon, Jul 8, 2019 at 4:18 PM Aaron Conole <aconole@redhat.com> wrote:
>
> Thomas Monjalon <thomas@monjalon.net> writes:
>
> > Hi please find some comments below:
> >
> > 06/06/2019 13:59, Hari Kumar Vemula:
> >> +++ b/doc/guides/prog_guide/meson_ut.rst
> >> @@ -0,0 +1,151 @@
> >> +..  SPDX-License-Identifier: BSD-3-Clause
> >> +
> >
> > Useless blank line.
> >
> >> +    Copyright(c) 2018-2019 Intel Corporation.
> >> +
> >> +.. _meson_unit_tests:
> >
> > Useless anchor. The doc can be referenced with :doc: links.
> >
> >> +
> >> +Running DPDK Unit Tests with Meson
> >> +==================================
> >> +
> >> +This section describes how to run testcases with the DPDK meson build system.
> >
> > Here and below, "testcases" should be split in two words.
> >
> >> +
> >> +
> >> +Building and running the unit tests
> >> +-----------------------------------
> >> +
> >> +* Create the meson build output folder using the following command::
> >> +
> >> +      $ meson <build_dir>
> >> +
> >> +* Enter into build output folder, which was created by above command::
> >> +
> >> +      $ cd build
> >
> > Should be the same as above: <build_dir>
> >
> >> +
> >> +* Compile DPDK using command::
> >> +
> >> +      $ ninja
> >
> > Do we really need to repeat above basic steps?
> > Would be easier to just reference another guide about meson.
> > I think doc/build-sdk-meson.txt should be moved to .rst.
>
> +1
>
> >> +
> >> +The output file of the build will be available in meson build folder. After
> >> +a successful ninja command, the binary ``dpdk-test`` is created in
> >> +``build/test/test/``.
> >
> > Again, "build" is an example directory.
> >
> >> +
> >> +* Run the unit testcases::
> >> +
> >> +      $ ninja test
> >> +      # or
> >> +      $ meson test
> >> +
> >> +* To run specific test case via meson::
> >> +
> >> +      $ meson test <test case>
> >> +      # or
> >> +      $ ninja test <test case>
> >
> > Would be worth to mention why meson or ninja can be used.
> >
> >> +
> >> +
> >> +Grouping of testcases
> >> +---------------------
> >> +
> >> +Testcases have been grouped into four different groups based on conditions
> >> +of time duration and performance of the individual testcase.
> >
> > Grouping has changed recently.
> > This part should be updated please.
> >
> >> +
> >> +* Fast tests which can be run in parallel.
> >> +* Fast tests which must run serially.
> >> +* Performance tests.
> >> +* Driver tests.
> >> +* Tests which produce lists of objects as output, and therefore that need
> >> +  manual checking.
> >> +
> >> +Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument
> >> +of ``test()`` in meson.build
> >> +
> >> +These tests can be run using the argument to ``meson test`` as
> >> +``--suite project_name:label``.
> >> +
> >> +For example::
> >> +
> >> +    $ meson test --suite DPDK:fast-tests
> >> +
> >> +
> >> +The project name is optional so the following is equivalent to the previous
> >> +command::
> >> +
> >> +
> >> +    $ meson test --suite fast-tests
> >> +
> >> +
> >> +Running different test suites
> >> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >> +
> >> +The following commands are some examples of how to run testcases using option
> >> +``--suite``:
>
> The following section is a bit misleading.  The limitation on run time
> is per-test.  So 600 seconds in perf-tests is 600 seconds PER TEST.  IE:
> if there are 10 tests, you'll be waiting up to 50 minutes.
>
> >> +* Fast Tests should take less than 10 seconds. The meson command to run them
> >> +  is::
> >> +
> >> +      $ meson test --suite DPDK:fast-tests
> >> +
> >> +* Performance Tests should take less than 600 seconds. The meson command to
> >> +  run them is::
> >> +
> >> +      $ meson test --suite DPDK:perf-tests
> >> +
> >> +* Driver Tests should take less than 600 seconds. The meson command to run
> >> +  them is::
> >> +
> >> +      $ meson test --suite DPDK:driver-tests
> >> +
> >> +* The meson command to run Dump Tests is::
> >> +
> >> +      $ meson test --suite DPDK:dump-tests
> >
> > Would be simpler to just list the suites.
>
> Even better would be to provide a 1-liner that would dump the suites so
> that new test suites wouldn't need to update the documentation.
Worth mentioning that you can run `meson test --list` to see a list of
all available tests
>
> >> +
> >> +
> >> +Dealing with skipped testcases
> >> +------------------------------
> >> +
> >> +Some unit test cases have a dependency on external libraries, driver modules
> >> +or config flags, without which the test cases cannot be run. Such test cases
> >> +will be reported as skipped if they cannot run. To enable those test cases,
> >> +the user should ensure the required dependencies are met.  Below are a few
> >> +possible causes why tests may be skipped and how they may be resolved:
> >> +
> >> +#. Optional external libraries are not found.
> >> +#. Config flags for the dependent library are not enabled.
> >> +#. Dependent driver modules are not installed on the system.
> >> +
> >> +To help find missing libraries, the user can specify addition search paths
> >
> > addition -> additional ?
> >
> >> +for those libraries as below:
> >> +
> >> +* Single path::
> >> +
> >> +      $ export LIBRARY_PATH=path
> >> +
> >> +* Multiple paths::
> >> +
> >> +      $ export LIBRARY_PATH=path1:path2:path3
> >> +
> >> +Some functionality may be disabled due to library headers being missed as part
> >> +of the build. To specify an additional search path for headers at
> >> +configuration time, use one of the commands below:
> >> +
> >> +*  Single path::
> >> +
> >> +       $ CFLAGS=-I/path meson build
> >> +
> >> +*  Multiple paths::
> >> +
> >> +       $ CFLAGS=-I/path1 -I/path2 meson build
> >
> > Some quotes are missing to set multiple paths.
> >
> >> +
> >> +Below are some examples that show how to export libraries and their header
> >> +paths.
> >> +
> >> +To specify a single library at a time::
> >> +
> >> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> >> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> >> +
> >> +To specify multiple libraries at a time::
> >> +
> >> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> >> +    $ CFLAGS=-I/path/zuc/include \
> >> +             -I/path/libsso_kasumi/include \
> >> +         meson build
> >
> > Why export is used for LIBRARY_PATH and not CFLAGS?
> > I think both variables can be exported or prepend the meson command?

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-09 18:57                 ` Michael Santana Francisco
@ 2019-07-22 12:39                   ` Parthasarathy, JananeeX M
  2019-07-22 12:53                     ` Thomas Monjalon
  0 siblings, 1 reply; 716+ messages in thread
From: Parthasarathy, JananeeX M @ 2019-07-22 12:39 UTC (permalink / raw)
  To: Michael Santana Francisco, Aaron Conole, Thomas Monjalon
  Cc: Hari Kumar Vemula, dev, Pattan, Reshma, Mcnamara, John,
	Kovacevic, Marko, Richardson, Bruce, David Marchand

Hi,

>-----Original Message-----
>From: Michael Santana Francisco [mailto:msantana@redhat.com]
>Sent: Wednesday, July 10, 2019 12:28 AM
>To: Aaron Conole <aconole@redhat.com>
>Cc: Thomas Monjalon <thomas@monjalon.net>; Hari Kumar Vemula
><hari.kumarx.vemula@intel.com>; dev <dev@dpdk.org>; Pattan, Reshma
><reshma.pattan@intel.com>; Mcnamara, John <john.mcnamara@intel.com>;
>Kovacevic, Marko <marko.kovacevic@intel.com>; Parthasarathy, JananeeX M
><jananeex.m.parthasarathy@intel.com>; Richardson, Bruce
><bruce.richardson@intel.com>; David Marchand
><david.marchand@redhat.com>
>Subject: Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
>
>On Mon, Jul 8, 2019 at 4:18 PM Aaron Conole <aconole@redhat.com> wrote:
>>
>> Thomas Monjalon <thomas@monjalon.net> writes:
>>
>> > Hi please find some comments below:
>> >
>> > 06/06/2019 13:59, Hari Kumar Vemula:
>> >> +++ b/doc/guides/prog_guide/meson_ut.rst
>> >> @@ -0,0 +1,151 @@
>> >> +..  SPDX-License-Identifier: BSD-3-Clause
>> >> +
>> >
>> > Useless blank line.
>> >
>> >> +    Copyright(c) 2018-2019 Intel Corporation.
>> >> +
>> >> +.. _meson_unit_tests:
>> >
>> > Useless anchor. The doc can be referenced with :doc: links.
>> >
>> >> +
>> >> +Running DPDK Unit Tests with Meson
>> >> +==================================
>> >> +
>> >> +This section describes how to run testcases with the DPDK meson build
>system.
>> >
>> > Here and below, "testcases" should be split in two words.

Will correct it.

>> >
>> >> +
>> >> +
>> >> +Building and running the unit tests
>> >> +-----------------------------------
>> >> +
>> >> +* Create the meson build output folder using the following command::
>> >> +
>> >> +      $ meson <build_dir>
>> >> +
>> >> +* Enter into build output folder, which was created by above command::
>> >> +
>> >> +      $ cd build
>> >
>> > Should be the same as above: <build_dir>

Will change accordingly.

>> >
>> >> +
>> >> +* Compile DPDK using command::
>> >> +
>> >> +      $ ninja
>> >
>> > Do we really need to repeat above basic steps?
>> > Would be easier to just reference another guide about meson.
>> > I think doc/build-sdk-meson.txt should be moved to .rst.
>>
>> +1
>>

This doc helps to run UT, having basic steps in same page will help user to go through together and execute the same.
Just for few lines moving back and forth to different pages might be bit confusing.
Anyway still if you would prefer to remove these then only 2 sections will be available in this doc.
Please let us know if it is ok.

>> >> +
>> >> +The output file of the build will be available in meson build
>> >> +folder. After a successful ninja command, the binary ``dpdk-test``
>> >> +is created in ``build/test/test/``.
>> >
>> > Again, "build" is an example directory.
>> >
>> >> +
>> >> +* Run the unit testcases::
>> >> +
>> >> +      $ ninja test
>> >> +      # or
>> >> +      $ meson test
>> >> +
>> >> +* To run specific test case via meson::
>> >> +
>> >> +      $ meson test <test case>
>> >> +      # or
>> >> +      $ ninja test <test case>
>> >
>> > Would be worth to mention why meson or ninja can be used.
>> >

OK
>> >> +
>> >> +
>> >> +Grouping of testcases
>> >> +---------------------
>> >> +
>> >> +Testcases have been grouped into four different groups based on
>> >> +conditions of time duration and performance of the individual testcase.
>> >
>> > Grouping has changed recently.
>> > This part should be updated please.
	
Thanks for the info. We observed that fast parallel test group is removed. 
Now we have four groups - fast, perf, driver, debug - all in non-parallel mode We will update the same.

>> >
>> >> +
>> >> +* Fast tests which can be run in parallel.
>> >> +* Fast tests which must run serially.
>> >> +* Performance tests.
>> >> +* Driver tests.
>> >> +* Tests which produce lists of objects as output, and therefore
>> >> +that need
>> >> +  manual checking.
>> >> +
>> >> +Testcases can be run in parallel or non-parallel mode using the
>> >> +``is_parallel`` argument of ``test()`` in meson.build
>> >> +
>> >> +These tests can be run using the argument to ``meson test`` as
>> >> +``--suite project_name:label``.
>> >> +
>> >> +For example::
>> >> +
>> >> +    $ meson test --suite DPDK:fast-tests
>> >> +
>> >> +
>> >> +The project name is optional so the following is equivalent to the
>> >> +previous
>> >> +command::
>> >> +
>> >> +
>> >> +    $ meson test --suite fast-tests
>> >> +
>> >> +
>> >> +Running different test suites
>> >> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> >> +
>> >> +The following commands are some examples of how to run testcases
>> >> +using option
>> >> +``--suite``:
>>
>> The following section is a bit misleading.  The limitation on run time
>> is per-test.  So 600 seconds in perf-tests is 600 seconds PER TEST.  IE:
>> if there are 10 tests, you'll be waiting up to 50 minutes.
>>
>> >> +* Fast Tests should take less than 10 seconds. The meson command
>> >> +to run them
>> >> +  is::
>> >> +
>> >> +      $ meson test --suite DPDK:fast-tests
>> >> +
>> >> +* Performance Tests should take less than 600 seconds. The meson
>> >> +command to
>> >> +  run them is::
>> >> +
>> >> +      $ meson test --suite DPDK:perf-tests
>> >> +
>> >> +* Driver Tests should take less than 600 seconds. The meson
>> >> +command to run
>> >> +  them is::
>> >> +
>> >> +      $ meson test --suite DPDK:driver-tests
>> >> +
>> >> +* The meson command to run Dump Tests is::
>> >> +
>> >> +      $ meson test --suite DPDK:dump-tests
>> >
>> > Would be simpler to just list the suites.
>>
>> Even better would be to provide a 1-liner that would dump the suites
>> so that new test suites wouldn't need to update the documentation.
>Worth mentioning that you can run `meson test --list` to see a list of all
>available tests
>>

Will update the same and remove multiple lines.

>> >> +
>> >> +
>> >> +Dealing with skipped testcases
>> >> +------------------------------
>> >> +
>> >> +Some unit test cases have a dependency on external libraries,
>> >> +driver modules or config flags, without which the test cases
>> >> +cannot be run. Such test cases will be reported as skipped if they
>> >> +cannot run. To enable those test cases, the user should ensure the
>> >> +required dependencies are met.  Below are a few possible causes why
>tests may be skipped and how they may be resolved:
>> >> +
>> >> +#. Optional external libraries are not found.
>> >> +#. Config flags for the dependent library are not enabled.
>> >> +#. Dependent driver modules are not installed on the system.
>> >> +
>> >> +To help find missing libraries, the user can specify addition
>> >> +search paths
>> >
>> > addition -> additional ?
>> >
>> >> +for those libraries as below:
>> >> +
>> >> +* Single path::
>> >> +
>> >> +      $ export LIBRARY_PATH=path
>> >> +
>> >> +* Multiple paths::
>> >> +
>> >> +      $ export LIBRARY_PATH=path1:path2:path3
>> >> +
>> >> +Some functionality may be disabled due to library headers being
>> >> +missed as part of the build. To specify an additional search path
>> >> +for headers at configuration time, use one of the commands below:
>> >> +
>> >> +*  Single path::
>> >> +
>> >> +       $ CFLAGS=-I/path meson build
>> >> +
>> >> +*  Multiple paths::
>> >> +
>> >> +       $ CFLAGS=-I/path1 -I/path2 meson build
>> >
>> > Some quotes are missing to set multiple paths.

Is <build_dir>  meant here?

>> >
>> >> +
>> >> +Below are some examples that show how to export libraries and
>> >> +their header paths.
>> >> +
>> >> +To specify a single library at a time::
>> >> +
>> >> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
>> >> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
>> >> +
>> >> +To specify multiple libraries at a time::
>> >> +
>> >> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
>> >> +    $ CFLAGS=-I/path/zuc/include \
>> >> +             -I/path/libsso_kasumi/include \
>> >> +         meson build
>> >
>> > Why export is used for LIBRARY_PATH and not CFLAGS?
>> > I think both variables can be exported or prepend the meson command?

CFLAGS given in meson command works and  also CFLAGS can be exported.
LIBRARY_PATH  cannot be prepended to meson command. We tried but it is not reflecting the required values.
Environment variables set using export is considered and not as command line args of meson command.


Will send the next version patch addressing these comments.

Thanks
M.P.Jananee


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-22 12:39                   ` Parthasarathy, JananeeX M
@ 2019-07-22 12:53                     ` Thomas Monjalon
  2019-07-22 13:53                       ` Bruce Richardson
  0 siblings, 1 reply; 716+ messages in thread
From: Thomas Monjalon @ 2019-07-22 12:53 UTC (permalink / raw)
  To: Parthasarathy, JananeeX M
  Cc: dev, Michael Santana Francisco, Aaron Conole, Hari Kumar Vemula,
	Pattan, Reshma, Mcnamara, John, Kovacevic, Marko, Richardson,
	Bruce, David Marchand

22/07/2019 14:39, Parthasarathy, JananeeX M:
>From: Michael Santana Francisco [mailto:msantana@redhat.com]
> >On Mon, Jul 8, 2019 at 4:18 PM Aaron Conole <aconole@redhat.com> wrote:
> >> Thomas Monjalon <thomas@monjalon.net> writes:
> >> >> +Building and running the unit tests
> >> >> +-----------------------------------
> >> >> +
> >> >> +* Create the meson build output folder using the following command::
> >> >> +
> >> >> +      $ meson <build_dir>
> >> >> +
> >> >> +* Enter into build output folder, which was created by above command::
> >> >> +
> >> >> +      $ cd build
> >> >
> >> > Should be the same as above: <build_dir>
> 
> Will change accordingly.
> 
> >> >
> >> >> +
> >> >> +* Compile DPDK using command::
> >> >> +
> >> >> +      $ ninja
> >> >
> >> > Do we really need to repeat above basic steps?
> >> > Would be easier to just reference another guide about meson.
> >> > I think doc/build-sdk-meson.txt should be moved to .rst.
> >>
> >> +1
> 
> This doc helps to run UT, having basic steps in same page will help user to go through together and execute the same.
> Just for few lines moving back and forth to different pages might be bit confusing.
> Anyway still if you would prefer to remove these then only 2 sections will be available in this doc.
> Please let us know if it is ok.

I think it is better to avoid repetition.


> >> >> +*  Multiple paths::
> >> >> +
> >> >> +       $ CFLAGS=-I/path1 -I/path2 meson build
> >> >
> >> > Some quotes are missing to set multiple paths.
> 
> Is <build_dir>  meant here?

I am just saying that space-separated value require some quotes.

> >> >> +Below are some examples that show how to export libraries and
> >> >> +their header paths.
> >> >> +
> >> >> +To specify a single library at a time::
> >> >> +
> >> >> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> >> >> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> >> >> +
> >> >> +To specify multiple libraries at a time::
> >> >> +
> >> >> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> >> >> +    $ CFLAGS=-I/path/zuc/include \
> >> >> +             -I/path/libsso_kasumi/include \
> >> >> +         meson build
> >> >
> >> > Why export is used for LIBRARY_PATH and not CFLAGS?
> >> > I think both variables can be exported or prepend the meson command?
> 
> CFLAGS given in meson command works and  also CFLAGS can be exported.
> LIBRARY_PATH  cannot be prepended to meson command. We tried but it is not reflecting the required values.
> Environment variables set using export is considered and not as command line args of meson command.

Please we need to understand why LIBRARY_PATH is not working
when preprended in the meson command.
Do you have more informations?



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-22 12:53                     ` Thomas Monjalon
@ 2019-07-22 13:53                       ` Bruce Richardson
  2019-07-23 11:34                         ` Parthasarathy, JananeeX M
  0 siblings, 1 reply; 716+ messages in thread
From: Bruce Richardson @ 2019-07-22 13:53 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Parthasarathy, JananeeX M, dev, Michael Santana Francisco,
	Aaron Conole, Hari Kumar Vemula, Pattan, Reshma, Mcnamara, John,
	Kovacevic, Marko, David Marchand

On Mon, Jul 22, 2019 at 02:53:34PM +0200, Thomas Monjalon wrote:
> 22/07/2019 14:39, Parthasarathy, JananeeX M:
> >From: Michael Santana Francisco [mailto:msantana@redhat.com]
> > >On Mon, Jul 8, 2019 at 4:18 PM Aaron Conole <aconole@redhat.com> wrote:
> > >> Thomas Monjalon <thomas@monjalon.net> writes:
> > >> >> +Building and running the unit tests
> > >> >> +-----------------------------------
> > >> >> +
> > >> >> +* Create the meson build output folder using the following command::
> > >> >> +
> > >> >> +      $ meson <build_dir>
> > >> >> +
> > >> >> +* Enter into build output folder, which was created by above command::
> > >> >> +
> > >> >> +      $ cd build
> > >> >
> > >> > Should be the same as above: <build_dir>
> > 
> > Will change accordingly.
> > 
> > >> >
> > >> >> +
> > >> >> +* Compile DPDK using command::
> > >> >> +
> > >> >> +      $ ninja
> > >> >
> > >> > Do we really need to repeat above basic steps?
> > >> > Would be easier to just reference another guide about meson.
> > >> > I think doc/build-sdk-meson.txt should be moved to .rst.
> > >>
> > >> +1
> > 
> > This doc helps to run UT, having basic steps in same page will help user to go through together and execute the same.
> > Just for few lines moving back and forth to different pages might be bit confusing.
> > Anyway still if you would prefer to remove these then only 2 sections will be available in this doc.
> > Please let us know if it is ok.
> 
> I think it is better to avoid repetition.
> 
> 
> > >> >> +*  Multiple paths::
> > >> >> +
> > >> >> +       $ CFLAGS=-I/path1 -I/path2 meson build
> > >> >
> > >> > Some quotes are missing to set multiple paths.
> > 
> > Is <build_dir>  meant here?
> 
> I am just saying that space-separated value require some quotes.
> 
> > >> >> +Below are some examples that show how to export libraries and
> > >> >> +their header paths.
> > >> >> +
> > >> >> +To specify a single library at a time::
> > >> >> +
> > >> >> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> > >> >> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> > >> >> +
> > >> >> +To specify multiple libraries at a time::
> > >> >> +
> > >> >> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> > >> >> +    $ CFLAGS=-I/path/zuc/include \
> > >> >> +             -I/path/libsso_kasumi/include \
> > >> >> +         meson build
> > >> >
> > >> > Why export is used for LIBRARY_PATH and not CFLAGS?
> > >> > I think both variables can be exported or prepend the meson command?
> > 
> > CFLAGS given in meson command works and  also CFLAGS can be exported.
> > LIBRARY_PATH  cannot be prepended to meson command. We tried but it is not reflecting the required values.
> > Environment variables set using export is considered and not as command line args of meson command.
> 
> Please we need to understand why LIBRARY_PATH is not working
> when preprended in the meson command.
> Do you have more informations?
>

Rather than using the environment, one can also use "-Dc_args='...'
-Dc_link_args='...'" when calling meson.

Otherwise, I agree with Thomas, we should find out why the LIBRARY_PATH
doesn't work when passed in directly. I'm not aware of any reason it
shouldn't work.

/Bruce 

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
  2019-07-22 13:53                       ` Bruce Richardson
@ 2019-07-23 11:34                         ` Parthasarathy, JananeeX M
  0 siblings, 0 replies; 716+ messages in thread
From: Parthasarathy, JananeeX M @ 2019-07-23 11:34 UTC (permalink / raw)
  To: Richardson, Bruce, Thomas Monjalon
  Cc: dev, Michael Santana Francisco, Aaron Conole, Hari Kumar Vemula,
	Pattan, Reshma, Mcnamara, John, Kovacevic, Marko, David Marchand

Hi,

>-----Original Message-----
>From: Bruce Richardson [mailto:bruce.richardson@intel.com]
>Sent: Monday, July 22, 2019 7:23 PM
>To: Thomas Monjalon <thomas@monjalon.net>
>Cc: Parthasarathy, JananeeX M <jananeex.m.parthasarathy@intel.com>;
>dev@dpdk.org; Michael Santana Francisco <msantana@redhat.com>; Aaron
>Conole <aconole@redhat.com>; Hari Kumar Vemula
><hari.kumarx.vemula@intel.com>; Pattan, Reshma
><reshma.pattan@intel.com>; Mcnamara, John <john.mcnamara@intel.com>;
>Kovacevic, Marko <marko.kovacevic@intel.com>; David Marchand
><david.marchand@redhat.com>
>Subject: Re: [dpdk-dev] [PATCH v6] doc: add meson ut info in prog guide
>
>On Mon, Jul 22, 2019 at 02:53:34PM +0200, Thomas Monjalon wrote:
>> 22/07/2019 14:39, Parthasarathy, JananeeX M:
>> >From: Michael Santana Francisco [mailto:msantana@redhat.com]
>> > >On Mon, Jul 8, 2019 at 4:18 PM Aaron Conole <aconole@redhat.com>
>wrote:
>> > >> Thomas Monjalon <thomas@monjalon.net> writes:
>> > >> >> +Building and running the unit tests
>> > >> >> +-----------------------------------
>> > >> >> +
>> > >> >> +* Create the meson build output folder using the following
>command::
>> > >> >> +
>> > >> >> +      $ meson <build_dir>
>> > >> >> +
>> > >> >> +* Enter into build output folder, which was created by above
>command::
>> > >> >> +
>> > >> >> +      $ cd build
>> > >> >
>> > >> > Should be the same as above: <build_dir>
>> >
>> > Will change accordingly.
>> >
>> > >> >
>> > >> >> +
>> > >> >> +* Compile DPDK using command::
>> > >> >> +
>> > >> >> +      $ ninja
>> > >> >
>> > >> > Do we really need to repeat above basic steps?
>> > >> > Would be easier to just reference another guide about meson.
>> > >> > I think doc/build-sdk-meson.txt should be moved to .rst.
>> > >>
>> > >> +1
>> >
>> > This doc helps to run UT, having basic steps in same page will help user to
>go through together and execute the same.
>> > Just for few lines moving back and forth to different pages might be bit
>confusing.
>> > Anyway still if you would prefer to remove these then only 2 sections will
>be available in this doc.
>> > Please let us know if it is ok.
>>
>> I think it is better to avoid repetition.
>>
>>
>> > >> >> +*  Multiple paths::
>> > >> >> +
>> > >> >> +       $ CFLAGS=-I/path1 -I/path2 meson build
>> > >> >
>> > >> > Some quotes are missing to set multiple paths.
>> >
>> > Is <build_dir>  meant here?
>>
>> I am just saying that space-separated value require some quotes.
>>
>> > >> >> +Below are some examples that show how to export libraries and
>> > >> >> +their header paths.
>> > >> >> +
>> > >> >> +To specify a single library at a time::
>> > >> >> +
>> > >> >> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
>> > >> >> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
>> > >> >> +
>> > >> >> +To specify multiple libraries at a time::
>> > >> >> +
>> > >> >> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
>> > >> >> +    $ CFLAGS=-I/path/zuc/include \
>> > >> >> +             -I/path/libsso_kasumi/include \
>> > >> >> +         meson build
>> > >> >
>> > >> > Why export is used for LIBRARY_PATH and not CFLAGS?
>> > >> > I think both variables can be exported or prepend the meson
>command?
>> >
>> > CFLAGS given in meson command works and  also CFLAGS can be
>exported.
>> > LIBRARY_PATH  cannot be prepended to meson command. We tried but it
>is not reflecting the required values.
>> > Environment variables set using export is considered and not as command
>line args of meson command.
>>
>> Please we need to understand why LIBRARY_PATH is not working when
>> preprended in the meson command.
>> Do you have more informations?
>>
>
>Rather than using the environment, one can also use "-Dc_args='...'
>-Dc_link_args='...'" when calling meson.
>
>Otherwise, I agree with Thomas, we should find out why the LIBRARY_PATH
>doesn't work when passed in directly. I'm not aware of any reason it shouldn't
>work.
>
>/Bruce

As per our earlier analysis,  

LDFLAGS was not supported earlier in meson command.

find_library() is used to check whether the external dependency library exists or not in order to configure the build.
This function uses the standard system path to check existence of library, or else LIBRARY_PATH can be used as environment variable for custom paths.
LIBRARY_PATH is not supported directly (not a build configure option).

Only recently we can observe that LDFLAGS support is included in meson and linker options can be provided using LDFLAGS.
$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options>

Although LDFLAGS can be used and build configuration gets updated in LINK_ARGS,

'dependencies' option of static_library and shared_library() should be an object which is return value from dependency()/find_library().
Due to use of find_library() currently, we need to set the environment variable.

Regards
M.P.Jananee

^ permalink raw reply	[flat|nested] 716+ messages in thread

* [dpdk-dev] [PATCH v7] doc: add meson ut info in prog guide
  2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
  2019-07-08 19:40             ` Thomas Monjalon
@ 2019-08-07 13:56             ` Agalya Babu RadhaKrishnan
  2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
                                 ` (2 more replies)
  1 sibling, 3 replies; 716+ messages in thread
From: Agalya Babu RadhaKrishnan @ 2019-08-07 13:56 UTC (permalink / raw)
  To: dev
  Cc: reshma.pattan, john.mcnamara, marko.kovacevic, bruce.richardson,
	jananeex.m.parthasarathy, Hari Kumar Vemula

From: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
v7: Updated v6 patch comments
v6: Updated comments
v5: Modified
v4: Typos corrected
v3: Modified
v2: Removed enhancement details
---
 .../prog_guide/build-sdk-meson.rst}           |  7 +-
 doc/guides/prog_guide/index.rst               |  2 +
 doc/guides/prog_guide/meson_ut.rst            | 92 +++++++++++++++++++
 3 files changed, 98 insertions(+), 3 deletions(-)
 rename doc/{build-sdk-meson.txt => guides/prog_guide/build-sdk-meson.rst} (97%)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/build-sdk-meson.txt b/doc/guides/prog_guide/build-sdk-meson.rst
similarity index 97%
rename from doc/build-sdk-meson.txt
rename to doc/guides/prog_guide/build-sdk-meson.rst
index fc7fe37b5..34c363694 100644
--- a/doc/build-sdk-meson.txt
+++ b/doc/guides/prog_guide/build-sdk-meson.rst
@@ -1,5 +1,5 @@
-INSTALLING DPDK USING THE MESON BUILD SYSTEM
----------------------------------------------
+Installing DPDK Using the meson build system
+============================================
 
 Summary
 --------
@@ -162,7 +162,8 @@ command::
 
 For example if the target machine is arm64 we can use the following
 command::
-	meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
+
+        meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
 
 where config/arm/arm64_armv8_linux_gcc contains settings for the compilers
 and other build tools to be used, as well as characteristics of the target
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 692409af8..0bab96c58 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -60,6 +60,8 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    build-sdk-meson
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..18392ce04
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,92 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2018-2019 Intel Corporation.
+
+Running DPDK Unit Tests with Meson
+==================================
+
+This section describes how to run test cases with the DPDK meson build system.
+
+Steps to build and run unit test cases using meson can be referred
+in :doc:`build-sdk-meson`
+
+Grouping of test cases
+----------------------
+
+Testcases have been grouped into four different groups.
+
+* Fast tests.
+* Performance tests.
+* Driver tests.
+* Tests which produce lists of objects as output, and therefore that need
+  manual checking.
+
+Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument
+of ``test()`` in meson.build
+
+These tests can be run using the argument to ``meson test`` as
+``--suite project_name:label``.
+
+For example::
+
+    $ meson test --suite DPDK:fast-tests
+
+The project name is optional so the following is equivalent to the previous
+command::
+
+    $ meson test --suite fast-tests
+
+The meson command to list all available tests::
+
+    $ meson test --list
+
+
+Dealing with skipped test cases
+-------------------------------
+
+Some unit test cases have a dependency on external libraries, driver modules
+or config flags, without which the test cases cannot be run. Such test cases
+will be reported as skipped if they cannot run. To enable those test cases,
+the user should ensure the required dependencies are met.  Below are a few
+possible causes why tests may be skipped and how they may be resolved:
+
+#. Optional external libraries are not found.
+#. Config flags for the dependent library are not enabled.
+#. Dependent driver modules are not installed on the system.
+
+To help find missing libraries, the user can specify additional search paths
+for those libraries as below:
+
+* Single path::
+
+      $ export LIBRARY_PATH=path
+
+* Multiple paths::
+
+      $ export LIBRARY_PATH=path1:path2:path3
+
+Some functionality may be disabled due to library headers being missed as part
+of the build. To specify an additional search path for headers at
+configuration time, use one of the commands below:
+
+*  Single path::
+
+       $ CFLAGS=-I/path meson build
+
+*  Multiple paths::
+
+       $ CFLAGS=`-I/path1 -I/path2 meson build`
+
+Below are some examples that show how to export libraries and their header
+paths.
+
+To specify a single library at a time::
+
+    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
+    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
+
+To specify multiple libraries at a time::
+
+    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
+    $ CFLAGS=-I/path/zuc/include \
+             -I/path/libsso_kasumi/include \
+	     meson build
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v7] doc: add meson ut info in prog guide
  2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
@ 2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
  2019-08-07 15:47               ` Michael Santana Francisco
  2019-08-12 12:40               ` [dpdk-dev] [PATCH v8] " Jananee Parthasarathy
  2 siblings, 0 replies; 716+ messages in thread
From: Jerin Jacob Kollanukkaran @ 2019-08-07 14:16 UTC (permalink / raw)
  To: Agalya Babu RadhaKrishnan, dev
  Cc: reshma.pattan, john.mcnamara, marko.kovacevic, bruce.richardson,
	jananeex.m.parthasarathy, Hari Kumar Vemula

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Agalya Babu
> RadhaKrishnan
> Sent: Wednesday, August 7, 2019 7:26 PM
> To: dev@dpdk.org
> Cc: reshma.pattan@intel.com; john.mcnamara@intel.com;
> marko.kovacevic@intel.com; bruce.richardson@intel.com;
> jananeex.m.parthasarathy@intel.com; Hari Kumar Vemula
> <hari.kumarx.vemula@intel.com>
> Subject: [dpdk-dev] [PATCH v7] doc: add meson ut info in prog guide
> 
> From: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> 
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> v7: Updated v6 patch comments
> v6: Updated comments
> v5: Modified
> v4: Typos corrected
> v3: Modified
> v2: Removed enhancement details
> ---
> +
> +Testcases can be run in parallel or non-parallel mode using the
> +``is_parallel`` argument of ``test()`` in meson.build
> +
> +These tests can be run using the argument to ``meson test`` as
> +``--suite project_name:label``.
> +
> +For example::
> +
> +    $ meson test --suite DPDK:fast-tests
> +
> +The project name is optional so the following is equivalent to the
> +previous
> +command::
> +
> +    $ meson test --suite fast-tests

I think, It is good mention about the timeout and/or other valid(if any) UT parameter as well.



^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v7] doc: add meson ut info in prog guide
  2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
  2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
@ 2019-08-07 15:47               ` Michael Santana Francisco
  2019-08-12 12:40               ` [dpdk-dev] [PATCH v8] " Jananee Parthasarathy
  2 siblings, 0 replies; 716+ messages in thread
From: Michael Santana Francisco @ 2019-08-07 15:47 UTC (permalink / raw)
  To: Agalya Babu RadhaKrishnan, dev
  Cc: reshma.pattan, john.mcnamara, marko.kovacevic, bruce.richardson,
	jananeex.m.parthasarathy, Hari Kumar Vemula

On 8/7/19 9:56 AM, Agalya Babu RadhaKrishnan wrote:
> From: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
>
> Add a programmer's guide section for meson ut
>
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
> v7: Updated v6 patch comments
> v6: Updated comments
> v5: Modified
> v4: Typos corrected
> v3: Modified
> v2: Removed enhancement details
> ---
>   .../prog_guide/build-sdk-meson.rst}           |  7 +-
>   doc/guides/prog_guide/index.rst               |  2 +
>   doc/guides/prog_guide/meson_ut.rst            | 92 +++++++++++++++++++
>   3 files changed, 98 insertions(+), 3 deletions(-)
>   rename doc/{build-sdk-meson.txt => guides/prog_guide/build-sdk-meson.rst} (97%)
>   create mode 100644 doc/guides/prog_guide/meson_ut.rst
>
> diff --git a/doc/build-sdk-meson.txt b/doc/guides/prog_guide/build-sdk-meson.rst
> similarity index 97%
> rename from doc/build-sdk-meson.txt
> rename to doc/guides/prog_guide/build-sdk-meson.rst
> index fc7fe37b5..34c363694 100644
> --- a/doc/build-sdk-meson.txt
> +++ b/doc/guides/prog_guide/build-sdk-meson.rst
> @@ -1,5 +1,5 @@
> -INSTALLING DPDK USING THE MESON BUILD SYSTEM
> ----------------------------------------------
> +Installing DPDK Using the meson build system
> +============================================
>   
>   Summary
>   --------
> @@ -162,7 +162,8 @@ command::
>   
>   For example if the target machine is arm64 we can use the following
>   command::
> -	meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
> +
> +        meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
>   
>   where config/arm/arm64_armv8_linux_gcc contains settings for the compilers
>   and other build tools to be used, as well as characteristics of the target
> diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
> index 692409af8..0bab96c58 100644
> --- a/doc/guides/prog_guide/index.rst
> +++ b/doc/guides/prog_guide/index.rst
> @@ -60,6 +60,8 @@ Programmer's Guide
>       source_org
>       dev_kit_build_system
>       dev_kit_root_make_help
> +    build-sdk-meson
> +    meson_ut
>       extend_dpdk
>       build_app
>       ext_app_lib_make_help
> diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
> new file mode 100644
> index 000000000..18392ce04
> --- /dev/null
> +++ b/doc/guides/prog_guide/meson_ut.rst
> @@ -0,0 +1,92 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +    Copyright(c) 2018-2019 Intel Corporation.
> +
> +Running DPDK Unit Tests with Meson
> +==================================
> +
> +This section describes how to run test cases with the DPDK meson build system.
> +
> +Steps to build and run unit test cases using meson can be referred
> +in :doc:`build-sdk-meson`
I think this is misleading. As far as I can see build-sdk-meson doesn't 
provide any details as to how to "run" test cases. I think you meant to 
say build-sdk-meson has the steps to build dpdk, or something among 
those lines
> +
> +Grouping of test cases
> +----------------------
> +
> +Testcases have been grouped into four different groups.

space between Test and cases.

I prefer not having to use the word 'group' twice in the same sentence, 
it just sounds awkward to me. I would do s/different groups/different 
test suites/

> +
> +* Fast tests.
> +* Performance tests.
> +* Driver tests.
> +* Tests which produce lists of objects as output, and therefore that need
> +  manual checking.
> +
> +Testcases can be run in parallel or non-parallel mode using the ``is_parallel`` argument

space between Test and cases.

I would also mention that by default all tests run serially for better 
stability

> +of ``test()`` in meson.build
> +
> +These tests can be run using the argument to ``meson test`` as
> +``--suite project_name:label``.
> +
> +For example::
> +
> +    $ meson test --suite DPDK:fast-tests

I would also somehow mention that these examples only work when your 
current working directory is the build directory. If you are not in the 
build directory you need to pass the -C flag, so like:

$ meson test -C <build path> --suite DPDK:fast-tests

the build path can either be a relative path or an absolute path, but I 
would skip this detail

> +
> +The project name is optional so the following is equivalent to the previous
> +command::
> +
> +    $ meson test --suite fast-tests
> +
> +The meson command to list all available tests::
> +
> +    $ meson test --list
> +
> +
> +Dealing with skipped test cases
> +-------------------------------
> +
> +Some unit test cases have a dependency on external libraries, driver modules
> +or config flags, without which the test cases cannot be run. Such test cases
> +will be reported as skipped if they cannot run. To enable those test cases,
> +the user should ensure the required dependencies are met.  Below are a few
> +possible causes why tests may be skipped and how they may be resolved:
> +
> +#. Optional external libraries are not found.
> +#. Config flags for the dependent library are not enabled.
> +#. Dependent driver modules are not installed on the system.

#. Note enough processing cores. Some tests are skipped on machines with 
2 or 4 cores


The rest lgtm

Acked-by: Michael Santana <msantana@redhat.com <mailto:msantana@redhat.com>>

> +
> +To help find missing libraries, the user can specify additional search paths
> +for those libraries as below:
> +
> +* Single path::
> +
> +      $ export LIBRARY_PATH=path
> +
> +* Multiple paths::
> +
> +      $ export LIBRARY_PATH=path1:path2:path3
> +
> +Some functionality may be disabled due to library headers being missed as part
> +of the build. To specify an additional search path for headers at
> +configuration time, use one of the commands below:
> +
> +*  Single path::
> +
> +       $ CFLAGS=-I/path meson build
> +
> +*  Multiple paths::
> +
> +       $ CFLAGS=`-I/path1 -I/path2 meson build`
> +
> +Below are some examples that show how to export libraries and their header
> +paths.
> +
> +To specify a single library at a time::
> +
> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> +
> +To specify multiple libraries at a time::
> +
> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> +    $ CFLAGS=-I/path/zuc/include \
> +             -I/path/libsso_kasumi/include \
> +	     meson build



^ permalink raw reply	[flat|nested] 716+ messages in thread

* [dpdk-dev] [PATCH v8] doc: add meson ut info in prog guide
  2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
  2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
  2019-08-07 15:47               ` Michael Santana Francisco
@ 2019-08-12 12:40               ` Jananee Parthasarathy
  2020-02-16 10:28                 ` Thomas Monjalon
  2 siblings, 1 reply; 716+ messages in thread
From: Jananee Parthasarathy @ 2019-08-12 12:40 UTC (permalink / raw)
  To: dev
  Cc: reshma.pattan, john.mcnamara, marko.kovacevic, bruce.richardson,
	jananeex.m.parthasarathy, Hari Kumar Vemula

From: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>

Add a programmer's guide section for meson ut

Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Acked-by: Michael Santana <msantana@redhat.com>
---
v8: Addressed v7 patch comments
v7: Updated v6 patch comments
v6: Updated comments
v5: Modified
v4: Typos corrected
v3: Modified
v2: Removed enhancement details
---
 .../prog_guide/build-sdk-meson.rst}           |   7 +-
 doc/guides/prog_guide/index.rst               |   2 +
 doc/guides/prog_guide/meson_ut.rst            | 104 ++++++++++++++++++
 3 files changed, 110 insertions(+), 3 deletions(-)
 rename doc/{build-sdk-meson.txt => guides/prog_guide/build-sdk-meson.rst} (97%)
 create mode 100644 doc/guides/prog_guide/meson_ut.rst

diff --git a/doc/build-sdk-meson.txt b/doc/guides/prog_guide/build-sdk-meson.rst
similarity index 97%
rename from doc/build-sdk-meson.txt
rename to doc/guides/prog_guide/build-sdk-meson.rst
index fc7fe37b5..34c363694 100644
--- a/doc/build-sdk-meson.txt
+++ b/doc/guides/prog_guide/build-sdk-meson.rst
@@ -1,5 +1,5 @@
-INSTALLING DPDK USING THE MESON BUILD SYSTEM
----------------------------------------------
+Installing DPDK Using the meson build system
+============================================
 
 Summary
 --------
@@ -162,7 +162,8 @@ command::
 
 For example if the target machine is arm64 we can use the following
 command::
-	meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
+
+        meson arm-build --cross-file config/arm/arm64_armv8_linux_gcc
 
 where config/arm/arm64_armv8_linux_gcc contains settings for the compilers
 and other build tools to be used, as well as characteristics of the target
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 692409af8..0bab96c58 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -60,6 +60,8 @@ Programmer's Guide
     source_org
     dev_kit_build_system
     dev_kit_root_make_help
+    build-sdk-meson
+    meson_ut
     extend_dpdk
     build_app
     ext_app_lib_make_help
diff --git a/doc/guides/prog_guide/meson_ut.rst b/doc/guides/prog_guide/meson_ut.rst
new file mode 100644
index 000000000..45193ddde
--- /dev/null
+++ b/doc/guides/prog_guide/meson_ut.rst
@@ -0,0 +1,104 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2018-2019 Intel Corporation.
+
+Running DPDK Unit Tests with Meson
+==================================
+
+This section describes how to run test cases with the DPDK meson build system.
+
+Steps to build and install DPDK using meson can be referred
+in :doc:`build-sdk-meson`
+
+Grouping of test cases
+----------------------
+
+Test cases have been classified into four different groups.
+
+* Fast tests.
+* Performance tests.
+* Driver tests.
+* Tests which produce lists of objects as output, and therefore that need
+  manual checking.
+
+These tests can be run using the argument to ``meson test`` as
+``--suite project_name:label``.
+
+For example::
+
+    $ meson test -C <build path> --suite DPDK:fast-tests
+
+If the ``<build path>`` is current working directory,
+the ``-C <build path>`` option can be skipped as below::
+
+    $ meson test --suite DPDK:fast-tests
+
+The project name is optional so the following is equivalent to the previous
+command::
+
+    $ meson test --suite fast-tests
+
+The meson command to list all available tests::
+
+    $ meson test --list
+
+Test cases are run serially by default for better stability.
+
+Arguments of ``test()`` that can be provided in meson.build are as below:
+
+* ``is_parallel`` is used to run test case either in parallel or non-parallel mode.
+* ``timeout`` is used to specify the timeout of test case.
+* ``args`` is used to specify test specific parameters.
+* ``env`` is used to specify test specific environment parameters.
+
+
+Dealing with skipped test cases
+-------------------------------
+
+Some unit test cases have a dependency on external libraries, driver modules
+or config flags, without which the test cases cannot be run. Such test cases
+will be reported as skipped if they cannot run. To enable those test cases,
+the user should ensure the required dependencies are met.  Below are a few
+possible causes why tests may be skipped and how they may be resolved:
+
+#. Optional external libraries are not found.
+#. Config flags for the dependent library are not enabled.
+#. Dependent driver modules are not installed on the system.
+#. Not enough processing cores. Some tests are skipped on machines with 2 or 4 cores.
+
+To help find missing libraries, the user can specify additional search paths
+for those libraries as below:
+
+* Single path::
+
+      $ export LIBRARY_PATH=path
+
+* Multiple paths::
+
+      $ export LIBRARY_PATH=path1:path2:path3
+
+Some functionality may be disabled due to library headers being missed as part
+of the build. To specify an additional search path for headers at
+configuration time, use one of the commands below:
+
+*  Single path::
+
+       $ CFLAGS=-I/path meson build
+
+*  Multiple paths::
+
+       $ CFLAGS=`-I/path1 -I/path2 meson build`
+
+Below are some examples that show how to export libraries and their header
+paths.
+
+To specify a single library at a time::
+
+    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
+    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
+
+To specify multiple libraries at a time::
+
+    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
+    $ CFLAGS=-I/path/zuc/include \
+             -I/path/libsso_kasumi/include \
+	     meson build
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 716+ messages in thread

* [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform
       [not found] <yes>
                   ` (89 preceding siblings ...)
  2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
@ 2019-12-04  9:36 ` Ani Sinha
  2019-12-16  9:31   ` Ani Sinha
       [not found] ` <20220630112644.3682066-1-Shreyas.Karmahe@toshiba-tsip.com>
  91 siblings, 1 reply; 716+ messages in thread
From: Ani Sinha @ 2019-12-04  9:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: Ani Sinha

CLZERO CPUID should be passed on to the guests that use EPYC or EPYC-IBPB CPU
model when the AMD ZEN based host supports it. This change makes it recognize
this CPUID for guests which use EPYC or EPYC-IBPB CPU model.

Signed-off-by: Ani Sinha <ani.sinha@nutanix.com>
---
 target/i386/cpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 69f518a..55f0691 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3813,6 +3813,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
             CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
             CPUID_EXT3_TOPOEXT,
+        .features[FEAT_8000_0008_EBX] =
+            CPUID_8000_0008_EBX_CLZERO,
         .features[FEAT_7_0_EBX] =
             CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
             CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
-- 
1.9.4



^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform
  2019-12-04  9:36 ` [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform Ani Sinha
@ 2019-12-16  9:31   ` Ani Sinha
  0 siblings, 0 replies; 716+ messages in thread
From: Ani Sinha @ 2019-12-16  9:31 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1059 bytes --]

Hi :

Can I get some love for this patch?

thanks
ani

On Dec 4, 2019, 3:06 PM +0530, Ani Sinha <ani.sinha@nutanix.com>, wrote:
CLZERO CPUID should be passed on to the guests that use EPYC or EPYC-IBPB CPU
model when the AMD ZEN based host supports it. This change makes it recognize
this CPUID for guests which use EPYC or EPYC-IBPB CPU model.

Signed-off-by: Ani Sinha <ani.sinha@nutanix.com>
---
target/i386/cpu.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 69f518a..55f0691 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3813,6 +3813,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
CPUID_EXT3_TOPOEXT,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_CLZERO,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
--
1.9.4


[-- Attachment #2: Type: text/html, Size: 1858 bytes --]

^ permalink raw reply related	[flat|nested] 716+ messages in thread

* Re: [dpdk-dev] [PATCH v8] doc: add meson ut info in prog guide
  2019-08-12 12:40               ` [dpdk-dev] [PATCH v8] " Jananee Parthasarathy
@ 2020-02-16 10:28                 ` Thomas Monjalon
  0 siblings, 0 replies; 716+ messages in thread
From: Thomas Monjalon @ 2020-02-16 10:28 UTC (permalink / raw)
  To: reshma.pattan, john.mcnamara, marko.kovacevic, Hari Kumar Vemula,
	Jananee Parthasarathy
  Cc: dev, bruce.richardson

12/08/2019 14:40, Jananee Parthasarathy:
> From: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> 
> Add a programmer's guide section for meson ut
> 
> Signed-off-by: Hari Kumar Vemula <hari.kumarx.vemula@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> Acked-by: Michael Santana <msantana@redhat.com>

The last part about enabling some skipped test case is not correct.
Because this patch is very old, I apply it without this last part:

> +To help find missing libraries, the user can specify additional search paths
> +for those libraries as below:
> +
> +* Single path::
> +
> +      $ export LIBRARY_PATH=path
> +
> +* Multiple paths::
> +
> +      $ export LIBRARY_PATH=path1:path2:path3
> +
> +Some functionality may be disabled due to library headers being missed as part
> +of the build. To specify an additional search path for headers at
> +configuration time, use one of the commands below:
> +
> +*  Single path::
> +
> +       $ CFLAGS=-I/path meson build
> +
> +*  Multiple paths::
> +
> +       $ CFLAGS=`-I/path1 -I/path2 meson build`
> +
> +Below are some examples that show how to export libraries and their header
> +paths.
> +
> +To specify a single library at a time::
> +
> +    $ export LIBRARY_PATH=/root/wireless_libs/zuc/
> +    $ CFLAGS=-I/root/wireless_libs/zuc/include meson build
> +
> +To specify multiple libraries at a time::
> +
> +    $ export LIBRARY_PATH=/path/zuc/:/path/libsso_kasumi/build/
> +    $ CFLAGS=-I/path/zuc/include \
> +             -I/path/libsso_kasumi/include \
> +	     meson build




^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
       [not found] ` <20220630112644.3682066-1-Shreyas.Karmahe@toshiba-tsip.com>
@ 2022-07-01 11:32   ` Jan Kiszka
  2022-07-01 11:33     ` Jan Kiszka
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kiszka @ 2022-07-01 11:32 UTC (permalink / raw)
  To: Shreyas.Karmahe, yes, cip-dev
  Cc: dinesh.kumar, venkata.pyla, kazuhiro3.hayashi

On 30.06.22 13:26, Shreyas.Karmahe@toshiba-tsip.com wrote:
> From: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
> 
> To enable and configure PAM for Remote and Local MFA Session Verification
> 
> Signed-off-by: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
> ---
>  .../security-customizations/files/postinst        | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/recipes-core/security-customizations/files/postinst b/recipes-core/security-customizations/files/postinst
> index bb7d15b..843ce3c 100644
> --- a/recipes-core/security-customizations/files/postinst
> +++ b/recipes-core/security-customizations/files/postinst
> @@ -15,7 +15,8 @@ echo "127.0.0.1 $HOSTNAME" >> /etc/hosts
>  PAM_PWD_FILE="/etc/pam.d/common-password"
>  pam_cracklib_config="password  requisite    pam_cracklib.so retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1  difok=3 gecoscheck=1 reject_username  enforce_for_root"
>  if grep -c "pam_cracklib.so" "${PAM_PWD_FILE}";then
> -        sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
> +        
> +sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
>  fi
>  sed -i "0,/^password.*/s/^password.*/${pam_cracklib_config}\n&/" "${PAM_PWD_FILE}"
>  
> @@ -49,3 +50,15 @@ sed -i 's/admin_space_left_action = .*/admin_space_left_action = SYSLOG/' $AUDIT
>  
>  # CR2.10: Response to audit processing failures
>  sed -i 's/disk_error_action = .*/disk_error_action = SYSLOG/' $AUDIT_CONF_FILE
> +
> +# CR2.11: Enable Mutli Factor Authentication for Local and Remote Session
> +SSHD_AUTH_CONFIG="/etc/pam.d/common-auth"
> +google_authenticator="auth required pam_google_authenticator.so nullok"
> +if grep -c "pam_google_authenticator.so" "${SSHD_AUTH_CONFIG}";then
> +		sed -i '/pam_google_authenticator.so/ s/^#*/#/'  "${SSHD_AUTH_CONFIG}"
> +fi
> +#sed -i "0,/^auth.*/s/^auth.*/${google_authenticator}\n&/" "${SSHD_AUTH_CONFIG}"

Dead code? Or forgotten to activate?

> +echo "auth required pam_google_authenticator.so nullok" | tee -a "${SSHD_AUTH_CONFIG}"
> +# Enable PAM configuration for Remote Session
> +sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' "${SSHD_CONFIG}"
> +echo "AuthenticationMethods keyboard-interactive" | tee -a "${SSHD_CONFIG}"

Jan

-- 
Siemens AG, Technology
Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
  2022-07-01 11:32   ` [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication Jan Kiszka
@ 2022-07-01 11:33     ` Jan Kiszka
  2022-07-04 16:51       ` Shreyas.Karmahe
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kiszka @ 2022-07-01 11:33 UTC (permalink / raw)
  To: Shreyas.Karmahe, yes, cip-dev
  Cc: dinesh.kumar, venkata.pyla, kazuhiro3.hayashi

On 01.07.22 13:32, Jan Kiszka wrote:
> On 30.06.22 13:26, Shreyas.Karmahe@toshiba-tsip.com wrote:
>> From: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>
>> To enable and configure PAM for Remote and Local MFA Session Verification
>>
>> Signed-off-by: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>> ---
>>  .../security-customizations/files/postinst        | 15 ++++++++++++++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/recipes-core/security-customizations/files/postinst b/recipes-core/security-customizations/files/postinst
>> index bb7d15b..843ce3c 100644
>> --- a/recipes-core/security-customizations/files/postinst
>> +++ b/recipes-core/security-customizations/files/postinst
>> @@ -15,7 +15,8 @@ echo "127.0.0.1 $HOSTNAME" >> /etc/hosts
>>  PAM_PWD_FILE="/etc/pam.d/common-password"
>>  pam_cracklib_config="password  requisite    pam_cracklib.so retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1  difok=3 gecoscheck=1 reject_username  enforce_for_root"
>>  if grep -c "pam_cracklib.so" "${PAM_PWD_FILE}";then
>> -        sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
>> +        
>> +sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"

And an accidental change here?

>>  fi
>>  sed -i "0,/^password.*/s/^password.*/${pam_cracklib_config}\n&/" "${PAM_PWD_FILE}"
>>  
>> @@ -49,3 +50,15 @@ sed -i 's/admin_space_left_action = .*/admin_space_left_action = SYSLOG/' $AUDIT
>>  
>>  # CR2.10: Response to audit processing failures
>>  sed -i 's/disk_error_action = .*/disk_error_action = SYSLOG/' $AUDIT_CONF_FILE
>> +
>> +# CR2.11: Enable Mutli Factor Authentication for Local and Remote Session
>> +SSHD_AUTH_CONFIG="/etc/pam.d/common-auth"
>> +google_authenticator="auth required pam_google_authenticator.so nullok"
>> +if grep -c "pam_google_authenticator.so" "${SSHD_AUTH_CONFIG}";then
>> +		sed -i '/pam_google_authenticator.so/ s/^#*/#/'  "${SSHD_AUTH_CONFIG}"
>> +fi
>> +#sed -i "0,/^auth.*/s/^auth.*/${google_authenticator}\n&/" "${SSHD_AUTH_CONFIG}"
> 
> Dead code? Or forgotten to activate?
> 
>> +echo "auth required pam_google_authenticator.so nullok" | tee -a "${SSHD_AUTH_CONFIG}"
>> +# Enable PAM configuration for Remote Session
>> +sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' "${SSHD_CONFIG}"
>> +echo "AuthenticationMethods keyboard-interactive" | tee -a "${SSHD_CONFIG}"
> 

Jan

-- 
Siemens AG, Technology
Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
  2022-07-01 11:33     ` Jan Kiszka
@ 2022-07-04 16:51       ` Shreyas.Karmahe
  2022-07-05 10:02         ` Jan Kiszka
  0 siblings, 1 reply; 716+ messages in thread
From: Shreyas.Karmahe @ 2022-07-04 16:51 UTC (permalink / raw)
  To: jan.kiszka, yes, cip-dev; +Cc: dinesh.kumar, Venkata.Pyla, kazuhiro3.hayashi

Hi Jan,

I have resend the patch again by removing the commented line from postinst file from security-customizations.
The commenting line is dead code only and used for debugging purpose.
Kindly review the following resend patch 

v2-0001-security-customizations-postinst-Add-configuratio.patch

Kind Regards, 
Shreyas
-----Original Message-----
From: Jan Kiszka <jan.kiszka@siemens.com> 
Sent: Friday, July 1, 2022 5:04 PM
To: karmahe shreyas(TSIP) <Shreyas.Karmahe@toshiba-tsip.com>; yes@arc11.toshiba.co.jp; cip-dev@lists.cip-project.org
Cc: dinesh kumar(TSIP) <dinesh.kumar@toshiba-tsip.com>; pyla venkata(TSIP TMIEC ODG Porting) <Venkata.Pyla@toshiba-tsip.com>; hayashi kazuhiro(林 和宏 □SWC◯ACT) <kazuhiro3.hayashi@toshiba.co.jp>
Subject: Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication

On 01.07.22 13:32, Jan Kiszka wrote:
> On 30.06.22 13:26, Shreyas.Karmahe@toshiba-tsip.com wrote:
>> From: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>
>> To enable and configure PAM for Remote and Local MFA Session 
>> Verification
>>
>> Signed-off-by: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>> ---
>>  .../security-customizations/files/postinst        | 15 ++++++++++++++-
>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/recipes-core/security-customizations/files/postinst 
>> b/recipes-core/security-customizations/files/postinst
>> index bb7d15b..843ce3c 100644
>> --- a/recipes-core/security-customizations/files/postinst
>> +++ b/recipes-core/security-customizations/files/postinst
>> @@ -15,7 +15,8 @@ echo "127.0.0.1 $HOSTNAME" >> /etc/hosts  
>> PAM_PWD_FILE="/etc/pam.d/common-password"
>>  pam_cracklib_config="password  requisite    pam_cracklib.so retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1  difok=3 gecoscheck=1 reject_username  enforce_for_root"
>>  if grep -c "pam_cracklib.so" "${PAM_PWD_FILE}";then
>> -        sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
>> +        
>> +sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"

And an accidental change here?

>>  fi
>>  sed -i "0,/^password.*/s/^password.*/${pam_cracklib_config}\n&/" "${PAM_PWD_FILE}"
>>  
>> @@ -49,3 +50,15 @@ sed -i 's/admin_space_left_action = 
>> .*/admin_space_left_action = SYSLOG/' $AUDIT
>>  
>>  # CR2.10: Response to audit processing failures  sed -i 
>> 's/disk_error_action = .*/disk_error_action = SYSLOG/' 
>> $AUDIT_CONF_FILE
>> +
>> +# CR2.11: Enable Mutli Factor Authentication for Local and Remote 
>> +Session SSHD_AUTH_CONFIG="/etc/pam.d/common-auth"
>> +google_authenticator="auth required pam_google_authenticator.so nullok"
>> +if grep -c "pam_google_authenticator.so" "${SSHD_AUTH_CONFIG}";then
>> +		sed -i '/pam_google_authenticator.so/ s/^#*/#/'  "${SSHD_AUTH_CONFIG}"
>> +fi
>> +#sed -i "0,/^auth.*/s/^auth.*/${google_authenticator}\n&/" "${SSHD_AUTH_CONFIG}"
> 
> Dead code? Or forgotten to activate?
> 
>> +echo "auth required pam_google_authenticator.so nullok" | tee -a "${SSHD_AUTH_CONFIG}"
>> +# Enable PAM configuration for Remote Session sed -i 
>> +'s/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' "${SSHD_CONFIG}"
>> +echo "AuthenticationMethods keyboard-interactive" | tee -a "${SSHD_CONFIG}"
> 

Jan

--
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
  2022-07-04 16:51       ` Shreyas.Karmahe
@ 2022-07-05 10:02         ` Jan Kiszka
  2022-07-07 10:46           ` Shreyas.Karmahe
  0 siblings, 1 reply; 716+ messages in thread
From: Jan Kiszka @ 2022-07-05 10:02 UTC (permalink / raw)
  To: Shreyas.Karmahe, yes, cip-dev
  Cc: dinesh.kumar, Venkata.Pyla, kazuhiro3.hayashi

On 04.07.22 18:51, Shreyas.Karmahe@toshiba-tsip.com wrote:
> Hi Jan,
> 
> I have resend the patch again by removing the commented line from postinst file from security-customizations.
> The commenting line is dead code only and used for debugging purpose.
> Kindly review the following resend patch 
> 
> v2-0001-security-customizations-postinst-Add-configuratio.patch

Please read both of my replies and address the other one as well.

Thanks,
Jan

> 
> Kind Regards, 
> Shreyas
> -----Original Message-----
> From: Jan Kiszka <jan.kiszka@siemens.com> 
> Sent: Friday, July 1, 2022 5:04 PM
> To: karmahe shreyas(TSIP) <Shreyas.Karmahe@toshiba-tsip.com>; yes@arc11.toshiba.co.jp; cip-dev@lists.cip-project.org
> Cc: dinesh kumar(TSIP) <dinesh.kumar@toshiba-tsip.com>; pyla venkata(TSIP TMIEC ODG Porting) <Venkata.Pyla@toshiba-tsip.com>; hayashi kazuhiro(林 和宏 □SWC◯ACT) <kazuhiro3.hayashi@toshiba.co.jp>
> Subject: Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
> 
> On 01.07.22 13:32, Jan Kiszka wrote:
>> On 30.06.22 13:26, Shreyas.Karmahe@toshiba-tsip.com wrote:
>>> From: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>>
>>> To enable and configure PAM for Remote and Local MFA Session 
>>> Verification
>>>
>>> Signed-off-by: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>> ---
>>>  .../security-customizations/files/postinst        | 15 ++++++++++++++-
>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/recipes-core/security-customizations/files/postinst 
>>> b/recipes-core/security-customizations/files/postinst
>>> index bb7d15b..843ce3c 100644
>>> --- a/recipes-core/security-customizations/files/postinst
>>> +++ b/recipes-core/security-customizations/files/postinst
>>> @@ -15,7 +15,8 @@ echo "127.0.0.1 $HOSTNAME" >> /etc/hosts  
>>> PAM_PWD_FILE="/etc/pam.d/common-password"
>>>  pam_cracklib_config="password  requisite    pam_cracklib.so retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1  difok=3 gecoscheck=1 reject_username  enforce_for_root"
>>>  if grep -c "pam_cracklib.so" "${PAM_PWD_FILE}";then
>>> -        sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
>>> +        
>>> +sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
> 
> And an accidental change here?
> 
>>>  fi
>>>  sed -i "0,/^password.*/s/^password.*/${pam_cracklib_config}\n&/" "${PAM_PWD_FILE}"
>>>  
>>> @@ -49,3 +50,15 @@ sed -i 's/admin_space_left_action = 
>>> .*/admin_space_left_action = SYSLOG/' $AUDIT
>>>  
>>>  # CR2.10: Response to audit processing failures  sed -i 
>>> 's/disk_error_action = .*/disk_error_action = SYSLOG/' 
>>> $AUDIT_CONF_FILE
>>> +
>>> +# CR2.11: Enable Mutli Factor Authentication for Local and Remote 
>>> +Session SSHD_AUTH_CONFIG="/etc/pam.d/common-auth"
>>> +google_authenticator="auth required pam_google_authenticator.so nullok"
>>> +if grep -c "pam_google_authenticator.so" "${SSHD_AUTH_CONFIG}";then
>>> +		sed -i '/pam_google_authenticator.so/ s/^#*/#/'  "${SSHD_AUTH_CONFIG}"
>>> +fi
>>> +#sed -i "0,/^auth.*/s/^auth.*/${google_authenticator}\n&/" "${SSHD_AUTH_CONFIG}"
>>
>> Dead code? Or forgotten to activate?
>>
>>> +echo "auth required pam_google_authenticator.so nullok" | tee -a "${SSHD_AUTH_CONFIG}"
>>> +# Enable PAM configuration for Remote Session sed -i 
>>> +'s/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' "${SSHD_CONFIG}"
>>> +echo "AuthenticationMethods keyboard-interactive" | tee -a "${SSHD_CONFIG}"
>>
> 
> Jan
> 
> --
> Siemens AG, Technology
> Competence Center Embedded Linux


-- 
Siemens AG, Technology
Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 716+ messages in thread

* Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication
  2022-07-05 10:02         ` Jan Kiszka
@ 2022-07-07 10:46           ` Shreyas.Karmahe
  0 siblings, 0 replies; 716+ messages in thread
From: Shreyas.Karmahe @ 2022-07-07 10:46 UTC (permalink / raw)
  To: jan.kiszka, yes, cip-dev; +Cc: dinesh.kumar, Venkata.Pyla, kazuhiro3.hayashi

Hi Jan,

I have created new patch that has only contain configuration for libpam-google-authenticator for Multi-Factor Authentication and kept it for review.
My apology as last time I missed out one of your comment and these patch has addressed all unnecessarily spaces and lines that included it last time.
Please review and let me know your comments

Kind Regards,
Shreyas

-----Original Message-----
From: Jan Kiszka <jan.kiszka@siemens.com> 
Sent: Tuesday, July 5, 2022 3:33 PM
To: karmahe shreyas(TSIP TMIEC ODG Porting) <Shreyas.Karmahe@toshiba-tsip.com>; yes@arc11.toshiba.co.jp; cip-dev@lists.cip-project.org
Cc: dinesh kumar(TSIP) <dinesh.kumar@toshiba-tsip.com>; pyla venkata(TSIP TMIEC ODG Porting) <Venkata.Pyla@toshiba-tsip.com>; hayashi kazuhiro(林 和宏 □SWC◯ACT) <kazuhiro3.hayashi@toshiba.co.jp>
Subject: Re: [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication

On 04.07.22 18:51, Shreyas.Karmahe@toshiba-tsip.com wrote:
> Hi Jan,
> 
> I have resend the patch again by removing the commented line from postinst file from security-customizations.
> The commenting line is dead code only and used for debugging purpose.
> Kindly review the following resend patch
> 
> v2-0001-security-customizations-postinst-Add-configuratio.patch

Please read both of my replies and address the other one as well.

Thanks,
Jan

> 
> Kind Regards,
> Shreyas
> -----Original Message-----
> From: Jan Kiszka <jan.kiszka@siemens.com>
> Sent: Friday, July 1, 2022 5:04 PM
> To: karmahe shreyas(TSIP) <Shreyas.Karmahe@toshiba-tsip.com>; 
> yes@arc11.toshiba.co.jp; cip-dev@lists.cip-project.org
> Cc: dinesh kumar(TSIP) <dinesh.kumar@toshiba-tsip.com>; pyla 
> venkata(TSIP TMIEC ODG Porting) <Venkata.Pyla@toshiba-tsip.com>; 
> hayashi kazuhiro(林 和宏 □SWC◯ACT) <kazuhiro3.hayashi@toshiba.co.jp>
> Subject: Re: [isar-cip-core] postinst:Added lines to verify Local and 
> Remote Multi-factor Authentication
> 
> On 01.07.22 13:32, Jan Kiszka wrote:
>> On 30.06.22 13:26, Shreyas.Karmahe@toshiba-tsip.com wrote:
>>> From: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>>
>>> To enable and configure PAM for Remote and Local MFA Session 
>>> Verification
>>>
>>> Signed-off-by: Shreyas Karmahe <Shreyas.Karmahe@toshiba-tsip.com>
>>> ---
>>>  .../security-customizations/files/postinst        | 15 ++++++++++++++-
>>>  1 file changed, 14 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/recipes-core/security-customizations/files/postinst
>>> b/recipes-core/security-customizations/files/postinst
>>> index bb7d15b..843ce3c 100644
>>> --- a/recipes-core/security-customizations/files/postinst
>>> +++ b/recipes-core/security-customizations/files/postinst
>>> @@ -15,7 +15,8 @@ echo "127.0.0.1 $HOSTNAME" >> /etc/hosts 
>>> PAM_PWD_FILE="/etc/pam.d/common-password"
>>>  pam_cracklib_config="password  requisite    pam_cracklib.so retry=3 minlen=8 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1  difok=3 gecoscheck=1 reject_username  enforce_for_root"
>>>  if grep -c "pam_cracklib.so" "${PAM_PWD_FILE}";then
>>> -        sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
>>> +        
>>> +sed -i '/pam_cracklib.so/ s/^#*/#/'  "${PAM_PWD_FILE}"
> 
> And an accidental change here?
> 
>>>  fi
>>>  sed -i "0,/^password.*/s/^password.*/${pam_cracklib_config}\n&/" "${PAM_PWD_FILE}"
>>>  
>>> @@ -49,3 +50,15 @@ sed -i 's/admin_space_left_action = 
>>> .*/admin_space_left_action = SYSLOG/' $AUDIT
>>>  
>>>  # CR2.10: Response to audit processing failures  sed -i 
>>> 's/disk_error_action = .*/disk_error_action = SYSLOG/'
>>> $AUDIT_CONF_FILE
>>> +
>>> +# CR2.11: Enable Mutli Factor Authentication for Local and Remote 
>>> +Session SSHD_AUTH_CONFIG="/etc/pam.d/common-auth"
>>> +google_authenticator="auth required pam_google_authenticator.so nullok"
>>> +if grep -c "pam_google_authenticator.so" "${SSHD_AUTH_CONFIG}";then
>>> +		sed -i '/pam_google_authenticator.so/ s/^#*/#/'  "${SSHD_AUTH_CONFIG}"
>>> +fi
>>> +#sed -i "0,/^auth.*/s/^auth.*/${google_authenticator}\n&/" "${SSHD_AUTH_CONFIG}"
>>
>> Dead code? Or forgotten to activate?
>>
>>> +echo "auth required pam_google_authenticator.so nullok" | tee -a "${SSHD_AUTH_CONFIG}"
>>> +# Enable PAM configuration for Remote Session sed -i 
>>> +'s/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' "${SSHD_CONFIG}"
>>> +echo "AuthenticationMethods keyboard-interactive" | tee -a "${SSHD_CONFIG}"
>>
> 
> Jan
> 
> --
> Siemens AG, Technology
> Competence Center Embedded Linux


--
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 716+ messages in thread

end of thread, other threads:[~2022-07-07 10:46 UTC | newest]

Thread overview: 716+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <yes>
2009-01-16 18:08 ` Quota fixes and improvements Jan Kara
2009-01-16 18:08   ` [PATCH 01/11] quota: Improve locking Jan Kara
2009-01-16 18:08     ` [PATCH 02/11] ocfs2: Remove ocfs2_dquot_initialize() and ocfs2_dquot_drop() Jan Kara
2009-01-16 18:08       ` [PATCH 03/11] ocfs2: Push out dropping of dentry lock to ocfs2_wq Jan Kara
2009-01-16 18:08         ` [PATCH 04/11] ocfs2: Fix possible deadlock in ocfs2_write_dquot() Jan Kara
2009-01-16 18:08           ` [PATCH 05/11] quota: Add quota reservation support Jan Kara
2009-01-16 18:08             ` [PATCH 06/11] quota: Add quota reservation claim and released operations Jan Kara
2009-01-16 18:08               ` [PATCH 07/11] quota: Use inode->i_blkbits to get block bits Jan Kara
2009-01-16 18:08                 ` [PATCH 08/11] quota: Move EXPORT_SYMBOL immediately next to the functions/varibles Jan Kara
2009-01-16 18:08                   ` [PATCH 09/11] ext3: Remove unnecessary quota functions Jan Kara
2009-01-16 18:08                     ` [PATCH 10/11] ext4: " Jan Kara
2009-01-16 18:08                       ` [PATCH 11/11] reiserfs: " Jan Kara
2009-01-16 18:08                         ` Jan Kara
2009-01-20 21:41                       ` [PATCH 10/11] ext4: " Mingming Cao
2009-01-20 21:41                         ` Mingming Cao
2009-01-20 21:41                     ` [PATCH 09/11] ext3: " Mingming Cao
2009-01-20 21:41                       ` Mingming Cao
2009-01-24  7:49     ` [PATCH 01/11] quota: Improve locking Andrew Morton
2009-01-26 10:04       ` Jan Kara
2009-05-31 14:49 ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS tom.leiming
2009-05-31 14:49   ` [PATCH 1/8] kernel:lockdep:improve implementation of BFS tom.leiming
2009-05-31 14:49     ` [PATCH 2/8] kernel:lockdep: introduce match function to BFS tom.leiming
2009-05-31 14:49       ` [PATCH 3/8] kernel:lockdep:implement check_noncircular() by BFS tom.leiming
2009-05-31 14:49         ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards " tom.leiming
2009-05-31 14:49           ` [PATCH 5/8] kernel:lockdep:introduce print_shortest_lock_dependencies tom.leiming
2009-05-31 14:49             ` [PATCH 6/8] kernel:lockdep: implement lockdep_count_*ward_deps by BFS tom.leiming
2009-05-31 14:49               ` [PATCH 7/8] kernel:lockdep: update memory usage introduced " tom.leiming
2009-05-31 14:49                 ` [PATCH 8/8] kernel:lockdep:add statistics info for max bfs queue depth tom.leiming
2009-05-31 15:14           ` [PATCH 4/8] kernel:lockdep:implement find_usage_*wards by BFS Daniel Walker
2009-06-01  0:14             ` Ming Lei
2009-06-08 12:22   ` [PATCH 0/8] kernel:lockdep:replace DFS with BFS Peter Zijlstra
2009-06-08 13:38     ` Ming Lei
2009-06-08 13:58     ` Ming Lei
2009-06-08 14:04       ` Peter Zijlstra
2009-06-08 15:50     ` Ming Lei
2009-06-09 12:52       ` Ming Lei
2009-07-28 16:34 ` [U-Boot] [RFC 0/3] uboot-doc User's Manual Generation Tool John Schmoller
2009-07-28 17:49   ` Wolfgang Denk
2009-07-28 20:40     ` jschmoller
2009-07-28 21:27       ` Wolfgang Denk
2009-07-28 22:16         ` Robin Getz
2009-07-30  9:59           ` Detlev Zundel
2009-07-30 18:45             ` Wolfgang Denk
2009-07-30 19:50               ` Robin Getz
2009-07-30 19:55                 ` Wolfgang Denk
2009-07-31  1:49                   ` Robin Getz
2009-08-13  7:32             ` Mike Frysinger
2009-07-29 14:48         ` jschmoller
2009-07-28 16:34 ` [U-Boot] [RFC 1/3] uboot-doc: Initial support of user documentation generator John Schmoller
2009-07-28 16:34 ` [U-Boot] [RFC 2/3] uboot-doc: Add example support for uboot-doc John Schmoller
2009-07-28 17:52   ` Wolfgang Denk
2009-07-28 20:42     ` jschmoller
2009-07-28 21:37       ` Wolfgang Denk
2009-07-28 16:34 ` [U-Boot] [RFC 3/3] xpedite5370: Add uboot-doc support John Schmoller
2009-10-07 13:49 ` [PATCH 1/1] perf tools: Up the verbose level for some really verbose stuff Arnaldo Carvalho de Melo
2009-10-08 17:31   ` [tip:perf/core] " tip-bot for Arnaldo Carvalho de Melo
2010-06-22 15:20 ` [RFC][PATCH 00/10] cifs: local caching support using FS-Cache Suresh Jayaraman
2010-06-22 15:20   ` Suresh Jayaraman
2010-06-22 15:22 ` [RFC][PATCH 01/10] cifs: add kernel config option for CIFS Client caching support Suresh Jayaraman
2010-06-22 15:22 ` [RFC][PATCH 02/10] cifs: guard cifsglob.h against multiple inclusion Suresh Jayaraman
     [not found]   ` <1277220170-3442-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-22 21:37     ` Jeff Layton
2010-06-22 21:37       ` Jeff Layton
2010-06-22 15:23 ` [RFC][PATCH 03/10] cifs: register CIFS for caching Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
     [not found]   ` <1277220198-3522-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-22 21:52     ` Jeff Layton
2010-06-22 21:52       ` Jeff Layton
     [not found]       ` <20100622175214.4c56234f-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2010-06-23  5:34         ` Suresh Jayaraman
2010-06-23  5:34           ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them Suresh Jayaraman
2010-06-22 15:23   ` Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 06/10] cifs: define inode-level cache object " Suresh Jayaraman
2010-06-22 15:23 ` [RFC][PATCH 07/10] cifs: FS-Cache page management Suresh Jayaraman
2010-06-22 15:24 ` [RFC][PATCH 08/10] cifs: store pages into local cache Suresh Jayaraman
2010-06-22 15:24 ` [RFC][PATCH 09/10] cifs: read pages from FS-Cache Suresh Jayaraman
2010-06-22 15:24   ` Suresh Jayaraman
2010-06-22 15:25 ` [RFC][PATCH 10/10] cifs: add mount option to enable local caching Suresh Jayaraman
2010-06-22 15:25   ` Suresh Jayaraman
2010-06-23 18:32   ` Scott Lovenberg
     [not found]     ` <4C225338.9010807-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2010-06-25 10:48       ` Suresh Jayaraman
2010-06-25 10:48         ` Suresh Jayaraman
     [not found] ` <1277220189-3485-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 16:51   ` [RFC][PATCH 03/10] cifs: register CIFS for caching David Howells
2010-06-23 16:51     ` David Howells
     [not found]     ` <9603.1277311877-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 10:56       ` Suresh Jayaraman
2010-06-25 10:56         ` Suresh Jayaraman
2010-06-23 16:54 ` [RFC][PATCH 04/10] cifs: define server-level cache index objects and register them with FS-Cache David Howells
     [not found] ` <1277220206-3559-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 16:58   ` [RFC][PATCH 05/10] cifs: define superblock-level cache index objects and register them David Howells
2010-06-23 16:58     ` David Howells
     [not found]     ` <9720.1277312290-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 12:44       ` Suresh Jayaraman
2010-06-25 12:44         ` Suresh Jayaraman
2010-06-25 12:58     ` David Howells
     [not found]     ` <22746.1277470713-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 13:26       ` David Howells
2010-06-25 13:26         ` David Howells
     [not found]         ` <23204.1277472412-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-28 12:53           ` Suresh Jayaraman
2010-06-28 12:53             ` Suresh Jayaraman
2010-06-28 13:24         ` David Howells
     [not found] ` <1277220214-3597-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:02   ` [RFC][PATCH 06/10] cifs: define inode-level cache object " David Howells
2010-06-23 17:02     ` David Howells
     [not found]     ` <9822.1277312573-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 12:50       ` Suresh Jayaraman
2010-06-25 12:50         ` Suresh Jayaraman
     [not found]     ` <4C24A606.5040001-l3A5Bk7waGM@public.gmane.org>
2010-06-25 12:55       ` David Howells
2010-06-25 12:55         ` David Howells
     [not found]         ` <22697.1277470549-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-25 16:53           ` Jeff Layton
2010-06-25 16:53             ` Jeff Layton
2010-06-25 21:46         ` David Howells
2010-06-25 22:26           ` Jeff Layton
2010-06-25 22:26             ` Jeff Layton
2010-06-25 23:05             ` Steve French
2010-06-25 23:05               ` Steve French
2010-06-26  0:52               ` Mingming Cao
2010-06-27 18:17                 ` Aneesh Kumar K. V
     [not found]                   ` <871vbscpce.fsf-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
2010-06-27 18:22                     ` Christoph Hellwig
2010-06-27 18:22                       ` Christoph Hellwig
     [not found]           ` <20100625182651.36800d06-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2010-06-25 23:04             ` David Howells
2010-06-25 23:04               ` David Howells
2010-06-23 17:05 ` [RFC][PATCH 07/10] cifs: FS-Cache page management David Howells
     [not found] ` <1277220240-3674-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:06   ` [RFC][PATCH 08/10] cifs: store pages into local cache David Howells
2010-06-23 17:06     ` David Howells
     [not found] ` <1277220261-3717-1-git-send-email-sjayaraman-l3A5Bk7waGM@public.gmane.org>
2010-06-23 17:07   ` [RFC][PATCH 09/10] cifs: read pages from FS-Cache David Howells
2010-06-23 17:07     ` David Howells
2010-06-23 17:08 ` [RFC][PATCH 10/10] cifs: add mount option to enable local caching David Howells
2010-08-11  5:21 ` [PATCH v3] OpenRD: Enable SD/UART selection for serial port 1 Tanmay Upadhyay
2010-08-11  7:27   ` Russell King - ARM Linux
2011-02-03  9:49 ` [PATCH 1/7] usb: otg: enable regulator only on cable/device connect Hema HK
2011-02-03  9:49 ` [PATCH 2/7] usb: otg: Remove one unnecessary I2C read request Hema HK
2011-02-03  9:49 ` [PATCH 3/7] usb: otg: OMAP4430: Introducing suspend function for power management Hema HK
2011-02-03  9:49 ` [PATCH 4/7] usb: otg: OMAP4430: Add phy_suspend function pointer to twl4030_usb_data Hema HK
2011-02-03 13:45   ` Sergei Shtylyov
     [not found]     ` <4D4AB187.50406-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2011-02-04  5:23       ` Hema Kalliguddi
2011-02-03 13:50   ` Sergei Shtylyov
     [not found]     ` <4D4AB2A5.7000002-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
2011-02-04  6:03       ` Hema Kalliguddi
2011-02-03  9:49 ` [PATCH 5/7] usb: otg: TWL6030: Introduce the twl6030_phy_suspend function Hema HK
2011-02-03  9:49 ` [PATCH 6/7] usb: otg: TWL6030 Save the last event in otg_transceiver Hema HK
2011-02-03  9:49 ` [PATCH 7/7] usb: musb: OMAP4430: Fix usb device detection if connected during boot Hema HK
2011-02-14 10:05   ` Felipe Balbi
2011-02-15  8:23     ` Hema Kalliguddi
2011-04-13 22:08 ` [PATCH 2/2] ltp-ddt: New recipe to build ltp-ddt test tool Carlos Hernandez
2011-05-02 21:01 ` [U-Boot] [PATCH v4 0/5] Add support for LaCie NAS Network Space v2 Simon Guinot
2011-05-02 21:29   ` Wolfgang Denk
2011-05-02 22:46     ` Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 1/5] sf: disable write protection for Macronix flash Simon Guinot
2011-05-02 21:07   ` Mike Frysinger
2011-05-02 21:01 ` [U-Boot] [PATCH v4 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 4/5] netconsole: remove `serverip' check Simon Guinot
2011-05-02 21:01 ` [U-Boot] [PATCH v4 5/5] Add support for Network Space v2 Simon Guinot
2011-05-02 22:42 ` [U-Boot] [PATCH v5 0/5] Add support for LaCie NAS " Simon Guinot
2011-05-03  9:59   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 1/5] sf: disable write protection for Macronix flash Simon Guinot
2011-07-08 20:32   ` [U-Boot] [PATCH v6] sf: macronix: disable write protection when initializing Mike Frysinger
2011-08-02 20:02     ` Wolfgang Denk
2011-05-02 22:42 ` [U-Boot] [PATCH v5 2/5] Kirkwood: allow to override CONFIG_SYS_TCLK Simon Guinot
2011-05-03 12:09   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 3/5] mv-common.h: fix DRAM banks configuration Simon Guinot
2011-05-03 12:09   ` Prafulla Wadaskar
2011-05-02 22:42 ` [U-Boot] [PATCH v5 4/5] netconsole: remove `serverip' check Simon Guinot
2011-05-02 22:42 ` [U-Boot] [PATCH v5 5/5] Add support for Network Space v2 Simon Guinot
2011-05-03 13:19   ` Simon Guinot
2011-05-12 17:24     ` Wolfgang Denk
2011-06-15  0:46 ` [PATCH] Add ok2440 development board support Wu DaoGuang
2011-06-15  0:46   ` Wu DaoGuang
2011-06-22  5:55 ` [PATCH 3/3 v2] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-07-06 12:20   ` Daniel Mack
2011-07-06 12:44     ` Eric Miao
2011-07-21  4:54 ` [PATCHV2] OMAP4: OPP: add OMAP4460 definitions Vishwanath BS
2011-07-21  4:54   ` Vishwanath BS
     [not found] ` <4e27b0d0.100e8e0a.43e0.ffffe6d9SMTPIN_ADDED@mx.google.com>
2011-07-21  4:56   ` Vishwanath Sripathy
2011-07-21  4:56     ` Vishwanath Sripathy
2011-10-03  0:32 ` [PATCH 1/1] ARM: Make debug UART optional for S3C devices Thiago A. Correa
2011-10-03  0:32   ` Thiago A. Correa
2011-10-10 14:44   ` Thiago A. Corrêa
2011-10-10 14:44     ` Thiago A. Corrêa
2011-12-11 13:10 ` [PATCH] block: Needn't read the size of device or partition again taco
2012-01-08 15:28 ` [Qemu-devel] [PATCH] Add tab-completion for device_add Andrzej Zaborowski
2012-01-12 17:01   ` Anthony Liguori
2012-02-16  2:59 ` [U-Boot] [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
2012-02-23  8:59   ` [U-Boot] reminder for " Mohamed Haneef
2012-10-26 21:15   ` [U-Boot] " Albert ARIBAUD
2012-02-16  2:59 ` [U-Boot] [PATCH 1/5] msm7x30: Add support for low speed uart on msm7x30 mohamed.haneef at lntinfotech.com
2012-02-28 23:44   ` Albert ARIBAUD
2012-03-05 14:34   ` [U-Boot] [PATCH v2 1/5] msm7x30: Add Support " Mohamed Haneef
2012-03-22  8:50   ` [U-Boot] reminder for [PATCH 0/5] Support for qualcomm msm7630 board mohamed.haneef at lntinfotech.com
2012-04-23  9:24   ` [U-Boot] (no subject) mohamed.haneef at lntinfotech.com
2012-04-23  9:31   ` [U-Boot] msm7630 mainline request mohamed.haneef at lntinfotech.com
2012-05-03  0:09     ` Marek Vasut
2012-02-16  2:59 ` [U-Boot] [PATCH 2/5] msm7x30: Add support for interprocessor communication mohamed.haneef at lntinfotech.com
2012-02-28 23:46   ` Albert ARIBAUD
2012-03-05 14:33     ` Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 3/5] msm7x30: Add support for Qualcomm msm7630 soc mohamed.haneef at lntinfotech.com
2012-02-29  0:00   ` Albert ARIBAUD
2012-03-05 14:39   ` [U-Boot] [PATCH v2 3/5] msm7x30: Add support for msm7x30 SoC Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 4/5] Add support for mmc read and writes mohamed.haneef at lntinfotech.com
2012-02-29  0:03   ` Albert ARIBAUD
2012-03-05 14:40   ` [U-Boot] [PATCH v2 4/5] Add Support for qc_mmc MMC Controller Mohamed Haneef
2012-05-03 22:05     ` Andy Fleming
2012-05-10 11:37       ` Mohamed Haneef
2012-02-16  2:59 ` [U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board mohamed.haneef at lntinfotech.com
2012-10-03  8:19   ` Albert ARIBAUD
2012-06-08 17:23 ` [PATCH 1/4] slub: change declare of get_slab() to inline at all times Joonsoo Kim
2012-06-08 17:23   ` Joonsoo Kim
2012-06-08 17:23   ` [PATCH 2/4] slub: use __cmpxchg_double_slab() at interrupt disabled place Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-08 17:23   ` [PATCH 3/4] slub: refactoring unfreeze_partials() Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-20  7:19     ` Pekka Enberg
2012-06-20  7:19       ` Pekka Enberg
2012-06-08 17:23   ` [PATCH 4/4] slub: deactivate freelist of kmem_cache_cpu all at once in deactivate_slab() Joonsoo Kim
2012-06-08 17:23     ` Joonsoo Kim
2012-06-08 19:04     ` Christoph Lameter
2012-06-08 19:04       ` Christoph Lameter
2012-06-10 10:27       ` JoonSoo Kim
2012-06-10 10:27         ` JoonSoo Kim
2012-06-22 18:34         ` JoonSoo Kim
2012-06-22 18:34           ` JoonSoo Kim
2012-06-08 19:02   ` [PATCH 1/4] slub: change declare of get_slab() to inline at all times Christoph Lameter
2012-06-08 19:02     ` Christoph Lameter
2012-06-09 15:57     ` JoonSoo Kim
2012-06-09 15:57       ` JoonSoo Kim
2012-06-11 15:04       ` Christoph Lameter
2012-06-11 15:04         ` Christoph Lameter
2012-06-22 18:22 ` [PATCH 1/3] slub: prefetch next freelist pointer in __slab_alloc() Joonsoo Kim
2012-06-22 18:22   ` Joonsoo Kim
2012-06-22 18:22   ` [PATCH 2/3] slub: reduce failure of this_cpu_cmpxchg in put_cpu_partial() after unfreezing Joonsoo Kim
2012-06-22 18:22     ` Joonsoo Kim
2012-07-04 13:05     ` Pekka Enberg
2012-07-04 13:05       ` Pekka Enberg
2012-07-05 14:20       ` Christoph Lameter
2012-07-05 14:20         ` Christoph Lameter
2012-08-16  7:06     ` Pekka Enberg
2012-08-16  7:06       ` Pekka Enberg
2012-06-22 18:22   ` [PATCH 3/3] slub: release a lock if freeing object with a lock is failed in __slab_free() Joonsoo Kim
2012-06-22 18:22     ` Joonsoo Kim
2012-07-04 13:10     ` Pekka Enberg
2012-07-04 13:10       ` Pekka Enberg
2012-07-04 14:48       ` JoonSoo Kim
2012-07-04 14:48         ` JoonSoo Kim
2012-07-05 14:26     ` Christoph Lameter
2012-07-05 14:26       ` Christoph Lameter
2012-07-06 14:19       ` JoonSoo Kim
2012-07-06 14:19         ` JoonSoo Kim
2012-07-06 14:34         ` Christoph Lameter
2012-07-06 14:34           ` Christoph Lameter
2012-07-06 14:59           ` JoonSoo Kim
2012-07-06 14:59             ` JoonSoo Kim
2012-07-06 15:10             ` Christoph Lameter
2012-07-06 15:10               ` Christoph Lameter
2012-07-08 16:19               ` JoonSoo Kim
2012-07-08 16:19                 ` JoonSoo Kim
2012-06-22 18:45   ` [PATCH 1/3 v2] slub: prefetch next freelist pointer in __slab_alloc() Joonsoo Kim
2012-06-22 18:45     ` Joonsoo Kim
2012-07-04 12:58     ` JoonSoo Kim
2012-07-04 12:58       ` JoonSoo Kim
2012-07-04 13:00     ` Pekka Enberg
2012-07-04 13:00       ` Pekka Enberg
2012-07-04 14:30       ` JoonSoo Kim
2012-07-04 14:30         ` JoonSoo Kim
2012-07-04 15:08         ` Pekka Enberg
2012-07-04 15:08           ` Pekka Enberg
2012-07-04 15:26           ` Eric Dumazet
2012-07-04 15:26             ` Eric Dumazet
2012-07-04 15:48             ` JoonSoo Kim
2012-07-04 15:48               ` JoonSoo Kim
2012-07-04 16:15               ` Eric Dumazet
2012-07-04 16:15                 ` Eric Dumazet
2012-07-04 16:24                 ` JoonSoo Kim
2012-07-04 16:24                   ` JoonSoo Kim
2012-07-04 15:45           ` JoonSoo Kim
2012-07-04 15:45             ` JoonSoo Kim
2012-07-04 15:59             ` Pekka Enberg
2012-07-04 15:59               ` Pekka Enberg
2012-07-04 16:04               ` JoonSoo Kim
2012-07-04 16:04                 ` JoonSoo Kim
2012-08-10  9:35 ` [PATCH BlueZ V5 1/5] AVRCP: Add TG Record to support AVRCP Browsing Vani-dineshbhai PATEL
2012-08-13 11:27   ` Luiz Augusto von Dentz
2012-08-13 11:49     ` Michal.Labedzki
2012-08-13 12:15       ` Luiz Augusto von Dentz
2012-09-20  7:28 ` [PATCH] mac80211 : Fix Ibss debug message Tx authentication yes
2012-09-20  7:55   ` Johannes Berg
2012-11-16  8:53 ` [PATCH] python: fix for Security Advisory - python - CVE-2012-2135 yanjun.zhu
2012-11-16 12:21   ` Otavio Salvador
2012-11-19  2:26     ` yzhu1
2012-11-19  2:36       ` yzhu1
2012-11-19 10:21         ` Otavio Salvador
2012-11-29 14:07   ` Paul Eggleton
2012-11-30  2:49     ` yzhu1
2013-02-07 17:33 ` [PATCH 00/10] usb: ehci: more bus glues as separate modules manjunath.goudar at linaro.org
2013-02-07 20:13   ` Ezequiel Garcia
2013-02-08 15:23   ` Alan Stern
     [not found] ` <1360258447-27247-1-git-send-email-yes>
2013-02-07 17:33   ` [PATCH 01/10] USB:Changed omap2plus_defconfig to support OMAP USB static driver manjunath.goudar at linaro.org
2013-02-07 17:33   ` [PATCH 02/10] USB: EHCI: make ehci-omap a separate driver manjunath.goudar at linaro.org
2013-02-08  7:42     ` Felipe Balbi
2013-02-08  8:56       ` Roger Quadros
2013-02-07 17:34   ` [PATCH 03/10] USB: EHCI: make ehci-spear " manjunath.goudar at linaro.org
2013-02-08  4:27     ` Viresh Kumar
2013-02-07 17:34   ` [PATCH 04/10] USB: EHCI: make ehci-orion " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 19:41     ` Arnd Bergmann
2013-02-07 19:41       ` Arnd Bergmann
2013-02-08 10:38     ` Florian Fainelli
2013-02-08 10:38       ` Florian Fainelli
2013-02-07 17:34   ` [PATCH 05/10] USB: EHCI: make ehci-atmel " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-08  2:58     ` Bo Shen
2013-02-08  2:58       ` Bo Shen
2013-06-12 11:53     ` Jean-Christophe PLAGNIOL-VILLARD
2013-06-12 11:53       ` Jean-Christophe PLAGNIOL-VILLARD
2013-02-07 17:34   ` [PATCH 06/10] USB: EHCI: make ehci-s5p " manjunath.goudar at linaro.org
2013-02-07 18:49     ` Stephen Warren
2013-02-07 17:34   ` [PATCH 07/10] USB: EHCI: make ehci-mv " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 17:34   ` [PATCH 08/10] USB: EHCI: make ehci-vt8500 " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 18:54     ` Tony Prisk
2013-02-07 18:54       ` Tony Prisk
2013-02-07 17:34   ` [PATCH 09/10] USB: EHCI: make ehci-msm " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-02-07 18:48     ` Stephen Warren
2013-02-07 18:48       ` Stephen Warren
2013-02-07 19:05     ` David Brown
2013-02-07 19:05       ` David Brown
2013-02-07 17:34   ` [PATCH 10/10] USB: EHCI: make ehci-w90X900 " manjunath.goudar
2013-02-07 17:34     ` manjunath.goudar at linaro.org
2013-03-09 15:39 ` [meta-fsl-arm][PATCH] imx-base: add imx6dl mapping for firmware John Weber
2013-03-09 19:05   ` Otavio Salvador
2013-03-12 19:16 ` [fsl-community-bsp-base][PATCH] Add Wandboard Dual to README John Weber
2013-03-12 19:20   ` Otavio Salvador
2013-03-16 13:45 ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): remove staging driver for brcm80211 John Weber
2013-03-16 14:39     ` Otavio Salvador
2013-03-17  1:08       ` John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): add brcm80211 driver backported from v3.5 John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): enable brcm wifi in wandboard dual defconfig John Weber
2013-03-16 14:32     ` Otavio Salvador
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): wandboard: add brcm80211 support to bbappend John Weber
2013-03-16 14:31     ` Otavio Salvador
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] linux-firmware: add support for bcm4329 John Weber
2013-03-16 14:31     ` Otavio Salvador
2013-03-17  0:40       ` John Weber
2013-03-16 13:45   ` [meta-fsl-arm-extra][PATCH] conf/machine: add firmware rrecomends to wandboard-dual John Weber
2013-03-16 14:23   ` [meta-fsl-arm-extra][PATCH] linux-imx (3.0.35): fix sdhc platform data Otavio Salvador
2013-03-18 20:25 ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 1/5] linux-imx (3.0.35): wandboard: fix sdhc platform data John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 2/5] linux-imx (3.0.35): wandboard: replace brcm80211 driver John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 3/5] linux-firmware: Add bbappend to include Broadcom wifi drivers John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 4/5] wandboard-wifi-support: add nvram file and create firmware links John Weber
2013-03-18 20:25   ` [meta-fsl-arm-extra][PATCH v2 5/5] wandboard-dual: Add wandboard-wifi-support to machine John Weber
2013-03-22  3:05   ` [meta-fsl-arm-extra][PATCH v2 0/5] Enable wifi support for Wandboard Dual Otavio Salvador
2013-03-22  8:13     ` Eric Bénard
2013-03-22 12:30       ` Otavio Salvador
2013-03-22 14:17         ` Eric Bénard
2013-03-22 14:23         ` Eric Bénard
2013-03-23 15:44           ` Otavio Salvador
2013-03-25  2:18             ` Fabio Estevam
2013-03-25  2:20               ` John Weber
2013-06-10  9:17 ` [PATCH v2 00/11] ARM:STixxxx: Add STixxxx platform and board support Srinivas KANDAGATLA
2013-06-10  9:17   ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 01/11] serial:st-asc: Add ST ASC driver Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:35     ` Russell King - ARM Linux
2013-06-10  9:35       ` Russell King - ARM Linux
2013-06-10  9:35       ` Russell King - ARM Linux
2013-06-10 11:53       ` Srinivas KANDAGATLA
2013-06-10 11:53         ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 02/11] clocksource:global_timer: Add ARM global timer support Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
     [not found]     ` <1370856087-6452-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 13:13       ` Linus Walleij
2013-06-10 13:13         ` Linus Walleij
     [not found]         ` <CACRpkdbQCRKBzRF4HzNsXHwXCLJJcFZ9T36GPmmYsnX1OfgGRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-06-10 13:41           ` Srinivas KANDAGATLA
2013-06-10 13:41             ` Srinivas KANDAGATLA
2013-06-11 14:05             ` Srinivas KANDAGATLA
2013-06-11 14:05               ` Srinivas KANDAGATLA
     [not found]               ` <51B72E9A.6070006-qxv4g6HH51o@public.gmane.org>
2013-06-11 20:13                 ` Linus Walleij
2013-06-11 20:13                   ` Linus Walleij
2013-06-12 10:45                   ` Srinivas KANDAGATLA
2013-06-12 10:45                     ` Srinivas KANDAGATLA
2013-06-12 10:45                     ` Srinivas KANDAGATLA
2013-06-10  9:21   ` [PATCH v2 03/11] regmap: Add regmap_field APIs Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-10  9:21     ` Srinivas KANDAGATLA
2013-06-11 10:48     ` Mark Brown
2013-06-11 10:48       ` Mark Brown
2013-06-11 10:48       ` Mark Brown
2013-06-11 11:36       ` Srinivas KANDAGATLA
2013-06-11 11:36         ` Srinivas KANDAGATLA
2013-06-11 11:36         ` Srinivas KANDAGATLA
2013-06-10  9:22   ` [PATCH v2 04/11] mfd:stixxxx-syscfg: Add ST System Configuration support Srinivas KANDAGATLA
2013-06-10  9:22     ` Srinivas KANDAGATLA
     [not found]     ` <1370856147-6552-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 13:16       ` Linus Walleij
2013-06-10 13:16         ` Linus Walleij
2013-06-10 13:52         ` Srinivas KANDAGATLA
2013-06-10 13:52           ` Srinivas KANDAGATLA
2013-06-10 13:52           ` Srinivas KANDAGATLA
2013-06-10 14:02           ` Arnd Bergmann
2013-06-10 14:02             ` Arnd Bergmann
2013-06-10 14:02             ` Arnd Bergmann
2013-06-10 15:51             ` Srinivas KANDAGATLA
2013-06-10 15:51               ` Srinivas KANDAGATLA
2013-06-10 15:51               ` Srinivas KANDAGATLA
2013-06-11  7:41             ` Srinivas KANDAGATLA
2013-06-11  7:41               ` Srinivas KANDAGATLA
2013-06-11  7:41               ` Srinivas KANDAGATLA
2013-06-10  9:22   ` [PATCH v2 05/11] pinctrl:stixxxx: Add pinctrl and pinconf support Srinivas KANDAGATLA
2013-06-10  9:22     ` Srinivas KANDAGATLA
     [not found]     ` <1370856161-6600-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-16 12:17       ` Linus Walleij
2013-06-16 12:17         ` Linus Walleij
2013-06-17 13:31         ` Srinivas KANDAGATLA
2013-06-17 13:31           ` Srinivas KANDAGATLA
     [not found]           ` <51BF0FC2.4000601-qxv4g6HH51o@public.gmane.org>
2013-06-17 16:27             ` Linus Walleij
2013-06-17 16:27               ` Linus Walleij
2013-06-10  9:26   ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
2013-06-10  9:26     ` =?yes?q?=5BPATCH=20v2=2006/11=5D=20ARM=3Astixxxx=3A=20Add=20STiH415=20SOC=20support?= Srinivas KANDAGATLA
2013-06-10  9:55     ` [PATCH v2 06/11] ARM:stixxxx: Add STiH415 SOC support Michal Simek
2013-06-10  9:55       ` Michal Simek
2013-06-10 11:08     ` Michal Simek
2013-06-10 11:08       ` Michal Simek
     [not found]     ` <CAHTX3d+dk3W_9b7SVUokWq4KYXnj=Z1=WPj5zJ-gUvJqqwE=+Q@mail.gmail.com>
2013-06-10 11:46       ` Srinivas KANDAGATLA
2013-06-10 11:46         ` Srinivas KANDAGATLA
2013-06-10 11:46         ` Srinivas KANDAGATLA
2013-06-10 23:19         ` Russell King - ARM Linux
2013-06-10 23:19           ` Russell King - ARM Linux
2013-06-10 23:19           ` Russell King - ARM Linux
2013-06-11  6:50           ` Srinivas KANDAGATLA
2013-06-11  6:50             ` Srinivas KANDAGATLA
2013-06-11  6:50             ` Srinivas KANDAGATLA
2013-06-13 11:56             ` Russell King - ARM Linux
2013-06-13 11:56               ` Russell King - ARM Linux
2013-06-13 11:56               ` Russell King - ARM Linux
2013-06-13 12:41               ` Srinivas KANDAGATLA
2013-06-13 12:41                 ` Srinivas KANDAGATLA
2013-06-13 12:41                 ` Srinivas KANDAGATLA
2013-06-13 12:47           ` Linus Walleij
2013-06-13 12:47             ` Linus Walleij
2013-06-13 12:47             ` Linus Walleij
     [not found]     ` <1370856381-6644-1-git-send-email-srinivas.kandagatla-qxv4g6HH51o@public.gmane.org>
2013-06-10 12:43       ` Linus Walleij
2013-06-10 12:43         ` Linus Walleij
     [not found]         ` <CACRpkdZ-xnDO+bte4tyKDWwY4A_qWUhLru3dUmuY9MQwseP3uQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-06-10 16:38           ` Srinivas KANDAGATLA
2013-06-10 16:38             ` Srinivas KANDAGATLA
     [not found]             ` <51B6011E.1060909-qxv4g6HH51o@public.gmane.org>
2013-06-14  7:31               ` Srinivas KANDAGATLA
2013-06-14  7:31                 ` Srinivas KANDAGATLA
     [not found]                 ` <51BAC6EC.8000703-qxv4g6HH51o@public.gmane.org>
2013-06-19 18:59                   ` Linus Walleij
2013-06-19 18:59                     ` Linus Walleij
2013-06-10  9:27   ` [PATCH v2 07/11] ARM:stixxxx: Add STiH416 " Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10 13:52     ` Arnd Bergmann
2013-06-10 13:52       ` Arnd Bergmann
2013-06-10 16:17       ` Srinivas KANDAGATLA
2013-06-10 16:17         ` Srinivas KANDAGATLA
2013-06-14  7:12       ` Srinivas KANDAGATLA
2013-06-14  7:12         ` Srinivas KANDAGATLA
2013-06-19 18:34       ` Linus Walleij
2013-06-19 18:34         ` Linus Walleij
2013-06-10  9:27   ` [PATCH v2 08/11] ARM:stixxxx: Add DEBUG_LL console support Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10  9:27   ` [PATCH v2 09/11] ARM:stixxxx: Add stixxxx options to multi_v7_defconfig Srinivas KANDAGATLA
2013-06-10  9:27     ` Srinivas KANDAGATLA
2013-06-10 10:40     ` Mark Rutland
2013-06-10 10:40       ` Mark Rutland
2013-06-10 10:40       ` Mark Rutland
2013-06-10 10:58       ` Srinivas KANDAGATLA
2013-06-10 10:58         ` Srinivas KANDAGATLA
2013-06-10 10:58         ` Srinivas KANDAGATLA
2013-06-10 13:15         ` Mark Rutland
2013-06-10 13:15           ` Mark Rutland
2013-06-10 13:15           ` Mark Rutland
2013-06-13  9:24           ` Srinivas KANDAGATLA
2013-06-13  9:24             ` Srinivas KANDAGATLA
2013-06-13  9:24             ` Srinivas KANDAGATLA
2013-06-17  9:32             ` Mark Rutland
2013-06-17  9:32               ` Mark Rutland
2013-06-17  9:32               ` Mark Rutland
2013-06-10  9:28   ` [PATCH v2 10/11] ARM:stih41x: Add B2000 board support Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28   ` [PATCH v2 11/11] ARM:stih41x: Add B2020 " Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-06-10  9:28     ` Srinivas KANDAGATLA
2013-09-10  9:25 ` [PATCH 0/1] ideas to improve the write performance of cluster dm-raid1 dongmao zhang
2013-09-10  9:25   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
2013-09-12  8:42 ` [PATCH 1/1] OMAPDSS: Return right error during connector probe Sathya Prakash M R
2013-09-16  9:41   ` Tomi Valkeinen
2013-10-28 10:07 ` [PATCH 0/1] patches to improve cluster raid1 performance [V3] dongmao zhang
2013-10-28 10:07   ` [PATCH 1/1] improve the performance of dm-log-userspace dongmao zhang
2013-10-30  1:35     ` Brassow Jonathan
2013-10-28 10:17 ` [PATCH 0/2] cmirror patch to improve cluster raid1 performance[v3] dongmao zhang
2013-10-28 10:17   ` [PATCH 1/2] add integrated_flush support to device-mapper dongmao zhang
2013-10-28 10:17     ` [PATCH 2/2] cmirrord support DM_INTEGRATED_FLUSH dongmao zhang
2013-10-30  1:48       ` Brassow Jonathan
2013-10-30  1:47     ` [PATCH 1/2] add integrated_flush support to device-mapper Brassow Jonathan
2014-01-13  6:51 ` [PATCH 0/2] Optimization on intel HDMI detect and get_modes Ramalingam C
2014-01-13  6:51   ` [PATCH 1/2] drm/i915: HDMI detection based on HPD pin live status Ramalingam C
2014-01-13  6:51   ` [PATCH 2/2] drm/i915: Optimize EDID retrival on detect and get_modes Ramalingam C
2014-01-13  7:29   ` [PATCH 0/2] Optimization on intel HDMI " Daniel Vetter
2014-01-13  9:39     ` Sharma, Shashank
2014-01-13 13:26       ` Daniel Vetter
2014-01-13 17:19         ` Sharma, Shashank
2014-04-09  6:19           ` Wang, Quanxian
2014-04-09  6:50             ` Sharma, Shashank
2014-04-10  6:46               ` Sharma, Shashank
2014-04-10  8:08                 ` Daniel Vetter
2014-04-10  8:10                   ` Sharma, Shashank
2014-04-10 10:42                 ` Wang, Quanxian
     [not found]                   ` <FF3DDC77922A8A4BB08A3BC48A1EA8CB01692A7B@BGSMSX101.gar.corp.intel.com>
2014-04-11 12:58                     ` Daniel Vetter
2014-04-11 13:23                       ` Sharma, Shashank
2014-04-11 14:22                         ` Daniel Vetter
2014-04-11 14:48                           ` Sharma, Shashank
2014-07-16 14:29                             ` Kumar, Shobhit
2014-02-07 23:23 ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 1/7] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
2014-02-10 21:25     ` Tom Rini
2014-02-11  1:05       ` Vitaly Andrianov
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 2/7] tools: sort the entries in Makefile Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 3/7 v1] tools: mkimage: add support for gpimage format Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 4/7 v1] arm: add support for arch timer Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 5/7 v1] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
2014-02-07 23:23   ` [U-Boot] [U-Boot:RESEND][[PATCH 6/7] k2hk: add support for k2hk SOC and EVM Murali Karicheri
2014-02-10 21:25     ` Tom Rini
2014-02-11  1:44       ` Vitaly Andrianov
2014-02-12 12:53         ` Tom Rini
2014-02-17 21:19       ` Andrianov, Vitaly
2014-02-17 21:57         ` Tom Rini
2014-02-20 17:27           ` Andrianov, Vitaly
2014-02-10  8:32   ` [U-Boot] [U-Boot: RESEND][PATCH 0/7] Add support for Keystone2 SoC and K2HK EVM Albert ARIBAUD
2014-02-10 17:22     ` Murali Karicheri
2014-02-10 18:01       ` Albert ARIBAUD
2014-02-10 19:42         ` Murali Karicheri
2014-02-10 19:58           ` Albert ARIBAUD
2014-02-10 21:23   ` Tom Rini
2014-02-20 17:55 ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 " Murali Karicheri
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 01/12] fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() Murali Karicheri
2014-02-25 22:10     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 02/12] tools: sort the entries in Makefile Murali Karicheri
2014-02-25 22:10     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 03/12] tools: mkimage: add support for gpimage format Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 04/12] arm: add support for arch timer Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 05/12] NAND: DaVinci: allow forced disable of subpage writes Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-26  4:01     ` Scott Wood
2014-02-27 16:38       ` Murali Karicheri
     [not found]       ` <3E54258959B69E4282D79E01AB1F32B7046C27D5@DFLE11.ent.ti.com>
2014-02-27 19:21         ` Scott Wood
2014-02-27 21:20           ` Murali Karicheri
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 06/12] i2c, davinci: move i2c_defs.h to the drivers/i2c directory Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 07/12] i2c, davinci: add support for multiple i2c buses Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-03-03 18:20       ` Murali Karicheri
2014-03-03 18:29         ` Tom Rini
2014-03-06 19:09       ` Andrianov, Vitaly
2014-03-06 19:29         ` Tom Rini
2014-03-07 16:41           ` Andrianov, Vitaly
2014-03-07 16:50             ` Tom Rini
2014-03-07 21:21       ` Murali Karicheri
2014-03-07 21:27         ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 09/12] keystone2: add keystone multicore navigator driver Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 10/12] keystone2: net: add keystone ethernet driver Murali Karicheri
2014-02-25 22:11     ` Tom Rini
2014-03-12 19:04       ` Murali Karicheri
2014-03-12 20:01         ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 11/12] spi: davinci: add support for multiple bus and chip select Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-20 17:55   ` [U-Boot] [U-Boot PATCH v2 12/12] k2hk-evm: add configuration for spi1 and spi2 support Murali Karicheri
2014-02-25 22:12     ` Tom Rini
2014-02-25 22:10   ` [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM Tom Rini
2014-02-27 16:18     ` Karicheri, Muralidharan
2014-03-12 19:21     ` Murali Karicheri
2014-03-12 19:35       ` Tom Rini
2014-02-25 22:49   ` Karicheri, Muralidharan
2014-02-25 22:51     ` Tom Rini
2014-08-12  6:40 ` [PATCH v3] uas: replace WARN_ON_ONCE() with lockdep_assert_held() Sanjeev Sharma
2014-08-12  6:40   ` Sanjeev Sharma
2014-08-12  6:28   ` Hans de Goede
2014-08-12  6:37     ` Sharma, Sanjeev
2014-08-19  6:33     ` Sharma, Sanjeev
2014-08-19  6:33       ` Sharma, Sanjeev
2014-08-19  9:30       ` gregkh
2014-08-19  9:38         ` Sharma, Sanjeev
2014-08-19  9:38           ` Sharma, Sanjeev
2014-09-04  7:06         ` Sharma, Sanjeev
2014-09-04 13:50 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c linux.delve
2014-09-04 13:51   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool linux.delve
2014-09-04 14:09 ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Chaitra Ramaiah
2014-09-04 14:09   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c This is a patch to the file r819xU_firmware.c that fixes a brace warning found by checkpatch.pl tool Chaitra Ramaiah
2014-09-04 14:28     ` Greg KH
2014-09-04 14:33     ` Dan Carpenter
2014-09-04 14:27   ` [PATCH] Staging: rtl8192u: fix brace style coding issue in r819xU_firmware.c Greg KH
2014-10-29 20:28 ` [PATCH v2 0/4] Enable PCI controller for Keystone SoCs Murali Karicheri
2014-10-29 20:28   ` Murali Karicheri
2014-10-29 20:28   ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 1/4] ARM: keystone: add pcie related options Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 2/4] ARM: keystone: defconfig: add options to enable PCI controller Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 3/4] ARM: dts: keystone: add DT bindings for PCI controller for port 0 Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28   ` [PATCH v2 4/4] ARM: dts: keystone-k2e: add DT bindings for PCI controller for port 1 Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 20:28     ` Murali Karicheri
2014-10-29 21:10   ` [PATCH v2 0/4] Enable PCI controller for Keystone SoCs santosh shilimkar
2014-10-29 21:10     ` santosh shilimkar
2015-02-12  7:56 ` [PATCH] pinctrl: mediatek: Fix build error in Mediatek pinctrl driver Hongzhou Yang
2015-02-20 10:04   ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-02-20 10:04     ` Linus Walleij
2015-07-27  8:16 ` [PATCH v1] mmc: sprd: add MMC host driver for Spreadtrum SoC Billows Wu
2015-10-19  2:27 ` [RFC PATCH] qspinlock: Improve performance by reducing load instruction rollback ling.ma.program
2015-10-19  7:58   ` Ingo Molnar
2015-10-19  9:34     ` Peter Zijlstra
2015-10-19 11:24       ` Ingo Molnar
2015-10-19 17:24         ` Waiman Long
2015-10-20  2:57     ` Ling Ma
2015-10-20  8:48       ` Ingo Molnar
2015-10-21  5:28         ` Ling Ma
2015-10-21  7:54           ` Peter Zijlstra
2015-10-20  9:15       ` Peter Zijlstra
2015-10-19  9:33   ` Peter Zijlstra
2015-10-19 17:20     ` Waiman Long
2015-10-20  3:00     ` Ling Ma
2015-10-19  9:46   ` Peter Zijlstra
2015-10-20  3:03     ` Ling Ma
2015-10-20  3:24     ` Ling Ma
2015-10-20  9:16       ` Peter Zijlstra
2015-10-21  5:30         ` Ling Ma
2015-10-19 17:18   ` Waiman Long
2015-10-20  3:12     ` Ling Ma
2015-10-20 18:55       ` Waiman Long
2015-10-21  5:43         ` Ling Ma
2015-12-31  8:09 ` [RFC PATCH] alispinlock: acceleration from lock integration on multi-core platform ling.ma.program
2016-01-05 18:46   ` Waiman Long
2016-01-08 22:48     ` Ling Ma
2016-01-05 21:18   ` Peter Zijlstra
2016-01-05 21:42     ` One Thousand Gnomes
2016-01-06  8:16       ` Peter Zijlstra
2016-01-06  8:21         ` Peter Zijlstra
2016-01-06 11:24           ` One Thousand Gnomes
2016-01-08 22:44             ` Ling Ma
2016-01-12 13:50               ` One Thousand Gnomes
2016-01-14  8:10                 ` Ling Ma
2016-01-19  8:52                   ` Ling Ma
2016-01-19 15:36                     ` Waiman Long
2016-02-03  4:40                       ` Ling Ma
2016-02-03  6:00                         ` Ling Ma
2016-02-03 21:42                         ` Waiman Long
2016-02-04  7:07                           ` Ling Ma
2016-04-05  3:44                           ` Ling Ma
2016-04-11  8:00                             ` Ling Ma
2016-01-08 23:01       ` Ling Ma
2016-01-08 22:56     ` Ling Ma
2018-12-12 11:35 ` [PATCH] doc: add meson ut enhancements in prog guide Hari Kumar Vemula
2019-01-20 12:04   ` Thomas Monjalon
2019-01-23  6:37   ` [PATCH v2] doc: add meson ut info " Hari Kumar Vemula
2019-01-23 10:53     ` Bruce Richardson
2019-01-24 13:41     ` [PATCH v3] " Hari Kumar Vemula
2019-01-24 14:15       ` Richardson, Bruce
2019-01-25  6:20       ` [PATCH v4] " Hari Kumar Vemula
2019-01-31 14:49         ` Bruce Richardson
2019-02-02 10:28         ` [PATCH v5] " Hari Kumar Vemula
2019-03-04 17:05           ` Bruce Richardson
2019-04-22 22:35           ` [dpdk-dev] " Thomas Monjalon
2019-05-01 11:39             ` Mcnamara, John
2019-06-06 11:59           ` [dpdk-dev] [PATCH v6] " Hari Kumar Vemula
2019-07-08 19:40             ` Thomas Monjalon
2019-07-08 20:18               ` Aaron Conole
2019-07-09 18:57                 ` Michael Santana Francisco
2019-07-22 12:39                   ` Parthasarathy, JananeeX M
2019-07-22 12:53                     ` Thomas Monjalon
2019-07-22 13:53                       ` Bruce Richardson
2019-07-23 11:34                         ` Parthasarathy, JananeeX M
2019-08-07 13:56             ` [dpdk-dev] [PATCH v7] " Agalya Babu RadhaKrishnan
2019-08-07 14:16               ` Jerin Jacob Kollanukkaran
2019-08-07 15:47               ` Michael Santana Francisco
2019-08-12 12:40               ` [dpdk-dev] [PATCH v8] " Jananee Parthasarathy
2020-02-16 10:28                 ` Thomas Monjalon
2019-01-03 12:28 ` [PATCH v2] eal: fix core number validation Hari kumar Vemula
2019-01-03 13:03   ` David Marchand
2019-01-07  7:05   ` Hari Kumar Vemula
2019-01-07 10:25   ` [PATCH v3] " Hari Kumar Vemula
2019-01-10 10:11     ` David Marchand
2019-01-11 14:15   ` [PATCH v4] " Hari Kumar Vemula
2019-01-11 15:06     ` David Marchand
2019-01-14 10:28     ` [PATCH v5] " Hari Kumar Vemula
2019-01-14 14:39       ` David Marchand
2019-01-17 12:13     ` [PATCH v6] " Hari Kumar Vemula
2019-01-17 12:19       ` Bruce Richardson
2019-01-17 12:32         ` David Marchand
2019-01-17 16:31       ` [dpdk-stable] " Thomas Monjalon
2019-01-07 13:01 ` [PATCH] net/bonding: fix create bonded device test failure Hari Kumar Vemula
2019-01-07 18:44   ` Chas Williams
2019-01-08 10:27     ` [dpdk-stable] " Ferruh Yigit
2019-01-08 11:14     ` Vemula, Hari KumarX
2019-01-15 17:37   ` Pattan, Reshma
2019-01-28  7:28   ` [PATCH v2] " Hari Kumar Vemula
2019-01-31 23:40     ` Chas Williams
2019-02-05 13:39     ` [PATCH v3] " Hari Kumar Vemula
2019-02-07 13:34       ` [dpdk-stable] " Ferruh Yigit
2019-12-04  9:36 ` [PATCH] i386: pass CLZERO to guests with EPYC CPU model on AMD ZEN platform Ani Sinha
2019-12-16  9:31   ` Ani Sinha
     [not found] ` <20220630112644.3682066-1-Shreyas.Karmahe@toshiba-tsip.com>
2022-07-01 11:32   ` [isar-cip-core] postinst:Added lines to verify Local and Remote Multi-factor Authentication Jan Kiszka
2022-07-01 11:33     ` Jan Kiszka
2022-07-04 16:51       ` Shreyas.Karmahe
2022-07-05 10:02         ` Jan Kiszka
2022-07-07 10:46           ` Shreyas.Karmahe
2011-05-02  5:59 ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-05-02  5:59 ` [PATCH 1/3] ARM: pxa168: Add support for UART3 Tanmay Upadhyay
2011-05-02  5:59 ` [PATCH 2/3] ARM: pxa168: Add support for Ethernet Tanmay Upadhyay
2011-06-10 13:31   ` Eric Miao
2011-05-02  6:00 ` [PATCH 3/3] ARM: pxa168: Add board support for gplugD Tanmay Upadhyay
2011-06-20  5:55   ` Eric Miao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.